From 22271d146a0bca6b432f458c96c4ca18a1b6b143 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 22 Aug 2023 00:50:36 +0600 Subject: [PATCH 001/223] Switch to `vcpkg` for library dependencies --- .github/workflows/continuous_integration.yml | 13 +++-- CMakeLists.txt | 25 ++++++++++ src/CMakeLists.txt | 14 ++++-- vcpkg.json | 51 ++++++++++++++++++++ 4 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 vcpkg.json diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 47a096312..d18de22ea 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -13,19 +13,19 @@ jobs: - { name: "Visual Studio 2022", os: windows-2022, - extra_options: "-A x64", + extra_options: "-A x64 -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake", build_type: "Release" } - { name: "Visual Studio 2019", os: windows-2019, - extra_options: "-A x64", + extra_options: "-A x64 -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake", build_type: "Release" } - { name: "Visual Studio 2019", os: windows-2019, - extra_options: "-A x64", + extra_options: "-A x64 -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake", build_type: "Debug" } - { @@ -90,6 +90,13 @@ jobs: wget -q "https://github.com/coelckers/gzdoom/releases/download/ci_deps/${ZMUSIC_PACKAGE}" tar -xf "${ZMUSIC_PACKAGE}" fi + + - name: Setup vcpkg + uses: lukka/run-vcpkg@v11 + if: runner.os == 'Windows' + with: + vcpkgDirectory: '${{ github.workspace }}/build/vcpkg' + vcpkgGitCommitId: '65c013b9667ff1f58fb8724209227e5a2e761043' - name: Configure shell: bash diff --git a/CMakeLists.txt b/CMakeLists.txt index ece590f0d..46205f0f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,8 +16,33 @@ if( COMMAND cmake_policy ) endif() endif() +if (LIBVPX_VCPKG) + list(APPEND VCPKG_MANIFEST_FEATURES "vcpkg-libvpx") +endif() + +if (OPENAL_SOFT_VCPKG) + list(APPEND VCPKG_MANIFEST_FEATURES "vcpkg-openal-soft") +endif() + +if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR (NOT CMAKE_SYSTEM_NAME AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")) + # Force static triplet on Windows + set(VCPKG_TARGET_TRIPLET "x64-windows-static") +endif() + project(GZDoom) +if (WIN32 AND VCPKG_TOOLCHAIN) + option(LIBVPX_VCPKG "Use libvpx from vcpkg" OFF) +endif() + +if (VCPKG_TOOLCHAIN) + option(OPENAL_SOFT_VCPKG "Use OpenAL from vcpkg" OFF) +endif() + +if (NOT VCPKG_TOOLCHAIN) + set(VCPKG_MANIFEST_FEATURES) +endif() + set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 212511c2c..3ee43be60 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -139,7 +139,11 @@ else() endif() if( NOT NO_OPENAL ) - if ( NOT DYN_OPENAL ) # DYN_OPENAL uses local copies of the headers. + if ( "vcpkg-openal-soft" IN_LIST VCPKG_MANIFEST_FEATURES ) + # Statically link to OpenAL from vcpkg + find_package( OpenAL CONFIG REQUIRED ) + list( APPEND PROJECT_LIBRARIES OpenAL::OpenAL ) + elseif ( NOT DYN_OPENAL ) # DYN_OPENAL uses local copies of the headers. find_package( OpenAL ) mark_as_advanced(CLEAR OPENAL_INCLUDE_DIR) if( OPENAL_INCLUDE_DIR ) @@ -300,7 +304,7 @@ if( UNIX ) add_definitions( -DNO_CLOCK_GETTIME ) endif() else() - set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} rt ) + list( APPEND PROJECT_LIBRARIES rt ) endif() endif() @@ -317,7 +321,7 @@ add_custom_target( revision_check ALL set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${CMAKE_DL_LIBS}" "${DRPC_LIBRARIES}") if (HAVE_VULKAN) - set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "zvulkan") + list( APPEND PROJECT_LIBRARIES "zvulkan" ) endif() # ZMUSIC @@ -1360,6 +1364,10 @@ add_custom_command(TARGET zdoom POST_BUILD ${CMAKE_SOURCE_DIR}/fm_banks/gs-by-papiezak-and-sneakernets.wopn $/fm_banks/gs-by-papiezak-and-sneakernets.wopn ) +if (VCPKG_TOOLCHAIN) + x_vcpkg_install_local_dependencies(TARGETS zdoom DESTINATION ".") +endif() + if( WIN32 ) set( INSTALL_SOUNDFONT_PATH . CACHE STRING "Directory where soundfonts and WOPL/WOPN banks will be placed during install." ) else() diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 000000000..941888414 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", + "builtin-baseline": "9d47b24eacbd1cd94f139457ef6cd35e5d92cc84", + "features": + { + "vcpkg-libvpx": + { + "description": "Use libvpx provided by vcpkg on Windows", + "dependencies": [ + { + "name": "libvpx", + "default-features": false, + "platform": "windows & static & staticcrt" + } + ] + }, + "vcpkg-openal-soft": + { + "description": "Use openal-soft provided by vcpkg.", + "dependencies": [ + { + "name": "openal-soft", + "default-features": false, + "platform": "!windows | (windows & static & staticcrt)" + } + ] + } + }, + "dependencies": [ + { + "name": "zlib", + "platform": "!windows | (windows & static & staticcrt)" + }, + { + "name": "libjpeg-turbo", + "platform": "!windows | (windows & static & staticcrt)" + }, + { + "name": "bzip2", + "platform": "!windows | (windows & static & staticcrt)" + }, + { + "name": "sdl2", + "platform": "!windows & !osx" + }, + { + "name": "libvpx", + "platform": "!windows" + } + ] +} \ No newline at end of file From ae2fa11963242cf730ef332d8af4033bd2c26fdc Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 22 Aug 2023 13:49:32 +0300 Subject: [PATCH 002/223] - added safeguards against very early access to console variables in Cocoa backend for an unknown reason, application activation functions can be called way too early during app launch `S_SetSoundPaused()` function tries to read values of `i_pauseinbackground` and `i_soundinbackground` console variables before their initialization leading to a null pointer dereference https://forum.zdoom.org/viewtopic.php?t=78092 --- src/common/platform/posix/cocoa/i_main.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common/platform/posix/cocoa/i_main.mm b/src/common/platform/posix/cocoa/i_main.mm index 8a9d96b07..8c58ca419 100644 --- a/src/common/platform/posix/cocoa/i_main.mm +++ b/src/common/platform/posix/cocoa/i_main.mm @@ -282,7 +282,8 @@ extern bool AppActive; { ZD_UNUSED(aNotification); - S_SetSoundPaused(1); + if (GSnd) + S_SetSoundPaused(1); AppActive = true; } @@ -291,7 +292,8 @@ extern bool AppActive; { ZD_UNUSED(aNotification); - S_SetSoundPaused(0); + if (GSnd) + S_SetSoundPaused(0); AppActive = false; } From 145450a0448a17a5d98b3888c4e4218632c13f86 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 22 Aug 2023 00:54:16 +0600 Subject: [PATCH 003/223] WebP image support --- .github/workflows/appimage.yml | 2 +- .github/workflows/continuous_integration.yml | 10 +- CMakeLists.txt | 14 ++ src/CMakeLists.txt | 8 ++ src/common/textures/formats/webptexture.cpp | 143 +++++++++++++++++++ src/common/textures/image.cpp | 2 + vcpkg.json | 4 + 7 files changed, 177 insertions(+), 6 deletions(-) create mode 100644 src/common/textures/formats/webptexture.cpp diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index e02a61097..885c32921 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -12,7 +12,7 @@ jobs: - name: Install GZDoom dependencies run: | sudo apt-get update - sudo apt-get install clang-12 libsdl2-dev libvpx-dev cmake -y + sudo apt-get install clang-12 libsdl2-dev libvpx-dev libwebp-dev cmake -y - name: Install appimage-builder dependencies run: | sudo apt-get install binutils coreutils desktop-file-utils fakeroot fuse libgdk-pixbuf2.0-dev patchelf -y diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index d18de22ea..4a7dcbee4 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -31,28 +31,28 @@ jobs: - { name: "macOS", os: macos-12, - deps_cmdline: "brew install libvpx", + deps_cmdline: "brew install libvpx webp", build_type: "Release" } - { name: "macOS", os: macos-12, extra_options: "-G Xcode -DDYN_OPENAL=OFF", - deps_cmdline: "brew install libvpx fluidsynth mpg123 libsndfile", + deps_cmdline: "brew install libvpx fluidsynth mpg123 libsndfile webp", build_type: "Debug" } - { name: "Linux GCC 7", os: ubuntu-20.04, extra_options: "-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7", - deps_cmdline: "sudo apt update && sudo apt install g++-7 libsdl2-dev libvpx-dev libgtk2.0-dev", + deps_cmdline: "sudo apt update && sudo apt install g++-7 libsdl2-dev libvpx-dev libgtk2.0-dev libwebp-dev", build_type: "RelWithDebInfo" } - { name: "Linux GCC 11", os: ubuntu-20.04, extra_options: "-DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11", - deps_cmdline: "sudo apt update && sudo apt install g++-11 libsdl2-dev libvpx-dev libgtk-3-dev", + deps_cmdline: "sudo apt update && sudo apt install g++-11 libsdl2-dev libvpx-dev libgtk-3-dev libwebp-dev", build_type: "MinSizeRel" } # - { @@ -66,7 +66,7 @@ jobs: name: "Linux Clang 12", os: ubuntu-20.04, extra_options: "-DCMAKE_C_COMPILER=clang-12 -DCMAKE_CXX_COMPILER=clang++-12", - deps_cmdline: "sudo apt update && sudo apt install clang-12 libsdl2-dev libvpx-dev", + deps_cmdline: "sudo apt update && sudo apt install clang-12 libsdl2-dev libvpx-dev libwebp-dev", build_type: "Release" } diff --git a/CMakeLists.txt b/CMakeLists.txt index 46205f0f8..d59560964 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -217,6 +217,20 @@ find_package( BZip2 ) find_package( JPEG ) find_package( VPX ) find_package( ZLIB ) +find_package( WebP ) +if (NOT WebP_FOUND) + include(FindPkgConfig) + pkg_check_modules(libwebp IMPORTED_TARGET libwebp) + if (NOT TARGET PkgConfig::libwebp) + message(SEND_ERROR "libwebp not found") + endif() + pkg_check_modules(libwebpmux REQUIRED IMPORTED_TARGET libwebpmux) + pkg_check_modules(libwebpdemux REQUIRED IMPORTED_TARGET libwebpdemux) + + add_library(WebP::webp ALIAS PkgConfig::libwebp) + add_library(WebP::webpdemux ALIAS PkgConfig::libwebpdemux) + add_library(WebP::libwebpmux ALIAS PkgConfig::libwebpmux) +endif() include( TargetArch ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3ee43be60..04f19ef68 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -380,6 +380,13 @@ else() message( SEND_ERROR "Could not find libvpx" ) endif() +if (TARGET WebP::webp) + list( APPEND PROJECT_LIBRARIES WebP::webp WebP::webpdemux WebP::libwebpmux ) + if (TARGET WebP::webpdecoder) + list( APPEND PROJECT_LIBRARIES WebP::webpdecoder) + endif() +endif() + include_directories( SYSTEM "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${ZMUSIC_INCLUDE_DIR}" "${DRPC_INCLUDE_DIR}") if( ${HAVE_VM_JIT} ) @@ -1028,6 +1035,7 @@ set (PCH_SOURCES common/textures/formats/anmtexture.cpp common/textures/formats/startscreentexture.cpp common/textures/formats/qoitexture.cpp + common/textures/formats/webptexture.cpp common/textures/hires/hqresize.cpp common/models/models_md3.cpp common/models/models_md2.cpp diff --git a/src/common/textures/formats/webptexture.cpp b/src/common/textures/formats/webptexture.cpp new file mode 100644 index 000000000..60a9ccbc3 --- /dev/null +++ b/src/common/textures/formats/webptexture.cpp @@ -0,0 +1,143 @@ +/* +** webptexture.cpp +** Texture class for WebP images. +** +**--------------------------------------------------------------------------- +** Copyright 2023 Cacodemon345 +** 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. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "webp/decode.h" +#include "webp/mux.h" + +#include "files.h" +#include "filesystem.h" +#include "bitmap.h" +#include "imagehelpers.h" +#include "image.h" +#include "printf.h" + +class FWebPTexture : public FImageSource +{ + +public: + FWebPTexture(int lumpnum, int w, int h, int xoff, int yoff); + PalettedPixels CreatePalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion) override; +}; + + +FImageSource *WebPImage_TryCreate(FileReader &file, int lumpnum) +{ + int width = 0, height = 0; + int xoff = 0, yoff = 0; + file.Seek(0, FileReader::SeekSet); + auto bytes = file.Read(); + + if (WebPGetInfo(bytes.Data(), bytes.Size(), &width, &height)) + { + WebPData data{ bytes.Data(), bytes.Size() }; + WebPData chunk_data; + auto mux = WebPMuxCreate(&data, 0); + if (mux) + { + const char fourcc[4] = { 'g', 'r', 'A', 'b' }; + if (WebPMuxGetChunk(mux, fourcc, &chunk_data) == WEBP_MUX_OK && chunk_data.size >= 4) + { + xoff = chunk_data.bytes[0] | (chunk_data.bytes[1] << 8); + yoff = chunk_data.bytes[2] | (chunk_data.bytes[3] << 8); + } + WebPMuxDelete(mux); + } + return new FWebPTexture(lumpnum, width, height, xoff, yoff); + } + return NULL; +} + +FWebPTexture::FWebPTexture(int lumpnum, int w, int h, int xoff, int yoff) + : FImageSource(lumpnum) +{ + Width = w; + Height = h; + LeftOffset = xoff; + TopOffset = yoff; +} + +PalettedPixels FWebPTexture::CreatePalettedPixels(int conversion) +{ + FBitmap bitmap; + bitmap.Create(Width, Height); + CopyPixels(&bitmap, conversion); + const uint8_t *data = bitmap.GetPixels(); + + uint8_t *dest_p; + int dest_adv = Height; + int dest_rew = Width * Height - 1; + + PalettedPixels Pixels(Width*Height); + dest_p = Pixels.Data(); + + bool doalpha = conversion == luminance; + // Convert the source image from row-major to column-major format and remap it + for (int y = Height; y != 0; --y) + { + for (int x = Width; x != 0; --x) + { + int b = *data++; + int g = *data++; + int r = *data++; + int a = *data++; + if (a < 128) *dest_p = 0; + else *dest_p = ImageHelpers::RGBToPalette(doalpha, r, g, b); + dest_p += dest_adv; + } + dest_p -= dest_rew; + } + return Pixels; +} + +int FWebPTexture::CopyPixels(FBitmap *bmp, int conversion) +{ + WebPDecoderConfig config; + auto lump = fileSystem.OpenFileReader(SourceLump); + auto bytes = lump.Read(); + + if (WebPInitDecoderConfig(&config) == false) + return 0; + + config.options.no_fancy_upsampling = 0; + config.output.colorspace = MODE_BGRA; + config.output.u.RGBA.rgba = (uint8_t*)bmp->GetPixels(); + config.output.u.RGBA.size = bmp->GetBufferSize(); + config.output.u.RGBA.stride = bmp->GetPitch(); + config.output.is_external_memory = 1; + + (void)WebPDecode(bytes.Data(), bytes.Size(), &config); + + return 0; +} diff --git a/src/common/textures/image.cpp b/src/common/textures/image.cpp index e1939dfe1..dcd1f28d3 100644 --- a/src/common/textures/image.cpp +++ b/src/common/textures/image.cpp @@ -323,6 +323,7 @@ FImageSource *PCXImage_TryCreate(FileReader &, int lumpnum); FImageSource *TGAImage_TryCreate(FileReader &, int lumpnum); FImageSource *StbImage_TryCreate(FileReader &, int lumpnum); FImageSource *QOIImage_TryCreate(FileReader &, int lumpnum); +FImageSource *WebPImage_TryCreate(FileReader &, int lumpnum); FImageSource *AnmImage_TryCreate(FileReader &, int lumpnum); FImageSource *RawPageImage_TryCreate(FileReader &, int lumpnum); FImageSource *FlatImage_TryCreate(FileReader &, int lumpnum); @@ -344,6 +345,7 @@ FImageSource * FImageSource::GetImage(int lumpnum, bool isflat) { PCXImage_TryCreate, false }, { StbImage_TryCreate, false }, { QOIImage_TryCreate, false }, + { WebPImage_TryCreate, false }, { TGAImage_TryCreate, false }, { AnmImage_TryCreate, false }, { StartupPageImage_TryCreate, false }, diff --git a/vcpkg.json b/vcpkg.json index 941888414..d89c12d12 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -46,6 +46,10 @@ { "name": "libvpx", "platform": "!windows" + }, + { + "name": "libwebp", + "platform": "!windows | (windows & static & staticcrt)" } ] } \ No newline at end of file From 1dc47f91c2f53f239fa8b4af130f5a9e7e1e0a0a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 18 Aug 2023 20:34:12 +0200 Subject: [PATCH 004/223] - file system error management refactoring. --- src/CMakeLists.txt | 32 +-- src/common/filesystem/ancientzip.cpp | 2 +- src/common/filesystem/ancientzip.h | 7 - src/common/filesystem/file_7z.cpp | 8 +- src/common/filesystem/file_directory.cpp | 9 +- src/common/filesystem/file_rff.cpp | 2 +- src/common/filesystem/file_wad.cpp | 10 +- src/common/filesystem/file_zip.cpp | 24 +-- src/common/filesystem/file_zip.h | 2 +- src/common/{utility => filesystem}/files.cpp | 0 src/common/{utility => filesystem}/files.h | 34 ++- .../files_decompress.cpp | 196 +++++++++++++----- src/common/filesystem/filesystem.cpp | 24 +-- src/common/filesystem/resourcefile.cpp | 26 ++- src/common/filesystem/resourcefile.h | 4 +- src/common/utility/engineerrors.h | 4 +- src/common/utility/utf8.h | 2 + src/d_main.cpp | 10 +- src/maploader/maploader.cpp | 44 ++-- 19 files changed, 288 insertions(+), 152 deletions(-) rename src/common/{utility => filesystem}/files.cpp (100%) rename src/common/{utility => filesystem}/files.h (91%) rename src/common/{utility => filesystem}/files_decompress.cpp (84%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 04f19ef68..518235f66 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1066,8 +1066,6 @@ set (PCH_SOURCES common/utility/m_alloc.cpp common/utility/utf8.cpp common/utility/palette.cpp - common/utility/files.cpp - common/utility/files_decompress.cpp common/utility/memarena.cpp common/utility/cmdlib.cpp common/utility/configfile.cpp @@ -1084,19 +1082,6 @@ set (PCH_SOURCES common/thirdparty/libsmackerdec/src/HuffmanVLC.cpp common/thirdparty/libsmackerdec/src/LogError.cpp common/thirdparty/libsmackerdec/src/SmackerDecoder.cpp - common/filesystem/filesystem.cpp - common/filesystem/ancientzip.cpp - common/filesystem/file_7z.cpp - common/filesystem/file_grp.cpp - common/filesystem/file_lump.cpp - common/filesystem/file_rff.cpp - common/filesystem/file_wad.cpp - common/filesystem/file_zip.cpp - common/filesystem/file_pak.cpp - common/filesystem/file_whres.cpp - common/filesystem/file_ssi.cpp - common/filesystem/file_directory.cpp - common/filesystem/resourcefile.cpp common/engine/cycler.cpp common/engine/d_event.cpp common/engine/date.cpp @@ -1220,6 +1205,23 @@ set( ZDOOM_SOURCES common/thirdparty/math/tan.c common/thirdparty/math/tanh.c common/thirdparty/math/fastsin.cpp + + common/filesystem/filesystem.cpp + common/filesystem/ancientzip.cpp + common/filesystem/file_7z.cpp + common/filesystem/file_grp.cpp + common/filesystem/file_lump.cpp + common/filesystem/file_rff.cpp + common/filesystem/file_wad.cpp + common/filesystem/file_zip.cpp + common/filesystem/file_pak.cpp + common/filesystem/file_whres.cpp + common/filesystem/file_ssi.cpp + common/filesystem/file_directory.cpp + common/filesystem/resourcefile.cpp + common/filesystem/files.cpp + common/filesystem/files_decompress.cpp + ) set( ZDOOM_NONPCH_SOURCES ${ZDOOM_SOURCES} ) diff --git a/src/common/filesystem/ancientzip.cpp b/src/common/filesystem/ancientzip.cpp index 0088d1f00..80f0c6093 100644 --- a/src/common/filesystem/ancientzip.cpp +++ b/src/common/filesystem/ancientzip.cpp @@ -310,7 +310,7 @@ int FZipExploder::Explode(unsigned char *out, unsigned int outsize, len += minMatchLen; dist++; if (bIdx + len > outsize) { - throw CExplosionError("Not enough output space"); + return -1; } if ((unsigned int)dist > bIdx) { /* Anything before the first input byte is zero. */ diff --git a/src/common/filesystem/ancientzip.h b/src/common/filesystem/ancientzip.h index 6241f775d..57b0f3584 100644 --- a/src/common/filesystem/ancientzip.h +++ b/src/common/filesystem/ancientzip.h @@ -1,6 +1,5 @@ #pragma once #include "files.h" -#include "engineerrors.h" class FZipExploder { @@ -42,10 +41,4 @@ public: int Explode(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize, int flags); }; -class CExplosionError : public CRecoverableError -{ -public: - CExplosionError(const char *message) : CRecoverableError(message) {} -}; - int ShrinkLoop(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize); \ No newline at end of file diff --git a/src/common/filesystem/file_7z.cpp b/src/common/filesystem/file_7z.cpp index 2bdd2e38f..405e9b919 100644 --- a/src/common/filesystem/file_7z.cpp +++ b/src/common/filesystem/file_7z.cpp @@ -168,7 +168,7 @@ struct F7ZLump : public FResourceLump { int Position; - virtual int FillCache(); + virtual int FillCache() override; }; @@ -340,7 +340,11 @@ F7ZFile::~F7ZFile() int F7ZLump::FillCache() { Cache = new char[LumpSize]; - static_cast(Owner)->Archive->Extract(Position, Cache); + SRes code = static_cast(Owner)->Archive->Extract(Position, Cache); + if (code != SZ_OK) + { + throw FileSystemException("Error %d reading from 7z archive", code); + } RefCount = 1; return 1; } diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/file_directory.cpp index f0ba89bfc..00b1e7a12 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/file_directory.cpp @@ -250,10 +250,13 @@ int FDirectoryLump::FillCache() Cache = new char[LumpSize]; if (!fr.OpenFile(mFullPath)) { - memset(Cache, 0, LumpSize); - return 0; + throw FileSystemException("unable to open file"); + } + auto read = fr.Read(Cache, LumpSize); + if (read != LumpSize) + { + throw FileSystemException("only read %d of %d bytes", (int)read, (int)LumpSize); } - fr.Read(Cache, LumpSize); RefCount = 1; return 1; } diff --git a/src/common/filesystem/file_rff.cpp b/src/common/filesystem/file_rff.cpp index 8d59749a5..67c26def1 100644 --- a/src/common/filesystem/file_rff.cpp +++ b/src/common/filesystem/file_rff.cpp @@ -72,7 +72,7 @@ struct RFFLump struct FRFFLump : public FUncompressedLump { virtual FileReader *GetReader(); - virtual int FillCache(); + virtual int FillCache() override; uint32_t IndexNum; diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/file_wad.cpp index 45e2ec39c..e856212ba 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/file_wad.cpp @@ -100,13 +100,19 @@ public: if(Compressed) { FileReader lzss; - if (lzss.OpenDecompressor(Owner->Reader, LumpSize, METHOD_LZSS, false, [](const char* err) { I_Error("%s", err); })) + if (lzss.OpenDecompressor(Owner->Reader, LumpSize, METHOD_LZSS, false, true)) { lzss.Read(Cache, LumpSize); } } else - Owner->Reader.Read(Cache, LumpSize); + { + auto read = Owner->Reader.Read(Cache, LumpSize); + if (read != LumpSize) + { + throw FileSystemException("only read %d of %d bytes", (int)read, (int)LumpSize); + } + } RefCount = 1; return 1; diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index 75ca09da1..355fefa97 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -34,6 +34,7 @@ */ #include +#include #include "file_zip.h" #include "cmdlib.h" @@ -49,7 +50,7 @@ // //========================================================================== -static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int LumpSize, int CompressedSize, int GPFlags) +static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int LumpSize, int CompressedSize, int GPFlags, bool exceptions) { switch (Method) { @@ -64,7 +65,7 @@ static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int L case METHOD_LZMA: { FileReader frz; - if (frz.OpenDecompressor(Reader, LumpSize, Method, false, [](const char* err) { I_Error("%s", err); })) + if (frz.OpenDecompressor(Reader, LumpSize, Method, false, exceptions)) { frz.Read(Cache, LumpSize); } @@ -75,7 +76,11 @@ static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int L case METHOD_IMPLODE: { FZipExploder exploder; - exploder.Explode((unsigned char *)Cache, LumpSize, Reader, CompressedSize, GPFlags); + if (exploder.Explode((unsigned char*)Cache, LumpSize, Reader, CompressedSize, GPFlags) == -1) + { + // decompression failed so zero the cache. + memset(Cache, 0, LumpSize); + } break; } @@ -96,7 +101,7 @@ bool FCompressedBuffer::Decompress(char *destbuffer) { FileReader mr; mr.OpenMemory(mBuffer, mCompressedSize); - return UncompressZipLump(destbuffer, mr, mMethod, mSize, mCompressedSize, mZipFlags); + return UncompressZipLump(destbuffer, mr, mMethod, mSize, mCompressedSize, mZipFlags, false); } //----------------------------------------------------------------------- @@ -499,16 +504,7 @@ int FZipLump::FillCache() Owner->Reader.Seek(Position, FileReader::SeekSet); Cache = new char[LumpSize]; - try - { - UncompressZipLump(Cache, Owner->Reader, Method, LumpSize, CompressedSize, GPFlags); - } - catch (const CRecoverableError& ) - { - // this cannot propagate the exception but also has no means to handle the error message. Damn... - // At least don't return uninitialized memory here. - memset(Cache, 0, LumpSize); - } + UncompressZipLump(Cache, Owner->Reader, Method, LumpSize, CompressedSize, GPFlags, true); RefCount = 1; return 1; } diff --git a/src/common/filesystem/file_zip.h b/src/common/filesystem/file_zip.h index fc1d9acab..028731f28 100644 --- a/src/common/filesystem/file_zip.h +++ b/src/common/filesystem/file_zip.h @@ -19,7 +19,7 @@ struct FZipLump : public FResourceLump unsigned CRC32; virtual FileReader *GetReader(); - virtual int FillCache(); + virtual int FillCache() override; private: void SetLumpAddress(); diff --git a/src/common/utility/files.cpp b/src/common/filesystem/files.cpp similarity index 100% rename from src/common/utility/files.cpp rename to src/common/filesystem/files.cpp diff --git a/src/common/utility/files.h b/src/common/filesystem/files.h similarity index 91% rename from src/common/utility/files.h rename to src/common/filesystem/files.h index 24d66e1d7..4cfe74382 100644 --- a/src/common/utility/files.h +++ b/src/common/filesystem/files.h @@ -39,11 +39,36 @@ #include #include #include +#include #include #include "basics.h" #include "m_swap.h" #include "tarray.h" +class FileSystemException : public std::exception +{ +protected: + static const int MAX_FSERRORTEXT = 1024; + char m_Message[MAX_FSERRORTEXT]; + +public: + FileSystemException(const char* error, ...) + { + va_list argptr; + va_start(argptr, error); + vsnprintf(m_Message, MAX_FSERRORTEXT, error, argptr); + va_end(argptr); + } + FileSystemException(const char* error, va_list argptr) + { + vsnprintf(m_Message, MAX_FSERRORTEXT, error, argptr); + } + char const* what() const noexcept override + { + return m_Message; + } +}; + // Zip compression methods, extended by some internal types to be passed to OpenDecompressor enum { @@ -172,7 +197,7 @@ public: bool OpenMemory(const void *mem, Size length); // read directly from the buffer bool OpenMemoryArray(const void *mem, Size length); // read from a copy of the buffer. bool OpenMemoryArray(std::function&)> getter); // read contents to a buffer and return a reader to it - bool OpenDecompressor(FileReader &parent, Size length, int method, bool seekable, const std::function& cb); // creates a decompressor stream. 'seekable' uses a buffered version so that the Seek and Tell methods can be used. + bool OpenDecompressor(FileReader &parent, Size length, int method, bool seekable, bool exceptions = false); // creates a decompressor stream. 'seekable' uses a buffered version so that the Seek and Tell methods can be used. Size Tell() const { @@ -306,7 +331,7 @@ public: class DecompressorBase : public FileReaderInterface { - std::function ErrorCallback = nullptr; + bool exceptions = false; public: // These do not work but need to be defined to satisfy the FileReaderInterface. // They will just error out when called. @@ -314,11 +339,8 @@ public: long Seek(long offset, int origin) override; char* Gets(char* strbuf, int len) override; void DecompressionError(const char* error, ...) const; - void SetErrorCallback(const std::function& cb) - { - ErrorCallback = cb; - } void SetOwnsReader(); + void EnableExceptions(bool on) { exceptions = on; } protected: FileReader* File = nullptr; diff --git a/src/common/utility/files_decompress.cpp b/src/common/filesystem/files_decompress.cpp similarity index 84% rename from src/common/utility/files_decompress.cpp rename to src/common/filesystem/files_decompress.cpp index 7954b5101..3e636d1bd 100644 --- a/src/common/utility/files_decompress.cpp +++ b/src/common/filesystem/files_decompress.cpp @@ -47,25 +47,22 @@ //========================================================================== // -// I_Error +// DecompressionError // -// Throw an error that will send us to the console if we are far enough -// along in the startup process. +// Allows catching errors from the decompressor. The default is just to +// return failure from the calling function. // //========================================================================== void DecompressorBase::DecompressionError(const char *error, ...) const { - const int MAX_ERRORTEXT = 300; - va_list argptr; - char errortext[MAX_ERRORTEXT]; - - va_start(argptr, error); - vsnprintf(errortext, MAX_ERRORTEXT, error, argptr); - va_end(argptr); - - if (ErrorCallback != nullptr) ErrorCallback(errortext); - else throw std::runtime_error(errortext); + if (exceptions) + { + va_list argptr; + va_start(argptr, error); + throw FileSystemException(error, argptr); + va_end(argptr); + } } long DecompressorBase::Tell () const @@ -103,18 +100,22 @@ class DecompressorZ : public DecompressorBase { enum { BUFF_SIZE = 4096 }; - bool SawEOF; + bool SawEOF = false; z_stream Stream; uint8_t InBuff[BUFF_SIZE]; public: - DecompressorZ (FileReader *file, bool zip, const std::function& cb) - : SawEOF(false) + bool Open (FileReader *file, bool zip) { + if (File != nullptr) + { + DecompressionError("File already open"); + return false; + } + int err; File = file; - SetErrorCallback(cb); FillBuffer (); Stream.zalloc = Z_NULL; @@ -126,7 +127,9 @@ public: if (err != Z_OK) { DecompressionError ("DecompressorZ: inflateInit failed: %s\n", M_ZLibError(err).GetChars()); + return false; } + return true; } ~DecompressorZ () @@ -138,6 +141,12 @@ public: { int err; + if (File == nullptr) + { + DecompressionError("File not open"); + return 0; + } + Stream.next_out = (Bytef *)buffer; Stream.avail_out = len; @@ -153,11 +162,13 @@ public: if (err != Z_OK && err != Z_STREAM_END) { DecompressionError ("Corrupt zlib stream"); + return 0; } if (Stream.avail_out != 0) { DecompressionError ("Ran out of data in zlib stream"); + return 0; } return len - Stream.avail_out; @@ -194,18 +205,22 @@ class DecompressorBZ2 : public DecompressorBase { enum { BUFF_SIZE = 4096 }; - bool SawEOF; + bool SawEOF = false; bz_stream Stream; uint8_t InBuff[BUFF_SIZE]; public: - DecompressorBZ2 (FileReader *file, const std::function& cb) - : SawEOF(false) + bool Open(FileReader *file) { + if (File != nullptr) + { + DecompressionError("File already open"); + return false; + } + int err; File = file; - SetErrorCallback(cb); stupidGlobal = this; FillBuffer (); @@ -218,7 +233,9 @@ public: if (err != BZ_OK) { DecompressionError ("DecompressorBZ2: bzDecompressInit failed: %d\n", err); + return false; } + return true; } ~DecompressorBZ2 () @@ -229,6 +246,12 @@ public: long Read (void *buffer, long len) override { + if (File == nullptr) + { + DecompressionError("File not open"); + return 0; + } + int err; stupidGlobal = this; @@ -247,11 +270,13 @@ public: if (err != BZ_OK && err != BZ_STREAM_END) { DecompressionError ("Corrupt bzip2 stream"); + return 0; } if (Stream.avail_out != 0) { DecompressionError ("Ran out of data in bzip2 stream"); + return 0; } return len - Stream.avail_out; @@ -303,7 +328,7 @@ class DecompressorLZMA : public DecompressorBase { enum { BUFF_SIZE = 4096 }; - bool SawEOF; + bool SawEOF = false; CLzmaDec Stream; size_t Size; size_t InPos, InSize; @@ -312,13 +337,17 @@ class DecompressorLZMA : public DecompressorBase public: - DecompressorLZMA (FileReader *file, size_t uncompressed_size, const std::function& cb) - : SawEOF(false) + bool Open(FileReader *file, size_t uncompressed_size) { + if (File != nullptr) + { + DecompressionError("File already open"); + return false; + } + uint8_t header[4 + LZMA_PROPS_SIZE]; int err; File = file; - SetErrorCallback(cb); Size = uncompressed_size; OutProcessed = 0; @@ -327,11 +356,13 @@ public: if (File->Read(header, sizeof(header)) < (long)sizeof(header)) { DecompressionError("DecompressorLZMA: File too short\n"); + return false; } if (header[2] + header[3] * 256 != LZMA_PROPS_SIZE) { DecompressionError("DecompressorLZMA: LZMA props size is %d (expected %d)\n", header[2] + header[3] * 256, LZMA_PROPS_SIZE); + return false; } FillBuffer(); @@ -342,9 +373,11 @@ public: if (err != SZ_OK) { DecompressionError("DecompressorLZMA: LzmaDec_Allocate failed: %d\n", err); + return false; } LzmaDec_Init(&Stream); + return true; } ~DecompressorLZMA () @@ -354,6 +387,12 @@ public: long Read (void *buffer, long len) override { + if (File == nullptr) + { + DecompressionError("File not open"); + return 0; + } + int err; Byte *next_out = (Byte *)buffer; @@ -372,12 +411,14 @@ public: if (err != SZ_OK) { DecompressionError ("Corrupt LZMA stream"); + return 0; } if (in_processed == 0 && out_processed == 0) { if (status != LZMA_STATUS_FINISHED_WITH_MARK) { DecompressionError ("Corrupt LZMA stream"); + return 0; } } if (InSize == 0 && !SawEOF) @@ -389,11 +430,13 @@ public: if (err != Z_OK && err != Z_STREAM_END) { DecompressionError ("Corrupt LZMA stream"); + return 0; } if (len != 0) { DecompressionError ("Ran out of data in LZMA stream"); + return 0; } return (long)(next_out - (Byte *)buffer); @@ -540,16 +583,22 @@ class DecompressorLZSS : public DecompressorBase } public: - DecompressorLZSS(FileReader *file, const std::function& cb) : SawEOF(false) + bool Open(FileReader *file) { + if (File != nullptr) + { + DecompressionError("File already open"); + return false; + } + File = file; - SetErrorCallback(cb); Stream.State = STREAM_EMPTY; Stream.WindowData = Stream.InternalBuffer = Stream.Window+WINDOW_SIZE; Stream.InternalOut = 0; Stream.AvailIn = 0; FillBuffer(); + return true; } ~DecompressorLZSS() @@ -604,50 +653,91 @@ public: }; -bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, bool seekable, const std::function& cb) +bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, bool seekable, bool exceptions) { - DecompressorBase *dec = nullptr; - FileReader *p = &parent; - switch (method & ~METHOD_TRANSFEROWNER) + DecompressorBase* dec = nullptr; + try { + FileReader* p = &parent; + switch (method & ~METHOD_TRANSFEROWNER) + { case METHOD_DEFLATE: case METHOD_ZLIB: - dec = new DecompressorZ(p, method == METHOD_DEFLATE, cb); + { + auto idec = new DecompressorZ; + dec = idec; + idec->EnableExceptions(exceptions); + if (!idec->Open(p, method == METHOD_DEFLATE)) + { + delete idec; + return false; + } break; - + } case METHOD_BZIP2: - dec = new DecompressorBZ2(p, cb); + { + auto idec = new DecompressorBZ2; + dec = idec; + idec->EnableExceptions(exceptions); + if (!idec->Open(p)) + { + delete idec; + return false; + } break; - + } case METHOD_LZMA: - dec = new DecompressorLZMA(p, length, cb); + { + auto idec = new DecompressorLZMA; + dec = idec; + idec->EnableExceptions(exceptions); + if (!idec->Open(p, length)) + { + delete idec; + return false; + } break; - + } case METHOD_LZSS: - dec = new DecompressorLZSS(p, cb); + { + auto idec = new DecompressorLZSS; + dec = idec; + idec->EnableExceptions(exceptions); + if (!idec->Open(p)) + { + delete idec; + return false; + } break; + } // todo: METHOD_IMPLODE, METHOD_SHRINK default: return false; - } - if (method & METHOD_TRANSFEROWNER) - { - dec->SetOwnsReader(); - } + } + if (method & METHOD_TRANSFEROWNER) + { + dec->SetOwnsReader(); + } - dec->Length = (long)length; - if (!seekable) - { - Close(); - mReader = dec; - return true; + dec->Length = (long)length; + if (!seekable) + { + Close(); + mReader = dec; + return true; + } + else + { + // todo: create a wrapper. for now this fails + delete dec; + return false; + } } - else + catch (...) { - // todo: create a wrapper. for now this fails - delete dec; - return false; + if (dec) delete dec; + throw; } } diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index c4bcb64cd..b7c370360 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -569,7 +569,7 @@ int FileSystem::GetNumForName (const char *name, int space) i = CheckNumForName (name, space); if (i == -1) - I_Error ("GetNumForName: %s not found!", name); + throw FileSystemException("GetNumForName: %s not found!", name); return i; } @@ -653,7 +653,7 @@ int FileSystem::GetNumForFullName (const char *name) i = CheckNumForFullName (name); if (i == -1) - I_Error ("GetNumForFullName: %s not found!", name); + throw FileSystemException("GetNumForFullName: %s not found!", name); return i; } @@ -743,7 +743,7 @@ int FileSystem::GetResource (int resid, const char *type, int filenum) const if (i == -1) { - I_Error("GetResource: %d of type %s not found!", resid, type); + throw FileSystemException("GetResource: %d of type %s not found!", resid, type); } return i; } @@ -922,19 +922,19 @@ void FileSystem::InitHashChains (void) LumpShortName& FileSystem::GetShortName(int i) { - if ((unsigned)i >= NumEntries) I_Error("GetShortName: Invalid index"); + if ((unsigned)i >= NumEntries) throw FileSystemException("GetShortName: Invalid index"); return FileInfo[i].shortName; } FString& FileSystem::GetLongName(int i) { - if ((unsigned)i >= NumEntries) I_Error("GetLongName: Invalid index"); + if ((unsigned)i >= NumEntries) throw FileSystemException("GetLongName: Invalid index"); return FileInfo[i].longName; } void FileSystem::RenameFile(int num, const char* newfn) { - if ((unsigned)num >= NumEntries) I_Error("RenameFile: Invalid index"); + if ((unsigned)num >= NumEntries) throw FileSystemException("RenameFile: Invalid index"); FileInfo[num].longName = newfn; // This does not alter the short name - call GetShortname to do that! } @@ -1345,7 +1345,7 @@ TArray FileSystem::GetFileData(int lump, int pad) if (numread != size) { - I_Error("GetFileData: only read %ld of %ld on lump %i\n", + throw FileSystemException("GetFileData: only read %ld of %ld on lump %i\n", numread, size, lump); } if (pad > 0) memset(&data[size], 0, pad); @@ -1367,8 +1367,8 @@ void FileSystem::ReadFile (int lump, void *dest) if (numread != size) { - I_Error ("W_ReadFile: only read %ld of %ld on lump %i\n", - numread, size, lump); + throw FileSystemException("W_ReadFile: only read %ld of %ld on '%s'\n", + numread, size, GetLongName(lump).GetChars()); } } @@ -1399,7 +1399,7 @@ FileReader FileSystem::OpenFileReader(int lump) { if ((unsigned)lump >= (unsigned)FileInfo.Size()) { - I_Error("OpenFileReader: %u >= NumEntries", lump); + throw FileSystemException("OpenFileReader: %u >= NumEntries", lump); } auto rl = FileInfo[lump].lump; @@ -1418,7 +1418,7 @@ FileReader FileSystem::ReopenFileReader(int lump, bool alwayscache) { if ((unsigned)lump >= (unsigned)FileInfo.Size()) { - I_Error("ReopenFileReader: %u >= NumEntries", lump); + throw FileSystemException("ReopenFileReader: %u >= NumEntries", lump); } auto rl = FileInfo[lump].lump; @@ -1619,7 +1619,7 @@ FString::FString (ELumpNum lumpnum) if (numread != size) { - I_Error ("ConstructStringFromLump: Only read %ld of %ld bytes on lump %i (%s)\n", + throw FileSystemException("ConstructStringFromLump: Only read %ld of %ld bytes on lump %i (%s)\n", numread, size, lumpnum, fileSystem.GetFileFullName((int)lumpnum)); } } diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index f8ae9b09c..3ccf506d9 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -193,7 +193,15 @@ void *FResourceLump::Lock() } else if (LumpSize > 0) { - FillCache(); + try + { + FillCache(); + } + catch (const FileSystemException& err) + { + // enrich the message with info about this lump. + throw FileSystemException("%s, file '%s': %s", getName(), Owner->FileName.GetChars(), err.what()); + } } return Cache; } @@ -609,7 +617,13 @@ int FUncompressedLump::FillCache() Owner->Reader.Seek(Position, FileReader::SeekSet); Cache = new char[LumpSize]; - Owner->Reader.Read(Cache, LumpSize); + + auto read = Owner->Reader.Read(Cache, LumpSize); + if (read != LumpSize) + { + throw FileSystemException("only read %d of %d bytes", (int)read, (int)LumpSize); + } + RefCount = 1; return 1; } @@ -672,11 +686,15 @@ int FExternalLump::FillCache() if (f.OpenFile(Filename)) { - f.Read(Cache, LumpSize); + auto read = f.Read(Cache, LumpSize); + if (read != LumpSize) + { + throw FileSystemException("only read %d of %d bytes", (int)read, (int)LumpSize); + } } else { - memset(Cache, 0, LumpSize); + throw FileSystemException("unable to open file"); } RefCount = 1; return 1; diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index 65a6a4636..96e0e6ca6 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -190,7 +190,7 @@ struct FUncompressedLump : public FResourceLump int Position; virtual FileReader *GetReader(); - virtual int FillCache(); + virtual int FillCache() override; virtual int GetFileOffset() { return Position; } }; @@ -213,7 +213,7 @@ struct FExternalLump : public FResourceLump FString Filename; FExternalLump(const char *_filename, int filesize = -1); - virtual int FillCache(); + virtual int FillCache() override; }; diff --git a/src/common/utility/engineerrors.h b/src/common/utility/engineerrors.h index 18fe849bc..a8d439f7a 100644 --- a/src/common/utility/engineerrors.h +++ b/src/common/utility/engineerrors.h @@ -59,13 +59,13 @@ public: strncpy (m_Message, message, MAX_ERRORTEXT-1); m_Message[MAX_ERRORTEXT-1] = '\0'; } - void AppendMessage(const char *message) + void AppendMessage(const char *message) noexcept { size_t len = strlen(m_Message); strncpy(m_Message + len, message, MAX_ERRORTEXT - 1 - len); m_Message[MAX_ERRORTEXT - 1] = '\0'; } - const char *GetMessage (void) const + const char *GetMessage (void) const noexcept { if (m_Message[0] != '\0') return (const char *)m_Message; diff --git a/src/common/utility/utf8.h b/src/common/utility/utf8.h index fe883232b..0b5e4ae0a 100644 --- a/src/common/utility/utf8.h +++ b/src/common/utility/utf8.h @@ -1,5 +1,7 @@ #pragma once +#include + int utf8_encode(int32_t codepoint, uint8_t *buffer, int *size); int utf8_decode(const uint8_t *src, int *size); int GetCharFromString(const uint8_t *&string); diff --git a/src/d_main.cpp b/src/d_main.cpp index 7709c046c..0603283e0 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1233,7 +1233,7 @@ void D_DoomLoop () return; } } - catch (CRecoverableError &error) + catch (const CRecoverableError &error) { if (error.GetMessage ()) { @@ -1241,6 +1241,14 @@ void D_DoomLoop () } D_ErrorCleanup (); } + catch (const FileSystemException& error) // in case this propagates up to here it should be treated as a recoverable error. + { + if (error.what()) + { + Printf(PRINT_NONOTIFY | PRINT_BOLD, "\n%s\n", error.what()); + } + D_ErrorCleanup(); + } catch (CVMAbortException &error) { error.MaybePrintMessage(); diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index f57a51b65..1bcd9c34f 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -733,45 +733,36 @@ bool MapLoader::LoadExtendedNodes (FileReader &dalump, uint32_t id) if (compressed) { FileReader zip; - try + if (zip.OpenDecompressor(dalump, -1, METHOD_ZLIB, false, true)) { - if (zip.OpenDecompressor(dalump, -1, METHOD_ZLIB, false, [](const char* err) { I_Error("%s", err); })) - { - LoadZNodes(zip, type); - } - else - { - Printf("Error loading nodes: Corrupt data.\n"); - return false; - } + LoadZNodes(zip, type); + return true; } - catch (const CRecoverableError& err) + else { - Printf("Error loading nodes: %s.\n", err.what()); - - ForceNodeBuild = true; - Level->subsectors.Clear(); - Level->segs.Clear(); - Level->nodes.Clear(); - return false; + Printf("Error loading nodes: Corrupt data.\n"); } } else { LoadZNodes(dalump, type); + return true; } - return true; } catch (CRecoverableError &error) { Printf("Error loading nodes: %s\n", error.GetMessage()); - - ForceNodeBuild = true; - Level->subsectors.Clear(); - Level->segs.Clear(); - Level->nodes.Clear(); - return false; } + catch (FileSystemException& error) + { + Printf("Error loading nodes: %s\n", error.what()); + } + // clean up. + ForceNodeBuild = true; + Level->subsectors.Clear(); + Level->segs.Clear(); + Level->nodes.Clear(); + return false; } @@ -3349,9 +3340,10 @@ void MapLoader::LoadLightmap(MapData *map) return; FileReader fr; - if (!fr.OpenDecompressor(map->Reader(ML_LIGHTMAP), -1, METHOD_ZLIB, false, [](const char* err) { I_Error("%s", err); })) + if (!fr.OpenDecompressor(map->Reader(ML_LIGHTMAP), -1, METHOD_ZLIB, false, false)) return; + int version = fr.ReadInt32(); if (version != 0) { From 2524ea6b0e97c04d7de3b2a31a0e81c000531769 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 18 Aug 2023 21:26:22 +0200 Subject: [PATCH 005/223] - moved linked textures from file system to texture manager. --- src/common/engine/serializer.cpp | 2 +- src/common/filesystem/filesystem.cpp | 31 ---------------- src/common/filesystem/filesystem.h | 5 --- src/common/scripting/interface/vmnatives.cpp | 2 +- src/common/textures/gametexture.cpp | 4 +- src/common/textures/texturemanager.cpp | 39 ++++++++++++++++++-- src/common/textures/texturemanager.h | 9 +++++ 7 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index ec84a5fee..8d5f9a6b8 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -1135,7 +1135,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe const char *name; auto lump = pic->GetSourceLump(); - if (fileSystem.GetLinkedTexture(lump) == pic) + if (TexMan.GetLinkedTexture(lump) == pic) { name = fileSystem.GetFileFullName(lump); } diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index b7c370360..2b300abcf 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -55,7 +55,6 @@ struct FileSystem::LumpRecord { FResourceLump *lump; - FGameTexture* linkedTexture; LumpShortName shortName; FString longName; int rfnum; @@ -67,7 +66,6 @@ struct FileSystem::LumpRecord { lump = lmp; rfnum = filenum; - linkedTexture = nullptr; flags = 0; if (lump->Flags & LUMPF_SHORTNAME) @@ -748,35 +746,6 @@ int FileSystem::GetResource (int resid, const char *type, int filenum) const return i; } -//========================================================================== -// -// link a texture with a given lump -// -//========================================================================== - -void FileSystem::SetLinkedTexture(int lump, FGameTexture *tex) -{ - if ((size_t)lump < NumEntries) - { - FileInfo[lump].linkedTexture = tex; - } -} - -//========================================================================== -// -// retrieve linked texture -// -//========================================================================== - -FGameTexture *FileSystem::GetLinkedTexture(int lump) -{ - if ((size_t)lump < NumEntries) - { - return FileInfo[lump].linkedTexture; - } - return NULL; -} - //========================================================================== // // FileLength diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index fb72d77de..b6ce6bad8 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -16,7 +16,6 @@ class FResourceFile; struct FResourceLump; -class FGameTexture; union LumpShortName { @@ -125,10 +124,6 @@ public: inline int CheckNumForFullName (const FString &name, int wadfile) { return CheckNumForFullName(name.GetChars(), wadfile); } inline int GetNumForFullName (const FString &name) { return GetNumForFullName(name.GetChars()); } - void SetLinkedTexture(int lump, FGameTexture *tex); - FGameTexture *GetLinkedTexture(int lump); - - void ReadFile (int lump, void *dest); TArray GetFileData(int lump, int pad = 0); // reads lump into a writable buffer and optionally adds some padding at the end. (FileData isn't writable!) FileData ReadFile (int lump); diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index 54cc0d2a9..f04e39d45 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -424,7 +424,7 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetName) { // Textures for full path names do not have their own name, they merely link to the source lump. auto lump = tex->GetSourceLump(); - if (fileSystem.GetLinkedTexture(lump) == tex) + if (TexMan.GetLinkedTexture(lump) == tex) retval = fileSystem.GetFileFullName(lump); } } diff --git a/src/common/textures/gametexture.cpp b/src/common/textures/gametexture.cpp index be4063213..3ddc8dd1b 100644 --- a/src/common/textures/gametexture.cpp +++ b/src/common/textures/gametexture.cpp @@ -98,8 +98,8 @@ FGameTexture::~FGameTexture() { if (Base != nullptr) { - FGameTexture* link = fileSystem.GetLinkedTexture(GetSourceLump()); - if (link == this) fileSystem.SetLinkedTexture(GetSourceLump(), nullptr); + FGameTexture* link = TexMan.GetLinkedTexture(GetSourceLump()); + if (link == this) TexMan.SetLinkedTexture(GetSourceLump(), nullptr); } if (SoftwareTexture != nullptr) { diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index 988498408..c149d99b2 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -244,11 +244,11 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset // Any graphic being placed in the zip's root directory can not be found by this. if (strchr(name, '/') || (flags & TEXMAN_ForceLookup)) { - FGameTexture *const NO_TEXTURE = (FGameTexture*)-1; + FGameTexture *const NO_TEXTURE = (FGameTexture*)-1; // marker for lumps we already checked that do not map to a texture. int lump = fileSystem.CheckNumForFullName(name); if (lump >= 0) { - FGameTexture *tex = fileSystem.GetLinkedTexture(lump); + FGameTexture *tex = GetLinkedTexture(lump); if (tex == NO_TEXTURE) return FTextureID(-1); if (tex != NULL) return tex->GetID(); if (flags & TEXMAN_DontCreate) return FTextureID(-1); // we only want to check, there's no need to create a texture if we don't have one yet. @@ -256,13 +256,13 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset if (tex != NULL) { tex->AddAutoMaterials(); - fileSystem.SetLinkedTexture(lump, tex); + SetLinkedTexture(lump, tex); return AddGameTexture(tex); } else { // mark this lump as having no valid texture so that we don't have to retry creating one later. - fileSystem.SetLinkedTexture(lump, NO_TEXTURE); + SetLinkedTexture(lump, NO_TEXTURE); } } } @@ -1627,6 +1627,37 @@ void FTextureManager::Listaliases() } } +//========================================================================== +// +// link a texture with a given lump +// +//========================================================================== + +void FTextureManager::SetLinkedTexture(int lump, FGameTexture* tex) +{ + if ((size_t)lump < fileSystem.GetNumEntries()) + { + linkedMap.Insert(lump, tex); + } +} + +//========================================================================== +// +// retrieve linked texture +// +//========================================================================== + +FGameTexture* FTextureManager::GetLinkedTexture(int lump) +{ + if ((size_t)lump < fileSystem.GetNumEntries()) + { + auto check = linkedMap.CheckKey(lump); + if (check) return *check; + } + return nullptr; +} + + //========================================================================== // // FTextureID::operator+ diff --git a/src/common/textures/texturemanager.h b/src/common/textures/texturemanager.h index 3f80514f3..cf799153f 100644 --- a/src/common/textures/texturemanager.h +++ b/src/common/textures/texturemanager.h @@ -88,6 +88,15 @@ public: } } + //========================================================================== + // + // link a texture with a given lump + // + //========================================================================== + + TMap linkedMap; + void SetLinkedTexture(int lump, FGameTexture* tex); + FGameTexture* GetLinkedTexture(int lump); enum { From 5a32f98bdeda2da7a0e66c58b5bea191fcd4ac62 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 18 Aug 2023 22:46:31 +0200 Subject: [PATCH 006/223] - first stage of uncoupling the file system from the engine. This replaces several FStrings and TArrays with std::string and std::vector. --- src/common/filesystem/file_7z.cpp | 26 +++--- src/common/filesystem/file_directory.cpp | 10 +-- src/common/filesystem/file_lump.cpp | 4 +- src/common/filesystem/file_wad.cpp | 26 +++--- src/common/filesystem/file_zip.cpp | 21 ++--- src/common/filesystem/filesystem.cpp | 8 +- src/common/filesystem/resourcefile.cpp | 103 +++++++++++++++-------- src/common/filesystem/resourcefile.h | 46 ++++++---- src/d_main.cpp | 16 ++-- 9 files changed, 150 insertions(+), 110 deletions(-) diff --git a/src/common/filesystem/file_7z.cpp b/src/common/filesystem/file_7z.cpp index 405e9b919..9b1535be2 100644 --- a/src/common/filesystem/file_7z.cpp +++ b/src/common/filesystem/file_7z.cpp @@ -36,9 +36,7 @@ // Note that 7z made the unwise decision to include windows.h :( #include "7z.h" #include "7zCrc.h" - #include "resourcefile.h" -#include "cmdlib.h" @@ -228,7 +226,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) Archive = NULL; if (res == SZ_ERROR_UNSUPPORTED) { - Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", FileName.c_str()); } else if (res == SZ_ERROR_MEM) { @@ -251,8 +249,8 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) Lumps = new F7ZLump[NumLumps]; F7ZLump *lump_p = Lumps; - TArray nameUTF16; - TArray nameASCII; + std::u16string nameUTF16; + std::string nameASCII; for (uint32_t i = 0; i < NumLumps; ++i) { @@ -271,19 +269,17 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) continue; } - nameUTF16.Resize((unsigned)nameLength); - nameASCII.Resize((unsigned)nameLength); - SzArEx_GetFileNameUtf16(archPtr, i, &nameUTF16[0]); + nameUTF16.resize((unsigned)nameLength); + nameASCII.resize((unsigned)nameLength); + // note that the file system is not equipped to handle non-ASCII, so don't bother with proper Unicode conversion here. + SzArEx_GetFileNameUtf16(archPtr, i, (UInt16*)nameUTF16.data()); for (size_t c = 0; c < nameLength; ++c) { - nameASCII[c] = static_cast(nameUTF16[c]); + nameASCII[c] = tolower(static_cast(nameUTF16[c])); + if (nameASCII[c] == '\\') nameASCII[c] = '/'; } - FixPathSeperator(&nameASCII[0]); - FString name = &nameASCII[0]; - name.ToLower(); - - lump_p->LumpNameSetup(name); + lump_p->LumpNameSetup(nameASCII.c_str()); lump_p->LumpSize = static_cast(SzArEx_GetFileSize(archPtr, i)); lump_p->Owner = this; lump_p->Flags = LUMPF_FULLPATH|LUMPF_COMPRESSED; @@ -303,7 +299,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0])) { - Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", FileName.c_str()); return false; } } diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/file_directory.cpp index 00b1e7a12..688a45aa0 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/file_directory.cpp @@ -84,7 +84,7 @@ public: //========================================================================== FDirectory::FDirectory(const char * directory, bool nosubdirflag) -: FResourceFile(NULL), nosubdir(nosubdirflag) + : FResourceFile(""), nosubdir(nosubdirflag) { FString dirname; @@ -194,7 +194,7 @@ int FDirectory::AddDirectory(const char *dirpath, FileSystemMessageFunc Printf) bool FDirectory::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) { - NumLumps = AddDirectory(FileName, Printf); + NumLumps = AddDirectory(FileName.c_str(), Printf); PostProcessArchive(&Lumps[0], sizeof(FDirectoryLump), filter); return true; } @@ -213,11 +213,11 @@ void FDirectory::AddEntry(const char *fullpath, int size) lump_p->mFullPath = fullpath; // [mxd] Convert name to lowercase - FString name = fullpath + strlen(FileName); - name.ToLower(); + std::string name = fullpath + FileName.length(); + for (auto& c : name) c = tolower(c); // The lump's name is only the part relative to the main directory - lump_p->LumpNameSetup(name); + lump_p->LumpNameSetup(name.c_str()); lump_p->LumpSize = size; lump_p->Owner = this; lump_p->Flags = 0; diff --git a/src/common/filesystem/file_lump.cpp b/src/common/filesystem/file_lump.cpp index 0101aecf4..f16fefaab 100644 --- a/src/common/filesystem/file_lump.cpp +++ b/src/common/filesystem/file_lump.cpp @@ -68,10 +68,8 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file) bool FLumpFile::Open(LumpFilterInfo*) { - FString name(ExtractFileBase(FileName, true)); - Lumps.Resize(1); - Lumps[0].LumpNameSetup(name); + Lumps[0].LumpNameSetup(ExtractBaseName(FileName.c_str(), true).c_str()); Lumps[0].Owner = this; Lumps[0].Position = 0; Lumps[0].LumpSize = (int)Reader.GetLength(); diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/file_wad.cpp index e856212ba..1a256db65 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/file_wad.cpp @@ -181,7 +181,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) // Check again to detect broken wads if (InfoTableOfs + NumLumps*sizeof(wadlump_t) > (unsigned)wadSize) { - Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", FileName.c_str()); return false; } } @@ -201,10 +201,10 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) // This requires explicit toggling for precisely the files that need it. #if 0 Lumps[i].Compressed = !(gameinfo.flags & GI_SHAREWARE) && (n[0] & 0x80) == 0x80; + n[0] &= ~0x80; #else Lumps[i].Compressed = false; #endif - n[0] &= ~0x80; Lumps[i].LumpNameSetup(n); Lumps[i].Owner = this; @@ -218,7 +218,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) { if (Lumps[i].LumpSize != 0) { - Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.GetChars(), Lumps[i].getName()); + Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.c_str(), Lumps[i].getName()); Lumps[i].LumpNameSetup(""); } Lumps[i].LumpSize = Lumps[i].Position = 0; @@ -303,7 +303,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { if (numendmarkers == 0) return; // no markers found - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), endmarker, startmarker); if (flathack) @@ -317,7 +317,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { // We can't add this to the flats namespace but // it needs to be flagged for the texture manager. - Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", FileName.GetChars(), Lumps[ii].getName()); + Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", FileName.c_str(), Lumps[ii].getName()); Lumps[ii].Flags |= LUMPF_MAYBEFLAT; } } @@ -331,7 +331,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name int start, end; if (markers[i].markertype != 0) { - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), endmarker, startmarker); i++; continue; } @@ -340,21 +340,21 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // skip over subsequent x_START markers while (i < markers.Size() && markers[i].markertype == 0) { - Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.GetChars(), startmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.c_str(), startmarker); i++; continue; } // same for x_END markers while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1)) { - Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.GetChars(), endmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.c_str(), endmarker); i++; continue; } // We found a starting marker but no end marker. Ignore this block. if (i >= markers.Size()) { - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.GetChars(), startmarker, endmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), startmarker, endmarker); end = NumLumps; } else @@ -363,14 +363,14 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name } // we found a marked block - Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", FileName.GetChars(), startmarker, markers[start].index, end); + Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", FileName.c_str(), startmarker, markers[start].index, end); for(int j = markers[start].index + 1; j < end; j++) { if (Lumps[j].Namespace != ns_global) { if (!warned) { - Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", FileName.GetChars(), j); + Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", FileName.c_str(), j); } warned = true; } @@ -380,7 +380,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // ignore sprite lumps smaller than 8 bytes (the smallest possible) // in size -- this was used by some dmadds wads // as an 'empty' graphics resource - Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", FileName.GetChars(), Lumps[j].getName(), j); + Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", FileName.c_str(), Lumps[j].getName(), j); } else { @@ -450,7 +450,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf) } if (skinned && hasmap) { - Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", FileName.GetChars()); + Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", FileName.c_str()); Printf(FSMessageLevel::Attention, "You should remove the skin from the wad to play these maps.\n"); } } diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index 355fefa97..55e4081fe 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -179,7 +179,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (centraldir == 0) { - Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", FileName.c_str()); return false; } @@ -195,7 +195,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.c_str()); return false; } @@ -214,7 +214,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.c_str()); return false; } @@ -253,7 +253,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.c_str()); return false; } @@ -267,7 +267,8 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (!foundprefix) { // check for special names, if one of these gets found this must be treated as a normal zip. - bool isspecial = name.IndexOf("/") < 0 || (filter && filter->reservedFolders.Find(name) < filter->reservedFolders.Size()); + bool isspecial = name.IndexOf("/") < 0 || + (filter && std::find(filter->reservedFolders.begin(), filter->reservedFolders.end(), name.GetChars()) != filter->reservedFolders.end()); if (isspecial) break; name0 = name.Left(name.LastIndexOf("/")+1); name1 = name.Left(name.IndexOf("/") + 1); @@ -292,7 +293,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) // at least one of the more common definition lumps must be present. for (auto &p : filter->requiredPrefixes) { - if (name.IndexOf(name0 + p) == 0 || name.LastIndexOf(p) == ptrdiff_t(name.Len() - strlen(p))) + if (name.IndexOf(name0 + p.c_str()) == 0 || name.LastIndexOf(p.c_str()) == ptrdiff_t(name.Len() - p.length())) { foundspeciallump = true; break; @@ -319,7 +320,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.GetChars()); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.c_str()); return false; } @@ -346,7 +347,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Method != METHOD_IMPLODE && zip_fh->Method != METHOD_SHRINK) { - Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.GetChars(), name.GetChars(), zip_fh->Method); + Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.c_str(), name.GetChars(), zip_fh->Method); skipped++; continue; } @@ -354,7 +355,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Flags = LittleShort(zip_fh->Flags); if (zip_fh->Flags & ZF_ENCRYPTED) { - Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName.GetChars(), name.GetChars()); + Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName.c_str(), name.GetChars()); skipped++; continue; } @@ -381,7 +382,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (zip_64->CompressedSize > 0x7fffffff || zip_64->UncompressedSize > 0x7fffffff) { // The file system is limited to 32 bit file sizes; - Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName.GetChars(), name.GetChars()); + Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName.c_str(), name.GetChars()); skipped++; continue; } diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 2b300abcf..7e6964632 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -233,7 +233,7 @@ bool FileSystem::InitMultipleFiles (TArray &filenames, LumpFilterInfo* AddFile (filenames[i], nullptr, filter, Printf, hashfile); if (i == (unsigned)MaxIwadIndex) MoveLumpsInFolder("after_iwad/"); - FStringf path("filter/%s", Files.Last()->GetHash().GetChars()); + FStringf path("filter/%s", Files.Last()->GetHash()); MoveLumpsInFolder(path); } @@ -1449,9 +1449,9 @@ const char *FileSystem::GetResourceFileName (int rfnum) const noexcept return NULL; } - name = Files[rfnum]->FileName; + name = Files[rfnum]->FileName.c_str(); slash = strrchr (name, '/'); - return (slash != NULL && slash[1] != 0) ? slash+1 : name; + return (slash != nullptr && slash[1] != 0) ? slash+1 : name; } //========================================================================== @@ -1515,7 +1515,7 @@ const char *FileSystem::GetResourceFileFullName (int rfnum) const noexcept return nullptr; } - return Files[rfnum]->FileName; + return Files[rfnum]->FileName.c_str(); } diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index 3ccf506d9..5b0dfdc3c 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -40,6 +40,42 @@ #include "md5.h" +std::string ExtractBaseName(const char* path, bool include_extension) +{ + const char* src, * dot; + + src = path + strlen(path) - 1; + + if (src >= path) + { + // back up until a / or the start + while (src != path && src[-1] != '/' && src[-1] != '\\') // check both on all systems for consistent behavior with archives. + src--; + + if (!include_extension && (dot = strrchr(src, '.'))) + { + return std::string(src, dot - src); + } + else + { + return std::string(src); + } + } + return std::string(); +} + +void strReplace(std::string& str, const char *from, const char* to) +{ + if (*from == 0) + return; + size_t start_pos = 0; + while ((start_pos = str.find(from, start_pos)) != std::string::npos) + { + str.replace(start_pos, strlen(from), to); + start_pos += strlen(to); + } +} + //========================================================================== // // File reader that reads from a lump's cache @@ -88,10 +124,10 @@ FResourceLump::~FResourceLump() // //========================================================================== -void FResourceLump::LumpNameSetup(FString iname) +void FResourceLump::LumpNameSetup(const char *iname) { // this causes interference with real Dehacked lumps. - if (!iname.CompareNoCase("dehacked.exe")) + if (!stricmp(iname, "dehacked.exe")) { iname = ""; } @@ -115,24 +151,24 @@ static bool IsWadInFolder(const FResourceFile* const archive, const char* const return false; } - const FString dirName = ExtractFileBase(archive->FileName); - const FString fileName = ExtractFileBase(resPath, true); - const FString filePath = dirName + '/' + fileName; + const auto dirName = ExtractBaseName(archive->FileName.c_str()); + const auto fileName = ExtractBaseName(resPath, true); + const std::string filePath = dirName + '/' + fileName; - return 0 == filePath.CompareNoCase(resPath); + return 0 == stricmp(filePath.c_str(), resPath); } void FResourceLump::CheckEmbedded(LumpFilterInfo* lfi) { // Checks for embedded archives - const char *c = strstr(FullName, ".wad"); - if (c && strlen(c) == 4 && (!strchr(FullName, '/') || IsWadInFolder(Owner, FullName))) + const char *c = strstr(FullName.c_str(), ".wad"); + if (c && strlen(c) == 4 && (!strchr(FullName.c_str(), '/') || IsWadInFolder(Owner, FullName.c_str()))) { Flags |= LUMPF_EMBEDDED; } else if (lfi) for (auto& fstr : lfi->embeddings) { - if (!stricmp(FullName, fstr)) + if (!stricmp(FullName.c_str(), fstr.c_str())) { Flags |= LUMPF_EMBEDDED; } @@ -200,7 +236,7 @@ void *FResourceLump::Lock() catch (const FileSystemException& err) { // enrich the message with info about this lump. - throw FileSystemException("%s, file '%s': %s", getName(), Owner->FileName.GetChars(), err.what()); + throw FileSystemException("%s, file '%s': %s", getName(), Owner->FileName.c_str(), err.what()); } } return Cache; @@ -323,7 +359,7 @@ void FResourceFile::GenerateHash() { // hash the lump directory after sorting - Hash.Format(("%08X-%04X-"), (unsigned)Reader.GetLength(), NumLumps); + auto n = snprintf(Hash, 48, "%08X-%04X-", (unsigned)Reader.GetLength(), NumLumps); MD5Context md5; @@ -331,13 +367,13 @@ void FResourceFile::GenerateHash() for(uint32_t i = 0; i < NumLumps; i++) { auto lump = GetLump(i); - md5.Update((const uint8_t*)lump->FullName.GetChars(), (unsigned)lump->FullName.Len() + 1); + md5.Update((const uint8_t*)lump->FullName.c_str(), (unsigned)lump->FullName.length() + 1); md5.Update((const uint8_t*)&lump->LumpSize, 4); } md5.Final(digest); for (auto c : digest) { - Hash.AppendFormat("%02X", c); + n += snprintf(Hash + n, 3, "%02X", c); } } @@ -366,11 +402,11 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterI ptrdiff_t len; ptrdiff_t lastpos = -1; - FString file; - FString LumpFilter = filter->dotFilter; - while ((len = LumpFilter.IndexOf('.', lastpos+1)) > 0) + std::string file; + std::string& LumpFilter = filter->dotFilter; + while ((len = LumpFilter.find_first_of('.', lastpos+1)) != LumpFilter.npos) { - max -= FilterLumps(LumpFilter.Left(len), lumps, lumpsize, max); + max -= FilterLumps(std::string(LumpFilter, 0, len), lumps, lumpsize, max); lastpos = len; } max -= FilterLumps(LumpFilter, lumps, lumpsize, max); @@ -388,24 +424,23 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterI // //========================================================================== -int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize, uint32_t max) +int FResourceFile::FilterLumps(const std::string& filtername, void *lumps, size_t lumpsize, uint32_t max) { - FString filter; uint32_t start, end; - if (filtername.IsEmpty()) + if (filtername.empty()) { return 0; } - filter << "filter/" << filtername << '/'; + std::string filter = "filter/" + filtername + '/'; - bool found = FindPrefixRange(filter, lumps, lumpsize, max, start, end); + bool found = FindPrefixRange(filter.c_str(), lumps, lumpsize, max, start, end); - // Workaround for old Doom filter names. - if (!found && filtername.IndexOf("doom.id.doom") == 0) + // Workaround for old Doom filter names (todo: move out of here.) + if (!found && filtername.find_first_of("doom.id.doom") == 0) { - filter.Substitute("doom.id.doom", "doom.doom"); - found = FindPrefixRange(filter, lumps, lumpsize, max, start, end); + strReplace(filter, "doom.id.doom", "doom.doom"); + found = FindPrefixRange(filter.c_str(), lumps, lumpsize, max, start, end); } if (found) @@ -417,8 +452,8 @@ int FResourceFile::FilterLumps(FString filtername, void *lumps, size_t lumpsize, for (uint32_t i = start; i < end; ++i, lump_p = (uint8_t *)lump_p + lumpsize) { FResourceLump *lump = (FResourceLump *)lump_p; - assert(lump->FullName.CompareNoCase(filter, (int)filter.Len()) == 0); - lump->LumpNameSetup(lump->FullName.Mid(filter.Len())); + assert(strnicmp(lump->FullName.c_str(), filter.c_str(), filter.length()) == 0); + lump->LumpNameSetup(lump->FullName.c_str() + filter.length()); } // Move filtered lumps to the end of the lump list. @@ -502,7 +537,7 @@ void FResourceFile::JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t m // //========================================================================== -bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize, uint32_t maxlump, uint32_t &start, uint32_t &end) +bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lumpsize, uint32_t maxlump, uint32_t &start, uint32_t &end) { uint32_t min, max, mid, inside; FResourceLump *lump; @@ -520,7 +555,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len()); + cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); if (cmp == 0) break; else if (cmp < 0) @@ -540,7 +575,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len()); + cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); // Go left on matches and right on misses. if (cmp == 0) max = mid - 1; @@ -555,7 +590,7 @@ bool FResourceFile::FindPrefixRange(FString filter, void *lumps, size_t lumpsize { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = lump->FullName.CompareNoCase(filter, (int)filter.Len()); + cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); // Go right on matches and left on misses. if (cmp == 0) min = mid + 1; @@ -577,7 +612,7 @@ FResourceLump *FResourceFile::FindLump(const char *name) for (unsigned i = 0; i < NumLumps; i++) { FResourceLump *lump = GetLump(i); - if (!stricmp(name, lump->FullName)) + if (!stricmp(name, lump->FullName.c_str())) { return lump; } @@ -684,7 +719,7 @@ int FExternalLump::FillCache() Cache = new char[LumpSize]; FileReader f; - if (f.OpenFile(Filename)) + if (f.OpenFile(Filename.c_str())) { auto read = f.Read(Cache, LumpSize); if (read != LumpSize) diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index 96e0e6ca6..ff785747b 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -4,20 +4,23 @@ #define __RESFILE_H #include - +#include +#include #include "files.h" -#include "zstring.h" + +std::string ExtractBaseName(const char* path, bool include_extension = false); +void strReplace(std::string& str, const char* from, const char* to); // user context in which the file system gets opened. This also contains a few callbacks to avoid direct dependencies on the engine. struct LumpFilterInfo { - TArray gameTypeFilter; // this can contain multiple entries - FString dotFilter; + std::vector gameTypeFilter; // this can contain multiple entries + std::string dotFilter; // The following are for checking if the root directory of a zip can be removed. - TArray reservedFolders; - TArray requiredPrefixes; - TArray embeddings; + std::vector reservedFolders; + std::vector requiredPrefixes; + std::vector embeddings; std::function postprocessFunc; }; @@ -107,7 +110,7 @@ struct FResourceLump int LumpSize; int RefCount; protected: - FString FullName; + std::string FullName; public: uint8_t Flags; char * Cache; @@ -127,7 +130,7 @@ public: virtual int GetFileOffset() { return -1; } virtual int GetIndexNum() const { return -1; } virtual int GetNamespace() const { return 0; } - void LumpNameSetup(FString iname); + void LumpNameSetup(const char* iname); void CheckEmbedded(LumpFilterInfo* lfi); virtual FCompressedBuffer GetRawData(); @@ -136,7 +139,7 @@ public: unsigned Size() const{ return LumpSize; } int LockCount() const { return RefCount; } - const char* getName() { return FullName.GetChars(); } + const char* getName() { return FullName.c_str(); } protected: virtual int FillCache() { return -1; } @@ -147,10 +150,10 @@ class FResourceFile { public: FileReader Reader; - FString FileName; + std::string FileName; protected: uint32_t NumLumps; - FString Hash; + char Hash[48]; FResourceFile(const char *filename); FResourceFile(const char *filename, FileReader &r); @@ -159,12 +162,23 @@ protected: void GenerateHash(); void PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterInfo *filter); + void FixPathSeparator(char* path) + { + while (*path) + { + if (*path == '\\') + *path = '/'; + path++; + } + } + + private: uint32_t FirstLump; - int FilterLumps(FString filtername, void *lumps, size_t lumpsize, uint32_t max); + int FilterLumps(const std::string& filtername, void *lumps, size_t lumpsize, uint32_t max); int FilterLumpsByGameType(LumpFilterInfo *filter, void *lumps, size_t lumpsize, uint32_t max); - bool FindPrefixRange(FString filter, void *lumps, size_t lumpsize, uint32_t max, uint32_t &start, uint32_t &end); + bool FindPrefixRange(const char* filter, void *lumps, size_t lumpsize, uint32_t max, uint32_t &start, uint32_t &end); void JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t max); static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf); @@ -178,7 +192,7 @@ public: uint32_t LumpCount() const { return NumLumps; } uint32_t GetFirstEntry() const { return FirstLump; } void SetFirstLump(uint32_t f) { FirstLump = f; } - const FString &GetHash() const { return Hash; } + const char* GetHash() const { return Hash; } virtual FResourceLump *GetLump(int no) = 0; @@ -210,7 +224,7 @@ protected: struct FExternalLump : public FResourceLump { - FString Filename; + std::string Filename; FExternalLump(const char *_filename, int filesize = -1); virtual int FillCache() override; diff --git a/src/d_main.cpp b/src/d_main.cpp index 0603283e0..937f04bc8 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -202,11 +202,6 @@ extern bool insave; extern TDeletingArray LightDefaults; extern FName MessageBoxClass; -static const char* iwad_folders[] = { "flats/", "textures/", "hires/", "sprites/", "voxels/", "colormaps/", "acs/", "maps/", "voices/", "patches/", "graphics/", "sounds/", "music/", - "materials/", "models/", "fonts/", "brightmaps/"}; -static const char* iwad_reserved[] = { "mapinfo", "zmapinfo", "umapinfo", "gameinfo", "sndinfo", "sndseq", "sbarinfo", "menudef", "gldefs", "animdefs", "decorate", "zscript", "iwadinfo", "maps/" }; - - CUSTOM_CVAR(Float, i_timescale, 1.0f, CVAR_NOINITCALL | CVAR_VIRTUAL) { if (netgame) @@ -1920,8 +1915,9 @@ static FString ParseGameInfo(TArray &pwads, const char *fn, const char void GetReserved(LumpFilterInfo& lfi) { - for (auto p : iwad_folders) lfi.reservedFolders.Push(p); - for (auto p : iwad_reserved) lfi.requiredPrefixes.Push(p); + lfi.reservedFolders = { "flats/", "textures/", "hires/", "sprites/", "voxels/", "colormaps/", "acs/", "maps/", "voices/", "patches/", "graphics/", "sounds/", "music/", + "materials/", "models/", "fonts/", "brightmaps/" }; + lfi.requiredPrefixes = { "mapinfo", "zmapinfo", "umapinfo", "gameinfo", "sndinfo", "sndseq", "sbarinfo", "menudef", "gldefs", "animdefs", "decorate", "zscript", "iwadinfo", "maps/" }; } static FString CheckGameInfo(TArray & pwads) @@ -3065,7 +3061,7 @@ static int FileSystemPrintf(FSMessageLevel level, const char* fmt, ...) DPrintf(DMSG_NOTIFY, "%s", text.GetChars()); break; } - return text.Len(); + return (int)text.Len(); } //========================================================================== // @@ -3138,9 +3134,9 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray& allwads, TArr for (auto& inf : blanket) { - if (gameinfo.gametype & inf.match) lfi.gameTypeFilter.Push(inf.name); + if (gameinfo.gametype & inf.match) lfi.gameTypeFilter.push_back(inf.name); } - lfi.gameTypeFilter.Push(FStringf("game-%s", GameTypeName())); + lfi.gameTypeFilter.push_back(FStringf("game-%s", GameTypeName()).GetChars()); GetReserved(lfi); From 219b3fb9f93eef7f8a6367141ccd6d7f8143ecad Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 09:24:33 +0200 Subject: [PATCH 007/223] - uncoupled directory loader from the rest of the engine. --- src/CMakeLists.txt | 1 + src/common/filesystem/file_directory.cpp | 108 ++++++----- src/common/filesystem/files.cpp | 9 +- src/common/filesystem/fs_findfile.cpp | 232 +++++++++++++++++++++++ src/common/filesystem/fs_findfile.h | 98 ++++++++++ src/common/filesystem/resourcefile.h | 2 + src/common/filesystem/w_zip.h | 15 +- src/d_main.cpp | 20 ++ 8 files changed, 430 insertions(+), 55 deletions(-) create mode 100644 src/common/filesystem/fs_findfile.cpp create mode 100644 src/common/filesystem/fs_findfile.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 518235f66..a35b048bf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1221,6 +1221,7 @@ set( ZDOOM_SOURCES common/filesystem/resourcefile.cpp common/filesystem/files.cpp common/filesystem/files_decompress.cpp + common/filesystem/fs_findfile.cpp ) diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/file_directory.cpp index 688a45aa0..51801c166 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/file_directory.cpp @@ -37,8 +37,11 @@ #include #include "resourcefile.h" -#include "cmdlib.h" -#include "findfile.h" +#include "fs_findfile.h" + +#ifdef _WIN32 +std::wstring toWide(const char* str); +#endif //========================================================================== // @@ -51,7 +54,7 @@ struct FDirectoryLump : public FResourceLump FileReader NewReader() override; int FillCache() override; - FString mFullPath; + std::string mFullPath; }; @@ -66,7 +69,7 @@ class FDirectory : public FResourceFile TArray Lumps; const bool nosubdir; - int AddDirectory(const char* dirpath, FileSystemMessageFunc Printf); + int AddDirectory(const char* dirpath, LumpFilterInfo* filter, FileSystemMessageFunc Printf); void AddEntry(const char *fullpath, int size); public: @@ -86,39 +89,47 @@ public: FDirectory::FDirectory(const char * directory, bool nosubdirflag) : FResourceFile(""), nosubdir(nosubdirflag) { - FString dirname; - - #ifdef _WIN32 - directory = _fullpath(NULL, directory, _MAX_PATH); - #else - // Todo for Linux: Resolve the path before using it - #endif - dirname = directory; -#ifdef _WIN32 - free((void *)directory); -#endif - dirname.Substitute("\\", "/"); - if (dirname[dirname.Len()-1] != '/') dirname += '/'; - FileName = dirname; + FileName = FS_FullPath(directory); + if (FileName[FileName.length()-1] != '/') FileName += '/'; } - //========================================================================== // // Windows version // //========================================================================== -int FDirectory::AddDirectory(const char *dirpath, FileSystemMessageFunc Printf) +static bool FS_GetFileInfo(const char* pathname, size_t* size) +{ +#ifndef _WIN32 + struct stat info; + bool res = stat(pathname, &info) == 0; +#else + // Windows must use the wide version of stat to preserve non-ASCII paths. + struct _stat64 info; + bool res = _wstat64(toWide(pathname).c_str(), &info) == 0; +#endif + if (!res || (info.st_mode & S_IFDIR)) return false; + if (size) *size = (size_t)info.st_size; + return res; +} + +//========================================================================== +// +// Windows version +// +//========================================================================== + +int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { void * handle; int count = 0; - FString dirmatch = dirpath; - findstate_t find; + std::string dirmatch = dirpath; dirmatch += '*'; + fs_findstate_t find; - handle = I_FindFirst(dirmatch.GetChars(), &find); + handle = FS_FindFirst(dirmatch.c_str(), &find); if (handle == ((void *)(-1))) { Printf(FSMessageLevel::Error, "Could not scan '%s': %s\n", dirpath, strerror(errno)); @@ -127,15 +138,15 @@ int FDirectory::AddDirectory(const char *dirpath, FileSystemMessageFunc Printf) { do { - // I_FindName only returns the file's name and not its full path - auto attr = I_FindAttr(&find); + // FS_FindName only returns the file's name and not its full path + auto attr = FS_FindAttr(&find); if (attr & FA_HIDDEN) { - // Skip hidden files and directories. (Prevents SVN bookkeeping + // Skip hidden files and directories. (Prevents SVN/Git bookkeeping // info from being included.) continue; } - FString fi = I_FindName(&find); + const char* fi = FS_FindName(&find); if (attr & FA_DIREC) { if (nosubdir || (fi[0] == '.' && @@ -145,9 +156,10 @@ int FDirectory::AddDirectory(const char *dirpath, FileSystemMessageFunc Printf) // Do not record . and .. directories. continue; } - FString newdir = dirpath; - newdir << fi << '/'; - count += AddDirectory(newdir, Printf); + std::string newdir = dirpath; + newdir += fi; + newdir += '/'; + count += AddDirectory(newdir.c_str(), filter, Printf); } else { @@ -157,31 +169,25 @@ int FDirectory::AddDirectory(const char *dirpath, FileSystemMessageFunc Printf) continue; } size_t size = 0; - FString fn = FString(dirpath) + fi; + std::string fn = dirpath; + fn += fi; - // The next one is courtesy of EDuke32. :( - // Putting cache files in the application directory is very bad style. - // Unfortunately, having a garbage file named "texture" present will cause serious problems down the line. - if (!stricmp(fi, "textures")) + if (filter->filenamecheck == nullptr || filter->filenamecheck(fi, fn.c_str())) { - FILE* f = fopen(fn, "rb"); - if (f) + if (FS_GetFileInfo(fn.c_str(), &size)) { - char check[3]{}; - fread(check, 1, 3, f); - if (!memcmp(check, "LZ4", 3)) continue; + if (size > 0x7fffffff) + { + Printf(FSMessageLevel::Warning, "%s is larger than 2GB and will be ignored\n", fn.c_str()); + } + AddEntry(fn.c_str(), (int)size); + count++; } } - - if (GetFileInfo(fn, &size, nullptr)) - { - AddEntry(fn, (int)size); - count++; - } } - } while (I_FindNext (handle, &find) == 0); - I_FindClose (handle); + } while (FS_FindNext (handle, &find) == 0); + FS_FindClose (handle); } return count; } @@ -194,7 +200,7 @@ int FDirectory::AddDirectory(const char *dirpath, FileSystemMessageFunc Printf) bool FDirectory::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) { - NumLumps = AddDirectory(FileName.c_str(), Printf); + NumLumps = AddDirectory(FileName.c_str(), filter, Printf); PostProcessArchive(&Lumps[0], sizeof(FDirectoryLump), filter); return true; } @@ -234,7 +240,7 @@ void FDirectory::AddEntry(const char *fullpath, int size) FileReader FDirectoryLump::NewReader() { FileReader fr; - fr.OpenFile(mFullPath); + fr.OpenFile(mFullPath.c_str()); return fr; } @@ -248,7 +254,7 @@ int FDirectoryLump::FillCache() { FileReader fr; Cache = new char[LumpSize]; - if (!fr.OpenFile(mFullPath)) + if (!fr.OpenFile(mFullPath.c_str())) { throw FileSystemException("unable to open file"); } diff --git a/src/common/filesystem/files.cpp b/src/common/filesystem/files.cpp index cbefc7bbc..094bd8a99 100644 --- a/src/common/filesystem/files.cpp +++ b/src/common/filesystem/files.cpp @@ -33,18 +33,21 @@ ** */ +#include #include "files.h" -#include "utf8.h" #include "stb_sprintf.h" +#ifdef _WIN32 +std::wstring toWide(const char* str); +#endif FILE *myfopen(const char *filename, const char *flags) { #ifndef _WIN32 return fopen(filename, flags); #else - auto widename = WideString(filename); - auto wideflags = WideString(flags); + auto widename = toWide(filename); + auto wideflags = toWide(flags); return _wfopen(widename.c_str(), wideflags.c_str()); #endif } diff --git a/src/common/filesystem/fs_findfile.cpp b/src/common/filesystem/fs_findfile.cpp new file mode 100644 index 000000000..7e47b33f4 --- /dev/null +++ b/src/common/filesystem/fs_findfile.cpp @@ -0,0 +1,232 @@ +/* +** findfile.cpp +** Wrapper around the native directory scanning APIs +** +**--------------------------------------------------------------------------- +** Copyright 1998-2016 Randy Heit +** Copyright 2005-2020 Christoph Oelckers +** +** 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. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "fs_findfile.h" + +#ifndef _WIN32 + +#include +#include +#include + +static const char *pattern; + +static int matchfile(const struct dirent *ent) +{ + return fnmatch(pattern, ent->d_name, FNM_NOESCAPE) == 0; +} + +void *FS_FindFirst(const char *const filespec, fs_findstate_t *const fileinfo) +{ + const char* dir; + + const char *const slash = strrchr(filespec, '/'); + + if (slash) + { + pattern = slash + 1; + fileinfo->path = std::string(filespec, slash - filespec + 1); + dir = fileinfo->path.c_str(); + } + else + { + pattern = filespec; + dir = "."; + } + + fileinfo->current = 0; + fileinfo->count = scandir(dir, &fileinfo->namelist, matchfile, alphasort); + + if (fileinfo->count > 0) + { + return fileinfo; + } + + return (void *)-1; +} + +int FS_FindNext(void *const handle, fs_findstate_t *const fileinfo) +{ + fs_findstate_t *const state = static_cast(handle); + + if (state->current < fileinfo->count) + { + return ++state->current < fileinfo->count ? 0 : -1; + } + + return -1; +} + +int FS_FindClose(void *const handle) +{ + fs_findstate_t *const state = static_cast(handle); + + if (handle != (void *)-1 && state->count > 0) + { + for (int i = 0; i < state->count; ++i) + { + free(state->namelist[i]); + } + + free(state->namelist); + state->namelist = nullptr; + state->count = 0; + } + + return 0; +} + +static bool DirEntryExists(const char* pathname, bool* isdir) +{ + if (isdir) *isdir = false; + struct stat info; + bool res = stat(pathname, &info) == 0; + if (isdir) *isdir = !!(info.st_mode & S_IFDIR); + return res; +} + +int FS_FindAttr(fs_findstate_t *const fileinfo) +{ + dirent *const ent = fileinfo->namelist[fileinfo->current]; + const std::string path = fileinfo->path + ent->d_name; + bool isdir; + + if (DirEntryExists(path.c_str(), &isdir)) + { + return isdir ? FA_DIREC : 0; + } + + return 0; +} + +std::string FS_FullPath(const char* directory) +{ + // todo + return directory +} + +#else + +#include +#include + +std::wstring toWide(const char* str) +{ + int len = (int)strlen(str); + int size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, nullptr, 0); + std::wstring wide; + wide.resize(size_needed); + MultiByteToWideChar(CP_UTF8, 0, str, len, &wide.front(), size_needed); + return wide; +} + +static std::string toUtf8(const wchar_t* str) +{ + auto len = wcslen(str); + int size_needed = WideCharToMultiByte(CP_UTF8, 0, str, (int)len, nullptr, 0, nullptr, nullptr); + std::string utf8; + utf8.resize(size_needed); + WideCharToMultiByte(CP_UTF8, 0, str, (int)len, &utf8.front(), size_needed, nullptr, nullptr); + return utf8; +} + +//========================================================================== +// +// FS_FindFirst +// +// Start a pattern matching sequence. +// +//========================================================================== + + +void *FS_FindFirst(const char *filespec, fs_findstate_t *fileinfo) +{ + static_assert(sizeof(WIN32_FIND_DATAW) == sizeof(fileinfo->FindData), "FindData size mismatch"); + fileinfo->UTF8Name = ""; + return FindFirstFileW(toWide(filespec).c_str(), (LPWIN32_FIND_DATAW)&fileinfo->FindData); +} + +//========================================================================== +// +// FS_FindNext +// +// Return the next file in a pattern matching sequence. +// +//========================================================================== + +int FS_FindNext(void *handle, fs_findstate_t *fileinfo) +{ + fileinfo->UTF8Name = ""; + return FindNextFileW((HANDLE)handle, (LPWIN32_FIND_DATAW)&fileinfo->FindData) == 0; +} + +//========================================================================== +// +// FS_FindClose +// +// Finish a pattern matching sequence. +// +//========================================================================== + +int FS_FindClose(void *handle) +{ + return FindClose((HANDLE)handle); +} + +//========================================================================== +// +// FS_FindName +// +// Returns the name for an entry +// +//========================================================================== + +const char *FS_FindName(fs_findstate_t *fileinfo) +{ + if (fileinfo->UTF8Name.empty()) + { + fileinfo->UTF8Name = toUtf8(fileinfo->FindData.Name); + } + return fileinfo->UTF8Name.c_str(); +} + +std::string FS_FullPath(const char* directory) +{ + auto wdirectory = _wfullpath(nullptr, toWide(directory).c_str(), _MAX_PATH); + std::string sdirectory = toUtf8(wdirectory); + free((void*)wdirectory); + for (auto& c : sdirectory) if (c == '\\') c = '/'; + return sdirectory; +} +#endif diff --git a/src/common/filesystem/fs_findfile.h b/src/common/filesystem/fs_findfile.h new file mode 100644 index 000000000..528c428c3 --- /dev/null +++ b/src/common/filesystem/fs_findfile.h @@ -0,0 +1,98 @@ +#pragma once +// Directory searching routines + +#include +#include + +enum +{ + ZPATH_MAX = 260 +}; + +#ifndef _WIN32 + +#include + +struct fs_findstate_t +{ +private: + std::string path; + struct dirent **namelist; + int current; + int count; + + friend void *FS_FindFirst(const char *filespec, fs_findstate_t *fileinfo); + friend int FS_FindNext(void *handle, fs_findstate_t *fileinfo); + friend const char *FS_FindName(fs_findstate_t *fileinfo); + friend int FS_FindAttr(fs_findstate_t *fileinfo); + friend int FS_FindClose(void *handle); +}; + +int FS_FindAttr (fs_findstate_t *fileinfo); + +inline const char *FS_FindName(fs_findstate_t *fileinfo) +{ + return (fileinfo->namelist[fileinfo->current]->d_name); +} + +enum +{ + FA_RDONLY = 1, + FA_HIDDEN = 2, + FA_SYSTEM = 4, + FA_DIREC = 8, + FA_ARCH = 16, +}; + + +#else + + +struct fs_findstate_t +{ +private: + struct FileTime + { + uint32_t lo, hi; + }; + // Mirror WIN32_FIND_DATAW in . We cannot pull in the Windows header here as it would pollute all consumers' symbol space. + struct WinData + { + uint32_t Attribs; + FileTime Times[3]; + uint32_t Size[2]; + uint32_t Reserved[2]; + wchar_t Name[ZPATH_MAX]; + wchar_t AltName[14]; + }; + WinData FindData; + std::string UTF8Name; + + friend void *FS_FindFirst(const char *filespec, fs_findstate_t *fileinfo); + friend int FS_FindNext(void *handle, fs_findstate_t *fileinfo); + friend const char *FS_FindName(fs_findstate_t *fileinfo); + friend int FS_FindAttr(fs_findstate_t *fileinfo); +}; + + +const char *FS_FindName(fs_findstate_t *fileinfo); +inline int FS_FindAttr(fs_findstate_t *fileinfo) +{ + return fileinfo->FindData.Attribs; +} + +enum +{ + FA_RDONLY = 1, + FA_HIDDEN = 2, + FA_SYSTEM = 4, + FA_DIREC = 16, + FA_ARCH = 32, +}; + +#endif + +void *FS_FindFirst (const char *filespec, fs_findstate_t *fileinfo); +int FS_FindNext (void *handle, fs_findstate_t *fileinfo); +int FS_FindClose (void *handle); +std::string FS_FullPath(const char* directory); diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index ff785747b..b2a81ac26 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -21,6 +21,8 @@ struct LumpFilterInfo std::vector reservedFolders; std::vector requiredPrefixes; std::vector embeddings; + std::vector blockednames; // File names that will never be accepted (e.g. dehacked.exe for Doom) + std::function filenamecheck; // for scanning directories, this allows to eliminate unwanted content. std::function postprocessFunc; }; diff --git a/src/common/filesystem/w_zip.h b/src/common/filesystem/w_zip.h index ddc065f07..c0905cd20 100644 --- a/src/common/filesystem/w_zip.h +++ b/src/common/filesystem/w_zip.h @@ -1,7 +1,11 @@ #ifndef __W_ZIP #define __W_ZIP -#include "basics.h" +#if defined(__GNUC__) +#define FORCE_PACKED __attribute__((__packed__)) +#else +#define FORCE_PACKED +#endif #pragma pack(1) // FZipCentralInfo @@ -85,6 +89,15 @@ struct FZipLocalFileHeader #pragma pack() +#ifndef MAKE_ID +#ifndef __BIG_ENDIAN__ +#define MAKE_ID(a,b,c,d) ((uint32_t)((a)|((b)<<8)|((c)<<16)|((d)<<24))) +#else +#define MAKE_ID(a,b,c,d) ((uint32_t)((d)|((c)<<8)|((b)<<16)|((a)<<24))) +#endif +#endif + + #define ZIP_LOCALFILE MAKE_ID('P','K',3,4) #define ZIP_CENTRALFILE MAKE_ID('P','K',1,2) #define ZIP_ENDOFDIR MAKE_ID('P','K',5,6) diff --git a/src/d_main.cpp b/src/d_main.cpp index 937f04bc8..d96467158 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -3034,6 +3034,26 @@ static FILE* D_GetHashFile() return hashfile; } +// checks if a file within a directory is allowed to be added to the file system. +static bool FileNameCheck(const char* base, const char* path) +{ + // This one is courtesy of EDuke32. :( + // Putting cache files in the application directory is very bad style. + // Unfortunately, having a garbage file named "textures" present will cause serious problems down the line. + if (!strnicmp(base, "textures", 8)) + { + // do not use fopen. The path may contain non-ASCII characters. + FileReader f; + if (f.OpenFile(path)) + { + char check[3]{}; + f.Read(check, 3); + if (!memcmp(check, "LZ4", 3)) return false; + } + } + return true; +} + static int FileSystemPrintf(FSMessageLevel level, const char* fmt, ...) { va_list arg; From 566a8f58a729a607f0c4f4dcdd6afe638c8be2aa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 13:55:02 +0200 Subject: [PATCH 008/223] - disable dir CCMD. The implementation of this one is garbage, it needs to be redone without I_ChDir. --- src/common/console/c_enginecmds.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/console/c_enginecmds.cpp b/src/common/console/c_enginecmds.cpp index 13593cb32..28133669c 100644 --- a/src/common/console/c_enginecmds.cpp +++ b/src/common/console/c_enginecmds.cpp @@ -176,6 +176,8 @@ UNSAFE_CCMD (crashout) #endif +// commented out because it's very poorly implemented (it should not abuse I_ChDir like this!) +#if 0 UNSAFE_CCMD (dir) { FString dir, path; @@ -248,6 +250,7 @@ UNSAFE_CCMD (dir) I_ChDir(curdir); } +#endif //========================================================================== // From 5f3d25ef44f8c3b7964eb2e0f162bc551d2db08a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 12:18:35 +0200 Subject: [PATCH 009/223] - use ScanDirectory in all places where the findfile API was used. This allows to completely hide its implementation details from the rest of the code which only gets a list of file names now. --- src/common/audio/music/i_soundfont.cpp | 24 +-- src/common/audio/music/i_soundfont.h | 2 +- src/common/console/c_enginecmds.cpp | 2 +- src/common/filesystem/file_7z.cpp | 3 +- src/common/filesystem/file_directory.cpp | 84 ++------ src/common/filesystem/fs_findfile.cpp | 188 ++++++++++++++++-- src/common/filesystem/fs_findfile.h | 103 ++-------- src/common/filesystem/resourcefile.h | 11 -- src/common/utility/cmdlib.cpp | 64 +----- src/common/utility/cmdlib.h | 7 - src/common/utility/findfile.cpp | 235 ++--------------------- src/common/utility/findfile.h | 85 -------- src/d_iwad.cpp | 25 ++- src/maploader/glnodes.cpp | 11 +- src/menu/loadsavemenu.cpp | 95 +-------- 15 files changed, 263 insertions(+), 676 deletions(-) diff --git a/src/common/audio/music/i_soundfont.cpp b/src/common/audio/music/i_soundfont.cpp index dd487954c..72b8ab44d 100644 --- a/src/common/audio/music/i_soundfont.cpp +++ b/src/common/audio/music/i_soundfont.cpp @@ -42,7 +42,8 @@ #include #include "resourcefile.h" #include "version.h" -#include "findfile.h" +#include "fs_findfile.h" +#include "resourcefile.h" #include "i_interface.h" #include "configfile.h" #include "printf.h" @@ -331,7 +332,7 @@ FileReader FLumpPatchSetReader::OpenFile(const char *name) // //========================================================================== -void FSoundFontManager::ProcessOneFile(const FString &fn) +void FSoundFontManager::ProcessOneFile(const char* fn) { auto fb = ExtractFileBase(fn, false); auto fbe = ExtractFileBase(fn, true); @@ -391,9 +392,6 @@ void FSoundFontManager::ProcessOneFile(const FString &fn) void FSoundFontManager::CollectSoundfonts() { - findstate_t c_file; - void *file; - FConfigFile* GameConfig = sysCallbacks.GetConfig ? sysCallbacks.GetConfig() : nullptr; if (GameConfig != NULL && GameConfig->SetSection ("SoundfontSearch.Directories")) { @@ -404,25 +402,23 @@ void FSoundFontManager::CollectSoundfonts() { if (stricmp (key, "Path") == 0) { + FileList list; + FString dir; dir = NicePath(value); FixPathSeperator(dir); if (dir.IsNotEmpty()) { - if (dir.Back() != '/') dir += '/'; - FString mask = dir + '*'; - if ((file = I_FindFirst(mask, &c_file)) != ((void *)(-1))) + if (ScanDirectory(list, dir.GetChars(), "*", true)) { - do + for(auto& entry : list) { - if (!(I_FindAttr(&c_file) & FA_DIREC)) + if (!entry.isDirectory) { - FStringf name("%s%s", dir.GetChars(), I_FindName(&c_file)); - ProcessOneFile(name); + ProcessOneFile(entry.FilePath.c_str()); } - } while (I_FindNext(file, &c_file) == 0); - I_FindClose(file); + } } } } diff --git a/src/common/audio/music/i_soundfont.h b/src/common/audio/music/i_soundfont.h index ef0295071..45e5b0ffa 100644 --- a/src/common/audio/music/i_soundfont.h +++ b/src/common/audio/music/i_soundfont.h @@ -148,7 +148,7 @@ class FSoundFontManager { TArray soundfonts; - void ProcessOneFile(const FString & fn); + void ProcessOneFile(const char* fn); public: void CollectSoundfonts(); diff --git a/src/common/console/c_enginecmds.cpp b/src/common/console/c_enginecmds.cpp index 28133669c..92b8cea53 100644 --- a/src/common/console/c_enginecmds.cpp +++ b/src/common/console/c_enginecmds.cpp @@ -50,7 +50,7 @@ #include "filesystem.h" #include "gstrings.h" #include "version.h" -#include "findfile.h" +#include "fs_findfile.h" #include "md5.h" #include "i_specialpaths.h" #include "i_system.h" diff --git a/src/common/filesystem/file_7z.cpp b/src/common/filesystem/file_7z.cpp index 9b1535be2..5539d5448 100644 --- a/src/common/filesystem/file_7z.cpp +++ b/src/common/filesystem/file_7z.cpp @@ -37,6 +37,7 @@ #include "7z.h" #include "7zCrc.h" #include "resourcefile.h" +#include "fs_findfile.h" @@ -276,8 +277,8 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) for (size_t c = 0; c < nameLength; ++c) { nameASCII[c] = tolower(static_cast(nameUTF16[c])); - if (nameASCII[c] == '\\') nameASCII[c] = '/'; } + FixPathSeparator(&nameASCII.front()); lump_p->LumpNameSetup(nameASCII.c_str()); lump_p->LumpSize = static_cast(SzArEx_GetFileSize(archPtr, i)); diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/file_directory.cpp index 51801c166..7117df760 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/file_directory.cpp @@ -39,6 +39,8 @@ #include "resourcefile.h" #include "fs_findfile.h" +std::string FS_FullPath(const char* directory); + #ifdef _WIN32 std::wstring toWide(const char* str); #endif @@ -99,95 +101,41 @@ FDirectory::FDirectory(const char * directory, bool nosubdirflag) // //========================================================================== -static bool FS_GetFileInfo(const char* pathname, size_t* size) -{ -#ifndef _WIN32 - struct stat info; - bool res = stat(pathname, &info) == 0; -#else - // Windows must use the wide version of stat to preserve non-ASCII paths. - struct _stat64 info; - bool res = _wstat64(toWide(pathname).c_str(), &info) == 0; -#endif - if (!res || (info.st_mode & S_IFDIR)) return false; - if (size) *size = (size_t)info.st_size; - return res; -} - -//========================================================================== -// -// Windows version -// -//========================================================================== - int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { - void * handle; int count = 0; - std::string dirmatch = dirpath; - dirmatch += '*'; - fs_findstate_t find; - - handle = FS_FindFirst(dirmatch.c_str(), &find); - if (handle == ((void *)(-1))) + FileList list; + if (!ScanDirectory(list, dirpath, "*")) { Printf(FSMessageLevel::Error, "Could not scan '%s': %s\n", dirpath, strerror(errno)); } else { - do + for(auto& entry : list) { - // FS_FindName only returns the file's name and not its full path - auto attr = FS_FindAttr(&find); - if (attr & FA_HIDDEN) + if (!entry.isDirectory) { - // Skip hidden files and directories. (Prevents SVN/Git bookkeeping - // info from being included.) - continue; - } - const char* fi = FS_FindName(&find); - if (attr & FA_DIREC) - { - if (nosubdir || (fi[0] == '.' && - (fi[1] == '\0' || - (fi[1] == '.' && fi[2] == '\0')))) - { - // Do not record . and .. directories. - continue; - } - std::string newdir = dirpath; - newdir += fi; - newdir += '/'; - count += AddDirectory(newdir.c_str(), filter, Printf); - } - else - { - if (strstr(fi, ".orig") || strstr(fi, ".bak") || strstr(fi, ".cache")) + auto fi = entry.FileName; + for (auto& c : fi) c = tolower(c); + if (strstr(fi.c_str(), ".orig") || strstr(fi.c_str(), ".bak") || strstr(fi.c_str(), ".cache")) { // We shouldn't add backup files to the file system continue; } - size_t size = 0; - std::string fn = dirpath; - fn += fi; - if (filter->filenamecheck == nullptr || filter->filenamecheck(fi, fn.c_str())) + if (filter->filenamecheck == nullptr || filter->filenamecheck(fi.c_str(), entry.FilePath.c_str())) { - if (FS_GetFileInfo(fn.c_str(), &size)) + if (entry.Length > 0x7fffffff) { - if (size > 0x7fffffff) - { - Printf(FSMessageLevel::Warning, "%s is larger than 2GB and will be ignored\n", fn.c_str()); - } - AddEntry(fn.c_str(), (int)size); - count++; + Printf(FSMessageLevel::Warning, "%s is larger than 2GB and will be ignored\n", entry.FilePath.c_str()); + continue; } + AddEntry(entry.FilePathRel.c_str(), (int)entry.Length); + count++; } } - - } while (FS_FindNext (handle, &find) == 0); - FS_FindClose (handle); + } } return count; } diff --git a/src/common/filesystem/fs_findfile.cpp b/src/common/filesystem/fs_findfile.cpp index 7e47b33f4..5830d2fca 100644 --- a/src/common/filesystem/fs_findfile.cpp +++ b/src/common/filesystem/fs_findfile.cpp @@ -33,6 +33,31 @@ */ #include "fs_findfile.h" +#include + + +enum +{ + ZPATH_MAX = 260 +}; + +#ifndef _WIN32 + + +#else + + +enum +{ + FA_RDONLY = 1, + FA_HIDDEN = 2, + FA_SYSTEM = 4, + FA_DIREC = 16, + FA_ARCH = 32, +}; + +#endif + #ifndef _WIN32 @@ -40,6 +65,31 @@ #include #include +#include + +struct findstate_t +{ + std::string path; + struct dirent** namelist; + int current; + int count; +}; + +static const char* FS_FindName(findstate_t* fileinfo) +{ + return (fileinfo->namelist[fileinfo->current]->d_name); +} + +enum +{ + FA_RDONLY = 1, + FA_HIDDEN = 2, + FA_SYSTEM = 4, + FA_DIREC = 8, + FA_ARCH = 16, +}; + + static const char *pattern; static int matchfile(const struct dirent *ent) @@ -47,7 +97,7 @@ static int matchfile(const struct dirent *ent) return fnmatch(pattern, ent->d_name, FNM_NOESCAPE) == 0; } -void *FS_FindFirst(const char *const filespec, fs_findstate_t *const fileinfo) +static void *FS_FindFirst(const char *const filespec, findstate_t *const fileinfo) { const char* dir; @@ -76,9 +126,9 @@ void *FS_FindFirst(const char *const filespec, fs_findstate_t *const fileinfo) return (void *)-1; } -int FS_FindNext(void *const handle, fs_findstate_t *const fileinfo) +static int FS_FindNext(void *const handle, findstate_t *const fileinfo) { - fs_findstate_t *const state = static_cast(handle); + findstate_t *const state = static_cast(handle); if (state->current < fileinfo->count) { @@ -88,9 +138,9 @@ int FS_FindNext(void *const handle, fs_findstate_t *const fileinfo) return -1; } -int FS_FindClose(void *const handle) +static int FS_FindClose(void *const handle) { - fs_findstate_t *const state = static_cast(handle); + findstate_t *const state = static_cast(handle); if (handle != (void *)-1 && state->count > 0) { @@ -116,7 +166,7 @@ static bool DirEntryExists(const char* pathname, bool* isdir) return res; } -int FS_FindAttr(fs_findstate_t *const fileinfo) +static int FS_FindAttr(findstate_t *const fileinfo) { dirent *const ent = fileinfo->namelist[fileinfo->current]; const std::string path = fileinfo->path + ent->d_name; @@ -136,6 +186,15 @@ std::string FS_FullPath(const char* directory) return directory } +static size_t FS_GetFileSize(findstate_t* handle, const char* pathname) +{ + struct stat info; + bool res = stat(pathname, &info) == 0; + if (!res || (info.st_mode & S_IFDIR)) return 0; + return (size_t)info.st_size; +} + + #else #include @@ -161,6 +220,32 @@ static std::string toUtf8(const wchar_t* str) return utf8; } +struct findstate_t +{ + struct FileTime + { + uint32_t lo, hi; + }; + // Mirror WIN32_FIND_DATAW in . We cannot pull in the Windows header here as it would pollute all consumers' symbol space. + struct WinData + { + uint32_t Attribs; + FileTime Times[3]; + uint32_t Size[2]; + uint32_t Reserved[2]; + wchar_t Name[ZPATH_MAX]; + wchar_t AltName[14]; + }; + WinData FindData; + std::string UTF8Name; +}; + + +static int FS_FindAttr(findstate_t* fileinfo) +{ + return fileinfo->FindData.Attribs; +} + //========================================================================== // // FS_FindFirst @@ -170,10 +255,9 @@ static std::string toUtf8(const wchar_t* str) //========================================================================== -void *FS_FindFirst(const char *filespec, fs_findstate_t *fileinfo) +static void *FS_FindFirst(const char *filespec, findstate_t *fileinfo) { static_assert(sizeof(WIN32_FIND_DATAW) == sizeof(fileinfo->FindData), "FindData size mismatch"); - fileinfo->UTF8Name = ""; return FindFirstFileW(toWide(filespec).c_str(), (LPWIN32_FIND_DATAW)&fileinfo->FindData); } @@ -185,9 +269,8 @@ void *FS_FindFirst(const char *filespec, fs_findstate_t *fileinfo) // //========================================================================== -int FS_FindNext(void *handle, fs_findstate_t *fileinfo) +static int FS_FindNext(void *handle, findstate_t *fileinfo) { - fileinfo->UTF8Name = ""; return FindNextFileW((HANDLE)handle, (LPWIN32_FIND_DATAW)&fileinfo->FindData) == 0; } @@ -199,7 +282,7 @@ int FS_FindNext(void *handle, fs_findstate_t *fileinfo) // //========================================================================== -int FS_FindClose(void *handle) +static int FS_FindClose(void *handle) { return FindClose((HANDLE)handle); } @@ -212,12 +295,9 @@ int FS_FindClose(void *handle) // //========================================================================== -const char *FS_FindName(fs_findstate_t *fileinfo) +static const char *FS_FindName(findstate_t *fileinfo) { - if (fileinfo->UTF8Name.empty()) - { - fileinfo->UTF8Name = toUtf8(fileinfo->FindData.Name); - } + fileinfo->UTF8Name = toUtf8(fileinfo->FindData.Name); return fileinfo->UTF8Name.c_str(); } @@ -229,4 +309,80 @@ std::string FS_FullPath(const char* directory) for (auto& c : sdirectory) if (c == '\\') c = '/'; return sdirectory; } + +static size_t FS_GetFileSize(findstate_t* handle, const char* pathname) +{ + return handle->FindData.Size[1] + ((uint64_t)handle->FindData.Size[0] << 32); +} + #endif + + +//========================================================================== +// +// ScanDirectory +// +//========================================================================== + +static bool DoScanDirectory(FileList& list, const char* dirpath, const char* match, const char* relpath, bool nosubdir, bool readhidden) +{ + findstate_t find; + + std::string dirpathn = dirpath; + FixPathSeparator(&dirpathn.front()); + if (dirpathn[dirpathn.length() - 1] != '/') dirpathn += '/'; + + std::string dirmatch = dirpathn; + dirmatch += match; + + auto handle = FS_FindFirst(dirmatch.c_str(), &find); + if (handle == ((void*)(-1))) return false; + FileListEntry fl; + do + { + auto attr = FS_FindAttr(&find); + if (!readhidden && (attr & FA_HIDDEN)) + { + // Skip hidden files and directories. (Prevents SVN/git bookkeeping info from being included.) + continue; + } + auto fn = FS_FindName(&find); + + if (attr & FA_DIREC) + { + if (fn[0] == '.' && + (fn[1] == '\0' || + (fn[1] == '.' && fn[2] == '\0'))) + { + // Do not record . and .. directories. + continue; + } + } + + fl.FileName = fn; + fl.FilePath = dirpathn + fn; + fl.FilePathRel = relpath; + if (fl.FilePathRel.length() > 0) fl.FilePathRel += '/'; + fl.FilePathRel += fn; + fl.isDirectory = !!(attr & FA_DIREC); + fl.isReadonly = !!(attr & FA_RDONLY); + fl.isHidden = !!(attr & FA_HIDDEN); + fl.isSystem = !!(attr & FA_SYSTEM); + fl.Length = FS_GetFileSize(&find, fl.FilePath.c_str()); + list.push_back(fl); + if (!nosubdir && (attr & FA_DIREC)) + { + DoScanDirectory(list, fl.FilePath.c_str(), match, fl.FilePathRel.c_str(), false, readhidden); + fl.Length = 0; + } + } while (FS_FindNext(handle, &find) == 0); + FS_FindClose(handle); + return true; +} + + +bool ScanDirectory(std::vector& list, const char* dirpath, const char* match, bool nosubdir, bool readhidden) +{ + return DoScanDirectory(list, dirpath, match, "", nosubdir, readhidden); +} + diff --git a/src/common/filesystem/fs_findfile.h b/src/common/filesystem/fs_findfile.h index 528c428c3..3c81009af 100644 --- a/src/common/filesystem/fs_findfile.h +++ b/src/common/filesystem/fs_findfile.h @@ -2,97 +2,32 @@ // Directory searching routines #include +#include #include -enum +struct FileListEntry { - ZPATH_MAX = 260 + std::string FileName; // file name only + std::string FilePath; // full path to file + std::string FilePathRel; // path relative to the scanned directory. + size_t Length = 0; + bool isDirectory = false; + bool isReadonly = false; + bool isHidden = false; + bool isSystem = false; }; -#ifndef _WIN32 +using FileList = std::vector; -#include +bool ScanDirectory(std::vector& list, const char* dirpath, const char* match, bool nosubdir = false, bool readhidden = false); -struct fs_findstate_t +inline void FixPathSeparator(char* path) { -private: - std::string path; - struct dirent **namelist; - int current; - int count; - - friend void *FS_FindFirst(const char *filespec, fs_findstate_t *fileinfo); - friend int FS_FindNext(void *handle, fs_findstate_t *fileinfo); - friend const char *FS_FindName(fs_findstate_t *fileinfo); - friend int FS_FindAttr(fs_findstate_t *fileinfo); - friend int FS_FindClose(void *handle); -}; - -int FS_FindAttr (fs_findstate_t *fileinfo); - -inline const char *FS_FindName(fs_findstate_t *fileinfo) -{ - return (fileinfo->namelist[fileinfo->current]->d_name); + while (*path) + { + if (*path == '\\') + *path = '/'; + path++; + } } -enum -{ - FA_RDONLY = 1, - FA_HIDDEN = 2, - FA_SYSTEM = 4, - FA_DIREC = 8, - FA_ARCH = 16, -}; - - -#else - - -struct fs_findstate_t -{ -private: - struct FileTime - { - uint32_t lo, hi; - }; - // Mirror WIN32_FIND_DATAW in . We cannot pull in the Windows header here as it would pollute all consumers' symbol space. - struct WinData - { - uint32_t Attribs; - FileTime Times[3]; - uint32_t Size[2]; - uint32_t Reserved[2]; - wchar_t Name[ZPATH_MAX]; - wchar_t AltName[14]; - }; - WinData FindData; - std::string UTF8Name; - - friend void *FS_FindFirst(const char *filespec, fs_findstate_t *fileinfo); - friend int FS_FindNext(void *handle, fs_findstate_t *fileinfo); - friend const char *FS_FindName(fs_findstate_t *fileinfo); - friend int FS_FindAttr(fs_findstate_t *fileinfo); -}; - - -const char *FS_FindName(fs_findstate_t *fileinfo); -inline int FS_FindAttr(fs_findstate_t *fileinfo) -{ - return fileinfo->FindData.Attribs; -} - -enum -{ - FA_RDONLY = 1, - FA_HIDDEN = 2, - FA_SYSTEM = 4, - FA_DIREC = 16, - FA_ARCH = 32, -}; - -#endif - -void *FS_FindFirst (const char *filespec, fs_findstate_t *fileinfo); -int FS_FindNext (void *handle, fs_findstate_t *fileinfo); -int FS_FindClose (void *handle); -std::string FS_FullPath(const char* directory); diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index b2a81ac26..df68d7c8d 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -164,17 +164,6 @@ protected: void GenerateHash(); void PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterInfo *filter); - void FixPathSeparator(char* path) - { - while (*path) - { - if (*path == '\\') - *path = '/'; - path++; - } - } - - private: uint32_t FirstLump; diff --git a/src/common/utility/cmdlib.cpp b/src/common/utility/cmdlib.cpp index a3b2ef4f5..f37bb6717 100644 --- a/src/common/utility/cmdlib.cpp +++ b/src/common/utility/cmdlib.cpp @@ -35,7 +35,7 @@ #include "cmdlib.h" -#include "findfile.h" +#include "fs_findfile.h" #include "files.h" #include "md5.h" @@ -894,68 +894,6 @@ FString NicePath(const char *path) } -//========================================================================== -// -// ScanDirectory -// -//========================================================================== - -bool ScanDirectory(TArray &list, const char *dirpath) -{ - findstate_t find; - FString dirmatch; - - dirmatch << dirpath << "*"; - - auto handle = I_FindFirst(dirmatch.GetChars(), &find); - if (handle == ((void*)(-1))) - { - return false; - } - else - { - do - { - auto attr = I_FindAttr(&find); - if (attr & FA_HIDDEN) - { - // Skip hidden files and directories. (Prevents SVN bookkeeping - // info from being included.) - continue; - } - auto fn = I_FindName(&find); - - if (attr & FA_DIREC) - { - if (fn[0] == '.' && - (fn[1] == '\0' || - (fn[1] == '.' && fn[2] == '\0'))) - { - // Do not record . and .. directories. - continue; - } - - FFileList* fl = &list[list.Reserve(1)]; - fl->Filename << dirpath << fn; - fl->isDirectory = true; - FString newdir = fl->Filename; - newdir << "/"; - ScanDirectory(list, newdir); - } - else - { - FFileList* fl = &list[list.Reserve(1)]; - fl->Filename << dirpath << fn; - fl->isDirectory = false; - } - } - while (I_FindNext(handle, &find) == 0); - I_FindClose(handle); - } - return true; -} - - //========================================================================== // // diff --git a/src/common/utility/cmdlib.h b/src/common/utility/cmdlib.h index b319056e8..e2e4aadbd 100644 --- a/src/common/utility/cmdlib.h +++ b/src/common/utility/cmdlib.h @@ -69,13 +69,6 @@ void CreatePath(const char * fn); FString ExpandEnvVars(const char *searchpathstring); FString NicePath(const char *path); -struct FFileList -{ - FString Filename; - bool isDirectory; -}; - -bool ScanDirectory(TArray &list, const char *dirpath); bool IsAbsPath(const char*); FString M_ZLibError(int zerrnum); diff --git a/src/common/utility/findfile.cpp b/src/common/utility/findfile.cpp index 0da6a97ff..ab5c4299c 100644 --- a/src/common/utility/findfile.cpp +++ b/src/common/utility/findfile.cpp @@ -38,160 +38,8 @@ #include "printf.h" #include "configfile.h" #include "i_system.h" +#include "fs_findfile.h" -#ifndef _WIN32 - -#include -#include -#include - -#include "cmdlib.h" - -static const char *pattern; - -static int matchfile(const struct dirent *ent) -{ - return fnmatch(pattern, ent->d_name, FNM_NOESCAPE) == 0; -} - -void *I_FindFirst(const char *const filespec, findstate_t *const fileinfo) -{ - FString dir; - - const char *const slash = strrchr(filespec, '/'); - - if (slash) - { - pattern = slash + 1; - dir = FString(filespec, slash - filespec + 1); - fileinfo->path = dir; - } - else - { - pattern = filespec; - dir = "."; - } - - fileinfo->current = 0; - fileinfo->count = scandir(dir.GetChars(), &fileinfo->namelist, matchfile, alphasort); - - if (fileinfo->count > 0) - { - return fileinfo; - } - - return (void *)-1; -} - -int I_FindNext(void *const handle, findstate_t *const fileinfo) -{ - findstate_t *const state = static_cast(handle); - - if (state->current < fileinfo->count) - { - return ++state->current < fileinfo->count ? 0 : -1; - } - - return -1; -} - -int I_FindClose(void *const handle) -{ - findstate_t *const state = static_cast(handle); - - if (handle != (void *)-1 && state->count > 0) - { - for (int i = 0; i < state->count; ++i) - { - free(state->namelist[i]); - } - - free(state->namelist); - state->namelist = nullptr; - state->count = 0; - } - - return 0; -} - -int I_FindAttr(findstate_t *const fileinfo) -{ - dirent *const ent = fileinfo->namelist[fileinfo->current]; - const FString path = fileinfo->path + ent->d_name; - bool isdir; - - if (DirEntryExists(path, &isdir)) - { - return isdir ? FA_DIREC : 0; - } - - return 0; -} - -#else - -#include -#include - -//========================================================================== -// -// I_FindFirst -// -// Start a pattern matching sequence. -// -//========================================================================== - - -void *I_FindFirst(const char *filespec, findstate_t *fileinfo) -{ - static_assert(sizeof(WIN32_FIND_DATAW) == sizeof(fileinfo->FindData), "FindData size mismatch"); - auto widespec = WideString(filespec); - fileinfo->UTF8Name = ""; - return FindFirstFileW(widespec.c_str(), (LPWIN32_FIND_DATAW)&fileinfo->FindData); -} - -//========================================================================== -// -// I_FindNext -// -// Return the next file in a pattern matching sequence. -// -//========================================================================== - -int I_FindNext(void *handle, findstate_t *fileinfo) -{ - fileinfo->UTF8Name = ""; - return !FindNextFileW((HANDLE)handle, (LPWIN32_FIND_DATAW)&fileinfo->FindData); -} - -//========================================================================== -// -// I_FindClose -// -// Finish a pattern matching sequence. -// -//========================================================================== - -int I_FindClose(void *handle) -{ - return FindClose((HANDLE)handle); -} - -//========================================================================== -// -// I_FindName -// -// Returns the name for an entry -// -//========================================================================== - -const char *I_FindName(findstate_t *fileinfo) -{ - if (fileinfo->UTF8Name.IsEmpty()) fileinfo->UTF8Name = fileinfo->FindData.Name; - return fileinfo->UTF8Name.GetChars(); -} - -#endif //========================================================================== // @@ -288,45 +136,20 @@ void D_AddWildFile(TArray& wadfiles, const char* value, const char *ext { D_AddFile(wadfiles, wadfile, true, -1, config); } - else - { // Try pattern matching - findstate_t findstate; - char path[ZPATH_MAX]; - char* sep; - void* handle = I_FindFirst(value, &findstate); - - strcpy(path, value); - sep = strrchr(path, '/'); - if (sep == nullptr) - { - sep = strrchr(path, '\\'); -#ifdef _WIN32 - if (sep == nullptr && path[1] == ':') + else + { + // Try pattern matching + FileList list; + auto path = ExtractFilePath(value); + auto name = ExtractFileBase(value, true); + if (path.IsEmpty()) path = "."; + if (ScanDirectory(list, path, name, true)) + { + for(auto& entry : list) { - sep = path + 1; + D_AddFile(wadfiles, entry.FilePath.c_str(), true, -1, config); } -#endif } - - if (handle != ((void*)-1)) - { - do - { - if (!(I_FindAttr(&findstate) & FA_DIREC)) - { - if (sep == nullptr) - { - D_AddFile(wadfiles, I_FindName(&findstate), true, -1, config); - } - else - { - strcpy(sep + 1, I_FindName(&findstate)); - D_AddFile(wadfiles, path, true, -1, config); - } - } - } while (I_FindNext(handle, &findstate) == 0); - } - I_FindClose(handle); } } @@ -370,40 +193,16 @@ void D_AddConfigFiles(TArray& wadfiles, const char* section, const char void D_AddDirectory(TArray& wadfiles, const char* dir, const char *filespec, FConfigFile* config) { - FString curdir = I_GetCWD(); - if (curdir.IsNotEmpty()) + FileList list; + if (ScanDirectory(list, dir, "*.wad", true)) { - char skindir[ZPATH_MAX]; - findstate_t findstate; - void* handle; - size_t stuffstart; - - stuffstart = strlen(dir); - memcpy(skindir, dir, stuffstart * sizeof(*dir)); - skindir[stuffstart] = 0; - - if (skindir[stuffstart - 1] == '/') + for (auto& entry : list) { - skindir[--stuffstart] = 0; - } - - if (I_ChDir(skindir)) - { - skindir[stuffstart++] = '/'; - if ((handle = I_FindFirst(filespec, &findstate)) != (void*)-1) + if (!entry.isDirectory) { - do - { - if (!(I_FindAttr(&findstate) & FA_DIREC)) - { - strcpy(skindir + stuffstart, I_FindName(&findstate)); - D_AddFile(wadfiles, skindir, true, -1, config); - } - } while (I_FindNext(handle, &findstate) == 0); - I_FindClose(handle); + D_AddFile(wadfiles, entry.FilePath.c_str(), true, -1, config); } } - I_ChDir(curdir); } } diff --git a/src/common/utility/findfile.h b/src/common/utility/findfile.h index 44bee1a35..31f8bd65b 100644 --- a/src/common/utility/findfile.h +++ b/src/common/utility/findfile.h @@ -4,91 +4,6 @@ #include #include "zstring.h" -enum -{ - ZPATH_MAX = 260 -}; - -#ifndef _WIN32 - -#include - -struct findstate_t -{ -private: - FString path; - struct dirent **namelist; - int current; - int count; - - friend void *I_FindFirst(const char *filespec, findstate_t *fileinfo); - friend int I_FindNext(void *handle, findstate_t *fileinfo); - friend const char *I_FindName(findstate_t *fileinfo); - friend int I_FindAttr(findstate_t *fileinfo); - friend int I_FindClose(void *handle); -}; - -int I_FindAttr (findstate_t *fileinfo); - -inline const char *I_FindName(findstate_t *fileinfo) -{ - return (fileinfo->namelist[fileinfo->current]->d_name); -} - -#define FA_RDONLY 1 -#define FA_HIDDEN 2 -#define FA_SYSTEM 4 -#define FA_DIREC 8 -#define FA_ARCH 16 - - -#else - -// Mirror WIN32_FIND_DATAW in - -struct findstate_t -{ -private: - struct FileTime - { - uint32_t lo, hi; - }; - struct WinData - { - uint32_t Attribs; - FileTime Times[3]; - uint32_t Size[2]; - uint32_t Reserved[2]; - wchar_t Name[ZPATH_MAX]; - wchar_t AltName[14]; - }; - WinData FindData; - FString UTF8Name; - - friend void *I_FindFirst(const char *filespec, findstate_t *fileinfo); - friend int I_FindNext(void *handle, findstate_t *fileinfo); - friend const char *I_FindName(findstate_t *fileinfo); - friend int I_FindAttr(findstate_t *fileinfo); -}; - - -const char *I_FindName(findstate_t *fileinfo); -inline int I_FindAttr(findstate_t *fileinfo) -{ - return fileinfo->FindData.Attribs; -} - -#define FA_RDONLY 0x00000001 -#define FA_HIDDEN 0x00000002 -#define FA_SYSTEM 0x00000004 -#define FA_DIREC 0x00000010 -#define FA_ARCH 0x00000020 - -#endif - -void *I_FindFirst (const char *filespec, findstate_t *fileinfo); -int I_FindNext (void *handle, findstate_t *fileinfo); -int I_FindClose (void *handle); class FConfigFile; diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 27bcb7276..bfa67961a 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -46,6 +46,7 @@ #include "version.h" #include "engineerrors.h" #include "v_text.h" +#include "fs_findfile.h" #include "findfile.h" #include "i_interface.h" @@ -471,36 +472,32 @@ void FIWadManager::CollectSearchPaths() void FIWadManager::AddIWADCandidates(const char *dir) { - void *handle; - findstate_t findstate; - FStringf slasheddir("%s/", dir); - FString findmask = slasheddir + "*.*"; - if ((handle = I_FindFirst(findmask, &findstate)) != (void *)-1) + FileList list; + + if (ScanDirectory(list, dir, "*", true)) { - do + for(auto& entry : list) { - if (!(I_FindAttr(&findstate) & FA_DIREC)) + if (!entry.isDirectory) { - auto FindName = I_FindName(&findstate); - auto p = strrchr(FindName, '.'); + auto p = strrchr(entry.FileName.c_str(), '.'); if (p != nullptr) { // special IWAD extension. if (!stricmp(p, ".iwad") || !stricmp(p, ".ipk3") || !stricmp(p, ".ipk7")) { - mFoundWads.Push(FFoundWadInfo{ slasheddir + FindName, "", -1 }); + mFoundWads.Push(FFoundWadInfo{ entry.FilePath.c_str(), "", -1 }); } } for (auto &name : mIWadNames) { - if (!stricmp(name, FindName)) + if (!stricmp(name, entry.FileName.c_str())) { - mFoundWads.Push(FFoundWadInfo{ slasheddir + FindName, "", -1 }); + mFoundWads.Push(FFoundWadInfo{ entry.FilePath.c_str(), "", -1 }); } } } - } while (I_FindNext(handle, &findstate) == 0); - I_FindClose(handle); + } } } diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index b7d773f03..38fa976fd 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -60,6 +60,7 @@ #include "g_levellocals.h" #include "i_time.h" #include "maploader.h" +#include "fs_findfile.h" EXTERN_CVAR(Bool, gl_cachenodes) EXTERN_CVAR(Float, gl_cachetime) @@ -1198,11 +1199,11 @@ bool MapLoader::CheckCachedNodes(MapData *map) UNSAFE_CCMD(clearnodecache) { - TArray list; + FileList list; FString path = M_GetCachePath(false); path += "/"; - if (!ScanDirectory(list, path)) + if (!ScanDirectory(list, path, "*", false)) { Printf("Unable to scan node cache directory %s\n", path.GetChars()); return; @@ -1210,15 +1211,15 @@ UNSAFE_CCMD(clearnodecache) // Scan list backwards so that when we reach a directory // all files within are already deleted. - for(int i = list.Size()-1; i >= 0; i--) + for(int i = (int)list.size()-1; i >= 0; i--) { if (list[i].isDirectory) { - rmdir(list[i].Filename); + rmdir(list[i].FilePath.c_str()); } else { - remove(list[i].Filename); + remove(list[i].FilePath.c_str()); } } diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index aaeb5ccbf..e6ed52e9e 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -44,7 +44,7 @@ #include "vm.h" #include "i_system.h" #include "v_video.h" -#include "findfile.h" +#include "fs_findfile.h" #include "v_draw.h" // Save name length limit for old binary formats. @@ -62,22 +62,16 @@ void FSavegameManager::ReadSaveStrings() { if (SaveGames.Size() == 0) { - void *filefirst; - findstate_t c_file; FString filter; LastSaved = LastAccessed = -1; quickSaveSlot = nullptr; - filter = G_BuildSaveName("*"); - filefirst = I_FindFirst(filter.GetChars(), &c_file); - if (filefirst != ((void *)(-1))) + FileList list; + if (ScanDirectory(list, G_GetSavegamesFolder().GetChars(), "*." SAVEGAME_EXT, true)) { - do + for (auto& entry : list) { - // I_FindName only returns the file's name and not its full path - FString filepath = G_BuildSaveName(I_FindName(&c_file)); - - std::unique_ptr savegame(FResourceFile::OpenResourceFile(filepath, true)); + std::unique_ptr savegame(FResourceFile::OpenResourceFile(entry.FilePath.c_str(), true)); if (savegame != nullptr) { bool oldVer = false; @@ -122,89 +116,14 @@ void FSavegameManager::ReadSaveStrings() } FSaveGameNode *node = new FSaveGameNode; - node->Filename = filepath; + node->Filename = entry.FilePath.c_str(); node->bOldVersion = oldVer; node->bMissingWads = missing; node->SaveTitle = title; InsertSaveNode(node); } - } - else // check for old formats. - { - FileReader file; - if (file.OpenFile(filepath)) - { - PNGHandle *png; - char sig[16]; - char title[OLDSAVESTRINGSIZE + 1]; - bool oldVer = true; - bool addIt = false; - bool missing = false; - - // ZDoom 1.23 betas 21-33 have the savesig first. - // Earlier versions have the savesig second. - // Later versions have the savegame encapsulated inside a PNG. - // - // Old savegame versions are always added to the menu so - // the user can easily delete them if desired. - - title[OLDSAVESTRINGSIZE] = 0; - - if (nullptr != (png = M_VerifyPNG(file))) - { - char *ver = M_GetPNGText(png, "ZDoom Save Version"); - if (ver != nullptr) - { - // An old version - if (!M_GetPNGText(png, "Title", title, OLDSAVESTRINGSIZE)) - { - strncpy(title, I_FindName(&c_file), OLDSAVESTRINGSIZE); - } - addIt = true; - delete[] ver; - } - delete png; - } - else - { - file.Seek(0, FileReader::SeekSet); - if (file.Read(sig, 16) == 16) - { - - if (strncmp(sig, "ZDOOMSAVE", 9) == 0) - { - if (file.Read(title, OLDSAVESTRINGSIZE) == OLDSAVESTRINGSIZE) - { - addIt = true; - } - } - else - { - memcpy(title, sig, 16); - if (file.Read(title + 16, OLDSAVESTRINGSIZE - 16) == OLDSAVESTRINGSIZE - 16 && - file.Read(sig, 16) == 16 && - strncmp(sig, "ZDOOMSAVE", 9) == 0) - { - addIt = true; - } - } - } - } - - if (addIt) - { - FSaveGameNode *node = new FSaveGameNode; - node->Filename = filepath; - node->bOldVersion = true; - node->bMissingWads = false; - node->SaveTitle = title; - InsertSaveNode(node); - } - } - } - } while (I_FindNext(filefirst, &c_file) == 0); - I_FindClose(filefirst); + } } } } From 771fa2b51c6a7e0368c8ce68ff7a0c7a349fa863 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 20 Aug 2023 20:44:11 +0200 Subject: [PATCH 010/223] - rewrote dir CCMD using ScanDirectory and avoiding I_ChDir entirely. --- src/common/console/c_enginecmds.cpp | 82 +++++++++-------------------- 1 file changed, 24 insertions(+), 58 deletions(-) diff --git a/src/common/console/c_enginecmds.cpp b/src/common/console/c_enginecmds.cpp index 92b8cea53..6c914db66 100644 --- a/src/common/console/c_enginecmds.cpp +++ b/src/common/console/c_enginecmds.cpp @@ -176,81 +176,47 @@ UNSAFE_CCMD (crashout) #endif -// commented out because it's very poorly implemented (it should not abuse I_ChDir like this!) -#if 0 UNSAFE_CCMD (dir) { - FString dir, path; - const char *match; - findstate_t c_file; - void *file; - - FString curdir = I_GetCWD(); - if (curdir.IsEmpty()) - { - Printf ("Current path too long\n"); - return; - } + FString path; if (argv.argc() > 1) { path = NicePath(argv[1]); - if (!I_ChDir(path)) - { - match = path; - dir = ExtractFilePath(path); - if (dir[0] != '\0') - { - match += dir.Len(); - } - else - { - dir = "./"; - } - if (match[0] == '\0') - { - match = "*"; - } - if (!I_ChDir(dir)) - { - Printf ("%s not found\n", dir.GetChars()); - return; - } - } - else - { - match = "*"; - dir = path; - } } else { - match = "*"; - dir = curdir; + path = I_GetCWD();; } - if (dir[dir.Len()-1] != '/') + auto base = ExtractFileBase(path, true); + FString bpath; + if (base.IndexOfAny("*?") >= 0) { - dir += '/'; + bpath = ExtractFilePath(path); } - - if ( (file = I_FindFirst (match, &c_file)) == ((void *)(-1))) - Printf ("Nothing matching %s%s\n", dir.GetChars(), match); else { - Printf ("Listing of %s%s:\n", dir.GetChars(), match); - do - { - if (I_FindAttr (&c_file) & FA_DIREC) - Printf (PRINT_BOLD, "%s \n", I_FindName (&c_file)); - else - Printf ("%s\n", I_FindName (&c_file)); - } while (I_FindNext (file, &c_file) == 0); - I_FindClose (file); + base = "*"; + bpath = path; } - I_ChDir(curdir); + FileList list; + if (!ScanDirectory(list, bpath, base, true)) + { + Printf ("Nothing matching %s\n", path.GetChars()); + } + else + { + Printf ("Listing of %s:\n", path.GetChars()); + for(auto& entry : list) + { + if (entry.isDirectory) + Printf (PRINT_BOLD, "%s \n", entry.FileName.c_str()); + else + Printf ("%s\n", entry.FileName.c_str()); + } + } } -#endif //========================================================================== // From 454af06acfb04fc3214459a06b43dd027117e259 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 14:06:06 +0200 Subject: [PATCH 011/223] - use a local byteswap header in the file system. --- src/common/filesystem/file_grp.cpp | 3 + src/common/filesystem/file_lump.cpp | 1 - src/common/filesystem/file_pak.cpp | 10 +- src/common/filesystem/file_rff.cpp | 5 +- src/common/filesystem/file_wad.cpp | 4 +- src/common/filesystem/file_whres.cpp | 16 +-- src/common/filesystem/file_zip.cpp | 8 +- src/common/filesystem/files.cpp | 4 +- src/common/filesystem/files.h | 33 +++--- src/common/filesystem/files_decompress.cpp | 6 +- src/common/filesystem/fs_findfile.cpp | 2 +- src/common/filesystem/fs_swap.h | 121 +++++++++++++++++++++ 12 files changed, 170 insertions(+), 43 deletions(-) create mode 100644 src/common/filesystem/fs_swap.h diff --git a/src/common/filesystem/file_grp.cpp b/src/common/filesystem/file_grp.cpp index 7ed922263..4765bcde0 100644 --- a/src/common/filesystem/file_grp.cpp +++ b/src/common/filesystem/file_grp.cpp @@ -34,6 +34,9 @@ */ #include "resourcefile.h" +#include "fs_swap.h" + +using namespace fs_private; //========================================================================== // diff --git a/src/common/filesystem/file_lump.cpp b/src/common/filesystem/file_lump.cpp index f16fefaab..60c957081 100644 --- a/src/common/filesystem/file_lump.cpp +++ b/src/common/filesystem/file_lump.cpp @@ -33,7 +33,6 @@ */ #include "resourcefile.h" -#include "cmdlib.h" //========================================================================== // diff --git a/src/common/filesystem/file_pak.cpp b/src/common/filesystem/file_pak.cpp index f9e96eed6..4003ce396 100644 --- a/src/common/filesystem/file_pak.cpp +++ b/src/common/filesystem/file_pak.cpp @@ -34,6 +34,8 @@ #include "resourcefile.h" +using namespace fs_private; + //========================================================================== // // @@ -43,14 +45,14 @@ struct dpackfile_t { char name[56]; - int filepos, filelen; + uint32_t filepos, filelen; } ; struct dpackheader_t { - int ident; // == IDPAKHEADER - int dirofs; - int dirlen; + uint32_t ident; // == IDPAKHEADER + uint32_t dirofs; + uint32_t dirlen; } ; diff --git a/src/common/filesystem/file_rff.cpp b/src/common/filesystem/file_rff.cpp index 67c26def1..723d184e6 100644 --- a/src/common/filesystem/file_rff.cpp +++ b/src/common/filesystem/file_rff.cpp @@ -34,6 +34,9 @@ */ #include "resourcefile.h" +#include "fs_swap.h" + +using namespace fs_private; //========================================================================== // @@ -217,7 +220,7 @@ int FRFFLump::FillCache() if (Flags & LUMPF_COMPRESSED) { - int cryptlen = min (LumpSize, 256); + int cryptlen = std::min (LumpSize, 256); uint8_t *data = (uint8_t *)Cache; for (int i = 0; i < cryptlen; ++i) diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/file_wad.cpp index 1a256db65..beab51476 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/file_wad.cpp @@ -36,7 +36,9 @@ #include #include "resourcefile.h" #include "filesystem.h" -#include "engineerrors.h" +#include "fs_swap.h" + +using namespace fs_private; struct wadinfo_t diff --git a/src/common/filesystem/file_whres.cpp b/src/common/filesystem/file_whres.cpp index cc37ec26c..2d5223041 100644 --- a/src/common/filesystem/file_whres.cpp +++ b/src/common/filesystem/file_whres.cpp @@ -37,25 +37,15 @@ #include "resourcefile.h" #include "cmdlib.h" +#include "fs_swap.h" + +using namespace fs_private; //========================================================================== // // // //========================================================================== -struct whresentry -{ - int filepospage, filelen, priority; -} ; - -struct dpackheader_t -{ - int ident; // == IDPAKHEADER - int dirofs; - int dirlen; -} ; - - //========================================================================== // // Wad file diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index 55e4081fe..d5680ba3e 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -41,6 +41,10 @@ #include "w_zip.h" #include "ancientzip.h" +#include "fs_findfile.h" +#include "fs_swap.h" + +using namespace fs_private; #define BUFREADCOMMENT (0x400) @@ -120,7 +124,7 @@ static uint32_t Zip_FindCentralDir(FileReader &fin, bool* zip64) uint32_t uPosFound=0; FileSize = (uint32_t)fin.GetLength(); - uMaxBack = min(0xffff, FileSize); + uMaxBack = std::min(0xffff, FileSize); uBackRead = 4; while (uBackRead < uMaxBack) @@ -133,7 +137,7 @@ static uint32_t Zip_FindCentralDir(FileReader &fin, bool* zip64) uBackRead += BUFREADCOMMENT; uReadPos = FileSize - uBackRead; - uReadSize = min((BUFREADCOMMENT + 4), (FileSize - uReadPos)); + uReadSize = std::min((BUFREADCOMMENT + 4), (FileSize - uReadPos)); if (fin.Seek(uReadPos, FileReader::SeekSet) != 0) break; diff --git a/src/common/filesystem/files.cpp b/src/common/filesystem/files.cpp index 094bd8a99..88a66a59e 100644 --- a/src/common/filesystem/files.cpp +++ b/src/common/filesystem/files.cpp @@ -37,6 +37,8 @@ #include "files.h" #include "stb_sprintf.h" +using namespace fs_private; + #ifdef _WIN32 std::wstring toWide(const char* str); #endif @@ -274,7 +276,7 @@ long MemoryReader::Seek(long offset, int origin) } if (offset < 0 || offset > Length) return -1; - FilePos = clamp(offset, 0, Length); + FilePos = std::clamp(offset, 0, Length); return 0; } diff --git a/src/common/filesystem/files.h b/src/common/filesystem/files.h index 4cfe74382..eb4b202ac 100644 --- a/src/common/filesystem/files.h +++ b/src/common/filesystem/files.h @@ -42,7 +42,7 @@ #include #include #include "basics.h" -#include "m_swap.h" +#include "fs_swap.h" #include "tarray.h" class FileSystemException : public std::exception @@ -268,53 +268,53 @@ public: return v; } + uint16_t ReadUInt16() { uint16_t v = 0; Read(&v, 2); - return LittleShort(v); + return fs_private::LittleShort(v); } int16_t ReadInt16() { - int16_t v = 0; + return (int16_t)ReadUInt16(); + } + + int16_t ReadUInt16BE() + { + uint16_t v = 0; Read(&v, 2); - return LittleShort(v); + return fs_private::BigShort(v); } int16_t ReadInt16BE() { - int16_t v = 0; - Read(&v, 2); - return BigShort(v); + return (int16_t)ReadUInt16BE(); } uint32_t ReadUInt32() { uint32_t v = 0; Read(&v, 4); - return LittleLong(v); + return fs_private::LittleLong(v); } int32_t ReadInt32() { - int32_t v = 0; - Read(&v, 4); - return LittleLong(v); + return (int32_t)ReadUInt32(); } uint32_t ReadUInt32BE() { uint32_t v = 0; Read(&v, 4); - return BigLong(v); + return fs_private::BigLong(v); } int32_t ReadInt32BE() { - int32_t v = 0; - Read(&v, 4); - return BigLong(v); + return (int32_t)ReadUInt32BE(); } uint64_t ReadUInt64() @@ -368,7 +368,8 @@ public: virtual size_t Write(const void *buffer, size_t len); virtual long Tell(); virtual long Seek(long offset, int mode); - size_t Printf(const char *fmt, ...) GCCPRINTF(2,3); + size_t Printf(const char *fmt, ...); + virtual void Close() { if (File != NULL) fclose(File); diff --git a/src/common/filesystem/files_decompress.cpp b/src/common/filesystem/files_decompress.cpp index 3e636d1bd..d38dfe25b 100644 --- a/src/common/filesystem/files_decompress.cpp +++ b/src/common/filesystem/files_decompress.cpp @@ -527,7 +527,7 @@ class DecompressorLZSS : public DecompressorBase return false; Stream.AvailIn -= 2; - uint16_t pos = BigShort(*(uint16_t*)Stream.In); + uint16_t pos = fs_private::BigShort(*(uint16_t*)Stream.In); uint8_t len = (pos & 0xF)+1; pos >>= 4; Stream.In += 2; @@ -551,7 +551,7 @@ class DecompressorLZSS : public DecompressorBase // Partial overlap: Copy in 2 or 3 chunks. do { - unsigned int copy = min(len, pos+1); + unsigned int copy = std::min(len, pos+1); memcpy(Stream.InternalBuffer, copyStart, copy); Stream.InternalBuffer += copy; Stream.InternalOut += copy; @@ -623,7 +623,7 @@ public: break; } - unsigned int copy = min(Stream.InternalOut, AvailOut); + unsigned int copy = std::min(Stream.InternalOut, AvailOut); if(copy > 0) { memcpy(Out, Stream.WindowData, copy); diff --git a/src/common/filesystem/fs_findfile.cpp b/src/common/filesystem/fs_findfile.cpp index 5830d2fca..021494644 100644 --- a/src/common/filesystem/fs_findfile.cpp +++ b/src/common/filesystem/fs_findfile.cpp @@ -106,7 +106,7 @@ static void *FS_FindFirst(const char *const filespec, findstate_t *const fileinf if (slash) { pattern = slash + 1; - fileinfo->path = std::string(filespec, slash - filespec + 1); + fileinfo->path = std::string(filespec, 0, slash - filespec + 1); dir = fileinfo->path.c_str(); } else diff --git a/src/common/filesystem/fs_swap.h b/src/common/filesystem/fs_swap.h new file mode 100644 index 000000000..1e8bbef83 --- /dev/null +++ b/src/common/filesystem/fs_swap.h @@ -0,0 +1,121 @@ +// +// DESCRIPTION: +// Endianess handling, swapping 16bit and 32bit. +// +//----------------------------------------------------------------------------- + + +#ifndef __FS_SWAP_H__ +#define __FS_SWAP_H__ + +#include + +// Endianess handling. +// WAD files are stored little endian. + +#ifdef __APPLE__ +#include +#endif + +namespace fs_private +{ + +#ifdef __APPLE__ + +inline unsigned short LittleShort(unsigned short x) +{ + return OSSwapLittleToHostInt16(x); +} + +inline unsigned int LittleLong(unsigned int x) +{ + return OSSwapLittleToHostInt32(x); +} + +inline unsigned short BigShort(unsigned short x) +{ + return OSSwapBigToHostInt16(x); +} + +inline unsigned int BigLong(unsigned int x) +{ + return OSSwapBigToHostInt32(x); +} + + +#elif defined __BIG_ENDIAN__ + +// Swap 16bit, that is, MSB and LSB byte. +// No masking with 0xFF should be necessary. +inline unsigned short LittleShort (unsigned short x) +{ + return (unsigned short)((x>>8) | (x<<8)); +} + +inline unsigned int LittleLong (unsigned int x) +{ + return (unsigned int)( + (x>>24) + | ((x>>8) & 0xff00) + | ((x<<8) & 0xff0000) + | (x<<24)); +} + +inline unsigned short BigShort(unsigned short x) +{ + return x; +} + +inline unsigned int BigLong(unsigned int x) +{ + return x; +} + +#else + +inline unsigned short LittleShort(unsigned short x) +{ + return x; +} + +inline unsigned int LittleLong(unsigned int x) +{ + return x; +} + +#ifdef _MSC_VER + +inline unsigned short BigShort(unsigned short x) +{ + return _byteswap_ushort(x); +} + +inline unsigned int BigLong(unsigned int x) +{ + return (unsigned int)_byteswap_ulong((unsigned long)x); +} + +#pragma warning (default: 4035) + +#else + +inline unsigned short BigShort (unsigned short x) +{ + return (unsigned short)((x>>8) | (x<<8)); +} + +inline unsigned int BigLong (unsigned int x) +{ + return (unsigned int)( + (x>>24) + | ((x>>8) & 0xff00) + | ((x<<8) & 0xff0000) + | (x<<24)); +} + +#endif + +#endif // __BIG_ENDIAN__ +} + +#endif // __M_SWAP_H__ From f0bbc32bae9cb32a6f56e26e2d518c3bdc3e0d5e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 15:18:01 +0200 Subject: [PATCH 012/223] - add m_swap.h to several files. --- src/common/fonts/singlelumpfont.cpp | 1 + src/common/models/models_md2.cpp | 1 + src/common/models/models_md3.cpp | 1 + src/common/textures/formats/ddstexture.cpp | 1 + src/common/textures/formats/jpegtexture.cpp | 1 + src/common/textures/formats/patchtexture.cpp | 1 + src/common/textures/formats/pcxtexture.cpp | 1 + src/common/textures/formats/pngtexture.cpp | 1 + src/common/textures/formats/rawpagetexture.cpp | 1 + src/common/textures/formats/tgatexture.cpp | 1 + src/common/textures/multipatchtexturebuilder.cpp | 1 + src/common/utility/palette.cpp | 1 + src/gamedata/textures/buildloader.cpp | 1 + 13 files changed, 13 insertions(+) diff --git a/src/common/fonts/singlelumpfont.cpp b/src/common/fonts/singlelumpfont.cpp index d3bee25a3..94cbd18ec 100644 --- a/src/common/fonts/singlelumpfont.cpp +++ b/src/common/fonts/singlelumpfont.cpp @@ -41,6 +41,7 @@ #include "utf8.h" #include "fontchars.h" #include "texturemanager.h" +#include "m_swap.h" #include "fontinternals.h" diff --git a/src/common/models/models_md2.cpp b/src/common/models/models_md2.cpp index 4f2a12d4e..56ab6274c 100644 --- a/src/common/models/models_md2.cpp +++ b/src/common/models/models_md2.cpp @@ -31,6 +31,7 @@ #include "texturemanager.h" #include "modelrenderer.h" #include "printf.h" +#include "m_swap.h" #ifdef _MSC_VER #pragma warning(disable:4244) // warning C4244: conversion from 'double' to 'float', possible loss of data diff --git a/src/common/models/models_md3.cpp b/src/common/models/models_md3.cpp index e716a6f26..2337a3897 100644 --- a/src/common/models/models_md3.cpp +++ b/src/common/models/models_md3.cpp @@ -25,6 +25,7 @@ #include "model_md3.h" #include "texturemanager.h" #include "modelrenderer.h" +#include "m_swap.h" #define MAX_QPATH 64 diff --git a/src/common/textures/formats/ddstexture.cpp b/src/common/textures/formats/ddstexture.cpp index 8a3d0ba74..5ccf309b9 100644 --- a/src/common/textures/formats/ddstexture.cpp +++ b/src/common/textures/formats/ddstexture.cpp @@ -54,6 +54,7 @@ #include "bitmap.h" #include "imagehelpers.h" #include "image.h" +#include "m_swap.h" // Since we want this to compile under Linux too, we need to define this // stuff ourselves instead of including a DirectX header. diff --git a/src/common/textures/formats/jpegtexture.cpp b/src/common/textures/formats/jpegtexture.cpp index b1e5163b3..79ba53671 100644 --- a/src/common/textures/formats/jpegtexture.cpp +++ b/src/common/textures/formats/jpegtexture.cpp @@ -46,6 +46,7 @@ extern "C" #include "bitmap.h" #include "imagehelpers.h" #include "image.h" +#include "m_swap.h" struct FLumpSourceMgr : public jpeg_source_mgr diff --git a/src/common/textures/formats/patchtexture.cpp b/src/common/textures/formats/patchtexture.cpp index 2fe36efe7..ecbd09147 100644 --- a/src/common/textures/formats/patchtexture.cpp +++ b/src/common/textures/formats/patchtexture.cpp @@ -38,6 +38,7 @@ #include "bitmap.h" #include "image.h" #include "imagehelpers.h" +#include "m_swap.h" // posts are runs of non masked source pixels diff --git a/src/common/textures/formats/pcxtexture.cpp b/src/common/textures/formats/pcxtexture.cpp index 60e2f4aba..7e97ba2ef 100644 --- a/src/common/textures/formats/pcxtexture.cpp +++ b/src/common/textures/formats/pcxtexture.cpp @@ -39,6 +39,7 @@ #include "bitmap.h" #include "imagehelpers.h" #include "image.h" +#include "m_swap.h" //========================================================================== // diff --git a/src/common/textures/formats/pngtexture.cpp b/src/common/textures/formats/pngtexture.cpp index f9e39fc8c..cdf14c15c 100644 --- a/src/common/textures/formats/pngtexture.cpp +++ b/src/common/textures/formats/pngtexture.cpp @@ -43,6 +43,7 @@ #include "printf.h" #include "texturemanager.h" #include "filesystem.h" +#include "m_swap.h" //========================================================================== // diff --git a/src/common/textures/formats/rawpagetexture.cpp b/src/common/textures/formats/rawpagetexture.cpp index 19d3f4587..09d07d0ce 100644 --- a/src/common/textures/formats/rawpagetexture.cpp +++ b/src/common/textures/formats/rawpagetexture.cpp @@ -38,6 +38,7 @@ #include "bitmap.h" #include "imagehelpers.h" #include "image.h" +#include "m_swap.h" //========================================================================== diff --git a/src/common/textures/formats/tgatexture.cpp b/src/common/textures/formats/tgatexture.cpp index 932eeeaf1..daa70cfa4 100644 --- a/src/common/textures/formats/tgatexture.cpp +++ b/src/common/textures/formats/tgatexture.cpp @@ -39,6 +39,7 @@ #include "bitmap.h" #include "imagehelpers.h" #include "image.h" +#include "m_swap.h" //========================================================================== diff --git a/src/common/textures/multipatchtexturebuilder.cpp b/src/common/textures/multipatchtexturebuilder.cpp index 2a8b77fea..201398ee8 100644 --- a/src/common/textures/multipatchtexturebuilder.cpp +++ b/src/common/textures/multipatchtexturebuilder.cpp @@ -44,6 +44,7 @@ #include "image.h" #include "formats/multipatchtexture.h" #include "texturemanager.h" +#include "m_swap.h" // On the Alpha, accessing the shorts directly if they aren't aligned on a diff --git a/src/common/utility/palette.cpp b/src/common/utility/palette.cpp index e7bc61f09..527d1cd17 100644 --- a/src/common/utility/palette.cpp +++ b/src/common/utility/palette.cpp @@ -39,6 +39,7 @@ #include "files.h" #include "filesystem.h" #include "printf.h" +#include "m_swap.h" #include "m_png.h" diff --git a/src/gamedata/textures/buildloader.cpp b/src/gamedata/textures/buildloader.cpp index bfcc63225..4bb7b2721 100644 --- a/src/gamedata/textures/buildloader.cpp +++ b/src/gamedata/textures/buildloader.cpp @@ -47,6 +47,7 @@ #include "texturemanager.h" #include "r_translate.h" #include "r_data/sprites.h" +#include "m_swap.h" //=========================================================================== // From 959d0e93f75bde1368a397654b2d11b20fa48c7e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 15:18:45 +0200 Subject: [PATCH 013/223] - fixed and cleaned up file_whres.cpp --- src/common/filesystem/file_whres.cpp | 33 ++++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/common/filesystem/file_whres.cpp b/src/common/filesystem/file_whres.cpp index 2d5223041..e11ce1b73 100644 --- a/src/common/filesystem/file_whres.cpp +++ b/src/common/filesystem/file_whres.cpp @@ -35,7 +35,9 @@ */ #include "resourcefile.h" -#include "cmdlib.h" +#include "fs_swap.h" + +using namespace fs_private; #include "fs_swap.h" @@ -54,7 +56,7 @@ using namespace fs_private; class FWHResFile : public FUncompressedFile { - FString basename; + std::string basename; public: FWHResFile(const char * filename, FileReader &file); bool Open(LumpFilterInfo* filter); @@ -72,7 +74,7 @@ public: FWHResFile::FWHResFile(const char *filename, FileReader &file) : FUncompressedFile(filename, file) { - basename = ExtractFileBase(filename, false); + basename = ExtractBaseName(filename, false); } //========================================================================== @@ -83,7 +85,7 @@ FWHResFile::FWHResFile(const char *filename, FileReader &file) bool FWHResFile::Open(LumpFilterInfo*) { - int directory[1024]; + uint32_t directory[1024]; Reader.Seek(-4096, FileReader::SeekEnd); Reader.Read(directory, 4096); @@ -95,11 +97,13 @@ bool FWHResFile::Open(LumpFilterInfo*) int i = 0; for(int k = 0; k < nl; k++) { - int offset = LittleLong(directory[k*3]) * 4096; - int length = LittleLong(directory[k*3+1]); - if (length <= 0) break; - FStringf synthname("%s/%04d", basename.GetChars(), k); - Lumps[i].LumpNameSetup(synthname); + uint32_t offset = LittleLong(directory[k*3]) * 4096; + uint32_t length = LittleLong(directory[k*3+1]); + if (length == 0) break; + char num[5]; + snprintf(num, 5, "/%04d", k); + std::string synthname = basename + num; + Lumps[i].LumpNameSetup(synthname.c_str()); Lumps[i].Owner = this; Lumps[i].Position = offset; Lumps[i].LumpSize = length; @@ -122,19 +126,20 @@ FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo { if (file.GetLength() >= 8192) // needs to be at least 8192 to contain one file and the directory. { - int directory[1024]; + unsigned directory[1024]; int nl =1024/3; file.Seek(-4096, FileReader::SeekEnd); file.Read(directory, 4096); + auto size = file.GetLength(); - int checkpos = 0; + uint32_t checkpos = 0; for(int k = 0; k < nl; k++) { - int offset = LittleLong(directory[k*3]); - int length = LittleLong(directory[k*3+1]); + unsigned offset = LittleLong(directory[k*3]); + unsigned length = LittleLong(directory[k*3+1]); if (length <= 0 && offset == 0) break; - if (offset != checkpos || length <= 0) return nullptr; + if (offset != checkpos || length == 0 || offset + length >= (size_t)size - 4096 ) return nullptr; checkpos += (length+4095) / 4096; } auto rf = new FWHResFile(filename, file); From 825f92b27423ca195e3972fce19816fce7de8df7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 15:26:28 +0200 Subject: [PATCH 014/223] - use std::string in FZipFile::Open --- src/common/filesystem/file_zip.cpp | 54 +++++++++++++------------- src/common/filesystem/resourcefile.cpp | 2 +- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index d5680ba3e..1048ad487 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -236,7 +236,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) char *dirptr = (char*)directory; FZipLump *lump_p = Lumps; - FString name0, name1; + std::string name0, name1; bool foundspeciallump = false; bool foundprefix = false; @@ -247,7 +247,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) FZipCentralDirectoryInfo *zip_fh = (FZipCentralDirectoryInfo *)dirptr; int len = LittleShort(zip_fh->NameLength); - FString name(dirptr + sizeof(FZipCentralDirectoryInfo), len); + std::string name(dirptr + sizeof(FZipCentralDirectoryInfo), len); dirptr += sizeof(FZipCentralDirectoryInfo) + LittleShort(zip_fh->NameLength) + @@ -261,35 +261,37 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) return false; } - name.ToLower(); - if (name.IndexOf("filter/") == 0) + for (auto& c : name) c = tolower(c); + + auto vv = name.find("__macosx"); + if (name.find("filter/") == 0) continue; // 'filter' is a reserved name of the file system. - if (name.IndexOf("__macosx") == 0) + if (name.find("__macosx") == 0) continue; // skip Apple garbage. At this stage only the root folder matters. - if (name.IndexOf(".bat") >= 0 || name.IndexOf(".exe") >= 0) + if (name.find(".bat") != std::string::npos || name.find(".exe") != std::string::npos) continue; // also ignore executables for this. if (!foundprefix) { // check for special names, if one of these gets found this must be treated as a normal zip. - bool isspecial = name.IndexOf("/") < 0 || - (filter && std::find(filter->reservedFolders.begin(), filter->reservedFolders.end(), name.GetChars()) != filter->reservedFolders.end()); + bool isspecial = name.find("/") == std::string::npos || + (filter && std::find(filter->reservedFolders.begin(), filter->reservedFolders.end(), name) != filter->reservedFolders.end()); if (isspecial) break; - name0 = name.Left(name.LastIndexOf("/")+1); - name1 = name.Left(name.IndexOf("/") + 1); + name0 = std::string(name, 0, name.rfind("/")+1); + name1 = std::string(name, 0, name.find("/") + 1); foundprefix = true; } - if (name.IndexOf(name0) != 0) + if (name.find(name0) != 0) { - if (name1.IsNotEmpty()) + if (!name1.empty()) { name0 = name1; - if (name.IndexOf(name0) != 0) + if (name.find(name0) != 0) { name0 = ""; } } - if (name0.IsEmpty()) + if (name0.empty()) break; } if (!foundspeciallump && filter) @@ -297,7 +299,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) // at least one of the more common definition lumps must be present. for (auto &p : filter->requiredPrefixes) { - if (name.IndexOf(name0 + p.c_str()) == 0 || name.LastIndexOf(p.c_str()) == ptrdiff_t(name.Len() - p.length())) + if (name.find(name0 + p) == 0 || name.rfind(p) == ptrdiff_t(name.length() - p.length())) { foundspeciallump = true; break; @@ -315,7 +317,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) FZipCentralDirectoryInfo *zip_fh = (FZipCentralDirectoryInfo *)dirptr; int len = LittleShort(zip_fh->NameLength); - FString name(dirptr + sizeof(FZipCentralDirectoryInfo), len); + std::string name(dirptr + sizeof(FZipCentralDirectoryInfo), len); dirptr += sizeof(FZipCentralDirectoryInfo) + LittleShort(zip_fh->NameLength) + LittleShort(zip_fh->ExtraLength) + @@ -328,15 +330,15 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) return false; } - if (name.IndexOf("__macosx") == 0 || name.IndexOf("__MACOSX") == 0) + if (name.find("__macosx") == 0 || name.find("__MACOSX") == 0) { skipped++; continue; // Weed out Apple's resource fork garbage right here because it interferes with safe operation. } - if (name0.IsNotEmpty()) name = name.Mid(name0.Len()); + if (!name0.empty()) name = std::string(name, name0.length()); // skip Directories - if (name.IsEmpty() || (name.Back() == '/' && LittleLong(zip_fh->UncompressedSize32) == 0)) + if (name.empty() || (name.back() == '/' && LittleLong(zip_fh->UncompressedSize32) == 0)) { skipped++; continue; @@ -351,7 +353,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Method != METHOD_IMPLODE && zip_fh->Method != METHOD_SHRINK) { - Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.c_str(), name.GetChars(), zip_fh->Method); + Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.c_str(), name.c_str(), zip_fh->Method); skipped++; continue; } @@ -359,14 +361,14 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Flags = LittleShort(zip_fh->Flags); if (zip_fh->Flags & ZF_ENCRYPTED) { - Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName.c_str(), name.GetChars()); + Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName.c_str(), name.c_str()); skipped++; continue; } - FixPathSeperator(name); - name.ToLower(); - + FixPathSeparator(&name.front()); + for (auto& c : name) c = tolower(c); + uint32_t UncompressedSize =LittleLong(zip_fh->UncompressedSize32); uint32_t CompressedSize = LittleLong(zip_fh->CompressedSize32); uint64_t LocalHeaderOffset = LittleLong(zip_fh->LocalHeaderOffset32); @@ -386,7 +388,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (zip_64->CompressedSize > 0x7fffffff || zip_64->UncompressedSize > 0x7fffffff) { // The file system is limited to 32 bit file sizes; - Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName.c_str(), name.GetChars()); + Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName.c_str(), name.c_str()); skipped++; continue; } @@ -397,7 +399,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) } } - lump_p->LumpNameSetup(name); + lump_p->LumpNameSetup(name.c_str()); lump_p->LumpSize = UncompressedSize; lump_p->Owner = this; // The start of the Reader will be determined the first time it is accessed. diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index 5b0dfdc3c..d3fa686b7 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -437,7 +437,7 @@ int FResourceFile::FilterLumps(const std::string& filtername, void *lumps, size_ bool found = FindPrefixRange(filter.c_str(), lumps, lumpsize, max, start, end); // Workaround for old Doom filter names (todo: move out of here.) - if (!found && filtername.find_first_of("doom.id.doom") == 0) + if (!found && filtername.find("doom.id.doom") == 0) { strReplace(filter, "doom.id.doom", "doom.doom"); found = FindPrefixRange(filter.c_str(), lumps, lumpsize, max, start, end); From 26713949616157145d6c1de1034fdae57945399f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 15:30:40 +0200 Subject: [PATCH 015/223] - only use standard types in WriteZip's API. --- src/common/engine/serializer.cpp | 1 + src/common/filesystem/file_zip.cpp | 30 +++++++++++++--------------- src/common/filesystem/fs_findfile.h | 2 ++ src/common/filesystem/resourcefile.h | 1 + src/g_game.cpp | 7 ++++--- 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index 8d5f9a6b8..571a314d0 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -747,6 +747,7 @@ FCompressedBuffer FSerializer::GetCompressedOutput() FCompressedBuffer buff; WriteObjects(); EndObject(); + buff.filename = nullptr; buff.mSize = (unsigned)w->mOutString.GetSize(); buff.mZipFlags = 0; buff.mCRC32 = crc32(0, (const Bytef*)w->mOutString.GetString(), buff.mSize); diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index 1048ad487..83427161e 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -593,7 +593,7 @@ static std::pair time_to_dos(struct tm *time) // //========================================================================== -int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &content, std::pair &dostime) +static int AppendToZip(FileWriter *zip_file, const FCompressedBuffer &content, std::pair &dostime) { FZipLocalFileHeader local; int position; @@ -608,7 +608,7 @@ int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &c local.CRC32 = content.mCRC32; local.UncompressedSize = LittleLong(content.mSize); local.CompressedSize = LittleLong(content.mCompressedSize); - local.NameLength = LittleShort((unsigned short)strlen(filename)); + local.NameLength = LittleShort((unsigned short)strlen(content.filename)); local.ExtraLength = 0; // Fill in local directory header. @@ -617,7 +617,7 @@ int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &c // Write out the header, file name, and file data. if (zip_file->Write(&local, sizeof(local)) != sizeof(local) || - zip_file->Write(filename, strlen(filename)) != strlen(filename) || + zip_file->Write(content.filename, strlen(content.filename)) != strlen(content.filename) || zip_file->Write(content.mBuffer, content.mCompressedSize) != content.mCompressedSize) { return -1; @@ -634,7 +634,7 @@ int AppendToZip(FileWriter *zip_file, const char *filename, FCompressedBuffer &c // //========================================================================== -int AppendCentralDirectory(FileWriter *zip_file, const char *filename, FCompressedBuffer &content, std::pair &dostime, int position) +int AppendCentralDirectory(FileWriter *zip_file, const FCompressedBuffer &content, std::pair &dostime, int position) { FZipCentralDirectoryInfo dir; @@ -650,23 +650,23 @@ int AppendCentralDirectory(FileWriter *zip_file, const char *filename, FCompress dir.CRC32 = content.mCRC32; dir.CompressedSize32 = LittleLong(content.mCompressedSize); dir.UncompressedSize32 = LittleLong(content.mSize); - dir.NameLength = LittleShort((unsigned short)strlen(filename)); + dir.NameLength = LittleShort((unsigned short)strlen(content.filename)); dir.ExtraLength = 0; dir.CommentLength = 0; dir.StartingDiskNumber = 0; dir.InternalAttributes = 0; dir.ExternalAttributes = 0; - dir.LocalHeaderOffset32 = LittleLong(position); + dir.LocalHeaderOffset32 = LittleLong((unsigned)position); if (zip_file->Write(&dir, sizeof(dir)) != sizeof(dir) || - zip_file->Write(filename, strlen(filename)) != strlen(filename)) + zip_file->Write(content.filename, strlen(content.filename)) != strlen(content.filename)) { return -1; } return 0; } -bool WriteZip(const char *filename, TArray &filenames, TArray &content) +bool WriteZip(const char* filename, const FCompressedBuffer* content, size_t contentcount) { // try to determine local time struct tm *ltime; @@ -677,14 +677,12 @@ bool WriteZip(const char *filename, TArray &filenames, TArray positions; - if (filenames.Size() != content.Size()) return false; - auto f = FileWriter::Open(filename); if (f != nullptr) { - for (unsigned i = 0; i < filenames.Size(); i++) + for (size_t i = 0; i < contentcount; i++) { - int pos = AppendToZip(f, filenames[i], content[i], dostime); + int pos = AppendToZip(f, content[i], dostime); if (pos == -1) { delete f; @@ -695,9 +693,9 @@ bool WriteZip(const char *filename, TArray &filenames, TArrayTell(); - for (unsigned i = 0; i < filenames.Size(); i++) + for (size_t i = 0; i < contentcount; i++) { - if (AppendCentralDirectory(f, filenames[i], content[i], dostime, positions[i]) < 0) + if (AppendCentralDirectory(f, content[i], dostime, positions[i]) < 0) { delete f; remove(filename); @@ -710,8 +708,8 @@ bool WriteZip(const char *filename, TArray &filenames, TArrayTell() - dirofs)); dirend.ZipCommentLength = 0; if (f->Write(&dirend, sizeof(dirend)) != sizeof(dirend)) diff --git a/src/common/filesystem/fs_findfile.h b/src/common/filesystem/fs_findfile.h index 3c81009af..85d328d43 100644 --- a/src/common/filesystem/fs_findfile.h +++ b/src/common/filesystem/fs_findfile.h @@ -19,7 +19,9 @@ struct FileListEntry using FileList = std::vector; +struct FCompressedBuffer; bool ScanDirectory(std::vector& list, const char* dirpath, const char* match, bool nosubdir = false, bool readhidden = false); +bool WriteZip(const char* filename, const FCompressedBuffer* content, size_t contentcount); inline void FixPathSeparator(char* path) { diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index df68d7c8d..c40e1c598 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -91,6 +91,7 @@ struct FCompressedBuffer int mZipFlags; unsigned mCRC32; char *mBuffer; + const char* filename; bool Decompress(char *destbuffer); void Clean() diff --git a/src/g_game.cpp b/src/g_game.cpp index e4b47082e..d1374a925 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -90,6 +90,7 @@ #include "doommenu.h" #include "screenjob.h" #include "i_interface.h" +#include "fs_findfile.h" static FRandom pr_dmspawn ("DMSpawn"); @@ -111,7 +112,6 @@ void G_DoAutoSave (); void G_DoQuickSave (); void STAT_Serialize(FSerializer &file); -bool WriteZip(const char *filename, TArray &filenames, TArray &content); CVARD_NAMED(Int, gameskill, skill, 2, CVAR_SERVERINFO|CVAR_LATCH, "sets the skill for the next newly started game") CVAR(Bool, save_formatted, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // use formatted JSON for saves (more readable but a larger files and a bit slower. @@ -2416,13 +2416,14 @@ void G_DoSaveGame (bool okForQuicksave, bool forceQuicksave, FString filename, c savegame_filenames.Push("info.json"); savegame_content.Push(savegameglobals.GetCompressedOutput()); savegame_filenames.Push("globals.json"); - G_WriteSnapshots (savegame_filenames, savegame_content); + for (unsigned i = 0; i < savegame_content.Size(); i++) + savegame_content[i].filename = savegame_filenames[i].GetChars(); bool succeeded = false; - if (WriteZip(filename, savegame_filenames, savegame_content)) + if (WriteZip(filename, savegame_content.Data(), savegame_content.Size())) { // Check whether the file is ok by trying to open it. FResourceFile *test = FResourceFile::OpenResourceFile(filename, true); From def6bffdfcbbfafb2737a4d0261f09e4adb22bf9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 15:32:53 +0200 Subject: [PATCH 016/223] - use std::vector for the MemoryArrayReader --- src/common/filesystem/file_zip.cpp | 3 --- src/common/filesystem/files.cpp | 12 ++++++------ src/common/filesystem/files.h | 4 ++-- src/common/menu/savegamemanager.cpp | 4 ++-- src/common/rendering/i_modelvertexbuffer.h | 1 + src/common/utility/cmdlib.cpp | 2 +- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index 83427161e..492a24276 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -36,10 +36,7 @@ #include #include #include "file_zip.h" -#include "cmdlib.h" - #include "w_zip.h" - #include "ancientzip.h" #include "fs_findfile.h" #include "fs_swap.h" diff --git a/src/common/filesystem/files.cpp b/src/common/filesystem/files.cpp index 88a66a59e..10ddd3832 100644 --- a/src/common/filesystem/files.cpp +++ b/src/common/filesystem/files.cpp @@ -329,26 +329,26 @@ char *MemoryReader::Gets(char *strbuf, int len) class MemoryArrayReader : public MemoryReader { - TArray buf; + std::vector buf; public: MemoryArrayReader(const char *buffer, long length) { if (length > 0) { - buf.Resize(length); + buf.resize(length); memcpy(&buf[0], buffer, length); } UpdateBuffer(); } - TArray &GetArray() { return buf; } + std::vector &GetArray() { return buf; } void UpdateBuffer() { - bufptr = (const char*)&buf[0]; + bufptr = (const char*)buf.data(); FilePos = 0; - Length = buf.Size(); + Length = (long)buf.size(); } }; @@ -397,7 +397,7 @@ bool FileReader::OpenMemoryArray(const void *mem, FileReader::Size length) return true; } -bool FileReader::OpenMemoryArray(std::function&)> getter) +bool FileReader::OpenMemoryArray(std::function&)> getter) { auto reader = new MemoryArrayReader(nullptr, 0); if (getter(reader->GetArray())) diff --git a/src/common/filesystem/files.h b/src/common/filesystem/files.h index eb4b202ac..f8b9f458e 100644 --- a/src/common/filesystem/files.h +++ b/src/common/filesystem/files.h @@ -41,8 +41,8 @@ #include #include #include -#include "basics.h" #include "fs_swap.h" + #include "tarray.h" class FileSystemException : public std::exception @@ -196,7 +196,7 @@ public: bool OpenFilePart(FileReader &parent, Size start, Size length); bool OpenMemory(const void *mem, Size length); // read directly from the buffer bool OpenMemoryArray(const void *mem, Size length); // read from a copy of the buffer. - bool OpenMemoryArray(std::function&)> getter); // read contents to a buffer and return a reader to it + bool OpenMemoryArray(std::function&)> getter); // read contents to a buffer and return a reader to it bool OpenDecompressor(FileReader &parent, Size length, int method, bool seekable, bool exceptions = false); // creates a decompressor stream. 'seekable' uses a buffered version so that the Seek and Tell methods can be used. Size Tell() const diff --git a/src/common/menu/savegamemanager.cpp b/src/common/menu/savegamemanager.cpp index 5dc22ec76..7e948267d 100644 --- a/src/common/menu/savegamemanager.cpp +++ b/src/common/menu/savegamemanager.cpp @@ -320,10 +320,10 @@ unsigned FSavegameManagerBase::ExtractSaveData(int index) { FileReader picreader; - picreader.OpenMemoryArray([=](TArray &array) + picreader.OpenMemoryArray([=](std::vector &array) { auto cache = pic->Lock(); - array.Resize(pic->LumpSize); + array.resize(pic->LumpSize); memcpy(&array[0], cache, pic->LumpSize); pic->Unlock(); return true; diff --git a/src/common/rendering/i_modelvertexbuffer.h b/src/common/rendering/i_modelvertexbuffer.h index f68d4e117..927fcfbf3 100644 --- a/src/common/rendering/i_modelvertexbuffer.h +++ b/src/common/rendering/i_modelvertexbuffer.h @@ -1,5 +1,6 @@ #pragma once +#include "basics.h" struct FModelVertex diff --git a/src/common/utility/cmdlib.cpp b/src/common/utility/cmdlib.cpp index f37bb6717..1e906e69c 100644 --- a/src/common/utility/cmdlib.cpp +++ b/src/common/utility/cmdlib.cpp @@ -983,7 +983,7 @@ void md5Update(FileReader& file, MD5Context& md5, unsigned len) while (len > 0) { - t = min(len, sizeof(readbuf)); + t = std::min(len, sizeof(readbuf)); len -= t; t = (long)file.Read(readbuf, t); md5.Update(readbuf, t); From 9f45cc046921e752d813361e285b148fa91c739f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 13:54:04 +0200 Subject: [PATCH 017/223] - use snprintf for FileWriter::Printf. pulling in stb_sprintf here may be tricky if the consuming application uses different options, so better not use it here. --- src/common/filesystem/files.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/common/filesystem/files.cpp b/src/common/filesystem/files.cpp index 10ddd3832..cd81580e6 100644 --- a/src/common/filesystem/files.cpp +++ b/src/common/filesystem/files.cpp @@ -35,7 +35,8 @@ #include #include "files.h" -#include "stb_sprintf.h" + +using namespace fs_private; using namespace fs_private; @@ -477,18 +478,16 @@ long FileWriter::Seek(long offset, int mode) size_t FileWriter::Printf(const char *fmt, ...) { - char workbuf[STB_SPRINTF_MIN]; + char c[300]; va_list arglist; va_start(arglist, fmt); - auto r = stbsp_vsprintfcb([](const char* cstr, void* data, int len) -> char* - { - auto fr = (FileWriter*)data; - auto writ = fr->Write(cstr, len); - return writ == (size_t)len? (char*)cstr : nullptr; // abort if writing caused an error. - }, this, workbuf, fmt, arglist); - + auto n = vsnprintf(c, 300, fmt, arglist); + std::string buf; + buf.resize(n); + va_start(arglist, fmt); + vsnprintf(&buf.front(), n, fmt, arglist); va_end(arglist); - return r; + return Write(buf.c_str(), n); } size_t BufferWriter::Write(const void *buffer, size_t len) From 7f024debfd1260bcb62ad9486a229de768989310 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 15:46:10 +0200 Subject: [PATCH 018/223] - clean up includes in 3 files. --- src/common/filesystem/file_whres.cpp | 13 +------------ src/common/filesystem/files.cpp | 2 -- src/common/filesystem/resourcefile.cpp | 8 ++++---- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/common/filesystem/file_whres.cpp b/src/common/filesystem/file_whres.cpp index e11ce1b73..d7149f116 100644 --- a/src/common/filesystem/file_whres.cpp +++ b/src/common/filesystem/file_whres.cpp @@ -39,18 +39,9 @@ using namespace fs_private; -#include "fs_swap.h" - -using namespace fs_private; //========================================================================== // -// -// -//========================================================================== - -//========================================================================== -// -// Wad file +// WH resource file // //========================================================================== @@ -65,9 +56,7 @@ public: //========================================================================== // -// FWadFile::FWadFile // -// Initializes a WAD file // //========================================================================== diff --git a/src/common/filesystem/files.cpp b/src/common/filesystem/files.cpp index cd81580e6..89983d87c 100644 --- a/src/common/filesystem/files.cpp +++ b/src/common/filesystem/files.cpp @@ -38,8 +38,6 @@ using namespace fs_private; -using namespace fs_private; - #ifdef _WIN32 std::wstring toWide(const char* str); #endif diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index d3fa686b7..a900c275c 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -36,9 +36,8 @@ #include #include "resourcefile.h" -#include "cmdlib.h" -#include "md5.h" +#include "md5.h" std::string ExtractBaseName(const char* path, bool include_extension) { @@ -290,9 +289,10 @@ static int nulPrintf(FSMessageLevel msg, const char* fmt, ...) FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf) { if (Printf == nullptr) Printf = nulPrintf; - for(size_t i = 0; i < countof(funcs) - containeronly; i++) + for(auto func : funcs) { - FResourceFile *resfile = funcs[i](filename, file, filter, Printf); + if (containeronly && func == CheckLump) break; + FResourceFile *resfile = func(filename, file, filter, Printf); if (resfile != NULL) return resfile; } return NULL; From 12c7413149c6112f636f521db3f5c9dfad70cb48 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 15:52:10 +0200 Subject: [PATCH 019/223] - handle ZLibError --- src/common/filesystem/files_decompress.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/common/filesystem/files_decompress.cpp b/src/common/filesystem/files_decompress.cpp index d38dfe25b..8b8f4958a 100644 --- a/src/common/filesystem/files_decompress.cpp +++ b/src/common/filesystem/files_decompress.cpp @@ -43,8 +43,6 @@ #include "files.h" -#include "cmdlib.h" - //========================================================================== // // DecompressionError @@ -87,6 +85,19 @@ void DecompressorBase::SetOwnsReader() File = &OwnedFile; } +//========================================================================== +// +// +// +//========================================================================== + +static const char* ZLibError(int zerr) +{ + static const char* const errs[6] = { "Errno", "Stream Error", "Data Error", "Memory Error", "Buffer Error", "Version Error" }; + if (zerr >= 0 || zerr < -6) return "Unknown"; + else return errs[-zerr - 1]; +} + //========================================================================== // // DecompressorZ @@ -124,9 +135,9 @@ public: if (!zip) err = inflateInit (&Stream); else err = inflateInit2 (&Stream, -MAX_WBITS); - if (err != Z_OK) + if (err < Z_OK) { - DecompressionError ("DecompressorZ: inflateInit failed: %s\n", M_ZLibError(err).GetChars()); + DecompressionError ("DecompressorZ: inflateInit failed: %s\n", ZLibError(err)); return false; } return true; From 21d6eb99ebfce8be86879a3d48b589f69f5bd380 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 16:16:56 +0200 Subject: [PATCH 020/223] use std::vector as return value for the FileReader's buffer readers. --- src/common/audio/music/i_music.cpp | 6 ++--- src/common/audio/sound/s_sound.cpp | 19 ++++++++------- src/common/audio/sound/s_soundinternal.h | 2 +- src/common/cutscenes/movieplayer.cpp | 5 ++-- src/common/engine/sc_man.cpp | 4 ++-- src/common/engine/sc_man.h | 5 ++++ src/common/filesystem/files.h | 24 +++++++++---------- src/common/textures/animlib.cpp | 2 +- src/common/textures/animlib.h | 2 +- src/common/textures/formats/anmtexture.cpp | 2 +- src/common/textures/formats/patchtexture.cpp | 4 ++-- src/common/textures/formats/pcxtexture.cpp | 12 +++++----- src/common/textures/formats/qoitexture.cpp | 4 ++-- .../textures/formats/rawpagetexture.cpp | 2 +- src/common/textures/formats/webptexture.cpp | 6 ++--- src/m_misc.cpp | 8 +++---- src/maploader/glnodes.cpp | 18 +++++++------- src/sound/s_doomsound.cpp | 4 ++-- 18 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/common/audio/music/i_music.cpp b/src/common/audio/music/i_music.cpp index 6b8580724..fd9395970 100644 --- a/src/common/audio/music/i_music.cpp +++ b/src/common/audio/music/i_music.cpp @@ -182,8 +182,8 @@ static void SetupGenMidi() auto data = fileSystem.OpenFileReader(lump); auto genmidi = data.Read(); - if (genmidi.Size() < 8 + 175 * 36 || memcmp(genmidi.Data(), "#OPL_II#", 8)) return; - ZMusic_SetGenMidi(genmidi.Data()+8); + if (genmidi.size() < 8 + 175 * 36 || memcmp(genmidi.data(), "#OPL_II#", 8)) return; + ZMusic_SetGenMidi(genmidi.data()+8); } static void SetupWgOpn() @@ -337,7 +337,7 @@ static ZMusic_MidiSource GetMIDISource(const char *fn) } auto data = wlump.Read(); - auto source = ZMusic_CreateMIDISource(data.Data(), data.Size(), type); + auto source = ZMusic_CreateMIDISource(data.data(), data.size(), type); if (source == nullptr) { diff --git a/src/common/audio/sound/s_sound.cpp b/src/common/audio/sound/s_sound.cpp index 2544d1f87..f2c44a1c1 100644 --- a/src/common/audio/sound/s_sound.cpp +++ b/src/common/audio/sound/s_sound.cpp @@ -744,32 +744,33 @@ sfxinfo_t *SoundEngine::LoadSound(sfxinfo_t *sfx) DPrintf(DMSG_NOTIFY, "Loading sound \"%s\" (%td)\n", sfx->name.GetChars(), sfx - &S_sfx[0]); auto sfxdata = ReadSound(sfx->lumpnum); - int size = sfxdata.Size(); + int size = (int)sfxdata.size(); if (size > 8) { - int32_t dmxlen = LittleLong(((int32_t *)sfxdata.Data())[1]); + auto sfxp = sfxdata.data(); + int32_t dmxlen = LittleLong(((int32_t *)sfxp)[1]); // If the sound is voc, use the custom loader. - if (strncmp ((const char *)sfxdata.Data(), "Creative Voice File", 19) == 0) + if (memcmp (sfxp, "Creative Voice File", 19) == 0) { - sfx->data = GSnd->LoadSoundVoc(sfxdata.Data(), size); + sfx->data = GSnd->LoadSoundVoc(sfxp, size); } // If the sound is raw, just load it as such. else if (sfx->bLoadRAW) { - sfx->data = GSnd->LoadSoundRaw(sfxdata.Data(), size, sfx->RawRate, 1, 8, sfx->LoopStart); + sfx->data = GSnd->LoadSoundRaw(sfxp, size, sfx->RawRate, 1, 8, sfx->LoopStart); } // Otherwise, try the sound as DMX format. - else if (((uint8_t *)sfxdata.Data())[0] == 3 && ((uint8_t *)sfxdata.Data())[1] == 0 && dmxlen <= size - 8) + else if (((uint8_t *)sfxp)[0] == 3 && ((uint8_t *)sfxp)[1] == 0 && dmxlen <= size - 8) { - int frequency = LittleShort(((uint16_t *)sfxdata.Data())[1]); + int frequency = LittleShort(((uint16_t *)sfxp)[1]); if (frequency == 0) frequency = 11025; - sfx->data = GSnd->LoadSoundRaw(sfxdata.Data()+8, dmxlen, frequency, 1, 8, sfx->LoopStart); + sfx->data = GSnd->LoadSoundRaw(sfxp+8, dmxlen, frequency, 1, 8, sfx->LoopStart); } // If that fails, let the sound system try and figure it out. else { - sfx->data = GSnd->LoadSound(sfxdata.Data(), size, sfx->LoopStart, sfx->LoopEnd); + sfx->data = GSnd->LoadSound(sfxp, size, sfx->LoopStart, sfx->LoopEnd); } } diff --git a/src/common/audio/sound/s_soundinternal.h b/src/common/audio/sound/s_soundinternal.h index 782fbe325..d8c07742c 100644 --- a/src/common/audio/sound/s_soundinternal.h +++ b/src/common/audio/sound/s_soundinternal.h @@ -216,7 +216,7 @@ private: // Checks if a copy of this sound is already playing. bool CheckSingular(FSoundID sound_id); - virtual TArray ReadSound(int lumpnum) = 0; + virtual std::vector ReadSound(int lumpnum) = 0; protected: virtual bool CheckSoundLimit(sfxinfo_t* sfx, const FVector3& pos, int near_limit, float limit_range, int sourcetype, const void* actor, int channel, float attenuation); diff --git a/src/common/cutscenes/movieplayer.cpp b/src/common/cutscenes/movieplayer.cpp index 94a7e4c60..ac915bfb0 100644 --- a/src/common/cutscenes/movieplayer.cpp +++ b/src/common/cutscenes/movieplayer.cpp @@ -153,7 +153,7 @@ class AnmPlayer : public MoviePlayer { // This doesn't need its own class type anim_t anim; - TArray buffer; + std::vector buffer; int numframes = 0; int curframe = 1; int frametime = 0; @@ -173,7 +173,7 @@ public: buffer = fr.ReadPadded(1); fr.Close(); - if (ANIM_LoadAnim(&anim, buffer.Data(), buffer.Size() - 1) < 0) + if (ANIM_LoadAnim(&anim, buffer.data(), buffer.size() - 1) < 0) { return; } @@ -231,7 +231,6 @@ public: ~AnmPlayer() { - buffer.Reset(); animtex.Clean(); } diff --git a/src/common/engine/sc_man.cpp b/src/common/engine/sc_man.cpp index 1568f677b..98de9f0b1 100644 --- a/src/common/engine/sc_man.cpp +++ b/src/common/engine/sc_man.cpp @@ -148,9 +148,9 @@ bool FScanner::OpenFile (const char *name) if (!fr.OpenFile(name)) return false; auto filesize = fr.GetLength(); auto filebuff = fr.Read(); - if (filebuff.Size() == 0 && filesize > 0) return false; + if (filebuff.size() == 0 && filesize > 0) return false; - ScriptBuffer = FString((const char *)filebuff.Data(), filesize); + ScriptBuffer = FString((const char *)filebuff.data(), filesize); ScriptName = name; // This is used for error messages so the full file name is preferable LumpNum = -1; PrepareScript (); diff --git a/src/common/engine/sc_man.h b/src/common/engine/sc_man.h index 4d66b5f21..307831dba 100644 --- a/src/common/engine/sc_man.h +++ b/src/common/engine/sc_man.h @@ -1,6 +1,7 @@ #ifndef __SC_MAN_H__ #define __SC_MAN_H__ +#include #include "zstring.h" #include "tarray.h" #include "name.h" @@ -74,6 +75,10 @@ public: { OpenMem(name, (const char*)buffer.Data(), buffer.Size()); } + void OpenMem(const char* name, const std::vector& buffer) + { + OpenMem(name, (const char*)buffer.data(), (int)buffer.size()); + } void OpenString(const char *name, FString buffer); void OpenLumpNum(int lump); void Close(); diff --git a/src/common/filesystem/files.h b/src/common/filesystem/files.h index f8b9f458e..99a3b133f 100644 --- a/src/common/filesystem/files.h +++ b/src/common/filesystem/files.h @@ -214,28 +214,26 @@ public: return mReader->Read(buffer, (long)len); } - TArray Read(size_t len) + std::vector Read(size_t len) { - TArray buffer((int)len, true); + std::vector buffer(len); Size length = mReader->Read(&buffer[0], (long)len); - buffer.Clamp((int)length); + buffer.resize((size_t)length); return buffer; } - TArray Read() + std::vector Read() { - TArray buffer(mReader->Length, true); - Size length = mReader->Read(&buffer[0], mReader->Length); - if (length < mReader->Length) buffer.Clear(); - return buffer; + return Read(GetLength()); } - TArray ReadPadded(int padding) + std::vector ReadPadded(size_t padding) { - TArray buffer(mReader->Length + padding, true); - Size length = mReader->Read(&buffer[0], mReader->Length); - if (length < mReader->Length) buffer.Clear(); - else memset(buffer.Data() + mReader->Length, 0, padding); + auto len = GetLength(); + std::vector buffer(len + padding); + Size length = mReader->Read(&buffer[0], (long)len); + if (length < len) buffer.clear(); + else memset(buffer.data() + len, 0, padding); return buffer; } diff --git a/src/common/textures/animlib.cpp b/src/common/textures/animlib.cpp index e42386bd9..949027786 100644 --- a/src/common/textures/animlib.cpp +++ b/src/common/textures/animlib.cpp @@ -217,7 +217,7 @@ static inline void drawframe(anim_t *anim, uint16_t framenumber) } // is the file size, for consistency checking. -int32_t ANIM_LoadAnim(anim_t *anim, uint8_t *buffer, int32_t length) +int32_t ANIM_LoadAnim(anim_t *anim, uint8_t *buffer, size_t length) { if (memcmp(buffer, "LPF ", 4)) return -1; diff --git a/src/common/textures/animlib.h b/src/common/textures/animlib.h index 661f00fb2..1fdaa354f 100644 --- a/src/common/textures/animlib.h +++ b/src/common/textures/animlib.h @@ -105,7 +105,7 @@ struct anim_t // //**************************************************************************** -int32_t ANIM_LoadAnim(anim_t *anim, uint8_t *buffer, int32_t length); +int32_t ANIM_LoadAnim(anim_t *anim, uint8_t *buffer, size_t length); //**************************************************************************** // diff --git a/src/common/textures/formats/anmtexture.cpp b/src/common/textures/formats/anmtexture.cpp index eeea41a89..f4fb332f0 100644 --- a/src/common/textures/formats/anmtexture.cpp +++ b/src/common/textures/formats/anmtexture.cpp @@ -73,7 +73,7 @@ FImageSource *AnmImage_TryCreate(FileReader & file, int lumpnum) auto buffer = file.ReadPadded(1); anim_t anim; - if (ANIM_LoadAnim(&anim, buffer.Data(), buffer.Size() - 1) < 0) + if (ANIM_LoadAnim(&anim, buffer.data(), buffer.size() - 1) < 0) { return nullptr; } diff --git a/src/common/textures/formats/patchtexture.cpp b/src/common/textures/formats/patchtexture.cpp index ecbd09147..d64e003e2 100644 --- a/src/common/textures/formats/patchtexture.cpp +++ b/src/common/textures/formats/patchtexture.cpp @@ -81,7 +81,7 @@ static bool CheckIfPatch(FileReader & file, bool &isalpha) file.Seek(0, FileReader::SeekSet); auto data = file.Read(file.GetLength()); - const patch_t *foo = (const patch_t *)data.Data(); + const patch_t *foo = (const patch_t *)data.data(); int height = LittleShort(foo->height); int width = LittleShort(foo->width); @@ -111,7 +111,7 @@ static bool CheckIfPatch(FileReader & file, bool &isalpha) { // only check this if the texture passed validation. // Here is a good point because we already have a valid buffer of the lump's data. - isalpha = checkPatchForAlpha(data.Data(), (uint32_t)file.GetLength()); + isalpha = checkPatchForAlpha(data.data(), (uint32_t)file.GetLength()); } return !gapAtStart; } diff --git a/src/common/textures/formats/pcxtexture.cpp b/src/common/textures/formats/pcxtexture.cpp index 7e97ba2ef..bc014659f 100644 --- a/src/common/textures/formats/pcxtexture.cpp +++ b/src/common/textures/formats/pcxtexture.cpp @@ -160,8 +160,8 @@ void FPCXTexture::ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr) int rle_count = 0; uint8_t rle_value = 0; - TArray srcp = lump.Read(lump.GetLength() - sizeof(PCXHeader)); - uint8_t * src = srcp.Data(); + auto srcp = lump.Read(lump.GetLength() - sizeof(PCXHeader)); + uint8_t * src = srcp.data(); for (y = 0; y < Height; ++y) { @@ -210,8 +210,8 @@ void FPCXTexture::ReadPCX4bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr) TArray line(hdr->bytesPerScanLine, true); TArray colorIndex(Width, true); - TArray srcp = lump.Read(lump.GetLength() - sizeof(PCXHeader)); - uint8_t * src = srcp.Data(); + auto srcp = lump.Read(lump.GetLength() - sizeof(PCXHeader)); + uint8_t * src = srcp.data(); for (y = 0; y < Height; ++y) { @@ -265,7 +265,7 @@ void FPCXTexture::ReadPCX8bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr) int y, bytes; auto srcp = lump.Read(lump.GetLength() - sizeof(PCXHeader)); - uint8_t * src = srcp.Data(); + uint8_t * src = srcp.data(); for (y = 0; y < Height; ++y) { @@ -306,7 +306,7 @@ void FPCXTexture::ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr int bytes; auto srcp = lump.Read(lump.GetLength() - sizeof(PCXHeader)); - uint8_t * src = srcp.Data(); + uint8_t * src = srcp.data(); for (y = 0; y < Height; ++y) { diff --git a/src/common/textures/formats/qoitexture.cpp b/src/common/textures/formats/qoitexture.cpp index d0aa2fd81..223a0b70e 100644 --- a/src/common/textures/formats/qoitexture.cpp +++ b/src/common/textures/formats/qoitexture.cpp @@ -142,13 +142,13 @@ int FQOITexture::CopyPixels(FBitmap *bmp, int conversion) auto lump = fileSystem.OpenFileReader(SourceLump); auto bytes = lump.Read(); - if (bytes.Size() < 22) return 0; // error + if (bytes.size() < 22) return 0; // error PalEntry index[64] = {}; PalEntry pe = 0xff000000; size_t p = 14, run = 0; - size_t chunks_len = bytes.Size() - 8; + size_t chunks_len = bytes.size() - 8; for (int h = 0; h < Height; h++) { diff --git a/src/common/textures/formats/rawpagetexture.cpp b/src/common/textures/formats/rawpagetexture.cpp index 09d07d0ce..d28714d81 100644 --- a/src/common/textures/formats/rawpagetexture.cpp +++ b/src/common/textures/formats/rawpagetexture.cpp @@ -74,7 +74,7 @@ bool CheckIfRaw(FileReader & data, unsigned desiredsize) data.Seek(0, FileReader::SeekSet); auto bits = data.Read(data.GetLength()); - foo = (patch_t *)bits.Data(); + foo = (patch_t *)bits.data(); height = LittleShort(foo->height); width = LittleShort(foo->width); diff --git a/src/common/textures/formats/webptexture.cpp b/src/common/textures/formats/webptexture.cpp index 60a9ccbc3..dd9a9c388 100644 --- a/src/common/textures/formats/webptexture.cpp +++ b/src/common/textures/formats/webptexture.cpp @@ -59,9 +59,9 @@ FImageSource *WebPImage_TryCreate(FileReader &file, int lumpnum) file.Seek(0, FileReader::SeekSet); auto bytes = file.Read(); - if (WebPGetInfo(bytes.Data(), bytes.Size(), &width, &height)) + if (WebPGetInfo(bytes.data(), bytes.size(), &width, &height)) { - WebPData data{ bytes.Data(), bytes.Size() }; + WebPData data{ bytes.data(), bytes.size() }; WebPData chunk_data; auto mux = WebPMuxCreate(&data, 0); if (mux) @@ -137,7 +137,7 @@ int FWebPTexture::CopyPixels(FBitmap *bmp, int conversion) config.output.u.RGBA.stride = bmp->GetPitch(); config.output.is_external_memory = 1; - (void)WebPDecode(bytes.Data(), bytes.Size(), &config); + (void)WebPDecode(bytes.data(), bytes.size(), &config); return 0; } diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 45af80cec..5960dfa36 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -98,7 +98,7 @@ void M_FindResponseFile (void) else { char **argv; - TArray file; + std::vector file; int argc = 0; int size; size_t argsize = 0; @@ -119,8 +119,8 @@ void M_FindResponseFile (void) Printf ("Found response file %s!\n", Args->GetArg(i) + 1); size = (int)fr.GetLength(); file = fr.Read (size); - file[size] = 0; - argsize = ParseCommandLine ((char*)file.Data(), &argc, NULL); + file.push_back(0); + argsize = ParseCommandLine ((char*)file.data(), &argc, NULL); } } else @@ -132,7 +132,7 @@ void M_FindResponseFile (void) { argv = (char **)M_Malloc (argc*sizeof(char *) + argsize); argv[0] = (char *)argv + argc*sizeof(char *); - ParseCommandLine ((char*)file.Data(), NULL, argv); + ParseCommandLine ((char*)file.data(), NULL, argv); // Create a new argument vector FArgs *newargs = new FArgs; diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index 38fa976fd..76f0de303 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -209,7 +209,7 @@ bool MapLoader::LoadGLVertexes(FileReader &lump) auto gllen=lump.GetLength(); if (gllen < 4) return false; - auto gldata = glbuf.Data(); + auto gldata = glbuf.data(); if (*(int *)gldata == gNd5) { @@ -288,13 +288,13 @@ bool MapLoader::LoadGLSegs(FileReader &lump) const unsigned numverts = Level->vertexes.Size(); const unsigned numlines = Level->lines.Size(); - if (!format5 && memcmp(data.Data(), "gNd3", 4)) + if (!format5 && memcmp(data.data(), "gNd3", 4)) { numsegs/=sizeof(glseg_t); segs.Alloc(numsegs); memset(&segs[0],0,sizeof(seg_t)*numsegs); - glseg_t * ml = (glseg_t*)data.Data(); + glseg_t * ml = (glseg_t*)data.data(); for(i = 0; i < numsegs; i++) { // check for gl-vertices @@ -365,7 +365,7 @@ bool MapLoader::LoadGLSegs(FileReader &lump) segs.Alloc(numsegs); memset(&segs[0],0,sizeof(seg_t)*numsegs); - glseg3_t * ml = (glseg3_t*)(data.Data() + (format5? 0:4)); + glseg3_t * ml = (glseg3_t*)(data.data() + (format5? 0:4)); for(i = 0; i < numsegs; i++) { // check for gl-vertices const unsigned v1idx = checkGLVertex3(LittleLong(ml->v1)); @@ -454,9 +454,9 @@ bool MapLoader::LoadGLSubsectors(FileReader &lump) return false; } - if (!format5 && memcmp(datab.Data(), "gNd3", 4)) + if (!format5 && memcmp(datab.data(), "gNd3", 4)) { - mapsubsector_t * data = (mapsubsector_t*) datab.Data(); + mapsubsector_t * data = (mapsubsector_t*) datab.data(); numsubsectors /= sizeof(mapsubsector_t); Level->subsectors.Alloc(numsubsectors); auto &subsectors = Level->subsectors; @@ -478,7 +478,7 @@ bool MapLoader::LoadGLSubsectors(FileReader &lump) } else { - gl3_mapsubsector_t * data = (gl3_mapsubsector_t*) (datab.Data()+(format5? 0:4)); + gl3_mapsubsector_t * data = (gl3_mapsubsector_t*) (datab.data()+(format5? 0:4)); numsubsectors /= sizeof(gl3_mapsubsector_t); Level->subsectors.Alloc(numsubsectors); auto &subsectors = Level->subsectors; @@ -545,7 +545,7 @@ bool MapLoader::LoadNodes (FileReader &lump) lump.Seek(0, FileReader::SeekSet); auto buf = lump.Read(); - basemn = mn = (mapnode_t*)buf.Data(); + basemn = mn = (mapnode_t*)buf.data(); used.Resize(numnodes); memset (used.Data(), 0, sizeof(uint16_t)*numnodes); @@ -601,7 +601,7 @@ bool MapLoader::LoadNodes (FileReader &lump) lump.Seek(0, FileReader::SeekSet); auto buf = lump.Read(); - basemn = mn = (gl5_mapnode_t*)buf.Data(); + basemn = mn = (gl5_mapnode_t*)buf.data(); used.Resize(numnodes); memset(used.Data(), 0, sizeof(uint16_t)*numnodes); diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index 50509eb3d..6a67fa446 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -81,7 +81,7 @@ class DoomSoundEngine : public SoundEngine void CalcPosVel(int type, const void* source, const float pt[3], int channum, int chanflags, FSoundID soundid, FVector3* pos, FVector3* vel, FSoundChan *) override; bool ValidatePosVel(int sourcetype, const void* source, const FVector3& pos, const FVector3& vel); - TArray ReadSound(int lumpnum); + std::vector ReadSound(int lumpnum); FSoundID PickReplacement(FSoundID refid); FSoundID ResolveSound(const void *ent, int type, FSoundID soundid, float &attenuation) override; void CacheSound(sfxinfo_t* sfx) override; @@ -1165,7 +1165,7 @@ bool DoomSoundEngine::ValidatePosVel(int sourcetype, const void* source, const F // //========================================================================== -TArray DoomSoundEngine::ReadSound(int lumpnum) +std::vector DoomSoundEngine::ReadSound(int lumpnum) { auto wlump = fileSystem.OpenFileReader(lumpnum); return wlump.Read(); From 5398045f7de81728fa6e67772bf963d8d2d41994 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 16:49:07 +0200 Subject: [PATCH 021/223] - got rid of FileSystem::GetFileData. Using FMemFile is better in all these places. --- src/common/audio/music/i_music.cpp | 7 +++-- src/common/engine/sc_man.cpp | 2 +- src/common/engine/stringtable.cpp | 26 +++++++++---------- src/common/engine/stringtable.h | 8 +++--- src/common/filesystem/filesystem.cpp | 30 ++-------------------- src/common/filesystem/filesystem.h | 10 ++------ src/common/textures/formats/qoitexture.cpp | 8 +++--- src/common/utility/zstring.h | 4 ++- src/d_iwad.cpp | 8 +++--- src/d_main.cpp | 4 +-- src/gamedata/xlat/parsecontext.cpp | 10 ++++---- src/gamedata/xlat/parsecontext.h | 2 +- src/playsim/fragglescript/t_prepro.cpp | 12 +++------ src/sound/s_doomsound.cpp | 3 ++- 14 files changed, 50 insertions(+), 84 deletions(-) diff --git a/src/common/audio/music/i_music.cpp b/src/common/audio/music/i_music.cpp index fd9395970..9a8ddfe81 100644 --- a/src/common/audio/music/i_music.cpp +++ b/src/common/audio/music/i_music.cpp @@ -179,11 +179,10 @@ static void SetupGenMidi() Printf("No GENMIDI lump found. OPL playback not available.\n"); return; } - auto data = fileSystem.OpenFileReader(lump); + auto genmidi = fileSystem.ReadFile(lump); - auto genmidi = data.Read(); - if (genmidi.size() < 8 + 175 * 36 || memcmp(genmidi.data(), "#OPL_II#", 8)) return; - ZMusic_SetGenMidi(genmidi.data()+8); + if (genmidi.GetSize() < 8 + 175 * 36 || memcmp(genmidi.GetMem(), "#OPL_II#", 8)) return; + ZMusic_SetGenMidi((uint8_t*)genmidi.GetString().GetChars() + 8); } static void SetupWgOpn() diff --git a/src/common/engine/sc_man.cpp b/src/common/engine/sc_man.cpp index 98de9f0b1..bc50c7925 100644 --- a/src/common/engine/sc_man.cpp +++ b/src/common/engine/sc_man.cpp @@ -136,7 +136,7 @@ void FScanner::Open (const char *name) // // FScanner :: OpenFile // -// Loads a script from a file. Uses new/delete for memory allocation. +// Loads a script from a file. // //========================================================================== diff --git a/src/common/engine/stringtable.cpp b/src/common/engine/stringtable.cpp index 92819c144..68cec6db8 100644 --- a/src/common/engine/stringtable.cpp +++ b/src/common/engine/stringtable.cpp @@ -60,10 +60,10 @@ void FStringTable::LoadStrings (const char *language) lastlump = 0; while ((lump = fileSystem.FindLump ("LANGUAGE", &lastlump)) != -1) { - auto lumpdata = fileSystem.GetFileData(lump); + auto lumpdata = fileSystem.ReadFile(lump); - if (!ParseLanguageCSV(lump, lumpdata)) - LoadLanguage (lump, lumpdata); + if (!ParseLanguageCSV(lump, lumpdata.GetString(), lumpdata.GetSize())) + LoadLanguage (lump, lumpdata.GetString(), lumpdata.GetSize()); } UpdateLanguage(language); allMacros.Clear(); @@ -77,9 +77,9 @@ void FStringTable::LoadStrings (const char *language) //========================================================================== -TArray> FStringTable::parseCSV(const TArray &buffer) +TArray> FStringTable::parseCSV(const char* buffer, size_t size) { - const size_t bufLength = buffer.Size(); + const size_t bufLength = size; TArray> data; TArray row; TArray cell; @@ -158,8 +158,8 @@ TArray> FStringTable::parseCSV(const TArray &buffer) bool FStringTable::readMacros(int lumpnum) { - auto lumpdata = fileSystem.GetFileData(lumpnum); - auto data = parseCSV(lumpdata); + auto lumpdata = fileSystem.ReadFile(lumpnum); + auto data = parseCSV(lumpdata.GetString(), lumpdata.GetSize()); for (unsigned i = 1; i < data.Size(); i++) { @@ -186,11 +186,11 @@ bool FStringTable::readMacros(int lumpnum) // //========================================================================== -bool FStringTable::ParseLanguageCSV(int lumpnum, const TArray &buffer) +bool FStringTable::ParseLanguageCSV(int lumpnum, const char* buffer, size_t size) { - if (buffer.Size() < 11) return false; - if (strnicmp((const char*)buffer.Data(), "default,", 8) && strnicmp((const char*)buffer.Data(), "identifier,", 11 )) return false; - auto data = parseCSV(buffer); + if (size < 11) return false; + if (strnicmp(buffer, "default,", 8) && strnicmp(buffer, "identifier,", 11 )) return false; + auto data = parseCSV(buffer, size); int labelcol = -1; int filtercol = -1; @@ -282,14 +282,14 @@ bool FStringTable::ParseLanguageCSV(int lumpnum, const TArray &buffer) // //========================================================================== -void FStringTable::LoadLanguage (int lumpnum, const TArray &buffer) +void FStringTable::LoadLanguage (int lumpnum, const char* buffer, size_t size) { bool errordone = false; TArray activeMaps; FScanner sc; bool hasDefaultEntry = false; - sc.OpenMem("LANGUAGE", buffer); + sc.OpenMem("LANGUAGE", buffer, (int)size); sc.SetCMode (true); while (sc.GetString ()) { diff --git a/src/common/engine/stringtable.h b/src/common/engine/stringtable.h index d75864303..df1508ae8 100644 --- a/src/common/engine/stringtable.h +++ b/src/common/engine/stringtable.h @@ -44,6 +44,7 @@ #include +#include #include "basics.h" #include "zstring.h" #include "tarray.h" @@ -111,11 +112,10 @@ private: LangMap allStrings; TArray> currentLanguageSet; - void LoadLanguage (int lumpnum, const TArray &buffer); - TArray> parseCSV(const TArray &buffer); - bool ParseLanguageCSV(int lumpnum, const TArray &buffer); + void LoadLanguage (int lumpnum, const char* buffer, size_t size); + TArray> parseCSV(const char* buffer, size_t size); + bool ParseLanguageCSV(int lumpnum, const char* buffer, size_t size); - bool LoadLanguageFromSpreadsheet(int lumpnum, const TArray &buffer); bool readMacros(int lumpnum); void DeleteString(int langid, FName label); void DeleteForLabel(int lumpnum, FName label); diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 7e6964632..796c319c9 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -1294,32 +1294,6 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, TArray &r return result.Size(); } -//========================================================================== -// -// GetFileData -// -// Loads the lump into a TArray and returns it. -// -//========================================================================== - -TArray FileSystem::GetFileData(int lump, int pad) -{ - if ((size_t)lump >= FileInfo.Size()) - return TArray(); - - auto lumpr = OpenFileReader(lump); - auto size = lumpr.GetLength(); - TArray data(size + pad, true); - auto numread = lumpr.Read(data.Data(), size); - - if (numread != size) - { - throw FileSystemException("GetFileData: only read %ld of %ld on lump %i\n", - numread, size, lump); - } - if (pad > 0) memset(&data[size], 0, pad); - return data; -} //========================================================================== // // W_ReadFile @@ -1352,7 +1326,7 @@ void FileSystem::ReadFile (int lump, void *dest) FileData FileSystem::ReadFile (int lump) { - return FileData(FString(ELumpNum(lump))); + return FileData(FString(*this, ELumpNum(lump))); } //========================================================================== @@ -1578,7 +1552,7 @@ FileData::~FileData () { } -FString::FString (ELumpNum lumpnum) +FString::FString (FileSystem& fileSystem, ELumpNum lumpnum) { auto lumpr = fileSystem.OpenFileReader ((int)lumpnum); auto size = lumpr.GetLength (); diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index b6ce6bad8..97eece802 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -125,16 +125,10 @@ public: inline int GetNumForFullName (const FString &name) { return GetNumForFullName(name.GetChars()); } void ReadFile (int lump, void *dest); - TArray GetFileData(int lump, int pad = 0); // reads lump into a writable buffer and optionally adds some padding at the end. (FileData isn't writable!) + // These should only be used if the file data really needs padding. FileData ReadFile (int lump); FileData ReadFile (const char *name) { return ReadFile (GetNumForName (name)); } - - inline TArray LoadFile(const char* name, int padding = 0) - { - auto lump = FindFile(name); - if (lump < 0) return TArray(); - return GetFileData(lump, padding); - } + FileData ReadFileFullName(const char* name) { return ReadFile(GetNumForFullName(name)); } FileReader OpenFileReader(int lump); // opens a reader that redirects to the containing file's one. FileReader ReopenFileReader(int lump, bool alwayscache = false); // opens an independent reader. diff --git a/src/common/textures/formats/qoitexture.cpp b/src/common/textures/formats/qoitexture.cpp index 223a0b70e..abe628223 100644 --- a/src/common/textures/formats/qoitexture.cpp +++ b/src/common/textures/formats/qoitexture.cpp @@ -140,15 +140,15 @@ int FQOITexture::CopyPixels(FBitmap *bmp, int conversion) constexpr auto QOI_COLOR_HASH = [](PalEntry C) { return (C.r * 3 + C.g * 5 + C.b * 7 + C.a * 11); }; - auto lump = fileSystem.OpenFileReader(SourceLump); - auto bytes = lump.Read(); - if (bytes.size() < 22) return 0; // error + auto lump = fileSystem.ReadFile(SourceLump); + if (lump.GetSize() < 22) return 0; // error PalEntry index[64] = {}; PalEntry pe = 0xff000000; size_t p = 14, run = 0; - size_t chunks_len = bytes.size() - 8; + size_t chunks_len = lump.GetSize() - 8; + auto bytes = (const uint8_t*)lump.GetMem(); for (int h = 0; h < Height; h++) { diff --git a/src/common/utility/zstring.h b/src/common/utility/zstring.h index 50e41d9c6..89ae13568 100644 --- a/src/common/utility/zstring.h +++ b/src/common/utility/zstring.h @@ -117,6 +117,8 @@ enum ELumpNum { }; +class FileSystem; + class FString { public: @@ -146,7 +148,7 @@ public: FString (char head, const FString &tail); // Other constructors - FString (ELumpNum); // Create from a lump + FString (FileSystem&, ELumpNum); // Create from a lump ~FString (); diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index bfa67961a..62e4e459b 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -314,8 +314,8 @@ FIWadManager::FIWadManager(const char *firstfn, const char *optfn) int num = check.CheckNumForName("IWADINFO"); if (num >= 0) { - auto data = check.GetFileData(num); - ParseIWadInfo("IWADINFO", (const char*)data.Data(), data.Size()); + auto data = check.ReadFile(num); + ParseIWadInfo("IWADINFO", data.GetString(), (int)data.GetSize()); } } } @@ -399,8 +399,8 @@ int FIWadManager::CheckIWADInfo(const char* fn) { FIWADInfo result; - auto data = check.GetFileData(num); - ParseIWadInfo(fn, (const char*)data.Data(), data.Size(), &result); + auto data = check.ReadFile(num); + ParseIWadInfo(fn, data.GetString(), (int)data.GetSize(), &result); for (unsigned i = 0, count = mIWadInfos.Size(); i < count; ++i) { diff --git a/src/d_main.cpp b/src/d_main.cpp index d96467158..5660c4ed2 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1934,9 +1934,9 @@ static FString CheckGameInfo(TArray & pwads) if (num >= 0) { // Found one! - auto data = check.GetFileData(num); + auto data = check.ReadFile(num); auto wadname = check.GetResourceFileName(check.GetFileContainer(num)); - return ParseGameInfo(pwads, wadname, (const char*)data.Data(), data.Size()); + return ParseGameInfo(pwads, wadname, data.GetString(), (int)data.GetSize()); } } return ""; diff --git a/src/gamedata/xlat/parsecontext.cpp b/src/gamedata/xlat/parsecontext.cpp index cac663cfc..1810af55d 100644 --- a/src/gamedata/xlat/parsecontext.cpp +++ b/src/gamedata/xlat/parsecontext.cpp @@ -78,7 +78,7 @@ bool FParseContext::FindSym (char *sym, FParseSymbol **val) // // //========================================================================== -int FParseContext::GetToken (char *&sourcep, FParseToken *yylval) +int FParseContext::GetToken (const char *&sourcep, FParseToken *yylval) { char token[80]; int toksize; @@ -103,7 +103,7 @@ loop: c = *sourcep++; if (c == 'x' || c == 'X') { - yylval->val = (int)strtoll(sourcep, &sourcep, 16); + yylval->val = (int)strtoll(sourcep, (char**)&sourcep, 16); return TokenTrans[NUM]; } else @@ -118,7 +118,7 @@ loop: if (*endp == '.') { // It's a float - yylval->fval = strtod(sourcep, &sourcep); + yylval->fval = strtod(sourcep, (char**)& sourcep); return TokenTrans[FLOATVAL]; } else @@ -323,12 +323,12 @@ void FParseContext::ParseLump(const char *lumpname) } // Read the lump into a buffer and add a 0-terminator - auto lumpdata = fileSystem.GetFileData(lumpno, 1); + auto lumpdata = fileSystem.ReadFile(lumpno); SourceLine = 0; SourceFile = lumpname; - char *sourcep = (char*)lumpdata.Data(); + const char *sourcep = lumpdata.GetString(); while ( (tokentype = GetToken(sourcep, &token)) ) { // It is much easier to handle include statements outside the main parser. diff --git a/src/gamedata/xlat/parsecontext.h b/src/gamedata/xlat/parsecontext.h index 48a342547..82c345f78 100644 --- a/src/gamedata/xlat/parsecontext.h +++ b/src/gamedata/xlat/parsecontext.h @@ -146,7 +146,7 @@ struct FParseContext void AddSym (char *sym, int val); bool FindSym (char *sym, FParseSymbol **val); virtual bool FindToken (char *tok, int *type) = 0; - int GetToken (char *&sourcep, FParseToken *yylval); + int GetToken (const char *&sourcep, FParseToken *yylval); int PrintError (const char *s); void ParseLump(const char *lumpname); }; diff --git a/src/playsim/fragglescript/t_prepro.cpp b/src/playsim/fragglescript/t_prepro.cpp index 409faa132..495092581 100644 --- a/src/playsim/fragglescript/t_prepro.cpp +++ b/src/playsim/fragglescript/t_prepro.cpp @@ -410,7 +410,6 @@ void DFsScript::Preprocess(FLevelLocals *Level) void DFsScript::ParseInclude(FLevelLocals *Level, char *lumpname) { int lumpnum; - char *lump; if((lumpnum = fileSystem.CheckNumForName(lumpname)) == -1) { @@ -419,21 +418,18 @@ void DFsScript::ParseInclude(FLevelLocals *Level, char *lumpname) } int lumplen=fileSystem.FileLength(lumpnum); - lump=new char[lumplen+10]; - fileSystem.ReadFile(lumpnum,lump); + TArray lump(lumplen + 10); + fileSystem.ReadFile(lumpnum,lump.Data()); lump[lumplen]=0; // preprocess the include // we assume that it does not include sections or labels or // other nasty things - ProcessFindChar(lump, 0); + ProcessFindChar(lump.Data(), 0); // now parse the lump FParser parse(Level, this); - parse.Run(lump, lump, lump+lumplen); - - // free the lump - delete[] lump; + parse.Run(lump.Data(), lump.Data(), lump.Data() + lumplen); } diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index 6a67fa446..9f000f4c7 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -237,7 +237,8 @@ void S_Init() TArray curve; if (curvelump >= 0) { - curve = fileSystem.GetFileData(curvelump); + curve.Resize(fileSystem.FileLength(curvelump)); + fileSystem.ReadFile(curvelump, curve.Data()); } soundEngine->Init(curve); } From eccbafc1bc18a16111804b50bf7e239a8d8f32ed Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 18:46:21 +0200 Subject: [PATCH 022/223] - let FileData.GetString only return a const char pointer. Not exposing the implementation will allow a lot more optimization in the backend and we also want to get rid of FString here. --- src/common/audio/music/i_music.cpp | 2 +- src/common/filesystem/filesystem.h | 4 ++-- src/common/rendering/gl/gl_shader.cpp | 24 +++++++++---------- src/common/rendering/gl/gl_shaderprogram.cpp | 2 +- src/common/rendering/gles/gles_shader.cpp | 24 +++++++++---------- .../rendering/gles/gles_shaderprogram.cpp | 2 +- .../rendering/vulkan/shaders/vk_ppshader.cpp | 2 +- src/common/scripting/interface/vmnatives.cpp | 2 +- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/common/audio/music/i_music.cpp b/src/common/audio/music/i_music.cpp index 9a8ddfe81..d7460fc76 100644 --- a/src/common/audio/music/i_music.cpp +++ b/src/common/audio/music/i_music.cpp @@ -182,7 +182,7 @@ static void SetupGenMidi() auto genmidi = fileSystem.ReadFile(lump); if (genmidi.GetSize() < 8 + 175 * 36 || memcmp(genmidi.GetMem(), "#OPL_II#", 8)) return; - ZMusic_SetGenMidi((uint8_t*)genmidi.GetString().GetChars() + 8); + ZMusic_SetGenMidi((uint8_t*)genmidi.GetString() + 8); } static void SetupWgOpn() diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index 97eece802..febb76911 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -35,9 +35,9 @@ public: FileData (const FileData ©); FileData &operator= (const FileData ©); ~FileData (); - void *GetMem () { return Block.Len() == 0 ? NULL : (void *)Block.GetChars(); } + const void *GetMem () { return Block.Len() == 0 ? NULL : (void *)Block.GetChars(); } size_t GetSize () { return Block.Len(); } - const FString &GetString () const { return Block; } + const char* GetString () const { return Block.GetChars(); } private: FileData (const FString &source); diff --git a/src/common/rendering/gl/gl_shader.cpp b/src/common/rendering/gl/gl_shader.cpp index d1b6aee54..85ba5c1eb 100644 --- a/src/common/rendering/gl/gl_shader.cpp +++ b/src/common/rendering/gl/gl_shader.cpp @@ -423,27 +423,27 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * int pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump, 0); // if it's a core shader, ignore overrides by user mods. if (pp_lump == -1) pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump); if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump); - FileData pp_data = fileSystem.ReadFile(pp_lump); + FString pp_data = fileSystem.ReadFile(pp_lump).GetString(); - if (pp_data.GetString().IndexOf("ProcessMaterial") < 0 && pp_data.GetString().IndexOf("SetupMaterial") < 0) + if (pp_data.IndexOf("ProcessMaterial") < 0 && pp_data.IndexOf("SetupMaterial") < 0) { // this looks like an old custom hardware shader. - if (pp_data.GetString().IndexOf("GetTexCoord") >= 0) + if (pp_data.IndexOf("GetTexCoord") >= 0) { int pl_lump = fileSystem.CheckNumForFullName("shaders/glsl/func_defaultmat2.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultmat2.fp"); FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString().GetChars(); + fp_comb << "\n" << pl_data.GetString(); } else { int pl_lump = fileSystem.CheckNumForFullName("shaders/glsl/func_defaultmat.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultmat.fp"); FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString().GetChars(); + fp_comb << "\n" << pl_data.GetString(); - if (pp_data.GetString().IndexOf("ProcessTexel") < 0) + if (pp_data.IndexOf("ProcessTexel") < 0) { // this looks like an even older custom hardware shader. // We need to replace the ProcessTexel call to make it work. @@ -452,7 +452,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * } } - if (pp_data.GetString().IndexOf("ProcessLight") >= 0) + if (pp_data.IndexOf("ProcessLight") >= 0) { // The ProcessLight signatured changed. Forward to the old one. fp_comb << "\nvec4 ProcessLight(vec4 color);\n"; @@ -460,19 +460,19 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * } } - fp_comb << RemoveLegacyUserUniforms(pp_data.GetString()).GetChars(); + fp_comb << RemoveLegacyUserUniforms(pp_data).GetChars(); fp_comb.Substitute("gl_TexCoord[0]", "vTexCoord"); // fix old custom shaders. - if (pp_data.GetString().IndexOf("ProcessLight") < 0) + if (pp_data.IndexOf("ProcessLight") < 0) { int pl_lump = fileSystem.CheckNumForFullName("shaders/glsl/func_defaultlight.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultlight.fp"); FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString().GetChars(); + fp_comb << "\n" << pl_data.GetString(); } // ProcessMaterial must be considered broken because it requires the user to fill in data they possibly cannot know all about. - if (pp_data.GetString().IndexOf("ProcessMaterial") >= 0 && pp_data.GetString().IndexOf("SetupMaterial") < 0) + if (pp_data.IndexOf("ProcessMaterial") >= 0 && pp_data.IndexOf("SetupMaterial") < 0) { // This reactivates the old logic and disables all features that cannot be supported with that method. placeholder << "#define LEGACY_USER_SHADER\n"; @@ -491,7 +491,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * int pp_lump = fileSystem.CheckNumForFullName(light_fragprog, 0); if (pp_lump == -1) I_Error("Unable to load '%s'", light_fragprog); FileData pp_data = fileSystem.ReadFile(pp_lump); - fp_comb << pp_data.GetString().GetChars() << "\n"; + fp_comb << pp_data.GetString() << "\n"; } if (gl.flags & RFL_NO_CLIP_PLANES) diff --git a/src/common/rendering/gl/gl_shaderprogram.cpp b/src/common/rendering/gl/gl_shaderprogram.cpp index 2b6df3254..69729a8c7 100644 --- a/src/common/rendering/gl/gl_shaderprogram.cpp +++ b/src/common/rendering/gl/gl_shaderprogram.cpp @@ -88,7 +88,7 @@ void FShaderProgram::Compile(ShaderType type, const char *lumpName, const char * { int lump = fileSystem.CheckNumForFullName(lumpName); if (lump == -1) I_FatalError("Unable to load '%s'", lumpName); - FString code = fileSystem.ReadFile(lump).GetString().GetChars(); + FString code = fileSystem.ReadFile(lump).GetString(); Compile(type, lumpName, code, defines, maxGlslVersion); } diff --git a/src/common/rendering/gles/gles_shader.cpp b/src/common/rendering/gles/gles_shader.cpp index 61c1a720e..16ff0eb65 100644 --- a/src/common/rendering/gles/gles_shader.cpp +++ b/src/common/rendering/gles/gles_shader.cpp @@ -422,27 +422,27 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * { int pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump); if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump.GetChars()); - FileData pp_data = fileSystem.ReadFile(pp_lump); + FString pp_data = fileSystem.ReadFile(pp_lump).GetString(); - if (pp_data.GetString().IndexOf("ProcessMaterial") < 0 && pp_data.GetString().IndexOf("SetupMaterial") < 0) + if (pp_data.IndexOf("ProcessMaterial") < 0 && pp_data.IndexOf("SetupMaterial") < 0) { // this looks like an old custom hardware shader. - if (pp_data.GetString().IndexOf("GetTexCoord") >= 0) + if (pp_data.IndexOf("GetTexCoord") >= 0) { int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultmat2.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultmat2.fp"); FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString().GetChars(); + fp_comb << "\n" << pl_data.GetString(); } else { int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultmat.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultmat.fp"); FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString().GetChars(); + fp_comb << "\n" << pl_data.GetString(); - if (pp_data.GetString().IndexOf("ProcessTexel") < 0) + if (pp_data.IndexOf("ProcessTexel") < 0) { // this looks like an even older custom hardware shader. // We need to replace the ProcessTexel call to make it work. @@ -451,7 +451,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * } } - if (pp_data.GetString().IndexOf("ProcessLight") >= 0) + if (pp_data.IndexOf("ProcessLight") >= 0) { // The ProcessLight signatured changed. Forward to the old one. fp_comb << "\nvec4 ProcessLight(vec4 color);\n"; @@ -459,19 +459,19 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * } } - fp_comb << RemoveLegacyUserUniforms(pp_data.GetString()).GetChars(); + fp_comb << RemoveLegacyUserUniforms(pp_data).GetChars(); fp_comb.Substitute("gl_TexCoord[0]", "vTexCoord"); // fix old custom shaders. - if (pp_data.GetString().IndexOf("ProcessLight") < 0) + if (pp_data.IndexOf("ProcessLight") < 0) { int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultlight.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultlight.fp"); FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString().GetChars(); + fp_comb << "\n" << pl_data.GetString(); } // ProcessMaterial must be considered broken because it requires the user to fill in data they possibly cannot know all about. - if (pp_data.GetString().IndexOf("ProcessMaterial") >= 0 && pp_data.GetString().IndexOf("SetupMaterial") < 0) + if (pp_data.IndexOf("ProcessMaterial") >= 0 && pp_data.IndexOf("SetupMaterial") < 0) { // This reactivates the old logic and disables all features that cannot be supported with that method. placeholder << "#define LEGACY_USER_SHADER\n"; @@ -490,7 +490,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * int pp_lump = fileSystem.CheckNumForFullName(light_fragprog, 0); if (pp_lump == -1) I_Error("Unable to load '%s'", light_fragprog.GetChars()); FileData pp_data = fileSystem.ReadFile(pp_lump); - fp_comb << pp_data.GetString().GetChars() << "\n"; + fp_comb << pp_data.GetString() << "\n"; } if (gles.flags & RFL_NO_CLIP_PLANES) diff --git a/src/common/rendering/gles/gles_shaderprogram.cpp b/src/common/rendering/gles/gles_shaderprogram.cpp index 16bd1ebe9..8677257f3 100644 --- a/src/common/rendering/gles/gles_shaderprogram.cpp +++ b/src/common/rendering/gles/gles_shaderprogram.cpp @@ -88,7 +88,7 @@ void FShaderProgram::Compile(ShaderType type, const char *lumpName, const char * { int lump = fileSystem.CheckNumForFullName(lumpName); if (lump == -1) I_FatalError("Unable to load '%s'", lumpName); - FString code = fileSystem.ReadFile(lump).GetString().GetChars(); + FString code = fileSystem.ReadFile(lump).GetString(); Compile(type, lumpName, code, defines, maxGlslVersion); } diff --git a/src/common/rendering/vulkan/shaders/vk_ppshader.cpp b/src/common/rendering/vulkan/shaders/vk_ppshader.cpp index 287762f77..f83b01c93 100644 --- a/src/common/rendering/vulkan/shaders/vk_ppshader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_ppshader.cpp @@ -66,7 +66,7 @@ FString VkPPShader::LoadShaderCode(const FString &lumpName, const FString &defin { int lump = fileSystem.CheckNumForFullName(lumpName); if (lump == -1) I_FatalError("Unable to load '%s'", lumpName.GetChars()); - FString code = fileSystem.ReadFile(lump).GetString().GetChars(); + FString code = fileSystem.ReadFile(lump).GetString(); FString patchedCode; patchedCode.AppendFormat("#version %d\n", 450); diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index f04e39d45..4dcd568e4 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -843,7 +843,7 @@ DEFINE_ACTION_FUNCTION(_Wads, ReadLump) PARAM_PROLOGUE; PARAM_INT(lump); const bool isLumpValid = lump >= 0 && lump < fileSystem.GetNumEntries(); - ACTION_RETURN_STRING(isLumpValid ? fileSystem.ReadFile(lump).GetString() : FString()); + ACTION_RETURN_STRING(isLumpValid ? fileSystem.ReadFile(lump).GetString() : ""); } //========================================================================== From c5b5b2b873fc2fac50f1482bca935c57bb28c411 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 20:54:51 +0200 Subject: [PATCH 023/223] - cleanup. --- src/common/filesystem/file_wad.cpp | 2 +- src/common/filesystem/filesystem.cpp | 17 ++++++++--------- src/common/filesystem/filesystem.h | 13 ------------- src/common/models/models_iqm.cpp | 6 ------ 4 files changed, 9 insertions(+), 29 deletions(-) diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/file_wad.cpp index beab51476..fb77a8781 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/file_wad.cpp @@ -197,7 +197,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) for(uint32_t i = 0; i < NumLumps; i++) { char n[9]; - uppercopy(n, fileinfo[i].Name); + for(int j = 0; j < 8; j++) n[j] = toupper(fileinfo[i].Name[j]); n[8] = 0; // This needs to be done differently. We cannot simply assume that all lumps where the first character's high bit is set are compressed without verification. // This requires explicit toggling for precisely the files that need it. diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 796c319c9..f58fb51ac 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -43,9 +43,12 @@ #include "m_argv.h" #include "cmdlib.h" #include "filesystem.h" + #include "m_crc32.h" -#include "printf.h" + +#if __has_include("md5.h") #include "md5.h" +#endif // MACROS ------------------------------------------------------------------ @@ -352,7 +355,7 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf if (resfile != NULL) { - if (!batchrun && Printf) + if (Printf) Printf(FSMessageLevel::Message, "adding %s, %d lumps\n", filename, resfile->LumpCount()); uint32_t lumpstart = FileInfo.Size(); @@ -379,6 +382,7 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf } } +#if __has_include("md5.h") if (hashfile) { uint8_t cksum[16]; @@ -423,6 +427,7 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf } } } +#endif return; } } @@ -895,12 +900,6 @@ LumpShortName& FileSystem::GetShortName(int i) return FileInfo[i].shortName; } -FString& FileSystem::GetLongName(int i) -{ - if ((unsigned)i >= NumEntries) throw FileSystemException("GetLongName: Invalid index"); - return FileInfo[i].longName; -} - void FileSystem::RenameFile(int num, const char* newfn) { if ((unsigned)num >= NumEntries) throw FileSystemException("RenameFile: Invalid index"); @@ -1311,7 +1310,7 @@ void FileSystem::ReadFile (int lump, void *dest) if (numread != size) { throw FileSystemException("W_ReadFile: only read %ld of %ld on '%s'\n", - numread, size, GetLongName(lump).GetChars()); + numread, size, FileInfo[lump].longName.GetChars()); } } diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index febb76911..0eb06b2fb 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -11,7 +11,6 @@ #include "files.h" #include "tarray.h" #include "cmdlib.h" -#include "zstring.h" #include "resourcefile.h" class FResourceFile; @@ -85,10 +84,8 @@ public: inline int CheckNumForName (const uint8_t *name) { return CheckNumForName ((const char *)name, ns_global); } inline int CheckNumForName (const char *name) { return CheckNumForName (name, ns_global); } - inline int CheckNumForName (const FString &name) { return CheckNumForName (name.GetChars()); } inline int CheckNumForName (const uint8_t *name, int ns) { return CheckNumForName ((const char *)name, ns); } inline int GetNumForName (const char *name) { return GetNumForName (name, ns_global); } - inline int GetNumForName (const FString &name) { return GetNumForName (name.GetChars(), ns_global); } inline int GetNumForName (const uint8_t *name) { return GetNumForName ((const char *)name); } inline int GetNumForName (const uint8_t *name, int ns) { return GetNumForName ((const char *)name, ns); } @@ -105,25 +102,15 @@ public: return FindFile(name) >= 0; } - bool FileExists(const FString& name) - { - return FindFile(name) >= 0; - } - bool FileExists(const std::string& name) { return FindFile(name.c_str()) >= 0; } LumpShortName& GetShortName(int i); // may only be called before the hash chains are set up. - FString& GetLongName(int i); // may only be called before the hash chains are set up. void RenameFile(int num, const char* fn); bool CreatePathlessCopy(const char* name, int id, int flags); - inline int CheckNumForFullName(const FString &name, bool trynormal = false, int namespc = ns_global) { return CheckNumForFullName(name.GetChars(), trynormal, namespc); } - inline int CheckNumForFullName (const FString &name, int wadfile) { return CheckNumForFullName(name.GetChars(), wadfile); } - inline int GetNumForFullName (const FString &name) { return GetNumForFullName(name.GetChars()); } - void ReadFile (int lump, void *dest); // These should only be used if the file data really needs padding. FileData ReadFile (int lump); diff --git a/src/common/models/models_iqm.cpp b/src/common/models/models_iqm.cpp index a2d72b11a..143c4334a 100644 --- a/src/common/models/models_iqm.cpp +++ b/src/common/models/models_iqm.cpp @@ -63,12 +63,6 @@ bool IQMModel::Load(const char* path, int lumpnum, const char* buffer, int lengt uint32_t num_extensions = reader.ReadUInt32(); uint32_t ofs_extensions = reader.ReadUInt32(); - /*if (num_joints <= 0) - { - Printf("Invalid model: \"%s%s\", no joint data is present\n", path, fileSystem.GetLongName(mLumpNum).GetChars()); - return false; - }*/ - if (num_text == 0) return false; From 25b7b18c3d7cee219faeb654309daa8c23aa47d6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 21:10:07 +0200 Subject: [PATCH 024/223] - got rid of the two copying variants of fileSystem.GetFileShortName. --- src/common/filesystem/filesystem.cpp | 18 ----------------- src/common/filesystem/filesystem.h | 2 -- src/common/scripting/interface/vmnatives.cpp | 4 +--- src/common/textures/formats/fontchars.cpp | 4 +--- .../textures/formats/rawpagetexture.cpp | 5 ++--- src/common/textures/texturemanager.cpp | 20 +++++++------------ src/maploader/maploader.cpp | 4 +--- src/playsim/p_acs.cpp | 3 +-- src/r_data/colormaps.cpp | 4 +--- src/r_data/sprites.cpp | 13 ++++-------- src/sound/s_advsound.cpp | 2 +- src/sound/s_doomsound.cpp | 10 +++------- 12 files changed, 22 insertions(+), 67 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index f58fb51ac..55847e714 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -1095,14 +1095,6 @@ bool FileSystem::CheckFileName (int lump, const char *name) // //========================================================================== -void FileSystem::GetFileShortName (char *to, int lump) const -{ - if ((size_t)lump >= NumEntries) - *to = 0; - else - uppercopy (to, FileInfo[lump].shortName.String); -} - const char* FileSystem::GetFileShortName(int lump) const { if ((size_t)lump >= NumEntries) @@ -1111,16 +1103,6 @@ const char* FileSystem::GetFileShortName(int lump) const return FileInfo[lump].shortName.String; } -void FileSystem::GetFileShortName(FString &to, int lump) const -{ - if ((size_t)lump >= NumEntries) - to = FString(); - else { - to = FileInfo[lump].shortName.String; - to.ToUpper(); - } -} - //========================================================================== // // FileSystem :: GetFileFullName diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index 0eb06b2fb..5ccca0971 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -136,8 +136,6 @@ public: int FileLength (int lump) const; int GetFileOffset (int lump); // [RH] Returns offset of lump in the wadfile int GetFileFlags (int lump); // Return the flags for this lump - void GetFileShortName (char *to, int lump) const; // [RH] Copies the lump name to to using uppercopy - void GetFileShortName (FString &to, int lump) const; const char* GetFileShortName(int lump) const; const char *GetFileFullName (int lump, bool returnshort = true) const; // [RH] Returns the lump's full name FString GetFileFullPath (int lump) const; // [RH] Returns wad's name + lump's full name diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index 4dcd568e4..636c340ae 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -819,9 +819,7 @@ DEFINE_ACTION_FUNCTION(_Wads, GetLumpName) { PARAM_PROLOGUE; PARAM_INT(lump); - FString lumpname; - fileSystem.GetFileShortName(lumpname, lump); - ACTION_RETURN_STRING(lumpname); + ACTION_RETURN_STRING(fileSystem.GetFileShortName(lump)); } DEFINE_ACTION_FUNCTION(_Wads, GetLumpFullName) diff --git a/src/common/textures/formats/fontchars.cpp b/src/common/textures/formats/fontchars.cpp index add4f1f74..09fbd718e 100644 --- a/src/common/textures/formats/fontchars.cpp +++ b/src/common/textures/formats/fontchars.cpp @@ -164,9 +164,7 @@ PalettedPixels FFontChar2::CreatePalettedPixels(int) if (destSize < 0) { - char name[9]; - fileSystem.GetFileShortName(name, SourceLump); - name[8] = 0; + auto name = fileSystem.GetFileShortName(SourceLump); I_FatalError("The font %s is corrupt", name); } return Pixels; diff --git a/src/common/textures/formats/rawpagetexture.cpp b/src/common/textures/formats/rawpagetexture.cpp index d28714d81..337ca5520 100644 --- a/src/common/textures/formats/rawpagetexture.cpp +++ b/src/common/textures/formats/rawpagetexture.cpp @@ -155,9 +155,8 @@ FRawPageTexture::FRawPageTexture (int lumpnum) Height = 200; // Special case hack for Heretic's E2 end pic. This is not going to be exposed as an editing feature because the implications would be horrible. - FString Name; - fileSystem.GetFileShortName(Name, lumpnum); - if (Name.CompareNoCase("E2END") == 0) + auto Name = fileSystem.GetFileShortName(lumpnum); + if (stricmp(Name, "E2END") == 0) { mPaletteLump = fileSystem.CheckNumForName("E2PAL"); if (fileSystem.FileLength(mPaletteLump) < 768) mPaletteLump = -1; diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index c149d99b2..236b049bc 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -451,7 +451,7 @@ FTextureID FTextureManager::CreateTexture (int lumpnum, ETextureType usetype) { FString str; if (!usefullnames) - fileSystem.GetFileShortName(str, lumpnum); + str = fileSystem.GetFileShortName(lumpnum); else { auto fn = fileSystem.GetFileFullName(lumpnum); @@ -563,7 +563,6 @@ void FTextureManager::AddGroup(int wadnum, int ns, ETextureType usetype) { int firsttx = fileSystem.GetFirstEntry(wadnum); int lasttx = fileSystem.GetLastEntry(wadnum); - FString Name; if (!usefullnames) { @@ -574,10 +573,9 @@ void FTextureManager::AddGroup(int wadnum, int ns, ETextureType usetype) for (; firsttx <= lasttx; ++firsttx) { + auto Name = fileSystem.GetFileShortName(firsttx); if (fileSystem.GetFileNamespace(firsttx) == ns) { - fileSystem.GetFileShortName(Name, firsttx); - if (fileSystem.CheckNumForName(Name, ns) == firsttx) { CreateTexture(firsttx, usetype); @@ -618,7 +616,6 @@ void FTextureManager::AddHiresTextures (int wadnum) int firsttx = fileSystem.GetFirstEntry(wadnum); int lasttx = fileSystem.GetLastEntry(wadnum); - FString Name; TArray tlist; if (firsttx == -1 || lasttx == -1) @@ -630,7 +627,7 @@ void FTextureManager::AddHiresTextures (int wadnum) { if (fileSystem.GetFileNamespace(firsttx) == ns_hires) { - fileSystem.GetFileShortName (Name, firsttx); + auto Name = fileSystem.GetFileShortName(firsttx); if (fileSystem.CheckNumForName (Name, ns_hires) == firsttx) { @@ -964,8 +961,7 @@ void FTextureManager::AddTexturesForWad(int wadnum, FMultipatchTextureBuilder &b for (int i= firsttx; i <= lasttx; i++) { bool skin = false; - FString Name; - fileSystem.GetFileShortName(Name, i); + auto Name = fileSystem.GetFileShortName(i); // Ignore anything not in the global namespace int ns = fileSystem.GetFileNamespace(i); @@ -997,7 +993,7 @@ void FTextureManager::AddTexturesForWad(int wadnum, FMultipatchTextureBuilder &b if (iwad) { // We need to make an exception for font characters of the SmallFont coming from the IWAD to be able to construct the original font. - if (Name.IndexOf("STCFN") != 0 && Name.IndexOf("FONTA") != 0) continue; + if (strncmp(Name, "STCFN", 5) != 0 && strncmp(Name, "FONTA", 5) != 0) continue; force = true; } else continue; @@ -1013,7 +1009,7 @@ void FTextureManager::AddTexturesForWad(int wadnum, FMultipatchTextureBuilder &b if (iwad) { // We need to make an exception for font characters of the SmallFont coming from the IWAD to be able to construct the original font. - if (Name.IndexOf("STCFN") != 0 && Name.IndexOf("FONTA") != 0) continue; + if (strncmp(Name, "STCFN", 5) != 0 && strncmp(Name, "FONTA", 5) != 0) continue; } else continue; } @@ -1513,9 +1509,7 @@ void FTextureManager::AdjustSpriteOffsets() if (fileSystem.GetFileContainer(i) > fileSystem.GetMaxIwadNum()) break; // we are past the IWAD if (fileSystem.GetFileNamespace(i) == ns_sprites && fileSystem.GetFileContainer(i) >= fileSystem.GetIwadNum() && fileSystem.GetFileContainer(i) <= fileSystem.GetMaxIwadNum()) { - char str[9]; - fileSystem.GetFileShortName(str, i); - str[8] = 0; + const char *str = fileSystem.GetFileShortName(i); FTextureID texid = TexMan.CheckForTexture(str, ETextureType::Sprite, 0); if (texid.isValid() && fileSystem.GetFileContainer(GetGameTexture(texid)->GetSourceLump()) > fileSystem.GetMaxIwadNum()) { diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index 1bcd9c34f..56b1e23fe 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -2121,9 +2121,7 @@ void MapLoader::ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec if (developer >= DMSG_NOTIFY) { - char lumpname[9]; - lumpname[8] = 0; - fileSystem.GetFileShortName(lumpname, lumpnum); + const char *lumpname = fileSystem.GetFileShortName(lumpnum); if (*alpha < 0) Printf("%s appears to be additive translucency %d (%d%%)\n", lumpname, -*alpha, -*alpha * 100 / 255); else Printf("%s appears to be translucency %d (%d%%)\n", lumpname, *alpha, *alpha * 100 / 255); } diff --git a/src/playsim/p_acs.cpp b/src/playsim/p_acs.cpp index 429fe1b69..17f6cc459 100644 --- a/src/playsim/p_acs.cpp +++ b/src/playsim/p_acs.cpp @@ -2277,8 +2277,7 @@ bool FBehavior::Init(FLevelLocals *Level, int lumpnum, FileReader * fr, int len, if (fr == NULL) { - fileSystem.GetFileShortName (ModuleName, lumpnum); - ModuleName[8] = 0; + strcpy(ModuleName, fileSystem.GetFileShortName (lumpnum)); } else { diff --git a/src/r_data/colormaps.cpp b/src/r_data/colormaps.cpp index 2ee96133a..ad1559c6b 100644 --- a/src/r_data/colormaps.cpp +++ b/src/r_data/colormaps.cpp @@ -106,9 +106,7 @@ void R_InitColormaps (bool allowCustomColormap) { if (fileSystem.GetFileNamespace(i) == ns_colormaps) { - char name[9]; - name[8] = 0; - fileSystem.GetFileShortName (name, i); + auto name = fileSystem.GetFileShortName(i); if (fileSystem.CheckNumForName (name, ns_colormaps) == (int)i) { diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 07a106e65..97a5e2e46 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -351,13 +351,11 @@ void R_InitSpriteDefs () { if (fileSystem.GetFileNamespace(i) == ns_voxels) { - char name[9]; size_t namelen; int spin; int sign; - fileSystem.GetFileShortName(name, i); - name[8] = 0; + const char* name = fileSystem.GetFileShortName(i); namelen = strlen(name); if (namelen < 4) { // name is too short @@ -812,9 +810,7 @@ void R_InitSkins (void) // specified, use whatever immediately follows the specifier lump. if (intname == 0) { - char name[9]; - fileSystem.GetFileShortName (name, base+1); - memcpy(&intname, name, 4); + memcpy(&intname, fileSystem.GetFileShortName(base + 1), 4); } int basens = fileSystem.GetFileNamespace(base); @@ -845,9 +841,8 @@ void R_InitSkins (void) for (k = base + 1; fileSystem.GetFileNamespace(k) == basens; k++) { - char lname[9]; + const char* lname = fileSystem.GetFileShortName(k); uint32_t lnameint; - fileSystem.GetFileShortName (lname, k); memcpy(&lnameint, lname, 4); if (lnameint == intname) { @@ -866,7 +861,7 @@ void R_InitSkins (void) break; } - fileSystem.GetFileShortName (temp.name, base+1); + memcpy(temp.name, fileSystem.GetFileShortName (base+1), 4); temp.name[4] = 0; int sprno = (int)sprites.Push (temp); if (spr==0) Skins[i].sprite = sprno; diff --git a/src/sound/s_advsound.cpp b/src/sound/s_advsound.cpp index 928cdeba5..98d17bc88 100644 --- a/src/sound/s_advsound.cpp +++ b/src/sound/s_advsound.cpp @@ -1124,7 +1124,7 @@ static void S_AddSNDINFO (int lump) static void S_AddStrifeVoice (int lumpnum) { char name[16] = "svox/"; - fileSystem.GetFileShortName (name+5, lumpnum); + strcpy(name + 5, fileSystem.GetFileShortName (lumpnum)); S_AddSound (name, lumpnum); } diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index 9f000f4c7..f47666e4e 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -1242,9 +1242,8 @@ void DoomSoundEngine::NoiseDebug() color = (chan->ChanFlags & CHANF_LOOP) ? CR_BROWN : CR_GREY; // Name - fileSystem.GetFileShortName(temp, S_sfx[chan->SoundID.index()].lumpnum); - temp[8] = 0; - DrawText(twod, NewConsoleFont, color, 0, y, temp, TAG_DONE); + auto tname = fileSystem.GetFileShortName(S_sfx[chan->SoundID.index()].lumpnum); + DrawText(twod, NewConsoleFont, color, 0, y, tname, TAG_DONE); if (!(chan->ChanFlags & CHANF_IS3D)) { @@ -1337,10 +1336,8 @@ ADD_STAT(sounddebug) void DoomSoundEngine::PrintSoundList() { - char lumpname[9]; unsigned int i; - lumpname[8] = 0; for (i = 0; i < soundEngine->GetNumSounds(); i++) { const sfxinfo_t* sfx = soundEngine->GetSfx(FSoundID::fromInt(i)); @@ -1360,8 +1357,7 @@ void DoomSoundEngine::PrintSoundList() } else if (S_sfx[i].lumpnum != -1) { - fileSystem.GetFileShortName(lumpname, sfx->lumpnum); - Printf("%3d. %s (%s)\n", i, sfx->name.GetChars(), lumpname); + Printf("%3d. %s (%s)\n", i, sfx->name.GetChars(), fileSystem.GetFileShortName(sfx->lumpnum)); } else if (S_sfx[i].link != sfxinfo_t::NO_LINK) { From 8a5d3c096b69ce02786d7a004dc21d1ff8ac44cb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 21:42:58 +0200 Subject: [PATCH 025/223] - return a std::string from GetFileFullPath --- src/common/engine/sc_man.cpp | 2 +- src/common/filesystem/filesystem.cpp | 8 +++++--- src/common/filesystem/filesystem.h | 2 +- src/common/models/models_obj.cpp | 4 ++-- src/common/scripting/frontend/zcc_parser.cpp | 6 ++---- src/common/textures/formats/jpegtexture.cpp | 8 ++++---- src/common/textures/texturemanager.cpp | 2 +- src/gamedata/d_dehacked.cpp | 2 +- src/maploader/glnodes.cpp | 2 +- src/scripting/decorate/thingdef_parse.cpp | 2 +- src/scripting/thingdef.cpp | 4 ++-- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/common/engine/sc_man.cpp b/src/common/engine/sc_man.cpp index bc50c7925..21a777756 100644 --- a/src/common/engine/sc_man.cpp +++ b/src/common/engine/sc_man.cpp @@ -203,7 +203,7 @@ void FScanner :: OpenLumpNum (int lump) FileData mem = fileSystem.ReadFile(lump); ScriptBuffer = mem.GetString(); } - ScriptName = fileSystem.GetFileFullPath(lump); + ScriptName = fileSystem.GetFileFullPath(lump).c_str(); LumpNum = lump; PrepareScript (); } diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 55847e714..1737d6d7c 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -1130,13 +1130,15 @@ const char *FileSystem::GetFileFullName (int lump, bool returnshort) const // //========================================================================== -FString FileSystem::GetFileFullPath(int lump) const +std::string FileSystem::GetFileFullPath(int lump) const { - FString foo; + std::string foo; if ((size_t) lump < NumEntries) { - foo << GetResourceFileName(FileInfo[lump].rfnum) << ':' << GetFileFullName(lump); + foo = GetResourceFileName(FileInfo[lump].rfnum); + foo += ':'; + foo += +GetFileFullName(lump); } return foo; } diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index 5ccca0971..9f7da8b3e 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -138,7 +138,7 @@ public: int GetFileFlags (int lump); // Return the flags for this lump const char* GetFileShortName(int lump) const; const char *GetFileFullName (int lump, bool returnshort = true) const; // [RH] Returns the lump's full name - FString GetFileFullPath (int lump) const; // [RH] Returns wad's name + lump's full name + std::string GetFileFullPath (int lump) const; // [RH] Returns wad's name + lump's full name int GetFileContainer (int lump) const; // [RH] Returns wadnum for a specified lump int GetFileNamespace (int lump) const; // [RH] Returns the namespace a lump belongs to void SetFileNamespace(int lump, int ns); diff --git a/src/common/models/models_obj.cpp b/src/common/models/models_obj.cpp index e1d777c81..087fe0d3a 100644 --- a/src/common/models/models_obj.cpp +++ b/src/common/models/models_obj.cpp @@ -37,7 +37,7 @@ */ bool FOBJModel::Load(const char* fn, int lumpnum, const char* buffer, int length) { - FString objName = fileSystem.GetFileFullPath(lumpnum); + auto objName = fileSystem.GetFileFullPath(lumpnum); FString objBuf(buffer, length); // Do some replacements before we parse the OBJ string @@ -101,7 +101,7 @@ bool FOBJModel::Load(const char* fn, int lumpnum, const char* buffer, int length wObjBuf = nullptr; objBuf.UnlockBuffer(); } - sc.OpenString(objName, objBuf); + sc.OpenString(objName.c_str(), objBuf); FTextureID curMtl = FNullTextureID(); OBJSurface *curSurface = nullptr; diff --git a/src/common/scripting/frontend/zcc_parser.cpp b/src/common/scripting/frontend/zcc_parser.cpp index cedeb53fb..978006054 100644 --- a/src/common/scripting/frontend/zcc_parser.cpp +++ b/src/common/scripting/frontend/zcc_parser.cpp @@ -407,8 +407,6 @@ PNamespace *ParseOneScript(const int baselump, ZCCParseState &state) int lumpnum = baselump; auto fileno = fileSystem.GetFileContainer(lumpnum); - FString file = fileSystem.GetFileFullPath(lumpnum); - state.FileNo = fileno; if (TokenMap.CountUsed() == 0) @@ -503,7 +501,7 @@ PNamespace *ParseOneScript(const int baselump, ZCCParseState &state) // If the parser fails, there is no point starting the compiler, because it'd only flood the output with endless errors. if (FScriptPosition::ErrorCounter > 0) { - I_Error("%d errors while parsing %s", FScriptPosition::ErrorCounter, fileSystem.GetFileFullPath(baselump).GetChars()); + I_Error("%d errors while parsing %s", FScriptPosition::ErrorCounter, fileSystem.GetFileFullPath(baselump).c_str()); } #ifndef NDEBUG @@ -517,7 +515,7 @@ PNamespace *ParseOneScript(const int baselump, ZCCParseState &state) if (Args->CheckParm("-dumpast")) { FString ast = ZCC_PrintAST(state.TopNode); - FString filename = fileSystem.GetFileFullPath(baselump); + FString filename = fileSystem.GetFileFullPath(baselump).c_str(); filename.ReplaceChars(":\\/?|", '.'); filename << ".ast"; FileWriter *ff = FileWriter::Open(filename); diff --git a/src/common/textures/formats/jpegtexture.cpp b/src/common/textures/formats/jpegtexture.cpp index 79ba53671..834dc44e3 100644 --- a/src/common/textures/formats/jpegtexture.cpp +++ b/src/common/textures/formats/jpegtexture.cpp @@ -287,7 +287,7 @@ PalettedPixels FJPEGTexture::CreatePalettedPixels(int conversion) (cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) || (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) { - Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", fileSystem.GetFileFullPath(SourceLump).GetChars()); + Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str()); } else { @@ -382,7 +382,7 @@ PalettedPixels FJPEGTexture::CreatePalettedPixels(int conversion) } catch (int) { - Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", fileSystem.GetFileFullPath(SourceLump).GetChars()); + Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str()); } jpeg_destroy_decompress(&cinfo); if (buff != NULL) @@ -426,7 +426,7 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion) (cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) || (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) { - Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", fileSystem.GetFileFullPath(SourceLump).GetChars()); + Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str()); } else { @@ -479,7 +479,7 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion) } catch (int) { - Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", fileSystem.GetFileFullPath(SourceLump).GetChars()); + Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str()); } jpeg_destroy_decompress(&cinfo); return 0; diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index 236b049bc..cbfdfc821 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -485,7 +485,7 @@ FTextureID FTextureManager::CreateTexture (int lumpnum, ETextureType usetype) } else { - Printf (TEXTCOLOR_ORANGE "Invalid data encountered for texture %s\n", fileSystem.GetFileFullPath(lumpnum).GetChars()); + Printf (TEXTCOLOR_ORANGE "Invalid data encountered for texture %s\n", fileSystem.GetFileFullPath(lumpnum).c_str()); return FTextureID(-1); } } diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 96925365c..bd9de53dc 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -3004,7 +3004,7 @@ bool D_LoadDehLump(int lumpnum) PatchSize = fileSystem.FileLength(lumpnum); - PatchName = fileSystem.GetFileFullPath(lumpnum); + PatchName = fileSystem.GetFileFullPath(lumpnum).c_str(); PatchFile = new char[PatchSize + 1]; fileSystem.ReadFile(lumpnum, PatchFile); PatchFile[PatchSize] = '\0'; // terminate with a '\0' character diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index 76f0de303..ff4492279 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -1001,7 +1001,7 @@ typedef TArray MemFile; static FString CreateCacheName(MapData *map, bool create) { FString path = M_GetCachePath(create); - FString lumpname = fileSystem.GetFileFullPath(map->lumpnum); + FString lumpname = fileSystem.GetFileFullPath(map->lumpnum).c_str(); auto separator = lumpname.IndexOf(':'); path << '/' << lumpname.Left(separator); if (create) CreatePath(path); diff --git a/src/scripting/decorate/thingdef_parse.cpp b/src/scripting/decorate/thingdef_parse.cpp index 8d49f7604..eb1cd5ee3 100644 --- a/src/scripting/decorate/thingdef_parse.cpp +++ b/src/scripting/decorate/thingdef_parse.cpp @@ -1129,7 +1129,7 @@ static PClassActor *ParseActorHeader(FScanner &sc, Baggage *bag) { PClassActor *info = CreateNewActor(sc, typeName, parentName); info->ActorInfo()->DoomEdNum = DoomEdNum > 0 ? DoomEdNum : -1; - info->SourceLumpName = fileSystem.GetFileFullPath(sc.LumpNum); + info->SourceLumpName = fileSystem.GetFileFullPath(sc.LumpNum).c_str(); if (!info->SetReplacement(replaceName)) { diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index d170096fb..6affab4c3 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -433,12 +433,12 @@ void ParseScripts() if (FScriptPosition::ErrorCounter > 0) { // Abort if the compiler produced any errors. Also do not compile further lumps, because they very likely miss some stuff. - I_Error("%d errors, %d warnings while compiling %s", FScriptPosition::ErrorCounter, FScriptPosition::WarnCounter, fileSystem.GetFileFullPath(lump).GetChars()); + I_Error("%d errors, %d warnings while compiling %s", FScriptPosition::ErrorCounter, FScriptPosition::WarnCounter, fileSystem.GetFileFullPath(lump).c_str()); } else if (FScriptPosition::WarnCounter > 0) { // If we got warnings, but no errors, print the information but continue. - Printf(TEXTCOLOR_ORANGE "%d warnings while compiling %s\n", FScriptPosition::WarnCounter, fileSystem.GetFileFullPath(lump).GetChars()); + Printf(TEXTCOLOR_ORANGE "%d warnings while compiling %s\n", FScriptPosition::WarnCounter, fileSystem.GetFileFullPath(lump).c_str()); } } From ca1d7fd5394b0864760be9b81f73a37f6dde37e9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 22:08:59 +0200 Subject: [PATCH 026/223] - store longName in a std::string and use std::vector for FileInfo TArray cannot handle std::string so this must both be changed together. --- src/common/filesystem/filesystem.cpp | 183 +++++++++++++------------ src/common/filesystem/filesystem.h | 2 +- src/common/textures/texturemanager.cpp | 8 +- 3 files changed, 102 insertions(+), 91 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 1737d6d7c..d768d5d28 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -54,12 +54,21 @@ #define NULL_INDEX (0xffffffff) +static void UpperCopy(char* to, const char* from) +{ + int i; + + for (i = 0; i < 8 && from[i]; i++) + to[i] = toupper(from[i]); + for (; i < 8; i++) + to[i] = 0; +} struct FileSystem::LumpRecord { FResourceLump *lump; LumpShortName shortName; - FString longName; + std::string longName; int rfnum; int Namespace; int resourceId; @@ -73,7 +82,7 @@ struct FileSystem::LumpRecord if (lump->Flags & LUMPF_SHORTNAME) { - uppercopy(shortName.String, lump->getName()); + UpperCopy(shortName.String, lump->getName()); shortName.String[8] = 0; longName = ""; Namespace = lump->GetNamespace(); @@ -94,42 +103,41 @@ struct FileSystem::LumpRecord // Map some directories to WAD namespaces. // Note that some of these namespaces don't exist in WADS. // CheckNumForName will handle any request for these namespaces accordingly. - Namespace = !strncmp(longName.GetChars(), "flats/", 6) ? ns_flats : - !strncmp(longName.GetChars(), "textures/", 9) ? ns_newtextures : - !strncmp(longName.GetChars(), "hires/", 6) ? ns_hires : - !strncmp(longName.GetChars(), "sprites/", 8) ? ns_sprites : - !strncmp(longName.GetChars(), "voxels/", 7) ? ns_voxels : - !strncmp(longName.GetChars(), "colormaps/", 10) ? ns_colormaps : - !strncmp(longName.GetChars(), "acs/", 4) ? ns_acslibrary : - !strncmp(longName.GetChars(), "voices/", 7) ? ns_strifevoices : - !strncmp(longName.GetChars(), "patches/", 8) ? ns_patches : - !strncmp(longName.GetChars(), "graphics/", 9) ? ns_graphics : - !strncmp(longName.GetChars(), "sounds/", 7) ? ns_sounds : - !strncmp(longName.GetChars(), "music/", 6) ? ns_music : - !strchr(longName.GetChars(), '/') ? ns_global : + Namespace = !strncmp(longName.c_str(), "flats/", 6) ? ns_flats : + !strncmp(longName.c_str(), "textures/", 9) ? ns_newtextures : + !strncmp(longName.c_str(), "hires/", 6) ? ns_hires : + !strncmp(longName.c_str(), "sprites/", 8) ? ns_sprites : + !strncmp(longName.c_str(), "voxels/", 7) ? ns_voxels : + !strncmp(longName.c_str(), "colormaps/", 10) ? ns_colormaps : + !strncmp(longName.c_str(), "acs/", 4) ? ns_acslibrary : + !strncmp(longName.c_str(), "voices/", 7) ? ns_strifevoices : + !strncmp(longName.c_str(), "patches/", 8) ? ns_patches : + !strncmp(longName.c_str(), "graphics/", 9) ? ns_graphics : + !strncmp(longName.c_str(), "sounds/", 7) ? ns_sounds : + !strncmp(longName.c_str(), "music/", 6) ? ns_music : + !strchr(longName.c_str(), '/') ? ns_global : ns_hidden; if (Namespace == ns_hidden) shortName.qword = 0; else { - ptrdiff_t encodedResID = longName.LastIndexOf(".{"); - if (resourceId == -1 && encodedResID >= 0) + ptrdiff_t encodedResID = longName.find_last_of(".{"); + if (resourceId == -1 && encodedResID != std::string::npos) { - const char* p = longName.GetChars() + encodedResID; + const char* p = longName.c_str() + encodedResID; char* q; int id = (int)strtoull(p+2, &q, 10); // only decimal numbers allowed here. if (q[0] == '}' && (q[1] == '.' || q[1] == 0)) { - FString toDelete(p, q - p + 1); - longName.Substitute(toDelete, ""); + longName.erase(longName.begin() + encodedResID, longName.begin() + (q - p) + 1); resourceId = id; } } - ptrdiff_t slash = longName.LastIndexOf('/'); - FString base = (slash >= 0) ? longName.Mid(slash + 1) : longName; - auto dot = base.LastIndexOf('.'); - if (dot >= 0) base.Truncate(dot); - uppercopy(shortName.String, base); + ptrdiff_t slash = longName.find_last_of('/'); + std::string base = (slash != std::string::npos) ? longName.c_str() + (slash + 1) : longName.c_str(); + auto dot = base.find_last_of('.'); + if (dot != std::string::npos) base.resize(dot); + UpperCopy(shortName.String, base.c_str()); shortName.String[8] = 0; // Since '\' can't be used as a file name's part inside a ZIP @@ -181,7 +189,7 @@ void FileSystem::DeleteAll () { if (frec.rfnum == -1) delete frec.lump; } - FileInfo.Clear(); + FileInfo.clear(); for (int i = Files.Size() - 1; i >= 0; --i) { delete Files[i]; @@ -240,7 +248,7 @@ bool FileSystem::InitMultipleFiles (TArray &filenames, LumpFilterInfo* MoveLumpsInFolder(path); } - NumEntries = FileInfo.Size(); + NumEntries = (uint32_t)FileInfo.size(); if (NumEntries == 0) { return false; @@ -262,8 +270,8 @@ bool FileSystem::InitMultipleFiles (TArray &filenames, LumpFilterInfo* void FileSystem::AddLump(FResourceLump *lump) { - FileSystem::LumpRecord *lumprec = &FileInfo[FileInfo.Reserve(1)]; - lumprec->SetFromLump(-1, lump); + FileInfo.resize(FileInfo.size() + 1); + FileInfo.back().SetFromLump(-1, lump); } //----------------------------------------------------------------------- @@ -278,7 +286,7 @@ int FileSystem::AddExternalFile(const char *filename) { FResourceLump *lump = new FExternalLump(filename); AddLump(lump); - return FileInfo.Size() - 1; // later + return (int)FileInfo.size() - 1; // later } //========================================================================== @@ -295,8 +303,8 @@ int FileSystem::AddFromBuffer(const char* name, const char* type, char* data, in auto newlump = new FMemoryLump(data, size); newlump->LumpNameSetup(fullname); AddLump(newlump); - FileInfo.Last().resourceId = id; - return FileInfo.Size()-1; + FileInfo.back().resourceId = id; + return (int)FileInfo.size()-1; } //========================================================================== @@ -358,13 +366,14 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf if (Printf) Printf(FSMessageLevel::Message, "adding %s, %d lumps\n", filename, resfile->LumpCount()); - uint32_t lumpstart = FileInfo.Size(); + uint32_t lumpstart = (uint32_t)FileInfo.size(); resfile->SetFirstLump(lumpstart); for (uint32_t i=0; i < resfile->LumpCount(); i++) { FResourceLump *lump = resfile->GetLump(i); - FileSystem::LumpRecord *lump_p = &FileInfo[FileInfo.Reserve(1)]; + FileInfo.resize(FileInfo.size() + 1); + FileSystem::LumpRecord* lump_p = &FileInfo.back(); lump_p->SetFromLump(Files.Size(), lump); } @@ -503,7 +512,7 @@ int FileSystem::CheckNumForName (const char *name, int space) return -1; } - uppercopy (uname, name); + UpperCopy (uname, name); i = FirstLumpIndex[LumpNameHash (uname) % NumEntries]; while (i != NULL_INDEX) @@ -541,7 +550,7 @@ int FileSystem::CheckNumForName (const char *name, int space, int rfnum, bool ex return CheckNumForName (name, space); } - uppercopy (uname, name); + UpperCopy (uname, name); i = FirstLumpIndex[LumpNameHash (uname) % NumEntries]; // If exact is true if will only find lumps in the same WAD, otherwise @@ -603,12 +612,12 @@ int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int names for (i = fli[MakeKey(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) { - if (strnicmp(name, FileInfo[i].longName, len)) continue; + if (strnicmp(name, FileInfo[i].longName.c_str(), len)) continue; if (FileInfo[i].longName[len] == 0) break; // this is a full match if (ignoreext && FileInfo[i].longName[len] == '.') { // is this the last '.' in the last path element, indicating that the remaining part of the name is only an extension? - if (strpbrk(FileInfo[i].longName.GetChars() + len + 1, "./") == nullptr) break; + if (strpbrk(FileInfo[i].longName.c_str() + len + 1, "./") == nullptr) break; } } @@ -633,7 +642,7 @@ int FileSystem::CheckNumForFullName (const char *name, int rfnum) i = FirstLumpIndex_FullName[MakeKey (name) % NumEntries]; while (i != NULL_INDEX && - (stricmp(name, FileInfo[i].longName) || FileInfo[i].rfnum != rfnum)) + (stricmp(name, FileInfo[i].longName.c_str()) || FileInfo[i].rfnum != rfnum)) { i = NextLumpIndex_FullName[i]; } @@ -684,10 +693,10 @@ int FileSystem::FindFileWithExtensions(const char* name, const char *const *exts for (i = fli[MakeKey(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) { - if (strnicmp(name, FileInfo[i].longName, len)) continue; + if (strnicmp(name, FileInfo[i].longName.c_str(), len)) continue; if (FileInfo[i].longName[len] != '.') continue; // we are looking for extensions but this file doesn't have one. - auto cp = FileInfo[i].longName.GetChars() + len + 1; + auto cp = FileInfo[i].longName.c_str() + len + 1; // is this the last '.' in the last path element, indicating that the remaining part of the name is only an extension? if (strpbrk(cp, "./") != nullptr) continue; // No, so it cannot be a valid entry. @@ -723,7 +732,7 @@ int FileSystem::FindResource (int resid, const char *type, int filenum) const no { if (filenum > 0 && FileInfo[i].rfnum != filenum) continue; if (FileInfo[i].resourceId != resid) continue; - auto extp = strrchr(FileInfo[i].longName, '.'); + auto extp = strrchr(FileInfo[i].longName.c_str(), '.'); if (!extp) continue; if (!stricmp(extp + 1, type)) return i; } @@ -840,7 +849,7 @@ void FileSystem::InitHashChains (void) { unsigned int i, j; - NumEntries = FileInfo.Size(); + NumEntries = (uint32_t)FileInfo.size(); Hashes.Resize(8 * NumEntries); // Mark all buckets as empty memset(Hashes.Data(), -1, Hashes.Size() * sizeof(Hashes[0])); @@ -862,18 +871,18 @@ void FileSystem::InitHashChains (void) FirstLumpIndex[j] = i; // Do the same for the full paths - if (FileInfo[i].longName.IsNotEmpty()) + if (!FileInfo[i].longName.empty()) { - j = MakeKey(FileInfo[i].longName) % NumEntries; + j = MakeKey(FileInfo[i].longName.c_str()) % NumEntries; NextLumpIndex_FullName[i] = FirstLumpIndex_FullName[j]; FirstLumpIndex_FullName[j] = i; - FString nameNoExt = FileInfo[i].longName; - auto dot = nameNoExt.LastIndexOf('.'); - auto slash = nameNoExt.LastIndexOf('/'); - if (dot > slash) nameNoExt.Truncate(dot); + auto nameNoExt = FileInfo[i].longName; + auto dot = nameNoExt.find_last_of('.'); + auto slash = nameNoExt.find_last_of('/'); + if ((dot > slash || slash == std::string::npos) && dot != std::string::npos) nameNoExt.resize(dot); - j = MakeKey(nameNoExt) % NumEntries; + j = MakeKey(nameNoExt.c_str()) % NumEntries; NextLumpIndex_NoExt[i] = FirstLumpIndex_NoExt[j]; FirstLumpIndex_NoExt[j] = i; @@ -883,7 +892,7 @@ void FileSystem::InitHashChains (void) } } - FileInfo.ShrinkToFit(); + FileInfo.shrink_to_fit(); Files.ShrinkToFit(); } @@ -924,25 +933,25 @@ static FResourceLump placeholderLump; void FileSystem::MoveLumpsInFolder(const char *path) { - if (FileInfo.Size() == 0) + if (FileInfo.size() == 0) { return; } auto len = strlen(path); - auto rfnum = FileInfo.Last().rfnum; + auto rfnum = FileInfo.back().rfnum; - unsigned i; - for (i = 0; i < FileInfo.Size(); i++) + size_t i; + for (i = 0; i < FileInfo.size(); i++) { auto& li = FileInfo[i]; if (li.rfnum >= GetIwadNum()) break; - if (li.longName.Left(len).CompareNoCase(path) == 0) + if (strnicmp(li.longName.c_str(), path, len) == 0) { - FileInfo.Push(li); + FileInfo.push_back(li); li.lump = &placeholderLump; // Make the old entry point to something empty. We cannot delete the lump record here because it'd require adjustment of all indices in the list. - auto &ln = FileInfo.Last(); - ln.lump->LumpNameSetup(ln.longName.Mid(len)); + auto &ln = FileInfo.back(); + ln.lump->LumpNameSetup(ln.longName.c_str() + len); ln.SetFromLump(rfnum, ln.lump); } } @@ -959,6 +968,7 @@ void FileSystem::MoveLumpsInFolder(const char *path) int FileSystem::FindLump (const char *name, int *lastlump, bool anyns) { + if (*lastlump >= FileInfo.size()) return -1; union { char name8[8]; @@ -966,15 +976,15 @@ int FileSystem::FindLump (const char *name, int *lastlump, bool anyns) }; LumpRecord *lump_p; - uppercopy (name8, name); + UpperCopy (name8, name); assert(lastlump != NULL && *lastlump >= 0); lump_p = &FileInfo[*lastlump]; - while (lump_p < &FileInfo[NumEntries]) + while (lump_p <= &FileInfo.back()) { if ((anyns || lump_p->Namespace == ns_global) && lump_p->shortName.qword == qname) { - int lump = int(lump_p - &FileInfo[0]); + int lump = int(lump_p - FileInfo.data()); *lastlump = lump + 1; return lump; } @@ -1000,7 +1010,7 @@ int FileSystem::FindLumpMulti (const char **names, int *lastlump, bool anyns, in assert(lastlump != NULL && *lastlump >= 0); lump_p = &FileInfo[*lastlump]; - while (lump_p < &FileInfo[NumEntries]) + while (lump_p <= &FileInfo.back()) { if (anyns || lump_p->Namespace == ns_global) { @@ -1009,7 +1019,7 @@ int FileSystem::FindLumpMulti (const char **names, int *lastlump, bool anyns, in { if (!strnicmp(*name, lump_p->shortName.String, 8)) { - int lump = int(lump_p - &FileInfo[0]); + int lump = int(lump_p - FileInfo.data()); *lastlump = lump + 1; if (nameindex != NULL) *nameindex = int(name - names); return lump; @@ -1039,11 +1049,11 @@ int FileSystem::FindLumpFullName(const char* name, int* lastlump, bool noext) if (!noext) { - while (lump_p < &FileInfo[NumEntries]) + while (lump_p <= &FileInfo.back()) { - if (!stricmp(name, lump_p->longName)) + if (!stricmp(name, lump_p->longName.c_str())) { - int lump = int(lump_p - &FileInfo[0]); + int lump = int(lump_p - FileInfo.data()); *lastlump = lump + 1; return lump; } @@ -1053,15 +1063,15 @@ int FileSystem::FindLumpFullName(const char* name, int* lastlump, bool noext) else { auto len = strlen(name); - while (lump_p < &FileInfo[NumEntries]) + while (lump_p <= &FileInfo.back()) { - auto res = strnicmp(name, lump_p->longName, len); + auto res = strnicmp(name, lump_p->longName.c_str(), len); if (res == 0) { - auto p = lump_p->longName.GetChars() + len; + auto p = lump_p->longName.c_str() + len; if (*p == 0 || (*p == '.' && strpbrk(p + 1, "./") == 0)) { - int lump = int(lump_p - &FileInfo[0]); + int lump = int(lump_p - FileInfo.data()); *lastlump = lump + 1; return lump; } @@ -1115,8 +1125,8 @@ const char *FileSystem::GetFileFullName (int lump, bool returnshort) const { if ((size_t)lump >= NumEntries) return NULL; - else if (FileInfo[lump].longName.IsNotEmpty()) - return FileInfo[lump].longName; + else if (!FileInfo[lump].longName.empty()) + return FileInfo[lump].longName.c_str(); else if (returnshort) return FileInfo[lump].shortName.String; else return nullptr; @@ -1194,7 +1204,7 @@ const char *FileSystem::GetResourceType(int lump) const return nullptr; else { - auto p = strrchr(FileInfo[lump].longName.GetChars(), '.'); + auto p = strrchr(FileInfo[lump].longName.c_str(), '.'); if (!p) return ""; // has no extension if (strchr(p, '/')) return ""; // the '.' is part of a directory. return p + 1; @@ -1209,7 +1219,7 @@ const char *FileSystem::GetResourceType(int lump) const int FileSystem::GetFileContainer (int lump) const { - if ((size_t)lump >= FileInfo.Size()) + if ((size_t)lump >= FileInfo.size()) return -1; return FileInfo[lump].rfnum; } @@ -1244,14 +1254,15 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, TArray &r path.ToLower(); if (path[path.Len() - 1] != '/') path += '/'; result.Clear(); - for (unsigned i = 0; i < FileInfo.Size(); i++) + for (size_t i = 0; i < FileInfo.size(); i++) { - if (FileInfo[i].longName.IndexOf(path) == 0) + if (FileInfo[i].longName.find(path) == 0) { // Only if it hasn't been replaced. - if ((unsigned)fileSystem.CheckNumForFullName(FileInfo[i].longName) == i) + if ((unsigned)fileSystem.CheckNumForFullName(FileInfo[i].longName.c_str()) == i) { - result.Push({ FileInfo[i].longName.GetChars(), i }); + FolderEntry fe{ FileInfo[i].longName.c_str(), (uint32_t)i }; + result.Push(fe); } } } @@ -1294,7 +1305,7 @@ void FileSystem::ReadFile (int lump, void *dest) if (numread != size) { throw FileSystemException("W_ReadFile: only read %ld of %ld on '%s'\n", - numread, size, FileInfo[lump].longName.GetChars()); + numread, size, FileInfo[lump].longName.c_str()); } } @@ -1323,7 +1334,7 @@ FileData FileSystem::ReadFile (int lump) FileReader FileSystem::OpenFileReader(int lump) { - if ((unsigned)lump >= (unsigned)FileInfo.Size()) + if ((unsigned)lump >= (unsigned)FileInfo.size()) { throw FileSystemException("OpenFileReader: %u >= NumEntries", lump); } @@ -1342,7 +1353,7 @@ FileReader FileSystem::OpenFileReader(int lump) FileReader FileSystem::ReopenFileReader(int lump, bool alwayscache) { - if ((unsigned)lump >= (unsigned)FileInfo.Size()) + if ((unsigned)lump >= (unsigned)FileInfo.size()) { throw FileSystemException("ReopenFileReader: %u >= NumEntries", lump); } @@ -1492,9 +1503,9 @@ bool FileSystem::CreatePathlessCopy(const char *name, int id, int /*flags*/) if (lump < 0) return false; // Does not exist. auto oldlump = FileInfo[lump]; - ptrdiff_t slash = oldlump.longName.LastIndexOf('/'); + ptrdiff_t slash = oldlump.longName.find_last_of('/'); - if (slash == -1) + if (slash == std::string::npos) { FileInfo[lump].flags = LUMPF_FULLPATH; return true; // already is pathless. @@ -1502,10 +1513,10 @@ bool FileSystem::CreatePathlessCopy(const char *name, int id, int /*flags*/) // just create a new reference to the original data with a different name. - oldlump.longName = oldlump.longName.Mid(slash + 1); + oldlump.longName.erase(oldlump.longName.begin(), oldlump.longName.begin() + (slash + 1)); oldlump.resourceId = id; oldlump.flags = LUMPF_FULLPATH; - FileInfo.Push(oldlump); + FileInfo.push_back(oldlump); return true; } diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index 9f7da8b3e..9845757e3 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -169,7 +169,7 @@ protected: struct LumpRecord; TArray Files; - TArray FileInfo; + std::vector FileInfo; TArray Hashes; // one allocation for all hash lists. uint32_t *FirstLumpIndex; // [RH] Hashing stuff moved out of lumpinfo structure diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index cbfdfc821..b38d2c078 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -679,15 +679,15 @@ void FTextureManager::AddHiresTextures (int wadnum) void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname, FMultipatchTextureBuilder &build) { - int remapLump, lastLump; + int texLump, lastLump; lastLump = 0; - while ((remapLump = fileSystem.FindLump(lumpname, &lastLump)) != -1) + while ((texLump = fileSystem.FindLump(lumpname, &lastLump)) != -1) { - if (fileSystem.GetFileContainer(remapLump) == wadnum) + if (fileSystem.GetFileContainer(texLump) == wadnum) { - ParseTextureDef(remapLump, build); + ParseTextureDef(texLump, build); } } } From a0d679b84b28d071c74fcf9df9d3c6074991c55d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 19 Aug 2023 22:59:11 +0200 Subject: [PATCH 027/223] - FileData cleanup and uncoupling from FString. Work is still needed to allow this to use the lump cache directly because some decisions in the past made this data padded by a zero byte. --- src/common/filesystem/filesystem.cpp | 41 ++++++------------- src/common/filesystem/filesystem.h | 15 ++++--- src/common/fonts/singlelumpfont.cpp | 4 +- src/common/models/model.cpp | 2 +- src/common/models/model_ue1.h | 10 ++--- src/common/models/models_md2.cpp | 4 +- src/common/models/models_md3.cpp | 2 +- src/common/models/models_ue1.cpp | 23 +++++------ src/common/models/voxels.cpp | 2 +- .../textures/formats/automaptexture.cpp | 2 +- src/common/textures/formats/imgztexture.cpp | 2 +- src/common/textures/formats/qoitexture.cpp | 2 +- .../textures/formats/rawpagetexture.cpp | 6 +-- .../textures/formats/startuptexture.cpp | 12 +++--- src/common/utility/palette.cpp | 11 +++-- src/common/utility/zstring.h | 3 -- src/gamedata/keysections.cpp | 4 +- src/gamedata/textures/anim_switches.cpp | 2 +- src/gamedata/textures/animations.cpp | 2 +- src/gamedata/textures/buildloader.cpp | 2 +- src/maploader/glnodes.cpp | 2 +- src/r_data/r_translate.cpp | 2 +- src/r_data/sprites.cpp | 2 +- src/r_data/v_palette.cpp | 2 +- 24 files changed, 69 insertions(+), 90 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index d768d5d28..1671438b5 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -40,10 +40,7 @@ #include #include -#include "m_argv.h" -#include "cmdlib.h" #include "filesystem.h" - #include "m_crc32.h" #if __has_include("md5.h") @@ -1320,7 +1317,13 @@ void FileSystem::ReadFile (int lump, void *dest) FileData FileSystem::ReadFile (int lump) { - return FileData(FString(*this, ELumpNum(lump))); + if ((unsigned)lump >= (unsigned)FileInfo.size()) + { + throw FileSystemException("ReadFile: %u >= NumEntries", lump); + } + auto lumpp = FileInfo[lump].lump; + + return FileData(lumpp); } //========================================================================== @@ -1522,10 +1525,6 @@ bool FileSystem::CreatePathlessCopy(const char *name, int id, int /*flags*/) // FileData ----------------------------------------------------------------- -FileData::FileData () -{ -} - FileData::FileData (const FileData ©) { Block = copy.Block; @@ -1537,29 +1536,15 @@ FileData &FileData::operator = (const FileData ©) return *this; } -FileData::FileData (const FString &source) -: Block (source) +FileData::FileData (FResourceLump* lump) { + auto size = lump->LumpSize; + Block.resize(1 + size); + memcpy(Block.data(), lump->Lock(), size); + Block[size] = 0; + lump->Unlock(); } -FileData::~FileData () -{ -} - -FString::FString (FileSystem& fileSystem, ELumpNum lumpnum) -{ - auto lumpr = fileSystem.OpenFileReader ((int)lumpnum); - auto size = lumpr.GetLength (); - AllocBuffer (1 + size); - auto numread = lumpr.Read (&Chars[0], size); - Chars[size] = '\0'; - - if (numread != size) - { - throw FileSystemException("ConstructStringFromLump: Only read %ld of %ld bytes on lump %i (%s)\n", - numread, size, lumpnum, fileSystem.GetFileFullName((int)lumpnum)); - } -} //========================================================================== // diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index 9845757e3..f28666907 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -29,19 +29,18 @@ union LumpShortName class FileData { public: - FileData (); - + FileData () = default; FileData (const FileData ©); FileData &operator= (const FileData ©); - ~FileData (); - const void *GetMem () { return Block.Len() == 0 ? NULL : (void *)Block.GetChars(); } - size_t GetSize () { return Block.Len(); } - const char* GetString () const { return Block.GetChars(); } + const void *GetMem () { return Block.size() <= 1 ? NULL : (void *)Block.data(); } + size_t GetSize () { return Block.size(); } + const char* GetString () const { return (const char*)Block.data(); } + const uint8_t* GetBytes() const { return Block.data(); } private: - FileData (const FString &source); + FileData (FResourceLump* lump); - FString Block; + std::vector Block; friend class FileSystem; }; diff --git a/src/common/fonts/singlelumpfont.cpp b/src/common/fonts/singlelumpfont.cpp index 94cbd18ec..72a3b1805 100644 --- a/src/common/fonts/singlelumpfont.cpp +++ b/src/common/fonts/singlelumpfont.cpp @@ -125,7 +125,7 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump) FontName = name; FileData data1 = fileSystem.ReadFile (lump); - const uint8_t *data = (const uint8_t *)data1.GetMem(); + auto data = data1.GetBytes(); if (data[0] == 0xE1 && data[1] == 0xE6 && data[2] == 0xD5 && data[3] == 0x1A) { @@ -475,7 +475,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) void FSingleLumpFont::CheckFON1Chars() { FileData memLump = fileSystem.ReadFile(Lump); - const uint8_t* data = (const uint8_t*)memLump.GetMem(); + auto data = memLump.GetBytes(); const uint8_t* data_p; data_p = data + 8; diff --git a/src/common/models/model.cpp b/src/common/models/model.cpp index c93fa7876..ceb77bcff 100644 --- a/src/common/models/model.cpp +++ b/src/common/models/model.cpp @@ -173,7 +173,7 @@ unsigned FindModel(const char * path, const char * modelfile, bool silent) int len = fileSystem.FileLength(lump); FileData lumpd = fileSystem.ReadFile(lump); - char * buffer = (char*)lumpd.GetMem(); + const char * buffer = lumpd.GetString(); if ( (size_t)fullname.LastIndexOf("_d.3d") == fullname.Len()-5 ) { diff --git a/src/common/models/model_ue1.h b/src/common/models/model_ue1.h index 9b529b44c..4163dd2ba 100644 --- a/src/common/models/model_ue1.h +++ b/src/common/models/model_ue1.h @@ -70,15 +70,15 @@ private: { uint16_t numframes, framesize; }; - d3dhead * dhead; - d3dpoly * dpolys; - a3dhead * ahead; - uint32_t * averts; + const d3dhead * dhead; + const d3dpoly * dpolys; + const a3dhead * ahead; + const uint32_t * averts; struct dxvert { int16_t x, y, z, pad; }; - dxvert * dxverts; + const dxvert * dxverts; // converted data structures struct UE1Vertex diff --git a/src/common/models/models_md2.cpp b/src/common/models/models_md2.cpp index 56ab6274c..0dd402cf9 100644 --- a/src/common/models/models_md2.cpp +++ b/src/common/models/models_md2.cpp @@ -178,7 +178,7 @@ void FDMDModel::LoadGeometry() { static int axis[3] = { VX, VY, VZ }; FileData lumpdata = fileSystem.ReadFile(mLumpNum); - const char *buffer = (const char *)lumpdata.GetMem(); + auto buffer = lumpdata.GetString(); texCoords = new FTexCoord[info.numTexCoords]; memcpy(texCoords, buffer + info.offsetTexCoords, info.numTexCoords * sizeof(FTexCoord)); @@ -502,7 +502,7 @@ void FMD2Model::LoadGeometry() static int axis[3] = { VX, VY, VZ }; uint8_t *md2_frames; FileData lumpdata = fileSystem.ReadFile(mLumpNum); - const char *buffer = (const char *)lumpdata.GetMem(); + auto buffer = lumpdata.GetString(); texCoords = new FTexCoord[info.numTexCoords]; memcpy(texCoords, (uint8_t*)buffer + info.offsetTexCoords, info.numTexCoords * sizeof(FTexCoord)); diff --git a/src/common/models/models_md3.cpp b/src/common/models/models_md3.cpp index 2337a3897..ea2083a8b 100644 --- a/src/common/models/models_md3.cpp +++ b/src/common/models/models_md3.cpp @@ -190,7 +190,7 @@ bool FMD3Model::Load(const char * path, int lumpnum, const char * buffer, int le void FMD3Model::LoadGeometry() { FileData lumpdata = fileSystem.ReadFile(mLumpNum); - const char *buffer = (const char *)lumpdata.GetMem(); + auto buffer = lumpdata.GetString(); md3_header_t * hdr = (md3_header_t *)buffer; md3_surface_t * surf = (md3_surface_t*)(buffer + LittleLong(hdr->Ofs_Surfaces)); diff --git a/src/common/models/models_ue1.cpp b/src/common/models/models_ue1.cpp index 5db36a672..aa8567850 100644 --- a/src/common/models/models_ue1.cpp +++ b/src/common/models/models_ue1.cpp @@ -69,26 +69,25 @@ bool FUE1Model::Load( const char *filename, int lumpnum, const char *buffer, int void FUE1Model::LoadGeometry() { - FileData lump, lump2; const char *buffer, *buffer2; - lump = fileSystem.ReadFile(mDataLump); - buffer = (char*)lump.GetMem(); - lump2 = fileSystem.ReadFile(mAnivLump); - buffer2 = (char*)lump2.GetMem(); + FileData lump = fileSystem.ReadFile(mDataLump); + buffer = lump.GetString(); + FileData lump2 = fileSystem.ReadFile(mAnivLump); + buffer2 = lump2.GetString(); // map structures - dhead = (d3dhead*)(buffer); - dpolys = (d3dpoly*)(buffer+sizeof(d3dhead)); - ahead = (a3dhead*)(buffer2); + dhead = (const d3dhead*)(buffer); + dpolys = (const d3dpoly*)(buffer+sizeof(d3dhead)); + ahead = (const a3dhead*)(buffer2); // detect deus ex format if ( (ahead->framesize/dhead->numverts) == 8 ) { - averts = NULL; - dxverts = (dxvert*)(buffer2+sizeof(a3dhead)); + averts = nullptr; + dxverts = (const dxvert*)(buffer2+sizeof(a3dhead)); } else { - averts = (uint32_t*)(buffer2+sizeof(a3dhead)); - dxverts = NULL; + averts = (const uint32_t*)(buffer2+sizeof(a3dhead)); + dxverts = nullptr; } // set counters numVerts = dhead->numverts; diff --git a/src/common/models/voxels.cpp b/src/common/models/voxels.cpp index d8d2b2245..6c7867ccf 100644 --- a/src/common/models/voxels.cpp +++ b/src/common/models/voxels.cpp @@ -162,7 +162,7 @@ FVoxel *R_LoadKVX(int lumpnum) int i, j, n; FileData lump = fileSystem.ReadFile(lumpnum); // FileData adds an extra 0 byte to the end. - uint8_t *rawvoxel = (uint8_t *)lump.GetMem(); + auto rawvoxel = lump.GetBytes(); int voxelsize = (int)(lump.GetSize()-1); // Oh, KVX, why couldn't you have a proper header? We'll just go through diff --git a/src/common/textures/formats/automaptexture.cpp b/src/common/textures/formats/automaptexture.cpp index c253650fd..6b660b1ba 100644 --- a/src/common/textures/formats/automaptexture.cpp +++ b/src/common/textures/formats/automaptexture.cpp @@ -93,7 +93,7 @@ PalettedPixels FAutomapTexture::CreatePalettedPixels(int conversion) { int x, y; FileData data = fileSystem.ReadFile (SourceLump); - const uint8_t *indata = (const uint8_t *)data.GetMem(); + auto indata = data.GetBytes(); PalettedPixels Pixels(Width * Height); diff --git a/src/common/textures/formats/imgztexture.cpp b/src/common/textures/formats/imgztexture.cpp index 733d20f84..fb020c9a1 100644 --- a/src/common/textures/formats/imgztexture.cpp +++ b/src/common/textures/formats/imgztexture.cpp @@ -121,7 +121,7 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1 PalettedPixels FIMGZTexture::CreatePalettedPixels(int conversion) { FileData lump = fileSystem.ReadFile (SourceLump); - const ImageHeader *imgz = (const ImageHeader *)lump.GetMem(); + auto imgz = (const ImageHeader *)lump.GetMem(); const uint8_t *data = (const uint8_t *)&imgz[1]; uint8_t *dest_p; diff --git a/src/common/textures/formats/qoitexture.cpp b/src/common/textures/formats/qoitexture.cpp index abe628223..c84ac38ce 100644 --- a/src/common/textures/formats/qoitexture.cpp +++ b/src/common/textures/formats/qoitexture.cpp @@ -148,7 +148,7 @@ int FQOITexture::CopyPixels(FBitmap *bmp, int conversion) size_t p = 14, run = 0; size_t chunks_len = lump.GetSize() - 8; - auto bytes = (const uint8_t*)lump.GetMem(); + auto bytes = lump.GetBytes(); for (int h = 0; h < Height; h++) { diff --git a/src/common/textures/formats/rawpagetexture.cpp b/src/common/textures/formats/rawpagetexture.cpp index 337ca5520..e2b6c1146 100644 --- a/src/common/textures/formats/rawpagetexture.cpp +++ b/src/common/textures/formats/rawpagetexture.cpp @@ -173,7 +173,7 @@ FRawPageTexture::FRawPageTexture (int lumpnum) PalettedPixels FRawPageTexture::CreatePalettedPixels(int conversion) { FileData lump = fileSystem.ReadFile (SourceLump); - const uint8_t *source = (const uint8_t *)lump.GetMem(); + auto source = lump.GetBytes(); const uint8_t *source_p = source; uint8_t *dest_p; @@ -206,8 +206,8 @@ int FRawPageTexture::CopyPixels(FBitmap *bmp, int conversion) { FileData lump = fileSystem.ReadFile(SourceLump); FileData plump = fileSystem.ReadFile(mPaletteLump); - const uint8_t *source = (const uint8_t *)lump.GetMem(); - const uint8_t *psource = (const uint8_t *)plump.GetMem(); + auto source = lump.GetBytes(); + auto psource = plump.GetBytes(); PalEntry paldata[256]; for (auto & pe : paldata) { diff --git a/src/common/textures/formats/startuptexture.cpp b/src/common/textures/formats/startuptexture.cpp index 8a2a1e602..718b7182a 100644 --- a/src/common/textures/formats/startuptexture.cpp +++ b/src/common/textures/formats/startuptexture.cpp @@ -165,7 +165,7 @@ FStartupTexture::FStartupTexture (int lumpnum) bUseGamePalette = false; FileData lump = fileSystem.ReadFile (SourceLump); - const uint8_t *source = (const uint8_t *)lump.GetMem(); + auto source = lump.GetBytes(); // Initialize the bitmap palette. // the palette is static so that the notches can share it. @@ -234,7 +234,7 @@ void PlanarToChunky(T* dest, const uint8_t* src, const T* remap, int width, int PalettedPixels FStartupTexture::CreatePalettedPixels(int conversion) { FileData lump = fileSystem.ReadFile (SourceLump); - const uint8_t *source = (const uint8_t *)lump.GetMem(); + auto source = lump.GetBytes(); const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); @@ -254,7 +254,7 @@ PalettedPixels FStartupTexture::CreatePalettedPixels(int conversion) int FStartupTexture::CopyPixels(FBitmap *bmp, int conversion) { FileData lump = fileSystem.ReadFile (SourceLump); - const uint8_t *source = (const uint8_t *)lump.GetMem(); + auto source = lump.GetBytes(); PlanarToChunky((uint32_t*)bmp->GetPixels(), source + 48, startuppalette32, Width, Height); return 0; } @@ -282,7 +282,7 @@ FNotchTexture::FNotchTexture (int lumpnum, int width, int height) PalettedPixels FNotchTexture::CreatePalettedPixels(int conversion) { FileData lump = fileSystem.ReadFile (SourceLump); - const uint8_t *source = (const uint8_t *)lump.GetMem(); + auto source = lump.GetBytes(); const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); TArray Work(Width*Height, true); @@ -305,7 +305,7 @@ PalettedPixels FNotchTexture::CreatePalettedPixels(int conversion) int FNotchTexture::CopyPixels(FBitmap *bmp, int conversion) { FileData lump = fileSystem.ReadFile (SourceLump); - const uint8_t *source = (const uint8_t *)lump.GetMem(); + auto source = lump.GetBytes(); auto Work = (uint32_t*)bmp->GetPixels(); for(int i = 0; i < Width * Height / 2; i++) @@ -339,7 +339,7 @@ FStrifeStartupTexture::FStrifeStartupTexture (int lumpnum, int w, int h) PalettedPixels FStrifeStartupTexture::CreatePalettedPixels(int conversion) { FileData lump = fileSystem.ReadFile (SourceLump); - const uint8_t *source = (const uint8_t *)lump.GetMem(); + auto source = lump.GetBytes(); PalettedPixels Pixels(Width*Height); const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); ImageHelpers::FlipNonSquareBlockRemap(Pixels.Data(), source, Width, Height, Width, remap); diff --git a/src/common/utility/palette.cpp b/src/common/utility/palette.cpp index 527d1cd17..4d1cd1444 100644 --- a/src/common/utility/palette.cpp +++ b/src/common/utility/palette.cpp @@ -663,9 +663,8 @@ int V_GetColorFromString(const char* cstr, FScriptPosition* sc) FString V_GetColorStringByName(const char* name, FScriptPosition* sc) { - FileData rgbNames; - char* rgbEnd; - char* rgb, * endp; + const char* rgbEnd; + const char* rgb, * endp; int rgblump; int c[3], step; size_t namelen; @@ -680,7 +679,7 @@ FString V_GetColorStringByName(const char* name, FScriptPosition* sc) return FString(); } - rgbNames = fileSystem.ReadFile(rgblump); + auto rgbNames = fileSystem.ReadFile(rgblump); rgb = (char*)rgbNames.GetMem(); rgbEnd = rgb + fileSystem.FileLength(rgblump); step = 0; @@ -705,7 +704,7 @@ FString V_GetColorStringByName(const char* name, FScriptPosition* sc) } else if (step < 3) { // collect RGB values - c[step++] = strtoul(rgb, &endp, 10); + c[step++] = strtoul(rgb, (char**)&endp, 10); if (endp == rgb) { break; @@ -930,7 +929,7 @@ int ReadPalette(int lumpnum, uint8_t* buffer) return 0; } FileData lump = fileSystem.ReadFile(lumpnum); - uint8_t* lumpmem = (uint8_t*)lump.GetMem(); + auto lumpmem = lump.GetBytes(); memset(buffer, 0, 768); FileReader fr; diff --git a/src/common/utility/zstring.h b/src/common/utility/zstring.h index 89ae13568..1164ddb6d 100644 --- a/src/common/utility/zstring.h +++ b/src/common/utility/zstring.h @@ -147,9 +147,6 @@ public: FString (const char *head, const char *tail); FString (char head, const FString &tail); - // Other constructors - FString (FileSystem&, ELumpNum); // Create from a lump - ~FString (); // Discard string's contents, create a new buffer, and lock it. diff --git a/src/gamedata/keysections.cpp b/src/gamedata/keysections.cpp index 5f06f192e..390c8009f 100644 --- a/src/gamedata/keysections.cpp +++ b/src/gamedata/keysections.cpp @@ -166,8 +166,8 @@ void D_LoadWadSettings () while ((lump = fileSystem.FindLump ("KEYCONF", &lastlump)) != -1) { FileData data = fileSystem.ReadFile (lump); - const char *eof = (char *)data.GetMem() + fileSystem.FileLength (lump); - const char *conf = (char *)data.GetMem(); + const char *eof = data.GetString() + fileSystem.FileLength (lump); + const char *conf = data.GetString(); while (conf < eof) { diff --git a/src/gamedata/textures/anim_switches.cpp b/src/gamedata/textures/anim_switches.cpp index 78e49508d..36666bc3f 100644 --- a/src/gamedata/textures/anim_switches.cpp +++ b/src/gamedata/textures/anim_switches.cpp @@ -67,7 +67,7 @@ void FTextureAnimator::InitSwitchList () if (lump != -1) { FileData lumpdata = fileSystem.ReadFile (lump); - const char *alphSwitchList = (const char *)lumpdata.GetMem(); + auto alphSwitchList = lumpdata.GetString(); const char *list_p; FSwitchDef *def1, *def2; diff --git a/src/gamedata/textures/animations.cpp b/src/gamedata/textures/animations.cpp index 0091a3ba5..51834d4e0 100644 --- a/src/gamedata/textures/animations.cpp +++ b/src/gamedata/textures/animations.cpp @@ -205,7 +205,7 @@ void FTextureAnimator::InitAnimated (void) { FileData animatedlump = fileSystem.ReadFile (lumpnum); int animatedlen = fileSystem.FileLength(lumpnum); - const uint8_t *animdefs = (const uint8_t *)animatedlump.GetMem(); + auto animdefs = animatedlump.GetBytes(); const uint8_t *anim_p; FTextureID pic1, pic2; int animtype; diff --git a/src/gamedata/textures/buildloader.cpp b/src/gamedata/textures/buildloader.cpp index 4bb7b2721..515635871 100644 --- a/src/gamedata/textures/buildloader.cpp +++ b/src/gamedata/textures/buildloader.cpp @@ -85,7 +85,7 @@ static int BuildPaletteTranslation(int lump) } FileData data = fileSystem.ReadFile(lump); - const uint8_t *ipal = (const uint8_t *)data.GetMem(); + auto ipal = data.GetBytes(); FRemapTable opal; bool blood = false; diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index ff4492279..15b4b46ba 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -754,7 +754,7 @@ static int FindGLNodesInWAD(int labellump) if (fileSystem.GetFileContainer(lump)==wadfile) { FileData mem = fileSystem.ReadFile(lump); - if (MatchHeader(fileSystem.GetFileFullName(labellump), (const char *)mem.GetMem())) return lump; + if (MatchHeader(fileSystem.GetFileFullName(labellump), mem.GetString())) return lump; } } } diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index 0f130e30a..1490faf26 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -431,7 +431,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC else { FileData translump = fileSystem.ReadFile(colorset->Lump); - const uint8_t *trans = (const uint8_t *)translump.GetMem(); + auto trans = translump.GetBytes(); for (i = start; i <= end; ++i) { table->Remap[i] = GPalette.Remap[trans[i]]; diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 97a5e2e46..1f6b161a9 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -947,7 +947,7 @@ CCMD (skins) static void R_CreateSkinTranslation (const char *palname) { FileData lump = fileSystem.ReadFile (palname); - const uint8_t *otherPal = (uint8_t *)lump.GetMem(); + auto otherPal = lump.GetBytes(); for (int i = 0; i < 256; ++i) { diff --git a/src/r_data/v_palette.cpp b/src/r_data/v_palette.cpp index 333cb7579..068edb124 100644 --- a/src/r_data/v_palette.cpp +++ b/src/r_data/v_palette.cpp @@ -63,7 +63,7 @@ void InitPalette () if (lump != -1) { FileData cmap = fileSystem.ReadFile(lump); - const unsigned char* cmapdata = (const unsigned char*)cmap.GetMem(); + auto cmapdata = cmap.GetBytes(); GPalette.GenerateGlobalBrightmapFromColormap(cmapdata, 32); MakeGoodRemap((uint32_t*)GPalette.BaseColors, GPalette.Remap, cmapdata + 7936); // last entry in colormap } From 4906d287cb19ee5bd78f3e467bbb659de597792e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 Aug 2023 21:26:44 +0200 Subject: [PATCH 028/223] - use std::vector to pass the file list to InitMultipleFiles --- src/common/console/c_dispatch.cpp | 2 +- src/common/console/c_dispatch.h | 4 ++- src/common/console/c_enginecmds.cpp | 1 + src/common/filesystem/filesystem.cpp | 22 ++++++------- src/common/filesystem/filesystem.h | 2 +- src/common/objects/dobjgc.cpp | 1 + src/common/platform/win32/i_mainwindow.cpp | 2 +- .../rendering/vulkan/shaders/vk_shader.cpp | 1 + src/common/startscreen/startscreen_strife.cpp | 1 + src/common/textures/gametexture.cpp | 1 + src/common/textures/texturemanager.cpp | 2 ++ src/common/utility/findfile.cpp | 16 +++++----- src/common/utility/findfile.h | 12 +++---- src/common/utility/palette.cpp | 1 + src/d_iwad.cpp | 15 +++++---- src/d_main.cpp | 31 ++++++++++++------- src/d_main.h | 4 +-- 17 files changed, 67 insertions(+), 51 deletions(-) diff --git a/src/common/console/c_dispatch.cpp b/src/common/console/c_dispatch.cpp index 7de13e2ea..7bac0b698 100644 --- a/src/common/console/c_dispatch.cpp +++ b/src/common/console/c_dispatch.cpp @@ -1003,7 +1003,7 @@ void FExecList::ExecCommands() const } } -void FExecList::AddPullins(TArray &wads, FConfigFile *config) const +void FExecList::AddPullins(std::vector& wads, FConfigFile *config) const { for (unsigned i = 0; i < Pullins.Size(); ++i) { diff --git a/src/common/console/c_dispatch.h b/src/common/console/c_dispatch.h index 532ed9b92..e8b2bfdf0 100644 --- a/src/common/console/c_dispatch.h +++ b/src/common/console/c_dispatch.h @@ -34,6 +34,8 @@ #ifndef __C_DISPATCH_H__ #define __C_DISPATCH_H__ +#include +#include #include #include #include "c_console.h" @@ -52,7 +54,7 @@ struct FExecList void AddCommand(const char *cmd, const char *file = nullptr); void ExecCommands() const; - void AddPullins(TArray &wads, FConfigFile *config) const; + void AddPullins(std::vector &wads, FConfigFile *config) const; }; extern bool ParsingKeyConf, UnsafeExecutionContext; diff --git a/src/common/console/c_enginecmds.cpp b/src/common/console/c_enginecmds.cpp index 6c914db66..40be68688 100644 --- a/src/common/console/c_enginecmds.cpp +++ b/src/common/console/c_enginecmds.cpp @@ -54,6 +54,7 @@ #include "md5.h" #include "i_specialpaths.h" #include "i_system.h" +#include "cmdlib.h" extern FILE* Logfile; diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 1671438b5..cea9cd99f 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -207,12 +207,11 @@ void FileSystem::DeleteAll () bool FileSystem::InitSingleFile(const char* filename, FileSystemMessageFunc Printf) { - TArray filenames; - filenames.Push(filename); + std::vector filenames = { filename }; return InitMultipleFiles(filenames, nullptr, Printf); } -bool FileSystem::InitMultipleFiles (TArray &filenames, LumpFilterInfo* filter, FileSystemMessageFunc Printf, bool allowduplicates, FILE* hashfile) +bool FileSystem::InitMultipleFiles (std::vector& filenames, LumpFilterInfo* filter, FileSystemMessageFunc Printf, bool allowduplicates, FILE* hashfile) { int numfiles; @@ -223,26 +222,27 @@ bool FileSystem::InitMultipleFiles (TArray &filenames, LumpFilterInfo* // first, check for duplicates if (allowduplicates) { - for (unsigned i=0;iGetHash()); - MoveLumpsInFolder(path); + std::string path = "filter/%s"; + path += Files.Last()->GetHash(); + MoveLumpsInFolder(path.c_str()); } NumEntries = (uint32_t)FileInfo.size(); diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index f28666907..cb4695280 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -65,7 +65,7 @@ public: void SetMaxIwadNum(int x) { MaxIwadIndex = x; } bool InitSingleFile(const char *filename, FileSystemMessageFunc Printf = nullptr); - bool InitMultipleFiles (TArray &filenames, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, bool allowduplicates = false, FILE* hashfile = nullptr); + bool InitMultipleFiles (std::vector& filenames, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, bool allowduplicates = false, FILE* hashfile = nullptr); void AddFile (const char *filename, FileReader *wadinfo, LumpFilterInfo* filter, FileSystemMessageFunc Printf, FILE* hashfile); int CheckIfResourceFileLoaded (const char *name) noexcept; void AddAdditionalFile(const char* filename, FileReader* wadinfo = NULL) {} diff --git a/src/common/objects/dobjgc.cpp b/src/common/objects/dobjgc.cpp index ac75b411a..64f36a129 100644 --- a/src/common/objects/dobjgc.cpp +++ b/src/common/objects/dobjgc.cpp @@ -62,6 +62,7 @@ #include "menu.h" #include "stats.h" #include "printf.h" +#include "cmdlib.h" // MACROS ------------------------------------------------------------------ diff --git a/src/common/platform/win32/i_mainwindow.cpp b/src/common/platform/win32/i_mainwindow.cpp index 5b246e457..4c4f61568 100644 --- a/src/common/platform/win32/i_mainwindow.cpp +++ b/src/common/platform/win32/i_mainwindow.cpp @@ -335,7 +335,7 @@ void MainWindow::SetNetStartProgress(int pos) if (NetStartPane != 0 && NetStartMaxPos > 1) { char buf[16]; - mysnprintf(buf, countof(buf), "%d/%d", pos, NetStartMaxPos); + mysnprintf(buf, sizeof(buf), "%d/%d", pos, NetStartMaxPos); SetDlgItemTextA(NetStartPane, IDC_NETSTARTCOUNT, buf); SendDlgItemMessage(NetStartPane, IDC_NETSTARTPROGRESS, PBM_SETPOS, min(pos, NetStartMaxPos), 0); } diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index 25b585531..2c3eb9241 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -28,6 +28,7 @@ #include "filesystem.h" #include "engineerrors.h" #include "version.h" +#include "cmdlib.h" bool VkShaderManager::CompileNextShader() { diff --git a/src/common/startscreen/startscreen_strife.cpp b/src/common/startscreen/startscreen_strife.cpp index 6587443b8..b4490a921 100644 --- a/src/common/startscreen/startscreen_strife.cpp +++ b/src/common/startscreen/startscreen_strife.cpp @@ -39,6 +39,7 @@ #include "image.h" #include "textures.h" #include "palettecontainer.h" +#include "cmdlib.h" // Strife startup screen #define PEASANT_INDEX 0 diff --git a/src/common/textures/gametexture.cpp b/src/common/textures/gametexture.cpp index 3ddc8dd1b..20b22939d 100644 --- a/src/common/textures/gametexture.cpp +++ b/src/common/textures/gametexture.cpp @@ -49,6 +49,7 @@ #include "texturemanager.h" #include "c_cvars.h" #include "hw_material.h" +#include "cmdlib.h" FTexture *CreateBrightmapTexture(FImageSource*); diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index b38d2c078..444b3b4eb 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -47,6 +47,8 @@ #include "vectors.h" #include "animtexture.h" #include "formats/multipatchtexture.h" +#include "basics.h" +#include "cmdlib.h" FTextureManager TexMan; diff --git a/src/common/utility/findfile.cpp b/src/common/utility/findfile.cpp index ab5c4299c..17d2c9154 100644 --- a/src/common/utility/findfile.cpp +++ b/src/common/utility/findfile.cpp @@ -47,7 +47,7 @@ // //========================================================================== -bool D_AddFile(TArray& wadfiles, const char* file, bool check, int position, FConfigFile* config) +bool D_AddFile(std::vector& wadfiles, const char* file, bool check, int position, FConfigFile* config) { if (file == nullptr || *file == '\0') { @@ -111,10 +111,10 @@ bool D_AddFile(TArray& wadfiles, const char* file, bool check, int posi file = f; } - FString f = file; - FixPathSeperator(f); - if (position == -1) wadfiles.Push(f); - else wadfiles.Insert(position, f); + std::string f = file; + for (auto& c : f) if (c == '\\') c = '/'; + if (position == -1) wadfiles.push_back(f); + else wadfiles.insert(wadfiles.begin() + position, f); return true; } @@ -124,7 +124,7 @@ bool D_AddFile(TArray& wadfiles, const char* file, bool check, int posi // //========================================================================== -void D_AddWildFile(TArray& wadfiles, const char* value, const char *extension, FConfigFile* config) +void D_AddWildFile(std::vector& wadfiles, const char* value, const char *extension, FConfigFile* config) { if (value == nullptr || *value == '\0') { @@ -161,7 +161,7 @@ void D_AddWildFile(TArray& wadfiles, const char* value, const char *ext // //========================================================================== -void D_AddConfigFiles(TArray& wadfiles, const char* section, const char* extension, FConfigFile *config) +void D_AddConfigFiles(std::vector& wadfiles, const char* section, const char* extension, FConfigFile *config) { if (config && config->SetSection(section)) { @@ -191,7 +191,7 @@ void D_AddConfigFiles(TArray& wadfiles, const char* section, const char // //========================================================================== -void D_AddDirectory(TArray& wadfiles, const char* dir, const char *filespec, FConfigFile* config) +void D_AddDirectory(std::vector& wadfiles, const char* dir, const char *filespec, FConfigFile* config) { FileList list; if (ScanDirectory(list, dir, "*.wad", true)) diff --git a/src/common/utility/findfile.h b/src/common/utility/findfile.h index 31f8bd65b..fd58ecde5 100644 --- a/src/common/utility/findfile.h +++ b/src/common/utility/findfile.h @@ -2,13 +2,13 @@ // Directory searching routines #include -#include "zstring.h" - +#include +#include class FConfigFile; -bool D_AddFile(TArray& wadfiles, const char* file, bool check, int position, FConfigFile* config); -void D_AddWildFile(TArray& wadfiles, const char* value, const char *extension, FConfigFile* config); -void D_AddConfigFiles(TArray& wadfiles, const char* section, const char* extension, FConfigFile* config); -void D_AddDirectory(TArray& wadfiles, const char* dir, const char *filespec, FConfigFile* config); +bool D_AddFile(std::vector& wadfiles, const char* file, bool check, int position, FConfigFile* config); +void D_AddWildFile(std::vector& wadfiles, const char* value, const char *extension, FConfigFile* config); +void D_AddConfigFiles(std::vector& wadfiles, const char* section, const char* extension, FConfigFile* config); +void D_AddDirectory(std::vector& wadfiles, const char* dir, const char *filespec, FConfigFile* config); const char* BaseFileSearch(const char* file, const char* ext, bool lookfirstinprogdir, FConfigFile* config); diff --git a/src/common/utility/palette.cpp b/src/common/utility/palette.cpp index 4d1cd1444..7598f5d4e 100644 --- a/src/common/utility/palette.cpp +++ b/src/common/utility/palette.cpp @@ -40,6 +40,7 @@ #include "filesystem.h" #include "printf.h" #include "m_swap.h" +#include "cmdlib.h" #include "m_png.h" diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 62e4e459b..cf46eec13 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -305,9 +305,9 @@ void GetReserved(LumpFilterInfo& lfi); FIWadManager::FIWadManager(const char *firstfn, const char *optfn) { FileSystem check; - TArray fns; - fns.Push(firstfn); - if (optfn) fns.Push(optfn); + std::vector fns; + fns.push_back(firstfn); + if (optfn) fns.push_back(optfn); if (check.InitMultipleFiles(fns, nullptr, nullptr)) { @@ -388,8 +388,7 @@ int FIWadManager::CheckIWADInfo(const char* fn) LumpFilterInfo lfi; GetReserved(lfi); - TArray filenames; - filenames.Push(fn); + std::vector filenames = { fn }; if (check.InitMultipleFiles(filenames, &lfi, nullptr)) { int num = check.CheckNumForName("IWADINFO"); @@ -552,7 +551,7 @@ void FIWadManager::ValidateIWADs() static bool havepicked = false; -int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, const char *zdoom_wad, const char *optional_wad) +int FIWadManager::IdentifyVersion (std::vector&wadfiles, const char *iwad, const char *zdoom_wad, const char *optional_wad) { const char *iwadparm = Args->CheckValue ("-iwad"); FString custwad; @@ -777,7 +776,7 @@ int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, } // zdoom.pk3 must always be the first file loaded and the IWAD second. - wadfiles.Clear(); + wadfiles.clear(); D_AddFile (wadfiles, zdoom_wad, true, -1, GameConfig); // [SP] Load non-free assets if available. This must be done before the IWAD. @@ -833,7 +832,7 @@ int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, // //========================================================================== -const FIWADInfo *FIWadManager::FindIWAD(TArray &wadfiles, const char *iwad, const char *basewad, const char *optionalwad) +const FIWADInfo *FIWadManager::FindIWAD(std::vector& wadfiles, const char *iwad, const char *basewad, const char *optionalwad) { int iwadType = IdentifyVersion(wadfiles, iwad, basewad, optionalwad); if (iwadType == -1) return nullptr; diff --git a/src/d_main.cpp b/src/d_main.cpp index 5660c4ed2..a35035fcc 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1775,7 +1775,7 @@ FExecList *D_MultiExec (FArgs *list, FExecList *exec) return exec; } -static void GetCmdLineFiles(TArray &wadfiles) +static void GetCmdLineFiles(std::vector& wadfiles) { FString *args; int i, argc; @@ -1788,7 +1788,7 @@ static void GetCmdLineFiles(TArray &wadfiles) } -static FString ParseGameInfo(TArray &pwads, const char *fn, const char *data, int size) +static FString ParseGameInfo(std::vector &pwads, const char *fn, const char *data, int size) { FScanner sc; FString iwad; @@ -1920,7 +1920,7 @@ void GetReserved(LumpFilterInfo& lfi) lfi.requiredPrefixes = { "mapinfo", "zmapinfo", "umapinfo", "gameinfo", "sndinfo", "sndseq", "sbarinfo", "menudef", "gldefs", "animdefs", "decorate", "zscript", "iwadinfo", "maps/" }; } -static FString CheckGameInfo(TArray & pwads) +static FString CheckGameInfo(std::vector & pwads) { FileSystem check; @@ -1987,7 +1987,7 @@ static void D_DoomInit() // //========================================================================== -static void AddAutoloadFiles(const char *autoname, TArray& allwads) +static void AddAutoloadFiles(const char *autoname, std::vector& allwads) { LumpFilterIWAD.Format("%s.", autoname); // The '.' is appened to simplify parsing the string @@ -3089,7 +3089,7 @@ static int FileSystemPrintf(FSMessageLevel level, const char* fmt, ...) // //========================================================================== -static int D_InitGame(const FIWADInfo* iwad_info, TArray& allwads, TArray& pwads) +static int D_InitGame(const FIWADInfo* iwad_info, std::vector& allwads, std::vector& pwads) { SavegameFolder = iwad_info->Autoname; gameinfo.gametype = iwad_info->gametype; @@ -3167,7 +3167,11 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray& allwads, TArr FixMacHexen(fileSystem); FindStrifeTeaserVoices(fileSystem); }; - allwads.Append(std::move(pwads)); + allwads.insert( + allwads.end(), + std::make_move_iterator(pwads.begin()), + std::make_move_iterator(pwads.end()) + ); bool allowduplicates = Args->CheckParm("-allowduplicates"); auto hashfile = D_GetHashFile(); @@ -3175,8 +3179,8 @@ static int D_InitGame(const FIWADInfo* iwad_info, TArray& allwads, TArr { I_FatalError("FileSystem: no files found"); } - allwads.Clear(); - allwads.ShrinkToFit(); + allwads.clear(); + allwads.shrink_to_fit(); SetMapxxFlag(); D_GrabCVarDefaults(); //parse DEFCVARS @@ -3708,7 +3712,7 @@ static int D_DoomMain_Internal (void) // Load zdoom.pk3 alone so that we can get access to the internal gameinfos before // the IWAD is known. - TArray pwads; + std::vector pwads; GetCmdLineFiles(pwads); FString iwad = CheckGameInfo(pwads); @@ -3716,18 +3720,21 @@ static int D_DoomMain_Internal (void) // restart is initiated without a defined IWAD assume for now that it's not going to change. if (iwad.IsEmpty()) iwad = lastIWAD; - TArray allwads; + std::vector allwads; const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad, optionalwad); if (!iwad_info) return 0; // user exited the selection popup via cancel button. - if ((iwad_info->flags & GI_SHAREWARE) && pwads.Size() > 0) + if ((iwad_info->flags & GI_SHAREWARE) && pwads.size() > 0) { I_FatalError ("You cannot -file with the shareware version. Register!"); } lastIWAD = iwad; int ret = D_InitGame(iwad_info, allwads, pwads); - allwads.Reset(); + pwads.clear(); + pwads.shrink_to_fit(); + allwads.clear(); + allwads.shrink_to_fit(); delete iwad_man; // now we won't need this anymore iwad_man = NULL; if (ret != 0) return ret; diff --git a/src/d_main.h b/src/d_main.h index a6f76a8d8..6f6c37458 100644 --- a/src/d_main.h +++ b/src/d_main.h @@ -128,13 +128,13 @@ class FIWadManager void ParseIWadInfo(const char *fn, const char *data, int datasize, FIWADInfo *result = nullptr); int ScanIWAD (const char *iwad); int CheckIWADInfo(const char *iwad); - int IdentifyVersion (TArray &wadfiles, const char *iwad, const char *zdoom_wad, const char *optional_wad); + int IdentifyVersion (std::vector& wadfiles, const char *iwad, const char *zdoom_wad, const char *optional_wad); void CollectSearchPaths(); void AddIWADCandidates(const char *dir); void ValidateIWADs(); public: FIWadManager(const char *fn, const char *fnopt); - const FIWADInfo *FindIWAD(TArray &wadfiles, const char *iwad, const char *basewad, const char *optionalwad); + const FIWADInfo *FindIWAD(std::vector& wadfiles, const char *iwad, const char *basewad, const char *optionalwad); const FString *GetAutoname(unsigned int num) const { if (num < mIWadInfos.Size()) return &mIWadInfos[num].Autoname; From acd5911cd41cad8d9c578edc977bde35220d40a5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 Aug 2023 22:20:30 +0200 Subject: [PATCH 029/223] - StringPool class added This is a specialized stripped doen FMemArena. --- src/CMakeLists.txt | 1 + src/common/filesystem/fs_stringpool.cpp | 123 ++++++++++++++++++++++++ src/common/filesystem/fs_stringpool.h | 23 +++++ 3 files changed, 147 insertions(+) create mode 100644 src/common/filesystem/fs_stringpool.cpp create mode 100644 src/common/filesystem/fs_stringpool.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a35b048bf..681a92016 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1222,6 +1222,7 @@ set( ZDOOM_SOURCES common/filesystem/files.cpp common/filesystem/files_decompress.cpp common/filesystem/fs_findfile.cpp + common/filesystem/fs_stringpool.cpp ) diff --git a/src/common/filesystem/fs_stringpool.cpp b/src/common/filesystem/fs_stringpool.cpp new file mode 100644 index 000000000..4aa46a62f --- /dev/null +++ b/src/common/filesystem/fs_stringpool.cpp @@ -0,0 +1,123 @@ +/* +** stringpool.cpp +** allocate static strings from larger blocks +** +**--------------------------------------------------------------------------- +** Copyright 2010 Randy Heit +** Copyright 2023 Christoph Oelckers +** 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. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 "stringpool.h" + +struct StringPool::Block +{ + Block *NextBlock; + void *Limit; // End of this block + void *Avail; // Start of free space in this block + void *alignme; // align to 16 bytes. + + void *Alloc(size_t size); +}; + +//========================================================================== +// +// StringPool Destructor +// +//========================================================================== + +StringPool::~StringPool() +{ + for (Block *next, *block = top; block != nullptr; block = next) + { + next = block->NextBlock; + free(block); + } + top = nullptr; +} + +//========================================================================== +// +// StringPool :: Alloc +// +//========================================================================== + +void *StringPool::Block::Alloc(size_t size) +{ + if ((char *)Avail + size > Limit) + { + return nullptr; + } + void *res = Avail; + Avail = RoundPointer((char *)Avail + size); + return res; +} + +StringPool::Block *StringPool::AddBlock(size_t size) +{ + size += sizeof(Block); // Account for header size + + // Allocate a new block + if (size < BlockSize) + { + size = BlockSize; + } + auto mem = (Block *)malloc(size); + if (mem == nullptr) + { + + } + mem->Limit = (uint8_t *)mem + size; + mem->Avail = &mem[1]; + mem->NextBlock = TopBlock; + TopBlock = mem; + return mem; +} + +void *StringPool::iAlloc(size_t size) +{ + Block *block; + + for (block = TopBlock; block != nullptr; block = block->NextBlock) + { + void *res = block->Alloc(size); + if (res != nullptr) + { + return res; + } + } + block = AddBlock(size); + return block->Alloc(size); +} + +const char* StringPool::Strdup(const char* str) +{ + char* p = (char*)iAlloc((strlen(str) + 15) & ~15 ); + strcpy(p, str); + return p; +} diff --git a/src/common/filesystem/fs_stringpool.h b/src/common/filesystem/fs_stringpool.h new file mode 100644 index 000000000..ce1e7d83f --- /dev/null +++ b/src/common/filesystem/fs_stringpool.h @@ -0,0 +1,23 @@ +#pragma once + +// Storage for all the static strings the file system must hold. +class StringPool +{ +public: + StringPool(size_t blocksize = 10*1024) : TopBlock(nullptr), FreeBlocks(nullptr), BlockSize(blocksize) {} + ~StringPool(); + const char* Strdup(const char*); + +protected: + struct Block; + + Block *AddBlock(size_t size); + void *iAlloc(size_t size); + + Block *TopBlock; + Block *FreeBlocks; + size_t BlockSize; +public: + bool shared; +}; + From 3e3526f1ec761106acf773ef829dc4428cebb640 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 Aug 2023 22:32:15 +0200 Subject: [PATCH 030/223] - use a local hash function in the file system. --- src/common/filesystem/filesystem.cpp | 31 +- src/common/filesystem/fs_stringpool.cpp | 11 +- src/common/filesystem/md5.hpp | 416 ++++++++++++++++++++++++ src/common/filesystem/resourcefile.cpp | 13 +- src/common/filesystem/resourcefile.h | 1 + 5 files changed, 451 insertions(+), 21 deletions(-) create mode 100644 src/common/filesystem/md5.hpp diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index cea9cd99f..140c41b38 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -36,16 +36,16 @@ // HEADER FILES ------------------------------------------------------------ +#include #include #include #include #include "filesystem.h" #include "m_crc32.h" +#include "fs_findfile.h" -#if __has_include("md5.h") -#include "md5.h" -#endif +#include "md5.hpp" // MACROS ------------------------------------------------------------------ @@ -61,6 +61,21 @@ static void UpperCopy(char* to, const char* from) to[i] = 0; } +static void md5Hash(FileReader& reader, uint8_t* digest) +{ + using namespace fs_private::md5; + + md5_state_t state; + md5_init(&state); + md5_byte_t buffer[4096]; + while (auto len = reader.Read(buffer, 4096)) + { + md5_append(&state, buffer, len); + } + md5_finish(&state, digest); +} + + struct FileSystem::LumpRecord { FResourceLump *lump; @@ -388,7 +403,6 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf } } -#if __has_include("md5.h") if (hashfile) { uint8_t cksum[16]; @@ -397,10 +411,8 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf if (filereader.isOpen()) { - MD5Context md5; filereader.Seek(0, FileReader::SeekSet); - md5Update(filereader, md5, (unsigned)filereader.GetLength()); - md5.Final(cksum); + md5Hash(filereader, cksum); for (size_t j = 0; j < sizeof(cksum); ++j) { @@ -419,10 +431,8 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf if (!(lump->Flags & LUMPF_EMBEDDED)) { - MD5Context md5; auto reader = lump->NewReader(); - md5Update(reader, md5, lump->LumpSize); - md5.Final(cksum); + md5Hash(filereader, cksum); for (size_t j = 0; j < sizeof(cksum); ++j) { @@ -433,7 +443,6 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf } } } -#endif return; } } diff --git a/src/common/filesystem/fs_stringpool.cpp b/src/common/filesystem/fs_stringpool.cpp index 4aa46a62f..b828d398f 100644 --- a/src/common/filesystem/fs_stringpool.cpp +++ b/src/common/filesystem/fs_stringpool.cpp @@ -33,7 +33,10 @@ ** */ -#include "stringpool.h" +#include +#include +#include +#include "fs_stringpool.h" struct StringPool::Block { @@ -53,12 +56,12 @@ struct StringPool::Block StringPool::~StringPool() { - for (Block *next, *block = top; block != nullptr; block = next) + for (Block *next, *block = TopBlock; block != nullptr; block = next) { next = block->NextBlock; free(block); } - top = nullptr; + TopBlock = nullptr; } //========================================================================== @@ -74,7 +77,7 @@ void *StringPool::Block::Alloc(size_t size) return nullptr; } void *res = Avail; - Avail = RoundPointer((char *)Avail + size); + Avail = ((char *)Avail + size); return res; } diff --git a/src/common/filesystem/md5.hpp b/src/common/filesystem/md5.hpp new file mode 100644 index 000000000..2027023ca --- /dev/null +++ b/src/common/filesystem/md5.hpp @@ -0,0 +1,416 @@ +#pragma once +/* + md5.hpp is a reformulation of the md5.h and md5.c code from + http://www.opensource.apple.com/source/cups/cups-59/cups/md5.c to allow it to + function as a component of a header only library. This conversion was done by + Peter Thorson (webmaster@zaphoyd.com) in 2012 for the WebSocket++ project. The + changes are released under the same license as the original (listed below) +*/ +/* + Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. + + 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. + + L. Peter Deutsch + ghost@aladdin.com + + */ + /* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ + /* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321, whose + text is available at + http://www.ietf.org/rfc/rfc1321.txt + The code is derived from the text of the RFC, including the test suite + (section A.5) but excluding the rest of Appendix A. It does not include + any code or documentation that is identified in the RFC as being + copyrighted. + + The original and principal author of md5.h is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 2002-04-13 lpd Removed support for non-ANSI compilers; removed + references to Ghostscript; clarified derivation from RFC 1321; + now handles byte order either statically or dynamically. + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); + added conditionalization for C++ compilation from Martin + Purschke . + 1999-05-03 lpd Original version. + */ + + + /* + * This package supports both compile-time and run-time determination of CPU + * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be + * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is + * defined as non-zero, the code will be compiled to run only on big-endian + * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to + * run on either big- or little-endian CPUs, but will run slightly less + * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined. + */ + +#include +#include + +namespace fs_private { + /// Provides MD5 hashing functionality + namespace md5 { + + typedef unsigned char md5_byte_t; /* 8-bit byte */ + typedef unsigned int md5_word_t; /* 32-bit word */ + + /* Define the state of the MD5 Algorithm. */ + typedef struct md5_state_s { + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ + } md5_state_t; + + /* Initialize the algorithm. */ + inline void md5_init(md5_state_t* pms); + + /* Append a string to the message. */ + inline void md5_append(md5_state_t* pms, md5_byte_t const* data, size_t nbytes); + + /* Finish the message and return the digest. */ + inline void md5_finish(md5_state_t* pms, md5_byte_t digest[16]); + +#undef ZSW_MD5_BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ +#ifdef ARCH_IS_BIG_ENDIAN +# define ZSW_MD5_BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1) +#else +# define ZSW_MD5_BYTE_ORDER 0 +#endif + +#define ZSW_MD5_T_MASK ((md5_word_t)~0) +#define ZSW_MD5_T1 /* 0xd76aa478 */ (ZSW_MD5_T_MASK ^ 0x28955b87) +#define ZSW_MD5_T2 /* 0xe8c7b756 */ (ZSW_MD5_T_MASK ^ 0x173848a9) +#define ZSW_MD5_T3 0x242070db +#define ZSW_MD5_T4 /* 0xc1bdceee */ (ZSW_MD5_T_MASK ^ 0x3e423111) +#define ZSW_MD5_T5 /* 0xf57c0faf */ (ZSW_MD5_T_MASK ^ 0x0a83f050) +#define ZSW_MD5_T6 0x4787c62a +#define ZSW_MD5_T7 /* 0xa8304613 */ (ZSW_MD5_T_MASK ^ 0x57cfb9ec) +#define ZSW_MD5_T8 /* 0xfd469501 */ (ZSW_MD5_T_MASK ^ 0x02b96afe) +#define ZSW_MD5_T9 0x698098d8 +#define ZSW_MD5_T10 /* 0x8b44f7af */ (ZSW_MD5_T_MASK ^ 0x74bb0850) +#define ZSW_MD5_T11 /* 0xffff5bb1 */ (ZSW_MD5_T_MASK ^ 0x0000a44e) +#define ZSW_MD5_T12 /* 0x895cd7be */ (ZSW_MD5_T_MASK ^ 0x76a32841) +#define ZSW_MD5_T13 0x6b901122 +#define ZSW_MD5_T14 /* 0xfd987193 */ (ZSW_MD5_T_MASK ^ 0x02678e6c) +#define ZSW_MD5_T15 /* 0xa679438e */ (ZSW_MD5_T_MASK ^ 0x5986bc71) +#define ZSW_MD5_T16 0x49b40821 +#define ZSW_MD5_T17 /* 0xf61e2562 */ (ZSW_MD5_T_MASK ^ 0x09e1da9d) +#define ZSW_MD5_T18 /* 0xc040b340 */ (ZSW_MD5_T_MASK ^ 0x3fbf4cbf) +#define ZSW_MD5_T19 0x265e5a51 +#define ZSW_MD5_T20 /* 0xe9b6c7aa */ (ZSW_MD5_T_MASK ^ 0x16493855) +#define ZSW_MD5_T21 /* 0xd62f105d */ (ZSW_MD5_T_MASK ^ 0x29d0efa2) +#define ZSW_MD5_T22 0x02441453 +#define ZSW_MD5_T23 /* 0xd8a1e681 */ (ZSW_MD5_T_MASK ^ 0x275e197e) +#define ZSW_MD5_T24 /* 0xe7d3fbc8 */ (ZSW_MD5_T_MASK ^ 0x182c0437) +#define ZSW_MD5_T25 0x21e1cde6 +#define ZSW_MD5_T26 /* 0xc33707d6 */ (ZSW_MD5_T_MASK ^ 0x3cc8f829) +#define ZSW_MD5_T27 /* 0xf4d50d87 */ (ZSW_MD5_T_MASK ^ 0x0b2af278) +#define ZSW_MD5_T28 0x455a14ed +#define ZSW_MD5_T29 /* 0xa9e3e905 */ (ZSW_MD5_T_MASK ^ 0x561c16fa) +#define ZSW_MD5_T30 /* 0xfcefa3f8 */ (ZSW_MD5_T_MASK ^ 0x03105c07) +#define ZSW_MD5_T31 0x676f02d9 +#define ZSW_MD5_T32 /* 0x8d2a4c8a */ (ZSW_MD5_T_MASK ^ 0x72d5b375) +#define ZSW_MD5_T33 /* 0xfffa3942 */ (ZSW_MD5_T_MASK ^ 0x0005c6bd) +#define ZSW_MD5_T34 /* 0x8771f681 */ (ZSW_MD5_T_MASK ^ 0x788e097e) +#define ZSW_MD5_T35 0x6d9d6122 +#define ZSW_MD5_T36 /* 0xfde5380c */ (ZSW_MD5_T_MASK ^ 0x021ac7f3) +#define ZSW_MD5_T37 /* 0xa4beea44 */ (ZSW_MD5_T_MASK ^ 0x5b4115bb) +#define ZSW_MD5_T38 0x4bdecfa9 +#define ZSW_MD5_T39 /* 0xf6bb4b60 */ (ZSW_MD5_T_MASK ^ 0x0944b49f) +#define ZSW_MD5_T40 /* 0xbebfbc70 */ (ZSW_MD5_T_MASK ^ 0x4140438f) +#define ZSW_MD5_T41 0x289b7ec6 +#define ZSW_MD5_T42 /* 0xeaa127fa */ (ZSW_MD5_T_MASK ^ 0x155ed805) +#define ZSW_MD5_T43 /* 0xd4ef3085 */ (ZSW_MD5_T_MASK ^ 0x2b10cf7a) +#define ZSW_MD5_T44 0x04881d05 +#define ZSW_MD5_T45 /* 0xd9d4d039 */ (ZSW_MD5_T_MASK ^ 0x262b2fc6) +#define ZSW_MD5_T46 /* 0xe6db99e5 */ (ZSW_MD5_T_MASK ^ 0x1924661a) +#define ZSW_MD5_T47 0x1fa27cf8 +#define ZSW_MD5_T48 /* 0xc4ac5665 */ (ZSW_MD5_T_MASK ^ 0x3b53a99a) +#define ZSW_MD5_T49 /* 0xf4292244 */ (ZSW_MD5_T_MASK ^ 0x0bd6ddbb) +#define ZSW_MD5_T50 0x432aff97 +#define ZSW_MD5_T51 /* 0xab9423a7 */ (ZSW_MD5_T_MASK ^ 0x546bdc58) +#define ZSW_MD5_T52 /* 0xfc93a039 */ (ZSW_MD5_T_MASK ^ 0x036c5fc6) +#define ZSW_MD5_T53 0x655b59c3 +#define ZSW_MD5_T54 /* 0x8f0ccc92 */ (ZSW_MD5_T_MASK ^ 0x70f3336d) +#define ZSW_MD5_T55 /* 0xffeff47d */ (ZSW_MD5_T_MASK ^ 0x00100b82) +#define ZSW_MD5_T56 /* 0x85845dd1 */ (ZSW_MD5_T_MASK ^ 0x7a7ba22e) +#define ZSW_MD5_T57 0x6fa87e4f +#define ZSW_MD5_T58 /* 0xfe2ce6e0 */ (ZSW_MD5_T_MASK ^ 0x01d3191f) +#define ZSW_MD5_T59 /* 0xa3014314 */ (ZSW_MD5_T_MASK ^ 0x5cfebceb) +#define ZSW_MD5_T60 0x4e0811a1 +#define ZSW_MD5_T61 /* 0xf7537e82 */ (ZSW_MD5_T_MASK ^ 0x08ac817d) +#define ZSW_MD5_T62 /* 0xbd3af235 */ (ZSW_MD5_T_MASK ^ 0x42c50dca) +#define ZSW_MD5_T63 0x2ad7d2bb +#define ZSW_MD5_T64 /* 0xeb86d391 */ (ZSW_MD5_T_MASK ^ 0x14792c6e) + + static void md5_process(md5_state_t* pms, md5_byte_t const* data /*[64]*/) { + md5_word_t + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + md5_word_t t; +#if ZSW_MD5_BYTE_ORDER > 0 + /* Define storage only for big-endian CPUs. */ + md5_word_t X[16]; +#else + /* Define storage for little-endian or both types of CPUs. */ + md5_word_t xbuf[16]; + md5_word_t const* X; +#endif + + { +#if ZSW_MD5_BYTE_ORDER == 0 + /* + * Determine dynamically whether this is a big-endian or + * little-endian machine, since we can use a more efficient + * algorithm on the latter. + */ + static int const w = 1; + + if (*((md5_byte_t const*)&w)) /* dynamic little-endian */ +#endif +#if ZSW_MD5_BYTE_ORDER <= 0 /* little-endian */ + { + /* + * On little-endian machines, we can process properly aligned + * data without copying it. + */ + if (!((data - (md5_byte_t const*)0) & 3)) { + /* data are properly aligned */ + X = (md5_word_t const*)data; + } + else { + /* not aligned */ + std::memcpy(xbuf, data, 64); + X = xbuf; + } + } +#endif +#if ZSW_MD5_BYTE_ORDER == 0 + else /* dynamic big-endian */ +#endif +#if ZSW_MD5_BYTE_ORDER >= 0 /* big-endian */ + { + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const md5_byte_t* xp = data; + int i; + +# if ZSW_MD5_BYTE_ORDER == 0 + X = xbuf; /* (dynamic only) */ +# else +# define xbuf X /* (static only) */ +# endif + for (i = 0; i < 16; ++i, xp += 4) + xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + } +#endif + } + +#define ZSW_MD5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ +#define ZSW_MD5_F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + ZSW_MD5_F(b,c,d) + X[k] + Ti;\ + a = ZSW_MD5_ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 7, ZSW_MD5_T1); + SET(d, a, b, c, 1, 12, ZSW_MD5_T2); + SET(c, d, a, b, 2, 17, ZSW_MD5_T3); + SET(b, c, d, a, 3, 22, ZSW_MD5_T4); + SET(a, b, c, d, 4, 7, ZSW_MD5_T5); + SET(d, a, b, c, 5, 12, ZSW_MD5_T6); + SET(c, d, a, b, 6, 17, ZSW_MD5_T7); + SET(b, c, d, a, 7, 22, ZSW_MD5_T8); + SET(a, b, c, d, 8, 7, ZSW_MD5_T9); + SET(d, a, b, c, 9, 12, ZSW_MD5_T10); + SET(c, d, a, b, 10, 17, ZSW_MD5_T11); + SET(b, c, d, a, 11, 22, ZSW_MD5_T12); + SET(a, b, c, d, 12, 7, ZSW_MD5_T13); + SET(d, a, b, c, 13, 12, ZSW_MD5_T14); + SET(c, d, a, b, 14, 17, ZSW_MD5_T15); + SET(b, c, d, a, 15, 22, ZSW_MD5_T16); +#undef SET + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ +#define ZSW_MD5_G(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + ZSW_MD5_G(b,c,d) + X[k] + Ti;\ + a = ZSW_MD5_ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 1, 5, ZSW_MD5_T17); + SET(d, a, b, c, 6, 9, ZSW_MD5_T18); + SET(c, d, a, b, 11, 14, ZSW_MD5_T19); + SET(b, c, d, a, 0, 20, ZSW_MD5_T20); + SET(a, b, c, d, 5, 5, ZSW_MD5_T21); + SET(d, a, b, c, 10, 9, ZSW_MD5_T22); + SET(c, d, a, b, 15, 14, ZSW_MD5_T23); + SET(b, c, d, a, 4, 20, ZSW_MD5_T24); + SET(a, b, c, d, 9, 5, ZSW_MD5_T25); + SET(d, a, b, c, 14, 9, ZSW_MD5_T26); + SET(c, d, a, b, 3, 14, ZSW_MD5_T27); + SET(b, c, d, a, 8, 20, ZSW_MD5_T28); + SET(a, b, c, d, 13, 5, ZSW_MD5_T29); + SET(d, a, b, c, 2, 9, ZSW_MD5_T30); + SET(c, d, a, b, 7, 14, ZSW_MD5_T31); + SET(b, c, d, a, 12, 20, ZSW_MD5_T32); +#undef SET + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ +#define ZSW_MD5_H(x, y, z) ((x) ^ (y) ^ (z)) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + ZSW_MD5_H(b,c,d) + X[k] + Ti;\ + a = ZSW_MD5_ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 5, 4, ZSW_MD5_T33); + SET(d, a, b, c, 8, 11, ZSW_MD5_T34); + SET(c, d, a, b, 11, 16, ZSW_MD5_T35); + SET(b, c, d, a, 14, 23, ZSW_MD5_T36); + SET(a, b, c, d, 1, 4, ZSW_MD5_T37); + SET(d, a, b, c, 4, 11, ZSW_MD5_T38); + SET(c, d, a, b, 7, 16, ZSW_MD5_T39); + SET(b, c, d, a, 10, 23, ZSW_MD5_T40); + SET(a, b, c, d, 13, 4, ZSW_MD5_T41); + SET(d, a, b, c, 0, 11, ZSW_MD5_T42); + SET(c, d, a, b, 3, 16, ZSW_MD5_T43); + SET(b, c, d, a, 6, 23, ZSW_MD5_T44); + SET(a, b, c, d, 9, 4, ZSW_MD5_T45); + SET(d, a, b, c, 12, 11, ZSW_MD5_T46); + SET(c, d, a, b, 15, 16, ZSW_MD5_T47); + SET(b, c, d, a, 2, 23, ZSW_MD5_T48); +#undef SET + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ +#define ZSW_MD5_I(x, y, z) ((y) ^ ((x) | ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + ZSW_MD5_I(b,c,d) + X[k] + Ti;\ + a = ZSW_MD5_ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 6, ZSW_MD5_T49); + SET(d, a, b, c, 7, 10, ZSW_MD5_T50); + SET(c, d, a, b, 14, 15, ZSW_MD5_T51); + SET(b, c, d, a, 5, 21, ZSW_MD5_T52); + SET(a, b, c, d, 12, 6, ZSW_MD5_T53); + SET(d, a, b, c, 3, 10, ZSW_MD5_T54); + SET(c, d, a, b, 10, 15, ZSW_MD5_T55); + SET(b, c, d, a, 1, 21, ZSW_MD5_T56); + SET(a, b, c, d, 8, 6, ZSW_MD5_T57); + SET(d, a, b, c, 15, 10, ZSW_MD5_T58); + SET(c, d, a, b, 6, 15, ZSW_MD5_T59); + SET(b, c, d, a, 13, 21, ZSW_MD5_T60); + SET(a, b, c, d, 4, 6, ZSW_MD5_T61); + SET(d, a, b, c, 11, 10, ZSW_MD5_T62); + SET(c, d, a, b, 2, 15, ZSW_MD5_T63); + SET(b, c, d, a, 9, 21, ZSW_MD5_T64); +#undef SET + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + pms->abcd[0] += a; + pms->abcd[1] += b; + pms->abcd[2] += c; + pms->abcd[3] += d; + } + + void md5_init(md5_state_t* pms) { + pms->count[0] = pms->count[1] = 0; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = /*0xefcdab89*/ ZSW_MD5_T_MASK ^ 0x10325476; + pms->abcd[2] = /*0x98badcfe*/ ZSW_MD5_T_MASK ^ 0x67452301; + pms->abcd[3] = 0x10325476; + } + + void md5_append(md5_state_t* pms, md5_byte_t const* data, size_t nbytes) { + md5_byte_t const* p = data; + size_t left = nbytes; + int offset = (pms->count[0] >> 3) & 63; + md5_word_t nbits = (md5_word_t)(nbytes << 3); + + if (nbytes <= 0) + return; + + /* Update the message length. */ + pms->count[1] += (md5_word_t)(nbytes >> 29); + pms->count[0] += nbits; + if (pms->count[0] < nbits) + pms->count[1]++; + + /* Process an initial partial block. */ + if (offset) { + int copy = (offset + nbytes > 64 ? 64 - offset : static_cast(nbytes)); + + std::memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + std::memcpy(pms->buf, p, left); + } + + void md5_finish(md5_state_t* pms, md5_byte_t digest[16]) { + static md5_byte_t const pad[64] = { + 0x80, 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 + }; + md5_byte_t data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + md5_append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); + } + + + } // md5 +} // fs_private + diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index a900c275c..718069c51 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -36,8 +36,7 @@ #include #include "resourcefile.h" - -#include "md5.h" +#include "md5.hpp" std::string ExtractBaseName(const char* path, bool include_extension) { @@ -358,19 +357,21 @@ int lumpcmp(const void * a, const void * b) void FResourceFile::GenerateHash() { // hash the lump directory after sorting + using namespace fs_private::md5; auto n = snprintf(Hash, 48, "%08X-%04X-", (unsigned)Reader.GetLength(), NumLumps); - MD5Context md5; + md5_state_t state; + md5_init(&state); uint8_t digest[16]; for(uint32_t i = 0; i < NumLumps; i++) { auto lump = GetLump(i); - md5.Update((const uint8_t*)lump->FullName.c_str(), (unsigned)lump->FullName.length() + 1); - md5.Update((const uint8_t*)&lump->LumpSize, 4); + md5_append(&state, (const uint8_t*)lump->FullName.c_str(), (unsigned)lump->FullName.length() + 1); + md5_append(&state, (const uint8_t*)&lump->LumpSize, 4); } - md5.Final(digest); + md5_finish(&state, digest); for (auto c : digest) { n += snprintf(Hash + n, 3, "%02X", c); diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index c40e1c598..2345f332f 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -8,6 +8,7 @@ #include #include "files.h" +class StringPool; std::string ExtractBaseName(const char* path, bool include_extension = false); void strReplace(std::string& str, const char* from, const char* to); From 5433430767ef46df3e8d039c8561c872c579ab18 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 Aug 2023 22:36:25 +0200 Subject: [PATCH 031/223] - FString is always gone. --- src/common/filesystem/filesystem.cpp | 33 +++++++++++++----------- src/common/filesystem/fs_findfile.cpp | 36 ++++++++++++++++++++------- src/common/filesystem/fs_findfile.h | 1 + 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 140c41b38..6032a4ccb 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -311,9 +311,11 @@ int FileSystem::AddExternalFile(const char *filename) int FileSystem::AddFromBuffer(const char* name, const char* type, char* data, int size, int id, int flags) { - FStringf fullname("%s.%s", name, type); + std::string fullname = name; + fullname += ':'; + fullname += type; auto newlump = new FMemoryLump(data, size); - newlump->LumpNameSetup(fullname); + newlump->LumpNameSetup(fullname.c_str()); AddLump(newlump); FileInfo.back().resourceId = id; return (int)FileInfo.size()-1; @@ -338,7 +340,7 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf if (filer == nullptr) { // Does this exist? If so, is it a directory? - if (!DirEntryExists(filename, &isdir)) + if (!FS_DirEntryExists(filename, &isdir)) { if (Printf) { @@ -396,10 +398,11 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf FResourceLump *lump = resfile->GetLump(i); if (lump->Flags & LUMPF_EMBEDDED) { - FString path; - path.Format("%s:%s", filename, lump->getName()); + std::string path = filename; + path += ':'; + path += lump->getName(); auto embedded = lump->NewReader(); - AddFile(path, &embedded, filter, Printf, hashfile); + AddFile(path.c_str(), &embedded, filter, Printf, hashfile); } } @@ -476,8 +479,8 @@ int FileSystem::CheckIfResourceFileLoaded (const char *name) noexcept { for (i = 0; i < Files.Size(); ++i) { - auto pth = ExtractFileBase(GetResourceFileName(i), true); - if (stricmp (pth.GetChars(), name) == 0) + auto pth = ExtractBaseName(GetResourceFileName(i), true); + if (stricmp (pth.c_str(), name) == 0) { return i; } @@ -1255,10 +1258,10 @@ static int folderentrycmp(const void *a, const void *b) unsigned FileSystem::GetFilesInFolder(const char *inpath, TArray &result, bool atomic) const { - FString path = inpath; - FixPathSeperator(path); - path.ToLower(); - if (path[path.Len() - 1] != '/') path += '/'; + std::string path = inpath; + FixPathSeparator(&path.front()); + for (auto& c : path) c = tolower(c); + if (path.back() != '/') path += '/'; result.Clear(); for (size_t i = 0; i < FileInfo.size(); i++) { @@ -1507,11 +1510,11 @@ const char *FileSystem::GetResourceFileFullName (int rfnum) const noexcept bool FileSystem::CreatePathlessCopy(const char *name, int id, int /*flags*/) { - FString name2=name, type2, path; + std::string name2 = name, type2, path; // The old code said 'filename' and ignored the path, this looked like a bug. - FixPathSeperator(name2); - auto lump = FindFile(name2); + FixPathSeparator(&name2.front()); + auto lump = FindFile(name2.c_str()); if (lump < 0) return false; // Does not exist. auto oldlump = FileInfo[lump]; diff --git a/src/common/filesystem/fs_findfile.cpp b/src/common/filesystem/fs_findfile.cpp index 021494644..9dde8fdcb 100644 --- a/src/common/filesystem/fs_findfile.cpp +++ b/src/common/filesystem/fs_findfile.cpp @@ -157,15 +157,6 @@ static int FS_FindClose(void *const handle) return 0; } -static bool DirEntryExists(const char* pathname, bool* isdir) -{ - if (isdir) *isdir = false; - struct stat info; - bool res = stat(pathname, &info) == 0; - if (isdir) *isdir = !!(info.st_mode & S_IFDIR); - return res; -} - static int FS_FindAttr(findstate_t *const fileinfo) { dirent *const ent = fileinfo->namelist[fileinfo->current]; @@ -386,3 +377,30 @@ bool ScanDirectory(std::vector& list, const char* dirpath, const return DoScanDirectory(list, dirpath, match, "", nosubdir, readhidden); } +//========================================================================== +// +// DirEntryExists +// +// Returns true if the given path exists, be it a directory or a file. +// +//========================================================================== + +bool FS_DirEntryExists(const char* pathname, bool* isdir) +{ + if (isdir) *isdir = false; + if (pathname == NULL || *pathname == 0) + return false; + +#ifndef _WIN32 + struct stat info; + bool res = stat(pathname, &info) == 0; +#else + // Windows must use the wide version of stat to preserve non-standard paths. + auto wstr = toWide(pathname); + struct _stat64 info; + bool res = _wstat64(wstr.c_str(), &info) == 0; +#endif + if (isdir) *isdir = !!(info.st_mode & S_IFDIR); + return res; +} + diff --git a/src/common/filesystem/fs_findfile.h b/src/common/filesystem/fs_findfile.h index 85d328d43..7b6d3e3d2 100644 --- a/src/common/filesystem/fs_findfile.h +++ b/src/common/filesystem/fs_findfile.h @@ -22,6 +22,7 @@ using FileList = std::vector; struct FCompressedBuffer; bool ScanDirectory(std::vector& list, const char* dirpath, const char* match, bool nosubdir = false, bool readhidden = false); bool WriteZip(const char* filename, const FCompressedBuffer* content, size_t contentcount); +bool FS_DirEntryExists(const char* pathname, bool* isdir); inline void FixPathSeparator(char* path) { From 2a6fb6da84e73abf3a16bf13fde50c497b83ea96 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 21 Aug 2023 23:29:07 +0200 Subject: [PATCH 032/223] - use better hash function. This is djb2 which is supposedly one of the best string hashing functions around. Avoids annoying dependencies and is a lot simpler and faster than the alternatives. --- src/common/filesystem/filesystem.cpp | 51 ++++++++++------------------ 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 6032a4ccb..237ac4c88 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -61,6 +61,16 @@ static void UpperCopy(char* to, const char* from) to[i] = 0; } + +//djb2 +static uint32_t MakeHash(const char* str, size_t length = SIZE_MAX) +{ + uint32_t hash = 5381; + uint32_t c; + while (length-- > 0 && (c = *str++)) hash = hash * 33 + (c | 32); + return hash; +} + static void md5Hash(FileReader& reader, uint8_t* digest) { using namespace fs_private::md5; @@ -522,7 +532,7 @@ int FileSystem::CheckNumForName (const char *name, int space) } UpperCopy (uname, name); - i = FirstLumpIndex[LumpNameHash (uname) % NumEntries]; + i = FirstLumpIndex[MakeHash(uname, 8) % NumEntries]; while (i != NULL_INDEX) { @@ -560,7 +570,7 @@ int FileSystem::CheckNumForName (const char *name, int space, int rfnum, bool ex } UpperCopy (uname, name); - i = FirstLumpIndex[LumpNameHash (uname) % NumEntries]; + i = FirstLumpIndex[MakeHash (uname, 8) % NumEntries]; // If exact is true if will only find lumps in the same WAD, otherwise // also those in earlier WADs. @@ -619,7 +629,7 @@ int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int names uint32_t *nli = ignoreext ? NextLumpIndex_NoExt : NextLumpIndex_FullName; auto len = strlen(name); - for (i = fli[MakeKey(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) + for (i = fli[MakeHash(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) { if (strnicmp(name, FileInfo[i].longName.c_str(), len)) continue; if (FileInfo[i].longName[len] == 0) break; // this is a full match @@ -648,7 +658,7 @@ int FileSystem::CheckNumForFullName (const char *name, int rfnum) return CheckNumForFullName (name); } - i = FirstLumpIndex_FullName[MakeKey (name) % NumEntries]; + i = FirstLumpIndex_FullName[MakeHash (name) % NumEntries]; while (i != NULL_INDEX && (stricmp(name, FileInfo[i].longName.c_str()) || FileInfo[i].rfnum != rfnum)) @@ -700,7 +710,7 @@ int FileSystem::FindFileWithExtensions(const char* name, const char *const *exts uint32_t* nli = NextLumpIndex_NoExt; auto len = strlen(name); - for (i = fli[MakeKey(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) + for (i = fli[MakeHash(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) { if (strnicmp(name, FileInfo[i].longName.c_str(), len)) continue; if (FileInfo[i].longName[len] != '.') continue; // we are looking for extensions but this file doesn't have one. @@ -820,31 +830,6 @@ int FileSystem::GetFileFlags (int lump) return FileInfo[lump].lump->Flags ^ FileInfo[lump].flags; } -//========================================================================== -// -// LumpNameHash -// -// NOTE: s should already be uppercase, in contrast to the BOOM version. -// -// Hash function used for lump names. -// Must be mod'ed with table size. -// Can be used for any 8-character names. -// -//========================================================================== - -uint32_t FileSystem::LumpNameHash (const char *s) -{ - const uint32_t *table = GetCRCTable (); - uint32_t hash = 0xffffffff; - int i; - - for (i = 8; i > 0 && *s; --i, ++s) - { - hash = CRC1 (hash, *s, table); - } - return hash ^ 0xffffffff; -} - //========================================================================== // // InitHashChains @@ -875,14 +860,14 @@ void FileSystem::InitHashChains (void) // Now set up the chains for (i = 0; i < (unsigned)NumEntries; i++) { - j = LumpNameHash (FileInfo[i].shortName.String) % NumEntries; + j = MakeHash (FileInfo[i].shortName.String, 8) % NumEntries; NextLumpIndex[i] = FirstLumpIndex[j]; FirstLumpIndex[j] = i; // Do the same for the full paths if (!FileInfo[i].longName.empty()) { - j = MakeKey(FileInfo[i].longName.c_str()) % NumEntries; + j = MakeHash(FileInfo[i].longName.c_str()) % NumEntries; NextLumpIndex_FullName[i] = FirstLumpIndex_FullName[j]; FirstLumpIndex_FullName[j] = i; @@ -891,7 +876,7 @@ void FileSystem::InitHashChains (void) auto slash = nameNoExt.find_last_of('/'); if ((dot > slash || slash == std::string::npos) && dot != std::string::npos) nameNoExt.resize(dot); - j = MakeKey(nameNoExt.c_str()) % NumEntries; + j = MakeHash(nameNoExt.c_str()) % NumEntries; NextLumpIndex_NoExt[i] = FirstLumpIndex_NoExt[j]; FirstLumpIndex_NoExt[j] = i; From 535eb9a8535220bda4e0a1321e311fe22795f216 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 20 Aug 2023 00:56:56 +0200 Subject: [PATCH 033/223] - use std::vector in GetFilesInFolder --- src/common/filesystem/filesystem.cpp | 16 ++++++++-------- src/common/filesystem/filesystem.h | 2 +- src/common/fonts/font.cpp | 15 ++++++++------- src/common/fonts/v_font.cpp | 4 ++-- src/common/fonts/v_font.h | 2 +- src/common/textures/texturemanager.cpp | 2 +- 6 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 237ac4c88..c1f3144b1 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -1241,13 +1241,13 @@ static int folderentrycmp(const void *a, const void *b) // //========================================================================== -unsigned FileSystem::GetFilesInFolder(const char *inpath, TArray &result, bool atomic) const +unsigned FileSystem::GetFilesInFolder(const char *inpath, std::vector &result, bool atomic) const { std::string path = inpath; FixPathSeparator(&path.front()); for (auto& c : path) c = tolower(c); if (path.back() != '/') path += '/'; - result.Clear(); + result.clear(); for (size_t i = 0; i < FileInfo.size(); i++) { if (FileInfo[i].longName.find(path) == 0) @@ -1256,11 +1256,11 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, TArray &r if ((unsigned)fileSystem.CheckNumForFullName(FileInfo[i].longName.c_str()) == i) { FolderEntry fe{ FileInfo[i].longName.c_str(), (uint32_t)i }; - result.Push(fe); + result.push_back(fe); } } } - if (result.Size()) + if (result.size()) { int maxfile = -1; if (atomic) @@ -1272,14 +1272,14 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, TArray &r if (thisfile > maxfile) maxfile = thisfile; } // Delete everything from older files. - for (int i = result.Size() - 1; i >= 0; i--) + for (int i = (int)result.size() - 1; i >= 0; i--) { - if (fileSystem.GetFileContainer(result[i].lumpnum) != maxfile) result.Delete(i); + if (fileSystem.GetFileContainer(result[i].lumpnum) != maxfile) result.erase(result.begin() + i); } } - qsort(result.Data(), result.Size(), sizeof(FolderEntry), folderentrycmp); + qsort(result.data(), result.size(), sizeof(FolderEntry), folderentrycmp); } - return result.Size(); + return (unsigned)result.size(); } //========================================================================== diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index cb4695280..6470a20bf 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -144,7 +144,7 @@ public: int GetResourceId(int lump) const; // Returns the RFF index number for this lump const char* GetResourceType(int lump) const; bool CheckFileName (int lump, const char *name) const; // [RH] Returns true if the names match - unsigned GetFilesInFolder(const char *path, TArray &result, bool atomic) const; + unsigned GetFilesInFolder(const char *path, std::vector &result, bool atomic) const; int GetNumEntries() const { diff --git a/src/common/fonts/font.cpp b/src/common/fonts/font.cpp index 3876dd7ea..063f31077 100644 --- a/src/common/fonts/font.cpp +++ b/src/common/fonts/font.cpp @@ -91,7 +91,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla // Read the font's configuration. // This will not be done for the default fonts, because they are not atomic and the default content does not need it. - TArray folderdata; + std::vector folderdata; if (filetemplate != nullptr) { FStringf path("fonts/%s/", filetemplate); @@ -103,12 +103,13 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla { FStringf infpath("fonts/%s/font.inf", filetemplate); - unsigned index = folderdata.FindEx([=](const FolderEntry &entry) + size_t index; + for(index = 0; index < folderdata.size(); index++) { - return infpath.CompareNoCase(entry.name) == 0; - }); + if (infpath.CompareNoCase(folderdata[i].name) == 0) break; + } - if (index < folderdata.Size()) + if (index < folderdata.size()) { FScanner sc; sc.OpenLumpNum(folderdata[index].lumpnum); @@ -288,7 +289,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla } } } - if (folderdata.Size() > 0) + if (folderdata.size() > 0) { // all valid lumps must be named with a hex number that represents its Unicode character index. for (auto &entry : folderdata) @@ -397,7 +398,7 @@ public: } }; -void FFont::ReadSheetFont(TArray &folderdata, int width, int height, const DVector2 &Scale) +void FFont::ReadSheetFont(std::vector &folderdata, int width, int height, const DVector2 &Scale) { TMap charMap; int minchar = INT_MAX; diff --git a/src/common/fonts/v_font.cpp b/src/common/fonts/v_font.cpp index cb206a4ec..f6e4ef0de 100644 --- a/src/common/fonts/v_font.cpp +++ b/src/common/fonts/v_font.cpp @@ -109,7 +109,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) int lump = -1; int folderfile = -1; - TArray folderdata; + std::vector folderdata; FStringf path("fonts/%s/", name); // Use a folder-based font only if it comes from a later file than the single lump version. @@ -149,7 +149,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) return font; } } - if (folderdata.Size() > 0) + if (folderdata.size() > 0) { font = new FFont(name, nullptr, name, 0, 0, 1, -1); if (translationsLoaded) font->LoadTranslations(); diff --git a/src/common/fonts/v_font.h b/src/common/fonts/v_font.h index 407ee0f5e..9fdab0228 100644 --- a/src/common/fonts/v_font.h +++ b/src/common/fonts/v_font.h @@ -175,7 +175,7 @@ protected: void FixXMoves(); - void ReadSheetFont(TArray &folderdata, int width, int height, const DVector2 &Scale); + void ReadSheetFont(std::vector &folderdata, int width, int height, const DVector2 &Scale); EFontType Type = EFontType::Unknown; FName AltFontName = NAME_None; diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index 444b3b4eb..969a5f201 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -1108,7 +1108,7 @@ void FTextureManager::SortTexturesByType(int start, int end) void FTextureManager::AddLocalizedVariants() { - TArray content; + std::vector content; fileSystem.GetFilesInFolder("localized/textures/", content, false); for (auto &entry : content) { From 79e6d068a93a806cd3a52afc2b9d0d47b7dfdad8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 20 Aug 2023 01:02:18 +0200 Subject: [PATCH 034/223] - got rid of the last two TArrays in the filesystem class. --- src/common/filesystem/filesystem.cpp | 36 +++++++++++++--------------- src/common/filesystem/filesystem.h | 7 +++--- src/common/fonts/font.cpp | 2 +- 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index c1f3144b1..6c67b9f45 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -42,9 +42,7 @@ #include #include "filesystem.h" -#include "m_crc32.h" #include "fs_findfile.h" - #include "md5.hpp" // MACROS ------------------------------------------------------------------ @@ -203,7 +201,7 @@ FileSystem::~FileSystem () void FileSystem::DeleteAll () { - Hashes.Clear(); + Hashes.clear(); NumEntries = 0; // explicitly delete all manually added lumps. @@ -212,11 +210,11 @@ void FileSystem::DeleteAll () if (frec.rfnum == -1) delete frec.lump; } FileInfo.clear(); - for (int i = Files.Size() - 1; i >= 0; --i) + for (int i = (int)Files.size() - 1; i >= 0; --i) { delete Files[i]; } - Files.Clear(); + Files.clear(); } //========================================================================== @@ -266,7 +264,7 @@ bool FileSystem::InitMultipleFiles (std::vector& filenames, LumpFil if (i == (unsigned)MaxIwadIndex) MoveLumpsInFolder("after_iwad/"); std::string path = "filter/%s"; - path += Files.Last()->GetHash(); + path += Files.back()->GetHash(); MoveLumpsInFolder(path.c_str()); } @@ -398,10 +396,10 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf FResourceLump *lump = resfile->GetLump(i); FileInfo.resize(FileInfo.size() + 1); FileSystem::LumpRecord* lump_p = &FileInfo.back(); - lump_p->SetFromLump(Files.Size(), lump); + lump_p->SetFromLump((int)Files.size(), lump); } - Files.Push(resfile); + Files.push_back(resfile); for (uint32_t i=0; i < resfile->LumpCount(); i++) { @@ -477,7 +475,7 @@ int FileSystem::CheckIfResourceFileLoaded (const char *name) noexcept if (strrchr (name, '/') != NULL) { - for (i = 0; i < Files.Size(); ++i) + for (i = 0; i < (unsigned)Files.size(); ++i) { if (stricmp (GetResourceFileFullName (i), name) == 0) { @@ -487,7 +485,7 @@ int FileSystem::CheckIfResourceFileLoaded (const char *name) noexcept } else { - for (i = 0; i < Files.Size(); ++i) + for (i = 0; i < (unsigned)Files.size(); ++i) { auto pth = ExtractBaseName(GetResourceFileName(i), true); if (stricmp (pth.c_str(), name) == 0) @@ -844,9 +842,9 @@ void FileSystem::InitHashChains (void) unsigned int i, j; NumEntries = (uint32_t)FileInfo.size(); - Hashes.Resize(8 * NumEntries); + Hashes.resize(8 * NumEntries); // Mark all buckets as empty - memset(Hashes.Data(), -1, Hashes.Size() * sizeof(Hashes[0])); + memset(Hashes.data(), -1, Hashes.size() * sizeof(Hashes[0])); FirstLumpIndex = &Hashes[0]; NextLumpIndex = &Hashes[NumEntries]; FirstLumpIndex_FullName = &Hashes[NumEntries * 2]; @@ -887,7 +885,7 @@ void FileSystem::InitHashChains (void) } } FileInfo.shrink_to_fit(); - Files.ShrinkToFit(); + Files.shrink_to_fit(); } //========================================================================== @@ -1392,7 +1390,7 @@ FileReader FileSystem::OpenFileReader(const char* name) FileReader *FileSystem::GetFileReader(int rfnum) { - if ((uint32_t)rfnum >= Files.Size()) + if ((uint32_t)rfnum >= Files.size()) { return NULL; } @@ -1412,7 +1410,7 @@ const char *FileSystem::GetResourceFileName (int rfnum) const noexcept { const char *name, *slash; - if ((uint32_t)rfnum >= Files.Size()) + if ((uint32_t)rfnum >= Files.size()) { return NULL; } @@ -1429,7 +1427,7 @@ const char *FileSystem::GetResourceFileName (int rfnum) const noexcept int FileSystem::GetFirstEntry (int rfnum) const noexcept { - if ((uint32_t)rfnum >= Files.Size()) + if ((uint32_t)rfnum >= Files.size()) { return 0; } @@ -1444,7 +1442,7 @@ int FileSystem::GetFirstEntry (int rfnum) const noexcept int FileSystem::GetLastEntry (int rfnum) const noexcept { - if ((uint32_t)rfnum >= Files.Size()) + if ((uint32_t)rfnum >= Files.size()) { return 0; } @@ -1459,7 +1457,7 @@ int FileSystem::GetLastEntry (int rfnum) const noexcept int FileSystem::GetEntryCount (int rfnum) const noexcept { - if ((uint32_t)rfnum >= Files.Size()) + if ((uint32_t)rfnum >= Files.size()) { return 0; } @@ -1478,7 +1476,7 @@ int FileSystem::GetEntryCount (int rfnum) const noexcept const char *FileSystem::GetResourceFileFullName (int rfnum) const noexcept { - if ((unsigned int)rfnum >= Files.Size()) + if ((unsigned int)rfnum >= Files.size()) { return nullptr; } diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index 6470a20bf..eb3b119a6 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -9,7 +9,6 @@ #include "files.h" -#include "tarray.h" #include "cmdlib.h" #include "resourcefile.h" @@ -153,7 +152,7 @@ public: int GetNumWads() const { - return Files.Size(); + return (int)Files.size(); } void AddLump(FResourceLump* lump); @@ -167,10 +166,10 @@ protected: struct LumpRecord; - TArray Files; + std::vector Files; std::vector FileInfo; - TArray Hashes; // one allocation for all hash lists. + std::vector Hashes; // one allocation for all hash lists. uint32_t *FirstLumpIndex; // [RH] Hashing stuff moved out of lumpinfo structure uint32_t *NextLumpIndex; diff --git a/src/common/fonts/font.cpp b/src/common/fonts/font.cpp index 063f31077..be02a8b59 100644 --- a/src/common/fonts/font.cpp +++ b/src/common/fonts/font.cpp @@ -106,7 +106,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla size_t index; for(index = 0; index < folderdata.size(); index++) { - if (infpath.CompareNoCase(folderdata[i].name) == 0) break; + if (infpath.CompareNoCase(folderdata[index].name) == 0) break; } if (index < folderdata.size()) From 2c2bf0265f89324b29e7a8b8ef2bae749f51e6d1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 20 Aug 2023 01:49:22 +0200 Subject: [PATCH 035/223] - refactored all places which treated FileData as zero terminated. --- src/common/audio/music/i_music.cpp | 2 +- src/common/engine/sc_man.cpp | 7 +++++-- src/common/rendering/gl/gl_shader.cpp | 20 +++++++------------ src/common/rendering/gl/gl_shaderprogram.cpp | 5 ++++- src/common/rendering/gles/gles_shader.cpp | 19 ++++++++---------- .../rendering/gles/gles_shaderprogram.cpp | 4 +++- .../rendering/vulkan/shaders/vk_ppshader.cpp | 4 +++- .../rendering/vulkan/shaders/vk_shader.cpp | 5 ++--- src/common/scripting/interface/vmnatives.cpp | 2 +- src/common/textures/animlib.cpp | 2 +- src/common/textures/animlib.h | 4 ++-- src/common/textures/formats/anmtexture.cpp | 2 +- src/common/utility/cmdlib.cpp | 15 ++++++++++++++ src/common/utility/cmdlib.h | 1 + src/common/utility/palette.cpp | 4 ++-- src/gamedata/keysections.cpp | 4 ++-- src/gamedata/xlat/parsecontext.cpp | 4 ++-- src/intermission/intermission_parse.cpp | 4 ++-- src/maploader/glnodes.cpp | 2 +- 19 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/common/audio/music/i_music.cpp b/src/common/audio/music/i_music.cpp index d7460fc76..19c830916 100644 --- a/src/common/audio/music/i_music.cpp +++ b/src/common/audio/music/i_music.cpp @@ -182,7 +182,7 @@ static void SetupGenMidi() auto genmidi = fileSystem.ReadFile(lump); if (genmidi.GetSize() < 8 + 175 * 36 || memcmp(genmidi.GetMem(), "#OPL_II#", 8)) return; - ZMusic_SetGenMidi((uint8_t*)genmidi.GetString() + 8); + ZMusic_SetGenMidi(genmidi.GetBytes() + 8); } static void SetupWgOpn() diff --git a/src/common/engine/sc_man.cpp b/src/common/engine/sc_man.cpp index 21a777756..cc72273a1 100644 --- a/src/common/engine/sc_man.cpp +++ b/src/common/engine/sc_man.cpp @@ -200,8 +200,11 @@ void FScanner :: OpenLumpNum (int lump) { Close (); { - FileData mem = fileSystem.ReadFile(lump); - ScriptBuffer = mem.GetString(); + auto mem = fileSystem.OpenFileReader(lump); + auto buff = ScriptBuffer.LockNewBuffer(mem.GetLength()); + mem.Read(buff, mem.GetLength()); + buff[mem.GetLength()] = 0; + ScriptBuffer.UnlockBuffer(); } ScriptName = fileSystem.GetFileFullPath(lump).c_str(); LumpNum = lump; diff --git a/src/common/rendering/gl/gl_shader.cpp b/src/common/rendering/gl/gl_shader.cpp index 85ba5c1eb..afa05b863 100644 --- a/src/common/rendering/gl/gl_shader.cpp +++ b/src/common/rendering/gl/gl_shader.cpp @@ -375,11 +375,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * int vp_lump = fileSystem.CheckNumForFullName(vert_prog_lump, 0); if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump); - FileData vp_data = fileSystem.ReadFile(vp_lump); int fp_lump = fileSystem.CheckNumForFullName(frag_prog_lump, 0); if (fp_lump == -1) I_Error("Unable to load '%s'", frag_prog_lump); - FileData fp_data = fileSystem.ReadFile(fp_lump); @@ -410,8 +408,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * vp_comb << "#line 1\n"; fp_comb << "#line 1\n"; - vp_comb << RemoveLayoutLocationDecl(vp_data.GetString(), "out").GetChars() << "\n"; - fp_comb << RemoveLayoutLocationDecl(fp_data.GetString(), "in").GetChars() << "\n"; + vp_comb << RemoveLayoutLocationDecl(GetStringFromLump(vp_lump), "out").GetChars() << "\n"; + fp_comb << RemoveLayoutLocationDecl(GetStringFromLump(fp_lump), "in").GetChars() << "\n"; FString placeholder = "\n"; if (proc_prog_lump != NULL) @@ -423,7 +421,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * int pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump, 0); // if it's a core shader, ignore overrides by user mods. if (pp_lump == -1) pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump); if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump); - FString pp_data = fileSystem.ReadFile(pp_lump).GetString(); + FString pp_data = GetStringFromLump(pp_lump); if (pp_data.IndexOf("ProcessMaterial") < 0 && pp_data.IndexOf("SetupMaterial") < 0) { @@ -433,15 +431,13 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * { int pl_lump = fileSystem.CheckNumForFullName("shaders/glsl/func_defaultmat2.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultmat2.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString(); + fp_comb << "\n" << GetStringFromLump(pl_lump); } else { int pl_lump = fileSystem.CheckNumForFullName("shaders/glsl/func_defaultmat.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultmat.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString(); + fp_comb << "\n" << GetStringFromLump(pl_lump); if (pp_data.IndexOf("ProcessTexel") < 0) { @@ -467,8 +463,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * { int pl_lump = fileSystem.CheckNumForFullName("shaders/glsl/func_defaultlight.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultlight.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString(); + fp_comb << "\n" << GetStringFromLump(pl_lump); } // ProcessMaterial must be considered broken because it requires the user to fill in data they possibly cannot know all about. @@ -490,8 +485,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * { int pp_lump = fileSystem.CheckNumForFullName(light_fragprog, 0); if (pp_lump == -1) I_Error("Unable to load '%s'", light_fragprog); - FileData pp_data = fileSystem.ReadFile(pp_lump); - fp_comb << pp_data.GetString() << "\n"; + fp_comb << GetStringFromLump(pp_lump) << "\n"; } if (gl.flags & RFL_NO_CLIP_PLANES) diff --git a/src/common/rendering/gl/gl_shaderprogram.cpp b/src/common/rendering/gl/gl_shaderprogram.cpp index 69729a8c7..feca86aa8 100644 --- a/src/common/rendering/gl/gl_shaderprogram.cpp +++ b/src/common/rendering/gl/gl_shaderprogram.cpp @@ -28,6 +28,7 @@ #include "hw_shaderpatcher.h" #include "filesystem.h" #include "printf.h" +#include "cmdlib.h" namespace OpenGLRenderer { @@ -88,7 +89,9 @@ void FShaderProgram::Compile(ShaderType type, const char *lumpName, const char * { int lump = fileSystem.CheckNumForFullName(lumpName); if (lump == -1) I_FatalError("Unable to load '%s'", lumpName); - FString code = fileSystem.ReadFile(lump).GetString(); + auto sp = fileSystem.ReadFile(lump); + FString code = GetStringFromLump(lump); + Compile(type, lumpName, code, defines, maxGlslVersion); } diff --git a/src/common/rendering/gles/gles_shader.cpp b/src/common/rendering/gles/gles_shader.cpp index 16ff0eb65..8f9103c61 100644 --- a/src/common/rendering/gles/gles_shader.cpp +++ b/src/common/rendering/gles/gles_shader.cpp @@ -410,8 +410,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * vp_comb << "#line 1\n"; fp_comb << "#line 1\n"; - vp_comb << RemoveLayoutLocationDecl(vp_data.GetString(), "out").GetChars() << "\n"; - fp_comb << RemoveLayoutLocationDecl(fp_data.GetString(), "in").GetChars() << "\n"; + vp_comb << RemoveLayoutLocationDecl(GetStringFromLump(vp_lump), "out").GetChars() << "\n"; + fp_comb << RemoveLayoutLocationDecl(GetStringFromLump(fp_lump), "in").GetChars() << "\n"; FString placeholder = "\n"; if (proc_prog_lump.Len()) @@ -422,7 +422,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * { int pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump); if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump.GetChars()); - FString pp_data = fileSystem.ReadFile(pp_lump).GetString(); + auto ppf = fileSystem.ReadFile(pp_lump); + FString pp_data = GetStringFromLump(pp_lump); if (pp_data.IndexOf("ProcessMaterial") < 0 && pp_data.IndexOf("SetupMaterial") < 0) { @@ -432,15 +433,13 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * { int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultmat2.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultmat2.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString(); + fp_comb << "\n" << GetStringFromLump(pl_lump); } else { int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultmat.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultmat.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString(); + fp_comb << "\n" << GetStringFromLump(pl_lump); if (pp_data.IndexOf("ProcessTexel") < 0) { @@ -466,8 +465,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * { int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultlight.fp", 0); if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultlight.fp"); - FileData pl_data = fileSystem.ReadFile(pl_lump); - fp_comb << "\n" << pl_data.GetString(); + fp_comb << "\n" << GetStringFromLump(pl_lump); } // ProcessMaterial must be considered broken because it requires the user to fill in data they possibly cannot know all about. @@ -489,8 +487,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * { int pp_lump = fileSystem.CheckNumForFullName(light_fragprog, 0); if (pp_lump == -1) I_Error("Unable to load '%s'", light_fragprog.GetChars()); - FileData pp_data = fileSystem.ReadFile(pp_lump); - fp_comb << pp_data.GetString() << "\n"; + fp_comb << GetStringFromLump(pp_lump) << "\n"; } if (gles.flags & RFL_NO_CLIP_PLANES) diff --git a/src/common/rendering/gles/gles_shaderprogram.cpp b/src/common/rendering/gles/gles_shaderprogram.cpp index 8677257f3..289008c21 100644 --- a/src/common/rendering/gles/gles_shaderprogram.cpp +++ b/src/common/rendering/gles/gles_shaderprogram.cpp @@ -26,6 +26,7 @@ #include "hw_shaderpatcher.h" #include "filesystem.h" #include "printf.h" +#include "cmdlib.h" namespace OpenGLESRenderer { @@ -88,7 +89,8 @@ void FShaderProgram::Compile(ShaderType type, const char *lumpName, const char * { int lump = fileSystem.CheckNumForFullName(lumpName); if (lump == -1) I_FatalError("Unable to load '%s'", lumpName); - FString code = fileSystem.ReadFile(lump).GetString(); + auto sp = fileSystem.ReadFile(lump); + FString code = GetStringFromLump(lump); Compile(type, lumpName, code, defines, maxGlslVersion); } diff --git a/src/common/rendering/vulkan/shaders/vk_ppshader.cpp b/src/common/rendering/vulkan/shaders/vk_ppshader.cpp index f83b01c93..d9f6078c7 100644 --- a/src/common/rendering/vulkan/shaders/vk_ppshader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_ppshader.cpp @@ -26,6 +26,7 @@ #include "zvulkan/vulkanbuilders.h" #include "vulkan/system/vk_commandbuffer.h" #include "filesystem.h" +#include "cmdlib.h" VkPPShader::VkPPShader(VulkanRenderDevice* fb, PPShader *shader) : fb(fb) { @@ -66,7 +67,8 @@ FString VkPPShader::LoadShaderCode(const FString &lumpName, const FString &defin { int lump = fileSystem.CheckNumForFullName(lumpName); if (lump == -1) I_FatalError("Unable to load '%s'", lumpName.GetChars()); - FString code = fileSystem.ReadFile(lump).GetString(); + auto sp = fileSystem.ReadFile(lump); + FString code = GetStringFromLump(lump); FString patchedCode; patchedCode.AppendFormat("#version %d\n", 450); diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index 2c3eb9241..3784543b3 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -466,8 +466,7 @@ FString VkShaderManager::LoadPublicShaderLump(const char *lumpname) int lump = fileSystem.CheckNumForFullName(lumpname, 0); if (lump == -1) lump = fileSystem.CheckNumForFullName(lumpname); if (lump == -1) I_Error("Unable to load '%s'", lumpname); - FileData data = fileSystem.ReadFile(lump); - return data.GetString(); + return GetStringFromLump(lump); } FString VkShaderManager::LoadPrivateShaderLump(const char *lumpname) @@ -475,7 +474,7 @@ FString VkShaderManager::LoadPrivateShaderLump(const char *lumpname) int lump = fileSystem.CheckNumForFullName(lumpname, 0); if (lump == -1) I_Error("Unable to load '%s'", lumpname); FileData data = fileSystem.ReadFile(lump); - return data.GetString(); + return GetStringFromLump(lump); } VkPPShader* VkShaderManager::GetVkShader(PPShader* shader) diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index 636c340ae..3e75e75d8 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -841,7 +841,7 @@ DEFINE_ACTION_FUNCTION(_Wads, ReadLump) PARAM_PROLOGUE; PARAM_INT(lump); const bool isLumpValid = lump >= 0 && lump < fileSystem.GetNumEntries(); - ACTION_RETURN_STRING(isLumpValid ? fileSystem.ReadFile(lump).GetString() : ""); + ACTION_RETURN_STRING(isLumpValid ? GetStringFromLump(lump) : FString()); } //========================================================================== diff --git a/src/common/textures/animlib.cpp b/src/common/textures/animlib.cpp index 949027786..1b31244f3 100644 --- a/src/common/textures/animlib.cpp +++ b/src/common/textures/animlib.cpp @@ -217,7 +217,7 @@ static inline void drawframe(anim_t *anim, uint16_t framenumber) } // is the file size, for consistency checking. -int32_t ANIM_LoadAnim(anim_t *anim, uint8_t *buffer, size_t length) +int32_t ANIM_LoadAnim(anim_t *anim, const uint8_t *buffer, size_t length) { if (memcmp(buffer, "LPF ", 4)) return -1; diff --git a/src/common/textures/animlib.h b/src/common/textures/animlib.h index 1fdaa354f..26fa124f4 100644 --- a/src/common/textures/animlib.h +++ b/src/common/textures/animlib.h @@ -92,7 +92,7 @@ struct anim_t lp_descriptor * curlp; // header of large page currently in memory uint16_t * thepage; // buffer where current large page is loaded uint8_t imagebuffer[IMAGEBUFFERSIZE]; // buffer where anim frame is decoded - uint8_t * buffer; + const uint8_t * buffer; uint8_t pal[768]; int32_t currentframe; }; @@ -105,7 +105,7 @@ struct anim_t // //**************************************************************************** -int32_t ANIM_LoadAnim(anim_t *anim, uint8_t *buffer, size_t length); +int32_t ANIM_LoadAnim(anim_t *anim, const uint8_t *buffer, size_t length); //**************************************************************************** // diff --git a/src/common/textures/formats/anmtexture.cpp b/src/common/textures/formats/anmtexture.cpp index f4fb332f0..f57b0e31e 100644 --- a/src/common/textures/formats/anmtexture.cpp +++ b/src/common/textures/formats/anmtexture.cpp @@ -104,7 +104,7 @@ FAnmTexture::FAnmTexture (int lumpnum, int w, int h) void FAnmTexture::ReadFrame(uint8_t *pixels, uint8_t *palette) { FileData lump = fileSystem.ReadFile (SourceLump); - uint8_t *source = (uint8_t *)lump.GetMem(); + auto source = lump.GetBytes(); anim_t anim; if (ANIM_LoadAnim(&anim, source, (int)lump.GetSize()) >= 0) diff --git a/src/common/utility/cmdlib.cpp b/src/common/utility/cmdlib.cpp index 1e906e69c..b5ac83415 100644 --- a/src/common/utility/cmdlib.cpp +++ b/src/common/utility/cmdlib.cpp @@ -36,6 +36,7 @@ #include "cmdlib.h" #include "fs_findfile.h" +#include "filesystem.h" #include "files.h" #include "md5.h" @@ -1008,3 +1009,17 @@ void uppercopy(char* to, const char* from) to[i] = 0; } +//========================================================================== +// +// GetStringFromLump +// +// Loads a zero terminated string from a lump in the file system +//========================================================================== + +FString GetStringFromLump(int lump) +{ + FileData fd = fileSystem.ReadFile(lump); + FString ScriptBuffer(fd.GetString(), fd.GetSize()); + ScriptBuffer.Truncate(strlen(ScriptBuffer.GetChars())); // this is necessary to properly truncate the generated string to not contain 0 bytes. + return ScriptBuffer; +} diff --git a/src/common/utility/cmdlib.h b/src/common/utility/cmdlib.h index e2e4aadbd..9d94d0d3f 100644 --- a/src/common/utility/cmdlib.h +++ b/src/common/utility/cmdlib.h @@ -87,6 +87,7 @@ struct MD5Context; void md5Update(FileReader& file, MD5Context& md5, unsigned len); void uppercopy(char* to, const char* from); +FString GetStringFromLump(int lump); inline void fillshort(void* buff, size_t count, uint16_t clear) { diff --git a/src/common/utility/palette.cpp b/src/common/utility/palette.cpp index 7598f5d4e..178db734b 100644 --- a/src/common/utility/palette.cpp +++ b/src/common/utility/palette.cpp @@ -681,8 +681,8 @@ FString V_GetColorStringByName(const char* name, FScriptPosition* sc) } auto rgbNames = fileSystem.ReadFile(rgblump); - rgb = (char*)rgbNames.GetMem(); - rgbEnd = rgb + fileSystem.FileLength(rgblump); + rgb = rgbNames.GetString(); + rgbEnd = rgb + rgbNames.GetSize(); step = 0; namelen = strlen(name); diff --git a/src/gamedata/keysections.cpp b/src/gamedata/keysections.cpp index 390c8009f..8561b6b24 100644 --- a/src/gamedata/keysections.cpp +++ b/src/gamedata/keysections.cpp @@ -166,8 +166,8 @@ void D_LoadWadSettings () while ((lump = fileSystem.FindLump ("KEYCONF", &lastlump)) != -1) { FileData data = fileSystem.ReadFile (lump); - const char *eof = data.GetString() + fileSystem.FileLength (lump); - const char *conf = data.GetString(); + const char* conf = data.GetString(); + const char *eof = conf + data.GetSize(); while (conf < eof) { diff --git a/src/gamedata/xlat/parsecontext.cpp b/src/gamedata/xlat/parsecontext.cpp index 1810af55d..0caa72f4b 100644 --- a/src/gamedata/xlat/parsecontext.cpp +++ b/src/gamedata/xlat/parsecontext.cpp @@ -323,12 +323,12 @@ void FParseContext::ParseLump(const char *lumpname) } // Read the lump into a buffer and add a 0-terminator - auto lumpdata = fileSystem.ReadFile(lumpno); SourceLine = 0; SourceFile = lumpname; - const char *sourcep = lumpdata.GetString(); + FString source = GetStringFromLump(lumpno); + const char *sourcep = source.GetChars(); while ( (tokentype = GetToken(sourcep, &token)) ) { // It is much easier to handle include statements outside the main parser. diff --git a/src/intermission/intermission_parse.cpp b/src/intermission/intermission_parse.cpp index 5b2de2c4d..b5a51aab5 100644 --- a/src/intermission/intermission_parse.cpp +++ b/src/intermission/intermission_parse.cpp @@ -320,7 +320,7 @@ bool FIntermissionActionTextscreen::ParseKey(FScanner &sc) } } if (!done) - mText = fileSystem.ReadFile(lump).GetString(); + mText = GetStringFromLump(lump); } else { @@ -864,7 +864,7 @@ DIntermissionController* F_StartFinale (const char *music, int musicorder, int c int lump = fileSystem.CheckNumForFullName(text, true); if (lump > 0) { - textscreen->mText = fileSystem.ReadFile(lump).GetString(); + textscreen->mText = GetStringFromLump(lump); } else { diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index 15b4b46ba..a72b3b7e4 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -754,7 +754,7 @@ static int FindGLNodesInWAD(int labellump) if (fileSystem.GetFileContainer(lump)==wadfile) { FileData mem = fileSystem.ReadFile(lump); - if (MatchHeader(fileSystem.GetFileFullName(labellump), mem.GetString())) return lump; + if (MatchHeader(fileSystem.GetFileFullName(labellump), GetStringFromLump(lump))) return lump; } } } From 4f8305de5f30909d3ae3fb99a8ee00a52975bc17 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 20 Aug 2023 02:04:19 +0200 Subject: [PATCH 036/223] - use the lump cache directly for FileData. This was the final puzzle piece to allow using memory mapped files. :) --- src/common/filesystem/filesystem.cpp | 23 ------------------- src/common/filesystem/filesystem.h | 34 ++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 6c67b9f45..097b6ffe5 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -1518,29 +1518,6 @@ bool FileSystem::CreatePathlessCopy(const char *name, int id, int /*flags*/) return true; } -// FileData ----------------------------------------------------------------- - -FileData::FileData (const FileData ©) -{ - Block = copy.Block; -} - -FileData &FileData::operator = (const FileData ©) -{ - Block = copy.Block; - return *this; -} - -FileData::FileData (FResourceLump* lump) -{ - auto size = lump->LumpSize; - Block.resize(1 + size); - memcpy(Block.data(), lump->Lock(), size); - Block[size] = 0; - lump->Unlock(); -} - - //========================================================================== // // PrintLastError diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index eb3b119a6..29b9b8b4e 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -28,18 +28,34 @@ union LumpShortName class FileData { public: - FileData () = default; - FileData (const FileData ©); - FileData &operator= (const FileData ©); - const void *GetMem () { return Block.size() <= 1 ? NULL : (void *)Block.data(); } - size_t GetSize () { return Block.size(); } - const char* GetString () const { return (const char*)Block.data(); } - const uint8_t* GetBytes() const { return Block.data(); } + FileData() { lump = nullptr; } + const void *GetMem () { return lump->Cache; } + size_t GetSize () { return lump->LumpSize; } + const char* GetString () const { return (const char*)lump->Cache; } + const uint8_t* GetBytes() const { return (const uint8_t*)lump->Cache; } + + FileData& operator = (const FileData& copy) = delete; + + FileData(const FileData& copy) + { + lump = copy.lump; + lump->Lock(); + } + + ~FileData() + { + if (lump) lump->Unlock(); + } + private: - FileData (FResourceLump* lump); + FileData(FResourceLump* nlump) + { + lump = nlump; + if (lump) lump->Lock(); + } - std::vector Block; + FResourceLump* lump; friend class FileSystem; }; From 3d673e3f20eca15de1e4485d8393031ead570db3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 00:56:31 +0200 Subject: [PATCH 037/223] - use a string pool to store the filenames in FResourceLump. --- src/common/filesystem/file_7z.cpp | 12 ++-- src/common/filesystem/file_directory.cpp | 12 ++-- src/common/filesystem/file_grp.cpp | 12 ++-- src/common/filesystem/file_lump.cpp | 12 ++-- src/common/filesystem/file_pak.cpp | 12 ++-- src/common/filesystem/file_rff.cpp | 12 ++-- src/common/filesystem/file_ssi.cpp | 14 ++-- src/common/filesystem/file_wad.cpp | 16 ++--- src/common/filesystem/file_whres.cpp | 12 ++-- src/common/filesystem/file_zip.cpp | 10 +-- src/common/filesystem/file_zip.h | 2 +- src/common/filesystem/filesystem.cpp | 12 ++-- src/common/filesystem/filesystem.h | 2 + src/common/filesystem/fs_stringpool.cpp | 2 +- src/common/filesystem/fs_stringpool.h | 6 +- src/common/filesystem/resourcefile.cpp | 83 +++++++++++++----------- src/common/filesystem/resourcefile.h | 25 +++---- 17 files changed, 137 insertions(+), 119 deletions(-) diff --git a/src/common/filesystem/file_7z.cpp b/src/common/filesystem/file_7z.cpp index 5539d5448..391a8aab2 100644 --- a/src/common/filesystem/file_7z.cpp +++ b/src/common/filesystem/file_7z.cpp @@ -186,7 +186,7 @@ class F7ZFile : public FResourceFile C7zArchive *Archive; public: - F7ZFile(const char * filename, FileReader &filer); + F7ZFile(const char * filename, FileReader &filer, StringPool* sp); bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); virtual ~F7ZFile(); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } @@ -200,8 +200,8 @@ public: // //========================================================================== -F7ZFile::F7ZFile(const char * filename, FileReader &filer) - : FResourceFile(filename, filer) +F7ZFile::F7ZFile(const char * filename, FileReader &filer, StringPool* sp) + : FResourceFile(filename, filer, sp) { Lumps = NULL; Archive = NULL; @@ -280,7 +280,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) } FixPathSeparator(&nameASCII.front()); - lump_p->LumpNameSetup(nameASCII.c_str()); + lump_p->LumpNameSetup(nameASCII.c_str(), stringpool); lump_p->LumpSize = static_cast(SzArEx_GetFileSize(archPtr, i)); lump_p->Owner = this; lump_p->Flags = LUMPF_FULLPATH|LUMPF_COMPRESSED; @@ -352,7 +352,7 @@ int F7ZLump::FillCache() // //========================================================================== -FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[k7zSignatureSize]; @@ -363,7 +363,7 @@ FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* f file.Seek(0, FileReader::SeekSet); if (!memcmp(head, k7zSignature, k7zSignatureSize)) { - auto rf = new F7ZFile(filename, file); + auto rf = new F7ZFile(filename, file, sp); if (rf->Open(filter, Printf)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/file_directory.cpp index 7117df760..a99e6fb56 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/file_directory.cpp @@ -75,7 +75,7 @@ class FDirectory : public FResourceFile void AddEntry(const char *fullpath, int size); public: - FDirectory(const char * dirname, bool nosubdirflag = false); + FDirectory(const char * dirname, StringPool* sp, bool nosubdirflag = false); bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } }; @@ -88,8 +88,8 @@ public: // //========================================================================== -FDirectory::FDirectory(const char * directory, bool nosubdirflag) - : FResourceFile(""), nosubdir(nosubdirflag) +FDirectory::FDirectory(const char * directory, StringPool* sp, bool nosubdirflag) + : FResourceFile("", sp), nosubdir(nosubdirflag) { FileName = FS_FullPath(directory); if (FileName[FileName.length()-1] != '/') FileName += '/'; @@ -171,7 +171,7 @@ void FDirectory::AddEntry(const char *fullpath, int size) for (auto& c : name) c = tolower(c); // The lump's name is only the part relative to the main directory - lump_p->LumpNameSetup(name.c_str()); + lump_p->LumpNameSetup(name.c_str(), stringpool); lump_p->LumpSize = size; lump_p->Owner = this; lump_p->Flags = 0; @@ -221,9 +221,9 @@ int FDirectoryLump::FillCache() // //========================================================================== -FResourceFile *CheckDir(const char *filename, bool nosubdirflag, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckDir(const char *filename, bool nosubdirflag, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { - auto rf = new FDirectory(filename, nosubdirflag); + auto rf = new FDirectory(filename, sp, nosubdirflag); if (rf->Open(filter, Printf)) return rf; delete rf; return nullptr; diff --git a/src/common/filesystem/file_grp.cpp b/src/common/filesystem/file_grp.cpp index 4765bcde0..dd8099a2a 100644 --- a/src/common/filesystem/file_grp.cpp +++ b/src/common/filesystem/file_grp.cpp @@ -73,7 +73,7 @@ struct GrpLump class FGrpFile : public FUncompressedFile { public: - FGrpFile(const char * filename, FileReader &file); + FGrpFile(const char * filename, FileReader &file, StringPool* sp); bool Open(LumpFilterInfo* filter); }; @@ -84,8 +84,8 @@ public: // //========================================================================== -FGrpFile::FGrpFile(const char *filename, FileReader &file) -: FUncompressedFile(filename, file) +FGrpFile::FGrpFile(const char *filename, FileReader &file, StringPool* sp) +: FUncompressedFile(filename, file, sp) { } @@ -117,7 +117,7 @@ bool FGrpFile::Open(LumpFilterInfo* filter) Position += fileinfo[i].Size; Lumps[i].Flags = 0; fileinfo[i].NameWithZero[12] = '\0'; // Be sure filename is null-terminated - Lumps[i].LumpNameSetup(fileinfo[i].NameWithZero); + Lumps[i].LumpNameSetup(fileinfo[i].NameWithZero, stringpool); } GenerateHash(); delete[] fileinfo; @@ -131,7 +131,7 @@ bool FGrpFile::Open(LumpFilterInfo* filter) // //========================================================================== -FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[12]; @@ -142,7 +142,7 @@ FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* file.Seek(0, FileReader::SeekSet); if (!memcmp(head, "KenSilverman", 12)) { - auto rf = new FGrpFile(filename, file); + auto rf = new FGrpFile(filename, file, sp); if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader diff --git a/src/common/filesystem/file_lump.cpp b/src/common/filesystem/file_lump.cpp index 60c957081..540ee6dd7 100644 --- a/src/common/filesystem/file_lump.cpp +++ b/src/common/filesystem/file_lump.cpp @@ -43,7 +43,7 @@ class FLumpFile : public FUncompressedFile { public: - FLumpFile(const char * filename, FileReader &file); + FLumpFile(const char * filename, FileReader &file, StringPool* sp); bool Open(LumpFilterInfo* filter); }; @@ -54,8 +54,8 @@ public: // //========================================================================== -FLumpFile::FLumpFile(const char *filename, FileReader &file) - : FUncompressedFile(filename, file) +FLumpFile::FLumpFile(const char *filename, FileReader &file, StringPool* sp) + : FUncompressedFile(filename, file, sp) { } @@ -68,7 +68,7 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file) bool FLumpFile::Open(LumpFilterInfo*) { Lumps.Resize(1); - Lumps[0].LumpNameSetup(ExtractBaseName(FileName.c_str(), true).c_str()); + Lumps[0].LumpNameSetup(ExtractBaseName(FileName.c_str(), true).c_str(), stringpool); Lumps[0].Owner = this; Lumps[0].Position = 0; Lumps[0].LumpSize = (int)Reader.GetLength(); @@ -83,10 +83,10 @@ bool FLumpFile::Open(LumpFilterInfo*) // //========================================================================== -FResourceFile *CheckLump(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckLump(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { // always succeeds - auto rf = new FLumpFile(filename, file); + auto rf = new FLumpFile(filename, file, sp); if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; diff --git a/src/common/filesystem/file_pak.cpp b/src/common/filesystem/file_pak.cpp index 4003ce396..dfcc22ef4 100644 --- a/src/common/filesystem/file_pak.cpp +++ b/src/common/filesystem/file_pak.cpp @@ -65,7 +65,7 @@ struct dpackheader_t class FPakFile : public FUncompressedFile { public: - FPakFile(const char * filename, FileReader &file); + FPakFile(const char * filename, FileReader &file, StringPool* sp); bool Open(LumpFilterInfo* filter); }; @@ -78,8 +78,8 @@ public: // //========================================================================== -FPakFile::FPakFile(const char *filename, FileReader &file) - : FUncompressedFile(filename, file) +FPakFile::FPakFile(const char *filename, FileReader &file, StringPool* sp) + : FUncompressedFile(filename, file, sp) { } @@ -105,7 +105,7 @@ bool FPakFile::Open(LumpFilterInfo* filter) for(uint32_t i = 0; i < NumLumps; i++) { - Lumps[i].LumpNameSetup(fileinfo[i].name); + Lumps[i].LumpNameSetup(fileinfo[i].name, stringpool); Lumps[i].Flags = LUMPF_FULLPATH; Lumps[i].Owner = this; Lumps[i].Position = LittleLong(fileinfo[i].filepos); @@ -124,7 +124,7 @@ bool FPakFile::Open(LumpFilterInfo* filter) // //========================================================================== -FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[4]; @@ -135,7 +135,7 @@ FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* file.Seek(0, FileReader::SeekSet); if (!memcmp(head, "PACK", 4)) { - auto rf = new FPakFile(filename, file); + auto rf = new FPakFile(filename, file, sp); if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader diff --git a/src/common/filesystem/file_rff.cpp b/src/common/filesystem/file_rff.cpp index 723d184e6..5204d7f0f 100644 --- a/src/common/filesystem/file_rff.cpp +++ b/src/common/filesystem/file_rff.cpp @@ -110,7 +110,7 @@ class FRFFFile : public FResourceFile FRFFLump *Lumps; public: - FRFFFile(const char * filename, FileReader &file); + FRFFFile(const char * filename, FileReader &file, StringPool* sp); virtual ~FRFFFile(); virtual bool Open(LumpFilterInfo* filter); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } @@ -123,8 +123,8 @@ public: // //========================================================================== -FRFFFile::FRFFFile(const char *filename, FileReader &file) -: FResourceFile(filename, file) +FRFFFile::FRFFFile(const char *filename, FileReader &file, StringPool* sp) +: FResourceFile(filename, file, sp) { Lumps = NULL; } @@ -172,7 +172,7 @@ bool FRFFFile::Open(LumpFilterInfo*) name[len+2] = lumps[i].Extension[1]; name[len+3] = lumps[i].Extension[2]; name[len+4] = 0; - Lumps[i].LumpNameSetup(name); + Lumps[i].LumpNameSetup(name, stringpool); } delete[] lumps; GenerateHash(); @@ -238,7 +238,7 @@ int FRFFLump::FillCache() // //========================================================================== -FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[4]; @@ -249,7 +249,7 @@ FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* file.Seek(0, FileReader::SeekSet); if (!memcmp(head, "RFF\x1a", 4)) { - auto rf = new FRFFFile(filename, file); + auto rf = new FRFFFile(filename, file, sp); if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader diff --git a/src/common/filesystem/file_ssi.cpp b/src/common/filesystem/file_ssi.cpp index 6bf60cc1e..0cfab8729 100644 --- a/src/common/filesystem/file_ssi.cpp +++ b/src/common/filesystem/file_ssi.cpp @@ -44,7 +44,7 @@ class FSSIFile : public FUncompressedFile { public: - FSSIFile(const char * filename, FileReader &file); + FSSIFile(const char * filename, FileReader &file, StringPool* sp); bool Open(int version, int lumpcount, LumpFilterInfo* filter); }; @@ -55,8 +55,8 @@ public: // //========================================================================== -FSSIFile::FSSIFile(const char *filename, FileReader &file) -: FUncompressedFile(filename, file) +FSSIFile::FSSIFile(const char *filename, FileReader &file, StringPool* sp) +: FUncompressedFile(filename, file, sp) { } @@ -85,7 +85,7 @@ bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*) int flength = Reader.ReadInt32(); - Lumps[i].LumpNameSetup(fn); + Lumps[i].LumpNameSetup(fn, stringpool); Lumps[i].Position = j; Lumps[i].LumpSize = flength; Lumps[i].Owner = this; @@ -94,7 +94,7 @@ bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*) // SSI files can swap the order of the extension's characters - but there's no reliable detection for this and it can be mixed inside the same container, // so we have no choice but to create another file record for the altered name. std::swap(fn[strlength - 1], fn[strlength - 3]); - Lumps[i+1].LumpNameSetup(fn); + Lumps[i+1].LumpNameSetup(fn, stringpool); Lumps[i+1].Position = j; Lumps[i+1].LumpSize = flength; Lumps[i+1].Owner = this; @@ -114,7 +114,7 @@ bool FSSIFile::Open(int version, int lumpcount, LumpFilterInfo*) // //========================================================================== -FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char zerobuf[72]; char buf[72]; @@ -144,7 +144,7 @@ FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* { if (!skipstring(70)) return nullptr; } - auto ssi = new FSSIFile(filename, file); + auto ssi = new FSSIFile(filename, file, sp); if (ssi->Open(version, numfiles, filter)) return ssi; file = std::move(ssi->Reader); // to avoid destruction of reader delete ssi; diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/file_wad.cpp index fb77a8781..badcc271f 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/file_wad.cpp @@ -136,7 +136,7 @@ class FWadFile : public FResourceFile void SkinHack (FileSystemMessageFunc Printf); public: - FWadFile(const char * filename, FileReader &file); + FWadFile(const char * filename, FileReader &file, StringPool* sp); FResourceLump *GetLump(int lump) { return &Lumps[lump]; } bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); }; @@ -150,8 +150,8 @@ public: // //========================================================================== -FWadFile::FWadFile(const char *filename, FileReader &file) - : FResourceFile(filename, file) +FWadFile::FWadFile(const char *filename, FileReader &file, StringPool* sp) + : FResourceFile(filename, file, sp) { } @@ -207,7 +207,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) #else Lumps[i].Compressed = false; #endif - Lumps[i].LumpNameSetup(n); + Lumps[i].LumpNameSetup(n, stringpool); Lumps[i].Owner = this; Lumps[i].Position = isBigEndian ? BigLong(fileinfo[i].FilePos) : LittleLong(fileinfo[i].FilePos); @@ -221,7 +221,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) if (Lumps[i].LumpSize != 0) { Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.c_str(), Lumps[i].getName()); - Lumps[i].LumpNameSetup(""); + Lumps[i].clearName(); } Lumps[i].LumpSize = Lumps[i].Position = 0; } @@ -420,7 +420,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf) if (!strnicmp(lump->getName(), "S_SKIN", 6)) { // Wad has at least one skin. - lump->LumpNameSetup("S_SKIN"); + lump->LumpNameSetup("S_SKIN", nullptr); if (!skinned) { skinned = true; @@ -464,7 +464,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf) // //========================================================================== -FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[4]; @@ -475,7 +475,7 @@ FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* file.Seek(0, FileReader::SeekSet); if (!memcmp(head, "IWAD", 4) || !memcmp(head, "PWAD", 4)) { - auto rf = new FWadFile(filename, file); + auto rf = new FWadFile(filename, file, sp); if (rf->Open(filter, Printf)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader diff --git a/src/common/filesystem/file_whres.cpp b/src/common/filesystem/file_whres.cpp index d7149f116..8629e6a64 100644 --- a/src/common/filesystem/file_whres.cpp +++ b/src/common/filesystem/file_whres.cpp @@ -49,7 +49,7 @@ class FWHResFile : public FUncompressedFile { std::string basename; public: - FWHResFile(const char * filename, FileReader &file); + FWHResFile(const char * filename, FileReader &file, StringPool* sp); bool Open(LumpFilterInfo* filter); }; @@ -60,8 +60,8 @@ public: // //========================================================================== -FWHResFile::FWHResFile(const char *filename, FileReader &file) - : FUncompressedFile(filename, file) +FWHResFile::FWHResFile(const char *filename, FileReader &file, StringPool* sp) + : FUncompressedFile(filename, file, sp) { basename = ExtractBaseName(filename, false); } @@ -92,7 +92,7 @@ bool FWHResFile::Open(LumpFilterInfo*) char num[5]; snprintf(num, 5, "/%04d", k); std::string synthname = basename + num; - Lumps[i].LumpNameSetup(synthname.c_str()); + Lumps[i].LumpNameSetup(synthname.c_str(), stringpool); Lumps[i].Owner = this; Lumps[i].Position = offset; Lumps[i].LumpSize = length; @@ -111,7 +111,7 @@ bool FWHResFile::Open(LumpFilterInfo*) // //========================================================================== -FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { if (file.GetLength() >= 8192) // needs to be at least 8192 to contain one file and the directory. { @@ -131,7 +131,7 @@ FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo if (offset != checkpos || length == 0 || offset + length >= (size_t)size - 4096 ) return nullptr; checkpos += (length+4095) / 4096; } - auto rf = new FWHResFile(filename, file); + auto rf = new FWHResFile(filename, file, sp); if (rf->Open(filter)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader delete rf; diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index 492a24276..175c53e18 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -164,8 +164,8 @@ static uint32_t Zip_FindCentralDir(FileReader &fin, bool* zip64) // //========================================================================== -FZipFile::FZipFile(const char * filename, FileReader &file) -: FResourceFile(filename, file) +FZipFile::FZipFile(const char * filename, FileReader &file, StringPool* sp) +: FResourceFile(filename, file, sp) { Lumps = NULL; } @@ -396,7 +396,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) } } - lump_p->LumpNameSetup(name.c_str()); + lump_p->LumpNameSetup(name.c_str(), stringpool); lump_p->LumpSize = UncompressedSize; lump_p->Owner = this; // The start of the Reader will be determined the first time it is accessed. @@ -532,7 +532,7 @@ int FZipLump::GetFileOffset() // //========================================================================== -FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { char head[4]; @@ -543,7 +543,7 @@ FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* file.Seek(0, FileReader::SeekSet); if (!memcmp(head, "PK\x3\x4", 4)) { - auto rf = new FZipFile(filename, file); + auto rf = new FZipFile(filename, file, sp); if (rf->Open(filter, Printf)) return rf; file = std::move(rf->Reader); // to avoid destruction of reader diff --git a/src/common/filesystem/file_zip.h b/src/common/filesystem/file_zip.h index 028731f28..5b49b714f 100644 --- a/src/common/filesystem/file_zip.h +++ b/src/common/filesystem/file_zip.h @@ -39,7 +39,7 @@ class FZipFile : public FResourceFile FZipLump *Lumps; public: - FZipFile(const char * filename, FileReader &file); + FZipFile(const char * filename, FileReader &file, StringPool* sp); virtual ~FZipFile(); bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 097b6ffe5..057493719 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -44,6 +44,7 @@ #include "filesystem.h" #include "fs_findfile.h" #include "md5.hpp" +#include "fs_stringpool.h" // MACROS ------------------------------------------------------------------ @@ -191,7 +192,8 @@ FileSystem fileSystem; FileSystem::FileSystem() { - // Cannot be defaulted! This is needed to initialize the LumpRecord array, which depends on data only available here. + stringpool = new StringPool; + stringpool->shared = true; // will be used by all owned resource files. } FileSystem::~FileSystem () @@ -323,7 +325,7 @@ int FileSystem::AddFromBuffer(const char* name, const char* type, char* data, in fullname += ':'; fullname += type; auto newlump = new FMemoryLump(data, size); - newlump->LumpNameSetup(fullname.c_str()); + newlump->LumpNameSetup(fullname.c_str(), stringpool); AddLump(newlump); FileInfo.back().resourceId = id; return (int)FileInfo.size()-1; @@ -379,9 +381,9 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf if (!isdir) - resfile = FResourceFile::OpenResourceFile(filename, filereader, false, filter, Printf); + resfile = FResourceFile::OpenResourceFile(filename, filereader, false, filter, Printf, stringpool); else - resfile = FResourceFile::OpenDirectory(filename, filter, Printf); + resfile = FResourceFile::OpenDirectory(filename, filter, Printf, stringpool); if (resfile != NULL) { @@ -943,7 +945,7 @@ void FileSystem::MoveLumpsInFolder(const char *path) FileInfo.push_back(li); li.lump = &placeholderLump; // Make the old entry point to something empty. We cannot delete the lump record here because it'd require adjustment of all indices in the list. auto &ln = FileInfo.back(); - ln.lump->LumpNameSetup(ln.longName.c_str() + len); + ln.lump->LumpNameSetup(ln.longName.c_str() + len, stringpool); // may be able to avoid the string allocation! ln.SetFromLump(rfnum, ln.lump); } } diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/filesystem.h index 29b9b8b4e..7dcda2f09 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/filesystem.h @@ -204,6 +204,8 @@ protected: int IwadIndex = -1; int MaxIwadIndex = -1; + StringPool* stringpool; + private: void DeleteAll(); void MoveLumpsInFolder(const char *); diff --git a/src/common/filesystem/fs_stringpool.cpp b/src/common/filesystem/fs_stringpool.cpp index b828d398f..29a472309 100644 --- a/src/common/filesystem/fs_stringpool.cpp +++ b/src/common/filesystem/fs_stringpool.cpp @@ -120,7 +120,7 @@ void *StringPool::iAlloc(size_t size) const char* StringPool::Strdup(const char* str) { - char* p = (char*)iAlloc((strlen(str) + 15) & ~15 ); + char* p = (char*)iAlloc((strlen(str) + 8) & ~7 ); strcpy(p, str); return p; } diff --git a/src/common/filesystem/fs_stringpool.h b/src/common/filesystem/fs_stringpool.h index ce1e7d83f..331f768f7 100644 --- a/src/common/filesystem/fs_stringpool.h +++ b/src/common/filesystem/fs_stringpool.h @@ -3,8 +3,12 @@ // Storage for all the static strings the file system must hold. class StringPool { -public: + // do not allow externally defining this. + friend class FileSystem; + friend class FResourceFile; +private: StringPool(size_t blocksize = 10*1024) : TopBlock(nullptr), FreeBlocks(nullptr), BlockSize(blocksize) {} +public: ~StringPool(); const char* Strdup(const char*); diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index 718069c51..5f044371f 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -37,6 +37,7 @@ #include #include "resourcefile.h" #include "md5.hpp" +#include "fs_stringpool.h" std::string ExtractBaseName(const char* path, bool include_extension) { @@ -122,13 +123,17 @@ FResourceLump::~FResourceLump() // //========================================================================== -void FResourceLump::LumpNameSetup(const char *iname) +void FResourceLump::LumpNameSetup(const char *iname, StringPool* allocator) { // this causes interference with real Dehacked lumps. if (!stricmp(iname, "dehacked.exe")) { iname = ""; } + else if (allocator) + { + iname = allocator->Strdup(iname); + } FullName = iname; } @@ -159,14 +164,14 @@ static bool IsWadInFolder(const FResourceFile* const archive, const char* const void FResourceLump::CheckEmbedded(LumpFilterInfo* lfi) { // Checks for embedded archives - const char *c = strstr(FullName.c_str(), ".wad"); - if (c && strlen(c) == 4 && (!strchr(FullName.c_str(), '/') || IsWadInFolder(Owner, FullName.c_str()))) + const char *c = strstr(FullName, ".wad"); + if (c && strlen(c) == 4 && (!strchr(FullName, '/') || IsWadInFolder(Owner, FullName))) { Flags |= LUMPF_EMBEDDED; } else if (lfi) for (auto& fstr : lfi->embeddings) { - if (!stricmp(FullName.c_str(), fstr.c_str())) + if (!stricmp(FullName, fstr.c_str())) { Flags |= LUMPF_EMBEDDED; } @@ -265,18 +270,18 @@ int FResourceLump::Unlock() // //========================================================================== -typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +typedef FResourceFile * (*CheckFunc)(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); -FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -FResourceFile* CheckWHRes(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -FResourceFile *CheckLump(const char *filename,FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf); -FResourceFile *CheckDir(const char *filename, bool nosub, LumpFilterInfo* filter, FileSystemMessageFunc Printf); +FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile* CheckWHRes(const char* filename, FileReader& file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckLump(const char *filename,FileReader &file, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); +FResourceFile *CheckDir(const char *filename, bool nosub, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); static CheckFunc funcs[] = { CheckWad, CheckZip, Check7Z, CheckPak, CheckGRP, CheckRFF, CheckSSI, CheckWHRes, CheckLump }; @@ -285,35 +290,35 @@ static int nulPrintf(FSMessageLevel msg, const char* fmt, ...) return 0; } -FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *FResourceFile::DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { if (Printf == nullptr) Printf = nulPrintf; for(auto func : funcs) { if (containeronly && func == CheckLump) break; - FResourceFile *resfile = func(filename, file, filter, Printf); + FResourceFile *resfile = func(filename, file, filter, Printf, sp); if (resfile != NULL) return resfile; } return NULL; } -FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *FResourceFile::OpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { - return DoOpenResourceFile(filename, file, containeronly, filter, Printf); + return DoOpenResourceFile(filename, file, containeronly, filter, Printf, sp); } -FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *FResourceFile::OpenResourceFile(const char *filename, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { FileReader file; if (!file.OpenFile(filename)) return nullptr; - return DoOpenResourceFile(filename, file, containeronly, filter, Printf); + return DoOpenResourceFile(filename, file, containeronly, filter, Printf, sp); } -FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo* filter, FileSystemMessageFunc Printf) +FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp) { if (Printf == nullptr) Printf = nulPrintf; - return CheckDir(filename, false, filter, Printf); + return CheckDir(filename, false, filter, Printf, sp); } //========================================================================== @@ -322,19 +327,21 @@ FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo // //========================================================================== -FResourceFile::FResourceFile(const char *filename) +FResourceFile::FResourceFile(const char *filename, StringPool* sp) : FileName(filename) { + stringpool = sp ? sp : new StringPool; } -FResourceFile::FResourceFile(const char *filename, FileReader &r) - : FResourceFile(filename) +FResourceFile::FResourceFile(const char *filename, FileReader &r, StringPool* sp) + : FResourceFile(filename,sp) { Reader = std::move(r); } FResourceFile::~FResourceFile() { + if (!stringpool->shared) delete stringpool; } int lumpcmp(const void * a, const void * b) @@ -368,7 +375,7 @@ void FResourceFile::GenerateHash() for(uint32_t i = 0; i < NumLumps; i++) { auto lump = GetLump(i); - md5_append(&state, (const uint8_t*)lump->FullName.c_str(), (unsigned)lump->FullName.length() + 1); + md5_append(&state, (const uint8_t*)lump->FullName, (unsigned)strlen(lump->FullName) + 1); md5_append(&state, (const uint8_t*)&lump->LumpSize, 4); } md5_finish(&state, digest); @@ -453,8 +460,8 @@ int FResourceFile::FilterLumps(const std::string& filtername, void *lumps, size_ for (uint32_t i = start; i < end; ++i, lump_p = (uint8_t *)lump_p + lumpsize) { FResourceLump *lump = (FResourceLump *)lump_p; - assert(strnicmp(lump->FullName.c_str(), filter.c_str(), filter.length()) == 0); - lump->LumpNameSetup(lump->FullName.c_str() + filter.length()); + assert(strnicmp(lump->FullName, filter.c_str(), filter.length()) == 0); + lump->LumpNameSetup(lump->FullName + filter.length(), nullptr); } // Move filtered lumps to the end of the lump list. @@ -523,7 +530,7 @@ void FResourceFile::JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t m for (void *p = (uint8_t *)lumps + start * lumpsize; p < stop; p = (uint8_t *)p + lumpsize) { FResourceLump *lump = (FResourceLump *)p; - lump->FullName = ""; + lump->clearName(); } } } @@ -556,7 +563,7 @@ bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lump { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); + cmp = strnicmp(lump->FullName, filter, (int)strlen(filter)); if (cmp == 0) break; else if (cmp < 0) @@ -576,7 +583,7 @@ bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lump { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); + cmp = strnicmp(lump->FullName, filter, (int)strlen(filter)); // Go left on matches and right on misses. if (cmp == 0) max = mid - 1; @@ -591,7 +598,7 @@ bool FResourceFile::FindPrefixRange(const char* filter, void *lumps, size_t lump { mid = min + (max - min) / 2; lump = (FResourceLump *)((uint8_t *)lumps + mid * lumpsize); - cmp = strnicmp(lump->FullName.c_str(), filter, (int)strlen(filter)); + cmp = strnicmp(lump->FullName, filter, (int)strlen(filter)); // Go right on matches and left on misses. if (cmp == 0) min = mid + 1; @@ -613,7 +620,7 @@ FResourceLump *FResourceFile::FindLump(const char *name) for (unsigned i = 0; i < NumLumps; i++) { FResourceLump *lump = GetLump(i); - if (!stricmp(name, lump->FullName.c_str())) + if (!stricmp(name, lump->FullName)) { return lump; } @@ -670,12 +677,12 @@ int FUncompressedLump::FillCache() // //========================================================================== -FUncompressedFile::FUncompressedFile(const char *filename) -: FResourceFile(filename) +FUncompressedFile::FUncompressedFile(const char *filename, StringPool* sp) +: FResourceFile(filename, sp) {} -FUncompressedFile::FUncompressedFile(const char *filename, FileReader &r) - : FResourceFile(filename, r) +FUncompressedFile::FUncompressedFile(const char *filename, FileReader &r, StringPool* sp) + : FResourceFile(filename, r, sp) {} diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index 2345f332f..6acf0b89b 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -114,7 +114,7 @@ struct FResourceLump int LumpSize; int RefCount; protected: - std::string FullName; + const char* FullName; public: uint8_t Flags; char * Cache; @@ -126,6 +126,7 @@ public: Owner = NULL; Flags = 0; RefCount = 0; + FullName = ""; } virtual ~FResourceLump(); @@ -134,7 +135,7 @@ public: virtual int GetFileOffset() { return -1; } virtual int GetIndexNum() const { return -1; } virtual int GetNamespace() const { return 0; } - void LumpNameSetup(const char* iname); + void LumpNameSetup(const char* iname, StringPool* allocator); void CheckEmbedded(LumpFilterInfo* lfi); virtual FCompressedBuffer GetRawData(); @@ -143,7 +144,8 @@ public: unsigned Size() const{ return LumpSize; } int LockCount() const { return RefCount; } - const char* getName() { return FullName.c_str(); } + const char* getName() { return FullName; } + void clearName() { FullName = ""; } protected: virtual int FillCache() { return -1; } @@ -158,9 +160,10 @@ public: protected: uint32_t NumLumps; char Hash[48]; + StringPool* stringpool; - FResourceFile(const char *filename); - FResourceFile(const char *filename, FileReader &r); + FResourceFile(const char *filename, StringPool* sp); + FResourceFile(const char *filename, FileReader &r, StringPool* sp); // for archives that can contain directories void GenerateHash(); @@ -173,12 +176,12 @@ private: int FilterLumpsByGameType(LumpFilterInfo *filter, void *lumps, size_t lumpsize, uint32_t max); bool FindPrefixRange(const char* filter, void *lumps, size_t lumpsize, uint32_t max, uint32_t &start, uint32_t &end); void JunkLeftoverFilters(void *lumps, size_t lumpsize, uint32_t max); - static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf); + static FResourceFile *DoOpenResourceFile(const char *filename, FileReader &file, bool containeronly, LumpFilterInfo* filter, FileSystemMessageFunc Printf, StringPool* sp); public: - static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr); - static FResourceFile *OpenResourceFile(const char *filename, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr); - static FResourceFile *OpenDirectory(const char *filename, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr); + static FResourceFile *OpenResourceFile(const char *filename, FileReader &file, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, StringPool* sp = nullptr); + static FResourceFile *OpenResourceFile(const char *filename, bool containeronly = false, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, StringPool* sp = nullptr); + static FResourceFile *OpenDirectory(const char *filename, LumpFilterInfo* filter = nullptr, FileSystemMessageFunc Printf = nullptr, StringPool* sp = nullptr); virtual ~FResourceFile(); // If this FResourceFile represents a directory, the Reader object is not usable so don't return it. FileReader *GetReader() { return Reader.isOpen()? &Reader : nullptr; } @@ -209,8 +212,8 @@ class FUncompressedFile : public FResourceFile protected: TArray Lumps; - FUncompressedFile(const char *filename); - FUncompressedFile(const char *filename, FileReader &r); + FUncompressedFile(const char *filename, StringPool* sp); + FUncompressedFile(const char *filename, FileReader &r, StringPool* sp); virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } }; From 6d2047eef6e031587c5f8418bb127d494d8779de Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 01:08:14 +0200 Subject: [PATCH 038/223] - also use the stringpool for the lump names in the filesystem. --- src/common/filesystem/filesystem.cpp | 106 ++++++++++++++------------- 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 057493719..6a0049fc8 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -89,13 +89,13 @@ struct FileSystem::LumpRecord { FResourceLump *lump; LumpShortName shortName; - std::string longName; + const char* LongName; int rfnum; int Namespace; int resourceId; int flags; - void SetFromLump(int filenum, FResourceLump* lmp) + void SetFromLump(int filenum, FResourceLump* lmp, StringPool* sp) { lump = lmp; rfnum = filenum; @@ -105,47 +105,48 @@ struct FileSystem::LumpRecord { UpperCopy(shortName.String, lump->getName()); shortName.String[8] = 0; - longName = ""; + LongName = ""; Namespace = lump->GetNamespace(); resourceId = -1; } else if ((lump->Flags & LUMPF_EMBEDDED) || !lump->getName() || !*lump->getName()) { shortName.qword = 0; - longName = ""; + LongName = ""; Namespace = ns_hidden; resourceId = -1; } else { - longName = lump->getName(); + LongName = lump->getName(); resourceId = lump->GetIndexNum(); // Map some directories to WAD namespaces. // Note that some of these namespaces don't exist in WADS. // CheckNumForName will handle any request for these namespaces accordingly. - Namespace = !strncmp(longName.c_str(), "flats/", 6) ? ns_flats : - !strncmp(longName.c_str(), "textures/", 9) ? ns_newtextures : - !strncmp(longName.c_str(), "hires/", 6) ? ns_hires : - !strncmp(longName.c_str(), "sprites/", 8) ? ns_sprites : - !strncmp(longName.c_str(), "voxels/", 7) ? ns_voxels : - !strncmp(longName.c_str(), "colormaps/", 10) ? ns_colormaps : - !strncmp(longName.c_str(), "acs/", 4) ? ns_acslibrary : - !strncmp(longName.c_str(), "voices/", 7) ? ns_strifevoices : - !strncmp(longName.c_str(), "patches/", 8) ? ns_patches : - !strncmp(longName.c_str(), "graphics/", 9) ? ns_graphics : - !strncmp(longName.c_str(), "sounds/", 7) ? ns_sounds : - !strncmp(longName.c_str(), "music/", 6) ? ns_music : - !strchr(longName.c_str(), '/') ? ns_global : + Namespace = !strncmp(LongName, "flats/", 6) ? ns_flats : + !strncmp(LongName, "textures/", 9) ? ns_newtextures : + !strncmp(LongName, "hires/", 6) ? ns_hires : + !strncmp(LongName, "sprites/", 8) ? ns_sprites : + !strncmp(LongName, "voxels/", 7) ? ns_voxels : + !strncmp(LongName, "colormaps/", 10) ? ns_colormaps : + !strncmp(LongName, "acs/", 4) ? ns_acslibrary : + !strncmp(LongName, "voices/", 7) ? ns_strifevoices : + !strncmp(LongName, "patches/", 8) ? ns_patches : + !strncmp(LongName, "graphics/", 9) ? ns_graphics : + !strncmp(LongName, "sounds/", 7) ? ns_sounds : + !strncmp(LongName, "music/", 6) ? ns_music : + !strchr(LongName, '/') ? ns_global : ns_hidden; if (Namespace == ns_hidden) shortName.qword = 0; - else + else if (strstr(LongName, ".{")) { + std::string longName = LongName; ptrdiff_t encodedResID = longName.find_last_of(".{"); if (resourceId == -1 && encodedResID != std::string::npos) { - const char* p = longName.c_str() + encodedResID; + const char* p = LongName + encodedResID; char* q; int id = (int)strtoull(p+2, &q, 10); // only decimal numbers allowed here. if (q[0] == '}' && (q[1] == '.' || q[1] == 0)) @@ -153,9 +154,10 @@ struct FileSystem::LumpRecord longName.erase(longName.begin() + encodedResID, longName.begin() + (q - p) + 1); resourceId = id; } + LongName = sp->Strdup(longName.c_str()); } ptrdiff_t slash = longName.find_last_of('/'); - std::string base = (slash != std::string::npos) ? longName.c_str() + (slash + 1) : longName.c_str(); + std::string base = (slash != std::string::npos) ? LongName + (slash + 1) : LongName; auto dot = base.find_last_of('.'); if (dot != std::string::npos) base.resize(dot); UpperCopy(shortName.String, base.c_str()); @@ -293,7 +295,7 @@ bool FileSystem::InitMultipleFiles (std::vector& filenames, LumpFil void FileSystem::AddLump(FResourceLump *lump) { FileInfo.resize(FileInfo.size() + 1); - FileInfo.back().SetFromLump(-1, lump); + FileInfo.back().SetFromLump(-1, lump, stringpool); } //----------------------------------------------------------------------- @@ -398,7 +400,7 @@ void FileSystem::AddFile (const char *filename, FileReader *filer, LumpFilterInf FResourceLump *lump = resfile->GetLump(i); FileInfo.resize(FileInfo.size() + 1); FileSystem::LumpRecord* lump_p = &FileInfo.back(); - lump_p->SetFromLump((int)Files.size(), lump); + lump_p->SetFromLump((int)Files.size(), lump, stringpool); } Files.push_back(resfile); @@ -631,12 +633,12 @@ int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int names for (i = fli[MakeHash(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) { - if (strnicmp(name, FileInfo[i].longName.c_str(), len)) continue; - if (FileInfo[i].longName[len] == 0) break; // this is a full match - if (ignoreext && FileInfo[i].longName[len] == '.') + if (strnicmp(name, FileInfo[i].LongName, len)) continue; + if (FileInfo[i].LongName[len] == 0) break; // this is a full match + if (ignoreext && FileInfo[i].LongName[len] == '.') { // is this the last '.' in the last path element, indicating that the remaining part of the name is only an extension? - if (strpbrk(FileInfo[i].longName.c_str() + len + 1, "./") == nullptr) break; + if (strpbrk(FileInfo[i].LongName + len + 1, "./") == nullptr) break; } } @@ -661,7 +663,7 @@ int FileSystem::CheckNumForFullName (const char *name, int rfnum) i = FirstLumpIndex_FullName[MakeHash (name) % NumEntries]; while (i != NULL_INDEX && - (stricmp(name, FileInfo[i].longName.c_str()) || FileInfo[i].rfnum != rfnum)) + (stricmp(name, FileInfo[i].LongName) || FileInfo[i].rfnum != rfnum)) { i = NextLumpIndex_FullName[i]; } @@ -712,10 +714,10 @@ int FileSystem::FindFileWithExtensions(const char* name, const char *const *exts for (i = fli[MakeHash(name) % NumEntries]; i != NULL_INDEX; i = nli[i]) { - if (strnicmp(name, FileInfo[i].longName.c_str(), len)) continue; - if (FileInfo[i].longName[len] != '.') continue; // we are looking for extensions but this file doesn't have one. + if (strnicmp(name, FileInfo[i].LongName, len)) continue; + if (FileInfo[i].LongName[len] != '.') continue; // we are looking for extensions but this file doesn't have one. - auto cp = FileInfo[i].longName.c_str() + len + 1; + auto cp = FileInfo[i].LongName + len + 1; // is this the last '.' in the last path element, indicating that the remaining part of the name is only an extension? if (strpbrk(cp, "./") != nullptr) continue; // No, so it cannot be a valid entry. @@ -751,7 +753,7 @@ int FileSystem::FindResource (int resid, const char *type, int filenum) const no { if (filenum > 0 && FileInfo[i].rfnum != filenum) continue; if (FileInfo[i].resourceId != resid) continue; - auto extp = strrchr(FileInfo[i].longName.c_str(), '.'); + auto extp = strrchr(FileInfo[i].LongName, '.'); if (!extp) continue; if (!stricmp(extp + 1, type)) return i; } @@ -865,13 +867,13 @@ void FileSystem::InitHashChains (void) FirstLumpIndex[j] = i; // Do the same for the full paths - if (!FileInfo[i].longName.empty()) + if (FileInfo[i].LongName[0] != 0) { - j = MakeHash(FileInfo[i].longName.c_str()) % NumEntries; + j = MakeHash(FileInfo[i].LongName) % NumEntries; NextLumpIndex_FullName[i] = FirstLumpIndex_FullName[j]; FirstLumpIndex_FullName[j] = i; - auto nameNoExt = FileInfo[i].longName; + std::string nameNoExt = FileInfo[i].LongName; auto dot = nameNoExt.find_last_of('.'); auto slash = nameNoExt.find_last_of('/'); if ((dot > slash || slash == std::string::npos) && dot != std::string::npos) nameNoExt.resize(dot); @@ -906,7 +908,7 @@ LumpShortName& FileSystem::GetShortName(int i) void FileSystem::RenameFile(int num, const char* newfn) { if ((unsigned)num >= NumEntries) throw FileSystemException("RenameFile: Invalid index"); - FileInfo[num].longName = newfn; + FileInfo[num].LongName = stringpool->Strdup(newfn); // This does not alter the short name - call GetShortname to do that! } @@ -940,13 +942,13 @@ void FileSystem::MoveLumpsInFolder(const char *path) { auto& li = FileInfo[i]; if (li.rfnum >= GetIwadNum()) break; - if (strnicmp(li.longName.c_str(), path, len) == 0) + if (strnicmp(li.LongName, path, len) == 0) { FileInfo.push_back(li); li.lump = &placeholderLump; // Make the old entry point to something empty. We cannot delete the lump record here because it'd require adjustment of all indices in the list. auto &ln = FileInfo.back(); - ln.lump->LumpNameSetup(ln.longName.c_str() + len, stringpool); // may be able to avoid the string allocation! - ln.SetFromLump(rfnum, ln.lump); + ln.lump->LumpNameSetup(ln.LongName + len, stringpool); // may be able to avoid the string allocation! + ln.SetFromLump(rfnum, ln.lump, stringpool); } } } @@ -1045,7 +1047,7 @@ int FileSystem::FindLumpFullName(const char* name, int* lastlump, bool noext) { while (lump_p <= &FileInfo.back()) { - if (!stricmp(name, lump_p->longName.c_str())) + if (!stricmp(name, lump_p->LongName)) { int lump = int(lump_p - FileInfo.data()); *lastlump = lump + 1; @@ -1059,10 +1061,10 @@ int FileSystem::FindLumpFullName(const char* name, int* lastlump, bool noext) auto len = strlen(name); while (lump_p <= &FileInfo.back()) { - auto res = strnicmp(name, lump_p->longName.c_str(), len); + auto res = strnicmp(name, lump_p->LongName, len); if (res == 0) { - auto p = lump_p->longName.c_str() + len; + auto p = lump_p->LongName + len; if (*p == 0 || (*p == '.' && strpbrk(p + 1, "./") == 0)) { int lump = int(lump_p - FileInfo.data()); @@ -1119,8 +1121,8 @@ const char *FileSystem::GetFileFullName (int lump, bool returnshort) const { if ((size_t)lump >= NumEntries) return NULL; - else if (!FileInfo[lump].longName.empty()) - return FileInfo[lump].longName.c_str(); + else if (FileInfo[lump].LongName[0] != 0) + return FileInfo[lump].LongName; else if (returnshort) return FileInfo[lump].shortName.String; else return nullptr; @@ -1198,7 +1200,7 @@ const char *FileSystem::GetResourceType(int lump) const return nullptr; else { - auto p = strrchr(FileInfo[lump].longName.c_str(), '.'); + auto p = strrchr(FileInfo[lump].LongName, '.'); if (!p) return ""; // has no extension if (strchr(p, '/')) return ""; // the '.' is part of a directory. return p + 1; @@ -1250,12 +1252,12 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, std::vector Date: Tue, 22 Aug 2023 18:48:11 +0200 Subject: [PATCH 039/223] - use the string pool for storing resource file names. --- src/common/filesystem/file_7z.cpp | 4 ++-- src/common/filesystem/file_directory.cpp | 10 ++++++---- src/common/filesystem/file_lump.cpp | 2 +- src/common/filesystem/file_wad.cpp | 24 ++++++++++++------------ src/common/filesystem/file_zip.cpp | 16 ++++++++-------- src/common/filesystem/filesystem.cpp | 4 ++-- src/common/filesystem/resourcefile.cpp | 6 +++--- src/common/filesystem/resourcefile.h | 2 +- 8 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/common/filesystem/file_7z.cpp b/src/common/filesystem/file_7z.cpp index 391a8aab2..262dd370d 100644 --- a/src/common/filesystem/file_7z.cpp +++ b/src/common/filesystem/file_7z.cpp @@ -227,7 +227,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) Archive = NULL; if (res == SZ_ERROR_UNSUPPORTED) { - Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", File_Name); } else if (res == SZ_ERROR_MEM) { @@ -300,7 +300,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0])) { - Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", File_Name); return false; } } diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/file_directory.cpp index a99e6fb56..cbb79b446 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/file_directory.cpp @@ -38,6 +38,7 @@ #include "resourcefile.h" #include "fs_findfile.h" +#include "fs_stringpool.h" std::string FS_FullPath(const char* directory); @@ -91,8 +92,9 @@ public: FDirectory::FDirectory(const char * directory, StringPool* sp, bool nosubdirflag) : FResourceFile("", sp), nosubdir(nosubdirflag) { - FileName = FS_FullPath(directory); - if (FileName[FileName.length()-1] != '/') FileName += '/'; + auto fn = FS_FullPath(directory); + if (fn.back() != '/') fn += '/'; + File_Name = sp->Strdup(fn.c_str()); } //========================================================================== @@ -148,7 +150,7 @@ int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSy bool FDirectory::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) { - NumLumps = AddDirectory(FileName.c_str(), filter, Printf); + NumLumps = AddDirectory(File_Name, filter, Printf); PostProcessArchive(&Lumps[0], sizeof(FDirectoryLump), filter); return true; } @@ -167,7 +169,7 @@ void FDirectory::AddEntry(const char *fullpath, int size) lump_p->mFullPath = fullpath; // [mxd] Convert name to lowercase - std::string name = fullpath + FileName.length(); + std::string name = fullpath + strlen(File_Name); for (auto& c : name) c = tolower(c); // The lump's name is only the part relative to the main directory diff --git a/src/common/filesystem/file_lump.cpp b/src/common/filesystem/file_lump.cpp index 540ee6dd7..962482c83 100644 --- a/src/common/filesystem/file_lump.cpp +++ b/src/common/filesystem/file_lump.cpp @@ -68,7 +68,7 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file, StringPool* sp) bool FLumpFile::Open(LumpFilterInfo*) { Lumps.Resize(1); - Lumps[0].LumpNameSetup(ExtractBaseName(FileName.c_str(), true).c_str(), stringpool); + Lumps[0].LumpNameSetup(ExtractBaseName(File_Name, true).c_str(), stringpool); Lumps[0].Owner = this; Lumps[0].Position = 0; Lumps[0].LumpSize = (int)Reader.GetLength(); diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/file_wad.cpp index badcc271f..b79c13cb0 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/file_wad.cpp @@ -183,7 +183,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) // Check again to detect broken wads if (InfoTableOfs + NumLumps*sizeof(wadlump_t) > (unsigned)wadSize) { - Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", File_Name); return false; } } @@ -220,7 +220,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) { if (Lumps[i].LumpSize != 0) { - Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName.c_str(), Lumps[i].getName()); + Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", File_Name, Lumps[i].getName()); Lumps[i].clearName(); } Lumps[i].LumpSize = Lumps[i].Position = 0; @@ -305,7 +305,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { if (numendmarkers == 0) return; // no markers found - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", File_Name, endmarker, startmarker); if (flathack) @@ -319,7 +319,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { // We can't add this to the flats namespace but // it needs to be flagged for the texture manager. - Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", FileName.c_str(), Lumps[ii].getName()); + Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", File_Name, Lumps[ii].getName()); Lumps[ii].Flags |= LUMPF_MAYBEFLAT; } } @@ -333,7 +333,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name int start, end; if (markers[i].markertype != 0) { - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", File_Name, endmarker, startmarker); i++; continue; } @@ -342,21 +342,21 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // skip over subsequent x_START markers while (i < markers.Size() && markers[i].markertype == 0) { - Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.c_str(), startmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", File_Name, startmarker); i++; continue; } // same for x_END markers while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1)) { - Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName.c_str(), endmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", File_Name, endmarker); i++; continue; } // We found a starting marker but no end marker. Ignore this block. if (i >= markers.Size()) { - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName.c_str(), startmarker, endmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", File_Name, startmarker, endmarker); end = NumLumps; } else @@ -365,14 +365,14 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name } // we found a marked block - Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", FileName.c_str(), startmarker, markers[start].index, end); + Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", File_Name, startmarker, markers[start].index, end); for(int j = markers[start].index + 1; j < end; j++) { if (Lumps[j].Namespace != ns_global) { if (!warned) { - Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", FileName.c_str(), j); + Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", File_Name, j); } warned = true; } @@ -382,7 +382,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // ignore sprite lumps smaller than 8 bytes (the smallest possible) // in size -- this was used by some dmadds wads // as an 'empty' graphics resource - Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", FileName.c_str(), Lumps[j].getName(), j); + Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", File_Name, Lumps[j].getName(), j); } else { @@ -452,7 +452,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf) } if (skinned && hasmap) { - Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", FileName.c_str()); + Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", File_Name); Printf(FSMessageLevel::Attention, "You should remove the skin from the wad to play these maps.\n"); } } diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index 175c53e18..c2acb10f7 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -180,7 +180,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (centraldir == 0) { - Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", File_Name); return false; } @@ -196,7 +196,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", File_Name); return false; } @@ -215,7 +215,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", File_Name); return false; } @@ -254,7 +254,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", File_Name); return false; } @@ -323,7 +323,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName.c_str()); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", File_Name); return false; } @@ -350,7 +350,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Method != METHOD_IMPLODE && zip_fh->Method != METHOD_SHRINK) { - Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName.c_str(), name.c_str(), zip_fh->Method); + Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", File_Name, name.c_str(), zip_fh->Method); skipped++; continue; } @@ -358,7 +358,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Flags = LittleShort(zip_fh->Flags); if (zip_fh->Flags & ZF_ENCRYPTED) { - Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName.c_str(), name.c_str()); + Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", File_Name, name.c_str()); skipped++; continue; } @@ -385,7 +385,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (zip_64->CompressedSize > 0x7fffffff || zip_64->UncompressedSize > 0x7fffffff) { // The file system is limited to 32 bit file sizes; - Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName.c_str(), name.c_str()); + Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", File_Name, name.c_str()); skipped++; continue; } diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 6a0049fc8..39a730b7d 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -1419,7 +1419,7 @@ const char *FileSystem::GetResourceFileName (int rfnum) const noexcept return NULL; } - name = Files[rfnum]->FileName.c_str(); + name = Files[rfnum]->File_Name; slash = strrchr (name, '/'); return (slash != nullptr && slash[1] != 0) ? slash+1 : name; } @@ -1485,7 +1485,7 @@ const char *FileSystem::GetResourceFileFullName (int rfnum) const noexcept return nullptr; } - return Files[rfnum]->FileName.c_str(); + return Files[rfnum]->File_Name; } diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index 5f044371f..0a92fe7da 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -154,7 +154,7 @@ static bool IsWadInFolder(const FResourceFile* const archive, const char* const return false; } - const auto dirName = ExtractBaseName(archive->FileName.c_str()); + const auto dirName = ExtractBaseName(archive->File_Name); const auto fileName = ExtractBaseName(resPath, true); const std::string filePath = dirName + '/' + fileName; @@ -239,7 +239,7 @@ void *FResourceLump::Lock() catch (const FileSystemException& err) { // enrich the message with info about this lump. - throw FileSystemException("%s, file '%s': %s", getName(), Owner->FileName.c_str(), err.what()); + throw FileSystemException("%s, file '%s': %s", getName(), Owner->File_Name, err.what()); } } return Cache; @@ -328,9 +328,9 @@ FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo //========================================================================== FResourceFile::FResourceFile(const char *filename, StringPool* sp) - : FileName(filename) { stringpool = sp ? sp : new StringPool; + File_Name = stringpool->Strdup(filename); } FResourceFile::FResourceFile(const char *filename, FileReader &r, StringPool* sp) diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index 6acf0b89b..b73d082c1 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -156,7 +156,7 @@ class FResourceFile { public: FileReader Reader; - std::string FileName; + const char* File_Name; protected: uint32_t NumLumps; char Hash[48]; From 8e250abe0adb0b04868633f9366b4e7811c8e090 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 19:11:08 +0200 Subject: [PATCH 040/223] - fix lump name setup. --- src/common/filesystem/filesystem.cpp | 33 ++++++++++++++-------------- src/d_iwad.cpp | 2 +- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 39a730b7d..f7150b28e 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -148,7 +148,7 @@ struct FileSystem::LumpRecord { const char* p = LongName + encodedResID; char* q; - int id = (int)strtoull(p+2, &q, 10); // only decimal numbers allowed here. + int id = (int)strtoull(p + 2, &q, 10); // only decimal numbers allowed here. if (q[0] == '}' && (q[1] == '.' || q[1] == 0)) { longName.erase(longName.begin() + encodedResID, longName.begin() + (q - p) + 1); @@ -156,24 +156,23 @@ struct FileSystem::LumpRecord } LongName = sp->Strdup(longName.c_str()); } - ptrdiff_t slash = longName.find_last_of('/'); - std::string base = (slash != std::string::npos) ? LongName + (slash + 1) : LongName; - auto dot = base.find_last_of('.'); - if (dot != std::string::npos) base.resize(dot); - UpperCopy(shortName.String, base.c_str()); - shortName.String[8] = 0; + } + auto slash = strrchr(LongName, '/'); + std::string base = slash ? (slash + 1) : LongName; + auto dot = base.find_last_of('.'); + if (dot != std::string::npos) base.resize(dot); + UpperCopy(shortName.String, base.c_str()); - // Since '\' can't be used as a file name's part inside a ZIP - // we have to work around this for sprites because it is a valid - // frame character. - if (Namespace == ns_sprites || Namespace == ns_voxels || Namespace == ns_hires) + // Since '\' can't be used as a file name's part inside a ZIP + // we have to work around this for sprites because it is a valid + // frame character. + if (Namespace == ns_sprites || Namespace == ns_voxels || Namespace == ns_hires) + { + char* c; + + while ((c = (char*)memchr(shortName.String, '^', 8))) { - char* c; - - while ((c = (char*)memchr(shortName.String, '^', 8))) - { - *c = '\\'; - } + *c = '\\'; } } } diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index cf46eec13..88cc0032e 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -608,7 +608,7 @@ int FIWadManager::IdentifyVersion (std::vector&wadfiles, const char // Check for symbolic links leading to non-existent files and for files that are unreadable. for (unsigned int i = 0; i < mFoundWads.Size(); i++) { - if (!FileExists(mFoundWads[i].mFullPath) || !FileReadable(mFoundWads[i].mFullPath)) mFoundWads.Delete(i); + if (!FileExists(mFoundWads[i].mFullPath) || !FileReadable(mFoundWads[i].mFullPath)) mFoundWads.Delete(i--); } // Now check if what got collected actually is an IWAD. From 929cae2f411f3847d19dad19d18037a5e388c844 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 19:56:38 +0200 Subject: [PATCH 041/223] - rename File_Name back. --- src/common/filesystem/file_7z.cpp | 4 ++-- src/common/filesystem/file_directory.cpp | 6 +++--- src/common/filesystem/file_lump.cpp | 2 +- src/common/filesystem/file_wad.cpp | 24 ++++++++++++------------ src/common/filesystem/file_zip.cpp | 16 ++++++++-------- src/common/filesystem/filesystem.cpp | 4 ++-- src/common/filesystem/resourcefile.cpp | 6 +++--- src/common/filesystem/resourcefile.h | 2 +- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/common/filesystem/file_7z.cpp b/src/common/filesystem/file_7z.cpp index 262dd370d..abf67fded 100644 --- a/src/common/filesystem/file_7z.cpp +++ b/src/common/filesystem/file_7z.cpp @@ -227,7 +227,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) Archive = NULL; if (res == SZ_ERROR_UNSUPPORTED) { - Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", File_Name); + Printf(FSMessageLevel::Error, "%s: Decoder does not support this archive\n", FileName); } else if (res == SZ_ERROR_MEM) { @@ -300,7 +300,7 @@ bool F7ZFile::Open(LumpFilterInfo *filter, FileSystemMessageFunc Printf) if (SZ_OK != Archive->Extract(Lumps[0].Position, &temp[0])) { - Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", File_Name); + Printf(FSMessageLevel::Error, "%s: unsupported 7z/LZMA file!\n", FileName); return false; } } diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/file_directory.cpp index cbb79b446..f9b24da3a 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/file_directory.cpp @@ -94,7 +94,7 @@ FDirectory::FDirectory(const char * directory, StringPool* sp, bool nosubdirflag { auto fn = FS_FullPath(directory); if (fn.back() != '/') fn += '/'; - File_Name = sp->Strdup(fn.c_str()); + FileName = sp->Strdup(fn.c_str()); } //========================================================================== @@ -150,7 +150,7 @@ int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSy bool FDirectory::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) { - NumLumps = AddDirectory(File_Name, filter, Printf); + NumLumps = AddDirectory(FileName, filter, Printf); PostProcessArchive(&Lumps[0], sizeof(FDirectoryLump), filter); return true; } @@ -169,7 +169,7 @@ void FDirectory::AddEntry(const char *fullpath, int size) lump_p->mFullPath = fullpath; // [mxd] Convert name to lowercase - std::string name = fullpath + strlen(File_Name); + std::string name = fullpath + strlen(FileName); for (auto& c : name) c = tolower(c); // The lump's name is only the part relative to the main directory diff --git a/src/common/filesystem/file_lump.cpp b/src/common/filesystem/file_lump.cpp index 962482c83..85f41d775 100644 --- a/src/common/filesystem/file_lump.cpp +++ b/src/common/filesystem/file_lump.cpp @@ -68,7 +68,7 @@ FLumpFile::FLumpFile(const char *filename, FileReader &file, StringPool* sp) bool FLumpFile::Open(LumpFilterInfo*) { Lumps.Resize(1); - Lumps[0].LumpNameSetup(ExtractBaseName(File_Name, true).c_str(), stringpool); + Lumps[0].LumpNameSetup(ExtractBaseName(FileName, true).c_str(), stringpool); Lumps[0].Owner = this; Lumps[0].Position = 0; Lumps[0].LumpSize = (int)Reader.GetLength(); diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/file_wad.cpp index b79c13cb0..60392dfb7 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/file_wad.cpp @@ -183,7 +183,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) // Check again to detect broken wads if (InfoTableOfs + NumLumps*sizeof(wadlump_t) > (unsigned)wadSize) { - Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", File_Name); + Printf(FSMessageLevel::Error, "%s: Bad directory offset.\n", FileName); return false; } } @@ -220,7 +220,7 @@ bool FWadFile::Open(LumpFilterInfo*, FileSystemMessageFunc Printf) { if (Lumps[i].LumpSize != 0) { - Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", File_Name, Lumps[i].getName()); + Printf(FSMessageLevel::Warning, "%s: Lump %s contains invalid positioning info and will be ignored\n", FileName, Lumps[i].getName()); Lumps[i].clearName(); } Lumps[i].LumpSize = Lumps[i].Position = 0; @@ -305,7 +305,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { if (numendmarkers == 0) return; // no markers found - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", File_Name, endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName, endmarker, startmarker); if (flathack) @@ -319,7 +319,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name { // We can't add this to the flats namespace but // it needs to be flagged for the texture manager. - Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", File_Name, Lumps[ii].getName()); + Printf(FSMessageLevel::DebugNotify, "%s: Marking %s as potential flat\n", FileName, Lumps[ii].getName()); Lumps[ii].Flags |= LUMPF_MAYBEFLAT; } } @@ -333,7 +333,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name int start, end; if (markers[i].markertype != 0) { - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", File_Name, endmarker, startmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName, endmarker, startmarker); i++; continue; } @@ -342,21 +342,21 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // skip over subsequent x_START markers while (i < markers.Size() && markers[i].markertype == 0) { - Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", File_Name, startmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName, startmarker); i++; continue; } // same for x_END markers while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1)) { - Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", File_Name, endmarker); + Printf(FSMessageLevel::Warning, "%s: duplicate %s marker found.\n", FileName, endmarker); i++; continue; } // We found a starting marker but no end marker. Ignore this block. if (i >= markers.Size()) { - Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", File_Name, startmarker, endmarker); + Printf(FSMessageLevel::Warning, "%s: %s marker without corresponding %s found.\n", FileName, startmarker, endmarker); end = NumLumps; } else @@ -365,14 +365,14 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name } // we found a marked block - Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", File_Name, startmarker, markers[start].index, end); + Printf(FSMessageLevel::DebugNotify, "%s: Found %s block at (%d-%d)\n", FileName, startmarker, markers[start].index, end); for(int j = markers[start].index + 1; j < end; j++) { if (Lumps[j].Namespace != ns_global) { if (!warned) { - Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", File_Name, j); + Printf(FSMessageLevel::Warning, "%s: Overlapping namespaces found (lump %d)\n", FileName, j); } warned = true; } @@ -382,7 +382,7 @@ void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, name // ignore sprite lumps smaller than 8 bytes (the smallest possible) // in size -- this was used by some dmadds wads // as an 'empty' graphics resource - Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", File_Name, Lumps[j].getName(), j); + Printf(FSMessageLevel::DebugWarn, "%s: Skipped empty sprite %s (lump %d)\n", FileName, Lumps[j].getName(), j); } else { @@ -452,7 +452,7 @@ void FWadFile::SkinHack (FileSystemMessageFunc Printf) } if (skinned && hasmap) { - Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", File_Name); + Printf(FSMessageLevel::Attention, "%s: The maps will not be loaded because it has a skin.\n", FileName); Printf(FSMessageLevel::Attention, "You should remove the skin from the wad to play these maps.\n"); } } diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/file_zip.cpp index c2acb10f7..f97f19656 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/file_zip.cpp @@ -180,7 +180,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (centraldir == 0) { - Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", File_Name); + Printf(FSMessageLevel::Error, "%s: ZIP file corrupt!\n", FileName); return false; } @@ -196,7 +196,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", File_Name); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName); return false; } @@ -215,7 +215,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (info.NumEntries != info.NumEntriesOnAllDisks || info.FirstDisk != 0 || info.DiskNumber != 0) { - Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", File_Name); + Printf(FSMessageLevel::Error, "%s: Multipart Zip files are not supported.\n", FileName); return false; } @@ -254,7 +254,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", File_Name); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName); return false; } @@ -323,7 +323,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (dirptr > ((char*)directory) + dirsize) // This directory entry goes beyond the end of the file. { free(directory); - Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", File_Name); + Printf(FSMessageLevel::Error, "%s: Central directory corrupted.", FileName); return false; } @@ -350,7 +350,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Method != METHOD_IMPLODE && zip_fh->Method != METHOD_SHRINK) { - Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", File_Name, name.c_str(), zip_fh->Method); + Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName, name.c_str(), zip_fh->Method); skipped++; continue; } @@ -358,7 +358,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Flags = LittleShort(zip_fh->Flags); if (zip_fh->Flags & ZF_ENCRYPTED) { - Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", File_Name, name.c_str()); + Printf(FSMessageLevel::Error, "%s: '%s' is encrypted. Encryption is not supported.\n", FileName, name.c_str()); skipped++; continue; } @@ -385,7 +385,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) if (zip_64->CompressedSize > 0x7fffffff || zip_64->UncompressedSize > 0x7fffffff) { // The file system is limited to 32 bit file sizes; - Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", File_Name, name.c_str()); + Printf(FSMessageLevel::Warning, "%s: '%s' is too large.\n", FileName, name.c_str()); skipped++; continue; } diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index f7150b28e..0589943b7 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -1418,7 +1418,7 @@ const char *FileSystem::GetResourceFileName (int rfnum) const noexcept return NULL; } - name = Files[rfnum]->File_Name; + name = Files[rfnum]->FileName; slash = strrchr (name, '/'); return (slash != nullptr && slash[1] != 0) ? slash+1 : name; } @@ -1484,7 +1484,7 @@ const char *FileSystem::GetResourceFileFullName (int rfnum) const noexcept return nullptr; } - return Files[rfnum]->File_Name; + return Files[rfnum]->FileName; } diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index 0a92fe7da..17dcbdd25 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -154,7 +154,7 @@ static bool IsWadInFolder(const FResourceFile* const archive, const char* const return false; } - const auto dirName = ExtractBaseName(archive->File_Name); + const auto dirName = ExtractBaseName(archive->FileName); const auto fileName = ExtractBaseName(resPath, true); const std::string filePath = dirName + '/' + fileName; @@ -239,7 +239,7 @@ void *FResourceLump::Lock() catch (const FileSystemException& err) { // enrich the message with info about this lump. - throw FileSystemException("%s, file '%s': %s", getName(), Owner->File_Name, err.what()); + throw FileSystemException("%s, file '%s': %s", getName(), Owner->FileName, err.what()); } } return Cache; @@ -330,7 +330,7 @@ FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo FResourceFile::FResourceFile(const char *filename, StringPool* sp) { stringpool = sp ? sp : new StringPool; - File_Name = stringpool->Strdup(filename); + FileName = stringpool->Strdup(filename); } FResourceFile::FResourceFile(const char *filename, FileReader &r, StringPool* sp) diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index b73d082c1..86e56970f 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -156,7 +156,7 @@ class FResourceFile { public: FileReader Reader; - const char* File_Name; + const char* FileName; protected: uint32_t NumLumps; char Hash[48]; From 94c9ee4593b17d3cc0397e9552eff26220e24aed Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 20:06:15 +0200 Subject: [PATCH 042/223] - got rid of the remaining persistent std::strings in the file system. This also uses the string pool now. --- src/common/filesystem/file_whres.cpp | 8 +++++--- src/common/filesystem/filesystem.cpp | 2 +- src/common/filesystem/resourcefile.cpp | 7 ++++--- src/common/filesystem/resourcefile.h | 5 +++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/common/filesystem/file_whres.cpp b/src/common/filesystem/file_whres.cpp index 8629e6a64..ba07945b3 100644 --- a/src/common/filesystem/file_whres.cpp +++ b/src/common/filesystem/file_whres.cpp @@ -35,6 +35,7 @@ */ #include "resourcefile.h" +#include "fs_stringpool.h" #include "fs_swap.h" using namespace fs_private; @@ -47,7 +48,7 @@ using namespace fs_private; class FWHResFile : public FUncompressedFile { - std::string basename; + const char* BaseName; public: FWHResFile(const char * filename, FileReader &file, StringPool* sp); bool Open(LumpFilterInfo* filter); @@ -63,7 +64,7 @@ public: FWHResFile::FWHResFile(const char *filename, FileReader &file, StringPool* sp) : FUncompressedFile(filename, file, sp) { - basename = ExtractBaseName(filename, false); + BaseName = stringpool->Strdup(ExtractBaseName(filename, false).c_str()); } //========================================================================== @@ -91,7 +92,8 @@ bool FWHResFile::Open(LumpFilterInfo*) if (length == 0) break; char num[5]; snprintf(num, 5, "/%04d", k); - std::string synthname = basename + num; + std::string synthname = BaseName; + synthname += num; Lumps[i].LumpNameSetup(synthname.c_str(), stringpool); Lumps[i].Owner = this; Lumps[i].Position = offset; diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/filesystem.cpp index 0589943b7..60a62697d 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/filesystem.cpp @@ -307,7 +307,7 @@ void FileSystem::AddLump(FResourceLump *lump) int FileSystem::AddExternalFile(const char *filename) { - FResourceLump *lump = new FExternalLump(filename); + FResourceLump *lump = new FExternalLump(filename, -1, stringpool); AddLump(lump); return (int)FileInfo.size() - 1; // later } diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/resourcefile.cpp index 17dcbdd25..6e7525591 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/resourcefile.cpp @@ -692,9 +692,10 @@ FUncompressedFile::FUncompressedFile(const char *filename, FileReader &r, String // //========================================================================== -FExternalLump::FExternalLump(const char *_filename, int filesize) - : Filename(_filename) +FExternalLump::FExternalLump(const char *_filename, int filesize, StringPool* stringpool) { + FileName = stringpool->Strdup(_filename); + if (filesize == -1) { FileReader f; @@ -727,7 +728,7 @@ int FExternalLump::FillCache() Cache = new char[LumpSize]; FileReader f; - if (f.OpenFile(Filename.c_str())) + if (f.OpenFile(FileName)) { auto read = f.Read(Cache, LumpSize); if (read != LumpSize) diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/resourcefile.h index 86e56970f..4619bbeb0 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/resourcefile.h @@ -218,11 +218,12 @@ protected: }; +// should only be used internally. struct FExternalLump : public FResourceLump { - std::string Filename; + const char* FileName; - FExternalLump(const char *_filename, int filesize = -1); + FExternalLump(const char *_filename, int filesize, StringPool* sp); virtual int FillCache() override; }; From ebb71cebf1313028ccff591e154541b5b2ff57d7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 21:20:28 +0200 Subject: [PATCH 043/223] - put the entire filesystem code into a namespace and created some subdirectories. --- src/CMakeLists.txt | 41 ++++++++++--------- src/common/audio/music/i_music.cpp | 5 ++- src/common/audio/music/i_soundfont.cpp | 7 ++-- src/common/audio/music/music.cpp | 1 + src/common/audio/music/s_music.h | 2 +- src/common/audio/sound/i_sound.h | 2 +- src/common/console/c_enginecmds.cpp | 4 +- src/common/engine/files.h | 6 +++ src/common/engine/filesystem.h | 7 ++++ src/common/engine/palettecontainer.h | 3 +- src/common/engine/serializer.cpp | 2 + src/common/engine/serializer.h | 5 +-- .../{files.h => include/fs_files.h} | 11 +++-- .../{filesystem.h => include/fs_filesystem.h} | 40 +++++++++--------- .../filesystem/{ => include}/fs_findfile.h | 3 ++ src/common/filesystem/{ => include}/fs_swap.h | 7 ++-- .../filesystem/{ => include}/resourcefile.h | 7 ++-- .../filesystem/{ => source}/ancientzip.cpp | 4 ++ .../filesystem/{ => source}/ancientzip.h | 7 +++- .../filesystem/{ => source}/file_7z.cpp | 5 ++- .../{ => source}/file_directory.cpp | 3 ++ .../filesystem/{ => source}/file_grp.cpp | 4 +- .../filesystem/{ => source}/file_lump.cpp | 2 + .../filesystem/{ => source}/file_pak.cpp | 4 +- .../filesystem/{ => source}/file_rff.cpp | 5 ++- .../filesystem/{ => source}/file_ssi.cpp | 3 ++ .../filesystem/{ => source}/file_wad.cpp | 7 ++-- .../filesystem/{ => source}/file_whres.cpp | 6 ++- .../filesystem/{ => source}/file_zip.cpp | 5 ++- src/common/filesystem/{ => source}/file_zip.h | 2 + src/common/filesystem/{ => source}/files.cpp | 8 ++-- .../{ => source}/files_decompress.cpp | 8 +++- .../filesystem/{ => source}/filesystem.cpp | 34 +++++++-------- .../filesystem/{ => source}/fs_findfile.cpp | 4 +- .../filesystem/{ => source}/fs_stringpool.cpp | 4 ++ .../filesystem/{ => source}/fs_stringpool.h | 2 + src/common/filesystem/{ => source}/md5.hpp | 2 +- .../filesystem/{ => source}/resourcefile.cpp | 6 ++- src/common/filesystem/{ => source}/w_zip.h | 3 ++ src/common/fonts/font.cpp | 4 +- src/common/fonts/hexfont.cpp | 2 +- src/common/fonts/singlelumpfont.cpp | 4 +- src/common/fonts/v_font.cpp | 2 +- src/common/fonts/v_font.h | 2 +- src/common/menu/menudef.cpp | 2 +- src/common/menu/savegamemanager.cpp | 4 +- src/common/models/model.cpp | 2 +- src/common/models/models_iqm.cpp | 2 +- src/common/models/models_md2.cpp | 4 +- src/common/models/models_md3.cpp | 2 +- src/common/models/models_ue1.cpp | 4 +- src/common/models/voxels.cpp | 2 +- src/common/rendering/gles/gles_shader.cpp | 4 +- src/common/rendering/v_video.h | 2 +- .../rendering/vulkan/shaders/vk_shader.cpp | 2 +- .../startscreen/startscreen_generic.cpp | 2 +- src/common/startscreen/startscreen_hexen.cpp | 6 +-- src/common/startscreen/startscreen_strife.cpp | 2 +- src/common/textures/formats/anmtexture.cpp | 2 +- .../textures/formats/automaptexture.cpp | 2 +- src/common/textures/formats/imgztexture.cpp | 2 +- src/common/textures/formats/patchtexture.cpp | 4 +- .../textures/formats/rawpagetexture.cpp | 6 +-- .../textures/formats/startuptexture.cpp | 12 +++--- src/common/textures/gametexture.cpp | 4 +- src/common/textures/m_png.h | 9 ++-- .../textures/multipatchtexturebuilder.cpp | 4 +- src/common/textures/texturemanager.cpp | 1 + src/common/utility/cmdlib.cpp | 2 +- src/common/utility/cmdlib.h | 2 +- src/common/utility/filereadermusicinterface.h | 1 + src/common/utility/findfile.cpp | 8 ++-- src/common/utility/palette.cpp | 2 +- src/common/utility/s_playlist.h | 2 +- src/common/utility/zstring.h | 3 +- src/d_iwad.cpp | 8 ++-- src/d_main.cpp | 2 + src/g_game.cpp | 4 +- src/g_level.cpp | 2 +- src/g_level.h | 2 +- src/gameconfigfile.h | 1 + src/gamedata/decallib.cpp | 2 +- src/gamedata/doomfont.h | 10 ++--- src/gamedata/g_mapinfo.cpp | 6 +-- src/gamedata/g_mapinfo.h | 3 +- src/gamedata/keysections.cpp | 2 +- src/gamedata/textures/anim_switches.cpp | 2 +- src/gamedata/textures/animations.cpp | 2 +- src/gamedata/textures/buildloader.cpp | 4 +- src/maploader/edata.cpp | 2 +- src/maploader/glnodes.cpp | 10 ++--- src/maploader/maploader.cpp | 8 ++-- src/maploader/maploader.h | 2 +- src/menu/loadsavemenu.cpp | 6 +-- src/p_conversation.h | 2 - src/p_setup.h | 2 +- src/playsim/fragglescript/t_func.cpp | 2 + src/playsim/p_acs.cpp | 4 +- src/playsim/p_acs.h | 2 +- src/playsim/p_user.cpp | 8 ++-- src/r_data/colormaps.cpp | 4 +- src/r_data/r_translate.cpp | 4 +- src/r_data/sprites.cpp | 10 ++--- src/r_data/v_palette.cpp | 2 + src/r_data/voxeldef.cpp | 2 + src/rendering/swrenderer/r_swcolormaps.cpp | 4 +- src/sound/s_advsound.cpp | 2 + src/sound/s_doomsound.cpp | 2 +- 108 files changed, 306 insertions(+), 223 deletions(-) create mode 100644 src/common/engine/files.h create mode 100644 src/common/engine/filesystem.h rename src/common/filesystem/{files.h => include/fs_files.h} (98%) rename src/common/filesystem/{filesystem.h => include/fs_filesystem.h} (83%) rename src/common/filesystem/{ => include}/fs_findfile.h (97%) rename src/common/filesystem/{ => include}/fs_swap.h (97%) rename src/common/filesystem/{ => include}/resourcefile.h (99%) rename src/common/filesystem/{ => source}/ancientzip.cpp (99%) rename src/common/filesystem/{ => source}/ancientzip.h (94%) rename src/common/filesystem/{ => source}/file_7z.cpp (99%) rename src/common/filesystem/{ => source}/file_directory.cpp (99%) rename src/common/filesystem/{ => source}/file_grp.cpp (98%) rename src/common/filesystem/{ => source}/file_lump.cpp (99%) rename src/common/filesystem/{ => source}/file_pak.cpp (98%) rename src/common/filesystem/{ => source}/file_rff.cpp (99%) rename src/common/filesystem/{ => source}/file_ssi.cpp (99%) rename src/common/filesystem/{ => source}/file_wad.cpp (99%) rename src/common/filesystem/{ => source}/file_whres.cpp (98%) rename src/common/filesystem/{ => source}/file_zip.cpp (99%) rename src/common/filesystem/{ => source}/file_zip.h (97%) rename src/common/filesystem/{ => source}/files.cpp (99%) rename src/common/filesystem/{ => source}/files_decompress.cpp (99%) rename src/common/filesystem/{ => source}/filesystem.cpp (98%) rename src/common/filesystem/{ => source}/fs_findfile.cpp (99%) rename src/common/filesystem/{ => source}/fs_stringpool.cpp (99%) rename src/common/filesystem/{ => source}/fs_stringpool.h (96%) rename src/common/filesystem/{ => source}/md5.hpp (99%) rename src/common/filesystem/{ => source}/resourcefile.cpp (99%) rename src/common/filesystem/{ => source}/w_zip.h (98%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 681a92016..35587dfa8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -581,7 +581,8 @@ file( GLOB HEADER_FILES common/statusbar/*.h common/fonts/*.h common/objects/*.h - common/filesystem/*.h + common/filesystem/include/*.h + common/filesystem/source/*.h common/platform/posix/cocoa/*.h common/platform/posix/sdl/*.h common/platform/win32/*.h @@ -1206,23 +1207,23 @@ set( ZDOOM_SOURCES common/thirdparty/math/tanh.c common/thirdparty/math/fastsin.cpp - common/filesystem/filesystem.cpp - common/filesystem/ancientzip.cpp - common/filesystem/file_7z.cpp - common/filesystem/file_grp.cpp - common/filesystem/file_lump.cpp - common/filesystem/file_rff.cpp - common/filesystem/file_wad.cpp - common/filesystem/file_zip.cpp - common/filesystem/file_pak.cpp - common/filesystem/file_whres.cpp - common/filesystem/file_ssi.cpp - common/filesystem/file_directory.cpp - common/filesystem/resourcefile.cpp - common/filesystem/files.cpp - common/filesystem/files_decompress.cpp - common/filesystem/fs_findfile.cpp - common/filesystem/fs_stringpool.cpp + common/filesystem/source/filesystem.cpp + common/filesystem/source/ancientzip.cpp + common/filesystem/source/file_7z.cpp + common/filesystem/source/file_grp.cpp + common/filesystem/source/file_lump.cpp + common/filesystem/source/file_rff.cpp + common/filesystem/source/file_wad.cpp + common/filesystem/source/file_zip.cpp + common/filesystem/source/file_pak.cpp + common/filesystem/source/file_whres.cpp + common/filesystem/source/file_ssi.cpp + common/filesystem/source/file_directory.cpp + common/filesystem/source/resourcefile.cpp + common/filesystem/source/files.cpp + common/filesystem/source/files_decompress.cpp + common/filesystem/source/fs_findfile.cpp + common/filesystem/source/fs_stringpool.cpp ) @@ -1269,7 +1270,7 @@ include_directories( common/textures/hires common/textures common/models - common/filesystem + common/filesystem/include common/utility common/console common/engine @@ -1470,6 +1471,8 @@ source_group("Common\\Objects" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/ source_group("Common\\Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/menu/.+") source_group("Common\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/fonts/.+") source_group("Common\\File System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/.+") +source_group("Common\\File System\\Include" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/include/.+") +source_group("Common\\File System\\Source" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/filesystem/source/.+") source_group("Common\\Scripting" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/.+") source_group("Common\\Scripting\\Interface" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/interface/.+") source_group("Common\\Scripting\\Frontend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/scripting/frontend/.+" FILES ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.c ${CMAKE_CURRENT_BINARY_DIR}/zcc-parse.h) diff --git a/src/common/audio/music/i_music.cpp b/src/common/audio/music/i_music.cpp index 19c830916..2e0f83319 100644 --- a/src/common/audio/music/i_music.cpp +++ b/src/common/audio/music/i_music.cpp @@ -53,6 +53,7 @@ #include "s_music.h" #include "filereadermusicinterface.h" +using namespace FileSys; void I_InitSoundFonts(); @@ -192,7 +193,7 @@ static void SetupWgOpn() { return; } - FileData data = fileSystem.ReadFile(lump); + auto data = fileSystem.ReadFile(lump); ZMusic_SetWgOpn(data.GetMem(), (uint32_t)data.GetSize()); } @@ -204,7 +205,7 @@ static void SetupDMXGUS() { return; } - FileData data = fileSystem.ReadFile(lump); + auto data = fileSystem.ReadFile(lump); ZMusic_SetDmxGus(data.GetMem(), (uint32_t)data.GetSize()); } diff --git a/src/common/audio/music/i_soundfont.cpp b/src/common/audio/music/i_soundfont.cpp index 72b8ab44d..bac39d3a1 100644 --- a/src/common/audio/music/i_soundfont.cpp +++ b/src/common/audio/music/i_soundfont.cpp @@ -40,10 +40,9 @@ #include "i_system.h" #include "filereadermusicinterface.h" #include -#include "resourcefile.h" +#include "fs_filesystem.h" #include "version.h" #include "fs_findfile.h" -#include "resourcefile.h" #include "i_interface.h" #include "configfile.h" #include "printf.h" @@ -402,7 +401,7 @@ void FSoundFontManager::CollectSoundfonts() { if (stricmp (key, "Path") == 0) { - FileList list; + FileSys::FileList list; FString dir; @@ -410,7 +409,7 @@ void FSoundFontManager::CollectSoundfonts() FixPathSeperator(dir); if (dir.IsNotEmpty()) { - if (ScanDirectory(list, dir.GetChars(), "*", true)) + if (FileSys::ScanDirectory(list, dir.GetChars(), "*", true)) { for(auto& entry : list) { diff --git a/src/common/audio/music/music.cpp b/src/common/audio/music/music.cpp index d9b99fc2b..adffe332f 100644 --- a/src/common/audio/music/music.cpp +++ b/src/common/audio/music/music.cpp @@ -55,6 +55,7 @@ #include "i_specialpaths.h" #include "configfile.h" #include "c_cvars.h" +#include "md5.h" // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- diff --git a/src/common/audio/music/s_music.h b/src/common/audio/music/s_music.h index 1970a57da..6ae4017c9 100644 --- a/src/common/audio/music/s_music.h +++ b/src/common/audio/music/s_music.h @@ -5,9 +5,9 @@ #include "zstring.h" #include "tarray.h" #include "name.h" +#include "files.h" #include -class FileReader; class SoundStream; diff --git a/src/common/audio/sound/i_sound.h b/src/common/audio/sound/i_sound.h index 080515494..e8e5a1a0e 100644 --- a/src/common/audio/sound/i_sound.h +++ b/src/common/audio/sound/i_sound.h @@ -40,8 +40,8 @@ #include "i_soundinternal.h" #include "zstring.h" #include +#include "files.h" -class FileReader; struct FSoundChan; enum EStartSoundFlags diff --git a/src/common/console/c_enginecmds.cpp b/src/common/console/c_enginecmds.cpp index 40be68688..f6b8732de 100644 --- a/src/common/console/c_enginecmds.cpp +++ b/src/common/console/c_enginecmds.cpp @@ -201,8 +201,8 @@ UNSAFE_CCMD (dir) bpath = path; } - FileList list; - if (!ScanDirectory(list, bpath, base, true)) + FileSys::FileList list; + if (!FileSys::ScanDirectory(list, bpath, base, true)) { Printf ("Nothing matching %s\n", path.GetChars()); } diff --git a/src/common/engine/files.h b/src/common/engine/files.h new file mode 100644 index 000000000..af6694cf0 --- /dev/null +++ b/src/common/engine/files.h @@ -0,0 +1,6 @@ +#pragma once +#include "fs_files.h" + +using FileSys::FileReader; +using FileSys::FileWriter; +using FileSys::BufferWriter; \ No newline at end of file diff --git a/src/common/engine/filesystem.h b/src/common/engine/filesystem.h new file mode 100644 index 000000000..53f491677 --- /dev/null +++ b/src/common/engine/filesystem.h @@ -0,0 +1,7 @@ +#pragma once +#include "fs_filesystem.h" + +using FileSys::FileSystem; +using FileSys::FResourceFile; + +inline FileSys::FileSystem fileSystem; diff --git a/src/common/engine/palettecontainer.h b/src/common/engine/palettecontainer.h index a220873a6..a761ae33c 100644 --- a/src/common/engine/palettecontainer.h +++ b/src/common/engine/palettecontainer.h @@ -3,8 +3,7 @@ #include #include "memarena.h" #include "palentry.h" - -class FileReader; +#include "files.h" enum { diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index 571a314d0..d0e6ac7c1 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -57,6 +57,8 @@ #include "base64.h" #include "vm.h" +using namespace FileSys; + extern DObject *WP_NOCHANGE; bool save_full = false; // for testing. Should be removed afterward. diff --git a/src/common/engine/serializer.h b/src/common/engine/serializer.h index c9cc26320..a6f74c037 100644 --- a/src/common/engine/serializer.h +++ b/src/common/engine/serializer.h @@ -4,7 +4,6 @@ #include #include #include "tarray.h" -#include "file_zip.h" #include "tflags.h" #include "vectors.h" #include "palentry.h" @@ -80,7 +79,7 @@ public: void SetUniqueSoundNames() { soundNamesAreUnique = true; } bool OpenWriter(bool pretty = true); bool OpenReader(const char *buffer, size_t length); - bool OpenReader(FCompressedBuffer *input); + bool OpenReader(FileSys::FCompressedBuffer *input); void Close(); void ReadObjects(bool hubtravel); bool BeginObject(const char *name); @@ -91,7 +90,7 @@ public: unsigned GetSize(const char *group); const char *GetKey(); const char *GetOutput(unsigned *len = nullptr); - FCompressedBuffer GetCompressedOutput(); + FileSys::FCompressedBuffer GetCompressedOutput(); // The sprite serializer is a special case because it is needed by the VM to handle its 'spriteid' type. virtual FSerializer &Sprite(const char *key, int32_t &spritenum, int32_t *def); // This is only needed by the type system. diff --git a/src/common/filesystem/files.h b/src/common/filesystem/include/fs_files.h similarity index 98% rename from src/common/filesystem/files.h rename to src/common/filesystem/include/fs_files.h index 99a3b133f..e73282497 100644 --- a/src/common/filesystem/files.h +++ b/src/common/filesystem/include/fs_files.h @@ -45,6 +45,8 @@ #include "tarray.h" +namespace FileSys { + class FileSystemException : public std::exception { protected: @@ -271,7 +273,7 @@ public: { uint16_t v = 0; Read(&v, 2); - return fs_private::LittleShort(v); + return byteswap::LittleShort(v); } int16_t ReadInt16() @@ -283,7 +285,7 @@ public: { uint16_t v = 0; Read(&v, 2); - return fs_private::BigShort(v); + return byteswap::BigShort(v); } int16_t ReadInt16BE() @@ -295,7 +297,7 @@ public: { uint32_t v = 0; Read(&v, 4); - return fs_private::LittleLong(v); + return byteswap::LittleLong(v); } int32_t ReadInt32() @@ -307,7 +309,7 @@ public: { uint32_t v = 0; Read(&v, 4); - return fs_private::BigLong(v); + return byteswap::BigLong(v); } int32_t ReadInt32BE() @@ -394,5 +396,6 @@ public: TArray&& TakeBuffer() { return std::move(mBuffer); } }; +} #endif diff --git a/src/common/filesystem/filesystem.h b/src/common/filesystem/include/fs_filesystem.h similarity index 83% rename from src/common/filesystem/filesystem.h rename to src/common/filesystem/include/fs_filesystem.h index 7dcda2f09..e97673314 100644 --- a/src/common/filesystem/filesystem.h +++ b/src/common/filesystem/include/fs_filesystem.h @@ -8,10 +8,11 @@ -#include "files.h" -#include "cmdlib.h" +#include "fs_files.h" #include "resourcefile.h" +namespace FileSys { + class FResourceFile; struct FResourceLump; @@ -92,31 +93,31 @@ public: int GetLastEntry(int wadnum) const noexcept; int GetEntryCount(int wadnum) const noexcept; - int CheckNumForName (const char *name, int namespc); - int CheckNumForName (const char *name, int namespc, int wadfile, bool exact = true); - int GetNumForName (const char *name, int namespc); + int CheckNumForName (const char *name, int namespc) const; + int CheckNumForName (const char *name, int namespc, int wadfile, bool exact = true) const; + int GetNumForName (const char *name, int namespc) const; - inline int CheckNumForName (const uint8_t *name) { return CheckNumForName ((const char *)name, ns_global); } - inline int CheckNumForName (const char *name) { return CheckNumForName (name, ns_global); } - inline int CheckNumForName (const uint8_t *name, int ns) { return CheckNumForName ((const char *)name, ns); } - inline int GetNumForName (const char *name) { return GetNumForName (name, ns_global); } - inline int GetNumForName (const uint8_t *name) { return GetNumForName ((const char *)name); } - inline int GetNumForName (const uint8_t *name, int ns) { return GetNumForName ((const char *)name, ns); } + inline int CheckNumForName (const uint8_t *name) const { return CheckNumForName ((const char *)name, ns_global); } + inline int CheckNumForName (const char *name) const { return CheckNumForName (name, ns_global); } + inline int CheckNumForName (const uint8_t *name, int ns) const { return CheckNumForName ((const char *)name, ns); } + inline int GetNumForName (const char *name) const { return GetNumForName (name, ns_global); } + inline int GetNumForName (const uint8_t *name) const { return GetNumForName ((const char *)name); } + inline int GetNumForName (const uint8_t *name, int ns) const { return GetNumForName ((const char *)name, ns); } - int CheckNumForFullName (const char *name, bool trynormal = false, int namespc = ns_global, bool ignoreext = false); - int CheckNumForFullName (const char *name, int wadfile); - int GetNumForFullName (const char *name); - int FindFile(const char* name) + int CheckNumForFullName (const char *cname, bool trynormal = false, int namespc = ns_global, bool ignoreext = false) const; + int CheckNumForFullName (const char *name, int wadfile) const; + int GetNumForFullName (const char *name) const; + int FindFile(const char* name) const { return CheckNumForFullName(name); } - bool FileExists(const char* name) + bool FileExists(const char* name) const { return FindFile(name) >= 0; } - bool FileExists(const std::string& name) + bool FileExists(const std::string& name) const { return FindFile(name.c_str()) >= 0; } @@ -140,7 +141,7 @@ public: int FindLumpFullName(const char* name, int* lastlump, bool noext = false); bool CheckFileName (int lump, const char *name); // [RH] True if lump's name == name - int FindFileWithExtensions(const char* name, const char* const* exts, int count); + int FindFileWithExtensions(const char* name, const char* const* exts, int count) const; int FindResource(int resid, const char* type, int filenum = -1) const noexcept; int GetResource(int resid, const char* type, int filenum = -1) const; @@ -212,5 +213,4 @@ private: }; -extern FileSystem fileSystem; - +} \ No newline at end of file diff --git a/src/common/filesystem/fs_findfile.h b/src/common/filesystem/include/fs_findfile.h similarity index 97% rename from src/common/filesystem/fs_findfile.h rename to src/common/filesystem/include/fs_findfile.h index 7b6d3e3d2..d845b7d14 100644 --- a/src/common/filesystem/fs_findfile.h +++ b/src/common/filesystem/include/fs_findfile.h @@ -5,6 +5,8 @@ #include #include +namespace FileSys { + struct FileListEntry { std::string FileName; // file name only @@ -34,3 +36,4 @@ inline void FixPathSeparator(char* path) } } +} diff --git a/src/common/filesystem/fs_swap.h b/src/common/filesystem/include/fs_swap.h similarity index 97% rename from src/common/filesystem/fs_swap.h rename to src/common/filesystem/include/fs_swap.h index 1e8bbef83..12b988585 100644 --- a/src/common/filesystem/fs_swap.h +++ b/src/common/filesystem/include/fs_swap.h @@ -17,9 +17,9 @@ #include #endif -namespace fs_private -{ - +namespace FileSys { +namespace byteswap { + #ifdef __APPLE__ inline unsigned short LittleShort(unsigned short x) @@ -117,5 +117,6 @@ inline unsigned int BigLong (unsigned int x) #endif // __BIG_ENDIAN__ } +} #endif // __M_SWAP_H__ diff --git a/src/common/filesystem/resourcefile.h b/src/common/filesystem/include/resourcefile.h similarity index 99% rename from src/common/filesystem/resourcefile.h rename to src/common/filesystem/include/resourcefile.h index 4619bbeb0..91d437d38 100644 --- a/src/common/filesystem/resourcefile.h +++ b/src/common/filesystem/include/resourcefile.h @@ -6,8 +6,10 @@ #include #include #include -#include "files.h" +#include "fs_files.h" +namespace FileSys { + class StringPool; std::string ExtractBaseName(const char* path, bool include_extension = false); void strReplace(std::string& str, const char* from, const char* to); @@ -246,7 +248,6 @@ struct FMemoryLump : public FResourceLump }; - - +} #endif diff --git a/src/common/filesystem/ancientzip.cpp b/src/common/filesystem/source/ancientzip.cpp similarity index 99% rename from src/common/filesystem/ancientzip.cpp rename to src/common/filesystem/source/ancientzip.cpp index 80f0c6093..4d1e6b990 100644 --- a/src/common/filesystem/ancientzip.cpp +++ b/src/common/filesystem/source/ancientzip.cpp @@ -46,6 +46,8 @@ #include #include "ancientzip.h" +namespace FileSys { + /**************************************************************** Bit-I/O variables and routines/macros @@ -433,3 +435,5 @@ int ShrinkLoop(unsigned char *out, unsigned int outsize, FileReader &_In, unsign } return 0; } + +} diff --git a/src/common/filesystem/ancientzip.h b/src/common/filesystem/source/ancientzip.h similarity index 94% rename from src/common/filesystem/ancientzip.h rename to src/common/filesystem/source/ancientzip.h index 57b0f3584..e25a75d3b 100644 --- a/src/common/filesystem/ancientzip.h +++ b/src/common/filesystem/source/ancientzip.h @@ -1,6 +1,8 @@ #pragma once -#include "files.h" +#include "fs_files.h" +namespace FileSys { + class FZipExploder { unsigned int Hold, Bits; @@ -41,4 +43,5 @@ public: int Explode(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize, int flags); }; -int ShrinkLoop(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize); \ No newline at end of file +int ShrinkLoop(unsigned char *out, unsigned int outsize, FileReader &in, unsigned int insize); +} diff --git a/src/common/filesystem/file_7z.cpp b/src/common/filesystem/source/file_7z.cpp similarity index 99% rename from src/common/filesystem/file_7z.cpp rename to src/common/filesystem/source/file_7z.cpp index abf67fded..c51a566b9 100644 --- a/src/common/filesystem/file_7z.cpp +++ b/src/common/filesystem/source/file_7z.cpp @@ -40,7 +40,8 @@ #include "fs_findfile.h" - +namespace FileSys { + //----------------------------------------------------------------------- // // Interface classes to 7z library @@ -374,4 +375,4 @@ FResourceFile *Check7Z(const char *filename, FileReader &file, LumpFilterInfo* f } - +} diff --git a/src/common/filesystem/file_directory.cpp b/src/common/filesystem/source/file_directory.cpp similarity index 99% rename from src/common/filesystem/file_directory.cpp rename to src/common/filesystem/source/file_directory.cpp index f9b24da3a..8208e6634 100644 --- a/src/common/filesystem/file_directory.cpp +++ b/src/common/filesystem/source/file_directory.cpp @@ -40,6 +40,8 @@ #include "fs_findfile.h" #include "fs_stringpool.h" +namespace FileSys { + std::string FS_FullPath(const char* directory); #ifdef _WIN32 @@ -231,3 +233,4 @@ FResourceFile *CheckDir(const char *filename, bool nosubdirflag, LumpFilterInfo* return nullptr; } +} diff --git a/src/common/filesystem/file_grp.cpp b/src/common/filesystem/source/file_grp.cpp similarity index 98% rename from src/common/filesystem/file_grp.cpp rename to src/common/filesystem/source/file_grp.cpp index dd8099a2a..bd543a559 100644 --- a/src/common/filesystem/file_grp.cpp +++ b/src/common/filesystem/source/file_grp.cpp @@ -36,7 +36,8 @@ #include "resourcefile.h" #include "fs_swap.h" -using namespace fs_private; +namespace FileSys { + using namespace byteswap; //========================================================================== // @@ -152,3 +153,4 @@ FResourceFile *CheckGRP(const char *filename, FileReader &file, LumpFilterInfo* return NULL; } +} diff --git a/src/common/filesystem/file_lump.cpp b/src/common/filesystem/source/file_lump.cpp similarity index 99% rename from src/common/filesystem/file_lump.cpp rename to src/common/filesystem/source/file_lump.cpp index 85f41d775..c9885a126 100644 --- a/src/common/filesystem/file_lump.cpp +++ b/src/common/filesystem/source/file_lump.cpp @@ -34,6 +34,7 @@ #include "resourcefile.h" +namespace FileSys { //========================================================================== // // Single lump @@ -93,3 +94,4 @@ FResourceFile *CheckLump(const char *filename, FileReader &file, LumpFilterInfo* return NULL; } +} diff --git a/src/common/filesystem/file_pak.cpp b/src/common/filesystem/source/file_pak.cpp similarity index 98% rename from src/common/filesystem/file_pak.cpp rename to src/common/filesystem/source/file_pak.cpp index dfcc22ef4..c8c039209 100644 --- a/src/common/filesystem/file_pak.cpp +++ b/src/common/filesystem/source/file_pak.cpp @@ -34,8 +34,9 @@ #include "resourcefile.h" -using namespace fs_private; +namespace FileSys { + using namespace byteswap; //========================================================================== // // @@ -145,3 +146,4 @@ FResourceFile *CheckPak(const char *filename, FileReader &file, LumpFilterInfo* return NULL; } +} diff --git a/src/common/filesystem/file_rff.cpp b/src/common/filesystem/source/file_rff.cpp similarity index 99% rename from src/common/filesystem/file_rff.cpp rename to src/common/filesystem/source/file_rff.cpp index 5204d7f0f..edb003810 100644 --- a/src/common/filesystem/file_rff.cpp +++ b/src/common/filesystem/source/file_rff.cpp @@ -36,7 +36,8 @@ #include "resourcefile.h" #include "fs_swap.h" -using namespace fs_private; +namespace FileSys { + using namespace byteswap; //========================================================================== // @@ -260,4 +261,4 @@ FResourceFile *CheckRFF(const char *filename, FileReader &file, LumpFilterInfo* } - +} diff --git a/src/common/filesystem/file_ssi.cpp b/src/common/filesystem/source/file_ssi.cpp similarity index 99% rename from src/common/filesystem/file_ssi.cpp rename to src/common/filesystem/source/file_ssi.cpp index 0cfab8729..0e48ef49d 100644 --- a/src/common/filesystem/file_ssi.cpp +++ b/src/common/filesystem/source/file_ssi.cpp @@ -35,6 +35,7 @@ #include "resourcefile.h" +namespace FileSys { //========================================================================== // // Build GRP file @@ -152,3 +153,5 @@ FResourceFile* CheckSSI(const char* filename, FileReader& file, LumpFilterInfo* } return nullptr; } + +} diff --git a/src/common/filesystem/file_wad.cpp b/src/common/filesystem/source/file_wad.cpp similarity index 99% rename from src/common/filesystem/file_wad.cpp rename to src/common/filesystem/source/file_wad.cpp index 60392dfb7..13eb0b098 100644 --- a/src/common/filesystem/file_wad.cpp +++ b/src/common/filesystem/source/file_wad.cpp @@ -35,11 +35,11 @@ #include #include "resourcefile.h" -#include "filesystem.h" +#include "fs_filesystem.h" #include "fs_swap.h" -using namespace fs_private; - +namespace FileSys { + using namespace byteswap; struct wadinfo_t { @@ -485,3 +485,4 @@ FResourceFile *CheckWad(const char *filename, FileReader &file, LumpFilterInfo* return NULL; } +} diff --git a/src/common/filesystem/file_whres.cpp b/src/common/filesystem/source/file_whres.cpp similarity index 98% rename from src/common/filesystem/file_whres.cpp rename to src/common/filesystem/source/file_whres.cpp index ba07945b3..41e418773 100644 --- a/src/common/filesystem/file_whres.cpp +++ b/src/common/filesystem/source/file_whres.cpp @@ -38,7 +38,8 @@ #include "fs_stringpool.h" #include "fs_swap.h" -using namespace fs_private; +namespace FileSys { + using namespace byteswap; //========================================================================== // @@ -140,4 +141,5 @@ FResourceFile *CheckWHRes(const char *filename, FileReader &file, LumpFilterInfo } return NULL; } - \ No newline at end of file + +} \ No newline at end of file diff --git a/src/common/filesystem/file_zip.cpp b/src/common/filesystem/source/file_zip.cpp similarity index 99% rename from src/common/filesystem/file_zip.cpp rename to src/common/filesystem/source/file_zip.cpp index f97f19656..c85788fe5 100644 --- a/src/common/filesystem/file_zip.cpp +++ b/src/common/filesystem/source/file_zip.cpp @@ -41,7 +41,8 @@ #include "fs_findfile.h" #include "fs_swap.h" -using namespace fs_private; +namespace FileSys { + using namespace byteswap; #define BUFREADCOMMENT (0x400) @@ -720,3 +721,5 @@ bool WriteZip(const char* filename, const FCompressedBuffer* content, size_t con } return false; } + +} diff --git a/src/common/filesystem/file_zip.h b/src/common/filesystem/source/file_zip.h similarity index 97% rename from src/common/filesystem/file_zip.h rename to src/common/filesystem/source/file_zip.h index 5b49b714f..8313c9eb2 100644 --- a/src/common/filesystem/file_zip.h +++ b/src/common/filesystem/source/file_zip.h @@ -3,6 +3,7 @@ #include "resourcefile.h" +namespace FileSys { //========================================================================== // // Zip Lump @@ -45,5 +46,6 @@ public: virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } }; +} #endif \ No newline at end of file diff --git a/src/common/filesystem/files.cpp b/src/common/filesystem/source/files.cpp similarity index 99% rename from src/common/filesystem/files.cpp rename to src/common/filesystem/source/files.cpp index 89983d87c..4d92cc25c 100644 --- a/src/common/filesystem/files.cpp +++ b/src/common/filesystem/source/files.cpp @@ -34,10 +34,10 @@ */ #include -#include "files.h" - -using namespace fs_private; +#include "fs_files.h" +namespace FileSys { + #ifdef _WIN32 std::wstring toWide(const char* str); #endif @@ -494,3 +494,5 @@ size_t BufferWriter::Write(const void *buffer, size_t len) memcpy(&mBuffer[ofs], buffer, len); return len; } + +} diff --git a/src/common/filesystem/files_decompress.cpp b/src/common/filesystem/source/files_decompress.cpp similarity index 99% rename from src/common/filesystem/files_decompress.cpp rename to src/common/filesystem/source/files_decompress.cpp index 8b8f4958a..5948177cf 100644 --- a/src/common/filesystem/files_decompress.cpp +++ b/src/common/filesystem/source/files_decompress.cpp @@ -41,7 +41,10 @@ #include #include -#include "files.h" +#include "fs_files.h" + +namespace FileSys { + using namespace byteswap; //========================================================================== // @@ -538,7 +541,7 @@ class DecompressorLZSS : public DecompressorBase return false; Stream.AvailIn -= 2; - uint16_t pos = fs_private::BigShort(*(uint16_t*)Stream.In); + uint16_t pos = BigShort(*(uint16_t*)Stream.In); uint8_t len = (pos & 0xF)+1; pos >>= 4; Stream.In += 2; @@ -752,3 +755,4 @@ bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, b } } +} diff --git a/src/common/filesystem/filesystem.cpp b/src/common/filesystem/source/filesystem.cpp similarity index 98% rename from src/common/filesystem/filesystem.cpp rename to src/common/filesystem/source/filesystem.cpp index 60a62697d..c8623765e 100644 --- a/src/common/filesystem/filesystem.cpp +++ b/src/common/filesystem/source/filesystem.cpp @@ -41,11 +41,13 @@ #include #include -#include "filesystem.h" +#include "fs_filesystem.h" #include "fs_findfile.h" #include "md5.hpp" #include "fs_stringpool.h" +namespace FileSys { + // MACROS ------------------------------------------------------------------ #define NULL_INDEX (0xffffffff) @@ -72,7 +74,7 @@ static uint32_t MakeHash(const char* str, size_t length = SIZE_MAX) static void md5Hash(FileReader& reader, uint8_t* digest) { - using namespace fs_private::md5; + using namespace md5; md5_state_t state; md5_init(&state); @@ -187,8 +189,6 @@ static void PrintLastError (FileSystemMessageFunc Printf); // PUBLIC DATA DEFINITIONS ------------------------------------------------- -FileSystem fileSystem; - // CODE -------------------------------------------------------------------- FileSystem::FileSystem() @@ -511,7 +511,7 @@ int FileSystem::CheckIfResourceFileLoaded (const char *name) noexcept // and namespace parameter //========================================================================== -int FileSystem::CheckNumForName (const char *name, int space) +int FileSystem::CheckNumForName (const char *name, int space) const { union { @@ -556,7 +556,7 @@ int FileSystem::CheckNumForName (const char *name, int space) return i != NULL_INDEX ? i : -1; } -int FileSystem::CheckNumForName (const char *name, int space, int rfnum, bool exact) +int FileSystem::CheckNumForName (const char *name, int space, int rfnum, bool exact) const { union { @@ -594,7 +594,7 @@ int FileSystem::CheckNumForName (const char *name, int space, int rfnum, bool ex // //========================================================================== -int FileSystem::GetNumForName (const char *name, int space) +int FileSystem::GetNumForName (const char *name, int space) const { int i; @@ -617,7 +617,7 @@ int FileSystem::GetNumForName (const char *name, int space) // //========================================================================== -int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int namespc, bool ignoreext) +int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int namespc, bool ignoreext) const { uint32_t i; @@ -650,7 +650,7 @@ int FileSystem::CheckNumForFullName (const char *name, bool trynormal, int names return -1; } -int FileSystem::CheckNumForFullName (const char *name, int rfnum) +int FileSystem::CheckNumForFullName (const char *name, int rfnum) const { uint32_t i; @@ -678,7 +678,7 @@ int FileSystem::CheckNumForFullName (const char *name, int rfnum) // //========================================================================== -int FileSystem::GetNumForFullName (const char *name) +int FileSystem::GetNumForFullName (const char *name) const { int i; @@ -698,7 +698,7 @@ int FileSystem::GetNumForFullName (const char *name) // //========================================================================== -int FileSystem::FindFileWithExtensions(const char* name, const char *const *exts, int count) +int FileSystem::FindFileWithExtensions(const char* name, const char *const *exts, int count) const { uint32_t i; @@ -1254,7 +1254,7 @@ unsigned FileSystem::GetFilesInFolder(const char *inpath, std::vector maxfile) maxfile = thisfile; } // Delete everything from older files. for (int i = (int)result.size() - 1; i >= 0; i--) { - if (fileSystem.GetFileContainer(result[i].lumpnum) != maxfile) result.erase(result.begin() + i); + if (GetFileContainer(result[i].lumpnum) != maxfile) result.erase(result.begin() + i); } } qsort(result.data(), result.size(), sizeof(FolderEntry), folderentrycmp); @@ -1364,8 +1364,8 @@ FileReader FileSystem::ReopenFileReader(int lump, bool alwayscache) if (rl->RefCount == 0 && rd != nullptr && !rd->GetBuffer() && !alwayscache && !(rl->Flags & LUMPF_COMPRESSED)) { - int fileno = fileSystem.GetFileContainer(lump); - const char *filename = fileSystem.GetResourceFileFullName(fileno); + int fileno = GetFileContainer(lump); + const char *filename = GetResourceFileFullName(fileno); FileReader fr; if (fr.OpenFile(filename, rl->GetFileOffset(), rl->LumpSize)) { @@ -1579,3 +1579,5 @@ FResourceLump* FileSystem::GetFileAt(int no) { return FileInfo[no].lump; } + +} diff --git a/src/common/filesystem/fs_findfile.cpp b/src/common/filesystem/source/fs_findfile.cpp similarity index 99% rename from src/common/filesystem/fs_findfile.cpp rename to src/common/filesystem/source/fs_findfile.cpp index 9dde8fdcb..39851ce08 100644 --- a/src/common/filesystem/fs_findfile.cpp +++ b/src/common/filesystem/source/fs_findfile.cpp @@ -35,7 +35,8 @@ #include "fs_findfile.h" #include - +namespace FileSys { + enum { ZPATH_MAX = 260 @@ -404,3 +405,4 @@ bool FS_DirEntryExists(const char* pathname, bool* isdir) return res; } +} diff --git a/src/common/filesystem/fs_stringpool.cpp b/src/common/filesystem/source/fs_stringpool.cpp similarity index 99% rename from src/common/filesystem/fs_stringpool.cpp rename to src/common/filesystem/source/fs_stringpool.cpp index 29a472309..1e4231139 100644 --- a/src/common/filesystem/fs_stringpool.cpp +++ b/src/common/filesystem/source/fs_stringpool.cpp @@ -38,6 +38,8 @@ #include #include "fs_stringpool.h" +namespace FileSys { + struct StringPool::Block { Block *NextBlock; @@ -124,3 +126,5 @@ const char* StringPool::Strdup(const char* str) strcpy(p, str); return p; } + +} diff --git a/src/common/filesystem/fs_stringpool.h b/src/common/filesystem/source/fs_stringpool.h similarity index 96% rename from src/common/filesystem/fs_stringpool.h rename to src/common/filesystem/source/fs_stringpool.h index 331f768f7..f72a180df 100644 --- a/src/common/filesystem/fs_stringpool.h +++ b/src/common/filesystem/source/fs_stringpool.h @@ -1,5 +1,6 @@ #pragma once +namespace FileSys { // Storage for all the static strings the file system must hold. class StringPool { @@ -25,3 +26,4 @@ public: bool shared; }; +} diff --git a/src/common/filesystem/md5.hpp b/src/common/filesystem/source/md5.hpp similarity index 99% rename from src/common/filesystem/md5.hpp rename to src/common/filesystem/source/md5.hpp index 2027023ca..1ecde05d4 100644 --- a/src/common/filesystem/md5.hpp +++ b/src/common/filesystem/source/md5.hpp @@ -69,7 +69,7 @@ #include #include -namespace fs_private { +namespace FileSys { /// Provides MD5 hashing functionality namespace md5 { diff --git a/src/common/filesystem/resourcefile.cpp b/src/common/filesystem/source/resourcefile.cpp similarity index 99% rename from src/common/filesystem/resourcefile.cpp rename to src/common/filesystem/source/resourcefile.cpp index 6e7525591..8a17c09a0 100644 --- a/src/common/filesystem/resourcefile.cpp +++ b/src/common/filesystem/source/resourcefile.cpp @@ -39,6 +39,8 @@ #include "md5.hpp" #include "fs_stringpool.h" +namespace FileSys { + std::string ExtractBaseName(const char* path, bool include_extension) { const char* src, * dot; @@ -364,7 +366,7 @@ int lumpcmp(const void * a, const void * b) void FResourceFile::GenerateHash() { // hash the lump directory after sorting - using namespace fs_private::md5; + using namespace FileSys::md5; auto n = snprintf(Hash, 48, "%08X-%04X-", (unsigned)Reader.GetLength(), NumLumps); @@ -745,4 +747,4 @@ int FExternalLump::FillCache() } - +} diff --git a/src/common/filesystem/w_zip.h b/src/common/filesystem/source/w_zip.h similarity index 98% rename from src/common/filesystem/w_zip.h rename to src/common/filesystem/source/w_zip.h index c0905cd20..d26d7f003 100644 --- a/src/common/filesystem/w_zip.h +++ b/src/common/filesystem/source/w_zip.h @@ -7,6 +7,8 @@ #define FORCE_PACKED #endif +namespace FileSys { + #pragma pack(1) // FZipCentralInfo struct FZipEndOfCentralDirectory @@ -105,4 +107,5 @@ struct FZipLocalFileHeader // File header flags. #define ZF_ENCRYPTED 0x1 +} #endif diff --git a/src/common/fonts/font.cpp b/src/common/fonts/font.cpp index be02a8b59..1714d78b4 100644 --- a/src/common/fonts/font.cpp +++ b/src/common/fonts/font.cpp @@ -91,7 +91,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla // Read the font's configuration. // This will not be done for the default fonts, because they are not atomic and the default content does not need it. - std::vector folderdata; + std::vector folderdata; if (filetemplate != nullptr) { FStringf path("fonts/%s/", filetemplate); @@ -398,7 +398,7 @@ public: } }; -void FFont::ReadSheetFont(std::vector &folderdata, int width, int height, const DVector2 &Scale) +void FFont::ReadSheetFont(std::vector &folderdata, int width, int height, const DVector2 &Scale) { TMap charMap; int minchar = INT_MAX; diff --git a/src/common/fonts/hexfont.cpp b/src/common/fonts/hexfont.cpp index 643b44d4d..52d723fa6 100644 --- a/src/common/fonts/hexfont.cpp +++ b/src/common/fonts/hexfont.cpp @@ -58,7 +58,7 @@ struct HexDataSource // //========================================================================== - void ParseDefinition(FResourceLump* font) + void ParseDefinition(FileSys::FResourceLump* font) { FScanner sc; diff --git a/src/common/fonts/singlelumpfont.cpp b/src/common/fonts/singlelumpfont.cpp index 72a3b1805..b40a86bff 100644 --- a/src/common/fonts/singlelumpfont.cpp +++ b/src/common/fonts/singlelumpfont.cpp @@ -124,7 +124,7 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump) FontName = name; - FileData data1 = fileSystem.ReadFile (lump); + auto data1 = fileSystem.ReadFile (lump); auto data = data1.GetBytes(); if (data[0] == 0xE1 && data[1] == 0xE6 && data[2] == 0xD5 && data[3] == 0x1A) @@ -474,7 +474,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) void FSingleLumpFont::CheckFON1Chars() { - FileData memLump = fileSystem.ReadFile(Lump); + auto memLump = fileSystem.ReadFile(Lump); auto data = memLump.GetBytes(); const uint8_t* data_p; diff --git a/src/common/fonts/v_font.cpp b/src/common/fonts/v_font.cpp index f6e4ef0de..591edb208 100644 --- a/src/common/fonts/v_font.cpp +++ b/src/common/fonts/v_font.cpp @@ -109,7 +109,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) int lump = -1; int folderfile = -1; - std::vector folderdata; + std::vector folderdata; FStringf path("fonts/%s/", name); // Use a folder-based font only if it comes from a later file than the single lump version. diff --git a/src/common/fonts/v_font.h b/src/common/fonts/v_font.h index 9fdab0228..0b5ce1338 100644 --- a/src/common/fonts/v_font.h +++ b/src/common/fonts/v_font.h @@ -175,7 +175,7 @@ protected: void FixXMoves(); - void ReadSheetFont(std::vector &folderdata, int width, int height, const DVector2 &Scale); + void ReadSheetFont(std::vector &folderdata, int width, int height, const DVector2 &Scale); EFontType Type = EFontType::Unknown; FName AltFontName = NAME_None; diff --git a/src/common/menu/menudef.cpp b/src/common/menu/menudef.cpp index e81bda2d2..34ef1fc9d 100644 --- a/src/common/menu/menudef.cpp +++ b/src/common/menu/menudef.cpp @@ -1519,7 +1519,7 @@ void M_ParseMenuDefs() DefaultOptionMenuSettings->Reset(); OptionSettings.mLinespacing = 17; - int IWADMenu = fileSystem.CheckNumForName("MENUDEF", ns_global, fileSystem.GetIwadNum()); + int IWADMenu = fileSystem.CheckNumForName("MENUDEF", FileSys::ns_global, fileSystem.GetIwadNum()); while ((lump = fileSystem.FindLump ("MENUDEF", &lastlump)) != -1) { diff --git a/src/common/menu/savegamemanager.cpp b/src/common/menu/savegamemanager.cpp index 7e948267d..29b0f447b 100644 --- a/src/common/menu/savegamemanager.cpp +++ b/src/common/menu/savegamemanager.cpp @@ -297,7 +297,7 @@ unsigned FSavegameManagerBase::ExtractSaveData(int index) !node->bOldVersion && (resf = FResourceFile::OpenResourceFile(node->Filename.GetChars(), true)) != nullptr) { - FResourceLump *info = resf->FindLump("info.json"); + auto info = resf->FindLump("info.json"); if (info == nullptr) { // this should not happen because the file has already been verified. @@ -315,7 +315,7 @@ unsigned FSavegameManagerBase::ExtractSaveData(int index) SaveCommentString = ExtractSaveComment(arc); - FResourceLump *pic = resf->FindLump("savepic.png"); + auto pic = resf->FindLump("savepic.png"); if (pic != nullptr) { FileReader picreader; diff --git a/src/common/models/model.cpp b/src/common/models/model.cpp index ceb77bcff..a7dccfc09 100644 --- a/src/common/models/model.cpp +++ b/src/common/models/model.cpp @@ -172,7 +172,7 @@ unsigned FindModel(const char * path, const char * modelfile, bool silent) } int len = fileSystem.FileLength(lump); - FileData lumpd = fileSystem.ReadFile(lump); + auto lumpd = fileSystem.ReadFile(lump); const char * buffer = lumpd.GetString(); if ( (size_t)fullname.LastIndexOf("_d.3d") == fullname.Len()-5 ) diff --git a/src/common/models/models_iqm.cpp b/src/common/models/models_iqm.cpp index 143c4334a..a2bc656a1 100644 --- a/src/common/models/models_iqm.cpp +++ b/src/common/models/models_iqm.cpp @@ -270,7 +270,7 @@ void IQMModel::LoadGeometry() { try { - FileData lumpdata = fileSystem.ReadFile(mLumpNum); + auto lumpdata = fileSystem.ReadFile(mLumpNum); IQMFileReader reader(lumpdata.GetMem(), (int)lumpdata.GetSize()); Vertices.Resize(NumVertices); diff --git a/src/common/models/models_md2.cpp b/src/common/models/models_md2.cpp index 0dd402cf9..d56d1e7c5 100644 --- a/src/common/models/models_md2.cpp +++ b/src/common/models/models_md2.cpp @@ -177,7 +177,7 @@ bool FDMDModel::Load(const char * path, int lumpnum, const char * buffer, int le void FDMDModel::LoadGeometry() { static int axis[3] = { VX, VY, VZ }; - FileData lumpdata = fileSystem.ReadFile(mLumpNum); + auto lumpdata = fileSystem.ReadFile(mLumpNum); auto buffer = lumpdata.GetString(); texCoords = new FTexCoord[info.numTexCoords]; memcpy(texCoords, buffer + info.offsetTexCoords, info.numTexCoords * sizeof(FTexCoord)); @@ -501,7 +501,7 @@ void FMD2Model::LoadGeometry() { static int axis[3] = { VX, VY, VZ }; uint8_t *md2_frames; - FileData lumpdata = fileSystem.ReadFile(mLumpNum); + auto lumpdata = fileSystem.ReadFile(mLumpNum); auto buffer = lumpdata.GetString(); texCoords = new FTexCoord[info.numTexCoords]; diff --git a/src/common/models/models_md3.cpp b/src/common/models/models_md3.cpp index ea2083a8b..65948d809 100644 --- a/src/common/models/models_md3.cpp +++ b/src/common/models/models_md3.cpp @@ -189,7 +189,7 @@ bool FMD3Model::Load(const char * path, int lumpnum, const char * buffer, int le void FMD3Model::LoadGeometry() { - FileData lumpdata = fileSystem.ReadFile(mLumpNum); + auto lumpdata = fileSystem.ReadFile(mLumpNum); auto buffer = lumpdata.GetString(); md3_header_t * hdr = (md3_header_t *)buffer; md3_surface_t * surf = (md3_surface_t*)(buffer + LittleLong(hdr->Ofs_Surfaces)); diff --git a/src/common/models/models_ue1.cpp b/src/common/models/models_ue1.cpp index aa8567850..742ef4aaf 100644 --- a/src/common/models/models_ue1.cpp +++ b/src/common/models/models_ue1.cpp @@ -70,9 +70,9 @@ bool FUE1Model::Load( const char *filename, int lumpnum, const char *buffer, int void FUE1Model::LoadGeometry() { const char *buffer, *buffer2; - FileData lump = fileSystem.ReadFile(mDataLump); + auto lump = fileSystem.ReadFile(mDataLump); buffer = lump.GetString(); - FileData lump2 = fileSystem.ReadFile(mAnivLump); + auto lump2 = fileSystem.ReadFile(mAnivLump); buffer2 = lump2.GetString(); // map structures dhead = (const d3dhead*)(buffer); diff --git a/src/common/models/voxels.cpp b/src/common/models/voxels.cpp index 6c7867ccf..9d2f1fdd6 100644 --- a/src/common/models/voxels.cpp +++ b/src/common/models/voxels.cpp @@ -161,7 +161,7 @@ FVoxel *R_LoadKVX(int lumpnum) int mip, maxmipsize; int i, j, n; - FileData lump = fileSystem.ReadFile(lumpnum); // FileData adds an extra 0 byte to the end. + auto lump = fileSystem.ReadFile(lumpnum); // FileData adds an extra 0 byte to the end. auto rawvoxel = lump.GetBytes(); int voxelsize = (int)(lump.GetSize()-1); diff --git a/src/common/rendering/gles/gles_shader.cpp b/src/common/rendering/gles/gles_shader.cpp index 8f9103c61..4fffa8b90 100644 --- a/src/common/rendering/gles/gles_shader.cpp +++ b/src/common/rendering/gles/gles_shader.cpp @@ -383,11 +383,11 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * int vp_lump = fileSystem.CheckNumForFullName(vert_prog_lump, 0); if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump.GetChars()); - FileData vp_data = fileSystem.ReadFile(vp_lump); + auto vp_data = fileSystem.ReadFile(vp_lump); int fp_lump = fileSystem.CheckNumForFullName(frag_prog_lump, 0); if (fp_lump == -1) I_Error("Unable to load '%s'", frag_prog_lump.GetChars()); - FileData fp_data = fileSystem.ReadFile(fp_lump); + auto fp_data = fileSystem.ReadFile(fp_lump); diff --git a/src/common/rendering/v_video.h b/src/common/rendering/v_video.h index bb3c8bb4d..ed428ee67 100644 --- a/src/common/rendering/v_video.h +++ b/src/common/rendering/v_video.h @@ -45,6 +45,7 @@ #include "hw_shadowmap.h" #include "hw_levelmesh.h" #include "buffers.h" +#include "files.h" struct FPortalSceneState; @@ -90,7 +91,6 @@ EXTERN_CVAR(Int, win_h) EXTERN_CVAR(Bool, win_maximized) struct FColormap; -class FileWriter; enum FTextureFormat : uint32_t; class FModelRenderer; struct SamplerUniform; diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index 3784543b3..4ccfbd302 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -473,7 +473,7 @@ FString VkShaderManager::LoadPrivateShaderLump(const char *lumpname) { int lump = fileSystem.CheckNumForFullName(lumpname, 0); if (lump == -1) I_Error("Unable to load '%s'", lumpname); - FileData data = fileSystem.ReadFile(lump); + auto data = fileSystem.ReadFile(lump); return GetStringFromLump(lump); } diff --git a/src/common/startscreen/startscreen_generic.cpp b/src/common/startscreen/startscreen_generic.cpp index c2af0bd50..3484e2200 100644 --- a/src/common/startscreen/startscreen_generic.cpp +++ b/src/common/startscreen/startscreen_generic.cpp @@ -72,7 +72,7 @@ FGenericStartScreen::FGenericStartScreen(int max_progress) : FStartScreen(max_progress) { // at this point we do not have a working texture manager yet, so we have to do the lookup via the file system - int startup_lump = fileSystem.CheckNumForName("GZDOOM", ns_graphics); + int startup_lump = fileSystem.CheckNumForName("GZDOOM", FileSys::ns_graphics); StartupBitmap.Create(640, 480); ClearBlock(StartupBitmap, { 0, 0, 0, 255 }, 0, 0, 640, 480); diff --git a/src/common/startscreen/startscreen_hexen.cpp b/src/common/startscreen/startscreen_hexen.cpp index 6eef73599..a82e21b35 100644 --- a/src/common/startscreen/startscreen_hexen.cpp +++ b/src/common/startscreen/startscreen_hexen.cpp @@ -81,9 +81,9 @@ FHexenStartScreen::FHexenStartScreen(int max_progress) : FStartScreen(max_progress) { // at this point we do not have a working texture manager yet, so we have to do the lookup via the file system - int startup_lump = fileSystem.CheckNumForName("STARTUP", ns_graphics); - int netnotch_lump = fileSystem.CheckNumForName("NETNOTCH", ns_graphics); - int notch_lump = fileSystem.CheckNumForName("NOTCH", ns_graphics); + int startup_lump = fileSystem.CheckNumForName("STARTUP", FileSys::ns_graphics); + int netnotch_lump = fileSystem.CheckNumForName("NETNOTCH", FileSys::ns_graphics); + int notch_lump = fileSystem.CheckNumForName("NOTCH", FileSys::ns_graphics); // For backwards compatibility we also need to look in the default namespace, because these were previously not handled as graphics. if (startup_lump == -1) startup_lump = fileSystem.CheckNumForName("STARTUP"); diff --git a/src/common/startscreen/startscreen_strife.cpp b/src/common/startscreen/startscreen_strife.cpp index b4490a921..5b1d48bf4 100644 --- a/src/common/startscreen/startscreen_strife.cpp +++ b/src/common/startscreen/startscreen_strife.cpp @@ -119,7 +119,7 @@ FStrifeStartScreen::FStrifeStartScreen(int max_progress) // Load the animated overlays. for (size_t i = 0; i < countof(StrifeStartupPicNames); ++i) { - int lumpnum = fileSystem.CheckNumForName(StrifeStartupPicNames[i], ns_graphics); + int lumpnum = fileSystem.CheckNumForName(StrifeStartupPicNames[i], FileSys::ns_graphics); if (lumpnum < 0) lumpnum = fileSystem.CheckNumForName(StrifeStartupPicNames[i]); if (lumpnum >= 0) diff --git a/src/common/textures/formats/anmtexture.cpp b/src/common/textures/formats/anmtexture.cpp index f57b0e31e..9fc3290d6 100644 --- a/src/common/textures/formats/anmtexture.cpp +++ b/src/common/textures/formats/anmtexture.cpp @@ -103,7 +103,7 @@ FAnmTexture::FAnmTexture (int lumpnum, int w, int h) void FAnmTexture::ReadFrame(uint8_t *pixels, uint8_t *palette) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); anim_t anim; diff --git a/src/common/textures/formats/automaptexture.cpp b/src/common/textures/formats/automaptexture.cpp index 6b660b1ba..5aade7730 100644 --- a/src/common/textures/formats/automaptexture.cpp +++ b/src/common/textures/formats/automaptexture.cpp @@ -92,7 +92,7 @@ FAutomapTexture::FAutomapTexture (int lumpnum) PalettedPixels FAutomapTexture::CreatePalettedPixels(int conversion) { int x, y; - FileData data = fileSystem.ReadFile (SourceLump); + auto data = fileSystem.ReadFile (SourceLump); auto indata = data.GetBytes(); PalettedPixels Pixels(Width * Height); diff --git a/src/common/textures/formats/imgztexture.cpp b/src/common/textures/formats/imgztexture.cpp index fb020c9a1..e85d3bac9 100644 --- a/src/common/textures/formats/imgztexture.cpp +++ b/src/common/textures/formats/imgztexture.cpp @@ -120,7 +120,7 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1 PalettedPixels FIMGZTexture::CreatePalettedPixels(int conversion) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto imgz = (const ImageHeader *)lump.GetMem(); const uint8_t *data = (const uint8_t *)&imgz[1]; diff --git a/src/common/textures/formats/patchtexture.cpp b/src/common/textures/formats/patchtexture.cpp index d64e003e2..80179a54d 100644 --- a/src/common/textures/formats/patchtexture.cpp +++ b/src/common/textures/formats/patchtexture.cpp @@ -174,7 +174,7 @@ PalettedPixels FPatchTexture::CreatePalettedPixels(int conversion) const column_t *maxcol; int x; - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); const patch_t *patch = (const patch_t *)lump.GetMem(); maxcol = (const column_t *)((const uint8_t *)patch + fileSystem.FileLength (SourceLump) - 3); @@ -284,7 +284,7 @@ void FPatchTexture::DetectBadPatches () // Check if this patch is likely to be a problem. // It must be 256 pixels tall, and all its columns must have exactly // one post, where each post has a supposed length of 0. - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); const patch_t *realpatch = (patch_t *)lump.GetMem(); const uint32_t *cofs = realpatch->columnofs; int x, x2 = LittleShort(realpatch->width); diff --git a/src/common/textures/formats/rawpagetexture.cpp b/src/common/textures/formats/rawpagetexture.cpp index e2b6c1146..4caa6bb9e 100644 --- a/src/common/textures/formats/rawpagetexture.cpp +++ b/src/common/textures/formats/rawpagetexture.cpp @@ -172,7 +172,7 @@ FRawPageTexture::FRawPageTexture (int lumpnum) PalettedPixels FRawPageTexture::CreatePalettedPixels(int conversion) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); const uint8_t *source_p = source; uint8_t *dest_p; @@ -204,8 +204,8 @@ int FRawPageTexture::CopyPixels(FBitmap *bmp, int conversion) if (mPaletteLump < 0) return FImageSource::CopyPixels(bmp, conversion); else { - FileData lump = fileSystem.ReadFile(SourceLump); - FileData plump = fileSystem.ReadFile(mPaletteLump); + auto lump = fileSystem.ReadFile(SourceLump); + auto plump = fileSystem.ReadFile(mPaletteLump); auto source = lump.GetBytes(); auto psource = plump.GetBytes(); PalEntry paldata[256]; diff --git a/src/common/textures/formats/startuptexture.cpp b/src/common/textures/formats/startuptexture.cpp index 718b7182a..cb1c5b719 100644 --- a/src/common/textures/formats/startuptexture.cpp +++ b/src/common/textures/formats/startuptexture.cpp @@ -164,7 +164,7 @@ FStartupTexture::FStartupTexture (int lumpnum) Height = 480; bUseGamePalette = false; - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); // Initialize the bitmap palette. @@ -233,7 +233,7 @@ void PlanarToChunky(T* dest, const uint8_t* src, const T* remap, int width, int PalettedPixels FStartupTexture::CreatePalettedPixels(int conversion) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); @@ -253,7 +253,7 @@ PalettedPixels FStartupTexture::CreatePalettedPixels(int conversion) int FStartupTexture::CopyPixels(FBitmap *bmp, int conversion) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); PlanarToChunky((uint32_t*)bmp->GetPixels(), source + 48, startuppalette32, Width, Height); return 0; @@ -281,7 +281,7 @@ FNotchTexture::FNotchTexture (int lumpnum, int width, int height) PalettedPixels FNotchTexture::CreatePalettedPixels(int conversion) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); @@ -304,7 +304,7 @@ PalettedPixels FNotchTexture::CreatePalettedPixels(int conversion) int FNotchTexture::CopyPixels(FBitmap *bmp, int conversion) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); auto Work = (uint32_t*)bmp->GetPixels(); @@ -338,7 +338,7 @@ FStrifeStartupTexture::FStrifeStartupTexture (int lumpnum, int w, int h) PalettedPixels FStrifeStartupTexture::CreatePalettedPixels(int conversion) { - FileData lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); PalettedPixels Pixels(Width*Height); const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); diff --git a/src/common/textures/gametexture.cpp b/src/common/textures/gametexture.cpp index 20b22939d..2c873d15f 100644 --- a/src/common/textures/gametexture.cpp +++ b/src/common/textures/gametexture.cpp @@ -182,7 +182,7 @@ void FGameTexture::AddAutoMaterials() if (this->*(layer.pointer) == nullptr) // only if no explicit assignment had been done. { FStringf lookup("%s%s%s", layer.path, fullname ? "" : "auto/", searchname.GetChars()); - auto lump = fileSystem.CheckNumForFullName(lookup, false, ns_global, true); + auto lump = fileSystem.CheckNumForFullName(lookup, false, FileSys::ns_global, true); if (lump != -1) { auto bmtex = TexMan.FindGameTexture(fileSystem.GetFileFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny); @@ -199,7 +199,7 @@ void FGameTexture::AddAutoMaterials() if (!this->Layers || this->Layers.get()->*(layer.pointer) == nullptr) // only if no explicit assignment had been done. { FStringf lookup("%s%s%s", layer.path, fullname ? "" : "auto/", searchname.GetChars()); - auto lump = fileSystem.CheckNumForFullName(lookup, false, ns_global, true); + auto lump = fileSystem.CheckNumForFullName(lookup, false, FileSys::ns_global, true); if (lump != -1) { auto bmtex = TexMan.FindGameTexture(fileSystem.GetFileFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny); diff --git a/src/common/textures/m_png.h b/src/common/textures/m_png.h index 2f52a1fcf..f65de4c0d 100644 --- a/src/common/textures/m_png.h +++ b/src/common/textures/m_png.h @@ -47,7 +47,6 @@ enum ESSType SS_BGRA }; -class FileWriter; // PNG Writing -------------------------------------------------------------- // Start writing an 8-bit palettized PNG file. @@ -82,13 +81,13 @@ struct PNGHandle uint32_t Size; }; - FileReader File; + FileSys::FileReader File; bool bDeleteFilePtr; TArray Chunks; TArray TextChunks; unsigned int ChunkPt; - PNGHandle(FileReader &file); + PNGHandle(FileSys::FileReader &file); ~PNGHandle(); }; @@ -96,7 +95,7 @@ struct PNGHandle // the signature, but also checking for the IEND chunk. CRC checking of // each chunk is not done. If it is valid, you get a PNGHandle to pass to // the following functions. -PNGHandle *M_VerifyPNG (FileReader &file); +PNGHandle *M_VerifyPNG (FileSys::FileReader &file); // Finds a chunk in a PNG file. The file pointer will be positioned at the // beginning of the chunk data, and its length will be returned. A return @@ -115,7 +114,7 @@ bool M_GetPNGText (PNGHandle *png, const char *keyword, char *buffer, size_t buf // The file must be positioned at the start of the first IDAT. It reads // image data into the provided buffer. Returns true on success. -bool M_ReadIDAT (FileReader &file, uint8_t *buffer, int width, int height, int pitch, +bool M_ReadIDAT (FileSys::FileReader &file, uint8_t *buffer, int width, int height, int pitch, uint8_t bitdepth, uint8_t colortype, uint8_t interlace, unsigned int idatlen); diff --git a/src/common/textures/multipatchtexturebuilder.cpp b/src/common/textures/multipatchtexturebuilder.cpp index 201398ee8..c032372c3 100644 --- a/src/common/textures/multipatchtexturebuilder.cpp +++ b/src/common/textures/multipatchtexturebuilder.cpp @@ -397,12 +397,12 @@ void FMultipatchTextureBuilder::AddTexturesLumps(int lump1, int lump2, int patch if (lump1 >= 0) { - FileData texdir = fileSystem.ReadFile(lump1); + auto texdir = fileSystem.ReadFile(lump1); AddTexturesLump(texdir.GetMem(), fileSystem.FileLength(lump1), lump1, patcheslump, firstdup, true); } if (lump2 >= 0) { - FileData texdir = fileSystem.ReadFile(lump2); + auto texdir = fileSystem.ReadFile(lump2); AddTexturesLump(texdir.GetMem(), fileSystem.FileLength(lump2), lump2, patcheslump, firstdup, false); } } diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index 969a5f201..c2ebe6249 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -50,6 +50,7 @@ #include "basics.h" #include "cmdlib.h" +using namespace FileSys; FTextureManager TexMan; diff --git a/src/common/utility/cmdlib.cpp b/src/common/utility/cmdlib.cpp index b5ac83415..8dbce2b7a 100644 --- a/src/common/utility/cmdlib.cpp +++ b/src/common/utility/cmdlib.cpp @@ -1018,7 +1018,7 @@ void uppercopy(char* to, const char* from) FString GetStringFromLump(int lump) { - FileData fd = fileSystem.ReadFile(lump); + auto fd = fileSystem.ReadFile(lump); FString ScriptBuffer(fd.GetString(), fd.GetSize()); ScriptBuffer.Truncate(strlen(ScriptBuffer.GetChars())); // this is necessary to properly truncate the generated string to not contain 0 bytes. return ScriptBuffer; diff --git a/src/common/utility/cmdlib.h b/src/common/utility/cmdlib.h index 9d94d0d3f..06b5a5e0f 100644 --- a/src/common/utility/cmdlib.h +++ b/src/common/utility/cmdlib.h @@ -12,6 +12,7 @@ #include #include #include "zstring.h" +#include "files.h" #if !defined(GUID_DEFINED) #define GUID_DEFINED @@ -82,7 +83,6 @@ inline constexpr double Scale(double a, double b, double c) return (a * b) / c; } -class FileReader; struct MD5Context; void md5Update(FileReader& file, MD5Context& md5, unsigned len); diff --git a/src/common/utility/filereadermusicinterface.h b/src/common/utility/filereadermusicinterface.h index f261f9dd0..633599b63 100644 --- a/src/common/utility/filereadermusicinterface.h +++ b/src/common/utility/filereadermusicinterface.h @@ -6,6 +6,7 @@ inline ZMusicCustomReader *GetMusicReader(FileReader& fr) { + using FileSys::FileReaderInterface; auto zcr = new ZMusicCustomReader; zcr->handle = fr.GetInterface(); diff --git a/src/common/utility/findfile.cpp b/src/common/utility/findfile.cpp index 17d2c9154..ff1e53f4f 100644 --- a/src/common/utility/findfile.cpp +++ b/src/common/utility/findfile.cpp @@ -139,11 +139,11 @@ void D_AddWildFile(std::vector& wadfiles, const char* value, const else { // Try pattern matching - FileList list; + FileSys::FileList list; auto path = ExtractFilePath(value); auto name = ExtractFileBase(value, true); if (path.IsEmpty()) path = "."; - if (ScanDirectory(list, path, name, true)) + if (FileSys::ScanDirectory(list, path, name, true)) { for(auto& entry : list) { @@ -193,8 +193,8 @@ void D_AddConfigFiles(std::vector& wadfiles, const char* section, c void D_AddDirectory(std::vector& wadfiles, const char* dir, const char *filespec, FConfigFile* config) { - FileList list; - if (ScanDirectory(list, dir, "*.wad", true)) + FileSys::FileList list; + if (FileSys::ScanDirectory(list, dir, "*.wad", true)) { for (auto& entry : list) { diff --git a/src/common/utility/palette.cpp b/src/common/utility/palette.cpp index 178db734b..0b5cca67b 100644 --- a/src/common/utility/palette.cpp +++ b/src/common/utility/palette.cpp @@ -929,7 +929,7 @@ int ReadPalette(int lumpnum, uint8_t* buffer) { return 0; } - FileData lump = fileSystem.ReadFile(lumpnum); + auto lump = fileSystem.ReadFile(lumpnum); auto lumpmem = lump.GetBytes(); memset(buffer, 0, 768); diff --git a/src/common/utility/s_playlist.h b/src/common/utility/s_playlist.h index 5bd5fd55e..84d2040b0 100644 --- a/src/common/utility/s_playlist.h +++ b/src/common/utility/s_playlist.h @@ -34,7 +34,7 @@ #ifndef __S_PLAYLIST_H__ #define __S_PLAYLIST_H__ -class FileReader; +#include "files.h" class FPlayList { diff --git a/src/common/utility/zstring.h b/src/common/utility/zstring.h index 1164ddb6d..7777bbf61 100644 --- a/src/common/utility/zstring.h +++ b/src/common/utility/zstring.h @@ -40,6 +40,7 @@ #include #include "tarray.h" #include "utf8.h" +#include "filesystem.h" #ifdef __GNUC__ #define PRINTFISH(x) __attribute__((format(printf, 2, x))) @@ -117,8 +118,6 @@ enum ELumpNum { }; -class FileSystem; - class FString { public: diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 88cc0032e..ab562f283 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -300,7 +300,7 @@ void FIWadManager::ParseIWadInfo(const char *fn, const char *data, int datasize, // Look for IWAD definition lump // //========================================================================== -void GetReserved(LumpFilterInfo& lfi); +void GetReserved(FileSys::LumpFilterInfo& lfi); FIWadManager::FIWadManager(const char *firstfn, const char *optfn) { @@ -385,7 +385,7 @@ int FIWadManager::CheckIWADInfo(const char* fn) { FileSystem check; - LumpFilterInfo lfi; + FileSys::LumpFilterInfo lfi; GetReserved(lfi); std::vector filenames = { fn }; @@ -471,9 +471,9 @@ void FIWadManager::CollectSearchPaths() void FIWadManager::AddIWADCandidates(const char *dir) { - FileList list; + FileSys::FileList list; - if (ScanDirectory(list, dir, "*", true)) + if (FileSys::ScanDirectory(list, dir, "*", true)) { for(auto& entry : list) { diff --git a/src/d_main.cpp b/src/d_main.cpp index a35035fcc..f2c5b6d5a 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -122,6 +122,8 @@ #include "i_system.h" // for SHARE_DIR #endif // __unix__ +using namespace FileSys; + EXTERN_CVAR(Bool, hud_althud) EXTERN_CVAR(Int, vr_mode) EXTERN_CVAR(Bool, cl_customizeinvulmap) diff --git a/src/g_game.cpp b/src/g_game.cpp index d1374a925..f68fca225 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1981,7 +1981,7 @@ void G_DoLoadGame () LoadGameError("TXT_COULDNOTREAD"); return; } - FResourceLump *info = resfile->FindLump("info.json"); + auto info = resfile->FindLump("info.json"); if (info == nullptr) { LoadGameError("TXT_NOINFOJSON"); @@ -2408,7 +2408,7 @@ void G_DoSaveGame (bool okForQuicksave, bool forceQuicksave, FString filename, c } auto picdata = savepic.GetBuffer(); - FCompressedBuffer bufpng = { picdata->Size(), picdata->Size(), METHOD_STORED, 0, static_cast(crc32(0, &(*picdata)[0], picdata->Size())), (char*)&(*picdata)[0] }; + FCompressedBuffer bufpng = { picdata->Size(), picdata->Size(), FileSys::METHOD_STORED, 0, static_cast(crc32(0, &(*picdata)[0], picdata->Size())), (char*)&(*picdata)[0] }; savegame_content.Push(bufpng); savegame_filenames.Push("savepic.png"); diff --git a/src/g_level.cpp b/src/g_level.cpp index 147f5d48a..4b7229ab0 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -2004,7 +2004,7 @@ void G_ReadSnapshots(FResourceFile *resf) for (unsigned j = 0; j < resf->LumpCount(); j++) { - FResourceLump * resl = resf->GetLump(j); + auto resl = resf->GetLump(j); if (resl != nullptr) { auto name = resl->getName(); diff --git a/src/g_level.h b/src/g_level.h index 75a0aab56..71ae6f276 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -3,10 +3,10 @@ #include "doomtype.h" #include "vectors.h" #include "sc_man.h" -#include "file_zip.h" #include "g_mapinfo.h" +using FileSys::FCompressedBuffer; extern bool savegamerestore; void G_InitNew (const char *mapname, bool bTitleLevel); diff --git a/src/gameconfigfile.h b/src/gameconfigfile.h index 023277ae7..0b898112e 100644 --- a/src/gameconfigfile.h +++ b/src/gameconfigfile.h @@ -36,6 +36,7 @@ #include "doomtype.h" #include "configfile.h" +#include "files.h" class FArgs; class FIWadManager; diff --git a/src/gamedata/decallib.cpp b/src/gamedata/decallib.cpp index e765959b8..961b63f30 100644 --- a/src/gamedata/decallib.cpp +++ b/src/gamedata/decallib.cpp @@ -392,7 +392,7 @@ void FDecalLib::ParseDecal (FScanner &sc) case DECAL_PIC: sc.MustGetString (); picnum = TexMan.CheckForTexture (sc.String, ETextureType::Any); - if (!picnum.Exists() && (lumpnum = fileSystem.CheckNumForName (sc.String, ns_graphics)) >= 0) + if (!picnum.Exists() && (lumpnum = fileSystem.CheckNumForName (sc.String, FileSys::ns_graphics)) >= 0) { picnum = TexMan.CreateTexture (lumpnum, ETextureType::Decal); } diff --git a/src/gamedata/doomfont.h b/src/gamedata/doomfont.h index b9d14db7d..fedeb513c 100644 --- a/src/gamedata/doomfont.h +++ b/src/gamedata/doomfont.h @@ -18,7 +18,7 @@ void InitDoomFonts() if (fileSystem.CheckNumForName("FONTA_S") >= 0) { int wadfile = -1; - auto a = fileSystem.CheckNumForName("FONTA33", ns_graphics); + auto a = fileSystem.CheckNumForName("FONTA33", FileSys::ns_graphics); if (a != -1) wadfile = fileSystem.GetFileContainer(a); if (wadfile > fileSystem.GetIwadNum()) { @@ -32,10 +32,10 @@ void InitDoomFonts() SmallFont->SetCursor('['); } } - else if (fileSystem.CheckNumForName("STCFN033", ns_graphics) >= 0) + else if (fileSystem.CheckNumForName("STCFN033", FileSys::ns_graphics) >= 0) { int wadfile = -1; - auto a = fileSystem.CheckNumForName("STCFN065", ns_graphics); + auto a = fileSystem.CheckNumForName("STCFN065", FileSys::ns_graphics); if (a != -1) wadfile = fileSystem.GetFileContainer(a); if (wadfile > fileSystem.GetIwadNum()) { @@ -55,7 +55,7 @@ void InitDoomFonts() OriginalSmallFont = new FFont("OriginalSmallFont", "FONTA%02u", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, 1, -1, -1, false, true); OriginalSmallFont->SetCursor('['); } - else if (fileSystem.CheckNumForName("STCFN033", ns_graphics) >= 0) + else if (fileSystem.CheckNumForName("STCFN033", FileSys::ns_graphics) >= 0) { OriginalSmallFont = new FFont("OriginalSmallFont", "STCFN%.3d", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1, -1, false, true, true); } @@ -63,7 +63,7 @@ void InitDoomFonts() if (!(SmallFont2 = V_GetFont("SmallFont2"))) // Only used by Strife { - if (fileSystem.CheckNumForName("STBFN033", ns_graphics) >= 0) + if (fileSystem.CheckNumForName("STBFN033", FileSys::ns_graphics) >= 0) { SmallFont2 = new FFont("SmallFont2", "STBFN%.3d", "defsmallfont2", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1); } diff --git a/src/gamedata/g_mapinfo.cpp b/src/gamedata/g_mapinfo.cpp index 78ffb15a1..bc692cd61 100644 --- a/src/gamedata/g_mapinfo.cpp +++ b/src/gamedata/g_mapinfo.cpp @@ -2596,7 +2596,7 @@ void G_ParseMapInfo (FString basemapinfo) // If that exists we need to skip this one. int wad = fileSystem.GetFileContainer(lump); - int altlump = fileSystem.CheckNumForName("ZMAPINFO", ns_global, wad, true); + int altlump = fileSystem.CheckNumForName("ZMAPINFO", FileSys::ns_global, wad, true); if (altlump >= 0) continue; } @@ -2604,9 +2604,9 @@ void G_ParseMapInfo (FString basemapinfo) { // MAPINFO and ZMAPINFO will override UMAPINFO if in the same WAD. int wad = fileSystem.GetFileContainer(lump); - int altlump = fileSystem.CheckNumForName("ZMAPINFO", ns_global, wad, true); + int altlump = fileSystem.CheckNumForName("ZMAPINFO", FileSys::ns_global, wad, true); if (altlump >= 0) continue; - altlump = fileSystem.CheckNumForName("MAPINFO", ns_global, wad, true); + altlump = fileSystem.CheckNumForName("MAPINFO", FileSys::ns_global, wad, true); if (altlump >= 0) continue; } if (nindex != 2) diff --git a/src/gamedata/g_mapinfo.h b/src/gamedata/g_mapinfo.h index f9e97e0c5..b7e48f301 100644 --- a/src/gamedata/g_mapinfo.h +++ b/src/gamedata/g_mapinfo.h @@ -38,7 +38,6 @@ #include "doomtype.h" #include "vectors.h" #include "sc_man.h" -#include "file_zip.h" #include "screenjob.h" #include "hwrenderer/postprocessing/hw_postprocess.h" #include "hw_viewpointuniforms.h" @@ -349,7 +348,7 @@ struct level_info_t FString AuthorName; int8_t WallVertLight, WallHorizLight; int musicorder; - FCompressedBuffer Snapshot; + FileSys::FCompressedBuffer Snapshot; TArray deferred; float skyspeed1; float skyspeed2; diff --git a/src/gamedata/keysections.cpp b/src/gamedata/keysections.cpp index 8561b6b24..30a3f8d2a 100644 --- a/src/gamedata/keysections.cpp +++ b/src/gamedata/keysections.cpp @@ -165,7 +165,7 @@ void D_LoadWadSettings () while ((lump = fileSystem.FindLump ("KEYCONF", &lastlump)) != -1) { - FileData data = fileSystem.ReadFile (lump); + auto data = fileSystem.ReadFile (lump); const char* conf = data.GetString(); const char *eof = conf + data.GetSize(); diff --git a/src/gamedata/textures/anim_switches.cpp b/src/gamedata/textures/anim_switches.cpp index 36666bc3f..c0485714b 100644 --- a/src/gamedata/textures/anim_switches.cpp +++ b/src/gamedata/textures/anim_switches.cpp @@ -66,7 +66,7 @@ void FTextureAnimator::InitSwitchList () if (lump != -1) { - FileData lumpdata = fileSystem.ReadFile (lump); + auto lumpdata = fileSystem.ReadFile (lump); auto alphSwitchList = lumpdata.GetString(); const char *list_p; FSwitchDef *def1, *def2; diff --git a/src/gamedata/textures/animations.cpp b/src/gamedata/textures/animations.cpp index 51834d4e0..202b5bdb6 100644 --- a/src/gamedata/textures/animations.cpp +++ b/src/gamedata/textures/animations.cpp @@ -203,7 +203,7 @@ void FTextureAnimator::InitAnimated (void) int lumpnum = fileSystem.CheckNumForName ("ANIMATED"); if (lumpnum != -1) { - FileData animatedlump = fileSystem.ReadFile (lumpnum); + auto animatedlump = fileSystem.ReadFile (lumpnum); int animatedlen = fileSystem.FileLength(lumpnum); auto animdefs = animatedlump.GetBytes(); const uint8_t *anim_p; diff --git a/src/gamedata/textures/buildloader.cpp b/src/gamedata/textures/buildloader.cpp index 515635871..2f076e29c 100644 --- a/src/gamedata/textures/buildloader.cpp +++ b/src/gamedata/textures/buildloader.cpp @@ -41,7 +41,7 @@ #include "colormatcher.h" #include "bitmap.h" #include "textures.h" -#include "resourcefile.h" +#include "fs_filesystem.h" #include "image.h" #include "animations.h" #include "texturemanager.h" @@ -84,7 +84,7 @@ static int BuildPaletteTranslation(int lump) return false; } - FileData data = fileSystem.ReadFile(lump); + auto data = fileSystem.ReadFile(lump); auto ipal = data.GetBytes(); FRemapTable opal; diff --git a/src/maploader/edata.cpp b/src/maploader/edata.cpp index 3bc4928f0..fcf82a10d 100644 --- a/src/maploader/edata.cpp +++ b/src/maploader/edata.cpp @@ -520,7 +520,7 @@ void MapLoader::InitED() FScanner sc; if (filename.IsEmpty()) return; - int lump = fileSystem.CheckNumForFullName(filename, true, ns_global); + int lump = fileSystem.CheckNumForFullName(filename, true, FileSys::ns_global); if (lump == -1) return; sc.OpenLumpNum(lump); diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index a72b3b7e4..1a6d67084 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -736,14 +736,14 @@ static int FindGLNodesInWAD(int labellump) glheader.Format("GL_%s", fileSystem.GetFileFullName(labellump)); if (glheader.Len()<=8) { - int gllabel = fileSystem.CheckNumForName(glheader, ns_global, wadfile); + int gllabel = fileSystem.CheckNumForName(glheader, FileSys::ns_global, wadfile); if (gllabel >= 0) return gllabel; } else { // Before scanning the entire WAD directory let's check first whether // it is necessary. - int gllabel = fileSystem.CheckNumForName("GL_LEVEL", ns_global, wadfile); + int gllabel = fileSystem.CheckNumForName("GL_LEVEL", FileSys::ns_global, wadfile); if (gllabel >= 0) { @@ -753,7 +753,7 @@ static int FindGLNodesInWAD(int labellump) { if (fileSystem.GetFileContainer(lump)==wadfile) { - FileData mem = fileSystem.ReadFile(lump); + auto mem = fileSystem.ReadFile(lump); if (MatchHeader(fileSystem.GetFileFullName(labellump), GetStringFromLump(lump))) return lump; } } @@ -1199,11 +1199,11 @@ bool MapLoader::CheckCachedNodes(MapData *map) UNSAFE_CCMD(clearnodecache) { - FileList list; + FileSys::FileList list; FString path = M_GetCachePath(false); path += "/"; - if (!ScanDirectory(list, path, "*", false)) + if (!FileSys::ScanDirectory(list, path, "*", false)) { Printf("Unable to scan node cache directory %s\n", path.GetChars()); return; diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index 56b1e23fe..fdb409c6a 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -733,7 +733,7 @@ bool MapLoader::LoadExtendedNodes (FileReader &dalump, uint32_t id) if (compressed) { FileReader zip; - if (zip.OpenDecompressor(dalump, -1, METHOD_ZLIB, false, true)) + if (zip.OpenDecompressor(dalump, -1, FileSys::METHOD_ZLIB, false, true)) { LoadZNodes(zip, type); return true; @@ -753,7 +753,7 @@ bool MapLoader::LoadExtendedNodes (FileReader &dalump, uint32_t id) { Printf("Error loading nodes: %s\n", error.GetMessage()); } - catch (FileSystemException& error) + catch (FileSys::FileSystemException& error) { Printf("Error loading nodes: %s\n", error.what()); } @@ -1157,7 +1157,7 @@ void MapLoader::LoadSectors (MapData *map, FMissingTextureTracker &missingtex) template bool MapLoader::LoadNodes (MapData * map) { - FileData data; + FileSys::FileData data; int j; int k; nodetype *mn; @@ -3338,7 +3338,7 @@ void MapLoader::LoadLightmap(MapData *map) return; FileReader fr; - if (!fr.OpenDecompressor(map->Reader(ML_LIGHTMAP), -1, METHOD_ZLIB, false, false)) + if (!fr.OpenDecompressor(map->Reader(ML_LIGHTMAP), -1, FileSys::METHOD_ZLIB, false, false)) return; diff --git a/src/maploader/maploader.h b/src/maploader/maploader.h index 93c65f983..6ea2e6121 100644 --- a/src/maploader/maploader.h +++ b/src/maploader/maploader.h @@ -2,8 +2,8 @@ #include "nodebuild.h" #include "g_levellocals.h" +#include "files.h" -class FileReader; struct FStrifeDialogueNode; struct FStrifeDialogueReply; struct Response; diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index e6ed52e9e..2651f24b4 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -66,8 +66,8 @@ void FSavegameManager::ReadSaveStrings() LastSaved = LastAccessed = -1; quickSaveSlot = nullptr; - FileList list; - if (ScanDirectory(list, G_GetSavegamesFolder().GetChars(), "*." SAVEGAME_EXT, true)) + FileSys::FileList list; + if (FileSys::ScanDirectory(list, G_GetSavegamesFolder().GetChars(), "*." SAVEGAME_EXT, true)) { for (auto& entry : list) { @@ -76,7 +76,7 @@ void FSavegameManager::ReadSaveStrings() { bool oldVer = false; bool missing = false; - FResourceLump *info = savegame->FindLump("info.json"); + auto info = savegame->FindLump("info.json"); if (info == nullptr) { // savegame info not found. This is not a savegame so leave it alone. diff --git a/src/p_conversation.h b/src/p_conversation.h index b055d5f4c..d674b3d53 100644 --- a/src/p_conversation.h +++ b/src/p_conversation.h @@ -72,7 +72,5 @@ void P_ResumeConversation (); void P_ConversationCommand (int netcode, int player, uint8_t **stream); -class FileReader; - #endif diff --git a/src/p_setup.h b/src/p_setup.h index 27c646b5b..e9142b356 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -28,7 +28,7 @@ #ifndef __P_SETUP__ #define __P_SETUP__ -#include "resourcefile.h" +#include "fs_filesystem.h" #include "doomdata.h" #include "r_defs.h" #include "nodebuild.h" diff --git a/src/playsim/fragglescript/t_func.cpp b/src/playsim/fragglescript/t_func.cpp index 549c330ae..fc711eac9 100644 --- a/src/playsim/fragglescript/t_func.cpp +++ b/src/playsim/fragglescript/t_func.cpp @@ -54,6 +54,8 @@ #include "s_music.h" #include "texturemanager.h" +using namespace FileSys; + static FRandom pr_script("FScript"); // functions. FParser::SF_ means Script Function not, well.. heh, me diff --git a/src/playsim/p_acs.cpp b/src/playsim/p_acs.cpp index 17f6cc459..6aa85943b 100644 --- a/src/playsim/p_acs.cpp +++ b/src/playsim/p_acs.cpp @@ -1930,7 +1930,7 @@ void FBehaviorContainer::LoadDefaultModules () FScanner sc(lump); while (sc.GetString()) { - int acslump = fileSystem.CheckNumForName (sc.String, ns_acslibrary); + int acslump = fileSystem.CheckNumForName (sc.String, FileSys::ns_acslibrary); if (acslump >= 0) { LoadModule (acslump); @@ -2567,7 +2567,7 @@ bool FBehavior::Init(FLevelLocals *Level, int lumpnum, FileReader * fr, int len, if (parse[i]) { FBehavior *module = NULL; - int lump = fileSystem.CheckNumForName (&parse[i], ns_acslibrary); + int lump = fileSystem.CheckNumForName (&parse[i], FileSys::ns_acslibrary); if (lump < 0) { Printf (TEXTCOLOR_RED "Could not find ACS library %s.\n", &parse[i]); diff --git a/src/playsim/p_acs.h b/src/playsim/p_acs.h index c2013a0f1..695b22948 100644 --- a/src/playsim/p_acs.h +++ b/src/playsim/p_acs.h @@ -38,12 +38,12 @@ #include "doomtype.h" #include "dthinker.h" #include "engineerrors.h" +#include "files.h" #define LOCAL_SIZE 20 #define NUM_MAPVARS 128 class FFont; -class FileReader; struct line_t; class FSerializer; diff --git a/src/playsim/p_user.cpp b/src/playsim/p_user.cpp index 87633398c..66a7e83bb 100644 --- a/src/playsim/p_user.cpp +++ b/src/playsim/p_user.cpp @@ -828,16 +828,16 @@ static int SetupCrouchSprite(AActor *self, int crouchsprite) FString normspritename = sprites[self->SpawnState->sprite].name; FString crouchspritename = sprites[crouchsprite].name; - int spritenorm = fileSystem.CheckNumForName(normspritename + "A1", ns_sprites); + int spritenorm = fileSystem.CheckNumForName(normspritename + "A1", FileSys::ns_sprites); if (spritenorm == -1) { - spritenorm = fileSystem.CheckNumForName(normspritename + "A0", ns_sprites); + spritenorm = fileSystem.CheckNumForName(normspritename + "A0", FileSys::ns_sprites); } - int spritecrouch = fileSystem.CheckNumForName(crouchspritename + "A1", ns_sprites); + int spritecrouch = fileSystem.CheckNumForName(crouchspritename + "A1", FileSys::ns_sprites); if (spritecrouch == -1) { - spritecrouch = fileSystem.CheckNumForName(crouchspritename + "A0", ns_sprites); + spritecrouch = fileSystem.CheckNumForName(crouchspritename + "A0", FileSys::ns_sprites); } if (spritenorm == -1 || spritecrouch == -1) diff --git a/src/r_data/colormaps.cpp b/src/r_data/colormaps.cpp index ad1559c6b..4d9604b61 100644 --- a/src/r_data/colormaps.cpp +++ b/src/r_data/colormaps.cpp @@ -104,11 +104,11 @@ void R_InitColormaps (bool allowCustomColormap) for (uint32_t i = 0; i < NumLumps; i++) { - if (fileSystem.GetFileNamespace(i) == ns_colormaps) + if (fileSystem.GetFileNamespace(i) == FileSys::ns_colormaps) { auto name = fileSystem.GetFileShortName(i); - if (fileSystem.CheckNumForName (name, ns_colormaps) == (int)i) + if (fileSystem.CheckNumForName (name, FileSys::ns_colormaps) == (int)i) { strncpy(cm.name, name, 8); cm.blend = 0; diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index 1490faf26..86100a1cb 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -430,7 +430,7 @@ static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerC } else { - FileData translump = fileSystem.ReadFile(colorset->Lump); + auto translump = fileSystem.ReadFile(colorset->Lump); auto trans = translump.GetBytes(); for (i = start; i <= end; ++i) { @@ -727,7 +727,7 @@ void R_ParseTrnslate() do { sc.MustGetToken(TK_StringConst); - int pallump = fileSystem.CheckNumForFullName(sc.String, true, ns_global); + int pallump = fileSystem.CheckNumForFullName(sc.String, true, FileSys::ns_global); if (pallump >= 0) // { int start = 0; diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 1f6b161a9..58b9336a1 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -349,7 +349,7 @@ void R_InitSpriteDefs () memset(vhashes.Data(), -1, sizeof(VHasher)*vmax); for (i = 0; i < vmax; ++i) { - if (fileSystem.GetFileNamespace(i) == ns_voxels) + if (fileSystem.GetFileNamespace(i) == FileSys::ns_voxels) { size_t namelen; int spin; @@ -715,7 +715,7 @@ void R_InitSkins (void) int lump = fileSystem.CheckNumForName (sc.String, Skins[i].namespc); if (lump == -1) { - lump = fileSystem.CheckNumForFullName (sc.String, true, ns_sounds); + lump = fileSystem.CheckNumForFullName (sc.String, true, FileSys::ns_sounds); } if (lump != -1) { @@ -748,7 +748,7 @@ void R_InitSkins (void) sndlumps[j] = fileSystem.CheckNumForName (sc.String, Skins[i].namespc); if (sndlumps[j] == -1) { // Replacement not found, try finding it in the global namespace - sndlumps[j] = fileSystem.CheckNumForFullName (sc.String, true, ns_sounds); + sndlumps[j] = fileSystem.CheckNumForFullName (sc.String, true, FileSys::ns_sounds); } } } @@ -946,7 +946,7 @@ CCMD (skins) static void R_CreateSkinTranslation (const char *palname) { - FileData lump = fileSystem.ReadFile (palname); + auto lump = fileSystem.ReadFile (palname); auto otherPal = lump.GetBytes(); for (int i = 0; i < 256; ++i) @@ -1016,7 +1016,7 @@ void R_InitSprites () Skins[i].range0end = basetype->IntVar(NAME_ColorRangeEnd); Skins[i].Scale = basetype->Scale; Skins[i].sprite = basetype->SpawnState->sprite; - Skins[i].namespc = ns_global; + Skins[i].namespc = FileSys::ns_global; PlayerClasses[i].Skins.Push (i); diff --git a/src/r_data/v_palette.cpp b/src/r_data/v_palette.cpp index 068edb124..cc6395549 100644 --- a/src/r_data/v_palette.cpp +++ b/src/r_data/v_palette.cpp @@ -44,6 +44,8 @@ #include "m_png.h" #include "v_colortables.h" +using namespace FileSys; + /* Current color blending values */ int BlendR, BlendG, BlendB, BlendA; diff --git a/src/r_data/voxeldef.cpp b/src/r_data/voxeldef.cpp index 128862178..35037158b 100644 --- a/src/r_data/voxeldef.cpp +++ b/src/r_data/voxeldef.cpp @@ -50,6 +50,8 @@ #include "g_level.h" #include "r_data/sprites.h" +using namespace FileSys; + struct VoxelOptions { int DroppedSpin = 0; diff --git a/src/rendering/swrenderer/r_swcolormaps.cpp b/src/rendering/swrenderer/r_swcolormaps.cpp index a2ca4666d..b303712eb 100644 --- a/src/rendering/swrenderer/r_swcolormaps.cpp +++ b/src/rendering/swrenderer/r_swcolormaps.cpp @@ -346,9 +346,9 @@ void SetDefaultColormap (const char *name) uint8_t unremap[256]; uint8_t remap[256]; - lump = fileSystem.CheckNumForFullName (name, true, ns_colormaps); + lump = fileSystem.CheckNumForFullName (name, true, FileSys::ns_colormaps); if (lump == -1) - lump = fileSystem.CheckNumForName (name, ns_global); + lump = fileSystem.CheckNumForName (name, FileSys::ns_global); // [RH] If using BUILD's palette, generate the colormap if (lump == -1 || fileSystem.CheckNumForFullName("palette.dat") >= 0 || fileSystem.CheckNumForFullName("blood.pal") >= 0) diff --git a/src/sound/s_advsound.cpp b/src/sound/s_advsound.cpp index 98d17bc88..4fbc221cd 100644 --- a/src/sound/s_advsound.cpp +++ b/src/sound/s_advsound.cpp @@ -50,6 +50,8 @@ #include "i_system.h" #include "s_music.h" +using namespace FileSys; + // MACROS ------------------------------------------------------------------ #define RANDOM 1 diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index f47666e4e..31a46ca2d 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -191,7 +191,7 @@ static FileReader OpenMusic(const char* musicname) { int lumpnum; lumpnum = fileSystem.CheckNumForFullName(musicname); - if (lumpnum == -1) lumpnum = fileSystem.CheckNumForName(musicname, ns_music); + if (lumpnum == -1) lumpnum = fileSystem.CheckNumForName(musicname, FileSys::ns_music); if (lumpnum == -1) { Printf("Music \"%s\" not found\n", musicname); From c77ece4922793a74ba77243267f9f39c596602ac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 21:36:57 +0200 Subject: [PATCH 044/223] moved private definitions out of public headers. --- src/common/filesystem/include/fs_files.h | 43 ---------------- src/common/filesystem/include/fs_filesystem.h | 3 -- src/common/filesystem/include/resourcefile.h | 50 ------------------- src/common/filesystem/source/file_grp.cpp | 2 +- src/common/filesystem/source/file_lump.cpp | 2 +- src/common/filesystem/source/file_pak.cpp | 2 +- src/common/filesystem/source/file_rff.cpp | 2 +- src/common/filesystem/source/file_ssi.cpp | 2 +- src/common/filesystem/source/file_whres.cpp | 2 +- src/common/filesystem/source/files.cpp | 2 +- .../filesystem/source/files_decompress.cpp | 20 ++++++++ src/common/filesystem/source/files_internal.h | 31 ++++++++++++ src/common/filesystem/source/filesystem.cpp | 14 +++++- src/common/filesystem/source/resourcefile.cpp | 3 +- .../filesystem/source/resourcefile_internal.h | 38 ++++++++++++++ 15 files changed, 111 insertions(+), 105 deletions(-) create mode 100644 src/common/filesystem/source/files_internal.h create mode 100644 src/common/filesystem/source/resourcefile_internal.h diff --git a/src/common/filesystem/include/fs_files.h b/src/common/filesystem/include/fs_files.h index e73282497..c3404a568 100644 --- a/src/common/filesystem/include/fs_files.h +++ b/src/common/filesystem/include/fs_files.h @@ -101,31 +101,6 @@ public: long GetLength () const { return Length; } }; -class MemoryReader : public FileReaderInterface -{ -protected: - const char * bufptr = nullptr; - long FilePos = 0; - - MemoryReader() - {} - -public: - MemoryReader(const char *buffer, long length) - { - bufptr = buffer; - Length = length; - FilePos = 0; - } - - long Tell() const override; - long Seek(long offset, int origin) override; - long Read(void *buffer, long len) override; - char *Gets(char *strbuf, int len) override; - virtual const char *GetBuffer() const override { return bufptr; } -}; - - struct FResourceLump; class FileReader @@ -329,24 +304,6 @@ public: friend class FileSystem; }; -class DecompressorBase : public FileReaderInterface -{ - bool exceptions = false; -public: - // These do not work but need to be defined to satisfy the FileReaderInterface. - // They will just error out when called. - long Tell() const override; - long Seek(long offset, int origin) override; - char* Gets(char* strbuf, int len) override; - void DecompressionError(const char* error, ...) const; - void SetOwnsReader(); - void EnableExceptions(bool on) { exceptions = on; } - -protected: - FileReader* File = nullptr; - FileReader OwnedFile; -}; - class FileWriter { diff --git a/src/common/filesystem/include/fs_filesystem.h b/src/common/filesystem/include/fs_filesystem.h index e97673314..b55949408 100644 --- a/src/common/filesystem/include/fs_filesystem.h +++ b/src/common/filesystem/include/fs_filesystem.h @@ -13,9 +13,6 @@ namespace FileSys { -class FResourceFile; -struct FResourceLump; - union LumpShortName { char String[9]; diff --git a/src/common/filesystem/include/resourcefile.h b/src/common/filesystem/include/resourcefile.h index 91d437d38..f714c7995 100644 --- a/src/common/filesystem/include/resourcefile.h +++ b/src/common/filesystem/include/resourcefile.h @@ -197,56 +197,6 @@ public: FResourceLump *FindLump(const char *name); }; -struct FUncompressedLump : public FResourceLump -{ - int Position; - - virtual FileReader *GetReader(); - virtual int FillCache() override; - virtual int GetFileOffset() { return Position; } - -}; - - -// Base class for uncompressed resource files (WAD, GRP, PAK and single lumps) -class FUncompressedFile : public FResourceFile -{ -protected: - TArray Lumps; - - FUncompressedFile(const char *filename, StringPool* sp); - FUncompressedFile(const char *filename, FileReader &r, StringPool* sp); - virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } -}; - - -// should only be used internally. -struct FExternalLump : public FResourceLump -{ - const char* FileName; - - FExternalLump(const char *_filename, int filesize, StringPool* sp); - virtual int FillCache() override; - -}; - -struct FMemoryLump : public FResourceLump -{ - FMemoryLump(const void* data, int length) - { - RefCount = INT_MAX / 2; - LumpSize = length; - Cache = new char[length]; - memcpy(Cache, data, length); - } - - virtual int FillCache() override - { - RefCount = INT_MAX / 2; // Make sure it never counts down to 0 by resetting it to something high each time it is used. - return 1; - } -}; - } diff --git a/src/common/filesystem/source/file_grp.cpp b/src/common/filesystem/source/file_grp.cpp index bd543a559..b289b121d 100644 --- a/src/common/filesystem/source/file_grp.cpp +++ b/src/common/filesystem/source/file_grp.cpp @@ -33,7 +33,7 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" #include "fs_swap.h" namespace FileSys { diff --git a/src/common/filesystem/source/file_lump.cpp b/src/common/filesystem/source/file_lump.cpp index c9885a126..ad4406a0f 100644 --- a/src/common/filesystem/source/file_lump.cpp +++ b/src/common/filesystem/source/file_lump.cpp @@ -32,7 +32,7 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" namespace FileSys { //========================================================================== diff --git a/src/common/filesystem/source/file_pak.cpp b/src/common/filesystem/source/file_pak.cpp index c8c039209..4e3b3ef93 100644 --- a/src/common/filesystem/source/file_pak.cpp +++ b/src/common/filesystem/source/file_pak.cpp @@ -32,7 +32,7 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" namespace FileSys { diff --git a/src/common/filesystem/source/file_rff.cpp b/src/common/filesystem/source/file_rff.cpp index edb003810..1d3cf15bf 100644 --- a/src/common/filesystem/source/file_rff.cpp +++ b/src/common/filesystem/source/file_rff.cpp @@ -33,7 +33,7 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" #include "fs_swap.h" namespace FileSys { diff --git a/src/common/filesystem/source/file_ssi.cpp b/src/common/filesystem/source/file_ssi.cpp index 0e48ef49d..4b68997f0 100644 --- a/src/common/filesystem/source/file_ssi.cpp +++ b/src/common/filesystem/source/file_ssi.cpp @@ -33,7 +33,7 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" namespace FileSys { //========================================================================== diff --git a/src/common/filesystem/source/file_whres.cpp b/src/common/filesystem/source/file_whres.cpp index 41e418773..efdfd5d39 100644 --- a/src/common/filesystem/source/file_whres.cpp +++ b/src/common/filesystem/source/file_whres.cpp @@ -34,7 +34,7 @@ ** */ -#include "resourcefile.h" +#include "resourcefile_internal.h" #include "fs_stringpool.h" #include "fs_swap.h" diff --git a/src/common/filesystem/source/files.cpp b/src/common/filesystem/source/files.cpp index 4d92cc25c..5cb1bd343 100644 --- a/src/common/filesystem/source/files.cpp +++ b/src/common/filesystem/source/files.cpp @@ -34,7 +34,7 @@ */ #include -#include "fs_files.h" +#include "files_internal.h" namespace FileSys { diff --git a/src/common/filesystem/source/files_decompress.cpp b/src/common/filesystem/source/files_decompress.cpp index 5948177cf..86529716a 100644 --- a/src/common/filesystem/source/files_decompress.cpp +++ b/src/common/filesystem/source/files_decompress.cpp @@ -46,6 +46,26 @@ namespace FileSys { using namespace byteswap; + +class DecompressorBase : public FileReaderInterface +{ + bool exceptions = false; +public: + // These do not work but need to be defined to satisfy the FileReaderInterface. + // They will just error out when called. + long Tell() const override; + long Seek(long offset, int origin) override; + char* Gets(char* strbuf, int len) override; + void DecompressionError(const char* error, ...) const; + void SetOwnsReader(); + void EnableExceptions(bool on) { exceptions = on; } + +protected: + FileReader* File = nullptr; + FileReader OwnedFile; +}; + + //========================================================================== // // DecompressionError diff --git a/src/common/filesystem/source/files_internal.h b/src/common/filesystem/source/files_internal.h new file mode 100644 index 000000000..34e73a070 --- /dev/null +++ b/src/common/filesystem/source/files_internal.h @@ -0,0 +1,31 @@ +#pragma once + +#include "fs_files.h" + +namespace FileSys { + +class MemoryReader : public FileReaderInterface +{ +protected: + const char * bufptr = nullptr; + long FilePos = 0; + + MemoryReader() + {} + +public: + MemoryReader(const char *buffer, long length) + { + bufptr = buffer; + Length = length; + FilePos = 0; + } + + long Tell() const override; + long Seek(long offset, int origin) override; + long Read(void *buffer, long len) override; + char *Gets(char *strbuf, int len) override; + virtual const char *GetBuffer() const override { return bufptr; } +}; + +} diff --git a/src/common/filesystem/source/filesystem.cpp b/src/common/filesystem/source/filesystem.cpp index c8623765e..2344f09cc 100644 --- a/src/common/filesystem/source/filesystem.cpp +++ b/src/common/filesystem/source/filesystem.cpp @@ -41,6 +41,7 @@ #include #include +#include "resourcefile_internal.h" #include "fs_filesystem.h" #include "fs_findfile.h" #include "md5.hpp" @@ -320,10 +321,21 @@ int FileSystem::AddExternalFile(const char *filename) // //========================================================================== +struct FMemoryLump : public FResourceLump +{ + FMemoryLump(const void* data, int length) + { + RefCount = -1; + LumpSize = length; + Cache = new char[length]; + memcpy(Cache, data, length); + } +}; + int FileSystem::AddFromBuffer(const char* name, const char* type, char* data, int size, int id, int flags) { std::string fullname = name; - fullname += ':'; + fullname += '.'; fullname += type; auto newlump = new FMemoryLump(data, size); newlump->LumpNameSetup(fullname.c_str(), stringpool); diff --git a/src/common/filesystem/source/resourcefile.cpp b/src/common/filesystem/source/resourcefile.cpp index 8a17c09a0..079998df9 100644 --- a/src/common/filesystem/source/resourcefile.cpp +++ b/src/common/filesystem/source/resourcefile.cpp @@ -35,9 +35,10 @@ */ #include -#include "resourcefile.h" +#include "resourcefile_internal.h" #include "md5.hpp" #include "fs_stringpool.h" +#include "files_internal.h" namespace FileSys { diff --git a/src/common/filesystem/source/resourcefile_internal.h b/src/common/filesystem/source/resourcefile_internal.h new file mode 100644 index 000000000..4371a7460 --- /dev/null +++ b/src/common/filesystem/source/resourcefile_internal.h @@ -0,0 +1,38 @@ +#pragma once + +#include "resourcefile.h" + +namespace FileSys { +struct FUncompressedLump : public FResourceLump +{ + int Position; + + virtual FileReader *GetReader(); + virtual int FillCache() override; + virtual int GetFileOffset() { return Position; } + +}; + +// Base class for uncompressed resource files (WAD, GRP, PAK and single lumps) +class FUncompressedFile : public FResourceFile +{ +protected: + TArray Lumps; + + FUncompressedFile(const char *filename, StringPool* sp); + FUncompressedFile(const char *filename, FileReader &r, StringPool* sp); + virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; } +}; + + +// should only be used internally. +struct FExternalLump : public FResourceLump +{ + const char* FileName; + + FExternalLump(const char *_filename, int filesize, StringPool* sp); + virtual int FillCache() override; + +}; + +} \ No newline at end of file From 17484770868554e9295fc2e9d71055c66a443e88 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 22:12:34 +0200 Subject: [PATCH 045/223] - use FileData for readinf WebP --- src/common/textures/formats/webptexture.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/common/textures/formats/webptexture.cpp b/src/common/textures/formats/webptexture.cpp index dd9a9c388..64cc46d08 100644 --- a/src/common/textures/formats/webptexture.cpp +++ b/src/common/textures/formats/webptexture.cpp @@ -124,8 +124,7 @@ PalettedPixels FWebPTexture::CreatePalettedPixels(int conversion) int FWebPTexture::CopyPixels(FBitmap *bmp, int conversion) { WebPDecoderConfig config; - auto lump = fileSystem.OpenFileReader(SourceLump); - auto bytes = lump.Read(); + auto bytes = fileSystem.ReadFile(SourceLump); if (WebPInitDecoderConfig(&config) == false) return 0; @@ -137,7 +136,7 @@ int FWebPTexture::CopyPixels(FBitmap *bmp, int conversion) config.output.u.RGBA.stride = bmp->GetPitch(); config.output.is_external_memory = 1; - (void)WebPDecode(bytes.data(), bytes.size(), &config); + (void)WebPDecode(bytes.GetBytes(), bytes.GetSize(), &config); return 0; } From 42283f56abe62e7487dc67634da26e5029a64760 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 22:35:39 +0200 Subject: [PATCH 046/223] - added a quick header check for WebP before loading the entire file for real identification. This allows quick rejection of virtually everything that's not a WebP without loading the entire file first. --- src/common/textures/formats/webptexture.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/common/textures/formats/webptexture.cpp b/src/common/textures/formats/webptexture.cpp index 64cc46d08..622c8e701 100644 --- a/src/common/textures/formats/webptexture.cpp +++ b/src/common/textures/formats/webptexture.cpp @@ -56,6 +56,12 @@ FImageSource *WebPImage_TryCreate(FileReader &file, int lumpnum) { int width = 0, height = 0; int xoff = 0, yoff = 0; + file.Seek(0, FileReader::SeekSet); + + uint8_t header[12]; + if (file.Read(header, 12) != 12) return nullptr; + if (memcmp(header, "RIFF", 4) || memcmp(header + 8, "WEBP", 4)) return nullptr; + file.Seek(0, FileReader::SeekSet); auto bytes = file.Read(); @@ -76,7 +82,7 @@ FImageSource *WebPImage_TryCreate(FileReader &file, int lumpnum) } return new FWebPTexture(lumpnum, width, height, xoff, yoff); } - return NULL; + return nullptr; } FWebPTexture::FWebPTexture(int lumpnum, int w, int h, int xoff, int yoff) From 5a1b858c0e94afb6e32cb87a285c6107d0e00944 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 22:59:29 +0200 Subject: [PATCH 047/223] - added some safety checks for reading empty lumps into a std::vector. These can trip the internal safety checks, even though nothing gets read in. --- src/common/filesystem/include/fs_files.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/common/filesystem/include/fs_files.h b/src/common/filesystem/include/fs_files.h index c3404a568..8e8f6927f 100644 --- a/src/common/filesystem/include/fs_files.h +++ b/src/common/filesystem/include/fs_files.h @@ -194,8 +194,11 @@ public: std::vector Read(size_t len) { std::vector buffer(len); - Size length = mReader->Read(&buffer[0], (long)len); - buffer.resize((size_t)length); + if (len > 0) + { + Size length = mReader->Read(&buffer[0], (long)len); + buffer.resize((size_t)length); + } return buffer; } @@ -208,9 +211,13 @@ public: { auto len = GetLength(); std::vector buffer(len + padding); - Size length = mReader->Read(&buffer[0], (long)len); - if (length < len) buffer.clear(); - else memset(buffer.data() + len, 0, padding); + if (len > 0) + { + Size length = mReader->Read(&buffer[0], (long)len); + if (length < len) buffer.clear(); + else memset(buffer.data() + len, 0, padding); + } + else buffer[0] = 0; return buffer; } From 44a3bd719c739cd9f05e89418c1bb4cba06eb703 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 23 Aug 2023 01:34:19 +0600 Subject: [PATCH 048/223] JPEG XL implementation --- CMakeLists.txt | 16 +- src/CMakeLists.txt | 11 + src/common/textures/formats/jpegxltexture.cpp | 221 ++++++++++++++++++ src/common/textures/image.cpp | 6 + vcpkg.json | 11 + 5 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 src/common/textures/formats/jpegxltexture.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d59560964..aa5dd2700 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,10 @@ if (OPENAL_SOFT_VCPKG) list(APPEND VCPKG_MANIFEST_FEATURES "vcpkg-openal-soft") endif() +if (NOT DEFINED JPEG_XL OR JPEG_XL) + list(APPEND VCPKG_MANIFEST_FEATURES "vcpkg-libjxl") +endif() + if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR (NOT CMAKE_SYSTEM_NAME AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")) # Force static triplet on Windows set(VCPKG_TARGET_TRIPLET "x64-windows-static") @@ -43,6 +47,10 @@ if (NOT VCPKG_TOOLCHAIN) set(VCPKG_MANIFEST_FEATURES) endif() +option(JPEG_XL "Enable JPEG XL support" ON) + +include ( FindPkgConfig ) + set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -219,7 +227,9 @@ find_package( VPX ) find_package( ZLIB ) find_package( WebP ) if (NOT WebP_FOUND) - include(FindPkgConfig) + if (NOT PKG_CONFIG_FOUND) + message(SEND_ERROR "pkgconfig not found") + endif() pkg_check_modules(libwebp IMPORTED_TARGET libwebp) if (NOT TARGET PkgConfig::libwebp) message(SEND_ERROR "libwebp not found") @@ -232,6 +242,10 @@ if (NOT WebP_FOUND) add_library(WebP::libwebpmux ALIAS PkgConfig::libwebpmux) endif() +if (PKG_CONFIG_FOUND AND JPEG_XL) + pkg_check_modules( libjxl IMPORTED_TARGET libjxl ) +endif() + include( TargetArch ) target_architecture(TARGET_ARCHITECTURE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 35587dfa8..3d174d7b2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -320,6 +320,11 @@ add_custom_target( revision_check ALL # required libraries set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${CMAKE_DL_LIBS}" "${DRPC_LIBRARIES}") + +if (TARGET PkgConfig::libjxl) + list( APPEND PROJECT_LIBRARIES PkgConfig::libjxl ) +endif() + if (HAVE_VULKAN) list( APPEND PROJECT_LIBRARIES "zvulkan" ) endif() @@ -1240,6 +1245,12 @@ set_source_files_properties( common/engine/sc_man.cpp PROPERTIES OBJECT_DEPENDS set_source_files_properties( ${NOT_COMPILED_SOURCE_FILES} PROPERTIES HEADER_FILE_ONLY TRUE ) set_source_files_properties( ${ZDOOM_NONPCH_SOURCES} common/textures/hires/hqresize.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE ) +if (TARGET PkgConfig::libjxl) + target_compile_definitions(zdoom PRIVATE -DHAVE_JPEGXL=1) + target_sources(zdoom PRIVATE common/textures/formats/jpegxltexture.cpp) +else() + message( STATUS "Compiling without JPEG XL support" ) +endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") # [BL] Solaris requires these to be explicitly linked. diff --git a/src/common/textures/formats/jpegxltexture.cpp b/src/common/textures/formats/jpegxltexture.cpp new file mode 100644 index 000000000..914922743 --- /dev/null +++ b/src/common/textures/formats/jpegxltexture.cpp @@ -0,0 +1,221 @@ +/* +** jpegxltexture.cpp +** Texture class for JPEG XL images +** +**--------------------------------------------------------------------------- +** Copyright 2023 Cacodemon345 +** Copyright 2022 Dominic Szablewski +** 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 + +#include "files.h" +#include "filesystem.h" +#include "bitmap.h" +#include "imagehelpers.h" +#include "image.h" + +class FJPEGXLTexture : public FImageSource +{ + +public: + FJPEGXLTexture (int lumpnum, int w, int h, int xoffset, int yoffset, bool transparent = true); + PalettedPixels CreatePalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion) override; +}; + +FImageSource *JPEGXLImage_TryCreate(FileReader & file, int lumpnum) +{ + JxlBasicInfo info; + file.Seek(0, FileReader::SeekSet); + auto array = file.Read(); + int width = 0, height = 0, xoffset = 0, yoffset = 0; + // TODO: Revisit this again when the box decoding API is well understood. + (void)xoffset; + (void)yoffset; + + auto jxlDecoder = JxlDecoderMake(nullptr); + if (!jxlDecoder) + { + return nullptr; + } + + auto jxlDecoderPtr = jxlDecoder.get(); + if (JxlDecoderSubscribeEvents(jxlDecoderPtr, JXL_DEC_BASIC_INFO) != JXL_DEC_SUCCESS) + { + return nullptr; + } + JxlDecoderSetInput(jxlDecoderPtr, array.Data(), array.Size()); + JxlDecoderCloseInput(jxlDecoderPtr); + + for (;;) + { + JxlDecoderStatus status = JxlDecoderProcessInput(jxlDecoderPtr); + + switch (status) + { + case JXL_DEC_ERROR: + return nullptr; + + case JXL_DEC_SUCCESS: + case JXL_DEC_BASIC_INFO: + { + if (JxlDecoderGetBasicInfo(jxlDecoderPtr, &info) != JXL_DEC_SUCCESS) + return nullptr; + + width = info.xsize; + height = info.ysize; + if (width && height) + return new FJPEGXLTexture(lumpnum, width, height, xoffset, yoffset, !!info.alpha_bits); + else + return nullptr; + break; + } + } + } + + return nullptr; +} + +FJPEGXLTexture::FJPEGXLTexture (int lumpnum, int w, int h, int xoffset, int yoffset, bool transparent) + : FImageSource(lumpnum) +{ + Width = w; + Height = h; + LeftOffset = xoffset; + TopOffset = yoffset; + if (!transparent) + bMasked = bTranslucent = false; +} + +PalettedPixels FJPEGXLTexture::CreatePalettedPixels(int conversion) +{ + FBitmap bitmap; + bitmap.Create(Width, Height); + CopyPixels(&bitmap, conversion); + const uint8_t *data = bitmap.GetPixels(); + + uint8_t *dest_p; + int dest_adv = Height; + int dest_rew = Width * Height - 1; + + PalettedPixels Pixels(Width * Height); + dest_p = Pixels.Data(); + + bool doalpha = conversion == luminance; + // Convert the source image from row-major to column-major format and remap it + for (int y = Height; y != 0; --y) + { + for (int x = Width; x != 0; --x) + { + int b = *data++; + int g = *data++; + int r = *data++; + int a = *data++; + if (a < 128) + *dest_p = 0; + else + *dest_p = ImageHelpers::RGBToPalette(doalpha, r, g, b); + dest_p += dest_adv; + } + dest_p -= dest_rew; + } + return Pixels; +} + +int FJPEGXLTexture::CopyPixels(FBitmap *bmp, int conversion) +{ + JxlBasicInfo info; + int width = 0, height = 0; + uint8_t* pixels = nullptr; + JxlPixelFormat format = {4, JXL_TYPE_UINT8, JXL_NATIVE_ENDIAN, 0}; + auto jxlDecoder = JxlDecoderMake(nullptr); + if (!jxlDecoder) + { + return 0; + } + + auto jxlDecoderPtr = jxlDecoder.get(); + if (JxlDecoderSubscribeEvents(jxlDecoderPtr, JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE) != JXL_DEC_SUCCESS) + { + return 0; + } + + auto lump = fileSystem.OpenFileReader(SourceLump); + auto array = lump.Read(); + JxlDecoderSetInput(jxlDecoderPtr, array.Data(), array.Size()); + JxlDecoderCloseInput(jxlDecoderPtr); + + for (;;) + { + JxlDecoderStatus status = JxlDecoderProcessInput(jxlDecoderPtr); + + switch (status) + { + case JXL_DEC_ERROR: + return 0; + + case JXL_DEC_BASIC_INFO: + { + if (JxlDecoderGetBasicInfo(jxlDecoderPtr, &info) != JXL_DEC_SUCCESS) + return 0; + + width = info.xsize; + height = info.ysize; + if (width != Width && height != Height) + return 0; + break; + } + + case JXL_DEC_NEED_IMAGE_OUT_BUFFER: + { + size_t bufferSize = 0; + if (JxlDecoderImageOutBufferSize(jxlDecoderPtr, &format, &bufferSize) != JXL_DEC_SUCCESS) + return 0; + + if (bufferSize != (Width * Height * 4)) + return 0; + + pixels = new uint8_t[Width * Height * 4]; + + if (JxlDecoderSetImageOutBuffer(jxlDecoderPtr, &format, pixels, bufferSize) != JXL_DEC_SUCCESS) + return 0; + break; + } + + case JXL_DEC_FULL_IMAGE: + { + break; + } + + case JXL_DEC_SUCCESS: + { + bmp->CopyPixelDataRGB(0, 0, pixels, Width, Height, 4, Width * 4, 0, CF_RGBA); + + return bMasked ? -1 : 0; + } + } + } +} \ No newline at end of file diff --git a/src/common/textures/image.cpp b/src/common/textures/image.cpp index dcd1f28d3..bd6b9d285 100644 --- a/src/common/textures/image.cpp +++ b/src/common/textures/image.cpp @@ -324,6 +324,9 @@ FImageSource *TGAImage_TryCreate(FileReader &, int lumpnum); FImageSource *StbImage_TryCreate(FileReader &, int lumpnum); FImageSource *QOIImage_TryCreate(FileReader &, int lumpnum); FImageSource *WebPImage_TryCreate(FileReader &, int lumpnum); +#ifdef HAVE_JPEGXL +FImageSource *JPEGXLImage_TryCreate(FileReader &, int lumpnum); +#endif FImageSource *AnmImage_TryCreate(FileReader &, int lumpnum); FImageSource *RawPageImage_TryCreate(FileReader &, int lumpnum); FImageSource *FlatImage_TryCreate(FileReader &, int lumpnum); @@ -346,6 +349,9 @@ FImageSource * FImageSource::GetImage(int lumpnum, bool isflat) { StbImage_TryCreate, false }, { QOIImage_TryCreate, false }, { WebPImage_TryCreate, false }, +#ifdef HAVE_JPEGXL + { JPEGXLImage_TryCreate, false }, +#endif { TGAImage_TryCreate, false }, { AnmImage_TryCreate, false }, { StartupPageImage_TryCreate, false }, diff --git a/vcpkg.json b/vcpkg.json index d89c12d12..998fceab7 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -24,6 +24,17 @@ "platform": "!windows | (windows & static & staticcrt)" } ] + }, + "vcpkg-libjxl": + { + "description": "Use libjxl provided by vcpkg.", + "dependencies": [ + { + "name": "libjxl", + "default-features": false, + "platform": "!windows | (windows & static & staticcrt)" + } + ] } }, "dependencies": [ From 145044ea34dd7948db15df6a59f924530f6f34b6 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 23 Aug 2023 02:21:16 +0600 Subject: [PATCH 049/223] Check if JPEG_XL is enabled instead of just relying on library existence alone --- src/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3d174d7b2..c72db95dc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -321,7 +321,7 @@ add_custom_target( revision_check ALL set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${CMAKE_DL_LIBS}" "${DRPC_LIBRARIES}") -if (TARGET PkgConfig::libjxl) +if (TARGET PkgConfig::libjxl AND JPEG_XL) list( APPEND PROJECT_LIBRARIES PkgConfig::libjxl ) endif() @@ -1245,7 +1245,7 @@ set_source_files_properties( common/engine/sc_man.cpp PROPERTIES OBJECT_DEPENDS set_source_files_properties( ${NOT_COMPILED_SOURCE_FILES} PROPERTIES HEADER_FILE_ONLY TRUE ) set_source_files_properties( ${ZDOOM_NONPCH_SOURCES} common/textures/hires/hqresize.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE ) -if (TARGET PkgConfig::libjxl) +if (TARGET PkgConfig::libjxl AND JPEG_XL) target_compile_definitions(zdoom PRIVATE -DHAVE_JPEGXL=1) target_sources(zdoom PRIVATE common/textures/formats/jpegxltexture.cpp) else() From 99fd354dd91a7aeae4f6fdee0cd12f582299e89a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 23 Aug 2023 02:22:25 +0600 Subject: [PATCH 050/223] Fix copyright mistake --- src/common/textures/formats/jpegxltexture.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/textures/formats/jpegxltexture.cpp b/src/common/textures/formats/jpegxltexture.cpp index 914922743..3019ba929 100644 --- a/src/common/textures/formats/jpegxltexture.cpp +++ b/src/common/textures/formats/jpegxltexture.cpp @@ -4,7 +4,6 @@ ** **--------------------------------------------------------------------------- ** Copyright 2023 Cacodemon345 -** Copyright 2022 Dominic Szablewski ** All rights reserved. ** ** Permission is hereby granted, free of charge, to any person obtaining a copy @@ -218,4 +217,4 @@ int FJPEGXLTexture::CopyPixels(FBitmap *bmp, int conversion) } } } -} \ No newline at end of file +} From be2f9c86603577b8a5019c19aeaba31204a6f2ba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 23:09:47 +0200 Subject: [PATCH 051/223] - added DSDA's passover/nopassover keys to the MAPINFO parser. --- src/gamedata/g_mapinfo.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/gamedata/g_mapinfo.cpp b/src/gamedata/g_mapinfo.cpp index bc692cd61..ab842582f 100644 --- a/src/gamedata/g_mapinfo.cpp +++ b/src/gamedata/g_mapinfo.cpp @@ -1695,6 +1695,7 @@ enum EMIType MITYPE_CLRFLAG3, MITYPE_SCFLAGS3, MITYPE_COMPATFLAG, + MITYPE_CLRCOMPATFLAG, }; struct MapInfoFlagHandler @@ -1799,6 +1800,8 @@ MapFlagHandlers[] = { "avoidmelee", MITYPE_SETFLAG3, LEVEL3_AVOIDMELEE, 0 }, { "attenuatelights", MITYPE_SETFLAG3, LEVEL3_ATTENUATE, 0 }, { "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes + { "nopassover", MITYPE_COMPATFLAG, COMPATF_NO_PASSMOBJ, 0 }, + { "passover", MITYPE_CLRCOMPATFLAG, COMPATF_NO_PASSMOBJ, 0 }, { "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 }, { "compat_stairs", MITYPE_COMPATFLAG, COMPATF_STAIRINDEX, 0 }, { "compat_limitpain", MITYPE_COMPATFLAG, COMPATF_LIMITPAIN, 0 }, @@ -1950,6 +1953,13 @@ void FMapInfoParser::ParseMapDefinition(level_info_t &info) info.flags3 = (info.flags3 & handler->data2) | handler->data1; break; + case MITYPE_CLRCOMPATFLAG: + info.compatflags &= ~handler->data1; + info.compatflags2 &= ~handler->data2; + info.compatmask |= handler->data1; + info.compatmask2 |= handler->data2; + break; + case MITYPE_COMPATFLAG: { int set = 1; From e28d3b7f0be43b6b05eab2fa079a98d4c2032f0a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 22 Aug 2023 23:14:40 +0200 Subject: [PATCH 052/223] - fix directory check in POSIX directory loader. --- src/common/filesystem/source/fs_findfile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/filesystem/source/fs_findfile.cpp b/src/common/filesystem/source/fs_findfile.cpp index 39851ce08..cf6e69d66 100644 --- a/src/common/filesystem/source/fs_findfile.cpp +++ b/src/common/filesystem/source/fs_findfile.cpp @@ -164,7 +164,7 @@ static int FS_FindAttr(findstate_t *const fileinfo) const std::string path = fileinfo->path + ent->d_name; bool isdir; - if (DirEntryExists(path.c_str(), &isdir)) + if (FS_DirEntryExists(path.c_str(), &isdir)) { return isdir ? FA_DIREC : 0; } From bfefc12427b720c4a7491c1113510d04af1464d7 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 23 Aug 2023 11:47:54 +0300 Subject: [PATCH 053/223] - fixed a bunch of Linux and macOS compilation errors --- src/common/filesystem/include/fs_files.h | 1 + src/common/filesystem/source/fs_findfile.cpp | 3 ++- src/common/textures/formats/jpegxltexture.cpp | 4 ++-- src/common/utility/findfile.cpp | 3 +++ src/rendering/swrenderer/r_renderer.h | 1 - 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/common/filesystem/include/fs_files.h b/src/common/filesystem/include/fs_files.h index 8e8f6927f..878122e82 100644 --- a/src/common/filesystem/include/fs_files.h +++ b/src/common/filesystem/include/fs_files.h @@ -41,6 +41,7 @@ #include #include #include +#include #include "fs_swap.h" #include "tarray.h" diff --git a/src/common/filesystem/source/fs_findfile.cpp b/src/common/filesystem/source/fs_findfile.cpp index cf6e69d66..086642bb5 100644 --- a/src/common/filesystem/source/fs_findfile.cpp +++ b/src/common/filesystem/source/fs_findfile.cpp @@ -33,6 +33,7 @@ */ #include "fs_findfile.h" +#include #include namespace FileSys { @@ -175,7 +176,7 @@ static int FS_FindAttr(findstate_t *const fileinfo) std::string FS_FullPath(const char* directory) { // todo - return directory + return directory; } static size_t FS_GetFileSize(findstate_t* handle, const char* pathname) diff --git a/src/common/textures/formats/jpegxltexture.cpp b/src/common/textures/formats/jpegxltexture.cpp index 3019ba929..01e798cbc 100644 --- a/src/common/textures/formats/jpegxltexture.cpp +++ b/src/common/textures/formats/jpegxltexture.cpp @@ -66,7 +66,7 @@ FImageSource *JPEGXLImage_TryCreate(FileReader & file, int lumpnum) { return nullptr; } - JxlDecoderSetInput(jxlDecoderPtr, array.Data(), array.Size()); + JxlDecoderSetInput(jxlDecoderPtr, array.data(), array.size()); JxlDecoderCloseInput(jxlDecoderPtr); for (;;) @@ -164,7 +164,7 @@ int FJPEGXLTexture::CopyPixels(FBitmap *bmp, int conversion) auto lump = fileSystem.OpenFileReader(SourceLump); auto array = lump.Read(); - JxlDecoderSetInput(jxlDecoderPtr, array.Data(), array.Size()); + JxlDecoderSetInput(jxlDecoderPtr, array.data(), array.size()); JxlDecoderCloseInput(jxlDecoderPtr); for (;;) diff --git a/src/common/utility/findfile.cpp b/src/common/utility/findfile.cpp index ff1e53f4f..e2c2ee707 100644 --- a/src/common/utility/findfile.cpp +++ b/src/common/utility/findfile.cpp @@ -40,6 +40,9 @@ #include "i_system.h" #include "fs_findfile.h" +#ifdef __unix__ +#include +#endif // __unix__ //========================================================================== // diff --git a/src/rendering/swrenderer/r_renderer.h b/src/rendering/swrenderer/r_renderer.h index 2ad6c7900..7d873f5f0 100644 --- a/src/rendering/swrenderer/r_renderer.h +++ b/src/rendering/swrenderer/r_renderer.h @@ -11,7 +11,6 @@ class AActor; class player_t; struct sector_t; class FCanvasTexture; -class FileWriter; class DCanvas; struct FLevelLocals; class PClassActor; From 79be69ec4a15b6d8da7989db2d4963456406a14c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 23 Aug 2023 14:57:22 +0300 Subject: [PATCH 054/223] - implemented `FS_FullPath()` function for POSIX --- src/common/filesystem/source/fs_findfile.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/common/filesystem/source/fs_findfile.cpp b/src/common/filesystem/source/fs_findfile.cpp index 086642bb5..689a5d644 100644 --- a/src/common/filesystem/source/fs_findfile.cpp +++ b/src/common/filesystem/source/fs_findfile.cpp @@ -63,6 +63,8 @@ enum #ifndef _WIN32 +#include +#include #include #include #include @@ -175,7 +177,11 @@ static int FS_FindAttr(findstate_t *const fileinfo) std::string FS_FullPath(const char* directory) { - // todo + char fullpath[PATH_MAX]; + + if (realpath(directory, fullpath) != nullptr) + return fullpath; + return directory; } From 53d8a5bb2cb3b4f5576d9286731ad5a4bd972949 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 23 Aug 2023 18:11:11 +0200 Subject: [PATCH 055/223] - Reverted JPEG XL support because the project is not really usable on vcpkg. --- CMakeLists.txt | 16 +- src/CMakeLists.txt | 11 - src/common/textures/formats/jpegxltexture.cpp | 220 ------------------ src/common/textures/image.cpp | 6 - vcpkg.json | 11 - 5 files changed, 1 insertion(+), 263 deletions(-) delete mode 100644 src/common/textures/formats/jpegxltexture.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index aa5dd2700..d59560964 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,10 +24,6 @@ if (OPENAL_SOFT_VCPKG) list(APPEND VCPKG_MANIFEST_FEATURES "vcpkg-openal-soft") endif() -if (NOT DEFINED JPEG_XL OR JPEG_XL) - list(APPEND VCPKG_MANIFEST_FEATURES "vcpkg-libjxl") -endif() - if (CMAKE_SYSTEM_NAME STREQUAL "Windows" OR (NOT CMAKE_SYSTEM_NAME AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")) # Force static triplet on Windows set(VCPKG_TARGET_TRIPLET "x64-windows-static") @@ -47,10 +43,6 @@ if (NOT VCPKG_TOOLCHAIN) set(VCPKG_MANIFEST_FEATURES) endif() -option(JPEG_XL "Enable JPEG XL support" ON) - -include ( FindPkgConfig ) - set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -227,9 +219,7 @@ find_package( VPX ) find_package( ZLIB ) find_package( WebP ) if (NOT WebP_FOUND) - if (NOT PKG_CONFIG_FOUND) - message(SEND_ERROR "pkgconfig not found") - endif() + include(FindPkgConfig) pkg_check_modules(libwebp IMPORTED_TARGET libwebp) if (NOT TARGET PkgConfig::libwebp) message(SEND_ERROR "libwebp not found") @@ -242,10 +232,6 @@ if (NOT WebP_FOUND) add_library(WebP::libwebpmux ALIAS PkgConfig::libwebpmux) endif() -if (PKG_CONFIG_FOUND AND JPEG_XL) - pkg_check_modules( libjxl IMPORTED_TARGET libjxl ) -endif() - include( TargetArch ) target_architecture(TARGET_ARCHITECTURE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c72db95dc..35587dfa8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -320,11 +320,6 @@ add_custom_target( revision_check ALL # required libraries set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${CMAKE_DL_LIBS}" "${DRPC_LIBRARIES}") - -if (TARGET PkgConfig::libjxl AND JPEG_XL) - list( APPEND PROJECT_LIBRARIES PkgConfig::libjxl ) -endif() - if (HAVE_VULKAN) list( APPEND PROJECT_LIBRARIES "zvulkan" ) endif() @@ -1245,12 +1240,6 @@ set_source_files_properties( common/engine/sc_man.cpp PROPERTIES OBJECT_DEPENDS set_source_files_properties( ${NOT_COMPILED_SOURCE_FILES} PROPERTIES HEADER_FILE_ONLY TRUE ) set_source_files_properties( ${ZDOOM_NONPCH_SOURCES} common/textures/hires/hqresize.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE ) -if (TARGET PkgConfig::libjxl AND JPEG_XL) - target_compile_definitions(zdoom PRIVATE -DHAVE_JPEGXL=1) - target_sources(zdoom PRIVATE common/textures/formats/jpegxltexture.cpp) -else() - message( STATUS "Compiling without JPEG XL support" ) -endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") # [BL] Solaris requires these to be explicitly linked. diff --git a/src/common/textures/formats/jpegxltexture.cpp b/src/common/textures/formats/jpegxltexture.cpp deleted file mode 100644 index 01e798cbc..000000000 --- a/src/common/textures/formats/jpegxltexture.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/* -** jpegxltexture.cpp -** Texture class for JPEG XL images -** -**--------------------------------------------------------------------------- -** Copyright 2023 Cacodemon345 -** 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 - -#include "files.h" -#include "filesystem.h" -#include "bitmap.h" -#include "imagehelpers.h" -#include "image.h" - -class FJPEGXLTexture : public FImageSource -{ - -public: - FJPEGXLTexture (int lumpnum, int w, int h, int xoffset, int yoffset, bool transparent = true); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; -}; - -FImageSource *JPEGXLImage_TryCreate(FileReader & file, int lumpnum) -{ - JxlBasicInfo info; - file.Seek(0, FileReader::SeekSet); - auto array = file.Read(); - int width = 0, height = 0, xoffset = 0, yoffset = 0; - // TODO: Revisit this again when the box decoding API is well understood. - (void)xoffset; - (void)yoffset; - - auto jxlDecoder = JxlDecoderMake(nullptr); - if (!jxlDecoder) - { - return nullptr; - } - - auto jxlDecoderPtr = jxlDecoder.get(); - if (JxlDecoderSubscribeEvents(jxlDecoderPtr, JXL_DEC_BASIC_INFO) != JXL_DEC_SUCCESS) - { - return nullptr; - } - JxlDecoderSetInput(jxlDecoderPtr, array.data(), array.size()); - JxlDecoderCloseInput(jxlDecoderPtr); - - for (;;) - { - JxlDecoderStatus status = JxlDecoderProcessInput(jxlDecoderPtr); - - switch (status) - { - case JXL_DEC_ERROR: - return nullptr; - - case JXL_DEC_SUCCESS: - case JXL_DEC_BASIC_INFO: - { - if (JxlDecoderGetBasicInfo(jxlDecoderPtr, &info) != JXL_DEC_SUCCESS) - return nullptr; - - width = info.xsize; - height = info.ysize; - if (width && height) - return new FJPEGXLTexture(lumpnum, width, height, xoffset, yoffset, !!info.alpha_bits); - else - return nullptr; - break; - } - } - } - - return nullptr; -} - -FJPEGXLTexture::FJPEGXLTexture (int lumpnum, int w, int h, int xoffset, int yoffset, bool transparent) - : FImageSource(lumpnum) -{ - Width = w; - Height = h; - LeftOffset = xoffset; - TopOffset = yoffset; - if (!transparent) - bMasked = bTranslucent = false; -} - -PalettedPixels FJPEGXLTexture::CreatePalettedPixels(int conversion) -{ - FBitmap bitmap; - bitmap.Create(Width, Height); - CopyPixels(&bitmap, conversion); - const uint8_t *data = bitmap.GetPixels(); - - uint8_t *dest_p; - int dest_adv = Height; - int dest_rew = Width * Height - 1; - - PalettedPixels Pixels(Width * Height); - dest_p = Pixels.Data(); - - bool doalpha = conversion == luminance; - // Convert the source image from row-major to column-major format and remap it - for (int y = Height; y != 0; --y) - { - for (int x = Width; x != 0; --x) - { - int b = *data++; - int g = *data++; - int r = *data++; - int a = *data++; - if (a < 128) - *dest_p = 0; - else - *dest_p = ImageHelpers::RGBToPalette(doalpha, r, g, b); - dest_p += dest_adv; - } - dest_p -= dest_rew; - } - return Pixels; -} - -int FJPEGXLTexture::CopyPixels(FBitmap *bmp, int conversion) -{ - JxlBasicInfo info; - int width = 0, height = 0; - uint8_t* pixels = nullptr; - JxlPixelFormat format = {4, JXL_TYPE_UINT8, JXL_NATIVE_ENDIAN, 0}; - auto jxlDecoder = JxlDecoderMake(nullptr); - if (!jxlDecoder) - { - return 0; - } - - auto jxlDecoderPtr = jxlDecoder.get(); - if (JxlDecoderSubscribeEvents(jxlDecoderPtr, JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE) != JXL_DEC_SUCCESS) - { - return 0; - } - - auto lump = fileSystem.OpenFileReader(SourceLump); - auto array = lump.Read(); - JxlDecoderSetInput(jxlDecoderPtr, array.data(), array.size()); - JxlDecoderCloseInput(jxlDecoderPtr); - - for (;;) - { - JxlDecoderStatus status = JxlDecoderProcessInput(jxlDecoderPtr); - - switch (status) - { - case JXL_DEC_ERROR: - return 0; - - case JXL_DEC_BASIC_INFO: - { - if (JxlDecoderGetBasicInfo(jxlDecoderPtr, &info) != JXL_DEC_SUCCESS) - return 0; - - width = info.xsize; - height = info.ysize; - if (width != Width && height != Height) - return 0; - break; - } - - case JXL_DEC_NEED_IMAGE_OUT_BUFFER: - { - size_t bufferSize = 0; - if (JxlDecoderImageOutBufferSize(jxlDecoderPtr, &format, &bufferSize) != JXL_DEC_SUCCESS) - return 0; - - if (bufferSize != (Width * Height * 4)) - return 0; - - pixels = new uint8_t[Width * Height * 4]; - - if (JxlDecoderSetImageOutBuffer(jxlDecoderPtr, &format, pixels, bufferSize) != JXL_DEC_SUCCESS) - return 0; - break; - } - - case JXL_DEC_FULL_IMAGE: - { - break; - } - - case JXL_DEC_SUCCESS: - { - bmp->CopyPixelDataRGB(0, 0, pixels, Width, Height, 4, Width * 4, 0, CF_RGBA); - - return bMasked ? -1 : 0; - } - } - } -} diff --git a/src/common/textures/image.cpp b/src/common/textures/image.cpp index bd6b9d285..dcd1f28d3 100644 --- a/src/common/textures/image.cpp +++ b/src/common/textures/image.cpp @@ -324,9 +324,6 @@ FImageSource *TGAImage_TryCreate(FileReader &, int lumpnum); FImageSource *StbImage_TryCreate(FileReader &, int lumpnum); FImageSource *QOIImage_TryCreate(FileReader &, int lumpnum); FImageSource *WebPImage_TryCreate(FileReader &, int lumpnum); -#ifdef HAVE_JPEGXL -FImageSource *JPEGXLImage_TryCreate(FileReader &, int lumpnum); -#endif FImageSource *AnmImage_TryCreate(FileReader &, int lumpnum); FImageSource *RawPageImage_TryCreate(FileReader &, int lumpnum); FImageSource *FlatImage_TryCreate(FileReader &, int lumpnum); @@ -349,9 +346,6 @@ FImageSource * FImageSource::GetImage(int lumpnum, bool isflat) { StbImage_TryCreate, false }, { QOIImage_TryCreate, false }, { WebPImage_TryCreate, false }, -#ifdef HAVE_JPEGXL - { JPEGXLImage_TryCreate, false }, -#endif { TGAImage_TryCreate, false }, { AnmImage_TryCreate, false }, { StartupPageImage_TryCreate, false }, diff --git a/vcpkg.json b/vcpkg.json index 998fceab7..d89c12d12 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -24,17 +24,6 @@ "platform": "!windows | (windows & static & staticcrt)" } ] - }, - "vcpkg-libjxl": - { - "description": "Use libjxl provided by vcpkg.", - "dependencies": [ - { - "name": "libjxl", - "default-features": false, - "platform": "!windows | (windows & static & staticcrt)" - } - ] } }, "dependencies": [ From 7c90ea6b84798a6aa361e960a645685d047495cb Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 22 Aug 2023 11:33:06 +0200 Subject: [PATCH 056/223] - Convert the entire image backend infrastructure to be animation-friendly --- src/common/fonts/hexfont.cpp | 16 +++---- src/common/models/models_voxel.cpp | 8 ++-- src/common/textures/formats/anmtexture.cpp | 10 ++--- .../textures/formats/automaptexture.cpp | 4 +- .../textures/formats/brightmaptexture.cpp | 4 +- src/common/textures/formats/buildtexture.cpp | 4 +- src/common/textures/formats/ddstexture.cpp | 8 ++-- src/common/textures/formats/emptytexture.cpp | 4 +- src/common/textures/formats/flattexture.cpp | 4 +- src/common/textures/formats/fontchars.cpp | 4 +- src/common/textures/formats/fontchars.h | 4 +- src/common/textures/formats/imgztexture.cpp | 8 ++-- src/common/textures/formats/jpegtexture.cpp | 8 ++-- .../textures/formats/multipatchtexture.cpp | 4 +- .../textures/formats/multipatchtexture.h | 4 +- src/common/textures/formats/patchtexture.cpp | 8 ++-- src/common/textures/formats/pcxtexture.cpp | 8 ++-- src/common/textures/formats/pngtexture.cpp | 8 ++-- src/common/textures/formats/qoitexture.cpp | 8 ++-- .../textures/formats/rawpagetexture.cpp | 8 ++-- src/common/textures/formats/shadertexture.cpp | 4 +- .../textures/formats/startscreentexture.cpp | 2 +- .../textures/formats/startuptexture.cpp | 24 +++++------ src/common/textures/formats/stbtexture.cpp | 8 ++-- src/common/textures/formats/tgatexture.cpp | 8 ++-- src/common/textures/formats/webptexture.cpp | 10 ++--- src/common/textures/image.cpp | 42 +++++++++++-------- src/common/textures/image.h | 25 +++++++---- src/common/textures/imagetexture.cpp | 11 ++--- src/common/textures/textures.h | 3 +- src/rendering/swrenderer/r_swscene.cpp | 2 +- 31 files changed, 145 insertions(+), 128 deletions(-) diff --git a/src/common/fonts/hexfont.cpp b/src/common/fonts/hexfont.cpp index 52d723fa6..3fb02004b 100644 --- a/src/common/fonts/hexfont.cpp +++ b/src/common/fonts/hexfont.cpp @@ -109,8 +109,8 @@ class FHexFontChar : public FImageSource public: FHexFontChar(uint8_t *sourcedata, int swidth, int width, int height); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap* bmp, int conversion); + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0); protected: int SourceWidth; @@ -144,7 +144,7 @@ FHexFontChar::FHexFontChar (uint8_t *sourcedata, int swidth, int width, int heig // //========================================================================== -PalettedPixels FHexFontChar::CreatePalettedPixels(int) +PalettedPixels FHexFontChar::CreatePalettedPixels(int, int) { int destSize = Width * Height; PalettedPixels Pixels(destSize); @@ -175,7 +175,7 @@ PalettedPixels FHexFontChar::CreatePalettedPixels(int) return Pixels; } -int FHexFontChar::CopyPixels(FBitmap* bmp, int conversion) +int FHexFontChar::CopyPixels(FBitmap* bmp, int conversion, int frame) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. PalEntry* palette = hexdata.ConsolePal; @@ -190,8 +190,8 @@ class FHexFontChar2 : public FHexFontChar public: FHexFontChar2(uint8_t *sourcedata, int swidth, int width, int height); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap* bmp, int conversion); + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0); }; @@ -216,7 +216,7 @@ FHexFontChar2::FHexFontChar2(uint8_t *sourcedata, int swidth, int width, int hei // //========================================================================== -PalettedPixels FHexFontChar2::CreatePalettedPixels(int) +PalettedPixels FHexFontChar2::CreatePalettedPixels(int, int) { int destSize = Width * Height; PalettedPixels Pixels(destSize); @@ -255,7 +255,7 @@ PalettedPixels FHexFontChar2::CreatePalettedPixels(int) return Pixels; } -int FHexFontChar2::CopyPixels(FBitmap* bmp, int conversion) +int FHexFontChar2::CopyPixels(FBitmap* bmp, int conversion, int frame) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. PalEntry* palette = hexdata.SmallPal; diff --git a/src/common/models/models_voxel.cpp b/src/common/models/models_voxel.cpp index f723d1fe4..5fb749b5e 100644 --- a/src/common/models/models_voxel.cpp +++ b/src/common/models/models_voxel.cpp @@ -57,8 +57,8 @@ class FVoxelTexture : public FImageSource public: FVoxelTexture(FVoxel *voxel); - int CopyPixels(FBitmap *bmp, int conversion) override; - PalettedPixels CreatePalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; protected: FVoxel *SourceVox; @@ -84,7 +84,7 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox) // //=========================================================================== -PalettedPixels FVoxelTexture::CreatePalettedPixels(int conversion) +PalettedPixels FVoxelTexture::CreatePalettedPixels(int conversion, int frame) { // GetPixels gets called when a translated palette is used so we still need to implement it here. PalettedPixels Pixels(256); @@ -123,7 +123,7 @@ PalettedPixels FVoxelTexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FVoxelTexture::CopyPixels(FBitmap *bmp, int conversion) +int FVoxelTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { PalEntry pe[256]; uint8_t bitmap[256]; diff --git a/src/common/textures/formats/anmtexture.cpp b/src/common/textures/formats/anmtexture.cpp index 9fc3290d6..ad02db728 100644 --- a/src/common/textures/formats/anmtexture.cpp +++ b/src/common/textures/formats/anmtexture.cpp @@ -51,8 +51,8 @@ class FAnmTexture : public FImageSource public: FAnmTexture (int lumpnum, int w, int h); void ReadFrame(uint8_t *buffer, uint8_t *palette); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; @@ -103,7 +103,7 @@ FAnmTexture::FAnmTexture (int lumpnum, int w, int h) void FAnmTexture::ReadFrame(uint8_t *pixels, uint8_t *palette) { - auto lump = fileSystem.ReadFile (SourceLump); + auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); anim_t anim; @@ -127,7 +127,7 @@ void FAnmTexture::ReadFrame(uint8_t *pixels, uint8_t *palette) // //========================================================================== -PalettedPixels FAnmTexture::CreatePalettedPixels(int conversion) +PalettedPixels FAnmTexture::CreatePalettedPixels(int conversion, int frame) { PalettedPixels pixels(Width*Height); uint8_t buffer[64000]; @@ -149,7 +149,7 @@ PalettedPixels FAnmTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FAnmTexture::CopyPixels(FBitmap *bmp, int conversion) +int FAnmTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { uint8_t buffer[64000]; uint8_t palette[768]; diff --git a/src/common/textures/formats/automaptexture.cpp b/src/common/textures/formats/automaptexture.cpp index 5aade7730..a3b16c720 100644 --- a/src/common/textures/formats/automaptexture.cpp +++ b/src/common/textures/formats/automaptexture.cpp @@ -50,7 +50,7 @@ class FAutomapTexture : public FImageSource { public: FAutomapTexture(int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; @@ -89,7 +89,7 @@ FAutomapTexture::FAutomapTexture (int lumpnum) // //========================================================================== -PalettedPixels FAutomapTexture::CreatePalettedPixels(int conversion) +PalettedPixels FAutomapTexture::CreatePalettedPixels(int conversion, int frame) { int x, y; auto data = fileSystem.ReadFile (SourceLump); diff --git a/src/common/textures/formats/brightmaptexture.cpp b/src/common/textures/formats/brightmaptexture.cpp index f7e36d628..43499f17e 100644 --- a/src/common/textures/formats/brightmaptexture.cpp +++ b/src/common/textures/formats/brightmaptexture.cpp @@ -43,7 +43,7 @@ class FBrightmapTexture : public FImageSource public: FBrightmapTexture (FImageSource *source); - int CopyPixels(FBitmap *bmp, int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; protected: FImageSource *SourcePic; @@ -65,7 +65,7 @@ FBrightmapTexture::FBrightmapTexture (FImageSource *source) bMasked = false; } -int FBrightmapTexture::CopyPixels(FBitmap *bmp, int conversion) +int FBrightmapTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { SourcePic->CopyTranslatedPixels(bmp, GPalette.GlobalBrightmap.Palette); return 0; diff --git a/src/common/textures/formats/buildtexture.cpp b/src/common/textures/formats/buildtexture.cpp index f8d8a7b6a..fec41227b 100644 --- a/src/common/textures/formats/buildtexture.cpp +++ b/src/common/textures/formats/buildtexture.cpp @@ -55,7 +55,7 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8 TopOffset = top; } -PalettedPixels FBuildTexture::CreatePalettedPixels(int conversion) +PalettedPixels FBuildTexture::CreatePalettedPixels(int conversion, int frame) { PalettedPixels Pixels(Width * Height); FRemapTable *Remap = Translation; @@ -67,7 +67,7 @@ PalettedPixels FBuildTexture::CreatePalettedPixels(int conversion) return Pixels; } -int FBuildTexture::CopyPixels(FBitmap *bmp, int conversion) +int FBuildTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { PalEntry *Remap = Translation->Palette; bmp->CopyPixelData(0, 0, RawPixels, Width, Height, Height, 1, 0, Remap); diff --git a/src/common/textures/formats/ddstexture.cpp b/src/common/textures/formats/ddstexture.cpp index 5ccf309b9..3949c3d88 100644 --- a/src/common/textures/formats/ddstexture.cpp +++ b/src/common/textures/formats/ddstexture.cpp @@ -164,7 +164,7 @@ class FDDSTexture : public FImageSource public: FDDSTexture (FileReader &lump, int lumpnum, void *surfdesc); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; protected: uint32_t Format; @@ -183,7 +183,7 @@ protected: void DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); void DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); - int CopyPixels(FBitmap *bmp, int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; friend class FTexture; }; @@ -372,7 +372,7 @@ void FDDSTexture::CalcBitShift (uint32_t mask, uint8_t *lshiftp, uint8_t *rshift // //========================================================================== -PalettedPixels FDDSTexture::CreatePalettedPixels(int conversion) +PalettedPixels FDDSTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.OpenFileReader (SourceLump); @@ -781,7 +781,7 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t // //=========================================================================== -int FDDSTexture::CopyPixels(FBitmap *bmp, int conversion) +int FDDSTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { auto lump = fileSystem.OpenFileReader (SourceLump); diff --git a/src/common/textures/formats/emptytexture.cpp b/src/common/textures/formats/emptytexture.cpp index 74e8fe1cb..cd53b996a 100644 --- a/src/common/textures/formats/emptytexture.cpp +++ b/src/common/textures/formats/emptytexture.cpp @@ -49,7 +49,7 @@ class FEmptyTexture : public FImageSource { public: FEmptyTexture (int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; //========================================================================== @@ -94,7 +94,7 @@ FEmptyTexture::FEmptyTexture (int lumpnum) // //========================================================================== -PalettedPixels FEmptyTexture::CreatePalettedPixels(int conversion) +PalettedPixels FEmptyTexture::CreatePalettedPixels(int conversion, int frame) { static uint8_t p; PalettedPixels Pixel(&p, 1); diff --git a/src/common/textures/formats/flattexture.cpp b/src/common/textures/formats/flattexture.cpp index a01016a36..5f26df931 100644 --- a/src/common/textures/formats/flattexture.cpp +++ b/src/common/textures/formats/flattexture.cpp @@ -48,7 +48,7 @@ class FFlatTexture : public FImageSource { public: FFlatTexture (int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; @@ -102,7 +102,7 @@ FFlatTexture::FFlatTexture (int lumpnum) // //========================================================================== -PalettedPixels FFlatTexture::CreatePalettedPixels(int conversion) +PalettedPixels FFlatTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.OpenFileReader (SourceLump); PalettedPixels Pixels(Width*Height); diff --git a/src/common/textures/formats/fontchars.cpp b/src/common/textures/formats/fontchars.cpp index 09fbd718e..2d09cf58d 100644 --- a/src/common/textures/formats/fontchars.cpp +++ b/src/common/textures/formats/fontchars.cpp @@ -66,7 +66,7 @@ FFontChar2::FFontChar2(int sourcelump, int sourcepos, int width, int height, int // //========================================================================== -PalettedPixels FFontChar2::CreatePalettedPixels(int) +PalettedPixels FFontChar2::CreatePalettedPixels(int, int) { auto lump = fileSystem.OpenFileReader(SourceLump); int destSize = Width * Height; @@ -170,7 +170,7 @@ PalettedPixels FFontChar2::CreatePalettedPixels(int) return Pixels; } -int FFontChar2::CopyPixels(FBitmap* bmp, int conversion) +int FFontChar2::CopyPixels(FBitmap* bmp, int conversion, int frame) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. auto ppix = CreatePalettedPixels(conversion); diff --git a/src/common/textures/formats/fontchars.h b/src/common/textures/formats/fontchars.h index 45c678566..089043969 100644 --- a/src/common/textures/formats/fontchars.h +++ b/src/common/textures/formats/fontchars.h @@ -6,8 +6,8 @@ class FFontChar2 : public FImageSource public: FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap* bmp, int conversion); + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0); void SetSourceRemap(const PalEntry* sourceremap) { diff --git a/src/common/textures/formats/imgztexture.cpp b/src/common/textures/formats/imgztexture.cpp index e85d3bac9..b5deaccac 100644 --- a/src/common/textures/formats/imgztexture.cpp +++ b/src/common/textures/formats/imgztexture.cpp @@ -66,8 +66,8 @@ class FIMGZTexture : public FImageSource public: FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool isalpha); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; @@ -118,7 +118,7 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1 // //========================================================================== -PalettedPixels FIMGZTexture::CreatePalettedPixels(int conversion) +PalettedPixels FIMGZTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.ReadFile (SourceLump); auto imgz = (const ImageHeader *)lump.GetMem(); @@ -198,7 +198,7 @@ PalettedPixels FIMGZTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FIMGZTexture::CopyPixels(FBitmap *bmp, int conversion) +int FIMGZTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { if (!isalpha) return FImageSource::CopyPixels(bmp, conversion); else return CopyTranslatedPixels(bmp, GPalette.GrayscaleMap.Palette); diff --git a/src/common/textures/formats/jpegtexture.cpp b/src/common/textures/formats/jpegtexture.cpp index 834dc44e3..964985421 100644 --- a/src/common/textures/formats/jpegtexture.cpp +++ b/src/common/textures/formats/jpegtexture.cpp @@ -185,8 +185,8 @@ class FJPEGTexture : public FImageSource public: FJPEGTexture (int lumpnum, int width, int height); - int CopyPixels(FBitmap *bmp, int conversion) override; - PalettedPixels CreatePalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; //========================================================================== @@ -260,7 +260,7 @@ FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) // //========================================================================== -PalettedPixels FJPEGTexture::CreatePalettedPixels(int conversion) +PalettedPixels FJPEGTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.OpenFileReader (SourceLump); JSAMPLE *buff = NULL; @@ -401,7 +401,7 @@ PalettedPixels FJPEGTexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion) +int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { PalEntry pe[256]; diff --git a/src/common/textures/formats/multipatchtexture.cpp b/src/common/textures/formats/multipatchtexture.cpp index 17c0a7b28..3a8e8ae7b 100644 --- a/src/common/textures/formats/multipatchtexture.cpp +++ b/src/common/textures/formats/multipatchtexture.cpp @@ -201,7 +201,7 @@ void FMultiPatchTexture::CopyToBlock(uint8_t *dest, int dwidth, int dheight, FIm // //========================================================================== -PalettedPixels FMultiPatchTexture::CreatePalettedPixels(int conversion) +PalettedPixels FMultiPatchTexture::CreatePalettedPixels(int conversion, int frame) { int numpix = Width * Height; uint8_t blendwork[256]; @@ -278,7 +278,7 @@ PalettedPixels FMultiPatchTexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FMultiPatchTexture::CopyPixels(FBitmap *bmp, int conversion) +int FMultiPatchTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { int retv = -1; diff --git a/src/common/textures/formats/multipatchtexture.h b/src/common/textures/formats/multipatchtexture.h index 4b92aad4f..ce1f5d932 100644 --- a/src/common/textures/formats/multipatchtexture.h +++ b/src/common/textures/formats/multipatchtexture.h @@ -74,8 +74,8 @@ protected: TexPart *Parts; // The getters must optionally redirect if it's a simple one-patch texture. - int CopyPixels(FBitmap *bmp, int conversion) override; - PalettedPixels CreatePalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; void CopyToBlock(uint8_t *dest, int dwidth, int dheight, FImageSource *source, int xpos, int ypos, int rotate, const uint8_t *translation, int style); void CollectForPrecache(PrecacheInfo &info, bool requiretruecolor) override; diff --git a/src/common/textures/formats/patchtexture.cpp b/src/common/textures/formats/patchtexture.cpp index 80179a54d..a6f70222f 100644 --- a/src/common/textures/formats/patchtexture.cpp +++ b/src/common/textures/formats/patchtexture.cpp @@ -62,8 +62,8 @@ class FPatchTexture : public FImageSource bool isalpha = false; public: FPatchTexture (int lumpnum, int w, int h, int lo, int to, bool isalphatex); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; bool SupportRemap0() override { return !badflag; } void DetectBadPatches(); }; @@ -167,7 +167,7 @@ FPatchTexture::FPatchTexture (int lumpnum, int w, int h, int lo, int to, bool is // //========================================================================== -PalettedPixels FPatchTexture::CreatePalettedPixels(int conversion) +PalettedPixels FPatchTexture::CreatePalettedPixels(int conversion, int frame) { uint8_t *remap, remaptable[256]; int numspans; @@ -264,7 +264,7 @@ PalettedPixels FPatchTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FPatchTexture::CopyPixels(FBitmap *bmp, int conversion) +int FPatchTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { if (!isalpha) return FImageSource::CopyPixels(bmp, conversion); else return CopyTranslatedPixels(bmp, GPalette.GrayscaleMap.Palette); diff --git a/src/common/textures/formats/pcxtexture.cpp b/src/common/textures/formats/pcxtexture.cpp index bc014659f..494adeb1f 100644 --- a/src/common/textures/formats/pcxtexture.cpp +++ b/src/common/textures/formats/pcxtexture.cpp @@ -84,7 +84,7 @@ class FPCXTexture : public FImageSource public: FPCXTexture (int lumpnum, PCXHeader &); - int CopyPixels(FBitmap *bmp, int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; protected: void ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr); @@ -92,7 +92,7 @@ protected: void ReadPCX8bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr); void ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr, int planes); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; @@ -345,7 +345,7 @@ void FPCXTexture::ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr // //========================================================================== -PalettedPixels FPCXTexture::CreatePalettedPixels(int conversion) +PalettedPixels FPCXTexture::CreatePalettedPixels(int conversion, int frame) { uint8_t PaletteMap[256]; PCXHeader header; @@ -433,7 +433,7 @@ PalettedPixels FPCXTexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion) +int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { PalEntry pe[256]; PCXHeader header; diff --git a/src/common/textures/formats/pngtexture.cpp b/src/common/textures/formats/pngtexture.cpp index cdf14c15c..01f210a1c 100644 --- a/src/common/textures/formats/pngtexture.cpp +++ b/src/common/textures/formats/pngtexture.cpp @@ -56,8 +56,8 @@ class FPNGTexture : public FImageSource public: FPNGTexture (FileReader &lump, int lumpnum, int width, int height, uint8_t bitdepth, uint8_t colortype, uint8_t interlace); - int CopyPixels(FBitmap *bmp, int conversion) override; - PalettedPixels CreatePalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; protected: void ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap); @@ -412,7 +412,7 @@ void FPNGTexture::ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap) // //========================================================================== -PalettedPixels FPNGTexture::CreatePalettedPixels(int conversion) +PalettedPixels FPNGTexture::CreatePalettedPixels(int conversion, int frame) { FileReader *lump; FileReader lfr; @@ -553,7 +553,7 @@ PalettedPixels FPNGTexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FPNGTexture::CopyPixels(FBitmap *bmp, int conversion) +int FPNGTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { // Parse pre-IDAT chunks. I skip the CRCs. Is that bad? PalEntry pe[256]; diff --git a/src/common/textures/formats/qoitexture.cpp b/src/common/textures/formats/qoitexture.cpp index c84ac38ce..663472f20 100644 --- a/src/common/textures/formats/qoitexture.cpp +++ b/src/common/textures/formats/qoitexture.cpp @@ -51,8 +51,8 @@ class FQOITexture : public FImageSource { public: FQOITexture(int lumpnum, QOIHeader& header); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; FImageSource *QOIImage_TryCreate(FileReader &file, int lumpnum) @@ -89,7 +89,7 @@ FQOITexture::FQOITexture(int lumpnum, QOIHeader& header) if (header.channels == 3) bMasked = bTranslucent = false; } -PalettedPixels FQOITexture::CreatePalettedPixels(int conversion) +PalettedPixels FQOITexture::CreatePalettedPixels(int conversion, int frame) { FBitmap bitmap; bitmap.Create(Width, Height); @@ -124,7 +124,7 @@ PalettedPixels FQOITexture::CreatePalettedPixels(int conversion) return Pixels; } -int FQOITexture::CopyPixels(FBitmap *bmp, int conversion) +int FQOITexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { enum { diff --git a/src/common/textures/formats/rawpagetexture.cpp b/src/common/textures/formats/rawpagetexture.cpp index 4caa6bb9e..b185f5ffc 100644 --- a/src/common/textures/formats/rawpagetexture.cpp +++ b/src/common/textures/formats/rawpagetexture.cpp @@ -52,8 +52,8 @@ class FRawPageTexture : public FImageSource int mPaletteLump = -1; public: FRawPageTexture (int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; //========================================================================== @@ -170,7 +170,7 @@ FRawPageTexture::FRawPageTexture (int lumpnum) // //========================================================================== -PalettedPixels FRawPageTexture::CreatePalettedPixels(int conversion) +PalettedPixels FRawPageTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); @@ -199,7 +199,7 @@ PalettedPixels FRawPageTexture::CreatePalettedPixels(int conversion) return Pixels; } -int FRawPageTexture::CopyPixels(FBitmap *bmp, int conversion) +int FRawPageTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { if (mPaletteLump < 0) return FImageSource::CopyPixels(bmp, conversion); else diff --git a/src/common/textures/formats/shadertexture.cpp b/src/common/textures/formats/shadertexture.cpp index ce5952fc2..0b69e8acb 100644 --- a/src/common/textures/formats/shadertexture.cpp +++ b/src/common/textures/formats/shadertexture.cpp @@ -98,7 +98,7 @@ public: } } - PalettedPixels CreatePalettedPixels(int conversion) override + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override { PalettedPixels Pix(512); if (conversion == luminance) @@ -118,7 +118,7 @@ public: return Pix; } - int CopyPixels(FBitmap *bmp, int conversion) override + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override { bmp->CopyPixelData(0, 0, Pixels, Width, Height, Height, 1, 0, GPalette.GrayRamp.Palette); return 0; diff --git a/src/common/textures/formats/startscreentexture.cpp b/src/common/textures/formats/startscreentexture.cpp index 85710d42f..f19a654f9 100644 --- a/src/common/textures/formats/startscreentexture.cpp +++ b/src/common/textures/formats/startscreentexture.cpp @@ -60,7 +60,7 @@ public: Height = srcdata.GetHeight(); bUseGamePalette = false; } - int CopyPixels(FBitmap* bmp, int conversion) + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0) { bmp->Blit(0, 0, info); return 0; diff --git a/src/common/textures/formats/startuptexture.cpp b/src/common/textures/formats/startuptexture.cpp index cb1c5b719..510061f7c 100644 --- a/src/common/textures/formats/startuptexture.cpp +++ b/src/common/textures/formats/startuptexture.cpp @@ -77,30 +77,30 @@ class FStartupTexture : public FImageSource { public: FStartupTexture (int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame) override; }; class FNotchTexture : public FImageSource { public: FNotchTexture (int lumpnum, int width, int height); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame) override; }; class FStrifeStartupTexture : public FImageSource { public: FStrifeStartupTexture (int lumpnum, int w, int h); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; class FStrifeStartupBackground : public FImageSource { public: FStrifeStartupBackground (int lumpnum); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; //========================================================================== @@ -231,7 +231,7 @@ void PlanarToChunky(T* dest, const uint8_t* src, const T* remap, int width, int // //========================================================================== -PalettedPixels FStartupTexture::CreatePalettedPixels(int conversion) +PalettedPixels FStartupTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); @@ -251,7 +251,7 @@ PalettedPixels FStartupTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FStartupTexture::CopyPixels(FBitmap *bmp, int conversion) +int FStartupTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); @@ -279,7 +279,7 @@ FNotchTexture::FNotchTexture (int lumpnum, int width, int height) // //========================================================================== -PalettedPixels FNotchTexture::CreatePalettedPixels(int conversion) +PalettedPixels FNotchTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); @@ -302,7 +302,7 @@ PalettedPixels FNotchTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FNotchTexture::CopyPixels(FBitmap *bmp, int conversion) +int FNotchTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); @@ -336,7 +336,7 @@ FStrifeStartupTexture::FStrifeStartupTexture (int lumpnum, int w, int h) // //========================================================================== -PalettedPixels FStrifeStartupTexture::CreatePalettedPixels(int conversion) +PalettedPixels FStrifeStartupTexture::CreatePalettedPixels(int conversion, int frame) { auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); @@ -366,7 +366,7 @@ FStrifeStartupBackground::FStrifeStartupBackground (int lumpnum) // //========================================================================== -PalettedPixels FStrifeStartupBackground::CreatePalettedPixels(int conversion) +PalettedPixels FStrifeStartupBackground::CreatePalettedPixels(int conversion, int frame) { TArray source(64000, true); memset(source.Data(), 0xF0, 64000); diff --git a/src/common/textures/formats/stbtexture.cpp b/src/common/textures/formats/stbtexture.cpp index e8d9fe2a0..2507cb5b2 100644 --- a/src/common/textures/formats/stbtexture.cpp +++ b/src/common/textures/formats/stbtexture.cpp @@ -67,8 +67,8 @@ class FStbTexture : public FImageSource public: FStbTexture (int lumpnum, int w, int h); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; @@ -117,7 +117,7 @@ FStbTexture::FStbTexture (int lumpnum, int w, int h) // //========================================================================== -PalettedPixels FStbTexture::CreatePalettedPixels(int conversion) +PalettedPixels FStbTexture::CreatePalettedPixels(int conversion, int frame) { FBitmap bitmap; bitmap.Create(Width, Height); @@ -156,7 +156,7 @@ PalettedPixels FStbTexture::CreatePalettedPixels(int conversion) // //========================================================================== -int FStbTexture::CopyPixels(FBitmap *bmp, int conversion) +int FStbTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { auto lump = fileSystem.OpenFileReader (SourceLump); int x, y, chan; diff --git a/src/common/textures/formats/tgatexture.cpp b/src/common/textures/formats/tgatexture.cpp index daa70cfa4..2318e4199 100644 --- a/src/common/textures/formats/tgatexture.cpp +++ b/src/common/textures/formats/tgatexture.cpp @@ -80,11 +80,11 @@ class FTGATexture : public FImageSource public: FTGATexture (int lumpnum, TGAHeader *); - int CopyPixels(FBitmap *bmp, int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; protected: void ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel); - PalettedPixels CreatePalettedPixels(int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; }; //========================================================================== @@ -178,7 +178,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe // //========================================================================== -PalettedPixels FTGATexture::CreatePalettedPixels(int conversion) +PalettedPixels FTGATexture::CreatePalettedPixels(int conversion, int frame) { uint8_t PaletteMap[256]; auto lump = fileSystem.OpenFileReader (SourceLump); @@ -385,7 +385,7 @@ PalettedPixels FTGATexture::CreatePalettedPixels(int conversion) // //=========================================================================== -int FTGATexture::CopyPixels(FBitmap *bmp, int conversion) +int FTGATexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { PalEntry pe[256]; auto lump = fileSystem.OpenFileReader (SourceLump); diff --git a/src/common/textures/formats/webptexture.cpp b/src/common/textures/formats/webptexture.cpp index 622c8e701..696bef71a 100644 --- a/src/common/textures/formats/webptexture.cpp +++ b/src/common/textures/formats/webptexture.cpp @@ -47,8 +47,8 @@ class FWebPTexture : public FImageSource public: FWebPTexture(int lumpnum, int w, int h, int xoff, int yoff); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap *bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; }; @@ -94,10 +94,10 @@ FWebPTexture::FWebPTexture(int lumpnum, int w, int h, int xoff, int yoff) TopOffset = yoff; } -PalettedPixels FWebPTexture::CreatePalettedPixels(int conversion) +PalettedPixels FWebPTexture::CreatePalettedPixels(int conversion, int frame) { FBitmap bitmap; - bitmap.Create(Width, Height); + bitmap.Create(Width, Height, frame); CopyPixels(&bitmap, conversion); const uint8_t *data = bitmap.GetPixels(); @@ -127,7 +127,7 @@ PalettedPixels FWebPTexture::CreatePalettedPixels(int conversion) return Pixels; } -int FWebPTexture::CopyPixels(FBitmap *bmp, int conversion) +int FWebPTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { WebPDecoderConfig config; auto bytes = fileSystem.ReadFile(SourceLump); diff --git a/src/common/textures/image.cpp b/src/common/textures/image.cpp index dcd1f28d3..8cee04102 100644 --- a/src/common/textures/image.cpp +++ b/src/common/textures/image.cpp @@ -51,6 +51,7 @@ struct PrecacheDataPaletted PalettedPixels Pixels; int RefCount; int ImageID; + int Frame; }; struct PrecacheDataRgba @@ -59,6 +60,7 @@ struct PrecacheDataRgba int TransInfo; int RefCount; int ImageID; + int Frame; }; // TMap doesn't handle this kind of data well. std::map neither. The linear search is still faster, even for a few 100 entries because it doesn't have to access the heap as often.. @@ -71,21 +73,21 @@ TArray precacheDataRgba; // //=========================================================================== -PalettedPixels FImageSource::CreatePalettedPixels(int conversion) +PalettedPixels FImageSource::CreatePalettedPixels(int conversion, int frame) { PalettedPixels Pixels(Width * Height); memset(Pixels.Data(), 0, Width * Height); return Pixels; } -PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion) +PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion, int frame) { PalettedPixels ret; auto imageID = ImageID; // Do we have this image in the cache? - unsigned index = conversion != normal? UINT_MAX : precacheDataPaletted.FindEx([=](PrecacheDataPaletted &entry) { return entry.ImageID == imageID; }); + unsigned index = conversion != normal? UINT_MAX : precacheDataPaletted.FindEx([=](PrecacheDataPaletted &entry) { return entry.ImageID == imageID && entry.Frame == frame; }); if (index < precacheDataPaletted.Size()) { auto cache = &precacheDataPaletted[index]; @@ -115,7 +117,7 @@ PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion) { // This is either the only copy needed or some access outside the caching block. In these cases create a new one and directly return it. //Printf("returning fresh copy of %s\n", name.GetChars()); - return CreatePalettedPixels(conversion); + return CreatePalettedPixels(conversion, frame); } else { @@ -126,16 +128,16 @@ PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion) pdp->ImageID = imageID; pdp->RefCount = info->second - 1; info->second = 0; - pdp->Pixels = CreatePalettedPixels(normal); + pdp->Pixels = CreatePalettedPixels(normal, frame); ret.Pixels.Set(pdp->Pixels.Data(), pdp->Pixels.Size()); } } return ret; } -TArray FImageSource::GetPalettedPixels(int conversion) +TArray FImageSource::GetPalettedPixels(int conversion, int frame) { - auto pix = GetCachedPalettedPixels(conversion); + auto pix = GetCachedPalettedPixels(conversion, frame); if (pix.ownsPixels()) { // return the pixel store of the returned data directly if this was the last reference. @@ -165,19 +167,19 @@ TArray FImageSource::GetPalettedPixels(int conversion) // //=========================================================================== -int FImageSource::CopyPixels(FBitmap *bmp, int conversion) +int FImageSource::CopyPixels(FBitmap *bmp, int conversion, int frame) { if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. PalEntry *palette = GPalette.BaseColors; - auto ppix = CreatePalettedPixels(conversion); + auto ppix = CreatePalettedPixels(conversion, frame); bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr); return 0; } -int FImageSource::CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap) +int FImageSource::CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap, int frame) { - auto ppix = CreatePalettedPixels(normal); + auto ppix = CreatePalettedPixels(normal, frame); bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, remap, nullptr); return 0; } @@ -188,26 +190,31 @@ int FImageSource::CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap) // //========================================================================== -FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int *ptrans) +FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int *ptrans, int frame) { FBitmap ret; int trans = -1; auto imageID = ImageID; + if (NumOfFrames == 1 && frame == 1) + { + frame = 0; + } + if (remap != nullptr) { // Remapped images are never run through the cache because they would complicate matters too much for very little gain. // Translated images are normally sprites which normally just consist of a single image and use no composition. // Additionally, since translation requires the base palette, the really time consuming stuff will never be subjected to it. ret.Create(Width, Height); - trans = CopyTranslatedPixels(&ret, remap); + trans = CopyTranslatedPixels(&ret, remap, frame); } else { if (conversion == luminance) conversion = normal; // luminance has no meaning for true color. // Do we have this image in the cache? - unsigned index = conversion != normal? UINT_MAX : precacheDataRgba.FindEx([=](PrecacheDataRgba &entry) { return entry.ImageID == imageID; }); + unsigned index = conversion != normal? UINT_MAX : precacheDataRgba.FindEx([=](PrecacheDataRgba &entry) { return entry.ImageID == imageID && entry.Frame == frame; }); if (index < precacheDataRgba.Size()) { auto cache = &precacheDataRgba[index]; @@ -230,7 +237,7 @@ FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int // This should never happen if the function is implemented correctly //Printf("something bad happened for %s, refcount = %d\n", name.GetChars(), cache->RefCount); ret.Create(Width, Height); - trans = CopyPixels(&ret, normal); + trans = CopyPixels(&ret, normal, frame); } } else @@ -242,7 +249,7 @@ FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int // This is either the only copy needed or some access outside the caching block. In these cases create a new one and directly return it. //Printf("returning fresh copy of %s\n", name.GetChars()); ret.Create(Width, Height); - trans = CopyPixels(&ret, conversion); + trans = CopyPixels(&ret, conversion, frame); } else { @@ -251,10 +258,11 @@ FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int PrecacheDataRgba *pdr = &precacheDataRgba[precacheDataRgba.Reserve(1)]; pdr->ImageID = imageID; + pdr->Frame = frame; pdr->RefCount = info->first - 1; info->first = 0; pdr->Pixels.Create(Width, Height); - trans = pdr->TransInfo = CopyPixels(&pdr->Pixels, normal); + trans = pdr->TransInfo = CopyPixels(&pdr->Pixels, normal, frame); ret.Copy(pdr->Pixels, false); } } diff --git a/src/common/textures/image.h b/src/common/textures/image.h index 5be852549..f9e761a20 100644 --- a/src/common/textures/image.h +++ b/src/common/textures/image.h @@ -67,12 +67,13 @@ protected: int LeftOffset = 0, TopOffset = 0; // Offsets stored in the image. bool bUseGamePalette = false; // true if this is an image without its own color set. int ImageID = -1; + int NumOfFrames = 1; // Internal image creation functions. All external access should go through the cache interface, // so that all code can benefit from future improvements to that. - virtual PalettedPixels CreatePalettedPixels(int conversion); - int CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap); + virtual PalettedPixels CreatePalettedPixels(int conversion, int frame = 0); + int CopyTranslatedPixels(FBitmap *bmp, const PalEntry *remap, int frame = 0); public: @@ -101,19 +102,25 @@ public: // 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture. // Either returns a reference to the cache, or a newly created item. The return of this has to be considered transient. If you need to store the result, use GetPalettedPixels - PalettedPixels GetCachedPalettedPixels(int conversion); + PalettedPixels GetCachedPalettedPixels(int conversion, int frame = 0); // tries to get a buffer from the cache. If not available, create a new one. If further references are pending, create a copy. - TArray GetPalettedPixels(int conversion); + TArray GetPalettedPixels(int conversion, int frame = 0); - virtual int CopyPixels(FBitmap* bmp, int conversion); + virtual int CopyPixels(FBitmap* bmp, int conversion, int frame = 0); - FBitmap GetCachedBitmap(const PalEntry *remap, int conversion, int *trans = nullptr); + FBitmap GetCachedBitmap(const PalEntry *remap, int conversion, int *trans = nullptr, int frame = 0); static void ClearImages() { ImageArena.FreeAll(); ImageForLump.Clear(); NextID = 0; } static FImageSource * GetImage(int lumpnum, bool checkflat); + // Frame functions + // Gets number of frames. + int GetNumOfFrames() { return NumOfFrames; } + + // Gets duration of frame in miliseconds. + virtual int GetDurationOfFrame(int frame) { return 1000; } // Conversion option enum EType @@ -180,8 +187,8 @@ class FBuildTexture : public FImageSource { public: FBuildTexture(const FString& pathprefix, int tilenum, const uint8_t* pixels, FRemapTable* translation, int width, int height, int left, int top); - PalettedPixels CreatePalettedPixels(int conversion) override; - int CopyPixels(FBitmap* bmp, int conversion) override; + PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0) override; protected: const uint8_t* RawPixels; @@ -191,4 +198,4 @@ protected: class FTexture; -FTexture* CreateImageTexture(FImageSource* img) noexcept; +FTexture* CreateImageTexture(FImageSource* img, int frame = 0) noexcept; diff --git a/src/common/textures/imagetexture.cpp b/src/common/textures/imagetexture.cpp index d94ff8002..233cf4b09 100644 --- a/src/common/textures/imagetexture.cpp +++ b/src/common/textures/imagetexture.cpp @@ -47,10 +47,11 @@ // //========================================================================== -FImageTexture::FImageTexture(FImageSource *img) noexcept +FImageTexture::FImageTexture(FImageSource *img, int frame) noexcept : FTexture(img? img->LumpNum() : 0) { mImage = img; + TexFrame = frame; if (img != nullptr) { SetFromImage(); @@ -79,7 +80,7 @@ void FImageTexture::SetFromImage() FBitmap FImageTexture::GetBgraBitmap(const PalEntry *p, int *trans) { - return mImage->GetCachedBitmap(p, bNoRemap0? FImageSource::noremap0 : FImageSource::normal, trans); + return mImage->GetCachedBitmap(p, bNoRemap0? FImageSource::noremap0 : FImageSource::normal, trans, TexFrame); } //=========================================================================== @@ -90,7 +91,7 @@ FBitmap FImageTexture::GetBgraBitmap(const PalEntry *p, int *trans) TArray FImageTexture::Get8BitPixels(bool alpha) { - return mImage->GetPalettedPixels(alpha? FImageSource::luminance : bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal); + return mImage->GetPalettedPixels(alpha? FImageSource::luminance : bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal, TexFrame); } //=========================================================================== @@ -113,8 +114,8 @@ bool FImageTexture::DetermineTranslucency() } -FTexture* CreateImageTexture(FImageSource* img) noexcept +FTexture* CreateImageTexture(FImageSource* img, int frame) noexcept { - return new FImageTexture(img); + return new FImageTexture(img, frame); } diff --git a/src/common/textures/textures.h b/src/common/textures/textures.h index 0d88f3843..164aa79b8 100644 --- a/src/common/textures/textures.h +++ b/src/common/textures/textures.h @@ -379,10 +379,11 @@ class FImageTexture : public FTexture { FImageSource* mImage; bool bNoRemap0 = false; + int TexFrame = 0; protected: void SetFromImage(); public: - FImageTexture(FImageSource* image) noexcept; + FImageTexture(FImageSource* image, int frame = 0) noexcept; ~FImageTexture(); TArray Get8BitPixels(bool alphatex) override; diff --git a/src/rendering/swrenderer/r_swscene.cpp b/src/rendering/swrenderer/r_swscene.cpp index 491370dfc..0aad92453 100644 --- a/src/rendering/swrenderer/r_swscene.cpp +++ b/src/rendering/swrenderer/r_swscene.cpp @@ -48,7 +48,7 @@ public: Height = 1; } - int CopyPixels(FBitmap *bmp, int conversion) override + int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override { PalEntry *pe = (PalEntry*)bmp->GetPixels(); for (int i = 0; i < 256; i++) From c6e2e0add29b6d24949f3e954bacf8cc524fd361 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 23 Aug 2023 18:26:42 +0200 Subject: [PATCH 057/223] - fix compilation --- src/common/textures/formats/webptexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/textures/formats/webptexture.cpp b/src/common/textures/formats/webptexture.cpp index 696bef71a..4a3233c9e 100644 --- a/src/common/textures/formats/webptexture.cpp +++ b/src/common/textures/formats/webptexture.cpp @@ -97,7 +97,7 @@ FWebPTexture::FWebPTexture(int lumpnum, int w, int h, int xoff, int yoff) PalettedPixels FWebPTexture::CreatePalettedPixels(int conversion, int frame) { FBitmap bitmap; - bitmap.Create(Width, Height, frame); + bitmap.Create(Width, Height); CopyPixels(&bitmap, conversion); const uint8_t *data = bitmap.GetPixels(); From e0b3bdaadc49ef5af7cef141854740a5bbb8ca84 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 23 Aug 2023 22:09:58 +0200 Subject: [PATCH 058/223] - fixed directory loader. --- src/CMakeLists.txt | 12 ++++++------ src/common/filesystem/source/file_directory.cpp | 16 ++++++++-------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 35587dfa8..cc4fafb5a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1177,7 +1177,7 @@ else() set( NOT_COMPILED_SOURCE_FILES ${NOT_COMPILED_SOURCE_FILES} ${VM_JIT_SOURCES} ) endif() -set( ZDOOM_SOURCES +set( GAME_SOURCES ${HEADER_FILES} ${NOT_COMPILED_SOURCE_FILES} ${SYSTEM_SOURCES} @@ -1227,8 +1227,8 @@ set( ZDOOM_SOURCES ) -set( ZDOOM_NONPCH_SOURCES ${ZDOOM_SOURCES} ) -list( REMOVE_ITEM ZDOOM_NONPCH_SOURCES ${PCH_SOURCES} ) +set( GAME_NONPCH_SOURCES ${GAME_SOURCES} ) +list( REMOVE_ITEM GAME_NONPCH_SOURCES ${PCH_SOURCES} ) add_executable( zdoom WIN32 MACOSX_BUNDLE ${ZDOOM_SOURCES} ) @@ -1238,7 +1238,7 @@ set_source_files_properties( ${FASTMATH_SOURCES} PROPERTIES COMPILE_FLAGS ${ZD_F set_source_files_properties( xlat/parse_xlat.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c" ) set_source_files_properties( common/engine/sc_man.cpp PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/sc_man_scanner.h" ) set_source_files_properties( ${NOT_COMPILED_SOURCE_FILES} PROPERTIES HEADER_FILE_ONLY TRUE ) -set_source_files_properties( ${ZDOOM_NONPCH_SOURCES} common/textures/hires/hqresize.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE ) +set_source_files_properties( ${GAME_NONPCH_SOURCES} common/textures/hires/hqresize.cpp PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE ) if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") @@ -1418,9 +1418,9 @@ if( APPLE ) endif() if( WIN32 ) - set( INSTALL_PATH . CACHE STRING "Directory where the zdoom executable will be placed during install." ) + set( INSTALL_PATH . CACHE STRING "Directory where the executable will be placed during install." ) else() - set( INSTALL_PATH bin CACHE STRING "Directory where the zdoom executable will be placed during install." ) + set( INSTALL_PATH bin CACHE STRING "Directory where the executable will be placed during install." ) endif() install(TARGETS zdoom DESTINATION ${INSTALL_PATH} diff --git a/src/common/filesystem/source/file_directory.cpp b/src/common/filesystem/source/file_directory.cpp index 8208e6634..84679ffc9 100644 --- a/src/common/filesystem/source/file_directory.cpp +++ b/src/common/filesystem/source/file_directory.cpp @@ -59,7 +59,7 @@ struct FDirectoryLump : public FResourceLump FileReader NewReader() override; int FillCache() override; - std::string mFullPath; + const char* mFullPath; }; @@ -75,7 +75,7 @@ class FDirectory : public FResourceFile const bool nosubdir; int AddDirectory(const char* dirpath, LumpFilterInfo* filter, FileSystemMessageFunc Printf); - void AddEntry(const char *fullpath, int size); + void AddEntry(const char *fullpath, const char* relpath, int size); public: FDirectory(const char * dirname, StringPool* sp, bool nosubdirflag = false); @@ -135,7 +135,7 @@ int FDirectory::AddDirectory(const char *dirpath, LumpFilterInfo* filter, FileSy Printf(FSMessageLevel::Warning, "%s is larger than 2GB and will be ignored\n", entry.FilePath.c_str()); continue; } - AddEntry(entry.FilePathRel.c_str(), (int)entry.Length); + AddEntry(entry.FilePath.c_str(), entry.FilePathRel.c_str(), (int)entry.Length); count++; } } @@ -163,15 +163,15 @@ bool FDirectory::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) // //========================================================================== -void FDirectory::AddEntry(const char *fullpath, int size) +void FDirectory::AddEntry(const char *fullpath, const char* relpath, int size) { FDirectoryLump *lump_p = &Lumps[Lumps.Reserve(1)]; // Store the full path here so that we can access the file later, even if it is from a filter directory. - lump_p->mFullPath = fullpath; + lump_p->mFullPath = stringpool->Strdup(fullpath); // [mxd] Convert name to lowercase - std::string name = fullpath + strlen(FileName); + std::string name = relpath; for (auto& c : name) c = tolower(c); // The lump's name is only the part relative to the main directory @@ -192,7 +192,7 @@ void FDirectory::AddEntry(const char *fullpath, int size) FileReader FDirectoryLump::NewReader() { FileReader fr; - fr.OpenFile(mFullPath.c_str()); + fr.OpenFile(mFullPath); return fr; } @@ -206,7 +206,7 @@ int FDirectoryLump::FillCache() { FileReader fr; Cache = new char[LumpSize]; - if (!fr.OpenFile(mFullPath.c_str())) + if (!fr.OpenFile(mFullPath)) { throw FileSystemException("unable to open file"); } From af3afca658211fa2c7425a912e0006886dac9557 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Thu, 24 Aug 2023 13:25:37 +0300 Subject: [PATCH 059/223] - fixed game sources variable in CMake CMake Error at src/CMakeLists.txt:1233 (add_executable): No SOURCES given to target: zdoom --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cc4fafb5a..8ecc719aa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1230,7 +1230,7 @@ set( GAME_SOURCES set( GAME_NONPCH_SOURCES ${GAME_SOURCES} ) list( REMOVE_ITEM GAME_NONPCH_SOURCES ${PCH_SOURCES} ) -add_executable( zdoom WIN32 MACOSX_BUNDLE ${ZDOOM_SOURCES} ) +add_executable( zdoom WIN32 MACOSX_BUNDLE ${GAME_SOURCES} ) target_precompile_headers( zdoom PRIVATE g_pch.h ) From d93657a11d7e6065bfd08a87c3c623c7aeba358d Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Fri, 25 Aug 2023 07:26:58 -0400 Subject: [PATCH 060/223] - add auto setup script for Windows --- auto-setup-windows.cmd | 77 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 auto-setup-windows.cmd diff --git a/auto-setup-windows.cmd b/auto-setup-windows.cmd new file mode 100644 index 000000000..dd2e935f6 --- /dev/null +++ b/auto-setup-windows.cmd @@ -0,0 +1,77 @@ +@echo off +goto aftercopyright + +** +** auto-setup-windows.cmd +** Automatic (easy) setup and build script for Windows +** +** Note that this script assumes you have both 'git' and 'cmake' installed properly and in your PATH! +** This script also assumes you have installed a build system that cmake can automatically detect. +** Such as Visual Studio Community. Requires appropriate SDK installed too! +** Without these items, this script will FAIL! So make sure you have your build environment properly +** set up in order for this script to succeed. +** +** The purpose of this script is to get someone easily going with a full working compile of GZDoom. +** This allows anyone to make simple changes or tweaks to the engine as they see fit and easily +** compile their own copy without having to follow complex instructions to get it working. +** Every build environment is different, and every computer system is different - this should work +** in most typical systems under Windows but it may fail under certain types of systems or conditions. +** Not guaranteed to work and your mileage will vary. +** +**--------------------------------------------------------------------------- +** Copyright 2023 Rachael Alexanderson and the GZDoom team +** 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. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. +**--------------------------------------------------------------------------- +** + +:aftercopyright + + +setlocal +rem -- Always operate within the build folder +if not exist "%~dp0\build" mkdir "%~dp0\build" +pushd "%~dp0\build" + +if exist vcpkg if exist vcpkg\* git -C ./vcpkg pull +if not exist vcpkg git clone https://github.com/microsoft/vcpkg + +if exist zmusic if exist vcpkg\* git -C ./zmusic pull +if not exist zmusic git clone https://github.com/zdoom/zmusic + +mkdir "%~dp0\build\zmusic\build" + +cmake -A x64 -S ./zmusic -B ./zmusic/build +cmake --build ./zmusic/build --config Release -- -maxcpucount -verbosity:minimal + +cmake -A x64 -S .. -B . ^ + -DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake ^ + -DZMUSIC_INCLUDE_DIR=./zmusic/include ^ + -DZMUSIC_LIBRARIES=./zmusic/build/source/Release/zmusic.lib +cmake --build . --config RelWithDebInfo -- -maxcpucount -verbosity:minimal + +rem -- If successful, show the build +if exist RelWithDebInfo\gzdoom.exe explorer.exe RelWithDebInfo + From afecb1ca0fcd43bffb0fc3becd025d3cfd26cc6a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 25 Aug 2023 20:04:30 +0200 Subject: [PATCH 061/223] - avoid high stack usage in anmtexture.cpp MSVC warned about this one. --- src/common/textures/formats/anmtexture.cpp | 45 ++++++++++++---------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/common/textures/formats/anmtexture.cpp b/src/common/textures/formats/anmtexture.cpp index ad02db728..5024edca2 100644 --- a/src/common/textures/formats/anmtexture.cpp +++ b/src/common/textures/formats/anmtexture.cpp @@ -33,6 +33,7 @@ ** */ +#include #include "files.h" #include "filesystem.h" #include "bitmap.h" @@ -72,12 +73,12 @@ FImageSource *AnmImage_TryCreate(FileReader & file, int lumpnum) file.Seek(0, FileReader::SeekSet); auto buffer = file.ReadPadded(1); - anim_t anim; - if (ANIM_LoadAnim(&anim, buffer.data(), buffer.size() - 1) < 0) + std::unique_ptr anim = std::make_unique(); // note that this struct is very large and should not go onto the stack! + if (ANIM_LoadAnim(anim.get(), buffer.data(), buffer.size() - 1) < 0) { return nullptr; } - int numframes = ANIM_NumFrames(&anim); + int numframes = ANIM_NumFrames(anim.get()); if (numframes >= 1) { return new FAnmTexture(lumpnum, 320, 200); @@ -106,14 +107,14 @@ void FAnmTexture::ReadFrame(uint8_t *pixels, uint8_t *palette) auto lump = fileSystem.ReadFile (SourceLump); auto source = lump.GetBytes(); - anim_t anim; - if (ANIM_LoadAnim(&anim, source, (int)lump.GetSize()) >= 0) + std::unique_ptr anim = std::make_unique(); // note that this struct is very large and should not go onto the stack! + if (ANIM_LoadAnim(anim.get(), source, (int)lump.GetSize()) >= 0) { - int numframes = ANIM_NumFrames(&anim); + int numframes = ANIM_NumFrames(anim.get()); if (numframes >= 1) { - memcpy(palette, ANIM_GetPalette(&anim), 768); - memcpy(pixels, ANIM_DrawFrame(&anim, 1), Width*Height); + memcpy(palette, ANIM_GetPalette(anim.get()), 768); + memcpy(pixels, ANIM_DrawFrame(anim.get(), 1), Width * Height); return; } } @@ -121,6 +122,12 @@ void FAnmTexture::ReadFrame(uint8_t *pixels, uint8_t *palette) memset(palette, 0, 768); } +struct workbuf +{ + uint8_t buffer[64000]; + uint8_t palette[768]; +}; + //========================================================================== // // @@ -130,16 +137,15 @@ void FAnmTexture::ReadFrame(uint8_t *pixels, uint8_t *palette) PalettedPixels FAnmTexture::CreatePalettedPixels(int conversion, int frame) { PalettedPixels pixels(Width*Height); - uint8_t buffer[64000]; - uint8_t palette[768]; uint8_t remap[256]; + std::unique_ptr w = std::make_unique(); - ReadFrame(buffer, palette); + ReadFrame(w->buffer, w->palette); for(int i=0;i<256;i++) { - remap[i] = ColorMatcher.Pick(palette[i*3], palette[i*3+1], palette[i*3+2]); + remap[i] = ColorMatcher.Pick(w->palette[i*3], w->palette[i*3+1], w->palette[i*3+2]); } - ImageHelpers::FlipNonSquareBlockRemap (pixels.Data(), buffer, Width, Height, Width, remap); + ImageHelpers::FlipNonSquareBlockRemap (pixels.Data(), w->buffer, Width, Height, Width, remap); return pixels; } @@ -151,18 +157,17 @@ PalettedPixels FAnmTexture::CreatePalettedPixels(int conversion, int frame) int FAnmTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { - uint8_t buffer[64000]; - uint8_t palette[768]; - ReadFrame(buffer, palette); + std::unique_ptr w = std::make_unique(); + ReadFrame(w->buffer, w->palette); auto dpix = bmp->GetPixels(); for (int i = 0; i < Width * Height; i++) { int p = i * 4; - int index = buffer[i]; - dpix[p + 0] = palette[index * 3 + 2]; - dpix[p + 1] = palette[index * 3 + 1]; - dpix[p + 2] = palette[index * 3]; + int index = w->buffer[i]; + dpix[p + 0] = w->palette[index * 3 + 2]; + dpix[p + 1] = w->palette[index * 3 + 1]; + dpix[p + 2] = w->palette[index * 3]; dpix[p + 3] = 255; } From ccd39d6df75328d50832ffdc2b28ff9ca3bd4860 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 25 Aug 2023 20:05:52 +0200 Subject: [PATCH 062/223] - code cleanup --- src/common/fonts/font.cpp | 2 +- src/common/fonts/fontinternals.h | 2 -- src/common/textures/animlib.cpp | 2 +- src/common/textures/bitmap.cpp | 2 +- src/common/textures/bitmap.h | 16 ++++++------- .../textures/formats/brightmaptexture.cpp | 2 +- src/common/textures/formats/imgztexture.cpp | 4 ++-- src/common/textures/formats/patchtexture.cpp | 15 ++++++++++-- .../textures/formats/rawpagetexture.cpp | 12 +++++++++- src/common/textures/image.h | 24 +++++++++++-------- src/common/textures/m_png.cpp | 10 +++++++- src/common/textures/m_png.h | 1 - src/common/textures/textures.h | 1 - 13 files changed, 60 insertions(+), 33 deletions(-) diff --git a/src/common/fonts/font.cpp b/src/common/fonts/font.cpp index 1714d78b4..ed7b871c2 100644 --- a/src/common/fonts/font.cpp +++ b/src/common/fonts/font.cpp @@ -422,7 +422,7 @@ void FFont::ReadSheetFont(std::vector &folderdata, int wid FBitmap* sheetimg = &sheetBitmaps[sheetBitmaps.Reserve(1)]; sheetimg->Create(tex->GetTexelWidth(), tex->GetTexelHeight()); - tex->GetTexture()->GetImage()->CopyPixels(sheetimg, FImageSource::normal); + tex->GetTexture()->GetImage()->CopyPixels(sheetimg, FImageSource::normal, 0); for (int y = 0; y < numtex_y; y++) { diff --git a/src/common/fonts/fontinternals.h b/src/common/fonts/fontinternals.h index b74750c57..149f9ab9f 100644 --- a/src/common/fonts/fontinternals.h +++ b/src/common/fonts/fontinternals.h @@ -35,5 +35,3 @@ extern TArray TranslationLookup; extern TArray TranslationColors; class FImageSource; - -void RecordTextureColors (FImageSource *pic, uint32_t *usedcolors); diff --git a/src/common/textures/animlib.cpp b/src/common/textures/animlib.cpp index 1b31244f3..cc83f87ba 100644 --- a/src/common/textures/animlib.cpp +++ b/src/common/textures/animlib.cpp @@ -25,9 +25,9 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au) */ //------------------------------------------------------------------------- +#include #include "animlib.h" #include "m_swap.h" -#include "m_alloc.h" //**************************************************************************** // diff --git a/src/common/textures/bitmap.cpp b/src/common/textures/bitmap.cpp index b685b0325..0a0553c3c 100644 --- a/src/common/textures/bitmap.cpp +++ b/src/common/textures/bitmap.cpp @@ -118,7 +118,7 @@ void iCopyColors(uint8_t *pout, const uint8_t *pin, int count, int step, FCopyIn a = TSrc::A(pin, tr, tg, tb); if (TBlend::ProcessAlpha0() || a) { - int gray = clamp(TSrc::Gray(pin),0,255); + int gray = std::clamp(TSrc::Gray(pin),0,255); PalEntry pe = cm->GrayscaleToColor[gray]; TBlend::OpC(pout[TDest::RED], pe.r , a, inf); diff --git a/src/common/textures/bitmap.h b/src/common/textures/bitmap.h index ae5ede88f..de9850c27 100644 --- a/src/common/textures/bitmap.h +++ b/src/common/textures/bitmap.h @@ -36,8 +36,6 @@ #ifndef __BITMAP_H__ #define __BITMAP_H__ -#include "basics.h" - #include "palentry.h" struct FCopyInfo; @@ -320,9 +318,9 @@ struct cCMYK struct cYCbCr { - static __forceinline unsigned char R(const unsigned char * p) { return clamp((int)(p[0] + 1.40200 * (int(p[2]) - 0x80)), 0, 255); } - static __forceinline unsigned char G(const unsigned char * p) { return clamp((int)(p[0] - 0.34414 * (int(p[1] - 0x80)) - 0.71414 * (int(p[2]) - 0x80)), 0, 255); } - static __forceinline unsigned char B(const unsigned char * p) { return clamp((int)(p[0] + 1.77200 * (int(p[1]) - 0x80)), 0, 255); } + static __forceinline unsigned char R(const unsigned char * p) { return std::clamp((int)(p[0] + 1.40200 * (int(p[2]) - 0x80)), 0, 255); } + static __forceinline unsigned char G(const unsigned char * p) { return std::clamp((int)(p[0] - 0.34414 * (int(p[1] - 0x80)) - 0.71414 * (int(p[2]) - 0x80)), 0, 255); } + static __forceinline unsigned char B(const unsigned char * p) { return std::clamp((int)(p[0] + 1.77200 * (int(p[1]) - 0x80)), 0, 255); } static __forceinline unsigned char A(const unsigned char * p, uint8_t x, uint8_t y, uint8_t z) { return 255; } static __forceinline int Gray(const unsigned char * p) { return (R(p) * 77 + G(p) * 143 + B(p) * 36) >> 8; } }; @@ -470,7 +468,7 @@ struct bCopyAlpha struct bOverlay { static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = (s*a + d*(255-a))/255; } - static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = max(s,d); } + static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = std::max(s,d); } static __forceinline bool ProcessAlpha0() { return false; } }; @@ -483,21 +481,21 @@ struct bBlend struct bAdd { - static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = min((d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 255); } + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = std::min((d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 255); } static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; struct bSubtract { - static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = max((d*BLENDUNIT - s*i->alpha) >> BLENDBITS, 0); } + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = std::max((d*BLENDUNIT - s*i->alpha) >> BLENDBITS, 0); } static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; struct bReverseSubtract { - static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = max((-d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 0); } + static __forceinline void OpC(uint8_t &d, uint8_t s, uint8_t a, FCopyInfo *i) { d = std::max((-d*BLENDUNIT + s*i->alpha) >> BLENDBITS, 0); } static __forceinline void OpA(uint8_t &d, uint8_t s, FCopyInfo *i) { d = s; } static __forceinline bool ProcessAlpha0() { return false; } }; diff --git a/src/common/textures/formats/brightmaptexture.cpp b/src/common/textures/formats/brightmaptexture.cpp index 43499f17e..262a520f6 100644 --- a/src/common/textures/formats/brightmaptexture.cpp +++ b/src/common/textures/formats/brightmaptexture.cpp @@ -67,7 +67,7 @@ FBrightmapTexture::FBrightmapTexture (FImageSource *source) int FBrightmapTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { - SourcePic->CopyTranslatedPixels(bmp, GPalette.GlobalBrightmap.Palette); + SourcePic->CopyTranslatedPixels(bmp, GPalette.GlobalBrightmap.Palette, frame); return 0; } diff --git a/src/common/textures/formats/imgztexture.cpp b/src/common/textures/formats/imgztexture.cpp index b5deaccac..831733a2b 100644 --- a/src/common/textures/formats/imgztexture.cpp +++ b/src/common/textures/formats/imgztexture.cpp @@ -200,7 +200,7 @@ PalettedPixels FIMGZTexture::CreatePalettedPixels(int conversion, int frame) int FIMGZTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { - if (!isalpha) return FImageSource::CopyPixels(bmp, conversion); - else return CopyTranslatedPixels(bmp, GPalette.GrayscaleMap.Palette); + if (!isalpha) return FImageSource::CopyPixels(bmp, conversion, frame); + else return CopyTranslatedPixels(bmp, GPalette.GrayscaleMap.Palette, frame); } diff --git a/src/common/textures/formats/patchtexture.cpp b/src/common/textures/formats/patchtexture.cpp index a6f70222f..0b6266a58 100644 --- a/src/common/textures/formats/patchtexture.cpp +++ b/src/common/textures/formats/patchtexture.cpp @@ -41,6 +41,17 @@ #include "m_swap.h" +// Doom patch format header +struct patch_t +{ + int16_t width; // bounding box size + int16_t height; + int16_t leftoffset; // pixels to the left of origin + int16_t topoffset; // pixels below the origin + uint32_t columnofs[1]; // only [width] used +}; + + // posts are runs of non masked source pixels struct column_t { @@ -266,8 +277,8 @@ PalettedPixels FPatchTexture::CreatePalettedPixels(int conversion, int frame) int FPatchTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { - if (!isalpha) return FImageSource::CopyPixels(bmp, conversion); - else return CopyTranslatedPixels(bmp, GPalette.GrayscaleMap.Palette); + if (!isalpha) return FImageSource::CopyPixels(bmp, conversion, frame); + else return CopyTranslatedPixels(bmp, GPalette.GrayscaleMap.Palette, frame); } //========================================================================== diff --git a/src/common/textures/formats/rawpagetexture.cpp b/src/common/textures/formats/rawpagetexture.cpp index b185f5ffc..cca68dd07 100644 --- a/src/common/textures/formats/rawpagetexture.cpp +++ b/src/common/textures/formats/rawpagetexture.cpp @@ -40,6 +40,16 @@ #include "image.h" #include "m_swap.h" +// Doom patch format header +struct patch_t +{ + int16_t width; // bounding box size + int16_t height; + int16_t leftoffset; // pixels to the left of origin + int16_t topoffset; // pixels below the origin + uint32_t columnofs[1]; // only [width] used +}; + //========================================================================== // @@ -201,7 +211,7 @@ PalettedPixels FRawPageTexture::CreatePalettedPixels(int conversion, int frame) int FRawPageTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) { - if (mPaletteLump < 0) return FImageSource::CopyPixels(bmp, conversion); + if (mPaletteLump < 0) return FImageSource::CopyPixels(bmp, conversion, frame); else { auto lump = fileSystem.ReadFile(SourceLump); diff --git a/src/common/textures/image.h b/src/common/textures/image.h index f9e761a20..72b5ca9df 100644 --- a/src/common/textures/image.h +++ b/src/common/textures/image.h @@ -5,20 +5,24 @@ #include "bitmap.h" #include "memarena.h" +#ifndef MAKE_ID +#ifndef __BIG_ENDIAN__ +#define MAKE_ID(a,b,c,d) ((uint32_t)((a)|((b)<<8)|((c)<<16)|((d)<<24))) +#else +#define MAKE_ID(a,b,c,d) ((uint32_t)((d)|((c)<<8)|((b)<<16)|((a)<<24))) +#endif +#endif + +using std::min; +using std::max; +using std::clamp; + + class FImageSource; using PrecacheInfo = TMap>; extern FMemArena ImageArena; -// Doom patch format header -struct patch_t -{ - int16_t width; // bounding box size - int16_t height; - int16_t leftoffset; // pixels to the left of origin - int16_t topoffset; // pixels below the origin - uint32_t columnofs[1]; // only [width] used -}; - +// Pixel store wrapper that can either own the pixels itself or refer to an external store. struct PalettedPixels { friend class FImageSource; diff --git a/src/common/textures/m_png.cpp b/src/common/textures/m_png.cpp index 8467a5d42..07cc1ab74 100644 --- a/src/common/textures/m_png.cpp +++ b/src/common/textures/m_png.cpp @@ -42,11 +42,13 @@ #include // for alloca() #endif -#include "basics.h" #include "m_crc32.h" #include "m_swap.h" +#if __has_include("c_cvars.h") #include "c_cvars.h" +#endif #include "m_png.h" +#include "basics.h" // MACROS ------------------------------------------------------------------ @@ -103,6 +105,8 @@ static void UnpackPixels (int width, int bytesPerRow, int bitdepth, const uint8_ // PUBLIC DATA DEFINITIONS ------------------------------------------------- +// allow this to compile without CVARs. +#if __has_include("c_cvars.h") CUSTOM_CVAR(Int, png_level, 5, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { if (self < 0) @@ -111,6 +115,10 @@ CUSTOM_CVAR(Int, png_level, 5, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) self = 9; } CVAR(Float, png_gamma, 0.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +#else +const int png_level = 5; +const float png_gamma = 0; +#endif // PRIVATE DATA DEFINITIONS ------------------------------------------------ diff --git a/src/common/textures/m_png.h b/src/common/textures/m_png.h index f65de4c0d..426e4d982 100644 --- a/src/common/textures/m_png.h +++ b/src/common/textures/m_png.h @@ -37,7 +37,6 @@ #include "zstring.h" #include "files.h" #include "palentry.h" -#include "basics.h" // Screenshot buffer image data types enum ESSType diff --git a/src/common/textures/textures.h b/src/common/textures/textures.h index 164aa79b8..6aa6c84a5 100644 --- a/src/common/textures/textures.h +++ b/src/common/textures/textures.h @@ -45,7 +45,6 @@ #include "floatrect.h" #include "refcounted.h" -typedef TMap SpriteHits; class FImageSource; class FGameTexture; class IHardwareTexture; From 948e7cd649c13172c16eba87f64052ffc5809cc7 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 26 Aug 2023 00:43:37 +0600 Subject: [PATCH 063/223] Update the auto setup script to build ZMusic with vcpkg as well --- auto-setup-windows.cmd | 9 +++++++-- vcpkg.json | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/auto-setup-windows.cmd b/auto-setup-windows.cmd index dd2e935f6..0a791ee92 100644 --- a/auto-setup-windows.cmd +++ b/auto-setup-windows.cmd @@ -62,14 +62,19 @@ if exist zmusic if exist vcpkg\* git -C ./zmusic pull if not exist zmusic git clone https://github.com/zdoom/zmusic mkdir "%~dp0\build\zmusic\build" +mkdir "%~dp0\build\vcpkg_installed" -cmake -A x64 -S ./zmusic -B ./zmusic/build +cmake -A x64 -S ./zmusic -B ./zmusic/build ^ + -DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake ^ + -DVCPKG_LIBSNDFILE=1 ^ + -DVCPKG_INSTALLLED_DIR=./vcpkg_installed/ cmake --build ./zmusic/build --config Release -- -maxcpucount -verbosity:minimal cmake -A x64 -S .. -B . ^ -DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake ^ -DZMUSIC_INCLUDE_DIR=./zmusic/include ^ - -DZMUSIC_LIBRARIES=./zmusic/build/source/Release/zmusic.lib + -DZMUSIC_LIBRARIES=./zmusic/build/source/Release/zmusic.lib ^ + -DVCPKG_INSTALLLED_DIR=./vcpkg_installed/ cmake --build . --config RelWithDebInfo -- -maxcpucount -verbosity:minimal rem -- If successful, show the build diff --git a/vcpkg.json b/vcpkg.json index d89c12d12..83cbaeb7a 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", - "builtin-baseline": "9d47b24eacbd1cd94f139457ef6cd35e5d92cc84", + "builtin-baseline": "65c013b9667ff1f58fb8724209227e5a2e761043", "features": { "vcpkg-libvpx": From 5d38e4c476762118c74ae3d54d20d7312dc107ab Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Fri, 25 Aug 2023 22:46:22 -0400 Subject: [PATCH 064/223] - fix paths in previous commit --- auto-setup-windows.cmd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/auto-setup-windows.cmd b/auto-setup-windows.cmd index 0a791ee92..00ed93cd1 100644 --- a/auto-setup-windows.cmd +++ b/auto-setup-windows.cmd @@ -65,9 +65,9 @@ mkdir "%~dp0\build\zmusic\build" mkdir "%~dp0\build\vcpkg_installed" cmake -A x64 -S ./zmusic -B ./zmusic/build ^ - -DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake ^ + -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake ^ -DVCPKG_LIBSNDFILE=1 ^ - -DVCPKG_INSTALLLED_DIR=./vcpkg_installed/ + -DVCPKG_INSTALLLED_DIR=../vcpkg_installed/ cmake --build ./zmusic/build --config Release -- -maxcpucount -verbosity:minimal cmake -A x64 -S .. -B . ^ From 44623daafe442bc1edf7b2d825dad3e5fe4c5532 Mon Sep 17 00:00:00 2001 From: Major Cooke Date: Mon, 28 Aug 2023 12:20:07 -0500 Subject: [PATCH 065/223] Fixed wrong pointer being used in PlayerFinishLevel, causing wrong inventory items to be destroyed. --- wadsrc/static/zscript/actors/player/player.zs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index 5f6d0f616..e103bcd5f 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -2111,7 +2111,7 @@ class PlayerPawn : Actor let it = toDelete[i]; if (!it.bDestroyed) { - item.DepleteOrDestroy(); + it.DepleteOrDestroy(); } } } From 520b6af947a174dff5caaa515e12670148e6ae6f Mon Sep 17 00:00:00 2001 From: inkoalawetrust <56005600+inkoalawetrust@users.noreply.github.com> Date: Thu, 31 Aug 2023 19:38:14 +0300 Subject: [PATCH 066/223] Added some null pointer checks to prevent crashes. --- src/playsim/p_interaction.cpp | 3 +++ src/playsim/p_maputl.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/playsim/p_interaction.cpp b/src/playsim/p_interaction.cpp index 4baac07a4..88a06e435 100644 --- a/src/playsim/p_interaction.cpp +++ b/src/playsim/p_interaction.cpp @@ -1614,6 +1614,9 @@ DEFINE_ACTION_FUNCTION(AActor, PoisonMobj) bool AActor::OkayToSwitchTarget(AActor *other) { + if (other == nullptr) + return false; + if (other == this) return false; // [RH] Don't hate self (can happen when shooting barrels) diff --git a/src/playsim/p_maputl.cpp b/src/playsim/p_maputl.cpp index 16c7d183c..8c172c479 100644 --- a/src/playsim/p_maputl.cpp +++ b/src/playsim/p_maputl.cpp @@ -1686,7 +1686,7 @@ FPathTraverse::~FPathTraverse() // int P_CheckFov(AActor* t1, AActor* t2, double fov) { - return absangle(t1->AngleTo(t2), t1->Angles.Yaw) <= DAngle::fromDeg(fov); + return absangle(t1->AngleTo(PARAM_NULLCHECK(t2,t2)), t1->Angles.Yaw) <= DAngle::fromDeg(fov); } DEFINE_ACTION_FUNCTION_NATIVE(AActor, CheckFov, P_CheckFov) From d0a955fef000e26f301c0bbf662ecaf106db80ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Fri, 1 Sep 2023 13:20:44 -0300 Subject: [PATCH 067/223] Allow disabling colors for NameAllKeys --- src/common/scripting/interface/vmnatives.cpp | 3 ++- wadsrc/static/zscript/engine/ui/menu/menu.zs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index 3e75e75d8..cd309f9cc 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -1038,7 +1038,8 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, NameAllKeys) { PARAM_PROLOGUE; PARAM_POINTER(array, TArray); - auto buffer = C_NameKeys(array->Data(), array->Size(), true); + PARAM_BOOL(color); + auto buffer = C_NameKeys(array->Data(), array->Size(), color); ACTION_RETURN_STRING(buffer); } diff --git a/wadsrc/static/zscript/engine/ui/menu/menu.zs b/wadsrc/static/zscript/engine/ui/menu/menu.zs index 1c1877041..e7a9550f4 100644 --- a/wadsrc/static/zscript/engine/ui/menu/menu.zs +++ b/wadsrc/static/zscript/engine/ui/menu/menu.zs @@ -36,7 +36,7 @@ struct KeyBindings native version("2.4") { native static String NameKeys(int k1, int k2); - native static String NameAllKeys(array list); + native static String NameAllKeys(array list, bool colors = true); native int, int GetKeysForCommand(String cmd); native void GetAllKeysForCommand(out array list, String cmd); From 4baabf98c4f308dbc66a25d1b823ee65de64fc47 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 3 Sep 2023 08:34:21 +0200 Subject: [PATCH 068/223] - use stb-image for JPEG decoding. the statically provided library did not provide any advantage over it whatsoever and even libjpeg-turbo's better performance cannot really play out here so ease of use and getting rid of a dependency wins. --- .gitignore | 1 + CMakeLists.txt | 12 - libraries/jpeg/CMakeLists.txt | 36 - libraries/jpeg/README | 378 -- libraries/jpeg/jaricom.c | 153 - libraries/jpeg/jcomapi.c | 106 - libraries/jpeg/jconfig.h | 32 - libraries/jpeg/jdapimin.c | 399 -- libraries/jpeg/jdapistd.c | 276 - libraries/jpeg/jdarith.c | 796 --- libraries/jpeg/jdatasrc.c | 275 - libraries/jpeg/jdcoefct.c | 741 --- libraries/jpeg/jdcolor.c | 731 --- libraries/jpeg/jdct.h | 416 -- libraries/jpeg/jddctmgr.c | 384 -- libraries/jpeg/jdhuff.c | 1553 ------ libraries/jpeg/jdinput.c | 662 --- libraries/jpeg/jdmainct.c | 507 -- libraries/jpeg/jdmarker.c | 1511 ------ libraries/jpeg/jdmaster.c | 538 -- libraries/jpeg/jdmerge.c | 451 -- libraries/jpeg/jdpostct.c | 290 - libraries/jpeg/jdsample.c | 358 -- libraries/jpeg/jerror.c | 253 - libraries/jpeg/jerror.h | 304 -- libraries/jpeg/jidctflt.c | 238 - libraries/jpeg/jidctfst.c | 351 -- libraries/jpeg/jidctint.c | 5240 ------------------- libraries/jpeg/jinclude.h | 97 - libraries/jpeg/jmemansi.c | 167 - libraries/jpeg/jmemmgr.c | 1119 ---- libraries/jpeg/jmemsys.h | 198 - libraries/jpeg/jmorecfg.h | 446 -- libraries/jpeg/jpegint.h | 439 -- libraries/jpeg/jpeglib.h | 1180 ----- libraries/jpeg/jquant1.c | 857 --- libraries/jpeg/jquant2.c | 1311 ----- libraries/jpeg/jutils.c | 227 - libraries/jpeg/jversion.h | 14 - src/CMakeLists.txt | 5 +- src/common/rendering/gl/gl_hwtexture.cpp | 1 + src/common/textures/formats/jpegtexture.cpp | 487 -- src/common/textures/formats/stbtexture.cpp | 3 +- src/common/textures/image.cpp | 2 - vcpkg.json | 4 - 45 files changed, 5 insertions(+), 23544 deletions(-) delete mode 100644 libraries/jpeg/CMakeLists.txt delete mode 100644 libraries/jpeg/README delete mode 100644 libraries/jpeg/jaricom.c delete mode 100644 libraries/jpeg/jcomapi.c delete mode 100644 libraries/jpeg/jconfig.h delete mode 100644 libraries/jpeg/jdapimin.c delete mode 100644 libraries/jpeg/jdapistd.c delete mode 100644 libraries/jpeg/jdarith.c delete mode 100644 libraries/jpeg/jdatasrc.c delete mode 100644 libraries/jpeg/jdcoefct.c delete mode 100644 libraries/jpeg/jdcolor.c delete mode 100644 libraries/jpeg/jdct.h delete mode 100644 libraries/jpeg/jddctmgr.c delete mode 100644 libraries/jpeg/jdhuff.c delete mode 100644 libraries/jpeg/jdinput.c delete mode 100644 libraries/jpeg/jdmainct.c delete mode 100644 libraries/jpeg/jdmarker.c delete mode 100644 libraries/jpeg/jdmaster.c delete mode 100644 libraries/jpeg/jdmerge.c delete mode 100644 libraries/jpeg/jdpostct.c delete mode 100644 libraries/jpeg/jdsample.c delete mode 100644 libraries/jpeg/jerror.c delete mode 100644 libraries/jpeg/jerror.h delete mode 100644 libraries/jpeg/jidctflt.c delete mode 100644 libraries/jpeg/jidctfst.c delete mode 100644 libraries/jpeg/jidctint.c delete mode 100644 libraries/jpeg/jinclude.h delete mode 100644 libraries/jpeg/jmemansi.c delete mode 100644 libraries/jpeg/jmemmgr.c delete mode 100644 libraries/jpeg/jmemsys.h delete mode 100644 libraries/jpeg/jmorecfg.h delete mode 100644 libraries/jpeg/jpegint.h delete mode 100644 libraries/jpeg/jpeglib.h delete mode 100644 libraries/jpeg/jquant1.c delete mode 100644 libraries/jpeg/jquant2.c delete mode 100644 libraries/jpeg/jutils.c delete mode 100644 libraries/jpeg/jversion.h delete mode 100644 src/common/textures/formats/jpegtexture.cpp diff --git a/.gitignore b/.gitignore index a7ea8ab4f..b434b52a7 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ /build2 /build_vc2019-64 /build_vc2019-32 +/build__ diff --git a/CMakeLists.txt b/CMakeLists.txt index d59560964..7554ea27f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,7 +214,6 @@ endmacro() option( NO_OPENAL "Disable OpenAL sound support" OFF ) find_package( BZip2 ) -find_package( JPEG ) find_package( VPX ) find_package( ZLIB ) find_package( WebP ) @@ -349,7 +348,6 @@ set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${REL_C_F set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" ) option(FORCE_INTERNAL_ZLIB "Use internal zlib") -option(FORCE_INTERNAL_JPEG "Use internal jpeg") option(FORCE_INTERNAL_BZIP2 "Use internal bzip2") option(FORCE_INTERNAL_ASMJIT "Use internal asmjit" ON) mark_as_advanced( FORCE_INTERNAL_ASMJIT ) @@ -401,16 +399,6 @@ if( ${HAVE_VM_JIT} ) endif() endif() -if( JPEG_FOUND AND NOT FORCE_INTERNAL_JPEG ) - message( STATUS "Using system jpeg library, includes found at ${JPEG_INCLUDE_DIR}" ) -else() - message( STATUS "Using internal jpeg library" ) - add_subdirectory( libraries/jpeg ) - set( JPEG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libraries/jpeg ) - set( JPEG_LIBRARIES jpeg ) - set( JPEG_LIBRARY jpeg ) -endif() - if( BZIP2_FOUND AND NOT FORCE_INTERNAL_BZIP2 ) message( STATUS "Using system bzip2 library, includes found at ${BZIP2_INCLUDE_DIR}" ) else() diff --git a/libraries/jpeg/CMakeLists.txt b/libraries/jpeg/CMakeLists.txt deleted file mode 100644 index d57779495..000000000 --- a/libraries/jpeg/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -cmake_minimum_required( VERSION 3.1.0 ) - -make_release_only() - -if( ZD_CMAKE_COMPILER_IS_GNUC_COMPATIBLE ) - set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-parameter -fomit-frame-pointer" ) -endif() - -add_library( jpeg STATIC - jaricom.c - jcomapi.c - jdapimin.c - jdapistd.c - jdarith.c - jdatasrc.c - jdcoefct.c - jdcolor.c - jddctmgr.c - jdhuff.c - jdinput.c - jdmainct.c - jdmarker.c - jdmaster.c - jdmerge.c - jdpostct.c - jdsample.c - jerror.c - jidctflt.c - jidctfst.c - jidctint.c - jmemansi.c - jmemmgr.c - jquant1.c - jquant2.c - jutils.c ) -target_link_libraries( jpeg ) diff --git a/libraries/jpeg/README b/libraries/jpeg/README deleted file mode 100644 index 56cdb6003..000000000 --- a/libraries/jpeg/README +++ /dev/null @@ -1,378 +0,0 @@ -The Independent JPEG Group's JPEG software -========================================== - -README for release 9c of 14-Jan-2018 -==================================== - -This distribution contains the ninth public release of the Independent JPEG -Group's free JPEG software. You are welcome to redistribute this software and -to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. - -This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone, -Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson, -Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers, -and other members of the Independent JPEG Group. - -IJG is not affiliated with the ISO/IEC JTC1/SC29/WG1 standards committee -(previously known as JPEG, together with ITU-T SG16). - - -DOCUMENTATION ROADMAP -===================== - -This file contains the following sections: - -OVERVIEW General description of JPEG and the IJG software. -LEGAL ISSUES Copyright, lack of warranty, terms of distribution. -REFERENCES Where to learn more about JPEG. -ARCHIVE LOCATIONS Where to find newer versions of this software. -ACKNOWLEDGMENTS Special thanks. -FILE FORMAT WARS Software *not* to get. -TO DO Plans for future IJG releases. - -Other documentation files in the distribution are: - -User documentation: - install.txt How to configure and install the IJG software. - usage.txt Usage instructions for cjpeg, djpeg, jpegtran, - rdjpgcom, and wrjpgcom. - *.1 Unix-style man pages for programs (same info as usage.txt). - wizard.txt Advanced usage instructions for JPEG wizards only. - change.log Version-to-version change highlights. -Programmer and internal documentation: - libjpeg.txt How to use the JPEG library in your own programs. - example.c Sample code for calling the JPEG library. - structure.txt Overview of the JPEG library's internal structure. - filelist.txt Road map of IJG files. - coderules.txt Coding style rules --- please read if you contribute code. - -Please read at least the files install.txt and usage.txt. Some information -can also be found in the JPEG FAQ (Frequently Asked Questions) article. See -ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. - -If you want to understand how the JPEG code works, we suggest reading one or -more of the REFERENCES, then looking at the documentation files (in roughly -the order listed) before diving into the code. - - -OVERVIEW -======== - -This package contains C software to implement JPEG image encoding, decoding, -and transcoding. JPEG (pronounced "jay-peg") is a standardized compression -method for full-color and grayscale images. - -This software implements JPEG baseline, extended-sequential, and progressive -compression processes. Provision is made for supporting all variants of these -processes, although some uncommon parameter settings aren't implemented yet. -We have made no provision for supporting the hierarchical or lossless -processes defined in the standard. - -We provide a set of library routines for reading and writing JPEG image files, -plus two sample applications "cjpeg" and "djpeg", which use the library to -perform conversion between JPEG and some other popular image file formats. -The library is intended to be reused in other applications. - -In order to support file conversion and viewing software, we have included -considerable functionality beyond the bare JPEG coding/decoding capability; -for example, the color quantization modules are not strictly part of JPEG -decoding, but they are essential for output to colormapped file formats or -colormapped displays. These extra functions can be compiled out of the -library if not required for a particular application. - -We have also included "jpegtran", a utility for lossless transcoding between -different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple -applications for inserting and extracting textual comments in JFIF files. - -The emphasis in designing this software has been on achieving portability and -flexibility, while also making it fast enough to be useful. In particular, -the software is not intended to be read as a tutorial on JPEG. (See the -REFERENCES section for introductory material.) Rather, it is intended to -be reliable, portable, industrial-strength code. We do not claim to have -achieved that goal in every aspect of the software, but we strive for it. - -We welcome the use of this software as a component of commercial products. -No royalty is required, but we do ask for an acknowledgement in product -documentation, as described under LEGAL ISSUES. - - -LEGAL ISSUES -============ - -In plain English: - -1. We don't promise that this software works. (But if you find any bugs, - please let us know!) -2. You can use this software for whatever you want. You don't have to pay us. -3. You may not pretend that you wrote this software. If you use it in a - program, you must acknowledge somewhere in your documentation that - you've used the IJG code. - -In legalese: - -The authors make NO WARRANTY or representation, either express or implied, -with respect to this software, its quality, accuracy, merchantability, or -fitness for a particular purpose. This software is provided "AS IS", and you, -its user, assume the entire risk as to its quality and accuracy. - -This software is copyright (C) 1991-2018, Thomas G. Lane, Guido Vollbeding. -All Rights Reserved except as specified below. - -Permission is hereby granted to use, copy, modify, and distribute this -software (or portions thereof) for any purpose, without fee, subject to these -conditions: -(1) If any part of the source code for this software is distributed, then this -README file must be included, with this copyright and no-warranty notice -unaltered; and any additions, deletions, or changes to the original files -must be clearly indicated in accompanying documentation. -(2) If only executable code is distributed, then the accompanying -documentation must state that "this software is based in part on the work of -the Independent JPEG Group". -(3) Permission for use of this software is granted only if the user accepts -full responsibility for any undesirable consequences; the authors accept -NO LIABILITY for damages of any kind. - -These conditions apply to any software derived from or based on the IJG code, -not just to the unmodified library. If you use our work, you ought to -acknowledge us. - -Permission is NOT granted for the use of any IJG author's name or company name -in advertising or publicity relating to this software or products derived from -it. This software may be referred to only as "the Independent JPEG Group's -software". - -We specifically permit and encourage the use of this software as the basis of -commercial products, provided that all warranty or liability claims are -assumed by the product vendor. - - -The Unix configuration script "configure" was produced with GNU Autoconf. -It is copyright by the Free Software Foundation but is freely distributable. -The same holds for its supporting scripts (config.guess, config.sub, -ltmain.sh). Another support script, install-sh, is copyright by X Consortium -but is also freely distributable. - -The IJG distribution formerly included code to read and write GIF files. -To avoid entanglement with the Unisys LZW patent (now expired), GIF reading -support has been removed altogether, and the GIF writer has been simplified -to produce "uncompressed GIFs". This technique does not use the LZW -algorithm; the resulting GIF files are larger than usual, but are readable -by all standard GIF decoders. - - -REFERENCES -========== - -We recommend reading one or more of these references before trying to -understand the innards of the JPEG software. - -The best short technical introduction to the JPEG compression algorithm is - Wallace, Gregory K. "The JPEG Still Picture Compression Standard", - Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. -(Adjacent articles in that issue discuss MPEG motion picture compression, -applications of JPEG, and related topics.) If you don't have the CACM issue -handy, a PDF file containing a revised version of Wallace's article is -available at http://www.ijg.org/files/Wallace.JPEG.pdf. The file (actually -a preprint for an article that appeared in IEEE Trans. Consumer Electronics) -omits the sample images that appeared in CACM, but it includes corrections -and some added material. Note: the Wallace article is copyright ACM and IEEE, -and it may not be used for commercial purposes. - -A somewhat less technical, more leisurely introduction to JPEG can be found in -"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by -M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides -good explanations and example C code for a multitude of compression methods -including JPEG. It is an excellent source if you are comfortable reading C -code but don't know much about data compression in general. The book's JPEG -sample code is far from industrial-strength, but when you are ready to look -at a full implementation, you've got one here... - -The best currently available description of JPEG is the textbook "JPEG Still -Image Data Compression Standard" by William B. Pennebaker and Joan L. -Mitchell, published by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. -Price US$59.95, 638 pp. The book includes the complete text of the ISO JPEG -standards (DIS 10918-1 and draft DIS 10918-2). -Although this is by far the most detailed and comprehensive exposition of -JPEG publicly available, we point out that it is still missing an explanation -of the most essential properties and algorithms of the underlying DCT -technology. -If you think that you know about DCT-based JPEG after reading this book, -then you are in delusion. The real fundamentals and corresponding potential -of DCT-based JPEG are not publicly known so far, and that is the reason for -all the mistaken developments taking place in the image coding domain. - -The original JPEG standard is divided into two parts, Part 1 being the actual -specification, while Part 2 covers compliance testing methods. Part 1 is -titled "Digital Compression and Coding of Continuous-tone Still Images, -Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS -10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of -Continuous-tone Still Images, Part 2: Compliance testing" and has document -numbers ISO/IEC IS 10918-2, ITU-T T.83. -IJG JPEG 8 introduced an implementation of the JPEG SmartScale extension -which is specified in two documents: A contributed document at ITU and ISO -with title "ITU-T JPEG-Plus Proposal for Extending ITU-T T.81 for Advanced -Image Coding", April 2006, Geneva, Switzerland. The latest version of this -document is Revision 3. And a contributed document ISO/IEC JTC1/SC29/WG1 N -5799 with title "Evolution of JPEG", June/July 2011, Berlin, Germany. -IJG JPEG 9 introduces a reversible color transform for improved lossless -compression which is described in a contributed document ISO/IEC JTC1/SC29/ -WG1 N 6080 with title "JPEG 9 Lossless Coding", June/July 2012, Paris, -France. - -The JPEG standard does not specify all details of an interchangeable file -format. For the omitted details we follow the "JFIF" conventions, version 2. -JFIF version 1 has been adopted as Recommendation ITU-T T.871 (05/2011) : -Information technology - Digital compression and coding of continuous-tone -still images: JPEG File Interchange Format (JFIF). It is available as a -free download in PDF file format from http://www.itu.int/rec/T-REC-T.871. -A PDF file of the older JFIF document is available at -http://www.w3.org/Graphics/JPEG/jfif3.pdf. - -The TIFF 6.0 file format specification can be obtained by FTP from -ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme -found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. -IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). -Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 -(Compression tag 7). Copies of this Note can be obtained from -http://www.ijg.org/files/. It is expected that the next revision -of the TIFF spec will replace the 6.0 JPEG design with the Note's design. -Although IJG's own code does not support TIFF/JPEG, the free libtiff library -uses our library to implement TIFF/JPEG per the Note. - - -ARCHIVE LOCATIONS -================= - -The "official" archive site for this software is www.ijg.org. -The most recent released version can always be found there in -directory "files". This particular version will be archived as -http://www.ijg.org/files/jpegsrc.v9c.tar.gz, and in Windows-compatible -"zip" archive format as http://www.ijg.org/files/jpegsr9c.zip. - -The JPEG FAQ (Frequently Asked Questions) article is a source of some -general information about JPEG. -It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/ -and other news.answers archive sites, including the official news.answers -archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/. -If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu -with body - send usenet/news.answers/jpeg-faq/part1 - send usenet/news.answers/jpeg-faq/part2 - - -ACKNOWLEDGMENTS -=============== - -Thank to Juergen Bruder for providing me with a copy of the common DCT -algorithm article, only to find out that I had come to the same result -in a more direct and comprehensible way with a more generative approach. - -Thank to Istvan Sebestyen and Joan L. Mitchell for inviting me to the -ITU JPEG (Study Group 16) meeting in Geneva, Switzerland. - -Thank to Thomas Wiegand and Gary Sullivan for inviting me to the -Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland. - -Thank to Thomas Richter and Daniel Lee for inviting me to the -ISO/IEC JTC1/SC29/WG1 (previously known as JPEG, together with ITU-T SG16) -meeting in Berlin, Germany. - -Thank to John Korejwa and Massimo Ballerini for inviting me to -fruitful consultations in Boston, MA and Milan, Italy. - -Thank to Hendrik Elstner, Roland Fassauer, Simone Zuck, Guenther -Maier-Gerber, Walter Stoeber, Fred Schmitz, and Norbert Braunagel -for corresponding business development. - -Thank to Nico Zschach and Dirk Stelling of the technical support team -at the Digital Images company in Halle for providing me with extra -equipment for configuration tests. - -Thank to Richard F. Lyon (then of Foveon Inc.) for fruitful -communication about JPEG configuration in Sigma Photo Pro software. - -Thank to Andrew Finkenstadt for hosting the ijg.org site. - -Thank to Thomas G. Lane for the original design and development of -this singular software package. - -Thank to Lars Goehler, Andreas Heinecke, Sebastian Fuss, Yvonne Roebert, -Andrej Werner, and Ulf-Dietrich Braumann for support and public relations. - - -FILE FORMAT WARS -================ - -The ISO/IEC JTC1/SC29/WG1 standards committee (previously known as JPEG, -together with ITU-T SG16) currently promotes different formats containing -the name "JPEG" which is misleading because these formats are incompatible -with original DCT-based JPEG and are based on faulty technologies. -IJG therefore does not and will not support such momentary mistakes -(see REFERENCES). -There exist also distributions under the name "OpenJPEG" promoting such -kind of formats which is misleading because they don't support original -JPEG images. -We have no sympathy for the promotion of inferior formats. Indeed, one of -the original reasons for developing this free software was to help force -convergence on common, interoperable format standards for JPEG files. -Don't use an incompatible file format! -(In any case, our decoder will remain capable of reading existing JPEG -image files indefinitely.) - -The ISO committee pretends to be "responsible for the popular JPEG" in their -public reports which is not true because they don't respond to actual -requirements for the maintenance of the original JPEG specification. -Furthermore, the ISO committee pretends to "ensure interoperability" with -their standards which is not true because their "standards" support only -application-specific and proprietary use cases and contain mathematically -incorrect code. - -There are currently different distributions in circulation containing the -name "libjpeg" which is misleading because they don't have the features and -are incompatible with formats supported by actual IJG libjpeg distributions. -One of those fakes is released by members of the ISO committee and just uses -the name of libjpeg for misdirection of people, similar to the abuse of the -name JPEG as described above, while having nothing in common with actual IJG -libjpeg distributions and containing mathematically incorrect code. -The other one claims to be a "derivative" or "fork" of the original libjpeg, -but violates the license conditions as described under LEGAL ISSUES above -and violates basic C programming properties. -We have no sympathy for the release of misleading, incorrect and illegal -distributions derived from obsolete code bases. -Don't use an obsolete code base! - -According to the UCC (Uniform Commercial Code) law, IJG has the lawful and -legal right to foreclose on certain standardization bodies and other -institutions or corporations that knowingly perform substantial and -systematic deceptive acts and practices, fraud, theft, and damaging of the -value of the people of this planet without their knowing, willing and -intentional consent. -The titles, ownership, and rights of these institutions and all their assets -are now duly secured and held in trust for the free people of this planet. -People of the planet, on every country, may have a financial interest in -the assets of these former principals, agents, and beneficiaries of the -foreclosed institutions and corporations. -IJG asserts what is: that each man, woman, and child has unalienable value -and rights granted and deposited in them by the Creator and not any one of -the people is subordinate to any artificial principality, corporate fiction -or the special interest of another without their appropriate knowing, -willing and intentional consent made by contract or accommodation agreement. -IJG expresses that which already was. -The people have already determined and demanded that public administration -entities, national governments, and their supporting judicial systems must -be fully transparent, accountable, and liable. -IJG has secured the value for all concerned free people of the planet. - -A partial list of foreclosed institutions and corporations ("Hall of Shame") -is currently prepared and will be published later. - - -TO DO -===== - -Version 9 is the second release of a new generation JPEG standard -to overcome the limitations of the original JPEG specification, -and is the first true source reference JPEG codec. -More features are being prepared for coming releases... - -Please send bug reports, offers of help, etc. to jpeg-info@jpegclub.org. diff --git a/libraries/jpeg/jaricom.c b/libraries/jpeg/jaricom.c deleted file mode 100644 index 690068861..000000000 --- a/libraries/jpeg/jaricom.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * jaricom.c - * - * Developed 1997-2011 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains probability estimation tables for common use in - * arithmetic entropy encoding and decoding routines. - * - * This data represents Table D.3 in the JPEG spec (D.2 in the draft), - * ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81, and Table 24 - * in the JBIG spec, ISO/IEC IS 11544 and CCITT Recommendation ITU-T T.82. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - -/* The following #define specifies the packing of the four components - * into the compact INT32 representation. - * Note that this formula must match the actual arithmetic encoder - * and decoder implementation. The implementation has to be changed - * if this formula is changed. - * The current organization is leaned on Markus Kuhn's JBIG - * implementation (jbig_tab.c). - */ - -#define V(i,a,b,c,d) (((INT32)a << 16) | ((INT32)c << 8) | ((INT32)d << 7) | b) - -const INT32 jpeg_aritab[113+1] = { -/* - * Index, Qe_Value, Next_Index_LPS, Next_Index_MPS, Switch_MPS - */ - V( 0, 0x5a1d, 1, 1, 1 ), - V( 1, 0x2586, 14, 2, 0 ), - V( 2, 0x1114, 16, 3, 0 ), - V( 3, 0x080b, 18, 4, 0 ), - V( 4, 0x03d8, 20, 5, 0 ), - V( 5, 0x01da, 23, 6, 0 ), - V( 6, 0x00e5, 25, 7, 0 ), - V( 7, 0x006f, 28, 8, 0 ), - V( 8, 0x0036, 30, 9, 0 ), - V( 9, 0x001a, 33, 10, 0 ), - V( 10, 0x000d, 35, 11, 0 ), - V( 11, 0x0006, 9, 12, 0 ), - V( 12, 0x0003, 10, 13, 0 ), - V( 13, 0x0001, 12, 13, 0 ), - V( 14, 0x5a7f, 15, 15, 1 ), - V( 15, 0x3f25, 36, 16, 0 ), - V( 16, 0x2cf2, 38, 17, 0 ), - V( 17, 0x207c, 39, 18, 0 ), - V( 18, 0x17b9, 40, 19, 0 ), - V( 19, 0x1182, 42, 20, 0 ), - V( 20, 0x0cef, 43, 21, 0 ), - V( 21, 0x09a1, 45, 22, 0 ), - V( 22, 0x072f, 46, 23, 0 ), - V( 23, 0x055c, 48, 24, 0 ), - V( 24, 0x0406, 49, 25, 0 ), - V( 25, 0x0303, 51, 26, 0 ), - V( 26, 0x0240, 52, 27, 0 ), - V( 27, 0x01b1, 54, 28, 0 ), - V( 28, 0x0144, 56, 29, 0 ), - V( 29, 0x00f5, 57, 30, 0 ), - V( 30, 0x00b7, 59, 31, 0 ), - V( 31, 0x008a, 60, 32, 0 ), - V( 32, 0x0068, 62, 33, 0 ), - V( 33, 0x004e, 63, 34, 0 ), - V( 34, 0x003b, 32, 35, 0 ), - V( 35, 0x002c, 33, 9, 0 ), - V( 36, 0x5ae1, 37, 37, 1 ), - V( 37, 0x484c, 64, 38, 0 ), - V( 38, 0x3a0d, 65, 39, 0 ), - V( 39, 0x2ef1, 67, 40, 0 ), - V( 40, 0x261f, 68, 41, 0 ), - V( 41, 0x1f33, 69, 42, 0 ), - V( 42, 0x19a8, 70, 43, 0 ), - V( 43, 0x1518, 72, 44, 0 ), - V( 44, 0x1177, 73, 45, 0 ), - V( 45, 0x0e74, 74, 46, 0 ), - V( 46, 0x0bfb, 75, 47, 0 ), - V( 47, 0x09f8, 77, 48, 0 ), - V( 48, 0x0861, 78, 49, 0 ), - V( 49, 0x0706, 79, 50, 0 ), - V( 50, 0x05cd, 48, 51, 0 ), - V( 51, 0x04de, 50, 52, 0 ), - V( 52, 0x040f, 50, 53, 0 ), - V( 53, 0x0363, 51, 54, 0 ), - V( 54, 0x02d4, 52, 55, 0 ), - V( 55, 0x025c, 53, 56, 0 ), - V( 56, 0x01f8, 54, 57, 0 ), - V( 57, 0x01a4, 55, 58, 0 ), - V( 58, 0x0160, 56, 59, 0 ), - V( 59, 0x0125, 57, 60, 0 ), - V( 60, 0x00f6, 58, 61, 0 ), - V( 61, 0x00cb, 59, 62, 0 ), - V( 62, 0x00ab, 61, 63, 0 ), - V( 63, 0x008f, 61, 32, 0 ), - V( 64, 0x5b12, 65, 65, 1 ), - V( 65, 0x4d04, 80, 66, 0 ), - V( 66, 0x412c, 81, 67, 0 ), - V( 67, 0x37d8, 82, 68, 0 ), - V( 68, 0x2fe8, 83, 69, 0 ), - V( 69, 0x293c, 84, 70, 0 ), - V( 70, 0x2379, 86, 71, 0 ), - V( 71, 0x1edf, 87, 72, 0 ), - V( 72, 0x1aa9, 87, 73, 0 ), - V( 73, 0x174e, 72, 74, 0 ), - V( 74, 0x1424, 72, 75, 0 ), - V( 75, 0x119c, 74, 76, 0 ), - V( 76, 0x0f6b, 74, 77, 0 ), - V( 77, 0x0d51, 75, 78, 0 ), - V( 78, 0x0bb6, 77, 79, 0 ), - V( 79, 0x0a40, 77, 48, 0 ), - V( 80, 0x5832, 80, 81, 1 ), - V( 81, 0x4d1c, 88, 82, 0 ), - V( 82, 0x438e, 89, 83, 0 ), - V( 83, 0x3bdd, 90, 84, 0 ), - V( 84, 0x34ee, 91, 85, 0 ), - V( 85, 0x2eae, 92, 86, 0 ), - V( 86, 0x299a, 93, 87, 0 ), - V( 87, 0x2516, 86, 71, 0 ), - V( 88, 0x5570, 88, 89, 1 ), - V( 89, 0x4ca9, 95, 90, 0 ), - V( 90, 0x44d9, 96, 91, 0 ), - V( 91, 0x3e22, 97, 92, 0 ), - V( 92, 0x3824, 99, 93, 0 ), - V( 93, 0x32b4, 99, 94, 0 ), - V( 94, 0x2e17, 93, 86, 0 ), - V( 95, 0x56a8, 95, 96, 1 ), - V( 96, 0x4f46, 101, 97, 0 ), - V( 97, 0x47e5, 102, 98, 0 ), - V( 98, 0x41cf, 103, 99, 0 ), - V( 99, 0x3c3d, 104, 100, 0 ), - V( 100, 0x375e, 99, 93, 0 ), - V( 101, 0x5231, 105, 102, 0 ), - V( 102, 0x4c0f, 106, 103, 0 ), - V( 103, 0x4639, 107, 104, 0 ), - V( 104, 0x415e, 103, 99, 0 ), - V( 105, 0x5627, 105, 106, 1 ), - V( 106, 0x50e7, 108, 107, 0 ), - V( 107, 0x4b85, 109, 103, 0 ), - V( 108, 0x5597, 110, 109, 0 ), - V( 109, 0x504f, 111, 107, 0 ), - V( 110, 0x5a10, 110, 111, 1 ), - V( 111, 0x5522, 112, 109, 0 ), - V( 112, 0x59eb, 112, 111, 1 ), -/* - * This last entry is used for fixed probability estimate of 0.5 - * as suggested in Section 10.3 Table 5 of ITU-T Rec. T.851. - */ - V( 113, 0x5a1d, 113, 113, 0 ) -}; diff --git a/libraries/jpeg/jcomapi.c b/libraries/jpeg/jcomapi.c deleted file mode 100644 index 9b1fa7568..000000000 --- a/libraries/jpeg/jcomapi.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * jcomapi.c - * - * Copyright (C) 1994-1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains application interface routines that are used for both - * compression and decompression. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * Abort processing of a JPEG compression or decompression operation, - * but don't destroy the object itself. - * - * For this, we merely clean up all the nonpermanent memory pools. - * Note that temp files (virtual arrays) are not allowed to belong to - * the permanent pool, so we will be able to close all temp files here. - * Closing a data source or destination, if necessary, is the application's - * responsibility. - */ - -GLOBAL(void) -jpeg_abort (j_common_ptr cinfo) -{ - int pool; - - /* Do nothing if called on a not-initialized or destroyed JPEG object. */ - if (cinfo->mem == NULL) - return; - - /* Releasing pools in reverse order might help avoid fragmentation - * with some (brain-damaged) malloc libraries. - */ - for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) { - (*cinfo->mem->free_pool) (cinfo, pool); - } - - /* Reset overall state for possible reuse of object */ - if (cinfo->is_decompressor) { - cinfo->global_state = DSTATE_START; - /* Try to keep application from accessing now-deleted marker list. - * A bit kludgy to do it here, but this is the most central place. - */ - ((j_decompress_ptr) cinfo)->marker_list = NULL; - } else { - cinfo->global_state = CSTATE_START; - } -} - - -/* - * Destruction of a JPEG object. - * - * Everything gets deallocated except the master jpeg_compress_struct itself - * and the error manager struct. Both of these are supplied by the application - * and must be freed, if necessary, by the application. (Often they are on - * the stack and so don't need to be freed anyway.) - * Closing a data source or destination, if necessary, is the application's - * responsibility. - */ - -GLOBAL(void) -jpeg_destroy (j_common_ptr cinfo) -{ - /* We need only tell the memory manager to release everything. */ - /* NB: mem pointer is NULL if memory mgr failed to initialize. */ - if (cinfo->mem != NULL) - (*cinfo->mem->self_destruct) (cinfo); - cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */ - cinfo->global_state = 0; /* mark it destroyed */ -} - - -/* - * Convenience routines for allocating quantization and Huffman tables. - * (Would jutils.c be a more reasonable place to put these?) - */ - -GLOBAL(JQUANT_TBL *) -jpeg_alloc_quant_table (j_common_ptr cinfo) -{ - JQUANT_TBL *tbl; - - tbl = (JQUANT_TBL *) - (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL)); - tbl->sent_table = FALSE; /* make sure this is false in any new table */ - return tbl; -} - - -GLOBAL(JHUFF_TBL *) -jpeg_alloc_huff_table (j_common_ptr cinfo) -{ - JHUFF_TBL *tbl; - - tbl = (JHUFF_TBL *) - (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL)); - tbl->sent_table = FALSE; /* make sure this is false in any new table */ - return tbl; -} diff --git a/libraries/jpeg/jconfig.h b/libraries/jpeg/jconfig.h deleted file mode 100644 index 347e6cb0f..000000000 --- a/libraries/jpeg/jconfig.h +++ /dev/null @@ -1,32 +0,0 @@ -/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */ -/* see jconfig.doc for explanations */ - -#define HAVE_PROTOTYPES -#define HAVE_UNSIGNED_CHAR -#define HAVE_UNSIGNED_SHORT -/* #define void char */ -/* #define const */ -#undef CHAR_IS_UNSIGNED -#define HAVE_STDDEF_H -#define HAVE_STDLIB_H -#undef NEED_BSD_STRINGS -#undef NEED_SYS_TYPES_H - -/* Define "boolean" as unsigned char, not int, per Windows custom */ -#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ -typedef unsigned char boolean; -#endif -#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -#ifdef JPEG_INTERNALS - -#undef RIGHT_SHIFT_IS_UNSIGNED - -#endif /* JPEG_INTERNALS */ diff --git a/libraries/jpeg/jdapimin.c b/libraries/jpeg/jdapimin.c deleted file mode 100644 index a6e0dd9fb..000000000 --- a/libraries/jpeg/jdapimin.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * jdapimin.c - * - * Copyright (C) 1994-1998, Thomas G. Lane. - * Modified 2009-2013 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains application interface code for the decompression half - * of the JPEG library. These are the "minimum" API routines that may be - * needed in either the normal full-decompression case or the - * transcoding-only case. - * - * Most of the routines intended to be called directly by an application - * are in this file or in jdapistd.c. But also see jcomapi.c for routines - * shared by compression and decompression, and jdtrans.c for the transcoding - * case. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * Initialization of a JPEG decompression object. - * The error manager must already be set up (in case memory manager fails). - */ - -GLOBAL(void) -jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize) -{ - int i; - - /* Guard against version mismatches between library and caller. */ - cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ - if (version != JPEG_LIB_VERSION) - ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); - if (structsize != SIZEOF(struct jpeg_decompress_struct)) - ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, - (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize); - - /* For debugging purposes, we zero the whole master structure. - * But the application has already set the err pointer, and may have set - * client_data, so we have to save and restore those fields. - * Note: if application hasn't set client_data, tools like Purify may - * complain here. - */ - { - struct jpeg_error_mgr * err = cinfo->err; - void * client_data = cinfo->client_data; /* ignore Purify complaint here */ - MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct)); - cinfo->err = err; - cinfo->client_data = client_data; - } - cinfo->is_decompressor = TRUE; - - /* Initialize a memory manager instance for this object */ - jinit_memory_mgr((j_common_ptr) cinfo); - - /* Zero out pointers to permanent structures. */ - cinfo->progress = NULL; - cinfo->src = NULL; - - for (i = 0; i < NUM_QUANT_TBLS; i++) - cinfo->quant_tbl_ptrs[i] = NULL; - - for (i = 0; i < NUM_HUFF_TBLS; i++) { - cinfo->dc_huff_tbl_ptrs[i] = NULL; - cinfo->ac_huff_tbl_ptrs[i] = NULL; - } - - /* Initialize marker processor so application can override methods - * for COM, APPn markers before calling jpeg_read_header. - */ - cinfo->marker_list = NULL; - jinit_marker_reader(cinfo); - - /* And initialize the overall input controller. */ - jinit_input_controller(cinfo); - - /* OK, I'm ready */ - cinfo->global_state = DSTATE_START; -} - - -/* - * Destruction of a JPEG decompression object - */ - -GLOBAL(void) -jpeg_destroy_decompress (j_decompress_ptr cinfo) -{ - jpeg_destroy((j_common_ptr) cinfo); /* use common routine */ -} - - -/* - * Abort processing of a JPEG decompression operation, - * but don't destroy the object itself. - */ - -GLOBAL(void) -jpeg_abort_decompress (j_decompress_ptr cinfo) -{ - jpeg_abort((j_common_ptr) cinfo); /* use common routine */ -} - - -/* - * Set default decompression parameters. - */ - -LOCAL(void) -default_decompress_parms (j_decompress_ptr cinfo) -{ - int cid0, cid1, cid2; - - /* Guess the input colorspace, and set output colorspace accordingly. */ - /* Note application may override our guesses. */ - switch (cinfo->num_components) { - case 1: - cinfo->jpeg_color_space = JCS_GRAYSCALE; - cinfo->out_color_space = JCS_GRAYSCALE; - break; - - case 3: - cid0 = cinfo->comp_info[0].component_id; - cid1 = cinfo->comp_info[1].component_id; - cid2 = cinfo->comp_info[2].component_id; - - /* First try to guess from the component IDs */ - if (cid0 == 0x01 && cid1 == 0x02 && cid2 == 0x03) - cinfo->jpeg_color_space = JCS_YCbCr; - else if (cid0 == 0x01 && cid1 == 0x22 && cid2 == 0x23) - cinfo->jpeg_color_space = JCS_BG_YCC; - else if (cid0 == 0x52 && cid1 == 0x47 && cid2 == 0x42) - cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ - else if (cid0 == 0x72 && cid1 == 0x67 && cid2 == 0x62) - cinfo->jpeg_color_space = JCS_BG_RGB; /* ASCII 'r', 'g', 'b' */ - else if (cinfo->saw_JFIF_marker) - cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ - else if (cinfo->saw_Adobe_marker) { - switch (cinfo->Adobe_transform) { - case 0: - cinfo->jpeg_color_space = JCS_RGB; - break; - case 1: - cinfo->jpeg_color_space = JCS_YCbCr; - break; - default: - WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); - cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ - break; - } - } else { - TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); - cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ - } - /* Always guess RGB is proper output colorspace. */ - cinfo->out_color_space = JCS_RGB; - break; - - case 4: - if (cinfo->saw_Adobe_marker) { - switch (cinfo->Adobe_transform) { - case 0: - cinfo->jpeg_color_space = JCS_CMYK; - break; - case 2: - cinfo->jpeg_color_space = JCS_YCCK; - break; - default: - WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); - cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */ - break; - } - } else { - /* No special markers, assume straight CMYK. */ - cinfo->jpeg_color_space = JCS_CMYK; - } - cinfo->out_color_space = JCS_CMYK; - break; - - default: - cinfo->jpeg_color_space = JCS_UNKNOWN; - cinfo->out_color_space = JCS_UNKNOWN; - break; - } - - /* Set defaults for other decompression parameters. */ - cinfo->scale_num = cinfo->block_size; /* 1:1 scaling */ - cinfo->scale_denom = cinfo->block_size; - cinfo->output_gamma = 1.0; - cinfo->buffered_image = FALSE; - cinfo->raw_data_out = FALSE; - cinfo->dct_method = JDCT_DEFAULT; - cinfo->do_fancy_upsampling = TRUE; - cinfo->do_block_smoothing = TRUE; - cinfo->quantize_colors = FALSE; - /* We set these in case application only sets quantize_colors. */ - cinfo->dither_mode = JDITHER_FS; -#ifdef QUANT_2PASS_SUPPORTED - cinfo->two_pass_quantize = TRUE; -#else - cinfo->two_pass_quantize = FALSE; -#endif - cinfo->desired_number_of_colors = 256; - cinfo->colormap = NULL; - /* Initialize for no mode change in buffered-image mode. */ - cinfo->enable_1pass_quant = FALSE; - cinfo->enable_external_quant = FALSE; - cinfo->enable_2pass_quant = FALSE; -} - - -/* - * Decompression startup: read start of JPEG datastream to see what's there. - * Need only initialize JPEG object and supply a data source before calling. - * - * This routine will read as far as the first SOS marker (ie, actual start of - * compressed data), and will save all tables and parameters in the JPEG - * object. It will also initialize the decompression parameters to default - * values, and finally return JPEG_HEADER_OK. On return, the application may - * adjust the decompression parameters and then call jpeg_start_decompress. - * (Or, if the application only wanted to determine the image parameters, - * the data need not be decompressed. In that case, call jpeg_abort or - * jpeg_destroy to release any temporary space.) - * If an abbreviated (tables only) datastream is presented, the routine will - * return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then - * re-use the JPEG object to read the abbreviated image datastream(s). - * It is unnecessary (but OK) to call jpeg_abort in this case. - * The JPEG_SUSPENDED return code only occurs if the data source module - * requests suspension of the decompressor. In this case the application - * should load more source data and then re-call jpeg_read_header to resume - * processing. - * If a non-suspending data source is used and require_image is TRUE, then the - * return code need not be inspected since only JPEG_HEADER_OK is possible. - * - * This routine is now just a front end to jpeg_consume_input, with some - * extra error checking. - */ - -GLOBAL(int) -jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) -{ - int retcode; - - if (cinfo->global_state != DSTATE_START && - cinfo->global_state != DSTATE_INHEADER) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - retcode = jpeg_consume_input(cinfo); - - switch (retcode) { - case JPEG_REACHED_SOS: - retcode = JPEG_HEADER_OK; - break; - case JPEG_REACHED_EOI: - if (require_image) /* Complain if application wanted an image */ - ERREXIT(cinfo, JERR_NO_IMAGE); - /* Reset to start state; it would be safer to require the application to - * call jpeg_abort, but we can't change it now for compatibility reasons. - * A side effect is to free any temporary memory (there shouldn't be any). - */ - jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */ - retcode = JPEG_HEADER_TABLES_ONLY; - break; - case JPEG_SUSPENDED: - /* no work */ - break; - } - - return retcode; -} - - -/* - * Consume data in advance of what the decompressor requires. - * This can be called at any time once the decompressor object has - * been created and a data source has been set up. - * - * This routine is essentially a state machine that handles a couple - * of critical state-transition actions, namely initial setup and - * transition from header scanning to ready-for-start_decompress. - * All the actual input is done via the input controller's consume_input - * method. - */ - -GLOBAL(int) -jpeg_consume_input (j_decompress_ptr cinfo) -{ - int retcode = JPEG_SUSPENDED; - - /* NB: every possible DSTATE value should be listed in this switch */ - switch (cinfo->global_state) { - case DSTATE_START: - /* Start-of-datastream actions: reset appropriate modules */ - (*cinfo->inputctl->reset_input_controller) (cinfo); - /* Initialize application's data source module */ - (*cinfo->src->init_source) (cinfo); - cinfo->global_state = DSTATE_INHEADER; - /*FALLTHROUGH*/ - case DSTATE_INHEADER: - retcode = (*cinfo->inputctl->consume_input) (cinfo); - if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */ - /* Set up default parameters based on header data */ - default_decompress_parms(cinfo); - /* Set global state: ready for start_decompress */ - cinfo->global_state = DSTATE_READY; - } - break; - case DSTATE_READY: - /* Can't advance past first SOS until start_decompress is called */ - retcode = JPEG_REACHED_SOS; - break; - case DSTATE_PRELOAD: - case DSTATE_PRESCAN: - case DSTATE_SCANNING: - case DSTATE_RAW_OK: - case DSTATE_BUFIMAGE: - case DSTATE_BUFPOST: - case DSTATE_STOPPING: - retcode = (*cinfo->inputctl->consume_input) (cinfo); - break; - default: - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - } - return retcode; -} - - -/* - * Have we finished reading the input file? - */ - -GLOBAL(boolean) -jpeg_input_complete (j_decompress_ptr cinfo) -{ - /* Check for valid jpeg object */ - if (cinfo->global_state < DSTATE_START || - cinfo->global_state > DSTATE_STOPPING) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - return cinfo->inputctl->eoi_reached; -} - - -/* - * Is there more than one scan? - */ - -GLOBAL(boolean) -jpeg_has_multiple_scans (j_decompress_ptr cinfo) -{ - /* Only valid after jpeg_read_header completes */ - if (cinfo->global_state < DSTATE_READY || - cinfo->global_state > DSTATE_STOPPING) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - return cinfo->inputctl->has_multiple_scans; -} - - -/* - * Finish JPEG decompression. - * - * This will normally just verify the file trailer and release temp storage. - * - * Returns FALSE if suspended. The return value need be inspected only if - * a suspending data source is used. - */ - -GLOBAL(boolean) -jpeg_finish_decompress (j_decompress_ptr cinfo) -{ - if ((cinfo->global_state == DSTATE_SCANNING || - cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) { - /* Terminate final pass of non-buffered mode */ - if (cinfo->output_scanline < cinfo->output_height) - ERREXIT(cinfo, JERR_TOO_LITTLE_DATA); - (*cinfo->master->finish_output_pass) (cinfo); - cinfo->global_state = DSTATE_STOPPING; - } else if (cinfo->global_state == DSTATE_BUFIMAGE) { - /* Finishing after a buffered-image operation */ - cinfo->global_state = DSTATE_STOPPING; - } else if (cinfo->global_state != DSTATE_STOPPING) { - /* STOPPING = repeat call after a suspension, anything else is error */ - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - } - /* Read until EOI */ - while (! cinfo->inputctl->eoi_reached) { - if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) - return FALSE; /* Suspend, come back later */ - } - /* Do final cleanup */ - (*cinfo->src->term_source) (cinfo); - /* We can use jpeg_abort to release memory and reset global_state */ - jpeg_abort((j_common_ptr) cinfo); - return TRUE; -} diff --git a/libraries/jpeg/jdapistd.c b/libraries/jpeg/jdapistd.c deleted file mode 100644 index 7f3a78b25..000000000 --- a/libraries/jpeg/jdapistd.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * jdapistd.c - * - * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2002-2013 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains application interface code for the decompression half - * of the JPEG library. These are the "standard" API routines that are - * used in the normal full-decompression case. They are not used by a - * transcoding-only application. Note that if an application links in - * jpeg_start_decompress, it will end up linking in the entire decompressor. - * We thus must separate this file from jdapimin.c to avoid linking the - * whole decompression library into a transcoder. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Forward declarations */ -LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo)); - - -/* - * Decompression initialization. - * jpeg_read_header must be completed before calling this. - * - * If a multipass operating mode was selected, this will do all but the - * last pass, and thus may take a great deal of time. - * - * Returns FALSE if suspended. The return value need be inspected only if - * a suspending data source is used. - */ - -GLOBAL(boolean) -jpeg_start_decompress (j_decompress_ptr cinfo) -{ - if (cinfo->global_state == DSTATE_READY) { - /* First call: initialize master control, select active modules */ - jinit_master_decompress(cinfo); - if (cinfo->buffered_image) { - /* No more work here; expecting jpeg_start_output next */ - cinfo->global_state = DSTATE_BUFIMAGE; - return TRUE; - } - cinfo->global_state = DSTATE_PRELOAD; - } - if (cinfo->global_state == DSTATE_PRELOAD) { - /* If file has multiple scans, absorb them all into the coef buffer */ - if (cinfo->inputctl->has_multiple_scans) { -#ifdef D_MULTISCAN_FILES_SUPPORTED - for (;;) { - int retcode; - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - /* Absorb some more input */ - retcode = (*cinfo->inputctl->consume_input) (cinfo); - if (retcode == JPEG_SUSPENDED) - return FALSE; - if (retcode == JPEG_REACHED_EOI) - break; - /* Advance progress counter if appropriate */ - if (cinfo->progress != NULL && - (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { - if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { - /* jdmaster underestimated number of scans; ratchet up one scan */ - cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; - } - } - } -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif /* D_MULTISCAN_FILES_SUPPORTED */ - } - cinfo->output_scan_number = cinfo->input_scan_number; - } else if (cinfo->global_state != DSTATE_PRESCAN) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - /* Perform any dummy output passes, and set up for the final pass */ - return output_pass_setup(cinfo); -} - - -/* - * Set up for an output pass, and perform any dummy pass(es) needed. - * Common subroutine for jpeg_start_decompress and jpeg_start_output. - * Entry: global_state = DSTATE_PRESCAN only if previously suspended. - * Exit: If done, returns TRUE and sets global_state for proper output mode. - * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN. - */ - -LOCAL(boolean) -output_pass_setup (j_decompress_ptr cinfo) -{ - if (cinfo->global_state != DSTATE_PRESCAN) { - /* First call: do pass setup */ - (*cinfo->master->prepare_for_output_pass) (cinfo); - cinfo->output_scanline = 0; - cinfo->global_state = DSTATE_PRESCAN; - } - /* Loop over any required dummy passes */ - while (cinfo->master->is_dummy_pass) { -#ifdef QUANT_2PASS_SUPPORTED - /* Crank through the dummy pass */ - while (cinfo->output_scanline < cinfo->output_height) { - JDIMENSION last_scanline; - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) cinfo->output_scanline; - cinfo->progress->pass_limit = (long) cinfo->output_height; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - } - /* Process some data */ - last_scanline = cinfo->output_scanline; - (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL, - &cinfo->output_scanline, (JDIMENSION) 0); - if (cinfo->output_scanline == last_scanline) - return FALSE; /* No progress made, must suspend */ - } - /* Finish up dummy pass, and set up for another one */ - (*cinfo->master->finish_output_pass) (cinfo); - (*cinfo->master->prepare_for_output_pass) (cinfo); - cinfo->output_scanline = 0; -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif /* QUANT_2PASS_SUPPORTED */ - } - /* Ready for application to drive output pass through - * jpeg_read_scanlines or jpeg_read_raw_data. - */ - cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING; - return TRUE; -} - - -/* - * Read some scanlines of data from the JPEG decompressor. - * - * The return value will be the number of lines actually read. - * This may be less than the number requested in several cases, - * including bottom of image, data source suspension, and operating - * modes that emit multiple scanlines at a time. - * - * Note: we warn about excess calls to jpeg_read_scanlines() since - * this likely signals an application programmer error. However, - * an oversize buffer (max_lines > scanlines remaining) is not an error. - */ - -GLOBAL(JDIMENSION) -jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, - JDIMENSION max_lines) -{ - JDIMENSION row_ctr; - - if (cinfo->global_state != DSTATE_SCANNING) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - if (cinfo->output_scanline >= cinfo->output_height) { - WARNMS(cinfo, JWRN_TOO_MUCH_DATA); - return 0; - } - - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) cinfo->output_scanline; - cinfo->progress->pass_limit = (long) cinfo->output_height; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - } - - /* Process some data */ - row_ctr = 0; - (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines); - cinfo->output_scanline += row_ctr; - return row_ctr; -} - - -/* - * Alternate entry point to read raw data. - * Processes exactly one iMCU row per call, unless suspended. - */ - -GLOBAL(JDIMENSION) -jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, - JDIMENSION max_lines) -{ - JDIMENSION lines_per_iMCU_row; - - if (cinfo->global_state != DSTATE_RAW_OK) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - if (cinfo->output_scanline >= cinfo->output_height) { - WARNMS(cinfo, JWRN_TOO_MUCH_DATA); - return 0; - } - - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) cinfo->output_scanline; - cinfo->progress->pass_limit = (long) cinfo->output_height; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - } - - /* Verify that at least one iMCU row can be returned. */ - lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_v_scaled_size; - if (max_lines < lines_per_iMCU_row) - ERREXIT(cinfo, JERR_BUFFER_SIZE); - - /* Decompress directly into user's buffer. */ - if (! (*cinfo->coef->decompress_data) (cinfo, data)) - return 0; /* suspension forced, can do nothing more */ - - /* OK, we processed one iMCU row. */ - cinfo->output_scanline += lines_per_iMCU_row; - return lines_per_iMCU_row; -} - - -/* Additional entry points for buffered-image mode. */ - -#ifdef D_MULTISCAN_FILES_SUPPORTED - -/* - * Initialize for an output pass in buffered-image mode. - */ - -GLOBAL(boolean) -jpeg_start_output (j_decompress_ptr cinfo, int scan_number) -{ - if (cinfo->global_state != DSTATE_BUFIMAGE && - cinfo->global_state != DSTATE_PRESCAN) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - /* Limit scan number to valid range */ - if (scan_number <= 0) - scan_number = 1; - if (cinfo->inputctl->eoi_reached && - scan_number > cinfo->input_scan_number) - scan_number = cinfo->input_scan_number; - cinfo->output_scan_number = scan_number; - /* Perform any dummy output passes, and set up for the real pass */ - return output_pass_setup(cinfo); -} - - -/* - * Finish up after an output pass in buffered-image mode. - * - * Returns FALSE if suspended. The return value need be inspected only if - * a suspending data source is used. - */ - -GLOBAL(boolean) -jpeg_finish_output (j_decompress_ptr cinfo) -{ - if ((cinfo->global_state == DSTATE_SCANNING || - cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) { - /* Terminate this pass. */ - /* We do not require the whole pass to have been completed. */ - (*cinfo->master->finish_output_pass) (cinfo); - cinfo->global_state = DSTATE_BUFPOST; - } else if (cinfo->global_state != DSTATE_BUFPOST) { - /* BUFPOST = repeat call after a suspension, anything else is error */ - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - } - /* Read markers looking for SOS or EOI */ - while (cinfo->input_scan_number <= cinfo->output_scan_number && - ! cinfo->inputctl->eoi_reached) { - if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) - return FALSE; /* Suspend, come back later */ - } - cinfo->global_state = DSTATE_BUFIMAGE; - return TRUE; -} - -#endif /* D_MULTISCAN_FILES_SUPPORTED */ diff --git a/libraries/jpeg/jdarith.c b/libraries/jpeg/jdarith.c deleted file mode 100644 index 5533c0739..000000000 --- a/libraries/jpeg/jdarith.c +++ /dev/null @@ -1,796 +0,0 @@ -/* - * jdarith.c - * - * Developed 1997-2015 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains portable arithmetic entropy decoding routines for JPEG - * (implementing the ISO/IEC IS 10918-1 and CCITT Recommendation ITU-T T.81). - * - * Both sequential and progressive modes are supported in this single module. - * - * Suspension is not currently supported in this module. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Expanded entropy decoder object for arithmetic decoding. */ - -typedef struct { - struct jpeg_entropy_decoder pub; /* public fields */ - - INT32 c; /* C register, base of coding interval + input bit buffer */ - INT32 a; /* A register, normalized size of coding interval */ - int ct; /* bit shift counter, # of bits left in bit buffer part of C */ - /* init: ct = -16 */ - /* run: ct = 0..7 */ - /* error: ct = -1 */ - int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ - int dc_context[MAX_COMPS_IN_SCAN]; /* context index for DC conditioning */ - - unsigned int restarts_to_go; /* MCUs left in this restart interval */ - - /* Pointers to statistics areas (these workspaces have image lifespan) */ - unsigned char * dc_stats[NUM_ARITH_TBLS]; - unsigned char * ac_stats[NUM_ARITH_TBLS]; - - /* Statistics bin for coding with fixed probability 0.5 */ - unsigned char fixed_bin[4]; -} arith_entropy_decoder; - -typedef arith_entropy_decoder * arith_entropy_ptr; - -/* The following two definitions specify the allocation chunk size - * for the statistics area. - * According to sections F.1.4.4.1.3 and F.1.4.4.2, we need at least - * 49 statistics bins for DC, and 245 statistics bins for AC coding. - * - * We use a compact representation with 1 byte per statistics bin, - * thus the numbers directly represent byte sizes. - * This 1 byte per statistics bin contains the meaning of the MPS - * (more probable symbol) in the highest bit (mask 0x80), and the - * index into the probability estimation state machine table - * in the lower bits (mask 0x7F). - */ - -#define DC_STAT_BINS 64 -#define AC_STAT_BINS 256 - - -LOCAL(int) -get_byte (j_decompress_ptr cinfo) -/* Read next input byte; we do not support suspension in this module. */ -{ - struct jpeg_source_mgr * src = cinfo->src; - - if (src->bytes_in_buffer == 0) - if (! (*src->fill_input_buffer) (cinfo)) - ERREXIT(cinfo, JERR_CANT_SUSPEND); - src->bytes_in_buffer--; - return GETJOCTET(*src->next_input_byte++); -} - - -/* - * The core arithmetic decoding routine (common in JPEG and JBIG). - * This needs to go as fast as possible. - * Machine-dependent optimization facilities - * are not utilized in this portable implementation. - * However, this code should be fairly efficient and - * may be a good base for further optimizations anyway. - * - * Return value is 0 or 1 (binary decision). - * - * Note: I've changed the handling of the code base & bit - * buffer register C compared to other implementations - * based on the standards layout & procedures. - * While it also contains both the actual base of the - * coding interval (16 bits) and the next-bits buffer, - * the cut-point between these two parts is floating - * (instead of fixed) with the bit shift counter CT. - * Thus, we also need only one (variable instead of - * fixed size) shift for the LPS/MPS decision, and - * we can do away with any renormalization update - * of C (except for new data insertion, of course). - * - * I've also introduced a new scheme for accessing - * the probability estimation state machine table, - * derived from Markus Kuhn's JBIG implementation. - */ - -LOCAL(int) -arith_decode (j_decompress_ptr cinfo, unsigned char *st) -{ - register arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy; - register unsigned char nl, nm; - register INT32 qe, temp; - register int sv, data; - - /* Renormalization & data input per section D.2.6 */ - while (e->a < 0x8000L) { - if (--e->ct < 0) { - /* Need to fetch next data byte */ - if (cinfo->unread_marker) - data = 0; /* stuff zero data */ - else { - data = get_byte(cinfo); /* read next input byte */ - if (data == 0xFF) { /* zero stuff or marker code */ - do data = get_byte(cinfo); - while (data == 0xFF); /* swallow extra 0xFF bytes */ - if (data == 0) - data = 0xFF; /* discard stuffed zero byte */ - else { - /* Note: Different from the Huffman decoder, hitting - * a marker while processing the compressed data - * segment is legal in arithmetic coding. - * The convention is to supply zero data - * then until decoding is complete. - */ - cinfo->unread_marker = data; - data = 0; - } - } - } - e->c = (e->c << 8) | data; /* insert data into C register */ - if ((e->ct += 8) < 0) /* update bit shift counter */ - /* Need more initial bytes */ - if (++e->ct == 0) - /* Got 2 initial bytes -> re-init A and exit loop */ - e->a = 0x8000L; /* => e->a = 0x10000L after loop exit */ - } - e->a <<= 1; - } - - /* Fetch values from our compact representation of Table D.3(D.2): - * Qe values and probability estimation state machine - */ - sv = *st; - qe = jpeg_aritab[sv & 0x7F]; /* => Qe_Value */ - nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */ - nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */ - - /* Decode & estimation procedures per sections D.2.4 & D.2.5 */ - temp = e->a - qe; - e->a = temp; - temp <<= e->ct; - if (e->c >= temp) { - e->c -= temp; - /* Conditional LPS (less probable symbol) exchange */ - if (e->a < qe) { - e->a = qe; - *st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */ - } else { - e->a = qe; - *st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */ - sv ^= 0x80; /* Exchange LPS/MPS */ - } - } else if (e->a < 0x8000L) { - /* Conditional MPS (more probable symbol) exchange */ - if (e->a < qe) { - *st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */ - sv ^= 0x80; /* Exchange LPS/MPS */ - } else { - *st = (sv & 0x80) ^ nm; /* Estimate_after_MPS */ - } - } - - return sv >> 7; -} - - -/* - * Check for a restart marker & resynchronize decoder. - */ - -LOCAL(void) -process_restart (j_decompress_ptr cinfo) -{ - arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; - int ci; - jpeg_component_info * compptr; - - /* Advance past the RSTn marker */ - if (! (*cinfo->marker->read_restart_marker) (cinfo)) - ERREXIT(cinfo, JERR_CANT_SUSPEND); - - /* Re-initialize statistics areas */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) { - MEMZERO(entropy->dc_stats[compptr->dc_tbl_no], DC_STAT_BINS); - /* Reset DC predictions to 0 */ - entropy->last_dc_val[ci] = 0; - entropy->dc_context[ci] = 0; - } - if ((! cinfo->progressive_mode && cinfo->lim_Se) || - (cinfo->progressive_mode && cinfo->Ss)) { - MEMZERO(entropy->ac_stats[compptr->ac_tbl_no], AC_STAT_BINS); - } - } - - /* Reset arithmetic decoding variables */ - entropy->c = 0; - entropy->a = 0; - entropy->ct = -16; /* force reading 2 initial bytes to fill C */ - - /* Reset restart counter */ - entropy->restarts_to_go = cinfo->restart_interval; -} - - -/* - * Arithmetic MCU decoding. - * Each of these routines decodes and returns one MCU's worth of - * arithmetic-compressed coefficients. - * The coefficients are reordered from zigzag order into natural array order, - * but are not dequantized. - * - * The i'th block of the MCU is stored into the block pointed to by - * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. - */ - -/* - * MCU decoding for DC initial scan (either spectral selection, - * or first pass of successive approximation). - */ - -METHODDEF(boolean) -decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; - JBLOCKROW block; - unsigned char *st; - int blkn, ci, tbl, sign; - int v, m; - - /* Process restart marker if needed */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - process_restart(cinfo); - entropy->restarts_to_go--; - } - - if (entropy->ct == -1) return TRUE; /* if error do nothing */ - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - block = MCU_data[blkn]; - ci = cinfo->MCU_membership[blkn]; - tbl = cinfo->cur_comp_info[ci]->dc_tbl_no; - - /* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */ - - /* Table F.4: Point to statistics bin S0 for DC coefficient coding */ - st = entropy->dc_stats[tbl] + entropy->dc_context[ci]; - - /* Figure F.19: Decode_DC_DIFF */ - if (arith_decode(cinfo, st) == 0) - entropy->dc_context[ci] = 0; - else { - /* Figure F.21: Decoding nonzero value v */ - /* Figure F.22: Decoding the sign of v */ - sign = arith_decode(cinfo, st + 1); - st += 2; st += sign; - /* Figure F.23: Decoding the magnitude category of v */ - if ((m = arith_decode(cinfo, st)) != 0) { - st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */ - while (arith_decode(cinfo, st)) { - if ((m <<= 1) == 0x8000) { - WARNMS(cinfo, JWRN_ARITH_BAD_CODE); - entropy->ct = -1; /* magnitude overflow */ - return TRUE; - } - st += 1; - } - } - /* Section F.1.4.4.1.2: Establish dc_context conditioning category */ - if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1)) - entropy->dc_context[ci] = 0; /* zero diff category */ - else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1)) - entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */ - else - entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */ - v = m; - /* Figure F.24: Decoding the magnitude bit pattern of v */ - st += 14; - while (m >>= 1) - if (arith_decode(cinfo, st)) v |= m; - v += 1; if (sign) v = -v; - entropy->last_dc_val[ci] += v; - } - - /* Scale and output the DC coefficient (assumes jpeg_natural_order[0]=0) */ - (*block)[0] = (JCOEF) (entropy->last_dc_val[ci] << cinfo->Al); - } - - return TRUE; -} - - -/* - * MCU decoding for AC initial scan (either spectral selection, - * or first pass of successive approximation). - */ - -METHODDEF(boolean) -decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; - JBLOCKROW block; - unsigned char *st; - int tbl, sign, k; - int v, m; - const int * natural_order; - - /* Process restart marker if needed */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - process_restart(cinfo); - entropy->restarts_to_go--; - } - - if (entropy->ct == -1) return TRUE; /* if error do nothing */ - - natural_order = cinfo->natural_order; - - /* There is always only one block per MCU */ - block = MCU_data[0]; - tbl = cinfo->cur_comp_info[0]->ac_tbl_no; - - /* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */ - - /* Figure F.20: Decode_AC_coefficients */ - k = cinfo->Ss - 1; - do { - st = entropy->ac_stats[tbl] + 3 * k; - if (arith_decode(cinfo, st)) break; /* EOB flag */ - for (;;) { - k++; - if (arith_decode(cinfo, st + 1)) break; - st += 3; - if (k >= cinfo->Se) { - WARNMS(cinfo, JWRN_ARITH_BAD_CODE); - entropy->ct = -1; /* spectral overflow */ - return TRUE; - } - } - /* Figure F.21: Decoding nonzero value v */ - /* Figure F.22: Decoding the sign of v */ - sign = arith_decode(cinfo, entropy->fixed_bin); - st += 2; - /* Figure F.23: Decoding the magnitude category of v */ - if ((m = arith_decode(cinfo, st)) != 0) { - if (arith_decode(cinfo, st)) { - m <<= 1; - st = entropy->ac_stats[tbl] + - (k <= cinfo->arith_ac_K[tbl] ? 189 : 217); - while (arith_decode(cinfo, st)) { - if ((m <<= 1) == 0x8000) { - WARNMS(cinfo, JWRN_ARITH_BAD_CODE); - entropy->ct = -1; /* magnitude overflow */ - return TRUE; - } - st += 1; - } - } - } - v = m; - /* Figure F.24: Decoding the magnitude bit pattern of v */ - st += 14; - while (m >>= 1) - if (arith_decode(cinfo, st)) v |= m; - v += 1; if (sign) v = -v; - /* Scale and output coefficient in natural (dezigzagged) order */ - (*block)[natural_order[k]] = (JCOEF) (v << cinfo->Al); - } while (k < cinfo->Se); - - return TRUE; -} - - -/* - * MCU decoding for DC successive approximation refinement scan. - * Note: we assume such scans can be multi-component, - * although the spec is not very clear on the point. - */ - -METHODDEF(boolean) -decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; - unsigned char *st; - int p1, blkn; - - /* Process restart marker if needed */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - process_restart(cinfo); - entropy->restarts_to_go--; - } - - st = entropy->fixed_bin; /* use fixed probability estimation */ - p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - /* Encoded data is simply the next bit of the two's-complement DC value */ - if (arith_decode(cinfo, st)) - MCU_data[blkn][0][0] |= p1; - } - - return TRUE; -} - - -/* - * MCU decoding for AC successive approximation refinement scan. - */ - -METHODDEF(boolean) -decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; - JBLOCKROW block; - JCOEFPTR thiscoef; - unsigned char *st; - int tbl, k, kex; - int p1, m1; - const int * natural_order; - - /* Process restart marker if needed */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - process_restart(cinfo); - entropy->restarts_to_go--; - } - - if (entropy->ct == -1) return TRUE; /* if error do nothing */ - - natural_order = cinfo->natural_order; - - /* There is always only one block per MCU */ - block = MCU_data[0]; - tbl = cinfo->cur_comp_info[0]->ac_tbl_no; - - p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ - m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ - - /* Establish EOBx (previous stage end-of-block) index */ - kex = cinfo->Se; - do { - if ((*block)[natural_order[kex]]) break; - } while (--kex); - - k = cinfo->Ss - 1; - do { - st = entropy->ac_stats[tbl] + 3 * k; - if (k >= kex) - if (arith_decode(cinfo, st)) break; /* EOB flag */ - for (;;) { - thiscoef = *block + natural_order[++k]; - if (*thiscoef) { /* previously nonzero coef */ - if (arith_decode(cinfo, st + 2)) { - if (*thiscoef < 0) - *thiscoef += m1; - else - *thiscoef += p1; - } - break; - } - if (arith_decode(cinfo, st + 1)) { /* newly nonzero coef */ - if (arith_decode(cinfo, entropy->fixed_bin)) - *thiscoef = m1; - else - *thiscoef = p1; - break; - } - st += 3; - if (k >= cinfo->Se) { - WARNMS(cinfo, JWRN_ARITH_BAD_CODE); - entropy->ct = -1; /* spectral overflow */ - return TRUE; - } - } - } while (k < cinfo->Se); - - return TRUE; -} - - -/* - * Decode one MCU's worth of arithmetic-compressed coefficients. - */ - -METHODDEF(boolean) -decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; - jpeg_component_info * compptr; - JBLOCKROW block; - unsigned char *st; - int blkn, ci, tbl, sign, k; - int v, m; - const int * natural_order; - - /* Process restart marker if needed */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - process_restart(cinfo); - entropy->restarts_to_go--; - } - - if (entropy->ct == -1) return TRUE; /* if error do nothing */ - - natural_order = cinfo->natural_order; - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - block = MCU_data[blkn]; - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - - /* Sections F.2.4.1 & F.1.4.4.1: Decoding of DC coefficients */ - - tbl = compptr->dc_tbl_no; - - /* Table F.4: Point to statistics bin S0 for DC coefficient coding */ - st = entropy->dc_stats[tbl] + entropy->dc_context[ci]; - - /* Figure F.19: Decode_DC_DIFF */ - if (arith_decode(cinfo, st) == 0) - entropy->dc_context[ci] = 0; - else { - /* Figure F.21: Decoding nonzero value v */ - /* Figure F.22: Decoding the sign of v */ - sign = arith_decode(cinfo, st + 1); - st += 2; st += sign; - /* Figure F.23: Decoding the magnitude category of v */ - if ((m = arith_decode(cinfo, st)) != 0) { - st = entropy->dc_stats[tbl] + 20; /* Table F.4: X1 = 20 */ - while (arith_decode(cinfo, st)) { - if ((m <<= 1) == 0x8000) { - WARNMS(cinfo, JWRN_ARITH_BAD_CODE); - entropy->ct = -1; /* magnitude overflow */ - return TRUE; - } - st += 1; - } - } - /* Section F.1.4.4.1.2: Establish dc_context conditioning category */ - if (m < (int) ((1L << cinfo->arith_dc_L[tbl]) >> 1)) - entropy->dc_context[ci] = 0; /* zero diff category */ - else if (m > (int) ((1L << cinfo->arith_dc_U[tbl]) >> 1)) - entropy->dc_context[ci] = 12 + (sign * 4); /* large diff category */ - else - entropy->dc_context[ci] = 4 + (sign * 4); /* small diff category */ - v = m; - /* Figure F.24: Decoding the magnitude bit pattern of v */ - st += 14; - while (m >>= 1) - if (arith_decode(cinfo, st)) v |= m; - v += 1; if (sign) v = -v; - entropy->last_dc_val[ci] += v; - } - - (*block)[0] = (JCOEF) entropy->last_dc_val[ci]; - - /* Sections F.2.4.2 & F.1.4.4.2: Decoding of AC coefficients */ - - if (cinfo->lim_Se == 0) continue; - tbl = compptr->ac_tbl_no; - k = 0; - - /* Figure F.20: Decode_AC_coefficients */ - do { - st = entropy->ac_stats[tbl] + 3 * k; - if (arith_decode(cinfo, st)) break; /* EOB flag */ - for (;;) { - k++; - if (arith_decode(cinfo, st + 1)) break; - st += 3; - if (k >= cinfo->lim_Se) { - WARNMS(cinfo, JWRN_ARITH_BAD_CODE); - entropy->ct = -1; /* spectral overflow */ - return TRUE; - } - } - /* Figure F.21: Decoding nonzero value v */ - /* Figure F.22: Decoding the sign of v */ - sign = arith_decode(cinfo, entropy->fixed_bin); - st += 2; - /* Figure F.23: Decoding the magnitude category of v */ - if ((m = arith_decode(cinfo, st)) != 0) { - if (arith_decode(cinfo, st)) { - m <<= 1; - st = entropy->ac_stats[tbl] + - (k <= cinfo->arith_ac_K[tbl] ? 189 : 217); - while (arith_decode(cinfo, st)) { - if ((m <<= 1) == 0x8000) { - WARNMS(cinfo, JWRN_ARITH_BAD_CODE); - entropy->ct = -1; /* magnitude overflow */ - return TRUE; - } - st += 1; - } - } - } - v = m; - /* Figure F.24: Decoding the magnitude bit pattern of v */ - st += 14; - while (m >>= 1) - if (arith_decode(cinfo, st)) v |= m; - v += 1; if (sign) v = -v; - (*block)[natural_order[k]] = (JCOEF) v; - } while (k < cinfo->lim_Se); - } - - return TRUE; -} - - -/* - * Initialize for an arithmetic-compressed scan. - */ - -METHODDEF(void) -start_pass (j_decompress_ptr cinfo) -{ - arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy; - int ci, tbl; - jpeg_component_info * compptr; - - if (cinfo->progressive_mode) { - /* Validate progressive scan parameters */ - if (cinfo->Ss == 0) { - if (cinfo->Se != 0) - goto bad; - } else { - /* need not check Ss/Se < 0 since they came from unsigned bytes */ - if (cinfo->Se < cinfo->Ss || cinfo->Se > cinfo->lim_Se) - goto bad; - /* AC scans may have only one component */ - if (cinfo->comps_in_scan != 1) - goto bad; - } - if (cinfo->Ah != 0) { - /* Successive approximation refinement scan: must have Al = Ah-1. */ - if (cinfo->Ah-1 != cinfo->Al) - goto bad; - } - if (cinfo->Al > 13) { /* need not check for < 0 */ - bad: - ERREXIT4(cinfo, JERR_BAD_PROGRESSION, - cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); - } - /* Update progression status, and verify that scan order is legal. - * Note that inter-scan inconsistencies are treated as warnings - * not fatal errors ... not clear if this is right way to behave. - */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - int coefi, cindex = cinfo->cur_comp_info[ci]->component_index; - int *coef_bit_ptr = & cinfo->coef_bits[cindex][0]; - if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */ - WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0); - for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { - int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; - if (cinfo->Ah != expected) - WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi); - coef_bit_ptr[coefi] = cinfo->Al; - } - } - /* Select MCU decoding routine */ - if (cinfo->Ah == 0) { - if (cinfo->Ss == 0) - entropy->pub.decode_mcu = decode_mcu_DC_first; - else - entropy->pub.decode_mcu = decode_mcu_AC_first; - } else { - if (cinfo->Ss == 0) - entropy->pub.decode_mcu = decode_mcu_DC_refine; - else - entropy->pub.decode_mcu = decode_mcu_AC_refine; - } - } else { - /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. - * This ought to be an error condition, but we make it a warning. - */ - if (cinfo->Ss != 0 || cinfo->Ah != 0 || cinfo->Al != 0 || - (cinfo->Se < DCTSIZE2 && cinfo->Se != cinfo->lim_Se)) - WARNMS(cinfo, JWRN_NOT_SEQUENTIAL); - /* Select MCU decoding routine */ - entropy->pub.decode_mcu = decode_mcu; - } - - /* Allocate & initialize requested statistics areas */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - if (! cinfo->progressive_mode || (cinfo->Ss == 0 && cinfo->Ah == 0)) { - tbl = compptr->dc_tbl_no; - if (tbl < 0 || tbl >= NUM_ARITH_TBLS) - ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl); - if (entropy->dc_stats[tbl] == NULL) - entropy->dc_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, DC_STAT_BINS); - MEMZERO(entropy->dc_stats[tbl], DC_STAT_BINS); - /* Initialize DC predictions to 0 */ - entropy->last_dc_val[ci] = 0; - entropy->dc_context[ci] = 0; - } - if ((! cinfo->progressive_mode && cinfo->lim_Se) || - (cinfo->progressive_mode && cinfo->Ss)) { - tbl = compptr->ac_tbl_no; - if (tbl < 0 || tbl >= NUM_ARITH_TBLS) - ERREXIT1(cinfo, JERR_NO_ARITH_TABLE, tbl); - if (entropy->ac_stats[tbl] == NULL) - entropy->ac_stats[tbl] = (unsigned char *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, AC_STAT_BINS); - MEMZERO(entropy->ac_stats[tbl], AC_STAT_BINS); - } - } - - /* Initialize arithmetic decoding variables */ - entropy->c = 0; - entropy->a = 0; - entropy->ct = -16; /* force reading 2 initial bytes to fill C */ - - /* Initialize restart counter */ - entropy->restarts_to_go = cinfo->restart_interval; -} - - -/* - * Finish up at the end of an arithmetic-compressed scan. - */ - -METHODDEF(void) -finish_pass (j_decompress_ptr cinfo) -{ - /* no work necessary here */ -} - - -/* - * Module initialization routine for arithmetic entropy decoding. - */ - -GLOBAL(void) -jinit_arith_decoder (j_decompress_ptr cinfo) -{ - arith_entropy_ptr entropy; - int i; - - entropy = (arith_entropy_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(arith_entropy_decoder)); - cinfo->entropy = &entropy->pub; - entropy->pub.start_pass = start_pass; - entropy->pub.finish_pass = finish_pass; - - /* Mark tables unallocated */ - for (i = 0; i < NUM_ARITH_TBLS; i++) { - entropy->dc_stats[i] = NULL; - entropy->ac_stats[i] = NULL; - } - - /* Initialize index for fixed probability estimation */ - entropy->fixed_bin[0] = 113; - - if (cinfo->progressive_mode) { - /* Create progression status table */ - int *coef_bit_ptr, ci; - cinfo->coef_bits = (int (*)[DCTSIZE2]) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components*DCTSIZE2*SIZEOF(int)); - coef_bit_ptr = & cinfo->coef_bits[0][0]; - for (ci = 0; ci < cinfo->num_components; ci++) - for (i = 0; i < DCTSIZE2; i++) - *coef_bit_ptr++ = -1; - } -} diff --git a/libraries/jpeg/jdatasrc.c b/libraries/jpeg/jdatasrc.c deleted file mode 100644 index 2a27cfed8..000000000 --- a/libraries/jpeg/jdatasrc.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * jdatasrc.c - * - * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2009-2015 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains decompression data source routines for the case of - * reading JPEG data from memory or from a file (or any stdio stream). - * While these routines are sufficient for most applications, - * some will want to use a different source manager. - * IMPORTANT: we assume that fread() will correctly transcribe an array of - * JOCTETs from 8-bit-wide elements on external storage. If char is wider - * than 8 bits on your machine, you may need to do some tweaking. - */ - -/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ -#include "jinclude.h" -#include "jpeglib.h" -#include "jerror.h" - - -/* Expanded data source object for stdio input */ - -typedef struct { - struct jpeg_source_mgr pub; /* public fields */ - - FILE * infile; /* source stream */ - JOCTET * buffer; /* start of buffer */ - boolean start_of_file; /* have we gotten any data yet? */ -} my_source_mgr; - -typedef my_source_mgr * my_src_ptr; - -#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ - - -/* - * Initialize source --- called by jpeg_read_header - * before any data is actually read. - */ - -METHODDEF(void) -init_source (j_decompress_ptr cinfo) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - - /* We reset the empty-input-file flag for each image, - * but we don't clear the input buffer. - * This is correct behavior for reading a series of images from one source. - */ - src->start_of_file = TRUE; -} - -METHODDEF(void) -init_mem_source (j_decompress_ptr cinfo) -{ - /* no work necessary here */ -} - - -/* - * Fill the input buffer --- called whenever buffer is emptied. - * - * In typical applications, this should read fresh data into the buffer - * (ignoring the current state of next_input_byte & bytes_in_buffer), - * reset the pointer & count to the start of the buffer, and return TRUE - * indicating that the buffer has been reloaded. It is not necessary to - * fill the buffer entirely, only to obtain at least one more byte. - * - * There is no such thing as an EOF return. If the end of the file has been - * reached, the routine has a choice of ERREXIT() or inserting fake data into - * the buffer. In most cases, generating a warning message and inserting a - * fake EOI marker is the best course of action --- this will allow the - * decompressor to output however much of the image is there. However, - * the resulting error message is misleading if the real problem is an empty - * input file, so we handle that case specially. - * - * In applications that need to be able to suspend compression due to input - * not being available yet, a FALSE return indicates that no more data can be - * obtained right now, but more may be forthcoming later. In this situation, - * the decompressor will return to its caller (with an indication of the - * number of scanlines it has read, if any). The application should resume - * decompression after it has loaded more data into the input buffer. Note - * that there are substantial restrictions on the use of suspension --- see - * the documentation. - * - * When suspending, the decompressor will back up to a convenient restart point - * (typically the start of the current MCU). next_input_byte & bytes_in_buffer - * indicate where the restart point will be if the current call returns FALSE. - * Data beyond this point must be rescanned after resumption, so move it to - * the front of the buffer rather than discarding it. - */ - -METHODDEF(boolean) -fill_input_buffer (j_decompress_ptr cinfo) -{ - my_src_ptr src = (my_src_ptr) cinfo->src; - size_t nbytes; - - nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE); - - if (nbytes <= 0) { - if (src->start_of_file) /* Treat empty input file as fatal error */ - ERREXIT(cinfo, JERR_INPUT_EMPTY); - WARNMS(cinfo, JWRN_JPEG_EOF); - /* Insert a fake EOI marker */ - src->buffer[0] = (JOCTET) 0xFF; - src->buffer[1] = (JOCTET) JPEG_EOI; - nbytes = 2; - } - - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = nbytes; - src->start_of_file = FALSE; - - return TRUE; -} - -METHODDEF(boolean) -fill_mem_input_buffer (j_decompress_ptr cinfo) -{ - static const JOCTET mybuffer[4] = { - (JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0 - }; - - /* The whole JPEG data is expected to reside in the supplied memory - * buffer, so any request for more data beyond the given buffer size - * is treated as an error. - */ - WARNMS(cinfo, JWRN_JPEG_EOF); - - /* Insert a fake EOI marker */ - - cinfo->src->next_input_byte = mybuffer; - cinfo->src->bytes_in_buffer = 2; - - return TRUE; -} - - -/* - * Skip data --- used to skip over a potentially large amount of - * uninteresting data (such as an APPn marker). - * - * Writers of suspendable-input applications must note that skip_input_data - * is not granted the right to give a suspension return. If the skip extends - * beyond the data currently in the buffer, the buffer can be marked empty so - * that the next read will cause a fill_input_buffer call that can suspend. - * Arranging for additional bytes to be discarded before reloading the input - * buffer is the application writer's problem. - */ - -METHODDEF(void) -skip_input_data (j_decompress_ptr cinfo, long num_bytes) -{ - struct jpeg_source_mgr * src = cinfo->src; - - /* Just a dumb implementation for now. Could use fseek() except - * it doesn't work on pipes. Not clear that being smart is worth - * any trouble anyway --- large skips are infrequent. - */ - if (num_bytes > 0) { - while (num_bytes > (long) src->bytes_in_buffer) { - num_bytes -= (long) src->bytes_in_buffer; - (void) (*src->fill_input_buffer) (cinfo); - /* note we assume that fill_input_buffer will never return FALSE, - * so suspension need not be handled. - */ - } - src->next_input_byte += (size_t) num_bytes; - src->bytes_in_buffer -= (size_t) num_bytes; - } -} - - -/* - * An additional method that can be provided by data source modules is the - * resync_to_restart method for error recovery in the presence of RST markers. - * For the moment, this source module just uses the default resync method - * provided by the JPEG library. That method assumes that no backtracking - * is possible. - */ - - -/* - * Terminate source --- called by jpeg_finish_decompress - * after all data has been read. Often a no-op. - * - * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding - * application must deal with any cleanup that should happen even - * for error exit. - */ - -METHODDEF(void) -term_source (j_decompress_ptr cinfo) -{ - /* no work necessary here */ -} - - -/* - * Prepare for input from a stdio stream. - * The caller must have already opened the stream, and is responsible - * for closing it after finishing decompression. - */ - -GLOBAL(void) -jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) -{ - my_src_ptr src; - - /* The source object and input buffer are made permanent so that a series - * of JPEG images can be read from the same file by calling jpeg_stdio_src - * only before the first one. (If we discarded the buffer at the end of - * one image, we'd likely lose the start of the next one.) - * This makes it unsafe to use this manager and a different source - * manager serially with the same JPEG object. Caveat programmer. - */ - if (cinfo->src == NULL) { /* first time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(my_source_mgr)); - src = (my_src_ptr) cinfo->src; - src->buffer = (JOCTET *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - INPUT_BUF_SIZE * SIZEOF(JOCTET)); - } - - src = (my_src_ptr) cinfo->src; - src->pub.init_source = init_source; - src->pub.fill_input_buffer = fill_input_buffer; - src->pub.skip_input_data = skip_input_data; - src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ - src->pub.term_source = term_source; - src->infile = infile; - src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ - src->pub.next_input_byte = NULL; /* until buffer loaded */ -} - - -/* - * Prepare for input from a supplied memory buffer. - * The buffer must contain the whole JPEG data. - */ - -GLOBAL(void) -jpeg_mem_src (j_decompress_ptr cinfo, - const unsigned char * inbuffer, unsigned long insize) -{ - struct jpeg_source_mgr * src; - - if (inbuffer == NULL || insize == 0) /* Treat empty input as fatal error */ - ERREXIT(cinfo, JERR_INPUT_EMPTY); - - /* The source object is made permanent so that a series of JPEG images - * can be read from the same buffer by calling jpeg_mem_src only before - * the first one. - */ - if (cinfo->src == NULL) { /* first time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(struct jpeg_source_mgr)); - } - - src = cinfo->src; - src->init_source = init_mem_source; - src->fill_input_buffer = fill_mem_input_buffer; - src->skip_input_data = skip_input_data; - src->resync_to_restart = jpeg_resync_to_restart; /* use default method */ - src->term_source = term_source; - src->bytes_in_buffer = (size_t) insize; - src->next_input_byte = (const JOCTET *) inbuffer; -} diff --git a/libraries/jpeg/jdcoefct.c b/libraries/jpeg/jdcoefct.c deleted file mode 100644 index ed02fc378..000000000 --- a/libraries/jpeg/jdcoefct.c +++ /dev/null @@ -1,741 +0,0 @@ -/* - * jdcoefct.c - * - * Copyright (C) 1994-1997, Thomas G. Lane. - * Modified 2002-2011 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the coefficient buffer controller for decompression. - * This controller is the top level of the JPEG decompressor proper. - * The coefficient buffer lies between entropy decoding and inverse-DCT steps. - * - * In buffered-image mode, this controller is the interface between - * input-oriented processing and output-oriented processing. - * Also, the input side (only) is used when reading a file for transcoding. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - -/* Block smoothing is only applicable for progressive JPEG, so: */ -#ifndef D_PROGRESSIVE_SUPPORTED -#undef BLOCK_SMOOTHING_SUPPORTED -#endif - -/* Private buffer controller object */ - -typedef struct { - struct jpeg_d_coef_controller pub; /* public fields */ - - /* These variables keep track of the current location of the input side. */ - /* cinfo->input_iMCU_row is also used for this. */ - JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ - int MCU_vert_offset; /* counts MCU rows within iMCU row */ - int MCU_rows_per_iMCU_row; /* number of such rows needed */ - - /* The output side's location is represented by cinfo->output_iMCU_row. */ - - /* In single-pass modes, it's sufficient to buffer just one MCU. - * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, - * and let the entropy decoder write into that workspace each time. - * (On 80x86, the workspace is FAR even though it's not really very big; - * this is to keep the module interfaces unchanged when a large coefficient - * buffer is necessary.) - * In multi-pass modes, this array points to the current MCU's blocks - * within the virtual arrays; it is used only by the input side. - */ - JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU]; - -#ifdef D_MULTISCAN_FILES_SUPPORTED - /* In multi-pass modes, we need a virtual block array for each component. */ - jvirt_barray_ptr whole_image[MAX_COMPONENTS]; -#endif - -#ifdef BLOCK_SMOOTHING_SUPPORTED - /* When doing block smoothing, we latch coefficient Al values here */ - int * coef_bits_latch; -#define SAVED_COEFS 6 /* we save coef_bits[0..5] */ -#endif -} my_coef_controller; - -typedef my_coef_controller * my_coef_ptr; - -/* Forward declarations */ -METHODDEF(int) decompress_onepass - JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); -#ifdef D_MULTISCAN_FILES_SUPPORTED -METHODDEF(int) decompress_data - JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); -#endif -#ifdef BLOCK_SMOOTHING_SUPPORTED -LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo)); -METHODDEF(int) decompress_smooth_data - JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); -#endif - - -LOCAL(void) -start_iMCU_row (j_decompress_ptr cinfo) -/* Reset within-iMCU-row counters for a new row (input side) */ -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - - /* In an interleaved scan, an MCU row is the same as an iMCU row. - * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. - * But at the bottom of the image, process only what's left. - */ - if (cinfo->comps_in_scan > 1) { - coef->MCU_rows_per_iMCU_row = 1; - } else { - if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1)) - coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; - else - coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; - } - - coef->MCU_ctr = 0; - coef->MCU_vert_offset = 0; -} - - -/* - * Initialize for an input processing pass. - */ - -METHODDEF(void) -start_input_pass (j_decompress_ptr cinfo) -{ - cinfo->input_iMCU_row = 0; - start_iMCU_row(cinfo); -} - - -/* - * Initialize for an output processing pass. - */ - -METHODDEF(void) -start_output_pass (j_decompress_ptr cinfo) -{ -#ifdef BLOCK_SMOOTHING_SUPPORTED - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - - /* If multipass, check to see whether to use block smoothing on this pass */ - if (coef->pub.coef_arrays != NULL) { - if (cinfo->do_block_smoothing && smoothing_ok(cinfo)) - coef->pub.decompress_data = decompress_smooth_data; - else - coef->pub.decompress_data = decompress_data; - } -#endif - cinfo->output_iMCU_row = 0; -} - - -/* - * Decompress and return some data in the single-pass case. - * Always attempts to emit one fully interleaved MCU row ("iMCU" row). - * Input and output must run in lockstep since we have only a one-MCU buffer. - * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. - * - * NB: output_buf contains a plane for each component in image, - * which we index according to the component's SOF position. - */ - -METHODDEF(int) -decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION MCU_col_num; /* index of current MCU within row */ - JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; - JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - int blkn, ci, xindex, yindex, yoffset, useful_width; - JSAMPARRAY output_ptr; - JDIMENSION start_col, output_col; - jpeg_component_info *compptr; - inverse_DCT_method_ptr inverse_DCT; - - /* Loop to process as much as one whole iMCU row */ - for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; - yoffset++) { - for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col; - MCU_col_num++) { - /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */ - if (cinfo->lim_Se) /* can bypass in DC only case */ - FMEMZERO((void FAR *) coef->MCU_buffer[0], - (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); - if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { - /* Suspension forced; update state counters and exit */ - coef->MCU_vert_offset = yoffset; - coef->MCU_ctr = MCU_col_num; - return JPEG_SUSPENDED; - } - /* Determine where data should go in output_buf and do the IDCT thing. - * We skip dummy blocks at the right and bottom edges (but blkn gets - * incremented past them!). Note the inner loop relies on having - * allocated the MCU_buffer[] blocks sequentially. - */ - blkn = 0; /* index of current DCT block within MCU */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* Don't bother to IDCT an uninteresting component. */ - if (! compptr->component_needed) { - blkn += compptr->MCU_blocks; - continue; - } - inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; - useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width - : compptr->last_col_width; - output_ptr = output_buf[compptr->component_index] + - yoffset * compptr->DCT_v_scaled_size; - start_col = MCU_col_num * compptr->MCU_sample_width; - for (yindex = 0; yindex < compptr->MCU_height; yindex++) { - if (cinfo->input_iMCU_row < last_iMCU_row || - yoffset+yindex < compptr->last_row_height) { - output_col = start_col; - for (xindex = 0; xindex < useful_width; xindex++) { - (*inverse_DCT) (cinfo, compptr, - (JCOEFPTR) coef->MCU_buffer[blkn+xindex], - output_ptr, output_col); - output_col += compptr->DCT_h_scaled_size; - } - } - blkn += compptr->MCU_width; - output_ptr += compptr->DCT_v_scaled_size; - } - } - } - /* Completed an MCU row, but perhaps not an iMCU row */ - coef->MCU_ctr = 0; - } - /* Completed the iMCU row, advance counters for next one */ - cinfo->output_iMCU_row++; - if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { - start_iMCU_row(cinfo); - return JPEG_ROW_COMPLETED; - } - /* Completed the scan */ - (*cinfo->inputctl->finish_input_pass) (cinfo); - return JPEG_SCAN_COMPLETED; -} - - -/* - * Dummy consume-input routine for single-pass operation. - */ - -METHODDEF(int) -dummy_consume_data (j_decompress_ptr cinfo) -{ - return JPEG_SUSPENDED; /* Always indicate nothing was done */ -} - - -#ifdef D_MULTISCAN_FILES_SUPPORTED - -/* - * Consume input data and store it in the full-image coefficient buffer. - * We read as much as one fully interleaved MCU row ("iMCU" row) per call, - * ie, v_samp_factor block rows for each component in the scan. - * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. - */ - -METHODDEF(int) -consume_data (j_decompress_ptr cinfo) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION MCU_col_num; /* index of current MCU within row */ - int blkn, ci, xindex, yindex, yoffset; - JDIMENSION start_col; - JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; - JBLOCKROW buffer_ptr; - jpeg_component_info *compptr; - - /* Align the virtual buffers for the components used in this scan. */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - buffer[ci] = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], - cinfo->input_iMCU_row * compptr->v_samp_factor, - (JDIMENSION) compptr->v_samp_factor, TRUE); - /* Note: entropy decoder expects buffer to be zeroed, - * but this is handled automatically by the memory manager - * because we requested a pre-zeroed array. - */ - } - - /* Loop to process one whole iMCU row */ - for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; - yoffset++) { - for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row; - MCU_col_num++) { - /* Construct list of pointers to DCT blocks belonging to this MCU */ - blkn = 0; /* index of current DCT block within MCU */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - start_col = MCU_col_num * compptr->MCU_width; - for (yindex = 0; yindex < compptr->MCU_height; yindex++) { - buffer_ptr = buffer[ci][yindex+yoffset] + start_col; - for (xindex = 0; xindex < compptr->MCU_width; xindex++) { - coef->MCU_buffer[blkn++] = buffer_ptr++; - } - } - } - /* Try to fetch the MCU. */ - if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { - /* Suspension forced; update state counters and exit */ - coef->MCU_vert_offset = yoffset; - coef->MCU_ctr = MCU_col_num; - return JPEG_SUSPENDED; - } - } - /* Completed an MCU row, but perhaps not an iMCU row */ - coef->MCU_ctr = 0; - } - /* Completed the iMCU row, advance counters for next one */ - if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { - start_iMCU_row(cinfo); - return JPEG_ROW_COMPLETED; - } - /* Completed the scan */ - (*cinfo->inputctl->finish_input_pass) (cinfo); - return JPEG_SCAN_COMPLETED; -} - - -/* - * Decompress and return some data in the multi-pass case. - * Always attempts to emit one fully interleaved MCU row ("iMCU" row). - * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. - * - * NB: output_buf contains a plane for each component in image. - */ - -METHODDEF(int) -decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - JDIMENSION block_num; - int ci, block_row, block_rows; - JBLOCKARRAY buffer; - JBLOCKROW buffer_ptr; - JSAMPARRAY output_ptr; - JDIMENSION output_col; - jpeg_component_info *compptr; - inverse_DCT_method_ptr inverse_DCT; - - /* Force some input to be done if we are getting ahead of the input. */ - while (cinfo->input_scan_number < cinfo->output_scan_number || - (cinfo->input_scan_number == cinfo->output_scan_number && - cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) { - if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) - return JPEG_SUSPENDED; - } - - /* OK, output from the virtual arrays. */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Don't bother to IDCT an uninteresting component. */ - if (! compptr->component_needed) - continue; - /* Align the virtual buffer for this component. */ - buffer = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[ci], - cinfo->output_iMCU_row * compptr->v_samp_factor, - (JDIMENSION) compptr->v_samp_factor, FALSE); - /* Count non-dummy DCT block rows in this iMCU row. */ - if (cinfo->output_iMCU_row < last_iMCU_row) - block_rows = compptr->v_samp_factor; - else { - /* NB: can't use last_row_height here; it is input-side-dependent! */ - block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); - if (block_rows == 0) block_rows = compptr->v_samp_factor; - } - inverse_DCT = cinfo->idct->inverse_DCT[ci]; - output_ptr = output_buf[ci]; - /* Loop over all DCT blocks to be processed. */ - for (block_row = 0; block_row < block_rows; block_row++) { - buffer_ptr = buffer[block_row]; - output_col = 0; - for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) { - (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr, - output_ptr, output_col); - buffer_ptr++; - output_col += compptr->DCT_h_scaled_size; - } - output_ptr += compptr->DCT_v_scaled_size; - } - } - - if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) - return JPEG_ROW_COMPLETED; - return JPEG_SCAN_COMPLETED; -} - -#endif /* D_MULTISCAN_FILES_SUPPORTED */ - - -#ifdef BLOCK_SMOOTHING_SUPPORTED - -/* - * This code applies interblock smoothing as described by section K.8 - * of the JPEG standard: the first 5 AC coefficients are estimated from - * the DC values of a DCT block and its 8 neighboring blocks. - * We apply smoothing only for progressive JPEG decoding, and only if - * the coefficients it can estimate are not yet known to full precision. - */ - -/* Natural-order array positions of the first 5 zigzag-order coefficients */ -#define Q01_POS 1 -#define Q10_POS 8 -#define Q20_POS 16 -#define Q11_POS 9 -#define Q02_POS 2 - -/* - * Determine whether block smoothing is applicable and safe. - * We also latch the current states of the coef_bits[] entries for the - * AC coefficients; otherwise, if the input side of the decompressor - * advances into a new scan, we might think the coefficients are known - * more accurately than they really are. - */ - -LOCAL(boolean) -smoothing_ok (j_decompress_ptr cinfo) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - boolean smoothing_useful = FALSE; - int ci, coefi; - jpeg_component_info *compptr; - JQUANT_TBL * qtable; - int * coef_bits; - int * coef_bits_latch; - - if (! cinfo->progressive_mode || cinfo->coef_bits == NULL) - return FALSE; - - /* Allocate latch area if not already done */ - if (coef->coef_bits_latch == NULL) - coef->coef_bits_latch = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components * - (SAVED_COEFS * SIZEOF(int))); - coef_bits_latch = coef->coef_bits_latch; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* All components' quantization values must already be latched. */ - if ((qtable = compptr->quant_table) == NULL) - return FALSE; - /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */ - if (qtable->quantval[0] == 0 || - qtable->quantval[Q01_POS] == 0 || - qtable->quantval[Q10_POS] == 0 || - qtable->quantval[Q20_POS] == 0 || - qtable->quantval[Q11_POS] == 0 || - qtable->quantval[Q02_POS] == 0) - return FALSE; - /* DC values must be at least partly known for all components. */ - coef_bits = cinfo->coef_bits[ci]; - if (coef_bits[0] < 0) - return FALSE; - /* Block smoothing is helpful if some AC coefficients remain inaccurate. */ - for (coefi = 1; coefi <= 5; coefi++) { - coef_bits_latch[coefi] = coef_bits[coefi]; - if (coef_bits[coefi] != 0) - smoothing_useful = TRUE; - } - coef_bits_latch += SAVED_COEFS; - } - - return smoothing_useful; -} - - -/* - * Variant of decompress_data for use when doing block smoothing. - */ - -METHODDEF(int) -decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) -{ - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; - JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; - JDIMENSION block_num, last_block_column; - int ci, block_row, block_rows, access_rows; - JBLOCKARRAY buffer; - JBLOCKROW buffer_ptr, prev_block_row, next_block_row; - JSAMPARRAY output_ptr; - JDIMENSION output_col; - jpeg_component_info *compptr; - inverse_DCT_method_ptr inverse_DCT; - boolean first_row, last_row; - JBLOCK workspace; - int *coef_bits; - JQUANT_TBL *quanttbl; - INT32 Q00,Q01,Q02,Q10,Q11,Q20, num; - int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9; - int Al, pred; - - /* Force some input to be done if we are getting ahead of the input. */ - while (cinfo->input_scan_number <= cinfo->output_scan_number && - ! cinfo->inputctl->eoi_reached) { - if (cinfo->input_scan_number == cinfo->output_scan_number) { - /* If input is working on current scan, we ordinarily want it to - * have completed the current row. But if input scan is DC, - * we want it to keep one row ahead so that next block row's DC - * values are up to date. - */ - JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0; - if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta) - break; - } - if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) - return JPEG_SUSPENDED; - } - - /* OK, output from the virtual arrays. */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Don't bother to IDCT an uninteresting component. */ - if (! compptr->component_needed) - continue; - /* Count non-dummy DCT block rows in this iMCU row. */ - if (cinfo->output_iMCU_row < last_iMCU_row) { - block_rows = compptr->v_samp_factor; - access_rows = block_rows * 2; /* this and next iMCU row */ - last_row = FALSE; - } else { - /* NB: can't use last_row_height here; it is input-side-dependent! */ - block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); - if (block_rows == 0) block_rows = compptr->v_samp_factor; - access_rows = block_rows; /* this iMCU row only */ - last_row = TRUE; - } - /* Align the virtual buffer for this component. */ - if (cinfo->output_iMCU_row > 0) { - access_rows += compptr->v_samp_factor; /* prior iMCU row too */ - buffer = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[ci], - (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor, - (JDIMENSION) access_rows, FALSE); - buffer += compptr->v_samp_factor; /* point to current iMCU row */ - first_row = FALSE; - } else { - buffer = (*cinfo->mem->access_virt_barray) - ((j_common_ptr) cinfo, coef->whole_image[ci], - (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE); - first_row = TRUE; - } - /* Fetch component-dependent info */ - coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS); - quanttbl = compptr->quant_table; - Q00 = quanttbl->quantval[0]; - Q01 = quanttbl->quantval[Q01_POS]; - Q10 = quanttbl->quantval[Q10_POS]; - Q20 = quanttbl->quantval[Q20_POS]; - Q11 = quanttbl->quantval[Q11_POS]; - Q02 = quanttbl->quantval[Q02_POS]; - inverse_DCT = cinfo->idct->inverse_DCT[ci]; - output_ptr = output_buf[ci]; - /* Loop over all DCT blocks to be processed. */ - for (block_row = 0; block_row < block_rows; block_row++) { - buffer_ptr = buffer[block_row]; - if (first_row && block_row == 0) - prev_block_row = buffer_ptr; - else - prev_block_row = buffer[block_row-1]; - if (last_row && block_row == block_rows-1) - next_block_row = buffer_ptr; - else - next_block_row = buffer[block_row+1]; - /* We fetch the surrounding DC values using a sliding-register approach. - * Initialize all nine here so as to do the right thing on narrow pics. - */ - DC1 = DC2 = DC3 = (int) prev_block_row[0][0]; - DC4 = DC5 = DC6 = (int) buffer_ptr[0][0]; - DC7 = DC8 = DC9 = (int) next_block_row[0][0]; - output_col = 0; - last_block_column = compptr->width_in_blocks - 1; - for (block_num = 0; block_num <= last_block_column; block_num++) { - /* Fetch current DCT block into workspace so we can modify it. */ - jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1); - /* Update DC values */ - if (block_num < last_block_column) { - DC3 = (int) prev_block_row[1][0]; - DC6 = (int) buffer_ptr[1][0]; - DC9 = (int) next_block_row[1][0]; - } - /* Compute coefficient estimates per K.8. - * An estimate is applied only if coefficient is still zero, - * and is not known to be fully accurate. - */ - /* AC01 */ - if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) { - num = 36 * Q00 * (DC4 - DC6); - if (num >= 0) { - pred = (int) (((Q01<<7) + num) / (Q01<<8)); - if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { - pred = (int) (((Q10<<7) + num) / (Q10<<8)); - if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { - pred = (int) (((Q20<<7) + num) / (Q20<<8)); - if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { - pred = (int) (((Q11<<7) + num) / (Q11<<8)); - if (Al > 0 && pred >= (1< 0 && pred >= (1<= 0) { - pred = (int) (((Q02<<7) + num) / (Q02<<8)); - if (Al > 0 && pred >= (1< 0 && pred >= (1<DCT_h_scaled_size; - } - output_ptr += compptr->DCT_v_scaled_size; - } - } - - if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) - return JPEG_ROW_COMPLETED; - return JPEG_SCAN_COMPLETED; -} - -#endif /* BLOCK_SMOOTHING_SUPPORTED */ - - -/* - * Initialize coefficient buffer controller. - */ - -GLOBAL(void) -jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) -{ - my_coef_ptr coef; - - coef = (my_coef_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_coef_controller)); - cinfo->coef = (struct jpeg_d_coef_controller *) coef; - coef->pub.start_input_pass = start_input_pass; - coef->pub.start_output_pass = start_output_pass; -#ifdef BLOCK_SMOOTHING_SUPPORTED - coef->coef_bits_latch = NULL; -#endif - - /* Create the coefficient buffer. */ - if (need_full_buffer) { -#ifdef D_MULTISCAN_FILES_SUPPORTED - /* Allocate a full-image virtual array for each component, */ - /* padded to a multiple of samp_factor DCT blocks in each direction. */ - /* Note we ask for a pre-zeroed array. */ - int ci, access_rows; - jpeg_component_info *compptr; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - access_rows = compptr->v_samp_factor; -#ifdef BLOCK_SMOOTHING_SUPPORTED - /* If block smoothing could be used, need a bigger window */ - if (cinfo->progressive_mode) - access_rows *= 3; -#endif - coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE, - (JDIMENSION) jround_up((long) compptr->width_in_blocks, - (long) compptr->h_samp_factor), - (JDIMENSION) jround_up((long) compptr->height_in_blocks, - (long) compptr->v_samp_factor), - (JDIMENSION) access_rows); - } - coef->pub.consume_data = consume_data; - coef->pub.decompress_data = decompress_data; - coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */ -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else { - /* We only need a single-MCU buffer. */ - JBLOCKROW buffer; - int i; - - buffer = (JBLOCKROW) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) { - coef->MCU_buffer[i] = buffer + i; - } - if (cinfo->lim_Se == 0) /* DC only case: want to bypass later */ - FMEMZERO((void FAR *) buffer, - (size_t) (D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK))); - coef->pub.consume_data = dummy_consume_data; - coef->pub.decompress_data = decompress_onepass; - coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ - } -} diff --git a/libraries/jpeg/jdcolor.c b/libraries/jpeg/jdcolor.c deleted file mode 100644 index 0316354da..000000000 --- a/libraries/jpeg/jdcolor.c +++ /dev/null @@ -1,731 +0,0 @@ -/* - * jdcolor.c - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2011-2017 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains output colorspace conversion routines. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -#if RANGE_BITS < 2 - /* Deliberate syntax err */ - Sorry, this code requires 2 or more range extension bits. -#endif - - -/* Private subobject */ - -typedef struct { - struct jpeg_color_deconverter pub; /* public fields */ - - /* Private state for YCbCr->RGB and BG_YCC->RGB conversion */ - int * Cr_r_tab; /* => table for Cr to R conversion */ - int * Cb_b_tab; /* => table for Cb to B conversion */ - INT32 * Cr_g_tab; /* => table for Cr to G conversion */ - INT32 * Cb_g_tab; /* => table for Cb to G conversion */ - - /* Private state for RGB->Y conversion */ - INT32 * rgb_y_tab; /* => table for RGB to Y conversion */ -} my_color_deconverter; - -typedef my_color_deconverter * my_cconvert_ptr; - - -/*************** YCbCr -> RGB conversion: most common case **************/ -/*************** BG_YCC -> RGB conversion: less common case **************/ -/*************** RGB -> Y conversion: less common case **************/ - -/* - * YCbCr is defined per Recommendation ITU-R BT.601-7 (03/2011), - * previously known as Recommendation CCIR 601-1, except that Cb and Cr - * are normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. - * sRGB (standard RGB color space) is defined per IEC 61966-2-1:1999. - * sYCC (standard luma-chroma-chroma color space with extended gamut) - * is defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex F. - * bg-sRGB and bg-sYCC (big gamut standard color spaces) - * are defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex G. - * Note that the derived conversion coefficients given in some of these - * documents are imprecise. The general conversion equations are - * - * R = Y + K * (1 - Kr) * Cr - * G = Y - K * (Kb * (1 - Kb) * Cb + Kr * (1 - Kr) * Cr) / (1 - Kr - Kb) - * B = Y + K * (1 - Kb) * Cb - * - * Y = Kr * R + (1 - Kr - Kb) * G + Kb * B - * - * With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993 - * from the 1953 FCC NTSC primaries and CIE Illuminant C), K = 2 for sYCC, - * the conversion equations to be implemented are therefore - * - * R = Y + 1.402 * Cr - * G = Y - 0.344136286 * Cb - 0.714136286 * Cr - * B = Y + 1.772 * Cb - * - * Y = 0.299 * R + 0.587 * G + 0.114 * B - * - * where Cb and Cr represent the incoming values less CENTERJSAMPLE. - * For bg-sYCC, with K = 4, the equations are - * - * R = Y + 2.804 * Cr - * G = Y - 0.688272572 * Cb - 1.428272572 * Cr - * B = Y + 3.544 * Cb - * - * To avoid floating-point arithmetic, we represent the fractional constants - * as integers scaled up by 2^16 (about 4 digits precision); we have to divide - * the products by 2^16, with appropriate rounding, to get the correct answer. - * Notice that Y, being an integral input, does not contribute any fraction - * so it need not participate in the rounding. - * - * For even more speed, we avoid doing any multiplications in the inner loop - * by precalculating the constants times Cb and Cr for all possible values. - * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); - * for 9-bit to 12-bit samples it is still acceptable. It's not very - * reasonable for 16-bit samples, but if you want lossless storage you - * shouldn't be changing colorspace anyway. - * The Cr=>R and Cb=>B values can be rounded to integers in advance; the - * values for the G calculation are left scaled up, since we must add them - * together before rounding. - */ - -#define SCALEBITS 16 /* speediest right-shift on some machines */ -#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) -#define FIX(x) ((INT32) ((x) * (1L<Y conversion and divide it up into - * three parts, instead of doing three alloc_small requests. This lets us - * use a single table base address, which can be held in a register in the - * inner loops on many machines (more than can hold all three addresses, - * anyway). - */ - -#define R_Y_OFF 0 /* offset to R => Y section */ -#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ -#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ -#define TABLE_SIZE (3*(MAXJSAMPLE+1)) - - -/* - * Initialize tables for YCbCr->RGB and BG_YCC->RGB colorspace conversion. - */ - -LOCAL(void) -build_ycc_rgb_table (j_decompress_ptr cinfo) -/* Normal case, sYCC */ -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - int i; - INT32 x; - SHIFT_TEMPS - - cconvert->Cr_r_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - cconvert->Cb_b_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - cconvert->Cr_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - cconvert->Cb_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - - for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { - /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ - /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ - /* Cr=>R value is nearest int to 1.402 * x */ - cconvert->Cr_r_tab[i] = (int) - RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS); - /* Cb=>B value is nearest int to 1.772 * x */ - cconvert->Cb_b_tab[i] = (int) - RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS); - /* Cr=>G value is scaled-up -0.714136286 * x */ - cconvert->Cr_g_tab[i] = (- FIX(0.714136286)) * x; - /* Cb=>G value is scaled-up -0.344136286 * x */ - /* We also add in ONE_HALF so that need not do it in inner loop */ - cconvert->Cb_g_tab[i] = (- FIX(0.344136286)) * x + ONE_HALF; - } -} - - -LOCAL(void) -build_bg_ycc_rgb_table (j_decompress_ptr cinfo) -/* Wide gamut case, bg-sYCC */ -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - int i; - INT32 x; - SHIFT_TEMPS - - cconvert->Cr_r_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - cconvert->Cb_b_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - cconvert->Cr_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - cconvert->Cb_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - - for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { - /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ - /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ - /* Cr=>R value is nearest int to 2.804 * x */ - cconvert->Cr_r_tab[i] = (int) - RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS); - /* Cb=>B value is nearest int to 3.544 * x */ - cconvert->Cb_b_tab[i] = (int) - RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS); - /* Cr=>G value is scaled-up -1.428272572 * x */ - cconvert->Cr_g_tab[i] = (- FIX(1.428272572)) * x; - /* Cb=>G value is scaled-up -0.688272572 * x */ - /* We also add in ONE_HALF so that need not do it in inner loop */ - cconvert->Cb_g_tab[i] = (- FIX(0.688272572)) * x + ONE_HALF; - } -} - - -/* - * Convert some rows of samples to the output colorspace. - * - * Note that we change from noninterleaved, one-plane-per-component format - * to interleaved-pixel format. The output buffer is therefore three times - * as wide as the input buffer. - * A starting row offset is provided only for the input buffer. The caller - * can easily adjust the passed output_buf value to accommodate any row - * offset required on that side. - */ - -METHODDEF(void) -ycc_rgb_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int y, cb, cr; - register JSAMPROW outptr; - register JSAMPROW inptr0, inptr1, inptr2; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->output_width; - /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - register int * Crrtab = cconvert->Cr_r_tab; - register int * Cbbtab = cconvert->Cb_b_tab; - register INT32 * Crgtab = cconvert->Cr_g_tab; - register INT32 * Cbgtab = cconvert->Cb_g_tab; - SHIFT_TEMPS - - while (--num_rows >= 0) { - inptr0 = input_buf[0][input_row]; - inptr1 = input_buf[1][input_row]; - inptr2 = input_buf[2][input_row]; - input_row++; - outptr = *output_buf++; - for (col = 0; col < num_cols; col++) { - y = GETJSAMPLE(inptr0[col]); - cb = GETJSAMPLE(inptr1[col]); - cr = GETJSAMPLE(inptr2[col]); - /* Range-limiting is essential due to noise introduced by DCT losses, - * for extended gamut (sYCC) and wide gamut (bg-sYCC) encodings. - */ - outptr[RGB_RED] = range_limit[y + Crrtab[cr]]; - outptr[RGB_GREEN] = range_limit[y + - ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], - SCALEBITS))]; - outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]]; - outptr += RGB_PIXELSIZE; - } - } -} - - -/**************** Cases other than YCC -> RGB ****************/ - - -/* - * Initialize for RGB->grayscale colorspace conversion. - */ - -LOCAL(void) -build_rgb_y_table (j_decompress_ptr cinfo) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - INT32 * rgb_y_tab; - INT32 i; - - /* Allocate and fill in the conversion tables. */ - cconvert->rgb_y_tab = rgb_y_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (TABLE_SIZE * SIZEOF(INT32))); - - for (i = 0; i <= MAXJSAMPLE; i++) { - rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i; - rgb_y_tab[i+G_Y_OFF] = FIX(0.587) * i; - rgb_y_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF; - } -} - - -/* - * Convert RGB to grayscale. - */ - -METHODDEF(void) -rgb_gray_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register INT32 * ctab = cconvert->rgb_y_tab; - register int r, g, b; - register JSAMPROW outptr; - register JSAMPROW inptr0, inptr1, inptr2; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->output_width; - - while (--num_rows >= 0) { - inptr0 = input_buf[0][input_row]; - inptr1 = input_buf[1][input_row]; - inptr2 = input_buf[2][input_row]; - input_row++; - outptr = *output_buf++; - for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr0[col]); - g = GETJSAMPLE(inptr1[col]); - b = GETJSAMPLE(inptr2[col]); - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); - } - } -} - - -/* - * [R-G,G,B-G] to [R,G,B] conversion with modulo calculation - * (inverse color transform). - * This can be seen as an adaption of the general YCbCr->RGB - * conversion equation with Kr = Kb = 0, while replacing the - * normalization by modulo calculation. - */ - -METHODDEF(void) -rgb1_rgb_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - register int r, g, b; - register JSAMPROW outptr; - register JSAMPROW inptr0, inptr1, inptr2; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->output_width; - - while (--num_rows >= 0) { - inptr0 = input_buf[0][input_row]; - inptr1 = input_buf[1][input_row]; - inptr2 = input_buf[2][input_row]; - input_row++; - outptr = *output_buf++; - for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr0[col]); - g = GETJSAMPLE(inptr1[col]); - b = GETJSAMPLE(inptr2[col]); - /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD - * (modulo) operator is equivalent to the bitmask operator AND. - */ - outptr[RGB_RED] = (JSAMPLE) ((r + g - CENTERJSAMPLE) & MAXJSAMPLE); - outptr[RGB_GREEN] = (JSAMPLE) g; - outptr[RGB_BLUE] = (JSAMPLE) ((b + g - CENTERJSAMPLE) & MAXJSAMPLE); - outptr += RGB_PIXELSIZE; - } - } -} - - -/* - * [R-G,G,B-G] to grayscale conversion with modulo calculation - * (inverse color transform). - */ - -METHODDEF(void) -rgb1_gray_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register INT32 * ctab = cconvert->rgb_y_tab; - register int r, g, b; - register JSAMPROW outptr; - register JSAMPROW inptr0, inptr1, inptr2; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->output_width; - - while (--num_rows >= 0) { - inptr0 = input_buf[0][input_row]; - inptr1 = input_buf[1][input_row]; - inptr2 = input_buf[2][input_row]; - input_row++; - outptr = *output_buf++; - for (col = 0; col < num_cols; col++) { - r = GETJSAMPLE(inptr0[col]); - g = GETJSAMPLE(inptr1[col]); - b = GETJSAMPLE(inptr2[col]); - /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD - * (modulo) operator is equivalent to the bitmask operator AND. - */ - r = (r + g - CENTERJSAMPLE) & MAXJSAMPLE; - b = (b + g - CENTERJSAMPLE) & MAXJSAMPLE; - /* Y */ - outptr[col] = (JSAMPLE) - ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) - >> SCALEBITS); - } - } -} - - -/* - * No colorspace change, but conversion from separate-planes - * to interleaved representation. - */ - -METHODDEF(void) -rgb_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - register JSAMPROW outptr; - register JSAMPROW inptr0, inptr1, inptr2; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->output_width; - - while (--num_rows >= 0) { - inptr0 = input_buf[0][input_row]; - inptr1 = input_buf[1][input_row]; - inptr2 = input_buf[2][input_row]; - input_row++; - outptr = *output_buf++; - for (col = 0; col < num_cols; col++) { - /* We can dispense with GETJSAMPLE() here */ - outptr[RGB_RED] = inptr0[col]; - outptr[RGB_GREEN] = inptr1[col]; - outptr[RGB_BLUE] = inptr2[col]; - outptr += RGB_PIXELSIZE; - } - } -} - - -/* - * Color conversion for no colorspace change: just copy the data, - * converting from separate-planes to interleaved representation. - */ - -METHODDEF(void) -null_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - int ci; - register int nc = cinfo->num_components; - register JSAMPROW outptr; - register JSAMPROW inptr; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->output_width; - - while (--num_rows >= 0) { - for (ci = 0; ci < nc; ci++) { - inptr = input_buf[ci][input_row]; - outptr = output_buf[0] + ci; - for (col = 0; col < num_cols; col++) { - *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */ - outptr += nc; - } - } - input_row++; - output_buf++; - } -} - - -/* - * Color conversion for grayscale: just copy the data. - * This also works for YCC -> grayscale conversion, in which - * we just copy the Y (luminance) component and ignore chrominance. - */ - -METHODDEF(void) -grayscale_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, - num_rows, cinfo->output_width); -} - - -/* - * Convert grayscale to RGB: just duplicate the graylevel three times. - * This is provided to support applications that don't want to cope - * with grayscale as a separate case. - */ - -METHODDEF(void) -gray_rgb_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - register JSAMPROW outptr; - register JSAMPROW inptr; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->output_width; - - while (--num_rows >= 0) { - inptr = input_buf[0][input_row++]; - outptr = *output_buf++; - for (col = 0; col < num_cols; col++) { - /* We can dispense with GETJSAMPLE() here */ - outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col]; - outptr += RGB_PIXELSIZE; - } - } -} - - -/* - * Adobe-style YCCK->CMYK conversion. - * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same - * conversion as above, while passing K (black) unchanged. - * We assume build_ycc_rgb_table has been called. - */ - -METHODDEF(void) -ycck_cmyk_convert (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows) -{ - my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; - register int y, cb, cr; - register JSAMPROW outptr; - register JSAMPROW inptr0, inptr1, inptr2, inptr3; - register JDIMENSION col; - JDIMENSION num_cols = cinfo->output_width; - /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - register int * Crrtab = cconvert->Cr_r_tab; - register int * Cbbtab = cconvert->Cb_b_tab; - register INT32 * Crgtab = cconvert->Cr_g_tab; - register INT32 * Cbgtab = cconvert->Cb_g_tab; - SHIFT_TEMPS - - while (--num_rows >= 0) { - inptr0 = input_buf[0][input_row]; - inptr1 = input_buf[1][input_row]; - inptr2 = input_buf[2][input_row]; - inptr3 = input_buf[3][input_row]; - input_row++; - outptr = *output_buf++; - for (col = 0; col < num_cols; col++) { - y = GETJSAMPLE(inptr0[col]); - cb = GETJSAMPLE(inptr1[col]); - cr = GETJSAMPLE(inptr2[col]); - /* Range-limiting is essential due to noise introduced by DCT losses, - * and for extended gamut encodings (sYCC). - */ - outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ - outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ - ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], - SCALEBITS)))]; - outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ - /* K passes through unchanged */ - outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */ - outptr += 4; - } - } -} - - -/* - * Empty method for start_pass. - */ - -METHODDEF(void) -start_pass_dcolor (j_decompress_ptr cinfo) -{ - /* no work needed */ -} - - -/* - * Module initialization routine for output colorspace conversion. - */ - -GLOBAL(void) -jinit_color_deconverter (j_decompress_ptr cinfo) -{ - my_cconvert_ptr cconvert; - int ci; - - cconvert = (my_cconvert_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_color_deconverter)); - cinfo->cconvert = &cconvert->pub; - cconvert->pub.start_pass = start_pass_dcolor; - - /* Make sure num_components agrees with jpeg_color_space */ - switch (cinfo->jpeg_color_space) { - case JCS_GRAYSCALE: - if (cinfo->num_components != 1) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - break; - - case JCS_RGB: - case JCS_YCbCr: - case JCS_BG_RGB: - case JCS_BG_YCC: - if (cinfo->num_components != 3) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - break; - - case JCS_CMYK: - case JCS_YCCK: - if (cinfo->num_components != 4) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - break; - - default: /* JCS_UNKNOWN can be anything */ - if (cinfo->num_components < 1) - ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - break; - } - - /* Support color transform only for RGB colorspaces */ - if (cinfo->color_transform && - cinfo->jpeg_color_space != JCS_RGB && - cinfo->jpeg_color_space != JCS_BG_RGB) - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - - /* Set out_color_components and conversion method based on requested space. - * Also clear the component_needed flags for any unused components, - * so that earlier pipeline stages can avoid useless computation. - */ - - switch (cinfo->out_color_space) { - case JCS_GRAYSCALE: - cinfo->out_color_components = 1; - switch (cinfo->jpeg_color_space) { - case JCS_GRAYSCALE: - case JCS_YCbCr: - case JCS_BG_YCC: - cconvert->pub.color_convert = grayscale_convert; - /* For color->grayscale conversion, only the Y (0) component is needed */ - for (ci = 1; ci < cinfo->num_components; ci++) - cinfo->comp_info[ci].component_needed = FALSE; - break; - case JCS_RGB: - switch (cinfo->color_transform) { - case JCT_NONE: - cconvert->pub.color_convert = rgb_gray_convert; - break; - case JCT_SUBTRACT_GREEN: - cconvert->pub.color_convert = rgb1_gray_convert; - break; - default: - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - } - build_rgb_y_table(cinfo); - break; - default: - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - } - break; - - case JCS_RGB: - cinfo->out_color_components = RGB_PIXELSIZE; - switch (cinfo->jpeg_color_space) { - case JCS_GRAYSCALE: - cconvert->pub.color_convert = gray_rgb_convert; - break; - case JCS_YCbCr: - cconvert->pub.color_convert = ycc_rgb_convert; - build_ycc_rgb_table(cinfo); - break; - case JCS_BG_YCC: - cconvert->pub.color_convert = ycc_rgb_convert; - build_bg_ycc_rgb_table(cinfo); - break; - case JCS_RGB: - switch (cinfo->color_transform) { - case JCT_NONE: - cconvert->pub.color_convert = rgb_convert; - break; - case JCT_SUBTRACT_GREEN: - cconvert->pub.color_convert = rgb1_rgb_convert; - break; - default: - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - } - break; - default: - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - } - break; - - case JCS_BG_RGB: - cinfo->out_color_components = RGB_PIXELSIZE; - if (cinfo->jpeg_color_space == JCS_BG_RGB) { - switch (cinfo->color_transform) { - case JCT_NONE: - cconvert->pub.color_convert = rgb_convert; - break; - case JCT_SUBTRACT_GREEN: - cconvert->pub.color_convert = rgb1_rgb_convert; - break; - default: - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - } - } else - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - - case JCS_CMYK: - cinfo->out_color_components = 4; - switch (cinfo->jpeg_color_space) { - case JCS_YCCK: - cconvert->pub.color_convert = ycck_cmyk_convert; - build_ycc_rgb_table(cinfo); - break; - case JCS_CMYK: - cconvert->pub.color_convert = null_convert; - break; - default: - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - } - break; - - default: - /* Permit null conversion to same output space */ - if (cinfo->out_color_space == cinfo->jpeg_color_space) { - cinfo->out_color_components = cinfo->num_components; - cconvert->pub.color_convert = null_convert; - } else /* unsupported non-null conversion */ - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - break; - } - - if (cinfo->quantize_colors) - cinfo->output_components = 1; /* single colormapped output component */ - else - cinfo->output_components = cinfo->out_color_components; -} diff --git a/libraries/jpeg/jdct.h b/libraries/jpeg/jdct.h deleted file mode 100644 index bcfedfcfd..000000000 --- a/libraries/jpeg/jdct.h +++ /dev/null @@ -1,416 +0,0 @@ -/* - * jdct.h - * - * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2002-2017 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This include file contains common declarations for the forward and - * inverse DCT modules. These declarations are private to the DCT managers - * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms. - * The individual DCT algorithms are kept in separate files to ease - * machine-dependent tuning (e.g., assembly coding). - */ - - -/* - * A forward DCT routine is given a pointer to an input sample array and - * a pointer to a work area of type DCTELEM[]; the DCT is to be performed - * in-place in that buffer. Type DCTELEM is int for 8-bit samples, INT32 - * for 12-bit samples. (NOTE: Floating-point DCT implementations use an - * array of type FAST_FLOAT, instead.) - * The input data is to be fetched from the sample array starting at a - * specified column. (Any row offset needed will be applied to the array - * pointer before it is passed to the FDCT code.) - * Note that the number of samples fetched by the FDCT routine is - * DCT_h_scaled_size * DCT_v_scaled_size. - * The DCT outputs are returned scaled up by a factor of 8; they therefore - * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This - * convention improves accuracy in integer implementations and saves some - * work in floating-point ones. - * Quantization of the output coefficients is done by jcdctmgr.c. - */ - -#if BITS_IN_JSAMPLE == 8 -typedef int DCTELEM; /* 16 or 32 bits is fine */ -#else -typedef INT32 DCTELEM; /* must have 32 bits */ -#endif - -typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data, - JSAMPARRAY sample_data, - JDIMENSION start_col)); -typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data, - JSAMPARRAY sample_data, - JDIMENSION start_col)); - - -/* - * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer - * to an output sample array. The routine must dequantize the input data as - * well as perform the IDCT; for dequantization, it uses the multiplier table - * pointed to by compptr->dct_table. The output data is to be placed into the - * sample array starting at a specified column. (Any row offset needed will - * be applied to the array pointer before it is passed to the IDCT code.) - * Note that the number of samples emitted by the IDCT routine is - * DCT_h_scaled_size * DCT_v_scaled_size. - */ - -/* typedef inverse_DCT_method_ptr is declared in jpegint.h */ - -/* - * Each IDCT routine has its own ideas about the best dct_table element type. - */ - -typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */ -#if BITS_IN_JSAMPLE == 8 -typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */ -#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */ -#else -typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */ -#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */ -#endif -typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ - - -/* - * Each IDCT routine is responsible for range-limiting its results and - * converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could - * be quite far out of range if the input data is corrupt, so a bulletproof - * range-limiting step is required. We use a mask-and-table-lookup method - * to do the combined operations quickly, assuming that RANGE_CENTER - * (defined in jpegint.h) is a power of 2. See the comments with - * prepare_range_limit_table (in jdmaster.c) for more info. - */ - -#define RANGE_MASK (RANGE_CENTER * 2 - 1) -#define RANGE_SUBSET (RANGE_CENTER - CENTERJSAMPLE) - -#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit - RANGE_SUBSET) - - -/* Short forms of external names for systems with brain-damaged linkers. */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_fdct_islow jFDislow -#define jpeg_fdct_ifast jFDifast -#define jpeg_fdct_float jFDfloat -#define jpeg_fdct_7x7 jFD7x7 -#define jpeg_fdct_6x6 jFD6x6 -#define jpeg_fdct_5x5 jFD5x5 -#define jpeg_fdct_4x4 jFD4x4 -#define jpeg_fdct_3x3 jFD3x3 -#define jpeg_fdct_2x2 jFD2x2 -#define jpeg_fdct_1x1 jFD1x1 -#define jpeg_fdct_9x9 jFD9x9 -#define jpeg_fdct_10x10 jFD10x10 -#define jpeg_fdct_11x11 jFD11x11 -#define jpeg_fdct_12x12 jFD12x12 -#define jpeg_fdct_13x13 jFD13x13 -#define jpeg_fdct_14x14 jFD14x14 -#define jpeg_fdct_15x15 jFD15x15 -#define jpeg_fdct_16x16 jFD16x16 -#define jpeg_fdct_16x8 jFD16x8 -#define jpeg_fdct_14x7 jFD14x7 -#define jpeg_fdct_12x6 jFD12x6 -#define jpeg_fdct_10x5 jFD10x5 -#define jpeg_fdct_8x4 jFD8x4 -#define jpeg_fdct_6x3 jFD6x3 -#define jpeg_fdct_4x2 jFD4x2 -#define jpeg_fdct_2x1 jFD2x1 -#define jpeg_fdct_8x16 jFD8x16 -#define jpeg_fdct_7x14 jFD7x14 -#define jpeg_fdct_6x12 jFD6x12 -#define jpeg_fdct_5x10 jFD5x10 -#define jpeg_fdct_4x8 jFD4x8 -#define jpeg_fdct_3x6 jFD3x6 -#define jpeg_fdct_2x4 jFD2x4 -#define jpeg_fdct_1x2 jFD1x2 -#define jpeg_idct_islow jRDislow -#define jpeg_idct_ifast jRDifast -#define jpeg_idct_float jRDfloat -#define jpeg_idct_7x7 jRD7x7 -#define jpeg_idct_6x6 jRD6x6 -#define jpeg_idct_5x5 jRD5x5 -#define jpeg_idct_4x4 jRD4x4 -#define jpeg_idct_3x3 jRD3x3 -#define jpeg_idct_2x2 jRD2x2 -#define jpeg_idct_1x1 jRD1x1 -#define jpeg_idct_9x9 jRD9x9 -#define jpeg_idct_10x10 jRD10x10 -#define jpeg_idct_11x11 jRD11x11 -#define jpeg_idct_12x12 jRD12x12 -#define jpeg_idct_13x13 jRD13x13 -#define jpeg_idct_14x14 jRD14x14 -#define jpeg_idct_15x15 jRD15x15 -#define jpeg_idct_16x16 jRD16x16 -#define jpeg_idct_16x8 jRD16x8 -#define jpeg_idct_14x7 jRD14x7 -#define jpeg_idct_12x6 jRD12x6 -#define jpeg_idct_10x5 jRD10x5 -#define jpeg_idct_8x4 jRD8x4 -#define jpeg_idct_6x3 jRD6x3 -#define jpeg_idct_4x2 jRD4x2 -#define jpeg_idct_2x1 jRD2x1 -#define jpeg_idct_8x16 jRD8x16 -#define jpeg_idct_7x14 jRD7x14 -#define jpeg_idct_6x12 jRD6x12 -#define jpeg_idct_5x10 jRD5x10 -#define jpeg_idct_4x8 jRD4x8 -#define jpeg_idct_3x6 jRD3x8 -#define jpeg_idct_2x4 jRD2x4 -#define jpeg_idct_1x2 jRD1x2 -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - -/* Extern declarations for the forward and inverse DCT routines. */ - -EXTERN(void) jpeg_fdct_islow - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_ifast - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_float - JPP((FAST_FLOAT * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_7x7 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_6x6 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_5x5 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_4x4 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_3x3 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_2x2 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_1x1 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_9x9 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_10x10 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_11x11 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_12x12 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_13x13 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_14x14 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_15x15 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_16x16 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_16x8 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_14x7 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_12x6 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_10x5 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_8x4 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_6x3 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_4x2 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_2x1 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_8x16 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_7x14 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_6x12 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_5x10 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_4x8 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_3x6 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_2x4 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); -EXTERN(void) jpeg_fdct_1x2 - JPP((DCTELEM * data, JSAMPARRAY sample_data, JDIMENSION start_col)); - -EXTERN(void) jpeg_idct_islow - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_ifast - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_float - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_7x7 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_6x6 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_5x5 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_4x4 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_3x3 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_2x2 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_1x1 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_9x9 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_10x10 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_11x11 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_12x12 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_13x13 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_14x14 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_15x15 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_16x16 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_16x8 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_14x7 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_12x6 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_10x5 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_8x4 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_6x3 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_4x2 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_2x1 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_8x16 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_7x14 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_6x12 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_5x10 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_4x8 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_3x6 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_2x4 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); -EXTERN(void) jpeg_idct_1x2 - JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); - - -/* - * Macros for handling fixed-point arithmetic; these are used by many - * but not all of the DCT/IDCT modules. - * - * All values are expected to be of type INT32. - * Fractional constants are scaled left by CONST_BITS bits. - * CONST_BITS is defined within each module using these macros, - * and may differ from one module to the next. - */ - -#define ONE ((INT32) 1) -#define CONST_SCALE (ONE << CONST_BITS) - -/* Convert a positive real constant to an integer scaled by CONST_SCALE. - * Caution: some C compilers fail to reduce "FIX(constant)" at compile time, - * thus causing a lot of useless floating-point operations at run time. - */ - -#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5)) - -/* Descale and correctly round an INT32 value that's scaled by N bits. - * We assume RIGHT_SHIFT rounds towards minus infinity, so adding - * the fudge factor is correct for either sign of X. - */ - -#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n) - -/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. - * This macro is used only when the two inputs will actually be no more than - * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a - * full 32x32 multiply. This provides a useful speedup on many machines. - * Unfortunately there is no way to specify a 16x16->32 multiply portably - * in C, but some C compilers will do the right thing if you provide the - * correct combination of casts. - */ - -#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ -#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const))) -#endif -#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ -#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const))) -#endif - -#ifndef MULTIPLY16C16 /* default definition */ -#define MULTIPLY16C16(var,const) ((var) * (const)) -#endif - -/* Same except both inputs are variables. */ - -#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ -#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2))) -#endif - -#ifndef MULTIPLY16V16 /* default definition */ -#define MULTIPLY16V16(var1,var2) ((var1) * (var2)) -#endif - -/* Like RIGHT_SHIFT, but applies to a DCTELEM. - * We assume that int right shift is unsigned if INT32 right shift is. - */ - -#ifdef RIGHT_SHIFT_IS_UNSIGNED -#define ISHIFT_TEMPS DCTELEM ishift_temp; -#if BITS_IN_JSAMPLE == 8 -#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */ -#else -#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */ -#endif -#define IRIGHT_SHIFT(x,shft) \ - ((ishift_temp = (x)) < 0 ? \ - (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \ - (ishift_temp >> (shft))) -#else -#define ISHIFT_TEMPS -#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) -#endif diff --git a/libraries/jpeg/jddctmgr.c b/libraries/jpeg/jddctmgr.c deleted file mode 100644 index 9ecfbb510..000000000 --- a/libraries/jpeg/jddctmgr.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * jddctmgr.c - * - * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2002-2013 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the inverse-DCT management logic. - * This code selects a particular IDCT implementation to be used, - * and it performs related housekeeping chores. No code in this file - * is executed per IDCT step, only during output pass setup. - * - * Note that the IDCT routines are responsible for performing coefficient - * dequantization as well as the IDCT proper. This module sets up the - * dequantization multiplier table needed by the IDCT routine. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - - -/* - * The decompressor input side (jdinput.c) saves away the appropriate - * quantization table for each component at the start of the first scan - * involving that component. (This is necessary in order to correctly - * decode files that reuse Q-table slots.) - * When we are ready to make an output pass, the saved Q-table is converted - * to a multiplier table that will actually be used by the IDCT routine. - * The multiplier table contents are IDCT-method-dependent. To support - * application changes in IDCT method between scans, we can remake the - * multiplier tables if necessary. - * In buffered-image mode, the first output pass may occur before any data - * has been seen for some components, and thus before their Q-tables have - * been saved away. To handle this case, multiplier tables are preset - * to zeroes; the result of the IDCT will be a neutral gray level. - */ - - -/* Private subobject for this module */ - -typedef struct { - struct jpeg_inverse_dct pub; /* public fields */ - - /* This array contains the IDCT method code that each multiplier table - * is currently set up for, or -1 if it's not yet set up. - * The actual multiplier tables are pointed to by dct_table in the - * per-component comp_info structures. - */ - int cur_method[MAX_COMPONENTS]; -} my_idct_controller; - -typedef my_idct_controller * my_idct_ptr; - - -/* Allocated multiplier tables: big enough for any supported variant */ - -typedef union { - ISLOW_MULT_TYPE islow_array[DCTSIZE2]; -#ifdef DCT_IFAST_SUPPORTED - IFAST_MULT_TYPE ifast_array[DCTSIZE2]; -#endif -#ifdef DCT_FLOAT_SUPPORTED - FLOAT_MULT_TYPE float_array[DCTSIZE2]; -#endif -} multiplier_table; - - -/* The current scaled-IDCT routines require ISLOW-style multiplier tables, - * so be sure to compile that code if either ISLOW or SCALING is requested. - */ -#ifdef DCT_ISLOW_SUPPORTED -#define PROVIDE_ISLOW_TABLES -#else -#ifdef IDCT_SCALING_SUPPORTED -#define PROVIDE_ISLOW_TABLES -#endif -#endif - - -/* - * Prepare for an output pass. - * Here we select the proper IDCT routine for each component and build - * a matching multiplier table. - */ - -METHODDEF(void) -start_pass (j_decompress_ptr cinfo) -{ - my_idct_ptr idct = (my_idct_ptr) cinfo->idct; - int ci, i; - jpeg_component_info *compptr; - int method = 0; - inverse_DCT_method_ptr method_ptr = NULL; - JQUANT_TBL * qtbl; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Select the proper IDCT routine for this component's scaling */ - switch ((compptr->DCT_h_scaled_size << 8) + compptr->DCT_v_scaled_size) { -#ifdef IDCT_SCALING_SUPPORTED - case ((1 << 8) + 1): - method_ptr = jpeg_idct_1x1; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((2 << 8) + 2): - method_ptr = jpeg_idct_2x2; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((3 << 8) + 3): - method_ptr = jpeg_idct_3x3; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((4 << 8) + 4): - method_ptr = jpeg_idct_4x4; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((5 << 8) + 5): - method_ptr = jpeg_idct_5x5; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((6 << 8) + 6): - method_ptr = jpeg_idct_6x6; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((7 << 8) + 7): - method_ptr = jpeg_idct_7x7; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((9 << 8) + 9): - method_ptr = jpeg_idct_9x9; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((10 << 8) + 10): - method_ptr = jpeg_idct_10x10; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((11 << 8) + 11): - method_ptr = jpeg_idct_11x11; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((12 << 8) + 12): - method_ptr = jpeg_idct_12x12; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((13 << 8) + 13): - method_ptr = jpeg_idct_13x13; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((14 << 8) + 14): - method_ptr = jpeg_idct_14x14; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((15 << 8) + 15): - method_ptr = jpeg_idct_15x15; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((16 << 8) + 16): - method_ptr = jpeg_idct_16x16; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((16 << 8) + 8): - method_ptr = jpeg_idct_16x8; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((14 << 8) + 7): - method_ptr = jpeg_idct_14x7; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((12 << 8) + 6): - method_ptr = jpeg_idct_12x6; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((10 << 8) + 5): - method_ptr = jpeg_idct_10x5; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((8 << 8) + 4): - method_ptr = jpeg_idct_8x4; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((6 << 8) + 3): - method_ptr = jpeg_idct_6x3; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((4 << 8) + 2): - method_ptr = jpeg_idct_4x2; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((2 << 8) + 1): - method_ptr = jpeg_idct_2x1; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((8 << 8) + 16): - method_ptr = jpeg_idct_8x16; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((7 << 8) + 14): - method_ptr = jpeg_idct_7x14; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((6 << 8) + 12): - method_ptr = jpeg_idct_6x12; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((5 << 8) + 10): - method_ptr = jpeg_idct_5x10; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((4 << 8) + 8): - method_ptr = jpeg_idct_4x8; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((3 << 8) + 6): - method_ptr = jpeg_idct_3x6; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((2 << 8) + 4): - method_ptr = jpeg_idct_2x4; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; - case ((1 << 8) + 2): - method_ptr = jpeg_idct_1x2; - method = JDCT_ISLOW; /* jidctint uses islow-style table */ - break; -#endif - case ((DCTSIZE << 8) + DCTSIZE): - switch (cinfo->dct_method) { -#ifdef DCT_ISLOW_SUPPORTED - case JDCT_ISLOW: - method_ptr = jpeg_idct_islow; - method = JDCT_ISLOW; - break; -#endif -#ifdef DCT_IFAST_SUPPORTED - case JDCT_IFAST: - method_ptr = jpeg_idct_ifast; - method = JDCT_IFAST; - break; -#endif -#ifdef DCT_FLOAT_SUPPORTED - case JDCT_FLOAT: - method_ptr = jpeg_idct_float; - method = JDCT_FLOAT; - break; -#endif - default: - ERREXIT(cinfo, JERR_NOT_COMPILED); - break; - } - break; - default: - ERREXIT2(cinfo, JERR_BAD_DCTSIZE, - compptr->DCT_h_scaled_size, compptr->DCT_v_scaled_size); - break; - } - idct->pub.inverse_DCT[ci] = method_ptr; - /* Create multiplier table from quant table. - * However, we can skip this if the component is uninteresting - * or if we already built the table. Also, if no quant table - * has yet been saved for the component, we leave the - * multiplier table all-zero; we'll be reading zeroes from the - * coefficient controller's buffer anyway. - */ - if (! compptr->component_needed || idct->cur_method[ci] == method) - continue; - qtbl = compptr->quant_table; - if (qtbl == NULL) /* happens if no data yet for component */ - continue; - idct->cur_method[ci] = method; - switch (method) { -#ifdef PROVIDE_ISLOW_TABLES - case JDCT_ISLOW: - { - /* For LL&M IDCT method, multipliers are equal to raw quantization - * coefficients, but are stored as ints to ensure access efficiency. - */ - ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table; - for (i = 0; i < DCTSIZE2; i++) { - ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i]; - } - } - break; -#endif -#ifdef DCT_IFAST_SUPPORTED - case JDCT_IFAST: - { - /* For AA&N IDCT method, multipliers are equal to quantization - * coefficients scaled by scalefactor[row]*scalefactor[col], where - * scalefactor[0] = 1 - * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 - * For integer operation, the multiplier table is to be scaled by - * IFAST_SCALE_BITS. - */ - IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; -#define CONST_BITS 14 - static const INT16 aanscales[DCTSIZE2] = { - /* precomputed values scaled up by 14 bits */ - 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, - 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, - 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, - 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, - 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, - 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, - 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, - 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 - }; - SHIFT_TEMPS - - for (i = 0; i < DCTSIZE2; i++) { - ifmtbl[i] = (IFAST_MULT_TYPE) - DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], - (INT32) aanscales[i]), - CONST_BITS-IFAST_SCALE_BITS); - } - } - break; -#endif -#ifdef DCT_FLOAT_SUPPORTED - case JDCT_FLOAT: - { - /* For float AA&N IDCT method, multipliers are equal to quantization - * coefficients scaled by scalefactor[row]*scalefactor[col], where - * scalefactor[0] = 1 - * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 - * We apply a further scale factor of 1/8. - */ - FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table; - int row, col; - static const double aanscalefactor[DCTSIZE] = { - 1.0, 1.387039845, 1.306562965, 1.175875602, - 1.0, 0.785694958, 0.541196100, 0.275899379 - }; - - i = 0; - for (row = 0; row < DCTSIZE; row++) { - for (col = 0; col < DCTSIZE; col++) { - fmtbl[i] = (FLOAT_MULT_TYPE) - ((double) qtbl->quantval[i] * - aanscalefactor[row] * aanscalefactor[col] * 0.125); - i++; - } - } - } - break; -#endif - default: - ERREXIT(cinfo, JERR_NOT_COMPILED); - break; - } - } -} - - -/* - * Initialize IDCT manager. - */ - -GLOBAL(void) -jinit_inverse_dct (j_decompress_ptr cinfo) -{ - my_idct_ptr idct; - int ci; - jpeg_component_info *compptr; - - idct = (my_idct_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_idct_controller)); - cinfo->idct = &idct->pub; - idct->pub.start_pass = start_pass; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Allocate and pre-zero a multiplier table for each component */ - compptr->dct_table = - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(multiplier_table)); - MEMZERO(compptr->dct_table, SIZEOF(multiplier_table)); - /* Mark multiplier table not yet set up for any method */ - idct->cur_method[ci] = -1; - } -} diff --git a/libraries/jpeg/jdhuff.c b/libraries/jpeg/jdhuff.c deleted file mode 100644 index 835d06ecb..000000000 --- a/libraries/jpeg/jdhuff.c +++ /dev/null @@ -1,1553 +0,0 @@ -/* - * jdhuff.c - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2006-2016 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains Huffman entropy decoding routines. - * Both sequential and progressive modes are supported in this single module. - * - * Much of the complexity here has to do with supporting input suspension. - * If the data source module demands suspension, we want to be able to back - * up to the start of the current MCU. To do this, we copy state variables - * into local working storage, and update them back to the permanent - * storage only upon successful completion of an MCU. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Derived data constructed for each Huffman table */ - -#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ - -typedef struct { - /* Basic tables: (element [0] of each array is unused) */ - INT32 maxcode[18]; /* largest code of length k (-1 if none) */ - /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */ - INT32 valoffset[17]; /* huffval[] offset for codes of length k */ - /* valoffset[k] = huffval[] index of 1st symbol of code length k, less - * the smallest code of length k; so given a code of length k, the - * corresponding symbol is huffval[code + valoffset[k]] - */ - - /* Link to public Huffman table (needed only in jpeg_huff_decode) */ - JHUFF_TBL *pub; - - /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of - * the input data stream. If the next Huffman code is no more - * than HUFF_LOOKAHEAD bits long, we can obtain its length and - * the corresponding symbol directly from these tables. - */ - int look_nbits[1< 32 bits on your machine, and shifting/masking longs is - * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE - * appropriately should be a win. Unfortunately we can't define the size - * with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8) - * because not all machines measure sizeof in 8-bit bytes. - */ - -typedef struct { /* Bitreading state saved across MCUs */ - bit_buf_type get_buffer; /* current bit-extraction buffer */ - int bits_left; /* # of unused bits in it */ -} bitread_perm_state; - -typedef struct { /* Bitreading working state within an MCU */ - /* Current data source location */ - /* We need a copy, rather than munging the original, in case of suspension */ - const JOCTET * next_input_byte; /* => next byte to read from source */ - size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ - /* Bit input buffer --- note these values are kept in register variables, - * not in this struct, inside the inner loops. - */ - bit_buf_type get_buffer; /* current bit-extraction buffer */ - int bits_left; /* # of unused bits in it */ - /* Pointer needed by jpeg_fill_bit_buffer. */ - j_decompress_ptr cinfo; /* back link to decompress master record */ -} bitread_working_state; - -/* Macros to declare and load/save bitread local variables. */ -#define BITREAD_STATE_VARS \ - register bit_buf_type get_buffer; \ - register int bits_left; \ - bitread_working_state br_state - -#define BITREAD_LOAD_STATE(cinfop,permstate) \ - br_state.cinfo = cinfop; \ - br_state.next_input_byte = cinfop->src->next_input_byte; \ - br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ - get_buffer = permstate.get_buffer; \ - bits_left = permstate.bits_left; - -#define BITREAD_SAVE_STATE(cinfop,permstate) \ - cinfop->src->next_input_byte = br_state.next_input_byte; \ - cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ - permstate.get_buffer = get_buffer; \ - permstate.bits_left = bits_left - -/* - * These macros provide the in-line portion of bit fetching. - * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer - * before using GET_BITS, PEEK_BITS, or DROP_BITS. - * The variables get_buffer and bits_left are assumed to be locals, - * but the state struct might not be (jpeg_huff_decode needs this). - * CHECK_BIT_BUFFER(state,n,action); - * Ensure there are N bits in get_buffer; if suspend, take action. - * val = GET_BITS(n); - * Fetch next N bits. - * val = PEEK_BITS(n); - * Fetch next N bits without removing them from the buffer. - * DROP_BITS(n); - * Discard next N bits. - * The value N should be a simple variable, not an expression, because it - * is evaluated multiple times. - */ - -#define CHECK_BIT_BUFFER(state,nbits,action) \ - { if (bits_left < (nbits)) { \ - if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \ - { action; } \ - get_buffer = (state).get_buffer; bits_left = (state).bits_left; } } - -#define GET_BITS(nbits) \ - (((int) (get_buffer >> (bits_left -= (nbits)))) & BIT_MASK(nbits)) - -#define PEEK_BITS(nbits) \ - (((int) (get_buffer >> (bits_left - (nbits)))) & BIT_MASK(nbits)) - -#define DROP_BITS(nbits) \ - (bits_left -= (nbits)) - - -/* - * Code for extracting next Huffman-coded symbol from input bit stream. - * Again, this is time-critical and we make the main paths be macros. - * - * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits - * without looping. Usually, more than 95% of the Huffman codes will be 8 - * or fewer bits long. The few overlength codes are handled with a loop, - * which need not be inline code. - * - * Notes about the HUFF_DECODE macro: - * 1. Near the end of the data segment, we may fail to get enough bits - * for a lookahead. In that case, we do it the hard way. - * 2. If the lookahead table contains no entry, the next code must be - * more than HUFF_LOOKAHEAD bits long. - * 3. jpeg_huff_decode returns -1 if forced to suspend. - */ - -#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \ -{ register int nb, look; \ - if (bits_left < HUFF_LOOKAHEAD) { \ - if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \ - get_buffer = state.get_buffer; bits_left = state.bits_left; \ - if (bits_left < HUFF_LOOKAHEAD) { \ - nb = 1; goto slowlabel; \ - } \ - } \ - look = PEEK_BITS(HUFF_LOOKAHEAD); \ - if ((nb = htbl->look_nbits[look]) != 0) { \ - DROP_BITS(nb); \ - result = htbl->look_sym[look]; \ - } else { \ - nb = HUFF_LOOKAHEAD+1; \ -slowlabel: \ - if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \ - { failaction; } \ - get_buffer = state.get_buffer; bits_left = state.bits_left; \ - } \ -} - - -/* - * Expanded entropy decoder object for Huffman decoding. - * - * The savable_state subrecord contains fields that change within an MCU, - * but must not be updated permanently until we complete the MCU. - */ - -typedef struct { - unsigned int EOBRUN; /* remaining EOBs in EOBRUN */ - int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ -} savable_state; - -/* This macro is to work around compilers with missing or broken - * structure assignment. You'll need to fix this code if you have - * such a compiler and you change MAX_COMPS_IN_SCAN. - */ - -#ifndef NO_STRUCT_ASSIGN -#define ASSIGN_STATE(dest,src) ((dest) = (src)) -#else -#if MAX_COMPS_IN_SCAN == 4 -#define ASSIGN_STATE(dest,src) \ - ((dest).EOBRUN = (src).EOBRUN, \ - (dest).last_dc_val[0] = (src).last_dc_val[0], \ - (dest).last_dc_val[1] = (src).last_dc_val[1], \ - (dest).last_dc_val[2] = (src).last_dc_val[2], \ - (dest).last_dc_val[3] = (src).last_dc_val[3]) -#endif -#endif - - -typedef struct { - struct jpeg_entropy_decoder pub; /* public fields */ - - /* These fields are loaded into local variables at start of each MCU. - * In case of suspension, we exit WITHOUT updating them. - */ - bitread_perm_state bitstate; /* Bit buffer at start of MCU */ - savable_state saved; /* Other state at start of MCU */ - - /* These fields are NOT loaded into local working state. */ - boolean insufficient_data; /* set TRUE after emitting warning */ - unsigned int restarts_to_go; /* MCUs left in this restart interval */ - - /* Following two fields used only in progressive mode */ - - /* Pointers to derived tables (these workspaces have image lifespan) */ - d_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; - - d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */ - - /* Following fields used only in sequential mode */ - - /* Pointers to derived tables (these workspaces have image lifespan) */ - d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; - d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; - - /* Precalculated info set up by start_pass for use in decode_mcu: */ - - /* Pointers to derived tables to be used for each block within an MCU */ - d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU]; - d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU]; - /* Whether we care about the DC and AC coefficient values for each block */ - int coef_limit[D_MAX_BLOCKS_IN_MCU]; -} huff_entropy_decoder; - -typedef huff_entropy_decoder * huff_entropy_ptr; - - -static const int jpeg_zigzag_order[8][8] = { - { 0, 1, 5, 6, 14, 15, 27, 28 }, - { 2, 4, 7, 13, 16, 26, 29, 42 }, - { 3, 8, 12, 17, 25, 30, 41, 43 }, - { 9, 11, 18, 24, 31, 40, 44, 53 }, - { 10, 19, 23, 32, 39, 45, 52, 54 }, - { 20, 22, 33, 38, 46, 51, 55, 60 }, - { 21, 34, 37, 47, 50, 56, 59, 61 }, - { 35, 36, 48, 49, 57, 58, 62, 63 } -}; - -static const int jpeg_zigzag_order7[7][7] = { - { 0, 1, 5, 6, 14, 15, 27 }, - { 2, 4, 7, 13, 16, 26, 28 }, - { 3, 8, 12, 17, 25, 29, 38 }, - { 9, 11, 18, 24, 30, 37, 39 }, - { 10, 19, 23, 31, 36, 40, 45 }, - { 20, 22, 32, 35, 41, 44, 46 }, - { 21, 33, 34, 42, 43, 47, 48 } -}; - -static const int jpeg_zigzag_order6[6][6] = { - { 0, 1, 5, 6, 14, 15 }, - { 2, 4, 7, 13, 16, 25 }, - { 3, 8, 12, 17, 24, 26 }, - { 9, 11, 18, 23, 27, 32 }, - { 10, 19, 22, 28, 31, 33 }, - { 20, 21, 29, 30, 34, 35 } -}; - -static const int jpeg_zigzag_order5[5][5] = { - { 0, 1, 5, 6, 14 }, - { 2, 4, 7, 13, 15 }, - { 3, 8, 12, 16, 21 }, - { 9, 11, 17, 20, 22 }, - { 10, 18, 19, 23, 24 } -}; - -static const int jpeg_zigzag_order4[4][4] = { - { 0, 1, 5, 6 }, - { 2, 4, 7, 12 }, - { 3, 8, 11, 13 }, - { 9, 10, 14, 15 } -}; - -static const int jpeg_zigzag_order3[3][3] = { - { 0, 1, 5 }, - { 2, 4, 6 }, - { 3, 7, 8 } -}; - -static const int jpeg_zigzag_order2[2][2] = { - { 0, 1 }, - { 2, 3 } -}; - - -/* - * Compute the derived values for a Huffman table. - * This routine also performs some validation checks on the table. - */ - -LOCAL(void) -jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno, - d_derived_tbl ** pdtbl) -{ - JHUFF_TBL *htbl; - d_derived_tbl *dtbl; - int p, i, l, si, numsymbols; - int lookbits, ctr; - char huffsize[257]; - unsigned int huffcode[257]; - unsigned int code; - - /* Note that huffsize[] and huffcode[] are filled in code-length order, - * paralleling the order of the symbols themselves in htbl->huffval[]. - */ - - /* Find the input Huffman table */ - if (tblno < 0 || tblno >= NUM_HUFF_TBLS) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); - htbl = - isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno]; - if (htbl == NULL) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno); - - /* Allocate a workspace if we haven't already done so. */ - if (*pdtbl == NULL) - *pdtbl = (d_derived_tbl *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(d_derived_tbl)); - dtbl = *pdtbl; - dtbl->pub = htbl; /* fill in back link */ - - /* Figure C.1: make table of Huffman code length for each symbol */ - - p = 0; - for (l = 1; l <= 16; l++) { - i = (int) htbl->bits[l]; - if (i < 0 || p + i > 256) /* protect against table overrun */ - ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); - while (i--) - huffsize[p++] = (char) l; - } - huffsize[p] = 0; - numsymbols = p; - - /* Figure C.2: generate the codes themselves */ - /* We also validate that the counts represent a legal Huffman code tree. */ - - code = 0; - si = huffsize[0]; - p = 0; - while (huffsize[p]) { - while (((int) huffsize[p]) == si) { - huffcode[p++] = code; - code++; - } - /* code is now 1 more than the last code used for codelength si; but - * it must still fit in si bits, since no code is allowed to be all ones. - */ - if (((INT32) code) >= (((INT32) 1) << si)) - ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); - code <<= 1; - si++; - } - - /* Figure F.15: generate decoding tables for bit-sequential decoding */ - - p = 0; - for (l = 1; l <= 16; l++) { - if (htbl->bits[l]) { - /* valoffset[l] = huffval[] index of 1st symbol of code length l, - * minus the minimum code of length l - */ - dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p]; - p += htbl->bits[l]; - dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */ - } else { - dtbl->maxcode[l] = -1; /* -1 if no codes of this length */ - } - } - dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */ - - /* Compute lookahead tables to speed up decoding. - * First we set all the table entries to 0, indicating "too long"; - * then we iterate through the Huffman codes that are short enough and - * fill in all the entries that correspond to bit sequences starting - * with that code. - */ - - MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits)); - - p = 0; - for (l = 1; l <= HUFF_LOOKAHEAD; l++) { - for (i = 1; i <= (int) htbl->bits[l]; i++, p++) { - /* l = current code's length, p = its index in huffcode[] & huffval[]. */ - /* Generate left-justified code followed by all possible bit sequences */ - lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l); - for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) { - dtbl->look_nbits[lookbits] = l; - dtbl->look_sym[lookbits] = htbl->huffval[p]; - lookbits++; - } - } - } - - /* Validate symbols as being reasonable. - * For AC tables, we make no check, but accept all byte values 0..255. - * For DC tables, we require the symbols to be in range 0..15. - * (Tighter bounds could be applied depending on the data depth and mode, - * but this is sufficient to ensure safe decoding.) - */ - if (isDC) { - for (i = 0; i < numsymbols; i++) { - int sym = htbl->huffval[i]; - if (sym < 0 || sym > 15) - ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); - } - } -} - - -/* - * Out-of-line code for bit fetching. - * Note: current values of get_buffer and bits_left are passed as parameters, - * but are returned in the corresponding fields of the state struct. - * - * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width - * of get_buffer to be used. (On machines with wider words, an even larger - * buffer could be used.) However, on some machines 32-bit shifts are - * quite slow and take time proportional to the number of places shifted. - * (This is true with most PC compilers, for instance.) In this case it may - * be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the - * average shift distance at the cost of more calls to jpeg_fill_bit_buffer. - */ - -#ifdef SLOW_SHIFT_32 -#define MIN_GET_BITS 15 /* minimum allowable value */ -#else -#define MIN_GET_BITS (BIT_BUF_SIZE-7) -#endif - - -LOCAL(boolean) -jpeg_fill_bit_buffer (bitread_working_state * state, - register bit_buf_type get_buffer, register int bits_left, - int nbits) -/* Load up the bit buffer to a depth of at least nbits */ -{ - /* Copy heavily used state fields into locals (hopefully registers) */ - register const JOCTET * next_input_byte = state->next_input_byte; - register size_t bytes_in_buffer = state->bytes_in_buffer; - j_decompress_ptr cinfo = state->cinfo; - - /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */ - /* (It is assumed that no request will be for more than that many bits.) */ - /* We fail to do so only if we hit a marker or are forced to suspend. */ - - if (cinfo->unread_marker == 0) { /* cannot advance past a marker */ - while (bits_left < MIN_GET_BITS) { - register int c; - - /* Attempt to read a byte */ - if (bytes_in_buffer == 0) { - if (! (*cinfo->src->fill_input_buffer) (cinfo)) - return FALSE; - next_input_byte = cinfo->src->next_input_byte; - bytes_in_buffer = cinfo->src->bytes_in_buffer; - } - bytes_in_buffer--; - c = GETJOCTET(*next_input_byte++); - - /* If it's 0xFF, check and discard stuffed zero byte */ - if (c == 0xFF) { - /* Loop here to discard any padding FF's on terminating marker, - * so that we can save a valid unread_marker value. NOTE: we will - * accept multiple FF's followed by a 0 as meaning a single FF data - * byte. This data pattern is not valid according to the standard. - */ - do { - if (bytes_in_buffer == 0) { - if (! (*cinfo->src->fill_input_buffer) (cinfo)) - return FALSE; - next_input_byte = cinfo->src->next_input_byte; - bytes_in_buffer = cinfo->src->bytes_in_buffer; - } - bytes_in_buffer--; - c = GETJOCTET(*next_input_byte++); - } while (c == 0xFF); - - if (c == 0) { - /* Found FF/00, which represents an FF data byte */ - c = 0xFF; - } else { - /* Oops, it's actually a marker indicating end of compressed data. - * Save the marker code for later use. - * Fine point: it might appear that we should save the marker into - * bitread working state, not straight into permanent state. But - * once we have hit a marker, we cannot need to suspend within the - * current MCU, because we will read no more bytes from the data - * source. So it is OK to update permanent state right away. - */ - cinfo->unread_marker = c; - /* See if we need to insert some fake zero bits. */ - goto no_more_bytes; - } - } - - /* OK, load c into get_buffer */ - get_buffer = (get_buffer << 8) | c; - bits_left += 8; - } /* end while */ - } else { - no_more_bytes: - /* We get here if we've read the marker that terminates the compressed - * data segment. There should be enough bits in the buffer register - * to satisfy the request; if so, no problem. - */ - if (nbits > bits_left) { - /* Uh-oh. Report corrupted data to user and stuff zeroes into - * the data stream, so that we can produce some kind of image. - * We use a nonvolatile flag to ensure that only one warning message - * appears per data segment. - */ - if (! ((huff_entropy_ptr) cinfo->entropy)->insufficient_data) { - WARNMS(cinfo, JWRN_HIT_MARKER); - ((huff_entropy_ptr) cinfo->entropy)->insufficient_data = TRUE; - } - /* Fill the buffer with zero bits */ - get_buffer <<= MIN_GET_BITS - bits_left; - bits_left = MIN_GET_BITS; - } - } - - /* Unload the local registers */ - state->next_input_byte = next_input_byte; - state->bytes_in_buffer = bytes_in_buffer; - state->get_buffer = get_buffer; - state->bits_left = bits_left; - - return TRUE; -} - - -/* - * Figure F.12: extend sign bit. - * On some machines, a shift and sub will be faster than a table lookup. - */ - -#ifdef AVOID_TABLES - -#define BIT_MASK(nbits) ((1<<(nbits))-1) -#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) - ((1<<(s))-1) : (x)) - -#else - -#define BIT_MASK(nbits) bmask[nbits] -#define HUFF_EXTEND(x,s) ((x) <= bmask[(s) - 1] ? (x) - bmask[s] : (x)) - -static const int bmask[16] = /* bmask[n] is mask for n rightmost bits */ - { 0, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, - 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF }; - -#endif /* AVOID_TABLES */ - - -/* - * Out-of-line code for Huffman code decoding. - */ - -LOCAL(int) -jpeg_huff_decode (bitread_working_state * state, - register bit_buf_type get_buffer, register int bits_left, - d_derived_tbl * htbl, int min_bits) -{ - register int l = min_bits; - register INT32 code; - - /* HUFF_DECODE has determined that the code is at least min_bits */ - /* bits long, so fetch that many bits in one swoop. */ - - CHECK_BIT_BUFFER(*state, l, return -1); - code = GET_BITS(l); - - /* Collect the rest of the Huffman code one bit at a time. */ - /* This is per Figure F.16 in the JPEG spec. */ - - while (code > htbl->maxcode[l]) { - code <<= 1; - CHECK_BIT_BUFFER(*state, 1, return -1); - code |= GET_BITS(1); - l++; - } - - /* Unload the local registers */ - state->get_buffer = get_buffer; - state->bits_left = bits_left; - - /* With garbage input we may reach the sentinel value l = 17. */ - - if (l > 16) { - WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE); - return 0; /* fake a zero as the safest result */ - } - - return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ]; -} - - -/* - * Finish up at the end of a Huffman-compressed scan. - */ - -METHODDEF(void) -finish_pass_huff (j_decompress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - - /* Throw away any unused bits remaining in bit buffer; */ - /* include any full bytes in next_marker's count of discarded bytes */ - cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; - entropy->bitstate.bits_left = 0; -} - - -/* - * Check for a restart marker & resynchronize decoder. - * Returns FALSE if must suspend. - */ - -LOCAL(boolean) -process_restart (j_decompress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci; - - finish_pass_huff(cinfo); - - /* Advance past the RSTn marker */ - if (! (*cinfo->marker->read_restart_marker) (cinfo)) - return FALSE; - - /* Re-initialize DC predictions to 0 */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) - entropy->saved.last_dc_val[ci] = 0; - /* Re-init EOB run count, too */ - entropy->saved.EOBRUN = 0; - - /* Reset restart counter */ - entropy->restarts_to_go = cinfo->restart_interval; - - /* Reset out-of-data flag, unless read_restart_marker left us smack up - * against a marker. In that case we will end up treating the next data - * segment as empty, and we can avoid producing bogus output pixels by - * leaving the flag set. - */ - if (cinfo->unread_marker == 0) - entropy->insufficient_data = FALSE; - - return TRUE; -} - - -/* - * Huffman MCU decoding. - * Each of these routines decodes and returns one MCU's worth of - * Huffman-compressed coefficients. - * The coefficients are reordered from zigzag order into natural array order, - * but are not dequantized. - * - * The i'th block of the MCU is stored into the block pointed to by - * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. - * (Wholesale zeroing is usually a little faster than retail...) - * - * We return FALSE if data source requested suspension. In that case no - * changes have been made to permanent state. (Exception: some output - * coefficients may already have been assigned. This is harmless for - * spectral selection, since we'll just re-assign them on the next call. - * Successive approximation AC refinement has to be more careful, however.) - */ - -/* - * MCU decoding for DC initial scan (either spectral selection, - * or first pass of successive approximation). - */ - -METHODDEF(boolean) -decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int Al = cinfo->Al; - register int s, r; - int blkn, ci; - JBLOCKROW block; - BITREAD_STATE_VARS; - savable_state state; - d_derived_tbl * tbl; - jpeg_component_info * compptr; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* If we've run out of data, just leave the MCU set to zeroes. - * This way, we return uniform gray for the remainder of the segment. - */ - if (! entropy->insufficient_data) { - - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(state, entropy->saved); - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - block = MCU_data[blkn]; - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - tbl = entropy->derived_tbls[compptr->dc_tbl_no]; - - /* Decode a single block's worth of coefficients */ - - /* Section F.2.2.1: decode the DC coefficient difference */ - HUFF_DECODE(s, br_state, tbl, return FALSE, label1); - if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - } - - /* Convert DC difference to actual value, update last_dc_val */ - s += state.last_dc_val[ci]; - state.last_dc_val[ci] = s; - /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */ - (*block)[0] = (JCOEF) (s << Al); - } - - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); - } - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; -} - - -/* - * MCU decoding for AC initial scan (either spectral selection, - * or first pass of successive approximation). - */ - -METHODDEF(boolean) -decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - register int s, k, r; - unsigned int EOBRUN; - int Se, Al; - const int * natural_order; - JBLOCKROW block; - BITREAD_STATE_VARS; - d_derived_tbl * tbl; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* If we've run out of data, just leave the MCU set to zeroes. - * This way, we return uniform gray for the remainder of the segment. - */ - if (! entropy->insufficient_data) { - - /* Load up working state. - * We can avoid loading/saving bitread state if in an EOB run. - */ - EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ - - /* There is always only one block per MCU */ - - if (EOBRUN) /* if it's a band of zeroes... */ - EOBRUN--; /* ...process it now (we do nothing) */ - else { - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - Se = cinfo->Se; - Al = cinfo->Al; - natural_order = cinfo->natural_order; - block = MCU_data[0]; - tbl = entropy->ac_derived_tbl; - - for (k = cinfo->Ss; k <= Se; k++) { - HUFF_DECODE(s, br_state, tbl, return FALSE, label2); - r = s >> 4; - s &= 15; - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - /* Scale and output coefficient in natural (dezigzagged) order */ - (*block)[natural_order[k]] = (JCOEF) (s << Al); - } else { - if (r != 15) { /* EOBr, run length is 2^r + appended bits */ - if (r) { /* EOBr, r > 0 */ - EOBRUN = 1 << r; - CHECK_BIT_BUFFER(br_state, r, return FALSE); - r = GET_BITS(r); - EOBRUN += r; - EOBRUN--; /* this band is processed at this moment */ - } - break; /* force end-of-band */ - } - k += 15; /* ZRL: skip 15 zeroes in band */ - } - } - - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - } - - /* Completed MCU, so update state */ - entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ - } - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; -} - - -/* - * MCU decoding for DC successive approximation refinement scan. - * Note: we assume such scans can be multi-component, - * although the spec is not very clear on the point. - */ - -METHODDEF(boolean) -decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int p1, blkn; - BITREAD_STATE_VARS; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* Not worth the cycles to check insufficient_data here, - * since we will not change the data anyway if we read zeroes. - */ - - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - - p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - /* Encoded data is simply the next bit of the two's-complement DC value */ - CHECK_BIT_BUFFER(br_state, 1, return FALSE); - if (GET_BITS(1)) - MCU_data[blkn][0][0] |= p1; - /* Note: since we use |=, repeating the assignment later is safe */ - } - - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; -} - - -/* - * MCU decoding for AC successive approximation refinement scan. - */ - -METHODDEF(boolean) -decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - register int s, k, r; - unsigned int EOBRUN; - int Se, p1, m1; - const int * natural_order; - JBLOCKROW block; - JCOEFPTR thiscoef; - BITREAD_STATE_VARS; - d_derived_tbl * tbl; - int num_newnz; - int newnz_pos[DCTSIZE2]; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* If we've run out of data, don't modify the MCU. - */ - if (! entropy->insufficient_data) { - - Se = cinfo->Se; - p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ - m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ - natural_order = cinfo->natural_order; - - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ - - /* There is always only one block per MCU */ - block = MCU_data[0]; - tbl = entropy->ac_derived_tbl; - - /* If we are forced to suspend, we must undo the assignments to any newly - * nonzero coefficients in the block, because otherwise we'd get confused - * next time about which coefficients were already nonzero. - * But we need not undo addition of bits to already-nonzero coefficients; - * instead, we can test the current bit to see if we already did it. - */ - num_newnz = 0; - - /* initialize coefficient loop counter to start of band */ - k = cinfo->Ss; - - if (EOBRUN == 0) { - do { - HUFF_DECODE(s, br_state, tbl, goto undoit, label3); - r = s >> 4; - s &= 15; - if (s) { - if (s != 1) /* size of new coef should always be 1 */ - WARNMS(cinfo, JWRN_HUFF_BAD_CODE); - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) - s = p1; /* newly nonzero coef is positive */ - else - s = m1; /* newly nonzero coef is negative */ - } else { - if (r != 15) { - EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ - if (r) { - CHECK_BIT_BUFFER(br_state, r, goto undoit); - r = GET_BITS(r); - EOBRUN += r; - } - break; /* rest of block is handled by EOB logic */ - } - /* note s = 0 for processing ZRL */ - } - /* Advance over already-nonzero coefs and r still-zero coefs, - * appending correction bits to the nonzeroes. A correction bit is 1 - * if the absolute value of the coefficient must be increased. - */ - do { - thiscoef = *block + natural_order[k]; - if (*thiscoef) { - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) { - if ((*thiscoef & p1) == 0) { /* do nothing if already set it */ - if (*thiscoef >= 0) - *thiscoef += p1; - else - *thiscoef += m1; - } - } - } else { - if (--r < 0) - break; /* reached target zero coefficient */ - } - k++; - } while (k <= Se); - if (s) { - int pos = natural_order[k]; - /* Output newly nonzero coefficient */ - (*block)[pos] = (JCOEF) s; - /* Remember its position in case we have to suspend */ - newnz_pos[num_newnz++] = pos; - } - k++; - } while (k <= Se); - } - - if (EOBRUN) { - /* Scan any remaining coefficient positions after the end-of-band - * (the last newly nonzero coefficient, if any). Append a correction - * bit to each already-nonzero coefficient. A correction bit is 1 - * if the absolute value of the coefficient must be increased. - */ - do { - thiscoef = *block + natural_order[k]; - if (*thiscoef) { - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) { - if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ - if (*thiscoef >= 0) - *thiscoef += p1; - else - *thiscoef += m1; - } - } - } - k++; - } while (k <= Se); - /* Count one block completed in EOB run */ - EOBRUN--; - } - - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ - } - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; - -undoit: - /* Re-zero any output coefficients that we made newly nonzero */ - while (num_newnz) - (*block)[newnz_pos[--num_newnz]] = 0; - - return FALSE; -} - - -/* - * Decode one MCU's worth of Huffman-compressed coefficients, - * partial blocks. - */ - -METHODDEF(boolean) -decode_mcu_sub (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - const int * natural_order; - int Se, blkn; - BITREAD_STATE_VARS; - savable_state state; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* If we've run out of data, just leave the MCU set to zeroes. - * This way, we return uniform gray for the remainder of the segment. - */ - if (! entropy->insufficient_data) { - - natural_order = cinfo->natural_order; - Se = cinfo->lim_Se; - - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(state, entropy->saved); - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - JBLOCKROW block = MCU_data[blkn]; - d_derived_tbl * htbl; - register int s, k, r; - int coef_limit, ci; - - /* Decode a single block's worth of coefficients */ - - /* Section F.2.2.1: decode the DC coefficient difference */ - htbl = entropy->dc_cur_tbls[blkn]; - HUFF_DECODE(s, br_state, htbl, return FALSE, label1); - - htbl = entropy->ac_cur_tbls[blkn]; - k = 1; - coef_limit = entropy->coef_limit[blkn]; - if (coef_limit) { - /* Convert DC difference to actual value, update last_dc_val */ - if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - } - ci = cinfo->MCU_membership[blkn]; - s += state.last_dc_val[ci]; - state.last_dc_val[ci] = s; - /* Output the DC coefficient */ - (*block)[0] = (JCOEF) s; - - /* Section F.2.2.2: decode the AC coefficients */ - /* Since zeroes are skipped, output area must be cleared beforehand */ - for (; k < coef_limit; k++) { - HUFF_DECODE(s, br_state, htbl, return FALSE, label2); - - r = s >> 4; - s &= 15; - - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - /* Output coefficient in natural (dezigzagged) order. - * Note: the extra entries in natural_order[] will save us - * if k > Se, which could happen if the data is corrupted. - */ - (*block)[natural_order[k]] = (JCOEF) s; - } else { - if (r != 15) - goto EndOfBlock; - k += 15; - } - } - } else { - if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - DROP_BITS(s); - } - } - - /* Section F.2.2.2: decode the AC coefficients */ - /* In this path we just discard the values */ - for (; k <= Se; k++) { - HUFF_DECODE(s, br_state, htbl, return FALSE, label3); - - r = s >> 4; - s &= 15; - - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - DROP_BITS(s); - } else { - if (r != 15) - break; - k += 15; - } - } - - EndOfBlock: ; - } - - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); - } - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; -} - - -/* - * Decode one MCU's worth of Huffman-compressed coefficients, - * full-size blocks. - */ - -METHODDEF(boolean) -decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int blkn; - BITREAD_STATE_VARS; - savable_state state; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* If we've run out of data, just leave the MCU set to zeroes. - * This way, we return uniform gray for the remainder of the segment. - */ - if (! entropy->insufficient_data) { - - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(state, entropy->saved); - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - JBLOCKROW block = MCU_data[blkn]; - d_derived_tbl * htbl; - register int s, k, r; - int coef_limit, ci; - - /* Decode a single block's worth of coefficients */ - - /* Section F.2.2.1: decode the DC coefficient difference */ - htbl = entropy->dc_cur_tbls[blkn]; - HUFF_DECODE(s, br_state, htbl, return FALSE, label1); - - htbl = entropy->ac_cur_tbls[blkn]; - k = 1; - coef_limit = entropy->coef_limit[blkn]; - if (coef_limit) { - /* Convert DC difference to actual value, update last_dc_val */ - if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - } - ci = cinfo->MCU_membership[blkn]; - s += state.last_dc_val[ci]; - state.last_dc_val[ci] = s; - /* Output the DC coefficient */ - (*block)[0] = (JCOEF) s; - - /* Section F.2.2.2: decode the AC coefficients */ - /* Since zeroes are skipped, output area must be cleared beforehand */ - for (; k < coef_limit; k++) { - HUFF_DECODE(s, br_state, htbl, return FALSE, label2); - - r = s >> 4; - s &= 15; - - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - /* Output coefficient in natural (dezigzagged) order. - * Note: the extra entries in jpeg_natural_order[] will save us - * if k >= DCTSIZE2, which could happen if the data is corrupted. - */ - (*block)[jpeg_natural_order[k]] = (JCOEF) s; - } else { - if (r != 15) - goto EndOfBlock; - k += 15; - } - } - } else { - if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - DROP_BITS(s); - } - } - - /* Section F.2.2.2: decode the AC coefficients */ - /* In this path we just discard the values */ - for (; k < DCTSIZE2; k++) { - HUFF_DECODE(s, br_state, htbl, return FALSE, label3); - - r = s >> 4; - s &= 15; - - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - DROP_BITS(s); - } else { - if (r != 15) - break; - k += 15; - } - } - - EndOfBlock: ; - } - - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); - } - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; -} - - -/* - * Initialize for a Huffman-compressed scan. - */ - -METHODDEF(void) -start_pass_huff_decoder (j_decompress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci, blkn, tbl, i; - jpeg_component_info * compptr; - - if (cinfo->progressive_mode) { - /* Validate progressive scan parameters */ - if (cinfo->Ss == 0) { - if (cinfo->Se != 0) - goto bad; - } else { - /* need not check Ss/Se < 0 since they came from unsigned bytes */ - if (cinfo->Se < cinfo->Ss || cinfo->Se > cinfo->lim_Se) - goto bad; - /* AC scans may have only one component */ - if (cinfo->comps_in_scan != 1) - goto bad; - } - if (cinfo->Ah != 0) { - /* Successive approximation refinement scan: must have Al = Ah-1. */ - if (cinfo->Ah-1 != cinfo->Al) - goto bad; - } - if (cinfo->Al > 13) { /* need not check for < 0 */ - /* Arguably the maximum Al value should be less than 13 for 8-bit precision, - * but the spec doesn't say so, and we try to be liberal about what we - * accept. Note: large Al values could result in out-of-range DC - * coefficients during early scans, leading to bizarre displays due to - * overflows in the IDCT math. But we won't crash. - */ - bad: - ERREXIT4(cinfo, JERR_BAD_PROGRESSION, - cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); - } - /* Update progression status, and verify that scan order is legal. - * Note that inter-scan inconsistencies are treated as warnings - * not fatal errors ... not clear if this is right way to behave. - */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - int coefi, cindex = cinfo->cur_comp_info[ci]->component_index; - int *coef_bit_ptr = & cinfo->coef_bits[cindex][0]; - if (cinfo->Ss && coef_bit_ptr[0] < 0) /* AC without prior DC scan */ - WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0); - for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { - int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; - if (cinfo->Ah != expected) - WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi); - coef_bit_ptr[coefi] = cinfo->Al; - } - } - - /* Select MCU decoding routine */ - if (cinfo->Ah == 0) { - if (cinfo->Ss == 0) - entropy->pub.decode_mcu = decode_mcu_DC_first; - else - entropy->pub.decode_mcu = decode_mcu_AC_first; - } else { - if (cinfo->Ss == 0) - entropy->pub.decode_mcu = decode_mcu_DC_refine; - else - entropy->pub.decode_mcu = decode_mcu_AC_refine; - } - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* Make sure requested tables are present, and compute derived tables. - * We may build same derived table more than once, but it's not expensive. - */ - if (cinfo->Ss == 0) { - if (cinfo->Ah == 0) { /* DC refinement needs no table */ - tbl = compptr->dc_tbl_no; - jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, - & entropy->derived_tbls[tbl]); - } - } else { - tbl = compptr->ac_tbl_no; - jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, - & entropy->derived_tbls[tbl]); - /* remember the single active table */ - entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; - } - /* Initialize DC predictions to 0 */ - entropy->saved.last_dc_val[ci] = 0; - } - - /* Initialize private state variables */ - entropy->saved.EOBRUN = 0; - } else { - /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. - * This ought to be an error condition, but we make it a warning because - * there are some baseline files out there with all zeroes in these bytes. - */ - if (cinfo->Ss != 0 || cinfo->Ah != 0 || cinfo->Al != 0 || - ((cinfo->is_baseline || cinfo->Se < DCTSIZE2) && - cinfo->Se != cinfo->lim_Se)) - WARNMS(cinfo, JWRN_NOT_SEQUENTIAL); - - /* Select MCU decoding routine */ - /* We retain the hard-coded case for full-size blocks. - * This is not necessary, but it appears that this version is slightly - * more performant in the given implementation. - * With an improved implementation we would prefer a single optimized - * function. - */ - if (cinfo->lim_Se != DCTSIZE2-1) - entropy->pub.decode_mcu = decode_mcu_sub; - else - entropy->pub.decode_mcu = decode_mcu; - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* Compute derived values for Huffman tables */ - /* We may do this more than once for a table, but it's not expensive */ - tbl = compptr->dc_tbl_no; - jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, - & entropy->dc_derived_tbls[tbl]); - if (cinfo->lim_Se) { /* AC needs no table when not present */ - tbl = compptr->ac_tbl_no; - jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, - & entropy->ac_derived_tbls[tbl]); - } - /* Initialize DC predictions to 0 */ - entropy->saved.last_dc_val[ci] = 0; - } - - /* Precalculate decoding info for each block in an MCU of this scan */ - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - /* Precalculate which table to use for each block */ - entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no]; - entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no]; - /* Decide whether we really care about the coefficient values */ - if (compptr->component_needed) { - ci = compptr->DCT_v_scaled_size; - i = compptr->DCT_h_scaled_size; - switch (cinfo->lim_Se) { - case (1*1-1): - entropy->coef_limit[blkn] = 1; - break; - case (2*2-1): - if (ci <= 0 || ci > 2) ci = 2; - if (i <= 0 || i > 2) i = 2; - entropy->coef_limit[blkn] = 1 + jpeg_zigzag_order2[ci - 1][i - 1]; - break; - case (3*3-1): - if (ci <= 0 || ci > 3) ci = 3; - if (i <= 0 || i > 3) i = 3; - entropy->coef_limit[blkn] = 1 + jpeg_zigzag_order3[ci - 1][i - 1]; - break; - case (4*4-1): - if (ci <= 0 || ci > 4) ci = 4; - if (i <= 0 || i > 4) i = 4; - entropy->coef_limit[blkn] = 1 + jpeg_zigzag_order4[ci - 1][i - 1]; - break; - case (5*5-1): - if (ci <= 0 || ci > 5) ci = 5; - if (i <= 0 || i > 5) i = 5; - entropy->coef_limit[blkn] = 1 + jpeg_zigzag_order5[ci - 1][i - 1]; - break; - case (6*6-1): - if (ci <= 0 || ci > 6) ci = 6; - if (i <= 0 || i > 6) i = 6; - entropy->coef_limit[blkn] = 1 + jpeg_zigzag_order6[ci - 1][i - 1]; - break; - case (7*7-1): - if (ci <= 0 || ci > 7) ci = 7; - if (i <= 0 || i > 7) i = 7; - entropy->coef_limit[blkn] = 1 + jpeg_zigzag_order7[ci - 1][i - 1]; - break; - default: - if (ci <= 0 || ci > 8) ci = 8; - if (i <= 0 || i > 8) i = 8; - entropy->coef_limit[blkn] = 1 + jpeg_zigzag_order[ci - 1][i - 1]; - break; - } - } else { - entropy->coef_limit[blkn] = 0; - } - } - } - - /* Initialize bitread state variables */ - entropy->bitstate.bits_left = 0; - entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ - entropy->insufficient_data = FALSE; - - /* Initialize restart counter */ - entropy->restarts_to_go = cinfo->restart_interval; -} - - -/* - * Module initialization routine for Huffman entropy decoding. - */ - -GLOBAL(void) -jinit_huff_decoder (j_decompress_ptr cinfo) -{ - huff_entropy_ptr entropy; - int i; - - entropy = (huff_entropy_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(huff_entropy_decoder)); - cinfo->entropy = &entropy->pub; - entropy->pub.start_pass = start_pass_huff_decoder; - entropy->pub.finish_pass = finish_pass_huff; - - if (cinfo->progressive_mode) { - /* Create progression status table */ - int *coef_bit_ptr, ci; - cinfo->coef_bits = (int (*)[DCTSIZE2]) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components*DCTSIZE2*SIZEOF(int)); - coef_bit_ptr = & cinfo->coef_bits[0][0]; - for (ci = 0; ci < cinfo->num_components; ci++) - for (i = 0; i < DCTSIZE2; i++) - *coef_bit_ptr++ = -1; - - /* Mark derived tables unallocated */ - for (i = 0; i < NUM_HUFF_TBLS; i++) { - entropy->derived_tbls[i] = NULL; - } - } else { - /* Mark tables unallocated */ - for (i = 0; i < NUM_HUFF_TBLS; i++) { - entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; - } - } -} diff --git a/libraries/jpeg/jdinput.c b/libraries/jpeg/jdinput.c deleted file mode 100644 index 0199553e8..000000000 --- a/libraries/jpeg/jdinput.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * jdinput.c - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2002-2013 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains input control logic for the JPEG decompressor. - * These routines are concerned with controlling the decompressor's input - * processing (marker reading and coefficient decoding). The actual input - * reading is done in jdmarker.c, jdhuff.c, and jdarith.c. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Private state */ - -typedef struct { - struct jpeg_input_controller pub; /* public fields */ - - int inheaders; /* Nonzero until first SOS is reached */ -} my_input_controller; - -typedef my_input_controller * my_inputctl_ptr; - - -/* Forward declarations */ -METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo)); - - -/* - * Routines to calculate various quantities related to the size of the image. - */ - - -/* - * Compute output image dimensions and related values. - * NOTE: this is exported for possible use by application. - * Hence it mustn't do anything that can't be done twice. - */ - -GLOBAL(void) -jpeg_core_output_dimensions (j_decompress_ptr cinfo) -/* Do computations that are needed before master selection phase. - * This function is used for transcoding and full decompression. - */ -{ -#ifdef IDCT_SCALING_SUPPORTED - int ci; - jpeg_component_info *compptr; - - /* Compute actual output image dimensions and DCT scaling choices. */ - if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom) { - /* Provide 1/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 1; - cinfo->min_DCT_v_scaled_size = 1; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 2) { - /* Provide 2/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 2L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 2L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 2; - cinfo->min_DCT_v_scaled_size = 2; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 3) { - /* Provide 3/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 3L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 3L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 3; - cinfo->min_DCT_v_scaled_size = 3; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 4) { - /* Provide 4/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 4L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 4L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 4; - cinfo->min_DCT_v_scaled_size = 4; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 5) { - /* Provide 5/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 5L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 5L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 5; - cinfo->min_DCT_v_scaled_size = 5; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 6) { - /* Provide 6/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 6L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 6L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 6; - cinfo->min_DCT_v_scaled_size = 6; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 7) { - /* Provide 7/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 7L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 7L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 7; - cinfo->min_DCT_v_scaled_size = 7; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 8) { - /* Provide 8/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 8L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 8L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 8; - cinfo->min_DCT_v_scaled_size = 8; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 9) { - /* Provide 9/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 9L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 9L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 9; - cinfo->min_DCT_v_scaled_size = 9; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 10) { - /* Provide 10/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 10L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 10L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 10; - cinfo->min_DCT_v_scaled_size = 10; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 11) { - /* Provide 11/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 11L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 11L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 11; - cinfo->min_DCT_v_scaled_size = 11; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 12) { - /* Provide 12/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 12L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 12L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 12; - cinfo->min_DCT_v_scaled_size = 12; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 13) { - /* Provide 13/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 13L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 13L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 13; - cinfo->min_DCT_v_scaled_size = 13; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 14) { - /* Provide 14/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 14L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 14L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 14; - cinfo->min_DCT_v_scaled_size = 14; - } else if (cinfo->scale_num * cinfo->block_size <= cinfo->scale_denom * 15) { - /* Provide 15/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 15L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 15L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 15; - cinfo->min_DCT_v_scaled_size = 15; - } else { - /* Provide 16/block_size scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * 16L, (long) cinfo->block_size); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * 16L, (long) cinfo->block_size); - cinfo->min_DCT_h_scaled_size = 16; - cinfo->min_DCT_v_scaled_size = 16; - } - - /* Recompute dimensions of components */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size; - compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size; - } - -#else /* !IDCT_SCALING_SUPPORTED */ - - /* Hardwire it to "no scaling" */ - cinfo->output_width = cinfo->image_width; - cinfo->output_height = cinfo->image_height; - /* initial_setup has already initialized DCT_scaled_size, - * and has computed unscaled downsampled_width and downsampled_height. - */ - -#endif /* IDCT_SCALING_SUPPORTED */ -} - - -LOCAL(void) -initial_setup (j_decompress_ptr cinfo) -/* Called once, when first SOS marker is reached */ -{ - int ci; - jpeg_component_info *compptr; - - /* Make sure image isn't bigger than I can handle */ - if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION || - (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) - ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); - - /* Only 8 to 12 bits data precision are supported for DCT based JPEG */ - if (cinfo->data_precision < 8 || cinfo->data_precision > 12) - ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); - - /* Check that number of components won't exceed internal array sizes */ - if (cinfo->num_components > MAX_COMPONENTS) - ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, - MAX_COMPONENTS); - - /* Compute maximum sampling factors; check factor validity */ - cinfo->max_h_samp_factor = 1; - cinfo->max_v_samp_factor = 1; - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR || - compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR) - ERREXIT(cinfo, JERR_BAD_SAMPLING); - cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor, - compptr->h_samp_factor); - cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor, - compptr->v_samp_factor); - } - - /* Derive block_size, natural_order, and lim_Se */ - if (cinfo->is_baseline || (cinfo->progressive_mode && - cinfo->comps_in_scan)) { /* no pseudo SOS marker */ - cinfo->block_size = DCTSIZE; - cinfo->natural_order = jpeg_natural_order; - cinfo->lim_Se = DCTSIZE2-1; - } else - switch (cinfo->Se) { - case (1*1-1): - cinfo->block_size = 1; - cinfo->natural_order = jpeg_natural_order; /* not needed */ - cinfo->lim_Se = cinfo->Se; - break; - case (2*2-1): - cinfo->block_size = 2; - cinfo->natural_order = jpeg_natural_order2; - cinfo->lim_Se = cinfo->Se; - break; - case (3*3-1): - cinfo->block_size = 3; - cinfo->natural_order = jpeg_natural_order3; - cinfo->lim_Se = cinfo->Se; - break; - case (4*4-1): - cinfo->block_size = 4; - cinfo->natural_order = jpeg_natural_order4; - cinfo->lim_Se = cinfo->Se; - break; - case (5*5-1): - cinfo->block_size = 5; - cinfo->natural_order = jpeg_natural_order5; - cinfo->lim_Se = cinfo->Se; - break; - case (6*6-1): - cinfo->block_size = 6; - cinfo->natural_order = jpeg_natural_order6; - cinfo->lim_Se = cinfo->Se; - break; - case (7*7-1): - cinfo->block_size = 7; - cinfo->natural_order = jpeg_natural_order7; - cinfo->lim_Se = cinfo->Se; - break; - case (8*8-1): - cinfo->block_size = 8; - cinfo->natural_order = jpeg_natural_order; - cinfo->lim_Se = DCTSIZE2-1; - break; - case (9*9-1): - cinfo->block_size = 9; - cinfo->natural_order = jpeg_natural_order; - cinfo->lim_Se = DCTSIZE2-1; - break; - case (10*10-1): - cinfo->block_size = 10; - cinfo->natural_order = jpeg_natural_order; - cinfo->lim_Se = DCTSIZE2-1; - break; - case (11*11-1): - cinfo->block_size = 11; - cinfo->natural_order = jpeg_natural_order; - cinfo->lim_Se = DCTSIZE2-1; - break; - case (12*12-1): - cinfo->block_size = 12; - cinfo->natural_order = jpeg_natural_order; - cinfo->lim_Se = DCTSIZE2-1; - break; - case (13*13-1): - cinfo->block_size = 13; - cinfo->natural_order = jpeg_natural_order; - cinfo->lim_Se = DCTSIZE2-1; - break; - case (14*14-1): - cinfo->block_size = 14; - cinfo->natural_order = jpeg_natural_order; - cinfo->lim_Se = DCTSIZE2-1; - break; - case (15*15-1): - cinfo->block_size = 15; - cinfo->natural_order = jpeg_natural_order; - cinfo->lim_Se = DCTSIZE2-1; - break; - case (16*16-1): - cinfo->block_size = 16; - cinfo->natural_order = jpeg_natural_order; - cinfo->lim_Se = DCTSIZE2-1; - break; - default: - ERREXIT4(cinfo, JERR_BAD_PROGRESSION, - cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); - break; - } - - /* We initialize DCT_scaled_size and min_DCT_scaled_size to block_size. - * In the full decompressor, - * this will be overridden by jpeg_calc_output_dimensions in jdmaster.c; - * but in the transcoder, - * jpeg_calc_output_dimensions is not used, so we must do it here. - */ - cinfo->min_DCT_h_scaled_size = cinfo->block_size; - cinfo->min_DCT_v_scaled_size = cinfo->block_size; - - /* Compute dimensions of components */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - compptr->DCT_h_scaled_size = cinfo->block_size; - compptr->DCT_v_scaled_size = cinfo->block_size; - /* Size in DCT blocks */ - compptr->width_in_blocks = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, - (long) (cinfo->max_h_samp_factor * cinfo->block_size)); - compptr->height_in_blocks = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, - (long) (cinfo->max_v_samp_factor * cinfo->block_size)); - /* downsampled_width and downsampled_height will also be overridden by - * jdmaster.c if we are doing full decompression. The transcoder library - * doesn't use these values, but the calling application might. - */ - /* Size in samples */ - compptr->downsampled_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, - (long) cinfo->max_h_samp_factor); - compptr->downsampled_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, - (long) cinfo->max_v_samp_factor); - /* Mark component needed, until color conversion says otherwise */ - compptr->component_needed = TRUE; - /* Mark no quantization table yet saved for component */ - compptr->quant_table = NULL; - } - - /* Compute number of fully interleaved MCU rows. */ - cinfo->total_iMCU_rows = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor * cinfo->block_size)); - - /* Decide whether file contains multiple scans */ - if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode) - cinfo->inputctl->has_multiple_scans = TRUE; - else - cinfo->inputctl->has_multiple_scans = FALSE; -} - - -LOCAL(void) -per_scan_setup (j_decompress_ptr cinfo) -/* Do computations that are needed before processing a JPEG scan */ -/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */ -{ - int ci, mcublks, tmp; - jpeg_component_info *compptr; - - if (cinfo->comps_in_scan == 1) { - - /* Noninterleaved (single-component) scan */ - compptr = cinfo->cur_comp_info[0]; - - /* Overall image size in MCUs */ - cinfo->MCUs_per_row = compptr->width_in_blocks; - cinfo->MCU_rows_in_scan = compptr->height_in_blocks; - - /* For noninterleaved scan, always one block per MCU */ - compptr->MCU_width = 1; - compptr->MCU_height = 1; - compptr->MCU_blocks = 1; - compptr->MCU_sample_width = compptr->DCT_h_scaled_size; - compptr->last_col_width = 1; - /* For noninterleaved scans, it is convenient to define last_row_height - * as the number of block rows present in the last iMCU row. - */ - tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); - if (tmp == 0) tmp = compptr->v_samp_factor; - compptr->last_row_height = tmp; - - /* Prepare array describing MCU composition */ - cinfo->blocks_in_MCU = 1; - cinfo->MCU_membership[0] = 0; - - } else { - - /* Interleaved (multi-component) scan */ - if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN) - ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan, - MAX_COMPS_IN_SCAN); - - /* Overall image size in MCUs */ - cinfo->MCUs_per_row = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width, - (long) (cinfo->max_h_samp_factor * cinfo->block_size)); - cinfo->MCU_rows_in_scan = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor * cinfo->block_size)); - - cinfo->blocks_in_MCU = 0; - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* Sampling factors give # of blocks of component in each MCU */ - compptr->MCU_width = compptr->h_samp_factor; - compptr->MCU_height = compptr->v_samp_factor; - compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; - compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_h_scaled_size; - /* Figure number of non-dummy blocks in last MCU column & row */ - tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); - if (tmp == 0) tmp = compptr->MCU_width; - compptr->last_col_width = tmp; - tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); - if (tmp == 0) tmp = compptr->MCU_height; - compptr->last_row_height = tmp; - /* Prepare array describing MCU composition */ - mcublks = compptr->MCU_blocks; - if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) - ERREXIT(cinfo, JERR_BAD_MCU_SIZE); - while (mcublks-- > 0) { - cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; - } - } - - } -} - - -/* - * Save away a copy of the Q-table referenced by each component present - * in the current scan, unless already saved during a prior scan. - * - * In a multiple-scan JPEG file, the encoder could assign different components - * the same Q-table slot number, but change table definitions between scans - * so that each component uses a different Q-table. (The IJG encoder is not - * currently capable of doing this, but other encoders might.) Since we want - * to be able to dequantize all the components at the end of the file, this - * means that we have to save away the table actually used for each component. - * We do this by copying the table at the start of the first scan containing - * the component. - * The JPEG spec prohibits the encoder from changing the contents of a Q-table - * slot between scans of a component using that slot. If the encoder does so - * anyway, this decoder will simply use the Q-table values that were current - * at the start of the first scan for the component. - * - * The decompressor output side looks only at the saved quant tables, - * not at the current Q-table slots. - */ - -LOCAL(void) -latch_quant_tables (j_decompress_ptr cinfo) -{ - int ci, qtblno; - jpeg_component_info *compptr; - JQUANT_TBL * qtbl; - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* No work if we already saved Q-table for this component */ - if (compptr->quant_table != NULL) - continue; - /* Make sure specified quantization table is present */ - qtblno = compptr->quant_tbl_no; - if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || - cinfo->quant_tbl_ptrs[qtblno] == NULL) - ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); - /* OK, save away the quantization table */ - qtbl = (JQUANT_TBL *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(JQUANT_TBL)); - MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); - compptr->quant_table = qtbl; - } -} - - -/* - * Initialize the input modules to read a scan of compressed data. - * The first call to this is done by jdmaster.c after initializing - * the entire decompressor (during jpeg_start_decompress). - * Subsequent calls come from consume_markers, below. - */ - -METHODDEF(void) -start_input_pass (j_decompress_ptr cinfo) -{ - per_scan_setup(cinfo); - latch_quant_tables(cinfo); - (*cinfo->entropy->start_pass) (cinfo); - (*cinfo->coef->start_input_pass) (cinfo); - cinfo->inputctl->consume_input = cinfo->coef->consume_data; -} - - -/* - * Finish up after inputting a compressed-data scan. - * This is called by the coefficient controller after it's read all - * the expected data of the scan. - */ - -METHODDEF(void) -finish_input_pass (j_decompress_ptr cinfo) -{ - (*cinfo->entropy->finish_pass) (cinfo); - cinfo->inputctl->consume_input = consume_markers; -} - - -/* - * Read JPEG markers before, between, or after compressed-data scans. - * Change state as necessary when a new scan is reached. - * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. - * - * The consume_input method pointer points either here or to the - * coefficient controller's consume_data routine, depending on whether - * we are reading a compressed data segment or inter-segment markers. - * - * Note: This function should NOT return a pseudo SOS marker (with zero - * component number) to the caller. A pseudo marker received by - * read_markers is processed and then skipped for other markers. - */ - -METHODDEF(int) -consume_markers (j_decompress_ptr cinfo) -{ - my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; - int val; - - if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */ - return JPEG_REACHED_EOI; - - for (;;) { /* Loop to pass pseudo SOS marker */ - val = (*cinfo->marker->read_markers) (cinfo); - - switch (val) { - case JPEG_REACHED_SOS: /* Found SOS */ - if (inputctl->inheaders) { /* 1st SOS */ - if (inputctl->inheaders == 1) - initial_setup(cinfo); - if (cinfo->comps_in_scan == 0) { /* pseudo SOS marker */ - inputctl->inheaders = 2; - break; - } - inputctl->inheaders = 0; - /* Note: start_input_pass must be called by jdmaster.c - * before any more input can be consumed. jdapimin.c is - * responsible for enforcing this sequencing. - */ - } else { /* 2nd or later SOS marker */ - if (! inputctl->pub.has_multiple_scans) - ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */ - if (cinfo->comps_in_scan == 0) /* unexpected pseudo SOS marker */ - break; - start_input_pass(cinfo); - } - return val; - case JPEG_REACHED_EOI: /* Found EOI */ - inputctl->pub.eoi_reached = TRUE; - if (inputctl->inheaders) { /* Tables-only datastream, apparently */ - if (cinfo->marker->saw_SOF) - ERREXIT(cinfo, JERR_SOF_NO_SOS); - } else { - /* Prevent infinite loop in coef ctlr's decompress_data routine - * if user set output_scan_number larger than number of scans. - */ - if (cinfo->output_scan_number > cinfo->input_scan_number) - cinfo->output_scan_number = cinfo->input_scan_number; - } - return val; - case JPEG_SUSPENDED: - return val; - default: - return val; - } - } -} - - -/* - * Reset state to begin a fresh datastream. - */ - -METHODDEF(void) -reset_input_controller (j_decompress_ptr cinfo) -{ - my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl; - - inputctl->pub.consume_input = consume_markers; - inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ - inputctl->pub.eoi_reached = FALSE; - inputctl->inheaders = 1; - /* Reset other modules */ - (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); - (*cinfo->marker->reset_marker_reader) (cinfo); - /* Reset progression state -- would be cleaner if entropy decoder did this */ - cinfo->coef_bits = NULL; -} - - -/* - * Initialize the input controller module. - * This is called only once, when the decompression object is created. - */ - -GLOBAL(void) -jinit_input_controller (j_decompress_ptr cinfo) -{ - my_inputctl_ptr inputctl; - - /* Create subobject in permanent pool */ - inputctl = (my_inputctl_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(my_input_controller)); - cinfo->inputctl = &inputctl->pub; - /* Initialize method pointers */ - inputctl->pub.consume_input = consume_markers; - inputctl->pub.reset_input_controller = reset_input_controller; - inputctl->pub.start_input_pass = start_input_pass; - inputctl->pub.finish_input_pass = finish_input_pass; - /* Initialize state: can't use reset_input_controller since we don't - * want to try to reset other modules yet. - */ - inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */ - inputctl->pub.eoi_reached = FALSE; - inputctl->inheaders = 1; -} diff --git a/libraries/jpeg/jdmainct.c b/libraries/jpeg/jdmainct.c deleted file mode 100644 index 4d738fbae..000000000 --- a/libraries/jpeg/jdmainct.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * jdmainct.c - * - * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2002-2016 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the main buffer controller for decompression. - * The main buffer lies between the JPEG decompressor proper and the - * post-processor; it holds downsampled data in the JPEG colorspace. - * - * Note that this code is bypassed in raw-data mode, since the application - * supplies the equivalent of the main buffer in that case. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * In the current system design, the main buffer need never be a full-image - * buffer; any full-height buffers will be found inside the coefficient or - * postprocessing controllers. Nonetheless, the main controller is not - * trivial. Its responsibility is to provide context rows for upsampling/ - * rescaling, and doing this in an efficient fashion is a bit tricky. - * - * Postprocessor input data is counted in "row groups". A row group is - * defined to be (v_samp_factor * DCT_v_scaled_size / min_DCT_v_scaled_size) - * sample rows of each component. (We require DCT_scaled_size values to be - * chosen such that these numbers are integers. In practice DCT_scaled_size - * values will likely be powers of two, so we actually have the stronger - * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.) - * Upsampling will typically produce max_v_samp_factor pixel rows from each - * row group (times any additional scale factor that the upsampler is - * applying). - * - * The coefficient controller will deliver data to us one iMCU row at a time; - * each iMCU row contains v_samp_factor * DCT_v_scaled_size sample rows, or - * exactly min_DCT_v_scaled_size row groups. (This amount of data corresponds - * to one row of MCUs when the image is fully interleaved.) Note that the - * number of sample rows varies across components, but the number of row - * groups does not. Some garbage sample rows may be included in the last iMCU - * row at the bottom of the image. - * - * Depending on the vertical scaling algorithm used, the upsampler may need - * access to the sample row(s) above and below its current input row group. - * The upsampler is required to set need_context_rows TRUE at global selection - * time if so. When need_context_rows is FALSE, this controller can simply - * obtain one iMCU row at a time from the coefficient controller and dole it - * out as row groups to the postprocessor. - * - * When need_context_rows is TRUE, this controller guarantees that the buffer - * passed to postprocessing contains at least one row group's worth of samples - * above and below the row group(s) being processed. Note that the context - * rows "above" the first passed row group appear at negative row offsets in - * the passed buffer. At the top and bottom of the image, the required - * context rows are manufactured by duplicating the first or last real sample - * row; this avoids having special cases in the upsampling inner loops. - * - * The amount of context is fixed at one row group just because that's a - * convenient number for this controller to work with. The existing - * upsamplers really only need one sample row of context. An upsampler - * supporting arbitrary output rescaling might wish for more than one row - * group of context when shrinking the image; tough, we don't handle that. - * (This is justified by the assumption that downsizing will be handled mostly - * by adjusting the DCT_scaled_size values, so that the actual scale factor at - * the upsample step needn't be much less than one.) - * - * To provide the desired context, we have to retain the last two row groups - * of one iMCU row while reading in the next iMCU row. (The last row group - * can't be processed until we have another row group for its below-context, - * and so we have to save the next-to-last group too for its above-context.) - * We could do this most simply by copying data around in our buffer, but - * that'd be very slow. We can avoid copying any data by creating a rather - * strange pointer structure. Here's how it works. We allocate a workspace - * consisting of M+2 row groups (where M = min_DCT_v_scaled_size is the number - * of row groups per iMCU row). We create two sets of redundant pointers to - * the workspace. Labeling the physical row groups 0 to M+1, the synthesized - * pointer lists look like this: - * M+1 M-1 - * master pointer --> 0 master pointer --> 0 - * 1 1 - * ... ... - * M-3 M-3 - * M-2 M - * M-1 M+1 - * M M-2 - * M+1 M-1 - * 0 0 - * We read alternate iMCU rows using each master pointer; thus the last two - * row groups of the previous iMCU row remain un-overwritten in the workspace. - * The pointer lists are set up so that the required context rows appear to - * be adjacent to the proper places when we pass the pointer lists to the - * upsampler. - * - * The above pictures describe the normal state of the pointer lists. - * At top and bottom of the image, we diddle the pointer lists to duplicate - * the first or last sample row as necessary (this is cheaper than copying - * sample rows around). - * - * This scheme breaks down if M < 2, ie, min_DCT_v_scaled_size is 1. In that - * situation each iMCU row provides only one row group so the buffering logic - * must be different (eg, we must read two iMCU rows before we can emit the - * first row group). For now, we simply do not support providing context - * rows when min_DCT_v_scaled_size is 1. That combination seems unlikely to - * be worth providing --- if someone wants a 1/8th-size preview, they probably - * want it quick and dirty, so a context-free upsampler is sufficient. - */ - - -/* Private buffer controller object */ - -typedef struct { - struct jpeg_d_main_controller pub; /* public fields */ - - /* Pointer to allocated workspace (M or M+2 row groups). */ - JSAMPARRAY buffer[MAX_COMPONENTS]; - - JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */ - JDIMENSION rowgroups_avail; /* row groups available to postprocessor */ - - /* Remaining fields are only used in the context case. */ - - boolean buffer_full; /* Have we gotten an iMCU row from decoder? */ - - /* These are the master pointers to the funny-order pointer lists. */ - JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */ - - int whichptr; /* indicates which pointer set is now in use */ - int context_state; /* process_data state machine status */ - JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */ -} my_main_controller; - -typedef my_main_controller * my_main_ptr; - -/* context_state values: */ -#define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */ -#define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */ -#define CTX_POSTPONED_ROW 2 /* feeding postponed row group */ - - -/* Forward declarations */ -METHODDEF(void) process_data_simple_main - JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); -METHODDEF(void) process_data_context_main - JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); -#ifdef QUANT_2PASS_SUPPORTED -METHODDEF(void) process_data_crank_post - JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)); -#endif - - -LOCAL(void) -alloc_funny_pointers (j_decompress_ptr cinfo) -/* Allocate space for the funny pointer lists. - * This is done only once, not once per pass. - */ -{ - my_main_ptr mainp = (my_main_ptr) cinfo->main; - int ci, rgroup; - int M = cinfo->min_DCT_v_scaled_size; - jpeg_component_info *compptr; - JSAMPARRAY xbuf; - - /* Get top-level space for component array pointers. - * We alloc both arrays with one call to save a few cycles. - */ - mainp->xbuffer[0] = (JSAMPIMAGE) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); - mainp->xbuffer[1] = mainp->xbuffer[0] + cinfo->num_components; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / - cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ - /* Get space for pointer lists --- M+4 row groups in each list. - * We alloc both pointer lists with one call to save a few cycles. - */ - xbuf = (JSAMPARRAY) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); - xbuf += rgroup; /* want one row group at negative offsets */ - mainp->xbuffer[0][ci] = xbuf; - xbuf += rgroup * (M + 4); - mainp->xbuffer[1][ci] = xbuf; - } -} - - -LOCAL(void) -make_funny_pointers (j_decompress_ptr cinfo) -/* Create the funny pointer lists discussed in the comments above. - * The actual workspace is already allocated (in mainp->buffer), - * and the space for the pointer lists is allocated too. - * This routine just fills in the curiously ordered lists. - * This will be repeated at the beginning of each pass. - */ -{ - my_main_ptr mainp = (my_main_ptr) cinfo->main; - int ci, i, rgroup; - int M = cinfo->min_DCT_v_scaled_size; - jpeg_component_info *compptr; - JSAMPARRAY buf, xbuf0, xbuf1; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / - cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ - xbuf0 = mainp->xbuffer[0][ci]; - xbuf1 = mainp->xbuffer[1][ci]; - /* First copy the workspace pointers as-is */ - buf = mainp->buffer[ci]; - for (i = 0; i < rgroup * (M + 2); i++) { - xbuf0[i] = xbuf1[i] = buf[i]; - } - /* In the second list, put the last four row groups in swapped order */ - for (i = 0; i < rgroup * 2; i++) { - xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i]; - xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i]; - } - /* The wraparound pointers at top and bottom will be filled later - * (see set_wraparound_pointers, below). Initially we want the "above" - * pointers to duplicate the first actual data line. This only needs - * to happen in xbuffer[0]. - */ - for (i = 0; i < rgroup; i++) { - xbuf0[i - rgroup] = xbuf0[0]; - } - } -} - - -LOCAL(void) -set_wraparound_pointers (j_decompress_ptr cinfo) -/* Set up the "wraparound" pointers at top and bottom of the pointer lists. - * This changes the pointer list state from top-of-image to the normal state. - */ -{ - my_main_ptr mainp = (my_main_ptr) cinfo->main; - int ci, i, rgroup; - int M = cinfo->min_DCT_v_scaled_size; - jpeg_component_info *compptr; - JSAMPARRAY xbuf0, xbuf1; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / - cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ - xbuf0 = mainp->xbuffer[0][ci]; - xbuf1 = mainp->xbuffer[1][ci]; - for (i = 0; i < rgroup; i++) { - xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; - xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; - xbuf0[rgroup*(M+2) + i] = xbuf0[i]; - xbuf1[rgroup*(M+2) + i] = xbuf1[i]; - } - } -} - - -LOCAL(void) -set_bottom_pointers (j_decompress_ptr cinfo) -/* Change the pointer lists to duplicate the last sample row at the bottom - * of the image. whichptr indicates which xbuffer holds the final iMCU row. - * Also sets rowgroups_avail to indicate number of nondummy row groups in row. - */ -{ - my_main_ptr mainp = (my_main_ptr) cinfo->main; - int ci, i, rgroup, iMCUheight, rows_left; - jpeg_component_info *compptr; - JSAMPARRAY xbuf; - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Count sample rows in one iMCU row and in one row group */ - iMCUheight = compptr->v_samp_factor * compptr->DCT_v_scaled_size; - rgroup = iMCUheight / cinfo->min_DCT_v_scaled_size; - /* Count nondummy sample rows remaining for this component */ - rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight); - if (rows_left == 0) rows_left = iMCUheight; - /* Count nondummy row groups. Should get same answer for each component, - * so we need only do it once. - */ - if (ci == 0) { - mainp->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); - } - /* Duplicate the last real sample row rgroup*2 times; this pads out the - * last partial rowgroup and ensures at least one full rowgroup of context. - */ - xbuf = mainp->xbuffer[mainp->whichptr][ci]; - for (i = 0; i < rgroup * 2; i++) { - xbuf[rows_left + i] = xbuf[rows_left-1]; - } - } -} - - -/* - * Initialize for a processing pass. - */ - -METHODDEF(void) -start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) -{ - my_main_ptr mainp = (my_main_ptr) cinfo->main; - - switch (pass_mode) { - case JBUF_PASS_THRU: - if (cinfo->upsample->need_context_rows) { - mainp->pub.process_data = process_data_context_main; - make_funny_pointers(cinfo); /* Create the xbuffer[] lists */ - mainp->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ - mainp->context_state = CTX_PREPARE_FOR_IMCU; - mainp->iMCU_row_ctr = 0; - mainp->buffer_full = FALSE; /* Mark buffer empty */ - } else { - /* Simple case with no context needed */ - mainp->pub.process_data = process_data_simple_main; - mainp->rowgroup_ctr = mainp->rowgroups_avail; /* Mark buffer empty */ - } - break; -#ifdef QUANT_2PASS_SUPPORTED - case JBUF_CRANK_DEST: - /* For last pass of 2-pass quantization, just crank the postprocessor */ - mainp->pub.process_data = process_data_crank_post; - break; -#endif - default: - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - break; - } -} - - -/* - * Process some data. - * This handles the simple case where no context is required. - */ - -METHODDEF(void) -process_data_simple_main (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - my_main_ptr mainp = (my_main_ptr) cinfo->main; - - /* Read input data if we haven't filled the main buffer yet */ - if (mainp->rowgroup_ctr >= mainp->rowgroups_avail) { - if (! (*cinfo->coef->decompress_data) (cinfo, mainp->buffer)) - return; /* suspension forced, can do nothing more */ - mainp->rowgroup_ctr = 0; /* OK, we have an iMCU row to work with */ - } - - /* Note: at the bottom of the image, we may pass extra garbage row groups - * to the postprocessor. The postprocessor has to check for bottom - * of image anyway (at row resolution), so no point in us doing it too. - */ - - /* Feed the postprocessor */ - (*cinfo->post->post_process_data) (cinfo, mainp->buffer, - &mainp->rowgroup_ctr, mainp->rowgroups_avail, - output_buf, out_row_ctr, out_rows_avail); -} - - -/* - * Process some data. - * This handles the case where context rows must be provided. - */ - -METHODDEF(void) -process_data_context_main (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - my_main_ptr mainp = (my_main_ptr) cinfo->main; - - /* Read input data if we haven't filled the main buffer yet */ - if (! mainp->buffer_full) { - if (! (*cinfo->coef->decompress_data) (cinfo, - mainp->xbuffer[mainp->whichptr])) - return; /* suspension forced, can do nothing more */ - mainp->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ - mainp->iMCU_row_ctr++; /* count rows received */ - } - - /* Postprocessor typically will not swallow all the input data it is handed - * in one call (due to filling the output buffer first). Must be prepared - * to exit and restart. This switch lets us keep track of how far we got. - * Note that each case falls through to the next on successful completion. - */ - switch (mainp->context_state) { - case CTX_POSTPONED_ROW: - /* Call postprocessor using previously set pointers for postponed row */ - (*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr], - &mainp->rowgroup_ctr, mainp->rowgroups_avail, - output_buf, out_row_ctr, out_rows_avail); - if (mainp->rowgroup_ctr < mainp->rowgroups_avail) - return; /* Need to suspend */ - mainp->context_state = CTX_PREPARE_FOR_IMCU; - if (*out_row_ctr >= out_rows_avail) - return; /* Postprocessor exactly filled output buf */ - /*FALLTHROUGH*/ - case CTX_PREPARE_FOR_IMCU: - /* Prepare to process first M-1 row groups of this iMCU row */ - mainp->rowgroup_ctr = 0; - mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size - 1); - /* Check for bottom of image: if so, tweak pointers to "duplicate" - * the last sample row, and adjust rowgroups_avail to ignore padding rows. - */ - if (mainp->iMCU_row_ctr == cinfo->total_iMCU_rows) - set_bottom_pointers(cinfo); - mainp->context_state = CTX_PROCESS_IMCU; - /*FALLTHROUGH*/ - case CTX_PROCESS_IMCU: - /* Call postprocessor using previously set pointers */ - (*cinfo->post->post_process_data) (cinfo, mainp->xbuffer[mainp->whichptr], - &mainp->rowgroup_ctr, mainp->rowgroups_avail, - output_buf, out_row_ctr, out_rows_avail); - if (mainp->rowgroup_ctr < mainp->rowgroups_avail) - return; /* Need to suspend */ - /* After the first iMCU, change wraparound pointers to normal state */ - if (mainp->iMCU_row_ctr == 1) - set_wraparound_pointers(cinfo); - /* Prepare to load new iMCU row using other xbuffer list */ - mainp->whichptr ^= 1; /* 0=>1 or 1=>0 */ - mainp->buffer_full = FALSE; - /* Still need to process last row group of this iMCU row, */ - /* which is saved at index M+1 of the other xbuffer */ - mainp->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 1); - mainp->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_v_scaled_size + 2); - mainp->context_state = CTX_POSTPONED_ROW; - } -} - - -/* - * Process some data. - * Final pass of two-pass quantization: just call the postprocessor. - * Source data will be the postprocessor controller's internal buffer. - */ - -#ifdef QUANT_2PASS_SUPPORTED - -METHODDEF(void) -process_data_crank_post (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL, - (JDIMENSION *) NULL, (JDIMENSION) 0, - output_buf, out_row_ctr, out_rows_avail); -} - -#endif /* QUANT_2PASS_SUPPORTED */ - - -/* - * Initialize main buffer controller. - */ - -GLOBAL(void) -jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) -{ - my_main_ptr mainp; - int ci, rgroup, ngroups; - jpeg_component_info *compptr; - - mainp = (my_main_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_main_controller)); - cinfo->main = &mainp->pub; - mainp->pub.start_pass = start_pass_main; - - if (need_full_buffer) /* shouldn't happen */ - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - - /* Allocate the workspace. - * ngroups is the number of row groups we need. - */ - if (cinfo->upsample->need_context_rows) { - if (cinfo->min_DCT_v_scaled_size < 2) /* unsupported, see comments above */ - ERREXIT(cinfo, JERR_NOTIMPL); - alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */ - ngroups = cinfo->min_DCT_v_scaled_size + 2; - } else { - /* There are always min_DCT_v_scaled_size row groups in an iMCU row. */ - ngroups = cinfo->min_DCT_v_scaled_size; - mainp->rowgroups_avail = (JDIMENSION) ngroups; - } - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / - cinfo->min_DCT_v_scaled_size; /* height of a row group of component */ - mainp->buffer[ci] = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - compptr->width_in_blocks * ((JDIMENSION) compptr->DCT_h_scaled_size), - (JDIMENSION) (rgroup * ngroups)); - } -} diff --git a/libraries/jpeg/jdmarker.c b/libraries/jpeg/jdmarker.c deleted file mode 100644 index 3fbe5c165..000000000 --- a/libraries/jpeg/jdmarker.c +++ /dev/null @@ -1,1511 +0,0 @@ -/* - * jdmarker.c - * - * Copyright (C) 1991-1998, Thomas G. Lane. - * Modified 2009-2013 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains routines to decode JPEG datastream markers. - * Most of the complexity arises from our desire to support input - * suspension: if not all of the data for a marker is available, - * we must exit back to the application. On resumption, we reprocess - * the marker. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -typedef enum { /* JPEG marker codes */ - M_SOF0 = 0xc0, - M_SOF1 = 0xc1, - M_SOF2 = 0xc2, - M_SOF3 = 0xc3, - - M_SOF5 = 0xc5, - M_SOF6 = 0xc6, - M_SOF7 = 0xc7, - - M_JPG = 0xc8, - M_SOF9 = 0xc9, - M_SOF10 = 0xca, - M_SOF11 = 0xcb, - - M_SOF13 = 0xcd, - M_SOF14 = 0xce, - M_SOF15 = 0xcf, - - M_DHT = 0xc4, - - M_DAC = 0xcc, - - M_RST0 = 0xd0, - M_RST1 = 0xd1, - M_RST2 = 0xd2, - M_RST3 = 0xd3, - M_RST4 = 0xd4, - M_RST5 = 0xd5, - M_RST6 = 0xd6, - M_RST7 = 0xd7, - - M_SOI = 0xd8, - M_EOI = 0xd9, - M_SOS = 0xda, - M_DQT = 0xdb, - M_DNL = 0xdc, - M_DRI = 0xdd, - M_DHP = 0xde, - M_EXP = 0xdf, - - M_APP0 = 0xe0, - M_APP1 = 0xe1, - M_APP2 = 0xe2, - M_APP3 = 0xe3, - M_APP4 = 0xe4, - M_APP5 = 0xe5, - M_APP6 = 0xe6, - M_APP7 = 0xe7, - M_APP8 = 0xe8, - M_APP9 = 0xe9, - M_APP10 = 0xea, - M_APP11 = 0xeb, - M_APP12 = 0xec, - M_APP13 = 0xed, - M_APP14 = 0xee, - M_APP15 = 0xef, - - M_JPG0 = 0xf0, - M_JPG8 = 0xf8, - M_JPG13 = 0xfd, - M_COM = 0xfe, - - M_TEM = 0x01, - - M_ERROR = 0x100 -} JPEG_MARKER; - - -/* Private state */ - -typedef struct { - struct jpeg_marker_reader pub; /* public fields */ - - /* Application-overridable marker processing methods */ - jpeg_marker_parser_method process_COM; - jpeg_marker_parser_method process_APPn[16]; - - /* Limit on marker data length to save for each marker type */ - unsigned int length_limit_COM; - unsigned int length_limit_APPn[16]; - - /* Status of COM/APPn marker saving */ - jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */ - unsigned int bytes_read; /* data bytes read so far in marker */ - /* Note: cur_marker is not linked into marker_list until it's all read. */ -} my_marker_reader; - -typedef my_marker_reader * my_marker_ptr; - - -/* - * Macros for fetching data from the data source module. - * - * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect - * the current restart point; we update them only when we have reached a - * suitable place to restart if a suspension occurs. - */ - -/* Declare and initialize local copies of input pointer/count */ -#define INPUT_VARS(cinfo) \ - struct jpeg_source_mgr * datasrc = (cinfo)->src; \ - const JOCTET * next_input_byte = datasrc->next_input_byte; \ - size_t bytes_in_buffer = datasrc->bytes_in_buffer - -/* Unload the local copies --- do this only at a restart boundary */ -#define INPUT_SYNC(cinfo) \ - ( datasrc->next_input_byte = next_input_byte, \ - datasrc->bytes_in_buffer = bytes_in_buffer ) - -/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */ -#define INPUT_RELOAD(cinfo) \ - ( next_input_byte = datasrc->next_input_byte, \ - bytes_in_buffer = datasrc->bytes_in_buffer ) - -/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. - * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, - * but we must reload the local copies after a successful fill. - */ -#define MAKE_BYTE_AVAIL(cinfo,action) \ - if (bytes_in_buffer == 0) { \ - if (! (*datasrc->fill_input_buffer) (cinfo)) \ - { action; } \ - INPUT_RELOAD(cinfo); \ - } - -/* Read a byte into variable V. - * If must suspend, take the specified action (typically "return FALSE"). - */ -#define INPUT_BYTE(cinfo,V,action) \ - MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ - bytes_in_buffer--; \ - V = GETJOCTET(*next_input_byte++); ) - -/* As above, but read two bytes interpreted as an unsigned 16-bit integer. - * V should be declared unsigned int or perhaps INT32. - */ -#define INPUT_2BYTES(cinfo,V,action) \ - MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ - bytes_in_buffer--; \ - V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ - MAKE_BYTE_AVAIL(cinfo,action); \ - bytes_in_buffer--; \ - V += GETJOCTET(*next_input_byte++); ) - - -/* - * Routines to process JPEG markers. - * - * Entry condition: JPEG marker itself has been read and its code saved - * in cinfo->unread_marker; input restart point is just after the marker. - * - * Exit: if return TRUE, have read and processed any parameters, and have - * updated the restart point to point after the parameters. - * If return FALSE, was forced to suspend before reaching end of - * marker parameters; restart point has not been moved. Same routine - * will be called again after application supplies more input data. - * - * This approach to suspension assumes that all of a marker's parameters - * can fit into a single input bufferload. This should hold for "normal" - * markers. Some COM/APPn markers might have large parameter segments - * that might not fit. If we are simply dropping such a marker, we use - * skip_input_data to get past it, and thereby put the problem on the - * source manager's shoulders. If we are saving the marker's contents - * into memory, we use a slightly different convention: when forced to - * suspend, the marker processor updates the restart point to the end of - * what it's consumed (ie, the end of the buffer) before returning FALSE. - * On resumption, cinfo->unread_marker still contains the marker code, - * but the data source will point to the next chunk of marker data. - * The marker processor must retain internal state to deal with this. - * - * Note that we don't bother to avoid duplicate trace messages if a - * suspension occurs within marker parameters. Other side effects - * require more care. - */ - - -LOCAL(boolean) -get_soi (j_decompress_ptr cinfo) -/* Process an SOI marker */ -{ - int i; - - TRACEMS(cinfo, 1, JTRC_SOI); - - if (cinfo->marker->saw_SOI) - ERREXIT(cinfo, JERR_SOI_DUPLICATE); - - /* Reset all parameters that are defined to be reset by SOI */ - - for (i = 0; i < NUM_ARITH_TBLS; i++) { - cinfo->arith_dc_L[i] = 0; - cinfo->arith_dc_U[i] = 1; - cinfo->arith_ac_K[i] = 5; - } - cinfo->restart_interval = 0; - - /* Set initial assumptions for colorspace etc */ - - cinfo->jpeg_color_space = JCS_UNKNOWN; - cinfo->color_transform = JCT_NONE; - cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */ - - cinfo->saw_JFIF_marker = FALSE; - cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */ - cinfo->JFIF_minor_version = 1; - cinfo->density_unit = 0; - cinfo->X_density = 1; - cinfo->Y_density = 1; - cinfo->saw_Adobe_marker = FALSE; - cinfo->Adobe_transform = 0; - - cinfo->marker->saw_SOI = TRUE; - - return TRUE; -} - - -LOCAL(boolean) -get_sof (j_decompress_ptr cinfo, boolean is_baseline, boolean is_prog, - boolean is_arith) -/* Process a SOFn marker */ -{ - INT32 length; - int c, ci, i; - jpeg_component_info * compptr; - INPUT_VARS(cinfo); - - cinfo->is_baseline = is_baseline; - cinfo->progressive_mode = is_prog; - cinfo->arith_code = is_arith; - - INPUT_2BYTES(cinfo, length, return FALSE); - - INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE); - INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE); - INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE); - INPUT_BYTE(cinfo, cinfo->num_components, return FALSE); - - length -= 8; - - TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker, - (int) cinfo->image_width, (int) cinfo->image_height, - cinfo->num_components); - - if (cinfo->marker->saw_SOF) - ERREXIT(cinfo, JERR_SOF_DUPLICATE); - - /* We don't support files in which the image height is initially specified */ - /* as 0 and is later redefined by DNL. As long as we have to check that, */ - /* might as well have a general sanity check. */ - if (cinfo->image_height <= 0 || cinfo->image_width <= 0 || - cinfo->num_components <= 0) - ERREXIT(cinfo, JERR_EMPTY_IMAGE); - - if (length != (cinfo->num_components * 3)) - ERREXIT(cinfo, JERR_BAD_LENGTH); - - if (cinfo->comp_info == NULL) /* do only once, even if suspend */ - cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components * SIZEOF(jpeg_component_info)); - - for (ci = 0; ci < cinfo->num_components; ci++) { - INPUT_BYTE(cinfo, c, return FALSE); - /* Check to see whether component id has already been seen */ - /* (in violation of the spec, but unfortunately seen in some */ - /* files). If so, create "fake" component id equal to the */ - /* max id seen so far + 1. */ - for (i = 0, compptr = cinfo->comp_info; i < ci; i++, compptr++) { - if (c == compptr->component_id) { - compptr = cinfo->comp_info; - c = compptr->component_id; - compptr++; - for (i = 1; i < ci; i++, compptr++) { - if (compptr->component_id > c) c = compptr->component_id; - } - c++; - break; - } - } - compptr->component_id = c; - compptr->component_index = ci; - INPUT_BYTE(cinfo, c, return FALSE); - compptr->h_samp_factor = (c >> 4) & 15; - compptr->v_samp_factor = (c ) & 15; - INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE); - - TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT, - compptr->component_id, compptr->h_samp_factor, - compptr->v_samp_factor, compptr->quant_tbl_no); - } - - cinfo->marker->saw_SOF = TRUE; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -LOCAL(boolean) -get_sos (j_decompress_ptr cinfo) -/* Process a SOS marker */ -{ - INT32 length; - int c, ci, i, n; - jpeg_component_info * compptr; - INPUT_VARS(cinfo); - - if (! cinfo->marker->saw_SOF) - ERREXITS(cinfo, JERR_SOF_BEFORE, "SOS"); - - INPUT_2BYTES(cinfo, length, return FALSE); - - INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */ - - TRACEMS1(cinfo, 1, JTRC_SOS, n); - - if (length != (n * 2 + 6) || n > MAX_COMPS_IN_SCAN || - (n == 0 && !cinfo->progressive_mode)) - /* pseudo SOS marker only allowed in progressive mode */ - ERREXIT(cinfo, JERR_BAD_LENGTH); - - cinfo->comps_in_scan = n; - - /* Collect the component-spec parameters */ - - for (i = 0; i < n; i++) { - INPUT_BYTE(cinfo, c, return FALSE); - - /* Detect the case where component id's are not unique, and, if so, */ - /* create a fake component id using the same logic as in get_sof. */ - /* Note: This also ensures that all of the SOF components are */ - /* referenced in the single scan case, which prevents access to */ - /* uninitialized memory in later decoding stages. */ - for (ci = 0; ci < i; ci++) { - if (c == cinfo->cur_comp_info[ci]->component_id) { - c = cinfo->cur_comp_info[0]->component_id; - for (ci = 1; ci < i; ci++) { - compptr = cinfo->cur_comp_info[ci]; - if (compptr->component_id > c) c = compptr->component_id; - } - c++; - break; - } - } - - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - if (c == compptr->component_id) - goto id_found; - } - - ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, c); - - id_found: - - cinfo->cur_comp_info[i] = compptr; - INPUT_BYTE(cinfo, c, return FALSE); - compptr->dc_tbl_no = (c >> 4) & 15; - compptr->ac_tbl_no = (c ) & 15; - - TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, compptr->component_id, - compptr->dc_tbl_no, compptr->ac_tbl_no); - } - - /* Collect the additional scan parameters Ss, Se, Ah/Al. */ - INPUT_BYTE(cinfo, c, return FALSE); - cinfo->Ss = c; - INPUT_BYTE(cinfo, c, return FALSE); - cinfo->Se = c; - INPUT_BYTE(cinfo, c, return FALSE); - cinfo->Ah = (c >> 4) & 15; - cinfo->Al = (c ) & 15; - - TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se, - cinfo->Ah, cinfo->Al); - - /* Prepare to scan data & restart markers */ - cinfo->marker->next_restart_num = 0; - - /* Count another (non-pseudo) SOS marker */ - if (n) cinfo->input_scan_number++; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -#ifdef D_ARITH_CODING_SUPPORTED - -LOCAL(boolean) -get_dac (j_decompress_ptr cinfo) -/* Process a DAC marker */ -{ - INT32 length; - int index, val; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - while (length > 0) { - INPUT_BYTE(cinfo, index, return FALSE); - INPUT_BYTE(cinfo, val, return FALSE); - - length -= 2; - - TRACEMS2(cinfo, 1, JTRC_DAC, index, val); - - if (index < 0 || index >= (2*NUM_ARITH_TBLS)) - ERREXIT1(cinfo, JERR_DAC_INDEX, index); - - if (index >= NUM_ARITH_TBLS) { /* define AC table */ - cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val; - } else { /* define DC table */ - cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F); - cinfo->arith_dc_U[index] = (UINT8) (val >> 4); - if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index]) - ERREXIT1(cinfo, JERR_DAC_VALUE, val); - } - } - - if (length != 0) - ERREXIT(cinfo, JERR_BAD_LENGTH); - - INPUT_SYNC(cinfo); - return TRUE; -} - -#else /* ! D_ARITH_CODING_SUPPORTED */ - -#define get_dac(cinfo) skip_variable(cinfo) - -#endif /* D_ARITH_CODING_SUPPORTED */ - - -LOCAL(boolean) -get_dht (j_decompress_ptr cinfo) -/* Process a DHT marker */ -{ - INT32 length; - UINT8 bits[17]; - UINT8 huffval[256]; - int i, index, count; - JHUFF_TBL **htblptr; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - while (length > 16) { - INPUT_BYTE(cinfo, index, return FALSE); - - TRACEMS1(cinfo, 1, JTRC_DHT, index); - - bits[0] = 0; - count = 0; - for (i = 1; i <= 16; i++) { - INPUT_BYTE(cinfo, bits[i], return FALSE); - count += bits[i]; - } - - length -= 1 + 16; - - TRACEMS8(cinfo, 2, JTRC_HUFFBITS, - bits[1], bits[2], bits[3], bits[4], - bits[5], bits[6], bits[7], bits[8]); - TRACEMS8(cinfo, 2, JTRC_HUFFBITS, - bits[9], bits[10], bits[11], bits[12], - bits[13], bits[14], bits[15], bits[16]); - - /* Here we just do minimal validation of the counts to avoid walking - * off the end of our table space. jdhuff.c will check more carefully. - */ - if (count > 256 || ((INT32) count) > length) - ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); - - MEMZERO(huffval, SIZEOF(huffval)); /* pre-zero array for later copy */ - - for (i = 0; i < count; i++) - INPUT_BYTE(cinfo, huffval[i], return FALSE); - - length -= count; - - if (index & 0x10) { /* AC table definition */ - index -= 0x10; - htblptr = &cinfo->ac_huff_tbl_ptrs[index]; - } else { /* DC table definition */ - htblptr = &cinfo->dc_huff_tbl_ptrs[index]; - } - - if (index < 0 || index >= NUM_HUFF_TBLS) - ERREXIT1(cinfo, JERR_DHT_INDEX, index); - - if (*htblptr == NULL) - *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); - - MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits)); - MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval)); - } - - if (length != 0) - ERREXIT(cinfo, JERR_BAD_LENGTH); - - INPUT_SYNC(cinfo); - return TRUE; -} - - -LOCAL(boolean) -get_dqt (j_decompress_ptr cinfo) -/* Process a DQT marker */ -{ - INT32 length, count, i; - int n, prec; - unsigned int tmp; - JQUANT_TBL *quant_ptr; - const int *natural_order; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - while (length > 0) { - length--; - INPUT_BYTE(cinfo, n, return FALSE); - prec = n >> 4; - n &= 0x0F; - - TRACEMS2(cinfo, 1, JTRC_DQT, n, prec); - - if (n >= NUM_QUANT_TBLS) - ERREXIT1(cinfo, JERR_DQT_INDEX, n); - - if (cinfo->quant_tbl_ptrs[n] == NULL) - cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo); - quant_ptr = cinfo->quant_tbl_ptrs[n]; - - if (prec) { - if (length < DCTSIZE2 * 2) { - /* Initialize full table for safety. */ - for (i = 0; i < DCTSIZE2; i++) { - quant_ptr->quantval[i] = 1; - } - count = length >> 1; - } else - count = DCTSIZE2; - } else { - if (length < DCTSIZE2) { - /* Initialize full table for safety. */ - for (i = 0; i < DCTSIZE2; i++) { - quant_ptr->quantval[i] = 1; - } - count = length; - } else - count = DCTSIZE2; - } - - switch (count) { - case (2*2): natural_order = jpeg_natural_order2; break; - case (3*3): natural_order = jpeg_natural_order3; break; - case (4*4): natural_order = jpeg_natural_order4; break; - case (5*5): natural_order = jpeg_natural_order5; break; - case (6*6): natural_order = jpeg_natural_order6; break; - case (7*7): natural_order = jpeg_natural_order7; break; - default: natural_order = jpeg_natural_order; break; - } - - for (i = 0; i < count; i++) { - if (prec) - INPUT_2BYTES(cinfo, tmp, return FALSE); - else - INPUT_BYTE(cinfo, tmp, return FALSE); - /* We convert the zigzag-order table to natural array order. */ - quant_ptr->quantval[natural_order[i]] = (UINT16) tmp; - } - - if (cinfo->err->trace_level >= 2) { - for (i = 0; i < DCTSIZE2; i += 8) { - TRACEMS8(cinfo, 2, JTRC_QUANTVALS, - quant_ptr->quantval[i], quant_ptr->quantval[i+1], - quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], - quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], - quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); - } - } - - length -= count; - if (prec) length -= count; - } - - if (length != 0) - ERREXIT(cinfo, JERR_BAD_LENGTH); - - INPUT_SYNC(cinfo); - return TRUE; -} - - -LOCAL(boolean) -get_dri (j_decompress_ptr cinfo) -/* Process a DRI marker */ -{ - INT32 length; - unsigned int tmp; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - - if (length != 4) - ERREXIT(cinfo, JERR_BAD_LENGTH); - - INPUT_2BYTES(cinfo, tmp, return FALSE); - - TRACEMS1(cinfo, 1, JTRC_DRI, tmp); - - cinfo->restart_interval = tmp; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -LOCAL(boolean) -get_lse (j_decompress_ptr cinfo) -/* Process an LSE marker */ -{ - INT32 length; - unsigned int tmp; - int cid; - INPUT_VARS(cinfo); - - if (! cinfo->marker->saw_SOF) - ERREXITS(cinfo, JERR_SOF_BEFORE, "LSE"); - - if (cinfo->num_components < 3) goto bad; - - INPUT_2BYTES(cinfo, length, return FALSE); - - if (length != 24) - ERREXIT(cinfo, JERR_BAD_LENGTH); - - INPUT_BYTE(cinfo, tmp, return FALSE); - if (tmp != 0x0D) /* ID inverse transform specification */ - ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); - INPUT_2BYTES(cinfo, tmp, return FALSE); - if (tmp != MAXJSAMPLE) goto bad; /* MAXTRANS */ - INPUT_BYTE(cinfo, tmp, return FALSE); - if (tmp != 3) goto bad; /* Nt=3 */ - INPUT_BYTE(cinfo, cid, return FALSE); - if (cid != cinfo->comp_info[1].component_id) goto bad; - INPUT_BYTE(cinfo, cid, return FALSE); - if (cid != cinfo->comp_info[0].component_id) goto bad; - INPUT_BYTE(cinfo, cid, return FALSE); - if (cid != cinfo->comp_info[2].component_id) goto bad; - INPUT_BYTE(cinfo, tmp, return FALSE); - if (tmp != 0x80) goto bad; /* F1: CENTER1=1, NORM1=0 */ - INPUT_2BYTES(cinfo, tmp, return FALSE); - if (tmp != 0) goto bad; /* A(1,1)=0 */ - INPUT_2BYTES(cinfo, tmp, return FALSE); - if (tmp != 0) goto bad; /* A(1,2)=0 */ - INPUT_BYTE(cinfo, tmp, return FALSE); - if (tmp != 0) goto bad; /* F2: CENTER2=0, NORM2=0 */ - INPUT_2BYTES(cinfo, tmp, return FALSE); - if (tmp != 1) goto bad; /* A(2,1)=1 */ - INPUT_2BYTES(cinfo, tmp, return FALSE); - if (tmp != 0) goto bad; /* A(2,2)=0 */ - INPUT_BYTE(cinfo, tmp, return FALSE); - if (tmp != 0) goto bad; /* F3: CENTER3=0, NORM3=0 */ - INPUT_2BYTES(cinfo, tmp, return FALSE); - if (tmp != 1) goto bad; /* A(3,1)=1 */ - INPUT_2BYTES(cinfo, tmp, return FALSE); - if (tmp != 0) { /* A(3,2)=0 */ - bad: - ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); - } - - /* OK, valid transform that we can handle. */ - cinfo->color_transform = JCT_SUBTRACT_GREEN; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -/* - * Routines for processing APPn and COM markers. - * These are either saved in memory or discarded, per application request. - * APP0 and APP14 are specially checked to see if they are - * JFIF and Adobe markers, respectively. - */ - -#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */ -#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */ -#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */ - - -LOCAL(void) -examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data, - unsigned int datalen, INT32 remaining) -/* Examine first few bytes from an APP0. - * Take appropriate action if it is a JFIF marker. - * datalen is # of bytes at data[], remaining is length of rest of marker data. - */ -{ - INT32 totallen = (INT32) datalen + remaining; - - if (datalen >= APP0_DATA_LEN && - GETJOCTET(data[0]) == 0x4A && - GETJOCTET(data[1]) == 0x46 && - GETJOCTET(data[2]) == 0x49 && - GETJOCTET(data[3]) == 0x46 && - GETJOCTET(data[4]) == 0) { - /* Found JFIF APP0 marker: save info */ - cinfo->saw_JFIF_marker = TRUE; - cinfo->JFIF_major_version = GETJOCTET(data[5]); - cinfo->JFIF_minor_version = GETJOCTET(data[6]); - cinfo->density_unit = GETJOCTET(data[7]); - cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]); - cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]); - /* Check version. - * Major version must be 1 or 2, anything else signals an incompatible - * change. - * (We used to treat this as an error, but now it's a nonfatal warning, - * because some bozo at Hijaak couldn't read the spec.) - * Minor version should be 0..2, but process anyway if newer. - */ - if (cinfo->JFIF_major_version != 1 && cinfo->JFIF_major_version != 2) - WARNMS2(cinfo, JWRN_JFIF_MAJOR, - cinfo->JFIF_major_version, cinfo->JFIF_minor_version); - /* Generate trace messages */ - TRACEMS5(cinfo, 1, JTRC_JFIF, - cinfo->JFIF_major_version, cinfo->JFIF_minor_version, - cinfo->X_density, cinfo->Y_density, cinfo->density_unit); - /* Validate thumbnail dimensions and issue appropriate messages */ - if (GETJOCTET(data[12]) | GETJOCTET(data[13])) - TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, - GETJOCTET(data[12]), GETJOCTET(data[13])); - totallen -= APP0_DATA_LEN; - if (totallen != - ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3)) - TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen); - } else if (datalen >= 6 && - GETJOCTET(data[0]) == 0x4A && - GETJOCTET(data[1]) == 0x46 && - GETJOCTET(data[2]) == 0x58 && - GETJOCTET(data[3]) == 0x58 && - GETJOCTET(data[4]) == 0) { - /* Found JFIF "JFXX" extension APP0 marker */ - /* The library doesn't actually do anything with these, - * but we try to produce a helpful trace message. - */ - switch (GETJOCTET(data[5])) { - case 0x10: - TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen); - break; - case 0x11: - TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen); - break; - case 0x13: - TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen); - break; - default: - TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, - GETJOCTET(data[5]), (int) totallen); - break; - } - } else { - /* Start of APP0 does not match "JFIF" or "JFXX", or too short */ - TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen); - } -} - - -LOCAL(void) -examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data, - unsigned int datalen, INT32 remaining) -/* Examine first few bytes from an APP14. - * Take appropriate action if it is an Adobe marker. - * datalen is # of bytes at data[], remaining is length of rest of marker data. - */ -{ - unsigned int version, flags0, flags1, transform; - - if (datalen >= APP14_DATA_LEN && - GETJOCTET(data[0]) == 0x41 && - GETJOCTET(data[1]) == 0x64 && - GETJOCTET(data[2]) == 0x6F && - GETJOCTET(data[3]) == 0x62 && - GETJOCTET(data[4]) == 0x65) { - /* Found Adobe APP14 marker */ - version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]); - flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]); - flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]); - transform = GETJOCTET(data[11]); - TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform); - cinfo->saw_Adobe_marker = TRUE; - cinfo->Adobe_transform = (UINT8) transform; - } else { - /* Start of APP14 does not match "Adobe", or too short */ - TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining)); - } -} - - -METHODDEF(boolean) -get_interesting_appn (j_decompress_ptr cinfo) -/* Process an APP0 or APP14 marker without saving it */ -{ - INT32 length; - JOCTET b[APPN_DATA_LEN]; - unsigned int i, numtoread; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - /* get the interesting part of the marker data */ - if (length >= APPN_DATA_LEN) - numtoread = APPN_DATA_LEN; - else if (length > 0) - numtoread = (unsigned int) length; - else - numtoread = 0; - for (i = 0; i < numtoread; i++) - INPUT_BYTE(cinfo, b[i], return FALSE); - length -= numtoread; - - /* process it */ - switch (cinfo->unread_marker) { - case M_APP0: - examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length); - break; - case M_APP14: - examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length); - break; - default: - /* can't get here unless jpeg_save_markers chooses wrong processor */ - ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); - break; - } - - /* skip any remaining data -- could be lots */ - INPUT_SYNC(cinfo); - if (length > 0) - (*cinfo->src->skip_input_data) (cinfo, (long) length); - - return TRUE; -} - - -#ifdef SAVE_MARKERS_SUPPORTED - -METHODDEF(boolean) -save_marker (j_decompress_ptr cinfo) -/* Save an APPn or COM marker into the marker list */ -{ - my_marker_ptr marker = (my_marker_ptr) cinfo->marker; - jpeg_saved_marker_ptr cur_marker = marker->cur_marker; - unsigned int bytes_read, data_length; - JOCTET FAR * data; - INT32 length = 0; - INPUT_VARS(cinfo); - - if (cur_marker == NULL) { - /* begin reading a marker */ - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - if (length >= 0) { /* watch out for bogus length word */ - /* figure out how much we want to save */ - unsigned int limit; - if (cinfo->unread_marker == (int) M_COM) - limit = marker->length_limit_COM; - else - limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0]; - if ((unsigned int) length < limit) - limit = (unsigned int) length; - /* allocate and initialize the marker item */ - cur_marker = (jpeg_saved_marker_ptr) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(struct jpeg_marker_struct) + limit); - cur_marker->next = NULL; - cur_marker->marker = (UINT8) cinfo->unread_marker; - cur_marker->original_length = (unsigned int) length; - cur_marker->data_length = limit; - /* data area is just beyond the jpeg_marker_struct */ - data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1); - marker->cur_marker = cur_marker; - marker->bytes_read = 0; - bytes_read = 0; - data_length = limit; - } else { - /* deal with bogus length word */ - bytes_read = data_length = 0; - data = NULL; - } - } else { - /* resume reading a marker */ - bytes_read = marker->bytes_read; - data_length = cur_marker->data_length; - data = cur_marker->data + bytes_read; - } - - while (bytes_read < data_length) { - INPUT_SYNC(cinfo); /* move the restart point to here */ - marker->bytes_read = bytes_read; - /* If there's not at least one byte in buffer, suspend */ - MAKE_BYTE_AVAIL(cinfo, return FALSE); - /* Copy bytes with reasonable rapidity */ - while (bytes_read < data_length && bytes_in_buffer > 0) { - *data++ = *next_input_byte++; - bytes_in_buffer--; - bytes_read++; - } - } - - /* Done reading what we want to read */ - if (cur_marker != NULL) { /* will be NULL if bogus length word */ - /* Add new marker to end of list */ - if (cinfo->marker_list == NULL) { - cinfo->marker_list = cur_marker; - } else { - jpeg_saved_marker_ptr prev = cinfo->marker_list; - while (prev->next != NULL) - prev = prev->next; - prev->next = cur_marker; - } - /* Reset pointer & calc remaining data length */ - data = cur_marker->data; - length = cur_marker->original_length - data_length; - } - /* Reset to initial state for next marker */ - marker->cur_marker = NULL; - - /* Process the marker if interesting; else just make a generic trace msg */ - switch (cinfo->unread_marker) { - case M_APP0: - examine_app0(cinfo, data, data_length, length); - break; - case M_APP14: - examine_app14(cinfo, data, data_length, length); - break; - default: - TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, - (int) (data_length + length)); - break; - } - - /* skip any remaining data -- could be lots */ - INPUT_SYNC(cinfo); /* do before skip_input_data */ - if (length > 0) - (*cinfo->src->skip_input_data) (cinfo, (long) length); - - return TRUE; -} - -#endif /* SAVE_MARKERS_SUPPORTED */ - - -METHODDEF(boolean) -skip_variable (j_decompress_ptr cinfo) -/* Skip over an unknown or uninteresting variable-length marker */ -{ - INT32 length; - INPUT_VARS(cinfo); - - INPUT_2BYTES(cinfo, length, return FALSE); - length -= 2; - - TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length); - - INPUT_SYNC(cinfo); /* do before skip_input_data */ - if (length > 0) - (*cinfo->src->skip_input_data) (cinfo, (long) length); - - return TRUE; -} - - -/* - * Find the next JPEG marker, save it in cinfo->unread_marker. - * Returns FALSE if had to suspend before reaching a marker; - * in that case cinfo->unread_marker is unchanged. - * - * Note that the result might not be a valid marker code, - * but it will never be 0 or FF. - */ - -LOCAL(boolean) -next_marker (j_decompress_ptr cinfo) -{ - int c; - INPUT_VARS(cinfo); - - for (;;) { - INPUT_BYTE(cinfo, c, return FALSE); - /* Skip any non-FF bytes. - * This may look a bit inefficient, but it will not occur in a valid file. - * We sync after each discarded byte so that a suspending data source - * can discard the byte from its buffer. - */ - while (c != 0xFF) { - cinfo->marker->discarded_bytes++; - INPUT_SYNC(cinfo); - INPUT_BYTE(cinfo, c, return FALSE); - } - /* This loop swallows any duplicate FF bytes. Extra FFs are legal as - * pad bytes, so don't count them in discarded_bytes. We assume there - * will not be so many consecutive FF bytes as to overflow a suspending - * data source's input buffer. - */ - do { - INPUT_BYTE(cinfo, c, return FALSE); - } while (c == 0xFF); - if (c != 0) - break; /* found a valid marker, exit loop */ - /* Reach here if we found a stuffed-zero data sequence (FF/00). - * Discard it and loop back to try again. - */ - cinfo->marker->discarded_bytes += 2; - INPUT_SYNC(cinfo); - } - - if (cinfo->marker->discarded_bytes != 0) { - WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c); - cinfo->marker->discarded_bytes = 0; - } - - cinfo->unread_marker = c; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -LOCAL(boolean) -first_marker (j_decompress_ptr cinfo) -/* Like next_marker, but used to obtain the initial SOI marker. */ -/* For this marker, we do not allow preceding garbage or fill; otherwise, - * we might well scan an entire input file before realizing it ain't JPEG. - * If an application wants to process non-JFIF files, it must seek to the - * SOI before calling the JPEG library. - */ -{ - int c, c2; - INPUT_VARS(cinfo); - - INPUT_BYTE(cinfo, c, return FALSE); - INPUT_BYTE(cinfo, c2, return FALSE); - if (c != 0xFF || c2 != (int) M_SOI) - ERREXIT2(cinfo, JERR_NO_SOI, c, c2); - - cinfo->unread_marker = c2; - - INPUT_SYNC(cinfo); - return TRUE; -} - - -/* - * Read markers until SOS or EOI. - * - * Returns same codes as are defined for jpeg_consume_input: - * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. - * - * Note: This function may return a pseudo SOS marker (with zero - * component number) for treat by input controller's consume_input. - * consume_input itself should filter out (skip) the pseudo marker - * after processing for the caller. - */ - -METHODDEF(int) -read_markers (j_decompress_ptr cinfo) -{ - /* Outer loop repeats once for each marker. */ - for (;;) { - /* Collect the marker proper, unless we already did. */ - /* NB: first_marker() enforces the requirement that SOI appear first. */ - if (cinfo->unread_marker == 0) { - if (! cinfo->marker->saw_SOI) { - if (! first_marker(cinfo)) - return JPEG_SUSPENDED; - } else { - if (! next_marker(cinfo)) - return JPEG_SUSPENDED; - } - } - /* At this point cinfo->unread_marker contains the marker code and the - * input point is just past the marker proper, but before any parameters. - * A suspension will cause us to return with this state still true. - */ - switch (cinfo->unread_marker) { - case M_SOI: - if (! get_soi(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_SOF0: /* Baseline */ - if (! get_sof(cinfo, TRUE, FALSE, FALSE)) - return JPEG_SUSPENDED; - break; - - case M_SOF1: /* Extended sequential, Huffman */ - if (! get_sof(cinfo, FALSE, FALSE, FALSE)) - return JPEG_SUSPENDED; - break; - - case M_SOF2: /* Progressive, Huffman */ - if (! get_sof(cinfo, FALSE, TRUE, FALSE)) - return JPEG_SUSPENDED; - break; - - case M_SOF9: /* Extended sequential, arithmetic */ - if (! get_sof(cinfo, FALSE, FALSE, TRUE)) - return JPEG_SUSPENDED; - break; - - case M_SOF10: /* Progressive, arithmetic */ - if (! get_sof(cinfo, FALSE, TRUE, TRUE)) - return JPEG_SUSPENDED; - break; - - /* Currently unsupported SOFn types */ - case M_SOF3: /* Lossless, Huffman */ - case M_SOF5: /* Differential sequential, Huffman */ - case M_SOF6: /* Differential progressive, Huffman */ - case M_SOF7: /* Differential lossless, Huffman */ - case M_JPG: /* Reserved for JPEG extensions */ - case M_SOF11: /* Lossless, arithmetic */ - case M_SOF13: /* Differential sequential, arithmetic */ - case M_SOF14: /* Differential progressive, arithmetic */ - case M_SOF15: /* Differential lossless, arithmetic */ - ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker); - break; - - case M_SOS: - if (! get_sos(cinfo)) - return JPEG_SUSPENDED; - cinfo->unread_marker = 0; /* processed the marker */ - return JPEG_REACHED_SOS; - - case M_EOI: - TRACEMS(cinfo, 1, JTRC_EOI); - cinfo->unread_marker = 0; /* processed the marker */ - return JPEG_REACHED_EOI; - - case M_DAC: - if (! get_dac(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_DHT: - if (! get_dht(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_DQT: - if (! get_dqt(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_DRI: - if (! get_dri(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_JPG8: - if (! get_lse(cinfo)) - return JPEG_SUSPENDED; - break; - - case M_APP0: - case M_APP1: - case M_APP2: - case M_APP3: - case M_APP4: - case M_APP5: - case M_APP6: - case M_APP7: - case M_APP8: - case M_APP9: - case M_APP10: - case M_APP11: - case M_APP12: - case M_APP13: - case M_APP14: - case M_APP15: - if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[ - cinfo->unread_marker - (int) M_APP0]) (cinfo)) - return JPEG_SUSPENDED; - break; - - case M_COM: - if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo)) - return JPEG_SUSPENDED; - break; - - case M_RST0: /* these are all parameterless */ - case M_RST1: - case M_RST2: - case M_RST3: - case M_RST4: - case M_RST5: - case M_RST6: - case M_RST7: - case M_TEM: - TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker); - break; - - case M_DNL: /* Ignore DNL ... perhaps the wrong thing */ - if (! skip_variable(cinfo)) - return JPEG_SUSPENDED; - break; - - default: /* must be DHP, EXP, JPGn, or RESn */ - /* For now, we treat the reserved markers as fatal errors since they are - * likely to be used to signal incompatible JPEG Part 3 extensions. - * Once the JPEG 3 version-number marker is well defined, this code - * ought to change! - */ - ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker); - break; - } - /* Successfully processed marker, so reset state variable */ - cinfo->unread_marker = 0; - } /* end loop */ -} - - -/* - * Read a restart marker, which is expected to appear next in the datastream; - * if the marker is not there, take appropriate recovery action. - * Returns FALSE if suspension is required. - * - * This is called by the entropy decoder after it has read an appropriate - * number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder - * has already read a marker from the data source. Under normal conditions - * cinfo->unread_marker will be reset to 0 before returning; if not reset, - * it holds a marker which the decoder will be unable to read past. - */ - -METHODDEF(boolean) -read_restart_marker (j_decompress_ptr cinfo) -{ - /* Obtain a marker unless we already did. */ - /* Note that next_marker will complain if it skips any data. */ - if (cinfo->unread_marker == 0) { - if (! next_marker(cinfo)) - return FALSE; - } - - if (cinfo->unread_marker == - ((int) M_RST0 + cinfo->marker->next_restart_num)) { - /* Normal case --- swallow the marker and let entropy decoder continue */ - TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num); - cinfo->unread_marker = 0; - } else { - /* Uh-oh, the restart markers have been messed up. */ - /* Let the data source manager determine how to resync. */ - if (! (*cinfo->src->resync_to_restart) (cinfo, - cinfo->marker->next_restart_num)) - return FALSE; - } - - /* Update next-restart state */ - cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7; - - return TRUE; -} - - -/* - * This is the default resync_to_restart method for data source managers - * to use if they don't have any better approach. Some data source managers - * may be able to back up, or may have additional knowledge about the data - * which permits a more intelligent recovery strategy; such managers would - * presumably supply their own resync method. - * - * read_restart_marker calls resync_to_restart if it finds a marker other than - * the restart marker it was expecting. (This code is *not* used unless - * a nonzero restart interval has been declared.) cinfo->unread_marker is - * the marker code actually found (might be anything, except 0 or FF). - * The desired restart marker number (0..7) is passed as a parameter. - * This routine is supposed to apply whatever error recovery strategy seems - * appropriate in order to position the input stream to the next data segment. - * Note that cinfo->unread_marker is treated as a marker appearing before - * the current data-source input point; usually it should be reset to zero - * before returning. - * Returns FALSE if suspension is required. - * - * This implementation is substantially constrained by wanting to treat the - * input as a data stream; this means we can't back up. Therefore, we have - * only the following actions to work with: - * 1. Simply discard the marker and let the entropy decoder resume at next - * byte of file. - * 2. Read forward until we find another marker, discarding intervening - * data. (In theory we could look ahead within the current bufferload, - * without having to discard data if we don't find the desired marker. - * This idea is not implemented here, in part because it makes behavior - * dependent on buffer size and chance buffer-boundary positions.) - * 3. Leave the marker unread (by failing to zero cinfo->unread_marker). - * This will cause the entropy decoder to process an empty data segment, - * inserting dummy zeroes, and then we will reprocess the marker. - * - * #2 is appropriate if we think the desired marker lies ahead, while #3 is - * appropriate if the found marker is a future restart marker (indicating - * that we have missed the desired restart marker, probably because it got - * corrupted). - * We apply #2 or #3 if the found marker is a restart marker no more than - * two counts behind or ahead of the expected one. We also apply #2 if the - * found marker is not a legal JPEG marker code (it's certainly bogus data). - * If the found marker is a restart marker more than 2 counts away, we do #1 - * (too much risk that the marker is erroneous; with luck we will be able to - * resync at some future point). - * For any valid non-restart JPEG marker, we apply #3. This keeps us from - * overrunning the end of a scan. An implementation limited to single-scan - * files might find it better to apply #2 for markers other than EOI, since - * any other marker would have to be bogus data in that case. - */ - -GLOBAL(boolean) -jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) -{ - int marker = cinfo->unread_marker; - int action = 1; - - /* Always put up a warning. */ - WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired); - - /* Outer loop handles repeated decision after scanning forward. */ - for (;;) { - if (marker < (int) M_SOF0) - action = 2; /* invalid marker */ - else if (marker < (int) M_RST0 || marker > (int) M_RST7) - action = 3; /* valid non-restart marker */ - else { - if (marker == ((int) M_RST0 + ((desired+1) & 7)) || - marker == ((int) M_RST0 + ((desired+2) & 7))) - action = 3; /* one of the next two expected restarts */ - else if (marker == ((int) M_RST0 + ((desired-1) & 7)) || - marker == ((int) M_RST0 + ((desired-2) & 7))) - action = 2; /* a prior restart, so advance */ - else - action = 1; /* desired restart or too far away */ - } - TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action); - switch (action) { - case 1: - /* Discard marker and let entropy decoder resume processing. */ - cinfo->unread_marker = 0; - return TRUE; - case 2: - /* Scan to the next marker, and repeat the decision loop. */ - if (! next_marker(cinfo)) - return FALSE; - marker = cinfo->unread_marker; - break; - case 3: - /* Return without advancing past this marker. */ - /* Entropy decoder will be forced to process an empty segment. */ - return TRUE; - } - } /* end loop */ -} - - -/* - * Reset marker processing state to begin a fresh datastream. - */ - -METHODDEF(void) -reset_marker_reader (j_decompress_ptr cinfo) -{ - my_marker_ptr marker = (my_marker_ptr) cinfo->marker; - - cinfo->comp_info = NULL; /* until allocated by get_sof */ - cinfo->input_scan_number = 0; /* no SOS seen yet */ - cinfo->unread_marker = 0; /* no pending marker */ - marker->pub.saw_SOI = FALSE; /* set internal state too */ - marker->pub.saw_SOF = FALSE; - marker->pub.discarded_bytes = 0; - marker->cur_marker = NULL; -} - - -/* - * Initialize the marker reader module. - * This is called only once, when the decompression object is created. - */ - -GLOBAL(void) -jinit_marker_reader (j_decompress_ptr cinfo) -{ - my_marker_ptr marker; - int i; - - /* Create subobject in permanent pool */ - marker = (my_marker_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(my_marker_reader)); - cinfo->marker = &marker->pub; - /* Initialize public method pointers */ - marker->pub.reset_marker_reader = reset_marker_reader; - marker->pub.read_markers = read_markers; - marker->pub.read_restart_marker = read_restart_marker; - /* Initialize COM/APPn processing. - * By default, we examine and then discard APP0 and APP14, - * but simply discard COM and all other APPn. - */ - marker->process_COM = skip_variable; - marker->length_limit_COM = 0; - for (i = 0; i < 16; i++) { - marker->process_APPn[i] = skip_variable; - marker->length_limit_APPn[i] = 0; - } - marker->process_APPn[0] = get_interesting_appn; - marker->process_APPn[14] = get_interesting_appn; - /* Reset marker processing state */ - reset_marker_reader(cinfo); -} - - -/* - * Control saving of COM and APPn markers into marker_list. - */ - -#ifdef SAVE_MARKERS_SUPPORTED - -GLOBAL(void) -jpeg_save_markers (j_decompress_ptr cinfo, int marker_code, - unsigned int length_limit) -{ - my_marker_ptr marker = (my_marker_ptr) cinfo->marker; - long maxlength; - jpeg_marker_parser_method processor; - - /* Length limit mustn't be larger than what we can allocate - * (should only be a concern in a 16-bit environment). - */ - maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct); - if (((long) length_limit) > maxlength) - length_limit = (unsigned int) maxlength; - - /* Choose processor routine to use. - * APP0/APP14 have special requirements. - */ - if (length_limit) { - processor = save_marker; - /* If saving APP0/APP14, save at least enough for our internal use. */ - if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN) - length_limit = APP0_DATA_LEN; - else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN) - length_limit = APP14_DATA_LEN; - } else { - processor = skip_variable; - /* If discarding APP0/APP14, use our regular on-the-fly processor. */ - if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14) - processor = get_interesting_appn; - } - - if (marker_code == (int) M_COM) { - marker->process_COM = processor; - marker->length_limit_COM = length_limit; - } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) { - marker->process_APPn[marker_code - (int) M_APP0] = processor; - marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit; - } else - ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); -} - -#endif /* SAVE_MARKERS_SUPPORTED */ - - -/* - * Install a special processing method for COM or APPn markers. - */ - -GLOBAL(void) -jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code, - jpeg_marker_parser_method routine) -{ - my_marker_ptr marker = (my_marker_ptr) cinfo->marker; - - if (marker_code == (int) M_COM) - marker->process_COM = routine; - else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) - marker->process_APPn[marker_code - (int) M_APP0] = routine; - else - ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code); -} diff --git a/libraries/jpeg/jdmaster.c b/libraries/jpeg/jdmaster.c deleted file mode 100644 index 62c07671f..000000000 --- a/libraries/jpeg/jdmaster.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * jdmaster.c - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2002-2017 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains master control logic for the JPEG decompressor. - * These routines are concerned with selecting the modules to be executed - * and with determining the number of passes and the work to be done in each - * pass. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Private state */ - -typedef struct { - struct jpeg_decomp_master pub; /* public fields */ - - int pass_number; /* # of passes completed */ - - boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */ - - /* Saved references to initialized quantizer modules, - * in case we need to switch modes. - */ - struct jpeg_color_quantizer * quantizer_1pass; - struct jpeg_color_quantizer * quantizer_2pass; -} my_decomp_master; - -typedef my_decomp_master * my_master_ptr; - - -/* - * Determine whether merged upsample/color conversion should be used. - * CRUCIAL: this must match the actual capabilities of jdmerge.c! - */ - -LOCAL(boolean) -use_merged_upsample (j_decompress_ptr cinfo) -{ -#ifdef UPSAMPLE_MERGING_SUPPORTED - /* Merging is the equivalent of plain box-filter upsampling. */ - /* The following condition is only needed if fancy shall select - * a different upsampling method. In our current implementation - * fancy only affects the DCT scaling, thus we can use fancy - * upsampling and merged upsample simultaneously, in particular - * with scaled DCT sizes larger than the default DCTSIZE. - */ -#if 0 - if (cinfo->do_fancy_upsampling) - return FALSE; -#endif - if (cinfo->CCIR601_sampling) - return FALSE; - /* jdmerge.c only supports YCC=>RGB color conversion */ - if ((cinfo->jpeg_color_space != JCS_YCbCr && - cinfo->jpeg_color_space != JCS_BG_YCC) || - cinfo->num_components != 3 || - cinfo->out_color_space != JCS_RGB || - cinfo->out_color_components != RGB_PIXELSIZE || - cinfo->color_transform) - return FALSE; - /* and it only handles 2h1v or 2h2v sampling ratios */ - if (cinfo->comp_info[0].h_samp_factor != 2 || - cinfo->comp_info[1].h_samp_factor != 1 || - cinfo->comp_info[2].h_samp_factor != 1 || - cinfo->comp_info[0].v_samp_factor > 2 || - cinfo->comp_info[1].v_samp_factor != 1 || - cinfo->comp_info[2].v_samp_factor != 1) - return FALSE; - /* furthermore, it doesn't work if we've scaled the IDCTs differently */ - if (cinfo->comp_info[0].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size || - cinfo->comp_info[1].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size || - cinfo->comp_info[2].DCT_h_scaled_size != cinfo->min_DCT_h_scaled_size || - cinfo->comp_info[0].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size || - cinfo->comp_info[1].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size || - cinfo->comp_info[2].DCT_v_scaled_size != cinfo->min_DCT_v_scaled_size) - return FALSE; - /* ??? also need to test for upsample-time rescaling, when & if supported */ - return TRUE; /* by golly, it'll work... */ -#else - return FALSE; -#endif -} - - -/* - * Compute output image dimensions and related values. - * NOTE: this is exported for possible use by application. - * Hence it mustn't do anything that can't be done twice. - * Also note that it may be called before the master module is initialized! - */ - -GLOBAL(void) -jpeg_calc_output_dimensions (j_decompress_ptr cinfo) -/* Do computations that are needed before master selection phase. - * This function is used for full decompression. - */ -{ -#ifdef IDCT_SCALING_SUPPORTED - int ci; - jpeg_component_info *compptr; -#endif - - /* Prevent application from calling me at wrong times */ - if (cinfo->global_state != DSTATE_READY) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - /* Compute core output image dimensions and DCT scaling choices. */ - jpeg_core_output_dimensions(cinfo); - -#ifdef IDCT_SCALING_SUPPORTED - - /* In selecting the actual DCT scaling for each component, we try to - * scale up the chroma components via IDCT scaling rather than upsampling. - * This saves time if the upsampler gets to use 1:1 scaling. - * Note this code adapts subsampling ratios which are powers of 2. - */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - int ssize = 1; - while (cinfo->min_DCT_h_scaled_size * ssize <= - (cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) && - (cinfo->max_h_samp_factor % (compptr->h_samp_factor * ssize * 2)) == 0) { - ssize = ssize * 2; - } - compptr->DCT_h_scaled_size = cinfo->min_DCT_h_scaled_size * ssize; - ssize = 1; - while (cinfo->min_DCT_v_scaled_size * ssize <= - (cinfo->do_fancy_upsampling ? DCTSIZE : DCTSIZE / 2) && - (cinfo->max_v_samp_factor % (compptr->v_samp_factor * ssize * 2)) == 0) { - ssize = ssize * 2; - } - compptr->DCT_v_scaled_size = cinfo->min_DCT_v_scaled_size * ssize; - - /* We don't support IDCT ratios larger than 2. */ - if (compptr->DCT_h_scaled_size > compptr->DCT_v_scaled_size * 2) - compptr->DCT_h_scaled_size = compptr->DCT_v_scaled_size * 2; - else if (compptr->DCT_v_scaled_size > compptr->DCT_h_scaled_size * 2) - compptr->DCT_v_scaled_size = compptr->DCT_h_scaled_size * 2; - } - - /* Recompute downsampled dimensions of components; - * application needs to know these if using raw downsampled data. - */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Size in samples, after IDCT scaling */ - compptr->downsampled_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * - (long) (compptr->h_samp_factor * compptr->DCT_h_scaled_size), - (long) (cinfo->max_h_samp_factor * cinfo->block_size)); - compptr->downsampled_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * - (long) (compptr->v_samp_factor * compptr->DCT_v_scaled_size), - (long) (cinfo->max_v_samp_factor * cinfo->block_size)); - } - -#endif /* IDCT_SCALING_SUPPORTED */ - - /* Report number of components in selected colorspace. */ - /* Probably this should be in the color conversion module... */ - switch (cinfo->out_color_space) { - case JCS_GRAYSCALE: - cinfo->out_color_components = 1; - break; - case JCS_RGB: - case JCS_BG_RGB: - cinfo->out_color_components = RGB_PIXELSIZE; - break; - case JCS_YCbCr: - case JCS_BG_YCC: - cinfo->out_color_components = 3; - break; - case JCS_CMYK: - case JCS_YCCK: - cinfo->out_color_components = 4; - break; - default: /* else must be same colorspace as in file */ - cinfo->out_color_components = cinfo->num_components; - break; - } - cinfo->output_components = (cinfo->quantize_colors ? 1 : - cinfo->out_color_components); - - /* See if upsampler will want to emit more than one row at a time */ - if (use_merged_upsample(cinfo)) - cinfo->rec_outbuf_height = cinfo->max_v_samp_factor; - else - cinfo->rec_outbuf_height = 1; -} - - -/* - * Several decompression processes need to range-limit values to the range - * 0..MAXJSAMPLE; the input value may fall somewhat outside this range - * due to noise introduced by quantization, roundoff error, etc. These - * processes are inner loops and need to be as fast as possible. On most - * machines, particularly CPUs with pipelines or instruction prefetch, - * a (subscript-check-less) C table lookup - * x = sample_range_limit[x]; - * is faster than explicit tests - * if (x < 0) x = 0; - * else if (x > MAXJSAMPLE) x = MAXJSAMPLE; - * These processes all use a common table prepared by the routine below. - * - * For most steps we can mathematically guarantee that the initial value - * of x is within 2*(MAXJSAMPLE+1) of the legal range, so a table running - * from -2*(MAXJSAMPLE+1) to 3*MAXJSAMPLE+2 is sufficient. But for the - * initial limiting step (just after the IDCT), a wildly out-of-range value - * is possible if the input data is corrupt. To avoid any chance of indexing - * off the end of memory and getting a bad-pointer trap, we perform the - * post-IDCT limiting thus: - * x = (sample_range_limit - SUBSET)[(x + CENTER) & MASK]; - * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit - * samples. Under normal circumstances this is more than enough range and - * a correct output will be generated; with bogus input data the mask will - * cause wraparound, and we will safely generate a bogus-but-in-range output. - * For the post-IDCT step, we want to convert the data from signed to unsigned - * representation by adding CENTERJSAMPLE at the same time that we limit it. - * This is accomplished with SUBSET = CENTER - CENTERJSAMPLE. - * - * Note that the table is allocated in near data space on PCs; it's small - * enough and used often enough to justify this. - */ - -LOCAL(void) -prepare_range_limit_table (j_decompress_ptr cinfo) -/* Allocate and fill in the sample_range_limit table */ -{ - JSAMPLE * table; - int i; - - table = (JSAMPLE *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, - JPOOL_IMAGE, (RANGE_CENTER * 2 + MAXJSAMPLE + 1) * SIZEOF(JSAMPLE)); - /* First segment of range limit table: limit[x] = 0 for x < 0 */ - MEMZERO(table, RANGE_CENTER * SIZEOF(JSAMPLE)); - table += RANGE_CENTER; /* allow negative subscripts of table */ - cinfo->sample_range_limit = table; - /* Main part of range limit table: limit[x] = x */ - for (i = 0; i <= MAXJSAMPLE; i++) - table[i] = (JSAMPLE) i; - /* End of range limit table: limit[x] = MAXJSAMPLE for x > MAXJSAMPLE */ - for (; i <= MAXJSAMPLE + RANGE_CENTER; i++) - table[i] = MAXJSAMPLE; -} - - -/* - * Master selection of decompression modules. - * This is done once at jpeg_start_decompress time. We determine - * which modules will be used and give them appropriate initialization calls. - * We also initialize the decompressor input side to begin consuming data. - * - * Since jpeg_read_header has finished, we know what is in the SOF - * and (first) SOS markers. We also have all the application parameter - * settings. - */ - -LOCAL(void) -master_selection (j_decompress_ptr cinfo) -{ - my_master_ptr master = (my_master_ptr) cinfo->master; - boolean use_c_buffer; - long samplesperrow; - JDIMENSION jd_samplesperrow; - - /* For now, precision must match compiled-in value... */ - if (cinfo->data_precision != BITS_IN_JSAMPLE) - ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); - - /* Initialize dimensions and other stuff */ - jpeg_calc_output_dimensions(cinfo); - prepare_range_limit_table(cinfo); - - /* Sanity check on image dimensions */ - if (cinfo->output_height <= 0 || cinfo->output_width <= 0 || - cinfo->out_color_components <= 0) - ERREXIT(cinfo, JERR_EMPTY_IMAGE); - - /* Width of an output scanline must be representable as JDIMENSION. */ - samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components; - jd_samplesperrow = (JDIMENSION) samplesperrow; - if ((long) jd_samplesperrow != samplesperrow) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); - - /* Initialize my private state */ - master->pass_number = 0; - master->using_merged_upsample = use_merged_upsample(cinfo); - - /* Color quantizer selection */ - master->quantizer_1pass = NULL; - master->quantizer_2pass = NULL; - /* No mode changes if not using buffered-image mode. */ - if (! cinfo->quantize_colors || ! cinfo->buffered_image) { - cinfo->enable_1pass_quant = FALSE; - cinfo->enable_external_quant = FALSE; - cinfo->enable_2pass_quant = FALSE; - } - if (cinfo->quantize_colors) { - if (cinfo->raw_data_out) - ERREXIT(cinfo, JERR_NOTIMPL); - /* 2-pass quantizer only works in 3-component color space. */ - if (cinfo->out_color_components != 3) { - cinfo->enable_1pass_quant = TRUE; - cinfo->enable_external_quant = FALSE; - cinfo->enable_2pass_quant = FALSE; - cinfo->colormap = NULL; - } else if (cinfo->colormap != NULL) { - cinfo->enable_external_quant = TRUE; - } else if (cinfo->two_pass_quantize) { - cinfo->enable_2pass_quant = TRUE; - } else { - cinfo->enable_1pass_quant = TRUE; - } - - if (cinfo->enable_1pass_quant) { -#ifdef QUANT_1PASS_SUPPORTED - jinit_1pass_quantizer(cinfo); - master->quantizer_1pass = cinfo->cquantize; -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } - - /* We use the 2-pass code to map to external colormaps. */ - if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) { -#ifdef QUANT_2PASS_SUPPORTED - jinit_2pass_quantizer(cinfo); - master->quantizer_2pass = cinfo->cquantize; -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } - /* If both quantizers are initialized, the 2-pass one is left active; - * this is necessary for starting with quantization to an external map. - */ - } - - /* Post-processing: in particular, color conversion first */ - if (! cinfo->raw_data_out) { - if (master->using_merged_upsample) { -#ifdef UPSAMPLE_MERGING_SUPPORTED - jinit_merged_upsampler(cinfo); /* does color conversion too */ -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else { - jinit_color_deconverter(cinfo); - jinit_upsampler(cinfo); - } - jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant); - } - /* Inverse DCT */ - jinit_inverse_dct(cinfo); - /* Entropy decoding: either Huffman or arithmetic coding. */ - if (cinfo->arith_code) - jinit_arith_decoder(cinfo); - else { - jinit_huff_decoder(cinfo); - } - - /* Initialize principal buffer controllers. */ - use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; - jinit_d_coef_controller(cinfo, use_c_buffer); - - if (! cinfo->raw_data_out) - jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */); - - /* We can now tell the memory manager to allocate virtual arrays. */ - (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); - - /* Initialize input side of decompressor to consume first scan. */ - (*cinfo->inputctl->start_input_pass) (cinfo); - -#ifdef D_MULTISCAN_FILES_SUPPORTED - /* If jpeg_start_decompress will read the whole file, initialize - * progress monitoring appropriately. The input step is counted - * as one pass. - */ - if (cinfo->progress != NULL && ! cinfo->buffered_image && - cinfo->inputctl->has_multiple_scans) { - int nscans; - /* Estimate number of scans to set pass_limit. */ - if (cinfo->progressive_mode) { - /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ - nscans = 2 + 3 * cinfo->num_components; - } else { - /* For a nonprogressive multiscan file, estimate 1 scan per component. */ - nscans = cinfo->num_components; - } - cinfo->progress->pass_counter = 0L; - cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans; - cinfo->progress->completed_passes = 0; - cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2); - /* Count the input pass as done */ - master->pass_number++; - } -#endif /* D_MULTISCAN_FILES_SUPPORTED */ -} - - -/* - * Per-pass setup. - * This is called at the beginning of each output pass. We determine which - * modules will be active during this pass and give them appropriate - * start_pass calls. We also set is_dummy_pass to indicate whether this - * is a "real" output pass or a dummy pass for color quantization. - * (In the latter case, jdapistd.c will crank the pass to completion.) - */ - -METHODDEF(void) -prepare_for_output_pass (j_decompress_ptr cinfo) -{ - my_master_ptr master = (my_master_ptr) cinfo->master; - - if (master->pub.is_dummy_pass) { -#ifdef QUANT_2PASS_SUPPORTED - /* Final pass of 2-pass quantization */ - master->pub.is_dummy_pass = FALSE; - (*cinfo->cquantize->start_pass) (cinfo, FALSE); - (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST); - (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif /* QUANT_2PASS_SUPPORTED */ - } else { - if (cinfo->quantize_colors && cinfo->colormap == NULL) { - /* Select new quantization method */ - if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) { - cinfo->cquantize = master->quantizer_2pass; - master->pub.is_dummy_pass = TRUE; - } else if (cinfo->enable_1pass_quant) { - cinfo->cquantize = master->quantizer_1pass; - } else { - ERREXIT(cinfo, JERR_MODE_CHANGE); - } - } - (*cinfo->idct->start_pass) (cinfo); - (*cinfo->coef->start_output_pass) (cinfo); - if (! cinfo->raw_data_out) { - if (! master->using_merged_upsample) - (*cinfo->cconvert->start_pass) (cinfo); - (*cinfo->upsample->start_pass) (cinfo); - if (cinfo->quantize_colors) - (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass); - (*cinfo->post->start_pass) (cinfo, - (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); - (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); - } - } - - /* Set up progress monitor's pass info if present */ - if (cinfo->progress != NULL) { - cinfo->progress->completed_passes = master->pass_number; - cinfo->progress->total_passes = master->pass_number + - (master->pub.is_dummy_pass ? 2 : 1); - /* In buffered-image mode, we assume one more output pass if EOI not - * yet reached, but no more passes if EOI has been reached. - */ - if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) { - cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1); - } - } -} - - -/* - * Finish up at end of an output pass. - */ - -METHODDEF(void) -finish_output_pass (j_decompress_ptr cinfo) -{ - my_master_ptr master = (my_master_ptr) cinfo->master; - - if (cinfo->quantize_colors) - (*cinfo->cquantize->finish_pass) (cinfo); - master->pass_number++; -} - - -#ifdef D_MULTISCAN_FILES_SUPPORTED - -/* - * Switch to a new external colormap between output passes. - */ - -GLOBAL(void) -jpeg_new_colormap (j_decompress_ptr cinfo) -{ - my_master_ptr master = (my_master_ptr) cinfo->master; - - /* Prevent application from calling me at wrong times */ - if (cinfo->global_state != DSTATE_BUFIMAGE) - ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - - if (cinfo->quantize_colors && cinfo->enable_external_quant && - cinfo->colormap != NULL) { - /* Select 2-pass quantizer for external colormap use */ - cinfo->cquantize = master->quantizer_2pass; - /* Notify quantizer of colormap change */ - (*cinfo->cquantize->new_color_map) (cinfo); - master->pub.is_dummy_pass = FALSE; /* just in case */ - } else - ERREXIT(cinfo, JERR_MODE_CHANGE); -} - -#endif /* D_MULTISCAN_FILES_SUPPORTED */ - - -/* - * Initialize master decompression control and select active modules. - * This is performed at the start of jpeg_start_decompress. - */ - -GLOBAL(void) -jinit_master_decompress (j_decompress_ptr cinfo) -{ - my_master_ptr master; - - master = (my_master_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_decomp_master)); - cinfo->master = &master->pub; - master->pub.prepare_for_output_pass = prepare_for_output_pass; - master->pub.finish_output_pass = finish_output_pass; - - master->pub.is_dummy_pass = FALSE; - - master_selection(cinfo); -} diff --git a/libraries/jpeg/jdmerge.c b/libraries/jpeg/jdmerge.c deleted file mode 100644 index 866693f52..000000000 --- a/libraries/jpeg/jdmerge.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * jdmerge.c - * - * Copyright (C) 1994-1996, Thomas G. Lane. - * Modified 2013-2017 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains code for merged upsampling/color conversion. - * - * This file combines functions from jdsample.c and jdcolor.c; - * read those files first to understand what's going on. - * - * When the chroma components are to be upsampled by simple replication - * (ie, box filtering), we can save some work in color conversion by - * calculating all the output pixels corresponding to a pair of chroma - * samples at one time. In the conversion equations - * R = Y + K1 * Cr - * G = Y + K2 * Cb + K3 * Cr - * B = Y + K4 * Cb - * only the Y term varies among the group of pixels corresponding to a pair - * of chroma samples, so the rest of the terms can be calculated just once. - * At typical sampling ratios, this eliminates half or three-quarters of the - * multiplications needed for color conversion. - * - * This file currently provides implementations for the following cases: - * YCC => RGB color conversion only (YCbCr or BG_YCC). - * Sampling ratios of 2h1v or 2h2v. - * No scaling needed at upsample time. - * Corner-aligned (non-CCIR601) sampling alignment. - * Other special cases could be added, but in most applications these are - * the only common cases. (For uncommon cases we fall back on the more - * general code in jdsample.c and jdcolor.c.) - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - -#ifdef UPSAMPLE_MERGING_SUPPORTED - - -#if RANGE_BITS < 2 - /* Deliberate syntax err */ - Sorry, this code requires 2 or more range extension bits. -#endif - - -/* Private subobject */ - -typedef struct { - struct jpeg_upsampler pub; /* public fields */ - - /* Pointer to routine to do actual upsampling/conversion of one row group */ - JMETHOD(void, upmethod, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, - JSAMPARRAY output_buf)); - - /* Private state for YCC->RGB conversion */ - int * Cr_r_tab; /* => table for Cr to R conversion */ - int * Cb_b_tab; /* => table for Cb to B conversion */ - INT32 * Cr_g_tab; /* => table for Cr to G conversion */ - INT32 * Cb_g_tab; /* => table for Cb to G conversion */ - - /* For 2:1 vertical sampling, we produce two output rows at a time. - * We need a "spare" row buffer to hold the second output row if the - * application provides just a one-row buffer; we also use the spare - * to discard the dummy last row if the image height is odd. - */ - JSAMPROW spare_row; - boolean spare_full; /* T if spare buffer is occupied */ - - JDIMENSION out_row_width; /* samples per output row */ - JDIMENSION rows_to_go; /* counts rows remaining in image */ -} my_upsampler; - -typedef my_upsampler * my_upsample_ptr; - -#define SCALEBITS 16 /* speediest right-shift on some machines */ -#define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) -#define FIX(x) ((INT32) ((x) * (1L<RGB and BG_YCC->RGB colorspace conversion. - * This is taken directly from jdcolor.c; see that file for more info. - */ - -LOCAL(void) -build_ycc_rgb_table (j_decompress_ptr cinfo) -/* Normal case, sYCC */ -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - int i; - INT32 x; - SHIFT_TEMPS - - upsample->Cr_r_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - upsample->Cb_b_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - upsample->Cr_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - upsample->Cb_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - - for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { - /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ - /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ - /* Cr=>R value is nearest int to 1.402 * x */ - upsample->Cr_r_tab[i] = (int) - RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS); - /* Cb=>B value is nearest int to 1.772 * x */ - upsample->Cb_b_tab[i] = (int) - RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS); - /* Cr=>G value is scaled-up -0.714136286 * x */ - upsample->Cr_g_tab[i] = (- FIX(0.714136286)) * x; - /* Cb=>G value is scaled-up -0.344136286 * x */ - /* We also add in ONE_HALF so that need not do it in inner loop */ - upsample->Cb_g_tab[i] = (- FIX(0.344136286)) * x + ONE_HALF; - } -} - - -LOCAL(void) -build_bg_ycc_rgb_table (j_decompress_ptr cinfo) -/* Wide gamut case, bg-sYCC */ -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - int i; - INT32 x; - SHIFT_TEMPS - - upsample->Cr_r_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - upsample->Cb_b_tab = (int *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(int)); - upsample->Cr_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - upsample->Cb_g_tab = (INT32 *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (MAXJSAMPLE+1) * SIZEOF(INT32)); - - for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { - /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ - /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ - /* Cr=>R value is nearest int to 2.804 * x */ - upsample->Cr_r_tab[i] = (int) - RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS); - /* Cb=>B value is nearest int to 3.544 * x */ - upsample->Cb_b_tab[i] = (int) - RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS); - /* Cr=>G value is scaled-up -1.428272572 * x */ - upsample->Cr_g_tab[i] = (- FIX(1.428272572)) * x; - /* Cb=>G value is scaled-up -0.688272572 * x */ - /* We also add in ONE_HALF so that need not do it in inner loop */ - upsample->Cb_g_tab[i] = (- FIX(0.688272572)) * x + ONE_HALF; - } -} - - -/* - * Initialize for an upsampling pass. - */ - -METHODDEF(void) -start_pass_merged_upsample (j_decompress_ptr cinfo) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - - /* Mark the spare buffer empty */ - upsample->spare_full = FALSE; - /* Initialize total-height counter for detecting bottom of image */ - upsample->rows_to_go = cinfo->output_height; -} - - -/* - * Control routine to do upsampling (and color conversion). - * - * The control routine just handles the row buffering considerations. - */ - -METHODDEF(void) -merged_2v_upsample (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -/* 2:1 vertical sampling case: may need a spare row. */ -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - JSAMPROW work_ptrs[2]; - JDIMENSION num_rows; /* number of rows returned to caller */ - - if (upsample->spare_full) { - /* If we have a spare row saved from a previous cycle, just return it. */ - jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0, - 1, upsample->out_row_width); - num_rows = 1; - upsample->spare_full = FALSE; - } else { - /* Figure number of rows to return to caller. */ - num_rows = 2; - /* Not more than the distance to the end of the image. */ - if (num_rows > upsample->rows_to_go) - num_rows = upsample->rows_to_go; - /* And not more than what the client can accept: */ - out_rows_avail -= *out_row_ctr; - if (num_rows > out_rows_avail) - num_rows = out_rows_avail; - /* Create output pointer array for upsampler. */ - work_ptrs[0] = output_buf[*out_row_ctr]; - if (num_rows > 1) { - work_ptrs[1] = output_buf[*out_row_ctr + 1]; - } else { - work_ptrs[1] = upsample->spare_row; - upsample->spare_full = TRUE; - } - /* Now do the upsampling. */ - (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs); - } - - /* Adjust counts */ - *out_row_ctr += num_rows; - upsample->rows_to_go -= num_rows; - /* When the buffer is emptied, declare this input row group consumed */ - if (! upsample->spare_full) - (*in_row_group_ctr)++; -} - - -METHODDEF(void) -merged_1v_upsample (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -/* 1:1 vertical sampling case: much easier, never need a spare row. */ -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - - /* Just do the upsampling. */ - (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, - output_buf + *out_row_ctr); - /* Adjust counts */ - (*out_row_ctr)++; - (*in_row_group_ctr)++; -} - - -/* - * These are the routines invoked by the control routines to do - * the actual upsampling/conversion. One row group is processed per call. - * - * Note: since we may be writing directly into application-supplied buffers, - * we have to be honest about the output width; we can't assume the buffer - * has been rounded up to an even width. - */ - - -/* - * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. - */ - -METHODDEF(void) -h2v1_merged_upsample (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, - JSAMPARRAY output_buf) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - register int y, cred, cgreen, cblue; - int cb, cr; - register JSAMPROW outptr; - JSAMPROW inptr0, inptr1, inptr2; - JDIMENSION col; - /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - int * Crrtab = upsample->Cr_r_tab; - int * Cbbtab = upsample->Cb_b_tab; - INT32 * Crgtab = upsample->Cr_g_tab; - INT32 * Cbgtab = upsample->Cb_g_tab; - SHIFT_TEMPS - - inptr0 = input_buf[0][in_row_group_ctr]; - inptr1 = input_buf[1][in_row_group_ctr]; - inptr2 = input_buf[2][in_row_group_ctr]; - outptr = output_buf[0]; - /* Loop for each pair of output pixels */ - for (col = cinfo->output_width >> 1; col > 0; col--) { - /* Do the chroma part of the calculation */ - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - /* Fetch 2 Y values and emit 2 pixels */ - y = GETJSAMPLE(*inptr0++); - outptr[RGB_RED] = range_limit[y + cred]; - outptr[RGB_GREEN] = range_limit[y + cgreen]; - outptr[RGB_BLUE] = range_limit[y + cblue]; - outptr += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr0++); - outptr[RGB_RED] = range_limit[y + cred]; - outptr[RGB_GREEN] = range_limit[y + cgreen]; - outptr[RGB_BLUE] = range_limit[y + cblue]; - outptr += RGB_PIXELSIZE; - } - /* If image width is odd, do the last output column separately */ - if (cinfo->output_width & 1) { - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr0); - outptr[RGB_RED] = range_limit[y + cred]; - outptr[RGB_GREEN] = range_limit[y + cgreen]; - outptr[RGB_BLUE] = range_limit[y + cblue]; - } -} - - -/* - * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. - */ - -METHODDEF(void) -h2v2_merged_upsample (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr, - JSAMPARRAY output_buf) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - register int y, cred, cgreen, cblue; - int cb, cr; - register JSAMPROW outptr0, outptr1; - JSAMPROW inptr00, inptr01, inptr1, inptr2; - JDIMENSION col; - /* copy these pointers into registers if possible */ - register JSAMPLE * range_limit = cinfo->sample_range_limit; - int * Crrtab = upsample->Cr_r_tab; - int * Cbbtab = upsample->Cb_b_tab; - INT32 * Crgtab = upsample->Cr_g_tab; - INT32 * Cbgtab = upsample->Cb_g_tab; - SHIFT_TEMPS - - inptr00 = input_buf[0][in_row_group_ctr*2]; - inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; - inptr1 = input_buf[1][in_row_group_ctr]; - inptr2 = input_buf[2][in_row_group_ctr]; - outptr0 = output_buf[0]; - outptr1 = output_buf[1]; - /* Loop for each group of output pixels */ - for (col = cinfo->output_width >> 1; col > 0; col--) { - /* Do the chroma part of the calculation */ - cb = GETJSAMPLE(*inptr1++); - cr = GETJSAMPLE(*inptr2++); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - /* Fetch 4 Y values and emit 4 pixels */ - y = GETJSAMPLE(*inptr00++); - outptr0[RGB_RED] = range_limit[y + cred]; - outptr0[RGB_GREEN] = range_limit[y + cgreen]; - outptr0[RGB_BLUE] = range_limit[y + cblue]; - outptr0 += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr00++); - outptr0[RGB_RED] = range_limit[y + cred]; - outptr0[RGB_GREEN] = range_limit[y + cgreen]; - outptr0[RGB_BLUE] = range_limit[y + cblue]; - outptr0 += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr01++); - outptr1[RGB_RED] = range_limit[y + cred]; - outptr1[RGB_GREEN] = range_limit[y + cgreen]; - outptr1[RGB_BLUE] = range_limit[y + cblue]; - outptr1 += RGB_PIXELSIZE; - y = GETJSAMPLE(*inptr01++); - outptr1[RGB_RED] = range_limit[y + cred]; - outptr1[RGB_GREEN] = range_limit[y + cgreen]; - outptr1[RGB_BLUE] = range_limit[y + cblue]; - outptr1 += RGB_PIXELSIZE; - } - /* If image width is odd, do the last output column separately */ - if (cinfo->output_width & 1) { - cb = GETJSAMPLE(*inptr1); - cr = GETJSAMPLE(*inptr2); - cred = Crrtab[cr]; - cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); - cblue = Cbbtab[cb]; - y = GETJSAMPLE(*inptr00); - outptr0[RGB_RED] = range_limit[y + cred]; - outptr0[RGB_GREEN] = range_limit[y + cgreen]; - outptr0[RGB_BLUE] = range_limit[y + cblue]; - y = GETJSAMPLE(*inptr01); - outptr1[RGB_RED] = range_limit[y + cred]; - outptr1[RGB_GREEN] = range_limit[y + cgreen]; - outptr1[RGB_BLUE] = range_limit[y + cblue]; - } -} - - -/* - * Module initialization routine for merged upsampling/color conversion. - * - * NB: this is called under the conditions determined by use_merged_upsample() - * in jdmaster.c. That routine MUST correspond to the actual capabilities - * of this module; no safety checks are made here. - */ - -GLOBAL(void) -jinit_merged_upsampler (j_decompress_ptr cinfo) -{ - my_upsample_ptr upsample; - - upsample = (my_upsample_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_upsampler)); - cinfo->upsample = &upsample->pub; - upsample->pub.start_pass = start_pass_merged_upsample; - upsample->pub.need_context_rows = FALSE; - - upsample->out_row_width = cinfo->output_width * cinfo->out_color_components; - - if (cinfo->max_v_samp_factor == 2) { - upsample->pub.upsample = merged_2v_upsample; - upsample->upmethod = h2v2_merged_upsample; - /* Allocate a spare row buffer */ - upsample->spare_row = (JSAMPROW) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE))); - } else { - upsample->pub.upsample = merged_1v_upsample; - upsample->upmethod = h2v1_merged_upsample; - /* No spare row needed */ - upsample->spare_row = NULL; - } - - if (cinfo->jpeg_color_space == JCS_BG_YCC) - build_bg_ycc_rgb_table(cinfo); - else - build_ycc_rgb_table(cinfo); -} - -#endif /* UPSAMPLE_MERGING_SUPPORTED */ diff --git a/libraries/jpeg/jdpostct.c b/libraries/jpeg/jdpostct.c deleted file mode 100644 index 571563d72..000000000 --- a/libraries/jpeg/jdpostct.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * jdpostct.c - * - * Copyright (C) 1994-1996, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the decompression postprocessing controller. - * This controller manages the upsampling, color conversion, and color - * quantization/reduction steps; specifically, it controls the buffering - * between upsample/color conversion and color quantization/reduction. - * - * If no color quantization/reduction is required, then this module has no - * work to do, and it just hands off to the upsample/color conversion code. - * An integrated upsample/convert/quantize process would replace this module - * entirely. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Private buffer controller object */ - -typedef struct { - struct jpeg_d_post_controller pub; /* public fields */ - - /* Color quantization source buffer: this holds output data from - * the upsample/color conversion step to be passed to the quantizer. - * For two-pass color quantization, we need a full-image buffer; - * for one-pass operation, a strip buffer is sufficient. - */ - jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */ - JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */ - JDIMENSION strip_height; /* buffer size in rows */ - /* for two-pass mode only: */ - JDIMENSION starting_row; /* row # of first row in current strip */ - JDIMENSION next_row; /* index of next row to fill/empty in strip */ -} my_post_controller; - -typedef my_post_controller * my_post_ptr; - - -/* Forward declarations */ -METHODDEF(void) post_process_1pass - JPP((j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); -#ifdef QUANT_2PASS_SUPPORTED -METHODDEF(void) post_process_prepass - JPP((j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); -METHODDEF(void) post_process_2pass - JPP((j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); -#endif - - -/* - * Initialize for a processing pass. - */ - -METHODDEF(void) -start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) -{ - my_post_ptr post = (my_post_ptr) cinfo->post; - - switch (pass_mode) { - case JBUF_PASS_THRU: - if (cinfo->quantize_colors) { - /* Single-pass processing with color quantization. */ - post->pub.post_process_data = post_process_1pass; - /* We could be doing buffered-image output before starting a 2-pass - * color quantization; in that case, jinit_d_post_controller did not - * allocate a strip buffer. Use the virtual-array buffer as workspace. - */ - if (post->buffer == NULL) { - post->buffer = (*cinfo->mem->access_virt_sarray) - ((j_common_ptr) cinfo, post->whole_image, - (JDIMENSION) 0, post->strip_height, TRUE); - } - } else { - /* For single-pass processing without color quantization, - * I have no work to do; just call the upsampler directly. - */ - post->pub.post_process_data = cinfo->upsample->upsample; - } - break; -#ifdef QUANT_2PASS_SUPPORTED - case JBUF_SAVE_AND_PASS: - /* First pass of 2-pass quantization */ - if (post->whole_image == NULL) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - post->pub.post_process_data = post_process_prepass; - break; - case JBUF_CRANK_DEST: - /* Second pass of 2-pass quantization */ - if (post->whole_image == NULL) - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - post->pub.post_process_data = post_process_2pass; - break; -#endif /* QUANT_2PASS_SUPPORTED */ - default: - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - break; - } - post->starting_row = post->next_row = 0; -} - - -/* - * Process some data in the one-pass (strip buffer) case. - * This is used for color precision reduction as well as one-pass quantization. - */ - -METHODDEF(void) -post_process_1pass (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - my_post_ptr post = (my_post_ptr) cinfo->post; - JDIMENSION num_rows, max_rows; - - /* Fill the buffer, but not more than what we can dump out in one go. */ - /* Note we rely on the upsampler to detect bottom of image. */ - max_rows = out_rows_avail - *out_row_ctr; - if (max_rows > post->strip_height) - max_rows = post->strip_height; - num_rows = 0; - (*cinfo->upsample->upsample) (cinfo, - input_buf, in_row_group_ctr, in_row_groups_avail, - post->buffer, &num_rows, max_rows); - /* Quantize and emit data. */ - (*cinfo->cquantize->color_quantize) (cinfo, - post->buffer, output_buf + *out_row_ctr, (int) num_rows); - *out_row_ctr += num_rows; -} - - -#ifdef QUANT_2PASS_SUPPORTED - -/* - * Process some data in the first pass of 2-pass quantization. - */ - -METHODDEF(void) -post_process_prepass (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - my_post_ptr post = (my_post_ptr) cinfo->post; - JDIMENSION old_next_row, num_rows; - - /* Reposition virtual buffer if at start of strip. */ - if (post->next_row == 0) { - post->buffer = (*cinfo->mem->access_virt_sarray) - ((j_common_ptr) cinfo, post->whole_image, - post->starting_row, post->strip_height, TRUE); - } - - /* Upsample some data (up to a strip height's worth). */ - old_next_row = post->next_row; - (*cinfo->upsample->upsample) (cinfo, - input_buf, in_row_group_ctr, in_row_groups_avail, - post->buffer, &post->next_row, post->strip_height); - - /* Allow quantizer to scan new data. No data is emitted, */ - /* but we advance out_row_ctr so outer loop can tell when we're done. */ - if (post->next_row > old_next_row) { - num_rows = post->next_row - old_next_row; - (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row, - (JSAMPARRAY) NULL, (int) num_rows); - *out_row_ctr += num_rows; - } - - /* Advance if we filled the strip. */ - if (post->next_row >= post->strip_height) { - post->starting_row += post->strip_height; - post->next_row = 0; - } -} - - -/* - * Process some data in the second pass of 2-pass quantization. - */ - -METHODDEF(void) -post_process_2pass (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - my_post_ptr post = (my_post_ptr) cinfo->post; - JDIMENSION num_rows, max_rows; - - /* Reposition virtual buffer if at start of strip. */ - if (post->next_row == 0) { - post->buffer = (*cinfo->mem->access_virt_sarray) - ((j_common_ptr) cinfo, post->whole_image, - post->starting_row, post->strip_height, FALSE); - } - - /* Determine number of rows to emit. */ - num_rows = post->strip_height - post->next_row; /* available in strip */ - max_rows = out_rows_avail - *out_row_ctr; /* available in output area */ - if (num_rows > max_rows) - num_rows = max_rows; - /* We have to check bottom of image here, can't depend on upsampler. */ - max_rows = cinfo->output_height - post->starting_row; - if (num_rows > max_rows) - num_rows = max_rows; - - /* Quantize and emit data. */ - (*cinfo->cquantize->color_quantize) (cinfo, - post->buffer + post->next_row, output_buf + *out_row_ctr, - (int) num_rows); - *out_row_ctr += num_rows; - - /* Advance if we filled the strip. */ - post->next_row += num_rows; - if (post->next_row >= post->strip_height) { - post->starting_row += post->strip_height; - post->next_row = 0; - } -} - -#endif /* QUANT_2PASS_SUPPORTED */ - - -/* - * Initialize postprocessing controller. - */ - -GLOBAL(void) -jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer) -{ - my_post_ptr post; - - post = (my_post_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_post_controller)); - cinfo->post = (struct jpeg_d_post_controller *) post; - post->pub.start_pass = start_pass_dpost; - post->whole_image = NULL; /* flag for no virtual arrays */ - post->buffer = NULL; /* flag for no strip buffer */ - - /* Create the quantization buffer, if needed */ - if (cinfo->quantize_colors) { - /* The buffer strip height is max_v_samp_factor, which is typically - * an efficient number of rows for upsampling to return. - * (In the presence of output rescaling, we might want to be smarter?) - */ - post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor; - if (need_full_buffer) { - /* Two-pass color quantization: need full-image storage. */ - /* We round up the number of rows to a multiple of the strip height. */ -#ifdef QUANT_2PASS_SUPPORTED - post->whole_image = (*cinfo->mem->request_virt_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, - cinfo->output_width * cinfo->out_color_components, - (JDIMENSION) jround_up((long) cinfo->output_height, - (long) post->strip_height), - post->strip_height); -#else - ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); -#endif /* QUANT_2PASS_SUPPORTED */ - } else { - /* One-pass color quantization: just make a strip buffer. */ - post->buffer = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->output_width * cinfo->out_color_components, - post->strip_height); - } - } -} diff --git a/libraries/jpeg/jdsample.c b/libraries/jpeg/jdsample.c deleted file mode 100644 index fd9907e20..000000000 --- a/libraries/jpeg/jdsample.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * jdsample.c - * - * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2002-2015 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains upsampling routines. - * - * Upsampling input data is counted in "row groups". A row group - * is defined to be (v_samp_factor * DCT_v_scaled_size / min_DCT_v_scaled_size) - * sample rows of each component. Upsampling will normally produce - * max_v_samp_factor pixel rows from each row group (but this could vary - * if the upsampler is applying a scale factor of its own). - * - * An excellent reference for image resampling is - * Digital Image Warping, George Wolberg, 1990. - * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* Pointer to routine to upsample a single component */ -typedef JMETHOD(void, upsample1_ptr, - (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)); - -/* Private subobject */ - -typedef struct { - struct jpeg_upsampler pub; /* public fields */ - - /* Color conversion buffer. When using separate upsampling and color - * conversion steps, this buffer holds one upsampled row group until it - * has been color converted and output. - * Note: we do not allocate any storage for component(s) which are full-size, - * ie do not need rescaling. The corresponding entry of color_buf[] is - * simply set to point to the input data array, thereby avoiding copying. - */ - JSAMPARRAY color_buf[MAX_COMPONENTS]; - - /* Per-component upsampling method pointers */ - upsample1_ptr methods[MAX_COMPONENTS]; - - int next_row_out; /* counts rows emitted from color_buf */ - JDIMENSION rows_to_go; /* counts rows remaining in image */ - - /* Height of an input row group for each component. */ - int rowgroup_height[MAX_COMPONENTS]; - - /* These arrays save pixel expansion factors so that int_expand need not - * recompute them each time. They are unused for other upsampling methods. - */ - UINT8 h_expand[MAX_COMPONENTS]; - UINT8 v_expand[MAX_COMPONENTS]; -} my_upsampler; - -typedef my_upsampler * my_upsample_ptr; - - -/* - * Initialize for an upsampling pass. - */ - -METHODDEF(void) -start_pass_upsample (j_decompress_ptr cinfo) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - - /* Mark the conversion buffer empty */ - upsample->next_row_out = cinfo->max_v_samp_factor; - /* Initialize total-height counter for detecting bottom of image */ - upsample->rows_to_go = cinfo->output_height; -} - - -/* - * Control routine to do upsampling (and color conversion). - * - * In this version we upsample each component independently. - * We upsample one row group into the conversion buffer, then apply - * color conversion a row at a time. - */ - -METHODDEF(void) -sep_upsample (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - int ci; - jpeg_component_info * compptr; - JDIMENSION num_rows; - - /* Fill the conversion buffer, if it's empty */ - if (upsample->next_row_out >= cinfo->max_v_samp_factor) { - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Invoke per-component upsample method. Notice we pass a POINTER - * to color_buf[ci], so that fullsize_upsample can change it. - */ - (*upsample->methods[ci]) (cinfo, compptr, - input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]), - upsample->color_buf + ci); - } - upsample->next_row_out = 0; - } - - /* Color-convert and emit rows */ - - /* How many we have in the buffer: */ - num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out); - /* Not more than the distance to the end of the image. Need this test - * in case the image height is not a multiple of max_v_samp_factor: - */ - if (num_rows > upsample->rows_to_go) - num_rows = upsample->rows_to_go; - /* And not more than what the client can accept: */ - out_rows_avail -= *out_row_ctr; - if (num_rows > out_rows_avail) - num_rows = out_rows_avail; - - (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf, - (JDIMENSION) upsample->next_row_out, - output_buf + *out_row_ctr, - (int) num_rows); - - /* Adjust counts */ - *out_row_ctr += num_rows; - upsample->rows_to_go -= num_rows; - upsample->next_row_out += num_rows; - /* When the buffer is emptied, declare this input row group consumed */ - if (upsample->next_row_out >= cinfo->max_v_samp_factor) - (*in_row_group_ctr)++; -} - - -/* - * These are the routines invoked by sep_upsample to upsample pixel values - * of a single component. One row group is processed per call. - */ - - -/* - * For full-size components, we just make color_buf[ci] point at the - * input buffer, and thus avoid copying any data. Note that this is - * safe only because sep_upsample doesn't declare the input row group - * "consumed" until we are done color converting and emitting it. - */ - -METHODDEF(void) -fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - *output_data_ptr = input_data; -} - - -/* - * This is a no-op version used for "uninteresting" components. - * These components will not be referenced by color conversion. - */ - -METHODDEF(void) -noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - *output_data_ptr = NULL; /* safety check */ -} - - -/* - * This version handles any integral sampling ratios. - * This is not used for typical JPEG files, so it need not be fast. - * Nor, for that matter, is it particularly accurate: the algorithm is - * simple replication of the input pixel onto the corresponding output - * pixels. The hi-falutin sampling literature refers to this as a - * "box filter". A box filter tends to introduce visible artifacts, - * so if you are actually going to use 3:1 or 4:1 sampling ratios - * you would be well advised to improve this code. - */ - -METHODDEF(void) -int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register JSAMPLE invalue; - register int h; - JSAMPROW outend; - int h_expand, v_expand; - int inrow, outrow; - - h_expand = upsample->h_expand[compptr->component_index]; - v_expand = upsample->v_expand[compptr->component_index]; - - inrow = outrow = 0; - while (outrow < cinfo->max_v_samp_factor) { - /* Generate one output row with proper horizontal expansion */ - inptr = input_data[inrow]; - outptr = output_data[outrow]; - outend = outptr + cinfo->output_width; - while (outptr < outend) { - invalue = *inptr++; /* don't need GETJSAMPLE() here */ - for (h = h_expand; h > 0; h--) { - *outptr++ = invalue; - } - } - /* Generate any additional output rows by duplicating the first one */ - if (v_expand > 1) { - jcopy_sample_rows(output_data, outrow, output_data, outrow+1, - v_expand-1, cinfo->output_width); - } - inrow++; - outrow += v_expand; - } -} - - -/* - * Fast processing for the common case of 2:1 horizontal and 1:1 vertical. - * It's still a box filter. - */ - -METHODDEF(void) -h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register JSAMPLE invalue; - JSAMPROW outend; - int outrow; - - for (outrow = 0; outrow < cinfo->max_v_samp_factor; outrow++) { - inptr = input_data[outrow]; - outptr = output_data[outrow]; - outend = outptr + cinfo->output_width; - while (outptr < outend) { - invalue = *inptr++; /* don't need GETJSAMPLE() here */ - *outptr++ = invalue; - *outptr++ = invalue; - } - } -} - - -/* - * Fast processing for the common case of 2:1 horizontal and 2:1 vertical. - * It's still a box filter. - */ - -METHODDEF(void) -h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) -{ - JSAMPARRAY output_data = *output_data_ptr; - register JSAMPROW inptr, outptr; - register JSAMPLE invalue; - JSAMPROW outend; - int inrow, outrow; - - inrow = outrow = 0; - while (outrow < cinfo->max_v_samp_factor) { - inptr = input_data[inrow]; - outptr = output_data[outrow]; - outend = outptr + cinfo->output_width; - while (outptr < outend) { - invalue = *inptr++; /* don't need GETJSAMPLE() here */ - *outptr++ = invalue; - *outptr++ = invalue; - } - jcopy_sample_rows(output_data, outrow, output_data, outrow+1, - 1, cinfo->output_width); - inrow++; - outrow += 2; - } -} - - -/* - * Module initialization routine for upsampling. - */ - -GLOBAL(void) -jinit_upsampler (j_decompress_ptr cinfo) -{ - my_upsample_ptr upsample; - int ci; - jpeg_component_info * compptr; - int h_in_group, v_in_group, h_out_group, v_out_group; - - upsample = (my_upsample_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_upsampler)); - cinfo->upsample = &upsample->pub; - upsample->pub.start_pass = start_pass_upsample; - upsample->pub.upsample = sep_upsample; - upsample->pub.need_context_rows = FALSE; /* until we find out differently */ - - if (cinfo->CCIR601_sampling) /* this isn't supported */ - ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); - - /* Verify we can handle the sampling factors, select per-component methods, - * and create storage as needed. - */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Compute size of an "input group" after IDCT scaling. This many samples - * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. - */ - h_in_group = (compptr->h_samp_factor * compptr->DCT_h_scaled_size) / - cinfo->min_DCT_h_scaled_size; - v_in_group = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) / - cinfo->min_DCT_v_scaled_size; - h_out_group = cinfo->max_h_samp_factor; - v_out_group = cinfo->max_v_samp_factor; - upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ - if (! compptr->component_needed) { - /* Don't bother to upsample an uninteresting component. */ - upsample->methods[ci] = noop_upsample; - continue; /* don't need to allocate buffer */ - } - if (h_in_group == h_out_group && v_in_group == v_out_group) { - /* Fullsize components can be processed without any work. */ - upsample->methods[ci] = fullsize_upsample; - continue; /* don't need to allocate buffer */ - } - if (h_in_group * 2 == h_out_group && v_in_group == v_out_group) { - /* Special case for 2h1v upsampling */ - upsample->methods[ci] = h2v1_upsample; - } else if (h_in_group * 2 == h_out_group && - v_in_group * 2 == v_out_group) { - /* Special case for 2h2v upsampling */ - upsample->methods[ci] = h2v2_upsample; - } else if ((h_out_group % h_in_group) == 0 && - (v_out_group % v_in_group) == 0) { - /* Generic integral-factors upsampling method */ - upsample->methods[ci] = int_upsample; - upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group); - upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group); - } else - ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL); - upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (JDIMENSION) jround_up((long) cinfo->output_width, - (long) cinfo->max_h_samp_factor), - (JDIMENSION) cinfo->max_v_samp_factor); - } -} diff --git a/libraries/jpeg/jerror.c b/libraries/jpeg/jerror.c deleted file mode 100644 index 7163af699..000000000 --- a/libraries/jpeg/jerror.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * jerror.c - * - * Copyright (C) 1991-1998, Thomas G. Lane. - * Modified 2012-2015 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains simple error-reporting and trace-message routines. - * These are suitable for Unix-like systems and others where writing to - * stderr is the right thing to do. Many applications will want to replace - * some or all of these routines. - * - * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile, - * you get a Windows-specific hack to display error messages in a dialog box. - * It ain't much, but it beats dropping error messages into the bit bucket, - * which is what happens to output to stderr under most Windows C compilers. - * - * These routines are used by both the compression and decompression code. - */ - -#ifdef USE_WINDOWS_MESSAGEBOX -#include -#endif - -/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ -#include "jinclude.h" -#include "jpeglib.h" -#include "jversion.h" -#include "jerror.h" - -#ifndef EXIT_FAILURE /* define exit() codes if not provided */ -#define EXIT_FAILURE 1 -#endif - - -/* - * Create the message string table. - * We do this from the master message list in jerror.h by re-reading - * jerror.h with a suitable definition for macro JMESSAGE. - * The message table is made an external symbol just in case any applications - * want to refer to it directly. - */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_std_message_table jMsgTable -#endif - -#define JMESSAGE(code,string) string , - -const char * const jpeg_std_message_table[] = { -#include "jerror.h" - NULL -}; - - -/* - * Error exit handler: must not return to caller. - * - * Applications may override this if they want to get control back after - * an error. Typically one would longjmp somewhere instead of exiting. - * The setjmp buffer can be made a private field within an expanded error - * handler object. Note that the info needed to generate an error message - * is stored in the error object, so you can generate the message now or - * later, at your convenience. - * You should make sure that the JPEG object is cleaned up (with jpeg_abort - * or jpeg_destroy) at some point. - */ - -METHODDEF(noreturn_t) -error_exit (j_common_ptr cinfo) -{ - /* Always display the message */ - (*cinfo->err->output_message) (cinfo); - - /* Let the memory manager delete any temp files before we die */ - jpeg_destroy(cinfo); - - exit(EXIT_FAILURE); -} - - -/* - * Actual output of an error or trace message. - * Applications may override this method to send JPEG messages somewhere - * other than stderr. - * - * On Windows, printing to stderr is generally completely useless, - * so we provide optional code to produce an error-dialog popup. - * Most Windows applications will still prefer to override this routine, - * but if they don't, it'll do something at least marginally useful. - * - * NOTE: to use the library in an environment that doesn't support the - * C stdio library, you may have to delete the call to fprintf() entirely, - * not just not use this routine. - */ - -METHODDEF(void) -output_message (j_common_ptr cinfo) -{ - char buffer[JMSG_LENGTH_MAX]; - - /* Create the message */ - (*cinfo->err->format_message) (cinfo, buffer); - -#ifdef USE_WINDOWS_MESSAGEBOX - /* Display it in a message dialog box */ - MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", - MB_OK | MB_ICONERROR); -#else - /* Send it to stderr, adding a newline */ - fprintf(stderr, "%s\n", buffer); -#endif -} - - -/* - * Decide whether to emit a trace or warning message. - * msg_level is one of: - * -1: recoverable corrupt-data warning, may want to abort. - * 0: important advisory messages (always display to user). - * 1: first level of tracing detail. - * 2,3,...: successively more detailed tracing messages. - * An application might override this method if it wanted to abort on warnings - * or change the policy about which messages to display. - */ - -METHODDEF(void) -emit_message (j_common_ptr cinfo, int msg_level) -{ - struct jpeg_error_mgr * err = cinfo->err; - - if (msg_level < 0) { - /* It's a warning message. Since corrupt files may generate many warnings, - * the policy implemented here is to show only the first warning, - * unless trace_level >= 3. - */ - if (err->num_warnings == 0 || err->trace_level >= 3) - (*err->output_message) (cinfo); - /* Always count warnings in num_warnings. */ - err->num_warnings++; - } else { - /* It's a trace message. Show it if trace_level >= msg_level. */ - if (err->trace_level >= msg_level) - (*err->output_message) (cinfo); - } -} - - -/* - * Format a message string for the most recent JPEG error or message. - * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX - * characters. Note that no '\n' character is added to the string. - * Few applications should need to override this method. - */ - -METHODDEF(void) -format_message (j_common_ptr cinfo, char * buffer) -{ - struct jpeg_error_mgr * err = cinfo->err; - int msg_code = err->msg_code; - const char * msgtext = NULL; - const char * msgptr; - char ch; - boolean isstring; - - /* Look up message string in proper table */ - if (msg_code > 0 && msg_code <= err->last_jpeg_message) { - msgtext = err->jpeg_message_table[msg_code]; - } else if (err->addon_message_table != NULL && - msg_code >= err->first_addon_message && - msg_code <= err->last_addon_message) { - msgtext = err->addon_message_table[msg_code - err->first_addon_message]; - } - - /* Defend against bogus message number */ - if (msgtext == NULL) { - err->msg_parm.i[0] = msg_code; - msgtext = err->jpeg_message_table[0]; - } - - /* Check for string parameter, as indicated by %s in the message text */ - isstring = FALSE; - msgptr = msgtext; - while ((ch = *msgptr++) != '\0') { - if (ch == '%') { - if (*msgptr == 's') isstring = TRUE; - break; - } - } - - /* Format the message into the passed buffer */ - if (isstring) - sprintf(buffer, msgtext, err->msg_parm.s); - else - sprintf(buffer, msgtext, - err->msg_parm.i[0], err->msg_parm.i[1], - err->msg_parm.i[2], err->msg_parm.i[3], - err->msg_parm.i[4], err->msg_parm.i[5], - err->msg_parm.i[6], err->msg_parm.i[7]); -} - - -/* - * Reset error state variables at start of a new image. - * This is called during compression startup to reset trace/error - * processing to default state, without losing any application-specific - * method pointers. An application might possibly want to override - * this method if it has additional error processing state. - */ - -METHODDEF(void) -reset_error_mgr (j_common_ptr cinfo) -{ - cinfo->err->num_warnings = 0; - /* trace_level is not reset since it is an application-supplied parameter */ - cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ -} - - -/* - * Fill in the standard error-handling methods in a jpeg_error_mgr object. - * Typical call is: - * struct jpeg_compress_struct cinfo; - * struct jpeg_error_mgr err; - * - * cinfo.err = jpeg_std_error(&err); - * after which the application may override some of the methods. - */ - -GLOBAL(struct jpeg_error_mgr *) -jpeg_std_error (struct jpeg_error_mgr * err) -{ - err->error_exit = error_exit; - err->emit_message = emit_message; - err->output_message = output_message; - err->format_message = format_message; - err->reset_error_mgr = reset_error_mgr; - - err->trace_level = 0; /* default = no tracing */ - err->num_warnings = 0; /* no warnings emitted yet */ - err->msg_code = 0; /* may be useful as a flag for "no error" */ - - /* Initialize message table pointers */ - err->jpeg_message_table = jpeg_std_message_table; - err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; - - err->addon_message_table = NULL; - err->first_addon_message = 0; /* for safety */ - err->last_addon_message = 0; - - return err; -} diff --git a/libraries/jpeg/jerror.h b/libraries/jpeg/jerror.h deleted file mode 100644 index a4b661f71..000000000 --- a/libraries/jpeg/jerror.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * jerror.h - * - * Copyright (C) 1994-1997, Thomas G. Lane. - * Modified 1997-2012 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file defines the error and message codes for the JPEG library. - * Edit this file to add new codes, or to translate the message strings to - * some other language. - * A set of error-reporting macros are defined too. Some applications using - * the JPEG library may wish to include this file to get the error codes - * and/or the macros. - */ - -/* - * To define the enum list of message codes, include this file without - * defining macro JMESSAGE. To create a message string table, include it - * again with a suitable JMESSAGE definition (see jerror.c for an example). - */ -#ifndef JMESSAGE -#ifndef JERROR_H -/* First time through, define the enum list */ -#define JMAKE_ENUM_LIST -#else -/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */ -#define JMESSAGE(code,string) -#endif /* JERROR_H */ -#endif /* JMESSAGE */ - -#ifdef JMAKE_ENUM_LIST - -typedef enum { - -#define JMESSAGE(code,string) code , - -#endif /* JMAKE_ENUM_LIST */ - -JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ - -/* For maintenance convenience, list is alphabetical by message code name */ -JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") -JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") -JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") -JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") -JMESSAGE(JERR_BAD_CROP_SPEC, "Invalid crop request") -JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") -JMESSAGE(JERR_BAD_DCTSIZE, "DCT scaled block size %dx%d not supported") -JMESSAGE(JERR_BAD_DROP_SAMPLING, - "Component index %d: mismatching sampling ratio %d:%d, %d:%d, %c") -JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") -JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") -JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") -JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") -JMESSAGE(JERR_BAD_LIB_VERSION, - "Wrong JPEG library version: library is %d, caller expects %d") -JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") -JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") -JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") -JMESSAGE(JERR_BAD_PROGRESSION, - "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") -JMESSAGE(JERR_BAD_PROG_SCRIPT, - "Invalid progressive parameters at scan script entry %d") -JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") -JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") -JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") -JMESSAGE(JERR_BAD_STRUCT_SIZE, - "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") -JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") -JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") -JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") -JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") -JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") -JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") -JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d") -JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x") -JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d") -JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d") -JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)") -JMESSAGE(JERR_EMS_READ, "Read from EMS failed") -JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed") -JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan") -JMESSAGE(JERR_FILE_READ, "Input file read error") -JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?") -JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet") -JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow") -JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry") -JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") -JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") -JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") -JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, - "Cannot transcode due to multiple use of quantization table %d") -JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") -JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") -JMESSAGE(JERR_NOTIMPL, "Not implemented yet") -JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") -JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined") -JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") -JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") -JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") -JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") -JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") -JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") -JMESSAGE(JERR_QUANT_COMPONENTS, - "Cannot quantize more than %d color components") -JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") -JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") -JMESSAGE(JERR_SOF_BEFORE, "Invalid JPEG file structure: %s before SOF") -JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") -JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") -JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x") -JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") -JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") -JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") -JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") -JMESSAGE(JERR_TFILE_WRITE, - "Write failed on temporary file --- out of disk space?") -JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") -JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") -JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") -JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation") -JMESSAGE(JERR_XMS_READ, "Read from XMS failed") -JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") -JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) -JMESSAGE(JMSG_VERSION, JVERSION) -JMESSAGE(JTRC_16BIT_TABLES, - "Caution: quantization tables are too coarse for baseline JPEG") -JMESSAGE(JTRC_ADOBE, - "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") -JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") -JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") -JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") -JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x") -JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d") -JMESSAGE(JTRC_DRI, "Define Restart Interval %u") -JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u") -JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u") -JMESSAGE(JTRC_EOI, "End Of Image") -JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") -JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") -JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, - "Warning: thumbnail image size does not match data length %u") -JMESSAGE(JTRC_JFIF_EXTENSION, - "JFIF extension marker: type 0x%02x, length %u") -JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") -JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") -JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") -JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u") -JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors") -JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors") -JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") -JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") -JMESSAGE(JTRC_RST, "RST%d") -JMESSAGE(JTRC_SMOOTH_NOTIMPL, - "Smoothing not supported with nonstandard sampling ratios") -JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") -JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") -JMESSAGE(JTRC_SOI, "Start of Image") -JMESSAGE(JTRC_SOS, "Start Of Scan: %d components") -JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d") -JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") -JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") -JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") -JMESSAGE(JTRC_THUMB_JPEG, - "JFIF extension marker: JPEG-compressed thumbnail image, length %u") -JMESSAGE(JTRC_THUMB_PALETTE, - "JFIF extension marker: palette thumbnail image, length %u") -JMESSAGE(JTRC_THUMB_RGB, - "JFIF extension marker: RGB thumbnail image, length %u") -JMESSAGE(JTRC_UNKNOWN_IDS, - "Unrecognized component IDs %d %d %d, assuming YCbCr") -JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") -JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") -JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") -JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code") -JMESSAGE(JWRN_BOGUS_PROGRESSION, - "Inconsistent progression sequence for component %d coefficient %d") -JMESSAGE(JWRN_EXTRANEOUS_DATA, - "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") -JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") -JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") -JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") -JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") -JMESSAGE(JWRN_MUST_RESYNC, - "Corrupt JPEG data: found marker 0x%02x instead of RST%d") -JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") -JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") - -#ifdef JMAKE_ENUM_LIST - - JMSG_LASTMSGCODE -} J_MESSAGE_CODE; - -#undef JMAKE_ENUM_LIST -#endif /* JMAKE_ENUM_LIST */ - -/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */ -#undef JMESSAGE - - -#ifndef JERROR_H -#define JERROR_H - -/* Macros to simplify using the error and trace message stuff */ -/* The first parameter is either type of cinfo pointer */ - -/* Fatal errors (print message and exit) */ -#define ERREXIT(cinfo,code) \ - ((cinfo)->err->msg_code = (code), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT1(cinfo,code,p1) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT2(cinfo,code,p1,p2) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT3(cinfo,code,p1,p2,p3) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (cinfo)->err->msg_parm.i[2] = (p3), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (cinfo)->err->msg_parm.i[2] = (p3), \ - (cinfo)->err->msg_parm.i[3] = (p4), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXIT6(cinfo,code,p1,p2,p3,p4,p5,p6) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (cinfo)->err->msg_parm.i[2] = (p3), \ - (cinfo)->err->msg_parm.i[3] = (p4), \ - (cinfo)->err->msg_parm.i[4] = (p5), \ - (cinfo)->err->msg_parm.i[5] = (p6), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define ERREXITS(cinfo,code,str) \ - ((cinfo)->err->msg_code = (code), \ - strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ - (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) - -#define MAKESTMT(stuff) do { stuff } while (0) - -/* Nonfatal errors (we can keep going, but the data is probably corrupt) */ -#define WARNMS(cinfo,code) \ - ((cinfo)->err->msg_code = (code), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) -#define WARNMS1(cinfo,code,p1) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) -#define WARNMS2(cinfo,code,p1,p2) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1)) - -/* Informational/debugging messages */ -#define TRACEMS(cinfo,lvl,code) \ - ((cinfo)->err->msg_code = (code), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) -#define TRACEMS1(cinfo,lvl,code,p1) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) -#define TRACEMS2(cinfo,lvl,code,p1,p2) \ - ((cinfo)->err->msg_code = (code), \ - (cinfo)->err->msg_parm.i[0] = (p1), \ - (cinfo)->err->msg_parm.i[1] = (p2), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) -#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - _mp[4] = (p5); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ - MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) -#define TRACEMSS(cinfo,lvl,code,str) \ - ((cinfo)->err->msg_code = (code), \ - strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) - -#endif /* JERROR_H */ diff --git a/libraries/jpeg/jidctflt.c b/libraries/jpeg/jidctflt.c deleted file mode 100644 index e33a2b5e4..000000000 --- a/libraries/jpeg/jidctflt.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * jidctflt.c - * - * Copyright (C) 1994-1998, Thomas G. Lane. - * Modified 2010-2017 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a floating-point implementation of the - * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine - * must also perform dequantization of the input coefficients. - * - * This implementation should be more accurate than either of the integer - * IDCT implementations. However, it may not give the same results on all - * machines because of differences in roundoff behavior. Speed will depend - * on the hardware's floating point capacity. - * - * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT - * on each row (or vice versa, but it's more convenient to emit a row at - * a time). Direct algorithms are also available, but they are much more - * complex and seem not to be any faster when reduced to code. - * - * This implementation is based on Arai, Agui, and Nakajima's algorithm for - * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in - * Japanese, but the algorithm is described in the Pennebaker & Mitchell - * JPEG textbook (see REFERENCES section in file README). The following code - * is based directly on figure 4-8 in P&M. - * While an 8-point DCT cannot be done in less than 11 multiplies, it is - * possible to arrange the computation so that many of the multiplies are - * simple scalings of the final outputs. These multiplies can then be - * folded into the multiplications or divisions by the JPEG quantization - * table entries. The AA&N method leaves only 5 multiplies and 29 adds - * to be done in the DCT itself. - * The primary disadvantage of this method is that with a fixed-point - * implementation, accuracy is lost due to imprecise representation of the - * scaled quantization values. However, that problem does not arise if - * we use floating point arithmetic. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - -#ifdef DCT_FLOAT_SUPPORTED - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCT blocks. /* deliberate syntax err */ -#endif - - -/* Dequantize a coefficient by multiplying it by the multiplier-table - * entry; produce a float result. - */ - -#define DEQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval)) - - -/* - * Perform dequantization and inverse DCT on one block of coefficients. - * - * cK represents cos(K*pi/16). - */ - -GLOBAL(void) -jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - FAST_FLOAT tmp10, tmp11, tmp12, tmp13; - FAST_FLOAT z5, z10, z11, z12, z13; - JCOEFPTR inptr; - FLOAT_MULT_TYPE * quantptr; - FAST_FLOAT * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */ - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = DCTSIZE; ctr > 0; ctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any column in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * column DCT calculations can be simplified this way. - */ - - if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && - inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && - inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && - inptr[DCTSIZE*7] == 0) { - /* AC terms all zero */ - FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - - wsptr[DCTSIZE*0] = dcval; - wsptr[DCTSIZE*1] = dcval; - wsptr[DCTSIZE*2] = dcval; - wsptr[DCTSIZE*3] = dcval; - wsptr[DCTSIZE*4] = dcval; - wsptr[DCTSIZE*5] = dcval; - wsptr[DCTSIZE*6] = dcval; - wsptr[DCTSIZE*7] = dcval; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - continue; - } - - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp10 = tmp0 + tmp2; /* phase 3 */ - tmp11 = tmp0 - tmp2; - - tmp13 = tmp1 + tmp3; /* phases 5-3 */ - tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ - - tmp0 = tmp10 + tmp13; /* phase 2 */ - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - /* Odd part */ - - tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - z13 = tmp6 + tmp5; /* phase 6 */ - z10 = tmp6 - tmp5; - z11 = tmp4 + tmp7; - z12 = tmp4 - tmp7; - - tmp7 = z11 + z13; /* phase 5 */ - tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ - - z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ - tmp10 = z5 - z12 * ((FAST_FLOAT) 1.082392200); /* 2*(c2-c6) */ - tmp12 = z5 - z10 * ((FAST_FLOAT) 2.613125930); /* 2*(c2+c6) */ - - tmp6 = tmp12 - tmp7; /* phase 2 */ - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 - tmp5; - - wsptr[DCTSIZE*0] = tmp0 + tmp7; - wsptr[DCTSIZE*7] = tmp0 - tmp7; - wsptr[DCTSIZE*1] = tmp1 + tmp6; - wsptr[DCTSIZE*6] = tmp1 - tmp6; - wsptr[DCTSIZE*2] = tmp2 + tmp5; - wsptr[DCTSIZE*5] = tmp2 - tmp5; - wsptr[DCTSIZE*3] = tmp3 + tmp4; - wsptr[DCTSIZE*4] = tmp3 - tmp4; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - } - - /* Pass 2: process rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < DCTSIZE; ctr++) { - outptr = output_buf[ctr] + output_col; - /* Rows of zeroes can be exploited in the same way as we did with columns. - * However, the column calculation has created many nonzero AC terms, so - * the simplification applies less often (typically 5% to 10% of the time). - * And testing floats for zero is relatively expensive, so we don't bother. - */ - - /* Even part */ - - /* Prepare range-limit and float->int conversion */ - z5 = wsptr[0] + (((FAST_FLOAT) RANGE_CENTER) + ((FAST_FLOAT) 0.5)); - tmp10 = z5 + wsptr[4]; - tmp11 = z5 - wsptr[4]; - - tmp13 = wsptr[2] + wsptr[6]; - tmp12 = (wsptr[2] - wsptr[6]) * - ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ - - tmp0 = tmp10 + tmp13; - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - /* Odd part */ - - z13 = wsptr[5] + wsptr[3]; - z10 = wsptr[5] - wsptr[3]; - z11 = wsptr[1] + wsptr[7]; - z12 = wsptr[1] - wsptr[7]; - - tmp7 = z11 + z13; /* phase 5 */ - tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ - - z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ - tmp10 = z5 - z12 * ((FAST_FLOAT) 1.082392200); /* 2*(c2-c6) */ - tmp12 = z5 - z10 * ((FAST_FLOAT) 2.613125930); /* 2*(c2+c6) */ - - tmp6 = tmp12 - tmp7; /* phase 2 */ - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 - tmp5; - - /* Final output stage: float->int conversion and range-limit */ - - outptr[0] = range_limit[(int) (tmp0 + tmp7) & RANGE_MASK]; - outptr[7] = range_limit[(int) (tmp0 - tmp7) & RANGE_MASK]; - outptr[1] = range_limit[(int) (tmp1 + tmp6) & RANGE_MASK]; - outptr[6] = range_limit[(int) (tmp1 - tmp6) & RANGE_MASK]; - outptr[2] = range_limit[(int) (tmp2 + tmp5) & RANGE_MASK]; - outptr[5] = range_limit[(int) (tmp2 - tmp5) & RANGE_MASK]; - outptr[3] = range_limit[(int) (tmp3 + tmp4) & RANGE_MASK]; - outptr[4] = range_limit[(int) (tmp3 - tmp4) & RANGE_MASK]; - - wsptr += DCTSIZE; /* advance pointer to next row */ - } -} - -#endif /* DCT_FLOAT_SUPPORTED */ diff --git a/libraries/jpeg/jidctfst.c b/libraries/jpeg/jidctfst.c deleted file mode 100644 index 1ac3e39cb..000000000 --- a/libraries/jpeg/jidctfst.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * jidctfst.c - * - * Copyright (C) 1994-1998, Thomas G. Lane. - * Modified 2015-2017 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a fast, not so accurate integer implementation of the - * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine - * must also perform dequantization of the input coefficients. - * - * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT - * on each row (or vice versa, but it's more convenient to emit a row at - * a time). Direct algorithms are also available, but they are much more - * complex and seem not to be any faster when reduced to code. - * - * This implementation is based on Arai, Agui, and Nakajima's algorithm for - * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in - * Japanese, but the algorithm is described in the Pennebaker & Mitchell - * JPEG textbook (see REFERENCES section in file README). The following code - * is based directly on figure 4-8 in P&M. - * While an 8-point DCT cannot be done in less than 11 multiplies, it is - * possible to arrange the computation so that many of the multiplies are - * simple scalings of the final outputs. These multiplies can then be - * folded into the multiplications or divisions by the JPEG quantization - * table entries. The AA&N method leaves only 5 multiplies and 29 adds - * to be done in the DCT itself. - * The primary disadvantage of this method is that with fixed-point math, - * accuracy is lost due to imprecise representation of the scaled - * quantization values. The smaller the quantization table entry, the less - * precise the scaled value, so this implementation does worse with high- - * quality-setting files than with low-quality ones. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - -#ifdef DCT_IFAST_SUPPORTED - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCT blocks. /* deliberate syntax err */ -#endif - - -/* Scaling decisions are generally the same as in the LL&M algorithm; - * see jidctint.c for more details. However, we choose to descale - * (right shift) multiplication products as soon as they are formed, - * rather than carrying additional fractional bits into subsequent additions. - * This compromises accuracy slightly, but it lets us save a few shifts. - * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples) - * everywhere except in the multiplications proper; this saves a good deal - * of work on 16-bit-int machines. - * - * The dequantized coefficients are not integers because the AA&N scaling - * factors have been incorporated. We represent them scaled up by PASS1_BITS, - * so that the first and second IDCT rounds have the same input scaling. - * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to - * avoid a descaling shift; this compromises accuracy rather drastically - * for small quantization table entries, but it saves a lot of shifts. - * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway, - * so we use a much larger scaling factor to preserve accuracy. - * - * A final compromise is to represent the multiplicative constants to only - * 8 fractional bits, rather than 13. This saves some shifting work on some - * machines, and may also reduce the cost of multiplication (since there - * are fewer one-bits in the constants). - */ - -#if BITS_IN_JSAMPLE == 8 -#define CONST_BITS 8 -#define PASS1_BITS 2 -#else -#define CONST_BITS 8 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ -#endif - -/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus - * causing a lot of useless floating-point operations at run time. - * To get around this we use the following pre-calculated constants. - * If you change CONST_BITS you may want to add appropriate values. - * (With a reasonable C compiler, you can just rely on the FIX() macro...) - */ - -#if CONST_BITS == 8 -#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */ -#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */ -#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */ -#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */ -#else -#define FIX_1_082392200 FIX(1.082392200) -#define FIX_1_414213562 FIX(1.414213562) -#define FIX_1_847759065 FIX(1.847759065) -#define FIX_2_613125930 FIX(2.613125930) -#endif - - -/* We can gain a little more speed, with a further compromise in accuracy, - * by omitting the addition in a descaling shift. This yields an incorrectly - * rounded result half the time... - */ - -#ifndef USE_ACCURATE_ROUNDING -#undef DESCALE -#define DESCALE(x,n) RIGHT_SHIFT(x, n) -#endif - - -/* Multiply a DCTELEM variable by an INT32 constant, and immediately - * descale to yield a DCTELEM result. - */ - -#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS)) - - -/* Dequantize a coefficient by multiplying it by the multiplier-table - * entry; produce a DCTELEM result. For 8-bit data a 16x16->16 - * multiplication will do. For 12-bit data, the multiplier table is - * declared INT32, so a 32-bit multiply will be used. - */ - -#if BITS_IN_JSAMPLE == 8 -#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval)) -#else -#define DEQUANTIZE(coef,quantval) \ - DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS) -#endif - - -/* - * Perform dequantization and inverse DCT on one block of coefficients. - * - * cK represents cos(K*pi/16). - */ - -GLOBAL(void) -jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; - DCTELEM tmp10, tmp11, tmp12, tmp13; - DCTELEM z5, z10, z11, z12, z13; - JCOEFPTR inptr; - IFAST_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[DCTSIZE2]; /* buffers data between passes */ - SHIFT_TEMPS /* for DESCALE */ - ISHIFT_TEMPS /* for IRIGHT_SHIFT */ - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (IFAST_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = DCTSIZE; ctr > 0; ctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any column in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * column DCT calculations can be simplified this way. - */ - - if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && - inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && - inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && - inptr[DCTSIZE*7] == 0) { - /* AC terms all zero */ - int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - - wsptr[DCTSIZE*0] = dcval; - wsptr[DCTSIZE*1] = dcval; - wsptr[DCTSIZE*2] = dcval; - wsptr[DCTSIZE*3] = dcval; - wsptr[DCTSIZE*4] = dcval; - wsptr[DCTSIZE*5] = dcval; - wsptr[DCTSIZE*6] = dcval; - wsptr[DCTSIZE*7] = dcval; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - continue; - } - - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp10 = tmp0 + tmp2; /* phase 3 */ - tmp11 = tmp0 - tmp2; - - tmp13 = tmp1 + tmp3; /* phases 5-3 */ - tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */ - - tmp0 = tmp10 + tmp13; /* phase 2 */ - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - /* Odd part */ - - tmp4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - tmp5 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - z13 = tmp6 + tmp5; /* phase 6 */ - z10 = tmp6 - tmp5; - z11 = tmp4 + tmp7; - z12 = tmp4 - tmp7; - - tmp7 = z11 + z13; /* phase 5 */ - tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ - - z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ - tmp10 = z5 - MULTIPLY(z12, FIX_1_082392200); /* 2*(c2-c6) */ - tmp12 = z5 - MULTIPLY(z10, FIX_2_613125930); /* 2*(c2+c6) */ - - tmp6 = tmp12 - tmp7; /* phase 2 */ - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 - tmp5; - - wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7); - wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7); - wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6); - wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6); - wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5); - wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5); - wsptr[DCTSIZE*3] = (int) (tmp3 + tmp4); - wsptr[DCTSIZE*4] = (int) (tmp3 - tmp4); - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - } - - /* Pass 2: process rows from work array, store into output array. - * Note that we must descale the results by a factor of 8 == 2**3, - * and also undo the PASS1_BITS scaling. - */ - - wsptr = workspace; - for (ctr = 0; ctr < DCTSIZE; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Add range center and fudge factor for final descale and range-limit. */ - z5 = (DCTELEM) wsptr[0] + - ((((DCTELEM) RANGE_CENTER) << (PASS1_BITS+3)) + - (1 << (PASS1_BITS+2))); - - /* Rows of zeroes can be exploited in the same way as we did with columns. - * However, the column calculation has created many nonzero AC terms, so - * the simplification applies less often (typically 5% to 10% of the time). - * On machines with very fast multiplication, it's possible that the - * test takes more time than it's worth. In that case this section - * may be commented out. - */ - -#ifndef NO_ZERO_ROW_TEST - if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && - wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { - /* AC terms all zero */ - JSAMPLE dcval = range_limit[(int) IRIGHT_SHIFT(z5, PASS1_BITS+3) - & RANGE_MASK]; - - outptr[0] = dcval; - outptr[1] = dcval; - outptr[2] = dcval; - outptr[3] = dcval; - outptr[4] = dcval; - outptr[5] = dcval; - outptr[6] = dcval; - outptr[7] = dcval; - - wsptr += DCTSIZE; /* advance pointer to next row */ - continue; - } -#endif - - /* Even part */ - - tmp10 = z5 + (DCTELEM) wsptr[4]; - tmp11 = z5 - (DCTELEM) wsptr[4]; - - tmp13 = (DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]; - tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], - FIX_1_414213562) - tmp13; /* 2*c4 */ - - tmp0 = tmp10 + tmp13; - tmp3 = tmp10 - tmp13; - tmp1 = tmp11 + tmp12; - tmp2 = tmp11 - tmp12; - - /* Odd part */ - - z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; - z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; - z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; - z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; - - tmp7 = z11 + z13; /* phase 5 */ - tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ - - z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ - tmp10 = z5 - MULTIPLY(z12, FIX_1_082392200); /* 2*(c2-c6) */ - tmp12 = z5 - MULTIPLY(z10, FIX_2_613125930); /* 2*(c2+c6) */ - - tmp6 = tmp12 - tmp7; /* phase 2 */ - tmp5 = tmp11 - tmp6; - tmp4 = tmp10 - tmp5; - - /* Final output stage: scale down by a factor of 8 and range-limit */ - - outptr[0] = range_limit[(int) IRIGHT_SHIFT(tmp0 + tmp7, PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) IRIGHT_SHIFT(tmp0 - tmp7, PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) IRIGHT_SHIFT(tmp1 + tmp6, PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) IRIGHT_SHIFT(tmp1 - tmp6, PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) IRIGHT_SHIFT(tmp2 + tmp5, PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) IRIGHT_SHIFT(tmp2 - tmp5, PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) IRIGHT_SHIFT(tmp3 + tmp4, PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) IRIGHT_SHIFT(tmp3 - tmp4, PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += DCTSIZE; /* advance pointer to next row */ - } -} - -#endif /* DCT_IFAST_SUPPORTED */ diff --git a/libraries/jpeg/jidctint.c b/libraries/jpeg/jidctint.c deleted file mode 100644 index 6437079a3..000000000 --- a/libraries/jpeg/jidctint.c +++ /dev/null @@ -1,5240 +0,0 @@ -/* - * jidctint.c - * - * Copyright (C) 1991-1998, Thomas G. Lane. - * Modification developed 2002-2016 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains a slow-but-accurate integer implementation of the - * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine - * must also perform dequantization of the input coefficients. - * - * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT - * on each row (or vice versa, but it's more convenient to emit a row at - * a time). Direct algorithms are also available, but they are much more - * complex and seem not to be any faster when reduced to code. - * - * This implementation is based on an algorithm described in - * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT - * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics, - * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991. - * The primary algorithm described there uses 11 multiplies and 29 adds. - * We use their alternate method with 12 multiplies and 32 adds. - * The advantage of this method is that no data path contains more than one - * multiplication; this allows a very simple and accurate implementation in - * scaled fixed-point arithmetic, with a minimal number of shifts. - * - * We also provide IDCT routines with various output sample block sizes for - * direct resolution reduction or enlargement and for direct resolving the - * common 2x1 and 1x2 subsampling cases without additional resampling: NxN - * (N=1...16), 2NxN, and Nx2N (N=1...8) pixels for one 8x8 input DCT block. - * - * For N<8 we simply take the corresponding low-frequency coefficients of - * the 8x8 input DCT block and apply an NxN point IDCT on the sub-block - * to yield the downscaled outputs. - * This can be seen as direct low-pass downsampling from the DCT domain - * point of view rather than the usual spatial domain point of view, - * yielding significant computational savings and results at least - * as good as common bilinear (averaging) spatial downsampling. - * - * For N>8 we apply a partial NxN IDCT on the 8 input coefficients as - * lower frequencies and higher frequencies assumed to be zero. - * It turns out that the computational effort is similar to the 8x8 IDCT - * regarding the output size. - * Furthermore, the scaling and descaling is the same for all IDCT sizes. - * - * CAUTION: We rely on the FIX() macro except for the N=1,2,4,8 cases - * since there would be too many additional constants to pre-calculate. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ - -#ifdef DCT_ISLOW_SUPPORTED - - -/* - * This module is specialized to the case DCTSIZE = 8. - */ - -#if DCTSIZE != 8 - Sorry, this code only copes with 8x8 DCT blocks. /* deliberate syntax err */ -#endif - - -/* - * The poop on this scaling stuff is as follows: - * - * Each 1-D IDCT step produces outputs which are a factor of sqrt(N) - * larger than the true IDCT outputs. The final outputs are therefore - * a factor of N larger than desired; since N=8 this can be cured by - * a simple right shift at the end of the algorithm. The advantage of - * this arrangement is that we save two multiplications per 1-D IDCT, - * because the y0 and y4 inputs need not be divided by sqrt(N). - * - * We have to do addition and subtraction of the integer inputs, which - * is no problem, and multiplication by fractional constants, which is - * a problem to do in integer arithmetic. We multiply all the constants - * by CONST_SCALE and convert them to integer constants (thus retaining - * CONST_BITS bits of precision in the constants). After doing a - * multiplication we have to divide the product by CONST_SCALE, with proper - * rounding, to produce the correct output. This division can be done - * cheaply as a right shift of CONST_BITS bits. We postpone shifting - * as long as possible so that partial sums can be added together with - * full fractional precision. - * - * The outputs of the first pass are scaled up by PASS1_BITS bits so that - * they are represented to better-than-integral precision. These outputs - * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word - * with the recommended scaling. (To scale up 12-bit sample data further, an - * intermediate INT32 array would be needed.) - * - * To avoid overflow of the 32-bit intermediate results in pass 2, we must - * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis - * shows that the values given below are the most effective. - */ - -#if BITS_IN_JSAMPLE == 8 -#define CONST_BITS 13 -#define PASS1_BITS 2 -#else -#define CONST_BITS 13 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ -#endif - -/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus - * causing a lot of useless floating-point operations at run time. - * To get around this we use the following pre-calculated constants. - * If you change CONST_BITS you may want to add appropriate values. - * (With a reasonable C compiler, you can just rely on the FIX() macro...) - */ - -#if CONST_BITS == 13 -#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ -#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ -#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ -#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ -#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ -#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ -#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ -#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ -#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ -#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ -#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ -#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ -#else -#define FIX_0_298631336 FIX(0.298631336) -#define FIX_0_390180644 FIX(0.390180644) -#define FIX_0_541196100 FIX(0.541196100) -#define FIX_0_765366865 FIX(0.765366865) -#define FIX_0_899976223 FIX(0.899976223) -#define FIX_1_175875602 FIX(1.175875602) -#define FIX_1_501321110 FIX(1.501321110) -#define FIX_1_847759065 FIX(1.847759065) -#define FIX_1_961570560 FIX(1.961570560) -#define FIX_2_053119869 FIX(2.053119869) -#define FIX_2_562915447 FIX(2.562915447) -#define FIX_3_072711026 FIX(3.072711026) -#endif - - -/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result. - * For 8-bit samples with the recommended scaling, all the variable - * and constant values involved are no more than 16 bits wide, so a - * 16x16->32 bit multiply can be used instead of a full 32x32 multiply. - * For 12-bit samples, a full 32-bit multiplication will be needed. - */ - -#if BITS_IN_JSAMPLE == 8 -#define MULTIPLY(var,const) MULTIPLY16C16(var,const) -#else -#define MULTIPLY(var,const) ((var) * (const)) -#endif - - -/* Dequantize a coefficient by multiplying it by the multiplier-table - * entry; produce an int result. In this module, both inputs and result - * are 16 bits or less, so either int or short multiply will work. - */ - -#define DEQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval)) - - -/* - * Perform dequantization and inverse DCT on one block of coefficients. - * - * Optimized algorithm with 12 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/16). - */ - -GLOBAL(void) -jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp3; - INT32 tmp10, tmp11, tmp12, tmp13; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[DCTSIZE2]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * Note results are scaled up by sqrt(8) compared to a true IDCT; - * furthermore, we scale the results by 2**PASS1_BITS. - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = DCTSIZE; ctr > 0; ctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any column in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * column DCT calculations can be simplified this way. - */ - - if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && - inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && - inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && - inptr[DCTSIZE*7] == 0) { - /* AC terms all zero */ - int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; - - wsptr[DCTSIZE*0] = dcval; - wsptr[DCTSIZE*1] = dcval; - wsptr[DCTSIZE*2] = dcval; - wsptr[DCTSIZE*3] = dcval; - wsptr[DCTSIZE*4] = dcval; - wsptr[DCTSIZE*5] = dcval; - wsptr[DCTSIZE*6] = dcval; - wsptr[DCTSIZE*7] = dcval; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - continue; - } - - /* Even part: reverse the even part of the forward DCT. - * The rotator is c(-6). - */ - - z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z2 <<= CONST_BITS; - z3 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z2 += ONE << (CONST_BITS-PASS1_BITS-1); - - tmp0 = z2 + z3; - tmp1 = z2 - z3; - - z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */ - tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */ - - tmp10 = tmp0 + tmp2; - tmp13 = tmp0 - tmp2; - tmp11 = tmp1 + tmp3; - tmp12 = tmp1 - tmp3; - - /* Odd part per figure 8; the matrix is unitary and hence its - * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. - */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - - z2 = tmp0 + tmp2; - z3 = tmp1 + tmp3; - - z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* c3 */ - z2 = MULTIPLY(z2, - FIX_1_961570560); /* -c3-c5 */ - z3 = MULTIPLY(z3, - FIX_0_390180644); /* -c3+c5 */ - z2 += z1; - z3 += z1; - - z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */ - tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* -c1+c3+c5-c7 */ - tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* c1+c3-c5-c7 */ - tmp0 += z1 + z2; - tmp3 += z1 + z3; - - z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */ - tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* c1+c3-c5+c7 */ - tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* c1+c3+c5-c7 */ - tmp1 += z1 + z3; - tmp2 += z1 + z2; - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - wsptr[DCTSIZE*0] = (int) RIGHT_SHIFT(tmp10 + tmp3, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*7] = (int) RIGHT_SHIFT(tmp10 - tmp3, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*1] = (int) RIGHT_SHIFT(tmp11 + tmp2, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*6] = (int) RIGHT_SHIFT(tmp11 - tmp2, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*2] = (int) RIGHT_SHIFT(tmp12 + tmp1, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*5] = (int) RIGHT_SHIFT(tmp12 - tmp1, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*3] = (int) RIGHT_SHIFT(tmp13 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*4] = (int) RIGHT_SHIFT(tmp13 - tmp0, CONST_BITS-PASS1_BITS); - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - } - - /* Pass 2: process rows from work array, store into output array. - * Note that we must descale the results by a factor of 8 == 2**3, - * and also undo the PASS1_BITS scaling. - */ - - wsptr = workspace; - for (ctr = 0; ctr < DCTSIZE; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Add range center and fudge factor for final descale and range-limit. */ - z2 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - - /* Rows of zeroes can be exploited in the same way as we did with columns. - * However, the column calculation has created many nonzero AC terms, so - * the simplification applies less often (typically 5% to 10% of the time). - * On machines with very fast multiplication, it's possible that the - * test takes more time than it's worth. In that case this section - * may be commented out. - */ - -#ifndef NO_ZERO_ROW_TEST - if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && - wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { - /* AC terms all zero */ - JSAMPLE dcval = range_limit[(int) RIGHT_SHIFT(z2, PASS1_BITS+3) - & RANGE_MASK]; - - outptr[0] = dcval; - outptr[1] = dcval; - outptr[2] = dcval; - outptr[3] = dcval; - outptr[4] = dcval; - outptr[5] = dcval; - outptr[6] = dcval; - outptr[7] = dcval; - - wsptr += DCTSIZE; /* advance pointer to next row */ - continue; - } -#endif - - /* Even part: reverse the even part of the forward DCT. - * The rotator is c(-6). - */ - - z3 = (INT32) wsptr[4]; - - tmp0 = (z2 + z3) << CONST_BITS; - tmp1 = (z2 - z3) << CONST_BITS; - - z2 = (INT32) wsptr[2]; - z3 = (INT32) wsptr[6]; - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */ - tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */ - - tmp10 = tmp0 + tmp2; - tmp13 = tmp0 - tmp2; - tmp11 = tmp1 + tmp3; - tmp12 = tmp1 - tmp3; - - /* Odd part per figure 8; the matrix is unitary and hence its - * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. - */ - - tmp0 = (INT32) wsptr[7]; - tmp1 = (INT32) wsptr[5]; - tmp2 = (INT32) wsptr[3]; - tmp3 = (INT32) wsptr[1]; - - z2 = tmp0 + tmp2; - z3 = tmp1 + tmp3; - - z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* c3 */ - z2 = MULTIPLY(z2, - FIX_1_961570560); /* -c3-c5 */ - z3 = MULTIPLY(z3, - FIX_0_390180644); /* -c3+c5 */ - z2 += z1; - z3 += z1; - - z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */ - tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* -c1+c3+c5-c7 */ - tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* c1+c3-c5-c7 */ - tmp0 += z1 + z2; - tmp3 += z1 + z3; - - z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */ - tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* c1+c3-c5+c7 */ - tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* c1+c3+c5-c7 */ - tmp1 += z1 + z3; - tmp2 += z1 + z2; - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp11 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp11 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp13 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp13 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += DCTSIZE; /* advance pointer to next row */ - } -} - -#ifdef IDCT_SCALING_SUPPORTED - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 7x7 output block. - * - * Optimized algorithm with 12 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/14). - */ - -GLOBAL(void) -jpeg_idct_7x7 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp10, tmp11, tmp12, tmp13; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[7*7]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 7; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp13 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp13 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp13 += ONE << (CONST_BITS-PASS1_BITS-1); - - z1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp10 = MULTIPLY(z2 - z3, FIX(0.881747734)); /* c4 */ - tmp12 = MULTIPLY(z1 - z2, FIX(0.314692123)); /* c6 */ - tmp11 = tmp10 + tmp12 + tmp13 - MULTIPLY(z2, FIX(1.841218003)); /* c2+c4-c6 */ - tmp0 = z1 + z3; - z2 -= tmp0; - tmp0 = MULTIPLY(tmp0, FIX(1.274162392)) + tmp13; /* c2 */ - tmp10 += tmp0 - MULTIPLY(z3, FIX(0.077722536)); /* c2-c4-c6 */ - tmp12 += tmp0 - MULTIPLY(z1, FIX(2.470602249)); /* c2+c4+c6 */ - tmp13 += MULTIPLY(z2, FIX(1.414213562)); /* c0 */ - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - - tmp1 = MULTIPLY(z1 + z2, FIX(0.935414347)); /* (c3+c1-c5)/2 */ - tmp2 = MULTIPLY(z1 - z2, FIX(0.170262339)); /* (c3+c5-c1)/2 */ - tmp0 = tmp1 - tmp2; - tmp1 += tmp2; - tmp2 = MULTIPLY(z2 + z3, - FIX(1.378756276)); /* -c1 */ - tmp1 += tmp2; - z2 = MULTIPLY(z1 + z3, FIX(0.613604268)); /* c5 */ - tmp0 += z2; - tmp2 += z2 + MULTIPLY(z3, FIX(1.870828693)); /* c3+c1-c5 */ - - /* Final output stage */ - - wsptr[7*0] = (int) RIGHT_SHIFT(tmp10 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[7*6] = (int) RIGHT_SHIFT(tmp10 - tmp0, CONST_BITS-PASS1_BITS); - wsptr[7*1] = (int) RIGHT_SHIFT(tmp11 + tmp1, CONST_BITS-PASS1_BITS); - wsptr[7*5] = (int) RIGHT_SHIFT(tmp11 - tmp1, CONST_BITS-PASS1_BITS); - wsptr[7*2] = (int) RIGHT_SHIFT(tmp12 + tmp2, CONST_BITS-PASS1_BITS); - wsptr[7*4] = (int) RIGHT_SHIFT(tmp12 - tmp2, CONST_BITS-PASS1_BITS); - wsptr[7*3] = (int) RIGHT_SHIFT(tmp13, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 7 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 7; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp13 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp13 <<= CONST_BITS; - - z1 = (INT32) wsptr[2]; - z2 = (INT32) wsptr[4]; - z3 = (INT32) wsptr[6]; - - tmp10 = MULTIPLY(z2 - z3, FIX(0.881747734)); /* c4 */ - tmp12 = MULTIPLY(z1 - z2, FIX(0.314692123)); /* c6 */ - tmp11 = tmp10 + tmp12 + tmp13 - MULTIPLY(z2, FIX(1.841218003)); /* c2+c4-c6 */ - tmp0 = z1 + z3; - z2 -= tmp0; - tmp0 = MULTIPLY(tmp0, FIX(1.274162392)) + tmp13; /* c2 */ - tmp10 += tmp0 - MULTIPLY(z3, FIX(0.077722536)); /* c2-c4-c6 */ - tmp12 += tmp0 - MULTIPLY(z1, FIX(2.470602249)); /* c2+c4+c6 */ - tmp13 += MULTIPLY(z2, FIX(1.414213562)); /* c0 */ - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - - tmp1 = MULTIPLY(z1 + z2, FIX(0.935414347)); /* (c3+c1-c5)/2 */ - tmp2 = MULTIPLY(z1 - z2, FIX(0.170262339)); /* (c3+c5-c1)/2 */ - tmp0 = tmp1 - tmp2; - tmp1 += tmp2; - tmp2 = MULTIPLY(z2 + z3, - FIX(1.378756276)); /* -c1 */ - tmp1 += tmp2; - z2 = MULTIPLY(z1 + z3, FIX(0.613604268)); /* c5 */ - tmp0 += z2; - tmp2 += z2 + MULTIPLY(z3, FIX(1.870828693)); /* c3+c1-c5 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp11 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp11 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 7; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 6x6 output block. - * - * Optimized algorithm with 3 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/12). - */ - -GLOBAL(void) -jpeg_idct_6x6 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp10, tmp11, tmp12; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[6*6]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 6; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp0 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp0 += ONE << (CONST_BITS-PASS1_BITS-1); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - tmp10 = MULTIPLY(tmp2, FIX(0.707106781)); /* c4 */ - tmp1 = tmp0 + tmp10; - tmp11 = RIGHT_SHIFT(tmp0 - tmp10 - tmp10, CONST_BITS-PASS1_BITS); - tmp10 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp0 = MULTIPLY(tmp10, FIX(1.224744871)); /* c2 */ - tmp10 = tmp1 + tmp0; - tmp12 = tmp1 - tmp0; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp1 = MULTIPLY(z1 + z3, FIX(0.366025404)); /* c5 */ - tmp0 = tmp1 + ((z1 + z2) << CONST_BITS); - tmp2 = tmp1 + ((z3 - z2) << CONST_BITS); - tmp1 = (z1 - z2 - z3) << PASS1_BITS; - - /* Final output stage */ - - wsptr[6*0] = (int) RIGHT_SHIFT(tmp10 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[6*5] = (int) RIGHT_SHIFT(tmp10 - tmp0, CONST_BITS-PASS1_BITS); - wsptr[6*1] = (int) (tmp11 + tmp1); - wsptr[6*4] = (int) (tmp11 - tmp1); - wsptr[6*2] = (int) RIGHT_SHIFT(tmp12 + tmp2, CONST_BITS-PASS1_BITS); - wsptr[6*3] = (int) RIGHT_SHIFT(tmp12 - tmp2, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 6 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 6; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp0 <<= CONST_BITS; - tmp2 = (INT32) wsptr[4]; - tmp10 = MULTIPLY(tmp2, FIX(0.707106781)); /* c4 */ - tmp1 = tmp0 + tmp10; - tmp11 = tmp0 - tmp10 - tmp10; - tmp10 = (INT32) wsptr[2]; - tmp0 = MULTIPLY(tmp10, FIX(1.224744871)); /* c2 */ - tmp10 = tmp1 + tmp0; - tmp12 = tmp1 - tmp0; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - tmp1 = MULTIPLY(z1 + z3, FIX(0.366025404)); /* c5 */ - tmp0 = tmp1 + ((z1 + z2) << CONST_BITS); - tmp2 = tmp1 + ((z3 - z2) << CONST_BITS); - tmp1 = (z1 - z2 - z3) << CONST_BITS; - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp11 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp11 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 6; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 5x5 output block. - * - * Optimized algorithm with 5 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/10). - */ - -GLOBAL(void) -jpeg_idct_5x5 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp10, tmp11, tmp12; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[5*5]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 5; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp12 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp12 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp12 += ONE << (CONST_BITS-PASS1_BITS-1); - tmp0 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp1 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z1 = MULTIPLY(tmp0 + tmp1, FIX(0.790569415)); /* (c2+c4)/2 */ - z2 = MULTIPLY(tmp0 - tmp1, FIX(0.353553391)); /* (c2-c4)/2 */ - z3 = tmp12 + z2; - tmp10 = z3 + z1; - tmp11 = z3 - z1; - tmp12 -= z2 << 2; - - /* Odd part */ - - z2 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - - z1 = MULTIPLY(z2 + z3, FIX(0.831253876)); /* c3 */ - tmp0 = z1 + MULTIPLY(z2, FIX(0.513743148)); /* c1-c3 */ - tmp1 = z1 - MULTIPLY(z3, FIX(2.176250899)); /* c1+c3 */ - - /* Final output stage */ - - wsptr[5*0] = (int) RIGHT_SHIFT(tmp10 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[5*4] = (int) RIGHT_SHIFT(tmp10 - tmp0, CONST_BITS-PASS1_BITS); - wsptr[5*1] = (int) RIGHT_SHIFT(tmp11 + tmp1, CONST_BITS-PASS1_BITS); - wsptr[5*3] = (int) RIGHT_SHIFT(tmp11 - tmp1, CONST_BITS-PASS1_BITS); - wsptr[5*2] = (int) RIGHT_SHIFT(tmp12, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 5 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 5; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp12 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp12 <<= CONST_BITS; - tmp0 = (INT32) wsptr[2]; - tmp1 = (INT32) wsptr[4]; - z1 = MULTIPLY(tmp0 + tmp1, FIX(0.790569415)); /* (c2+c4)/2 */ - z2 = MULTIPLY(tmp0 - tmp1, FIX(0.353553391)); /* (c2-c4)/2 */ - z3 = tmp12 + z2; - tmp10 = z3 + z1; - tmp11 = z3 - z1; - tmp12 -= z2 << 2; - - /* Odd part */ - - z2 = (INT32) wsptr[1]; - z3 = (INT32) wsptr[3]; - - z1 = MULTIPLY(z2 + z3, FIX(0.831253876)); /* c3 */ - tmp0 = z1 + MULTIPLY(z2, FIX(0.513743148)); /* c1-c3 */ - tmp1 = z1 - MULTIPLY(z3, FIX(2.176250899)); /* c1+c3 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp11 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp11 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 5; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 4x4 output block. - * - * Optimized algorithm with 3 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point IDCT]. - */ - -GLOBAL(void) -jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp2, tmp10, tmp12; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[4*4]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - - tmp10 = (tmp0 + tmp2) << PASS1_BITS; - tmp12 = (tmp0 - tmp2) << PASS1_BITS; - - /* Odd part */ - /* Same rotation as in the even part of the 8x8 LL&M IDCT */ - - z2 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - /* Add fudge factor here for final descale. */ - z1 += ONE << (CONST_BITS-PASS1_BITS-1); - tmp0 = RIGHT_SHIFT(z1 + MULTIPLY(z2, FIX_0_765366865), /* c2-c6 */ - CONST_BITS-PASS1_BITS); - tmp2 = RIGHT_SHIFT(z1 - MULTIPLY(z3, FIX_1_847759065), /* c2+c6 */ - CONST_BITS-PASS1_BITS); - - /* Final output stage */ - - wsptr[4*0] = (int) (tmp10 + tmp0); - wsptr[4*3] = (int) (tmp10 - tmp0); - wsptr[4*1] = (int) (tmp12 + tmp2); - wsptr[4*2] = (int) (tmp12 - tmp2); - } - - /* Pass 2: process 4 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 4; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp2 = (INT32) wsptr[2]; - - tmp10 = (tmp0 + tmp2) << CONST_BITS; - tmp12 = (tmp0 - tmp2) << CONST_BITS; - - /* Odd part */ - /* Same rotation as in the even part of the 8x8 LL&M IDCT */ - - z2 = (INT32) wsptr[1]; - z3 = (INT32) wsptr[3]; - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - tmp0 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */ - tmp2 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp12 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 4; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 3x3 output block. - * - * Optimized algorithm with 2 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/6). - */ - -GLOBAL(void) -jpeg_idct_3x3 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp2, tmp10, tmp12; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[3*3]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 3; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp0 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp0 += ONE << (CONST_BITS-PASS1_BITS-1); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp12 = MULTIPLY(tmp2, FIX(0.707106781)); /* c2 */ - tmp10 = tmp0 + tmp12; - tmp2 = tmp0 - tmp12 - tmp12; - - /* Odd part */ - - tmp12 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - tmp0 = MULTIPLY(tmp12, FIX(1.224744871)); /* c1 */ - - /* Final output stage */ - - wsptr[3*0] = (int) RIGHT_SHIFT(tmp10 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[3*2] = (int) RIGHT_SHIFT(tmp10 - tmp0, CONST_BITS-PASS1_BITS); - wsptr[3*1] = (int) RIGHT_SHIFT(tmp2, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 3 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 3; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp0 <<= CONST_BITS; - tmp2 = (INT32) wsptr[2]; - tmp12 = MULTIPLY(tmp2, FIX(0.707106781)); /* c2 */ - tmp10 = tmp0 + tmp12; - tmp2 = tmp0 - tmp12 - tmp12; - - /* Odd part */ - - tmp12 = (INT32) wsptr[1]; - tmp0 = MULTIPLY(tmp12, FIX(1.224744871)); /* c1 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 3; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 2x2 output block. - * - * Multiplication-less algorithm. - */ - -GLOBAL(void) -jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - ISLOW_MULT_TYPE * quantptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - ISHIFT_TEMPS - - /* Pass 1: process columns from input. */ - - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - - /* Column 0 */ - tmp4 = DEQUANTIZE(coef_block[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp5 = DEQUANTIZE(coef_block[DCTSIZE*1], quantptr[DCTSIZE*1]); - /* Add range center and fudge factor for final descale and range-limit. */ - tmp4 += (((DCTELEM) RANGE_CENTER) << 3) + (1 << 2); - - tmp0 = tmp4 + tmp5; - tmp2 = tmp4 - tmp5; - - /* Column 1 */ - tmp4 = DEQUANTIZE(coef_block[DCTSIZE*0+1], quantptr[DCTSIZE*0+1]); - tmp5 = DEQUANTIZE(coef_block[DCTSIZE*1+1], quantptr[DCTSIZE*1+1]); - - tmp1 = tmp4 + tmp5; - tmp3 = tmp4 - tmp5; - - /* Pass 2: process 2 rows, store into output array. */ - - /* Row 0 */ - outptr = output_buf[0] + output_col; - - outptr[0] = range_limit[(int) IRIGHT_SHIFT(tmp0 + tmp1, 3) & RANGE_MASK]; - outptr[1] = range_limit[(int) IRIGHT_SHIFT(tmp0 - tmp1, 3) & RANGE_MASK]; - - /* Row 1 */ - outptr = output_buf[1] + output_col; - - outptr[0] = range_limit[(int) IRIGHT_SHIFT(tmp2 + tmp3, 3) & RANGE_MASK]; - outptr[1] = range_limit[(int) IRIGHT_SHIFT(tmp2 - tmp3, 3) & RANGE_MASK]; -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 1x1 output block. - * - * We hardly need an inverse DCT routine for this: just take the - * average pixel value, which is one-eighth of the DC coefficient. - */ - -GLOBAL(void) -jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - DCTELEM dcval; - ISLOW_MULT_TYPE * quantptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - ISHIFT_TEMPS - - /* 1x1 is trivial: just take the DC coefficient divided by 8. */ - - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - - dcval = DEQUANTIZE(coef_block[0], quantptr[0]); - /* Add range center and fudge factor for descale and range-limit. */ - dcval += (((DCTELEM) RANGE_CENTER) << 3) + (1 << 2); - - output_buf[0][output_col] = - range_limit[(int) IRIGHT_SHIFT(dcval, 3) & RANGE_MASK]; -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 9x9 output block. - * - * Optimized algorithm with 10 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/18). - */ - -GLOBAL(void) -jpeg_idct_9x9 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp3, tmp10, tmp11, tmp12, tmp13, tmp14; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*9]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp0 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp0 += ONE << (CONST_BITS-PASS1_BITS-1); - - z1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp3 = MULTIPLY(z3, FIX(0.707106781)); /* c6 */ - tmp1 = tmp0 + tmp3; - tmp2 = tmp0 - tmp3 - tmp3; - - tmp0 = MULTIPLY(z1 - z2, FIX(0.707106781)); /* c6 */ - tmp11 = tmp2 + tmp0; - tmp14 = tmp2 - tmp0 - tmp0; - - tmp0 = MULTIPLY(z1 + z2, FIX(1.328926049)); /* c2 */ - tmp2 = MULTIPLY(z1, FIX(1.083350441)); /* c4 */ - tmp3 = MULTIPLY(z2, FIX(0.245575608)); /* c8 */ - - tmp10 = tmp1 + tmp0 - tmp3; - tmp12 = tmp1 - tmp0 + tmp2; - tmp13 = tmp1 - tmp2 + tmp3; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - z2 = MULTIPLY(z2, - FIX(1.224744871)); /* -c3 */ - - tmp2 = MULTIPLY(z1 + z3, FIX(0.909038955)); /* c5 */ - tmp3 = MULTIPLY(z1 + z4, FIX(0.483689525)); /* c7 */ - tmp0 = tmp2 + tmp3 - z2; - tmp1 = MULTIPLY(z3 - z4, FIX(1.392728481)); /* c1 */ - tmp2 += z2 - tmp1; - tmp3 += z2 + tmp1; - tmp1 = MULTIPLY(z1 - z3 - z4, FIX(1.224744871)); /* c3 */ - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp10 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[8*8] = (int) RIGHT_SHIFT(tmp10 - tmp0, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp11 + tmp1, CONST_BITS-PASS1_BITS); - wsptr[8*7] = (int) RIGHT_SHIFT(tmp11 - tmp1, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp12 + tmp2, CONST_BITS-PASS1_BITS); - wsptr[8*6] = (int) RIGHT_SHIFT(tmp12 - tmp2, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp13 + tmp3, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp13 - tmp3, CONST_BITS-PASS1_BITS); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp14, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 9 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 9; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp0 <<= CONST_BITS; - - z1 = (INT32) wsptr[2]; - z2 = (INT32) wsptr[4]; - z3 = (INT32) wsptr[6]; - - tmp3 = MULTIPLY(z3, FIX(0.707106781)); /* c6 */ - tmp1 = tmp0 + tmp3; - tmp2 = tmp0 - tmp3 - tmp3; - - tmp0 = MULTIPLY(z1 - z2, FIX(0.707106781)); /* c6 */ - tmp11 = tmp2 + tmp0; - tmp14 = tmp2 - tmp0 - tmp0; - - tmp0 = MULTIPLY(z1 + z2, FIX(1.328926049)); /* c2 */ - tmp2 = MULTIPLY(z1, FIX(1.083350441)); /* c4 */ - tmp3 = MULTIPLY(z2, FIX(0.245575608)); /* c8 */ - - tmp10 = tmp1 + tmp0 - tmp3; - tmp12 = tmp1 - tmp0 + tmp2; - tmp13 = tmp1 - tmp2 + tmp3; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z4 = (INT32) wsptr[7]; - - z2 = MULTIPLY(z2, - FIX(1.224744871)); /* -c3 */ - - tmp2 = MULTIPLY(z1 + z3, FIX(0.909038955)); /* c5 */ - tmp3 = MULTIPLY(z1 + z4, FIX(0.483689525)); /* c7 */ - tmp0 = tmp2 + tmp3 - z2; - tmp1 = MULTIPLY(z3 - z4, FIX(1.392728481)); /* c1 */ - tmp2 += z2 - tmp1; - tmp3 += z2 + tmp1; - tmp1 = MULTIPLY(z1 - z3 - z4, FIX(1.224744871)); /* c3 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp11 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp11 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp13 + tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp13 - tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 10x10 output block. - * - * Optimized algorithm with 12 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/20). - */ - -GLOBAL(void) -jpeg_idct_10x10 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24; - INT32 z1, z2, z3, z4, z5; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*10]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z3 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z3 += ONE << (CONST_BITS-PASS1_BITS-1); - z4 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z1 = MULTIPLY(z4, FIX(1.144122806)); /* c4 */ - z2 = MULTIPLY(z4, FIX(0.437016024)); /* c8 */ - tmp10 = z3 + z1; - tmp11 = z3 - z2; - - tmp22 = RIGHT_SHIFT(z3 - ((z1 - z2) << 1), /* c0 = (c4-c8)*2 */ - CONST_BITS-PASS1_BITS); - - z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - z1 = MULTIPLY(z2 + z3, FIX(0.831253876)); /* c6 */ - tmp12 = z1 + MULTIPLY(z2, FIX(0.513743148)); /* c2-c6 */ - tmp13 = z1 - MULTIPLY(z3, FIX(2.176250899)); /* c2+c6 */ - - tmp20 = tmp10 + tmp12; - tmp24 = tmp10 - tmp12; - tmp21 = tmp11 + tmp13; - tmp23 = tmp11 - tmp13; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - tmp11 = z2 + z4; - tmp13 = z2 - z4; - - tmp12 = MULTIPLY(tmp13, FIX(0.309016994)); /* (c3-c7)/2 */ - z5 = z3 << CONST_BITS; - - z2 = MULTIPLY(tmp11, FIX(0.951056516)); /* (c3+c7)/2 */ - z4 = z5 + tmp12; - - tmp10 = MULTIPLY(z1, FIX(1.396802247)) + z2 + z4; /* c1 */ - tmp14 = MULTIPLY(z1, FIX(0.221231742)) - z2 + z4; /* c9 */ - - z2 = MULTIPLY(tmp11, FIX(0.587785252)); /* (c1-c9)/2 */ - z4 = z5 - tmp12 - (tmp13 << (CONST_BITS - 1)); - - tmp12 = (z1 - tmp13 - z3) << PASS1_BITS; - - tmp11 = MULTIPLY(z1, FIX(1.260073511)) - z2 - z4; /* c3 */ - tmp13 = MULTIPLY(z1, FIX(0.642039522)) - z2 + z4; /* c7 */ - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*9] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp21 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*8] = (int) RIGHT_SHIFT(tmp21 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) (tmp22 + tmp12); - wsptr[8*7] = (int) (tmp22 - tmp12); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp23 + tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*6] = (int) RIGHT_SHIFT(tmp23 - tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp24 + tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp24 - tmp14, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 10 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 10; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - z3 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - z3 <<= CONST_BITS; - z4 = (INT32) wsptr[4]; - z1 = MULTIPLY(z4, FIX(1.144122806)); /* c4 */ - z2 = MULTIPLY(z4, FIX(0.437016024)); /* c8 */ - tmp10 = z3 + z1; - tmp11 = z3 - z2; - - tmp22 = z3 - ((z1 - z2) << 1); /* c0 = (c4-c8)*2 */ - - z2 = (INT32) wsptr[2]; - z3 = (INT32) wsptr[6]; - - z1 = MULTIPLY(z2 + z3, FIX(0.831253876)); /* c6 */ - tmp12 = z1 + MULTIPLY(z2, FIX(0.513743148)); /* c2-c6 */ - tmp13 = z1 - MULTIPLY(z3, FIX(2.176250899)); /* c2+c6 */ - - tmp20 = tmp10 + tmp12; - tmp24 = tmp10 - tmp12; - tmp21 = tmp11 + tmp13; - tmp23 = tmp11 - tmp13; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z3 <<= CONST_BITS; - z4 = (INT32) wsptr[7]; - - tmp11 = z2 + z4; - tmp13 = z2 - z4; - - tmp12 = MULTIPLY(tmp13, FIX(0.309016994)); /* (c3-c7)/2 */ - - z2 = MULTIPLY(tmp11, FIX(0.951056516)); /* (c3+c7)/2 */ - z4 = z3 + tmp12; - - tmp10 = MULTIPLY(z1, FIX(1.396802247)) + z2 + z4; /* c1 */ - tmp14 = MULTIPLY(z1, FIX(0.221231742)) - z2 + z4; /* c9 */ - - z2 = MULTIPLY(tmp11, FIX(0.587785252)); /* (c1-c9)/2 */ - z4 = z3 - tmp12 - (tmp13 << (CONST_BITS - 1)); - - tmp12 = ((z1 - tmp13) << CONST_BITS) - z3; - - tmp11 = MULTIPLY(z1, FIX(1.260073511)) - z2 - z4; /* c3 */ - tmp13 = MULTIPLY(z1, FIX(0.642039522)) - z2 + z4; /* c7 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 11x11 output block. - * - * Optimized algorithm with 24 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/22). - */ - -GLOBAL(void) -jpeg_idct_11x11 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*11]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp10 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp10 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp10 += ONE << (CONST_BITS-PASS1_BITS-1); - - z1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp20 = MULTIPLY(z2 - z3, FIX(2.546640132)); /* c2+c4 */ - tmp23 = MULTIPLY(z2 - z1, FIX(0.430815045)); /* c2-c6 */ - z4 = z1 + z3; - tmp24 = MULTIPLY(z4, - FIX(1.155664402)); /* -(c2-c10) */ - z4 -= z2; - tmp25 = tmp10 + MULTIPLY(z4, FIX(1.356927976)); /* c2 */ - tmp21 = tmp20 + tmp23 + tmp25 - - MULTIPLY(z2, FIX(1.821790775)); /* c2+c4+c10-c6 */ - tmp20 += tmp25 + MULTIPLY(z3, FIX(2.115825087)); /* c4+c6 */ - tmp23 += tmp25 - MULTIPLY(z1, FIX(1.513598477)); /* c6+c8 */ - tmp24 += tmp25; - tmp22 = tmp24 - MULTIPLY(z3, FIX(0.788749120)); /* c8+c10 */ - tmp24 += MULTIPLY(z2, FIX(1.944413522)) - /* c2+c8 */ - MULTIPLY(z1, FIX(1.390975730)); /* c4+c10 */ - tmp25 = tmp10 - MULTIPLY(z4, FIX(1.414213562)); /* c0 */ - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - tmp11 = z1 + z2; - tmp14 = MULTIPLY(tmp11 + z3 + z4, FIX(0.398430003)); /* c9 */ - tmp11 = MULTIPLY(tmp11, FIX(0.887983902)); /* c3-c9 */ - tmp12 = MULTIPLY(z1 + z3, FIX(0.670361295)); /* c5-c9 */ - tmp13 = tmp14 + MULTIPLY(z1 + z4, FIX(0.366151574)); /* c7-c9 */ - tmp10 = tmp11 + tmp12 + tmp13 - - MULTIPLY(z1, FIX(0.923107866)); /* c7+c5+c3-c1-2*c9 */ - z1 = tmp14 - MULTIPLY(z2 + z3, FIX(1.163011579)); /* c7+c9 */ - tmp11 += z1 + MULTIPLY(z2, FIX(2.073276588)); /* c1+c7+3*c9-c3 */ - tmp12 += z1 - MULTIPLY(z3, FIX(1.192193623)); /* c3+c5-c7-c9 */ - z1 = MULTIPLY(z2 + z4, - FIX(1.798248910)); /* -(c1+c9) */ - tmp11 += z1; - tmp13 += z1 + MULTIPLY(z4, FIX(2.102458632)); /* c1+c5+c9-c7 */ - tmp14 += MULTIPLY(z2, - FIX(1.467221301)) + /* -(c5+c9) */ - MULTIPLY(z3, FIX(1.001388905)) - /* c1-c9 */ - MULTIPLY(z4, FIX(1.684843907)); /* c3+c9 */ - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*10] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp21 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*9] = (int) RIGHT_SHIFT(tmp21 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp22 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*8] = (int) RIGHT_SHIFT(tmp22 - tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp23 + tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*7] = (int) RIGHT_SHIFT(tmp23 - tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp24 + tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*6] = (int) RIGHT_SHIFT(tmp24 - tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp25, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 11 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 11; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp10 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp10 <<= CONST_BITS; - - z1 = (INT32) wsptr[2]; - z2 = (INT32) wsptr[4]; - z3 = (INT32) wsptr[6]; - - tmp20 = MULTIPLY(z2 - z3, FIX(2.546640132)); /* c2+c4 */ - tmp23 = MULTIPLY(z2 - z1, FIX(0.430815045)); /* c2-c6 */ - z4 = z1 + z3; - tmp24 = MULTIPLY(z4, - FIX(1.155664402)); /* -(c2-c10) */ - z4 -= z2; - tmp25 = tmp10 + MULTIPLY(z4, FIX(1.356927976)); /* c2 */ - tmp21 = tmp20 + tmp23 + tmp25 - - MULTIPLY(z2, FIX(1.821790775)); /* c2+c4+c10-c6 */ - tmp20 += tmp25 + MULTIPLY(z3, FIX(2.115825087)); /* c4+c6 */ - tmp23 += tmp25 - MULTIPLY(z1, FIX(1.513598477)); /* c6+c8 */ - tmp24 += tmp25; - tmp22 = tmp24 - MULTIPLY(z3, FIX(0.788749120)); /* c8+c10 */ - tmp24 += MULTIPLY(z2, FIX(1.944413522)) - /* c2+c8 */ - MULTIPLY(z1, FIX(1.390975730)); /* c4+c10 */ - tmp25 = tmp10 - MULTIPLY(z4, FIX(1.414213562)); /* c0 */ - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z4 = (INT32) wsptr[7]; - - tmp11 = z1 + z2; - tmp14 = MULTIPLY(tmp11 + z3 + z4, FIX(0.398430003)); /* c9 */ - tmp11 = MULTIPLY(tmp11, FIX(0.887983902)); /* c3-c9 */ - tmp12 = MULTIPLY(z1 + z3, FIX(0.670361295)); /* c5-c9 */ - tmp13 = tmp14 + MULTIPLY(z1 + z4, FIX(0.366151574)); /* c7-c9 */ - tmp10 = tmp11 + tmp12 + tmp13 - - MULTIPLY(z1, FIX(0.923107866)); /* c7+c5+c3-c1-2*c9 */ - z1 = tmp14 - MULTIPLY(z2 + z3, FIX(1.163011579)); /* c7+c9 */ - tmp11 += z1 + MULTIPLY(z2, FIX(2.073276588)); /* c1+c7+3*c9-c3 */ - tmp12 += z1 - MULTIPLY(z3, FIX(1.192193623)); /* c3+c5-c7-c9 */ - z1 = MULTIPLY(z2 + z4, - FIX(1.798248910)); /* -(c1+c9) */ - tmp11 += z1; - tmp13 += z1 + MULTIPLY(z4, FIX(2.102458632)); /* c1+c5+c9-c7 */ - tmp14 += MULTIPLY(z2, - FIX(1.467221301)) + /* -(c5+c9) */ - MULTIPLY(z3, FIX(1.001388905)) - /* c1-c9 */ - MULTIPLY(z4, FIX(1.684843907)); /* c3+c9 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[10] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp25, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 12x12 output block. - * - * Optimized algorithm with 15 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/24). - */ - -GLOBAL(void) -jpeg_idct_12x12 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*12]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z3 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z3 += ONE << (CONST_BITS-PASS1_BITS-1); - - z4 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z4 = MULTIPLY(z4, FIX(1.224744871)); /* c4 */ - - tmp10 = z3 + z4; - tmp11 = z3 - z4; - - z1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z4 = MULTIPLY(z1, FIX(1.366025404)); /* c2 */ - z1 <<= CONST_BITS; - z2 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - z2 <<= CONST_BITS; - - tmp12 = z1 - z2; - - tmp21 = z3 + tmp12; - tmp24 = z3 - tmp12; - - tmp12 = z4 + z2; - - tmp20 = tmp10 + tmp12; - tmp25 = tmp10 - tmp12; - - tmp12 = z4 - z1 - z2; - - tmp22 = tmp11 + tmp12; - tmp23 = tmp11 - tmp12; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - tmp11 = MULTIPLY(z2, FIX(1.306562965)); /* c3 */ - tmp14 = MULTIPLY(z2, - FIX_0_541196100); /* -c9 */ - - tmp10 = z1 + z3; - tmp15 = MULTIPLY(tmp10 + z4, FIX(0.860918669)); /* c7 */ - tmp12 = tmp15 + MULTIPLY(tmp10, FIX(0.261052384)); /* c5-c7 */ - tmp10 = tmp12 + tmp11 + MULTIPLY(z1, FIX(0.280143716)); /* c1-c5 */ - tmp13 = MULTIPLY(z3 + z4, - FIX(1.045510580)); /* -(c7+c11) */ - tmp12 += tmp13 + tmp14 - MULTIPLY(z3, FIX(1.478575242)); /* c1+c5-c7-c11 */ - tmp13 += tmp15 - tmp11 + MULTIPLY(z4, FIX(1.586706681)); /* c1+c11 */ - tmp15 += tmp14 - MULTIPLY(z1, FIX(0.676326758)) - /* c7-c11 */ - MULTIPLY(z4, FIX(1.982889723)); /* c5+c7 */ - - z1 -= z4; - z2 -= z3; - z3 = MULTIPLY(z1 + z2, FIX_0_541196100); /* c9 */ - tmp11 = z3 + MULTIPLY(z1, FIX_0_765366865); /* c3-c9 */ - tmp14 = z3 - MULTIPLY(z2, FIX_1_847759065); /* c3+c9 */ - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*11] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp21 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*10] = (int) RIGHT_SHIFT(tmp21 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp22 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*9] = (int) RIGHT_SHIFT(tmp22 - tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp23 + tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*8] = (int) RIGHT_SHIFT(tmp23 - tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp24 + tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*7] = (int) RIGHT_SHIFT(tmp24 - tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp25 + tmp15, CONST_BITS-PASS1_BITS); - wsptr[8*6] = (int) RIGHT_SHIFT(tmp25 - tmp15, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 12 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 12; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - z3 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - z3 <<= CONST_BITS; - - z4 = (INT32) wsptr[4]; - z4 = MULTIPLY(z4, FIX(1.224744871)); /* c4 */ - - tmp10 = z3 + z4; - tmp11 = z3 - z4; - - z1 = (INT32) wsptr[2]; - z4 = MULTIPLY(z1, FIX(1.366025404)); /* c2 */ - z1 <<= CONST_BITS; - z2 = (INT32) wsptr[6]; - z2 <<= CONST_BITS; - - tmp12 = z1 - z2; - - tmp21 = z3 + tmp12; - tmp24 = z3 - tmp12; - - tmp12 = z4 + z2; - - tmp20 = tmp10 + tmp12; - tmp25 = tmp10 - tmp12; - - tmp12 = z4 - z1 - z2; - - tmp22 = tmp11 + tmp12; - tmp23 = tmp11 - tmp12; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z4 = (INT32) wsptr[7]; - - tmp11 = MULTIPLY(z2, FIX(1.306562965)); /* c3 */ - tmp14 = MULTIPLY(z2, - FIX_0_541196100); /* -c9 */ - - tmp10 = z1 + z3; - tmp15 = MULTIPLY(tmp10 + z4, FIX(0.860918669)); /* c7 */ - tmp12 = tmp15 + MULTIPLY(tmp10, FIX(0.261052384)); /* c5-c7 */ - tmp10 = tmp12 + tmp11 + MULTIPLY(z1, FIX(0.280143716)); /* c1-c5 */ - tmp13 = MULTIPLY(z3 + z4, - FIX(1.045510580)); /* -(c7+c11) */ - tmp12 += tmp13 + tmp14 - MULTIPLY(z3, FIX(1.478575242)); /* c1+c5-c7-c11 */ - tmp13 += tmp15 - tmp11 + MULTIPLY(z4, FIX(1.586706681)); /* c1+c11 */ - tmp15 += tmp14 - MULTIPLY(z1, FIX(0.676326758)) - /* c7-c11 */ - MULTIPLY(z4, FIX(1.982889723)); /* c5+c7 */ - - z1 -= z4; - z2 -= z3; - z3 = MULTIPLY(z1 + z2, FIX_0_541196100); /* c9 */ - tmp11 = z3 + MULTIPLY(z1, FIX_0_765366865); /* c3-c9 */ - tmp14 = z3 - MULTIPLY(z2, FIX_1_847759065); /* c3+c9 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[11] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[10] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp25 + tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp25 - tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 13x13 output block. - * - * Optimized algorithm with 29 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/26). - */ - -GLOBAL(void) -jpeg_idct_13x13 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*13]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z1 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z1 += ONE << (CONST_BITS-PASS1_BITS-1); - - z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z4 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp10 = z3 + z4; - tmp11 = z3 - z4; - - tmp12 = MULTIPLY(tmp10, FIX(1.155388986)); /* (c4+c6)/2 */ - tmp13 = MULTIPLY(tmp11, FIX(0.096834934)) + z1; /* (c4-c6)/2 */ - - tmp20 = MULTIPLY(z2, FIX(1.373119086)) + tmp12 + tmp13; /* c2 */ - tmp22 = MULTIPLY(z2, FIX(0.501487041)) - tmp12 + tmp13; /* c10 */ - - tmp12 = MULTIPLY(tmp10, FIX(0.316450131)); /* (c8-c12)/2 */ - tmp13 = MULTIPLY(tmp11, FIX(0.486914739)) + z1; /* (c8+c12)/2 */ - - tmp21 = MULTIPLY(z2, FIX(1.058554052)) - tmp12 + tmp13; /* c6 */ - tmp25 = MULTIPLY(z2, - FIX(1.252223920)) + tmp12 + tmp13; /* c4 */ - - tmp12 = MULTIPLY(tmp10, FIX(0.435816023)); /* (c2-c10)/2 */ - tmp13 = MULTIPLY(tmp11, FIX(0.937303064)) - z1; /* (c2+c10)/2 */ - - tmp23 = MULTIPLY(z2, - FIX(0.170464608)) - tmp12 - tmp13; /* c12 */ - tmp24 = MULTIPLY(z2, - FIX(0.803364869)) + tmp12 - tmp13; /* c8 */ - - tmp26 = MULTIPLY(tmp11 - z2, FIX(1.414213562)) + z1; /* c0 */ - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - tmp11 = MULTIPLY(z1 + z2, FIX(1.322312651)); /* c3 */ - tmp12 = MULTIPLY(z1 + z3, FIX(1.163874945)); /* c5 */ - tmp15 = z1 + z4; - tmp13 = MULTIPLY(tmp15, FIX(0.937797057)); /* c7 */ - tmp10 = tmp11 + tmp12 + tmp13 - - MULTIPLY(z1, FIX(2.020082300)); /* c7+c5+c3-c1 */ - tmp14 = MULTIPLY(z2 + z3, - FIX(0.338443458)); /* -c11 */ - tmp11 += tmp14 + MULTIPLY(z2, FIX(0.837223564)); /* c5+c9+c11-c3 */ - tmp12 += tmp14 - MULTIPLY(z3, FIX(1.572116027)); /* c1+c5-c9-c11 */ - tmp14 = MULTIPLY(z2 + z4, - FIX(1.163874945)); /* -c5 */ - tmp11 += tmp14; - tmp13 += tmp14 + MULTIPLY(z4, FIX(2.205608352)); /* c3+c5+c9-c7 */ - tmp14 = MULTIPLY(z3 + z4, - FIX(0.657217813)); /* -c9 */ - tmp12 += tmp14; - tmp13 += tmp14; - tmp15 = MULTIPLY(tmp15, FIX(0.338443458)); /* c11 */ - tmp14 = tmp15 + MULTIPLY(z1, FIX(0.318774355)) - /* c9-c11 */ - MULTIPLY(z2, FIX(0.466105296)); /* c1-c7 */ - z1 = MULTIPLY(z3 - z2, FIX(0.937797057)); /* c7 */ - tmp14 += z1; - tmp15 += z1 + MULTIPLY(z3, FIX(0.384515595)) - /* c3-c7 */ - MULTIPLY(z4, FIX(1.742345811)); /* c1+c11 */ - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*12] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp21 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*11] = (int) RIGHT_SHIFT(tmp21 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp22 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*10] = (int) RIGHT_SHIFT(tmp22 - tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp23 + tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*9] = (int) RIGHT_SHIFT(tmp23 - tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp24 + tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*8] = (int) RIGHT_SHIFT(tmp24 - tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp25 + tmp15, CONST_BITS-PASS1_BITS); - wsptr[8*7] = (int) RIGHT_SHIFT(tmp25 - tmp15, CONST_BITS-PASS1_BITS); - wsptr[8*6] = (int) RIGHT_SHIFT(tmp26, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 13 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 13; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - z1 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - z1 <<= CONST_BITS; - - z2 = (INT32) wsptr[2]; - z3 = (INT32) wsptr[4]; - z4 = (INT32) wsptr[6]; - - tmp10 = z3 + z4; - tmp11 = z3 - z4; - - tmp12 = MULTIPLY(tmp10, FIX(1.155388986)); /* (c4+c6)/2 */ - tmp13 = MULTIPLY(tmp11, FIX(0.096834934)) + z1; /* (c4-c6)/2 */ - - tmp20 = MULTIPLY(z2, FIX(1.373119086)) + tmp12 + tmp13; /* c2 */ - tmp22 = MULTIPLY(z2, FIX(0.501487041)) - tmp12 + tmp13; /* c10 */ - - tmp12 = MULTIPLY(tmp10, FIX(0.316450131)); /* (c8-c12)/2 */ - tmp13 = MULTIPLY(tmp11, FIX(0.486914739)) + z1; /* (c8+c12)/2 */ - - tmp21 = MULTIPLY(z2, FIX(1.058554052)) - tmp12 + tmp13; /* c6 */ - tmp25 = MULTIPLY(z2, - FIX(1.252223920)) + tmp12 + tmp13; /* c4 */ - - tmp12 = MULTIPLY(tmp10, FIX(0.435816023)); /* (c2-c10)/2 */ - tmp13 = MULTIPLY(tmp11, FIX(0.937303064)) - z1; /* (c2+c10)/2 */ - - tmp23 = MULTIPLY(z2, - FIX(0.170464608)) - tmp12 - tmp13; /* c12 */ - tmp24 = MULTIPLY(z2, - FIX(0.803364869)) + tmp12 - tmp13; /* c8 */ - - tmp26 = MULTIPLY(tmp11 - z2, FIX(1.414213562)) + z1; /* c0 */ - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z4 = (INT32) wsptr[7]; - - tmp11 = MULTIPLY(z1 + z2, FIX(1.322312651)); /* c3 */ - tmp12 = MULTIPLY(z1 + z3, FIX(1.163874945)); /* c5 */ - tmp15 = z1 + z4; - tmp13 = MULTIPLY(tmp15, FIX(0.937797057)); /* c7 */ - tmp10 = tmp11 + tmp12 + tmp13 - - MULTIPLY(z1, FIX(2.020082300)); /* c7+c5+c3-c1 */ - tmp14 = MULTIPLY(z2 + z3, - FIX(0.338443458)); /* -c11 */ - tmp11 += tmp14 + MULTIPLY(z2, FIX(0.837223564)); /* c5+c9+c11-c3 */ - tmp12 += tmp14 - MULTIPLY(z3, FIX(1.572116027)); /* c1+c5-c9-c11 */ - tmp14 = MULTIPLY(z2 + z4, - FIX(1.163874945)); /* -c5 */ - tmp11 += tmp14; - tmp13 += tmp14 + MULTIPLY(z4, FIX(2.205608352)); /* c3+c5+c9-c7 */ - tmp14 = MULTIPLY(z3 + z4, - FIX(0.657217813)); /* -c9 */ - tmp12 += tmp14; - tmp13 += tmp14; - tmp15 = MULTIPLY(tmp15, FIX(0.338443458)); /* c11 */ - tmp14 = tmp15 + MULTIPLY(z1, FIX(0.318774355)) - /* c9-c11 */ - MULTIPLY(z2, FIX(0.466105296)); /* c1-c7 */ - z1 = MULTIPLY(z3 - z2, FIX(0.937797057)); /* c7 */ - tmp14 += z1; - tmp15 += z1 + MULTIPLY(z3, FIX(0.384515595)) - /* c3-c7 */ - MULTIPLY(z4, FIX(1.742345811)); /* c1+c11 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[12] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[11] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[10] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp25 + tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp25 - tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp26, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 14x14 output block. - * - * Optimized algorithm with 20 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/28). - */ - -GLOBAL(void) -jpeg_idct_14x14 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*14]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z1 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z1 += ONE << (CONST_BITS-PASS1_BITS-1); - z4 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z2 = MULTIPLY(z4, FIX(1.274162392)); /* c4 */ - z3 = MULTIPLY(z4, FIX(0.314692123)); /* c12 */ - z4 = MULTIPLY(z4, FIX(0.881747734)); /* c8 */ - - tmp10 = z1 + z2; - tmp11 = z1 + z3; - tmp12 = z1 - z4; - - tmp23 = RIGHT_SHIFT(z1 - ((z2 + z3 - z4) << 1), /* c0 = (c4+c12-c8)*2 */ - CONST_BITS-PASS1_BITS); - - z1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z2 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - z3 = MULTIPLY(z1 + z2, FIX(1.105676686)); /* c6 */ - - tmp13 = z3 + MULTIPLY(z1, FIX(0.273079590)); /* c2-c6 */ - tmp14 = z3 - MULTIPLY(z2, FIX(1.719280954)); /* c6+c10 */ - tmp15 = MULTIPLY(z1, FIX(0.613604268)) - /* c10 */ - MULTIPLY(z2, FIX(1.378756276)); /* c2 */ - - tmp20 = tmp10 + tmp13; - tmp26 = tmp10 - tmp13; - tmp21 = tmp11 + tmp14; - tmp25 = tmp11 - tmp14; - tmp22 = tmp12 + tmp15; - tmp24 = tmp12 - tmp15; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - tmp13 = z4 << CONST_BITS; - - tmp14 = z1 + z3; - tmp11 = MULTIPLY(z1 + z2, FIX(1.334852607)); /* c3 */ - tmp12 = MULTIPLY(tmp14, FIX(1.197448846)); /* c5 */ - tmp10 = tmp11 + tmp12 + tmp13 - MULTIPLY(z1, FIX(1.126980169)); /* c3+c5-c1 */ - tmp14 = MULTIPLY(tmp14, FIX(0.752406978)); /* c9 */ - tmp16 = tmp14 - MULTIPLY(z1, FIX(1.061150426)); /* c9+c11-c13 */ - z1 -= z2; - tmp15 = MULTIPLY(z1, FIX(0.467085129)) - tmp13; /* c11 */ - tmp16 += tmp15; - z1 += z4; - z4 = MULTIPLY(z2 + z3, - FIX(0.158341681)) - tmp13; /* -c13 */ - tmp11 += z4 - MULTIPLY(z2, FIX(0.424103948)); /* c3-c9-c13 */ - tmp12 += z4 - MULTIPLY(z3, FIX(2.373959773)); /* c3+c5-c13 */ - z4 = MULTIPLY(z3 - z2, FIX(1.405321284)); /* c1 */ - tmp14 += z4 + tmp13 - MULTIPLY(z3, FIX(1.6906431334)); /* c1+c9-c11 */ - tmp15 += z4 + MULTIPLY(z2, FIX(0.674957567)); /* c1+c11-c5 */ - - tmp13 = (z1 - z3) << PASS1_BITS; - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*13] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp21 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*12] = (int) RIGHT_SHIFT(tmp21 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp22 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*11] = (int) RIGHT_SHIFT(tmp22 - tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) (tmp23 + tmp13); - wsptr[8*10] = (int) (tmp23 - tmp13); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp24 + tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*9] = (int) RIGHT_SHIFT(tmp24 - tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp25 + tmp15, CONST_BITS-PASS1_BITS); - wsptr[8*8] = (int) RIGHT_SHIFT(tmp25 - tmp15, CONST_BITS-PASS1_BITS); - wsptr[8*6] = (int) RIGHT_SHIFT(tmp26 + tmp16, CONST_BITS-PASS1_BITS); - wsptr[8*7] = (int) RIGHT_SHIFT(tmp26 - tmp16, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 14 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 14; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - z1 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - z1 <<= CONST_BITS; - z4 = (INT32) wsptr[4]; - z2 = MULTIPLY(z4, FIX(1.274162392)); /* c4 */ - z3 = MULTIPLY(z4, FIX(0.314692123)); /* c12 */ - z4 = MULTIPLY(z4, FIX(0.881747734)); /* c8 */ - - tmp10 = z1 + z2; - tmp11 = z1 + z3; - tmp12 = z1 - z4; - - tmp23 = z1 - ((z2 + z3 - z4) << 1); /* c0 = (c4+c12-c8)*2 */ - - z1 = (INT32) wsptr[2]; - z2 = (INT32) wsptr[6]; - - z3 = MULTIPLY(z1 + z2, FIX(1.105676686)); /* c6 */ - - tmp13 = z3 + MULTIPLY(z1, FIX(0.273079590)); /* c2-c6 */ - tmp14 = z3 - MULTIPLY(z2, FIX(1.719280954)); /* c6+c10 */ - tmp15 = MULTIPLY(z1, FIX(0.613604268)) - /* c10 */ - MULTIPLY(z2, FIX(1.378756276)); /* c2 */ - - tmp20 = tmp10 + tmp13; - tmp26 = tmp10 - tmp13; - tmp21 = tmp11 + tmp14; - tmp25 = tmp11 - tmp14; - tmp22 = tmp12 + tmp15; - tmp24 = tmp12 - tmp15; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z4 = (INT32) wsptr[7]; - z4 <<= CONST_BITS; - - tmp14 = z1 + z3; - tmp11 = MULTIPLY(z1 + z2, FIX(1.334852607)); /* c3 */ - tmp12 = MULTIPLY(tmp14, FIX(1.197448846)); /* c5 */ - tmp10 = tmp11 + tmp12 + z4 - MULTIPLY(z1, FIX(1.126980169)); /* c3+c5-c1 */ - tmp14 = MULTIPLY(tmp14, FIX(0.752406978)); /* c9 */ - tmp16 = tmp14 - MULTIPLY(z1, FIX(1.061150426)); /* c9+c11-c13 */ - z1 -= z2; - tmp15 = MULTIPLY(z1, FIX(0.467085129)) - z4; /* c11 */ - tmp16 += tmp15; - tmp13 = MULTIPLY(z2 + z3, - FIX(0.158341681)) - z4; /* -c13 */ - tmp11 += tmp13 - MULTIPLY(z2, FIX(0.424103948)); /* c3-c9-c13 */ - tmp12 += tmp13 - MULTIPLY(z3, FIX(2.373959773)); /* c3+c5-c13 */ - tmp13 = MULTIPLY(z3 - z2, FIX(1.405321284)); /* c1 */ - tmp14 += tmp13 + z4 - MULTIPLY(z3, FIX(1.6906431334)); /* c1+c9-c11 */ - tmp15 += tmp13 + MULTIPLY(z2, FIX(0.674957567)); /* c1+c11-c5 */ - - tmp13 = ((z1 - z3) << CONST_BITS) + z4; - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[13] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[12] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[11] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[10] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp25 + tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp25 - tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp26 + tmp16, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp26 - tmp16, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 15x15 output block. - * - * Optimized algorithm with 22 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/30). - */ - -GLOBAL(void) -jpeg_idct_15x15 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*15]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z1 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z1 += ONE << (CONST_BITS-PASS1_BITS-1); - - z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z4 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp10 = MULTIPLY(z4, FIX(0.437016024)); /* c12 */ - tmp11 = MULTIPLY(z4, FIX(1.144122806)); /* c6 */ - - tmp12 = z1 - tmp10; - tmp13 = z1 + tmp11; - z1 -= (tmp11 - tmp10) << 1; /* c0 = (c6-c12)*2 */ - - z4 = z2 - z3; - z3 += z2; - tmp10 = MULTIPLY(z3, FIX(1.337628990)); /* (c2+c4)/2 */ - tmp11 = MULTIPLY(z4, FIX(0.045680613)); /* (c2-c4)/2 */ - z2 = MULTIPLY(z2, FIX(1.439773946)); /* c4+c14 */ - - tmp20 = tmp13 + tmp10 + tmp11; - tmp23 = tmp12 - tmp10 + tmp11 + z2; - - tmp10 = MULTIPLY(z3, FIX(0.547059574)); /* (c8+c14)/2 */ - tmp11 = MULTIPLY(z4, FIX(0.399234004)); /* (c8-c14)/2 */ - - tmp25 = tmp13 - tmp10 - tmp11; - tmp26 = tmp12 + tmp10 - tmp11 - z2; - - tmp10 = MULTIPLY(z3, FIX(0.790569415)); /* (c6+c12)/2 */ - tmp11 = MULTIPLY(z4, FIX(0.353553391)); /* (c6-c12)/2 */ - - tmp21 = tmp12 + tmp10 + tmp11; - tmp24 = tmp13 - tmp10 + tmp11; - tmp11 += tmp11; - tmp22 = z1 + tmp11; /* c10 = c6-c12 */ - tmp27 = z1 - tmp11 - tmp11; /* c0 = (c6-c12)*2 */ - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z4 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z3 = MULTIPLY(z4, FIX(1.224744871)); /* c5 */ - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - tmp13 = z2 - z4; - tmp15 = MULTIPLY(z1 + tmp13, FIX(0.831253876)); /* c9 */ - tmp11 = tmp15 + MULTIPLY(z1, FIX(0.513743148)); /* c3-c9 */ - tmp14 = tmp15 - MULTIPLY(tmp13, FIX(2.176250899)); /* c3+c9 */ - - tmp13 = MULTIPLY(z2, - FIX(0.831253876)); /* -c9 */ - tmp15 = MULTIPLY(z2, - FIX(1.344997024)); /* -c3 */ - z2 = z1 - z4; - tmp12 = z3 + MULTIPLY(z2, FIX(1.406466353)); /* c1 */ - - tmp10 = tmp12 + MULTIPLY(z4, FIX(2.457431844)) - tmp15; /* c1+c7 */ - tmp16 = tmp12 - MULTIPLY(z1, FIX(1.112434820)) + tmp13; /* c1-c13 */ - tmp12 = MULTIPLY(z2, FIX(1.224744871)) - z3; /* c5 */ - z2 = MULTIPLY(z1 + z4, FIX(0.575212477)); /* c11 */ - tmp13 += z2 + MULTIPLY(z1, FIX(0.475753014)) - z3; /* c7-c11 */ - tmp15 += z2 - MULTIPLY(z4, FIX(0.869244010)) + z3; /* c11+c13 */ - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*14] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp21 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*13] = (int) RIGHT_SHIFT(tmp21 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp22 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*12] = (int) RIGHT_SHIFT(tmp22 - tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp23 + tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*11] = (int) RIGHT_SHIFT(tmp23 - tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp24 + tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*10] = (int) RIGHT_SHIFT(tmp24 - tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp25 + tmp15, CONST_BITS-PASS1_BITS); - wsptr[8*9] = (int) RIGHT_SHIFT(tmp25 - tmp15, CONST_BITS-PASS1_BITS); - wsptr[8*6] = (int) RIGHT_SHIFT(tmp26 + tmp16, CONST_BITS-PASS1_BITS); - wsptr[8*8] = (int) RIGHT_SHIFT(tmp26 - tmp16, CONST_BITS-PASS1_BITS); - wsptr[8*7] = (int) RIGHT_SHIFT(tmp27, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 15 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 15; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - z1 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - z1 <<= CONST_BITS; - - z2 = (INT32) wsptr[2]; - z3 = (INT32) wsptr[4]; - z4 = (INT32) wsptr[6]; - - tmp10 = MULTIPLY(z4, FIX(0.437016024)); /* c12 */ - tmp11 = MULTIPLY(z4, FIX(1.144122806)); /* c6 */ - - tmp12 = z1 - tmp10; - tmp13 = z1 + tmp11; - z1 -= (tmp11 - tmp10) << 1; /* c0 = (c6-c12)*2 */ - - z4 = z2 - z3; - z3 += z2; - tmp10 = MULTIPLY(z3, FIX(1.337628990)); /* (c2+c4)/2 */ - tmp11 = MULTIPLY(z4, FIX(0.045680613)); /* (c2-c4)/2 */ - z2 = MULTIPLY(z2, FIX(1.439773946)); /* c4+c14 */ - - tmp20 = tmp13 + tmp10 + tmp11; - tmp23 = tmp12 - tmp10 + tmp11 + z2; - - tmp10 = MULTIPLY(z3, FIX(0.547059574)); /* (c8+c14)/2 */ - tmp11 = MULTIPLY(z4, FIX(0.399234004)); /* (c8-c14)/2 */ - - tmp25 = tmp13 - tmp10 - tmp11; - tmp26 = tmp12 + tmp10 - tmp11 - z2; - - tmp10 = MULTIPLY(z3, FIX(0.790569415)); /* (c6+c12)/2 */ - tmp11 = MULTIPLY(z4, FIX(0.353553391)); /* (c6-c12)/2 */ - - tmp21 = tmp12 + tmp10 + tmp11; - tmp24 = tmp13 - tmp10 + tmp11; - tmp11 += tmp11; - tmp22 = z1 + tmp11; /* c10 = c6-c12 */ - tmp27 = z1 - tmp11 - tmp11; /* c0 = (c6-c12)*2 */ - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z4 = (INT32) wsptr[5]; - z3 = MULTIPLY(z4, FIX(1.224744871)); /* c5 */ - z4 = (INT32) wsptr[7]; - - tmp13 = z2 - z4; - tmp15 = MULTIPLY(z1 + tmp13, FIX(0.831253876)); /* c9 */ - tmp11 = tmp15 + MULTIPLY(z1, FIX(0.513743148)); /* c3-c9 */ - tmp14 = tmp15 - MULTIPLY(tmp13, FIX(2.176250899)); /* c3+c9 */ - - tmp13 = MULTIPLY(z2, - FIX(0.831253876)); /* -c9 */ - tmp15 = MULTIPLY(z2, - FIX(1.344997024)); /* -c3 */ - z2 = z1 - z4; - tmp12 = z3 + MULTIPLY(z2, FIX(1.406466353)); /* c1 */ - - tmp10 = tmp12 + MULTIPLY(z4, FIX(2.457431844)) - tmp15; /* c1+c7 */ - tmp16 = tmp12 - MULTIPLY(z1, FIX(1.112434820)) + tmp13; /* c1-c13 */ - tmp12 = MULTIPLY(z2, FIX(1.224744871)) - z3; /* c5 */ - z2 = MULTIPLY(z1 + z4, FIX(0.575212477)); /* c11 */ - tmp13 += z2 + MULTIPLY(z1, FIX(0.475753014)) - z3; /* c7-c11 */ - tmp15 += z2 - MULTIPLY(z4, FIX(0.869244010)) + z3; /* c11+c13 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[14] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[13] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[12] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[11] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[10] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp25 + tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp25 - tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp26 + tmp16, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp26 - tmp16, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp27, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 16x16 output block. - * - * Optimized algorithm with 28 multiplications in the 1-D kernel. - * cK represents sqrt(2) * cos(K*pi/32). - */ - -GLOBAL(void) -jpeg_idct_16x16 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp3, tmp10, tmp11, tmp12, tmp13; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*16]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp0 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp0 += ONE << (CONST_BITS-PASS1_BITS-1); - - z1 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - tmp1 = MULTIPLY(z1, FIX(1.306562965)); /* c4[16] = c2[8] */ - tmp2 = MULTIPLY(z1, FIX_0_541196100); /* c12[16] = c6[8] */ - - tmp10 = tmp0 + tmp1; - tmp11 = tmp0 - tmp1; - tmp12 = tmp0 + tmp2; - tmp13 = tmp0 - tmp2; - - z1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z2 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - z3 = z1 - z2; - z4 = MULTIPLY(z3, FIX(0.275899379)); /* c14[16] = c7[8] */ - z3 = MULTIPLY(z3, FIX(1.387039845)); /* c2[16] = c1[8] */ - - tmp0 = z3 + MULTIPLY(z2, FIX_2_562915447); /* (c6+c2)[16] = (c3+c1)[8] */ - tmp1 = z4 + MULTIPLY(z1, FIX_0_899976223); /* (c6-c14)[16] = (c3-c7)[8] */ - tmp2 = z3 - MULTIPLY(z1, FIX(0.601344887)); /* (c2-c10)[16] = (c1-c5)[8] */ - tmp3 = z4 - MULTIPLY(z2, FIX(0.509795579)); /* (c10-c14)[16] = (c5-c7)[8] */ - - tmp20 = tmp10 + tmp0; - tmp27 = tmp10 - tmp0; - tmp21 = tmp12 + tmp1; - tmp26 = tmp12 - tmp1; - tmp22 = tmp13 + tmp2; - tmp25 = tmp13 - tmp2; - tmp23 = tmp11 + tmp3; - tmp24 = tmp11 - tmp3; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - tmp11 = z1 + z3; - - tmp1 = MULTIPLY(z1 + z2, FIX(1.353318001)); /* c3 */ - tmp2 = MULTIPLY(tmp11, FIX(1.247225013)); /* c5 */ - tmp3 = MULTIPLY(z1 + z4, FIX(1.093201867)); /* c7 */ - tmp10 = MULTIPLY(z1 - z4, FIX(0.897167586)); /* c9 */ - tmp11 = MULTIPLY(tmp11, FIX(0.666655658)); /* c11 */ - tmp12 = MULTIPLY(z1 - z2, FIX(0.410524528)); /* c13 */ - tmp0 = tmp1 + tmp2 + tmp3 - - MULTIPLY(z1, FIX(2.286341144)); /* c7+c5+c3-c1 */ - tmp13 = tmp10 + tmp11 + tmp12 - - MULTIPLY(z1, FIX(1.835730603)); /* c9+c11+c13-c15 */ - z1 = MULTIPLY(z2 + z3, FIX(0.138617169)); /* c15 */ - tmp1 += z1 + MULTIPLY(z2, FIX(0.071888074)); /* c9+c11-c3-c15 */ - tmp2 += z1 - MULTIPLY(z3, FIX(1.125726048)); /* c5+c7+c15-c3 */ - z1 = MULTIPLY(z3 - z2, FIX(1.407403738)); /* c1 */ - tmp11 += z1 - MULTIPLY(z3, FIX(0.766367282)); /* c1+c11-c9-c13 */ - tmp12 += z1 + MULTIPLY(z2, FIX(1.971951411)); /* c1+c5+c13-c7 */ - z2 += z4; - z1 = MULTIPLY(z2, - FIX(0.666655658)); /* -c11 */ - tmp1 += z1; - tmp3 += z1 + MULTIPLY(z4, FIX(1.065388962)); /* c3+c11+c15-c7 */ - z2 = MULTIPLY(z2, - FIX(1.247225013)); /* -c5 */ - tmp10 += z2 + MULTIPLY(z4, FIX(3.141271809)); /* c1+c5+c9-c13 */ - tmp12 += z2; - z2 = MULTIPLY(z3 + z4, - FIX(1.353318001)); /* -c3 */ - tmp2 += z2; - tmp3 += z2; - z2 = MULTIPLY(z4 - z3, FIX(0.410524528)); /* c13 */ - tmp10 += z2; - tmp11 += z2; - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp20 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[8*15] = (int) RIGHT_SHIFT(tmp20 - tmp0, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp21 + tmp1, CONST_BITS-PASS1_BITS); - wsptr[8*14] = (int) RIGHT_SHIFT(tmp21 - tmp1, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp22 + tmp2, CONST_BITS-PASS1_BITS); - wsptr[8*13] = (int) RIGHT_SHIFT(tmp22 - tmp2, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp23 + tmp3, CONST_BITS-PASS1_BITS); - wsptr[8*12] = (int) RIGHT_SHIFT(tmp23 - tmp3, CONST_BITS-PASS1_BITS); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp24 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*11] = (int) RIGHT_SHIFT(tmp24 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp25 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*10] = (int) RIGHT_SHIFT(tmp25 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*6] = (int) RIGHT_SHIFT(tmp26 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*9] = (int) RIGHT_SHIFT(tmp26 - tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*7] = (int) RIGHT_SHIFT(tmp27 + tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*8] = (int) RIGHT_SHIFT(tmp27 - tmp13, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 16 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 16; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp0 <<= CONST_BITS; - - z1 = (INT32) wsptr[4]; - tmp1 = MULTIPLY(z1, FIX(1.306562965)); /* c4[16] = c2[8] */ - tmp2 = MULTIPLY(z1, FIX_0_541196100); /* c12[16] = c6[8] */ - - tmp10 = tmp0 + tmp1; - tmp11 = tmp0 - tmp1; - tmp12 = tmp0 + tmp2; - tmp13 = tmp0 - tmp2; - - z1 = (INT32) wsptr[2]; - z2 = (INT32) wsptr[6]; - z3 = z1 - z2; - z4 = MULTIPLY(z3, FIX(0.275899379)); /* c14[16] = c7[8] */ - z3 = MULTIPLY(z3, FIX(1.387039845)); /* c2[16] = c1[8] */ - - tmp0 = z3 + MULTIPLY(z2, FIX_2_562915447); /* (c6+c2)[16] = (c3+c1)[8] */ - tmp1 = z4 + MULTIPLY(z1, FIX_0_899976223); /* (c6-c14)[16] = (c3-c7)[8] */ - tmp2 = z3 - MULTIPLY(z1, FIX(0.601344887)); /* (c2-c10)[16] = (c1-c5)[8] */ - tmp3 = z4 - MULTIPLY(z2, FIX(0.509795579)); /* (c10-c14)[16] = (c5-c7)[8] */ - - tmp20 = tmp10 + tmp0; - tmp27 = tmp10 - tmp0; - tmp21 = tmp12 + tmp1; - tmp26 = tmp12 - tmp1; - tmp22 = tmp13 + tmp2; - tmp25 = tmp13 - tmp2; - tmp23 = tmp11 + tmp3; - tmp24 = tmp11 - tmp3; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z4 = (INT32) wsptr[7]; - - tmp11 = z1 + z3; - - tmp1 = MULTIPLY(z1 + z2, FIX(1.353318001)); /* c3 */ - tmp2 = MULTIPLY(tmp11, FIX(1.247225013)); /* c5 */ - tmp3 = MULTIPLY(z1 + z4, FIX(1.093201867)); /* c7 */ - tmp10 = MULTIPLY(z1 - z4, FIX(0.897167586)); /* c9 */ - tmp11 = MULTIPLY(tmp11, FIX(0.666655658)); /* c11 */ - tmp12 = MULTIPLY(z1 - z2, FIX(0.410524528)); /* c13 */ - tmp0 = tmp1 + tmp2 + tmp3 - - MULTIPLY(z1, FIX(2.286341144)); /* c7+c5+c3-c1 */ - tmp13 = tmp10 + tmp11 + tmp12 - - MULTIPLY(z1, FIX(1.835730603)); /* c9+c11+c13-c15 */ - z1 = MULTIPLY(z2 + z3, FIX(0.138617169)); /* c15 */ - tmp1 += z1 + MULTIPLY(z2, FIX(0.071888074)); /* c9+c11-c3-c15 */ - tmp2 += z1 - MULTIPLY(z3, FIX(1.125726048)); /* c5+c7+c15-c3 */ - z1 = MULTIPLY(z3 - z2, FIX(1.407403738)); /* c1 */ - tmp11 += z1 - MULTIPLY(z3, FIX(0.766367282)); /* c1+c11-c9-c13 */ - tmp12 += z1 + MULTIPLY(z2, FIX(1.971951411)); /* c1+c5+c13-c7 */ - z2 += z4; - z1 = MULTIPLY(z2, - FIX(0.666655658)); /* -c11 */ - tmp1 += z1; - tmp3 += z1 + MULTIPLY(z4, FIX(1.065388962)); /* c3+c11+c15-c7 */ - z2 = MULTIPLY(z2, - FIX(1.247225013)); /* -c5 */ - tmp10 += z2 + MULTIPLY(z4, FIX(3.141271809)); /* c1+c5+c9-c13 */ - tmp12 += z2; - z2 = MULTIPLY(z3 + z4, - FIX(1.353318001)); /* -c3 */ - tmp2 += z2; - tmp3 += z2; - z2 = MULTIPLY(z4 - z3, FIX(0.410524528)); /* c13 */ - tmp10 += z2; - tmp11 += z2; - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[15] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[14] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[13] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[12] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[11] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp25 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[10] = range_limit[(int) RIGHT_SHIFT(tmp25 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp26 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp26 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp27 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp27 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 16x8 output block. - * - * 8-point IDCT in pass 1 (columns), 16-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_16x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp3, tmp10, tmp11, tmp12, tmp13; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*8]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * Note results are scaled up by sqrt(8) compared to a true IDCT; - * furthermore, we scale the results by 2**PASS1_BITS. - * 8-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/16). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = DCTSIZE; ctr > 0; ctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any column in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * column DCT calculations can be simplified this way. - */ - - if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && - inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && - inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && - inptr[DCTSIZE*7] == 0) { - /* AC terms all zero */ - int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; - - wsptr[DCTSIZE*0] = dcval; - wsptr[DCTSIZE*1] = dcval; - wsptr[DCTSIZE*2] = dcval; - wsptr[DCTSIZE*3] = dcval; - wsptr[DCTSIZE*4] = dcval; - wsptr[DCTSIZE*5] = dcval; - wsptr[DCTSIZE*6] = dcval; - wsptr[DCTSIZE*7] = dcval; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - continue; - } - - /* Even part: reverse the even part of the forward DCT. - * The rotator is c(-6). - */ - - z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z2 <<= CONST_BITS; - z3 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z2 += ONE << (CONST_BITS-PASS1_BITS-1); - - tmp0 = z2 + z3; - tmp1 = z2 - z3; - - z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */ - tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */ - - tmp10 = tmp0 + tmp2; - tmp13 = tmp0 - tmp2; - tmp11 = tmp1 + tmp3; - tmp12 = tmp1 - tmp3; - - /* Odd part per figure 8; the matrix is unitary and hence its - * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. - */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - - z2 = tmp0 + tmp2; - z3 = tmp1 + tmp3; - - z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* c3 */ - z2 = MULTIPLY(z2, - FIX_1_961570560); /* -c3-c5 */ - z3 = MULTIPLY(z3, - FIX_0_390180644); /* -c3+c5 */ - z2 += z1; - z3 += z1; - - z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */ - tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* -c1+c3+c5-c7 */ - tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* c1+c3-c5-c7 */ - tmp0 += z1 + z2; - tmp3 += z1 + z3; - - z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */ - tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* c1+c3-c5+c7 */ - tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* c1+c3+c5-c7 */ - tmp1 += z1 + z3; - tmp2 += z1 + z2; - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - wsptr[DCTSIZE*0] = (int) RIGHT_SHIFT(tmp10 + tmp3, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*7] = (int) RIGHT_SHIFT(tmp10 - tmp3, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*1] = (int) RIGHT_SHIFT(tmp11 + tmp2, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*6] = (int) RIGHT_SHIFT(tmp11 - tmp2, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*2] = (int) RIGHT_SHIFT(tmp12 + tmp1, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*5] = (int) RIGHT_SHIFT(tmp12 - tmp1, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*3] = (int) RIGHT_SHIFT(tmp13 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[DCTSIZE*4] = (int) RIGHT_SHIFT(tmp13 - tmp0, CONST_BITS-PASS1_BITS); - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - } - - /* Pass 2: process 8 rows from work array, store into output array. - * 16-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/32). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp0 <<= CONST_BITS; - - z1 = (INT32) wsptr[4]; - tmp1 = MULTIPLY(z1, FIX(1.306562965)); /* c4[16] = c2[8] */ - tmp2 = MULTIPLY(z1, FIX_0_541196100); /* c12[16] = c6[8] */ - - tmp10 = tmp0 + tmp1; - tmp11 = tmp0 - tmp1; - tmp12 = tmp0 + tmp2; - tmp13 = tmp0 - tmp2; - - z1 = (INT32) wsptr[2]; - z2 = (INT32) wsptr[6]; - z3 = z1 - z2; - z4 = MULTIPLY(z3, FIX(0.275899379)); /* c14[16] = c7[8] */ - z3 = MULTIPLY(z3, FIX(1.387039845)); /* c2[16] = c1[8] */ - - tmp0 = z3 + MULTIPLY(z2, FIX_2_562915447); /* (c6+c2)[16] = (c3+c1)[8] */ - tmp1 = z4 + MULTIPLY(z1, FIX_0_899976223); /* (c6-c14)[16] = (c3-c7)[8] */ - tmp2 = z3 - MULTIPLY(z1, FIX(0.601344887)); /* (c2-c10)[16] = (c1-c5)[8] */ - tmp3 = z4 - MULTIPLY(z2, FIX(0.509795579)); /* (c10-c14)[16] = (c5-c7)[8] */ - - tmp20 = tmp10 + tmp0; - tmp27 = tmp10 - tmp0; - tmp21 = tmp12 + tmp1; - tmp26 = tmp12 - tmp1; - tmp22 = tmp13 + tmp2; - tmp25 = tmp13 - tmp2; - tmp23 = tmp11 + tmp3; - tmp24 = tmp11 - tmp3; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z4 = (INT32) wsptr[7]; - - tmp11 = z1 + z3; - - tmp1 = MULTIPLY(z1 + z2, FIX(1.353318001)); /* c3 */ - tmp2 = MULTIPLY(tmp11, FIX(1.247225013)); /* c5 */ - tmp3 = MULTIPLY(z1 + z4, FIX(1.093201867)); /* c7 */ - tmp10 = MULTIPLY(z1 - z4, FIX(0.897167586)); /* c9 */ - tmp11 = MULTIPLY(tmp11, FIX(0.666655658)); /* c11 */ - tmp12 = MULTIPLY(z1 - z2, FIX(0.410524528)); /* c13 */ - tmp0 = tmp1 + tmp2 + tmp3 - - MULTIPLY(z1, FIX(2.286341144)); /* c7+c5+c3-c1 */ - tmp13 = tmp10 + tmp11 + tmp12 - - MULTIPLY(z1, FIX(1.835730603)); /* c9+c11+c13-c15 */ - z1 = MULTIPLY(z2 + z3, FIX(0.138617169)); /* c15 */ - tmp1 += z1 + MULTIPLY(z2, FIX(0.071888074)); /* c9+c11-c3-c15 */ - tmp2 += z1 - MULTIPLY(z3, FIX(1.125726048)); /* c5+c7+c15-c3 */ - z1 = MULTIPLY(z3 - z2, FIX(1.407403738)); /* c1 */ - tmp11 += z1 - MULTIPLY(z3, FIX(0.766367282)); /* c1+c11-c9-c13 */ - tmp12 += z1 + MULTIPLY(z2, FIX(1.971951411)); /* c1+c5+c13-c7 */ - z2 += z4; - z1 = MULTIPLY(z2, - FIX(0.666655658)); /* -c11 */ - tmp1 += z1; - tmp3 += z1 + MULTIPLY(z4, FIX(1.065388962)); /* c3+c11+c15-c7 */ - z2 = MULTIPLY(z2, - FIX(1.247225013)); /* -c5 */ - tmp10 += z2 + MULTIPLY(z4, FIX(3.141271809)); /* c1+c5+c9-c13 */ - tmp12 += z2; - z2 = MULTIPLY(z3 + z4, - FIX(1.353318001)); /* -c3 */ - tmp2 += z2; - tmp3 += z2; - z2 = MULTIPLY(z4 - z3, FIX(0.410524528)); /* c13 */ - tmp10 += z2; - tmp11 += z2; - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[15] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[14] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[13] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[12] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[11] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp25 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[10] = range_limit[(int) RIGHT_SHIFT(tmp25 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp26 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp26 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp27 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp27 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 14x7 output block. - * - * 7-point IDCT in pass 1 (columns), 14-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_14x7 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*7]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 7-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/14). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp23 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp23 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp23 += ONE << (CONST_BITS-PASS1_BITS-1); - - z1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - tmp20 = MULTIPLY(z2 - z3, FIX(0.881747734)); /* c4 */ - tmp22 = MULTIPLY(z1 - z2, FIX(0.314692123)); /* c6 */ - tmp21 = tmp20 + tmp22 + tmp23 - MULTIPLY(z2, FIX(1.841218003)); /* c2+c4-c6 */ - tmp10 = z1 + z3; - z2 -= tmp10; - tmp10 = MULTIPLY(tmp10, FIX(1.274162392)) + tmp23; /* c2 */ - tmp20 += tmp10 - MULTIPLY(z3, FIX(0.077722536)); /* c2-c4-c6 */ - tmp22 += tmp10 - MULTIPLY(z1, FIX(2.470602249)); /* c2+c4+c6 */ - tmp23 += MULTIPLY(z2, FIX(1.414213562)); /* c0 */ - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - - tmp11 = MULTIPLY(z1 + z2, FIX(0.935414347)); /* (c3+c1-c5)/2 */ - tmp12 = MULTIPLY(z1 - z2, FIX(0.170262339)); /* (c3+c5-c1)/2 */ - tmp10 = tmp11 - tmp12; - tmp11 += tmp12; - tmp12 = MULTIPLY(z2 + z3, - FIX(1.378756276)); /* -c1 */ - tmp11 += tmp12; - z2 = MULTIPLY(z1 + z3, FIX(0.613604268)); /* c5 */ - tmp10 += z2; - tmp12 += z2 + MULTIPLY(z3, FIX(1.870828693)); /* c3+c1-c5 */ - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*6] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp21 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp21 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp22 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp22 - tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp23, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 7 rows from work array, store into output array. - * 14-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/28). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 7; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - z1 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - z1 <<= CONST_BITS; - z4 = (INT32) wsptr[4]; - z2 = MULTIPLY(z4, FIX(1.274162392)); /* c4 */ - z3 = MULTIPLY(z4, FIX(0.314692123)); /* c12 */ - z4 = MULTIPLY(z4, FIX(0.881747734)); /* c8 */ - - tmp10 = z1 + z2; - tmp11 = z1 + z3; - tmp12 = z1 - z4; - - tmp23 = z1 - ((z2 + z3 - z4) << 1); /* c0 = (c4+c12-c8)*2 */ - - z1 = (INT32) wsptr[2]; - z2 = (INT32) wsptr[6]; - - z3 = MULTIPLY(z1 + z2, FIX(1.105676686)); /* c6 */ - - tmp13 = z3 + MULTIPLY(z1, FIX(0.273079590)); /* c2-c6 */ - tmp14 = z3 - MULTIPLY(z2, FIX(1.719280954)); /* c6+c10 */ - tmp15 = MULTIPLY(z1, FIX(0.613604268)) - /* c10 */ - MULTIPLY(z2, FIX(1.378756276)); /* c2 */ - - tmp20 = tmp10 + tmp13; - tmp26 = tmp10 - tmp13; - tmp21 = tmp11 + tmp14; - tmp25 = tmp11 - tmp14; - tmp22 = tmp12 + tmp15; - tmp24 = tmp12 - tmp15; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z4 = (INT32) wsptr[7]; - z4 <<= CONST_BITS; - - tmp14 = z1 + z3; - tmp11 = MULTIPLY(z1 + z2, FIX(1.334852607)); /* c3 */ - tmp12 = MULTIPLY(tmp14, FIX(1.197448846)); /* c5 */ - tmp10 = tmp11 + tmp12 + z4 - MULTIPLY(z1, FIX(1.126980169)); /* c3+c5-c1 */ - tmp14 = MULTIPLY(tmp14, FIX(0.752406978)); /* c9 */ - tmp16 = tmp14 - MULTIPLY(z1, FIX(1.061150426)); /* c9+c11-c13 */ - z1 -= z2; - tmp15 = MULTIPLY(z1, FIX(0.467085129)) - z4; /* c11 */ - tmp16 += tmp15; - tmp13 = MULTIPLY(z2 + z3, - FIX(0.158341681)) - z4; /* -c13 */ - tmp11 += tmp13 - MULTIPLY(z2, FIX(0.424103948)); /* c3-c9-c13 */ - tmp12 += tmp13 - MULTIPLY(z3, FIX(2.373959773)); /* c3+c5-c13 */ - tmp13 = MULTIPLY(z3 - z2, FIX(1.405321284)); /* c1 */ - tmp14 += tmp13 + z4 - MULTIPLY(z3, FIX(1.6906431334)); /* c1+c9-c11 */ - tmp15 += tmp13 + MULTIPLY(z2, FIX(0.674957567)); /* c1+c11-c5 */ - - tmp13 = ((z1 - z3) << CONST_BITS) + z4; - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[13] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[12] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[11] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[10] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp25 + tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp25 - tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp26 + tmp16, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp26 - tmp16, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 12x6 output block. - * - * 6-point IDCT in pass 1 (columns), 12-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_12x6 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*6]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 6-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/12). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp10 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp10 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp10 += ONE << (CONST_BITS-PASS1_BITS-1); - tmp12 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - tmp20 = MULTIPLY(tmp12, FIX(0.707106781)); /* c4 */ - tmp11 = tmp10 + tmp20; - tmp21 = RIGHT_SHIFT(tmp10 - tmp20 - tmp20, CONST_BITS-PASS1_BITS); - tmp20 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp10 = MULTIPLY(tmp20, FIX(1.224744871)); /* c2 */ - tmp20 = tmp11 + tmp10; - tmp22 = tmp11 - tmp10; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp11 = MULTIPLY(z1 + z3, FIX(0.366025404)); /* c5 */ - tmp10 = tmp11 + ((z1 + z2) << CONST_BITS); - tmp12 = tmp11 + ((z3 - z2) << CONST_BITS); - tmp11 = (z1 - z2 - z3) << PASS1_BITS; - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) (tmp21 + tmp11); - wsptr[8*4] = (int) (tmp21 - tmp11); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp22 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp22 - tmp12, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 6 rows from work array, store into output array. - * 12-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/24). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 6; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - z3 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - z3 <<= CONST_BITS; - - z4 = (INT32) wsptr[4]; - z4 = MULTIPLY(z4, FIX(1.224744871)); /* c4 */ - - tmp10 = z3 + z4; - tmp11 = z3 - z4; - - z1 = (INT32) wsptr[2]; - z4 = MULTIPLY(z1, FIX(1.366025404)); /* c2 */ - z1 <<= CONST_BITS; - z2 = (INT32) wsptr[6]; - z2 <<= CONST_BITS; - - tmp12 = z1 - z2; - - tmp21 = z3 + tmp12; - tmp24 = z3 - tmp12; - - tmp12 = z4 + z2; - - tmp20 = tmp10 + tmp12; - tmp25 = tmp10 - tmp12; - - tmp12 = z4 - z1 - z2; - - tmp22 = tmp11 + tmp12; - tmp23 = tmp11 - tmp12; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z4 = (INT32) wsptr[7]; - - tmp11 = MULTIPLY(z2, FIX(1.306562965)); /* c3 */ - tmp14 = MULTIPLY(z2, - FIX_0_541196100); /* -c9 */ - - tmp10 = z1 + z3; - tmp15 = MULTIPLY(tmp10 + z4, FIX(0.860918669)); /* c7 */ - tmp12 = tmp15 + MULTIPLY(tmp10, FIX(0.261052384)); /* c5-c7 */ - tmp10 = tmp12 + tmp11 + MULTIPLY(z1, FIX(0.280143716)); /* c1-c5 */ - tmp13 = MULTIPLY(z3 + z4, - FIX(1.045510580)); /* -(c7+c11) */ - tmp12 += tmp13 + tmp14 - MULTIPLY(z3, FIX(1.478575242)); /* c1+c5-c7-c11 */ - tmp13 += tmp15 - tmp11 + MULTIPLY(z4, FIX(1.586706681)); /* c1+c11 */ - tmp15 += tmp14 - MULTIPLY(z1, FIX(0.676326758)) - /* c7-c11 */ - MULTIPLY(z4, FIX(1.982889723)); /* c5+c7 */ - - z1 -= z4; - z2 -= z3; - z3 = MULTIPLY(z1 + z2, FIX_0_541196100); /* c9 */ - tmp11 = z3 + MULTIPLY(z1, FIX_0_765366865); /* c3-c9 */ - tmp14 = z3 - MULTIPLY(z2, FIX_1_847759065); /* c3+c9 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[11] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[10] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp25 + tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp25 - tmp15, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 10x5 output block. - * - * 5-point IDCT in pass 1 (columns), 10-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_10x5 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*5]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 5-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/10). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp12 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp12 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp12 += ONE << (CONST_BITS-PASS1_BITS-1); - tmp13 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp14 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z1 = MULTIPLY(tmp13 + tmp14, FIX(0.790569415)); /* (c2+c4)/2 */ - z2 = MULTIPLY(tmp13 - tmp14, FIX(0.353553391)); /* (c2-c4)/2 */ - z3 = tmp12 + z2; - tmp10 = z3 + z1; - tmp11 = z3 - z1; - tmp12 -= z2 << 2; - - /* Odd part */ - - z2 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - - z1 = MULTIPLY(z2 + z3, FIX(0.831253876)); /* c3 */ - tmp13 = z1 + MULTIPLY(z2, FIX(0.513743148)); /* c1-c3 */ - tmp14 = z1 - MULTIPLY(z3, FIX(2.176250899)); /* c1+c3 */ - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp10 + tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp10 - tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp11 + tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp11 - tmp14, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp12, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 5 rows from work array, store into output array. - * 10-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/20). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 5; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - z3 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - z3 <<= CONST_BITS; - z4 = (INT32) wsptr[4]; - z1 = MULTIPLY(z4, FIX(1.144122806)); /* c4 */ - z2 = MULTIPLY(z4, FIX(0.437016024)); /* c8 */ - tmp10 = z3 + z1; - tmp11 = z3 - z2; - - tmp22 = z3 - ((z1 - z2) << 1); /* c0 = (c4-c8)*2 */ - - z2 = (INT32) wsptr[2]; - z3 = (INT32) wsptr[6]; - - z1 = MULTIPLY(z2 + z3, FIX(0.831253876)); /* c6 */ - tmp12 = z1 + MULTIPLY(z2, FIX(0.513743148)); /* c2-c6 */ - tmp13 = z1 - MULTIPLY(z3, FIX(2.176250899)); /* c2+c6 */ - - tmp20 = tmp10 + tmp12; - tmp24 = tmp10 - tmp12; - tmp21 = tmp11 + tmp13; - tmp23 = tmp11 - tmp13; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - z3 <<= CONST_BITS; - z4 = (INT32) wsptr[7]; - - tmp11 = z2 + z4; - tmp13 = z2 - z4; - - tmp12 = MULTIPLY(tmp13, FIX(0.309016994)); /* (c3-c7)/2 */ - - z2 = MULTIPLY(tmp11, FIX(0.951056516)); /* (c3+c7)/2 */ - z4 = z3 + tmp12; - - tmp10 = MULTIPLY(z1, FIX(1.396802247)) + z2 + z4; /* c1 */ - tmp14 = MULTIPLY(z1, FIX(0.221231742)) - z2 + z4; /* c9 */ - - z2 = MULTIPLY(tmp11, FIX(0.587785252)); /* (c1-c9)/2 */ - z4 = z3 - tmp12 - (tmp13 << (CONST_BITS - 1)); - - tmp12 = ((z1 - tmp13) << CONST_BITS) - z3; - - tmp11 = MULTIPLY(z1, FIX(1.260073511)) - z2 - z4; /* c3 */ - tmp13 = MULTIPLY(z1, FIX(0.642039522)) - z2 + z4; /* c7 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[9] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[8] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp23 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp24 + tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp24 - tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 8; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 8x4 output block. - * - * 4-point IDCT in pass 1 (columns), 8-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_8x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp3; - INT32 tmp10, tmp11, tmp12, tmp13; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*4]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 4-point IDCT kernel, - * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point IDCT]. - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - - tmp10 = (tmp0 + tmp2) << PASS1_BITS; - tmp12 = (tmp0 - tmp2) << PASS1_BITS; - - /* Odd part */ - /* Same rotation as in the even part of the 8x8 LL&M IDCT */ - - z2 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - /* Add fudge factor here for final descale. */ - z1 += ONE << (CONST_BITS-PASS1_BITS-1); - tmp0 = RIGHT_SHIFT(z1 + MULTIPLY(z2, FIX_0_765366865), /* c2-c6 */ - CONST_BITS-PASS1_BITS); - tmp2 = RIGHT_SHIFT(z1 - MULTIPLY(z3, FIX_1_847759065), /* c2+c6 */ - CONST_BITS-PASS1_BITS); - - /* Final output stage */ - - wsptr[8*0] = (int) (tmp10 + tmp0); - wsptr[8*3] = (int) (tmp10 - tmp0); - wsptr[8*1] = (int) (tmp12 + tmp2); - wsptr[8*2] = (int) (tmp12 - tmp2); - } - - /* Pass 2: process rows from work array, store into output array. - * Note that we must descale the results by a factor of 8 == 2**3, - * and also undo the PASS1_BITS scaling. - * 8-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/16). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 4; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part: reverse the even part of the forward DCT. - * The rotator is c(-6). - */ - - /* Add range center and fudge factor for final descale and range-limit. */ - z2 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - z3 = (INT32) wsptr[4]; - - tmp0 = (z2 + z3) << CONST_BITS; - tmp1 = (z2 - z3) << CONST_BITS; - - z2 = (INT32) wsptr[2]; - z3 = (INT32) wsptr[6]; - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */ - tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */ - - tmp10 = tmp0 + tmp2; - tmp13 = tmp0 - tmp2; - tmp11 = tmp1 + tmp3; - tmp12 = tmp1 - tmp3; - - /* Odd part per figure 8; the matrix is unitary and hence its - * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. - */ - - tmp0 = (INT32) wsptr[7]; - tmp1 = (INT32) wsptr[5]; - tmp2 = (INT32) wsptr[3]; - tmp3 = (INT32) wsptr[1]; - - z2 = tmp0 + tmp2; - z3 = tmp1 + tmp3; - - z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* c3 */ - z2 = MULTIPLY(z2, - FIX_1_961570560); /* -c3-c5 */ - z3 = MULTIPLY(z3, - FIX_0_390180644); /* -c3+c5 */ - z2 += z1; - z3 += z1; - - z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */ - tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* -c1+c3+c5-c7 */ - tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* c1+c3-c5-c7 */ - tmp0 += z1 + z2; - tmp3 += z1 + z3; - - z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */ - tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* c1+c3-c5+c7 */ - tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* c1+c3+c5-c7 */ - tmp1 += z1 + z3; - tmp2 += z1 + z2; - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp11 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp11 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp13 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp13 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += DCTSIZE; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 6x3 output block. - * - * 3-point IDCT in pass 1 (columns), 6-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_6x3 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp10, tmp11, tmp12; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[6*3]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 3-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/6). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 6; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp0 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp0 += ONE << (CONST_BITS-PASS1_BITS-1); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp12 = MULTIPLY(tmp2, FIX(0.707106781)); /* c2 */ - tmp10 = tmp0 + tmp12; - tmp2 = tmp0 - tmp12 - tmp12; - - /* Odd part */ - - tmp12 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - tmp0 = MULTIPLY(tmp12, FIX(1.224744871)); /* c1 */ - - /* Final output stage */ - - wsptr[6*0] = (int) RIGHT_SHIFT(tmp10 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[6*2] = (int) RIGHT_SHIFT(tmp10 - tmp0, CONST_BITS-PASS1_BITS); - wsptr[6*1] = (int) RIGHT_SHIFT(tmp2, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 3 rows from work array, store into output array. - * 6-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/12). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 3; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp0 <<= CONST_BITS; - tmp2 = (INT32) wsptr[4]; - tmp10 = MULTIPLY(tmp2, FIX(0.707106781)); /* c4 */ - tmp1 = tmp0 + tmp10; - tmp11 = tmp0 - tmp10 - tmp10; - tmp10 = (INT32) wsptr[2]; - tmp0 = MULTIPLY(tmp10, FIX(1.224744871)); /* c2 */ - tmp10 = tmp1 + tmp0; - tmp12 = tmp1 - tmp0; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - tmp1 = MULTIPLY(z1 + z3, FIX(0.366025404)); /* c5 */ - tmp0 = tmp1 + ((z1 + z2) << CONST_BITS); - tmp2 = tmp1 + ((z3 - z2) << CONST_BITS); - tmp1 = (z1 - z2 - z3) << CONST_BITS; - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp11 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp11 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 6; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 4x2 output block. - * - * 2-point IDCT in pass 1 (columns), 4-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_4x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp2, tmp10, tmp12; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - INT32 * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - INT32 workspace[4*2]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 4; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp10 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - - /* Odd part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - - /* Final output stage */ - - wsptr[4*0] = tmp10 + tmp0; - wsptr[4*1] = tmp10 - tmp0; - } - - /* Pass 2: process 2 rows from work array, store into output array. - * 4-point IDCT kernel, - * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point IDCT]. - */ - - wsptr = workspace; - for (ctr = 0; ctr < 2; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 = wsptr[0] + ((((INT32) RANGE_CENTER) << 3) + (ONE << 2)); - tmp2 = wsptr[2]; - - tmp10 = (tmp0 + tmp2) << CONST_BITS; - tmp12 = (tmp0 - tmp2) << CONST_BITS; - - /* Odd part */ - /* Same rotation as in the even part of the 8x8 LL&M IDCT */ - - z2 = wsptr[1]; - z3 = wsptr[3]; - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - tmp0 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */ - tmp2 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, - CONST_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, - CONST_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp12 + tmp2, - CONST_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp2, - CONST_BITS+3) - & RANGE_MASK]; - - wsptr += 4; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 2x1 output block. - * - * 1-point IDCT in pass 1 (columns), 2-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_2x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - DCTELEM tmp0, tmp1; - ISLOW_MULT_TYPE * quantptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - ISHIFT_TEMPS - - /* Pass 1: empty. */ - - /* Pass 2: process 1 row from input, store into output array. */ - - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - outptr = output_buf[0] + output_col; - - /* Even part */ - - tmp0 = DEQUANTIZE(coef_block[0], quantptr[0]); - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 += (((DCTELEM) RANGE_CENTER) << 3) + (1 << 2); - - /* Odd part */ - - tmp1 = DEQUANTIZE(coef_block[1], quantptr[1]); - - /* Final output stage */ - - outptr[0] = range_limit[(int) IRIGHT_SHIFT(tmp0 + tmp1, 3) & RANGE_MASK]; - outptr[1] = range_limit[(int) IRIGHT_SHIFT(tmp0 - tmp1, 3) & RANGE_MASK]; -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 8x16 output block. - * - * 16-point IDCT in pass 1 (columns), 8-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_8x16 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp3, tmp10, tmp11, tmp12, tmp13; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[8*16]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 16-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/32). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp0 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp0 += ONE << (CONST_BITS-PASS1_BITS-1); - - z1 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - tmp1 = MULTIPLY(z1, FIX(1.306562965)); /* c4[16] = c2[8] */ - tmp2 = MULTIPLY(z1, FIX_0_541196100); /* c12[16] = c6[8] */ - - tmp10 = tmp0 + tmp1; - tmp11 = tmp0 - tmp1; - tmp12 = tmp0 + tmp2; - tmp13 = tmp0 - tmp2; - - z1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z2 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - z3 = z1 - z2; - z4 = MULTIPLY(z3, FIX(0.275899379)); /* c14[16] = c7[8] */ - z3 = MULTIPLY(z3, FIX(1.387039845)); /* c2[16] = c1[8] */ - - tmp0 = z3 + MULTIPLY(z2, FIX_2_562915447); /* (c6+c2)[16] = (c3+c1)[8] */ - tmp1 = z4 + MULTIPLY(z1, FIX_0_899976223); /* (c6-c14)[16] = (c3-c7)[8] */ - tmp2 = z3 - MULTIPLY(z1, FIX(0.601344887)); /* (c2-c10)[16] = (c1-c5)[8] */ - tmp3 = z4 - MULTIPLY(z2, FIX(0.509795579)); /* (c10-c14)[16] = (c5-c7)[8] */ - - tmp20 = tmp10 + tmp0; - tmp27 = tmp10 - tmp0; - tmp21 = tmp12 + tmp1; - tmp26 = tmp12 - tmp1; - tmp22 = tmp13 + tmp2; - tmp25 = tmp13 - tmp2; - tmp23 = tmp11 + tmp3; - tmp24 = tmp11 - tmp3; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - tmp11 = z1 + z3; - - tmp1 = MULTIPLY(z1 + z2, FIX(1.353318001)); /* c3 */ - tmp2 = MULTIPLY(tmp11, FIX(1.247225013)); /* c5 */ - tmp3 = MULTIPLY(z1 + z4, FIX(1.093201867)); /* c7 */ - tmp10 = MULTIPLY(z1 - z4, FIX(0.897167586)); /* c9 */ - tmp11 = MULTIPLY(tmp11, FIX(0.666655658)); /* c11 */ - tmp12 = MULTIPLY(z1 - z2, FIX(0.410524528)); /* c13 */ - tmp0 = tmp1 + tmp2 + tmp3 - - MULTIPLY(z1, FIX(2.286341144)); /* c7+c5+c3-c1 */ - tmp13 = tmp10 + tmp11 + tmp12 - - MULTIPLY(z1, FIX(1.835730603)); /* c9+c11+c13-c15 */ - z1 = MULTIPLY(z2 + z3, FIX(0.138617169)); /* c15 */ - tmp1 += z1 + MULTIPLY(z2, FIX(0.071888074)); /* c9+c11-c3-c15 */ - tmp2 += z1 - MULTIPLY(z3, FIX(1.125726048)); /* c5+c7+c15-c3 */ - z1 = MULTIPLY(z3 - z2, FIX(1.407403738)); /* c1 */ - tmp11 += z1 - MULTIPLY(z3, FIX(0.766367282)); /* c1+c11-c9-c13 */ - tmp12 += z1 + MULTIPLY(z2, FIX(1.971951411)); /* c1+c5+c13-c7 */ - z2 += z4; - z1 = MULTIPLY(z2, - FIX(0.666655658)); /* -c11 */ - tmp1 += z1; - tmp3 += z1 + MULTIPLY(z4, FIX(1.065388962)); /* c3+c11+c15-c7 */ - z2 = MULTIPLY(z2, - FIX(1.247225013)); /* -c5 */ - tmp10 += z2 + MULTIPLY(z4, FIX(3.141271809)); /* c1+c5+c9-c13 */ - tmp12 += z2; - z2 = MULTIPLY(z3 + z4, - FIX(1.353318001)); /* -c3 */ - tmp2 += z2; - tmp3 += z2; - z2 = MULTIPLY(z4 - z3, FIX(0.410524528)); /* c13 */ - tmp10 += z2; - tmp11 += z2; - - /* Final output stage */ - - wsptr[8*0] = (int) RIGHT_SHIFT(tmp20 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[8*15] = (int) RIGHT_SHIFT(tmp20 - tmp0, CONST_BITS-PASS1_BITS); - wsptr[8*1] = (int) RIGHT_SHIFT(tmp21 + tmp1, CONST_BITS-PASS1_BITS); - wsptr[8*14] = (int) RIGHT_SHIFT(tmp21 - tmp1, CONST_BITS-PASS1_BITS); - wsptr[8*2] = (int) RIGHT_SHIFT(tmp22 + tmp2, CONST_BITS-PASS1_BITS); - wsptr[8*13] = (int) RIGHT_SHIFT(tmp22 - tmp2, CONST_BITS-PASS1_BITS); - wsptr[8*3] = (int) RIGHT_SHIFT(tmp23 + tmp3, CONST_BITS-PASS1_BITS); - wsptr[8*12] = (int) RIGHT_SHIFT(tmp23 - tmp3, CONST_BITS-PASS1_BITS); - wsptr[8*4] = (int) RIGHT_SHIFT(tmp24 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*11] = (int) RIGHT_SHIFT(tmp24 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[8*5] = (int) RIGHT_SHIFT(tmp25 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*10] = (int) RIGHT_SHIFT(tmp25 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[8*6] = (int) RIGHT_SHIFT(tmp26 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*9] = (int) RIGHT_SHIFT(tmp26 - tmp12, CONST_BITS-PASS1_BITS); - wsptr[8*7] = (int) RIGHT_SHIFT(tmp27 + tmp13, CONST_BITS-PASS1_BITS); - wsptr[8*8] = (int) RIGHT_SHIFT(tmp27 - tmp13, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process rows from work array, store into output array. - * Note that we must descale the results by a factor of 8 == 2**3, - * and also undo the PASS1_BITS scaling. - * 8-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/16). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 16; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part: reverse the even part of the forward DCT. - * The rotator is c(-6). - */ - - /* Add range center and fudge factor for final descale and range-limit. */ - z2 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - z3 = (INT32) wsptr[4]; - - tmp0 = (z2 + z3) << CONST_BITS; - tmp1 = (z2 - z3) << CONST_BITS; - - z2 = (INT32) wsptr[2]; - z3 = (INT32) wsptr[6]; - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */ - tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */ - - tmp10 = tmp0 + tmp2; - tmp13 = tmp0 - tmp2; - tmp11 = tmp1 + tmp3; - tmp12 = tmp1 - tmp3; - - /* Odd part per figure 8; the matrix is unitary and hence its - * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. - */ - - tmp0 = (INT32) wsptr[7]; - tmp1 = (INT32) wsptr[5]; - tmp2 = (INT32) wsptr[3]; - tmp3 = (INT32) wsptr[1]; - - z2 = tmp0 + tmp2; - z3 = tmp1 + tmp3; - - z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* c3 */ - z2 = MULTIPLY(z2, - FIX_1_961570560); /* -c3-c5 */ - z3 = MULTIPLY(z3, - FIX_0_390180644); /* -c3+c5 */ - z2 += z1; - z3 += z1; - - z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */ - tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* -c1+c3+c5-c7 */ - tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* c1+c3-c5-c7 */ - tmp0 += z1 + z2; - tmp3 += z1 + z3; - - z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */ - tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* c1+c3-c5+c7 */ - tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* c1+c3+c5-c7 */ - tmp1 += z1 + z3; - tmp2 += z1 + z2; - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[7] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp11 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp11 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp13 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp13 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += DCTSIZE; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 7x14 output block. - * - * 14-point IDCT in pass 1 (columns), 7-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_7x14 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[7*14]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 14-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/28). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 7; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z1 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z1 += ONE << (CONST_BITS-PASS1_BITS-1); - z4 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z2 = MULTIPLY(z4, FIX(1.274162392)); /* c4 */ - z3 = MULTIPLY(z4, FIX(0.314692123)); /* c12 */ - z4 = MULTIPLY(z4, FIX(0.881747734)); /* c8 */ - - tmp10 = z1 + z2; - tmp11 = z1 + z3; - tmp12 = z1 - z4; - - tmp23 = RIGHT_SHIFT(z1 - ((z2 + z3 - z4) << 1), /* c0 = (c4+c12-c8)*2 */ - CONST_BITS-PASS1_BITS); - - z1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z2 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - z3 = MULTIPLY(z1 + z2, FIX(1.105676686)); /* c6 */ - - tmp13 = z3 + MULTIPLY(z1, FIX(0.273079590)); /* c2-c6 */ - tmp14 = z3 - MULTIPLY(z2, FIX(1.719280954)); /* c6+c10 */ - tmp15 = MULTIPLY(z1, FIX(0.613604268)) - /* c10 */ - MULTIPLY(z2, FIX(1.378756276)); /* c2 */ - - tmp20 = tmp10 + tmp13; - tmp26 = tmp10 - tmp13; - tmp21 = tmp11 + tmp14; - tmp25 = tmp11 - tmp14; - tmp22 = tmp12 + tmp15; - tmp24 = tmp12 - tmp15; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - tmp13 = z4 << CONST_BITS; - - tmp14 = z1 + z3; - tmp11 = MULTIPLY(z1 + z2, FIX(1.334852607)); /* c3 */ - tmp12 = MULTIPLY(tmp14, FIX(1.197448846)); /* c5 */ - tmp10 = tmp11 + tmp12 + tmp13 - MULTIPLY(z1, FIX(1.126980169)); /* c3+c5-c1 */ - tmp14 = MULTIPLY(tmp14, FIX(0.752406978)); /* c9 */ - tmp16 = tmp14 - MULTIPLY(z1, FIX(1.061150426)); /* c9+c11-c13 */ - z1 -= z2; - tmp15 = MULTIPLY(z1, FIX(0.467085129)) - tmp13; /* c11 */ - tmp16 += tmp15; - z1 += z4; - z4 = MULTIPLY(z2 + z3, - FIX(0.158341681)) - tmp13; /* -c13 */ - tmp11 += z4 - MULTIPLY(z2, FIX(0.424103948)); /* c3-c9-c13 */ - tmp12 += z4 - MULTIPLY(z3, FIX(2.373959773)); /* c3+c5-c13 */ - z4 = MULTIPLY(z3 - z2, FIX(1.405321284)); /* c1 */ - tmp14 += z4 + tmp13 - MULTIPLY(z3, FIX(1.6906431334)); /* c1+c9-c11 */ - tmp15 += z4 + MULTIPLY(z2, FIX(0.674957567)); /* c1+c11-c5 */ - - tmp13 = (z1 - z3) << PASS1_BITS; - - /* Final output stage */ - - wsptr[7*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[7*13] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[7*1] = (int) RIGHT_SHIFT(tmp21 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[7*12] = (int) RIGHT_SHIFT(tmp21 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[7*2] = (int) RIGHT_SHIFT(tmp22 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[7*11] = (int) RIGHT_SHIFT(tmp22 - tmp12, CONST_BITS-PASS1_BITS); - wsptr[7*3] = (int) (tmp23 + tmp13); - wsptr[7*10] = (int) (tmp23 - tmp13); - wsptr[7*4] = (int) RIGHT_SHIFT(tmp24 + tmp14, CONST_BITS-PASS1_BITS); - wsptr[7*9] = (int) RIGHT_SHIFT(tmp24 - tmp14, CONST_BITS-PASS1_BITS); - wsptr[7*5] = (int) RIGHT_SHIFT(tmp25 + tmp15, CONST_BITS-PASS1_BITS); - wsptr[7*8] = (int) RIGHT_SHIFT(tmp25 - tmp15, CONST_BITS-PASS1_BITS); - wsptr[7*6] = (int) RIGHT_SHIFT(tmp26 + tmp16, CONST_BITS-PASS1_BITS); - wsptr[7*7] = (int) RIGHT_SHIFT(tmp26 - tmp16, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 14 rows from work array, store into output array. - * 7-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/14). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 14; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp23 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp23 <<= CONST_BITS; - - z1 = (INT32) wsptr[2]; - z2 = (INT32) wsptr[4]; - z3 = (INT32) wsptr[6]; - - tmp20 = MULTIPLY(z2 - z3, FIX(0.881747734)); /* c4 */ - tmp22 = MULTIPLY(z1 - z2, FIX(0.314692123)); /* c6 */ - tmp21 = tmp20 + tmp22 + tmp23 - MULTIPLY(z2, FIX(1.841218003)); /* c2+c4-c6 */ - tmp10 = z1 + z3; - z2 -= tmp10; - tmp10 = MULTIPLY(tmp10, FIX(1.274162392)) + tmp23; /* c2 */ - tmp20 += tmp10 - MULTIPLY(z3, FIX(0.077722536)); /* c2-c4-c6 */ - tmp22 += tmp10 - MULTIPLY(z1, FIX(2.470602249)); /* c2+c4+c6 */ - tmp23 += MULTIPLY(z2, FIX(1.414213562)); /* c0 */ - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - - tmp11 = MULTIPLY(z1 + z2, FIX(0.935414347)); /* (c3+c1-c5)/2 */ - tmp12 = MULTIPLY(z1 - z2, FIX(0.170262339)); /* (c3+c5-c1)/2 */ - tmp10 = tmp11 - tmp12; - tmp11 += tmp12; - tmp12 = MULTIPLY(z2 + z3, - FIX(1.378756276)); /* -c1 */ - tmp11 += tmp12; - z2 = MULTIPLY(z1 + z3, FIX(0.613604268)); /* c5 */ - tmp10 += z2; - tmp12 += z2 + MULTIPLY(z3, FIX(1.870828693)); /* c3+c1-c5 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[6] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp23, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 7; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 6x12 output block. - * - * 12-point IDCT in pass 1 (columns), 6-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_6x12 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14, tmp15; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24, tmp25; - INT32 z1, z2, z3, z4; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[6*12]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 12-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/24). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 6; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z3 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z3 += ONE << (CONST_BITS-PASS1_BITS-1); - - z4 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z4 = MULTIPLY(z4, FIX(1.224744871)); /* c4 */ - - tmp10 = z3 + z4; - tmp11 = z3 - z4; - - z1 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z4 = MULTIPLY(z1, FIX(1.366025404)); /* c2 */ - z1 <<= CONST_BITS; - z2 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - z2 <<= CONST_BITS; - - tmp12 = z1 - z2; - - tmp21 = z3 + tmp12; - tmp24 = z3 - tmp12; - - tmp12 = z4 + z2; - - tmp20 = tmp10 + tmp12; - tmp25 = tmp10 - tmp12; - - tmp12 = z4 - z1 - z2; - - tmp22 = tmp11 + tmp12; - tmp23 = tmp11 - tmp12; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - tmp11 = MULTIPLY(z2, FIX(1.306562965)); /* c3 */ - tmp14 = MULTIPLY(z2, - FIX_0_541196100); /* -c9 */ - - tmp10 = z1 + z3; - tmp15 = MULTIPLY(tmp10 + z4, FIX(0.860918669)); /* c7 */ - tmp12 = tmp15 + MULTIPLY(tmp10, FIX(0.261052384)); /* c5-c7 */ - tmp10 = tmp12 + tmp11 + MULTIPLY(z1, FIX(0.280143716)); /* c1-c5 */ - tmp13 = MULTIPLY(z3 + z4, - FIX(1.045510580)); /* -(c7+c11) */ - tmp12 += tmp13 + tmp14 - MULTIPLY(z3, FIX(1.478575242)); /* c1+c5-c7-c11 */ - tmp13 += tmp15 - tmp11 + MULTIPLY(z4, FIX(1.586706681)); /* c1+c11 */ - tmp15 += tmp14 - MULTIPLY(z1, FIX(0.676326758)) - /* c7-c11 */ - MULTIPLY(z4, FIX(1.982889723)); /* c5+c7 */ - - z1 -= z4; - z2 -= z3; - z3 = MULTIPLY(z1 + z2, FIX_0_541196100); /* c9 */ - tmp11 = z3 + MULTIPLY(z1, FIX_0_765366865); /* c3-c9 */ - tmp14 = z3 - MULTIPLY(z2, FIX_1_847759065); /* c3+c9 */ - - /* Final output stage */ - - wsptr[6*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[6*11] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[6*1] = (int) RIGHT_SHIFT(tmp21 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[6*10] = (int) RIGHT_SHIFT(tmp21 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[6*2] = (int) RIGHT_SHIFT(tmp22 + tmp12, CONST_BITS-PASS1_BITS); - wsptr[6*9] = (int) RIGHT_SHIFT(tmp22 - tmp12, CONST_BITS-PASS1_BITS); - wsptr[6*3] = (int) RIGHT_SHIFT(tmp23 + tmp13, CONST_BITS-PASS1_BITS); - wsptr[6*8] = (int) RIGHT_SHIFT(tmp23 - tmp13, CONST_BITS-PASS1_BITS); - wsptr[6*4] = (int) RIGHT_SHIFT(tmp24 + tmp14, CONST_BITS-PASS1_BITS); - wsptr[6*7] = (int) RIGHT_SHIFT(tmp24 - tmp14, CONST_BITS-PASS1_BITS); - wsptr[6*5] = (int) RIGHT_SHIFT(tmp25 + tmp15, CONST_BITS-PASS1_BITS); - wsptr[6*6] = (int) RIGHT_SHIFT(tmp25 - tmp15, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 12 rows from work array, store into output array. - * 6-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/12). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 12; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp10 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp10 <<= CONST_BITS; - tmp12 = (INT32) wsptr[4]; - tmp20 = MULTIPLY(tmp12, FIX(0.707106781)); /* c4 */ - tmp11 = tmp10 + tmp20; - tmp21 = tmp10 - tmp20 - tmp20; - tmp20 = (INT32) wsptr[2]; - tmp10 = MULTIPLY(tmp20, FIX(1.224744871)); /* c2 */ - tmp20 = tmp11 + tmp10; - tmp22 = tmp11 - tmp10; - - /* Odd part */ - - z1 = (INT32) wsptr[1]; - z2 = (INT32) wsptr[3]; - z3 = (INT32) wsptr[5]; - tmp11 = MULTIPLY(z1 + z3, FIX(0.366025404)); /* c5 */ - tmp10 = tmp11 + ((z1 + z2) << CONST_BITS); - tmp12 = tmp11 + ((z3 - z2) << CONST_BITS); - tmp11 = (z1 - z2 - z3) << CONST_BITS; - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp20 + tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[5] = range_limit[(int) RIGHT_SHIFT(tmp20 - tmp10, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp21 + tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp21 - tmp11, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp22 + tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp22 - tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 6; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 5x10 output block. - * - * 10-point IDCT in pass 1 (columns), 5-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_5x10 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp10, tmp11, tmp12, tmp13, tmp14; - INT32 tmp20, tmp21, tmp22, tmp23, tmp24; - INT32 z1, z2, z3, z4, z5; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[5*10]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 10-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/20). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 5; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - z3 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z3 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z3 += ONE << (CONST_BITS-PASS1_BITS-1); - z4 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z1 = MULTIPLY(z4, FIX(1.144122806)); /* c4 */ - z2 = MULTIPLY(z4, FIX(0.437016024)); /* c8 */ - tmp10 = z3 + z1; - tmp11 = z3 - z2; - - tmp22 = RIGHT_SHIFT(z3 - ((z1 - z2) << 1), /* c0 = (c4-c8)*2 */ - CONST_BITS-PASS1_BITS); - - z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - z1 = MULTIPLY(z2 + z3, FIX(0.831253876)); /* c6 */ - tmp12 = z1 + MULTIPLY(z2, FIX(0.513743148)); /* c2-c6 */ - tmp13 = z1 - MULTIPLY(z3, FIX(2.176250899)); /* c2+c6 */ - - tmp20 = tmp10 + tmp12; - tmp24 = tmp10 - tmp12; - tmp21 = tmp11 + tmp13; - tmp23 = tmp11 - tmp13; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - z4 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - - tmp11 = z2 + z4; - tmp13 = z2 - z4; - - tmp12 = MULTIPLY(tmp13, FIX(0.309016994)); /* (c3-c7)/2 */ - z5 = z3 << CONST_BITS; - - z2 = MULTIPLY(tmp11, FIX(0.951056516)); /* (c3+c7)/2 */ - z4 = z5 + tmp12; - - tmp10 = MULTIPLY(z1, FIX(1.396802247)) + z2 + z4; /* c1 */ - tmp14 = MULTIPLY(z1, FIX(0.221231742)) - z2 + z4; /* c9 */ - - z2 = MULTIPLY(tmp11, FIX(0.587785252)); /* (c1-c9)/2 */ - z4 = z5 - tmp12 - (tmp13 << (CONST_BITS - 1)); - - tmp12 = (z1 - tmp13 - z3) << PASS1_BITS; - - tmp11 = MULTIPLY(z1, FIX(1.260073511)) - z2 - z4; /* c3 */ - tmp13 = MULTIPLY(z1, FIX(0.642039522)) - z2 + z4; /* c7 */ - - /* Final output stage */ - - wsptr[5*0] = (int) RIGHT_SHIFT(tmp20 + tmp10, CONST_BITS-PASS1_BITS); - wsptr[5*9] = (int) RIGHT_SHIFT(tmp20 - tmp10, CONST_BITS-PASS1_BITS); - wsptr[5*1] = (int) RIGHT_SHIFT(tmp21 + tmp11, CONST_BITS-PASS1_BITS); - wsptr[5*8] = (int) RIGHT_SHIFT(tmp21 - tmp11, CONST_BITS-PASS1_BITS); - wsptr[5*2] = (int) (tmp22 + tmp12); - wsptr[5*7] = (int) (tmp22 - tmp12); - wsptr[5*3] = (int) RIGHT_SHIFT(tmp23 + tmp13, CONST_BITS-PASS1_BITS); - wsptr[5*6] = (int) RIGHT_SHIFT(tmp23 - tmp13, CONST_BITS-PASS1_BITS); - wsptr[5*4] = (int) RIGHT_SHIFT(tmp24 + tmp14, CONST_BITS-PASS1_BITS); - wsptr[5*5] = (int) RIGHT_SHIFT(tmp24 - tmp14, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 10 rows from work array, store into output array. - * 5-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/10). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 10; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp12 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp12 <<= CONST_BITS; - tmp13 = (INT32) wsptr[2]; - tmp14 = (INT32) wsptr[4]; - z1 = MULTIPLY(tmp13 + tmp14, FIX(0.790569415)); /* (c2+c4)/2 */ - z2 = MULTIPLY(tmp13 - tmp14, FIX(0.353553391)); /* (c2-c4)/2 */ - z3 = tmp12 + z2; - tmp10 = z3 + z1; - tmp11 = z3 - z1; - tmp12 -= z2 << 2; - - /* Odd part */ - - z2 = (INT32) wsptr[1]; - z3 = (INT32) wsptr[3]; - - z1 = MULTIPLY(z2 + z3, FIX(0.831253876)); /* c3 */ - tmp13 = z1 + MULTIPLY(z2, FIX(0.513743148)); /* c1-c3 */ - tmp14 = z1 - MULTIPLY(z3, FIX(2.176250899)); /* c1+c3 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[4] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp13, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp11 + tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp11 - tmp14, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 5; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 4x8 output block. - * - * 8-point IDCT in pass 1 (columns), 4-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_4x8 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp3; - INT32 tmp10, tmp11, tmp12, tmp13; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[4*8]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * Note results are scaled up by sqrt(8) compared to a true IDCT; - * furthermore, we scale the results by 2**PASS1_BITS. - * 8-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/16). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 4; ctr > 0; ctr--) { - /* Due to quantization, we will usually find that many of the input - * coefficients are zero, especially the AC terms. We can exploit this - * by short-circuiting the IDCT calculation for any column in which all - * the AC terms are zero. In that case each output is equal to the - * DC coefficient (with scale factor as needed). - * With typical images and quantization tables, half or more of the - * column DCT calculations can be simplified this way. - */ - - if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && - inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && - inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && - inptr[DCTSIZE*7] == 0) { - /* AC terms all zero */ - int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; - - wsptr[4*0] = dcval; - wsptr[4*1] = dcval; - wsptr[4*2] = dcval; - wsptr[4*3] = dcval; - wsptr[4*4] = dcval; - wsptr[4*5] = dcval; - wsptr[4*6] = dcval; - wsptr[4*7] = dcval; - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - continue; - } - - /* Even part: reverse the even part of the forward DCT. - * The rotator is c(-6). - */ - - z2 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - z3 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - z2 <<= CONST_BITS; - z3 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - z2 += ONE << (CONST_BITS-PASS1_BITS-1); - - tmp0 = z2 + z3; - tmp1 = z2 - z3; - - z2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - z3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - tmp2 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */ - tmp3 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */ - - tmp10 = tmp0 + tmp2; - tmp13 = tmp0 - tmp2; - tmp11 = tmp1 + tmp3; - tmp12 = tmp1 - tmp3; - - /* Odd part per figure 8; the matrix is unitary and hence its - * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively. - */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - tmp1 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - tmp3 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - - z2 = tmp0 + tmp2; - z3 = tmp1 + tmp3; - - z1 = MULTIPLY(z2 + z3, FIX_1_175875602); /* c3 */ - z2 = MULTIPLY(z2, - FIX_1_961570560); /* -c3-c5 */ - z3 = MULTIPLY(z3, - FIX_0_390180644); /* -c3+c5 */ - z2 += z1; - z3 += z1; - - z1 = MULTIPLY(tmp0 + tmp3, - FIX_0_899976223); /* -c3+c7 */ - tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* -c1+c3+c5-c7 */ - tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* c1+c3-c5-c7 */ - tmp0 += z1 + z2; - tmp3 += z1 + z3; - - z1 = MULTIPLY(tmp1 + tmp2, - FIX_2_562915447); /* -c1-c3 */ - tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* c1+c3-c5+c7 */ - tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* c1+c3+c5-c7 */ - tmp1 += z1 + z3; - tmp2 += z1 + z2; - - /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ - - wsptr[4*0] = (int) RIGHT_SHIFT(tmp10 + tmp3, CONST_BITS-PASS1_BITS); - wsptr[4*7] = (int) RIGHT_SHIFT(tmp10 - tmp3, CONST_BITS-PASS1_BITS); - wsptr[4*1] = (int) RIGHT_SHIFT(tmp11 + tmp2, CONST_BITS-PASS1_BITS); - wsptr[4*6] = (int) RIGHT_SHIFT(tmp11 - tmp2, CONST_BITS-PASS1_BITS); - wsptr[4*2] = (int) RIGHT_SHIFT(tmp12 + tmp1, CONST_BITS-PASS1_BITS); - wsptr[4*5] = (int) RIGHT_SHIFT(tmp12 - tmp1, CONST_BITS-PASS1_BITS); - wsptr[4*3] = (int) RIGHT_SHIFT(tmp13 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[4*4] = (int) RIGHT_SHIFT(tmp13 - tmp0, CONST_BITS-PASS1_BITS); - - inptr++; /* advance pointers to next column */ - quantptr++; - wsptr++; - } - - /* Pass 2: process 8 rows from work array, store into output array. - * 4-point IDCT kernel, - * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point IDCT]. - */ - - wsptr = workspace; - for (ctr = 0; ctr < 8; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp2 = (INT32) wsptr[2]; - - tmp10 = (tmp0 + tmp2) << CONST_BITS; - tmp12 = (tmp0 - tmp2) << CONST_BITS; - - /* Odd part */ - /* Same rotation as in the even part of the 8x8 LL&M IDCT */ - - z2 = (INT32) wsptr[1]; - z3 = (INT32) wsptr[3]; - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - tmp0 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */ - tmp2 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[3] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp12 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp12 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 4; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a reduced-size 3x6 output block. - * - * 6-point IDCT in pass 1 (columns), 3-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_3x6 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp1, tmp2, tmp10, tmp11, tmp12; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - int * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - int workspace[3*6]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 6-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/12). - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 3; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp0 <<= CONST_BITS; - /* Add fudge factor here for final descale. */ - tmp0 += ONE << (CONST_BITS-PASS1_BITS-1); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); - tmp10 = MULTIPLY(tmp2, FIX(0.707106781)); /* c4 */ - tmp1 = tmp0 + tmp10; - tmp11 = RIGHT_SHIFT(tmp0 - tmp10 - tmp10, CONST_BITS-PASS1_BITS); - tmp10 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - tmp0 = MULTIPLY(tmp10, FIX(1.224744871)); /* c2 */ - tmp10 = tmp1 + tmp0; - tmp12 = tmp1 - tmp0; - - /* Odd part */ - - z1 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z2 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - z3 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); - tmp1 = MULTIPLY(z1 + z3, FIX(0.366025404)); /* c5 */ - tmp0 = tmp1 + ((z1 + z2) << CONST_BITS); - tmp2 = tmp1 + ((z3 - z2) << CONST_BITS); - tmp1 = (z1 - z2 - z3) << PASS1_BITS; - - /* Final output stage */ - - wsptr[3*0] = (int) RIGHT_SHIFT(tmp10 + tmp0, CONST_BITS-PASS1_BITS); - wsptr[3*5] = (int) RIGHT_SHIFT(tmp10 - tmp0, CONST_BITS-PASS1_BITS); - wsptr[3*1] = (int) (tmp11 + tmp1); - wsptr[3*4] = (int) (tmp11 - tmp1); - wsptr[3*2] = (int) RIGHT_SHIFT(tmp12 + tmp2, CONST_BITS-PASS1_BITS); - wsptr[3*3] = (int) RIGHT_SHIFT(tmp12 - tmp2, CONST_BITS-PASS1_BITS); - } - - /* Pass 2: process 6 rows from work array, store into output array. - * 3-point IDCT kernel, cK represents sqrt(2) * cos(K*pi/6). - */ - - wsptr = workspace; - for (ctr = 0; ctr < 6; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 = (INT32) wsptr[0] + - ((((INT32) RANGE_CENTER) << (PASS1_BITS+3)) + - (ONE << (PASS1_BITS+2))); - tmp0 <<= CONST_BITS; - tmp2 = (INT32) wsptr[2]; - tmp12 = MULTIPLY(tmp2, FIX(0.707106781)); /* c2 */ - tmp10 = tmp0 + tmp12; - tmp2 = tmp0 - tmp12 - tmp12; - - /* Odd part */ - - tmp12 = (INT32) wsptr[1]; - tmp0 = MULTIPLY(tmp12, FIX(1.224744871)); /* c1 */ - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[2] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; - - wsptr += 3; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 2x4 output block. - * - * 4-point IDCT in pass 1 (columns), 2-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_2x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - INT32 tmp0, tmp2, tmp10, tmp12; - INT32 z1, z2, z3; - JCOEFPTR inptr; - ISLOW_MULT_TYPE * quantptr; - INT32 * wsptr; - JSAMPROW outptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - int ctr; - INT32 workspace[2*4]; /* buffers data between passes */ - SHIFT_TEMPS - - /* Pass 1: process columns from input, store into work array. - * 4-point IDCT kernel, - * cK represents sqrt(2) * cos(K*pi/16) [refers to 8-point IDCT]. - */ - - inptr = coef_block; - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - wsptr = workspace; - for (ctr = 0; ctr < 2; ctr++, inptr++, quantptr++, wsptr++) { - /* Even part */ - - tmp0 = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); - tmp2 = DEQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]); - - tmp10 = (tmp0 + tmp2) << CONST_BITS; - tmp12 = (tmp0 - tmp2) << CONST_BITS; - - /* Odd part */ - /* Same rotation as in the even part of the 8x8 LL&M IDCT */ - - z2 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); - z3 = DEQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]); - - z1 = MULTIPLY(z2 + z3, FIX_0_541196100); /* c6 */ - tmp0 = z1 + MULTIPLY(z2, FIX_0_765366865); /* c2-c6 */ - tmp2 = z1 - MULTIPLY(z3, FIX_1_847759065); /* c2+c6 */ - - /* Final output stage */ - - wsptr[2*0] = tmp10 + tmp0; - wsptr[2*3] = tmp10 - tmp0; - wsptr[2*1] = tmp12 + tmp2; - wsptr[2*2] = tmp12 - tmp2; - } - - /* Pass 2: process 4 rows from work array, store into output array. */ - - wsptr = workspace; - for (ctr = 0; ctr < 4; ctr++) { - outptr = output_buf[ctr] + output_col; - - /* Even part */ - - /* Add range center and fudge factor for final descale and range-limit. */ - tmp10 = wsptr[0] + - ((((INT32) RANGE_CENTER) << (CONST_BITS+3)) + - (ONE << (CONST_BITS+2))); - - /* Odd part */ - - tmp0 = wsptr[1]; - - /* Final output stage */ - - outptr[0] = range_limit[(int) RIGHT_SHIFT(tmp10 + tmp0, CONST_BITS+3) - & RANGE_MASK]; - outptr[1] = range_limit[(int) RIGHT_SHIFT(tmp10 - tmp0, CONST_BITS+3) - & RANGE_MASK]; - - wsptr += 2; /* advance pointer to next row */ - } -} - - -/* - * Perform dequantization and inverse DCT on one block of coefficients, - * producing a 1x2 output block. - * - * 2-point IDCT in pass 1 (columns), 1-point in pass 2 (rows). - */ - -GLOBAL(void) -jpeg_idct_1x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) -{ - DCTELEM tmp0, tmp1; - ISLOW_MULT_TYPE * quantptr; - JSAMPLE *range_limit = IDCT_range_limit(cinfo); - ISHIFT_TEMPS - - /* Process 1 column from input, store into output array. */ - - quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table; - - /* Even part */ - - tmp0 = DEQUANTIZE(coef_block[DCTSIZE*0], quantptr[DCTSIZE*0]); - /* Add range center and fudge factor for final descale and range-limit. */ - tmp0 += (((DCTELEM) RANGE_CENTER) << 3) + (1 << 2); - - /* Odd part */ - - tmp1 = DEQUANTIZE(coef_block[DCTSIZE*1], quantptr[DCTSIZE*1]); - - /* Final output stage */ - - output_buf[0][output_col] = - range_limit[(int) IRIGHT_SHIFT(tmp0 + tmp1, 3) & RANGE_MASK]; - output_buf[1][output_col] = - range_limit[(int) IRIGHT_SHIFT(tmp0 - tmp1, 3) & RANGE_MASK]; -} - -#endif /* IDCT_SCALING_SUPPORTED */ -#endif /* DCT_ISLOW_SUPPORTED */ diff --git a/libraries/jpeg/jinclude.h b/libraries/jpeg/jinclude.h deleted file mode 100644 index 20ed4ef11..000000000 --- a/libraries/jpeg/jinclude.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * jinclude.h - * - * Copyright (C) 1991-1994, Thomas G. Lane. - * Modified 2017 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file exists to provide a single place to fix any problems with - * including the wrong system include files. (Common problems are taken - * care of by the standard jconfig symbols, but on really weird systems - * you may have to edit this file.) - * - * NOTE: this file is NOT intended to be included by applications using the - * JPEG library. Most applications need only include jpeglib.h. - */ - - -/* Include auto-config file to find out which system include files we need. */ - -#include "jconfig.h" /* auto configuration options */ -#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ - -/* - * We need the NULL macro and size_t typedef. - * On an ANSI-conforming system it is sufficient to include . - * Otherwise, we get them from or ; we may have to - * pull in as well. - * Note that the core JPEG library does not require ; - * only the default error handler and data source/destination modules do. - * But we must pull it in because of the references to FILE in jpeglib.h. - * You can remove those references if you want to compile without . - */ - -#ifdef HAVE_STDDEF_H -#include -#endif - -#ifdef HAVE_STDLIB_H -#include -#endif - -#ifdef NEED_SYS_TYPES_H -#include -#endif - -#include - -/* - * We need memory copying and zeroing functions, plus strncpy(). - * ANSI and System V implementations declare these in . - * BSD doesn't have the mem() functions, but it does have bcopy()/bzero(). - * Some systems may declare memset and memcpy in . - * - * NOTE: we assume the size parameters to these functions are of type size_t. - * Change the casts in these macros if not! - */ - -#ifdef NEED_BSD_STRINGS - -#include -#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) -#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) - -#else /* not BSD, assume ANSI/SysV string lib */ - -#include -#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) -#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) - -#endif - -/* - * In ANSI C, and indeed any rational implementation, size_t is also the - * type returned by sizeof(). However, it seems there are some irrational - * implementations out there, in which sizeof() returns an int even though - * size_t is defined as long or unsigned long. To ensure consistent results - * we always use this SIZEOF() macro in place of using sizeof() directly. - */ - -#define SIZEOF(object) ((size_t) sizeof(object)) - -/* - * The modules that use fread() and fwrite() always invoke them through - * these macros. On some systems you may need to twiddle the argument casts. - * CAUTION: argument order is different from underlying functions! - * - * Furthermore, macros are provided for fflush() and ferror() in order - * to facilitate adaption by applications using an own FILE class. - */ - -#define JFREAD(file,buf,sizeofbuf) \ - ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) -#define JFWRITE(file,buf,sizeofbuf) \ - ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) -#define JFFLUSH(file) fflush(file) -#define JFERROR(file) ferror(file) diff --git a/libraries/jpeg/jmemansi.c b/libraries/jpeg/jmemansi.c deleted file mode 100644 index 2d93e4962..000000000 --- a/libraries/jpeg/jmemansi.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * jmemansi.c - * - * Copyright (C) 1992-1996, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides a simple generic implementation of the system- - * dependent portion of the JPEG memory manager. This implementation - * assumes that you have the ANSI-standard library routine tmpfile(). - * Also, the problem of determining the amount of memory available - * is shoved onto the user. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef HAVE_STDLIB_H /* should declare malloc(),free() */ -extern void * malloc JPP((size_t size)); -extern void free JPP((void *ptr)); -#endif - -#ifndef SEEK_SET /* pre-ANSI systems may not define this; */ -#define SEEK_SET 0 /* if not, assume 0 is correct */ -#endif - - -/* - * Memory allocation and freeing are controlled by the regular library - * routines malloc() and free(). - */ - -GLOBAL(void *) -jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void *) malloc(sizeofobject); -} - -GLOBAL(void) -jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * "Large" objects are treated the same as "small" ones. - * NB: although we include FAR keywords in the routine declarations, - * this file won't actually work in 80x86 small/medium model; at least, - * you probably won't be able to process useful-size images in only 64KB. - */ - -GLOBAL(void FAR *) -jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) -{ - return (void FAR *) malloc(sizeofobject); -} - -GLOBAL(void) -jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) -{ - free(object); -} - - -/* - * This routine computes the total memory space available for allocation. - * It's impossible to do this in a portable way; our current solution is - * to make the user tell us (with a default value set at compile time). - * If you can actually get the available space, it's a good idea to subtract - * a slop factor of 5% or so. - */ - -#ifndef DEFAULT_MAX_MEM /* so can override from makefile */ -#define DEFAULT_MAX_MEM 1000000L /* default: one megabyte */ -#endif - -GLOBAL(long) -jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, - long max_bytes_needed, long already_allocated) -{ - return cinfo->mem->max_memory_to_use - already_allocated; -} - - -/* - * Backing store (temporary file) management. - * Backing store objects are only used when the value returned by - * jpeg_mem_available is less than the total space needed. You can dispense - * with these routines if you have plenty of virtual memory; see jmemnobs.c. - */ - - -METHODDEF(void) -read_backing_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (fseek(info->temp_file, file_offset, SEEK_SET)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - if (JFREAD(info->temp_file, buffer_address, byte_count) - != (size_t) byte_count) - ERREXIT(cinfo, JERR_TFILE_READ); -} - - -METHODDEF(void) -write_backing_store (j_common_ptr cinfo, backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count) -{ - if (fseek(info->temp_file, file_offset, SEEK_SET)) - ERREXIT(cinfo, JERR_TFILE_SEEK); - if (JFWRITE(info->temp_file, buffer_address, byte_count) - != (size_t) byte_count) - ERREXIT(cinfo, JERR_TFILE_WRITE); -} - - -METHODDEF(void) -close_backing_store (j_common_ptr cinfo, backing_store_ptr info) -{ - fclose(info->temp_file); - /* Since this implementation uses tmpfile() to create the file, - * no explicit file deletion is needed. - */ -} - - -/* - * Initial opening of a backing-store object. - * - * This version uses tmpfile(), which constructs a suitable file name - * behind the scenes. We don't have to use info->temp_name[] at all; - * indeed, we can't even find out the actual name of the temp file. - */ - -GLOBAL(void) -jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, - long total_bytes_needed) -{ - if ((info->temp_file = tmpfile()) == NULL) - ERREXITS(cinfo, JERR_TFILE_CREATE, ""); - info->read_backing_store = read_backing_store; - info->write_backing_store = write_backing_store; - info->close_backing_store = close_backing_store; -} - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. - */ - -GLOBAL(long) -jpeg_mem_init (j_common_ptr cinfo) -{ - return DEFAULT_MAX_MEM; /* default for max_memory_to_use */ -} - -GLOBAL(void) -jpeg_mem_term (j_common_ptr cinfo) -{ - /* no work */ -} diff --git a/libraries/jpeg/jmemmgr.c b/libraries/jpeg/jmemmgr.c deleted file mode 100644 index 0a137cdde..000000000 --- a/libraries/jpeg/jmemmgr.c +++ /dev/null @@ -1,1119 +0,0 @@ -/* - * jmemmgr.c - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2011-2012 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains the JPEG system-independent memory management - * routines. This code is usable across a wide variety of machines; most - * of the system dependencies have been isolated in a separate file. - * The major functions provided here are: - * * pool-based allocation and freeing of memory; - * * policy decisions about how to divide available memory among the - * virtual arrays; - * * control logic for swapping virtual arrays between main memory and - * backing storage. - * The separate system-dependent file provides the actual backing-storage - * access code, and it contains the policy decision about how much total - * main memory to use. - * This file is system-dependent in the sense that some of its functions - * are unnecessary in some systems. For example, if there is enough virtual - * memory so that backing storage will never be used, much of the virtual - * array control logic could be removed. (Of course, if you have that much - * memory then you shouldn't care about a little bit of unused code...) - */ - -#define JPEG_INTERNALS -#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */ -#include "jinclude.h" -#include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ - -#ifndef NO_GETENV -#ifndef HAVE_STDLIB_H /* should declare getenv() */ -extern char * getenv JPP((const char * name)); -#endif -#endif - - -/* - * Some important notes: - * The allocation routines provided here must never return NULL. - * They should exit to error_exit if unsuccessful. - * - * It's not a good idea to try to merge the sarray and barray routines, - * even though they are textually almost the same, because samples are - * usually stored as bytes while coefficients are shorts or ints. Thus, - * in machines where byte pointers have a different representation from - * word pointers, the resulting machine code could not be the same. - */ - - -/* - * Many machines require storage alignment: longs must start on 4-byte - * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc() - * always returns pointers that are multiples of the worst-case alignment - * requirement, and we had better do so too. - * There isn't any really portable way to determine the worst-case alignment - * requirement. This module assumes that the alignment requirement is - * multiples of sizeof(ALIGN_TYPE). - * By default, we define ALIGN_TYPE as double. This is necessary on some - * workstations (where doubles really do need 8-byte alignment) and will work - * fine on nearly everything. If your machine has lesser alignment needs, - * you can save a few bytes by making ALIGN_TYPE smaller. - * The only place I know of where this will NOT work is certain Macintosh - * 680x0 compilers that define double as a 10-byte IEEE extended float. - * Doing 10-byte alignment is counterproductive because longwords won't be - * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have - * such a compiler. - */ - -#ifndef ALIGN_TYPE /* so can override from jconfig.h */ -#define ALIGN_TYPE double -#endif - - -/* - * We allocate objects from "pools", where each pool is gotten with a single - * request to jpeg_get_small() or jpeg_get_large(). There is no per-object - * overhead within a pool, except for alignment padding. Each pool has a - * header with a link to the next pool of the same class. - * Small and large pool headers are identical except that the latter's - * link pointer must be FAR on 80x86 machines. - * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE - * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple - * of the alignment requirement of ALIGN_TYPE. - */ - -typedef union small_pool_struct * small_pool_ptr; - -typedef union small_pool_struct { - struct { - small_pool_ptr next; /* next in list of pools */ - size_t bytes_used; /* how many bytes already used within pool */ - size_t bytes_left; /* bytes still available in this pool */ - } hdr; - ALIGN_TYPE dummy; /* included in union to ensure alignment */ -} small_pool_hdr; - -typedef union large_pool_struct FAR * large_pool_ptr; - -typedef union large_pool_struct { - struct { - large_pool_ptr next; /* next in list of pools */ - size_t bytes_used; /* how many bytes already used within pool */ - size_t bytes_left; /* bytes still available in this pool */ - } hdr; - ALIGN_TYPE dummy; /* included in union to ensure alignment */ -} large_pool_hdr; - - -/* - * Here is the full definition of a memory manager object. - */ - -typedef struct { - struct jpeg_memory_mgr pub; /* public fields */ - - /* Each pool identifier (lifetime class) names a linked list of pools. */ - small_pool_ptr small_list[JPOOL_NUMPOOLS]; - large_pool_ptr large_list[JPOOL_NUMPOOLS]; - - /* Since we only have one lifetime class of virtual arrays, only one - * linked list is necessary (for each datatype). Note that the virtual - * array control blocks being linked together are actually stored somewhere - * in the small-pool list. - */ - jvirt_sarray_ptr virt_sarray_list; - jvirt_barray_ptr virt_barray_list; - - /* This counts total space obtained from jpeg_get_small/large */ - long total_space_allocated; - - /* alloc_sarray and alloc_barray set this value for use by virtual - * array routines. - */ - JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */ -} my_memory_mgr; - -typedef my_memory_mgr * my_mem_ptr; - - -/* - * The control blocks for virtual arrays. - * Note that these blocks are allocated in the "small" pool area. - * System-dependent info for the associated backing store (if any) is hidden - * inside the backing_store_info struct. - */ - -struct jvirt_sarray_control { - JSAMPARRAY mem_buffer; /* => the in-memory buffer */ - JDIMENSION rows_in_array; /* total virtual array height */ - JDIMENSION samplesperrow; /* width of array (and of memory buffer) */ - JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */ - JDIMENSION rows_in_mem; /* height of memory buffer */ - JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ - JDIMENSION cur_start_row; /* first logical row # in the buffer */ - JDIMENSION first_undef_row; /* row # of first uninitialized row */ - boolean pre_zero; /* pre-zero mode requested? */ - boolean dirty; /* do current buffer contents need written? */ - boolean b_s_open; /* is backing-store data valid? */ - jvirt_sarray_ptr next; /* link to next virtual sarray control block */ - backing_store_info b_s_info; /* System-dependent control info */ -}; - -struct jvirt_barray_control { - JBLOCKARRAY mem_buffer; /* => the in-memory buffer */ - JDIMENSION rows_in_array; /* total virtual array height */ - JDIMENSION blocksperrow; /* width of array (and of memory buffer) */ - JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */ - JDIMENSION rows_in_mem; /* height of memory buffer */ - JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ - JDIMENSION cur_start_row; /* first logical row # in the buffer */ - JDIMENSION first_undef_row; /* row # of first uninitialized row */ - boolean pre_zero; /* pre-zero mode requested? */ - boolean dirty; /* do current buffer contents need written? */ - boolean b_s_open; /* is backing-store data valid? */ - jvirt_barray_ptr next; /* link to next virtual barray control block */ - backing_store_info b_s_info; /* System-dependent control info */ -}; - - -#ifdef MEM_STATS /* optional extra stuff for statistics */ - -LOCAL(void) -print_mem_stats (j_common_ptr cinfo, int pool_id) -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - small_pool_ptr shdr_ptr; - large_pool_ptr lhdr_ptr; - - /* Since this is only a debugging stub, we can cheat a little by using - * fprintf directly rather than going through the trace message code. - * This is helpful because message parm array can't handle longs. - */ - fprintf(stderr, "Freeing pool %d, total space = %ld\n", - pool_id, mem->total_space_allocated); - - for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL; - lhdr_ptr = lhdr_ptr->hdr.next) { - fprintf(stderr, " Large chunk used %ld\n", - (long) lhdr_ptr->hdr.bytes_used); - } - - for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL; - shdr_ptr = shdr_ptr->hdr.next) { - fprintf(stderr, " Small chunk used %ld free %ld\n", - (long) shdr_ptr->hdr.bytes_used, - (long) shdr_ptr->hdr.bytes_left); - } -} - -#endif /* MEM_STATS */ - - -LOCAL(noreturn_t) -out_of_memory (j_common_ptr cinfo, int which) -/* Report an out-of-memory error and stop execution */ -/* If we compiled MEM_STATS support, report alloc requests before dying */ -{ -#ifdef MEM_STATS - cinfo->err->trace_level = 2; /* force self_destruct to report stats */ -#endif - ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which); -} - - -/* - * Allocation of "small" objects. - * - * For these, we use pooled storage. When a new pool must be created, - * we try to get enough space for the current request plus a "slop" factor, - * where the slop will be the amount of leftover space in the new pool. - * The speed vs. space tradeoff is largely determined by the slop values. - * A different slop value is provided for each pool class (lifetime), - * and we also distinguish the first pool of a class from later ones. - * NOTE: the values given work fairly well on both 16- and 32-bit-int - * machines, but may be too small if longs are 64 bits or more. - */ - -static const size_t first_pool_slop[JPOOL_NUMPOOLS] = -{ - 1600, /* first PERMANENT pool */ - 16000 /* first IMAGE pool */ -}; - -static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = -{ - 0, /* additional PERMANENT pools */ - 5000 /* additional IMAGE pools */ -}; - -#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ - - -METHODDEF(void *) -alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) -/* Allocate a "small" object */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - small_pool_ptr hdr_ptr, prev_hdr_ptr; - char * data_ptr; - size_t odd_bytes, min_request, slop; - - /* Check for unsatisfiable request (do now to ensure no overflow below) */ - if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr))) - out_of_memory(cinfo, 1); /* request exceeds malloc's ability */ - - /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ - odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); - if (odd_bytes > 0) - sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; - - /* See if space is available in any existing pool */ - if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ - prev_hdr_ptr = NULL; - hdr_ptr = mem->small_list[pool_id]; - while (hdr_ptr != NULL) { - if (hdr_ptr->hdr.bytes_left >= sizeofobject) - break; /* found pool with enough space */ - prev_hdr_ptr = hdr_ptr; - hdr_ptr = hdr_ptr->hdr.next; - } - - /* Time to make a new pool? */ - if (hdr_ptr == NULL) { - /* min_request is what we need now, slop is what will be leftover */ - min_request = sizeofobject + SIZEOF(small_pool_hdr); - if (prev_hdr_ptr == NULL) /* first pool in class? */ - slop = first_pool_slop[pool_id]; - else - slop = extra_pool_slop[pool_id]; - /* Don't ask for more than MAX_ALLOC_CHUNK */ - if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request)) - slop = (size_t) (MAX_ALLOC_CHUNK-min_request); - /* Try to get space, if fail reduce slop and try again */ - for (;;) { - hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop); - if (hdr_ptr != NULL) - break; - slop /= 2; - if (slop < MIN_SLOP) /* give up when it gets real small */ - out_of_memory(cinfo, 2); /* jpeg_get_small failed */ - } - mem->total_space_allocated += min_request + slop; - /* Success, initialize the new pool header and add to end of list */ - hdr_ptr->hdr.next = NULL; - hdr_ptr->hdr.bytes_used = 0; - hdr_ptr->hdr.bytes_left = sizeofobject + slop; - if (prev_hdr_ptr == NULL) /* first pool in class? */ - mem->small_list[pool_id] = hdr_ptr; - else - prev_hdr_ptr->hdr.next = hdr_ptr; - } - - /* OK, allocate the object from the current pool */ - data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */ - data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */ - hdr_ptr->hdr.bytes_used += sizeofobject; - hdr_ptr->hdr.bytes_left -= sizeofobject; - - return (void *) data_ptr; -} - - -/* - * Allocation of "large" objects. - * - * The external semantics of these are the same as "small" objects, - * except that FAR pointers are used on 80x86. However the pool - * management heuristics are quite different. We assume that each - * request is large enough that it may as well be passed directly to - * jpeg_get_large; the pool management just links everything together - * so that we can free it all on demand. - * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY - * structures. The routines that create these structures (see below) - * deliberately bunch rows together to ensure a large request size. - */ - -METHODDEF(void FAR *) -alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) -/* Allocate a "large" object */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - large_pool_ptr hdr_ptr; - size_t odd_bytes; - - /* Check for unsatisfiable request (do now to ensure no overflow below) */ - if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr))) - out_of_memory(cinfo, 3); /* request exceeds malloc's ability */ - - /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ - odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); - if (odd_bytes > 0) - sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes; - - /* Always make a new pool */ - if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ - - hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject + - SIZEOF(large_pool_hdr)); - if (hdr_ptr == NULL) - out_of_memory(cinfo, 4); /* jpeg_get_large failed */ - mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr); - - /* Success, initialize the new pool header and add to list */ - hdr_ptr->hdr.next = mem->large_list[pool_id]; - /* We maintain space counts in each pool header for statistical purposes, - * even though they are not needed for allocation. - */ - hdr_ptr->hdr.bytes_used = sizeofobject; - hdr_ptr->hdr.bytes_left = 0; - mem->large_list[pool_id] = hdr_ptr; - - return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */ -} - - -/* - * Creation of 2-D sample arrays. - * The pointers are in near heap, the samples themselves in FAR heap. - * - * To minimize allocation overhead and to allow I/O of large contiguous - * blocks, we allocate the sample rows in groups of as many rows as possible - * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request. - * NB: the virtual array control routines, later in this file, know about - * this chunking of rows. The rowsperchunk value is left in the mem manager - * object so that it can be saved away if this sarray is the workspace for - * a virtual array. - */ - -METHODDEF(JSAMPARRAY) -alloc_sarray (j_common_ptr cinfo, int pool_id, - JDIMENSION samplesperrow, JDIMENSION numrows) -/* Allocate a 2-D sample array */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - JSAMPARRAY result; - JSAMPROW workspace; - JDIMENSION rowsperchunk, currow, i; - long ltemp; - - /* Calculate max # of rows allowed in one allocation chunk */ - ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / - ((long) samplesperrow * SIZEOF(JSAMPLE)); - if (ltemp <= 0) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); - if (ltemp < (long) numrows) - rowsperchunk = (JDIMENSION) ltemp; - else - rowsperchunk = numrows; - mem->last_rowsperchunk = rowsperchunk; - - /* Get space for row pointers (small object) */ - result = (JSAMPARRAY) alloc_small(cinfo, pool_id, - (size_t) (numrows * SIZEOF(JSAMPROW))); - - /* Get the rows themselves (large objects) */ - currow = 0; - while (currow < numrows) { - rowsperchunk = MIN(rowsperchunk, numrows - currow); - workspace = (JSAMPROW) alloc_large(cinfo, pool_id, - (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow - * SIZEOF(JSAMPLE))); - for (i = rowsperchunk; i > 0; i--) { - result[currow++] = workspace; - workspace += samplesperrow; - } - } - - return result; -} - - -/* - * Creation of 2-D coefficient-block arrays. - * This is essentially the same as the code for sample arrays, above. - */ - -METHODDEF(JBLOCKARRAY) -alloc_barray (j_common_ptr cinfo, int pool_id, - JDIMENSION blocksperrow, JDIMENSION numrows) -/* Allocate a 2-D coefficient-block array */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - JBLOCKARRAY result; - JBLOCKROW workspace; - JDIMENSION rowsperchunk, currow, i; - long ltemp; - - /* Calculate max # of rows allowed in one allocation chunk */ - ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / - ((long) blocksperrow * SIZEOF(JBLOCK)); - if (ltemp <= 0) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); - if (ltemp < (long) numrows) - rowsperchunk = (JDIMENSION) ltemp; - else - rowsperchunk = numrows; - mem->last_rowsperchunk = rowsperchunk; - - /* Get space for row pointers (small object) */ - result = (JBLOCKARRAY) alloc_small(cinfo, pool_id, - (size_t) (numrows * SIZEOF(JBLOCKROW))); - - /* Get the rows themselves (large objects) */ - currow = 0; - while (currow < numrows) { - rowsperchunk = MIN(rowsperchunk, numrows - currow); - workspace = (JBLOCKROW) alloc_large(cinfo, pool_id, - (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow - * SIZEOF(JBLOCK))); - for (i = rowsperchunk; i > 0; i--) { - result[currow++] = workspace; - workspace += blocksperrow; - } - } - - return result; -} - - -/* - * About virtual array management: - * - * The above "normal" array routines are only used to allocate strip buffers - * (as wide as the image, but just a few rows high). Full-image-sized buffers - * are handled as "virtual" arrays. The array is still accessed a strip at a - * time, but the memory manager must save the whole array for repeated - * accesses. The intended implementation is that there is a strip buffer in - * memory (as high as is possible given the desired memory limit), plus a - * backing file that holds the rest of the array. - * - * The request_virt_array routines are told the total size of the image and - * the maximum number of rows that will be accessed at once. The in-memory - * buffer must be at least as large as the maxaccess value. - * - * The request routines create control blocks but not the in-memory buffers. - * That is postponed until realize_virt_arrays is called. At that time the - * total amount of space needed is known (approximately, anyway), so free - * memory can be divided up fairly. - * - * The access_virt_array routines are responsible for making a specific strip - * area accessible (after reading or writing the backing file, if necessary). - * Note that the access routines are told whether the caller intends to modify - * the accessed strip; during a read-only pass this saves having to rewrite - * data to disk. The access routines are also responsible for pre-zeroing - * any newly accessed rows, if pre-zeroing was requested. - * - * In current usage, the access requests are usually for nonoverlapping - * strips; that is, successive access start_row numbers differ by exactly - * num_rows = maxaccess. This means we can get good performance with simple - * buffer dump/reload logic, by making the in-memory buffer be a multiple - * of the access height; then there will never be accesses across bufferload - * boundaries. The code will still work with overlapping access requests, - * but it doesn't handle bufferload overlaps very efficiently. - */ - - -METHODDEF(jvirt_sarray_ptr) -request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, - JDIMENSION samplesperrow, JDIMENSION numrows, - JDIMENSION maxaccess) -/* Request a virtual 2-D sample array */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - jvirt_sarray_ptr result; - - /* Only IMAGE-lifetime virtual arrays are currently supported */ - if (pool_id != JPOOL_IMAGE) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ - - /* get control block */ - result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id, - SIZEOF(struct jvirt_sarray_control)); - - result->mem_buffer = NULL; /* marks array not yet realized */ - result->rows_in_array = numrows; - result->samplesperrow = samplesperrow; - result->maxaccess = maxaccess; - result->pre_zero = pre_zero; - result->b_s_open = FALSE; /* no associated backing-store object */ - result->next = mem->virt_sarray_list; /* add to list of virtual arrays */ - mem->virt_sarray_list = result; - - return result; -} - - -METHODDEF(jvirt_barray_ptr) -request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, - JDIMENSION blocksperrow, JDIMENSION numrows, - JDIMENSION maxaccess) -/* Request a virtual 2-D coefficient-block array */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - jvirt_barray_ptr result; - - /* Only IMAGE-lifetime virtual arrays are currently supported */ - if (pool_id != JPOOL_IMAGE) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ - - /* get control block */ - result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id, - SIZEOF(struct jvirt_barray_control)); - - result->mem_buffer = NULL; /* marks array not yet realized */ - result->rows_in_array = numrows; - result->blocksperrow = blocksperrow; - result->maxaccess = maxaccess; - result->pre_zero = pre_zero; - result->b_s_open = FALSE; /* no associated backing-store object */ - result->next = mem->virt_barray_list; /* add to list of virtual arrays */ - mem->virt_barray_list = result; - - return result; -} - - -METHODDEF(void) -realize_virt_arrays (j_common_ptr cinfo) -/* Allocate the in-memory buffers for any unrealized virtual arrays */ -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - long space_per_minheight, maximum_space, avail_mem; - long minheights, max_minheights; - jvirt_sarray_ptr sptr; - jvirt_barray_ptr bptr; - - /* Compute the minimum space needed (maxaccess rows in each buffer) - * and the maximum space needed (full image height in each buffer). - * These may be of use to the system-dependent jpeg_mem_available routine. - */ - space_per_minheight = 0; - maximum_space = 0; - for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { - if (sptr->mem_buffer == NULL) { /* if not realized yet */ - space_per_minheight += (long) sptr->maxaccess * - (long) sptr->samplesperrow * SIZEOF(JSAMPLE); - maximum_space += (long) sptr->rows_in_array * - (long) sptr->samplesperrow * SIZEOF(JSAMPLE); - } - } - for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { - if (bptr->mem_buffer == NULL) { /* if not realized yet */ - space_per_minheight += (long) bptr->maxaccess * - (long) bptr->blocksperrow * SIZEOF(JBLOCK); - maximum_space += (long) bptr->rows_in_array * - (long) bptr->blocksperrow * SIZEOF(JBLOCK); - } - } - - if (space_per_minheight <= 0) - return; /* no unrealized arrays, no work */ - - /* Determine amount of memory to actually use; this is system-dependent. */ - avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space, - mem->total_space_allocated); - - /* If the maximum space needed is available, make all the buffers full - * height; otherwise parcel it out with the same number of minheights - * in each buffer. - */ - if (avail_mem >= maximum_space) - max_minheights = 1000000000L; - else { - max_minheights = avail_mem / space_per_minheight; - /* If there doesn't seem to be enough space, try to get the minimum - * anyway. This allows a "stub" implementation of jpeg_mem_available(). - */ - if (max_minheights <= 0) - max_minheights = 1; - } - - /* Allocate the in-memory buffers and initialize backing store as needed. */ - - for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { - if (sptr->mem_buffer == NULL) { /* if not realized yet */ - minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L; - if (minheights <= max_minheights) { - /* This buffer fits in memory */ - sptr->rows_in_mem = sptr->rows_in_array; - } else { - /* It doesn't fit in memory, create backing store. */ - sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess); - jpeg_open_backing_store(cinfo, & sptr->b_s_info, - (long) sptr->rows_in_array * - (long) sptr->samplesperrow * - (long) SIZEOF(JSAMPLE)); - sptr->b_s_open = TRUE; - } - sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE, - sptr->samplesperrow, sptr->rows_in_mem); - sptr->rowsperchunk = mem->last_rowsperchunk; - sptr->cur_start_row = 0; - sptr->first_undef_row = 0; - sptr->dirty = FALSE; - } - } - - for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { - if (bptr->mem_buffer == NULL) { /* if not realized yet */ - minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L; - if (minheights <= max_minheights) { - /* This buffer fits in memory */ - bptr->rows_in_mem = bptr->rows_in_array; - } else { - /* It doesn't fit in memory, create backing store. */ - bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess); - jpeg_open_backing_store(cinfo, & bptr->b_s_info, - (long) bptr->rows_in_array * - (long) bptr->blocksperrow * - (long) SIZEOF(JBLOCK)); - bptr->b_s_open = TRUE; - } - bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE, - bptr->blocksperrow, bptr->rows_in_mem); - bptr->rowsperchunk = mem->last_rowsperchunk; - bptr->cur_start_row = 0; - bptr->first_undef_row = 0; - bptr->dirty = FALSE; - } - } -} - - -LOCAL(void) -do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing) -/* Do backing store read or write of a virtual sample array */ -{ - long bytesperrow, file_offset, byte_count, rows, thisrow, i; - - bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE); - file_offset = ptr->cur_start_row * bytesperrow; - /* Loop to read or write each allocation chunk in mem_buffer */ - for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { - /* One chunk, but check for short chunk at end of buffer */ - rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); - /* Transfer no more than is currently defined */ - thisrow = (long) ptr->cur_start_row + i; - rows = MIN(rows, (long) ptr->first_undef_row - thisrow); - /* Transfer no more than fits in file */ - rows = MIN(rows, (long) ptr->rows_in_array - thisrow); - if (rows <= 0) /* this chunk might be past end of file! */ - break; - byte_count = rows * bytesperrow; - if (writing) - (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); - else - (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); - file_offset += byte_count; - } -} - - -LOCAL(void) -do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) -/* Do backing store read or write of a virtual coefficient-block array */ -{ - long bytesperrow, file_offset, byte_count, rows, thisrow, i; - - bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK); - file_offset = ptr->cur_start_row * bytesperrow; - /* Loop to read or write each allocation chunk in mem_buffer */ - for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) { - /* One chunk, but check for short chunk at end of buffer */ - rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i); - /* Transfer no more than is currently defined */ - thisrow = (long) ptr->cur_start_row + i; - rows = MIN(rows, (long) ptr->first_undef_row - thisrow); - /* Transfer no more than fits in file */ - rows = MIN(rows, (long) ptr->rows_in_array - thisrow); - if (rows <= 0) /* this chunk might be past end of file! */ - break; - byte_count = rows * bytesperrow; - if (writing) - (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); - else - (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); - file_offset += byte_count; - } -} - - -METHODDEF(JSAMPARRAY) -access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, - JDIMENSION start_row, JDIMENSION num_rows, - boolean writable) -/* Access the part of a virtual sample array starting at start_row */ -/* and extending for num_rows rows. writable is true if */ -/* caller intends to modify the accessed area. */ -{ - JDIMENSION end_row = start_row + num_rows; - JDIMENSION undef_row; - - /* debugging check */ - if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || - ptr->mem_buffer == NULL) - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - - /* Make the desired part of the virtual array accessible */ - if (start_row < ptr->cur_start_row || - end_row > ptr->cur_start_row+ptr->rows_in_mem) { - if (! ptr->b_s_open) - ERREXIT(cinfo, JERR_VIRTUAL_BUG); - /* Flush old buffer contents if necessary */ - if (ptr->dirty) { - do_sarray_io(cinfo, ptr, TRUE); - ptr->dirty = FALSE; - } - /* Decide what part of virtual array to access. - * Algorithm: if target address > current window, assume forward scan, - * load starting at target address. If target address < current window, - * assume backward scan, load so that target area is top of window. - * Note that when switching from forward write to forward read, will have - * start_row = 0, so the limiting case applies and we load from 0 anyway. - */ - if (start_row > ptr->cur_start_row) { - ptr->cur_start_row = start_row; - } else { - /* use long arithmetic here to avoid overflow & unsigned problems */ - long ltemp; - - ltemp = (long) end_row - (long) ptr->rows_in_mem; - if (ltemp < 0) - ltemp = 0; /* don't fall off front end of file */ - ptr->cur_start_row = (JDIMENSION) ltemp; - } - /* Read in the selected part of the array. - * During the initial write pass, we will do no actual read - * because the selected part is all undefined. - */ - do_sarray_io(cinfo, ptr, FALSE); - } - /* Ensure the accessed part of the array is defined; prezero if needed. - * To improve locality of access, we only prezero the part of the array - * that the caller is about to access, not the entire in-memory array. - */ - if (ptr->first_undef_row < end_row) { - if (ptr->first_undef_row < start_row) { - if (writable) /* writer skipped over a section of array */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - undef_row = start_row; /* but reader is allowed to read ahead */ - } else { - undef_row = ptr->first_undef_row; - } - if (writable) - ptr->first_undef_row = end_row; - if (ptr->pre_zero) { - size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE); - undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ - end_row -= ptr->cur_start_row; - while (undef_row < end_row) { - FMEMZERO((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); - undef_row++; - } - } else { - if (! writable) /* reader looking at undefined data */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - } - } - /* Flag the buffer dirty if caller will write in it */ - if (writable) - ptr->dirty = TRUE; - /* Return address of proper part of the buffer */ - return ptr->mem_buffer + (start_row - ptr->cur_start_row); -} - - -METHODDEF(JBLOCKARRAY) -access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, - JDIMENSION start_row, JDIMENSION num_rows, - boolean writable) -/* Access the part of a virtual block array starting at start_row */ -/* and extending for num_rows rows. writable is true if */ -/* caller intends to modify the accessed area. */ -{ - JDIMENSION end_row = start_row + num_rows; - JDIMENSION undef_row; - - /* debugging check */ - if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess || - ptr->mem_buffer == NULL) - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - - /* Make the desired part of the virtual array accessible */ - if (start_row < ptr->cur_start_row || - end_row > ptr->cur_start_row+ptr->rows_in_mem) { - if (! ptr->b_s_open) - ERREXIT(cinfo, JERR_VIRTUAL_BUG); - /* Flush old buffer contents if necessary */ - if (ptr->dirty) { - do_barray_io(cinfo, ptr, TRUE); - ptr->dirty = FALSE; - } - /* Decide what part of virtual array to access. - * Algorithm: if target address > current window, assume forward scan, - * load starting at target address. If target address < current window, - * assume backward scan, load so that target area is top of window. - * Note that when switching from forward write to forward read, will have - * start_row = 0, so the limiting case applies and we load from 0 anyway. - */ - if (start_row > ptr->cur_start_row) { - ptr->cur_start_row = start_row; - } else { - /* use long arithmetic here to avoid overflow & unsigned problems */ - long ltemp; - - ltemp = (long) end_row - (long) ptr->rows_in_mem; - if (ltemp < 0) - ltemp = 0; /* don't fall off front end of file */ - ptr->cur_start_row = (JDIMENSION) ltemp; - } - /* Read in the selected part of the array. - * During the initial write pass, we will do no actual read - * because the selected part is all undefined. - */ - do_barray_io(cinfo, ptr, FALSE); - } - /* Ensure the accessed part of the array is defined; prezero if needed. - * To improve locality of access, we only prezero the part of the array - * that the caller is about to access, not the entire in-memory array. - */ - if (ptr->first_undef_row < end_row) { - if (ptr->first_undef_row < start_row) { - if (writable) /* writer skipped over a section of array */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - undef_row = start_row; /* but reader is allowed to read ahead */ - } else { - undef_row = ptr->first_undef_row; - } - if (writable) - ptr->first_undef_row = end_row; - if (ptr->pre_zero) { - size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK); - undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ - end_row -= ptr->cur_start_row; - while (undef_row < end_row) { - FMEMZERO((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); - undef_row++; - } - } else { - if (! writable) /* reader looking at undefined data */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - } - } - /* Flag the buffer dirty if caller will write in it */ - if (writable) - ptr->dirty = TRUE; - /* Return address of proper part of the buffer */ - return ptr->mem_buffer + (start_row - ptr->cur_start_row); -} - - -/* - * Release all objects belonging to a specified pool. - */ - -METHODDEF(void) -free_pool (j_common_ptr cinfo, int pool_id) -{ - my_mem_ptr mem = (my_mem_ptr) cinfo->mem; - small_pool_ptr shdr_ptr; - large_pool_ptr lhdr_ptr; - size_t space_freed; - - if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ - -#ifdef MEM_STATS - if (cinfo->err->trace_level > 1) - print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */ -#endif - - /* If freeing IMAGE pool, close any virtual arrays first */ - if (pool_id == JPOOL_IMAGE) { - jvirt_sarray_ptr sptr; - jvirt_barray_ptr bptr; - - for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { - if (sptr->b_s_open) { /* there may be no backing store */ - sptr->b_s_open = FALSE; /* prevent recursive close if error */ - (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info); - } - } - mem->virt_sarray_list = NULL; - for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { - if (bptr->b_s_open) { /* there may be no backing store */ - bptr->b_s_open = FALSE; /* prevent recursive close if error */ - (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info); - } - } - mem->virt_barray_list = NULL; - } - - /* Release large objects */ - lhdr_ptr = mem->large_list[pool_id]; - mem->large_list[pool_id] = NULL; - - while (lhdr_ptr != NULL) { - large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next; - space_freed = lhdr_ptr->hdr.bytes_used + - lhdr_ptr->hdr.bytes_left + - SIZEOF(large_pool_hdr); - jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed); - mem->total_space_allocated -= space_freed; - lhdr_ptr = next_lhdr_ptr; - } - - /* Release small objects */ - shdr_ptr = mem->small_list[pool_id]; - mem->small_list[pool_id] = NULL; - - while (shdr_ptr != NULL) { - small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next; - space_freed = shdr_ptr->hdr.bytes_used + - shdr_ptr->hdr.bytes_left + - SIZEOF(small_pool_hdr); - jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed); - mem->total_space_allocated -= space_freed; - shdr_ptr = next_shdr_ptr; - } -} - - -/* - * Close up shop entirely. - * Note that this cannot be called unless cinfo->mem is non-NULL. - */ - -METHODDEF(void) -self_destruct (j_common_ptr cinfo) -{ - int pool; - - /* Close all backing store, release all memory. - * Releasing pools in reverse order might help avoid fragmentation - * with some (brain-damaged) malloc libraries. - */ - for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { - free_pool(cinfo, pool); - } - - /* Release the memory manager control block too. */ - jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr)); - cinfo->mem = NULL; /* ensures I will be called only once */ - - jpeg_mem_term(cinfo); /* system-dependent cleanup */ -} - - -/* - * Memory manager initialization. - * When this is called, only the error manager pointer is valid in cinfo! - */ - -GLOBAL(void) -jinit_memory_mgr (j_common_ptr cinfo) -{ - my_mem_ptr mem; - long max_to_use; - int pool; - size_t test_mac; - - cinfo->mem = NULL; /* for safety if init fails */ - - /* Check for configuration errors. - * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably - * doesn't reflect any real hardware alignment requirement. - * The test is a little tricky: for X>0, X and X-1 have no one-bits - * in common if and only if X is a power of 2, ie has only one one-bit. - * Some compilers may give an "unreachable code" warning here; ignore it. - */ - if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0) - ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE); - /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be - * a multiple of SIZEOF(ALIGN_TYPE). - * Again, an "unreachable code" warning may be ignored here. - * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK. - */ - test_mac = (size_t) MAX_ALLOC_CHUNK; - if ((long) test_mac != MAX_ALLOC_CHUNK || - (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0) - ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK); - - max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */ - - /* Attempt to allocate memory manager's control block */ - mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr)); - - if (mem == NULL) { - jpeg_mem_term(cinfo); /* system-dependent cleanup */ - ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); - } - - /* OK, fill in the method pointers */ - mem->pub.alloc_small = alloc_small; - mem->pub.alloc_large = alloc_large; - mem->pub.alloc_sarray = alloc_sarray; - mem->pub.alloc_barray = alloc_barray; - mem->pub.request_virt_sarray = request_virt_sarray; - mem->pub.request_virt_barray = request_virt_barray; - mem->pub.realize_virt_arrays = realize_virt_arrays; - mem->pub.access_virt_sarray = access_virt_sarray; - mem->pub.access_virt_barray = access_virt_barray; - mem->pub.free_pool = free_pool; - mem->pub.self_destruct = self_destruct; - - /* Make MAX_ALLOC_CHUNK accessible to other modules */ - mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK; - - /* Initialize working state */ - mem->pub.max_memory_to_use = max_to_use; - - for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) { - mem->small_list[pool] = NULL; - mem->large_list[pool] = NULL; - } - mem->virt_sarray_list = NULL; - mem->virt_barray_list = NULL; - - mem->total_space_allocated = SIZEOF(my_memory_mgr); - - /* Declare ourselves open for business */ - cinfo->mem = & mem->pub; - - /* Check for an environment variable JPEGMEM; if found, override the - * default max_memory setting from jpeg_mem_init. Note that the - * surrounding application may again override this value. - * If your system doesn't support getenv(), define NO_GETENV to disable - * this feature. - */ -#ifndef NO_GETENV - { char * memenv; - - if ((memenv = getenv("JPEGMEM")) != NULL) { - char ch = 'x'; - - if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) { - if (ch == 'm' || ch == 'M') - max_to_use *= 1000L; - mem->pub.max_memory_to_use = max_to_use * 1000L; - } - } - } -#endif - -} diff --git a/libraries/jpeg/jmemsys.h b/libraries/jpeg/jmemsys.h deleted file mode 100644 index 6c3c6d348..000000000 --- a/libraries/jpeg/jmemsys.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * jmemsys.h - * - * Copyright (C) 1992-1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This include file defines the interface between the system-independent - * and system-dependent portions of the JPEG memory manager. No other - * modules need include it. (The system-independent portion is jmemmgr.c; - * there are several different versions of the system-dependent portion.) - * - * This file works as-is for the system-dependent memory managers supplied - * in the IJG distribution. You may need to modify it if you write a - * custom memory manager. If system-dependent changes are needed in - * this file, the best method is to #ifdef them based on a configuration - * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR - * and USE_MAC_MEMMGR. - */ - - -/* Short forms of external names for systems with brain-damaged linkers. */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_get_small jGetSmall -#define jpeg_free_small jFreeSmall -#define jpeg_get_large jGetLarge -#define jpeg_free_large jFreeLarge -#define jpeg_mem_available jMemAvail -#define jpeg_open_backing_store jOpenBackStore -#define jpeg_mem_init jMemInit -#define jpeg_mem_term jMemTerm -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - - -/* - * These two functions are used to allocate and release small chunks of - * memory. (Typically the total amount requested through jpeg_get_small is - * no more than 20K or so; this will be requested in chunks of a few K each.) - * Behavior should be the same as for the standard library functions malloc - * and free; in particular, jpeg_get_small must return NULL on failure. - * On most systems, these ARE malloc and free. jpeg_free_small is passed the - * size of the object being freed, just in case it's needed. - * On an 80x86 machine using small-data memory model, these manage near heap. - */ - -EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); -EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object, - size_t sizeofobject)); - -/* - * These two functions are used to allocate and release large chunks of - * memory (up to the total free space designated by jpeg_mem_available). - * The interface is the same as above, except that on an 80x86 machine, - * far pointers are used. On most other machines these are identical to - * the jpeg_get/free_small routines; but we keep them separate anyway, - * in case a different allocation strategy is desirable for large chunks. - */ - -EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo, - size_t sizeofobject)); -EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, - size_t sizeofobject)); - -/* - * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may - * be requested in a single call to jpeg_get_large (and jpeg_get_small for that - * matter, but that case should never come into play). This macro is needed - * to model the 64Kb-segment-size limit of far addressing on 80x86 machines. - * On those machines, we expect that jconfig.h will provide a proper value. - * On machines with 32-bit flat address spaces, any large constant may be used. - * - * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type - * size_t and will be a multiple of sizeof(align_type). - */ - -#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */ -#define MAX_ALLOC_CHUNK 1000000000L -#endif - -/* - * This routine computes the total space still available for allocation by - * jpeg_get_large. If more space than this is needed, backing store will be - * used. NOTE: any memory already allocated must not be counted. - * - * There is a minimum space requirement, corresponding to the minimum - * feasible buffer sizes; jmemmgr.c will request that much space even if - * jpeg_mem_available returns zero. The maximum space needed, enough to hold - * all working storage in memory, is also passed in case it is useful. - * Finally, the total space already allocated is passed. If no better - * method is available, cinfo->mem->max_memory_to_use - already_allocated - * is often a suitable calculation. - * - * It is OK for jpeg_mem_available to underestimate the space available - * (that'll just lead to more backing-store access than is really necessary). - * However, an overestimate will lead to failure. Hence it's wise to subtract - * a slop factor from the true available space. 5% should be enough. - * - * On machines with lots of virtual memory, any large constant may be returned. - * Conversely, zero may be returned to always use the minimum amount of memory. - */ - -EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo, - long min_bytes_needed, - long max_bytes_needed, - long already_allocated)); - - -/* - * This structure holds whatever state is needed to access a single - * backing-store object. The read/write/close method pointers are called - * by jmemmgr.c to manipulate the backing-store object; all other fields - * are private to the system-dependent backing store routines. - */ - -#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ - - -#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ - -typedef unsigned short XMSH; /* type of extended-memory handles */ -typedef unsigned short EMSH; /* type of expanded-memory handles */ - -typedef union { - short file_handle; /* DOS file handle if it's a temp file */ - XMSH xms_handle; /* handle if it's a chunk of XMS */ - EMSH ems_handle; /* handle if it's a chunk of EMS */ -} handle_union; - -#endif /* USE_MSDOS_MEMMGR */ - -#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ -#include -#endif /* USE_MAC_MEMMGR */ - - -typedef struct backing_store_struct * backing_store_ptr; - -typedef struct backing_store_struct { - /* Methods for reading/writing/closing this backing-store object */ - JMETHOD(void, read_backing_store, (j_common_ptr cinfo, - backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count)); - JMETHOD(void, write_backing_store, (j_common_ptr cinfo, - backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count)); - JMETHOD(void, close_backing_store, (j_common_ptr cinfo, - backing_store_ptr info)); - - /* Private fields for system-dependent backing-store management */ -#ifdef USE_MSDOS_MEMMGR - /* For the MS-DOS manager (jmemdos.c), we need: */ - handle_union handle; /* reference to backing-store storage object */ - char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ -#else -#ifdef USE_MAC_MEMMGR - /* For the Mac manager (jmemmac.c), we need: */ - short temp_file; /* file reference number to temp file */ - FSSpec tempSpec; /* the FSSpec for the temp file */ - char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ -#else - /* For a typical implementation with temp files, we need: */ - FILE * temp_file; /* stdio reference to temp file */ - char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ -#endif -#endif -} backing_store_info; - - -/* - * Initial opening of a backing-store object. This must fill in the - * read/write/close pointers in the object. The read/write routines - * may take an error exit if the specified maximum file size is exceeded. - * (If jpeg_mem_available always returns a large value, this routine can - * just take an error exit.) - */ - -EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo, - backing_store_ptr info, - long total_bytes_needed)); - - -/* - * These routines take care of any system-dependent initialization and - * cleanup required. jpeg_mem_init will be called before anything is - * allocated (and, therefore, nothing in cinfo is of use except the error - * manager pointer). It should return a suitable default value for - * max_memory_to_use; this may subsequently be overridden by the surrounding - * application. (Note that max_memory_to_use is only important if - * jpeg_mem_available chooses to consult it ... no one else will.) - * jpeg_mem_term may assume that all requested memory has been freed and that - * all opened backing-store objects have been closed. - */ - -EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo)); -EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo)); diff --git a/libraries/jpeg/jmorecfg.h b/libraries/jpeg/jmorecfg.h deleted file mode 100644 index 679d68bdc..000000000 --- a/libraries/jpeg/jmorecfg.h +++ /dev/null @@ -1,446 +0,0 @@ -/* - * jmorecfg.h - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 1997-2013 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains additional configuration options that customize the - * JPEG software for special applications or support machine-dependent - * optimizations. Most users will not need to touch this file. - */ - - -/* - * Define BITS_IN_JSAMPLE as either - * 8 for 8-bit sample values (the usual setting) - * 9 for 9-bit sample values - * 10 for 10-bit sample values - * 11 for 11-bit sample values - * 12 for 12-bit sample values - * Only 8, 9, 10, 11, and 12 bits sample data precision are supported for - * full-feature DCT processing. Further depths up to 16-bit may be added - * later for the lossless modes of operation. - * Run-time selection and conversion of data precision will be added later - * and are currently not supported, sorry. - * Exception: The transcoding part (jpegtran) supports all settings in a - * single instance, since it operates on the level of DCT coefficients and - * not sample values. The DCT coefficients are of the same type (16 bits) - * in all cases (see below). - */ - -#define BITS_IN_JSAMPLE 8 /* use 8, 9, 10, 11, or 12 */ - - -/* - * Maximum number of components (color channels) allowed in JPEG image. - * To meet the letter of the JPEG spec, set this to 255. However, darn - * few applications need more than 4 channels (maybe 5 for CMYK + alpha - * mask). We recommend 10 as a reasonable compromise; use 4 if you are - * really short on memory. (Each allowed component costs a hundred or so - * bytes of storage, whether actually used in an image or not.) - */ - -#define MAX_COMPONENTS 10 /* maximum number of image components */ - - -/* - * Basic data types. - * You may need to change these if you have a machine with unusual data - * type sizes; for example, "char" not 8 bits, "short" not 16 bits, - * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, - * but it had better be at least 16. - */ - -/* Representation of a single sample (pixel element value). - * We frequently allocate large arrays of these, so it's important to keep - * them small. But if you have memory to burn and access to char or short - * arrays is very slow on your hardware, you might want to change these. - */ - -#if BITS_IN_JSAMPLE == 8 -/* JSAMPLE should be the smallest type that will hold the values 0..255. - * You can use a signed char by having GETJSAMPLE mask it with 0xFF. - */ - -#ifdef HAVE_UNSIGNED_CHAR - -typedef unsigned char JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#else /* not HAVE_UNSIGNED_CHAR */ - -typedef char JSAMPLE; -#ifdef CHAR_IS_UNSIGNED -#define GETJSAMPLE(value) ((int) (value)) -#else -#define GETJSAMPLE(value) ((int) (value) & 0xFF) -#endif /* CHAR_IS_UNSIGNED */ - -#endif /* HAVE_UNSIGNED_CHAR */ - -#define MAXJSAMPLE 255 -#define CENTERJSAMPLE 128 - -#endif /* BITS_IN_JSAMPLE == 8 */ - - -#if BITS_IN_JSAMPLE == 9 -/* JSAMPLE should be the smallest type that will hold the values 0..511. - * On nearly all machines "short" will do nicely. - */ - -typedef short JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#define MAXJSAMPLE 511 -#define CENTERJSAMPLE 256 - -#endif /* BITS_IN_JSAMPLE == 9 */ - - -#if BITS_IN_JSAMPLE == 10 -/* JSAMPLE should be the smallest type that will hold the values 0..1023. - * On nearly all machines "short" will do nicely. - */ - -typedef short JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#define MAXJSAMPLE 1023 -#define CENTERJSAMPLE 512 - -#endif /* BITS_IN_JSAMPLE == 10 */ - - -#if BITS_IN_JSAMPLE == 11 -/* JSAMPLE should be the smallest type that will hold the values 0..2047. - * On nearly all machines "short" will do nicely. - */ - -typedef short JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#define MAXJSAMPLE 2047 -#define CENTERJSAMPLE 1024 - -#endif /* BITS_IN_JSAMPLE == 11 */ - - -#if BITS_IN_JSAMPLE == 12 -/* JSAMPLE should be the smallest type that will hold the values 0..4095. - * On nearly all machines "short" will do nicely. - */ - -typedef short JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#define MAXJSAMPLE 4095 -#define CENTERJSAMPLE 2048 - -#endif /* BITS_IN_JSAMPLE == 12 */ - - -/* Representation of a DCT frequency coefficient. - * This should be a signed value of at least 16 bits; "short" is usually OK. - * Again, we allocate large arrays of these, but you can change to int - * if you have memory to burn and "short" is really slow. - */ - -typedef short JCOEF; - - -/* Compressed datastreams are represented as arrays of JOCTET. - * These must be EXACTLY 8 bits wide, at least once they are written to - * external storage. Note that when using the stdio data source/destination - * managers, this is also the data type passed to fread/fwrite. - */ - -#ifdef HAVE_UNSIGNED_CHAR - -typedef unsigned char JOCTET; -#define GETJOCTET(value) (value) - -#else /* not HAVE_UNSIGNED_CHAR */ - -typedef char JOCTET; -#ifdef CHAR_IS_UNSIGNED -#define GETJOCTET(value) (value) -#else -#define GETJOCTET(value) ((value) & 0xFF) -#endif /* CHAR_IS_UNSIGNED */ - -#endif /* HAVE_UNSIGNED_CHAR */ - - -/* These typedefs are used for various table entries and so forth. - * They must be at least as wide as specified; but making them too big - * won't cost a huge amount of memory, so we don't provide special - * extraction code like we did for JSAMPLE. (In other words, these - * typedefs live at a different point on the speed/space tradeoff curve.) - */ - -/* UINT8 must hold at least the values 0..255. */ - -#ifdef HAVE_UNSIGNED_CHAR -typedef unsigned char UINT8; -#else /* not HAVE_UNSIGNED_CHAR */ -#ifdef CHAR_IS_UNSIGNED -typedef char UINT8; -#else /* not CHAR_IS_UNSIGNED */ -typedef short UINT8; -#endif /* CHAR_IS_UNSIGNED */ -#endif /* HAVE_UNSIGNED_CHAR */ - -/* UINT16 must hold at least the values 0..65535. */ - -#ifdef HAVE_UNSIGNED_SHORT -typedef unsigned short UINT16; -#else /* not HAVE_UNSIGNED_SHORT */ -typedef unsigned int UINT16; -#endif /* HAVE_UNSIGNED_SHORT */ - -/* INT16 must hold at least the values -32768..32767. */ - -#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ -typedef short INT16; -#endif - -/* INT32 must hold at least signed 32-bit values. */ - -#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ -#ifndef _BASETSD_H_ /* Microsoft defines it in basetsd.h */ -#ifndef _BASETSD_H /* MinGW is slightly different */ -#ifndef QGLOBAL_H /* Qt defines it in qglobal.h */ -typedef long INT32; -#endif -#endif -#endif -#endif - -/* Datatype used for image dimensions. The JPEG standard only supports - * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore - * "unsigned int" is sufficient on all machines. However, if you need to - * handle larger images and you don't mind deviating from the spec, you - * can change this datatype. - */ - -typedef unsigned int JDIMENSION; - -#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ - - -/* These macros are used in all function definitions and extern declarations. - * You could modify them if you need to change function linkage conventions; - * in particular, you'll need to do that to make the library a Windows DLL. - * Another application is to make all functions global for use with debuggers - * or code profilers that require it. - */ - -/* a function called through method pointers: */ -#define METHODDEF(type) static type -/* a function used only in its module: */ -#define LOCAL(type) static type -/* a function referenced thru EXTERNs: */ -#define GLOBAL(type) type -/* a reference to a GLOBAL function: */ -#define EXTERN(type) extern type - - -/* This macro is used to declare a "method", that is, a function pointer. - * We want to supply prototype parameters if the compiler can cope. - * Note that the arglist parameter must be parenthesized! - * Again, you can customize this if you need special linkage keywords. - */ - -#ifdef HAVE_PROTOTYPES -#define JMETHOD(type,methodname,arglist) type (*methodname) arglist -#else -#define JMETHOD(type,methodname,arglist) type (*methodname) () -#endif - - -/* The noreturn type identifier is used to declare functions - * which cannot return. - * Compilers can thus create more optimized code and perform - * better checks for warnings and errors. - * Static analyzer tools can make improved inferences about - * execution paths and are prevented from giving false alerts. - * - * Unfortunately, the proposed specifications of corresponding - * extensions in the Dec 2011 ISO C standard revision (C11), - * GCC, MSVC, etc. are not viable. - * Thus we introduce a user defined type to declare noreturn - * functions at least for clarity. A proper compiler would - * have a suitable noreturn type to match in place of void. - */ - -#ifndef HAVE_NORETURN_T -typedef void noreturn_t; -#endif - - -/* Here is the pseudo-keyword for declaring pointers that must be "far" - * on 80x86 machines. Most of the specialized coding for 80x86 is handled - * by just saying "FAR *" where such a pointer is needed. In a few places - * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. - */ - -#ifndef FAR -#ifdef NEED_FAR_POINTERS -#define FAR far -#else -#define FAR -#endif -#endif - - -/* - * On a few systems, type boolean and/or its values FALSE, TRUE may appear - * in standard header files. Or you may have conflicts with application- - * specific header files that you want to include together with these files. - * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. - */ - -#ifndef HAVE_BOOLEAN -#if defined FALSE || defined TRUE || defined QGLOBAL_H -/* Qt3 defines FALSE and TRUE as "const" variables in qglobal.h */ -typedef int boolean; -#ifndef FALSE /* in case these macros already exist */ -#define FALSE 0 /* values of boolean */ -#endif -#ifndef TRUE -#define TRUE 1 -#endif -#else -typedef enum { FALSE = 0, TRUE = 1 } boolean; -#endif -#endif - - -/* - * The remaining options affect code selection within the JPEG library, - * but they don't need to be visible to most applications using the library. - * To minimize application namespace pollution, the symbols won't be - * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. - */ - -#ifdef JPEG_INTERNALS -#define JPEG_INTERNAL_OPTIONS -#endif - -#ifdef JPEG_INTERNAL_OPTIONS - - -/* - * These defines indicate whether to include various optional functions. - * Undefining some of these symbols will produce a smaller but less capable - * library. Note that you can leave certain source files out of the - * compilation/linking process if you've #undef'd the corresponding symbols. - * (You may HAVE to do that if your compiler doesn't like null source files.) - */ - -/* Capability options common to encoder and decoder: */ - -#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ -#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ -#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ - -/* Encoder capability options: */ - -#define C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ -#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define DCT_SCALING_SUPPORTED /* Input rescaling via DCT? (Requires DCT_ISLOW)*/ -#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ -/* Note: if you selected more than 8-bit data precision, it is dangerous to - * turn off ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only - * good for 8-bit precision, so arithmetic coding is recommended for higher - * precision. The Huffman encoder normally uses entropy optimization to - * compute usable tables for higher precision. Otherwise, you'll have to - * supply different default Huffman tables. - * The exact same statements apply for progressive JPEG: the default tables - * don't work for progressive mode. (This may get fixed, however.) - */ -#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ - -/* Decoder capability options: */ - -#define D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ -#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? (Requires DCT_ISLOW)*/ -#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ -#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ -#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ -#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ -#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ -#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ - -/* more capability options later, no doubt */ - - -/* - * Ordering of RGB data in scanlines passed to or from the application. - * If your application wants to deal with data in the order B,G,R, just - * change these macros. You can also deal with formats such as R,G,B,X - * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing - * the offsets will also change the order in which colormap data is organized. - * RESTRICTIONS: - * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. - * 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE - * is not 3 (they don't understand about dummy color components!). So you - * can't use color quantization if you change that value. - */ - -#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ -#define RGB_GREEN 1 /* Offset of Green */ -#define RGB_BLUE 2 /* Offset of Blue */ -#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ - - -/* Definitions for speed-related optimizations. */ - - -/* If your compiler supports inline functions, define INLINE - * as the inline keyword; otherwise define it as empty. - */ - -#ifndef INLINE -#ifdef __GNUC__ /* for instance, GNU C knows about inline */ -#define INLINE __inline__ -#endif -#ifndef INLINE -#define INLINE /* default is to define it as empty */ -#endif -#endif - - -/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying - * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER - * as short on such a machine. MULTIPLIER must be at least 16 bits wide. - */ - -#ifndef MULTIPLIER -#define MULTIPLIER int /* type for fastest integer multiply */ -#endif - - -/* FAST_FLOAT should be either float or double, whichever is done faster - * by your compiler. (Note that this type is only used in the floating point - * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) - * Typically, float is faster in ANSI C compilers, while double is faster in - * pre-ANSI compilers (because they insist on converting to double anyway). - * The code below therefore chooses float if we have ANSI-style prototypes. - */ - -#ifndef FAST_FLOAT -#ifdef HAVE_PROTOTYPES -#define FAST_FLOAT float -#else -#define FAST_FLOAT double -#endif -#endif - -#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/libraries/jpeg/jpegint.h b/libraries/jpeg/jpegint.h deleted file mode 100644 index e312e1af9..000000000 --- a/libraries/jpeg/jpegint.h +++ /dev/null @@ -1,439 +0,0 @@ -/* - * jpegint.h - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 1997-2017 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file provides common declarations for the various JPEG modules. - * These declarations are considered internal to the JPEG library; most - * applications using the library shouldn't need to include this file. - */ - - -/* Declarations for both compression & decompression */ - -typedef enum { /* Operating modes for buffer controllers */ - JBUF_PASS_THRU, /* Plain stripwise operation */ - /* Remaining modes require a full-image buffer to have been created */ - JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ - JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ - JBUF_SAVE_AND_PASS /* Run both subobjects, save output */ -} J_BUF_MODE; - -/* Values of global_state field (jdapi.c has some dependencies on ordering!) */ -#define CSTATE_START 100 /* after create_compress */ -#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */ -#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */ -#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */ -#define DSTATE_START 200 /* after create_decompress */ -#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ -#define DSTATE_READY 202 /* found SOS, ready for start_decompress */ -#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/ -#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ -#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ -#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ -#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */ -#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */ -#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ -#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ - - -/* Declarations for compression modules */ - -/* Master control module */ -struct jpeg_comp_master { - JMETHOD(void, prepare_for_pass, (j_compress_ptr cinfo)); - JMETHOD(void, pass_startup, (j_compress_ptr cinfo)); - JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); - - /* State variables made visible to other modules */ - boolean call_pass_startup; /* True if pass_startup must be called */ - boolean is_last_pass; /* True during last pass */ -}; - -/* Main buffer control (downsampled-data buffer) */ -struct jpeg_c_main_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, process_data, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail)); -}; - -/* Compression preprocessing (downsampling input buffer control) */ -struct jpeg_c_prep_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, pre_process_data, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, - JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail, - JSAMPIMAGE output_buf, - JDIMENSION *out_row_group_ctr, - JDIMENSION out_row_groups_avail)); -}; - -/* Coefficient buffer control */ -struct jpeg_c_coef_controller { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, - JSAMPIMAGE input_buf)); -}; - -/* Colorspace conversion */ -struct jpeg_color_converter { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - JMETHOD(void, color_convert, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPIMAGE output_buf, - JDIMENSION output_row, int num_rows)); -}; - -/* Downsampling */ -struct jpeg_downsampler { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - JMETHOD(void, downsample, (j_compress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_index, - JSAMPIMAGE output_buf, - JDIMENSION out_row_group_index)); - - boolean need_context_rows; /* TRUE if need rows above & below */ -}; - -/* Forward DCT (also controls coefficient quantization) */ -typedef JMETHOD(void, forward_DCT_ptr, - (j_compress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY sample_data, JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, - JDIMENSION num_blocks)); - -struct jpeg_forward_dct { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - /* It is useful to allow each component to have a separate FDCT method. */ - forward_DCT_ptr forward_DCT[MAX_COMPONENTS]; -}; - -/* Entropy encoding */ -struct jpeg_entropy_encoder { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); - JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); - JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); -}; - -/* Marker writing */ -struct jpeg_marker_writer { - JMETHOD(void, write_file_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_frame_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_scan_header, (j_compress_ptr cinfo)); - JMETHOD(void, write_file_trailer, (j_compress_ptr cinfo)); - JMETHOD(void, write_tables_only, (j_compress_ptr cinfo)); - /* These routines are exported to allow insertion of extra markers */ - /* Probably only COM and APPn markers should be written this way */ - JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker, - unsigned int datalen)); - JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val)); -}; - - -/* Declarations for decompression modules */ - -/* Master control module */ -struct jpeg_decomp_master { - JMETHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); - - /* State variables made visible to other modules */ - boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ -}; - -/* Input control module */ -struct jpeg_input_controller { - JMETHOD(int, consume_input, (j_decompress_ptr cinfo)); - JMETHOD(void, reset_input_controller, (j_decompress_ptr cinfo)); - JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); - - /* State variables made visible to other modules */ - boolean has_multiple_scans; /* True if file has multiple scans */ - boolean eoi_reached; /* True when EOI has been consumed */ -}; - -/* Main buffer control (downsampled-data buffer) */ -struct jpeg_d_main_controller { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, process_data, (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); -}; - -/* Coefficient buffer control */ -struct jpeg_d_coef_controller { - JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); - JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); - JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); - JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, - JSAMPIMAGE output_buf)); - /* Pointer to array of coefficient virtual arrays, or NULL if none */ - jvirt_barray_ptr *coef_arrays; -}; - -/* Decompression postprocessing (color quantization buffer control) */ -struct jpeg_d_post_controller { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); - JMETHOD(void, post_process_data, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); -}; - -/* Marker reading & parsing */ -struct jpeg_marker_reader { - JMETHOD(void, reset_marker_reader, (j_decompress_ptr cinfo)); - /* Read markers until SOS or EOI. - * Returns same codes as are defined for jpeg_consume_input: - * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI. - */ - JMETHOD(int, read_markers, (j_decompress_ptr cinfo)); - /* Read a restart marker --- exported for use by entropy decoder only */ - jpeg_marker_parser_method read_restart_marker; - - /* State of marker reader --- nominally internal, but applications - * supplying COM or APPn handlers might like to know the state. - */ - boolean saw_SOI; /* found SOI? */ - boolean saw_SOF; /* found SOF? */ - int next_restart_num; /* next restart number expected (0-7) */ - unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ -}; - -/* Entropy decoding */ -struct jpeg_entropy_decoder { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)); - JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); -}; - -/* Inverse DCT (also performs dequantization) */ -typedef JMETHOD(void, inverse_DCT_method_ptr, - (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col)); - -struct jpeg_inverse_dct { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - /* It is useful to allow each component to have a separate IDCT method. */ - inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; -}; - -/* Upsampling (note that upsampler must also call color converter) */ -struct jpeg_upsampler { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, upsample, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); - - boolean need_context_rows; /* TRUE if need rows above & below */ -}; - -/* Colorspace conversion */ -struct jpeg_color_deconverter { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, color_convert, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows)); -}; - -/* Color quantization or color precision reduction */ -struct jpeg_color_quantizer { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); - JMETHOD(void, color_quantize, (j_decompress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPARRAY output_buf, - int num_rows)); - JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); - JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); -}; - - -/* Definition of range extension bits for decompression processes. - * See the comments with prepare_range_limit_table (in jdmaster.c) - * for more info. - * The recommended default value for normal applications is 2. - * Applications with special requirements may use a different value. - * For example, Ghostscript wants to use 3 for proper handling of - * wacky images with oversize coefficient values. - */ - -#define RANGE_BITS 2 -#define RANGE_CENTER (CENTERJSAMPLE << RANGE_BITS) - - -/* Miscellaneous useful macros */ - -#undef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#undef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) - - -/* We assume that right shift corresponds to signed division by 2 with - * rounding towards minus infinity. This is correct for typical "arithmetic - * shift" instructions that shift in copies of the sign bit. But some - * C compilers implement >> with an unsigned shift. For these machines you - * must define RIGHT_SHIFT_IS_UNSIGNED. - * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity. - * It is only applied with constant shift counts. SHIFT_TEMPS must be - * included in the variables of any routine using RIGHT_SHIFT. - */ - -#ifdef RIGHT_SHIFT_IS_UNSIGNED -#define SHIFT_TEMPS INT32 shift_temp; -#define RIGHT_SHIFT(x,shft) \ - ((shift_temp = (x)) < 0 ? \ - (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ - (shift_temp >> (shft))) -#else -#define SHIFT_TEMPS -#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) -#endif - - -/* Short forms of external names for systems with brain-damaged linkers. */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jinit_compress_master jICompress -#define jinit_c_master_control jICMaster -#define jinit_c_main_controller jICMainC -#define jinit_c_prep_controller jICPrepC -#define jinit_c_coef_controller jICCoefC -#define jinit_color_converter jICColor -#define jinit_downsampler jIDownsampler -#define jinit_forward_dct jIFDCT -#define jinit_huff_encoder jIHEncoder -#define jinit_arith_encoder jIAEncoder -#define jinit_marker_writer jIMWriter -#define jinit_master_decompress jIDMaster -#define jinit_d_main_controller jIDMainC -#define jinit_d_coef_controller jIDCoefC -#define jinit_d_post_controller jIDPostC -#define jinit_input_controller jIInCtlr -#define jinit_marker_reader jIMReader -#define jinit_huff_decoder jIHDecoder -#define jinit_arith_decoder jIADecoder -#define jinit_inverse_dct jIIDCT -#define jinit_upsampler jIUpsampler -#define jinit_color_deconverter jIDColor -#define jinit_1pass_quantizer jI1Quant -#define jinit_2pass_quantizer jI2Quant -#define jinit_merged_upsampler jIMUpsampler -#define jinit_memory_mgr jIMemMgr -#define jdiv_round_up jDivRound -#define jround_up jRound -#define jzero_far jZeroFar -#define jcopy_sample_rows jCopySamples -#define jcopy_block_row jCopyBlocks -#define jpeg_zigzag_order jZIGTable -#define jpeg_natural_order jZAGTable -#define jpeg_natural_order7 jZAG7Table -#define jpeg_natural_order6 jZAG6Table -#define jpeg_natural_order5 jZAG5Table -#define jpeg_natural_order4 jZAG4Table -#define jpeg_natural_order3 jZAG3Table -#define jpeg_natural_order2 jZAG2Table -#define jpeg_aritab jAriTab -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - - -/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays - * and coefficient-block arrays. This won't work on 80x86 because the arrays - * are FAR and we're assuming a small-pointer memory model. However, some - * DOS compilers provide far-pointer versions of memcpy() and memset() even - * in the small-model libraries. These will be used if USE_FMEM is defined. - * Otherwise, the routines in jutils.c do it the hard way. - */ - -#ifndef NEED_FAR_POINTERS /* normal case, same as regular macro */ -#define FMEMZERO(target,size) MEMZERO(target,size) -#else /* 80x86 case */ -#ifdef USE_FMEM -#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) -#else -EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero)); -#define FMEMZERO(target,size) jzero_far(target, size) -#endif -#endif - - -/* Compression module initialization routines */ -EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo, - boolean transcode_only)); -EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_arith_encoder JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo)); -/* Decompression module initialization routines */ -EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_arith_decoder JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo)); -/* Memory manager initialization */ -EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo)); - -/* Utility routines in jutils.c */ -EXTERN(long) jdiv_round_up JPP((long a, long b)); -EXTERN(long) jround_up JPP((long a, long b)); -EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, - int num_rows, JDIMENSION num_cols)); -EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, - JDIMENSION num_blocks)); -/* Constant tables in jutils.c */ -#if 0 /* This table is not actually needed in v6a */ -extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ -#endif -extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ -extern const int jpeg_natural_order7[]; /* zz to natural order for 7x7 block */ -extern const int jpeg_natural_order6[]; /* zz to natural order for 6x6 block */ -extern const int jpeg_natural_order5[]; /* zz to natural order for 5x5 block */ -extern const int jpeg_natural_order4[]; /* zz to natural order for 4x4 block */ -extern const int jpeg_natural_order3[]; /* zz to natural order for 3x3 block */ -extern const int jpeg_natural_order2[]; /* zz to natural order for 2x2 block */ - -/* Arithmetic coding probability estimation tables in jaricom.c */ -extern const INT32 jpeg_aritab[]; - -/* Suppress undefined-structure complaints if necessary. */ - -#ifdef INCOMPLETE_TYPES_BROKEN -#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ -struct jvirt_sarray_control { long dummy; }; -struct jvirt_barray_control { long dummy; }; -#endif -#endif /* INCOMPLETE_TYPES_BROKEN */ diff --git a/libraries/jpeg/jpeglib.h b/libraries/jpeg/jpeglib.h deleted file mode 100644 index 4bd985316..000000000 --- a/libraries/jpeg/jpeglib.h +++ /dev/null @@ -1,1180 +0,0 @@ -/* - * jpeglib.h - * - * Copyright (C) 1991-1998, Thomas G. Lane. - * Modified 2002-2017 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file defines the application interface for the JPEG library. - * Most applications using the library need only include this file, - * and perhaps jerror.h if they want to know the exact error codes. - */ - -#ifndef JPEGLIB_H -#define JPEGLIB_H - -/* - * First we include the configuration files that record how this - * installation of the JPEG library is set up. jconfig.h can be - * generated automatically for many systems. jmorecfg.h contains - * manual configuration options that most people need not worry about. - */ - -#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ -#include "jconfig.h" /* widely used configuration options */ -#endif -#include "jmorecfg.h" /* seldom changed options */ - - -#ifdef __cplusplus -#ifndef DONT_USE_EXTERN_C -extern "C" { -#endif -#endif - -/* Version IDs for the JPEG library. - * Might be useful for tests like "#if JPEG_LIB_VERSION >= 90". - */ - -#define JPEG_LIB_VERSION 90 /* Compatibility version 9.0 */ -#define JPEG_LIB_VERSION_MAJOR 9 -#define JPEG_LIB_VERSION_MINOR 3 - - -/* Various constants determining the sizes of things. - * All of these are specified by the JPEG standard, - * so don't change them if you want to be compatible. - */ - -#define DCTSIZE 8 /* The basic DCT block is 8x8 coefficients */ -#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ -#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ -#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ -#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ -#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ -#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ -/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; - * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. - * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU - * to handle it. We even let you do this from the jconfig.h file. However, - * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe - * sometimes emits noncompliant files doesn't mean you should too. - */ -#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ -#ifndef D_MAX_BLOCKS_IN_MCU -#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ -#endif - - -/* Data structures for images (arrays of samples and of DCT coefficients). - * On 80x86 machines, the image arrays are too big for near pointers, - * but the pointer arrays can fit in near memory. - */ - -typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ -typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ -typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ - -typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ -typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ -typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ -typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ - -typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ - - -/* Types for JPEG compression parameters and working tables. */ - - -/* DCT coefficient quantization tables. */ - -typedef struct { - /* This array gives the coefficient quantizers in natural array order - * (not the zigzag order in which they are stored in a JPEG DQT marker). - * CAUTION: IJG versions prior to v6a kept this array in zigzag order. - */ - UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ - /* This field is used only during compression. It's initialized FALSE when - * the table is created, and set TRUE when it's been output to the file. - * You could suppress output of a table by setting this to TRUE. - * (See jpeg_suppress_tables for an example.) - */ - boolean sent_table; /* TRUE when table has been output */ -} JQUANT_TBL; - - -/* Huffman coding tables. */ - -typedef struct { - /* These two fields directly represent the contents of a JPEG DHT marker */ - UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ - /* length k bits; bits[0] is unused */ - UINT8 huffval[256]; /* The symbols, in order of incr code length */ - /* This field is used only during compression. It's initialized FALSE when - * the table is created, and set TRUE when it's been output to the file. - * You could suppress output of a table by setting this to TRUE. - * (See jpeg_suppress_tables for an example.) - */ - boolean sent_table; /* TRUE when table has been output */ -} JHUFF_TBL; - - -/* Basic info about one component (color channel). */ - -typedef struct { - /* These values are fixed over the whole image. */ - /* For compression, they must be supplied by parameter setup; */ - /* for decompression, they are read from the SOF marker. */ - int component_id; /* identifier for this component (0..255) */ - int component_index; /* its index in SOF or cinfo->comp_info[] */ - int h_samp_factor; /* horizontal sampling factor (1..4) */ - int v_samp_factor; /* vertical sampling factor (1..4) */ - int quant_tbl_no; /* quantization table selector (0..3) */ - /* These values may vary between scans. */ - /* For compression, they must be supplied by parameter setup; */ - /* for decompression, they are read from the SOS marker. */ - /* The decompressor output side may not use these variables. */ - int dc_tbl_no; /* DC entropy table selector (0..3) */ - int ac_tbl_no; /* AC entropy table selector (0..3) */ - - /* Remaining fields should be treated as private by applications. */ - - /* These values are computed during compression or decompression startup: */ - /* Component's size in DCT blocks. - * Any dummy blocks added to complete an MCU are not counted; therefore - * these values do not depend on whether a scan is interleaved or not. - */ - JDIMENSION width_in_blocks; - JDIMENSION height_in_blocks; - /* Size of a DCT block in samples, - * reflecting any scaling we choose to apply during the DCT step. - * Values from 1 to 16 are supported. - * Note that different components may receive different DCT scalings. - */ - int DCT_h_scaled_size; - int DCT_v_scaled_size; - /* The downsampled dimensions are the component's actual, unpadded number - * of samples at the main buffer (preprocessing/compression interface); - * DCT scaling is included, so - * downsampled_width = - * ceil(image_width * Hi/Hmax * DCT_h_scaled_size/block_size) - * and similarly for height. - */ - JDIMENSION downsampled_width; /* actual width in samples */ - JDIMENSION downsampled_height; /* actual height in samples */ - /* For decompression, in cases where some of the components will be - * ignored (eg grayscale output from YCbCr image), we can skip most - * computations for the unused components. - * For compression, some of the components will need further quantization - * scale by factor of 2 after DCT (eg BG_YCC output from normal RGB input). - * The field is first set TRUE for decompression, FALSE for compression - * in initial_setup, and then adapted in color conversion setup. - */ - boolean component_needed; - - /* These values are computed before starting a scan of the component. */ - /* The decompressor output side may not use these variables. */ - int MCU_width; /* number of blocks per MCU, horizontally */ - int MCU_height; /* number of blocks per MCU, vertically */ - int MCU_blocks; /* MCU_width * MCU_height */ - int MCU_sample_width; /* MCU width in samples: MCU_width * DCT_h_scaled_size */ - int last_col_width; /* # of non-dummy blocks across in last MCU */ - int last_row_height; /* # of non-dummy blocks down in last MCU */ - - /* Saved quantization table for component; NULL if none yet saved. - * See jdinput.c comments about the need for this information. - * This field is currently used only for decompression. - */ - JQUANT_TBL * quant_table; - - /* Private per-component storage for DCT or IDCT subsystem. */ - void * dct_table; -} jpeg_component_info; - - -/* The script for encoding a multiple-scan file is an array of these: */ - -typedef struct { - int comps_in_scan; /* number of components encoded in this scan */ - int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ - int Ss, Se; /* progressive JPEG spectral selection parms */ - int Ah, Al; /* progressive JPEG successive approx. parms */ -} jpeg_scan_info; - -/* The decompressor can save APPn and COM markers in a list of these: */ - -typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; - -struct jpeg_marker_struct { - jpeg_saved_marker_ptr next; /* next in list, or NULL */ - UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ - unsigned int original_length; /* # bytes of data in the file */ - unsigned int data_length; /* # bytes of data saved at data[] */ - JOCTET FAR * data; /* the data contained in the marker */ - /* the marker length word is not counted in data_length or original_length */ -}; - -/* Known color spaces. */ - -typedef enum { - JCS_UNKNOWN, /* error/unspecified */ - JCS_GRAYSCALE, /* monochrome */ - JCS_RGB, /* red/green/blue, standard RGB (sRGB) */ - JCS_YCbCr, /* Y/Cb/Cr (also known as YUV), standard YCC */ - JCS_CMYK, /* C/M/Y/K */ - JCS_YCCK, /* Y/Cb/Cr/K */ - JCS_BG_RGB, /* big gamut red/green/blue, bg-sRGB */ - JCS_BG_YCC /* big gamut Y/Cb/Cr, bg-sYCC */ -} J_COLOR_SPACE; - -/* Supported color transforms. */ - -typedef enum { - JCT_NONE = 0, - JCT_SUBTRACT_GREEN = 1 -} J_COLOR_TRANSFORM; - -/* DCT/IDCT algorithm options. */ - -typedef enum { - JDCT_ISLOW, /* slow but accurate integer algorithm */ - JDCT_IFAST, /* faster, less accurate integer method */ - JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ -} J_DCT_METHOD; - -#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ -#define JDCT_DEFAULT JDCT_ISLOW -#endif -#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ -#define JDCT_FASTEST JDCT_IFAST -#endif - -/* Dithering options for decompression. */ - -typedef enum { - JDITHER_NONE, /* no dithering */ - JDITHER_ORDERED, /* simple ordered dither */ - JDITHER_FS /* Floyd-Steinberg error diffusion dither */ -} J_DITHER_MODE; - - -/* Common fields between JPEG compression and decompression master structs. */ - -#define jpeg_common_fields \ - struct jpeg_error_mgr * err; /* Error handler module */\ - struct jpeg_memory_mgr * mem; /* Memory manager module */\ - struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ - void * client_data; /* Available for use by application */\ - boolean is_decompressor; /* So common code can tell which is which */\ - int global_state /* For checking call sequence validity */ - -/* Routines that are to be used by both halves of the library are declared - * to receive a pointer to this structure. There are no actual instances of - * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. - */ -struct jpeg_common_struct { - jpeg_common_fields; /* Fields common to both master struct types */ - /* Additional fields follow in an actual jpeg_compress_struct or - * jpeg_decompress_struct. All three structs must agree on these - * initial fields! (This would be a lot cleaner in C++.) - */ -}; - -typedef struct jpeg_common_struct * j_common_ptr; -typedef struct jpeg_compress_struct * j_compress_ptr; -typedef struct jpeg_decompress_struct * j_decompress_ptr; - - -/* Master record for a compression instance */ - -struct jpeg_compress_struct { - jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ - - /* Destination for compressed data */ - struct jpeg_destination_mgr * dest; - - /* Description of source image --- these fields must be filled in by - * outer application before starting compression. in_color_space must - * be correct before you can even call jpeg_set_defaults(). - */ - - JDIMENSION image_width; /* input image width */ - JDIMENSION image_height; /* input image height */ - int input_components; /* # of color components in input image */ - J_COLOR_SPACE in_color_space; /* colorspace of input image */ - - double input_gamma; /* image gamma of input image */ - - /* Compression parameters --- these fields must be set before calling - * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to - * initialize everything to reasonable defaults, then changing anything - * the application specifically wants to change. That way you won't get - * burnt when new parameters are added. Also note that there are several - * helper routines to simplify changing parameters. - */ - - unsigned int scale_num, scale_denom; /* fraction by which to scale image */ - - JDIMENSION jpeg_width; /* scaled JPEG image width */ - JDIMENSION jpeg_height; /* scaled JPEG image height */ - /* Dimensions of actual JPEG image that will be written to file, - * derived from input dimensions by scaling factors above. - * These fields are computed by jpeg_start_compress(). - * You can also use jpeg_calc_jpeg_dimensions() to determine these values - * in advance of calling jpeg_start_compress(). - */ - - int data_precision; /* bits of precision in image data */ - - int num_components; /* # of color components in JPEG image */ - J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ - - jpeg_component_info * comp_info; - /* comp_info[i] describes component that appears i'th in SOF */ - - JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; - int q_scale_factor[NUM_QUANT_TBLS]; - /* ptrs to coefficient quantization tables, or NULL if not defined, - * and corresponding scale factors (percentage, initialized 100). - */ - - JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; - JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; - /* ptrs to Huffman coding tables, or NULL if not defined */ - - UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ - UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ - UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ - - int num_scans; /* # of entries in scan_info array */ - const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ - /* The default value of scan_info is NULL, which causes a single-scan - * sequential JPEG file to be emitted. To create a multi-scan file, - * set num_scans and scan_info to point to an array of scan definitions. - */ - - boolean raw_data_in; /* TRUE=caller supplies downsampled data */ - boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ - boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ - boolean CCIR601_sampling; /* TRUE=first samples are cosited */ - boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */ - int smoothing_factor; /* 1..100, or 0 for no input smoothing */ - J_DCT_METHOD dct_method; /* DCT algorithm selector */ - - /* The restart interval can be specified in absolute MCUs by setting - * restart_interval, or in MCU rows by setting restart_in_rows - * (in which case the correct restart_interval will be figured - * for each scan). - */ - unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ - int restart_in_rows; /* if > 0, MCU rows per restart interval */ - - /* Parameters controlling emission of special markers. */ - - boolean write_JFIF_header; /* should a JFIF marker be written? */ - UINT8 JFIF_major_version; /* What to write for the JFIF version number */ - UINT8 JFIF_minor_version; - /* These three values are not used by the JPEG code, merely copied */ - /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ - /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ - /* ratio is defined by X_density/Y_density even when density_unit=0. */ - UINT8 density_unit; /* JFIF code for pixel size units */ - UINT16 X_density; /* Horizontal pixel density */ - UINT16 Y_density; /* Vertical pixel density */ - boolean write_Adobe_marker; /* should an Adobe marker be written? */ - - J_COLOR_TRANSFORM color_transform; - /* Color transform identifier, writes LSE marker if nonzero */ - - /* State variable: index of next scanline to be written to - * jpeg_write_scanlines(). Application may use this to control its - * processing loop, e.g., "while (next_scanline < image_height)". - */ - - JDIMENSION next_scanline; /* 0 .. image_height-1 */ - - /* Remaining fields are known throughout compressor, but generally - * should not be touched by a surrounding application. - */ - - /* - * These fields are computed during compression startup - */ - boolean progressive_mode; /* TRUE if scan script uses progressive mode */ - int max_h_samp_factor; /* largest h_samp_factor */ - int max_v_samp_factor; /* largest v_samp_factor */ - - int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ - int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ - - JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ - /* The coefficient controller receives data in units of MCU rows as defined - * for fully interleaved scans (whether the JPEG file is interleaved or not). - * There are v_samp_factor * DCT_v_scaled_size sample rows of each component - * in an "iMCU" (interleaved MCU) row. - */ - - /* - * These fields are valid during any one scan. - * They describe the components and MCUs actually appearing in the scan. - */ - int comps_in_scan; /* # of JPEG components in this scan */ - jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; - /* *cur_comp_info[i] describes component that appears i'th in SOS */ - - JDIMENSION MCUs_per_row; /* # of MCUs across the image */ - JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ - - int blocks_in_MCU; /* # of DCT blocks per MCU */ - int MCU_membership[C_MAX_BLOCKS_IN_MCU]; - /* MCU_membership[i] is index in cur_comp_info of component owning */ - /* i'th block in an MCU */ - - int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ - - int block_size; /* the basic DCT block size: 1..16 */ - const int * natural_order; /* natural-order position array */ - int lim_Se; /* min( Se, DCTSIZE2-1 ) */ - - /* - * Links to compression subobjects (methods and private variables of modules) - */ - struct jpeg_comp_master * master; - struct jpeg_c_main_controller * main; - struct jpeg_c_prep_controller * prep; - struct jpeg_c_coef_controller * coef; - struct jpeg_marker_writer * marker; - struct jpeg_color_converter * cconvert; - struct jpeg_downsampler * downsample; - struct jpeg_forward_dct * fdct; - struct jpeg_entropy_encoder * entropy; - jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ - int script_space_size; -}; - - -/* Master record for a decompression instance */ - -struct jpeg_decompress_struct { - jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ - - /* Source of compressed data */ - struct jpeg_source_mgr * src; - - /* Basic description of image --- filled in by jpeg_read_header(). */ - /* Application may inspect these values to decide how to process image. */ - - JDIMENSION image_width; /* nominal image width (from SOF marker) */ - JDIMENSION image_height; /* nominal image height */ - int num_components; /* # of color components in JPEG image */ - J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ - - /* Decompression processing parameters --- these fields must be set before - * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes - * them to default values. - */ - - J_COLOR_SPACE out_color_space; /* colorspace for output */ - - unsigned int scale_num, scale_denom; /* fraction by which to scale image */ - - double output_gamma; /* image gamma wanted in output */ - - boolean buffered_image; /* TRUE=multiple output passes */ - boolean raw_data_out; /* TRUE=downsampled data wanted */ - - J_DCT_METHOD dct_method; /* IDCT algorithm selector */ - boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ - boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ - - boolean quantize_colors; /* TRUE=colormapped output wanted */ - /* the following are ignored if not quantize_colors: */ - J_DITHER_MODE dither_mode; /* type of color dithering to use */ - boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ - int desired_number_of_colors; /* max # colors to use in created colormap */ - /* these are significant only in buffered-image mode: */ - boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ - boolean enable_external_quant;/* enable future use of external colormap */ - boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ - - /* Description of actual output image that will be returned to application. - * These fields are computed by jpeg_start_decompress(). - * You can also use jpeg_calc_output_dimensions() to determine these values - * in advance of calling jpeg_start_decompress(). - */ - - JDIMENSION output_width; /* scaled image width */ - JDIMENSION output_height; /* scaled image height */ - int out_color_components; /* # of color components in out_color_space */ - int output_components; /* # of color components returned */ - /* output_components is 1 (a colormap index) when quantizing colors; - * otherwise it equals out_color_components. - */ - int rec_outbuf_height; /* min recommended height of scanline buffer */ - /* If the buffer passed to jpeg_read_scanlines() is less than this many rows - * high, space and time will be wasted due to unnecessary data copying. - * Usually rec_outbuf_height will be 1 or 2, at most 4. - */ - - /* When quantizing colors, the output colormap is described by these fields. - * The application can supply a colormap by setting colormap non-NULL before - * calling jpeg_start_decompress; otherwise a colormap is created during - * jpeg_start_decompress or jpeg_start_output. - * The map has out_color_components rows and actual_number_of_colors columns. - */ - int actual_number_of_colors; /* number of entries in use */ - JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ - - /* State variables: these variables indicate the progress of decompression. - * The application may examine these but must not modify them. - */ - - /* Row index of next scanline to be read from jpeg_read_scanlines(). - * Application may use this to control its processing loop, e.g., - * "while (output_scanline < output_height)". - */ - JDIMENSION output_scanline; /* 0 .. output_height-1 */ - - /* Current input scan number and number of iMCU rows completed in scan. - * These indicate the progress of the decompressor input side. - */ - int input_scan_number; /* Number of SOS markers seen so far */ - JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ - - /* The "output scan number" is the notional scan being displayed by the - * output side. The decompressor will not allow output scan/row number - * to get ahead of input scan/row, but it can fall arbitrarily far behind. - */ - int output_scan_number; /* Nominal scan number being displayed */ - JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ - - /* Current progression status. coef_bits[c][i] indicates the precision - * with which component c's DCT coefficient i (in zigzag order) is known. - * It is -1 when no data has yet been received, otherwise it is the point - * transform (shift) value for the most recent scan of the coefficient - * (thus, 0 at completion of the progression). - * This pointer is NULL when reading a non-progressive file. - */ - int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ - - /* Internal JPEG parameters --- the application usually need not look at - * these fields. Note that the decompressor output side may not use - * any parameters that can change between scans. - */ - - /* Quantization and Huffman tables are carried forward across input - * datastreams when processing abbreviated JPEG datastreams. - */ - - JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; - /* ptrs to coefficient quantization tables, or NULL if not defined */ - - JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; - JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; - /* ptrs to Huffman coding tables, or NULL if not defined */ - - /* These parameters are never carried across datastreams, since they - * are given in SOF/SOS markers or defined to be reset by SOI. - */ - - int data_precision; /* bits of precision in image data */ - - jpeg_component_info * comp_info; - /* comp_info[i] describes component that appears i'th in SOF */ - - boolean is_baseline; /* TRUE if Baseline SOF0 encountered */ - boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ - boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ - - UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ - UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ - UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ - - unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ - - /* These fields record data obtained from optional markers recognized by - * the JPEG library. - */ - boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ - /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ - UINT8 JFIF_major_version; /* JFIF version number */ - UINT8 JFIF_minor_version; - UINT8 density_unit; /* JFIF code for pixel size units */ - UINT16 X_density; /* Horizontal pixel density */ - UINT16 Y_density; /* Vertical pixel density */ - boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ - UINT8 Adobe_transform; /* Color transform code from Adobe marker */ - - J_COLOR_TRANSFORM color_transform; - /* Color transform identifier derived from LSE marker, otherwise zero */ - - boolean CCIR601_sampling; /* TRUE=first samples are cosited */ - - /* Aside from the specific data retained from APPn markers known to the - * library, the uninterpreted contents of any or all APPn and COM markers - * can be saved in a list for examination by the application. - */ - jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ - - /* Remaining fields are known throughout decompressor, but generally - * should not be touched by a surrounding application. - */ - - /* - * These fields are computed during decompression startup - */ - int max_h_samp_factor; /* largest h_samp_factor */ - int max_v_samp_factor; /* largest v_samp_factor */ - - int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */ - int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */ - - JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ - /* The coefficient controller's input and output progress is measured in - * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows - * in fully interleaved JPEG scans, but are used whether the scan is - * interleaved or not. We define an iMCU row as v_samp_factor DCT block - * rows of each component. Therefore, the IDCT output contains - * v_samp_factor * DCT_v_scaled_size sample rows of a component per iMCU row. - */ - - JSAMPLE * sample_range_limit; /* table for fast range-limiting */ - - /* - * These fields are valid during any one scan. - * They describe the components and MCUs actually appearing in the scan. - * Note that the decompressor output side must not use these fields. - */ - int comps_in_scan; /* # of JPEG components in this scan */ - jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; - /* *cur_comp_info[i] describes component that appears i'th in SOS */ - - JDIMENSION MCUs_per_row; /* # of MCUs across the image */ - JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ - - int blocks_in_MCU; /* # of DCT blocks per MCU */ - int MCU_membership[D_MAX_BLOCKS_IN_MCU]; - /* MCU_membership[i] is index in cur_comp_info of component owning */ - /* i'th block in an MCU */ - - int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ - - /* These fields are derived from Se of first SOS marker. - */ - int block_size; /* the basic DCT block size: 1..16 */ - const int * natural_order; /* natural-order position array for entropy decode */ - int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */ - - /* This field is shared between entropy decoder and marker parser. - * It is either zero or the code of a JPEG marker that has been - * read from the data source, but has not yet been processed. - */ - int unread_marker; - - /* - * Links to decompression subobjects (methods, private variables of modules) - */ - struct jpeg_decomp_master * master; - struct jpeg_d_main_controller * main; - struct jpeg_d_coef_controller * coef; - struct jpeg_d_post_controller * post; - struct jpeg_input_controller * inputctl; - struct jpeg_marker_reader * marker; - struct jpeg_entropy_decoder * entropy; - struct jpeg_inverse_dct * idct; - struct jpeg_upsampler * upsample; - struct jpeg_color_deconverter * cconvert; - struct jpeg_color_quantizer * cquantize; -}; - - -/* "Object" declarations for JPEG modules that may be supplied or called - * directly by the surrounding application. - * As with all objects in the JPEG library, these structs only define the - * publicly visible methods and state variables of a module. Additional - * private fields may exist after the public ones. - */ - - -/* Error handler object */ - -struct jpeg_error_mgr { - /* Error exit handler: does not return to caller */ - JMETHOD(noreturn_t, error_exit, (j_common_ptr cinfo)); - /* Conditionally emit a trace or warning message */ - JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); - /* Routine that actually outputs a trace or error message */ - JMETHOD(void, output_message, (j_common_ptr cinfo)); - /* Format a message string for the most recent JPEG error or message */ - JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); -#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ - /* Reset error state variables at start of a new image */ - JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); - - /* The message ID code and any parameters are saved here. - * A message can have one string parameter or up to 8 int parameters. - */ - int msg_code; -#define JMSG_STR_PARM_MAX 80 - union { - int i[8]; - char s[JMSG_STR_PARM_MAX]; - } msg_parm; - - /* Standard state variables for error facility */ - - int trace_level; /* max msg_level that will be displayed */ - - /* For recoverable corrupt-data errors, we emit a warning message, - * but keep going unless emit_message chooses to abort. emit_message - * should count warnings in num_warnings. The surrounding application - * can check for bad data by seeing if num_warnings is nonzero at the - * end of processing. - */ - long num_warnings; /* number of corrupt-data warnings */ - - /* These fields point to the table(s) of error message strings. - * An application can change the table pointer to switch to a different - * message list (typically, to change the language in which errors are - * reported). Some applications may wish to add additional error codes - * that will be handled by the JPEG library error mechanism; the second - * table pointer is used for this purpose. - * - * First table includes all errors generated by JPEG library itself. - * Error code 0 is reserved for a "no such error string" message. - */ - const char * const * jpeg_message_table; /* Library errors */ - int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ - /* Second table can be added by application (see cjpeg/djpeg for example). - * It contains strings numbered first_addon_message..last_addon_message. - */ - const char * const * addon_message_table; /* Non-library errors */ - int first_addon_message; /* code for first string in addon table */ - int last_addon_message; /* code for last string in addon table */ -}; - - -/* Progress monitor object */ - -struct jpeg_progress_mgr { - JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); - - long pass_counter; /* work units completed in this pass */ - long pass_limit; /* total number of work units in this pass */ - int completed_passes; /* passes completed so far */ - int total_passes; /* total number of passes expected */ -}; - - -/* Data destination object for compression */ - -struct jpeg_destination_mgr { - JOCTET * next_output_byte; /* => next byte to write in buffer */ - size_t free_in_buffer; /* # of byte spaces remaining in buffer */ - - JMETHOD(void, init_destination, (j_compress_ptr cinfo)); - JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); - JMETHOD(void, term_destination, (j_compress_ptr cinfo)); -}; - - -/* Data source object for decompression */ - -struct jpeg_source_mgr { - const JOCTET * next_input_byte; /* => next byte to read from buffer */ - size_t bytes_in_buffer; /* # of bytes remaining in buffer */ - - JMETHOD(void, init_source, (j_decompress_ptr cinfo)); - JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); - JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); - JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); - JMETHOD(void, term_source, (j_decompress_ptr cinfo)); -}; - - -/* Memory manager object. - * Allocates "small" objects (a few K total), "large" objects (tens of K), - * and "really big" objects (virtual arrays with backing store if needed). - * The memory manager does not allow individual objects to be freed; rather, - * each created object is assigned to a pool, and whole pools can be freed - * at once. This is faster and more convenient than remembering exactly what - * to free, especially where malloc()/free() are not too speedy. - * NB: alloc routines never return NULL. They exit to error_exit if not - * successful. - */ - -#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ -#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ -#define JPOOL_NUMPOOLS 2 - -typedef struct jvirt_sarray_control * jvirt_sarray_ptr; -typedef struct jvirt_barray_control * jvirt_barray_ptr; - - -struct jpeg_memory_mgr { - /* Method pointers */ - JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, - size_t sizeofobject)); - JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, - size_t sizeofobject)); - JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, - JDIMENSION samplesperrow, - JDIMENSION numrows)); - JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, - JDIMENSION blocksperrow, - JDIMENSION numrows)); - JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, - int pool_id, - boolean pre_zero, - JDIMENSION samplesperrow, - JDIMENSION numrows, - JDIMENSION maxaccess)); - JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, - int pool_id, - boolean pre_zero, - JDIMENSION blocksperrow, - JDIMENSION numrows, - JDIMENSION maxaccess)); - JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); - JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, - jvirt_sarray_ptr ptr, - JDIMENSION start_row, - JDIMENSION num_rows, - boolean writable)); - JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, - jvirt_barray_ptr ptr, - JDIMENSION start_row, - JDIMENSION num_rows, - boolean writable)); - JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); - JMETHOD(void, self_destruct, (j_common_ptr cinfo)); - - /* Limit on memory allocation for this JPEG object. (Note that this is - * merely advisory, not a guaranteed maximum; it only affects the space - * used for virtual-array buffers.) May be changed by outer application - * after creating the JPEG object. - */ - long max_memory_to_use; - - /* Maximum allocation request accepted by alloc_large. */ - long max_alloc_chunk; -}; - - -/* Routine signature for application-supplied marker processing methods. - * Need not pass marker code since it is stored in cinfo->unread_marker. - */ -typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); - - -/* Declarations for routines called by application. - * The JPP macro hides prototype parameters from compilers that can't cope. - * Note JPP requires double parentheses. - */ - -#ifdef HAVE_PROTOTYPES -#define JPP(arglist) arglist -#else -#define JPP(arglist) () -#endif - - -/* Short forms of external names for systems with brain-damaged linkers. - * We shorten external names to be unique in the first six letters, which - * is good enough for all known systems. - * (If your compiler itself needs names to be unique in less than 15 - * characters, you are out of luck. Get a better compiler.) - */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_std_error jStdError -#define jpeg_CreateCompress jCreaCompress -#define jpeg_CreateDecompress jCreaDecompress -#define jpeg_destroy_compress jDestCompress -#define jpeg_destroy_decompress jDestDecompress -#define jpeg_stdio_dest jStdDest -#define jpeg_stdio_src jStdSrc -#define jpeg_mem_dest jMemDest -#define jpeg_mem_src jMemSrc -#define jpeg_set_defaults jSetDefaults -#define jpeg_set_colorspace jSetColorspace -#define jpeg_default_colorspace jDefColorspace -#define jpeg_set_quality jSetQuality -#define jpeg_set_linear_quality jSetLQuality -#define jpeg_default_qtables jDefQTables -#define jpeg_add_quant_table jAddQuantTable -#define jpeg_quality_scaling jQualityScaling -#define jpeg_simple_progression jSimProgress -#define jpeg_suppress_tables jSuppressTables -#define jpeg_alloc_quant_table jAlcQTable -#define jpeg_alloc_huff_table jAlcHTable -#define jpeg_start_compress jStrtCompress -#define jpeg_write_scanlines jWrtScanlines -#define jpeg_finish_compress jFinCompress -#define jpeg_calc_jpeg_dimensions jCjpegDimensions -#define jpeg_write_raw_data jWrtRawData -#define jpeg_write_marker jWrtMarker -#define jpeg_write_m_header jWrtMHeader -#define jpeg_write_m_byte jWrtMByte -#define jpeg_write_tables jWrtTables -#define jpeg_read_header jReadHeader -#define jpeg_start_decompress jStrtDecompress -#define jpeg_read_scanlines jReadScanlines -#define jpeg_finish_decompress jFinDecompress -#define jpeg_read_raw_data jReadRawData -#define jpeg_has_multiple_scans jHasMultScn -#define jpeg_start_output jStrtOutput -#define jpeg_finish_output jFinOutput -#define jpeg_input_complete jInComplete -#define jpeg_new_colormap jNewCMap -#define jpeg_consume_input jConsumeInput -#define jpeg_core_output_dimensions jCoreDimensions -#define jpeg_calc_output_dimensions jCalcDimensions -#define jpeg_save_markers jSaveMarkers -#define jpeg_set_marker_processor jSetMarker -#define jpeg_read_coefficients jReadCoefs -#define jpeg_write_coefficients jWrtCoefs -#define jpeg_copy_critical_parameters jCopyCrit -#define jpeg_abort_compress jAbrtCompress -#define jpeg_abort_decompress jAbrtDecompress -#define jpeg_abort jAbort -#define jpeg_destroy jDestroy -#define jpeg_resync_to_restart jResyncRestart -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - - -/* Default error-management setup */ -EXTERN(struct jpeg_error_mgr *) jpeg_std_error - JPP((struct jpeg_error_mgr * err)); - -/* Initialization of JPEG compression objects. - * jpeg_create_compress() and jpeg_create_decompress() are the exported - * names that applications should call. These expand to calls on - * jpeg_CreateCompress and jpeg_CreateDecompress with additional information - * passed for version mismatch checking. - * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. - */ -#define jpeg_create_compress(cinfo) \ - jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ - (size_t) sizeof(struct jpeg_compress_struct)) -#define jpeg_create_decompress(cinfo) \ - jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ - (size_t) sizeof(struct jpeg_decompress_struct)) -EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, - int version, size_t structsize)); -EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, - int version, size_t structsize)); -/* Destruction of JPEG compression objects */ -EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); - -/* Standard data source and destination managers: stdio streams. */ -/* Caller is responsible for opening the file before and closing after. */ -EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); -EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); - -/* Data source and destination managers: memory buffers. */ -EXTERN(void) jpeg_mem_dest JPP((j_compress_ptr cinfo, - unsigned char ** outbuffer, - unsigned long * outsize)); -EXTERN(void) jpeg_mem_src JPP((j_decompress_ptr cinfo, - const unsigned char * inbuffer, - unsigned long insize)); - -/* Default parameter setup for compression */ -EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); -/* Compression parameter setup aids */ -EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, - J_COLOR_SPACE colorspace)); -EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, - boolean force_baseline)); -EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, - int scale_factor, - boolean force_baseline)); -EXTERN(void) jpeg_default_qtables JPP((j_compress_ptr cinfo, - boolean force_baseline)); -EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, - const unsigned int *basic_table, - int scale_factor, - boolean force_baseline)); -EXTERN(int) jpeg_quality_scaling JPP((int quality)); -EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, - boolean suppress)); -EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); -EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); - -/* Main entry points for compression */ -EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, - boolean write_all_tables)); -EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION num_lines)); -EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); - -/* Precalculate JPEG dimensions for current compression parameters. */ -EXTERN(void) jpeg_calc_jpeg_dimensions JPP((j_compress_ptr cinfo)); - -/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ -EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION num_lines)); - -/* Write a special marker. See libjpeg.txt concerning safe usage. */ -EXTERN(void) jpeg_write_marker - JPP((j_compress_ptr cinfo, int marker, - const JOCTET * dataptr, unsigned int datalen)); -/* Same, but piecemeal. */ -EXTERN(void) jpeg_write_m_header - JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); -EXTERN(void) jpeg_write_m_byte - JPP((j_compress_ptr cinfo, int val)); - -/* Alternate compression function: just write an abbreviated table file */ -EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); - -/* Decompression startup: read start of JPEG datastream to see what's there */ -EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, - boolean require_image)); -/* Return value is one of: */ -#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ -#define JPEG_HEADER_OK 1 /* Found valid image datastream */ -#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ -/* If you pass require_image = TRUE (normal case), you need not check for - * a TABLES_ONLY return code; an abbreviated file will cause an error exit. - * JPEG_SUSPENDED is only possible if you use a data source module that can - * give a suspension return (the stdio source module doesn't). - */ - -/* Main entry points for decompression */ -EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); -EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION max_lines)); -EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); - -/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ -EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION max_lines)); - -/* Additional entry points for buffered-image mode. */ -EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); -EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, - int scan_number)); -EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); -EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); -EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); -EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); -/* Return value is one of: */ -/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ -#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ -#define JPEG_REACHED_EOI 2 /* Reached end of image */ -#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ -#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ - -/* Precalculate output dimensions for current decompression parameters. */ -EXTERN(void) jpeg_core_output_dimensions JPP((j_decompress_ptr cinfo)); -EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); - -/* Control saving of COM and APPn markers into marker_list. */ -EXTERN(void) jpeg_save_markers - JPP((j_decompress_ptr cinfo, int marker_code, - unsigned int length_limit)); - -/* Install a special processing method for COM or APPn markers. */ -EXTERN(void) jpeg_set_marker_processor - JPP((j_decompress_ptr cinfo, int marker_code, - jpeg_marker_parser_method routine)); - -/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ -EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); -EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, - jvirt_barray_ptr * coef_arrays)); -EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, - j_compress_ptr dstinfo)); - -/* If you choose to abort compression or decompression before completing - * jpeg_finish_(de)compress, then you need to clean up to release memory, - * temporary files, etc. You can just call jpeg_destroy_(de)compress - * if you're done with the JPEG object, but if you want to clean it up and - * reuse it, call this: - */ -EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); - -/* Generic versions of jpeg_abort and jpeg_destroy that work on either - * flavor of JPEG object. These may be more convenient in some places. - */ -EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); -EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); - -/* Default restart-marker-resync procedure for use by data source modules */ -EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, - int desired)); - - -/* These marker codes are exported since applications and data source modules - * are likely to want to use them. - */ - -#define JPEG_RST0 0xD0 /* RST0 marker code */ -#define JPEG_EOI 0xD9 /* EOI marker code */ -#define JPEG_APP0 0xE0 /* APP0 marker code */ -#define JPEG_COM 0xFE /* COM marker code */ - - -/* If we have a brain-damaged compiler that emits warnings (or worse, errors) - * for structure definitions that are never filled in, keep it quiet by - * supplying dummy definitions for the various substructures. - */ - -#ifdef INCOMPLETE_TYPES_BROKEN -#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ -struct jvirt_sarray_control { long dummy; }; -struct jvirt_barray_control { long dummy; }; -struct jpeg_comp_master { long dummy; }; -struct jpeg_c_main_controller { long dummy; }; -struct jpeg_c_prep_controller { long dummy; }; -struct jpeg_c_coef_controller { long dummy; }; -struct jpeg_marker_writer { long dummy; }; -struct jpeg_color_converter { long dummy; }; -struct jpeg_downsampler { long dummy; }; -struct jpeg_forward_dct { long dummy; }; -struct jpeg_entropy_encoder { long dummy; }; -struct jpeg_decomp_master { long dummy; }; -struct jpeg_d_main_controller { long dummy; }; -struct jpeg_d_coef_controller { long dummy; }; -struct jpeg_d_post_controller { long dummy; }; -struct jpeg_input_controller { long dummy; }; -struct jpeg_marker_reader { long dummy; }; -struct jpeg_entropy_decoder { long dummy; }; -struct jpeg_inverse_dct { long dummy; }; -struct jpeg_upsampler { long dummy; }; -struct jpeg_color_deconverter { long dummy; }; -struct jpeg_color_quantizer { long dummy; }; -#endif /* JPEG_INTERNALS */ -#endif /* INCOMPLETE_TYPES_BROKEN */ - - -/* - * The JPEG library modules define JPEG_INTERNALS before including this file. - * The internal structure declarations are read only when that is true. - * Applications using the library should not include jpegint.h, but may wish - * to include jerror.h. - */ - -#ifdef JPEG_INTERNALS -#include "jpegint.h" /* fetch private declarations */ -#include "jerror.h" /* fetch error codes too */ -#endif - -#ifdef __cplusplus -#ifndef DONT_USE_EXTERN_C -} -#endif -#endif - -#endif /* JPEGLIB_H */ diff --git a/libraries/jpeg/jquant1.c b/libraries/jpeg/jquant1.c deleted file mode 100644 index 9d11f7066..000000000 --- a/libraries/jpeg/jquant1.c +++ /dev/null @@ -1,857 +0,0 @@ -/* - * jquant1.c - * - * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2011 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains 1-pass color quantization (color mapping) routines. - * These routines provide mapping to a fixed color map using equally spaced - * color values. Optional Floyd-Steinberg or ordered dithering is available. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - -#ifdef QUANT_1PASS_SUPPORTED - - -/* - * The main purpose of 1-pass quantization is to provide a fast, if not very - * high quality, colormapped output capability. A 2-pass quantizer usually - * gives better visual quality; however, for quantized grayscale output this - * quantizer is perfectly adequate. Dithering is highly recommended with this - * quantizer, though you can turn it off if you really want to. - * - * In 1-pass quantization the colormap must be chosen in advance of seeing the - * image. We use a map consisting of all combinations of Ncolors[i] color - * values for the i'th component. The Ncolors[] values are chosen so that - * their product, the total number of colors, is no more than that requested. - * (In most cases, the product will be somewhat less.) - * - * Since the colormap is orthogonal, the representative value for each color - * component can be determined without considering the other components; - * then these indexes can be combined into a colormap index by a standard - * N-dimensional-array-subscript calculation. Most of the arithmetic involved - * can be precalculated and stored in the lookup table colorindex[]. - * colorindex[i][j] maps pixel value j in component i to the nearest - * representative value (grid plane) for that component; this index is - * multiplied by the array stride for component i, so that the - * index of the colormap entry closest to a given pixel value is just - * sum( colorindex[component-number][pixel-component-value] ) - * Aside from being fast, this scheme allows for variable spacing between - * representative values with no additional lookup cost. - * - * If gamma correction has been applied in color conversion, it might be wise - * to adjust the color grid spacing so that the representative colors are - * equidistant in linear space. At this writing, gamma correction is not - * implemented by jdcolor, so nothing is done here. - */ - - -/* Declarations for ordered dithering. - * - * We use a standard 16x16 ordered dither array. The basic concept of ordered - * dithering is described in many references, for instance Dale Schumacher's - * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991). - * In place of Schumacher's comparisons against a "threshold" value, we add a - * "dither" value to the input pixel and then round the result to the nearest - * output value. The dither value is equivalent to (0.5 - threshold) times - * the distance between output values. For ordered dithering, we assume that - * the output colors are equally spaced; if not, results will probably be - * worse, since the dither may be too much or too little at a given point. - * - * The normal calculation would be to form pixel value + dither, range-limit - * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual. - * We can skip the separate range-limiting step by extending the colorindex - * table in both directions. - */ - -#define ODITHER_SIZE 16 /* dimension of dither matrix */ -/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */ -#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */ -#define ODITHER_MASK (ODITHER_SIZE-1) /* mask for wrapping around counters */ - -typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE]; -typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE]; - -static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { - /* Bayer's order-4 dither array. Generated by the code given in - * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. - * The values in this array must range from 0 to ODITHER_CELLS-1. - */ - { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, - { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 }, - { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 }, - { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 }, - { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 }, - { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 }, - { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 }, - { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 }, - { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 }, - { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 }, - { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 }, - { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 }, - { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 }, - { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 }, - { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, - { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } -}; - - -/* Declarations for Floyd-Steinberg dithering. - * - * Errors are accumulated into the array fserrors[], at a resolution of - * 1/16th of a pixel count. The error at a given pixel is propagated - * to its not-yet-processed neighbors using the standard F-S fractions, - * ... (here) 7/16 - * 3/16 5/16 1/16 - * We work left-to-right on even rows, right-to-left on odd rows. - * - * We can get away with a single array (holding one row's worth of errors) - * by using it to store the current row's errors at pixel columns not yet - * processed, but the next row's errors at columns already processed. We - * need only a few extra variables to hold the errors immediately around the - * current column. (If we are lucky, those variables are in registers, but - * even if not, they're probably cheaper to access than array elements are.) - * - * The fserrors[] array is indexed [component#][position]. - * We provide (#columns + 2) entries per component; the extra entry at each - * end saves us from special-casing the first and last pixels. - * - * Note: on a wide image, we might not have enough room in a PC's near data - * segment to hold the error array; so it is allocated with alloc_large. - */ - -#if BITS_IN_JSAMPLE == 8 -typedef INT16 FSERROR; /* 16 bits should be enough */ -typedef int LOCFSERROR; /* use 'int' for calculation temps */ -#else -typedef INT32 FSERROR; /* may need more than 16 bits */ -typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */ -#endif - -typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */ - - -/* Private subobject */ - -#define MAX_Q_COMPS 4 /* max components I can handle */ - -typedef struct { - struct jpeg_color_quantizer pub; /* public fields */ - - /* Initially allocated colormap is saved here */ - JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */ - int sv_actual; /* number of entries in use */ - - JSAMPARRAY colorindex; /* Precomputed mapping for speed */ - /* colorindex[i][j] = index of color closest to pixel value j in component i, - * premultiplied as described above. Since colormap indexes must fit into - * JSAMPLEs, the entries of this array will too. - */ - boolean is_padded; /* is the colorindex padded for odither? */ - - int Ncolors[MAX_Q_COMPS]; /* # of values alloced to each component */ - - /* Variables for ordered dithering */ - int row_index; /* cur row's vertical index in dither matrix */ - ODITHER_MATRIX_PTR odither[MAX_Q_COMPS]; /* one dither array per component */ - - /* Variables for Floyd-Steinberg dithering */ - FSERRPTR fserrors[MAX_Q_COMPS]; /* accumulated errors */ - boolean on_odd_row; /* flag to remember which row we are on */ -} my_cquantizer; - -typedef my_cquantizer * my_cquantize_ptr; - - -/* - * Policy-making subroutines for create_colormap and create_colorindex. - * These routines determine the colormap to be used. The rest of the module - * only assumes that the colormap is orthogonal. - * - * * select_ncolors decides how to divvy up the available colors - * among the components. - * * output_value defines the set of representative values for a component. - * * largest_input_value defines the mapping from input values to - * representative values for a component. - * Note that the latter two routines may impose different policies for - * different components, though this is not currently done. - */ - - -LOCAL(int) -select_ncolors (j_decompress_ptr cinfo, int Ncolors[]) -/* Determine allocation of desired colors to components, */ -/* and fill in Ncolors[] array to indicate choice. */ -/* Return value is total number of colors (product of Ncolors[] values). */ -{ - int nc = cinfo->out_color_components; /* number of color components */ - int max_colors = cinfo->desired_number_of_colors; - int total_colors, iroot, i, j; - boolean changed; - long temp; - static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE }; - - /* We can allocate at least the nc'th root of max_colors per component. */ - /* Compute floor(nc'th root of max_colors). */ - iroot = 1; - do { - iroot++; - temp = iroot; /* set temp = iroot ** nc */ - for (i = 1; i < nc; i++) - temp *= iroot; - } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */ - iroot--; /* now iroot = floor(root) */ - - /* Must have at least 2 color values per component */ - if (iroot < 2) - ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, (int) temp); - - /* Initialize to iroot color values for each component */ - total_colors = 1; - for (i = 0; i < nc; i++) { - Ncolors[i] = iroot; - total_colors *= iroot; - } - /* We may be able to increment the count for one or more components without - * exceeding max_colors, though we know not all can be incremented. - * Sometimes, the first component can be incremented more than once! - * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.) - * In RGB colorspace, try to increment G first, then R, then B. - */ - do { - changed = FALSE; - for (i = 0; i < nc; i++) { - j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i); - /* calculate new total_colors if Ncolors[j] is incremented */ - temp = total_colors / Ncolors[j]; - temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */ - if (temp > (long) max_colors) - break; /* won't fit, done with this pass */ - Ncolors[j]++; /* OK, apply the increment */ - total_colors = (int) temp; - changed = TRUE; - } - } while (changed); - - return total_colors; -} - - -LOCAL(int) -output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) -/* Return j'th output value, where j will range from 0 to maxj */ -/* The output values must fall in 0..MAXJSAMPLE in increasing order */ -{ - /* We always provide values 0 and MAXJSAMPLE for each component; - * any additional values are equally spaced between these limits. - * (Forcing the upper and lower values to the limits ensures that - * dithering can't produce a color outside the selected gamut.) - */ - return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj); -} - - -LOCAL(int) -largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) -/* Return largest input value that should map to j'th output value */ -/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ -{ - /* Breakpoints are halfway between values returned by output_value */ - return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); -} - - -/* - * Create the colormap. - */ - -LOCAL(void) -create_colormap (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - JSAMPARRAY colormap; /* Created colormap */ - int total_colors; /* Number of distinct output colors */ - int i,j,k, nci, blksize, blkdist, ptr, val; - - /* Select number of colors for each component */ - total_colors = select_ncolors(cinfo, cquantize->Ncolors); - - /* Report selected color counts */ - if (cinfo->out_color_components == 3) - TRACEMS4(cinfo, 1, JTRC_QUANT_3_NCOLORS, - total_colors, cquantize->Ncolors[0], - cquantize->Ncolors[1], cquantize->Ncolors[2]); - else - TRACEMS1(cinfo, 1, JTRC_QUANT_NCOLORS, total_colors); - - /* Allocate and fill in the colormap. */ - /* The colors are ordered in the map in standard row-major order, */ - /* i.e. rightmost (highest-indexed) color changes most rapidly. */ - - colormap = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components); - - /* blksize is number of adjacent repeated entries for a component */ - /* blkdist is distance between groups of identical entries for a component */ - blkdist = total_colors; - - for (i = 0; i < cinfo->out_color_components; i++) { - /* fill in colormap entries for i'th color component */ - nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ - blksize = blkdist / nci; - for (j = 0; j < nci; j++) { - /* Compute j'th output value (out of nci) for component */ - val = output_value(cinfo, i, j, nci-1); - /* Fill in all colormap entries that have this value of this component */ - for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) { - /* fill in blksize entries beginning at ptr */ - for (k = 0; k < blksize; k++) - colormap[i][ptr+k] = (JSAMPLE) val; - } - } - blkdist = blksize; /* blksize of this color is blkdist of next */ - } - - /* Save the colormap in private storage, - * where it will survive color quantization mode changes. - */ - cquantize->sv_colormap = colormap; - cquantize->sv_actual = total_colors; -} - - -/* - * Create the color index table. - */ - -LOCAL(void) -create_colorindex (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - JSAMPROW indexptr; - int i,j,k, nci, blksize, val, pad; - - /* For ordered dither, we pad the color index tables by MAXJSAMPLE in - * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE). - * This is not necessary in the other dithering modes. However, we - * flag whether it was done in case user changes dithering mode. - */ - if (cinfo->dither_mode == JDITHER_ORDERED) { - pad = MAXJSAMPLE*2; - cquantize->is_padded = TRUE; - } else { - pad = 0; - cquantize->is_padded = FALSE; - } - - cquantize->colorindex = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (JDIMENSION) (MAXJSAMPLE+1 + pad), - (JDIMENSION) cinfo->out_color_components); - - /* blksize is number of adjacent repeated entries for a component */ - blksize = cquantize->sv_actual; - - for (i = 0; i < cinfo->out_color_components; i++) { - /* fill in colorindex entries for i'th color component */ - nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ - blksize = blksize / nci; - - /* adjust colorindex pointers to provide padding at negative indexes. */ - if (pad) - cquantize->colorindex[i] += MAXJSAMPLE; - - /* in loop, val = index of current output value, */ - /* and k = largest j that maps to current val */ - indexptr = cquantize->colorindex[i]; - val = 0; - k = largest_input_value(cinfo, i, 0, nci-1); - for (j = 0; j <= MAXJSAMPLE; j++) { - while (j > k) /* advance val if past boundary */ - k = largest_input_value(cinfo, i, ++val, nci-1); - /* premultiply so that no multiplication needed in main processing */ - indexptr[j] = (JSAMPLE) (val * blksize); - } - /* Pad at both ends if necessary */ - if (pad) - for (j = 1; j <= MAXJSAMPLE; j++) { - indexptr[-j] = indexptr[0]; - indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE]; - } - } -} - - -/* - * Create an ordered-dither array for a component having ncolors - * distinct output values. - */ - -LOCAL(ODITHER_MATRIX_PTR) -make_odither_array (j_decompress_ptr cinfo, int ncolors) -{ - ODITHER_MATRIX_PTR odither; - int j,k; - INT32 num,den; - - odither = (ODITHER_MATRIX_PTR) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(ODITHER_MATRIX)); - /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1). - * Hence the dither value for the matrix cell with fill order f - * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1). - * On 16-bit-int machine, be careful to avoid overflow. - */ - den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1)); - for (j = 0; j < ODITHER_SIZE; j++) { - for (k = 0; k < ODITHER_SIZE; k++) { - num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k]))) - * MAXJSAMPLE; - /* Ensure round towards zero despite C's lack of consistency - * about rounding negative values in integer division... - */ - odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den); - } - } - return odither; -} - - -/* - * Create the ordered-dither tables. - * Components having the same number of representative colors may - * share a dither table. - */ - -LOCAL(void) -create_odither_tables (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - ODITHER_MATRIX_PTR odither; - int i, j, nci; - - for (i = 0; i < cinfo->out_color_components; i++) { - nci = cquantize->Ncolors[i]; /* # of distinct values for this color */ - odither = NULL; /* search for matching prior component */ - for (j = 0; j < i; j++) { - if (nci == cquantize->Ncolors[j]) { - odither = cquantize->odither[j]; - break; - } - } - if (odither == NULL) /* need a new table? */ - odither = make_odither_array(cinfo, nci); - cquantize->odither[i] = odither; - } -} - - -/* - * Map some rows of pixels to the output colormapped representation. - */ - -METHODDEF(void) -color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -/* General case, no dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - JSAMPARRAY colorindex = cquantize->colorindex; - register int pixcode, ci; - register JSAMPROW ptrin, ptrout; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - register int nc = cinfo->out_color_components; - - for (row = 0; row < num_rows; row++) { - ptrin = input_buf[row]; - ptrout = output_buf[row]; - for (col = width; col > 0; col--) { - pixcode = 0; - for (ci = 0; ci < nc; ci++) { - pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]); - } - *ptrout++ = (JSAMPLE) pixcode; - } - } -} - - -METHODDEF(void) -color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -/* Fast path for out_color_components==3, no dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register int pixcode; - register JSAMPROW ptrin, ptrout; - JSAMPROW colorindex0 = cquantize->colorindex[0]; - JSAMPROW colorindex1 = cquantize->colorindex[1]; - JSAMPROW colorindex2 = cquantize->colorindex[2]; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - - for (row = 0; row < num_rows; row++) { - ptrin = input_buf[row]; - ptrout = output_buf[row]; - for (col = width; col > 0; col--) { - pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]); - pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]); - pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]); - *ptrout++ = (JSAMPLE) pixcode; - } - } -} - - -METHODDEF(void) -quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -/* General case, with ordered dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register JSAMPROW input_ptr; - register JSAMPROW output_ptr; - JSAMPROW colorindex_ci; - int * dither; /* points to active row of dither matrix */ - int row_index, col_index; /* current indexes into dither matrix */ - int nc = cinfo->out_color_components; - int ci; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - - for (row = 0; row < num_rows; row++) { - /* Initialize output values to 0 so can process components separately */ - FMEMZERO((void FAR *) output_buf[row], - (size_t) (width * SIZEOF(JSAMPLE))); - row_index = cquantize->row_index; - for (ci = 0; ci < nc; ci++) { - input_ptr = input_buf[row] + ci; - output_ptr = output_buf[row]; - colorindex_ci = cquantize->colorindex[ci]; - dither = cquantize->odither[ci][row_index]; - col_index = 0; - - for (col = width; col > 0; col--) { - /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE, - * select output value, accumulate into output code for this pixel. - * Range-limiting need not be done explicitly, as we have extended - * the colorindex table to produce the right answers for out-of-range - * inputs. The maximum dither is +- MAXJSAMPLE; this sets the - * required amount of padding. - */ - *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]]; - input_ptr += nc; - output_ptr++; - col_index = (col_index + 1) & ODITHER_MASK; - } - } - /* Advance row index for next row */ - row_index = (row_index + 1) & ODITHER_MASK; - cquantize->row_index = row_index; - } -} - - -METHODDEF(void) -quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -/* Fast path for out_color_components==3, with ordered dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register int pixcode; - register JSAMPROW input_ptr; - register JSAMPROW output_ptr; - JSAMPROW colorindex0 = cquantize->colorindex[0]; - JSAMPROW colorindex1 = cquantize->colorindex[1]; - JSAMPROW colorindex2 = cquantize->colorindex[2]; - int * dither0; /* points to active row of dither matrix */ - int * dither1; - int * dither2; - int row_index, col_index; /* current indexes into dither matrix */ - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - - for (row = 0; row < num_rows; row++) { - row_index = cquantize->row_index; - input_ptr = input_buf[row]; - output_ptr = output_buf[row]; - dither0 = cquantize->odither[0][row_index]; - dither1 = cquantize->odither[1][row_index]; - dither2 = cquantize->odither[2][row_index]; - col_index = 0; - - for (col = width; col > 0; col--) { - pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) + - dither0[col_index]]); - pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) + - dither1[col_index]]); - pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) + - dither2[col_index]]); - *output_ptr++ = (JSAMPLE) pixcode; - col_index = (col_index + 1) & ODITHER_MASK; - } - row_index = (row_index + 1) & ODITHER_MASK; - cquantize->row_index = row_index; - } -} - - -METHODDEF(void) -quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, - JSAMPARRAY output_buf, int num_rows) -/* General case, with Floyd-Steinberg dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - register LOCFSERROR cur; /* current error or pixel value */ - LOCFSERROR belowerr; /* error for pixel below cur */ - LOCFSERROR bpreverr; /* error for below/prev col */ - LOCFSERROR bnexterr; /* error for below/next col */ - LOCFSERROR delta; - register FSERRPTR errorptr; /* => fserrors[] at column before current */ - register JSAMPROW input_ptr; - register JSAMPROW output_ptr; - JSAMPROW colorindex_ci; - JSAMPROW colormap_ci; - int pixcode; - int nc = cinfo->out_color_components; - int dir; /* 1 for left-to-right, -1 for right-to-left */ - int dirnc; /* dir * nc */ - int ci; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - JSAMPLE *range_limit = cinfo->sample_range_limit; - SHIFT_TEMPS - - for (row = 0; row < num_rows; row++) { - /* Initialize output values to 0 so can process components separately */ - FMEMZERO((void FAR *) output_buf[row], - (size_t) (width * SIZEOF(JSAMPLE))); - for (ci = 0; ci < nc; ci++) { - input_ptr = input_buf[row] + ci; - output_ptr = output_buf[row]; - if (cquantize->on_odd_row) { - /* work right to left in this row */ - input_ptr += (width-1) * nc; /* so point to rightmost pixel */ - output_ptr += width-1; - dir = -1; - dirnc = -nc; - errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */ - } else { - /* work left to right in this row */ - dir = 1; - dirnc = nc; - errorptr = cquantize->fserrors[ci]; /* => entry before first column */ - } - colorindex_ci = cquantize->colorindex[ci]; - colormap_ci = cquantize->sv_colormap[ci]; - /* Preset error values: no error propagated to first pixel from left */ - cur = 0; - /* and no error propagated to row below yet */ - belowerr = bpreverr = 0; - - for (col = width; col > 0; col--) { - /* cur holds the error propagated from the previous pixel on the - * current line. Add the error propagated from the previous line - * to form the complete error correction term for this pixel, and - * round the error term (which is expressed * 16) to an integer. - * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct - * for either sign of the error value. - * Note: errorptr points to *previous* column's array entry. - */ - cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4); - /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. - * The maximum error is +- MAXJSAMPLE; this sets the required size - * of the range_limit array. - */ - cur += GETJSAMPLE(*input_ptr); - cur = GETJSAMPLE(range_limit[cur]); - /* Select output value, accumulate into output code for this pixel */ - pixcode = GETJSAMPLE(colorindex_ci[cur]); - *output_ptr += (JSAMPLE) pixcode; - /* Compute actual representation error at this pixel */ - /* Note: we can do this even though we don't have the final */ - /* pixel code, because the colormap is orthogonal. */ - cur -= GETJSAMPLE(colormap_ci[pixcode]); - /* Compute error fractions to be propagated to adjacent pixels. - * Add these into the running sums, and simultaneously shift the - * next-line error sums left by 1 column. - */ - bnexterr = cur; - delta = cur * 2; - cur += delta; /* form error * 3 */ - errorptr[0] = (FSERROR) (bpreverr + cur); - cur += delta; /* form error * 5 */ - bpreverr = belowerr + cur; - belowerr = bnexterr; - cur += delta; /* form error * 7 */ - /* At this point cur contains the 7/16 error value to be propagated - * to the next pixel on the current line, and all the errors for the - * next line have been shifted over. We are therefore ready to move on. - */ - input_ptr += dirnc; /* advance input ptr to next column */ - output_ptr += dir; /* advance output ptr to next column */ - errorptr += dir; /* advance errorptr to current column */ - } - /* Post-loop cleanup: we must unload the final error value into the - * final fserrors[] entry. Note we need not unload belowerr because - * it is for the dummy column before or after the actual array. - */ - errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */ - } - cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE); - } -} - - -/* - * Allocate workspace for Floyd-Steinberg errors. - */ - -LOCAL(void) -alloc_fs_workspace (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - size_t arraysize; - int i; - - arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); - for (i = 0; i < cinfo->out_color_components; i++) { - cquantize->fserrors[i] = (FSERRPTR) - (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); - } -} - - -/* - * Initialize for one-pass color quantization. - */ - -METHODDEF(void) -start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - size_t arraysize; - int i; - - /* Install my colormap. */ - cinfo->colormap = cquantize->sv_colormap; - cinfo->actual_number_of_colors = cquantize->sv_actual; - - /* Initialize for desired dithering mode. */ - switch (cinfo->dither_mode) { - case JDITHER_NONE: - if (cinfo->out_color_components == 3) - cquantize->pub.color_quantize = color_quantize3; - else - cquantize->pub.color_quantize = color_quantize; - break; - case JDITHER_ORDERED: - if (cinfo->out_color_components == 3) - cquantize->pub.color_quantize = quantize3_ord_dither; - else - cquantize->pub.color_quantize = quantize_ord_dither; - cquantize->row_index = 0; /* initialize state for ordered dither */ - /* If user changed to ordered dither from another mode, - * we must recreate the color index table with padding. - * This will cost extra space, but probably isn't very likely. - */ - if (! cquantize->is_padded) - create_colorindex(cinfo); - /* Create ordered-dither tables if we didn't already. */ - if (cquantize->odither[0] == NULL) - create_odither_tables(cinfo); - break; - case JDITHER_FS: - cquantize->pub.color_quantize = quantize_fs_dither; - cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */ - /* Allocate Floyd-Steinberg workspace if didn't already. */ - if (cquantize->fserrors[0] == NULL) - alloc_fs_workspace(cinfo); - /* Initialize the propagated errors to zero. */ - arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR)); - for (i = 0; i < cinfo->out_color_components; i++) - FMEMZERO((void FAR *) cquantize->fserrors[i], arraysize); - break; - default: - ERREXIT(cinfo, JERR_NOT_COMPILED); - break; - } -} - - -/* - * Finish up at the end of the pass. - */ - -METHODDEF(void) -finish_pass_1_quant (j_decompress_ptr cinfo) -{ - /* no work in 1-pass case */ -} - - -/* - * Switch to a new external colormap between output passes. - * Shouldn't get to this module! - */ - -METHODDEF(void) -new_color_map_1_quant (j_decompress_ptr cinfo) -{ - ERREXIT(cinfo, JERR_MODE_CHANGE); -} - - -/* - * Module initialization routine for 1-pass color quantization. - */ - -GLOBAL(void) -jinit_1pass_quantizer (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize; - - cquantize = (my_cquantize_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_cquantizer)); - cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; - cquantize->pub.start_pass = start_pass_1_quant; - cquantize->pub.finish_pass = finish_pass_1_quant; - cquantize->pub.new_color_map = new_color_map_1_quant; - cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */ - cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */ - - /* Make sure my internal arrays won't overflow */ - if (cinfo->out_color_components > MAX_Q_COMPS) - ERREXIT1(cinfo, JERR_QUANT_COMPONENTS, MAX_Q_COMPS); - /* Make sure colormap indexes can be represented by JSAMPLEs */ - if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1)) - ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXJSAMPLE+1); - - /* Create the colormap and color index table. */ - create_colormap(cinfo); - create_colorindex(cinfo); - - /* Allocate Floyd-Steinberg workspace now if requested. - * We do this now since it is FAR storage and may affect the memory - * manager's space calculations. If the user changes to FS dither - * mode in a later pass, we will allocate the space then, and will - * possibly overrun the max_memory_to_use setting. - */ - if (cinfo->dither_mode == JDITHER_FS) - alloc_fs_workspace(cinfo); -} - -#endif /* QUANT_1PASS_SUPPORTED */ diff --git a/libraries/jpeg/jquant2.c b/libraries/jpeg/jquant2.c deleted file mode 100644 index 38fc2af7a..000000000 --- a/libraries/jpeg/jquant2.c +++ /dev/null @@ -1,1311 +0,0 @@ -/* - * jquant2.c - * - * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2011 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains 2-pass color quantization (color mapping) routines. - * These routines provide selection of a custom color map for an image, - * followed by mapping of the image to that color map, with optional - * Floyd-Steinberg dithering. - * It is also possible to use just the second pass to map to an arbitrary - * externally-given color map. - * - * Note: ordered dithering is not supported, since there isn't any fast - * way to compute intercolor distances; it's unclear that ordered dither's - * fundamental assumptions even hold with an irregularly spaced color map. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - -#ifdef QUANT_2PASS_SUPPORTED - - -/* - * This module implements the well-known Heckbert paradigm for color - * quantization. Most of the ideas used here can be traced back to - * Heckbert's seminal paper - * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display", - * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304. - * - * In the first pass over the image, we accumulate a histogram showing the - * usage count of each possible color. To keep the histogram to a reasonable - * size, we reduce the precision of the input; typical practice is to retain - * 5 or 6 bits per color, so that 8 or 4 different input values are counted - * in the same histogram cell. - * - * Next, the color-selection step begins with a box representing the whole - * color space, and repeatedly splits the "largest" remaining box until we - * have as many boxes as desired colors. Then the mean color in each - * remaining box becomes one of the possible output colors. - * - * The second pass over the image maps each input pixel to the closest output - * color (optionally after applying a Floyd-Steinberg dithering correction). - * This mapping is logically trivial, but making it go fast enough requires - * considerable care. - * - * Heckbert-style quantizers vary a good deal in their policies for choosing - * the "largest" box and deciding where to cut it. The particular policies - * used here have proved out well in experimental comparisons, but better ones - * may yet be found. - * - * In earlier versions of the IJG code, this module quantized in YCbCr color - * space, processing the raw upsampled data without a color conversion step. - * This allowed the color conversion math to be done only once per colormap - * entry, not once per pixel. However, that optimization precluded other - * useful optimizations (such as merging color conversion with upsampling) - * and it also interfered with desired capabilities such as quantizing to an - * externally-supplied colormap. We have therefore abandoned that approach. - * The present code works in the post-conversion color space, typically RGB. - * - * To improve the visual quality of the results, we actually work in scaled - * RGB space, giving G distances more weight than R, and R in turn more than - * B. To do everything in integer math, we must use integer scale factors. - * The 2/3/1 scale factors used here correspond loosely to the relative - * weights of the colors in the NTSC grayscale equation. - * If you want to use this code to quantize a non-RGB color space, you'll - * probably need to change these scale factors. - */ - -#define R_SCALE 2 /* scale R distances by this much */ -#define G_SCALE 3 /* scale G distances by this much */ -#define B_SCALE 1 /* and B by this much */ - -/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined - * in jmorecfg.h. As the code stands, it will do the right thing for R,G,B - * and B,G,R orders. If you define some other weird order in jmorecfg.h, - * you'll get compile errors until you extend this logic. In that case - * you'll probably want to tweak the histogram sizes too. - */ - -#if RGB_RED == 0 -#define C0_SCALE R_SCALE -#endif -#if RGB_BLUE == 0 -#define C0_SCALE B_SCALE -#endif -#if RGB_GREEN == 1 -#define C1_SCALE G_SCALE -#endif -#if RGB_RED == 2 -#define C2_SCALE R_SCALE -#endif -#if RGB_BLUE == 2 -#define C2_SCALE B_SCALE -#endif - - -/* - * First we have the histogram data structure and routines for creating it. - * - * The number of bits of precision can be adjusted by changing these symbols. - * We recommend keeping 6 bits for G and 5 each for R and B. - * If you have plenty of memory and cycles, 6 bits all around gives marginally - * better results; if you are short of memory, 5 bits all around will save - * some space but degrade the results. - * To maintain a fully accurate histogram, we'd need to allocate a "long" - * (preferably unsigned long) for each cell. In practice this is overkill; - * we can get by with 16 bits per cell. Few of the cell counts will overflow, - * and clamping those that do overflow to the maximum value will give close- - * enough results. This reduces the recommended histogram size from 256Kb - * to 128Kb, which is a useful savings on PC-class machines. - * (In the second pass the histogram space is re-used for pixel mapping data; - * in that capacity, each cell must be able to store zero to the number of - * desired colors. 16 bits/cell is plenty for that too.) - * Since the JPEG code is intended to run in small memory model on 80x86 - * machines, we can't just allocate the histogram in one chunk. Instead - * of a true 3-D array, we use a row of pointers to 2-D arrays. Each - * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and - * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that - * on 80x86 machines, the pointer row is in near memory but the actual - * arrays are in far memory (same arrangement as we use for image arrays). - */ - -#define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */ - -/* These will do the right thing for either R,G,B or B,G,R color order, - * but you may not like the results for other color orders. - */ -#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */ -#define HIST_C1_BITS 6 /* bits of precision in G histogram */ -#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */ - -/* Number of elements along histogram axes. */ -#define HIST_C0_ELEMS (1<cquantize; - register JSAMPROW ptr; - register histptr histp; - register hist3d histogram = cquantize->histogram; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - - for (row = 0; row < num_rows; row++) { - ptr = input_buf[row]; - for (col = width; col > 0; col--) { - /* get pixel value and index into the histogram */ - histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT] - [GETJSAMPLE(ptr[1]) >> C1_SHIFT] - [GETJSAMPLE(ptr[2]) >> C2_SHIFT]; - /* increment, check for overflow and undo increment if so. */ - if (++(*histp) <= 0) - (*histp)--; - ptr += 3; - } - } -} - - -/* - * Next we have the really interesting routines: selection of a colormap - * given the completed histogram. - * These routines work with a list of "boxes", each representing a rectangular - * subset of the input color space (to histogram precision). - */ - -typedef struct { - /* The bounds of the box (inclusive); expressed as histogram indexes */ - int c0min, c0max; - int c1min, c1max; - int c2min, c2max; - /* The volume (actually 2-norm) of the box */ - INT32 volume; - /* The number of nonzero histogram cells within this box */ - long colorcount; -} box; - -typedef box * boxptr; - - -LOCAL(boxptr) -find_biggest_color_pop (boxptr boxlist, int numboxes) -/* Find the splittable box with the largest color population */ -/* Returns NULL if no splittable boxes remain */ -{ - register boxptr boxp; - register int i; - register long maxc = 0; - boxptr which = NULL; - - for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { - if (boxp->colorcount > maxc && boxp->volume > 0) { - which = boxp; - maxc = boxp->colorcount; - } - } - return which; -} - - -LOCAL(boxptr) -find_biggest_volume (boxptr boxlist, int numboxes) -/* Find the splittable box with the largest (scaled) volume */ -/* Returns NULL if no splittable boxes remain */ -{ - register boxptr boxp; - register int i; - register INT32 maxv = 0; - boxptr which = NULL; - - for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) { - if (boxp->volume > maxv) { - which = boxp; - maxv = boxp->volume; - } - } - return which; -} - - -LOCAL(void) -update_box (j_decompress_ptr cinfo, boxptr boxp) -/* Shrink the min/max bounds of a box to enclose only nonzero elements, */ -/* and recompute its volume and population */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - histptr histp; - int c0,c1,c2; - int c0min,c0max,c1min,c1max,c2min,c2max; - INT32 dist0,dist1,dist2; - long ccount; - - c0min = boxp->c0min; c0max = boxp->c0max; - c1min = boxp->c1min; c1max = boxp->c1max; - c2min = boxp->c2min; c2max = boxp->c2max; - - if (c0max > c0min) - for (c0 = c0min; c0 <= c0max; c0++) - for (c1 = c1min; c1 <= c1max; c1++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) { - boxp->c0min = c0min = c0; - goto have_c0min; - } - } - have_c0min: - if (c0max > c0min) - for (c0 = c0max; c0 >= c0min; c0--) - for (c1 = c1min; c1 <= c1max; c1++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) { - boxp->c0max = c0max = c0; - goto have_c0max; - } - } - have_c0max: - if (c1max > c1min) - for (c1 = c1min; c1 <= c1max; c1++) - for (c0 = c0min; c0 <= c0max; c0++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) { - boxp->c1min = c1min = c1; - goto have_c1min; - } - } - have_c1min: - if (c1max > c1min) - for (c1 = c1max; c1 >= c1min; c1--) - for (c0 = c0min; c0 <= c0max; c0++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) - if (*histp++ != 0) { - boxp->c1max = c1max = c1; - goto have_c1max; - } - } - have_c1max: - if (c2max > c2min) - for (c2 = c2min; c2 <= c2max; c2++) - for (c0 = c0min; c0 <= c0max; c0++) { - histp = & histogram[c0][c1min][c2]; - for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) - if (*histp != 0) { - boxp->c2min = c2min = c2; - goto have_c2min; - } - } - have_c2min: - if (c2max > c2min) - for (c2 = c2max; c2 >= c2min; c2--) - for (c0 = c0min; c0 <= c0max; c0++) { - histp = & histogram[c0][c1min][c2]; - for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS) - if (*histp != 0) { - boxp->c2max = c2max = c2; - goto have_c2max; - } - } - have_c2max: - - /* Update box volume. - * We use 2-norm rather than real volume here; this biases the method - * against making long narrow boxes, and it has the side benefit that - * a box is splittable iff norm > 0. - * Since the differences are expressed in histogram-cell units, - * we have to shift back to JSAMPLE units to get consistent distances; - * after which, we scale according to the selected distance scale factors. - */ - dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE; - dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE; - dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE; - boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2; - - /* Now scan remaining volume of box and compute population */ - ccount = 0; - for (c0 = c0min; c0 <= c0max; c0++) - for (c1 = c1min; c1 <= c1max; c1++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++, histp++) - if (*histp != 0) { - ccount++; - } - } - boxp->colorcount = ccount; -} - - -LOCAL(int) -median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes, - int desired_colors) -/* Repeatedly select and split the largest box until we have enough boxes */ -{ - int n,lb; - int c0,c1,c2,cmax; - register boxptr b1,b2; - - while (numboxes < desired_colors) { - /* Select box to split. - * Current algorithm: by population for first half, then by volume. - */ - if (numboxes*2 <= desired_colors) { - b1 = find_biggest_color_pop(boxlist, numboxes); - } else { - b1 = find_biggest_volume(boxlist, numboxes); - } - if (b1 == NULL) /* no splittable boxes left! */ - break; - b2 = &boxlist[numboxes]; /* where new box will go */ - /* Copy the color bounds to the new box. */ - b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max; - b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min; - /* Choose which axis to split the box on. - * Current algorithm: longest scaled axis. - * See notes in update_box about scaling distances. - */ - c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE; - c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE; - c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE; - /* We want to break any ties in favor of green, then red, blue last. - * This code does the right thing for R,G,B or B,G,R color orders only. - */ -#if RGB_RED == 0 - cmax = c1; n = 1; - if (c0 > cmax) { cmax = c0; n = 0; } - if (c2 > cmax) { n = 2; } -#else - cmax = c1; n = 1; - if (c2 > cmax) { cmax = c2; n = 2; } - if (c0 > cmax) { n = 0; } -#endif - /* Choose split point along selected axis, and update box bounds. - * Current algorithm: split at halfway point. - * (Since the box has been shrunk to minimum volume, - * any split will produce two nonempty subboxes.) - * Note that lb value is max for lower box, so must be < old max. - */ - switch (n) { - case 0: - lb = (b1->c0max + b1->c0min) / 2; - b1->c0max = lb; - b2->c0min = lb+1; - break; - case 1: - lb = (b1->c1max + b1->c1min) / 2; - b1->c1max = lb; - b2->c1min = lb+1; - break; - case 2: - lb = (b1->c2max + b1->c2min) / 2; - b1->c2max = lb; - b2->c2min = lb+1; - break; - } - /* Update stats for boxes */ - update_box(cinfo, b1); - update_box(cinfo, b2); - numboxes++; - } - return numboxes; -} - - -LOCAL(void) -compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor) -/* Compute representative color for a box, put it in colormap[icolor] */ -{ - /* Current algorithm: mean weighted by pixels (not colors) */ - /* Note it is important to get the rounding correct! */ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - histptr histp; - int c0,c1,c2; - int c0min,c0max,c1min,c1max,c2min,c2max; - long count; - long total = 0; - long c0total = 0; - long c1total = 0; - long c2total = 0; - - c0min = boxp->c0min; c0max = boxp->c0max; - c1min = boxp->c1min; c1max = boxp->c1max; - c2min = boxp->c2min; c2max = boxp->c2max; - - for (c0 = c0min; c0 <= c0max; c0++) - for (c1 = c1min; c1 <= c1max; c1++) { - histp = & histogram[c0][c1][c2min]; - for (c2 = c2min; c2 <= c2max; c2++) { - if ((count = *histp++) != 0) { - total += count; - c0total += ((c0 << C0_SHIFT) + ((1<>1)) * count; - c1total += ((c1 << C1_SHIFT) + ((1<>1)) * count; - c2total += ((c2 << C2_SHIFT) + ((1<>1)) * count; - } - } - } - - cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total); - cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total); - cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total); -} - - -LOCAL(void) -select_colors (j_decompress_ptr cinfo, int desired_colors) -/* Master routine for color selection */ -{ - boxptr boxlist; - int numboxes; - int i; - - /* Allocate workspace for box list */ - boxlist = (boxptr) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box)); - /* Initialize one box containing whole space */ - numboxes = 1; - boxlist[0].c0min = 0; - boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT; - boxlist[0].c1min = 0; - boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT; - boxlist[0].c2min = 0; - boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT; - /* Shrink it to actually-used volume and set its statistics */ - update_box(cinfo, & boxlist[0]); - /* Perform median-cut to produce final box list */ - numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors); - /* Compute the representative color for each box, fill colormap */ - for (i = 0; i < numboxes; i++) - compute_color(cinfo, & boxlist[i], i); - cinfo->actual_number_of_colors = numboxes; - TRACEMS1(cinfo, 1, JTRC_QUANT_SELECTED, numboxes); -} - - -/* - * These routines are concerned with the time-critical task of mapping input - * colors to the nearest color in the selected colormap. - * - * We re-use the histogram space as an "inverse color map", essentially a - * cache for the results of nearest-color searches. All colors within a - * histogram cell will be mapped to the same colormap entry, namely the one - * closest to the cell's center. This may not be quite the closest entry to - * the actual input color, but it's almost as good. A zero in the cache - * indicates we haven't found the nearest color for that cell yet; the array - * is cleared to zeroes before starting the mapping pass. When we find the - * nearest color for a cell, its colormap index plus one is recorded in the - * cache for future use. The pass2 scanning routines call fill_inverse_cmap - * when they need to use an unfilled entry in the cache. - * - * Our method of efficiently finding nearest colors is based on the "locally - * sorted search" idea described by Heckbert and on the incremental distance - * calculation described by Spencer W. Thomas in chapter III.1 of Graphics - * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that - * the distances from a given colormap entry to each cell of the histogram can - * be computed quickly using an incremental method: the differences between - * distances to adjacent cells themselves differ by a constant. This allows a - * fairly fast implementation of the "brute force" approach of computing the - * distance from every colormap entry to every histogram cell. Unfortunately, - * it needs a work array to hold the best-distance-so-far for each histogram - * cell (because the inner loop has to be over cells, not colormap entries). - * The work array elements have to be INT32s, so the work array would need - * 256Kb at our recommended precision. This is not feasible in DOS machines. - * - * To get around these problems, we apply Thomas' method to compute the - * nearest colors for only the cells within a small subbox of the histogram. - * The work array need be only as big as the subbox, so the memory usage - * problem is solved. Furthermore, we need not fill subboxes that are never - * referenced in pass2; many images use only part of the color gamut, so a - * fair amount of work is saved. An additional advantage of this - * approach is that we can apply Heckbert's locality criterion to quickly - * eliminate colormap entries that are far away from the subbox; typically - * three-fourths of the colormap entries are rejected by Heckbert's criterion, - * and we need not compute their distances to individual cells in the subbox. - * The speed of this approach is heavily influenced by the subbox size: too - * small means too much overhead, too big loses because Heckbert's criterion - * can't eliminate as many colormap entries. Empirically the best subbox - * size seems to be about 1/512th of the histogram (1/8th in each direction). - * - * Thomas' article also describes a refined method which is asymptotically - * faster than the brute-force method, but it is also far more complex and - * cannot efficiently be applied to small subboxes. It is therefore not - * useful for programs intended to be portable to DOS machines. On machines - * with plenty of memory, filling the whole histogram in one shot with Thomas' - * refined method might be faster than the present code --- but then again, - * it might not be any faster, and it's certainly more complicated. - */ - - -/* log2(histogram cells in update box) for each axis; this can be adjusted */ -#define BOX_C0_LOG (HIST_C0_BITS-3) -#define BOX_C1_LOG (HIST_C1_BITS-3) -#define BOX_C2_LOG (HIST_C2_BITS-3) - -#define BOX_C0_ELEMS (1<actual_number_of_colors; - int maxc0, maxc1, maxc2; - int centerc0, centerc1, centerc2; - int i, x, ncolors; - INT32 minmaxdist, min_dist, max_dist, tdist; - INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */ - - /* Compute true coordinates of update box's upper corner and center. - * Actually we compute the coordinates of the center of the upper-corner - * histogram cell, which are the upper bounds of the volume we care about. - * Note that since ">>" rounds down, the "center" values may be closer to - * min than to max; hence comparisons to them must be "<=", not "<". - */ - maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT)); - centerc0 = (minc0 + maxc0) >> 1; - maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT)); - centerc1 = (minc1 + maxc1) >> 1; - maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT)); - centerc2 = (minc2 + maxc2) >> 1; - - /* For each color in colormap, find: - * 1. its minimum squared-distance to any point in the update box - * (zero if color is within update box); - * 2. its maximum squared-distance to any point in the update box. - * Both of these can be found by considering only the corners of the box. - * We save the minimum distance for each color in mindist[]; - * only the smallest maximum distance is of interest. - */ - minmaxdist = 0x7FFFFFFFL; - - for (i = 0; i < numcolors; i++) { - /* We compute the squared-c0-distance term, then add in the other two. */ - x = GETJSAMPLE(cinfo->colormap[0][i]); - if (x < minc0) { - tdist = (x - minc0) * C0_SCALE; - min_dist = tdist*tdist; - tdist = (x - maxc0) * C0_SCALE; - max_dist = tdist*tdist; - } else if (x > maxc0) { - tdist = (x - maxc0) * C0_SCALE; - min_dist = tdist*tdist; - tdist = (x - minc0) * C0_SCALE; - max_dist = tdist*tdist; - } else { - /* within cell range so no contribution to min_dist */ - min_dist = 0; - if (x <= centerc0) { - tdist = (x - maxc0) * C0_SCALE; - max_dist = tdist*tdist; - } else { - tdist = (x - minc0) * C0_SCALE; - max_dist = tdist*tdist; - } - } - - x = GETJSAMPLE(cinfo->colormap[1][i]); - if (x < minc1) { - tdist = (x - minc1) * C1_SCALE; - min_dist += tdist*tdist; - tdist = (x - maxc1) * C1_SCALE; - max_dist += tdist*tdist; - } else if (x > maxc1) { - tdist = (x - maxc1) * C1_SCALE; - min_dist += tdist*tdist; - tdist = (x - minc1) * C1_SCALE; - max_dist += tdist*tdist; - } else { - /* within cell range so no contribution to min_dist */ - if (x <= centerc1) { - tdist = (x - maxc1) * C1_SCALE; - max_dist += tdist*tdist; - } else { - tdist = (x - minc1) * C1_SCALE; - max_dist += tdist*tdist; - } - } - - x = GETJSAMPLE(cinfo->colormap[2][i]); - if (x < minc2) { - tdist = (x - minc2) * C2_SCALE; - min_dist += tdist*tdist; - tdist = (x - maxc2) * C2_SCALE; - max_dist += tdist*tdist; - } else if (x > maxc2) { - tdist = (x - maxc2) * C2_SCALE; - min_dist += tdist*tdist; - tdist = (x - minc2) * C2_SCALE; - max_dist += tdist*tdist; - } else { - /* within cell range so no contribution to min_dist */ - if (x <= centerc2) { - tdist = (x - maxc2) * C2_SCALE; - max_dist += tdist*tdist; - } else { - tdist = (x - minc2) * C2_SCALE; - max_dist += tdist*tdist; - } - } - - mindist[i] = min_dist; /* save away the results */ - if (max_dist < minmaxdist) - minmaxdist = max_dist; - } - - /* Now we know that no cell in the update box is more than minmaxdist - * away from some colormap entry. Therefore, only colors that are - * within minmaxdist of some part of the box need be considered. - */ - ncolors = 0; - for (i = 0; i < numcolors; i++) { - if (mindist[i] <= minmaxdist) - colorlist[ncolors++] = (JSAMPLE) i; - } - return ncolors; -} - - -LOCAL(void) -find_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2, - int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[]) -/* Find the closest colormap entry for each cell in the update box, - * given the list of candidate colors prepared by find_nearby_colors. - * Return the indexes of the closest entries in the bestcolor[] array. - * This routine uses Thomas' incremental distance calculation method to - * find the distance from a colormap entry to successive cells in the box. - */ -{ - int ic0, ic1, ic2; - int i, icolor; - register INT32 * bptr; /* pointer into bestdist[] array */ - JSAMPLE * cptr; /* pointer into bestcolor[] array */ - INT32 dist0, dist1; /* initial distance values */ - register INT32 dist2; /* current distance in inner loop */ - INT32 xx0, xx1; /* distance increments */ - register INT32 xx2; - INT32 inc0, inc1, inc2; /* initial values for increments */ - /* This array holds the distance to the nearest-so-far color for each cell */ - INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; - - /* Initialize best-distance for each cell of the update box */ - bptr = bestdist; - for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--) - *bptr++ = 0x7FFFFFFFL; - - /* For each color selected by find_nearby_colors, - * compute its distance to the center of each cell in the box. - * If that's less than best-so-far, update best distance and color number. - */ - - /* Nominal steps between cell centers ("x" in Thomas article) */ -#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE) -#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE) -#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE) - - for (i = 0; i < numcolors; i++) { - icolor = GETJSAMPLE(colorlist[i]); - /* Compute (square of) distance from minc0/c1/c2 to this color */ - inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE; - dist0 = inc0*inc0; - inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE; - dist0 += inc1*inc1; - inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE; - dist0 += inc2*inc2; - /* Form the initial difference increments */ - inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0; - inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1; - inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2; - /* Now loop over all cells in box, updating distance per Thomas method */ - bptr = bestdist; - cptr = bestcolor; - xx0 = inc0; - for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) { - dist1 = dist0; - xx1 = inc1; - for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) { - dist2 = dist1; - xx2 = inc2; - for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) { - if (dist2 < *bptr) { - *bptr = dist2; - *cptr = (JSAMPLE) icolor; - } - dist2 += xx2; - xx2 += 2 * STEP_C2 * STEP_C2; - bptr++; - cptr++; - } - dist1 += xx1; - xx1 += 2 * STEP_C1 * STEP_C1; - } - dist0 += xx0; - xx0 += 2 * STEP_C0 * STEP_C0; - } - } -} - - -LOCAL(void) -fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2) -/* Fill the inverse-colormap entries in the update box that contains */ -/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */ -/* we can fill as many others as we wish.) */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - int minc0, minc1, minc2; /* lower left corner of update box */ - int ic0, ic1, ic2; - register JSAMPLE * cptr; /* pointer into bestcolor[] array */ - register histptr cachep; /* pointer into main cache array */ - /* This array lists the candidate colormap indexes. */ - JSAMPLE colorlist[MAXNUMCOLORS]; - int numcolors; /* number of candidate colors */ - /* This array holds the actually closest colormap index for each cell. */ - JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS]; - - /* Convert cell coordinates to update box ID */ - c0 >>= BOX_C0_LOG; - c1 >>= BOX_C1_LOG; - c2 >>= BOX_C2_LOG; - - /* Compute true coordinates of update box's origin corner. - * Actually we compute the coordinates of the center of the corner - * histogram cell, which are the lower bounds of the volume we care about. - */ - minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1); - minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1); - minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1); - - /* Determine which colormap entries are close enough to be candidates - * for the nearest entry to some cell in the update box. - */ - numcolors = find_nearby_colors(cinfo, minc0, minc1, minc2, colorlist); - - /* Determine the actually nearest colors. */ - find_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist, - bestcolor); - - /* Save the best color numbers (plus 1) in the main cache array */ - c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ - c1 <<= BOX_C1_LOG; - c2 <<= BOX_C2_LOG; - cptr = bestcolor; - for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) { - for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { - cachep = & histogram[c0+ic0][c1+ic1][c2]; - for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) { - *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1); - } - } - } -} - - -/* - * Map some rows of pixels to the output colormapped representation. - */ - -METHODDEF(void) -pass2_no_dither (j_decompress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) -/* This version performs no dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - register JSAMPROW inptr, outptr; - register histptr cachep; - register int c0, c1, c2; - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - - for (row = 0; row < num_rows; row++) { - inptr = input_buf[row]; - outptr = output_buf[row]; - for (col = width; col > 0; col--) { - /* get pixel value and index into the cache */ - c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT; - c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT; - c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT; - cachep = & histogram[c0][c1][c2]; - /* If we have not seen this color before, find nearest colormap entry */ - /* and update the cache */ - if (*cachep == 0) - fill_inverse_cmap(cinfo, c0,c1,c2); - /* Now emit the colormap index for this cell */ - *outptr++ = (JSAMPLE) (*cachep - 1); - } - } -} - - -METHODDEF(void) -pass2_fs_dither (j_decompress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows) -/* This version performs Floyd-Steinberg dithering */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ - LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ - LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ - register FSERRPTR errorptr; /* => fserrors[] at column before current */ - JSAMPROW inptr; /* => current input pixel */ - JSAMPROW outptr; /* => current output pixel */ - histptr cachep; - int dir; /* +1 or -1 depending on direction */ - int dir3; /* 3*dir, for advancing inptr & errorptr */ - int row; - JDIMENSION col; - JDIMENSION width = cinfo->output_width; - JSAMPLE *range_limit = cinfo->sample_range_limit; - int *error_limit = cquantize->error_limiter; - JSAMPROW colormap0 = cinfo->colormap[0]; - JSAMPROW colormap1 = cinfo->colormap[1]; - JSAMPROW colormap2 = cinfo->colormap[2]; - SHIFT_TEMPS - - for (row = 0; row < num_rows; row++) { - inptr = input_buf[row]; - outptr = output_buf[row]; - if (cquantize->on_odd_row) { - /* work right to left in this row */ - inptr += (width-1) * 3; /* so point to rightmost pixel */ - outptr += width-1; - dir = -1; - dir3 = -3; - errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */ - cquantize->on_odd_row = FALSE; /* flip for next time */ - } else { - /* work left to right in this row */ - dir = 1; - dir3 = 3; - errorptr = cquantize->fserrors; /* => entry before first real column */ - cquantize->on_odd_row = TRUE; /* flip for next time */ - } - /* Preset error values: no error propagated to first pixel from left */ - cur0 = cur1 = cur2 = 0; - /* and no error propagated to row below yet */ - belowerr0 = belowerr1 = belowerr2 = 0; - bpreverr0 = bpreverr1 = bpreverr2 = 0; - - for (col = width; col > 0; col--) { - /* curN holds the error propagated from the previous pixel on the - * current line. Add the error propagated from the previous line - * to form the complete error correction term for this pixel, and - * round the error term (which is expressed * 16) to an integer. - * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct - * for either sign of the error value. - * Note: errorptr points to *previous* column's array entry. - */ - cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4); - cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4); - cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4); - /* Limit the error using transfer function set by init_error_limit. - * See comments with init_error_limit for rationale. - */ - cur0 = error_limit[cur0]; - cur1 = error_limit[cur1]; - cur2 = error_limit[cur2]; - /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. - * The maximum error is +- MAXJSAMPLE (or less with error limiting); - * this sets the required size of the range_limit array. - */ - cur0 += GETJSAMPLE(inptr[0]); - cur1 += GETJSAMPLE(inptr[1]); - cur2 += GETJSAMPLE(inptr[2]); - cur0 = GETJSAMPLE(range_limit[cur0]); - cur1 = GETJSAMPLE(range_limit[cur1]); - cur2 = GETJSAMPLE(range_limit[cur2]); - /* Index into the cache with adjusted pixel value */ - cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT]; - /* If we have not seen this color before, find nearest colormap */ - /* entry and update the cache */ - if (*cachep == 0) - fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT); - /* Now emit the colormap index for this cell */ - { register int pixcode = *cachep - 1; - *outptr = (JSAMPLE) pixcode; - /* Compute representation error for this pixel */ - cur0 -= GETJSAMPLE(colormap0[pixcode]); - cur1 -= GETJSAMPLE(colormap1[pixcode]); - cur2 -= GETJSAMPLE(colormap2[pixcode]); - } - /* Compute error fractions to be propagated to adjacent pixels. - * Add these into the running sums, and simultaneously shift the - * next-line error sums left by 1 column. - */ - { register LOCFSERROR bnexterr, delta; - - bnexterr = cur0; /* Process component 0 */ - delta = cur0 * 2; - cur0 += delta; /* form error * 3 */ - errorptr[0] = (FSERROR) (bpreverr0 + cur0); - cur0 += delta; /* form error * 5 */ - bpreverr0 = belowerr0 + cur0; - belowerr0 = bnexterr; - cur0 += delta; /* form error * 7 */ - bnexterr = cur1; /* Process component 1 */ - delta = cur1 * 2; - cur1 += delta; /* form error * 3 */ - errorptr[1] = (FSERROR) (bpreverr1 + cur1); - cur1 += delta; /* form error * 5 */ - bpreverr1 = belowerr1 + cur1; - belowerr1 = bnexterr; - cur1 += delta; /* form error * 7 */ - bnexterr = cur2; /* Process component 2 */ - delta = cur2 * 2; - cur2 += delta; /* form error * 3 */ - errorptr[2] = (FSERROR) (bpreverr2 + cur2); - cur2 += delta; /* form error * 5 */ - bpreverr2 = belowerr2 + cur2; - belowerr2 = bnexterr; - cur2 += delta; /* form error * 7 */ - } - /* At this point curN contains the 7/16 error value to be propagated - * to the next pixel on the current line, and all the errors for the - * next line have been shifted over. We are therefore ready to move on. - */ - inptr += dir3; /* Advance pixel pointers to next column */ - outptr += dir; - errorptr += dir3; /* advance errorptr to current column */ - } - /* Post-loop cleanup: we must unload the final error values into the - * final fserrors[] entry. Note we need not unload belowerrN because - * it is for the dummy column before or after the actual array. - */ - errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */ - errorptr[1] = (FSERROR) bpreverr1; - errorptr[2] = (FSERROR) bpreverr2; - } -} - - -/* - * Initialize the error-limiting transfer function (lookup table). - * The raw F-S error computation can potentially compute error values of up to - * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be - * much less, otherwise obviously wrong pixels will be created. (Typical - * effects include weird fringes at color-area boundaries, isolated bright - * pixels in a dark area, etc.) The standard advice for avoiding this problem - * is to ensure that the "corners" of the color cube are allocated as output - * colors; then repeated errors in the same direction cannot cause cascading - * error buildup. However, that only prevents the error from getting - * completely out of hand; Aaron Giles reports that error limiting improves - * the results even with corner colors allocated. - * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty - * well, but the smoother transfer function used below is even better. Thanks - * to Aaron Giles for this idea. - */ - -LOCAL(void) -init_error_limit (j_decompress_ptr cinfo) -/* Allocate and fill in the error_limiter table */ -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - int * table; - int in, out; - - table = (int *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int)); - table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ - cquantize->error_limiter = table; - -#define STEPSIZE ((MAXJSAMPLE+1)/16) - /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ - out = 0; - for (in = 0; in < STEPSIZE; in++, out++) { - table[in] = out; table[-in] = -out; - } - /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ - for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) { - table[in] = out; table[-in] = -out; - } - /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ - for (; in <= MAXJSAMPLE; in++) { - table[in] = out; table[-in] = -out; - } -#undef STEPSIZE -} - - -/* - * Finish up at the end of each pass. - */ - -METHODDEF(void) -finish_pass1 (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - - /* Select the representative colors and fill in cinfo->colormap */ - cinfo->colormap = cquantize->sv_colormap; - select_colors(cinfo, cquantize->desired); - /* Force next pass to zero the color index table */ - cquantize->needs_zeroed = TRUE; -} - - -METHODDEF(void) -finish_pass2 (j_decompress_ptr cinfo) -{ - /* no work */ -} - - -/* - * Initialize for each processing pass. - */ - -METHODDEF(void) -start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - hist3d histogram = cquantize->histogram; - int i; - - /* Only F-S dithering or no dithering is supported. */ - /* If user asks for ordered dither, give him F-S. */ - if (cinfo->dither_mode != JDITHER_NONE) - cinfo->dither_mode = JDITHER_FS; - - if (is_pre_scan) { - /* Set up method pointers */ - cquantize->pub.color_quantize = prescan_quantize; - cquantize->pub.finish_pass = finish_pass1; - cquantize->needs_zeroed = TRUE; /* Always zero histogram */ - } else { - /* Set up method pointers */ - if (cinfo->dither_mode == JDITHER_FS) - cquantize->pub.color_quantize = pass2_fs_dither; - else - cquantize->pub.color_quantize = pass2_no_dither; - cquantize->pub.finish_pass = finish_pass2; - - /* Make sure color count is acceptable */ - i = cinfo->actual_number_of_colors; - if (i < 1) - ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 1); - if (i > MAXNUMCOLORS) - ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); - - if (cinfo->dither_mode == JDITHER_FS) { - size_t arraysize = (size_t) ((cinfo->output_width + 2) * - (3 * SIZEOF(FSERROR))); - /* Allocate Floyd-Steinberg workspace if we didn't already. */ - if (cquantize->fserrors == NULL) - cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) - ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize); - /* Initialize the propagated errors to zero. */ - FMEMZERO((void FAR *) cquantize->fserrors, arraysize); - /* Make the error-limit table if we didn't already. */ - if (cquantize->error_limiter == NULL) - init_error_limit(cinfo); - cquantize->on_odd_row = FALSE; - } - - } - /* Zero the histogram or inverse color map, if necessary */ - if (cquantize->needs_zeroed) { - for (i = 0; i < HIST_C0_ELEMS; i++) { - FMEMZERO((void FAR *) histogram[i], - HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); - } - cquantize->needs_zeroed = FALSE; - } -} - - -/* - * Switch to a new external colormap between output passes. - */ - -METHODDEF(void) -new_color_map_2_quant (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; - - /* Reset the inverse color map */ - cquantize->needs_zeroed = TRUE; -} - - -/* - * Module initialization routine for 2-pass color quantization. - */ - -GLOBAL(void) -jinit_2pass_quantizer (j_decompress_ptr cinfo) -{ - my_cquantize_ptr cquantize; - int i; - - cquantize = (my_cquantize_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_cquantizer)); - cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize; - cquantize->pub.start_pass = start_pass_2_quant; - cquantize->pub.new_color_map = new_color_map_2_quant; - cquantize->fserrors = NULL; /* flag optional arrays not allocated */ - cquantize->error_limiter = NULL; - - /* Make sure jdmaster didn't give me a case I can't handle */ - if (cinfo->out_color_components != 3) - ERREXIT(cinfo, JERR_NOTIMPL); - - /* Allocate the histogram/inverse colormap storage */ - cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d)); - for (i = 0; i < HIST_C0_ELEMS; i++) { - cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell)); - } - cquantize->needs_zeroed = TRUE; /* histogram is garbage now */ - - /* Allocate storage for the completed colormap, if required. - * We do this now since it is FAR storage and may affect - * the memory manager's space calculations. - */ - if (cinfo->enable_2pass_quant) { - /* Make sure color count is acceptable */ - int desired = cinfo->desired_number_of_colors; - /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */ - if (desired < 8) - ERREXIT1(cinfo, JERR_QUANT_FEW_COLORS, 8); - /* Make sure colormap indexes can be represented by JSAMPLEs */ - if (desired > MAXNUMCOLORS) - ERREXIT1(cinfo, JERR_QUANT_MANY_COLORS, MAXNUMCOLORS); - cquantize->sv_colormap = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3); - cquantize->desired = desired; - } else - cquantize->sv_colormap = NULL; - - /* Only F-S dithering or no dithering is supported. */ - /* If user asks for ordered dither, give him F-S. */ - if (cinfo->dither_mode != JDITHER_NONE) - cinfo->dither_mode = JDITHER_FS; - - /* Allocate Floyd-Steinberg workspace if necessary. - * This isn't really needed until pass 2, but again it is FAR storage. - * Although we will cope with a later change in dither_mode, - * we do not promise to honor max_memory_to_use if dither_mode changes. - */ - if (cinfo->dither_mode == JDITHER_FS) { - cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR)))); - /* Might as well create the error-limiting table too. */ - init_error_limit(cinfo); - } -} - -#endif /* QUANT_2PASS_SUPPORTED */ diff --git a/libraries/jpeg/jutils.c b/libraries/jpeg/jutils.c deleted file mode 100644 index 5b16b6d03..000000000 --- a/libraries/jpeg/jutils.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * jutils.c - * - * Copyright (C) 1991-1996, Thomas G. Lane. - * Modified 2009-2011 by Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains tables and miscellaneous utility routines needed - * for both compression and decompression. - * Note we prefix all global names with "j" to minimize conflicts with - * a surrounding application. - */ - -#define JPEG_INTERNALS -#include "jinclude.h" -#include "jpeglib.h" - - -/* - * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element - * of a DCT block read in natural order (left to right, top to bottom). - */ - -#if 0 /* This table is not actually needed in v6a */ - -const int jpeg_zigzag_order[DCTSIZE2] = { - 0, 1, 5, 6, 14, 15, 27, 28, - 2, 4, 7, 13, 16, 26, 29, 42, - 3, 8, 12, 17, 25, 30, 41, 43, - 9, 11, 18, 24, 31, 40, 44, 53, - 10, 19, 23, 32, 39, 45, 52, 54, - 20, 22, 33, 38, 46, 51, 55, 60, - 21, 34, 37, 47, 50, 56, 59, 61, - 35, 36, 48, 49, 57, 58, 62, 63 -}; - -#endif - -/* - * jpeg_natural_order[i] is the natural-order position of the i'th element - * of zigzag order. - * - * When reading corrupted data, the Huffman decoders could attempt - * to reference an entry beyond the end of this array (if the decoded - * zero run length reaches past the end of the block). To prevent - * wild stores without adding an inner-loop test, we put some extra - * "63"s after the real entries. This will cause the extra coefficient - * to be stored in location 63 of the block, not somewhere random. - * The worst case would be a run-length of 15, which means we need 16 - * fake entries. - */ - -const int jpeg_natural_order[DCTSIZE2+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 -}; - -const int jpeg_natural_order7[7*7+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 14, 21, 28, 35, - 42, 49, 50, 43, 36, 29, 22, 30, - 37, 44, 51, 52, 45, 38, 46, 53, - 54, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 -}; - -const int jpeg_natural_order6[6*6+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 41, 34, 27, - 20, 13, 21, 28, 35, 42, 43, 36, - 29, 37, 44, 45, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 -}; - -const int jpeg_natural_order5[5*5+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 12, - 19, 26, 33, 34, 27, 20, 28, 35, - 36, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 -}; - -const int jpeg_natural_order4[4*4+16] = { - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 25, 18, 11, 19, 26, 27, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 -}; - -const int jpeg_natural_order3[3*3+16] = { - 0, 1, 8, 16, 9, 2, 10, 17, - 18, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 -}; - -const int jpeg_natural_order2[2*2+16] = { - 0, 1, 8, 9, - 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */ - 63, 63, 63, 63, 63, 63, 63, 63 -}; - - -/* - * Arithmetic utilities - */ - -GLOBAL(long) -jdiv_round_up (long a, long b) -/* Compute a/b rounded up to next integer, ie, ceil(a/b) */ -/* Assumes a >= 0, b > 0 */ -{ - return (a + b - 1L) / b; -} - - -GLOBAL(long) -jround_up (long a, long b) -/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */ -/* Assumes a >= 0, b > 0 */ -{ - a += b - 1L; - return a - (a % b); -} - - -/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays - * and coefficient-block arrays. This won't work on 80x86 because the arrays - * are FAR and we're assuming a small-pointer memory model. However, some - * DOS compilers provide far-pointer versions of memcpy() and memset() even - * in the small-model libraries. These will be used if USE_FMEM is defined. - * Otherwise, the routines below do it the hard way. (The performance cost - * is not all that great, because these routines aren't very heavily used.) - */ - -#ifndef NEED_FAR_POINTERS /* normal case, same as regular macro */ -#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size) -#else /* 80x86 case, define if we can */ -#ifdef USE_FMEM -#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) -#else -/* This function is for use by the FMEMZERO macro defined in jpegint.h. - * Do not call this function directly, use the FMEMZERO macro instead. - */ -GLOBAL(void) -jzero_far (void FAR * target, size_t bytestozero) -/* Zero out a chunk of FAR memory. */ -/* This might be sample-array data, block-array data, or alloc_large data. */ -{ - register char FAR * ptr = (char FAR *) target; - register size_t count; - - for (count = bytestozero; count > 0; count--) { - *ptr++ = 0; - } -} -#endif -#endif - - -GLOBAL(void) -jcopy_sample_rows (JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, - int num_rows, JDIMENSION num_cols) -/* Copy some rows of samples from one place to another. - * num_rows rows are copied from input_array[source_row++] - * to output_array[dest_row++]; these areas may overlap for duplication. - * The source and destination arrays must be at least as wide as num_cols. - */ -{ - register JSAMPROW inptr, outptr; -#ifdef FMEMCOPY - register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE)); -#else - register JDIMENSION count; -#endif - register int row; - - input_array += source_row; - output_array += dest_row; - - for (row = num_rows; row > 0; row--) { - inptr = *input_array++; - outptr = *output_array++; -#ifdef FMEMCOPY - FMEMCOPY(outptr, inptr, count); -#else - for (count = num_cols; count > 0; count--) - *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */ -#endif - } -} - - -GLOBAL(void) -jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, - JDIMENSION num_blocks) -/* Copy a row of coefficient blocks from one place to another. */ -{ -#ifdef FMEMCOPY - FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF))); -#else - register JCOEFPTR inptr, outptr; - register long count; - - inptr = (JCOEFPTR) input_row; - outptr = (JCOEFPTR) output_row; - for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) { - *outptr++ = *inptr++; - } -#endif -} diff --git a/libraries/jpeg/jversion.h b/libraries/jpeg/jversion.h deleted file mode 100644 index d096384f7..000000000 --- a/libraries/jpeg/jversion.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * jversion.h - * - * Copyright (C) 1991-2018, Thomas G. Lane, Guido Vollbeding. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains software version identification. - */ - - -#define JVERSION "9c 14-Jan-2018" - -#define JCOPYRIGHT "Copyright (C) 2018, Thomas G. Lane, Guido Vollbeding" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8ecc719aa..7072b143e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -319,7 +319,7 @@ add_custom_target( revision_check ALL # required libraries -set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${ZLIB_LIBRARIES}" "${JPEG_LIBRARIES}" "${BZIP2_LIBRARIES}" "${CMAKE_DL_LIBS}" "${DRPC_LIBRARIES}") +set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${ZLIB_LIBRARIES}" "${BZIP2_LIBRARIES}" "${CMAKE_DL_LIBS}" "${DRPC_LIBRARIES}") if (HAVE_VULKAN) list( APPEND PROJECT_LIBRARIES "zvulkan" ) endif() @@ -387,7 +387,7 @@ if (TARGET WebP::webp) endif() endif() -include_directories( SYSTEM "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${JPEG_INCLUDE_DIR}" "${ZMUSIC_INCLUDE_DIR}" "${DRPC_INCLUDE_DIR}") +include_directories( SYSTEM "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${ZMUSIC_INCLUDE_DIR}" "${DRPC_INCLUDE_DIR}") if( ${HAVE_VM_JIT} ) add_definitions( -DHAVE_VM_JIT ) @@ -1021,7 +1021,6 @@ set (PCH_SOURCES common/textures/formats/flattexture.cpp common/textures/formats/fontchars.cpp common/textures/formats/imgztexture.cpp - common/textures/formats/jpegtexture.cpp common/textures/formats/md5check.cpp common/textures/formats/multipatchtexture.cpp common/textures/formats/patchtexture.cpp diff --git a/src/common/rendering/gl/gl_hwtexture.cpp b/src/common/rendering/gl/gl_hwtexture.cpp index 37b066155..8fe1b074b 100644 --- a/src/common/rendering/gl/gl_hwtexture.cpp +++ b/src/common/rendering/gl/gl_hwtexture.cpp @@ -45,6 +45,7 @@ #include "gl_renderstate.h" #include "gl_samplers.h" #include "gl_hwtexture.h" +#include "printf.h" namespace OpenGLRenderer { diff --git a/src/common/textures/formats/jpegtexture.cpp b/src/common/textures/formats/jpegtexture.cpp deleted file mode 100644 index 964985421..000000000 --- a/src/common/textures/formats/jpegtexture.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/* -** jpegtexture.cpp -** Texture class for JPEG images -** -**--------------------------------------------------------------------------- -** Copyright 2005-2016 Randy Heit -** Copyright 2005-2019 Christoph Oelckers -** 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. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 -extern "C" -{ -#include -} - -#include "files.h" -#include "filesystem.h" -#include "printf.h" -#include "bitmap.h" -#include "imagehelpers.h" -#include "image.h" -#include "m_swap.h" - - -struct FLumpSourceMgr : public jpeg_source_mgr -{ - FileReader *Lump; - JOCTET Buffer[4096]; - bool StartOfFile; - - FLumpSourceMgr (FileReader *lump, j_decompress_ptr cinfo); - static void InitSource (j_decompress_ptr cinfo); - static boolean FillInputBuffer (j_decompress_ptr cinfo); - static void SkipInputData (j_decompress_ptr cinfo, long num_bytes); - static void TermSource (j_decompress_ptr cinfo); -}; - - -//========================================================================== -// -// -// -//========================================================================== - -void FLumpSourceMgr::InitSource (j_decompress_ptr cinfo) -{ - ((FLumpSourceMgr *)(cinfo->src))->StartOfFile = true; -} - -//========================================================================== -// -// -// -//========================================================================== - -boolean FLumpSourceMgr::FillInputBuffer (j_decompress_ptr cinfo) -{ - FLumpSourceMgr *me = (FLumpSourceMgr *)(cinfo->src); - auto nbytes = me->Lump->Read (me->Buffer, sizeof(me->Buffer)); - - if (nbytes <= 0) - { - me->Buffer[0] = (JOCTET)0xFF; - me->Buffer[1] = (JOCTET)JPEG_EOI; - nbytes = 2; - } - me->next_input_byte = me->Buffer; - me->bytes_in_buffer = nbytes; - me->StartOfFile = false; - return TRUE; -} - -//========================================================================== -// -// -// -//========================================================================== - -void FLumpSourceMgr::SkipInputData (j_decompress_ptr cinfo, long num_bytes) -{ - FLumpSourceMgr *me = (FLumpSourceMgr *)(cinfo->src); - if (num_bytes <= (long)me->bytes_in_buffer) - { - me->bytes_in_buffer -= num_bytes; - me->next_input_byte += num_bytes; - } - else - { - num_bytes -= (long)me->bytes_in_buffer; - me->Lump->Seek (num_bytes, FileReader::SeekCur); - FillInputBuffer (cinfo); - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FLumpSourceMgr::TermSource (j_decompress_ptr cinfo) -{ -} - -//========================================================================== -// -// -// -//========================================================================== - -FLumpSourceMgr::FLumpSourceMgr (FileReader *lump, j_decompress_ptr cinfo) -: Lump (lump) -{ - cinfo->src = this; - init_source = InitSource; - fill_input_buffer = FillInputBuffer; - skip_input_data = SkipInputData; - resync_to_restart = jpeg_resync_to_restart; - term_source = TermSource; - bytes_in_buffer = 0; - next_input_byte = NULL; -} - -//========================================================================== -// -// -// -//========================================================================== - -void JPEG_ErrorExit (j_common_ptr cinfo) -{ - (*cinfo->err->output_message) (cinfo); - throw -1; -} - -//========================================================================== -// -// -// -//========================================================================== - -void JPEG_OutputMessage (j_common_ptr cinfo) -{ - char buffer[JMSG_LENGTH_MAX]; - - (*cinfo->err->format_message) (cinfo, buffer); - Printf (TEXTCOLOR_ORANGE "JPEG failure: %s\n", buffer); -} - -//========================================================================== -// -// A JPEG texture -// -//========================================================================== - -class FJPEGTexture : public FImageSource -{ -public: - FJPEGTexture (int lumpnum, int width, int height); - - int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override; - PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; -}; - -//========================================================================== -// -// -// -//========================================================================== - -FImageSource *JPEGImage_TryCreate(FileReader & data, int lumpnum) -{ - union - { - uint32_t dw; - uint16_t w[2]; - uint8_t b[4]; - } first4bytes; - - data.Seek(0, FileReader::SeekSet); - if (data.Read(&first4bytes, 4) < 4) return NULL; - - if (first4bytes.b[0] != 0xFF || first4bytes.b[1] != 0xD8 || first4bytes.b[2] != 0xFF) - return NULL; - - // Find the SOFn marker to extract the image dimensions, - // where n is 0, 1, or 2 (other types are unsupported). - while ((unsigned)first4bytes.b[3] - 0xC0 >= 3) - { - if (data.Read (first4bytes.w, 2) != 2) - { - return NULL; - } - data.Seek (BigShort(first4bytes.w[0]) - 2, FileReader::SeekCur); - if (data.Read (first4bytes.b + 2, 2) != 2 || first4bytes.b[2] != 0xFF) - { - return NULL; - } - } - if (data.Read (first4bytes.b, 3) != 3) - { - return NULL; - } - if (BigShort (first4bytes.w[0]) < 5) - { - return NULL; - } - if (data.Read (first4bytes.b, 4) != 4) - { - return NULL; - } - return new FJPEGTexture (lumpnum, BigShort(first4bytes.w[1]), BigShort(first4bytes.w[0])); -} - -//========================================================================== -// -// -// -//========================================================================== - -FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) -: FImageSource(lumpnum) -{ - bMasked = false; - - Width = width; - Height = height; -} - -//========================================================================== -// -// -// -//========================================================================== - -PalettedPixels FJPEGTexture::CreatePalettedPixels(int conversion, int frame) -{ - auto lump = fileSystem.OpenFileReader (SourceLump); - JSAMPLE *buff = NULL; - - jpeg_decompress_struct cinfo; - jpeg_error_mgr jerr; - - PalettedPixels Pixels(Width * Height); - memset (Pixels.Data(), 0xBA, Width * Height); - - cinfo.err = jpeg_std_error(&jerr); - cinfo.err->output_message = JPEG_OutputMessage; - cinfo.err->error_exit = JPEG_ErrorExit; - jpeg_create_decompress(&cinfo); - - FLumpSourceMgr sourcemgr(&lump, &cinfo); - try - { - bool doalpha = conversion == luminance; - jpeg_read_header(&cinfo, TRUE); - if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) || - (cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) || - (cinfo.out_color_space == JCS_YCCK && cinfo.num_components == 4) || - (cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) || - (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) - { - Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str()); - } - else - { - jpeg_start_decompress(&cinfo); - - int y = 0; - buff = new uint8_t[cinfo.output_width * cinfo.output_components]; - - while (cinfo.output_scanline < cinfo.output_height) - { - jpeg_read_scanlines(&cinfo, &buff, 1); - uint8_t *in = buff; - uint8_t *out = Pixels.Data() + y; - switch (cinfo.out_color_space) - { - case JCS_RGB: - for (int x = Width; x > 0; --x) - { - *out = ImageHelpers::RGBToPalette(doalpha, in[0], in[1], in[2]); - out += Height; - in += 3; - } - break; - - case JCS_GRAYSCALE: - { - auto remap = ImageHelpers::GetRemap(doalpha, true); - for (int x = Width; x > 0; --x) - { - *out = remap[in[0]]; - out += Height; - in += 1; - } - break; - } - case JCS_CMYK: - // What are you doing using a CMYK image? :) - for (int x = Width; x > 0; --x) - { - // To be precise, these calculations should use 255, but - // 256 is much faster and virtually indistinguishable. - int r = in[3] - (((256 - in[0])*in[3]) >> 8); - int g = in[3] - (((256 - in[1])*in[3]) >> 8); - int b = in[3] - (((256 - in[2])*in[3]) >> 8); - *out = ImageHelpers::RGBToPalette(doalpha, r, g, b); - out += Height; - in += 4; - } - break; - - case JCS_YCbCr: - // Probably useless but since I had the formula available... - for (int x = Width; x > 0; --x) - { - double Y = in[0], Cb = in[1], Cr = in[2]; - int r = clamp((int)(Y + 1.40200 * (Cr - 0x80)), 0, 255); - int g = clamp((int)(Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80)), 0, 255); - int b = clamp((int)(Y + 1.77200 * (Cb - 0x80)), 0, 255); - *out = ImageHelpers::RGBToPalette(doalpha, r, g, b); - out += Height; - in += 4; - } - break; - - case JCS_YCCK: - // Probably useless but since I had the formula available... - for (int x = Width; x > 0; --x) - { - double Y = in[0], Cb = in[1], Cr = in[2]; - int K = in[3]; - int r = clamp((int)(Y + 1.40200 * (Cr - 0x80)), 0, 255); - int g = clamp((int)(Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80)), 0, 255); - int b = clamp((int)(Y + 1.77200 * (Cb - 0x80)), 0, 255); - r = r - ((r * K) >> 8); - g = g - ((g * K) >> 8); - b = b - ((b * K) >> 8); - *out = ImageHelpers::RGBToPalette(doalpha, r, g, b); - out += Height; - in += 4; - } - break; - - default: - // The other colorspaces were considered above and discarded, - // but GCC will complain without a default for them here. - break; - } - y++; - } - jpeg_finish_decompress(&cinfo); - } - } - catch (int) - { - Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str()); - } - jpeg_destroy_decompress(&cinfo); - if (buff != NULL) - { - delete[] buff; - } - return Pixels; -} - - -//=========================================================================== -// -// FJPEGTexture::CopyPixels -// -// Preserves the full color information (unlike software mode) -// -//=========================================================================== - -int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion, int frame) -{ - PalEntry pe[256]; - - auto lump = fileSystem.OpenFileReader (SourceLump); - - jpeg_decompress_struct cinfo; - jpeg_error_mgr jerr; - - cinfo.err = jpeg_std_error(&jerr); - cinfo.err->output_message = JPEG_OutputMessage; - cinfo.err->error_exit = JPEG_ErrorExit; - jpeg_create_decompress(&cinfo); - - FLumpSourceMgr sourcemgr(&lump, &cinfo); - try - { - jpeg_read_header(&cinfo, TRUE); - - if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) || - (cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) || - (cinfo.out_color_space == JCS_YCCK && cinfo.num_components == 4) || - (cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) || - (cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1))) - { - Printf(TEXTCOLOR_ORANGE "Unsupported color format in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str()); - } - else - { - jpeg_start_decompress(&cinfo); - - int yc = 0; - TArray buff(cinfo.output_height * cinfo.output_width * cinfo.output_components, true); - - while (cinfo.output_scanline < cinfo.output_height) - { - uint8_t * ptr = buff.Data() + cinfo.output_width * cinfo.output_components * yc; - jpeg_read_scanlines(&cinfo, &ptr, 1); - yc++; - } - - switch (cinfo.out_color_space) - { - case JCS_RGB: - bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height, - 3, cinfo.output_width * cinfo.output_components, 0, CF_RGB); - break; - - case JCS_GRAYSCALE: - for (int i = 0; i < 256; i++) pe[i] = PalEntry(255, i, i, i); // default to a gray map - bmp->CopyPixelData(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height, - 1, cinfo.output_width, 0, pe); - break; - - case JCS_CMYK: - bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height, - 4, cinfo.output_width * cinfo.output_components, 0, CF_CMYK); - break; - - case JCS_YCCK: - bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height, - 4, cinfo.output_width * cinfo.output_components, 0, CF_YCCK); - break; - - case JCS_YCbCr: - bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height, - 4, cinfo.output_width * cinfo.output_components, 0, CF_YCbCr); - break; - - default: - assert(0); - break; - } - jpeg_finish_decompress(&cinfo); - } - } - catch (int) - { - Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", fileSystem.GetFileFullPath(SourceLump).c_str()); - } - jpeg_destroy_decompress(&cinfo); - return 0; -} - diff --git a/src/common/textures/formats/stbtexture.cpp b/src/common/textures/formats/stbtexture.cpp index 2507cb5b2..827013a58 100644 --- a/src/common/textures/formats/stbtexture.cpp +++ b/src/common/textures/formats/stbtexture.cpp @@ -36,9 +36,8 @@ #define STB_IMAGE_IMPLEMENTATION #define STBI_NO_STDIO // Undefine formats we do not want to support here. -#define STBI_NO_JPEG //#define STBI_NO_PNG we need PNG for 16 bit channel images. Regular ones still use our own, more flexible decoder. -#define STBI_NO_TGA +#define STBI_NO_TGA // we could use that but our own loader has better palette support. #define STBI_NO_PSD #define STBI_NO_HDR #define STBI_NO_PNM diff --git a/src/common/textures/image.cpp b/src/common/textures/image.cpp index 8cee04102..83f7450eb 100644 --- a/src/common/textures/image.cpp +++ b/src/common/textures/image.cpp @@ -325,7 +325,6 @@ struct TexCreateInfo FImageSource *IMGZImage_TryCreate(FileReader &, int lumpnum); FImageSource *PNGImage_TryCreate(FileReader &, int lumpnum); -FImageSource *JPEGImage_TryCreate(FileReader &, int lumpnum); FImageSource *DDSImage_TryCreate(FileReader &, int lumpnum); FImageSource *PCXImage_TryCreate(FileReader &, int lumpnum); FImageSource *TGAImage_TryCreate(FileReader &, int lumpnum); @@ -348,7 +347,6 @@ FImageSource * FImageSource::GetImage(int lumpnum, bool isflat) static TexCreateInfo CreateInfo[] = { { IMGZImage_TryCreate, false }, { PNGImage_TryCreate, false }, - { JPEGImage_TryCreate, false }, { DDSImage_TryCreate, false }, { PCXImage_TryCreate, false }, { StbImage_TryCreate, false }, diff --git a/vcpkg.json b/vcpkg.json index 83cbaeb7a..a045b8d74 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -31,10 +31,6 @@ "name": "zlib", "platform": "!windows | (windows & static & staticcrt)" }, - { - "name": "libjpeg-turbo", - "platform": "!windows | (windows & static & staticcrt)" - }, { "name": "bzip2", "platform": "!windows | (windows & static & staticcrt)" From 351e0d7ed9d08d275d7b2c0423de5c6661a5446b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 3 Sep 2023 09:04:17 +0200 Subject: [PATCH 069/223] - removed obsolete CMake version requirements. Most were still at 3.1 which prompts noisy warnings from up-to-date CMake versions. Version requirements have been removed entirely from dependent subprojects, all others were upped to 3.16. --- libraries/asmjit/CMakeLists.txt | 2 -- libraries/bzip2/CMakeLists.txt | 2 -- libraries/discordrpc/CMakeLists.txt | 1 - libraries/lzma/CMakeLists.txt | 2 -- libraries/zlib/CMakeLists.txt | 1 - tools/CMakeLists.txt | 2 +- tools/lemon/CMakeLists.txt | 2 +- tools/re2c/CMakeLists.txt | 2 +- tools/zipdir/CMakeLists.txt | 2 +- wadsrc/CMakeLists.txt | 2 -- wadsrc_bm/CMakeLists.txt | 2 -- wadsrc_extra/CMakeLists.txt | 2 -- wadsrc_lights/CMakeLists.txt | 2 -- wadsrc_widepix/CMakeLists.txt | 2 -- 14 files changed, 4 insertions(+), 22 deletions(-) diff --git a/libraries/asmjit/CMakeLists.txt b/libraries/asmjit/CMakeLists.txt index 283b54fbc..4167e4c33 100644 --- a/libraries/asmjit/CMakeLists.txt +++ b/libraries/asmjit/CMakeLists.txt @@ -1,5 +1,3 @@ -cmake_minimum_required( VERSION 3.1.0 ) - #make_release_only() project(asmjit C) diff --git a/libraries/bzip2/CMakeLists.txt b/libraries/bzip2/CMakeLists.txt index 452954c8a..846db25c2 100644 --- a/libraries/bzip2/CMakeLists.txt +++ b/libraries/bzip2/CMakeLists.txt @@ -1,5 +1,3 @@ -cmake_minimum_required( VERSION 3.1.0 ) - make_release_only() if (MSVC) diff --git a/libraries/discordrpc/CMakeLists.txt b/libraries/discordrpc/CMakeLists.txt index a369a7dc1..2c417721a 100644 --- a/libraries/discordrpc/CMakeLists.txt +++ b/libraries/discordrpc/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required (VERSION 3.2.0) project (DiscordRPC) include(GNUInstallDirs) diff --git a/libraries/lzma/CMakeLists.txt b/libraries/lzma/CMakeLists.txt index 2ef5b078f..462419226 100644 --- a/libraries/lzma/CMakeLists.txt +++ b/libraries/lzma/CMakeLists.txt @@ -1,5 +1,3 @@ -cmake_minimum_required( VERSION 3.1.0 ) - make_release_only() set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_7ZIP_PPMD_SUPPPORT" ) diff --git a/libraries/zlib/CMakeLists.txt b/libraries/zlib/CMakeLists.txt index 14f0175f6..22c2d5117 100644 --- a/libraries/zlib/CMakeLists.txt +++ b/libraries/zlib/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required( VERSION 3.1.0 ) set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) make_release_only() diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 8725c56e8..25f4d243c 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 3.1.0 ) +cmake_minimum_required( VERSION 3.16 ) add_subdirectory( re2c ) add_subdirectory( lemon ) diff --git a/tools/lemon/CMakeLists.txt b/tools/lemon/CMakeLists.txt index 71418eda5..a4da050b3 100644 --- a/tools/lemon/CMakeLists.txt +++ b/tools/lemon/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 3.1.0 ) +cmake_minimum_required( VERSION 3.16 ) if( NOT CMAKE_CROSSCOMPILING ) set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG" ) diff --git a/tools/re2c/CMakeLists.txt b/tools/re2c/CMakeLists.txt index 9fcfef5a2..6b888773c 100644 --- a/tools/re2c/CMakeLists.txt +++ b/tools/re2c/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 3.1.0 ) +cmake_minimum_required( VERSION 3.16 ) if( NOT CMAKE_CROSSCOMPILING ) diff --git a/tools/zipdir/CMakeLists.txt b/tools/zipdir/CMakeLists.txt index 762d9027f..17c3af223 100644 --- a/tools/zipdir/CMakeLists.txt +++ b/tools/zipdir/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 3.1.0 ) +cmake_minimum_required( VERSION 3.16 ) if( NOT CMAKE_CROSSCOMPILING ) include_directories( SYSTEM "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" ) diff --git a/wadsrc/CMakeLists.txt b/wadsrc/CMakeLists.txt index 9e4393864..5128f20a0 100644 --- a/wadsrc/CMakeLists.txt +++ b/wadsrc/CMakeLists.txt @@ -1,3 +1 @@ -cmake_minimum_required( VERSION 3.1.0 ) - add_pk3(gzdoom.pk3 ${CMAKE_CURRENT_SOURCE_DIR}/static) diff --git a/wadsrc_bm/CMakeLists.txt b/wadsrc_bm/CMakeLists.txt index e0268d1a3..639c33144 100644 --- a/wadsrc_bm/CMakeLists.txt +++ b/wadsrc_bm/CMakeLists.txt @@ -1,3 +1 @@ -cmake_minimum_required( VERSION 3.1.0 ) - add_pk3(brightmaps.pk3 ${CMAKE_CURRENT_SOURCE_DIR}/static) diff --git a/wadsrc_extra/CMakeLists.txt b/wadsrc_extra/CMakeLists.txt index d9a1b272f..964a177c6 100644 --- a/wadsrc_extra/CMakeLists.txt +++ b/wadsrc_extra/CMakeLists.txt @@ -1,3 +1 @@ -cmake_minimum_required( VERSION 3.1.0 ) - add_pk3(game_support.pk3 ${CMAKE_CURRENT_SOURCE_DIR}/static) diff --git a/wadsrc_lights/CMakeLists.txt b/wadsrc_lights/CMakeLists.txt index 4f9d87d7c..57a493dcd 100644 --- a/wadsrc_lights/CMakeLists.txt +++ b/wadsrc_lights/CMakeLists.txt @@ -1,3 +1 @@ -cmake_minimum_required( VERSION 3.1.0 ) - add_pk3(lights.pk3 ${CMAKE_CURRENT_SOURCE_DIR}/static) diff --git a/wadsrc_widepix/CMakeLists.txt b/wadsrc_widepix/CMakeLists.txt index 83ed458e3..8151a60d3 100644 --- a/wadsrc_widepix/CMakeLists.txt +++ b/wadsrc_widepix/CMakeLists.txt @@ -1,3 +1 @@ -cmake_minimum_required( VERSION 3.1.0 ) - add_pk3(game_widescreen_gfx.pk3 ${CMAKE_CURRENT_SOURCE_DIR}/static) From ef8fd472a8d1e2996828b0d5184e87d14254d527 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 3 Sep 2023 19:52:53 +0200 Subject: [PATCH 070/223] - fixed bad virtual override in FSheetTexture. --- src/common/fonts/font.cpp | 2 +- src/common/fonts/hexfont.cpp | 4 ++-- src/common/textures/formats/startscreentexture.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/fonts/font.cpp b/src/common/fonts/font.cpp index ed7b871c2..8b1542898 100644 --- a/src/common/fonts/font.cpp +++ b/src/common/fonts/font.cpp @@ -390,7 +390,7 @@ public: Y = y; } - int CopyPixels(FBitmap* dest, int conversion) + int CopyPixels(FBitmap* dest, int conversion, int frame = 0) override { auto& pic = sheetBitmaps[baseSheet]; dest->CopyPixelDataRGB(0, 0, pic.GetPixels() + 4 * (X + pic.GetWidth() * Y), Width, Height, 4, pic.GetWidth() * 4, 0, CF_BGRA); diff --git a/src/common/fonts/hexfont.cpp b/src/common/fonts/hexfont.cpp index 3fb02004b..3ec2816e6 100644 --- a/src/common/fonts/hexfont.cpp +++ b/src/common/fonts/hexfont.cpp @@ -110,7 +110,7 @@ public: FHexFontChar(uint8_t *sourcedata, int swidth, int width, int height); PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; - int CopyPixels(FBitmap* bmp, int conversion, int frame = 0); + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0) override; protected: int SourceWidth; @@ -191,7 +191,7 @@ public: FHexFontChar2(uint8_t *sourcedata, int swidth, int width, int height); PalettedPixels CreatePalettedPixels(int conversion, int frame = 0) override; - int CopyPixels(FBitmap* bmp, int conversion, int frame = 0); + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0) override; }; diff --git a/src/common/textures/formats/startscreentexture.cpp b/src/common/textures/formats/startscreentexture.cpp index f19a654f9..155bae19b 100644 --- a/src/common/textures/formats/startscreentexture.cpp +++ b/src/common/textures/formats/startscreentexture.cpp @@ -60,7 +60,7 @@ public: Height = srcdata.GetHeight(); bUseGamePalette = false; } - int CopyPixels(FBitmap* bmp, int conversion, int frame = 0) + int CopyPixels(FBitmap* bmp, int conversion, int frame = 0) override { bmp->Blit(0, 0, info); return 0; From 17ab6e851a3dc7a0c219e927255b5bd133284380 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 3 Sep 2023 23:48:42 +0200 Subject: [PATCH 071/223] - make sure that FileWriter::Printf never writes null characters. --- src/common/filesystem/source/files.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/filesystem/source/files.cpp b/src/common/filesystem/source/files.cpp index 5cb1bd343..8a0b5ed27 100644 --- a/src/common/filesystem/source/files.cpp +++ b/src/common/filesystem/source/files.cpp @@ -481,11 +481,11 @@ size_t FileWriter::Printf(const char *fmt, ...) va_start(arglist, fmt); auto n = vsnprintf(c, 300, fmt, arglist); std::string buf; - buf.resize(n); + buf.resize(n + 1); va_start(arglist, fmt); - vsnprintf(&buf.front(), n, fmt, arglist); + vsnprintf(&buf.front(), n + 1, fmt, arglist); va_end(arglist); - return Write(buf.c_str(), n); + return Write(buf.c_str(), strlen(buf.c_str())); // Make sure we write no null bytes. } size_t BufferWriter::Write(const void *buffer, size_t len) From e7a79b0d448759b8cfe51e325f8a0b36cf340041 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Sep 2023 00:19:36 +0200 Subject: [PATCH 072/223] - string conversion fixes --- src/common/filesystem/source/fs_findfile.cpp | 18 ++++++++++++------ src/common/rendering/gl/gl_hwtexture.cpp | 1 - src/common/utility/utf8.cpp | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/common/filesystem/source/fs_findfile.cpp b/src/common/filesystem/source/fs_findfile.cpp index 689a5d644..06d9b69f1 100644 --- a/src/common/filesystem/source/fs_findfile.cpp +++ b/src/common/filesystem/source/fs_findfile.cpp @@ -202,20 +202,26 @@ static size_t FS_GetFileSize(findstate_t* handle, const char* pathname) std::wstring toWide(const char* str) { int len = (int)strlen(str); - int size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, nullptr, 0); std::wstring wide; - wide.resize(size_needed); - MultiByteToWideChar(CP_UTF8, 0, str, len, &wide.front(), size_needed); + if (len > 0) + { + int size_needed = MultiByteToWideChar(CP_UTF8, 0, str, len, nullptr, 0); + wide.resize(size_needed); + MultiByteToWideChar(CP_UTF8, 0, str, len, &wide.front(), size_needed); + } return wide; } static std::string toUtf8(const wchar_t* str) { auto len = wcslen(str); - int size_needed = WideCharToMultiByte(CP_UTF8, 0, str, (int)len, nullptr, 0, nullptr, nullptr); std::string utf8; - utf8.resize(size_needed); - WideCharToMultiByte(CP_UTF8, 0, str, (int)len, &utf8.front(), size_needed, nullptr, nullptr); + if (len > 0) + { + int size_needed = WideCharToMultiByte(CP_UTF8, 0, str, (int)len, nullptr, 0, nullptr, nullptr); + utf8.resize(size_needed); + WideCharToMultiByte(CP_UTF8, 0, str, (int)len, &utf8.front(), size_needed, nullptr, nullptr); + } return utf8; } diff --git a/src/common/rendering/gl/gl_hwtexture.cpp b/src/common/rendering/gl/gl_hwtexture.cpp index 8fe1b074b..37b066155 100644 --- a/src/common/rendering/gl/gl_hwtexture.cpp +++ b/src/common/rendering/gl/gl_hwtexture.cpp @@ -45,7 +45,6 @@ #include "gl_renderstate.h" #include "gl_samplers.h" #include "gl_hwtexture.h" -#include "printf.h" namespace OpenGLRenderer { diff --git a/src/common/utility/utf8.cpp b/src/common/utility/utf8.cpp index 1ac6ea62b..cad98375e 100644 --- a/src/common/utility/utf8.cpp +++ b/src/common/utility/utf8.cpp @@ -413,7 +413,7 @@ int getAlternative(int code) case 0x41e: return 'O'; case 0x420: return 'P'; case 0x421: return 'C'; - case 0x423: return 'T'; + case 0x422: return 'T'; case 0x425: return 'X'; case 0x430: return 'a'; case 0x435: return 'e'; From de770faeb1476fa8d1801e3acdbfe5f5fb4d56ff Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 6 Sep 2023 21:47:20 +0200 Subject: [PATCH 073/223] - disabled nosectionmerge because it doesn't work right. --- src/maploader/compatibility.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/maploader/compatibility.cpp b/src/maploader/compatibility.cpp index f85d89b19..3549cd0bb 100644 --- a/src/maploader/compatibility.cpp +++ b/src/maploader/compatibility.cpp @@ -303,7 +303,7 @@ FName MapLoader::CheckCompatibility(MapData *map) } if (gameinfo.flags & GI_NOSECTIONMERGE) { - Level->ib_compatflags |= BCOMPATF_NOSECTIONMERGE; + //Level->ib_compatflags |= BCOMPATF_NOSECTIONMERGE; } } From 06f13006ca3ff1a91beb182b67f1f478dc78fe73 Mon Sep 17 00:00:00 2001 From: Romain Tisserand Date: Thu, 7 Sep 2023 15:35:33 +0200 Subject: [PATCH 074/223] Allows building gzdoom with Vulkan with either X11 or Wayland WSI integration through CMake options --- libraries/ZVulkan/CMakeLists.txt | 11 +++++++++++ libraries/ZVulkan/src/volk/volk.c | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/libraries/ZVulkan/CMakeLists.txt b/libraries/ZVulkan/CMakeLists.txt index 8a99d6a91..3b47b7b68 100644 --- a/libraries/ZVulkan/CMakeLists.txt +++ b/libraries/ZVulkan/CMakeLists.txt @@ -1,6 +1,17 @@ cmake_minimum_required(VERSION 3.15) project(zvulkan) +option( VULKAN_USE_XLIB "Use Vulkan xlib (X11) WSI integration" ON ) +option( VULKAN_USE_WAYLAND "Use Vulkan Wayland WSI integration" OFF ) + +if ( VULKAN_USE_XLIB ) + add_definitions( -DVULKAN_USE_XLIB=1 ) +else() + if (VULKAN_USE_WAYLAND) + add_definitions( -DVULKAN_USE_WAYLAND=1 ) + endif() +endif() + set(ZVULKAN_SOURCES src/vulkanbuilders.cpp src/vulkandevice.cpp diff --git a/libraries/ZVulkan/src/volk/volk.c b/libraries/ZVulkan/src/volk/volk.c index 7a6969b10..33255c030 100644 --- a/libraries/ZVulkan/src/volk/volk.c +++ b/libraries/ZVulkan/src/volk/volk.c @@ -5,7 +5,11 @@ #define VK_USE_PLATFORM_MACOS_MVK #define VK_USE_PLATFORM_METAL_EXT #else +#if defined(VULKAN_USE_XLIB) #define VK_USE_PLATFORM_XLIB_KHR +#elif defined(VULKAN_USE_WAYLAND) +#define VK_USE_PLATFORM_WAYLAND_KHR +#endif #endif /* This file is part of volk library; see volk.h for version/license details */ From 86ca0cbecda0e11cd3f22e12154df7f6900e1e92 Mon Sep 17 00:00:00 2001 From: mc776 <24984517+mc776@users.noreply.github.com> Date: Sat, 2 Sep 2023 10:34:46 -0700 Subject: [PATCH 075/223] lights: update for Freedoom. - new FloatingSkull light. - use armour primary colours instead of red for both, with the red gem having its separate light. - give subtractive pulselight to blursphere. --- .../static/filter/doom.freedoom/gldefs.txt | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/wadsrc_lights/static/filter/doom.freedoom/gldefs.txt b/wadsrc_lights/static/filter/doom.freedoom/gldefs.txt index 6e9bb1336..604da8904 100644 --- a/wadsrc_lights/static/filter/doom.freedoom/gldefs.txt +++ b/wadsrc_lights/static/filter/doom.freedoom/gldefs.txt @@ -522,6 +522,21 @@ object Candlestick frame CAND { light CANDLE } } +// Floating Skull Rock +pulselight SKULLROCK +{ + color 0.5 0.4 0.1 + offset 0 5 0 + size 60 + secondarysize 40 + interval 0.6 + attenuate 1 +} +object FloatingSkull +{ + frame FSKU { light SKULLROCK } +} + // ---------------- // -- Doom Items -- // ---------------- @@ -575,12 +590,15 @@ object InvulnerabilitySphere } // Blur Sphere -pointlight BLURSPHERE1 +pulselight BLURSPHERE1 { - color 0.5 0.5 0.5 - size 60 + color 0.6 0.6 0.6 + size 40 + secondarysize 35 offset 0 16 0 + subtractive 1 attenuate 1 + interval 0.3 } object BlurSphere @@ -670,20 +688,36 @@ object RedSkull // Both armor pickups have a big red blinking light in the middle pointlight GREENARMOR2 { - color 0.4 0.0 0.0 + color 0.1 0.2 0.0 size 40 attenuate 1 offset 0 10 0 } +pointlight REDARMOR +{ + color 0.2 0.0 0.0 + size 40 + attenuate 1 + offset 0 10 0 +} +pointlight ARMORLITE +{ + color 0.4 0.0 0.0 + size 10 + attenuate 1 + offset 0 20 0 +} object GreenArmor { - frame ARM1B { light GREENARMOR2 } + frame ARM1 { light GREENARMOR2 } + frame ARM1B { light ARMORLITE } } object BlueArmor { - frame ARM2B { light GREENARMOR2 } + frame ARM2 { light REDARMOR } + frame ARM2B { light ARMORLITE } } From bf0e74447db01aab896561c84f72aa12c892328b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 6 Sep 2023 19:34:23 -0300 Subject: [PATCH 076/223] add float.equal_epsilon and double.equal_epsilon --- src/common/engine/namedef.h | 1 + src/common/scripting/core/types.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/common/engine/namedef.h b/src/common/engine/namedef.h index 2571cb315..948228cb9 100644 --- a/src/common/engine/namedef.h +++ b/src/common/engine/namedef.h @@ -139,6 +139,7 @@ xx(Max) xx(Min_Normal) xx(Min_Denormal) xx(Epsilon) +xx(Equal_Epsilon) xx(NaN) xx(Infinity) xx(Dig) diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index 693e84e2e..078845d6d 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -853,6 +853,7 @@ void PFloat::SetDoubleSymbols() { NAME_Min_Normal, DBL_MIN }, { NAME_Max, DBL_MAX }, { NAME_Epsilon, DBL_EPSILON }, + { NAME_Equal_Epsilon, EQUAL_EPSILON }, { NAME_NaN, std::numeric_limits::quiet_NaN() }, { NAME_Infinity, std::numeric_limits::infinity() }, { NAME_Min_Denormal, std::numeric_limits::denorm_min() } @@ -885,6 +886,7 @@ void PFloat::SetSingleSymbols() { NAME_Min_Normal, FLT_MIN }, { NAME_Max, FLT_MAX }, { NAME_Epsilon, FLT_EPSILON }, + { NAME_Equal_Epsilon, (float)EQUAL_EPSILON }, { NAME_NaN, std::numeric_limits::quiet_NaN() }, { NAME_Infinity, std::numeric_limits::infinity() }, { NAME_Min_Denormal, std::numeric_limits::denorm_min() } From f6c3ce6b154723faf90ecd17388e0cf57660ea6a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 10 Sep 2023 11:45:23 +0200 Subject: [PATCH 077/223] - fixed several line ID functions accessing the sector tag array. --- src/playsim/p_tags.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/playsim/p_tags.cpp b/src/playsim/p_tags.cpp index 70c1832ec..591fcb0ed 100644 --- a/src/playsim/p_tags.cpp +++ b/src/playsim/p_tags.cpp @@ -111,7 +111,7 @@ void FTagManager::RemoveLineIDs(int line) { while (allIDs[start].target == line) { - allTags[start].tag = allTags[start].target = -1; + allIDs[start].tag = allIDs[start].target = -1; start++; } } @@ -371,12 +371,12 @@ int FTagManager::CountLineIDs(const line_t *line) if (LineHasIDs(i)) { - const int n = allTags.Size(); + const int n = allIDs.Size(); int j = startForLine[i]; int c = 0; - while(j < n && allTags[j].target == i) + while(j < n && allIDs[j].target == i) { j++; c++; @@ -394,11 +394,11 @@ int FTagManager::GetLineID(const line_t *line, int index) if (LineHasIDs(i)) { - const int n = allTags.Size(); + const int n = allIDs.Size(); int j = startForLine[i] + index; - return (j < n && allTags[j].target == i) ? allTags[j].tag : 0; + return (j < n && allIDs[j].target == i) ? allIDs[j].tag : 0; } return 0; From a44f7a72cabd503e530957de3e24610f674da4f9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 10 Sep 2023 21:31:53 +0200 Subject: [PATCH 078/223] - fixed voxel loader --- src/common/models/voxels.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/models/voxels.cpp b/src/common/models/voxels.cpp index 9d2f1fdd6..e5b61bcb6 100644 --- a/src/common/models/voxels.cpp +++ b/src/common/models/voxels.cpp @@ -163,7 +163,7 @@ FVoxel *R_LoadKVX(int lumpnum) auto lump = fileSystem.ReadFile(lumpnum); // FileData adds an extra 0 byte to the end. auto rawvoxel = lump.GetBytes(); - int voxelsize = (int)(lump.GetSize()-1); + int voxelsize = (int)(lump.GetSize()); // Oh, KVX, why couldn't you have a proper header? We'll just go through // and collect each MIP level, doing lots of range checking, and if the From 0243efd85198f9c69499730e5a6ee90d331098f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 10 Sep 2023 22:43:50 -0300 Subject: [PATCH 079/223] Fix pointer math in FileSystem to stop debug assertions in std::vector --- src/common/filesystem/source/filesystem.cpp | 26 ++++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/common/filesystem/source/filesystem.cpp b/src/common/filesystem/source/filesystem.cpp index 2344f09cc..8e86b51d0 100644 --- a/src/common/filesystem/source/filesystem.cpp +++ b/src/common/filesystem/source/filesystem.cpp @@ -981,13 +981,16 @@ int FileSystem::FindLump (const char *name, int *lastlump, bool anyns) char name8[8]; uint64_t qname; }; - LumpRecord *lump_p; UpperCopy (name8, name); assert(lastlump != NULL && *lastlump >= 0); - lump_p = &FileInfo[*lastlump]; - while (lump_p <= &FileInfo.back()) + + const LumpRecord * last = FileInfo.data() + FileInfo.size(); + + LumpRecord * lump_p = FileInfo.data() + *lastlump; + + while (lump_p < last) { if ((anyns || lump_p->Namespace == ns_global) && lump_p->shortName.qword == qname) { @@ -1013,11 +1016,13 @@ int FileSystem::FindLump (const char *name, int *lastlump, bool anyns) int FileSystem::FindLumpMulti (const char **names, int *lastlump, bool anyns, int *nameindex) { - LumpRecord *lump_p; - assert(lastlump != NULL && *lastlump >= 0); - lump_p = &FileInfo[*lastlump]; - while (lump_p <= &FileInfo.back()) + + const LumpRecord * last = FileInfo.data() + FileInfo.size(); + + LumpRecord * lump_p = FileInfo.data() + *lastlump; + + while (lump_p < last) { if (anyns || lump_p->Namespace == ns_global) { @@ -1052,11 +1057,14 @@ int FileSystem::FindLumpMulti (const char **names, int *lastlump, bool anyns, in int FileSystem::FindLumpFullName(const char* name, int* lastlump, bool noext) { assert(lastlump != NULL && *lastlump >= 0); - auto lump_p = &FileInfo[*lastlump]; + + const LumpRecord * last = FileInfo.data() + FileInfo.size(); + + LumpRecord * lump_p = FileInfo.data() + *lastlump; if (!noext) { - while (lump_p <= &FileInfo.back()) + while (lump_p < last) { if (!stricmp(name, lump_p->LongName)) { From 99983b37cad75d365679cf2546f5bf0ab55f261e Mon Sep 17 00:00:00 2001 From: nashmuhandes Date: Mon, 11 Sep 2023 08:29:38 +0800 Subject: [PATCH 080/223] Update ZDRay UDMF specs and remove deleted features. --- specs/udmf_zdoom.txt | 18 ++++++++++++++++++ src/maploader/udmf.cpp | 13 ------------- src/namedef_custom.h | 11 ----------- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 8218feeb1..957a33ce9 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -152,6 +152,11 @@ Note: All fields default to false unless mentioned otherwise. For lines with ACS specials (80-86 and 226), if arg0str is present and non-null, it will be used as the name of the script to execute, and arg0 will be ignored. + + lm_sampledist_line = ; // ZDRay customizable sampling distance for this line. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 + lm_sampledist_top = ; // ZDRay customizable sampling distance for this line's top part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 + lm_sampledist_mid = ; // ZDRay customizable sampling distance for this line's middle part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 + lm_sampledist_bot = ; // ZDRay customizable sampling distance for this line's bottom part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 } sidedef @@ -221,6 +226,11 @@ Note: All fields default to false unless mentioned otherwise. colorization_top = ; // Sets a colorization record for the upper texture. Colorization records must be defined in TEXTURES. colorization_mid = ; // Sets a colorization record for the middle texture. Colorization records must be defined in TEXTURES. colorization_bottom = ; // Sets a colorization record for the lower texture. Colorization records must be defined in TEXTURES. + + lm_sampledist_line = ; // ZDRay customizable sampling distance for this sidedef. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 + lm_sampledist_top = ; // ZDRay customizable sampling distance for this sidedef's top part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 + lm_sampledist_mid = ; // ZDRay customizable sampling distance for this sidedef's middle part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 + lm_sampledist_bot = ; // ZDRay customizable sampling distance for this sidedef's bottom part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 } sector @@ -326,6 +336,8 @@ Note: All fields default to false unless mentioned otherwise. for Doom format maps so any map converter converting to the ZDoomTranslated namespace should set this flag for each tagged sector. + lm_sampledist_floor = ; // ZDRay customizable sampling distance for this sector's floor. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 + lm_sampledist_ceiling = ; // ZDRay customizable sampling distance for this sector's ceiling. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0 } thing @@ -356,6 +368,9 @@ Note: All fields default to false unless mentioned otherwise. scale = ; // Vertical and horizontal scaling on thing. Default = 0 (ignored). floatbobphase = ; // Sets the thing's floatbobphase. Valid phase values are 0-63. Default = -1 (use actor class default). + lm_sampledistance = ; // ZDRay lightmap sample distance for the entire map. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 16 + lm_suncolor = ; // ZDRay lightmap sun color in hex. Default: "FFFFFF" + * Note about arg0str For things with ACS specials (80-86 and 226), if arg0str is present and non-null, it @@ -519,6 +534,9 @@ Blocklandmonsters MBF21 flag 1.33 06.11.2021 Added separate light levels for sidedef tiers (top/mid/bottom) +1.34 09.11.2023 +Added/updated ZDRay/lightmap-related properties. + =============================================================================== EOF =============================================================================== diff --git a/src/maploader/udmf.cpp b/src/maploader/udmf.cpp index ed0ec0cd3..941b33e0d 100644 --- a/src/maploader/udmf.cpp +++ b/src/maploader/udmf.cpp @@ -755,7 +755,6 @@ public: case NAME_lm_suncolor: case NAME_lm_sampledistance: - case NAME_lm_gridsize: CHECK_N(Zd | Zdt) break; @@ -1129,9 +1128,6 @@ public: ld->healthgroup = CheckInt(key); break; - case NAME_lm_lightcolorline: - case NAME_lm_lightintensityline: - case NAME_lm_lightdistanceline: case NAME_lm_sampledist_line: case NAME_lm_sampledist_top: case NAME_lm_sampledist_mid: @@ -1481,9 +1477,6 @@ public: sd->Flags |= WALLF_EXTCOLOR; break; - case NAME_lm_lightcolorline: - case NAME_lm_lightintensityline: - case NAME_lm_lightdistanceline: case NAME_lm_sampledist_line: case NAME_lm_sampledist_top: case NAME_lm_sampledist_mid: @@ -1999,12 +1992,6 @@ public: sec->health3dgroup = CheckInt(key); break; - case NAME_lm_lightcolorfloor: - case NAME_lm_lightintensityfloor: - case NAME_lm_lightdistancefloor: - case NAME_lm_lightcolorceiling: - case NAME_lm_lightintensityceiling: - case NAME_lm_lightdistanceceiling: case NAME_lm_sampledist_floor: case NAME_lm_sampledist_ceiling: CHECK_N(Zd | Zdt) diff --git a/src/namedef_custom.h b/src/namedef_custom.h index d0964ce7f..a5604475d 100644 --- a/src/namedef_custom.h +++ b/src/namedef_custom.h @@ -849,16 +849,6 @@ xx(Sky) xx(Pagename) // Lightmap/ZDRay keywords -// (Surface lights are temporarily disabled and don't do anything) -xx(lm_lightcolorline) -xx(lm_lightintensityline) -xx(lm_lightdistanceline) -xx(lm_lightcolorfloor) -xx(lm_lightintensityfloor) -xx(lm_lightdistancefloor) -xx(lm_lightcolorceiling) -xx(lm_lightintensityceiling) -xx(lm_lightdistanceceiling) xx(lm_sampledist_line) xx(lm_sampledist_top) xx(lm_sampledist_mid) @@ -867,6 +857,5 @@ xx(lm_sampledist_floor) xx(lm_sampledist_ceiling) xx(lm_suncolor) xx(lm_sampledistance) -xx(lm_gridsize) xx(Corona) From b44741b8aaf1f8804ad3c98a515ed2a32c26ee4a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 12 Sep 2021 21:04:40 +0200 Subject: [PATCH 081/223] - dsdehacked: allow dynamic creation of new states. --- src/gamedata/d_dehacked.cpp | 41 ++++++++++++++++++++++++++----- src/gamedata/info.h | 3 +++ src/p_states.cpp | 17 +++++++++---- src/playsim/p_actionfunctions.cpp | 1 - src/playsim/p_pspr.cpp | 30 ++++++++++++++-------- src/serializer_doom.cpp | 16 +++++++++++- 6 files changed, 85 insertions(+), 23 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index bd9de53dc..db87de3cd 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -150,7 +150,7 @@ struct MBFArgs int argsused; }; static TMap stateargs; -static FState* FindState(int statenum); +static FState* FindState(int statenum, bool mustexist = false); // DeHackEd trickery to support MBF-style parameters // List of states that are hacked to use a codepointer @@ -341,7 +341,7 @@ FString PatchName; static int PatchSize; static char *Line1, *Line2; static int dversion, pversion; -static bool including, includenotext; +static bool including, includenotext, dsdhacked = false; static int LumpFileNum; static const char *unknown_str = "Unknown key %s encountered in %s %d.\n"; @@ -373,6 +373,8 @@ static int PatchPars (int); static int PatchCodePtrs (int); static int PatchMusic (int); static int DoInclude (int); +static int PatchSpriteNames (int); +static int PatchSoundNames(int) {} // todo static bool DoDehPatch(); static const struct { @@ -396,6 +398,8 @@ static const struct { { "[PARS]", PatchPars }, { "[CODEPTR]", PatchCodePtrs }, { "[MUSIC]", PatchMusic }, + { "[SPRITES]", PatchSpriteNames }, + { "[SOUNDS]", PatchSoundNames }, { NULL, NULL }, }; @@ -456,12 +460,12 @@ static int FindSprite (const char *sprname) return f == UnchangedSpriteNames.Size() ? -1 : f; } -static FState *FindState (int statenum) +static FState *FindState (int statenum, bool mustexist) { int stateacc; unsigned i; - if (statenum == 0) + if (statenum <= 0) return NULL; for (i = 0, stateacc = 1; i < StateMap.Size(); i++) @@ -480,6 +484,18 @@ static FState *FindState (int statenum) } stateacc += StateMap[i].StateSpan; } + if (dsdhacked && !mustexist) + { + auto p = dehExtStates.CheckKey(statenum); + if (p) return *p; + auto state = (FState*)ClassDataAllocator.Alloc(sizeof(FState)); + dehExtStates.Insert(statenum, state); + memset(state, 0, sizeof(*state)); + state->Tics = -1; + state->NextState = state; + state->DehIndex = statenum; + + } return NULL; } @@ -745,7 +761,7 @@ static void CreatePlaySoundFunc(FunctionCallEmitter &emitters, int value1, int v // misc1 = state, misc2 = probability static void CreateRandomJumpFunc(FunctionCallEmitter &emitters, int value1, int value2, MBFParamState* state) { // A_Jump - auto symlabel = StateLabels.AddPointer(FindState(value1)); + auto symlabel = StateLabels.AddPointer(FindState(value1, true)); emitters.AddParameterIntConst(value2); // maxchance emitters.AddParameterIntConst(symlabel); // jumpto @@ -2288,7 +2304,7 @@ static int PatchPointer (int ptrNum) { if ((unsigned)ptrNum < CodePConv.Size() && (!stricmp (Line1, "Codep Frame"))) { - FState *state = FindState (CodePConv[ptrNum]); + FState *state = FindState (CodePConv[ptrNum], true); if (state) { int index = atoi(Line2); @@ -3112,6 +3128,11 @@ static bool DoDehPatch() dversion = 1; else if (dversion == 21) dversion = 4; + else if (dversion == 2021) + { + dversion = 4; + dsdhacked = true; + } else { Printf ("Patch created with unknown DOOM version.\nAssuming version 1.9.\n"); @@ -3319,6 +3340,7 @@ static bool LoadDehSupp () else if (sc.Compare("StateMap")) { bool addit = StateMap.Size() == 0; + int dehcount = 0; sc.MustGetStringName("{"); while (!sc.CheckString("}")) @@ -3360,6 +3382,13 @@ static bool LoadDehSupp () if (sc.CheckString("}")) break; sc.MustGetStringName(","); + // This mapping is mainly for P_SetSafeFlash. + for (int i = 0; i < s.StateSpan; i++) + { + dehExtStates.Insert(dehcount, s.State + i); + s.State[i].DehIndex = dehcount; + dehcount++; + } } } else if (sc.Compare("SoundMap")) diff --git a/src/gamedata/info.h b/src/gamedata/info.h index d9e89037b..69ad560e0 100644 --- a/src/gamedata/info.h +++ b/src/gamedata/info.h @@ -112,6 +112,7 @@ struct FState uint8_t DefineFlags; int32_t Misc1; // Was changed to int8_t, reverted to long for MBF compat int32_t Misc2; // Was changed to uint8_t, reverted to long for MBF compat + int32_t DehIndex; // we need this to resolve offsets in P_SetSafeFlash. public: inline int GetFrame() const { @@ -178,6 +179,8 @@ public: }; +extern TMap dehExtStates; + struct FStateLabels; struct FStateLabel { diff --git a/src/p_states.cpp b/src/p_states.cpp index 6c3ff2f33..90241dd54 100644 --- a/src/p_states.cpp +++ b/src/p_states.cpp @@ -44,6 +44,7 @@ // stores indices for symbolic state labels for some old-style DECORATE functions. FStateLabelStorage StateLabels; +TMap dehExtStates; // Each state is owned by an actor. Actors can own any number of // states, but a single state cannot be owned by more than one @@ -138,6 +139,7 @@ FString FState::StaticGetStateName(const FState *state, PClassActor *info) } if (so == nullptr) { + if (state->DehIndex > 0) return FStringf("DehExtraState.%d", state->DehIndex); return ""; } return FStringf("%s.%d", so->TypeName.GetChars(), int(state - so->GetStates())); @@ -1029,6 +1031,7 @@ int FStateDefinitions::FinishStates(PClassActor *actor) for (i = 0; i < count; i++) { + realstates[i].DehIndex = -1; // resolve labels and jumps switch (realstates[i].DefineFlags) { @@ -1074,16 +1077,20 @@ void DumpStateHelper(FStateLabels *StateList, const FString &prefix) { for (int i = 0; i < StateList->NumLabels; i++) { - if (StateList->Labels[i].State != NULL) + auto state = StateList->Labels[i].State; + if (state != NULL) { - const PClassActor *owner = FState::StaticFindStateOwner(StateList->Labels[i].State); + const PClassActor *owner = FState::StaticFindStateOwner(state); if (owner == NULL) { - Printf(PRINT_LOG, "%s%s: invalid\n", prefix.GetChars(), StateList->Labels[i].Label.GetChars()); + if (state->DehIndex >= 0) + Printf(PRINT_LOG, "%s%s: DehExtra %d\n", prefix.GetChars(), state->DehIndex); + else + Printf(PRINT_LOG, "%s%s: invalid\n", prefix.GetChars(), StateList->Labels[i].Label.GetChars()); } else { - Printf(PRINT_LOG, "%s%s: %s\n", prefix.GetChars(), StateList->Labels[i].Label.GetChars(), FState::StaticGetStateName(StateList->Labels[i].State).GetChars()); + Printf(PRINT_LOG, "%s%s: %s\n", prefix.GetChars(), StateList->Labels[i].Label.GetChars(), FState::StaticGetStateName(state).GetChars()); } } if (StateList->Labels[i].Children != NULL) @@ -1135,7 +1142,7 @@ DEFINE_ACTION_FUNCTION(FState, DistanceTo) { // Safely calculate the distance between two states. auto o1 = FState::StaticFindStateOwner(self); - if (o1->OwnsState(other)) retv = int(other - self); + if (o1 && o1->OwnsState(other)) retv = int(other - self); } ACTION_RETURN_INT(retv); } diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 5eb72ef17..de0abf053 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -128,7 +128,6 @@ static int CallStateChain (AActor *self, AActor *actor, FState *state) if (state->ActionFunc->Unsafe) { // If an unsafe function (i.e. one that accesses user variables) is being detected, print a warning once and remove the bogus function. We may not call it because that would inevitably crash. - auto owner = FState::StaticFindStateOwner(state); Printf(TEXTCOLOR_RED "Unsafe state call in state %s to %s which accesses user variables. The action function has been removed from this state\n", FState::StaticGetStateName(state).GetChars(), state->ActionFunc->PrintableName); state->ActionFunc = nullptr; diff --git a/src/playsim/p_pspr.cpp b/src/playsim/p_pspr.cpp index 3864967b0..d65b4d003 100644 --- a/src/playsim/p_pspr.cpp +++ b/src/playsim/p_pspr.cpp @@ -1352,25 +1352,35 @@ void P_SetSafeFlash(AActor *weapon, player_t *player, FState *flashstate, int in P_SetPsprite(player, PSP_FLASH, flashstate + index, true); return; } - else + else if (flashstate->DehIndex < 0) { - // oh, no! The state is beyond the end of the state table so use the original flash state. + // oh, no! The state is beyond the end of the state table so use the original flash state if it does not have a Dehacked index. P_SetPsprite(player, PSP_FLASH, flashstate, true); return; } + else break; // no need to continue. } // try again with parent class cls = static_cast(cls->ParentClass); } - // if we get here the state doesn't seem to belong to any class in the inheritance chain - // This can happen with Dehacked if the flash states are remapped. - // The only way to check this would be to go through all Dehacked modifiable actors, convert - // their states into a single flat array and find the correct one. - // Rather than that, just check to make sure it belongs to something. - if (FState::StaticFindStateOwner(flashstate + index) == NULL) - { // Invalid state. With no index offset, it should at least be valid. - index = 0; + + // if we get here the target state doesn't belong to any class in the inheritance chain. + // This can happen with Dehacked if the flash states are remapped. + // In this case we should check the Dehacked state map to get the proper state. + if (flashstate->DehIndex >= 0) + { + auto pTargetstate = dehExtStates.CheckKey(flashstate->DehIndex + index); + if (pTargetstate) + { + P_SetPsprite(player, PSP_FLASH, *pTargetstate, true); + return; + } } + + // If we still haven't found anything here, just use the base flash state. + // Normally this code should not be reachable. + index = 0; + } P_SetPsprite(player, PSP_FLASH, flashstate + index, true); } diff --git a/src/serializer_doom.cpp b/src/serializer_doom.cpp index 953bb9afc..63dc08b07 100644 --- a/src/serializer_doom.cpp +++ b/src/serializer_doom.cpp @@ -346,6 +346,13 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FState *&state, FState arc.w->Uint((uint32_t)(state - info->GetStates())); arc.w->EndArray(); } + else if (state->DehIndex >= 0) + { + arc.w->StartArray(); + arc.w->String("@DehExtraState@"); + arc.w->Uint(state->DehIndex); + arc.w->EndArray(); + } else { arc.w->Null(); @@ -373,11 +380,18 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FState *&state, FState assert(cls.IsString() && ndx.IsUint()); if (cls.IsString() && ndx.IsUint()) { - PClassActor *clas = PClass::FindActor(UnicodeToString(cls.GetString())); + auto str = UnicodeToString(cls.GetString()); + PClassActor *clas = PClass::FindActor(str); if (clas && ndx.GetUint() < (unsigned)clas->GetStateCount()) { state = clas->GetStates() + ndx.GetUint(); } + else if (!strcmp(str, "@DehExtraState@")) + { + state = nullptr; + auto pState = dehExtStates.CheckKey(ndx.GetInt()); + if (pState) state = *pState; + } else { // this can actually happen by changing the DECORATE so treat it as a warning, not an error. From 24d57b58c50d247c20f24f924c510971f47df2b7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 12 Sep 2021 21:45:51 +0200 Subject: [PATCH 082/223] - dsdhacked: Allow dynamic creation of new actors --- src/gamedata/d_dehacked.cpp | 67 +++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index db87de3cd..97f927475 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -97,6 +97,7 @@ static TArray OrgHeights; // disappear, but that doesn't explain why frame patches specify an exact // state rather than a code pointer.) static TArray CodePConv; +static bool dsdhacked = false; // Sprite names in the order Doom originally had them. struct DEHSprName @@ -122,6 +123,28 @@ static TArray SoundMap; // Names of different actor types, in original Doom 2 order static TArray InfoNames; +static PClassActor* FindInfoName(int index, bool mustexist = false) +{ + if (index < 0) return nullptr; + if (index < (int)InfoNames.Size()) return InfoNames[index]; + + if (dsdhacked) + { + FStringf name("~Dsdhacked~%d", index); + auto cls = PClass::FindActor(name); + if (cls) + { + GetDefaultByType(cls)->flags8 |= MF8_RETARGETAFTERSLAM; // This flag is not a ZDoom default, but it must be a Dehacked default. + return cls; + } + if (!mustexist) + { + return static_cast(RUNTIME_CLASS(AActor)->CreateDerivedClass(name.GetChars(), (unsigned)sizeof(AActor))); + } + } + return nullptr; +} + // bit flags for PatchThing (a .bex extension): struct BitName { @@ -163,10 +186,8 @@ struct MBFParamState PClassActor* GetTypeArg(int i) { - PClassActor* type = nullptr; int num = (int)args[i]; - if (num > 0 && num < int(InfoNames.Size())) type = InfoNames[num-1]; // Dehacked is 1-based. - return type; + return FindInfoName(num-1, true); } FState* GetStateArg(int i) @@ -341,7 +362,7 @@ FString PatchName; static int PatchSize; static char *Line1, *Line2; static int dversion, pversion; -static bool including, includenotext, dsdhacked = false; +static bool including, includenotext; static int LumpFileNum; static const char *unknown_str = "Unknown key %s encountered in %s %d.\n"; @@ -373,8 +394,8 @@ static int PatchPars (int); static int PatchCodePtrs (int); static int PatchMusic (int); static int DoInclude (int); -static int PatchSpriteNames (int); -static int PatchSoundNames(int) {} // todo +static int PatchSpriteNames(int) { return 0; } // todo +static int PatchSoundNames(int) { return 0; } // todo static bool DoDehPatch(); static const struct { @@ -710,11 +731,12 @@ static void CreateMushroomFunc(FunctionCallEmitter &emitters, int value1, int va // misc1 = type (arg +0), misc2 = Z-pos (arg +2) static void CreateSpawnFunc(FunctionCallEmitter &emitters, int value1, int value2, MBFParamState* state) { // A_SpawnItem - if (InfoNames[value1-1] == nullptr) + auto p = FindInfoName(value1 - 1, true); + if (p == nullptr) { I_Error("No class found for dehackednum %d!\n", value1+1); } - emitters.AddParameterPointerConst(InfoNames[value1-1]); // itemtype + emitters.AddParameterPointerConst(p); // itemtype emitters.AddParameterFloatConst(0); // distance emitters.AddParameterFloatConst(value2); // height emitters.AddParameterIntConst(0); // useammo @@ -1124,29 +1146,16 @@ static int PatchThing (int thingy) type = NULL; info = (AActor *)&dummy; ednum = &dummyed; - if (thingy > (int)InfoNames.Size() || thingy <= 0) + auto thingytype = FindInfoName(thingy-1); + if (thingytype == nullptr) { - Printf ("Thing %d out of range.\n", thingy); + Printf ("Thing %d out of range or invalid.\n", thingy); } else { DPrintf (DMSG_SPAMMY, "Thing %d\n", thingy); - if (thingy > 0) - { - type = InfoNames[thingy - 1]; - if (type == NULL) - { - info = (AActor *)&dummy; - ednum = &dummyed; - // An error for the name has already been printed while loading DEHSUPP. - Printf ("Could not find thing %d\n", thingy); - } - else - { - info = GetDefaultByType (type); - ednum = &type->ActorInfo()->DoomEdNum; - } - } + info = GetDefaultByType (type); + ednum = &type->ActorInfo()->DoomEdNum; } oldflags = info->flags; @@ -1280,13 +1289,13 @@ static int PatchThing (int thingy) } else if (linelen == 12 && stricmp(Line1, "dropped item") == 0) { - val--; // This is 1-based and 0 means 'no drop'. - if ((unsigned)val < InfoNames.Size()) + auto drop = FindInfoName(val - 1); + if (drop) { FDropItem* di = (FDropItem*)ClassDataAllocator.Alloc(sizeof(FDropItem)); di->Next = nullptr; - di->Name = InfoNames[val]->TypeName.GetChars(); + di->Name = drop->TypeName; di->Probability = 255; di->Amount = -1; info->GetInfo()->DropItems = di; From bdd02d9b2cb282470f61b8efec494ac6b359170d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 13 Sep 2021 00:12:08 +0200 Subject: [PATCH 083/223] - implemented the remaining dynamic structures of dsdhacked --- src/gamedata/d_dehacked.cpp | 247 +++++++++++++++++++++++++----------- 1 file changed, 173 insertions(+), 74 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 97f927475..f0ff88c16 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -105,6 +105,8 @@ struct DEHSprName char c[5]; }; static TArray OrgSprNames; +size_t OrgSprOrgSize; +static TMap stateSprites; struct StateMapper { @@ -139,12 +141,75 @@ static PClassActor* FindInfoName(int index, bool mustexist = false) } if (!mustexist) { - return static_cast(RUNTIME_CLASS(AActor)->CreateDerivedClass(name.GetChars(), (unsigned)sizeof(AActor))); + cls = static_cast(RUNTIME_CLASS(AActor)->CreateDerivedClass(name.GetChars(), (unsigned)sizeof(AActor))); + NewClassType(cls, -1); // This needs a VM type to work as intended. + return cls; } } return nullptr; } +static FSoundID DehFindSound(int index,bool mustexist = false) +{ + if (index < 0) return NO_SOUND; + if (index < (int) SoundMap.Size()) return SoundMap[index]; + FStringf name("~dsdhacked/#%d", index); + if (dsdhacked && !mustexist) return soundEngine->FindSoundTentative(name); + return NO_SOUND; +} + +static void ReplaceSoundName(int index, const char* newname) +{ + // This must physically replace the sound's lump name in the sound record. + auto snd = DehFindSound(index-1); + if (snd == NO_SOUND) return; + auto sfx = soundEngine->GetWritableSfx(snd); + FStringf dsname("ds%s", newname); + sfx->lumpnum = fileSystem.CheckNumForName(dsname, FileSys::ns_sounds); + sfx->bTentative = false; + sfx->bRandomHeader = false; + sfx->bLoadRAW = false; + sfx->b16bit = false; + sfx->bUsed = false; + sfx->UserData[0] = 0; +} + +void RemapAllSprites() +{ + TMap::Iterator it(stateSprites); + TMap::Pair *pair; + + while (it.NextPair(pair)) + { + int frameNum = 0; // Hmmm... + auto info = pair->Key; + int val = pair->Value; + unsigned int i; + + if (val >= 0 && val < (int)OrgSprNames.Size()) + { + for (i = 0; i < sprites.Size(); i++) + { + if (memcmp (OrgSprNames[val].c, sprites[i].name, 4) == 0) + { + info->sprite = (int)i; + break; + } + } + if (i == sprites.Size ()) + { + Printf ("Frame %d: Sprite %d (%s) is undefined\n", + frameNum, val, OrgSprNames[val].c); + } + } + else + { + Printf ("Frame %d: Sprite %d out of range\n", frameNum, val); + } + } + stateSprites.Clear(); +} + // bit flags for PatchThing (a .bex extension): struct BitName { @@ -202,11 +267,10 @@ struct MBFParamState return argsused & (1 << i)? (int)args[i] : def; } - int GetSoundArg(int i, int def = 0) + FSoundID GetSoundArg(int i, int def = 0) { int num = argsused & (1 << i) ? (int)args[i] : def; - if (num > 0 && num <= int(SoundMap.Size())) return SoundMap[num-1].index(); - return 0; + return DehFindSound(num-1, true); } double GetFloatArg(int i, double def = 0) @@ -394,8 +458,8 @@ static int PatchPars (int); static int PatchCodePtrs (int); static int PatchMusic (int); static int DoInclude (int); -static int PatchSpriteNames(int) { return 0; } // todo -static int PatchSoundNames(int) { return 0; } // todo +static int PatchSpriteNames(int); +static int PatchSoundNames(int); static bool DoDehPatch(); static const struct { @@ -762,7 +826,7 @@ static void CreateFaceFunc(FunctionCallEmitter &emitters, int value1, int value2 static void CreateScratchFunc(FunctionCallEmitter &emitters, int value1, int value2, MBFParamState* state) { // A_CustomMeleeAttack emitters.AddParameterIntConst(value1); // damage - emitters.AddParameterIntConst(value2 ? (int)SoundMap[value2 - 1].index() : 0); // hit sound + emitters.AddParameterIntConst(DehFindSound(value2 - 1, true).index()); // hit sound emitters.AddParameterIntConst(0); // miss sound emitters.AddParameterIntConst(NAME_None); // damage type emitters.AddParameterIntConst(true); // bleed @@ -771,7 +835,7 @@ static void CreateScratchFunc(FunctionCallEmitter &emitters, int value1, int val // misc1 = sound, misc2 = attenuation none (true) or normal (false) static void CreatePlaySoundFunc(FunctionCallEmitter &emitters, int value1, int value2, MBFParamState* state) { // A_PlaySound - emitters.AddParameterIntConst(value1 ? (int)SoundMap[value1 - 1].index() : 0); // soundid + emitters.AddParameterIntConst(DehFindSound(value1 - 1, true).index()); // soundid emitters.AddParameterIntConst(CHAN_BODY); // channel emitters.AddParameterFloatConst(1); // volume emitters.AddParameterIntConst(false); // looping @@ -840,7 +904,7 @@ static void CreateMonsterMeleeAttackFunc(FunctionCallEmitter &emitters, int valu state->ValidateArgCount(4, "A_MonsterMeleeAttack"); emitters.AddParameterIntConst(state->GetIntArg(0, 3)); emitters.AddParameterIntConst(state->GetIntArg(1, 8)); - emitters.AddParameterIntConst(state->GetSoundArg(2, 0)); + emitters.AddParameterIntConst(state->GetSoundArg(2, 0).index()); emitters.AddParameterFloatConst(state->GetFloatArg(3)); } @@ -856,7 +920,7 @@ static void CreateHealChaseFunc(FunctionCallEmitter &emitters, int value1, int v { state->ValidateArgCount(2, "A_HealChase"); emitters.AddParameterPointerConst(state->GetStateArg(0)); - emitters.AddParameterIntConst(state->GetSoundArg(1)); + emitters.AddParameterIntConst(state->GetSoundArg(1).index()); } static void CreateSeekTracerFunc(FunctionCallEmitter &emitters, int value1, int value2, MBFParamState* state) @@ -928,14 +992,14 @@ static void CreateWeaponMeleeAttackFunc(FunctionCallEmitter &emitters, int value emitters.AddParameterIntConst(state->GetIntArg(0, 2)); emitters.AddParameterIntConst(state->GetIntArg(1, 10)); emitters.AddParameterFloatConst(state->GetFloatArg(2, 1)); - emitters.AddParameterIntConst(state->GetSoundArg(3)); + emitters.AddParameterIntConst(state->GetSoundArg(3).index()); emitters.AddParameterFloatConst(state->GetFloatArg(4)); } static void CreateWeaponSoundFunc(FunctionCallEmitter &emitters, int value1, int value2, MBFParamState* state) { state->ValidateArgCount(2, "A_WeaponSound"); - emitters.AddParameterIntConst(state->GetSoundArg(0)); + emitters.AddParameterIntConst(state->GetSoundArg(0).index()); emitters.AddParameterIntConst(state->GetIntArg(1)); } @@ -1411,9 +1475,9 @@ static int PatchThing (int thingy) } else if (stricmp (Line1 + linelen - 6, " sound") == 0) { - FSoundID snd = NO_SOUND; + FSoundID snd = DehFindSound(val - 1); - if (val == 0 || val >= SoundMap.Size()) + if (snd == NO_SOUND) // This won't trigger for dsdhacked patches! { if (endptr == Line2) { // Sound was not a (valid) number, @@ -1422,10 +1486,6 @@ static int PatchThing (int thingy) snd = S_FindSound(Line2); } } - else - { - snd = SoundMap[val-1]; - } if (!strnicmp (Line1, "Alert", 5)) info->SeeSound = snd; @@ -1817,28 +1877,7 @@ static int PatchFrame (int frameNum) } else if (keylen == 13 && stricmp (Line1, "Sprite number") == 0) { - unsigned int i; - - if (val < (int)OrgSprNames.Size()) - { - for (i = 0; i < sprites.Size(); i++) - { - if (memcmp (OrgSprNames[val].c, sprites[i].name, 4) == 0) - { - info->sprite = (int)i; - break; - } - } - if (i == sprites.Size ()) - { - Printf ("Frame %d: Sprite %d (%s) is undefined\n", - frameNum, val, OrgSprNames[val].c); - } - } - else - { - Printf ("Frame %d: Sprite %d out of range\n", frameNum, val); - } + stateSprites.Insert(info, val); } else if (keylen == 10 && stricmp (Line1, "Next frame") == 0) { @@ -1940,7 +1979,7 @@ static int PatchSprite (int sprNum) int result; int offset = 0; - if ((unsigned)sprNum < OrgSprNames.Size()) + if ((unsigned)sprNum < OrgSprOrgSize) { DPrintf (DMSG_SPAMMY, "Sprite %d\n", sprNum); } @@ -1957,12 +1996,12 @@ static int PatchSprite (int sprNum) else Printf (unknown_str, Line1, "Sprite", sprNum); } - if (offset > 0 && sprNum != -1) + if (offset > 0 && sprNum != -1 && !dsdhacked) { // Calculate offset from beginning of sprite names. offset = (offset - toff[dversion] - 22044) / 8; - if ((unsigned)offset < OrgSprNames.Size()) + if ((unsigned)offset < OrgSprOrgSize) { sprNum = FindSprite (OrgSprNames[sprNum].c); if (sprNum != -1) @@ -2609,6 +2648,7 @@ static int PatchPars (int dummy) return result; } + static int PatchCodePtrs (int dummy) { int result; @@ -2702,6 +2742,40 @@ static int PatchMusic (int dummy) return result; } + +// This repplaces a sprite name in the current working data +static void ReplaceSpriteInData(const char* oldStr, const char* newStr) + { + if (strncmp ("PLAY", oldStr, 4) == 0) + { + strncpy (deh.PlayerSprite, newStr, 4); + } + // If this sprite is used by a pickup, then the DehackedPickup sprite map + // needs to be updated too. + for (size_t i = 0; i < countof(DehSpriteMappings); ++i) + { + if (strncmp (DehSpriteMappings[i].Sprite, oldStr, 4) == 0) + { + // Found a match, so change it. + strncpy (DehSpriteMappings[i].Sprite, newStr, 4); + + // Now shift the map's entries around so that it stays sorted. + // This must be done because the map is scanned using a binary search. + while (i > 0 && strncmp (DehSpriteMappings[i-1].Sprite, newStr, 4) > 0) + { + std::swap (DehSpriteMappings[i-1], DehSpriteMappings[i]); + --i; + } + while ((size_t)i < countof(DehSpriteMappings)-1 && + strncmp (DehSpriteMappings[i+1].Sprite, newStr, 4) < 0) + { + std::swap (DehSpriteMappings[i+1], DehSpriteMappings[i]); + ++i; + } + break; + } + } + } static int PatchText (int oldSize) { @@ -2759,42 +2833,14 @@ static int PatchText (int oldSize) if (i != -1) { strncpy (sprites[i].name, newStr, 4); - if (strncmp ("PLAY", oldStr, 4) == 0) - { - strncpy (deh.PlayerSprite, newStr, 4); - } - for (unsigned ii = 0; ii < OrgSprNames.Size(); ii++) + for (unsigned ii = 0; ii < OrgSprOrgSize; ii++) { if (!stricmp(OrgSprNames[ii].c, oldStr)) { strcpy(OrgSprNames[ii].c, newStr); } } - // If this sprite is used by a pickup, then the DehackedPickup sprite map - // needs to be updated too. - for (i = 0; (size_t)i < countof(DehSpriteMappings); ++i) - { - if (strncmp (DehSpriteMappings[i].Sprite, oldStr, 4) == 0) - { - // Found a match, so change it. - strncpy (DehSpriteMappings[i].Sprite, newStr, 4); - - // Now shift the map's entries around so that it stays sorted. - // This must be done because the map is scanned using a binary search. - while (i > 0 && strncmp (DehSpriteMappings[i-1].Sprite, newStr, 4) > 0) - { - std::swap (DehSpriteMappings[i-1], DehSpriteMappings[i]); - --i; - } - while ((size_t)i < countof(DehSpriteMappings)-1 && - strncmp (DehSpriteMappings[i+1].Sprite, newStr, 4) < 0) - { - std::swap (DehSpriteMappings[i+1], DehSpriteMappings[i]); - ++i; - } - break; - } - } + ReplaceSpriteInData(oldStr, newStr); goto donewithtext; } } @@ -2875,6 +2921,57 @@ static int PatchStrings (int dummy) return result; } +static int PatchSoundNames (int dummy) +{ + int result; + + DPrintf (DMSG_SPAMMY, "[Sounds]\n"); + + while ((result = GetLine()) == 1) + { + FString newname = skipwhite (Line2); + ReplaceSoundName((int)strtoll(Line1, nullptr, 10), newname); + DPrintf (DMSG_SPAMMY, "Sound %d set to:\n%s\n", Line1, newname.GetChars()); + } + + return result; +} + +static int PatchSpriteNames (int dummy) +{ + int result; + + DPrintf (DMSG_SPAMMY, "[Sprites]\n"); + + while ((result = GetLine()) == 1) + { + FString newname = skipwhite (Line2); + if (newname.Len() != 4) + { + Printf("Sprite name must be 4 characters long, got '%s'\n", newname.GetChars()); + continue; + } + int64_t line1val = strtoll(Line1, nullptr, 10); + if (line1val >= OrgSprNames.Size()) + { + unsigned osize = OrgSprNames.Size(); + OrgSprNames.Resize(line1val + 1); + DEHSprName nulname{}; + for (unsigned o = osize; o < OrgSprNames.Size(); o++) + { + OrgSprNames[o] = nulname; + } + int v = GetSpriteIndex(newname); + memcpy(OrgSprNames[line1val].c, sprites[v].name, 5); + } + + DPrintf (DMSG_SPAMMY, "Sprite %d set to:\n%s\n", Line1, newname.GetChars()); + } + + return result; + } + + static int DoInclude (int dummy) { char *data; @@ -3345,6 +3442,7 @@ static bool LoadDehSupp () if (sc.CheckString("}")) break; sc.MustGetStringName(","); } + OrgSprOrgSize = OrgSprNames.Size(); } else if (sc.Compare("StateMap")) { @@ -3557,7 +3655,8 @@ void FinishDehPatch () { GetDefaultByType(cls)->flags8 |= MF8_RETARGETAFTERSLAM; } - + RemapAllSprites(); + for (touchedIndex = 0; touchedIndex < TouchedActors.Size(); ++touchedIndex) { PClassActor *subclass; From 7f612666215bb41bcdb742aa8d0b476a762fe506 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 11 Sep 2023 23:19:22 +0200 Subject: [PATCH 084/223] - fixed memory leaks in file system management --- src/common/filesystem/source/filesystem.cpp | 4 +++- src/common/filesystem/source/fs_stringpool.h | 2 +- src/common/filesystem/source/resourcefile.cpp | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/common/filesystem/source/filesystem.cpp b/src/common/filesystem/source/filesystem.cpp index 8e86b51d0..c22682ec0 100644 --- a/src/common/filesystem/source/filesystem.cpp +++ b/src/common/filesystem/source/filesystem.cpp @@ -194,7 +194,7 @@ static void PrintLastError (FileSystemMessageFunc Printf); FileSystem::FileSystem() { - stringpool = new StringPool; + stringpool = new StringPool(true); stringpool->shared = true; // will be used by all owned resource files. } @@ -219,6 +219,8 @@ void FileSystem::DeleteAll () delete Files[i]; } Files.clear(); + delete stringpool; + stringpool = nullptr; } //========================================================================== diff --git a/src/common/filesystem/source/fs_stringpool.h b/src/common/filesystem/source/fs_stringpool.h index f72a180df..3472cd792 100644 --- a/src/common/filesystem/source/fs_stringpool.h +++ b/src/common/filesystem/source/fs_stringpool.h @@ -8,7 +8,7 @@ class StringPool friend class FileSystem; friend class FResourceFile; private: - StringPool(size_t blocksize = 10*1024) : TopBlock(nullptr), FreeBlocks(nullptr), BlockSize(blocksize) {} + StringPool(bool _shared, size_t blocksize = 10*1024) : TopBlock(nullptr), FreeBlocks(nullptr), BlockSize(blocksize), shared(_shared) {} public: ~StringPool(); const char* Strdup(const char*); diff --git a/src/common/filesystem/source/resourcefile.cpp b/src/common/filesystem/source/resourcefile.cpp index 079998df9..c86d4e11f 100644 --- a/src/common/filesystem/source/resourcefile.cpp +++ b/src/common/filesystem/source/resourcefile.cpp @@ -332,7 +332,7 @@ FResourceFile *FResourceFile::OpenDirectory(const char *filename, LumpFilterInfo FResourceFile::FResourceFile(const char *filename, StringPool* sp) { - stringpool = sp ? sp : new StringPool; + stringpool = sp ? sp : new StringPool(false); FileName = stringpool->Strdup(filename); } From 99f17f2dcee7802bb5e3dc850d747d4197561cd3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 11 Sep 2023 23:21:12 +0200 Subject: [PATCH 085/223] - fixed several issues with parsing DSDhacked --- src/gamedata/d_dehacked.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index f0ff88c16..a2ab57df6 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -1218,6 +1218,7 @@ static int PatchThing (int thingy) else { DPrintf (DMSG_SPAMMY, "Thing %d\n", thingy); + type = thingytype; info = GetDefaultByType (type); ednum = &type->ActorInfo()->DoomEdNum; } @@ -2929,6 +2930,7 @@ static int PatchSoundNames (int dummy) while ((result = GetLine()) == 1) { + stripwhite(Line2); FString newname = skipwhite (Line2); ReplaceSoundName((int)strtoll(Line1, nullptr, 10), newname); DPrintf (DMSG_SPAMMY, "Sound %d set to:\n%s\n", Line1, newname.GetChars()); @@ -2945,6 +2947,7 @@ static int PatchSpriteNames (int dummy) while ((result = GetLine()) == 1) { + stripwhite(Line2); FString newname = skipwhite (Line2); if (newname.Len() != 4) { @@ -2961,10 +2964,10 @@ static int PatchSpriteNames (int dummy) { OrgSprNames[o] = nulname; } - int v = GetSpriteIndex(newname); - memcpy(OrgSprNames[line1val].c, sprites[v].name, 5); } - + int v = GetSpriteIndex(newname); + memcpy(OrgSprNames[line1val].c, sprites[v].name, 5); + DPrintf (DMSG_SPAMMY, "Sprite %d set to:\n%s\n", Line1, newname.GetChars()); } @@ -3297,16 +3300,15 @@ static void UnloadDehSupp () MBFParamStates.ShrinkToFit(); MBFCodePointers.Clear(); MBFCodePointers.ShrinkToFit(); - // StateMap is not freed here, because if you load a second + // OrgSprNames and StateMap are not freed here, because if you load a second // dehacked patch through some means other than including it - // in the first patch, it won't see the state information + // in the first patch, it won't see the state/sprite information // that was altered by the first. So we need to keep the // StateMap around until all patches have been applied. DehUseCount = 0; Actions.Reset(); OrgHeights.Reset(); CodePConv.Reset(); - OrgSprNames.Reset(); SoundMap.Reset(); InfoNames.Reset(); BitNames.Reset(); @@ -3419,6 +3421,7 @@ static bool LoadDehSupp () } else if (sc.Compare("OrgSprNames")) { + bool addit = OrgSprNames.Size() == 0; sc.MustGetStringName("{"); while (!sc.CheckString("}")) { @@ -3438,7 +3441,7 @@ static bool LoadDehSupp () { sc.ScriptError("Invalid sprite name '%s' (must be 4 characters)", sc.String); } - OrgSprNames.Push(s); + if (addit) OrgSprNames.Push(s); if (sc.CheckString("}")) break; sc.MustGetStringName(","); } @@ -3725,6 +3728,7 @@ void FinishDehPatch () } // Now that all Dehacked patches have been processed, it's okay to free StateMap. StateMap.Reset(); + OrgSprNames.Reset(); TouchedActors.Reset(); EnglishStrings.Clear(); GStrings.SetOverrideStrings(std::move(DehStrings)); From b75a8ed8ff2408e1fa0d3897b3d5520bfdc1bcf8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 11 Sep 2023 23:21:48 +0200 Subject: [PATCH 086/223] - removed pointless heap allocation that never was freed. --- src/gamedata/d_dehacked.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index a2ab57df6..0b4f25576 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -1067,11 +1067,6 @@ static void SetDehParams(FState *state, int codepointer, VMDisassemblyDumper &di bool returnsState = codepointer == 6; - // Fakey fake script position thingamajig. Because NULL cannot be used instead. - // Even if the lump was parsed by an FScanner, there would hardly be a way to - // identify which line is troublesome. - FScriptPosition *pos = new FScriptPosition(FString("DEHACKED"), 0); - // Let's identify the codepointer we're dealing with. PFunction *sym; sym = dyn_cast(PClass::FindActor(NAME_Weapon)->FindSymbol(FName(MBFCodePointers[codepointer].name), true)); From 76734201e61ea6db5bb00f2ba7417c5026982874 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 13 Sep 2023 12:50:42 +0300 Subject: [PATCH 087/223] - updated zlib to 1.3 https://www.zlib.net/zlib-1.3.tar.gz --- libraries/zlib/ChangeLog | 20 +- libraries/zlib/FAQ | 2 +- libraries/zlib/README | 19 +- libraries/zlib/adler32.c | 32 +-- libraries/zlib/compress.c | 21 +- libraries/zlib/crc32.c | 248 ++++++----------- libraries/zlib/deflate.c | 569 ++++++++++++++++---------------------- libraries/zlib/deflate.h | 16 +- libraries/zlib/gzguts.h | 23 +- libraries/zlib/infback.c | 30 +- libraries/zlib/inffast.c | 5 +- libraries/zlib/inffast.h | 2 +- libraries/zlib/inflate.c | 129 ++------- libraries/zlib/inftrees.c | 17 +- libraries/zlib/inftrees.h | 6 +- libraries/zlib/trees.c | 526 +++++++++++++++-------------------- libraries/zlib/uncompr.c | 16 +- libraries/zlib/zconf.h | 8 +- libraries/zlib/zlib.3 | 6 +- libraries/zlib/zlib.3.pdf | Bin 19366 -> 19505 bytes libraries/zlib/zlib.h | 379 ++++++++++++------------- libraries/zlib/zutil.c | 60 ++-- libraries/zlib/zutil.h | 20 +- 23 files changed, 879 insertions(+), 1275 deletions(-) diff --git a/libraries/zlib/ChangeLog b/libraries/zlib/ChangeLog index 457526bc6..8707988ac 100644 --- a/libraries/zlib/ChangeLog +++ b/libraries/zlib/ChangeLog @@ -1,6 +1,24 @@ ChangeLog file for zlib +Changes in 1.3 (18 Aug 2023) +- Remove K&R function definitions and zlib2ansi +- Fix bug in deflateBound() for level 0 and memLevel 9 +- Fix bug when gzungetc() is used immediately after gzopen() +- Fix bug when using gzflush() with a very small buffer +- Fix crash when gzsetparams() attempted for transparent write +- Fix test/example.c to work with FORCE_STORED +- Rewrite of zran in examples (see zran.c version history) +- Fix minizip to allow it to open an empty zip file +- Fix reading disk number start on zip64 files in minizip +- Fix logic error in minizip argument processing +- Add minizip testing to Makefile +- Read multiple bytes instead of byte-by-byte in minizip unzip.c +- Add memory sanitizer to configure (--memory) +- Various portability improvements +- Various documentation improvements +- Various spelling and typo corrections + Changes in 1.2.13 (13 Oct 2022) - Fix configure issue that discarded provided CC definition - Correct incorrect inputs provided to the CRC functions @@ -1445,7 +1463,7 @@ Changes in 0.99 (27 Jan 96) - fix typo in Make_vms.com (f$trnlnm -> f$getsyi) - in fcalloc, normalize pointer if size > 65520 bytes - don't use special fcalloc for 32 bit Borland C++ -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... +- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc. - use Z_BINARY instead of BINARY - document that gzclose after gzdopen will close the file - allow "a" as mode in gzopen diff --git a/libraries/zlib/FAQ b/libraries/zlib/FAQ index 99b7cf92e..55f1cdc22 100644 --- a/libraries/zlib/FAQ +++ b/libraries/zlib/FAQ @@ -4,7 +4,7 @@ If your question is not there, please check the zlib home page http://zlib.net/ which may have more recent information. -The lastest zlib FAQ is at http://zlib.net/zlib_faq.html +The latest zlib FAQ is at http://zlib.net/zlib_faq.html 1. Is zlib Y2K-compliant? diff --git a/libraries/zlib/README b/libraries/zlib/README index ba34d1894..e02fc5aa2 100644 --- a/libraries/zlib/README +++ b/libraries/zlib/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.13 is a general purpose data compression library. All the code is +zlib 1.3 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 @@ -29,18 +29,17 @@ PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. Mark Nelson 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/ . +https://marknelson.us/posts/1997/01/01/zlib-engine.html . -The changes made in version 1.2.13 are documented in the file ChangeLog. +The changes made in version 1.3 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/ . +zlib is available in Java using the java.util.zip package. Follow the API +Documentation link at: https://docs.oracle.com/search/?q=java.util.zip . -A Perl interface to zlib written by Paul Marquess is available -at CPAN (Comprehensive Perl Archive Network) sites, including -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . +A Perl interface to zlib and bzip2 written by Paul Marquess +can be found at https://github.com/pmqs/IO-Compress . A Python interface to zlib written by A.M. Kuchling is available in Python 1.5 and later versions, see @@ -64,7 +63,7 @@ Notes for some targets: - 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 +- On Digital Unix 4.0D (formerly 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 @@ -84,7 +83,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2022 Jean-loup Gailly and Mark Adler + (C) 1995-2023 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 diff --git a/libraries/zlib/adler32.c b/libraries/zlib/adler32.c index d0be4380a..04b81d29b 100644 --- a/libraries/zlib/adler32.c +++ b/libraries/zlib/adler32.c @@ -7,8 +7,6 @@ #include "zutil.h" -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); - #define BASE 65521U /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ @@ -60,11 +58,7 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); #endif /* ========================================================================= */ -uLong ZEXPORT adler32_z(adler, buf, len) - uLong adler; - const Bytef *buf; - z_size_t len; -{ +uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { unsigned long sum2; unsigned n; @@ -131,20 +125,12 @@ uLong ZEXPORT adler32_z(adler, buf, len) } /* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ +uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { return adler32_z(adler, buf, len); } /* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ +local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { unsigned long sum1; unsigned long sum2; unsigned rem; @@ -169,18 +155,10 @@ local uLong adler32_combine_(adler1, adler2, len2) } /* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ +uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { return adler32_combine_(adler1, adler2, len2); } -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ +uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { return adler32_combine_(adler1, adler2, len2); } diff --git a/libraries/zlib/compress.c b/libraries/zlib/compress.c index 2ad5326c1..f43bacf7a 100644 --- a/libraries/zlib/compress.c +++ b/libraries/zlib/compress.c @@ -19,13 +19,8 @@ memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ -int ZEXPORT compress2(dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ +int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen, int level) { z_stream stream; int err; const uInt max = (uInt)-1; @@ -65,12 +60,8 @@ int ZEXPORT compress2(dest, destLen, source, sourceLen, level) /* =========================================================================== */ -int ZEXPORT compress(dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ +int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); } @@ -78,9 +69,7 @@ int ZEXPORT compress(dest, destLen, source, sourceLen) If the default memLevel or windowBits for deflateInit() is changed, then this function needs to be updated. */ -uLong ZEXPORT compressBound(sourceLen) - uLong sourceLen; -{ +uLong ZEXPORT compressBound(uLong sourceLen) { return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + (sourceLen >> 25) + 13; } diff --git a/libraries/zlib/crc32.c b/libraries/zlib/crc32.c index f8357b083..6c38f5c04 100644 --- a/libraries/zlib/crc32.c +++ b/libraries/zlib/crc32.c @@ -103,19 +103,6 @@ # define ARMCRC32 #endif -/* Local functions. */ -local z_crc_t multmodp OF((z_crc_t a, z_crc_t b)); -local z_crc_t x2nmodp OF((z_off64_t n, unsigned k)); - -#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) - local z_word_t byte_swap OF((z_word_t word)); -#endif - -#if defined(W) && !defined(ARMCRC32) - local z_crc_t crc_word OF((z_word_t data)); - local z_word_t crc_word_big OF((z_word_t data)); -#endif - #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) /* Swap the bytes in a z_word_t to convert between little and big endian. Any @@ -123,9 +110,7 @@ local z_crc_t x2nmodp OF((z_off64_t n, unsigned k)); instruction, if one is available. This assumes that word_t is either 32 bits or 64 bits. */ -local z_word_t byte_swap(word) - z_word_t word; -{ +local z_word_t byte_swap(z_word_t word) { # if W == 8 return (word & 0xff00000000000000) >> 56 | @@ -146,24 +131,77 @@ local z_word_t byte_swap(word) } #endif +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Table of powers of x for combining CRC-32s, filled in by make_crc_table() + * below. + */ + local z_crc_t FAR x2n_table[32]; +#else +/* ========================================================================= + * Tables for byte-wise and braided CRC-32 calculations, and a table of powers + * of x for combining CRC-32s, all made by make_crc_table(). + */ +# include "crc32.h" +#endif + /* CRC polynomial. */ #define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ -#ifdef DYNAMIC_CRC_TABLE +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +local z_crc_t multmodp(z_crc_t a, z_crc_t b) { + z_crc_t m, p; + m = (z_crc_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} + +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +local z_crc_t x2nmodp(z_off64_t n, unsigned k) { + z_crc_t p; + + p = (z_crc_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +#ifdef DYNAMIC_CRC_TABLE +/* ========================================================================= + * Build the tables for byte-wise and braided CRC-32 calculations, and a table + * of powers of x for combining CRC-32s. + */ local z_crc_t FAR crc_table[256]; -local z_crc_t FAR x2n_table[32]; -local void make_crc_table OF((void)); #ifdef W local z_word_t FAR crc_big_table[256]; local z_crc_t FAR crc_braid_table[W][256]; local z_word_t FAR crc_braid_big_table[W][256]; - local void braid OF((z_crc_t [][256], z_word_t [][256], int, int)); + local void braid(z_crc_t [][256], z_word_t [][256], int, int); #endif #ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *, int)); - local void write_table32hi OF((FILE *, const z_word_t FAR *, int)); - local void write_table64 OF((FILE *, const z_word_t FAR *, int)); + local void write_table(FILE *, const z_crc_t FAR *, int); + local void write_table32hi(FILE *, const z_word_t FAR *, int); + local void write_table64(FILE *, const z_word_t FAR *, int); #endif /* MAKECRCH */ /* @@ -176,7 +214,6 @@ local void make_crc_table OF((void)); /* Definition of once functionality. */ typedef struct once_s once_t; -local void once OF((once_t *, void (*)(void))); /* Check for the availability of atomics. */ #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ @@ -196,10 +233,7 @@ struct once_s { invoke once() at the same time. The state must be a once_t initialized with ONCE_INIT. */ -local void once(state, init) - once_t *state; - void (*init)(void); -{ +local void once(once_t *state, void (*init)(void)) { if (!atomic_load(&state->done)) { if (atomic_flag_test_and_set(&state->begun)) while (!atomic_load(&state->done)) @@ -222,10 +256,7 @@ struct once_s { /* Test and set. Alas, not atomic, but tries to minimize the period of vulnerability. */ -local int test_and_set OF((int volatile *)); -local int test_and_set(flag) - int volatile *flag; -{ +local int test_and_set(int volatile *flag) { int was; was = *flag; @@ -234,10 +265,7 @@ local int test_and_set(flag) } /* Run the provided init() function once. This is not thread-safe. */ -local void once(state, init) - once_t *state; - void (*init)(void); -{ +local void once(once_t *state, void (*init)(void)) { if (!state->done) { if (test_and_set(&state->begun)) while (!state->done) @@ -279,8 +307,7 @@ local once_t made = ONCE_INIT; combinations of CRC register values and incoming bytes. */ -local void make_crc_table() -{ +local void make_crc_table(void) { unsigned i, j, n; z_crc_t p; @@ -447,11 +474,7 @@ local void make_crc_table() Write the 32-bit values in table[0..k-1] to out, five per line in hexadecimal separated by commas. */ -local void write_table(out, table, k) - FILE *out; - const z_crc_t FAR *table; - int k; -{ +local void write_table(FILE *out, const z_crc_t FAR *table, int k) { int n; for (n = 0; n < k; n++) @@ -464,11 +487,7 @@ local void write_table(out, table, k) Write the high 32-bits of each value in table[0..k-1] to out, five per line in hexadecimal separated by commas. */ -local void write_table32hi(out, table, k) -FILE *out; -const z_word_t FAR *table; -int k; -{ +local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { int n; for (n = 0; n < k; n++) @@ -484,11 +503,7 @@ int k; bits. If not, then the type cast and format string can be adjusted accordingly. */ -local void write_table64(out, table, k) - FILE *out; - const z_word_t FAR *table; - int k; -{ +local void write_table64(FILE *out, const z_word_t FAR *table, int k) { int n; for (n = 0; n < k; n++) @@ -498,8 +513,7 @@ local void write_table64(out, table, k) } /* Actually do the deed. */ -int main() -{ +int main(void) { make_crc_table(); return 0; } @@ -511,12 +525,7 @@ int main() Generate the little and big-endian braid tables for the given n and z_word_t size w. Each array must have room for w blocks of 256 elements. */ -local void braid(ltl, big, n, w) - z_crc_t ltl[][256]; - z_word_t big[][256]; - int n; - int w; -{ +local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { int k; z_crc_t i, p, q; for (k = 0; k < w; k++) { @@ -531,69 +540,13 @@ local void braid(ltl, big, n, w) } #endif -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables for byte-wise and braided CRC-32 calculations, and a table of powers - * of x for combining CRC-32s, all made by make_crc_table(). - */ -#include "crc32.h" #endif /* DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Routines used for CRC calculation. Some are also required for the table - * generation above. - */ - -/* - Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, - reflected. For speed, this requires that a not be zero. - */ -local z_crc_t multmodp(a, b) - z_crc_t a; - z_crc_t b; -{ - z_crc_t m, p; - - m = (z_crc_t)1 << 31; - p = 0; - for (;;) { - if (a & m) { - p ^= b; - if ((a & (m - 1)) == 0) - break; - } - m >>= 1; - b = b & 1 ? (b >> 1) ^ POLY : b >> 1; - } - return p; -} - -/* - Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been - initialized. - */ -local z_crc_t x2nmodp(n, k) - z_off64_t n; - unsigned k; -{ - z_crc_t p; - - p = (z_crc_t)1 << 31; /* x^0 == 1 */ - while (n) { - if (n & 1) - p = multmodp(x2n_table[k & 31], p); - n >>= 1; - k++; - } - return p; -} - /* ========================================================================= * This function can be used by asm versions of crc32(), and to force the * generation of the CRC tables in a threaded application. */ -const z_crc_t FAR * ZEXPORT get_crc_table() -{ +const z_crc_t FAR * ZEXPORT get_crc_table(void) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ @@ -619,11 +572,8 @@ const z_crc_t FAR * ZEXPORT get_crc_table() #define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ #define Z_BATCH_MIN 800 /* fewest words in a final batch */ -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { z_crc_t val; z_word_t crc1, crc2; const z_word_t *word; @@ -723,18 +673,14 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) least-significant byte of the word as the first byte of data, without any pre or post conditioning. This is used to combine the CRCs of each braid. */ -local z_crc_t crc_word(data) - z_word_t data; -{ +local z_crc_t crc_word(z_word_t data) { int k; for (k = 0; k < W; k++) data = (data >> 8) ^ crc_table[data & 0xff]; return (z_crc_t)data; } -local z_word_t crc_word_big(data) - z_word_t data; -{ +local z_word_t crc_word_big(z_word_t data) { int k; for (k = 0; k < W; k++) data = (data << 8) ^ @@ -745,11 +691,8 @@ local z_word_t crc_word_big(data) #endif /* ========================================================================= */ -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ +unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, + z_size_t len) { /* Return initial CRC, if requested. */ if (buf == Z_NULL) return 0; @@ -781,8 +724,8 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) words = (z_word_t const *)buf; /* Do endian check at execution time instead of compile time, since ARM - processors can change the endianess at execution time. If the - compiler knows what the endianess will be, it can optimize out the + processors can change the endianness at execution time. If the + compiler knows what the endianness will be, it can optimize out the check and the unused branch. */ endian = 1; if (*(unsigned char *)&endian) { @@ -1069,20 +1012,13 @@ unsigned long ZEXPORT crc32_z(crc, buf, len) #endif /* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ +unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, + uInt len) { return crc32_z(crc, buf, len); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ +uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ @@ -1090,18 +1026,12 @@ uLong ZEXPORT crc32_combine64(crc1, crc2, len2) } /* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ +uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { return crc32_combine64(crc1, crc2, (z_off64_t)len2); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen64(len2) - z_off64_t len2; -{ +uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { #ifdef DYNAMIC_CRC_TABLE once(&made, make_crc_table); #endif /* DYNAMIC_CRC_TABLE */ @@ -1109,17 +1039,11 @@ uLong ZEXPORT crc32_combine_gen64(len2) } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen(len2) - z_off_t len2; -{ +uLong ZEXPORT crc32_combine_gen(z_off_t len2) { return crc32_combine_gen64((z_off64_t)len2); } /* ========================================================================= */ -uLong ZEXPORT crc32_combine_op(crc1, crc2, op) - uLong crc1; - uLong crc2; - uLong op; -{ +uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { return multmodp(op, crc1) ^ (crc2 & 0xffffffff); } diff --git a/libraries/zlib/deflate.c b/libraries/zlib/deflate.c index 4a689db35..bd0117519 100644 --- a/libraries/zlib/deflate.c +++ b/libraries/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler "; + " deflate 1.3 Copyright 1995-2023 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -60,9 +60,6 @@ const char deflate_copyright[] = copyright string in the executable of your product. */ -/* =========================================================================== - * Function prototypes. - */ typedef enum { need_more, /* block not completed, need more input or more output */ block_done, /* block flush performed */ @@ -70,29 +67,16 @@ typedef enum { finish_done /* finish done, accept no more input or output */ } block_state; -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +typedef block_state (*compress_func)(deflate_state *s, int flush); /* Compression function. Returns the block state after the call. */ -local int deflateStateCheck OF((z_streamp strm)); -local void slide_hash OF((deflate_state *s)); -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_stored(deflate_state *s, int flush); +local block_state deflate_fast(deflate_state *s, int flush); #ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -local uInt longest_match OF((deflate_state *s, IPos cur_match)); - -#ifdef ZLIB_DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); +local block_state deflate_slow(deflate_state *s, int flush); #endif +local block_state deflate_rle(deflate_state *s, int flush); +local block_state deflate_huff(deflate_state *s, int flush); /* =========================================================================== * Local data @@ -195,9 +179,12 @@ local const config configuration_table[10] = { * bit values at the expense of memory usage). We slide even when level == 0 to * keep the hash table consistent if we switch back to level > 0 later. */ -local void slide_hash(s) - deflate_state *s; -{ +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) + __attribute__((no_sanitize("memory"))) +# endif +#endif +local void slide_hash(deflate_state *s) { unsigned n, m; Posf *p; uInt wsize = s->w_size; @@ -221,30 +208,177 @@ local void slide_hash(s) #endif } +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) { + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, buf, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, buf, len); + } +#endif + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(deflate_state *s) { + unsigned n; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize + MAX_DIST(s)) { + + zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + if (s->insert > s->strstart) + s->insert = s->strstart; + slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + while (s->insert) { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); +#ifndef FASTEST + s->prev[str & s->w_mask] = s->head[s->ins_h]; +#endif + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to MAX_MATCH since the longest match + * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } + + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + /* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ +int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, + int stream_size) { return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ +int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, int strategy, + const char *version, int stream_size) { deflate_state *s; int wrap = 1; static const char my_version[] = ZLIB_VERSION; @@ -386,9 +520,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, /* ========================================================================= * Check for a valid deflate stream state. Return 0 if ok, 1 if not. */ -local int deflateStateCheck(strm) - z_streamp strm; -{ +local int deflateStateCheck(z_streamp strm) { deflate_state *s; if (strm == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) @@ -409,11 +541,8 @@ local int deflateStateCheck(strm) } /* ========================================================================= */ -int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ +int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { deflate_state *s; uInt str, n; int wrap; @@ -478,11 +607,8 @@ int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) } /* ========================================================================= */ -int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) - z_streamp strm; - Bytef *dictionary; - uInt *dictLength; -{ +int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { deflate_state *s; uInt len; @@ -500,9 +626,7 @@ int ZEXPORT deflateGetDictionary(strm, dictionary, dictLength) } /* ========================================================================= */ -int ZEXPORT deflateResetKeep(strm) - z_streamp strm; -{ +int ZEXPORT deflateResetKeep(z_streamp strm) { deflate_state *s; if (deflateStateCheck(strm)) { @@ -537,10 +661,32 @@ int ZEXPORT deflateResetKeep(strm) return Z_OK; } +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init(deflate_state *s) { + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +} + /* ========================================================================= */ -int ZEXPORT deflateReset(strm) - z_streamp strm; -{ +int ZEXPORT deflateReset(z_streamp strm) { int ret; ret = deflateResetKeep(strm); @@ -550,10 +696,7 @@ int ZEXPORT deflateReset(strm) } /* ========================================================================= */ -int ZEXPORT deflateSetHeader(strm, head) - z_streamp strm; - gz_headerp head; -{ +int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { if (deflateStateCheck(strm) || strm->state->wrap != 2) return Z_STREAM_ERROR; strm->state->gzhead = head; @@ -561,11 +704,7 @@ int ZEXPORT deflateSetHeader(strm, head) } /* ========================================================================= */ -int ZEXPORT deflatePending(strm, pending, bits) - unsigned *pending; - int *bits; - z_streamp strm; -{ +int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; if (pending != Z_NULL) *pending = strm->state->pending; @@ -575,11 +714,7 @@ int ZEXPORT deflatePending(strm, pending, bits) } /* ========================================================================= */ -int ZEXPORT deflatePrime(strm, bits, value) - z_streamp strm; - int bits; - int value; -{ +int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { deflate_state *s; int put; @@ -602,11 +737,7 @@ int ZEXPORT deflatePrime(strm, bits, value) } /* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ +int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) { deflate_state *s; compress_func func; @@ -651,13 +782,8 @@ int ZEXPORT deflateParams(strm, level, strategy) } /* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ +int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, + int nice_length, int max_chain) { deflate_state *s; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -693,10 +819,7 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) * * Shifts are used to approximate divisions, for speed. */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ +uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { deflate_state *s; uLong fixedlen, storelen, wraplen; @@ -752,7 +875,8 @@ uLong ZEXPORT deflateBound(strm, sourceLen) /* if not default parameters, return one of the conservative bounds */ if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return (s->w_bits <= s->hash_bits ? fixedlen : storelen) + wraplen; + return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + + wraplen; /* default settings: return tight bound for that case -- ~0.03% overhead plus a small constant */ @@ -765,10 +889,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ -local void putShortMSB(s, b) - deflate_state *s; - uInt b; -{ +local void putShortMSB(deflate_state *s, uInt b) { put_byte(s, (Byte)(b >> 8)); put_byte(s, (Byte)(b & 0xff)); } @@ -779,9 +900,7 @@ local void putShortMSB(s, b) * applications may wish to modify it to avoid allocating a large * strm->next_out buffer and copying into it. (See also read_buf()). */ -local void flush_pending(strm) - z_streamp strm; -{ +local void flush_pending(z_streamp strm) { unsigned len; deflate_state *s = strm->state; @@ -812,10 +931,7 @@ local void flush_pending(strm) } while (0) /* ========================================================================= */ -int ZEXPORT deflate(strm, flush) - z_streamp strm; - int flush; -{ +int ZEXPORT deflate(z_streamp strm, int flush) { int old_flush; /* value of flush param for previous deflate call */ deflate_state *s; @@ -1127,9 +1243,7 @@ int ZEXPORT deflate(strm, flush) } /* ========================================================================= */ -int ZEXPORT deflateEnd(strm) - z_streamp strm; -{ +int ZEXPORT deflateEnd(z_streamp strm) { int status; if (deflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1153,11 +1267,10 @@ int ZEXPORT deflateEnd(strm) * To simplify the source, this is not supported for 16-bit MSDOS (which * doesn't have enough memory anyway to duplicate compression states). */ -int ZEXPORT deflateCopy(dest, source) - z_streamp dest; - z_streamp source; -{ +int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { #ifdef MAXSEG_64K + (void)dest; + (void)source; return Z_STREAM_ERROR; #else deflate_state *ds; @@ -1205,66 +1318,6 @@ int ZEXPORT deflateCopy(dest, source) #endif /* MAXSEG_64K */ } -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local unsigned read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init(s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -} - #ifndef FASTEST /* =========================================================================== * Set match_start to the longest match starting at the given string and @@ -1275,10 +1328,7 @@ local void lm_init(s) * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 * OUT assertion: the match length is not greater than s->lookahead. */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ +local uInt longest_match(deflate_state *s, IPos cur_match) { unsigned chain_length = s->max_chain_length;/* max hash chain length */ register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ @@ -1426,10 +1476,7 @@ local uInt longest_match(s, cur_match) /* --------------------------------------------------------------------------- * Optimized version for FASTEST only */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ +local uInt longest_match(deflate_state *s, IPos cur_match) { register Bytef *scan = s->window + s->strstart; /* current string */ register Bytef *match; /* matched string */ register int len; /* length of current match */ @@ -1490,11 +1537,7 @@ local uInt longest_match(s, cur_match) /* =========================================================================== * Check that the match at match_start is indeed a match. */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ +local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ if (zmemcmp(s->window + match, s->window + start, length) != EQUAL) { @@ -1514,137 +1557,6 @@ local void check_match(s, start, match, length) # define check_match(s, start, match, length) #endif /* ZLIB_DEBUG */ -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - unsigned n; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize + MAX_DIST(s)) { - - zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - if (s->insert > s->strstart) - s->insert = s->strstart; - slide_hash(s); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. @@ -1687,10 +1599,7 @@ local void fill_window(s) * copied. It is most efficient with large input and output buffers, which * maximizes the opportunities to have a single copy from next_in to next_out. */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_stored(deflate_state *s, int flush) { /* Smallest worthy block size when not flushing or finishing. By default * this is 32K. This can be as small as 507 bytes for memLevel == 1. For * large input and output buffers, the stored block size will be larger. @@ -1874,10 +1783,7 @@ local block_state deflate_stored(s, flush) * new strings in the dictionary only for unmatched strings or for short * matches. It is used only for the fast compression options. */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_fast(deflate_state *s, int flush) { IPos hash_head; /* head of the hash chain */ int bflush; /* set if current block must be flushed */ @@ -1976,10 +1882,7 @@ local block_state deflate_fast(s, flush) * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_slow(deflate_state *s, int flush) { IPos hash_head; /* head of hash chain */ int bflush; /* set if current block must be flushed */ @@ -2107,10 +2010,7 @@ local block_state deflate_slow(s, flush) * one. Do not maintain a hash table. (It will be regenerated if this run of * deflate switches away from Z_RLE.) */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_rle(deflate_state *s, int flush) { int bflush; /* set if current block must be flushed */ uInt prev; /* byte at distance one to match */ Bytef *scan, *strend; /* scan goes up to strend for length of run */ @@ -2181,10 +2081,7 @@ local block_state deflate_rle(s, flush) * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. * (It will be regenerated if this run of deflate switches away from Huffman.) */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ +local block_state deflate_huff(deflate_state *s, int flush) { int bflush; /* set if current block must be flushed */ for (;;) { diff --git a/libraries/zlib/deflate.h b/libraries/zlib/deflate.h index 1a06cd5f2..869679142 100644 --- a/libraries/zlib/deflate.h +++ b/libraries/zlib/deflate.h @@ -291,14 +291,14 @@ typedef struct internal_state { 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)); +void ZLIB_INTERNAL _tr_init(deflate_state *s); +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last); +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); +void ZLIB_INTERNAL _tr_align(deflate_state *s); +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last); #define d_code(dist) \ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) diff --git a/libraries/zlib/gzguts.h b/libraries/zlib/gzguts.h index 57faf3716..f9375047e 100644 --- a/libraries/zlib/gzguts.h +++ b/libraries/zlib/gzguts.h @@ -7,9 +7,8 @@ # ifndef _LARGEFILE_SOURCE # define _LARGEFILE_SOURCE 1 # endif -# ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -# endif +# undef _FILE_OFFSET_BITS +# undef _TIME_BITS #endif #ifdef HAVE_HIDDEN @@ -119,8 +118,8 @@ /* gz* functions always use library allocation functions */ #ifndef STDC - extern voidp malloc OF((uInt size)); - extern void free OF((voidpf ptr)); + extern voidp malloc(uInt size); + extern void free(voidpf ptr); #endif /* get errno and strerror definition */ @@ -138,10 +137,10 @@ /* 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)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); #endif /* default memLevel */ @@ -203,9 +202,9 @@ typedef struct { typedef gz_state FAR *gz_statep; /* shared functions */ -void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); +void ZLIB_INTERNAL gz_error(gz_statep, int, const char *); #if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); +char ZLIB_INTERNAL *gz_strwinerror(DWORD error); #endif /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t @@ -214,6 +213,6 @@ char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); #ifdef INT_MAX # define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) #else -unsigned ZLIB_INTERNAL gz_intmax OF((void)); +unsigned ZLIB_INTERNAL gz_intmax(void); # define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) #endif diff --git a/libraries/zlib/infback.c b/libraries/zlib/infback.c index babeaf180..e7b25b307 100644 --- a/libraries/zlib/infback.c +++ b/libraries/zlib/infback.c @@ -15,9 +15,6 @@ #include "inflate.h" #include "inffast.h" -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - /* strm provides memory allocation functions in zalloc and zfree, or Z_NULL to use the library memory allocation functions. @@ -25,13 +22,9 @@ local void fixedtables OF((struct inflate_state FAR *state)); windowBits is in the range 8..15, and window is a user-supplied window and output buffer that is 2**windowBits bytes. */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ +int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, const char *version, + int stream_size) { struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || @@ -80,9 +73,7 @@ int stream_size; used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ +local void fixedtables(struct inflate_state FAR *state) { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; @@ -248,13 +239,8 @@ struct inflate_state FAR *state; inflateBack() can also return Z_STREAM_ERROR if the input parameters are not correct, i.e. strm is Z_NULL or the state was not initialized. */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ +int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc) { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ @@ -632,9 +618,7 @@ void FAR *out_desc; return ret; } -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ +int ZEXPORT inflateBackEnd(z_streamp strm) { if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; ZFREE(strm, strm->state); diff --git a/libraries/zlib/inffast.c b/libraries/zlib/inffast.c index 1fec7f363..9354676e7 100644 --- a/libraries/zlib/inffast.c +++ b/libraries/zlib/inffast.c @@ -47,10 +47,7 @@ requires strm->avail_out >= 258 for each loop to avoid checking for output space. */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { struct inflate_state FAR *state; z_const unsigned char FAR *in; /* local strm->next_in */ z_const unsigned char FAR *last; /* have enough input while in < last */ diff --git a/libraries/zlib/inffast.h b/libraries/zlib/inffast.h index e5c1aa4ca..49c6d156c 100644 --- a/libraries/zlib/inffast.h +++ b/libraries/zlib/inffast.h @@ -8,4 +8,4 @@ subject to change. Applications should only use zlib.h. */ -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); +void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start); diff --git a/libraries/zlib/inflate.c b/libraries/zlib/inflate.c index 8acbef44e..b0757a9b2 100644 --- a/libraries/zlib/inflate.c +++ b/libraries/zlib/inflate.c @@ -91,20 +91,7 @@ # endif #endif -/* function prototypes */ -local int inflateStateCheck OF((z_streamp strm)); -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, - unsigned len)); - -local int inflateStateCheck(strm) -z_streamp strm; -{ +local int inflateStateCheck(z_streamp strm) { struct inflate_state FAR *state; if (strm == Z_NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) @@ -116,9 +103,7 @@ z_streamp strm; return 0; } -int ZEXPORT inflateResetKeep(strm) -z_streamp strm; -{ +int ZEXPORT inflateResetKeep(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -142,9 +127,7 @@ z_streamp strm; return Z_OK; } -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ +int ZEXPORT inflateReset(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -155,10 +138,7 @@ z_streamp strm; return inflateResetKeep(strm); } -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ +int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { int wrap; struct inflate_state FAR *state; @@ -195,12 +175,8 @@ int windowBits; return inflateReset(strm); } -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ +int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size) { int ret; struct inflate_state FAR *state; @@ -239,22 +215,17 @@ int stream_size; return ret; } -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ +int ZEXPORT inflateInit_(z_streamp strm, const char *version, + int stream_size) { return inflateInit2_(strm, DEF_WBITS, version, stream_size); } -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ +int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (bits == 0) + return Z_OK; state = (struct inflate_state FAR *)strm->state; if (bits < 0) { state->hold = 0; @@ -278,9 +249,7 @@ int value; used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ +local void fixedtables(struct inflate_state FAR *state) { #ifdef BUILDFIXED static int virgin = 1; static code *lenfix, *distfix; @@ -342,7 +311,7 @@ struct inflate_state FAR *state; a.out > inffixed.h */ -void makefixed() +void makefixed(void) { unsigned low, size; struct inflate_state state; @@ -396,11 +365,7 @@ void makefixed() output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ -local int updatewindow(strm, end, copy) -z_streamp strm; -const Bytef *end; -unsigned copy; -{ +local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { struct inflate_state FAR *state; unsigned dist; @@ -622,10 +587,7 @@ unsigned copy; will return Z_BUF_ERROR if it has not reached the end of the stream. */ -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ +int ZEXPORT inflate(z_streamp strm, int flush) { struct inflate_state FAR *state; z_const unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ @@ -1301,9 +1263,7 @@ int flush; return ret; } -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ +int ZEXPORT inflateEnd(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1315,11 +1275,8 @@ z_streamp strm; return Z_OK; } -int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; -Bytef *dictionary; -uInt *dictLength; -{ +int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, + uInt *dictLength) { struct inflate_state FAR *state; /* check state */ @@ -1338,11 +1295,8 @@ uInt *dictLength; return Z_OK; } -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ +int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, + uInt dictLength) { struct inflate_state FAR *state; unsigned long dictid; int ret; @@ -1373,10 +1327,7 @@ uInt dictLength; return Z_OK; } -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ +int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { struct inflate_state FAR *state; /* check state */ @@ -1401,11 +1352,8 @@ gz_headerp head; called again with more data and the *have state. *have is initialized to zero for the first call. */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -const unsigned char FAR *buf; -unsigned len; -{ +local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, + unsigned len) { unsigned got; unsigned next; @@ -1424,9 +1372,7 @@ unsigned len; return next; } -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ +int ZEXPORT inflateSync(z_streamp strm) { unsigned len; /* number of bytes to look at or looked at */ int flags; /* temporary to save header status */ unsigned long in, out; /* temporary to save total_in and total_out */ @@ -1482,9 +1428,7 @@ z_streamp strm; block. When decompressing, PPP checks that at the end of input packet, inflate is waiting for these length bytes. */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ +int ZEXPORT inflateSyncPoint(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1492,10 +1436,7 @@ z_streamp strm; return state->mode == STORED && state->bits == 0; } -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ +int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { struct inflate_state FAR *state; struct inflate_state FAR *copy; unsigned char FAR *window; @@ -1539,10 +1480,7 @@ z_streamp source; return Z_OK; } -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ +int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1557,10 +1495,7 @@ int subvert; #endif } -int ZEXPORT inflateValidate(strm, check) -z_streamp strm; -int check; -{ +int ZEXPORT inflateValidate(z_streamp strm, int check) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return Z_STREAM_ERROR; @@ -1572,9 +1507,7 @@ int check; return Z_OK; } -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ +long ZEXPORT inflateMark(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) @@ -1585,9 +1518,7 @@ z_streamp strm; (state->mode == MATCH ? state->was - state->length : 0)); } -unsigned long ZEXPORT inflateCodesUsed(strm) -z_streamp strm; -{ +unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { struct inflate_state FAR *state; if (inflateStateCheck(strm)) return (unsigned long)-1; state = (struct inflate_state FAR *)strm->state; diff --git a/libraries/zlib/inftrees.c b/libraries/zlib/inftrees.c index 57d2793be..8a208c2da 100644 --- a/libraries/zlib/inftrees.c +++ b/libraries/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2022 Mark Adler + * Copyright (C) 1995-2023 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.13 Copyright 1995-2022 Mark Adler "; + " inflate 1.3 Copyright 1995-2023 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -29,14 +29,9 @@ const char inflate_copyright[] = table index bits. It will differ if the request is greater than the longest code or if it is less than the shortest code. */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work) { unsigned len; /* a code's length in bits */ unsigned sym; /* index of code symbols */ unsigned min, max; /* minimum and maximum code lengths */ @@ -62,7 +57,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 194, 65}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/libraries/zlib/inftrees.h b/libraries/zlib/inftrees.h index f53665311..a10712d8c 100644 --- a/libraries/zlib/inftrees.h +++ b/libraries/zlib/inftrees.h @@ -57,6 +57,6 @@ typedef enum { 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)); +int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work); diff --git a/libraries/zlib/trees.c b/libraries/zlib/trees.c index 5f305c472..8dbdc40ba 100644 --- a/libraries/zlib/trees.c +++ b/libraries/zlib/trees.c @@ -122,39 +122,116 @@ struct static_tree_desc_s { int max_length; /* max bit length for the codes */ }; -local const static_tree_desc static_l_desc = +#ifdef NO_INIT_GLOBAL_POINTERS +# define TCONST +#else +# define TCONST const +#endif + +local TCONST static_tree_desc static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; -local const static_tree_desc static_d_desc = +local TCONST static_tree_desc static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; -local const static_tree_desc static_bl_desc = +local TCONST static_tree_desc static_bl_desc = {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== - * Local (static) routines in this file. + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, const ct_data *ltree, - const ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned code, int len)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(unsigned code, int len) { + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(deflate_state *s) { + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(deflate_state *s) { + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->bits_sent = (s->bits_sent + 7) & ~7; +#endif +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits - 1]) << 1; + next_code[bits] = (ush)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = (ush)bi_reverse(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); + } +} #ifdef GEN_TREES_H -local void gen_trees_header OF((void)); +local void gen_trees_header(void); #endif #ifndef ZLIB_DEBUG @@ -167,27 +244,12 @@ local void gen_trees_header OF((void)); send_bits(s, tree[c].Code, tree[c].Len); } #endif -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef ZLIB_DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ +local void send_bits(deflate_state *s, int value, int length) { Tracevv((stderr," l %2d v %4x ", length, value)); Assert(length > 0 && length <= 15, "invalid length"); s->bits_sent += (ulg)length; @@ -229,8 +291,7 @@ local void send_bits(s, value, length) /* =========================================================================== * Initialize the various 'constant' tables. */ -local void tr_static_init() -{ +local void tr_static_init(void) { #if defined(GEN_TREES_H) || !defined(STDC) static int static_init_done = 0; int n; /* iterates over tree elements */ @@ -323,8 +384,7 @@ local void tr_static_init() ((i) == (last)? "\n};\n\n" : \ ((i) % (width) == (width) - 1 ? ",\n" : ", ")) -void gen_trees_header() -{ +void gen_trees_header(void) { FILE *header = fopen("trees.h", "w"); int i; @@ -373,12 +433,26 @@ void gen_trees_header() } #endif /* GEN_TREES_H */ +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(deflate_state *s) { + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->sym_next = s->matches = 0; +} + /* =========================================================================== * Initialize the tree data structures for a new zlib stream. */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ +void ZLIB_INTERNAL _tr_init(deflate_state *s) { tr_static_init(); s->l_desc.dyn_tree = s->dyn_ltree; @@ -401,24 +475,6 @@ void ZLIB_INTERNAL _tr_init(s) init_block(s); } -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->sym_next = s->matches = 0; -} - #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ @@ -448,11 +504,7 @@ local void init_block(s) * when the heap property is re-established (each father smaller than its * two sons). */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ +local void pqdownheap(deflate_state *s, ct_data *tree, int k) { int v = s->heap[k]; int j = k << 1; /* left son of k */ while (j <= s->heap_len) { @@ -483,10 +535,7 @@ local void pqdownheap(s, tree, k) * The length opt_len is updated; static_len is also updated if stree is * not null. */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ +local void gen_bitlen(deflate_state *s, tree_desc *desc) { ct_data *tree = desc->dyn_tree; int max_code = desc->max_code; const ct_data *stree = desc->stat_desc->static_tree; @@ -561,48 +610,9 @@ local void gen_bitlen(s, desc) } } -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes(tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - unsigned code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = (ush)code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = (ush)bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); - } -} +#ifdef DUMP_BL_TREE +# include +#endif /* =========================================================================== * Construct one Huffman tree and assigns the code bit strings and lengths. @@ -612,10 +622,7 @@ local void gen_codes(tree, max_code, bl_count) * and corresponding code. The length opt_len is updated; static_len is * also updated if stree is not null. The field max_code is set. */ -local void build_tree(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ +local void build_tree(deflate_state *s, tree_desc *desc) { ct_data *tree = desc->dyn_tree; const ct_data *stree = desc->stat_desc->static_tree; int elems = desc->stat_desc->elems; @@ -700,11 +707,7 @@ local void build_tree(s, desc) * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ -local void scan_tree(s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ +local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ @@ -745,11 +748,7 @@ local void scan_tree(s, tree, max_code) * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ -local void send_tree(s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ +local void send_tree(deflate_state *s, ct_data *tree, int max_code) { int n; /* iterates over all tree elements */ int prevlen = -1; /* last emitted length */ int curlen; /* length of current code */ @@ -796,9 +795,7 @@ local void send_tree(s, tree, max_code) * Construct the Huffman tree for the bit lengths and return the index in * bl_order of the last bit length code to send. */ -local int build_bl_tree(s) - deflate_state *s; -{ +local int build_bl_tree(deflate_state *s) { int max_blindex; /* index of last bit length code of non zero freq */ /* Determine the bit length frequencies for literal and distance trees */ @@ -831,10 +828,8 @@ local int build_bl_tree(s) * lengths of the bit length codes, the literal tree and the distance tree. * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ +local void send_all_trees(deflate_state *s, int lcodes, int dcodes, + int blcodes) { int rank; /* index in bl_order */ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); @@ -860,12 +855,8 @@ local void send_all_trees(s, lcodes, dcodes, blcodes) /* =========================================================================== * Send a stored block */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ +void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ bi_windup(s); /* align on byte boundary */ put_short(s, (ush)stored_len); @@ -884,9 +875,7 @@ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) /* =========================================================================== * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) */ -void ZLIB_INTERNAL _tr_flush_bits(s) - deflate_state *s; -{ +void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { bi_flush(s); } @@ -894,9 +883,7 @@ void ZLIB_INTERNAL _tr_flush_bits(s) * Send one empty static block to give enough lookahead for inflate. * This takes 10 bits, of which 7 may remain in the bit buffer. */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ +void ZLIB_INTERNAL _tr_align(deflate_state *s) { send_bits(s, STATIC_TREES<<1, 3); send_code(s, END_BLOCK, static_ltree); #ifdef ZLIB_DEBUG @@ -905,16 +892,99 @@ void ZLIB_INTERNAL _tr_align(s) bi_flush(s); } +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(deflate_state *s, const ct_data *ltree, + const ct_data *dtree) { + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned sx = 0; /* running index in sym_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->sym_next != 0) do { + dist = s->sym_buf[sx++] & 0xff; + dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; + lc = s->sym_buf[sx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS + 1, ltree); /* send length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= (unsigned)base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and sym_buf is ok: */ + Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); + + } while (sx < s->sym_next); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "block list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +local int detect_data_type(deflate_state *s) { + /* block_mask is the bit mask of block-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long block_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("block-listed") bytes. */ + for (n = 0; n <= 31; n++, block_mask >>= 1) + if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("allow-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 + || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "block-listed" or "allow-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + /* =========================================================================== * Determine the best encoding for the current block: dynamic trees, static * trees or store, and write out the encoded block. */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ +void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, + ulg stored_len, int last) { ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ int max_blindex = 0; /* index of last bit length code of non zero freq */ @@ -1011,11 +1081,7 @@ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ -int ZLIB_INTERNAL _tr_tally(s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length - MIN_MATCH or unmatched char (dist==0) */ -{ +int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; @@ -1035,147 +1101,3 @@ int ZLIB_INTERNAL _tr_tally(s, dist, lc) } return (s->sym_next == s->sym_end); } - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - const ct_data *ltree; /* literal tree */ - const ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->sym_next != 0) do { - dist = s->sym_buf[sx++] & 0xff; - dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; - lc = s->sym_buf[sx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS + 1, ltree); /* send length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= (unsigned)base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and sym_buf is ok: */ - Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - - } while (sx < s->sym_next); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long block_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>= 1) - if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("allow-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent + 7) & ~7; -#endif -} diff --git a/libraries/zlib/uncompr.c b/libraries/zlib/uncompr.c index f9532f46c..5e256663b 100644 --- a/libraries/zlib/uncompr.c +++ b/libraries/zlib/uncompr.c @@ -24,12 +24,8 @@ Z_DATA_ERROR if the input data was corrupted, including if the input data is an incomplete zlib stream. */ -int ZEXPORT uncompress2(dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong *sourceLen; -{ +int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong *sourceLen) { z_stream stream; int err; const uInt max = (uInt)-1; @@ -83,11 +79,7 @@ int ZEXPORT uncompress2(dest, destLen, source, sourceLen) err; } -int ZEXPORT uncompress(dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ +int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, + uLong sourceLen) { return uncompress2(dest, destLen, source, &sourceLen); } diff --git a/libraries/zlib/zconf.h b/libraries/zlib/zconf.h index bf977d3e7..fb76ffe31 100644 --- a/libraries/zlib/zconf.h +++ b/libraries/zlib/zconf.h @@ -241,7 +241,11 @@ #endif #ifdef Z_SOLO - typedef unsigned long z_size_t; +# ifdef _WIN64 + typedef unsigned long long z_size_t; +# else + typedef unsigned long z_size_t; +# endif #else # define z_longlong long long # if defined(NO_SIZE_T) @@ -520,7 +524,7 @@ typedef uLong FAR uLongf; #if !defined(_WIN32) && defined(Z_LARGE64) # define z_off64_t off64_t #else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +# if defined(_WIN32) && !defined(__GNUC__) # define z_off64_t __int64 # else # define z_off64_t z_off_t diff --git a/libraries/zlib/zlib.3 b/libraries/zlib/zlib.3 index 6f6e91404..4dd289675 100644 --- a/libraries/zlib/zlib.3 +++ b/libraries/zlib/zlib.3 @@ -1,4 +1,4 @@ -.TH ZLIB 3 "13 Oct 2022" +.TH ZLIB 3 "18 Aug 2023" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS @@ -105,9 +105,9 @@ before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). .SH AUTHORS AND LICENSE -Version 1.2.13 +Version 1.3 .LP -Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler +Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler .LP This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/libraries/zlib/zlib.3.pdf b/libraries/zlib/zlib.3.pdf index 8132d840c861ea6823b8ec0b41ee5050ea56ff15..da12d37183a7371513c0991fd14a7d932fd42e84 100644 GIT binary patch delta 13422 zcmZ2BopIv~#tEP5PYBjt4?lCeDfCf>-i~+s*62qa*SmSmYmKk!r7$iPML|Q33oHpU z|Ft~{{?z|+o-~`n)0|14!ZLLkjBW2O_n-gnWBMTtb)Nq-=C6J$sobAF|NM?$x`y^) z(VvP6%L*qy&==!R|CQ<|4|E#HPWtIN@$<0+#mvzpaNnR%R_tN#%>vCRA+jBm) z1h>oXD=(bf*lN;!;lxglq*-k#ddYuuetdZJcWK>8IcB*tJ0-sT4V&uyNqd+rUwOf9_$+;MC)9 zr2E)=1b=s^e4_Vab=R8ivaR#aR=P-frv$t+Fx$U+?s500J;C$R?nTDO-`lsVvU+dD z?~nC|Hy@A9>GM0iV#2wq(i<0#+blIqKV(zxIPt?&){~rbRHy9hmq=Y$6}3%8z27x< zg{sramj>^n9eyMGhxUKKAaP z0;;n97wbXG4E5Fx1-|;x~4DY_jR3%hI14EYyE) zsPI{QLr-o??tb0Z?pwQBTzrM53(uJT>T}-Y@(sz3xAfLu|5^7|NOAIqAfZ&^?Y&Gy}x#y<>a3#U}%(P`263+ zQ#QSsI&TxtdH0Jw;LS@CxUzaxJafWVc zwNMKZVVfUy$wpy|N&m?i7X{`d)UYsKuV8BK{mUSJ#(LF(>6cofgN~H%Ja_FVo6wWf zJ}p*}-FvOJ-aGCc#CBm*PC3&qO;JJl3A$e&Z@d3?mhHLVS>)v339)~S=WDxge2K7G=lGyrsY1Hzc@dk=iHa$#weC_IYWzRF+UO|PR-CHD zc`9!+Yt8dlCe!X%8q}+;+0DPfYtkbl$A$NU83j9!uP;AX#T&Qw6W_LqCfCws&!c_H zJx;CdGMU2J`K_gJ!uqb6t5_qY0%XnQTBjUmes3)0ZdDsssTc9oG?FQQQMMO@S|+1= zy=Y$W8;_NT7te_6=A_<&v~I2V^f%eDYu8J8bCySs@;6@jz_;;F zbFxC{&ZkcvY>*dXzv7ZpAAiPo9h0$hh>Y-|omUIXSa)Rd-VT}Ss%JShD#Tf%vBxW? z>~p~GC%J1IXOzGA7H)Y z@!x9EvzyD<7dTuH<2PP2k;A_x=840h7dpMdy#3lATt!}%MBV85^U#OMG1_O|8Wq83 z(?2f#DW_e0yIx@Kl+BeLavYl%WOIfIZxOor{-g@;B*&W%^Zy5G)|m<&d&xJC$xW!c z^?3f%yhYYVr{*5wc*o4=zK{RKWAh&?9k@<~sC{&hicpy#@NL2}tqBig zmoA9DTauuz!5GjMHP`#fEUtx3T`spam1q2Yq+)9;Y#h7j^l_;vSJ{$6GXJtJ@4o64 z$h7r{+HU=xhVn&cycyTzWcw&bhi>Xf4!zhJxm|UF_g<@toms&QaeWa+c?^Gqn1vQg zYPBUPXiPZoJ@>KMvb!d=TkF+I6IFTxQiV*^y60B>4f=6OCa7Y9!oj-KtrH$+VtG@4&JVdI7QtJCs@xwR_yJ16O6 zFJKN9ahVZt)Nq|f%Sy4k`V3ahY&MRI&pi!vn?LoU%=GDguWudQsIz9a=!WpM^}0c; zosap?;^F&h$}>NEWm1N~GTW(NcK2+FX4*YX3}TP{{M=A|nf4LX*y z=}Xs<+sp2+FZrQzglR{PhGVA8%M$&mEX_VTBG;EG^6z_gTQ*2)$ENECCB5fHoV@w` z?+mM_FTQcI9p5T^zE#q9@(Isfi{9$>Xf`m{=bk##C9=y%C3~*~bIeTN#SB69QeqKz zybHHlnP@CcO3q9@?v;PQrNAy$K4jbC1RLKRE?4h)X&K7glNUI=%i>+$^p5v&&Y_i2 zg`(?bMe=8__t}+~Zle+OY?7+RK0blQ9GOXR>q`w^b_h>BepzGf>DrC2q=dCQyOLf= zhz3jE>UhzE?s=N)?u2%F7N!Bf?Z$JJFhRC&BetYWA*R-=~cncGZ(zO z<|e;9W@8-F+L_st`KHP%s>Mcgq`xWtBKN92ZTV_p2G%$A-*y$PeO{!hd5bw@R_`CD?M~jm)awK9JBN2wTD2@9xeBW`TnG#JYiLn0sa&kY>2=MVT{rS{|38|4 zSX(&Y=sNxj6<40m3JH2Mb?Ixzm+hxp#FF^r zO3GpJMZ2oC*YJd%bZoru;G(swO-!M$eV2LA#8btSs;AgS{ASta6ui(?vVOsZspckH zMte0Qwls4YJ}u#VyZSWu>~gVOWzI8xBHd3L_Y@vv6gio=c9W4Pi&${Q%yyaMK8IDF zY(LiSW6_%(`qXrreCpo^TydX23twr`wWwGitT6lcO-sJxMbov?I#||D7LM6DUuz!& z)6Bgk&72wDpWnGN%Nf4Qb7U>O`|fysclYw;%Og{`SY&yOx;S`u{U{67iw~cwl^Aib zq$c=;leKBW%reEhCAYl}x_mWRcA;nSl*WvNdm49-$hPFMFO1(6>o%oRbb7mc@x{VK zPR6u%OC1g~zhFA$t8+|B^5Cwsr>nRWIDSnyquy!#N$tiiF^NW#o@u=8&GyxI-R4Ue z)hqw_EBX2DQ`O4C(%&EV%NWQz&-GvME?UM$RQQ~9NZ|&Va;tk8tefwgQ7MUTU!GIN zv&nV(g%LxU(K0NecRH{9iER)to>c@-u^>j!yWf?IidgF>b5?;zSN4- z>Wr*v+yBRhqH1=0Jk430{Q1H3@B?P%N1w}WS^h0e=8;7Q|82EvbJx$(4Qu~a=T;$R zs1QEa(&A0;rNUa*|Sz%JtLONsN0?Az@PiAU;Koq`0w_qw?5l_ z*swMH^y=Abc(2sU%1ATaQaCBH@ubEH?~HA}O9eS|CeC&1+!r`|cKESZKk5x8&o>fI zUwHSzubJm=OHFrTYP)alxBpYUw7Q>UyX^5J?Q?wZu(!I_U3cmXx16^`*5kKr!mr6* zM?2K=9vsh@GQ;p&JJTx%-bD);#hdssJnLiht(KWrhMZ(S zbltq=K&+sBp{vD{8aAh<)P<)j1D4L1dZYNK`UT7A;1irLtWR%y%dKpAXVLoaW$vr@ z-L*aST5$F*x6P5e1fPFmpM2xnt3&q|vb^0LEMI-_<@Y7$R?q))R&`pr`+Z(e z@7uGhrrtX9`d*{In<@;%lRC?J#iP59SANc zOY7U3q%;<;W3cI4Irj?7e7CJWHS4D>Ot4**s;!N>!Ov|O71is%|6_{&ebumQ zSvUJHE@tm1;>s36>b?h!iYGG3d0u*G*Uwq&nwD4pL@lq)g(o)p%^e=s*}i{eDmPDh zpsxS3#XZa7P^H%Gq%9pje+19|eChwbDRuhvck|rjgAz1PDw*3gPP!o0x_3vALdYvS z=B^FGTs9l`x#?|N@^*pvrMqfdq8~a4#XGXz&Q8_UH+~=W^A zM9jEYSwb@HOsAHKCq~^*R9ke^{&uwDL54NW0#k#cTTeZb$ychMyMV)3TjO8Mwb#e) z*fMwSn)YR-?L_UifcW@W$rlSBn|yJ|ZZgdeN%pOqt=h&by+5!l>e)`WoA*u}oagYo zIADibf{m*Fo#%g*1$|E3j4}A(xVT~Uc|Gy;{fFk)Gi%;mVU(JeQe0A$nwZO#nwOHF zl*MJHV4wh^jm^vqxF(D7yVmaj^+6w;O_|!N$`H3%f8JNC&hm8G^fkUqjm|NTa#6+j08E!Dof3;@s0bryVuCEfc0BW|KVoveu95Z*R}HV|$f+B5!rO-kqBIs7|G4 zs}8iC&D%Q7=G@s`o08K%n>}@n@>#F^`PKR4&9bYuy}X&9>YROvWw%n|^)v3hsb~Kb zZpoAV*m5TSVK!rY<-`fQvu7@~>AxAZG(};@&$(jmTl`dFmT5)L+xPSJ{daa7W|!M< zzP)|@{XM@wq;0afSt@a&BV8*rM|X+gFMiv4X;GW7b9WcK7UU9+k+gnySE}&&v%jyu zWfYvKT+(&tFw5m9XLlxF{g=5w)adc4#R;{4CHAmgSfnv&YtNFT{Vz5}UVmGWQm?ss zm)+(~HyK?fvz;^+ZaPskPi1oP{QR`_$#T1o?~a;no4v9~?)1&u9C{Z{en0qZ<*Ug1 zc6`eP6x@{RH75j}{qW(&)_)g^w_djXw&>0E(EpEAtwRq7Tk{oY|M~uG`qW1e$>;P~ z&a3mWJZGKMb-cp7^-O5kj1B*b-;~_nEOtYtue4RzZ;PtG;EgG#t1B+IE^rVLtqd?b zd~?o>4^A_MMelLA?{3(?^zUYCkD!Uq&jnp>;bIgGl-qJ^2BU0!ij#I~pZ?7)Mip@t zeEF^_%f-(&TzEZ;*MHX3$G03-8!^^ZF}aF`J-Gb!jpJtZ*!K~!Q~4M6G(~MbeqjfX zkKnhK`Tm+RZ1HM8%DjI}c`hPgIi>op@rA_R6!A(S_Rx6K>Tfr;vOm6kBm0`&qt{B? zr-c1_pjRYpv8Syw=iuY-X7xWfB`T)qW$vxu#F4S?>Z)&Ko`LSd>^IT7!IT>=x9iy-3zNn~L^dj)f z;YquOgfdKmEpd7@r2BGlF$cx$iR#F5{thijv3&jWQ@2z{e7EG%DaAEQC1G$HGUyeV<)iU=9*U$Nyit9Bd zE(v~Pexyv|&Fzi1v%bkp+VM0}F5~jv>L*vX3Z2rvW1+N`w_fTEW7aFHrnf1Q;-@$- zr$@huxj5xZ?}s<10yJm!PFnE(`JV;np9kutt6ya~{q5yaO?PjjFTdYko;3Auh}e;N z9&w6)7Ob4d7SA!wZ(1QY;}WgiA^%n9d~ba8(8@R1n)^UM*A3ZI+=3^%mL8is`~Usf zOw!KF`PT*)Ty}lbv;3rMasAgvo8GK%*u<-P>FQK&31Nrl{_})#tmftlp9}JO^g`BB zzoaW{htc(_4_gw=mvHIn!0lt|=s`_)IK0tup(hJP)pDJp4qasH#`y)ic>#@jrnP03Hrv`>!vWFGsXCgo&-yu&5`b-jzyRwZ8GH7E$pPG8Q{ zT>fTf{l2B29w~`4*4GCn1&Ud_nE3M8zb<@naP`YuVwyA0^Ko2nIQ^_Re>sn}uzYFt zk)GWT!qTNA?rr&qI@B49O^M;)}PZjk@o)_=--+X!A(WzF3!f&^{JAV0l z2nR=?zuc{9ru)nnC6+z061W@2d{i@laYah7fnm{STu0Z)h z&lxWqoNH9xEa0g9(0uf#o`}-nc}*`AM6U3aEB~_+G1?UWK5f#2uw|PpN}cxKUc7vk z*_&Qx{YOV-Z0?_18ZjmGfPGA!_Kx+*|MGUKf3DUDNvzLXaLTddojd25Wjp5Ad=KX| zurA;HI)`QQqkM_h?V*c3o@>Xv>3%Qw{o^^dAFEdK?^!wTN8PN%WI>yHo?IuFu4NGm zCLi<2+m~^ALbJ5-|5;1kN#1?weCN%_gOeR*oy|8}z5nt1`oNxw_Q{;$GE5dGo7KgY znAqIH1N*C3mOaxh|DcezeRXHIUIUIYnKNCzN#*2AyG1)fCi=)o?o&`u@|!b7seaS>bE!5SY0HE^r~8R%OV%6fJvZ7M z!&&gOVRiAo=O-_2t3lIi&YAMZDpznNv6f3N0!i_6Xs8Chjvz1Te| zI}M!l{%laXqv9pz?%fjq&~cT9o}yu#%EX`DkClTawOSumJ?Ru5Suw}r6Tk8NpuhDe zIh$rEdVZ+)o1%95&}F40~{k zmL$J%<_E=^PTdyyhyFgQ%LG+EN-7?R5j=Oq@sXvZ=e`0VE8E9w%Ku%e?EkE-*S`AM zyruh=#O+v9aPz&=V#_bjzc^KK?qxUKWjOudp*J!;8-3C*x!0$Eh?=M$d^X)u`0AbX z5c#afpWZ2|-#&0RT+Vi_;qR-rczky~XZseu=f{jf(=iV`|=XcbfF-&gP0)PkGimpR>2O zGOx+KcJ%!$0Z#h^hn@fat1snz*0LyLf${ZE)eoJ5Dq9TCPGCEEAV^VXXWW!IQ`by8 z5N8pxI^*=#j8zNScKPfLjlH&dd9?MKEoXCdS25qpwekAa^7AQYr~iYV*%A-3Z-363 z%Dd9M{OgZ!HM!{`M-DpuaKAI{z*On&|5ZCn&vstwP>{ND()`&!iQ6;oF0y0)QlJ0f z*PXe)pWpJ2&#iMhzi^4Q$j740iU+$^Toqtw^!2>^DeWoi3zjEerPjJluJW5|CO)^Z z{KDq%7Ty=+H8)(I-TrcKddks1=~sNOuaob7#E7=7d|z9=f!pX!3O#L(ow-$^~&BUttS;4H@vaU{Jr#cvgT$6CH=eZd$U+mx$*W>w=lFiUClTuE9vbg3EojxLAeqi^ zm*;6u(q9-Elp2Pf3R@eP&Y~>xviqy*mmn?wWv7`~SzW_l=!K>9Z)&@=I^(ybMQM8_(d&)f1 zH-L9J&r?=WewK}vQ72kVP8el*m9kxEX5{(hRC|%*u;890Z;r~QOyikc?soBnHs9sD zr^7Q%7c_>PFnKonBO9|w{f+v)56yNd9hk(T(fF=oTZ2*L!Yc}_VH|OdnL6!tZlc$v zPoFxKwI(<9ZG=yHf0ze%asSf?yE965?wV7xQ{j7nSKIbq`KvbEdC{YL>BEM_w?7+i zm6W*K_pABt%V{yIk8!OnxOXG!R>mrgofn**@5+dA2-4g9bcV^&TR{fND%+Im*=uai z3S}7EU(Sy_VbsyMn(Ftue;p5I-ljY;x4zsxX@nD4NQyH|1rDNcHcoU zY{K4ywzB01f6Px};MQPgNz-rrde$#MUe(V|%Juq2AH9X;HMN%id=d)UU$f`2g)Wtt z%q^72S-(c4HHYu3_+}NIrchbwJkPbOe(hna;QH@7xGsvw7gn#VnVGC=go+vJFTWR-*-&ArEoIlpwQeI zp0Zz`Ez-+6RD8&HU*qXDi%+rdeDhtzc=FFT-`l!s*e*Uwtp9ZLz3o@EQ%|P%O5_yG zs@t8^p*n4S$A_D?+9lBd)2eUxlne3b`P(q5>s-|JsF|5%wJwH-#wrG zvFwVrBd1nuUs&Sv{;51l{}LwbowuW(_hHs9BU6c- zU$ds@t<>FfX72Vq0Tc7;J-$b9XS-DYZK_=q!I!rt``nN3o*DP%=G^uyoqN2zVDY-| zo78+264TpQxEuear^GH#pLn`ZUwm%N@|GG7JNYW-#M5g}uWvtYknlR^{mzi<;q4Xq zGuAT239SC~c>BS~%*ri>YY*hH)_v;btWNsN?8@lyyQSRzo#xAR`<`U(zE*$XPTpGG zts>X{$5rp%nJ7A`=Z`A;(wZv^4&Tl>k@?_V|ATwCb?(h&UEufS&WV42*wc-7JIB8{ z8oQLMee>G(+Lh7F>y=j@;PsUCe{|hYXlkO|o)!GLqPmBE?p-nEX2ly0ssC)R-z`i2 zba-RlV`urlWqU3>+#YSW^(o^Qk>76@ckQm<{>%2(LeH>@i2Qu@tP|JLvW%~9de7Q7 zqibTdIs3uAucxHk4`i5naLr@M zF`4{-1J{G>&9#XbJ&DhvhSy$VC(P=?WwgsCPe`=qc(RIK#Ep^rDi+rCS8ofIC zWO}e0&$@LiAMJZ2Ht*B;!Uk*R?9g91IoZICH8nFmqh#_5gWvULrsj5b&{2?zIdj7~ zLqx)_t=sl;l~81hUuQ>|vWC(oP7MWbmYXT@p#mW(p_vXY0!p4SlQj5ClU#ZYn|3TX z#@gw&c)<>qNgPUo6OX2;XHM;OJA3EVo@etbS^d(U**~{WKUe?Y!0J`u+u!|uxA*?v zbsd+a+&f*A-Zo6B@7Xiuj;Uwop{b(zN{^QJJzm~r{^*Q-(-l^sx>3m-Qd4K_d>F6)@4ru=i0G54JI~ZxX9t$eIbU^O zWoPEPo(o99al z=A^%R^Jv$B+-XmD-sGM>JtBCDq^R4@pl2Z#rp;Xo?yQ&@qLS+98n}5y#;HkN3)6zV zHMFxdP1~c~Dub_u=xpuSwD6IJeEq3uQGP#z%BILa^*_6mNrOGh@TmuDkY9*^X+PJp zXTge7j77b62F#qIzSR9?F!##NDU7Keo-4~&cuwh<eJ+!8OXiD>D8o+bsGL(Qs%tgA^MoF|F>_BPM^^8?%!LRwrtCud;QmH7oCmu z6I49EU7l9L^jGq4&&8ys8O%P)pQWV_=&5|G(ki+|D@R)oNybGKL1G z5m_6KEx1##_o3WjyOkX0UaWi@AgS~I!Q0a=HEJpKg}D~qpJpBVeT9qj+QN?q1zVql z?~>i5@*$GF-Td+b=Dk9;`}n4QoVfO7YMbucdA1vN-}b25)~f&9 z7d{xW?TKHk%ebk&uYLChnfp^2oVoM068nYBw0W&VFRbJWmGrz{;>V==m*K8OQ0>n{ zM>oxWp(o|BYV+O$UO#`QpS!x%*Kzx&{l1pdYwX@}#~*nl71jE_c!MO%d5A}zpJ zB#U$L4>l}aEcxx=KIUfz(mL$-4>)nm`OX!6+S_L5@^YJxDmI3PE}t{oB)ddm@9lMy zUat%;p897)P)V$6SoFt^(=6({`QEgoDSz*ovEgXNA*v9tP>Ok4*hCm-2Cfy>&)d()rAT<=d#84N zeeg=olphTH9G%WtZp#cf>L1$4u71!`s>zYb=tR5C8df72rQ^>tu6A%9|IffJIpgCE zuJ%V0%GZA2`MLjR{UZ6iNq>qSZWsK1wKZ;E&z8SsML#m_g>`0ktKN{V{x+*|&(?28 z?q*rq9ZulhDs5hIUDkV}U(4*pu`h%#Fzuqm*In^x zSGpIs@}}vc2dAe<4xJZ{JxvN0agJ?DB@22frBw{f>3L z?X_*jkp)*@PpjT==|g%?gO8-izvJQ$mJ01xi8lz%>T(m&it4{_IL-C?uf**AGx(o; z-SH^=-~Gf`q544E?+M!1PoFdhRD6HqOKhO4oR?`|Z}jWEN>3kLw7L1a-OlPuq3COm z_Xl^K6*TBQQc&do_;laY`!nRH@0R`eU+J^PDx-BjpOt+6%RTer?v$!m$~(PoENq$V zby0Lu-bS0_4|lJdFxmgHXK~Jkjo}AQX0J{;ouBq?v7*?Ydgj~>to4QAOMGX(k=!e% zvoTD+%$YAEFfZj#&HV};#~U3-cN*~Cc7C&7Hgqn3s%Y4xs-_z=?}Xi36?x^hZrfg# zHI)X3Sv+tG9GhQH*X<8E6*YsutR^C+ zgHy|}er`frb!b+rZr(MYhP3E!Xp*5+ zreMq*7S5WTN7{}}lj6@gRXstKCHs`B(+;aEX{n12pHHym%$z^r(^8(U9~rrce)W#m zW*rJS@=GoL_0;&yd`TP1jyoAJWTvZ2ocf`id|dd=XLGg2w<~Ikd%yDBi!z!#Z|O!e zRc>pkH7C>OUDB`Iec!Zf(#7IW-`*}d{kLF4^qKn5!?|~Va{iLoIP<-%m16sQ$*J|a z&upB{)s~+$OUVy>6Lad@h3faQHdh;O9G|`^ss5?-%tu?AzW?2x^!6<4{593~CADr$ zpVHUPK2(>#YW0p#{of|fT;Az^QN6W)b&-Cz?t%Hvk+->ui>{}vsnh4%*r=KQDldM8 zjFpDGO+khKQ^#-q+uo@hkLQ?QXwdj)3fB{xzGJ0(_^&v<&Dj29x0}*KRi^_p>J_U+ z`wAa0&*!>PFZIYHhhw5pwv^bzAepAqD(5o{+E@$@aZXCC+VW=c=^qpLKB%0z%4^P< zfAqf6gno@%?~E_ay0HGWQM9jvnM=nJX`AQ!4}Nkzz3K4erv+V%+%e}?9^=q{QZE=L z8?(0;N9!W{#EG>XWVn zE?#8Hw#O?;vBJvX^R8KpCud(&*zW9LY_YZbM^MFl=UDmJ`!Rc$oqzi*=TjxOw9c`( z8`&p#bR3uOmV8mf6t*tDCW;}dDNN?{u1WP(zh6F@{bpTS-ur^T{k9!%*T&~4%dah% zH^VejlvhCNmVZM*(52`7HIaME&9&^5st?rX-1?lznJ9n0Wh(bmzJ336XZ^^t+gIkFT*ue)IW|*v!x6oMde$ndo)#u}X{yJe=GQTyG`_@Mu$$hFDEbmT0J#<){Pvt*=qWx-#ypn+)$hCU!QhWj>{y={d?d1-G55YE_7r0 zrDG_5!o&DOn?T-zYuwVwFOBqonlrJIta3KV{P^I0#t)3MOV;_tL?>p8vrmIQr_V)+=LFe}IUZtPT(@Hm-{u$pb3 z795gL5iR+(@vV9ppLlcqxnIk&|weroa)>*HNdsVJD2l`G^ zFAO-FaykD4GTL+wMH?^WlWQPUe;bj3I4RfQDSuaI2IVW;EgBA2es`>tyb6GH$y5NqJJFiHy?ZV;W!o-j125`$x+2{Qu%D0Y;a8 z_vhE&|8w}~6b4B-!90%X_v1a{bYebTp0V7}JpH%Yv)1D$jozuqeRf}S<(~M__3@Ht z?2^9x`yg5Du(wjEMS%TGrj4s{hxmu)BaAllb(T+DYFW>lcx3whjDlzLn|D9knZk28 zFzuwS@tgN-@sqp`2mFc`?)hSH@c9vqcTFLOUh-cRm+v~TAv&hqWZqt3Go6mYwUv^P`+kz|)o~f@)@(j6xmmE`Nd3w&Vf~&i{ zB$02;K`+ma6zv&#HB$Fgyw~#Di#9~?uT8(c=7Z55tHg6Tw||IlkeL=QU1#RTpk!g7 z(8jzZ&V-%qN~WL>o7nUGW5L`v6dc!0{qnJ#h8a#`tN-H zef`$!o*`hGvtx3^+={}N(-|}LxD*z<`<-gnE}O(S@m}obmn)f%YptuP-o&>tmRC?t zFgv;V@{=;d8%6)L{^#B}IODv8F!vva-HQ71pQMc@*)@EFpKImg$X)t*8A6U9w&6 z#FF)5Yy7y%XE&+y-#%Dk@b|U8!A|X!_r6Z@vFeGezr=ED-TH_p^4kw(Km4>>SNHn* zZ6}wm{}8*jv5g~r`3H~Rm5E<%YrmGWA8#}1c;B$B?BY?y9Y11X*w@`jT=VyaxW<*v zD80D6J)eSaGB7E#RI$G8{66Wm^Er;@)tysW&5j;(Hv4ey@2%wR>rZtTI!sy0%H_Cv zpI%ntL)kjz<$n&=pTDN4b0qWMq_*ew*UdHErT=7Ce28Ls?4i0wb~VesnCvYI|7z6K z&R?5&O61+FhwO7Iof(_|+&kZY|Ku_QU+dND7srW}u=E9a$8}4EK5`4ve|CN5q>e>z zzVx4**Jhi(excqs)ti^pMM7Q+8`gMyJ9EhGpoPH0ogCJGI+)`pc)qANd&}{x@Il`J z&c-WIaY?BE!Cw_d^D^%}TDR)=vyA$;+lw;KZ>kM_{eI?_g>Av+QhE2SFSlAnMzkg$ zkQIN(dBfn`*+8?~iah?3vM-AgSid#<%a_Vo-PAh0>-{9@y{26=d=H;9;9jH?aTlKFe{_pKlxDL2LQYod9l-WBlk_{RC? z>3+3Hj=Z|tH$6{FzV6A-{QUn+;~lPje*|3QBEDPxb%{1zn7qBuuY6^np6g%c=<5es zCQtMb-n`9u8zZx!p3!7Rca6!@UCjiHbqy?Z4J|?p46RHIt&B}4-*wf-6qInYWHB<* zGnpLf)}dl)mXu^*l47B2Zkm*)YiO8escT?hV4$01WN2xUXkcbxmS(w`(ft&ovZ0=l zCYQc*QEFmIW`3SaVo9ooi#i+`!zx)y~F*kcwC?J3Fr8lEk8tilWpsE<+0oOG7SIRabvE FE&wd34n_a~ delta 13319 zcmdlugK^n(#tEP5-Gpkdho6aV3w@NKw?j?;qwC3AOK)@?J#}r})LTrR9!I2DGMKjb z)E|Dg{EdCy_d5m+8ljt_{idce&UpFKuJ%`nzn$g?&;L++ld@A#j&?T32J z+{4#(`U@GSPB?m1viAF<>8Ed&A3XHo_s$6^8`+Et*5;RPRr#;Dx@`CD>9OHk&mP^y z^Uw9cPq}b$&vTPRdYb&7Pja34Z_ka%j~DNKKI!<6cQGnDhrho(d;i|v{rf75ljCZ0 zxc}amy0lWGrB;je^duW|>$)p#=al?z)~9{@{pjt@ImWJHs}oFT8ccmUvvU5utvlwV zWVYp}_B8)j`khnXett*ggw%hH-%hw!t;pV_xBF_HnYiI&o6s${zCP%_|MlGC#awzb zPJDW>X1#uXTx~`1-ipuv?oK`)n^_-0yl!==TM8mxJmtHljikjr4YG zaZk1}s$ag^Drmy*O`6}0Em*|^ow{ee;VXzb`f}Y{uT6Ttnrsd+%!^Ht^nSd&tYyJs z|ATslEKRz5HoLOK?_fWtv`aH_eW~Yx4RxFKyG>tm$trMc?D)7lW|PVfznSk(6$kNn ztLuDASQuM=Bkb(nIG3k_-ogA;)6{qV+jC#UHYZ}zI{jJor5od`mptc+^LlDrcQ#aS zj%nWB-OihxCX_t6Ff}{q&FSTR%2QG{Zn`MqbBpzXO>D)y;Mp=^(m^FD(RtCis}5xx zc~d!J9|D(VV3Yhz#+cI?+2$0>Whu1@s++qHEbTSH67 zL_^=o@BLw7k%xqy@)gIiR`Ta_Ob3=6zOm#%IiuxI!HyWllLzhPM9cM=r7sJw*Hzcf3(ek zMQWG3b(dMIJPmV~deu-QvO_C<)|<~gM#AQT?mjBa8@a{2C)=%O5?|BRrqgJ2(NvUS za!JEtsqLEOON<^~4ABccvg0U^?VU_72BvdO3CE2LeKx!|slRgc-#(Sp%X06`S(rrL z)o(TVIK`)6`Xu++lOE`NXjb175%KK)^xZ--o7zfW-AbG?$4kj|-vciJHhB~WC$`}orTOI}Wak8%5u$JNQG&aWR zPEUiAGCK8+FdSPKAO7}?<)I&QH@BoO|0A1vey8E)eB3j_F*@~^xYWqqC{o^*W+&?!=YM7MKerQ1_+p7ncyVM*T zA39}w9a?64CHvBpu$>;Uyvj!_9$jJi8`LHweW@Zqs$_rBBzJq}UKty0rb!;`KY3?Q z`dHWaqBd=F|CW^tR2p(k0LGB@sp~2|A}fYZO+vMlikWu?yA-T6x)SnPTIUQ#;mMu=_rYt-eve z-sgdcOXKRsrIE{8lC!QvOlV&EEb@v$eD_=$W3=$=?B`^49PO^FI(6P3B!QBo% zxz}oX-9;~$r-ucqR{@C7)SS{&s%TonExXYKy|uw4|pk zM^EJ(P_>=Ej^D~^(!tCnxc@`7Mf26S{IN=4_A`C5JMwkXr7O#RO=J<>~Kc%rmxa;#fcz5B`-t#PRL;eMYC zrk=+0wWiCCTk%MSue2AO^DAJ1eW33aYmLyIYzr2(P7}T>*mY*x=AzqrdJTVF9z|Hb zn5FR4W!CRw$G7{sT`!hgxbC=8wDZ&BFB+ca%f4DN@zaenRu1*GoM-v8SVT6wR^B3Z zc4y*Lp52Krcl&&MS0ot5{NQKBf%iX4Z*1Zd7Wy^)bs(qY*3A#yo0dL|Pz?;5GWpk? zu+xrPF7vl9ZQQ&z{Ltf=bOYOYlV@*OE&t}BpZ(ph&#i3iw;QLvJh4?lCS;4uR7Gw3 zc#~xzP1eEsdhE&jotAjEYSss3WH6lDIs10Nggs&XS#^w~Z4u8vX`_=5lkaS^ChZ{{ZXC{M9e=>vK6~ zWJq1zr6-kRzv|c*QICYT{rmxf+aBC&^l8Y-OMh?Y0v71SxJnm+Tt=YY5+WOZ~;s$Ht)pkif zS@1ffGS4b>+so}+**f2)<;;{kuEBoxfv#NrB0jF|?FaP#>M0*;shU0S#mZx;s*`Tq z*(GB3fMHWZlCflwa?p0yt3DT*73Gb7nq;dtulH5l@GC=tSNi{AYyM^Bc7`f$PtqUS z{P{F#&yHP{|JB)#^cU)>S@7#F#{p>PU)@l3&MXQ*7FI{mqFz$-?(>5uBGow34GqjdQ!si=(Y|1?dWJiK0C!ZANn({5WN|HH%5Y!}+D2FV{j6ZXbZ z=!d6^Uea;?MA^orHOZeZYbVU&fBKwxgFZoa!E zIsGN~&h%d6^?&XkI~iPmEHT^gVYX$dvZ41!*@y&|A zLrYBk-RCxu^NvOzY`CKSZEu^m@VS;0TO`A$t*>@5f16#F!YBD=>&4f9GwS6-F8|Yd z^0mY8uZ--jbxY-vlBD$aZ`OPxcH)jN$J=}J{@Hb$N%Wt!=wD(=QVGR7e|PS#qZ=(;dv?x9Dm6B&T@xa-@O{AlmJmi=5ie2JRX;?Sau?+Y zcJ#7ITbGDS9OTyfV9#=XPtLp5%eKVUXGW9+|6H;2PeJA1f6XsLlXg{newSYK_W#d+ zPp>}JH=n%CX2l8p)7I5nr?QD>btad{NWDLuIBoTXM2n+GXKvg3-Q(k(+r><|Cg&D@ zxpRJjs!@ynB$lshN}nzdd^+iTsNSAObHdgMzf#~2H++?FoTdMnqT5vs`j&SG z7Y8?{e&`Mr(fl4;w9`C1Wa0tO0K1qIh1H95)?ZOO*UA!NGxy$^KTD6uuMJksN<@?^p6!prLw3huTRtXtcBzD@e!YXi1BSH-godVLp9eJFTg)qMYp z$7>m%rG4_K-Cg&Z)7M(uFY)h}rax9D`9^>Ct51k5`N_Js-TIH<%&z@E*{?-J)m)1` zn|#-6`ZOjH@3x8)^@{(y-w7|fG^Hx;hi9aP|Rs-3%O_D1WwJQJn~ z*sXo>Wx>t(LP^_p%MP*sFY>BX+O6i?v!h*qcyHF< zyUgGiv?=zp!Ymf4yUYFO=lu}o-jTrgw|D>1M9~d*UtRW^u|4OHCf}RoXJ57dZi&m0 z3oqN4(3#>XvFU8$(oIv`E3DS;`G05cub0is?SAA`eKMC1e_hYO9kfj|LA_aao@9cI#bz+%`UOEncFp^pw$Q^Y3eu z4qI844jD1_9z`f^1tGB<2ytnrByPLe$Q~&OhtlIJPfBEOzT2H(*i_MB=t*kGw z`MYMipX}aQ0!uREvi$)|(pGJ!jp#`u?HsYvrGg6PCuseNQh= zIn-+4u2sWW@Oa`MQOOy98UJ+_wY|EP0ACqv1tKHH3K_1CXX3r+p^z`IK!FmCD1#rbpi9=g3& zn6pXi-kB~{;oajQ|@khBYG;`@0jmCpSBq`5;G&BHCEThEk07USZVFOX|eX7 z+6pw}YYd%?zRa3tyDcjGxp$NsXV6=|x6?kjbN^^>@89*}rO%=VP0vHG{^(nw-X+(1 zU;kwE42S=Totm0r3lv!UPi}a$(lxeV+s38Km999etWTY`BqjXX;xlTFPg167KQc=E zw02PfyS=h|$P?b!^RJdIe^hTfC3dyvB9n=q+{@;5?T~!a=X31kmc=VRP0G@Lf7gpc zENtGbW!K$|dG!5NmF&unkW z+;VZ8@qF3gqZoew?P9`~L)&~4E%kz@1eU4JV$L-zaTgX4J~zQXg^Bf2))cPH!#Ybd913PH$p5;0 zAMB^@-teZzId&@Ismm6P&noD{V4^BNbSyemSyO{OaGDofS`&T#u zH|{qy&DqKRfB*TgY30eff|JvB^=8;-XgQtoa}Ko#I(;dB;jEBZ(`_HmzM!Rb`qB!f zC{LOA6%*M1dpT5{m~JGdCFhg7?qAvL&p8Qe?M&8*&!`hov+2`|`l=FqI*+$TI$lll z>nzFJ92NC`FwfID;dvf=F5xMg?Yo)V?7yYR^z0}&c;D}{>=b$3npe{DCtrNNJN?p^jRuEn-UKMd z-S#^&yR3c9gx=?srZTT4iC@v`vb}!$;EYo1>BY%Xw>hQn)Zcvdf1%34&mjR42FaGc zWqlWwoj7}=J5E8!Jn3wif_=#4Eey(~0=~BM;{F!&du>`=)wXitw;Su@SA9CjD}FKD z*f#3i61Sfg0>?U~IiA0}sryWOL#*27;?6?9|FPEZ)r1o&#MCb@`H*JTsOhCDZ2T?t zXx;hW`gh{hH^`-Xp9rWw+9ur1z`83|W$|i;{o>)}Epq?%&fvc@V{03?#+^J#v#oepJhYE#8-a!F}wQ}*Q5)Hi!&e&4&-H0deJi=kGAYRJt@M=t6HT;uY$lnS2-jyZNG#@` zd+|`-jYOei%TG7TZPnOmB5u-sINe&aw`8Zx>)Vwv-9L`nZj!XxHG4}q(~@U$Kkn{k z`f8lBZheIen>S-oX4$6AI}F^p=YFiSsr7GY5cv9fUuJ~uS6`FM(_+{cx!$~N`XuN` z=rM8ExwAZ*gg(Cey1IUG+*-v~9L%>4)(eLBPUI^Q=4hE~mY5`Eb?*B<0nTqJF6;|e z>|Q2U|Bzeq#_``XRWi?n3hnaB+h)Bb!r0B{n4;*zq#1SQNBe{vzgo5YynQ-Xa{j6I z{c-O+m)VM}Qk4}iQ2l?vCU(l#3i&0s zxR*bQuI}%y&1SBN3ulj;UcFD6{h`40SNwMJ?OJ!_lGyr|cgywuemh@c_6vKKKc*{q zu6b|%^EBPo^P+W}5u%%FXif&W!b8*#W|lV(-+JWKMOwo^#4z$D~`O zY1hAR7CXNE(XIubf)0pxH83^_D6puw$a!)oS{gdEw3I723a}hxU&OKIyr4U`t4rdQ zAa>cgQst)-%U_vYjo3PU#nV6cUcFki?zhEv>-#_7{hXyTXD-JimF2%X9$j`ZDhxT& z)NrDruxM3AQhkZuV@D(7xijnwH$|SjG275``pldvz*{13fz6#sD4H>vDXSSECt zgYj8cff}E{`I8!-S|?w4DVe_abNIR4bK?swV|c%td=>qAD7E#pow(%Lg_>20d;9M7 z&bl+>bV6zw&ylF*#*)g$74^9%rmuXsdCo_vcgCy4w-#4^pD=mv|99H`@3!5jm5N7}s~y*fh!Y z6wI(UT3b^lS7U2F>FzY?<-P4Jv!3#-bv|crZ)IGPd+q4^S%RGQ2M#ya{`=ZlKkdjO zi3OXleX4#CQ&hP`^X?2j%>zLTb#}&0nKXCN!~=2`5z8~qZ_UbHAZB&e_UhbitJQB? zAt7*mhenItl!)Xib0}UMW<(7S)*D3mWexP|^ zcdmb|S9M=?YTVLwQf&_tv(K;9uGL-qfx9=RR*viX8mkS;nPT~cSB>9!ab15fL4H5? zt)SJ5yy{b0H5D2^%(?sW_Y%j#MIDDTPnqO$U6B4(Ztr%b)WtUE>y~K|+;3(ud|?td zzdI{^?z!DPHFo0P*jBA}p8UJ&KleM;kgLVLji-gBLb94qDRUf}ygheOD^Fv*$?Rvfc78f$k-BvVNYX0uYrl|9!R}-fl;o5q2?std$E8-$`oMGOv zp-b;xi@3x%w?OIgq?{}D5=D-zQUR~8TKrbK$zZ&{zvg$-VT*@PrU&_Em|gGgN>48~ z51eUt=l7LYgYJ51%PzZXEot59e$_&JtzG!~ zbJMwt_?M+sW&c~nb-wrH9i?6ld!Z@wm!3ZIVw<_li&Gn(-P&T7(Y$%two7Wot|xbf zSzUL1%`~ZKW^C@YX|KEvHch7#7N0ofK66Ej_4K6hjR#K$7?dlvs%=(XGiz(nf8T|@ z8gE3UkNrLAcqX7@>PLB}?2R8jZ~RcMcrk)$e(V>!#@`cG$vpd{S1~_lI#1P?gMW{4 zPyh9Iko8}o&Mv3JY)Y1)kMKHuWl50X9b%+ zF+CK#qx{jMsgHX_bw#gd=xaTk{h%PfqhZFYp2;`2&U$=-VSBcm>HpVXw#WAFy}+!S zIj#BFoW))z4r-mfx?1KBpTT7|k7r!dUi|QR)nP7P8uWPHTV(e5V}Mmo~fgP~~sgQ3Y?Ec)^#Ov%_v|%b3P}-=V|yN68n> z!uCg23gHs6IZiCcBsN=`9AkfR_4n?1*QL6+PuZ?!`*A#;|6U!_-U738LIok20Zl?7 zRa^ZG56WvxI{ayT&{_4!&a7kg%Trg9Hb`a%Sug$8VN`zalap(k;o)T6`Za=YKXQNU zOtajvah>JU``QaD%ZuI|H~lJi|6uR0d8cocG`7r@lu}~(H9zpHxJ`FVU**mhPped) zIG?z=L7J;NueOfarmgOG>*u@EUsb;re9yZ%^Z<8SXx*PO3tioQ!=>Ur5smX}k{`XZ z`0o(NaKTP6wtu(xt}MOETkB1?&Dmamb!rs1wB41uLw7cCdAj|Z)Es1=dEsGh*^?{v z-`xw|X9~VQ#dblZGB2h6-`vfScNUtzdvq?S_3+JWhwp7!+jxDV?}N4_ecB&iYjmD6 z;E%gE%?uFI^^8eS+=NACU%-$w(jq^2NA)BHSeD>>?of%;f*cR0-@@v&GrxP-Z!4y zla_2ep2{m&2}{J`Zz zpxv>*x>JQ0ojrBxgwOeNlV4m_apzZ?9jH?=ggvx5$XRLq$h&KVMNeB0jZ&-ff!-kuW`e5mxYW?0;Nl}QNuza^L|}5y+a4))6)E1PM*_YgE=o!Zcu!2&;{0evdEW9_ z|LbBus8;5$-G42*{$NyX`>xRC-)?R_Z)cKf(y%D=mW6?;a=pH4d0^0@l63v3OOHAj zA936)n)B0r!@dSV_gMiaT-tnkzV!;cd9vuez>ixz&v=)mnAlz{?~V0&@@C`XW0pRr zPwAbAoHA`*_S08J_wHsTHeQ`=9#*G$T5M@*)XhoVd#3cP$tm?p%e$fU_0ZGPYZeI^ zPyhS%;s1QCu0>7D)6RW7TR&@>?DOqc?9+d3YPfUYsqv?#Pr}XNIy{;lT)IAd-kkn( zXNpaf+o_RN_+`?Jp2$}>^&ZFGy|;DN3&WemJ$FBD41PAvBFCqoWY&A1z-u8EPaSUt z7_STrVR`D=yG%(lTB}RS*)_N@l?1I8m2RU&YQe2nGOKLny4y=UFig1D z5X&5QLMJ6~Q%&UZzzr9z77M%WH!?alt==p z^Kb5-`sbQpvisxQW4_FL+4W?8+&FS8rOR{O$;`>pYWw-PBkVK#%(2-! zXX_fQHm^3SIP%~-+jHJH`yY=c__xoQ5L~3aGpg@N^;6MLt3R1pWUVT9lbUf`X;(&u zq41`bdbK%6_auD`+dJ!^n$Eq8tJCU|XDfC$o{whPGl^CBMS{;!sU?ES(w9v?wWZB3 zyKyCLoy9eUcY-|Cw;u8=U-9?&)VB80^hr)re$3BZBzj%4wX;_ z`rd!q7Li_74Yq_0Jx7fTS^3(z*o<{*dKmMKC5#=`J$_iPb>?Wef1(K0XmH zjQ^!97rxP|#=Bvvz=>Fw_Up0{g$Dn*O}(5vU0*HzX{l{={j6Fu(?@4UGiSTy6>Haa zegD+g{XJk}?sKzlzWTFYPWr8QIprYZ$0ZGK@2uG<|Ly&z#*GQr|4J=$xUgG)WAmyb z?iD3R+4+w)E7#1Kt2En@v1|2NtEnsPOvAP9u3maxYP5H6M~hEEdEUWy89JX%b#Tr% z)IH0VnB3xf%Khr^*xntJ|4JMz`SRvuT*t%X8?%$c^`mC4S~h+;Z6QTaM4wO;tw@cjzrR zDE#MMD`UjcpdCLJo=`oxuts}%!G}cAtpO5Be~N02`$O~w{F$egd49Ftv0qP9PaOFuL!Kq=6H0(;iHxFx107WqSgB@oZQuZs8GzQfl>8| zvz!@|DqrZs$7|MI4-%+v(Uj@gmEM22;6?SfiYc%1Kgz#p>28Uid}OOiP3^;wdcTV` zmX*&YzMK|eDQA2`{C7!2^Qw)%9$e)TwL6sJGnUj^R9^AIF$yd;g$jjG5S4-N;at&VcSc35Z*`9PrL!=4jRwb$RqRimY_51=;htk?`XS&c)6+ZMGv}^o zZ*LG!;PF$~E&sB9MW9{U^d?!eR|n>u5cNIX+cW=xe7|JN*~&TG${V?l{JR!(ugZPr z`FT6t1gvM>*0^>3vTUx=4W|QD;%>f&7XM+YGm6+~sBWD7y>9Er%SNfp-w*!c@8%Yq zziro+7}g((>Km8vZ}=>=%U7N6%E=?2S&Z*2yu5mD!QMoLE7pP+7BtsSmbfUPz0@`C zHrwpm%S>i!hjmmsAGMuaV7lBQUG(XDJLQkFrM)K3PTBDIPWIwB4bi%@D_#X$&Am5W zS@4_pxy|lIGh8!X-&kFz@^q2@Ws^BlT%3>Oj!isT#+IL>S~c05!|+Ywl9H`2)|!4< zcYMQ?C0`c0{0!oAt=Y1}V7WqeU}C-2qra22twW~r9h5Q4o5|$taPbyb(b9@-_0^aD zJZfF|;EMVF-h+u#UL5F2J1!x!=0vM8H($z3_cz5Cf0j2JU*7J2ap_FE%beD?QXX9o zJv57V{(^qN`9J@iYu5VFc$qaM`Jj4EWznpn$ZuI++iuoa?|%AhaajOC>oq8p>C2|KGbV?f%m2Q|FWTp2a!EFU*xbz3sydF(#HN zTelggmj@m@^!>4b{FI_C&pw^pG*5QbySKZ|roVmgKjd}TroWmWb}}%Zj9;m8jyWPm z`In<<$oJ6hdMOFFlqD^N^@`Pe-?$&J&-c7>s!(N`bG^#r1BXmvx|}z*Ri0^LRcWyF zOPIH*_PAY?a@)2B{=ju+J3LCX{|Pnj3BOy?9URhH8$9`D2Ina`C6#>-j31hY`Ocnf zYaGeiZn@!THB0RNgw}uU30D=?&bxf!`$@iKlWux+B&`vXR$+SJv-V%^q=kts+bXsk zWaL+mEKEIke?xx#$t8=fG%YGg32d>u5wT(B{6lY}Hou;{_l1Dfp3?Wz*~{PG`TbN< zm=Ng)g@|E#l~5-1VhCOQ*nM?{%K^ z7iT4W3|6hIydLqKDa!PB8raqF8`%<3! zH}dB363tiDv5Pi&FO&CED>Z%*QGZw<@c0d{iDerfDL9LN-lc!?tUv_+yR%y&xK^{2 z{9pW8TU*Tb%N~nqI{B|VQY*CP-Ad*yOSlxq|3;1}?A@0iTO3Td&)%M2YWDxcF6E=* zKYPC(nzsCU-WKJ3k8km~ht9v@+4^;g-yP4ABTn%O4@7c$=YHUdVR)b5?(sU$GNjhG z{%X}~Aqf`d${!4?4+!dqRY^3y=C+w2aOu3%>-z_%^Vy+ii(6G1b+}l+ah2Li1o%%wIUs=80{BfXHji;8tqNRd4t&uV1XJh=& zM;6Db{(5wVO+v}AN92g`+=4|nV+@_PC@1bYt~u|XhmXeW#7@z?8xqw!-*VcSdxuU8 zm|M(w*Wvl8bJsrJl-cGrFZc2EsIuC%MNGeU))q@_SRr}Wrr^&R^HA$-!5JS@b}9Hx zY@FW86?-*!V?ArwnVGNt<>d%-d?@?6xBY+Ty1LAb4{p@_zE>#AbdTxNM$?0aqRSJR zjP(v^bKLQpaINC)Y2oWr*58$!!?C-iWyS7=+@HkO&+gaR@cI6SQpV@uEMFMf=VTft zuBxx}b_(3Jus6ax()s?!eC1<7o2I6+Utf1cJ6qsmaGycQs$wbN>1JfM|xz{l542zkATO{Aj|aM@z03 zzI~Y-x?(Q-&hNRJqIYXoZZJ|(E3o|7>3;3qY5NJ=lMSN|>^|?mEqIob-~4^H)w=7m z=ewMn$oIz6N=@?HmW^G{tF~TrsefH|a;?yXdD}1WT1`}&a;5V&YslVz-QWAwxB6Rj zpXIoH_pQwbgX^bOs9S2yFbv=RrbMf2i^IuEPs!89pM}ECyUfeD_U?=E&G`C)MNec_ z{!wkTekSj?YTmthd`4F~>n?@NTeHd{$~)+;aA$k{Fty%Hqv6p#G)E?%K{i{yBU-6~c!oy@% z%H3n%Zc5rNU;2<+Y0m!((OetCvUj{?d|jnmS}*3$arMIe$-y7{mM8};65GK4uGwBM zJ#JHlp^YM6DO>W2B`f7uzoH^{mCg-ddi$JCH|-|a=oe-C|(HvC*J;}O1Ws_3-E zr}yl*+G%sVY`^v4kP3b_8>Z-`JEp#Fj-52~SDB>6gnspJt9}>MUH0#h;F>@2+R?tF zpLzCHY`k&0CoxeyGwD~z*L+>?ZC~=&S$tf-&h@lr-re1Qod5Q#2Qf|E5niQm_g{fg zWm}1M-xIl`F*5b9=g%-V_M2I#T3FBUNL25iM%~Ll0{`^Vf3?TgGyIzBtT=@w;qaq} zZFx44Z`2qca6Tzg*|{ZAan6xXO|6}egg+SBR0hAT&s@0wZR007$tf={w@7Nl%$1rh zFvptj;X|9adU@^#4Bw)PM6Nen{p9|!^wgDCGuxR3-{*eWaY^p{!Fq1tW4)za^=!q7 zc~37N|Lfk-_BPh&hMz?GjeAS|yB`>B(5Y9I3p~K?9k=Sq!iv@t>)rc(?p)E7xRkC+NYrY^l+uL$M<7-tA4%t@a^yK zb9Ln_*gk$=?_S}q)5q%>Y%W>GH*f3TmGDIWZE$&(Z6%+ z`AfDn6szl2O?sR9I+^t_L)o-Mjn56Xv86TFMUU9;6HBqJN_$~3|3}yFN|m;^f=eT- zr_~7;t3S5uJoxOU_6BzCb@2}_O z)&nw)nU2Me&OXUr=)QE{xl8xNq7%F2+$(;Eef@X(dB{-&!mHo!kc=}YKPrPR{8tqtDoCFUBx-m z=S4lf-E{UVQ$3$={8ah++f1rhZ7GqbbDmkpl0cgL9vp z<^DX`z*x~bd~^NlXY1|mFMrjT%%c~j5aYO9d|m%Nf!Vf(>QlpgVrER;rE}G&>fcc- zgRHuXda44;?_Zq1%lW=a)~?QkuEYP*wOZ~JLpp%R4jL3 z`TwoLjT3&EU+p}RwttuRk_FcBf9K0oY*s3?-6>U>F8yP&>U^h{^?R2jiC=uzTx;6+ zH@jFNfAU-9%C-&m%N}jW)UWpMout9=`rU>52c;yZIInHE?$c~q&!*A5qR!0Q?Zo<7 zVzW2Q5!n#&aixh${N>~Gm^jy8-Mf0`X&sd{*Vd=`6o2omE^~VFO*MW4e@`iMwAsuV zTc*z9S+wFmYj5wS*_-uTPBJnZ=ow7zao3ovx@+hNfnwrluB~ zd)!Ykx*F&iXmaU07o{eaWaj6&B$lLVxL6q(7#SHF7#bNF8JHPb=o*--8yKi-a_Rf# zr(jhvdA6q##PWll`u0W^<_aL&3>5MdxWEiU3sXx|G%*7+BO^m}F;h!p)5-c?s`VBo zmgsWkhNkFd7#bOx8=$K*voJA66Eie0F~wA8Vrqn@&cNKl#0(@>Z-8*TftfL;LNfz% zbWa)>TbN-u+SJm}1Y{tJc_s!J7F!rXEQYFc1qGX-fw>{NLPH}nOvjj;8>3rdXl`t5 zJbAjeZLFJTSTma9&{v`ka diff --git a/libraries/zlib/zlib.h b/libraries/zlib/zlib.h index 953cb5012..6b7244f99 100644 --- a/libraries/zlib/zlib.h +++ b/libraries/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.13, October 13th, 2022 + version 1.3, August 18th, 2023 - Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2023 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 @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.13" -#define ZLIB_VERNUM 0x12d0 +#define ZLIB_VERSION "1.3" +#define ZLIB_VERNUM 0x1300 #define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 13 +#define ZLIB_VER_MINOR 3 +#define ZLIB_VER_REVISION 0 #define ZLIB_VER_SUBREVISION 0 /* @@ -78,8 +78,8 @@ extern "C" { even in the case of corrupted input. */ -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); +typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); +typedef void (*free_func)(voidpf opaque, voidpf address); struct internal_state; @@ -217,7 +217,7 @@ typedef gz_header FAR *gz_headerp; /* basic functions */ -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +ZEXTERN const char * ZEXPORT zlibVersion(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 @@ -225,12 +225,12 @@ ZEXTERN const char * ZEXPORT zlibVersion OF((void)); */ /* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); +ZEXTERN int ZEXPORT deflateInit(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. + allocation functions. total_in, total_out, adler, and msg are initialized. 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 @@ -247,7 +247,7 @@ ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); */ -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +ZEXTERN int ZEXPORT deflate(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 @@ -320,8 +320,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); 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. + avail_out is greater than six when the flush marker begins, in order to avoid + repeated flush markers upon calling deflate() again when avail_out == 0. 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 @@ -360,7 +360,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); */ -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateEnd(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 @@ -375,7 +375,7 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); /* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateInit(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 @@ -383,7 +383,8 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); read or consumed. The allocation of a sliding window will be deferred to the first call of inflate (if the decompression does not complete on the first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. + them to use default allocation functions. total_in, total_out, adler, and + msg are initialized. 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 @@ -397,7 +398,7 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); */ -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +ZEXTERN int ZEXPORT inflate(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 @@ -517,7 +518,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); */ -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateEnd(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 @@ -535,12 +536,12 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); */ /* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); +ZEXTERN int ZEXPORT deflateInit2(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 zalloc, zfree and opaque must be initialized before by the caller. @@ -607,9 +608,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, compression: this will be done by deflate(). */ -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); +ZEXTERN int ZEXPORT deflateSetDictionary(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 @@ -651,9 +652,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, not perform any compression: this will be done by deflate(). */ -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); +ZEXTERN int ZEXPORT deflateGetDictionary(z_streamp strm, + Bytef *dictionary, + uInt *dictLength); /* Returns the sliding dictionary being maintained by deflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied @@ -673,8 +674,8 @@ ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, stream state is inconsistent. */ -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); +ZEXTERN int ZEXPORT deflateCopy(z_streamp dest, + z_streamp source); /* Sets the destination stream as a complete copy of the source stream. @@ -691,20 +692,20 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, destination. */ -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +ZEXTERN int ZEXPORT deflateReset(z_streamp strm); /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate the internal compression state. The stream will leave the compression level and any other attributes that may have been - set unchanged. + set unchanged. total_in, total_out, adler, and msg are initialized. 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)); +ZEXTERN int ZEXPORT deflateParams(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 @@ -729,7 +730,7 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, Then no more input data should be provided before the deflateParams() call. If this is done, the old level and strategy will be applied to the data compressed before deflateParams(), and the new level and strategy will be - applied to the the data compressed after deflateParams(). + applied to the data compressed after deflateParams(). deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if @@ -740,11 +741,11 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, retried with more output space. */ -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); +ZEXTERN int ZEXPORT deflateTune(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 @@ -757,8 +758,8 @@ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); +ZEXTERN uLong ZEXPORT deflateBound(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 @@ -772,9 +773,9 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, than Z_FINISH or Z_NO_FLUSH are used. */ -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); +ZEXTERN int ZEXPORT deflatePending(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 @@ -787,9 +788,9 @@ ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, stream state was inconsistent. */ -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); +ZEXTERN int ZEXPORT deflatePrime(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 @@ -804,8 +805,8 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, source stream state was inconsistent. */ -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); +ZEXTERN int ZEXPORT deflateSetHeader(z_streamp strm, + gz_headerp head); /* deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called @@ -821,16 +822,17 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, 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(). + the time set to zero, and os set to the current operating system, 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)); +ZEXTERN int ZEXPORT inflateInit2(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 @@ -883,9 +885,9 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, deferred until inflate() is called. */ -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); +ZEXTERN int ZEXPORT inflateSetDictionary(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, @@ -906,9 +908,9 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflate(). */ -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); +ZEXTERN int ZEXPORT inflateGetDictionary(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 @@ -921,7 +923,7 @@ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, stream state is inconsistent. */ -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateSync(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 @@ -940,8 +942,8 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); input each time, until success or end of the input data. */ -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); +ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, + z_streamp source); /* Sets the destination stream as a complete copy of the source stream. @@ -956,18 +958,19 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, destination. */ -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateReset(z_streamp strm); /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. + total_in, total_out, adler, and msg are initialized. 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)); +ZEXTERN int ZEXPORT inflateReset2(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 @@ -980,9 +983,9 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, the windowBits parameter is invalid. */ -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); +ZEXTERN int ZEXPORT inflatePrime(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 @@ -1001,7 +1004,7 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, stream state was inconsistent. */ -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); +ZEXTERN long ZEXPORT inflateMark(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 @@ -1029,8 +1032,8 @@ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); source stream state was inconsistent. */ -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); +ZEXTERN int ZEXPORT inflateGetHeader(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 @@ -1070,8 +1073,8 @@ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, */ /* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); +ZEXTERN int ZEXPORT inflateBackInit(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 @@ -1091,13 +1094,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, 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)); +typedef unsigned (*in_func)(void FAR *, + z_const unsigned char FAR * FAR *); +typedef int (*out_func)(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)); +ZEXTERN int ZEXPORT inflateBack(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 @@ -1165,7 +1168,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, cannot return Z_OK. */ -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); +ZEXTERN int ZEXPORT inflateBackEnd(z_streamp strm); /* All memory allocated by inflateBackInit() is freed. @@ -1173,7 +1176,7 @@ ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); state was inconsistent. */ -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +ZEXTERN uLong ZEXPORT zlibCompileFlags(void); /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: @@ -1226,8 +1229,8 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); you need special options. */ -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); +ZEXTERN int ZEXPORT compress(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 @@ -1241,9 +1244,9 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, buffer. */ -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); +ZEXTERN int ZEXPORT compress2(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 @@ -1257,15 +1260,15 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, Z_STREAM_ERROR if the level parameter is invalid. */ -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +ZEXTERN uLong ZEXPORT compressBound(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)); +ZEXTERN int ZEXPORT uncompress(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 @@ -1282,8 +1285,8 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, buffer with the uncompressed data up to that point. */ -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen)); +ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, + const Bytef *source, uLong *sourceLen); /* Same as uncompress, except that sourceLen is a pointer, where the length of the source is *sourceLen. On return, *sourceLen is the number of @@ -1302,7 +1305,7 @@ ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ /* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +ZEXTERN gzFile ZEXPORT gzopen(const char *path, const char *mode); Open the gzip (.gz) file at path for reading and decompressing, or compressing and writing. The mode parameter is as in fopen ("rb" or "wb") @@ -1339,7 +1342,7 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); file could not be opened. */ -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +ZEXTERN gzFile ZEXPORT gzdopen(int fd, const char *mode); /* Associate a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (if the file has @@ -1362,7 +1365,7 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); will not detect if fd is invalid (unless fd is -1). */ -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); +ZEXTERN int ZEXPORT gzbuffer(gzFile file, unsigned size); /* Set the internal buffer size used by this library's functions for file to size. The default buffer size is 8192 bytes. This function must be called @@ -1378,7 +1381,7 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); too late. */ -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +ZEXTERN int ZEXPORT gzsetparams(gzFile file, int level, int strategy); /* Dynamically update the compression level and strategy for file. See the description of deflateInit2 for the meaning of these parameters. Previously @@ -1389,7 +1392,7 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); or Z_MEM_ERROR if there is a memory allocation error. */ -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); /* Read and decompress up to len uncompressed bytes from file into buf. If the input file is not in gzip format, gzread copies the given number of @@ -1419,8 +1422,8 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); Z_STREAM_ERROR. */ -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, - gzFile file)); +ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, + gzFile file); /* Read and decompress up to nitems items of size size from file into buf, otherwise operating as gzread() does. This duplicates the interface of @@ -1445,14 +1448,14 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, file, resetting and retrying on end-of-file, when size is not 1. */ -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); +ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); /* Compress and write the len uncompressed bytes at buf to file. gzwrite returns the number of uncompressed bytes written or 0 in case of error. */ -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, - z_size_t nitems, gzFile file)); +ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, + z_size_t nitems, gzFile file); /* Compress and write nitems items of size size from buf to file, duplicating the interface of stdio's fwrite(), with size_t request and return types. If @@ -1465,7 +1468,7 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, is returned, and the error state is set to Z_STREAM_ERROR. */ -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); +ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); /* Convert, format, compress, and write the arguments (...) to file under control of the string format, as in fprintf. gzprintf returns the number of @@ -1480,7 +1483,7 @@ ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); This can be determined using zlibCompileFlags(). */ -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +ZEXTERN int ZEXPORT gzputs(gzFile file, const char *s); /* Compress and write the given null-terminated string s to file, excluding the terminating null character. @@ -1488,7 +1491,7 @@ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); gzputs returns the number of characters written, or -1 in case of error. */ -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); /* Read and decompress bytes from file into buf, until len-1 characters are read, or until a newline character is read and transferred to buf, or an @@ -1502,13 +1505,13 @@ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); buf are indeterminate. */ -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +ZEXTERN int ZEXPORT gzputc(gzFile file, int c); /* Compress and write c, converted to an unsigned char, into file. gzputc returns the value that was written, or -1 in case of error. */ -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +ZEXTERN int ZEXPORT gzgetc(gzFile file); /* Read and decompress one byte from file. gzgetc returns this byte or -1 in case of end of file or error. This is implemented as a macro for speed. @@ -1517,7 +1520,7 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); points to has been clobbered or not. */ -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +ZEXTERN int ZEXPORT gzungetc(int c, gzFile file); /* Push c back onto the stream for file to be read as the first character on the next read. At least one character of push-back is always allowed. @@ -1529,7 +1532,7 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); gzseek() or gzrewind(). */ -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +ZEXTERN int ZEXPORT gzflush(gzFile file, int flush); /* Flush all pending output to file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function @@ -1545,8 +1548,8 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); */ /* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); +ZEXTERN z_off_t ZEXPORT gzseek(gzFile file, + z_off_t offset, int whence); Set the starting position to offset relative to whence for the next gzread or gzwrite on file. The offset represents a number of bytes in the @@ -1564,7 +1567,7 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, would be before the current position. */ -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +ZEXTERN int ZEXPORT gzrewind(gzFile file); /* Rewind file. This function is supported only for reading. @@ -1572,7 +1575,7 @@ ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); */ /* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +ZEXTERN z_off_t ZEXPORT gztell(gzFile file); Return the starting position for the next gzread or gzwrite on file. This position represents a number of bytes in the uncompressed data stream, @@ -1583,7 +1586,7 @@ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); */ /* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); +ZEXTERN z_off_t ZEXPORT gzoffset(gzFile file); Return the current compressed (actual) read or write offset of file. This offset includes the count of bytes that precede the gzip stream, for example @@ -1592,7 +1595,7 @@ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); be used for a progress indicator. On error, gzoffset() returns -1. */ -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +ZEXTERN int ZEXPORT gzeof(gzFile file); /* Return true (1) if the end-of-file indicator for file has been set while reading, false (0) otherwise. Note that the end-of-file indicator is set @@ -1607,7 +1610,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); has grown since the previous end of file was detected. */ -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); +ZEXTERN int ZEXPORT gzdirect(gzFile file); /* Return true (1) if file is being copied directly while reading, or false (0) if file is a gzip stream being decompressed. @@ -1628,7 +1631,7 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); gzip file reading and decompression, which may not be desired.) */ -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +ZEXTERN int ZEXPORT gzclose(gzFile file); /* Flush all pending output for file, if necessary, close file and deallocate the (de)compression state. Note that once file is closed, you @@ -1641,8 +1644,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); 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)); +ZEXTERN int ZEXPORT gzclose_r(gzFile file); +ZEXTERN int ZEXPORT gzclose_w(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 @@ -1653,7 +1656,7 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); zlib library. */ -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +ZEXTERN const char * ZEXPORT gzerror(gzFile file, int *errnum); /* Return the error message for the last error which occurred on file. errnum is set to zlib error number. If an error occurred in the file system @@ -1669,7 +1672,7 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); functions above that do not distinguish those cases in their return values. */ -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +ZEXTERN void ZEXPORT gzclearerr(gzFile file); /* Clear 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 @@ -1686,7 +1689,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); library. */ -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); +ZEXTERN uLong ZEXPORT adler32(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. An Adler-32 value is in the range of a 32-bit @@ -1706,15 +1709,15 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); if (adler != original_adler) error(); */ -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); +ZEXTERN uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, + z_size_t len); /* Same as adler32(), but with a size_t length. */ /* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); +ZEXTERN uLong ZEXPORT adler32_combine(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 @@ -1724,7 +1727,7 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, negative, the result has no meaning or utility. */ -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +ZEXTERN uLong ZEXPORT crc32(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. A CRC-32 value is in the range of a 32-bit unsigned integer. @@ -1742,14 +1745,14 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); if (crc != original_crc) error(); */ -ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf, - z_size_t len)); +ZEXTERN uLong ZEXPORT crc32_z(uLong crc, const Bytef *buf, + z_size_t len); /* Same as crc32(), but with a size_t length. */ /* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); +ZEXTERN uLong ZEXPORT crc32_combine(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 @@ -1759,13 +1762,13 @@ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); */ /* -ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2)); +ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with crc32_combine_op(). */ -ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op)); +ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); /* Give the same result as crc32_combine(), using op in place of len2. op is is generated from len2 by crc32_combine_gen(). This will be faster than @@ -1778,20 +1781,20 @@ ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op)); /* 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)); +ZEXTERN int ZEXPORT deflateInit_(z_streamp strm, int level, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, + const char *version, int stream_size); +ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size); +ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, + const char *version, int stream_size); +ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size); #ifdef Z_PREFIX_SET # define z_deflateInit(strm, level) \ deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) @@ -1836,7 +1839,7 @@ struct gzFile_s { unsigned char *next; z_off64_t pos; }; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ +ZEXTERN int ZEXPORT gzgetc_(gzFile file); /* backward compatibility */ #ifdef Z_PREFIX_SET # undef z_gzgetc # define z_gzgetc(g) \ @@ -1853,13 +1856,13 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ * 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)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); + ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off64_t); #endif #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) @@ -1881,50 +1884,50 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ # define crc32_combine_gen crc32_combine_gen64 # 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)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t)); + ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell64(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(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)); - ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); + ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); + ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); + ZEXTERN z_off_t ZEXPORT gztell(gzFile); + ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(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)); - ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); + ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); #endif /* !Z_SOLO */ /* 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 inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF((z_streamp)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); +ZEXTERN const char * ZEXPORT zError(int); +ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); +ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); +ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); +ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); +ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); +ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); +ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); #if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); +ZEXTERN gzFile ZEXPORT gzopen_w(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)); +ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, + const char *format, + va_list va); # endif #endif diff --git a/libraries/zlib/zutil.c b/libraries/zlib/zutil.c index 9543ae825..b1c5d2d3c 100644 --- a/libraries/zlib/zutil.c +++ b/libraries/zlib/zutil.c @@ -24,13 +24,11 @@ z_const char * const z_errmsg[10] = { }; -const char * ZEXPORT zlibVersion() -{ +const char * ZEXPORT zlibVersion(void) { return ZLIB_VERSION; } -uLong ZEXPORT zlibCompileFlags() -{ +uLong ZEXPORT zlibCompileFlags(void) { uLong flags; flags = 0; @@ -121,9 +119,7 @@ uLong ZEXPORT zlibCompileFlags() # endif int ZLIB_INTERNAL z_verbose = verbose; -void ZLIB_INTERNAL z_error(m) - char *m; -{ +void ZLIB_INTERNAL z_error(char *m) { fprintf(stderr, "%s\n", m); exit(1); } @@ -132,9 +128,7 @@ void ZLIB_INTERNAL z_error(m) /* exported to allow conversion of error code to string for compress() and * uncompress() */ -const char * ZEXPORT zError(err) - int err; -{ +const char * ZEXPORT zError(int err) { return ERR_MSG(err); } @@ -148,22 +142,14 @@ const char * ZEXPORT zError(err) #ifndef HAVE_MEMCPY -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ +void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { if (len == 0) return; do { *dest++ = *source++; /* ??? to be unrolled */ } while (--len != 0); } -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ +int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { uInt j; for (j = 0; j < len; j++) { @@ -172,10 +158,7 @@ int ZLIB_INTERNAL zmemcmp(s1, s2, len) return 0; } -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ +void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { if (len == 0) return; do { *dest++ = 0; /* ??? to be unrolled */ @@ -216,8 +199,7 @@ local ptr_table table[MAX_PTR]; * a protected system like OS/2. Use Microsoft C instead. */ -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { voidpf buf; ulg bsize = (ulg)items*size; @@ -242,8 +224,7 @@ voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) return buf; } -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { int n; (void)opaque; @@ -279,14 +260,12 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) # define _hfree hfree #endif -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { (void)opaque; return _halloc((long)items, size); } -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; _hfree(ptr); } @@ -299,25 +278,18 @@ void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); +extern voidp malloc(uInt size); +extern voidp calloc(uInt items, uInt size); +extern void free(voidpf ptr); #endif -voidpf ZLIB_INTERNAL zcalloc(opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { (void)opaque; return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } -void ZLIB_INTERNAL zcfree(opaque, ptr) - voidpf opaque; - voidpf ptr; -{ +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { (void)opaque; free(ptr); } diff --git a/libraries/zlib/zutil.h b/libraries/zlib/zutil.h index 0bc7f4ecd..902a304cc 100644 --- a/libraries/zlib/zutil.h +++ b/libraries/zlib/zutil.h @@ -191,9 +191,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* 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)); - ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t)); + ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); + ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); #endif /* common defaults */ @@ -232,16 +232,16 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # 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)); + void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len); + int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); + void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); #endif /* Diagnostic functions */ #ifdef ZLIB_DEBUG # include extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); + extern void ZLIB_INTERNAL z_error(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 ;} @@ -258,9 +258,9 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif #ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); - void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); + voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, + unsigned size); + void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr); #endif #define ZALLOC(strm, items, size) \ From 5cfdd82e0f9a58a5f358b742edfd9ece3a60daf6 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 13 Sep 2023 12:52:45 +0300 Subject: [PATCH 088/223] - ci: update to clang 10 versions before 9 fails to compile with the following error /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_tree.h:701:4: error: exception specification of explicitly defaulted move constructor does not match the calculated one clang 9 fails to link with the following errors /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/cmath:223: undefined reference to `__expf_finite' src/rendering/swrenderer/drawers/r_draw_rgba.cpp:1120: undefined reference to `__log2_finite' src/rendering/swrenderer/drawers/r_draw_rgba.cpp:1120: undefined reference to `__log2_finite' src/rendering/swrenderer/drawers/r_draw_rgba.cpp:1120: undefined reference to `__log2_finite' src/rendering/swrenderer/plane/r_flatplane.cpp:183: undefined reference to `__log2_finite' src/rendering/swrenderer/viewport/r_spritedrawer.cpp:174: undefined reference to `__log2_finite' --- .github/workflows/continuous_integration.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 4a7dcbee4..365116bb5 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -55,13 +55,13 @@ jobs: deps_cmdline: "sudo apt update && sudo apt install g++-11 libsdl2-dev libvpx-dev libgtk-3-dev libwebp-dev", build_type: "MinSizeRel" } -# - { -# name: "Linux Clang 6", -# os: ubuntu-20.04, -# extra_options: "-DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DDYN_OPENAL=OFF", -# deps_cmdline: "sudo apt update && sudo apt install clang-6.0 libsdl2-dev libvpx-dev libopenal-dev libfluidsynth-dev libmpg123-dev libsndfile1-dev", -# build_type: "Debug" -# } + - { + name: "Linux Clang 10", + os: ubuntu-20.04, + extra_options: "-DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 -DDYN_OPENAL=OFF", + deps_cmdline: "sudo apt update && sudo apt install clang-9 libsdl2-dev libvpx-dev libopenal-dev libfluidsynth-dev libmpg123-dev libsndfile1-dev libwebp-dev", + build_type: "Debug" + } - { name: "Linux Clang 12", os: ubuntu-20.04, From 8b31e0d3b65017d6afa1f6274f8bd4c2b73c4000 Mon Sep 17 00:00:00 2001 From: Professor Hastig Date: Wed, 13 Sep 2023 09:47:09 +0200 Subject: [PATCH 089/223] - fix bad stringpool setup in filesystem. Doing it in the constructor does not work because InitMultipleFiles will clear everything again before building up the directory so it would always be null. This triggered another bug in file_directory.cpp which used the constructor's unvalidated parameter. --- src/common/filesystem/include/fs_filesystem.h | 2 +- src/common/filesystem/source/file_directory.cpp | 2 +- src/common/filesystem/source/filesystem.cpp | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/common/filesystem/include/fs_filesystem.h b/src/common/filesystem/include/fs_filesystem.h index b55949408..bac46e1bb 100644 --- a/src/common/filesystem/include/fs_filesystem.h +++ b/src/common/filesystem/include/fs_filesystem.h @@ -202,7 +202,7 @@ protected: int IwadIndex = -1; int MaxIwadIndex = -1; - StringPool* stringpool; + StringPool* stringpool = nullptr; private: void DeleteAll(); diff --git a/src/common/filesystem/source/file_directory.cpp b/src/common/filesystem/source/file_directory.cpp index 84679ffc9..89b9625fc 100644 --- a/src/common/filesystem/source/file_directory.cpp +++ b/src/common/filesystem/source/file_directory.cpp @@ -96,7 +96,7 @@ FDirectory::FDirectory(const char * directory, StringPool* sp, bool nosubdirflag { auto fn = FS_FullPath(directory); if (fn.back() != '/') fn += '/'; - FileName = sp->Strdup(fn.c_str()); + FileName = stringpool->Strdup(fn.c_str()); } //========================================================================== diff --git a/src/common/filesystem/source/filesystem.cpp b/src/common/filesystem/source/filesystem.cpp index c22682ec0..cc810cc2e 100644 --- a/src/common/filesystem/source/filesystem.cpp +++ b/src/common/filesystem/source/filesystem.cpp @@ -194,8 +194,6 @@ static void PrintLastError (FileSystemMessageFunc Printf); FileSystem::FileSystem() { - stringpool = new StringPool(true); - stringpool->shared = true; // will be used by all owned resource files. } FileSystem::~FileSystem () @@ -219,7 +217,7 @@ void FileSystem::DeleteAll () delete Files[i]; } Files.clear(); - delete stringpool; + if (stringpool != nullptr) delete stringpool; stringpool = nullptr; } @@ -248,6 +246,9 @@ bool FileSystem::InitMultipleFiles (std::vector& filenames, LumpFil DeleteAll(); numfiles = 0; + stringpool = new StringPool(true); + stringpool->shared = true; // will be used by all owned resource files. + // first, check for duplicates if (allowduplicates) { From f72da434a8980d3872014ca8e3d4ac16899a0f97 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 13 Sep 2023 17:50:19 +0200 Subject: [PATCH 090/223] - fixed: For Dehacked, A_CPosAttack needs to use a hard coded attack sound. This discrepancy is ancient, so the approach used for the shotgunner does not work here and some hacks are needed to remap the function only for Dehacked. --- src/gamedata/d_dehacked.cpp | 5 ++++- wadsrc/static/zscript/actors/doom/possessed.zs | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 0b4f25576..6cb5b99bb 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -2696,6 +2696,8 @@ static int PatchCodePtrs (int dummy) // This skips the action table and goes directly to the internal symbol table // DEH compatible functions are easy to recognize. + // Note that A_CPosAttack needs to be remapped because it differs from the original and cannot be renamed anymore. + if (!symname.CompareNoCase("A_CPosAttack")) symname = "A_CPosAttackDehacked"; PFunction *sym = dyn_cast(PClass::FindActor(NAME_Weapon)->FindSymbol(symname, true)); if (sym == NULL) { @@ -3371,7 +3373,8 @@ static bool LoadDehSupp () // all relevant code pointers are either defined in Weapon // or Actor so this will find all of them. FString name = "A_"; - name << sc.String; + if (sc.Compare("CPosAttack")) name << "CPosAttackDehacked"; + else name << sc.String; PFunction *sym = dyn_cast(wcls->FindSymbol(name, true)); if (sym == NULL) { diff --git a/wadsrc/static/zscript/actors/doom/possessed.zs b/wadsrc/static/zscript/actors/doom/possessed.zs index eef344ab8..4fa9e0f7e 100644 --- a/wadsrc/static/zscript/actors/doom/possessed.zs +++ b/wadsrc/static/zscript/actors/doom/possessed.zs @@ -315,12 +315,12 @@ extend class Actor } } - void A_CPosAttack() + private void A_CPosAttackInternal(Sound snd) { if (target) { if (bStealth) visdir = 1; - A_StartSound(AttackSound, CHAN_WEAPON); + A_StartSound(snd, CHAN_WEAPON); A_FaceTarget(); double slope = AimLineAttack(angle, MISSILERANGE); double ang = angle + Random2[CPosAttack]() * (22.5/256); @@ -328,6 +328,17 @@ extend class Actor LineAttack(ang, MISSILERANGE, slope, damage, "Hitscan", "Bulletpuff"); } } + + void A_CPosAttack() + { + A_CPosAttackInternal(AttackSound); + } + + void A_CPosAttackDehacked() + { + A_CPosAttackInternal("chainguy/attack"); + } + void A_CPosRefire() { From 2fe0a7c60d9b297bb7ba9f5a2475a735208ae6fb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 13 Sep 2023 18:44:14 +0200 Subject: [PATCH 091/223] - fixed sound issues with DSDHacked. * forward declarations must be allowed. * this must disable map-local SNDINFOs because the added sounds would get lost otherwise. --- src/d_main.cpp | 5 +++++ src/gamedata/d_dehacked.cpp | 2 +- src/sound/s_advsound.cpp | 16 +++++++++++++++- src/sound/s_sound.h | 1 + 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index f2c5b6d5a..256632cfc 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -3358,6 +3358,8 @@ static int D_InitGame(const FIWADInfo* iwad_info, std::vector& allw if (!batchrun) Printf ("DecalLibrary: Load decals.\n"); DecalLibrary.ReadAllDecals (); + auto numbasesounds = soundEngine->GetNumSounds(); + // Load embedded Dehacked patches D_LoadDehLumps(FromIWAD); @@ -3387,6 +3389,9 @@ static int D_InitGame(const FIWADInfo* iwad_info, std::vector& allw // Create replacements for dehacked pickups FinishDehPatch(); + auto numdehsounds = soundEngine->GetNumSounds(); + if (numbasesounds < numdehsounds) S_LockLocalSndinfo(); // DSDHacked sounds are not compatible with map-local SNDINFOs. + if (!batchrun) Printf("M_Init: Init menus.\n"); SetDefaultMenuColors(); M_Init(); diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 6cb5b99bb..5a8822aa9 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -270,7 +270,7 @@ struct MBFParamState FSoundID GetSoundArg(int i, int def = 0) { int num = argsused & (1 << i) ? (int)args[i] : def; - return DehFindSound(num-1, true); + return DehFindSound(num-1); } double GetFloatArg(int i, double def = 0) diff --git a/src/sound/s_advsound.cpp b/src/sound/s_advsound.cpp index 4fbc221cd..884ae7114 100644 --- a/src/sound/s_advsound.cpp +++ b/src/sound/s_advsound.cpp @@ -172,6 +172,7 @@ struct FSavedPlayerSoundInfo // This specifies whether Timidity or Windows playback is preferred for a certain song (only useful for Windows.) MusicAliasMap MusicAliases; +static bool sndinfo_locked; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -581,7 +582,10 @@ void S_ParseSndInfo (bool redefine) { int lump; - if (!redefine) SavedPlayerSounds.Clear(); // clear skin sounds only for initial parsing. + if (redefine && sndinfo_locked) return; + + SavedPlayerSounds.Clear(); // clear skin sounds only for initial parsing. + S_ClearSoundData(); // remove old sound data first! CurrentPitchMask = 0; @@ -610,6 +614,11 @@ void S_ParseSndInfo (bool redefine) S_CheckIntegrity(); } +void S_LockLocalSndinfo() +{ + sndinfo_locked = true; +} + //========================================================================== // // Adds a level specific SNDINFO lump @@ -618,6 +627,11 @@ void S_ParseSndInfo (bool redefine) void S_AddLocalSndInfo(int lump) { + if (sndinfo_locked) + { + Printf("Local SNDINFO cannot be combined with DSDHacked sounds!"); + return; + } S_AddSNDINFO(lump); soundEngine->HashSounds (); diff --git a/src/sound/s_sound.h b/src/sound/s_sound.h index eb1800913..216f5829e 100644 --- a/src/sound/s_sound.h +++ b/src/sound/s_sound.h @@ -65,6 +65,7 @@ extern MusicAliasMap MusicAliases; // [RH] S_sfx "maintenance" routines void S_ClearSoundData(); void S_ParseSndInfo (bool redefine); +void S_LockLocalSndinfo(); bool S_AreSoundsEquivalent (AActor *actor, FSoundID id1, FSoundID id2); FSoundID S_LookupPlayerSound (const char *playerclass, int gender, FSoundID refid); From 0980b538817aea609397ebc53bdba6d04b305ae0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 13 Sep 2023 20:48:57 +0200 Subject: [PATCH 092/223] - fixed: MBF21's BOSS flag implies NORADIUSDMG. --- src/gamedata/d_dehacked.cpp | 16 ++++++++++++++-- wadsrc/static/zscript/actors/actor.zs | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 5a8822aa9..09a6dc310 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -1148,7 +1148,7 @@ static const struct DehFlags2 deh_mobjflags_mbf21[] = { {"RANGEHALF", [](AActor* defaults) { defaults->flags4 |= MF4_MISSILEMORE; }}, // use half distance for missile attack probability {"NOTHRESHOLD", [](AActor* defaults) { defaults->flags4 |= MF4_QUICKTORETALIATE; }}, // no targeting threshold {"LONGMELEE", [](AActor* defaults) { defaults->meleethreshold = 196; }}, // long melee range - {"BOSS", [](AActor* defaults) { defaults->flags2 |= MF2_BOSS; }}, // full volume see / death sound + splash immunity + {"BOSS", [](AActor* defaults) { defaults->flags2 |= MF2_BOSS; defaults->flags3 |= MF3_NORADIUSDMG; }}, // full volume see / death sound + splash immunity {"MAP07BOSS1", [](AActor* defaults) { defaults->flags8 |= MF8_MAP07BOSS1; }}, // Tag 666 "boss" on doom 2 map 7 {"MAP07BOSS2", [](AActor* defaults) { defaults->flags8 |= MF8_MAP07BOSS2; }}, // Tag 667 "boss" on doom 2 map 7 {"E1M8BOSS", [](AActor* defaults) { defaults->flags8 |= MF8_E1M8BOSS; }}, // E1M8 boss @@ -3890,6 +3890,18 @@ void ClearCountkill(AActor* a) if (a->CountsAsKill() && a->health > 0) a->Level->total_monsters++; } +void SetBoss(AActor* a) +{ + a->flags2 |= MF2_BOSS; + a->flags3 |= MF3_NORADIUSDMG; +} + +void ClearBoss(AActor* a) +{ + a->flags2 &= ~MF2_BOSS; + a->flags3 &= ~MF3_NORADIUSDMG; +} + void SetCountitem(AActor* a) { if (!(a->flags & MF_COUNTITEM)) @@ -4087,7 +4099,7 @@ static FlagHandler flag2handlers[32] = { F4(MF4_MISSILEMORE), F4(MF4_QUICKTORETALIATE), DEPF(DEPF_LONGMELEERANGE), - F2(MF2_BOSS), + { SetBoss, ClearBoss, [](AActor* a)->bool { return a->flags2 & MF2_BOSS; } }, F8(MF8_MAP07BOSS1), F8(MF8_MAP07BOSS2), F8(MF8_E1M8BOSS), diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 4e8e5977c..17949c18f 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -1321,7 +1321,7 @@ class Actor : Thinker native { if (DeathSound) { - A_StartSound(DeathSound, CHAN_VOICE, CHANF_DEFAULT, 1, bBoss? ATTN_NONE : ATTN_NORM); + A_StartSound(DeathSound, CHAN_VOICE, CHANF_DEFAULT, 1, bBoss || bFullvolDeath? ATTN_NONE : ATTN_NORM); } } From 52ec2b2a5b859534b68d3ec70112b63d9f6244aa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 13 Sep 2023 21:10:08 +0200 Subject: [PATCH 093/223] - listsounds CCMD --- src/common/audio/sound/s_sound.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/common/audio/sound/s_sound.cpp b/src/common/audio/sound/s_sound.cpp index f2c44a1c1..58e4a981f 100644 --- a/src/common/audio/sound/s_sound.cpp +++ b/src/common/audio/sound/s_sound.cpp @@ -1856,6 +1856,15 @@ CCMD(snd_listdrivers) GSnd->PrintDriversList(); } +CCMD(listsounds) +{ + for (unsigned i = 1; i < soundEngine->GetNumSounds(); i++) + { + auto S_sfx = soundEngine->GetSfx(FSoundID::fromInt(i)); + Printf("%04d: %s\n", i, S_sfx->name.GetChars()); + } +} + ADD_STAT(sound) { return GSnd->GatherStats(); From fbf7d1025a6f48d5dd739344b61bff9d28b76129 Mon Sep 17 00:00:00 2001 From: Professor Hastig Date: Thu, 14 Sep 2023 08:48:47 +0200 Subject: [PATCH 094/223] - fixed bad clamp in software renderer This one can have its upper bound below its lower bound which triggers the validation within std::clamp. Fixes #2125 --- src/rendering/swrenderer/line/r_walldraw.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/swrenderer/line/r_walldraw.cpp b/src/rendering/swrenderer/line/r_walldraw.cpp index 0e2338d1e..bd7ae48c4 100644 --- a/src/rendering/swrenderer/line/r_walldraw.cpp +++ b/src/rendering/swrenderer/line/r_walldraw.cpp @@ -108,7 +108,7 @@ namespace swrenderer { for (int j = x1; j < x2; ++j) { - down[j] = clamp(most3.ScreenY[j], up[j], dwal[j]); + down[j] = max(min(most3.ScreenY[j], up[j]), dwal[j]); // this cannot use clamp due to failing range checks. } ProcessNormalWall(up, down, texcoords); up = down; From e4bf6c229a3c375c9d5ffda2173863365bdb0f65 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Thu, 14 Sep 2023 08:36:48 -0400 Subject: [PATCH 095/223] - update vcpkg base to address vulnerability [CVE-2023-4863](https://nvd.nist.gov/vuln/detail/CVE-2023-4863) --- vcpkg.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcpkg.json b/vcpkg.json index a045b8d74..edf05d241 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", - "builtin-baseline": "65c013b9667ff1f58fb8724209227e5a2e761043", + "builtin-baseline": "2c401863dd54a640aeb26ed736c55489c079323b", "features": { "vcpkg-libvpx": From 6033b054e25dfeae2049fce532bc151c8aa74775 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Thu, 14 Sep 2023 08:45:39 -0400 Subject: [PATCH 096/223] - bump vcpkg version in continuous integration --- .github/workflows/continuous_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 365116bb5..30bf10df1 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -96,7 +96,7 @@ jobs: if: runner.os == 'Windows' with: vcpkgDirectory: '${{ github.workspace }}/build/vcpkg' - vcpkgGitCommitId: '65c013b9667ff1f58fb8724209227e5a2e761043' + vcpkgGitCommitId: '2c401863dd54a640aeb26ed736c55489c079323b' - name: Configure shell: bash From 736d38e8c33d86f7e4f126839148bc78aeffab08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Mon, 15 May 2023 02:48:17 -0300 Subject: [PATCH 097/223] add StartGameDirect function --- src/g_level.cpp | 2 +- src/menu/doommenu.cpp | 73 +++++++++++++++++++-- src/menu/doommenu.h | 3 +- wadsrc/static/zscript/ui/menu/playermenu.zs | 2 + 4 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 4b7229ab0..d161059e6 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -271,7 +271,7 @@ void G_DeferedInitNew (const char *mapname, int newskill) void G_DeferedInitNew (FNewGameStartup *gs) { - if (gs->PlayerClass != NULL) playerclass = gs->PlayerClass; + if (gs->hasPlayerClass) playerclass = gs->PlayerClass; d_mapname = AllEpisodes[gs->Episode].mEpisodeMap; d_skill = gs->Skill; CheckWarpTransMap (d_mapname, true); diff --git a/src/menu/doommenu.cpp b/src/menu/doommenu.cpp index 5fd354202..c8fb9cd3a 100644 --- a/src/menu/doommenu.cpp +++ b/src/menu/doommenu.cpp @@ -86,6 +86,59 @@ bool OkForLocalization(FTextureID texnum, const char* substitute); FNewGameStartup NewGameStartupInfo; int LastSkill = -1; +void StartGameDirect(bool hasPlayerClass, bool randomPlayerClass, PClassActor * playerClass, int Episode, int Skill) +{ + // shouldn't work outside of a menu + if (DMenu::InMenu) + { + NewGameStartupInfo.hasPlayerClass = hasPlayerClass; + + if(hasPlayerClass) + { + if(randomPlayerClass) + { + NewGameStartupInfo.PlayerClass = "Random"; + } + else if(!playerClass) + { + NullParam("playerClass"); + } + else + { + NewGameStartupInfo.PlayerClass = playerClass->GetDisplayName(); + } + } + + NewGameStartupInfo.Episode = Episode; + NewGameStartupInfo.Skill = Skill; + + G_DeferedInitNew (&NewGameStartupInfo); + + if (gamestate == GS_FULLCONSOLE) + { + gamestate = GS_HIDECONSOLE; + gameaction = ga_newgame; + } + + M_ClearMenus (); + } + else + { + ThrowAbortException(X_OTHER, "Attempt to start a new game outside of menu code"); + } +} + +DEFINE_ACTION_FUNCTION_NATIVE(DPlayerMenu, StartGameDirect, StartGameDirect) +{ + PARAM_PROLOGUE; + PARAM_BOOL(hasPlayerClass); + PARAM_BOOL(randomPlayerClass); + PARAM_POINTER(playerClass, PClassActor); + PARAM_INT(Episode); + PARAM_INT(Skill); + StartGameDirect(hasPlayerClass, randomPlayerClass, playerClass, Episode, Skill); + return 0; +} bool M_SetSpecialMenu(FName& menu, int param) { @@ -127,9 +180,17 @@ bool M_SetSpecialMenu(FName& menu, int param) // sent from the player class menu NewGameStartupInfo.Skill = -1; NewGameStartupInfo.Episode = -1; - NewGameStartupInfo.PlayerClass = - param == -1000? nullptr : - param == -1? "Random" : GetPrintableDisplayName(PlayerClasses[param].Type).GetChars(); + + if(param == -1000) + { + NewGameStartupInfo.hasPlayerClass = false; + } + else + { + NewGameStartupInfo.hasPlayerClass = true; + NewGameStartupInfo.PlayerClass = (param == -1) ? FString("Random") : PlayerClasses[param].Type->GetDisplayName(); + } + M_StartupEpisodeMenu(&NewGameStartupInfo); // needs player class name from class menu (later) break; @@ -1180,7 +1241,7 @@ void M_StartupSkillMenu(FNewGameStartup *gs) DMenuItemBase *li = nullptr; FString *pItemText = nullptr; - if (gs->PlayerClass != nullptr) + if (gs->hasPlayerClass) { pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); } @@ -1207,7 +1268,7 @@ void M_StartupSkillMenu(FNewGameStartup *gs) FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? NAME_StartgameConfirm : NAME_Startgame; FString *pItemText = nullptr; - if (gs->PlayerClass != nullptr) + if (gs->hasPlayerClass) { pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); } @@ -1277,7 +1338,7 @@ fail: "StartgameConfirm" : "Startgame"; FString *pItemText = nullptr; - if (gs->PlayerClass != nullptr) + if (gs->hasPlayerClass) { pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); } diff --git a/src/menu/doommenu.h b/src/menu/doommenu.h index f80c7571f..3e9b5a75a 100644 --- a/src/menu/doommenu.h +++ b/src/menu/doommenu.h @@ -4,7 +4,8 @@ struct FNewGameStartup { - const char *PlayerClass; + bool hasPlayerClass; + FString PlayerClass; int Episode; int Skill; }; diff --git a/wadsrc/static/zscript/ui/menu/playermenu.zs b/wadsrc/static/zscript/ui/menu/playermenu.zs index 6404ac713..38a577a6d 100644 --- a/wadsrc/static/zscript/ui/menu/playermenu.zs +++ b/wadsrc/static/zscript/ui/menu/playermenu.zs @@ -40,6 +40,8 @@ class PlayerMenu : ListMenu PlayerClass mPlayerClass; Array PlayerColorSets; Array mPlayerSkins; + + static native void StartGameDirect(bool hasPlayerClass, bool randomPlayerClass, Class playerClass, int Episode, int Skill); // All write function for the player config are native to prevent abuse. static native void AutoaimChanged(float val); From 133fbf139045e288db6ee00db027658540188d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Mon, 15 May 2023 10:38:12 -0300 Subject: [PATCH 098/223] Disallow starting a new game during a netgame --- src/menu/doommenu.cpp | 47 +++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/menu/doommenu.cpp b/src/menu/doommenu.cpp index c8fb9cd3a..c9f54e581 100644 --- a/src/menu/doommenu.cpp +++ b/src/menu/doommenu.cpp @@ -91,33 +91,40 @@ void StartGameDirect(bool hasPlayerClass, bool randomPlayerClass, PClassActor * // shouldn't work outside of a menu if (DMenu::InMenu) { - NewGameStartupInfo.hasPlayerClass = hasPlayerClass; - - if(hasPlayerClass) + if(!netgame) { - if(randomPlayerClass) + NewGameStartupInfo.hasPlayerClass = hasPlayerClass; + + if(hasPlayerClass) { - NewGameStartupInfo.PlayerClass = "Random"; + if(randomPlayerClass) + { + NewGameStartupInfo.PlayerClass = "Random"; + } + else if(!playerClass) + { + NullParam("playerClass"); + } + else + { + NewGameStartupInfo.PlayerClass = playerClass->GetDisplayName(); + } } - else if(!playerClass) + + NewGameStartupInfo.Episode = Episode; + NewGameStartupInfo.Skill = Skill; + + G_DeferedInitNew (&NewGameStartupInfo); + + if (gamestate == GS_FULLCONSOLE) { - NullParam("playerClass"); - } - else - { - NewGameStartupInfo.PlayerClass = playerClass->GetDisplayName(); + gamestate = GS_HIDECONSOLE; + gameaction = ga_newgame; } } - - NewGameStartupInfo.Episode = Episode; - NewGameStartupInfo.Skill = Skill; - - G_DeferedInitNew (&NewGameStartupInfo); - - if (gamestate == GS_FULLCONSOLE) + else { - gamestate = GS_HIDECONSOLE; - gameaction = ga_newgame; + DPrintf(DMSG_WARNING, TEXTCOLOR_RED "Cannot start a new game during a netgame\n"); } M_ClearMenus (); From 9f24d8babce31b5b60d430cf1b5072749275ea1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 16 Jul 2023 19:03:30 -0300 Subject: [PATCH 099/223] Move StartGameDirect from PlayerMenu to Menu --- src/menu/doommenu.cpp | 2 +- wadsrc/static/zscript/ui/menu/playermenu.zs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/menu/doommenu.cpp b/src/menu/doommenu.cpp index c9f54e581..f2a80ddc6 100644 --- a/src/menu/doommenu.cpp +++ b/src/menu/doommenu.cpp @@ -135,7 +135,7 @@ void StartGameDirect(bool hasPlayerClass, bool randomPlayerClass, PClassActor * } } -DEFINE_ACTION_FUNCTION_NATIVE(DPlayerMenu, StartGameDirect, StartGameDirect) +DEFINE_ACTION_FUNCTION_NATIVE(DMenu, StartGameDirect, StartGameDirect) { PARAM_PROLOGUE; PARAM_BOOL(hasPlayerClass); diff --git a/wadsrc/static/zscript/ui/menu/playermenu.zs b/wadsrc/static/zscript/ui/menu/playermenu.zs index 38a577a6d..85a4b944b 100644 --- a/wadsrc/static/zscript/ui/menu/playermenu.zs +++ b/wadsrc/static/zscript/ui/menu/playermenu.zs @@ -33,6 +33,11 @@ ** */ +extend class Menu +{ + static native void StartGameDirect(bool hasPlayerClass, bool randomPlayerClass, Class playerClass, int Episode, int Skill); +} + class PlayerMenu : ListMenu { int mRotation; @@ -40,8 +45,6 @@ class PlayerMenu : ListMenu PlayerClass mPlayerClass; Array PlayerColorSets; Array mPlayerSkins; - - static native void StartGameDirect(bool hasPlayerClass, bool randomPlayerClass, Class playerClass, int Episode, int Skill); // All write function for the player config are native to prevent abuse. static native void AutoaimChanged(float val); From e61ab4cbe208c59db045b4f338cd0adacf572554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Mon, 13 Feb 2023 17:03:43 -0300 Subject: [PATCH 100/223] Expose OF_Transient to actors as bNoSaveGame --- src/common/engine/serializer.cpp | 2 ++ src/common/objects/dobjtype.cpp | 4 ++++ src/scripting/thingdef_data.cpp | 2 ++ 3 files changed, 8 insertions(+) diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index d0e6ac7c1..bf813118b 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -604,6 +604,8 @@ void FSerializer::WriteObjects() { auto obj = w->mDObjects[i]; + if(obj->ObjectFlags & OF_Transient) continue; + BeginObject(nullptr); w->Key("classtype"); w->String(obj->GetClass()->TypeName.GetChars()); diff --git a/src/common/objects/dobjtype.cpp b/src/common/objects/dobjtype.cpp index f9ccc4c77..b6379106c 100644 --- a/src/common/objects/dobjtype.cpp +++ b/src/common/objects/dobjtype.cpp @@ -440,6 +440,10 @@ DObject *PClass::CreateNew() I_Error("Attempt to instantiate abstract class %s.", TypeName.GetChars()); } ConstructNative (mem); + + if (Defaults != nullptr) + ((DObject *)mem)->ObjectFlags |= ((DObject *)Defaults)->ObjectFlags & OF_Transient; + ((DObject *)mem)->SetClass (const_cast(this)); InitializeSpecials(mem, Defaults, &PClass::SpecialInits); return (DObject *)mem; diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 792675576..cedf305b0 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -396,6 +396,8 @@ static FFlagDef ActorFlagDefs[]= DEFINE_FLAG2(BOUNCE_NotOnShootables, DONTBOUNCEONSHOOTABLES, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_BounceOnUnrips, BOUNCEONUNRIPPABLES, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_NotOnSky, DONTBOUNCEONSKY, AActor, BounceFlags), + + DEFINE_FLAG2(OF_Transient, NOSAVEGAME, AActor, ObjectFlags), }; // These won't be accessible through bitfield variables From 0e70e95fa42c31acc44310c1e7a9d1af9a25bc98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 1 Feb 2023 12:30:21 -0300 Subject: [PATCH 101/223] Add Inventory::ModifyBob and Inventory::ModifyBob3D --- src/common/scripting/vm/vm.h | 12 +++++++++ src/playsim/p_pspr.cpp | 26 +++++++++++++++++++ .../zscript/actors/inventory/inventory.zs | 4 +++ 3 files changed, 42 insertions(+) diff --git a/src/common/scripting/vm/vm.h b/src/common/scripting/vm/vm.h index 4b9334c04..73c4b48bb 100644 --- a/src/common/scripting/vm/vm.h +++ b/src/common/scripting/vm/vm.h @@ -830,4 +830,16 @@ unsigned GetVirtualIndex(PClass *cls, const char *funcname); VMFunction *func = clss->Virtuals.Size() > VIndex? clss->Virtuals[VIndex] : nullptr; \ if (func != nullptr) +#define IFOVERRIDENVIRTUALPTRNAME(self, clsname, funcname) \ + static VMFunction *orig_func = nullptr; \ + static unsigned VIndex = ~0u; \ + if (VIndex == ~0u) { \ + PClass *cls = PClass::FindClass(clsname); \ + VIndex = GetVirtualIndex(cls, #funcname); \ + orig_func = cls->Virtuals.Size() > VIndex? cls->Virtuals[VIndex] : nullptr; \ + assert(VIndex != ~0u); \ + } \ + auto *clss = self->GetClass(); \ + VMFunction *func = clss->Virtuals.Size() > VIndex? clss->Virtuals[VIndex] : nullptr; \ + if (func && func != orig_func ) #endif diff --git a/src/playsim/p_pspr.cpp b/src/playsim/p_pspr.cpp index d65b4d003..91e9dafc8 100644 --- a/src/playsim/p_pspr.cpp +++ b/src/playsim/p_pspr.cpp @@ -641,6 +641,19 @@ void P_BobWeapon (player_t *player, float *x, float *y, double ticfrac) DVector2 result; VMReturn ret(&result); VMCall(func, param, 2, &ret, 1); + + auto inv = player->mo->Inventory; + while(inv != nullptr && !(inv->ObjectFlags & OF_EuthanizeMe)) // same loop as ModifyDamage, except it actually checks if it's overriden before calling + { + auto nextinv = inv->Inventory; + IFOVERRIDENVIRTUALPTRNAME(inv, NAME_Inventory, ModifyBob) + { + VMValue param[] = { (DObject*)inv, result.X, result.Y, ticfrac }; + VMCall(func, param, 4, &ret, 1); + } + inv = nextinv; + } + *x = (float)result.X; *y = (float)result.Y; return; @@ -658,6 +671,19 @@ void P_BobWeapon3D (player_t *player, FVector3 *translation, FVector3 *rotation, returns[0].Vec3At(&t); returns[1].Vec3At(&r); VMCall(func, param, 2, returns, 2); + + auto inv = player->mo->Inventory; + while(inv != nullptr && !(inv->ObjectFlags & OF_EuthanizeMe)) + { + auto nextinv = inv->Inventory; + IFOVERRIDENVIRTUALPTRNAME(inv, NAME_Inventory, ModifyBob3D) + { + VMValue param[] = { (DObject*)inv, t.X, t.Y, t.Z, r.X, r.Y, r.Z, ticfrac }; + VMCall(func, param, 8, returns, 2); + } + inv = nextinv; + } + translation->X = (float)t.X; translation->Y = (float)t.Y; translation->Z = (float)t.Z; diff --git a/wadsrc/static/zscript/actors/inventory/inventory.zs b/wadsrc/static/zscript/actors/inventory/inventory.zs index 88bbd2f10..35c1a3d95 100644 --- a/wadsrc/static/zscript/actors/inventory/inventory.zs +++ b/wadsrc/static/zscript/actors/inventory/inventory.zs @@ -1021,6 +1021,10 @@ class Inventory : Actor //=========================================================================== virtual void ModifyDamage(int damage, Name damageType, out int newdamage, bool passive, Actor inflictor = null, Actor source = null, int flags = 0) {} + + virtual Vector2 ModifyBob(Vector2 Bob, double ticfrac) {return Bob;} + + virtual Vector3, Vector3 ModifyBob3D(Vector3 Translation, Vector3 Rotation, double ticfrac) {return Translation, Rotation;} virtual bool Use (bool pickup) { return false; } From a5e1f3bcad16949b7132bd91fa6977650d4bdb94 Mon Sep 17 00:00:00 2001 From: Professor Hastig Date: Thu, 14 Sep 2023 09:06:36 +0200 Subject: [PATCH 102/223] - fixed M_GetSavegamesPath for Linux. --- src/common/platform/posix/unix/i_specialpaths.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/platform/posix/unix/i_specialpaths.cpp b/src/common/platform/posix/unix/i_specialpaths.cpp index 524f94c60..f844f0dd0 100644 --- a/src/common/platform/posix/unix/i_specialpaths.cpp +++ b/src/common/platform/posix/unix/i_specialpaths.cpp @@ -191,7 +191,7 @@ FString M_GetScreenshotsPath() FString M_GetSavegamesPath() { - return NicePath("$HOME/" GAME_DIR "/"); + return NicePath("$HOME/" GAME_DIR "/savegames/"); } //=========================================================================== From ffa78917198f9522f023263b4abf7b3a4c7dc78b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 14 Sep 2023 16:39:21 +0200 Subject: [PATCH 103/223] - remove pointless assert. --- src/common/engine/serializer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index bf813118b..11eab7b9f 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -698,7 +698,6 @@ void FSerializer::ReadObjects(bool hubtravel) } EndArray(); - assert(!founderrors); if (founderrors) { Printf(TEXTCOLOR_RED "Failed to restore all objects in savegame\n"); From 30c2524742ae3ef8da3c8ee73fab9ce6b562cf1d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 14 Sep 2023 16:45:06 +0200 Subject: [PATCH 104/223] - validate text data before drawing the console. --- src/common/console/c_console.cpp | 71 +++++++++++++++++--------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/common/console/c_console.cpp b/src/common/console/c_console.cpp index f6366d7cd..b6377f1f1 100644 --- a/src/common/console/c_console.cpp +++ b/src/common/console/c_console.cpp @@ -648,48 +648,51 @@ void C_DrawConsole () conbuffer->FormatText(CurrentConsoleFont, ConWidth / textScale); unsigned int consolelines = conbuffer->GetFormattedLineCount(); FBrokenLines *blines = conbuffer->GetLines(); - FBrokenLines *printline = blines + consolelines - 1 - RowAdjust; - - int bottomline = ConBottom / textScale - CurrentConsoleFont->GetHeight()*2 - 4; - - for(FBrokenLines *p = printline; p >= blines && lines > 0; p--, lines--) + if (blines != nullptr) { - if (textScale == 1) - { - DrawText(twod, CurrentConsoleFont, CR_TAN, LEFTMARGIN, offset + lines * CurrentConsoleFont->GetHeight(), p->Text, TAG_DONE); - } - else - { - DrawText(twod, CurrentConsoleFont, CR_TAN, LEFTMARGIN, offset + lines * CurrentConsoleFont->GetHeight(), p->Text, - DTA_VirtualWidth, twod->GetWidth() / textScale, - DTA_VirtualHeight, twod->GetHeight() / textScale, - DTA_KeepRatio, true, TAG_DONE); - } - } + FBrokenLines* printline = blines + consolelines - 1 - RowAdjust; - if (ConBottom >= 20) - { - if (gamestate != GS_STARTUP) + int bottomline = ConBottom / textScale - CurrentConsoleFont->GetHeight() * 2 - 4; + + for (FBrokenLines* p = printline; p >= blines && lines > 0; p--, lines--) { - auto now = I_msTime(); - if (now > CursorTicker) - { - CursorTicker = now + 500; - cursoron = !cursoron; - } - CmdLine.Draw(left, bottomline, textScale, cursoron); - } - if (RowAdjust && ConBottom >= CurrentConsoleFont->GetHeight()*7/2) - { - // Indicate that the view has been scrolled up (10) - // and if we can scroll no further (12) if (textScale == 1) - DrawChar(twod, CurrentConsoleFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10, TAG_DONE); + { + DrawText(twod, CurrentConsoleFont, CR_TAN, LEFTMARGIN, offset + lines * CurrentConsoleFont->GetHeight(), p->Text, TAG_DONE); + } else - DrawChar(twod, CurrentConsoleFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10, + { + DrawText(twod, CurrentConsoleFont, CR_TAN, LEFTMARGIN, offset + lines * CurrentConsoleFont->GetHeight(), p->Text, DTA_VirtualWidth, twod->GetWidth() / textScale, DTA_VirtualHeight, twod->GetHeight() / textScale, DTA_KeepRatio, true, TAG_DONE); + } + } + + if (ConBottom >= 20) + { + if (gamestate != GS_STARTUP) + { + auto now = I_msTime(); + if (now > CursorTicker) + { + CursorTicker = now + 500; + cursoron = !cursoron; + } + CmdLine.Draw(left, bottomline, textScale, cursoron); + } + if (RowAdjust && ConBottom >= CurrentConsoleFont->GetHeight() * 7 / 2) + { + // Indicate that the view has been scrolled up (10) + // and if we can scroll no further (12) + if (textScale == 1) + DrawChar(twod, CurrentConsoleFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10, TAG_DONE); + else + DrawChar(twod, CurrentConsoleFont, CR_GREEN, 0, bottomline, RowAdjust == conbuffer->GetFormattedLineCount() ? 12 : 10, + DTA_VirtualWidth, twod->GetWidth() / textScale, + DTA_VirtualHeight, twod->GetHeight() / textScale, + DTA_KeepRatio, true, TAG_DONE); + } } } } From 4ad76f549e29a42b809879364b9a1af73bae5146 Mon Sep 17 00:00:00 2001 From: Nikolay Ambartsumov Date: Thu, 14 Sep 2023 20:36:47 +0300 Subject: [PATCH 105/223] When compat_floormove is enabled prevent sector floor from lowering if a thing is stuck in the ceiling (vanilla behavior) --- src/playsim/p_map.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index 797feb8e7..edb865b16 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -6652,6 +6652,12 @@ int P_PushDown(AActor *thing, FChangePosition *cpos) void PIT_FloorDrop(AActor *thing, FChangePosition *cpos) { + if ((thing->Level->i_compatflags2 & COMPATF2_FLOORMOVE) && (thing->Top() > thing->ceilingz)) + { + cpos->nofit = true; + return; + } + double oldfloorz = thing->floorz; double oldz = thing->Z(); @@ -7027,7 +7033,6 @@ bool P_ChangeSector(sector_t *sector, int crunch, double amt, int floorOrCeil, b } } - return cpos.nofit; } From 6847a9a5c11ebe9505887b0ea3f8956c6011ccd9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 14 Sep 2023 20:21:06 +0200 Subject: [PATCH 106/223] - added a nomirrors compatibility handler and applied it to Conf256's CONF55 map. This is for disabling broken plane reflection setups. --- src/doomdef.h | 1 + src/maploader/compatibility.cpp | 1 + src/rendering/hwrenderer/scene/hw_sky.cpp | 2 +- src/rendering/hwrenderer/scene/hw_walls.cpp | 2 +- wadsrc/static/compatibility.txt | 5 +++++ 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index bdeb81611..5d70ecd20 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -251,6 +251,7 @@ enum BCOMPATF_NOSLOPEID = 1 << 9, // disable line IDs on slopes. BCOMPATF_CLIPMIDTEX = 1 << 10, // Always Clip midtex's in the software renderer (required to run certain GZDoom maps, has no effect in the hardware renderer) BCOMPATF_NOSECTIONMERGE = 1 << 11, // (for IWAD maps) keep separate sections for sectors with intra-sector linedefs. + BCOMPATF_NOMIRRORS = 1 << 12, // disable mirrors, for maps that have broken setups. }; // phares 3/20/98: diff --git a/src/maploader/compatibility.cpp b/src/maploader/compatibility.cpp index 3549cd0bb..802ec3465 100644 --- a/src/maploader/compatibility.cpp +++ b/src/maploader/compatibility.cpp @@ -127,6 +127,7 @@ static FCompatOption Options[] = { "noslopeid", BCOMPATF_NOSLOPEID, SLOT_BCOMPAT }, { "clipmidtex", BCOMPATF_CLIPMIDTEX, SLOT_BCOMPAT }, { "nosectionmerge", BCOMPATF_NOSECTIONMERGE, SLOT_BCOMPAT }, + { "nomirrors", BCOMPATF_NOMIRRORS, SLOT_BCOMPAT }, // list copied from g_mapinfo.cpp diff --git a/src/rendering/hwrenderer/scene/hw_sky.cpp b/src/rendering/hwrenderer/scene/hw_sky.cpp index 5e4fc02ef..0af7309b2 100644 --- a/src/rendering/hwrenderer/scene/hw_sky.cpp +++ b/src/rendering/hwrenderer/scene/hw_sky.cpp @@ -155,7 +155,7 @@ void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowref break; } } - else if (allowreflect && sector->GetReflect(plane) > 0) + else if (allowreflect && sector->GetReflect(plane) > 0 && !(di->Level->ib_compatflags & BCOMPATF_NOMIRRORS)) { auto vpz = di->Viewpoint.Pos.Z; if ((plane == sector_t::ceiling && vpz > sector->ceilingplane.fD()) || diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index 88ed52068..b049ee172 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -1273,7 +1273,7 @@ void HWWall::DoTexture(HWDrawInfo *di, int _type,seg_t * seg, int peg, if (!SetWallCoordinates(seg, &tci, floatceilingref, topleft, topright, bottomleft, bottomright, seg->sidedef->GetTextureXOffset(texpos))) return; - if (seg->linedef->special == Line_Mirror && _type == RENDERWALL_M1S && gl_mirrors) + if (seg->linedef->special == Line_Mirror && _type == RENDERWALL_M1S && gl_mirrors && !(di->Level->ib_compatflags & BCOMPATF_NOMIRRORS)) { PutPortal(di, PORTALTYPE_MIRROR, -1); } diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 635e27d70..d80950583 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -320,3 +320,8 @@ F50C91A05E1A1E646690517641F0D1DD // daedalus.wad map19 { shorttex } + +65C155579BEA34642A7B83DF5481B29B // Conf256.pk3 CONF55 +{ + nomirrors +} From 139d1a7eb6d42fb0dc190d254d2939962374b585 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 14 Sep 2023 20:34:28 +0200 Subject: [PATCH 107/223] - use wrapping fixed point conversion for SW rendering coordinates. --- src/rendering/swrenderer/line/r_wallsetup.cpp | 4 ++-- src/rendering/swrenderer/plane/r_skyplane.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rendering/swrenderer/line/r_wallsetup.cpp b/src/rendering/swrenderer/line/r_wallsetup.cpp index 2ecf3cab9..c2359325d 100644 --- a/src/rendering/swrenderer/line/r_wallsetup.cpp +++ b/src/rendering/swrenderer/line/r_wallsetup.cpp @@ -501,7 +501,7 @@ namespace swrenderer double rowoffset = lineseg->sidedef->GetTextureYOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureYOffset(side_t::mid); double planez = rover->model->GetPlaneTexZ(sector_t::ceiling); - fixed_t xoffset = FLOAT2FIXED(lineseg->sidedef->GetTextureXOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureXOffset(side_t::mid)); + fixed_t xoffset = xs_Fix<16>::ToFix(lineseg->sidedef->GetTextureXOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureXOffset(side_t::mid)); if (rowoffset < 0) { rowoffset += pic->GetHeight(); @@ -633,7 +633,7 @@ namespace swrenderer fixed_t ProjectedWallTexcoords::GetXOffset(seg_t* lineseg, FSoftwareTexture* tex, side_t::ETexpart texpart) { - fixed_t TextureOffsetU = FLOAT2FIXED(lineseg->sidedef->GetTextureXOffset(texpart)); + fixed_t TextureOffsetU = xs_Fix<16>::ToFix(lineseg->sidedef->GetTextureXOffset(texpart)); double xscale = GetXScale(lineseg->sidedef, tex, texpart); fixed_t xoffset; diff --git a/src/rendering/swrenderer/plane/r_skyplane.cpp b/src/rendering/swrenderer/plane/r_skyplane.cpp index 35a04cf4c..9020b76a7 100644 --- a/src/rendering/swrenderer/plane/r_skyplane.cpp +++ b/src/rendering/swrenderer/plane/r_skyplane.cpp @@ -186,7 +186,7 @@ namespace swrenderer // to allow sky rotation as well as careful positioning. // However, the offset is scaled very small, so that it // allows a long-period of sky rotation. - skyangle += FLOAT2FIXED(s->GetTextureXOffset(pos)); + skyangle += xs_Fix<16>::ToFix(s->GetTextureXOffset(pos)); // Vertical offset allows careful sky positioning. skymid = s->GetTextureYOffset(pos) - 28.0; From 4fd5f00c4b21d4b15e13ab6731f02c50da1e6c45 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 14 Sep 2023 21:45:38 +0200 Subject: [PATCH 108/223] - made all FileReader implementations 64 bit capable. --- src/common/filesystem/include/fs_files.h | 26 ++--- src/common/filesystem/source/files.cpp | 94 ++++++++++--------- .../filesystem/source/files_decompress.cpp | 76 +++++++++------ src/common/filesystem/source/files_internal.h | 12 +-- src/common/utility/filereadermusicinterface.h | 6 +- 5 files changed, 117 insertions(+), 97 deletions(-) diff --git a/src/common/filesystem/include/fs_files.h b/src/common/filesystem/include/fs_files.h index 878122e82..06160d258 100644 --- a/src/common/filesystem/include/fs_files.h +++ b/src/common/filesystem/include/fs_files.h @@ -92,14 +92,14 @@ class FileReader; class FileReaderInterface { public: - long Length = -1; + ptrdiff_t Length = -1; virtual ~FileReaderInterface() {} - virtual long Tell () const = 0; - virtual long Seek (long offset, int origin) = 0; - virtual long Read (void *buffer, long len) = 0; - virtual char *Gets(char *strbuf, int len) = 0; + virtual ptrdiff_t Tell () const = 0; + virtual ptrdiff_t Seek (ptrdiff_t offset, int origin) = 0; + virtual ptrdiff_t Read (void *buffer, ptrdiff_t len) = 0; + virtual char *Gets(char *strbuf, ptrdiff_t len) = 0; virtual const char *GetBuffer() const { return nullptr; } - long GetLength () const { return Length; } + ptrdiff_t GetLength () const { return Length; } }; struct FResourceLump; @@ -184,12 +184,12 @@ public: Size Seek(Size offset, ESeek origin) { - return mReader->Seek((long)offset, origin); + return mReader->Seek(offset, origin); } Size Read(void *buffer, Size len) const { - return mReader->Read(buffer, (long)len); + return mReader->Read(buffer, len); } std::vector Read(size_t len) @@ -197,7 +197,7 @@ public: std::vector buffer(len); if (len > 0) { - Size length = mReader->Read(&buffer[0], (long)len); + Size length = mReader->Read(&buffer[0], len); buffer.resize((size_t)length); } return buffer; @@ -214,7 +214,7 @@ public: std::vector buffer(len + padding); if (len > 0) { - Size length = mReader->Read(&buffer[0], (long)len); + Size length = mReader->Read(&buffer[0], len); if (length < len) buffer.clear(); else memset(buffer.data() + len, 0, padding); } @@ -224,7 +224,7 @@ public: char *Gets(char *strbuf, Size len) { - return mReader->Gets(strbuf, (int)len); + return mReader->Gets(strbuf, len); } const char *GetBuffer() @@ -331,8 +331,8 @@ public: static FileWriter *Open(const char *filename); virtual size_t Write(const void *buffer, size_t len); - virtual long Tell(); - virtual long Seek(long offset, int mode); + virtual ptrdiff_t Tell(); + virtual ptrdiff_t Seek(ptrdiff_t offset, int mode); size_t Printf(const char *fmt, ...); virtual void Close() diff --git a/src/common/filesystem/source/files.cpp b/src/common/filesystem/source/files.cpp index 8a0b5ed27..a17f7c1b8 100644 --- a/src/common/filesystem/source/files.cpp +++ b/src/common/filesystem/source/files.cpp @@ -53,6 +53,10 @@ FILE *myfopen(const char *filename, const char *flags) #endif } +#ifdef _WIN32 +#define fseek _fseeki64 +#define ftell _ftelli64 +#endif //========================================================================== // @@ -65,8 +69,8 @@ FILE *myfopen(const char *filename, const char *flags) class StdFileReader : public FileReaderInterface { FILE *File = nullptr; - long StartPos = 0; - long FilePos = 0; + ptrdiff_t StartPos = 0; + ptrdiff_t FilePos = 0; public: StdFileReader() @@ -81,7 +85,7 @@ public: File = nullptr; } - bool Open(const char *filename, long startpos = 0, long len = -1) + bool Open(const char *filename, ptrdiff_t startpos = 0, ptrdiff_t len = -1) { File = myfopen(filename, "rb"); if (File == nullptr) return false; @@ -93,12 +97,12 @@ public: return true; } - long Tell() const override + ptrdiff_t Tell() const override { return FilePos - StartPos; } - long Seek(long offset, int origin) override + ptrdiff_t Seek(ptrdiff_t offset, int origin) override { if (origin == SEEK_SET) { @@ -122,7 +126,7 @@ public: return -1; } - long Read(void *buffer, long len) override + ptrdiff_t Read(void *buffer, ptrdiff_t len) override { assert(len >= 0); if (len <= 0) return 0; @@ -130,16 +134,16 @@ public: { len = Length - FilePos + StartPos; } - len = (long)fread(buffer, 1, len, File); + len = fread(buffer, 1, len, File); FilePos += len; return len; } - char *Gets(char *strbuf, int len) override + char *Gets(char *strbuf, ptrdiff_t len) override { - if (len <= 0 || FilePos >= StartPos + Length) return NULL; + if (len <= 0 || len > 0x7fffffff || FilePos >= StartPos + Length) return nullptr; char *p = fgets(strbuf, len, File); - if (p != NULL) + if (p != nullptr) { int old = FilePos; FilePos = ftell(File); @@ -152,9 +156,9 @@ public: } private: - long CalcFileLen() const + ptrdiff_t CalcFileLen() const { - long endpos; + ptrdiff_t endpos; fseek(File, 0, SEEK_END); endpos = ftell(File); @@ -174,11 +178,11 @@ private: class FileReaderRedirect : public FileReaderInterface { FileReader *mReader = nullptr; - long StartPos = 0; - long FilePos = 0; + ptrdiff_t StartPos = 0; + ptrdiff_t FilePos = 0; public: - FileReaderRedirect(FileReader &parent, long start, long length) + FileReaderRedirect(FileReader &parent, ptrdiff_t start, ptrdiff_t length) { mReader = &parent; FilePos = start; @@ -187,12 +191,12 @@ public: Seek(0, SEEK_SET); } - virtual long Tell() const override + virtual ptrdiff_t Tell() const override { return FilePos - StartPos; } - virtual long Seek(long offset, int origin) override + virtual ptrdiff_t Seek(ptrdiff_t offset, int origin) override { switch (origin) { @@ -205,7 +209,7 @@ public: break; case SEEK_CUR: - offset += (long)mReader->Tell(); + offset += mReader->Tell(); break; } if (offset < StartPos || offset > StartPos + Length) return -1; // out of scope @@ -217,7 +221,7 @@ public: return -1; } - virtual long Read(void *buffer, long len) override + virtual ptrdiff_t Read(void *buffer, ptrdiff_t len) override { assert(len >= 0); if (len <= 0) return 0; @@ -225,19 +229,19 @@ public: { len = Length - FilePos + StartPos; } - len = (long)mReader->Read(buffer, len); + len = mReader->Read(buffer, len); FilePos += len; return len; } - virtual char *Gets(char *strbuf, int len) override + virtual char *Gets(char *strbuf, ptrdiff_t len) override { - if (len <= 0 || FilePos >= StartPos + Length) return NULL; + if (len <= 0 || FilePos >= StartPos + Length) return nullptr; char *p = mReader->Gets(strbuf, len); - if (p != NULL) + if (p != nullptr) { int old = FilePos; - FilePos = (long)mReader->Tell(); + FilePos = mReader->Tell(); if (FilePos - StartPos > Length) { strbuf[Length - old + StartPos] = 0; @@ -256,12 +260,12 @@ public: // //========================================================================== -long MemoryReader::Tell() const +ptrdiff_t MemoryReader::Tell() const { return FilePos; } -long MemoryReader::Seek(long offset, int origin) +ptrdiff_t MemoryReader::Seek(ptrdiff_t offset, int origin) { switch (origin) { @@ -275,11 +279,11 @@ long MemoryReader::Seek(long offset, int origin) } if (offset < 0 || offset > Length) return -1; - FilePos = std::clamp(offset, 0, Length); + FilePos = std::clamp(offset, 0, Length); return 0; } -long MemoryReader::Read(void *buffer, long len) +ptrdiff_t MemoryReader::Read(void *buffer, ptrdiff_t len) { if (len>Length - FilePos) len = Length - FilePos; if (len<0) len = 0; @@ -288,10 +292,10 @@ long MemoryReader::Read(void *buffer, long len) return len; } -char *MemoryReader::Gets(char *strbuf, int len) +char *MemoryReader::Gets(char *strbuf, ptrdiff_t len) { if (len>Length - FilePos) len = Length - FilePos; - if (len <= 0) return NULL; + if (len <= 0) return nullptr; char *p = strbuf; while (len > 1) @@ -313,7 +317,7 @@ char *MemoryReader::Gets(char *strbuf, int len) } FilePos++; } - if (p == strbuf) return NULL; + if (p == strbuf) return nullptr; *p++ = 0; return strbuf; } @@ -331,7 +335,7 @@ class MemoryArrayReader : public MemoryReader std::vector buf; public: - MemoryArrayReader(const char *buffer, long length) + MemoryArrayReader(const char *buffer, ptrdiff_t length) { if (length > 0) { @@ -347,7 +351,7 @@ public: { bufptr = (const char*)buf.data(); FilePos = 0; - Length = (long)buf.size(); + Length = buf.size(); } }; @@ -364,7 +368,7 @@ public: bool FileReader::OpenFile(const char *filename, FileReader::Size start, FileReader::Size length) { auto reader = new StdFileReader; - if (!reader->Open(filename, (long)start, (long)length)) + if (!reader->Open(filename, start, length)) { delete reader; return false; @@ -376,7 +380,7 @@ bool FileReader::OpenFile(const char *filename, FileReader::Size start, FileRead bool FileReader::OpenFilePart(FileReader &parent, FileReader::Size start, FileReader::Size length) { - auto reader = new FileReaderRedirect(parent, (long)start, (long)length); + auto reader = new FileReaderRedirect(parent, start, length); Close(); mReader = reader; return true; @@ -385,14 +389,14 @@ bool FileReader::OpenFilePart(FileReader &parent, FileReader::Size start, FileRe bool FileReader::OpenMemory(const void *mem, FileReader::Size length) { Close(); - mReader = new MemoryReader((const char *)mem, (long)length); + mReader = new MemoryReader((const char *)mem, length); return true; } bool FileReader::OpenMemoryArray(const void *mem, FileReader::Size length) { Close(); - mReader = new MemoryArrayReader((const char *)mem, (long)length); + mReader = new MemoryArrayReader((const char *)mem, length); return true; } @@ -424,7 +428,7 @@ bool FileReader::OpenMemoryArray(std::function&)> gett bool FileWriter::OpenDirect(const char *filename) { File = myfopen(filename, "wb"); - return (File != NULL); + return (File != nullptr); } FileWriter *FileWriter::Open(const char *filename) @@ -435,12 +439,12 @@ FileWriter *FileWriter::Open(const char *filename) return fwrit; } delete fwrit; - return NULL; + return nullptr; } size_t FileWriter::Write(const void *buffer, size_t len) { - if (File != NULL) + if (File != nullptr) { return fwrite(buffer, 1, len, File); } @@ -450,9 +454,9 @@ size_t FileWriter::Write(const void *buffer, size_t len) } } -long FileWriter::Tell() +ptrdiff_t FileWriter::Tell() { - if (File != NULL) + if (File != nullptr) { return ftell(File); } @@ -462,9 +466,9 @@ long FileWriter::Tell() } } -long FileWriter::Seek(long offset, int mode) +ptrdiff_t FileWriter::Seek(ptrdiff_t offset, int mode) { - if (File != NULL) + if (File != nullptr) { return fseek(File, offset, mode); } @@ -485,7 +489,7 @@ size_t FileWriter::Printf(const char *fmt, ...) va_start(arglist, fmt); vsnprintf(&buf.front(), n + 1, fmt, arglist); va_end(arglist); - return Write(buf.c_str(), strlen(buf.c_str())); // Make sure we write no null bytes. + return Write(buf.c_str(), strlen(buf.c_str())); // Make sure we write no nullptr bytes. } size_t BufferWriter::Write(const void *buffer, size_t len) diff --git a/src/common/filesystem/source/files_decompress.cpp b/src/common/filesystem/source/files_decompress.cpp index 86529716a..0be5abdaa 100644 --- a/src/common/filesystem/source/files_decompress.cpp +++ b/src/common/filesystem/source/files_decompress.cpp @@ -53,9 +53,9 @@ class DecompressorBase : public FileReaderInterface public: // These do not work but need to be defined to satisfy the FileReaderInterface. // They will just error out when called. - long Tell() const override; - long Seek(long offset, int origin) override; - char* Gets(char* strbuf, int len) override; + ptrdiff_t Tell() const override; + ptrdiff_t Seek(ptrdiff_t offset, int origin) override; + char* Gets(char* strbuf, ptrdiff_t len) override; void DecompressionError(const char* error, ...) const; void SetOwnsReader(); void EnableExceptions(bool on) { exceptions = on; } @@ -86,17 +86,17 @@ void DecompressorBase::DecompressionError(const char *error, ...) const } } -long DecompressorBase::Tell () const +ptrdiff_t DecompressorBase::Tell () const { DecompressionError("Cannot get position of decompressor stream"); return 0; } -long DecompressorBase::Seek (long offset, int origin) +ptrdiff_t DecompressorBase::Seek (ptrdiff_t offset, int origin) { DecompressionError("Cannot seek in decompressor stream"); return 0; } -char *DecompressorBase::Gets(char *strbuf, int len) +char *DecompressorBase::Gets(char *strbuf, ptrdiff_t len) { DecompressionError("Cannot use Gets on decompressor stream"); return nullptr; @@ -171,7 +171,7 @@ public: inflateEnd (&Stream); } - long Read (void *buffer, long len) override + ptrdiff_t Read (void *buffer, ptrdiff_t len) override { int err; @@ -180,18 +180,25 @@ public: DecompressionError("File not open"); return 0; } + if (len == 0) return 0; - Stream.next_out = (Bytef *)buffer; - Stream.avail_out = len; - - do + while (len > 0) { - err = inflate (&Stream, Z_SYNC_FLUSH); - if (Stream.avail_in == 0 && !SawEOF) + Stream.next_out = (Bytef*)buffer; + auto rlen = std::min(len, 0x40000000); + Stream.avail_out = rlen; + buffer = Stream.next_out + rlen; + len -= rlen; + + do { - FillBuffer (); - } - } while (err == Z_OK && Stream.avail_out != 0); + err = inflate(&Stream, Z_SYNC_FLUSH); + if (Stream.avail_in == 0 && !SawEOF) + { + FillBuffer(); + } + } while (err == Z_OK && Stream.avail_out != 0); + } if (err != Z_OK && err != Z_STREAM_END) { @@ -278,28 +285,36 @@ public: BZ2_bzDecompressEnd (&Stream); } - long Read (void *buffer, long len) override + ptrdiff_t Read (void *buffer, ptrdiff_t len) override { if (File == nullptr) { DecompressionError("File not open"); return 0; } + if (len == 0) return 0; - int err; + int err = BZ_OK; stupidGlobal = this; - Stream.next_out = (char *)buffer; - Stream.avail_out = len; - do + while (len > 0) { - err = BZ2_bzDecompress(&Stream); - if (Stream.avail_in == 0 && !SawEOF) + Stream.next_out = (char*)buffer; + auto rlen = std::min(len, 0x40000000); + Stream.avail_out = rlen; + buffer = Stream.next_out + rlen; + len -= rlen; + + do { - FillBuffer (); - } - } while (err == BZ_OK && Stream.avail_out != 0); + err = BZ2_bzDecompress(&Stream); + if (Stream.avail_in == 0 && !SawEOF) + { + FillBuffer(); + } + } while (err == BZ_OK && Stream.avail_out != 0); + } if (err != BZ_OK && err != BZ_STREAM_END) { @@ -419,7 +434,7 @@ public: LzmaDec_Free(&Stream, &g_Alloc); } - long Read (void *buffer, long len) override + ptrdiff_t Read (void *buffer, ptrdiff_t len) override { if (File == nullptr) { @@ -639,11 +654,12 @@ public: { } - long Read(void *buffer, long len) override + ptrdiff_t Read(void *buffer, ptrdiff_t len) override { + if (len > 0xffffffff) len = 0xffffffff; // this format cannot be larger than 4GB. uint8_t *Out = (uint8_t*)buffer; - long AvailOut = len; + unsigned AvailOut = len; do { @@ -754,7 +770,7 @@ bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, b dec->SetOwnsReader(); } - dec->Length = (long)length; + dec->Length = length; if (!seekable) { Close(); diff --git a/src/common/filesystem/source/files_internal.h b/src/common/filesystem/source/files_internal.h index 34e73a070..3317796ac 100644 --- a/src/common/filesystem/source/files_internal.h +++ b/src/common/filesystem/source/files_internal.h @@ -8,23 +8,23 @@ class MemoryReader : public FileReaderInterface { protected: const char * bufptr = nullptr; - long FilePos = 0; + ptrdiff_t FilePos = 0; MemoryReader() {} public: - MemoryReader(const char *buffer, long length) + MemoryReader(const char *buffer, ptrdiff_t length) { bufptr = buffer; Length = length; FilePos = 0; } - long Tell() const override; - long Seek(long offset, int origin) override; - long Read(void *buffer, long len) override; - char *Gets(char *strbuf, int len) override; + ptrdiff_t Tell() const override; + ptrdiff_t Seek(ptrdiff_t offset, int origin) override; + ptrdiff_t Read(void *buffer, ptrdiff_t len) override; + char *Gets(char *strbuf, ptrdiff_t len) override; virtual const char *GetBuffer() const override { return bufptr; } }; diff --git a/src/common/utility/filereadermusicinterface.h b/src/common/utility/filereadermusicinterface.h index 633599b63..042804b53 100644 --- a/src/common/utility/filereadermusicinterface.h +++ b/src/common/utility/filereadermusicinterface.h @@ -11,9 +11,9 @@ inline ZMusicCustomReader *GetMusicReader(FileReader& fr) zcr->handle = fr.GetInterface(); zcr->gets = [](ZMusicCustomReader* zr, char* buff, int n) { return reinterpret_cast(zr->handle)->Gets(buff, n); }; - zcr->read = [](ZMusicCustomReader* zr, void* buff, int32_t size) { return reinterpret_cast(zr->handle)->Read(buff, (long)size); }; - zcr->seek = [](ZMusicCustomReader* zr, long offset, int whence) { return reinterpret_cast(zr->handle)->Seek(offset, whence); }; - zcr->tell = [](ZMusicCustomReader* zr) { return reinterpret_cast(zr->handle)->Tell(); }; + zcr->read = [](ZMusicCustomReader* zr, void* buff, int32_t size) -> long { return reinterpret_cast(zr->handle)->Read(buff, size); }; + zcr->seek = [](ZMusicCustomReader* zr, long offset, int whence) -> long { return reinterpret_cast(zr->handle)->Seek(offset, whence); }; + zcr->tell = [](ZMusicCustomReader* zr) -> long { return reinterpret_cast(zr->handle)->Tell(); }; zcr->close = [](ZMusicCustomReader* zr) { delete reinterpret_cast(zr->handle); From 727c57583bc19f525643c0f31be9e7252695b6d4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 14 Sep 2023 22:15:26 +0200 Subject: [PATCH 109/223] - add unexplored secret color for overlay automap to the menu --- wadsrc/static/menudef.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index c706da24a..e0c8d8c81 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1462,6 +1462,7 @@ OptionMenu MapColorMenuOverlay protected ColorPicker "$MAPCOLORMNU_INTRALEVELCOLOR", "am_ovtelecolor" ColorPicker "$MAPCOLORMNU_INTERLEVELCOLOR", "am_ovinterlevelcolor" ColorPicker "$MAPCOLORMNU_SECRETSECTORCOLOR", "am_ovsecretsectorcolor" + ColorPicker "$MAPCOLORMNU_UNEXPLOREDSECRETCOLOR", "am_ovunexploredsecretcolor" ColorPicker "$MAPCOLORMNU_SPECIALWALLCOLOR", "am_ovspecialwallcolor" ColorPicker "$MAPCOLORMNU_PORTAL", "am_ovportalcolor" } From 79ef78e2b5b049914e94a4d5527468413ae69706 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 14 Sep 2023 22:32:20 +0200 Subject: [PATCH 110/223] - fix ammo consumption of powered up Phoenix Rod. --- wadsrc/static/zscript/actors/heretic/weaponphoenix.zs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/zscript/actors/heretic/weaponphoenix.zs b/wadsrc/static/zscript/actors/heretic/weaponphoenix.zs index 3300c43d3..884db86f8 100644 --- a/wadsrc/static/zscript/actors/heretic/weaponphoenix.zs +++ b/wadsrc/static/zscript/actors/heretic/weaponphoenix.zs @@ -93,7 +93,7 @@ class PhoenixRodPowered : PhoenixRod override void EndPowerup () { - DepleteAmmo (bAltFire); + if (FlameCount > 0) DepleteAmmo (bAltFire); Owner.player.refire = 0; Owner.A_StopSound (CHAN_WEAPON); Owner.player.ReadyWeapon = SisterWeapon; @@ -178,9 +178,10 @@ class PhoenixRodPowered : PhoenixRod return; } A_StopSound (CHAN_WEAPON); - Weapon weapon = player.ReadyWeapon; + PhoenixRodPowered weapon = PhoenixRodPowered(player.ReadyWeapon); if (weapon != null) { + weapon.FlameCount = 0; weapon.DepleteAmmo (weapon.bAltFire); } } From 04815f9db48d090fd5ff8afe52c20cf4348571e5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 14 Sep 2023 23:08:59 +0200 Subject: [PATCH 111/223] - let Dehacked set the implicit missile flags. --- src/gamedata/d_dehacked.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 09a6dc310..1a67c16ab 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -1622,6 +1622,11 @@ static int PatchThing (int thingy) value[0] &= ~MF_TRANSLUCENT; // clean the slot vchanged[2] = true; value[2] |= 2; // let the TRANSLUCxx code below handle it } + if (value[0] & MF_MISSILE) + { + // all missiles in Doom are NOTELEPORT, the other flags are for consistency. + info->flags2 |= MF2_IMPACT | MF2_PCROSS | MF2_NOTELEPORT; + } if ((info->flags & MF_MISSILE) && (info->flags2 & MF2_NOTELEPORT) && !(value[0] & MF_MISSILE)) { @@ -4031,12 +4036,14 @@ void ClearBounces(AActor* info) void SetMissile(AActor* info) { info->flags |= MF_MISSILE; + info->flags2 |= MF2_NOTELEPORT | MF2_PCROSS | MF2_IMPACT; if (info->BounceFlags & BOUNCE_DEH) info->BounceFlags = BOUNCE_Classic | BOUNCE_DEH; } void ClearMissile(AActor* info) { info->flags &= ~MF_MISSILE; + info->flags2 &= ~(MF2_NOTELEPORT | MF2_PCROSS | MF2_IMPACT); if (info->BounceFlags & BOUNCE_DEH) info->BounceFlags = BOUNCE_Grenade | BOUNCE_DEH; } From 44d134298ac493410bd84f93516eef312cf4587c Mon Sep 17 00:00:00 2001 From: Gutawer Date: Wed, 13 Sep 2023 15:23:41 +0100 Subject: [PATCH 112/223] - add support for not localizing some text functions, and modify menu text fields to use this --- src/common/2d/v_draw.cpp | 11 +++++++--- src/common/2d/v_draw.h | 4 +++- src/common/2d/v_drawtext.cpp | 18 +++++++++------- src/common/scripting/interface/vmnatives.cpp | 21 +++++++++++-------- wadsrc/static/zscript/engine/base.zs | 7 ++++--- wadsrc/static/zscript/engine/ui/menu/menu.zs | 12 +++++------ .../zscript/engine/ui/menu/optionmenuitems.zs | 10 ++++----- 7 files changed, 48 insertions(+), 35 deletions(-) diff --git a/src/common/2d/v_draw.cpp b/src/common/2d/v_draw.cpp index 85ed31517..e7ea8d3ef 100644 --- a/src/common/2d/v_draw.cpp +++ b/src/common/2d/v_draw.cpp @@ -831,7 +831,7 @@ static inline FSpecialColormap * ListGetSpecialColormap(VMVa_List &tags) //========================================================================== template -bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, int type, PalEntry fill, double fillalpha) +bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, int type, PalEntry fill, double fillalpha, bool scriptDifferences) { INTBOOL boolval; int intval; @@ -886,6 +886,7 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double parms->scalex = parms->scaley = 1; parms->cellx = parms->celly = 0; parms->maxstrlen = INT_MAX; + parms->localize = scriptDifferences; parms->virtBottom = false; parms->srcx = 0.; parms->srcy = 0.; @@ -1323,6 +1324,10 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double parms->maxstrlen = ListGetInt(tags); break; + case DTA_Localize: + parms->localize = ListGetInt(tags); + break; + case DTA_CellX: parms->cellx = ListGetInt(tags); break; @@ -1434,8 +1439,8 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double } // explicitly instantiate both versions for v_text.cpp. -template bool ParseDrawTextureTags(F2DDrawer* drawer, FGameTexture *img, double x, double y, uint32_t tag, Va_List& tags, DrawParms *parms, int type, PalEntry fill, double fillalpha); -template bool ParseDrawTextureTags(F2DDrawer* drawer, FGameTexture *img, double x, double y, uint32_t tag, VMVa_List& tags, DrawParms *parms, int type, PalEntry fill, double fillalpha); +template bool ParseDrawTextureTags(F2DDrawer* drawer, FGameTexture *img, double x, double y, uint32_t tag, Va_List& tags, DrawParms *parms, int type, PalEntry fill, double fillalpha, bool scriptDifferences); +template bool ParseDrawTextureTags(F2DDrawer* drawer, FGameTexture *img, double x, double y, uint32_t tag, VMVa_List& tags, DrawParms *parms, int type, PalEntry fill, double fillalpha, bool scriptDifferences); //========================================================================== // diff --git a/src/common/2d/v_draw.h b/src/common/2d/v_draw.h index 686e5dc46..c2503a543 100644 --- a/src/common/2d/v_draw.h +++ b/src/common/2d/v_draw.h @@ -100,6 +100,7 @@ enum // For DrawText calls: DTA_TextLen, // stop after this many characters, even if \0 not hit + DTA_Localize, // localize text DTA_CellX, // horizontal size of character cell DTA_CellY, // vertical size of character cell @@ -194,6 +195,7 @@ struct DrawParms int monospace; int spacing; int maxstrlen; + bool localize; bool fortext; bool virtBottom; bool burn; @@ -266,7 +268,7 @@ enum }; template -bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture* img, double x, double y, uint32_t tag, T& tags, DrawParms* parms, int type, PalEntry fill = ~0u, double fillalpha = 0.0); +bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture* img, double x, double y, uint32_t tag, T& tags, DrawParms* parms, int type, PalEntry fill = ~0u, double fillalpha = 0.0, bool scriptDifferences = false); template void DrawTextCommon(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double y, const T* string, DrawParms& parms); diff --git a/src/common/2d/v_drawtext.cpp b/src/common/2d/v_drawtext.cpp index 2bdb64dca..ea760b4b6 100644 --- a/src/common/2d/v_drawtext.cpp +++ b/src/common/2d/v_drawtext.cpp @@ -380,6 +380,7 @@ void DrawText(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double { return; } + const char *txt = (parms.localize && string[0] == '$') ? GStrings(&string[1]) : string; DrawTextCommon(drawer, font, normalcolor, x, y, (const uint8_t*)string, parms); } @@ -399,24 +400,27 @@ void DrawText(F2DDrawer *drawer, FFont* font, int normalcolor, double x, double { return; } + // [Gutawer] right now nothing needs the char32_t version to have localisation support, and i don't know how to do it + assert(parms.localize == false); DrawTextCommon(drawer, font, normalcolor, x, y, string, parms); } -void DrawText(F2DDrawer *drawer, FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args) +void DrawText(F2DDrawer *drawer, FFont *font, int normalcolor, double x, double y, const FString& string, VMVa_List &args) { DrawParms parms; - if (font == NULL || string == NULL) + if (font == NULL) return; uint32_t tag = ListGetInt(args); - bool res = ParseDrawTextureTags(drawer, nullptr, 0, 0, tag, args, &parms, DrawTexture_Text); + bool res = ParseDrawTextureTags(drawer, nullptr, 0, 0, tag, args, &parms, DrawTexture_Text, ~0u, 0.0, true); if (!res) { return; } - DrawTextCommon(drawer, font, normalcolor, x, y, (const uint8_t*)string, parms); + const char *txt = (parms.localize && string[0] == '$') ? GStrings(&string[1]) : string.GetChars(); + DrawTextCommon(drawer, font, normalcolor, x, y, (uint8_t*)txt, parms); } DEFINE_ACTION_FUNCTION(_Screen, DrawText) @@ -432,8 +436,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawText) if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); VMVa_List args = { param + 5, 0, numparam - 6, va_reginfo + 5 }; - const char *txt = chr[0] == '$' ? GStrings(&chr[1]) : chr.GetChars(); - DrawText(twod, font, cr, x, y, txt, args); + DrawText(twod, font, cr, x, y, chr, args); return 0; } @@ -450,8 +453,7 @@ DEFINE_ACTION_FUNCTION(FCanvas, DrawText) PARAM_VA_POINTER(va_reginfo) // Get the hidden type information array VMVa_List args = { param + 6, 0, numparam - 7, va_reginfo + 6 }; - const char *txt = chr[0] == '$' ? GStrings(&chr[1]) : chr.GetChars(); - DrawText(&self->Drawer, font, cr, x, y, txt, args); + DrawText(&self->Drawer, font, cr, x, y, chr, args); self->Tex->NeedUpdate(); return 0; } diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index cd309f9cc..16bf394db 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -667,9 +667,9 @@ DEFINE_ACTION_FUNCTION_NATIVE(FFont, GetBottomAlignOffset, GetBottomAlignOffset) ACTION_RETURN_FLOAT(GetBottomAlignOffset(self, code)); } -static int StringWidth(FFont *font, const FString &str) +static int StringWidth(FFont *font, const FString &str, bool localize) { - const char *txt = str[0] == '$' ? GStrings(&str[1]) : str.GetChars(); + const char *txt = (localize && str[0] == '$') ? GStrings(&str[1]) : str.GetChars(); return font->StringWidth(txt); } @@ -677,12 +677,13 @@ DEFINE_ACTION_FUNCTION_NATIVE(FFont, StringWidth, StringWidth) { PARAM_SELF_STRUCT_PROLOGUE(FFont); PARAM_STRING(str); - ACTION_RETURN_INT(StringWidth(self, str)); + PARAM_BOOL(localize); + ACTION_RETURN_INT(StringWidth(self, str, localize)); } -static int GetMaxAscender(FFont* font, const FString& str) +static int GetMaxAscender(FFont* font, const FString& str, bool localize) { - const char* txt = str[0] == '$' ? GStrings(&str[1]) : str.GetChars(); + const char* txt = (localize && str[0] == '$') ? GStrings(&str[1]) : str.GetChars(); return font->GetMaxAscender(txt); } @@ -690,12 +691,13 @@ DEFINE_ACTION_FUNCTION_NATIVE(FFont, GetMaxAscender, GetMaxAscender) { PARAM_SELF_STRUCT_PROLOGUE(FFont); PARAM_STRING(str); - ACTION_RETURN_INT(GetMaxAscender(self, str)); + PARAM_BOOL(localize); + ACTION_RETURN_INT(GetMaxAscender(self, str, localize)); } -static int CanPrint(FFont *font, const FString &str) +static int CanPrint(FFont *font, const FString &str, bool localize) { - const char *txt = str[0] == '$' ? GStrings(&str[1]) : str.GetChars(); + const char *txt = (localize && str[0] == '$') ? GStrings(&str[1]) : str.GetChars(); return font->CanPrint(txt); } @@ -703,7 +705,8 @@ DEFINE_ACTION_FUNCTION_NATIVE(FFont, CanPrint, CanPrint) { PARAM_SELF_STRUCT_PROLOGUE(FFont); PARAM_STRING(str); - ACTION_RETURN_INT(CanPrint(self, str)); + PARAM_BOOL(localize); + ACTION_RETURN_INT(CanPrint(self, str, localize)); } static int FindFontColor(int name) diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index 7d02a9adf..b313bc1e0 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -430,6 +430,7 @@ enum DrawTextureTags // For DrawText calls only: DTA_TextLen, // stop after this many characters, even if \0 not hit + DTA_Localize, // localize drawn string DTA_CellX, // horizontal size of character cell DTA_CellY, // vertical size of character cell @@ -641,9 +642,9 @@ struct Font native // native Font(const Name name); native int GetCharWidth(int code); - native int StringWidth(String code); - native int GetMaxAscender(String code); - native bool CanPrint(String code); + native int StringWidth(String code, bool localize = true); + native int GetMaxAscender(String code, bool localize = true); + native bool CanPrint(String code, bool localize = true); native int GetHeight(); native int GetDisplacement(); native String GetCursor(); diff --git a/wadsrc/static/zscript/engine/ui/menu/menu.zs b/wadsrc/static/zscript/engine/ui/menu/menu.zs index e7a9550f4..154eee82a 100644 --- a/wadsrc/static/zscript/engine/ui/menu/menu.zs +++ b/wadsrc/static/zscript/engine/ui/menu/menu.zs @@ -349,16 +349,16 @@ class Menu : Object native ui version("2.4") return OptionFont().GetHeight(); } - static int OptionWidth(String s) + static int OptionWidth(String s, bool localize = true) { - return OptionFont().StringWidth(s); + return OptionFont().StringWidth(s, localize); } - static void DrawOptionText(int x, int y, int color, String text, bool grayed = false) + static void DrawOptionText(int x, int y, int color, String text, bool grayed = false, bool localize = true) { - String label = Stringtable.Localize(text); + String label = localize ? Stringtable.Localize(text) : text; int overlay = grayed? Color(96,48,0,0) : 0; - screen.DrawText (OptionFont(), color, x, y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay); + screen.DrawText (OptionFont(), color, x, y, text, DTA_CleanNoMove_1, true, DTA_ColorOverlay, overlay, DTA_Localize, localize); } @@ -380,4 +380,4 @@ class GenericMenu : Menu { Super.Init(parent); } -} \ No newline at end of file +} diff --git a/wadsrc/static/zscript/engine/ui/menu/optionmenuitems.zs b/wadsrc/static/zscript/engine/ui/menu/optionmenuitems.zs index 4733d5b3b..53ef2d8e3 100644 --- a/wadsrc/static/zscript/engine/ui/menu/optionmenuitems.zs +++ b/wadsrc/static/zscript/engine/ui/menu/optionmenuitems.zs @@ -61,9 +61,9 @@ class OptionMenuItem : MenuItemBase return x; } - protected void drawValue(int indent, int y, int color, String text, bool grayed = false) + protected void drawValue(int indent, int y, int color, String text, bool grayed = false, bool localize = true) { - Menu.DrawOptionText(indent + CursorSpace(), y, color, text, grayed); + Menu.DrawOptionText(indent + CursorSpace(), y, color, text, grayed, localize); } @@ -999,7 +999,7 @@ class OptionMenuFieldBase : OptionMenuItem { bool grayed = mGrayCheck != null && !mGrayCheck.GetInt(); drawLabel(indent, y, selected ? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, grayed); - drawValue(indent, y, OptionMenuSettings.mFontColorValue, Represent(), grayed); + drawValue(indent, y, OptionMenuSettings.mFontColorValue, Represent(), grayed, false); return indent; } @@ -1068,7 +1068,7 @@ class OptionMenuItemTextField : OptionMenuFieldBase { // reposition the text so that the cursor is visible when in entering mode. String text = Represent(); - int tlen = Menu.OptionWidth(text) * CleanXfac_1; + int tlen = Menu.OptionWidth(text, false) * CleanXfac_1; int newindent = screen.GetWidth() - tlen - CursorSpace(); if (newindent < indent) indent = newindent; } @@ -1295,4 +1295,4 @@ class OptionMenuItemFlagOption : OptionMenuItemOption } } } -} \ No newline at end of file +} From 23b489960e7c71811d6e2da854d0e7389a41b79f Mon Sep 17 00:00:00 2001 From: Gutawer Date: Thu, 14 Sep 2023 18:31:53 +0100 Subject: [PATCH 113/223] - put DTA_Localize at the end of the enum for backwards compat with integer usage --- src/common/2d/v_draw.h | 2 +- wadsrc/static/zscript/engine/base.zs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/2d/v_draw.h b/src/common/2d/v_draw.h index c2503a543..97668d97c 100644 --- a/src/common/2d/v_draw.h +++ b/src/common/2d/v_draw.h @@ -100,7 +100,6 @@ enum // For DrawText calls: DTA_TextLen, // stop after this many characters, even if \0 not hit - DTA_Localize, // localize text DTA_CellX, // horizontal size of character cell DTA_CellY, // vertical size of character cell @@ -133,6 +132,7 @@ enum DTA_Indexed, // Use an indexed texture combined with the given translation. DTA_CleanTop, // Like DTA_Clean but aligns to the top of the screen instead of the center. DTA_NoOffset, // Ignore 2D drawer's offset. + DTA_Localize, // localize drawn string, for DrawText only }; diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index b313bc1e0..dd9813ae6 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -430,7 +430,6 @@ enum DrawTextureTags // For DrawText calls only: DTA_TextLen, // stop after this many characters, even if \0 not hit - DTA_Localize, // localize drawn string DTA_CellX, // horizontal size of character cell DTA_CellY, // vertical size of character cell @@ -463,6 +462,7 @@ enum DrawTextureTags DTA_Indexed, // Use an indexed texture combined with the given translation. DTA_CleanTop, // Like DTA_Clean but aligns to the top of the screen instead of the center. DTA_NoOffset, // Ignore 2D drawer's offset. + DTA_Localize, // localize drawn string, for DrawText only }; From 15521e5181145e75a336e8b91168240d789ff48d Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sun, 28 May 2023 11:26:57 -0400 Subject: [PATCH 114/223] Fix a very rare crash with complex Polyobjects If all of the worst stars align when compiling Polyobject BSP and splitting a seg into two sets: - The very first seg in the current set fails all of the metrics for determining which side of a split it is on, and doesn't know which side it should go to. Since there are 0 are in front, it goes to front by default. - Every other seg in the same set don't fail their metrics, and they all decide they are meant to go to the front side. - Oops! Now there's nothing in the back side! I've fixed this by collecting all of the undecided segs in a split, and setting the new side after the other segs. Doing it in the normal loop means there's a non-zero chance the crash prevention will fail depending on how the segs are in memory. This can technically happen with even the most simplistic Polyobjects, but it becomes more common the more complex it is (add tons of lines, move and rotate it at the same time, so on). Quite an annoying crash since it doesn't always replicate consistently. --- src/utility/nodebuilder/nodebuild.cpp | 154 ++++++++++++++++---------- src/utility/nodebuilder/nodebuild.h | 5 +- 2 files changed, 100 insertions(+), 59 deletions(-) diff --git a/src/utility/nodebuilder/nodebuild.cpp b/src/utility/nodebuilder/nodebuild.cpp index 0efe38b0e..58b20f625 100644 --- a/src/utility/nodebuilder/nodebuild.cpp +++ b/src/utility/nodebuilder/nodebuild.cpp @@ -496,8 +496,9 @@ int FNodeBuilder::SelectSplitter (uint32_t set, node_t &node, uint32_t &splitseg } if (bestseg == UINT_MAX) - { // No lines split any others into two sets, so this is a convex region. - D(Printf (PRINT_LOG, "set %d, step %d, nosplit %d has no good splitter (%d)\n", set, step, nosplit, nosplitters)); + { + // No lines split any others into two sets, so this is a convex region. + D(Printf (PRINT_LOG, "set %d, step %d, nosplit %d has no good splitter (%d)\n", set, step, nosplit, nosplitters)); return nosplitters ? -1 : 0; } @@ -752,6 +753,54 @@ int FNodeBuilder::Heuristic (node_t &node, uint32_t set, bool honorNoSplit) return score; } +void FNodeBuilder::DoGLSegSplit (uint32_t set, node_t &node, uint32_t splitseg, uint32_t &outset0, uint32_t &outset1, int side, int sidev0, int sidev1, bool hack) +{ + FPrivSeg *seg = &Segs[set]; + + if (side >= 0 && GLNodes) + { + if (sidev0 == 0) + { + double dist1 = AddIntersection (node, seg->v1); + if (sidev1 == 0) + { + double dist2 = AddIntersection (node, seg->v2); + FSplitSharer share = { dist1, set, dist2 > dist1 }; + SplitSharers.Push (share); + } + } + else if (sidev1 == 0) + { + AddIntersection (node, seg->v2); + } + } + + if (hack && GLNodes) + { + uint32_t newback, newfront; + + newback = AddMiniseg (seg->v2, seg->v1, UINT_MAX, set, splitseg); + if (HackMate == UINT_MAX) + { + newfront = AddMiniseg (Segs[set].v1, Segs[set].v2, newback, set, splitseg); + Segs[newfront].next = outset0; + outset0 = newfront; + } + else + { + newfront = HackMate; + Segs[newfront].partner = newback; + Segs[newback].partner = newfront; + } + Segs[newback].frontsector = Segs[newback].backsector = + Segs[newfront].frontsector = Segs[newfront].backsector = + Segs[set].frontsector; + + Segs[newback].next = outset1; + outset1 = newback; + } +} + void FNodeBuilder::SplitSegs (uint32_t set, node_t &node, uint32_t splitseg, uint32_t &outset0, uint32_t &outset1, unsigned int &count0, unsigned int &count1) { unsigned int _count0 = 0; @@ -760,14 +809,15 @@ void FNodeBuilder::SplitSegs (uint32_t set, node_t &node, uint32_t splitseg, uin outset1 = UINT_MAX; Events.DeleteAll (); + UnsetSegs.Clear (); SplitSharers.Clear (); while (set != UINT_MAX) { + bool unset = false; bool hack; FPrivSeg *seg = &Segs[set]; int next = seg->next; - int sidev[2], side; if (HackSeg == set) @@ -844,73 +894,61 @@ void FNodeBuilder::SplitSegs (uint32_t set, node_t &node, uint32_t splitseg, uin } else { - // all that matters here is to prevent a crash so we must make sure that we do not end up with all segs being sorted to the same side - even if this may not be correct. - // But if we do not do that this code would not be able to move on. Just discarding the seg is also not an option because it won't guarantee that we achieve an actual split. - if (_count0 == 0) - { - side = 0; - seg->next = outset0; - outset0 = set; - _count0++; - } - else - { - side = 1; - seg->next = outset1; - outset1 = set; - _count1++; - } + // Sal May 28 2023 + // If all of the worst stars align: + // - The very first seg in the list doesn't know which side it should go to and makes it here. 0 are in front, so it goes to front. + // - Literally every other seg in the list all want to go to the front side from the other metrics + // - Oops! Now there's nothing in the back side! + // So we need to collect these now and do them later, otherwise the crash prevention fails. + UnsetSegs.Push(set); + unset = true; } break; } - if (side >= 0 && GLNodes) + if (unset == false) { - if (sidev[0] == 0) - { - double dist1 = AddIntersection (node, seg->v1); - if (sidev[1] == 0) - { - double dist2 = AddIntersection (node, seg->v2); - FSplitSharer share = { dist1, set, dist2 > dist1 }; - SplitSharers.Push (share); - } - } - else if (sidev[1] == 0) - { - AddIntersection (node, seg->v2); - } - } - if (hack && GLNodes) - { - uint32_t newback, newfront; - - newback = AddMiniseg (seg->v2, seg->v1, UINT_MAX, set, splitseg); - if (HackMate == UINT_MAX) - { - newfront = AddMiniseg (Segs[set].v1, Segs[set].v2, newback, set, splitseg); - Segs[newfront].next = outset0; - outset0 = newfront; - } - else - { - newfront = HackMate; - Segs[newfront].partner = newback; - Segs[newback].partner = newfront; - } - Segs[newback].frontsector = Segs[newback].backsector = - Segs[newfront].frontsector = Segs[newfront].backsector = - Segs[set].frontsector; - - Segs[newback].next = outset1; - outset1 = newback; + DoGLSegSplit (set, node, splitseg, outset0, outset1, side, sidev[0], sidev[1], hack); } set = next; } + + for (unsigned int i = 0; i < UnsetSegs.Size(); ++i) + { + uint32_t unsetID = UnsetSegs[i]; + FPrivSeg *seg = &Segs[unsetID]; + int sidev[2], side; + + side = ClassifyLine (node, &Vertices[seg->v1], &Vertices[seg->v2], sidev); + + // all that matters here is to prevent a crash so we must make sure that we do not end up with all segs being sorted to the same side - even if this may not be correct. + // But if we do not do that this code would not be able to move on. Just discarding the seg is also not an option because it won't guarantee that we achieve an actual split. + + if (_count0 == 0) + { + side = 0; + seg->next = outset0; + outset0 = unsetID; + _count0++; + } + else + { + side = 1; + seg->next = outset1; + outset1 = unsetID; + _count1++; + } + + DoGLSegSplit (unsetID, node, splitseg, outset0, outset1, side, sidev[0], sidev[1], false); + } + FixSplitSharers (node); if (GLNodes) { AddMinisegs (node, splitseg, outset0, outset1); } + + assert(_count0 != 0 && _count1 != 0); + count0 = _count0; count1 = _count1; } diff --git a/src/utility/nodebuilder/nodebuild.h b/src/utility/nodebuilder/nodebuild.h index f9f6b018a..1f5ef566c 100644 --- a/src/utility/nodebuilder/nodebuild.h +++ b/src/utility/nodebuilder/nodebuild.h @@ -269,6 +269,7 @@ private: TArray Colinear; // Loops with edges colinear to a splitter FEventTree Events; // Vertices intersected by the current splitter + TArray UnsetSegs; // Segs with no definitive side in current splitter TArray SplitSharers; // Segs colinear with the current splitter uint32_t HackSeg; // Seg to force to back of splitter @@ -294,7 +295,9 @@ private: void CreateSubsectorsForReal (); bool CheckSubsector (uint32_t set, node_t &node, uint32_t &splitseg); bool CheckSubsectorOverlappingSegs (uint32_t set, node_t &node, uint32_t &splitseg); - bool ShoveSegBehind (uint32_t set, node_t &node, uint32_t seg, uint32_t mate); int SelectSplitter (uint32_t set, node_t &node, uint32_t &splitseg, int step, bool nosplit); + bool ShoveSegBehind (uint32_t set, node_t &node, uint32_t seg, uint32_t mate); + int SelectSplitter (uint32_t set, node_t &node, uint32_t &splitseg, int step, bool nosplit); + void DoGLSegSplit (uint32_t set, node_t &node, uint32_t splitseg, uint32_t &outset0, uint32_t &outset1, int side, int sidev0, int sidev1, bool hack); void SplitSegs (uint32_t set, node_t &node, uint32_t splitseg, uint32_t &outset0, uint32_t &outset1, unsigned int &count0, unsigned int &count1); uint32_t SplitSeg (uint32_t segnum, int splitvert, int v1InFront); int Heuristic (node_t &node, uint32_t set, bool honorNoSplit); From 096b9cdc4f139c937aaa4b37852c6ced029c7086 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Sep 2023 00:34:45 +0200 Subject: [PATCH 115/223] - fixed. Boom's generalized crushers must stop 8 units above the floor This required changing the special, so a new one was added to avoid altering Generic_Crusher. --- src/playsim/actionspecials.h | 1 + src/playsim/p_lnspec.cpp | 8 ++++++++ src/rendering/hwrenderer/hw_models.cpp | 1 + wadsrc/static/xlat/base.txt | 2 +- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/playsim/actionspecials.h b/src/playsim/actionspecials.h index 2e5e95b72..7cfa43ce5 100644 --- a/src/playsim/actionspecials.h +++ b/src/playsim/actionspecials.h @@ -272,6 +272,7 @@ DEFINE_SPECIAL(Ceiling_MoveToValueAndCrush, 280, 4, 5, 5) DEFINE_SPECIAL(Line_SetAutomapFlags, 281, 3, 3, 3) DEFINE_SPECIAL(Line_SetAutomapStyle, 282, 2, 2, 2) DEFINE_SPECIAL(Polyobj_StopSound, 283, 1, 1, 1) +DEFINE_SPECIAL(Generic_CrusherDist, 284, 5, 5, 5) DEFINE_SPECIAL(Line_QuickPortal, 301, -1, -1, 1) diff --git a/src/playsim/p_lnspec.cpp b/src/playsim/p_lnspec.cpp index 88b37f8c3..0ac2c977e 100644 --- a/src/playsim/p_lnspec.cpp +++ b/src/playsim/p_lnspec.cpp @@ -941,6 +941,13 @@ FUNC(LS_Generic_Crusher2) SPEED(arg2), 0, arg4, arg3 ? 2 : 0, 0, DCeiling::ECrushMode::crushHexen); } +FUNC(LS_Generic_CrusherDist) +// Generic_CrusherDist (tag, dnspeed, upspeed, silent, damage) +{ + return Level->EV_DoCeiling(DCeiling::ceilCrushAndRaise, ln, arg0, SPEED(arg1), + SPEED(arg2), 8, arg4, arg3 ? 2 : 0, 0, (arg1 <= 24 && arg2 <= 24) ? DCeiling::ECrushMode::crushSlowdown : DCeiling::ECrushMode::crushDoom); +} + FUNC(LS_Plat_PerpetualRaise) // Plat_PerpetualRaise (tag, speed, delay) { @@ -3863,6 +3870,7 @@ static lnSpecFunc LineSpecials[] = /* 281 */ LS_Line_SetAutomapFlags, /* 282 */ LS_Line_SetAutomapStyle, /* 283 */ LS_Polyobj_StopSound, + /* 284 */ LS_Generic_CrusherDist }; #define DEFINE_SPECIAL(name, num, min, max, mmax) {#name, num, min, max, mmax}, diff --git a/src/rendering/hwrenderer/hw_models.cpp b/src/rendering/hwrenderer/hw_models.cpp index c6d568df7..b0fb572be 100644 --- a/src/rendering/hwrenderer/hw_models.cpp +++ b/src/rendering/hwrenderer/hw_models.cpp @@ -82,6 +82,7 @@ void FHWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) { state.SetDepthFunc(DF_LEqual); + state.SetDepthClamp(true); // [BB] In case the model should be rendered translucent, do back face culling. // This solves a few of the problems caused by the lack of depth sorting. diff --git a/wadsrc/static/xlat/base.txt b/wadsrc/static/xlat/base.txt index 99e5ec732..a53119b9e 100644 --- a/wadsrc/static/xlat/base.txt +++ b/wadsrc/static/xlat/base.txt @@ -421,7 +421,7 @@ include "xlat/defines.i" // Generalized crusher (tag, dnspeed, upspeed, silent, damage) -[Generic_Crusher] (0x2f80, 0x2fff) +[Generic_CrusherDist] (0x2f80, 0x2fff) { flags |= 0x0020 [0x0020 : MONST] arg2 = 0x0018 [0x0000 : C_SLOW, From eb93c764ee8ab1c0179832814c76be8b6271726e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Sep 2023 00:40:41 +0200 Subject: [PATCH 116/223] - restrict msglevel filtering only to the notify display, not the console, log and debug output. --- src/common/console/c_console.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/common/console/c_console.cpp b/src/common/console/c_console.cpp index b6377f1f1..c909592a5 100644 --- a/src/common/console/c_console.cpp +++ b/src/common/console/c_console.cpp @@ -417,7 +417,7 @@ int PrintString (int iprintlevel, const char *outline) if (!conbuffer) return 0; // when called too early int printlevel = iprintlevel & PRINT_TYPES; - if (printlevel < msglevel || *outline == '\0') + if (*outline == '\0') { return 0; } @@ -434,7 +434,10 @@ int PrintString (int iprintlevel, const char *outline) conbuffer->AddText(printlevel, outline); if (vidactive && screen && !(iprintlevel & PRINT_NONOTIFY) && NotifyStrings) { - NotifyStrings->AddString(iprintlevel, outline); + if (printlevel >= msglevel) + { + NotifyStrings->AddString(iprintlevel, outline); + } } } if (Logfile != nullptr && !(iprintlevel & PRINT_NOLOG)) From 85ba35a1f1933c673e554f31c27139a682f36cef Mon Sep 17 00:00:00 2001 From: Professor Hastig Date: Fri, 15 Sep 2023 09:20:00 +0200 Subject: [PATCH 117/223] - fix Strife-style startup asset check. The STARTUP0 check is not only redundant but also was wrong. It already gets checked and validated in the asset loading loop, and this up-front check did not handle placement as a graphic. --- src/common/startscreen/startscreen_strife.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/common/startscreen/startscreen_strife.cpp b/src/common/startscreen/startscreen_strife.cpp index 5b1d48bf4..df5467f96 100644 --- a/src/common/startscreen/startscreen_strife.cpp +++ b/src/common/startscreen/startscreen_strife.cpp @@ -105,18 +105,10 @@ protected: FStrifeStartScreen::FStrifeStartScreen(int max_progress) : FStartScreen(max_progress) { - // at this point we do not have a working texture manager yet, so we have to do the lookup via the file system - - int startup_lump = fileSystem.CheckNumForName("STARTUP0"); - - if (startup_lump < 0) - { - I_Error("bad startscreen assets"); - } - StartupBitmap.Create(320, 200); - // Load the animated overlays. + // at this point we do not have a working texture manager yet, so we have to do the lookup via the file system + // Load the background and animated overlays. for (size_t i = 0; i < countof(StrifeStartupPicNames); ++i) { int lumpnum = fileSystem.CheckNumForName(StrifeStartupPicNames[i], FileSys::ns_graphics); From cd31c74ecc729551aa8bdfbabc6b1cc571b74562 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Sep 2023 20:48:07 +0200 Subject: [PATCH 118/223] - stop all cutscenes before the ENDOOM screen. --- src/menu/doommenu.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/menu/doommenu.cpp b/src/menu/doommenu.cpp index f2a80ddc6..200dc90fc 100644 --- a/src/menu/doommenu.cpp +++ b/src/menu/doommenu.cpp @@ -365,6 +365,7 @@ void System_M_Dim() static void M_Quit() { + DeleteScreenJob(); S_StopAllChannels(); S_StopMusic(true); CleanSWDrawer(); From d001c3464d22d5d65845b7bfb5367bc719418bb2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Sep 2023 20:51:05 +0200 Subject: [PATCH 119/223] - removed another bad assert from codegen.cpp --- src/common/scripting/backend/codegen.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 8acbe668e..5bf359e32 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -2606,7 +2606,6 @@ FxExpression *FxAssignSelf::Resolve(FCompileContext &ctx) ExpEmit FxAssignSelf::Emit(VMFunctionBuilder *build) { - assert(ValueType == Assignment->ValueType); ExpEmit pointer = Assignment->Address; // FxAssign should have already emitted it if (!pointer.Target) { From 7f7edc4f72417bed52c2aa7bbd8c2f73f7650ec3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Sep 2023 21:46:53 +0200 Subject: [PATCH 120/223] - clear the Dehacked string table after passing it to GStrings. For some reason std::move does not work here so make sure it won't stick around. --- src/common/engine/stringtable.cpp | 1 + src/common/engine/stringtable.h | 2 +- src/gamedata/d_dehacked.cpp | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common/engine/stringtable.cpp b/src/common/engine/stringtable.cpp index 68cec6db8..ef3236942 100644 --- a/src/common/engine/stringtable.cpp +++ b/src/common/engine/stringtable.cpp @@ -51,6 +51,7 @@ void FStringTable::LoadStrings (const char *language) { int lastlump, lump; + allStrings.Clear(); lastlump = 0; while ((lump = fileSystem.FindLump("LMACROS", &lastlump)) != -1) { diff --git a/src/common/engine/stringtable.h b/src/common/engine/stringtable.h index df1508ae8..6850f8832 100644 --- a/src/common/engine/stringtable.h +++ b/src/common/engine/stringtable.h @@ -87,7 +87,7 @@ public: void LoadStrings(const char *language); void UpdateLanguage(const char* language); StringMap GetDefaultStrings() { return allStrings[default_table]; } // Dehacked needs these for comparison - void SetOverrideStrings(StringMap && map) + void SetOverrideStrings(StringMap & map) { allStrings.Insert(override_table, map); UpdateLanguage(nullptr); diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 1a67c16ab..9eb143817 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -3734,7 +3734,8 @@ void FinishDehPatch () OrgSprNames.Reset(); TouchedActors.Reset(); EnglishStrings.Clear(); - GStrings.SetOverrideStrings(std::move(DehStrings)); + GStrings.SetOverrideStrings(DehStrings); + DehStrings.Clear(); // Now it gets nasty: We have to fiddle around with the weapons' ammo use info to make Doom's original // ammo consumption work as intended. From b082c5050261cc215b641269013cd5c6b841950f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Sep 2023 22:00:05 +0200 Subject: [PATCH 121/223] - fixed doublebind check with automap. When no doublebinds get passed to C_DoKey it may not set the doubleclick flag. For the automap C_DoKey gets called twice, once with the automap bindings and once with the regular bindings and doubleclicks. --- src/common/console/c_bind.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/console/c_bind.cpp b/src/common/console/c_bind.cpp index 90ceaedce..57499e68c 100644 --- a/src/common/console/c_bind.cpp +++ b/src/common/console/c_bind.cpp @@ -836,7 +836,7 @@ bool C_DoKey (event_t *ev, FKeyBindings *binds, FKeyBindings *doublebinds) if (ev->type == EV_KeyDown) { // Key pressed for a normal press binding = binds->GetBinding(ev->data1); - DClickTime[ev->data1] = nowtime + 571; + if (doublebinds != nullptr) DClickTime[ev->data1] = nowtime + 571; } else if (doublebinds != nullptr && DClicked[ev->data1]) { // Key released from a double click From e522260037fdcc5924f825a6153046b08f666403 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Sep 2023 22:05:56 +0200 Subject: [PATCH 122/223] - added some missed UDMF properties to spec. --- specs/udmf_zdoom.txt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 957a33ce9..8a78826a9 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -1,5 +1,5 @@ =============================================================================== -Universal Doom Map Format ZDoom extensions v1.15 - 14.12.2010 +Universal Doom Map Format ZDoom extensions v1.33 15.09.2023 Copyright (c) 2008 Christoph Oelckers. @@ -118,6 +118,8 @@ Note: All fields default to false unless mentioned otherwise. blockuse = ; // Line blocks all use actions blocksight = ; // Line blocks monster line of sight blockhitscan = ; // Line blocks hitscan attacks + blockfloaters = ; // Line blocks floating monsters' movement. + blocklandmonsters = ; // Line blocks walking monsters' movement. locknumber = ; // Line special is locked arg0str = ; // Alternate string-based version of arg0 moreids = ; // Additional line IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505") @@ -534,9 +536,12 @@ Blocklandmonsters MBF21 flag 1.33 06.11.2021 Added separate light levels for sidedef tiers (top/mid/bottom) -1.34 09.11.2023 +1.34 11.09.2023 Added/updated ZDRay/lightmap-related properties. +1.35 15.09.2023 +fixed omissions: Blocklandmonsters and Blockfloaters line flags. + =============================================================================== EOF =============================================================================== From ef79ec193f5335de0ef451ed73dcde6e8c500e7e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 15 Sep 2023 22:33:03 +0200 Subject: [PATCH 123/223] - let P_CheckSwitchRange always check all 3 tiers. To account for cases that a switch is unreachable but another tier got a reachable one. --- src/playsim/p_switch.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/playsim/p_switch.cpp b/src/playsim/p_switch.cpp index 73aa95daa..9daf8cf9d 100644 --- a/src/playsim/p_switch.cpp +++ b/src/playsim/p_switch.cpp @@ -199,7 +199,7 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, const DVector3 * ? (user->Top() >= open.top) : (user->Top() > open.top); } - else if ((TexAnim.FindSwitch(side->GetTexture(side_t::bottom))) != NULL) + if ((TexAnim.FindSwitch(side->GetTexture(side_t::bottom))) != NULL) { // Check 3D floors on back side { @@ -223,7 +223,7 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, const DVector3 * ? (user->Z() <= open.bottom) : (user->Z() < open.bottom); } - else if ((flags & ML_3DMIDTEX) || (TexAnim.FindSwitch(side->GetTexture(side_t::mid))) != NULL) + if ((flags & ML_3DMIDTEX) || (TexAnim.FindSwitch(side->GetTexture(side_t::mid))) != NULL) { // 3DMIDTEX lines will force a mid texture check if no switch is found on this line // to keep compatibility with Eternity's implementation. From d354d7332fdba73f094085c7fe962da175977739 Mon Sep 17 00:00:00 2001 From: jekyllgrim Date: Fri, 15 Sep 2023 22:58:35 +0300 Subject: [PATCH 124/223] Allow viewbob speed adjustment through properties This adds ViewBobSpeed to PlayerPawn that is passed in CalcHeight() instead of the value of 20 and can be adjusted with the Player.ViewBobSpeed variable. This will let modders dynamically adjust how to only how far the camera bobs up and down, but also how *quickly* it does that, which allows to easily convey a feeling of a heavy, slow-moving character whose view might bob a lot but would do it slowly. --- wadsrc/static/zscript/actors/player/player.zs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/actors/player/player.zs b/wadsrc/static/zscript/actors/player/player.zs index e103bcd5f..aca1c4bca 100644 --- a/wadsrc/static/zscript/actors/player/player.zs +++ b/wadsrc/static/zscript/actors/player/player.zs @@ -48,6 +48,7 @@ class PlayerPawn : Actor color DamageFade; // [CW] Fades for when you are being damaged. double FlyBob; // [B] Fly bobbing mulitplier double ViewBob; // [SP] ViewBob Multiplier + double ViewBobSpeed; // [AA] ViewBob speed multiplier double WaterClimbSpeed; // [B] Speed when climbing up walls in water double FullHeight; double curBob; @@ -79,6 +80,7 @@ class PlayerPawn : Actor property TeleportFreezeTime: TeleportFreezeTime; property FlyBob: FlyBob; property ViewBob: ViewBob; + property ViewBobSpeed: ViewBobSpeed; property WaterClimbSpeed : WaterClimbSpeed; flagdef NoThrustWhenInvul: PlayerFlags, 0; @@ -128,6 +130,7 @@ class PlayerPawn : Actor Player.AirCapacity 1; Player.FlyBob 1; Player.ViewBob 1; + Player.ViewBobSpeed 20; Player.WaterClimbSpeed 3.5; Player.TeleportFreezeTime 18; Obituary "$OB_MPDEFAULT"; @@ -619,7 +622,7 @@ class PlayerPawn : Actor } else { - angle = Level.maptime / (20 * TICRATE / 35.) * 360.; + angle = Level.maptime / (ViewBobSpeed * TICRATE / 35.) * 360.; bob = player.bob * sin(angle) * (waterlevel > 1 ? 0.25f : 0.5f); } From 45a2cbe081deea641743ae2d67c70b41898b1e2e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 16 Sep 2023 03:13:43 +0200 Subject: [PATCH 125/223] Update zvulkan to latest version --- .../zvulkan/vk_mem_alloc/vk_mem_alloc.h | 24037 ++++++++-------- .../ZVulkan/include/zvulkan/vulkanbuilders.h | 39 +- .../ZVulkan/include/zvulkan/vulkandevice.h | 2 +- .../ZVulkan/include/zvulkan/vulkaninstance.h | 12 +- .../ZVulkan/include/zvulkan/vulkanobjects.h | 2 +- .../ZVulkan/include/zvulkan/vulkanswapchain.h | 21 +- libraries/ZVulkan/src/vulkanbuilders.cpp | 174 +- libraries/ZVulkan/src/vulkandevice.cpp | 20 +- libraries/ZVulkan/src/vulkaninstance.cpp | 27 +- libraries/ZVulkan/src/vulkanswapchain.cpp | 297 +- .../rendering/vulkan/shaders/vk_ppshader.cpp | 6 +- .../rendering/vulkan/shaders/vk_shader.cpp | 6 +- .../vulkan/system/vk_commandbuffer.cpp | 2 +- .../vulkan/system/vk_renderdevice.cpp | 30 +- .../vulkan/textures/vk_renderbuffers.cpp | 2 +- 15 files changed, 12305 insertions(+), 12372 deletions(-) diff --git a/libraries/ZVulkan/include/zvulkan/vk_mem_alloc/vk_mem_alloc.h b/libraries/ZVulkan/include/zvulkan/vk_mem_alloc/vk_mem_alloc.h index db0b94f4e..39f9d9d42 100644 --- a/libraries/ZVulkan/include/zvulkan/vk_mem_alloc/vk_mem_alloc.h +++ b/libraries/ZVulkan/include/zvulkan/vk_mem_alloc/vk_mem_alloc.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2017-2022 Advanced Micro Devices, Inc. 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 @@ -25,12 +25,12 @@ /** \mainpage Vulkan Memory Allocator -Version 3.0.0-development (2021-06-21) +Version 3.0.1 (2022-05-26) -Copyright (c) 2017-2021 Advanced Micro Devices, Inc. All rights reserved. \n +Copyright (c) 2017-2022 Advanced Micro Devices, Inc. All rights reserved. \n License: MIT -Documentation of all members: vk_mem_alloc.h +API documentation divided into groups: [Modules](modules.html) \section main_table_of_contents Table of contents @@ -49,7 +49,6 @@ Documentation of all members: vk_mem_alloc.h - [Mapping functions](@ref memory_mapping_mapping_functions) - [Persistently mapped memory](@ref memory_mapping_persistently_mapped_memory) - [Cache flush and invalidate](@ref memory_mapping_cache_control) - - [Finding out if memory is mappable](@ref memory_mapping_finding_if_memory_mappable) - \subpage staying_within_budget - [Querying for budget](@ref staying_within_budget_querying_for_budget) - [Controlling memory usage](@ref staying_within_budget_controlling_memory_usage) @@ -61,61 +60,90 @@ Documentation of all members: vk_mem_alloc.h - [Stack](@ref linear_algorithm_stack) - [Double stack](@ref linear_algorithm_double_stack) - [Ring buffer](@ref linear_algorithm_ring_buffer) - - [Buddy allocation algorithm](@ref buddy_algorithm) - \subpage defragmentation - - [Defragmenting CPU memory](@ref defragmentation_cpu) - - [Defragmenting GPU memory](@ref defragmentation_gpu) - - [Additional notes](@ref defragmentation_additional_notes) - - [Writing custom allocation algorithm](@ref defragmentation_custom_algorithm) - - \subpage lost_allocations - \subpage statistics - [Numeric statistics](@ref statistics_numeric_statistics) - [JSON dump](@ref statistics_json_dump) - \subpage allocation_annotation - [Allocation user data](@ref allocation_user_data) - [Allocation names](@ref allocation_names) + - \subpage virtual_allocator - \subpage debugging_memory_usage - [Memory initialization](@ref debugging_memory_usage_initialization) - [Margins](@ref debugging_memory_usage_margins) - [Corruption detection](@ref debugging_memory_usage_corruption_detection) - - \subpage record_and_replay - \subpage opengl_interop - \subpage usage_patterns - - [Common mistakes](@ref usage_patterns_common_mistakes) - - [Simple patterns](@ref usage_patterns_simple) - - [Advanced patterns](@ref usage_patterns_advanced) + - [GPU-only resource](@ref usage_patterns_gpu_only) + - [Staging copy for upload](@ref usage_patterns_staging_copy_upload) + - [Readback](@ref usage_patterns_readback) + - [Advanced data uploading](@ref usage_patterns_advanced_data_uploading) + - [Other use cases](@ref usage_patterns_other_use_cases) - \subpage configuration - [Pointers to Vulkan functions](@ref config_Vulkan_functions) - [Custom host memory allocator](@ref custom_memory_allocator) - [Device memory allocation callbacks](@ref allocation_callbacks) - [Device heap memory limit](@ref heap_memory_limit) - - \subpage vk_khr_dedicated_allocation - - \subpage enabling_buffer_device_address - - \subpage vk_amd_device_coherent_memory +- Extension support + - \subpage vk_khr_dedicated_allocation + - \subpage enabling_buffer_device_address + - \subpage vk_ext_memory_priority + - \subpage vk_amd_device_coherent_memory - \subpage general_considerations - [Thread safety](@ref general_considerations_thread_safety) + - [Versioning and compatibility](@ref general_considerations_versioning_and_compatibility) - [Validation layer warnings](@ref general_considerations_validation_layer_warnings) - [Allocation algorithm](@ref general_considerations_allocation_algorithm) - [Features not supported](@ref general_considerations_features_not_supported) \section main_see_also See also -- [Product page on GPUOpen](https://gpuopen.com/gaming-product/vulkan-memory-allocator/) -- [Source repository on GitHub](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) +- [**Product page on GPUOpen**](https://gpuopen.com/gaming-product/vulkan-memory-allocator/) +- [**Source repository on GitHub**](https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator) + +\defgroup group_init Library initialization + +\brief API elements related to the initialization and management of the entire library, especially #VmaAllocator object. + +\defgroup group_alloc Memory allocation + +\brief API elements related to the allocation, deallocation, and management of Vulkan memory, buffers, images. +Most basic ones being: vmaCreateBuffer(), vmaCreateImage(). + +\defgroup group_virtual Virtual allocator + +\brief API elements related to the mechanism of \ref virtual_allocator - using the core allocation algorithm +for user-defined purpose without allocating any real GPU memory. + +\defgroup group_stats Statistics + +\brief API elements that query current status of the allocator, from memory usage, budget, to full dump of the internal state in JSON format. +See documentation chapter: \ref statistics. */ -#include #ifdef __cplusplus +#include extern "C" { #endif -/* -Define this macro to 0/1 to disable/enable support for recording functionality, -available through VmaAllocatorCreateInfo::pRecordSettings. -*/ -#ifndef VMA_RECORDING_ENABLED - #define VMA_RECORDING_ENABLED 0 +#ifndef VULKAN_H_ + #include +#endif + +// Define this macro to declare maximum supported Vulkan version in format AAABBBCCC, +// where AAA = major, BBB = minor, CCC = patch. +// If you want to use version > 1.0, it still needs to be enabled via VmaAllocatorCreateInfo::vulkanApiVersion. +#if !defined(VMA_VULKAN_VERSION) + #if defined(VK_VERSION_1_3) + #define VMA_VULKAN_VERSION 1003000 + #elif defined(VK_VERSION_1_2) + #define VMA_VULKAN_VERSION 1002000 + #elif defined(VK_VERSION_1_1) + #define VMA_VULKAN_VERSION 1001000 + #else + #define VMA_VULKAN_VERSION 1000000 + #endif #endif #if defined(__ANDROID__) && defined(VK_NO_PROTOTYPES) && VMA_STATIC_VULKAN_FUNCTIONS @@ -147,23 +175,6 @@ available through VmaAllocatorCreateInfo::pRecordSettings. #endif // #if VMA_VULKAN_VERSION >= 1001000 #endif // #if defined(__ANDROID__) && VMA_STATIC_VULKAN_FUNCTIONS && VK_NO_PROTOTYPES -#ifndef VULKAN_H_ - #include -#endif - -// Define this macro to declare maximum supported Vulkan version in format AAABBBCCC, -// where AAA = major, BBB = minor, CCC = patch. -// If you want to use version > 1.0, it still needs to be enabled via VmaAllocatorCreateInfo::vulkanApiVersion. -#if !defined(VMA_VULKAN_VERSION) - #if defined(VK_VERSION_1_2) - #define VMA_VULKAN_VERSION 1002000 - #elif defined(VK_VERSION_1_1) - #define VMA_VULKAN_VERSION 1001000 - #else - #define VMA_VULKAN_VERSION 1000000 - #endif -#endif - #if !defined(VMA_DEDICATED_ALLOCATION) #if VK_KHR_get_memory_requirements2 && VK_KHR_dedicated_allocation #define VMA_DEDICATED_ALLOCATION 1 @@ -280,50 +291,29 @@ available through VmaAllocatorCreateInfo::pRecordSettings. #endif #endif -/** \struct VmaAllocator -\brief Represents main object of this library initialized. +#ifndef VMA_STATS_STRING_ENABLED + #define VMA_STATS_STRING_ENABLED 1 +#endif -Fill structure #VmaAllocatorCreateInfo and call function vmaCreateAllocator() to create it. -Call function vmaDestroyAllocator() to destroy it. +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// INTERFACE +// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// -It is recommended to create just one object of this type per `VkDevice` object, -right after Vulkan is initialized and keep it alive until before Vulkan device is destroyed. +// Sections for managing code placement in file, only for development purposes e.g. for convenient folding inside an IDE. +#ifndef _VMA_ENUM_DECLARATIONS + +/** +\addtogroup group_init +@{ */ -VK_DEFINE_HANDLE(VmaAllocator) - -/// Callback function called after successful vkAllocateMemory. -typedef void (VKAPI_PTR *PFN_vmaAllocateDeviceMemoryFunction)( - VmaAllocator VMA_NOT_NULL allocator, - uint32_t memoryType, - VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory, - VkDeviceSize size, - void* VMA_NULLABLE pUserData); -/// Callback function called before vkFreeMemory. -typedef void (VKAPI_PTR *PFN_vmaFreeDeviceMemoryFunction)( - VmaAllocator VMA_NOT_NULL allocator, - uint32_t memoryType, - VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory, - VkDeviceSize size, - void* VMA_NULLABLE pUserData); - -/** \brief Set of callbacks that the library will call for `vkAllocateMemory` and `vkFreeMemory`. - -Provided for informative purpose, e.g. to gather statistics about number of -allocations or total amount of memory allocated in Vulkan. - -Used in VmaAllocatorCreateInfo::pDeviceMemoryCallbacks. -*/ -typedef struct VmaDeviceMemoryCallbacks { - /// Optional, can be null. - PFN_vmaAllocateDeviceMemoryFunction VMA_NULLABLE pfnAllocate; - /// Optional, can be null. - PFN_vmaFreeDeviceMemoryFunction VMA_NULLABLE pfnFree; - /// Optional, can be null. - void* VMA_NULLABLE pUserData; -} VmaDeviceMemoryCallbacks; /// Flags for created #VmaAllocator. -typedef enum VmaAllocatorCreateFlagBits { +typedef enum VmaAllocatorCreateFlagBits +{ /** \brief Allocator and all objects created from it will not be synchronized internally, so you must guarantee they are used from only one thread at a time or synchronized externally by you. Using this flag may increase performance because internal mutexes are not used. @@ -437,13 +427,536 @@ typedef enum VmaAllocatorCreateFlagBits { VMA_ALLOCATOR_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VmaAllocatorCreateFlagBits; +/// See #VmaAllocatorCreateFlagBits. typedef VkFlags VmaAllocatorCreateFlags; +/** @} */ + +/** +\addtogroup group_alloc +@{ +*/ + +/// \brief Intended usage of the allocated memory. +typedef enum VmaMemoryUsage +{ + /** No intended memory usage specified. + Use other members of VmaAllocationCreateInfo to specify your requirements. + */ + VMA_MEMORY_USAGE_UNKNOWN = 0, + /** + \deprecated Obsolete, preserved for backward compatibility. + Prefers `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`. + */ + VMA_MEMORY_USAGE_GPU_ONLY = 1, + /** + \deprecated Obsolete, preserved for backward compatibility. + Guarantees `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` and `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT`. + */ + VMA_MEMORY_USAGE_CPU_ONLY = 2, + /** + \deprecated Obsolete, preserved for backward compatibility. + Guarantees `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`, prefers `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`. + */ + VMA_MEMORY_USAGE_CPU_TO_GPU = 3, + /** + \deprecated Obsolete, preserved for backward compatibility. + Guarantees `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`, prefers `VK_MEMORY_PROPERTY_HOST_CACHED_BIT`. + */ + VMA_MEMORY_USAGE_GPU_TO_CPU = 4, + /** + \deprecated Obsolete, preserved for backward compatibility. + Prefers not `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`. + */ + VMA_MEMORY_USAGE_CPU_COPY = 5, + /** + Lazily allocated GPU memory having `VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT`. + Exists mostly on mobile platforms. Using it on desktop PC or other GPUs with no such memory type present will fail the allocation. + + Usage: Memory for transient attachment images (color attachments, depth attachments etc.), created with `VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT`. + + Allocations with this usage are always created as dedicated - it implies #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. + */ + VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED = 6, + /** + Selects best memory type automatically. + This flag is recommended for most common use cases. + + When using this flag, if you want to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT), + you must pass one of the flags: #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT + in VmaAllocationCreateInfo::flags. + + It can be used only with functions that let the library know `VkBufferCreateInfo` or `VkImageCreateInfo`, e.g. + vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo() + and not with generic memory allocation functions. + */ + VMA_MEMORY_USAGE_AUTO = 7, + /** + Selects best memory type automatically with preference for GPU (device) memory. + + When using this flag, if you want to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT), + you must pass one of the flags: #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT + in VmaAllocationCreateInfo::flags. + + It can be used only with functions that let the library know `VkBufferCreateInfo` or `VkImageCreateInfo`, e.g. + vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo() + and not with generic memory allocation functions. + */ + VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE = 8, + /** + Selects best memory type automatically with preference for CPU (host) memory. + + When using this flag, if you want to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT), + you must pass one of the flags: #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT + in VmaAllocationCreateInfo::flags. + + It can be used only with functions that let the library know `VkBufferCreateInfo` or `VkImageCreateInfo`, e.g. + vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo(), vmaFindMemoryTypeIndexForImageInfo() + and not with generic memory allocation functions. + */ + VMA_MEMORY_USAGE_AUTO_PREFER_HOST = 9, + + VMA_MEMORY_USAGE_MAX_ENUM = 0x7FFFFFFF +} VmaMemoryUsage; + +/// Flags to be passed as VmaAllocationCreateInfo::flags. +typedef enum VmaAllocationCreateFlagBits +{ + /** \brief Set this flag if the allocation should have its own memory block. + + Use it for special, big resources, like fullscreen images used as attachments. + */ + VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT = 0x00000001, + + /** \brief Set this flag to only try to allocate from existing `VkDeviceMemory` blocks and never create new such block. + + If new allocation cannot be placed in any of the existing blocks, allocation + fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY` error. + + You should not use #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT and + #VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT at the same time. It makes no sense. + */ + VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT = 0x00000002, + /** \brief Set this flag to use a memory that will be persistently mapped and retrieve pointer to it. + + Pointer to mapped memory will be returned through VmaAllocationInfo::pMappedData. + + It is valid to use this flag for allocation made from memory type that is not + `HOST_VISIBLE`. This flag is then ignored and memory is not mapped. This is + useful if you need an allocation that is efficient to use on GPU + (`DEVICE_LOCAL`) and still want to map it directly if possible on platforms that + support it (e.g. Intel GPU). + */ + VMA_ALLOCATION_CREATE_MAPPED_BIT = 0x00000004, + /** \deprecated Preserved for backward compatibility. Consider using vmaSetAllocationName() instead. + + Set this flag to treat VmaAllocationCreateInfo::pUserData as pointer to a + null-terminated string. Instead of copying pointer value, a local copy of the + string is made and stored in allocation's `pName`. The string is automatically + freed together with the allocation. It is also used in vmaBuildStatsString(). + */ + VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT = 0x00000020, + /** Allocation will be created from upper stack in a double stack pool. + + This flag is only allowed for custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT flag. + */ + VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = 0x00000040, + /** Create both buffer/image and allocation, but don't bind them together. + It is useful when you want to bind yourself to do some more advanced binding, e.g. using some extensions. + The flag is meaningful only with functions that bind by default: vmaCreateBuffer(), vmaCreateImage(). + Otherwise it is ignored. + + If you want to make sure the new buffer/image is not tied to the new memory allocation + through `VkMemoryDedicatedAllocateInfoKHR` structure in case the allocation ends up in its own memory block, + use also flag #VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT. + */ + VMA_ALLOCATION_CREATE_DONT_BIND_BIT = 0x00000080, + /** Create allocation only if additional device memory required for it, if any, won't exceed + memory budget. Otherwise return `VK_ERROR_OUT_OF_DEVICE_MEMORY`. + */ + VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT = 0x00000100, + /** \brief Set this flag if the allocated memory will have aliasing resources. + + Usage of this flag prevents supplying `VkMemoryDedicatedAllocateInfoKHR` when #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT is specified. + Otherwise created dedicated memory will not be suitable for aliasing resources, resulting in Vulkan Validation Layer errors. + */ + VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT = 0x00000200, + /** + Requests possibility to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT). + + - If you use #VMA_MEMORY_USAGE_AUTO or other `VMA_MEMORY_USAGE_AUTO*` value, + you must use this flag to be able to map the allocation. Otherwise, mapping is incorrect. + - If you use other value of #VmaMemoryUsage, this flag is ignored and mapping is always possible in memory types that are `HOST_VISIBLE`. + This includes allocations created in \ref custom_memory_pools. + + Declares that mapped memory will only be written sequentially, e.g. using `memcpy()` or a loop writing number-by-number, + never read or accessed randomly, so a memory type can be selected that is uncached and write-combined. + + \warning Violating this declaration may work correctly, but will likely be very slow. + Watch out for implicit reads introduced by doing e.g. `pMappedData[i] += x;` + Better prepare your data in a local variable and `memcpy()` it to the mapped pointer all at once. + */ + VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT = 0x00000400, + /** + Requests possibility to map the allocation (using vmaMapMemory() or #VMA_ALLOCATION_CREATE_MAPPED_BIT). + + - If you use #VMA_MEMORY_USAGE_AUTO or other `VMA_MEMORY_USAGE_AUTO*` value, + you must use this flag to be able to map the allocation. Otherwise, mapping is incorrect. + - If you use other value of #VmaMemoryUsage, this flag is ignored and mapping is always possible in memory types that are `HOST_VISIBLE`. + This includes allocations created in \ref custom_memory_pools. + + Declares that mapped memory can be read, written, and accessed in random order, + so a `HOST_CACHED` memory type is required. + */ + VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT = 0x00000800, + /** + Together with #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT, + it says that despite request for host access, a not-`HOST_VISIBLE` memory type can be selected + if it may improve performance. + + By using this flag, you declare that you will check if the allocation ended up in a `HOST_VISIBLE` memory type + (e.g. using vmaGetAllocationMemoryProperties()) and if not, you will create some "staging" buffer and + issue an explicit transfer to write/read your data. + To prepare for this possibility, don't forget to add appropriate flags like + `VK_BUFFER_USAGE_TRANSFER_DST_BIT`, `VK_BUFFER_USAGE_TRANSFER_SRC_BIT` to the parameters of created buffer or image. + */ + VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT = 0x00001000, + /** Allocation strategy that chooses smallest possible free range for the allocation + to minimize memory usage and fragmentation, possibly at the expense of allocation time. + */ + VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = 0x00010000, + /** Allocation strategy that chooses first suitable free range for the allocation - + not necessarily in terms of the smallest offset but the one that is easiest and fastest to find + to minimize allocation time, possibly at the expense of allocation quality. + */ + VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = 0x00020000, + /** Allocation strategy that chooses always the lowest offset in available space. + This is not the most efficient strategy but achieves highly packed data. + Used internally by defragmentation, not recomended in typical usage. + */ + VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = 0x00040000, + /** Alias to #VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT. + */ + VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT, + /** Alias to #VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT. + */ + VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT, + /** A bit mask to extract only `STRATEGY` bits from entire set of flags. + */ + VMA_ALLOCATION_CREATE_STRATEGY_MASK = + VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT | + VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT | + VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT, + + VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VmaAllocationCreateFlagBits; +/// See #VmaAllocationCreateFlagBits. +typedef VkFlags VmaAllocationCreateFlags; + +/// Flags to be passed as VmaPoolCreateInfo::flags. +typedef enum VmaPoolCreateFlagBits +{ + /** \brief Use this flag if you always allocate only buffers and linear images or only optimal images out of this pool and so Buffer-Image Granularity can be ignored. + + This is an optional optimization flag. + + If you always allocate using vmaCreateBuffer(), vmaCreateImage(), + vmaAllocateMemoryForBuffer(), then you don't need to use it because allocator + knows exact type of your allocations so it can handle Buffer-Image Granularity + in the optimal way. + + If you also allocate using vmaAllocateMemoryForImage() or vmaAllocateMemory(), + exact type of such allocations is not known, so allocator must be conservative + in handling Buffer-Image Granularity, which can lead to suboptimal allocation + (wasted memory). In that case, if you can make sure you always allocate only + buffers and linear images or only optimal images out of this pool, use this flag + to make allocator disregard Buffer-Image Granularity and so make allocations + faster and more optimal. + */ + VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT = 0x00000002, + + /** \brief Enables alternative, linear allocation algorithm in this pool. + + Specify this flag to enable linear allocation algorithm, which always creates + new allocations after last one and doesn't reuse space from allocations freed in + between. It trades memory consumption for simplified algorithm and data + structure, which has better performance and uses less memory for metadata. + + By using this flag, you can achieve behavior of free-at-once, stack, + ring buffer, and double stack. + For details, see documentation chapter \ref linear_algorithm. + */ + VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT = 0x00000004, + + /** Bit mask to extract only `ALGORITHM` bits from entire set of flags. + */ + VMA_POOL_CREATE_ALGORITHM_MASK = + VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT, + + VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VmaPoolCreateFlagBits; +/// Flags to be passed as VmaPoolCreateInfo::flags. See #VmaPoolCreateFlagBits. +typedef VkFlags VmaPoolCreateFlags; + +/// Flags to be passed as VmaDefragmentationInfo::flags. +typedef enum VmaDefragmentationFlagBits +{ + /* \brief Use simple but fast algorithm for defragmentation. + May not achieve best results but will require least time to compute and least allocations to copy. + */ + VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT = 0x1, + /* \brief Default defragmentation algorithm, applied also when no `ALGORITHM` flag is specified. + Offers a balance between defragmentation quality and the amount of allocations and bytes that need to be moved. + */ + VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT = 0x2, + /* \brief Perform full defragmentation of memory. + Can result in notably more time to compute and allocations to copy, but will achieve best memory packing. + */ + VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT = 0x4, + /** \brief Use the most roboust algorithm at the cost of time to compute and number of copies to make. + Only available when bufferImageGranularity is greater than 1, since it aims to reduce + alignment issues between different types of resources. + Otherwise falls back to same behavior as #VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT. + */ + VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT = 0x8, + + /// A bit mask to extract only `ALGORITHM` bits from entire set of flags. + VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK = + VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT | + VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT | + VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT | + VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT, + + VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VmaDefragmentationFlagBits; +/// See #VmaDefragmentationFlagBits. +typedef VkFlags VmaDefragmentationFlags; + +/// Operation performed on single defragmentation move. See structure #VmaDefragmentationMove. +typedef enum VmaDefragmentationMoveOperation +{ + /// Buffer/image has been recreated at `dstTmpAllocation`, data has been copied, old buffer/image has been destroyed. `srcAllocation` should be changed to point to the new place. This is the default value set by vmaBeginDefragmentationPass(). + VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY = 0, + /// Set this value if you cannot move the allocation. New place reserved at `dstTmpAllocation` will be freed. `srcAllocation` will remain unchanged. + VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE = 1, + /// Set this value if you decide to abandon the allocation and you destroyed the buffer/image. New place reserved at `dstTmpAllocation` will be freed, along with `srcAllocation`, which will be destroyed. + VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY = 2, +} VmaDefragmentationMoveOperation; + +/** @} */ + +/** +\addtogroup group_virtual +@{ +*/ + +/// Flags to be passed as VmaVirtualBlockCreateInfo::flags. +typedef enum VmaVirtualBlockCreateFlagBits +{ + /** \brief Enables alternative, linear allocation algorithm in this virtual block. + + Specify this flag to enable linear allocation algorithm, which always creates + new allocations after last one and doesn't reuse space from allocations freed in + between. It trades memory consumption for simplified algorithm and data + structure, which has better performance and uses less memory for metadata. + + By using this flag, you can achieve behavior of free-at-once, stack, + ring buffer, and double stack. + For details, see documentation chapter \ref linear_algorithm. + */ + VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT = 0x00000001, + + /** \brief Bit mask to extract only `ALGORITHM` bits from entire set of flags. + */ + VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK = + VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT, + + VMA_VIRTUAL_BLOCK_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VmaVirtualBlockCreateFlagBits; +/// Flags to be passed as VmaVirtualBlockCreateInfo::flags. See #VmaVirtualBlockCreateFlagBits. +typedef VkFlags VmaVirtualBlockCreateFlags; + +/// Flags to be passed as VmaVirtualAllocationCreateInfo::flags. +typedef enum VmaVirtualAllocationCreateFlagBits +{ + /** \brief Allocation will be created from upper stack in a double stack pool. + + This flag is only allowed for virtual blocks created with #VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT flag. + */ + VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT, + /** \brief Allocation strategy that tries to minimize memory usage. + */ + VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT, + /** \brief Allocation strategy that tries to minimize allocation time. + */ + VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT, + /** Allocation strategy that chooses always the lowest offset in available space. + This is not the most efficient strategy but achieves highly packed data. + */ + VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT = VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT, + /** \brief A bit mask to extract only `STRATEGY` bits from entire set of flags. + + These strategy flags are binary compatible with equivalent flags in #VmaAllocationCreateFlagBits. + */ + VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK = VMA_ALLOCATION_CREATE_STRATEGY_MASK, + + VMA_VIRTUAL_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VmaVirtualAllocationCreateFlagBits; +/// Flags to be passed as VmaVirtualAllocationCreateInfo::flags. See #VmaVirtualAllocationCreateFlagBits. +typedef VkFlags VmaVirtualAllocationCreateFlags; + +/** @} */ + +#endif // _VMA_ENUM_DECLARATIONS + +#ifndef _VMA_DATA_TYPES_DECLARATIONS + +/** +\addtogroup group_init +@{ */ + +/** \struct VmaAllocator +\brief Represents main object of this library initialized. + +Fill structure #VmaAllocatorCreateInfo and call function vmaCreateAllocator() to create it. +Call function vmaDestroyAllocator() to destroy it. + +It is recommended to create just one object of this type per `VkDevice` object, +right after Vulkan is initialized and keep it alive until before Vulkan device is destroyed. +*/ +VK_DEFINE_HANDLE(VmaAllocator) + +/** @} */ + +/** +\addtogroup group_alloc +@{ +*/ + +/** \struct VmaPool +\brief Represents custom memory pool + +Fill structure VmaPoolCreateInfo and call function vmaCreatePool() to create it. +Call function vmaDestroyPool() to destroy it. + +For more information see [Custom memory pools](@ref choosing_memory_type_custom_memory_pools). +*/ +VK_DEFINE_HANDLE(VmaPool) + +/** \struct VmaAllocation +\brief Represents single memory allocation. + +It may be either dedicated block of `VkDeviceMemory` or a specific region of a bigger block of this type +plus unique offset. + +There are multiple ways to create such object. +You need to fill structure VmaAllocationCreateInfo. +For more information see [Choosing memory type](@ref choosing_memory_type). + +Although the library provides convenience functions that create Vulkan buffer or image, +allocate memory for it and bind them together, +binding of the allocation to a buffer or an image is out of scope of the allocation itself. +Allocation object can exist without buffer/image bound, +binding can be done manually by the user, and destruction of it can be done +independently of destruction of the allocation. + +The object also remembers its size and some other information. +To retrieve this information, use function vmaGetAllocationInfo() and inspect +returned structure VmaAllocationInfo. +*/ +VK_DEFINE_HANDLE(VmaAllocation) + +/** \struct VmaDefragmentationContext +\brief An opaque object that represents started defragmentation process. + +Fill structure #VmaDefragmentationInfo and call function vmaBeginDefragmentation() to create it. +Call function vmaEndDefragmentation() to destroy it. +*/ +VK_DEFINE_HANDLE(VmaDefragmentationContext) + +/** @} */ + +/** +\addtogroup group_virtual +@{ +*/ + +/** \struct VmaVirtualAllocation +\brief Represents single memory allocation done inside VmaVirtualBlock. + +Use it as a unique identifier to virtual allocation within the single block. + +Use value `VK_NULL_HANDLE` to represent a null/invalid allocation. +*/ +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VmaVirtualAllocation); + +/** @} */ + +/** +\addtogroup group_virtual +@{ +*/ + +/** \struct VmaVirtualBlock +\brief Handle to a virtual block object that allows to use core allocation algorithm without allocating any real GPU memory. + +Fill in #VmaVirtualBlockCreateInfo structure and use vmaCreateVirtualBlock() to create it. Use vmaDestroyVirtualBlock() to destroy it. +For more information, see documentation chapter \ref virtual_allocator. + +This object is not thread-safe - should not be used from multiple threads simultaneously, must be synchronized externally. +*/ +VK_DEFINE_HANDLE(VmaVirtualBlock) + +/** @} */ + +/** +\addtogroup group_init +@{ +*/ + +/// Callback function called after successful vkAllocateMemory. +typedef void (VKAPI_PTR* PFN_vmaAllocateDeviceMemoryFunction)( + VmaAllocator VMA_NOT_NULL allocator, + uint32_t memoryType, + VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory, + VkDeviceSize size, + void* VMA_NULLABLE pUserData); + +/// Callback function called before vkFreeMemory. +typedef void (VKAPI_PTR* PFN_vmaFreeDeviceMemoryFunction)( + VmaAllocator VMA_NOT_NULL allocator, + uint32_t memoryType, + VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory, + VkDeviceSize size, + void* VMA_NULLABLE pUserData); + +/** \brief Set of callbacks that the library will call for `vkAllocateMemory` and `vkFreeMemory`. + +Provided for informative purpose, e.g. to gather statistics about number of +allocations or total amount of memory allocated in Vulkan. + +Used in VmaAllocatorCreateInfo::pDeviceMemoryCallbacks. +*/ +typedef struct VmaDeviceMemoryCallbacks +{ + /// Optional, can be null. + PFN_vmaAllocateDeviceMemoryFunction VMA_NULLABLE pfnAllocate; + /// Optional, can be null. + PFN_vmaFreeDeviceMemoryFunction VMA_NULLABLE pfnFree; + /// Optional, can be null. + void* VMA_NULLABLE pUserData; +} VmaDeviceMemoryCallbacks; + /** \brief Pointers to some Vulkan functions - a subset used by the library. Used in VmaAllocatorCreateInfo::pVulkanFunctions. */ -typedef struct VmaVulkanFunctions { +typedef struct VmaVulkanFunctions +{ + /// Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS. + PFN_vkGetInstanceProcAddr VMA_NULLABLE vkGetInstanceProcAddr; + /// Required when using VMA_DYNAMIC_VULKAN_FUNCTIONS. + PFN_vkGetDeviceProcAddr VMA_NULLABLE vkGetDeviceProcAddr; PFN_vkGetPhysicalDeviceProperties VMA_NULLABLE vkGetPhysicalDeviceProperties; PFN_vkGetPhysicalDeviceMemoryProperties VMA_NULLABLE vkGetPhysicalDeviceMemoryProperties; PFN_vkAllocateMemory VMA_NULLABLE vkAllocateMemory; @@ -462,46 +975,28 @@ typedef struct VmaVulkanFunctions { PFN_vkDestroyImage VMA_NULLABLE vkDestroyImage; PFN_vkCmdCopyBuffer VMA_NULLABLE vkCmdCopyBuffer; #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 + /// Fetch "vkGetBufferMemoryRequirements2" on Vulkan >= 1.1, fetch "vkGetBufferMemoryRequirements2KHR" when using VK_KHR_dedicated_allocation extension. PFN_vkGetBufferMemoryRequirements2KHR VMA_NULLABLE vkGetBufferMemoryRequirements2KHR; + /// Fetch "vkGetImageMemoryRequirements2" on Vulkan >= 1.1, fetch "vkGetImageMemoryRequirements2KHR" when using VK_KHR_dedicated_allocation extension. PFN_vkGetImageMemoryRequirements2KHR VMA_NULLABLE vkGetImageMemoryRequirements2KHR; #endif #if VMA_BIND_MEMORY2 || VMA_VULKAN_VERSION >= 1001000 + /// Fetch "vkBindBufferMemory2" on Vulkan >= 1.1, fetch "vkBindBufferMemory2KHR" when using VK_KHR_bind_memory2 extension. PFN_vkBindBufferMemory2KHR VMA_NULLABLE vkBindBufferMemory2KHR; + /// Fetch "vkBindImageMemory2" on Vulkan >= 1.1, fetch "vkBindImageMemory2KHR" when using VK_KHR_bind_memory2 extension. PFN_vkBindImageMemory2KHR VMA_NULLABLE vkBindImageMemory2KHR; #endif #if VMA_MEMORY_BUDGET || VMA_VULKAN_VERSION >= 1001000 PFN_vkGetPhysicalDeviceMemoryProperties2KHR VMA_NULLABLE vkGetPhysicalDeviceMemoryProperties2KHR; #endif +#if VMA_VULKAN_VERSION >= 1003000 + /// Fetch from "vkGetDeviceBufferMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceBufferMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4. + PFN_vkGetDeviceBufferMemoryRequirements VMA_NULLABLE vkGetDeviceBufferMemoryRequirements; + /// Fetch from "vkGetDeviceImageMemoryRequirements" on Vulkan >= 1.3, but you can also fetch it from "vkGetDeviceImageMemoryRequirementsKHR" if you enabled extension VK_KHR_maintenance4. + PFN_vkGetDeviceImageMemoryRequirements VMA_NULLABLE vkGetDeviceImageMemoryRequirements; +#endif } VmaVulkanFunctions; -/// Flags to be used in VmaRecordSettings::flags. -typedef enum VmaRecordFlagBits { - /** \brief Enables flush after recording every function call. - - Enable it if you expect your application to crash, which may leave recording file truncated. - It may degrade performance though. - */ - VMA_RECORD_FLUSH_AFTER_CALL_BIT = 0x00000001, - - VMA_RECORD_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VmaRecordFlagBits; -typedef VkFlags VmaRecordFlags; - -/// Parameters for recording calls to VMA functions. To be used in VmaAllocatorCreateInfo::pRecordSettings. -typedef struct VmaRecordSettings -{ - /// Flags for recording. Use #VmaRecordFlagBits enum. - VmaRecordFlags flags; - /** \brief Path to the file that should be written by the recording. - - Suggested extension: "csv". - If the file already exists, it will be overwritten. - It will be opened for the whole time #VmaAllocator object is alive. - If opening this file fails, creation of the whole allocator object fails. - */ - const char* VMA_NOT_NULL pFilePath; -} VmaRecordSettings; - /// Description of a Allocator to be created. typedef struct VmaAllocatorCreateInfo { @@ -522,20 +1017,6 @@ typedef struct VmaAllocatorCreateInfo /// Informative callbacks for `vkAllocateMemory`, `vkFreeMemory`. Optional. /** Optional, can be null. */ const VmaDeviceMemoryCallbacks* VMA_NULLABLE pDeviceMemoryCallbacks; - /** \brief Maximum number of additional frames that are in use at the same time as current frame. - - This value is used only when you make allocations with - VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag. Such allocation cannot become - lost if allocation.lastUseFrameIndex >= allocator.currentFrameIndex - frameInUseCount. - - For example, if you double-buffer your command buffers, so resources used for - rendering in previous frame may still be in use by the GPU at the moment you - allocate resources needed for the current frame, set this value to 1. - - If you want to allow any allocations other than used in the current frame to - become lost, set this value to 0. - */ - uint32_t frameInUseCount; /** \brief Either null or a pointer to an array of limits on maximum number of bytes that can be allocated out of particular Vulkan memory heap. If not NULL, it must be a pointer to an array of @@ -567,13 +1048,6 @@ typedef struct VmaAllocatorCreateInfo For details see [Pointers to Vulkan functions](@ref config_Vulkan_functions). */ const VmaVulkanFunctions* VMA_NULLABLE pVulkanFunctions; - /** \brief Parameters for recording of VMA calls. Can be null. - - If not null, it enables recording of calls to VMA functions to a file. - If support for recording is not enabled using `VMA_RECORDING_ENABLED` macro, - creation of the allocator object fails with `VK_ERROR_FEATURE_NOT_PRESENT`. - */ - const VmaRecordSettings* VMA_NULLABLE pRecordSettings; /** \brief Handle to Vulkan instance object. Starting from version 3.0.0 this member is no longer optional, it must be set! @@ -584,7 +1058,7 @@ typedef struct VmaAllocatorCreateInfo It must be a value in the format as created by macro `VK_MAKE_VERSION` or a constant like: `VK_API_VERSION_1_1`, `VK_API_VERSION_1_0`. The patch version number specified is ignored. Only the major and minor versions are considered. It must be less or equal (preferably equal) to value as passed to `vkCreateInstance` as `VkApplicationInfo::apiVersion`. - Only versions 1.0, 1.1, 1.2 are supported by the current implementation. + Only versions 1.0, 1.1, 1.2, 1.3 are supported by the current implementation. Leaving it initialized to zero is equivalent to `VK_API_VERSION_1_0`. */ uint32_t vulkanApiVersion; @@ -602,17 +1076,7 @@ typedef struct VmaAllocatorCreateInfo #endif // #if VMA_EXTERNAL_MEMORY } VmaAllocatorCreateInfo; -/// Creates Allocator object. -VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator( - const VmaAllocatorCreateInfo* VMA_NOT_NULL pCreateInfo, - VmaAllocator VMA_NULLABLE * VMA_NOT_NULL pAllocator); - -/// Destroys allocator object. -VMA_CALL_PRE void VMA_CALL_POST vmaDestroyAllocator( - VmaAllocator VMA_NULLABLE allocator); - -/** \brief Information about existing #VmaAllocator object. -*/ +/// Information about existing #VmaAllocator object. typedef struct VmaAllocatorInfo { /** \brief Handle to Vulkan instance object. @@ -632,359 +1096,129 @@ typedef struct VmaAllocatorInfo VkDevice VMA_NOT_NULL device; } VmaAllocatorInfo; -/** \brief Returns information about existing #VmaAllocator object - handle to Vulkan device etc. - -It might be useful if you want to keep just the #VmaAllocator handle and fetch other required handles to -`VkPhysicalDevice`, `VkDevice` etc. every time using this function. -*/ -VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocatorInfo(VmaAllocator VMA_NOT_NULL allocator, VmaAllocatorInfo* VMA_NOT_NULL pAllocatorInfo); +/** @} */ /** -PhysicalDeviceProperties are fetched from physicalDevice by the allocator. -You can access it here, without fetching it again on your own. +\addtogroup group_stats +@{ */ -VMA_CALL_PRE void VMA_CALL_POST vmaGetPhysicalDeviceProperties( - VmaAllocator VMA_NOT_NULL allocator, - const VkPhysicalDeviceProperties* VMA_NULLABLE * VMA_NOT_NULL ppPhysicalDeviceProperties); -/** -PhysicalDeviceMemoryProperties are fetched from physicalDevice by the allocator. -You can access it here, without fetching it again on your own. +/** \brief Calculated statistics of memory usage e.g. in a specific memory type, heap, custom pool, or total. + +These are fast to calculate. +See functions: vmaGetHeapBudgets(), vmaGetPoolStatistics(). */ -VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryProperties( - VmaAllocator VMA_NOT_NULL allocator, - const VkPhysicalDeviceMemoryProperties* VMA_NULLABLE * VMA_NOT_NULL ppPhysicalDeviceMemoryProperties); - -/** -\brief Given Memory Type Index, returns Property Flags of this memory type. - -This is just a convenience function. Same information can be obtained using -vmaGetMemoryProperties(). -*/ -VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryTypeProperties( - VmaAllocator VMA_NOT_NULL allocator, - uint32_t memoryTypeIndex, - VkMemoryPropertyFlags* VMA_NOT_NULL pFlags); - -/** \brief Sets index of the current frame. - -This function must be used if you make allocations with -#VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT and -#VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flags to inform the allocator -when a new frame begins. Allocations queried using vmaGetAllocationInfo() cannot -become lost in the current frame. -*/ -VMA_CALL_PRE void VMA_CALL_POST vmaSetCurrentFrameIndex( - VmaAllocator VMA_NOT_NULL allocator, - uint32_t frameIndex); - -/** \brief Calculated statistics of memory usage in entire allocator. -*/ -typedef struct VmaStatInfo +typedef struct VmaStatistics { - /// Number of `VkDeviceMemory` Vulkan memory blocks allocated. + /** \brief Number of `VkDeviceMemory` objects - Vulkan memory blocks allocated. + */ uint32_t blockCount; - /// Number of #VmaAllocation allocation objects allocated. + /** \brief Number of #VmaAllocation objects allocated. + + Dedicated allocations have their own blocks, so each one adds 1 to `allocationCount` as well as `blockCount`. + */ uint32_t allocationCount; + /** \brief Number of bytes allocated in `VkDeviceMemory` blocks. + + \note To avoid confusion, please be aware that what Vulkan calls an "allocation" - a whole `VkDeviceMemory` object + (e.g. as in `VkPhysicalDeviceLimits::maxMemoryAllocationCount`) is called a "block" in VMA, while VMA calls + "allocation" a #VmaAllocation object that represents a memory region sub-allocated from such block, usually for a single buffer or image. + */ + VkDeviceSize blockBytes; + /** \brief Total number of bytes occupied by all #VmaAllocation objects. + + Always less or equal than `blockBytes`. + Difference `(blockBytes - allocationBytes)` is the amount of memory allocated from Vulkan + but unused by any #VmaAllocation. + */ + VkDeviceSize allocationBytes; +} VmaStatistics; + +/** \brief More detailed statistics than #VmaStatistics. + +These are slower to calculate. Use for debugging purposes. +See functions: vmaCalculateStatistics(), vmaCalculatePoolStatistics(). + +Previous version of the statistics API provided averages, but they have been removed +because they can be easily calculated as: + +\code +VkDeviceSize allocationSizeAvg = detailedStats.statistics.allocationBytes / detailedStats.statistics.allocationCount; +VkDeviceSize unusedBytes = detailedStats.statistics.blockBytes - detailedStats.statistics.allocationBytes; +VkDeviceSize unusedRangeSizeAvg = unusedBytes / detailedStats.unusedRangeCount; +\endcode +*/ +typedef struct VmaDetailedStatistics +{ + /// Basic statistics. + VmaStatistics statistics; /// Number of free ranges of memory between allocations. uint32_t unusedRangeCount; - /// Total number of bytes occupied by all allocations. - VkDeviceSize usedBytes; - /// Total number of bytes occupied by unused ranges. - VkDeviceSize unusedBytes; - VkDeviceSize allocationSizeMin, allocationSizeAvg, allocationSizeMax; - VkDeviceSize unusedRangeSizeMin, unusedRangeSizeAvg, unusedRangeSizeMax; -} VmaStatInfo; + /// Smallest allocation size. `VK_WHOLE_SIZE` if there are 0 allocations. + VkDeviceSize allocationSizeMin; + /// Largest allocation size. 0 if there are 0 allocations. + VkDeviceSize allocationSizeMax; + /// Smallest empty range size. `VK_WHOLE_SIZE` if there are 0 empty ranges. + VkDeviceSize unusedRangeSizeMin; + /// Largest empty range size. 0 if there are 0 empty ranges. + VkDeviceSize unusedRangeSizeMax; +} VmaDetailedStatistics; -/// General statistics from current state of Allocator. -typedef struct VmaStats -{ - VmaStatInfo memoryType[VK_MAX_MEMORY_TYPES]; - VmaStatInfo memoryHeap[VK_MAX_MEMORY_HEAPS]; - VmaStatInfo total; -} VmaStats; +/** \brief General statistics from current state of the Allocator - +total memory usage across all memory heaps and types. -/** \brief Retrieves statistics from current state of the Allocator. - -This function is called "calculate" not "get" because it has to traverse all -internal data structures, so it may be quite slow. For faster but more brief statistics -suitable to be called every frame or every allocation, use vmaGetBudget(). - -Note that when using allocator from multiple threads, returned information may immediately -become outdated. +These are slower to calculate. Use for debugging purposes. +See function vmaCalculateStatistics(). */ -VMA_CALL_PRE void VMA_CALL_POST vmaCalculateStats( - VmaAllocator VMA_NOT_NULL allocator, - VmaStats* VMA_NOT_NULL pStats); +typedef struct VmaTotalStatistics +{ + VmaDetailedStatistics memoryType[VK_MAX_MEMORY_TYPES]; + VmaDetailedStatistics memoryHeap[VK_MAX_MEMORY_HEAPS]; + VmaDetailedStatistics total; +} VmaTotalStatistics; -/** \brief Statistics of current memory usage and available budget, in bytes, for specific memory heap. +/** \brief Statistics of current memory usage and available budget for a specific memory heap. + +These are fast to calculate. +See function vmaGetHeapBudgets(). */ typedef struct VmaBudget { - /** \brief Sum size of all `VkDeviceMemory` blocks allocated from particular heap, in bytes. + /** \brief Statistics fetched from the library. */ - VkDeviceSize blockBytes; - - /** \brief Sum size of all allocations created in particular heap, in bytes. - - Usually less or equal than `blockBytes`. - Difference `blockBytes - allocationBytes` is the amount of memory allocated but unused - - available for new allocations or wasted due to fragmentation. - - It might be greater than `blockBytes` if there are some allocations in lost state, as they account - to this value as well. - */ - VkDeviceSize allocationBytes; - + VmaStatistics statistics; /** \brief Estimated current memory usage of the program, in bytes. - Fetched from system using `VK_EXT_memory_budget` extension if enabled. + Fetched from system using VK_EXT_memory_budget extension if enabled. - It might be different than `blockBytes` (usually higher) due to additional implicit objects + It might be different than `statistics.blockBytes` (usually higher) due to additional implicit objects also occupying the memory, like swapchain, pipelines, descriptor heaps, command buffers, or `VkDeviceMemory` blocks allocated outside of this library, if any. */ VkDeviceSize usage; - /** \brief Estimated amount of memory available to the program, in bytes. - Fetched from system using `VK_EXT_memory_budget` extension if enabled. + Fetched from system using VK_EXT_memory_budget extension if enabled. It might be different (most probably smaller) than `VkMemoryHeap::size[heapIndex]` due to factors - external to the program, like other programs also consuming system resources. + external to the program, decided by the operating system. Difference `budget - usage` is the amount of additional memory that can probably be allocated without problems. Exceeding the budget may result in various problems. */ VkDeviceSize budget; } VmaBudget; -/** \brief Retrieves information about current memory budget for all memory heaps. +/** @} */ -\param allocator -\param[out] pBudget Must point to array with number of elements at least equal to number of memory heaps in physical device used. - -This function is called "get" not "calculate" because it is very fast, suitable to be called -every frame or every allocation. For more detailed statistics use vmaCalculateStats(). - -Note that when using allocator from multiple threads, returned information may immediately -become outdated. -*/ -VMA_CALL_PRE void VMA_CALL_POST vmaGetBudget( - VmaAllocator VMA_NOT_NULL allocator, - VmaBudget* VMA_NOT_NULL pBudget); - -#ifndef VMA_STATS_STRING_ENABLED -#define VMA_STATS_STRING_ENABLED 1 -#endif - -#if VMA_STATS_STRING_ENABLED - -/// Builds and returns statistics as string in JSON format. /** -@param allocator -@param[out] ppStatsString Must be freed using vmaFreeStatsString() function. -@param detailedMap +\addtogroup group_alloc +@{ */ -VMA_CALL_PRE void VMA_CALL_POST vmaBuildStatsString( - VmaAllocator VMA_NOT_NULL allocator, - char* VMA_NULLABLE * VMA_NOT_NULL ppStatsString, - VkBool32 detailedMap); -VMA_CALL_PRE void VMA_CALL_POST vmaFreeStatsString( - VmaAllocator VMA_NOT_NULL allocator, - char* VMA_NULLABLE pStatsString); +/** \brief Parameters of new #VmaAllocation. -#endif // #if VMA_STATS_STRING_ENABLED - -/** \struct VmaPool -\brief Represents custom memory pool - -Fill structure VmaPoolCreateInfo and call function vmaCreatePool() to create it. -Call function vmaDestroyPool() to destroy it. - -For more information see [Custom memory pools](@ref choosing_memory_type_custom_memory_pools). +To be used with functions like vmaCreateBuffer(), vmaCreateImage(), and many others. */ -VK_DEFINE_HANDLE(VmaPool) - -typedef enum VmaMemoryUsage -{ - /** No intended memory usage specified. - Use other members of VmaAllocationCreateInfo to specify your requirements. - */ - VMA_MEMORY_USAGE_UNKNOWN = 0, - /** Memory will be used on device only, so fast access from the device is preferred. - It usually means device-local GPU (video) memory. - No need to be mappable on host. - It is roughly equivalent of `D3D12_HEAP_TYPE_DEFAULT`. - - Usage: - - - Resources written and read by device, e.g. images used as attachments. - - Resources transferred from host once (immutable) or infrequently and read by - device multiple times, e.g. textures to be sampled, vertex buffers, uniform - (constant) buffers, and majority of other types of resources used on GPU. - - Allocation may still end up in `HOST_VISIBLE` memory on some implementations. - In such case, you are free to map it. - You can use #VMA_ALLOCATION_CREATE_MAPPED_BIT with this usage type. - */ - VMA_MEMORY_USAGE_GPU_ONLY = 1, - /** Memory will be mappable on host. - It usually means CPU (system) memory. - Guarantees to be `HOST_VISIBLE` and `HOST_COHERENT`. - CPU access is typically uncached. Writes may be write-combined. - Resources created in this pool may still be accessible to the device, but access to them can be slow. - It is roughly equivalent of `D3D12_HEAP_TYPE_UPLOAD`. - - Usage: Staging copy of resources used as transfer source. - */ - VMA_MEMORY_USAGE_CPU_ONLY = 2, - /** - Memory that is both mappable on host (guarantees to be `HOST_VISIBLE`) and preferably fast to access by GPU. - CPU access is typically uncached. Writes may be write-combined. - - Usage: Resources written frequently by host (dynamic), read by device. E.g. textures (with LINEAR layout), vertex buffers, uniform buffers updated every frame or every draw call. - */ - VMA_MEMORY_USAGE_CPU_TO_GPU = 3, - /** Memory mappable on host (guarantees to be `HOST_VISIBLE`) and cached. - It is roughly equivalent of `D3D12_HEAP_TYPE_READBACK`. - - Usage: - - - Resources written by device, read by host - results of some computations, e.g. screen capture, average scene luminance for HDR tone mapping. - - Any resources read or accessed randomly on host, e.g. CPU-side copy of vertex buffer used as source of transfer, but also used for collision detection. - */ - VMA_MEMORY_USAGE_GPU_TO_CPU = 4, - /** CPU memory - memory that is preferably not `DEVICE_LOCAL`, but also not guaranteed to be `HOST_VISIBLE`. - - Usage: Staging copy of resources moved from GPU memory to CPU memory as part - of custom paging/residency mechanism, to be moved back to GPU memory when needed. - */ - VMA_MEMORY_USAGE_CPU_COPY = 5, - /** Lazily allocated GPU memory having `VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT`. - Exists mostly on mobile platforms. Using it on desktop PC or other GPUs with no such memory type present will fail the allocation. - - Usage: Memory for transient attachment images (color attachments, depth attachments etc.), created with `VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT`. - - Allocations with this usage are always created as dedicated - it implies #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. - */ - VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED = 6, - - VMA_MEMORY_USAGE_MAX_ENUM = 0x7FFFFFFF -} VmaMemoryUsage; - -/// Flags to be passed as VmaAllocationCreateInfo::flags. -typedef enum VmaAllocationCreateFlagBits { - /** \brief Set this flag if the allocation should have its own memory block. - - Use it for special, big resources, like fullscreen images used as attachments. - - You should not use this flag if VmaAllocationCreateInfo::pool is not null. - */ - VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT = 0x00000001, - - /** \brief Set this flag to only try to allocate from existing `VkDeviceMemory` blocks and never create new such block. - - If new allocation cannot be placed in any of the existing blocks, allocation - fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY` error. - - You should not use #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT and - #VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT at the same time. It makes no sense. - - If VmaAllocationCreateInfo::pool is not null, this flag is implied and ignored. */ - VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT = 0x00000002, - /** \brief Set this flag to use a memory that will be persistently mapped and retrieve pointer to it. - - Pointer to mapped memory will be returned through VmaAllocationInfo::pMappedData. - - It is valid to use this flag for allocation made from memory type that is not - `HOST_VISIBLE`. This flag is then ignored and memory is not mapped. This is - useful if you need an allocation that is efficient to use on GPU - (`DEVICE_LOCAL`) and still want to map it directly if possible on platforms that - support it (e.g. Intel GPU). - - You should not use this flag together with #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT. - */ - VMA_ALLOCATION_CREATE_MAPPED_BIT = 0x00000004, - /** Allocation created with this flag can become lost as a result of another - allocation with #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag, so you - must check it before use. - - To check if allocation is not lost, call vmaGetAllocationInfo() and check if - VmaAllocationInfo::deviceMemory is not `VK_NULL_HANDLE`. - - For details about supporting lost allocations, see Lost Allocations - chapter of User Guide on Main Page. - - You should not use this flag together with #VMA_ALLOCATION_CREATE_MAPPED_BIT. - */ - VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT = 0x00000008, - /** While creating allocation using this flag, other allocations that were - created with flag #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT can become lost. - - For details about supporting lost allocations, see Lost Allocations - chapter of User Guide on Main Page. - */ - VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT = 0x00000010, - /** Set this flag to treat VmaAllocationCreateInfo::pUserData as pointer to a - null-terminated string. Instead of copying pointer value, a local copy of the - string is made and stored in allocation's `pUserData`. The string is automatically - freed together with the allocation. It is also used in vmaBuildStatsString(). - */ - VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT = 0x00000020, - /** Allocation will be created from upper stack in a double stack pool. - - This flag is only allowed for custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT flag. - */ - VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT = 0x00000040, - /** Create both buffer/image and allocation, but don't bind them together. - It is useful when you want to bind yourself to do some more advanced binding, e.g. using some extensions. - The flag is meaningful only with functions that bind by default: vmaCreateBuffer(), vmaCreateImage(). - Otherwise it is ignored. - */ - VMA_ALLOCATION_CREATE_DONT_BIND_BIT = 0x00000080, - /** Create allocation only if additional device memory required for it, if any, won't exceed - memory budget. Otherwise return `VK_ERROR_OUT_OF_DEVICE_MEMORY`. - */ - VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT = 0x00000100, - - /** Allocation strategy that chooses smallest possible free range for the - allocation. - */ - VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT = 0x00010000, - /** Allocation strategy that chooses biggest possible free range for the - allocation. - */ - VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT = 0x00020000, - /** Allocation strategy that chooses first suitable free range for the - allocation. - - "First" doesn't necessarily means the one with smallest offset in memory, - but rather the one that is easiest and fastest to find. - */ - VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT = 0x00040000, - - /** Allocation strategy that tries to minimize memory usage. - */ - VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT = VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT, - /** Allocation strategy that tries to minimize allocation time. - */ - VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT = VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT, - /** Allocation strategy that tries to minimize memory fragmentation. - */ - VMA_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT = VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT, - - /** A bit mask to extract only `STRATEGY` bits from entire set of flags. - */ - VMA_ALLOCATION_CREATE_STRATEGY_MASK = - VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT | - VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT | - VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT, - - VMA_ALLOCATION_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VmaAllocationCreateFlagBits; -typedef VkFlags VmaAllocationCreateFlags; - typedef struct VmaAllocationCreateInfo { /// Use #VmaAllocationCreateFlagBits enum. @@ -1035,6 +1269,394 @@ typedef struct VmaAllocationCreateInfo float priority; } VmaAllocationCreateInfo; +/// Describes parameter of created #VmaPool. +typedef struct VmaPoolCreateInfo +{ + /** \brief Vulkan memory type index to allocate this pool from. + */ + uint32_t memoryTypeIndex; + /** \brief Use combination of #VmaPoolCreateFlagBits. + */ + VmaPoolCreateFlags flags; + /** \brief Size of a single `VkDeviceMemory` block to be allocated as part of this pool, in bytes. Optional. + + Specify nonzero to set explicit, constant size of memory blocks used by this + pool. + + Leave 0 to use default and let the library manage block sizes automatically. + Sizes of particular blocks may vary. + In this case, the pool will also support dedicated allocations. + */ + VkDeviceSize blockSize; + /** \brief Minimum number of blocks to be always allocated in this pool, even if they stay empty. + + Set to 0 to have no preallocated blocks and allow the pool be completely empty. + */ + size_t minBlockCount; + /** \brief Maximum number of blocks that can be allocated in this pool. Optional. + + Set to 0 to use default, which is `SIZE_MAX`, which means no limit. + + Set to same value as VmaPoolCreateInfo::minBlockCount to have fixed amount of memory allocated + throughout whole lifetime of this pool. + */ + size_t maxBlockCount; + /** \brief A floating-point value between 0 and 1, indicating the priority of the allocations in this pool relative to other memory allocations. + + It is used only when #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT flag was used during creation of the #VmaAllocator object. + Otherwise, this variable is ignored. + */ + float priority; + /** \brief Additional minimum alignment to be used for all allocations created from this pool. Can be 0. + + Leave 0 (default) not to impose any additional alignment. If not 0, it must be a power of two. + It can be useful in cases where alignment returned by Vulkan by functions like `vkGetBufferMemoryRequirements` is not enough, + e.g. when doing interop with OpenGL. + */ + VkDeviceSize minAllocationAlignment; + /** \brief Additional `pNext` chain to be attached to `VkMemoryAllocateInfo` used for every allocation made by this pool. Optional. + + Optional, can be null. If not null, it must point to a `pNext` chain of structures that can be attached to `VkMemoryAllocateInfo`. + It can be useful for special needs such as adding `VkExportMemoryAllocateInfoKHR`. + Structures pointed by this member must remain alive and unchanged for the whole lifetime of the custom pool. + + Please note that some structures, e.g. `VkMemoryPriorityAllocateInfoEXT`, `VkMemoryDedicatedAllocateInfoKHR`, + can be attached automatically by this library when using other, more convenient of its features. + */ + void* VMA_NULLABLE pMemoryAllocateNext; +} VmaPoolCreateInfo; + +/** @} */ + +/** +\addtogroup group_alloc +@{ +*/ + +/// Parameters of #VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo(). +typedef struct VmaAllocationInfo +{ + /** \brief Memory type index that this allocation was allocated from. + + It never changes. + */ + uint32_t memoryType; + /** \brief Handle to Vulkan memory object. + + Same memory object can be shared by multiple allocations. + + It can change after the allocation is moved during \ref defragmentation. + */ + VkDeviceMemory VMA_NULLABLE_NON_DISPATCHABLE deviceMemory; + /** \brief Offset in `VkDeviceMemory` object to the beginning of this allocation, in bytes. `(deviceMemory, offset)` pair is unique to this allocation. + + You usually don't need to use this offset. If you create a buffer or an image together with the allocation using e.g. function + vmaCreateBuffer(), vmaCreateImage(), functions that operate on these resources refer to the beginning of the buffer or image, + not entire device memory block. Functions like vmaMapMemory(), vmaBindBufferMemory() also refer to the beginning of the allocation + and apply this offset automatically. + + It can change after the allocation is moved during \ref defragmentation. + */ + VkDeviceSize offset; + /** \brief Size of this allocation, in bytes. + + It never changes. + + \note Allocation size returned in this variable may be greater than the size + requested for the resource e.g. as `VkBufferCreateInfo::size`. Whole size of the + allocation is accessible for operations on memory e.g. using a pointer after + mapping with vmaMapMemory(), but operations on the resource e.g. using + `vkCmdCopyBuffer` must be limited to the size of the resource. + */ + VkDeviceSize size; + /** \brief Pointer to the beginning of this allocation as mapped data. + + If the allocation hasn't been mapped using vmaMapMemory() and hasn't been + created with #VMA_ALLOCATION_CREATE_MAPPED_BIT flag, this value is null. + + It can change after call to vmaMapMemory(), vmaUnmapMemory(). + It can also change after the allocation is moved during \ref defragmentation. + */ + void* VMA_NULLABLE pMappedData; + /** \brief Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vmaSetAllocationUserData(). + + It can change after call to vmaSetAllocationUserData() for this allocation. + */ + void* VMA_NULLABLE pUserData; + /** \brief Custom allocation name that was set with vmaSetAllocationName(). + + It can change after call to vmaSetAllocationName() for this allocation. + + Another way to set custom name is to pass it in VmaAllocationCreateInfo::pUserData with + additional flag #VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT set [DEPRECATED]. + */ + const char* VMA_NULLABLE pName; +} VmaAllocationInfo; + +/** \brief Parameters for defragmentation. + +To be used with function vmaBeginDefragmentation(). +*/ +typedef struct VmaDefragmentationInfo +{ + /// \brief Use combination of #VmaDefragmentationFlagBits. + VmaDefragmentationFlags flags; + /** \brief Custom pool to be defragmented. + + If null then default pools will undergo defragmentation process. + */ + VmaPool VMA_NULLABLE pool; + /** \brief Maximum numbers of bytes that can be copied during single pass, while moving allocations to different places. + + `0` means no limit. + */ + VkDeviceSize maxBytesPerPass; + /** \brief Maximum number of allocations that can be moved during single pass to a different place. + + `0` means no limit. + */ + uint32_t maxAllocationsPerPass; +} VmaDefragmentationInfo; + +/// Single move of an allocation to be done for defragmentation. +typedef struct VmaDefragmentationMove +{ + /// Operation to be performed on the allocation by vmaEndDefragmentationPass(). Default value is #VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY. You can modify it. + VmaDefragmentationMoveOperation operation; + /// Allocation that should be moved. + VmaAllocation VMA_NOT_NULL srcAllocation; + /** \brief Temporary allocation pointing to destination memory that will replace `srcAllocation`. + + \warning Do not store this allocation in your data structures! It exists only temporarily, for the duration of the defragmentation pass, + to be used for binding new buffer/image to the destination memory using e.g. vmaBindBufferMemory(). + vmaEndDefragmentationPass() will destroy it and make `srcAllocation` point to this memory. + */ + VmaAllocation VMA_NOT_NULL dstTmpAllocation; +} VmaDefragmentationMove; + +/** \brief Parameters for incremental defragmentation steps. + +To be used with function vmaBeginDefragmentationPass(). +*/ +typedef struct VmaDefragmentationPassMoveInfo +{ + /// Number of elements in the `pMoves` array. + uint32_t moveCount; + /** \brief Array of moves to be performed by the user in the current defragmentation pass. + + Pointer to an array of `moveCount` elements, owned by VMA, created in vmaBeginDefragmentationPass(), destroyed in vmaEndDefragmentationPass(). + + For each element, you should: + + 1. Create a new buffer/image in the place pointed by VmaDefragmentationMove::dstMemory + VmaDefragmentationMove::dstOffset. + 2. Copy data from the VmaDefragmentationMove::srcAllocation e.g. using `vkCmdCopyBuffer`, `vkCmdCopyImage`. + 3. Make sure these commands finished executing on the GPU. + 4. Destroy the old buffer/image. + + Only then you can finish defragmentation pass by calling vmaEndDefragmentationPass(). + After this call, the allocation will point to the new place in memory. + + Alternatively, if you cannot move specific allocation, you can set VmaDefragmentationMove::operation to #VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE. + + Alternatively, if you decide you want to completely remove the allocation: + + 1. Destroy its buffer/image. + 2. Set VmaDefragmentationMove::operation to #VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY. + + Then, after vmaEndDefragmentationPass() the allocation will be freed. + */ + VmaDefragmentationMove* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(moveCount) pMoves; +} VmaDefragmentationPassMoveInfo; + +/// Statistics returned for defragmentation process in function vmaEndDefragmentation(). +typedef struct VmaDefragmentationStats +{ + /// Total number of bytes that have been copied while moving allocations to different places. + VkDeviceSize bytesMoved; + /// Total number of bytes that have been released to the system by freeing empty `VkDeviceMemory` objects. + VkDeviceSize bytesFreed; + /// Number of allocations that have been moved to different places. + uint32_t allocationsMoved; + /// Number of empty `VkDeviceMemory` objects that have been released to the system. + uint32_t deviceMemoryBlocksFreed; +} VmaDefragmentationStats; + +/** @} */ + +/** +\addtogroup group_virtual +@{ +*/ + +/// Parameters of created #VmaVirtualBlock object to be passed to vmaCreateVirtualBlock(). +typedef struct VmaVirtualBlockCreateInfo +{ + /** \brief Total size of the virtual block. + + Sizes can be expressed in bytes or any units you want as long as you are consistent in using them. + For example, if you allocate from some array of structures, 1 can mean single instance of entire structure. + */ + VkDeviceSize size; + + /** \brief Use combination of #VmaVirtualBlockCreateFlagBits. + */ + VmaVirtualBlockCreateFlags flags; + + /** \brief Custom CPU memory allocation callbacks. Optional. + + Optional, can be null. When specified, they will be used for all CPU-side memory allocations. + */ + const VkAllocationCallbacks* VMA_NULLABLE pAllocationCallbacks; +} VmaVirtualBlockCreateInfo; + +/// Parameters of created virtual allocation to be passed to vmaVirtualAllocate(). +typedef struct VmaVirtualAllocationCreateInfo +{ + /** \brief Size of the allocation. + + Cannot be zero. + */ + VkDeviceSize size; + /** \brief Required alignment of the allocation. Optional. + + Must be power of two. Special value 0 has the same meaning as 1 - means no special alignment is required, so allocation can start at any offset. + */ + VkDeviceSize alignment; + /** \brief Use combination of #VmaVirtualAllocationCreateFlagBits. + */ + VmaVirtualAllocationCreateFlags flags; + /** \brief Custom pointer to be associated with the allocation. Optional. + + It can be any value and can be used for user-defined purposes. It can be fetched or changed later. + */ + void* VMA_NULLABLE pUserData; +} VmaVirtualAllocationCreateInfo; + +/// Parameters of an existing virtual allocation, returned by vmaGetVirtualAllocationInfo(). +typedef struct VmaVirtualAllocationInfo +{ + /** \brief Offset of the allocation. + + Offset at which the allocation was made. + */ + VkDeviceSize offset; + /** \brief Size of the allocation. + + Same value as passed in VmaVirtualAllocationCreateInfo::size. + */ + VkDeviceSize size; + /** \brief Custom pointer associated with the allocation. + + Same value as passed in VmaVirtualAllocationCreateInfo::pUserData or to vmaSetVirtualAllocationUserData(). + */ + void* VMA_NULLABLE pUserData; +} VmaVirtualAllocationInfo; + +/** @} */ + +#endif // _VMA_DATA_TYPES_DECLARATIONS + +#ifndef _VMA_FUNCTION_HEADERS + +/** +\addtogroup group_init +@{ +*/ + +/// Creates #VmaAllocator object. +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator( + const VmaAllocatorCreateInfo* VMA_NOT_NULL pCreateInfo, + VmaAllocator VMA_NULLABLE* VMA_NOT_NULL pAllocator); + +/// Destroys allocator object. +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyAllocator( + VmaAllocator VMA_NULLABLE allocator); + +/** \brief Returns information about existing #VmaAllocator object - handle to Vulkan device etc. + +It might be useful if you want to keep just the #VmaAllocator handle and fetch other required handles to +`VkPhysicalDevice`, `VkDevice` etc. every time using this function. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocatorInfo( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocatorInfo* VMA_NOT_NULL pAllocatorInfo); + +/** +PhysicalDeviceProperties are fetched from physicalDevice by the allocator. +You can access it here, without fetching it again on your own. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetPhysicalDeviceProperties( + VmaAllocator VMA_NOT_NULL allocator, + const VkPhysicalDeviceProperties* VMA_NULLABLE* VMA_NOT_NULL ppPhysicalDeviceProperties); + +/** +PhysicalDeviceMemoryProperties are fetched from physicalDevice by the allocator. +You can access it here, without fetching it again on your own. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryProperties( + VmaAllocator VMA_NOT_NULL allocator, + const VkPhysicalDeviceMemoryProperties* VMA_NULLABLE* VMA_NOT_NULL ppPhysicalDeviceMemoryProperties); + +/** +\brief Given Memory Type Index, returns Property Flags of this memory type. + +This is just a convenience function. Same information can be obtained using +vmaGetMemoryProperties(). +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetMemoryTypeProperties( + VmaAllocator VMA_NOT_NULL allocator, + uint32_t memoryTypeIndex, + VkMemoryPropertyFlags* VMA_NOT_NULL pFlags); + +/** \brief Sets index of the current frame. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaSetCurrentFrameIndex( + VmaAllocator VMA_NOT_NULL allocator, + uint32_t frameIndex); + +/** @} */ + +/** +\addtogroup group_stats +@{ +*/ + +/** \brief Retrieves statistics from current state of the Allocator. + +This function is called "calculate" not "get" because it has to traverse all +internal data structures, so it may be quite slow. Use it for debugging purposes. +For faster but more brief statistics suitable to be called every frame or every allocation, +use vmaGetHeapBudgets(). + +Note that when using allocator from multiple threads, returned information may immediately +become outdated. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaCalculateStatistics( + VmaAllocator VMA_NOT_NULL allocator, + VmaTotalStatistics* VMA_NOT_NULL pStats); + +/** \brief Retrieves information about current memory usage and budget for all memory heaps. + +\param allocator +\param[out] pBudgets Must point to array with number of elements at least equal to number of memory heaps in physical device used. + +This function is called "get" not "calculate" because it is very fast, suitable to be called +every frame or every allocation. For more detailed statistics use vmaCalculateStatistics(). + +Note that when using allocator from multiple threads, returned information may immediately +become outdated. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetHeapBudgets( + VmaAllocator VMA_NOT_NULL allocator, + VmaBudget* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL("VkPhysicalDeviceMemoryProperties::memoryHeapCount") pBudgets); + +/** @} */ + +/** +\addtogroup group_alloc +@{ +*/ + /** \brief Helps to find memoryTypeIndex, given memoryTypeBits and VmaAllocationCreateInfo. @@ -1062,12 +1684,6 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndex( It can be useful e.g. to determine value to be used as VmaPoolCreateInfo::memoryTypeIndex. It internally creates a temporary, dummy buffer that never has memory bound. -It is just a convenience function, equivalent to calling: - -- `vkCreateBuffer` -- `vkGetBufferMemoryRequirements` -- `vmaFindMemoryTypeIndex` -- `vkDestroyBuffer` */ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo( VmaAllocator VMA_NOT_NULL allocator, @@ -1080,12 +1696,6 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo( It can be useful e.g. to determine value to be used as VmaPoolCreateInfo::memoryTypeIndex. It internally creates a temporary, dummy image that never has memory bound. -It is just a convenience function, equivalent to calling: - -- `vkCreateImage` -- `vkGetImageMemoryRequirements` -- `vmaFindMemoryTypeIndex` -- `vkDestroyImage` */ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo( VmaAllocator VMA_NOT_NULL allocator, @@ -1093,172 +1703,16 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo( const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo, uint32_t* VMA_NOT_NULL pMemoryTypeIndex); -/// Flags to be passed as VmaPoolCreateInfo::flags. -typedef enum VmaPoolCreateFlagBits { - /** \brief Use this flag if you always allocate only buffers and linear images or only optimal images out of this pool and so Buffer-Image Granularity can be ignored. - - This is an optional optimization flag. - - If you always allocate using vmaCreateBuffer(), vmaCreateImage(), - vmaAllocateMemoryForBuffer(), then you don't need to use it because allocator - knows exact type of your allocations so it can handle Buffer-Image Granularity - in the optimal way. - - If you also allocate using vmaAllocateMemoryForImage() or vmaAllocateMemory(), - exact type of such allocations is not known, so allocator must be conservative - in handling Buffer-Image Granularity, which can lead to suboptimal allocation - (wasted memory). In that case, if you can make sure you always allocate only - buffers and linear images or only optimal images out of this pool, use this flag - to make allocator disregard Buffer-Image Granularity and so make allocations - faster and more optimal. - */ - VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT = 0x00000002, - - /** \brief Enables alternative, linear allocation algorithm in this pool. - - Specify this flag to enable linear allocation algorithm, which always creates - new allocations after last one and doesn't reuse space from allocations freed in - between. It trades memory consumption for simplified algorithm and data - structure, which has better performance and uses less memory for metadata. - - By using this flag, you can achieve behavior of free-at-once, stack, - ring buffer, and double stack. For details, see documentation chapter - \ref linear_algorithm. - - When using this flag, you must specify VmaPoolCreateInfo::maxBlockCount == 1 (or 0 for default). - - For more details, see [Linear allocation algorithm](@ref linear_algorithm). - */ - VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT = 0x00000004, - - /** \brief Enables alternative, buddy allocation algorithm in this pool. - - It operates on a tree of blocks, each having size that is a power of two and - a half of its parent's size. Comparing to default algorithm, this one provides - faster allocation and deallocation and decreased external fragmentation, - at the expense of more memory wasted (internal fragmentation). - - For more details, see [Buddy allocation algorithm](@ref buddy_algorithm). - */ - VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT = 0x00000008, - - /** Bit mask to extract only `ALGORITHM` bits from entire set of flags. - */ - VMA_POOL_CREATE_ALGORITHM_MASK = - VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT | - VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT, - - VMA_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VmaPoolCreateFlagBits; -typedef VkFlags VmaPoolCreateFlags; - -/** \brief Describes parameter of created #VmaPool. -*/ -typedef struct VmaPoolCreateInfo { - /** \brief Vulkan memory type index to allocate this pool from. - */ - uint32_t memoryTypeIndex; - /** \brief Use combination of #VmaPoolCreateFlagBits. - */ - VmaPoolCreateFlags flags; - /** \brief Size of a single `VkDeviceMemory` block to be allocated as part of this pool, in bytes. Optional. - - Specify nonzero to set explicit, constant size of memory blocks used by this - pool. - - Leave 0 to use default and let the library manage block sizes automatically. - Sizes of particular blocks may vary. - */ - VkDeviceSize blockSize; - /** \brief Minimum number of blocks to be always allocated in this pool, even if they stay empty. - - Set to 0 to have no preallocated blocks and allow the pool be completely empty. - */ - size_t minBlockCount; - /** \brief Maximum number of blocks that can be allocated in this pool. Optional. - - Set to 0 to use default, which is `SIZE_MAX`, which means no limit. - - Set to same value as VmaPoolCreateInfo::minBlockCount to have fixed amount of memory allocated - throughout whole lifetime of this pool. - */ - size_t maxBlockCount; - /** \brief Maximum number of additional frames that are in use at the same time as current frame. - - This value is used only when you make allocations with - #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag. Such allocation cannot become - lost if allocation.lastUseFrameIndex >= allocator.currentFrameIndex - frameInUseCount. - - For example, if you double-buffer your command buffers, so resources used for - rendering in previous frame may still be in use by the GPU at the moment you - allocate resources needed for the current frame, set this value to 1. - - If you want to allow any allocations other than used in the current frame to - become lost, set this value to 0. - */ - uint32_t frameInUseCount; - /** \brief A floating-point value between 0 and 1, indicating the priority of the allocations in this pool relative to other memory allocations. - - It is used only when #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT flag was used during creation of the #VmaAllocator object. - Otherwise, this variable is ignored. - */ - float priority; - /** \brief Additional minimum alignment to be used for all allocations created from this pool. Can be 0. - - Leave 0 (default) not to impose any additional alignment. If not 0, it must be a power of two. - It can be useful in cases where alignment returned by Vulkan by functions like `vkGetBufferMemoryRequirements` is not enough, - e.g. when doing interop with OpenGL. - */ - VkDeviceSize minAllocationAlignment; - /** \brief Additional `pNext` chain to be attached to `VkMemoryAllocateInfo` used for every allocation made by this pool. Optional. - - Optional, can be null. If not null, it must point to a `pNext` chain of structures that can be attached to `VkMemoryAllocateInfo`. - It can be useful for special needs such as adding `VkExportMemoryAllocateInfoKHR`. - Structures pointed by this member must remain alive and unchanged for the whole lifetime of the custom pool. - - Please note that some structures, e.g. `VkMemoryPriorityAllocateInfoEXT`, `VkMemoryDedicatedAllocateInfoKHR`, - can be attached automatically by this library when using other, more convenient of its features. - */ - void* VMA_NULLABLE pMemoryAllocateNext; -} VmaPoolCreateInfo; - -/** \brief Describes parameter of existing #VmaPool. -*/ -typedef struct VmaPoolStats { - /** \brief Total amount of `VkDeviceMemory` allocated from Vulkan for this pool, in bytes. - */ - VkDeviceSize size; - /** \brief Total number of bytes in the pool not used by any #VmaAllocation. - */ - VkDeviceSize unusedSize; - /** \brief Number of #VmaAllocation objects created from this pool that were not destroyed or lost. - */ - size_t allocationCount; - /** \brief Number of continuous memory ranges in the pool not used by any #VmaAllocation. - */ - size_t unusedRangeCount; - /** \brief Size of the largest continuous free memory region available for new allocation. - - Making a new allocation of that size is not guaranteed to succeed because of - possible additional margin required to respect alignment and buffer/image - granularity. - */ - VkDeviceSize unusedRangeSizeMax; - /** \brief Number of `VkDeviceMemory` blocks allocated for this pool. - */ - size_t blockCount; -} VmaPoolStats; - /** \brief Allocates Vulkan device memory and creates #VmaPool object. -@param allocator Allocator object. -@param pCreateInfo Parameters of pool to create. -@param[out] pPool Handle to created pool. +\param allocator Allocator object. +\param pCreateInfo Parameters of pool to create. +\param[out] pPool Handle to created pool. */ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreatePool( VmaAllocator VMA_NOT_NULL allocator, const VmaPoolCreateInfo* VMA_NOT_NULL pCreateInfo, - VmaPool VMA_NULLABLE * VMA_NOT_NULL pPool); + VmaPool VMA_NULLABLE* VMA_NOT_NULL pPool); /** \brief Destroys #VmaPool object and frees Vulkan device memory. */ @@ -1266,27 +1720,41 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyPool( VmaAllocator VMA_NOT_NULL allocator, VmaPool VMA_NULLABLE pool); +/** @} */ + +/** +\addtogroup group_stats +@{ +*/ + /** \brief Retrieves statistics of existing #VmaPool object. -@param allocator Allocator object. -@param pool Pool object. -@param[out] pPoolStats Statistics of specified pool. +\param allocator Allocator object. +\param pool Pool object. +\param[out] pPoolStats Statistics of specified pool. */ -VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolStats( +VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolStatistics( VmaAllocator VMA_NOT_NULL allocator, VmaPool VMA_NOT_NULL pool, - VmaPoolStats* VMA_NOT_NULL pPoolStats); + VmaStatistics* VMA_NOT_NULL pPoolStats); -/** \brief Marks all allocations in given pool as lost if they are not used in current frame or VmaPoolCreateInfo::frameInUseCount back from now. +/** \brief Retrieves detailed statistics of existing #VmaPool object. -@param allocator Allocator object. -@param pool Pool. -@param[out] pLostAllocationCount Number of allocations marked as lost. Optional - pass null if you don't need this information. +\param allocator Allocator object. +\param pool Pool object. +\param[out] pPoolStats Statistics of specified pool. */ -VMA_CALL_PRE void VMA_CALL_POST vmaMakePoolAllocationsLost( +VMA_CALL_PRE void VMA_CALL_POST vmaCalculatePoolStatistics( VmaAllocator VMA_NOT_NULL allocator, VmaPool VMA_NOT_NULL pool, - size_t* VMA_NULLABLE pLostAllocationCount); + VmaDetailedStatistics* VMA_NOT_NULL pPoolStats); + +/** @} */ + +/** +\addtogroup group_alloc +@{ +*/ /** \brief Checks magic number in margins around all allocations in given memory pool in search for corruptions. @@ -1302,7 +1770,9 @@ Possible return values: `VMA_ASSERT` is also fired in that case. - Other value: Error returned by Vulkan, e.g. memory mapping failure. */ -VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckPoolCorruption(VmaAllocator VMA_NOT_NULL allocator, VmaPool VMA_NOT_NULL pool); +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckPoolCorruption( + VmaAllocator VMA_NOT_NULL allocator, + VmaPool VMA_NOT_NULL pool); /** \brief Retrieves name of a custom pool. @@ -1313,7 +1783,7 @@ destroyed or its name is changed using vmaSetPoolName(). VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolName( VmaAllocator VMA_NOT_NULL allocator, VmaPool VMA_NOT_NULL pool, - const char* VMA_NULLABLE * VMA_NOT_NULL ppName); + const char* VMA_NULLABLE* VMA_NOT_NULL ppName); /** \brief Sets name of a custom pool. @@ -1325,93 +1795,13 @@ VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName( VmaPool VMA_NOT_NULL pool, const char* VMA_NULLABLE pName); -/** \struct VmaAllocation -\brief Represents single memory allocation. - -It may be either dedicated block of `VkDeviceMemory` or a specific region of a bigger block of this type -plus unique offset. - -There are multiple ways to create such object. -You need to fill structure VmaAllocationCreateInfo. -For more information see [Choosing memory type](@ref choosing_memory_type). - -Although the library provides convenience functions that create Vulkan buffer or image, -allocate memory for it and bind them together, -binding of the allocation to a buffer or an image is out of scope of the allocation itself. -Allocation object can exist without buffer/image bound, -binding can be done manually by the user, and destruction of it can be done -independently of destruction of the allocation. - -The object also remembers its size and some other information. -To retrieve this information, use function vmaGetAllocationInfo() and inspect -returned structure VmaAllocationInfo. - -Some kinds allocations can be in lost state. -For more information, see [Lost allocations](@ref lost_allocations). -*/ -VK_DEFINE_HANDLE(VmaAllocation) - -/** \brief Parameters of #VmaAllocation objects, that can be retrieved using function vmaGetAllocationInfo(). -*/ -typedef struct VmaAllocationInfo { - /** \brief Memory type index that this allocation was allocated from. - - It never changes. - */ - uint32_t memoryType; - /** \brief Handle to Vulkan memory object. - - Same memory object can be shared by multiple allocations. - - It can change after call to vmaDefragment() if this allocation is passed to the function, or if allocation is lost. - - If the allocation is lost, it is equal to `VK_NULL_HANDLE`. - */ - VkDeviceMemory VMA_NULLABLE_NON_DISPATCHABLE deviceMemory; - /** \brief Offset in `VkDeviceMemory` object to the beginning of this allocation, in bytes. `(deviceMemory, offset)` pair is unique to this allocation. - - You usually don't need to use this offset. If you create a buffer or an image together with the allocation using e.g. function - vmaCreateBuffer(), vmaCreateImage(), functions that operate on these resources refer to the beginning of the buffer or image, - not entire device memory block. Functions like vmaMapMemory(), vmaBindBufferMemory() also refer to the beginning of the allocation - and apply this offset automatically. - - It can change after call to vmaDefragment() if this allocation is passed to the function, or if allocation is lost. - */ - VkDeviceSize offset; - /** \brief Size of this allocation, in bytes. - - It never changes, unless allocation is lost. - - \note Allocation size returned in this variable may be greater than the size - requested for the resource e.g. as `VkBufferCreateInfo::size`. Whole size of the - allocation is accessible for operations on memory e.g. using a pointer after - mapping with vmaMapMemory(), but operations on the resource e.g. using - `vkCmdCopyBuffer` must be limited to the size of the resource. - */ - VkDeviceSize size; - /** \brief Pointer to the beginning of this allocation as mapped data. - - If the allocation hasn't been mapped using vmaMapMemory() and hasn't been - created with #VMA_ALLOCATION_CREATE_MAPPED_BIT flag, this value is null. - - It can change after call to vmaMapMemory(), vmaUnmapMemory(). - It can also change after call to vmaDefragment() if this allocation is passed to the function. - */ - void* VMA_NULLABLE pMappedData; - /** \brief Custom general-purpose pointer that was passed as VmaAllocationCreateInfo::pUserData or set using vmaSetAllocationUserData(). - - It can change after call to vmaSetAllocationUserData() for this allocation. - */ - void* VMA_NULLABLE pUserData; -} VmaAllocationInfo; - /** \brief General purpose memory allocation. -@param allocator -@param pVkMemoryRequirements -@param pCreateInfo -@param[out] pAllocation Handle to allocated memory. -@param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo(). +\param allocator +\param pVkMemoryRequirements +\param pCreateInfo +\param[out] pAllocation Handle to allocated memory. +\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo(). You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages(). @@ -1422,17 +1812,17 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory( VmaAllocator VMA_NOT_NULL allocator, const VkMemoryRequirements* VMA_NOT_NULL pVkMemoryRequirements, const VmaAllocationCreateInfo* VMA_NOT_NULL pCreateInfo, - VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation, VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); /** \brief General purpose memory allocation for multiple allocation objects at once. -@param allocator Allocator object. -@param pVkMemoryRequirements Memory requirements for each allocation. -@param pCreateInfo Creation parameters for each alloction. -@param allocationCount Number of allocations to make. -@param[out] pAllocations Pointer to array that will be filled with handles to created allocations. -@param[out] pAllocationInfo Optional. Pointer to array that will be filled with parameters of created allocations. +\param allocator Allocator object. +\param pVkMemoryRequirements Memory requirements for each allocation. +\param pCreateInfo Creation parameters for each allocation. +\param allocationCount Number of allocations to make. +\param[out] pAllocations Pointer to array that will be filled with handles to created allocations. +\param[out] pAllocationInfo Optional. Pointer to array that will be filled with parameters of created allocations. You should free the memory using vmaFreeMemory() or vmaFreeMemoryPages(). @@ -1449,31 +1839,49 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryPages( const VkMemoryRequirements* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pVkMemoryRequirements, const VmaAllocationCreateInfo* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pCreateInfo, size_t allocationCount, - VmaAllocation VMA_NULLABLE * VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations, + VmaAllocation VMA_NULLABLE* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations, VmaAllocationInfo* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocationInfo); -/** -@param allocator -@param buffer -@param pCreateInfo -@param[out] pAllocation Handle to allocated memory. -@param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo(). +/** \brief Allocates memory suitable for given `VkBuffer`. -You should free the memory using vmaFreeMemory(). +\param allocator +\param buffer +\param pCreateInfo +\param[out] pAllocation Handle to allocated memory. +\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo(). + +It only creates #VmaAllocation. To bind the memory to the buffer, use vmaBindBufferMemory(). + +This is a special-purpose function. In most cases you should use vmaCreateBuffer(). + +You must free the allocation using vmaFreeMemory() when no longer needed. */ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForBuffer( VmaAllocator VMA_NOT_NULL allocator, VkBuffer VMA_NOT_NULL_NON_DISPATCHABLE buffer, const VmaAllocationCreateInfo* VMA_NOT_NULL pCreateInfo, - VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation, VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); -/// Function similar to vmaAllocateMemoryForBuffer(). +/** \brief Allocates memory suitable for given `VkImage`. + +\param allocator +\param image +\param pCreateInfo +\param[out] pAllocation Handle to allocated memory. +\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo(). + +It only creates #VmaAllocation. To bind the memory to the buffer, use vmaBindImageMemory(). + +This is a special-purpose function. In most cases you should use vmaCreateImage(). + +You must free the allocation using vmaFreeMemory() when no longer needed. +*/ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForImage( VmaAllocator VMA_NOT_NULL allocator, VkImage VMA_NOT_NULL_NON_DISPATCHABLE image, const VmaAllocationCreateInfo* VMA_NOT_NULL pCreateInfo, - VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation, VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); /** \brief Frees memory previously allocated using vmaAllocateMemory(), vmaAllocateMemoryForBuffer(), or vmaAllocateMemoryForImage(). @@ -1497,58 +1905,27 @@ Passing `VK_NULL_HANDLE` as elements of `pAllocations` array is valid. Such entr VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemoryPages( VmaAllocator VMA_NOT_NULL allocator, size_t allocationCount, - const VmaAllocation VMA_NULLABLE * VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations); + const VmaAllocation VMA_NULLABLE* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations); -/** \brief Returns current information about specified allocation and atomically marks it as used in current frame. +/** \brief Returns current information about specified allocation. Current paramteres of given allocation are returned in `pAllocationInfo`. -This function also atomically "touches" allocation - marks it as used in current frame, -just like vmaTouchAllocation(). -If the allocation is in lost state, `pAllocationInfo->deviceMemory == VK_NULL_HANDLE`. - -Although this function uses atomics and doesn't lock any mutex, so it should be quite efficient, -you can avoid calling it too often. - -- You can retrieve same VmaAllocationInfo structure while creating your resource, from function - vmaCreateBuffer(), vmaCreateImage(). You can remember it if you are sure parameters don't change - (e.g. due to defragmentation or allocation becoming lost). -- If you just want to check if allocation is not lost, vmaTouchAllocation() will work faster. +Although this function doesn't lock any mutex, so it should be quite efficient, +you should avoid calling it too often. +You can retrieve same VmaAllocationInfo structure while creating your resource, from function +vmaCreateBuffer(), vmaCreateImage(). You can remember it if you are sure parameters don't change +(e.g. due to defragmentation). */ VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationInfo( VmaAllocator VMA_NOT_NULL allocator, VmaAllocation VMA_NOT_NULL allocation, VmaAllocationInfo* VMA_NOT_NULL pAllocationInfo); -/** \brief Returns `VK_TRUE` if allocation is not lost and atomically marks it as used in current frame. - -If the allocation has been created with #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag, -this function returns `VK_TRUE` if it is not in lost state, so it can still be used. -It then also atomically "touches" the allocation - marks it as used in current frame, -so that you can be sure it won't become lost in current frame or next `frameInUseCount` frames. - -If the allocation is in lost state, the function returns `VK_FALSE`. -Memory of such allocation, as well as buffer or image bound to it, should not be used. -Lost allocation and the buffer/image still need to be destroyed. - -If the allocation has been created without #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag, -this function always returns `VK_TRUE`. -*/ -VMA_CALL_PRE VkBool32 VMA_CALL_POST vmaTouchAllocation( - VmaAllocator VMA_NOT_NULL allocator, - VmaAllocation VMA_NOT_NULL allocation); - /** \brief Sets pUserData in given allocation to new value. -If the allocation was created with VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT, -pUserData must be either null, or pointer to a null-terminated string. The function -makes local copy of the string and sets it as allocation's `pUserData`. String -passed as pUserData doesn't need to be valid for whole lifetime of the allocation - -you can free it after this call. String previously pointed by allocation's -pUserData is freed from memory. - -If the flag was not used, the value of pointer `pUserData` is just copied to -allocation's `pUserData`. It is opaque, so you can use it however you want - e.g. +The value of pointer `pUserData` is copied to allocation's `pUserData`. +It is opaque, so you can use it however you want - e.g. as a pointer, ordinal number or some handle to you own data. */ VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationUserData( @@ -1556,27 +1933,40 @@ VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationUserData( VmaAllocation VMA_NOT_NULL allocation, void* VMA_NULLABLE pUserData); -/** \brief Creates new allocation that is in lost state from the beginning. +/** \brief Sets pName in given allocation to new value. -It can be useful if you need a dummy, non-null allocation. - -You still need to destroy created object using vmaFreeMemory(). - -Returned allocation is not tied to any specific memory pool or memory type and -not bound to any image or buffer. It has size = 0. It cannot be turned into -a real, non-empty allocation. +`pName` must be either null, or pointer to a null-terminated string. The function +makes local copy of the string and sets it as allocation's `pName`. String +passed as pName doesn't need to be valid for whole lifetime of the allocation - +you can free it after this call. String previously pointed by allocation's +`pName` is freed from memory. */ -VMA_CALL_PRE void VMA_CALL_POST vmaCreateLostAllocation( +VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationName( VmaAllocator VMA_NOT_NULL allocator, - VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation); + VmaAllocation VMA_NOT_NULL allocation, + const char* VMA_NULLABLE pName); + +/** +\brief Given an allocation, returns Property Flags of its memory type. + +This is just a convenience function. Same information can be obtained using +vmaGetAllocationInfo() + vmaGetMemoryProperties(). +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationMemoryProperties( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + VkMemoryPropertyFlags* VMA_NOT_NULL pFlags); /** \brief Maps memory represented by given allocation and returns pointer to it. Maps memory represented by given allocation to make it accessible to CPU code. When succeeded, `*ppData` contains pointer to first byte of this memory. -If the allocation is part of bigger `VkDeviceMemory` block, the pointer is -correctly offsetted to the beginning of region assigned to this particular -allocation. + +\warning +If the allocation is part of a bigger `VkDeviceMemory` block, returned pointer is +correctly offsetted to the beginning of region assigned to this particular allocation. +Unlike the result of `vkMapMemory`, it points to the allocation, not to the beginning of the whole block. +You should not add VmaAllocationInfo::offset to it! Mapping is internally reference-counted and synchronized, so despite raw Vulkan function `vkMapMemory()` cannot be used to map same block of `VkDeviceMemory` @@ -1600,10 +1990,6 @@ vmaMapMemory(). You must not call vmaUnmapMemory() additional time to free the This function fails when used on allocation made in memory type that is not `HOST_VISIBLE`. -This function always fails when called for allocation that was created with -#VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag. Such allocations cannot be -mapped. - This function doesn't automatically flush or invalidate caches. If the allocation is made from a memory types that is not `HOST_COHERENT`, you also need to use vmaInvalidateAllocation() / vmaFlushAllocation(), as required by Vulkan specification. @@ -1611,7 +1997,7 @@ you also need to use vmaInvalidateAllocation() / vmaFlushAllocation(), as requir VMA_CALL_PRE VkResult VMA_CALL_POST vmaMapMemory( VmaAllocator VMA_NOT_NULL allocator, VmaAllocation VMA_NOT_NULL allocation, - void* VMA_NULLABLE * VMA_NOT_NULL ppData); + void* VMA_NULLABLE* VMA_NOT_NULL ppData); /** \brief Unmaps memory represented by given allocation, mapped previously using vmaMapMemory(). @@ -1696,7 +2082,7 @@ called, otherwise `VK_SUCCESS`. VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocations( VmaAllocator VMA_NOT_NULL allocator, uint32_t allocationCount, - const VmaAllocation VMA_NOT_NULL * VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) allocations, + const VmaAllocation VMA_NOT_NULL* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) allocations, const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) offsets, const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) sizes); @@ -1717,14 +2103,14 @@ called, otherwise `VK_SUCCESS`. VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocations( VmaAllocator VMA_NOT_NULL allocator, uint32_t allocationCount, - const VmaAllocation VMA_NOT_NULL * VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) allocations, + const VmaAllocation VMA_NOT_NULL* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) allocations, const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) offsets, const VkDeviceSize* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) sizes); /** \brief Checks magic number in margins around all allocations in given memory types (in both default and custom pools) in search for corruptions. -@param allocator -@param memoryTypeBits Bit mask, where each bit set means that a memory type with that index should be checked. +\param allocator +\param memoryTypeBits Bit mask, where each bit set means that a memory type with that index should be checked. Corruption detection is enabled only when `VMA_DEBUG_DETECT_CORRUPTION` macro is defined to nonzero, `VMA_DEBUG_MARGIN` is defined to nonzero and only for memory types that are @@ -1738,245 +2124,77 @@ Possible return values: `VMA_ASSERT` is also fired in that case. - Other value: Error returned by Vulkan, e.g. memory mapping failure. */ -VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption(VmaAllocator VMA_NOT_NULL allocator, uint32_t memoryTypeBits); - -/** \struct VmaDefragmentationContext -\brief Represents Opaque object that represents started defragmentation process. - -Fill structure #VmaDefragmentationInfo2 and call function vmaDefragmentationBegin() to create it. -Call function vmaDefragmentationEnd() to destroy it. -*/ -VK_DEFINE_HANDLE(VmaDefragmentationContext) - -/// Flags to be used in vmaDefragmentationBegin(). None at the moment. Reserved for future use. -typedef enum VmaDefragmentationFlagBits { - VMA_DEFRAGMENTATION_FLAG_INCREMENTAL = 0x1, - VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF -} VmaDefragmentationFlagBits; -typedef VkFlags VmaDefragmentationFlags; - -/** \brief Parameters for defragmentation. - -To be used with function vmaDefragmentationBegin(). -*/ -typedef struct VmaDefragmentationInfo2 { - /** \brief Reserved for future use. Should be 0. - */ - VmaDefragmentationFlags flags; - /** \brief Number of allocations in `pAllocations` array. - */ - uint32_t allocationCount; - /** \brief Pointer to array of allocations that can be defragmented. - - The array should have `allocationCount` elements. - The array should not contain nulls. - Elements in the array should be unique - same allocation cannot occur twice. - It is safe to pass allocations that are in the lost state - they are ignored. - All allocations not present in this array are considered non-moveable during this defragmentation. - */ - const VmaAllocation VMA_NOT_NULL * VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations; - /** \brief Optional, output. Pointer to array that will be filled with information whether the allocation at certain index has been changed during defragmentation. - - The array should have `allocationCount` elements. - You can pass null if you are not interested in this information. - */ - VkBool32* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocationsChanged; - /** \brief Numer of pools in `pPools` array. - */ - uint32_t poolCount; - /** \brief Either null or pointer to array of pools to be defragmented. - - All the allocations in the specified pools can be moved during defragmentation - and there is no way to check if they were really moved as in `pAllocationsChanged`, - so you must query all the allocations in all these pools for new `VkDeviceMemory` - and offset using vmaGetAllocationInfo() if you might need to recreate buffers - and images bound to them. - - The array should have `poolCount` elements. - The array should not contain nulls. - Elements in the array should be unique - same pool cannot occur twice. - - Using this array is equivalent to specifying all allocations from the pools in `pAllocations`. - It might be more efficient. - */ - const VmaPool VMA_NOT_NULL * VMA_NULLABLE VMA_LEN_IF_NOT_NULL(poolCount) pPools; - /** \brief Maximum total numbers of bytes that can be copied while moving allocations to different places using transfers on CPU side, like `memcpy()`, `memmove()`. - - `VK_WHOLE_SIZE` means no limit. - */ - VkDeviceSize maxCpuBytesToMove; - /** \brief Maximum number of allocations that can be moved to a different place using transfers on CPU side, like `memcpy()`, `memmove()`. - - `UINT32_MAX` means no limit. - */ - uint32_t maxCpuAllocationsToMove; - /** \brief Maximum total numbers of bytes that can be copied while moving allocations to different places using transfers on GPU side, posted to `commandBuffer`. - - `VK_WHOLE_SIZE` means no limit. - */ - VkDeviceSize maxGpuBytesToMove; - /** \brief Maximum number of allocations that can be moved to a different place using transfers on GPU side, posted to `commandBuffer`. - - `UINT32_MAX` means no limit. - */ - uint32_t maxGpuAllocationsToMove; - /** \brief Optional. Command buffer where GPU copy commands will be posted. - - If not null, it must be a valid command buffer handle that supports Transfer queue type. - It must be in the recording state and outside of a render pass instance. - You need to submit it and make sure it finished execution before calling vmaDefragmentationEnd(). - - Passing null means that only CPU defragmentation will be performed. - */ - VkCommandBuffer VMA_NULLABLE commandBuffer; -} VmaDefragmentationInfo2; - -typedef struct VmaDefragmentationPassMoveInfo { - VmaAllocation VMA_NOT_NULL allocation; - VkDeviceMemory VMA_NOT_NULL_NON_DISPATCHABLE memory; - VkDeviceSize offset; -} VmaDefragmentationPassMoveInfo; - -/** \brief Parameters for incremental defragmentation steps. - -To be used with function vmaBeginDefragmentationPass(). -*/ -typedef struct VmaDefragmentationPassInfo { - uint32_t moveCount; - VmaDefragmentationPassMoveInfo* VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(moveCount) pMoves; -} VmaDefragmentationPassInfo; - -/** \brief Deprecated. Optional configuration parameters to be passed to function vmaDefragment(). - -\deprecated This is a part of the old interface. It is recommended to use structure #VmaDefragmentationInfo2 and function vmaDefragmentationBegin() instead. -*/ -typedef struct VmaDefragmentationInfo { - /** \brief Maximum total numbers of bytes that can be copied while moving allocations to different places. - - Default is `VK_WHOLE_SIZE`, which means no limit. - */ - VkDeviceSize maxBytesToMove; - /** \brief Maximum number of allocations that can be moved to different place. - - Default is `UINT32_MAX`, which means no limit. - */ - uint32_t maxAllocationsToMove; -} VmaDefragmentationInfo; - -/** \brief Statistics returned by function vmaDefragment(). */ -typedef struct VmaDefragmentationStats { - /// Total number of bytes that have been copied while moving allocations to different places. - VkDeviceSize bytesMoved; - /// Total number of bytes that have been released to the system by freeing empty `VkDeviceMemory` objects. - VkDeviceSize bytesFreed; - /// Number of allocations that have been moved to different places. - uint32_t allocationsMoved; - /// Number of empty `VkDeviceMemory` objects that have been released to the system. - uint32_t deviceMemoryBlocksFreed; -} VmaDefragmentationStats; +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption( + VmaAllocator VMA_NOT_NULL allocator, + uint32_t memoryTypeBits); /** \brief Begins defragmentation process. -@param allocator Allocator object. -@param pInfo Structure filled with parameters of defragmentation. -@param[out] pStats Optional. Statistics of defragmentation. You can pass null if you are not interested in this information. -@param[out] pContext Context object that must be passed to vmaDefragmentationEnd() to finish defragmentation. -@return `VK_SUCCESS` and `*pContext == null` if defragmentation finished within this function call. `VK_NOT_READY` and `*pContext != null` if defragmentation has been started and you need to call vmaDefragmentationEnd() to finish it. Negative value in case of error. +\param allocator Allocator object. +\param pInfo Structure filled with parameters of defragmentation. +\param[out] pContext Context object that must be passed to vmaEndDefragmentation() to finish defragmentation. +\returns +- `VK_SUCCESS` if defragmentation can begin. +- `VK_ERROR_FEATURE_NOT_PRESENT` if defragmentation is not supported. -Use this function instead of old, deprecated vmaDefragment(). - -Warning! Between the call to vmaDefragmentationBegin() and vmaDefragmentationEnd(): - -- You should not use any of allocations passed as `pInfo->pAllocations` or - any allocations that belong to pools passed as `pInfo->pPools`, - including calling vmaGetAllocationInfo(), vmaTouchAllocation(), or access - their data. -- Some mutexes protecting internal data structures may be locked, so trying to - make or free any allocations, bind buffers or images, map memory, or launch - another simultaneous defragmentation in between may cause stall (when done on - another thread) or deadlock (when done on the same thread), unless you are - 100% sure that defragmented allocations are in different pools. -- Information returned via `pStats` and `pInfo->pAllocationsChanged` are undefined. - They become valid after call to vmaDefragmentationEnd(). -- If `pInfo->commandBuffer` is not null, you must submit that command buffer - and make sure it finished execution before calling vmaDefragmentationEnd(). - -For more information and important limitations regarding defragmentation, see documentation chapter: +For more information about defragmentation, see documentation chapter: [Defragmentation](@ref defragmentation). */ -VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationBegin( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentation( VmaAllocator VMA_NOT_NULL allocator, - const VmaDefragmentationInfo2* VMA_NOT_NULL pInfo, - VmaDefragmentationStats* VMA_NULLABLE pStats, - VmaDefragmentationContext VMA_NULLABLE * VMA_NOT_NULL pContext); + const VmaDefragmentationInfo* VMA_NOT_NULL pInfo, + VmaDefragmentationContext VMA_NULLABLE* VMA_NOT_NULL pContext); /** \brief Ends defragmentation process. -Use this function to finish defragmentation started by vmaDefragmentationBegin(). -It is safe to pass `context == null`. The function then does nothing. -*/ -VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationEnd( - VmaAllocator VMA_NOT_NULL allocator, - VmaDefragmentationContext VMA_NULLABLE context); +\param allocator Allocator object. +\param context Context object that has been created by vmaBeginDefragmentation(). +\param[out] pStats Optional stats for the defragmentation. Can be null. +Use this function to finish defragmentation started by vmaBeginDefragmentation(). +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaEndDefragmentation( + VmaAllocator VMA_NOT_NULL allocator, + VmaDefragmentationContext VMA_NOT_NULL context, + VmaDefragmentationStats* VMA_NULLABLE pStats); + +/** \brief Starts single defragmentation pass. + +\param allocator Allocator object. +\param context Context object that has been created by vmaBeginDefragmentation(). +\param[out] pPassInfo Computed informations for current pass. +\returns +- `VK_SUCCESS` if no more moves are possible. Then you can omit call to vmaEndDefragmentationPass() and simply end whole defragmentation. +- `VK_INCOMPLETE` if there are pending moves returned in `pPassInfo`. You need to perform them, call vmaEndDefragmentationPass(), + and then preferably try another pass with vmaBeginDefragmentationPass(). +*/ VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentationPass( VmaAllocator VMA_NOT_NULL allocator, - VmaDefragmentationContext VMA_NULLABLE context, - VmaDefragmentationPassInfo* VMA_NOT_NULL pInfo -); + VmaDefragmentationContext VMA_NOT_NULL context, + VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo); + +/** \brief Ends single defragmentation pass. + +\param allocator Allocator object. +\param context Context object that has been created by vmaBeginDefragmentation(). +\param pPassInfo Computed informations for current pass filled by vmaBeginDefragmentationPass() and possibly modified by you. + +Returns `VK_SUCCESS` if no more moves are possible or `VK_INCOMPLETE` if more defragmentations are possible. + +Ends incremental defragmentation pass and commits all defragmentation moves from `pPassInfo`. +After this call: + +- Allocations at `pPassInfo[i].srcAllocation` that had `pPassInfo[i].operation ==` #VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY + (which is the default) will be pointing to the new destination place. +- Allocation at `pPassInfo[i].srcAllocation` that had `pPassInfo[i].operation ==` #VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY + will be freed. + +If no more moves are possible you can end whole defragmentation. +*/ VMA_CALL_PRE VkResult VMA_CALL_POST vmaEndDefragmentationPass( VmaAllocator VMA_NOT_NULL allocator, - VmaDefragmentationContext VMA_NULLABLE context -); - -/** \brief Deprecated. Compacts memory by moving allocations. - -@param allocator -@param pAllocations Array of allocations that can be moved during this compation. -@param allocationCount Number of elements in pAllocations and pAllocationsChanged arrays. -@param[out] pAllocationsChanged Array of boolean values that will indicate whether matching allocation in pAllocations array has been moved. This parameter is optional. Pass null if you don't need this information. -@param pDefragmentationInfo Configuration parameters. Optional - pass null to use default values. -@param[out] pDefragmentationStats Statistics returned by the function. Optional - pass null if you don't need this information. -@return `VK_SUCCESS` if completed, negative error code in case of error. - -\deprecated This is a part of the old interface. It is recommended to use structure #VmaDefragmentationInfo2 and function vmaDefragmentationBegin() instead. - -This function works by moving allocations to different places (different -`VkDeviceMemory` objects and/or different offsets) in order to optimize memory -usage. Only allocations that are in `pAllocations` array can be moved. All other -allocations are considered nonmovable in this call. Basic rules: - -- Only allocations made in memory types that have - `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` and `VK_MEMORY_PROPERTY_HOST_COHERENT_BIT` - flags can be compacted. You may pass other allocations but it makes no sense - - these will never be moved. -- Custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT or - #VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT flag are not defragmented. Allocations - passed to this function that come from such pools are ignored. -- Allocations created with #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT or - created as dedicated allocations for any other reason are also ignored. -- Both allocations made with or without #VMA_ALLOCATION_CREATE_MAPPED_BIT - flag can be compacted. If not persistently mapped, memory will be mapped - temporarily inside this function if needed. -- You must not pass same #VmaAllocation object multiple times in `pAllocations` array. - -The function also frees empty `VkDeviceMemory` blocks. - -Warning: This function may be time-consuming, so you shouldn't call it too often -(like after every resource creation/destruction). -You can call it on special occasions (like when reloading a game level or -when you just destroyed a lot of objects). Calling it every frame may be OK, but -you should measure that on your platform. - -For more information, see [Defragmentation](@ref defragmentation) chapter. -*/ -VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragment( - VmaAllocator VMA_NOT_NULL allocator, - const VmaAllocation VMA_NOT_NULL * VMA_NOT_NULL VMA_LEN_IF_NOT_NULL(allocationCount) pAllocations, - size_t allocationCount, - VkBool32* VMA_NULLABLE VMA_LEN_IF_NOT_NULL(allocationCount) pAllocationsChanged, - const VmaDefragmentationInfo* VMA_NULLABLE pDefragmentationInfo, - VmaDefragmentationStats* VMA_NULLABLE pDefragmentationStats); + VmaDefragmentationContext VMA_NOT_NULL context, + VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo); /** \brief Binds buffer to allocation. @@ -1997,11 +2215,11 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory( /** \brief Binds buffer to allocation with additional parameters. -@param allocator -@param allocation -@param allocationLocalOffset Additional offset to be added while binding, relative to the beginning of the `allocation`. Normally it should be 0. -@param buffer -@param pNext A chain of structures to be attached to `VkBindBufferMemoryInfoKHR` structure used internally. Normally it should be null. +\param allocator +\param allocation +\param allocationLocalOffset Additional offset to be added while binding, relative to the beginning of the `allocation`. Normally it should be 0. +\param buffer +\param pNext A chain of structures to be attached to `VkBindBufferMemoryInfoKHR` structure used internally. Normally it should be null. This function is similar to vmaBindBufferMemory(), but it provides additional parameters. @@ -2034,11 +2252,11 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory( /** \brief Binds image to allocation with additional parameters. -@param allocator -@param allocation -@param allocationLocalOffset Additional offset to be added while binding, relative to the beginning of the `allocation`. Normally it should be 0. -@param image -@param pNext A chain of structures to be attached to `VkBindImageMemoryInfoKHR` structure used internally. Normally it should be null. +\param allocator +\param allocation +\param allocationLocalOffset Additional offset to be added while binding, relative to the beginning of the `allocation`. Normally it should be 0. +\param image +\param pNext A chain of structures to be attached to `VkBindImageMemoryInfoKHR` structure used internally. Normally it should be null. This function is similar to vmaBindImageMemory(), but it provides additional parameters. @@ -2052,13 +2270,14 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindImageMemory2( VkImage VMA_NOT_NULL_NON_DISPATCHABLE image, const void* VMA_NULLABLE pNext); -/** -@param allocator -@param pBufferCreateInfo -@param pAllocationCreateInfo -@param[out] pBuffer Buffer that was created. -@param[out] pAllocation Allocation that was created. -@param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo(). +/** \brief Creates a new `VkBuffer`, allocates and binds memory for it. + +\param allocator +\param pBufferCreateInfo +\param pAllocationCreateInfo +\param[out] pBuffer Buffer that was created. +\param[out] pAllocation Allocation that was created. +\param[out] pAllocationInfo Optional. Information about allocated memory. It can be later fetched using function vmaGetAllocationInfo(). This function automatically: @@ -2067,7 +2286,7 @@ This function automatically: -# Binds the buffer with the memory. If any of these operations fail, buffer and allocation are not created, -returned value is negative error code, *pBuffer and *pAllocation are null. +returned value is negative error code, `*pBuffer` and `*pAllocation` are null. If the function succeeded, you must destroy both buffer and allocation when you no longer need them using either convenience function vmaDestroyBuffer() or @@ -2076,8 +2295,8 @@ separately, using `vkDestroyBuffer()` and vmaFreeMemory(). If #VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT flag was used, VK_KHR_dedicated_allocation extension is used internally to query driver whether it requires or prefers the new buffer to have dedicated allocation. If yes, -and if dedicated allocation is possible (VmaAllocationCreateInfo::pool is null -and #VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT is not used), it creates dedicated +and if dedicated allocation is possible +(#VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT is not used), it creates dedicated allocation for this buffer, just like when using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. @@ -2089,8 +2308,8 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBuffer( VmaAllocator VMA_NOT_NULL allocator, const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo, const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo, - VkBuffer VMA_NULLABLE_NON_DISPATCHABLE * VMA_NOT_NULL pBuffer, - VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VkBuffer VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pBuffer, + VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation, VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); /** \brief Creates a buffer with additional minimum alignment. @@ -2104,10 +2323,35 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment( const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo, const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo, VkDeviceSize minAlignment, - VkBuffer VMA_NULLABLE_NON_DISPATCHABLE * VMA_NOT_NULL pBuffer, - VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VkBuffer VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pBuffer, + VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation, VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); +/** \brief Creates a new `VkBuffer`, binds already created memory for it. + +\param allocator +\param allocation Allocation that provides memory to be used for binding new buffer to it. +\param pBufferCreateInfo +\param[out] pBuffer Buffer that was created. + +This function automatically: + +-# Creates buffer. +-# Binds the buffer with the supplied memory. + +If any of these operations fail, buffer is not created, +returned value is negative error code and `*pBuffer` is null. + +If the function succeeded, you must destroy the buffer when you +no longer need it using `vkDestroyBuffer()`. If you want to also destroy the corresponding +allocation you can use convenience function vmaDestroyBuffer(). +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingBuffer( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo, + VkBuffer VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pBuffer); + /** \brief Destroys Vulkan buffer and frees allocated memory. This is just a convenience function equivalent to: @@ -2129,10 +2373,17 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage( VmaAllocator VMA_NOT_NULL allocator, const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo, const VmaAllocationCreateInfo* VMA_NOT_NULL pAllocationCreateInfo, - VkImage VMA_NULLABLE_NON_DISPATCHABLE * VMA_NOT_NULL pImage, - VmaAllocation VMA_NULLABLE * VMA_NOT_NULL pAllocation, + VkImage VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pImage, + VmaAllocation VMA_NULLABLE* VMA_NOT_NULL pAllocation, VmaAllocationInfo* VMA_NULLABLE pAllocationInfo); +/// Function similar to vmaCreateAliasingBuffer(). +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingImage( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo, + VkImage VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pImage); + /** \brief Destroys Vulkan image and frees allocated memory. This is just a convenience function equivalent to: @@ -2149,12 +2400,164 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyImage( VkImage VMA_NULLABLE_NON_DISPATCHABLE image, VmaAllocation VMA_NULLABLE allocation); +/** @} */ + +/** +\addtogroup group_virtual +@{ +*/ + +/** \brief Creates new #VmaVirtualBlock object. + +\param pCreateInfo Parameters for creation. +\param[out] pVirtualBlock Returned virtual block object or `VMA_NULL` if creation failed. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateVirtualBlock( + const VmaVirtualBlockCreateInfo* VMA_NOT_NULL pCreateInfo, + VmaVirtualBlock VMA_NULLABLE* VMA_NOT_NULL pVirtualBlock); + +/** \brief Destroys #VmaVirtualBlock object. + +Please note that you should consciously handle virtual allocations that could remain unfreed in the block. +You should either free them individually using vmaVirtualFree() or call vmaClearVirtualBlock() +if you are sure this is what you want. If you do neither, an assert is called. + +If you keep pointers to some additional metadata associated with your virtual allocations in their `pUserData`, +don't forget to free them. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyVirtualBlock( + VmaVirtualBlock VMA_NULLABLE virtualBlock); + +/** \brief Returns true of the #VmaVirtualBlock is empty - contains 0 virtual allocations and has all its space available for new allocations. +*/ +VMA_CALL_PRE VkBool32 VMA_CALL_POST vmaIsVirtualBlockEmpty( + VmaVirtualBlock VMA_NOT_NULL virtualBlock); + +/** \brief Returns information about a specific virtual allocation within a virtual block, like its size and `pUserData` pointer. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetVirtualAllocationInfo( + VmaVirtualBlock VMA_NOT_NULL virtualBlock, + VmaVirtualAllocation VMA_NOT_NULL_NON_DISPATCHABLE allocation, VmaVirtualAllocationInfo* VMA_NOT_NULL pVirtualAllocInfo); + +/** \brief Allocates new virtual allocation inside given #VmaVirtualBlock. + +If the allocation fails due to not enough free space available, `VK_ERROR_OUT_OF_DEVICE_MEMORY` is returned +(despite the function doesn't ever allocate actual GPU memory). +`pAllocation` is then set to `VK_NULL_HANDLE` and `pOffset`, if not null, it set to `UINT64_MAX`. + +\param virtualBlock Virtual block +\param pCreateInfo Parameters for the allocation +\param[out] pAllocation Returned handle of the new allocation +\param[out] pOffset Returned offset of the new allocation. Optional, can be null. +*/ +VMA_CALL_PRE VkResult VMA_CALL_POST vmaVirtualAllocate( + VmaVirtualBlock VMA_NOT_NULL virtualBlock, + const VmaVirtualAllocationCreateInfo* VMA_NOT_NULL pCreateInfo, + VmaVirtualAllocation VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pAllocation, + VkDeviceSize* VMA_NULLABLE pOffset); + +/** \brief Frees virtual allocation inside given #VmaVirtualBlock. + +It is correct to call this function with `allocation == VK_NULL_HANDLE` - it does nothing. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaVirtualFree( + VmaVirtualBlock VMA_NOT_NULL virtualBlock, + VmaVirtualAllocation VMA_NULLABLE_NON_DISPATCHABLE allocation); + +/** \brief Frees all virtual allocations inside given #VmaVirtualBlock. + +You must either call this function or free each virtual allocation individually with vmaVirtualFree() +before destroying a virtual block. Otherwise, an assert is called. + +If you keep pointer to some additional metadata associated with your virtual allocation in its `pUserData`, +don't forget to free it as well. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaClearVirtualBlock( + VmaVirtualBlock VMA_NOT_NULL virtualBlock); + +/** \brief Changes custom pointer associated with given virtual allocation. +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaSetVirtualAllocationUserData( + VmaVirtualBlock VMA_NOT_NULL virtualBlock, + VmaVirtualAllocation VMA_NOT_NULL_NON_DISPATCHABLE allocation, + void* VMA_NULLABLE pUserData); + +/** \brief Calculates and returns statistics about virtual allocations and memory usage in given #VmaVirtualBlock. + +This function is fast to call. For more detailed statistics, see vmaCalculateVirtualBlockStatistics(). +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaGetVirtualBlockStatistics( + VmaVirtualBlock VMA_NOT_NULL virtualBlock, + VmaStatistics* VMA_NOT_NULL pStats); + +/** \brief Calculates and returns detailed statistics about virtual allocations and memory usage in given #VmaVirtualBlock. + +This function is slow to call. Use for debugging purposes. +For less detailed statistics, see vmaGetVirtualBlockStatistics(). +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaCalculateVirtualBlockStatistics( + VmaVirtualBlock VMA_NOT_NULL virtualBlock, + VmaDetailedStatistics* VMA_NOT_NULL pStats); + +/** @} */ + +#if VMA_STATS_STRING_ENABLED +/** +\addtogroup group_stats +@{ +*/ + +/** \brief Builds and returns a null-terminated string in JSON format with information about given #VmaVirtualBlock. +\param virtualBlock Virtual block. +\param[out] ppStatsString Returned string. +\param detailedMap Pass `VK_FALSE` to only obtain statistics as returned by vmaCalculateVirtualBlockStatistics(). Pass `VK_TRUE` to also obtain full list of allocations and free spaces. + +Returned string must be freed using vmaFreeVirtualBlockStatsString(). +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaBuildVirtualBlockStatsString( + VmaVirtualBlock VMA_NOT_NULL virtualBlock, + char* VMA_NULLABLE* VMA_NOT_NULL ppStatsString, + VkBool32 detailedMap); + +/// Frees a string returned by vmaBuildVirtualBlockStatsString(). +VMA_CALL_PRE void VMA_CALL_POST vmaFreeVirtualBlockStatsString( + VmaVirtualBlock VMA_NOT_NULL virtualBlock, + char* VMA_NULLABLE pStatsString); + +/** \brief Builds and returns statistics as a null-terminated string in JSON format. +\param allocator +\param[out] ppStatsString Must be freed using vmaFreeStatsString() function. +\param detailedMap +*/ +VMA_CALL_PRE void VMA_CALL_POST vmaBuildStatsString( + VmaAllocator VMA_NOT_NULL allocator, + char* VMA_NULLABLE* VMA_NOT_NULL ppStatsString, + VkBool32 detailedMap); + +VMA_CALL_PRE void VMA_CALL_POST vmaFreeStatsString( + VmaAllocator VMA_NOT_NULL allocator, + char* VMA_NULLABLE pStatsString); + +/** @} */ + +#endif // VMA_STATS_STRING_ENABLED + +#endif // _VMA_FUNCTION_HEADERS + #ifdef __cplusplus } #endif #endif // AMD_VULKAN_MEMORY_ALLOCATOR_H +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// IMPLEMENTATION +// +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + // For Visual Studio IntelliSense. #if defined(__cplusplus) && defined(__INTELLISENSE__) #define VMA_IMPLEMENTATION @@ -2167,15 +2570,13 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyImage( #include #include #include +#include -#if VMA_RECORDING_ENABLED - #include - #if defined(_WIN32) - #include - #else - #include - #include - #endif +#ifdef _MSC_VER + #include // For functions like __popcnt, _BitScanForward etc. +#endif +#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L // C++20 + #include // For std::popcount #endif /******************************************************************************* @@ -2184,6 +2585,7 @@ CONFIGURATION SECTION Define some of these macros before each #include of this header or change them here if you need other then default behavior depending on your environment. */ +#ifndef _VMA_CONFIGURATION /* Define this macro to 1 to make the library fetch pointers to Vulkan functions @@ -2199,29 +2601,14 @@ internally, like: Define this macro to 1 to make the library fetch pointers to Vulkan functions internally, like: - vulkanFunctions.vkAllocateMemory = (PFN_vkAllocateMemory)vkGetDeviceProcAddr(m_hDevice, vkAllocateMemory); + vulkanFunctions.vkAllocateMemory = (PFN_vkAllocateMemory)vkGetDeviceProcAddr(device, "vkAllocateMemory"); + +To use this feature in new versions of VMA you now have to pass +VmaVulkanFunctions::vkGetInstanceProcAddr and vkGetDeviceProcAddr as +VmaAllocatorCreateInfo::pVulkanFunctions. Other members can be null. */ #if !defined(VMA_DYNAMIC_VULKAN_FUNCTIONS) #define VMA_DYNAMIC_VULKAN_FUNCTIONS 1 - #if defined(VK_NO_PROTOTYPES) - extern PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; - extern PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; - #endif -#endif - -// Define this macro to 1 to make the library use STL containers instead of its own implementation. -//#define VMA_USE_STL_CONTAINERS 1 - -/* Set this macro to 1 to make the library including and using STL containers: -std::pair, std::vector, std::list, std::unordered_map. - -Set it to 0 or undefined to make the library using its own implementation of -the containers. -*/ -#if VMA_USE_STL_CONTAINERS - #define VMA_USE_STL_VECTOR 1 - #define VMA_USE_STL_UNORDERED_MAP 1 - #define VMA_USE_STL_LIST 1 #endif #ifndef VMA_USE_STL_SHARED_MUTEX @@ -2230,7 +2617,6 @@ the containers. #define VMA_USE_STL_SHARED_MUTEX 1 // Visual studio defines __cplusplus properly only when passed additional parameter: /Zc:__cplusplus // Otherwise it is always 199711L, despite shared_mutex works since Visual Studio 2015 Update 2. - // See: https://blogs.msdn.microsoft.com/vcblog/2018/04/09/msvc-now-correctly-reports-__cplusplus/ #elif defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023918 && __cplusplus == 199711L && _MSVC_LANG >= 201703L #define VMA_USE_STL_SHARED_MUTEX 1 #else @@ -2239,28 +2625,33 @@ the containers. #endif /* -THESE INCLUDES ARE NOT ENABLED BY DEFAULT. -Library has its own container implementation. -*/ -#if VMA_USE_STL_VECTOR - #include -#endif +Define this macro to include custom header files without having to edit this file directly, e.g.: -#if VMA_USE_STL_UNORDERED_MAP - #include -#endif + // Inside of "my_vma_configuration_user_includes.h": -#if VMA_USE_STL_LIST - #include -#endif + #include "my_custom_assert.h" // for MY_CUSTOM_ASSERT + #include "my_custom_min.h" // for my_custom_min + #include + #include -/* -Following headers are used in this CONFIGURATION section only, so feel free to + // Inside a different file, which includes "vk_mem_alloc.h": + + #define VMA_CONFIGURATION_USER_INCLUDES_H "my_vma_configuration_user_includes.h" + #define VMA_ASSERT(expr) MY_CUSTOM_ASSERT(expr) + #define VMA_MIN(v1, v2) (my_custom_min(v1, v2)) + #include "vk_mem_alloc.h" + ... + +The following headers are used in this CONFIGURATION section only, so feel free to remove them if not needed. */ -#include // for assert -#include // for min, max -#include +#if !defined(VMA_CONFIGURATION_USER_INCLUDES_H) + #include // for assert + #include // for min, max + #include +#else + #include VMA_CONFIGURATION_USER_INCLUDES_H +#endif #ifndef VMA_NULL // Value used as null pointer. Define it to e.g.: nullptr, NULL, 0, (void*)0. @@ -2379,6 +2770,21 @@ static void vma_aligned_free(void* VMA_NULLABLE ptr) #endif #endif +#ifndef VMA_COUNT_BITS_SET + // Returns number of bits set to 1 in (v) + #define VMA_COUNT_BITS_SET(v) VmaCountBitsSet(v) +#endif + +#ifndef VMA_BITSCAN_LSB + // Scans integer for index of first nonzero value from the Least Significant Bit (LSB). If mask is 0 then returns UINT8_MAX + #define VMA_BITSCAN_LSB(mask) VmaBitScanLSB(mask) +#endif + +#ifndef VMA_BITSCAN_MSB + // Scans integer for index of first nonzero value from the Most Significant Bit (MSB). If mask is 0 then returns UINT8_MAX + #define VMA_BITSCAN_MSB(mask) VmaBitScanMSB(mask) +#endif + #ifndef VMA_MIN #define VMA_MIN(v1, v2) ((std::min)((v1), (v2))) #endif @@ -2522,7 +2928,7 @@ If providing your own implementation, you need to implement a subset of std::ato #ifndef VMA_DEBUG_MARGIN /** - Minimum margin before and after every allocation, in bytes. + Minimum margin after every allocation, in bytes. Set nonzero for debugging purposes only. */ #define VMA_DEBUG_MARGIN (0) @@ -2539,7 +2945,7 @@ If providing your own implementation, you need to implement a subset of std::ato #ifndef VMA_DEBUG_DETECT_CORRUPTION /** Define this macro to 1 together with non-zero value of VMA_DEBUG_MARGIN to - enable writing magic value to the margin before and after every allocation and + enable writing magic value to the margin after every allocation and validating it, so that memory corruptions (out-of-bounds writes) are detected. */ #define VMA_DEBUG_DETECT_CORRUPTION (0) @@ -2579,6 +2985,17 @@ If providing your own implementation, you need to implement a subset of std::ato #define VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE (256ull * 1024 * 1024) #endif +/* +Mapping hysteresis is a logic that launches when vmaMapMemory/vmaUnmapMemory is called +or a persistently mapped allocation is created and destroyed several times in a row. +It keeps additional +1 mapping of a device memory block to prevent calling actual +vkMapMemory/vkUnmapMemory too many times, which may improve performance and help +tools like RenderDOc. +*/ +#ifndef VMA_MAPPING_HYSTERESIS_ENABLED + #define VMA_MAPPING_HYSTERESIS_ENABLED 1 +#endif + #ifndef VMA_CLASS_NO_COPY #define VMA_CLASS_NO_COPY(className) \ private: \ @@ -2586,38 +3003,281 @@ If providing your own implementation, you need to implement a subset of std::ato className& operator=(const className&) = delete; #endif -static const uint32_t VMA_FRAME_INDEX_LOST = UINT32_MAX; - -// Decimal 2139416166, float NaN, little-endian binary 66 E6 84 7F. -static const uint32_t VMA_CORRUPTION_DETECTION_MAGIC_VALUE = 0x7F84E666; - -static const uint8_t VMA_ALLOCATION_FILL_PATTERN_CREATED = 0xDC; -static const uint8_t VMA_ALLOCATION_FILL_PATTERN_DESTROYED = 0xEF; +#define VMA_VALIDATE(cond) do { if(!(cond)) { \ + VMA_ASSERT(0 && "Validation failed: " #cond); \ + return false; \ + } } while(false) /******************************************************************************* END OF CONFIGURATION */ +#endif // _VMA_CONFIGURATION -// # Copy of some Vulkan definitions so we don't need to check their existence just to handle few constants. +static const uint8_t VMA_ALLOCATION_FILL_PATTERN_CREATED = 0xDC; +static const uint8_t VMA_ALLOCATION_FILL_PATTERN_DESTROYED = 0xEF; +// Decimal 2139416166, float NaN, little-endian binary 66 E6 84 7F. +static const uint32_t VMA_CORRUPTION_DETECTION_MAGIC_VALUE = 0x7F84E666; + +// Copy of some Vulkan definitions so we don't need to check their existence just to handle few constants. static const uint32_t VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY = 0x00000040; static const uint32_t VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY = 0x00000080; static const uint32_t VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY = 0x00020000; - +static const uint32_t VK_IMAGE_CREATE_DISJOINT_BIT_COPY = 0x00000200; +static const int32_t VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT_COPY = 1000158000; static const uint32_t VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET = 0x10000000u; +static const uint32_t VMA_ALLOCATION_TRY_COUNT = 32; +static const uint32_t VMA_VENDOR_ID_AMD = 4098; -static VkAllocationCallbacks VmaEmptyAllocationCallbacks = { - VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL }; +// This one is tricky. Vulkan specification defines this code as available since +// Vulkan 1.0, but doesn't actually define it in Vulkan SDK earlier than 1.2.131. +// See pull request #207. +#define VK_ERROR_UNKNOWN_COPY ((VkResult)-13) -// Returns number of bits set to 1 in (v). + +#if VMA_STATS_STRING_ENABLED +// Correspond to values of enum VmaSuballocationType. +static const char* VMA_SUBALLOCATION_TYPE_NAMES[] = +{ + "FREE", + "UNKNOWN", + "BUFFER", + "IMAGE_UNKNOWN", + "IMAGE_LINEAR", + "IMAGE_OPTIMAL", +}; +#endif + +static VkAllocationCallbacks VmaEmptyAllocationCallbacks = + { VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL, VMA_NULL }; + + +#ifndef _VMA_ENUM_DECLARATIONS + +enum VmaSuballocationType +{ + VMA_SUBALLOCATION_TYPE_FREE = 0, + VMA_SUBALLOCATION_TYPE_UNKNOWN = 1, + VMA_SUBALLOCATION_TYPE_BUFFER = 2, + VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN = 3, + VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR = 4, + VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL = 5, + VMA_SUBALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF +}; + +enum VMA_CACHE_OPERATION +{ + VMA_CACHE_FLUSH, + VMA_CACHE_INVALIDATE +}; + +enum class VmaAllocationRequestType +{ + Normal, + TLSF, + // Used by "Linear" algorithm. + UpperAddress, + EndOf1st, + EndOf2nd, +}; + +#endif // _VMA_ENUM_DECLARATIONS + +#ifndef _VMA_FORWARD_DECLARATIONS +// Opaque handle used by allocation algorithms to identify single allocation in any conforming way. +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VmaAllocHandle); + +struct VmaMutexLock; +struct VmaMutexLockRead; +struct VmaMutexLockWrite; + +template +struct AtomicTransactionalIncrement; + +template +struct VmaStlAllocator; + +template +class VmaVector; + +template +class VmaSmallVector; + +template +class VmaPoolAllocator; + +template +struct VmaListItem; + +template +class VmaRawList; + +template +class VmaList; + +template +class VmaIntrusiveLinkedList; + +// Unused in this version +#if 0 +template +struct VmaPair; +template +struct VmaPairFirstLess; + +template +class VmaMap; +#endif + +#if VMA_STATS_STRING_ENABLED +class VmaStringBuilder; +class VmaJsonWriter; +#endif + +class VmaDeviceMemoryBlock; + +struct VmaDedicatedAllocationListItemTraits; +class VmaDedicatedAllocationList; + +struct VmaSuballocation; +struct VmaSuballocationOffsetLess; +struct VmaSuballocationOffsetGreater; +struct VmaSuballocationItemSizeLess; + +typedef VmaList> VmaSuballocationList; + +struct VmaAllocationRequest; + +class VmaBlockMetadata; +class VmaBlockMetadata_Linear; +class VmaBlockMetadata_TLSF; + +class VmaBlockVector; + +struct VmaPoolListItemTraits; + +struct VmaCurrentBudgetData; + +class VmaAllocationObjectAllocator; + +#endif // _VMA_FORWARD_DECLARATIONS + + +#ifndef _VMA_FUNCTIONS + +/* +Returns number of bits set to 1 in (v). + +On specific platforms and compilers you can use instrinsics like: + +Visual Studio: + return __popcnt(v); +GCC, Clang: + return static_cast(__builtin_popcount(v)); + +Define macro VMA_COUNT_BITS_SET to provide your optimized implementation. +But you need to check in runtime whether user's CPU supports these, as some old processors don't. +*/ static inline uint32_t VmaCountBitsSet(uint32_t v) { +#if __cplusplus >= 202002L || _MSVC_LANG >= 202002L // C++20 + return std::popcount(v); +#else uint32_t c = v - ((v >> 1) & 0x55555555); - c = ((c >> 2) & 0x33333333) + (c & 0x33333333); - c = ((c >> 4) + c) & 0x0F0F0F0F; - c = ((c >> 8) + c) & 0x00FF00FF; + c = ((c >> 2) & 0x33333333) + (c & 0x33333333); + c = ((c >> 4) + c) & 0x0F0F0F0F; + c = ((c >> 8) + c) & 0x00FF00FF; c = ((c >> 16) + c) & 0x0000FFFF; return c; +#endif +} + +static inline uint8_t VmaBitScanLSB(uint64_t mask) +{ +#if defined(_MSC_VER) && defined(_WIN64) + unsigned long pos; + if (_BitScanForward64(&pos, mask)) + return static_cast(pos); + return UINT8_MAX; +#elif defined __GNUC__ || defined __clang__ + return static_cast(__builtin_ffsll(mask)) - 1U; +#else + uint8_t pos = 0; + uint64_t bit = 1; + do + { + if (mask & bit) + return pos; + bit <<= 1; + } while (pos++ < 63); + return UINT8_MAX; +#endif +} + +static inline uint8_t VmaBitScanLSB(uint32_t mask) +{ +#ifdef _MSC_VER + unsigned long pos; + if (_BitScanForward(&pos, mask)) + return static_cast(pos); + return UINT8_MAX; +#elif defined __GNUC__ || defined __clang__ + return static_cast(__builtin_ffs(mask)) - 1U; +#else + uint8_t pos = 0; + uint32_t bit = 1; + do + { + if (mask & bit) + return pos; + bit <<= 1; + } while (pos++ < 31); + return UINT8_MAX; +#endif +} + +static inline uint8_t VmaBitScanMSB(uint64_t mask) +{ +#if defined(_MSC_VER) && defined(_WIN64) + unsigned long pos; + if (_BitScanReverse64(&pos, mask)) + return static_cast(pos); +#elif defined __GNUC__ || defined __clang__ + if (mask) + return 63 - static_cast(__builtin_clzll(mask)); +#else + uint8_t pos = 63; + uint64_t bit = 1ULL << 63; + do + { + if (mask & bit) + return pos; + bit >>= 1; + } while (pos-- > 0); +#endif + return UINT8_MAX; +} + +static inline uint8_t VmaBitScanMSB(uint32_t mask) +{ +#ifdef _MSC_VER + unsigned long pos; + if (_BitScanReverse(&pos, mask)) + return static_cast(pos); +#elif defined __GNUC__ || defined __clang__ + if (mask) + return 31 - static_cast(__builtin_clz(mask)); +#else + uint8_t pos = 31; + uint32_t bit = 1UL << 31; + do + { + if (mask & bit) + return pos; + bit >>= 1; + } while (pos-- > 0); +#endif + return UINT8_MAX; } /* @@ -2628,7 +3288,7 @@ For 0 returns true. template inline bool VmaIsPow2(T x) { - return (x & (x-1)) == 0; + return (x & (x - 1)) == 0; } // Aligns given value up to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 16. @@ -2639,6 +3299,7 @@ static inline T VmaAlignUp(T val, T alignment) VMA_HEAVY_ASSERT(VmaIsPow2(alignment)); return (val + alignment - 1) & ~(alignment - 1); } + // Aligns given value down to nearest multiply of align value. For example: VmaAlignUp(11, 8) = 8. // Use types like uint32_t, uint64_t as T. template @@ -2655,6 +3316,13 @@ static inline T VmaRoundDiv(T x, T y) return (x + (y / (T)2)) / y; } +// Divide by 'y' and round up to nearest integer. +template +static inline T VmaDivideRoundingUp(T x, T y) +{ + return (x + y - (T)1) / y; +} + // Returns smallest power of 2 greater or equal to v. static inline uint32_t VmaNextPow2(uint32_t v) { @@ -2667,6 +3335,7 @@ static inline uint32_t VmaNextPow2(uint32_t v) v++; return v; } + static inline uint64_t VmaNextPow2(uint64_t v) { v--; @@ -2691,6 +3360,7 @@ static inline uint32_t VmaPrevPow2(uint32_t v) v = v ^ (v >> 1); return v; } + static inline uint64_t VmaPrevPow2(uint64_t v) { v |= v >> 1; @@ -2708,66 +3378,6 @@ static inline bool VmaStrIsEmpty(const char* pStr) return pStr == VMA_NULL || *pStr == '\0'; } -#if VMA_STATS_STRING_ENABLED - -static const char* VmaAlgorithmToStr(uint32_t algorithm) -{ - switch(algorithm) - { - case VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT: - return "Linear"; - case VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT: - return "Buddy"; - case 0: - return "Default"; - default: - VMA_ASSERT(0); - return ""; - } -} - -#endif // #if VMA_STATS_STRING_ENABLED - -#ifndef VMA_SORT - -template -Iterator VmaQuickSortPartition(Iterator beg, Iterator end, Compare cmp) -{ - Iterator centerValue = end; --centerValue; - Iterator insertIndex = beg; - for(Iterator memTypeIndex = beg; memTypeIndex < centerValue; ++memTypeIndex) - { - if(cmp(*memTypeIndex, *centerValue)) - { - if(insertIndex != memTypeIndex) - { - VMA_SWAP(*memTypeIndex, *insertIndex); - } - ++insertIndex; - } - } - if(insertIndex != centerValue) - { - VMA_SWAP(*insertIndex, *centerValue); - } - return insertIndex; -} - -template -void VmaQuickSort(Iterator beg, Iterator end, Compare cmp) -{ - if(beg < end) - { - Iterator it = VmaQuickSortPartition(beg, end, cmp); - VmaQuickSort(beg, it, cmp); - VmaQuickSort(it + 1, end, cmp); - } -} - -#define VMA_SORT(beg, end, cmp) VmaQuickSort(beg, end, cmp) - -#endif // #ifndef VMA_SORT - /* Returns true if two memory blocks occupy overlapping pages. ResourceA must be in less memory offset than ResourceB. @@ -2789,17 +3399,6 @@ static inline bool VmaBlocksOnSamePage( return resourceAEndPage == resourceBStartPage; } -enum VmaSuballocationType -{ - VMA_SUBALLOCATION_TYPE_FREE = 0, - VMA_SUBALLOCATION_TYPE_UNKNOWN = 1, - VMA_SUBALLOCATION_TYPE_BUFFER = 2, - VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN = 3, - VMA_SUBALLOCATION_TYPE_IMAGE_LINEAR = 4, - VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL = 5, - VMA_SUBALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF -}; - /* Returns true if given suballocation types could conflict and must respect VkPhysicalDeviceLimits::bufferImageGranularity. They conflict if one is buffer @@ -2810,12 +3409,12 @@ static inline bool VmaIsBufferImageGranularityConflict( VmaSuballocationType suballocType1, VmaSuballocationType suballocType2) { - if(suballocType1 > suballocType2) + if (suballocType1 > suballocType2) { VMA_SWAP(suballocType1, suballocType2); } - switch(suballocType1) + switch (suballocType1) { case VMA_SUBALLOCATION_TYPE_FREE: return false; @@ -2846,7 +3445,7 @@ static void VmaWriteMagicValue(void* pData, VkDeviceSize offset) #if VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_DETECT_CORRUPTION uint32_t* pDst = (uint32_t*)((char*)pData + offset); const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t); - for(size_t i = 0; i < numberCount; ++i, ++pDst) + for (size_t i = 0; i < numberCount; ++i, ++pDst) { *pDst = VMA_CORRUPTION_DETECTION_MAGIC_VALUE; } @@ -2860,9 +3459,9 @@ static bool VmaValidateMagicValue(const void* pData, VkDeviceSize offset) #if VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_DETECT_CORRUPTION const uint32_t* pSrc = (const uint32_t*)((const char*)pData + offset); const size_t numberCount = VMA_DEBUG_MARGIN / sizeof(uint32_t); - for(size_t i = 0; i < numberCount; ++i, ++pSrc) + for (size_t i = 0; i < numberCount; ++i, ++pSrc) { - if(*pSrc != VMA_CORRUPTION_DETECTION_MAGIC_VALUE) + if (*pSrc != VMA_CORRUPTION_DETECTION_MAGIC_VALUE) { return false; } @@ -2883,55 +3482,6 @@ static void VmaFillGpuDefragmentationBufferCreateInfo(VkBufferCreateInfo& outBuf outBufCreateInfo.size = (VkDeviceSize)VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE; // Example size. } -// Helper RAII class to lock a mutex in constructor and unlock it in destructor (at the end of scope). -struct VmaMutexLock -{ - VMA_CLASS_NO_COPY(VmaMutexLock) -public: - VmaMutexLock(VMA_MUTEX& mutex, bool useMutex = true) : - m_pMutex(useMutex ? &mutex : VMA_NULL) - { if(m_pMutex) { m_pMutex->Lock(); } } - ~VmaMutexLock() - { if(m_pMutex) { m_pMutex->Unlock(); } } -private: - VMA_MUTEX* m_pMutex; -}; - -// Helper RAII class to lock a RW mutex in constructor and unlock it in destructor (at the end of scope), for reading. -struct VmaMutexLockRead -{ - VMA_CLASS_NO_COPY(VmaMutexLockRead) -public: - VmaMutexLockRead(VMA_RW_MUTEX& mutex, bool useMutex) : - m_pMutex(useMutex ? &mutex : VMA_NULL) - { if(m_pMutex) { m_pMutex->LockRead(); } } - ~VmaMutexLockRead() { if(m_pMutex) { m_pMutex->UnlockRead(); } } -private: - VMA_RW_MUTEX* m_pMutex; -}; - -// Helper RAII class to lock a RW mutex in constructor and unlock it in destructor (at the end of scope), for writing. -struct VmaMutexLockWrite -{ - VMA_CLASS_NO_COPY(VmaMutexLockWrite) -public: - VmaMutexLockWrite(VMA_RW_MUTEX& mutex, bool useMutex) : - m_pMutex(useMutex ? &mutex : VMA_NULL) - { if(m_pMutex) { m_pMutex->LockWrite(); } } - ~VmaMutexLockWrite() { if(m_pMutex) { m_pMutex->UnlockWrite(); } } -private: - VMA_RW_MUTEX* m_pMutex; -}; - -#if VMA_DEBUG_GLOBAL_MUTEX - static VMA_MUTEX gDebugGlobalMutex; - #define VMA_DEBUG_GLOBAL_MUTEX_LOCK VmaMutexLock debugGlobalMutexLock(gDebugGlobalMutex, true); -#else - #define VMA_DEBUG_GLOBAL_MUTEX_LOCK -#endif - -// Minimum size of a free suballocation to register it in the free suballocation collection. -static const VkDeviceSize VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER = 16; /* Performs binary search and returns iterator to first element that is greater or @@ -2943,13 +3493,13 @@ Returned value is the found element, if present in the collection or place where new element with value (key) should be inserted. */ template -static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT &key, const CmpLess& cmp) +static IterT VmaBinaryFindFirstNotLess(IterT beg, IterT end, const KeyT& key, const CmpLess& cmp) { size_t down = 0, up = (end - beg); - while(down < up) + while (down < up) { const size_t mid = down + (up - down) / 2; // Overflow-safe midpoint calculation - if(cmp(*(beg+mid), key)) + if (cmp(*(beg + mid), key)) { down = mid + 1; } @@ -2966,7 +3516,7 @@ IterT VmaBinaryFindSorted(const IterT& beg, const IterT& end, const KeyT& value, { IterT it = VmaBinaryFindFirstNotLess( beg, end, value, cmp); - if(it == end || + if (it == end || (!cmp(*it, value) && !cmp(value, *it))) { return it; @@ -2982,16 +3532,16 @@ T must be pointer type, e.g. VmaAllocation, VmaPool. template static bool VmaValidatePointerArray(uint32_t count, const T* arr) { - for(uint32_t i = 0; i < count; ++i) + for (uint32_t i = 0; i < count; ++i) { const T iPtr = arr[i]; - if(iPtr == VMA_NULL) + if (iPtr == VMA_NULL) { return false; } - for(uint32_t j = i + 1; j < count; ++j) + for (uint32_t j = i + 1; j < count; ++j) { - if(iPtr == arr[j]) + if (iPtr == arr[j]) { return false; } @@ -3007,13 +3557,161 @@ static inline void VmaPnextChainPushFront(MainT* mainStruct, NewT* newStruct) mainStruct->pNext = newStruct; } +// This is the main algorithm that guides the selection of a memory type best for an allocation - +// converts usage to required/preferred/not preferred flags. +static bool FindMemoryPreferences( + bool isIntegratedGPU, + const VmaAllocationCreateInfo& allocCreateInfo, + VkFlags bufImgUsage, // VkBufferCreateInfo::usage or VkImageCreateInfo::usage. UINT32_MAX if unknown. + VkMemoryPropertyFlags& outRequiredFlags, + VkMemoryPropertyFlags& outPreferredFlags, + VkMemoryPropertyFlags& outNotPreferredFlags) +{ + outRequiredFlags = allocCreateInfo.requiredFlags; + outPreferredFlags = allocCreateInfo.preferredFlags; + outNotPreferredFlags = 0; + + switch(allocCreateInfo.usage) + { + case VMA_MEMORY_USAGE_UNKNOWN: + break; + case VMA_MEMORY_USAGE_GPU_ONLY: + if(!isIntegratedGPU || (outPreferredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) + { + outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + break; + case VMA_MEMORY_USAGE_CPU_ONLY: + outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + break; + case VMA_MEMORY_USAGE_CPU_TO_GPU: + outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + if(!isIntegratedGPU || (outPreferredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) + { + outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + break; + case VMA_MEMORY_USAGE_GPU_TO_CPU: + outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + outPreferredFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + break; + case VMA_MEMORY_USAGE_CPU_COPY: + outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + break; + case VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED: + outRequiredFlags |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT; + break; + case VMA_MEMORY_USAGE_AUTO: + case VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE: + case VMA_MEMORY_USAGE_AUTO_PREFER_HOST: + { + if(bufImgUsage == UINT32_MAX) + { + VMA_ASSERT(0 && "VMA_MEMORY_USAGE_AUTO* values can only be used with functions like vmaCreateBuffer, vmaCreateImage so that the details of the created resource are known."); + return false; + } + // This relies on values of VK_IMAGE_USAGE_TRANSFER* being the same VK_BUFFER_IMAGE_TRANSFER*. + const bool deviceAccess = (bufImgUsage & ~(VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT)) != 0; + const bool hostAccessSequentialWrite = (allocCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT) != 0; + const bool hostAccessRandom = (allocCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) != 0; + const bool hostAccessAllowTransferInstead = (allocCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT) != 0; + const bool preferDevice = allocCreateInfo.usage == VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE; + const bool preferHost = allocCreateInfo.usage == VMA_MEMORY_USAGE_AUTO_PREFER_HOST; + + // CPU random access - e.g. a buffer written to or transferred from GPU to read back on CPU. + if(hostAccessRandom) + { + if(!isIntegratedGPU && deviceAccess && hostAccessAllowTransferInstead && !preferHost) + { + // Nice if it will end up in HOST_VISIBLE, but more importantly prefer DEVICE_LOCAL. + // Omitting HOST_VISIBLE here is intentional. + // In case there is DEVICE_LOCAL | HOST_VISIBLE | HOST_CACHED, it will pick that one. + // Otherwise, this will give same weight to DEVICE_LOCAL as HOST_VISIBLE | HOST_CACHED and select the former if occurs first on the list. + outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + } + else + { + // Always CPU memory, cached. + outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + } + } + // CPU sequential write - may be CPU or host-visible GPU memory, uncached and write-combined. + else if(hostAccessSequentialWrite) + { + // Want uncached and write-combined. + outNotPreferredFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; + + if(!isIntegratedGPU && deviceAccess && hostAccessAllowTransferInstead && !preferHost) + { + outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + } + else + { + outRequiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; + // Direct GPU access, CPU sequential write (e.g. a dynamic uniform buffer updated every frame) + if(deviceAccess) + { + // Could go to CPU memory or GPU BAR/unified. Up to the user to decide. If no preference, choose GPU memory. + if(preferHost) + outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + else + outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + // GPU no direct access, CPU sequential write (e.g. an upload buffer to be transferred to the GPU) + else + { + // Could go to CPU memory or GPU BAR/unified. Up to the user to decide. If no preference, choose CPU memory. + if(preferDevice) + outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + else + outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + } + } + // No CPU access + else + { + // GPU access, no CPU access (e.g. a color attachment image) - prefer GPU memory + if(deviceAccess) + { + // ...unless there is a clear preference from the user not to do so. + if(preferHost) + outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + else + outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + // No direct GPU access, no CPU access, just transfers. + // It may be staging copy intended for e.g. preserving image for next frame (then better GPU memory) or + // a "swap file" copy to free some GPU memory (then better CPU memory). + // Up to the user to decide. If no preferece, assume the former and choose GPU memory. + if(preferHost) + outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + else + outPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + } + break; + } + default: + VMA_ASSERT(0); + } + + // Avoid DEVICE_COHERENT unless explicitly requested. + if(((allocCreateInfo.requiredFlags | allocCreateInfo.preferredFlags) & + (VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY | VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY)) == 0) + { + outNotPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY; + } + + return true; +} + //////////////////////////////////////////////////////////////////////////////// // Memory allocation static void* VmaMalloc(const VkAllocationCallbacks* pAllocationCallbacks, size_t size, size_t alignment) { void* result = VMA_NULL; - if((pAllocationCallbacks != VMA_NULL) && + if ((pAllocationCallbacks != VMA_NULL) && (pAllocationCallbacks->pfnAllocation != VMA_NULL)) { result = (*pAllocationCallbacks->pfnAllocation)( @@ -3032,7 +3730,7 @@ static void* VmaMalloc(const VkAllocationCallbacks* pAllocationCallbacks, size_t static void VmaFree(const VkAllocationCallbacks* pAllocationCallbacks, void* ptr) { - if((pAllocationCallbacks != VMA_NULL) && + if ((pAllocationCallbacks != VMA_NULL) && (pAllocationCallbacks->pfnFree != VMA_NULL)) { (*pAllocationCallbacks->pfnFree)(pAllocationCallbacks->pUserData, ptr); @@ -3069,9 +3767,9 @@ static void vma_delete(const VkAllocationCallbacks* pAllocationCallbacks, T* ptr template static void vma_delete_array(const VkAllocationCallbacks* pAllocationCallbacks, T* ptr, size_t count) { - if(ptr != VMA_NULL) + if (ptr != VMA_NULL) { - for(size_t i = count; i--; ) + for (size_t i = count; i--; ) { ptr[i].~T(); } @@ -3081,317 +3779,39 @@ static void vma_delete_array(const VkAllocationCallbacks* pAllocationCallbacks, static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr) { - if(srcStr != VMA_NULL) + if (srcStr != VMA_NULL) { const size_t len = strlen(srcStr); char* const result = vma_new_array(allocs, char, len + 1); memcpy(result, srcStr, len + 1); return result; } - else - { - return VMA_NULL; - } + return VMA_NULL; } +#if VMA_STATS_STRING_ENABLED +static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr, size_t strLen) +{ + if (srcStr != VMA_NULL) + { + char* const result = vma_new_array(allocs, char, strLen + 1); + memcpy(result, srcStr, strLen); + result[strLen] = '\0'; + return result; + } + return VMA_NULL; +} +#endif // VMA_STATS_STRING_ENABLED + static void VmaFreeString(const VkAllocationCallbacks* allocs, char* str) { - if(str != VMA_NULL) + if (str != VMA_NULL) { const size_t len = strlen(str); vma_delete_array(allocs, str, len + 1); } } -// STL-compatible allocator. -template -class VmaStlAllocator -{ -public: - const VkAllocationCallbacks* const m_pCallbacks; - typedef T value_type; - - VmaStlAllocator(const VkAllocationCallbacks* pCallbacks) : m_pCallbacks(pCallbacks) { } - template VmaStlAllocator(const VmaStlAllocator& src) : m_pCallbacks(src.m_pCallbacks) { } - - T* allocate(size_t n) { return VmaAllocateArray(m_pCallbacks, n); } - void deallocate(T* p, size_t n) { VmaFree(m_pCallbacks, p); } - - template - bool operator==(const VmaStlAllocator& rhs) const - { - return m_pCallbacks == rhs.m_pCallbacks; - } - template - bool operator!=(const VmaStlAllocator& rhs) const - { - return m_pCallbacks != rhs.m_pCallbacks; - } - - VmaStlAllocator& operator=(const VmaStlAllocator& x) = delete; - VmaStlAllocator(const VmaStlAllocator&) = default; -}; - -#if VMA_USE_STL_VECTOR - -#define VmaVector std::vector - -template -static void VmaVectorInsert(std::vector& vec, size_t index, const T& item) -{ - vec.insert(vec.begin() + index, item); -} - -template -static void VmaVectorRemove(std::vector& vec, size_t index) -{ - vec.erase(vec.begin() + index); -} - -#else // #if VMA_USE_STL_VECTOR - -/* Class with interface compatible with subset of std::vector. -T must be POD because constructors and destructors are not called and memcpy is -used for these objects. */ -template -class VmaVector -{ -public: - typedef T value_type; - - VmaVector(const AllocatorT& allocator) : - m_Allocator(allocator), - m_pArray(VMA_NULL), - m_Count(0), - m_Capacity(0) - { - } - - VmaVector(size_t count, const AllocatorT& allocator) : - m_Allocator(allocator), - m_pArray(count ? (T*)VmaAllocateArray(allocator.m_pCallbacks, count) : VMA_NULL), - m_Count(count), - m_Capacity(count) - { - } - - // This version of the constructor is here for compatibility with pre-C++14 std::vector. - // value is unused. - VmaVector(size_t count, const T& value, const AllocatorT& allocator) - : VmaVector(count, allocator) {} - - VmaVector(const VmaVector& src) : - m_Allocator(src.m_Allocator), - m_pArray(src.m_Count ? (T*)VmaAllocateArray(src.m_Allocator.m_pCallbacks, src.m_Count) : VMA_NULL), - m_Count(src.m_Count), - m_Capacity(src.m_Count) - { - if(m_Count != 0) - { - memcpy(m_pArray, src.m_pArray, m_Count * sizeof(T)); - } - } - - ~VmaVector() - { - VmaFree(m_Allocator.m_pCallbacks, m_pArray); - } - - VmaVector& operator=(const VmaVector& rhs) - { - if(&rhs != this) - { - resize(rhs.m_Count); - if(m_Count != 0) - { - memcpy(m_pArray, rhs.m_pArray, m_Count * sizeof(T)); - } - } - return *this; - } - - bool empty() const { return m_Count == 0; } - size_t size() const { return m_Count; } - T* data() { return m_pArray; } - const T* data() const { return m_pArray; } - - T& operator[](size_t index) - { - VMA_HEAVY_ASSERT(index < m_Count); - return m_pArray[index]; - } - const T& operator[](size_t index) const - { - VMA_HEAVY_ASSERT(index < m_Count); - return m_pArray[index]; - } - - T& front() - { - VMA_HEAVY_ASSERT(m_Count > 0); - return m_pArray[0]; - } - const T& front() const - { - VMA_HEAVY_ASSERT(m_Count > 0); - return m_pArray[0]; - } - T& back() - { - VMA_HEAVY_ASSERT(m_Count > 0); - return m_pArray[m_Count - 1]; - } - const T& back() const - { - VMA_HEAVY_ASSERT(m_Count > 0); - return m_pArray[m_Count - 1]; - } - - void reserve(size_t newCapacity, bool freeMemory = false) - { - newCapacity = VMA_MAX(newCapacity, m_Count); - - if((newCapacity < m_Capacity) && !freeMemory) - { - newCapacity = m_Capacity; - } - - if(newCapacity != m_Capacity) - { - T* const newArray = newCapacity ? VmaAllocateArray(m_Allocator, newCapacity) : VMA_NULL; - if(m_Count != 0) - { - memcpy(newArray, m_pArray, m_Count * sizeof(T)); - } - VmaFree(m_Allocator.m_pCallbacks, m_pArray); - m_Capacity = newCapacity; - m_pArray = newArray; - } - } - - void resize(size_t newCount) - { - size_t newCapacity = m_Capacity; - if(newCount > m_Capacity) - { - newCapacity = VMA_MAX(newCount, VMA_MAX(m_Capacity * 3 / 2, (size_t)8)); - } - - if(newCapacity != m_Capacity) - { - T* const newArray = newCapacity ? VmaAllocateArray(m_Allocator.m_pCallbacks, newCapacity) : VMA_NULL; - const size_t elementsToCopy = VMA_MIN(m_Count, newCount); - if(elementsToCopy != 0) - { - memcpy(newArray, m_pArray, elementsToCopy * sizeof(T)); - } - VmaFree(m_Allocator.m_pCallbacks, m_pArray); - m_Capacity = newCapacity; - m_pArray = newArray; - } - - m_Count = newCount; - } - - void clear() - { - resize(0); - } - - void shrink_to_fit() - { - if(m_Capacity > m_Count) - { - T* newArray = VMA_NULL; - if(m_Count > 0) - { - newArray = VmaAllocateArray(m_Allocator.m_pCallbacks, m_Count); - memcpy(newArray, m_pArray, m_Count * sizeof(T)); - } - VmaFree(m_Allocator.m_pCallbacks, m_pArray); - m_Capacity = m_Count; - m_pArray = newArray; - } - } - - void insert(size_t index, const T& src) - { - VMA_HEAVY_ASSERT(index <= m_Count); - const size_t oldCount = size(); - resize(oldCount + 1); - if(index < oldCount) - { - memmove(m_pArray + (index + 1), m_pArray + index, (oldCount - index) * sizeof(T)); - } - m_pArray[index] = src; - } - - void remove(size_t index) - { - VMA_HEAVY_ASSERT(index < m_Count); - const size_t oldCount = size(); - if(index < oldCount - 1) - { - memmove(m_pArray + index, m_pArray + (index + 1), (oldCount - index - 1) * sizeof(T)); - } - resize(oldCount - 1); - } - - void push_back(const T& src) - { - const size_t newIndex = size(); - resize(newIndex + 1); - m_pArray[newIndex] = src; - } - - void pop_back() - { - VMA_HEAVY_ASSERT(m_Count > 0); - resize(size() - 1); - } - - void push_front(const T& src) - { - insert(0, src); - } - - void pop_front() - { - VMA_HEAVY_ASSERT(m_Count > 0); - remove(0); - } - - typedef T* iterator; - typedef const T* const_iterator; - - iterator begin() { return m_pArray; } - iterator end() { return m_pArray + m_Count; } - const_iterator cbegin() const { return m_pArray; } - const_iterator cend() const { return m_pArray + m_Count; } - const_iterator begin() const { return cbegin(); } - const_iterator end() const { return cend(); } - -private: - AllocatorT m_Allocator; - T* m_pArray; - size_t m_Count; - size_t m_Capacity; -}; - -template -static void VmaVectorInsert(VmaVector& vec, size_t index, const T& item) -{ - vec.insert(index, item); -} - -template -static void VmaVectorRemove(VmaVector& vec, size_t index) -{ - vec.remove(index); -} - -#endif // #if VMA_USE_STL_VECTOR - template size_t VmaVectorInsertSorted(VectorT& vector, const typename VectorT::value_type& value) { @@ -3413,7 +3833,7 @@ bool VmaVectorRemoveSorted(VectorT& vector, const typename VectorT::value_type& vector.end(), value, comparator); - if((it != vector.end()) && !comparator(*it, value) && !comparator(value, *it)) + if ((it != vector.end()) && !comparator(*it, value) && !comparator(value, *it)) { size_t indexToRemove = it - vector.begin(); VmaVectorRemove(vector, indexToRemove); @@ -3421,10 +3841,390 @@ bool VmaVectorRemoveSorted(VectorT& vector, const typename VectorT::value_type& } return false; } +#endif // _VMA_FUNCTIONS -//////////////////////////////////////////////////////////////////////////////// -// class VmaSmallVector +#ifndef _VMA_STATISTICS_FUNCTIONS +static void VmaClearStatistics(VmaStatistics& outStats) +{ + outStats.blockCount = 0; + outStats.allocationCount = 0; + outStats.blockBytes = 0; + outStats.allocationBytes = 0; +} + +static void VmaAddStatistics(VmaStatistics& inoutStats, const VmaStatistics& src) +{ + inoutStats.blockCount += src.blockCount; + inoutStats.allocationCount += src.allocationCount; + inoutStats.blockBytes += src.blockBytes; + inoutStats.allocationBytes += src.allocationBytes; +} + +static void VmaClearDetailedStatistics(VmaDetailedStatistics& outStats) +{ + VmaClearStatistics(outStats.statistics); + outStats.unusedRangeCount = 0; + outStats.allocationSizeMin = VK_WHOLE_SIZE; + outStats.allocationSizeMax = 0; + outStats.unusedRangeSizeMin = VK_WHOLE_SIZE; + outStats.unusedRangeSizeMax = 0; +} + +static void VmaAddDetailedStatisticsAllocation(VmaDetailedStatistics& inoutStats, VkDeviceSize size) +{ + inoutStats.statistics.allocationCount++; + inoutStats.statistics.allocationBytes += size; + inoutStats.allocationSizeMin = VMA_MIN(inoutStats.allocationSizeMin, size); + inoutStats.allocationSizeMax = VMA_MAX(inoutStats.allocationSizeMax, size); +} + +static void VmaAddDetailedStatisticsUnusedRange(VmaDetailedStatistics& inoutStats, VkDeviceSize size) +{ + inoutStats.unusedRangeCount++; + inoutStats.unusedRangeSizeMin = VMA_MIN(inoutStats.unusedRangeSizeMin, size); + inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, size); +} + +static void VmaAddDetailedStatistics(VmaDetailedStatistics& inoutStats, const VmaDetailedStatistics& src) +{ + VmaAddStatistics(inoutStats.statistics, src.statistics); + inoutStats.unusedRangeCount += src.unusedRangeCount; + inoutStats.allocationSizeMin = VMA_MIN(inoutStats.allocationSizeMin, src.allocationSizeMin); + inoutStats.allocationSizeMax = VMA_MAX(inoutStats.allocationSizeMax, src.allocationSizeMax); + inoutStats.unusedRangeSizeMin = VMA_MIN(inoutStats.unusedRangeSizeMin, src.unusedRangeSizeMin); + inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, src.unusedRangeSizeMax); +} + +#endif // _VMA_STATISTICS_FUNCTIONS + +#ifndef _VMA_MUTEX_LOCK +// Helper RAII class to lock a mutex in constructor and unlock it in destructor (at the end of scope). +struct VmaMutexLock +{ + VMA_CLASS_NO_COPY(VmaMutexLock) +public: + VmaMutexLock(VMA_MUTEX& mutex, bool useMutex = true) : + m_pMutex(useMutex ? &mutex : VMA_NULL) + { + if (m_pMutex) { m_pMutex->Lock(); } + } + ~VmaMutexLock() { if (m_pMutex) { m_pMutex->Unlock(); } } + +private: + VMA_MUTEX* m_pMutex; +}; + +// Helper RAII class to lock a RW mutex in constructor and unlock it in destructor (at the end of scope), for reading. +struct VmaMutexLockRead +{ + VMA_CLASS_NO_COPY(VmaMutexLockRead) +public: + VmaMutexLockRead(VMA_RW_MUTEX& mutex, bool useMutex) : + m_pMutex(useMutex ? &mutex : VMA_NULL) + { + if (m_pMutex) { m_pMutex->LockRead(); } + } + ~VmaMutexLockRead() { if (m_pMutex) { m_pMutex->UnlockRead(); } } + +private: + VMA_RW_MUTEX* m_pMutex; +}; + +// Helper RAII class to lock a RW mutex in constructor and unlock it in destructor (at the end of scope), for writing. +struct VmaMutexLockWrite +{ + VMA_CLASS_NO_COPY(VmaMutexLockWrite) +public: + VmaMutexLockWrite(VMA_RW_MUTEX& mutex, bool useMutex) + : m_pMutex(useMutex ? &mutex : VMA_NULL) + { + if (m_pMutex) { m_pMutex->LockWrite(); } + } + ~VmaMutexLockWrite() { if (m_pMutex) { m_pMutex->UnlockWrite(); } } + +private: + VMA_RW_MUTEX* m_pMutex; +}; + +#if VMA_DEBUG_GLOBAL_MUTEX + static VMA_MUTEX gDebugGlobalMutex; + #define VMA_DEBUG_GLOBAL_MUTEX_LOCK VmaMutexLock debugGlobalMutexLock(gDebugGlobalMutex, true); +#else + #define VMA_DEBUG_GLOBAL_MUTEX_LOCK +#endif +#endif // _VMA_MUTEX_LOCK + +#ifndef _VMA_ATOMIC_TRANSACTIONAL_INCREMENT +// An object that increments given atomic but decrements it back in the destructor unless Commit() is called. +template +struct AtomicTransactionalIncrement +{ +public: + typedef std::atomic AtomicT; + + ~AtomicTransactionalIncrement() + { + if(m_Atomic) + --(*m_Atomic); + } + + void Commit() { m_Atomic = nullptr; } + T Increment(AtomicT* atomic) + { + m_Atomic = atomic; + return m_Atomic->fetch_add(1); + } + +private: + AtomicT* m_Atomic = nullptr; +}; +#endif // _VMA_ATOMIC_TRANSACTIONAL_INCREMENT + +#ifndef _VMA_STL_ALLOCATOR +// STL-compatible allocator. +template +struct VmaStlAllocator +{ + const VkAllocationCallbacks* const m_pCallbacks; + typedef T value_type; + + VmaStlAllocator(const VkAllocationCallbacks* pCallbacks) : m_pCallbacks(pCallbacks) {} + template + VmaStlAllocator(const VmaStlAllocator& src) : m_pCallbacks(src.m_pCallbacks) {} + VmaStlAllocator(const VmaStlAllocator&) = default; + VmaStlAllocator& operator=(const VmaStlAllocator&) = delete; + + T* allocate(size_t n) { return VmaAllocateArray(m_pCallbacks, n); } + void deallocate(T* p, size_t n) { VmaFree(m_pCallbacks, p); } + + template + bool operator==(const VmaStlAllocator& rhs) const + { + return m_pCallbacks == rhs.m_pCallbacks; + } + template + bool operator!=(const VmaStlAllocator& rhs) const + { + return m_pCallbacks != rhs.m_pCallbacks; + } +}; +#endif // _VMA_STL_ALLOCATOR + +#ifndef _VMA_VECTOR +/* Class with interface compatible with subset of std::vector. +T must be POD because constructors and destructors are not called and memcpy is +used for these objects. */ +template +class VmaVector +{ +public: + typedef T value_type; + typedef T* iterator; + typedef const T* const_iterator; + + VmaVector(const AllocatorT& allocator); + VmaVector(size_t count, const AllocatorT& allocator); + // This version of the constructor is here for compatibility with pre-C++14 std::vector. + // value is unused. + VmaVector(size_t count, const T& value, const AllocatorT& allocator) : VmaVector(count, allocator) {} + VmaVector(const VmaVector& src); + VmaVector& operator=(const VmaVector& rhs); + ~VmaVector() { VmaFree(m_Allocator.m_pCallbacks, m_pArray); } + + bool empty() const { return m_Count == 0; } + size_t size() const { return m_Count; } + T* data() { return m_pArray; } + T& front() { VMA_HEAVY_ASSERT(m_Count > 0); return m_pArray[0]; } + T& back() { VMA_HEAVY_ASSERT(m_Count > 0); return m_pArray[m_Count - 1]; } + const T* data() const { return m_pArray; } + const T& front() const { VMA_HEAVY_ASSERT(m_Count > 0); return m_pArray[0]; } + const T& back() const { VMA_HEAVY_ASSERT(m_Count > 0); return m_pArray[m_Count - 1]; } + + iterator begin() { return m_pArray; } + iterator end() { return m_pArray + m_Count; } + const_iterator cbegin() const { return m_pArray; } + const_iterator cend() const { return m_pArray + m_Count; } + const_iterator begin() const { return cbegin(); } + const_iterator end() const { return cend(); } + + void pop_front() { VMA_HEAVY_ASSERT(m_Count > 0); remove(0); } + void pop_back() { VMA_HEAVY_ASSERT(m_Count > 0); resize(size() - 1); } + void push_front(const T& src) { insert(0, src); } + + void push_back(const T& src); + void reserve(size_t newCapacity, bool freeMemory = false); + void resize(size_t newCount); + void clear() { resize(0); } + void shrink_to_fit(); + void insert(size_t index, const T& src); + void remove(size_t index); + + T& operator[](size_t index) { VMA_HEAVY_ASSERT(index < m_Count); return m_pArray[index]; } + const T& operator[](size_t index) const { VMA_HEAVY_ASSERT(index < m_Count); return m_pArray[index]; } + +private: + AllocatorT m_Allocator; + T* m_pArray; + size_t m_Count; + size_t m_Capacity; +}; + +#ifndef _VMA_VECTOR_FUNCTIONS +template +VmaVector::VmaVector(const AllocatorT& allocator) + : m_Allocator(allocator), + m_pArray(VMA_NULL), + m_Count(0), + m_Capacity(0) {} + +template +VmaVector::VmaVector(size_t count, const AllocatorT& allocator) + : m_Allocator(allocator), + m_pArray(count ? (T*)VmaAllocateArray(allocator.m_pCallbacks, count) : VMA_NULL), + m_Count(count), + m_Capacity(count) {} + +template +VmaVector::VmaVector(const VmaVector& src) + : m_Allocator(src.m_Allocator), + m_pArray(src.m_Count ? (T*)VmaAllocateArray(src.m_Allocator.m_pCallbacks, src.m_Count) : VMA_NULL), + m_Count(src.m_Count), + m_Capacity(src.m_Count) +{ + if (m_Count != 0) + { + memcpy(m_pArray, src.m_pArray, m_Count * sizeof(T)); + } +} + +template +VmaVector& VmaVector::operator=(const VmaVector& rhs) +{ + if (&rhs != this) + { + resize(rhs.m_Count); + if (m_Count != 0) + { + memcpy(m_pArray, rhs.m_pArray, m_Count * sizeof(T)); + } + } + return *this; +} + +template +void VmaVector::push_back(const T& src) +{ + const size_t newIndex = size(); + resize(newIndex + 1); + m_pArray[newIndex] = src; +} + +template +void VmaVector::reserve(size_t newCapacity, bool freeMemory) +{ + newCapacity = VMA_MAX(newCapacity, m_Count); + + if ((newCapacity < m_Capacity) && !freeMemory) + { + newCapacity = m_Capacity; + } + + if (newCapacity != m_Capacity) + { + T* const newArray = newCapacity ? VmaAllocateArray(m_Allocator, newCapacity) : VMA_NULL; + if (m_Count != 0) + { + memcpy(newArray, m_pArray, m_Count * sizeof(T)); + } + VmaFree(m_Allocator.m_pCallbacks, m_pArray); + m_Capacity = newCapacity; + m_pArray = newArray; + } +} + +template +void VmaVector::resize(size_t newCount) +{ + size_t newCapacity = m_Capacity; + if (newCount > m_Capacity) + { + newCapacity = VMA_MAX(newCount, VMA_MAX(m_Capacity * 3 / 2, (size_t)8)); + } + + if (newCapacity != m_Capacity) + { + T* const newArray = newCapacity ? VmaAllocateArray(m_Allocator.m_pCallbacks, newCapacity) : VMA_NULL; + const size_t elementsToCopy = VMA_MIN(m_Count, newCount); + if (elementsToCopy != 0) + { + memcpy(newArray, m_pArray, elementsToCopy * sizeof(T)); + } + VmaFree(m_Allocator.m_pCallbacks, m_pArray); + m_Capacity = newCapacity; + m_pArray = newArray; + } + + m_Count = newCount; +} + +template +void VmaVector::shrink_to_fit() +{ + if (m_Capacity > m_Count) + { + T* newArray = VMA_NULL; + if (m_Count > 0) + { + newArray = VmaAllocateArray(m_Allocator.m_pCallbacks, m_Count); + memcpy(newArray, m_pArray, m_Count * sizeof(T)); + } + VmaFree(m_Allocator.m_pCallbacks, m_pArray); + m_Capacity = m_Count; + m_pArray = newArray; + } +} + +template +void VmaVector::insert(size_t index, const T& src) +{ + VMA_HEAVY_ASSERT(index <= m_Count); + const size_t oldCount = size(); + resize(oldCount + 1); + if (index < oldCount) + { + memmove(m_pArray + (index + 1), m_pArray + index, (oldCount - index) * sizeof(T)); + } + m_pArray[index] = src; +} + +template +void VmaVector::remove(size_t index) +{ + VMA_HEAVY_ASSERT(index < m_Count); + const size_t oldCount = size(); + if (index < oldCount - 1) + { + memmove(m_pArray + index, m_pArray + (index + 1), (oldCount - index - 1) * sizeof(T)); + } + resize(oldCount - 1); +} +#endif // _VMA_VECTOR_FUNCTIONS + +template +static void VmaVectorInsert(VmaVector& vec, size_t index, const T& item) +{ + vec.insert(index, item); +} + +template +static void VmaVectorRemove(VmaVector& vec, size_t index) +{ + vec.remove(index); +} +#endif // _VMA_VECTOR + +#ifndef _VMA_SMALL_VECTOR /* This is a vector (a variable-sized array), optimized for the case when the array is small. @@ -3432,180 +4232,155 @@ It contains some number of elements in-place, which allows it to avoid heap allo when the actual number of elements is below that threshold. This allows normal "small" cases to be fast without losing generality for large inputs. */ - template class VmaSmallVector { public: typedef T value_type; + typedef T* iterator; - VmaSmallVector(const AllocatorT& allocator) : - m_Count(0), - m_DynamicArray(allocator) - { - } - VmaSmallVector(size_t count, const AllocatorT& allocator) : - m_Count(count), - m_DynamicArray(count > N ? count : 0, allocator) - { - } + VmaSmallVector(const AllocatorT& allocator); + VmaSmallVector(size_t count, const AllocatorT& allocator); template - VmaSmallVector(const VmaSmallVector& src) = delete; + VmaSmallVector(const VmaSmallVector&) = delete; template - VmaSmallVector& operator=(const VmaSmallVector& rhs) = delete; + VmaSmallVector& operator=(const VmaSmallVector&) = delete; + ~VmaSmallVector() = default; bool empty() const { return m_Count == 0; } size_t size() const { return m_Count; } T* data() { return m_Count > N ? m_DynamicArray.data() : m_StaticArray; } + T& front() { VMA_HEAVY_ASSERT(m_Count > 0); return data()[0]; } + T& back() { VMA_HEAVY_ASSERT(m_Count > 0); return data()[m_Count - 1]; } const T* data() const { return m_Count > N ? m_DynamicArray.data() : m_StaticArray; } - - T& operator[](size_t index) - { - VMA_HEAVY_ASSERT(index < m_Count); - return data()[index]; - } - const T& operator[](size_t index) const - { - VMA_HEAVY_ASSERT(index < m_Count); - return data()[index]; - } - - T& front() - { - VMA_HEAVY_ASSERT(m_Count > 0); - return data()[0]; - } - const T& front() const - { - VMA_HEAVY_ASSERT(m_Count > 0); - return data()[0]; - } - T& back() - { - VMA_HEAVY_ASSERT(m_Count > 0); - return data()[m_Count - 1]; - } - const T& back() const - { - VMA_HEAVY_ASSERT(m_Count > 0); - return data()[m_Count - 1]; - } - - void resize(size_t newCount, bool freeMemory = false) - { - if(newCount > N && m_Count > N) - { - // Any direction, staying in m_DynamicArray - m_DynamicArray.resize(newCount); - if(freeMemory) - { - m_DynamicArray.shrink_to_fit(); - } - } - else if(newCount > N && m_Count <= N) - { - // Growing, moving from m_StaticArray to m_DynamicArray - m_DynamicArray.resize(newCount); - if(m_Count > 0) - { - memcpy(m_DynamicArray.data(), m_StaticArray, m_Count * sizeof(T)); - } - } - else if(newCount <= N && m_Count > N) - { - // Shrinking, moving from m_DynamicArray to m_StaticArray - if(newCount > 0) - { - memcpy(m_StaticArray, m_DynamicArray.data(), newCount * sizeof(T)); - } - m_DynamicArray.resize(0); - if(freeMemory) - { - m_DynamicArray.shrink_to_fit(); - } - } - else - { - // Any direction, staying in m_StaticArray - nothing to do here - } - m_Count = newCount; - } - - void clear(bool freeMemory = false) - { - m_DynamicArray.clear(); - if(freeMemory) - { - m_DynamicArray.shrink_to_fit(); - } - m_Count = 0; - } - - void insert(size_t index, const T& src) - { - VMA_HEAVY_ASSERT(index <= m_Count); - const size_t oldCount = size(); - resize(oldCount + 1); - T* const dataPtr = data(); - if(index < oldCount) - { - // I know, this could be more optimal for case where memmove can be memcpy directly from m_StaticArray to m_DynamicArray. - memmove(dataPtr + (index + 1), dataPtr + index, (oldCount - index) * sizeof(T)); - } - dataPtr[index] = src; - } - - void remove(size_t index) - { - VMA_HEAVY_ASSERT(index < m_Count); - const size_t oldCount = size(); - if(index < oldCount - 1) - { - // I know, this could be more optimal for case where memmove can be memcpy directly from m_DynamicArray to m_StaticArray. - T* const dataPtr = data(); - memmove(dataPtr + index, dataPtr + (index + 1), (oldCount - index - 1) * sizeof(T)); - } - resize(oldCount - 1); - } - - void push_back(const T& src) - { - const size_t newIndex = size(); - resize(newIndex + 1); - data()[newIndex] = src; - } - - void pop_back() - { - VMA_HEAVY_ASSERT(m_Count > 0); - resize(size() - 1); - } - - void push_front(const T& src) - { - insert(0, src); - } - - void pop_front() - { - VMA_HEAVY_ASSERT(m_Count > 0); - remove(0); - } - - typedef T* iterator; + const T& front() const { VMA_HEAVY_ASSERT(m_Count > 0); return data()[0]; } + const T& back() const { VMA_HEAVY_ASSERT(m_Count > 0); return data()[m_Count - 1]; } iterator begin() { return data(); } iterator end() { return data() + m_Count; } + void pop_front() { VMA_HEAVY_ASSERT(m_Count > 0); remove(0); } + void pop_back() { VMA_HEAVY_ASSERT(m_Count > 0); resize(size() - 1); } + void push_front(const T& src) { insert(0, src); } + + void push_back(const T& src); + void resize(size_t newCount, bool freeMemory = false); + void clear(bool freeMemory = false); + void insert(size_t index, const T& src); + void remove(size_t index); + + T& operator[](size_t index) { VMA_HEAVY_ASSERT(index < m_Count); return data()[index]; } + const T& operator[](size_t index) const { VMA_HEAVY_ASSERT(index < m_Count); return data()[index]; } + private: size_t m_Count; T m_StaticArray[N]; // Used when m_Size <= N VmaVector m_DynamicArray; // Used when m_Size > N }; -//////////////////////////////////////////////////////////////////////////////// -// class VmaPoolAllocator +#ifndef _VMA_SMALL_VECTOR_FUNCTIONS +template +VmaSmallVector::VmaSmallVector(const AllocatorT& allocator) + : m_Count(0), + m_DynamicArray(allocator) {} +template +VmaSmallVector::VmaSmallVector(size_t count, const AllocatorT& allocator) + : m_Count(count), + m_DynamicArray(count > N ? count : 0, allocator) {} + +template +void VmaSmallVector::push_back(const T& src) +{ + const size_t newIndex = size(); + resize(newIndex + 1); + data()[newIndex] = src; +} + +template +void VmaSmallVector::resize(size_t newCount, bool freeMemory) +{ + if (newCount > N && m_Count > N) + { + // Any direction, staying in m_DynamicArray + m_DynamicArray.resize(newCount); + if (freeMemory) + { + m_DynamicArray.shrink_to_fit(); + } + } + else if (newCount > N && m_Count <= N) + { + // Growing, moving from m_StaticArray to m_DynamicArray + m_DynamicArray.resize(newCount); + if (m_Count > 0) + { + memcpy(m_DynamicArray.data(), m_StaticArray, m_Count * sizeof(T)); + } + } + else if (newCount <= N && m_Count > N) + { + // Shrinking, moving from m_DynamicArray to m_StaticArray + if (newCount > 0) + { + memcpy(m_StaticArray, m_DynamicArray.data(), newCount * sizeof(T)); + } + m_DynamicArray.resize(0); + if (freeMemory) + { + m_DynamicArray.shrink_to_fit(); + } + } + else + { + // Any direction, staying in m_StaticArray - nothing to do here + } + m_Count = newCount; +} + +template +void VmaSmallVector::clear(bool freeMemory) +{ + m_DynamicArray.clear(); + if (freeMemory) + { + m_DynamicArray.shrink_to_fit(); + } + m_Count = 0; +} + +template +void VmaSmallVector::insert(size_t index, const T& src) +{ + VMA_HEAVY_ASSERT(index <= m_Count); + const size_t oldCount = size(); + resize(oldCount + 1); + T* const dataPtr = data(); + if (index < oldCount) + { + // I know, this could be more optimal for case where memmove can be memcpy directly from m_StaticArray to m_DynamicArray. + memmove(dataPtr + (index + 1), dataPtr + index, (oldCount - index) * sizeof(T)); + } + dataPtr[index] = src; +} + +template +void VmaSmallVector::remove(size_t index) +{ + VMA_HEAVY_ASSERT(index < m_Count); + const size_t oldCount = size(); + if (index < oldCount - 1) + { + // I know, this could be more optimal for case where memmove can be memcpy directly from m_DynamicArray to m_StaticArray. + T* const dataPtr = data(); + memmove(dataPtr + index, dataPtr + (index + 1), (oldCount - index - 1) * sizeof(T)); + } + resize(oldCount - 1); +} +#endif // _VMA_SMALL_VECTOR_FUNCTIONS +#endif // _VMA_SMALL_VECTOR + +#ifndef _VMA_POOL_ALLOCATOR /* Allocator for objects of type T using a list of arrays (pools) to speed up allocation. Number of elements that can be allocated is not bounded because @@ -3627,7 +4402,6 @@ private: uint32_t NextFreeIndex; alignas(T) char Value[sizeof(T)]; }; - struct ItemBlock { Item* pItems; @@ -3637,14 +4411,15 @@ private: const VkAllocationCallbacks* m_pAllocationCallbacks; const uint32_t m_FirstBlockCapacity; - VmaVector< ItemBlock, VmaStlAllocator > m_ItemBlocks; + VmaVector> m_ItemBlocks; ItemBlock& CreateNewBlock(); }; +#ifndef _VMA_POOL_ALLOCATOR_FUNCTIONS template -VmaPoolAllocator::VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, uint32_t firstBlockCapacity) : - m_pAllocationCallbacks(pAllocationCallbacks), +VmaPoolAllocator::VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCallbacks, uint32_t firstBlockCapacity) + : m_pAllocationCallbacks(pAllocationCallbacks), m_FirstBlockCapacity(firstBlockCapacity), m_ItemBlocks(VmaStlAllocator(pAllocationCallbacks)) { @@ -3654,7 +4429,7 @@ VmaPoolAllocator::VmaPoolAllocator(const VkAllocationCallbacks* pAllocationCa template VmaPoolAllocator::~VmaPoolAllocator() { - for(size_t i = m_ItemBlocks.size(); i--; ) + for (size_t i = m_ItemBlocks.size(); i--;) vma_delete_array(m_pAllocationCallbacks, m_ItemBlocks[i].pItems, m_ItemBlocks[i].Capacity); m_ItemBlocks.clear(); } @@ -3662,11 +4437,11 @@ VmaPoolAllocator::~VmaPoolAllocator() template template T* VmaPoolAllocator::Alloc(Types&&... args) { - for(size_t i = m_ItemBlocks.size(); i--; ) + for (size_t i = m_ItemBlocks.size(); i--; ) { ItemBlock& block = m_ItemBlocks[i]; // This block has some free items: Use first one. - if(block.FirstFreeIndex != UINT32_MAX) + if (block.FirstFreeIndex != UINT32_MAX) { Item* const pItem = &block.pItems[block.FirstFreeIndex]; block.FirstFreeIndex = pItem->NextFreeIndex; @@ -3681,7 +4456,7 @@ template T* VmaPoolAllocator::Alloc(Types&&... args) Item* const pItem = &newBlock.pItems[0]; newBlock.FirstFreeIndex = pItem->NextFreeIndex; T* result = (T*)&pItem->Value; - new(result)T(std::forward(args)...); // Explicit constructor call. + new(result) T(std::forward(args)...); // Explicit constructor call. return result; } @@ -3689,7 +4464,7 @@ template void VmaPoolAllocator::Free(T* ptr) { // Search all memory blocks to find ptr. - for(size_t i = m_ItemBlocks.size(); i--; ) + for (size_t i = m_ItemBlocks.size(); i--; ) { ItemBlock& block = m_ItemBlocks[i]; @@ -3698,7 +4473,7 @@ void VmaPoolAllocator::Free(T* ptr) memcpy(&pItemPtr, &ptr, sizeof(pItemPtr)); // Check if pItemPtr is in address range of this block. - if((pItemPtr >= block.pItems) && (pItemPtr < block.pItems + block.Capacity)) + if ((pItemPtr >= block.pItems) && (pItemPtr < block.pItems + block.Capacity)) { ptr->~T(); // Explicit destructor call. const uint32_t index = static_cast(pItemPtr - block.pItems); @@ -3716,29 +4491,25 @@ typename VmaPoolAllocator::ItemBlock& VmaPoolAllocator::CreateNewBlock() const uint32_t newBlockCapacity = m_ItemBlocks.empty() ? m_FirstBlockCapacity : m_ItemBlocks.back().Capacity * 3 / 2; - const ItemBlock newBlock = { + const ItemBlock newBlock = + { vma_new_array(m_pAllocationCallbacks, Item, newBlockCapacity), newBlockCapacity, - 0 }; + 0 + }; m_ItemBlocks.push_back(newBlock); // Setup singly-linked list of all free items in this block. - for(uint32_t i = 0; i < newBlockCapacity - 1; ++i) + for (uint32_t i = 0; i < newBlockCapacity - 1; ++i) newBlock.pItems[i].NextFreeIndex = i + 1; newBlock.pItems[newBlockCapacity - 1].NextFreeIndex = UINT32_MAX; return m_ItemBlocks.back(); } +#endif // _VMA_POOL_ALLOCATOR_FUNCTIONS +#endif // _VMA_POOL_ALLOCATOR -//////////////////////////////////////////////////////////////////////////////// -// class VmaRawList, VmaList - -#if VMA_USE_STL_LIST - -#define VmaList std::list - -#else // #if VMA_USE_STL_LIST - +#ifndef _VMA_RAW_LIST template struct VmaListItem { @@ -3756,32 +4527,33 @@ public: typedef VmaListItem ItemType; VmaRawList(const VkAllocationCallbacks* pAllocationCallbacks); - ~VmaRawList(); - void Clear(); + // Intentionally not calling Clear, because that would be unnecessary + // computations to return all items to m_ItemAllocator as free. + ~VmaRawList() = default; size_t GetCount() const { return m_Count; } bool IsEmpty() const { return m_Count == 0; } ItemType* Front() { return m_pFront; } - const ItemType* Front() const { return m_pFront; } ItemType* Back() { return m_pBack; } + const ItemType* Front() const { return m_pFront; } const ItemType* Back() const { return m_pBack; } - ItemType* PushBack(); ItemType* PushFront(); - ItemType* PushBack(const T& value); + ItemType* PushBack(); ItemType* PushFront(const T& value); - void PopBack(); + ItemType* PushBack(const T& value); void PopFront(); + void PopBack(); // Item can be null - it means PushBack. ItemType* InsertBefore(ItemType* pItem); // Item can be null - it means PushFront. ItemType* InsertAfter(ItemType* pItem); - ItemType* InsertBefore(ItemType* pItem, const T& value); ItemType* InsertAfter(ItemType* pItem, const T& value); + void Clear(); void Remove(ItemType* pItem); private: @@ -3792,39 +4564,35 @@ private: size_t m_Count; }; +#ifndef _VMA_RAW_LIST_FUNCTIONS template -VmaRawList::VmaRawList(const VkAllocationCallbacks* pAllocationCallbacks) : - m_pAllocationCallbacks(pAllocationCallbacks), +VmaRawList::VmaRawList(const VkAllocationCallbacks* pAllocationCallbacks) + : m_pAllocationCallbacks(pAllocationCallbacks), m_ItemAllocator(pAllocationCallbacks, 128), m_pFront(VMA_NULL), m_pBack(VMA_NULL), - m_Count(0) -{ -} + m_Count(0) {} template -VmaRawList::~VmaRawList() +VmaListItem* VmaRawList::PushFront() { - // Intentionally not calling Clear, because that would be unnecessary - // computations to return all items to m_ItemAllocator as free. -} - -template -void VmaRawList::Clear() -{ - if(IsEmpty() == false) + ItemType* const pNewItem = m_ItemAllocator.Alloc(); + pNewItem->pPrev = VMA_NULL; + if (IsEmpty()) { - ItemType* pItem = m_pBack; - while(pItem != VMA_NULL) - { - ItemType* const pPrevItem = pItem->pPrev; - m_ItemAllocator.Free(pItem); - pItem = pPrevItem; - } - m_pFront = VMA_NULL; - m_pBack = VMA_NULL; - m_Count = 0; + pNewItem->pNext = VMA_NULL; + m_pFront = pNewItem; + m_pBack = pNewItem; + m_Count = 1; } + else + { + pNewItem->pNext = m_pFront; + m_pFront->pPrev = pNewItem; + m_pFront = pNewItem; + ++m_Count; + } + return pNewItem; } template @@ -3850,24 +4618,10 @@ VmaListItem* VmaRawList::PushBack() } template -VmaListItem* VmaRawList::PushFront() +VmaListItem* VmaRawList::PushFront(const T& value) { - ItemType* const pNewItem = m_ItemAllocator.Alloc(); - pNewItem->pPrev = VMA_NULL; - if(IsEmpty()) - { - pNewItem->pNext = VMA_NULL; - m_pFront = pNewItem; - m_pBack = pNewItem; - m_Count = 1; - } - else - { - pNewItem->pNext = m_pFront; - m_pFront->pPrev = pNewItem; - m_pFront = pNewItem; - ++m_Count; - } + ItemType* const pNewItem = PushFront(); + pNewItem->Value = value; return pNewItem; } @@ -3880,11 +4634,18 @@ VmaListItem* VmaRawList::PushBack(const T& value) } template -VmaListItem* VmaRawList::PushFront(const T& value) +void VmaRawList::PopFront() { - ItemType* const pNewItem = PushFront(); - pNewItem->Value = value; - return pNewItem; + VMA_HEAVY_ASSERT(m_Count > 0); + ItemType* const pFrontItem = m_pFront; + ItemType* const pNextItem = pFrontItem->pNext; + if (pNextItem != VMA_NULL) + { + pNextItem->pPrev = VMA_NULL; + } + m_pFront = pNextItem; + m_ItemAllocator.Free(pFrontItem); + --m_Count; } template @@ -3903,18 +4664,21 @@ void VmaRawList::PopBack() } template -void VmaRawList::PopFront() +void VmaRawList::Clear() { - VMA_HEAVY_ASSERT(m_Count > 0); - ItemType* const pFrontItem = m_pFront; - ItemType* const pNextItem = pFrontItem->pNext; - if(pNextItem != VMA_NULL) + if (IsEmpty() == false) { - pNextItem->pPrev = VMA_NULL; + ItemType* pItem = m_pBack; + while (pItem != VMA_NULL) + { + ItemType* const pPrevItem = pItem->pPrev; + m_ItemAllocator.Free(pItem); + pItem = pPrevItem; + } + m_pFront = VMA_NULL; + m_pBack = VMA_NULL; + m_Count = 0; } - m_pFront = pNextItem; - m_ItemAllocator.Free(pFrontItem); - --m_Count; } template @@ -4014,173 +4778,129 @@ VmaListItem* VmaRawList::InsertAfter(ItemType* pItem, const T& value) newItem->Value = value; return newItem; } +#endif // _VMA_RAW_LIST_FUNCTIONS +#endif // _VMA_RAW_LIST +#ifndef _VMA_LIST template class VmaList { VMA_CLASS_NO_COPY(VmaList) public: + class reverse_iterator; + class const_iterator; + class const_reverse_iterator; + class iterator { + friend class const_iterator; + friend class VmaList; public: - iterator() : - m_pList(VMA_NULL), - m_pItem(VMA_NULL) - { - } + iterator() : m_pList(VMA_NULL), m_pItem(VMA_NULL) {} + iterator(const reverse_iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {} - T& operator*() const - { - VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); - return m_pItem->Value; - } - T* operator->() const - { - VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); - return &m_pItem->Value; - } + T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return m_pItem->Value; } + T* operator->() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return &m_pItem->Value; } - iterator& operator++() - { - VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); - m_pItem = m_pItem->pNext; - return *this; - } - iterator& operator--() - { - if(m_pItem != VMA_NULL) - { - m_pItem = m_pItem->pPrev; - } - else - { - VMA_HEAVY_ASSERT(!m_pList->IsEmpty()); - m_pItem = m_pList->Back(); - } - return *this; - } + bool operator==(const iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem == rhs.m_pItem; } + bool operator!=(const iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem != rhs.m_pItem; } - iterator operator++(int) - { - iterator result = *this; - ++*this; - return result; - } - iterator operator--(int) - { - iterator result = *this; - --*this; - return result; - } + iterator operator++(int) { iterator result = *this; ++*this; return result; } + iterator operator--(int) { iterator result = *this; --*this; return result; } - bool operator==(const iterator& rhs) const - { - VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); - return m_pItem == rhs.m_pItem; - } - bool operator!=(const iterator& rhs) const - { - VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); - return m_pItem != rhs.m_pItem; - } + iterator& operator++() { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); m_pItem = m_pItem->pNext; return *this; } + iterator& operator--(); private: VmaRawList* m_pList; VmaListItem* m_pItem; - iterator(VmaRawList* pList, VmaListItem* pItem) : - m_pList(pList), - m_pItem(pItem) - { - } - - friend class VmaList; + iterator(VmaRawList* pList, VmaListItem* pItem) : m_pList(pList), m_pItem(pItem) {} }; - - class const_iterator + class reverse_iterator { + friend class const_reverse_iterator; + friend class VmaList; public: - const_iterator() : - m_pList(VMA_NULL), - m_pItem(VMA_NULL) - { - } + reverse_iterator() : m_pList(VMA_NULL), m_pItem(VMA_NULL) {} + reverse_iterator(const iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {} - const_iterator(const iterator& src) : - m_pList(src.m_pList), - m_pItem(src.m_pItem) - { - } + T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return m_pItem->Value; } + T* operator->() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return &m_pItem->Value; } - const T& operator*() const - { - VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); - return m_pItem->Value; - } - const T* operator->() const - { - VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); - return &m_pItem->Value; - } + bool operator==(const reverse_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem == rhs.m_pItem; } + bool operator!=(const reverse_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem != rhs.m_pItem; } - const_iterator& operator++() - { - VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); - m_pItem = m_pItem->pNext; - return *this; - } - const_iterator& operator--() - { - if(m_pItem != VMA_NULL) - { - m_pItem = m_pItem->pPrev; - } - else - { - VMA_HEAVY_ASSERT(!m_pList->IsEmpty()); - m_pItem = m_pList->Back(); - } - return *this; - } + reverse_iterator operator++(int) { reverse_iterator result = *this; ++* this; return result; } + reverse_iterator operator--(int) { reverse_iterator result = *this; --* this; return result; } - const_iterator operator++(int) - { - const_iterator result = *this; - ++*this; - return result; - } - const_iterator operator--(int) - { - const_iterator result = *this; - --*this; - return result; - } - - bool operator==(const const_iterator& rhs) const - { - VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); - return m_pItem == rhs.m_pItem; - } - bool operator!=(const const_iterator& rhs) const - { - VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); - return m_pItem != rhs.m_pItem; - } + reverse_iterator& operator++() { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); m_pItem = m_pItem->pPrev; return *this; } + reverse_iterator& operator--(); private: - const_iterator(const VmaRawList* pList, const VmaListItem* pItem) : - m_pList(pList), - m_pItem(pItem) - { - } + VmaRawList* m_pList; + VmaListItem* m_pItem; + reverse_iterator(VmaRawList* pList, VmaListItem* pItem) : m_pList(pList), m_pItem(pItem) {} + }; + class const_iterator + { + friend class VmaList; + public: + const_iterator() : m_pList(VMA_NULL), m_pItem(VMA_NULL) {} + const_iterator(const iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {} + const_iterator(const reverse_iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {} + + iterator drop_const() { return { const_cast*>(m_pList), const_cast*>(m_pItem) }; } + + const T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return m_pItem->Value; } + const T* operator->() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return &m_pItem->Value; } + + bool operator==(const const_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem == rhs.m_pItem; } + bool operator!=(const const_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem != rhs.m_pItem; } + + const_iterator operator++(int) { const_iterator result = *this; ++* this; return result; } + const_iterator operator--(int) { const_iterator result = *this; --* this; return result; } + + const_iterator& operator++() { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); m_pItem = m_pItem->pNext; return *this; } + const_iterator& operator--(); + + private: const VmaRawList* m_pList; const VmaListItem* m_pItem; + const_iterator(const VmaRawList* pList, const VmaListItem* pItem) : m_pList(pList), m_pItem(pItem) {} + }; + class const_reverse_iterator + { friend class VmaList; + public: + const_reverse_iterator() : m_pList(VMA_NULL), m_pItem(VMA_NULL) {} + const_reverse_iterator(const reverse_iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {} + const_reverse_iterator(const iterator& src) : m_pList(src.m_pList), m_pItem(src.m_pItem) {} + + reverse_iterator drop_const() { return { const_cast*>(m_pList), const_cast*>(m_pItem) }; } + + const T& operator*() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return m_pItem->Value; } + const T* operator->() const { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); return &m_pItem->Value; } + + bool operator==(const const_reverse_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem == rhs.m_pItem; } + bool operator!=(const const_reverse_iterator& rhs) const { VMA_HEAVY_ASSERT(m_pList == rhs.m_pList); return m_pItem != rhs.m_pItem; } + + const_reverse_iterator operator++(int) { const_reverse_iterator result = *this; ++* this; return result; } + const_reverse_iterator operator--(int) { const_reverse_iterator result = *this; --* this; return result; } + + const_reverse_iterator& operator++() { VMA_HEAVY_ASSERT(m_pItem != VMA_NULL); m_pItem = m_pItem->pPrev; return *this; } + const_reverse_iterator& operator--(); + + private: + const VmaRawList* m_pList; + const VmaListItem* m_pItem; + + const_reverse_iterator(const VmaRawList* pList, const VmaListItem* pItem) : m_pList(pList), m_pItem(pItem) {} }; - VmaList(const AllocatorT& allocator) : m_RawList(allocator.m_pCallbacks) { } + VmaList(const AllocatorT& allocator) : m_RawList(allocator.m_pCallbacks) {} bool empty() const { return m_RawList.IsEmpty(); } size_t size() const { return m_RawList.GetCount(); } @@ -4194,20 +4914,89 @@ public: const_iterator begin() const { return cbegin(); } const_iterator end() const { return cend(); } - void clear() { m_RawList.Clear(); } + reverse_iterator rbegin() { return reverse_iterator(&m_RawList, m_RawList.Back()); } + reverse_iterator rend() { return reverse_iterator(&m_RawList, VMA_NULL); } + + const_reverse_iterator crbegin() const { return const_reverse_iterator(&m_RawList, m_RawList.Back()); } + const_reverse_iterator crend() const { return const_reverse_iterator(&m_RawList, VMA_NULL); } + + const_reverse_iterator rbegin() const { return crbegin(); } + const_reverse_iterator rend() const { return crend(); } + void push_back(const T& value) { m_RawList.PushBack(value); } - void erase(iterator it) { m_RawList.Remove(it.m_pItem); } iterator insert(iterator it, const T& value) { return iterator(&m_RawList, m_RawList.InsertBefore(it.m_pItem, value)); } + void clear() { m_RawList.Clear(); } + void erase(iterator it) { m_RawList.Remove(it.m_pItem); } + private: VmaRawList m_RawList; }; -#endif // #if VMA_USE_STL_LIST +#ifndef _VMA_LIST_FUNCTIONS +template +typename VmaList::iterator& VmaList::iterator::operator--() +{ + if (m_pItem != VMA_NULL) + { + m_pItem = m_pItem->pPrev; + } + else + { + VMA_HEAVY_ASSERT(!m_pList->IsEmpty()); + m_pItem = m_pList->Back(); + } + return *this; +} -//////////////////////////////////////////////////////////////////////////////// -// class VmaIntrusiveLinkedList +template +typename VmaList::reverse_iterator& VmaList::reverse_iterator::operator--() +{ + if (m_pItem != VMA_NULL) + { + m_pItem = m_pItem->pNext; + } + else + { + VMA_HEAVY_ASSERT(!m_pList->IsEmpty()); + m_pItem = m_pList->Front(); + } + return *this; +} +template +typename VmaList::const_iterator& VmaList::const_iterator::operator--() +{ + if (m_pItem != VMA_NULL) + { + m_pItem = m_pItem->pPrev; + } + else + { + VMA_HEAVY_ASSERT(!m_pList->IsEmpty()); + m_pItem = m_pList->Back(); + } + return *this; +} + +template +typename VmaList::const_reverse_iterator& VmaList::const_reverse_iterator::operator--() +{ + if (m_pItem != VMA_NULL) + { + m_pItem = m_pItem->pNext; + } + else + { + VMA_HEAVY_ASSERT(!m_pList->IsEmpty()); + m_pItem = m_pList->Back(); + } + return *this; +} +#endif // _VMA_LIST_FUNCTIONS +#endif // _VMA_LIST + +#ifndef _VMA_INTRUSIVE_LINKED_LIST /* Expected interface of ItemTypeTraits: struct MyItemTypeTraits @@ -4226,251 +5015,249 @@ public: typedef typename ItemTypeTraits::ItemType ItemType; static ItemType* GetPrev(const ItemType* item) { return ItemTypeTraits::GetPrev(item); } static ItemType* GetNext(const ItemType* item) { return ItemTypeTraits::GetNext(item); } + // Movable, not copyable. - VmaIntrusiveLinkedList() { } - VmaIntrusiveLinkedList(const VmaIntrusiveLinkedList& src) = delete; - VmaIntrusiveLinkedList(VmaIntrusiveLinkedList&& src) : - m_Front(src.m_Front), m_Back(src.m_Back), m_Count(src.m_Count) - { - src.m_Front = src.m_Back = VMA_NULL; - src.m_Count = 0; - } - ~VmaIntrusiveLinkedList() - { - VMA_HEAVY_ASSERT(IsEmpty()); - } - VmaIntrusiveLinkedList& operator=(const VmaIntrusiveLinkedList& src) = delete; - VmaIntrusiveLinkedList& operator=(VmaIntrusiveLinkedList&& src) - { - if(&src != this) - { - VMA_HEAVY_ASSERT(IsEmpty()); - m_Front = src.m_Front; - m_Back = src.m_Back; - m_Count = src.m_Count; - src.m_Front = src.m_Back = VMA_NULL; - src.m_Count = 0; - } - return *this; - } - void RemoveAll() - { - if(!IsEmpty()) - { - ItemType* item = m_Back; - while(item != VMA_NULL) - { - ItemType* const prevItem = ItemTypeTraits::AccessPrev(item); - ItemTypeTraits::AccessPrev(item) = VMA_NULL; - ItemTypeTraits::AccessNext(item) = VMA_NULL; - item = prevItem; - } - m_Front = VMA_NULL; - m_Back = VMA_NULL; - m_Count = 0; - } - } + VmaIntrusiveLinkedList() = default; + VmaIntrusiveLinkedList(VmaIntrusiveLinkedList && src); + VmaIntrusiveLinkedList(const VmaIntrusiveLinkedList&) = delete; + VmaIntrusiveLinkedList& operator=(VmaIntrusiveLinkedList&& src); + VmaIntrusiveLinkedList& operator=(const VmaIntrusiveLinkedList&) = delete; + ~VmaIntrusiveLinkedList() { VMA_HEAVY_ASSERT(IsEmpty()); } + size_t GetCount() const { return m_Count; } bool IsEmpty() const { return m_Count == 0; } ItemType* Front() { return m_Front; } - const ItemType* Front() const { return m_Front; } ItemType* Back() { return m_Back; } + const ItemType* Front() const { return m_Front; } const ItemType* Back() const { return m_Back; } - void PushBack(ItemType* item) - { - VMA_HEAVY_ASSERT(ItemTypeTraits::GetPrev(item) == VMA_NULL && ItemTypeTraits::GetNext(item) == VMA_NULL); - if(IsEmpty()) - { - m_Front = item; - m_Back = item; - m_Count = 1; - } - else - { - ItemTypeTraits::AccessPrev(item) = m_Back; - ItemTypeTraits::AccessNext(m_Back) = item; - m_Back = item; - ++m_Count; - } - } - void PushFront(ItemType* item) - { - VMA_HEAVY_ASSERT(ItemTypeTraits::GetPrev(item) == VMA_NULL && ItemTypeTraits::GetNext(item) == VMA_NULL); - if(IsEmpty()) - { - m_Front = item; - m_Back = item; - m_Count = 1; - } - else - { - ItemTypeTraits::AccessNext(item) = m_Front; - ItemTypeTraits::AccessPrev(m_Front) = item; - m_Front = item; - ++m_Count; - } - } - ItemType* PopBack() - { - VMA_HEAVY_ASSERT(m_Count > 0); - ItemType* const backItem = m_Back; - ItemType* const prevItem = ItemTypeTraits::GetPrev(backItem); - if(prevItem != VMA_NULL) - { - ItemTypeTraits::AccessNext(prevItem) = VMA_NULL; - } - m_Back = prevItem; - --m_Count; - ItemTypeTraits::AccessPrev(backItem) = VMA_NULL; - ItemTypeTraits::AccessNext(backItem) = VMA_NULL; - return backItem; - } - ItemType* PopFront() - { - VMA_HEAVY_ASSERT(m_Count > 0); - ItemType* const frontItem = m_Front; - ItemType* const nextItem = ItemTypeTraits::GetNext(frontItem); - if(nextItem != VMA_NULL) - { - ItemTypeTraits::AccessPrev(nextItem) = VMA_NULL; - } - m_Front = nextItem; - --m_Count; - ItemTypeTraits::AccessPrev(frontItem) = VMA_NULL; - ItemTypeTraits::AccessNext(frontItem) = VMA_NULL; - return frontItem; - } + + void PushBack(ItemType* item); + void PushFront(ItemType* item); + ItemType* PopBack(); + ItemType* PopFront(); // MyItem can be null - it means PushBack. - void InsertBefore(ItemType* existingItem, ItemType* newItem) - { - VMA_HEAVY_ASSERT(newItem != VMA_NULL && ItemTypeTraits::GetPrev(newItem) == VMA_NULL && ItemTypeTraits::GetNext(newItem) == VMA_NULL); - if(existingItem != VMA_NULL) - { - ItemType* const prevItem = ItemTypeTraits::GetPrev(existingItem); - ItemTypeTraits::AccessPrev(newItem) = prevItem; - ItemTypeTraits::AccessNext(newItem) = existingItem; - ItemTypeTraits::AccessPrev(existingItem) = newItem; - if(prevItem != VMA_NULL) - { - ItemTypeTraits::AccessNext(prevItem) = newItem; - } - else - { - VMA_HEAVY_ASSERT(m_Front == existingItem); - m_Front = newItem; - } - ++m_Count; - } - else - PushBack(newItem); - } + void InsertBefore(ItemType* existingItem, ItemType* newItem); // MyItem can be null - it means PushFront. - void InsertAfter(ItemType* existingItem, ItemType* newItem) - { - VMA_HEAVY_ASSERT(newItem != VMA_NULL && ItemTypeTraits::GetPrev(newItem) == VMA_NULL && ItemTypeTraits::GetNext(newItem) == VMA_NULL); - if(existingItem != VMA_NULL) - { - ItemType* const nextItem = ItemTypeTraits::GetNext(existingItem); - ItemTypeTraits::AccessNext(newItem) = nextItem; - ItemTypeTraits::AccessPrev(newItem) = existingItem; - ItemTypeTraits::AccessNext(existingItem) = newItem; - if(nextItem != VMA_NULL) - { - ItemTypeTraits::AccessPrev(nextItem) = newItem; - } - else - { - VMA_HEAVY_ASSERT(m_Back == existingItem); - m_Back = newItem; - } - ++m_Count; - } - else - return PushFront(newItem); - } - void Remove(ItemType* item) - { - VMA_HEAVY_ASSERT(item != VMA_NULL && m_Count > 0); - if(ItemTypeTraits::GetPrev(item) != VMA_NULL) - { - ItemTypeTraits::AccessNext(ItemTypeTraits::AccessPrev(item)) = ItemTypeTraits::GetNext(item); - } - else - { - VMA_HEAVY_ASSERT(m_Front == item); - m_Front = ItemTypeTraits::GetNext(item); - } + void InsertAfter(ItemType* existingItem, ItemType* newItem); + void Remove(ItemType* item); + void RemoveAll(); - if(ItemTypeTraits::GetNext(item) != VMA_NULL) - { - ItemTypeTraits::AccessPrev(ItemTypeTraits::AccessNext(item)) = ItemTypeTraits::GetPrev(item); - } - else - { - VMA_HEAVY_ASSERT(m_Back == item); - m_Back = ItemTypeTraits::GetPrev(item); - } - ItemTypeTraits::AccessPrev(item) = VMA_NULL; - ItemTypeTraits::AccessNext(item) = VMA_NULL; - --m_Count; - } private: ItemType* m_Front = VMA_NULL; ItemType* m_Back = VMA_NULL; size_t m_Count = 0; }; -//////////////////////////////////////////////////////////////////////////////// -// class VmaMap +#ifndef _VMA_INTRUSIVE_LINKED_LIST_FUNCTIONS +template +VmaIntrusiveLinkedList::VmaIntrusiveLinkedList(VmaIntrusiveLinkedList&& src) + : m_Front(src.m_Front), m_Back(src.m_Back), m_Count(src.m_Count) +{ + src.m_Front = src.m_Back = VMA_NULL; + src.m_Count = 0; +} + +template +VmaIntrusiveLinkedList& VmaIntrusiveLinkedList::operator=(VmaIntrusiveLinkedList&& src) +{ + if (&src != this) + { + VMA_HEAVY_ASSERT(IsEmpty()); + m_Front = src.m_Front; + m_Back = src.m_Back; + m_Count = src.m_Count; + src.m_Front = src.m_Back = VMA_NULL; + src.m_Count = 0; + } + return *this; +} + +template +void VmaIntrusiveLinkedList::PushBack(ItemType* item) +{ + VMA_HEAVY_ASSERT(ItemTypeTraits::GetPrev(item) == VMA_NULL && ItemTypeTraits::GetNext(item) == VMA_NULL); + if (IsEmpty()) + { + m_Front = item; + m_Back = item; + m_Count = 1; + } + else + { + ItemTypeTraits::AccessPrev(item) = m_Back; + ItemTypeTraits::AccessNext(m_Back) = item; + m_Back = item; + ++m_Count; + } +} + +template +void VmaIntrusiveLinkedList::PushFront(ItemType* item) +{ + VMA_HEAVY_ASSERT(ItemTypeTraits::GetPrev(item) == VMA_NULL && ItemTypeTraits::GetNext(item) == VMA_NULL); + if (IsEmpty()) + { + m_Front = item; + m_Back = item; + m_Count = 1; + } + else + { + ItemTypeTraits::AccessNext(item) = m_Front; + ItemTypeTraits::AccessPrev(m_Front) = item; + m_Front = item; + ++m_Count; + } +} + +template +typename VmaIntrusiveLinkedList::ItemType* VmaIntrusiveLinkedList::PopBack() +{ + VMA_HEAVY_ASSERT(m_Count > 0); + ItemType* const backItem = m_Back; + ItemType* const prevItem = ItemTypeTraits::GetPrev(backItem); + if (prevItem != VMA_NULL) + { + ItemTypeTraits::AccessNext(prevItem) = VMA_NULL; + } + m_Back = prevItem; + --m_Count; + ItemTypeTraits::AccessPrev(backItem) = VMA_NULL; + ItemTypeTraits::AccessNext(backItem) = VMA_NULL; + return backItem; +} + +template +typename VmaIntrusiveLinkedList::ItemType* VmaIntrusiveLinkedList::PopFront() +{ + VMA_HEAVY_ASSERT(m_Count > 0); + ItemType* const frontItem = m_Front; + ItemType* const nextItem = ItemTypeTraits::GetNext(frontItem); + if (nextItem != VMA_NULL) + { + ItemTypeTraits::AccessPrev(nextItem) = VMA_NULL; + } + m_Front = nextItem; + --m_Count; + ItemTypeTraits::AccessPrev(frontItem) = VMA_NULL; + ItemTypeTraits::AccessNext(frontItem) = VMA_NULL; + return frontItem; +} + +template +void VmaIntrusiveLinkedList::InsertBefore(ItemType* existingItem, ItemType* newItem) +{ + VMA_HEAVY_ASSERT(newItem != VMA_NULL && ItemTypeTraits::GetPrev(newItem) == VMA_NULL && ItemTypeTraits::GetNext(newItem) == VMA_NULL); + if (existingItem != VMA_NULL) + { + ItemType* const prevItem = ItemTypeTraits::GetPrev(existingItem); + ItemTypeTraits::AccessPrev(newItem) = prevItem; + ItemTypeTraits::AccessNext(newItem) = existingItem; + ItemTypeTraits::AccessPrev(existingItem) = newItem; + if (prevItem != VMA_NULL) + { + ItemTypeTraits::AccessNext(prevItem) = newItem; + } + else + { + VMA_HEAVY_ASSERT(m_Front == existingItem); + m_Front = newItem; + } + ++m_Count; + } + else + PushBack(newItem); +} + +template +void VmaIntrusiveLinkedList::InsertAfter(ItemType* existingItem, ItemType* newItem) +{ + VMA_HEAVY_ASSERT(newItem != VMA_NULL && ItemTypeTraits::GetPrev(newItem) == VMA_NULL && ItemTypeTraits::GetNext(newItem) == VMA_NULL); + if (existingItem != VMA_NULL) + { + ItemType* const nextItem = ItemTypeTraits::GetNext(existingItem); + ItemTypeTraits::AccessNext(newItem) = nextItem; + ItemTypeTraits::AccessPrev(newItem) = existingItem; + ItemTypeTraits::AccessNext(existingItem) = newItem; + if (nextItem != VMA_NULL) + { + ItemTypeTraits::AccessPrev(nextItem) = newItem; + } + else + { + VMA_HEAVY_ASSERT(m_Back == existingItem); + m_Back = newItem; + } + ++m_Count; + } + else + return PushFront(newItem); +} + +template +void VmaIntrusiveLinkedList::Remove(ItemType* item) +{ + VMA_HEAVY_ASSERT(item != VMA_NULL && m_Count > 0); + if (ItemTypeTraits::GetPrev(item) != VMA_NULL) + { + ItemTypeTraits::AccessNext(ItemTypeTraits::AccessPrev(item)) = ItemTypeTraits::GetNext(item); + } + else + { + VMA_HEAVY_ASSERT(m_Front == item); + m_Front = ItemTypeTraits::GetNext(item); + } + + if (ItemTypeTraits::GetNext(item) != VMA_NULL) + { + ItemTypeTraits::AccessPrev(ItemTypeTraits::AccessNext(item)) = ItemTypeTraits::GetPrev(item); + } + else + { + VMA_HEAVY_ASSERT(m_Back == item); + m_Back = ItemTypeTraits::GetPrev(item); + } + ItemTypeTraits::AccessPrev(item) = VMA_NULL; + ItemTypeTraits::AccessNext(item) = VMA_NULL; + --m_Count; +} + +template +void VmaIntrusiveLinkedList::RemoveAll() +{ + if (!IsEmpty()) + { + ItemType* item = m_Back; + while (item != VMA_NULL) + { + ItemType* const prevItem = ItemTypeTraits::AccessPrev(item); + ItemTypeTraits::AccessPrev(item) = VMA_NULL; + ItemTypeTraits::AccessNext(item) = VMA_NULL; + item = prevItem; + } + m_Front = VMA_NULL; + m_Back = VMA_NULL; + m_Count = 0; + } +} +#endif // _VMA_INTRUSIVE_LINKED_LIST_FUNCTIONS +#endif // _VMA_INTRUSIVE_LINKED_LIST // Unused in this version. #if 0 -#if VMA_USE_STL_UNORDERED_MAP - -#define VmaPair std::pair - -#define VMA_MAP_TYPE(KeyT, ValueT) \ - std::unordered_map< KeyT, ValueT, std::hash, std::equal_to, VmaStlAllocator< std::pair > > - -#else // #if VMA_USE_STL_UNORDERED_MAP - +#ifndef _VMA_PAIR template struct VmaPair { T1 first; T2 second; - VmaPair() : first(), second() { } - VmaPair(const T1& firstSrc, const T2& secondSrc) : first(firstSrc), second(secondSrc) { } + VmaPair() : first(), second() {} + VmaPair(const T1& firstSrc, const T2& secondSrc) : first(firstSrc), second(secondSrc) {} }; -/* Class compatible with subset of interface of std::unordered_map. -KeyT, ValueT must be POD because they will be stored in VmaVector. -*/ -template -class VmaMap -{ -public: - typedef VmaPair PairType; - typedef PairType* iterator; - - VmaMap(const VmaStlAllocator& allocator) : m_Vector(allocator) { } - - iterator begin() { return m_Vector.begin(); } - iterator end() { return m_Vector.end(); } - - void insert(const PairType& pair); - iterator find(const KeyT& key); - void erase(iterator it); - -private: - VmaVector< PairType, VmaStlAllocator > m_Vector; -}; - -#define VMA_MAP_TYPE(KeyT, ValueT) VmaMap - template struct VmaPairFirstLess { @@ -4483,7 +5270,34 @@ struct VmaPairFirstLess return lhs.first < rhsFirst; } }; +#endif // _VMA_PAIR +#ifndef _VMA_MAP +/* Class compatible with subset of interface of std::unordered_map. +KeyT, ValueT must be POD because they will be stored in VmaVector. +*/ +template +class VmaMap +{ +public: + typedef VmaPair PairType; + typedef PairType* iterator; + + VmaMap(const VmaStlAllocator& allocator) : m_Vector(allocator) {} + + iterator begin() { return m_Vector.begin(); } + iterator end() { return m_Vector.end(); } + size_t size() { return m_Vector.size(); } + + void insert(const PairType& pair); + iterator find(const KeyT& key); + void erase(iterator it); + +private: + VmaVector< PairType, VmaStlAllocator> m_Vector; +}; + +#ifndef _VMA_MAP_FUNCTIONS template void VmaMap::insert(const PairType& pair) { @@ -4503,7 +5317,7 @@ VmaPair* VmaMap::find(const KeyT& key) m_Vector.data() + m_Vector.size(), key, VmaPairFirstLess()); - if((it != m_Vector.end()) && (it->first == key)) + if ((it != m_Vector.end()) && (it->first == key)) { return it; } @@ -4518,25 +5332,639 @@ void VmaMap::erase(iterator it) { VmaVectorRemove(m_Vector, it - m_Vector.begin()); } - -#endif // #if VMA_USE_STL_UNORDERED_MAP +#endif // _VMA_MAP_FUNCTIONS +#endif // _VMA_MAP #endif // #if 0 -//////////////////////////////////////////////////////////////////////////////// +#if !defined(_VMA_STRING_BUILDER) && VMA_STATS_STRING_ENABLED +class VmaStringBuilder +{ +public: + VmaStringBuilder(const VkAllocationCallbacks* allocationCallbacks) : m_Data(VmaStlAllocator(allocationCallbacks)) {} + ~VmaStringBuilder() = default; -class VmaDeviceMemoryBlock; + size_t GetLength() const { return m_Data.size(); } + const char* GetData() const { return m_Data.data(); } + void AddNewLine() { Add('\n'); } + void Add(char ch) { m_Data.push_back(ch); } -enum VMA_CACHE_OPERATION { VMA_CACHE_FLUSH, VMA_CACHE_INVALIDATE }; + void Add(const char* pStr); + void AddNumber(uint32_t num); + void AddNumber(uint64_t num); + void AddPointer(const void* ptr); +private: + VmaVector> m_Data; +}; + +#ifndef _VMA_STRING_BUILDER_FUNCTIONS +void VmaStringBuilder::Add(const char* pStr) +{ + const size_t strLen = strlen(pStr); + if (strLen > 0) + { + const size_t oldCount = m_Data.size(); + m_Data.resize(oldCount + strLen); + memcpy(m_Data.data() + oldCount, pStr, strLen); + } +} + +void VmaStringBuilder::AddNumber(uint32_t num) +{ + char buf[11]; + buf[10] = '\0'; + char* p = &buf[10]; + do + { + *--p = '0' + (num % 10); + num /= 10; + } while (num); + Add(p); +} + +void VmaStringBuilder::AddNumber(uint64_t num) +{ + char buf[21]; + buf[20] = '\0'; + char* p = &buf[20]; + do + { + *--p = '0' + (num % 10); + num /= 10; + } while (num); + Add(p); +} + +void VmaStringBuilder::AddPointer(const void* ptr) +{ + char buf[21]; + VmaPtrToStr(buf, sizeof(buf), ptr); + Add(buf); +} +#endif //_VMA_STRING_BUILDER_FUNCTIONS +#endif // _VMA_STRING_BUILDER + +#if !defined(_VMA_JSON_WRITER) && VMA_STATS_STRING_ENABLED +/* +Allows to conveniently build a correct JSON document to be written to the +VmaStringBuilder passed to the constructor. +*/ +class VmaJsonWriter +{ + VMA_CLASS_NO_COPY(VmaJsonWriter) +public: + // sb - string builder to write the document to. Must remain alive for the whole lifetime of this object. + VmaJsonWriter(const VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder& sb); + ~VmaJsonWriter(); + + // Begins object by writing "{". + // Inside an object, you must call pairs of WriteString and a value, e.g.: + // j.BeginObject(true); j.WriteString("A"); j.WriteNumber(1); j.WriteString("B"); j.WriteNumber(2); j.EndObject(); + // Will write: { "A": 1, "B": 2 } + void BeginObject(bool singleLine = false); + // Ends object by writing "}". + void EndObject(); + + // Begins array by writing "[". + // Inside an array, you can write a sequence of any values. + void BeginArray(bool singleLine = false); + // Ends array by writing "[". + void EndArray(); + + // Writes a string value inside "". + // pStr can contain any ANSI characters, including '"', new line etc. - they will be properly escaped. + void WriteString(const char* pStr); + + // Begins writing a string value. + // Call BeginString, ContinueString, ContinueString, ..., EndString instead of + // WriteString to conveniently build the string content incrementally, made of + // parts including numbers. + void BeginString(const char* pStr = VMA_NULL); + // Posts next part of an open string. + void ContinueString(const char* pStr); + // Posts next part of an open string. The number is converted to decimal characters. + void ContinueString(uint32_t n); + void ContinueString(uint64_t n); + void ContinueString_Size(size_t n); + // Posts next part of an open string. Pointer value is converted to characters + // using "%p" formatting - shown as hexadecimal number, e.g.: 000000081276Ad00 + void ContinueString_Pointer(const void* ptr); + // Ends writing a string value by writing '"'. + void EndString(const char* pStr = VMA_NULL); + + // Writes a number value. + void WriteNumber(uint32_t n); + void WriteNumber(uint64_t n); + void WriteSize(size_t n); + // Writes a boolean value - false or true. + void WriteBool(bool b); + // Writes a null value. + void WriteNull(); + +private: + enum COLLECTION_TYPE + { + COLLECTION_TYPE_OBJECT, + COLLECTION_TYPE_ARRAY, + }; + struct StackItem + { + COLLECTION_TYPE type; + uint32_t valueCount; + bool singleLineMode; + }; + + static const char* const INDENT; + + VmaStringBuilder& m_SB; + VmaVector< StackItem, VmaStlAllocator > m_Stack; + bool m_InsideString; + + // Write size_t for less than 64bits + void WriteSize(size_t n, std::integral_constant) { m_SB.AddNumber(static_cast(n)); } + // Write size_t for 64bits + void WriteSize(size_t n, std::integral_constant) { m_SB.AddNumber(static_cast(n)); } + + void BeginValue(bool isString); + void WriteIndent(bool oneLess = false); +}; +const char* const VmaJsonWriter::INDENT = " "; + +#ifndef _VMA_JSON_WRITER_FUNCTIONS +VmaJsonWriter::VmaJsonWriter(const VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder& sb) + : m_SB(sb), + m_Stack(VmaStlAllocator(pAllocationCallbacks)), + m_InsideString(false) {} + +VmaJsonWriter::~VmaJsonWriter() +{ + VMA_ASSERT(!m_InsideString); + VMA_ASSERT(m_Stack.empty()); +} + +void VmaJsonWriter::BeginObject(bool singleLine) +{ + VMA_ASSERT(!m_InsideString); + + BeginValue(false); + m_SB.Add('{'); + + StackItem item; + item.type = COLLECTION_TYPE_OBJECT; + item.valueCount = 0; + item.singleLineMode = singleLine; + m_Stack.push_back(item); +} + +void VmaJsonWriter::EndObject() +{ + VMA_ASSERT(!m_InsideString); + + WriteIndent(true); + m_SB.Add('}'); + + VMA_ASSERT(!m_Stack.empty() && m_Stack.back().type == COLLECTION_TYPE_OBJECT); + m_Stack.pop_back(); +} + +void VmaJsonWriter::BeginArray(bool singleLine) +{ + VMA_ASSERT(!m_InsideString); + + BeginValue(false); + m_SB.Add('['); + + StackItem item; + item.type = COLLECTION_TYPE_ARRAY; + item.valueCount = 0; + item.singleLineMode = singleLine; + m_Stack.push_back(item); +} + +void VmaJsonWriter::EndArray() +{ + VMA_ASSERT(!m_InsideString); + + WriteIndent(true); + m_SB.Add(']'); + + VMA_ASSERT(!m_Stack.empty() && m_Stack.back().type == COLLECTION_TYPE_ARRAY); + m_Stack.pop_back(); +} + +void VmaJsonWriter::WriteString(const char* pStr) +{ + BeginString(pStr); + EndString(); +} + +void VmaJsonWriter::BeginString(const char* pStr) +{ + VMA_ASSERT(!m_InsideString); + + BeginValue(true); + m_SB.Add('"'); + m_InsideString = true; + if (pStr != VMA_NULL && pStr[0] != '\0') + { + ContinueString(pStr); + } +} + +void VmaJsonWriter::ContinueString(const char* pStr) +{ + VMA_ASSERT(m_InsideString); + + const size_t strLen = strlen(pStr); + for (size_t i = 0; i < strLen; ++i) + { + char ch = pStr[i]; + if (ch == '\\') + { + m_SB.Add("\\\\"); + } + else if (ch == '"') + { + m_SB.Add("\\\""); + } + else if (ch >= 32) + { + m_SB.Add(ch); + } + else switch (ch) + { + case '\b': + m_SB.Add("\\b"); + break; + case '\f': + m_SB.Add("\\f"); + break; + case '\n': + m_SB.Add("\\n"); + break; + case '\r': + m_SB.Add("\\r"); + break; + case '\t': + m_SB.Add("\\t"); + break; + default: + VMA_ASSERT(0 && "Character not currently supported."); + break; + } + } +} + +void VmaJsonWriter::ContinueString(uint32_t n) +{ + VMA_ASSERT(m_InsideString); + m_SB.AddNumber(n); +} + +void VmaJsonWriter::ContinueString(uint64_t n) +{ + VMA_ASSERT(m_InsideString); + m_SB.AddNumber(n); +} + +void VmaJsonWriter::ContinueString_Size(size_t n) +{ + VMA_ASSERT(m_InsideString); + // Fix for AppleClang incorrect type casting + // TODO: Change to if constexpr when C++17 used as minimal standard + WriteSize(n, std::is_same{}); +} + +void VmaJsonWriter::ContinueString_Pointer(const void* ptr) +{ + VMA_ASSERT(m_InsideString); + m_SB.AddPointer(ptr); +} + +void VmaJsonWriter::EndString(const char* pStr) +{ + VMA_ASSERT(m_InsideString); + if (pStr != VMA_NULL && pStr[0] != '\0') + { + ContinueString(pStr); + } + m_SB.Add('"'); + m_InsideString = false; +} + +void VmaJsonWriter::WriteNumber(uint32_t n) +{ + VMA_ASSERT(!m_InsideString); + BeginValue(false); + m_SB.AddNumber(n); +} + +void VmaJsonWriter::WriteNumber(uint64_t n) +{ + VMA_ASSERT(!m_InsideString); + BeginValue(false); + m_SB.AddNumber(n); +} + +void VmaJsonWriter::WriteSize(size_t n) +{ + VMA_ASSERT(!m_InsideString); + BeginValue(false); + // Fix for AppleClang incorrect type casting + // TODO: Change to if constexpr when C++17 used as minimal standard + WriteSize(n, std::is_same{}); +} + +void VmaJsonWriter::WriteBool(bool b) +{ + VMA_ASSERT(!m_InsideString); + BeginValue(false); + m_SB.Add(b ? "true" : "false"); +} + +void VmaJsonWriter::WriteNull() +{ + VMA_ASSERT(!m_InsideString); + BeginValue(false); + m_SB.Add("null"); +} + +void VmaJsonWriter::BeginValue(bool isString) +{ + if (!m_Stack.empty()) + { + StackItem& currItem = m_Stack.back(); + if (currItem.type == COLLECTION_TYPE_OBJECT && + currItem.valueCount % 2 == 0) + { + VMA_ASSERT(isString); + } + + if (currItem.type == COLLECTION_TYPE_OBJECT && + currItem.valueCount % 2 != 0) + { + m_SB.Add(": "); + } + else if (currItem.valueCount > 0) + { + m_SB.Add(", "); + WriteIndent(); + } + else + { + WriteIndent(); + } + ++currItem.valueCount; + } +} + +void VmaJsonWriter::WriteIndent(bool oneLess) +{ + if (!m_Stack.empty() && !m_Stack.back().singleLineMode) + { + m_SB.AddNewLine(); + + size_t count = m_Stack.size(); + if (count > 0 && oneLess) + { + --count; + } + for (size_t i = 0; i < count; ++i) + { + m_SB.Add(INDENT); + } + } +} +#endif // _VMA_JSON_WRITER_FUNCTIONS + +static void VmaPrintDetailedStatistics(VmaJsonWriter& json, const VmaDetailedStatistics& stat) +{ + json.BeginObject(); + + json.WriteString("BlockCount"); + json.WriteNumber(stat.statistics.blockCount); + json.WriteString("BlockBytes"); + json.WriteNumber(stat.statistics.blockBytes); + json.WriteString("AllocationCount"); + json.WriteNumber(stat.statistics.allocationCount); + json.WriteString("AllocationBytes"); + json.WriteNumber(stat.statistics.allocationBytes); + json.WriteString("UnusedRangeCount"); + json.WriteNumber(stat.unusedRangeCount); + + if (stat.statistics.allocationCount > 1) + { + json.WriteString("AllocationSizeMin"); + json.WriteNumber(stat.allocationSizeMin); + json.WriteString("AllocationSizeMax"); + json.WriteNumber(stat.allocationSizeMax); + } + if (stat.unusedRangeCount > 1) + { + json.WriteString("UnusedRangeSizeMin"); + json.WriteNumber(stat.unusedRangeSizeMin); + json.WriteString("UnusedRangeSizeMax"); + json.WriteNumber(stat.unusedRangeSizeMax); + } + json.EndObject(); +} +#endif // _VMA_JSON_WRITER + +#ifndef _VMA_MAPPING_HYSTERESIS + +class VmaMappingHysteresis +{ + VMA_CLASS_NO_COPY(VmaMappingHysteresis) +public: + VmaMappingHysteresis() = default; + + uint32_t GetExtraMapping() const { return m_ExtraMapping; } + + // Call when Map was called. + // Returns true if switched to extra +1 mapping reference count. + bool PostMap() + { +#if VMA_MAPPING_HYSTERESIS_ENABLED + if(m_ExtraMapping == 0) + { + ++m_MajorCounter; + if(m_MajorCounter >= COUNTER_MIN_EXTRA_MAPPING) + { + m_ExtraMapping = 1; + m_MajorCounter = 0; + m_MinorCounter = 0; + return true; + } + } + else // m_ExtraMapping == 1 + PostMinorCounter(); +#endif // #if VMA_MAPPING_HYSTERESIS_ENABLED + return false; + } + + // Call when Unmap was called. + void PostUnmap() + { +#if VMA_MAPPING_HYSTERESIS_ENABLED + if(m_ExtraMapping == 0) + ++m_MajorCounter; + else // m_ExtraMapping == 1 + PostMinorCounter(); +#endif // #if VMA_MAPPING_HYSTERESIS_ENABLED + } + + // Call when allocation was made from the memory block. + void PostAlloc() + { +#if VMA_MAPPING_HYSTERESIS_ENABLED + if(m_ExtraMapping == 1) + ++m_MajorCounter; + else // m_ExtraMapping == 0 + PostMinorCounter(); +#endif // #if VMA_MAPPING_HYSTERESIS_ENABLED + } + + // Call when allocation was freed from the memory block. + // Returns true if switched to extra -1 mapping reference count. + bool PostFree() + { +#if VMA_MAPPING_HYSTERESIS_ENABLED + if(m_ExtraMapping == 1) + { + ++m_MajorCounter; + if(m_MajorCounter >= COUNTER_MIN_EXTRA_MAPPING && + m_MajorCounter > m_MinorCounter + 1) + { + m_ExtraMapping = 0; + m_MajorCounter = 0; + m_MinorCounter = 0; + return true; + } + } + else // m_ExtraMapping == 0 + PostMinorCounter(); +#endif // #if VMA_MAPPING_HYSTERESIS_ENABLED + return false; + } + +private: + static const int32_t COUNTER_MIN_EXTRA_MAPPING = 7; + + uint32_t m_MinorCounter = 0; + uint32_t m_MajorCounter = 0; + uint32_t m_ExtraMapping = 0; // 0 or 1. + + void PostMinorCounter() + { + if(m_MinorCounter < m_MajorCounter) + { + ++m_MinorCounter; + } + else if(m_MajorCounter > 0) + { + --m_MajorCounter; + --m_MinorCounter; + } + } +}; + +#endif // _VMA_MAPPING_HYSTERESIS + +#ifndef _VMA_DEVICE_MEMORY_BLOCK +/* +Represents a single block of device memory (`VkDeviceMemory`) with all the +data about its regions (aka suballocations, #VmaAllocation), assigned and free. + +Thread-safety: +- Access to m_pMetadata must be externally synchronized. +- Map, Unmap, Bind* are synchronized internally. +*/ +class VmaDeviceMemoryBlock +{ + VMA_CLASS_NO_COPY(VmaDeviceMemoryBlock) +public: + VmaBlockMetadata* m_pMetadata; + + VmaDeviceMemoryBlock(VmaAllocator hAllocator); + ~VmaDeviceMemoryBlock(); + + // Always call after construction. + void Init( + VmaAllocator hAllocator, + VmaPool hParentPool, + uint32_t newMemoryTypeIndex, + VkDeviceMemory newMemory, + VkDeviceSize newSize, + uint32_t id, + uint32_t algorithm, + VkDeviceSize bufferImageGranularity); + // Always call before destruction. + void Destroy(VmaAllocator allocator); + + VmaPool GetParentPool() const { return m_hParentPool; } + VkDeviceMemory GetDeviceMemory() const { return m_hMemory; } + uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; } + uint32_t GetId() const { return m_Id; } + void* GetMappedData() const { return m_pMappedData; } + uint32_t GetMapRefCount() const { return m_MapCount; } + + // Call when allocation/free was made from m_pMetadata. + // Used for m_MappingHysteresis. + void PostAlloc() { m_MappingHysteresis.PostAlloc(); } + void PostFree(VmaAllocator hAllocator); + + // Validates all data structures inside this object. If not valid, returns false. + bool Validate() const; + VkResult CheckCorruption(VmaAllocator hAllocator); + + // ppData can be null. + VkResult Map(VmaAllocator hAllocator, uint32_t count, void** ppData); + void Unmap(VmaAllocator hAllocator, uint32_t count); + + VkResult WriteMagicValueAfterAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize); + VkResult ValidateMagicValueAfterAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize); + + VkResult BindBufferMemory( + const VmaAllocator hAllocator, + const VmaAllocation hAllocation, + VkDeviceSize allocationLocalOffset, + VkBuffer hBuffer, + const void* pNext); + VkResult BindImageMemory( + const VmaAllocator hAllocator, + const VmaAllocation hAllocation, + VkDeviceSize allocationLocalOffset, + VkImage hImage, + const void* pNext); + +private: + VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool. + uint32_t m_MemoryTypeIndex; + uint32_t m_Id; + VkDeviceMemory m_hMemory; + + /* + Protects access to m_hMemory so it is not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory. + Also protects m_MapCount, m_pMappedData. + Allocations, deallocations, any change in m_pMetadata is protected by parent's VmaBlockVector::m_Mutex. + */ + VMA_MUTEX m_MapAndBindMutex; + VmaMappingHysteresis m_MappingHysteresis; + uint32_t m_MapCount; + void* m_pMappedData; +}; +#endif // _VMA_DEVICE_MEMORY_BLOCK + +#ifndef _VMA_ALLOCATION_T struct VmaAllocation_T { -private: - static const uint8_t MAP_COUNT_FLAG_PERSISTENT_MAP = 0x80; + friend struct VmaDedicatedAllocationListItemTraits; enum FLAGS { - FLAG_USER_DATA_STRING = 0x01, + FLAG_PERSISTENT_MAP = 0x01, + FLAG_MAPPING_ALLOWED = 0x02, }; public: @@ -4547,148 +5975,48 @@ public: ALLOCATION_TYPE_DEDICATED, }; - /* - This struct is allocated using VmaPoolAllocator. - */ - - VmaAllocation_T(uint32_t currentFrameIndex, bool userDataString) : - m_Alignment{1}, - m_Size{0}, - m_pUserData{VMA_NULL}, - m_LastUseFrameIndex{currentFrameIndex}, - m_MemoryTypeIndex{0}, - m_Type{(uint8_t)ALLOCATION_TYPE_NONE}, - m_SuballocationType{(uint8_t)VMA_SUBALLOCATION_TYPE_UNKNOWN}, - m_MapCount{0}, - m_Flags{userDataString ? (uint8_t)FLAG_USER_DATA_STRING : (uint8_t)0} - { -#if VMA_STATS_STRING_ENABLED - m_CreationFrameIndex = currentFrameIndex; - m_BufferImageUsage = 0; -#endif - } - - ~VmaAllocation_T() - { - VMA_ASSERT((m_MapCount & ~MAP_COUNT_FLAG_PERSISTENT_MAP) == 0 && "Allocation was not unmapped before destruction."); - - // Check if owned string was freed. - VMA_ASSERT(m_pUserData == VMA_NULL); - } + // This struct is allocated using VmaPoolAllocator. + VmaAllocation_T(bool mappingAllowed); + ~VmaAllocation_T(); void InitBlockAllocation( VmaDeviceMemoryBlock* block, - VkDeviceSize offset, + VmaAllocHandle allocHandle, VkDeviceSize alignment, VkDeviceSize size, uint32_t memoryTypeIndex, VmaSuballocationType suballocationType, - bool mapped, - bool canBecomeLost) - { - VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE); - VMA_ASSERT(block != VMA_NULL); - m_Type = (uint8_t)ALLOCATION_TYPE_BLOCK; - m_Alignment = alignment; - m_Size = size; - m_MemoryTypeIndex = memoryTypeIndex; - m_MapCount = mapped ? MAP_COUNT_FLAG_PERSISTENT_MAP : 0; - m_SuballocationType = (uint8_t)suballocationType; - m_BlockAllocation.m_Block = block; - m_BlockAllocation.m_Offset = offset; - m_BlockAllocation.m_CanBecomeLost = canBecomeLost; - } - - void InitLost() - { - VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE); - VMA_ASSERT(m_LastUseFrameIndex.load() == VMA_FRAME_INDEX_LOST); - m_Type = (uint8_t)ALLOCATION_TYPE_BLOCK; - m_MemoryTypeIndex = 0; - m_BlockAllocation.m_Block = VMA_NULL; - m_BlockAllocation.m_Offset = 0; - m_BlockAllocation.m_CanBecomeLost = true; - } - - void ChangeBlockAllocation( - VmaAllocator hAllocator, - VmaDeviceMemoryBlock* block, - VkDeviceSize offset); - - void ChangeOffset(VkDeviceSize newOffset); - + bool mapped); // pMappedData not null means allocation is created with MAPPED flag. void InitDedicatedAllocation( + VmaPool hParentPool, uint32_t memoryTypeIndex, VkDeviceMemory hMemory, VmaSuballocationType suballocationType, void* pMappedData, - VkDeviceSize size) - { - VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE); - VMA_ASSERT(hMemory != VK_NULL_HANDLE); - m_Type = (uint8_t)ALLOCATION_TYPE_DEDICATED; - m_Alignment = 0; - m_Size = size; - m_MemoryTypeIndex = memoryTypeIndex; - m_SuballocationType = (uint8_t)suballocationType; - m_MapCount = (pMappedData != VMA_NULL) ? MAP_COUNT_FLAG_PERSISTENT_MAP : 0; - m_DedicatedAllocation.m_hMemory = hMemory; - m_DedicatedAllocation.m_pMappedData = pMappedData; - m_DedicatedAllocation.m_Prev = VMA_NULL; - m_DedicatedAllocation.m_Next = VMA_NULL; - } + VkDeviceSize size); ALLOCATION_TYPE GetType() const { return (ALLOCATION_TYPE)m_Type; } VkDeviceSize GetAlignment() const { return m_Alignment; } VkDeviceSize GetSize() const { return m_Size; } - bool IsUserDataString() const { return (m_Flags & FLAG_USER_DATA_STRING) != 0; } void* GetUserData() const { return m_pUserData; } - void SetUserData(VmaAllocator hAllocator, void* pUserData); + const char* GetName() const { return m_pName; } VmaSuballocationType GetSuballocationType() const { return (VmaSuballocationType)m_SuballocationType; } - VmaDeviceMemoryBlock* GetBlock() const - { - VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK); - return m_BlockAllocation.m_Block; - } - VkDeviceSize GetOffset() const; - VkDeviceMemory GetMemory() const; + VmaDeviceMemoryBlock* GetBlock() const { VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK); return m_BlockAllocation.m_Block; } uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; } - bool IsPersistentMap() const { return (m_MapCount & MAP_COUNT_FLAG_PERSISTENT_MAP) != 0; } + bool IsPersistentMap() const { return (m_Flags & FLAG_PERSISTENT_MAP) != 0; } + bool IsMappingAllowed() const { return (m_Flags & FLAG_MAPPING_ALLOWED) != 0; } + + void SetUserData(VmaAllocator hAllocator, void* pUserData) { m_pUserData = pUserData; } + void SetName(VmaAllocator hAllocator, const char* pName); + void FreeName(VmaAllocator hAllocator); + uint8_t SwapBlockAllocation(VmaAllocator hAllocator, VmaAllocation allocation); + VmaAllocHandle GetAllocHandle() const; + VkDeviceSize GetOffset() const; + VmaPool GetParentPool() const; + VkDeviceMemory GetMemory() const; void* GetMappedData() const; - bool CanBecomeLost() const; - - uint32_t GetLastUseFrameIndex() const - { - return m_LastUseFrameIndex.load(); - } - bool CompareExchangeLastUseFrameIndex(uint32_t& expected, uint32_t desired) - { - return m_LastUseFrameIndex.compare_exchange_weak(expected, desired); - } - /* - - If hAllocation.LastUseFrameIndex + frameInUseCount < allocator.CurrentFrameIndex, - makes it lost by setting LastUseFrameIndex = VMA_FRAME_INDEX_LOST and returns true. - - Else, returns false. - - If hAllocation is already lost, assert - you should not call it then. - If hAllocation was not created with CAN_BECOME_LOST_BIT, assert. - */ - bool MakeLost(uint32_t currentFrameIndex, uint32_t frameInUseCount); - - void DedicatedAllocCalcStatsInfo(VmaStatInfo& outInfo) - { - VMA_ASSERT(m_Type == ALLOCATION_TYPE_DEDICATED); - outInfo.blockCount = 1; - outInfo.allocationCount = 1; - outInfo.unusedRangeCount = 0; - outInfo.usedBytes = m_Size; - outInfo.unusedBytes = 0; - outInfo.allocationSizeMin = outInfo.allocationSizeMax = m_Size; - outInfo.unusedRangeSizeMin = UINT64_MAX; - outInfo.unusedRangeSizeMax = 0; - } void BlockAllocMap(); void BlockAllocUnmap(); @@ -4696,48 +6024,28 @@ public: void DedicatedAllocUnmap(VmaAllocator hAllocator); #if VMA_STATS_STRING_ENABLED - uint32_t GetCreationFrameIndex() const { return m_CreationFrameIndex; } uint32_t GetBufferImageUsage() const { return m_BufferImageUsage; } - void InitBufferImageUsage(uint32_t bufferImageUsage) - { - VMA_ASSERT(m_BufferImageUsage == 0); - m_BufferImageUsage = bufferImageUsage; - } - + void InitBufferImageUsage(uint32_t bufferImageUsage); void PrintParameters(class VmaJsonWriter& json) const; #endif private: - VkDeviceSize m_Alignment; - VkDeviceSize m_Size; - void* m_pUserData; - VMA_ATOMIC_UINT32 m_LastUseFrameIndex; - uint32_t m_MemoryTypeIndex; - uint8_t m_Type; // ALLOCATION_TYPE - uint8_t m_SuballocationType; // VmaSuballocationType - // Bit 0x80 is set when allocation was created with VMA_ALLOCATION_CREATE_MAPPED_BIT. - // Bits with mask 0x7F are reference counter for vmaMapMemory()/vmaUnmapMemory(). - uint8_t m_MapCount; - uint8_t m_Flags; // enum FLAGS - // Allocation out of VmaDeviceMemoryBlock. struct BlockAllocation { VmaDeviceMemoryBlock* m_Block; - VkDeviceSize m_Offset; - bool m_CanBecomeLost; + VmaAllocHandle m_AllocHandle; }; - // Allocation for an object that has its own private VkDeviceMemory. struct DedicatedAllocation { + VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool. VkDeviceMemory m_hMemory; void* m_pMappedData; // Not null means memory is mapped. VmaAllocation_T* m_Prev; VmaAllocation_T* m_Next; }; - union { // Allocation out of VmaDeviceMemoryBlock. @@ -4746,19 +6054,27 @@ private: DedicatedAllocation m_DedicatedAllocation; }; + VkDeviceSize m_Alignment; + VkDeviceSize m_Size; + void* m_pUserData; + char* m_pName; + uint32_t m_MemoryTypeIndex; + uint8_t m_Type; // ALLOCATION_TYPE + uint8_t m_SuballocationType; // VmaSuballocationType + // Reference counter for vmaMapMemory()/vmaUnmapMemory(). + uint8_t m_MapCount; + uint8_t m_Flags; // enum FLAGS #if VMA_STATS_STRING_ENABLED - uint32_t m_CreationFrameIndex; uint32_t m_BufferImageUsage; // 0 if unknown. #endif - - void FreeUserDataString(VmaAllocator hAllocator); - - friend struct VmaDedicatedAllocationListItemTraits; }; +#endif // _VMA_ALLOCATION_T +#ifndef _VMA_DEDICATED_ALLOCATION_LIST_ITEM_TRAITS struct VmaDedicatedAllocationListItemTraits { typedef VmaAllocation_T ItemType; + static ItemType* GetPrev(const ItemType* item) { VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED); @@ -4774,12 +6090,138 @@ struct VmaDedicatedAllocationListItemTraits VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED); return item->m_DedicatedAllocation.m_Prev; } - static ItemType*& AccessNext(ItemType* item){ + static ItemType*& AccessNext(ItemType* item) + { VMA_HEAVY_ASSERT(item->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED); return item->m_DedicatedAllocation.m_Next; } }; +#endif // _VMA_DEDICATED_ALLOCATION_LIST_ITEM_TRAITS +#ifndef _VMA_DEDICATED_ALLOCATION_LIST +/* +Stores linked list of VmaAllocation_T objects. +Thread-safe, synchronized internally. +*/ +class VmaDedicatedAllocationList +{ +public: + VmaDedicatedAllocationList() {} + ~VmaDedicatedAllocationList(); + + void Init(bool useMutex) { m_UseMutex = useMutex; } + bool Validate(); + + void AddDetailedStatistics(VmaDetailedStatistics& inoutStats); + void AddStatistics(VmaStatistics& inoutStats); +#if VMA_STATS_STRING_ENABLED + // Writes JSON array with the list of allocations. + void BuildStatsString(VmaJsonWriter& json); +#endif + + bool IsEmpty(); + void Register(VmaAllocation alloc); + void Unregister(VmaAllocation alloc); + +private: + typedef VmaIntrusiveLinkedList DedicatedAllocationLinkedList; + + bool m_UseMutex = true; + VMA_RW_MUTEX m_Mutex; + DedicatedAllocationLinkedList m_AllocationList; +}; + +#ifndef _VMA_DEDICATED_ALLOCATION_LIST_FUNCTIONS + +VmaDedicatedAllocationList::~VmaDedicatedAllocationList() +{ + VMA_HEAVY_ASSERT(Validate()); + + if (!m_AllocationList.IsEmpty()) + { + VMA_ASSERT(false && "Unfreed dedicated allocations found!"); + } +} + +bool VmaDedicatedAllocationList::Validate() +{ + const size_t declaredCount = m_AllocationList.GetCount(); + size_t actualCount = 0; + VmaMutexLockRead lock(m_Mutex, m_UseMutex); + for (VmaAllocation alloc = m_AllocationList.Front(); + alloc != VMA_NULL; alloc = m_AllocationList.GetNext(alloc)) + { + ++actualCount; + } + VMA_VALIDATE(actualCount == declaredCount); + + return true; +} + +void VmaDedicatedAllocationList::AddDetailedStatistics(VmaDetailedStatistics& inoutStats) +{ + for(auto* item = m_AllocationList.Front(); item != nullptr; item = DedicatedAllocationLinkedList::GetNext(item)) + { + const VkDeviceSize size = item->GetSize(); + inoutStats.statistics.blockCount++; + inoutStats.statistics.blockBytes += size; + VmaAddDetailedStatisticsAllocation(inoutStats, item->GetSize()); + } +} + +void VmaDedicatedAllocationList::AddStatistics(VmaStatistics& inoutStats) +{ + VmaMutexLockRead lock(m_Mutex, m_UseMutex); + + const uint32_t allocCount = (uint32_t)m_AllocationList.GetCount(); + inoutStats.blockCount += allocCount; + inoutStats.allocationCount += allocCount; + + for(auto* item = m_AllocationList.Front(); item != nullptr; item = DedicatedAllocationLinkedList::GetNext(item)) + { + const VkDeviceSize size = item->GetSize(); + inoutStats.blockBytes += size; + inoutStats.allocationBytes += size; + } +} + +#if VMA_STATS_STRING_ENABLED +void VmaDedicatedAllocationList::BuildStatsString(VmaJsonWriter& json) +{ + VmaMutexLockRead lock(m_Mutex, m_UseMutex); + json.BeginArray(); + for (VmaAllocation alloc = m_AllocationList.Front(); + alloc != VMA_NULL; alloc = m_AllocationList.GetNext(alloc)) + { + json.BeginObject(true); + alloc->PrintParameters(json); + json.EndObject(); + } + json.EndArray(); +} +#endif // VMA_STATS_STRING_ENABLED + +bool VmaDedicatedAllocationList::IsEmpty() +{ + VmaMutexLockRead lock(m_Mutex, m_UseMutex); + return m_AllocationList.IsEmpty(); +} + +void VmaDedicatedAllocationList::Register(VmaAllocation alloc) +{ + VmaMutexLockWrite lock(m_Mutex, m_UseMutex); + m_AllocationList.PushBack(alloc); +} + +void VmaDedicatedAllocationList::Unregister(VmaAllocation alloc) +{ + VmaMutexLockWrite lock(m_Mutex, m_UseMutex); + m_AllocationList.Remove(alloc); +} +#endif // _VMA_DEDICATED_ALLOCATION_LIST_FUNCTIONS +#endif // _VMA_DEDICATED_ALLOCATION_LIST + +#ifndef _VMA_SUBALLOCATION /* Represents a region of VmaDeviceMemoryBlock that is either assigned and returned as allocated memory block or free. @@ -4788,7 +6230,7 @@ struct VmaSuballocation { VkDeviceSize offset; VkDeviceSize size; - VmaAllocation hAllocation; + void* userData; VmaSuballocationType type; }; @@ -4800,6 +6242,7 @@ struct VmaSuballocationOffsetLess return lhs.offset < rhs.offset; } }; + struct VmaSuballocationOffsetGreater { bool operator()(const VmaSuballocation& lhs, const VmaSuballocation& rhs) const @@ -4808,49 +6251,39 @@ struct VmaSuballocationOffsetGreater } }; -typedef VmaList< VmaSuballocation, VmaStlAllocator > VmaSuballocationList; - -// Cost of one additional allocation lost, as equivalent in bytes. -static const VkDeviceSize VMA_LOST_ALLOCATION_COST = 1048576; - -enum class VmaAllocationRequestType +struct VmaSuballocationItemSizeLess { - Normal, - // Used by "Linear" algorithm. - UpperAddress, - EndOf1st, - EndOf2nd, -}; + bool operator()(const VmaSuballocationList::iterator lhs, + const VmaSuballocationList::iterator rhs) const + { + return lhs->size < rhs->size; + } + bool operator()(const VmaSuballocationList::iterator lhs, + VkDeviceSize rhsSize) const + { + return lhs->size < rhsSize; + } +}; +#endif // _VMA_SUBALLOCATION + +#ifndef _VMA_ALLOCATION_REQUEST /* Parameters of planned allocation inside a VmaDeviceMemoryBlock. - -If canMakeOtherLost was false: -- item points to a FREE suballocation. -- itemsToMakeLostCount is 0. - -If canMakeOtherLost was true: -- item points to first of sequence of suballocations, which are either FREE, - or point to VmaAllocations that can become lost. -- itemsToMakeLostCount is the number of VmaAllocations that need to be made lost for - the requested allocation to succeed. +item points to a FREE suballocation. */ struct VmaAllocationRequest { - VkDeviceSize offset; - VkDeviceSize sumFreeSize; // Sum size of free items that overlap with proposed allocation. - VkDeviceSize sumItemSize; // Sum size of items to make lost that overlap with proposed allocation. + VmaAllocHandle allocHandle; + VkDeviceSize size; VmaSuballocationList::iterator item; - size_t itemsToMakeLostCount; void* customData; + uint64_t algorithmData; VmaAllocationRequestType type; - - VkDeviceSize CalcCost() const - { - return sumItemSize + itemsToMakeLostCount * VMA_LOST_ALLOCATION_COST; - } }; +#endif // _VMA_ALLOCATION_REQUEST +#ifndef _VMA_BLOCK_METADATA /* Data structure used for bookkeeping of allocations and unused ranges of memory in a single VkDeviceMemory block. @@ -4858,22 +6291,33 @@ in a single VkDeviceMemory block. class VmaBlockMetadata { public: - VmaBlockMetadata(VmaAllocator hAllocator); - virtual ~VmaBlockMetadata() { } + // pAllocationCallbacks, if not null, must be owned externally - alive and unchanged for the whole lifetime of this object. + VmaBlockMetadata(const VkAllocationCallbacks* pAllocationCallbacks, + VkDeviceSize bufferImageGranularity, bool isVirtual); + virtual ~VmaBlockMetadata() = default; + virtual void Init(VkDeviceSize size) { m_Size = size; } + bool IsVirtual() const { return m_IsVirtual; } + VkDeviceSize GetSize() const { return m_Size; } // Validates all data structures inside this object. If not valid, returns false. virtual bool Validate() const = 0; - VkDeviceSize GetSize() const { return m_Size; } virtual size_t GetAllocationCount() const = 0; + virtual size_t GetFreeRegionsCount() const = 0; virtual VkDeviceSize GetSumFreeSize() const = 0; - virtual VkDeviceSize GetUnusedRangeSizeMax() const = 0; // Returns true if this block is empty - contains only single free suballocation. virtual bool IsEmpty() const = 0; + virtual void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) = 0; + virtual VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const = 0; + virtual void* GetAllocationUserData(VmaAllocHandle allocHandle) const = 0; + + virtual VmaAllocHandle GetAllocationListBegin() const = 0; + virtual VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const = 0; + virtual VkDeviceSize GetNextFreeRegionSize(VmaAllocHandle alloc) const = 0; - virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const = 0; // Shouldn't modify blockCount. - virtual void AddPoolStats(VmaPoolStats& inoutStats) const = 0; + virtual void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const = 0; + virtual void AddStatistics(VmaStatistics& inoutStats) const = 0; #if VMA_STATS_STRING_ENABLED virtual void PrintDetailedMap(class VmaJsonWriter& json) const = 0; @@ -4883,49 +6327,46 @@ public: // If succeeded, fills pAllocationRequest and returns true. // If failed, returns false. virtual bool CreateAllocationRequest( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, VkDeviceSize allocSize, VkDeviceSize allocAlignment, bool upperAddress, VmaSuballocationType allocType, - bool canMakeOtherLost, // Always one of VMA_ALLOCATION_CREATE_STRATEGY_* or VMA_ALLOCATION_INTERNAL_STRATEGY_* flags. uint32_t strategy, VmaAllocationRequest* pAllocationRequest) = 0; - virtual bool MakeRequestedAllocationsLost( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VmaAllocationRequest* pAllocationRequest) = 0; - - virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) = 0; - virtual VkResult CheckCorruption(const void* pBlockData) = 0; // Makes actual allocation based on request. Request must already be checked and valid. virtual void Alloc( const VmaAllocationRequest& request, VmaSuballocationType type, - VkDeviceSize allocSize, - VmaAllocation hAllocation) = 0; + void* userData) = 0; // Frees suballocation assigned to given memory region. - virtual void Free(const VmaAllocation allocation) = 0; - virtual void FreeAtOffset(VkDeviceSize offset) = 0; + virtual void Free(VmaAllocHandle allocHandle) = 0; + + // Frees all allocations. + // Careful! Don't call it if there are VmaAllocation objects owned by userData of cleared allocations! + virtual void Clear() = 0; + + virtual void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) = 0; + virtual void DebugLogAllAllocations() const = 0; protected: const VkAllocationCallbacks* GetAllocationCallbacks() const { return m_pAllocationCallbacks; } + VkDeviceSize GetBufferImageGranularity() const { return m_BufferImageGranularity; } + VkDeviceSize GetDebugMargin() const { return IsVirtual() ? 0 : VMA_DEBUG_MARGIN; } + void DebugLogAllocation(VkDeviceSize offset, VkDeviceSize size, void* userData) const; #if VMA_STATS_STRING_ENABLED + // mapRefCount == UINT32_MAX means unspecified. void PrintDetailedMap_Begin(class VmaJsonWriter& json, VkDeviceSize unusedBytes, size_t allocationCount, size_t unusedRangeCount) const; void PrintDetailedMap_Allocation(class VmaJsonWriter& json, - VkDeviceSize offset, - VmaAllocation hAllocation) const; + VkDeviceSize offset, VkDeviceSize size, void* userData) const; void PrintDetailedMap_UnusedRange(class VmaJsonWriter& json, VkDeviceSize offset, VkDeviceSize size) const; @@ -4935,99 +6376,426 @@ protected: private: VkDeviceSize m_Size; const VkAllocationCallbacks* m_pAllocationCallbacks; + const VkDeviceSize m_BufferImageGranularity; + const bool m_IsVirtual; }; -#define VMA_VALIDATE(cond) do { if(!(cond)) { \ - VMA_ASSERT(0 && "Validation failed: " #cond); \ - return false; \ - } } while(false) +#ifndef _VMA_BLOCK_METADATA_FUNCTIONS +VmaBlockMetadata::VmaBlockMetadata(const VkAllocationCallbacks* pAllocationCallbacks, + VkDeviceSize bufferImageGranularity, bool isVirtual) + : m_Size(0), + m_pAllocationCallbacks(pAllocationCallbacks), + m_BufferImageGranularity(bufferImageGranularity), + m_IsVirtual(isVirtual) {} -class VmaBlockMetadata_Generic : public VmaBlockMetadata +void VmaBlockMetadata::DebugLogAllocation(VkDeviceSize offset, VkDeviceSize size, void* userData) const { - VMA_CLASS_NO_COPY(VmaBlockMetadata_Generic) -public: - VmaBlockMetadata_Generic(VmaAllocator hAllocator); - virtual ~VmaBlockMetadata_Generic(); - virtual void Init(VkDeviceSize size); + if (IsVirtual()) + { + VMA_DEBUG_LOG("UNFREED VIRTUAL ALLOCATION; Offset: %llu; Size: %llu; UserData: %p", offset, size, userData); + } + else + { + VMA_ASSERT(userData != VMA_NULL); + VmaAllocation allocation = reinterpret_cast(userData); - virtual bool Validate() const; - virtual size_t GetAllocationCount() const { return m_Suballocations.size() - m_FreeCount; } - virtual VkDeviceSize GetSumFreeSize() const { return m_SumFreeSize; } - virtual VkDeviceSize GetUnusedRangeSizeMax() const; - virtual bool IsEmpty() const; - - virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const; - virtual void AddPoolStats(VmaPoolStats& inoutStats) const; + userData = allocation->GetUserData(); + const char* name = allocation->GetName(); #if VMA_STATS_STRING_ENABLED - virtual void PrintDetailedMap(class VmaJsonWriter& json) const; + VMA_DEBUG_LOG("UNFREED ALLOCATION; Offset: %llu; Size: %llu; UserData: %p; Name: %s; Type: %s; Usage: %u", + offset, size, userData, name ? name : "vma_empty", + VMA_SUBALLOCATION_TYPE_NAMES[allocation->GetSuballocationType()], + allocation->GetBufferImageUsage()); +#else + VMA_DEBUG_LOG("UNFREED ALLOCATION; Offset: %llu; Size: %llu; UserData: %p; Name: %s; Type: %u", + offset, size, userData, name ? name : "vma_empty", + (uint32_t)allocation->GetSuballocationType()); +#endif // VMA_STATS_STRING_ENABLED + } + +} + +#if VMA_STATS_STRING_ENABLED +void VmaBlockMetadata::PrintDetailedMap_Begin(class VmaJsonWriter& json, + VkDeviceSize unusedBytes, size_t allocationCount, size_t unusedRangeCount) const +{ + json.WriteString("TotalBytes"); + json.WriteNumber(GetSize()); + + json.WriteString("UnusedBytes"); + json.WriteSize(unusedBytes); + + json.WriteString("Allocations"); + json.WriteSize(allocationCount); + + json.WriteString("UnusedRanges"); + json.WriteSize(unusedRangeCount); + + json.WriteString("Suballocations"); + json.BeginArray(); +} + +void VmaBlockMetadata::PrintDetailedMap_Allocation(class VmaJsonWriter& json, + VkDeviceSize offset, VkDeviceSize size, void* userData) const +{ + json.BeginObject(true); + + json.WriteString("Offset"); + json.WriteNumber(offset); + + if (IsVirtual()) + { + json.WriteString("Size"); + json.WriteNumber(size); + if (userData) + { + json.WriteString("CustomData"); + json.BeginString(); + json.ContinueString_Pointer(userData); + json.EndString(); + } + } + else + { + ((VmaAllocation)userData)->PrintParameters(json); + } + + json.EndObject(); +} + +void VmaBlockMetadata::PrintDetailedMap_UnusedRange(class VmaJsonWriter& json, + VkDeviceSize offset, VkDeviceSize size) const +{ + json.BeginObject(true); + + json.WriteString("Offset"); + json.WriteNumber(offset); + + json.WriteString("Type"); + json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[VMA_SUBALLOCATION_TYPE_FREE]); + + json.WriteString("Size"); + json.WriteNumber(size); + + json.EndObject(); +} + +void VmaBlockMetadata::PrintDetailedMap_End(class VmaJsonWriter& json) const +{ + json.EndArray(); +} +#endif // VMA_STATS_STRING_ENABLED +#endif // _VMA_BLOCK_METADATA_FUNCTIONS +#endif // _VMA_BLOCK_METADATA + +#ifndef _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY +// Before deleting object of this class remember to call 'Destroy()' +class VmaBlockBufferImageGranularity final +{ +public: + struct ValidationContext + { + const VkAllocationCallbacks* allocCallbacks; + uint16_t* pageAllocs; + }; + + VmaBlockBufferImageGranularity(VkDeviceSize bufferImageGranularity); + ~VmaBlockBufferImageGranularity(); + + bool IsEnabled() const { return m_BufferImageGranularity > MAX_LOW_BUFFER_IMAGE_GRANULARITY; } + + void Init(const VkAllocationCallbacks* pAllocationCallbacks, VkDeviceSize size); + // Before destroying object you must call free it's memory + void Destroy(const VkAllocationCallbacks* pAllocationCallbacks); + + void RoundupAllocRequest(VmaSuballocationType allocType, + VkDeviceSize& inOutAllocSize, + VkDeviceSize& inOutAllocAlignment) const; + + bool CheckConflictAndAlignUp(VkDeviceSize& inOutAllocOffset, + VkDeviceSize allocSize, + VkDeviceSize blockOffset, + VkDeviceSize blockSize, + VmaSuballocationType allocType) const; + + void AllocPages(uint8_t allocType, VkDeviceSize offset, VkDeviceSize size); + void FreePages(VkDeviceSize offset, VkDeviceSize size); + void Clear(); + + ValidationContext StartValidation(const VkAllocationCallbacks* pAllocationCallbacks, + bool isVirutal) const; + bool Validate(ValidationContext& ctx, VkDeviceSize offset, VkDeviceSize size) const; + bool FinishValidation(ValidationContext& ctx) const; + +private: + static const uint16_t MAX_LOW_BUFFER_IMAGE_GRANULARITY = 256; + + struct RegionInfo + { + uint8_t allocType; + uint16_t allocCount; + }; + + VkDeviceSize m_BufferImageGranularity; + uint32_t m_RegionCount; + RegionInfo* m_RegionInfo; + + uint32_t GetStartPage(VkDeviceSize offset) const { return OffsetToPageIndex(offset & ~(m_BufferImageGranularity - 1)); } + uint32_t GetEndPage(VkDeviceSize offset, VkDeviceSize size) const { return OffsetToPageIndex((offset + size - 1) & ~(m_BufferImageGranularity - 1)); } + + uint32_t OffsetToPageIndex(VkDeviceSize offset) const; + void AllocPage(RegionInfo& page, uint8_t allocType); +}; + +#ifndef _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY_FUNCTIONS +VmaBlockBufferImageGranularity::VmaBlockBufferImageGranularity(VkDeviceSize bufferImageGranularity) + : m_BufferImageGranularity(bufferImageGranularity), + m_RegionCount(0), + m_RegionInfo(VMA_NULL) {} + +VmaBlockBufferImageGranularity::~VmaBlockBufferImageGranularity() +{ + VMA_ASSERT(m_RegionInfo == VMA_NULL && "Free not called before destroying object!"); +} + +void VmaBlockBufferImageGranularity::Init(const VkAllocationCallbacks* pAllocationCallbacks, VkDeviceSize size) +{ + if (IsEnabled()) + { + m_RegionCount = static_cast(VmaDivideRoundingUp(size, m_BufferImageGranularity)); + m_RegionInfo = vma_new_array(pAllocationCallbacks, RegionInfo, m_RegionCount); + memset(m_RegionInfo, 0, m_RegionCount * sizeof(RegionInfo)); + } +} + +void VmaBlockBufferImageGranularity::Destroy(const VkAllocationCallbacks* pAllocationCallbacks) +{ + if (m_RegionInfo) + { + vma_delete_array(pAllocationCallbacks, m_RegionInfo, m_RegionCount); + m_RegionInfo = VMA_NULL; + } +} + +void VmaBlockBufferImageGranularity::RoundupAllocRequest(VmaSuballocationType allocType, + VkDeviceSize& inOutAllocSize, + VkDeviceSize& inOutAllocAlignment) const +{ + if (m_BufferImageGranularity > 1 && + m_BufferImageGranularity <= MAX_LOW_BUFFER_IMAGE_GRANULARITY) + { + if (allocType == VMA_SUBALLOCATION_TYPE_UNKNOWN || + allocType == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN || + allocType == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL) + { + inOutAllocAlignment = VMA_MAX(inOutAllocAlignment, m_BufferImageGranularity); + inOutAllocSize = VmaAlignUp(inOutAllocSize, m_BufferImageGranularity); + } + } +} + +bool VmaBlockBufferImageGranularity::CheckConflictAndAlignUp(VkDeviceSize& inOutAllocOffset, + VkDeviceSize allocSize, + VkDeviceSize blockOffset, + VkDeviceSize blockSize, + VmaSuballocationType allocType) const +{ + if (IsEnabled()) + { + uint32_t startPage = GetStartPage(inOutAllocOffset); + if (m_RegionInfo[startPage].allocCount > 0 && + VmaIsBufferImageGranularityConflict(static_cast(m_RegionInfo[startPage].allocType), allocType)) + { + inOutAllocOffset = VmaAlignUp(inOutAllocOffset, m_BufferImageGranularity); + if (blockSize < allocSize + inOutAllocOffset - blockOffset) + return true; + ++startPage; + } + uint32_t endPage = GetEndPage(inOutAllocOffset, allocSize); + if (endPage != startPage && + m_RegionInfo[endPage].allocCount > 0 && + VmaIsBufferImageGranularityConflict(static_cast(m_RegionInfo[endPage].allocType), allocType)) + { + return true; + } + } + return false; +} + +void VmaBlockBufferImageGranularity::AllocPages(uint8_t allocType, VkDeviceSize offset, VkDeviceSize size) +{ + if (IsEnabled()) + { + uint32_t startPage = GetStartPage(offset); + AllocPage(m_RegionInfo[startPage], allocType); + + uint32_t endPage = GetEndPage(offset, size); + if (startPage != endPage) + AllocPage(m_RegionInfo[endPage], allocType); + } +} + +void VmaBlockBufferImageGranularity::FreePages(VkDeviceSize offset, VkDeviceSize size) +{ + if (IsEnabled()) + { + uint32_t startPage = GetStartPage(offset); + --m_RegionInfo[startPage].allocCount; + if (m_RegionInfo[startPage].allocCount == 0) + m_RegionInfo[startPage].allocType = VMA_SUBALLOCATION_TYPE_FREE; + uint32_t endPage = GetEndPage(offset, size); + if (startPage != endPage) + { + --m_RegionInfo[endPage].allocCount; + if (m_RegionInfo[endPage].allocCount == 0) + m_RegionInfo[endPage].allocType = VMA_SUBALLOCATION_TYPE_FREE; + } + } +} + +void VmaBlockBufferImageGranularity::Clear() +{ + if (m_RegionInfo) + memset(m_RegionInfo, 0, m_RegionCount * sizeof(RegionInfo)); +} + +VmaBlockBufferImageGranularity::ValidationContext VmaBlockBufferImageGranularity::StartValidation( + const VkAllocationCallbacks* pAllocationCallbacks, bool isVirutal) const +{ + ValidationContext ctx{ pAllocationCallbacks, VMA_NULL }; + if (!isVirutal && IsEnabled()) + { + ctx.pageAllocs = vma_new_array(pAllocationCallbacks, uint16_t, m_RegionCount); + memset(ctx.pageAllocs, 0, m_RegionCount * sizeof(uint16_t)); + } + return ctx; +} + +bool VmaBlockBufferImageGranularity::Validate(ValidationContext& ctx, + VkDeviceSize offset, VkDeviceSize size) const +{ + if (IsEnabled()) + { + uint32_t start = GetStartPage(offset); + ++ctx.pageAllocs[start]; + VMA_VALIDATE(m_RegionInfo[start].allocCount > 0); + + uint32_t end = GetEndPage(offset, size); + if (start != end) + { + ++ctx.pageAllocs[end]; + VMA_VALIDATE(m_RegionInfo[end].allocCount > 0); + } + } + return true; +} + +bool VmaBlockBufferImageGranularity::FinishValidation(ValidationContext& ctx) const +{ + // Check proper page structure + if (IsEnabled()) + { + VMA_ASSERT(ctx.pageAllocs != VMA_NULL && "Validation context not initialized!"); + + for (uint32_t page = 0; page < m_RegionCount; ++page) + { + VMA_VALIDATE(ctx.pageAllocs[page] == m_RegionInfo[page].allocCount); + } + vma_delete_array(ctx.allocCallbacks, ctx.pageAllocs, m_RegionCount); + ctx.pageAllocs = VMA_NULL; + } + return true; +} + +uint32_t VmaBlockBufferImageGranularity::OffsetToPageIndex(VkDeviceSize offset) const +{ + return static_cast(offset >> VMA_BITSCAN_MSB(m_BufferImageGranularity)); +} + +void VmaBlockBufferImageGranularity::AllocPage(RegionInfo& page, uint8_t allocType) +{ + // When current alloc type is free then it can be overriden by new type + if (page.allocCount == 0 || (page.allocCount > 0 && page.allocType == VMA_SUBALLOCATION_TYPE_FREE)) + page.allocType = allocType; + + ++page.allocCount; +} +#endif // _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY_FUNCTIONS +#endif // _VMA_BLOCK_BUFFER_IMAGE_GRANULARITY + +#if 0 +#ifndef _VMA_BLOCK_METADATA_GENERIC +class VmaBlockMetadata_Generic : public VmaBlockMetadata +{ + friend class VmaDefragmentationAlgorithm_Generic; + friend class VmaDefragmentationAlgorithm_Fast; + VMA_CLASS_NO_COPY(VmaBlockMetadata_Generic) +public: + VmaBlockMetadata_Generic(const VkAllocationCallbacks* pAllocationCallbacks, + VkDeviceSize bufferImageGranularity, bool isVirtual); + virtual ~VmaBlockMetadata_Generic() = default; + + size_t GetAllocationCount() const override { return m_Suballocations.size() - m_FreeCount; } + VkDeviceSize GetSumFreeSize() const override { return m_SumFreeSize; } + bool IsEmpty() const override { return (m_Suballocations.size() == 1) && (m_FreeCount == 1); } + void Free(VmaAllocHandle allocHandle) override { FreeSuballocation(FindAtOffset((VkDeviceSize)allocHandle - 1)); } + VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle - 1; }; + + void Init(VkDeviceSize size) override; + bool Validate() const override; + + void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const override; + void AddStatistics(VmaStatistics& inoutStats) const override; + +#if VMA_STATS_STRING_ENABLED + void PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const override; #endif - virtual bool CreateAllocationRequest( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, + bool CreateAllocationRequest( VkDeviceSize allocSize, VkDeviceSize allocAlignment, bool upperAddress, VmaSuballocationType allocType, - bool canMakeOtherLost, uint32_t strategy, - VmaAllocationRequest* pAllocationRequest); + VmaAllocationRequest* pAllocationRequest) override; - virtual bool MakeRequestedAllocationsLost( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VmaAllocationRequest* pAllocationRequest); + VkResult CheckCorruption(const void* pBlockData) override; - virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount); - - virtual VkResult CheckCorruption(const void* pBlockData); - - virtual void Alloc( + void Alloc( const VmaAllocationRequest& request, VmaSuballocationType type, - VkDeviceSize allocSize, - VmaAllocation hAllocation); + void* userData) override; - virtual void Free(const VmaAllocation allocation); - virtual void FreeAtOffset(VkDeviceSize offset); - - //////////////////////////////////////////////////////////////////////////////// - // For defragmentation - - bool IsBufferImageGranularityConflictPossible( - VkDeviceSize bufferImageGranularity, - VmaSuballocationType& inOutPrevSuballocType) const; + void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override; + void* GetAllocationUserData(VmaAllocHandle allocHandle) const override; + VmaAllocHandle GetAllocationListBegin() const override; + VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override; + void Clear() override; + void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override; + void DebugLogAllAllocations() const override; private: - friend class VmaDefragmentationAlgorithm_Generic; - friend class VmaDefragmentationAlgorithm_Fast; - uint32_t m_FreeCount; VkDeviceSize m_SumFreeSize; VmaSuballocationList m_Suballocations; - // Suballocations that are free and have size greater than certain threshold. - // Sorted by size, ascending. - VmaVector< VmaSuballocationList::iterator, VmaStlAllocator< VmaSuballocationList::iterator > > m_FreeSuballocationsBySize; + // Suballocations that are free. Sorted by size, ascending. + VmaVector> m_FreeSuballocationsBySize; + VkDeviceSize AlignAllocationSize(VkDeviceSize size) const { return IsVirtual() ? size : VmaAlignUp(size, (VkDeviceSize)16); } + + VmaSuballocationList::iterator FindAtOffset(VkDeviceSize offset) const; bool ValidateFreeSuballocationList() const; // Checks if requested suballocation with given parameters can be placed in given pFreeSuballocItem. // If yes, fills pOffset and returns true. If no, returns false. bool CheckAllocation( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, VkDeviceSize allocSize, VkDeviceSize allocAlignment, VmaSuballocationType allocType, VmaSuballocationList::const_iterator suballocItem, - bool canMakeOtherLost, - VkDeviceSize* pOffset, - size_t* itemsToMakeLostCount, - VkDeviceSize* pSumFreeSize, - VkDeviceSize* pSumItemSize) const; + VmaAllocHandle* pAllocHandle) const; + // Given free suballocation, it merges it with following one, which must also be free. void MergeFreeWithNext(VmaSuballocationList::iterator item); // Releases given suballocation, making it free. @@ -5042,6 +6810,685 @@ private: void UnregisterFreeSuballocation(VmaSuballocationList::iterator item); }; +#ifndef _VMA_BLOCK_METADATA_GENERIC_FUNCTIONS +VmaBlockMetadata_Generic::VmaBlockMetadata_Generic(const VkAllocationCallbacks* pAllocationCallbacks, + VkDeviceSize bufferImageGranularity, bool isVirtual) + : VmaBlockMetadata(pAllocationCallbacks, bufferImageGranularity, isVirtual), + m_FreeCount(0), + m_SumFreeSize(0), + m_Suballocations(VmaStlAllocator(pAllocationCallbacks)), + m_FreeSuballocationsBySize(VmaStlAllocator(pAllocationCallbacks)) {} + +void VmaBlockMetadata_Generic::Init(VkDeviceSize size) +{ + VmaBlockMetadata::Init(size); + + m_FreeCount = 1; + m_SumFreeSize = size; + + VmaSuballocation suballoc = {}; + suballoc.offset = 0; + suballoc.size = size; + suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + + m_Suballocations.push_back(suballoc); + m_FreeSuballocationsBySize.push_back(m_Suballocations.begin()); +} + +bool VmaBlockMetadata_Generic::Validate() const +{ + VMA_VALIDATE(!m_Suballocations.empty()); + + // Expected offset of new suballocation as calculated from previous ones. + VkDeviceSize calculatedOffset = 0; + // Expected number of free suballocations as calculated from traversing their list. + uint32_t calculatedFreeCount = 0; + // Expected sum size of free suballocations as calculated from traversing their list. + VkDeviceSize calculatedSumFreeSize = 0; + // Expected number of free suballocations that should be registered in + // m_FreeSuballocationsBySize calculated from traversing their list. + size_t freeSuballocationsToRegister = 0; + // True if previous visited suballocation was free. + bool prevFree = false; + + const VkDeviceSize debugMargin = GetDebugMargin(); + + for (const auto& subAlloc : m_Suballocations) + { + // Actual offset of this suballocation doesn't match expected one. + VMA_VALIDATE(subAlloc.offset == calculatedOffset); + + const bool currFree = (subAlloc.type == VMA_SUBALLOCATION_TYPE_FREE); + // Two adjacent free suballocations are invalid. They should be merged. + VMA_VALIDATE(!prevFree || !currFree); + + VmaAllocation alloc = (VmaAllocation)subAlloc.userData; + if (!IsVirtual()) + { + VMA_VALIDATE(currFree == (alloc == VK_NULL_HANDLE)); + } + + if (currFree) + { + calculatedSumFreeSize += subAlloc.size; + ++calculatedFreeCount; + ++freeSuballocationsToRegister; + + // Margin required between allocations - every free space must be at least that large. + VMA_VALIDATE(subAlloc.size >= debugMargin); + } + else + { + if (!IsVirtual()) + { + VMA_VALIDATE((VkDeviceSize)alloc->GetAllocHandle() == subAlloc.offset + 1); + VMA_VALIDATE(alloc->GetSize() == subAlloc.size); + } + + // Margin required between allocations - previous allocation must be free. + VMA_VALIDATE(debugMargin == 0 || prevFree); + } + + calculatedOffset += subAlloc.size; + prevFree = currFree; + } + + // Number of free suballocations registered in m_FreeSuballocationsBySize doesn't + // match expected one. + VMA_VALIDATE(m_FreeSuballocationsBySize.size() == freeSuballocationsToRegister); + + VkDeviceSize lastSize = 0; + for (size_t i = 0; i < m_FreeSuballocationsBySize.size(); ++i) + { + VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[i]; + + // Only free suballocations can be registered in m_FreeSuballocationsBySize. + VMA_VALIDATE(suballocItem->type == VMA_SUBALLOCATION_TYPE_FREE); + // They must be sorted by size ascending. + VMA_VALIDATE(suballocItem->size >= lastSize); + + lastSize = suballocItem->size; + } + + // Check if totals match calculated values. + VMA_VALIDATE(ValidateFreeSuballocationList()); + VMA_VALIDATE(calculatedOffset == GetSize()); + VMA_VALIDATE(calculatedSumFreeSize == m_SumFreeSize); + VMA_VALIDATE(calculatedFreeCount == m_FreeCount); + + return true; +} + +void VmaBlockMetadata_Generic::AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const +{ + const uint32_t rangeCount = (uint32_t)m_Suballocations.size(); + inoutStats.statistics.blockCount++; + inoutStats.statistics.blockBytes += GetSize(); + + for (const auto& suballoc : m_Suballocations) + { + if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) + VmaAddDetailedStatisticsAllocation(inoutStats, suballoc.size); + else + VmaAddDetailedStatisticsUnusedRange(inoutStats, suballoc.size); + } +} + +void VmaBlockMetadata_Generic::AddStatistics(VmaStatistics& inoutStats) const +{ + inoutStats.blockCount++; + inoutStats.allocationCount += (uint32_t)m_Suballocations.size() - m_FreeCount; + inoutStats.blockBytes += GetSize(); + inoutStats.allocationBytes += GetSize() - m_SumFreeSize; +} + +#if VMA_STATS_STRING_ENABLED +void VmaBlockMetadata_Generic::PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const +{ + PrintDetailedMap_Begin(json, + m_SumFreeSize, // unusedBytes + m_Suballocations.size() - (size_t)m_FreeCount, // allocationCount + m_FreeCount, // unusedRangeCount + mapRefCount); + + for (const auto& suballoc : m_Suballocations) + { + if (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE) + { + PrintDetailedMap_UnusedRange(json, suballoc.offset, suballoc.size); + } + else + { + PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.size, suballoc.userData); + } + } + + PrintDetailedMap_End(json); +} +#endif // VMA_STATS_STRING_ENABLED + +bool VmaBlockMetadata_Generic::CreateAllocationRequest( + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + bool upperAddress, + VmaSuballocationType allocType, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) +{ + VMA_ASSERT(allocSize > 0); + VMA_ASSERT(!upperAddress); + VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE); + VMA_ASSERT(pAllocationRequest != VMA_NULL); + VMA_HEAVY_ASSERT(Validate()); + + allocSize = AlignAllocationSize(allocSize); + + pAllocationRequest->type = VmaAllocationRequestType::Normal; + pAllocationRequest->size = allocSize; + + const VkDeviceSize debugMargin = GetDebugMargin(); + + // There is not enough total free space in this block to fulfill the request: Early return. + if (m_SumFreeSize < allocSize + debugMargin) + { + return false; + } + + // New algorithm, efficiently searching freeSuballocationsBySize. + const size_t freeSuballocCount = m_FreeSuballocationsBySize.size(); + if (freeSuballocCount > 0) + { + if (strategy == 0 || + strategy == VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT) + { + // Find first free suballocation with size not less than allocSize + debugMargin. + VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess( + m_FreeSuballocationsBySize.data(), + m_FreeSuballocationsBySize.data() + freeSuballocCount, + allocSize + debugMargin, + VmaSuballocationItemSizeLess()); + size_t index = it - m_FreeSuballocationsBySize.data(); + for (; index < freeSuballocCount; ++index) + { + if (CheckAllocation( + allocSize, + allocAlignment, + allocType, + m_FreeSuballocationsBySize[index], + &pAllocationRequest->allocHandle)) + { + pAllocationRequest->item = m_FreeSuballocationsBySize[index]; + return true; + } + } + } + else if (strategy == VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET) + { + for (VmaSuballocationList::iterator it = m_Suballocations.begin(); + it != m_Suballocations.end(); + ++it) + { + if (it->type == VMA_SUBALLOCATION_TYPE_FREE && CheckAllocation( + allocSize, + allocAlignment, + allocType, + it, + &pAllocationRequest->allocHandle)) + { + pAllocationRequest->item = it; + return true; + } + } + } + else + { + VMA_ASSERT(strategy & (VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT | VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT )); + // Search staring from biggest suballocations. + for (size_t index = freeSuballocCount; index--; ) + { + if (CheckAllocation( + allocSize, + allocAlignment, + allocType, + m_FreeSuballocationsBySize[index], + &pAllocationRequest->allocHandle)) + { + pAllocationRequest->item = m_FreeSuballocationsBySize[index]; + return true; + } + } + } + } + + return false; +} + +VkResult VmaBlockMetadata_Generic::CheckCorruption(const void* pBlockData) +{ + for (auto& suballoc : m_Suballocations) + { + if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) + { + if (!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!"); + return VK_ERROR_UNKNOWN_COPY; + } + } + } + + return VK_SUCCESS; +} + +void VmaBlockMetadata_Generic::Alloc( + const VmaAllocationRequest& request, + VmaSuballocationType type, + void* userData) +{ + VMA_ASSERT(request.type == VmaAllocationRequestType::Normal); + VMA_ASSERT(request.item != m_Suballocations.end()); + VmaSuballocation& suballoc = *request.item; + // Given suballocation is a free block. + VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); + + // Given offset is inside this suballocation. + VMA_ASSERT((VkDeviceSize)request.allocHandle - 1 >= suballoc.offset); + const VkDeviceSize paddingBegin = (VkDeviceSize)request.allocHandle - suballoc.offset - 1; + VMA_ASSERT(suballoc.size >= paddingBegin + request.size); + const VkDeviceSize paddingEnd = suballoc.size - paddingBegin - request.size; + + // Unregister this free suballocation from m_FreeSuballocationsBySize and update + // it to become used. + UnregisterFreeSuballocation(request.item); + + suballoc.offset = (VkDeviceSize)request.allocHandle - 1; + suballoc.size = request.size; + suballoc.type = type; + suballoc.userData = userData; + + // If there are any free bytes remaining at the end, insert new free suballocation after current one. + if (paddingEnd) + { + VmaSuballocation paddingSuballoc = {}; + paddingSuballoc.offset = suballoc.offset + suballoc.size; + paddingSuballoc.size = paddingEnd; + paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + VmaSuballocationList::iterator next = request.item; + ++next; + const VmaSuballocationList::iterator paddingEndItem = + m_Suballocations.insert(next, paddingSuballoc); + RegisterFreeSuballocation(paddingEndItem); + } + + // If there are any free bytes remaining at the beginning, insert new free suballocation before current one. + if (paddingBegin) + { + VmaSuballocation paddingSuballoc = {}; + paddingSuballoc.offset = suballoc.offset - paddingBegin; + paddingSuballoc.size = paddingBegin; + paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + const VmaSuballocationList::iterator paddingBeginItem = + m_Suballocations.insert(request.item, paddingSuballoc); + RegisterFreeSuballocation(paddingBeginItem); + } + + // Update totals. + m_FreeCount = m_FreeCount - 1; + if (paddingBegin > 0) + { + ++m_FreeCount; + } + if (paddingEnd > 0) + { + ++m_FreeCount; + } + m_SumFreeSize -= request.size; +} + +void VmaBlockMetadata_Generic::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) +{ + outInfo.offset = (VkDeviceSize)allocHandle - 1; + const VmaSuballocation& suballoc = *FindAtOffset(outInfo.offset); + outInfo.size = suballoc.size; + outInfo.pUserData = suballoc.userData; +} + +void* VmaBlockMetadata_Generic::GetAllocationUserData(VmaAllocHandle allocHandle) const +{ + return FindAtOffset((VkDeviceSize)allocHandle - 1)->userData; +} + +VmaAllocHandle VmaBlockMetadata_Generic::GetAllocationListBegin() const +{ + if (IsEmpty()) + return VK_NULL_HANDLE; + + for (const auto& suballoc : m_Suballocations) + { + if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) + return (VmaAllocHandle)(suballoc.offset + 1); + } + VMA_ASSERT(false && "Should contain at least 1 allocation!"); + return VK_NULL_HANDLE; +} + +VmaAllocHandle VmaBlockMetadata_Generic::GetNextAllocation(VmaAllocHandle prevAlloc) const +{ + VmaSuballocationList::const_iterator prev = FindAtOffset((VkDeviceSize)prevAlloc - 1); + + for (VmaSuballocationList::const_iterator it = ++prev; it != m_Suballocations.end(); ++it) + { + if (it->type != VMA_SUBALLOCATION_TYPE_FREE) + return (VmaAllocHandle)(it->offset + 1); + } + return VK_NULL_HANDLE; +} + +void VmaBlockMetadata_Generic::Clear() +{ + const VkDeviceSize size = GetSize(); + + VMA_ASSERT(IsVirtual()); + m_FreeCount = 1; + m_SumFreeSize = size; + m_Suballocations.clear(); + m_FreeSuballocationsBySize.clear(); + + VmaSuballocation suballoc = {}; + suballoc.offset = 0; + suballoc.size = size; + suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + m_Suballocations.push_back(suballoc); + + m_FreeSuballocationsBySize.push_back(m_Suballocations.begin()); +} + +void VmaBlockMetadata_Generic::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) +{ + VmaSuballocation& suballoc = *FindAtOffset((VkDeviceSize)allocHandle - 1); + suballoc.userData = userData; +} + +void VmaBlockMetadata_Generic::DebugLogAllAllocations() const +{ + for (const auto& suballoc : m_Suballocations) + { + if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) + DebugLogAllocation(suballoc.offset, suballoc.size, suballoc.userData); + } +} + +VmaSuballocationList::iterator VmaBlockMetadata_Generic::FindAtOffset(VkDeviceSize offset) const +{ + VMA_HEAVY_ASSERT(!m_Suballocations.empty()); + const VkDeviceSize last = m_Suballocations.rbegin()->offset; + if (last == offset) + return m_Suballocations.rbegin().drop_const(); + const VkDeviceSize first = m_Suballocations.begin()->offset; + if (first == offset) + return m_Suballocations.begin().drop_const(); + + const size_t suballocCount = m_Suballocations.size(); + const VkDeviceSize step = (last - first + m_Suballocations.begin()->size) / suballocCount; + auto findSuballocation = [&](auto begin, auto end) -> VmaSuballocationList::iterator + { + for (auto suballocItem = begin; + suballocItem != end; + ++suballocItem) + { + if (suballocItem->offset == offset) + return suballocItem.drop_const(); + } + VMA_ASSERT(false && "Not found!"); + return m_Suballocations.end().drop_const(); + }; + // If requested offset is closer to the end of range, search from the end + if (offset - first > suballocCount * step / 2) + { + return findSuballocation(m_Suballocations.rbegin(), m_Suballocations.rend()); + } + return findSuballocation(m_Suballocations.begin(), m_Suballocations.end()); +} + +bool VmaBlockMetadata_Generic::ValidateFreeSuballocationList() const +{ + VkDeviceSize lastSize = 0; + for (size_t i = 0, count = m_FreeSuballocationsBySize.size(); i < count; ++i) + { + const VmaSuballocationList::iterator it = m_FreeSuballocationsBySize[i]; + + VMA_VALIDATE(it->type == VMA_SUBALLOCATION_TYPE_FREE); + VMA_VALIDATE(it->size >= lastSize); + lastSize = it->size; + } + return true; +} + +bool VmaBlockMetadata_Generic::CheckAllocation( + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + VmaSuballocationType allocType, + VmaSuballocationList::const_iterator suballocItem, + VmaAllocHandle* pAllocHandle) const +{ + VMA_ASSERT(allocSize > 0); + VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE); + VMA_ASSERT(suballocItem != m_Suballocations.cend()); + VMA_ASSERT(pAllocHandle != VMA_NULL); + + const VkDeviceSize debugMargin = GetDebugMargin(); + const VkDeviceSize bufferImageGranularity = GetBufferImageGranularity(); + + const VmaSuballocation& suballoc = *suballocItem; + VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); + + // Size of this suballocation is too small for this request: Early return. + if (suballoc.size < allocSize) + { + return false; + } + + // Start from offset equal to beginning of this suballocation. + VkDeviceSize offset = suballoc.offset + (suballocItem == m_Suballocations.cbegin() ? 0 : GetDebugMargin()); + + // Apply debugMargin from the end of previous alloc. + if (debugMargin > 0) + { + offset += debugMargin; + } + + // Apply alignment. + offset = VmaAlignUp(offset, allocAlignment); + + // Check previous suballocations for BufferImageGranularity conflicts. + // Make bigger alignment if necessary. + if (bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment) + { + bool bufferImageGranularityConflict = false; + VmaSuballocationList::const_iterator prevSuballocItem = suballocItem; + while (prevSuballocItem != m_Suballocations.cbegin()) + { + --prevSuballocItem; + const VmaSuballocation& prevSuballoc = *prevSuballocItem; + if (VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, offset, bufferImageGranularity)) + { + if (VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType)) + { + bufferImageGranularityConflict = true; + break; + } + } + else + // Already on previous page. + break; + } + if (bufferImageGranularityConflict) + { + offset = VmaAlignUp(offset, bufferImageGranularity); + } + } + + // Calculate padding at the beginning based on current offset. + const VkDeviceSize paddingBegin = offset - suballoc.offset; + + // Fail if requested size plus margin after is bigger than size of this suballocation. + if (paddingBegin + allocSize + debugMargin > suballoc.size) + { + return false; + } + + // Check next suballocations for BufferImageGranularity conflicts. + // If conflict exists, allocation cannot be made here. + if (allocSize % bufferImageGranularity || offset % bufferImageGranularity) + { + VmaSuballocationList::const_iterator nextSuballocItem = suballocItem; + ++nextSuballocItem; + while (nextSuballocItem != m_Suballocations.cend()) + { + const VmaSuballocation& nextSuballoc = *nextSuballocItem; + if (VmaBlocksOnSamePage(offset, allocSize, nextSuballoc.offset, bufferImageGranularity)) + { + if (VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type)) + { + return false; + } + } + else + { + // Already on next page. + break; + } + ++nextSuballocItem; + } + } + + *pAllocHandle = (VmaAllocHandle)(offset + 1); + // All tests passed: Success. pAllocHandle is already filled. + return true; +} + +void VmaBlockMetadata_Generic::MergeFreeWithNext(VmaSuballocationList::iterator item) +{ + VMA_ASSERT(item != m_Suballocations.end()); + VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE); + + VmaSuballocationList::iterator nextItem = item; + ++nextItem; + VMA_ASSERT(nextItem != m_Suballocations.end()); + VMA_ASSERT(nextItem->type == VMA_SUBALLOCATION_TYPE_FREE); + + item->size += nextItem->size; + --m_FreeCount; + m_Suballocations.erase(nextItem); +} + +VmaSuballocationList::iterator VmaBlockMetadata_Generic::FreeSuballocation(VmaSuballocationList::iterator suballocItem) +{ + // Change this suballocation to be marked as free. + VmaSuballocation& suballoc = *suballocItem; + suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + suballoc.userData = VMA_NULL; + + // Update totals. + ++m_FreeCount; + m_SumFreeSize += suballoc.size; + + // Merge with previous and/or next suballocation if it's also free. + bool mergeWithNext = false; + bool mergeWithPrev = false; + + VmaSuballocationList::iterator nextItem = suballocItem; + ++nextItem; + if ((nextItem != m_Suballocations.end()) && (nextItem->type == VMA_SUBALLOCATION_TYPE_FREE)) + { + mergeWithNext = true; + } + + VmaSuballocationList::iterator prevItem = suballocItem; + if (suballocItem != m_Suballocations.begin()) + { + --prevItem; + if (prevItem->type == VMA_SUBALLOCATION_TYPE_FREE) + { + mergeWithPrev = true; + } + } + + if (mergeWithNext) + { + UnregisterFreeSuballocation(nextItem); + MergeFreeWithNext(suballocItem); + } + + if (mergeWithPrev) + { + UnregisterFreeSuballocation(prevItem); + MergeFreeWithNext(prevItem); + RegisterFreeSuballocation(prevItem); + return prevItem; + } + else + { + RegisterFreeSuballocation(suballocItem); + return suballocItem; + } +} + +void VmaBlockMetadata_Generic::RegisterFreeSuballocation(VmaSuballocationList::iterator item) +{ + VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE); + VMA_ASSERT(item->size > 0); + + // You may want to enable this validation at the beginning or at the end of + // this function, depending on what do you want to check. + VMA_HEAVY_ASSERT(ValidateFreeSuballocationList()); + + if (m_FreeSuballocationsBySize.empty()) + { + m_FreeSuballocationsBySize.push_back(item); + } + else + { + VmaVectorInsertSorted(m_FreeSuballocationsBySize, item); + } + + //VMA_HEAVY_ASSERT(ValidateFreeSuballocationList()); +} + +void VmaBlockMetadata_Generic::UnregisterFreeSuballocation(VmaSuballocationList::iterator item) +{ + VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE); + VMA_ASSERT(item->size > 0); + + // You may want to enable this validation at the beginning or at the end of + // this function, depending on what do you want to check. + VMA_HEAVY_ASSERT(ValidateFreeSuballocationList()); + + VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess( + m_FreeSuballocationsBySize.data(), + m_FreeSuballocationsBySize.data() + m_FreeSuballocationsBySize.size(), + item, + VmaSuballocationItemSizeLess()); + for (size_t index = it - m_FreeSuballocationsBySize.data(); + index < m_FreeSuballocationsBySize.size(); + ++index) + { + if (m_FreeSuballocationsBySize[index] == item) + { + VmaVectorRemove(m_FreeSuballocationsBySize, index); + return; + } + VMA_ASSERT((m_FreeSuballocationsBySize[index]->size == item->size) && "Not found."); + } + VMA_ASSERT(0 && "Not found."); + + //VMA_HEAVY_ASSERT(ValidateFreeSuballocationList()); +} +#endif // _VMA_BLOCK_METADATA_GENERIC_FUNCTIONS +#endif // _VMA_BLOCK_METADATA_GENERIC +#endif // #if 0 + +#ifndef _VMA_BLOCK_METADATA_LINEAR /* Allocations and their references in internal data structure look like this: @@ -5124,52 +7571,50 @@ class VmaBlockMetadata_Linear : public VmaBlockMetadata { VMA_CLASS_NO_COPY(VmaBlockMetadata_Linear) public: - VmaBlockMetadata_Linear(VmaAllocator hAllocator); - virtual ~VmaBlockMetadata_Linear(); - virtual void Init(VkDeviceSize size); + VmaBlockMetadata_Linear(const VkAllocationCallbacks* pAllocationCallbacks, + VkDeviceSize bufferImageGranularity, bool isVirtual); + virtual ~VmaBlockMetadata_Linear() = default; - virtual bool Validate() const; - virtual size_t GetAllocationCount() const; - virtual VkDeviceSize GetSumFreeSize() const { return m_SumFreeSize; } - virtual VkDeviceSize GetUnusedRangeSizeMax() const; - virtual bool IsEmpty() const { return GetAllocationCount() == 0; } + VkDeviceSize GetSumFreeSize() const override { return m_SumFreeSize; } + bool IsEmpty() const override { return GetAllocationCount() == 0; } + VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle - 1; }; - virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const; - virtual void AddPoolStats(VmaPoolStats& inoutStats) const; + void Init(VkDeviceSize size) override; + bool Validate() const override; + size_t GetAllocationCount() const override; + size_t GetFreeRegionsCount() const override; + + void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const override; + void AddStatistics(VmaStatistics& inoutStats) const override; #if VMA_STATS_STRING_ENABLED - virtual void PrintDetailedMap(class VmaJsonWriter& json) const; + void PrintDetailedMap(class VmaJsonWriter& json) const override; #endif - virtual bool CreateAllocationRequest( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, + bool CreateAllocationRequest( VkDeviceSize allocSize, VkDeviceSize allocAlignment, bool upperAddress, VmaSuballocationType allocType, - bool canMakeOtherLost, uint32_t strategy, - VmaAllocationRequest* pAllocationRequest); + VmaAllocationRequest* pAllocationRequest) override; - virtual bool MakeRequestedAllocationsLost( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VmaAllocationRequest* pAllocationRequest); + VkResult CheckCorruption(const void* pBlockData) override; - virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount); - - virtual VkResult CheckCorruption(const void* pBlockData); - - virtual void Alloc( + void Alloc( const VmaAllocationRequest& request, VmaSuballocationType type, - VkDeviceSize allocSize, - VmaAllocation hAllocation); + void* userData) override; - virtual void Free(const VmaAllocation allocation); - virtual void FreeAtOffset(VkDeviceSize offset); + void Free(VmaAllocHandle allocHandle) override; + void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override; + void* GetAllocationUserData(VmaAllocHandle allocHandle) const override; + VmaAllocHandle GetAllocationListBegin() const override; + VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override; + VkDeviceSize GetNextFreeRegionSize(VmaAllocHandle alloc) const override; + void Clear() override; + void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override; + void DebugLogAllAllocations() const override; private: /* @@ -5179,7 +7624,7 @@ private: 2nd can be non-empty only when 1st is not empty. When 2nd is not empty, m_2ndVectorMode indicates its mode of operation. */ - typedef VmaVector< VmaSuballocation, VmaStlAllocator > SuballocationVectorType; + typedef VmaVector> SuballocationVectorType; enum SECOND_VECTOR_MODE { @@ -5201,12 +7646,6 @@ private: SuballocationVectorType m_Suballocations0, m_Suballocations1; uint32_t m_1stVectorIndex; SECOND_VECTOR_MODE m_2ndVectorMode; - - SuballocationVectorType& AccessSuballocations1st() { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; } - SuballocationVectorType& AccessSuballocations2nd() { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; } - const SuballocationVectorType& AccessSuballocations1st() const { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; } - const SuballocationVectorType& AccessSuballocations2nd() const { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; } - // Number of items in 1st vector with hAllocation = null at the beginning. size_t m_1stNullItemsBeginCount; // Number of other items in 1st vector with hAllocation = null somewhere in the middle. @@ -5214,31 +7653,1567 @@ private: // Number of items in 2nd vector with hAllocation = null. size_t m_2ndNullItemsCount; + SuballocationVectorType& AccessSuballocations1st() { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; } + SuballocationVectorType& AccessSuballocations2nd() { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; } + const SuballocationVectorType& AccessSuballocations1st() const { return m_1stVectorIndex ? m_Suballocations1 : m_Suballocations0; } + const SuballocationVectorType& AccessSuballocations2nd() const { return m_1stVectorIndex ? m_Suballocations0 : m_Suballocations1; } + + VmaSuballocation& FindSuballocation(VkDeviceSize offset) const; bool ShouldCompact1st() const; void CleanupAfterFree(); bool CreateAllocationRequest_LowerAddress( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, VkDeviceSize allocSize, VkDeviceSize allocAlignment, VmaSuballocationType allocType, - bool canMakeOtherLost, uint32_t strategy, VmaAllocationRequest* pAllocationRequest); bool CreateAllocationRequest_UpperAddress( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, VkDeviceSize allocSize, VkDeviceSize allocAlignment, VmaSuballocationType allocType, - bool canMakeOtherLost, uint32_t strategy, VmaAllocationRequest* pAllocationRequest); }; +#ifndef _VMA_BLOCK_METADATA_LINEAR_FUNCTIONS +VmaBlockMetadata_Linear::VmaBlockMetadata_Linear(const VkAllocationCallbacks* pAllocationCallbacks, + VkDeviceSize bufferImageGranularity, bool isVirtual) + : VmaBlockMetadata(pAllocationCallbacks, bufferImageGranularity, isVirtual), + m_SumFreeSize(0), + m_Suballocations0(VmaStlAllocator(pAllocationCallbacks)), + m_Suballocations1(VmaStlAllocator(pAllocationCallbacks)), + m_1stVectorIndex(0), + m_2ndVectorMode(SECOND_VECTOR_EMPTY), + m_1stNullItemsBeginCount(0), + m_1stNullItemsMiddleCount(0), + m_2ndNullItemsCount(0) {} + +void VmaBlockMetadata_Linear::Init(VkDeviceSize size) +{ + VmaBlockMetadata::Init(size); + m_SumFreeSize = size; +} + +bool VmaBlockMetadata_Linear::Validate() const +{ + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + VMA_VALIDATE(suballocations2nd.empty() == (m_2ndVectorMode == SECOND_VECTOR_EMPTY)); + VMA_VALIDATE(!suballocations1st.empty() || + suballocations2nd.empty() || + m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER); + + if (!suballocations1st.empty()) + { + // Null item at the beginning should be accounted into m_1stNullItemsBeginCount. + VMA_VALIDATE(suballocations1st[m_1stNullItemsBeginCount].type != VMA_SUBALLOCATION_TYPE_FREE); + // Null item at the end should be just pop_back(). + VMA_VALIDATE(suballocations1st.back().type != VMA_SUBALLOCATION_TYPE_FREE); + } + if (!suballocations2nd.empty()) + { + // Null item at the end should be just pop_back(). + VMA_VALIDATE(suballocations2nd.back().type != VMA_SUBALLOCATION_TYPE_FREE); + } + + VMA_VALIDATE(m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount <= suballocations1st.size()); + VMA_VALIDATE(m_2ndNullItemsCount <= suballocations2nd.size()); + + VkDeviceSize sumUsedSize = 0; + const size_t suballoc1stCount = suballocations1st.size(); + const VkDeviceSize debugMargin = GetDebugMargin(); + VkDeviceSize offset = 0; + + if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + const size_t suballoc2ndCount = suballocations2nd.size(); + size_t nullItem2ndCount = 0; + for (size_t i = 0; i < suballoc2ndCount; ++i) + { + const VmaSuballocation& suballoc = suballocations2nd[i]; + const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); + + VmaAllocation const alloc = (VmaAllocation)suballoc.userData; + if (!IsVirtual()) + { + VMA_VALIDATE(currFree == (alloc == VK_NULL_HANDLE)); + } + VMA_VALIDATE(suballoc.offset >= offset); + + if (!currFree) + { + if (!IsVirtual()) + { + VMA_VALIDATE((VkDeviceSize)alloc->GetAllocHandle() == suballoc.offset + 1); + VMA_VALIDATE(alloc->GetSize() == suballoc.size); + } + sumUsedSize += suballoc.size; + } + else + { + ++nullItem2ndCount; + } + + offset = suballoc.offset + suballoc.size + debugMargin; + } + + VMA_VALIDATE(nullItem2ndCount == m_2ndNullItemsCount); + } + + for (size_t i = 0; i < m_1stNullItemsBeginCount; ++i) + { + const VmaSuballocation& suballoc = suballocations1st[i]; + VMA_VALIDATE(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE && + suballoc.userData == VMA_NULL); + } + + size_t nullItem1stCount = m_1stNullItemsBeginCount; + + for (size_t i = m_1stNullItemsBeginCount; i < suballoc1stCount; ++i) + { + const VmaSuballocation& suballoc = suballocations1st[i]; + const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); + + VmaAllocation const alloc = (VmaAllocation)suballoc.userData; + if (!IsVirtual()) + { + VMA_VALIDATE(currFree == (alloc == VK_NULL_HANDLE)); + } + VMA_VALIDATE(suballoc.offset >= offset); + VMA_VALIDATE(i >= m_1stNullItemsBeginCount || currFree); + + if (!currFree) + { + if (!IsVirtual()) + { + VMA_VALIDATE((VkDeviceSize)alloc->GetAllocHandle() == suballoc.offset + 1); + VMA_VALIDATE(alloc->GetSize() == suballoc.size); + } + sumUsedSize += suballoc.size; + } + else + { + ++nullItem1stCount; + } + + offset = suballoc.offset + suballoc.size + debugMargin; + } + VMA_VALIDATE(nullItem1stCount == m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount); + + if (m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + const size_t suballoc2ndCount = suballocations2nd.size(); + size_t nullItem2ndCount = 0; + for (size_t i = suballoc2ndCount; i--; ) + { + const VmaSuballocation& suballoc = suballocations2nd[i]; + const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); + + VmaAllocation const alloc = (VmaAllocation)suballoc.userData; + if (!IsVirtual()) + { + VMA_VALIDATE(currFree == (alloc == VK_NULL_HANDLE)); + } + VMA_VALIDATE(suballoc.offset >= offset); + + if (!currFree) + { + if (!IsVirtual()) + { + VMA_VALIDATE((VkDeviceSize)alloc->GetAllocHandle() == suballoc.offset + 1); + VMA_VALIDATE(alloc->GetSize() == suballoc.size); + } + sumUsedSize += suballoc.size; + } + else + { + ++nullItem2ndCount; + } + + offset = suballoc.offset + suballoc.size + debugMargin; + } + + VMA_VALIDATE(nullItem2ndCount == m_2ndNullItemsCount); + } + + VMA_VALIDATE(offset <= GetSize()); + VMA_VALIDATE(m_SumFreeSize == GetSize() - sumUsedSize); + + return true; +} + +size_t VmaBlockMetadata_Linear::GetAllocationCount() const +{ + return AccessSuballocations1st().size() - m_1stNullItemsBeginCount - m_1stNullItemsMiddleCount + + AccessSuballocations2nd().size() - m_2ndNullItemsCount; +} + +size_t VmaBlockMetadata_Linear::GetFreeRegionsCount() const +{ + // Function only used for defragmentation, which is disabled for this algorithm + VMA_ASSERT(0); + return SIZE_MAX; +} + +void VmaBlockMetadata_Linear::AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const +{ + const VkDeviceSize size = GetSize(); + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + const size_t suballoc1stCount = suballocations1st.size(); + const size_t suballoc2ndCount = suballocations2nd.size(); + + inoutStats.statistics.blockCount++; + inoutStats.statistics.blockBytes += size; + + VkDeviceSize lastOffset = 0; + + if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; + size_t nextAlloc2ndIndex = 0; + while (lastOffset < freeSpace2ndTo1stEnd) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while (nextAlloc2ndIndex < suballoc2ndCount && + suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL) + { + ++nextAlloc2ndIndex; + } + + // Found non-null allocation. + if (nextAlloc2ndIndex < suballoc2ndCount) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + VmaAddDetailedStatisticsAllocation(inoutStats, suballoc.size); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc2ndIndex; + } + // We are at the end. + else + { + // There is free space from lastOffset to freeSpace2ndTo1stEnd. + if (lastOffset < freeSpace2ndTo1stEnd) + { + const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset; + VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize); + } + + // End of loop. + lastOffset = freeSpace2ndTo1stEnd; + } + } + } + + size_t nextAlloc1stIndex = m_1stNullItemsBeginCount; + const VkDeviceSize freeSpace1stTo2ndEnd = + m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size; + while (lastOffset < freeSpace1stTo2ndEnd) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while (nextAlloc1stIndex < suballoc1stCount && + suballocations1st[nextAlloc1stIndex].userData == VMA_NULL) + { + ++nextAlloc1stIndex; + } + + // Found non-null allocation. + if (nextAlloc1stIndex < suballoc1stCount) + { + const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + VmaAddDetailedStatisticsAllocation(inoutStats, suballoc.size); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc1stIndex; + } + // We are at the end. + else + { + // There is free space from lastOffset to freeSpace1stTo2ndEnd. + if (lastOffset < freeSpace1stTo2ndEnd) + { + const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset; + VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize); + } + + // End of loop. + lastOffset = freeSpace1stTo2ndEnd; + } + } + + if (m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; + while (lastOffset < size) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while (nextAlloc2ndIndex != SIZE_MAX && + suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL) + { + --nextAlloc2ndIndex; + } + + // Found non-null allocation. + if (nextAlloc2ndIndex != SIZE_MAX) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + VmaAddDetailedStatisticsAllocation(inoutStats, suballoc.size); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + --nextAlloc2ndIndex; + } + // We are at the end. + else + { + // There is free space from lastOffset to size. + if (lastOffset < size) + { + const VkDeviceSize unusedRangeSize = size - lastOffset; + VmaAddDetailedStatisticsUnusedRange(inoutStats, unusedRangeSize); + } + + // End of loop. + lastOffset = size; + } + } + } +} + +void VmaBlockMetadata_Linear::AddStatistics(VmaStatistics& inoutStats) const +{ + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + const VkDeviceSize size = GetSize(); + const size_t suballoc1stCount = suballocations1st.size(); + const size_t suballoc2ndCount = suballocations2nd.size(); + + inoutStats.blockCount++; + inoutStats.blockBytes += size; + inoutStats.allocationBytes += size - m_SumFreeSize; + + VkDeviceSize lastOffset = 0; + + if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; + size_t nextAlloc2ndIndex = m_1stNullItemsBeginCount; + while (lastOffset < freeSpace2ndTo1stEnd) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while (nextAlloc2ndIndex < suballoc2ndCount && + suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL) + { + ++nextAlloc2ndIndex; + } + + // Found non-null allocation. + if (nextAlloc2ndIndex < suballoc2ndCount) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++inoutStats.allocationCount; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc2ndIndex; + } + // We are at the end. + else + { + if (lastOffset < freeSpace2ndTo1stEnd) + { + // There is free space from lastOffset to freeSpace2ndTo1stEnd. + const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset; + } + + // End of loop. + lastOffset = freeSpace2ndTo1stEnd; + } + } + } + + size_t nextAlloc1stIndex = m_1stNullItemsBeginCount; + const VkDeviceSize freeSpace1stTo2ndEnd = + m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size; + while (lastOffset < freeSpace1stTo2ndEnd) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while (nextAlloc1stIndex < suballoc1stCount && + suballocations1st[nextAlloc1stIndex].userData == VMA_NULL) + { + ++nextAlloc1stIndex; + } + + // Found non-null allocation. + if (nextAlloc1stIndex < suballoc1stCount) + { + const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++inoutStats.allocationCount; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc1stIndex; + } + // We are at the end. + else + { + if (lastOffset < freeSpace1stTo2ndEnd) + { + // There is free space from lastOffset to freeSpace1stTo2ndEnd. + const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset; + } + + // End of loop. + lastOffset = freeSpace1stTo2ndEnd; + } + } + + if (m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; + while (lastOffset < size) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while (nextAlloc2ndIndex != SIZE_MAX && + suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL) + { + --nextAlloc2ndIndex; + } + + // Found non-null allocation. + if (nextAlloc2ndIndex != SIZE_MAX) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++inoutStats.allocationCount; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + --nextAlloc2ndIndex; + } + // We are at the end. + else + { + if (lastOffset < size) + { + // There is free space from lastOffset to size. + const VkDeviceSize unusedRangeSize = size - lastOffset; + } + + // End of loop. + lastOffset = size; + } + } + } +} + +#if VMA_STATS_STRING_ENABLED +void VmaBlockMetadata_Linear::PrintDetailedMap(class VmaJsonWriter& json) const +{ + const VkDeviceSize size = GetSize(); + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + const size_t suballoc1stCount = suballocations1st.size(); + const size_t suballoc2ndCount = suballocations2nd.size(); + + // FIRST PASS + + size_t unusedRangeCount = 0; + VkDeviceSize usedBytes = 0; + + VkDeviceSize lastOffset = 0; + + size_t alloc2ndCount = 0; + if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; + size_t nextAlloc2ndIndex = 0; + while (lastOffset < freeSpace2ndTo1stEnd) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while (nextAlloc2ndIndex < suballoc2ndCount && + suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL) + { + ++nextAlloc2ndIndex; + } + + // Found non-null allocation. + if (nextAlloc2ndIndex < suballoc2ndCount) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + ++unusedRangeCount; + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++alloc2ndCount; + usedBytes += suballoc.size; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc2ndIndex; + } + // We are at the end. + else + { + if (lastOffset < freeSpace2ndTo1stEnd) + { + // There is free space from lastOffset to freeSpace2ndTo1stEnd. + ++unusedRangeCount; + } + + // End of loop. + lastOffset = freeSpace2ndTo1stEnd; + } + } + } + + size_t nextAlloc1stIndex = m_1stNullItemsBeginCount; + size_t alloc1stCount = 0; + const VkDeviceSize freeSpace1stTo2ndEnd = + m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size; + while (lastOffset < freeSpace1stTo2ndEnd) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while (nextAlloc1stIndex < suballoc1stCount && + suballocations1st[nextAlloc1stIndex].userData == VMA_NULL) + { + ++nextAlloc1stIndex; + } + + // Found non-null allocation. + if (nextAlloc1stIndex < suballoc1stCount) + { + const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + ++unusedRangeCount; + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++alloc1stCount; + usedBytes += suballoc.size; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc1stIndex; + } + // We are at the end. + else + { + if (lastOffset < size) + { + // There is free space from lastOffset to freeSpace1stTo2ndEnd. + ++unusedRangeCount; + } + + // End of loop. + lastOffset = freeSpace1stTo2ndEnd; + } + } + + if (m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; + while (lastOffset < size) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while (nextAlloc2ndIndex != SIZE_MAX && + suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL) + { + --nextAlloc2ndIndex; + } + + // Found non-null allocation. + if (nextAlloc2ndIndex != SIZE_MAX) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + ++unusedRangeCount; + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + ++alloc2ndCount; + usedBytes += suballoc.size; + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + --nextAlloc2ndIndex; + } + // We are at the end. + else + { + if (lastOffset < size) + { + // There is free space from lastOffset to size. + ++unusedRangeCount; + } + + // End of loop. + lastOffset = size; + } + } + } + + const VkDeviceSize unusedBytes = size - usedBytes; + PrintDetailedMap_Begin(json, unusedBytes, alloc1stCount + alloc2ndCount, unusedRangeCount); + + // SECOND PASS + lastOffset = 0; + + if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; + size_t nextAlloc2ndIndex = 0; + while (lastOffset < freeSpace2ndTo1stEnd) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while (nextAlloc2ndIndex < suballoc2ndCount && + suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL) + { + ++nextAlloc2ndIndex; + } + + // Found non-null allocation. + if (nextAlloc2ndIndex < suballoc2ndCount) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.size, suballoc.userData); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc2ndIndex; + } + // We are at the end. + else + { + if (lastOffset < freeSpace2ndTo1stEnd) + { + // There is free space from lastOffset to freeSpace2ndTo1stEnd. + const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // End of loop. + lastOffset = freeSpace2ndTo1stEnd; + } + } + } + + nextAlloc1stIndex = m_1stNullItemsBeginCount; + while (lastOffset < freeSpace1stTo2ndEnd) + { + // Find next non-null allocation or move nextAllocIndex to the end. + while (nextAlloc1stIndex < suballoc1stCount && + suballocations1st[nextAlloc1stIndex].userData == VMA_NULL) + { + ++nextAlloc1stIndex; + } + + // Found non-null allocation. + if (nextAlloc1stIndex < suballoc1stCount) + { + const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.size, suballoc.userData); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + ++nextAlloc1stIndex; + } + // We are at the end. + else + { + if (lastOffset < freeSpace1stTo2ndEnd) + { + // There is free space from lastOffset to freeSpace1stTo2ndEnd. + const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // End of loop. + lastOffset = freeSpace1stTo2ndEnd; + } + } + + if (m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; + while (lastOffset < size) + { + // Find next non-null allocation or move nextAlloc2ndIndex to the end. + while (nextAlloc2ndIndex != SIZE_MAX && + suballocations2nd[nextAlloc2ndIndex].userData == VMA_NULL) + { + --nextAlloc2ndIndex; + } + + // Found non-null allocation. + if (nextAlloc2ndIndex != SIZE_MAX) + { + const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; + + // 1. Process free space before this allocation. + if (lastOffset < suballoc.offset) + { + // There is free space from lastOffset to suballoc.offset. + const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // 2. Process this allocation. + // There is allocation with suballoc.offset, suballoc.size. + PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.size, suballoc.userData); + + // 3. Prepare for next iteration. + lastOffset = suballoc.offset + suballoc.size; + --nextAlloc2ndIndex; + } + // We are at the end. + else + { + if (lastOffset < size) + { + // There is free space from lastOffset to size. + const VkDeviceSize unusedRangeSize = size - lastOffset; + PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); + } + + // End of loop. + lastOffset = size; + } + } + } + + PrintDetailedMap_End(json); +} +#endif // VMA_STATS_STRING_ENABLED + +bool VmaBlockMetadata_Linear::CreateAllocationRequest( + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + bool upperAddress, + VmaSuballocationType allocType, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) +{ + VMA_ASSERT(allocSize > 0); + VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE); + VMA_ASSERT(pAllocationRequest != VMA_NULL); + VMA_HEAVY_ASSERT(Validate()); + pAllocationRequest->size = allocSize; + return upperAddress ? + CreateAllocationRequest_UpperAddress( + allocSize, allocAlignment, allocType, strategy, pAllocationRequest) : + CreateAllocationRequest_LowerAddress( + allocSize, allocAlignment, allocType, strategy, pAllocationRequest); +} + +VkResult VmaBlockMetadata_Linear::CheckCorruption(const void* pBlockData) +{ + VMA_ASSERT(!IsVirtual()); + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + for (size_t i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i < count; ++i) + { + const VmaSuballocation& suballoc = suballocations1st[i]; + if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) + { + if (!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!"); + return VK_ERROR_UNKNOWN_COPY; + } + } + } + + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + for (size_t i = 0, count = suballocations2nd.size(); i < count; ++i) + { + const VmaSuballocation& suballoc = suballocations2nd[i]; + if (suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) + { + if (!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!"); + return VK_ERROR_UNKNOWN_COPY; + } + } + } + + return VK_SUCCESS; +} + +void VmaBlockMetadata_Linear::Alloc( + const VmaAllocationRequest& request, + VmaSuballocationType type, + void* userData) +{ + const VkDeviceSize offset = (VkDeviceSize)request.allocHandle - 1; + const VmaSuballocation newSuballoc = { offset, request.size, userData, type }; + + switch (request.type) + { + case VmaAllocationRequestType::UpperAddress: + { + VMA_ASSERT(m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER && + "CRITICAL ERROR: Trying to use linear allocator as double stack while it was already used as ring buffer."); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + suballocations2nd.push_back(newSuballoc); + m_2ndVectorMode = SECOND_VECTOR_DOUBLE_STACK; + } + break; + case VmaAllocationRequestType::EndOf1st: + { + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + + VMA_ASSERT(suballocations1st.empty() || + offset >= suballocations1st.back().offset + suballocations1st.back().size); + // Check if it fits before the end of the block. + VMA_ASSERT(offset + request.size <= GetSize()); + + suballocations1st.push_back(newSuballoc); + } + break; + case VmaAllocationRequestType::EndOf2nd: + { + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + // New allocation at the end of 2-part ring buffer, so before first allocation from 1st vector. + VMA_ASSERT(!suballocations1st.empty() && + offset + request.size <= suballocations1st[m_1stNullItemsBeginCount].offset); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + switch (m_2ndVectorMode) + { + case SECOND_VECTOR_EMPTY: + // First allocation from second part ring buffer. + VMA_ASSERT(suballocations2nd.empty()); + m_2ndVectorMode = SECOND_VECTOR_RING_BUFFER; + break; + case SECOND_VECTOR_RING_BUFFER: + // 2-part ring buffer is already started. + VMA_ASSERT(!suballocations2nd.empty()); + break; + case SECOND_VECTOR_DOUBLE_STACK: + VMA_ASSERT(0 && "CRITICAL ERROR: Trying to use linear allocator as ring buffer while it was already used as double stack."); + break; + default: + VMA_ASSERT(0); + } + + suballocations2nd.push_back(newSuballoc); + } + break; + default: + VMA_ASSERT(0 && "CRITICAL INTERNAL ERROR."); + } + + m_SumFreeSize -= newSuballoc.size; +} + +void VmaBlockMetadata_Linear::Free(VmaAllocHandle allocHandle) +{ + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + VkDeviceSize offset = (VkDeviceSize)allocHandle - 1; + + if (!suballocations1st.empty()) + { + // First allocation: Mark it as next empty at the beginning. + VmaSuballocation& firstSuballoc = suballocations1st[m_1stNullItemsBeginCount]; + if (firstSuballoc.offset == offset) + { + firstSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE; + firstSuballoc.userData = VMA_NULL; + m_SumFreeSize += firstSuballoc.size; + ++m_1stNullItemsBeginCount; + CleanupAfterFree(); + return; + } + } + + // Last allocation in 2-part ring buffer or top of upper stack (same logic). + if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER || + m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + VmaSuballocation& lastSuballoc = suballocations2nd.back(); + if (lastSuballoc.offset == offset) + { + m_SumFreeSize += lastSuballoc.size; + suballocations2nd.pop_back(); + CleanupAfterFree(); + return; + } + } + // Last allocation in 1st vector. + else if (m_2ndVectorMode == SECOND_VECTOR_EMPTY) + { + VmaSuballocation& lastSuballoc = suballocations1st.back(); + if (lastSuballoc.offset == offset) + { + m_SumFreeSize += lastSuballoc.size; + suballocations1st.pop_back(); + CleanupAfterFree(); + return; + } + } + + VmaSuballocation refSuballoc; + refSuballoc.offset = offset; + // Rest of members stays uninitialized intentionally for better performance. + + // Item from the middle of 1st vector. + { + const SuballocationVectorType::iterator it = VmaBinaryFindSorted( + suballocations1st.begin() + m_1stNullItemsBeginCount, + suballocations1st.end(), + refSuballoc, + VmaSuballocationOffsetLess()); + if (it != suballocations1st.end()) + { + it->type = VMA_SUBALLOCATION_TYPE_FREE; + it->userData = VMA_NULL; + ++m_1stNullItemsMiddleCount; + m_SumFreeSize += it->size; + CleanupAfterFree(); + return; + } + } + + if (m_2ndVectorMode != SECOND_VECTOR_EMPTY) + { + // Item from the middle of 2nd vector. + const SuballocationVectorType::iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ? + VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetLess()) : + VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetGreater()); + if (it != suballocations2nd.end()) + { + it->type = VMA_SUBALLOCATION_TYPE_FREE; + it->userData = VMA_NULL; + ++m_2ndNullItemsCount; + m_SumFreeSize += it->size; + CleanupAfterFree(); + return; + } + } + + VMA_ASSERT(0 && "Allocation to free not found in linear allocator!"); +} + +void VmaBlockMetadata_Linear::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) +{ + outInfo.offset = (VkDeviceSize)allocHandle - 1; + VmaSuballocation& suballoc = FindSuballocation(outInfo.offset); + outInfo.size = suballoc.size; + outInfo.pUserData = suballoc.userData; +} + +void* VmaBlockMetadata_Linear::GetAllocationUserData(VmaAllocHandle allocHandle) const +{ + return FindSuballocation((VkDeviceSize)allocHandle - 1).userData; +} + +VmaAllocHandle VmaBlockMetadata_Linear::GetAllocationListBegin() const +{ + // Function only used for defragmentation, which is disabled for this algorithm + VMA_ASSERT(0); + return VK_NULL_HANDLE; +} + +VmaAllocHandle VmaBlockMetadata_Linear::GetNextAllocation(VmaAllocHandle prevAlloc) const +{ + // Function only used for defragmentation, which is disabled for this algorithm + VMA_ASSERT(0); + return VK_NULL_HANDLE; +} + +VkDeviceSize VmaBlockMetadata_Linear::GetNextFreeRegionSize(VmaAllocHandle alloc) const +{ + // Function only used for defragmentation, which is disabled for this algorithm + VMA_ASSERT(0); + return 0; +} + +void VmaBlockMetadata_Linear::Clear() +{ + m_SumFreeSize = GetSize(); + m_Suballocations0.clear(); + m_Suballocations1.clear(); + // Leaving m_1stVectorIndex unchanged - it doesn't matter. + m_2ndVectorMode = SECOND_VECTOR_EMPTY; + m_1stNullItemsBeginCount = 0; + m_1stNullItemsMiddleCount = 0; + m_2ndNullItemsCount = 0; +} + +void VmaBlockMetadata_Linear::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) +{ + VmaSuballocation& suballoc = FindSuballocation((VkDeviceSize)allocHandle - 1); + suballoc.userData = userData; +} + +void VmaBlockMetadata_Linear::DebugLogAllAllocations() const +{ + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + for (auto it = suballocations1st.begin() + m_1stNullItemsBeginCount; it != suballocations1st.end(); ++it) + if (it->type != VMA_SUBALLOCATION_TYPE_FREE) + DebugLogAllocation(it->offset, it->size, it->userData); + + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + for (auto it = suballocations2nd.begin(); it != suballocations2nd.end(); ++it) + if (it->type != VMA_SUBALLOCATION_TYPE_FREE) + DebugLogAllocation(it->offset, it->size, it->userData); +} + +VmaSuballocation& VmaBlockMetadata_Linear::FindSuballocation(VkDeviceSize offset) const +{ + const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + VmaSuballocation refSuballoc; + refSuballoc.offset = offset; + // Rest of members stays uninitialized intentionally for better performance. + + // Item from the 1st vector. + { + SuballocationVectorType::const_iterator it = VmaBinaryFindSorted( + suballocations1st.begin() + m_1stNullItemsBeginCount, + suballocations1st.end(), + refSuballoc, + VmaSuballocationOffsetLess()); + if (it != suballocations1st.end()) + { + return const_cast(*it); + } + } + + if (m_2ndVectorMode != SECOND_VECTOR_EMPTY) + { + // Rest of members stays uninitialized intentionally for better performance. + SuballocationVectorType::const_iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ? + VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetLess()) : + VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetGreater()); + if (it != suballocations2nd.end()) + { + return const_cast(*it); + } + } + + VMA_ASSERT(0 && "Allocation not found in linear allocator!"); + return const_cast(suballocations1st.back()); // Should never occur. +} + +bool VmaBlockMetadata_Linear::ShouldCompact1st() const +{ + const size_t nullItemCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount; + const size_t suballocCount = AccessSuballocations1st().size(); + return suballocCount > 32 && nullItemCount * 2 >= (suballocCount - nullItemCount) * 3; +} + +void VmaBlockMetadata_Linear::CleanupAfterFree() +{ + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + if (IsEmpty()) + { + suballocations1st.clear(); + suballocations2nd.clear(); + m_1stNullItemsBeginCount = 0; + m_1stNullItemsMiddleCount = 0; + m_2ndNullItemsCount = 0; + m_2ndVectorMode = SECOND_VECTOR_EMPTY; + } + else + { + const size_t suballoc1stCount = suballocations1st.size(); + const size_t nullItem1stCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount; + VMA_ASSERT(nullItem1stCount <= suballoc1stCount); + + // Find more null items at the beginning of 1st vector. + while (m_1stNullItemsBeginCount < suballoc1stCount && + suballocations1st[m_1stNullItemsBeginCount].type == VMA_SUBALLOCATION_TYPE_FREE) + { + ++m_1stNullItemsBeginCount; + --m_1stNullItemsMiddleCount; + } + + // Find more null items at the end of 1st vector. + while (m_1stNullItemsMiddleCount > 0 && + suballocations1st.back().type == VMA_SUBALLOCATION_TYPE_FREE) + { + --m_1stNullItemsMiddleCount; + suballocations1st.pop_back(); + } + + // Find more null items at the end of 2nd vector. + while (m_2ndNullItemsCount > 0 && + suballocations2nd.back().type == VMA_SUBALLOCATION_TYPE_FREE) + { + --m_2ndNullItemsCount; + suballocations2nd.pop_back(); + } + + // Find more null items at the beginning of 2nd vector. + while (m_2ndNullItemsCount > 0 && + suballocations2nd[0].type == VMA_SUBALLOCATION_TYPE_FREE) + { + --m_2ndNullItemsCount; + VmaVectorRemove(suballocations2nd, 0); + } + + if (ShouldCompact1st()) + { + const size_t nonNullItemCount = suballoc1stCount - nullItem1stCount; + size_t srcIndex = m_1stNullItemsBeginCount; + for (size_t dstIndex = 0; dstIndex < nonNullItemCount; ++dstIndex) + { + while (suballocations1st[srcIndex].type == VMA_SUBALLOCATION_TYPE_FREE) + { + ++srcIndex; + } + if (dstIndex != srcIndex) + { + suballocations1st[dstIndex] = suballocations1st[srcIndex]; + } + ++srcIndex; + } + suballocations1st.resize(nonNullItemCount); + m_1stNullItemsBeginCount = 0; + m_1stNullItemsMiddleCount = 0; + } + + // 2nd vector became empty. + if (suballocations2nd.empty()) + { + m_2ndVectorMode = SECOND_VECTOR_EMPTY; + } + + // 1st vector became empty. + if (suballocations1st.size() - m_1stNullItemsBeginCount == 0) + { + suballocations1st.clear(); + m_1stNullItemsBeginCount = 0; + + if (!suballocations2nd.empty() && m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + // Swap 1st with 2nd. Now 2nd is empty. + m_2ndVectorMode = SECOND_VECTOR_EMPTY; + m_1stNullItemsMiddleCount = m_2ndNullItemsCount; + while (m_1stNullItemsBeginCount < suballocations2nd.size() && + suballocations2nd[m_1stNullItemsBeginCount].type == VMA_SUBALLOCATION_TYPE_FREE) + { + ++m_1stNullItemsBeginCount; + --m_1stNullItemsMiddleCount; + } + m_2ndNullItemsCount = 0; + m_1stVectorIndex ^= 1; + } + } + } + + VMA_HEAVY_ASSERT(Validate()); +} + +bool VmaBlockMetadata_Linear::CreateAllocationRequest_LowerAddress( + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + VmaSuballocationType allocType, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) +{ + const VkDeviceSize blockSize = GetSize(); + const VkDeviceSize debugMargin = GetDebugMargin(); + const VkDeviceSize bufferImageGranularity = GetBufferImageGranularity(); + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + if (m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + // Try to allocate at the end of 1st vector. + + VkDeviceSize resultBaseOffset = 0; + if (!suballocations1st.empty()) + { + const VmaSuballocation& lastSuballoc = suballocations1st.back(); + resultBaseOffset = lastSuballoc.offset + lastSuballoc.size + debugMargin; + } + + // Start from offset equal to beginning of free space. + VkDeviceSize resultOffset = resultBaseOffset; + + // Apply alignment. + resultOffset = VmaAlignUp(resultOffset, allocAlignment); + + // Check previous suballocations for BufferImageGranularity conflicts. + // Make bigger alignment if necessary. + if (bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations1st.empty()) + { + bool bufferImageGranularityConflict = false; + for (size_t prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; ) + { + const VmaSuballocation& prevSuballoc = suballocations1st[prevSuballocIndex]; + if (VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity)) + { + if (VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType)) + { + bufferImageGranularityConflict = true; + break; + } + } + else + // Already on previous page. + break; + } + if (bufferImageGranularityConflict) + { + resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity); + } + } + + const VkDeviceSize freeSpaceEnd = m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? + suballocations2nd.back().offset : blockSize; + + // There is enough free space at the end after alignment. + if (resultOffset + allocSize + debugMargin <= freeSpaceEnd) + { + // Check next suballocations for BufferImageGranularity conflicts. + // If conflict exists, allocation cannot be made here. + if ((allocSize % bufferImageGranularity || resultOffset % bufferImageGranularity) && m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) + { + for (size_t nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; ) + { + const VmaSuballocation& nextSuballoc = suballocations2nd[nextSuballocIndex]; + if (VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) + { + if (VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type)) + { + return false; + } + } + else + { + // Already on previous page. + break; + } + } + } + + // All tests passed: Success. + pAllocationRequest->allocHandle = (VmaAllocHandle)(resultOffset + 1); + // pAllocationRequest->item, customData unused. + pAllocationRequest->type = VmaAllocationRequestType::EndOf1st; + return true; + } + } + + // Wrap-around to end of 2nd vector. Try to allocate there, watching for the + // beginning of 1st vector as the end of free space. + if (m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + VMA_ASSERT(!suballocations1st.empty()); + + VkDeviceSize resultBaseOffset = 0; + if (!suballocations2nd.empty()) + { + const VmaSuballocation& lastSuballoc = suballocations2nd.back(); + resultBaseOffset = lastSuballoc.offset + lastSuballoc.size + debugMargin; + } + + // Start from offset equal to beginning of free space. + VkDeviceSize resultOffset = resultBaseOffset; + + // Apply alignment. + resultOffset = VmaAlignUp(resultOffset, allocAlignment); + + // Check previous suballocations for BufferImageGranularity conflicts. + // Make bigger alignment if necessary. + if (bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations2nd.empty()) + { + bool bufferImageGranularityConflict = false; + for (size_t prevSuballocIndex = suballocations2nd.size(); prevSuballocIndex--; ) + { + const VmaSuballocation& prevSuballoc = suballocations2nd[prevSuballocIndex]; + if (VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity)) + { + if (VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType)) + { + bufferImageGranularityConflict = true; + break; + } + } + else + // Already on previous page. + break; + } + if (bufferImageGranularityConflict) + { + resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity); + } + } + + size_t index1st = m_1stNullItemsBeginCount; + + // There is enough free space at the end after alignment. + if ((index1st == suballocations1st.size() && resultOffset + allocSize + debugMargin <= blockSize) || + (index1st < suballocations1st.size() && resultOffset + allocSize + debugMargin <= suballocations1st[index1st].offset)) + { + // Check next suballocations for BufferImageGranularity conflicts. + // If conflict exists, allocation cannot be made here. + if (allocSize % bufferImageGranularity || resultOffset % bufferImageGranularity) + { + for (size_t nextSuballocIndex = index1st; + nextSuballocIndex < suballocations1st.size(); + nextSuballocIndex++) + { + const VmaSuballocation& nextSuballoc = suballocations1st[nextSuballocIndex]; + if (VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) + { + if (VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type)) + { + return false; + } + } + else + { + // Already on next page. + break; + } + } + } + + // All tests passed: Success. + pAllocationRequest->allocHandle = (VmaAllocHandle)(resultOffset + 1); + pAllocationRequest->type = VmaAllocationRequestType::EndOf2nd; + // pAllocationRequest->item, customData unused. + return true; + } + } + + return false; +} + +bool VmaBlockMetadata_Linear::CreateAllocationRequest_UpperAddress( + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + VmaSuballocationType allocType, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) +{ + const VkDeviceSize blockSize = GetSize(); + const VkDeviceSize bufferImageGranularity = GetBufferImageGranularity(); + SuballocationVectorType& suballocations1st = AccessSuballocations1st(); + SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); + + if (m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) + { + VMA_ASSERT(0 && "Trying to use pool with linear algorithm as double stack, while it is already being used as ring buffer."); + return false; + } + + // Try to allocate before 2nd.back(), or end of block if 2nd.empty(). + if (allocSize > blockSize) + { + return false; + } + VkDeviceSize resultBaseOffset = blockSize - allocSize; + if (!suballocations2nd.empty()) + { + const VmaSuballocation& lastSuballoc = suballocations2nd.back(); + resultBaseOffset = lastSuballoc.offset - allocSize; + if (allocSize > lastSuballoc.offset) + { + return false; + } + } + + // Start from offset equal to end of free space. + VkDeviceSize resultOffset = resultBaseOffset; + + const VkDeviceSize debugMargin = GetDebugMargin(); + + // Apply debugMargin at the end. + if (debugMargin > 0) + { + if (resultOffset < debugMargin) + { + return false; + } + resultOffset -= debugMargin; + } + + // Apply alignment. + resultOffset = VmaAlignDown(resultOffset, allocAlignment); + + // Check next suballocations from 2nd for BufferImageGranularity conflicts. + // Make bigger alignment if necessary. + if (bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations2nd.empty()) + { + bool bufferImageGranularityConflict = false; + for (size_t nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; ) + { + const VmaSuballocation& nextSuballoc = suballocations2nd[nextSuballocIndex]; + if (VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) + { + if (VmaIsBufferImageGranularityConflict(nextSuballoc.type, allocType)) + { + bufferImageGranularityConflict = true; + break; + } + } + else + // Already on previous page. + break; + } + if (bufferImageGranularityConflict) + { + resultOffset = VmaAlignDown(resultOffset, bufferImageGranularity); + } + } + + // There is enough free space. + const VkDeviceSize endOf1st = !suballocations1st.empty() ? + suballocations1st.back().offset + suballocations1st.back().size : + 0; + if (endOf1st + debugMargin <= resultOffset) + { + // Check previous suballocations for BufferImageGranularity conflicts. + // If conflict exists, allocation cannot be made here. + if (bufferImageGranularity > 1) + { + for (size_t prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; ) + { + const VmaSuballocation& prevSuballoc = suballocations1st[prevSuballocIndex]; + if (VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity)) + { + if (VmaIsBufferImageGranularityConflict(allocType, prevSuballoc.type)) + { + return false; + } + } + else + { + // Already on next page. + break; + } + } + } + + // All tests passed: Success. + pAllocationRequest->allocHandle = (VmaAllocHandle)(resultOffset + 1); + // pAllocationRequest->item unused. + pAllocationRequest->type = VmaAllocationRequestType::UpperAddress; + return true; + } + + return false; +} +#endif // _VMA_BLOCK_METADATA_LINEAR_FUNCTIONS +#endif // _VMA_BLOCK_METADATA_LINEAR + +#if 0 +#ifndef _VMA_BLOCK_METADATA_BUDDY /* - GetSize() is the original size of allocated memory block. - m_UsableSize is this size aligned down to a power of two. @@ -5254,69 +9229,57 @@ class VmaBlockMetadata_Buddy : public VmaBlockMetadata { VMA_CLASS_NO_COPY(VmaBlockMetadata_Buddy) public: - VmaBlockMetadata_Buddy(VmaAllocator hAllocator); + VmaBlockMetadata_Buddy(const VkAllocationCallbacks* pAllocationCallbacks, + VkDeviceSize bufferImageGranularity, bool isVirtual); virtual ~VmaBlockMetadata_Buddy(); - virtual void Init(VkDeviceSize size); - virtual bool Validate() const; - virtual size_t GetAllocationCount() const { return m_AllocationCount; } - virtual VkDeviceSize GetSumFreeSize() const { return m_SumFreeSize + GetUnusableSize(); } - virtual VkDeviceSize GetUnusedRangeSizeMax() const; - virtual bool IsEmpty() const { return m_Root->type == Node::TYPE_FREE; } + size_t GetAllocationCount() const override { return m_AllocationCount; } + VkDeviceSize GetSumFreeSize() const override { return m_SumFreeSize + GetUnusableSize(); } + bool IsEmpty() const override { return m_Root->type == Node::TYPE_FREE; } + VkResult CheckCorruption(const void* pBlockData) override { return VK_ERROR_FEATURE_NOT_PRESENT; } + VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return (VkDeviceSize)allocHandle - 1; }; + void DebugLogAllAllocations() const override { DebugLogAllAllocationNode(m_Root, 0); } - virtual void CalcAllocationStatInfo(VmaStatInfo& outInfo) const; - virtual void AddPoolStats(VmaPoolStats& inoutStats) const; + void Init(VkDeviceSize size) override; + bool Validate() const override; + + void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const override; + void AddStatistics(VmaStatistics& inoutStats) const override; #if VMA_STATS_STRING_ENABLED - virtual void PrintDetailedMap(class VmaJsonWriter& json) const; + void PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const override; #endif - virtual bool CreateAllocationRequest( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, + bool CreateAllocationRequest( VkDeviceSize allocSize, VkDeviceSize allocAlignment, bool upperAddress, VmaSuballocationType allocType, - bool canMakeOtherLost, uint32_t strategy, - VmaAllocationRequest* pAllocationRequest); + VmaAllocationRequest* pAllocationRequest) override; - virtual bool MakeRequestedAllocationsLost( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VmaAllocationRequest* pAllocationRequest); - - virtual uint32_t MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount); - - virtual VkResult CheckCorruption(const void* pBlockData) { return VK_ERROR_FEATURE_NOT_PRESENT; } - - virtual void Alloc( + void Alloc( const VmaAllocationRequest& request, VmaSuballocationType type, - VkDeviceSize allocSize, - VmaAllocation hAllocation); + void* userData) override; - virtual void Free(const VmaAllocation allocation) { FreeAtOffset(allocation, allocation->GetOffset()); } - virtual void FreeAtOffset(VkDeviceSize offset) { FreeAtOffset(VMA_NULL, offset); } + void Free(VmaAllocHandle allocHandle) override; + void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override; + void* GetAllocationUserData(VmaAllocHandle allocHandle) const override; + VmaAllocHandle GetAllocationListBegin() const override; + VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override; + void Clear() override; + void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override; private: - static const VkDeviceSize MIN_NODE_SIZE = 32; - static const size_t MAX_LEVELS = 30; + static const size_t MAX_LEVELS = 48; struct ValidationContext { - size_t calculatedAllocationCount; - size_t calculatedFreeCount; - VkDeviceSize calculatedSumFreeSize; - - ValidationContext() : - calculatedAllocationCount(0), - calculatedFreeCount(0), - calculatedSumFreeSize(0) { } + size_t calculatedAllocationCount = 0; + size_t calculatedFreeCount = 0; + VkDeviceSize calculatedSumFreeSize = 0; }; - struct Node { VkDeviceSize offset; @@ -5339,7 +9302,7 @@ private: } free; struct { - VmaAllocation alloc; + void* userData; } allocation; struct { @@ -5351,27 +9314,38 @@ private: // Size of the memory block aligned down to a power of two. VkDeviceSize m_UsableSize; uint32_t m_LevelCount; - + VmaPoolAllocator m_NodeAllocator; Node* m_Root; - struct { + struct + { Node* front; Node* back; } m_FreeList[MAX_LEVELS]; + // Number of nodes in the tree with type == TYPE_ALLOCATION. size_t m_AllocationCount; // Number of nodes in the tree with type == TYPE_FREE. size_t m_FreeCount; - // This includes space wasted due to internal fragmentation. Doesn't include unusable size. + // Doesn't include space wasted due to internal fragmentation - allocation sizes are just aligned up to node sizes. + // Doesn't include unusable size. VkDeviceSize m_SumFreeSize; VkDeviceSize GetUnusableSize() const { return GetSize() - m_UsableSize; } - void DeleteNode(Node* node); + VkDeviceSize LevelToNodeSize(uint32_t level) const { return m_UsableSize >> level; } + + VkDeviceSize AlignAllocationSize(VkDeviceSize size) const + { + if (!IsVirtual()) + { + size = VmaAlignUp(size, (VkDeviceSize)16); + } + return VmaNextPow2(size); + } + Node* FindAllocationNode(VkDeviceSize offset, uint32_t& outLevel) const; + void DeleteNodeChildren(Node* node); bool ValidateNode(ValidationContext& ctx, const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const; uint32_t AllocSizeToLevel(VkDeviceSize allocSize) const; - inline VkDeviceSize LevelToNodeSize(uint32_t level) const { return m_UsableSize >> level; } - // Alloc passed just for validation. Can be null. - void FreeAtOffset(VmaAllocation alloc, VkDeviceSize offset); - void CalcAllocationStatInfoNode(VmaStatInfo& outInfo, const Node* node, VkDeviceSize levelNodeSize) const; + void AddNodeToDetailedStatistics(VmaDetailedStatistics& inoutStats, const Node* node, VkDeviceSize levelNodeSize) const; // Adds node to the front of FreeList at given level. // node->type must be FREE. // node->free.prev, next can be undefined. @@ -5380,113 +9354,1517 @@ private: // node->type must be FREE. // node->free.prev, next stay untouched. void RemoveFromFreeList(uint32_t level, Node* node); + void DebugLogAllAllocationNode(Node* node, uint32_t level) const; #if VMA_STATS_STRING_ENABLED void PrintDetailedMapNode(class VmaJsonWriter& json, const Node* node, VkDeviceSize levelNodeSize) const; #endif }; -/* -Represents a single block of device memory (`VkDeviceMemory`) with all the -data about its regions (aka suballocations, #VmaAllocation), assigned and free. - -Thread-safety: This class must be externally synchronized. -*/ -class VmaDeviceMemoryBlock +#ifndef _VMA_BLOCK_METADATA_BUDDY_FUNCTIONS +VmaBlockMetadata_Buddy::VmaBlockMetadata_Buddy(const VkAllocationCallbacks* pAllocationCallbacks, + VkDeviceSize bufferImageGranularity, bool isVirtual) + : VmaBlockMetadata(pAllocationCallbacks, bufferImageGranularity, isVirtual), + m_NodeAllocator(pAllocationCallbacks, 32), // firstBlockCapacity + m_Root(VMA_NULL), + m_AllocationCount(0), + m_FreeCount(1), + m_SumFreeSize(0) { - VMA_CLASS_NO_COPY(VmaDeviceMemoryBlock) -public: - VmaBlockMetadata* m_pMetadata; + memset(m_FreeList, 0, sizeof(m_FreeList)); +} - VmaDeviceMemoryBlock(VmaAllocator hAllocator); +VmaBlockMetadata_Buddy::~VmaBlockMetadata_Buddy() +{ + DeleteNodeChildren(m_Root); + m_NodeAllocator.Free(m_Root); +} - ~VmaDeviceMemoryBlock() +void VmaBlockMetadata_Buddy::Init(VkDeviceSize size) +{ + VmaBlockMetadata::Init(size); + + m_UsableSize = VmaPrevPow2(size); + m_SumFreeSize = m_UsableSize; + + // Calculate m_LevelCount. + const VkDeviceSize minNodeSize = IsVirtual() ? 1 : 16; + m_LevelCount = 1; + while (m_LevelCount < MAX_LEVELS && + LevelToNodeSize(m_LevelCount) >= minNodeSize) { - VMA_ASSERT(m_MapCount == 0 && "VkDeviceMemory block is being destroyed while it is still mapped."); - VMA_ASSERT(m_hMemory == VK_NULL_HANDLE); + ++m_LevelCount; } - // Always call after construction. - void Init( - VmaAllocator hAllocator, - VmaPool hParentPool, - uint32_t newMemoryTypeIndex, - VkDeviceMemory newMemory, - VkDeviceSize newSize, - uint32_t id, - uint32_t algorithm); - // Always call before destruction. - void Destroy(VmaAllocator allocator); + Node* rootNode = m_NodeAllocator.Alloc(); + rootNode->offset = 0; + rootNode->type = Node::TYPE_FREE; + rootNode->parent = VMA_NULL; + rootNode->buddy = VMA_NULL; - VmaPool GetParentPool() const { return m_hParentPool; } - VkDeviceMemory GetDeviceMemory() const { return m_hMemory; } - uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; } - uint32_t GetId() const { return m_Id; } - void* GetMappedData() const { return m_pMappedData; } + m_Root = rootNode; + AddToFreeListFront(0, rootNode); +} - // Validates all data structures inside this object. If not valid, returns false. - bool Validate() const; +bool VmaBlockMetadata_Buddy::Validate() const +{ + // Validate tree. + ValidationContext ctx; + if (!ValidateNode(ctx, VMA_NULL, m_Root, 0, LevelToNodeSize(0))) + { + VMA_VALIDATE(false && "ValidateNode failed."); + } + VMA_VALIDATE(m_AllocationCount == ctx.calculatedAllocationCount); + VMA_VALIDATE(m_SumFreeSize == ctx.calculatedSumFreeSize); - VkResult CheckCorruption(VmaAllocator hAllocator); + // Validate free node lists. + for (uint32_t level = 0; level < m_LevelCount; ++level) + { + VMA_VALIDATE(m_FreeList[level].front == VMA_NULL || + m_FreeList[level].front->free.prev == VMA_NULL); - // ppData can be null. - VkResult Map(VmaAllocator hAllocator, uint32_t count, void** ppData); - void Unmap(VmaAllocator hAllocator, uint32_t count); + for (Node* node = m_FreeList[level].front; + node != VMA_NULL; + node = node->free.next) + { + VMA_VALIDATE(node->type == Node::TYPE_FREE); - VkResult WriteMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize); - VkResult ValidateMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize); + if (node->free.next == VMA_NULL) + { + VMA_VALIDATE(m_FreeList[level].back == node); + } + else + { + VMA_VALIDATE(node->free.next->free.prev == node); + } + } + } - VkResult BindBufferMemory( - const VmaAllocator hAllocator, - const VmaAllocation hAllocation, - VkDeviceSize allocationLocalOffset, - VkBuffer hBuffer, - const void* pNext); - VkResult BindImageMemory( - const VmaAllocator hAllocator, - const VmaAllocation hAllocation, - VkDeviceSize allocationLocalOffset, - VkImage hImage, - const void* pNext); + // Validate that free lists ar higher levels are empty. + for (uint32_t level = m_LevelCount; level < MAX_LEVELS; ++level) + { + VMA_VALIDATE(m_FreeList[level].front == VMA_NULL && m_FreeList[level].back == VMA_NULL); + } + + return true; +} + +void VmaBlockMetadata_Buddy::AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const +{ + inoutStats.statistics.blockCount++; + inoutStats.statistics.blockBytes += GetSize(); + + AddNodeToDetailedStatistics(inoutStats, m_Root, LevelToNodeSize(0)); + + const VkDeviceSize unusableSize = GetUnusableSize(); + if (unusableSize > 0) + VmaAddDetailedStatisticsUnusedRange(inoutStats, unusableSize); +} + +void VmaBlockMetadata_Buddy::AddStatistics(VmaStatistics& inoutStats) const +{ + inoutStats.blockCount++; + inoutStats.allocationCount += (uint32_t)m_AllocationCount; + inoutStats.blockBytes += GetSize(); + inoutStats.allocationBytes += GetSize() - m_SumFreeSize; +} + +#if VMA_STATS_STRING_ENABLED +void VmaBlockMetadata_Buddy::PrintDetailedMap(class VmaJsonWriter& json, uint32_t mapRefCount) const +{ + VmaDetailedStatistics stats; + VmaClearDetailedStatistics(stats); + AddDetailedStatistics(stats); + + PrintDetailedMap_Begin( + json, + stats.statistics.blockBytes - stats.statistics.allocationBytes, + stats.statistics.allocationCount, + stats.unusedRangeCount, + mapRefCount); + + PrintDetailedMapNode(json, m_Root, LevelToNodeSize(0)); + + const VkDeviceSize unusableSize = GetUnusableSize(); + if (unusableSize > 0) + { + PrintDetailedMap_UnusedRange(json, + m_UsableSize, // offset + unusableSize); // size + } + + PrintDetailedMap_End(json); +} +#endif // VMA_STATS_STRING_ENABLED + +bool VmaBlockMetadata_Buddy::CreateAllocationRequest( + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + bool upperAddress, + VmaSuballocationType allocType, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) +{ + VMA_ASSERT(!upperAddress && "VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT can be used only with linear algorithm."); + + allocSize = AlignAllocationSize(allocSize); + + // Simple way to respect bufferImageGranularity. May be optimized some day. + // Whenever it might be an OPTIMAL image... + if (allocType == VMA_SUBALLOCATION_TYPE_UNKNOWN || + allocType == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN || + allocType == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL) + { + allocAlignment = VMA_MAX(allocAlignment, GetBufferImageGranularity()); + allocSize = VmaAlignUp(allocSize, GetBufferImageGranularity()); + } + + if (allocSize > m_UsableSize) + { + return false; + } + + const uint32_t targetLevel = AllocSizeToLevel(allocSize); + for (uint32_t level = targetLevel; level--; ) + { + for (Node* freeNode = m_FreeList[level].front; + freeNode != VMA_NULL; + freeNode = freeNode->free.next) + { + if (freeNode->offset % allocAlignment == 0) + { + pAllocationRequest->type = VmaAllocationRequestType::Normal; + pAllocationRequest->allocHandle = (VmaAllocHandle)(freeNode->offset + 1); + pAllocationRequest->size = allocSize; + pAllocationRequest->customData = (void*)(uintptr_t)level; + return true; + } + } + } + + return false; +} + +void VmaBlockMetadata_Buddy::Alloc( + const VmaAllocationRequest& request, + VmaSuballocationType type, + void* userData) +{ + VMA_ASSERT(request.type == VmaAllocationRequestType::Normal); + + const uint32_t targetLevel = AllocSizeToLevel(request.size); + uint32_t currLevel = (uint32_t)(uintptr_t)request.customData; + + Node* currNode = m_FreeList[currLevel].front; + VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE); + const VkDeviceSize offset = (VkDeviceSize)request.allocHandle - 1; + while (currNode->offset != offset) + { + currNode = currNode->free.next; + VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE); + } + + // Go down, splitting free nodes. + while (currLevel < targetLevel) + { + // currNode is already first free node at currLevel. + // Remove it from list of free nodes at this currLevel. + RemoveFromFreeList(currLevel, currNode); + + const uint32_t childrenLevel = currLevel + 1; + + // Create two free sub-nodes. + Node* leftChild = m_NodeAllocator.Alloc(); + Node* rightChild = m_NodeAllocator.Alloc(); + + leftChild->offset = currNode->offset; + leftChild->type = Node::TYPE_FREE; + leftChild->parent = currNode; + leftChild->buddy = rightChild; + + rightChild->offset = currNode->offset + LevelToNodeSize(childrenLevel); + rightChild->type = Node::TYPE_FREE; + rightChild->parent = currNode; + rightChild->buddy = leftChild; + + // Convert current currNode to split type. + currNode->type = Node::TYPE_SPLIT; + currNode->split.leftChild = leftChild; + + // Add child nodes to free list. Order is important! + AddToFreeListFront(childrenLevel, rightChild); + AddToFreeListFront(childrenLevel, leftChild); + + ++m_FreeCount; + ++currLevel; + currNode = m_FreeList[currLevel].front; + + /* + We can be sure that currNode, as left child of node previously split, + also fulfills the alignment requirement. + */ + } + + // Remove from free list. + VMA_ASSERT(currLevel == targetLevel && + currNode != VMA_NULL && + currNode->type == Node::TYPE_FREE); + RemoveFromFreeList(currLevel, currNode); + + // Convert to allocation node. + currNode->type = Node::TYPE_ALLOCATION; + currNode->allocation.userData = userData; + + ++m_AllocationCount; + --m_FreeCount; + m_SumFreeSize -= request.size; +} + +void VmaBlockMetadata_Buddy::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) +{ + uint32_t level = 0; + outInfo.offset = (VkDeviceSize)allocHandle - 1; + const Node* const node = FindAllocationNode(outInfo.offset, level); + outInfo.size = LevelToNodeSize(level); + outInfo.pUserData = node->allocation.userData; +} + +void* VmaBlockMetadata_Buddy::GetAllocationUserData(VmaAllocHandle allocHandle) const +{ + uint32_t level = 0; + const Node* const node = FindAllocationNode((VkDeviceSize)allocHandle - 1, level); + return node->allocation.userData; +} + +VmaAllocHandle VmaBlockMetadata_Buddy::GetAllocationListBegin() const +{ + // Function only used for defragmentation, which is disabled for this algorithm + return VK_NULL_HANDLE; +} + +VmaAllocHandle VmaBlockMetadata_Buddy::GetNextAllocation(VmaAllocHandle prevAlloc) const +{ + // Function only used for defragmentation, which is disabled for this algorithm + return VK_NULL_HANDLE; +} + +void VmaBlockMetadata_Buddy::DeleteNodeChildren(Node* node) +{ + if (node->type == Node::TYPE_SPLIT) + { + DeleteNodeChildren(node->split.leftChild->buddy); + DeleteNodeChildren(node->split.leftChild); + const VkAllocationCallbacks* allocationCallbacks = GetAllocationCallbacks(); + m_NodeAllocator.Free(node->split.leftChild->buddy); + m_NodeAllocator.Free(node->split.leftChild); + } +} + +void VmaBlockMetadata_Buddy::Clear() +{ + DeleteNodeChildren(m_Root); + m_Root->type = Node::TYPE_FREE; + m_AllocationCount = 0; + m_FreeCount = 1; + m_SumFreeSize = m_UsableSize; +} + +void VmaBlockMetadata_Buddy::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) +{ + uint32_t level = 0; + Node* const node = FindAllocationNode((VkDeviceSize)allocHandle - 1, level); + node->allocation.userData = userData; +} + +VmaBlockMetadata_Buddy::Node* VmaBlockMetadata_Buddy::FindAllocationNode(VkDeviceSize offset, uint32_t& outLevel) const +{ + Node* node = m_Root; + VkDeviceSize nodeOffset = 0; + outLevel = 0; + VkDeviceSize levelNodeSize = LevelToNodeSize(0); + while (node->type == Node::TYPE_SPLIT) + { + const VkDeviceSize nextLevelNodeSize = levelNodeSize >> 1; + if (offset < nodeOffset + nextLevelNodeSize) + { + node = node->split.leftChild; + } + else + { + node = node->split.leftChild->buddy; + nodeOffset += nextLevelNodeSize; + } + ++outLevel; + levelNodeSize = nextLevelNodeSize; + } + + VMA_ASSERT(node != VMA_NULL && node->type == Node::TYPE_ALLOCATION); + return node; +} + +bool VmaBlockMetadata_Buddy::ValidateNode(ValidationContext& ctx, const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const +{ + VMA_VALIDATE(level < m_LevelCount); + VMA_VALIDATE(curr->parent == parent); + VMA_VALIDATE((curr->buddy == VMA_NULL) == (parent == VMA_NULL)); + VMA_VALIDATE(curr->buddy == VMA_NULL || curr->buddy->buddy == curr); + switch (curr->type) + { + case Node::TYPE_FREE: + // curr->free.prev, next are validated separately. + ctx.calculatedSumFreeSize += levelNodeSize; + ++ctx.calculatedFreeCount; + break; + case Node::TYPE_ALLOCATION: + ++ctx.calculatedAllocationCount; + if (!IsVirtual()) + { + VMA_VALIDATE(curr->allocation.userData != VMA_NULL); + } + break; + case Node::TYPE_SPLIT: + { + const uint32_t childrenLevel = level + 1; + const VkDeviceSize childrenLevelNodeSize = levelNodeSize >> 1; + const Node* const leftChild = curr->split.leftChild; + VMA_VALIDATE(leftChild != VMA_NULL); + VMA_VALIDATE(leftChild->offset == curr->offset); + if (!ValidateNode(ctx, curr, leftChild, childrenLevel, childrenLevelNodeSize)) + { + VMA_VALIDATE(false && "ValidateNode for left child failed."); + } + const Node* const rightChild = leftChild->buddy; + VMA_VALIDATE(rightChild->offset == curr->offset + childrenLevelNodeSize); + if (!ValidateNode(ctx, curr, rightChild, childrenLevel, childrenLevelNodeSize)) + { + VMA_VALIDATE(false && "ValidateNode for right child failed."); + } + } + break; + default: + return false; + } + + return true; +} + +uint32_t VmaBlockMetadata_Buddy::AllocSizeToLevel(VkDeviceSize allocSize) const +{ + // I know this could be optimized somehow e.g. by using std::log2p1 from C++20. + uint32_t level = 0; + VkDeviceSize currLevelNodeSize = m_UsableSize; + VkDeviceSize nextLevelNodeSize = currLevelNodeSize >> 1; + while (allocSize <= nextLevelNodeSize && level + 1 < m_LevelCount) + { + ++level; + currLevelNodeSize >>= 1; + nextLevelNodeSize >>= 1; + } + return level; +} + +void VmaBlockMetadata_Buddy::Free(VmaAllocHandle allocHandle) +{ + uint32_t level = 0; + Node* node = FindAllocationNode((VkDeviceSize)allocHandle - 1, level); + + ++m_FreeCount; + --m_AllocationCount; + m_SumFreeSize += LevelToNodeSize(level); + + node->type = Node::TYPE_FREE; + + // Join free nodes if possible. + while (level > 0 && node->buddy->type == Node::TYPE_FREE) + { + RemoveFromFreeList(level, node->buddy); + Node* const parent = node->parent; + + m_NodeAllocator.Free(node->buddy); + m_NodeAllocator.Free(node); + parent->type = Node::TYPE_FREE; + + node = parent; + --level; + --m_FreeCount; + } + + AddToFreeListFront(level, node); +} + +void VmaBlockMetadata_Buddy::AddNodeToDetailedStatistics(VmaDetailedStatistics& inoutStats, const Node* node, VkDeviceSize levelNodeSize) const +{ + switch (node->type) + { + case Node::TYPE_FREE: + VmaAddDetailedStatisticsUnusedRange(inoutStats, levelNodeSize); + break; + case Node::TYPE_ALLOCATION: + VmaAddDetailedStatisticsAllocation(inoutStats, levelNodeSize); + break; + case Node::TYPE_SPLIT: + { + const VkDeviceSize childrenNodeSize = levelNodeSize / 2; + const Node* const leftChild = node->split.leftChild; + AddNodeToDetailedStatistics(inoutStats, leftChild, childrenNodeSize); + const Node* const rightChild = leftChild->buddy; + AddNodeToDetailedStatistics(inoutStats, rightChild, childrenNodeSize); + } + break; + default: + VMA_ASSERT(0); + } +} + +void VmaBlockMetadata_Buddy::AddToFreeListFront(uint32_t level, Node* node) +{ + VMA_ASSERT(node->type == Node::TYPE_FREE); + + // List is empty. + Node* const frontNode = m_FreeList[level].front; + if (frontNode == VMA_NULL) + { + VMA_ASSERT(m_FreeList[level].back == VMA_NULL); + node->free.prev = node->free.next = VMA_NULL; + m_FreeList[level].front = m_FreeList[level].back = node; + } + else + { + VMA_ASSERT(frontNode->free.prev == VMA_NULL); + node->free.prev = VMA_NULL; + node->free.next = frontNode; + frontNode->free.prev = node; + m_FreeList[level].front = node; + } +} + +void VmaBlockMetadata_Buddy::RemoveFromFreeList(uint32_t level, Node* node) +{ + VMA_ASSERT(m_FreeList[level].front != VMA_NULL); + + // It is at the front. + if (node->free.prev == VMA_NULL) + { + VMA_ASSERT(m_FreeList[level].front == node); + m_FreeList[level].front = node->free.next; + } + else + { + Node* const prevFreeNode = node->free.prev; + VMA_ASSERT(prevFreeNode->free.next == node); + prevFreeNode->free.next = node->free.next; + } + + // It is at the back. + if (node->free.next == VMA_NULL) + { + VMA_ASSERT(m_FreeList[level].back == node); + m_FreeList[level].back = node->free.prev; + } + else + { + Node* const nextFreeNode = node->free.next; + VMA_ASSERT(nextFreeNode->free.prev == node); + nextFreeNode->free.prev = node->free.prev; + } +} + +void VmaBlockMetadata_Buddy::DebugLogAllAllocationNode(Node* node, uint32_t level) const +{ + switch (node->type) + { + case Node::TYPE_FREE: + break; + case Node::TYPE_ALLOCATION: + DebugLogAllocation(node->offset, LevelToNodeSize(level), node->allocation.userData); + break; + case Node::TYPE_SPLIT: + { + ++level; + DebugLogAllAllocationNode(node->split.leftChild, level); + DebugLogAllAllocationNode(node->split.leftChild->buddy, level); + } + break; + default: + VMA_ASSERT(0); + } +} + +#if VMA_STATS_STRING_ENABLED +void VmaBlockMetadata_Buddy::PrintDetailedMapNode(class VmaJsonWriter& json, const Node* node, VkDeviceSize levelNodeSize) const +{ + switch (node->type) + { + case Node::TYPE_FREE: + PrintDetailedMap_UnusedRange(json, node->offset, levelNodeSize); + break; + case Node::TYPE_ALLOCATION: + PrintDetailedMap_Allocation(json, node->offset, levelNodeSize, node->allocation.userData); + break; + case Node::TYPE_SPLIT: + { + const VkDeviceSize childrenNodeSize = levelNodeSize / 2; + const Node* const leftChild = node->split.leftChild; + PrintDetailedMapNode(json, leftChild, childrenNodeSize); + const Node* const rightChild = leftChild->buddy; + PrintDetailedMapNode(json, rightChild, childrenNodeSize); + } + break; + default: + VMA_ASSERT(0); + } +} +#endif // VMA_STATS_STRING_ENABLED +#endif // _VMA_BLOCK_METADATA_BUDDY_FUNCTIONS +#endif // _VMA_BLOCK_METADATA_BUDDY +#endif // #if 0 + +#ifndef _VMA_BLOCK_METADATA_TLSF +// To not search current larger region if first allocation won't succeed and skip to smaller range +// use with VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT as strategy in CreateAllocationRequest(). +// When fragmentation and reusal of previous blocks doesn't matter then use with +// VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT for fastest alloc time possible. +class VmaBlockMetadata_TLSF : public VmaBlockMetadata +{ + VMA_CLASS_NO_COPY(VmaBlockMetadata_TLSF) +public: + VmaBlockMetadata_TLSF(const VkAllocationCallbacks* pAllocationCallbacks, + VkDeviceSize bufferImageGranularity, bool isVirtual); + virtual ~VmaBlockMetadata_TLSF(); + + size_t GetAllocationCount() const override { return m_AllocCount; } + size_t GetFreeRegionsCount() const override { return m_BlocksFreeCount + 1; } + VkDeviceSize GetSumFreeSize() const override { return m_BlocksFreeSize + m_NullBlock->size; } + bool IsEmpty() const override { return m_NullBlock->offset == 0; } + VkDeviceSize GetAllocationOffset(VmaAllocHandle allocHandle) const override { return ((Block*)allocHandle)->offset; }; + + void Init(VkDeviceSize size) override; + bool Validate() const override; + + void AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const override; + void AddStatistics(VmaStatistics& inoutStats) const override; + +#if VMA_STATS_STRING_ENABLED + void PrintDetailedMap(class VmaJsonWriter& json) const override; +#endif + + bool CreateAllocationRequest( + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + bool upperAddress, + VmaSuballocationType allocType, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) override; + + VkResult CheckCorruption(const void* pBlockData) override; + void Alloc( + const VmaAllocationRequest& request, + VmaSuballocationType type, + void* userData) override; + + void Free(VmaAllocHandle allocHandle) override; + void GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) override; + void* GetAllocationUserData(VmaAllocHandle allocHandle) const override; + VmaAllocHandle GetAllocationListBegin() const override; + VmaAllocHandle GetNextAllocation(VmaAllocHandle prevAlloc) const override; + VkDeviceSize GetNextFreeRegionSize(VmaAllocHandle alloc) const override; + void Clear() override; + void SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) override; + void DebugLogAllAllocations() const override; private: - VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool. - uint32_t m_MemoryTypeIndex; - uint32_t m_Id; - VkDeviceMemory m_hMemory; + // According to original paper it should be preferable 4 or 5: + // M. Masmano, I. Ripoll, A. Crespo, and J. Real "TLSF: a New Dynamic Memory Allocator for Real-Time Systems" + // http://www.gii.upv.es/tlsf/files/ecrts04_tlsf.pdf + static const uint8_t SECOND_LEVEL_INDEX = 5; + static const uint16_t SMALL_BUFFER_SIZE = 256; + static const uint32_t INITIAL_BLOCK_ALLOC_COUNT = 16; + static const uint8_t MEMORY_CLASS_SHIFT = 7; + static const uint8_t MAX_MEMORY_CLASSES = 65 - MEMORY_CLASS_SHIFT; + class Block + { + public: + VkDeviceSize offset; + VkDeviceSize size; + Block* prevPhysical; + Block* nextPhysical; + + void MarkFree() { prevFree = VMA_NULL; } + void MarkTaken() { prevFree = this; } + bool IsFree() const { return prevFree != this; } + void*& UserData() { VMA_HEAVY_ASSERT(!IsFree()); return userData; } + Block*& PrevFree() { return prevFree; } + Block*& NextFree() { VMA_HEAVY_ASSERT(IsFree()); return nextFree; } + + private: + Block* prevFree; // Address of the same block here indicates that block is taken + union + { + Block* nextFree; + void* userData; + }; + }; + + size_t m_AllocCount; + // Total number of free blocks besides null block + size_t m_BlocksFreeCount; + // Total size of free blocks excluding null block + VkDeviceSize m_BlocksFreeSize; + uint32_t m_IsFreeBitmap; + uint8_t m_MemoryClasses; + uint32_t m_InnerIsFreeBitmap[MAX_MEMORY_CLASSES]; + uint32_t m_ListsCount; /* - Protects access to m_hMemory so it is not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory. - Also protects m_MapCount, m_pMappedData. - Allocations, deallocations, any change in m_pMetadata is protected by parent's VmaBlockVector::m_Mutex. + * 0: 0-3 lists for small buffers + * 1+: 0-(2^SLI-1) lists for normal buffers */ - VMA_MUTEX m_Mutex; - uint32_t m_MapCount; - void* m_pMappedData; + Block** m_FreeList; + VmaPoolAllocator m_BlockAllocator; + Block* m_NullBlock; + VmaBlockBufferImageGranularity m_GranularityHandler; + + uint8_t SizeToMemoryClass(VkDeviceSize size) const; + uint16_t SizeToSecondIndex(VkDeviceSize size, uint8_t memoryClass) const; + uint32_t GetListIndex(uint8_t memoryClass, uint16_t secondIndex) const; + uint32_t GetListIndex(VkDeviceSize size) const; + + void RemoveFreeBlock(Block* block); + void InsertFreeBlock(Block* block); + void MergeBlock(Block* block, Block* prev); + + Block* FindFreeBlock(VkDeviceSize size, uint32_t& listIndex) const; + bool CheckBlock( + Block& block, + uint32_t listIndex, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + VmaSuballocationType allocType, + VmaAllocationRequest* pAllocationRequest); }; -struct VmaDefragmentationMove +#ifndef _VMA_BLOCK_METADATA_TLSF_FUNCTIONS +VmaBlockMetadata_TLSF::VmaBlockMetadata_TLSF(const VkAllocationCallbacks* pAllocationCallbacks, + VkDeviceSize bufferImageGranularity, bool isVirtual) + : VmaBlockMetadata(pAllocationCallbacks, bufferImageGranularity, isVirtual), + m_AllocCount(0), + m_BlocksFreeCount(0), + m_BlocksFreeSize(0), + m_IsFreeBitmap(0), + m_MemoryClasses(0), + m_ListsCount(0), + m_FreeList(VMA_NULL), + m_BlockAllocator(pAllocationCallbacks, INITIAL_BLOCK_ALLOC_COUNT), + m_NullBlock(VMA_NULL), + m_GranularityHandler(bufferImageGranularity) {} + +VmaBlockMetadata_TLSF::~VmaBlockMetadata_TLSF() { - size_t srcBlockIndex; - size_t dstBlockIndex; - VkDeviceSize srcOffset; - VkDeviceSize dstOffset; - VkDeviceSize size; - VmaAllocation hAllocation; - VmaDeviceMemoryBlock* pSrcBlock; - VmaDeviceMemoryBlock* pDstBlock; -}; + if (m_FreeList) + vma_delete_array(GetAllocationCallbacks(), m_FreeList, m_ListsCount); + m_GranularityHandler.Destroy(GetAllocationCallbacks()); +} -class VmaDefragmentationAlgorithm; +void VmaBlockMetadata_TLSF::Init(VkDeviceSize size) +{ + VmaBlockMetadata::Init(size); + if (!IsVirtual()) + m_GranularityHandler.Init(GetAllocationCallbacks(), size); + + m_NullBlock = m_BlockAllocator.Alloc(); + m_NullBlock->size = size; + m_NullBlock->offset = 0; + m_NullBlock->prevPhysical = VMA_NULL; + m_NullBlock->nextPhysical = VMA_NULL; + m_NullBlock->MarkFree(); + m_NullBlock->NextFree() = VMA_NULL; + m_NullBlock->PrevFree() = VMA_NULL; + uint8_t memoryClass = SizeToMemoryClass(size); + uint16_t sli = SizeToSecondIndex(size, memoryClass); + m_ListsCount = (memoryClass == 0 ? 0 : (memoryClass - 1) * (1UL << SECOND_LEVEL_INDEX) + sli) + 1; + if (IsVirtual()) + m_ListsCount += 1UL << SECOND_LEVEL_INDEX; + else + m_ListsCount += 4; + + m_MemoryClasses = memoryClass + 2; + memset(m_InnerIsFreeBitmap, 0, MAX_MEMORY_CLASSES * sizeof(uint32_t)); + + m_FreeList = vma_new_array(GetAllocationCallbacks(), Block*, m_ListsCount); + memset(m_FreeList, 0, m_ListsCount * sizeof(Block*)); +} + +bool VmaBlockMetadata_TLSF::Validate() const +{ + VMA_VALIDATE(GetSumFreeSize() <= GetSize()); + + VkDeviceSize calculatedSize = m_NullBlock->size; + VkDeviceSize calculatedFreeSize = m_NullBlock->size; + size_t allocCount = 0; + size_t freeCount = 0; + + // Check integrity of free lists + for (uint32_t list = 0; list < m_ListsCount; ++list) + { + Block* block = m_FreeList[list]; + if (block != VMA_NULL) + { + VMA_VALIDATE(block->IsFree()); + VMA_VALIDATE(block->PrevFree() == VMA_NULL); + while (block->NextFree()) + { + VMA_VALIDATE(block->NextFree()->IsFree()); + VMA_VALIDATE(block->NextFree()->PrevFree() == block); + block = block->NextFree(); + } + } + } + + VkDeviceSize nextOffset = m_NullBlock->offset; + auto validateCtx = m_GranularityHandler.StartValidation(GetAllocationCallbacks(), IsVirtual()); + + VMA_VALIDATE(m_NullBlock->nextPhysical == VMA_NULL); + if (m_NullBlock->prevPhysical) + { + VMA_VALIDATE(m_NullBlock->prevPhysical->nextPhysical == m_NullBlock); + } + // Check all blocks + for (Block* prev = m_NullBlock->prevPhysical; prev != VMA_NULL; prev = prev->prevPhysical) + { + VMA_VALIDATE(prev->offset + prev->size == nextOffset); + nextOffset = prev->offset; + calculatedSize += prev->size; + + uint32_t listIndex = GetListIndex(prev->size); + if (prev->IsFree()) + { + ++freeCount; + // Check if free block belongs to free list + Block* freeBlock = m_FreeList[listIndex]; + VMA_VALIDATE(freeBlock != VMA_NULL); + + bool found = false; + do + { + if (freeBlock == prev) + found = true; + + freeBlock = freeBlock->NextFree(); + } while (!found && freeBlock != VMA_NULL); + + VMA_VALIDATE(found); + calculatedFreeSize += prev->size; + } + else + { + ++allocCount; + // Check if taken block is not on a free list + Block* freeBlock = m_FreeList[listIndex]; + while (freeBlock) + { + VMA_VALIDATE(freeBlock != prev); + freeBlock = freeBlock->NextFree(); + } + + if (!IsVirtual()) + { + VMA_VALIDATE(m_GranularityHandler.Validate(validateCtx, prev->offset, prev->size)); + } + } + + if (prev->prevPhysical) + { + VMA_VALIDATE(prev->prevPhysical->nextPhysical == prev); + } + } + + if (!IsVirtual()) + { + VMA_VALIDATE(m_GranularityHandler.FinishValidation(validateCtx)); + } + + VMA_VALIDATE(nextOffset == 0); + VMA_VALIDATE(calculatedSize == GetSize()); + VMA_VALIDATE(calculatedFreeSize == GetSumFreeSize()); + VMA_VALIDATE(allocCount == m_AllocCount); + VMA_VALIDATE(freeCount == m_BlocksFreeCount); + + return true; +} + +void VmaBlockMetadata_TLSF::AddDetailedStatistics(VmaDetailedStatistics& inoutStats) const +{ + inoutStats.statistics.blockCount++; + inoutStats.statistics.blockBytes += GetSize(); + if (m_NullBlock->size > 0) + VmaAddDetailedStatisticsUnusedRange(inoutStats, m_NullBlock->size); + + for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical) + { + if (block->IsFree()) + VmaAddDetailedStatisticsUnusedRange(inoutStats, block->size); + else + VmaAddDetailedStatisticsAllocation(inoutStats, block->size); + } +} + +void VmaBlockMetadata_TLSF::AddStatistics(VmaStatistics& inoutStats) const +{ + inoutStats.blockCount++; + inoutStats.allocationCount += (uint32_t)m_AllocCount; + inoutStats.blockBytes += GetSize(); + inoutStats.allocationBytes += GetSize() - GetSumFreeSize(); +} + +#if VMA_STATS_STRING_ENABLED +void VmaBlockMetadata_TLSF::PrintDetailedMap(class VmaJsonWriter& json) const +{ + size_t blockCount = m_AllocCount + m_BlocksFreeCount; + VmaStlAllocator allocator(GetAllocationCallbacks()); + VmaVector> blockList(blockCount, allocator); + + size_t i = blockCount; + for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical) + { + blockList[--i] = block; + } + VMA_ASSERT(i == 0); + + VmaDetailedStatistics stats; + VmaClearDetailedStatistics(stats); + AddDetailedStatistics(stats); + + PrintDetailedMap_Begin(json, + stats.statistics.blockBytes - stats.statistics.allocationBytes, + stats.statistics.allocationCount, + stats.unusedRangeCount); + + for (; i < blockCount; ++i) + { + Block* block = blockList[i]; + if (block->IsFree()) + PrintDetailedMap_UnusedRange(json, block->offset, block->size); + else + PrintDetailedMap_Allocation(json, block->offset, block->size, block->UserData()); + } + if (m_NullBlock->size > 0) + PrintDetailedMap_UnusedRange(json, m_NullBlock->offset, m_NullBlock->size); + + PrintDetailedMap_End(json); +} +#endif + +bool VmaBlockMetadata_TLSF::CreateAllocationRequest( + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + bool upperAddress, + VmaSuballocationType allocType, + uint32_t strategy, + VmaAllocationRequest* pAllocationRequest) +{ + VMA_ASSERT(allocSize > 0 && "Cannot allocate empty block!"); + VMA_ASSERT(!upperAddress && "VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT can be used only with linear algorithm."); + + // For small granularity round up + if (!IsVirtual()) + m_GranularityHandler.RoundupAllocRequest(allocType, allocSize, allocAlignment); + + allocSize += GetDebugMargin(); + // Quick check for too small pool + if (allocSize > GetSumFreeSize()) + return false; + + // If no free blocks in pool then check only null block + if (m_BlocksFreeCount == 0) + return CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest); + + // Round up to the next block + VkDeviceSize sizeForNextList = allocSize; + VkDeviceSize smallSizeStep = SMALL_BUFFER_SIZE / (IsVirtual() ? 1 << SECOND_LEVEL_INDEX : 4); + if (allocSize > SMALL_BUFFER_SIZE) + { + sizeForNextList += (1ULL << (VMA_BITSCAN_MSB(allocSize) - SECOND_LEVEL_INDEX)); + } + else if (allocSize > SMALL_BUFFER_SIZE - smallSizeStep) + sizeForNextList = SMALL_BUFFER_SIZE + 1; + else + sizeForNextList += smallSizeStep; + + uint32_t nextListIndex = 0; + uint32_t prevListIndex = 0; + Block* nextListBlock = VMA_NULL; + Block* prevListBlock = VMA_NULL; + + // Check blocks according to strategies + if (strategy & VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT) + { + // Quick check for larger block first + nextListBlock = FindFreeBlock(sizeForNextList, nextListIndex); + if (nextListBlock != VMA_NULL && CheckBlock(*nextListBlock, nextListIndex, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + + // If not fitted then null block + if (CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + + // Null block failed, search larger bucket + while (nextListBlock) + { + if (CheckBlock(*nextListBlock, nextListIndex, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + nextListBlock = nextListBlock->NextFree(); + } + + // Failed again, check best fit bucket + prevListBlock = FindFreeBlock(allocSize, prevListIndex); + while (prevListBlock) + { + if (CheckBlock(*prevListBlock, prevListIndex, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + prevListBlock = prevListBlock->NextFree(); + } + } + else if (strategy & VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT) + { + // Check best fit bucket + prevListBlock = FindFreeBlock(allocSize, prevListIndex); + while (prevListBlock) + { + if (CheckBlock(*prevListBlock, prevListIndex, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + prevListBlock = prevListBlock->NextFree(); + } + + // If failed check null block + if (CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + + // Check larger bucket + nextListBlock = FindFreeBlock(sizeForNextList, nextListIndex); + while (nextListBlock) + { + if (CheckBlock(*nextListBlock, nextListIndex, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + nextListBlock = nextListBlock->NextFree(); + } + } + else if (strategy & VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT ) + { + // Perform search from the start + VmaStlAllocator allocator(GetAllocationCallbacks()); + VmaVector> blockList(m_BlocksFreeCount, allocator); + + size_t i = m_BlocksFreeCount; + for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical) + { + if (block->IsFree() && block->size >= allocSize) + blockList[--i] = block; + } + + for (; i < m_BlocksFreeCount; ++i) + { + Block& block = *blockList[i]; + if (CheckBlock(block, GetListIndex(block.size), allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + } + + // If failed check null block + if (CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + + // Whole range searched, no more memory + return false; + } + else + { + // Check larger bucket + nextListBlock = FindFreeBlock(sizeForNextList, nextListIndex); + while (nextListBlock) + { + if (CheckBlock(*nextListBlock, nextListIndex, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + nextListBlock = nextListBlock->NextFree(); + } + + // If failed check null block + if (CheckBlock(*m_NullBlock, m_ListsCount, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + + // Check best fit bucket + prevListBlock = FindFreeBlock(allocSize, prevListIndex); + while (prevListBlock) + { + if (CheckBlock(*prevListBlock, prevListIndex, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + prevListBlock = prevListBlock->NextFree(); + } + } + + // Worst case, full search has to be done + while (++nextListIndex < m_ListsCount) + { + nextListBlock = m_FreeList[nextListIndex]; + while (nextListBlock) + { + if (CheckBlock(*nextListBlock, nextListIndex, allocSize, allocAlignment, allocType, pAllocationRequest)) + return true; + nextListBlock = nextListBlock->NextFree(); + } + } + + // No more memory sadly + return false; +} + +VkResult VmaBlockMetadata_TLSF::CheckCorruption(const void* pBlockData) +{ + for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical) + { + if (!block->IsFree()) + { + if (!VmaValidateMagicValue(pBlockData, block->offset + block->size)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!"); + return VK_ERROR_UNKNOWN_COPY; + } + } + } + + return VK_SUCCESS; +} + +void VmaBlockMetadata_TLSF::Alloc( + const VmaAllocationRequest& request, + VmaSuballocationType type, + void* userData) +{ + VMA_ASSERT(request.type == VmaAllocationRequestType::TLSF); + + // Get block and pop it from the free list + Block* currentBlock = (Block*)request.allocHandle; + VkDeviceSize offset = request.algorithmData; + VMA_ASSERT(currentBlock != VMA_NULL); + VMA_ASSERT(currentBlock->offset <= offset); + + if (currentBlock != m_NullBlock) + RemoveFreeBlock(currentBlock); + + VkDeviceSize debugMargin = GetDebugMargin(); + VkDeviceSize misssingAlignment = offset - currentBlock->offset; + + // Append missing alignment to prev block or create new one + if (misssingAlignment) + { + Block* prevBlock = currentBlock->prevPhysical; + VMA_ASSERT(prevBlock != VMA_NULL && "There should be no missing alignment at offset 0!"); + + if (prevBlock->IsFree() && prevBlock->size != debugMargin) + { + uint32_t oldList = GetListIndex(prevBlock->size); + prevBlock->size += misssingAlignment; + // Check if new size crosses list bucket + if (oldList != GetListIndex(prevBlock->size)) + { + prevBlock->size -= misssingAlignment; + RemoveFreeBlock(prevBlock); + prevBlock->size += misssingAlignment; + InsertFreeBlock(prevBlock); + } + else + m_BlocksFreeSize += misssingAlignment; + } + else + { + Block* newBlock = m_BlockAllocator.Alloc(); + currentBlock->prevPhysical = newBlock; + prevBlock->nextPhysical = newBlock; + newBlock->prevPhysical = prevBlock; + newBlock->nextPhysical = currentBlock; + newBlock->size = misssingAlignment; + newBlock->offset = currentBlock->offset; + newBlock->MarkTaken(); + + InsertFreeBlock(newBlock); + } + + currentBlock->size -= misssingAlignment; + currentBlock->offset += misssingAlignment; + } + + VkDeviceSize size = request.size + debugMargin; + if (currentBlock->size == size) + { + if (currentBlock == m_NullBlock) + { + // Setup new null block + m_NullBlock = m_BlockAllocator.Alloc(); + m_NullBlock->size = 0; + m_NullBlock->offset = currentBlock->offset + size; + m_NullBlock->prevPhysical = currentBlock; + m_NullBlock->nextPhysical = VMA_NULL; + m_NullBlock->MarkFree(); + m_NullBlock->PrevFree() = VMA_NULL; + m_NullBlock->NextFree() = VMA_NULL; + currentBlock->nextPhysical = m_NullBlock; + currentBlock->MarkTaken(); + } + } + else + { + VMA_ASSERT(currentBlock->size > size && "Proper block already found, shouldn't find smaller one!"); + + // Create new free block + Block* newBlock = m_BlockAllocator.Alloc(); + newBlock->size = currentBlock->size - size; + newBlock->offset = currentBlock->offset + size; + newBlock->prevPhysical = currentBlock; + newBlock->nextPhysical = currentBlock->nextPhysical; + currentBlock->nextPhysical = newBlock; + currentBlock->size = size; + + if (currentBlock == m_NullBlock) + { + m_NullBlock = newBlock; + m_NullBlock->MarkFree(); + m_NullBlock->NextFree() = VMA_NULL; + m_NullBlock->PrevFree() = VMA_NULL; + currentBlock->MarkTaken(); + } + else + { + newBlock->nextPhysical->prevPhysical = newBlock; + newBlock->MarkTaken(); + InsertFreeBlock(newBlock); + } + } + currentBlock->UserData() = userData; + + if (debugMargin > 0) + { + currentBlock->size -= debugMargin; + Block* newBlock = m_BlockAllocator.Alloc(); + newBlock->size = debugMargin; + newBlock->offset = currentBlock->offset + currentBlock->size; + newBlock->prevPhysical = currentBlock; + newBlock->nextPhysical = currentBlock->nextPhysical; + newBlock->MarkTaken(); + currentBlock->nextPhysical->prevPhysical = newBlock; + currentBlock->nextPhysical = newBlock; + InsertFreeBlock(newBlock); + } + + if (!IsVirtual()) + m_GranularityHandler.AllocPages((uint8_t)(uintptr_t)request.customData, + currentBlock->offset, currentBlock->size); + ++m_AllocCount; +} + +void VmaBlockMetadata_TLSF::Free(VmaAllocHandle allocHandle) +{ + Block* block = (Block*)allocHandle; + Block* next = block->nextPhysical; + VMA_ASSERT(!block->IsFree() && "Block is already free!"); + + if (!IsVirtual()) + m_GranularityHandler.FreePages(block->offset, block->size); + --m_AllocCount; + + VkDeviceSize debugMargin = GetDebugMargin(); + if (debugMargin > 0) + { + RemoveFreeBlock(next); + MergeBlock(next, block); + block = next; + next = next->nextPhysical; + } + + // Try merging + Block* prev = block->prevPhysical; + if (prev != VMA_NULL && prev->IsFree() && prev->size != debugMargin) + { + RemoveFreeBlock(prev); + MergeBlock(block, prev); + } + + if (!next->IsFree()) + InsertFreeBlock(block); + else if (next == m_NullBlock) + MergeBlock(m_NullBlock, block); + else + { + RemoveFreeBlock(next); + MergeBlock(next, block); + InsertFreeBlock(next); + } +} + +void VmaBlockMetadata_TLSF::GetAllocationInfo(VmaAllocHandle allocHandle, VmaVirtualAllocationInfo& outInfo) +{ + Block* block = (Block*)allocHandle; + VMA_ASSERT(!block->IsFree() && "Cannot get allocation info for free block!"); + outInfo.offset = block->offset; + outInfo.size = block->size; + outInfo.pUserData = block->UserData(); +} + +void* VmaBlockMetadata_TLSF::GetAllocationUserData(VmaAllocHandle allocHandle) const +{ + Block* block = (Block*)allocHandle; + VMA_ASSERT(!block->IsFree() && "Cannot get user data for free block!"); + return block->UserData(); +} + +VmaAllocHandle VmaBlockMetadata_TLSF::GetAllocationListBegin() const +{ + if (m_AllocCount == 0) + return VK_NULL_HANDLE; + + for (Block* block = m_NullBlock->prevPhysical; block; block = block->prevPhysical) + { + if (!block->IsFree()) + return (VmaAllocHandle)block; + } + VMA_ASSERT(false && "If m_AllocCount > 0 then should find any allocation!"); + return VK_NULL_HANDLE; +} + +VmaAllocHandle VmaBlockMetadata_TLSF::GetNextAllocation(VmaAllocHandle prevAlloc) const +{ + Block* startBlock = (Block*)prevAlloc; + VMA_ASSERT(!startBlock->IsFree() && "Incorrect block!"); + + for (Block* block = startBlock->prevPhysical; block; block = block->prevPhysical) + { + if (!block->IsFree()) + return (VmaAllocHandle)block; + } + return VK_NULL_HANDLE; +} + +VkDeviceSize VmaBlockMetadata_TLSF::GetNextFreeRegionSize(VmaAllocHandle alloc) const +{ + Block* block = (Block*)alloc; + VMA_ASSERT(!block->IsFree() && "Incorrect block!"); + + if (block->prevPhysical) + return block->prevPhysical->IsFree() ? block->prevPhysical->size : 0; + return 0; +} + +void VmaBlockMetadata_TLSF::Clear() +{ + m_AllocCount = 0; + m_BlocksFreeCount = 0; + m_BlocksFreeSize = 0; + m_IsFreeBitmap = 0; + m_NullBlock->offset = 0; + m_NullBlock->size = GetSize(); + Block* block = m_NullBlock->prevPhysical; + m_NullBlock->prevPhysical = VMA_NULL; + while (block) + { + Block* prev = block->prevPhysical; + m_BlockAllocator.Free(block); + block = prev; + } + memset(m_FreeList, 0, m_ListsCount * sizeof(Block*)); + memset(m_InnerIsFreeBitmap, 0, m_MemoryClasses * sizeof(uint32_t)); + m_GranularityHandler.Clear(); +} + +void VmaBlockMetadata_TLSF::SetAllocationUserData(VmaAllocHandle allocHandle, void* userData) +{ + Block* block = (Block*)allocHandle; + VMA_ASSERT(!block->IsFree() && "Trying to set user data for not allocated block!"); + block->UserData() = userData; +} + +void VmaBlockMetadata_TLSF::DebugLogAllAllocations() const +{ + for (Block* block = m_NullBlock->prevPhysical; block != VMA_NULL; block = block->prevPhysical) + if (!block->IsFree()) + DebugLogAllocation(block->offset, block->size, block->UserData()); +} + +uint8_t VmaBlockMetadata_TLSF::SizeToMemoryClass(VkDeviceSize size) const +{ + if (size > SMALL_BUFFER_SIZE) + return VMA_BITSCAN_MSB(size) - MEMORY_CLASS_SHIFT; + return 0; +} + +uint16_t VmaBlockMetadata_TLSF::SizeToSecondIndex(VkDeviceSize size, uint8_t memoryClass) const +{ + if (memoryClass == 0) + { + if (IsVirtual()) + return static_cast((size - 1) / 8); + else + return static_cast((size - 1) / 64); + } + return static_cast((size >> (memoryClass + MEMORY_CLASS_SHIFT - SECOND_LEVEL_INDEX)) ^ (1U << SECOND_LEVEL_INDEX)); +} + +uint32_t VmaBlockMetadata_TLSF::GetListIndex(uint8_t memoryClass, uint16_t secondIndex) const +{ + if (memoryClass == 0) + return secondIndex; + + const uint32_t index = static_cast(memoryClass - 1) * (1 << SECOND_LEVEL_INDEX) + secondIndex; + if (IsVirtual()) + return index + (1 << SECOND_LEVEL_INDEX); + else + return index + 4; +} + +uint32_t VmaBlockMetadata_TLSF::GetListIndex(VkDeviceSize size) const +{ + uint8_t memoryClass = SizeToMemoryClass(size); + return GetListIndex(memoryClass, SizeToSecondIndex(size, memoryClass)); +} + +void VmaBlockMetadata_TLSF::RemoveFreeBlock(Block* block) +{ + VMA_ASSERT(block != m_NullBlock); + VMA_ASSERT(block->IsFree()); + + if (block->NextFree() != VMA_NULL) + block->NextFree()->PrevFree() = block->PrevFree(); + if (block->PrevFree() != VMA_NULL) + block->PrevFree()->NextFree() = block->NextFree(); + else + { + uint8_t memClass = SizeToMemoryClass(block->size); + uint16_t secondIndex = SizeToSecondIndex(block->size, memClass); + uint32_t index = GetListIndex(memClass, secondIndex); + VMA_ASSERT(m_FreeList[index] == block); + m_FreeList[index] = block->NextFree(); + if (block->NextFree() == VMA_NULL) + { + m_InnerIsFreeBitmap[memClass] &= ~(1U << secondIndex); + if (m_InnerIsFreeBitmap[memClass] == 0) + m_IsFreeBitmap &= ~(1UL << memClass); + } + } + block->MarkTaken(); + block->UserData() = VMA_NULL; + --m_BlocksFreeCount; + m_BlocksFreeSize -= block->size; +} + +void VmaBlockMetadata_TLSF::InsertFreeBlock(Block* block) +{ + VMA_ASSERT(block != m_NullBlock); + VMA_ASSERT(!block->IsFree() && "Cannot insert block twice!"); + + uint8_t memClass = SizeToMemoryClass(block->size); + uint16_t secondIndex = SizeToSecondIndex(block->size, memClass); + uint32_t index = GetListIndex(memClass, secondIndex); + VMA_ASSERT(index < m_ListsCount); + block->PrevFree() = VMA_NULL; + block->NextFree() = m_FreeList[index]; + m_FreeList[index] = block; + if (block->NextFree() != VMA_NULL) + block->NextFree()->PrevFree() = block; + else + { + m_InnerIsFreeBitmap[memClass] |= 1U << secondIndex; + m_IsFreeBitmap |= 1UL << memClass; + } + ++m_BlocksFreeCount; + m_BlocksFreeSize += block->size; +} + +void VmaBlockMetadata_TLSF::MergeBlock(Block* block, Block* prev) +{ + VMA_ASSERT(block->prevPhysical == prev && "Cannot merge seperate physical regions!"); + VMA_ASSERT(!prev->IsFree() && "Cannot merge block that belongs to free list!"); + + block->offset = prev->offset; + block->size += prev->size; + block->prevPhysical = prev->prevPhysical; + if (block->prevPhysical) + block->prevPhysical->nextPhysical = block; + m_BlockAllocator.Free(prev); +} + +VmaBlockMetadata_TLSF::Block* VmaBlockMetadata_TLSF::FindFreeBlock(VkDeviceSize size, uint32_t& listIndex) const +{ + uint8_t memoryClass = SizeToMemoryClass(size); + uint32_t innerFreeMap = m_InnerIsFreeBitmap[memoryClass] & (~0U << SizeToSecondIndex(size, memoryClass)); + if (!innerFreeMap) + { + // Check higher levels for avaiable blocks + uint32_t freeMap = m_IsFreeBitmap & (~0UL << (memoryClass + 1)); + if (!freeMap) + return VMA_NULL; // No more memory avaible + + // Find lowest free region + memoryClass = VMA_BITSCAN_LSB(freeMap); + innerFreeMap = m_InnerIsFreeBitmap[memoryClass]; + VMA_ASSERT(innerFreeMap != 0); + } + // Find lowest free subregion + listIndex = GetListIndex(memoryClass, VMA_BITSCAN_LSB(innerFreeMap)); + VMA_ASSERT(m_FreeList[listIndex]); + return m_FreeList[listIndex]; +} + +bool VmaBlockMetadata_TLSF::CheckBlock( + Block& block, + uint32_t listIndex, + VkDeviceSize allocSize, + VkDeviceSize allocAlignment, + VmaSuballocationType allocType, + VmaAllocationRequest* pAllocationRequest) +{ + VMA_ASSERT(block.IsFree() && "Block is already taken!"); + + VkDeviceSize alignedOffset = VmaAlignUp(block.offset, allocAlignment); + if (block.size < allocSize + alignedOffset - block.offset) + return false; + + // Check for granularity conflicts + if (!IsVirtual() && + m_GranularityHandler.CheckConflictAndAlignUp(alignedOffset, allocSize, block.offset, block.size, allocType)) + return false; + + // Alloc successful + pAllocationRequest->type = VmaAllocationRequestType::TLSF; + pAllocationRequest->allocHandle = (VmaAllocHandle)█ + pAllocationRequest->size = allocSize - GetDebugMargin(); + pAllocationRequest->customData = (void*)allocType; + pAllocationRequest->algorithmData = alignedOffset; + + // Place block at the start of list if it's normal block + if (listIndex != m_ListsCount && block.PrevFree()) + { + block.PrevFree()->NextFree() = block.NextFree(); + if (block.NextFree()) + block.NextFree()->PrevFree() = block.PrevFree(); + block.PrevFree() = VMA_NULL; + block.NextFree() = m_FreeList[listIndex]; + m_FreeList[listIndex] = █ + if (block.NextFree()) + block.NextFree()->PrevFree() = █ + } + + return true; +} +#endif // _VMA_BLOCK_METADATA_TLSF_FUNCTIONS +#endif // _VMA_BLOCK_METADATA_TLSF + +#ifndef _VMA_BLOCK_VECTOR /* Sequence of VmaDeviceMemoryBlock. Represents memory blocks allocated for a specific Vulkan memory type. Synchronized internally with a mutex. */ -struct VmaBlockVector +class VmaBlockVector { + friend struct VmaDefragmentationContext_T; VMA_CLASS_NO_COPY(VmaBlockVector) public: VmaBlockVector( @@ -5497,7 +10875,6 @@ public: size_t minBlockCount, size_t maxBlockCount, VkDeviceSize bufferImageGranularity, - uint32_t frameInUseCount, bool explicitBlockSize, uint32_t algorithm, float priority, @@ -5505,24 +10882,29 @@ public: void* pMemoryAllocateNext); ~VmaBlockVector(); - VkResult CreateMinBlocks(); - VmaAllocator GetAllocator() const { return m_hAllocator; } VmaPool GetParentPool() const { return m_hParentPool; } bool IsCustomPool() const { return m_hParentPool != VMA_NULL; } uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; } VkDeviceSize GetPreferredBlockSize() const { return m_PreferredBlockSize; } VkDeviceSize GetBufferImageGranularity() const { return m_BufferImageGranularity; } - uint32_t GetFrameInUseCount() const { return m_FrameInUseCount; } uint32_t GetAlgorithm() const { return m_Algorithm; } + bool HasExplicitBlockSize() const { return m_ExplicitBlockSize; } + float GetPriority() const { return m_Priority; } + const void* GetAllocationNextPtr() const { return m_pMemoryAllocateNext; } + // To be used only while the m_Mutex is locked. Used during defragmentation. + size_t GetBlockCount() const { return m_Blocks.size(); } + // To be used only while the m_Mutex is locked. Used during defragmentation. + VmaDeviceMemoryBlock* GetBlock(size_t index) const { return m_Blocks[index]; } + VMA_RW_MUTEX &GetMutex() { return m_Mutex; } - void GetPoolStats(VmaPoolStats* pStats); - + VkResult CreateMinBlocks(); + void AddStatistics(VmaStatistics& inoutStats); + void AddDetailedStatistics(VmaDetailedStatistics& inoutStats); bool IsEmpty(); bool IsCorruptionDetectionEnabled() const; VkResult Allocate( - uint32_t currentFrameIndex, VkDeviceSize size, VkDeviceSize alignment, const VmaAllocationCreateInfo& createInfo, @@ -5532,49 +10914,13 @@ public: void Free(const VmaAllocation hAllocation); - // Adds statistics of this BlockVector to pStats. - void AddStats(VmaStats* pStats); - #if VMA_STATS_STRING_ENABLED void PrintDetailedMap(class VmaJsonWriter& json); #endif - void MakePoolAllocationsLost( - uint32_t currentFrameIndex, - size_t* pLostAllocationCount); VkResult CheckCorruption(); - // Saves results in pCtx->res. - void Defragment( - class VmaBlockVectorDefragmentationContext* pCtx, - VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags, - VkDeviceSize& maxCpuBytesToMove, uint32_t& maxCpuAllocationsToMove, - VkDeviceSize& maxGpuBytesToMove, uint32_t& maxGpuAllocationsToMove, - VkCommandBuffer commandBuffer); - void DefragmentationEnd( - class VmaBlockVectorDefragmentationContext* pCtx, - uint32_t flags, - VmaDefragmentationStats* pStats); - - uint32_t ProcessDefragmentations( - class VmaBlockVectorDefragmentationContext *pCtx, - VmaDefragmentationPassMoveInfo* pMove, uint32_t maxMoves); - - void CommitDefragmentations( - class VmaBlockVectorDefragmentationContext *pCtx, - VmaDefragmentationStats* pStats); - - //////////////////////////////////////////////////////////////////////////////// - // To be used only while the m_Mutex is locked. Used during defragmentation. - - size_t GetBlockCount() const { return m_Blocks.size(); } - VmaDeviceMemoryBlock* GetBlock(size_t index) const { return m_Blocks[index]; } - size_t CalcAllocationCount() const; - bool IsBufferImageGranularityConflictPossible() const; - private: - friend class VmaDefragmentationAlgorithm_Generic; - const VmaAllocator m_hAllocator; const VmaPool m_hParentPool; const uint32_t m_MemoryTypeIndex; @@ -5582,42 +10928,37 @@ private: const size_t m_MinBlockCount; const size_t m_MaxBlockCount; const VkDeviceSize m_BufferImageGranularity; - const uint32_t m_FrameInUseCount; const bool m_ExplicitBlockSize; const uint32_t m_Algorithm; const float m_Priority; const VkDeviceSize m_MinAllocationAlignment; + void* const m_pMemoryAllocateNext; VMA_RW_MUTEX m_Mutex; - - /* There can be at most one allocation that is completely empty (except when minBlockCount > 0) - - a hysteresis to avoid pessimistic case of alternating creation and destruction of a VkDeviceMemory. */ - bool m_HasEmptyBlock; // Incrementally sorted by sumFreeSize, ascending. - VmaVector< VmaDeviceMemoryBlock*, VmaStlAllocator > m_Blocks; + VmaVector> m_Blocks; uint32_t m_NextBlockId; + bool m_IncrementalSort = true; + + void SetIncrementalSort(bool val) { m_IncrementalSort = val; } VkDeviceSize CalcMaxBlockSize() const; - // Finds and removes given block from vector. void Remove(VmaDeviceMemoryBlock* pBlock); - // Performs single step in sorting m_Blocks. They may not be fully sorted // after this call. void IncrementallySortBlocks(); + void SortByFreeSize(); VkResult AllocatePage( - uint32_t currentFrameIndex, VkDeviceSize size, VkDeviceSize alignment, const VmaAllocationCreateInfo& createInfo, VmaSuballocationType suballocType, VmaAllocation* pAllocation); - // To be used only without CAN_MAKE_OTHER_LOST flag. VkResult AllocateFromBlock( VmaDeviceMemoryBlock* pBlock, - uint32_t currentFrameIndex, VkDeviceSize size, VkDeviceSize alignment, VmaAllocationCreateFlags allocFlags, @@ -5626,32 +10967,114 @@ private: uint32_t strategy, VmaAllocation* pAllocation); + VkResult CommitAllocationRequest( + VmaAllocationRequest& allocRequest, + VmaDeviceMemoryBlock* pBlock, + VkDeviceSize alignment, + VmaAllocationCreateFlags allocFlags, + void* pUserData, + VmaSuballocationType suballocType, + VmaAllocation* pAllocation); + VkResult CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex); - - // Saves result to pCtx->res. - void ApplyDefragmentationMovesCpu( - class VmaBlockVectorDefragmentationContext* pDefragCtx, - const VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves); - // Saves result to pCtx->res. - void ApplyDefragmentationMovesGpu( - class VmaBlockVectorDefragmentationContext* pDefragCtx, - VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, - VkCommandBuffer commandBuffer); - - /* - Used during defragmentation. pDefragmentationStats is optional. It is in/out - - updated with new data. - */ - void FreeEmptyBlocks(VmaDefragmentationStats* pDefragmentationStats); - - void UpdateHasEmptyBlock(); + bool HasEmptyBlock(); }; +#endif // _VMA_BLOCK_VECTOR +#ifndef _VMA_DEFRAGMENTATION_CONTEXT +struct VmaDefragmentationContext_T +{ + VMA_CLASS_NO_COPY(VmaDefragmentationContext_T) +public: + VmaDefragmentationContext_T( + VmaAllocator hAllocator, + const VmaDefragmentationInfo& info); + ~VmaDefragmentationContext_T(); + + void GetStats(VmaDefragmentationStats& outStats) { outStats = m_GlobalStats; } + + VkResult DefragmentPassBegin(VmaDefragmentationPassMoveInfo& moveInfo); + VkResult DefragmentPassEnd(VmaDefragmentationPassMoveInfo& moveInfo); + +private: + // Max number of allocations to ignore due to size constraints before ending single pass + static const uint8_t MAX_ALLOCS_TO_IGNORE = 16; + enum class CounterStatus { Pass, Ignore, End }; + + struct FragmentedBlock + { + uint32_t data; + VmaDeviceMemoryBlock* block; + }; + struct StateBalanced + { + VkDeviceSize avgFreeSize = 0; + VkDeviceSize avgAllocSize = UINT64_MAX; + }; + struct StateExtensive + { + enum class Operation : uint8_t + { + FindFreeBlockBuffer, FindFreeBlockTexture, FindFreeBlockAll, + MoveBuffers, MoveTextures, MoveAll, + Cleanup, Done + }; + + Operation operation = Operation::FindFreeBlockTexture; + size_t firstFreeBlock = SIZE_MAX; + }; + struct MoveAllocationData + { + VkDeviceSize size; + VkDeviceSize alignment; + VmaSuballocationType type; + VmaAllocationCreateFlags flags; + VmaDefragmentationMove move = {}; + }; + + const VkDeviceSize m_MaxPassBytes; + const uint32_t m_MaxPassAllocations; + + VmaStlAllocator m_MoveAllocator; + VmaVector> m_Moves; + + uint8_t m_IgnoredAllocs = 0; + uint32_t m_Algorithm; + uint32_t m_BlockVectorCount; + VmaBlockVector* m_PoolBlockVector; + VmaBlockVector** m_pBlockVectors; + size_t m_ImmovableBlockCount = 0; + VmaDefragmentationStats m_GlobalStats = { 0 }; + VmaDefragmentationStats m_PassStats = { 0 }; + void* m_AlgorithmState = VMA_NULL; + + static MoveAllocationData GetMoveData(VmaAllocHandle handle, VmaBlockMetadata* metadata); + CounterStatus CheckCounters(VkDeviceSize bytes); + bool IncrementCounters(VkDeviceSize bytes); + bool ReallocWithinBlock(VmaBlockVector& vector, VmaDeviceMemoryBlock* block); + bool AllocInOtherBlock(size_t start, size_t end, MoveAllocationData& data, VmaBlockVector& vector); + + bool ComputeDefragmentation(VmaBlockVector& vector, size_t index); + bool ComputeDefragmentation_Fast(VmaBlockVector& vector); + bool ComputeDefragmentation_Balanced(VmaBlockVector& vector, size_t index, bool update); + bool ComputeDefragmentation_Full(VmaBlockVector& vector); + bool ComputeDefragmentation_Extensive(VmaBlockVector& vector, size_t index); + + void UpdateVectorStatistics(VmaBlockVector& vector, StateBalanced& state); + bool MoveDataToFreeBlocks(VmaSuballocationType currentType, + VmaBlockVector& vector, size_t firstFreeBlock, + bool& texturePresent, bool& bufferPresent, bool& otherPresent); +}; +#endif // _VMA_DEFRAGMENTATION_CONTEXT + +#ifndef _VMA_POOL_T struct VmaPool_T { + friend struct VmaPoolListItemTraits; VMA_CLASS_NO_COPY(VmaPool_T) public: VmaBlockVector m_BlockVector; + VmaDedicatedAllocationList m_DedicatedAllocations; VmaPool_T( VmaAllocator hAllocator, @@ -5674,616 +11097,24 @@ private: char* m_Name; VmaPool_T* m_PrevPool = VMA_NULL; VmaPool_T* m_NextPool = VMA_NULL; - friend struct VmaPoolListItemTraits; }; struct VmaPoolListItemTraits { typedef VmaPool_T ItemType; + static ItemType* GetPrev(const ItemType* item) { return item->m_PrevPool; } static ItemType* GetNext(const ItemType* item) { return item->m_NextPool; } static ItemType*& AccessPrev(ItemType* item) { return item->m_PrevPool; } static ItemType*& AccessNext(ItemType* item) { return item->m_NextPool; } }; +#endif // _VMA_POOL_T -/* -Performs defragmentation: - -- Updates `pBlockVector->m_pMetadata`. -- Updates allocations by calling ChangeBlockAllocation() or ChangeOffset(). -- Does not move actual data, only returns requested moves as `moves`. -*/ -class VmaDefragmentationAlgorithm -{ - VMA_CLASS_NO_COPY(VmaDefragmentationAlgorithm) -public: - VmaDefragmentationAlgorithm( - VmaAllocator hAllocator, - VmaBlockVector* pBlockVector, - uint32_t currentFrameIndex) : - m_hAllocator(hAllocator), - m_pBlockVector(pBlockVector), - m_CurrentFrameIndex(currentFrameIndex) - { - } - virtual ~VmaDefragmentationAlgorithm() - { - } - - virtual void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) = 0; - virtual void AddAll() = 0; - - virtual VkResult Defragment( - VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, - VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove, - VmaDefragmentationFlags flags) = 0; - - virtual VkDeviceSize GetBytesMoved() const = 0; - virtual uint32_t GetAllocationsMoved() const = 0; - -protected: - VmaAllocator const m_hAllocator; - VmaBlockVector* const m_pBlockVector; - const uint32_t m_CurrentFrameIndex; - - struct AllocationInfo - { - VmaAllocation m_hAllocation; - VkBool32* m_pChanged; - - AllocationInfo() : - m_hAllocation(VK_NULL_HANDLE), - m_pChanged(VMA_NULL) - { - } - AllocationInfo(VmaAllocation hAlloc, VkBool32* pChanged) : - m_hAllocation(hAlloc), - m_pChanged(pChanged) - { - } - }; -}; - -class VmaDefragmentationAlgorithm_Generic : public VmaDefragmentationAlgorithm -{ - VMA_CLASS_NO_COPY(VmaDefragmentationAlgorithm_Generic) -public: - VmaDefragmentationAlgorithm_Generic( - VmaAllocator hAllocator, - VmaBlockVector* pBlockVector, - uint32_t currentFrameIndex, - bool overlappingMoveSupported); - virtual ~VmaDefragmentationAlgorithm_Generic(); - - virtual void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged); - virtual void AddAll() { m_AllAllocations = true; } - - virtual VkResult Defragment( - VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, - VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove, - VmaDefragmentationFlags flags); - - virtual VkDeviceSize GetBytesMoved() const { return m_BytesMoved; } - virtual uint32_t GetAllocationsMoved() const { return m_AllocationsMoved; } - -private: - uint32_t m_AllocationCount; - bool m_AllAllocations; - - VkDeviceSize m_BytesMoved; - uint32_t m_AllocationsMoved; - - struct AllocationInfoSizeGreater - { - bool operator()(const AllocationInfo& lhs, const AllocationInfo& rhs) const - { - return lhs.m_hAllocation->GetSize() > rhs.m_hAllocation->GetSize(); - } - }; - - struct AllocationInfoOffsetGreater - { - bool operator()(const AllocationInfo& lhs, const AllocationInfo& rhs) const - { - return lhs.m_hAllocation->GetOffset() > rhs.m_hAllocation->GetOffset(); - } - }; - - struct BlockInfo - { - size_t m_OriginalBlockIndex; - VmaDeviceMemoryBlock* m_pBlock; - bool m_HasNonMovableAllocations; - VmaVector< AllocationInfo, VmaStlAllocator > m_Allocations; - - BlockInfo(const VkAllocationCallbacks* pAllocationCallbacks) : - m_OriginalBlockIndex(SIZE_MAX), - m_pBlock(VMA_NULL), - m_HasNonMovableAllocations(true), - m_Allocations(pAllocationCallbacks) - { - } - - void CalcHasNonMovableAllocations() - { - const size_t blockAllocCount = m_pBlock->m_pMetadata->GetAllocationCount(); - const size_t defragmentAllocCount = m_Allocations.size(); - m_HasNonMovableAllocations = blockAllocCount != defragmentAllocCount; - } - - void SortAllocationsBySizeDescending() - { - VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoSizeGreater()); - } - - void SortAllocationsByOffsetDescending() - { - VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoOffsetGreater()); - } - }; - - struct BlockPointerLess - { - bool operator()(const BlockInfo* pLhsBlockInfo, const VmaDeviceMemoryBlock* pRhsBlock) const - { - return pLhsBlockInfo->m_pBlock < pRhsBlock; - } - bool operator()(const BlockInfo* pLhsBlockInfo, const BlockInfo* pRhsBlockInfo) const - { - return pLhsBlockInfo->m_pBlock < pRhsBlockInfo->m_pBlock; - } - }; - - // 1. Blocks with some non-movable allocations go first. - // 2. Blocks with smaller sumFreeSize go first. - struct BlockInfoCompareMoveDestination - { - bool operator()(const BlockInfo* pLhsBlockInfo, const BlockInfo* pRhsBlockInfo) const - { - if(pLhsBlockInfo->m_HasNonMovableAllocations && !pRhsBlockInfo->m_HasNonMovableAllocations) - { - return true; - } - if(!pLhsBlockInfo->m_HasNonMovableAllocations && pRhsBlockInfo->m_HasNonMovableAllocations) - { - return false; - } - if(pLhsBlockInfo->m_pBlock->m_pMetadata->GetSumFreeSize() < pRhsBlockInfo->m_pBlock->m_pMetadata->GetSumFreeSize()) - { - return true; - } - return false; - } - }; - - typedef VmaVector< BlockInfo*, VmaStlAllocator > BlockInfoVector; - BlockInfoVector m_Blocks; - - VkResult DefragmentRound( - VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, - VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove, - bool freeOldAllocations); - - size_t CalcBlocksWithNonMovableCount() const; - - static bool MoveMakesSense( - size_t dstBlockIndex, VkDeviceSize dstOffset, - size_t srcBlockIndex, VkDeviceSize srcOffset); -}; - -class VmaDefragmentationAlgorithm_Fast : public VmaDefragmentationAlgorithm -{ - VMA_CLASS_NO_COPY(VmaDefragmentationAlgorithm_Fast) -public: - VmaDefragmentationAlgorithm_Fast( - VmaAllocator hAllocator, - VmaBlockVector* pBlockVector, - uint32_t currentFrameIndex, - bool overlappingMoveSupported); - virtual ~VmaDefragmentationAlgorithm_Fast(); - - virtual void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) { ++m_AllocationCount; } - virtual void AddAll() { m_AllAllocations = true; } - - virtual VkResult Defragment( - VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, - VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove, - VmaDefragmentationFlags flags); - - virtual VkDeviceSize GetBytesMoved() const { return m_BytesMoved; } - virtual uint32_t GetAllocationsMoved() const { return m_AllocationsMoved; } - -private: - struct BlockInfo - { - size_t origBlockIndex; - }; - - class FreeSpaceDatabase - { - public: - FreeSpaceDatabase() - { - FreeSpace s = {}; - s.blockInfoIndex = SIZE_MAX; - for(size_t i = 0; i < MAX_COUNT; ++i) - { - m_FreeSpaces[i] = s; - } - } - - void Register(size_t blockInfoIndex, VkDeviceSize offset, VkDeviceSize size) - { - if(size < VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) - { - return; - } - - // Find first invalid or the smallest structure. - size_t bestIndex = SIZE_MAX; - for(size_t i = 0; i < MAX_COUNT; ++i) - { - // Empty structure. - if(m_FreeSpaces[i].blockInfoIndex == SIZE_MAX) - { - bestIndex = i; - break; - } - if(m_FreeSpaces[i].size < size && - (bestIndex == SIZE_MAX || m_FreeSpaces[bestIndex].size > m_FreeSpaces[i].size)) - { - bestIndex = i; - } - } - - if(bestIndex != SIZE_MAX) - { - m_FreeSpaces[bestIndex].blockInfoIndex = blockInfoIndex; - m_FreeSpaces[bestIndex].offset = offset; - m_FreeSpaces[bestIndex].size = size; - } - } - - bool Fetch(VkDeviceSize alignment, VkDeviceSize size, - size_t& outBlockInfoIndex, VkDeviceSize& outDstOffset) - { - size_t bestIndex = SIZE_MAX; - VkDeviceSize bestFreeSpaceAfter = 0; - for(size_t i = 0; i < MAX_COUNT; ++i) - { - // Structure is valid. - if(m_FreeSpaces[i].blockInfoIndex != SIZE_MAX) - { - const VkDeviceSize dstOffset = VmaAlignUp(m_FreeSpaces[i].offset, alignment); - // Allocation fits into this structure. - if(dstOffset + size <= m_FreeSpaces[i].offset + m_FreeSpaces[i].size) - { - const VkDeviceSize freeSpaceAfter = (m_FreeSpaces[i].offset + m_FreeSpaces[i].size) - - (dstOffset + size); - if(bestIndex == SIZE_MAX || freeSpaceAfter > bestFreeSpaceAfter) - { - bestIndex = i; - bestFreeSpaceAfter = freeSpaceAfter; - } - } - } - } - - if(bestIndex != SIZE_MAX) - { - outBlockInfoIndex = m_FreeSpaces[bestIndex].blockInfoIndex; - outDstOffset = VmaAlignUp(m_FreeSpaces[bestIndex].offset, alignment); - - if(bestFreeSpaceAfter >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) - { - // Leave this structure for remaining empty space. - const VkDeviceSize alignmentPlusSize = (outDstOffset - m_FreeSpaces[bestIndex].offset) + size; - m_FreeSpaces[bestIndex].offset += alignmentPlusSize; - m_FreeSpaces[bestIndex].size -= alignmentPlusSize; - } - else - { - // This structure becomes invalid. - m_FreeSpaces[bestIndex].blockInfoIndex = SIZE_MAX; - } - - return true; - } - - return false; - } - - private: - static const size_t MAX_COUNT = 4; - - struct FreeSpace - { - size_t blockInfoIndex; // SIZE_MAX means this structure is invalid. - VkDeviceSize offset; - VkDeviceSize size; - } m_FreeSpaces[MAX_COUNT]; - }; - - const bool m_OverlappingMoveSupported; - - uint32_t m_AllocationCount; - bool m_AllAllocations; - - VkDeviceSize m_BytesMoved; - uint32_t m_AllocationsMoved; - - VmaVector< BlockInfo, VmaStlAllocator > m_BlockInfos; - - void PreprocessMetadata(); - void PostprocessMetadata(); - void InsertSuballoc(VmaBlockMetadata_Generic* pMetadata, const VmaSuballocation& suballoc); -}; - -struct VmaBlockDefragmentationContext -{ - enum BLOCK_FLAG - { - BLOCK_FLAG_USED = 0x00000001, - }; - uint32_t flags; - VkBuffer hBuffer; -}; - -class VmaBlockVectorDefragmentationContext -{ - VMA_CLASS_NO_COPY(VmaBlockVectorDefragmentationContext) -public: - VkResult res; - bool mutexLocked; - VmaVector< VmaBlockDefragmentationContext, VmaStlAllocator > blockContexts; - VmaVector< VmaDefragmentationMove, VmaStlAllocator > defragmentationMoves; - uint32_t defragmentationMovesProcessed; - uint32_t defragmentationMovesCommitted; - bool hasDefragmentationPlan; - - VmaBlockVectorDefragmentationContext( - VmaAllocator hAllocator, - VmaPool hCustomPool, // Optional. - VmaBlockVector* pBlockVector, - uint32_t currFrameIndex); - ~VmaBlockVectorDefragmentationContext(); - - VmaPool GetCustomPool() const { return m_hCustomPool; } - VmaBlockVector* GetBlockVector() const { return m_pBlockVector; } - VmaDefragmentationAlgorithm* GetAlgorithm() const { return m_pAlgorithm; } - - void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged); - void AddAll() { m_AllAllocations = true; } - - void Begin(bool overlappingMoveSupported, VmaDefragmentationFlags flags); - -private: - const VmaAllocator m_hAllocator; - // Null if not from custom pool. - const VmaPool m_hCustomPool; - // Redundant, for convenience not to fetch from m_hCustomPool->m_BlockVector or m_hAllocator->m_pBlockVectors. - VmaBlockVector* const m_pBlockVector; - const uint32_t m_CurrFrameIndex; - // Owner of this object. - VmaDefragmentationAlgorithm* m_pAlgorithm; - - struct AllocInfo - { - VmaAllocation hAlloc; - VkBool32* pChanged; - }; - // Used between constructor and Begin. - VmaVector< AllocInfo, VmaStlAllocator > m_Allocations; - bool m_AllAllocations; -}; - -struct VmaDefragmentationContext_T -{ -private: - VMA_CLASS_NO_COPY(VmaDefragmentationContext_T) -public: - VmaDefragmentationContext_T( - VmaAllocator hAllocator, - uint32_t currFrameIndex, - uint32_t flags, - VmaDefragmentationStats* pStats); - ~VmaDefragmentationContext_T(); - - void AddPools(uint32_t poolCount, const VmaPool* pPools); - void AddAllocations( - uint32_t allocationCount, - const VmaAllocation* pAllocations, - VkBool32* pAllocationsChanged); - - /* - Returns: - - `VK_SUCCESS` if succeeded and object can be destroyed immediately. - - `VK_NOT_READY` if succeeded but the object must remain alive until vmaDefragmentationEnd(). - - Negative value if error occurred and object can be destroyed immediately. - */ - VkResult Defragment( - VkDeviceSize maxCpuBytesToMove, uint32_t maxCpuAllocationsToMove, - VkDeviceSize maxGpuBytesToMove, uint32_t maxGpuAllocationsToMove, - VkCommandBuffer commandBuffer, VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags); - - VkResult DefragmentPassBegin(VmaDefragmentationPassInfo* pInfo); - VkResult DefragmentPassEnd(); - -private: - const VmaAllocator m_hAllocator; - const uint32_t m_CurrFrameIndex; - const uint32_t m_Flags; - VmaDefragmentationStats* const m_pStats; - - VkDeviceSize m_MaxCpuBytesToMove; - uint32_t m_MaxCpuAllocationsToMove; - VkDeviceSize m_MaxGpuBytesToMove; - uint32_t m_MaxGpuAllocationsToMove; - - // Owner of these objects. - VmaBlockVectorDefragmentationContext* m_DefaultPoolContexts[VK_MAX_MEMORY_TYPES]; - // Owner of these objects. - VmaVector< VmaBlockVectorDefragmentationContext*, VmaStlAllocator > m_CustomPoolContexts; -}; - -#if VMA_RECORDING_ENABLED - -class VmaRecorder -{ -public: - VmaRecorder(); - VkResult Init(const VmaRecordSettings& settings, bool useMutex); - void WriteConfiguration( - const VkPhysicalDeviceProperties& devProps, - const VkPhysicalDeviceMemoryProperties& memProps, - uint32_t vulkanApiVersion, - bool dedicatedAllocationExtensionEnabled, - bool bindMemory2ExtensionEnabled, - bool memoryBudgetExtensionEnabled, - bool deviceCoherentMemoryExtensionEnabled); - ~VmaRecorder(); - - void RecordCreateAllocator(uint32_t frameIndex); - void RecordDestroyAllocator(uint32_t frameIndex); - void RecordCreatePool(uint32_t frameIndex, - const VmaPoolCreateInfo& createInfo, - VmaPool pool); - void RecordDestroyPool(uint32_t frameIndex, VmaPool pool); - void RecordAllocateMemory(uint32_t frameIndex, - const VkMemoryRequirements& vkMemReq, - const VmaAllocationCreateInfo& createInfo, - VmaAllocation allocation); - void RecordAllocateMemoryPages(uint32_t frameIndex, - const VkMemoryRequirements& vkMemReq, - const VmaAllocationCreateInfo& createInfo, - uint64_t allocationCount, - const VmaAllocation* pAllocations); - void RecordAllocateMemoryForBuffer(uint32_t frameIndex, - const VkMemoryRequirements& vkMemReq, - bool requiresDedicatedAllocation, - bool prefersDedicatedAllocation, - const VmaAllocationCreateInfo& createInfo, - VmaAllocation allocation); - void RecordAllocateMemoryForImage(uint32_t frameIndex, - const VkMemoryRequirements& vkMemReq, - bool requiresDedicatedAllocation, - bool prefersDedicatedAllocation, - const VmaAllocationCreateInfo& createInfo, - VmaAllocation allocation); - void RecordFreeMemory(uint32_t frameIndex, - VmaAllocation allocation); - void RecordFreeMemoryPages(uint32_t frameIndex, - uint64_t allocationCount, - const VmaAllocation* pAllocations); - void RecordSetAllocationUserData(uint32_t frameIndex, - VmaAllocation allocation, - const void* pUserData); - void RecordCreateLostAllocation(uint32_t frameIndex, - VmaAllocation allocation); - void RecordMapMemory(uint32_t frameIndex, - VmaAllocation allocation); - void RecordUnmapMemory(uint32_t frameIndex, - VmaAllocation allocation); - void RecordFlushAllocation(uint32_t frameIndex, - VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size); - void RecordInvalidateAllocation(uint32_t frameIndex, - VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size); - void RecordCreateBuffer(uint32_t frameIndex, - const VkBufferCreateInfo& bufCreateInfo, - const VmaAllocationCreateInfo& allocCreateInfo, - VmaAllocation allocation); - void RecordCreateImage(uint32_t frameIndex, - const VkImageCreateInfo& imageCreateInfo, - const VmaAllocationCreateInfo& allocCreateInfo, - VmaAllocation allocation); - void RecordDestroyBuffer(uint32_t frameIndex, - VmaAllocation allocation); - void RecordDestroyImage(uint32_t frameIndex, - VmaAllocation allocation); - void RecordTouchAllocation(uint32_t frameIndex, - VmaAllocation allocation); - void RecordGetAllocationInfo(uint32_t frameIndex, - VmaAllocation allocation); - void RecordMakePoolAllocationsLost(uint32_t frameIndex, - VmaPool pool); - void RecordDefragmentationBegin(uint32_t frameIndex, - const VmaDefragmentationInfo2& info, - VmaDefragmentationContext ctx); - void RecordDefragmentationEnd(uint32_t frameIndex, - VmaDefragmentationContext ctx); - void RecordSetPoolName(uint32_t frameIndex, - VmaPool pool, - const char* name); - -private: - struct CallParams - { - uint32_t threadId; - double time; - }; - - class UserDataString - { - public: - UserDataString(VmaAllocationCreateFlags allocFlags, const void* pUserData); - const char* GetString() const { return m_Str; } - - private: - char m_PtrStr[17]; - const char* m_Str; - }; - - bool m_UseMutex; - VmaRecordFlags m_Flags; - FILE* m_File; - VMA_MUTEX m_FileMutex; - std::chrono::time_point m_RecordingStartTime; - - void GetBasicParams(CallParams& outParams); - - // T must be a pointer type, e.g. VmaAllocation, VmaPool. - template - void PrintPointerList(uint64_t count, const T* pItems) - { - if(count) - { - fprintf(m_File, "%p", pItems[0]); - for(uint64_t i = 1; i < count; ++i) - { - fprintf(m_File, " %p", pItems[i]); - } - } - } - - void PrintPointerList(uint64_t count, const VmaAllocation* pItems); - void Flush(); -}; - -#endif // #if VMA_RECORDING_ENABLED - -/* -Thread-safe wrapper over VmaPoolAllocator free list, for allocation of VmaAllocation_T objects. -*/ -class VmaAllocationObjectAllocator -{ - VMA_CLASS_NO_COPY(VmaAllocationObjectAllocator) -public: - VmaAllocationObjectAllocator(const VkAllocationCallbacks* pAllocationCallbacks); - - template VmaAllocation Allocate(Types&&... args); - void Free(VmaAllocation hAlloc); - -private: - VMA_MUTEX m_Mutex; - VmaPoolAllocator m_Allocator; -}; - +#ifndef _VMA_CURRENT_BUDGET_DATA struct VmaCurrentBudgetData { + VMA_ATOMIC_UINT32 m_BlockCount[VK_MAX_MEMORY_HEAPS]; + VMA_ATOMIC_UINT32 m_AllocationCount[VK_MAX_MEMORY_HEAPS]; VMA_ATOMIC_UINT64 m_BlockBytes[VK_MAX_MEMORY_HEAPS]; VMA_ATOMIC_UINT64 m_AllocationBytes[VK_MAX_MEMORY_HEAPS]; @@ -6293,44 +11124,229 @@ struct VmaCurrentBudgetData uint64_t m_VulkanUsage[VK_MAX_MEMORY_HEAPS]; uint64_t m_VulkanBudget[VK_MAX_MEMORY_HEAPS]; uint64_t m_BlockBytesAtBudgetFetch[VK_MAX_MEMORY_HEAPS]; -#endif // #if VMA_MEMORY_BUDGET +#endif // VMA_MEMORY_BUDGET - VmaCurrentBudgetData() - { - for(uint32_t heapIndex = 0; heapIndex < VK_MAX_MEMORY_HEAPS; ++heapIndex) - { - m_BlockBytes[heapIndex] = 0; - m_AllocationBytes[heapIndex] = 0; -#if VMA_MEMORY_BUDGET - m_VulkanUsage[heapIndex] = 0; - m_VulkanBudget[heapIndex] = 0; - m_BlockBytesAtBudgetFetch[heapIndex] = 0; -#endif - } + VmaCurrentBudgetData(); -#if VMA_MEMORY_BUDGET - m_OperationsSinceBudgetFetch = 0; -#endif - } - - void AddAllocation(uint32_t heapIndex, VkDeviceSize allocationSize) - { - m_AllocationBytes[heapIndex] += allocationSize; -#if VMA_MEMORY_BUDGET - ++m_OperationsSinceBudgetFetch; -#endif - } - - void RemoveAllocation(uint32_t heapIndex, VkDeviceSize allocationSize) - { - VMA_ASSERT(m_AllocationBytes[heapIndex] >= allocationSize); // DELME - m_AllocationBytes[heapIndex] -= allocationSize; -#if VMA_MEMORY_BUDGET - ++m_OperationsSinceBudgetFetch; -#endif - } + void AddAllocation(uint32_t heapIndex, VkDeviceSize allocationSize); + void RemoveAllocation(uint32_t heapIndex, VkDeviceSize allocationSize); }; +#ifndef _VMA_CURRENT_BUDGET_DATA_FUNCTIONS +VmaCurrentBudgetData::VmaCurrentBudgetData() +{ + for (uint32_t heapIndex = 0; heapIndex < VK_MAX_MEMORY_HEAPS; ++heapIndex) + { + m_BlockCount[heapIndex] = 0; + m_AllocationCount[heapIndex] = 0; + m_BlockBytes[heapIndex] = 0; + m_AllocationBytes[heapIndex] = 0; +#if VMA_MEMORY_BUDGET + m_VulkanUsage[heapIndex] = 0; + m_VulkanBudget[heapIndex] = 0; + m_BlockBytesAtBudgetFetch[heapIndex] = 0; +#endif + } + +#if VMA_MEMORY_BUDGET + m_OperationsSinceBudgetFetch = 0; +#endif +} + +void VmaCurrentBudgetData::AddAllocation(uint32_t heapIndex, VkDeviceSize allocationSize) +{ + m_AllocationBytes[heapIndex] += allocationSize; + ++m_AllocationCount[heapIndex]; +#if VMA_MEMORY_BUDGET + ++m_OperationsSinceBudgetFetch; +#endif +} + +void VmaCurrentBudgetData::RemoveAllocation(uint32_t heapIndex, VkDeviceSize allocationSize) +{ + VMA_ASSERT(m_AllocationBytes[heapIndex] >= allocationSize); + m_AllocationBytes[heapIndex] -= allocationSize; + VMA_ASSERT(m_AllocationCount[heapIndex] > 0); + --m_AllocationCount[heapIndex]; +#if VMA_MEMORY_BUDGET + ++m_OperationsSinceBudgetFetch; +#endif +} +#endif // _VMA_CURRENT_BUDGET_DATA_FUNCTIONS +#endif // _VMA_CURRENT_BUDGET_DATA + +#ifndef _VMA_ALLOCATION_OBJECT_ALLOCATOR +/* +Thread-safe wrapper over VmaPoolAllocator free list, for allocation of VmaAllocation_T objects. +*/ +class VmaAllocationObjectAllocator +{ + VMA_CLASS_NO_COPY(VmaAllocationObjectAllocator) +public: + VmaAllocationObjectAllocator(const VkAllocationCallbacks* pAllocationCallbacks) + : m_Allocator(pAllocationCallbacks, 1024) {} + + template VmaAllocation Allocate(Types&&... args); + void Free(VmaAllocation hAlloc); + +private: + VMA_MUTEX m_Mutex; + VmaPoolAllocator m_Allocator; +}; + +template +VmaAllocation VmaAllocationObjectAllocator::Allocate(Types&&... args) +{ + VmaMutexLock mutexLock(m_Mutex); + return m_Allocator.Alloc(std::forward(args)...); +} + +void VmaAllocationObjectAllocator::Free(VmaAllocation hAlloc) +{ + VmaMutexLock mutexLock(m_Mutex); + m_Allocator.Free(hAlloc); +} +#endif // _VMA_ALLOCATION_OBJECT_ALLOCATOR + +#ifndef _VMA_VIRTUAL_BLOCK_T +struct VmaVirtualBlock_T +{ + VMA_CLASS_NO_COPY(VmaVirtualBlock_T) +public: + const bool m_AllocationCallbacksSpecified; + const VkAllocationCallbacks m_AllocationCallbacks; + + VmaVirtualBlock_T(const VmaVirtualBlockCreateInfo& createInfo); + ~VmaVirtualBlock_T(); + + VkResult Init() { return VK_SUCCESS; } + bool IsEmpty() const { return m_Metadata->IsEmpty(); } + void Free(VmaVirtualAllocation allocation) { m_Metadata->Free((VmaAllocHandle)allocation); } + void SetAllocationUserData(VmaVirtualAllocation allocation, void* userData) { m_Metadata->SetAllocationUserData((VmaAllocHandle)allocation, userData); } + void Clear() { m_Metadata->Clear(); } + + const VkAllocationCallbacks* GetAllocationCallbacks() const; + void GetAllocationInfo(VmaVirtualAllocation allocation, VmaVirtualAllocationInfo& outInfo); + VkResult Allocate(const VmaVirtualAllocationCreateInfo& createInfo, VmaVirtualAllocation& outAllocation, + VkDeviceSize* outOffset); + void GetStatistics(VmaStatistics& outStats) const; + void CalculateDetailedStatistics(VmaDetailedStatistics& outStats) const; +#if VMA_STATS_STRING_ENABLED + void BuildStatsString(bool detailedMap, VmaStringBuilder& sb) const; +#endif + +private: + VmaBlockMetadata* m_Metadata; +}; + +#ifndef _VMA_VIRTUAL_BLOCK_T_FUNCTIONS +VmaVirtualBlock_T::VmaVirtualBlock_T(const VmaVirtualBlockCreateInfo& createInfo) + : m_AllocationCallbacksSpecified(createInfo.pAllocationCallbacks != VMA_NULL), + m_AllocationCallbacks(createInfo.pAllocationCallbacks != VMA_NULL ? *createInfo.pAllocationCallbacks : VmaEmptyAllocationCallbacks) +{ + const uint32_t algorithm = createInfo.flags & VMA_VIRTUAL_BLOCK_CREATE_ALGORITHM_MASK; + switch (algorithm) + { + default: + VMA_ASSERT(0); + case 0: + m_Metadata = vma_new(GetAllocationCallbacks(), VmaBlockMetadata_TLSF)(VK_NULL_HANDLE, 1, true); + break; + case VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT: + m_Metadata = vma_new(GetAllocationCallbacks(), VmaBlockMetadata_Linear)(VK_NULL_HANDLE, 1, true); + break; + } + + m_Metadata->Init(createInfo.size); +} + +VmaVirtualBlock_T::~VmaVirtualBlock_T() +{ + // Define macro VMA_DEBUG_LOG to receive the list of the unfreed allocations + if (!m_Metadata->IsEmpty()) + m_Metadata->DebugLogAllAllocations(); + // This is the most important assert in the entire library. + // Hitting it means you have some memory leak - unreleased virtual allocations. + VMA_ASSERT(m_Metadata->IsEmpty() && "Some virtual allocations were not freed before destruction of this virtual block!"); + + vma_delete(GetAllocationCallbacks(), m_Metadata); +} + +const VkAllocationCallbacks* VmaVirtualBlock_T::GetAllocationCallbacks() const +{ + return m_AllocationCallbacksSpecified ? &m_AllocationCallbacks : VMA_NULL; +} + +void VmaVirtualBlock_T::GetAllocationInfo(VmaVirtualAllocation allocation, VmaVirtualAllocationInfo& outInfo) +{ + m_Metadata->GetAllocationInfo((VmaAllocHandle)allocation, outInfo); +} + +VkResult VmaVirtualBlock_T::Allocate(const VmaVirtualAllocationCreateInfo& createInfo, VmaVirtualAllocation& outAllocation, + VkDeviceSize* outOffset) +{ + VmaAllocationRequest request = {}; + if (m_Metadata->CreateAllocationRequest( + createInfo.size, // allocSize + VMA_MAX(createInfo.alignment, (VkDeviceSize)1), // allocAlignment + (createInfo.flags & VMA_VIRTUAL_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0, // upperAddress + VMA_SUBALLOCATION_TYPE_UNKNOWN, // allocType - unimportant + createInfo.flags & VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MASK, // strategy + &request)) + { + m_Metadata->Alloc(request, + VMA_SUBALLOCATION_TYPE_UNKNOWN, // type - unimportant + createInfo.pUserData); + outAllocation = (VmaVirtualAllocation)request.allocHandle; + if(outOffset) + *outOffset = m_Metadata->GetAllocationOffset(request.allocHandle); + return VK_SUCCESS; + } + outAllocation = (VmaVirtualAllocation)VK_NULL_HANDLE; + if (outOffset) + *outOffset = UINT64_MAX; + return VK_ERROR_OUT_OF_DEVICE_MEMORY; +} + +void VmaVirtualBlock_T::GetStatistics(VmaStatistics& outStats) const +{ + VmaClearStatistics(outStats); + m_Metadata->AddStatistics(outStats); +} + +void VmaVirtualBlock_T::CalculateDetailedStatistics(VmaDetailedStatistics& outStats) const +{ + VmaClearDetailedStatistics(outStats); + m_Metadata->AddDetailedStatistics(outStats); +} + +#if VMA_STATS_STRING_ENABLED +void VmaVirtualBlock_T::BuildStatsString(bool detailedMap, VmaStringBuilder& sb) const +{ + VmaJsonWriter json(GetAllocationCallbacks(), sb); + json.BeginObject(); + + VmaDetailedStatistics stats; + CalculateDetailedStatistics(stats); + + json.WriteString("Stats"); + VmaPrintDetailedStatistics(json, stats); + + if (detailedMap) + { + json.WriteString("Details"); + json.BeginObject(); + m_Metadata->PrintDetailedMap(json); + json.EndObject(); + } + + json.EndObject(); +} +#endif // VMA_STATS_STRING_ENABLED +#endif // _VMA_VIRTUAL_BLOCK_T_FUNCTIONS +#endif // _VMA_VIRTUAL_BLOCK_T + + // Main allocator object. struct VmaAllocator_T { @@ -6359,10 +11375,7 @@ public: // Default pools. VmaBlockVector* m_pBlockVectors[VK_MAX_MEMORY_TYPES]; - - typedef VmaIntrusiveLinkedList DedicatedAllocationLinkedList; - DedicatedAllocationLinkedList m_DedicatedAllocations[VK_MAX_MEMORY_TYPES]; - VMA_RW_MUTEX m_DedicatedAllocationsMutex[VK_MAX_MEMORY_TYPES]; + VmaDedicatedAllocationList m_DedicatedAllocations[VK_MAX_MEMORY_TYPES]; VmaCurrentBudgetData m_Budget; VMA_ATOMIC_UINT32 m_DeviceMemoryCount; // Total number of VkDeviceMemory objects. @@ -6373,7 +11386,7 @@ public: const VkAllocationCallbacks* GetAllocationCallbacks() const { - return m_AllocationCallbacksSpecified ? &m_AllocationCallbacks : 0; + return m_AllocationCallbacksSpecified ? &m_AllocationCallbacks : VMA_NULL; } const VmaVulkanFunctions& GetVulkanFunctions() const { @@ -6418,10 +11431,6 @@ public: uint32_t GetGlobalMemoryTypeBits() const { return m_GlobalMemoryTypeBits; } -#if VMA_RECORDING_ENABLED - VmaRecorder* GetRecorder() const { return m_pRecorder; } -#endif - void GetBufferMemoryRequirements( VkBuffer hBuffer, VkMemoryRequirements& memReq, @@ -6432,6 +11441,11 @@ public: VkMemoryRequirements& memReq, bool& requiresDedicatedAllocation, bool& prefersDedicatedAllocation) const; + VkResult FindMemoryTypeIndex( + uint32_t memoryTypeBits, + const VmaAllocationCreateInfo* pAllocationCreateInfo, + VkFlags bufImgUsage, // VkBufferCreateInfo::usage or VkImageCreateInfo::usage. UINT32_MAX if unknown. + uint32_t* pMemoryTypeIndex) const; // Main allocation function. VkResult AllocateMemory( @@ -6439,8 +11453,8 @@ public: bool requiresDedicatedAllocation, bool prefersDedicatedAllocation, VkBuffer dedicatedBuffer, - VkBufferUsageFlags dedicatedBufferUsage, // UINT32_MAX when unknown. VkImage dedicatedImage, + VkFlags dedicatedBufferImageUsage, // UINT32_MAX if unknown. const VmaAllocationCreateInfo& createInfo, VmaSuballocationType suballocType, size_t allocationCount, @@ -6451,46 +11465,28 @@ public: size_t allocationCount, const VmaAllocation* pAllocations); - void CalculateStats(VmaStats* pStats); + void CalculateStatistics(VmaTotalStatistics* pStats); - void GetBudget( - VmaBudget* outBudget, uint32_t firstHeap, uint32_t heapCount); + void GetHeapBudgets( + VmaBudget* outBudgets, uint32_t firstHeap, uint32_t heapCount); #if VMA_STATS_STRING_ENABLED void PrintDetailedMap(class VmaJsonWriter& json); #endif - VkResult DefragmentationBegin( - const VmaDefragmentationInfo2& info, - VmaDefragmentationStats* pStats, - VmaDefragmentationContext* pContext); - VkResult DefragmentationEnd( - VmaDefragmentationContext context); - - VkResult DefragmentationPassBegin( - VmaDefragmentationPassInfo* pInfo, - VmaDefragmentationContext context); - VkResult DefragmentationPassEnd( - VmaDefragmentationContext context); - void GetAllocationInfo(VmaAllocation hAllocation, VmaAllocationInfo* pAllocationInfo); - bool TouchAllocation(VmaAllocation hAllocation); VkResult CreatePool(const VmaPoolCreateInfo* pCreateInfo, VmaPool* pPool); void DestroyPool(VmaPool pool); - void GetPoolStats(VmaPool pool, VmaPoolStats* pPoolStats); + void GetPoolStatistics(VmaPool pool, VmaStatistics* pPoolStats); + void CalculatePoolStatistics(VmaPool pool, VmaDetailedStatistics* pPoolStats); void SetCurrentFrameIndex(uint32_t frameIndex); uint32_t GetCurrentFrameIndex() const { return m_CurrentFrameIndex.load(); } - void MakePoolAllocationsLost( - VmaPool hPool, - size_t* pLostAllocationCount); VkResult CheckPoolCorruption(VmaPool hPool); VkResult CheckCorruption(uint32_t memoryTypeBits); - void CreateLostAllocation(VmaAllocation* pAllocation); - // Call to Vulkan function vkAllocateMemory with accompanying bookkeeping. VkResult AllocateVulkanMemory(const VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory); // Call to Vulkan function vkFreeMemory with accompanying bookkeeping. @@ -6568,10 +11564,6 @@ private: // Global bit mask AND-ed with any memoryTypeBits to disallow certain memory types. uint32_t m_GlobalMemoryTypeBits; -#if VMA_RECORDING_ENABLED - VmaRecorder* m_pRecorder; -#endif - void ImportVulkanFunctions(const VmaVulkanFunctions* pVulkanFunctions); #if VMA_STATIC_VULKAN_FUNCTIONS == 1 @@ -6589,53 +11581,71 @@ private: VkDeviceSize CalcPreferredBlockSize(uint32_t memTypeIndex); VkResult AllocateMemoryOfType( + VmaPool pool, VkDeviceSize size, VkDeviceSize alignment, - bool dedicatedAllocation, + bool dedicatedPreferred, VkBuffer dedicatedBuffer, - VkBufferUsageFlags dedicatedBufferUsage, VkImage dedicatedImage, + VkFlags dedicatedBufferImageUsage, const VmaAllocationCreateInfo& createInfo, uint32_t memTypeIndex, VmaSuballocationType suballocType, + VmaDedicatedAllocationList& dedicatedAllocations, + VmaBlockVector& blockVector, size_t allocationCount, VmaAllocation* pAllocations); // Helper function only to be used inside AllocateDedicatedMemory. VkResult AllocateDedicatedMemoryPage( + VmaPool pool, VkDeviceSize size, VmaSuballocationType suballocType, uint32_t memTypeIndex, const VkMemoryAllocateInfo& allocInfo, bool map, bool isUserDataString, + bool isMappingAllowed, void* pUserData, VmaAllocation* pAllocation); // Allocates and registers new VkDeviceMemory specifically for dedicated allocations. VkResult AllocateDedicatedMemory( + VmaPool pool, VkDeviceSize size, VmaSuballocationType suballocType, + VmaDedicatedAllocationList& dedicatedAllocations, uint32_t memTypeIndex, - bool withinBudget, bool map, bool isUserDataString, + bool isMappingAllowed, + bool canAliasMemory, void* pUserData, float priority, VkBuffer dedicatedBuffer, - VkBufferUsageFlags dedicatedBufferUsage, VkImage dedicatedImage, + VkFlags dedicatedBufferImageUsage, size_t allocationCount, - VmaAllocation* pAllocations); + VmaAllocation* pAllocations, + const void* pNextChain = nullptr); void FreeDedicatedMemory(const VmaAllocation allocation); + VkResult CalcMemTypeParams( + VmaAllocationCreateInfo& outCreateInfo, + uint32_t memTypeIndex, + VkDeviceSize size, + size_t allocationCount); + VkResult CalcAllocationParams( + VmaAllocationCreateInfo& outCreateInfo, + bool dedicatedRequired, + bool dedicatedPreferred); + /* Calculates and returns bit mask of memory types that can support defragmentation on GPU as they support creation of required buffer for copy operations. */ uint32_t CalculateGpuDefragmentationMemoryTypeBits() const; - uint32_t CalculateGlobalMemoryTypeBits() const; bool GetFlushOrInvalidateRange( @@ -6648,9 +11658,8 @@ private: #endif // #if VMA_MEMORY_BUDGET }; -//////////////////////////////////////////////////////////////////////////////// -// Memory allocation #2 after VmaAllocator_T definition +#ifndef _VMA_MEMORY_FUNCTIONS static void* VmaMalloc(VmaAllocator hAllocator, size_t size, size_t alignment) { return VmaMalloc(&hAllocator->m_AllocationCallbacks, size, alignment); @@ -6693,421 +11702,377 @@ static void vma_delete_array(VmaAllocator hAllocator, T* ptr, size_t count) VmaFree(hAllocator, ptr); } } +#endif // _VMA_MEMORY_FUNCTIONS -//////////////////////////////////////////////////////////////////////////////// -// VmaStringBuilder +#ifndef _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS +VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator) + : m_pMetadata(VMA_NULL), + m_MemoryTypeIndex(UINT32_MAX), + m_Id(0), + m_hMemory(VK_NULL_HANDLE), + m_MapCount(0), + m_pMappedData(VMA_NULL) {} -#if VMA_STATS_STRING_ENABLED - -class VmaStringBuilder +VmaDeviceMemoryBlock::~VmaDeviceMemoryBlock() { -public: - VmaStringBuilder(VmaAllocator alloc) : m_Data(VmaStlAllocator(alloc->GetAllocationCallbacks())) { } - size_t GetLength() const { return m_Data.size(); } - const char* GetData() const { return m_Data.data(); } + VMA_ASSERT(m_MapCount == 0 && "VkDeviceMemory block is being destroyed while it is still mapped."); + VMA_ASSERT(m_hMemory == VK_NULL_HANDLE); +} - void Add(char ch) { m_Data.push_back(ch); } - void Add(const char* pStr); - void AddNewLine() { Add('\n'); } - void AddNumber(uint32_t num); - void AddNumber(uint64_t num); - void AddPointer(const void* ptr); - -private: - VmaVector< char, VmaStlAllocator > m_Data; -}; - -void VmaStringBuilder::Add(const char* pStr) +void VmaDeviceMemoryBlock::Init( + VmaAllocator hAllocator, + VmaPool hParentPool, + uint32_t newMemoryTypeIndex, + VkDeviceMemory newMemory, + VkDeviceSize newSize, + uint32_t id, + uint32_t algorithm, + VkDeviceSize bufferImageGranularity) { - const size_t strLen = strlen(pStr); - if(strLen > 0) + VMA_ASSERT(m_hMemory == VK_NULL_HANDLE); + + m_hParentPool = hParentPool; + m_MemoryTypeIndex = newMemoryTypeIndex; + m_Id = id; + m_hMemory = newMemory; + + switch (algorithm) { - const size_t oldCount = m_Data.size(); - m_Data.resize(oldCount + strLen); - memcpy(m_Data.data() + oldCount, pStr, strLen); + case VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT: + m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Linear)(hAllocator->GetAllocationCallbacks(), + bufferImageGranularity, false); // isVirtual + break; + default: + VMA_ASSERT(0); + // Fall-through. + case 0: + m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_TLSF)(hAllocator->GetAllocationCallbacks(), + bufferImageGranularity, false); // isVirtual } + m_pMetadata->Init(newSize); } -void VmaStringBuilder::AddNumber(uint32_t num) +void VmaDeviceMemoryBlock::Destroy(VmaAllocator allocator) { - char buf[11]; - buf[10] = '\0'; - char *p = &buf[10]; - do + // Define macro VMA_DEBUG_LOG to receive the list of the unfreed allocations + if (!m_pMetadata->IsEmpty()) + m_pMetadata->DebugLogAllAllocations(); + // This is the most important assert in the entire library. + // Hitting it means you have some memory leak - unreleased VmaAllocation objects. + VMA_ASSERT(m_pMetadata->IsEmpty() && "Some allocations were not freed before destruction of this memory block!"); + + VMA_ASSERT(m_hMemory != VK_NULL_HANDLE); + allocator->FreeVulkanMemory(m_MemoryTypeIndex, m_pMetadata->GetSize(), m_hMemory); + m_hMemory = VK_NULL_HANDLE; + + vma_delete(allocator, m_pMetadata); + m_pMetadata = VMA_NULL; +} + +void VmaDeviceMemoryBlock::PostFree(VmaAllocator hAllocator) +{ + if(m_MappingHysteresis.PostFree()) { - *--p = '0' + (num % 10); - num /= 10; - } - while(num); - Add(p); -} - -void VmaStringBuilder::AddNumber(uint64_t num) -{ - char buf[21]; - buf[20] = '\0'; - char *p = &buf[20]; - do - { - *--p = '0' + (num % 10); - num /= 10; - } - while(num); - Add(p); -} - -void VmaStringBuilder::AddPointer(const void* ptr) -{ - char buf[21]; - VmaPtrToStr(buf, sizeof(buf), ptr); - Add(buf); -} - -#endif // #if VMA_STATS_STRING_ENABLED - -//////////////////////////////////////////////////////////////////////////////// -// VmaJsonWriter - -#if VMA_STATS_STRING_ENABLED - -class VmaJsonWriter -{ - VMA_CLASS_NO_COPY(VmaJsonWriter) -public: - VmaJsonWriter(const VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder& sb); - ~VmaJsonWriter(); - - void BeginObject(bool singleLine = false); - void EndObject(); - - void BeginArray(bool singleLine = false); - void EndArray(); - - void WriteString(const char* pStr); - void BeginString(const char* pStr = VMA_NULL); - void ContinueString(const char* pStr); - void ContinueString(uint32_t n); - void ContinueString(uint64_t n); - void ContinueString_Pointer(const void* ptr); - void EndString(const char* pStr = VMA_NULL); - - void WriteNumber(uint32_t n); - void WriteNumber(uint64_t n); - void WriteBool(bool b); - void WriteNull(); - -private: - static const char* const INDENT; - - enum COLLECTION_TYPE - { - COLLECTION_TYPE_OBJECT, - COLLECTION_TYPE_ARRAY, - }; - struct StackItem - { - COLLECTION_TYPE type; - uint32_t valueCount; - bool singleLineMode; - }; - - VmaStringBuilder& m_SB; - VmaVector< StackItem, VmaStlAllocator > m_Stack; - bool m_InsideString; - - void BeginValue(bool isString); - void WriteIndent(bool oneLess = false); -}; - -const char* const VmaJsonWriter::INDENT = " "; - -VmaJsonWriter::VmaJsonWriter(const VkAllocationCallbacks* pAllocationCallbacks, VmaStringBuilder& sb) : - m_SB(sb), - m_Stack(VmaStlAllocator(pAllocationCallbacks)), - m_InsideString(false) -{ -} - -VmaJsonWriter::~VmaJsonWriter() -{ - VMA_ASSERT(!m_InsideString); - VMA_ASSERT(m_Stack.empty()); -} - -void VmaJsonWriter::BeginObject(bool singleLine) -{ - VMA_ASSERT(!m_InsideString); - - BeginValue(false); - m_SB.Add('{'); - - StackItem item; - item.type = COLLECTION_TYPE_OBJECT; - item.valueCount = 0; - item.singleLineMode = singleLine; - m_Stack.push_back(item); -} - -void VmaJsonWriter::EndObject() -{ - VMA_ASSERT(!m_InsideString); - - WriteIndent(true); - m_SB.Add('}'); - - VMA_ASSERT(!m_Stack.empty() && m_Stack.back().type == COLLECTION_TYPE_OBJECT); - m_Stack.pop_back(); -} - -void VmaJsonWriter::BeginArray(bool singleLine) -{ - VMA_ASSERT(!m_InsideString); - - BeginValue(false); - m_SB.Add('['); - - StackItem item; - item.type = COLLECTION_TYPE_ARRAY; - item.valueCount = 0; - item.singleLineMode = singleLine; - m_Stack.push_back(item); -} - -void VmaJsonWriter::EndArray() -{ - VMA_ASSERT(!m_InsideString); - - WriteIndent(true); - m_SB.Add(']'); - - VMA_ASSERT(!m_Stack.empty() && m_Stack.back().type == COLLECTION_TYPE_ARRAY); - m_Stack.pop_back(); -} - -void VmaJsonWriter::WriteString(const char* pStr) -{ - BeginString(pStr); - EndString(); -} - -void VmaJsonWriter::BeginString(const char* pStr) -{ - VMA_ASSERT(!m_InsideString); - - BeginValue(true); - m_SB.Add('"'); - m_InsideString = true; - if(pStr != VMA_NULL && pStr[0] != '\0') - { - ContinueString(pStr); - } -} - -void VmaJsonWriter::ContinueString(const char* pStr) -{ - VMA_ASSERT(m_InsideString); - - const size_t strLen = strlen(pStr); - for(size_t i = 0; i < strLen; ++i) - { - char ch = pStr[i]; - if(ch == '\\') + VMA_ASSERT(m_MappingHysteresis.GetExtraMapping() == 0); + if (m_MapCount == 0) { - m_SB.Add("\\\\"); - } - else if(ch == '"') - { - m_SB.Add("\\\""); - } - else if(ch >= 32) - { - m_SB.Add(ch); - } - else switch(ch) - { - case '\b': - m_SB.Add("\\b"); - break; - case '\f': - m_SB.Add("\\f"); - break; - case '\n': - m_SB.Add("\\n"); - break; - case '\r': - m_SB.Add("\\r"); - break; - case '\t': - m_SB.Add("\\t"); - break; - default: - VMA_ASSERT(0 && "Character not currently supported."); - break; + m_pMappedData = VMA_NULL; + (*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, m_hMemory); } } } -void VmaJsonWriter::ContinueString(uint32_t n) +bool VmaDeviceMemoryBlock::Validate() const { - VMA_ASSERT(m_InsideString); - m_SB.AddNumber(n); + VMA_VALIDATE((m_hMemory != VK_NULL_HANDLE) && + (m_pMetadata->GetSize() != 0)); + + return m_pMetadata->Validate(); } -void VmaJsonWriter::ContinueString(uint64_t n) +VkResult VmaDeviceMemoryBlock::CheckCorruption(VmaAllocator hAllocator) { - VMA_ASSERT(m_InsideString); - m_SB.AddNumber(n); -} - -void VmaJsonWriter::ContinueString_Pointer(const void* ptr) -{ - VMA_ASSERT(m_InsideString); - m_SB.AddPointer(ptr); -} - -void VmaJsonWriter::EndString(const char* pStr) -{ - VMA_ASSERT(m_InsideString); - if(pStr != VMA_NULL && pStr[0] != '\0') + void* pData = nullptr; + VkResult res = Map(hAllocator, 1, &pData); + if (res != VK_SUCCESS) { - ContinueString(pStr); + return res; } - m_SB.Add('"'); - m_InsideString = false; + + res = m_pMetadata->CheckCorruption(pData); + + Unmap(hAllocator, 1); + + return res; } -void VmaJsonWriter::WriteNumber(uint32_t n) +VkResult VmaDeviceMemoryBlock::Map(VmaAllocator hAllocator, uint32_t count, void** ppData) { - VMA_ASSERT(!m_InsideString); - BeginValue(false); - m_SB.AddNumber(n); -} - -void VmaJsonWriter::WriteNumber(uint64_t n) -{ - VMA_ASSERT(!m_InsideString); - BeginValue(false); - m_SB.AddNumber(n); -} - -void VmaJsonWriter::WriteBool(bool b) -{ - VMA_ASSERT(!m_InsideString); - BeginValue(false); - m_SB.Add(b ? "true" : "false"); -} - -void VmaJsonWriter::WriteNull() -{ - VMA_ASSERT(!m_InsideString); - BeginValue(false); - m_SB.Add("null"); -} - -void VmaJsonWriter::BeginValue(bool isString) -{ - if(!m_Stack.empty()) + if (count == 0) { - StackItem& currItem = m_Stack.back(); - if(currItem.type == COLLECTION_TYPE_OBJECT && - currItem.valueCount % 2 == 0) - { - VMA_ASSERT(isString); - } - - if(currItem.type == COLLECTION_TYPE_OBJECT && - currItem.valueCount % 2 != 0) - { - m_SB.Add(": "); - } - else if(currItem.valueCount > 0) - { - m_SB.Add(", "); - WriteIndent(); - } - else - { - WriteIndent(); - } - ++currItem.valueCount; + return VK_SUCCESS; } -} -void VmaJsonWriter::WriteIndent(bool oneLess) -{ - if(!m_Stack.empty() && !m_Stack.back().singleLineMode) + VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex); + const uint32_t oldTotalMapCount = m_MapCount + m_MappingHysteresis.GetExtraMapping(); + m_MappingHysteresis.PostMap(); + if (oldTotalMapCount != 0) { - m_SB.AddNewLine(); - - size_t count = m_Stack.size(); - if(count > 0 && oneLess) + m_MapCount += count; + VMA_ASSERT(m_pMappedData != VMA_NULL); + if (ppData != VMA_NULL) { - --count; - } - for(size_t i = 0; i < count; ++i) - { - m_SB.Add(INDENT); - } - } -} - -#endif // #if VMA_STATS_STRING_ENABLED - -//////////////////////////////////////////////////////////////////////////////// - -void VmaAllocation_T::SetUserData(VmaAllocator hAllocator, void* pUserData) -{ - if(IsUserDataString()) - { - VMA_ASSERT(pUserData == VMA_NULL || pUserData != m_pUserData); - - FreeUserDataString(hAllocator); - - if(pUserData != VMA_NULL) - { - m_pUserData = VmaCreateStringCopy(hAllocator->GetAllocationCallbacks(), (const char*)pUserData); + *ppData = m_pMappedData; } + return VK_SUCCESS; } else { - m_pUserData = pUserData; + VkResult result = (*hAllocator->GetVulkanFunctions().vkMapMemory)( + hAllocator->m_hDevice, + m_hMemory, + 0, // offset + VK_WHOLE_SIZE, + 0, // flags + &m_pMappedData); + if (result == VK_SUCCESS) + { + if (ppData != VMA_NULL) + { + *ppData = m_pMappedData; + } + m_MapCount = count; + } + return result; } } -void VmaAllocation_T::ChangeBlockAllocation( - VmaAllocator hAllocator, - VmaDeviceMemoryBlock* block, - VkDeviceSize offset) +void VmaDeviceMemoryBlock::Unmap(VmaAllocator hAllocator, uint32_t count) { - VMA_ASSERT(block != VMA_NULL); - VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK); - - // Move mapping reference counter from old block to new block. - if(block != m_BlockAllocation.m_Block) + if (count == 0) { - uint32_t mapRefCount = m_MapCount & ~MAP_COUNT_FLAG_PERSISTENT_MAP; - if(IsPersistentMap()) - ++mapRefCount; - m_BlockAllocation.m_Block->Unmap(hAllocator, mapRefCount); - block->Map(hAllocator, mapRefCount, VMA_NULL); + return; } - m_BlockAllocation.m_Block = block; - m_BlockAllocation.m_Offset = offset; + VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex); + if (m_MapCount >= count) + { + m_MapCount -= count; + const uint32_t totalMapCount = m_MapCount + m_MappingHysteresis.GetExtraMapping(); + if (totalMapCount == 0) + { + m_pMappedData = VMA_NULL; + (*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, m_hMemory); + } + m_MappingHysteresis.PostUnmap(); + } + else + { + VMA_ASSERT(0 && "VkDeviceMemory block is being unmapped while it was not previously mapped."); + } } -void VmaAllocation_T::ChangeOffset(VkDeviceSize newOffset) +VkResult VmaDeviceMemoryBlock::WriteMagicValueAfterAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize) { + VMA_ASSERT(VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_MARGIN % 4 == 0 && VMA_DEBUG_DETECT_CORRUPTION); + + void* pData; + VkResult res = Map(hAllocator, 1, &pData); + if (res != VK_SUCCESS) + { + return res; + } + + VmaWriteMagicValue(pData, allocOffset + allocSize); + + Unmap(hAllocator, 1); + return VK_SUCCESS; +} + +VkResult VmaDeviceMemoryBlock::ValidateMagicValueAfterAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize) +{ + VMA_ASSERT(VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_MARGIN % 4 == 0 && VMA_DEBUG_DETECT_CORRUPTION); + + void* pData; + VkResult res = Map(hAllocator, 1, &pData); + if (res != VK_SUCCESS) + { + return res; + } + + if (!VmaValidateMagicValue(pData, allocOffset + allocSize)) + { + VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER FREED ALLOCATION!"); + } + + Unmap(hAllocator, 1); + return VK_SUCCESS; +} + +VkResult VmaDeviceMemoryBlock::BindBufferMemory( + const VmaAllocator hAllocator, + const VmaAllocation hAllocation, + VkDeviceSize allocationLocalOffset, + VkBuffer hBuffer, + const void* pNext) +{ + VMA_ASSERT(hAllocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK && + hAllocation->GetBlock() == this); + VMA_ASSERT(allocationLocalOffset < hAllocation->GetSize() && + "Invalid allocationLocalOffset. Did you forget that this offset is relative to the beginning of the allocation, not the whole memory block?"); + const VkDeviceSize memoryOffset = hAllocation->GetOffset() + allocationLocalOffset; + // This lock is important so that we don't call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads. + VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex); + return hAllocator->BindVulkanBuffer(m_hMemory, memoryOffset, hBuffer, pNext); +} + +VkResult VmaDeviceMemoryBlock::BindImageMemory( + const VmaAllocator hAllocator, + const VmaAllocation hAllocation, + VkDeviceSize allocationLocalOffset, + VkImage hImage, + const void* pNext) +{ + VMA_ASSERT(hAllocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK && + hAllocation->GetBlock() == this); + VMA_ASSERT(allocationLocalOffset < hAllocation->GetSize() && + "Invalid allocationLocalOffset. Did you forget that this offset is relative to the beginning of the allocation, not the whole memory block?"); + const VkDeviceSize memoryOffset = hAllocation->GetOffset() + allocationLocalOffset; + // This lock is important so that we don't call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads. + VmaMutexLock lock(m_MapAndBindMutex, hAllocator->m_UseMutex); + return hAllocator->BindVulkanImage(m_hMemory, memoryOffset, hImage, pNext); +} +#endif // _VMA_DEVICE_MEMORY_BLOCK_FUNCTIONS + +#ifndef _VMA_ALLOCATION_T_FUNCTIONS +VmaAllocation_T::VmaAllocation_T(bool mappingAllowed) + : m_Alignment{ 1 }, + m_Size{ 0 }, + m_pUserData{ VMA_NULL }, + m_pName{ VMA_NULL }, + m_MemoryTypeIndex{ 0 }, + m_Type{ (uint8_t)ALLOCATION_TYPE_NONE }, + m_SuballocationType{ (uint8_t)VMA_SUBALLOCATION_TYPE_UNKNOWN }, + m_MapCount{ 0 }, + m_Flags{ 0 } +{ + if(mappingAllowed) + m_Flags |= (uint8_t)FLAG_MAPPING_ALLOWED; + +#if VMA_STATS_STRING_ENABLED + m_BufferImageUsage = 0; +#endif +} + +VmaAllocation_T::~VmaAllocation_T() +{ + VMA_ASSERT(m_MapCount == 0 && "Allocation was not unmapped before destruction."); + + // Check if owned string was freed. + VMA_ASSERT(m_pName == VMA_NULL); +} + +void VmaAllocation_T::InitBlockAllocation( + VmaDeviceMemoryBlock* block, + VmaAllocHandle allocHandle, + VkDeviceSize alignment, + VkDeviceSize size, + uint32_t memoryTypeIndex, + VmaSuballocationType suballocationType, + bool mapped) +{ + VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE); + VMA_ASSERT(block != VMA_NULL); + m_Type = (uint8_t)ALLOCATION_TYPE_BLOCK; + m_Alignment = alignment; + m_Size = size; + m_MemoryTypeIndex = memoryTypeIndex; + if(mapped) + { + VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it."); + m_Flags |= (uint8_t)FLAG_PERSISTENT_MAP; + } + m_SuballocationType = (uint8_t)suballocationType; + m_BlockAllocation.m_Block = block; + m_BlockAllocation.m_AllocHandle = allocHandle; +} + +void VmaAllocation_T::InitDedicatedAllocation( + VmaPool hParentPool, + uint32_t memoryTypeIndex, + VkDeviceMemory hMemory, + VmaSuballocationType suballocationType, + void* pMappedData, + VkDeviceSize size) +{ + VMA_ASSERT(m_Type == ALLOCATION_TYPE_NONE); + VMA_ASSERT(hMemory != VK_NULL_HANDLE); + m_Type = (uint8_t)ALLOCATION_TYPE_DEDICATED; + m_Alignment = 0; + m_Size = size; + m_MemoryTypeIndex = memoryTypeIndex; + m_SuballocationType = (uint8_t)suballocationType; + if(pMappedData != VMA_NULL) + { + VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it."); + m_Flags |= (uint8_t)FLAG_PERSISTENT_MAP; + } + m_DedicatedAllocation.m_hParentPool = hParentPool; + m_DedicatedAllocation.m_hMemory = hMemory; + m_DedicatedAllocation.m_pMappedData = pMappedData; + m_DedicatedAllocation.m_Prev = VMA_NULL; + m_DedicatedAllocation.m_Next = VMA_NULL; +} + +void VmaAllocation_T::SetName(VmaAllocator hAllocator, const char* pName) +{ + VMA_ASSERT(pName == VMA_NULL || pName != m_pName); + + FreeName(hAllocator); + + if (pName != VMA_NULL) + m_pName = VmaCreateStringCopy(hAllocator->GetAllocationCallbacks(), pName); +} + +uint8_t VmaAllocation_T::SwapBlockAllocation(VmaAllocator hAllocator, VmaAllocation allocation) +{ + VMA_ASSERT(allocation != VMA_NULL); VMA_ASSERT(m_Type == ALLOCATION_TYPE_BLOCK); - m_BlockAllocation.m_Offset = newOffset; + VMA_ASSERT(allocation->m_Type == ALLOCATION_TYPE_BLOCK); + + if (m_MapCount != 0) + m_BlockAllocation.m_Block->Unmap(hAllocator, m_MapCount); + + m_BlockAllocation.m_Block->m_pMetadata->SetAllocationUserData(m_BlockAllocation.m_AllocHandle, allocation); + VMA_SWAP(m_BlockAllocation, allocation->m_BlockAllocation); + m_BlockAllocation.m_Block->m_pMetadata->SetAllocationUserData(m_BlockAllocation.m_AllocHandle, this); + +#if VMA_STATS_STRING_ENABLED + VMA_SWAP(m_BufferImageUsage, allocation->m_BufferImageUsage); +#endif + return m_MapCount; +} + +VmaAllocHandle VmaAllocation_T::GetAllocHandle() const +{ + switch (m_Type) + { + case ALLOCATION_TYPE_BLOCK: + return m_BlockAllocation.m_AllocHandle; + case ALLOCATION_TYPE_DEDICATED: + return VK_NULL_HANDLE; + default: + VMA_ASSERT(0); + return VK_NULL_HANDLE; + } } VkDeviceSize VmaAllocation_T::GetOffset() const { - switch(m_Type) + switch (m_Type) { case ALLOCATION_TYPE_BLOCK: - return m_BlockAllocation.m_Offset; + return m_BlockAllocation.m_Block->m_pMetadata->GetAllocationOffset(m_BlockAllocation.m_AllocHandle); case ALLOCATION_TYPE_DEDICATED: return 0; default: @@ -7116,9 +12081,23 @@ VkDeviceSize VmaAllocation_T::GetOffset() const } } +VmaPool VmaAllocation_T::GetParentPool() const +{ + switch (m_Type) + { + case ALLOCATION_TYPE_BLOCK: + return m_BlockAllocation.m_Block->GetParentPool(); + case ALLOCATION_TYPE_DEDICATED: + return m_DedicatedAllocation.m_hParentPool; + default: + VMA_ASSERT(0); + return VK_NULL_HANDLE; + } +} + VkDeviceMemory VmaAllocation_T::GetMemory() const { - switch(m_Type) + switch (m_Type) { case ALLOCATION_TYPE_BLOCK: return m_BlockAllocation.m_Block->GetDeviceMemory(); @@ -7132,14 +12111,14 @@ VkDeviceMemory VmaAllocation_T::GetMemory() const void* VmaAllocation_T::GetMappedData() const { - switch(m_Type) + switch (m_Type) { case ALLOCATION_TYPE_BLOCK: - if(m_MapCount != 0) + if (m_MapCount != 0 || IsPersistentMap()) { void* pBlockData = m_BlockAllocation.m_Block->GetMappedData(); VMA_ASSERT(pBlockData != VMA_NULL); - return (char*)pBlockData + m_BlockAllocation.m_Offset; + return (char*)pBlockData + GetOffset(); } else { @@ -7147,7 +12126,7 @@ void* VmaAllocation_T::GetMappedData() const } break; case ALLOCATION_TYPE_DEDICATED: - VMA_ASSERT((m_DedicatedAllocation.m_pMappedData != VMA_NULL) == (m_MapCount != 0)); + VMA_ASSERT((m_DedicatedAllocation.m_pMappedData != VMA_NULL) == (m_MapCount != 0 || IsPersistentMap())); return m_DedicatedAllocation.m_pMappedData; default: VMA_ASSERT(0); @@ -7155,114 +12134,12 @@ void* VmaAllocation_T::GetMappedData() const } } -bool VmaAllocation_T::CanBecomeLost() const -{ - switch(m_Type) - { - case ALLOCATION_TYPE_BLOCK: - return m_BlockAllocation.m_CanBecomeLost; - case ALLOCATION_TYPE_DEDICATED: - return false; - default: - VMA_ASSERT(0); - return false; - } -} - -bool VmaAllocation_T::MakeLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) -{ - VMA_ASSERT(CanBecomeLost()); - - /* - Warning: This is a carefully designed algorithm. - Do not modify unless you really know what you're doing :) - */ - uint32_t localLastUseFrameIndex = GetLastUseFrameIndex(); - for(;;) - { - if(localLastUseFrameIndex == VMA_FRAME_INDEX_LOST) - { - VMA_ASSERT(0); - return false; - } - else if(localLastUseFrameIndex + frameInUseCount >= currentFrameIndex) - { - return false; - } - else // Last use time earlier than current time. - { - if(CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, VMA_FRAME_INDEX_LOST)) - { - // Setting hAllocation.LastUseFrameIndex atomic to VMA_FRAME_INDEX_LOST is enough to mark it as LOST. - // Calling code just needs to unregister this allocation in owning VmaDeviceMemoryBlock. - return true; - } - } - } -} - -#if VMA_STATS_STRING_ENABLED - -// Correspond to values of enum VmaSuballocationType. -static const char* VMA_SUBALLOCATION_TYPE_NAMES[] = { - "FREE", - "UNKNOWN", - "BUFFER", - "IMAGE_UNKNOWN", - "IMAGE_LINEAR", - "IMAGE_OPTIMAL", -}; - -void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const -{ - json.WriteString("Type"); - json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[m_SuballocationType]); - - json.WriteString("Size"); - json.WriteNumber(m_Size); - - if(m_pUserData != VMA_NULL) - { - json.WriteString("UserData"); - if(IsUserDataString()) - { - json.WriteString((const char*)m_pUserData); - } - else - { - json.BeginString(); - json.ContinueString_Pointer(m_pUserData); - json.EndString(); - } - } - - json.WriteString("CreationFrameIndex"); - json.WriteNumber(m_CreationFrameIndex); - - json.WriteString("LastUseFrameIndex"); - json.WriteNumber(GetLastUseFrameIndex()); - - if(m_BufferImageUsage != 0) - { - json.WriteString("Usage"); - json.WriteNumber(m_BufferImageUsage); - } -} - -#endif - -void VmaAllocation_T::FreeUserDataString(VmaAllocator hAllocator) -{ - VMA_ASSERT(IsUserDataString()); - VmaFreeString(hAllocator->GetAllocationCallbacks(), (char*)m_pUserData); - m_pUserData = VMA_NULL; -} - void VmaAllocation_T::BlockAllocMap() { VMA_ASSERT(GetType() == ALLOCATION_TYPE_BLOCK); + VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it."); - if((m_MapCount & ~MAP_COUNT_FLAG_PERSISTENT_MAP) < 0x7F) + if (m_MapCount < 0xFF) { ++m_MapCount; } @@ -7276,7 +12153,7 @@ void VmaAllocation_T::BlockAllocUnmap() { VMA_ASSERT(GetType() == ALLOCATION_TYPE_BLOCK); - if((m_MapCount & ~MAP_COUNT_FLAG_PERSISTENT_MAP) != 0) + if (m_MapCount > 0) { --m_MapCount; } @@ -7289,10 +12166,11 @@ void VmaAllocation_T::BlockAllocUnmap() VkResult VmaAllocation_T::DedicatedAllocMap(VmaAllocator hAllocator, void** ppData) { VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED); + VMA_ASSERT(IsMappingAllowed() && "Mapping is not allowed on this allocation! Please use one of the new VMA_ALLOCATION_CREATE_HOST_ACCESS_* flags when creating it."); - if(m_MapCount != 0) + if (m_MapCount != 0 || IsPersistentMap()) { - if((m_MapCount & ~MAP_COUNT_FLAG_PERSISTENT_MAP) < 0x7F) + if (m_MapCount < 0xFF) { VMA_ASSERT(m_DedicatedAllocation.m_pMappedData != VMA_NULL); *ppData = m_DedicatedAllocation.m_pMappedData; @@ -7314,7 +12192,7 @@ VkResult VmaAllocation_T::DedicatedAllocMap(VmaAllocator hAllocator, void** ppDa VK_WHOLE_SIZE, 0, // flags ppData); - if(result == VK_SUCCESS) + if (result == VK_SUCCESS) { m_DedicatedAllocation.m_pMappedData = *ppData; m_MapCount = 1; @@ -7327,10 +12205,10 @@ void VmaAllocation_T::DedicatedAllocUnmap(VmaAllocator hAllocator) { VMA_ASSERT(GetType() == ALLOCATION_TYPE_DEDICATED); - if((m_MapCount & ~MAP_COUNT_FLAG_PERSISTENT_MAP) != 0) + if (m_MapCount > 0) { --m_MapCount; - if(m_MapCount == 0) + if (m_MapCount == 0 && !IsPersistentMap()) { m_DedicatedAllocation.m_pMappedData = VMA_NULL; (*hAllocator->GetVulkanFunctions().vkUnmapMemory)( @@ -7345,3739 +12223,48 @@ void VmaAllocation_T::DedicatedAllocUnmap(VmaAllocator hAllocator) } #if VMA_STATS_STRING_ENABLED - -static void VmaPrintStatInfo(VmaJsonWriter& json, const VmaStatInfo& stat) +void VmaAllocation_T::InitBufferImageUsage(uint32_t bufferImageUsage) { - json.BeginObject(); - - json.WriteString("Blocks"); - json.WriteNumber(stat.blockCount); - - json.WriteString("Allocations"); - json.WriteNumber(stat.allocationCount); - - json.WriteString("UnusedRanges"); - json.WriteNumber(stat.unusedRangeCount); - - json.WriteString("UsedBytes"); - json.WriteNumber(stat.usedBytes); - - json.WriteString("UnusedBytes"); - json.WriteNumber(stat.unusedBytes); - - if(stat.allocationCount > 1) - { - json.WriteString("AllocationSize"); - json.BeginObject(true); - json.WriteString("Min"); - json.WriteNumber(stat.allocationSizeMin); - json.WriteString("Avg"); - json.WriteNumber(stat.allocationSizeAvg); - json.WriteString("Max"); - json.WriteNumber(stat.allocationSizeMax); - json.EndObject(); - } - - if(stat.unusedRangeCount > 1) - { - json.WriteString("UnusedRangeSize"); - json.BeginObject(true); - json.WriteString("Min"); - json.WriteNumber(stat.unusedRangeSizeMin); - json.WriteString("Avg"); - json.WriteNumber(stat.unusedRangeSizeAvg); - json.WriteString("Max"); - json.WriteNumber(stat.unusedRangeSizeMax); - json.EndObject(); - } - - json.EndObject(); + VMA_ASSERT(m_BufferImageUsage == 0); + m_BufferImageUsage = bufferImageUsage; } -#endif // #if VMA_STATS_STRING_ENABLED - -struct VmaSuballocationItemSizeLess +void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const { - bool operator()( - const VmaSuballocationList::iterator lhs, - const VmaSuballocationList::iterator rhs) const - { - return lhs->size < rhs->size; - } - bool operator()( - const VmaSuballocationList::iterator lhs, - VkDeviceSize rhsSize) const - { - return lhs->size < rhsSize; - } -}; - - -//////////////////////////////////////////////////////////////////////////////// -// class VmaBlockMetadata - -VmaBlockMetadata::VmaBlockMetadata(VmaAllocator hAllocator) : - m_Size(0), - m_pAllocationCallbacks(hAllocator->GetAllocationCallbacks()) -{ -} - -#if VMA_STATS_STRING_ENABLED - -void VmaBlockMetadata::PrintDetailedMap_Begin(class VmaJsonWriter& json, - VkDeviceSize unusedBytes, - size_t allocationCount, - size_t unusedRangeCount) const -{ - json.BeginObject(); - - json.WriteString("TotalBytes"); - json.WriteNumber(GetSize()); - - json.WriteString("UnusedBytes"); - json.WriteNumber(unusedBytes); - - json.WriteString("Allocations"); - json.WriteNumber((uint64_t)allocationCount); - - json.WriteString("UnusedRanges"); - json.WriteNumber((uint64_t)unusedRangeCount); - - json.WriteString("Suballocations"); - json.BeginArray(); -} - -void VmaBlockMetadata::PrintDetailedMap_Allocation(class VmaJsonWriter& json, - VkDeviceSize offset, - VmaAllocation hAllocation) const -{ - json.BeginObject(true); - - json.WriteString("Offset"); - json.WriteNumber(offset); - - hAllocation->PrintParameters(json); - - json.EndObject(); -} - -void VmaBlockMetadata::PrintDetailedMap_UnusedRange(class VmaJsonWriter& json, - VkDeviceSize offset, - VkDeviceSize size) const -{ - json.BeginObject(true); - - json.WriteString("Offset"); - json.WriteNumber(offset); - json.WriteString("Type"); - json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[VMA_SUBALLOCATION_TYPE_FREE]); + json.WriteString(VMA_SUBALLOCATION_TYPE_NAMES[m_SuballocationType]); json.WriteString("Size"); - json.WriteNumber(size); + json.WriteNumber(m_Size); + json.WriteString("Usage"); + json.WriteNumber(m_BufferImageUsage); - json.EndObject(); -} - -void VmaBlockMetadata::PrintDetailedMap_End(class VmaJsonWriter& json) const -{ - json.EndArray(); - json.EndObject(); -} - -#endif // #if VMA_STATS_STRING_ENABLED - -//////////////////////////////////////////////////////////////////////////////// -// class VmaBlockMetadata_Generic - -VmaBlockMetadata_Generic::VmaBlockMetadata_Generic(VmaAllocator hAllocator) : - VmaBlockMetadata(hAllocator), - m_FreeCount(0), - m_SumFreeSize(0), - m_Suballocations(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), - m_FreeSuballocationsBySize(VmaStlAllocator(hAllocator->GetAllocationCallbacks())) -{ -} - -VmaBlockMetadata_Generic::~VmaBlockMetadata_Generic() -{ -} - -void VmaBlockMetadata_Generic::Init(VkDeviceSize size) -{ - VmaBlockMetadata::Init(size); - - m_FreeCount = 1; - m_SumFreeSize = size; - - VmaSuballocation suballoc = {}; - suballoc.offset = 0; - suballoc.size = size; - suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; - suballoc.hAllocation = VK_NULL_HANDLE; - - VMA_ASSERT(size > VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER); - m_Suballocations.push_back(suballoc); - VmaSuballocationList::iterator suballocItem = m_Suballocations.end(); - --suballocItem; - m_FreeSuballocationsBySize.push_back(suballocItem); -} - -bool VmaBlockMetadata_Generic::Validate() const -{ - VMA_VALIDATE(!m_Suballocations.empty()); - - // Expected offset of new suballocation as calculated from previous ones. - VkDeviceSize calculatedOffset = 0; - // Expected number of free suballocations as calculated from traversing their list. - uint32_t calculatedFreeCount = 0; - // Expected sum size of free suballocations as calculated from traversing their list. - VkDeviceSize calculatedSumFreeSize = 0; - // Expected number of free suballocations that should be registered in - // m_FreeSuballocationsBySize calculated from traversing their list. - size_t freeSuballocationsToRegister = 0; - // True if previous visited suballocation was free. - bool prevFree = false; - - for(const auto& subAlloc : m_Suballocations) - { - // Actual offset of this suballocation doesn't match expected one. - VMA_VALIDATE(subAlloc.offset == calculatedOffset); - - const bool currFree = (subAlloc.type == VMA_SUBALLOCATION_TYPE_FREE); - // Two adjacent free suballocations are invalid. They should be merged. - VMA_VALIDATE(!prevFree || !currFree); - - VMA_VALIDATE(currFree == (subAlloc.hAllocation == VK_NULL_HANDLE)); - - if(currFree) - { - calculatedSumFreeSize += subAlloc.size; - ++calculatedFreeCount; - if(subAlloc.size >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) - { - ++freeSuballocationsToRegister; - } - - // Margin required between allocations - every free space must be at least that large. - VMA_VALIDATE(subAlloc.size >= VMA_DEBUG_MARGIN); - } - else - { - VMA_VALIDATE(subAlloc.hAllocation->GetOffset() == subAlloc.offset); - VMA_VALIDATE(subAlloc.hAllocation->GetSize() == subAlloc.size); - - // Margin required between allocations - previous allocation must be free. - VMA_VALIDATE(VMA_DEBUG_MARGIN == 0 || prevFree); - } - - calculatedOffset += subAlloc.size; - prevFree = currFree; - } - - // Number of free suballocations registered in m_FreeSuballocationsBySize doesn't - // match expected one. - VMA_VALIDATE(m_FreeSuballocationsBySize.size() == freeSuballocationsToRegister); - - VkDeviceSize lastSize = 0; - for(size_t i = 0; i < m_FreeSuballocationsBySize.size(); ++i) - { - VmaSuballocationList::iterator suballocItem = m_FreeSuballocationsBySize[i]; - - // Only free suballocations can be registered in m_FreeSuballocationsBySize. - VMA_VALIDATE(suballocItem->type == VMA_SUBALLOCATION_TYPE_FREE); - // They must be sorted by size ascending. - VMA_VALIDATE(suballocItem->size >= lastSize); - - lastSize = suballocItem->size; - } - - // Check if totals match calculated values. - VMA_VALIDATE(ValidateFreeSuballocationList()); - VMA_VALIDATE(calculatedOffset == GetSize()); - VMA_VALIDATE(calculatedSumFreeSize == m_SumFreeSize); - VMA_VALIDATE(calculatedFreeCount == m_FreeCount); - - return true; -} - -VkDeviceSize VmaBlockMetadata_Generic::GetUnusedRangeSizeMax() const -{ - if(!m_FreeSuballocationsBySize.empty()) - { - return m_FreeSuballocationsBySize.back()->size; - } - else - { - return 0; - } -} - -bool VmaBlockMetadata_Generic::IsEmpty() const -{ - return (m_Suballocations.size() == 1) && (m_FreeCount == 1); -} - -void VmaBlockMetadata_Generic::CalcAllocationStatInfo(VmaStatInfo& outInfo) const -{ - outInfo.blockCount = 1; - - const uint32_t rangeCount = (uint32_t)m_Suballocations.size(); - outInfo.allocationCount = rangeCount - m_FreeCount; - outInfo.unusedRangeCount = m_FreeCount; - - outInfo.unusedBytes = m_SumFreeSize; - outInfo.usedBytes = GetSize() - outInfo.unusedBytes; - - outInfo.allocationSizeMin = UINT64_MAX; - outInfo.allocationSizeMax = 0; - outInfo.unusedRangeSizeMin = UINT64_MAX; - outInfo.unusedRangeSizeMax = 0; - - for(const auto& suballoc : m_Suballocations) - { - if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) - { - outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size); - outInfo.allocationSizeMax = VMA_MAX(outInfo.allocationSizeMax, suballoc.size); - } - else - { - outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, suballoc.size); - outInfo.unusedRangeSizeMax = VMA_MAX(outInfo.unusedRangeSizeMax, suballoc.size); - } - } -} - -void VmaBlockMetadata_Generic::AddPoolStats(VmaPoolStats& inoutStats) const -{ - const uint32_t rangeCount = (uint32_t)m_Suballocations.size(); - - inoutStats.size += GetSize(); - inoutStats.unusedSize += m_SumFreeSize; - inoutStats.allocationCount += rangeCount - m_FreeCount; - inoutStats.unusedRangeCount += m_FreeCount; - inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, GetUnusedRangeSizeMax()); -} - -#if VMA_STATS_STRING_ENABLED - -void VmaBlockMetadata_Generic::PrintDetailedMap(class VmaJsonWriter& json) const -{ - PrintDetailedMap_Begin(json, - m_SumFreeSize, // unusedBytes - m_Suballocations.size() - (size_t)m_FreeCount, // allocationCount - m_FreeCount); // unusedRangeCount - - for(const auto& suballoc : m_Suballocations) - { - if(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE) - { - PrintDetailedMap_UnusedRange(json, suballoc.offset, suballoc.size); - } - else - { - PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation); - } - } - - PrintDetailedMap_End(json); -} - -#endif // #if VMA_STATS_STRING_ENABLED - -bool VmaBlockMetadata_Generic::CreateAllocationRequest( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, - VkDeviceSize allocSize, - VkDeviceSize allocAlignment, - bool upperAddress, - VmaSuballocationType allocType, - bool canMakeOtherLost, - uint32_t strategy, - VmaAllocationRequest* pAllocationRequest) -{ - VMA_ASSERT(allocSize > 0); - VMA_ASSERT(!upperAddress); - VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE); - VMA_ASSERT(pAllocationRequest != VMA_NULL); - VMA_HEAVY_ASSERT(Validate()); - - pAllocationRequest->type = VmaAllocationRequestType::Normal; - - // There is not enough total free space in this block to fullfill the request: Early return. - if(canMakeOtherLost == false && - m_SumFreeSize < allocSize + 2 * VMA_DEBUG_MARGIN) - { - return false; - } - - // New algorithm, efficiently searching freeSuballocationsBySize. - const size_t freeSuballocCount = m_FreeSuballocationsBySize.size(); - if(freeSuballocCount > 0) - { - if(strategy == VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT) - { - // Find first free suballocation with size not less than allocSize + 2 * VMA_DEBUG_MARGIN. - VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess( - m_FreeSuballocationsBySize.data(), - m_FreeSuballocationsBySize.data() + freeSuballocCount, - allocSize + 2 * VMA_DEBUG_MARGIN, - VmaSuballocationItemSizeLess()); - size_t index = it - m_FreeSuballocationsBySize.data(); - for(; index < freeSuballocCount; ++index) - { - if(CheckAllocation( - currentFrameIndex, - frameInUseCount, - bufferImageGranularity, - allocSize, - allocAlignment, - allocType, - m_FreeSuballocationsBySize[index], - false, // canMakeOtherLost - &pAllocationRequest->offset, - &pAllocationRequest->itemsToMakeLostCount, - &pAllocationRequest->sumFreeSize, - &pAllocationRequest->sumItemSize)) - { - pAllocationRequest->item = m_FreeSuballocationsBySize[index]; - return true; - } - } - } - else if(strategy == VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET) - { - for(VmaSuballocationList::iterator it = m_Suballocations.begin(); - it != m_Suballocations.end(); - ++it) - { - if(it->type == VMA_SUBALLOCATION_TYPE_FREE && CheckAllocation( - currentFrameIndex, - frameInUseCount, - bufferImageGranularity, - allocSize, - allocAlignment, - allocType, - it, - false, // canMakeOtherLost - &pAllocationRequest->offset, - &pAllocationRequest->itemsToMakeLostCount, - &pAllocationRequest->sumFreeSize, - &pAllocationRequest->sumItemSize)) - { - pAllocationRequest->item = it; - return true; - } - } - } - else // WORST_FIT, FIRST_FIT - { - // Search staring from biggest suballocations. - for(size_t index = freeSuballocCount; index--; ) - { - if(CheckAllocation( - currentFrameIndex, - frameInUseCount, - bufferImageGranularity, - allocSize, - allocAlignment, - allocType, - m_FreeSuballocationsBySize[index], - false, // canMakeOtherLost - &pAllocationRequest->offset, - &pAllocationRequest->itemsToMakeLostCount, - &pAllocationRequest->sumFreeSize, - &pAllocationRequest->sumItemSize)) - { - pAllocationRequest->item = m_FreeSuballocationsBySize[index]; - return true; - } - } - } - } - - if(canMakeOtherLost) - { - // Brute-force algorithm. TODO: Come up with something better. - - bool found = false; - VmaAllocationRequest tmpAllocRequest = {}; - tmpAllocRequest.type = VmaAllocationRequestType::Normal; - for(VmaSuballocationList::iterator suballocIt = m_Suballocations.begin(); - suballocIt != m_Suballocations.end(); - ++suballocIt) - { - if(suballocIt->type == VMA_SUBALLOCATION_TYPE_FREE || - suballocIt->hAllocation->CanBecomeLost()) - { - if(CheckAllocation( - currentFrameIndex, - frameInUseCount, - bufferImageGranularity, - allocSize, - allocAlignment, - allocType, - suballocIt, - canMakeOtherLost, - &tmpAllocRequest.offset, - &tmpAllocRequest.itemsToMakeLostCount, - &tmpAllocRequest.sumFreeSize, - &tmpAllocRequest.sumItemSize)) - { - if(strategy == VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT) - { - *pAllocationRequest = tmpAllocRequest; - pAllocationRequest->item = suballocIt; - break; - } - if(!found || tmpAllocRequest.CalcCost() < pAllocationRequest->CalcCost()) - { - *pAllocationRequest = tmpAllocRequest; - pAllocationRequest->item = suballocIt; - found = true; - } - } - } - } - - return found; - } - - return false; -} - -bool VmaBlockMetadata_Generic::MakeRequestedAllocationsLost( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VmaAllocationRequest* pAllocationRequest) -{ - VMA_ASSERT(pAllocationRequest && pAllocationRequest->type == VmaAllocationRequestType::Normal); - - while(pAllocationRequest->itemsToMakeLostCount > 0) - { - if(pAllocationRequest->item->type == VMA_SUBALLOCATION_TYPE_FREE) - { - ++pAllocationRequest->item; - } - VMA_ASSERT(pAllocationRequest->item != m_Suballocations.end()); - VMA_ASSERT(pAllocationRequest->item->hAllocation != VK_NULL_HANDLE); - VMA_ASSERT(pAllocationRequest->item->hAllocation->CanBecomeLost()); - if(pAllocationRequest->item->hAllocation->MakeLost(currentFrameIndex, frameInUseCount)) - { - pAllocationRequest->item = FreeSuballocation(pAllocationRequest->item); - --pAllocationRequest->itemsToMakeLostCount; - } - else - { - return false; - } - } - - VMA_HEAVY_ASSERT(Validate()); - VMA_ASSERT(pAllocationRequest->item != m_Suballocations.end()); - VMA_ASSERT(pAllocationRequest->item->type == VMA_SUBALLOCATION_TYPE_FREE); - - return true; -} - -uint32_t VmaBlockMetadata_Generic::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) -{ - uint32_t lostAllocationCount = 0; - for(VmaSuballocationList::iterator it = m_Suballocations.begin(); - it != m_Suballocations.end(); - ++it) - { - if(it->type != VMA_SUBALLOCATION_TYPE_FREE && - it->hAllocation->CanBecomeLost() && - it->hAllocation->MakeLost(currentFrameIndex, frameInUseCount)) - { - it = FreeSuballocation(it); - ++lostAllocationCount; - } - } - return lostAllocationCount; -} - -VkResult VmaBlockMetadata_Generic::CheckCorruption(const void* pBlockData) -{ - for(auto& suballoc : m_Suballocations) - { - if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) - { - if(!VmaValidateMagicValue(pBlockData, suballoc.offset - VMA_DEBUG_MARGIN)) - { - VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!"); - return VK_ERROR_UNKNOWN; - } - if(!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size)) - { - VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!"); - return VK_ERROR_UNKNOWN; - } - } - } - - return VK_SUCCESS; -} - -void VmaBlockMetadata_Generic::Alloc( - const VmaAllocationRequest& request, - VmaSuballocationType type, - VkDeviceSize allocSize, - VmaAllocation hAllocation) -{ - VMA_ASSERT(request.type == VmaAllocationRequestType::Normal); - VMA_ASSERT(request.item != m_Suballocations.end()); - VmaSuballocation& suballoc = *request.item; - // Given suballocation is a free block. - VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); - // Given offset is inside this suballocation. - VMA_ASSERT(request.offset >= suballoc.offset); - const VkDeviceSize paddingBegin = request.offset - suballoc.offset; - VMA_ASSERT(suballoc.size >= paddingBegin + allocSize); - const VkDeviceSize paddingEnd = suballoc.size - paddingBegin - allocSize; - - // Unregister this free suballocation from m_FreeSuballocationsBySize and update - // it to become used. - UnregisterFreeSuballocation(request.item); - - suballoc.offset = request.offset; - suballoc.size = allocSize; - suballoc.type = type; - suballoc.hAllocation = hAllocation; - - // If there are any free bytes remaining at the end, insert new free suballocation after current one. - if(paddingEnd) - { - VmaSuballocation paddingSuballoc = {}; - paddingSuballoc.offset = request.offset + allocSize; - paddingSuballoc.size = paddingEnd; - paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE; - VmaSuballocationList::iterator next = request.item; - ++next; - const VmaSuballocationList::iterator paddingEndItem = - m_Suballocations.insert(next, paddingSuballoc); - RegisterFreeSuballocation(paddingEndItem); - } - - // If there are any free bytes remaining at the beginning, insert new free suballocation before current one. - if(paddingBegin) - { - VmaSuballocation paddingSuballoc = {}; - paddingSuballoc.offset = request.offset - paddingBegin; - paddingSuballoc.size = paddingBegin; - paddingSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE; - const VmaSuballocationList::iterator paddingBeginItem = - m_Suballocations.insert(request.item, paddingSuballoc); - RegisterFreeSuballocation(paddingBeginItem); - } - - // Update totals. - m_FreeCount = m_FreeCount - 1; - if(paddingBegin > 0) - { - ++m_FreeCount; - } - if(paddingEnd > 0) - { - ++m_FreeCount; - } - m_SumFreeSize -= allocSize; -} - -void VmaBlockMetadata_Generic::Free(const VmaAllocation allocation) -{ - for(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin(); - suballocItem != m_Suballocations.end(); - ++suballocItem) - { - VmaSuballocation& suballoc = *suballocItem; - if(suballoc.hAllocation == allocation) - { - FreeSuballocation(suballocItem); - VMA_HEAVY_ASSERT(Validate()); - return; - } - } - VMA_ASSERT(0 && "Not found!"); -} - -void VmaBlockMetadata_Generic::FreeAtOffset(VkDeviceSize offset) -{ - for(VmaSuballocationList::iterator suballocItem = m_Suballocations.begin(); - suballocItem != m_Suballocations.end(); - ++suballocItem) - { - VmaSuballocation& suballoc = *suballocItem; - if(suballoc.offset == offset) - { - FreeSuballocation(suballocItem); - return; - } - } - VMA_ASSERT(0 && "Not found!"); -} - -bool VmaBlockMetadata_Generic::ValidateFreeSuballocationList() const -{ - VkDeviceSize lastSize = 0; - for(size_t i = 0, count = m_FreeSuballocationsBySize.size(); i < count; ++i) - { - const VmaSuballocationList::iterator it = m_FreeSuballocationsBySize[i]; - - VMA_VALIDATE(it->type == VMA_SUBALLOCATION_TYPE_FREE); - VMA_VALIDATE(it->size >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER); - VMA_VALIDATE(it->size >= lastSize); - lastSize = it->size; - } - return true; -} - -bool VmaBlockMetadata_Generic::CheckAllocation( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, - VkDeviceSize allocSize, - VkDeviceSize allocAlignment, - VmaSuballocationType allocType, - VmaSuballocationList::const_iterator suballocItem, - bool canMakeOtherLost, - VkDeviceSize* pOffset, - size_t* itemsToMakeLostCount, - VkDeviceSize* pSumFreeSize, - VkDeviceSize* pSumItemSize) const -{ - VMA_ASSERT(allocSize > 0); - VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE); - VMA_ASSERT(suballocItem != m_Suballocations.cend()); - VMA_ASSERT(pOffset != VMA_NULL); - - *itemsToMakeLostCount = 0; - *pSumFreeSize = 0; - *pSumItemSize = 0; - - if(canMakeOtherLost) - { - if(suballocItem->type == VMA_SUBALLOCATION_TYPE_FREE) - { - *pSumFreeSize = suballocItem->size; - } - else - { - if(suballocItem->hAllocation->CanBecomeLost() && - suballocItem->hAllocation->GetLastUseFrameIndex() + frameInUseCount < currentFrameIndex) - { - ++*itemsToMakeLostCount; - *pSumItemSize = suballocItem->size; - } - else - { - return false; - } - } - - // Remaining size is too small for this request: Early return. - if(GetSize() - suballocItem->offset < allocSize) - { - return false; - } - - // Start from offset equal to beginning of this suballocation. - *pOffset = suballocItem->offset; - - // Apply VMA_DEBUG_MARGIN at the beginning. - if(VMA_DEBUG_MARGIN > 0) - { - *pOffset += VMA_DEBUG_MARGIN; - } - - // Apply alignment. - *pOffset = VmaAlignUp(*pOffset, allocAlignment); - - // Check previous suballocations for BufferImageGranularity conflicts. - // Make bigger alignment if necessary. - if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment) - { - bool bufferImageGranularityConflict = false; - VmaSuballocationList::const_iterator prevSuballocItem = suballocItem; - while(prevSuballocItem != m_Suballocations.cbegin()) - { - --prevSuballocItem; - const VmaSuballocation& prevSuballoc = *prevSuballocItem; - if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, *pOffset, bufferImageGranularity)) - { - if(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType)) - { - bufferImageGranularityConflict = true; - break; - } - } - else - // Already on previous page. - break; - } - if(bufferImageGranularityConflict) - { - *pOffset = VmaAlignUp(*pOffset, bufferImageGranularity); - } - } - - // Now that we have final *pOffset, check if we are past suballocItem. - // If yes, return false - this function should be called for another suballocItem as starting point. - if(*pOffset >= suballocItem->offset + suballocItem->size) - { - return false; - } - - // Calculate padding at the beginning based on current offset. - const VkDeviceSize paddingBegin = *pOffset - suballocItem->offset; - - // Calculate required margin at the end. - const VkDeviceSize requiredEndMargin = VMA_DEBUG_MARGIN; - - const VkDeviceSize totalSize = paddingBegin + allocSize + requiredEndMargin; - // Another early return check. - if(suballocItem->offset + totalSize > GetSize()) - { - return false; - } - - // Advance lastSuballocItem until desired size is reached. - // Update itemsToMakeLostCount. - VmaSuballocationList::const_iterator lastSuballocItem = suballocItem; - if(totalSize > suballocItem->size) - { - VkDeviceSize remainingSize = totalSize - suballocItem->size; - while(remainingSize > 0) - { - ++lastSuballocItem; - if(lastSuballocItem == m_Suballocations.cend()) - { - return false; - } - if(lastSuballocItem->type == VMA_SUBALLOCATION_TYPE_FREE) - { - *pSumFreeSize += lastSuballocItem->size; - } - else - { - VMA_ASSERT(lastSuballocItem->hAllocation != VK_NULL_HANDLE); - if(lastSuballocItem->hAllocation->CanBecomeLost() && - lastSuballocItem->hAllocation->GetLastUseFrameIndex() + frameInUseCount < currentFrameIndex) - { - ++*itemsToMakeLostCount; - *pSumItemSize += lastSuballocItem->size; - } - else - { - return false; - } - } - remainingSize = (lastSuballocItem->size < remainingSize) ? - remainingSize - lastSuballocItem->size : 0; - } - } - - // Check next suballocations for BufferImageGranularity conflicts. - // If conflict exists, we must mark more allocations lost or fail. - if(allocSize % bufferImageGranularity || *pOffset % bufferImageGranularity) - { - VmaSuballocationList::const_iterator nextSuballocItem = lastSuballocItem; - ++nextSuballocItem; - while(nextSuballocItem != m_Suballocations.cend()) - { - const VmaSuballocation& nextSuballoc = *nextSuballocItem; - if(VmaBlocksOnSamePage(*pOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) - { - if(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type)) - { - VMA_ASSERT(nextSuballoc.hAllocation != VK_NULL_HANDLE); - if(nextSuballoc.hAllocation->CanBecomeLost() && - nextSuballoc.hAllocation->GetLastUseFrameIndex() + frameInUseCount < currentFrameIndex) - { - ++*itemsToMakeLostCount; - } - else - { - return false; - } - } - } - else - { - // Already on next page. - break; - } - ++nextSuballocItem; - } - } - } - else - { - const VmaSuballocation& suballoc = *suballocItem; - VMA_ASSERT(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); - - *pSumFreeSize = suballoc.size; - - // Size of this suballocation is too small for this request: Early return. - if(suballoc.size < allocSize) - { - return false; - } - - // Start from offset equal to beginning of this suballocation. - *pOffset = suballoc.offset; - - // Apply VMA_DEBUG_MARGIN at the beginning. - if(VMA_DEBUG_MARGIN > 0) - { - *pOffset += VMA_DEBUG_MARGIN; - } - - // Apply alignment. - *pOffset = VmaAlignUp(*pOffset, allocAlignment); - - // Check previous suballocations for BufferImageGranularity conflicts. - // Make bigger alignment if necessary. - if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment) - { - bool bufferImageGranularityConflict = false; - VmaSuballocationList::const_iterator prevSuballocItem = suballocItem; - while(prevSuballocItem != m_Suballocations.cbegin()) - { - --prevSuballocItem; - const VmaSuballocation& prevSuballoc = *prevSuballocItem; - if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, *pOffset, bufferImageGranularity)) - { - if(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType)) - { - bufferImageGranularityConflict = true; - break; - } - } - else - // Already on previous page. - break; - } - if(bufferImageGranularityConflict) - { - *pOffset = VmaAlignUp(*pOffset, bufferImageGranularity); - } - } - - // Calculate padding at the beginning based on current offset. - const VkDeviceSize paddingBegin = *pOffset - suballoc.offset; - - // Calculate required margin at the end. - const VkDeviceSize requiredEndMargin = VMA_DEBUG_MARGIN; - - // Fail if requested size plus margin before and after is bigger than size of this suballocation. - if(paddingBegin + allocSize + requiredEndMargin > suballoc.size) - { - return false; - } - - // Check next suballocations for BufferImageGranularity conflicts. - // If conflict exists, allocation cannot be made here. - if(allocSize % bufferImageGranularity || *pOffset % bufferImageGranularity) - { - VmaSuballocationList::const_iterator nextSuballocItem = suballocItem; - ++nextSuballocItem; - while(nextSuballocItem != m_Suballocations.cend()) - { - const VmaSuballocation& nextSuballoc = *nextSuballocItem; - if(VmaBlocksOnSamePage(*pOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) - { - if(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type)) - { - return false; - } - } - else - { - // Already on next page. - break; - } - ++nextSuballocItem; - } - } - } - - // All tests passed: Success. pOffset is already filled. - return true; -} - -void VmaBlockMetadata_Generic::MergeFreeWithNext(VmaSuballocationList::iterator item) -{ - VMA_ASSERT(item != m_Suballocations.end()); - VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE); - - VmaSuballocationList::iterator nextItem = item; - ++nextItem; - VMA_ASSERT(nextItem != m_Suballocations.end()); - VMA_ASSERT(nextItem->type == VMA_SUBALLOCATION_TYPE_FREE); - - item->size += nextItem->size; - --m_FreeCount; - m_Suballocations.erase(nextItem); -} - -VmaSuballocationList::iterator VmaBlockMetadata_Generic::FreeSuballocation(VmaSuballocationList::iterator suballocItem) -{ - // Change this suballocation to be marked as free. - VmaSuballocation& suballoc = *suballocItem; - suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; - suballoc.hAllocation = VK_NULL_HANDLE; - - // Update totals. - ++m_FreeCount; - m_SumFreeSize += suballoc.size; - - // Merge with previous and/or next suballocation if it's also free. - bool mergeWithNext = false; - bool mergeWithPrev = false; - - VmaSuballocationList::iterator nextItem = suballocItem; - ++nextItem; - if((nextItem != m_Suballocations.end()) && (nextItem->type == VMA_SUBALLOCATION_TYPE_FREE)) - { - mergeWithNext = true; - } - - VmaSuballocationList::iterator prevItem = suballocItem; - if(suballocItem != m_Suballocations.begin()) - { - --prevItem; - if(prevItem->type == VMA_SUBALLOCATION_TYPE_FREE) - { - mergeWithPrev = true; - } - } - - if(mergeWithNext) - { - UnregisterFreeSuballocation(nextItem); - MergeFreeWithNext(suballocItem); - } - - if(mergeWithPrev) - { - UnregisterFreeSuballocation(prevItem); - MergeFreeWithNext(prevItem); - RegisterFreeSuballocation(prevItem); - return prevItem; - } - else - { - RegisterFreeSuballocation(suballocItem); - return suballocItem; - } -} - -void VmaBlockMetadata_Generic::RegisterFreeSuballocation(VmaSuballocationList::iterator item) -{ - VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE); - VMA_ASSERT(item->size > 0); - - // You may want to enable this validation at the beginning or at the end of - // this function, depending on what do you want to check. - VMA_HEAVY_ASSERT(ValidateFreeSuballocationList()); - - if(item->size >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) - { - if(m_FreeSuballocationsBySize.empty()) - { - m_FreeSuballocationsBySize.push_back(item); - } - else - { - VmaVectorInsertSorted(m_FreeSuballocationsBySize, item); - } - } - - //VMA_HEAVY_ASSERT(ValidateFreeSuballocationList()); -} - - -void VmaBlockMetadata_Generic::UnregisterFreeSuballocation(VmaSuballocationList::iterator item) -{ - VMA_ASSERT(item->type == VMA_SUBALLOCATION_TYPE_FREE); - VMA_ASSERT(item->size > 0); - - // You may want to enable this validation at the beginning or at the end of - // this function, depending on what do you want to check. - VMA_HEAVY_ASSERT(ValidateFreeSuballocationList()); - - if(item->size >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) - { - VmaSuballocationList::iterator* const it = VmaBinaryFindFirstNotLess( - m_FreeSuballocationsBySize.data(), - m_FreeSuballocationsBySize.data() + m_FreeSuballocationsBySize.size(), - item, - VmaSuballocationItemSizeLess()); - for(size_t index = it - m_FreeSuballocationsBySize.data(); - index < m_FreeSuballocationsBySize.size(); - ++index) - { - if(m_FreeSuballocationsBySize[index] == item) - { - VmaVectorRemove(m_FreeSuballocationsBySize, index); - return; - } - VMA_ASSERT((m_FreeSuballocationsBySize[index]->size == item->size) && "Not found."); - } - VMA_ASSERT(0 && "Not found."); - } - - //VMA_HEAVY_ASSERT(ValidateFreeSuballocationList()); -} - -bool VmaBlockMetadata_Generic::IsBufferImageGranularityConflictPossible( - VkDeviceSize bufferImageGranularity, - VmaSuballocationType& inOutPrevSuballocType) const -{ - if(bufferImageGranularity == 1 || IsEmpty()) - { - return false; - } - - VkDeviceSize minAlignment = VK_WHOLE_SIZE; - bool typeConflictFound = false; - for(const auto& suballoc : m_Suballocations) - { - const VmaSuballocationType suballocType = suballoc.type; - if(suballocType != VMA_SUBALLOCATION_TYPE_FREE) - { - minAlignment = VMA_MIN(minAlignment, suballoc.hAllocation->GetAlignment()); - if(VmaIsBufferImageGranularityConflict(inOutPrevSuballocType, suballocType)) - { - typeConflictFound = true; - } - inOutPrevSuballocType = suballocType; - } - } - - return typeConflictFound || minAlignment >= bufferImageGranularity; -} - -//////////////////////////////////////////////////////////////////////////////// -// class VmaBlockMetadata_Linear - -VmaBlockMetadata_Linear::VmaBlockMetadata_Linear(VmaAllocator hAllocator) : - VmaBlockMetadata(hAllocator), - m_SumFreeSize(0), - m_Suballocations0(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), - m_Suballocations1(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), - m_1stVectorIndex(0), - m_2ndVectorMode(SECOND_VECTOR_EMPTY), - m_1stNullItemsBeginCount(0), - m_1stNullItemsMiddleCount(0), - m_2ndNullItemsCount(0) -{ -} - -VmaBlockMetadata_Linear::~VmaBlockMetadata_Linear() -{ -} - -void VmaBlockMetadata_Linear::Init(VkDeviceSize size) -{ - VmaBlockMetadata::Init(size); - m_SumFreeSize = size; -} - -bool VmaBlockMetadata_Linear::Validate() const -{ - const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - - VMA_VALIDATE(suballocations2nd.empty() == (m_2ndVectorMode == SECOND_VECTOR_EMPTY)); - VMA_VALIDATE(!suballocations1st.empty() || - suballocations2nd.empty() || - m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER); - - if(!suballocations1st.empty()) - { - // Null item at the beginning should be accounted into m_1stNullItemsBeginCount. - VMA_VALIDATE(suballocations1st[m_1stNullItemsBeginCount].hAllocation != VK_NULL_HANDLE); - // Null item at the end should be just pop_back(). - VMA_VALIDATE(suballocations1st.back().hAllocation != VK_NULL_HANDLE); - } - if(!suballocations2nd.empty()) - { - // Null item at the end should be just pop_back(). - VMA_VALIDATE(suballocations2nd.back().hAllocation != VK_NULL_HANDLE); - } - - VMA_VALIDATE(m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount <= suballocations1st.size()); - VMA_VALIDATE(m_2ndNullItemsCount <= suballocations2nd.size()); - - VkDeviceSize sumUsedSize = 0; - const size_t suballoc1stCount = suballocations1st.size(); - VkDeviceSize offset = VMA_DEBUG_MARGIN; - - if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) - { - const size_t suballoc2ndCount = suballocations2nd.size(); - size_t nullItem2ndCount = 0; - for(size_t i = 0; i < suballoc2ndCount; ++i) - { - const VmaSuballocation& suballoc = suballocations2nd[i]; - const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); - - VMA_VALIDATE(currFree == (suballoc.hAllocation == VK_NULL_HANDLE)); - VMA_VALIDATE(suballoc.offset >= offset); - - if(!currFree) - { - VMA_VALIDATE(suballoc.hAllocation->GetOffset() == suballoc.offset); - VMA_VALIDATE(suballoc.hAllocation->GetSize() == suballoc.size); - sumUsedSize += suballoc.size; - } - else - { - ++nullItem2ndCount; - } - - offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN; - } - - VMA_VALIDATE(nullItem2ndCount == m_2ndNullItemsCount); - } - - for(size_t i = 0; i < m_1stNullItemsBeginCount; ++i) - { - const VmaSuballocation& suballoc = suballocations1st[i]; - VMA_VALIDATE(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE && - suballoc.hAllocation == VK_NULL_HANDLE); - } - - size_t nullItem1stCount = m_1stNullItemsBeginCount; - - for(size_t i = m_1stNullItemsBeginCount; i < suballoc1stCount; ++i) - { - const VmaSuballocation& suballoc = suballocations1st[i]; - const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); - - VMA_VALIDATE(currFree == (suballoc.hAllocation == VK_NULL_HANDLE)); - VMA_VALIDATE(suballoc.offset >= offset); - VMA_VALIDATE(i >= m_1stNullItemsBeginCount || currFree); - - if(!currFree) - { - VMA_VALIDATE(suballoc.hAllocation->GetOffset() == suballoc.offset); - VMA_VALIDATE(suballoc.hAllocation->GetSize() == suballoc.size); - sumUsedSize += suballoc.size; - } - else - { - ++nullItem1stCount; - } - - offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN; - } - VMA_VALIDATE(nullItem1stCount == m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount); - - if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) - { - const size_t suballoc2ndCount = suballocations2nd.size(); - size_t nullItem2ndCount = 0; - for(size_t i = suballoc2ndCount; i--; ) - { - const VmaSuballocation& suballoc = suballocations2nd[i]; - const bool currFree = (suballoc.type == VMA_SUBALLOCATION_TYPE_FREE); - - VMA_VALIDATE(currFree == (suballoc.hAllocation == VK_NULL_HANDLE)); - VMA_VALIDATE(suballoc.offset >= offset); - - if(!currFree) - { - VMA_VALIDATE(suballoc.hAllocation->GetOffset() == suballoc.offset); - VMA_VALIDATE(suballoc.hAllocation->GetSize() == suballoc.size); - sumUsedSize += suballoc.size; - } - else - { - ++nullItem2ndCount; - } - - offset = suballoc.offset + suballoc.size + VMA_DEBUG_MARGIN; - } - - VMA_VALIDATE(nullItem2ndCount == m_2ndNullItemsCount); - } - - VMA_VALIDATE(offset <= GetSize()); - VMA_VALIDATE(m_SumFreeSize == GetSize() - sumUsedSize); - - return true; -} - -size_t VmaBlockMetadata_Linear::GetAllocationCount() const -{ - return AccessSuballocations1st().size() - (m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount) + - AccessSuballocations2nd().size() - m_2ndNullItemsCount; -} - -VkDeviceSize VmaBlockMetadata_Linear::GetUnusedRangeSizeMax() const -{ - const VkDeviceSize size = GetSize(); - - /* - We don't consider gaps inside allocation vectors with freed allocations because - they are not suitable for reuse in linear allocator. We consider only space that - is available for new allocations. - */ - if(IsEmpty()) - { - return size; - } - - const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - - switch(m_2ndVectorMode) - { - case SECOND_VECTOR_EMPTY: - /* - Available space is after end of 1st, as well as before beginning of 1st (which - would make it a ring buffer). - */ - { - const size_t suballocations1stCount = suballocations1st.size(); - VMA_ASSERT(suballocations1stCount > m_1stNullItemsBeginCount); - const VmaSuballocation& firstSuballoc = suballocations1st[m_1stNullItemsBeginCount]; - const VmaSuballocation& lastSuballoc = suballocations1st[suballocations1stCount - 1]; - return VMA_MAX( - firstSuballoc.offset, - size - (lastSuballoc.offset + lastSuballoc.size)); - } - break; - - case SECOND_VECTOR_RING_BUFFER: - /* - Available space is only between end of 2nd and beginning of 1st. - */ - { - const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - const VmaSuballocation& lastSuballoc2nd = suballocations2nd.back(); - const VmaSuballocation& firstSuballoc1st = suballocations1st[m_1stNullItemsBeginCount]; - return firstSuballoc1st.offset - (lastSuballoc2nd.offset + lastSuballoc2nd.size); - } - break; - - case SECOND_VECTOR_DOUBLE_STACK: - /* - Available space is only between end of 1st and top of 2nd. - */ - { - const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - const VmaSuballocation& topSuballoc2nd = suballocations2nd.back(); - const VmaSuballocation& lastSuballoc1st = suballocations1st.back(); - return topSuballoc2nd.offset - (lastSuballoc1st.offset + lastSuballoc1st.size); - } - break; - - default: - VMA_ASSERT(0); - return 0; - } -} - -void VmaBlockMetadata_Linear::CalcAllocationStatInfo(VmaStatInfo& outInfo) const -{ - const VkDeviceSize size = GetSize(); - const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - const size_t suballoc1stCount = suballocations1st.size(); - const size_t suballoc2ndCount = suballocations2nd.size(); - - outInfo.blockCount = 1; - outInfo.allocationCount = (uint32_t)GetAllocationCount(); - outInfo.unusedRangeCount = 0; - outInfo.usedBytes = 0; - outInfo.allocationSizeMin = UINT64_MAX; - outInfo.allocationSizeMax = 0; - outInfo.unusedRangeSizeMin = UINT64_MAX; - outInfo.unusedRangeSizeMax = 0; - - VkDeviceSize lastOffset = 0; - - if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) - { - const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; - size_t nextAlloc2ndIndex = 0; - while(lastOffset < freeSpace2ndTo1stEnd) - { - // Find next non-null allocation or move nextAllocIndex to the end. - while(nextAlloc2ndIndex < suballoc2ndCount && - suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) - { - ++nextAlloc2ndIndex; - } - - // Found non-null allocation. - if(nextAlloc2ndIndex < suballoc2ndCount) - { - const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; - ++outInfo.unusedRangeCount; - outInfo.unusedBytes += unusedRangeSize; - outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); - outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - outInfo.usedBytes += suballoc.size; - outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size); - outInfo.allocationSizeMax = VMA_MIN(outInfo.allocationSizeMax, suballoc.size); - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - ++nextAlloc2ndIndex; - } - // We are at the end. - else - { - // There is free space from lastOffset to freeSpace2ndTo1stEnd. - if(lastOffset < freeSpace2ndTo1stEnd) - { - const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset; - ++outInfo.unusedRangeCount; - outInfo.unusedBytes += unusedRangeSize; - outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); - outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); - } - - // End of loop. - lastOffset = freeSpace2ndTo1stEnd; - } - } - } - - size_t nextAlloc1stIndex = m_1stNullItemsBeginCount; - const VkDeviceSize freeSpace1stTo2ndEnd = - m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size; - while(lastOffset < freeSpace1stTo2ndEnd) - { - // Find next non-null allocation or move nextAllocIndex to the end. - while(nextAlloc1stIndex < suballoc1stCount && - suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE) - { - ++nextAlloc1stIndex; - } - - // Found non-null allocation. - if(nextAlloc1stIndex < suballoc1stCount) - { - const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; - ++outInfo.unusedRangeCount; - outInfo.unusedBytes += unusedRangeSize; - outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); - outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - outInfo.usedBytes += suballoc.size; - outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size); - outInfo.allocationSizeMax = VMA_MIN(outInfo.allocationSizeMax, suballoc.size); - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - ++nextAlloc1stIndex; - } - // We are at the end. - else - { - // There is free space from lastOffset to freeSpace1stTo2ndEnd. - if(lastOffset < freeSpace1stTo2ndEnd) - { - const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset; - ++outInfo.unusedRangeCount; - outInfo.unusedBytes += unusedRangeSize; - outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); - outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); - } - - // End of loop. - lastOffset = freeSpace1stTo2ndEnd; - } - } - - if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) - { - size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; - while(lastOffset < size) - { - // Find next non-null allocation or move nextAllocIndex to the end. - while(nextAlloc2ndIndex != SIZE_MAX && - suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) - { - --nextAlloc2ndIndex; - } - - // Found non-null allocation. - if(nextAlloc2ndIndex != SIZE_MAX) - { - const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; - ++outInfo.unusedRangeCount; - outInfo.unusedBytes += unusedRangeSize; - outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); - outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - outInfo.usedBytes += suballoc.size; - outInfo.allocationSizeMin = VMA_MIN(outInfo.allocationSizeMin, suballoc.size); - outInfo.allocationSizeMax = VMA_MIN(outInfo.allocationSizeMax, suballoc.size); - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - --nextAlloc2ndIndex; - } - // We are at the end. - else - { - // There is free space from lastOffset to size. - if(lastOffset < size) - { - const VkDeviceSize unusedRangeSize = size - lastOffset; - ++outInfo.unusedRangeCount; - outInfo.unusedBytes += unusedRangeSize; - outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusedRangeSize); - outInfo.unusedRangeSizeMax = VMA_MIN(outInfo.unusedRangeSizeMax, unusedRangeSize); - } - - // End of loop. - lastOffset = size; - } - } - } - - outInfo.unusedBytes = size - outInfo.usedBytes; -} - -void VmaBlockMetadata_Linear::AddPoolStats(VmaPoolStats& inoutStats) const -{ - const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - const VkDeviceSize size = GetSize(); - const size_t suballoc1stCount = suballocations1st.size(); - const size_t suballoc2ndCount = suballocations2nd.size(); - - inoutStats.size += size; - - VkDeviceSize lastOffset = 0; - - if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) - { - const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; - size_t nextAlloc2ndIndex = m_1stNullItemsBeginCount; - while(lastOffset < freeSpace2ndTo1stEnd) - { - // Find next non-null allocation or move nextAlloc2ndIndex to the end. - while(nextAlloc2ndIndex < suballoc2ndCount && - suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) - { - ++nextAlloc2ndIndex; - } - - // Found non-null allocation. - if(nextAlloc2ndIndex < suballoc2ndCount) - { - const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; - inoutStats.unusedSize += unusedRangeSize; - ++inoutStats.unusedRangeCount; - inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - ++inoutStats.allocationCount; - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - ++nextAlloc2ndIndex; - } - // We are at the end. - else - { - if(lastOffset < freeSpace2ndTo1stEnd) - { - // There is free space from lastOffset to freeSpace2ndTo1stEnd. - const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset; - inoutStats.unusedSize += unusedRangeSize; - ++inoutStats.unusedRangeCount; - inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); - } - - // End of loop. - lastOffset = freeSpace2ndTo1stEnd; - } - } - } - - size_t nextAlloc1stIndex = m_1stNullItemsBeginCount; - const VkDeviceSize freeSpace1stTo2ndEnd = - m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size; - while(lastOffset < freeSpace1stTo2ndEnd) - { - // Find next non-null allocation or move nextAllocIndex to the end. - while(nextAlloc1stIndex < suballoc1stCount && - suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE) - { - ++nextAlloc1stIndex; - } - - // Found non-null allocation. - if(nextAlloc1stIndex < suballoc1stCount) - { - const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; - inoutStats.unusedSize += unusedRangeSize; - ++inoutStats.unusedRangeCount; - inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - ++inoutStats.allocationCount; - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - ++nextAlloc1stIndex; - } - // We are at the end. - else - { - if(lastOffset < freeSpace1stTo2ndEnd) - { - // There is free space from lastOffset to freeSpace1stTo2ndEnd. - const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset; - inoutStats.unusedSize += unusedRangeSize; - ++inoutStats.unusedRangeCount; - inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); - } - - // End of loop. - lastOffset = freeSpace1stTo2ndEnd; - } - } - - if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) - { - size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; - while(lastOffset < size) - { - // Find next non-null allocation or move nextAlloc2ndIndex to the end. - while(nextAlloc2ndIndex != SIZE_MAX && - suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) - { - --nextAlloc2ndIndex; - } - - // Found non-null allocation. - if(nextAlloc2ndIndex != SIZE_MAX) - { - const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; - inoutStats.unusedSize += unusedRangeSize; - ++inoutStats.unusedRangeCount; - inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - ++inoutStats.allocationCount; - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - --nextAlloc2ndIndex; - } - // We are at the end. - else - { - if(lastOffset < size) - { - // There is free space from lastOffset to size. - const VkDeviceSize unusedRangeSize = size - lastOffset; - inoutStats.unusedSize += unusedRangeSize; - ++inoutStats.unusedRangeCount; - inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, unusedRangeSize); - } - - // End of loop. - lastOffset = size; - } - } - } -} - -#if VMA_STATS_STRING_ENABLED -void VmaBlockMetadata_Linear::PrintDetailedMap(class VmaJsonWriter& json) const -{ - const VkDeviceSize size = GetSize(); - const SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - const SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - const size_t suballoc1stCount = suballocations1st.size(); - const size_t suballoc2ndCount = suballocations2nd.size(); - - // FIRST PASS - - size_t unusedRangeCount = 0; - VkDeviceSize usedBytes = 0; - - VkDeviceSize lastOffset = 0; - - size_t alloc2ndCount = 0; - if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) - { - const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; - size_t nextAlloc2ndIndex = 0; - while(lastOffset < freeSpace2ndTo1stEnd) - { - // Find next non-null allocation or move nextAlloc2ndIndex to the end. - while(nextAlloc2ndIndex < suballoc2ndCount && - suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) - { - ++nextAlloc2ndIndex; - } - - // Found non-null allocation. - if(nextAlloc2ndIndex < suballoc2ndCount) - { - const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - ++unusedRangeCount; - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - ++alloc2ndCount; - usedBytes += suballoc.size; - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - ++nextAlloc2ndIndex; - } - // We are at the end. - else - { - if(lastOffset < freeSpace2ndTo1stEnd) - { - // There is free space from lastOffset to freeSpace2ndTo1stEnd. - ++unusedRangeCount; - } - - // End of loop. - lastOffset = freeSpace2ndTo1stEnd; - } - } - } - - size_t nextAlloc1stIndex = m_1stNullItemsBeginCount; - size_t alloc1stCount = 0; - const VkDeviceSize freeSpace1stTo2ndEnd = - m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? suballocations2nd.back().offset : size; - while(lastOffset < freeSpace1stTo2ndEnd) - { - // Find next non-null allocation or move nextAllocIndex to the end. - while(nextAlloc1stIndex < suballoc1stCount && - suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE) - { - ++nextAlloc1stIndex; - } - - // Found non-null allocation. - if(nextAlloc1stIndex < suballoc1stCount) - { - const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - ++unusedRangeCount; - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - ++alloc1stCount; - usedBytes += suballoc.size; - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - ++nextAlloc1stIndex; - } - // We are at the end. - else - { - if(lastOffset < size) - { - // There is free space from lastOffset to freeSpace1stTo2ndEnd. - ++unusedRangeCount; - } - - // End of loop. - lastOffset = freeSpace1stTo2ndEnd; - } - } - - if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) - { - size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; - while(lastOffset < size) - { - // Find next non-null allocation or move nextAlloc2ndIndex to the end. - while(nextAlloc2ndIndex != SIZE_MAX && - suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) - { - --nextAlloc2ndIndex; - } - - // Found non-null allocation. - if(nextAlloc2ndIndex != SIZE_MAX) - { - const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - ++unusedRangeCount; - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - ++alloc2ndCount; - usedBytes += suballoc.size; - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - --nextAlloc2ndIndex; - } - // We are at the end. - else - { - if(lastOffset < size) - { - // There is free space from lastOffset to size. - ++unusedRangeCount; - } - - // End of loop. - lastOffset = size; - } - } - } - - const VkDeviceSize unusedBytes = size - usedBytes; - PrintDetailedMap_Begin(json, unusedBytes, alloc1stCount + alloc2ndCount, unusedRangeCount); - - // SECOND PASS - lastOffset = 0; - - if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) - { - const VkDeviceSize freeSpace2ndTo1stEnd = suballocations1st[m_1stNullItemsBeginCount].offset; - size_t nextAlloc2ndIndex = 0; - while(lastOffset < freeSpace2ndTo1stEnd) - { - // Find next non-null allocation or move nextAlloc2ndIndex to the end. - while(nextAlloc2ndIndex < suballoc2ndCount && - suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) - { - ++nextAlloc2ndIndex; - } - - // Found non-null allocation. - if(nextAlloc2ndIndex < suballoc2ndCount) - { - const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; - PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation); - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - ++nextAlloc2ndIndex; - } - // We are at the end. - else - { - if(lastOffset < freeSpace2ndTo1stEnd) - { - // There is free space from lastOffset to freeSpace2ndTo1stEnd. - const VkDeviceSize unusedRangeSize = freeSpace2ndTo1stEnd - lastOffset; - PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); - } - - // End of loop. - lastOffset = freeSpace2ndTo1stEnd; - } - } - } - - nextAlloc1stIndex = m_1stNullItemsBeginCount; - while(lastOffset < freeSpace1stTo2ndEnd) - { - // Find next non-null allocation or move nextAllocIndex to the end. - while(nextAlloc1stIndex < suballoc1stCount && - suballocations1st[nextAlloc1stIndex].hAllocation == VK_NULL_HANDLE) - { - ++nextAlloc1stIndex; - } - - // Found non-null allocation. - if(nextAlloc1stIndex < suballoc1stCount) - { - const VmaSuballocation& suballoc = suballocations1st[nextAlloc1stIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; - PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation); - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - ++nextAlloc1stIndex; - } - // We are at the end. - else - { - if(lastOffset < freeSpace1stTo2ndEnd) - { - // There is free space from lastOffset to freeSpace1stTo2ndEnd. - const VkDeviceSize unusedRangeSize = freeSpace1stTo2ndEnd - lastOffset; - PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); - } - - // End of loop. - lastOffset = freeSpace1stTo2ndEnd; - } - } - - if(m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) - { - size_t nextAlloc2ndIndex = suballocations2nd.size() - 1; - while(lastOffset < size) - { - // Find next non-null allocation or move nextAlloc2ndIndex to the end. - while(nextAlloc2ndIndex != SIZE_MAX && - suballocations2nd[nextAlloc2ndIndex].hAllocation == VK_NULL_HANDLE) - { - --nextAlloc2ndIndex; - } - - // Found non-null allocation. - if(nextAlloc2ndIndex != SIZE_MAX) - { - const VmaSuballocation& suballoc = suballocations2nd[nextAlloc2ndIndex]; - - // 1. Process free space before this allocation. - if(lastOffset < suballoc.offset) - { - // There is free space from lastOffset to suballoc.offset. - const VkDeviceSize unusedRangeSize = suballoc.offset - lastOffset; - PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); - } - - // 2. Process this allocation. - // There is allocation with suballoc.offset, suballoc.size. - PrintDetailedMap_Allocation(json, suballoc.offset, suballoc.hAllocation); - - // 3. Prepare for next iteration. - lastOffset = suballoc.offset + suballoc.size; - --nextAlloc2ndIndex; - } - // We are at the end. - else - { - if(lastOffset < size) - { - // There is free space from lastOffset to size. - const VkDeviceSize unusedRangeSize = size - lastOffset; - PrintDetailedMap_UnusedRange(json, lastOffset, unusedRangeSize); - } - - // End of loop. - lastOffset = size; - } - } - } - - PrintDetailedMap_End(json); -} -#endif // #if VMA_STATS_STRING_ENABLED - -bool VmaBlockMetadata_Linear::CreateAllocationRequest( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, - VkDeviceSize allocSize, - VkDeviceSize allocAlignment, - bool upperAddress, - VmaSuballocationType allocType, - bool canMakeOtherLost, - uint32_t strategy, - VmaAllocationRequest* pAllocationRequest) -{ - VMA_ASSERT(allocSize > 0); - VMA_ASSERT(allocType != VMA_SUBALLOCATION_TYPE_FREE); - VMA_ASSERT(pAllocationRequest != VMA_NULL); - VMA_HEAVY_ASSERT(Validate()); - return upperAddress ? - CreateAllocationRequest_UpperAddress( - currentFrameIndex, frameInUseCount, bufferImageGranularity, - allocSize, allocAlignment, allocType, canMakeOtherLost, strategy, pAllocationRequest) : - CreateAllocationRequest_LowerAddress( - currentFrameIndex, frameInUseCount, bufferImageGranularity, - allocSize, allocAlignment, allocType, canMakeOtherLost, strategy, pAllocationRequest); -} - -bool VmaBlockMetadata_Linear::CreateAllocationRequest_UpperAddress( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, - VkDeviceSize allocSize, - VkDeviceSize allocAlignment, - VmaSuballocationType allocType, - bool canMakeOtherLost, - uint32_t strategy, - VmaAllocationRequest* pAllocationRequest) -{ - const VkDeviceSize size = GetSize(); - SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - - if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) - { - VMA_ASSERT(0 && "Trying to use pool with linear algorithm as double stack, while it is already being used as ring buffer."); - return false; - } - - // Try to allocate before 2nd.back(), or end of block if 2nd.empty(). - if(allocSize > size) - { - return false; - } - VkDeviceSize resultBaseOffset = size - allocSize; - if(!suballocations2nd.empty()) - { - const VmaSuballocation& lastSuballoc = suballocations2nd.back(); - resultBaseOffset = lastSuballoc.offset - allocSize; - if(allocSize > lastSuballoc.offset) - { - return false; - } - } - - // Start from offset equal to end of free space. - VkDeviceSize resultOffset = resultBaseOffset; - - // Apply VMA_DEBUG_MARGIN at the end. - if(VMA_DEBUG_MARGIN > 0) - { - if(resultOffset < VMA_DEBUG_MARGIN) - { - return false; - } - resultOffset -= VMA_DEBUG_MARGIN; - } - - // Apply alignment. - resultOffset = VmaAlignDown(resultOffset, allocAlignment); - - // Check next suballocations from 2nd for BufferImageGranularity conflicts. - // Make bigger alignment if necessary. - if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations2nd.empty()) - { - bool bufferImageGranularityConflict = false; - for(size_t nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; ) - { - const VmaSuballocation& nextSuballoc = suballocations2nd[nextSuballocIndex]; - if(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) - { - if(VmaIsBufferImageGranularityConflict(nextSuballoc.type, allocType)) - { - bufferImageGranularityConflict = true; - break; - } - } - else - // Already on previous page. - break; - } - if(bufferImageGranularityConflict) - { - resultOffset = VmaAlignDown(resultOffset, bufferImageGranularity); - } - } - - // There is enough free space. - const VkDeviceSize endOf1st = !suballocations1st.empty() ? - suballocations1st.back().offset + suballocations1st.back().size : - 0; - if(endOf1st + VMA_DEBUG_MARGIN <= resultOffset) - { - // Check previous suballocations for BufferImageGranularity conflicts. - // If conflict exists, allocation cannot be made here. - if(bufferImageGranularity > 1) - { - for(size_t prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; ) - { - const VmaSuballocation& prevSuballoc = suballocations1st[prevSuballocIndex]; - if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity)) - { - if(VmaIsBufferImageGranularityConflict(allocType, prevSuballoc.type)) - { - return false; - } - } - else - { - // Already on next page. - break; - } - } - } - - // All tests passed: Success. - pAllocationRequest->offset = resultOffset; - pAllocationRequest->sumFreeSize = resultBaseOffset + allocSize - endOf1st; - pAllocationRequest->sumItemSize = 0; - // pAllocationRequest->item unused. - pAllocationRequest->itemsToMakeLostCount = 0; - pAllocationRequest->type = VmaAllocationRequestType::UpperAddress; - return true; - } - - return false; -} - -bool VmaBlockMetadata_Linear::CreateAllocationRequest_LowerAddress( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, - VkDeviceSize allocSize, - VkDeviceSize allocAlignment, - VmaSuballocationType allocType, - bool canMakeOtherLost, - uint32_t strategy, - VmaAllocationRequest* pAllocationRequest) -{ - const VkDeviceSize size = GetSize(); - SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - - if(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) - { - // Try to allocate at the end of 1st vector. - - VkDeviceSize resultBaseOffset = 0; - if(!suballocations1st.empty()) - { - const VmaSuballocation& lastSuballoc = suballocations1st.back(); - resultBaseOffset = lastSuballoc.offset + lastSuballoc.size; - } - - // Start from offset equal to beginning of free space. - VkDeviceSize resultOffset = resultBaseOffset; - - // Apply VMA_DEBUG_MARGIN at the beginning. - if(VMA_DEBUG_MARGIN > 0) - { - resultOffset += VMA_DEBUG_MARGIN; - } - - // Apply alignment. - resultOffset = VmaAlignUp(resultOffset, allocAlignment); - - // Check previous suballocations for BufferImageGranularity conflicts. - // Make bigger alignment if necessary. - if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations1st.empty()) - { - bool bufferImageGranularityConflict = false; - for(size_t prevSuballocIndex = suballocations1st.size(); prevSuballocIndex--; ) - { - const VmaSuballocation& prevSuballoc = suballocations1st[prevSuballocIndex]; - if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity)) - { - if(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType)) - { - bufferImageGranularityConflict = true; - break; - } - } - else - // Already on previous page. - break; - } - if(bufferImageGranularityConflict) - { - resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity); - } - } - - const VkDeviceSize freeSpaceEnd = m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK ? - suballocations2nd.back().offset : size; - - // There is enough free space at the end after alignment. - if(resultOffset + allocSize + VMA_DEBUG_MARGIN <= freeSpaceEnd) - { - // Check next suballocations for BufferImageGranularity conflicts. - // If conflict exists, allocation cannot be made here. - if((allocSize % bufferImageGranularity || resultOffset % bufferImageGranularity) && m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) - { - for(size_t nextSuballocIndex = suballocations2nd.size(); nextSuballocIndex--; ) - { - const VmaSuballocation& nextSuballoc = suballocations2nd[nextSuballocIndex]; - if(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) - { - if(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type)) - { - return false; - } - } - else - { - // Already on previous page. - break; - } - } - } - - // All tests passed: Success. - pAllocationRequest->offset = resultOffset; - pAllocationRequest->sumFreeSize = freeSpaceEnd - resultBaseOffset; - pAllocationRequest->sumItemSize = 0; - // pAllocationRequest->item, customData unused. - pAllocationRequest->type = VmaAllocationRequestType::EndOf1st; - pAllocationRequest->itemsToMakeLostCount = 0; - return true; - } - } - - // Wrap-around to end of 2nd vector. Try to allocate there, watching for the - // beginning of 1st vector as the end of free space. - if(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) - { - VMA_ASSERT(!suballocations1st.empty()); - - VkDeviceSize resultBaseOffset = 0; - if(!suballocations2nd.empty()) - { - const VmaSuballocation& lastSuballoc = suballocations2nd.back(); - resultBaseOffset = lastSuballoc.offset + lastSuballoc.size; - } - - // Start from offset equal to beginning of free space. - VkDeviceSize resultOffset = resultBaseOffset; - - // Apply VMA_DEBUG_MARGIN at the beginning. - if(VMA_DEBUG_MARGIN > 0) - { - resultOffset += VMA_DEBUG_MARGIN; - } - - // Apply alignment. - resultOffset = VmaAlignUp(resultOffset, allocAlignment); - - // Check previous suballocations for BufferImageGranularity conflicts. - // Make bigger alignment if necessary. - if(bufferImageGranularity > 1 && bufferImageGranularity != allocAlignment && !suballocations2nd.empty()) - { - bool bufferImageGranularityConflict = false; - for(size_t prevSuballocIndex = suballocations2nd.size(); prevSuballocIndex--; ) - { - const VmaSuballocation& prevSuballoc = suballocations2nd[prevSuballocIndex]; - if(VmaBlocksOnSamePage(prevSuballoc.offset, prevSuballoc.size, resultOffset, bufferImageGranularity)) - { - if(VmaIsBufferImageGranularityConflict(prevSuballoc.type, allocType)) - { - bufferImageGranularityConflict = true; - break; - } - } - else - // Already on previous page. - break; - } - if(bufferImageGranularityConflict) - { - resultOffset = VmaAlignUp(resultOffset, bufferImageGranularity); - } - } - - pAllocationRequest->itemsToMakeLostCount = 0; - pAllocationRequest->sumItemSize = 0; - size_t index1st = m_1stNullItemsBeginCount; - - if(canMakeOtherLost) - { - while(index1st < suballocations1st.size() && - resultOffset + allocSize + VMA_DEBUG_MARGIN > suballocations1st[index1st].offset) - { - // Next colliding allocation at the beginning of 1st vector found. Try to make it lost. - const VmaSuballocation& suballoc = suballocations1st[index1st]; - if(suballoc.type == VMA_SUBALLOCATION_TYPE_FREE) - { - // No problem. - } - else - { - VMA_ASSERT(suballoc.hAllocation != VK_NULL_HANDLE); - if(suballoc.hAllocation->CanBecomeLost() && - suballoc.hAllocation->GetLastUseFrameIndex() + frameInUseCount < currentFrameIndex) - { - ++pAllocationRequest->itemsToMakeLostCount; - pAllocationRequest->sumItemSize += suballoc.size; - } - else - { - return false; - } - } - ++index1st; - } - - // Check next suballocations for BufferImageGranularity conflicts. - // If conflict exists, we must mark more allocations lost or fail. - if(allocSize % bufferImageGranularity || resultOffset % bufferImageGranularity) - { - while(index1st < suballocations1st.size()) - { - const VmaSuballocation& suballoc = suballocations1st[index1st]; - if(VmaBlocksOnSamePage(resultOffset, allocSize, suballoc.offset, bufferImageGranularity)) - { - if(suballoc.hAllocation != VK_NULL_HANDLE) - { - // Not checking actual VmaIsBufferImageGranularityConflict(allocType, suballoc.type). - if(suballoc.hAllocation->CanBecomeLost() && - suballoc.hAllocation->GetLastUseFrameIndex() + frameInUseCount < currentFrameIndex) - { - ++pAllocationRequest->itemsToMakeLostCount; - pAllocationRequest->sumItemSize += suballoc.size; - } - else - { - return false; - } - } - } - else - { - // Already on next page. - break; - } - ++index1st; - } - } - - // Special case: There is not enough room at the end for this allocation, even after making all from the 1st lost. - if(index1st == suballocations1st.size() && - resultOffset + allocSize + VMA_DEBUG_MARGIN > size) - { - // TODO: This is a known bug that it's not yet implemented and the allocation is failing. - VMA_DEBUG_LOG("Unsupported special case in custom pool with linear allocation algorithm used as ring buffer with allocations that can be lost."); - } - } - - // There is enough free space at the end after alignment. - if((index1st == suballocations1st.size() && resultOffset + allocSize + VMA_DEBUG_MARGIN <= size) || - (index1st < suballocations1st.size() && resultOffset + allocSize + VMA_DEBUG_MARGIN <= suballocations1st[index1st].offset)) - { - // Check next suballocations for BufferImageGranularity conflicts. - // If conflict exists, allocation cannot be made here. - if(allocSize % bufferImageGranularity || resultOffset % bufferImageGranularity) - { - for(size_t nextSuballocIndex = index1st; - nextSuballocIndex < suballocations1st.size(); - nextSuballocIndex++) - { - const VmaSuballocation& nextSuballoc = suballocations1st[nextSuballocIndex]; - if(VmaBlocksOnSamePage(resultOffset, allocSize, nextSuballoc.offset, bufferImageGranularity)) - { - if(VmaIsBufferImageGranularityConflict(allocType, nextSuballoc.type)) - { - return false; - } - } - else - { - // Already on next page. - break; - } - } - } - - // All tests passed: Success. - pAllocationRequest->offset = resultOffset; - pAllocationRequest->sumFreeSize = - (index1st < suballocations1st.size() ? suballocations1st[index1st].offset : size) - - resultBaseOffset - - pAllocationRequest->sumItemSize; - pAllocationRequest->type = VmaAllocationRequestType::EndOf2nd; - // pAllocationRequest->item, customData unused. - return true; - } - } - - return false; -} - -bool VmaBlockMetadata_Linear::MakeRequestedAllocationsLost( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VmaAllocationRequest* pAllocationRequest) -{ - if(pAllocationRequest->itemsToMakeLostCount == 0) - { - return true; - } - - VMA_ASSERT(m_2ndVectorMode == SECOND_VECTOR_EMPTY || m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER); - - // We always start from 1st. - SuballocationVectorType* suballocations = &AccessSuballocations1st(); - size_t index = m_1stNullItemsBeginCount; - size_t madeLostCount = 0; - while(madeLostCount < pAllocationRequest->itemsToMakeLostCount) - { - if(index == suballocations->size()) - { - index = 0; - // If we get to the end of 1st, we wrap around to beginning of 2nd of 1st. - if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) - { - suballocations = &AccessSuballocations2nd(); - } - // else: m_2ndVectorMode == SECOND_VECTOR_EMPTY: - // suballocations continues pointing at AccessSuballocations1st(). - VMA_ASSERT(!suballocations->empty()); - } - VmaSuballocation& suballoc = (*suballocations)[index]; - if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) - { - VMA_ASSERT(suballoc.hAllocation != VK_NULL_HANDLE); - VMA_ASSERT(suballoc.hAllocation->CanBecomeLost()); - if(suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount)) - { - suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; - suballoc.hAllocation = VK_NULL_HANDLE; - m_SumFreeSize += suballoc.size; - if(suballocations == &AccessSuballocations1st()) - { - ++m_1stNullItemsMiddleCount; - } - else - { - ++m_2ndNullItemsCount; - } - ++madeLostCount; - } - else - { - return false; - } - } - ++index; - } - - CleanupAfterFree(); - //VMA_HEAVY_ASSERT(Validate()); // Already called by CleanupAfterFree(). - - return true; -} - -uint32_t VmaBlockMetadata_Linear::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) -{ - uint32_t lostAllocationCount = 0; - - SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - for(size_t i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i < count; ++i) - { - VmaSuballocation& suballoc = suballocations1st[i]; - if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE && - suballoc.hAllocation->CanBecomeLost() && - suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount)) - { - suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; - suballoc.hAllocation = VK_NULL_HANDLE; - ++m_1stNullItemsMiddleCount; - m_SumFreeSize += suballoc.size; - ++lostAllocationCount; - } - } - - SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - for(size_t i = 0, count = suballocations2nd.size(); i < count; ++i) - { - VmaSuballocation& suballoc = suballocations2nd[i]; - if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE && - suballoc.hAllocation->CanBecomeLost() && - suballoc.hAllocation->MakeLost(currentFrameIndex, frameInUseCount)) - { - suballoc.type = VMA_SUBALLOCATION_TYPE_FREE; - suballoc.hAllocation = VK_NULL_HANDLE; - ++m_2ndNullItemsCount; - m_SumFreeSize += suballoc.size; - ++lostAllocationCount; - } - } - - if(lostAllocationCount) - { - CleanupAfterFree(); - } - - return lostAllocationCount; -} - -VkResult VmaBlockMetadata_Linear::CheckCorruption(const void* pBlockData) -{ - SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - for(size_t i = m_1stNullItemsBeginCount, count = suballocations1st.size(); i < count; ++i) - { - const VmaSuballocation& suballoc = suballocations1st[i]; - if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) - { - if(!VmaValidateMagicValue(pBlockData, suballoc.offset - VMA_DEBUG_MARGIN)) - { - VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!"); - return VK_ERROR_UNKNOWN; - } - if(!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size)) - { - VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!"); - return VK_ERROR_UNKNOWN; - } - } - } - - SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - for(size_t i = 0, count = suballocations2nd.size(); i < count; ++i) - { - const VmaSuballocation& suballoc = suballocations2nd[i]; - if(suballoc.type != VMA_SUBALLOCATION_TYPE_FREE) - { - if(!VmaValidateMagicValue(pBlockData, suballoc.offset - VMA_DEBUG_MARGIN)) - { - VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE VALIDATED ALLOCATION!"); - return VK_ERROR_UNKNOWN; - } - if(!VmaValidateMagicValue(pBlockData, suballoc.offset + suballoc.size)) - { - VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER VALIDATED ALLOCATION!"); - return VK_ERROR_UNKNOWN; - } - } - } - - return VK_SUCCESS; -} - -void VmaBlockMetadata_Linear::Alloc( - const VmaAllocationRequest& request, - VmaSuballocationType type, - VkDeviceSize allocSize, - VmaAllocation hAllocation) -{ - const VmaSuballocation newSuballoc = { request.offset, allocSize, hAllocation, type }; - - switch(request.type) - { - case VmaAllocationRequestType::UpperAddress: - { - VMA_ASSERT(m_2ndVectorMode != SECOND_VECTOR_RING_BUFFER && - "CRITICAL ERROR: Trying to use linear allocator as double stack while it was already used as ring buffer."); - SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - suballocations2nd.push_back(newSuballoc); - m_2ndVectorMode = SECOND_VECTOR_DOUBLE_STACK; - } - break; - case VmaAllocationRequestType::EndOf1st: - { - SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - - VMA_ASSERT(suballocations1st.empty() || - request.offset >= suballocations1st.back().offset + suballocations1st.back().size); - // Check if it fits before the end of the block. - VMA_ASSERT(request.offset + allocSize <= GetSize()); - - suballocations1st.push_back(newSuballoc); - } - break; - case VmaAllocationRequestType::EndOf2nd: - { - SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - // New allocation at the end of 2-part ring buffer, so before first allocation from 1st vector. - VMA_ASSERT(!suballocations1st.empty() && - request.offset + allocSize <= suballocations1st[m_1stNullItemsBeginCount].offset); - SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - - switch(m_2ndVectorMode) - { - case SECOND_VECTOR_EMPTY: - // First allocation from second part ring buffer. - VMA_ASSERT(suballocations2nd.empty()); - m_2ndVectorMode = SECOND_VECTOR_RING_BUFFER; - break; - case SECOND_VECTOR_RING_BUFFER: - // 2-part ring buffer is already started. - VMA_ASSERT(!suballocations2nd.empty()); - break; - case SECOND_VECTOR_DOUBLE_STACK: - VMA_ASSERT(0 && "CRITICAL ERROR: Trying to use linear allocator as ring buffer while it was already used as double stack."); - break; - default: - VMA_ASSERT(0); - } - - suballocations2nd.push_back(newSuballoc); - } - break; - default: - VMA_ASSERT(0 && "CRITICAL INTERNAL ERROR."); - } - - m_SumFreeSize -= newSuballoc.size; -} - -void VmaBlockMetadata_Linear::Free(const VmaAllocation allocation) -{ - FreeAtOffset(allocation->GetOffset()); -} - -void VmaBlockMetadata_Linear::FreeAtOffset(VkDeviceSize offset) -{ - SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - - if(!suballocations1st.empty()) - { - // First allocation: Mark it as next empty at the beginning. - VmaSuballocation& firstSuballoc = suballocations1st[m_1stNullItemsBeginCount]; - if(firstSuballoc.offset == offset) - { - firstSuballoc.type = VMA_SUBALLOCATION_TYPE_FREE; - firstSuballoc.hAllocation = VK_NULL_HANDLE; - m_SumFreeSize += firstSuballoc.size; - ++m_1stNullItemsBeginCount; - CleanupAfterFree(); - return; - } - } - - // Last allocation in 2-part ring buffer or top of upper stack (same logic). - if(m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER || - m_2ndVectorMode == SECOND_VECTOR_DOUBLE_STACK) - { - VmaSuballocation& lastSuballoc = suballocations2nd.back(); - if(lastSuballoc.offset == offset) - { - m_SumFreeSize += lastSuballoc.size; - suballocations2nd.pop_back(); - CleanupAfterFree(); - return; - } - } - // Last allocation in 1st vector. - else if(m_2ndVectorMode == SECOND_VECTOR_EMPTY) - { - VmaSuballocation& lastSuballoc = suballocations1st.back(); - if(lastSuballoc.offset == offset) - { - m_SumFreeSize += lastSuballoc.size; - suballocations1st.pop_back(); - CleanupAfterFree(); - return; - } - } - - // Item from the middle of 1st vector. - { - VmaSuballocation refSuballoc; - refSuballoc.offset = offset; - // Rest of members stays uninitialized intentionally for better performance. - SuballocationVectorType::iterator it = VmaBinaryFindSorted( - suballocations1st.begin() + m_1stNullItemsBeginCount, - suballocations1st.end(), - refSuballoc, - VmaSuballocationOffsetLess()); - if(it != suballocations1st.end()) - { - it->type = VMA_SUBALLOCATION_TYPE_FREE; - it->hAllocation = VK_NULL_HANDLE; - ++m_1stNullItemsMiddleCount; - m_SumFreeSize += it->size; - CleanupAfterFree(); - return; - } - } - - if(m_2ndVectorMode != SECOND_VECTOR_EMPTY) - { - // Item from the middle of 2nd vector. - VmaSuballocation refSuballoc; - refSuballoc.offset = offset; - // Rest of members stays uninitialized intentionally for better performance. - SuballocationVectorType::iterator it = m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER ? - VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetLess()) : - VmaBinaryFindSorted(suballocations2nd.begin(), suballocations2nd.end(), refSuballoc, VmaSuballocationOffsetGreater()); - if(it != suballocations2nd.end()) - { - it->type = VMA_SUBALLOCATION_TYPE_FREE; - it->hAllocation = VK_NULL_HANDLE; - ++m_2ndNullItemsCount; - m_SumFreeSize += it->size; - CleanupAfterFree(); - return; - } - } - - VMA_ASSERT(0 && "Allocation to free not found in linear allocator!"); -} - -bool VmaBlockMetadata_Linear::ShouldCompact1st() const -{ - const size_t nullItemCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount; - const size_t suballocCount = AccessSuballocations1st().size(); - return suballocCount > 32 && nullItemCount * 2 >= (suballocCount - nullItemCount) * 3; -} - -void VmaBlockMetadata_Linear::CleanupAfterFree() -{ - SuballocationVectorType& suballocations1st = AccessSuballocations1st(); - SuballocationVectorType& suballocations2nd = AccessSuballocations2nd(); - - if(IsEmpty()) - { - suballocations1st.clear(); - suballocations2nd.clear(); - m_1stNullItemsBeginCount = 0; - m_1stNullItemsMiddleCount = 0; - m_2ndNullItemsCount = 0; - m_2ndVectorMode = SECOND_VECTOR_EMPTY; - } - else - { - const size_t suballoc1stCount = suballocations1st.size(); - const size_t nullItem1stCount = m_1stNullItemsBeginCount + m_1stNullItemsMiddleCount; - VMA_ASSERT(nullItem1stCount <= suballoc1stCount); - - // Find more null items at the beginning of 1st vector. - while(m_1stNullItemsBeginCount < suballoc1stCount && - suballocations1st[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE) - { - ++m_1stNullItemsBeginCount; - --m_1stNullItemsMiddleCount; - } - - // Find more null items at the end of 1st vector. - while(m_1stNullItemsMiddleCount > 0 && - suballocations1st.back().hAllocation == VK_NULL_HANDLE) - { - --m_1stNullItemsMiddleCount; - suballocations1st.pop_back(); - } - - // Find more null items at the end of 2nd vector. - while(m_2ndNullItemsCount > 0 && - suballocations2nd.back().hAllocation == VK_NULL_HANDLE) - { - --m_2ndNullItemsCount; - suballocations2nd.pop_back(); - } - - // Find more null items at the beginning of 2nd vector. - while(m_2ndNullItemsCount > 0 && - suballocations2nd[0].hAllocation == VK_NULL_HANDLE) - { - --m_2ndNullItemsCount; - VmaVectorRemove(suballocations2nd, 0); - } - - if(ShouldCompact1st()) - { - const size_t nonNullItemCount = suballoc1stCount - nullItem1stCount; - size_t srcIndex = m_1stNullItemsBeginCount; - for(size_t dstIndex = 0; dstIndex < nonNullItemCount; ++dstIndex) - { - while(suballocations1st[srcIndex].hAllocation == VK_NULL_HANDLE) - { - ++srcIndex; - } - if(dstIndex != srcIndex) - { - suballocations1st[dstIndex] = suballocations1st[srcIndex]; - } - ++srcIndex; - } - suballocations1st.resize(nonNullItemCount); - m_1stNullItemsBeginCount = 0; - m_1stNullItemsMiddleCount = 0; - } - - // 2nd vector became empty. - if(suballocations2nd.empty()) - { - m_2ndVectorMode = SECOND_VECTOR_EMPTY; - } - - // 1st vector became empty. - if(suballocations1st.size() - m_1stNullItemsBeginCount == 0) - { - suballocations1st.clear(); - m_1stNullItemsBeginCount = 0; - - if(!suballocations2nd.empty() && m_2ndVectorMode == SECOND_VECTOR_RING_BUFFER) - { - // Swap 1st with 2nd. Now 2nd is empty. - m_2ndVectorMode = SECOND_VECTOR_EMPTY; - m_1stNullItemsMiddleCount = m_2ndNullItemsCount; - while(m_1stNullItemsBeginCount < suballocations2nd.size() && - suballocations2nd[m_1stNullItemsBeginCount].hAllocation == VK_NULL_HANDLE) - { - ++m_1stNullItemsBeginCount; - --m_1stNullItemsMiddleCount; - } - m_2ndNullItemsCount = 0; - m_1stVectorIndex ^= 1; - } - } - } - - VMA_HEAVY_ASSERT(Validate()); -} - - -//////////////////////////////////////////////////////////////////////////////// -// class VmaBlockMetadata_Buddy - -VmaBlockMetadata_Buddy::VmaBlockMetadata_Buddy(VmaAllocator hAllocator) : - VmaBlockMetadata(hAllocator), - m_Root(VMA_NULL), - m_AllocationCount(0), - m_FreeCount(1), - m_SumFreeSize(0) -{ - memset(m_FreeList, 0, sizeof(m_FreeList)); -} - -VmaBlockMetadata_Buddy::~VmaBlockMetadata_Buddy() -{ - DeleteNode(m_Root); -} - -void VmaBlockMetadata_Buddy::Init(VkDeviceSize size) -{ - VmaBlockMetadata::Init(size); - - m_UsableSize = VmaPrevPow2(size); - m_SumFreeSize = m_UsableSize; - - // Calculate m_LevelCount. - m_LevelCount = 1; - while(m_LevelCount < MAX_LEVELS && - LevelToNodeSize(m_LevelCount) >= MIN_NODE_SIZE) - { - ++m_LevelCount; - } - - Node* rootNode = vma_new(GetAllocationCallbacks(), Node)(); - rootNode->offset = 0; - rootNode->type = Node::TYPE_FREE; - rootNode->parent = VMA_NULL; - rootNode->buddy = VMA_NULL; - - m_Root = rootNode; - AddToFreeListFront(0, rootNode); -} - -bool VmaBlockMetadata_Buddy::Validate() const -{ - // Validate tree. - ValidationContext ctx; - if(!ValidateNode(ctx, VMA_NULL, m_Root, 0, LevelToNodeSize(0))) - { - VMA_VALIDATE(false && "ValidateNode failed."); - } - VMA_VALIDATE(m_AllocationCount == ctx.calculatedAllocationCount); - VMA_VALIDATE(m_SumFreeSize == ctx.calculatedSumFreeSize); - - // Validate free node lists. - for(uint32_t level = 0; level < m_LevelCount; ++level) - { - VMA_VALIDATE(m_FreeList[level].front == VMA_NULL || - m_FreeList[level].front->free.prev == VMA_NULL); - - for(Node* node = m_FreeList[level].front; - node != VMA_NULL; - node = node->free.next) - { - VMA_VALIDATE(node->type == Node::TYPE_FREE); - - if(node->free.next == VMA_NULL) - { - VMA_VALIDATE(m_FreeList[level].back == node); - } - else - { - VMA_VALIDATE(node->free.next->free.prev == node); - } - } - } - - // Validate that free lists ar higher levels are empty. - for(uint32_t level = m_LevelCount; level < MAX_LEVELS; ++level) - { - VMA_VALIDATE(m_FreeList[level].front == VMA_NULL && m_FreeList[level].back == VMA_NULL); - } - - return true; -} - -VkDeviceSize VmaBlockMetadata_Buddy::GetUnusedRangeSizeMax() const -{ - for(uint32_t level = 0; level < m_LevelCount; ++level) - { - if(m_FreeList[level].front != VMA_NULL) - { - return LevelToNodeSize(level); - } - } - return 0; -} - -void VmaBlockMetadata_Buddy::CalcAllocationStatInfo(VmaStatInfo& outInfo) const -{ - const VkDeviceSize unusableSize = GetUnusableSize(); - - outInfo.blockCount = 1; - - outInfo.allocationCount = outInfo.unusedRangeCount = 0; - outInfo.usedBytes = outInfo.unusedBytes = 0; - - outInfo.allocationSizeMax = outInfo.unusedRangeSizeMax = 0; - outInfo.allocationSizeMin = outInfo.unusedRangeSizeMin = UINT64_MAX; - outInfo.allocationSizeAvg = outInfo.unusedRangeSizeAvg = 0; // Unused. - - CalcAllocationStatInfoNode(outInfo, m_Root, LevelToNodeSize(0)); - - if(unusableSize > 0) - { - ++outInfo.unusedRangeCount; - outInfo.unusedBytes += unusableSize; - outInfo.unusedRangeSizeMax = VMA_MAX(outInfo.unusedRangeSizeMax, unusableSize); - outInfo.unusedRangeSizeMin = VMA_MIN(outInfo.unusedRangeSizeMin, unusableSize); - } -} - -void VmaBlockMetadata_Buddy::AddPoolStats(VmaPoolStats& inoutStats) const -{ - const VkDeviceSize unusableSize = GetUnusableSize(); - - inoutStats.size += GetSize(); - inoutStats.unusedSize += m_SumFreeSize + unusableSize; - inoutStats.allocationCount += m_AllocationCount; - inoutStats.unusedRangeCount += m_FreeCount; - inoutStats.unusedRangeSizeMax = VMA_MAX(inoutStats.unusedRangeSizeMax, GetUnusedRangeSizeMax()); - - if(unusableSize > 0) - { - ++inoutStats.unusedRangeCount; - // Not updating inoutStats.unusedRangeSizeMax with unusableSize because this space is not available for allocations. - } -} - -#if VMA_STATS_STRING_ENABLED - -void VmaBlockMetadata_Buddy::PrintDetailedMap(class VmaJsonWriter& json) const -{ - // TODO optimize - VmaStatInfo stat; - CalcAllocationStatInfo(stat); - - PrintDetailedMap_Begin( - json, - stat.unusedBytes, - stat.allocationCount, - stat.unusedRangeCount); - - PrintDetailedMapNode(json, m_Root, LevelToNodeSize(0)); - - const VkDeviceSize unusableSize = GetUnusableSize(); - if(unusableSize > 0) - { - PrintDetailedMap_UnusedRange(json, - m_UsableSize, // offset - unusableSize); // size - } - - PrintDetailedMap_End(json); -} - -#endif // #if VMA_STATS_STRING_ENABLED - -bool VmaBlockMetadata_Buddy::CreateAllocationRequest( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VkDeviceSize bufferImageGranularity, - VkDeviceSize allocSize, - VkDeviceSize allocAlignment, - bool upperAddress, - VmaSuballocationType allocType, - bool canMakeOtherLost, - uint32_t strategy, - VmaAllocationRequest* pAllocationRequest) -{ - VMA_ASSERT(!upperAddress && "VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT can be used only with linear algorithm."); - - // Simple way to respect bufferImageGranularity. May be optimized some day. - // Whenever it might be an OPTIMAL image... - if(allocType == VMA_SUBALLOCATION_TYPE_UNKNOWN || - allocType == VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN || - allocType == VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL) - { - allocAlignment = VMA_MAX(allocAlignment, bufferImageGranularity); - allocSize = VMA_MAX(allocSize, bufferImageGranularity); - } - - if(allocSize > m_UsableSize) - { - return false; - } - - const uint32_t targetLevel = AllocSizeToLevel(allocSize); - for(uint32_t level = targetLevel + 1; level--; ) - { - for(Node* freeNode = m_FreeList[level].front; - freeNode != VMA_NULL; - freeNode = freeNode->free.next) - { - if(freeNode->offset % allocAlignment == 0) - { - pAllocationRequest->type = VmaAllocationRequestType::Normal; - pAllocationRequest->offset = freeNode->offset; - pAllocationRequest->sumFreeSize = LevelToNodeSize(level); - pAllocationRequest->sumItemSize = 0; - pAllocationRequest->itemsToMakeLostCount = 0; - pAllocationRequest->customData = (void*)(uintptr_t)level; - return true; - } - } - } - - return false; -} - -bool VmaBlockMetadata_Buddy::MakeRequestedAllocationsLost( - uint32_t currentFrameIndex, - uint32_t frameInUseCount, - VmaAllocationRequest* pAllocationRequest) -{ - /* - Lost allocations are not supported in buddy allocator at the moment. - Support might be added in the future. - */ - return pAllocationRequest->itemsToMakeLostCount == 0; -} - -uint32_t VmaBlockMetadata_Buddy::MakeAllocationsLost(uint32_t currentFrameIndex, uint32_t frameInUseCount) -{ - /* - Lost allocations are not supported in buddy allocator at the moment. - Support might be added in the future. - */ - return 0; -} - -void VmaBlockMetadata_Buddy::Alloc( - const VmaAllocationRequest& request, - VmaSuballocationType type, - VkDeviceSize allocSize, - VmaAllocation hAllocation) -{ - VMA_ASSERT(request.type == VmaAllocationRequestType::Normal); - - const uint32_t targetLevel = AllocSizeToLevel(allocSize); - uint32_t currLevel = (uint32_t)(uintptr_t)request.customData; - - Node* currNode = m_FreeList[currLevel].front; - VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE); - while(currNode->offset != request.offset) - { - currNode = currNode->free.next; - VMA_ASSERT(currNode != VMA_NULL && currNode->type == Node::TYPE_FREE); - } - - // Go down, splitting free nodes. - while(currLevel < targetLevel) - { - // currNode is already first free node at currLevel. - // Remove it from list of free nodes at this currLevel. - RemoveFromFreeList(currLevel, currNode); - - const uint32_t childrenLevel = currLevel + 1; - - // Create two free sub-nodes. - Node* leftChild = vma_new(GetAllocationCallbacks(), Node)(); - Node* rightChild = vma_new(GetAllocationCallbacks(), Node)(); - - leftChild->offset = currNode->offset; - leftChild->type = Node::TYPE_FREE; - leftChild->parent = currNode; - leftChild->buddy = rightChild; - - rightChild->offset = currNode->offset + LevelToNodeSize(childrenLevel); - rightChild->type = Node::TYPE_FREE; - rightChild->parent = currNode; - rightChild->buddy = leftChild; - - // Convert current currNode to split type. - currNode->type = Node::TYPE_SPLIT; - currNode->split.leftChild = leftChild; - - // Add child nodes to free list. Order is important! - AddToFreeListFront(childrenLevel, rightChild); - AddToFreeListFront(childrenLevel, leftChild); - - ++m_FreeCount; - //m_SumFreeSize -= LevelToNodeSize(currLevel) % 2; // Useful only when level node sizes can be non power of 2. - ++currLevel; - currNode = m_FreeList[currLevel].front; - - /* - We can be sure that currNode, as left child of node previously split, - also fullfills the alignment requirement. - */ - } - - // Remove from free list. - VMA_ASSERT(currLevel == targetLevel && - currNode != VMA_NULL && - currNode->type == Node::TYPE_FREE); - RemoveFromFreeList(currLevel, currNode); - - // Convert to allocation node. - currNode->type = Node::TYPE_ALLOCATION; - currNode->allocation.alloc = hAllocation; - - ++m_AllocationCount; - --m_FreeCount; - m_SumFreeSize -= allocSize; -} - -void VmaBlockMetadata_Buddy::DeleteNode(Node* node) -{ - if(node->type == Node::TYPE_SPLIT) - { - DeleteNode(node->split.leftChild->buddy); - DeleteNode(node->split.leftChild); - } - - vma_delete(GetAllocationCallbacks(), node); -} - -bool VmaBlockMetadata_Buddy::ValidateNode(ValidationContext& ctx, const Node* parent, const Node* curr, uint32_t level, VkDeviceSize levelNodeSize) const -{ - VMA_VALIDATE(level < m_LevelCount); - VMA_VALIDATE(curr->parent == parent); - VMA_VALIDATE((curr->buddy == VMA_NULL) == (parent == VMA_NULL)); - VMA_VALIDATE(curr->buddy == VMA_NULL || curr->buddy->buddy == curr); - switch(curr->type) - { - case Node::TYPE_FREE: - // curr->free.prev, next are validated separately. - ctx.calculatedSumFreeSize += levelNodeSize; - ++ctx.calculatedFreeCount; - break; - case Node::TYPE_ALLOCATION: - ++ctx.calculatedAllocationCount; - ctx.calculatedSumFreeSize += levelNodeSize - curr->allocation.alloc->GetSize(); - VMA_VALIDATE(curr->allocation.alloc != VK_NULL_HANDLE); - break; - case Node::TYPE_SPLIT: - { - const uint32_t childrenLevel = level + 1; - const VkDeviceSize childrenLevelNodeSize = levelNodeSize / 2; - const Node* const leftChild = curr->split.leftChild; - VMA_VALIDATE(leftChild != VMA_NULL); - VMA_VALIDATE(leftChild->offset == curr->offset); - if(!ValidateNode(ctx, curr, leftChild, childrenLevel, childrenLevelNodeSize)) - { - VMA_VALIDATE(false && "ValidateNode for left child failed."); - } - const Node* const rightChild = leftChild->buddy; - VMA_VALIDATE(rightChild->offset == curr->offset + childrenLevelNodeSize); - if(!ValidateNode(ctx, curr, rightChild, childrenLevel, childrenLevelNodeSize)) - { - VMA_VALIDATE(false && "ValidateNode for right child failed."); - } - } - break; - default: - return false; - } - - return true; -} - -uint32_t VmaBlockMetadata_Buddy::AllocSizeToLevel(VkDeviceSize allocSize) const -{ - // I know this could be optimized somehow e.g. by using std::log2p1 from C++20. - uint32_t level = 0; - VkDeviceSize currLevelNodeSize = m_UsableSize; - VkDeviceSize nextLevelNodeSize = currLevelNodeSize >> 1; - while(allocSize <= nextLevelNodeSize && level + 1 < m_LevelCount) - { - ++level; - currLevelNodeSize = nextLevelNodeSize; - nextLevelNodeSize = currLevelNodeSize >> 1; - } - return level; -} - -void VmaBlockMetadata_Buddy::FreeAtOffset(VmaAllocation alloc, VkDeviceSize offset) -{ - // Find node and level. - Node* node = m_Root; - VkDeviceSize nodeOffset = 0; - uint32_t level = 0; - VkDeviceSize levelNodeSize = LevelToNodeSize(0); - while(node->type == Node::TYPE_SPLIT) - { - const VkDeviceSize nextLevelSize = levelNodeSize >> 1; - if(offset < nodeOffset + nextLevelSize) - { - node = node->split.leftChild; - } - else - { - node = node->split.leftChild->buddy; - nodeOffset += nextLevelSize; - } - ++level; - levelNodeSize = nextLevelSize; - } - - VMA_ASSERT(node != VMA_NULL && node->type == Node::TYPE_ALLOCATION); - VMA_ASSERT(alloc == VK_NULL_HANDLE || node->allocation.alloc == alloc); - - ++m_FreeCount; - --m_AllocationCount; - m_SumFreeSize += alloc->GetSize(); - - node->type = Node::TYPE_FREE; - - // Join free nodes if possible. - while(level > 0 && node->buddy->type == Node::TYPE_FREE) - { - RemoveFromFreeList(level, node->buddy); - Node* const parent = node->parent; - - vma_delete(GetAllocationCallbacks(), node->buddy); - vma_delete(GetAllocationCallbacks(), node); - parent->type = Node::TYPE_FREE; - - node = parent; - --level; - //m_SumFreeSize += LevelToNodeSize(level) % 2; // Useful only when level node sizes can be non power of 2. - --m_FreeCount; - } - - AddToFreeListFront(level, node); -} - -void VmaBlockMetadata_Buddy::CalcAllocationStatInfoNode(VmaStatInfo& outInfo, const Node* node, VkDeviceSize levelNodeSize) const -{ - switch(node->type) - { - case Node::TYPE_FREE: - ++outInfo.unusedRangeCount; - outInfo.unusedBytes += levelNodeSize; - outInfo.unusedRangeSizeMax = VMA_MAX(outInfo.unusedRangeSizeMax, levelNodeSize); - outInfo.unusedRangeSizeMin = VMA_MAX(outInfo.unusedRangeSizeMin, levelNodeSize); - break; - case Node::TYPE_ALLOCATION: - { - const VkDeviceSize allocSize = node->allocation.alloc->GetSize(); - ++outInfo.allocationCount; - outInfo.usedBytes += allocSize; - outInfo.allocationSizeMax = VMA_MAX(outInfo.allocationSizeMax, allocSize); - outInfo.allocationSizeMin = VMA_MAX(outInfo.allocationSizeMin, allocSize); - - const VkDeviceSize unusedRangeSize = levelNodeSize - allocSize; - if(unusedRangeSize > 0) - { - ++outInfo.unusedRangeCount; - outInfo.unusedBytes += unusedRangeSize; - outInfo.unusedRangeSizeMax = VMA_MAX(outInfo.unusedRangeSizeMax, unusedRangeSize); - outInfo.unusedRangeSizeMin = VMA_MAX(outInfo.unusedRangeSizeMin, unusedRangeSize); - } - } - break; - case Node::TYPE_SPLIT: - { - const VkDeviceSize childrenNodeSize = levelNodeSize / 2; - const Node* const leftChild = node->split.leftChild; - CalcAllocationStatInfoNode(outInfo, leftChild, childrenNodeSize); - const Node* const rightChild = leftChild->buddy; - CalcAllocationStatInfoNode(outInfo, rightChild, childrenNodeSize); - } - break; - default: - VMA_ASSERT(0); - } -} - -void VmaBlockMetadata_Buddy::AddToFreeListFront(uint32_t level, Node* node) -{ - VMA_ASSERT(node->type == Node::TYPE_FREE); - - // List is empty. - Node* const frontNode = m_FreeList[level].front; - if(frontNode == VMA_NULL) - { - VMA_ASSERT(m_FreeList[level].back == VMA_NULL); - node->free.prev = node->free.next = VMA_NULL; - m_FreeList[level].front = m_FreeList[level].back = node; - } - else - { - VMA_ASSERT(frontNode->free.prev == VMA_NULL); - node->free.prev = VMA_NULL; - node->free.next = frontNode; - frontNode->free.prev = node; - m_FreeList[level].front = node; - } -} - -void VmaBlockMetadata_Buddy::RemoveFromFreeList(uint32_t level, Node* node) -{ - VMA_ASSERT(m_FreeList[level].front != VMA_NULL); - - // It is at the front. - if(node->free.prev == VMA_NULL) - { - VMA_ASSERT(m_FreeList[level].front == node); - m_FreeList[level].front = node->free.next; - } - else - { - Node* const prevFreeNode = node->free.prev; - VMA_ASSERT(prevFreeNode->free.next == node); - prevFreeNode->free.next = node->free.next; - } - - // It is at the back. - if(node->free.next == VMA_NULL) - { - VMA_ASSERT(m_FreeList[level].back == node); - m_FreeList[level].back = node->free.prev; - } - else - { - Node* const nextFreeNode = node->free.next; - VMA_ASSERT(nextFreeNode->free.prev == node); - nextFreeNode->free.prev = node->free.prev; - } -} - -#if VMA_STATS_STRING_ENABLED -void VmaBlockMetadata_Buddy::PrintDetailedMapNode(class VmaJsonWriter& json, const Node* node, VkDeviceSize levelNodeSize) const -{ - switch(node->type) - { - case Node::TYPE_FREE: - PrintDetailedMap_UnusedRange(json, node->offset, levelNodeSize); - break; - case Node::TYPE_ALLOCATION: - { - PrintDetailedMap_Allocation(json, node->offset, node->allocation.alloc); - const VkDeviceSize allocSize = node->allocation.alloc->GetSize(); - if(allocSize < levelNodeSize) - { - PrintDetailedMap_UnusedRange(json, node->offset + allocSize, levelNodeSize - allocSize); - } - } - break; - case Node::TYPE_SPLIT: - { - const VkDeviceSize childrenNodeSize = levelNodeSize / 2; - const Node* const leftChild = node->split.leftChild; - PrintDetailedMapNode(json, leftChild, childrenNodeSize); - const Node* const rightChild = leftChild->buddy; - PrintDetailedMapNode(json, rightChild, childrenNodeSize); - } - break; - default: - VMA_ASSERT(0); - } -} -#endif // #if VMA_STATS_STRING_ENABLED - - -//////////////////////////////////////////////////////////////////////////////// -// class VmaDeviceMemoryBlock - -VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator) : - m_pMetadata(VMA_NULL), - m_MemoryTypeIndex(UINT32_MAX), - m_Id(0), - m_hMemory(VK_NULL_HANDLE), - m_MapCount(0), - m_pMappedData(VMA_NULL) -{ -} - -void VmaDeviceMemoryBlock::Init( - VmaAllocator hAllocator, - VmaPool hParentPool, - uint32_t newMemoryTypeIndex, - VkDeviceMemory newMemory, - VkDeviceSize newSize, - uint32_t id, - uint32_t algorithm) -{ - VMA_ASSERT(m_hMemory == VK_NULL_HANDLE); - - m_hParentPool = hParentPool; - m_MemoryTypeIndex = newMemoryTypeIndex; - m_Id = id; - m_hMemory = newMemory; - - switch(algorithm) - { - case VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT: - m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Linear)(hAllocator); - break; - case VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT: - m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Buddy)(hAllocator); - break; - default: - VMA_ASSERT(0); - // Fall-through. - case 0: - m_pMetadata = vma_new(hAllocator, VmaBlockMetadata_Generic)(hAllocator); - } - m_pMetadata->Init(newSize); -} - -void VmaDeviceMemoryBlock::Destroy(VmaAllocator allocator) -{ - // This is the most important assert in the entire library. - // Hitting it means you have some memory leak - unreleased VmaAllocation objects. - VMA_ASSERT(m_pMetadata->IsEmpty() && "Some allocations were not freed before destruction of this memory block!"); - - VMA_ASSERT(m_hMemory != VK_NULL_HANDLE); - allocator->FreeVulkanMemory(m_MemoryTypeIndex, m_pMetadata->GetSize(), m_hMemory); - m_hMemory = VK_NULL_HANDLE; - - vma_delete(allocator, m_pMetadata); - m_pMetadata = VMA_NULL; -} - -bool VmaDeviceMemoryBlock::Validate() const -{ - VMA_VALIDATE((m_hMemory != VK_NULL_HANDLE) && - (m_pMetadata->GetSize() != 0)); - - return m_pMetadata->Validate(); -} - -VkResult VmaDeviceMemoryBlock::CheckCorruption(VmaAllocator hAllocator) -{ - void* pData = nullptr; - VkResult res = Map(hAllocator, 1, &pData); - if(res != VK_SUCCESS) - { - return res; - } - - res = m_pMetadata->CheckCorruption(pData); - - Unmap(hAllocator, 1); - - return res; -} - -VkResult VmaDeviceMemoryBlock::Map(VmaAllocator hAllocator, uint32_t count, void** ppData) -{ - if(count == 0) - { - return VK_SUCCESS; - } - - VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex); - if(m_MapCount != 0) - { - m_MapCount += count; - VMA_ASSERT(m_pMappedData != VMA_NULL); - if(ppData != VMA_NULL) - { - *ppData = m_pMappedData; - } - return VK_SUCCESS; - } - else - { - VkResult result = (*hAllocator->GetVulkanFunctions().vkMapMemory)( - hAllocator->m_hDevice, - m_hMemory, - 0, // offset - VK_WHOLE_SIZE, - 0, // flags - &m_pMappedData); - if(result == VK_SUCCESS) - { - if(ppData != VMA_NULL) - { - *ppData = m_pMappedData; - } - m_MapCount = count; - } - return result; - } -} - -void VmaDeviceMemoryBlock::Unmap(VmaAllocator hAllocator, uint32_t count) -{ - if(count == 0) - { - return; - } - - VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex); - if(m_MapCount >= count) - { - m_MapCount -= count; - if(m_MapCount == 0) - { - m_pMappedData = VMA_NULL; - (*hAllocator->GetVulkanFunctions().vkUnmapMemory)(hAllocator->m_hDevice, m_hMemory); - } - } - else - { - VMA_ASSERT(0 && "VkDeviceMemory block is being unmapped while it was not previously mapped."); - } -} - -VkResult VmaDeviceMemoryBlock::WriteMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize) -{ - VMA_ASSERT(VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_MARGIN % 4 == 0 && VMA_DEBUG_DETECT_CORRUPTION); - VMA_ASSERT(allocOffset >= VMA_DEBUG_MARGIN); - - void* pData; - VkResult res = Map(hAllocator, 1, &pData); - if(res != VK_SUCCESS) - { - return res; - } - - VmaWriteMagicValue(pData, allocOffset - VMA_DEBUG_MARGIN); - VmaWriteMagicValue(pData, allocOffset + allocSize); - - Unmap(hAllocator, 1); - - return VK_SUCCESS; -} - -VkResult VmaDeviceMemoryBlock::ValidateMagicValueAroundAllocation(VmaAllocator hAllocator, VkDeviceSize allocOffset, VkDeviceSize allocSize) -{ - VMA_ASSERT(VMA_DEBUG_MARGIN > 0 && VMA_DEBUG_MARGIN % 4 == 0 && VMA_DEBUG_DETECT_CORRUPTION); - VMA_ASSERT(allocOffset >= VMA_DEBUG_MARGIN); - - void* pData; - VkResult res = Map(hAllocator, 1, &pData); - if(res != VK_SUCCESS) - { - return res; - } - - if(!VmaValidateMagicValue(pData, allocOffset - VMA_DEBUG_MARGIN)) + if (m_pUserData != VMA_NULL) { - VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED BEFORE FREED ALLOCATION!"); + json.WriteString("CustomData"); + json.BeginString(); + json.ContinueString_Pointer(m_pUserData); + json.EndString(); } - else if(!VmaValidateMagicValue(pData, allocOffset + allocSize)) + if (m_pName != VMA_NULL) { - VMA_ASSERT(0 && "MEMORY CORRUPTION DETECTED AFTER FREED ALLOCATION!"); + json.WriteString("Name"); + json.WriteString(m_pName); } - - Unmap(hAllocator, 1); - - return VK_SUCCESS; -} - -VkResult VmaDeviceMemoryBlock::BindBufferMemory( - const VmaAllocator hAllocator, - const VmaAllocation hAllocation, - VkDeviceSize allocationLocalOffset, - VkBuffer hBuffer, - const void* pNext) -{ - VMA_ASSERT(hAllocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK && - hAllocation->GetBlock() == this); - VMA_ASSERT(allocationLocalOffset < hAllocation->GetSize() && - "Invalid allocationLocalOffset. Did you forget that this offset is relative to the beginning of the allocation, not the whole memory block?"); - const VkDeviceSize memoryOffset = hAllocation->GetOffset() + allocationLocalOffset; - // This lock is important so that we don't call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads. - VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex); - return hAllocator->BindVulkanBuffer(m_hMemory, memoryOffset, hBuffer, pNext); -} - -VkResult VmaDeviceMemoryBlock::BindImageMemory( - const VmaAllocator hAllocator, - const VmaAllocation hAllocation, - VkDeviceSize allocationLocalOffset, - VkImage hImage, - const void* pNext) -{ - VMA_ASSERT(hAllocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK && - hAllocation->GetBlock() == this); - VMA_ASSERT(allocationLocalOffset < hAllocation->GetSize() && - "Invalid allocationLocalOffset. Did you forget that this offset is relative to the beginning of the allocation, not the whole memory block?"); - const VkDeviceSize memoryOffset = hAllocation->GetOffset() + allocationLocalOffset; - // This lock is important so that we don't call vkBind... and/or vkMap... simultaneously on the same VkDeviceMemory from multiple threads. - VmaMutexLock lock(m_Mutex, hAllocator->m_UseMutex); - return hAllocator->BindVulkanImage(m_hMemory, memoryOffset, hImage, pNext); -} - -static void InitStatInfo(VmaStatInfo& outInfo) -{ - memset(&outInfo, 0, sizeof(outInfo)); - outInfo.allocationSizeMin = UINT64_MAX; - outInfo.unusedRangeSizeMin = UINT64_MAX; -} - -// Adds statistics srcInfo into inoutInfo, like: inoutInfo += srcInfo. -static void VmaAddStatInfo(VmaStatInfo& inoutInfo, const VmaStatInfo& srcInfo) -{ - inoutInfo.blockCount += srcInfo.blockCount; - inoutInfo.allocationCount += srcInfo.allocationCount; - inoutInfo.unusedRangeCount += srcInfo.unusedRangeCount; - inoutInfo.usedBytes += srcInfo.usedBytes; - inoutInfo.unusedBytes += srcInfo.unusedBytes; - inoutInfo.allocationSizeMin = VMA_MIN(inoutInfo.allocationSizeMin, srcInfo.allocationSizeMin); - inoutInfo.allocationSizeMax = VMA_MAX(inoutInfo.allocationSizeMax, srcInfo.allocationSizeMax); - inoutInfo.unusedRangeSizeMin = VMA_MIN(inoutInfo.unusedRangeSizeMin, srcInfo.unusedRangeSizeMin); - inoutInfo.unusedRangeSizeMax = VMA_MAX(inoutInfo.unusedRangeSizeMax, srcInfo.unusedRangeSizeMax); -} - -static void VmaPostprocessCalcStatInfo(VmaStatInfo& inoutInfo) -{ - inoutInfo.allocationSizeAvg = (inoutInfo.allocationCount > 0) ? - VmaRoundDiv(inoutInfo.usedBytes, inoutInfo.allocationCount) : 0; - inoutInfo.unusedRangeSizeAvg = (inoutInfo.unusedRangeCount > 0) ? - VmaRoundDiv(inoutInfo.unusedBytes, inoutInfo.unusedRangeCount) : 0; -} - -VmaPool_T::VmaPool_T( - VmaAllocator hAllocator, - const VmaPoolCreateInfo& createInfo, - VkDeviceSize preferredBlockSize) : - m_BlockVector( - hAllocator, - this, // hParentPool - createInfo.memoryTypeIndex, - createInfo.blockSize != 0 ? createInfo.blockSize : preferredBlockSize, - createInfo.minBlockCount, - createInfo.maxBlockCount, - (createInfo.flags & VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT) != 0 ? 1 : hAllocator->GetBufferImageGranularity(), - createInfo.frameInUseCount, - createInfo.blockSize != 0, // explicitBlockSize - createInfo.flags & VMA_POOL_CREATE_ALGORITHM_MASK, // algorithm - createInfo.priority, - VMA_MAX(hAllocator->GetMemoryTypeMinAlignment(createInfo.memoryTypeIndex), createInfo.minAllocationAlignment), - createInfo.pMemoryAllocateNext), - m_Id(0), - m_Name(VMA_NULL) -{ } +#endif // VMA_STATS_STRING_ENABLED -VmaPool_T::~VmaPool_T() +void VmaAllocation_T::FreeName(VmaAllocator hAllocator) { - VMA_ASSERT(m_PrevPool == VMA_NULL && m_NextPool == VMA_NULL); -} - -void VmaPool_T::SetName(const char* pName) -{ - const VkAllocationCallbacks* allocs = m_BlockVector.GetAllocator()->GetAllocationCallbacks(); - VmaFreeString(allocs, m_Name); - - if(pName != VMA_NULL) + if(m_pName) { - m_Name = VmaCreateStringCopy(allocs, pName); - } - else - { - m_Name = VMA_NULL; + VmaFreeString(hAllocator->GetAllocationCallbacks(), m_pName); + m_pName = VMA_NULL; } } +#endif // _VMA_ALLOCATION_T_FUNCTIONS -#if VMA_STATS_STRING_ENABLED - -#endif // #if VMA_STATS_STRING_ENABLED - +#ifndef _VMA_BLOCK_VECTOR_FUNCTIONS VmaBlockVector::VmaBlockVector( VmaAllocator hAllocator, VmaPool hParentPool, @@ -11086,34 +12273,29 @@ VmaBlockVector::VmaBlockVector( size_t minBlockCount, size_t maxBlockCount, VkDeviceSize bufferImageGranularity, - uint32_t frameInUseCount, bool explicitBlockSize, uint32_t algorithm, float priority, VkDeviceSize minAllocationAlignment, - void* pMemoryAllocateNext) : - m_hAllocator(hAllocator), + void* pMemoryAllocateNext) + : m_hAllocator(hAllocator), m_hParentPool(hParentPool), m_MemoryTypeIndex(memoryTypeIndex), m_PreferredBlockSize(preferredBlockSize), m_MinBlockCount(minBlockCount), m_MaxBlockCount(maxBlockCount), m_BufferImageGranularity(bufferImageGranularity), - m_FrameInUseCount(frameInUseCount), m_ExplicitBlockSize(explicitBlockSize), m_Algorithm(algorithm), m_Priority(priority), m_MinAllocationAlignment(minAllocationAlignment), m_pMemoryAllocateNext(pMemoryAllocateNext), - m_HasEmptyBlock(false), m_Blocks(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), - m_NextBlockId(0) -{ -} + m_NextBlockId(0) {} VmaBlockVector::~VmaBlockVector() { - for(size_t i = m_Blocks.size(); i--; ) + for (size_t i = m_Blocks.size(); i--; ) { m_Blocks[i]->Destroy(m_hAllocator); vma_delete(m_hAllocator, m_Blocks[i]); @@ -11122,10 +12304,10 @@ VmaBlockVector::~VmaBlockVector() VkResult VmaBlockVector::CreateMinBlocks() { - for(size_t i = 0; i < m_MinBlockCount; ++i) + for (size_t i = 0; i < m_MinBlockCount; ++i) { VkResult res = CreateBlock(m_PreferredBlockSize, VMA_NULL); - if(res != VK_SUCCESS) + if (res != VK_SUCCESS) { return res; } @@ -11133,25 +12315,31 @@ VkResult VmaBlockVector::CreateMinBlocks() return VK_SUCCESS; } -void VmaBlockVector::GetPoolStats(VmaPoolStats* pStats) +void VmaBlockVector::AddStatistics(VmaStatistics& inoutStats) { VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); const size_t blockCount = m_Blocks.size(); - - pStats->size = 0; - pStats->unusedSize = 0; - pStats->allocationCount = 0; - pStats->unusedRangeCount = 0; - pStats->unusedRangeSizeMax = 0; - pStats->blockCount = blockCount; - - for(uint32_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) + for (uint32_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) { const VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex]; VMA_ASSERT(pBlock); VMA_HEAVY_ASSERT(pBlock->Validate()); - pBlock->m_pMetadata->AddPoolStats(*pStats); + pBlock->m_pMetadata->AddStatistics(inoutStats); + } +} + +void VmaBlockVector::AddDetailedStatistics(VmaDetailedStatistics& inoutStats) +{ + VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); + + const size_t blockCount = m_Blocks.size(); + for (uint32_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) + { + const VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex]; + VMA_ASSERT(pBlock); + VMA_HEAVY_ASSERT(pBlock->Validate()); + pBlock->m_pMetadata->AddDetailedStatistics(inoutStats); } } @@ -11170,10 +12358,7 @@ bool VmaBlockVector::IsCorruptionDetectionEnabled() const (m_hAllocator->m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags & requiredMemFlags) == requiredMemFlags; } -static const uint32_t VMA_ALLOCATION_TRY_COUNT = 32; - VkResult VmaBlockVector::Allocate( - uint32_t currentFrameIndex, VkDeviceSize size, VkDeviceSize alignment, const VmaAllocationCreateInfo& createInfo, @@ -11186,7 +12371,7 @@ VkResult VmaBlockVector::Allocate( alignment = VMA_MAX(alignment, m_MinAllocationAlignment); - if(IsCorruptionDetectionEnabled()) + if (IsCorruptionDetectionEnabled()) { size = VmaAlignUp(size, sizeof(VMA_CORRUPTION_DETECTION_MAGIC_VALUE)); alignment = VmaAlignUp(alignment, sizeof(VMA_CORRUPTION_DETECTION_MAGIC_VALUE)); @@ -11194,33 +12379,26 @@ VkResult VmaBlockVector::Allocate( { VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex); - for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex) + for (allocIndex = 0; allocIndex < allocationCount; ++allocIndex) { res = AllocatePage( - currentFrameIndex, size, alignment, createInfo, suballocType, pAllocations + allocIndex); - if(res != VK_SUCCESS) + if (res != VK_SUCCESS) { break; } } } - if(res != VK_SUCCESS) + if (res != VK_SUCCESS) { // Free all already created allocations. - const uint32_t heapIndex = m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex); - while(allocIndex--) - { - VmaAllocation_T* const alloc = pAllocations[allocIndex]; - const VkDeviceSize allocSize = alloc->GetSize(); - Free(alloc); - m_hAllocator->m_Budget.RemoveAllocation(heapIndex, allocSize); - } + while (allocIndex--) + Free(pAllocations[allocIndex]); memset(pAllocations, 0, sizeof(VmaAllocation) * allocationCount); } @@ -11228,7 +12406,6 @@ VkResult VmaBlockVector::Allocate( } VkResult VmaBlockVector::AllocatePage( - uint32_t currentFrameIndex, VkDeviceSize size, VkDeviceSize alignment, const VmaAllocationCreateInfo& createInfo, @@ -11236,377 +12413,203 @@ VkResult VmaBlockVector::AllocatePage( VmaAllocation* pAllocation) { const bool isUpperAddress = (createInfo.flags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0; - bool canMakeOtherLost = (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT) != 0; - const bool mapped = (createInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0; - const bool isUserDataString = (createInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0; VkDeviceSize freeMemory; { const uint32_t heapIndex = m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex); VmaBudget heapBudget = {}; - m_hAllocator->GetBudget(&heapBudget, heapIndex, 1); + m_hAllocator->GetHeapBudgets(&heapBudget, heapIndex, 1); freeMemory = (heapBudget.usage < heapBudget.budget) ? (heapBudget.budget - heapBudget.usage) : 0; } - const bool canFallbackToDedicated = !IsCustomPool(); + const bool canFallbackToDedicated = !HasExplicitBlockSize() && + (createInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0; const bool canCreateNewBlock = ((createInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0) && (m_Blocks.size() < m_MaxBlockCount) && (freeMemory >= size || !canFallbackToDedicated); uint32_t strategy = createInfo.flags & VMA_ALLOCATION_CREATE_STRATEGY_MASK; - // If linearAlgorithm is used, canMakeOtherLost is available only when used as ring buffer. - // Which in turn is available only when maxBlockCount = 1. - if(m_Algorithm == VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT && m_MaxBlockCount > 1) - { - canMakeOtherLost = false; - } - // Upper address can only be used with linear allocator and within single memory block. - if(isUpperAddress && + if (isUpperAddress && (m_Algorithm != VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT || m_MaxBlockCount > 1)) { return VK_ERROR_FEATURE_NOT_PRESENT; } - // Validate strategy. - switch(strategy) - { - case 0: - strategy = VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT; - break; - case VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT: - case VMA_ALLOCATION_CREATE_STRATEGY_WORST_FIT_BIT: - case VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT: - break; - default: - return VK_ERROR_FEATURE_NOT_PRESENT; - } - // Early reject: requested allocation size is larger that maximum block size for this block vector. - if(size + 2 * VMA_DEBUG_MARGIN > m_PreferredBlockSize) + if (size + VMA_DEBUG_MARGIN > m_PreferredBlockSize) { return VK_ERROR_OUT_OF_DEVICE_MEMORY; } - /* - Under certain condition, this whole section can be skipped for optimization, so - we move on directly to trying to allocate with canMakeOtherLost. That is the case - e.g. for custom pools with linear algorithm. - */ - if(!canMakeOtherLost || canCreateNewBlock) + // 1. Search existing allocations. Try to allocate. + if (m_Algorithm == VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) { - // 1. Search existing allocations. Try to allocate without making other allocations lost. - VmaAllocationCreateFlags allocFlagsCopy = createInfo.flags; - allocFlagsCopy &= ~VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT; - - if(m_Algorithm == VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) + // Use only last block. + if (!m_Blocks.empty()) { - // Use only last block. - if(!m_Blocks.empty()) + VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks.back(); + VMA_ASSERT(pCurrBlock); + VkResult res = AllocateFromBlock( + pCurrBlock, size, alignment, createInfo.flags, createInfo.pUserData, suballocType, strategy, pAllocation); + if (res == VK_SUCCESS) { - VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks.back(); - VMA_ASSERT(pCurrBlock); - VkResult res = AllocateFromBlock( - pCurrBlock, - currentFrameIndex, - size, - alignment, - allocFlagsCopy, - createInfo.pUserData, - suballocType, - strategy, - pAllocation); - if(res == VK_SUCCESS) - { - VMA_DEBUG_LOG(" Returned from last block #%u", pCurrBlock->GetId()); - return VK_SUCCESS; - } + VMA_DEBUG_LOG(" Returned from last block #%u", pCurrBlock->GetId()); + IncrementallySortBlocks(); + return VK_SUCCESS; } } - else + } + else + { + if (strategy != VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT) // MIN_MEMORY or default { - if(strategy == VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT) + const bool isHostVisible = + (m_hAllocator->m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0; + if(isHostVisible) + { + const bool isMappingAllowed = (createInfo.flags & + (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0; + /* + For non-mappable allocations, check blocks that are not mapped first. + For mappable allocations, check blocks that are already mapped first. + This way, having many blocks, we will separate mappable and non-mappable allocations, + hopefully limiting the number of blocks that are mapped, which will help tools like RenderDoc. + */ + for(size_t mappingI = 0; mappingI < 2; ++mappingI) + { + // Forward order in m_Blocks - prefer blocks with smallest amount of free space. + for (size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) + { + VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; + VMA_ASSERT(pCurrBlock); + const bool isBlockMapped = pCurrBlock->GetMappedData() != VMA_NULL; + if((mappingI == 0) == (isMappingAllowed == isBlockMapped)) + { + VkResult res = AllocateFromBlock( + pCurrBlock, size, alignment, createInfo.flags, createInfo.pUserData, suballocType, strategy, pAllocation); + if (res == VK_SUCCESS) + { + VMA_DEBUG_LOG(" Returned from existing block #%u", pCurrBlock->GetId()); + IncrementallySortBlocks(); + return VK_SUCCESS; + } + } + } + } + } + else { // Forward order in m_Blocks - prefer blocks with smallest amount of free space. - for(size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex ) + for (size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) { VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; VMA_ASSERT(pCurrBlock); VkResult res = AllocateFromBlock( - pCurrBlock, - currentFrameIndex, - size, - alignment, - allocFlagsCopy, - createInfo.pUserData, - suballocType, - strategy, - pAllocation); - if(res == VK_SUCCESS) - { - VMA_DEBUG_LOG(" Returned from existing block #%u", pCurrBlock->GetId()); - return VK_SUCCESS; - } - } - } - else // WORST_FIT, FIRST_FIT - { - // Backward order in m_Blocks - prefer blocks with largest amount of free space. - for(size_t blockIndex = m_Blocks.size(); blockIndex--; ) - { - VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; - VMA_ASSERT(pCurrBlock); - VkResult res = AllocateFromBlock( - pCurrBlock, - currentFrameIndex, - size, - alignment, - allocFlagsCopy, - createInfo.pUserData, - suballocType, - strategy, - pAllocation); - if(res == VK_SUCCESS) + pCurrBlock, size, alignment, createInfo.flags, createInfo.pUserData, suballocType, strategy, pAllocation); + if (res == VK_SUCCESS) { VMA_DEBUG_LOG(" Returned from existing block #%u", pCurrBlock->GetId()); + IncrementallySortBlocks(); return VK_SUCCESS; } } } } - - // 2. Try to create new block. - if(canCreateNewBlock) + else // VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT { - // Calculate optimal size for new block. - VkDeviceSize newBlockSize = m_PreferredBlockSize; - uint32_t newBlockSizeShift = 0; - const uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3; - - if(!m_ExplicitBlockSize) + // Backward order in m_Blocks - prefer blocks with largest amount of free space. + for (size_t blockIndex = m_Blocks.size(); blockIndex--; ) { - // Allocate 1/8, 1/4, 1/2 as first blocks. - const VkDeviceSize maxExistingBlockSize = CalcMaxBlockSize(); - for(uint32_t i = 0; i < NEW_BLOCK_SIZE_SHIFT_MAX; ++i) + VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; + VMA_ASSERT(pCurrBlock); + VkResult res = AllocateFromBlock(pCurrBlock, size, alignment, createInfo.flags, createInfo.pUserData, suballocType, strategy, pAllocation); + if (res == VK_SUCCESS) { - const VkDeviceSize smallerNewBlockSize = newBlockSize / 2; - if(smallerNewBlockSize > maxExistingBlockSize && smallerNewBlockSize >= size * 2) - { - newBlockSize = smallerNewBlockSize; - ++newBlockSizeShift; - } - else - { - break; - } - } - } - - size_t newBlockIndex = 0; - VkResult res = (newBlockSize <= freeMemory || !canFallbackToDedicated) ? - CreateBlock(newBlockSize, &newBlockIndex) : VK_ERROR_OUT_OF_DEVICE_MEMORY; - // Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize. - if(!m_ExplicitBlockSize) - { - while(res < 0 && newBlockSizeShift < NEW_BLOCK_SIZE_SHIFT_MAX) - { - const VkDeviceSize smallerNewBlockSize = newBlockSize / 2; - if(smallerNewBlockSize >= size) - { - newBlockSize = smallerNewBlockSize; - ++newBlockSizeShift; - res = (newBlockSize <= freeMemory || !canFallbackToDedicated) ? - CreateBlock(newBlockSize, &newBlockIndex) : VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - else - { - break; - } - } - } - - if(res == VK_SUCCESS) - { - VmaDeviceMemoryBlock* const pBlock = m_Blocks[newBlockIndex]; - VMA_ASSERT(pBlock->m_pMetadata->GetSize() >= size); - - res = AllocateFromBlock( - pBlock, - currentFrameIndex, - size, - alignment, - allocFlagsCopy, - createInfo.pUserData, - suballocType, - strategy, - pAllocation); - if(res == VK_SUCCESS) - { - VMA_DEBUG_LOG(" Created new block #%u Size=%llu", pBlock->GetId(), newBlockSize); + VMA_DEBUG_LOG(" Returned from existing block #%u", pCurrBlock->GetId()); + IncrementallySortBlocks(); return VK_SUCCESS; } - else - { - // Allocation from new block failed, possibly due to VMA_DEBUG_MARGIN or alignment. - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } } } } - // 3. Try to allocate from existing blocks with making other allocations lost. - if(canMakeOtherLost) + // 2. Try to create new block. + if (canCreateNewBlock) { - uint32_t tryIndex = 0; - for(; tryIndex < VMA_ALLOCATION_TRY_COUNT; ++tryIndex) + // Calculate optimal size for new block. + VkDeviceSize newBlockSize = m_PreferredBlockSize; + uint32_t newBlockSizeShift = 0; + const uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3; + + if (!m_ExplicitBlockSize) { - VmaDeviceMemoryBlock* pBestRequestBlock = VMA_NULL; - VmaAllocationRequest bestRequest = {}; - VkDeviceSize bestRequestCost = VK_WHOLE_SIZE; - - // 1. Search existing allocations. - if(strategy == VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT) + // Allocate 1/8, 1/4, 1/2 as first blocks. + const VkDeviceSize maxExistingBlockSize = CalcMaxBlockSize(); + for (uint32_t i = 0; i < NEW_BLOCK_SIZE_SHIFT_MAX; ++i) { - // Forward order in m_Blocks - prefer blocks with smallest amount of free space. - for(size_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex ) + const VkDeviceSize smallerNewBlockSize = newBlockSize / 2; + if (smallerNewBlockSize > maxExistingBlockSize && smallerNewBlockSize >= size * 2) { - VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; - VMA_ASSERT(pCurrBlock); - VmaAllocationRequest currRequest = {}; - if(pCurrBlock->m_pMetadata->CreateAllocationRequest( - currentFrameIndex, - m_FrameInUseCount, - m_BufferImageGranularity, - size, - alignment, - (createInfo.flags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0, - suballocType, - canMakeOtherLost, - strategy, - &currRequest)) - { - const VkDeviceSize currRequestCost = currRequest.CalcCost(); - if(pBestRequestBlock == VMA_NULL || - currRequestCost < bestRequestCost) - { - pBestRequestBlock = pCurrBlock; - bestRequest = currRequest; - bestRequestCost = currRequestCost; - - if(bestRequestCost == 0) - { - break; - } - } - } + newBlockSize = smallerNewBlockSize; + ++newBlockSizeShift; + } + else + { + break; } } - else // WORST_FIT, FIRST_FIT - { - // Backward order in m_Blocks - prefer blocks with largest amount of free space. - for(size_t blockIndex = m_Blocks.size(); blockIndex--; ) - { - VmaDeviceMemoryBlock* const pCurrBlock = m_Blocks[blockIndex]; - VMA_ASSERT(pCurrBlock); - VmaAllocationRequest currRequest = {}; - if(pCurrBlock->m_pMetadata->CreateAllocationRequest( - currentFrameIndex, - m_FrameInUseCount, - m_BufferImageGranularity, - size, - alignment, - (createInfo.flags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0, - suballocType, - canMakeOtherLost, - strategy, - &currRequest)) - { - const VkDeviceSize currRequestCost = currRequest.CalcCost(); - if(pBestRequestBlock == VMA_NULL || - currRequestCost < bestRequestCost || - strategy == VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT) - { - pBestRequestBlock = pCurrBlock; - bestRequest = currRequest; - bestRequestCost = currRequestCost; + } - if(bestRequestCost == 0 || - strategy == VMA_ALLOCATION_CREATE_STRATEGY_FIRST_FIT_BIT) - { - break; - } - } - } + size_t newBlockIndex = 0; + VkResult res = (newBlockSize <= freeMemory || !canFallbackToDedicated) ? + CreateBlock(newBlockSize, &newBlockIndex) : VK_ERROR_OUT_OF_DEVICE_MEMORY; + // Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize. + if (!m_ExplicitBlockSize) + { + while (res < 0 && newBlockSizeShift < NEW_BLOCK_SIZE_SHIFT_MAX) + { + const VkDeviceSize smallerNewBlockSize = newBlockSize / 2; + if (smallerNewBlockSize >= size) + { + newBlockSize = smallerNewBlockSize; + ++newBlockSizeShift; + res = (newBlockSize <= freeMemory || !canFallbackToDedicated) ? + CreateBlock(newBlockSize, &newBlockIndex) : VK_ERROR_OUT_OF_DEVICE_MEMORY; + } + else + { + break; } } + } - if(pBestRequestBlock != VMA_NULL) + if (res == VK_SUCCESS) + { + VmaDeviceMemoryBlock* const pBlock = m_Blocks[newBlockIndex]; + VMA_ASSERT(pBlock->m_pMetadata->GetSize() >= size); + + res = AllocateFromBlock( + pBlock, size, alignment, createInfo.flags, createInfo.pUserData, suballocType, strategy, pAllocation); + if (res == VK_SUCCESS) { - if(mapped) - { - VkResult res = pBestRequestBlock->Map(m_hAllocator, 1, VMA_NULL); - if(res != VK_SUCCESS) - { - return res; - } - } - - if(pBestRequestBlock->m_pMetadata->MakeRequestedAllocationsLost( - currentFrameIndex, - m_FrameInUseCount, - &bestRequest)) - { - // Allocate from this pBlock. - *pAllocation = m_hAllocator->m_AllocationObjectAllocator.Allocate(currentFrameIndex, isUserDataString); - pBestRequestBlock->m_pMetadata->Alloc(bestRequest, suballocType, size, *pAllocation); - UpdateHasEmptyBlock(); - (*pAllocation)->InitBlockAllocation( - pBestRequestBlock, - bestRequest.offset, - alignment, - size, - m_MemoryTypeIndex, - suballocType, - mapped, - (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0); - VMA_HEAVY_ASSERT(pBestRequestBlock->Validate()); - VMA_DEBUG_LOG(" Returned from existing block #%u", pBestRequestBlock->GetId()); - (*pAllocation)->SetUserData(m_hAllocator, createInfo.pUserData); - m_hAllocator->m_Budget.AddAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), size); - if(VMA_DEBUG_INITIALIZE_ALLOCATIONS) - { - m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED); - } - if(IsCorruptionDetectionEnabled()) - { - VkResult res = pBestRequestBlock->WriteMagicValueAroundAllocation(m_hAllocator, bestRequest.offset, size); - VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to write magic value."); - } - return VK_SUCCESS; - } - // else: Some allocations must have been touched while we are here. Next try. + VMA_DEBUG_LOG(" Created new block #%u Size=%llu", pBlock->GetId(), newBlockSize); + IncrementallySortBlocks(); + return VK_SUCCESS; } else { - // Could not find place in any of the blocks - break outer loop. - break; + // Allocation from new block failed, possibly due to VMA_DEBUG_MARGIN or alignment. + return VK_ERROR_OUT_OF_DEVICE_MEMORY; } } - /* Maximum number of tries exceeded - a very unlike event when many other - threads are simultaneously touching allocations making it impossible to make - lost at the same time as we try to allocate. */ - if(tryIndex == VMA_ALLOCATION_TRY_COUNT) - { - return VK_ERROR_TOO_MANY_OBJECTS; - } } return VK_ERROR_OUT_OF_DEVICE_MEMORY; } -void VmaBlockVector::Free( - const VmaAllocation hAllocation) +void VmaBlockVector::Free(const VmaAllocation hAllocation) { VmaDeviceMemoryBlock* pBlockToDelete = VMA_NULL; @@ -11614,7 +12617,7 @@ void VmaBlockVector::Free( { const uint32_t heapIndex = m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex); VmaBudget heapBudget = {}; - m_hAllocator->GetBudget(&heapBudget, heapIndex, 1); + m_hAllocator->GetHeapBudgets(&heapBudget, heapIndex, 1); budgetExceeded = heapBudget.usage >= heapBudget.budget; } @@ -11624,67 +12627,71 @@ void VmaBlockVector::Free( VmaDeviceMemoryBlock* pBlock = hAllocation->GetBlock(); - if(IsCorruptionDetectionEnabled()) + if (IsCorruptionDetectionEnabled()) { - VkResult res = pBlock->ValidateMagicValueAroundAllocation(m_hAllocator, hAllocation->GetOffset(), hAllocation->GetSize()); + VkResult res = pBlock->ValidateMagicValueAfterAllocation(m_hAllocator, hAllocation->GetOffset(), hAllocation->GetSize()); VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to validate magic value."); } - if(hAllocation->IsPersistentMap()) + if (hAllocation->IsPersistentMap()) { pBlock->Unmap(m_hAllocator, 1); } - pBlock->m_pMetadata->Free(hAllocation); + const bool hadEmptyBlockBeforeFree = HasEmptyBlock(); + pBlock->m_pMetadata->Free(hAllocation->GetAllocHandle()); + pBlock->PostFree(m_hAllocator); VMA_HEAVY_ASSERT(pBlock->Validate()); VMA_DEBUG_LOG(" Freed from MemoryTypeIndex=%u", m_MemoryTypeIndex); const bool canDeleteBlock = m_Blocks.size() > m_MinBlockCount; // pBlock became empty after this deallocation. - if(pBlock->m_pMetadata->IsEmpty()) + if (pBlock->m_pMetadata->IsEmpty()) { - // Already has empty block. We don't want to have two, so delete this one. - if((m_HasEmptyBlock || budgetExceeded) && canDeleteBlock) + // Already had empty block. We don't want to have two, so delete this one. + if ((hadEmptyBlockBeforeFree || budgetExceeded) && canDeleteBlock) { pBlockToDelete = pBlock; Remove(pBlock); } - // else: We now have an empty block - leave it. + // else: We now have one empty block - leave it. A hysteresis to avoid allocating whole block back and forth. } // pBlock didn't become empty, but we have another empty block - find and free that one. // (This is optional, heuristics.) - else if(m_HasEmptyBlock && canDeleteBlock) + else if (hadEmptyBlockBeforeFree && canDeleteBlock) { VmaDeviceMemoryBlock* pLastBlock = m_Blocks.back(); - if(pLastBlock->m_pMetadata->IsEmpty()) + if (pLastBlock->m_pMetadata->IsEmpty()) { pBlockToDelete = pLastBlock; m_Blocks.pop_back(); } } - UpdateHasEmptyBlock(); IncrementallySortBlocks(); } // Destruction of a free block. Deferred until this point, outside of mutex // lock, for performance reason. - if(pBlockToDelete != VMA_NULL) + if (pBlockToDelete != VMA_NULL) { VMA_DEBUG_LOG(" Deleted empty block #%u", pBlockToDelete->GetId()); pBlockToDelete->Destroy(m_hAllocator); vma_delete(m_hAllocator, pBlockToDelete); } + + m_hAllocator->m_Budget.RemoveAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), hAllocation->GetSize()); + m_hAllocator->m_AllocationObjectAllocator.Free(hAllocation); } VkDeviceSize VmaBlockVector::CalcMaxBlockSize() const { VkDeviceSize result = 0; - for(size_t i = m_Blocks.size(); i--; ) + for (size_t i = m_Blocks.size(); i--; ) { result = VMA_MAX(result, m_Blocks[i]->m_pMetadata->GetSize()); - if(result >= m_PreferredBlockSize) + if (result >= m_PreferredBlockSize) { break; } @@ -11694,9 +12701,9 @@ VkDeviceSize VmaBlockVector::CalcMaxBlockSize() const void VmaBlockVector::Remove(VmaDeviceMemoryBlock* pBlock) { - for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) + for (uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) { - if(m_Blocks[blockIndex] == pBlock) + if (m_Blocks[blockIndex] == pBlock) { VmaVectorRemove(m_Blocks, blockIndex); return; @@ -11707,12 +12714,14 @@ void VmaBlockVector::Remove(VmaDeviceMemoryBlock* pBlock) void VmaBlockVector::IncrementallySortBlocks() { - if(m_Algorithm != VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) + if (!m_IncrementalSort) + return; + if (m_Algorithm != VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) { // Bubble sort only until first swap. - for(size_t i = 1; i < m_Blocks.size(); ++i) + for (size_t i = 1; i < m_Blocks.size(); ++i) { - if(m_Blocks[i - 1]->m_pMetadata->GetSumFreeSize() > m_Blocks[i]->m_pMetadata->GetSumFreeSize()) + if (m_Blocks[i - 1]->m_pMetadata->GetSumFreeSize() > m_Blocks[i]->m_pMetadata->GetSumFreeSize()) { VMA_SWAP(m_Blocks[i - 1], m_Blocks[i]); return; @@ -11721,9 +12730,17 @@ void VmaBlockVector::IncrementallySortBlocks() } } +void VmaBlockVector::SortByFreeSize() +{ + VMA_SORT(m_Blocks.begin(), m_Blocks.end(), + [](VmaDeviceMemoryBlock* b1, VmaDeviceMemoryBlock* b2) -> bool + { + return b1->m_pMetadata->GetSumFreeSize() < b2->m_pMetadata->GetSumFreeSize(); + }); +} + VkResult VmaBlockVector::AllocateFromBlock( VmaDeviceMemoryBlock* pBlock, - uint32_t currentFrameIndex, VkDeviceSize size, VkDeviceSize alignment, VmaAllocationCreateFlags allocFlags, @@ -11732,65 +12749,75 @@ VkResult VmaBlockVector::AllocateFromBlock( uint32_t strategy, VmaAllocation* pAllocation) { - VMA_ASSERT((allocFlags & VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT) == 0); const bool isUpperAddress = (allocFlags & VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT) != 0; - const bool mapped = (allocFlags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0; - const bool isUserDataString = (allocFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0; VmaAllocationRequest currRequest = {}; - if(pBlock->m_pMetadata->CreateAllocationRequest( - currentFrameIndex, - m_FrameInUseCount, - m_BufferImageGranularity, + if (pBlock->m_pMetadata->CreateAllocationRequest( size, alignment, isUpperAddress, suballocType, - false, // canMakeOtherLost strategy, &currRequest)) { - // Allocate from pCurrBlock. - VMA_ASSERT(currRequest.itemsToMakeLostCount == 0); - - if(mapped) - { - VkResult res = pBlock->Map(m_hAllocator, 1, VMA_NULL); - if(res != VK_SUCCESS) - { - return res; - } - } - - *pAllocation = m_hAllocator->m_AllocationObjectAllocator.Allocate(currentFrameIndex, isUserDataString); - pBlock->m_pMetadata->Alloc(currRequest, suballocType, size, *pAllocation); - UpdateHasEmptyBlock(); - (*pAllocation)->InitBlockAllocation( - pBlock, - currRequest.offset, - alignment, - size, - m_MemoryTypeIndex, - suballocType, - mapped, - (allocFlags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0); - VMA_HEAVY_ASSERT(pBlock->Validate()); - (*pAllocation)->SetUserData(m_hAllocator, pUserData); - m_hAllocator->m_Budget.AddAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), size); - if(VMA_DEBUG_INITIALIZE_ALLOCATIONS) - { - m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED); - } - if(IsCorruptionDetectionEnabled()) - { - VkResult res = pBlock->WriteMagicValueAroundAllocation(m_hAllocator, currRequest.offset, size); - VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to write magic value."); - } - return VK_SUCCESS; + return CommitAllocationRequest(currRequest, pBlock, alignment, allocFlags, pUserData, suballocType, pAllocation); } return VK_ERROR_OUT_OF_DEVICE_MEMORY; } +VkResult VmaBlockVector::CommitAllocationRequest( + VmaAllocationRequest& allocRequest, + VmaDeviceMemoryBlock* pBlock, + VkDeviceSize alignment, + VmaAllocationCreateFlags allocFlags, + void* pUserData, + VmaSuballocationType suballocType, + VmaAllocation* pAllocation) +{ + const bool mapped = (allocFlags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0; + const bool isUserDataString = (allocFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0; + const bool isMappingAllowed = (allocFlags & + (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0; + + pBlock->PostAlloc(); + // Allocate from pCurrBlock. + if (mapped) + { + VkResult res = pBlock->Map(m_hAllocator, 1, VMA_NULL); + if (res != VK_SUCCESS) + { + return res; + } + } + + *pAllocation = m_hAllocator->m_AllocationObjectAllocator.Allocate(isMappingAllowed); + pBlock->m_pMetadata->Alloc(allocRequest, suballocType, *pAllocation); + (*pAllocation)->InitBlockAllocation( + pBlock, + allocRequest.allocHandle, + alignment, + allocRequest.size, // Not size, as actual allocation size may be larger than requested! + m_MemoryTypeIndex, + suballocType, + mapped); + VMA_HEAVY_ASSERT(pBlock->Validate()); + if (isUserDataString) + (*pAllocation)->SetName(m_hAllocator, (const char*)pUserData); + else + (*pAllocation)->SetUserData(m_hAllocator, pUserData); + m_hAllocator->m_Budget.AddAllocation(m_hAllocator->MemoryTypeIndexToHeapIndex(m_MemoryTypeIndex), allocRequest.size); + if (VMA_DEBUG_INITIALIZE_ALLOCATIONS) + { + m_hAllocator->FillAllocation(*pAllocation, VMA_ALLOCATION_FILL_PATTERN_CREATED); + } + if (IsCorruptionDetectionEnabled()) + { + VkResult res = pBlock->WriteMagicValueAfterAllocation(m_hAllocator, (*pAllocation)->GetOffset(), allocRequest.size); + VMA_ASSERT(res == VK_SUCCESS && "Couldn't map block memory to write magic value."); + } + return VK_SUCCESS; +} + VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIndex) { VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; @@ -11801,35 +12828,36 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn #if VMA_BUFFER_DEVICE_ADDRESS // Every standalone block can potentially contain a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT - always enable the feature. VkMemoryAllocateFlagsInfoKHR allocFlagsInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR }; - if(m_hAllocator->m_UseKhrBufferDeviceAddress) + if (m_hAllocator->m_UseKhrBufferDeviceAddress) { allocFlagsInfo.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR; VmaPnextChainPushFront(&allocInfo, &allocFlagsInfo); } -#endif // #if VMA_BUFFER_DEVICE_ADDRESS +#endif // VMA_BUFFER_DEVICE_ADDRESS #if VMA_MEMORY_PRIORITY VkMemoryPriorityAllocateInfoEXT priorityInfo = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT }; - if(m_hAllocator->m_UseExtMemoryPriority) + if (m_hAllocator->m_UseExtMemoryPriority) { + VMA_ASSERT(m_Priority >= 0.f && m_Priority <= 1.f); priorityInfo.priority = m_Priority; VmaPnextChainPushFront(&allocInfo, &priorityInfo); } -#endif // #if VMA_MEMORY_PRIORITY +#endif // VMA_MEMORY_PRIORITY #if VMA_EXTERNAL_MEMORY // Attach VkExportMemoryAllocateInfoKHR if necessary. VkExportMemoryAllocateInfoKHR exportMemoryAllocInfo = { VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR }; exportMemoryAllocInfo.handleTypes = m_hAllocator->GetExternalMemoryHandleTypeFlags(m_MemoryTypeIndex); - if(exportMemoryAllocInfo.handleTypes != 0) + if (exportMemoryAllocInfo.handleTypes != 0) { VmaPnextChainPushFront(&allocInfo, &exportMemoryAllocInfo); } -#endif // #if VMA_EXTERNAL_MEMORY +#endif // VMA_EXTERNAL_MEMORY VkDeviceMemory mem = VK_NULL_HANDLE; VkResult res = m_hAllocator->AllocateVulkanMemory(&allocInfo, &mem); - if(res < 0) + if (res < 0) { return res; } @@ -11845,10 +12873,11 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn mem, allocInfo.allocationSize, m_NextBlockId++, - m_Algorithm); + m_Algorithm, + m_BufferImageGranularity); m_Blocks.push_back(pBlock); - if(pNewBlockIndex != VMA_NULL) + if (pNewBlockIndex != VMA_NULL) { *pNewBlockIndex = m_Blocks.size() - 1; } @@ -11856,532 +12885,12 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn return VK_SUCCESS; } -void VmaBlockVector::ApplyDefragmentationMovesCpu( - class VmaBlockVectorDefragmentationContext* pDefragCtx, - const VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves) +bool VmaBlockVector::HasEmptyBlock() { - const size_t blockCount = m_Blocks.size(); - const bool isNonCoherent = m_hAllocator->IsMemoryTypeNonCoherent(m_MemoryTypeIndex); - - enum BLOCK_FLAG - { - BLOCK_FLAG_USED = 0x00000001, - BLOCK_FLAG_MAPPED_FOR_DEFRAGMENTATION = 0x00000002, - }; - - struct BlockInfo - { - uint32_t flags; - void* pMappedData; - }; - VmaVector< BlockInfo, VmaStlAllocator > - blockInfo(blockCount, BlockInfo(), VmaStlAllocator(m_hAllocator->GetAllocationCallbacks())); - memset(blockInfo.data(), 0, blockCount * sizeof(BlockInfo)); - - // Go over all moves. Mark blocks that are used with BLOCK_FLAG_USED. - const size_t moveCount = moves.size(); - for(size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex) - { - const VmaDefragmentationMove& move = moves[moveIndex]; - blockInfo[move.srcBlockIndex].flags |= BLOCK_FLAG_USED; - blockInfo[move.dstBlockIndex].flags |= BLOCK_FLAG_USED; - } - - VMA_ASSERT(pDefragCtx->res == VK_SUCCESS); - - // Go over all blocks. Get mapped pointer or map if necessary. - for(size_t blockIndex = 0; pDefragCtx->res == VK_SUCCESS && blockIndex < blockCount; ++blockIndex) - { - BlockInfo& currBlockInfo = blockInfo[blockIndex]; - VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex]; - if((currBlockInfo.flags & BLOCK_FLAG_USED) != 0) - { - currBlockInfo.pMappedData = pBlock->GetMappedData(); - // It is not originally mapped - map it. - if(currBlockInfo.pMappedData == VMA_NULL) - { - pDefragCtx->res = pBlock->Map(m_hAllocator, 1, &currBlockInfo.pMappedData); - if(pDefragCtx->res == VK_SUCCESS) - { - currBlockInfo.flags |= BLOCK_FLAG_MAPPED_FOR_DEFRAGMENTATION; - } - } - } - } - - // Go over all moves. Do actual data transfer. - if(pDefragCtx->res == VK_SUCCESS) - { - const VkDeviceSize nonCoherentAtomSize = m_hAllocator->m_PhysicalDeviceProperties.limits.nonCoherentAtomSize; - VkMappedMemoryRange memRange = { VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE }; - - for(size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex) - { - const VmaDefragmentationMove& move = moves[moveIndex]; - - const BlockInfo& srcBlockInfo = blockInfo[move.srcBlockIndex]; - const BlockInfo& dstBlockInfo = blockInfo[move.dstBlockIndex]; - - VMA_ASSERT(srcBlockInfo.pMappedData && dstBlockInfo.pMappedData); - - // Invalidate source. - if(isNonCoherent) - { - VmaDeviceMemoryBlock* const pSrcBlock = m_Blocks[move.srcBlockIndex]; - memRange.memory = pSrcBlock->GetDeviceMemory(); - memRange.offset = VmaAlignDown(move.srcOffset, nonCoherentAtomSize); - memRange.size = VMA_MIN( - VmaAlignUp(move.size + (move.srcOffset - memRange.offset), nonCoherentAtomSize), - pSrcBlock->m_pMetadata->GetSize() - memRange.offset); - (*m_hAllocator->GetVulkanFunctions().vkInvalidateMappedMemoryRanges)(m_hAllocator->m_hDevice, 1, &memRange); - } - - // THE PLACE WHERE ACTUAL DATA COPY HAPPENS. - memmove( - reinterpret_cast(dstBlockInfo.pMappedData) + move.dstOffset, - reinterpret_cast(srcBlockInfo.pMappedData) + move.srcOffset, - static_cast(move.size)); - - if(IsCorruptionDetectionEnabled()) - { - VmaWriteMagicValue(dstBlockInfo.pMappedData, move.dstOffset - VMA_DEBUG_MARGIN); - VmaWriteMagicValue(dstBlockInfo.pMappedData, move.dstOffset + move.size); - } - - // Flush destination. - if(isNonCoherent) - { - VmaDeviceMemoryBlock* const pDstBlock = m_Blocks[move.dstBlockIndex]; - memRange.memory = pDstBlock->GetDeviceMemory(); - memRange.offset = VmaAlignDown(move.dstOffset, nonCoherentAtomSize); - memRange.size = VMA_MIN( - VmaAlignUp(move.size + (move.dstOffset - memRange.offset), nonCoherentAtomSize), - pDstBlock->m_pMetadata->GetSize() - memRange.offset); - (*m_hAllocator->GetVulkanFunctions().vkFlushMappedMemoryRanges)(m_hAllocator->m_hDevice, 1, &memRange); - } - } - } - - // Go over all blocks in reverse order. Unmap those that were mapped just for defragmentation. - // Regardless of pCtx->res == VK_SUCCESS. - for(size_t blockIndex = blockCount; blockIndex--; ) - { - const BlockInfo& currBlockInfo = blockInfo[blockIndex]; - if((currBlockInfo.flags & BLOCK_FLAG_MAPPED_FOR_DEFRAGMENTATION) != 0) - { - VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex]; - pBlock->Unmap(m_hAllocator, 1); - } - } -} - -void VmaBlockVector::ApplyDefragmentationMovesGpu( - class VmaBlockVectorDefragmentationContext* pDefragCtx, - VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, - VkCommandBuffer commandBuffer) -{ - const size_t blockCount = m_Blocks.size(); - - pDefragCtx->blockContexts.resize(blockCount); - memset(pDefragCtx->blockContexts.data(), 0, blockCount * sizeof(VmaBlockDefragmentationContext)); - - // Go over all moves. Mark blocks that are used with BLOCK_FLAG_USED. - const size_t moveCount = moves.size(); - for(size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex) - { - const VmaDefragmentationMove& move = moves[moveIndex]; - - //if(move.type == VMA_ALLOCATION_TYPE_UNKNOWN) - { - // Old school move still require us to map the whole block - pDefragCtx->blockContexts[move.srcBlockIndex].flags |= VmaBlockDefragmentationContext::BLOCK_FLAG_USED; - pDefragCtx->blockContexts[move.dstBlockIndex].flags |= VmaBlockDefragmentationContext::BLOCK_FLAG_USED; - } - } - - VMA_ASSERT(pDefragCtx->res == VK_SUCCESS); - - // Go over all blocks. Create and bind buffer for whole block if necessary. - { - VkBufferCreateInfo bufCreateInfo; - VmaFillGpuDefragmentationBufferCreateInfo(bufCreateInfo); - - for(size_t blockIndex = 0; pDefragCtx->res == VK_SUCCESS && blockIndex < blockCount; ++blockIndex) - { - VmaBlockDefragmentationContext& currBlockCtx = pDefragCtx->blockContexts[blockIndex]; - VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex]; - if((currBlockCtx.flags & VmaBlockDefragmentationContext::BLOCK_FLAG_USED) != 0) - { - bufCreateInfo.size = pBlock->m_pMetadata->GetSize(); - pDefragCtx->res = (*m_hAllocator->GetVulkanFunctions().vkCreateBuffer)( - m_hAllocator->m_hDevice, &bufCreateInfo, m_hAllocator->GetAllocationCallbacks(), &currBlockCtx.hBuffer); - if(pDefragCtx->res == VK_SUCCESS) - { - pDefragCtx->res = (*m_hAllocator->GetVulkanFunctions().vkBindBufferMemory)( - m_hAllocator->m_hDevice, currBlockCtx.hBuffer, pBlock->GetDeviceMemory(), 0); - } - } - } - } - - // Go over all moves. Post data transfer commands to command buffer. - if(pDefragCtx->res == VK_SUCCESS) - { - for(size_t moveIndex = 0; moveIndex < moveCount; ++moveIndex) - { - const VmaDefragmentationMove& move = moves[moveIndex]; - - const VmaBlockDefragmentationContext& srcBlockCtx = pDefragCtx->blockContexts[move.srcBlockIndex]; - const VmaBlockDefragmentationContext& dstBlockCtx = pDefragCtx->blockContexts[move.dstBlockIndex]; - - VMA_ASSERT(srcBlockCtx.hBuffer && dstBlockCtx.hBuffer); - - VkBufferCopy region = { - move.srcOffset, - move.dstOffset, - move.size }; - (*m_hAllocator->GetVulkanFunctions().vkCmdCopyBuffer)( - commandBuffer, srcBlockCtx.hBuffer, dstBlockCtx.hBuffer, 1, ®ion); - } - } - - // Save buffers to defrag context for later destruction. - if(pDefragCtx->res == VK_SUCCESS && moveCount > 0) - { - pDefragCtx->res = VK_NOT_READY; - } -} - -void VmaBlockVector::FreeEmptyBlocks(VmaDefragmentationStats* pDefragmentationStats) -{ - for(size_t blockIndex = m_Blocks.size(); blockIndex--; ) - { - VmaDeviceMemoryBlock* pBlock = m_Blocks[blockIndex]; - if(pBlock->m_pMetadata->IsEmpty()) - { - if(m_Blocks.size() > m_MinBlockCount) - { - if(pDefragmentationStats != VMA_NULL) - { - ++pDefragmentationStats->deviceMemoryBlocksFreed; - pDefragmentationStats->bytesFreed += pBlock->m_pMetadata->GetSize(); - } - - VmaVectorRemove(m_Blocks, blockIndex); - pBlock->Destroy(m_hAllocator); - vma_delete(m_hAllocator, pBlock); - } - else - { - break; - } - } - } - UpdateHasEmptyBlock(); -} - -void VmaBlockVector::UpdateHasEmptyBlock() -{ - m_HasEmptyBlock = false; - for(size_t index = 0, count = m_Blocks.size(); index < count; ++index) + for (size_t index = 0, count = m_Blocks.size(); index < count; ++index) { VmaDeviceMemoryBlock* const pBlock = m_Blocks[index]; - if(pBlock->m_pMetadata->IsEmpty()) - { - m_HasEmptyBlock = true; - break; - } - } -} - -#if VMA_STATS_STRING_ENABLED - -void VmaBlockVector::PrintDetailedMap(class VmaJsonWriter& json) -{ - VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); - - json.BeginObject(); - - if(IsCustomPool()) - { - const char* poolName = m_hParentPool->GetName(); - if(poolName != VMA_NULL && poolName[0] != '\0') - { - json.WriteString("Name"); - json.WriteString(poolName); - } - - json.WriteString("MemoryTypeIndex"); - json.WriteNumber(m_MemoryTypeIndex); - - json.WriteString("BlockSize"); - json.WriteNumber(m_PreferredBlockSize); - - json.WriteString("BlockCount"); - json.BeginObject(true); - if(m_MinBlockCount > 0) - { - json.WriteString("Min"); - json.WriteNumber((uint64_t)m_MinBlockCount); - } - if(m_MaxBlockCount < SIZE_MAX) - { - json.WriteString("Max"); - json.WriteNumber((uint64_t)m_MaxBlockCount); - } - json.WriteString("Cur"); - json.WriteNumber((uint64_t)m_Blocks.size()); - json.EndObject(); - - if(m_FrameInUseCount > 0) - { - json.WriteString("FrameInUseCount"); - json.WriteNumber(m_FrameInUseCount); - } - - if(m_Algorithm != 0) - { - json.WriteString("Algorithm"); - json.WriteString(VmaAlgorithmToStr(m_Algorithm)); - } - } - else - { - json.WriteString("PreferredBlockSize"); - json.WriteNumber(m_PreferredBlockSize); - } - - json.WriteString("Blocks"); - json.BeginObject(); - for(size_t i = 0; i < m_Blocks.size(); ++i) - { - json.BeginString(); - json.ContinueString(m_Blocks[i]->GetId()); - json.EndString(); - - m_Blocks[i]->m_pMetadata->PrintDetailedMap(json); - } - json.EndObject(); - - json.EndObject(); -} - -#endif // #if VMA_STATS_STRING_ENABLED - -void VmaBlockVector::Defragment( - class VmaBlockVectorDefragmentationContext* pCtx, - VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags, - VkDeviceSize& maxCpuBytesToMove, uint32_t& maxCpuAllocationsToMove, - VkDeviceSize& maxGpuBytesToMove, uint32_t& maxGpuAllocationsToMove, - VkCommandBuffer commandBuffer) -{ - pCtx->res = VK_SUCCESS; - - const VkMemoryPropertyFlags memPropFlags = - m_hAllocator->m_MemProps.memoryTypes[m_MemoryTypeIndex].propertyFlags; - const bool isHostVisible = (memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0; - - const bool canDefragmentOnCpu = maxCpuBytesToMove > 0 && maxCpuAllocationsToMove > 0 && - isHostVisible; - const bool canDefragmentOnGpu = maxGpuBytesToMove > 0 && maxGpuAllocationsToMove > 0 && - !IsCorruptionDetectionEnabled() && - ((1u << m_MemoryTypeIndex) & m_hAllocator->GetGpuDefragmentationMemoryTypeBits()) != 0; - - // There are options to defragment this memory type. - if(canDefragmentOnCpu || canDefragmentOnGpu) - { - bool defragmentOnGpu; - // There is only one option to defragment this memory type. - if(canDefragmentOnGpu != canDefragmentOnCpu) - { - defragmentOnGpu = canDefragmentOnGpu; - } - // Both options are available: Heuristics to choose the best one. - else - { - defragmentOnGpu = (memPropFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0 || - m_hAllocator->IsIntegratedGpu(); - } - - bool overlappingMoveSupported = !defragmentOnGpu; - - if(m_hAllocator->m_UseMutex) - { - if(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL) - { - if(!m_Mutex.TryLockWrite()) - { - pCtx->res = VK_ERROR_INITIALIZATION_FAILED; - return; - } - } - else - { - m_Mutex.LockWrite(); - pCtx->mutexLocked = true; - } - } - - pCtx->Begin(overlappingMoveSupported, flags); - - // Defragment. - - const VkDeviceSize maxBytesToMove = defragmentOnGpu ? maxGpuBytesToMove : maxCpuBytesToMove; - const uint32_t maxAllocationsToMove = defragmentOnGpu ? maxGpuAllocationsToMove : maxCpuAllocationsToMove; - pCtx->res = pCtx->GetAlgorithm()->Defragment(pCtx->defragmentationMoves, maxBytesToMove, maxAllocationsToMove, flags); - - // Accumulate statistics. - if(pStats != VMA_NULL) - { - const VkDeviceSize bytesMoved = pCtx->GetAlgorithm()->GetBytesMoved(); - const uint32_t allocationsMoved = pCtx->GetAlgorithm()->GetAllocationsMoved(); - pStats->bytesMoved += bytesMoved; - pStats->allocationsMoved += allocationsMoved; - VMA_ASSERT(bytesMoved <= maxBytesToMove); - VMA_ASSERT(allocationsMoved <= maxAllocationsToMove); - if(defragmentOnGpu) - { - maxGpuBytesToMove -= bytesMoved; - maxGpuAllocationsToMove -= allocationsMoved; - } - else - { - maxCpuBytesToMove -= bytesMoved; - maxCpuAllocationsToMove -= allocationsMoved; - } - } - - if(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL) - { - if(m_hAllocator->m_UseMutex) - m_Mutex.UnlockWrite(); - - if(pCtx->res >= VK_SUCCESS && !pCtx->defragmentationMoves.empty()) - pCtx->res = VK_NOT_READY; - - return; - } - - if(pCtx->res >= VK_SUCCESS) - { - if(defragmentOnGpu) - { - ApplyDefragmentationMovesGpu(pCtx, pCtx->defragmentationMoves, commandBuffer); - } - else - { - ApplyDefragmentationMovesCpu(pCtx, pCtx->defragmentationMoves); - } - } - } -} - -void VmaBlockVector::DefragmentationEnd( - class VmaBlockVectorDefragmentationContext* pCtx, - uint32_t flags, - VmaDefragmentationStats* pStats) -{ - if(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL && m_hAllocator->m_UseMutex) - { - VMA_ASSERT(pCtx->mutexLocked == false); - - // Incremental defragmentation doesn't hold the lock, so when we enter here we don't actually have any - // lock protecting us. Since we mutate state here, we have to take the lock out now - m_Mutex.LockWrite(); - pCtx->mutexLocked = true; - } - - // If the mutex isn't locked we didn't do any work and there is nothing to delete. - if(pCtx->mutexLocked || !m_hAllocator->m_UseMutex) - { - // Destroy buffers. - for(size_t blockIndex = pCtx->blockContexts.size(); blockIndex--;) - { - VmaBlockDefragmentationContext &blockCtx = pCtx->blockContexts[blockIndex]; - if(blockCtx.hBuffer) - { - (*m_hAllocator->GetVulkanFunctions().vkDestroyBuffer)(m_hAllocator->m_hDevice, blockCtx.hBuffer, m_hAllocator->GetAllocationCallbacks()); - } - } - - if(pCtx->res >= VK_SUCCESS) - { - FreeEmptyBlocks(pStats); - } - } - - if(pCtx->mutexLocked) - { - VMA_ASSERT(m_hAllocator->m_UseMutex); - m_Mutex.UnlockWrite(); - } -} - -uint32_t VmaBlockVector::ProcessDefragmentations( - class VmaBlockVectorDefragmentationContext *pCtx, - VmaDefragmentationPassMoveInfo* pMove, uint32_t maxMoves) -{ - VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex); - - const uint32_t moveCount = VMA_MIN(uint32_t(pCtx->defragmentationMoves.size()) - pCtx->defragmentationMovesProcessed, maxMoves); - - for(uint32_t i = 0; i < moveCount; ++ i) - { - VmaDefragmentationMove& move = pCtx->defragmentationMoves[pCtx->defragmentationMovesProcessed + i]; - - pMove->allocation = move.hAllocation; - pMove->memory = move.pDstBlock->GetDeviceMemory(); - pMove->offset = move.dstOffset; - - ++ pMove; - } - - pCtx->defragmentationMovesProcessed += moveCount; - - return moveCount; -} - -void VmaBlockVector::CommitDefragmentations( - class VmaBlockVectorDefragmentationContext *pCtx, - VmaDefragmentationStats* pStats) -{ - VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex); - - for(uint32_t i = pCtx->defragmentationMovesCommitted; i < pCtx->defragmentationMovesProcessed; ++ i) - { - const VmaDefragmentationMove &move = pCtx->defragmentationMoves[i]; - - move.pSrcBlock->m_pMetadata->FreeAtOffset(move.srcOffset); - move.hAllocation->ChangeBlockAllocation(m_hAllocator, move.pDstBlock, move.dstOffset); - } - - pCtx->defragmentationMovesCommitted = pCtx->defragmentationMovesProcessed; - FreeEmptyBlocks(pStats); -} - -size_t VmaBlockVector::CalcAllocationCount() const -{ - size_t result = 0; - for(size_t i = 0; i < m_Blocks.size(); ++i) - { - result += m_Blocks[i]->m_pMetadata->GetAllocationCount(); - } - return result; -} - -bool VmaBlockVector::IsBufferImageGranularityConflictPossible() const -{ - if(m_BufferImageGranularity == 1) - { - return false; - } - VmaSuballocationType lastSuballocType = VMA_SUBALLOCATION_TYPE_FREE; - for(size_t i = 0, count = m_Blocks.size(); i < count; ++i) - { - VmaDeviceMemoryBlock* const pBlock = m_Blocks[i]; - VMA_ASSERT(m_Algorithm == 0); - VmaBlockMetadata_Generic* const pMetadata = (VmaBlockMetadata_Generic*)pBlock->m_pMetadata; - if(pMetadata->IsBufferImageGranularityConflictPossible(m_BufferImageGranularity, lastSuballocType)) + if (pBlock->m_pMetadata->IsEmpty()) { return true; } @@ -12389,38 +12898,44 @@ bool VmaBlockVector::IsBufferImageGranularityConflictPossible() const return false; } -void VmaBlockVector::MakePoolAllocationsLost( - uint32_t currentFrameIndex, - size_t* pLostAllocationCount) +#if VMA_STATS_STRING_ENABLED +void VmaBlockVector::PrintDetailedMap(class VmaJsonWriter& json) { - VmaMutexLockWrite lock(m_Mutex, m_hAllocator->m_UseMutex); - size_t lostAllocationCount = 0; - for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) + VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); + + + json.BeginObject(); + for (size_t i = 0; i < m_Blocks.size(); ++i) { - VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex]; - VMA_ASSERT(pBlock); - lostAllocationCount += pBlock->m_pMetadata->MakeAllocationsLost(currentFrameIndex, m_FrameInUseCount); - } - if(pLostAllocationCount != VMA_NULL) - { - *pLostAllocationCount = lostAllocationCount; + json.BeginString(); + json.ContinueString(m_Blocks[i]->GetId()); + json.EndString(); + + json.BeginObject(); + json.WriteString("MapRefCount"); + json.WriteNumber(m_Blocks[i]->GetMapRefCount()); + + m_Blocks[i]->m_pMetadata->PrintDetailedMap(json); + json.EndObject(); } + json.EndObject(); } +#endif // VMA_STATS_STRING_ENABLED VkResult VmaBlockVector::CheckCorruption() { - if(!IsCorruptionDetectionEnabled()) + if (!IsCorruptionDetectionEnabled()) { return VK_ERROR_FEATURE_NOT_PRESENT; } VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); - for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) + for (uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) { VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex]; VMA_ASSERT(pBlock); VkResult res = pBlock->CheckCorruption(m_hAllocator); - if(res != VK_SUCCESS) + if (res != VK_SUCCESS) { return res; } @@ -12428,1755 +12943,1029 @@ VkResult VmaBlockVector::CheckCorruption() return VK_SUCCESS; } -void VmaBlockVector::AddStats(VmaStats* pStats) -{ - const uint32_t memTypeIndex = m_MemoryTypeIndex; - const uint32_t memHeapIndex = m_hAllocator->MemoryTypeIndexToHeapIndex(memTypeIndex); +#endif // _VMA_BLOCK_VECTOR_FUNCTIONS - VmaMutexLockRead lock(m_Mutex, m_hAllocator->m_UseMutex); - - for(uint32_t blockIndex = 0; blockIndex < m_Blocks.size(); ++blockIndex) - { - const VmaDeviceMemoryBlock* const pBlock = m_Blocks[blockIndex]; - VMA_ASSERT(pBlock); - VMA_HEAVY_ASSERT(pBlock->Validate()); - VmaStatInfo allocationStatInfo; - pBlock->m_pMetadata->CalcAllocationStatInfo(allocationStatInfo); - VmaAddStatInfo(pStats->total, allocationStatInfo); - VmaAddStatInfo(pStats->memoryType[memTypeIndex], allocationStatInfo); - VmaAddStatInfo(pStats->memoryHeap[memHeapIndex], allocationStatInfo); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// VmaDefragmentationAlgorithm_Generic members definition - -VmaDefragmentationAlgorithm_Generic::VmaDefragmentationAlgorithm_Generic( +#ifndef _VMA_DEFRAGMENTATION_CONTEXT_FUNCTIONS +VmaDefragmentationContext_T::VmaDefragmentationContext_T( VmaAllocator hAllocator, - VmaBlockVector* pBlockVector, - uint32_t currentFrameIndex, - bool overlappingMoveSupported) : - VmaDefragmentationAlgorithm(hAllocator, pBlockVector, currentFrameIndex), - m_AllocationCount(0), - m_AllAllocations(false), - m_BytesMoved(0), - m_AllocationsMoved(0), - m_Blocks(VmaStlAllocator(hAllocator->GetAllocationCallbacks())) + const VmaDefragmentationInfo& info) + : m_MaxPassBytes(info.maxBytesPerPass == 0 ? VK_WHOLE_SIZE : info.maxBytesPerPass), + m_MaxPassAllocations(info.maxAllocationsPerPass == 0 ? UINT32_MAX : info.maxAllocationsPerPass), + m_MoveAllocator(hAllocator->GetAllocationCallbacks()), + m_Moves(m_MoveAllocator) { - // Create block info for each block. - const size_t blockCount = m_pBlockVector->m_Blocks.size(); - for(size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) + m_Algorithm = info.flags & VMA_DEFRAGMENTATION_FLAG_ALGORITHM_MASK; + + if (info.pool != VMA_NULL) { - BlockInfo* pBlockInfo = vma_new(m_hAllocator, BlockInfo)(m_hAllocator->GetAllocationCallbacks()); - pBlockInfo->m_OriginalBlockIndex = blockIndex; - pBlockInfo->m_pBlock = m_pBlockVector->m_Blocks[blockIndex]; - m_Blocks.push_back(pBlockInfo); + m_BlockVectorCount = 1; + m_PoolBlockVector = &info.pool->m_BlockVector; + m_pBlockVectors = &m_PoolBlockVector; + m_PoolBlockVector->SetIncrementalSort(false); + m_PoolBlockVector->SortByFreeSize(); } - - // Sort them by m_pBlock pointer value. - VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockPointerLess()); -} - -VmaDefragmentationAlgorithm_Generic::~VmaDefragmentationAlgorithm_Generic() -{ - for(size_t i = m_Blocks.size(); i--; ) + else { - vma_delete(m_hAllocator, m_Blocks[i]); - } -} - -void VmaDefragmentationAlgorithm_Generic::AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) -{ - // Now as we are inside VmaBlockVector::m_Mutex, we can make final check if this allocation was not lost. - if(hAlloc->GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST) - { - VmaDeviceMemoryBlock* pBlock = hAlloc->GetBlock(); - BlockInfoVector::iterator it = VmaBinaryFindFirstNotLess(m_Blocks.begin(), m_Blocks.end(), pBlock, BlockPointerLess()); - if(it != m_Blocks.end() && (*it)->m_pBlock == pBlock) + m_BlockVectorCount = hAllocator->GetMemoryTypeCount(); + m_PoolBlockVector = VMA_NULL; + m_pBlockVectors = hAllocator->m_pBlockVectors; + for (uint32_t i = 0; i < m_BlockVectorCount; ++i) { - AllocationInfo allocInfo = AllocationInfo(hAlloc, pChanged); - (*it)->m_Allocations.push_back(allocInfo); + VmaBlockVector* vector = m_pBlockVectors[i]; + if (vector != VMA_NULL) + { + vector->SetIncrementalSort(false); + vector->SortByFreeSize(); + } + } + } + + switch (m_Algorithm) + { + case 0: // Default algorithm + m_Algorithm = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT; + case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT: + { + m_AlgorithmState = vma_new_array(hAllocator, StateBalanced, m_BlockVectorCount); + break; + } + case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT: + { + if (hAllocator->GetBufferImageGranularity() > 1) + { + m_AlgorithmState = vma_new_array(hAllocator, StateExtensive, m_BlockVectorCount); + } + break; + } + } +} + +VmaDefragmentationContext_T::~VmaDefragmentationContext_T() +{ + if (m_PoolBlockVector != VMA_NULL) + { + m_PoolBlockVector->SetIncrementalSort(true); + } + else + { + for (uint32_t i = 0; i < m_BlockVectorCount; ++i) + { + VmaBlockVector* vector = m_pBlockVectors[i]; + if (vector != VMA_NULL) + vector->SetIncrementalSort(true); + } + } + + if (m_AlgorithmState) + { + switch (m_Algorithm) + { + case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT: + vma_delete_array(m_MoveAllocator.m_pCallbacks, reinterpret_cast(m_AlgorithmState), m_BlockVectorCount); + break; + case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT: + vma_delete_array(m_MoveAllocator.m_pCallbacks, reinterpret_cast(m_AlgorithmState), m_BlockVectorCount); + break; + default: + VMA_ASSERT(0); + } + } +} + +VkResult VmaDefragmentationContext_T::DefragmentPassBegin(VmaDefragmentationPassMoveInfo& moveInfo) +{ + if (m_PoolBlockVector != VMA_NULL) + { + VmaMutexLockWrite lock(m_PoolBlockVector->GetMutex(), m_PoolBlockVector->GetAllocator()->m_UseMutex); + + if (m_PoolBlockVector->GetBlockCount() > 1) + ComputeDefragmentation(*m_PoolBlockVector, 0); + else if (m_PoolBlockVector->GetBlockCount() == 1) + ReallocWithinBlock(*m_PoolBlockVector, m_PoolBlockVector->GetBlock(0)); + } + else + { + for (uint32_t i = 0; i < m_BlockVectorCount; ++i) + { + if (m_pBlockVectors[i] != VMA_NULL) + { + VmaMutexLockWrite lock(m_pBlockVectors[i]->GetMutex(), m_pBlockVectors[i]->GetAllocator()->m_UseMutex); + + if (m_pBlockVectors[i]->GetBlockCount() > 1) + { + if (ComputeDefragmentation(*m_pBlockVectors[i], i)) + break; + } + else if (m_pBlockVectors[i]->GetBlockCount() == 1) + { + if (ReallocWithinBlock(*m_pBlockVectors[i], m_pBlockVectors[i]->GetBlock(0))) + break; + } + } + } + } + + moveInfo.moveCount = static_cast(m_Moves.size()); + if (moveInfo.moveCount > 0) + { + moveInfo.pMoves = m_Moves.data(); + return VK_INCOMPLETE; + } + + moveInfo.pMoves = VMA_NULL; + return VK_SUCCESS; +} + +VkResult VmaDefragmentationContext_T::DefragmentPassEnd(VmaDefragmentationPassMoveInfo& moveInfo) +{ + VMA_ASSERT(moveInfo.moveCount > 0 ? moveInfo.pMoves != VMA_NULL : true); + + VkResult result = VK_SUCCESS; + VmaStlAllocator blockAllocator(m_MoveAllocator.m_pCallbacks); + VmaVector> immovableBlocks(blockAllocator); + VmaVector> mappedBlocks(blockAllocator); + + VmaAllocator allocator = VMA_NULL; + for (uint32_t i = 0; i < moveInfo.moveCount; ++i) + { + VmaDefragmentationMove& move = moveInfo.pMoves[i]; + size_t prevCount = 0, currentCount = 0; + VkDeviceSize freedBlockSize = 0; + + uint32_t vectorIndex; + VmaBlockVector* vector; + if (m_PoolBlockVector != VMA_NULL) + { + vectorIndex = 0; + vector = m_PoolBlockVector; } else { + vectorIndex = move.srcAllocation->GetMemoryTypeIndex(); + vector = m_pBlockVectors[vectorIndex]; + VMA_ASSERT(vector != VMA_NULL); + } + + switch (move.operation) + { + case VMA_DEFRAGMENTATION_MOVE_OPERATION_COPY: + { + uint8_t mapCount = move.srcAllocation->SwapBlockAllocation(vector->m_hAllocator, move.dstTmpAllocation); + if (mapCount > 0) + { + allocator = vector->m_hAllocator; + VmaDeviceMemoryBlock* newMapBlock = move.srcAllocation->GetBlock(); + bool notPresent = true; + for (FragmentedBlock& block : mappedBlocks) + { + if (block.block == newMapBlock) + { + notPresent = false; + block.data += mapCount; + break; + } + } + if (notPresent) + mappedBlocks.push_back({ mapCount, newMapBlock }); + } + + // Scope for locks, Free have it's own lock + { + VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex); + prevCount = vector->GetBlockCount(); + freedBlockSize = move.dstTmpAllocation->GetBlock()->m_pMetadata->GetSize(); + } + vector->Free(move.dstTmpAllocation); + { + VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex); + currentCount = vector->GetBlockCount(); + } + + result = VK_INCOMPLETE; + break; + } + case VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE: + { + m_PassStats.bytesMoved -= move.srcAllocation->GetSize(); + --m_PassStats.allocationsMoved; + vector->Free(move.dstTmpAllocation); + + VmaDeviceMemoryBlock* newBlock = move.srcAllocation->GetBlock(); + bool notPresent = true; + for (const FragmentedBlock& block : immovableBlocks) + { + if (block.block == newBlock) + { + notPresent = false; + break; + } + } + if (notPresent) + immovableBlocks.push_back({ vectorIndex, newBlock }); + break; + } + case VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY: + { + m_PassStats.bytesMoved -= move.srcAllocation->GetSize(); + --m_PassStats.allocationsMoved; + // Scope for locks, Free have it's own lock + { + VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex); + prevCount = vector->GetBlockCount(); + freedBlockSize = move.srcAllocation->GetBlock()->m_pMetadata->GetSize(); + } + vector->Free(move.srcAllocation); + { + VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex); + currentCount = vector->GetBlockCount(); + } + freedBlockSize *= prevCount - currentCount; + + VkDeviceSize dstBlockSize; + { + VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex); + dstBlockSize = move.dstTmpAllocation->GetBlock()->m_pMetadata->GetSize(); + } + vector->Free(move.dstTmpAllocation); + { + VmaMutexLockRead lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex); + freedBlockSize += dstBlockSize * (currentCount - vector->GetBlockCount()); + currentCount = vector->GetBlockCount(); + } + + result = VK_INCOMPLETE; + break; + } + default: VMA_ASSERT(0); } - ++m_AllocationCount; - } -} - -VkResult VmaDefragmentationAlgorithm_Generic::DefragmentRound( - VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, - VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove, - bool freeOldAllocations) -{ - if(m_Blocks.empty()) - { - return VK_SUCCESS; - } - - // This is a choice based on research. - // Option 1: - uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT; - // Option 2: - //uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT; - // Option 3: - //uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT; - - size_t srcBlockMinIndex = 0; - // When FAST_ALGORITHM, move allocations from only last out of blocks that contain non-movable allocations. - /* - if(m_AlgorithmFlags & VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT) - { - const size_t blocksWithNonMovableCount = CalcBlocksWithNonMovableCount(); - if(blocksWithNonMovableCount > 0) + if (prevCount > currentCount) { - srcBlockMinIndex = blocksWithNonMovableCount - 1; - } - } - */ - - size_t srcBlockIndex = m_Blocks.size() - 1; - size_t srcAllocIndex = SIZE_MAX; - for(;;) - { - // 1. Find next allocation to move. - // 1.1. Start from last to first m_Blocks - they are sorted from most "destination" to most "source". - // 1.2. Then start from last to first m_Allocations. - while(srcAllocIndex >= m_Blocks[srcBlockIndex]->m_Allocations.size()) - { - if(m_Blocks[srcBlockIndex]->m_Allocations.empty()) - { - // Finished: no more allocations to process. - if(srcBlockIndex == srcBlockMinIndex) - { - return VK_SUCCESS; - } - else - { - --srcBlockIndex; - srcAllocIndex = SIZE_MAX; - } - } - else - { - srcAllocIndex = m_Blocks[srcBlockIndex]->m_Allocations.size() - 1; - } + size_t freedBlocks = prevCount - currentCount; + m_PassStats.deviceMemoryBlocksFreed += static_cast(freedBlocks); + m_PassStats.bytesFreed += freedBlockSize; } - BlockInfo* pSrcBlockInfo = m_Blocks[srcBlockIndex]; - AllocationInfo& allocInfo = pSrcBlockInfo->m_Allocations[srcAllocIndex]; - - const VkDeviceSize size = allocInfo.m_hAllocation->GetSize(); - const VkDeviceSize srcOffset = allocInfo.m_hAllocation->GetOffset(); - const VkDeviceSize alignment = allocInfo.m_hAllocation->GetAlignment(); - const VmaSuballocationType suballocType = allocInfo.m_hAllocation->GetSuballocationType(); - - // 2. Try to find new place for this allocation in preceding or current block. - for(size_t dstBlockIndex = 0; dstBlockIndex <= srcBlockIndex; ++dstBlockIndex) + switch (m_Algorithm) { - BlockInfo* pDstBlockInfo = m_Blocks[dstBlockIndex]; - VmaAllocationRequest dstAllocRequest; - if(pDstBlockInfo->m_pBlock->m_pMetadata->CreateAllocationRequest( - m_CurrentFrameIndex, - m_pBlockVector->GetFrameInUseCount(), - m_pBlockVector->GetBufferImageGranularity(), - size, - alignment, - false, // upperAddress - suballocType, - false, // canMakeOtherLost - strategy, - &dstAllocRequest) && - MoveMakesSense( - dstBlockIndex, dstAllocRequest.offset, srcBlockIndex, srcOffset)) + case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT: + { + if (m_AlgorithmState != VMA_NULL) { - VMA_ASSERT(dstAllocRequest.itemsToMakeLostCount == 0); - - // Reached limit on number of allocations or bytes to move. - if((m_AllocationsMoved + 1 > maxAllocationsToMove) || - (m_BytesMoved + size > maxBytesToMove)) + // Avoid unnecessary tries to allocate when new free block is avaiable + StateExtensive& state = reinterpret_cast(m_AlgorithmState)[vectorIndex]; + if (state.firstFreeBlock != SIZE_MAX) { - return VK_SUCCESS; + const size_t diff = prevCount - currentCount; + if (state.firstFreeBlock >= diff) + { + state.firstFreeBlock -= diff; + if (state.firstFreeBlock != 0) + state.firstFreeBlock -= vector->GetBlock(state.firstFreeBlock - 1)->m_pMetadata->IsEmpty(); + } + else + state.firstFreeBlock = 0; } + } + } + } + } + moveInfo.moveCount = 0; + moveInfo.pMoves = VMA_NULL; + m_Moves.clear(); - VmaDefragmentationMove move = {}; - move.srcBlockIndex = pSrcBlockInfo->m_OriginalBlockIndex; - move.dstBlockIndex = pDstBlockInfo->m_OriginalBlockIndex; - move.srcOffset = srcOffset; - move.dstOffset = dstAllocRequest.offset; - move.size = size; - move.hAllocation = allocInfo.m_hAllocation; - move.pSrcBlock = pSrcBlockInfo->m_pBlock; - move.pDstBlock = pDstBlockInfo->m_pBlock; + // Update stats + m_GlobalStats.allocationsMoved += m_PassStats.allocationsMoved; + m_GlobalStats.bytesFreed += m_PassStats.bytesFreed; + m_GlobalStats.bytesMoved += m_PassStats.bytesMoved; + m_GlobalStats.deviceMemoryBlocksFreed += m_PassStats.deviceMemoryBlocksFreed; + m_PassStats = { 0 }; - moves.push_back(move); - - pDstBlockInfo->m_pBlock->m_pMetadata->Alloc( - dstAllocRequest, - suballocType, - size, - allocInfo.m_hAllocation); - - if(freeOldAllocations) + // Move blocks with immovable allocations according to algorithm + if (immovableBlocks.size() > 0) + { + switch (m_Algorithm) + { + case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT: + { + if (m_AlgorithmState != VMA_NULL) + { + bool swapped = false; + // Move to the start of free blocks range + for (const FragmentedBlock& block : immovableBlocks) { - pSrcBlockInfo->m_pBlock->m_pMetadata->FreeAtOffset(srcOffset); - allocInfo.m_hAllocation->ChangeBlockAllocation(m_hAllocator, pDstBlockInfo->m_pBlock, dstAllocRequest.offset); + StateExtensive& state = reinterpret_cast(m_AlgorithmState)[block.data]; + if (state.operation != StateExtensive::Operation::Cleanup) + { + VmaBlockVector* vector = m_pBlockVectors[block.data]; + VmaMutexLockWrite lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex); + + for (size_t i = 0, count = vector->GetBlockCount() - m_ImmovableBlockCount; i < count; ++i) + { + if (vector->GetBlock(i) == block.block) + { + VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[vector->GetBlockCount() - ++m_ImmovableBlockCount]); + if (state.firstFreeBlock != SIZE_MAX) + { + if (i + 1 < state.firstFreeBlock) + { + if (state.firstFreeBlock > 1) + VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[--state.firstFreeBlock]); + else + --state.firstFreeBlock; + } + } + swapped = true; + break; + } + } + } } - - if(allocInfo.m_pChanged != VMA_NULL) - { - *allocInfo.m_pChanged = VK_TRUE; - } - - ++m_AllocationsMoved; - m_BytesMoved += size; - - VmaVectorRemove(pSrcBlockInfo->m_Allocations, srcAllocIndex); - + if (swapped) + result = VK_INCOMPLETE; break; } } - - // If not processed, this allocInfo remains in pBlockInfo->m_Allocations for next round. - - if(srcAllocIndex > 0) + default: { - --srcAllocIndex; - } - else - { - if(srcBlockIndex > 0) + // Move to the begining + for (const FragmentedBlock& block : immovableBlocks) { - --srcBlockIndex; - srcAllocIndex = SIZE_MAX; - } - else - { - return VK_SUCCESS; - } - } - } -} + VmaBlockVector* vector = m_pBlockVectors[block.data]; + VmaMutexLockWrite lock(vector->GetMutex(), vector->GetAllocator()->m_UseMutex); -size_t VmaDefragmentationAlgorithm_Generic::CalcBlocksWithNonMovableCount() const -{ - size_t result = 0; - for(size_t i = 0; i < m_Blocks.size(); ++i) - { - if(m_Blocks[i]->m_HasNonMovableAllocations) - { - ++result; - } - } - return result; -} - -VkResult VmaDefragmentationAlgorithm_Generic::Defragment( - VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, - VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove, - VmaDefragmentationFlags flags) -{ - if(!m_AllAllocations && m_AllocationCount == 0) - { - return VK_SUCCESS; - } - - const size_t blockCount = m_Blocks.size(); - for(size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) - { - BlockInfo* pBlockInfo = m_Blocks[blockIndex]; - - if(m_AllAllocations) - { - VmaBlockMetadata_Generic* pMetadata = (VmaBlockMetadata_Generic*)pBlockInfo->m_pBlock->m_pMetadata; - for(VmaSuballocationList::const_iterator it = pMetadata->m_Suballocations.begin(); - it != pMetadata->m_Suballocations.end(); - ++it) - { - if(it->type != VMA_SUBALLOCATION_TYPE_FREE) + for (size_t i = m_ImmovableBlockCount; i < vector->GetBlockCount(); ++i) { - AllocationInfo allocInfo = AllocationInfo(it->hAllocation, VMA_NULL); - pBlockInfo->m_Allocations.push_back(allocInfo); + if (vector->GetBlock(i) == block.block) + { + VMA_SWAP(vector->m_Blocks[i], vector->m_Blocks[m_ImmovableBlockCount++]); + break; + } } } + break; + } } - - pBlockInfo->CalcHasNonMovableAllocations(); - - // This is a choice based on research. - // Option 1: - pBlockInfo->SortAllocationsByOffsetDescending(); - // Option 2: - //pBlockInfo->SortAllocationsBySizeDescending(); } - // Sort m_Blocks this time by the main criterium, from most "destination" to most "source" blocks. - VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockInfoCompareMoveDestination()); - - // This is a choice based on research. - const uint32_t roundCount = 2; - - // Execute defragmentation rounds (the main part). - VkResult result = VK_SUCCESS; - for(uint32_t round = 0; (round < roundCount) && (result == VK_SUCCESS); ++round) + // Bulk-map destination blocks + for (const FragmentedBlock& block : mappedBlocks) { - result = DefragmentRound(moves, maxBytesToMove, maxAllocationsToMove, !(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL)); + VkResult res = block.block->Map(allocator, block.data, VMA_NULL); + VMA_ASSERT(res == VK_SUCCESS); } - return result; } -bool VmaDefragmentationAlgorithm_Generic::MoveMakesSense( - size_t dstBlockIndex, VkDeviceSize dstOffset, - size_t srcBlockIndex, VkDeviceSize srcOffset) +bool VmaDefragmentationContext_T::ComputeDefragmentation(VmaBlockVector& vector, size_t index) { - if(dstBlockIndex < srcBlockIndex) + switch (m_Algorithm) { - return true; + case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT: + return ComputeDefragmentation_Fast(vector); + default: + VMA_ASSERT(0); + case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_BALANCED_BIT: + return ComputeDefragmentation_Balanced(vector, index, true); + case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FULL_BIT: + return ComputeDefragmentation_Full(vector); + case VMA_DEFRAGMENTATION_FLAG_ALGORITHM_EXTENSIVE_BIT: + return ComputeDefragmentation_Extensive(vector, index); } - if(dstBlockIndex > srcBlockIndex) +} + +VmaDefragmentationContext_T::MoveAllocationData VmaDefragmentationContext_T::GetMoveData( + VmaAllocHandle handle, VmaBlockMetadata* metadata) +{ + MoveAllocationData moveData; + moveData.move.srcAllocation = (VmaAllocation)metadata->GetAllocationUserData(handle); + moveData.size = moveData.move.srcAllocation->GetSize(); + moveData.alignment = moveData.move.srcAllocation->GetAlignment(); + moveData.type = moveData.move.srcAllocation->GetSuballocationType(); + moveData.flags = 0; + + if (moveData.move.srcAllocation->IsPersistentMap()) + moveData.flags |= VMA_ALLOCATION_CREATE_MAPPED_BIT; + if (moveData.move.srcAllocation->IsMappingAllowed()) + moveData.flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; + + return moveData; +} + +VmaDefragmentationContext_T::CounterStatus VmaDefragmentationContext_T::CheckCounters(VkDeviceSize bytes) +{ + // Ignore allocation if will exceed max size for copy + if (m_PassStats.bytesMoved + bytes > m_MaxPassBytes) { - return false; + if (++m_IgnoredAllocs < MAX_ALLOCS_TO_IGNORE) + return CounterStatus::Ignore; + else + return CounterStatus::End; } - if(dstOffset < srcOffset) + return CounterStatus::Pass; +} + +bool VmaDefragmentationContext_T::IncrementCounters(VkDeviceSize bytes) +{ + m_PassStats.bytesMoved += bytes; + // Early return when max found + if (++m_PassStats.allocationsMoved >= m_MaxPassAllocations || m_PassStats.bytesMoved >= m_MaxPassBytes) { + VMA_ASSERT(m_PassStats.allocationsMoved == m_MaxPassAllocations || + m_PassStats.bytesMoved == m_MaxPassBytes && "Exceeded maximal pass threshold!"); return true; } return false; } -//////////////////////////////////////////////////////////////////////////////// -// VmaDefragmentationAlgorithm_Fast - -VmaDefragmentationAlgorithm_Fast::VmaDefragmentationAlgorithm_Fast( - VmaAllocator hAllocator, - VmaBlockVector* pBlockVector, - uint32_t currentFrameIndex, - bool overlappingMoveSupported) : - VmaDefragmentationAlgorithm(hAllocator, pBlockVector, currentFrameIndex), - m_OverlappingMoveSupported(overlappingMoveSupported), - m_AllocationCount(0), - m_AllAllocations(false), - m_BytesMoved(0), - m_AllocationsMoved(0), - m_BlockInfos(VmaStlAllocator(hAllocator->GetAllocationCallbacks())) +bool VmaDefragmentationContext_T::ReallocWithinBlock(VmaBlockVector& vector, VmaDeviceMemoryBlock* block) { - VMA_ASSERT(VMA_DEBUG_MARGIN == 0); + VmaBlockMetadata* metadata = block->m_pMetadata; -} - -VmaDefragmentationAlgorithm_Fast::~VmaDefragmentationAlgorithm_Fast() -{ -} - -VkResult VmaDefragmentationAlgorithm_Fast::Defragment( - VmaVector< VmaDefragmentationMove, VmaStlAllocator >& moves, - VkDeviceSize maxBytesToMove, - uint32_t maxAllocationsToMove, - VmaDefragmentationFlags flags) -{ - VMA_ASSERT(m_AllAllocations || m_pBlockVector->CalcAllocationCount() == m_AllocationCount); - - const size_t blockCount = m_pBlockVector->GetBlockCount(); - if(blockCount == 0 || maxBytesToMove == 0 || maxAllocationsToMove == 0) + for (VmaAllocHandle handle = metadata->GetAllocationListBegin(); + handle != VK_NULL_HANDLE; + handle = metadata->GetNextAllocation(handle)) { - return VK_SUCCESS; - } - - PreprocessMetadata(); - - // Sort blocks in order from most destination. - - m_BlockInfos.resize(blockCount); - for(size_t i = 0; i < blockCount; ++i) - { - m_BlockInfos[i].origBlockIndex = i; - } - - VMA_SORT(m_BlockInfos.begin(), m_BlockInfos.end(), [this](const BlockInfo& lhs, const BlockInfo& rhs) -> bool { - return m_pBlockVector->GetBlock(lhs.origBlockIndex)->m_pMetadata->GetSumFreeSize() < - m_pBlockVector->GetBlock(rhs.origBlockIndex)->m_pMetadata->GetSumFreeSize(); - }); - - // THE MAIN ALGORITHM - - FreeSpaceDatabase freeSpaceDb; - - size_t dstBlockInfoIndex = 0; - size_t dstOrigBlockIndex = m_BlockInfos[dstBlockInfoIndex].origBlockIndex; - VmaDeviceMemoryBlock* pDstBlock = m_pBlockVector->GetBlock(dstOrigBlockIndex); - VmaBlockMetadata_Generic* pDstMetadata = (VmaBlockMetadata_Generic*)pDstBlock->m_pMetadata; - VkDeviceSize dstBlockSize = pDstMetadata->GetSize(); - VkDeviceSize dstOffset = 0; - - bool end = false; - for(size_t srcBlockInfoIndex = 0; !end && srcBlockInfoIndex < blockCount; ++srcBlockInfoIndex) - { - const size_t srcOrigBlockIndex = m_BlockInfos[srcBlockInfoIndex].origBlockIndex; - VmaDeviceMemoryBlock* const pSrcBlock = m_pBlockVector->GetBlock(srcOrigBlockIndex); - VmaBlockMetadata_Generic* const pSrcMetadata = (VmaBlockMetadata_Generic*)pSrcBlock->m_pMetadata; - for(VmaSuballocationList::iterator srcSuballocIt = pSrcMetadata->m_Suballocations.begin(); - !end && srcSuballocIt != pSrcMetadata->m_Suballocations.end(); ) + MoveAllocationData moveData = GetMoveData(handle, metadata); + // Ignore newly created allocations by defragmentation algorithm + if (moveData.move.srcAllocation->GetUserData() == this) + continue; + switch (CheckCounters(moveData.move.srcAllocation->GetSize())) { - VmaAllocation_T* const pAlloc = srcSuballocIt->hAllocation; - const VkDeviceSize srcAllocAlignment = pAlloc->GetAlignment(); - const VkDeviceSize srcAllocSize = srcSuballocIt->size; - if(m_AllocationsMoved == maxAllocationsToMove || - m_BytesMoved + srcAllocSize > maxBytesToMove) + case CounterStatus::Ignore: + continue; + case CounterStatus::End: + return true; + default: + VMA_ASSERT(0); + case CounterStatus::Pass: + break; + } + + VkDeviceSize offset = moveData.move.srcAllocation->GetOffset(); + if (offset != 0 && metadata->GetSumFreeSize() >= moveData.size) + { + VmaAllocationRequest request = {}; + if (metadata->CreateAllocationRequest( + moveData.size, + moveData.alignment, + false, + moveData.type, + VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT, + &request)) { - end = true; + if (metadata->GetAllocationOffset(request.allocHandle) < offset) + { + if (vector.CommitAllocationRequest( + request, + block, + moveData.alignment, + moveData.flags, + this, + moveData.type, + &moveData.move.dstTmpAllocation) == VK_SUCCESS) + { + m_Moves.push_back(moveData.move); + if (IncrementCounters(moveData.size)) + return true; + } + } + } + } + } + return false; +} + +bool VmaDefragmentationContext_T::AllocInOtherBlock(size_t start, size_t end, MoveAllocationData& data, VmaBlockVector& vector) +{ + for (; start < end; ++start) + { + VmaDeviceMemoryBlock* dstBlock = vector.GetBlock(start); + if (dstBlock->m_pMetadata->GetSumFreeSize() >= data.size) + { + if (vector.AllocateFromBlock(dstBlock, + data.size, + data.alignment, + data.flags, + this, + data.type, + 0, + &data.move.dstTmpAllocation) == VK_SUCCESS) + { + m_Moves.push_back(data.move); + if (IncrementCounters(data.size)) + return true; break; } - const VkDeviceSize srcAllocOffset = srcSuballocIt->offset; + } + } + return false; +} - VmaDefragmentationMove move = {}; - // Try to place it in one of free spaces from the database. - size_t freeSpaceInfoIndex; - VkDeviceSize dstAllocOffset; - if(freeSpaceDb.Fetch(srcAllocAlignment, srcAllocSize, - freeSpaceInfoIndex, dstAllocOffset)) +bool VmaDefragmentationContext_T::ComputeDefragmentation_Fast(VmaBlockVector& vector) +{ + // Move only between blocks + + // Go through allocations in last blocks and try to fit them inside first ones + for (size_t i = vector.GetBlockCount() - 1; i > m_ImmovableBlockCount; --i) + { + VmaBlockMetadata* metadata = vector.GetBlock(i)->m_pMetadata; + + for (VmaAllocHandle handle = metadata->GetAllocationListBegin(); + handle != VK_NULL_HANDLE; + handle = metadata->GetNextAllocation(handle)) + { + MoveAllocationData moveData = GetMoveData(handle, metadata); + // Ignore newly created allocations by defragmentation algorithm + if (moveData.move.srcAllocation->GetUserData() == this) + continue; + switch (CheckCounters(moveData.move.srcAllocation->GetSize())) { - size_t freeSpaceOrigBlockIndex = m_BlockInfos[freeSpaceInfoIndex].origBlockIndex; - VmaDeviceMemoryBlock* pFreeSpaceBlock = m_pBlockVector->GetBlock(freeSpaceOrigBlockIndex); - VmaBlockMetadata_Generic* pFreeSpaceMetadata = (VmaBlockMetadata_Generic*)pFreeSpaceBlock->m_pMetadata; - - // Same block - if(freeSpaceInfoIndex == srcBlockInfoIndex) - { - VMA_ASSERT(dstAllocOffset <= srcAllocOffset); - - // MOVE OPTION 1: Move the allocation inside the same block by decreasing offset. - - VmaSuballocation suballoc = *srcSuballocIt; - suballoc.offset = dstAllocOffset; - suballoc.hAllocation->ChangeOffset(dstAllocOffset); - m_BytesMoved += srcAllocSize; - ++m_AllocationsMoved; - - VmaSuballocationList::iterator nextSuballocIt = srcSuballocIt; - ++nextSuballocIt; - pSrcMetadata->m_Suballocations.erase(srcSuballocIt); - srcSuballocIt = nextSuballocIt; - - InsertSuballoc(pFreeSpaceMetadata, suballoc); - - move.srcBlockIndex = srcOrigBlockIndex; - move.dstBlockIndex = freeSpaceOrigBlockIndex; - move.srcOffset = srcAllocOffset; - move.dstOffset = dstAllocOffset; - move.size = srcAllocSize; - - moves.push_back(move); - } - // Different block - else - { - // MOVE OPTION 2: Move the allocation to a different block. - - VMA_ASSERT(freeSpaceInfoIndex < srcBlockInfoIndex); - - VmaSuballocation suballoc = *srcSuballocIt; - suballoc.offset = dstAllocOffset; - suballoc.hAllocation->ChangeBlockAllocation(m_hAllocator, pFreeSpaceBlock, dstAllocOffset); - m_BytesMoved += srcAllocSize; - ++m_AllocationsMoved; - - VmaSuballocationList::iterator nextSuballocIt = srcSuballocIt; - ++nextSuballocIt; - pSrcMetadata->m_Suballocations.erase(srcSuballocIt); - srcSuballocIt = nextSuballocIt; - - InsertSuballoc(pFreeSpaceMetadata, suballoc); - - move.srcBlockIndex = srcOrigBlockIndex; - move.dstBlockIndex = freeSpaceOrigBlockIndex; - move.srcOffset = srcAllocOffset; - move.dstOffset = dstAllocOffset; - move.size = srcAllocSize; - - moves.push_back(move); - } + case CounterStatus::Ignore: + continue; + case CounterStatus::End: + return true; + default: + VMA_ASSERT(0); + case CounterStatus::Pass: + break; } - else + + // Check all previous blocks for free space + if (AllocInOtherBlock(0, i, moveData, vector)) + return true; + } + } + return false; +} + +bool VmaDefragmentationContext_T::ComputeDefragmentation_Balanced(VmaBlockVector& vector, size_t index, bool update) +{ + // Go over every allocation and try to fit it in previous blocks at lowest offsets, + // if not possible: realloc within single block to minimize offset (exclude offset == 0), + // but only if there are noticable gaps between them (some heuristic, ex. average size of allocation in block) + VMA_ASSERT(m_AlgorithmState != VMA_NULL); + + StateBalanced& vectorState = reinterpret_cast(m_AlgorithmState)[index]; + if (update && vectorState.avgAllocSize == UINT64_MAX) + UpdateVectorStatistics(vector, vectorState); + + const size_t startMoveCount = m_Moves.size(); + VkDeviceSize minimalFreeRegion = vectorState.avgFreeSize / 2; + for (size_t i = vector.GetBlockCount() - 1; i > m_ImmovableBlockCount; --i) + { + VmaDeviceMemoryBlock* block = vector.GetBlock(i); + VmaBlockMetadata* metadata = block->m_pMetadata; + VkDeviceSize prevFreeRegionSize = 0; + + for (VmaAllocHandle handle = metadata->GetAllocationListBegin(); + handle != VK_NULL_HANDLE; + handle = metadata->GetNextAllocation(handle)) + { + MoveAllocationData moveData = GetMoveData(handle, metadata); + // Ignore newly created allocations by defragmentation algorithm + if (moveData.move.srcAllocation->GetUserData() == this) + continue; + switch (CheckCounters(moveData.move.srcAllocation->GetSize())) { - dstAllocOffset = VmaAlignUp(dstOffset, srcAllocAlignment); + case CounterStatus::Ignore: + continue; + case CounterStatus::End: + return true; + default: + VMA_ASSERT(0); + case CounterStatus::Pass: + break; + } - // If the allocation doesn't fit before the end of dstBlock, forward to next block. - while(dstBlockInfoIndex < srcBlockInfoIndex && - dstAllocOffset + srcAllocSize > dstBlockSize) + // Check all previous blocks for free space + const size_t prevMoveCount = m_Moves.size(); + if (AllocInOtherBlock(0, i, moveData, vector)) + return true; + + VkDeviceSize nextFreeRegionSize = metadata->GetNextFreeRegionSize(handle); + // If no room found then realloc within block for lower offset + VkDeviceSize offset = moveData.move.srcAllocation->GetOffset(); + if (prevMoveCount == m_Moves.size() && offset != 0 && metadata->GetSumFreeSize() >= moveData.size) + { + // Check if realloc will make sense + if (prevFreeRegionSize >= minimalFreeRegion || + nextFreeRegionSize >= minimalFreeRegion || + moveData.size <= vectorState.avgFreeSize || + moveData.size <= vectorState.avgAllocSize) { - // But before that, register remaining free space at the end of dst block. - freeSpaceDb.Register(dstBlockInfoIndex, dstOffset, dstBlockSize - dstOffset); - - ++dstBlockInfoIndex; - dstOrigBlockIndex = m_BlockInfos[dstBlockInfoIndex].origBlockIndex; - pDstBlock = m_pBlockVector->GetBlock(dstOrigBlockIndex); - pDstMetadata = (VmaBlockMetadata_Generic*)pDstBlock->m_pMetadata; - dstBlockSize = pDstMetadata->GetSize(); - dstOffset = 0; - dstAllocOffset = 0; - } - - // Same block - if(dstBlockInfoIndex == srcBlockInfoIndex) - { - VMA_ASSERT(dstAllocOffset <= srcAllocOffset); - - const bool overlap = dstAllocOffset + srcAllocSize > srcAllocOffset; - - bool skipOver = overlap; - if(overlap && m_OverlappingMoveSupported && dstAllocOffset < srcAllocOffset) + VmaAllocationRequest request = {}; + if (metadata->CreateAllocationRequest( + moveData.size, + moveData.alignment, + false, + moveData.type, + VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT, + &request)) { - // If destination and source place overlap, skip if it would move it - // by only < 1/64 of its size. - skipOver = (srcAllocOffset - dstAllocOffset) * 64 < srcAllocSize; - } - - if(skipOver) - { - freeSpaceDb.Register(dstBlockInfoIndex, dstOffset, srcAllocOffset - dstOffset); - - dstOffset = srcAllocOffset + srcAllocSize; - ++srcSuballocIt; - } - // MOVE OPTION 1: Move the allocation inside the same block by decreasing offset. - else - { - srcSuballocIt->offset = dstAllocOffset; - srcSuballocIt->hAllocation->ChangeOffset(dstAllocOffset); - dstOffset = dstAllocOffset + srcAllocSize; - m_BytesMoved += srcAllocSize; - ++m_AllocationsMoved; - ++srcSuballocIt; - - move.srcBlockIndex = srcOrigBlockIndex; - move.dstBlockIndex = dstOrigBlockIndex; - move.srcOffset = srcAllocOffset; - move.dstOffset = dstAllocOffset; - move.size = srcAllocSize; - - moves.push_back(move); - } - } - // Different block - else - { - // MOVE OPTION 2: Move the allocation to a different block. - - VMA_ASSERT(dstBlockInfoIndex < srcBlockInfoIndex); - VMA_ASSERT(dstAllocOffset + srcAllocSize <= dstBlockSize); - - VmaSuballocation suballoc = *srcSuballocIt; - suballoc.offset = dstAllocOffset; - suballoc.hAllocation->ChangeBlockAllocation(m_hAllocator, pDstBlock, dstAllocOffset); - dstOffset = dstAllocOffset + srcAllocSize; - m_BytesMoved += srcAllocSize; - ++m_AllocationsMoved; - - VmaSuballocationList::iterator nextSuballocIt = srcSuballocIt; - ++nextSuballocIt; - pSrcMetadata->m_Suballocations.erase(srcSuballocIt); - srcSuballocIt = nextSuballocIt; - - pDstMetadata->m_Suballocations.push_back(suballoc); - - move.srcBlockIndex = srcOrigBlockIndex; - move.dstBlockIndex = dstOrigBlockIndex; - move.srcOffset = srcAllocOffset; - move.dstOffset = dstAllocOffset; - move.size = srcAllocSize; - - moves.push_back(move); - } - } - } - } - - m_BlockInfos.clear(); - - PostprocessMetadata(); - - return VK_SUCCESS; -} - -void VmaDefragmentationAlgorithm_Fast::PreprocessMetadata() -{ - const size_t blockCount = m_pBlockVector->GetBlockCount(); - for(size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) - { - VmaBlockMetadata_Generic* const pMetadata = - (VmaBlockMetadata_Generic*)m_pBlockVector->GetBlock(blockIndex)->m_pMetadata; - pMetadata->m_FreeCount = 0; - pMetadata->m_SumFreeSize = pMetadata->GetSize(); - pMetadata->m_FreeSuballocationsBySize.clear(); - for(VmaSuballocationList::iterator it = pMetadata->m_Suballocations.begin(); - it != pMetadata->m_Suballocations.end(); ) - { - if(it->type == VMA_SUBALLOCATION_TYPE_FREE) - { - VmaSuballocationList::iterator nextIt = it; - ++nextIt; - pMetadata->m_Suballocations.erase(it); - it = nextIt; - } - else - { - ++it; - } - } - } -} - -void VmaDefragmentationAlgorithm_Fast::PostprocessMetadata() -{ - const size_t blockCount = m_pBlockVector->GetBlockCount(); - for(size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex) - { - VmaBlockMetadata_Generic* const pMetadata = - (VmaBlockMetadata_Generic*)m_pBlockVector->GetBlock(blockIndex)->m_pMetadata; - const VkDeviceSize blockSize = pMetadata->GetSize(); - - // No allocations in this block - entire area is free. - if(pMetadata->m_Suballocations.empty()) - { - pMetadata->m_FreeCount = 1; - //pMetadata->m_SumFreeSize is already set to blockSize. - VmaSuballocation suballoc = { - 0, // offset - blockSize, // size - VMA_NULL, // hAllocation - VMA_SUBALLOCATION_TYPE_FREE }; - pMetadata->m_Suballocations.push_back(suballoc); - pMetadata->RegisterFreeSuballocation(pMetadata->m_Suballocations.begin()); - } - // There are some allocations in this block. - else - { - VkDeviceSize offset = 0; - VmaSuballocationList::iterator it; - for(it = pMetadata->m_Suballocations.begin(); - it != pMetadata->m_Suballocations.end(); - ++it) - { - VMA_ASSERT(it->type != VMA_SUBALLOCATION_TYPE_FREE); - VMA_ASSERT(it->offset >= offset); - - // Need to insert preceding free space. - if(it->offset > offset) - { - ++pMetadata->m_FreeCount; - const VkDeviceSize freeSize = it->offset - offset; - VmaSuballocation suballoc = { - offset, // offset - freeSize, // size - VMA_NULL, // hAllocation - VMA_SUBALLOCATION_TYPE_FREE }; - VmaSuballocationList::iterator precedingFreeIt = pMetadata->m_Suballocations.insert(it, suballoc); - if(freeSize >= VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) - { - pMetadata->m_FreeSuballocationsBySize.push_back(precedingFreeIt); - } - } - - pMetadata->m_SumFreeSize -= it->size; - offset = it->offset + it->size; - } - - // Need to insert trailing free space. - if(offset < blockSize) - { - ++pMetadata->m_FreeCount; - const VkDeviceSize freeSize = blockSize - offset; - VmaSuballocation suballoc = { - offset, // offset - freeSize, // size - VMA_NULL, // hAllocation - VMA_SUBALLOCATION_TYPE_FREE }; - VMA_ASSERT(it == pMetadata->m_Suballocations.end()); - VmaSuballocationList::iterator trailingFreeIt = pMetadata->m_Suballocations.insert(it, suballoc); - if(freeSize > VMA_MIN_FREE_SUBALLOCATION_SIZE_TO_REGISTER) - { - pMetadata->m_FreeSuballocationsBySize.push_back(trailingFreeIt); - } - } - - VMA_SORT( - pMetadata->m_FreeSuballocationsBySize.begin(), - pMetadata->m_FreeSuballocationsBySize.end(), - VmaSuballocationItemSizeLess()); - } - - VMA_HEAVY_ASSERT(pMetadata->Validate()); - } -} - -void VmaDefragmentationAlgorithm_Fast::InsertSuballoc(VmaBlockMetadata_Generic* pMetadata, const VmaSuballocation& suballoc) -{ - // TODO: Optimize somehow. Remember iterator instead of searching for it linearly. - VmaSuballocationList::iterator it = pMetadata->m_Suballocations.begin(); - while(it != pMetadata->m_Suballocations.end()) - { - if(it->offset < suballoc.offset) - { - ++it; - } - } - pMetadata->m_Suballocations.insert(it, suballoc); -} - -//////////////////////////////////////////////////////////////////////////////// -// VmaBlockVectorDefragmentationContext - -VmaBlockVectorDefragmentationContext::VmaBlockVectorDefragmentationContext( - VmaAllocator hAllocator, - VmaPool hCustomPool, - VmaBlockVector* pBlockVector, - uint32_t currFrameIndex) : - res(VK_SUCCESS), - mutexLocked(false), - blockContexts(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), - defragmentationMoves(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), - defragmentationMovesProcessed(0), - defragmentationMovesCommitted(0), - hasDefragmentationPlan(0), - m_hAllocator(hAllocator), - m_hCustomPool(hCustomPool), - m_pBlockVector(pBlockVector), - m_CurrFrameIndex(currFrameIndex), - m_pAlgorithm(VMA_NULL), - m_Allocations(VmaStlAllocator(hAllocator->GetAllocationCallbacks())), - m_AllAllocations(false) -{ -} - -VmaBlockVectorDefragmentationContext::~VmaBlockVectorDefragmentationContext() -{ - vma_delete(m_hAllocator, m_pAlgorithm); -} - -void VmaBlockVectorDefragmentationContext::AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged) -{ - AllocInfo info = { hAlloc, pChanged }; - m_Allocations.push_back(info); -} - -void VmaBlockVectorDefragmentationContext::Begin(bool overlappingMoveSupported, VmaDefragmentationFlags flags) -{ - const bool allAllocations = m_AllAllocations || - m_Allocations.size() == m_pBlockVector->CalcAllocationCount(); - - /******************************** - HERE IS THE CHOICE OF DEFRAGMENTATION ALGORITHM. - ********************************/ - - /* - Fast algorithm is supported only when certain criteria are met: - - VMA_DEBUG_MARGIN is 0. - - All allocations in this block vector are moveable. - - There is no possibility of image/buffer granularity conflict. - - The defragmentation is not incremental - */ - if(VMA_DEBUG_MARGIN == 0 && - allAllocations && - !m_pBlockVector->IsBufferImageGranularityConflictPossible() && - !(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL)) - { - m_pAlgorithm = vma_new(m_hAllocator, VmaDefragmentationAlgorithm_Fast)( - m_hAllocator, m_pBlockVector, m_CurrFrameIndex, overlappingMoveSupported); - } - else - { - m_pAlgorithm = vma_new(m_hAllocator, VmaDefragmentationAlgorithm_Generic)( - m_hAllocator, m_pBlockVector, m_CurrFrameIndex, overlappingMoveSupported); - } - - if(allAllocations) - { - m_pAlgorithm->AddAll(); - } - else - { - for(size_t i = 0, count = m_Allocations.size(); i < count; ++i) - { - m_pAlgorithm->AddAllocation(m_Allocations[i].hAlloc, m_Allocations[i].pChanged); - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// VmaDefragmentationContext - -VmaDefragmentationContext_T::VmaDefragmentationContext_T( - VmaAllocator hAllocator, - uint32_t currFrameIndex, - uint32_t flags, - VmaDefragmentationStats* pStats) : - m_hAllocator(hAllocator), - m_CurrFrameIndex(currFrameIndex), - m_Flags(flags), - m_pStats(pStats), - m_CustomPoolContexts(VmaStlAllocator(hAllocator->GetAllocationCallbacks())) -{ - memset(m_DefaultPoolContexts, 0, sizeof(m_DefaultPoolContexts)); -} - -VmaDefragmentationContext_T::~VmaDefragmentationContext_T() -{ - for(size_t i = m_CustomPoolContexts.size(); i--; ) - { - VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_CustomPoolContexts[i]; - pBlockVectorCtx->GetBlockVector()->DefragmentationEnd(pBlockVectorCtx, m_Flags, m_pStats); - vma_delete(m_hAllocator, pBlockVectorCtx); - } - for(size_t i = m_hAllocator->m_MemProps.memoryTypeCount; i--; ) - { - VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[i]; - if(pBlockVectorCtx) - { - pBlockVectorCtx->GetBlockVector()->DefragmentationEnd(pBlockVectorCtx, m_Flags, m_pStats); - vma_delete(m_hAllocator, pBlockVectorCtx); - } - } -} - -void VmaDefragmentationContext_T::AddPools(uint32_t poolCount, const VmaPool* pPools) -{ - for(uint32_t poolIndex = 0; poolIndex < poolCount; ++poolIndex) - { - VmaPool pool = pPools[poolIndex]; - VMA_ASSERT(pool); - // Pools with algorithm other than default are not defragmented. - if(pool->m_BlockVector.GetAlgorithm() == 0) - { - VmaBlockVectorDefragmentationContext* pBlockVectorDefragCtx = VMA_NULL; - - for(size_t i = m_CustomPoolContexts.size(); i--; ) - { - if(m_CustomPoolContexts[i]->GetCustomPool() == pool) - { - pBlockVectorDefragCtx = m_CustomPoolContexts[i]; - break; - } - } - - if(!pBlockVectorDefragCtx) - { - pBlockVectorDefragCtx = vma_new(m_hAllocator, VmaBlockVectorDefragmentationContext)( - m_hAllocator, - pool, - &pool->m_BlockVector, - m_CurrFrameIndex); - m_CustomPoolContexts.push_back(pBlockVectorDefragCtx); - } - - pBlockVectorDefragCtx->AddAll(); - } - } -} - -void VmaDefragmentationContext_T::AddAllocations( - uint32_t allocationCount, - const VmaAllocation* pAllocations, - VkBool32* pAllocationsChanged) -{ - // Dispatch pAllocations among defragmentators. Create them when necessary. - for(uint32_t allocIndex = 0; allocIndex < allocationCount; ++allocIndex) - { - const VmaAllocation hAlloc = pAllocations[allocIndex]; - VMA_ASSERT(hAlloc); - // DedicatedAlloc cannot be defragmented. - if((hAlloc->GetType() == VmaAllocation_T::ALLOCATION_TYPE_BLOCK) && - // Lost allocation cannot be defragmented. - (hAlloc->GetLastUseFrameIndex() != VMA_FRAME_INDEX_LOST)) - { - VmaBlockVectorDefragmentationContext* pBlockVectorDefragCtx = VMA_NULL; - - const VmaPool hAllocPool = hAlloc->GetBlock()->GetParentPool(); - // This allocation belongs to custom pool. - if(hAllocPool != VK_NULL_HANDLE) - { - // Pools with algorithm other than default are not defragmented. - if(hAllocPool->m_BlockVector.GetAlgorithm() == 0) - { - for(size_t i = m_CustomPoolContexts.size(); i--; ) - { - if(m_CustomPoolContexts[i]->GetCustomPool() == hAllocPool) + if (metadata->GetAllocationOffset(request.allocHandle) < offset) { - pBlockVectorDefragCtx = m_CustomPoolContexts[i]; - break; + if (vector.CommitAllocationRequest( + request, + block, + moveData.alignment, + moveData.flags, + this, + moveData.type, + &moveData.move.dstTmpAllocation) == VK_SUCCESS) + { + m_Moves.push_back(moveData.move); + if (IncrementCounters(moveData.size)) + return true; + } } } - if(!pBlockVectorDefragCtx) + } + } + prevFreeRegionSize = nextFreeRegionSize; + } + } + + // No moves perfomed, update statistics to current vector state + if (startMoveCount == m_Moves.size() && !update) + { + vectorState.avgAllocSize = UINT64_MAX; + return ComputeDefragmentation_Balanced(vector, index, false); + } + return false; +} + +bool VmaDefragmentationContext_T::ComputeDefragmentation_Full(VmaBlockVector& vector) +{ + // Go over every allocation and try to fit it in previous blocks at lowest offsets, + // if not possible: realloc within single block to minimize offset (exclude offset == 0) + + for (size_t i = vector.GetBlockCount() - 1; i > m_ImmovableBlockCount; --i) + { + VmaDeviceMemoryBlock* block = vector.GetBlock(i); + VmaBlockMetadata* metadata = block->m_pMetadata; + + for (VmaAllocHandle handle = metadata->GetAllocationListBegin(); + handle != VK_NULL_HANDLE; + handle = metadata->GetNextAllocation(handle)) + { + MoveAllocationData moveData = GetMoveData(handle, metadata); + // Ignore newly created allocations by defragmentation algorithm + if (moveData.move.srcAllocation->GetUserData() == this) + continue; + switch (CheckCounters(moveData.move.srcAllocation->GetSize())) + { + case CounterStatus::Ignore: + continue; + case CounterStatus::End: + return true; + default: + VMA_ASSERT(0); + case CounterStatus::Pass: + break; + } + + // Check all previous blocks for free space + const size_t prevMoveCount = m_Moves.size(); + if (AllocInOtherBlock(0, i, moveData, vector)) + return true; + + // If no room found then realloc within block for lower offset + VkDeviceSize offset = moveData.move.srcAllocation->GetOffset(); + if (prevMoveCount == m_Moves.size() && offset != 0 && metadata->GetSumFreeSize() >= moveData.size) + { + VmaAllocationRequest request = {}; + if (metadata->CreateAllocationRequest( + moveData.size, + moveData.alignment, + false, + moveData.type, + VMA_ALLOCATION_CREATE_STRATEGY_MIN_OFFSET_BIT, + &request)) + { + if (metadata->GetAllocationOffset(request.allocHandle) < offset) { - pBlockVectorDefragCtx = vma_new(m_hAllocator, VmaBlockVectorDefragmentationContext)( - m_hAllocator, - hAllocPool, - &hAllocPool->m_BlockVector, - m_CurrFrameIndex); - m_CustomPoolContexts.push_back(pBlockVectorDefragCtx); + if (vector.CommitAllocationRequest( + request, + block, + moveData.alignment, + moveData.flags, + this, + moveData.type, + &moveData.move.dstTmpAllocation) == VK_SUCCESS) + { + m_Moves.push_back(moveData.move); + if (IncrementCounters(moveData.size)) + return true; + } } } } - // This allocation belongs to default pool. - else + } + } + return false; +} + +bool VmaDefragmentationContext_T::ComputeDefragmentation_Extensive(VmaBlockVector& vector, size_t index) +{ + // First free single block, then populate it to the brim, then free another block, and so on + + // Fallback to previous algorithm since without granularity conflicts it can achieve max packing + if (vector.m_BufferImageGranularity == 1) + return ComputeDefragmentation_Full(vector); + + VMA_ASSERT(m_AlgorithmState != VMA_NULL); + + StateExtensive& vectorState = reinterpret_cast(m_AlgorithmState)[index]; + + bool texturePresent = false, bufferPresent = false, otherPresent = false; + switch (vectorState.operation) + { + case StateExtensive::Operation::Done: // Vector defragmented + return false; + case StateExtensive::Operation::FindFreeBlockBuffer: + case StateExtensive::Operation::FindFreeBlockTexture: + case StateExtensive::Operation::FindFreeBlockAll: + { + // No more blocks to free, just perform fast realloc and move to cleanup + if (vectorState.firstFreeBlock == 0) + { + vectorState.operation = StateExtensive::Operation::Cleanup; + return ComputeDefragmentation_Fast(vector); + } + + // No free blocks, have to clear last one + size_t last = (vectorState.firstFreeBlock == SIZE_MAX ? vector.GetBlockCount() : vectorState.firstFreeBlock) - 1; + VmaBlockMetadata* freeMetadata = vector.GetBlock(last)->m_pMetadata; + + const size_t prevMoveCount = m_Moves.size(); + for (VmaAllocHandle handle = freeMetadata->GetAllocationListBegin(); + handle != VK_NULL_HANDLE; + handle = freeMetadata->GetNextAllocation(handle)) + { + MoveAllocationData moveData = GetMoveData(handle, freeMetadata); + switch (CheckCounters(moveData.move.srcAllocation->GetSize())) { - const uint32_t memTypeIndex = hAlloc->GetMemoryTypeIndex(); - pBlockVectorDefragCtx = m_DefaultPoolContexts[memTypeIndex]; - if(!pBlockVectorDefragCtx) + case CounterStatus::Ignore: + continue; + case CounterStatus::End: + return true; + default: + VMA_ASSERT(0); + case CounterStatus::Pass: + break; + } + + // Check all previous blocks for free space + if (AllocInOtherBlock(0, last, moveData, vector)) + { + // Full clear performed already + if (prevMoveCount != m_Moves.size() && freeMetadata->GetNextAllocation(handle) == VK_NULL_HANDLE) + reinterpret_cast(m_AlgorithmState)[index] = last; + return true; + } + } + + if (prevMoveCount == m_Moves.size()) + { + // Cannot perform full clear, have to move data in other blocks around + if (last != 0) + { + for (size_t i = last - 1; i; --i) { - pBlockVectorDefragCtx = vma_new(m_hAllocator, VmaBlockVectorDefragmentationContext)( - m_hAllocator, - VMA_NULL, // hCustomPool - m_hAllocator->m_pBlockVectors[memTypeIndex], - m_CurrFrameIndex); - m_DefaultPoolContexts[memTypeIndex] = pBlockVectorDefragCtx; + if (ReallocWithinBlock(vector, vector.GetBlock(i))) + return true; } } - if(pBlockVectorDefragCtx) + if (prevMoveCount == m_Moves.size()) { - VkBool32* const pChanged = (pAllocationsChanged != VMA_NULL) ? - &pAllocationsChanged[allocIndex] : VMA_NULL; - pBlockVectorDefragCtx->AddAllocation(hAlloc, pChanged); + // No possible reallocs within blocks, try to move them around fast + return ComputeDefragmentation_Fast(vector); } } - } -} - -VkResult VmaDefragmentationContext_T::Defragment( - VkDeviceSize maxCpuBytesToMove, uint32_t maxCpuAllocationsToMove, - VkDeviceSize maxGpuBytesToMove, uint32_t maxGpuAllocationsToMove, - VkCommandBuffer commandBuffer, VmaDefragmentationStats* pStats, VmaDefragmentationFlags flags) -{ - if(pStats) - { - memset(pStats, 0, sizeof(VmaDefragmentationStats)); - } - - if(flags & VMA_DEFRAGMENTATION_FLAG_INCREMENTAL) - { - // For incremental defragmetnations, we just earmark how much we can move - // The real meat is in the defragmentation steps - m_MaxCpuBytesToMove = maxCpuBytesToMove; - m_MaxCpuAllocationsToMove = maxCpuAllocationsToMove; - - m_MaxGpuBytesToMove = maxGpuBytesToMove; - m_MaxGpuAllocationsToMove = maxGpuAllocationsToMove; - - if(m_MaxCpuBytesToMove == 0 && m_MaxCpuAllocationsToMove == 0 && - m_MaxGpuBytesToMove == 0 && m_MaxGpuAllocationsToMove == 0) - return VK_SUCCESS; - - return VK_NOT_READY; - } - - if(commandBuffer == VK_NULL_HANDLE) - { - maxGpuBytesToMove = 0; - maxGpuAllocationsToMove = 0; - } - - VkResult res = VK_SUCCESS; - - // Process default pools. - for(uint32_t memTypeIndex = 0; - memTypeIndex < m_hAllocator->GetMemoryTypeCount() && res >= VK_SUCCESS; - ++memTypeIndex) - { - VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex]; - if(pBlockVectorCtx) - { - VMA_ASSERT(pBlockVectorCtx->GetBlockVector()); - pBlockVectorCtx->GetBlockVector()->Defragment( - pBlockVectorCtx, - pStats, flags, - maxCpuBytesToMove, maxCpuAllocationsToMove, - maxGpuBytesToMove, maxGpuAllocationsToMove, - commandBuffer); - if(pBlockVectorCtx->res != VK_SUCCESS) - { - res = pBlockVectorCtx->res; - } - } - } - - // Process custom pools. - for(size_t customCtxIndex = 0, customCtxCount = m_CustomPoolContexts.size(); - customCtxIndex < customCtxCount && res >= VK_SUCCESS; - ++customCtxIndex) - { - VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_CustomPoolContexts[customCtxIndex]; - VMA_ASSERT(pBlockVectorCtx && pBlockVectorCtx->GetBlockVector()); - pBlockVectorCtx->GetBlockVector()->Defragment( - pBlockVectorCtx, - pStats, flags, - maxCpuBytesToMove, maxCpuAllocationsToMove, - maxGpuBytesToMove, maxGpuAllocationsToMove, - commandBuffer); - if(pBlockVectorCtx->res != VK_SUCCESS) - { - res = pBlockVectorCtx->res; - } - } - - return res; -} - -VkResult VmaDefragmentationContext_T::DefragmentPassBegin(VmaDefragmentationPassInfo* pInfo) -{ - VmaDefragmentationPassMoveInfo* pCurrentMove = pInfo->pMoves; - uint32_t movesLeft = pInfo->moveCount; - - // Process default pools. - for(uint32_t memTypeIndex = 0; - memTypeIndex < m_hAllocator->GetMemoryTypeCount(); - ++memTypeIndex) - { - VmaBlockVectorDefragmentationContext *pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex]; - if(pBlockVectorCtx) - { - VMA_ASSERT(pBlockVectorCtx->GetBlockVector()); - - if(!pBlockVectorCtx->hasDefragmentationPlan) - { - pBlockVectorCtx->GetBlockVector()->Defragment( - pBlockVectorCtx, - m_pStats, m_Flags, - m_MaxCpuBytesToMove, m_MaxCpuAllocationsToMove, - m_MaxGpuBytesToMove, m_MaxGpuAllocationsToMove, - VK_NULL_HANDLE); - - if(pBlockVectorCtx->res < VK_SUCCESS) - continue; - - pBlockVectorCtx->hasDefragmentationPlan = true; - } - - const uint32_t processed = pBlockVectorCtx->GetBlockVector()->ProcessDefragmentations( - pBlockVectorCtx, - pCurrentMove, movesLeft); - - movesLeft -= processed; - pCurrentMove += processed; - } - } - - // Process custom pools. - for(size_t customCtxIndex = 0, customCtxCount = m_CustomPoolContexts.size(); - customCtxIndex < customCtxCount; - ++customCtxIndex) - { - VmaBlockVectorDefragmentationContext *pBlockVectorCtx = m_CustomPoolContexts[customCtxIndex]; - VMA_ASSERT(pBlockVectorCtx && pBlockVectorCtx->GetBlockVector()); - - if(!pBlockVectorCtx->hasDefragmentationPlan) - { - pBlockVectorCtx->GetBlockVector()->Defragment( - pBlockVectorCtx, - m_pStats, m_Flags, - m_MaxCpuBytesToMove, m_MaxCpuAllocationsToMove, - m_MaxGpuBytesToMove, m_MaxGpuAllocationsToMove, - VK_NULL_HANDLE); - - if(pBlockVectorCtx->res < VK_SUCCESS) - continue; - - pBlockVectorCtx->hasDefragmentationPlan = true; - } - - const uint32_t processed = pBlockVectorCtx->GetBlockVector()->ProcessDefragmentations( - pBlockVectorCtx, - pCurrentMove, movesLeft); - - movesLeft -= processed; - pCurrentMove += processed; - } - - pInfo->moveCount = pInfo->moveCount - movesLeft; - - return VK_SUCCESS; -} -VkResult VmaDefragmentationContext_T::DefragmentPassEnd() -{ - VkResult res = VK_SUCCESS; - - // Process default pools. - for(uint32_t memTypeIndex = 0; - memTypeIndex < m_hAllocator->GetMemoryTypeCount(); - ++memTypeIndex) - { - VmaBlockVectorDefragmentationContext *pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex]; - if(pBlockVectorCtx) - { - VMA_ASSERT(pBlockVectorCtx->GetBlockVector()); - - if(!pBlockVectorCtx->hasDefragmentationPlan) - { - res = VK_NOT_READY; - continue; - } - - pBlockVectorCtx->GetBlockVector()->CommitDefragmentations( - pBlockVectorCtx, m_pStats); - - if(pBlockVectorCtx->defragmentationMoves.size() != pBlockVectorCtx->defragmentationMovesCommitted) - res = VK_NOT_READY; - } - } - - // Process custom pools. - for(size_t customCtxIndex = 0, customCtxCount = m_CustomPoolContexts.size(); - customCtxIndex < customCtxCount; - ++customCtxIndex) - { - VmaBlockVectorDefragmentationContext *pBlockVectorCtx = m_CustomPoolContexts[customCtxIndex]; - VMA_ASSERT(pBlockVectorCtx && pBlockVectorCtx->GetBlockVector()); - - if(!pBlockVectorCtx->hasDefragmentationPlan) - { - res = VK_NOT_READY; - continue; - } - - pBlockVectorCtx->GetBlockVector()->CommitDefragmentations( - pBlockVectorCtx, m_pStats); - - if(pBlockVectorCtx->defragmentationMoves.size() != pBlockVectorCtx->defragmentationMovesCommitted) - res = VK_NOT_READY; - } - - return res; -} - -//////////////////////////////////////////////////////////////////////////////// -// VmaRecorder - -#if VMA_RECORDING_ENABLED - -VmaRecorder::VmaRecorder() : - m_UseMutex(true), - m_Flags(0), - m_File(VMA_NULL), - m_RecordingStartTime(std::chrono::high_resolution_clock::now()) -{ -} - -VkResult VmaRecorder::Init(const VmaRecordSettings& settings, bool useMutex) -{ - m_UseMutex = useMutex; - m_Flags = settings.flags; - -#if defined(_WIN32) - // Open file for writing. - errno_t err = fopen_s(&m_File, settings.pFilePath, "wb"); - - if(err != 0) - { - return VK_ERROR_INITIALIZATION_FAILED; - } -#else - // Open file for writing. - m_File = fopen(settings.pFilePath, "wb"); - - if(m_File == 0) - { - return VK_ERROR_INITIALIZATION_FAILED; - } -#endif - - // Write header. - fprintf(m_File, "%s\n", "Vulkan Memory Allocator,Calls recording"); - fprintf(m_File, "%s\n", "1,8"); - - return VK_SUCCESS; -} - -VmaRecorder::~VmaRecorder() -{ - if(m_File != VMA_NULL) - { - fclose(m_File); - } -} - -void VmaRecorder::RecordCreateAllocator(uint32_t frameIndex) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaCreateAllocator\n", callParams.threadId, callParams.time, frameIndex); - Flush(); -} - -void VmaRecorder::RecordDestroyAllocator(uint32_t frameIndex) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaDestroyAllocator\n", callParams.threadId, callParams.time, frameIndex); - Flush(); -} - -void VmaRecorder::RecordCreatePool(uint32_t frameIndex, const VmaPoolCreateInfo& createInfo, VmaPool pool) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaCreatePool,%u,%u,%llu,%llu,%llu,%u,%p\n", callParams.threadId, callParams.time, frameIndex, - createInfo.memoryTypeIndex, - createInfo.flags, - createInfo.blockSize, - (uint64_t)createInfo.minBlockCount, - (uint64_t)createInfo.maxBlockCount, - createInfo.frameInUseCount, - pool); - Flush(); -} - -void VmaRecorder::RecordDestroyPool(uint32_t frameIndex, VmaPool pool) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaDestroyPool,%p\n", callParams.threadId, callParams.time, frameIndex, - pool); - Flush(); -} - -void VmaRecorder::RecordAllocateMemory(uint32_t frameIndex, - const VkMemoryRequirements& vkMemReq, - const VmaAllocationCreateInfo& createInfo, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - UserDataString userDataStr(createInfo.flags, createInfo.pUserData); - fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemory,%llu,%llu,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex, - vkMemReq.size, - vkMemReq.alignment, - vkMemReq.memoryTypeBits, - createInfo.flags, - createInfo.usage, - createInfo.requiredFlags, - createInfo.preferredFlags, - createInfo.memoryTypeBits, - createInfo.pool, - allocation, - userDataStr.GetString()); - Flush(); -} - -void VmaRecorder::RecordAllocateMemoryPages(uint32_t frameIndex, - const VkMemoryRequirements& vkMemReq, - const VmaAllocationCreateInfo& createInfo, - uint64_t allocationCount, - const VmaAllocation* pAllocations) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - UserDataString userDataStr(createInfo.flags, createInfo.pUserData); - fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemoryPages,%llu,%llu,%u,%u,%u,%u,%u,%u,%p,", callParams.threadId, callParams.time, frameIndex, - vkMemReq.size, - vkMemReq.alignment, - vkMemReq.memoryTypeBits, - createInfo.flags, - createInfo.usage, - createInfo.requiredFlags, - createInfo.preferredFlags, - createInfo.memoryTypeBits, - createInfo.pool); - PrintPointerList(allocationCount, pAllocations); - fprintf(m_File, ",%s\n", userDataStr.GetString()); - Flush(); -} - -void VmaRecorder::RecordAllocateMemoryForBuffer(uint32_t frameIndex, - const VkMemoryRequirements& vkMemReq, - bool requiresDedicatedAllocation, - bool prefersDedicatedAllocation, - const VmaAllocationCreateInfo& createInfo, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - UserDataString userDataStr(createInfo.flags, createInfo.pUserData); - fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemoryForBuffer,%llu,%llu,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex, - vkMemReq.size, - vkMemReq.alignment, - vkMemReq.memoryTypeBits, - requiresDedicatedAllocation ? 1 : 0, - prefersDedicatedAllocation ? 1 : 0, - createInfo.flags, - createInfo.usage, - createInfo.requiredFlags, - createInfo.preferredFlags, - createInfo.memoryTypeBits, - createInfo.pool, - allocation, - userDataStr.GetString()); - Flush(); -} - -void VmaRecorder::RecordAllocateMemoryForImage(uint32_t frameIndex, - const VkMemoryRequirements& vkMemReq, - bool requiresDedicatedAllocation, - bool prefersDedicatedAllocation, - const VmaAllocationCreateInfo& createInfo, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - UserDataString userDataStr(createInfo.flags, createInfo.pUserData); - fprintf(m_File, "%u,%.3f,%u,vmaAllocateMemoryForImage,%llu,%llu,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex, - vkMemReq.size, - vkMemReq.alignment, - vkMemReq.memoryTypeBits, - requiresDedicatedAllocation ? 1 : 0, - prefersDedicatedAllocation ? 1 : 0, - createInfo.flags, - createInfo.usage, - createInfo.requiredFlags, - createInfo.preferredFlags, - createInfo.memoryTypeBits, - createInfo.pool, - allocation, - userDataStr.GetString()); - Flush(); -} - -void VmaRecorder::RecordFreeMemory(uint32_t frameIndex, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaFreeMemory,%p\n", callParams.threadId, callParams.time, frameIndex, - allocation); - Flush(); -} - -void VmaRecorder::RecordFreeMemoryPages(uint32_t frameIndex, - uint64_t allocationCount, - const VmaAllocation* pAllocations) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaFreeMemoryPages,", callParams.threadId, callParams.time, frameIndex); - PrintPointerList(allocationCount, pAllocations); - fprintf(m_File, "\n"); - Flush(); -} - -void VmaRecorder::RecordSetAllocationUserData(uint32_t frameIndex, - VmaAllocation allocation, - const void* pUserData) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - UserDataString userDataStr( - allocation->IsUserDataString() ? VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT : 0, - pUserData); - fprintf(m_File, "%u,%.3f,%u,vmaSetAllocationUserData,%p,%s\n", callParams.threadId, callParams.time, frameIndex, - allocation, - userDataStr.GetString()); - Flush(); -} - -void VmaRecorder::RecordCreateLostAllocation(uint32_t frameIndex, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaCreateLostAllocation,%p\n", callParams.threadId, callParams.time, frameIndex, - allocation); - Flush(); -} - -void VmaRecorder::RecordMapMemory(uint32_t frameIndex, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaMapMemory,%p\n", callParams.threadId, callParams.time, frameIndex, - allocation); - Flush(); -} - -void VmaRecorder::RecordUnmapMemory(uint32_t frameIndex, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaUnmapMemory,%p\n", callParams.threadId, callParams.time, frameIndex, - allocation); - Flush(); -} - -void VmaRecorder::RecordFlushAllocation(uint32_t frameIndex, - VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaFlushAllocation,%p,%llu,%llu\n", callParams.threadId, callParams.time, frameIndex, - allocation, - offset, - size); - Flush(); -} - -void VmaRecorder::RecordInvalidateAllocation(uint32_t frameIndex, - VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaInvalidateAllocation,%p,%llu,%llu\n", callParams.threadId, callParams.time, frameIndex, - allocation, - offset, - size); - Flush(); -} - -void VmaRecorder::RecordCreateBuffer(uint32_t frameIndex, - const VkBufferCreateInfo& bufCreateInfo, - const VmaAllocationCreateInfo& allocCreateInfo, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - UserDataString userDataStr(allocCreateInfo.flags, allocCreateInfo.pUserData); - fprintf(m_File, "%u,%.3f,%u,vmaCreateBuffer,%u,%llu,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex, - bufCreateInfo.flags, - bufCreateInfo.size, - bufCreateInfo.usage, - bufCreateInfo.sharingMode, - allocCreateInfo.flags, - allocCreateInfo.usage, - allocCreateInfo.requiredFlags, - allocCreateInfo.preferredFlags, - allocCreateInfo.memoryTypeBits, - allocCreateInfo.pool, - allocation, - userDataStr.GetString()); - Flush(); -} - -void VmaRecorder::RecordCreateImage(uint32_t frameIndex, - const VkImageCreateInfo& imageCreateInfo, - const VmaAllocationCreateInfo& allocCreateInfo, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - UserDataString userDataStr(allocCreateInfo.flags, allocCreateInfo.pUserData); - fprintf(m_File, "%u,%.3f,%u,vmaCreateImage,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%p,%p,%s\n", callParams.threadId, callParams.time, frameIndex, - imageCreateInfo.flags, - imageCreateInfo.imageType, - imageCreateInfo.format, - imageCreateInfo.extent.width, - imageCreateInfo.extent.height, - imageCreateInfo.extent.depth, - imageCreateInfo.mipLevels, - imageCreateInfo.arrayLayers, - imageCreateInfo.samples, - imageCreateInfo.tiling, - imageCreateInfo.usage, - imageCreateInfo.sharingMode, - imageCreateInfo.initialLayout, - allocCreateInfo.flags, - allocCreateInfo.usage, - allocCreateInfo.requiredFlags, - allocCreateInfo.preferredFlags, - allocCreateInfo.memoryTypeBits, - allocCreateInfo.pool, - allocation, - userDataStr.GetString()); - Flush(); -} - -void VmaRecorder::RecordDestroyBuffer(uint32_t frameIndex, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaDestroyBuffer,%p\n", callParams.threadId, callParams.time, frameIndex, - allocation); - Flush(); -} - -void VmaRecorder::RecordDestroyImage(uint32_t frameIndex, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaDestroyImage,%p\n", callParams.threadId, callParams.time, frameIndex, - allocation); - Flush(); -} - -void VmaRecorder::RecordTouchAllocation(uint32_t frameIndex, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaTouchAllocation,%p\n", callParams.threadId, callParams.time, frameIndex, - allocation); - Flush(); -} - -void VmaRecorder::RecordGetAllocationInfo(uint32_t frameIndex, - VmaAllocation allocation) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaGetAllocationInfo,%p\n", callParams.threadId, callParams.time, frameIndex, - allocation); - Flush(); -} - -void VmaRecorder::RecordMakePoolAllocationsLost(uint32_t frameIndex, - VmaPool pool) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaMakePoolAllocationsLost,%p\n", callParams.threadId, callParams.time, frameIndex, - pool); - Flush(); -} - -void VmaRecorder::RecordDefragmentationBegin(uint32_t frameIndex, - const VmaDefragmentationInfo2& info, - VmaDefragmentationContext ctx) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaDefragmentationBegin,%u,", callParams.threadId, callParams.time, frameIndex, - info.flags); - PrintPointerList(info.allocationCount, info.pAllocations); - fprintf(m_File, ","); - PrintPointerList(info.poolCount, info.pPools); - fprintf(m_File, ",%llu,%u,%llu,%u,%p,%p\n", - info.maxCpuBytesToMove, - info.maxCpuAllocationsToMove, - info.maxGpuBytesToMove, - info.maxGpuAllocationsToMove, - info.commandBuffer, - ctx); - Flush(); -} - -void VmaRecorder::RecordDefragmentationEnd(uint32_t frameIndex, - VmaDefragmentationContext ctx) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaDefragmentationEnd,%p\n", callParams.threadId, callParams.time, frameIndex, - ctx); - Flush(); -} - -void VmaRecorder::RecordSetPoolName(uint32_t frameIndex, - VmaPool pool, - const char* name) -{ - CallParams callParams; - GetBasicParams(callParams); - - VmaMutexLock lock(m_FileMutex, m_UseMutex); - fprintf(m_File, "%u,%.3f,%u,vmaSetPoolName,%p,%s\n", callParams.threadId, callParams.time, frameIndex, - pool, name != VMA_NULL ? name : ""); - Flush(); -} - -VmaRecorder::UserDataString::UserDataString(VmaAllocationCreateFlags allocFlags, const void* pUserData) -{ - if(pUserData != VMA_NULL) - { - if((allocFlags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0) - { - m_Str = (const char*)pUserData; - } else { - // If VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT is not specified, convert the string's memory address to a string and store it. - snprintf(m_PtrStr, 17, "%p", pUserData); - m_Str = m_PtrStr; + switch (vectorState.operation) + { + case StateExtensive::Operation::FindFreeBlockBuffer: + vectorState.operation = StateExtensive::Operation::MoveBuffers; + break; + default: + VMA_ASSERT(0); + case StateExtensive::Operation::FindFreeBlockTexture: + vectorState.operation = StateExtensive::Operation::MoveTextures; + break; + case StateExtensive::Operation::FindFreeBlockAll: + vectorState.operation = StateExtensive::Operation::MoveAll; + break; + } + vectorState.firstFreeBlock = last; + // Nothing done, block found without reallocations, can perform another reallocs in same pass + return ComputeDefragmentation_Extensive(vector, index); } + break; + } + case StateExtensive::Operation::MoveTextures: + { + if (MoveDataToFreeBlocks(VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL, vector, + vectorState.firstFreeBlock, texturePresent, bufferPresent, otherPresent)) + { + if (texturePresent) + { + vectorState.operation = StateExtensive::Operation::FindFreeBlockTexture; + return ComputeDefragmentation_Extensive(vector, index); + } + + if (!bufferPresent && !otherPresent) + { + vectorState.operation = StateExtensive::Operation::Cleanup; + break; + } + + // No more textures to move, check buffers + vectorState.operation = StateExtensive::Operation::MoveBuffers; + bufferPresent = false; + otherPresent = false; + } + else + break; + } + case StateExtensive::Operation::MoveBuffers: + { + if (MoveDataToFreeBlocks(VMA_SUBALLOCATION_TYPE_BUFFER, vector, + vectorState.firstFreeBlock, texturePresent, bufferPresent, otherPresent)) + { + if (bufferPresent) + { + vectorState.operation = StateExtensive::Operation::FindFreeBlockBuffer; + return ComputeDefragmentation_Extensive(vector, index); + } + + if (!otherPresent) + { + vectorState.operation = StateExtensive::Operation::Cleanup; + break; + } + + // No more buffers to move, check all others + vectorState.operation = StateExtensive::Operation::MoveAll; + otherPresent = false; + } + else + break; + } + case StateExtensive::Operation::MoveAll: + { + if (MoveDataToFreeBlocks(VMA_SUBALLOCATION_TYPE_FREE, vector, + vectorState.firstFreeBlock, texturePresent, bufferPresent, otherPresent)) + { + if (otherPresent) + { + vectorState.operation = StateExtensive::Operation::FindFreeBlockBuffer; + return ComputeDefragmentation_Extensive(vector, index); + } + // Everything moved + vectorState.operation = StateExtensive::Operation::Cleanup; + } + break; + } + case StateExtensive::Operation::Cleanup: + // Cleanup is handled below so that other operations may reuse the cleanup code. This case is here to prevent the unhandled enum value warning (C4062). + break; + } + + if (vectorState.operation == StateExtensive::Operation::Cleanup) + { + // All other work done, pack data in blocks even tighter if possible + const size_t prevMoveCount = m_Moves.size(); + for (size_t i = 0; i < vector.GetBlockCount(); ++i) + { + if (ReallocWithinBlock(vector, vector.GetBlock(i))) + return true; + } + + if (prevMoveCount == m_Moves.size()) + vectorState.operation = StateExtensive::Operation::Done; + } + return false; +} + +void VmaDefragmentationContext_T::UpdateVectorStatistics(VmaBlockVector& vector, StateBalanced& state) +{ + size_t allocCount = 0; + size_t freeCount = 0; + state.avgFreeSize = 0; + state.avgAllocSize = 0; + + for (size_t i = 0; i < vector.GetBlockCount(); ++i) + { + VmaBlockMetadata* metadata = vector.GetBlock(i)->m_pMetadata; + + allocCount += metadata->GetAllocationCount(); + freeCount += metadata->GetFreeRegionsCount(); + state.avgFreeSize += metadata->GetSumFreeSize(); + state.avgAllocSize += metadata->GetSize(); + } + + state.avgAllocSize = (state.avgAllocSize - state.avgFreeSize) / allocCount; + state.avgFreeSize /= freeCount; +} + +bool VmaDefragmentationContext_T::MoveDataToFreeBlocks(VmaSuballocationType currentType, + VmaBlockVector& vector, size_t firstFreeBlock, + bool& texturePresent, bool& bufferPresent, bool& otherPresent) +{ + const size_t prevMoveCount = m_Moves.size(); + for (size_t i = firstFreeBlock ; i;) + { + VmaDeviceMemoryBlock* block = vector.GetBlock(--i); + VmaBlockMetadata* metadata = block->m_pMetadata; + + for (VmaAllocHandle handle = metadata->GetAllocationListBegin(); + handle != VK_NULL_HANDLE; + handle = metadata->GetNextAllocation(handle)) + { + MoveAllocationData moveData = GetMoveData(handle, metadata); + // Ignore newly created allocations by defragmentation algorithm + if (moveData.move.srcAllocation->GetUserData() == this) + continue; + switch (CheckCounters(moveData.move.srcAllocation->GetSize())) + { + case CounterStatus::Ignore: + continue; + case CounterStatus::End: + return true; + default: + VMA_ASSERT(0); + case CounterStatus::Pass: + break; + } + + // Move only single type of resources at once + if (!VmaIsBufferImageGranularityConflict(moveData.type, currentType)) + { + // Try to fit allocation into free blocks + if (AllocInOtherBlock(firstFreeBlock, vector.GetBlockCount(), moveData, vector)) + return false; + } + + if (!VmaIsBufferImageGranularityConflict(moveData.type, VMA_SUBALLOCATION_TYPE_IMAGE_OPTIMAL)) + texturePresent = true; + else if (!VmaIsBufferImageGranularityConflict(moveData.type, VMA_SUBALLOCATION_TYPE_BUFFER)) + bufferPresent = true; + else + otherPresent = true; + } + } + return prevMoveCount == m_Moves.size(); +} +#endif // _VMA_DEFRAGMENTATION_CONTEXT_FUNCTIONS + +#ifndef _VMA_POOL_T_FUNCTIONS +VmaPool_T::VmaPool_T( + VmaAllocator hAllocator, + const VmaPoolCreateInfo& createInfo, + VkDeviceSize preferredBlockSize) + : m_BlockVector( + hAllocator, + this, // hParentPool + createInfo.memoryTypeIndex, + createInfo.blockSize != 0 ? createInfo.blockSize : preferredBlockSize, + createInfo.minBlockCount, + createInfo.maxBlockCount, + (createInfo.flags& VMA_POOL_CREATE_IGNORE_BUFFER_IMAGE_GRANULARITY_BIT) != 0 ? 1 : hAllocator->GetBufferImageGranularity(), + createInfo.blockSize != 0, // explicitBlockSize + createInfo.flags & VMA_POOL_CREATE_ALGORITHM_MASK, // algorithm + createInfo.priority, + VMA_MAX(hAllocator->GetMemoryTypeMinAlignment(createInfo.memoryTypeIndex), createInfo.minAllocationAlignment), + createInfo.pMemoryAllocateNext), + m_Id(0), + m_Name(VMA_NULL) {} + +VmaPool_T::~VmaPool_T() +{ + VMA_ASSERT(m_PrevPool == VMA_NULL && m_NextPool == VMA_NULL); +} + +void VmaPool_T::SetName(const char* pName) +{ + const VkAllocationCallbacks* allocs = m_BlockVector.GetAllocator()->GetAllocationCallbacks(); + VmaFreeString(allocs, m_Name); + + if (pName != VMA_NULL) + { + m_Name = VmaCreateStringCopy(allocs, pName); } else { - m_Str = ""; + m_Name = VMA_NULL; } } +#endif // _VMA_POOL_T_FUNCTIONS -void VmaRecorder::WriteConfiguration( - const VkPhysicalDeviceProperties& devProps, - const VkPhysicalDeviceMemoryProperties& memProps, - uint32_t vulkanApiVersion, - bool dedicatedAllocationExtensionEnabled, - bool bindMemory2ExtensionEnabled, - bool memoryBudgetExtensionEnabled, - bool deviceCoherentMemoryExtensionEnabled) -{ - fprintf(m_File, "Config,Begin\n"); - - fprintf(m_File, "VulkanApiVersion,%u,%u\n", VK_VERSION_MAJOR(vulkanApiVersion), VK_VERSION_MINOR(vulkanApiVersion)); - - fprintf(m_File, "PhysicalDevice,apiVersion,%u\n", devProps.apiVersion); - fprintf(m_File, "PhysicalDevice,driverVersion,%u\n", devProps.driverVersion); - fprintf(m_File, "PhysicalDevice,vendorID,%u\n", devProps.vendorID); - fprintf(m_File, "PhysicalDevice,deviceID,%u\n", devProps.deviceID); - fprintf(m_File, "PhysicalDevice,deviceType,%u\n", devProps.deviceType); - fprintf(m_File, "PhysicalDevice,deviceName,%s\n", devProps.deviceName); - - fprintf(m_File, "PhysicalDeviceLimits,maxMemoryAllocationCount,%u\n", devProps.limits.maxMemoryAllocationCount); - fprintf(m_File, "PhysicalDeviceLimits,bufferImageGranularity,%llu\n", devProps.limits.bufferImageGranularity); - fprintf(m_File, "PhysicalDeviceLimits,nonCoherentAtomSize,%llu\n", devProps.limits.nonCoherentAtomSize); - - fprintf(m_File, "PhysicalDeviceMemory,HeapCount,%u\n", memProps.memoryHeapCount); - for(uint32_t i = 0; i < memProps.memoryHeapCount; ++i) - { - fprintf(m_File, "PhysicalDeviceMemory,Heap,%u,size,%llu\n", i, memProps.memoryHeaps[i].size); - fprintf(m_File, "PhysicalDeviceMemory,Heap,%u,flags,%u\n", i, memProps.memoryHeaps[i].flags); - } - fprintf(m_File, "PhysicalDeviceMemory,TypeCount,%u\n", memProps.memoryTypeCount); - for(uint32_t i = 0; i < memProps.memoryTypeCount; ++i) - { - fprintf(m_File, "PhysicalDeviceMemory,Type,%u,heapIndex,%u\n", i, memProps.memoryTypes[i].heapIndex); - fprintf(m_File, "PhysicalDeviceMemory,Type,%u,propertyFlags,%u\n", i, memProps.memoryTypes[i].propertyFlags); - } - - fprintf(m_File, "Extension,VK_KHR_dedicated_allocation,%u\n", dedicatedAllocationExtensionEnabled ? 1 : 0); - fprintf(m_File, "Extension,VK_KHR_bind_memory2,%u\n", bindMemory2ExtensionEnabled ? 1 : 0); - fprintf(m_File, "Extension,VK_EXT_memory_budget,%u\n", memoryBudgetExtensionEnabled ? 1 : 0); - fprintf(m_File, "Extension,VK_AMD_device_coherent_memory,%u\n", deviceCoherentMemoryExtensionEnabled ? 1 : 0); - - fprintf(m_File, "Macro,VMA_DEBUG_ALWAYS_DEDICATED_MEMORY,%u\n", VMA_DEBUG_ALWAYS_DEDICATED_MEMORY ? 1 : 0); - fprintf(m_File, "Macro,VMA_MIN_ALIGNMENT,%llu\n", (VkDeviceSize)VMA_MIN_ALIGNMENT); - fprintf(m_File, "Macro,VMA_DEBUG_MARGIN,%llu\n", (VkDeviceSize)VMA_DEBUG_MARGIN); - fprintf(m_File, "Macro,VMA_DEBUG_INITIALIZE_ALLOCATIONS,%u\n", VMA_DEBUG_INITIALIZE_ALLOCATIONS ? 1 : 0); - fprintf(m_File, "Macro,VMA_DEBUG_DETECT_CORRUPTION,%u\n", VMA_DEBUG_DETECT_CORRUPTION ? 1 : 0); - fprintf(m_File, "Macro,VMA_DEBUG_GLOBAL_MUTEX,%u\n", VMA_DEBUG_GLOBAL_MUTEX ? 1 : 0); - fprintf(m_File, "Macro,VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY,%llu\n", (VkDeviceSize)VMA_DEBUG_MIN_BUFFER_IMAGE_GRANULARITY); - fprintf(m_File, "Macro,VMA_SMALL_HEAP_MAX_SIZE,%llu\n", (VkDeviceSize)VMA_SMALL_HEAP_MAX_SIZE); - fprintf(m_File, "Macro,VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE,%llu\n", (VkDeviceSize)VMA_DEFAULT_LARGE_HEAP_BLOCK_SIZE); - - fprintf(m_File, "Config,End\n"); -} - -void VmaRecorder::GetBasicParams(CallParams& outParams) -{ - #if defined(_WIN32) - outParams.threadId = GetCurrentThreadId(); - #else - // Use C++11 features to get thread id and convert it to uint32_t. - // There is room for optimization since sstream is quite slow. - // Is there a better way to convert std::this_thread::get_id() to uint32_t? - std::thread::id thread_id = std::this_thread::get_id(); - std::stringstream thread_id_to_string_converter; - thread_id_to_string_converter << thread_id; - std::string thread_id_as_string = thread_id_to_string_converter.str(); - outParams.threadId = static_cast(std::stoi(thread_id_as_string.c_str())); - #endif - - auto current_time = std::chrono::high_resolution_clock::now(); - - outParams.time = std::chrono::duration(current_time - m_RecordingStartTime).count(); -} - -void VmaRecorder::PrintPointerList(uint64_t count, const VmaAllocation* pItems) -{ - if(count) - { - fprintf(m_File, "%p", pItems[0]); - for(uint64_t i = 1; i < count; ++i) - { - fprintf(m_File, " %p", pItems[i]); - } - } -} - -void VmaRecorder::Flush() -{ - if((m_Flags & VMA_RECORD_FLUSH_AFTER_CALL_BIT) != 0) - { - fflush(m_File); - } -} - -#endif // #if VMA_RECORDING_ENABLED - -//////////////////////////////////////////////////////////////////////////////// -// VmaAllocationObjectAllocator - -VmaAllocationObjectAllocator::VmaAllocationObjectAllocator(const VkAllocationCallbacks* pAllocationCallbacks) : - m_Allocator(pAllocationCallbacks, 1024) -{ -} - -template VmaAllocation VmaAllocationObjectAllocator::Allocate(Types&&... args) -{ - VmaMutexLock mutexLock(m_Mutex); - return m_Allocator.Alloc(std::forward(args)...); -} - -void VmaAllocationObjectAllocator::Free(VmaAllocation hAlloc) -{ - VmaMutexLock mutexLock(m_Mutex); - m_Allocator.Free(hAlloc); -} - -//////////////////////////////////////////////////////////////////////////////// -// VmaAllocator_T - +#ifndef _VMA_ALLOCATOR_T_FUNCTIONS VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) : m_UseMutex((pCreateInfo->flags & VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT) == 0), m_VulkanApiVersion(pCreateInfo->vulkanApiVersion != 0 ? pCreateInfo->vulkanApiVersion : VK_API_VERSION_1_0), @@ -14196,13 +13985,9 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) : m_DeviceMemoryCount(0), m_PreferredLargeHeapBlockSize(0), m_PhysicalDevice(pCreateInfo->physicalDevice), - m_CurrentFrameIndex(0), m_GpuDefragmentationMemoryTypeBits(UINT32_MAX), m_NextPoolId(0), m_GlobalMemoryTypeBits(UINT32_MAX) -#if VMA_RECORDING_ENABLED - ,m_pRecorder(VMA_NULL) -#endif { if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) { @@ -14323,24 +14108,26 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) : for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) { - const VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(memTypeIndex); - - m_pBlockVectors[memTypeIndex] = vma_new(this, VmaBlockVector)( - this, - VK_NULL_HANDLE, // hParentPool - memTypeIndex, - preferredBlockSize, - 0, - SIZE_MAX, - GetBufferImageGranularity(), - pCreateInfo->frameInUseCount, - false, // explicitBlockSize - false, // linearAlgorithm - 0.5f, // priority (0.5 is the default per Vulkan spec) - GetMemoryTypeMinAlignment(memTypeIndex), // minAllocationAlignment - VMA_NULL); // // pMemoryAllocateNext - // No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]->CreateMinBlocks here, - // becase minBlockCount is 0. + // Create only supported types + if((m_GlobalMemoryTypeBits & (1u << memTypeIndex)) != 0) + { + const VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(memTypeIndex); + m_pBlockVectors[memTypeIndex] = vma_new(this, VmaBlockVector)( + this, + VK_NULL_HANDLE, // hParentPool + memTypeIndex, + preferredBlockSize, + 0, + SIZE_MAX, + GetBufferImageGranularity(), + false, // explicitBlockSize + 0, // algorithm + 0.5f, // priority (0.5 is the default per Vulkan spec) + GetMemoryTypeMinAlignment(memTypeIndex), // minAllocationAlignment + VMA_NULL); // // pMemoryAllocateNext + // No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]->CreateMinBlocks here, + // becase minBlockCount is 0. + } } } @@ -14348,31 +14135,6 @@ VkResult VmaAllocator_T::Init(const VmaAllocatorCreateInfo* pCreateInfo) { VkResult res = VK_SUCCESS; - if(pCreateInfo->pRecordSettings != VMA_NULL && - !VmaStrIsEmpty(pCreateInfo->pRecordSettings->pFilePath)) - { -#if VMA_RECORDING_ENABLED - m_pRecorder = vma_new(this, VmaRecorder)(); - res = m_pRecorder->Init(*pCreateInfo->pRecordSettings, m_UseMutex); - if(res != VK_SUCCESS) - { - return res; - } - m_pRecorder->WriteConfiguration( - m_PhysicalDeviceProperties, - m_MemProps, - m_VulkanApiVersion, - m_UseKhrDedicatedAllocation, - m_UseKhrBindMemory2, - m_UseExtMemoryBudget, - m_UseAmdDeviceCoherentMemory); - m_pRecorder->RecordCreateAllocator(GetCurrentFrameIndex()); -#else - VMA_ASSERT(0 && "VmaAllocatorCreateInfo::pRecordSettings used, but not supported due to VMA_RECORDING_ENABLED not defined to 1."); - return VK_ERROR_FEATURE_NOT_PRESENT; -#endif - } - #if VMA_MEMORY_BUDGET if(m_UseExtMemoryBudget) { @@ -14385,23 +14147,10 @@ VkResult VmaAllocator_T::Init(const VmaAllocatorCreateInfo* pCreateInfo) VmaAllocator_T::~VmaAllocator_T() { -#if VMA_RECORDING_ENABLED - if(m_pRecorder != VMA_NULL) - { - m_pRecorder->RecordDestroyAllocator(GetCurrentFrameIndex()); - vma_delete(this, m_pRecorder); - } -#endif - VMA_ASSERT(m_Pools.IsEmpty()); for(size_t memTypeIndex = GetMemoryTypeCount(); memTypeIndex--; ) { - if(!m_DedicatedAllocations[memTypeIndex].IsEmpty()) - { - VMA_ASSERT(0 && "Unfreed dedicated allocations found."); - } - vma_delete(this, m_pBlockVectors[memTypeIndex]); } } @@ -14429,6 +14178,8 @@ void VmaAllocator_T::ImportVulkanFunctions(const VmaVulkanFunctions* pVulkanFunc void VmaAllocator_T::ImportVulkanFunctions_Static() { // Vulkan 1.0 + m_VulkanFunctions.vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)vkGetInstanceProcAddr; + m_VulkanFunctions.vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)vkGetDeviceProcAddr; m_VulkanFunctions.vkGetPhysicalDeviceProperties = (PFN_vkGetPhysicalDeviceProperties)vkGetPhysicalDeviceProperties; m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties = (PFN_vkGetPhysicalDeviceMemoryProperties)vkGetPhysicalDeviceMemoryProperties; m_VulkanFunctions.vkAllocateMemory = (PFN_vkAllocateMemory)vkAllocateMemory; @@ -14458,9 +14209,17 @@ void VmaAllocator_T::ImportVulkanFunctions_Static() m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR = (PFN_vkGetPhysicalDeviceMemoryProperties2)vkGetPhysicalDeviceMemoryProperties2; } #endif + +#if VMA_VULKAN_VERSION >= 1003000 + if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0)) + { + m_VulkanFunctions.vkGetDeviceBufferMemoryRequirements = (PFN_vkGetDeviceBufferMemoryRequirements)vkGetDeviceBufferMemoryRequirements; + m_VulkanFunctions.vkGetDeviceImageMemoryRequirements = (PFN_vkGetDeviceImageMemoryRequirements)vkGetDeviceImageMemoryRequirements; + } +#endif } -#endif // #if VMA_STATIC_VULKAN_FUNCTIONS == 1 +#endif // VMA_STATIC_VULKAN_FUNCTIONS == 1 void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVulkanFunctions) { @@ -14469,6 +14228,8 @@ void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVul #define VMA_COPY_IF_NOT_NULL(funcName) \ if(pVulkanFunctions->funcName != VMA_NULL) m_VulkanFunctions.funcName = pVulkanFunctions->funcName; + VMA_COPY_IF_NOT_NULL(vkGetInstanceProcAddr); + VMA_COPY_IF_NOT_NULL(vkGetDeviceProcAddr); VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceProperties); VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties); VMA_COPY_IF_NOT_NULL(vkAllocateMemory); @@ -14501,6 +14262,11 @@ void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVul VMA_COPY_IF_NOT_NULL(vkGetPhysicalDeviceMemoryProperties2KHR); #endif +#if VMA_VULKAN_VERSION >= 1003000 + VMA_COPY_IF_NOT_NULL(vkGetDeviceBufferMemoryRequirements); + VMA_COPY_IF_NOT_NULL(vkGetDeviceImageMemoryRequirements); +#endif + #undef VMA_COPY_IF_NOT_NULL } @@ -14508,14 +14274,19 @@ void VmaAllocator_T::ImportVulkanFunctions_Custom(const VmaVulkanFunctions* pVul void VmaAllocator_T::ImportVulkanFunctions_Dynamic() { + VMA_ASSERT(m_VulkanFunctions.vkGetInstanceProcAddr && m_VulkanFunctions.vkGetDeviceProcAddr && + "To use VMA_DYNAMIC_VULKAN_FUNCTIONS in new versions of VMA you now have to pass " + "VmaVulkanFunctions::vkGetInstanceProcAddr and vkGetDeviceProcAddr as VmaAllocatorCreateInfo::pVulkanFunctions. " + "Other members can be null."); + #define VMA_FETCH_INSTANCE_FUNC(memberName, functionPointerType, functionNameString) \ if(m_VulkanFunctions.memberName == VMA_NULL) \ m_VulkanFunctions.memberName = \ - (functionPointerType)vkGetInstanceProcAddr(m_hInstance, functionNameString); + (functionPointerType)m_VulkanFunctions.vkGetInstanceProcAddr(m_hInstance, functionNameString); #define VMA_FETCH_DEVICE_FUNC(memberName, functionPointerType, functionNameString) \ if(m_VulkanFunctions.memberName == VMA_NULL) \ m_VulkanFunctions.memberName = \ - (functionPointerType)vkGetDeviceProcAddr(m_hDevice, functionNameString); + (functionPointerType)m_VulkanFunctions.vkGetDeviceProcAddr(m_hDevice, functionNameString); VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceProperties, PFN_vkGetPhysicalDeviceProperties, "vkGetPhysicalDeviceProperties"); VMA_FETCH_INSTANCE_FUNC(vkGetPhysicalDeviceMemoryProperties, PFN_vkGetPhysicalDeviceMemoryProperties, "vkGetPhysicalDeviceMemoryProperties"); @@ -14569,11 +14340,19 @@ void VmaAllocator_T::ImportVulkanFunctions_Dynamic() } #endif // #if VMA_MEMORY_BUDGET +#if VMA_VULKAN_VERSION >= 1003000 + if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0)) + { + VMA_FETCH_DEVICE_FUNC(vkGetDeviceBufferMemoryRequirements, PFN_vkGetDeviceBufferMemoryRequirements, "vkGetDeviceBufferMemoryRequirements"); + VMA_FETCH_DEVICE_FUNC(vkGetDeviceImageMemoryRequirements, PFN_vkGetDeviceImageMemoryRequirements, "vkGetDeviceImageMemoryRequirements"); + } +#endif + #undef VMA_FETCH_DEVICE_FUNC #undef VMA_FETCH_INSTANCE_FUNC } -#endif // #if VMA_DYNAMIC_VULKAN_FUNCTIONS == 1 +#endif // VMA_DYNAMIC_VULKAN_FUNCTIONS == 1 void VmaAllocator_T::ValidateVulkanFunctions() { @@ -14617,6 +14396,14 @@ void VmaAllocator_T::ValidateVulkanFunctions() VMA_ASSERT(m_VulkanFunctions.vkGetPhysicalDeviceMemoryProperties2KHR != VMA_NULL); } #endif + +#if VMA_VULKAN_VERSION >= 1003000 + if(m_VulkanApiVersion >= VK_MAKE_VERSION(1, 3, 0)) + { + VMA_ASSERT(m_VulkanFunctions.vkGetDeviceBufferMemoryRequirements != VMA_NULL); + VMA_ASSERT(m_VulkanFunctions.vkGetDeviceImageMemoryRequirements != VMA_NULL); + } +#endif } VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex) @@ -14628,15 +14415,18 @@ VkDeviceSize VmaAllocator_T::CalcPreferredBlockSize(uint32_t memTypeIndex) } VkResult VmaAllocator_T::AllocateMemoryOfType( + VmaPool pool, VkDeviceSize size, VkDeviceSize alignment, - bool dedicatedAllocation, + bool dedicatedPreferred, VkBuffer dedicatedBuffer, - VkBufferUsageFlags dedicatedBufferUsage, VkImage dedicatedImage, + VkFlags dedicatedBufferImageUsage, const VmaAllocationCreateInfo& createInfo, uint32_t memTypeIndex, VmaSuballocationType suballocType, + VmaDedicatedAllocationList& dedicatedAllocations, + VmaBlockVector& blockVector, size_t allocationCount, VmaAllocation* pAllocations) { @@ -14644,64 +14434,88 @@ VkResult VmaAllocator_T::AllocateMemoryOfType( VMA_DEBUG_LOG(" AllocateMemory: MemoryTypeIndex=%u, AllocationCount=%zu, Size=%llu", memTypeIndex, allocationCount, size); VmaAllocationCreateInfo finalCreateInfo = createInfo; - - // If memory type is not HOST_VISIBLE, disable MAPPED. - if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0 && - (m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) - { - finalCreateInfo.flags &= ~VMA_ALLOCATION_CREATE_MAPPED_BIT; - } - // If memory is lazily allocated, it should be always dedicated. - if(finalCreateInfo.usage == VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED) - { - finalCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; - } - - VmaBlockVector* const blockVector = m_pBlockVectors[memTypeIndex]; - VMA_ASSERT(blockVector); - - const VkDeviceSize preferredBlockSize = blockVector->GetPreferredBlockSize(); - bool preferDedicatedMemory = - VMA_DEBUG_ALWAYS_DEDICATED_MEMORY || - dedicatedAllocation || - // Heuristics: Allocate dedicated memory if requested size if greater than half of preferred block size. - size > preferredBlockSize / 2; - - if(preferDedicatedMemory && - (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0 && - finalCreateInfo.pool == VK_NULL_HANDLE) - { - finalCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; - } + VkResult res = CalcMemTypeParams( + finalCreateInfo, + memTypeIndex, + size, + allocationCount); + if(res != VK_SUCCESS) + return res; if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0) { - if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0) - { - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - else - { - return AllocateDedicatedMemory( - size, - suballocType, - memTypeIndex, - (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT) != 0, - (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0, - (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0, - finalCreateInfo.pUserData, - finalCreateInfo.priority, - dedicatedBuffer, - dedicatedBufferUsage, - dedicatedImage, - allocationCount, - pAllocations); - } + return AllocateDedicatedMemory( + pool, + size, + suballocType, + dedicatedAllocations, + memTypeIndex, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0, + (finalCreateInfo.flags & + (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT) != 0, + finalCreateInfo.pUserData, + finalCreateInfo.priority, + dedicatedBuffer, + dedicatedImage, + dedicatedBufferImageUsage, + allocationCount, + pAllocations, + blockVector.GetAllocationNextPtr()); } else { - VkResult res = blockVector->Allocate( - m_CurrentFrameIndex.load(), + const bool canAllocateDedicated = + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) == 0 && + (pool == VK_NULL_HANDLE || !blockVector.HasExplicitBlockSize()); + + if(canAllocateDedicated) + { + // Heuristics: Allocate dedicated memory if requested size if greater than half of preferred block size. + if(size > blockVector.GetPreferredBlockSize() / 2) + { + dedicatedPreferred = true; + } + // Protection against creating each allocation as dedicated when we reach or exceed heap size/budget, + // which can quickly deplete maxMemoryAllocationCount: Don't prefer dedicated allocations when above + // 3/4 of the maximum allocation count. + if(m_DeviceMemoryCount.load() > m_PhysicalDeviceProperties.limits.maxMemoryAllocationCount * 3 / 4) + { + dedicatedPreferred = false; + } + + if(dedicatedPreferred) + { + res = AllocateDedicatedMemory( + pool, + size, + suballocType, + dedicatedAllocations, + memTypeIndex, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0, + (finalCreateInfo.flags & + (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT) != 0, + finalCreateInfo.pUserData, + finalCreateInfo.priority, + dedicatedBuffer, + dedicatedImage, + dedicatedBufferImageUsage, + allocationCount, + pAllocations, + blockVector.GetAllocationNextPtr()); + if(res == VK_SUCCESS) + { + // Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here. + VMA_DEBUG_LOG(" Allocated as DedicatedMemory"); + return VK_SUCCESS; + } + } + } + + res = blockVector.Allocate( size, alignment, finalCreateInfo, @@ -14709,99 +14523,86 @@ VkResult VmaAllocator_T::AllocateMemoryOfType( allocationCount, pAllocations); if(res == VK_SUCCESS) - { - return res; - } - - // 5. Try dedicated memory. - if((finalCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0) - { - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - - // Protection against creating each allocation as dedicated when we reach or exceed heap size/budget, - // which can quickly deplete maxMemoryAllocationCount: Don't try dedicated allocations when above - // 3/4 of the maximum allocation count. - if(m_DeviceMemoryCount.load() > m_PhysicalDeviceProperties.limits.maxMemoryAllocationCount * 3 / 4) - { - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - - res = AllocateDedicatedMemory( - size, - suballocType, - memTypeIndex, - (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT) != 0, - (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0, - (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0, - finalCreateInfo.pUserData, - finalCreateInfo.priority, - dedicatedBuffer, - dedicatedBufferUsage, - dedicatedImage, - allocationCount, - pAllocations); - if(res == VK_SUCCESS) - { - // Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here. - VMA_DEBUG_LOG(" Allocated as DedicatedMemory"); return VK_SUCCESS; - } - else + + // Try dedicated memory. + if(canAllocateDedicated && !dedicatedPreferred) { - // Everything failed: Return error code. - VMA_DEBUG_LOG(" vkAllocateMemory FAILED"); - return res; + res = AllocateDedicatedMemory( + pool, + size, + suballocType, + dedicatedAllocations, + memTypeIndex, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT) != 0, + (finalCreateInfo.flags & + (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0, + (finalCreateInfo.flags & VMA_ALLOCATION_CREATE_CAN_ALIAS_BIT) != 0, + finalCreateInfo.pUserData, + finalCreateInfo.priority, + dedicatedBuffer, + dedicatedImage, + dedicatedBufferImageUsage, + allocationCount, + pAllocations, + blockVector.GetAllocationNextPtr()); + if(res == VK_SUCCESS) + { + // Succeeded: AllocateDedicatedMemory function already filld pMemory, nothing more to do here. + VMA_DEBUG_LOG(" Allocated as DedicatedMemory"); + return VK_SUCCESS; + } } + // Everything failed: Return error code. + VMA_DEBUG_LOG(" vkAllocateMemory FAILED"); + return res; } } VkResult VmaAllocator_T::AllocateDedicatedMemory( + VmaPool pool, VkDeviceSize size, VmaSuballocationType suballocType, + VmaDedicatedAllocationList& dedicatedAllocations, uint32_t memTypeIndex, - bool withinBudget, bool map, bool isUserDataString, + bool isMappingAllowed, + bool canAliasMemory, void* pUserData, float priority, VkBuffer dedicatedBuffer, - VkBufferUsageFlags dedicatedBufferUsage, VkImage dedicatedImage, + VkFlags dedicatedBufferImageUsage, size_t allocationCount, - VmaAllocation* pAllocations) + VmaAllocation* pAllocations, + const void* pNextChain) { VMA_ASSERT(allocationCount > 0 && pAllocations); - if(withinBudget) - { - const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex); - VmaBudget heapBudget = {}; - GetBudget(&heapBudget, heapIndex, 1); - if(heapBudget.usage + size * allocationCount > heapBudget.budget) - { - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - } - VkMemoryAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; allocInfo.memoryTypeIndex = memTypeIndex; allocInfo.allocationSize = size; + allocInfo.pNext = pNextChain; #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 VkMemoryDedicatedAllocateInfoKHR dedicatedAllocInfo = { VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR }; - if(m_UseKhrDedicatedAllocation || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) + if(!canAliasMemory) { - if(dedicatedBuffer != VK_NULL_HANDLE) + if(m_UseKhrDedicatedAllocation || m_VulkanApiVersion >= VK_MAKE_VERSION(1, 1, 0)) { - VMA_ASSERT(dedicatedImage == VK_NULL_HANDLE); - dedicatedAllocInfo.buffer = dedicatedBuffer; - VmaPnextChainPushFront(&allocInfo, &dedicatedAllocInfo); - } - else if(dedicatedImage != VK_NULL_HANDLE) - { - dedicatedAllocInfo.image = dedicatedImage; - VmaPnextChainPushFront(&allocInfo, &dedicatedAllocInfo); + if(dedicatedBuffer != VK_NULL_HANDLE) + { + VMA_ASSERT(dedicatedImage == VK_NULL_HANDLE); + dedicatedAllocInfo.buffer = dedicatedBuffer; + VmaPnextChainPushFront(&allocInfo, &dedicatedAllocInfo); + } + else if(dedicatedImage != VK_NULL_HANDLE) + { + dedicatedAllocInfo.image = dedicatedImage; + VmaPnextChainPushFront(&allocInfo, &dedicatedAllocInfo); + } } } #endif // #if VMA_DEDICATED_ALLOCATION || VMA_VULKAN_VERSION >= 1001000 @@ -14813,8 +14614,8 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory( bool canContainBufferWithDeviceAddress = true; if(dedicatedBuffer != VK_NULL_HANDLE) { - canContainBufferWithDeviceAddress = dedicatedBufferUsage == UINT32_MAX || // Usage flags unknown - (dedicatedBufferUsage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT) != 0; + canContainBufferWithDeviceAddress = dedicatedBufferImageUsage == UINT32_MAX || // Usage flags unknown + (dedicatedBufferImageUsage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT) != 0; } else if(dedicatedImage != VK_NULL_HANDLE) { @@ -14832,6 +14633,7 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory( VkMemoryPriorityAllocateInfoEXT priorityInfo = { VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT }; if(m_UseExtMemoryPriority) { + VMA_ASSERT(priority >= 0.f && priority <= 1.f); priorityInfo.priority = priority; VmaPnextChainPushFront(&allocInfo, &priorityInfo); } @@ -14852,12 +14654,14 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory( for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex) { res = AllocateDedicatedMemoryPage( + pool, size, suballocType, memTypeIndex, allocInfo, map, isUserDataString, + isMappingAllowed, pUserData, pAllocations + allocIndex); if(res != VK_SUCCESS) @@ -14868,16 +14672,10 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory( if(res == VK_SUCCESS) { - // Register them in m_DedicatedAllocations. + for (allocIndex = 0; allocIndex < allocationCount; ++allocIndex) { - VmaMutexLockWrite lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); - DedicatedAllocationLinkedList& dedicatedAllocations = m_DedicatedAllocations[memTypeIndex]; - for(allocIndex = 0; allocIndex < allocationCount; ++allocIndex) - { - dedicatedAllocations.PushBack(pAllocations[allocIndex]); - } + dedicatedAllocations.Register(pAllocations[allocIndex]); } - VMA_DEBUG_LOG(" Allocated DedicatedMemory Count=%zu, MemoryTypeIndex=#%u", allocationCount, memTypeIndex); } else @@ -14900,7 +14698,6 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory( FreeVulkanMemory(memTypeIndex, currAlloc->GetSize(), hMemory); m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(memTypeIndex), currAlloc->GetSize()); - currAlloc->SetUserData(this, VMA_NULL); m_AllocationObjectAllocator.Free(currAlloc); } @@ -14911,12 +14708,14 @@ VkResult VmaAllocator_T::AllocateDedicatedMemory( } VkResult VmaAllocator_T::AllocateDedicatedMemoryPage( + VmaPool pool, VkDeviceSize size, VmaSuballocationType suballocType, uint32_t memTypeIndex, const VkMemoryAllocateInfo& allocInfo, bool map, bool isUserDataString, + bool isMappingAllowed, void* pUserData, VmaAllocation* pAllocation) { @@ -14946,9 +14745,12 @@ VkResult VmaAllocator_T::AllocateDedicatedMemoryPage( } } - *pAllocation = m_AllocationObjectAllocator.Allocate(m_CurrentFrameIndex.load(), isUserDataString); - (*pAllocation)->InitDedicatedAllocation(memTypeIndex, hMemory, suballocType, pMappedData, size); - (*pAllocation)->SetUserData(this, pUserData); + *pAllocation = m_AllocationObjectAllocator.Allocate(isMappingAllowed); + (*pAllocation)->InitDedicatedAllocation(pool, memTypeIndex, hMemory, suballocType, pMappedData, size); + if (isUserDataString) + (*pAllocation)->SetName(this, (const char*)pUserData); + else + (*pAllocation)->SetUserData(this, pUserData); m_Budget.AddAllocation(MemoryTypeIndexToHeapIndex(memTypeIndex), size); if(VMA_DEBUG_INITIALIZE_ALLOCATIONS) { @@ -15022,13 +14824,165 @@ void VmaAllocator_T::GetImageMemoryRequirements( } } +VkResult VmaAllocator_T::FindMemoryTypeIndex( + uint32_t memoryTypeBits, + const VmaAllocationCreateInfo* pAllocationCreateInfo, + VkFlags bufImgUsage, + uint32_t* pMemoryTypeIndex) const +{ + memoryTypeBits &= GetGlobalMemoryTypeBits(); + + if(pAllocationCreateInfo->memoryTypeBits != 0) + { + memoryTypeBits &= pAllocationCreateInfo->memoryTypeBits; + } + + VkMemoryPropertyFlags requiredFlags = 0, preferredFlags = 0, notPreferredFlags = 0; + if(!FindMemoryPreferences( + IsIntegratedGpu(), + *pAllocationCreateInfo, + bufImgUsage, + requiredFlags, preferredFlags, notPreferredFlags)) + { + return VK_ERROR_FEATURE_NOT_PRESENT; + } + + *pMemoryTypeIndex = UINT32_MAX; + uint32_t minCost = UINT32_MAX; + for(uint32_t memTypeIndex = 0, memTypeBit = 1; + memTypeIndex < GetMemoryTypeCount(); + ++memTypeIndex, memTypeBit <<= 1) + { + // This memory type is acceptable according to memoryTypeBits bitmask. + if((memTypeBit & memoryTypeBits) != 0) + { + const VkMemoryPropertyFlags currFlags = + m_MemProps.memoryTypes[memTypeIndex].propertyFlags; + // This memory type contains requiredFlags. + if((requiredFlags & ~currFlags) == 0) + { + // Calculate cost as number of bits from preferredFlags not present in this memory type. + uint32_t currCost = VMA_COUNT_BITS_SET(preferredFlags & ~currFlags) + + VMA_COUNT_BITS_SET(currFlags & notPreferredFlags); + // Remember memory type with lowest cost. + if(currCost < minCost) + { + *pMemoryTypeIndex = memTypeIndex; + if(currCost == 0) + { + return VK_SUCCESS; + } + minCost = currCost; + } + } + } + } + return (*pMemoryTypeIndex != UINT32_MAX) ? VK_SUCCESS : VK_ERROR_FEATURE_NOT_PRESENT; +} + +VkResult VmaAllocator_T::CalcMemTypeParams( + VmaAllocationCreateInfo& inoutCreateInfo, + uint32_t memTypeIndex, + VkDeviceSize size, + size_t allocationCount) +{ + // If memory type is not HOST_VISIBLE, disable MAPPED. + if((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0 && + (m_MemProps.memoryTypes[memTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) + { + inoutCreateInfo.flags &= ~VMA_ALLOCATION_CREATE_MAPPED_BIT; + } + + if((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0 && + (inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT) != 0) + { + const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex); + VmaBudget heapBudget = {}; + GetHeapBudgets(&heapBudget, heapIndex, 1); + if(heapBudget.usage + size * allocationCount > heapBudget.budget) + { + return VK_ERROR_OUT_OF_DEVICE_MEMORY; + } + } + return VK_SUCCESS; +} + +VkResult VmaAllocator_T::CalcAllocationParams( + VmaAllocationCreateInfo& inoutCreateInfo, + bool dedicatedRequired, + bool dedicatedPreferred) +{ + VMA_ASSERT((inoutCreateInfo.flags & + (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != + (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT) && + "Specifying both flags VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT and VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT is incorrect."); + VMA_ASSERT((((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT) == 0 || + (inoutCreateInfo.flags & (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0)) && + "Specifying VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT requires also VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT."); + if(inoutCreateInfo.usage == VMA_MEMORY_USAGE_AUTO || inoutCreateInfo.usage == VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE || inoutCreateInfo.usage == VMA_MEMORY_USAGE_AUTO_PREFER_HOST) + { + if((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0) + { + VMA_ASSERT((inoutCreateInfo.flags & (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) != 0 && + "When using VMA_ALLOCATION_CREATE_MAPPED_BIT and usage = VMA_MEMORY_USAGE_AUTO*, you must also specify VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT."); + } + } + + // If memory is lazily allocated, it should be always dedicated. + if(dedicatedRequired || + inoutCreateInfo.usage == VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED) + { + inoutCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + } + + if(inoutCreateInfo.pool != VK_NULL_HANDLE) + { + if(inoutCreateInfo.pool->m_BlockVector.HasExplicitBlockSize() && + (inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0) + { + VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT while current custom pool doesn't support dedicated allocations."); + return VK_ERROR_FEATURE_NOT_PRESENT; + } + inoutCreateInfo.priority = inoutCreateInfo.pool->m_BlockVector.GetPriority(); + } + + if((inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0 && + (inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0) + { + VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT together with VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT makes no sense."); + return VK_ERROR_FEATURE_NOT_PRESENT; + } + + if(VMA_DEBUG_ALWAYS_DEDICATED_MEMORY && + (inoutCreateInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0) + { + inoutCreateInfo.flags |= VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + } + + // Non-auto USAGE values imply HOST_ACCESS flags. + // And so does VMA_MEMORY_USAGE_UNKNOWN because it is used with custom pools. + // Which specific flag is used doesn't matter. They change things only when used with VMA_MEMORY_USAGE_AUTO*. + // Otherwise they just protect from assert on mapping. + if(inoutCreateInfo.usage != VMA_MEMORY_USAGE_AUTO && + inoutCreateInfo.usage != VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE && + inoutCreateInfo.usage != VMA_MEMORY_USAGE_AUTO_PREFER_HOST) + { + if((inoutCreateInfo.flags & (VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT)) == 0) + { + inoutCreateInfo.flags |= VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; + } + } + + return VK_SUCCESS; +} + VkResult VmaAllocator_T::AllocateMemory( const VkMemoryRequirements& vkMemReq, bool requiresDedicatedAllocation, bool prefersDedicatedAllocation, VkBuffer dedicatedBuffer, - VkBufferUsageFlags dedicatedBufferUsage, VkImage dedicatedImage, + VkFlags dedicatedBufferImageUsage, const VmaAllocationCreateInfo& createInfo, VmaSuballocationType suballocType, size_t allocationCount, @@ -15042,54 +14996,28 @@ VkResult VmaAllocator_T::AllocateMemory( { return VK_ERROR_INITIALIZATION_FAILED; } - if((createInfo.flags & VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT) != 0 && - (createInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0) - { - VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT together with VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT makes no sense."); - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - if((createInfo.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0 && - (createInfo.flags & VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT) != 0) - { - VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_MAPPED_BIT together with VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT is invalid."); - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - if(requiresDedicatedAllocation) - { - if((createInfo.flags & VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT) != 0) - { - VMA_ASSERT(0 && "VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT specified while dedicated allocation is required."); - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - if(createInfo.pool != VK_NULL_HANDLE) - { - VMA_ASSERT(0 && "Pool specified while dedicated allocation is required."); - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - } - if((createInfo.pool != VK_NULL_HANDLE) && - ((createInfo.flags & (VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT)) != 0)) - { - VMA_ASSERT(0 && "Specifying VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT when pool != null is invalid."); - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - if(createInfo.pool != VK_NULL_HANDLE) - { - VmaAllocationCreateInfo createInfoForPool = createInfo; - // If memory type is not HOST_VISIBLE, disable MAPPED. - if((createInfoForPool.flags & VMA_ALLOCATION_CREATE_MAPPED_BIT) != 0 && - (m_MemProps.memoryTypes[createInfo.pool->m_BlockVector.GetMemoryTypeIndex()].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) - { - createInfoForPool.flags &= ~VMA_ALLOCATION_CREATE_MAPPED_BIT; - } + VmaAllocationCreateInfo createInfoFinal = createInfo; + VkResult res = CalcAllocationParams(createInfoFinal, requiresDedicatedAllocation, prefersDedicatedAllocation); + if(res != VK_SUCCESS) + return res; - return createInfo.pool->m_BlockVector.Allocate( - m_CurrentFrameIndex.load(), + if(createInfoFinal.pool != VK_NULL_HANDLE) + { + VmaBlockVector& blockVector = createInfoFinal.pool->m_BlockVector; + return AllocateMemoryOfType( + createInfoFinal.pool, vkMemReq.size, vkMemReq.alignment, - createInfoForPool, + prefersDedicatedAllocation, + dedicatedBuffer, + dedicatedImage, + dedicatedBufferImageUsage, + createInfoFinal, + blockVector.GetMemoryTypeIndex(), suballocType, + createInfoFinal.pool->m_DedicatedAllocations, + blockVector, allocationCount, pAllocations); } @@ -15098,68 +15026,42 @@ VkResult VmaAllocator_T::AllocateMemory( // Bit mask of memory Vulkan types acceptable for this allocation. uint32_t memoryTypeBits = vkMemReq.memoryTypeBits; uint32_t memTypeIndex = UINT32_MAX; - VkResult res = vmaFindMemoryTypeIndex(this, memoryTypeBits, &createInfo, &memTypeIndex); - if(res == VK_SUCCESS) + res = FindMemoryTypeIndex(memoryTypeBits, &createInfoFinal, dedicatedBufferImageUsage, &memTypeIndex); + // Can't find any single memory type matching requirements. res is VK_ERROR_FEATURE_NOT_PRESENT. + if(res != VK_SUCCESS) + return res; + do { + VmaBlockVector* blockVector = m_pBlockVectors[memTypeIndex]; + VMA_ASSERT(blockVector && "Trying to use unsupported memory type!"); res = AllocateMemoryOfType( + VK_NULL_HANDLE, vkMemReq.size, vkMemReq.alignment, requiresDedicatedAllocation || prefersDedicatedAllocation, dedicatedBuffer, - dedicatedBufferUsage, dedicatedImage, - createInfo, + dedicatedBufferImageUsage, + createInfoFinal, memTypeIndex, suballocType, + m_DedicatedAllocations[memTypeIndex], + *blockVector, allocationCount, pAllocations); - // Succeeded on first try. + // Allocation succeeded if(res == VK_SUCCESS) - { - return res; - } - // Allocation from this memory type failed. Try other compatible memory types. - else - { - for(;;) - { - // Remove old memTypeIndex from list of possibilities. - memoryTypeBits &= ~(1u << memTypeIndex); - // Find alternative memTypeIndex. - res = vmaFindMemoryTypeIndex(this, memoryTypeBits, &createInfo, &memTypeIndex); - if(res == VK_SUCCESS) - { - res = AllocateMemoryOfType( - vkMemReq.size, - vkMemReq.alignment, - requiresDedicatedAllocation || prefersDedicatedAllocation, - dedicatedBuffer, - dedicatedBufferUsage, - dedicatedImage, - createInfo, - memTypeIndex, - suballocType, - allocationCount, - pAllocations); - // Allocation from this alternative memory type succeeded. - if(res == VK_SUCCESS) - { - return res; - } - // else: Allocation from this memory type failed. Try next one - next loop iteration. - } - // No other matching memory type index could be found. - else - { - // Not returning res, which is VK_ERROR_FEATURE_NOT_PRESENT, because we already failed to allocate once. - return VK_ERROR_OUT_OF_DEVICE_MEMORY; - } - } - } - } - // Can't find any single memory type maching requirements. res is VK_ERROR_FEATURE_NOT_PRESENT. - else - return res; + return VK_SUCCESS; + + // Remove old memTypeIndex from list of possibilities. + memoryTypeBits &= ~(1u << memTypeIndex); + // Find alternative memTypeIndex. + res = FindMemoryTypeIndex(memoryTypeBits, &createInfoFinal, dedicatedBufferImageUsage, &memTypeIndex); + } while(res == VK_SUCCESS); + + // No other matching memory type index could be found. + // Not returning res, which is VK_ERROR_FEATURE_NOT_PRESENT, because we already failed to allocate once. + return VK_ERROR_OUT_OF_DEVICE_MEMORY; } } @@ -15175,62 +15077,57 @@ void VmaAllocator_T::FreeMemory( if(allocation != VK_NULL_HANDLE) { - if(TouchAllocation(allocation)) + if(VMA_DEBUG_INITIALIZE_ALLOCATIONS) { - if(VMA_DEBUG_INITIALIZE_ALLOCATIONS) - { - FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED); - } - - switch(allocation->GetType()) - { - case VmaAllocation_T::ALLOCATION_TYPE_BLOCK: - { - VmaBlockVector* pBlockVector = VMA_NULL; - VmaPool hPool = allocation->GetBlock()->GetParentPool(); - if(hPool != VK_NULL_HANDLE) - { - pBlockVector = &hPool->m_BlockVector; - } - else - { - const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex(); - pBlockVector = m_pBlockVectors[memTypeIndex]; - } - pBlockVector->Free(allocation); - } - break; - case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED: - FreeDedicatedMemory(allocation); - break; - default: - VMA_ASSERT(0); - } + FillAllocation(allocation, VMA_ALLOCATION_FILL_PATTERN_DESTROYED); } - // Do this regardless of whether the allocation is lost. Lost allocations still account to Budget.AllocationBytes. - m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(allocation->GetMemoryTypeIndex()), allocation->GetSize()); - allocation->SetUserData(this, VMA_NULL); - m_AllocationObjectAllocator.Free(allocation); + allocation->FreeName(this); + + switch(allocation->GetType()) + { + case VmaAllocation_T::ALLOCATION_TYPE_BLOCK: + { + VmaBlockVector* pBlockVector = VMA_NULL; + VmaPool hPool = allocation->GetParentPool(); + if(hPool != VK_NULL_HANDLE) + { + pBlockVector = &hPool->m_BlockVector; + } + else + { + const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex(); + pBlockVector = m_pBlockVectors[memTypeIndex]; + VMA_ASSERT(pBlockVector && "Trying to free memory of unsupported type!"); + } + pBlockVector->Free(allocation); + } + break; + case VmaAllocation_T::ALLOCATION_TYPE_DEDICATED: + FreeDedicatedMemory(allocation); + break; + default: + VMA_ASSERT(0); + } } } } -void VmaAllocator_T::CalculateStats(VmaStats* pStats) +void VmaAllocator_T::CalculateStatistics(VmaTotalStatistics* pStats) { // Initialize. - InitStatInfo(pStats->total); - for(size_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) - InitStatInfo(pStats->memoryType[i]); - for(size_t i = 0; i < VK_MAX_MEMORY_HEAPS; ++i) - InitStatInfo(pStats->memoryHeap[i]); + VmaClearDetailedStatistics(pStats->total); + for(uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) + VmaClearDetailedStatistics(pStats->memoryType[i]); + for(uint32_t i = 0; i < VK_MAX_MEMORY_HEAPS; ++i) + VmaClearDetailedStatistics(pStats->memoryHeap[i]); // Process default pools. for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) { VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex]; - VMA_ASSERT(pBlockVector); - pBlockVector->AddStats(pStats); + if (pBlockVector != VMA_NULL) + pBlockVector->AddDetailedStatistics(pStats->memoryType[memTypeIndex]); } // Process custom pools. @@ -15238,36 +15135,37 @@ void VmaAllocator_T::CalculateStats(VmaStats* pStats) VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex); for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool)) { - pool->m_BlockVector.AddStats(pStats); + VmaBlockVector& blockVector = pool->m_BlockVector; + const uint32_t memTypeIndex = blockVector.GetMemoryTypeIndex(); + blockVector.AddDetailedStatistics(pStats->memoryType[memTypeIndex]); + pool->m_DedicatedAllocations.AddDetailedStatistics(pStats->memoryType[memTypeIndex]); } } // Process dedicated allocations. for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) { - const uint32_t memHeapIndex = MemoryTypeIndexToHeapIndex(memTypeIndex); - VmaMutexLockRead dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); - DedicatedAllocationLinkedList& dedicatedAllocList = m_DedicatedAllocations[memTypeIndex]; - for(VmaAllocation alloc = dedicatedAllocList.Front(); - alloc != VMA_NULL; alloc = dedicatedAllocList.GetNext(alloc)) - { - VmaStatInfo allocationStatInfo; - alloc->DedicatedAllocCalcStatsInfo(allocationStatInfo); - VmaAddStatInfo(pStats->total, allocationStatInfo); - VmaAddStatInfo(pStats->memoryType[memTypeIndex], allocationStatInfo); - VmaAddStatInfo(pStats->memoryHeap[memHeapIndex], allocationStatInfo); - } + m_DedicatedAllocations[memTypeIndex].AddDetailedStatistics(pStats->memoryType[memTypeIndex]); } - // Postprocess. - VmaPostprocessCalcStatInfo(pStats->total); - for(size_t i = 0; i < GetMemoryTypeCount(); ++i) - VmaPostprocessCalcStatInfo(pStats->memoryType[i]); - for(size_t i = 0; i < GetMemoryHeapCount(); ++i) - VmaPostprocessCalcStatInfo(pStats->memoryHeap[i]); + // Sum from memory types to memory heaps. + for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) + { + const uint32_t memHeapIndex = m_MemProps.memoryTypes[memTypeIndex].heapIndex; + VmaAddDetailedStatistics(pStats->memoryHeap[memHeapIndex], pStats->memoryType[memTypeIndex]); + } + + // Sum from memory heaps to total. + for(uint32_t memHeapIndex = 0; memHeapIndex < GetMemoryHeapCount(); ++memHeapIndex) + VmaAddDetailedStatistics(pStats->total, pStats->memoryHeap[memHeapIndex]); + + VMA_ASSERT(pStats->total.statistics.allocationCount == 0 || + pStats->total.allocationSizeMax >= pStats->total.allocationSizeMin); + VMA_ASSERT(pStats->total.unusedRangeCount == 0 || + pStats->total.unusedRangeSizeMax >= pStats->total.unusedRangeSizeMin); } -void VmaAllocator_T::GetBudget(VmaBudget* outBudget, uint32_t firstHeap, uint32_t heapCount) +void VmaAllocator_T::GetHeapBudgets(VmaBudget* outBudgets, uint32_t firstHeap, uint32_t heapCount) { #if VMA_MEMORY_BUDGET if(m_UseExtMemoryBudget) @@ -15275,225 +15173,63 @@ void VmaAllocator_T::GetBudget(VmaBudget* outBudget, uint32_t firstHeap, uint32_ if(m_Budget.m_OperationsSinceBudgetFetch < 30) { VmaMutexLockRead lockRead(m_Budget.m_BudgetMutex, m_UseMutex); - for(uint32_t i = 0; i < heapCount; ++i, ++outBudget) + for(uint32_t i = 0; i < heapCount; ++i, ++outBudgets) { const uint32_t heapIndex = firstHeap + i; - outBudget->blockBytes = m_Budget.m_BlockBytes[heapIndex]; - outBudget->allocationBytes = m_Budget.m_AllocationBytes[heapIndex]; + outBudgets->statistics.blockCount = m_Budget.m_BlockCount[heapIndex]; + outBudgets->statistics.allocationCount = m_Budget.m_AllocationCount[heapIndex]; + outBudgets->statistics.blockBytes = m_Budget.m_BlockBytes[heapIndex]; + outBudgets->statistics.allocationBytes = m_Budget.m_AllocationBytes[heapIndex]; - if(m_Budget.m_VulkanUsage[heapIndex] + outBudget->blockBytes > m_Budget.m_BlockBytesAtBudgetFetch[heapIndex]) + if(m_Budget.m_VulkanUsage[heapIndex] + outBudgets->statistics.blockBytes > m_Budget.m_BlockBytesAtBudgetFetch[heapIndex]) { - outBudget->usage = m_Budget.m_VulkanUsage[heapIndex] + - outBudget->blockBytes - m_Budget.m_BlockBytesAtBudgetFetch[heapIndex]; + outBudgets->usage = m_Budget.m_VulkanUsage[heapIndex] + + outBudgets->statistics.blockBytes - m_Budget.m_BlockBytesAtBudgetFetch[heapIndex]; } else { - outBudget->usage = 0; + outBudgets->usage = 0; } // Have to take MIN with heap size because explicit HeapSizeLimit is included in it. - outBudget->budget = VMA_MIN( + outBudgets->budget = VMA_MIN( m_Budget.m_VulkanBudget[heapIndex], m_MemProps.memoryHeaps[heapIndex].size); } } else { UpdateVulkanBudget(); // Outside of mutex lock - GetBudget(outBudget, firstHeap, heapCount); // Recursion + GetHeapBudgets(outBudgets, firstHeap, heapCount); // Recursion } } else #endif { - for(uint32_t i = 0; i < heapCount; ++i, ++outBudget) + for(uint32_t i = 0; i < heapCount; ++i, ++outBudgets) { const uint32_t heapIndex = firstHeap + i; - outBudget->blockBytes = m_Budget.m_BlockBytes[heapIndex]; - outBudget->allocationBytes = m_Budget.m_AllocationBytes[heapIndex]; + outBudgets->statistics.blockCount = m_Budget.m_BlockCount[heapIndex]; + outBudgets->statistics.allocationCount = m_Budget.m_AllocationCount[heapIndex]; + outBudgets->statistics.blockBytes = m_Budget.m_BlockBytes[heapIndex]; + outBudgets->statistics.allocationBytes = m_Budget.m_AllocationBytes[heapIndex]; - outBudget->usage = outBudget->blockBytes; - outBudget->budget = m_MemProps.memoryHeaps[heapIndex].size * 8 / 10; // 80% heuristics. + outBudgets->usage = outBudgets->statistics.blockBytes; + outBudgets->budget = m_MemProps.memoryHeaps[heapIndex].size * 8 / 10; // 80% heuristics. } } } -static const uint32_t VMA_VENDOR_ID_AMD = 4098; - -VkResult VmaAllocator_T::DefragmentationBegin( - const VmaDefragmentationInfo2& info, - VmaDefragmentationStats* pStats, - VmaDefragmentationContext* pContext) -{ - if(info.pAllocationsChanged != VMA_NULL) - { - memset(info.pAllocationsChanged, 0, info.allocationCount * sizeof(VkBool32)); - } - - *pContext = vma_new(this, VmaDefragmentationContext_T)( - this, m_CurrentFrameIndex.load(), info.flags, pStats); - - (*pContext)->AddPools(info.poolCount, info.pPools); - (*pContext)->AddAllocations( - info.allocationCount, info.pAllocations, info.pAllocationsChanged); - - VkResult res = (*pContext)->Defragment( - info.maxCpuBytesToMove, info.maxCpuAllocationsToMove, - info.maxGpuBytesToMove, info.maxGpuAllocationsToMove, - info.commandBuffer, pStats, info.flags); - - if(res != VK_NOT_READY) - { - vma_delete(this, *pContext); - *pContext = VMA_NULL; - } - - return res; -} - -VkResult VmaAllocator_T::DefragmentationEnd( - VmaDefragmentationContext context) -{ - vma_delete(this, context); - return VK_SUCCESS; -} - -VkResult VmaAllocator_T::DefragmentationPassBegin( - VmaDefragmentationPassInfo* pInfo, - VmaDefragmentationContext context) -{ - return context->DefragmentPassBegin(pInfo); -} -VkResult VmaAllocator_T::DefragmentationPassEnd( - VmaDefragmentationContext context) -{ - return context->DefragmentPassEnd(); - -} - void VmaAllocator_T::GetAllocationInfo(VmaAllocation hAllocation, VmaAllocationInfo* pAllocationInfo) { - if(hAllocation->CanBecomeLost()) - { - /* - Warning: This is a carefully designed algorithm. - Do not modify unless you really know what you are doing :) - */ - const uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load(); - uint32_t localLastUseFrameIndex = hAllocation->GetLastUseFrameIndex(); - for(;;) - { - if(localLastUseFrameIndex == VMA_FRAME_INDEX_LOST) - { - pAllocationInfo->memoryType = UINT32_MAX; - pAllocationInfo->deviceMemory = VK_NULL_HANDLE; - pAllocationInfo->offset = 0; - pAllocationInfo->size = hAllocation->GetSize(); - pAllocationInfo->pMappedData = VMA_NULL; - pAllocationInfo->pUserData = hAllocation->GetUserData(); - return; - } - else if(localLastUseFrameIndex == localCurrFrameIndex) - { - pAllocationInfo->memoryType = hAllocation->GetMemoryTypeIndex(); - pAllocationInfo->deviceMemory = hAllocation->GetMemory(); - pAllocationInfo->offset = hAllocation->GetOffset(); - pAllocationInfo->size = hAllocation->GetSize(); - pAllocationInfo->pMappedData = VMA_NULL; - pAllocationInfo->pUserData = hAllocation->GetUserData(); - return; - } - else // Last use time earlier than current time. - { - if(hAllocation->CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex)) - { - localLastUseFrameIndex = localCurrFrameIndex; - } - } - } - } - else - { -#if VMA_STATS_STRING_ENABLED - uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load(); - uint32_t localLastUseFrameIndex = hAllocation->GetLastUseFrameIndex(); - for(;;) - { - VMA_ASSERT(localLastUseFrameIndex != VMA_FRAME_INDEX_LOST); - if(localLastUseFrameIndex == localCurrFrameIndex) - { - break; - } - else // Last use time earlier than current time. - { - if(hAllocation->CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex)) - { - localLastUseFrameIndex = localCurrFrameIndex; - } - } - } -#endif - - pAllocationInfo->memoryType = hAllocation->GetMemoryTypeIndex(); - pAllocationInfo->deviceMemory = hAllocation->GetMemory(); - pAllocationInfo->offset = hAllocation->GetOffset(); - pAllocationInfo->size = hAllocation->GetSize(); - pAllocationInfo->pMappedData = hAllocation->GetMappedData(); - pAllocationInfo->pUserData = hAllocation->GetUserData(); - } -} - -bool VmaAllocator_T::TouchAllocation(VmaAllocation hAllocation) -{ - // This is a stripped-down version of VmaAllocator_T::GetAllocationInfo. - if(hAllocation->CanBecomeLost()) - { - uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load(); - uint32_t localLastUseFrameIndex = hAllocation->GetLastUseFrameIndex(); - for(;;) - { - if(localLastUseFrameIndex == VMA_FRAME_INDEX_LOST) - { - return false; - } - else if(localLastUseFrameIndex == localCurrFrameIndex) - { - return true; - } - else // Last use time earlier than current time. - { - if(hAllocation->CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex)) - { - localLastUseFrameIndex = localCurrFrameIndex; - } - } - } - } - else - { -#if VMA_STATS_STRING_ENABLED - uint32_t localCurrFrameIndex = m_CurrentFrameIndex.load(); - uint32_t localLastUseFrameIndex = hAllocation->GetLastUseFrameIndex(); - for(;;) - { - VMA_ASSERT(localLastUseFrameIndex != VMA_FRAME_INDEX_LOST); - if(localLastUseFrameIndex == localCurrFrameIndex) - { - break; - } - else // Last use time earlier than current time. - { - if(hAllocation->CompareExchangeLastUseFrameIndex(localLastUseFrameIndex, localCurrFrameIndex)) - { - localLastUseFrameIndex = localCurrFrameIndex; - } - } - } -#endif - - return true; - } + pAllocationInfo->memoryType = hAllocation->GetMemoryTypeIndex(); + pAllocationInfo->deviceMemory = hAllocation->GetMemory(); + pAllocationInfo->offset = hAllocation->GetOffset(); + pAllocationInfo->size = hAllocation->GetSize(); + pAllocationInfo->pMappedData = hAllocation->GetMappedData(); + pAllocationInfo->pUserData = hAllocation->GetUserData(); + pAllocationInfo->pName = hAllocation->GetName(); } VkResult VmaAllocator_T::CreatePool(const VmaPoolCreateInfo* pCreateInfo, VmaPool* pPool) @@ -15560,9 +15296,18 @@ void VmaAllocator_T::DestroyPool(VmaPool pool) vma_delete(this, pool); } -void VmaAllocator_T::GetPoolStats(VmaPool pool, VmaPoolStats* pPoolStats) +void VmaAllocator_T::GetPoolStatistics(VmaPool pool, VmaStatistics* pPoolStats) { - pool->m_BlockVector.GetPoolStats(pPoolStats); + VmaClearStatistics(*pPoolStats); + pool->m_BlockVector.AddStatistics(*pPoolStats); + pool->m_DedicatedAllocations.AddStatistics(*pPoolStats); +} + +void VmaAllocator_T::CalculatePoolStatistics(VmaPool pool, VmaDetailedStatistics* pPoolStats) +{ + VmaClearDetailedStatistics(*pPoolStats); + pool->m_BlockVector.AddDetailedStatistics(*pPoolStats); + pool->m_DedicatedAllocations.AddDetailedStatistics(*pPoolStats); } void VmaAllocator_T::SetCurrentFrameIndex(uint32_t frameIndex) @@ -15577,15 +15322,6 @@ void VmaAllocator_T::SetCurrentFrameIndex(uint32_t frameIndex) #endif // #if VMA_MEMORY_BUDGET } -void VmaAllocator_T::MakePoolAllocationsLost( - VmaPool hPool, - size_t* pLostAllocationCount) -{ - hPool->m_BlockVector.MakePoolAllocationsLost( - m_CurrentFrameIndex.load(), - pLostAllocationCount); -} - VkResult VmaAllocator_T::CheckPoolCorruption(VmaPool hPool) { return hPool->m_BlockVector.CheckCorruption(); @@ -15598,10 +15334,9 @@ VkResult VmaAllocator_T::CheckCorruption(uint32_t memoryTypeBits) // Process default pools. for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) { - if(((1u << memTypeIndex) & memoryTypeBits) != 0) + VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex]; + if(pBlockVector != VMA_NULL) { - VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex]; - VMA_ASSERT(pBlockVector); VkResult localRes = pBlockVector->CheckCorruption(); switch(localRes) { @@ -15641,37 +15376,6 @@ VkResult VmaAllocator_T::CheckCorruption(uint32_t memoryTypeBits) return finalRes; } -void VmaAllocator_T::CreateLostAllocation(VmaAllocation* pAllocation) -{ - *pAllocation = m_AllocationObjectAllocator.Allocate(VMA_FRAME_INDEX_LOST, false); - (*pAllocation)->InitLost(); -} - -// An object that increments given atomic but decrements it back in the destructor unless Commit() is called. -template -struct AtomicTransactionalIncrement -{ -public: - typedef std::atomic AtomicT; - ~AtomicTransactionalIncrement() - { - if(m_Atomic) - --(*m_Atomic); - } - T Increment(AtomicT* atomic) - { - m_Atomic = atomic; - return m_Atomic->fetch_add(1); - } - void Commit() - { - m_Atomic = nullptr; - } - -private: - AtomicT* m_Atomic = nullptr; -}; - VkResult VmaAllocator_T::AllocateVulkanMemory(const VkMemoryAllocateInfo* pAllocateInfo, VkDeviceMemory* pMemory) { AtomicTransactionalIncrement deviceMemoryCountIncrement; @@ -15707,6 +15411,7 @@ VkResult VmaAllocator_T::AllocateVulkanMemory(const VkMemoryAllocateInfo* pAlloc { m_Budget.m_BlockBytes[heapIndex] += pAllocateInfo->allocationSize; } + ++m_Budget.m_BlockCount[heapIndex]; // VULKAN CALL vkAllocateMemory. VkResult res = (*m_VulkanFunctions.vkAllocateMemory)(m_hDevice, pAllocateInfo, GetAllocationCallbacks(), pMemory); @@ -15727,6 +15432,7 @@ VkResult VmaAllocator_T::AllocateVulkanMemory(const VkMemoryAllocateInfo* pAlloc } else { + --m_Budget.m_BlockCount[heapIndex]; m_Budget.m_BlockBytes[heapIndex] -= pAllocateInfo->allocationSize; } @@ -15744,7 +15450,9 @@ void VmaAllocator_T::FreeVulkanMemory(uint32_t memoryType, VkDeviceSize size, Vk // VULKAN CALL vkFreeMemory. (*m_VulkanFunctions.vkFreeMemory)(m_hDevice, hMemory, GetAllocationCallbacks()); - m_Budget.m_BlockBytes[MemoryTypeIndexToHeapIndex(memoryType)] -= size; + const uint32_t heapIndex = MemoryTypeIndexToHeapIndex(memoryType); + --m_Budget.m_BlockCount[heapIndex]; + m_Budget.m_BlockBytes[heapIndex] -= size; --m_DeviceMemoryCount; } @@ -15813,11 +15521,6 @@ VkResult VmaAllocator_T::BindVulkanImage( VkResult VmaAllocator_T::Map(VmaAllocation hAllocation, void** ppData) { - if(hAllocation->CanBecomeLost()) - { - return VK_ERROR_MEMORY_MAP_FAILED; - } - switch(hAllocation->GetType()) { case VmaAllocation_T::ALLOCATION_TYPE_BLOCK: @@ -15874,7 +15577,7 @@ VkResult VmaAllocator_T::BindBufferMemory( case VmaAllocation_T::ALLOCATION_TYPE_BLOCK: { VmaDeviceMemoryBlock* const pBlock = hAllocation->GetBlock(); - VMA_ASSERT(pBlock && "Binding buffer to allocation that doesn't belong to any block. Is the allocation lost?"); + VMA_ASSERT(pBlock && "Binding buffer to allocation that doesn't belong to any block."); res = pBlock->BindBufferMemory(this, hAllocation, allocationLocalOffset, hBuffer, pNext); break; } @@ -15899,7 +15602,7 @@ VkResult VmaAllocator_T::BindImageMemory( case VmaAllocation_T::ALLOCATION_TYPE_BLOCK: { VmaDeviceMemoryBlock* pBlock = hAllocation->GetBlock(); - VMA_ASSERT(pBlock && "Binding image to allocation that doesn't belong to any block. Is the allocation lost?"); + VMA_ASSERT(pBlock && "Binding image to allocation that doesn't belong to any block."); res = pBlock->BindImageMemory(this, hAllocation, allocationLocalOffset, hImage, pNext); break; } @@ -15981,10 +15684,16 @@ void VmaAllocator_T::FreeDedicatedMemory(const VmaAllocation allocation) VMA_ASSERT(allocation && allocation->GetType() == VmaAllocation_T::ALLOCATION_TYPE_DEDICATED); const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex(); + VmaPool parentPool = allocation->GetParentPool(); + if(parentPool == VK_NULL_HANDLE) { - VmaMutexLockWrite lock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); - DedicatedAllocationLinkedList& dedicatedAllocations = m_DedicatedAllocations[memTypeIndex]; - dedicatedAllocations.Remove(allocation); + // Default pool + m_DedicatedAllocations[memTypeIndex].Unregister(allocation); + } + else + { + // Custom pool + parentPool->m_DedicatedAllocations.Unregister(allocation); } VkDeviceMemory hMemory = allocation->GetMemory(); @@ -16001,6 +15710,9 @@ void VmaAllocator_T::FreeDedicatedMemory(const VmaAllocation allocation) FreeVulkanMemory(memTypeIndex, allocation->GetSize(), hMemory); + m_Budget.RemoveAllocation(MemoryTypeIndexToHeapIndex(allocation->GetMemoryTypeIndex()), allocation->GetSize()); + m_AllocationObjectAllocator.Free(allocation); + VMA_DEBUG_LOG(" Freed DedicatedMemory MemoryTypeIndex=%u", memTypeIndex); } @@ -16115,7 +15827,6 @@ bool VmaAllocator_T::GetFlushOrInvalidateRange( } #if VMA_MEMORY_BUDGET - void VmaAllocator_T::UpdateVulkanBudget() { VMA_ASSERT(m_UseExtMemoryBudget); @@ -16153,13 +15864,12 @@ void VmaAllocator_T::UpdateVulkanBudget() m_Budget.m_OperationsSinceBudgetFetch = 0; } } - -#endif // #if VMA_MEMORY_BUDGET +#endif // VMA_MEMORY_BUDGET void VmaAllocator_T::FillAllocation(const VmaAllocation hAllocation, uint8_t pattern) { if(VMA_DEBUG_INITIALIZE_ALLOCATIONS && - !hAllocation->CanBecomeLost() && + hAllocation->IsMappingAllowed() && (m_MemProps.memoryTypes[hAllocation->GetMemoryTypeIndex()].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) { void* pData = VMA_NULL; @@ -16189,106 +15899,114 @@ uint32_t VmaAllocator_T::GetGpuDefragmentationMemoryTypeBits() } #if VMA_STATS_STRING_ENABLED - void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json) { - bool dedicatedAllocationsStarted = false; - for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) + json.WriteString("DefaultPools"); + json.BeginObject(); { - VmaMutexLockRead dedicatedAllocationsLock(m_DedicatedAllocationsMutex[memTypeIndex], m_UseMutex); - DedicatedAllocationLinkedList& dedicatedAllocList = m_DedicatedAllocations[memTypeIndex]; - if(!dedicatedAllocList.IsEmpty()) + for (uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) { - if(dedicatedAllocationsStarted == false) + VmaBlockVector* pBlockVector = m_pBlockVectors[memTypeIndex]; + VmaDedicatedAllocationList& dedicatedAllocList = m_DedicatedAllocations[memTypeIndex]; + if (pBlockVector != VMA_NULL) { - dedicatedAllocationsStarted = true; - json.WriteString("DedicatedAllocations"); - json.BeginObject(); - } - - json.BeginString("Type "); - json.ContinueString(memTypeIndex); - json.EndString(); - - json.BeginArray(); - - for(VmaAllocation alloc = dedicatedAllocList.Front(); - alloc != VMA_NULL; alloc = dedicatedAllocList.GetNext(alloc)) - { - json.BeginObject(true); - alloc->PrintParameters(json); - json.EndObject(); - } - - json.EndArray(); - } - } - if(dedicatedAllocationsStarted) - { - json.EndObject(); - } - - { - bool allocationsStarted = false; - for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) - { - if(m_pBlockVectors[memTypeIndex]->IsEmpty() == false) - { - if(allocationsStarted == false) - { - allocationsStarted = true; - json.WriteString("DefaultPools"); - json.BeginObject(); - } - json.BeginString("Type "); json.ContinueString(memTypeIndex); json.EndString(); + json.BeginObject(); + { + json.WriteString("PreferredBlockSize"); + json.WriteNumber(pBlockVector->GetPreferredBlockSize()); - m_pBlockVectors[memTypeIndex]->PrintDetailedMap(json); + json.WriteString("Blocks"); + pBlockVector->PrintDetailedMap(json); + + json.WriteString("DedicatedAllocations"); + dedicatedAllocList.BuildStatsString(json); + } + json.EndObject(); } } - if(allocationsStarted) - { - json.EndObject(); - } } + json.EndObject(); - // Custom pools + json.WriteString("CustomPools"); + json.BeginObject(); { VmaMutexLockRead lock(m_PoolsMutex, m_UseMutex); - if(!m_Pools.IsEmpty()) + if (!m_Pools.IsEmpty()) { - json.WriteString("Pools"); - json.BeginObject(); - for(VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool)) + for (uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex) { - json.BeginString(); - json.ContinueString(pool->GetId()); - json.EndString(); + bool displayType = true; + size_t index = 0; + for (VmaPool pool = m_Pools.Front(); pool != VMA_NULL; pool = m_Pools.GetNext(pool)) + { + VmaBlockVector& blockVector = pool->m_BlockVector; + if (blockVector.GetMemoryTypeIndex() == memTypeIndex) + { + if (displayType) + { + json.BeginString("Type "); + json.ContinueString(memTypeIndex); + json.EndString(); + json.BeginArray(); + displayType = false; + } - pool->m_BlockVector.PrintDetailedMap(json); + json.BeginObject(); + { + json.WriteString("Name"); + json.BeginString(); + json.ContinueString_Size(index++); + if (pool->GetName()) + { + json.ContinueString(" - "); + json.ContinueString(pool->GetName()); + } + json.EndString(); + + json.WriteString("PreferredBlockSize"); + json.WriteNumber(blockVector.GetPreferredBlockSize()); + + json.WriteString("Blocks"); + blockVector.PrintDetailedMap(json); + + json.WriteString("DedicatedAllocations"); + pool->m_DedicatedAllocations.BuildStatsString(json); + } + json.EndObject(); + } + } + + if (!displayType) + json.EndArray(); } - json.EndObject(); } } + json.EndObject(); } +#endif // VMA_STATS_STRING_ENABLED +#endif // _VMA_ALLOCATOR_T_FUNCTIONS -#endif // #if VMA_STATS_STRING_ENABLED - -//////////////////////////////////////////////////////////////////////////////// -// Public interface +#ifndef _VMA_PUBLIC_INTERFACE VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAllocator( const VmaAllocatorCreateInfo* pCreateInfo, VmaAllocator* pAllocator) { VMA_ASSERT(pCreateInfo && pAllocator); VMA_ASSERT(pCreateInfo->vulkanApiVersion == 0 || - (VK_VERSION_MAJOR(pCreateInfo->vulkanApiVersion) == 1 && VK_VERSION_MINOR(pCreateInfo->vulkanApiVersion) <= 2)); + (VK_VERSION_MAJOR(pCreateInfo->vulkanApiVersion) == 1 && VK_VERSION_MINOR(pCreateInfo->vulkanApiVersion) <= 3)); VMA_DEBUG_LOG("vmaCreateAllocator"); *pAllocator = vma_new(pCreateInfo->pAllocationCallbacks, VmaAllocator_T)(pCreateInfo); - return (*pAllocator)->Init(pCreateInfo); + VkResult result = (*pAllocator)->Init(pCreateInfo); + if(result < 0) + { + vma_delete(pCreateInfo->pAllocationCallbacks, *pAllocator); + *pAllocator = VK_NULL_HANDLE; + } + return result; } VMA_CALL_PRE void VMA_CALL_POST vmaDestroyAllocator( @@ -16297,7 +16015,7 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyAllocator( if(allocator != VK_NULL_HANDLE) { VMA_DEBUG_LOG("vmaDestroyAllocator"); - VkAllocationCallbacks allocationCallbacks = allocator->m_AllocationCallbacks; + VkAllocationCallbacks allocationCallbacks = allocator->m_AllocationCallbacks; // Have to copy the callbacks when destroying. vma_delete(&allocationCallbacks, allocator); } } @@ -16341,29 +16059,28 @@ VMA_CALL_PRE void VMA_CALL_POST vmaSetCurrentFrameIndex( uint32_t frameIndex) { VMA_ASSERT(allocator); - VMA_ASSERT(frameIndex != VMA_FRAME_INDEX_LOST); VMA_DEBUG_GLOBAL_MUTEX_LOCK allocator->SetCurrentFrameIndex(frameIndex); } -VMA_CALL_PRE void VMA_CALL_POST vmaCalculateStats( +VMA_CALL_PRE void VMA_CALL_POST vmaCalculateStatistics( VmaAllocator allocator, - VmaStats* pStats) + VmaTotalStatistics* pStats) { VMA_ASSERT(allocator && pStats); VMA_DEBUG_GLOBAL_MUTEX_LOCK - allocator->CalculateStats(pStats); + allocator->CalculateStatistics(pStats); } -VMA_CALL_PRE void VMA_CALL_POST vmaGetBudget( +VMA_CALL_PRE void VMA_CALL_POST vmaGetHeapBudgets( VmaAllocator allocator, - VmaBudget* pBudget) + VmaBudget* pBudgets) { - VMA_ASSERT(allocator && pBudget); + VMA_ASSERT(allocator && pBudgets); VMA_DEBUG_GLOBAL_MUTEX_LOCK - allocator->GetBudget(pBudget, 0, allocator->GetMemoryHeapCount()); + allocator->GetHeapBudgets(pBudgets, 0, allocator->GetMemoryHeapCount()); } #if VMA_STATS_STRING_ENABLED @@ -16376,137 +16093,183 @@ VMA_CALL_PRE void VMA_CALL_POST vmaBuildStatsString( VMA_ASSERT(allocator && ppStatsString); VMA_DEBUG_GLOBAL_MUTEX_LOCK - VmaStringBuilder sb(allocator); + VmaStringBuilder sb(allocator->GetAllocationCallbacks()); { + VmaBudget budgets[VK_MAX_MEMORY_HEAPS]; + allocator->GetHeapBudgets(budgets, 0, allocator->GetMemoryHeapCount()); + + VmaTotalStatistics stats; + allocator->CalculateStatistics(&stats); + VmaJsonWriter json(allocator->GetAllocationCallbacks(), sb); json.BeginObject(); - - VmaBudget budget[VK_MAX_MEMORY_HEAPS]; - allocator->GetBudget(budget, 0, allocator->GetMemoryHeapCount()); - - VmaStats stats; - allocator->CalculateStats(&stats); - - json.WriteString("Total"); - VmaPrintStatInfo(json, stats.total); - - for(uint32_t heapIndex = 0; heapIndex < allocator->GetMemoryHeapCount(); ++heapIndex) { - json.BeginString("Heap "); - json.ContinueString(heapIndex); - json.EndString(); - json.BeginObject(); - - json.WriteString("Size"); - json.WriteNumber(allocator->m_MemProps.memoryHeaps[heapIndex].size); - - json.WriteString("Flags"); - json.BeginArray(true); - if((allocator->m_MemProps.memoryHeaps[heapIndex].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0) - { - json.WriteString("DEVICE_LOCAL"); - } - json.EndArray(); - - json.WriteString("Budget"); + json.WriteString("General"); json.BeginObject(); { - json.WriteString("BlockBytes"); - json.WriteNumber(budget[heapIndex].blockBytes); - json.WriteString("AllocationBytes"); - json.WriteNumber(budget[heapIndex].allocationBytes); - json.WriteString("Usage"); - json.WriteNumber(budget[heapIndex].usage); - json.WriteString("Budget"); - json.WriteNumber(budget[heapIndex].budget); + const VkPhysicalDeviceProperties& deviceProperties = allocator->m_PhysicalDeviceProperties; + const VkPhysicalDeviceMemoryProperties& memoryProperties = allocator->m_MemProps; + + json.WriteString("API"); + json.WriteString("Vulkan"); + + json.WriteString("apiVersion"); + json.BeginString(); + json.ContinueString(VK_API_VERSION_MAJOR(deviceProperties.apiVersion)); + json.ContinueString("."); + json.ContinueString(VK_API_VERSION_MINOR(deviceProperties.apiVersion)); + json.ContinueString("."); + json.ContinueString(VK_API_VERSION_PATCH(deviceProperties.apiVersion)); + json.EndString(); + + json.WriteString("GPU"); + json.WriteString(deviceProperties.deviceName); + json.WriteString("deviceType"); + json.WriteNumber(static_cast(deviceProperties.deviceType)); + + json.WriteString("maxMemoryAllocationCount"); + json.WriteNumber(deviceProperties.limits.maxMemoryAllocationCount); + json.WriteString("bufferImageGranularity"); + json.WriteNumber(deviceProperties.limits.bufferImageGranularity); + json.WriteString("nonCoherentAtomSize"); + json.WriteNumber(deviceProperties.limits.nonCoherentAtomSize); + + json.WriteString("memoryHeapCount"); + json.WriteNumber(memoryProperties.memoryHeapCount); + json.WriteString("memoryTypeCount"); + json.WriteNumber(memoryProperties.memoryTypeCount); } json.EndObject(); - - if(stats.memoryHeap[heapIndex].blockCount > 0) + } + { + json.WriteString("Total"); + VmaPrintDetailedStatistics(json, stats.total); + } + { + json.WriteString("MemoryInfo"); + json.BeginObject(); { - json.WriteString("Stats"); - VmaPrintStatInfo(json, stats.memoryHeap[heapIndex]); - } - - for(uint32_t typeIndex = 0; typeIndex < allocator->GetMemoryTypeCount(); ++typeIndex) - { - if(allocator->MemoryTypeIndexToHeapIndex(typeIndex) == heapIndex) + for (uint32_t heapIndex = 0; heapIndex < allocator->GetMemoryHeapCount(); ++heapIndex) { - json.BeginString("Type "); - json.ContinueString(typeIndex); + json.BeginString("Heap "); + json.ContinueString(heapIndex); json.EndString(); - json.BeginObject(); + { + const VkMemoryHeap& heapInfo = allocator->m_MemProps.memoryHeaps[heapIndex]; + json.WriteString("Flags"); + json.BeginArray(true); + { + if (heapInfo.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) + json.WriteString("DEVICE_LOCAL"); + #if VMA_VULKAN_VERSION >= 1001000 + if (heapInfo.flags & VK_MEMORY_HEAP_MULTI_INSTANCE_BIT) + json.WriteString("MULTI_INSTANCE"); + #endif - json.WriteString("Flags"); - json.BeginArray(true); - VkMemoryPropertyFlags flags = allocator->m_MemProps.memoryTypes[typeIndex].propertyFlags; - if((flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) != 0) - { - json.WriteString("DEVICE_LOCAL"); - } - if((flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) - { - json.WriteString("HOST_VISIBLE"); - } - if((flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0) - { - json.WriteString("HOST_COHERENT"); - } - if((flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) != 0) - { - json.WriteString("HOST_CACHED"); - } - if((flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) != 0) - { - json.WriteString("LAZILY_ALLOCATED"); - } -#if VMA_VULKAN_VERSION >= 1001000 - if((flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) != 0) - { - json.WriteString("PROTECTED"); - } -#endif // #if VMA_VULKAN_VERSION >= 1001000 -#if VK_AMD_device_coherent_memory - if((flags & VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY) != 0) - { - json.WriteString("DEVICE_COHERENT"); - } - if((flags & VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY) != 0) - { - json.WriteString("DEVICE_UNCACHED"); - } -#endif // #if VK_AMD_device_coherent_memory - json.EndArray(); + VkMemoryHeapFlags flags = heapInfo.flags & + ~(VK_MEMORY_HEAP_DEVICE_LOCAL_BIT + #if VMA_VULKAN_VERSION >= 1001000 + | VK_MEMORY_HEAP_MULTI_INSTANCE_BIT + #endif + ); + if (flags != 0) + json.WriteNumber(flags); + } + json.EndArray(); + + json.WriteString("Size"); + json.WriteNumber(heapInfo.size); + + json.WriteString("Budget"); + json.BeginObject(); + { + json.WriteString("BudgetBytes"); + json.WriteNumber(budgets[heapIndex].budget); + json.WriteString("UsageBytes"); + json.WriteNumber(budgets[heapIndex].usage); + } + json.EndObject(); - if(stats.memoryType[typeIndex].blockCount > 0) - { json.WriteString("Stats"); - VmaPrintStatInfo(json, stats.memoryType[typeIndex]); - } + VmaPrintDetailedStatistics(json, stats.memoryHeap[heapIndex]); + json.WriteString("MemoryPools"); + json.BeginObject(); + { + for (uint32_t typeIndex = 0; typeIndex < allocator->GetMemoryTypeCount(); ++typeIndex) + { + if (allocator->MemoryTypeIndexToHeapIndex(typeIndex) == heapIndex) + { + json.BeginString("Type "); + json.ContinueString(typeIndex); + json.EndString(); + json.BeginObject(); + { + json.WriteString("Flags"); + json.BeginArray(true); + { + VkMemoryPropertyFlags flags = allocator->m_MemProps.memoryTypes[typeIndex].propertyFlags; + if (flags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) + json.WriteString("DEVICE_LOCAL"); + if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + json.WriteString("HOST_VISIBLE"); + if (flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) + json.WriteString("HOST_COHERENT"); + if (flags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) + json.WriteString("HOST_CACHED"); + if (flags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) + json.WriteString("LAZILY_ALLOCATED"); + #if VMA_VULKAN_VERSION >= 1001000 + if (flags & VK_MEMORY_PROPERTY_PROTECTED_BIT) + json.WriteString("PROTECTED"); + #endif + #if VK_AMD_device_coherent_memory + if (flags & VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY) + json.WriteString("DEVICE_COHERENT_AMD"); + if (flags & VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY) + json.WriteString("DEVICE_UNCACHED_AMD"); + #endif + + flags &= ~(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT + #if VMA_VULKAN_VERSION >= 1001000 + | VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT + #endif + #if VK_AMD_device_coherent_memory + | VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY + | VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY + #endif + | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT + | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT + | VK_MEMORY_PROPERTY_HOST_CACHED_BIT); + if (flags != 0) + json.WriteNumber(flags); + } + json.EndArray(); + + json.WriteString("Stats"); + VmaPrintDetailedStatistics(json, stats.memoryType[typeIndex]); + } + json.EndObject(); + } + } + + } + json.EndObject(); + } json.EndObject(); } } - json.EndObject(); } - if(detailedMap == VK_TRUE) - { + + if (detailedMap == VK_TRUE) allocator->PrintDetailedMap(json); - } json.EndObject(); } - const size_t len = sb.GetLength(); - char* const pChars = vma_new_array(allocator, char, len + 1); - if(len > 0) - { - memcpy(pChars, sb.GetData(), len); - } - pChars[len] = '\0'; - *ppStatsString = pChars; + *ppStatsString = VmaCreateStringCopy(allocator->GetAllocationCallbacks(), sb.GetData(), sb.GetLength()); } VMA_CALL_PRE void VMA_CALL_POST vmaFreeStatsString( @@ -16516,12 +16279,11 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeStatsString( if(pStatsString != VMA_NULL) { VMA_ASSERT(allocator); - size_t len = strlen(pStatsString); - vma_delete_array(allocator, pStatsString, len + 1); + VmaFreeString(allocator->GetAllocationCallbacks(), pStatsString); } } -#endif // #if VMA_STATS_STRING_ENABLED +#endif // VMA_STATS_STRING_ENABLED /* This function is not protected by any mutex because it just reads immutable data. @@ -16536,91 +16298,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndex( VMA_ASSERT(pAllocationCreateInfo != VMA_NULL); VMA_ASSERT(pMemoryTypeIndex != VMA_NULL); - memoryTypeBits &= allocator->GetGlobalMemoryTypeBits(); - - if(pAllocationCreateInfo->memoryTypeBits != 0) - { - memoryTypeBits &= pAllocationCreateInfo->memoryTypeBits; - } - - uint32_t requiredFlags = pAllocationCreateInfo->requiredFlags; - uint32_t preferredFlags = pAllocationCreateInfo->preferredFlags; - uint32_t notPreferredFlags = 0; - - // Convert usage to requiredFlags and preferredFlags. - switch(pAllocationCreateInfo->usage) - { - case VMA_MEMORY_USAGE_UNKNOWN: - break; - case VMA_MEMORY_USAGE_GPU_ONLY: - if(!allocator->IsIntegratedGpu() || (preferredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) - { - preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - } - break; - case VMA_MEMORY_USAGE_CPU_ONLY: - requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - break; - case VMA_MEMORY_USAGE_CPU_TO_GPU: - requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - if(!allocator->IsIntegratedGpu() || (preferredFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == 0) - { - preferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - } - break; - case VMA_MEMORY_USAGE_GPU_TO_CPU: - requiredFlags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - preferredFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - break; - case VMA_MEMORY_USAGE_CPU_COPY: - notPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; - break; - case VMA_MEMORY_USAGE_GPU_LAZILY_ALLOCATED: - requiredFlags |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT; - break; - default: - VMA_ASSERT(0); - break; - } - - // Avoid DEVICE_COHERENT unless explicitly requested. - if(((pAllocationCreateInfo->requiredFlags | pAllocationCreateInfo->preferredFlags) & - (VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY | VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD_COPY)) == 0) - { - notPreferredFlags |= VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD_COPY; - } - - *pMemoryTypeIndex = UINT32_MAX; - uint32_t minCost = UINT32_MAX; - for(uint32_t memTypeIndex = 0, memTypeBit = 1; - memTypeIndex < allocator->GetMemoryTypeCount(); - ++memTypeIndex, memTypeBit <<= 1) - { - // This memory type is acceptable according to memoryTypeBits bitmask. - if((memTypeBit & memoryTypeBits) != 0) - { - const VkMemoryPropertyFlags currFlags = - allocator->m_MemProps.memoryTypes[memTypeIndex].propertyFlags; - // This memory type contains requiredFlags. - if((requiredFlags & ~currFlags) == 0) - { - // Calculate cost as number of bits from preferredFlags not present in this memory type. - uint32_t currCost = VmaCountBitsSet(preferredFlags & ~currFlags) + - VmaCountBitsSet(currFlags & notPreferredFlags); - // Remember memory type with lowest cost. - if(currCost < minCost) - { - *pMemoryTypeIndex = memTypeIndex; - if(currCost == 0) - { - return VK_SUCCESS; - } - minCost = currCost; - } - } - } - } - return (*pMemoryTypeIndex != UINT32_MAX) ? VK_SUCCESS : VK_ERROR_FEATURE_NOT_PRESENT; + return allocator->FindMemoryTypeIndex(memoryTypeBits, pAllocationCreateInfo, UINT32_MAX, pMemoryTypeIndex); } VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo( @@ -16635,23 +16313,40 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForBufferInfo( VMA_ASSERT(pMemoryTypeIndex != VMA_NULL); const VkDevice hDev = allocator->m_hDevice; - VkBuffer hBuffer = VK_NULL_HANDLE; - VkResult res = allocator->GetVulkanFunctions().vkCreateBuffer( - hDev, pBufferCreateInfo, allocator->GetAllocationCallbacks(), &hBuffer); - if(res == VK_SUCCESS) + const VmaVulkanFunctions* funcs = &allocator->GetVulkanFunctions(); + VkResult res; + +#if VMA_VULKAN_VERSION >= 1003000 + if(funcs->vkGetDeviceBufferMemoryRequirements) { - VkMemoryRequirements memReq = {}; - allocator->GetVulkanFunctions().vkGetBufferMemoryRequirements( - hDev, hBuffer, &memReq); + // Can query straight from VkBufferCreateInfo :) + VkDeviceBufferMemoryRequirements devBufMemReq = {VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS}; + devBufMemReq.pCreateInfo = pBufferCreateInfo; - res = vmaFindMemoryTypeIndex( - allocator, - memReq.memoryTypeBits, - pAllocationCreateInfo, - pMemoryTypeIndex); + VkMemoryRequirements2 memReq = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2}; + (*funcs->vkGetDeviceBufferMemoryRequirements)(hDev, &devBufMemReq, &memReq); - allocator->GetVulkanFunctions().vkDestroyBuffer( - hDev, hBuffer, allocator->GetAllocationCallbacks()); + res = allocator->FindMemoryTypeIndex( + memReq.memoryRequirements.memoryTypeBits, pAllocationCreateInfo, pBufferCreateInfo->usage, pMemoryTypeIndex); + } + else +#endif // #if VMA_VULKAN_VERSION >= 1003000 + { + // Must create a dummy buffer to query :( + VkBuffer hBuffer = VK_NULL_HANDLE; + res = funcs->vkCreateBuffer( + hDev, pBufferCreateInfo, allocator->GetAllocationCallbacks(), &hBuffer); + if(res == VK_SUCCESS) + { + VkMemoryRequirements memReq = {}; + funcs->vkGetBufferMemoryRequirements(hDev, hBuffer, &memReq); + + res = allocator->FindMemoryTypeIndex( + memReq.memoryTypeBits, pAllocationCreateInfo, pBufferCreateInfo->usage, pMemoryTypeIndex); + + funcs->vkDestroyBuffer( + hDev, hBuffer, allocator->GetAllocationCallbacks()); + } } return res; } @@ -16668,23 +16363,42 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFindMemoryTypeIndexForImageInfo( VMA_ASSERT(pMemoryTypeIndex != VMA_NULL); const VkDevice hDev = allocator->m_hDevice; - VkImage hImage = VK_NULL_HANDLE; - VkResult res = allocator->GetVulkanFunctions().vkCreateImage( - hDev, pImageCreateInfo, allocator->GetAllocationCallbacks(), &hImage); - if(res == VK_SUCCESS) + const VmaVulkanFunctions* funcs = &allocator->GetVulkanFunctions(); + VkResult res; + +#if VMA_VULKAN_VERSION >= 1003000 + if(funcs->vkGetDeviceImageMemoryRequirements) { - VkMemoryRequirements memReq = {}; - allocator->GetVulkanFunctions().vkGetImageMemoryRequirements( - hDev, hImage, &memReq); + // Can query straight from VkImageCreateInfo :) + VkDeviceImageMemoryRequirements devImgMemReq = {VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS}; + devImgMemReq.pCreateInfo = pImageCreateInfo; + VMA_ASSERT(pImageCreateInfo->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT_COPY && (pImageCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT_COPY) == 0 && + "Cannot use this VkImageCreateInfo with vmaFindMemoryTypeIndexForImageInfo as I don't know what to pass as VkDeviceImageMemoryRequirements::planeAspect."); - res = vmaFindMemoryTypeIndex( - allocator, - memReq.memoryTypeBits, - pAllocationCreateInfo, - pMemoryTypeIndex); + VkMemoryRequirements2 memReq = {VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2}; + (*funcs->vkGetDeviceImageMemoryRequirements)(hDev, &devImgMemReq, &memReq); - allocator->GetVulkanFunctions().vkDestroyImage( - hDev, hImage, allocator->GetAllocationCallbacks()); + res = allocator->FindMemoryTypeIndex( + memReq.memoryRequirements.memoryTypeBits, pAllocationCreateInfo, pImageCreateInfo->usage, pMemoryTypeIndex); + } + else +#endif // #if VMA_VULKAN_VERSION >= 1003000 + { + // Must create a dummy image to query :( + VkImage hImage = VK_NULL_HANDLE; + res = funcs->vkCreateImage( + hDev, pImageCreateInfo, allocator->GetAllocationCallbacks(), &hImage); + if(res == VK_SUCCESS) + { + VkMemoryRequirements memReq = {}; + funcs->vkGetImageMemoryRequirements(hDev, hImage, &memReq); + + res = allocator->FindMemoryTypeIndex( + memReq.memoryTypeBits, pAllocationCreateInfo, pImageCreateInfo->usage, pMemoryTypeIndex); + + funcs->vkDestroyImage( + hDev, hImage, allocator->GetAllocationCallbacks()); + } } return res; } @@ -16700,16 +16414,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreatePool( VMA_DEBUG_GLOBAL_MUTEX_LOCK - VkResult res = allocator->CreatePool(pCreateInfo, pPool); - -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordCreatePool(allocator->GetCurrentFrameIndex(), *pCreateInfo, *pPool); - } -#endif - - return res; + return allocator->CreatePool(pCreateInfo, pPool); } VMA_CALL_PRE void VMA_CALL_POST vmaDestroyPool( @@ -16727,45 +16432,31 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyPool( VMA_DEBUG_GLOBAL_MUTEX_LOCK -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordDestroyPool(allocator->GetCurrentFrameIndex(), pool); - } -#endif - allocator->DestroyPool(pool); } -VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolStats( +VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolStatistics( VmaAllocator allocator, VmaPool pool, - VmaPoolStats* pPoolStats) + VmaStatistics* pPoolStats) { VMA_ASSERT(allocator && pool && pPoolStats); VMA_DEBUG_GLOBAL_MUTEX_LOCK - allocator->GetPoolStats(pool, pPoolStats); + allocator->GetPoolStatistics(pool, pPoolStats); } -VMA_CALL_PRE void VMA_CALL_POST vmaMakePoolAllocationsLost( +VMA_CALL_PRE void VMA_CALL_POST vmaCalculatePoolStatistics( VmaAllocator allocator, VmaPool pool, - size_t* pLostAllocationCount) + VmaDetailedStatistics* pPoolStats) { - VMA_ASSERT(allocator && pool); + VMA_ASSERT(allocator && pool && pPoolStats); VMA_DEBUG_GLOBAL_MUTEX_LOCK -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordMakePoolAllocationsLost(allocator->GetCurrentFrameIndex(), pool); - } -#endif - - allocator->MakePoolAllocationsLost(pool, pLostAllocationCount); + allocator->CalculatePoolStatistics(pool, pPoolStats); } VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckPoolCorruption(VmaAllocator allocator, VmaPool pool) @@ -16805,13 +16496,6 @@ VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName( VMA_DEBUG_GLOBAL_MUTEX_LOCK pool->SetName(pName); - -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordSetPoolName(allocator->GetCurrentFrameIndex(), pool, pName); - } -#endif } VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory( @@ -16832,24 +16516,13 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory( false, // requiresDedicatedAllocation false, // prefersDedicatedAllocation VK_NULL_HANDLE, // dedicatedBuffer - UINT32_MAX, // dedicatedBufferUsage VK_NULL_HANDLE, // dedicatedImage + UINT32_MAX, // dedicatedBufferImageUsage *pCreateInfo, VMA_SUBALLOCATION_TYPE_UNKNOWN, 1, // allocationCount pAllocation); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordAllocateMemory( - allocator->GetCurrentFrameIndex(), - *pVkMemoryRequirements, - *pCreateInfo, - *pAllocation); - } -#endif - if(pAllocationInfo != VMA_NULL && result == VK_SUCCESS) { allocator->GetAllocationInfo(*pAllocation, pAllocationInfo); @@ -16882,25 +16555,13 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryPages( false, // requiresDedicatedAllocation false, // prefersDedicatedAllocation VK_NULL_HANDLE, // dedicatedBuffer - UINT32_MAX, // dedicatedBufferUsage VK_NULL_HANDLE, // dedicatedImage + UINT32_MAX, // dedicatedBufferImageUsage *pCreateInfo, VMA_SUBALLOCATION_TYPE_UNKNOWN, allocationCount, pAllocations); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordAllocateMemoryPages( - allocator->GetCurrentFrameIndex(), - *pVkMemoryRequirements, - *pCreateInfo, - (uint64_t)allocationCount, - pAllocations); - } -#endif - if(pAllocationInfo != VMA_NULL && result == VK_SUCCESS) { for(size_t i = 0; i < allocationCount; ++i) @@ -16937,26 +16598,13 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForBuffer( requiresDedicatedAllocation, prefersDedicatedAllocation, buffer, // dedicatedBuffer - UINT32_MAX, // dedicatedBufferUsage VK_NULL_HANDLE, // dedicatedImage + UINT32_MAX, // dedicatedBufferImageUsage *pCreateInfo, VMA_SUBALLOCATION_TYPE_BUFFER, 1, // allocationCount pAllocation); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordAllocateMemoryForBuffer( - allocator->GetCurrentFrameIndex(), - vkMemReq, - requiresDedicatedAllocation, - prefersDedicatedAllocation, - *pCreateInfo, - *pAllocation); - } -#endif - if(pAllocationInfo && result == VK_SUCCESS) { allocator->GetAllocationInfo(*pAllocation, pAllocationInfo); @@ -16989,26 +16637,13 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemoryForImage( requiresDedicatedAllocation, prefersDedicatedAllocation, VK_NULL_HANDLE, // dedicatedBuffer - UINT32_MAX, // dedicatedBufferUsage image, // dedicatedImage + UINT32_MAX, // dedicatedBufferImageUsage *pCreateInfo, VMA_SUBALLOCATION_TYPE_IMAGE_UNKNOWN, 1, // allocationCount pAllocation); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordAllocateMemoryForImage( - allocator->GetCurrentFrameIndex(), - vkMemReq, - requiresDedicatedAllocation, - prefersDedicatedAllocation, - *pCreateInfo, - *pAllocation); - } -#endif - if(pAllocationInfo && result == VK_SUCCESS) { allocator->GetAllocationInfo(*pAllocation, pAllocationInfo); @@ -17032,15 +16667,6 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemory( VMA_DEBUG_GLOBAL_MUTEX_LOCK -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordFreeMemory( - allocator->GetCurrentFrameIndex(), - allocation); - } -#endif - allocator->FreeMemory( 1, // allocationCount &allocation); @@ -17062,16 +16688,6 @@ VMA_CALL_PRE void VMA_CALL_POST vmaFreeMemoryPages( VMA_DEBUG_GLOBAL_MUTEX_LOCK -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordFreeMemoryPages( - allocator->GetCurrentFrameIndex(), - (uint64_t)allocationCount, - pAllocations); - } -#endif - allocator->FreeMemory(allocationCount, pAllocations); } @@ -17084,38 +16700,9 @@ VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationInfo( VMA_DEBUG_GLOBAL_MUTEX_LOCK -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordGetAllocationInfo( - allocator->GetCurrentFrameIndex(), - allocation); - } -#endif - allocator->GetAllocationInfo(allocation, pAllocationInfo); } -VMA_CALL_PRE VkBool32 VMA_CALL_POST vmaTouchAllocation( - VmaAllocator allocator, - VmaAllocation allocation) -{ - VMA_ASSERT(allocator && allocation); - - VMA_DEBUG_GLOBAL_MUTEX_LOCK - -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordTouchAllocation( - allocator->GetCurrentFrameIndex(), - allocation); - } -#endif - - return allocator->TouchAllocation(allocation); -} - VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationUserData( VmaAllocator allocator, VmaAllocation allocation, @@ -17126,36 +16713,24 @@ VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationUserData( VMA_DEBUG_GLOBAL_MUTEX_LOCK allocation->SetUserData(allocator, pUserData); - -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordSetAllocationUserData( - allocator->GetCurrentFrameIndex(), - allocation, - pUserData); - } -#endif } -VMA_CALL_PRE void VMA_CALL_POST vmaCreateLostAllocation( - VmaAllocator allocator, - VmaAllocation* pAllocation) +VMA_CALL_PRE void VMA_CALL_POST vmaSetAllocationName( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + const char* VMA_NULLABLE pName) { - VMA_ASSERT(allocator && pAllocation); + allocation->SetName(allocator, pName); +} - VMA_DEBUG_GLOBAL_MUTEX_LOCK; - - allocator->CreateLostAllocation(pAllocation); - -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordCreateLostAllocation( - allocator->GetCurrentFrameIndex(), - *pAllocation); - } -#endif +VMA_CALL_PRE void VMA_CALL_POST vmaGetAllocationMemoryProperties( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + VkMemoryPropertyFlags* VMA_NOT_NULL pFlags) +{ + VMA_ASSERT(allocator && allocation && pFlags); + const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex(); + *pFlags = allocator->m_MemProps.memoryTypes[memTypeIndex].propertyFlags; } VMA_CALL_PRE VkResult VMA_CALL_POST vmaMapMemory( @@ -17167,18 +16742,7 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaMapMemory( VMA_DEBUG_GLOBAL_MUTEX_LOCK - VkResult res = allocator->Map(allocation, ppData); - -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordMapMemory( - allocator->GetCurrentFrameIndex(), - allocation); - } -#endif - - return res; + return allocator->Map(allocation, ppData); } VMA_CALL_PRE void VMA_CALL_POST vmaUnmapMemory( @@ -17189,19 +16753,14 @@ VMA_CALL_PRE void VMA_CALL_POST vmaUnmapMemory( VMA_DEBUG_GLOBAL_MUTEX_LOCK -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordUnmapMemory( - allocator->GetCurrentFrameIndex(), - allocation); - } -#endif - allocator->Unmap(allocation); } -VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size) +VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocation( + VmaAllocator allocator, + VmaAllocation allocation, + VkDeviceSize offset, + VkDeviceSize size) { VMA_ASSERT(allocator && allocation); @@ -17211,19 +16770,14 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocation(VmaAllocator allocator, V const VkResult res = allocator->FlushOrInvalidateAllocation(allocation, offset, size, VMA_CACHE_FLUSH); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordFlushAllocation( - allocator->GetCurrentFrameIndex(), - allocation, offset, size); - } -#endif - return res; } -VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocation(VmaAllocator allocator, VmaAllocation allocation, VkDeviceSize offset, VkDeviceSize size) +VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocation( + VmaAllocator allocator, + VmaAllocation allocation, + VkDeviceSize offset, + VkDeviceSize size) { VMA_ASSERT(allocator && allocation); @@ -17233,15 +16787,6 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocation(VmaAllocator allocat const VkResult res = allocator->FlushOrInvalidateAllocation(allocation, offset, size, VMA_CACHE_INVALIDATE); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordInvalidateAllocation( - allocator->GetCurrentFrameIndex(), - allocation, offset, size); - } -#endif - return res; } @@ -17267,13 +16812,6 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaFlushAllocations( const VkResult res = allocator->FlushOrInvalidateAllocations(allocationCount, allocations, offsets, sizes, VMA_CACHE_FLUSH); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - //TODO - } -#endif - return res; } @@ -17299,17 +16837,12 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaInvalidateAllocations( const VkResult res = allocator->FlushOrInvalidateAllocations(allocationCount, allocations, offsets, sizes, VMA_CACHE_INVALIDATE); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - //TODO - } -#endif - return res; } -VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption(VmaAllocator allocator, uint32_t memoryTypeBits) +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption( + VmaAllocator allocator, + uint32_t memoryTypeBits) { VMA_ASSERT(allocator); @@ -17320,139 +16853,70 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckCorruption(VmaAllocator allocator, u return allocator->CheckCorruption(memoryTypeBits); } -VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragment( +VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentation( VmaAllocator allocator, - const VmaAllocation* pAllocations, - size_t allocationCount, - VkBool32* pAllocationsChanged, - const VmaDefragmentationInfo *pDefragmentationInfo, - VmaDefragmentationStats* pDefragmentationStats) -{ - // Deprecated interface, reimplemented using new one. - - VmaDefragmentationInfo2 info2 = {}; - info2.allocationCount = (uint32_t)allocationCount; - info2.pAllocations = pAllocations; - info2.pAllocationsChanged = pAllocationsChanged; - if(pDefragmentationInfo != VMA_NULL) - { - info2.maxCpuAllocationsToMove = pDefragmentationInfo->maxAllocationsToMove; - info2.maxCpuBytesToMove = pDefragmentationInfo->maxBytesToMove; - } - else - { - info2.maxCpuAllocationsToMove = UINT32_MAX; - info2.maxCpuBytesToMove = VK_WHOLE_SIZE; - } - // info2.flags, maxGpuAllocationsToMove, maxGpuBytesToMove, commandBuffer deliberately left zero. - - VmaDefragmentationContext ctx; - VkResult res = vmaDefragmentationBegin(allocator, &info2, pDefragmentationStats, &ctx); - if(res == VK_NOT_READY) - { - res = vmaDefragmentationEnd( allocator, ctx); - } - return res; -} - -VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationBegin( - VmaAllocator allocator, - const VmaDefragmentationInfo2* pInfo, - VmaDefragmentationStats* pStats, - VmaDefragmentationContext *pContext) + const VmaDefragmentationInfo* pInfo, + VmaDefragmentationContext* pContext) { VMA_ASSERT(allocator && pInfo && pContext); - // Degenerate case: Nothing to defragment. - if(pInfo->allocationCount == 0 && pInfo->poolCount == 0) + VMA_DEBUG_LOG("vmaBeginDefragmentation"); + + if (pInfo->pool != VMA_NULL) { - return VK_SUCCESS; + // Check if run on supported algorithms + if (pInfo->pool->m_BlockVector.GetAlgorithm() & VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT) + return VK_ERROR_FEATURE_NOT_PRESENT; } - VMA_ASSERT(pInfo->allocationCount == 0 || pInfo->pAllocations != VMA_NULL); - VMA_ASSERT(pInfo->poolCount == 0 || pInfo->pPools != VMA_NULL); - VMA_HEAVY_ASSERT(VmaValidatePointerArray(pInfo->allocationCount, pInfo->pAllocations)); - VMA_HEAVY_ASSERT(VmaValidatePointerArray(pInfo->poolCount, pInfo->pPools)); - - VMA_DEBUG_LOG("vmaDefragmentationBegin"); - VMA_DEBUG_GLOBAL_MUTEX_LOCK - VkResult res = allocator->DefragmentationBegin(*pInfo, pStats, pContext); - -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordDefragmentationBegin( - allocator->GetCurrentFrameIndex(), *pInfo, *pContext); - } -#endif - - return res; + *pContext = vma_new(allocator, VmaDefragmentationContext_T)(allocator, *pInfo); + return VK_SUCCESS; } -VMA_CALL_PRE VkResult VMA_CALL_POST vmaDefragmentationEnd( +VMA_CALL_PRE void VMA_CALL_POST vmaEndDefragmentation( VmaAllocator allocator, - VmaDefragmentationContext context) + VmaDefragmentationContext context, + VmaDefragmentationStats* pStats) { - VMA_ASSERT(allocator); + VMA_ASSERT(allocator && context); - VMA_DEBUG_LOG("vmaDefragmentationEnd"); + VMA_DEBUG_LOG("vmaEndDefragmentation"); - if(context != VK_NULL_HANDLE) - { - VMA_DEBUG_GLOBAL_MUTEX_LOCK + VMA_DEBUG_GLOBAL_MUTEX_LOCK -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordDefragmentationEnd( - allocator->GetCurrentFrameIndex(), context); - } -#endif - - return allocator->DefragmentationEnd(context); - } - else - { - return VK_SUCCESS; - } + if (pStats) + context->GetStats(*pStats); + vma_delete(allocator, context); } VMA_CALL_PRE VkResult VMA_CALL_POST vmaBeginDefragmentationPass( - VmaAllocator allocator, - VmaDefragmentationContext context, - VmaDefragmentationPassInfo* pInfo - ) + VmaAllocator VMA_NOT_NULL allocator, + VmaDefragmentationContext VMA_NOT_NULL context, + VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo) { - VMA_ASSERT(allocator); - VMA_ASSERT(pInfo); + VMA_ASSERT(context && pPassInfo); VMA_DEBUG_LOG("vmaBeginDefragmentationPass"); VMA_DEBUG_GLOBAL_MUTEX_LOCK - if(context == VK_NULL_HANDLE) - { - pInfo->moveCount = 0; - return VK_SUCCESS; - } - - return allocator->DefragmentationPassBegin(pInfo, context); + return context->DefragmentPassBegin(*pPassInfo); } + VMA_CALL_PRE VkResult VMA_CALL_POST vmaEndDefragmentationPass( - VmaAllocator allocator, - VmaDefragmentationContext context) + VmaAllocator VMA_NOT_NULL allocator, + VmaDefragmentationContext VMA_NOT_NULL context, + VmaDefragmentationPassMoveInfo* VMA_NOT_NULL pPassInfo) { - VMA_ASSERT(allocator); + VMA_ASSERT(context && pPassInfo); VMA_DEBUG_LOG("vmaEndDefragmentationPass"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK - if(context == VK_NULL_HANDLE) - return VK_SUCCESS; - - return allocator->DefragmentationPassEnd(context); + return context->DefragmentPassEnd(*pPassInfo); } VMA_CALL_PRE VkResult VMA_CALL_POST vmaBindBufferMemory( @@ -17564,24 +17028,13 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBuffer( requiresDedicatedAllocation, prefersDedicatedAllocation, *pBuffer, // dedicatedBuffer - pBufferCreateInfo->usage, // dedicatedBufferUsage VK_NULL_HANDLE, // dedicatedImage + pBufferCreateInfo->usage, // dedicatedBufferImageUsage *pAllocationCreateInfo, VMA_SUBALLOCATION_TYPE_BUFFER, 1, // allocationCount pAllocation); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordCreateBuffer( - allocator->GetCurrentFrameIndex(), - *pBufferCreateInfo, - *pAllocationCreateInfo, - *pAllocation); - } -#endif - if(res >= 0) { // 3. Bind buffer with memory. @@ -17670,20 +17123,13 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment( requiresDedicatedAllocation, prefersDedicatedAllocation, *pBuffer, // dedicatedBuffer - pBufferCreateInfo->usage, // dedicatedBufferUsage VK_NULL_HANDLE, // dedicatedImage + pBufferCreateInfo->usage, // dedicatedBufferImageUsage *pAllocationCreateInfo, VMA_SUBALLOCATION_TYPE_BUFFER, 1, // allocationCount pAllocation); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - VMA_ASSERT(0 && "Not implemented."); - } -#endif - if(res >= 0) { // 3. Bind buffer with memory. @@ -17719,6 +17165,50 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateBufferWithAlignment( return res; } +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingBuffer( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + const VkBufferCreateInfo* VMA_NOT_NULL pBufferCreateInfo, + VkBuffer VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pBuffer) +{ + VMA_ASSERT(allocator && pBufferCreateInfo && pBuffer && allocation); + + VMA_DEBUG_LOG("vmaCreateAliasingBuffer"); + + *pBuffer = VK_NULL_HANDLE; + + if (pBufferCreateInfo->size == 0) + { + return VK_ERROR_INITIALIZATION_FAILED; + } + if ((pBufferCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_COPY) != 0 && + !allocator->m_UseKhrBufferDeviceAddress) + { + VMA_ASSERT(0 && "Creating a buffer with VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT is not valid if VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT was not used."); + return VK_ERROR_INITIALIZATION_FAILED; + } + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + // 1. Create VkBuffer. + VkResult res = (*allocator->GetVulkanFunctions().vkCreateBuffer)( + allocator->m_hDevice, + pBufferCreateInfo, + allocator->GetAllocationCallbacks(), + pBuffer); + if (res >= 0) + { + // 2. Bind buffer with memory. + res = allocator->BindBufferMemory(allocation, 0, *pBuffer, VMA_NULL); + if (res >= 0) + { + return VK_SUCCESS; + } + (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, *pBuffer, allocator->GetAllocationCallbacks()); + } + return res; +} + VMA_CALL_PRE void VMA_CALL_POST vmaDestroyBuffer( VmaAllocator allocator, VkBuffer buffer, @@ -17735,15 +17225,6 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyBuffer( VMA_DEBUG_GLOBAL_MUTEX_LOCK -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordDestroyBuffer( - allocator->GetCurrentFrameIndex(), - allocation); - } -#endif - if(buffer != VK_NULL_HANDLE) { (*allocator->GetVulkanFunctions().vkDestroyBuffer)(allocator->m_hDevice, buffer, allocator->GetAllocationCallbacks()); @@ -17807,24 +17288,13 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage( requiresDedicatedAllocation, prefersDedicatedAllocation, VK_NULL_HANDLE, // dedicatedBuffer - UINT32_MAX, // dedicatedBufferUsage *pImage, // dedicatedImage + pImageCreateInfo->usage, // dedicatedBufferImageUsage *pAllocationCreateInfo, suballocType, 1, // allocationCount pAllocation); -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordCreateImage( - allocator->GetCurrentFrameIndex(), - *pImageCreateInfo, - *pAllocationCreateInfo, - *pAllocation); - } -#endif - if(res >= 0) { // 3. Bind image with memory. @@ -17860,10 +17330,52 @@ VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateImage( return res; } +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateAliasingImage( + VmaAllocator VMA_NOT_NULL allocator, + VmaAllocation VMA_NOT_NULL allocation, + const VkImageCreateInfo* VMA_NOT_NULL pImageCreateInfo, + VkImage VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pImage) +{ + VMA_ASSERT(allocator && pImageCreateInfo && pImage && allocation); + + *pImage = VK_NULL_HANDLE; + + VMA_DEBUG_LOG("vmaCreateImage"); + + if (pImageCreateInfo->extent.width == 0 || + pImageCreateInfo->extent.height == 0 || + pImageCreateInfo->extent.depth == 0 || + pImageCreateInfo->mipLevels == 0 || + pImageCreateInfo->arrayLayers == 0) + { + return VK_ERROR_INITIALIZATION_FAILED; + } + + VMA_DEBUG_GLOBAL_MUTEX_LOCK + + // 1. Create VkImage. + VkResult res = (*allocator->GetVulkanFunctions().vkCreateImage)( + allocator->m_hDevice, + pImageCreateInfo, + allocator->GetAllocationCallbacks(), + pImage); + if (res >= 0) + { + // 2. Bind image with memory. + res = allocator->BindImageMemory(allocation, 0, *pImage, VMA_NULL); + if (res >= 0) + { + return VK_SUCCESS; + } + (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, *pImage, allocator->GetAllocationCallbacks()); + } + return res; +} + VMA_CALL_PRE void VMA_CALL_POST vmaDestroyImage( - VmaAllocator allocator, - VkImage image, - VmaAllocation allocation) + VmaAllocator VMA_NOT_NULL allocator, + VkImage VMA_NULLABLE_NON_DISPATCHABLE image, + VmaAllocation VMA_NULLABLE allocation) { VMA_ASSERT(allocator); @@ -17876,15 +17388,6 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyImage( VMA_DEBUG_GLOBAL_MUTEX_LOCK -#if VMA_RECORDING_ENABLED - if(allocator->GetRecorder() != VMA_NULL) - { - allocator->GetRecorder()->RecordDestroyImage( - allocator->GetCurrentFrameIndex(), - allocation); - } -#endif - if(image != VK_NULL_HANDLE) { (*allocator->GetVulkanFunctions().vkDestroyImage)(allocator->m_hDevice, image, allocator->GetAllocationCallbacks()); @@ -17897,7 +17400,134 @@ VMA_CALL_PRE void VMA_CALL_POST vmaDestroyImage( } } -#endif // #ifdef VMA_IMPLEMENTATION +VMA_CALL_PRE VkResult VMA_CALL_POST vmaCreateVirtualBlock( + const VmaVirtualBlockCreateInfo* VMA_NOT_NULL pCreateInfo, + VmaVirtualBlock VMA_NULLABLE * VMA_NOT_NULL pVirtualBlock) +{ + VMA_ASSERT(pCreateInfo && pVirtualBlock); + VMA_ASSERT(pCreateInfo->size > 0); + VMA_DEBUG_LOG("vmaCreateVirtualBlock"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + *pVirtualBlock = vma_new(pCreateInfo->pAllocationCallbacks, VmaVirtualBlock_T)(*pCreateInfo); + VkResult res = (*pVirtualBlock)->Init(); + if(res < 0) + { + vma_delete(pCreateInfo->pAllocationCallbacks, *pVirtualBlock); + *pVirtualBlock = VK_NULL_HANDLE; + } + return res; +} + +VMA_CALL_PRE void VMA_CALL_POST vmaDestroyVirtualBlock(VmaVirtualBlock VMA_NULLABLE virtualBlock) +{ + if(virtualBlock != VK_NULL_HANDLE) + { + VMA_DEBUG_LOG("vmaDestroyVirtualBlock"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + VkAllocationCallbacks allocationCallbacks = virtualBlock->m_AllocationCallbacks; // Have to copy the callbacks when destroying. + vma_delete(&allocationCallbacks, virtualBlock); + } +} + +VMA_CALL_PRE VkBool32 VMA_CALL_POST vmaIsVirtualBlockEmpty(VmaVirtualBlock VMA_NOT_NULL virtualBlock) +{ + VMA_ASSERT(virtualBlock != VK_NULL_HANDLE); + VMA_DEBUG_LOG("vmaIsVirtualBlockEmpty"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + return virtualBlock->IsEmpty() ? VK_TRUE : VK_FALSE; +} + +VMA_CALL_PRE void VMA_CALL_POST vmaGetVirtualAllocationInfo(VmaVirtualBlock VMA_NOT_NULL virtualBlock, + VmaVirtualAllocation VMA_NOT_NULL_NON_DISPATCHABLE allocation, VmaVirtualAllocationInfo* VMA_NOT_NULL pVirtualAllocInfo) +{ + VMA_ASSERT(virtualBlock != VK_NULL_HANDLE && pVirtualAllocInfo != VMA_NULL); + VMA_DEBUG_LOG("vmaGetVirtualAllocationInfo"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + virtualBlock->GetAllocationInfo(allocation, *pVirtualAllocInfo); +} + +VMA_CALL_PRE VkResult VMA_CALL_POST vmaVirtualAllocate(VmaVirtualBlock VMA_NOT_NULL virtualBlock, + const VmaVirtualAllocationCreateInfo* VMA_NOT_NULL pCreateInfo, VmaVirtualAllocation VMA_NULLABLE_NON_DISPATCHABLE* VMA_NOT_NULL pAllocation, + VkDeviceSize* VMA_NULLABLE pOffset) +{ + VMA_ASSERT(virtualBlock != VK_NULL_HANDLE && pCreateInfo != VMA_NULL && pAllocation != VMA_NULL); + VMA_DEBUG_LOG("vmaVirtualAllocate"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + return virtualBlock->Allocate(*pCreateInfo, *pAllocation, pOffset); +} + +VMA_CALL_PRE void VMA_CALL_POST vmaVirtualFree(VmaVirtualBlock VMA_NOT_NULL virtualBlock, VmaVirtualAllocation VMA_NULLABLE_NON_DISPATCHABLE allocation) +{ + if(allocation != VK_NULL_HANDLE) + { + VMA_ASSERT(virtualBlock != VK_NULL_HANDLE); + VMA_DEBUG_LOG("vmaVirtualFree"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + virtualBlock->Free(allocation); + } +} + +VMA_CALL_PRE void VMA_CALL_POST vmaClearVirtualBlock(VmaVirtualBlock VMA_NOT_NULL virtualBlock) +{ + VMA_ASSERT(virtualBlock != VK_NULL_HANDLE); + VMA_DEBUG_LOG("vmaClearVirtualBlock"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + virtualBlock->Clear(); +} + +VMA_CALL_PRE void VMA_CALL_POST vmaSetVirtualAllocationUserData(VmaVirtualBlock VMA_NOT_NULL virtualBlock, + VmaVirtualAllocation VMA_NOT_NULL_NON_DISPATCHABLE allocation, void* VMA_NULLABLE pUserData) +{ + VMA_ASSERT(virtualBlock != VK_NULL_HANDLE); + VMA_DEBUG_LOG("vmaSetVirtualAllocationUserData"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + virtualBlock->SetAllocationUserData(allocation, pUserData); +} + +VMA_CALL_PRE void VMA_CALL_POST vmaGetVirtualBlockStatistics(VmaVirtualBlock VMA_NOT_NULL virtualBlock, + VmaStatistics* VMA_NOT_NULL pStats) +{ + VMA_ASSERT(virtualBlock != VK_NULL_HANDLE && pStats != VMA_NULL); + VMA_DEBUG_LOG("vmaGetVirtualBlockStatistics"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + virtualBlock->GetStatistics(*pStats); +} + +VMA_CALL_PRE void VMA_CALL_POST vmaCalculateVirtualBlockStatistics(VmaVirtualBlock VMA_NOT_NULL virtualBlock, + VmaDetailedStatistics* VMA_NOT_NULL pStats) +{ + VMA_ASSERT(virtualBlock != VK_NULL_HANDLE && pStats != VMA_NULL); + VMA_DEBUG_LOG("vmaCalculateVirtualBlockStatistics"); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + virtualBlock->CalculateDetailedStatistics(*pStats); +} + +#if VMA_STATS_STRING_ENABLED + +VMA_CALL_PRE void VMA_CALL_POST vmaBuildVirtualBlockStatsString(VmaVirtualBlock VMA_NOT_NULL virtualBlock, + char* VMA_NULLABLE * VMA_NOT_NULL ppStatsString, VkBool32 detailedMap) +{ + VMA_ASSERT(virtualBlock != VK_NULL_HANDLE && ppStatsString != VMA_NULL); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + const VkAllocationCallbacks* allocationCallbacks = virtualBlock->GetAllocationCallbacks(); + VmaStringBuilder sb(allocationCallbacks); + virtualBlock->BuildStatsString(detailedMap != VK_FALSE, sb); + *ppStatsString = VmaCreateStringCopy(allocationCallbacks, sb.GetData(), sb.GetLength()); +} + +VMA_CALL_PRE void VMA_CALL_POST vmaFreeVirtualBlockStatsString(VmaVirtualBlock VMA_NOT_NULL virtualBlock, + char* VMA_NULLABLE pStatsString) +{ + if(pStatsString != VMA_NULL) + { + VMA_ASSERT(virtualBlock != VK_NULL_HANDLE); + VMA_DEBUG_GLOBAL_MUTEX_LOCK; + VmaFreeString(virtualBlock->GetAllocationCallbacks(), pStatsString); + } +} +#endif // VMA_STATS_STRING_ENABLED +#endif // _VMA_PUBLIC_INTERFACE +#endif // VMA_IMPLEMENTATION /** \page quick_start Quick start @@ -17927,24 +17557,16 @@ To do it properly: It may be a good idea to create dedicated CPP file just for this purpose. -Note on language: This library is written in C++, but has C-compatible interface. -Thus you can include and use vk_mem_alloc.h in C or C++ code, but full -implementation with `VMA_IMPLEMENTATION` macro must be compiled as C++, NOT as C. - -Please note that this library includes header ``, which in turn +This library includes header ``, which in turn includes `` on Windows. If you need some specific macros defined before including these headers (like `WIN32_LEAN_AND_MEAN` or `WINVER` for Windows, `VK_USE_PLATFORM_WIN32_KHR` for Vulkan), you must define them before every `#include` of this library. -You may need to configure the way you import Vulkan functions. - -- By default, VMA assumes you you link statically with Vulkan API. If this is not the case, - `#define VMA_STATIC_VULKAN_FUNCTIONS 0` before `#include` of the VMA implementation and use another way. -- You can `#define VMA_DYNAMIC_VULKAN_FUNCTIONS 1` and make sure `vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` globals are defined. - All the remaining Vulkan functions will be fetched automatically. -- Finally, you can provide your own pointers to all Vulkan functions needed by VMA using structure member - VmaAllocatorCreateInfo::pVulkanFunctions, if you fetched them in some custom way e.g. using some loader like [Volk](https://github.com/zeux/volk). +This library is written in C++, but has C-compatible interface. +Thus you can include and use vk_mem_alloc.h in C or C++ code, but full +implementation with `VMA_IMPLEMENTATION` macro must be compiled as C++, NOT as C. +Some features of C++14 used. STL containers, RTTI, or C++ exceptions are not used. \section quick_start_initialization Initialization @@ -17955,23 +17577,44 @@ At program startup: -# Fill VmaAllocatorCreateInfo structure and create #VmaAllocator object by calling vmaCreateAllocator(). -\code -VmaAllocatorCreateInfo allocatorInfo = {}; -allocatorInfo.vulkanApiVersion = VK_API_VERSION_1_2; -allocatorInfo.physicalDevice = physicalDevice; -allocatorInfo.device = device; -allocatorInfo.instance = instance; - -VmaAllocator allocator; -vmaCreateAllocator(&allocatorInfo, &allocator); -\endcode - Only members `physicalDevice`, `device`, `instance` are required. However, you should inform the library which Vulkan version do you use by setting VmaAllocatorCreateInfo::vulkanApiVersion and which extensions did you enable by setting VmaAllocatorCreateInfo::flags (like #VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT for VK_KHR_buffer_device_address). Otherwise, VMA would use only features of Vulkan 1.0 core with no extensions. +You may need to configure importing Vulkan functions. There are 3 ways to do this: + +-# **If you link with Vulkan static library** (e.g. "vulkan-1.lib" on Windows): + - You don't need to do anything. + - VMA will use these, as macro `VMA_STATIC_VULKAN_FUNCTIONS` is defined to 1 by default. +-# **If you want VMA to fetch pointers to Vulkan functions dynamically** using `vkGetInstanceProcAddr`, + `vkGetDeviceProcAddr` (this is the option presented in the example below): + - Define `VMA_STATIC_VULKAN_FUNCTIONS` to 0, `VMA_DYNAMIC_VULKAN_FUNCTIONS` to 1. + - Provide pointers to these two functions via VmaVulkanFunctions::vkGetInstanceProcAddr, + VmaVulkanFunctions::vkGetDeviceProcAddr. + - The library will fetch pointers to all other functions it needs internally. +-# **If you fetch pointers to all Vulkan functions in a custom way**, e.g. using some loader like + [Volk](https://github.com/zeux/volk): + - Define `VMA_STATIC_VULKAN_FUNCTIONS` and `VMA_DYNAMIC_VULKAN_FUNCTIONS` to 0. + - Pass these pointers via structure #VmaVulkanFunctions. + +\code +VmaVulkanFunctions vulkanFunctions = {}; +vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr; +vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr; + +VmaAllocatorCreateInfo allocatorCreateInfo = {}; +allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2; +allocatorCreateInfo.physicalDevice = physicalDevice; +allocatorCreateInfo.device = device; +allocatorCreateInfo.instance = instance; +allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions; + +VmaAllocator allocator; +vmaCreateAllocator(&allocatorCreateInfo, &allocator); +\endcode + \section quick_start_resource_allocation Resource allocation @@ -17980,7 +17623,7 @@ When you want to create a buffer or image: -# Fill `VkBufferCreateInfo` / `VkImageCreateInfo` structure. -# Fill VmaAllocationCreateInfo structure. -# Call vmaCreateBuffer() / vmaCreateImage() to get `VkBuffer`/`VkImage` with memory - already allocated and bound to it. + already allocated and bound to it, plus #VmaAllocation objects that represents its underlying memory. \code VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; @@ -17988,7 +17631,7 @@ bufferInfo.size = 65536; bufferInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; VmaAllocationCreateInfo allocInfo = {}; -allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; +allocInfo.usage = VMA_MEMORY_USAGE_AUTO; VkBuffer buffer; VmaAllocation allocation; @@ -18012,8 +17655,8 @@ appropriate members of VmaAllocationCreateInfo structure, as described below. You can also combine multiple methods. -# If you just want to find memory type index that meets your requirements, you - can use function: vmaFindMemoryTypeIndex(), vmaFindMemoryTypeIndexForBufferInfo(), - vmaFindMemoryTypeIndexForImageInfo(). + can use function: vmaFindMemoryTypeIndexForBufferInfo(), + vmaFindMemoryTypeIndexForImageInfo(), vmaFindMemoryTypeIndex(). -# If you want to allocate a region of device memory without association with any specific image or buffer, you can use function vmaAllocateMemory(). Usage of this function is not recommended and usually not needed. @@ -18024,9 +17667,10 @@ You can also combine multiple methods. vmaAllocateMemoryForBuffer(), vmaAllocateMemoryForImage(). For binding you should use functions: vmaBindBufferMemory(), vmaBindImageMemory() or their extended versions: vmaBindBufferMemory2(), vmaBindImageMemory2(). --# If you want to create a buffer or an image, allocate memory for it and bind +-# **This is the easiest and recommended way to use this library:** + If you want to create a buffer or an image, allocate memory for it and bind them together, all in one call, you can use function vmaCreateBuffer(), - vmaCreateImage(). This is the easiest and recommended way to use this library. + vmaCreateImage(). When using 3. or 4., the library internally queries Vulkan for memory types supported for that buffer or image (function `vkGetBufferMemoryRequirements()`) @@ -18044,11 +17688,12 @@ It is valid, although not very useful. The easiest way to specify memory requirements is to fill member VmaAllocationCreateInfo::usage using one of the values of enum #VmaMemoryUsage. It defines high level, common usage types. -For more details, see description of this enum. +Since version 3 of the library, it is recommended to use #VMA_MEMORY_USAGE_AUTO to let it select best memory type for your resource automatically. For example, if you want to create a uniform buffer that will be filled using -transfer only once or infrequently and used for rendering every frame, you can -do it using following code: +transfer only once or infrequently and then used for rendering every frame as a uniform buffer, you can +do it using following code. The buffer will most likely end up in a memory type with +`VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT` to be fast to access by the GPU device. \code VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; @@ -18056,13 +17701,56 @@ bufferInfo.size = 65536; bufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; VmaAllocationCreateInfo allocInfo = {}; -allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; +allocInfo.usage = VMA_MEMORY_USAGE_AUTO; VkBuffer buffer; VmaAllocation allocation; vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); \endcode +If you have a preference for putting the resource in GPU (device) memory or CPU (host) memory +on systems with discrete graphics card that have the memories separate, you can use +#VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE or #VMA_MEMORY_USAGE_AUTO_PREFER_HOST. + +When using `VMA_MEMORY_USAGE_AUTO*` while you want to map the allocated memory, +you also need to specify one of the host access flags: +#VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT. +This will help the library decide about preferred memory type to ensure it has `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` +so you can map it. + +For example, a staging buffer that will be filled via mapped pointer and then +used as a source of transfer to the buffer decribed previously can be created like this. +It will likely and up in a memory type that is `HOST_VISIBLE` and `HOST_COHERENT` +but not `HOST_CACHED` (meaning uncached, write-combined) and not `DEVICE_LOCAL` (meaning system RAM). + +\code +VkBufferCreateInfo stagingBufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +stagingBufferInfo.size = 65536; +stagingBufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + +VmaAllocationCreateInfo stagingAllocInfo = {}; +stagingAllocInfo.usage = VMA_MEMORY_USAGE_AUTO; +stagingAllocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; + +VkBuffer stagingBuffer; +VmaAllocation stagingAllocation; +vmaCreateBuffer(allocator, &stagingBufferInfo, &stagingAllocInfo, &stagingBuffer, &stagingAllocation, nullptr); +\endcode + +For more examples of creating different kinds of resources, see chapter \ref usage_patterns. + +Usage values `VMA_MEMORY_USAGE_AUTO*` are legal to use only when the library knows +about the resource being created by having `VkBufferCreateInfo` / `VkImageCreateInfo` passed, +so they work with functions like: vmaCreateBuffer(), vmaCreateImage(), vmaFindMemoryTypeIndexForBufferInfo() etc. +If you allocate raw memory using function vmaAllocateMemory(), you have to use other means of selecting +memory type, as decribed below. + +\note +Old usage values (`VMA_MEMORY_USAGE_GPU_ONLY`, `VMA_MEMORY_USAGE_CPU_ONLY`, +`VMA_MEMORY_USAGE_CPU_TO_GPU`, `VMA_MEMORY_USAGE_GPU_TO_CPU`, `VMA_MEMORY_USAGE_CPU_COPY`) +are still available and work same way as in previous versions of the library +for backward compatibility, but they are not recommended. + \section choosing_memory_type_required_preferred_flags Required and preferred flags You can specify more detailed requirements by filling members @@ -18076,7 +17764,7 @@ use following code: VmaAllocationCreateInfo allocInfo = {}; allocInfo.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; allocInfo.preferredFlags = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; -allocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; +allocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; VkBuffer buffer; VmaAllocation allocation; @@ -18086,8 +17774,8 @@ vmaCreateBuffer(allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullpt A memory type is chosen that has all the required flags and as many preferred flags set as possible. -If you use VmaAllocationCreateInfo::usage, it is just internally converted to -a set of required and preferred flags. +Value passed in VmaAllocationCreateInfo::usage is internally converted to a set of required and preferred flags, +plus some extra "magic" (heuristics). \section choosing_memory_type_explicit_memory_types Explicit memory types @@ -18154,6 +17842,13 @@ Mapping the same `VkDeviceMemory` block multiple times is illegal - only one map This includes mapping disjoint regions. Mapping is not reference-counted internally by Vulkan. Because of this, Vulkan Memory Allocator provides following facilities: +\note If you want to be able to map an allocation, you need to specify one of the flags +#VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT +in VmaAllocationCreateInfo::flags. These flags are required for an allocation to be mappable +when using #VMA_MEMORY_USAGE_AUTO or other `VMA_MEMORY_USAGE_AUTO*` enum values. +For other usage values they are ignored and every such allocation made in `HOST_VISIBLE` memory type is mappable, +but they can still be used for consistency. + \section memory_mapping_mapping_functions Mapping functions The library provides following functions for mapping of a specific #VmaAllocation: vmaMapMemory(), vmaUnmapMemory(). @@ -18166,16 +17861,15 @@ Example: \code // Having these objects initialized: - struct ConstantBuffer { ... }; -ConstantBuffer constantBufferData; +ConstantBuffer constantBufferData = ... -VmaAllocator allocator; -VkBuffer constantBuffer; -VmaAllocation constantBufferAllocation; +VmaAllocator allocator = ... +VkBuffer constantBuffer = ... +VmaAllocation constantBufferAllocation = ... // You can map and fill your buffer using following code: @@ -18212,8 +17906,9 @@ bufCreateInfo.size = sizeof(ConstantBuffer); bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY; -allocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; +allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; +allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | + VMA_ALLOCATION_CREATE_MAPPED_BIT; VkBuffer buf; VmaAllocation alloc; @@ -18224,18 +17919,12 @@ vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allo memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData)); \endcode -There are some exceptions though, when you should consider mapping memory only for a short period of time: - -- When operating system is Windows 7 or 8.x (Windows 10 is not affected because it uses WDDM2), - device is discrete AMD GPU, - and memory type is the special 256 MiB pool of `DEVICE_LOCAL + HOST_VISIBLE` memory - (selected when you use #VMA_MEMORY_USAGE_CPU_TO_GPU), - then whenever a memory block allocated from this memory type stays mapped - for the time of any call to `vkQueueSubmit()` or `vkQueuePresentKHR()`, this - block is migrated by WDDM to system RAM, which degrades performance. It doesn't - matter if that particular memory block is actually used by the command buffer - being submitted. -- Keeping many large memory blocks mapped may impact performance or stability of some debugging tools. +\note #VMA_ALLOCATION_CREATE_MAPPED_BIT by itself doesn't guarantee that the allocation will end up +in a mappable memory type. +For this, you need to also specify #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT or +#VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT. +#VMA_ALLOCATION_CREATE_MAPPED_BIT only guarantees that if the memory is `HOST_VISIBLE`, the allocation will be mapped on creation. +For an example of how to make use of this fact, see section \ref usage_patterns_advanced_data_uploading. \section memory_mapping_cache_control Cache flush and invalidate @@ -18256,87 +17945,9 @@ In any memory type that is `HOST_VISIBLE` but not `HOST_COHERENT`, all allocatio within blocks are aligned to this value, so their offsets are always multiply of `nonCoherentAtomSize` and two different allocations never share same "line" of this size. -Please note that memory allocated with #VMA_MEMORY_USAGE_CPU_ONLY is guaranteed to be `HOST_COHERENT`. - -Also, Windows drivers from all 3 **PC** GPU vendors (AMD, Intel, NVIDIA) +Also, Windows drivers from all 3 PC GPU vendors (AMD, Intel, NVIDIA) currently provide `HOST_COHERENT` flag on all memory types that are -`HOST_VISIBLE`, so on this platform you may not need to bother. - -\section memory_mapping_finding_if_memory_mappable Finding out if memory is mappable - -It may happen that your allocation ends up in memory that is `HOST_VISIBLE` (available for mapping) -despite it wasn't explicitly requested. -For example, application may work on integrated graphics with unified memory (like Intel) or -allocation from video memory might have failed, so the library chose system memory as fallback. - -You can detect this case and map such allocation to access its memory on CPU directly, -instead of launching a transfer operation. -In order to do that: inspect `allocInfo.memoryType`, call vmaGetMemoryTypeProperties(), -and look for `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` flag in properties of that memory type. - -\code -VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -bufCreateInfo.size = sizeof(ConstantBuffer); -bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - -VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; -allocCreateInfo.preferredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT; - -VkBuffer buf; -VmaAllocation alloc; -VmaAllocationInfo allocInfo; -vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); - -VkMemoryPropertyFlags memFlags; -vmaGetMemoryTypeProperties(allocator, allocInfo.memoryType, &memFlags); -if((memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) -{ - // Allocation ended up in mappable memory. You can map it and access it directly. - void* mappedData; - vmaMapMemory(allocator, alloc, &mappedData); - memcpy(mappedData, &constantBufferData, sizeof(constantBufferData)); - vmaUnmapMemory(allocator, alloc); -} -else -{ - // Allocation ended up in non-mappable memory. - // You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer. -} -\endcode - -You can even use #VMA_ALLOCATION_CREATE_MAPPED_BIT flag while creating allocations -that are not necessarily `HOST_VISIBLE` (e.g. using #VMA_MEMORY_USAGE_GPU_ONLY). -If the allocation ends up in memory type that is `HOST_VISIBLE`, it will be persistently mapped and you can use it directly. -If not, the flag is just ignored. -Example: - -\code -VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -bufCreateInfo.size = sizeof(ConstantBuffer); -bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - -VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; -allocCreateInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT; - -VkBuffer buf; -VmaAllocation alloc; -VmaAllocationInfo allocInfo; -vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); - -if(allocInfo.pMappedData != nullptr) -{ - // Allocation ended up in mappable memory. - // It is persistently mapped. You can access it directly. - memcpy(allocInfo.pMappedData, &constantBufferData, sizeof(constantBufferData)); -} -else -{ - // Allocation ended up in non-mappable memory. - // You need to create CPU-side buffer in VMA_MEMORY_USAGE_CPU_ONLY and make a transfer. -} -\endcode +`HOST_VISIBLE`, so on PC you may not need to bother. \page staying_within_budget Staying within budget @@ -18357,12 +17968,12 @@ operating system: \section staying_within_budget_querying_for_budget Querying for budget -To query for current memory usage and available budget, use function vmaGetBudget(). +To query for current memory usage and available budget, use function vmaGetHeapBudgets(). Returned structure #VmaBudget contains quantities expressed in bytes, per Vulkan memory heap. Please note that this function returns different information and works faster than -vmaCalculateStats(). vmaGetBudget() can be called every frame or even before every -allocation, while vmaCalculateStats() is intended to be used rarely, +vmaCalculateStatistics(). vmaGetHeapBudgets() can be called every frame or even before every +allocation, while vmaCalculateStatistics() is intended to be used rarely, only to obtain statistical information, e.g. for debugging purposes. It is recommended to use VK_EXT_memory_budget device extension to obtain information @@ -18392,22 +18003,27 @@ budget, by default the library still tries to create it, leaving it to the Vulka implementation whether the allocation succeeds or fails. You can change this behavior by using #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag. With it, the allocation is not made if it would exceed the budget or if the budget is already exceeded. -Some other allocations become lost instead to make room for it, if the mechanism of -[lost allocations](@ref lost_allocations) is used. -If that is not possible, the allocation fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`. +VMA then tries to make the allocation from the next eligible Vulkan memory type. +The all of them fail, the call then fails with `VK_ERROR_OUT_OF_DEVICE_MEMORY`. Example usage pattern may be to pass the #VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT flag when creating resources that are not essential for the application (e.g. the texture of a specific object) and not to pass it when creating critically important resources (e.g. render targets). +On AMD graphics cards there is a custom vendor extension available: VK_AMD_memory_overallocation_behavior +that allows to control the behavior of the Vulkan implementation in out-of-memory cases - +whether it should fail with an error code or still allow the allocation. +Usage of this extension involves only passing extra structure on Vulkan device creation, +so it is out of scope of this library. + Finally, you can also use #VMA_ALLOCATION_CREATE_NEVER_ALLOCATE_BIT flag to make sure a new allocation is created only when it fits inside one of the existing memory blocks. If it would require to allocate a new block, if fails instead with `VK_ERROR_OUT_OF_DEVICE_MEMORY`. This also ensures that the function call is very fast because it never goes to Vulkan to obtain a new block. -Please note that creating \ref custom_memory_pools with VmaPoolCreateInfo::minBlockCount -set to more than 0 will try to allocate memory blocks without checking whether they +\note Creating \ref custom_memory_pools with VmaPoolCreateInfo::minBlockCount +set to more than 0 will currently try to allocate memory blocks without checking whether they fit within budget. @@ -18481,7 +18097,7 @@ finalMemReq.memoryTypeBits = img1MemReq.memoryTypeBits & img2MemReq.memoryTypeBi // Validate if(finalMemReq.memoryTypeBits != 0) VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; +allocCreateInfo.preferredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; VmaAllocation alloc; res = vmaAllocateMemory(allocator, &finalMemReq, &allocCreateInfo, &alloc, nullptr); @@ -18510,7 +18126,7 @@ See chapter 11.8. "Memory Aliasing" of Vulkan specification or `VK_IMAGE_CREATE_ - You can create more complex layout where different images and buffers are bound at different offsets inside one large allocation. For example, one can imagine a big texture used in some render passes, aliasing with a set of many small buffers -used between in some further passes. To bind a resource at non-zero offset of an allocation, +used between in some further passes. To bind a resource at non-zero offset in an allocation, use vmaBindBufferMemory2() / vmaBindImageMemory2(). - Before allocating memory for the resources you want to alias, check `memoryTypeBits` returned in memory requirements of each resource to make sure the bits overlap. @@ -18535,6 +18151,7 @@ It can be useful if you want to: - Reserve minimum or fixed amount of Vulkan memory always preallocated for that pool. - Use extra parameters for a set of your allocations that are available in #VmaPoolCreateInfo but not in #VmaAllocationCreateInfo - e.g., custom minimum alignment, custom `pNext` chain. +- Perform defragmentation on a specific subset of your allocations. To use custom memory pools: @@ -18546,14 +18163,28 @@ To use custom memory pools: Example: \code +// Find memoryTypeIndex for the pool. +VkBufferCreateInfo sampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +sampleBufCreateInfo.size = 0x10000; // Doesn't matter. +sampleBufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + +VmaAllocationCreateInfo sampleAllocCreateInfo = {}; +sampleAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; + +uint32_t memTypeIndex; +VkResult res = vmaFindMemoryTypeIndexForBufferInfo(allocator, + &sampleBufCreateInfo, &sampleAllocCreateInfo, &memTypeIndex); +// Check res... + // Create a pool that can have at most 2 blocks, 128 MiB each. VmaPoolCreateInfo poolCreateInfo = {}; -poolCreateInfo.memoryTypeIndex = ... +poolCreateInfo.memoryTypeIndex = memTypeIndex; poolCreateInfo.blockSize = 128ull * 1024 * 1024; poolCreateInfo.maxBlockCount = 2; VmaPool pool; -vmaCreatePool(allocator, &poolCreateInfo, &pool); +res = vmaCreatePool(allocator, &poolCreateInfo, &pool); +// Check res... // Allocate a buffer out of it. VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; @@ -18565,8 +18196,8 @@ allocCreateInfo.pool = pool; VkBuffer buf; VmaAllocation alloc; -VmaAllocationInfo allocInfo; -vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); +res = vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, nullptr); +// Check res... \endcode You have to free all allocations made from this pool before destroying it. @@ -18576,6 +18207,19 @@ vmaDestroyBuffer(allocator, buf, alloc); vmaDestroyPool(allocator, pool); \endcode +New versions of this library support creating dedicated allocations in custom pools. +It is supported only when VmaPoolCreateInfo::blockSize = 0. +To use this feature, set VmaAllocationCreateInfo::pool to the pointer to your custom pool and +VmaAllocationCreateInfo::flags to #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. + +\note Excessive use of custom pools is a common mistake when using this library. +Custom pools may be useful for special purposes - when you want to +keep certain type of resources separate e.g. to reserve minimum amount of memory +for them or limit maximum amount of memory they can occupy. For most +resources this is not needed and so it is not recommended to create #VmaPool +objects and allocations out of them. Allocating from the default pool is sufficient. + + \section custom_memory_pools_MemTypeIndex Choosing memory type index When creating a pool, you must explicitly specify memory type index. @@ -18586,11 +18230,11 @@ that you are going to create in that pool. \code VkBufferCreateInfo exampleBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -exampleBufCreateInfo.size = 1024; // Whatever. -exampleBufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; // Change if needed. +exampleBufCreateInfo.size = 1024; // Doesn't matter +exampleBufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; // Change if needed. +allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; uint32_t memTypeIndex; vmaFindMemoryTypeIndexForBufferInfo(allocator, &exampleBufCreateInfo, &allocCreateInfo, &memTypeIndex); @@ -18630,6 +18274,7 @@ less memory consumed by metadata. With this one flag, you can create a custom pool that can be used in many ways: free-at-once, stack, double stack, and ring buffer. See below for details. +You don't need to specify explicitly which of these options you are going to use - it is detected automatically. \subsection linear_algorithm_free_at_once Free-at-once @@ -18665,7 +18310,7 @@ stacks: - First, default one, growing up from offset 0. - Second, "upper" one, growing down from the end towards lower offsets. -To make allocation from upper stack, add flag #VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT +To make allocation from the upper stack, add flag #VMA_ALLOCATION_CREATE_UPPER_ADDRESS_BIT to VmaAllocationCreateInfo::flags. ![Double stack](../gfx/Linear_allocator_7_double_stack.png) @@ -18687,52 +18332,11 @@ you can achieve behavior of a ring buffer / queue. ![Ring buffer](../gfx/Linear_allocator_5_ring_buffer.png) -Pools with linear algorithm support [lost allocations](@ref lost_allocations) when used as ring buffer. -If there is not enough free space for a new allocation, but existing allocations -from the front of the queue can become lost, they become lost and the allocation -succeeds. - -![Ring buffer with lost allocations](../gfx/Linear_allocator_6_ring_buffer_lost.png) - Ring buffer is available only in pools with one memory block - VmaPoolCreateInfo::maxBlockCount must be 1. Otherwise behavior is undefined. -\section buddy_algorithm Buddy allocation algorithm +\note \ref defragmentation is not supported in custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT. -There is another allocation algorithm that can be used with custom pools, called -"buddy". Its internal data structure is based on a tree of blocks, each having -size that is a power of two and a half of its parent's size. When you want to -allocate memory of certain size, a free node in the tree is located. If it is too -large, it is recursively split into two halves (called "buddies"). However, if -requested allocation size is not a power of two, the size of a tree node is -aligned up to the nearest power of two and the remaining space is wasted. When -two buddy nodes become free, they are merged back into one larger node. - -![Buddy allocator](../gfx/Buddy_allocator.png) - -The advantage of buddy allocation algorithm over default algorithm is faster -allocation and deallocation, as well as smaller external fragmentation. The -disadvantage is more wasted space (internal fragmentation). - -For more information, please read ["Buddy memory allocation" on Wikipedia](https://en.wikipedia.org/wiki/Buddy_memory_allocation) -or other sources that describe this concept in general. - -To use buddy allocation algorithm with a custom pool, add flag -#VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT to VmaPoolCreateInfo::flags while creating -#VmaPool object. - -Several limitations apply to pools that use buddy algorithm: - -- It is recommended to use VmaPoolCreateInfo::blockSize that is a power of two. - Otherwise, only largest power of two smaller than the size is used for - allocations. The remaining space always stays unused. -- [Margins](@ref debugging_memory_usage_margins) and - [corruption detection](@ref debugging_memory_usage_corruption_detection) - don't work in such pools. -- [Lost allocations](@ref lost_allocations) don't work in such pools. You can - use them, but they never become lost. Support may be added in the future. -- [Defragmentation](@ref defragmentation) doesn't work with allocations made from - such pool. \page defragmentation Defragmentation @@ -18742,354 +18346,185 @@ to find a continuous range of free memory for a new allocation despite there is enough free space, just scattered across many small free ranges between existing allocations. -To mitigate this problem, you can use defragmentation feature: -structure #VmaDefragmentationInfo2, function vmaDefragmentationBegin(), vmaDefragmentationEnd(). -Given set of allocations, -this function can move them to compact used memory, ensure more continuous free -space and possibly also free some `VkDeviceMemory` blocks. - -What the defragmentation does is: - -- Updates #VmaAllocation objects to point to new `VkDeviceMemory` and offset. - After allocation has been moved, its VmaAllocationInfo::deviceMemory and/or - VmaAllocationInfo::offset changes. You must query them again using - vmaGetAllocationInfo() if you need them. -- Moves actual data in memory. - -What it doesn't do, so you need to do it yourself: - -- Recreate buffers and images that were bound to allocations that were defragmented and - bind them with their new places in memory. - You must use `vkDestroyBuffer()`, `vkDestroyImage()`, - `vkCreateBuffer()`, `vkCreateImage()`, vmaBindBufferMemory(), vmaBindImageMemory() - for that purpose and NOT vmaDestroyBuffer(), - vmaDestroyImage(), vmaCreateBuffer(), vmaCreateImage(), because you don't need to - destroy or create allocation objects! -- Recreate views and update descriptors that point to these buffers and images. - -\section defragmentation_cpu Defragmenting CPU memory - -Following example demonstrates how you can run defragmentation on CPU. -Only allocations created in memory types that are `HOST_VISIBLE` can be defragmented. -Others are ignored. - -The way it works is: - -- It temporarily maps entire memory blocks when necessary. -- It moves data using `memmove()` function. - -\code -// Given following variables already initialized: -VkDevice device; -VmaAllocator allocator; -std::vector buffers; -std::vector allocations; - - -const uint32_t allocCount = (uint32_t)allocations.size(); -std::vector allocationsChanged(allocCount); - -VmaDefragmentationInfo2 defragInfo = {}; -defragInfo.allocationCount = allocCount; -defragInfo.pAllocations = allocations.data(); -defragInfo.pAllocationsChanged = allocationsChanged.data(); -defragInfo.maxCpuBytesToMove = VK_WHOLE_SIZE; // No limit. -defragInfo.maxCpuAllocationsToMove = UINT32_MAX; // No limit. - -VmaDefragmentationContext defragCtx; -vmaDefragmentationBegin(allocator, &defragInfo, nullptr, &defragCtx); -vmaDefragmentationEnd(allocator, defragCtx); - -for(uint32_t i = 0; i < allocCount; ++i) -{ - if(allocationsChanged[i]) - { - // Destroy buffer that is immutably bound to memory region which is no longer valid. - vkDestroyBuffer(device, buffers[i], nullptr); - - // Create new buffer with same parameters. - VkBufferCreateInfo bufferInfo = ...; - vkCreateBuffer(device, &bufferInfo, nullptr, &buffers[i]); - - // You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning. - - // Bind new buffer to new memory region. Data contained in it is already moved. - VmaAllocationInfo allocInfo; - vmaGetAllocationInfo(allocator, allocations[i], &allocInfo); - vmaBindBufferMemory(allocator, allocations[i], buffers[i]); - } -} -\endcode - -Setting VmaDefragmentationInfo2::pAllocationsChanged is optional. -This output array tells whether particular allocation in VmaDefragmentationInfo2::pAllocations at the same index -has been modified during defragmentation. -You can pass null, but you then need to query every allocation passed to defragmentation -for new parameters using vmaGetAllocationInfo() if you might need to recreate and rebind a buffer or image associated with it. - -If you use [Custom memory pools](@ref choosing_memory_type_custom_memory_pools), -you can fill VmaDefragmentationInfo2::poolCount and VmaDefragmentationInfo2::pPools -instead of VmaDefragmentationInfo2::allocationCount and VmaDefragmentationInfo2::pAllocations -to defragment all allocations in given pools. -You cannot use VmaDefragmentationInfo2::pAllocationsChanged in that case. -You can also combine both methods. - -\section defragmentation_gpu Defragmenting GPU memory - -It is also possible to defragment allocations created in memory types that are not `HOST_VISIBLE`. -To do that, you need to pass a command buffer that meets requirements as described in -VmaDefragmentationInfo2::commandBuffer. The way it works is: - -- It creates temporary buffers and binds them to entire memory blocks when necessary. -- It issues `vkCmdCopyBuffer()` to passed command buffer. +To mitigate this problem, you can use defragmentation feature. +It doesn't happen automatically though and needs your cooperation, +because VMA is a low level library that only allocates memory. +It cannot recreate buffers and images in a new place as it doesn't remember the contents of `VkBufferCreateInfo` / `VkImageCreateInfo` structures. +It cannot copy their contents as it doesn't record any commands to a command buffer. Example: \code -// Given following variables already initialized: -VkDevice device; -VmaAllocator allocator; -VkCommandBuffer commandBuffer; -std::vector buffers; -std::vector allocations; - - -const uint32_t allocCount = (uint32_t)allocations.size(); -std::vector allocationsChanged(allocCount); - -VkCommandBufferBeginInfo cmdBufBeginInfo = ...; -vkBeginCommandBuffer(commandBuffer, &cmdBufBeginInfo); - -VmaDefragmentationInfo2 defragInfo = {}; -defragInfo.allocationCount = allocCount; -defragInfo.pAllocations = allocations.data(); -defragInfo.pAllocationsChanged = allocationsChanged.data(); -defragInfo.maxGpuBytesToMove = VK_WHOLE_SIZE; // Notice it is "GPU" this time. -defragInfo.maxGpuAllocationsToMove = UINT32_MAX; // Notice it is "GPU" this time. -defragInfo.commandBuffer = commandBuffer; +VmaDefragmentationInfo defragInfo = {}; +defragInfo.pool = myPool; +defragInfo.flags = VMA_DEFRAGMENTATION_FLAG_ALGORITHM_FAST_BIT; VmaDefragmentationContext defragCtx; -vmaDefragmentationBegin(allocator, &defragInfo, nullptr, &defragCtx); +VkResult res = vmaBeginDefragmentation(allocator, &defragInfo, &defragCtx); +// Check res... -vkEndCommandBuffer(commandBuffer); - -// Submit commandBuffer. -// Wait for a fence that ensures commandBuffer execution finished. - -vmaDefragmentationEnd(allocator, defragCtx); - -for(uint32_t i = 0; i < allocCount; ++i) +for(;;) { - if(allocationsChanged[i]) + VmaDefragmentationPassMoveInfo pass; + res = vmaBeginDefragmentationPass(allocator, defragCtx, &pass); + if(res == VK_SUCCESS) + break; + else if(res != VK_INCOMPLETE) + // Handle error... + + for(uint32_t i = 0; i < pass.moveCount; ++i) { - // Destroy buffer that is immutably bound to memory region which is no longer valid. - vkDestroyBuffer(device, buffers[i], nullptr); - - // Create new buffer with same parameters. - VkBufferCreateInfo bufferInfo = ...; - vkCreateBuffer(device, &bufferInfo, nullptr, &buffers[i]); - - // You can make dummy call to vkGetBufferMemoryRequirements here to silence validation layer warning. - - // Bind new buffer to new memory region. Data contained in it is already moved. + // Inspect pass.pMoves[i].srcAllocation, identify what buffer/image it represents. VmaAllocationInfo allocInfo; - vmaGetAllocationInfo(allocator, allocations[i], &allocInfo); - vmaBindBufferMemory(allocator, allocations[i], buffers[i]); + vmaGetAllocationInfo(allocator, pMoves[i].srcAllocation, &allocInfo); + MyEngineResourceData* resData = (MyEngineResourceData*)allocInfo.pUserData; + + // Recreate and bind this buffer/image at: pass.pMoves[i].dstMemory, pass.pMoves[i].dstOffset. + VkImageCreateInfo imgCreateInfo = ... + VkImage newImg; + res = vkCreateImage(device, &imgCreateInfo, nullptr, &newImg); + // Check res... + res = vmaBindImageMemory(allocator, pMoves[i].dstTmpAllocation, newImg); + // Check res... + + // Issue a vkCmdCopyBuffer/vkCmdCopyImage to copy its content to the new place. + vkCmdCopyImage(cmdBuf, resData->img, ..., newImg, ...); } -} -\endcode + + // Make sure the copy commands finished executing. + vkWaitForFences(...); -You can combine these two methods by specifying non-zero `maxGpu*` as well as `maxCpu*` parameters. -The library automatically chooses best method to defragment each memory pool. - -You may try not to block your entire program to wait until defragmentation finishes, -but do it in the background, as long as you carefully fullfill requirements described -in function vmaDefragmentationBegin(). - -\section defragmentation_additional_notes Additional notes - -It is only legal to defragment allocations bound to: - -- buffers -- images created with `VK_IMAGE_CREATE_ALIAS_BIT`, `VK_IMAGE_TILING_LINEAR`, and - being currently in `VK_IMAGE_LAYOUT_GENERAL` or `VK_IMAGE_LAYOUT_PREINITIALIZED`. - -Defragmentation of images created with `VK_IMAGE_TILING_OPTIMAL` or in any other -layout may give undefined results. - -If you defragment allocations bound to images, new images to be bound to new -memory region after defragmentation should be created with `VK_IMAGE_LAYOUT_PREINITIALIZED` -and then transitioned to their original layout from before defragmentation if -needed using an image memory barrier. - -While using defragmentation, you may experience validation layer warnings, which you just need to ignore. -See [Validation layer warnings](@ref general_considerations_validation_layer_warnings). - -Please don't expect memory to be fully compacted after defragmentation. -Algorithms inside are based on some heuristics that try to maximize number of Vulkan -memory blocks to make totally empty to release them, as well as to maximize continuous -empty space inside remaining blocks, while minimizing the number and size of allocations that -need to be moved. Some fragmentation may still remain - this is normal. - -\section defragmentation_custom_algorithm Writing custom defragmentation algorithm - -If you want to implement your own, custom defragmentation algorithm, -there is infrastructure prepared for that, -but it is not exposed through the library API - you need to hack its source code. -Here are steps needed to do this: - --# Main thing you need to do is to define your own class derived from base abstract - class `VmaDefragmentationAlgorithm` and implement your version of its pure virtual methods. - See definition and comments of this class for details. --# Your code needs to interact with device memory block metadata. - If you need more access to its data than it is provided by its public interface, - declare your new class as a friend class e.g. in class `VmaBlockMetadata_Generic`. --# If you want to create a flag that would enable your algorithm or pass some additional - flags to configure it, add them to `VmaDefragmentationFlagBits` and use them in - VmaDefragmentationInfo2::flags. --# Modify function `VmaBlockVectorDefragmentationContext::Begin` to create object - of your new class whenever needed. - - -\page lost_allocations Lost allocations - -If your game oversubscribes video memory, if may work OK in previous-generation -graphics APIs (DirectX 9, 10, 11, OpenGL) because resources are automatically -paged to system RAM. In Vulkan you can't do it because when you run out of -memory, an allocation just fails. If you have more data (e.g. textures) that can -fit into VRAM and you don't need it all at once, you may want to upload them to -GPU on demand and "push out" ones that are not used for a long time to make room -for the new ones, effectively using VRAM (or a cartain memory pool) as a form of -cache. Vulkan Memory Allocator can help you with that by supporting a concept of -"lost allocations". - -To create an allocation that can become lost, include #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT -flag in VmaAllocationCreateInfo::flags. Before using a buffer or image bound to -such allocation in every new frame, you need to query it if it is not lost. -To check it, call vmaTouchAllocation(). -If the allocation is lost, you should not use it or buffer/image bound to it. -You mustn't forget to destroy this allocation and this buffer/image. -vmaGetAllocationInfo() can also be used for checking status of the allocation. -Allocation is lost when returned VmaAllocationInfo::deviceMemory == `VK_NULL_HANDLE`. - -To create an allocation that can make some other allocations lost to make room -for it, use #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag. You will -usually use both flags #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT and -#VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT at the same time. - -Warning! Current implementation uses quite naive, brute force algorithm, -which can make allocation calls that use #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT -flag quite slow. A new, more optimal algorithm and data structure to speed this -up is planned for the future. - -Q: When interleaving creation of new allocations with usage of existing ones, -how do you make sure that an allocation won't become lost while it is used in the -current frame? - -It is ensured because vmaTouchAllocation() / vmaGetAllocationInfo() not only returns allocation -status/parameters and checks whether it is not lost, but when it is not, it also -atomically marks it as used in the current frame, which makes it impossible to -become lost in that frame. It uses lockless algorithm, so it works fast and -doesn't involve locking any internal mutex. - -Q: What if my allocation may still be in use by the GPU when it is rendering a -previous frame while I already submit new frame on the CPU? - -You can make sure that allocations "touched" by vmaTouchAllocation() / vmaGetAllocationInfo() will not -become lost for a number of additional frames back from the current one by -specifying this number as VmaAllocatorCreateInfo::frameInUseCount (for default -memory pool) and VmaPoolCreateInfo::frameInUseCount (for custom pool). - -Q: How do you inform the library when new frame starts? - -You need to call function vmaSetCurrentFrameIndex(). - -Example code: - -\code -struct MyBuffer -{ - VkBuffer m_Buf = nullptr; - VmaAllocation m_Alloc = nullptr; - - // Called when the buffer is really needed in the current frame. - void EnsureBuffer(); -}; - -void MyBuffer::EnsureBuffer() -{ - // Buffer has been created. - if(m_Buf != VK_NULL_HANDLE) + // Destroy old buffers/images bound with pass.pMoves[i].srcAllocation. + for(uint32_t i = 0; i < pass.moveCount; ++i) { - // Check if its allocation is not lost + mark it as used in current frame. - if(vmaTouchAllocation(allocator, m_Alloc)) - { - // It is all OK - safe to use m_Buf. - return; - } + // ... + vkDestroyImage(device, resData->img, nullptr); } - // Buffer not yet exists or lost - destroy and recreate it. - - vmaDestroyBuffer(allocator, m_Buf, m_Alloc); - - VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; - bufCreateInfo.size = 1024; - bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; - - VmaAllocationCreateInfo allocCreateInfo = {}; - allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; - allocCreateInfo.flags = VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT | - VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT; - - vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &m_Buf, &m_Alloc, nullptr); + // Update appropriate descriptors to point to the new places... + + res = vmaEndDefragmentationPass(allocator, defragCtx, &pass); + if(res == VK_SUCCESS) + break; + else if(res != VK_INCOMPLETE) + // Handle error... } + +vmaEndDefragmentation(allocator, defragCtx, nullptr); \endcode -When using lost allocations, you may see some Vulkan validation layer warnings -about overlapping regions of memory bound to different kinds of buffers and -images. This is still valid as long as you implement proper handling of lost -allocations (like in the example above) and don't use them. +Although functions like vmaCreateBuffer(), vmaCreateImage(), vmaDestroyBuffer(), vmaDestroyImage() +create/destroy an allocation and a buffer/image at once, these are just a shortcut for +creating the resource, allocating memory, and binding them together. +Defragmentation works on memory allocations only. You must handle the rest manually. +Defragmentation is an iterative process that should repreat "passes" as long as related functions +return `VK_INCOMPLETE` not `VK_SUCCESS`. +In each pass: -You can create an allocation that is already in lost state from the beginning using function -vmaCreateLostAllocation(). It may be useful if you need a "dummy" allocation that is not null. +1. vmaBeginDefragmentationPass() function call: + - Calculates and returns the list of allocations to be moved in this pass. + Note this can be a time-consuming process. + - Reserves destination memory for them by creating temporary destination allocations + that you can query for their `VkDeviceMemory` + offset using vmaGetAllocationInfo(). +2. Inside the pass, **you should**: + - Inspect the returned list of allocations to be moved. + - Create new buffers/images and bind them at the returned destination temporary allocations. + - Copy data from source to destination resources if necessary. + - Destroy the source buffers/images, but NOT their allocations. +3. vmaEndDefragmentationPass() function call: + - Frees the source memory reserved for the allocations that are moved. + - Modifies source #VmaAllocation objects that are moved to point to the destination reserved memory. + - Frees `VkDeviceMemory` blocks that became empty. -You can call function vmaMakePoolAllocationsLost() to set all eligible allocations -in a specified custom pool to lost state. -Allocations that have been "touched" in current frame or VmaPoolCreateInfo::frameInUseCount frames back -cannot become lost. +Unlike in previous iterations of the defragmentation API, there is no list of "movable" allocations passed as a parameter. +Defragmentation algorithm tries to move all suitable allocations. +You can, however, refuse to move some of them inside a defragmentation pass, by setting +`pass.pMoves[i].operation` to #VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE. +This is not recommended and may result in suboptimal packing of the allocations after defragmentation. +If you cannot ensure any allocation can be moved, it is better to keep movable allocations separate in a custom pool. -Q: Can I touch allocation that cannot become lost? +Inside a pass, for each allocation that should be moved: -Yes, although it has no visible effect. -Calls to vmaGetAllocationInfo() and vmaTouchAllocation() update last use frame index -also for allocations that cannot become lost, but the only way to observe it is to dump -internal allocator state using vmaBuildStatsString(). -You can use this feature for debugging purposes to explicitly mark allocations that you use -in current frame and then analyze JSON dump to see for how long each allocation stays unused. +- You should copy its data from the source to the destination place by calling e.g. `vkCmdCopyBuffer()`, `vkCmdCopyImage()`. + - You need to make sure these commands finished executing before destroying the source buffers/images and before calling vmaEndDefragmentationPass(). +- If a resource doesn't contain any meaningful data, e.g. it is a transient color attachment image to be cleared, + filled, and used temporarily in each rendering frame, you can just recreate this image + without copying its data. +- If the resource is in `HOST_VISIBLE` and `HOST_CACHED` memory, you can copy its data on the CPU + using `memcpy()`. +- If you cannot move the allocation, you can set `pass.pMoves[i].operation` to #VMA_DEFRAGMENTATION_MOVE_OPERATION_IGNORE. + This will cancel the move. + - vmaEndDefragmentationPass() will then free the destination memory + not the source memory of the allocation, leaving it unchanged. +- If you decide the allocation is unimportant and can be destroyed instead of moved (e.g. it wasn't used for long time), + you can set `pass.pMoves[i].operation` to #VMA_DEFRAGMENTATION_MOVE_OPERATION_DESTROY. + - vmaEndDefragmentationPass() will then free both source and destination memory, and will destroy the source #VmaAllocation object. + +You can defragment a specific custom pool by setting VmaDefragmentationInfo::pool +(like in the example above) or all the default pools by setting this member to null. + +Defragmentation is always performed in each pool separately. +Allocations are never moved between different Vulkan memory types. +The size of the destination memory reserved for a moved allocation is the same as the original one. +Alignment of an allocation as it was determined using `vkGetBufferMemoryRequirements()` etc. is also respected after defragmentation. +Buffers/images should be recreated with the same `VkBufferCreateInfo` / `VkImageCreateInfo` parameters as the original ones. + +You can perform the defragmentation incrementally to limit the number of allocations and bytes to be moved +in each pass, e.g. to call it in sync with render frames and not to experience too big hitches. +See members: VmaDefragmentationInfo::maxBytesPerPass, VmaDefragmentationInfo::maxAllocationsPerPass. + +It is also safe to perform the defragmentation asynchronously to render frames and other Vulkan and VMA +usage, possibly from multiple threads, with the exception that allocations +returned in VmaDefragmentationPassMoveInfo::pMoves shouldn't be destroyed until the defragmentation pass is ended. + +Mapping is preserved on allocations that are moved during defragmentation. +Whether through #VMA_ALLOCATION_CREATE_MAPPED_BIT or vmaMapMemory(), the allocations +are mapped at their new place. Of course, pointer to the mapped data changes, so it needs to be queried +using VmaAllocationInfo::pMappedData. + +\note Defragmentation is not supported in custom pools created with #VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT. \page statistics Statistics -This library contains functions that return information about its internal state, +This library contains several functions that return information about its internal state, especially the amount of memory allocated from Vulkan. -Please keep in mind that these functions need to traverse all internal data structures -to gather these information, so they may be quite time-consuming. -Don't call them too often. \section statistics_numeric_statistics Numeric statistics -You can query for overall statistics of the allocator using function vmaCalculateStats(). -Information are returned using structure #VmaStats. -It contains #VmaStatInfo - number of allocated blocks, number of allocations -(occupied ranges in these blocks), number of unused (free) ranges in these blocks, -number of bytes used and unused (but still allocated from Vulkan) and other information. -They are summed across memory heaps, memory types and total for whole allocator. +If you need to obtain basic statistics about memory usage per heap, together with current budget, +you can call function vmaGetHeapBudgets() and inspect structure #VmaBudget. +This is useful to keep track of memory usage and stay withing budget +(see also \ref staying_within_budget). +Example: -You can query for statistics of a custom pool using function vmaGetPoolStats(). -Information are returned using structure #VmaPoolStats. +\code +uint32_t heapIndex = ... -You can query for information about specific allocation using function vmaGetAllocationInfo(). +VmaBudget budgets[VK_MAX_MEMORY_HEAPS]; +vmaGetHeapBudgets(allocator, budgets); + +printf("My heap currently has %u allocations taking %llu B,\n", + budgets[heapIndex].statistics.allocationCount, + budgets[heapIndex].statistics.allocationBytes); +printf("allocated out of %u Vulkan device memory blocks taking %llu B,\n", + budgets[heapIndex].statistics.blockCount, + budgets[heapIndex].statistics.blockBytes); +printf("Vulkan reports total usage %llu B with budget %llu B.\n", + budgets[heapIndex].usage, + budgets[heapIndex].budget); +\endcode + +You can query for more detailed statistics per memory heap, type, and totals, +including minimum and maximum allocation size and unused range size, +by calling function vmaCalculateStatistics() and inspecting structure #VmaTotalStatistics. +This function is slower though, as it has to traverse all the internal data structures, +so it should be used only for debugging purposes. + +You can query for statistics of a custom pool using function vmaGetPoolStatistics() +or vmaCalculatePoolStatistics(). + +You can query for information about a specific allocation using function vmaGetAllocationInfo(). It fill structure #VmaAllocationInfo. \section statistics_json_dump JSON dump @@ -19106,7 +18541,7 @@ The format of this JSON string is not part of official documentation of the libr but it will not change in backward-incompatible way without increasing library major version number and appropriate mention in changelog. -The JSON string contains all the data that can be obtained using vmaCalculateStats(). +The JSON string contains all the data that can be obtained using vmaCalculateStatistics(). It can also contain detailed map of allocated memory blocks and their regions - free and occupied by allocations. This allows e.g. to visualize the memory or assess fragmentation. @@ -19121,20 +18556,21 @@ To do that, fill VmaAllocationCreateInfo::pUserData field when creating an allocation. It is an opaque `void*` pointer. You can use it e.g. as a pointer, some handle, index, key, ordinal number or any other value that would associate the allocation with your custom metadata. +It it useful to identify appropriate data structures in your engine given #VmaAllocation, +e.g. when doing \ref defragmentation. \code -VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; -// Fill bufferInfo... +VkBufferCreateInfo bufCreateInfo = ... MyBufferMetadata* pMetadata = CreateBufferMetadata(); VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; +allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; allocCreateInfo.pUserData = pMetadata; VkBuffer buffer; VmaAllocation allocation; -vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, nullptr); +vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buffer, &allocation, nullptr); \endcode The pointer may be later retrieved as VmaAllocationInfo::pUserData: @@ -19148,50 +18584,190 @@ MyBufferMetadata* pMetadata = (MyBufferMetadata*)allocInfo.pUserData; It can also be changed using function vmaSetAllocationUserData(). Values of (non-zero) allocations' `pUserData` are printed in JSON report created by -vmaBuildStatsString(), in hexadecimal form. +vmaBuildStatsString() in hexadecimal form. \section allocation_names Allocation names -There is alternative mode available where `pUserData` pointer is used to point to -a null-terminated string, giving a name to the allocation. To use this mode, -set #VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT flag in VmaAllocationCreateInfo::flags. -Then `pUserData` passed as VmaAllocationCreateInfo::pUserData or argument to -vmaSetAllocationUserData() must be either null or pointer to a null-terminated string. +An allocation can also carry a null-terminated string, giving a name to the allocation. +To set it, call vmaSetAllocationName(). The library creates internal copy of the string, so the pointer you pass doesn't need to be valid for whole lifetime of the allocation. You can free it after the call. \code -VkImageCreateInfo imageInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; -// Fill imageInfo... - std::string imageName = "Texture: "; imageName += fileName; - -VmaAllocationCreateInfo allocCreateInfo = {}; -allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; -allocCreateInfo.flags = VMA_ALLOCATION_CREATE_USER_DATA_COPY_STRING_BIT; -allocCreateInfo.pUserData = imageName.c_str(); - -VkImage image; -VmaAllocation allocation; -vmaCreateImage(allocator, &imageInfo, &allocCreateInfo, &image, &allocation, nullptr); +vmaSetAllocationName(allocator, allocation, imageName.c_str()); \endcode -The value of `pUserData` pointer of the allocation will be different than the one -you passed when setting allocation's name - pointing to a buffer managed -internally that holds copy of the string. +The string can be later retrieved by inspecting VmaAllocationInfo::pName. +It is also printed in JSON report created by vmaBuildStatsString(). + +\note Setting string name to VMA allocation doesn't automatically set it to the Vulkan buffer or image created with it. +You must do it manually using an extension like VK_EXT_debug_utils, which is independent of this library. + + +\page virtual_allocator Virtual allocator + +As an extra feature, the core allocation algorithm of the library is exposed through a simple and convenient API of "virtual allocator". +It doesn't allocate any real GPU memory. It just keeps track of used and free regions of a "virtual block". +You can use it to allocate your own memory or other objects, even completely unrelated to Vulkan. +A common use case is sub-allocation of pieces of one large GPU buffer. + +\section virtual_allocator_creating_virtual_block Creating virtual block + +To use this functionality, there is no main "allocator" object. +You don't need to have #VmaAllocator object created. +All you need to do is to create a separate #VmaVirtualBlock object for each block of memory you want to be managed by the allocator: + +-# Fill in #VmaVirtualBlockCreateInfo structure. +-# Call vmaCreateVirtualBlock(). Get new #VmaVirtualBlock object. + +Example: \code -VmaAllocationInfo allocInfo; -vmaGetAllocationInfo(allocator, allocation, &allocInfo); -const char* imageName = (const char*)allocInfo.pUserData; -printf("Image name: %s\n", imageName); +VmaVirtualBlockCreateInfo blockCreateInfo = {}; +blockCreateInfo.size = 1048576; // 1 MB + +VmaVirtualBlock block; +VkResult res = vmaCreateVirtualBlock(&blockCreateInfo, &block); \endcode -That string is also printed in JSON report created by vmaBuildStatsString(). +\section virtual_allocator_making_virtual_allocations Making virtual allocations -\note Passing string name to VMA allocation doesn't automatically set it to the Vulkan buffer or image created with it. -You must do it manually using an extension like VK_EXT_debug_utils, which is independent of this library. +#VmaVirtualBlock object contains internal data structure that keeps track of free and occupied regions +using the same code as the main Vulkan memory allocator. +Similarly to #VmaAllocation for standard GPU allocations, there is #VmaVirtualAllocation type +that represents an opaque handle to an allocation withing the virtual block. + +In order to make such allocation: + +-# Fill in #VmaVirtualAllocationCreateInfo structure. +-# Call vmaVirtualAllocate(). Get new #VmaVirtualAllocation object that represents the allocation. + You can also receive `VkDeviceSize offset` that was assigned to the allocation. + +Example: + +\code +VmaVirtualAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.size = 4096; // 4 KB + +VmaVirtualAllocation alloc; +VkDeviceSize offset; +res = vmaVirtualAllocate(block, &allocCreateInfo, &alloc, &offset); +if(res == VK_SUCCESS) +{ + // Use the 4 KB of your memory starting at offset. +} +else +{ + // Allocation failed - no space for it could be found. Handle this error! +} +\endcode + +\section virtual_allocator_deallocation Deallocation + +When no longer needed, an allocation can be freed by calling vmaVirtualFree(). +You can only pass to this function an allocation that was previously returned by vmaVirtualAllocate() +called for the same #VmaVirtualBlock. + +When whole block is no longer needed, the block object can be released by calling vmaDestroyVirtualBlock(). +All allocations must be freed before the block is destroyed, which is checked internally by an assert. +However, if you don't want to call vmaVirtualFree() for each allocation, you can use vmaClearVirtualBlock() to free them all at once - +a feature not available in normal Vulkan memory allocator. Example: + +\code +vmaVirtualFree(block, alloc); +vmaDestroyVirtualBlock(block); +\endcode + +\section virtual_allocator_allocation_parameters Allocation parameters + +You can attach a custom pointer to each allocation by using vmaSetVirtualAllocationUserData(). +Its default value is null. +It can be used to store any data that needs to be associated with that allocation - e.g. an index, a handle, or a pointer to some +larger data structure containing more information. Example: + +\code +struct CustomAllocData +{ + std::string m_AllocName; +}; +CustomAllocData* allocData = new CustomAllocData(); +allocData->m_AllocName = "My allocation 1"; +vmaSetVirtualAllocationUserData(block, alloc, allocData); +\endcode + +The pointer can later be fetched, along with allocation offset and size, by passing the allocation handle to function +vmaGetVirtualAllocationInfo() and inspecting returned structure #VmaVirtualAllocationInfo. +If you allocated a new object to be used as the custom pointer, don't forget to delete that object before freeing the allocation! +Example: + +\code +VmaVirtualAllocationInfo allocInfo; +vmaGetVirtualAllocationInfo(block, alloc, &allocInfo); +delete (CustomAllocData*)allocInfo.pUserData; + +vmaVirtualFree(block, alloc); +\endcode + +\section virtual_allocator_alignment_and_units Alignment and units + +It feels natural to express sizes and offsets in bytes. +If an offset of an allocation needs to be aligned to a multiply of some number (e.g. 4 bytes), you can fill optional member +VmaVirtualAllocationCreateInfo::alignment to request it. Example: + +\code +VmaVirtualAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.size = 4096; // 4 KB +allocCreateInfo.alignment = 4; // Returned offset must be a multiply of 4 B + +VmaVirtualAllocation alloc; +res = vmaVirtualAllocate(block, &allocCreateInfo, &alloc, nullptr); +\endcode + +Alignments of different allocations made from one block may vary. +However, if all alignments and sizes are always multiply of some size e.g. 4 B or `sizeof(MyDataStruct)`, +you can express all sizes, alignments, and offsets in multiples of that size instead of individual bytes. +It might be more convenient, but you need to make sure to use this new unit consistently in all the places: + +- VmaVirtualBlockCreateInfo::size +- VmaVirtualAllocationCreateInfo::size and VmaVirtualAllocationCreateInfo::alignment +- Using offset returned by vmaVirtualAllocate() or in VmaVirtualAllocationInfo::offset + +\section virtual_allocator_statistics Statistics + +You can obtain statistics of a virtual block using vmaGetVirtualBlockStatistics() +(to get brief statistics that are fast to calculate) +or vmaCalculateVirtualBlockStatistics() (to get more detailed statistics, slower to calculate). +The functions fill structures #VmaStatistics, #VmaDetailedStatistics respectively - same as used by the normal Vulkan memory allocator. +Example: + +\code +VmaStatistics stats; +vmaGetVirtualBlockStatistics(block, &stats); +printf("My virtual block has %llu bytes used by %u virtual allocations\n", + stats.allocationBytes, stats.allocationCount); +\endcode + +You can also request a full list of allocations and free regions as a string in JSON format by calling +vmaBuildVirtualBlockStatsString(). +Returned string must be later freed using vmaFreeVirtualBlockStatsString(). +The format of this string differs from the one returned by the main Vulkan allocator, but it is similar. + +\section virtual_allocator_additional_considerations Additional considerations + +The "virtual allocator" functionality is implemented on a level of individual memory blocks. +Keeping track of a whole collection of blocks, allocating new ones when out of free space, +deleting empty ones, and deciding which one to try first for a new allocation must be implemented by the user. + +Alternative allocation algorithms are supported, just like in custom pools of the real GPU memory. +See enum #VmaVirtualBlockCreateFlagBits to learn how to specify them (e.g. #VMA_VIRTUAL_BLOCK_CREATE_LINEAR_ALGORITHM_BIT). +You can find their description in chapter \ref custom_memory_pools. +Allocation strategies are also supported. +See enum #VmaVirtualAllocationCreateFlagBits to learn how to specify them (e.g. #VMA_VIRTUAL_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT). + +Following features are supported only by the allocator of the real GPU memory and not by virtual allocations: +buffer-image granularity, `VMA_DEBUG_MARGIN`, `VMA_MIN_ALIGNMENT`. \page debugging_memory_usage Debugging incorrect memory usage @@ -19211,17 +18787,15 @@ To do it, define macro `VMA_DEBUG_INITIALIZE_ALLOCATIONS` to 1. #include "vk_mem_alloc.h" \endcode -It makes memory of all new allocations initialized to bit pattern `0xDCDCDCDC`. +It makes memory of new allocations initialized to bit pattern `0xDCDCDCDC`. Before an allocation is destroyed, its memory is filled with bit pattern `0xEFEFEFEF`. Memory is automatically mapped and unmapped if necessary. If you find these values while debugging your program, good chances are that you incorrectly read Vulkan memory that is allocated but not initialized, or already freed, respectively. -Memory initialization works only with memory types that are `HOST_VISIBLE`. +Memory initialization works only with memory types that are `HOST_VISIBLE` and with allocations that can be mapped. It works also with dedicated allocations. -It doesn't work with allocations created with #VMA_ALLOCATION_CREATE_CAN_BECOME_LOST_BIT flag, -as they cannot be mapped. \section debugging_memory_usage_margins Margins @@ -19231,7 +18805,7 @@ By default, allocations are laid out in memory blocks next to each other if poss ![Allocations without margin](../gfx/Margins_1.png) Define macro `VMA_DEBUG_MARGIN` to some non-zero value (e.g. 16) to enforce specified -number of bytes as a margin before and after every allocation. +number of bytes as a margin after every allocation. \code #define VMA_DEBUG_MARGIN 16 @@ -19245,9 +18819,6 @@ being overwritten outside of allocation boundaries. It is not 100% certain thoug Change in application behavior may also be caused by different order and distribution of allocations across memory blocks after margins are applied. -The margin is applied also before first and after last allocation in a block. -It may occur only once between two adjacent allocations. - Margins work with all types of memory. Margin is applied only to allocations made out of memory blocks and not to dedicated @@ -19255,12 +18826,13 @@ allocations, which have their own memory block of specific size. It is thus not applied to allocations made using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT flag or those automatically decided to put into dedicated allocations, e.g. due to its large size or recommended by VK_KHR_dedicated_allocation extension. -Margins are also not active in custom pools created with #VMA_POOL_CREATE_BUDDY_ALGORITHM_BIT flag. Margins appear in [JSON dump](@ref statistics_json_dump) as part of free space. Note that enabling margins increases memory usage and fragmentation. +Margins do not apply to \ref virtual_allocator. + \section debugging_memory_usage_corruption_detection Corruption detection You can additionally define macro `VMA_DEBUG_DETECT_CORRUPTION` to 1 to enable validation @@ -19273,7 +18845,7 @@ of contents of the margins. \endcode When this feature is enabled, number of bytes specified as `VMA_DEBUG_MARGIN` -(it must be multiply of 4) before and after every allocation is filled with a magic number. +(it must be multiply of 4) after every allocation is filled with a magic number. This idea is also know as "canary". Memory is automatically mapped and unmapped if necessary. @@ -19291,58 +18863,6 @@ Margin validation (corruption detection) works only for memory types that are `HOST_VISIBLE` and `HOST_COHERENT`. -\page record_and_replay Record and replay - -\section record_and_replay_introduction Introduction - -While using the library, sequence of calls to its functions together with their -parameters can be recorded to a file and later replayed using standalone player -application. It can be useful to: - -- Test correctness - check if same sequence of calls will not cause crash or - failures on a target platform. -- Gather statistics - see number of allocations, peak memory usage, number of - calls etc. -- Benchmark performance - see how much time it takes to replay the whole - sequence. - -\section record_and_replay_usage Usage - -Recording functionality is disabled by default. -To enable it, define following macro before every include of this library: - -\code -#define VMA_RECORDING_ENABLED 1 -\endcode - -To record sequence of calls to a file: Fill in -VmaAllocatorCreateInfo::pRecordSettings member while creating #VmaAllocator -object. File is opened and written during whole lifetime of the allocator. - -To replay file: Use VmaReplay - standalone command-line program. -Precompiled binary can be found in "bin" directory. -Its source can be found in "src/VmaReplay" directory. -Its project is generated by Premake. -Command line syntax is printed when the program is launched without parameters. -Basic usage: - - VmaReplay.exe MyRecording.csv - -Documentation of file format can be found in file: "docs/Recording file format.md". -It is a human-readable, text file in CSV format (Comma Separated Values). - -\section record_and_replay_additional_considerations Additional considerations - -- Replaying file that was recorded on a different GPU (with different parameters - like `bufferImageGranularity`, `nonCoherentAtomSize`, and especially different - set of memory heaps and types) may give different performance and memory usage - results, as well as issue some warnings and errors. -- Current implementation of recording in VMA, as well as VmaReplay application, is - coded and tested only on Windows. Inclusion of recording code is driven by - `VMA_RECORDING_ENABLED` macro. Support for other platforms should be easy to - add. Contributions are welcomed. - - \page opengl_interop OpenGL Interop VMA provides some features that help with interoperability with OpenGL. @@ -19363,8 +18883,7 @@ also dedicated allocations or other allocations made from default pools, an alternative solution is to fill in VmaAllocatorCreateInfo::pTypeExternalMemoryHandleTypes. It should point to an array with `VkExternalMemoryHandleTypeFlagsKHR` to be automatically passed by the library through `VkExportMemoryAllocateInfoKHR` on each allocation made from a specific memory type. -This is currently the only method to use if you need exported dedicated allocations, as they cannot be created out of custom pools. -This will change in future versions of the library though. +Please note that new versions of the library also support dedicated allocations created in custom pools. You should not mix these two methods in a way that allows to apply both to the same memory type. Otherwise, `VkExportMemoryAllocateInfoKHR` structure would be attached twice to the `pNext` chain of `VkMemoryAllocateInfo`. @@ -19384,8 +18903,6 @@ from a function like `vkGetBufferMemoryRequirements`, which is called by VMA aut If you want to create a buffer with a specific minimum alignment out of default pools, use special function vmaCreateBufferWithAlignment(), which takes additional parameter `minAlignment`. -This is currently the only method to use if you need exported dedicated allocations, as they cannot be created out of custom pools. -This will change in future versions of the library though. Note the problem of alignment affects only resources placed inside bigger `VkDeviceMemory` blocks and not dedicated allocations, as these, by definition, always have alignment = 0 because the resource is bound to the beginning of its dedicated block. @@ -19394,34 +18911,14 @@ Contrary to Direct3D 12, Vulkan doesn't have a concept of alignment of the entir \page usage_patterns Recommended usage patterns +Vulkan gives great flexibility in memory allocation. +This chapter shows the most common patterns. + See also slides from talk: [Sawicki, Adam. Advanced Graphics Techniques Tutorial: Memory management in Vulkan and DX12. Game Developers Conference, 2018](https://www.gdcvault.com/play/1025458/Advanced-Graphics-Techniques-Tutorial-New) -\section usage_patterns_common_mistakes Common mistakes - -Use of CPU_TO_GPU instead of CPU_ONLY memory - -#VMA_MEMORY_USAGE_CPU_TO_GPU is recommended only for resources that will be -mapped and written by the CPU, as well as read directly by the GPU - like some -buffers or textures updated every frame (dynamic). If you create a staging copy -of a resource to be written by CPU and then used as a source of transfer to -another resource placed in the GPU memory, that staging resource should be -created with #VMA_MEMORY_USAGE_CPU_ONLY. Please read the descriptions of these -enums carefully for details. - -Unnecessary use of custom pools - -\ref custom_memory_pools may be useful for special purposes - when you want to -keep certain type of resources separate e.g. to reserve minimum amount of memory -for them, limit maximum amount of memory they can occupy, or make some of them -push out the other through the mechanism of \ref lost_allocations. For most -resources this is not needed and so it is not recommended to create #VmaPool -objects and allocations out of them. Allocating from the default pool is sufficient. - -\section usage_patterns_simple Simple patterns - -\subsection usage_patterns_simple_render_targets Render targets +\section usage_patterns_gpu_only GPU-only resource When: Any resources that you frequently write and read on GPU, @@ -19429,123 +18926,219 @@ e.g. images used as color attachments (aka "render targets"), depth-stencil atta images/buffers used as storage image/buffer (aka "Unordered Access View (UAV)"). What to do: -Create them in video memory that is fastest to access from GPU using -#VMA_MEMORY_USAGE_GPU_ONLY. +Let the library select the optimal memory type, which will likely have `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`. -Consider using [VK_KHR_dedicated_allocation](@ref vk_khr_dedicated_allocation) extension -and/or manually creating them as dedicated allocations using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, -especially if they are large or if you plan to destroy and recreate them e.g. when -display resolution changes. +\code +VkImageCreateInfo imgCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; +imgCreateInfo.imageType = VK_IMAGE_TYPE_2D; +imgCreateInfo.extent.width = 3840; +imgCreateInfo.extent.height = 2160; +imgCreateInfo.extent.depth = 1; +imgCreateInfo.mipLevels = 1; +imgCreateInfo.arrayLayers = 1; +imgCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM; +imgCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; +imgCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; +imgCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; +imgCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; +allocCreateInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; +allocCreateInfo.priority = 1.0f; + +VkImage img; +VmaAllocation alloc; +vmaCreateImage(allocator, &imgCreateInfo, &allocCreateInfo, &img, &alloc, nullptr); +\endcode + +Also consider: +Consider creating them as dedicated allocations using #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, +especially if they are large or if you plan to destroy and recreate them with different sizes +e.g. when display resolution changes. Prefer to create such resources first and all other GPU resources (like textures and vertex buffers) later. +When VK_EXT_memory_priority extension is enabled, it is also worth setting high priority to such allocation +to decrease chances to be evicted to system memory by the operating system. -\subsection usage_patterns_simple_immutable_resources Immutable resources +\section usage_patterns_staging_copy_upload Staging copy for upload When: -Any resources that you fill on CPU only once (aka "immutable") or infrequently -and then read frequently on GPU, -e.g. textures, vertex and index buffers, constant buffers that don't change often. +A "staging" buffer than you want to map and fill from CPU code, then use as a source od transfer +to some GPU resource. What to do: -Create them in video memory that is fastest to access from GPU using -#VMA_MEMORY_USAGE_GPU_ONLY. +Use flag #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT. +Let the library select the optimal memory type, which will always have `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT`. -To initialize content of such resource, create a CPU-side (aka "staging") copy of it -in system memory - #VMA_MEMORY_USAGE_CPU_ONLY, map it, fill it, -and submit a transfer from it to the GPU resource. -You can keep the staging copy if you need it for another upload transfer in the future. -If you don't, you can destroy it or reuse this buffer for uploading different resource -after the transfer finishes. +\code +VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +bufCreateInfo.size = 65536; +bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; -Prefer to create just buffers in system memory rather than images, even for uploading textures. -Use `vkCmdCopyBufferToImage()`. -Dont use images with `VK_IMAGE_TILING_LINEAR`. +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; +allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | + VMA_ALLOCATION_CREATE_MAPPED_BIT; -\subsection usage_patterns_dynamic_resources Dynamic resources +VkBuffer buf; +VmaAllocation alloc; +VmaAllocationInfo allocInfo; +vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); + +... + +memcpy(allocInfo.pMappedData, myData, myDataSize); +\endcode + +Also consider: +You can map the allocation using vmaMapMemory() or you can create it as persistenly mapped +using #VMA_ALLOCATION_CREATE_MAPPED_BIT, as in the example above. + + +\section usage_patterns_readback Readback When: -Any resources that change frequently (aka "dynamic"), e.g. every frame or every draw call, -written on CPU, read on GPU. - -What to do: -Create them using #VMA_MEMORY_USAGE_CPU_TO_GPU. -You can map it and write to it directly on CPU, as well as read from it on GPU. - -This is a more complex situation. Different solutions are possible, -and the best one depends on specific GPU type, but you can use this simple approach for the start. -Prefer to write to such resource sequentially (e.g. using `memcpy`). -Don't perform random access or any reads from it on CPU, as it may be very slow. -Also note that textures written directly from the host through a mapped pointer need to be in LINEAR not OPTIMAL layout. - -\subsection usage_patterns_readback Readback - -When: -Resources that contain data written by GPU that you want to read back on CPU, +Buffers for data written by or transferred from the GPU that you want to read back on the CPU, e.g. results of some computations. What to do: -Create them using #VMA_MEMORY_USAGE_GPU_TO_CPU. -You can write to them directly on GPU, as well as map and read them on CPU. +Use flag #VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT. +Let the library select the optimal memory type, which will always have `VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT` +and `VK_MEMORY_PROPERTY_HOST_CACHED_BIT`. -\section usage_patterns_advanced Advanced patterns +\code +VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +bufCreateInfo.size = 65536; +bufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; -\subsection usage_patterns_integrated_graphics Detecting integrated graphics +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; +allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | + VMA_ALLOCATION_CREATE_MAPPED_BIT; -You can support integrated graphics (like Intel HD Graphics, AMD APU) better -by detecting it in Vulkan. -To do it, call `vkGetPhysicalDeviceProperties()`, inspect -`VkPhysicalDeviceProperties::deviceType` and look for `VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU`. -When you find it, you can assume that memory is unified and all memory types are comparably fast -to access from GPU, regardless of `VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT`. +VkBuffer buf; +VmaAllocation alloc; +VmaAllocationInfo allocInfo; +vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); -You can then sum up sizes of all available memory heaps and treat them as useful for -your GPU resources, instead of only `DEVICE_LOCAL` ones. -You can also prefer to create your resources in memory types that are `HOST_VISIBLE` to map them -directly instead of submitting explicit transfer (see below). +... -\subsection usage_patterns_direct_vs_transfer Direct access versus transfer +const float* downloadedData = (const float*)allocInfo.pMappedData; +\endcode -For resources that you frequently write on CPU and read on GPU, many solutions are possible: --# Create one copy in video memory using #VMA_MEMORY_USAGE_GPU_ONLY, - second copy in system memory using #VMA_MEMORY_USAGE_CPU_ONLY and submit explicit transfer each time. --# Create just a single copy using #VMA_MEMORY_USAGE_CPU_TO_GPU, map it and fill it on CPU, - read it directly on GPU. --# Create just a single copy using #VMA_MEMORY_USAGE_CPU_ONLY, map it and fill it on CPU, - read it directly on GPU. +\section usage_patterns_advanced_data_uploading Advanced data uploading -Which solution is the most efficient depends on your resource and especially on the GPU. -It is best to measure it and then make the decision. -Some general recommendations: +For resources that you frequently write on CPU via mapped pointer and +freqnently read on GPU e.g. as a uniform buffer (also called "dynamic"), multiple options are possible: -- On integrated graphics use (2) or (3) to avoid unnecessary time and memory overhead - related to using a second copy and making transfer. -- For small resources (e.g. constant buffers) use (2). - Discrete AMD cards have special 256 MiB pool of video memory that is directly mappable. - Even if the resource ends up in system memory, its data may be cached on GPU after first - fetch over PCIe bus. -- For larger resources (e.g. textures), decide between (1) and (2). - You may want to differentiate NVIDIA and AMD, e.g. by looking for memory type that is - both `DEVICE_LOCAL` and `HOST_VISIBLE`. When you find it, use (2), otherwise use (1). +-# Easiest solution is to have one copy of the resource in `HOST_VISIBLE` memory, + even if it means system RAM (not `DEVICE_LOCAL`) on systems with a discrete graphics card, + and make the device reach out to that resource directly. + - Reads performed by the device will then go through PCI Express bus. + The performace of this access may be limited, but it may be fine depending on the size + of this resource (whether it is small enough to quickly end up in GPU cache) and the sparsity + of access. +-# On systems with unified memory (e.g. AMD APU or Intel integrated graphics, mobile chips), + a memory type may be available that is both `HOST_VISIBLE` (available for mapping) and `DEVICE_LOCAL` + (fast to access from the GPU). Then, it is likely the best choice for such type of resource. +-# Systems with a discrete graphics card and separate video memory may or may not expose + a memory type that is both `HOST_VISIBLE` and `DEVICE_LOCAL`, also known as Base Address Register (BAR). + If they do, it represents a piece of VRAM (or entire VRAM, if ReBAR is enabled in the motherboard BIOS) + that is available to CPU for mapping. + - Writes performed by the host to that memory go through PCI Express bus. + The performance of these writes may be limited, but it may be fine, especially on PCIe 4.0, + as long as rules of using uncached and write-combined memory are followed - only sequential writes and no reads. +-# Finally, you may need or prefer to create a separate copy of the resource in `DEVICE_LOCAL` memory, + a separate "staging" copy in `HOST_VISIBLE` memory and perform an explicit transfer command between them. -Similarly, for resources that you frequently write on GPU and read on CPU, multiple -solutions are possible: +Thankfully, VMA offers an aid to create and use such resources in the the way optimal +for the current Vulkan device. To help the library make the best choice, +use flag #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT together with +#VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT. +It will then prefer a memory type that is both `DEVICE_LOCAL` and `HOST_VISIBLE` (integrated memory or BAR), +but if no such memory type is available or allocation from it fails +(PC graphics cards have only 256 MB of BAR by default, unless ReBAR is supported and enabled in BIOS), +it will fall back to `DEVICE_LOCAL` memory for fast GPU access. +It is then up to you to detect that the allocation ended up in a memory type that is not `HOST_VISIBLE`, +so you need to create another "staging" allocation and perform explicit transfers. --# Create one copy in video memory using #VMA_MEMORY_USAGE_GPU_ONLY, - second copy in system memory using #VMA_MEMORY_USAGE_GPU_TO_CPU and submit explicit tranfer each time. --# Create just single copy using #VMA_MEMORY_USAGE_GPU_TO_CPU, write to it directly on GPU, - map it and read it on CPU. +\code +VkBufferCreateInfo bufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; +bufCreateInfo.size = 65536; +bufCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; +allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | + VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | + VMA_ALLOCATION_CREATE_MAPPED_BIT; + +VkBuffer buf; +VmaAllocation alloc; +VmaAllocationInfo allocInfo; +vmaCreateBuffer(allocator, &bufCreateInfo, &allocCreateInfo, &buf, &alloc, &allocInfo); -You should take some measurements to decide which option is faster in case of your specific -resource. +VkMemoryPropertyFlags memPropFlags; +vmaGetAllocationMemoryProperties(allocator, alloc, &memPropFlags); -Note that textures accessed directly from the host through a mapped pointer need to be in LINEAR layout, -which may slow down their usage on the device. -Textures accessed only by the device and transfer operations can use OPTIMAL layout. +if(memPropFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) +{ + // Allocation ended up in a mappable memory and is already mapped - write to it directly. -If you don't want to specialize your code for specific types of GPUs, you can still make -an simple optimization for cases when your resource ends up in mappable memory to use it -directly in this case instead of creating CPU-side staging copy. -For details see [Finding out if memory is mappable](@ref memory_mapping_finding_if_memory_mappable). + // [Executed in runtime]: + memcpy(allocInfo.pMappedData, myData, myDataSize); +} +else +{ + // Allocation ended up in a non-mappable memory - need to transfer. + VkBufferCreateInfo stagingBufCreateInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + stagingBufCreateInfo.size = 65536; + stagingBufCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + + VmaAllocationCreateInfo stagingAllocCreateInfo = {}; + stagingAllocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; + stagingAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | + VMA_ALLOCATION_CREATE_MAPPED_BIT; + + VkBuffer stagingBuf; + VmaAllocation stagingAlloc; + VmaAllocationInfo stagingAllocInfo; + vmaCreateBuffer(allocator, &stagingBufCreateInfo, &stagingAllocCreateInfo, + &stagingBuf, &stagingAlloc, stagingAllocInfo); + + // [Executed in runtime]: + memcpy(stagingAllocInfo.pMappedData, myData, myDataSize); + //vkCmdPipelineBarrier: VK_ACCESS_HOST_WRITE_BIT --> VK_ACCESS_TRANSFER_READ_BIT + VkBufferCopy bufCopy = { + 0, // srcOffset + 0, // dstOffset, + myDataSize); // size + vkCmdCopyBuffer(cmdBuf, stagingBuf, buf, 1, &bufCopy); +} +\endcode + +\section usage_patterns_other_use_cases Other use cases + +Here are some other, less obvious use cases and their recommended settings: + +- An image that is used only as transfer source and destination, but it should stay on the device, + as it is used to temporarily store a copy of some texture, e.g. from the current to the next frame, + for temporal antialiasing or other temporal effects. + - Use `VkImageCreateInfo::usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT` + - Use VmaAllocationCreateInfo::usage = #VMA_MEMORY_USAGE_AUTO +- An image that is used only as transfer source and destination, but it should be placed + in the system RAM despite it doesn't need to be mapped, because it serves as a "swap" copy to evict + least recently used textures from VRAM. + - Use `VkImageCreateInfo::usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT` + - Use VmaAllocationCreateInfo::usage = #VMA_MEMORY_USAGE_AUTO_PREFER_HOST, + as VMA needs a hint here to differentiate from the previous case. +- A buffer that you want to map and write from the CPU, directly read from the GPU + (e.g. as a uniform or vertex buffer), but you have a clear preference to place it in device or + host memory due to its large size. + - Use `VkBufferCreateInfo::usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT` + - Use VmaAllocationCreateInfo::usage = #VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE or #VMA_MEMORY_USAGE_AUTO_PREFER_HOST + - Use VmaAllocationCreateInfo::flags = #VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT \page configuration Configuration @@ -19584,6 +19177,8 @@ by using a helper library like [volk](https://github.com/zeux/volk). Third, VMA tries to fetch remaining pointers that are still null by calling `vkGetInstanceProcAddr` and `vkGetDeviceProcAddr` on its own. +You need to only fill in VmaVulkanFunctions::vkGetInstanceProcAddr and VmaVulkanFunctions::vkGetDeviceProcAddr. +Other pointers will be fetched automatically. If you want to disable this feature, set configuration macro: `#define VMA_DYNAMIC_VULKAN_FUNCTIONS 0`. Finally, all the function pointers required by the library (considering selected @@ -19608,7 +19203,7 @@ VmaAllocatorCreateInfo::pDeviceMemoryCallbacks. \section heap_memory_limit Device heap memory limit When device memory of certain heap runs out of free space, new allocations may -fail (returning error code) or they may succeed, silently pushing some existing +fail (returning error code) or they may succeed, silently pushing some existing_ memory blocks from GPU VRAM to system RAM (which degrades performance). This behavior is implementation-dependent - it depends on GPU vendor and graphics driver. @@ -19629,10 +19224,14 @@ VK_KHR_dedicated_allocation is a Vulkan extension which can be used to improve performance on some GPUs. It augments Vulkan API with possibility to query driver whether it prefers particular buffer or image to have its own, dedicated allocation (separate `VkDeviceMemory` block) for better efficiency - to be able -to do some internal optimizations. +to do some internal optimizations. The extension is supported by this library. +It will be used automatically when enabled. -The extension is supported by this library. It will be used automatically when -enabled. To enable it: +It has been promoted to core Vulkan 1.1, so if you use eligible Vulkan version +and inform VMA about it by setting VmaAllocatorCreateInfo::vulkanApiVersion, +you are all set. + +Otherwise, if you want to use it as an extension: 1 . When creating Vulkan device, check if following 2 device extensions are supported (call `vkEnumerateDeviceExtensionProperties()`). @@ -19644,7 +19243,7 @@ If yes, enable them (fill `VkDeviceCreateInfo::ppEnabledExtensionNames`). If you enabled these extensions: 2 . Use #VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT flag when creating -your #VmaAllocator`to inform the library that you enabled required extensions +your #VmaAllocator to inform the library that you enabled required extensions and you want the library to use them. \code @@ -19659,7 +19258,7 @@ buffer using vmaCreateBuffer() or image using vmaCreateImage(). When using the extension together with Vulkan Validation Layer, you will receive warnings like this: - vkBindBufferMemory(): Binding memory to buffer 0x33 but vkGetBufferMemoryRequirements() has not been called on that buffer. +_vkBindBufferMemory(): Binding memory to buffer 0x33 but vkGetBufferMemoryRequirements() has not been called on that buffer._ It is OK, you should just ignore it. It happens because you use function `vkGetBufferMemoryRequirements2KHR()` instead of standard @@ -19673,6 +19272,86 @@ To learn more about this extension, see: +\page vk_ext_memory_priority VK_EXT_memory_priority + +VK_EXT_memory_priority is a device extension that allows to pass additional "priority" +value to Vulkan memory allocations that the implementation may use prefer certain +buffers and images that are critical for performance to stay in device-local memory +in cases when the memory is over-subscribed, while some others may be moved to the system memory. + +VMA offers convenient usage of this extension. +If you enable it, you can pass "priority" parameter when creating allocations or custom pools +and the library automatically passes the value to Vulkan using this extension. + +If you want to use this extension in connection with VMA, follow these steps: + +\section vk_ext_memory_priority_initialization Initialization + +1) Call `vkEnumerateDeviceExtensionProperties` for the physical device. +Check if the extension is supported - if returned array of `VkExtensionProperties` contains "VK_EXT_memory_priority". + +2) Call `vkGetPhysicalDeviceFeatures2` for the physical device instead of old `vkGetPhysicalDeviceFeatures`. +Attach additional structure `VkPhysicalDeviceMemoryPriorityFeaturesEXT` to `VkPhysicalDeviceFeatures2::pNext` to be returned. +Check if the device feature is really supported - check if `VkPhysicalDeviceMemoryPriorityFeaturesEXT::memoryPriority` is true. + +3) While creating device with `vkCreateDevice`, enable this extension - add "VK_EXT_memory_priority" +to the list passed as `VkDeviceCreateInfo::ppEnabledExtensionNames`. + +4) While creating the device, also don't set `VkDeviceCreateInfo::pEnabledFeatures`. +Fill in `VkPhysicalDeviceFeatures2` structure instead and pass it as `VkDeviceCreateInfo::pNext`. +Enable this device feature - attach additional structure `VkPhysicalDeviceMemoryPriorityFeaturesEXT` to +`VkPhysicalDeviceFeatures2::pNext` chain and set its member `memoryPriority` to `VK_TRUE`. + +5) While creating #VmaAllocator with vmaCreateAllocator() inform VMA that you +have enabled this extension and feature - add #VMA_ALLOCATOR_CREATE_EXT_MEMORY_PRIORITY_BIT +to VmaAllocatorCreateInfo::flags. + +\section vk_ext_memory_priority_usage Usage + +When using this extension, you should initialize following member: + +- VmaAllocationCreateInfo::priority when creating a dedicated allocation with #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. +- VmaPoolCreateInfo::priority when creating a custom pool. + +It should be a floating-point value between `0.0f` and `1.0f`, where recommended default is `0.5f`. +Memory allocated with higher value can be treated by the Vulkan implementation as higher priority +and so it can have lower chances of being pushed out to system memory, experiencing degraded performance. + +It might be a good idea to create performance-critical resources like color-attachment or depth-stencil images +as dedicated and set high priority to them. For example: + +\code +VkImageCreateInfo imgCreateInfo = { VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO }; +imgCreateInfo.imageType = VK_IMAGE_TYPE_2D; +imgCreateInfo.extent.width = 3840; +imgCreateInfo.extent.height = 2160; +imgCreateInfo.extent.depth = 1; +imgCreateInfo.mipLevels = 1; +imgCreateInfo.arrayLayers = 1; +imgCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM; +imgCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL; +imgCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; +imgCreateInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; +imgCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT; + +VmaAllocationCreateInfo allocCreateInfo = {}; +allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO; +allocCreateInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; +allocCreateInfo.priority = 1.0f; + +VkImage img; +VmaAllocation alloc; +vmaCreateImage(allocator, &imgCreateInfo, &allocCreateInfo, &img, &alloc, nullptr); +\endcode + +`priority` member is ignored in the following situations: + +- Allocations created in custom pools: They inherit the priority, along with all other allocation parameters + from the parametrs passed in #VmaPoolCreateInfo when the pool was created. +- Allocations created in default pools: They inherit the priority from the parameters + VMA used when creating default pools, which means `priority == 0.5f`. + + \page vk_amd_device_coherent_memory VK_AMD_device_coherent_memory VK_AMD_device_coherent_memory is a device extension that enables access to @@ -19716,7 +19395,7 @@ out of the special `DEVICE_COHERENT` and `DEVICE_UNCACHED` memory types on eligi devices. There are multiple ways to do it, for example: - You can request or prefer to allocate out of such memory types by adding - `VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD` to VmaAllocationCreateInfo::requiredFlags + `VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD` to VmaAllocationCreateInfo::requiredFlags or VmaAllocationCreateInfo::preferredFlags. Those flags can be freely mixed with other ways of \ref choosing_memory_type, like setting VmaAllocationCreateInfo::usage. - If you manually found memory type index to use for this purpose, force allocation @@ -19734,7 +19413,7 @@ accompanying this library. Device extension VK_KHR_buffer_device_address allow to fetch raw GPU pointer to a buffer and pass it for usage in a shader code. -It is promoted to core Vulkan 1.2. +It has been promoted to core Vulkan 1.2. If you want to use this feature in connection with VMA, follow these steps: @@ -19787,6 +19466,7 @@ accompanying this library. - By default, all calls to functions that take #VmaAllocator as first parameter are safe to call from multiple threads simultaneously because they are synchronized internally when needed. + This includes allocation and deallocation from default memory pool, as well as custom #VmaPool. - When the allocator is created with #VMA_ALLOCATOR_CREATE_EXTERNALLY_SYNCHRONIZED_BIT flag, calls to functions that take such #VmaAllocator object must be synchronized externally. @@ -19794,6 +19474,29 @@ accompanying this library. you must not call vmaGetAllocationInfo() and vmaMapMemory() from different threads at the same time if you pass the same #VmaAllocation object to these functions. +- #VmaVirtualBlock is not safe to be used from multiple threads simultaneously. + +\section general_considerations_versioning_and_compatibility Versioning and compatibility + +The library uses [**Semantic Versioning**](https://semver.org/), +which means version numbers follow convention: Major.Minor.Patch (e.g. 2.3.0), where: + +- Incremented Patch version means a release is backward- and forward-compatible, + introducing only some internal improvements, bug fixes, optimizations etc. + or changes that are out of scope of the official API described in this documentation. +- Incremented Minor version means a release is backward-compatible, + so existing code that uses the library should continue to work, while some new + symbols could have been added: new structures, functions, new values in existing + enums and bit flags, new structure members, but not new function parameters. +- Incrementing Major version means a release could break some backward compatibility. + +All changes between official releases are documented in file "CHANGELOG.md". + +\warning Backward compatiblity is considered on the level of C++ source code, not binary linkage. +Adding new members to existing structures is treated as backward compatible if initializing +the new members to binary zero results in the old behavior. +You should always fully initialize all library structures to zeros and not rely on their +exact binary size. \section general_considerations_validation_layer_warnings Validation layer warnings @@ -19809,9 +19512,7 @@ to just ignore them. `VkDeviceMemory` block, where different types of images and buffers may end up together, especially on GPUs with unified memory like Intel. - *Non-linear image 0xebc91 is aliased with linear buffer 0xeb8e4 which may indicate a bug.* - - It happens when you use lost allocations, and a new image or buffer is - created in place of an existing object that became lost. - - It may happen also when you use [defragmentation](@ref defragmentation). + - It may happen when you use [defragmentation](@ref defragmentation). \section general_considerations_allocation_algorithm Allocation algorithm @@ -19819,10 +19520,7 @@ The library uses following algorithm for allocation, in order: -# Try to find free range of memory in existing blocks. -# If failed, try to create a new block of `VkDeviceMemory`, with preferred block size. --# If failed, try to create such block with size/2, size/4, size/8. --# If failed and #VMA_ALLOCATION_CREATE_CAN_MAKE_OTHER_LOST_BIT flag was - specified, try to find space in existing blocks, possilby making some other - allocations lost. +-# If failed, try to create such block with size / 2, size / 4, size / 8. -# If failed, try to allocate separate `VkDeviceMemory` for this allocation, just like when you use #VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT. -# If failed, choose other memory type that meets the requirements specified in @@ -19833,28 +19531,29 @@ The library uses following algorithm for allocation, in order: Features deliberately excluded from the scope of this library: -- **Data transfer.** Uploading (streaming) and downloading data of buffers and images - between CPU and GPU memory and related synchronization is responsibility of the user. - Defining some "texture" object that would automatically stream its data from a - staging copy in CPU memory to GPU memory would rather be a feature of another, - higher-level library implemented on top of VMA. -- **Recreation of buffers and images.** Although the library has functions for - buffer and image creation (vmaCreateBuffer(), vmaCreateImage()), you need to - recreate these objects yourself after defragmentation. That is because the big - structures `VkBufferCreateInfo`, `VkImageCreateInfo` are not stored in - #VmaAllocation object. -- **Handling CPU memory allocation failures.** When dynamically creating small C++ - objects in CPU memory (not Vulkan memory), allocation failures are not checked - and handled gracefully, because that would complicate code significantly and - is usually not needed in desktop PC applications anyway. - Success of an allocation is just checked with an assert. -- **Code free of any compiler warnings.** Maintaining the library to compile and - work correctly on so many different platforms is hard enough. Being free of - any warnings, on any version of any compiler, is simply not feasible. - There are many preprocessor macros that make some variables unused, function parameters unreferenced, - or conditional expressions constant in some configurations. - The code of this library should not be bigger or more complicated just to silence these warnings. - It is recommended to disable such warnings instead. -- This is a C++ library with C interface. **Bindings or ports to any other programming languages** are welcome as external projects but - are not going to be included into this repository. +-# **Data transfer.** Uploading (streaming) and downloading data of buffers and images + between CPU and GPU memory and related synchronization is responsibility of the user. + Defining some "texture" object that would automatically stream its data from a + staging copy in CPU memory to GPU memory would rather be a feature of another, + higher-level library implemented on top of VMA. + VMA doesn't record any commands to a `VkCommandBuffer`. It just allocates memory. +-# **Recreation of buffers and images.** Although the library has functions for + buffer and image creation: vmaCreateBuffer(), vmaCreateImage(), you need to + recreate these objects yourself after defragmentation. That is because the big + structures `VkBufferCreateInfo`, `VkImageCreateInfo` are not stored in + #VmaAllocation object. +-# **Handling CPU memory allocation failures.** When dynamically creating small C++ + objects in CPU memory (not Vulkan memory), allocation failures are not checked + and handled gracefully, because that would complicate code significantly and + is usually not needed in desktop PC applications anyway. + Success of an allocation is just checked with an assert. +-# **Code free of any compiler warnings.** Maintaining the library to compile and + work correctly on so many different platforms is hard enough. Being free of + any warnings, on any version of any compiler, is simply not feasible. + There are many preprocessor macros that make some variables unused, function parameters unreferenced, + or conditional expressions constant in some configurations. + The code of this library should not be bigger or more complicated just to silence these warnings. + It is recommended to disable such warnings instead. +-# This is a C++ library with C interface. **Bindings or ports to any other programming languages** are welcome as external projects but + are not going to be included into this repository. */ diff --git a/libraries/ZVulkan/include/zvulkan/vulkanbuilders.h b/libraries/ZVulkan/include/zvulkan/vulkanbuilders.h index 667732a5d..920834b48 100644 --- a/libraries/ZVulkan/include/zvulkan/vulkanbuilders.h +++ b/libraries/ZVulkan/include/zvulkan/vulkanbuilders.h @@ -184,6 +184,7 @@ public: BufferBuilder& Size(size_t size); BufferBuilder& Usage(VkBufferUsageFlags bufferUsage, VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_GPU_ONLY, VmaAllocationCreateFlags allocFlags = 0); BufferBuilder& MemoryType(VkMemoryPropertyFlags requiredFlags, VkMemoryPropertyFlags preferredFlags, uint32_t memoryTypeBits = 0); + BufferBuilder& MinAlignment(VkDeviceSize memoryAlignment); BufferBuilder& DebugName(const char* name) { debugName = name; return *this; } std::unique_ptr Create(VulkanDevice *device); @@ -192,6 +193,27 @@ private: VkBufferCreateInfo bufferInfo = {}; VmaAllocationCreateInfo allocInfo = {}; const char* debugName = nullptr; + VkDeviceSize minAlignment = 0; +}; + +enum class ShaderType +{ + Vertex, + TessControl, + TessEvaluation, + Geometry, + Fragment, + Compute +}; + +class ShaderIncludeResult +{ +public: + ShaderIncludeResult(std::string name, std::string text) : name(std::move(name)), text(std::move(text)) { } + ShaderIncludeResult(std::string error) : text(std::move(error)) { } + + std::string name; // fully resolved name of the included header file + std::string text; // the file contents - or include error message if name is empty }; class ShaderBuilder @@ -202,16 +224,23 @@ public: static void Init(); static void Deinit(); - ShaderBuilder& VertexShader(const std::string &code); - ShaderBuilder& FragmentShader(const std::string&code); + ShaderBuilder& Type(ShaderType type); + ShaderBuilder& AddSource(const std::string& name, const std::string& code); + + ShaderBuilder& OnIncludeSystem(std::function onIncludeSystem); + ShaderBuilder& OnIncludeLocal(std::function onIncludeLocal); + ShaderBuilder& DebugName(const char* name) { debugName = name; return *this; } std::unique_ptr Create(const char *shadername, VulkanDevice *device); private: - std::string code; + std::vector> sources; + std::function onIncludeSystem; + std::function onIncludeLocal; int stage = 0; const char* debugName = nullptr; + friend class ShaderBuilderIncluderImpl; }; class AccelerationStructureBuilder @@ -463,8 +492,8 @@ public: PipelineBarrier& AddMemory(VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask); PipelineBarrier& AddBuffer(VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask); PipelineBarrier& AddBuffer(VulkanBuffer *buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask); - PipelineBarrier& AddImage(VulkanImage *image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1); - PipelineBarrier& AddImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1); + PipelineBarrier& AddImage(VulkanImage *image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1, int baseArrayLayer = 0, int layerCount = 1); + PipelineBarrier& AddImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1, int baseArrayLayer = 0, int layerCount = 1); PipelineBarrier& AddQueueTransfer(int srcFamily, int dstFamily, VulkanBuffer *buffer, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask); PipelineBarrier& AddQueueTransfer(int srcFamily, int dstFamily, VulkanImage *image, VkImageLayout layout, VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, int baseMipLevel = 0, int levelCount = 1); diff --git a/libraries/ZVulkan/include/zvulkan/vulkandevice.h b/libraries/ZVulkan/include/zvulkan/vulkandevice.h index 48c1a1f59..c7d0822d6 100644 --- a/libraries/ZVulkan/include/zvulkan/vulkandevice.h +++ b/libraries/ZVulkan/include/zvulkan/vulkandevice.h @@ -39,7 +39,7 @@ public: int PresentFamily = -1; bool GraphicsTimeQueries = false; - bool SupportsDeviceExtension(const char* ext) const; + bool SupportsExtension(const char* ext) const; void SetObjectName(const char* name, uint64_t handle, VkObjectType type); diff --git a/libraries/ZVulkan/include/zvulkan/vulkaninstance.h b/libraries/ZVulkan/include/zvulkan/vulkaninstance.h index d30d6aa19..8522a8a0f 100644 --- a/libraries/ZVulkan/include/zvulkan/vulkaninstance.h +++ b/libraries/ZVulkan/include/zvulkan/vulkaninstance.h @@ -31,14 +31,22 @@ public: VkPhysicalDeviceDescriptorIndexingFeatures DescriptorIndexing = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT }; }; +class VulkanDeviceProperties +{ +public: + VkPhysicalDeviceProperties Properties = {}; + VkPhysicalDeviceMemoryProperties Memory = {}; + VkPhysicalDeviceAccelerationStructurePropertiesKHR AccelerationStructure = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR }; + VkPhysicalDeviceDescriptorIndexingProperties DescriptorIndexing = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT }; +}; + class VulkanPhysicalDevice { public: VkPhysicalDevice Device = VK_NULL_HANDLE; std::vector Extensions; std::vector QueueFamilies; - VkPhysicalDeviceProperties Properties = {}; - VkPhysicalDeviceMemoryProperties MemoryProperties = {}; + VulkanDeviceProperties Properties; VulkanDeviceFeatures Features; }; diff --git a/libraries/ZVulkan/include/zvulkan/vulkanobjects.h b/libraries/ZVulkan/include/zvulkan/vulkanobjects.h index e3bf4505c..c7842f670 100644 --- a/libraries/ZVulkan/include/zvulkan/vulkanobjects.h +++ b/libraries/ZVulkan/include/zvulkan/vulkanobjects.h @@ -569,7 +569,7 @@ inline RenderPassBegin& RenderPassBegin::Framebuffer(VulkanFramebuffer* framebuf inline RenderPassBegin& RenderPassBegin::AddClearColor(float r, float g, float b, float a) { VkClearValue clearValue = { }; - clearValue.color = { { r, g, b, a } }; + clearValue.color = { r, g, b, a }; clearValues.push_back(clearValue); renderPassInfo.clearValueCount = (uint32_t)clearValues.size(); diff --git a/libraries/ZVulkan/include/zvulkan/vulkanswapchain.h b/libraries/ZVulkan/include/zvulkan/vulkanswapchain.h index cc9a9ed22..6c5e97db0 100644 --- a/libraries/ZVulkan/include/zvulkan/vulkanswapchain.h +++ b/libraries/ZVulkan/include/zvulkan/vulkanswapchain.h @@ -6,6 +6,19 @@ class VulkanSemaphore; class VulkanFence; +class VulkanSurfaceCapabilities +{ +public: + VkSurfaceCapabilitiesKHR Capabilites = { }; +#ifdef WIN32 + VkSurfaceCapabilitiesFullScreenExclusiveEXT FullScreenExclusive = { VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT }; +#else + struct { void* pNext = nullptr; VkBool32 fullScreenExclusiveSupported = 0; } FullScreenExclusive; +#endif + std::vector PresentModes; + std::vector Formats; +}; + class VulkanSwapChain { public: @@ -27,13 +40,11 @@ public: void QueuePresent(int imageIndex, VulkanSemaphore* semaphore = nullptr); private: - void SelectFormat(bool hdr); - void SelectPresentMode(bool vsync, bool exclusivefullscreen); + void SelectFormat(const VulkanSurfaceCapabilities& caps, bool hdr); - bool CreateSwapchain(int width, int height, int imageCount, bool exclusivefullscreen, VkSwapchainKHR oldSwapChain = VK_NULL_HANDLE); + bool CreateSwapchain(int width, int height, int imageCount, bool vsync, bool hdr, bool exclusivefullscreen); - std::vector GetSurfaceFormats(); - std::vector GetPresentModes(bool exclusivefullscreen); + VulkanSurfaceCapabilities GetSurfaceCapabilities(bool exclusivefullscreen); VulkanDevice* device = nullptr; bool lost = true; diff --git a/libraries/ZVulkan/src/vulkanbuilders.cpp b/libraries/ZVulkan/src/vulkanbuilders.cpp index c1d6a84f6..013c34c22 100644 --- a/libraries/ZVulkan/src/vulkanbuilders.cpp +++ b/libraries/ZVulkan/src/vulkanbuilders.cpp @@ -128,29 +128,143 @@ ShaderBuilder::ShaderBuilder() { } -ShaderBuilder& ShaderBuilder::VertexShader(const std::string& c) +ShaderBuilder& ShaderBuilder::Type(ShaderType type) { - code = c; - stage = EShLanguage::EShLangVertex; + switch (type) + { + case ShaderType::Vertex: stage = EShLanguage::EShLangVertex; break; + case ShaderType::TessControl: stage = EShLanguage::EShLangTessControl; break; + case ShaderType::TessEvaluation: stage = EShLanguage::EShLangTessEvaluation; break; + case ShaderType::Geometry: stage = EShLanguage::EShLangGeometry; break; + case ShaderType::Fragment: stage = EShLanguage::EShLangFragment; break; + case ShaderType::Compute: stage = EShLanguage::EShLangCompute; break; + } return *this; } -ShaderBuilder& ShaderBuilder::FragmentShader(const std::string& c) +ShaderBuilder& ShaderBuilder::AddSource(const std::string& name, const std::string& code) { - code = c; - stage = EShLanguage::EShLangFragment; + sources.push_back({ name, code }); return *this; } +ShaderBuilder& ShaderBuilder::OnIncludeSystem(std::function onIncludeSystem) +{ + this->onIncludeSystem = std::move(onIncludeSystem); + return *this; +} + +ShaderBuilder& ShaderBuilder::OnIncludeLocal(std::function onIncludeLocal) +{ + this->onIncludeLocal = std::move(onIncludeLocal); + return *this; +} + +class ShaderBuilderIncluderImpl : public glslang::TShader::Includer +{ +public: + ShaderBuilderIncluderImpl(ShaderBuilder* shaderBuilder) : shaderBuilder(shaderBuilder) + { + } + + IncludeResult* includeSystem(const char* headerName, const char* includerName, size_t inclusionDepth) override + { + if (!shaderBuilder->onIncludeSystem) + { + return nullptr; + } + + try + { + std::unique_ptr result; + try + { + result = std::make_unique(shaderBuilder->onIncludeSystem(headerName, includerName, inclusionDepth)); + } + catch (const std::exception& e) + { + result = std::make_unique(e.what()); + } + + if (!result || (result->name.empty() && result->text.empty())) + { + return nullptr; + } + + IncludeResult* outer = new IncludeResult(result->name, result->text.data(), result->text.size(), result.get()); + result.release(); + return outer; + } + catch (...) + { + return nullptr; + } + } + + IncludeResult* includeLocal(const char* headerName, const char* includerName, size_t inclusionDepth) override + { + if (!shaderBuilder->onIncludeLocal) + { + return nullptr; + } + + try + { + std::unique_ptr result; + try + { + result = std::make_unique(shaderBuilder->onIncludeLocal(headerName, includerName, inclusionDepth)); + } + catch (const std::exception& e) + { + result = std::make_unique(e.what()); + } + + if (!result || (result->name.empty() && result->text.empty())) + { + return nullptr; + } + + IncludeResult* outer = new IncludeResult(result->name, result->text.data(), result->text.size(), result.get()); + result.release(); + return outer; + } + catch (...) + { + return nullptr; + } + } + + void releaseInclude(IncludeResult* result) override + { + if (result) + { + delete (ShaderIncludeResult*)result->userData; + delete result; + } + } + +private: + ShaderBuilder* shaderBuilder = nullptr; +}; + std::unique_ptr ShaderBuilder::Create(const char *shadername, VulkanDevice *device) { EShLanguage stage = (EShLanguage)this->stage; - const char *sources[] = { code.c_str() }; + + std::vector namesC, sourcesC; + std::vector lengthsC; + for (const auto& s : sources) + { + namesC.push_back(s.first.c_str()); + sourcesC.push_back(s.second.c_str()); + lengthsC.push_back((int)s.second.size()); + } TBuiltInResource resources = DefaultTBuiltInResource; glslang::TShader shader(stage); - shader.setStrings(sources, 1); + shader.setStringsWithLengthsAndNames(sourcesC.data(), lengthsC.data(), namesC.data(), (int)sources.size()); shader.setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, 100); if (device->Instance->ApiVersion >= VK_API_VERSION_1_2) { @@ -162,7 +276,9 @@ std::unique_ptr ShaderBuilder::Create(const char *shadername, Vulk shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_0); shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_0); } - bool compileSuccess = shader.parse(&resources, 110, false, EShMsgVulkanRules); + + ShaderBuilderIncluderImpl includer(this); + bool compileSuccess = shader.parse(&resources, 110, false, EShMsgVulkanRules, includer); if (!compileSuccess) { throw std::runtime_error(std::string("Shader compile failed: ") + shader.getInfoLog()); @@ -527,13 +643,27 @@ BufferBuilder& BufferBuilder::MemoryType(VkMemoryPropertyFlags requiredFlags, Vk return *this; } +BufferBuilder& BufferBuilder::MinAlignment(VkDeviceSize memoryAlignment) +{ + minAlignment = memoryAlignment; + return *this; +} + std::unique_ptr BufferBuilder::Create(VulkanDevice* device) { VkBuffer buffer; VmaAllocation allocation; - VkResult result = vmaCreateBuffer(device->allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); - CheckVulkanError(result, "Could not allocate memory for vulkan buffer"); + if (minAlignment == 0) + { + VkResult result = vmaCreateBuffer(device->allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); + CheckVulkanError(result, "Could not allocate memory for vulkan buffer"); + } + else + { + VkResult result = vmaCreateBufferWithAlignment(device->allocator, &bufferInfo, &allocInfo, minAlignment, &buffer, &allocation, nullptr); + CheckVulkanError(result, "Could not allocate memory for vulkan buffer"); + } auto obj = std::make_unique(device, buffer, allocation, bufferInfo.size); if (debugName) @@ -1175,9 +1305,9 @@ std::unique_ptr PipelineCacheBuilder::Create(VulkanDevice* { VkPipelineCacheHeaderVersionOne* header = (VkPipelineCacheHeaderVersionOne*)initData.data(); if (header->headerVersion == VK_PIPELINE_CACHE_HEADER_VERSION_ONE && - header->vendorID == device->PhysicalDevice.Properties.vendorID && - header->deviceID == device->PhysicalDevice.Properties.deviceID && - memcmp(header->pipelineCacheUUID, device->PhysicalDevice.Properties.pipelineCacheUUID, VK_UUID_SIZE) == 0) + header->vendorID == device->PhysicalDevice.Properties.Properties.vendorID && + header->deviceID == device->PhysicalDevice.Properties.Properties.deviceID && + memcmp(header->pipelineCacheUUID, device->PhysicalDevice.Properties.Properties.pipelineCacheUUID, VK_UUID_SIZE) == 0) { pipelineCacheInfo.pInitialData = initData.data(); pipelineCacheInfo.initialDataSize = initData.size(); @@ -1329,12 +1459,12 @@ PipelineBarrier& PipelineBarrier::AddBuffer(VulkanBuffer* buffer, VkDeviceSize o return *this; } -PipelineBarrier& PipelineBarrier::AddImage(VulkanImage* image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount) +PipelineBarrier& PipelineBarrier::AddImage(VulkanImage* image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount, int baseArrayLayer, int layerCount) { - return AddImage(image->image, oldLayout, newLayout, srcAccessMask, dstAccessMask, aspectMask, baseMipLevel, levelCount); + return AddImage(image->image, oldLayout, newLayout, srcAccessMask, dstAccessMask, aspectMask, baseMipLevel, levelCount, baseArrayLayer, layerCount); } -PipelineBarrier& PipelineBarrier::AddImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount) +PipelineBarrier& PipelineBarrier::AddImage(VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageAspectFlags aspectMask, int baseMipLevel, int levelCount, int baseArrayLayer, int layerCount) { VkImageMemoryBarrier barrier = { }; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -1348,8 +1478,8 @@ PipelineBarrier& PipelineBarrier::AddImage(VkImage image, VkImageLayout oldLayou barrier.subresourceRange.aspectMask = aspectMask; barrier.subresourceRange.baseMipLevel = baseMipLevel; barrier.subresourceRange.levelCount = levelCount; - barrier.subresourceRange.baseArrayLayer = 0; - barrier.subresourceRange.layerCount = 1; + barrier.subresourceRange.baseArrayLayer = baseArrayLayer; + barrier.subresourceRange.layerCount = layerCount; imageMemoryBarriers.push_back(barrier); return *this; } @@ -1767,13 +1897,13 @@ std::vector VulkanDeviceBuilder::FindDevices(const std:: { // Sort by GPU type first. This will ensure the "best" device is most likely to map to vk_device 0 static const int typeSort[] = { 4, 1, 0, 2, 3 }; - int sortA = a.Device->Properties.deviceType < 5 ? typeSort[a.Device->Properties.deviceType] : (int)a.Device->Properties.deviceType; - int sortB = b.Device->Properties.deviceType < 5 ? typeSort[b.Device->Properties.deviceType] : (int)b.Device->Properties.deviceType; + int sortA = a.Device->Properties.Properties.deviceType < 5 ? typeSort[a.Device->Properties.Properties.deviceType] : (int)a.Device->Properties.Properties.deviceType; + int sortB = b.Device->Properties.Properties.deviceType < 5 ? typeSort[b.Device->Properties.Properties.deviceType] : (int)b.Device->Properties.Properties.deviceType; if (sortA != sortB) return sortA < sortB; // Then sort by the device's unique ID so that vk_device uses a consistent order - int sortUUID = memcmp(a.Device->Properties.pipelineCacheUUID, b.Device->Properties.pipelineCacheUUID, VK_UUID_SIZE); + int sortUUID = memcmp(a.Device->Properties.Properties.pipelineCacheUUID, b.Device->Properties.Properties.pipelineCacheUUID, VK_UUID_SIZE); return sortUUID < 0; }; std::stable_sort(supportedDevices.begin(), supportedDevices.end(), sortFunc); diff --git a/libraries/ZVulkan/src/vulkandevice.cpp b/libraries/ZVulkan/src/vulkandevice.cpp index 2edd93d05..0adfff5c2 100644 --- a/libraries/ZVulkan/src/vulkandevice.cpp +++ b/libraries/ZVulkan/src/vulkandevice.cpp @@ -33,18 +33,20 @@ VulkanDevice::~VulkanDevice() ReleaseResources(); } -bool VulkanDevice::SupportsDeviceExtension(const char* ext) const +bool VulkanDevice::SupportsExtension(const char* ext) const { - return EnabledDeviceExtensions.find(ext) != EnabledDeviceExtensions.end(); + return + EnabledDeviceExtensions.find(ext) != EnabledDeviceExtensions.end() || + Instance->EnabledExtensions.find(ext) != Instance->EnabledExtensions.end(); } void VulkanDevice::CreateAllocator() { VmaAllocatorCreateInfo allocinfo = {}; allocinfo.vulkanApiVersion = Instance->ApiVersion; - if (SupportsDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME) && SupportsDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) + if (SupportsExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME) && SupportsExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME)) allocinfo.flags |= VMA_ALLOCATOR_CREATE_KHR_DEDICATED_ALLOCATION_BIT; - if (SupportsDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) + if (SupportsExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) allocinfo.flags |= VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT; allocinfo.physicalDevice = PhysicalDevice.Device; allocinfo.device = device; @@ -91,7 +93,7 @@ void VulkanDevice::CreateDevice() deviceFeatures2.features = EnabledFeatures.Features; void** next = const_cast(&deviceCreateInfo.pNext); - if (SupportsDeviceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) + if (SupportsExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { *next = &deviceFeatures2; next = &deviceFeatures2.pNext; @@ -101,22 +103,22 @@ void VulkanDevice::CreateDevice() deviceCreateInfo.pEnabledFeatures = &deviceFeatures2.features; } - if (SupportsDeviceExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) + if (SupportsExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) { *next = &EnabledFeatures.BufferDeviceAddress; next = &EnabledFeatures.BufferDeviceAddress.pNext; } - if (SupportsDeviceExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME)) + if (SupportsExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME)) { *next = &EnabledFeatures.AccelerationStructure; next = &EnabledFeatures.AccelerationStructure.pNext; } - if (SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME)) + if (SupportsExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME)) { *next = &EnabledFeatures.RayQuery; next = &EnabledFeatures.RayQuery.pNext; } - if (SupportsDeviceExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) + if (SupportsExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) { *next = &EnabledFeatures.DescriptorIndexing; next = &EnabledFeatures.DescriptorIndexing.pNext; diff --git a/libraries/ZVulkan/src/vulkaninstance.cpp b/libraries/ZVulkan/src/vulkaninstance.cpp index 7d41a9e6a..939dc737a 100644 --- a/libraries/ZVulkan/src/vulkaninstance.cpp +++ b/libraries/ZVulkan/src/vulkaninstance.cpp @@ -163,9 +163,6 @@ std::vector VulkanInstance::GetPhysicalDevices(VkInstance auto& dev = devinfo[i]; dev.Device = devices[i]; - vkGetPhysicalDeviceMemoryProperties(dev.Device, &dev.MemoryProperties); - vkGetPhysicalDeviceProperties(dev.Device, &dev.Properties); - uint32_t queueFamilyCount = 0; vkGetPhysicalDeviceQueueFamilyProperties(dev.Device, &queueFamilyCount, nullptr); dev.QueueFamilies.resize(queueFamilyCount); @@ -186,11 +183,32 @@ std::vector VulkanInstance::GetPhysicalDevices(VkInstance return false; }; + vkGetPhysicalDeviceMemoryProperties(dev.Device, &dev.Properties.Memory); + if (apiVersion != VK_API_VERSION_1_0) { + VkPhysicalDeviceProperties2 deviceProperties2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 }; + + void** next = const_cast(&deviceProperties2.pNext); + if (checkForExtension(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME)) + { + *next = &dev.Properties.AccelerationStructure; + next = &dev.Properties.AccelerationStructure.pNext; + } + if (checkForExtension(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) + { + *next = &dev.Properties.DescriptorIndexing; + next = &dev.Properties.DescriptorIndexing.pNext; + } + + vkGetPhysicalDeviceProperties2(dev.Device, &deviceProperties2); + dev.Properties.Properties = deviceProperties2.properties; + dev.Properties.AccelerationStructure.pNext = nullptr; + dev.Properties.DescriptorIndexing.pNext = nullptr; + VkPhysicalDeviceFeatures2 deviceFeatures2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 }; - void** next = const_cast(&deviceFeatures2.pNext); + next = const_cast(&deviceFeatures2.pNext); if (checkForExtension(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME)) { *next = &dev.Features.BufferDeviceAddress; @@ -221,6 +239,7 @@ std::vector VulkanInstance::GetPhysicalDevices(VkInstance } else { + vkGetPhysicalDeviceProperties(dev.Device, &dev.Properties.Properties); vkGetPhysicalDeviceFeatures(dev.Device, &dev.Features.Features); } } diff --git a/libraries/ZVulkan/src/vulkanswapchain.cpp b/libraries/ZVulkan/src/vulkanswapchain.cpp index ba528a95c..495c68416 100644 --- a/libraries/ZVulkan/src/vulkanswapchain.cpp +++ b/libraries/ZVulkan/src/vulkanswapchain.cpp @@ -1,4 +1,4 @@ -#include + #include "vulkanswapchain.h" #include "vulkanobjects.h" #include "vulkansurface.h" @@ -21,26 +21,12 @@ void VulkanSwapChain::Create(int width, int height, int imageCount, bool vsync, views.clear(); images.clear(); - SelectFormat(hdr); - SelectPresentMode(vsync, exclusivefullscreen); - - VkSwapchainKHR oldSwapchain = swapchain; - CreateSwapchain(width, height, imageCount, exclusivefullscreen, oldSwapchain); - if (oldSwapchain) - vkDestroySwapchainKHR(device->device, oldSwapchain, nullptr); + CreateSwapchain(width, height, imageCount, vsync, hdr, exclusivefullscreen); if (exclusivefullscreen && lost) { // We could not acquire exclusive fullscreen. Fall back to normal fullsceen instead. - exclusivefullscreen = false; - - SelectFormat(hdr); - SelectPresentMode(vsync, exclusivefullscreen); - - oldSwapchain = swapchain; - CreateSwapchain(width, height, imageCount, exclusivefullscreen, oldSwapchain); - if (oldSwapchain) - vkDestroySwapchainKHR(device->device, oldSwapchain, nullptr); + CreateSwapchain(width, height, imageCount, vsync, hdr, false); } if (swapchain) @@ -70,13 +56,9 @@ void VulkanSwapChain::Create(int width, int height, int imageCount, bool vsync, } } -void VulkanSwapChain::SelectFormat(bool hdr) +void VulkanSwapChain::SelectFormat(const VulkanSurfaceCapabilities& caps, bool hdr) { - std::vector surfaceFormats = GetSurfaceFormats(); - if (surfaceFormats.empty()) - throw std::runtime_error("No surface formats supported"); - - if (surfaceFormats.size() == 1 && surfaceFormats.front().format == VK_FORMAT_UNDEFINED) + if (caps.Formats.size() == 1 && caps.Formats.front().format == VK_FORMAT_UNDEFINED) { format.format = VK_FORMAT_B8G8R8A8_UNORM; format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; @@ -85,7 +67,7 @@ void VulkanSwapChain::SelectFormat(bool hdr) if (hdr) { - for (const auto& f : surfaceFormats) + for (const auto& f : caps.Formats) { if (f.format == VK_FORMAT_R16G16B16A16_SFLOAT && f.colorSpace == VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT) { @@ -95,7 +77,7 @@ void VulkanSwapChain::SelectFormat(bool hdr) } } - for (const auto& f : surfaceFormats) + for (const auto& f : caps.Formats) { if (f.format == VK_FORMAT_B8G8R8A8_UNORM && f.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) { @@ -104,79 +86,58 @@ void VulkanSwapChain::SelectFormat(bool hdr) } } - format = surfaceFormats.front(); + format = caps.Formats.front(); } -void VulkanSwapChain::SelectPresentMode(bool vsync, bool exclusivefullscreen) +bool VulkanSwapChain::CreateSwapchain(int width, int height, int imageCount, bool vsync, bool hdr, bool exclusivefullscreen) { - std::vector presentModes = GetPresentModes(exclusivefullscreen); - if (presentModes.empty()) + lost = false; + + VulkanSurfaceCapabilities caps = GetSurfaceCapabilities(exclusivefullscreen); + + if (exclusivefullscreen && (caps.PresentModes.empty() || !caps.FullScreenExclusive.fullScreenExclusiveSupported)) + { + // Try again without exclusive full screen. + exclusivefullscreen = false; + caps = GetSurfaceCapabilities(exclusivefullscreen); + } + + if (caps.PresentModes.empty()) throw std::runtime_error("No surface present modes supported"); + bool supportsFifoRelaxed = std::find(caps.PresentModes.begin(), caps.PresentModes.end(), VK_PRESENT_MODE_FIFO_RELAXED_KHR) != caps.PresentModes.end(); + bool supportsMailbox = std::find(caps.PresentModes.begin(), caps.PresentModes.end(), VK_PRESENT_MODE_MAILBOX_KHR) != caps.PresentModes.end(); + bool supportsImmediate = std::find(caps.PresentModes.begin(), caps.PresentModes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR) != caps.PresentModes.end(); + presentMode = VK_PRESENT_MODE_FIFO_KHR; if (vsync) { - bool supportsFifoRelaxed = std::find(presentModes.begin(), presentModes.end(), VK_PRESENT_MODE_FIFO_RELAXED_KHR) != presentModes.end(); if (supportsFifoRelaxed) presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR; } else { - bool supportsMailbox = std::find(presentModes.begin(), presentModes.end(), VK_PRESENT_MODE_MAILBOX_KHR) != presentModes.end(); - bool supportsImmediate = std::find(presentModes.begin(), presentModes.end(), VK_PRESENT_MODE_IMMEDIATE_KHR) != presentModes.end(); - if (supportsMailbox) - presentMode = VK_PRESENT_MODE_MAILBOX_KHR; - else if (supportsImmediate) - presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + if (exclusivefullscreen) // Exclusive full screen doesn't seem to support mailbox for some reason, even if it is advertised + { + if (supportsImmediate) + presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + else if (supportsMailbox) + presentMode = VK_PRESENT_MODE_MAILBOX_KHR; + } + else + { + if (supportsMailbox) + presentMode = VK_PRESENT_MODE_MAILBOX_KHR; + else if (supportsImmediate) + presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + } } -} -bool VulkanSwapChain::CreateSwapchain(int width, int height, int imageCount, bool exclusivefullscreen, VkSwapchainKHR oldSwapChain) -{ - lost = false; - - VkResult result; - VkSurfaceCapabilitiesKHR surfaceCapabilities; -#ifdef WIN32 - if (exclusivefullscreen && device->SupportsDeviceExtension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) - { - VkPhysicalDeviceSurfaceInfo2KHR info = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR }; - VkSurfaceFullScreenExclusiveInfoEXT exclusiveInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; - VkSurfaceFullScreenExclusiveWin32InfoEXT exclusiveWin32Info = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT }; - info.surface = device->Surface->Surface; - info.pNext = &exclusiveInfo; - exclusiveInfo.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT; - exclusiveInfo.pNext = &exclusiveWin32Info; - exclusiveWin32Info.hmonitor = MonitorFromWindow(device->Surface->Window, MONITOR_DEFAULTTONEAREST); - - VkSurfaceCapabilities2KHR capabilites = { VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR }; - VkSurfaceCapabilitiesFullScreenExclusiveEXT exclusiveCapabilities = { VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT }; - capabilites.pNext = &exclusiveCapabilities; - - result = vkGetPhysicalDeviceSurfaceCapabilities2KHR(device->PhysicalDevice.Device, &info, &capabilites); - if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceCapabilities2EXT failed"); - - surfaceCapabilities = capabilites.surfaceCapabilities; - exclusivefullscreen = exclusiveCapabilities.fullScreenExclusiveSupported == VK_TRUE; - } - else - { - result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &surfaceCapabilities); - if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed"); - exclusivefullscreen = false; - } -#else - result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &surfaceCapabilities); - if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed"); - exclusivefullscreen = false; -#endif + SelectFormat(caps, hdr); actualExtent = { static_cast(width), static_cast(height) }; - actualExtent.width = std::max(surfaceCapabilities.minImageExtent.width, std::min(surfaceCapabilities.maxImageExtent.width, actualExtent.width)); - actualExtent.height = std::max(surfaceCapabilities.minImageExtent.height, std::min(surfaceCapabilities.maxImageExtent.height, actualExtent.height)); + actualExtent.width = std::max(caps.Capabilites.minImageExtent.width, std::min(caps.Capabilites.maxImageExtent.width, actualExtent.width)); + actualExtent.height = std::max(caps.Capabilites.minImageExtent.height, std::min(caps.Capabilites.maxImageExtent.height, actualExtent.height)); if (actualExtent.width == 0 || actualExtent.height == 0) { swapchain = VK_NULL_HANDLE; @@ -184,9 +145,16 @@ bool VulkanSwapChain::CreateSwapchain(int width, int height, int imageCount, boo return false; } - imageCount = std::max(surfaceCapabilities.minImageCount, std::min(surfaceCapabilities.maxImageCount, (uint32_t)imageCount)); + if (caps.Capabilites.maxImageCount != 0) + imageCount = std::min(caps.Capabilites.maxImageCount, (uint32_t)imageCount); + imageCount = std::max(caps.Capabilites.minImageCount, (uint32_t)imageCount); VkSwapchainCreateInfoKHR swapChainCreateInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR }; +#ifdef WIN32 + VkSurfaceFullScreenExclusiveInfoEXT exclusiveInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; + VkSurfaceFullScreenExclusiveWin32InfoEXT exclusiveWin32Info = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT }; +#endif + swapChainCreateInfo.surface = device->Surface->Surface; swapChainCreateInfo.minImageCount = imageCount; swapChainCreateInfo.imageFormat = format.format; @@ -209,25 +177,27 @@ bool VulkanSwapChain::CreateSwapchain(int width, int height, int imageCount, boo swapChainCreateInfo.pQueueFamilyIndices = nullptr; } - swapChainCreateInfo.preTransform = surfaceCapabilities.currentTransform; + swapChainCreateInfo.preTransform = caps.Capabilites.currentTransform; swapChainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; // If alpha channel is passed on to the DWM or not swapChainCreateInfo.presentMode = presentMode; - swapChainCreateInfo.clipped = VK_FALSE;// VK_TRUE; - swapChainCreateInfo.oldSwapchain = oldSwapChain; + swapChainCreateInfo.clipped = VK_TRUE; // Applications SHOULD set this value to VK_TRUE if they do not expect to read back the content of presentable images before presenting them or after reacquiring them, and if their fragment shaders do not have any side effects that require them to run for all pixels in the presentable image + swapChainCreateInfo.oldSwapchain = swapchain; #ifdef WIN32 - VkSurfaceFullScreenExclusiveInfoEXT exclusiveInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; - VkSurfaceFullScreenExclusiveWin32InfoEXT exclusiveWin32Info = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT }; - if (exclusivefullscreen && device->SupportsDeviceExtension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) + if (exclusivefullscreen) { swapChainCreateInfo.pNext = &exclusiveInfo; - exclusiveInfo.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT; exclusiveInfo.pNext = &exclusiveWin32Info; + exclusiveInfo.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT; exclusiveWin32Info.hmonitor = MonitorFromWindow(device->Surface->Window, MONITOR_DEFAULTTONEAREST); } #endif - result = vkCreateSwapchainKHR(device->device, &swapChainCreateInfo, nullptr, &swapchain); + VkResult result = vkCreateSwapchainKHR(device->device, &swapChainCreateInfo, nullptr, &swapchain); + + if (swapChainCreateInfo.oldSwapchain) + vkDestroySwapchainKHR(device->device, swapChainCreateInfo.oldSwapchain, nullptr); + if (result != VK_SUCCESS) { swapchain = VK_NULL_HANDLE; @@ -236,7 +206,7 @@ bool VulkanSwapChain::CreateSwapchain(int width, int height, int imageCount, boo } #ifdef WIN32 - if (exclusivefullscreen && device->SupportsDeviceExtension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) + if (exclusivefullscreen) { result = vkAcquireFullScreenExclusiveModeEXT(device->device, swapchain); if (result != VK_SUCCESS) @@ -312,45 +282,84 @@ void VulkanSwapChain::QueuePresent(int imageIndex, VulkanSemaphore* semaphore) } } -std::vector VulkanSwapChain::GetSurfaceFormats() +VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusivefullscreen) { - uint32_t surfaceFormatCount = 0; - VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(device->PhysicalDevice.Device, device->Surface->Surface, &surfaceFormatCount, nullptr); - if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormatsKHR failed"); - else if (surfaceFormatCount == 0) - return {}; + // They sure made it easy to query something that isn't even time critical. Good job guys! - std::vector surfaceFormats(surfaceFormatCount); - result = vkGetPhysicalDeviceSurfaceFormatsKHR(device->PhysicalDevice.Device, device->Surface->Surface, &surfaceFormatCount, surfaceFormats.data()); - if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormatsKHR failed"); - return surfaceFormats; -} + VulkanSurfaceCapabilities caps; -std::vector VulkanSwapChain::GetPresentModes(bool exclusivefullscreen) -{ + VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR }; #ifdef WIN32 - if (exclusivefullscreen && device->SupportsDeviceExtension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) + VkSurfaceFullScreenExclusiveInfoEXT exclusiveInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; + VkSurfaceFullScreenExclusiveWin32InfoEXT exclusiveWin32Info = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT }; +#endif + +#ifdef WIN32 + if (exclusivefullscreen) { - VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR }; - VkSurfaceFullScreenExclusiveInfoEXT exclusiveInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; - surfaceInfo.surface = device->Surface->Surface; - surfaceInfo.pNext = &exclusiveInfo; exclusiveInfo.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT; + exclusiveWin32Info.hmonitor = MonitorFromWindow(device->Surface->Window, MONITOR_DEFAULTTONEAREST); + } +#endif + + surfaceInfo.surface = device->Surface->Surface; + + if (device->SupportsExtension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) + { + const void** next = &surfaceInfo.pNext; + +#ifdef WIN32 + if (exclusivefullscreen && device->SupportsExtension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) + { + *next = &exclusiveInfo; + next = const_cast(&exclusiveInfo.pNext); + + *next = &exclusiveWin32Info; + next = &exclusiveWin32Info.pNext; + } +#endif + + VkSurfaceCapabilities2KHR caps2 = { VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR }; + next = const_cast(&caps2.pNext); + +#ifdef WIN32 + if (exclusivefullscreen && device->SupportsExtension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) + { + *next = &caps.FullScreenExclusive; + next = const_cast(&caps.FullScreenExclusive.pNext); + } +#endif + + VkResult result = vkGetPhysicalDeviceSurfaceCapabilities2KHR(device->PhysicalDevice.Device, &surfaceInfo, &caps2); + if (result != VK_SUCCESS) + throw std::runtime_error("vkGetPhysicalDeviceSurfaceCapabilities2KHR failed"); + + caps.Capabilites = caps2.surfaceCapabilities; + } + else + { + VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &caps.Capabilites); + if (result != VK_SUCCESS) + throw std::runtime_error("vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed"); + } + +#ifdef WIN32 + if (exclusivefullscreen && device->SupportsExtension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)) + { + const void** next = &surfaceInfo.pNext; uint32_t presentModeCount = 0; VkResult result = vkGetPhysicalDeviceSurfacePresentModes2EXT(device->PhysicalDevice.Device, &surfaceInfo, &presentModeCount, nullptr); if (result != VK_SUCCESS) throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModes2EXT failed"); - else if (presentModeCount == 0) - return {}; - std::vector presentModes(presentModeCount); - result = vkGetPhysicalDeviceSurfacePresentModes2EXT(device->PhysicalDevice.Device, &surfaceInfo, &presentModeCount, presentModes.data()); - if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModes2EXT failed"); - return presentModes; + if (presentModeCount > 0) + { + caps.PresentModes.resize(presentModeCount); + result = vkGetPhysicalDeviceSurfacePresentModes2EXT(device->PhysicalDevice.Device, &surfaceInfo, &presentModeCount, caps.PresentModes.data()); + if (result != VK_SUCCESS) + throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModes2EXT failed"); + } } else #endif @@ -359,13 +368,51 @@ std::vector VulkanSwapChain::GetPresentModes(bool exclusiveful VkResult result = vkGetPhysicalDeviceSurfacePresentModesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &presentModeCount, nullptr); if (result != VK_SUCCESS) throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModesKHR failed"); - else if (presentModeCount == 0) - return {}; - std::vector presentModes(presentModeCount); - result = vkGetPhysicalDeviceSurfacePresentModesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &presentModeCount, presentModes.data()); - if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModesKHR failed"); - return presentModes; + if (presentModeCount > 0) + { + caps.PresentModes.resize(presentModeCount); + result = vkGetPhysicalDeviceSurfacePresentModesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &presentModeCount, caps.PresentModes.data()); + if (result != VK_SUCCESS) + throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModesKHR failed"); + } } + + if (device->SupportsExtension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) + { + uint32_t surfaceFormatCount = 0; + VkResult result = vkGetPhysicalDeviceSurfaceFormats2KHR(device->PhysicalDevice.Device, &surfaceInfo, &surfaceFormatCount, nullptr); + if (result != VK_SUCCESS) + throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormats2KHR failed"); + + if (surfaceFormatCount > 0) + { + std::vector formats(surfaceFormatCount, { VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR }); + result = vkGetPhysicalDeviceSurfaceFormats2KHR(device->PhysicalDevice.Device, &surfaceInfo, &surfaceFormatCount, formats.data()); + if (result != VK_SUCCESS) + throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormats2KHR failed"); + + for (VkSurfaceFormat2KHR& fmt : formats) + caps.Formats.push_back(fmt.surfaceFormat); + } + } + else + { + uint32_t surfaceFormatCount = 0; + VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(device->PhysicalDevice.Device, device->Surface->Surface, &surfaceFormatCount, nullptr); + if (result != VK_SUCCESS) + throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormatsKHR failed"); + + if (surfaceFormatCount > 0) + { + caps.Formats.resize(surfaceFormatCount); + result = vkGetPhysicalDeviceSurfaceFormatsKHR(device->PhysicalDevice.Device, device->Surface->Surface, &surfaceFormatCount, caps.Formats.data()); + if (result != VK_SUCCESS) + throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormatsKHR failed"); + } + } + + caps.FullScreenExclusive.pNext = nullptr; + + return caps; } diff --git a/src/common/rendering/vulkan/shaders/vk_ppshader.cpp b/src/common/rendering/vulkan/shaders/vk_ppshader.cpp index d9f6078c7..3aa6861eb 100644 --- a/src/common/rendering/vulkan/shaders/vk_ppshader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_ppshader.cpp @@ -36,12 +36,14 @@ VkPPShader::VkPPShader(VulkanRenderDevice* fb, PPShader *shader) : fb(fb) prolog += shader->Defines; VertexShader = ShaderBuilder() - .VertexShader(LoadShaderCode(shader->VertexShader, "", shader->Version).GetChars()) + .Type(ShaderType::Vertex) + .AddSource(shader->VertexShader.GetChars(), LoadShaderCode(shader->VertexShader, "", shader->Version).GetChars()) .DebugName(shader->VertexShader.GetChars()) .Create(shader->VertexShader.GetChars(), fb->device.get()); FragmentShader = ShaderBuilder() - .FragmentShader(LoadShaderCode(shader->FragmentShader, prolog, shader->Version).GetChars()) + .Type(ShaderType::Fragment) + .AddSource(shader->FragmentShader.GetChars(), LoadShaderCode(shader->FragmentShader, prolog, shader->Version).GetChars()) .DebugName(shader->FragmentShader.GetChars()) .Create(shader->FragmentShader.GetChars(), fb->device.get()); diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index 4ccfbd302..0140aa6cb 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -352,7 +352,8 @@ std::unique_ptr VkShaderManager::LoadVertShader(FString shadername code << LoadPrivateShaderLump(vert_lump).GetChars() << "\n"; return ShaderBuilder() - .VertexShader(code.GetChars()) + .Type(ShaderType::Vertex) + .AddSource(shadername.GetChars(), code.GetChars()) .DebugName(shadername.GetChars()) .Create(shadername.GetChars(), fb->device.get()); } @@ -444,7 +445,8 @@ std::unique_ptr VkShaderManager::LoadFragShader(FString shadername } return ShaderBuilder() - .FragmentShader(code.GetChars()) + .Type(ShaderType::Fragment) + .AddSource(shadername.GetChars(), code.GetChars()) .DebugName(shadername.GetChars()) .Create(shadername.GetChars(), fb->device.get()); } diff --git a/src/common/rendering/vulkan/system/vk_commandbuffer.cpp b/src/common/rendering/vulkan/system/vk_commandbuffer.cpp index 59d19719d..41dc568e5 100644 --- a/src/common/rendering/vulkan/system/vk_commandbuffer.cpp +++ b/src/common/rendering/vulkan/system/vk_commandbuffer.cpp @@ -241,7 +241,7 @@ void VkCommandBufferManager::UpdateGpuStats() if (mNextTimestampQuery > 0) mTimestampQueryPool->getResults(0, mNextTimestampQuery, sizeof(uint64_t) * mNextTimestampQuery, timestamps, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT); - double timestampPeriod = fb->device->PhysicalDevice.Properties.limits.timestampPeriod; + double timestampPeriod = fb->device->PhysicalDevice.Properties.Properties.limits.timestampPeriod; gpuStatOutput = ""; for (auto& q : timeElapsedQueries) diff --git a/src/common/rendering/vulkan/system/vk_renderdevice.cpp b/src/common/rendering/vulkan/system/vk_renderdevice.cpp index 7ef3e5531..ecc9a5ffe 100644 --- a/src/common/rendering/vulkan/system/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/system/vk_renderdevice.cpp @@ -72,21 +72,6 @@ EXTERN_CVAR(Int, gl_tonemap) EXTERN_CVAR(Int, screenblocks) EXTERN_CVAR(Bool, cl_capfps) -CCMD(vk_memstats) -{ - if (screen->IsVulkan()) - { - VmaStats stats = {}; - vmaCalculateStats(static_cast(screen)->device->allocator, &stats); - Printf("Allocated objects: %d, used bytes: %d MB\n", (int)stats.total.allocationCount, (int)stats.total.usedBytes / (1024 * 1024)); - Printf("Unused range count: %d, unused bytes: %d MB\n", (int)stats.total.unusedRangeCount, (int)stats.total.unusedBytes / (1024 * 1024)); - } - else - { - Printf("Vulkan is not the current render device\n"); - } -} - CVAR(Bool, vk_raytrace, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // Physical device info @@ -108,7 +93,7 @@ CCMD(vk_listdevices) { for (size_t i = 0; i < SupportedDevices.size(); i++) { - Printf("#%d - %s\n", (int)i, SupportedDevices[i].Device->Properties.deviceName); + Printf("#%d - %s\n", (int)i, SupportedDevices[i].Device->Properties.Properties.deviceName); } } @@ -179,7 +164,7 @@ void VulkanRenderDevice::InitializeState() } // Use the same names here as OpenGL returns. - switch (device->PhysicalDevice.Properties.vendorID) + switch (device->PhysicalDevice.Properties.Properties.vendorID) { case 0x1002: vendorstring = "ATI Technologies Inc."; break; case 0x10DE: vendorstring = "NVIDIA Corporation"; break; @@ -189,8 +174,8 @@ void VulkanRenderDevice::InitializeState() hwcaps = RFL_SHADER_STORAGE_BUFFER | RFL_BUFFER_STORAGE; glslversion = 4.50f; - uniformblockalignment = (unsigned int)device->PhysicalDevice.Properties.limits.minUniformBufferOffsetAlignment; - maxuniformblock = device->PhysicalDevice.Properties.limits.maxUniformBufferRange; + uniformblockalignment = (unsigned int)device->PhysicalDevice.Properties.Properties.limits.minUniformBufferOffsetAlignment; + maxuniformblock = device->PhysicalDevice.Properties.Properties.limits.maxUniformBufferRange; mCommands.reset(new VkCommandBufferManager(this)); @@ -293,8 +278,7 @@ void VulkanRenderDevice::PostProcessScene(bool swscene, int fixedcm, float flash const char* VulkanRenderDevice::DeviceName() const { - const auto &props = device->PhysicalDevice.Properties; - return props.deviceName; + return device->PhysicalDevice.Properties.Properties.deviceName; } void VulkanRenderDevice::SetVSync(bool vsync) @@ -513,7 +497,7 @@ unsigned int VulkanRenderDevice::GetLightBufferBlockSize() const void VulkanRenderDevice::PrintStartupLog() { - const auto &props = device->PhysicalDevice.Properties; + const auto &props = device->PhysicalDevice.Properties.Properties; FString deviceType; switch (props.deviceType) @@ -585,5 +569,5 @@ void VulkanRenderDevice::SetSceneRenderTarget(bool useSSAO) bool VulkanRenderDevice::RaytracingEnabled() { - return vk_raytrace && device->SupportsDeviceExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME); + return vk_raytrace && device->SupportsExtension(VK_KHR_RAY_QUERY_EXTENSION_NAME); } diff --git a/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp b/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp index 01bc8f59a..474934e67 100644 --- a/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp +++ b/src/common/rendering/vulkan/textures/vk_renderbuffers.cpp @@ -41,7 +41,7 @@ VkRenderBuffers::~VkRenderBuffers() VkSampleCountFlagBits VkRenderBuffers::GetBestSampleCount() { - const auto &limits = fb->device->PhysicalDevice.Properties.limits; + const auto &limits = fb->device->PhysicalDevice.Properties.Properties.limits; VkSampleCountFlags deviceSampleCounts = limits.sampledImageColorSampleCounts & limits.sampledImageDepthSampleCounts & limits.sampledImageStencilSampleCounts; int requestedSamples = clamp((int)gl_multisample, 0, 64); From 71cc93f42cf5de7ec80f66f70c98b739c77b04dc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 16 Sep 2023 07:44:21 +0200 Subject: [PATCH 126/223] - fixed: ZScript's lump reader may not truncate strings at 0 bytes, like all other callers of GetStringFromLump need. --- src/common/scripting/interface/vmnatives.cpp | 2 +- src/common/utility/cmdlib.cpp | 4 ++-- src/common/utility/cmdlib.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index 16bf394db..350bf5ce3 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -844,7 +844,7 @@ DEFINE_ACTION_FUNCTION(_Wads, ReadLump) PARAM_PROLOGUE; PARAM_INT(lump); const bool isLumpValid = lump >= 0 && lump < fileSystem.GetNumEntries(); - ACTION_RETURN_STRING(isLumpValid ? GetStringFromLump(lump) : FString()); + ACTION_RETURN_STRING(isLumpValid ? GetStringFromLump(lump, false) : FString()); } //========================================================================== diff --git a/src/common/utility/cmdlib.cpp b/src/common/utility/cmdlib.cpp index 8dbce2b7a..28cba8fcd 100644 --- a/src/common/utility/cmdlib.cpp +++ b/src/common/utility/cmdlib.cpp @@ -1016,10 +1016,10 @@ void uppercopy(char* to, const char* from) // Loads a zero terminated string from a lump in the file system //========================================================================== -FString GetStringFromLump(int lump) +FString GetStringFromLump(int lump, bool zerotruncate) { auto fd = fileSystem.ReadFile(lump); FString ScriptBuffer(fd.GetString(), fd.GetSize()); - ScriptBuffer.Truncate(strlen(ScriptBuffer.GetChars())); // this is necessary to properly truncate the generated string to not contain 0 bytes. + if (zerotruncate) ScriptBuffer.Truncate(strlen(ScriptBuffer.GetChars())); // this is necessary to properly truncate the generated string to not contain 0 bytes. return ScriptBuffer; } diff --git a/src/common/utility/cmdlib.h b/src/common/utility/cmdlib.h index 06b5a5e0f..6f40c184c 100644 --- a/src/common/utility/cmdlib.h +++ b/src/common/utility/cmdlib.h @@ -87,7 +87,7 @@ struct MD5Context; void md5Update(FileReader& file, MD5Context& md5, unsigned len); void uppercopy(char* to, const char* from); -FString GetStringFromLump(int lump); +FString GetStringFromLump(int lump, bool zerotruncate = true); inline void fillshort(void* buff, size_t count, uint16_t clear) { From 81e42142af5cada7074d58775a101ff534bf48b7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 16 Sep 2023 09:25:21 +0200 Subject: [PATCH 127/223] - added compatibility handler for Phocas Island 2 MAP01. --- wadsrc/static/zscript/level_compatibility.zs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wadsrc/static/zscript/level_compatibility.zs b/wadsrc/static/zscript/level_compatibility.zs index e88343ec2..348fc9c63 100644 --- a/wadsrc/static/zscript/level_compatibility.zs +++ b/wadsrc/static/zscript/level_compatibility.zs @@ -2158,6 +2158,12 @@ class LevelCompatibility : LevelPostProcessor SetThingEdNum(59, 3); break; } + + case '3F0965ADCEB2F4A7BF46FADF6DD941B0': // phocas2.wad map01 + { + SetThingEdNum(699, 9044); + break; + } } } } From ea51c92fda93dedfd36e60a3ab2504e10aa9a80f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 16 Sep 2023 09:48:43 +0200 Subject: [PATCH 128/223] - validate partner seg index in LoadGLZSegs before using it KDiZD Z1M10 has something bogus in there, this case will now trigger a node rebuild. --- src/maploader/maploader.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index fdb409c6a..095c795ec 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -426,7 +426,7 @@ void MapLoader::LoadVertexes(MapData * map) if (numvertexes == 0) { - I_Error("Map has no vertices.\n"); + I_Error("Map has no vertices."); } // Allocate memory for buffer. @@ -497,6 +497,11 @@ void MapLoader::LoadGLZSegs (FileReader &data, int type) uint32_t partner = data.ReadUInt32(); uint32_t line; + if (partner != 0xffffffffu && partner >= Level->segs.Size()) + { + I_Error("partner seg index out of range for subsector %d, seg %d", i, j); + } + if (type >= 2) { line = data.ReadUInt32(); @@ -563,7 +568,7 @@ void MapLoader::LoadZNodes(FileReader &data, int glnodes) if (orgVerts > Level->vertexes.Size()) { // These nodes are based on a map with more vertex data than we have. // We can't use them. - throw CRecoverableError("Incorrect number of vertexes in nodes.\n"); + I_Error("Incorrect number of vertexes in nodes."); } auto oldvertexes = &Level->vertexes[0]; if (orgVerts + newVerts != Level->vertexes.Size()) @@ -606,7 +611,7 @@ void MapLoader::LoadZNodes(FileReader &data, int glnodes) // segs used by subsectors. if (numSegs != currSeg) { - throw CRecoverableError("Incorrect number of segs in nodes.\n"); + I_Error("Incorrect number of segs in nodes."); } Level->segs.Alloc(numSegs); @@ -758,6 +763,7 @@ bool MapLoader::LoadExtendedNodes (FileReader &dalump, uint32_t id) Printf("Error loading nodes: %s\n", error.what()); } // clean up. + Printf("The BSP will be rebuilt\n"); ForceNodeBuild = true; Level->subsectors.Clear(); Level->segs.Clear(); @@ -1654,7 +1660,7 @@ void MapLoader::FinishLoadingLineDefs () } else { - I_Error ("%d sidedefs is not enough\n", sidecount); + I_Error ("%d sidedefs is not enough", sidecount); } } @@ -2695,7 +2701,7 @@ void MapLoader::GroupLines (bool buildmap) } if (flaggedNoFronts) { - I_Error ("You need to fix these lines to play this map.\n"); + I_Error ("You need to fix these lines to play this map."); } // build line tables for each sector @@ -3086,8 +3092,8 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position) } } - // If loading the regular nodes failed try GL nodes before considering a rebuild - if (!NodesLoaded) + // If loading the regular nodes failed try GL nodes before considering a rebuild (unless a rebuild was already asked for) + if (!NodesLoaded && !ForceNodeBuild) { if (LoadGLNodes(map)) reloop = true; From bd4f4f739a3e4134da6fd1bdf39e3622dbadbdee Mon Sep 17 00:00:00 2001 From: John Stebbins Date: Thu, 23 Feb 2023 07:44:20 -0700 Subject: [PATCH 129/223] Fix gameinfo load from same directory as file containing gameinfo lump Fixes scenario 2 in https://github.com/ZDoom/gzdoom/issues/2011#issuecomment-1440997829 --- src/d_main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 256632cfc..e34b59459 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1798,6 +1798,8 @@ static FString ParseGameInfo(std::vector &pwads, const char *fn, co bool isDir; const char *lastSlash = strrchr (fn, '/'); + if (lastSlash == NULL) + lastSlash = strrchr (fn, ':'); sc.OpenMem("GAMEINFO", data, size); while(sc.GetToken()) @@ -1822,8 +1824,7 @@ static FString ParseGameInfo(std::vector &pwads, const char *fn, co FString checkpath; if (lastSlash != NULL) { - checkpath = FString(fn, (lastSlash - fn) + 1); - checkpath += sc.String; + checkpath = FString(fn, lastSlash - fn) + '/' + sc.String; } else { From 56c2bd018d9b32ac7abf855f70aefd8c3189673f Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 3 Feb 2023 14:36:55 +0100 Subject: [PATCH 130/223] Add more information in saved game comments Save games now store kills/items/secrets and player health/armor in the comment string, which is displayed in the save/load game menu. This change is not retroactive: old savegames will not display this information until they are overwritten. --- src/g_game.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index f68fca225..f686a573b 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2289,7 +2289,25 @@ static void PutSaveComment (FSerializer &arc) // Append elapsed time const char *const time = GStrings("SAVECOMMENT_TIME"); levelTime = primaryLevel->time / TICRATE; - comment.AppendFormat("%s: %02d:%02d:%02d", time, levelTime/3600, (levelTime%3600)/60, levelTime%60); + comment.AppendFormat("%s: %02d:%02d:%02d\n", time, levelTime/3600, (levelTime%3600)/60, levelTime%60); + + // Append kills/items/secrets + comment.AppendFormat("K: %d/%d - I: %d/%d - S: %d/%d\n", primaryLevel->killed_monsters, primaryLevel->total_monsters, primaryLevel->found_items, primaryLevel->total_items, primaryLevel->found_secrets, primaryLevel->total_secrets); + + // Append player health and armor + const char *const health = GStrings("SAVECOMMENT_HEALTH"); + const char *const armor = GStrings("SAVECOMMENT_ARMOR"); + int armorAmount = 0; + auto basicArmorItem = primaryLevel->Players[consoleplayer]->mo->FindInventory(NAME_BasicArmor); + if (basicArmorItem) { + armorAmount += basicArmorItem->IntVar(NAME_Amount); + } + auto hexenArmorItem = primaryLevel->Players[consoleplayer]->mo->FindInventory(NAME_HexenArmor); + if (hexenArmorItem) { + double *Slots = (double*)hexenArmorItem->ScriptVar(NAME_Slots, nullptr); + armorAmount += Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4]; + } + comment.AppendFormat("%s: %d - %s: %d", health, primaryLevel->Players[consoleplayer]->mo->health, armor, armorAmount); // Write out the comment arc.AddString("Comment", comment); From 23ffaaecb0841b9790ed1e7674c6e48f09244364 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 16 Sep 2023 11:45:00 +0200 Subject: [PATCH 131/223] - changed last commit to not translate the text written to the savegame info. This would be a bit problematic if it was transferred to other systems if the source language cannot be understood. --- src/g_game.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index f686a573b..5a4a51eec 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2295,8 +2295,8 @@ static void PutSaveComment (FSerializer &arc) comment.AppendFormat("K: %d/%d - I: %d/%d - S: %d/%d\n", primaryLevel->killed_monsters, primaryLevel->total_monsters, primaryLevel->found_items, primaryLevel->total_items, primaryLevel->found_secrets, primaryLevel->total_secrets); // Append player health and armor - const char *const health = GStrings("SAVECOMMENT_HEALTH"); - const char *const armor = GStrings("SAVECOMMENT_ARMOR"); + const char* const health = "Health";// GStrings("SAVECOMMENT_HEALTH"); + const char* const armor = "Armor"; // GStrings("SAVECOMMENT_ARMOR"); int armorAmount = 0; auto basicArmorItem = primaryLevel->Players[consoleplayer]->mo->FindInventory(NAME_BasicArmor); if (basicArmorItem) { From 7fbd99ca0f84b9b342d22530b89714ae59c47c13 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 16 Sep 2023 12:06:07 +0200 Subject: [PATCH 132/223] - fixed flags for gl_lightmode. With how this is being handled now, the CVAR needs to have the CVAR_GLOBALCONFIG flag and CVAR_NOINITCALL unset or it simply won't work right. Since its meaning has completely changed now (i.e. it's mainly a performance switch to a less demanding implementation instead of being able to select vastly different lighting methods) making it global is more sensible. --- src/g_level.cpp | 4 ++-- src/gameconfigfile.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index d161059e6..c21031706 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -151,9 +151,9 @@ CUSTOM_CVAR(Int, gl_maplightmode, -1, CVAR_NOINITCALL) // this is just for testi if (self > 5 || self < -1) self = -1; } -CUSTOM_CVAR(Int, gl_lightmode, 1, CVAR_ARCHIVE | CVAR_NOINITCALL) +CUSTOM_CVAR(Int, gl_lightmode, 1, CVAR_ARCHIVE) { - if (self < 0 || self > 2) self = 2; + if (self < 0 || self > 2) self = 1; } ELightMode getRealLightmode(FLevelLocals* Level, bool for3d) diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 5a801bff3..0b3931e88 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -612,7 +612,7 @@ void FGameConfigFile::DoGlobalSetup () if (const auto var = FindCVar("gl_lightmode", NULL)) { UCVarValue v = var->GetGenericRep(CVAR_Int); - v.Int /= 8; // all legacy modes map to 0, ZDoom software to 1 and Vanilla software to 2. + v.Int = v.Int == 16 ? 2 : v.Int == 8 ? 1 : 0; var->SetGenericRep(v, CVAR_Int); } } From f55e388d3fe13c6b6cbfabf07e92902766804ca2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 16 Sep 2023 12:09:57 +0200 Subject: [PATCH 133/223] - add description to gl_lightmode --- src/g_level.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index c21031706..a4c3648bd 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -151,7 +151,7 @@ CUSTOM_CVAR(Int, gl_maplightmode, -1, CVAR_NOINITCALL) // this is just for testi if (self > 5 || self < -1) self = -1; } -CUSTOM_CVAR(Int, gl_lightmode, 1, CVAR_ARCHIVE) +CUSTOM_CVARD(Int, gl_lightmode, 1, CVAR_ARCHIVE, "Select lighting mode. 2 is vanilla accurate, 1 is accurate to the ZDoom software renderer and 0 is a less demanding non-shader implementation") { if (self < 0 || self > 2) self = 1; } From c27beb0be8105e68f4ff77c8f05ff8f7c1a2acbc Mon Sep 17 00:00:00 2001 From: nashmuhandes Date: Sat, 16 Sep 2023 23:27:53 +0800 Subject: [PATCH 134/223] Delete the light probe DoomEdNum --- wadsrc/static/mapinfo/common.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/wadsrc/static/mapinfo/common.txt b/wadsrc/static/mapinfo/common.txt index 6982a5bce..f079ee6e6 100644 --- a/wadsrc/static/mapinfo/common.txt +++ b/wadsrc/static/mapinfo/common.txt @@ -136,7 +136,6 @@ DoomEdNums 9872 = SpotLightFlickerAttenuated 9873 = SectorSpotLightAttenuated 9874 = SpotLightFlickerRandomAttenuated - 9875 = None // ZDRay light probe 9876 = None // ZDRay static point light 9881 = None // ZDRay static spotlight 9890 = None // ZDRayInfo From e86de4463f8d938ac15d099854e7fdfe9f51ad71 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 16 Sep 2023 21:05:44 +0200 Subject: [PATCH 135/223] fixed CheckswitchRange logic for multiple switches on a line. --- src/playsim/p_switch.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/playsim/p_switch.cpp b/src/playsim/p_switch.cpp index 9daf8cf9d..e89f03011 100644 --- a/src/playsim/p_switch.cpp +++ b/src/playsim/p_switch.cpp @@ -195,9 +195,12 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, const DVector3 * } } - return (user->Level->i_compatflags2 & COMPATF2_CHECKSWITCHRANGE) + if ((user->Level->i_compatflags2 & COMPATF2_CHECKSWITCHRANGE) ? (user->Top() >= open.top) - : (user->Top() > open.top); + : (user->Top() > open.top)) + { + return true; + } } if ((TexAnim.FindSwitch(side->GetTexture(side_t::bottom))) != NULL) { @@ -219,9 +222,12 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, const DVector3 * } } - return (user->Level->i_compatflags2 & COMPATF2_CHECKSWITCHRANGE) + if ((user->Level->i_compatflags2 & COMPATF2_CHECKSWITCHRANGE) ? (user->Z() <= open.bottom) - : (user->Z() < open.bottom); + : (user->Z() < open.bottom)) + { + return true; + } } if ((flags & ML_3DMIDTEX) || (TexAnim.FindSwitch(side->GetTexture(side_t::mid))) != NULL) { From d596e5a8fab1bda6d207b363c427e95c45e2d186 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 16 Sep 2023 21:35:01 +0200 Subject: [PATCH 136/223] - fixed: EV_DoDonut checked the wrong compatibility variable. This missed all map specified flags. --- src/playsim/mapthinkers/a_floor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/playsim/mapthinkers/a_floor.cpp b/src/playsim/mapthinkers/a_floor.cpp index 330738494..ff7c91412 100644 --- a/src/playsim/mapthinkers/a_floor.cpp +++ b/src/playsim/mapthinkers/a_floor.cpp @@ -811,7 +811,7 @@ bool FLevelLocals::EV_DoDonut (int tag, line_t *line, double pillarspeed, double if (!s2) // note lowest numbered line around continue; // pillar must be two-sided - if (!(compatflags2 & COMPATF2_FLOORMOVE) && s2->PlaneMoving(sector_t::floor)) + if (!(i_compatflags2 & COMPATF2_FLOORMOVE) && s2->PlaneMoving(sector_t::floor)) continue; for (auto ln : s2->Lines) From f7c379b7202dc04d35b2d85ade9d82ff88655eff Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 16 Sep 2023 21:55:35 +0200 Subject: [PATCH 137/223] - fixed: The UDMF loader did not adjust the floor/ceiling overlap state after processing UDMF sector plane properties. --- src/maploader/udmf.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/maploader/udmf.cpp b/src/maploader/udmf.cpp index 941b33e0d..d02ee237e 100644 --- a/src/maploader/udmf.cpp +++ b/src/maploader/udmf.cpp @@ -2060,6 +2060,7 @@ public: DVector3 n = DVector3(cp[0], cp[1], cp[2]).Unit(); sec->ceilingplane.set(n.X, n.Y, n.Z, cp[3]); } + sec->CheckOverlap(); if (lightcolor == ~0u && fadecolor == ~0u && desaturation == -1 && fogdensity == -1) { From 5f11fd051bc73ca0a9b871fa2cc02dc0b4bfbbec Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 16 Sep 2023 22:17:09 +0200 Subject: [PATCH 138/223] - fixed the overlapping sector handler in hw_fakeflat.cpp. this picked the wrong plane as the proper texture cutoff. --- src/rendering/hwrenderer/scene/hw_fakeflat.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rendering/hwrenderer/scene/hw_fakeflat.cpp b/src/rendering/hwrenderer/scene/hw_fakeflat.cpp index 1839d3be6..d56e9926e 100644 --- a/src/rendering/hwrenderer/scene/hw_fakeflat.cpp +++ b/src/rendering/hwrenderer/scene/hw_fakeflat.cpp @@ -224,9 +224,9 @@ sector_t * hw_FakeFlat(sector_t * sec, area_t in_area, bool back, sector_t *loca if (fakesectorbuffer && fakesectorbuffer[sec->sectornum]) return fakesectorbuffer[sec->sectornum]; auto dest = localcopy? localcopy : allocateSector(sec); *dest = *sec; - dest->ceilingplane = sec->floorplane; - dest->ceilingplane.FlipVert(); - dest->planes[sector_t::ceiling].TexZ = dest->planes[sector_t::floor].TexZ; + dest->floorplane = sec->ceilingplane; + dest->floorplane.FlipVert(); + dest->planes[sector_t::floor].TexZ = dest->planes[sector_t::ceiling].TexZ; dest->ClearPortal(sector_t::ceiling); dest->ClearPortal(sector_t::floor); return dest; From 17e689ecdfcf0c902f6f4c5a7828d74c1e77d062 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Sep 2023 08:18:36 +0200 Subject: [PATCH 139/223] fix for Genesis of Descent E1M2 Genesis of Descent E1M2 is impossible to complete on ITYTD/HNTR. I had to decompile the ACS script to figure out what was going on, basically at one point you get locked into a room and have to kill exactly 3 enemies with TID 215 for the door to unlock. One of these is a Baron tagged for only Medium and Hard, in his place is an Imp #1184 that has all the right script setups but is not set to appear on any difficulty. The fix is to simply have this imp appear on Easy. Thanks to brick' for the fix. --- wadsrc/static/zscript/level_compatibility.zs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wadsrc/static/zscript/level_compatibility.zs b/wadsrc/static/zscript/level_compatibility.zs index 348fc9c63..0e5c90fa1 100644 --- a/wadsrc/static/zscript/level_compatibility.zs +++ b/wadsrc/static/zscript/level_compatibility.zs @@ -2161,9 +2161,17 @@ class LevelCompatibility : LevelPostProcessor case '3F0965ADCEB2F4A7BF46FADF6DD941B0': // phocas2.wad map01 { + // turn map spot into teleport dest. SetThingEdNum(699, 9044); break; } + + case 'C8E727FFBA0BA445666C80340BF3D0AC': // god_.WAD E1M2 + { + // fix bad skill flags for a monster that's required to be killed. + SetThingSkills(1184, 1); + break; + } } } } From 084301f4d630c7426470f1304cc7b5a52e32839e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Sep 2023 08:40:36 +0200 Subject: [PATCH 140/223] - refined light mode selection. This is to ensure that if the map specifies light mode Doom (i.e. hardware approximation of software lighting) it is not overridden by the user-selected software emulating light mode. gl_lightmode should only apply if neither the map nor gl_maplightmode set an explicit light mode. --- src/g_level.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index a4c3648bd..474f85a38 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -158,18 +158,17 @@ CUSTOM_CVARD(Int, gl_lightmode, 1, CVAR_ARCHIVE, "Select lighting mode. 2 is van ELightMode getRealLightmode(FLevelLocals* Level, bool for3d) { - auto lightmode = Level->info->lightmode; - if (lightmode == ELightMode::NotSet) - { - if (gl_maplightmode != -1) lightmode = (ELightMode)*gl_maplightmode; - else lightmode = ELightMode::Doom; - } - if (lightmode == ELightMode::Doom && for3d) - { - if (gl_lightmode == 1) lightmode = ELightMode::ZDoomSoftware; - else if (gl_lightmode == 2) lightmode = ELightMode::DoomSoftware; - } - return lightmode; + // The rules are: + // 1) if the map sets a proper light mode, it is taken unconditionally. + if (Level->info->lightmode != ELightMode::NotSet) return Level->info->lightmode; + // 2) if the user sets gl_maplightmode, this is being used. + if (gl_maplightmode != -1) return (ELightMode)*gl_maplightmode; + // 3) if not for 3D use lightmode Doom. This is for the automap where the software light modes do not work + if (!for3d) return ELightMode::Doom; + // otherwise use lightmode Doom or software lighting based on user preferences. + if (gl_lightmode == 1) return ELightMode::ZDoomSoftware; + else if (gl_lightmode == 2) return ELightMode::DoomSoftware; + return ELightMode::Doom; } CVAR(Int, sv_alwaystally, 0, CVAR_SERVERINFO) From 2666f22ed7df11184723ee88e8bbb69f487d5dda Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 17 Sep 2023 09:04:44 +0200 Subject: [PATCH 141/223] - new text duplicate for pending menu redesign --- wadsrc/static/language.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/language.def b/wadsrc/static/language.def index 43e9afbf1..683615e8a 100644 --- a/wadsrc/static/language.def +++ b/wadsrc/static/language.def @@ -382,4 +382,4 @@ TAG_ARTITELEPORT = "$$TXT_ARTITELEPORT"; TAG_ARTITOMEOFPOWER = "$$TXT_ARTITOMEOFPOWER"; TAG_ARTITORCH = "$$TXT_ARTITORCH"; - +OPTMNU_SWRENDERER = "$$DSPLYMNU_SWOPT"; From 25e9561279257a8d849eb4472d9dbefb540ba21c Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 17 Sep 2023 04:44:10 -0400 Subject: [PATCH 142/223] - change anonstats cvars in order to allow easier updates to them in the future --- src/d_anonstats.cpp | 35 ++++++++++++++++------------------- src/d_defcvars.cpp | 3 +++ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/d_anonstats.cpp b/src/d_anonstats.cpp index 48762bd6d..2abe0ba2e 100644 --- a/src/d_anonstats.cpp +++ b/src/d_anonstats.cpp @@ -38,9 +38,9 @@ extern int sys_ostype; #include "gl_interface.h" #include "printf.h" -CVAR(Int, sys_statsenabled49, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) -CVAR(String, sys_statshost, "gzstats.drdteam.org", CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) -CVAR(Int, sys_statsport, 80, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) +CVAR(Int, anonstats_enabled411, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) +CVAR(String, anonstats_host, "gzstats.drdteam.org", CVAR_NOSET) +CVAR(Int, anonstats_port, 80, CVAR_NOSET) #define CHECKVERSION 490 #define CHECKVERSIONSTR "490" @@ -73,9 +73,6 @@ FString URLencode(const char *s) bool I_HTTPRequest(const char* request) { - if ((*sys_statshost)[0] == 0) - return false; // no host, disable - WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { @@ -84,20 +81,20 @@ bool I_HTTPRequest(const char* request) } SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); struct hostent *host; - host = gethostbyname(sys_statshost); + host = gethostbyname(anonstats_host); if (host == nullptr) { DPrintf(DMSG_ERROR, "Error looking up hostname.\n"); return false; } SOCKADDR_IN SockAddr; - SockAddr.sin_port = htons(sys_statsport); + SockAddr.sin_port = htons(anonstats_port); SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = *((uint32_t*)host->h_addr); - DPrintf(DMSG_NOTIFY, "Connecting to host %s\n", *sys_statshost); + DPrintf(DMSG_NOTIFY, "Connecting to host %s\n", *anonstats_host); if (connect(Socket, (SOCKADDR*)(&SockAddr), sizeof(SockAddr)) != 0) { - DPrintf(DMSG_ERROR, "Connection to host %s failed!\n", *sys_statshost); + DPrintf(DMSG_ERROR, "Connection to host %s failed!\n", *anonstats_host); return false; } send(Socket, request, (int)strlen(request), 0); @@ -119,14 +116,14 @@ bool I_HTTPRequest(const char* request) #else bool I_HTTPRequest(const char* request) { - if ((*sys_statshost)[0] == 0) + if ((*anonstats_host)[0] == 0) return false; // no host, disable int sockfd, portno, n; struct sockaddr_in serv_addr; struct hostent *server; - portno = sys_statsport; + portno = anonstats_port; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) @@ -135,7 +132,7 @@ bool I_HTTPRequest(const char* request) return false; } - server = gethostbyname(sys_statshost); + server = gethostbyname(anonstats_host); if (server == NULL) { DPrintf(DMSG_ERROR, "Error looking up hostname.\n"); @@ -148,10 +145,10 @@ bool I_HTTPRequest(const char* request) server->h_length); serv_addr.sin_port = htons(portno); - DPrintf(DMSG_NOTIFY, "Connecting to host %s\n", *sys_statshost); + DPrintf(DMSG_NOTIFY, "Connecting to host %s\n", *anonstats_host); if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { - DPrintf(DMSG_ERROR, "Connection to host %s failed!\n", *sys_statshost); + DPrintf(DMSG_ERROR, "Connection to host %s failed!\n", *anonstats_host); return false; } @@ -294,7 +291,7 @@ void D_DoAnonStats() { #ifndef _DEBUG // Do not repeat if already sent. - if (sys_statsenabled49 != 1 || sentstats_hwr_done >= CHECKVERSION) + if (anonstats_enabled411 != 1 || sentstats_hwr_done >= CHECKVERSION) { return; } @@ -307,7 +304,7 @@ void D_DoAnonStats() static char requeststring[1024]; mysnprintf(requeststring, sizeof requeststring, "GET /stats_202109.py?render=%i&cores=%i&os=%i&glversion=%i&vendor=%s&model=%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\nUser-Agent: %s %s\r\n\r\n", - GetRenderInfo(), GetCoreInfo(), GetOSVersion(), GetGLVersion(), URLencode(screen->vendorstring).GetChars(), URLencode(screen->DeviceName()).GetChars(), *sys_statshost, GAMENAME, VERSIONSTR); + GetRenderInfo(), GetCoreInfo(), GetOSVersion(), GetGLVersion(), URLencode(screen->vendorstring).GetChars(), URLencode(screen->DeviceName()).GetChars(), *anonstats_host, GAMENAME, VERSIONSTR); DPrintf(DMSG_NOTIFY, "Sending %s", requeststring); #if 1//ndef _DEBUG // Don't send info in debug builds @@ -320,7 +317,7 @@ void D_DoAnonStats() void D_ConfirmSendStats() { - if (sys_statsenabled49 >= 0) + if (anonstats_enabled411 >= 0) { return; } @@ -376,7 +373,7 @@ void D_ConfirmSendStats() enabled.Int = SDL_ShowMessageBox(&messageboxdata, &buttonid) == 0 && buttonid == 0; #endif // _WIN32 - sys_statsenabled49->ForceSet(enabled, CVAR_Int); + anonstats_enabled411->ForceSet(enabled, CVAR_Int); } #endif // NO_SEND_STATS diff --git a/src/d_defcvars.cpp b/src/d_defcvars.cpp index 2da8f0bd2..d066647b2 100644 --- a/src/d_defcvars.cpp +++ b/src/d_defcvars.cpp @@ -124,9 +124,12 @@ void D_GrabCVarDefaults() SHOULD_BLACKLIST(vid_adapter) SHOULD_BLACKLIST(sys_statsenabled47) SHOULD_BLACKLIST(sys_statsenabled49) + SHOULD_BLACKLIST(anonstats_statsenabled411) SHOULD_BLACKLIST(save_dir) SHOULD_BLACKLIST(sys_statsport) SHOULD_BLACKLIST(sys_statshost) + SHOULD_BLACKLIST(anonstats_port) + SHOULD_BLACKLIST(anonstats_host) SHOULD_BLACKLIST(sentstats_hwr_done) var = FindCVar(CurrentFindCVar, NULL); From 9b3409b28da9826004b75d597a6d6cbc0a461b34 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 17 Sep 2023 06:13:21 -0400 Subject: [PATCH 143/223] - update stats script --- src/d_anonstats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_anonstats.cpp b/src/d_anonstats.cpp index 2abe0ba2e..5c15d8cf0 100644 --- a/src/d_anonstats.cpp +++ b/src/d_anonstats.cpp @@ -303,7 +303,7 @@ void D_DoAnonStats() static char requeststring[1024]; - mysnprintf(requeststring, sizeof requeststring, "GET /stats_202109.py?render=%i&cores=%i&os=%i&glversion=%i&vendor=%s&model=%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\nUser-Agent: %s %s\r\n\r\n", + mysnprintf(requeststring, sizeof requeststring, "GET /stats_202309.py?render=%i&cores=%i&os=%i&glversion=%i&vendor=%s&model=%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\nUser-Agent: %s %s\r\n\r\n", GetRenderInfo(), GetCoreInfo(), GetOSVersion(), GetGLVersion(), URLencode(screen->vendorstring).GetChars(), URLencode(screen->DeviceName()).GetChars(), *anonstats_host, GAMENAME, VERSIONSTR); DPrintf(DMSG_NOTIFY, "Sending %s", requeststring); #if 1//ndef _DEBUG From ba9ce0e83f6e25e3ddef5000bd51d53f2e3947a2 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 17 Sep 2023 13:48:39 +0200 Subject: [PATCH 144/223] Switch to miniz from zlib --- CMakeLists.txt | 14 +- libraries/miniz/CMakeLists.txt | 9 + libraries/miniz/miniz.c | 7833 ++++++++++++++ libraries/miniz/miniz.h | 1422 +++ libraries/zlib/CMakeLists.txt | 196 - libraries/zlib/ChangeLog | 1608 --- libraries/zlib/FAQ | 368 - libraries/zlib/INDEX | 68 - libraries/zlib/README | 117 - libraries/zlib/adler32.c | 164 - libraries/zlib/algorithm.txt | 209 - libraries/zlib/compress.c | 75 - libraries/zlib/crc32.c | 1049 -- libraries/zlib/crc32.h | 9446 ----------------- libraries/zlib/deflate.c | 2114 ---- libraries/zlib/deflate.h | 346 - libraries/zlib/example.c | 565 - libraries/zlib/gzguts.h | 218 - libraries/zlib/infback.c | 628 -- libraries/zlib/inffast.c | 320 - libraries/zlib/inffast.h | 11 - libraries/zlib/inffixed.h | 94 - libraries/zlib/inflate.c | 1526 --- libraries/zlib/inflate.h | 126 - libraries/zlib/inftrees.c | 299 - libraries/zlib/inftrees.h | 62 - libraries/zlib/trees.c | 1103 -- libraries/zlib/trees.h | 128 - libraries/zlib/uncompr.c | 85 - libraries/zlib/win32/zlib.def | 97 - libraries/zlib/win32/zlib1.rc | 40 - libraries/zlib/zconf.h | 551 - libraries/zlib/zlib.3 | 149 - libraries/zlib/zlib.3.pdf | Bin 19505 -> 0 bytes libraries/zlib/zlib.h | 1938 ---- libraries/zlib/zutil.c | 299 - libraries/zlib/zutil.h | 275 - src/CMakeLists.txt | 4 +- src/common/audio/music/i_music.cpp | 2 +- src/common/engine/serializer.cpp | 2 +- .../filesystem/source/files_decompress.cpp | 2 +- src/common/filesystem/source/filesystem.cpp | 2 +- src/common/filesystem/source/resourcefile.cpp | 2 +- src/common/models/model.cpp | 13 +- src/common/platform/win32/i_crash.cpp | 2 +- src/common/textures/m_png.cpp | 2 +- src/common/thirdparty/m_crc32.h | 5 +- src/g_pch.h | 2 +- src/g_pch2.h | 2 +- src/maploader/glnodes.cpp | 2 +- src/serializer_doom.cpp | 2 +- tools/zipdir/CMakeLists.txt | 4 +- tools/zipdir/zipdir.c | 2 +- vcpkg.json | 4 - 54 files changed, 9285 insertions(+), 24321 deletions(-) create mode 100644 libraries/miniz/CMakeLists.txt create mode 100644 libraries/miniz/miniz.c create mode 100644 libraries/miniz/miniz.h delete mode 100644 libraries/zlib/CMakeLists.txt delete mode 100644 libraries/zlib/ChangeLog delete mode 100644 libraries/zlib/FAQ delete mode 100644 libraries/zlib/INDEX delete mode 100644 libraries/zlib/README delete mode 100644 libraries/zlib/adler32.c delete mode 100644 libraries/zlib/algorithm.txt delete mode 100644 libraries/zlib/compress.c delete mode 100644 libraries/zlib/crc32.c delete mode 100644 libraries/zlib/crc32.h delete mode 100644 libraries/zlib/deflate.c delete mode 100644 libraries/zlib/deflate.h delete mode 100644 libraries/zlib/example.c delete mode 100644 libraries/zlib/gzguts.h delete mode 100644 libraries/zlib/infback.c delete mode 100644 libraries/zlib/inffast.c delete mode 100644 libraries/zlib/inffast.h delete mode 100644 libraries/zlib/inffixed.h delete mode 100644 libraries/zlib/inflate.c delete mode 100644 libraries/zlib/inflate.h delete mode 100644 libraries/zlib/inftrees.c delete mode 100644 libraries/zlib/inftrees.h delete mode 100644 libraries/zlib/trees.c delete mode 100644 libraries/zlib/trees.h delete mode 100644 libraries/zlib/uncompr.c delete mode 100644 libraries/zlib/win32/zlib.def delete mode 100644 libraries/zlib/win32/zlib1.rc delete mode 100644 libraries/zlib/zconf.h delete mode 100644 libraries/zlib/zlib.3 delete mode 100644 libraries/zlib/zlib.3.pdf delete mode 100644 libraries/zlib/zlib.h delete mode 100644 libraries/zlib/zutil.c delete mode 100644 libraries/zlib/zutil.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7554ea27f..94101d28a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,7 +215,6 @@ option( NO_OPENAL "Disable OpenAL sound support" OFF ) find_package( BZip2 ) find_package( VPX ) -find_package( ZLIB ) find_package( WebP ) if (NOT WebP_FOUND) include(FindPkgConfig) @@ -347,7 +346,6 @@ set( CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${REL_C_FLAGS}" ) set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${REL_C_FLAGS}" ) set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" ) -option(FORCE_INTERNAL_ZLIB "Use internal zlib") option(FORCE_INTERNAL_BZIP2 "Use internal bzip2") option(FORCE_INTERNAL_ASMJIT "Use internal asmjit" ON) mark_as_advanced( FORCE_INTERNAL_ASMJIT ) @@ -361,17 +359,6 @@ set( DRPC_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries/discordrpc/include" set( DRPC_LIBRARIES discord-rpc ) set( DRPC_LIBRARY discord-rpc ) -if( ZLIB_FOUND AND NOT FORCE_INTERNAL_ZLIB ) - message( STATUS "Using system zlib, includes found at ${ZLIB_INCLUDE_DIR}" ) -else() - message( STATUS "Using internal zlib" ) - set( SKIP_INSTALL_ALL TRUE ) # Avoid installing zlib - add_subdirectory( libraries/zlib ) - set( ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libraries/zlib ) - set( ZLIB_LIBRARIES z ) - set( ZLIB_LIBRARY z ) -endif() - if( HAVE_VM_JIT AND UNIX ) check_symbol_exists( "backtrace" "execinfo.h" HAVE_BACKTRACE ) if( NOT HAVE_BACKTRACE ) @@ -430,6 +417,7 @@ install(DIRECTORY docs/ option( DYN_OPENAL "Dynamically load OpenAL" ON ) add_subdirectory( libraries/lzma ) +add_subdirectory( libraries/miniz ) add_subdirectory( tools ) add_subdirectory( wadsrc ) add_subdirectory( wadsrc_bm ) diff --git a/libraries/miniz/CMakeLists.txt b/libraries/miniz/CMakeLists.txt new file mode 100644 index 000000000..b5a5529f2 --- /dev/null +++ b/libraries/miniz/CMakeLists.txt @@ -0,0 +1,9 @@ +make_release_only() + +if (MSVC) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4244" ) +endif() + +add_library( miniz miniz.c ) +target_compile_definitions( miniz PRIVATE -DMINIZ_NO_STDIO ) +target_include_directories( miniz INTERFACE "$" ) \ No newline at end of file diff --git a/libraries/miniz/miniz.c b/libraries/miniz/miniz.c new file mode 100644 index 000000000..8d0032f9e --- /dev/null +++ b/libraries/miniz/miniz.c @@ -0,0 +1,7833 @@ +#include "miniz.h" +/************************************************************************** + * + * Copyright 2013-2014 RAD Game Tools and Valve Software + * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC + * 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. + * + **************************************************************************/ + + + +typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1]; +typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1]; +typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1]; + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------- zlib-style API's */ + +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) +{ + mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); + size_t block_len = buf_len % 5552; + if (!ptr) + return MZ_ADLER32_INIT; + while (buf_len) + { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) + { + s1 += ptr[0], s2 += s1; + s1 += ptr[1], s2 += s1; + s1 += ptr[2], s2 += s1; + s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; + s1 += ptr[5], s2 += s1; + s1 += ptr[6], s2 += s1; + s1 += ptr[7], s2 += s1; + } + for (; i < block_len; ++i) + s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; + buf_len -= block_len; + block_len = 5552; + } + return (s2 << 16) + s1; +} + +/* Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ */ +#if 0 + mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) + { + static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; + mz_uint32 crcu32 = (mz_uint32)crc; + if (!ptr) + return MZ_CRC32_INIT; + crcu32 = ~crcu32; + while (buf_len--) + { + mz_uint8 b = *ptr++; + crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; + crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; + } + return ~crcu32; + } +#elif defined(USE_EXTERNAL_MZCRC) +/* If USE_EXTERNAL_CRC is defined, an external module will export the + * mz_crc32() symbol for us to use, e.g. an SSE-accelerated version. + * Depending on the impl, it may be necessary to ~ the input/output crc values. + */ +mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len); +#else +/* Faster, but larger CPU cache footprint. + */ +mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) +{ + static const mz_uint32 s_crc_table[256] = + { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, + 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, + 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, + 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, + 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, + 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, + 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, + 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, + 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, + 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, + 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, + 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, + 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, + 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, + 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, + 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, + 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, + 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, + 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, + 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, + 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, + 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, + 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, + 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, + 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, + 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, + 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, + 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + }; + + mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF; + const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr; + + while (buf_len >= 4) + { + crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF]; + crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF]; + crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF]; + crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF]; + pByte_buf += 4; + buf_len -= 4; + } + + while (buf_len) + { + crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF]; + ++pByte_buf; + --buf_len; + } + + return ~crc32; +} +#endif + +void mz_free(void *p) +{ + MZ_FREE(p); +} + +MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size) +{ + (void)opaque, (void)items, (void)size; + return MZ_MALLOC(items * size); +} +MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address) +{ + (void)opaque, (void)address; + MZ_FREE(address); +} +MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size) +{ + (void)opaque, (void)address, (void)items, (void)size; + return MZ_REALLOC(address, items * size); +} + +const char *mz_version(void) +{ + return MZ_VERSION; +} + +#ifndef MINIZ_NO_ZLIB_APIS + +#ifndef MINIZ_NO_DEFLATE_APIS + +int mz_deflateInit(mz_streamp pStream, int level) +{ + return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY); +} + +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) +{ + tdefl_compressor *pComp; + mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); + + if (!pStream) + return MZ_STREAM_ERROR; + if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) + return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = MZ_ADLER32_INIT; + pStream->msg = NULL; + pStream->reserved = 0; + pStream->total_in = 0; + pStream->total_out = 0; + if (!pStream->zalloc) + pStream->zalloc = miniz_def_alloc_func; + if (!pStream->zfree) + pStream->zfree = miniz_def_free_func; + + pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor)); + if (!pComp) + return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pComp; + + if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) + { + mz_deflateEnd(pStream); + return MZ_PARAM_ERROR; + } + + return MZ_OK; +} + +int mz_deflateReset(mz_streamp pStream) +{ + if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) + return MZ_STREAM_ERROR; + pStream->total_in = pStream->total_out = 0; + tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags); + return MZ_OK; +} + +int mz_deflate(mz_streamp pStream, int flush) +{ + size_t in_bytes, out_bytes; + mz_ulong orig_total_in, orig_total_out; + int mz_status = MZ_OK; + + if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) + return MZ_STREAM_ERROR; + if (!pStream->avail_out) + return MZ_BUF_ERROR; + + if (flush == MZ_PARTIAL_FLUSH) + flush = MZ_SYNC_FLUSH; + + if (((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE) + return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR; + + orig_total_in = pStream->total_in; + orig_total_out = pStream->total_out; + for (;;) + { + tdefl_status defl_status; + in_bytes = pStream->avail_in; + out_bytes = pStream->avail_out; + + defl_status = tdefl_compress((tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush); + pStream->next_in += (mz_uint)in_bytes; + pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state); + + pStream->next_out += (mz_uint)out_bytes; + pStream->avail_out -= (mz_uint)out_bytes; + pStream->total_out += (mz_uint)out_bytes; + + if (defl_status < 0) + { + mz_status = MZ_STREAM_ERROR; + break; + } + else if (defl_status == TDEFL_STATUS_DONE) + { + mz_status = MZ_STREAM_END; + break; + } + else if (!pStream->avail_out) + break; + else if ((!pStream->avail_in) && (flush != MZ_FINISH)) + { + if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out)) + break; + return MZ_BUF_ERROR; /* Can't make forward progress without some input. + */ + } + } + return mz_status; +} + +int mz_deflateEnd(mz_streamp pStream) +{ + if (!pStream) + return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) +{ + (void)pStream; + /* This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) */ + return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5); +} + +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level) +{ + int status; + mz_stream stream; + memset(&stream, 0, sizeof(stream)); + + /* In case mz_ulong is 64-bits (argh I hate longs). */ + if ((mz_uint64)(source_len | *pDest_len) > 0xFFFFFFFFU) + return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_deflateInit(&stream, level); + if (status != MZ_OK) + return status; + + status = mz_deflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) + { + mz_deflateEnd(&stream); + return (status == MZ_OK) ? MZ_BUF_ERROR : status; + } + + *pDest_len = stream.total_out; + return mz_deflateEnd(&stream); +} + +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION); +} + +mz_ulong mz_compressBound(mz_ulong source_len) +{ + return mz_deflateBound(NULL, source_len); +} + +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ + +#ifndef MINIZ_NO_INFLATE_APIS + +typedef struct +{ + tinfl_decompressor m_decomp; + mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; + int m_window_bits; + mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; + tinfl_status m_last_status; +} inflate_state; + +int mz_inflateInit2(mz_streamp pStream, int window_bits) +{ + inflate_state *pDecomp; + if (!pStream) + return MZ_STREAM_ERROR; + if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) + return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = 0; + pStream->msg = NULL; + pStream->total_in = 0; + pStream->total_out = 0; + pStream->reserved = 0; + if (!pStream->zalloc) + pStream->zalloc = miniz_def_alloc_func; + if (!pStream->zfree) + pStream->zfree = miniz_def_free_func; + + pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state)); + if (!pDecomp) + return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pDecomp; + + tinfl_init(&pDecomp->m_decomp); + pDecomp->m_dict_ofs = 0; + pDecomp->m_dict_avail = 0; + pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; + pDecomp->m_first_call = 1; + pDecomp->m_has_flushed = 0; + pDecomp->m_window_bits = window_bits; + + return MZ_OK; +} + +int mz_inflateInit(mz_streamp pStream) +{ + return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS); +} + +int mz_inflateReset(mz_streamp pStream) +{ + inflate_state *pDecomp; + if (!pStream) + return MZ_STREAM_ERROR; + + pStream->data_type = 0; + pStream->adler = 0; + pStream->msg = NULL; + pStream->total_in = 0; + pStream->total_out = 0; + pStream->reserved = 0; + + pDecomp = (inflate_state *)pStream->state; + + tinfl_init(&pDecomp->m_decomp); + pDecomp->m_dict_ofs = 0; + pDecomp->m_dict_avail = 0; + pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; + pDecomp->m_first_call = 1; + pDecomp->m_has_flushed = 0; + /* pDecomp->m_window_bits = window_bits */; + + return MZ_OK; +} + +int mz_inflate(mz_streamp pStream, int flush) +{ + inflate_state *pState; + mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; + size_t in_bytes, out_bytes, orig_avail_in; + tinfl_status status; + + if ((!pStream) || (!pStream->state)) + return MZ_STREAM_ERROR; + if (flush == MZ_PARTIAL_FLUSH) + flush = MZ_SYNC_FLUSH; + if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) + return MZ_STREAM_ERROR; + + pState = (inflate_state *)pStream->state; + if (pState->m_window_bits > 0) + decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; + orig_avail_in = pStream->avail_in; + + first_call = pState->m_first_call; + pState->m_first_call = 0; + if (pState->m_last_status < 0) + return MZ_DATA_ERROR; + + if (pState->m_has_flushed && (flush != MZ_FINISH)) + return MZ_STREAM_ERROR; + pState->m_has_flushed |= (flush == MZ_FINISH); + + if ((flush == MZ_FINISH) && (first_call)) + { + /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */ + decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; + in_bytes = pStream->avail_in; + out_bytes = pStream->avail_out; + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags); + pState->m_last_status = status; + pStream->next_in += (mz_uint)in_bytes; + pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tinfl_get_adler32(&pState->m_decomp); + pStream->next_out += (mz_uint)out_bytes; + pStream->avail_out -= (mz_uint)out_bytes; + pStream->total_out += (mz_uint)out_bytes; + + if (status < 0) + return MZ_DATA_ERROR; + else if (status != TINFL_STATUS_DONE) + { + pState->m_last_status = TINFL_STATUS_FAILED; + return MZ_BUF_ERROR; + } + return MZ_STREAM_END; + } + /* flush != MZ_FINISH then we must assume there's more input. */ + if (flush != MZ_FINISH) + decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; + + if (pState->m_dict_avail) + { + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; + pStream->avail_out -= n; + pStream->total_out += n; + pState->m_dict_avail -= n; + pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; + } + + for (;;) + { + in_bytes = pStream->avail_in; + out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; + + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); + pState->m_last_status = status; + + pStream->next_in += (mz_uint)in_bytes; + pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tinfl_get_adler32(&pState->m_decomp); + + pState->m_dict_avail = (mz_uint)out_bytes; + + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; + pStream->avail_out -= n; + pStream->total_out += n; + pState->m_dict_avail -= n; + pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + + if (status < 0) + return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */ + else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) + return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */ + else if (flush == MZ_FINISH) + { + /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */ + if (status == TINFL_STATUS_DONE) + return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; + /* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. */ + else if (!pStream->avail_out) + return MZ_BUF_ERROR; + } + else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail)) + break; + } + + return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; +} + +int mz_inflateEnd(mz_streamp pStream) +{ + if (!pStream) + return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} +int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len) +{ + mz_stream stream; + int status; + memset(&stream, 0, sizeof(stream)); + + /* In case mz_ulong is 64-bits (argh I hate longs). */ + if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU) + return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)*pSource_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_inflateInit(&stream); + if (status != MZ_OK) + return status; + + status = mz_inflate(&stream, MZ_FINISH); + *pSource_len = *pSource_len - stream.avail_in; + if (status != MZ_STREAM_END) + { + mz_inflateEnd(&stream); + return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status; + } + *pDest_len = stream.total_out; + + return mz_inflateEnd(&stream); +} + +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + return mz_uncompress2(pDest, pDest_len, pSource, &source_len); +} + +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ + +const char *mz_error(int err) +{ + static struct + { + int m_err; + const char *m_pDesc; + } s_error_descs[] = + { + { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" } + }; + mz_uint i; + for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) + if (s_error_descs[i].m_err == err) + return s_error_descs[i].m_pDesc; + return NULL; +} + +#endif /*MINIZ_NO_ZLIB_APIS */ + +#ifdef __cplusplus +} +#endif + +/* + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to +*/ +/************************************************************************** + * + * Copyright 2013-2014 RAD Game Tools and Valve Software + * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC + * 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 MINIZ_NO_DEFLATE_APIS + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------- Low-level Compression (independent from all decompression API's) */ + +/* Purposely making these tables static for faster init and thread safety. */ +static const mz_uint16 s_tdefl_len_sym[256] = + { + 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272, + 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285 + }; + +static const mz_uint8 s_tdefl_len_extra[256] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0 + }; + +static const mz_uint8 s_tdefl_small_dist_sym[512] = + { + 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, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17 + }; + +static const mz_uint8 s_tdefl_small_dist_extra[512] = + { + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 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, 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, 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, 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, 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, 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, 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 + }; + +static const mz_uint8 s_tdefl_large_dist_sym[128] = + { + 0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 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, 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 + }; + +static const mz_uint8 s_tdefl_large_dist_extra[128] = + { + 0, 0, 8, 8, 9, 9, 9, 9, 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, + 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 + }; + +/* Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. */ +typedef struct +{ + mz_uint16 m_key, m_sym_index; +} tdefl_sym_freq; +static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *pSyms0, tdefl_sym_freq *pSyms1) +{ + mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; + tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1; + MZ_CLEAR_ARR(hist); + for (i = 0; i < num_syms; i++) + { + mz_uint freq = pSyms0[i].m_key; + hist[freq & 0xFF]++; + hist[256 + ((freq >> 8) & 0xFF)]++; + } + while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) + total_passes--; + for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) + { + const mz_uint32 *pHist = &hist[pass << 8]; + mz_uint offsets[256], cur_ofs = 0; + for (i = 0; i < 256; i++) + { + offsets[i] = cur_ofs; + cur_ofs += pHist[i]; + } + for (i = 0; i < num_syms; i++) + pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i]; + { + tdefl_sym_freq *t = pCur_syms; + pCur_syms = pNew_syms; + pNew_syms = t; + } + } + return pCur_syms; +} + +/* tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. */ +static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) +{ + int root, leaf, next, avbl, used, dpth; + if (n == 0) + return; + else if (n == 1) + { + A[0].m_key = 1; + return; + } + A[0].m_key += A[1].m_key; + root = 0; + leaf = 2; + for (next = 1; next < n - 1; next++) + { + if (leaf >= n || A[root].m_key < A[leaf].m_key) + { + A[next].m_key = A[root].m_key; + A[root++].m_key = (mz_uint16)next; + } + else + A[next].m_key = A[leaf++].m_key; + if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key)) + { + A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key); + A[root++].m_key = (mz_uint16)next; + } + else + A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key); + } + A[n - 2].m_key = 0; + for (next = n - 3; next >= 0; next--) + A[next].m_key = A[A[next].m_key].m_key + 1; + avbl = 1; + used = dpth = 0; + root = n - 2; + next = n - 1; + while (avbl > 0) + { + while (root >= 0 && (int)A[root].m_key == dpth) + { + used++; + root--; + } + while (avbl > used) + { + A[next--].m_key = (mz_uint16)(dpth); + avbl--; + } + avbl = 2 * used; + dpth++; + used = 0; + } +} + +/* Limits canonical Huffman code table's max code size. */ +enum +{ + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 +}; +static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size) +{ + int i; + mz_uint32 total = 0; + if (code_list_len <= 1) + return; + for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) + pNum_codes[max_code_size] += pNum_codes[i]; + for (i = max_code_size; i > 0; i--) + total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i)); + while (total != (1UL << max_code_size)) + { + pNum_codes[max_code_size]--; + for (i = max_code_size - 1; i > 0; i--) + if (pNum_codes[i]) + { + pNum_codes[i]--; + pNum_codes[i + 1] += 2; + break; + } + total--; + } +} + +static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table) +{ + int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; + mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; + MZ_CLEAR_ARR(num_codes); + if (static_table) + { + for (i = 0; i < table_len; i++) + num_codes[d->m_huff_code_sizes[table_num][i]]++; + } + else + { + tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms; + int num_used_syms = 0; + const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0]; + for (i = 0; i < table_len; i++) + if (pSym_count[i]) + { + syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; + syms0[num_used_syms++].m_sym_index = (mz_uint16)i; + } + + pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); + tdefl_calculate_minimum_redundancy(pSyms, num_used_syms); + + for (i = 0; i < num_used_syms; i++) + num_codes[pSyms[i].m_key]++; + + tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit); + + MZ_CLEAR_ARR(d->m_huff_code_sizes[table_num]); + MZ_CLEAR_ARR(d->m_huff_codes[table_num]); + for (i = 1, j = num_used_syms; i <= code_size_limit; i++) + for (l = num_codes[i]; l > 0; l--) + d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); + } + + next_code[1] = 0; + for (j = 0, i = 2; i <= code_size_limit; i++) + next_code[i] = j = ((j + num_codes[i - 1]) << 1); + + for (i = 0; i < table_len; i++) + { + mz_uint rev_code = 0, code, code_size; + if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) + continue; + code = next_code[code_size]++; + for (l = code_size; l > 0; l--, code >>= 1) + rev_code = (rev_code << 1) | (code & 1); + d->m_huff_codes[table_num][i] = (mz_uint16)rev_code; + } +} + +#define TDEFL_PUT_BITS(b, l) \ + do \ + { \ + mz_uint bits = b; \ + mz_uint len = l; \ + MZ_ASSERT(bits <= ((1U << len) - 1U)); \ + d->m_bit_buffer |= (bits << d->m_bits_in); \ + d->m_bits_in += len; \ + while (d->m_bits_in >= 8) \ + { \ + if (d->m_pOutput_buf < d->m_pOutput_buf_end) \ + *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \ + d->m_bit_buffer >>= 8; \ + d->m_bits_in -= 8; \ + } \ + } \ + MZ_MACRO_END + +#define TDEFL_RLE_PREV_CODE_SIZE() \ + { \ + if (rle_repeat_count) \ + { \ + if (rle_repeat_count < 3) \ + { \ + d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \ + while (rle_repeat_count--) \ + packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \ + } \ + else \ + { \ + d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \ + packed_code_sizes[num_packed_code_sizes++] = 16; \ + packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \ + } \ + rle_repeat_count = 0; \ + } \ + } + +#define TDEFL_RLE_ZERO_CODE_SIZE() \ + { \ + if (rle_z_count) \ + { \ + if (rle_z_count < 3) \ + { \ + d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \ + while (rle_z_count--) \ + packed_code_sizes[num_packed_code_sizes++] = 0; \ + } \ + else if (rle_z_count <= 10) \ + { \ + d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \ + packed_code_sizes[num_packed_code_sizes++] = 17; \ + packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \ + } \ + else \ + { \ + d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \ + packed_code_sizes[num_packed_code_sizes++] = 18; \ + packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \ + } \ + rle_z_count = 0; \ + } \ + } + +static const mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + +static void tdefl_start_dynamic_block(tdefl_compressor *d) +{ + int num_lit_codes, num_dist_codes, num_bit_lengths; + mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index; + mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF; + + d->m_huff_count[0][256] = 1; + + tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE); + tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE); + + for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) + if (d->m_huff_code_sizes[0][num_lit_codes - 1]) + break; + for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) + if (d->m_huff_code_sizes[1][num_dist_codes - 1]) + break; + + memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes); + memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes); + total_code_sizes_to_pack = num_lit_codes + num_dist_codes; + num_packed_code_sizes = 0; + rle_z_count = 0; + rle_repeat_count = 0; + + memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2); + for (i = 0; i < total_code_sizes_to_pack; i++) + { + mz_uint8 code_size = code_sizes_to_pack[i]; + if (!code_size) + { + TDEFL_RLE_PREV_CODE_SIZE(); + if (++rle_z_count == 138) + { + TDEFL_RLE_ZERO_CODE_SIZE(); + } + } + else + { + TDEFL_RLE_ZERO_CODE_SIZE(); + if (code_size != prev_code_size) + { + TDEFL_RLE_PREV_CODE_SIZE(); + d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); + packed_code_sizes[num_packed_code_sizes++] = code_size; + } + else if (++rle_repeat_count == 6) + { + TDEFL_RLE_PREV_CODE_SIZE(); + } + } + prev_code_size = code_size; + } + if (rle_repeat_count) + { + TDEFL_RLE_PREV_CODE_SIZE(); + } + else + { + TDEFL_RLE_ZERO_CODE_SIZE(); + } + + tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE); + + TDEFL_PUT_BITS(2, 2); + + TDEFL_PUT_BITS(num_lit_codes - 257, 5); + TDEFL_PUT_BITS(num_dist_codes - 1, 5); + + for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) + if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) + break; + num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); + TDEFL_PUT_BITS(num_bit_lengths - 4, 4); + for (i = 0; (int)i < num_bit_lengths; i++) + TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3); + + for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes;) + { + mz_uint code = packed_code_sizes[packed_code_sizes_index++]; + MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2); + TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]); + if (code >= 16) + TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]); + } +} + +static void tdefl_start_static_block(tdefl_compressor *d) +{ + mz_uint i; + mz_uint8 *p = &d->m_huff_code_sizes[0][0]; + + for (i = 0; i <= 143; ++i) + *p++ = 8; + for (; i <= 255; ++i) + *p++ = 9; + for (; i <= 279; ++i) + *p++ = 7; + for (; i <= 287; ++i) + *p++ = 8; + + memset(d->m_huff_code_sizes[1], 5, 32); + + tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE); + tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE); + + TDEFL_PUT_BITS(1, 2); +} + +static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) +{ + mz_uint flags; + mz_uint8 *pLZ_codes; + mz_uint8 *pOutput_buf = d->m_pOutput_buf; + mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf; + mz_uint64 bit_buffer = d->m_bit_buffer; + mz_uint bits_in = d->m_bits_in; + +#define TDEFL_PUT_BITS_FAST(b, l) \ + { \ + bit_buffer |= (((mz_uint64)(b)) << bits_in); \ + bits_in += (l); \ + } + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1) + { + if (flags == 1) + flags = *pLZ_codes++ | 0x100; + + if (flags & 1) + { + mz_uint s0, s1, n0, n1, sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0]; + mz_uint match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); + pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); + + /* This sequence coaxes MSVC into using cmov's vs. jmp's. */ + s0 = s_tdefl_small_dist_sym[match_dist & 511]; + n0 = s_tdefl_small_dist_extra[match_dist & 511]; + s1 = s_tdefl_large_dist_sym[match_dist >> 8]; + n1 = s_tdefl_large_dist_extra[match_dist >> 8]; + sym = (match_dist < 512) ? s0 : s1; + num_extra_bits = (match_dist < 512) ? n0 : n1; + + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } + else + { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) + { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) + { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + } + + if (pOutput_buf >= d->m_pOutput_buf_end) + return MZ_FALSE; + + memcpy(pOutput_buf, &bit_buffer, sizeof(mz_uint64)); + pOutput_buf += (bits_in >> 3); + bit_buffer >>= (bits_in & ~7); + bits_in &= 7; + } + +#undef TDEFL_PUT_BITS_FAST + + d->m_pOutput_buf = pOutput_buf; + d->m_bits_in = 0; + d->m_bit_buffer = 0; + + while (bits_in) + { + mz_uint32 n = MZ_MIN(bits_in, 16); + TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n); + bit_buffer >>= n; + bits_in -= n; + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#else +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) +{ + mz_uint flags; + mz_uint8 *pLZ_codes; + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1) + { + if (flags == 1) + flags = *pLZ_codes++ | 0x100; + if (flags & 1) + { + mz_uint sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); + pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); + + if (match_dist < 512) + { + sym = s_tdefl_small_dist_sym[match_dist]; + num_extra_bits = s_tdefl_small_dist_extra[match_dist]; + } + else + { + sym = s_tdefl_large_dist_sym[match_dist >> 8]; + num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8]; + } + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } + else + { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS */ + +static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) +{ + if (static_block) + tdefl_start_static_block(d); + else + tdefl_start_dynamic_block(d); + return tdefl_compress_lz_codes(d); +} + +static const mz_uint s_tdefl_num_probes[11]; + +static int tdefl_flush_block(tdefl_compressor *d, int flush) +{ + mz_uint saved_bit_buf, saved_bits_in; + mz_uint8 *pSaved_output_buf; + mz_bool comp_block_succeeded = MZ_FALSE; + int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; + mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf; + + d->m_pOutput_buf = pOutput_buf_start; + d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16; + + MZ_ASSERT(!d->m_output_flush_remaining); + d->m_output_flush_ofs = 0; + d->m_output_flush_remaining = 0; + + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left); + d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); + + if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) + { + const mz_uint8 cmf = 0x78; + mz_uint8 flg, flevel = 3; + mz_uint header, i, mz_un = sizeof(s_tdefl_num_probes) / sizeof(mz_uint); + + /* Determine compression level by reversing the process in tdefl_create_comp_flags_from_zip_params() */ + for (i = 0; i < mz_un; i++) + if (s_tdefl_num_probes[i] == (d->m_flags & 0xFFF)) break; + + if (i < 2) + flevel = 0; + else if (i < 6) + flevel = 1; + else if (i == 6) + flevel = 2; + + header = cmf << 8 | (flevel << 6); + header += 31 - (header % 31); + flg = header & 0xFF; + + TDEFL_PUT_BITS(cmf, 8); + TDEFL_PUT_BITS(flg, 8); + } + + TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); + + pSaved_output_buf = d->m_pOutput_buf; + saved_bit_buf = d->m_bit_buffer; + saved_bits_in = d->m_bits_in; + + if (!use_raw_block) + comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48)); + + /* If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. */ + if (((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) && + ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size)) + { + mz_uint i; + d->m_pOutput_buf = pSaved_output_buf; + d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + TDEFL_PUT_BITS(0, 2); + if (d->m_bits_in) + { + TDEFL_PUT_BITS(0, 8 - d->m_bits_in); + } + for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) + { + TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16); + } + for (i = 0; i < d->m_total_lz_bytes; ++i) + { + TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8); + } + } + /* Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. */ + else if (!comp_block_succeeded) + { + d->m_pOutput_buf = pSaved_output_buf; + d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + tdefl_compress_block(d, MZ_TRUE); + } + + if (flush) + { + if (flush == TDEFL_FINISH) + { + if (d->m_bits_in) + { + TDEFL_PUT_BITS(0, 8 - d->m_bits_in); + } + if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) + { + mz_uint i, a = d->m_adler32; + for (i = 0; i < 4; i++) + { + TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); + a <<= 8; + } + } + } + else + { + mz_uint i, z = 0; + TDEFL_PUT_BITS(0, 3); + if (d->m_bits_in) + { + TDEFL_PUT_BITS(0, 8 - d->m_bits_in); + } + for (i = 2; i; --i, z ^= 0xFFFF) + { + TDEFL_PUT_BITS(z & 0xFFFF, 16); + } + } + } + + MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end); + + memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; + d->m_pLZ_flags = d->m_lz_code_buf; + d->m_num_flags_left = 8; + d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; + d->m_total_lz_bytes = 0; + d->m_block_index++; + + if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) + { + if (d->m_pPut_buf_func) + { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user)) + return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED); + } + else if (pOutput_buf_start == d->m_output_buf) + { + int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs)); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy); + d->m_out_buf_ofs += bytes_to_copy; + if ((n -= bytes_to_copy) != 0) + { + d->m_output_flush_ofs = bytes_to_copy; + d->m_output_flush_remaining = n; + } + } + else + { + d->m_out_buf_ofs += n; + } + } + + return d->m_output_flush_remaining; +} + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES +#ifdef MINIZ_UNALIGNED_USE_MEMCPY +static mz_uint16 TDEFL_READ_UNALIGNED_WORD(const mz_uint8* p) +{ + mz_uint16 ret; + memcpy(&ret, p, sizeof(mz_uint16)); + return ret; +} +static mz_uint16 TDEFL_READ_UNALIGNED_WORD2(const mz_uint16* p) +{ + mz_uint16 ret; + memcpy(&ret, p, sizeof(mz_uint16)); + return ret; +} +#else +#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p) +#define TDEFL_READ_UNALIGNED_WORD2(p) *(const mz_uint16 *)(p) +#endif +static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) +{ + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q; + mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD2(s); + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); + if (max_match_len <= match_len) + return; + for (;;) + { + for (;;) + { + if (--num_probes_left == 0) + return; +#define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \ + return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \ + break; + TDEFL_PROBE; + TDEFL_PROBE; + TDEFL_PROBE; + } + if (!dist) + break; + q = (const mz_uint16 *)(d->m_dict + probe_pos); + if (TDEFL_READ_UNALIGNED_WORD2(q) != s01) + continue; + p = s; + probe_len = 32; + do + { + } while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && + (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0)); + if (!probe_len) + { + *pMatch_dist = dist; + *pMatch_len = MZ_MIN(max_match_len, (mz_uint)TDEFL_MAX_MATCH_LEN); + break; + } + else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q)) > match_len) + { + *pMatch_dist = dist; + if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) + break; + c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]); + } + } +} +#else +static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) +{ + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint8 *s = d->m_dict + pos, *p, *q; + mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1]; + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); + if (max_match_len <= match_len) + return; + for (;;) + { + for (;;) + { + if (--num_probes_left == 0) + return; +#define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \ + return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) \ + break; + TDEFL_PROBE; + TDEFL_PROBE; + TDEFL_PROBE; + } + if (!dist) + break; + p = s; + q = d->m_dict + probe_pos; + for (probe_len = 0; probe_len < max_match_len; probe_len++) + if (*p++ != *q++) + break; + if (probe_len > match_len) + { + *pMatch_dist = dist; + if ((*pMatch_len = match_len = probe_len) == max_match_len) + return; + c0 = d->m_dict[pos + match_len]; + c1 = d->m_dict[pos + match_len - 1]; + } + } +} +#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES */ + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN +#ifdef MINIZ_UNALIGNED_USE_MEMCPY +static mz_uint32 TDEFL_READ_UNALIGNED_WORD32(const mz_uint8* p) +{ + mz_uint32 ret; + memcpy(&ret, p, sizeof(mz_uint32)); + return ret; +} +#else +#define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p) +#endif +static mz_bool tdefl_compress_fast(tdefl_compressor *d) +{ + /* Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. */ + mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left; + mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags; + mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + + while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) + { + const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096; + mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size); + d->m_src_buf_left -= num_bytes_to_process; + lookahead_size += num_bytes_to_process; + + while (num_bytes_to_process) + { + mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process); + memcpy(d->m_dict + dst_pos, d->m_pSrc, n); + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos)); + d->m_pSrc += n; + dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK; + num_bytes_to_process -= n; + } + + dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size); + if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) + break; + + while (lookahead_size >= 4) + { + mz_uint cur_match_dist, cur_match_len = 1; + mz_uint8 *pCur_dict = d->m_dict + cur_pos; + mz_uint first_trigram = TDEFL_READ_UNALIGNED_WORD32(pCur_dict) & 0xFFFFFF; + mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK; + mz_uint probe_pos = d->m_hash[hash]; + d->m_hash[hash] = (mz_uint16)lookahead_pos; + + if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((TDEFL_READ_UNALIGNED_WORD32(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram)) + { + const mz_uint16 *p = (const mz_uint16 *)pCur_dict; + const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos); + mz_uint32 probe_len = 32; + do + { + } while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && + (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0)); + cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q); + if (!probe_len) + cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0; + + if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U))) + { + cur_match_len = 1; + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + else + { + mz_uint32 s0, s1; + cur_match_len = MZ_MIN(cur_match_len, lookahead_size); + + MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE)); + + cur_match_dist--; + + pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); +#ifdef MINIZ_UNALIGNED_USE_MEMCPY + memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist)); +#else + *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; +#endif + pLZ_code_buf += 3; + *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80); + + s0 = s_tdefl_small_dist_sym[cur_match_dist & 511]; + s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8]; + d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++; + + d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++; + } + } + else + { + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + + if (--num_flags_left == 0) + { + num_flags_left = 8; + pLZ_flags = pLZ_code_buf++; + } + + total_lz_bytes += cur_match_len; + lookahead_pos += cur_match_len; + dict_size = MZ_MIN(dict_size + cur_match_len, (mz_uint)TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK; + MZ_ASSERT(lookahead_size >= cur_match_len); + lookahead_size -= cur_match_len; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) + { + int n; + d->m_lookahead_pos = lookahead_pos; + d->m_lookahead_size = lookahead_size; + d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; + d->m_pLZ_code_buf = pLZ_code_buf; + d->m_pLZ_flags = pLZ_flags; + d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; + pLZ_code_buf = d->m_pLZ_code_buf; + pLZ_flags = d->m_pLZ_flags; + num_flags_left = d->m_num_flags_left; + } + } + + while (lookahead_size) + { + mz_uint8 lit = d->m_dict[cur_pos]; + + total_lz_bytes++; + *pLZ_code_buf++ = lit; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + if (--num_flags_left == 0) + { + num_flags_left = 8; + pLZ_flags = pLZ_code_buf++; + } + + d->m_huff_count[0][lit]++; + + lookahead_pos++; + dict_size = MZ_MIN(dict_size + 1, (mz_uint)TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; + lookahead_size--; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) + { + int n; + d->m_lookahead_pos = lookahead_pos; + d->m_lookahead_size = lookahead_size; + d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; + d->m_pLZ_code_buf = pLZ_code_buf; + d->m_pLZ_flags = pLZ_flags; + d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; + pLZ_code_buf = d->m_pLZ_code_buf; + pLZ_flags = d->m_pLZ_flags; + num_flags_left = d->m_num_flags_left; + } + } + } + + d->m_lookahead_pos = lookahead_pos; + d->m_lookahead_size = lookahead_size; + d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; + d->m_pLZ_code_buf = pLZ_code_buf; + d->m_pLZ_flags = pLZ_flags; + d->m_num_flags_left = num_flags_left; + return MZ_TRUE; +} +#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */ + +static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit) +{ + d->m_total_lz_bytes++; + *d->m_pLZ_code_buf++ = lit; + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); + if (--d->m_num_flags_left == 0) + { + d->m_num_flags_left = 8; + d->m_pLZ_flags = d->m_pLZ_code_buf++; + } + d->m_huff_count[0][lit]++; +} + +static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) +{ + mz_uint32 s0, s1; + + MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE)); + + d->m_total_lz_bytes += match_len; + + d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN); + + match_dist -= 1; + d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF); + d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); + d->m_pLZ_code_buf += 3; + + *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); + if (--d->m_num_flags_left == 0) + { + d->m_num_flags_left = 8; + d->m_pLZ_flags = d->m_pLZ_code_buf++; + } + + s0 = s_tdefl_small_dist_sym[match_dist & 511]; + s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127]; + d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; + d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; +} + +static mz_bool tdefl_compress_normal(tdefl_compressor *d) +{ + const mz_uint8 *pSrc = d->m_pSrc; + size_t src_buf_left = d->m_src_buf_left; + tdefl_flush flush = d->m_flush; + + while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) + { + mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; + /* Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. */ + if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) + { + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; + mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); + const mz_uint8 *pSrc_end = pSrc ? pSrc + num_bytes_to_process : NULL; + src_buf_left -= num_bytes_to_process; + d->m_lookahead_size += num_bytes_to_process; + while (pSrc != pSrc_end) + { + mz_uint8 c = *pSrc++; + d->m_dict[dst_pos] = c; + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; + d->m_hash[hash] = (mz_uint16)(ins_pos); + dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; + ins_pos++; + } + } + else + { + while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) + { + mz_uint8 c = *pSrc++; + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + src_buf_left--; + d->m_dict[dst_pos] = c; + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) + { + mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; + mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; + d->m_hash[hash] = (mz_uint16)(ins_pos); + } + } + } + d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); + if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) + break; + + /* Simple lazy/greedy parsing state machine. */ + len_to_move = 1; + cur_match_dist = 0; + cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); + cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) + { + if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) + { + mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK]; + cur_match_len = 0; + while (cur_match_len < d->m_lookahead_size) + { + if (d->m_dict[cur_pos + cur_match_len] != c) + break; + cur_match_len++; + } + if (cur_match_len < TDEFL_MIN_MATCH_LEN) + cur_match_len = 0; + else + cur_match_dist = 1; + } + } + else + { + tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len); + } + if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) + { + cur_match_dist = cur_match_len = 0; + } + if (d->m_saved_match_len) + { + if (cur_match_len > d->m_saved_match_len) + { + tdefl_record_literal(d, (mz_uint8)d->m_saved_lit); + if (cur_match_len >= 128) + { + tdefl_record_match(d, cur_match_len, cur_match_dist); + d->m_saved_match_len = 0; + len_to_move = cur_match_len; + } + else + { + d->m_saved_lit = d->m_dict[cur_pos]; + d->m_saved_match_dist = cur_match_dist; + d->m_saved_match_len = cur_match_len; + } + } + else + { + tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist); + len_to_move = d->m_saved_match_len - 1; + d->m_saved_match_len = 0; + } + } + else if (!cur_match_dist) + tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]); + else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128)) + { + tdefl_record_match(d, cur_match_len, cur_match_dist); + len_to_move = cur_match_len; + } + else + { + d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; + d->m_saved_match_dist = cur_match_dist; + d->m_saved_match_len = cur_match_len; + } + /* Move the lookahead forward by len_to_move bytes. */ + d->m_lookahead_pos += len_to_move; + MZ_ASSERT(d->m_lookahead_size >= len_to_move); + d->m_lookahead_size -= len_to_move; + d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE); + /* Check if it's time to flush the current LZ codes to the internal output buffer. */ + if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) || + ((d->m_total_lz_bytes > 31 * 1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))) + { + int n; + d->m_pSrc = pSrc; + d->m_src_buf_left = src_buf_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + } + } + + d->m_pSrc = pSrc; + d->m_src_buf_left = src_buf_left; + return MZ_TRUE; +} + +static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) +{ + if (d->m_pIn_buf_size) + { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + } + + if (d->m_pOut_buf_size) + { + size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n); + d->m_output_flush_ofs += (mz_uint)n; + d->m_output_flush_remaining -= (mz_uint)n; + d->m_out_buf_ofs += n; + + *d->m_pOut_buf_size = d->m_out_buf_ofs; + } + + return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush) +{ + if (!d) + { + if (pIn_buf_size) + *pIn_buf_size = 0; + if (pOut_buf_size) + *pOut_buf_size = 0; + return TDEFL_STATUS_BAD_PARAM; + } + + d->m_pIn_buf = pIn_buf; + d->m_pIn_buf_size = pIn_buf_size; + d->m_pOut_buf = pOut_buf; + d->m_pOut_buf_size = pOut_buf_size; + d->m_pSrc = (const mz_uint8 *)(pIn_buf); + d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0; + d->m_out_buf_ofs = 0; + d->m_flush = flush; + + if (((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) || + (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf)) + { + if (pIn_buf_size) + *pIn_buf_size = 0; + if (pOut_buf_size) + *pOut_buf_size = 0; + return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM); + } + d->m_wants_to_finish |= (flush == TDEFL_FINISH); + + if ((d->m_output_flush_remaining) || (d->m_finished)) + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) && + ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) && + ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0)) + { + if (!tdefl_compress_fast(d)) + return d->m_prev_return_status; + } + else +#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */ + { + if (!tdefl_compress_normal(d)) + return d->m_prev_return_status; + } + + if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf)) + d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf); + + if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining)) + { + if (tdefl_flush_block(d, flush) < 0) + return d->m_prev_return_status; + d->m_finished = (flush == TDEFL_FINISH); + if (flush == TDEFL_FULL_FLUSH) + { + MZ_CLEAR_ARR(d->m_hash); + MZ_CLEAR_ARR(d->m_next); + d->m_dict_size = 0; + } + } + + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); +} + +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush) +{ + MZ_ASSERT(d->m_pPut_buf_func); + return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush); +} + +tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + d->m_pPut_buf_func = pPut_buf_func; + d->m_pPut_buf_user = pPut_buf_user; + d->m_flags = (mz_uint)(flags); + d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; + d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; + d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; + if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) + MZ_CLEAR_ARR(d->m_hash); + d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; + d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; + d->m_pLZ_flags = d->m_lz_code_buf; + *d->m_pLZ_flags = 0; + d->m_num_flags_left = 8; + d->m_pOutput_buf = d->m_output_buf; + d->m_pOutput_buf_end = d->m_output_buf; + d->m_prev_return_status = TDEFL_STATUS_OKAY; + d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; + d->m_adler32 = 1; + d->m_pIn_buf = NULL; + d->m_pOut_buf = NULL; + d->m_pIn_buf_size = NULL; + d->m_pOut_buf_size = NULL; + d->m_flush = TDEFL_NO_FLUSH; + d->m_pSrc = NULL; + d->m_src_buf_left = 0; + d->m_out_buf_ofs = 0; + if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) + MZ_CLEAR_ARR(d->m_dict); + memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + return TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) +{ + return d->m_prev_return_status; +} + +mz_uint32 tdefl_get_adler32(tdefl_compressor *d) +{ + return d->m_adler32; +} + +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + tdefl_compressor *pComp; + mz_bool succeeded; + if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) + return MZ_FALSE; + pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); + if (!pComp) + return MZ_FALSE; + succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY); + succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE); + MZ_FREE(pComp); + return succeeded; +} + +typedef struct +{ + size_t m_size, m_capacity; + mz_uint8 *m_pBuf; + mz_bool m_expandable; +} tdefl_output_buffer; + +static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser) +{ + tdefl_output_buffer *p = (tdefl_output_buffer *)pUser; + size_t new_size = p->m_size + len; + if (new_size > p->m_capacity) + { + size_t new_capacity = p->m_capacity; + mz_uint8 *pNew_buf; + if (!p->m_expandable) + return MZ_FALSE; + do + { + new_capacity = MZ_MAX(128U, new_capacity << 1U); + } while (new_size > new_capacity); + pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity); + if (!pNew_buf) + return MZ_FALSE; + p->m_pBuf = pNew_buf; + p->m_capacity = new_capacity; + } + memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len); + p->m_size = new_size; + return MZ_TRUE; +} + +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tdefl_output_buffer out_buf; + MZ_CLEAR_OBJ(out_buf); + if (!pOut_len) + return MZ_FALSE; + else + *pOut_len = 0; + out_buf.m_expandable = MZ_TRUE; + if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) + return NULL; + *pOut_len = out_buf.m_size; + return out_buf.m_pBuf; +} + +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tdefl_output_buffer out_buf; + MZ_CLEAR_OBJ(out_buf); + if (!pOut_buf) + return 0; + out_buf.m_pBuf = (mz_uint8 *)pOut_buf; + out_buf.m_capacity = out_buf_len; + if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) + return 0; + return out_buf.m_size; +} + +static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; + +/* level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). */ +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy) +{ + mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); + if (window_bits > 0) + comp_flags |= TDEFL_WRITE_ZLIB_HEADER; + + if (!level) + comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; + else if (strategy == MZ_FILTERED) + comp_flags |= TDEFL_FILTER_MATCHES; + else if (strategy == MZ_HUFFMAN_ONLY) + comp_flags &= ~TDEFL_MAX_PROBES_MASK; + else if (strategy == MZ_FIXED) + comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS; + else if (strategy == MZ_RLE) + comp_flags |= TDEFL_RLE_MATCHES; + + return comp_flags; +} + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4204) /* nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) */ +#endif + +/* Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at + http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. + This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck. */ +void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip) +{ + /* Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined. */ + static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; + tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); + tdefl_output_buffer out_buf; + int i, bpl = w * num_chans, y, z; + mz_uint32 c; + *pLen_out = 0; + if (!pComp) + return NULL; + MZ_CLEAR_OBJ(out_buf); + out_buf.m_expandable = MZ_TRUE; + out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h); + if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity))) + { + MZ_FREE(pComp); + return NULL; + } + /* write dummy header */ + for (z = 41; z; --z) + tdefl_output_buffer_putter(&z, 1, &out_buf); + /* compress image data */ + tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER); + for (y = 0; y < h; ++y) + { + tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); + tdefl_compress_buffer(pComp, (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH); + } + if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) + { + MZ_FREE(pComp); + MZ_FREE(out_buf.m_pBuf); + return NULL; + } + /* write real header */ + *pLen_out = out_buf.m_size - 41; + { + static const mz_uint8 chans[] = { 0x00, 0x00, 0x04, 0x02, 0x06 }; + mz_uint8 pnghdr[41] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, + 0x0a, 0x1a, 0x0a, 0x00, 0x00, + 0x00, 0x0d, 0x49, 0x48, 0x44, + 0x52, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x49, 0x44, 0x41, + 0x54 }; + pnghdr[18] = (mz_uint8)(w >> 8); + pnghdr[19] = (mz_uint8)w; + pnghdr[22] = (mz_uint8)(h >> 8); + pnghdr[23] = (mz_uint8)h; + pnghdr[25] = chans[num_chans]; + pnghdr[33] = (mz_uint8)(*pLen_out >> 24); + pnghdr[34] = (mz_uint8)(*pLen_out >> 16); + pnghdr[35] = (mz_uint8)(*pLen_out >> 8); + pnghdr[36] = (mz_uint8)*pLen_out; + c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17); + for (i = 0; i < 4; ++i, c <<= 8) + ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24); + memcpy(out_buf.m_pBuf, pnghdr, 41); + } + /* write footer (IDAT CRC-32, followed by IEND chunk) */ + if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) + { + *pLen_out = 0; + MZ_FREE(pComp); + MZ_FREE(out_buf.m_pBuf); + return NULL; + } + c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, *pLen_out + 4); + for (i = 0; i < 4; ++i, c <<= 8) + (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24); + /* compute final size of file, grab compressed data buffer and return */ + *pLen_out += 57; + MZ_FREE(pComp); + return out_buf.m_pBuf; +} +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out) +{ + /* Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out) */ + return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE); +} + +#ifndef MINIZ_NO_MALLOC +/* Allocate the tdefl_compressor and tinfl_decompressor structures in C so that */ +/* non-C language bindings to tdefL_ and tinfl_ API don't need to worry about */ +/* structure size and allocation mechanism. */ +tdefl_compressor *tdefl_compressor_alloc(void) +{ + return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); +} + +void tdefl_compressor_free(tdefl_compressor *pComp) +{ + MZ_FREE(pComp); +} +#endif + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ + /************************************************************************** + * + * Copyright 2013-2014 RAD Game Tools and Valve Software + * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC + * 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 MINIZ_NO_INFLATE_APIS + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------- Low-level Decompression (completely independent from all compression API's) */ + +#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) +#define TINFL_MEMSET(p, c, l) memset(p, c, l) + +#define TINFL_CR_BEGIN \ + switch (r->m_state) \ + { \ + case 0: +#define TINFL_CR_RETURN(state_index, result) \ + do \ + { \ + status = result; \ + r->m_state = state_index; \ + goto common_exit; \ + case state_index:; \ + } \ + MZ_MACRO_END +#define TINFL_CR_RETURN_FOREVER(state_index, result) \ + do \ + { \ + for (;;) \ + { \ + TINFL_CR_RETURN(state_index, result); \ + } \ + } \ + MZ_MACRO_END +#define TINFL_CR_FINISH } + +#define TINFL_GET_BYTE(state_index, c) \ + do \ + { \ + while (pIn_buf_cur >= pIn_buf_end) \ + { \ + TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \ + } \ + c = *pIn_buf_cur++; \ + } \ + MZ_MACRO_END + +#define TINFL_NEED_BITS(state_index, n) \ + do \ + { \ + mz_uint c; \ + TINFL_GET_BYTE(state_index, c); \ + bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \ + num_bits += 8; \ + } while (num_bits < (mz_uint)(n)) +#define TINFL_SKIP_BITS(state_index, n) \ + do \ + { \ + if (num_bits < (mz_uint)(n)) \ + { \ + TINFL_NEED_BITS(state_index, n); \ + } \ + bit_buf >>= (n); \ + num_bits -= (n); \ + } \ + MZ_MACRO_END +#define TINFL_GET_BITS(state_index, b, n) \ + do \ + { \ + if (num_bits < (mz_uint)(n)) \ + { \ + TINFL_NEED_BITS(state_index, n); \ + } \ + b = bit_buf & ((1 << (n)) - 1); \ + bit_buf >>= (n); \ + num_bits -= (n); \ + } \ + MZ_MACRO_END + +/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */ +/* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */ +/* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */ +/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */ +#define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \ + do \ + { \ + temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ + if (temp >= 0) \ + { \ + code_len = temp >> 9; \ + if ((code_len) && (num_bits >= code_len)) \ + break; \ + } \ + else if (num_bits > TINFL_FAST_LOOKUP_BITS) \ + { \ + code_len = TINFL_FAST_LOOKUP_BITS; \ + do \ + { \ + temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ + } while ((temp < 0) && (num_bits >= (code_len + 1))); \ + if (temp >= 0) \ + break; \ + } \ + TINFL_GET_BYTE(state_index, c); \ + bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \ + num_bits += 8; \ + } while (num_bits < 15); + +/* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read */ +/* beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully */ +/* decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. */ +/* The slow path is only executed at the very end of the input buffer. */ +/* v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes */ +/* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */ +#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \ + do \ + { \ + int temp; \ + mz_uint code_len, c; \ + if (num_bits < 15) \ + { \ + if ((pIn_buf_end - pIn_buf_cur) < 2) \ + { \ + TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \ + } \ + else \ + { \ + bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \ + pIn_buf_cur += 2; \ + num_bits += 16; \ + } \ + } \ + if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ + code_len = temp >> 9, temp &= 511; \ + else \ + { \ + code_len = TINFL_FAST_LOOKUP_BITS; \ + do \ + { \ + temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ + } while (temp < 0); \ + } \ + sym = temp; \ + bit_buf >>= code_len; \ + num_bits -= code_len; \ + } \ + MZ_MACRO_END + +static void tinfl_clear_tree(tinfl_decompressor *r) +{ + if (r->m_type == 0) + MZ_CLEAR_ARR(r->m_tree_0); + else if (r->m_type == 1) + MZ_CLEAR_ARR(r->m_tree_1); + else + MZ_CLEAR_ARR(r->m_tree_2); +} + +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) +{ + static const mz_uint16 s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 }; + static const mz_uint8 s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 }; + static const mz_uint16 s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 }; + static const mz_uint8 s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 }; + static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 }; + + mz_int16 *pTrees[3]; + mz_uint8 *pCode_sizes[3]; + + tinfl_status status = TINFL_STATUS_FAILED; + mz_uint32 num_bits, dist, counter, num_extra; + tinfl_bit_buf_t bit_buf; + const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; + mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next ? pOut_buf_next + *pOut_buf_size : NULL; + size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; + + /* Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). */ + if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) + { + *pIn_buf_size = *pOut_buf_size = 0; + return TINFL_STATUS_BAD_PARAM; + } + + pTrees[0] = r->m_tree_0; + pTrees[1] = r->m_tree_1; + pTrees[2] = r->m_tree_2; + pCode_sizes[0] = r->m_code_size_0; + pCode_sizes[1] = r->m_code_size_1; + pCode_sizes[2] = r->m_code_size_2; + + num_bits = r->m_num_bits; + bit_buf = r->m_bit_buf; + dist = r->m_dist; + counter = r->m_counter; + num_extra = r->m_num_extra; + dist_from_out_buf_start = r->m_dist_from_out_buf_start; + TINFL_CR_BEGIN + + bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; + r->m_z_adler32 = r->m_check_adler32 = 1; + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_GET_BYTE(1, r->m_zhdr0); + TINFL_GET_BYTE(2, r->m_zhdr1); + counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); + if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) + counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)((size_t)1 << (8U + (r->m_zhdr0 >> 4))))); + if (counter) + { + TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); + } + } + + do + { + TINFL_GET_BITS(3, r->m_final, 3); + r->m_type = r->m_final >> 1; + if (r->m_type == 0) + { + TINFL_SKIP_BITS(5, num_bits & 7); + for (counter = 0; counter < 4; ++counter) + { + if (num_bits) + TINFL_GET_BITS(6, r->m_raw_header[counter], 8); + else + TINFL_GET_BYTE(7, r->m_raw_header[counter]); + } + if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) + { + TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); + } + while ((counter) && (num_bits)) + { + TINFL_GET_BITS(51, dist, 8); + while (pOut_buf_cur >= pOut_buf_end) + { + TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); + } + *pOut_buf_cur++ = (mz_uint8)dist; + counter--; + } + while (counter) + { + size_t n; + while (pOut_buf_cur >= pOut_buf_end) + { + TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); + } + while (pIn_buf_cur >= pIn_buf_end) + { + TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); + } + n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter); + TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); + pIn_buf_cur += n; + pOut_buf_cur += n; + counter -= (mz_uint)n; + } + } + else if (r->m_type == 3) + { + TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); + } + else + { + if (r->m_type == 1) + { + mz_uint8 *p = r->m_code_size_0; + mz_uint i; + r->m_table_sizes[0] = 288; + r->m_table_sizes[1] = 32; + TINFL_MEMSET(r->m_code_size_1, 5, 32); + for (i = 0; i <= 143; ++i) + *p++ = 8; + for (; i <= 255; ++i) + *p++ = 9; + for (; i <= 279; ++i) + *p++ = 7; + for (; i <= 287; ++i) + *p++ = 8; + } + else + { + for (counter = 0; counter < 3; counter++) + { + TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); + r->m_table_sizes[counter] += s_min_table_sizes[counter]; + } + MZ_CLEAR_ARR(r->m_code_size_2); + for (counter = 0; counter < r->m_table_sizes[2]; counter++) + { + mz_uint s; + TINFL_GET_BITS(14, s, 3); + r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s; + } + r->m_table_sizes[2] = 19; + } + for (; (int)r->m_type >= 0; r->m_type--) + { + int tree_next, tree_cur; + mz_int16 *pLookUp; + mz_int16 *pTree; + mz_uint8 *pCode_size; + mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; + pLookUp = r->m_look_up[r->m_type]; + pTree = pTrees[r->m_type]; + pCode_size = pCode_sizes[r->m_type]; + MZ_CLEAR_ARR(total_syms); + TINFL_MEMSET(pLookUp, 0, sizeof(r->m_look_up[0])); + tinfl_clear_tree(r); + for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) + total_syms[pCode_size[i]]++; + used_syms = 0, total = 0; + next_code[0] = next_code[1] = 0; + for (i = 1; i <= 15; ++i) + { + used_syms += total_syms[i]; + next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); + } + if ((65536 != total) && (used_syms > 1)) + { + TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); + } + for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) + { + mz_uint rev_code = 0, l, cur_code, code_size = pCode_size[sym_index]; + if (!code_size) + continue; + cur_code = next_code[code_size]++; + for (l = code_size; l > 0; l--, cur_code >>= 1) + rev_code = (rev_code << 1) | (cur_code & 1); + if (code_size <= TINFL_FAST_LOOKUP_BITS) + { + mz_int16 k = (mz_int16)((code_size << 9) | sym_index); + while (rev_code < TINFL_FAST_LOOKUP_SIZE) + { + pLookUp[rev_code] = k; + rev_code += (1 << code_size); + } + continue; + } + if (0 == (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) + { + pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; + tree_cur = tree_next; + tree_next -= 2; + } + rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); + for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) + { + tree_cur -= ((rev_code >>= 1) & 1); + if (!pTree[-tree_cur - 1]) + { + pTree[-tree_cur - 1] = (mz_int16)tree_next; + tree_cur = tree_next; + tree_next -= 2; + } + else + tree_cur = pTree[-tree_cur - 1]; + } + tree_cur -= ((rev_code >>= 1) & 1); + pTree[-tree_cur - 1] = (mz_int16)sym_index; + } + if (r->m_type == 2) + { + for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);) + { + mz_uint s; + TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2); + if (dist < 16) + { + r->m_len_codes[counter++] = (mz_uint8)dist; + continue; + } + if ((dist == 16) && (!counter)) + { + TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); + } + num_extra = "\02\03\07"[dist - 16]; + TINFL_GET_BITS(18, s, num_extra); + s += "\03\03\013"[dist - 16]; + TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); + counter += s; + } + if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) + { + TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); + } + TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]); + TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); + } + } + for (;;) + { + mz_uint8 *pSrc; + for (;;) + { + if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) + { + TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0); + if (counter >= 256) + break; + while (pOut_buf_cur >= pOut_buf_end) + { + TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); + } + *pOut_buf_cur++ = (mz_uint8)counter; + } + else + { + int sym2; + mz_uint code_len; +#if TINFL_USE_64BIT_BITBUF + if (num_bits < 30) + { + bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); + pIn_buf_cur += 4; + num_bits += 32; + } +#else + if (num_bits < 15) + { + bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); + pIn_buf_cur += 2; + num_bits += 16; + } +#endif + if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; + do + { + sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)]; + } while (sym2 < 0); + } + counter = sym2; + bit_buf >>= code_len; + num_bits -= code_len; + if (counter & 256) + break; + +#if !TINFL_USE_64BIT_BITBUF + if (num_bits < 15) + { + bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); + pIn_buf_cur += 2; + num_bits += 16; + } +#endif + if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; + do + { + sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)]; + } while (sym2 < 0); + } + bit_buf >>= code_len; + num_bits -= code_len; + + pOut_buf_cur[0] = (mz_uint8)counter; + if (sym2 & 256) + { + pOut_buf_cur++; + counter = sym2; + break; + } + pOut_buf_cur[1] = (mz_uint8)sym2; + pOut_buf_cur += 2; + } + } + if ((counter &= 511) == 256) + break; + + num_extra = s_length_extra[counter - 257]; + counter = s_length_base[counter - 257]; + if (num_extra) + { + mz_uint extra_bits; + TINFL_GET_BITS(25, extra_bits, num_extra); + counter += extra_bits; + } + + TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1); + num_extra = s_dist_extra[dist]; + dist = s_dist_base[dist]; + if (num_extra) + { + mz_uint extra_bits; + TINFL_GET_BITS(27, extra_bits, num_extra); + dist += extra_bits; + } + + dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; + if ((dist == 0 || dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) + { + TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); + } + + pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask); + + if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) + { + while (counter--) + { + while (pOut_buf_cur >= pOut_buf_end) + { + TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); + } + *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask]; + } + continue; + } +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + else if ((counter >= 9) && (counter <= dist)) + { + const mz_uint8 *pSrc_end = pSrc + (counter & ~7); + do + { +#ifdef MINIZ_UNALIGNED_USE_MEMCPY + memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2); +#else + ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; + ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; +#endif + pOut_buf_cur += 8; + } while ((pSrc += 8) < pSrc_end); + if ((counter &= 7) < 3) + { + if (counter) + { + pOut_buf_cur[0] = pSrc[0]; + if (counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + continue; + } + } +#endif + while(counter>2) + { + pOut_buf_cur[0] = pSrc[0]; + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur[2] = pSrc[2]; + pOut_buf_cur += 3; + pSrc += 3; + counter -= 3; + } + if (counter > 0) + { + pOut_buf_cur[0] = pSrc[0]; + if (counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + } + } + } while (!(r->m_final & 1)); + + /* Ensure byte alignment and put back any bytes from the bitbuf if we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data. */ + /* I'm being super conservative here. A number of simplifications can be made to the byte alignment part, and the Adler32 check shouldn't ever need to worry about reading from the bitbuf now. */ + TINFL_SKIP_BITS(32, num_bits & 7); + while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) + { + --pIn_buf_cur; + num_bits -= 8; + } + bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits); + MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams). */ + + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + for (counter = 0; counter < 4; ++counter) + { + mz_uint s; + if (num_bits) + TINFL_GET_BITS(41, s, 8); + else + TINFL_GET_BYTE(42, s); + r->m_z_adler32 = (r->m_z_adler32 << 8) | s; + } + } + TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); + + TINFL_CR_FINISH + +common_exit: + /* As long as we aren't telling the caller that we NEED more input to make forward progress: */ + /* Put back any bytes from the bitbuf in case we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data. */ + /* We need to be very careful here to NOT push back any bytes we definitely know we need to make forward progress, though, or we'll lock the caller up into an inf loop. */ + if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS)) + { + while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) + { + --pIn_buf_cur; + num_bits -= 8; + } + } + r->m_num_bits = num_bits; + r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits); + r->m_dist = dist; + r->m_counter = counter; + r->m_num_extra = num_extra; + r->m_dist_from_out_buf_start = dist_from_out_buf_start; + *pIn_buf_size = pIn_buf_cur - pIn_buf_next; + *pOut_buf_size = pOut_buf_cur - pOut_buf_next; + if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0)) + { + const mz_uint8 *ptr = pOut_buf_next; + size_t buf_len = *pOut_buf_size; + mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; + size_t block_len = buf_len % 5552; + while (buf_len) + { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) + { + s1 += ptr[0], s2 += s1; + s1 += ptr[1], s2 += s1; + s1 += ptr[2], s2 += s1; + s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; + s1 += ptr[5], s2 += s1; + s1 += ptr[6], s2 += s1; + s1 += ptr[7], s2 += s1; + } + for (; i < block_len; ++i) + s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; + buf_len -= block_len; + block_len = 5552; + } + r->m_check_adler32 = (s2 << 16) + s1; + if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) + status = TINFL_STATUS_ADLER32_MISMATCH; + } + return status; +} + +/* Higher level helper functions. */ +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tinfl_decompressor decomp; + void *pBuf = NULL, *pNew_buf; + size_t src_buf_ofs = 0, out_buf_capacity = 0; + *pOut_len = 0; + tinfl_init(&decomp); + for (;;) + { + size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL, &dst_buf_size, + (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) + { + MZ_FREE(pBuf); + *pOut_len = 0; + return NULL; + } + src_buf_ofs += src_buf_size; + *pOut_len += dst_buf_size; + if (status == TINFL_STATUS_DONE) + break; + new_out_buf_capacity = out_buf_capacity * 2; + if (new_out_buf_capacity < 128) + new_out_buf_capacity = 128; + pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); + if (!pNew_buf) + { + MZ_FREE(pBuf); + *pOut_len = 0; + return NULL; + } + pBuf = pNew_buf; + out_buf_capacity = new_out_buf_capacity; + } + return pBuf; +} + +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tinfl_decompressor decomp; + tinfl_status status; + tinfl_init(&decomp); + status = tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf, &src_buf_len, (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len; +} + +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + int result = 0; + tinfl_decompressor decomp; + mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE); + size_t in_buf_ofs = 0, dict_ofs = 0; + if (!pDict) + return TINFL_STATUS_FAILED; + memset(pDict,0,TINFL_LZ_DICT_SIZE); + tinfl_init(&decomp); + for (;;) + { + size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, + (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); + in_buf_ofs += in_buf_size; + if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) + break; + if (status != TINFL_STATUS_HAS_MORE_OUTPUT) + { + result = (status == TINFL_STATUS_DONE); + break; + } + dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); + } + MZ_FREE(pDict); + *pIn_buf_size = in_buf_ofs; + return result; +} + +#ifndef MINIZ_NO_MALLOC +tinfl_decompressor *tinfl_decompressor_alloc(void) +{ + tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor)); + if (pDecomp) + tinfl_init(pDecomp); + return pDecomp; +} + +void tinfl_decompressor_free(tinfl_decompressor *pDecomp) +{ + MZ_FREE(pDecomp); +} +#endif + +#ifdef __cplusplus +} +#endif + +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ + /************************************************************************** + * + * Copyright 2013-2014 RAD Game Tools and Valve Software + * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC + * Copyright 2016 Martin Raiber + * 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 MINIZ_NO_ARCHIVE_APIS + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------- .ZIP archive reading */ + +#ifdef MINIZ_NO_STDIO +#define MZ_FILE void * +#else +#include + +#if defined(_MSC_VER) || defined(__MINGW64__) + +#define WIN32_LEAN_AND_MEAN +#include + +static WCHAR* mz_utf8z_to_widechar(const char* str) +{ + int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0); + WCHAR* wStr = (WCHAR*)malloc(reqChars * sizeof(WCHAR)); + MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, reqChars); + return wStr; +} + +static FILE *mz_fopen(const char *pFilename, const char *pMode) +{ + WCHAR* wFilename = mz_utf8z_to_widechar(pFilename); + WCHAR* wMode = mz_utf8z_to_widechar(pMode); + FILE* pFile = NULL; + errno_t err = _wfopen_s(&pFile, wFilename, wMode); + free(wFilename); + free(wMode); + return err ? NULL : pFile; +} + +static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) +{ + WCHAR* wPath = mz_utf8z_to_widechar(pPath); + WCHAR* wMode = mz_utf8z_to_widechar(pMode); + FILE* pFile = NULL; + errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream); + free(wPath); + free(wMode); + return err ? NULL : pFile; +} + +static int mz_stat64(const char *path, struct __stat64 *buffer) +{ + WCHAR* wPath = mz_utf8z_to_widechar(path); + int res = _wstat64(wPath, buffer); + free(wPath); + return res; +} + +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FOPEN mz_fopen +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#define MZ_FTELL64 _ftelli64 +#define MZ_FSEEK64 _fseeki64 +#define MZ_FILE_STAT_STRUCT _stat64 +#define MZ_FILE_STAT mz_stat64 +#define MZ_FFLUSH fflush +#define MZ_FREOPEN mz_freopen +#define MZ_DELETE_FILE remove + +#elif defined(__MINGW32__) || defined(__WATCOMC__) +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FOPEN(f, m) fopen(f, m) +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#define MZ_FTELL64 _ftelli64 +#define MZ_FSEEK64 _fseeki64 +#define MZ_FILE_STAT_STRUCT stat +#define MZ_FILE_STAT stat +#define MZ_FFLUSH fflush +#define MZ_FREOPEN(f, m, s) freopen(f, m, s) +#define MZ_DELETE_FILE remove + +#elif defined(__TINYC__) +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FOPEN(f, m) fopen(f, m) +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#define MZ_FTELL64 ftell +#define MZ_FSEEK64 fseek +#define MZ_FILE_STAT_STRUCT stat +#define MZ_FILE_STAT stat +#define MZ_FFLUSH fflush +#define MZ_FREOPEN(f, m, s) freopen(f, m, s) +#define MZ_DELETE_FILE remove + +#elif defined(__USE_LARGEFILE64) /* gcc, clang */ +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FOPEN(f, m) fopen64(f, m) +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#define MZ_FTELL64 ftello64 +#define MZ_FSEEK64 fseeko64 +#define MZ_FILE_STAT_STRUCT stat64 +#define MZ_FILE_STAT stat64 +#define MZ_FFLUSH fflush +#define MZ_FREOPEN(p, m, s) freopen64(p, m, s) +#define MZ_DELETE_FILE remove + +#elif defined(__APPLE__) || defined(__FreeBSD__) +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FOPEN(f, m) fopen(f, m) +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#define MZ_FTELL64 ftello +#define MZ_FSEEK64 fseeko +#define MZ_FILE_STAT_STRUCT stat +#define MZ_FILE_STAT stat +#define MZ_FFLUSH fflush +#define MZ_FREOPEN(p, m, s) freopen(p, m, s) +#define MZ_DELETE_FILE remove + +#else +#pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.") +#ifndef MINIZ_NO_TIME +#include +#endif +#define MZ_FOPEN(f, m) fopen(f, m) +#define MZ_FCLOSE fclose +#define MZ_FREAD fread +#define MZ_FWRITE fwrite +#ifdef __STRICT_ANSI__ +#define MZ_FTELL64 ftell +#define MZ_FSEEK64 fseek +#else +#define MZ_FTELL64 ftello +#define MZ_FSEEK64 fseeko +#endif +#define MZ_FILE_STAT_STRUCT stat +#define MZ_FILE_STAT stat +#define MZ_FFLUSH fflush +#define MZ_FREOPEN(f, m, s) freopen(f, m, s) +#define MZ_DELETE_FILE remove +#endif /* #ifdef _MSC_VER */ +#endif /* #ifdef MINIZ_NO_STDIO */ + +#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) + +/* Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff. */ +enum +{ + /* ZIP archive identifiers and record sizes */ + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50, + MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50, + MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50, + MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22, + + /* ZIP64 archive identifier and record sizes */ + MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06064b50, + MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50, + MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE = 56, + MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20, + MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001, + MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50, + MZ_ZIP_DATA_DESCRIPTER_SIZE64 = 24, + MZ_ZIP_DATA_DESCRIPTER_SIZE32 = 16, + + /* Central directory header record offsets */ + MZ_ZIP_CDH_SIG_OFS = 0, + MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, + MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6, + MZ_ZIP_CDH_BIT_FLAG_OFS = 8, + MZ_ZIP_CDH_METHOD_OFS = 10, + MZ_ZIP_CDH_FILE_TIME_OFS = 12, + MZ_ZIP_CDH_FILE_DATE_OFS = 14, + MZ_ZIP_CDH_CRC32_OFS = 16, + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20, + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24, + MZ_ZIP_CDH_FILENAME_LEN_OFS = 28, + MZ_ZIP_CDH_EXTRA_LEN_OFS = 30, + MZ_ZIP_CDH_COMMENT_LEN_OFS = 32, + MZ_ZIP_CDH_DISK_START_OFS = 34, + MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36, + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38, + MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42, + + /* Local directory header offsets */ + MZ_ZIP_LDH_SIG_OFS = 0, + MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4, + MZ_ZIP_LDH_BIT_FLAG_OFS = 6, + MZ_ZIP_LDH_METHOD_OFS = 8, + MZ_ZIP_LDH_FILE_TIME_OFS = 10, + MZ_ZIP_LDH_FILE_DATE_OFS = 12, + MZ_ZIP_LDH_CRC32_OFS = 14, + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18, + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22, + MZ_ZIP_LDH_FILENAME_LEN_OFS = 26, + MZ_ZIP_LDH_EXTRA_LEN_OFS = 28, + MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR = 1 << 3, + + /* End of central directory offsets */ + MZ_ZIP_ECDH_SIG_OFS = 0, + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4, + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6, + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8, + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10, + MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, + MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, + MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20, + + /* ZIP64 End of central directory locator offsets */ + MZ_ZIP64_ECDL_SIG_OFS = 0, /* 4 bytes */ + MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS = 4, /* 4 bytes */ + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS = 8, /* 8 bytes */ + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS = 16, /* 4 bytes */ + + /* ZIP64 End of central directory header offsets */ + MZ_ZIP64_ECDH_SIG_OFS = 0, /* 4 bytes */ + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS = 4, /* 8 bytes */ + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS = 12, /* 2 bytes */ + MZ_ZIP64_ECDH_VERSION_NEEDED_OFS = 14, /* 2 bytes */ + MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS = 16, /* 4 bytes */ + MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS = 20, /* 4 bytes */ + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 24, /* 8 bytes */ + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS = 32, /* 8 bytes */ + MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40, /* 8 bytes */ + MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48, /* 8 bytes */ + MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID = 0, + MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG = 0x10, + MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED = 1, + MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG = 32, + MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION = 64, + MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED = 8192, + MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 = 1 << 11 +}; + +typedef struct +{ + void *m_p; + size_t m_size, m_capacity; + mz_uint m_element_size; +} mz_zip_array; + +struct mz_zip_internal_state_tag +{ + mz_zip_array m_central_dir; + mz_zip_array m_central_dir_offsets; + mz_zip_array m_sorted_central_dir_offsets; + + /* The flags passed in when the archive is initially opened. */ + mz_uint32 m_init_flags; + + /* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. */ + mz_bool m_zip64; + + /* MZ_TRUE if we found zip64 extended info in the central directory (m_zip64 will also be slammed to true too, even if we didn't find a zip64 end of central dir header, etc.) */ + mz_bool m_zip64_has_extended_info_fields; + + /* These fields are used by the file, FILE, memory, and memory/heap read/write helpers. */ + MZ_FILE *m_pFile; + mz_uint64 m_file_archive_start_ofs; + + void *m_pMem; + size_t m_mem_size; + size_t m_mem_capacity; +}; + +#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size + +#if defined(DEBUG) || defined(_DEBUG) +static MZ_FORCEINLINE mz_uint mz_zip_array_range_check(const mz_zip_array *pArray, mz_uint index) +{ + MZ_ASSERT(index < pArray->m_size); + return index; +} +#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[mz_zip_array_range_check(array_ptr, index)] +#else +#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index] +#endif + +static MZ_FORCEINLINE void mz_zip_array_init(mz_zip_array *pArray, mz_uint32 element_size) +{ + memset(pArray, 0, sizeof(mz_zip_array)); + pArray->m_element_size = element_size; +} + +static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray) +{ + pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p); + memset(pArray, 0, sizeof(mz_zip_array)); +} + +static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing) +{ + void *pNew_p; + size_t new_capacity = min_new_capacity; + MZ_ASSERT(pArray->m_element_size); + if (pArray->m_capacity >= min_new_capacity) + return MZ_TRUE; + if (growing) + { + new_capacity = MZ_MAX(1, pArray->m_capacity); + while (new_capacity < min_new_capacity) + new_capacity *= 2; + } + if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity))) + return MZ_FALSE; + pArray->m_p = pNew_p; + pArray->m_capacity = new_capacity; + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing) +{ + if (new_capacity > pArray->m_capacity) + { + if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) + return MZ_FALSE; + } + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing) +{ + if (new_size > pArray->m_capacity) + { + if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) + return MZ_FALSE; + } + pArray->m_size = new_size; + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n) +{ + return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE); +} + +static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n) +{ + size_t orig_size = pArray->m_size; + if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) + return MZ_FALSE; + if (n > 0) + memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size); + return MZ_TRUE; +} + +#ifndef MINIZ_NO_TIME +static MZ_TIME_T mz_zip_dos_to_time_t(int dos_time, int dos_date) +{ + struct tm tm; + memset(&tm, 0, sizeof(tm)); + tm.tm_isdst = -1; + tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; + tm.tm_mon = ((dos_date >> 5) & 15) - 1; + tm.tm_mday = dos_date & 31; + tm.tm_hour = (dos_time >> 11) & 31; + tm.tm_min = (dos_time >> 5) & 63; + tm.tm_sec = (dos_time << 1) & 62; + return mktime(&tm); +} + +#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS +static void mz_zip_time_t_to_dos_time(MZ_TIME_T time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date) +{ +#ifdef _MSC_VER + struct tm tm_struct; + struct tm *tm = &tm_struct; + errno_t err = localtime_s(tm, &time); + if (err) + { + *pDOS_date = 0; + *pDOS_time = 0; + return; + } +#else + struct tm *tm = localtime(&time); +#endif /* #ifdef _MSC_VER */ + + *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1)); + *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday); +} +#endif /* MINIZ_NO_ARCHIVE_WRITING_APIS */ + +#ifndef MINIZ_NO_STDIO +#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS +static mz_bool mz_zip_get_file_modified_time(const char *pFilename, MZ_TIME_T *pTime) +{ + struct MZ_FILE_STAT_STRUCT file_stat; + + /* On Linux with x86 glibc, this call will fail on large files (I think >= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. */ + if (MZ_FILE_STAT(pFilename, &file_stat) != 0) + return MZ_FALSE; + + *pTime = file_stat.st_mtime; + + return MZ_TRUE; +} +#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS*/ + +static mz_bool mz_zip_set_file_times(const char *pFilename, MZ_TIME_T access_time, MZ_TIME_T modified_time) +{ + struct utimbuf t; + + memset(&t, 0, sizeof(t)); + t.actime = access_time; + t.modtime = modified_time; + + return !utime(pFilename, &t); +} +#endif /* #ifndef MINIZ_NO_STDIO */ +#endif /* #ifndef MINIZ_NO_TIME */ + +static MZ_FORCEINLINE mz_bool mz_zip_set_error(mz_zip_archive *pZip, mz_zip_error err_num) +{ + if (pZip) + pZip->m_last_error = err_num; + return MZ_FALSE; +} + +static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint flags) +{ + (void)flags; + if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (!pZip->m_pAlloc) + pZip->m_pAlloc = miniz_def_alloc_func; + if (!pZip->m_pFree) + pZip->m_pFree = miniz_def_free_func; + if (!pZip->m_pRealloc) + pZip->m_pRealloc = miniz_def_realloc_func; + + pZip->m_archive_size = 0; + pZip->m_central_directory_file_ofs = 0; + pZip->m_total_files = 0; + pZip->m_last_error = MZ_ZIP_NO_ERROR; + + if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32)); + pZip->m_pState->m_init_flags = flags; + pZip->m_pState->m_zip64 = MZ_FALSE; + pZip->m_pState->m_zip64_has_extended_info_fields = MZ_FALSE; + + pZip->m_zip_mode = MZ_ZIP_MODE_READING; + + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index) +{ + const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE; + const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index)); + mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS); + mz_uint8 l = 0, r = 0; + pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + pE = pL + MZ_MIN(l_len, r_len); + while (pL < pE) + { + if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) + break; + pL++; + pR++; + } + return (pL == pE) ? (l_len < r_len) : (l < r); +} + +#define MZ_SWAP_UINT32(a, b) \ + do \ + { \ + mz_uint32 t = a; \ + a = b; \ + b = t; \ + } \ + MZ_MACRO_END + +/* Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.) */ +static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip) +{ + mz_zip_internal_state *pState = pZip->m_pState; + const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; + const mz_zip_array *pCentral_dir = &pState->m_central_dir; + mz_uint32 *pIndices; + mz_uint32 start, end; + const mz_uint32 size = pZip->m_total_files; + + if (size <= 1U) + return; + + pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0); + + start = (size - 2U) >> 1U; + for (;;) + { + mz_uint64 child, root = start; + for (;;) + { + if ((child = (root << 1U) + 1U) >= size) + break; + child += (((child + 1U) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U]))); + if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child])) + break; + MZ_SWAP_UINT32(pIndices[root], pIndices[child]); + root = child; + } + if (!start) + break; + start--; + } + + end = size - 1; + while (end > 0) + { + mz_uint64 child, root = 0; + MZ_SWAP_UINT32(pIndices[end], pIndices[0]); + for (;;) + { + if ((child = (root << 1U) + 1U) >= end) + break; + child += (((child + 1U) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U])); + if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child])) + break; + MZ_SWAP_UINT32(pIndices[root], pIndices[child]); + root = child; + } + end--; + } +} + +static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 record_sig, mz_uint32 record_size, mz_int64 *pOfs) +{ + mz_int64 cur_file_ofs; + mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; + mz_uint8 *pBuf = (mz_uint8 *)buf_u32; + + /* Basic sanity checks - reject files which are too small */ + if (pZip->m_archive_size < record_size) + return MZ_FALSE; + + /* Find the record by scanning the file from the end towards the beginning. */ + cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0); + for (;;) + { + int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs); + + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n) + return MZ_FALSE; + + for (i = n - 4; i >= 0; --i) + { + mz_uint s = MZ_READ_LE32(pBuf + i); + if (s == record_sig) + { + if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size) + break; + } + } + + if (i >= 0) + { + cur_file_ofs += i; + break; + } + + /* Give up if we've searched the entire file, or we've gone back "too far" (~64kb) */ + if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (MZ_UINT16_MAX + record_size))) + return MZ_FALSE; + + cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); + } + + *pOfs = cur_file_ofs; + return MZ_TRUE; +} + +static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flags) +{ + mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0; + mz_uint64 cdir_ofs = 0; + mz_int64 cur_file_ofs = 0; + const mz_uint8 *p; + + mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; + mz_uint8 *pBuf = (mz_uint8 *)buf_u32; + mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0); + mz_uint32 zip64_end_of_central_dir_locator_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; + mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32; + + mz_uint32 zip64_end_of_central_dir_header_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; + mz_uint8 *pZip64_end_of_central_dir = (mz_uint8 *)zip64_end_of_central_dir_header_u32; + + mz_uint64 zip64_end_of_central_dir_ofs = 0; + + /* Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there. */ + if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); + + if (!mz_zip_reader_locate_header_sig(pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs)) + return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR); + + /* Read and verify the end of central directory record. */ + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + + if (MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) + return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); + + if (cur_file_ofs >= (MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)) + { + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE, pZip64_locator, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) + { + if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG) + { + zip64_end_of_central_dir_ofs = MZ_READ_LE64(pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS); + if (zip64_end_of_central_dir_ofs > (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)) + return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); + + if (pZip->m_pRead(pZip->m_pIO_opaque, zip64_end_of_central_dir_ofs, pZip64_end_of_central_dir, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) + { + if (MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG) + { + pZip->m_pState->m_zip64 = MZ_TRUE; + } + } + } + } + } + + pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS); + cdir_entries_on_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS); + num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS); + cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS); + cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS); + cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); + + if (pZip->m_pState->m_zip64) + { + mz_uint32 zip64_total_num_of_disks = MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS); + mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS); + mz_uint64 zip64_cdir_total_entries_on_this_disk = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS); + mz_uint64 zip64_size_of_end_of_central_dir_record = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS); + mz_uint64 zip64_size_of_central_directory = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS); + + if (zip64_size_of_end_of_central_dir_record < (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + if (zip64_total_num_of_disks != 1U) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); + + /* Check for miniz's practical limits */ + if (zip64_cdir_total_entries > MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); + + pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries; + + if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); + + cdir_entries_on_this_disk = (mz_uint32)zip64_cdir_total_entries_on_this_disk; + + /* Check for miniz's current practical limits (sorry, this should be enough for millions of files) */ + if (zip64_size_of_central_directory > MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); + + cdir_size = (mz_uint32)zip64_size_of_central_directory; + + num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS); + + cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS); + + cdir_ofs = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS); + } + + if (pZip->m_total_files != cdir_entries_on_this_disk) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); + + if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1))) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); + + if (cdir_size < (mz_uint64)pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + pZip->m_central_directory_file_ofs = cdir_ofs; + + if (pZip->m_total_files) + { + mz_uint i, n; + /* Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and possibly another to hold the sorted indices. */ + if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) || + (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE))) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + if (sort_central_dir) + { + if (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE)) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + + /* Now create an index into the central directory file records, do some basic sanity checking on each record */ + p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p; + for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) + { + mz_uint total_header_size, disk_index, bit_flags, filename_size, ext_data_size; + mz_uint64 comp_size, decomp_size, local_header_ofs; + + if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p); + + if (sort_central_dir) + MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i; + + comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); + decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); + local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); + filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); + ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS); + + if ((!pZip->m_pState->m_zip64_has_extended_info_fields) && + (ext_data_size) && + (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) == MZ_UINT32_MAX)) + { + /* Attempt to find zip64 extended information field in the entry's extra data */ + mz_uint32 extra_size_remaining = ext_data_size; + + if (extra_size_remaining) + { + const mz_uint8 *pExtra_data; + void* buf = NULL; + + if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > n) + { + buf = MZ_MALLOC(ext_data_size); + if(buf==NULL) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size, buf, ext_data_size) != ext_data_size) + { + MZ_FREE(buf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + } + + pExtra_data = (mz_uint8*)buf; + } + else + { + pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size; + } + + do + { + mz_uint32 field_id; + mz_uint32 field_data_size; + + if (extra_size_remaining < (sizeof(mz_uint16) * 2)) + { + MZ_FREE(buf); + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } + + field_id = MZ_READ_LE16(pExtra_data); + field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); + + if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining) + { + MZ_FREE(buf); + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } + + if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) + { + /* Ok, the archive didn't have any zip64 headers but it uses a zip64 extended information field so mark it as zip64 anyway (this can occur with infozip's zip util when it reads compresses files from stdin). */ + pZip->m_pState->m_zip64 = MZ_TRUE; + pZip->m_pState->m_zip64_has_extended_info_fields = MZ_TRUE; + break; + } + + pExtra_data += sizeof(mz_uint16) * 2 + field_data_size; + extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size; + } while (extra_size_remaining); + + MZ_FREE(buf); + } + } + + /* I've seen archives that aren't marked as zip64 that uses zip64 ext data, argh */ + if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX)) + { + if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } + + disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS); + if ((disk_index == MZ_UINT16_MAX) || ((disk_index != num_this_disk) && (disk_index != 1))) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK); + + if (comp_size != MZ_UINT32_MAX) + { + if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } + + bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); + if (bit_flags & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); + + if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + n -= total_header_size; + p += total_header_size; + } + } + + if (sort_central_dir) + mz_zip_reader_sort_central_dir_offsets_by_filename(pZip); + + return MZ_TRUE; +} + +void mz_zip_zero_struct(mz_zip_archive *pZip) +{ + if (pZip) + MZ_CLEAR_PTR(pZip); +} + +static mz_bool mz_zip_reader_end_internal(mz_zip_archive *pZip, mz_bool set_last_error) +{ + mz_bool status = MZ_TRUE; + + if (!pZip) + return MZ_FALSE; + + if ((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) + { + if (set_last_error) + pZip->m_last_error = MZ_ZIP_INVALID_PARAMETER; + + return MZ_FALSE; + } + + if (pZip->m_pState) + { + mz_zip_internal_state *pState = pZip->m_pState; + pZip->m_pState = NULL; + + mz_zip_array_clear(pZip, &pState->m_central_dir); + mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); + mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); + +#ifndef MINIZ_NO_STDIO + if (pState->m_pFile) + { + if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) + { + if (MZ_FCLOSE(pState->m_pFile) == EOF) + { + if (set_last_error) + pZip->m_last_error = MZ_ZIP_FILE_CLOSE_FAILED; + status = MZ_FALSE; + } + } + pState->m_pFile = NULL; + } +#endif /* #ifndef MINIZ_NO_STDIO */ + + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + } + pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; + + return status; +} + +mz_bool mz_zip_reader_end(mz_zip_archive *pZip) +{ + return mz_zip_reader_end_internal(pZip, MZ_TRUE); +} +mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags) +{ + if ((!pZip) || (!pZip->m_pRead)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (!mz_zip_reader_init_internal(pZip, flags)) + return MZ_FALSE; + + pZip->m_zip_type = MZ_ZIP_TYPE_USER; + pZip->m_archive_size = size; + + if (!mz_zip_reader_read_central_dir(pZip, flags)) + { + mz_zip_reader_end_internal(pZip, MZ_FALSE); + return MZ_FALSE; + } + + return MZ_TRUE; +} + +static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) +{ + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n); + memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s); + return s; +} + +mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags) +{ + if (!pMem) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); + + if (!mz_zip_reader_init_internal(pZip, flags)) + return MZ_FALSE; + + pZip->m_zip_type = MZ_ZIP_TYPE_MEMORY; + pZip->m_archive_size = size; + pZip->m_pRead = mz_zip_mem_read_func; + pZip->m_pIO_opaque = pZip; + pZip->m_pNeeds_keepalive = NULL; + +#ifdef __cplusplus + pZip->m_pState->m_pMem = const_cast(pMem); +#else + pZip->m_pState->m_pMem = (void *)pMem; +#endif + + pZip->m_pState->m_mem_size = size; + + if (!mz_zip_reader_read_central_dir(pZip, flags)) + { + mz_zip_reader_end_internal(pZip, MZ_FALSE); + return MZ_FALSE; + } + + return MZ_TRUE; +} + +#ifndef MINIZ_NO_STDIO +static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) +{ + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); + + file_ofs += pZip->m_pState->m_file_archive_start_ofs; + + if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) + return 0; + + return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile); +} + +mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags) +{ + return mz_zip_reader_init_file_v2(pZip, pFilename, flags, 0, 0); +} + +mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size) +{ + mz_uint64 file_size; + MZ_FILE *pFile; + + if ((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + pFile = MZ_FOPEN(pFilename, "rb"); + if (!pFile) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); + + file_size = archive_size; + if (!file_size) + { + if (MZ_FSEEK64(pFile, 0, SEEK_END)) + { + MZ_FCLOSE(pFile); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); + } + + file_size = MZ_FTELL64(pFile); + } + + /* TODO: Better sanity check archive_size and the # of actual remaining bytes */ + + if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + { + MZ_FCLOSE(pFile); + return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); + } + + if (!mz_zip_reader_init_internal(pZip, flags)) + { + MZ_FCLOSE(pFile); + return MZ_FALSE; + } + + pZip->m_zip_type = MZ_ZIP_TYPE_FILE; + pZip->m_pRead = mz_zip_file_read_func; + pZip->m_pIO_opaque = pZip; + pZip->m_pState->m_pFile = pFile; + pZip->m_archive_size = file_size; + pZip->m_pState->m_file_archive_start_ofs = file_start_ofs; + + if (!mz_zip_reader_read_central_dir(pZip, flags)) + { + mz_zip_reader_end_internal(pZip, MZ_FALSE); + return MZ_FALSE; + } + + return MZ_TRUE; +} + +mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags) +{ + mz_uint64 cur_file_ofs; + + if ((!pZip) || (!pFile)) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); + + cur_file_ofs = MZ_FTELL64(pFile); + + if (!archive_size) + { + if (MZ_FSEEK64(pFile, 0, SEEK_END)) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); + + archive_size = MZ_FTELL64(pFile) - cur_file_ofs; + + if (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); + } + + if (!mz_zip_reader_init_internal(pZip, flags)) + return MZ_FALSE; + + pZip->m_zip_type = MZ_ZIP_TYPE_CFILE; + pZip->m_pRead = mz_zip_file_read_func; + + pZip->m_pIO_opaque = pZip; + pZip->m_pState->m_pFile = pFile; + pZip->m_archive_size = archive_size; + pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs; + + if (!mz_zip_reader_read_central_dir(pZip, flags)) + { + mz_zip_reader_end_internal(pZip, MZ_FALSE); + return MZ_FALSE; + } + + return MZ_TRUE; +} + +#endif /* #ifndef MINIZ_NO_STDIO */ + +static MZ_FORCEINLINE const mz_uint8 *mz_zip_get_cdh(mz_zip_archive *pZip, mz_uint file_index) +{ + if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files)) + return NULL; + return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index)); +} + +mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index) +{ + mz_uint m_bit_flag; + const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); + if (!p) + { + mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + return MZ_FALSE; + } + + m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); + return (m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) != 0; +} + +mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index) +{ + mz_uint bit_flag; + mz_uint method; + + const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); + if (!p) + { + mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + return MZ_FALSE; + } + + method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS); + bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); + + if ((method != 0) && (method != MZ_DEFLATED)) + { + mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); + return MZ_FALSE; + } + + if (bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) + { + mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); + return MZ_FALSE; + } + + if (bit_flag & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG) + { + mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); + return MZ_FALSE; + } + + return MZ_TRUE; +} + +mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index) +{ + mz_uint filename_len, attribute_mapping_id, external_attr; + const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); + if (!p) + { + mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + return MZ_FALSE; + } + + filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); + if (filename_len) + { + if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/') + return MZ_TRUE; + } + + /* Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct. */ + /* Most/all zip writers (hopefully) set DOS file/directory attributes in the low 16-bits, so check for the DOS directory flag and ignore the source OS ID in the created by field. */ + /* FIXME: Remove this check? Is it necessary - we already check the filename. */ + attribute_mapping_id = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS) >> 8; + (void)attribute_mapping_id; + + external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); + if ((external_attr & MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG) != 0) + { + return MZ_TRUE; + } + + return MZ_FALSE; +} + +static mz_bool mz_zip_file_stat_internal(mz_zip_archive *pZip, mz_uint file_index, const mz_uint8 *pCentral_dir_header, mz_zip_archive_file_stat *pStat, mz_bool *pFound_zip64_extra_data) +{ + mz_uint n; + const mz_uint8 *p = pCentral_dir_header; + + if (pFound_zip64_extra_data) + *pFound_zip64_extra_data = MZ_FALSE; + + if ((!p) || (!pStat)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + /* Extract fields from the central directory record. */ + pStat->m_file_index = file_index; + pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index); + pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS); + pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS); + pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); + pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS); +#ifndef MINIZ_NO_TIME + pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS)); +#endif + pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS); + pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); + pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); + pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS); + pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); + pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); + + /* Copy as much of the filename and comment as possible. */ + n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); + n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1); + memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); + pStat->m_filename[n] = '\0'; + + n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); + n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1); + pStat->m_comment_size = n; + memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n); + pStat->m_comment[n] = '\0'; + + /* Set some flags for convienance */ + pStat->m_is_directory = mz_zip_reader_is_file_a_directory(pZip, file_index); + pStat->m_is_encrypted = mz_zip_reader_is_file_encrypted(pZip, file_index); + pStat->m_is_supported = mz_zip_reader_is_file_supported(pZip, file_index); + + /* See if we need to read any zip64 extended information fields. */ + /* Confusingly, these zip64 fields can be present even on non-zip64 archives (Debian zip on a huge files from stdin piped to stdout creates them). */ + if (MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size), pStat->m_local_header_ofs) == MZ_UINT32_MAX) + { + /* Attempt to find zip64 extended information field in the entry's extra data */ + mz_uint32 extra_size_remaining = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS); + + if (extra_size_remaining) + { + const mz_uint8 *pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); + + do + { + mz_uint32 field_id; + mz_uint32 field_data_size; + + if (extra_size_remaining < (sizeof(mz_uint16) * 2)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + field_id = MZ_READ_LE16(pExtra_data); + field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); + + if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) + { + const mz_uint8 *pField_data = pExtra_data + sizeof(mz_uint16) * 2; + mz_uint32 field_data_remaining = field_data_size; + + if (pFound_zip64_extra_data) + *pFound_zip64_extra_data = MZ_TRUE; + + if (pStat->m_uncomp_size == MZ_UINT32_MAX) + { + if (field_data_remaining < sizeof(mz_uint64)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + pStat->m_uncomp_size = MZ_READ_LE64(pField_data); + pField_data += sizeof(mz_uint64); + field_data_remaining -= sizeof(mz_uint64); + } + + if (pStat->m_comp_size == MZ_UINT32_MAX) + { + if (field_data_remaining < sizeof(mz_uint64)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + pStat->m_comp_size = MZ_READ_LE64(pField_data); + pField_data += sizeof(mz_uint64); + field_data_remaining -= sizeof(mz_uint64); + } + + if (pStat->m_local_header_ofs == MZ_UINT32_MAX) + { + if (field_data_remaining < sizeof(mz_uint64)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + pStat->m_local_header_ofs = MZ_READ_LE64(pField_data); + pField_data += sizeof(mz_uint64); + field_data_remaining -= sizeof(mz_uint64); + } + + break; + } + + pExtra_data += sizeof(mz_uint16) * 2 + field_data_size; + extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size; + } while (extra_size_remaining); + } + } + + return MZ_TRUE; +} + +static MZ_FORCEINLINE mz_bool mz_zip_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags) +{ + mz_uint i; + if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE) + return 0 == memcmp(pA, pB, len); + for (i = 0; i < len; ++i) + if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i])) + return MZ_FALSE; + return MZ_TRUE; +} + +static MZ_FORCEINLINE int mz_zip_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len) +{ + const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE; + mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS); + mz_uint8 l = 0, r = 0; + pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + pE = pL + MZ_MIN(l_len, r_len); + while (pL < pE) + { + if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) + break; + pL++; + pR++; + } + return (pL == pE) ? (int)(l_len - r_len) : (l - r); +} + +static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename, mz_uint32 *pIndex) +{ + mz_zip_internal_state *pState = pZip->m_pState; + const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; + const mz_zip_array *pCentral_dir = &pState->m_central_dir; + mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0); + const mz_uint32 size = pZip->m_total_files; + const mz_uint filename_len = (mz_uint)strlen(pFilename); + + if (pIndex) + *pIndex = 0; + + if (size) + { + /* yes I could use uint32_t's, but then we would have to add some special case checks in the loop, argh, and */ + /* honestly the major expense here on 32-bit CPU's will still be the filename compare */ + mz_int64 l = 0, h = (mz_int64)size - 1; + + while (l <= h) + { + mz_int64 m = l + ((h - l) >> 1); + mz_uint32 file_index = pIndices[(mz_uint32)m]; + + int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len); + if (!comp) + { + if (pIndex) + *pIndex = file_index; + return MZ_TRUE; + } + else if (comp < 0) + l = m + 1; + else + h = m - 1; + } + } + + return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND); +} + +int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags) +{ + mz_uint32 index; + if (!mz_zip_reader_locate_file_v2(pZip, pName, pComment, flags, &index)) + return -1; + else + return (int)index; +} + +mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex) +{ + mz_uint file_index; + size_t name_len, comment_len; + + if (pIndex) + *pIndex = 0; + + if ((!pZip) || (!pZip->m_pState) || (!pName)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + /* See if we can use a binary search */ + if (((pZip->m_pState->m_init_flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) && + (pZip->m_zip_mode == MZ_ZIP_MODE_READING) && + ((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size)) + { + return mz_zip_locate_file_binary_search(pZip, pName, pIndex); + } + + /* Locate the entry by scanning the entire central directory */ + name_len = strlen(pName); + if (name_len > MZ_UINT16_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + comment_len = pComment ? strlen(pComment) : 0; + if (comment_len > MZ_UINT16_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + for (file_index = 0; file_index < pZip->m_total_files; file_index++) + { + const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index)); + mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS); + const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; + if (filename_len < name_len) + continue; + if (comment_len) + { + mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS); + const char *pFile_comment = pFilename + filename_len + file_extra_len; + if ((file_comment_len != comment_len) || (!mz_zip_string_equal(pComment, pFile_comment, file_comment_len, flags))) + continue; + } + if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len)) + { + int ofs = filename_len - 1; + do + { + if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':')) + break; + } while (--ofs >= 0); + ofs++; + pFilename += ofs; + filename_len -= ofs; + } + if ((filename_len == name_len) && (mz_zip_string_equal(pName, pFilename, filename_len, flags))) + { + if (pIndex) + *pIndex = file_index; + return MZ_TRUE; + } + } + + return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND); +} + +static +mz_bool mz_zip_reader_extract_to_mem_no_alloc1(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size, const mz_zip_archive_file_stat *st) +{ + int status = TINFL_STATUS_DONE; + mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail; + mz_zip_archive_file_stat file_stat; + void *pRead_buf; + mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; + mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + tinfl_decompressor inflator; + + if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (st) { + file_stat = *st; + } else + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) + return MZ_FALSE; + + /* A directory or zero length file */ + if ((file_stat.m_is_directory) || (!file_stat.m_comp_size)) + return MZ_TRUE; + + /* Encryption and patch files are not supported. */ + if (file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); + + /* This function only supports decompressing stored and deflate. */ + if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); + + /* Ensure supplied output buffer is large enough. */ + needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size; + if (buf_size < needed_size) + return mz_zip_set_error(pZip, MZ_ZIP_BUF_TOO_SMALL); + + /* Read and parse the local directory entry. */ + cur_file_ofs = file_stat.m_local_header_ofs; + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) + { + /* The file is stored or the caller has requested the compressed data. */ + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0) + { + if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32) + return mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED); + } +#endif + + return MZ_TRUE; + } + + /* Decompress the file either directly from memory or from a file input buffer. */ + tinfl_init(&inflator); + + if (pZip->m_pState->m_pMem) + { + /* Read directly from the archive in memory. */ + pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; + read_buf_size = read_buf_avail = file_stat.m_comp_size; + comp_remaining = 0; + } + else if (pUser_read_buf) + { + /* Use a user provided read buffer. */ + if (!user_read_buf_size) + return MZ_FALSE; + pRead_buf = (mz_uint8 *)pUser_read_buf; + read_buf_size = user_read_buf_size; + read_buf_avail = 0; + comp_remaining = file_stat.m_comp_size; + } + else + { + /* Temporarily allocate a read buffer. */ + read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); + if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF)) + return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + + if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + read_buf_avail = 0; + comp_remaining = file_stat.m_comp_size; + } + + do + { + /* The size_t cast here should be OK because we've verified that the output buffer is >= file_stat.m_uncomp_size above */ + size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs); + if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) + { + read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) + { + status = TINFL_STATUS_FAILED; + mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED); + break; + } + cur_file_ofs += read_buf_avail; + comp_remaining -= read_buf_avail; + read_buf_ofs = 0; + } + in_buf_size = (size_t)read_buf_avail; + status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0)); + read_buf_avail -= in_buf_size; + read_buf_ofs += in_buf_size; + out_buf_ofs += out_buf_size; + } while (status == TINFL_STATUS_NEEDS_MORE_INPUT); + + if (status == TINFL_STATUS_DONE) + { + /* Make sure the entire file was decompressed, and check its CRC. */ + if (out_buf_ofs != file_stat.m_uncomp_size) + { + mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE); + status = TINFL_STATUS_FAILED; + } +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + else if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32) + { + mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED); + status = TINFL_STATUS_FAILED; + } +#endif + } + + if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf)) + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + + return status == TINFL_STATUS_DONE; +} + +mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) +{ + return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size, NULL); +} + +mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) +{ + mz_uint32 file_index; + if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) + return MZ_FALSE; + return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size, NULL); +} + +mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags) +{ + return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, buf_size, flags, NULL, 0, NULL); +} + +mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags) +{ + return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0); +} + +void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags) +{ + mz_zip_archive_file_stat file_stat; + mz_uint64 alloc_size; + void *pBuf; + + if (pSize) + *pSize = 0; + + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) + return NULL; + + alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size; + if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) + { + mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + return NULL; + } + + if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size))) + { + mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + return NULL; + } + + if (!mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, (size_t)alloc_size, flags, NULL, 0, &file_stat)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return NULL; + } + + if (pSize) + *pSize = (size_t)alloc_size; + return pBuf; +} + +void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags) +{ + mz_uint32 file_index; + if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) + { + if (pSize) + *pSize = 0; + return MZ_FALSE; + } + return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags); +} + +mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) +{ + int status = TINFL_STATUS_DONE; +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + mz_uint file_crc32 = MZ_CRC32_INIT; +#endif + mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs; + mz_zip_archive_file_stat file_stat; + void *pRead_buf = NULL; + void *pWrite_buf = NULL; + mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; + mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + + if ((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) + return MZ_FALSE; + + /* A directory or zero length file */ + if ((file_stat.m_is_directory) || (!file_stat.m_comp_size)) + return MZ_TRUE; + + /* Encryption and patch files are not supported. */ + if (file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); + + /* This function only supports decompressing stored and deflate. */ + if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); + + /* Read and do some minimal validation of the local directory entry (this doesn't crack the zip64 stuff, which we already have from the central dir) */ + cur_file_ofs = file_stat.m_local_header_ofs; + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + /* Decompress the file either directly from memory or from a file input buffer. */ + if (pZip->m_pState->m_pMem) + { + pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; + read_buf_size = read_buf_avail = file_stat.m_comp_size; + comp_remaining = 0; + } + else + { + read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); + if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + read_buf_avail = 0; + comp_remaining = file_stat.m_comp_size; + } + + if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) + { + /* The file is stored or the caller has requested the compressed data. */ + if (pZip->m_pState->m_pMem) + { + if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > MZ_UINT32_MAX)) + return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + + if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size) + { + mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED); + status = TINFL_STATUS_FAILED; + } + else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + { +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size); +#endif + } + + cur_file_ofs += file_stat.m_comp_size; + out_buf_ofs += file_stat.m_comp_size; + comp_remaining = 0; + } + else + { + while (comp_remaining) + { + read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) + { + mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + status = TINFL_STATUS_FAILED; + break; + } + +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + { + file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail); + } +#endif + + if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) + { + mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED); + status = TINFL_STATUS_FAILED; + break; + } + + cur_file_ofs += read_buf_avail; + out_buf_ofs += read_buf_avail; + comp_remaining -= read_buf_avail; + } + } + } + else + { + tinfl_decompressor inflator; + tinfl_init(&inflator); + + if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE))) + { + mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + status = TINFL_STATUS_FAILED; + } + else + { + do + { + mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); + size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); + if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) + { + read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); + if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) + { + mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + status = TINFL_STATUS_FAILED; + break; + } + cur_file_ofs += read_buf_avail; + comp_remaining -= read_buf_avail; + read_buf_ofs = 0; + } + + in_buf_size = (size_t)read_buf_avail; + status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0); + read_buf_avail -= in_buf_size; + read_buf_ofs += in_buf_size; + + if (out_buf_size) + { + if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size) + { + mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED); + status = TINFL_STATUS_FAILED; + break; + } + +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size); +#endif + if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) + { + mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED); + status = TINFL_STATUS_FAILED; + break; + } + } + } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT)); + } + } + + if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) + { + /* Make sure the entire file was decompressed, and check its CRC. */ + if (out_buf_ofs != file_stat.m_uncomp_size) + { + mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE); + status = TINFL_STATUS_FAILED; + } +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + else if (file_crc32 != file_stat.m_crc32) + { + mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED); + status = TINFL_STATUS_FAILED; + } +#endif + } + + if (!pZip->m_pState->m_pMem) + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + + if (pWrite_buf) + pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf); + + return status == TINFL_STATUS_DONE; +} + +mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) +{ + mz_uint32 file_index; + if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) + return MZ_FALSE; + + return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags); +} + +mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags) +{ + mz_zip_reader_extract_iter_state *pState; + mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; + mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + + /* Argument sanity check */ + if ((!pZip) || (!pZip->m_pState)) + return NULL; + + /* Allocate an iterator status structure */ + pState = (mz_zip_reader_extract_iter_state*)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_reader_extract_iter_state)); + if (!pState) + { + mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + return NULL; + } + + /* Fetch file details */ + if (!mz_zip_reader_file_stat(pZip, file_index, &pState->file_stat)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + return NULL; + } + + /* Encryption and patch files are not supported. */ + if (pState->file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)) + { + mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + return NULL; + } + + /* This function only supports decompressing stored and deflate. */ + if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (pState->file_stat.m_method != 0) && (pState->file_stat.m_method != MZ_DEFLATED)) + { + mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + return NULL; + } + + /* Init state - save args */ + pState->pZip = pZip; + pState->flags = flags; + + /* Init state - reset variables to defaults */ + pState->status = TINFL_STATUS_DONE; +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + pState->file_crc32 = MZ_CRC32_INIT; +#endif + pState->read_buf_ofs = 0; + pState->out_buf_ofs = 0; + pState->pRead_buf = NULL; + pState->pWrite_buf = NULL; + pState->out_blk_remain = 0; + + /* Read and parse the local directory entry. */ + pState->cur_file_ofs = pState->file_stat.m_local_header_ofs; + if (pZip->m_pRead(pZip->m_pIO_opaque, pState->cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + { + mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + return NULL; + } + + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + { + mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + return NULL; + } + + pState->cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) > pZip->m_archive_size) + { + mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + return NULL; + } + + /* Decompress the file either directly from memory or from a file input buffer. */ + if (pZip->m_pState->m_pMem) + { + pState->pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + pState->cur_file_ofs; + pState->read_buf_size = pState->read_buf_avail = pState->file_stat.m_comp_size; + pState->comp_remaining = pState->file_stat.m_comp_size; + } + else + { + if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method))) + { + /* Decompression required, therefore intermediate read buffer required */ + pState->read_buf_size = MZ_MIN(pState->file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE); + if (NULL == (pState->pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)pState->read_buf_size))) + { + mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + return NULL; + } + } + else + { + /* Decompression not required - we will be reading directly into user buffer, no temp buf required */ + pState->read_buf_size = 0; + } + pState->read_buf_avail = 0; + pState->comp_remaining = pState->file_stat.m_comp_size; + } + + if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method))) + { + /* Decompression required, init decompressor */ + tinfl_init( &pState->inflator ); + + /* Allocate write buffer */ + if (NULL == (pState->pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE))) + { + mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + if (pState->pRead_buf) + pZip->m_pFree(pZip->m_pAlloc_opaque, pState->pRead_buf); + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + return NULL; + } + } + + return pState; +} + +mz_zip_reader_extract_iter_state* mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags) +{ + mz_uint32 file_index; + + /* Locate file index by name */ + if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index)) + return NULL; + + /* Construct iterator */ + return mz_zip_reader_extract_iter_new(pZip, file_index, flags); +} + +size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState, void* pvBuf, size_t buf_size) +{ + size_t copied_to_caller = 0; + + /* Argument sanity check */ + if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState) || (!pvBuf)) + return 0; + + if ((pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)) + { + /* The file is stored or the caller has requested the compressed data, calc amount to return. */ + copied_to_caller = (size_t)MZ_MIN( buf_size, pState->comp_remaining ); + + /* Zip is in memory....or requires reading from a file? */ + if (pState->pZip->m_pState->m_pMem) + { + /* Copy data to caller's buffer */ + memcpy( pvBuf, pState->pRead_buf, copied_to_caller ); + pState->pRead_buf = ((mz_uint8*)pState->pRead_buf) + copied_to_caller; + } + else + { + /* Read directly into caller's buffer */ + if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pvBuf, copied_to_caller) != copied_to_caller) + { + /* Failed to read all that was asked for, flag failure and alert user */ + mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED); + pState->status = TINFL_STATUS_FAILED; + copied_to_caller = 0; + } + } + +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + /* Compute CRC if not returning compressed data only */ + if (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, (const mz_uint8 *)pvBuf, copied_to_caller); +#endif + + /* Advance offsets, dec counters */ + pState->cur_file_ofs += copied_to_caller; + pState->out_buf_ofs += copied_to_caller; + pState->comp_remaining -= copied_to_caller; + } + else + { + do + { + /* Calc ptr to write buffer - given current output pos and block size */ + mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pState->pWrite_buf + (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); + + /* Calc max output size - given current output pos and block size */ + size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); + + if (!pState->out_blk_remain) + { + /* Read more data from file if none available (and reading from file) */ + if ((!pState->read_buf_avail) && (!pState->pZip->m_pState->m_pMem)) + { + /* Calc read size */ + pState->read_buf_avail = MZ_MIN(pState->read_buf_size, pState->comp_remaining); + if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pState->pRead_buf, (size_t)pState->read_buf_avail) != pState->read_buf_avail) + { + mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED); + pState->status = TINFL_STATUS_FAILED; + break; + } + + /* Advance offsets, dec counters */ + pState->cur_file_ofs += pState->read_buf_avail; + pState->comp_remaining -= pState->read_buf_avail; + pState->read_buf_ofs = 0; + } + + /* Perform decompression */ + in_buf_size = (size_t)pState->read_buf_avail; + pState->status = tinfl_decompress(&pState->inflator, (const mz_uint8 *)pState->pRead_buf + pState->read_buf_ofs, &in_buf_size, (mz_uint8 *)pState->pWrite_buf, pWrite_buf_cur, &out_buf_size, pState->comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0); + pState->read_buf_avail -= in_buf_size; + pState->read_buf_ofs += in_buf_size; + + /* Update current output block size remaining */ + pState->out_blk_remain = out_buf_size; + } + + if (pState->out_blk_remain) + { + /* Calc amount to return. */ + size_t to_copy = MZ_MIN( (buf_size - copied_to_caller), pState->out_blk_remain ); + + /* Copy data to caller's buffer */ + memcpy( (mz_uint8*)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy ); + +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + /* Perform CRC */ + pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, pWrite_buf_cur, to_copy); +#endif + + /* Decrement data consumed from block */ + pState->out_blk_remain -= to_copy; + + /* Inc output offset, while performing sanity check */ + if ((pState->out_buf_ofs += to_copy) > pState->file_stat.m_uncomp_size) + { + mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED); + pState->status = TINFL_STATUS_FAILED; + break; + } + + /* Increment counter of data copied to caller */ + copied_to_caller += to_copy; + } + } while ( (copied_to_caller < buf_size) && ((pState->status == TINFL_STATUS_NEEDS_MORE_INPUT) || (pState->status == TINFL_STATUS_HAS_MORE_OUTPUT)) ); + } + + /* Return how many bytes were copied into user buffer */ + return copied_to_caller; +} + +mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state* pState) +{ + int status; + + /* Argument sanity check */ + if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState)) + return MZ_FALSE; + + /* Was decompression completed and requested? */ + if ((pState->status == TINFL_STATUS_DONE) && (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) + { + /* Make sure the entire file was decompressed, and check its CRC. */ + if (pState->out_buf_ofs != pState->file_stat.m_uncomp_size) + { + mz_zip_set_error(pState->pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE); + pState->status = TINFL_STATUS_FAILED; + } +#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + else if (pState->file_crc32 != pState->file_stat.m_crc32) + { + mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED); + pState->status = TINFL_STATUS_FAILED; + } +#endif + } + + /* Free buffers */ + if (!pState->pZip->m_pState->m_pMem) + pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pRead_buf); + if (pState->pWrite_buf) + pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pWrite_buf); + + /* Save status */ + status = pState->status; + + /* Free context */ + pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState); + + return status == TINFL_STATUS_DONE; +} + +#ifndef MINIZ_NO_STDIO +static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n) +{ + (void)ofs; + + return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque); +} + +mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags) +{ + mz_bool status; + mz_zip_archive_file_stat file_stat; + MZ_FILE *pFile; + + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) + return MZ_FALSE; + + if ((file_stat.m_is_directory) || (!file_stat.m_is_supported)) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); + + pFile = MZ_FOPEN(pDst_filename, "wb"); + if (!pFile) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); + + status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags); + + if (MZ_FCLOSE(pFile) == EOF) + { + if (status) + mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED); + + status = MZ_FALSE; + } + +#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO) + if (status) + mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time); +#endif + + return status; +} + +mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags) +{ + mz_uint32 file_index; + if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index)) + return MZ_FALSE; + + return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags); +} + +mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *pFile, mz_uint flags) +{ + mz_zip_archive_file_stat file_stat; + + if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) + return MZ_FALSE; + + if ((file_stat.m_is_directory) || (!file_stat.m_is_supported)) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); + + return mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags); +} + +mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags) +{ + mz_uint32 file_index; + if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index)) + return MZ_FALSE; + + return mz_zip_reader_extract_to_cfile(pZip, file_index, pFile, flags); +} +#endif /* #ifndef MINIZ_NO_STDIO */ + +static size_t mz_zip_compute_crc32_callback(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) +{ + mz_uint32 *p = (mz_uint32 *)pOpaque; + (void)file_ofs; + *p = (mz_uint32)mz_crc32(*p, (const mz_uint8 *)pBuf, n); + return n; +} + +mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags) +{ + mz_zip_archive_file_stat file_stat; + mz_zip_internal_state *pState; + const mz_uint8 *pCentral_dir_header; + mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE; + mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE; + mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; + mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + mz_uint64 local_header_ofs = 0; + mz_uint32 local_header_filename_len, local_header_extra_len, local_header_crc32; + mz_uint64 local_header_comp_size, local_header_uncomp_size; + mz_uint32 uncomp_crc32 = MZ_CRC32_INIT; + mz_bool has_data_descriptor; + mz_uint32 local_header_bit_flags; + + mz_zip_array file_data_array; + mz_zip_array_init(&file_data_array, 1); + + if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (file_index > pZip->m_total_files) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + pState = pZip->m_pState; + + pCentral_dir_header = mz_zip_get_cdh(pZip, file_index); + + if (!mz_zip_file_stat_internal(pZip, file_index, pCentral_dir_header, &file_stat, &found_zip64_ext_data_in_cdir)) + return MZ_FALSE; + + /* A directory or zero length file */ + if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size)) + return MZ_TRUE; + + /* Encryption and patch files are not supported. */ + if (file_stat.m_is_encrypted) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION); + + /* This function only supports stored and deflate. */ + if ((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD); + + if (!file_stat.m_is_supported) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE); + + /* Read and parse the local directory entry. */ + local_header_ofs = file_stat.m_local_header_ofs; + if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + local_header_filename_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS); + local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS); + local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS); + local_header_crc32 = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_CRC32_OFS); + local_header_bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS); + has_data_descriptor = (local_header_bit_flags & 8) != 0; + + if (local_header_filename_len != strlen(file_stat.m_filename)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + if ((local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size) > pZip->m_archive_size) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + if (!mz_zip_array_resize(pZip, &file_data_array, MZ_MAX(local_header_filename_len, local_header_extra_len), MZ_FALSE)) + { + mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + goto handle_failure; + } + + if (local_header_filename_len) + { + if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE, file_data_array.m_p, local_header_filename_len) != local_header_filename_len) + { + mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + goto handle_failure; + } + + /* I've seen 1 archive that had the same pathname, but used backslashes in the local dir and forward slashes in the central dir. Do we care about this? For now, this case will fail validation. */ + if (memcmp(file_stat.m_filename, file_data_array.m_p, local_header_filename_len) != 0) + { + mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); + goto handle_failure; + } + } + + if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX))) + { + mz_uint32 extra_size_remaining = local_header_extra_len; + const mz_uint8 *pExtra_data = (const mz_uint8 *)file_data_array.m_p; + + if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len, file_data_array.m_p, local_header_extra_len) != local_header_extra_len) + { + mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + goto handle_failure; + } + + do + { + mz_uint32 field_id, field_data_size, field_total_size; + + if (extra_size_remaining < (sizeof(mz_uint16) * 2)) + { + mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + goto handle_failure; + } + + field_id = MZ_READ_LE16(pExtra_data); + field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); + field_total_size = field_data_size + sizeof(mz_uint16) * 2; + + if (field_total_size > extra_size_remaining) + { + mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + goto handle_failure; + } + + if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) + { + const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32); + + if (field_data_size < sizeof(mz_uint64) * 2) + { + mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + goto handle_failure; + } + + local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data); + local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64)); + + found_zip64_ext_data_in_ldir = MZ_TRUE; + break; + } + + pExtra_data += field_total_size; + extra_size_remaining -= field_total_size; + } while (extra_size_remaining); + } + + /* TODO: parse local header extra data when local_header_comp_size is 0xFFFFFFFF! (big_descriptor.zip) */ + /* I've seen zips in the wild with the data descriptor bit set, but proper local header values and bogus data descriptors */ + if ((has_data_descriptor) && (!local_header_comp_size) && (!local_header_crc32)) + { + mz_uint8 descriptor_buf[32]; + mz_bool has_id; + const mz_uint8 *pSrc; + mz_uint32 file_crc32; + mz_uint64 comp_size = 0, uncomp_size = 0; + + mz_uint32 num_descriptor_uint32s = ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4; + + if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size, descriptor_buf, sizeof(mz_uint32) * num_descriptor_uint32s) != (sizeof(mz_uint32) * num_descriptor_uint32s)) + { + mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + goto handle_failure; + } + + has_id = (MZ_READ_LE32(descriptor_buf) == MZ_ZIP_DATA_DESCRIPTOR_ID); + pSrc = has_id ? (descriptor_buf + sizeof(mz_uint32)) : descriptor_buf; + + file_crc32 = MZ_READ_LE32(pSrc); + + if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) + { + comp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32)); + uncomp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32) + sizeof(mz_uint64)); + } + else + { + comp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32)); + uncomp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32) + sizeof(mz_uint32)); + } + + if ((file_crc32 != file_stat.m_crc32) || (comp_size != file_stat.m_comp_size) || (uncomp_size != file_stat.m_uncomp_size)) + { + mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); + goto handle_failure; + } + } + else + { + if ((local_header_crc32 != file_stat.m_crc32) || (local_header_comp_size != file_stat.m_comp_size) || (local_header_uncomp_size != file_stat.m_uncomp_size)) + { + mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); + goto handle_failure; + } + } + + mz_zip_array_clear(pZip, &file_data_array); + + if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0) + { + if (!mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_compute_crc32_callback, &uncomp_crc32, 0)) + return MZ_FALSE; + + /* 1 more check to be sure, although the extract checks too. */ + if (uncomp_crc32 != file_stat.m_crc32) + { + mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); + return MZ_FALSE; + } + } + + return MZ_TRUE; + +handle_failure: + mz_zip_array_clear(pZip, &file_data_array); + return MZ_FALSE; +} + +mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags) +{ + mz_zip_internal_state *pState; + mz_uint32 i; + + if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + pState = pZip->m_pState; + + /* Basic sanity checks */ + if (!pState->m_zip64) + { + if (pZip->m_total_files > MZ_UINT16_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); + + if (pZip->m_archive_size > MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); + } + else + { + if (pState->m_central_dir.m_size >= MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); + } + + for (i = 0; i < pZip->m_total_files; i++) + { + if (MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG & flags) + { + mz_uint32 found_index; + mz_zip_archive_file_stat stat; + + if (!mz_zip_reader_file_stat(pZip, i, &stat)) + return MZ_FALSE; + + if (!mz_zip_reader_locate_file_v2(pZip, stat.m_filename, NULL, 0, &found_index)) + return MZ_FALSE; + + /* This check can fail if there are duplicate filenames in the archive (which we don't check for when writing - that's up to the user) */ + if (found_index != i) + return mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED); + } + + if (!mz_zip_validate_file(pZip, i, flags)) + return MZ_FALSE; + } + + return MZ_TRUE; +} + +mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr) +{ + mz_bool success = MZ_TRUE; + mz_zip_archive zip; + mz_zip_error actual_err = MZ_ZIP_NO_ERROR; + + if ((!pMem) || (!size)) + { + if (pErr) + *pErr = MZ_ZIP_INVALID_PARAMETER; + return MZ_FALSE; + } + + mz_zip_zero_struct(&zip); + + if (!mz_zip_reader_init_mem(&zip, pMem, size, flags)) + { + if (pErr) + *pErr = zip.m_last_error; + return MZ_FALSE; + } + + if (!mz_zip_validate_archive(&zip, flags)) + { + actual_err = zip.m_last_error; + success = MZ_FALSE; + } + + if (!mz_zip_reader_end_internal(&zip, success)) + { + if (!actual_err) + actual_err = zip.m_last_error; + success = MZ_FALSE; + } + + if (pErr) + *pErr = actual_err; + + return success; +} + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr) +{ + mz_bool success = MZ_TRUE; + mz_zip_archive zip; + mz_zip_error actual_err = MZ_ZIP_NO_ERROR; + + if (!pFilename) + { + if (pErr) + *pErr = MZ_ZIP_INVALID_PARAMETER; + return MZ_FALSE; + } + + mz_zip_zero_struct(&zip); + + if (!mz_zip_reader_init_file_v2(&zip, pFilename, flags, 0, 0)) + { + if (pErr) + *pErr = zip.m_last_error; + return MZ_FALSE; + } + + if (!mz_zip_validate_archive(&zip, flags)) + { + actual_err = zip.m_last_error; + success = MZ_FALSE; + } + + if (!mz_zip_reader_end_internal(&zip, success)) + { + if (!actual_err) + actual_err = zip.m_last_error; + success = MZ_FALSE; + } + + if (pErr) + *pErr = actual_err; + + return success; +} +#endif /* #ifndef MINIZ_NO_STDIO */ + +/* ------------------- .ZIP archive writing */ + +#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + +static MZ_FORCEINLINE void mz_write_le16(mz_uint8 *p, mz_uint16 v) +{ + p[0] = (mz_uint8)v; + p[1] = (mz_uint8)(v >> 8); +} +static MZ_FORCEINLINE void mz_write_le32(mz_uint8 *p, mz_uint32 v) +{ + p[0] = (mz_uint8)v; + p[1] = (mz_uint8)(v >> 8); + p[2] = (mz_uint8)(v >> 16); + p[3] = (mz_uint8)(v >> 24); +} +static MZ_FORCEINLINE void mz_write_le64(mz_uint8 *p, mz_uint64 v) +{ + mz_write_le32(p, (mz_uint32)v); + mz_write_le32(p + sizeof(mz_uint32), (mz_uint32)(v >> 32)); +} + +#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v)) +#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v)) +#define MZ_WRITE_LE64(p, v) mz_write_le64((mz_uint8 *)(p), (mz_uint64)(v)) + +static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) +{ + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + mz_zip_internal_state *pState = pZip->m_pState; + mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size); + + if (!n) + return 0; + + /* An allocation this big is likely to just fail on 32-bit systems, so don't even go there. */ + if ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)) + { + mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE); + return 0; + } + + if (new_size > pState->m_mem_capacity) + { + void *pNew_block; + size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); + + while (new_capacity < new_size) + new_capacity *= 2; + + if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity))) + { + mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + return 0; + } + + pState->m_pMem = pNew_block; + pState->m_mem_capacity = new_capacity; + } + memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n); + pState->m_mem_size = (size_t)new_size; + return n; +} + +static mz_bool mz_zip_writer_end_internal(mz_zip_archive *pZip, mz_bool set_last_error) +{ + mz_zip_internal_state *pState; + mz_bool status = MZ_TRUE; + + if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))) + { + if (set_last_error) + mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + return MZ_FALSE; + } + + pState = pZip->m_pState; + pZip->m_pState = NULL; + mz_zip_array_clear(pZip, &pState->m_central_dir); + mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); + mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); + +#ifndef MINIZ_NO_STDIO + if (pState->m_pFile) + { + if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) + { + if (MZ_FCLOSE(pState->m_pFile) == EOF) + { + if (set_last_error) + mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED); + status = MZ_FALSE; + } + } + + pState->m_pFile = NULL; + } +#endif /* #ifndef MINIZ_NO_STDIO */ + + if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem); + pState->m_pMem = NULL; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pState); + pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; + return status; +} + +mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags) +{ + mz_bool zip64 = (flags & MZ_ZIP_FLAG_WRITE_ZIP64) != 0; + + if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) + { + if (!pZip->m_pRead) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + } + + if (pZip->m_file_offset_alignment) + { + /* Ensure user specified file offset alignment is a power of 2. */ + if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + } + + if (!pZip->m_pAlloc) + pZip->m_pAlloc = miniz_def_alloc_func; + if (!pZip->m_pFree) + pZip->m_pFree = miniz_def_free_func; + if (!pZip->m_pRealloc) + pZip->m_pRealloc = miniz_def_realloc_func; + + pZip->m_archive_size = existing_size; + pZip->m_central_directory_file_ofs = 0; + pZip->m_total_files = 0; + + if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); + + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32)); + MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32)); + + pZip->m_pState->m_zip64 = zip64; + pZip->m_pState->m_zip64_has_extended_info_fields = zip64; + + pZip->m_zip_type = MZ_ZIP_TYPE_USER; + pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size) +{ + return mz_zip_writer_init_v2(pZip, existing_size, 0); +} + +mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags) +{ + pZip->m_pWrite = mz_zip_heap_write_func; + pZip->m_pNeeds_keepalive = NULL; + + if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) + pZip->m_pRead = mz_zip_mem_read_func; + + pZip->m_pIO_opaque = pZip; + + if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags)) + return MZ_FALSE; + + pZip->m_zip_type = MZ_ZIP_TYPE_HEAP; + + if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning))) + { + if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size))) + { + mz_zip_writer_end_internal(pZip, MZ_FALSE); + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + pZip->m_pState->m_mem_capacity = initial_allocation_size; + } + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size) +{ + return mz_zip_writer_init_heap_v2(pZip, size_to_reserve_at_beginning, initial_allocation_size, 0); +} + +#ifndef MINIZ_NO_STDIO +static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) +{ + mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; + mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); + + file_ofs += pZip->m_pState->m_file_archive_start_ofs; + + if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) + { + mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED); + return 0; + } + + return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile); +} + +mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning) +{ + return mz_zip_writer_init_file_v2(pZip, pFilename, size_to_reserve_at_beginning, 0); +} + +mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags) +{ + MZ_FILE *pFile; + + pZip->m_pWrite = mz_zip_file_write_func; + pZip->m_pNeeds_keepalive = NULL; + + if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) + pZip->m_pRead = mz_zip_file_read_func; + + pZip->m_pIO_opaque = pZip; + + if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags)) + return MZ_FALSE; + + if (NULL == (pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) ? "w+b" : "wb"))) + { + mz_zip_writer_end(pZip); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); + } + + pZip->m_pState->m_pFile = pFile; + pZip->m_zip_type = MZ_ZIP_TYPE_FILE; + + if (size_to_reserve_at_beginning) + { + mz_uint64 cur_ofs = 0; + char buf[4096]; + + MZ_CLEAR_ARR(buf); + + do + { + size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n) + { + mz_zip_writer_end(pZip); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + cur_ofs += n; + size_to_reserve_at_beginning -= n; + } while (size_to_reserve_at_beginning); + } + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags) +{ + pZip->m_pWrite = mz_zip_file_write_func; + pZip->m_pNeeds_keepalive = NULL; + + if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) + pZip->m_pRead = mz_zip_file_read_func; + + pZip->m_pIO_opaque = pZip; + + if (!mz_zip_writer_init_v2(pZip, 0, flags)) + return MZ_FALSE; + + pZip->m_pState->m_pFile = pFile; + pZip->m_pState->m_file_archive_start_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); + pZip->m_zip_type = MZ_ZIP_TYPE_CFILE; + + return MZ_TRUE; +} +#endif /* #ifndef MINIZ_NO_STDIO */ + +mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags) +{ + mz_zip_internal_state *pState; + + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (flags & MZ_ZIP_FLAG_WRITE_ZIP64) + { + /* We don't support converting a non-zip64 file to zip64 - this seems like more trouble than it's worth. (What about the existing 32-bit data descriptors that could follow the compressed data?) */ + if (!pZip->m_pState->m_zip64) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + } + + /* No sense in trying to write to an archive that's already at the support max size */ + if (pZip->m_pState->m_zip64) + { + if (pZip->m_total_files == MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); + } + else + { + if (pZip->m_total_files == MZ_UINT16_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); + + if ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE); + } + + pState = pZip->m_pState; + + if (pState->m_pFile) + { +#ifdef MINIZ_NO_STDIO + (void)pFilename; + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); +#else + if (pZip->m_pIO_opaque != pZip) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) + { + if (!pFilename) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + /* Archive is being read from stdio and was originally opened only for reading. Try to reopen as writable. */ + if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile))) + { + /* The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it. */ + mz_zip_reader_end_internal(pZip, MZ_FALSE); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); + } + } + + pZip->m_pWrite = mz_zip_file_write_func; + pZip->m_pNeeds_keepalive = NULL; +#endif /* #ifdef MINIZ_NO_STDIO */ + } + else if (pState->m_pMem) + { + /* Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback. */ + if (pZip->m_pIO_opaque != pZip) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + pState->m_mem_capacity = pState->m_mem_size; + pZip->m_pWrite = mz_zip_heap_write_func; + pZip->m_pNeeds_keepalive = NULL; + } + /* Archive is being read via a user provided read function - make sure the user has specified a write function too. */ + else if (!pZip->m_pWrite) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + /* Start writing new files at the archive's current central directory location. */ + /* TODO: We could add a flag that lets the user start writing immediately AFTER the existing central dir - this would be safer. */ + pZip->m_archive_size = pZip->m_central_directory_file_ofs; + pZip->m_central_directory_file_ofs = 0; + + /* Clear the sorted central dir offsets, they aren't useful or maintained now. */ + /* Even though we're now in write mode, files can still be extracted and verified, but file locates will be slow. */ + /* TODO: We could easily maintain the sorted central directory offsets. */ + mz_zip_array_clear(pZip, &pZip->m_pState->m_sorted_central_dir_offsets); + + pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename) +{ + return mz_zip_writer_init_from_reader_v2(pZip, pFilename, 0); +} + +/* TODO: pArchive_name is a terrible name here! */ +mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags) +{ + return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0); +} + +typedef struct +{ + mz_zip_archive *m_pZip; + mz_uint64 m_cur_archive_file_ofs; + mz_uint64 m_comp_size; +} mz_zip_writer_add_state; + +static mz_bool mz_zip_writer_add_put_buf_callback(const void *pBuf, int len, void *pUser) +{ + mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser; + if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len) + return MZ_FALSE; + + pState->m_cur_archive_file_ofs += len; + pState->m_comp_size += len; + return MZ_TRUE; +} + +#define MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 2) +#define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 3) +static mz_uint32 mz_zip_writer_create_zip64_extra_data(mz_uint8 *pBuf, mz_uint64 *pUncomp_size, mz_uint64 *pComp_size, mz_uint64 *pLocal_header_ofs) +{ + mz_uint8 *pDst = pBuf; + mz_uint32 field_size = 0; + + MZ_WRITE_LE16(pDst + 0, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID); + MZ_WRITE_LE16(pDst + 2, 0); + pDst += sizeof(mz_uint16) * 2; + + if (pUncomp_size) + { + MZ_WRITE_LE64(pDst, *pUncomp_size); + pDst += sizeof(mz_uint64); + field_size += sizeof(mz_uint64); + } + + if (pComp_size) + { + MZ_WRITE_LE64(pDst, *pComp_size); + pDst += sizeof(mz_uint64); + field_size += sizeof(mz_uint64); + } + + if (pLocal_header_ofs) + { + MZ_WRITE_LE64(pDst, *pLocal_header_ofs); + pDst += sizeof(mz_uint64); + field_size += sizeof(mz_uint64); + } + + MZ_WRITE_LE16(pBuf + 2, field_size); + + return (mz_uint32)(pDst - pBuf); +} + +static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date) +{ + (void)pZip; + memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, MZ_MIN(comp_size, MZ_UINT32_MAX)); + MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, MZ_MIN(uncomp_size, MZ_UINT32_MAX)); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size); + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, + mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size, + mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, + mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, + mz_uint64 local_header_ofs, mz_uint32 ext_attributes) +{ + (void)pZip; + memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, MZ_MIN(comp_size, MZ_UINT32_MAX)); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, MZ_MIN(uncomp_size, MZ_UINT32_MAX)); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size); + MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes); + MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_MIN(local_header_ofs, MZ_UINT32_MAX)); + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, + const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, + mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, + mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, + mz_uint64 local_header_ofs, mz_uint32 ext_attributes, + const char *user_extra_data, mz_uint user_extra_data_len) +{ + mz_zip_internal_state *pState = pZip->m_pState; + mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size; + size_t orig_central_dir_size = pState->m_central_dir.m_size; + mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; + + if (!pZip->m_pState->m_zip64) + { + if (local_header_ofs > 0xFFFFFFFF) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE); + } + + /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */ + if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + user_extra_data_len + comment_size) >= MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); + + if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, (mz_uint16)(extra_size + user_extra_data_len), comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes)) + return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + + if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir, user_extra_data, user_extra_data_len)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) || + (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, ¢ral_dir_ofs, 1))) + { + /* Try to resize the central directory array back into its original state. */ + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + return MZ_TRUE; +} + +static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name) +{ + /* Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes. */ + if (*pArchive_name == '/') + return MZ_FALSE; + + /* Making sure the name does not contain drive letters or DOS style backward slashes is the responsibility of the program using miniz*/ + + return MZ_TRUE; +} + +static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip) +{ + mz_uint32 n; + if (!pZip->m_file_offset_alignment) + return 0; + n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1)); + return (mz_uint)((pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1)); +} + +static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n) +{ + char buf[4096]; + memset(buf, 0, MZ_MIN(sizeof(buf), n)); + while (n) + { + mz_uint32 s = MZ_MIN(sizeof(buf), n); + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_file_ofs += s; + n -= s; + } + return MZ_TRUE; +} + +mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, + mz_uint64 uncomp_size, mz_uint32 uncomp_crc32) +{ + return mz_zip_writer_add_mem_ex_v2(pZip, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, uncomp_size, uncomp_crc32, NULL, NULL, 0, NULL, 0); +} + +mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, + mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified, + const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) +{ + mz_uint16 method = 0, dos_time = 0, dos_date = 0; + mz_uint level, ext_attributes = 0, num_alignment_padding_bytes; + mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; + size_t archive_name_size; + mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; + tdefl_compressor *pComp = NULL; + mz_bool store_data_uncompressed; + mz_zip_internal_state *pState; + mz_uint8 *pExtra_data = NULL; + mz_uint32 extra_size = 0; + mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE]; + mz_uint16 bit_flags = 0; + + if ((int)level_and_flags < 0) + level_and_flags = MZ_DEFAULT_LEVEL; + + if (uncomp_size || (buf_size && !(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) + bit_flags |= MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR; + + if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME)) + bit_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8; + + level = level_and_flags & 0xF; + store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)); + + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + pState = pZip->m_pState; + + if (pState->m_zip64) + { + if (pZip->m_total_files == MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); + } + else + { + if (pZip->m_total_files == MZ_UINT16_MAX) + { + pState->m_zip64 = MZ_TRUE; + /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */ + } + if (((mz_uint64)buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) + { + pState->m_zip64 = MZ_TRUE; + /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ + } + } + + if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (!mz_zip_writer_validate_archive_name(pArchive_name)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); + +#ifndef MINIZ_NO_TIME + if (last_modified != NULL) + { + mz_zip_time_t_to_dos_time(*last_modified, &dos_time, &dos_date); + } + else + { + MZ_TIME_T cur_time; + time(&cur_time); + mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date); + } +#endif /* #ifndef MINIZ_NO_TIME */ + + if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + { + uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size); + uncomp_size = buf_size; + if (uncomp_size <= 3) + { + level = 0; + store_data_uncompressed = MZ_TRUE; + } + } + + archive_name_size = strlen(pArchive_name); + if (archive_name_size > MZ_UINT16_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); + + num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); + + /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */ + if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); + + if (!pState->m_zip64) + { + /* Bail early if the archive would obviously become too large */ + if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len + + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len + + MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF) + { + pState->m_zip64 = MZ_TRUE; + /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ + } + } + + if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) + { + /* Set DOS Subdirectory attribute bit. */ + ext_attributes |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG; + + /* Subdirectories cannot contain data. */ + if ((buf_size) || (uncomp_size)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + } + + /* Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.) */ + if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + (pState->m_zip64 ? MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE : 0))) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1))) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + if ((!store_data_uncompressed) && (buf_size)) + { + if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)))) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return MZ_FALSE; + } + + local_dir_header_ofs += num_alignment_padding_bytes; + if (pZip->m_file_offset_alignment) + { + MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); + } + cur_archive_file_ofs += num_alignment_padding_bytes; + + MZ_CLEAR_ARR(local_dir_header); + + if (!store_data_uncompressed || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + { + method = MZ_DEFLATED; + } + + if (pState->m_zip64) + { + if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) + { + pExtra_data = extra_data; + extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, + (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); + } + + if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method, bit_flags, dos_time, dos_date)) + return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_archive_file_ofs += sizeof(local_dir_header); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + cur_archive_file_ofs += archive_name_size; + + if (pExtra_data != NULL) + { + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_archive_file_ofs += extra_size; + } + } + else + { + if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) + return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); + if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date)) + return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_archive_file_ofs += sizeof(local_dir_header); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + cur_archive_file_ofs += archive_name_size; + } + + if (user_extra_data_len > 0) + { + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_archive_file_ofs += user_extra_data_len; + } + + if (store_data_uncompressed) + { + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + + cur_archive_file_ofs += buf_size; + comp_size = buf_size; + } + else if (buf_size) + { + mz_zip_writer_add_state state; + + state.m_pZip = pZip; + state.m_cur_archive_file_ofs = cur_archive_file_ofs; + state.m_comp_size = 0; + + if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) || + (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + return mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED); + } + + comp_size = state.m_comp_size; + cur_archive_file_ofs = state.m_cur_archive_file_ofs; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + pComp = NULL; + + if (uncomp_size) + { + mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64]; + mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32; + + MZ_ASSERT(bit_flags & MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR); + + MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID); + MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32); + if (pExtra_data == NULL) + { + if (comp_size > MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); + + MZ_WRITE_LE32(local_dir_footer + 8, comp_size); + MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size); + } + else + { + MZ_WRITE_LE64(local_dir_footer + 8, comp_size); + MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size); + local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64; + } + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size) + return MZ_FALSE; + + cur_archive_file_ofs += local_dir_footer_size; + } + + if (pExtra_data != NULL) + { + extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, + (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); + } + + if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, (mz_uint16)extra_size, pComment, + comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes, + user_extra_data_central, user_extra_data_central_len)) + return MZ_FALSE; + + pZip->m_total_files++; + pZip->m_archive_size = cur_archive_file_ofs; + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, + const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) +{ + mz_uint16 gen_flags; + mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes; + mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0; + mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0; + size_t archive_name_size; + mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; + mz_uint8 *pExtra_data = NULL; + mz_uint32 extra_size = 0; + mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE]; + mz_zip_internal_state *pState; + mz_uint64 file_ofs = 0, cur_archive_header_file_ofs; + + if ((int)level_and_flags < 0) + level_and_flags = MZ_DEFAULT_LEVEL; + level = level_and_flags & 0xF; + + gen_flags = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) ? 0 : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR; + + if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME)) + gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8; + + /* Sanity checks */ + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + pState = pZip->m_pState; + + if ((!pState->m_zip64) && (max_size > MZ_UINT32_MAX)) + { + /* Source file is too large for non-zip64 */ + /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ + pState->m_zip64 = MZ_TRUE; + } + + /* We could support this, but why? */ + if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (!mz_zip_writer_validate_archive_name(pArchive_name)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); + + if (pState->m_zip64) + { + if (pZip->m_total_files == MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); + } + else + { + if (pZip->m_total_files == MZ_UINT16_MAX) + { + pState->m_zip64 = MZ_TRUE; + /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */ + } + } + + archive_name_size = strlen(pArchive_name); + if (archive_name_size > MZ_UINT16_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME); + + num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); + + /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */ + if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); + + if (!pState->m_zip64) + { + /* Bail early if the archive would obviously become too large */ + if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + + archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024 + + MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF) + { + pState->m_zip64 = MZ_TRUE; + /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ + } + } + +#ifndef MINIZ_NO_TIME + if (pFile_time) + { + mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date); + } +#endif + + if (max_size <= 3) + level = 0; + + if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes)) + { + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + + cur_archive_file_ofs += num_alignment_padding_bytes; + local_dir_header_ofs = cur_archive_file_ofs; + + if (pZip->m_file_offset_alignment) + { + MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == 0); + } + + if (max_size && level) + { + method = MZ_DEFLATED; + } + + MZ_CLEAR_ARR(local_dir_header); + if (pState->m_zip64) + { + if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) + { + pExtra_data = extra_data; + if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) + extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, + (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL, + (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); + else + extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, NULL, + NULL, + (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); + } + + if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method, gen_flags, dos_time, dos_date)) + return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_archive_file_ofs += sizeof(local_dir_header); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) + { + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + + cur_archive_file_ofs += archive_name_size; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_archive_file_ofs += extra_size; + } + else + { + if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX)) + return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); + if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date)) + return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_archive_file_ofs += sizeof(local_dir_header); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) + { + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + + cur_archive_file_ofs += archive_name_size; + } + + if (user_extra_data_len > 0) + { + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_archive_file_ofs += user_extra_data_len; + } + + if (max_size) + { + void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE); + if (!pRead_buf) + { + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + if (!level) + { + while (1) + { + size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE); + if (n == 0) + break; + + if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + } + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + file_ofs += n; + uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); + cur_archive_file_ofs += n; + } + uncomp_size = file_ofs; + comp_size = uncomp_size; + } + else + { + mz_bool result = MZ_FALSE; + mz_zip_writer_add_state state; + tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)); + if (!pComp) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + state.m_pZip = pZip; + state.m_cur_archive_file_ofs = cur_archive_file_ofs; + state.m_comp_size = 0; + + if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + } + + for (;;) + { + tdefl_status status; + tdefl_flush flush = TDEFL_NO_FLUSH; + + size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE); + if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size)) + { + mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + break; + } + + file_ofs += n; + uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); + + if (pZip->m_pNeeds_keepalive != NULL && pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque)) + flush = TDEFL_FULL_FLUSH; + + if (n == 0) + flush = TDEFL_FINISH; + + status = tdefl_compress_buffer(pComp, pRead_buf, n, flush); + if (status == TDEFL_STATUS_DONE) + { + result = MZ_TRUE; + break; + } + else if (status != TDEFL_STATUS_OKAY) + { + mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED); + break; + } + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); + + if (!result) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + return MZ_FALSE; + } + + uncomp_size = file_ofs; + comp_size = state.m_comp_size; + cur_archive_file_ofs = state.m_cur_archive_file_ofs; + } + + pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); + } + + if (!(level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)) + { + mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64]; + mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32; + + MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID); + MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32); + if (pExtra_data == NULL) + { + if (comp_size > MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); + + MZ_WRITE_LE32(local_dir_footer + 8, comp_size); + MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size); + } + else + { + MZ_WRITE_LE64(local_dir_footer + 8, comp_size); + MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size); + local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64; + } + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size) + return MZ_FALSE; + + cur_archive_file_ofs += local_dir_footer_size; + } + + if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) + { + if (pExtra_data != NULL) + { + extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, + (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); + } + + if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, + (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), + (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size, + (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size, + uncomp_crc32, method, gen_flags, dos_time, dos_date)) + return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); + + cur_archive_header_file_ofs = local_dir_header_ofs; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + if (pExtra_data != NULL) + { + cur_archive_header_file_ofs += sizeof(local_dir_header); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, pArchive_name, archive_name_size) != archive_name_size) + { + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + + cur_archive_header_file_ofs += archive_name_size; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, extra_data, extra_size) != extra_size) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_archive_header_file_ofs += extra_size; + } + } + + if (pExtra_data != NULL) + { + extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL, + (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL); + } + + if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, (mz_uint16)extra_size, pComment, comment_size, + uncomp_size, comp_size, uncomp_crc32, method, gen_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes, + user_extra_data_central, user_extra_data_central_len)) + return MZ_FALSE; + + pZip->m_total_files++; + pZip->m_archive_size = cur_archive_file_ofs; + + return MZ_TRUE; +} + +#ifndef MINIZ_NO_STDIO + +static size_t mz_file_read_func_stdio(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) +{ + MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque; + mz_int64 cur_ofs = MZ_FTELL64(pSrc_file); + + if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET)))) + return 0; + + return MZ_FREAD(pBuf, 1, n, pSrc_file); +} + +mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, + const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) +{ + return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags, + user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len); +} + +mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) +{ + MZ_FILE *pSrc_file = NULL; + mz_uint64 uncomp_size = 0; + MZ_TIME_T file_modified_time; + MZ_TIME_T *pFile_time = NULL; + mz_bool status; + + memset(&file_modified_time, 0, sizeof(file_modified_time)); + +#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO) + pFile_time = &file_modified_time; + if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time)) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_STAT_FAILED); +#endif + + pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); + if (!pSrc_file) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED); + + MZ_FSEEK64(pSrc_file, 0, SEEK_END); + uncomp_size = MZ_FTELL64(pSrc_file); + MZ_FSEEK64(pSrc_file, 0, SEEK_SET); + + status = mz_zip_writer_add_cfile(pZip, pArchive_name, pSrc_file, uncomp_size, pFile_time, pComment, comment_size, level_and_flags, NULL, 0, NULL, 0); + + MZ_FCLOSE(pSrc_file); + + return status; +} +#endif /* #ifndef MINIZ_NO_STDIO */ + +static mz_bool mz_zip_writer_update_zip64_extension_block(mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, mz_uint32 ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start) +{ + /* + 64 should be enough for any new zip64 data */ + if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE)) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + mz_zip_array_resize(pZip, pNew_ext, 0, MZ_FALSE); + + if ((pUncomp_size) || (pComp_size) || (pLocal_header_ofs) || (pDisk_start)) + { + mz_uint8 new_ext_block[64]; + mz_uint8 *pDst = new_ext_block; + mz_write_le16(pDst, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID); + mz_write_le16(pDst + sizeof(mz_uint16), 0); + pDst += sizeof(mz_uint16) * 2; + + if (pUncomp_size) + { + mz_write_le64(pDst, *pUncomp_size); + pDst += sizeof(mz_uint64); + } + + if (pComp_size) + { + mz_write_le64(pDst, *pComp_size); + pDst += sizeof(mz_uint64); + } + + if (pLocal_header_ofs) + { + mz_write_le64(pDst, *pLocal_header_ofs); + pDst += sizeof(mz_uint64); + } + + if (pDisk_start) + { + mz_write_le32(pDst, *pDisk_start); + pDst += sizeof(mz_uint32); + } + + mz_write_le16(new_ext_block + sizeof(mz_uint16), (mz_uint16)((pDst - new_ext_block) - sizeof(mz_uint16) * 2)); + + if (!mz_zip_array_push_back(pZip, pNew_ext, new_ext_block, pDst - new_ext_block)) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + if ((pExt) && (ext_len)) + { + mz_uint32 extra_size_remaining = ext_len; + const mz_uint8 *pExtra_data = pExt; + + do + { + mz_uint32 field_id, field_data_size, field_total_size; + + if (extra_size_remaining < (sizeof(mz_uint16) * 2)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + field_id = MZ_READ_LE16(pExtra_data); + field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); + field_total_size = field_data_size + sizeof(mz_uint16) * 2; + + if (field_total_size > extra_size_remaining) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + if (field_id != MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) + { + if (!mz_zip_array_push_back(pZip, pNew_ext, pExtra_data, field_total_size)) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + pExtra_data += field_total_size; + extra_size_remaining -= field_total_size; + } while (extra_size_remaining); + } + + return MZ_TRUE; +} + +/* TODO: This func is now pretty freakin complex due to zip64, split it up? */ +mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index) +{ + mz_uint n, bit_flags, num_alignment_padding_bytes, src_central_dir_following_data_size; + mz_uint64 src_archive_bytes_remaining, local_dir_header_ofs; + mz_uint64 cur_src_file_ofs, cur_dst_file_ofs; + mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; + mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; + mz_uint8 new_central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; + size_t orig_central_dir_size; + mz_zip_internal_state *pState; + void *pBuf; + const mz_uint8 *pSrc_central_header; + mz_zip_archive_file_stat src_file_stat; + mz_uint32 src_filename_len, src_comment_len, src_ext_len; + mz_uint32 local_header_filename_size, local_header_extra_len; + mz_uint64 local_header_comp_size, local_header_uncomp_size; + mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE; + + /* Sanity checks */ + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pSource_zip->m_pRead)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + pState = pZip->m_pState; + + /* Don't support copying files from zip64 archives to non-zip64, even though in some cases this is possible */ + if ((pSource_zip->m_pState->m_zip64) && (!pZip->m_pState->m_zip64)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + /* Get pointer to the source central dir header and crack it */ + if (NULL == (pSrc_central_header = mz_zip_get_cdh(pSource_zip, src_file_index))) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_SIG_OFS) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + src_filename_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS); + src_comment_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS); + src_ext_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS); + src_central_dir_following_data_size = src_filename_len + src_ext_len + src_comment_len; + + /* TODO: We don't support central dir's >= MZ_UINT32_MAX bytes right now (+32 fudge factor in case we need to add more extra data) */ + if ((pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + 32) >= MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); + + num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); + + if (!pState->m_zip64) + { + if (pZip->m_total_files == MZ_UINT16_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); + } + else + { + /* TODO: Our zip64 support still has some 32-bit limits that may not be worth fixing. */ + if (pZip->m_total_files == MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); + } + + if (!mz_zip_file_stat_internal(pSource_zip, src_file_index, pSrc_central_header, &src_file_stat, NULL)) + return MZ_FALSE; + + cur_src_file_ofs = src_file_stat.m_local_header_ofs; + cur_dst_file_ofs = pZip->m_archive_size; + + /* Read the source archive's local dir header */ + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + + if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + + cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; + + /* Compute the total size we need to copy (filename+extra data+compressed data) */ + local_header_filename_size = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS); + local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); + local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS); + local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS); + src_archive_bytes_remaining = local_header_filename_size + local_header_extra_len + src_file_stat.m_comp_size; + + /* Try to find a zip64 extended information field */ + if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX))) + { + mz_zip_array file_data_array; + const mz_uint8 *pExtra_data; + mz_uint32 extra_size_remaining = local_header_extra_len; + + mz_zip_array_init(&file_data_array, 1); + if (!mz_zip_array_resize(pZip, &file_data_array, local_header_extra_len, MZ_FALSE)) + { + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, src_file_stat.m_local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_size, file_data_array.m_p, local_header_extra_len) != local_header_extra_len) + { + mz_zip_array_clear(pZip, &file_data_array); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + } + + pExtra_data = (const mz_uint8 *)file_data_array.m_p; + + do + { + mz_uint32 field_id, field_data_size, field_total_size; + + if (extra_size_remaining < (sizeof(mz_uint16) * 2)) + { + mz_zip_array_clear(pZip, &file_data_array); + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } + + field_id = MZ_READ_LE16(pExtra_data); + field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); + field_total_size = field_data_size + sizeof(mz_uint16) * 2; + + if (field_total_size > extra_size_remaining) + { + mz_zip_array_clear(pZip, &file_data_array); + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } + + if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) + { + const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32); + + if (field_data_size < sizeof(mz_uint64) * 2) + { + mz_zip_array_clear(pZip, &file_data_array); + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } + + local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data); + local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64)); /* may be 0 if there's a descriptor */ + + found_zip64_ext_data_in_ldir = MZ_TRUE; + break; + } + + pExtra_data += field_total_size; + extra_size_remaining -= field_total_size; + } while (extra_size_remaining); + + mz_zip_array_clear(pZip, &file_data_array); + } + + if (!pState->m_zip64) + { + /* Try to detect if the new archive will most likely wind up too big and bail early (+(sizeof(mz_uint32) * 4) is for the optional descriptor which could be present, +64 is a fudge factor). */ + /* We also check when the archive is finalized so this doesn't need to be perfect. */ + mz_uint64 approx_new_archive_size = cur_dst_file_ofs + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + src_archive_bytes_remaining + (sizeof(mz_uint32) * 4) + + pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 64; + + if (approx_new_archive_size >= MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); + } + + /* Write dest archive padding */ + if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes)) + return MZ_FALSE; + + cur_dst_file_ofs += num_alignment_padding_bytes; + + local_dir_header_ofs = cur_dst_file_ofs; + if (pZip->m_file_offset_alignment) + { + MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); + } + + /* The original zip's local header+ext block doesn't change, even with zip64, so we can just copy it over to the dest zip */ + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; + + /* Copy over the source archive bytes to the dest archive, also ensure we have enough buf space to handle optional data descriptor */ + if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(32U, MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining))))) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + while (src_archive_bytes_remaining) + { + n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining); + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + } + cur_src_file_ofs += n; + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + cur_dst_file_ofs += n; + + src_archive_bytes_remaining -= n; + } + + /* Now deal with the optional data descriptor */ + bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS); + if (bit_flags & 8) + { + /* Copy data descriptor */ + if ((pSource_zip->m_pState->m_zip64) || (found_zip64_ext_data_in_ldir)) + { + /* src is zip64, dest must be zip64 */ + + /* name uint32_t's */ + /* id 1 (optional in zip64?) */ + /* crc 1 */ + /* comp_size 2 */ + /* uncomp_size 2 */ + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (sizeof(mz_uint32) * 6)) != (sizeof(mz_uint32) * 6)) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + } + + n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID) ? 6 : 5); + } + else + { + /* src is NOT zip64 */ + mz_bool has_id; + + if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + } + + has_id = (MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID); + + if (pZip->m_pState->m_zip64) + { + /* dest is zip64, so upgrade the data descriptor */ + const mz_uint8 *pSrc_descriptor = (const mz_uint8 *)pBuf + (has_id ? sizeof(mz_uint32) : 0); + const mz_uint32 src_crc32 = MZ_READ_LE32(pSrc_descriptor); + const mz_uint64 src_comp_size = MZ_READ_LE32(pSrc_descriptor + sizeof(mz_uint32)); + const mz_uint64 src_uncomp_size = MZ_READ_LE32(pSrc_descriptor + 2*sizeof(mz_uint32)); + + mz_write_le32((mz_uint8 *)pBuf, MZ_ZIP_DATA_DESCRIPTOR_ID); + mz_write_le32((mz_uint8 *)pBuf + sizeof(mz_uint32) * 1, src_crc32); + mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 2, src_comp_size); + mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 4, src_uncomp_size); + + n = sizeof(mz_uint32) * 6; + } + else + { + /* dest is NOT zip64, just copy it as-is */ + n = sizeof(mz_uint32) * (has_id ? 4 : 3); + } + } + + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) + { + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + } + + cur_src_file_ofs += n; + cur_dst_file_ofs += n; + } + pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); + + /* Finally, add the new central dir header */ + orig_central_dir_size = pState->m_central_dir.m_size; + + memcpy(new_central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); + + if (pState->m_zip64) + { + /* This is the painful part: We need to write a new central dir header + ext block with updated zip64 fields, and ensure the old fields (if any) are not included. */ + const mz_uint8 *pSrc_ext = pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len; + mz_zip_array new_ext_block; + + mz_zip_array_init(&new_ext_block, sizeof(mz_uint8)); + + MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, MZ_UINT32_MAX); + MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, MZ_UINT32_MAX); + MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_UINT32_MAX); + + if (!mz_zip_writer_update_zip64_extension_block(&new_ext_block, pZip, pSrc_ext, src_ext_len, &src_file_stat.m_comp_size, &src_file_stat.m_uncomp_size, &local_dir_header_ofs, NULL)) + { + mz_zip_array_clear(pZip, &new_ext_block); + return MZ_FALSE; + } + + MZ_WRITE_LE16(new_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS, new_ext_block.m_size); + + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) + { + mz_zip_array_clear(pZip, &new_ext_block); + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_filename_len)) + { + mz_zip_array_clear(pZip, &new_ext_block); + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_ext_block.m_p, new_ext_block.m_size)) + { + mz_zip_array_clear(pZip, &new_ext_block); + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len + src_ext_len, src_comment_len)) + { + mz_zip_array_clear(pZip, &new_ext_block); + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + mz_zip_array_clear(pZip, &new_ext_block); + } + else + { + /* sanity checks */ + if (cur_dst_file_ofs > MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); + + if (local_dir_header_ofs >= MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); + + MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs); + + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_central_dir_following_data_size)) + { + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + } + + /* This shouldn't trigger unless we screwed up during the initial sanity checks */ + if (pState->m_central_dir.m_size >= MZ_UINT32_MAX) + { + /* TODO: Support central dirs >= 32-bits in size */ + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); + return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE); + } + + n = (mz_uint32)orig_central_dir_size; + if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) + { + mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + } + + pZip->m_total_files++; + pZip->m_archive_size = cur_dst_file_ofs; + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) +{ + mz_zip_internal_state *pState; + mz_uint64 central_dir_ofs, central_dir_size; + mz_uint8 hdr[256]; + + if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + pState = pZip->m_pState; + + if (pState->m_zip64) + { + if ((mz_uint64)pState->m_central_dir.m_size >= MZ_UINT32_MAX) + return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); + } + else + { + if ((pZip->m_total_files > MZ_UINT16_MAX) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX)) + return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); + } + + central_dir_ofs = 0; + central_dir_size = 0; + if (pZip->m_total_files) + { + /* Write central directory */ + central_dir_ofs = pZip->m_archive_size; + central_dir_size = pState->m_central_dir.m_size; + pZip->m_central_directory_file_ofs = central_dir_ofs; + if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + pZip->m_archive_size += central_dir_size; + } + + if (pState->m_zip64) + { + /* Write zip64 end of central directory header */ + mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size; + + MZ_CLEAR_ARR(hdr); + MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDH_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG); + MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - sizeof(mz_uint32) - sizeof(mz_uint64)); + MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS, 0x031E); /* TODO: always Unix */ + MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_NEEDED_OFS, 0x002D); + MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files); + MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files); + MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_SIZE_OFS, central_dir_size); + MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_OFS_OFS, central_dir_ofs); + if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE; + + /* Write zip64 end of central directory locator */ + MZ_CLEAR_ARR(hdr); + MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG); + MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS, rel_ofs_to_zip64_ecdr); + MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS, 1); + if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) != MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + + pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE; + } + + /* Write end of central directory record */ + MZ_CLEAR_ARR(hdr); + MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG); + MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files)); + MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files)); + MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_size)); + MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_ofs)); + + if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + +#ifndef MINIZ_NO_STDIO + if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF)) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED); +#endif /* #ifndef MINIZ_NO_STDIO */ + + pZip->m_archive_size += MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE; + + pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED; + return MZ_TRUE; +} + +mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize) +{ + if ((!ppBuf) || (!pSize)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + *ppBuf = NULL; + *pSize = 0; + + if ((!pZip) || (!pZip->m_pState)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (pZip->m_pWrite != mz_zip_heap_write_func) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + if (!mz_zip_writer_finalize_archive(pZip)) + return MZ_FALSE; + + *ppBuf = pZip->m_pState->m_pMem; + *pSize = pZip->m_pState->m_mem_size; + pZip->m_pState->m_pMem = NULL; + pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0; + + return MZ_TRUE; +} + +mz_bool mz_zip_writer_end(mz_zip_archive *pZip) +{ + return mz_zip_writer_end_internal(pZip, MZ_TRUE); +} + +#ifndef MINIZ_NO_STDIO +mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) +{ + return mz_zip_add_mem_to_archive_file_in_place_v2(pZip_filename, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, NULL); +} + +mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr) +{ + mz_bool status, created_new_archive = MZ_FALSE; + mz_zip_archive zip_archive; + struct MZ_FILE_STAT_STRUCT file_stat; + mz_zip_error actual_err = MZ_ZIP_NO_ERROR; + + mz_zip_zero_struct(&zip_archive); + if ((int)level_and_flags < 0) + level_and_flags = MZ_DEFAULT_LEVEL; + + if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION)) + { + if (pErr) + *pErr = MZ_ZIP_INVALID_PARAMETER; + return MZ_FALSE; + } + + if (!mz_zip_writer_validate_archive_name(pArchive_name)) + { + if (pErr) + *pErr = MZ_ZIP_INVALID_FILENAME; + return MZ_FALSE; + } + + /* Important: The regular non-64 bit version of stat() can fail here if the file is very large, which could cause the archive to be overwritten. */ + /* So be sure to compile with _LARGEFILE64_SOURCE 1 */ + if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) + { + /* Create a new archive. */ + if (!mz_zip_writer_init_file_v2(&zip_archive, pZip_filename, 0, level_and_flags)) + { + if (pErr) + *pErr = zip_archive.m_last_error; + return MZ_FALSE; + } + + created_new_archive = MZ_TRUE; + } + else + { + /* Append to an existing archive. */ + if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) + { + if (pErr) + *pErr = zip_archive.m_last_error; + return MZ_FALSE; + } + + if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags)) + { + if (pErr) + *pErr = zip_archive.m_last_error; + + mz_zip_reader_end_internal(&zip_archive, MZ_FALSE); + + return MZ_FALSE; + } + } + + status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0); + actual_err = zip_archive.m_last_error; + + /* Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) */ + if (!mz_zip_writer_finalize_archive(&zip_archive)) + { + if (!actual_err) + actual_err = zip_archive.m_last_error; + + status = MZ_FALSE; + } + + if (!mz_zip_writer_end_internal(&zip_archive, status)) + { + if (!actual_err) + actual_err = zip_archive.m_last_error; + + status = MZ_FALSE; + } + + if ((!status) && (created_new_archive)) + { + /* It's a new archive and something went wrong, so just delete it. */ + int ignoredStatus = MZ_DELETE_FILE(pZip_filename); + (void)ignoredStatus; + } + + if (pErr) + *pErr = actual_err; + + return status; +} + +void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr) +{ + mz_uint32 file_index; + mz_zip_archive zip_archive; + void *p = NULL; + + if (pSize) + *pSize = 0; + + if ((!pZip_filename) || (!pArchive_name)) + { + if (pErr) + *pErr = MZ_ZIP_INVALID_PARAMETER; + + return NULL; + } + + mz_zip_zero_struct(&zip_archive); + if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) + { + if (pErr) + *pErr = zip_archive.m_last_error; + + return NULL; + } + + if (mz_zip_reader_locate_file_v2(&zip_archive, pArchive_name, pComment, flags, &file_index)) + { + p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags); + } + + mz_zip_reader_end_internal(&zip_archive, p != NULL); + + if (pErr) + *pErr = zip_archive.m_last_error; + + return p; +} + +void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags) +{ + return mz_zip_extract_archive_file_to_heap_v2(pZip_filename, pArchive_name, NULL, pSize, flags, NULL); +} + +#endif /* #ifndef MINIZ_NO_STDIO */ + +#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */ + +/* ------------------- Misc utils */ + +mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip) +{ + return pZip ? pZip->m_zip_mode : MZ_ZIP_MODE_INVALID; +} + +mz_zip_type mz_zip_get_type(mz_zip_archive *pZip) +{ + return pZip ? pZip->m_zip_type : MZ_ZIP_TYPE_INVALID; +} + +mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num) +{ + mz_zip_error prev_err; + + if (!pZip) + return MZ_ZIP_INVALID_PARAMETER; + + prev_err = pZip->m_last_error; + + pZip->m_last_error = err_num; + return prev_err; +} + +mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip) +{ + if (!pZip) + return MZ_ZIP_INVALID_PARAMETER; + + return pZip->m_last_error; +} + +mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip) +{ + return mz_zip_set_last_error(pZip, MZ_ZIP_NO_ERROR); +} + +mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip) +{ + mz_zip_error prev_err; + + if (!pZip) + return MZ_ZIP_INVALID_PARAMETER; + + prev_err = pZip->m_last_error; + + pZip->m_last_error = MZ_ZIP_NO_ERROR; + return prev_err; +} + +const char *mz_zip_get_error_string(mz_zip_error mz_err) +{ + switch (mz_err) + { + case MZ_ZIP_NO_ERROR: + return "no error"; + case MZ_ZIP_UNDEFINED_ERROR: + return "undefined error"; + case MZ_ZIP_TOO_MANY_FILES: + return "too many files"; + case MZ_ZIP_FILE_TOO_LARGE: + return "file too large"; + case MZ_ZIP_UNSUPPORTED_METHOD: + return "unsupported method"; + case MZ_ZIP_UNSUPPORTED_ENCRYPTION: + return "unsupported encryption"; + case MZ_ZIP_UNSUPPORTED_FEATURE: + return "unsupported feature"; + case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR: + return "failed finding central directory"; + case MZ_ZIP_NOT_AN_ARCHIVE: + return "not a ZIP archive"; + case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED: + return "invalid header or archive is corrupted"; + case MZ_ZIP_UNSUPPORTED_MULTIDISK: + return "unsupported multidisk archive"; + case MZ_ZIP_DECOMPRESSION_FAILED: + return "decompression failed or archive is corrupted"; + case MZ_ZIP_COMPRESSION_FAILED: + return "compression failed"; + case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE: + return "unexpected decompressed size"; + case MZ_ZIP_CRC_CHECK_FAILED: + return "CRC-32 check failed"; + case MZ_ZIP_UNSUPPORTED_CDIR_SIZE: + return "unsupported central directory size"; + case MZ_ZIP_ALLOC_FAILED: + return "allocation failed"; + case MZ_ZIP_FILE_OPEN_FAILED: + return "file open failed"; + case MZ_ZIP_FILE_CREATE_FAILED: + return "file create failed"; + case MZ_ZIP_FILE_WRITE_FAILED: + return "file write failed"; + case MZ_ZIP_FILE_READ_FAILED: + return "file read failed"; + case MZ_ZIP_FILE_CLOSE_FAILED: + return "file close failed"; + case MZ_ZIP_FILE_SEEK_FAILED: + return "file seek failed"; + case MZ_ZIP_FILE_STAT_FAILED: + return "file stat failed"; + case MZ_ZIP_INVALID_PARAMETER: + return "invalid parameter"; + case MZ_ZIP_INVALID_FILENAME: + return "invalid filename"; + case MZ_ZIP_BUF_TOO_SMALL: + return "buffer too small"; + case MZ_ZIP_INTERNAL_ERROR: + return "internal error"; + case MZ_ZIP_FILE_NOT_FOUND: + return "file not found"; + case MZ_ZIP_ARCHIVE_TOO_LARGE: + return "archive is too large"; + case MZ_ZIP_VALIDATION_FAILED: + return "validation failed"; + case MZ_ZIP_WRITE_CALLBACK_FAILED: + return "write callback failed"; + case MZ_ZIP_TOTAL_ERRORS: + return "total errors"; + default: + break; + } + + return "unknown error"; +} + +/* Note: Just because the archive is not zip64 doesn't necessarily mean it doesn't have Zip64 extended information extra field, argh. */ +mz_bool mz_zip_is_zip64(mz_zip_archive *pZip) +{ + if ((!pZip) || (!pZip->m_pState)) + return MZ_FALSE; + + return pZip->m_pState->m_zip64; +} + +size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip) +{ + if ((!pZip) || (!pZip->m_pState)) + return 0; + + return pZip->m_pState->m_central_dir.m_size; +} + +mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip) +{ + return pZip ? pZip->m_total_files : 0; +} + +mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip) +{ + if (!pZip) + return 0; + return pZip->m_archive_size; +} + +mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip) +{ + if ((!pZip) || (!pZip->m_pState)) + return 0; + return pZip->m_pState->m_file_archive_start_ofs; +} + +MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip) +{ + if ((!pZip) || (!pZip->m_pState)) + return 0; + return pZip->m_pState->m_pFile; +} + +size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n) +{ + if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pZip->m_pRead)) + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + + return pZip->m_pRead(pZip->m_pIO_opaque, file_ofs, pBuf, n); +} + +mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size) +{ + mz_uint n; + const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index); + if (!p) + { + if (filename_buf_size) + pFilename[0] = '\0'; + mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER); + return 0; + } + n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); + if (filename_buf_size) + { + n = MZ_MIN(n, filename_buf_size - 1); + memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); + pFilename[n] = '\0'; + } + return n + 1; +} + +mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat) +{ + return mz_zip_file_stat_internal(pZip, file_index, mz_zip_get_cdh(pZip, file_index), pStat, NULL); +} + +mz_bool mz_zip_end(mz_zip_archive *pZip) +{ + if (!pZip) + return MZ_FALSE; + + if (pZip->m_zip_mode == MZ_ZIP_MODE_READING) + return mz_zip_reader_end(pZip); +#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + else if ((pZip->m_zip_mode == MZ_ZIP_MODE_WRITING) || (pZip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)) + return mz_zip_writer_end(pZip); +#endif + + return MZ_FALSE; +} + +#ifdef __cplusplus +} +#endif + +#endif /*#ifndef MINIZ_NO_ARCHIVE_APIS*/ diff --git a/libraries/miniz/miniz.h b/libraries/miniz/miniz.h new file mode 100644 index 000000000..9fcfffcc8 --- /dev/null +++ b/libraries/miniz/miniz.h @@ -0,0 +1,1422 @@ +#ifndef MINIZ_EXPORT +#define MINIZ_EXPORT +#endif +/* miniz.c 3.0.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing + See "unlicense" statement at the end of this file. + Rich Geldreich , last updated Oct. 13, 2013 + Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt + + Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define + MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros). + + * Low-level Deflate/Inflate implementation notes: + + Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or + greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses + approximately as well as zlib. + + Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function + coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory + block large enough to hold the entire file. + + The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation. + + * zlib-style API notes: + + miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in + zlib replacement in many apps: + The z_stream struct, optional memory allocation callbacks + deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound + inflateInit/inflateInit2/inflate/inflateReset/inflateEnd + compress, compress2, compressBound, uncompress + CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines. + Supports raw deflate streams or standard zlib streams with adler-32 checking. + + Limitations: + The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries. + I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but + there are no guarantees that miniz.c pulls this off perfectly. + + * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by + Alex Evans. Supports 1-4 bytes/pixel images. + + * ZIP archive API notes: + + The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to + get the job done with minimal fuss. There are simple API's to retrieve file information, read files from + existing archives, create new archives, append new files to existing archives, or clone archive data from + one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h), + or you can specify custom file read/write callbacks. + + - Archive reading: Just call this function to read a single file from a disk archive: + + void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, + size_t *pSize, mz_uint zip_flags); + + For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central + directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files. + + - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file: + + int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); + + The locate operation can optionally check file comments too, which (as one example) can be used to identify + multiple versions of the same file in an archive. This function uses a simple linear search through the central + directory, so it's not very fast. + + Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and + retrieve detailed info on each file by calling mz_zip_reader_file_stat(). + + - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data + to disk and builds an exact image of the central directory in memory. The central directory image is written + all at once at the end of the archive file when the archive is finalized. + + The archive writer can optionally align each file's local header and file data to any power of 2 alignment, + which can be useful when the archive will be read from optical media. Also, the writer supports placing + arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still + readable by any ZIP tool. + + - Archive appending: The simple way to add a single file to an archive is to call this function: + + mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, + const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); + + The archive will be created if it doesn't already exist, otherwise it'll be appended to. + Note the appending is done in-place and is not an atomic operation, so if something goes wrong + during the operation it's possible the archive could be left without a central directory (although the local + file headers and file data will be fine, so the archive will be recoverable). + + For more complex archive modification scenarios: + 1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to + preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the + compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and + you're done. This is safe but requires a bunch of temporary disk space or heap memory. + + 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(), + append new files as needed, then finalize the archive which will write an updated central directory to the + original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a + possibility that the archive's central directory could be lost with this method if anything goes wrong, though. + + - ZIP archive support limitations: + No spanning support. Extraction functions can only handle unencrypted, stored or deflated files. + Requires streams capable of seeking. + + * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the + below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it. + + * Important: For best perf. be sure to customize the below macros for your target platform: + #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 + #define MINIZ_LITTLE_ENDIAN 1 + #define MINIZ_HAS_64BIT_REGISTERS 1 + + * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz + uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files + (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes). +*/ +#pragma once + + + +/* Defines to completely disable specific portions of miniz.c: + If all macros here are defined the only functionality remaining will be CRC-32 and adler-32. */ + +/* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */ +/*#define MINIZ_NO_STDIO */ + +/* If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or */ +/* get/set file times, and the C run-time funcs that get/set times won't be called. */ +/* The current downside is the times written to your archives will be from 1979. */ +/*#define MINIZ_NO_TIME */ + +/* Define MINIZ_NO_DEFLATE_APIS to disable all compression API's. */ +/*#define MINIZ_NO_DEFLATE_APIS */ + +/* Define MINIZ_NO_INFLATE_APIS to disable all decompression API's. */ +/*#define MINIZ_NO_INFLATE_APIS */ + +/* Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. */ +/*#define MINIZ_NO_ARCHIVE_APIS */ + +/* Define MINIZ_NO_ARCHIVE_WRITING_APIS to disable all writing related ZIP archive API's. */ +/*#define MINIZ_NO_ARCHIVE_WRITING_APIS */ + +/* Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. */ +/*#define MINIZ_NO_ZLIB_APIS */ + +/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. */ +/*#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES */ + +/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. + Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc + callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user + functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */ +/*#define MINIZ_NO_MALLOC */ + +#ifdef MINIZ_NO_INFLATE_APIS +#define MINIZ_NO_ARCHIVE_APIS +#endif + +#ifdef MINIZ_NO_DEFLATE_APIS +#define MINIZ_NO_ARCHIVE_WRITING_APIS +#endif + +#if defined(__TINYC__) && (defined(__linux) || defined(__linux__)) +/* TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux */ +#define MINIZ_NO_TIME +#endif + +#include + +#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS) +#include +#endif + +#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__) +/* MINIZ_X86_OR_X64_CPU is only used to help set the below macros. */ +#define MINIZ_X86_OR_X64_CPU 1 +#else +#define MINIZ_X86_OR_X64_CPU 0 +#endif + +/* Set MINIZ_LITTLE_ENDIAN only if not set */ +#if !defined(MINIZ_LITTLE_ENDIAN) +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) + +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */ +#define MINIZ_LITTLE_ENDIAN 1 +#else +#define MINIZ_LITTLE_ENDIAN 0 +#endif + +#else + +#if MINIZ_X86_OR_X64_CPU +#define MINIZ_LITTLE_ENDIAN 1 +#else +#define MINIZ_LITTLE_ENDIAN 0 +#endif + +#endif +#endif + +/* Using unaligned loads and stores causes errors when using UBSan */ +#if defined(__has_feature) +#if __has_feature(undefined_behavior_sanitizer) +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0 +#endif +#endif + +/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES only if not set */ +#if !defined(MINIZ_USE_UNALIGNED_LOADS_AND_STORES) +#if MINIZ_X86_OR_X64_CPU +/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. */ +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0 +#define MINIZ_UNALIGNED_USE_MEMCPY +#else +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0 +#endif +#endif + +#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__) +/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). */ +#define MINIZ_HAS_64BIT_REGISTERS 1 +#else +#define MINIZ_HAS_64BIT_REGISTERS 0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------- zlib-style API Definitions. */ + +/* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! */ +typedef unsigned long mz_ulong; + +/* mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. */ +MINIZ_EXPORT void mz_free(void *p); + +#define MZ_ADLER32_INIT (1) +/* mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. */ +MINIZ_EXPORT mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len); + +#define MZ_CRC32_INIT (0) +/* mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. */ +MINIZ_EXPORT mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len); + +/* Compression strategies. */ +enum +{ + MZ_DEFAULT_STRATEGY = 0, + MZ_FILTERED = 1, + MZ_HUFFMAN_ONLY = 2, + MZ_RLE = 3, + MZ_FIXED = 4 +}; + +/* Method */ +#define MZ_DEFLATED 8 + +/* Heap allocation callbacks. +Note that mz_alloc_func parameter types purposely differ from zlib's: items/size is size_t, not unsigned long. */ +typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); +typedef void (*mz_free_func)(void *opaque, void *address); +typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size); + +/* Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. */ +enum +{ + MZ_NO_COMPRESSION = 0, + MZ_BEST_SPEED = 1, + MZ_BEST_COMPRESSION = 9, + MZ_UBER_COMPRESSION = 10, + MZ_DEFAULT_LEVEL = 6, + MZ_DEFAULT_COMPRESSION = -1 +}; + +#define MZ_VERSION "11.0.2" +#define MZ_VERNUM 0xB002 +#define MZ_VER_MAJOR 11 +#define MZ_VER_MINOR 2 +#define MZ_VER_REVISION 0 +#define MZ_VER_SUBREVISION 0 + +#ifndef MINIZ_NO_ZLIB_APIS + +/* Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). */ +enum +{ + MZ_NO_FLUSH = 0, + MZ_PARTIAL_FLUSH = 1, + MZ_SYNC_FLUSH = 2, + MZ_FULL_FLUSH = 3, + MZ_FINISH = 4, + MZ_BLOCK = 5 +}; + +/* Return status codes. MZ_PARAM_ERROR is non-standard. */ +enum +{ + MZ_OK = 0, + MZ_STREAM_END = 1, + MZ_NEED_DICT = 2, + MZ_ERRNO = -1, + MZ_STREAM_ERROR = -2, + MZ_DATA_ERROR = -3, + MZ_MEM_ERROR = -4, + MZ_BUF_ERROR = -5, + MZ_VERSION_ERROR = -6, + MZ_PARAM_ERROR = -10000 +}; + +/* Window bits */ +#define MZ_DEFAULT_WINDOW_BITS 15 + +struct mz_internal_state; + +/* Compression/decompression stream struct. */ +typedef struct mz_stream_s +{ + const unsigned char *next_in; /* pointer to next byte to read */ + unsigned int avail_in; /* number of bytes available at next_in */ + mz_ulong total_in; /* total number of bytes consumed so far */ + + unsigned char *next_out; /* pointer to next byte to write */ + unsigned int avail_out; /* number of bytes that can be written to next_out */ + mz_ulong total_out; /* total number of bytes produced so far */ + + char *msg; /* error msg (unused) */ + struct mz_internal_state *state; /* internal state, allocated by zalloc/zfree */ + + mz_alloc_func zalloc; /* optional heap allocation function (defaults to malloc) */ + mz_free_func zfree; /* optional heap free function (defaults to free) */ + void *opaque; /* heap alloc function user pointer */ + + int data_type; /* data_type (unused) */ + mz_ulong adler; /* adler32 of the source or uncompressed data */ + mz_ulong reserved; /* not used */ +} mz_stream; + +typedef mz_stream *mz_streamp; + +/* Returns the version string of miniz.c. */ +MINIZ_EXPORT const char *mz_version(void); + +#ifndef MINIZ_NO_DEFLATE_APIS + +/* mz_deflateInit() initializes a compressor with default options: */ +/* Parameters: */ +/* pStream must point to an initialized mz_stream struct. */ +/* level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. */ +/* level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. */ +/* (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) */ +/* Return values: */ +/* MZ_OK on success. */ +/* MZ_STREAM_ERROR if the stream is bogus. */ +/* MZ_PARAM_ERROR if the input parameters are bogus. */ +/* MZ_MEM_ERROR on out of memory. */ +MINIZ_EXPORT int mz_deflateInit(mz_streamp pStream, int level); + +/* mz_deflateInit2() is like mz_deflate(), except with more control: */ +/* Additional parameters: */ +/* method must be MZ_DEFLATED */ +/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) */ +/* mem_level must be between [1, 9] (it's checked but ignored by miniz.c) */ +MINIZ_EXPORT int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); + +/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). */ +MINIZ_EXPORT int mz_deflateReset(mz_streamp pStream); + +/* mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. */ +/* Parameters: */ +/* pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. */ +/* flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. */ +/* Return values: */ +/* MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). */ +/* MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. */ +/* MZ_STREAM_ERROR if the stream is bogus. */ +/* MZ_PARAM_ERROR if one of the parameters is invalid. */ +/* MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) */ +MINIZ_EXPORT int mz_deflate(mz_streamp pStream, int flush); + +/* mz_deflateEnd() deinitializes a compressor: */ +/* Return values: */ +/* MZ_OK on success. */ +/* MZ_STREAM_ERROR if the stream is bogus. */ +MINIZ_EXPORT int mz_deflateEnd(mz_streamp pStream); + +/* mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. */ +MINIZ_EXPORT mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len); + +/* Single-call compression functions mz_compress() and mz_compress2(): */ +/* Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. */ +MINIZ_EXPORT int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); +MINIZ_EXPORT int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level); + +/* mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). */ +MINIZ_EXPORT mz_ulong mz_compressBound(mz_ulong source_len); + +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ + +#ifndef MINIZ_NO_INFLATE_APIS + +/* Initializes a decompressor. */ +MINIZ_EXPORT int mz_inflateInit(mz_streamp pStream); + +/* mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: */ +/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). */ +MINIZ_EXPORT int mz_inflateInit2(mz_streamp pStream, int window_bits); + +/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_inflateEnd() followed by mz_inflateInit()/mz_inflateInit2(). */ +MINIZ_EXPORT int mz_inflateReset(mz_streamp pStream); + +/* Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. */ +/* Parameters: */ +/* pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. */ +/* flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. */ +/* On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). */ +/* MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. */ +/* Return values: */ +/* MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. */ +/* MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. */ +/* MZ_STREAM_ERROR if the stream is bogus. */ +/* MZ_DATA_ERROR if the deflate stream is invalid. */ +/* MZ_PARAM_ERROR if one of the parameters is invalid. */ +/* MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again */ +/* with more input data, or with more room in the output buffer (except when using single call decompression, described above). */ +MINIZ_EXPORT int mz_inflate(mz_streamp pStream, int flush); + +/* Deinitializes a decompressor. */ +MINIZ_EXPORT int mz_inflateEnd(mz_streamp pStream); + +/* Single-call decompression. */ +/* Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. */ +MINIZ_EXPORT int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); +MINIZ_EXPORT int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len); +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ + +/* Returns a string description of the specified error code, or NULL if the error code is invalid. */ +MINIZ_EXPORT const char *mz_error(int err); + +/* Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. */ +/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. */ +#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES +typedef unsigned char Byte; +typedef unsigned int uInt; +typedef mz_ulong uLong; +typedef Byte Bytef; +typedef uInt uIntf; +typedef char charf; +typedef int intf; +typedef void *voidpf; +typedef uLong uLongf; +typedef void *voidp; +typedef void *const voidpc; +#define Z_NULL 0 +#define Z_NO_FLUSH MZ_NO_FLUSH +#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH +#define Z_SYNC_FLUSH MZ_SYNC_FLUSH +#define Z_FULL_FLUSH MZ_FULL_FLUSH +#define Z_FINISH MZ_FINISH +#define Z_BLOCK MZ_BLOCK +#define Z_OK MZ_OK +#define Z_STREAM_END MZ_STREAM_END +#define Z_NEED_DICT MZ_NEED_DICT +#define Z_ERRNO MZ_ERRNO +#define Z_STREAM_ERROR MZ_STREAM_ERROR +#define Z_DATA_ERROR MZ_DATA_ERROR +#define Z_MEM_ERROR MZ_MEM_ERROR +#define Z_BUF_ERROR MZ_BUF_ERROR +#define Z_VERSION_ERROR MZ_VERSION_ERROR +#define Z_PARAM_ERROR MZ_PARAM_ERROR +#define Z_NO_COMPRESSION MZ_NO_COMPRESSION +#define Z_BEST_SPEED MZ_BEST_SPEED +#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION +#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION +#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY +#define Z_FILTERED MZ_FILTERED +#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY +#define Z_RLE MZ_RLE +#define Z_FIXED MZ_FIXED +#define Z_DEFLATED MZ_DEFLATED +#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS +#define alloc_func mz_alloc_func +#define free_func mz_free_func +#define internal_state mz_internal_state +#define z_stream mz_stream + +#ifndef MINIZ_NO_DEFLATE_APIS +#define deflateInit mz_deflateInit +#define deflateInit2 mz_deflateInit2 +#define deflateReset mz_deflateReset +#define deflate mz_deflate +#define deflateEnd mz_deflateEnd +#define deflateBound mz_deflateBound +#define compress mz_compress +#define compress2 mz_compress2 +#define compressBound mz_compressBound +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ + +#ifndef MINIZ_NO_INFLATE_APIS +#define inflateInit mz_inflateInit +#define inflateInit2 mz_inflateInit2 +#define inflateReset mz_inflateReset +#define inflate mz_inflate +#define inflateEnd mz_inflateEnd +#define uncompress mz_uncompress +#define uncompress2 mz_uncompress2 +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ + +#define crc32 mz_crc32 +#define adler32 mz_adler32 +#define MAX_WBITS 15 +#define MAX_MEM_LEVEL 9 +#define zError mz_error +#define ZLIB_VERSION MZ_VERSION +#define ZLIB_VERNUM MZ_VERNUM +#define ZLIB_VER_MAJOR MZ_VER_MAJOR +#define ZLIB_VER_MINOR MZ_VER_MINOR +#define ZLIB_VER_REVISION MZ_VER_REVISION +#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION +#define zlibVersion mz_version +#define zlib_version mz_version() +#endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */ + +#endif /* MINIZ_NO_ZLIB_APIS */ + +#ifdef __cplusplus +} +#endif + + + + + +#pragma once +#include +#include +#include +#include + + + +/* ------------------- Types and macros */ +typedef unsigned char mz_uint8; +typedef signed short mz_int16; +typedef unsigned short mz_uint16; +typedef unsigned int mz_uint32; +typedef unsigned int mz_uint; +typedef int64_t mz_int64; +typedef uint64_t mz_uint64; +typedef int mz_bool; + +#define MZ_FALSE (0) +#define MZ_TRUE (1) + +/* Works around MSVC's spammy "warning C4127: conditional expression is constant" message. */ +#ifdef _MSC_VER +#define MZ_MACRO_END while (0, 0) +#else +#define MZ_MACRO_END while (0) +#endif + +#ifdef MINIZ_NO_STDIO +#define MZ_FILE void * +#else +#include +#define MZ_FILE FILE +#endif /* #ifdef MINIZ_NO_STDIO */ + +#ifdef MINIZ_NO_TIME +typedef struct mz_dummy_time_t_tag +{ + mz_uint32 m_dummy1; + mz_uint32 m_dummy2; +} mz_dummy_time_t; +#define MZ_TIME_T mz_dummy_time_t +#else +#define MZ_TIME_T time_t +#endif + +#define MZ_ASSERT(x) assert(x) + +#ifdef MINIZ_NO_MALLOC +#define MZ_MALLOC(x) NULL +#define MZ_FREE(x) (void)x, ((void)0) +#define MZ_REALLOC(p, x) NULL +#else +#define MZ_MALLOC(x) malloc(x) +#define MZ_FREE(x) free(x) +#define MZ_REALLOC(p, x) realloc(p, x) +#endif + +#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) +#define MZ_CLEAR_ARR(obj) memset((obj), 0, sizeof(obj)) +#define MZ_CLEAR_PTR(obj) memset((obj), 0, sizeof(*obj)) + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN +#define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) +#define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) +#else +#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) +#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) +#endif + +#define MZ_READ_LE64(p) (((mz_uint64)MZ_READ_LE32(p)) | (((mz_uint64)MZ_READ_LE32((const mz_uint8 *)(p) + sizeof(mz_uint32))) << 32U)) + +#ifdef _MSC_VER +#define MZ_FORCEINLINE __forceinline +#elif defined(__GNUC__) +#define MZ_FORCEINLINE __inline__ __attribute__((__always_inline__)) +#else +#define MZ_FORCEINLINE inline +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +extern MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size); +extern MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address); +extern MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size); + +#define MZ_UINT16_MAX (0xFFFFU) +#define MZ_UINT32_MAX (0xFFFFFFFFU) + +#ifdef __cplusplus +} +#endif + #pragma once + + +#ifndef MINIZ_NO_DEFLATE_APIS + +#ifdef __cplusplus +extern "C" { +#endif +/* ------------------- Low-level Compression API Definitions */ + +/* Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). */ +#define TDEFL_LESS_MEMORY 0 + +/* tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): */ +/* TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). */ +enum +{ + TDEFL_HUFFMAN_ONLY = 0, + TDEFL_DEFAULT_MAX_PROBES = 128, + TDEFL_MAX_PROBES_MASK = 0xFFF +}; + +/* TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. */ +/* TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). */ +/* TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. */ +/* TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). */ +/* TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) */ +/* TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. */ +/* TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. */ +/* TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. */ +/* The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK). */ +enum +{ + TDEFL_WRITE_ZLIB_HEADER = 0x01000, + TDEFL_COMPUTE_ADLER32 = 0x02000, + TDEFL_GREEDY_PARSING_FLAG = 0x04000, + TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000, + TDEFL_RLE_MATCHES = 0x10000, + TDEFL_FILTER_MATCHES = 0x20000, + TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000, + TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000 +}; + +/* High level compression functions: */ +/* tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). */ +/* On entry: */ +/* pSrc_buf, src_buf_len: Pointer and size of source block to compress. */ +/* flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. */ +/* On return: */ +/* Function returns a pointer to the compressed data, or NULL on failure. */ +/* *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. */ +/* The caller must free() the returned block when it's no longer needed. */ +MINIZ_EXPORT void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +/* tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. */ +/* Returns 0 on failure. */ +MINIZ_EXPORT size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +/* Compresses an image to a compressed PNG file in memory. */ +/* On entry: */ +/* pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. */ +/* The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory. */ +/* level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL */ +/* If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps). */ +/* On return: */ +/* Function returns a pointer to the compressed data, or NULL on failure. */ +/* *pLen_out will be set to the size of the PNG image file. */ +/* The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. */ +MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip); +MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out); + +/* Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. */ +typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser); + +/* tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. */ +MINIZ_EXPORT mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +enum +{ + TDEFL_MAX_HUFF_TABLES = 3, + TDEFL_MAX_HUFF_SYMBOLS_0 = 288, + TDEFL_MAX_HUFF_SYMBOLS_1 = 32, + TDEFL_MAX_HUFF_SYMBOLS_2 = 19, + TDEFL_LZ_DICT_SIZE = 32768, + TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, + TDEFL_MIN_MATCH_LEN = 3, + TDEFL_MAX_MATCH_LEN = 258 +}; + +/* TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). */ +#if TDEFL_LESS_MEMORY +enum +{ + TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, + TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, + TDEFL_MAX_HUFF_SYMBOLS = 288, + TDEFL_LZ_HASH_BITS = 12, + TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, + TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, + TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS +}; +#else +enum +{ + TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, + TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10, + TDEFL_MAX_HUFF_SYMBOLS = 288, + TDEFL_LZ_HASH_BITS = 15, + TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, + TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, + TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS +}; +#endif + +/* The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. */ +typedef enum { + TDEFL_STATUS_BAD_PARAM = -2, + TDEFL_STATUS_PUT_BUF_FAILED = -1, + TDEFL_STATUS_OKAY = 0, + TDEFL_STATUS_DONE = 1 +} tdefl_status; + +/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */ +typedef enum { + TDEFL_NO_FLUSH = 0, + TDEFL_SYNC_FLUSH = 2, + TDEFL_FULL_FLUSH = 3, + TDEFL_FINISH = 4 +} tdefl_flush; + +/* tdefl's compression state structure. */ +typedef struct +{ + tdefl_put_buf_func_ptr m_pPut_buf_func; + void *m_pPut_buf_user; + mz_uint m_flags, m_max_probes[2]; + int m_greedy_parsing; + mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size; + mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end; + mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer; + mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish; + tdefl_status m_prev_return_status; + const void *m_pIn_buf; + void *m_pOut_buf; + size_t *m_pIn_buf_size, *m_pOut_buf_size; + tdefl_flush m_flush; + const mz_uint8 *m_pSrc; + size_t m_src_buf_left, m_out_buf_ofs; + mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1]; + mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]; + mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]; + mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]; + mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]; +} tdefl_compressor; + +/* Initializes the compressor. */ +/* There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory. */ +/* pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. */ +/* If pBut_buf_func is NULL the user should always call the tdefl_compress() API. */ +/* flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) */ +MINIZ_EXPORT tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +/* Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. */ +MINIZ_EXPORT tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush); + +/* tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. */ +/* tdefl_compress_buffer() always consumes the entire input buffer. */ +MINIZ_EXPORT tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush); + +MINIZ_EXPORT tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d); +MINIZ_EXPORT mz_uint32 tdefl_get_adler32(tdefl_compressor *d); + +/* Create tdefl_compress() flags given zlib-style compression parameters. */ +/* level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) */ +/* window_bits may be -15 (raw deflate) or 15 (zlib) */ +/* strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED */ +MINIZ_EXPORT mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy); + +#ifndef MINIZ_NO_MALLOC +/* Allocate the tdefl_compressor structure in C so that */ +/* non-C language bindings to tdefl_ API don't need to worry about */ +/* structure size and allocation mechanism. */ +MINIZ_EXPORT tdefl_compressor *tdefl_compressor_alloc(void); +MINIZ_EXPORT void tdefl_compressor_free(tdefl_compressor *pComp); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/ + #pragma once + +/* ------------------- Low-level Decompression API Definitions */ + +#ifndef MINIZ_NO_INFLATE_APIS + +#ifdef __cplusplus +extern "C" { +#endif +/* Decompression flags used by tinfl_decompress(). */ +/* TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. */ +/* TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. */ +/* TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). */ +/* TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. */ +enum +{ + TINFL_FLAG_PARSE_ZLIB_HEADER = 1, + TINFL_FLAG_HAS_MORE_INPUT = 2, + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, + TINFL_FLAG_COMPUTE_ADLER32 = 8 +}; + +/* High level decompression functions: */ +/* tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). */ +/* On entry: */ +/* pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. */ +/* On return: */ +/* Function returns a pointer to the decompressed data, or NULL on failure. */ +/* *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. */ +/* The caller must call mz_free() on the returned block when it's no longer needed. */ +MINIZ_EXPORT void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +/* tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. */ +/* Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. */ +#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) +MINIZ_EXPORT size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +/* tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. */ +/* Returns 1 on success or 0 on failure. */ +typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser); +MINIZ_EXPORT int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +struct tinfl_decompressor_tag; +typedef struct tinfl_decompressor_tag tinfl_decompressor; + +#ifndef MINIZ_NO_MALLOC +/* Allocate the tinfl_decompressor structure in C so that */ +/* non-C language bindings to tinfl_ API don't need to worry about */ +/* structure size and allocation mechanism. */ +MINIZ_EXPORT tinfl_decompressor *tinfl_decompressor_alloc(void); +MINIZ_EXPORT void tinfl_decompressor_free(tinfl_decompressor *pDecomp); +#endif + +/* Max size of LZ dictionary. */ +#define TINFL_LZ_DICT_SIZE 32768 + +/* Return status. */ +typedef enum { + /* This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data */ + /* is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly). */ + /* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */ + TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS = -4, + + /* This flag indicates that one or more of the input parameters was obviously bogus. (You can try calling it again, but if you get this error the calling code is wrong.) */ + TINFL_STATUS_BAD_PARAM = -3, + + /* This flags indicate the inflator is finished but the adler32 check of the uncompressed data didn't match. If you call it again it'll return TINFL_STATUS_DONE. */ + TINFL_STATUS_ADLER32_MISMATCH = -2, + + /* This flags indicate the inflator has somehow failed (bad code, corrupted input, etc.). If you call it again without resetting via tinfl_init() it it'll just keep on returning the same status failure code. */ + TINFL_STATUS_FAILED = -1, + + /* Any status code less than TINFL_STATUS_DONE must indicate a failure. */ + + /* This flag indicates the inflator has returned every byte of uncompressed data that it can, has consumed every byte that it needed, has successfully reached the end of the deflate stream, and */ + /* if zlib headers and adler32 checking enabled that it has successfully checked the uncompressed data's adler32. If you call it again you'll just get TINFL_STATUS_DONE over and over again. */ + TINFL_STATUS_DONE = 0, + + /* This flag indicates the inflator MUST have more input data (even 1 byte) before it can make any more forward progress, or you need to clear the TINFL_FLAG_HAS_MORE_INPUT */ + /* flag on the next call if you don't have any more source data. If the source data was somehow corrupted it's also possible (but unlikely) for the inflator to keep on demanding input to */ + /* proceed, so be sure to properly set the TINFL_FLAG_HAS_MORE_INPUT flag. */ + TINFL_STATUS_NEEDS_MORE_INPUT = 1, + + /* This flag indicates the inflator definitely has 1 or more bytes of uncompressed data available, but it cannot write this data into the output buffer. */ + /* Note if the source compressed data was corrupted it's possible for the inflator to return a lot of uncompressed data to the caller. I've been assuming you know how much uncompressed data to expect */ + /* (either exact or worst case) and will stop calling the inflator and fail after receiving too much. In pure streaming scenarios where you have no idea how many bytes to expect this may not be possible */ + /* so I may need to add some code to address this. */ + TINFL_STATUS_HAS_MORE_OUTPUT = 2 +} tinfl_status; + +/* Initializes the decompressor to its initial state. */ +#define tinfl_init(r) \ + do \ + { \ + (r)->m_state = 0; \ + } \ + MZ_MACRO_END +#define tinfl_get_adler32(r) (r)->m_check_adler32 + +/* Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. */ +/* This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. */ +MINIZ_EXPORT tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags); + +/* Internal/private bits follow. */ +enum +{ + TINFL_MAX_HUFF_TABLES = 3, + TINFL_MAX_HUFF_SYMBOLS_0 = 288, + TINFL_MAX_HUFF_SYMBOLS_1 = 32, + TINFL_MAX_HUFF_SYMBOLS_2 = 19, + TINFL_FAST_LOOKUP_BITS = 10, + TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS +}; + +#if MINIZ_HAS_64BIT_REGISTERS +#define TINFL_USE_64BIT_BITBUF 1 +#else +#define TINFL_USE_64BIT_BITBUF 0 +#endif + +#if TINFL_USE_64BIT_BITBUF +typedef mz_uint64 tinfl_bit_buf_t; +#define TINFL_BITBUF_SIZE (64) +#else +typedef mz_uint32 tinfl_bit_buf_t; +#define TINFL_BITBUF_SIZE (32) +#endif + +struct tinfl_decompressor_tag +{ + mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; + tinfl_bit_buf_t m_bit_buf; + size_t m_dist_from_out_buf_start; + mz_int16 m_look_up[TINFL_MAX_HUFF_TABLES][TINFL_FAST_LOOKUP_SIZE]; + mz_int16 m_tree_0[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; + mz_int16 m_tree_1[TINFL_MAX_HUFF_SYMBOLS_1 * 2]; + mz_int16 m_tree_2[TINFL_MAX_HUFF_SYMBOLS_2 * 2]; + mz_uint8 m_code_size_0[TINFL_MAX_HUFF_SYMBOLS_0]; + mz_uint8 m_code_size_1[TINFL_MAX_HUFF_SYMBOLS_1]; + mz_uint8 m_code_size_2[TINFL_MAX_HUFF_SYMBOLS_2]; + mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; +}; + +#ifdef __cplusplus +} +#endif + +#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ + +#pragma once + + +/* ------------------- ZIP archive reading/writing */ + +#ifndef MINIZ_NO_ARCHIVE_APIS + +#ifdef __cplusplus +extern "C" { +#endif + +enum +{ + /* Note: These enums can be reduced as needed to save memory or stack space - they are pretty conservative. */ + MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024, + MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 512, + MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 512 +}; + +typedef struct +{ + /* Central directory file index. */ + mz_uint32 m_file_index; + + /* Byte offset of this entry in the archive's central directory. Note we currently only support up to UINT_MAX or less bytes in the central dir. */ + mz_uint64 m_central_dir_ofs; + + /* These fields are copied directly from the zip's central dir. */ + mz_uint16 m_version_made_by; + mz_uint16 m_version_needed; + mz_uint16 m_bit_flag; + mz_uint16 m_method; + + /* CRC-32 of uncompressed data. */ + mz_uint32 m_crc32; + + /* File's compressed size. */ + mz_uint64 m_comp_size; + + /* File's uncompressed size. Note, I've seen some old archives where directory entries had 512 bytes for their uncompressed sizes, but when you try to unpack them you actually get 0 bytes. */ + mz_uint64 m_uncomp_size; + + /* Zip internal and external file attributes. */ + mz_uint16 m_internal_attr; + mz_uint32 m_external_attr; + + /* Entry's local header file offset in bytes. */ + mz_uint64 m_local_header_ofs; + + /* Size of comment in bytes. */ + mz_uint32 m_comment_size; + + /* MZ_TRUE if the entry appears to be a directory. */ + mz_bool m_is_directory; + + /* MZ_TRUE if the entry uses encryption/strong encryption (which miniz_zip doesn't support) */ + mz_bool m_is_encrypted; + + /* MZ_TRUE if the file is not encrypted, a patch file, and if it uses a compression method we support. */ + mz_bool m_is_supported; + + /* Filename. If string ends in '/' it's a subdirectory entry. */ + /* Guaranteed to be zero terminated, may be truncated to fit. */ + char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]; + + /* Comment field. */ + /* Guaranteed to be zero terminated, may be truncated to fit. */ + char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE]; + +#ifdef MINIZ_NO_TIME + MZ_TIME_T m_padding; +#else + MZ_TIME_T m_time; +#endif +} mz_zip_archive_file_stat; + +typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n); +typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n); +typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque); + +struct mz_zip_internal_state_tag; +typedef struct mz_zip_internal_state_tag mz_zip_internal_state; + +typedef enum { + MZ_ZIP_MODE_INVALID = 0, + MZ_ZIP_MODE_READING = 1, + MZ_ZIP_MODE_WRITING = 2, + MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3 +} mz_zip_mode; + +typedef enum { + MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100, + MZ_ZIP_FLAG_IGNORE_PATH = 0x0200, + MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400, + MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800, + MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG = 0x1000, /* if enabled, mz_zip_reader_locate_file() will be called on each file as its validated to ensure the func finds the file in the central dir (intended for testing) */ + MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = 0x2000, /* validate the local headers, but don't decompress the entire file and check the crc32 */ + MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000, /* always use the zip64 file format, instead of the original zip file format with automatic switch to zip64. Use as flags parameter with mz_zip_writer_init*_v2 */ + MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000, + MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000, + /*After adding a compressed file, seek back + to local file header and set the correct sizes*/ + MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000 +} mz_zip_flags; + +typedef enum { + MZ_ZIP_TYPE_INVALID = 0, + MZ_ZIP_TYPE_USER, + MZ_ZIP_TYPE_MEMORY, + MZ_ZIP_TYPE_HEAP, + MZ_ZIP_TYPE_FILE, + MZ_ZIP_TYPE_CFILE, + MZ_ZIP_TOTAL_TYPES +} mz_zip_type; + +/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or modify this enum. */ +typedef enum { + MZ_ZIP_NO_ERROR = 0, + MZ_ZIP_UNDEFINED_ERROR, + MZ_ZIP_TOO_MANY_FILES, + MZ_ZIP_FILE_TOO_LARGE, + MZ_ZIP_UNSUPPORTED_METHOD, + MZ_ZIP_UNSUPPORTED_ENCRYPTION, + MZ_ZIP_UNSUPPORTED_FEATURE, + MZ_ZIP_FAILED_FINDING_CENTRAL_DIR, + MZ_ZIP_NOT_AN_ARCHIVE, + MZ_ZIP_INVALID_HEADER_OR_CORRUPTED, + MZ_ZIP_UNSUPPORTED_MULTIDISK, + MZ_ZIP_DECOMPRESSION_FAILED, + MZ_ZIP_COMPRESSION_FAILED, + MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE, + MZ_ZIP_CRC_CHECK_FAILED, + MZ_ZIP_UNSUPPORTED_CDIR_SIZE, + MZ_ZIP_ALLOC_FAILED, + MZ_ZIP_FILE_OPEN_FAILED, + MZ_ZIP_FILE_CREATE_FAILED, + MZ_ZIP_FILE_WRITE_FAILED, + MZ_ZIP_FILE_READ_FAILED, + MZ_ZIP_FILE_CLOSE_FAILED, + MZ_ZIP_FILE_SEEK_FAILED, + MZ_ZIP_FILE_STAT_FAILED, + MZ_ZIP_INVALID_PARAMETER, + MZ_ZIP_INVALID_FILENAME, + MZ_ZIP_BUF_TOO_SMALL, + MZ_ZIP_INTERNAL_ERROR, + MZ_ZIP_FILE_NOT_FOUND, + MZ_ZIP_ARCHIVE_TOO_LARGE, + MZ_ZIP_VALIDATION_FAILED, + MZ_ZIP_WRITE_CALLBACK_FAILED, + MZ_ZIP_TOTAL_ERRORS +} mz_zip_error; + +typedef struct +{ + mz_uint64 m_archive_size; + mz_uint64 m_central_directory_file_ofs; + + /* We only support up to UINT32_MAX files in zip64 mode. */ + mz_uint32 m_total_files; + mz_zip_mode m_zip_mode; + mz_zip_type m_zip_type; + mz_zip_error m_last_error; + + mz_uint64 m_file_offset_alignment; + + mz_alloc_func m_pAlloc; + mz_free_func m_pFree; + mz_realloc_func m_pRealloc; + void *m_pAlloc_opaque; + + mz_file_read_func m_pRead; + mz_file_write_func m_pWrite; + mz_file_needs_keepalive m_pNeeds_keepalive; + void *m_pIO_opaque; + + mz_zip_internal_state *m_pState; + +} mz_zip_archive; + +typedef struct +{ + mz_zip_archive *pZip; + mz_uint flags; + + int status; + + mz_uint64 read_buf_size, read_buf_ofs, read_buf_avail, comp_remaining, out_buf_ofs, cur_file_ofs; + mz_zip_archive_file_stat file_stat; + void *pRead_buf; + void *pWrite_buf; + + size_t out_blk_remain; + + tinfl_decompressor inflator; + +#ifdef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS + mz_uint padding; +#else + mz_uint file_crc32; +#endif + +} mz_zip_reader_extract_iter_state; + +/* -------- ZIP reading */ + +/* Inits a ZIP archive reader. */ +/* These functions read and validate the archive's central directory. */ +MINIZ_EXPORT mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags); + +MINIZ_EXPORT mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags); + +#ifndef MINIZ_NO_STDIO +/* Read a archive from a disk file. */ +/* file_start_ofs is the file offset where the archive actually begins, or 0. */ +/* actual_archive_size is the true total size of the archive, which may be smaller than the file's actual size on disk. If zero the entire file is treated as the archive. */ +MINIZ_EXPORT mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags); +MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size); + +/* Read an archive from an already opened FILE, beginning at the current file position. */ +/* The archive is assumed to be archive_size bytes long. If archive_size is 0, then the entire rest of the file is assumed to contain the archive. */ +/* The FILE will NOT be closed when mz_zip_reader_end() is called. */ +MINIZ_EXPORT mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags); +#endif + +/* Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. */ +MINIZ_EXPORT mz_bool mz_zip_reader_end(mz_zip_archive *pZip); + +/* -------- ZIP reading or writing */ + +/* Clears a mz_zip_archive struct to all zeros. */ +/* Important: This must be done before passing the struct to any mz_zip functions. */ +MINIZ_EXPORT void mz_zip_zero_struct(mz_zip_archive *pZip); + +MINIZ_EXPORT mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip); +MINIZ_EXPORT mz_zip_type mz_zip_get_type(mz_zip_archive *pZip); + +/* Returns the total number of files in the archive. */ +MINIZ_EXPORT mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip); + +MINIZ_EXPORT mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip); +MINIZ_EXPORT mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip); +MINIZ_EXPORT MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip); + +/* Reads n bytes of raw archive data, starting at file offset file_ofs, to pBuf. */ +MINIZ_EXPORT size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n); + +/* All mz_zip funcs set the m_last_error field in the mz_zip_archive struct. These functions retrieve/manipulate this field. */ +/* Note that the m_last_error functionality is not thread safe. */ +MINIZ_EXPORT mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num); +MINIZ_EXPORT mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip); +MINIZ_EXPORT mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip); +MINIZ_EXPORT mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip); +MINIZ_EXPORT const char *mz_zip_get_error_string(mz_zip_error mz_err); + +/* MZ_TRUE if the archive file entry is a directory entry. */ +MINIZ_EXPORT mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index); + +/* MZ_TRUE if the file is encrypted/strong encrypted. */ +MINIZ_EXPORT mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index); + +/* MZ_TRUE if the compression method is supported, and the file is not encrypted, and the file is not a compressed patch file. */ +MINIZ_EXPORT mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index); + +/* Retrieves the filename of an archive file entry. */ +/* Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. */ +MINIZ_EXPORT mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size); + +/* Attempts to locates a file in the archive's central directory. */ +/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */ +/* Returns -1 if the file cannot be found. */ +MINIZ_EXPORT int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); +MINIZ_EXPORT mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *file_index); + +/* Returns detailed information about an archive file entry. */ +MINIZ_EXPORT mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat); + +/* MZ_TRUE if the file is in zip64 format. */ +/* A file is considered zip64 if it contained a zip64 end of central directory marker, or if it contained any zip64 extended file information fields in the central directory. */ +MINIZ_EXPORT mz_bool mz_zip_is_zip64(mz_zip_archive *pZip); + +/* Returns the total central directory size in bytes. */ +/* The current max supported size is <= MZ_UINT32_MAX. */ +MINIZ_EXPORT size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip); + +/* Extracts a archive file to a memory buffer using no memory allocation. */ +/* There must be at least enough room on the stack to store the inflator's state (~34KB or so). */ +MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); +MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); + +/* Extracts a archive file to a memory buffer. */ +MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags); +MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags); + +/* Extracts a archive file to a dynamically allocated heap buffer. */ +/* The memory will be allocated via the mz_zip_archive's alloc/realloc functions. */ +/* Returns NULL and sets the last error on failure. */ +MINIZ_EXPORT void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags); +MINIZ_EXPORT void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags); + +/* Extracts a archive file using a callback function to output the file's data. */ +MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags); +MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags); + +/* Extract a file iteratively */ +MINIZ_EXPORT mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); +MINIZ_EXPORT mz_zip_reader_extract_iter_state* mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags); +MINIZ_EXPORT size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState, void* pvBuf, size_t buf_size); +MINIZ_EXPORT mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state* pState); + +#ifndef MINIZ_NO_STDIO +/* Extracts a archive file to a disk file and sets its last accessed and modified times. */ +/* This function only extracts files, not archive directory records. */ +MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags); +MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags); + +/* Extracts a archive file starting at the current position in the destination FILE stream. */ +MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *File, mz_uint flags); +MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags); +#endif + +#if 0 +/* TODO */ + typedef void *mz_zip_streaming_extract_state_ptr; + mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); + mz_uint64 mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); + mz_uint64 mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); + mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, mz_uint64 new_ofs); + size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size); + mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); +#endif + +/* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */ +/* It also validates that each file can be successfully uncompressed unless the MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY is specified. */ +MINIZ_EXPORT mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); + +/* Validates an entire archive by calling mz_zip_validate_file() on each file. */ +MINIZ_EXPORT mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags); + +/* Misc utils/helpers, valid for ZIP reading or writing */ +MINIZ_EXPORT mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr); +#ifndef MINIZ_NO_STDIO +MINIZ_EXPORT mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr); +#endif + +/* Universal end function - calls either mz_zip_reader_end() or mz_zip_writer_end(). */ +MINIZ_EXPORT mz_bool mz_zip_end(mz_zip_archive *pZip); + +/* -------- ZIP writing */ + +#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS + +/* Inits a ZIP archive writer. */ +/*Set pZip->m_pWrite (and pZip->m_pIO_opaque) before calling mz_zip_writer_init or mz_zip_writer_init_v2*/ +/*The output is streamable, i.e. file_ofs in mz_file_write_func always increases only by n*/ +MINIZ_EXPORT mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size); +MINIZ_EXPORT mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags); + +MINIZ_EXPORT mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size); +MINIZ_EXPORT mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags); + +#ifndef MINIZ_NO_STDIO +MINIZ_EXPORT mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning); +MINIZ_EXPORT mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags); +MINIZ_EXPORT mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags); +#endif + +/* Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. */ +/* For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called. */ +/* For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it). */ +/* Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. */ +/* Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before */ +/* the archive is finalized the file's central directory will be hosed. */ +MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename); +MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags); + +/* Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. */ +/* To add a directory entry, call this method with an archive name ending in a forwardslash with an empty buffer. */ +/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */ +MINIZ_EXPORT mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags); + +/* Like mz_zip_writer_add_mem(), except you can specify a file comment field, and optionally supply the function with already compressed data. */ +/* uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA flag is specified. */ +MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, + mz_uint64 uncomp_size, mz_uint32 uncomp_crc32); + +MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, + mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified, const char *user_extra_data_local, mz_uint user_extra_data_local_len, + const char *user_extra_data_central, mz_uint user_extra_data_central_len); + +/* Adds the contents of a file to an archive. This function also records the disk file's modified time into the archive. */ +/* File data is supplied via a read callback function. User mz_zip_writer_add_(c)file to add a file directly.*/ +MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size, + const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len, + const char *user_extra_data_central, mz_uint user_extra_data_central_len); + + +#ifndef MINIZ_NO_STDIO +/* Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. */ +/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */ +MINIZ_EXPORT mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); + +/* Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. */ +MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, + const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len, + const char *user_extra_data_central, mz_uint user_extra_data_central_len); +#endif + +/* Adds a file to an archive by fully cloning the data from another archive. */ +/* This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data (it may add or modify the zip64 local header extra data field), and the optional descriptor following the compressed data. */ +MINIZ_EXPORT mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index); + +/* Finalizes the archive by writing the central directory records followed by the end of central directory record. */ +/* After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). */ +/* An archive must be manually finalized by calling this function for it to be valid. */ +MINIZ_EXPORT mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip); + +/* Finalizes a heap archive, returning a pointer to the heap block and its size. */ +/* The heap block will be allocated using the mz_zip_archive's alloc/realloc callbacks. */ +MINIZ_EXPORT mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize); + +/* Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. */ +/* Note for the archive to be valid, it *must* have been finalized before ending (this function will not do it for you). */ +MINIZ_EXPORT mz_bool mz_zip_writer_end(mz_zip_archive *pZip); + +/* -------- Misc. high-level helper functions: */ + +/* mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive. */ +/* Note this is NOT a fully safe operation. If it crashes or dies in some way your archive can be left in a screwed up state (without a central directory). */ +/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */ +/* TODO: Perhaps add an option to leave the existing central dir in place in case the add dies? We could then truncate the file (so the old central dir would be at the end) if something goes wrong. */ +MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); +MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr); + +#ifndef MINIZ_NO_STDIO +/* Reads a single file from an archive into a heap block. */ +/* If pComment is not NULL, only the file with the specified comment will be extracted. */ +/* Returns NULL on failure. */ +MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags); +MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr); +#endif + +#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */ + +#ifdef __cplusplus +} +#endif + +#endif /* MINIZ_NO_ARCHIVE_APIS */ diff --git a/libraries/zlib/CMakeLists.txt b/libraries/zlib/CMakeLists.txt deleted file mode 100644 index 22c2d5117..000000000 --- a/libraries/zlib/CMakeLists.txt +++ /dev/null @@ -1,196 +0,0 @@ -set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) - -make_release_only() - -project(zlib C) - -set(VERSION "1.2.7") - -if(NOT DEFINED BUILD_SHARED_LIBS) - option(BUILD_SHARED_LIBS "Build a shared library form of zlib" OFF) -endif() - -set(ZLIBNAME z) - -include(CheckTypeSize) -include(CheckFunctionExists) -include(CheckIncludeFile) -include(CheckCSourceCompiles) -enable_testing() - -check_include_file(sys/types.h HAVE_SYS_TYPES_H) -check_include_file(stdint.h HAVE_STDINT_H) -check_include_file(stddef.h HAVE_STDDEF_H) - -# -# Check to see if we have large file support -# -set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) -# We add these other definitions here because CheckTypeSize.cmake -# in CMake 2.4.x does not automatically do so and we want -# compatibility with CMake 2.4.x. -if(HAVE_SYS_TYPES_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) -endif() -if(HAVE_STDINT_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) -endif() -if(HAVE_STDDEF_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) -endif() -check_type_size(off64_t OFF64_T) -if(HAVE_OFF64_T) - add_definitions(-D_LARGEFILE64_SOURCE=1) -endif() -set(CMAKE_REQUIRED_DEFINITIONS) # clear variable - -# -# Check for fseeko -# -check_function_exists(fseeko HAVE_FSEEKO) -if(NOT HAVE_FSEEKO) - add_definitions(-DNO_FSEEKO) -endif() - -# -# Check for unistd.h -# -check_include_file(unistd.h Z_HAVE_UNISTD_H) - -if(MSVC) - set(CMAKE_DEBUG_POSTFIX "d") - add_definitions(-D_CRT_SECURE_NO_DEPRECATE) - add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -endif() - -#if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) -# # If we're doing an out of source build and the user has a zconf.h -# # in their source tree... -# if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) -# message(FATAL_ERROR -# "You must remove ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h " -# "from the source tree. This file is included with zlib " -# "but CMake generates this file for you automatically " -# "in the build directory.") -# endif() -#endif() -# -#configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein -# ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) -#include_directories(${CMAKE_CURRENT_BINARY_DIR}) - - -#============================================================================ -# zlib -#============================================================================ - -set(ZLIB_PUBLIC_HDRS - zconf.h - zlib.h -) -set(ZLIB_PRIVATE_HDRS - crc32.h - deflate.h - gzguts.h - inffast.h - inffixed.h - inflate.h - inftrees.h - trees.h - zutil.h -) -set(ZLIB_SRCS - adler32.c - compress.c - crc32.c - deflate.c -# gzclose.c -# gzlib.c -# gzread.c -# gzwrite.c - inflate.c - infback.c - inftrees.c - inffast.c - trees.c - uncompr.c - zutil.c -# win32/zlib1.rc -) - -# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) -string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([0-9A-Za-z.]+)\".*" - "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) - -if(MINGW) - # This gets us DLL resource information when compiling on MinGW. - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - COMMAND windres.exe - -D GCC_WINDRES - -I ${CMAKE_CURRENT_SOURCE_DIR} - -I ${CMAKE_CURRENT_BINARY_DIR} - -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) - set(ZLIB_SRCS ${ZLIB_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) -endif() - -add_library(${ZLIBNAME} STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -set_target_properties(${ZLIBNAME} PROPERTIES DEFINE_SYMBOL ZLIB_DLL) - -set_target_properties(${ZLIBNAME} PROPERTIES SOVERSION 1) - -if(NOT CYGWIN) - # This property causes shared libraries on Linux to have the full version - # encoded into their final filename. We disable this on Cygwin because - # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll - # seems to be the default. - # - # This has no effect with MSVC, on that platform the version info for - # the DLL comes from the resource file win32/zlib1.rc - set_target_properties(${ZLIBNAME} PROPERTIES VERSION ${ZLIB_FULL_VERSION}) -endif() - -if(BUILD_SHARED_LIBS AND WIN32) - # Creates zlib1.dll when building shared library version - set_target_properties(${ZLIBNAME} PROPERTIES SUFFIX "1.dll") -else() - # On unix-like platforms the library is almost always called libz - set_target_properties(${ZLIBNAME} PROPERTIES OUTPUT_NAME z) -endif() - -if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) - install(TARGETS ${ZLIBNAME} - RUNTIME DESTINATION bin - ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib ) -endif() -if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) - install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION include) -endif() -if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) - install(FILES zlib.3 DESTINATION share/man/man3) -endif() - -#============================================================================ -# Example binaries -#============================================================================ - -#add_executable(example example.c) -#target_link_libraries(example ${ZLIBNAME}) -#add_test(example example) - -#add_executable(minigzip minigzip.c) -#target_link_libraries(minigzip ${ZLIBNAME}) - -#if(HAVE_OFF64_T) -# add_executable(example64 example.c) -# target_link_libraries(example64 ${ZLIBNAME}) -# set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") -# add_test(example64 example64) -# -# add_executable(minigzip64 minigzip.c) -# target_link_libraries(minigzip64 ${ZLIBNAME}) -# set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") -#endif() diff --git a/libraries/zlib/ChangeLog b/libraries/zlib/ChangeLog deleted file mode 100644 index 8707988ac..000000000 --- a/libraries/zlib/ChangeLog +++ /dev/null @@ -1,1608 +0,0 @@ - - ChangeLog file for zlib - -Changes in 1.3 (18 Aug 2023) -- Remove K&R function definitions and zlib2ansi -- Fix bug in deflateBound() for level 0 and memLevel 9 -- Fix bug when gzungetc() is used immediately after gzopen() -- Fix bug when using gzflush() with a very small buffer -- Fix crash when gzsetparams() attempted for transparent write -- Fix test/example.c to work with FORCE_STORED -- Rewrite of zran in examples (see zran.c version history) -- Fix minizip to allow it to open an empty zip file -- Fix reading disk number start on zip64 files in minizip -- Fix logic error in minizip argument processing -- Add minizip testing to Makefile -- Read multiple bytes instead of byte-by-byte in minizip unzip.c -- Add memory sanitizer to configure (--memory) -- Various portability improvements -- Various documentation improvements -- Various spelling and typo corrections - -Changes in 1.2.13 (13 Oct 2022) -- Fix configure issue that discarded provided CC definition -- Correct incorrect inputs provided to the CRC functions -- Repair prototypes and exporting of new CRC functions -- Fix inflateBack to detect invalid input with distances too far -- Have infback() deliver all of the available output up to any error -- Fix a bug when getting a gzip header extra field with inflate() -- Fix bug in block type selection when Z_FIXED used -- Tighten deflateBound bounds -- Remove deleted assembler code references -- Various portability and appearance improvements - -Changes in 1.2.12 (27 Mar 2022) -- Cygwin does not have _wopen(), so do not create gzopen_w() there -- Permit a deflateParams() parameter change as soon as possible -- Limit hash table inserts after switch from stored deflate -- Fix bug when window full in deflate_stored() -- Fix CLEAR_HASH macro to be usable as a single statement -- Avoid a conversion error in gzseek when off_t type too small -- Have Makefile return non-zero error code on test failure -- Avoid some conversion warnings in gzread.c and gzwrite.c -- Update use of errno for newer Windows CE versions -- Small speedup to inflate [psumbera] -- Return an error if the gzputs string length can't fit in an int -- Add address checking in clang to -w option of configure -- Don't compute check value for raw inflate if asked to validate -- Handle case where inflateSync used when header never processed -- Avoid the use of ptrdiff_t -- Avoid an undefined behavior of memcpy() in gzappend() -- Avoid undefined behaviors of memcpy() in gz*printf() -- Avoid an undefined behavior of memcpy() in _tr_stored_block() -- Make the names in functions declarations identical to definitions -- Remove old assembler code in which bugs have manifested -- Fix deflateEnd() to not report an error at start of raw deflate -- Add legal disclaimer to README -- Emphasize the need to continue decompressing gzip members -- Correct the initialization requirements for deflateInit2() -- Fix a bug that can crash deflate on some input when using Z_FIXED -- Assure that the number of bits for deflatePrime() is valid -- Use a structure to make globals in enough.c evident -- Use a macro for the printf format of big_t in enough.c -- Clean up code style in enough.c, update version -- Use inline function instead of macro for index in enough.c -- Clarify that prefix codes are counted in enough.c -- Show all the codes for the maximum tables size in enough.c -- Add gznorm.c example, which normalizes gzip files -- Fix the zran.c example to work on a multiple-member gzip file -- Add tables for crc32_combine(), to speed it up by a factor of 200 -- Add crc32_combine_gen() and crc32_combine_op() for fast combines -- Speed up software CRC-32 computation by a factor of 1.5 to 3 -- Use atomic test and set, if available, for dynamic CRC tables -- Don't bother computing check value after successful inflateSync() -- Correct comment in crc32.c -- Add use of the ARMv8 crc32 instructions when requested -- Use ARM crc32 instructions if the ARM architecture has them -- Explicitly note that the 32-bit check values are 32 bits -- Avoid adding empty gzip member after gzflush with Z_FINISH -- Fix memory leak on error in gzlog.c -- Fix error in comment on the polynomial representation of a byte -- Clarify gz* function interfaces, referring to parameter names -- Change macro name in inflate.c to avoid collision in VxWorks -- Correct typo in blast.c -- Improve portability of contrib/minizip -- Fix indentation in minizip's zip.c -- Replace black/white with allow/block. (theresa-m) -- minizip warning fix if MAXU32 already defined. (gvollant) -- Fix unztell64() in minizip to work past 4GB. (Daniël Hörchner) -- Clean up minizip to reduce warnings for testing -- Add fallthrough comments for gcc -- Eliminate use of ULL constants -- Separate out address sanitizing from warnings in configure -- Remove destructive aspects of make distclean -- Check for cc masquerading as gcc or clang in configure -- Fix crc32.c to compile local functions only if used - -Changes in 1.2.11 (15 Jan 2017) -- Fix deflate stored bug when pulling last block from window -- Permit immediate deflateParams changes before any deflate input - -Changes in 1.2.10 (2 Jan 2017) -- Avoid warnings on snprintf() return value -- Fix bug in deflate_stored() for zero-length input -- Fix bug in gzwrite.c that produced corrupt gzip files -- Remove files to be installed before copying them in Makefile.in -- Add warnings when compiling with assembler code - -Changes in 1.2.9 (31 Dec 2016) -- Fix contrib/minizip to permit unzipping with desktop API [Zouzou] -- Improve contrib/blast to return unused bytes -- Assure that gzoffset() is correct when appending -- Improve compress() and uncompress() to support large lengths -- Fix bug in test/example.c where error code not saved -- Remedy Coverity warning [Randers-Pehrson] -- Improve speed of gzprintf() in transparent mode -- Fix inflateInit2() bug when windowBits is 16 or 32 -- Change DEBUG macro to ZLIB_DEBUG -- Avoid uninitialized access by gzclose_w() -- Allow building zlib outside of the source directory -- Fix bug that accepted invalid zlib header when windowBits is zero -- Fix gzseek() problem on MinGW due to buggy _lseeki64 there -- Loop on write() calls in gzwrite.c in case of non-blocking I/O -- Add --warn (-w) option to ./configure for more compiler warnings -- Reject a window size of 256 bytes if not using the zlib wrapper -- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE -- Add --debug (-d) option to ./configure to define ZLIB_DEBUG -- Fix bugs in creating a very large gzip header -- Add uncompress2() function, which returns the input size used -- Assure that deflateParams() will not switch functions mid-block -- Dramatically speed up deflation for level 0 (storing) -- Add gzfread(), duplicating the interface of fread() -- Add gzfwrite(), duplicating the interface of fwrite() -- Add deflateGetDictionary() function -- Use snprintf() for later versions of Microsoft C -- Fix *Init macros to use z_ prefix when requested -- Replace as400 with os400 for OS/400 support [Monnerat] -- Add crc32_z() and adler32_z() functions with size_t lengths -- Update Visual Studio project files [AraHaan] - -Changes in 1.2.8 (28 Apr 2013) -- Update contrib/minizip/iowin32.c for Windows RT [Vollant] -- Do not force Z_CONST for C++ -- Clean up contrib/vstudio [Roß] -- Correct spelling error in zlib.h -- Fix mixed line endings in contrib/vstudio - -Changes in 1.2.7.3 (13 Apr 2013) -- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc - -Changes in 1.2.7.2 (13 Apr 2013) -- Change check for a four-byte type back to hexadecimal -- Fix typo in win32/Makefile.msc -- Add casts in gzwrite.c for pointer differences - -Changes in 1.2.7.1 (24 Mar 2013) -- Replace use of unsafe string functions with snprintf if available -- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] -- Fix gzgetc undefine when Z_PREFIX set [Turk] -- Eliminate use of mktemp in Makefile (not always available) -- Fix bug in 'F' mode for gzopen() -- Add inflateGetDictionary() function -- Correct comment in deflate.h -- Use _snprintf for snprintf in Microsoft C -- On Darwin, only use /usr/bin/libtool if libtool is not Apple -- Delete "--version" file if created by "ar --version" [Richard G.] -- Fix configure check for veracity of compiler error return codes -- Fix CMake compilation of static lib for MSVC2010 x64 -- Remove unused variable in infback9.c -- Fix argument checks in gzlog_compress() and gzlog_write() -- Clean up the usage of z_const and respect const usage within zlib -- Clean up examples/gzlog.[ch] comparisons of different types -- Avoid shift equal to bits in type (caused endless loop) -- Fix uninitialized value bug in gzputc() introduced by const patches -- Fix memory allocation error in examples/zran.c [Nor] -- Fix bug where gzopen(), gzclose() would write an empty file -- Fix bug in gzclose() when gzwrite() runs out of memory -- Check for input buffer malloc failure in examples/gzappend.c -- Add note to contrib/blast to use binary mode in stdio -- Fix comparisons of differently signed integers in contrib/blast -- Check for invalid code length codes in contrib/puff -- Fix serious but very rare decompression bug in inftrees.c -- Update inflateBack() comments, since inflate() can be faster -- Use underscored I/O function names for WINAPI_FAMILY -- Add _tr_flush_bits to the external symbols prefixed by --zprefix -- Add contrib/vstudio/vc10 pre-build step for static only -- Quote --version-script argument in CMakeLists.txt -- Don't specify --version-script on Apple platforms in CMakeLists.txt -- Fix casting error in contrib/testzlib/testzlib.c -- Fix types in contrib/minizip to match result of get_crc_table() -- Simplify contrib/vstudio/vc10 with 'd' suffix -- Add TOP support to win32/Makefile.msc -- Support i686 and amd64 assembler builds in CMakeLists.txt -- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h -- Add vc11 and vc12 build files to contrib/vstudio -- Add gzvprintf() as an undocumented function in zlib -- Fix configure for Sun shell -- Remove runtime check in configure for four-byte integer type -- Add casts and consts to ease user conversion to C++ -- Add man pages for minizip and miniunzip -- In Makefile uninstall, don't rm if preceding cd fails -- Do not return Z_BUF_ERROR if deflateParam() has nothing to write - -Changes in 1.2.7 (2 May 2012) -- Replace use of memmove() with a simple copy for portability -- Test for existence of strerror -- Restore gzgetc_ for backward compatibility with 1.2.6 -- Fix build with non-GNU make on Solaris -- Require gcc 4.0 or later on Mac OS X to use the hidden attribute -- Include unistd.h for Watcom C -- Use __WATCOMC__ instead of __WATCOM__ -- Do not use the visibility attribute if NO_VIZ defined -- Improve the detection of no hidden visibility attribute -- Avoid using __int64 for gcc or solo compilation -- Cast to char * in gzprintf to avoid warnings [Zinser] -- Fix make_vms.com for VAX [Zinser] -- Don't use library or built-in byte swaps -- Simplify test and use of gcc hidden attribute -- Fix bug in gzclose_w() when gzwrite() fails to allocate memory -- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() -- Fix bug in test/minigzip.c for configure --solo -- Fix contrib/vstudio project link errors [Mohanathas] -- Add ability to choose the builder in make_vms.com [Schweda] -- Add DESTDIR support to mingw32 win32/Makefile.gcc -- Fix comments in win32/Makefile.gcc for proper usage -- Allow overriding the default install locations for cmake -- Generate and install the pkg-config file with cmake -- Build both a static and a shared version of zlib with cmake -- Include version symbols for cmake builds -- If using cmake with MSVC, add the source directory to the includes -- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] -- Move obsolete emx makefile to old [Truta] -- Allow the use of -Wundef when compiling or using zlib -- Avoid the use of the -u option with mktemp -- Improve inflate() documentation on the use of Z_FINISH -- Recognize clang as gcc -- Add gzopen_w() in Windows for wide character path names -- Rename zconf.h in CMakeLists.txt to move it out of the way -- Add source directory in CMakeLists.txt for building examples -- Look in build directory for zlib.pc in CMakeLists.txt -- Remove gzflags from zlibvc.def in vc9 and vc10 -- Fix contrib/minizip compilation in the MinGW environment -- Update ./configure for Solaris, support --64 [Mooney] -- Remove -R. from Solaris shared build (possible security issue) -- Avoid race condition for parallel make (-j) running example -- Fix type mismatch between get_crc_table() and crc_table -- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] -- Fix the path to zlib.map in CMakeLists.txt -- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] -- Add instructions to win32/Makefile.gcc for shared install [Torri] - -Changes in 1.2.6.1 (12 Feb 2012) -- Avoid the use of the Objective-C reserved name "id" -- Include io.h in gzguts.h for Microsoft compilers -- Fix problem with ./configure --prefix and gzgetc macro -- Include gz_header definition when compiling zlib solo -- Put gzflags() functionality back in zutil.c -- Avoid library header include in crc32.c for Z_SOLO -- Use name in GCC_CLASSIC as C compiler for coverage testing, if set -- Minor cleanup in contrib/minizip/zip.c [Vollant] -- Update make_vms.com [Zinser] -- Remove unnecessary gzgetc_ function -- Use optimized byte swap operations for Microsoft and GNU [Snyder] -- Fix minor typo in zlib.h comments [Rzesniowiecki] - -Changes in 1.2.6 (29 Jan 2012) -- Update the Pascal interface in contrib/pascal -- Fix function numbers for gzgetc_ in zlibvc.def files -- Fix configure.ac for contrib/minizip [Schiffer] -- Fix large-entry detection in minizip on 64-bit systems [Schiffer] -- Have ./configure use the compiler return code for error indication -- Fix CMakeLists.txt for cross compilation [McClure] -- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] -- Fix compilation of contrib/minizip on FreeBSD [Marquez] -- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] -- Include io.h for Turbo C / Borland C on all platforms [Truta] -- Make version explicit in contrib/minizip/configure.ac [Bosmans] -- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] -- Minor cleanup up contrib/minizip/unzip.c [Vollant] -- Fix bug when compiling minizip with C++ [Vollant] -- Protect for long name and extra fields in contrib/minizip [Vollant] -- Avoid some warnings in contrib/minizip [Vollant] -- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip -- Add missing libs to minizip linker command -- Add support for VPATH builds in contrib/minizip -- Add an --enable-demos option to contrib/minizip/configure -- Add the generation of configure.log by ./configure -- Exit when required parameters not provided to win32/Makefile.gcc -- Have gzputc return the character written instead of the argument -- Use the -m option on ldconfig for BSD systems [Tobias] -- Correct in zlib.map when deflateResetKeep was added - -Changes in 1.2.5.3 (15 Jan 2012) -- Restore gzgetc function for binary compatibility -- Do not use _lseeki64 under Borland C++ [Truta] -- Update win32/Makefile.msc to build test/*.c [Truta] -- Remove old/visualc6 given CMakefile and other alternatives -- Update AS400 build files and documentation [Monnerat] -- Update win32/Makefile.gcc to build test/*.c [Truta] -- Permit stronger flushes after Z_BLOCK flushes -- Avoid extraneous empty blocks when doing empty flushes -- Permit Z_NULL arguments to deflatePending -- Allow deflatePrime() to insert bits in the middle of a stream -- Remove second empty static block for Z_PARTIAL_FLUSH -- Write out all of the available bits when using Z_BLOCK -- Insert the first two strings in the hash table after a flush - -Changes in 1.2.5.2 (17 Dec 2011) -- fix ld error: unable to find version dependency 'ZLIB_1.2.5' -- use relative symlinks for shared libs -- Avoid searching past window for Z_RLE strategy -- Assure that high-water mark initialization is always applied in deflate -- Add assertions to fill_window() in deflate.c to match comments -- Update python link in README -- Correct spelling error in gzread.c -- Fix bug in gzgets() for a concatenated empty gzip stream -- Correct error in comment for gz_make() -- Change gzread() and related to ignore junk after gzip streams -- Allow gzread() and related to continue after gzclearerr() -- Allow gzrewind() and gzseek() after a premature end-of-file -- Simplify gzseek() now that raw after gzip is ignored -- Change gzgetc() to a macro for speed (~40% speedup in testing) -- Fix gzclose() to return the actual error last encountered -- Always add large file support for windows -- Include zconf.h for windows large file support -- Include zconf.h.cmakein for windows large file support -- Update zconf.h.cmakein on make distclean -- Merge vestigial vsnprintf determination from zutil.h to gzguts.h -- Clarify how gzopen() appends in zlib.h comments -- Correct documentation of gzdirect() since junk at end now ignored -- Add a transparent write mode to gzopen() when 'T' is in the mode -- Update python link in zlib man page -- Get inffixed.h and MAKEFIXED result to match -- Add a ./config --solo option to make zlib subset with no library use -- Add undocumented inflateResetKeep() function for CAB file decoding -- Add --cover option to ./configure for gcc coverage testing -- Add #define ZLIB_CONST option to use const in the z_stream interface -- Add comment to gzdopen() in zlib.h to use dup() when using fileno() -- Note behavior of uncompress() to provide as much data as it can -- Add files in contrib/minizip to aid in building libminizip -- Split off AR options in Makefile.in and configure -- Change ON macro to Z_ARG to avoid application conflicts -- Facilitate compilation with Borland C++ for pragmas and vsnprintf -- Include io.h for Turbo C / Borland C++ -- Move example.c and minigzip.c to test/ -- Simplify incomplete code table filling in inflate_table() -- Remove code from inflate.c and infback.c that is impossible to execute -- Test the inflate code with full coverage -- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) -- Add deflateResetKeep and fix inflateResetKeep to retain dictionary -- Fix gzwrite.c to accommodate reduced memory zlib compilation -- Have inflate() with Z_FINISH avoid the allocation of a window -- Do not set strm->adler when doing raw inflate -- Fix gzeof() to behave just like feof() when read is not past end of file -- Fix bug in gzread.c when end-of-file is reached -- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF -- Document gzread() capability to read concurrently written files -- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] - -Changes in 1.2.5.1 (10 Sep 2011) -- Update FAQ entry on shared builds (#13) -- Avoid symbolic argument to chmod in Makefile.in -- Fix bug and add consts in contrib/puff [Oberhumer] -- Update contrib/puff/zeros.raw test file to have all block types -- Add full coverage test for puff in contrib/puff/Makefile -- Fix static-only-build install in Makefile.in -- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] -- Add libz.a dependency to shared in Makefile.in for parallel builds -- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out -- Replace $(...) with `...` in configure for non-bash sh [Bowler] -- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] -- Add solaris* to Linux* in configure to allow gcc use [Groffen] -- Add *bsd* to Linux* case in configure [Bar-Lev] -- Add inffast.obj to dependencies in win32/Makefile.msc -- Correct spelling error in deflate.h [Kohler] -- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc -- Add test to configure for GNU C looking for gcc in output of $cc -v -- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] -- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not -- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense -- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) -- Make stronger test in zconf.h to include unistd.h for LFS -- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] -- Fix zlib.h LFS support when Z_PREFIX used -- Add updated as400 support (removed from old) [Monnerat] -- Avoid deflate sensitivity to volatile input data -- Avoid division in adler32_combine for NO_DIVIDE -- Clarify the use of Z_FINISH with deflateBound() amount of space -- Set binary for output file in puff.c -- Use u4 type for crc_table to avoid conversion warnings -- Apply casts in zlib.h to avoid conversion warnings -- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] -- Improve inflateSync() documentation to note indeterminacy -- Add deflatePending() function to return the amount of pending output -- Correct the spelling of "specification" in FAQ [Randers-Pehrson] -- Add a check in configure for stdarg.h, use for gzprintf() -- Check that pointers fit in ints when gzprint() compiled old style -- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] -- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] -- Add debug records in assembler code [Londer] -- Update RFC references to use http://tools.ietf.org/html/... [Li] -- Add --archs option, use of libtool to configure for Mac OS X [Borstel] - -Changes in 1.2.5 (19 Apr 2010) -- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] -- Default to libdir as sharedlibdir in configure [Nieder] -- Update copyright dates on modified source files -- Update trees.c to be able to generate modified trees.h -- Exit configure for MinGW, suggesting win32/Makefile.gcc -- Check for NULL path in gz_open [Homurlu] - -Changes in 1.2.4.5 (18 Apr 2010) -- Set sharedlibdir in configure [Torok] -- Set LDFLAGS in Makefile.in [Bar-Lev] -- Avoid mkdir objs race condition in Makefile.in [Bowler] -- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays -- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C -- Don't use hidden attribute when it is a warning generator (e.g. Solaris) - -Changes in 1.2.4.4 (18 Apr 2010) -- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] -- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty -- Try to use bash or ksh regardless of functionality of /bin/sh -- Fix configure incompatibility with NetBSD sh -- Remove attempt to run under bash or ksh since have better NetBSD fix -- Fix win32/Makefile.gcc for MinGW [Bar-Lev] -- Add diagnostic messages when using CROSS_PREFIX in configure -- Added --sharedlibdir option to configure [Weigelt] -- Use hidden visibility attribute when available [Frysinger] - -Changes in 1.2.4.3 (10 Apr 2010) -- Only use CROSS_PREFIX in configure for ar and ranlib if they exist -- Use CROSS_PREFIX for nm [Bar-Lev] -- Assume _LARGEFILE64_SOURCE defined is equivalent to true -- Avoid use of undefined symbols in #if with && and || -- Make *64 prototypes in gzguts.h consistent with functions -- Add -shared load option for MinGW in configure [Bowler] -- Move z_off64_t to public interface, use instead of off64_t -- Remove ! from shell test in configure (not portable to Solaris) -- Change +0 macro tests to -0 for possibly increased portability - -Changes in 1.2.4.2 (9 Apr 2010) -- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 -- Really provide prototypes for *64 functions when building without LFS -- Only define unlink() in minigzip.c if unistd.h not included -- Update README to point to contrib/vstudio project files -- Move projects/vc6 to old/ and remove projects/ -- Include stdlib.h in minigzip.c for setmode() definition under WinCE -- Clean up assembler builds in win32/Makefile.msc [Rowe] -- Include sys/types.h for Microsoft for off_t definition -- Fix memory leak on error in gz_open() -- Symbolize nm as $NM in configure [Weigelt] -- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] -- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined -- Fix bug in gzeof() to take into account unused input data -- Avoid initialization of structures with variables in puff.c -- Updated win32/README-WIN32.txt [Rowe] - -Changes in 1.2.4.1 (28 Mar 2010) -- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] -- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] -- Restore "for debugging" comment on sprintf() in gzlib.c -- Remove fdopen for MVS from gzguts.h -- Put new README-WIN32.txt in win32 [Rowe] -- Add check for shell to configure and invoke another shell if needed -- Fix big fat stinking bug in gzseek() on uncompressed files -- Remove vestigial F_OPEN64 define in zutil.h -- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE -- Avoid errors on non-LFS systems when applications define LFS macros -- Set EXE to ".exe" in configure for MINGW [Kahle] -- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] -- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] -- Add DLL install in win32/makefile.gcc [Bar-Lev] -- Allow Linux* or linux* from uname in configure [Bar-Lev] -- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] -- Add cross-compilation prefixes to configure [Bar-Lev] -- Match type exactly in gz_load() invocation in gzread.c -- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func -- Provide prototypes for *64 functions when building zlib without LFS -- Don't use -lc when linking shared library on MinGW -- Remove errno.h check in configure and vestigial errno code in zutil.h - -Changes in 1.2.4 (14 Mar 2010) -- Fix VER3 extraction in configure for no fourth subversion -- Update zlib.3, add docs to Makefile.in to make .pdf out of it -- Add zlib.3.pdf to distribution -- Don't set error code in gzerror() if passed pointer is NULL -- Apply destination directory fixes to CMakeLists.txt [Lowman] -- Move #cmakedefine's to a new zconf.in.cmakein -- Restore zconf.h for builds that don't use configure or cmake -- Add distclean to dummy Makefile for convenience -- Update and improve INDEX, README, and FAQ -- Update CMakeLists.txt for the return of zconf.h [Lowman] -- Update contrib/vstudio/vc9 and vc10 [Vollant] -- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc -- Apply license and readme changes to contrib/asm686 [Raiter] -- Check file name lengths and add -c option in minigzip.c [Li] -- Update contrib/amd64 and contrib/masmx86/ [Vollant] -- Avoid use of "eof" parameter in trees.c to not shadow library variable -- Update make_vms.com for removal of zlibdefs.h [Zinser] -- Update assembler code and vstudio projects in contrib [Vollant] -- Remove outdated assembler code contrib/masm686 and contrib/asm586 -- Remove old vc7 and vc8 from contrib/vstudio -- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] -- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() -- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] -- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) -- Fix bug in void-returning vsprintf() case in gzwrite.c -- Fix name change from inflate.h in contrib/inflate86/inffas86.c -- Check if temporary file exists before removing in make_vms.com [Zinser] -- Fix make install and uninstall for --static option -- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] -- Update readme.txt in contrib/masmx64 and masmx86 to assemble - -Changes in 1.2.3.9 (21 Feb 2010) -- Expunge gzio.c -- Move as400 build information to old -- Fix updates in contrib/minizip and contrib/vstudio -- Add const to vsnprintf test in configure to avoid warnings [Weigelt] -- Delete zconf.h (made by configure) [Weigelt] -- Change zconf.in.h to zconf.h.in per convention [Weigelt] -- Check for NULL buf in gzgets() -- Return empty string for gzgets() with len == 1 (like fgets()) -- Fix description of gzgets() in zlib.h for end-of-file, NULL return -- Update minizip to 1.1 [Vollant] -- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c -- Note in zlib.h that gzerror() should be used to distinguish from EOF -- Remove use of snprintf() from gzlib.c -- Fix bug in gzseek() -- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] -- Fix zconf.h generation in CMakeLists.txt [Lowman] -- Improve comments in zconf.h where modified by configure - -Changes in 1.2.3.8 (13 Feb 2010) -- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] -- Use z_off64_t in gz_zero() and gz_skip() to match state->skip -- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) -- Revert to Makefile.in from 1.2.3.6 (live with the clutter) -- Fix missing error return in gzflush(), add zlib.h note -- Add *64 functions to zlib.map [Levin] -- Fix signed/unsigned comparison in gz_comp() -- Use SFLAGS when testing shared linking in configure -- Add --64 option to ./configure to use -m64 with gcc -- Fix ./configure --help to correctly name options -- Have make fail if a test fails [Levin] -- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] -- Remove assembler object files from contrib - -Changes in 1.2.3.7 (24 Jan 2010) -- Always gzopen() with O_LARGEFILE if available -- Fix gzdirect() to work immediately after gzopen() or gzdopen() -- Make gzdirect() more precise when the state changes while reading -- Improve zlib.h documentation in many places -- Catch memory allocation failure in gz_open() -- Complete close operation if seek forward in gzclose_w() fails -- Return Z_ERRNO from gzclose_r() if close() fails -- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL -- Return zero for gzwrite() errors to match zlib.h description -- Return -1 on gzputs() error to match zlib.h description -- Add zconf.in.h to allow recovery from configure modification [Weigelt] -- Fix static library permissions in Makefile.in [Weigelt] -- Avoid warnings in configure tests that hide functionality [Weigelt] -- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] -- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] -- Avoid access of uninitialized data for first inflateReset2 call [Gomes] -- Keep object files in subdirectories to reduce the clutter somewhat -- Remove default Makefile and zlibdefs.h, add dummy Makefile -- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ -- Remove zlibdefs.h completely -- modify zconf.h instead - -Changes in 1.2.3.6 (17 Jan 2010) -- Avoid void * arithmetic in gzread.c and gzwrite.c -- Make compilers happier with const char * for gz_error message -- Avoid unused parameter warning in inflate.c -- Avoid signed-unsigned comparison warning in inflate.c -- Indent #pragma's for traditional C -- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() -- Correct email address in configure for system options -- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] -- Update zlib.map [Brown] -- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] -- Apply various fixes to CMakeLists.txt [Lowman] -- Add checks on len in gzread() and gzwrite() -- Add error message for no more room for gzungetc() -- Remove zlib version check in gzwrite() -- Defer compression of gzprintf() result until need to -- Use snprintf() in gzdopen() if available -- Remove USE_MMAP configuration determination (only used by minigzip) -- Remove examples/pigz.c (available separately) -- Update examples/gun.c to 1.6 - -Changes in 1.2.3.5 (8 Jan 2010) -- Add space after #if in zutil.h for some compilers -- Fix relatively harmless bug in deflate_fast() [Exarevsky] -- Fix same problem in deflate_slow() -- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] -- Add deflate_rle() for faster Z_RLE strategy run-length encoding -- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding -- Change name of "write" variable in inffast.c to avoid library collisions -- Fix premature EOF from gzread() in gzio.c [Brown] -- Use zlib header window size if windowBits is 0 in inflateInit2() -- Remove compressBound() call in deflate.c to avoid linking compress.o -- Replace use of errno in gz* with functions, support WinCE [Alves] -- Provide alternative to perror() in minigzip.c for WinCE [Alves] -- Don't use _vsnprintf on later versions of MSVC [Lowman] -- Add CMake build script and input file [Lowman] -- Update contrib/minizip to 1.1 [Svensson, Vollant] -- Moved nintendods directory from contrib to root -- Replace gzio.c with a new set of routines with the same functionality -- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above -- Update contrib/minizip to 1.1b -- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h - -Changes in 1.2.3.4 (21 Dec 2009) -- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility -- Update comments in configure and Makefile.in for default --shared -- Fix test -z's in configure [Marquess] -- Build examplesh and minigzipsh when not testing -- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h -- Import LDFLAGS from the environment in configure -- Fix configure to populate SFLAGS with discovered CFLAGS options -- Adapt make_vms.com to the new Makefile.in [Zinser] -- Add zlib2ansi script for C++ compilation [Marquess] -- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) -- Add AMD64 assembler code for longest match to contrib [Teterin] -- Include options from $SFLAGS when doing $LDSHARED -- Simplify 64-bit file support by introducing z_off64_t type -- Make shared object files in objs directory to work around old Sun cc -- Use only three-part version number for Darwin shared compiles -- Add rc option to ar in Makefile.in for when ./configure not run -- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* -- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile -- Protect against _FILE_OFFSET_BITS being defined when compiling zlib -- Rename Makefile.in targets allstatic to static and allshared to shared -- Fix static and shared Makefile.in targets to be independent -- Correct error return bug in gz_open() by setting state [Brown] -- Put spaces before ;;'s in configure for better sh compatibility -- Add pigz.c (parallel implementation of gzip) to examples/ -- Correct constant in crc32.c to UL [Leventhal] -- Reject negative lengths in crc32_combine() -- Add inflateReset2() function to work like inflateEnd()/inflateInit2() -- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] -- Correct typo in doc/algorithm.txt [Janik] -- Fix bug in adler32_combine() [Zhu] -- Catch missing-end-of-block-code error in all inflates and in puff - Assures that random input to inflate eventually results in an error -- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ -- Update ENOUGH and its usage to reflect discovered bounds -- Fix gzerror() error report on empty input file [Brown] -- Add ush casts in trees.c to avoid pedantic runtime errors -- Fix typo in zlib.h uncompress() description [Reiss] -- Correct inflate() comments with regard to automatic header detection -- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) -- Put new version of gzlog (2.0) in examples with interruption recovery -- Add puff compile option to permit invalid distance-too-far streams -- Add puff TEST command options, ability to read piped input -- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but - _LARGEFILE64_SOURCE not defined -- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart -- Fix deflateSetDictionary() to use all 32K for output consistency -- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) -- Clear bytes after deflate lookahead to avoid use of uninitialized data -- Change a limit in inftrees.c to be more transparent to Coverity Prevent -- Update win32/zlib.def with exported symbols from zlib.h -- Correct spelling errors in zlib.h [Willem, Sobrado] -- Allow Z_BLOCK for deflate() to force a new block -- Allow negative bits in inflatePrime() to delete existing bit buffer -- Add Z_TREES flush option to inflate() to return at end of trees -- Add inflateMark() to return current state information for random access -- Add Makefile for NintendoDS to contrib [Costa] -- Add -w in configure compile tests to avoid spurious warnings [Beucler] -- Fix typos in zlib.h comments for deflateSetDictionary() -- Fix EOF detection in transparent gzread() [Maier] - -Changes in 1.2.3.3 (2 October 2006) -- Make --shared the default for configure, add a --static option -- Add compile option to permit invalid distance-too-far streams -- Add inflateUndermine() function which is required to enable above -- Remove use of "this" variable name for C++ compatibility [Marquess] -- Add testing of shared library in make test, if shared library built -- Use ftello() and fseeko() if available instead of ftell() and fseek() -- Provide two versions of all functions that use the z_off_t type for - binary compatibility -- a normal version and a 64-bit offset version, - per the Large File Support Extension when _LARGEFILE64_SOURCE is - defined; use the 64-bit versions by default when _FILE_OFFSET_BITS - is defined to be 64 -- Add a --uname= option to configure to perhaps help with cross-compiling - -Changes in 1.2.3.2 (3 September 2006) -- Turn off silly Borland warnings [Hay] -- Use off64_t and define _LARGEFILE64_SOURCE when present -- Fix missing dependency on inffixed.h in Makefile.in -- Rig configure --shared to build both shared and static [Teredesai, Truta] -- Remove zconf.in.h and instead create a new zlibdefs.h file -- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] -- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] - -Changes in 1.2.3.1 (16 August 2006) -- Add watcom directory with OpenWatcom make files [Daniel] -- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] -- Update make_vms.com [Zinser] -- Use -fPIC for shared build in configure [Teredesai, Nicholson] -- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] -- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] -- Add some FAQ entries about the contrib directory -- Update the MVS question in the FAQ -- Avoid extraneous reads after EOF in gzio.c [Brown] -- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] -- Add comments to zlib.h about gzerror() usage [Brown] -- Set extra flags in gzip header in gzopen() like deflate() does -- Make configure options more compatible with double-dash conventions - [Weigelt] -- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] -- Fix uninstall target in Makefile.in [Truta] -- Add pkgconfig support [Weigelt] -- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] -- Replace set_data_type() with a more accurate detect_data_type() in - trees.c, according to the txtvsbin.txt document [Truta] -- Swap the order of #include and #include "zlib.h" in - gzio.c, example.c and minigzip.c [Truta] -- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, - Truta] (where?) -- Fix target "clean" from win32/Makefile.bor [Truta] -- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] -- Update zlib www home address in win32/DLL_FAQ.txt [Truta] -- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] -- Enable browse info in the "Debug" and "ASM Debug" configurations in - the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] -- Add pkgconfig support [Weigelt] -- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, - for use in win32/zlib1.rc [Polushin, Rowe, Truta] -- Add a document that explains the new text detection scheme to - doc/txtvsbin.txt [Truta] -- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] -- Move algorithm.txt into doc/ [Truta] -- Synchronize FAQ with website -- Fix compressBound(), was low for some pathological cases [Fearnley] -- Take into account wrapper variations in deflateBound() -- Set examples/zpipe.c input and output to binary mode for Windows -- Update examples/zlib_how.html with new zpipe.c (also web site) -- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems - that gcc became pickier in 4.0) -- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain - un-versioned, the patch adds versioning only for symbols introduced in - zlib-1.2.0 or later. It also declares as local those symbols which are - not designed to be exported." [Levin] -- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure -- Do not initialize global static by default in trees.c, add a response - NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] -- Don't use strerror() in gzio.c under WinCE [Yakimov] -- Don't use errno.h in zutil.h under WinCE [Yakimov] -- Move arguments for AR to its usage to allow replacing ar [Marot] -- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] -- Improve inflateInit() and inflateInit2() documentation -- Fix structure size comment in inflate.h -- Change configure help option from --h* to --help [Santos] - -Changes in 1.2.3 (18 July 2005) -- Apply security vulnerability fixes to contrib/infback9 as well -- Clean up some text files (carriage returns, trailing space) -- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] - -Changes in 1.2.2.4 (11 July 2005) -- Add inflatePrime() function for starting inflation at bit boundary -- Avoid some Visual C warnings in deflate.c -- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit - compile -- Fix some spelling errors in comments [Betts] -- Correct inflateInit2() error return documentation in zlib.h -- Add zran.c example of compressed data random access to examples - directory, shows use of inflatePrime() -- Fix cast for assignments to strm->state in inflate.c and infback.c -- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] -- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] -- Add cast in trees.c t avoid a warning [Oberhumer] -- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] -- Update make_vms.com [Zinser] -- Initialize state->write in inflateReset() since copied in inflate_fast() -- Be more strict on incomplete code sets in inflate_table() and increase - ENOUGH and MAXD -- this repairs a possible security vulnerability for - invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for - discovering the vulnerability and providing test cases -- Add ia64 support to configure for HP-UX [Smith] -- Add error return to gzread() for format or i/o error [Levin] -- Use malloc.h for OS/2 [Necasek] - -Changes in 1.2.2.3 (27 May 2005) -- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile -- Typecast fread() return values in gzio.c [Vollant] -- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) -- Fix crc check bug in gzread() after gzungetc() [Heiner] -- Add the deflateTune() function to adjust internal compression parameters -- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) -- Remove an incorrect assertion in examples/zpipe.c -- Add C++ wrapper in infback9.h [Donais] -- Fix bug in inflateCopy() when decoding fixed codes -- Note in zlib.h how much deflateSetDictionary() actually uses -- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) -- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] -- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] -- Add gzdirect() function to indicate transparent reads -- Update contrib/minizip [Vollant] -- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] -- Add casts in crc32.c to avoid warnings [Oberhumer] -- Add contrib/masmx64 [Vollant] -- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] - -Changes in 1.2.2.2 (30 December 2004) -- Replace structure assignments in deflate.c and inflate.c with zmemcpy to - avoid implicit memcpy calls (portability for no-library compilation) -- Increase sprintf() buffer size in gzdopen() to allow for large numbers -- Add INFLATE_STRICT to check distances against zlib header -- Improve WinCE errno handling and comments [Chang] -- Remove comment about no gzip header processing in FAQ -- Add Z_FIXED strategy option to deflateInit2() to force fixed trees -- Add updated make_vms.com [Coghlan], update README -- Create a new "examples" directory, move gzappend.c there, add zpipe.c, - fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html -- Add FAQ entry and comments in deflate.c on uninitialized memory access -- Add Solaris 9 make options in configure [Gilbert] -- Allow strerror() usage in gzio.c for STDC -- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] -- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] -- Use z_off_t for adler32_combine() and crc32_combine() lengths -- Make adler32() much faster for small len -- Use OS_CODE in deflate() default gzip header - -Changes in 1.2.2.1 (31 October 2004) -- Allow inflateSetDictionary() call for raw inflate -- Fix inflate header crc check bug for file names and comments -- Add deflateSetHeader() and gz_header structure for custom gzip headers -- Add inflateGetheader() to retrieve gzip headers -- Add crc32_combine() and adler32_combine() functions -- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list -- Use zstreamp consistently in zlib.h (inflate_back functions) -- Remove GUNZIP condition from definition of inflate_mode in inflate.h - and in contrib/inflate86/inffast.S [Truta, Anderson] -- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] -- Update projects/README.projects and projects/visualc6 [Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] -- Deprecate Z_ASCII; use Z_TEXT instead [Truta] -- Use a new algorithm for setting strm->data_type in trees.c [Truta] -- Do not define an exit() prototype in zutil.c unless DEBUG defined -- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] -- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() -- Fix Darwin build version identification [Peterson] - -Changes in 1.2.2 (3 October 2004) -- Update zlib.h comments on gzip in-memory processing -- Set adler to 1 in inflateReset() to support Java test suite [Walles] -- Add contrib/dotzlib [Ravn] -- Update win32/DLL_FAQ.txt [Truta] -- Update contrib/minizip [Vollant] -- Move contrib/visual-basic.txt to old/ [Truta] -- Fix assembler builds in projects/visualc6/ [Truta] - -Changes in 1.2.1.2 (9 September 2004) -- Update INDEX file -- Fix trees.c to update strm->data_type (no one ever noticed!) -- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] -- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) -- Add limited multitasking protection to DYNAMIC_CRC_TABLE -- Add NO_vsnprintf for VMS in zutil.h [Mozilla] -- Don't declare strerror() under VMS [Mozilla] -- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize -- Update contrib/ada [Anisimkov] -- Update contrib/minizip [Vollant] -- Fix configure to not hardcode directories for Darwin [Peterson] -- Fix gzio.c to not return error on empty files [Brown] -- Fix indentation; update version in contrib/delphi/ZLib.pas and - contrib/pascal/zlibpas.pas [Truta] -- Update mkasm.bat in contrib/masmx86 [Truta] -- Update contrib/untgz [Truta] -- Add projects/README.projects [Truta] -- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] -- Remove an unnecessary assignment to curr in inftrees.c [Truta] -- Add OS/2 to exe builds in configure [Poltorak] -- Remove err dummy parameter in zlib.h [Kientzle] - -Changes in 1.2.1.1 (9 January 2004) -- Update email address in README -- Several FAQ updates -- Fix a big fat bug in inftrees.c that prevented decoding valid - dynamic blocks with only literals and no distance codes -- - Thanks to "Hot Emu" for the bug report and sample file -- Add a note to puff.c on no distance codes case - -Changes in 1.2.1 (17 November 2003) -- Remove a tab in contrib/gzappend/gzappend.c -- Update some interfaces in contrib for new zlib functions -- Update zlib version number in some contrib entries -- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] -- Support shared libraries on Hurd and KFreeBSD [Brown] -- Fix error in NO_DIVIDE option of adler32.c - -Changes in 1.2.0.8 (4 November 2003) -- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas -- Add experimental NO_DIVIDE #define in adler32.c - - Possibly faster on some processors (let me know if it is) -- Correct Z_BLOCK to not return on first inflate call if no wrap -- Fix strm->data_type on inflate() return to correctly indicate EOB -- Add deflatePrime() function for appending in the middle of a byte -- Add contrib/gzappend for an example of appending to a stream -- Update win32/DLL_FAQ.txt [Truta] -- Delete Turbo C comment in README [Truta] -- Improve some indentation in zconf.h [Truta] -- Fix infinite loop on bad input in configure script [Church] -- Fix gzeof() for concatenated gzip files [Johnson] -- Add example to contrib/visual-basic.txt [Michael B.] -- Add -p to mkdir's in Makefile.in [vda] -- Fix configure to properly detect presence or lack of printf functions -- Add AS400 support [Monnerat] -- Add a little Cygwin support [Wilson] - -Changes in 1.2.0.7 (21 September 2003) -- Correct some debug formats in contrib/infback9 -- Cast a type in a debug statement in trees.c -- Change search and replace delimiter in configure from % to # [Beebe] -- Update contrib/untgz to 0.2 with various fixes [Truta] -- Add build support for Amiga [Nikl] -- Remove some directories in old that have been updated to 1.2 -- Add dylib building for Mac OS X in configure and Makefile.in -- Remove old distribution stuff from Makefile -- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X -- Update links in README - -Changes in 1.2.0.6 (13 September 2003) -- Minor FAQ updates -- Update contrib/minizip to 1.00 [Vollant] -- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] -- Update POSTINC comment for 68060 [Nikl] -- Add contrib/infback9 with deflate64 decoding (unsupported) -- For MVS define NO_vsnprintf and undefine FAR [van Burik] -- Add pragma for fdopen on MVS [van Burik] - -Changes in 1.2.0.5 (8 September 2003) -- Add OF to inflateBackEnd() declaration in zlib.h -- Remember start when using gzdopen in the middle of a file -- Use internal off_t counters in gz* functions to properly handle seeks -- Perform more rigorous check for distance-too-far in inffast.c -- Add Z_BLOCK flush option to return from inflate at block boundary -- Set strm->data_type on return from inflate - - Indicate bits unused, if at block boundary, and if in last block -- Replace size_t with ptrdiff_t in crc32.c, and check for correct size -- Add condition so old NO_DEFLATE define still works for compatibility -- FAQ update regarding the Windows DLL [Truta] -- INDEX update: add qnx entry, remove aix entry [Truta] -- Install zlib.3 into mandir [Wilson] -- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] -- Adapt the zlib interface to the new DLL convention guidelines [Truta] -- Introduce ZLIB_WINAPI macro to allow the export of functions using - the WINAPI calling convention, for Visual Basic [Vollant, Truta] -- Update msdos and win32 scripts and makefiles [Truta] -- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] -- Add contrib/ada [Anisimkov] -- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] -- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] -- Add contrib/masm686 [Truta] -- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm - [Truta, Vollant] -- Update contrib/delphi; rename to contrib/pascal; add example [Truta] -- Remove contrib/delphi2; add a new contrib/delphi [Truta] -- Avoid inclusion of the nonstandard in contrib/iostream, - and fix some method prototypes [Truta] -- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip - [Truta] -- Avoid the use of backslash (\) in contrib/minizip [Vollant] -- Fix file time handling in contrib/untgz; update makefiles [Truta] -- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines - [Vollant] -- Remove contrib/vstudio/vc15_16 [Vollant] -- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] -- Update README.contrib [Truta] -- Invert the assignment order of match_head and s->prev[...] in - INSERT_STRING [Truta] -- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings - [Truta] -- Compare function pointers with 0, not with NULL or Z_NULL [Truta] -- Fix prototype of syncsearch in inflate.c [Truta] -- Introduce ASMINF macro to be enabled when using an ASM implementation - of inflate_fast [Truta] -- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] -- Modify test_gzio in example.c to take a single file name as a - parameter [Truta] -- Exit the example.c program if gzopen fails [Truta] -- Add type casts around strlen in example.c [Truta] -- Remove casting to sizeof in minigzip.c; give a proper type - to the variable compared with SUFFIX_LEN [Truta] -- Update definitions of STDC and STDC99 in zconf.h [Truta] -- Synchronize zconf.h with the new Windows DLL interface [Truta] -- Use SYS16BIT instead of __32BIT__ to distinguish between - 16- and 32-bit platforms [Truta] -- Use far memory allocators in small 16-bit memory models for - Turbo C [Truta] -- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in - zlibCompileFlags [Truta] -- Cygwin has vsnprintf [Wilson] -- In Windows16, OS_CODE is 0, as in MSDOS [Truta] -- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] - -Changes in 1.2.0.4 (10 August 2003) -- Minor FAQ updates -- Be more strict when checking inflateInit2's windowBits parameter -- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well -- Add gzip wrapper option to deflateInit2 using windowBits -- Add updated QNX rule in configure and qnx directory [Bonnefoy] -- Make inflate distance-too-far checks more rigorous -- Clean up FAR usage in inflate -- Add casting to sizeof() in gzio.c and minigzip.c - -Changes in 1.2.0.3 (19 July 2003) -- Fix silly error in gzungetc() implementation [Vollant] -- Update contrib/minizip and contrib/vstudio [Vollant] -- Fix printf format in example.c -- Correct cdecl support in zconf.in.h [Anisimkov] -- Minor FAQ updates - -Changes in 1.2.0.2 (13 July 2003) -- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons -- Attempt to avoid warnings in crc32.c for pointer-int conversion -- Add AIX to configure, remove aix directory [Bakker] -- Add some casts to minigzip.c -- Improve checking after insecure sprintf() or vsprintf() calls -- Remove #elif's from crc32.c -- Change leave label to inf_leave in inflate.c and infback.c to avoid - library conflicts -- Remove inflate gzip decoding by default--only enable gzip decoding by - special request for stricter backward compatibility -- Add zlibCompileFlags() function to return compilation information -- More typecasting in deflate.c to avoid warnings -- Remove leading underscore from _Capital #defines [Truta] -- Fix configure to link shared library when testing -- Add some Windows CE target adjustments [Mai] -- Remove #define ZLIB_DLL in zconf.h [Vollant] -- Add zlib.3 [Rodgers] -- Update RFC URL in deflate.c and algorithm.txt [Mai] -- Add zlib_dll_FAQ.txt to contrib [Truta] -- Add UL to some constants [Truta] -- Update minizip and vstudio [Vollant] -- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h -- Expand use of NO_DUMMY_DECL to avoid all dummy structures -- Added iostream3 to contrib [Schwardt] -- Replace rewind() with fseek() for WinCE [Truta] -- Improve setting of zlib format compression level flags - - Report 0 for huffman and rle strategies and for level == 0 or 1 - - Report 2 only for level == 6 -- Only deal with 64K limit when necessary at compile time [Truta] -- Allow TOO_FAR check to be turned off at compile time [Truta] -- Add gzclearerr() function [Souza] -- Add gzungetc() function - -Changes in 1.2.0.1 (17 March 2003) -- Add Z_RLE strategy for run-length encoding [Truta] - - When Z_RLE requested, restrict matches to distance one - - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE -- Correct FASTEST compilation to allow level == 0 -- Clean up what gets compiled for FASTEST -- Incorporate changes to zconf.in.h [Vollant] - - Refine detection of Turbo C need for dummy returns - - Refine ZLIB_DLL compilation - - Include additional header file on VMS for off_t typedef -- Try to use _vsnprintf where it supplants vsprintf [Vollant] -- Add some casts in inffast.c -- Enhance comments in zlib.h on what happens if gzprintf() tries to - write more than 4095 bytes before compression -- Remove unused state from inflateBackEnd() -- Remove exit(0) from minigzip.c, example.c -- Get rid of all those darn tabs -- Add "check" target to Makefile.in that does the same thing as "test" -- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in -- Update contrib/inflate86 [Anderson] -- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] -- Add msdos and win32 directories with makefiles [Truta] -- More additions and improvements to the FAQ - -Changes in 1.2.0 (9 March 2003) -- New and improved inflate code - - About 20% faster - - Does not allocate 32K window unless and until needed - - Automatically detects and decompresses gzip streams - - Raw inflate no longer needs an extra dummy byte at end - - Added inflateBack functions using a callback interface--even faster - than inflate, useful for file utilities (gzip, zip) - - Added inflateCopy() function to record state for random access on - externally generated deflate streams (e.g. in gzip files) - - More readable code (I hope) -- New and improved crc32() - - About 50% faster, thanks to suggestions from Rodney Brown -- Add deflateBound() and compressBound() functions -- Fix memory leak in deflateInit2() -- Permit setting dictionary for raw deflate (for parallel deflate) -- Fix const declaration for gzwrite() -- Check for some malloc() failures in gzio.c -- Fix bug in gzopen() on single-byte file 0x1f -- Fix bug in gzread() on concatenated file with 0x1f at end of buffer - and next buffer doesn't start with 0x8b -- Fix uncompress() to return Z_DATA_ERROR on truncated input -- Free memory at end of example.c -- Remove MAX #define in trees.c (conflicted with some libraries) -- Fix static const's in deflate.c, gzio.c, and zutil.[ch] -- Declare malloc() and free() in gzio.c if STDC not defined -- Use malloc() instead of calloc() in zutil.c if int big enough -- Define STDC for AIX -- Add aix/ with approach for compiling shared library on AIX -- Add HP-UX support for shared libraries in configure -- Add OpenUNIX support for shared libraries in configure -- Use $cc instead of gcc to build shared library -- Make prefix directory if needed when installing -- Correct Macintosh avoidance of typedef Byte in zconf.h -- Correct Turbo C memory allocation when under Linux -- Use libz.a instead of -lz in Makefile (assure use of compiled library) -- Update configure to check for snprintf or vsnprintf functions and their - return value, warn during make if using an insecure function -- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that - is lost when library is used--resolution is to build new zconf.h -- Documentation improvements (in zlib.h): - - Document raw deflate and inflate - - Update RFCs URL - - Point out that zlib and gzip formats are different - - Note that Z_BUF_ERROR is not fatal - - Document string limit for gzprintf() and possible buffer overflow - - Note requirement on avail_out when flushing - - Note permitted values of flush parameter of inflate() -- Add some FAQs (and even answers) to the FAQ -- Add contrib/inflate86/ for x86 faster inflate -- Add contrib/blast/ for PKWare Data Compression Library decompression -- Add contrib/puff/ simple inflate for deflate format description - -Changes in 1.1.4 (11 March 2002) -- ZFREE was repeated on same allocation on some error conditions - This creates a security problem described in - http://www.zlib.org/advisory-2002-03-11.txt -- Returned incorrect error (Z_MEM_ERROR) on some invalid data -- Avoid accesses before window for invalid distances with inflate window - less than 32K -- force windowBits > 8 to avoid a bug in the encoder for a window size - of 256 bytes. (A complete fix will be available in 1.1.5) - -Changes in 1.1.3 (9 July 1998) -- fix "an inflate input buffer bug that shows up on rare but persistent - occasions" (Mark) -- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) -- fix gzseek(..., SEEK_SET) in write mode -- fix crc check after a gzeek (Frank Faubert) -- fix miniunzip when the last entry in a zip file is itself a zip file - (J Lillge) -- add contrib/asm586 and contrib/asm686 (Brian Raiter) - See http://www.muppetlabs.com/~breadbox/software/assembly.html -- add support for Delphi 3 in contrib/delphi (Bob Dellaca) -- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) -- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) -- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) -- added a FAQ file - -- Support gzdopen on Mac with Metrowerks (Jason Linhart) -- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) -- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) -- avoid some warnings with Borland C (Tom Tanner) -- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) -- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) -- allow several arguments to configure (Tim Mooney, Frodo Looijaard) -- use libdir and includedir in Makefile.in (Tim Mooney) -- support shared libraries on OSF1 V4 (Tim Mooney) -- remove so_locations in "make clean" (Tim Mooney) -- fix maketree.c compilation error (Glenn, Mark) -- Python interface to zlib now in Python 1.5 (Jeremy Hylton) -- new Makefile.riscos (Rich Walker) -- initialize static descriptors in trees.c for embedded targets (Nick Smith) -- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) -- add the OS/2 files in Makefile.in too (Andrew Zabolotny) -- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) -- fix maketree.c to allow clean compilation of inffixed.h (Mark) -- fix parameter check in deflateCopy (Gunther Nikl) -- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) -- Many portability patches by Christian Spieler: - . zutil.c, zutil.h: added "const" for zmem* - . Make_vms.com: fixed some typos - . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists - . msdos/Makefile.msc: remove "default rtl link library" info from obj files - . msdos/Makefile.*: use model-dependent name for the built zlib library - . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: - new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) -- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) -- replace __far with _far for better portability (Christian Spieler, Tom Lane) -- fix test for errno.h in configure (Tim Newsham) - -Changes in 1.1.2 (19 March 98) -- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) - See http://www.winimage.com/zLibDll/unzip.html -- preinitialize the inflate tables for fixed codes, to make the code - completely thread safe (Mark) -- some simplifications and slight speed-up to the inflate code (Mark) -- fix gzeof on non-compressed files (Allan Schrum) -- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) -- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) -- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) -- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) -- do not wrap extern "C" around system includes (Tom Lane) -- mention zlib binding for TCL in README (Andreas Kupries) -- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) -- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) -- allow "configure --prefix $HOME" (Tim Mooney) -- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) -- move Makefile.sas to amiga/Makefile.sas - -Changes in 1.1.1 (27 Feb 98) -- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) -- remove block truncation heuristic which had very marginal effect for zlib - (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the - compression ratio on some files. This also allows inlining _tr_tally for - matches in deflate_slow -- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) - -Changes in 1.1.0 (24 Feb 98) -- do not return STREAM_END prematurely in inflate (John Bowler) -- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) -- compile with -DFASTEST to get compression code optimized for speed only -- in minigzip, try mmap'ing the input file first (Miguel Albrecht) -- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain - on Sun but significant on HP) - -- add a pointer to experimental unzip library in README (Gilles Vollant) -- initialize variable gcc in configure (Chris Herborth) - -Changes in 1.0.9 (17 Feb 1998) -- added gzputs and gzgets functions -- do not clear eof flag in gzseek (Mark Diekhans) -- fix gzseek for files in transparent mode (Mark Diekhans) -- do not assume that vsprintf returns the number of bytes written (Jens Krinke) -- replace EXPORT with ZEXPORT to avoid conflict with other programs -- added compress2 in zconf.h, zlib.def, zlib.dnt -- new asm code from Gilles Vollant in contrib/asm386 -- simplify the inflate code (Mark): - . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() - . ZALLOC the length list in inflate_trees_fixed() instead of using stack - . ZALLOC the value area for huft_build() instead of using stack - . Simplify Z_FINISH check in inflate() - -- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 -- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) -- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with - the declaration of FAR (Gilles Vollant) -- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) -- read_buf buf parameter of type Bytef* instead of charf* -- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) -- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) -- fix check for presence of directories in "make install" (Ian Willis) - -Changes in 1.0.8 (27 Jan 1998) -- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) -- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) -- added compress2() to allow setting the compression level -- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) -- use constant arrays for the static trees in trees.c instead of computing - them at run time (thanks to Ken Raeburn for this suggestion). To create - trees.h, compile with GEN_TREES_H and run "make test" -- check return code of example in "make test" and display result -- pass minigzip command line options to file_compress -- simplifying code of inflateSync to avoid gcc 2.8 bug - -- support CC="gcc -Wall" in configure -s (QingLong) -- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) -- fix test for shared library support to avoid compiler warnings -- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) -- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) -- do not use fdopen for Metrowerks on Mac (Brad Pettit)) -- add checks for gzputc and gzputc in example.c -- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) -- use const for the CRC table (Ken Raeburn) -- fixed "make uninstall" for shared libraries -- use Tracev instead of Trace in infblock.c -- in example.c use correct compressed length for test_sync -- suppress +vnocompatwarnings in configure for HPUX (not always supported) - -Changes in 1.0.7 (20 Jan 1998) -- fix gzseek which was broken in write mode -- return error for gzseek to negative absolute position -- fix configure for Linux (Chun-Chung Chen) -- increase stack space for MSC (Tim Wegner) -- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) -- define EXPORTVA for gzprintf (Gilles Vollant) -- added man page zlib.3 (Rick Rodgers) -- for contrib/untgz, fix makedir() and improve Makefile - -- check gzseek in write mode in example.c -- allocate extra buffer for seeks only if gzseek is actually called -- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) -- add inflateSyncPoint in zconf.h -- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def - -Changes in 1.0.6 (19 Jan 1998) -- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and - gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) -- Fix a deflate bug occurring only with compression level 0 (thanks to - Andy Buckler for finding this one) -- In minigzip, pass transparently also the first byte for .Z files -- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() -- check Z_FINISH in inflate (thanks to Marc Schluper) -- Implement deflateCopy (thanks to Adam Costello) -- make static libraries by default in configure, add --shared option -- move MSDOS or Windows specific files to directory msdos -- suppress the notion of partial flush to simplify the interface - (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) -- suppress history buffer provided by application to simplify the interface - (this feature was not implemented anyway in 1.0.4) -- next_in and avail_in must be initialized before calling inflateInit or - inflateInit2 -- add EXPORT in all exported functions (for Windows DLL) -- added Makefile.nt (thanks to Stephen Williams) -- added the unsupported "contrib" directory: - contrib/asm386/ by Gilles Vollant - 386 asm code replacing longest_match() - contrib/iostream/ by Kevin Ruland - A C++ I/O streams interface to the zlib gz* functions - contrib/iostream2/ by Tyge Løvset - Another C++ I/O streams interface - contrib/untgz/ by "Pedro A. Aranda Guti\irrez" - A very simple tar.gz file extractor using zlib - contrib/visual-basic.txt by Carlos Rios - How to use compress(), uncompress() and the gz* functions from VB -- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression - level) in minigzip (thanks to Tom Lane) - -- use const for rommable constants in deflate -- added test for gzseek and gztell in example.c -- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) -- add undocumented function zError to convert error code to string - (for Tim Smithers) -- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code -- Use default memcpy for Symantec MSDOS compiler -- Add EXPORT keyword for check_func (needed for Windows DLL) -- add current directory to LD_LIBRARY_PATH for "make test" -- create also a link for libz.so.1 -- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) -- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) -- added -soname for Linux in configure (Chun-Chung Chen, -- assign numbers to the exported functions in zlib.def (for Windows DLL) -- add advice in zlib.h for best usage of deflateSetDictionary -- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) -- allow compilation with ANSI keywords only enabled for TurboC in large model -- avoid "versionString"[0] (Borland bug) -- add NEED_DUMMY_RETURN for Borland -- use variable z_verbose for tracing in debug mode (L. Peter Deutsch) -- allow compilation with CC -- defined STDC for OS/2 (David Charlap) -- limit external names to 8 chars for MVS (Thomas Lund) -- in minigzip.c, use static buffers only for 16-bit systems -- fix suffix check for "minigzip -d foo.gz" -- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) -- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) -- added makelcc.bat for lcc-win32 (Tom St Denis) -- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion -- check for unistd.h in configure (for off_t) -- remove useless check parameter in inflate_blocks_free -- avoid useless assignment of s->check to itself in inflate_blocks_new -- do not flush twice in gzclose (thanks to Ken Raeburn) -- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h -- use NO_ERRNO_H instead of enumeration of operating systems with errno.h -- work around buggy fclose on pipes for HP/UX -- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) -- fix configure if CC is already equal to gcc - -Changes in 1.0.5 (3 Jan 98) -- Fix inflate to terminate gracefully when fed corrupted or invalid data -- Use const for rommable constants in inflate -- Eliminate memory leaks on error conditions in inflate -- Removed some vestigial code in inflate -- Update web address in README - -Changes in 1.0.4 (24 Jul 96) -- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF - bit, so the decompressor could decompress all the correct data but went - on to attempt decompressing extra garbage data. This affected minigzip too -- zlibVersion and gzerror return const char* (needed for DLL) -- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) -- use z_error only for DEBUG (avoid problem with DLLs) - -Changes in 1.0.3 (2 Jul 96) -- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS - small and medium models; this makes the library incompatible with previous - versions for these models. (No effect in large model or on other systems.) -- return OK instead of BUF_ERROR if previous deflate call returned with - avail_out as zero but there is nothing to do -- added memcmp for non STDC compilers -- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) -- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) -- better check for 16-bit mode MSC (avoids problem with Symantec) - -Changes in 1.0.2 (23 May 96) -- added Windows DLL support -- added a function zlibVersion (for the DLL support) -- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) -- Bytef is define's instead of typedef'd only for Borland C -- avoid reading uninitialized memory in example.c -- mention in README that the zlib format is now RFC1950 -- updated Makefile.dj2 -- added algorithm.doc - -Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] -- fix array overlay in deflate.c which sometimes caused bad compressed data -- fix inflate bug with empty stored block -- fix MSDOS medium model which was broken in 0.99 -- fix deflateParams() which could generate bad compressed data -- Bytef is define'd instead of typedef'ed (work around Borland bug) -- added an INDEX file -- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), - Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) -- speed up adler32 for modern machines without auto-increment -- added -ansi for IRIX in configure -- static_init_done in trees.c is an int -- define unlink as delete for VMS -- fix configure for QNX -- add configure branch for SCO and HPUX -- avoid many warnings (unused variables, dead assignments, etc...) -- no fdopen for BeOS -- fix the Watcom fix for 32 bit mode (define FAR as empty) -- removed redefinition of Byte for MKWERKS -- work around an MWKERKS bug (incorrect merge of all .h files) - -Changes in 0.99 (27 Jan 96) -- allow preset dictionary shared between compressor and decompressor -- allow compression level 0 (no compression) -- add deflateParams in zlib.h: allow dynamic change of compression level - and compression strategy -- test large buffers and deflateParams in example.c -- add optional "configure" to build zlib as a shared library -- suppress Makefile.qnx, use configure instead -- fixed deflate for 64-bit systems (detected on Cray) -- fixed inflate_blocks for 64-bit systems (detected on Alpha) -- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) -- always return Z_BUF_ERROR when deflate() has nothing to do -- deflateInit and inflateInit are now macros to allow version checking -- prefix all global functions and types with z_ with -DZ_PREFIX -- make falloc completely reentrant (inftrees.c) -- fixed very unlikely race condition in ct_static_init -- free in reverse order of allocation to help memory manager -- use zlib-1.0/* instead of zlib/* inside the tar.gz -- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith - -Wconversion -Wstrict-prototypes -Wmissing-prototypes" -- allow gzread on concatenated .gz files -- deflateEnd now returns Z_DATA_ERROR if it was premature -- deflate is finally (?) fully deterministic (no matches beyond end of input) -- Document Z_SYNC_FLUSH -- add uninstall in Makefile -- Check for __cpluplus in zlib.h -- Better test in ct_align for partial flush -- avoid harmless warnings for Borland C++ -- initialize hash_head in deflate.c -- avoid warning on fdopen (gzio.c) for HP cc -Aa -- include stdlib.h for STDC compilers -- include errno.h for Cray -- ignore error if ranlib doesn't exist -- call ranlib twice for NeXTSTEP -- use exec_prefix instead of prefix for libz.a -- renamed ct_* as _tr_* to avoid conflict with applications -- clear z->msg in inflateInit2 before any error return -- initialize opaque in example.c, gzio.c, deflate.c and inflate.c -- fixed typo in zconf.h (_GNUC__ => __GNUC__) -- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) -- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) -- in fcalloc, normalize pointer if size > 65520 bytes -- don't use special fcalloc for 32 bit Borland C++ -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc. -- use Z_BINARY instead of BINARY -- document that gzclose after gzdopen will close the file -- allow "a" as mode in gzopen -- fix error checking in gzread -- allow skipping .gz extra-field on pipes -- added reference to Perl interface in README -- put the crc table in FAR data (I dislike more and more the medium model :) -- added get_crc_table -- added a dimension to all arrays (Borland C can't count) -- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast -- guard against multiple inclusion of *.h (for precompiled header on Mac) -- Watcom C pretends to be Microsoft C small model even in 32 bit mode -- don't use unsized arrays to avoid silly warnings by Visual C++: - warning C4746: 'inflate_mask' : unsized array treated as '__far' - (what's wrong with far data in far model?) -- define enum out of inflate_blocks_state to allow compilation with C++ - -Changes in 0.95 (16 Aug 95) -- fix MSDOS small and medium model (now easier to adapt to any compiler) -- inlined send_bits -- fix the final (:-) bug for deflate with flush (output was correct but - not completely flushed in rare occasions) -- default window size is same for compression and decompression - (it's now sufficient to set MAX_WBITS in zconf.h) -- voidp -> voidpf and voidnp -> voidp (for consistency with other - typedefs and because voidnp was not near in large model) - -Changes in 0.94 (13 Aug 95) -- support MSDOS medium model -- fix deflate with flush (could sometimes generate bad output) -- fix deflateReset (zlib header was incorrectly suppressed) -- added support for VMS -- allow a compression level in gzopen() -- gzflush now calls fflush -- For deflate with flush, flush even if no more input is provided -- rename libgz.a as libz.a -- avoid complex expression in infcodes.c triggering Turbo C bug -- work around a problem with gcc on Alpha (in INSERT_STRING) -- don't use inline functions (problem with some gcc versions) -- allow renaming of Byte, uInt, etc... with #define -- avoid warning about (unused) pointer before start of array in deflate.c -- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c -- avoid reserved word 'new' in trees.c - -Changes in 0.93 (25 June 95) -- temporarily disable inline functions -- make deflate deterministic -- give enough lookahead for PARTIAL_FLUSH -- Set binary mode for stdin/stdout in minigzip.c for OS/2 -- don't even use signed char in inflate (not portable enough) -- fix inflate memory leak for segmented architectures - -Changes in 0.92 (3 May 95) -- don't assume that char is signed (problem on SGI) -- Clear bit buffer when starting a stored block -- no memcpy on Pyramid -- suppressed inftest.c -- optimized fill_window, put longest_match inline for gcc -- optimized inflate on stored blocks -- untabify all sources to simplify patches - -Changes in 0.91 (2 May 95) -- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h -- Document the memory requirements in zconf.h -- added "make install" -- fix sync search logic in inflateSync -- deflate(Z_FULL_FLUSH) now works even if output buffer too short -- after inflateSync, don't scare people with just "lo world" -- added support for DJGPP - -Changes in 0.9 (1 May 95) -- don't assume that zalloc clears the allocated memory (the TurboC bug - was Mark's bug after all :) -- let again gzread copy uncompressed data unchanged (was working in 0.71) -- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented -- added a test of inflateSync in example.c -- moved MAX_WBITS to zconf.h because users might want to change that -- document explicitly that zalloc(64K) on MSDOS must return a normalized - pointer (zero offset) -- added Makefiles for Microsoft C, Turbo C, Borland C++ -- faster crc32() - -Changes in 0.8 (29 April 95) -- added fast inflate (inffast.c) -- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this - is incompatible with previous versions of zlib which returned Z_OK -- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) - (actually that was not a compiler bug, see 0.81 above) -- gzread no longer reads one extra byte in certain cases -- In gzio destroy(), don't reference a freed structure -- avoid many warnings for MSDOS -- avoid the ERROR symbol which is used by MS Windows - -Changes in 0.71 (14 April 95) -- Fixed more MSDOS compilation problems :( There is still a bug with - TurboC large model - -Changes in 0.7 (14 April 95) -- Added full inflate support -- Simplified the crc32() interface. The pre- and post-conditioning - (one's complement) is now done inside crc32(). WARNING: this is - incompatible with previous versions; see zlib.h for the new usage - -Changes in 0.61 (12 April 95) -- workaround for a bug in TurboC. example and minigzip now work on MSDOS - -Changes in 0.6 (11 April 95) -- added minigzip.c -- added gzdopen to reopen a file descriptor as gzFile -- added transparent reading of non-gziped files in gzread -- fixed bug in gzread (don't read crc as data) -- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose) -- don't allocate big arrays in the stack (for MSDOS) -- fix some MSDOS compilation problems - -Changes in 0.5: -- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but - not yet Z_FULL_FLUSH -- support decompression but only in a single step (forced Z_FINISH) -- added opaque object for zalloc and zfree -- added deflateReset and inflateReset -- added a variable zlib_version for consistency checking -- renamed the 'filter' parameter of deflateInit2 as 'strategy' - Added Z_FILTERED and Z_HUFFMAN_ONLY constants - -Changes in 0.4: -- avoid "zip" everywhere, use zlib instead of ziplib -- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush - if compression method == 8 -- added adler32 and crc32 -- renamed deflateOptions as deflateInit2, call one or the other but not both -- added the method parameter for deflateInit2 -- added inflateInit2 -- simplified considerably deflateInit and inflateInit by not supporting - user-provided history buffer. This is supported only in deflateInit2 - and inflateInit2 - -Changes in 0.3: -- prefix all macro names with Z_ -- use Z_FINISH instead of deflateEnd to finish compression -- added Z_HUFFMAN_ONLY -- added gzerror() diff --git a/libraries/zlib/FAQ b/libraries/zlib/FAQ deleted file mode 100644 index 55f1cdc22..000000000 --- a/libraries/zlib/FAQ +++ /dev/null @@ -1,368 +0,0 @@ - - Frequently Asked Questions about zlib - - -If your question is not there, please check the zlib home page -http://zlib.net/ which may have more recent information. -The latest zlib FAQ is at http://zlib.net/zlib_faq.html - - - 1. Is zlib Y2K-compliant? - - Yes. zlib doesn't handle dates. - - 2. Where can I get a Windows DLL version? - - The zlib sources can be compiled without change to produce a DLL. See the - file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the - precompiled DLL are found in the zlib web site at http://zlib.net/ . - - 3. Where can I get a Visual Basic interface to zlib? - - See - * http://marknelson.us/1997/01/01/zlib-engine/ - * win32/DLL_FAQ.txt in the zlib distribution - - 4. compress() returns Z_BUF_ERROR. - - Make sure that before the call of compress(), the length of the compressed - buffer is equal to the available size of the compressed buffer and not - zero. For Visual Basic, check that this parameter is passed by reference - ("as any"), not by value ("as long"). - - 5. deflate() or inflate() returns Z_BUF_ERROR. - - Before making the call, make sure that avail_in and avail_out are not zero. - When setting the parameter flush equal to Z_FINISH, also make sure that - avail_out is big enough to allow processing all pending input. Note that a - Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be - made with more input or output space. A Z_BUF_ERROR may in fact be - unavoidable depending on how the functions are used, since it is not - possible to tell whether or not there is more output pending when - strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a - heavily annotated example. - - 6. Where's the zlib documentation (man pages, etc.)? - - It's in zlib.h . Examples of zlib usage are in the files test/example.c - and test/minigzip.c, with more in examples/ . - - 7. Why don't you use GNU autoconf or libtool or ...? - - Because we would like to keep zlib as a very small and simple package. - zlib is rather portable and doesn't need much configuration. - - 8. I found a bug in zlib. - - Most of the time, such problems are due to an incorrect usage of zlib. - Please try to reproduce the problem with a small program and send the - corresponding source to us at zlib@gzip.org . Do not send multi-megabyte - data files without prior agreement. - - 9. Why do I get "undefined reference to gzputc"? - - If "make test" produces something like - - example.o(.text+0x154): undefined reference to `gzputc' - - check that you don't have old files libz.* in /usr/lib, /usr/local/lib or - /usr/X11R6/lib. Remove any old versions, then do "make install". - -10. I need a Delphi interface to zlib. - - See the contrib/delphi directory in the zlib distribution. - -11. Can zlib handle .zip archives? - - Not by itself, no. See the directory contrib/minizip in the zlib - distribution. - -12. Can zlib handle .Z files? - - No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt - the code of uncompress on your own. - -13. How can I make a Unix shared library? - - By default a shared (and a static) library is built for Unix. So: - - make distclean - ./configure - make - -14. How do I install a shared zlib library on Unix? - - After the above, then: - - make install - - However, many flavors of Unix come with a shared zlib already installed. - Before going to the trouble of compiling a shared version of zlib and - trying to install it, you may want to check if it's already there! If you - can #include , it's there. The -lz option will probably link to - it. You can check the version at the top of zlib.h or with the - ZLIB_VERSION symbol defined in zlib.h . - -15. I have a question about OttoPDF. - - We are not the authors of OttoPDF. The real author is on the OttoPDF web - site: Joel Hainley, jhainley@myndkryme.com. - -16. Can zlib decode Flate data in an Adobe PDF file? - - Yes. See http://www.pdflib.com/ . To modify PDF forms, see - http://sourceforge.net/projects/acroformtool/ . - -17. Why am I getting this "register_frame_info not found" error on Solaris? - - After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib - generates an error such as: - - ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: - symbol __register_frame_info: referenced symbol not found - - The symbol __register_frame_info is not part of zlib, it is generated by - the C compiler (cc or gcc). You must recompile applications using zlib - which have this problem. This problem is specific to Solaris. See - http://www.sunfreeware.com for Solaris versions of zlib and applications - using zlib. - -18. Why does gzip give an error on a file I make with compress/deflate? - - The compress and deflate functions produce data in the zlib format, which - is different and incompatible with the gzip format. The gz* functions in - zlib on the other hand use the gzip format. Both the zlib and gzip formats - use the same compressed data format internally, but have different headers - and trailers around the compressed data. - -19. Ok, so why are there two different formats? - - The gzip format was designed to retain the directory information about a - single file, such as the name and last modification date. The zlib format - on the other hand was designed for in-memory and communication channel - applications, and has a much more compact header and trailer and uses a - faster integrity check than gzip. - -20. Well that's nice, but how do I make a gzip file in memory? - - You can request that deflate write the gzip format instead of the zlib - format using deflateInit2(). You can also request that inflate decode the - gzip format using inflateInit2(). Read zlib.h for more details. - -21. Is zlib thread-safe? - - Yes. However any library routines that zlib uses and any application- - provided memory allocation routines must also be thread-safe. zlib's gz* - functions use stdio library routines, and most of zlib's functions use the - library memory allocation routines by default. zlib's *Init* functions - allow for the application to provide custom memory allocation routines. - - Of course, you should only operate on any given zlib or gzip stream from a - single thread at a time. - -22. Can I use zlib in my commercial application? - - Yes. Please read the license in zlib.h. - -23. Is zlib under the GNU license? - - No. Please read the license in zlib.h. - -24. The license says that altered source versions must be "plainly marked". So - what exactly do I need to do to meet that requirement? - - You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In - particular, the final version number needs to be changed to "f", and an - identification string should be appended to ZLIB_VERSION. Version numbers - x.x.x.f are reserved for modifications to zlib by others than the zlib - maintainers. For example, if the version of the base zlib you are altering - is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and - ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also - update the version strings in deflate.c and inftrees.c. - - For altered source distributions, you should also note the origin and - nature of the changes in zlib.h, as well as in ChangeLog and README, along - with the dates of the alterations. The origin should include at least your - name (or your company's name), and an email address to contact for help or - issues with the library. - - Note that distributing a compiled zlib library along with zlib.h and - zconf.h is also a source distribution, and so you should change - ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes - in zlib.h as you would for a full source distribution. - -25. Will zlib work on a big-endian or little-endian architecture, and can I - exchange compressed data between them? - - Yes and yes. - -26. Will zlib work on a 64-bit machine? - - Yes. It has been tested on 64-bit machines, and has no dependence on any - data types being limited to 32-bits in length. If you have any - difficulties, please provide a complete problem report to zlib@gzip.org - -27. Will zlib decompress data from the PKWare Data Compression Library? - - No. The PKWare DCL uses a completely different compressed data format than - does PKZIP and zlib. However, you can look in zlib's contrib/blast - directory for a possible solution to your problem. - -28. Can I access data randomly in a compressed stream? - - No, not without some preparation. If when compressing you periodically use - Z_FULL_FLUSH, carefully write all the pending data at those points, and - keep an index of those locations, then you can start decompression at those - points. You have to be careful to not use Z_FULL_FLUSH too often, since it - can significantly degrade compression. Alternatively, you can scan a - deflate stream once to generate an index, and then use that index for - random access. See examples/zran.c . - -29. Does zlib work on MVS, OS/390, CICS, etc.? - - It has in the past, but we have not heard of any recent evidence. There - were working ports of zlib 1.1.4 to MVS, but those links no longer work. - If you know of recent, successful applications of zlib on these operating - systems, please let us know. Thanks. - -30. Is there some simpler, easier to read version of inflate I can look at to - understand the deflate format? - - First off, you should read RFC 1951. Second, yes. Look in zlib's - contrib/puff directory. - -31. Does zlib infringe on any patents? - - As far as we know, no. In fact, that was originally the whole point behind - zlib. Look here for some more information: - - http://www.gzip.org/#faq11 - -32. Can zlib work with greater than 4 GB of data? - - Yes. inflate() and deflate() will process any amount of data correctly. - Each call of inflate() or deflate() is limited to input and output chunks - of the maximum value that can be stored in the compiler's "unsigned int" - type, but there is no limit to the number of chunks. Note however that the - strm.total_in and strm_total_out counters may be limited to 4 GB. These - counters are provided as a convenience and are not used internally by - inflate() or deflate(). The application can easily set up its own counters - updated after each call of inflate() or deflate() to count beyond 4 GB. - compress() and uncompress() may be limited to 4 GB, since they operate in a - single call. gzseek() and gztell() may be limited to 4 GB depending on how - zlib is compiled. See the zlibCompileFlags() function in zlib.h. - - The word "may" appears several times above since there is a 4 GB limit only - if the compiler's "long" type is 32 bits. If the compiler's "long" type is - 64 bits, then the limit is 16 exabytes. - -33. Does zlib have any security vulnerabilities? - - The only one that we are aware of is potentially in gzprintf(). If zlib is - compiled to use sprintf() or vsprintf(), then there is no protection - against a buffer overflow of an 8K string space (or other value as set by - gzbuffer()), other than the caller of gzprintf() assuring that the output - will not exceed 8K. On the other hand, if zlib is compiled to use - snprintf() or vsnprintf(), which should normally be the case, then there is - no vulnerability. The ./configure script will display warnings if an - insecure variation of sprintf() will be used by gzprintf(). Also the - zlibCompileFlags() function will return information on what variant of - sprintf() is used by gzprintf(). - - If you don't have snprintf() or vsnprintf() and would like one, you can - find a portable implementation here: - - http://www.ijs.si/software/snprintf/ - - Note that you should be using the most recent version of zlib. Versions - 1.1.3 and before were subject to a double-free vulnerability, and versions - 1.2.1 and 1.2.2 were subject to an access exception when decompressing - invalid compressed data. - -34. Is there a Java version of zlib? - - Probably what you want is to use zlib in Java. zlib is already included - as part of the Java SDK in the java.util.zip package. If you really want - a version of zlib written in the Java language, look on the zlib home - page for links: http://zlib.net/ . - -35. I get this or that compiler or source-code scanner warning when I crank it - up to maximally-pedantic. Can't you guys write proper code? - - Many years ago, we gave up attempting to avoid warnings on every compiler - in the universe. It just got to be a waste of time, and some compilers - were downright silly as well as contradicted each other. So now, we simply - make sure that the code always works. - -36. Valgrind (or some similar memory access checker) says that deflate is - performing a conditional jump that depends on an uninitialized value. - Isn't that a bug? - - No. That is intentional for performance reasons, and the output of deflate - is not affected. This only started showing up recently since zlib 1.2.x - uses malloc() by default for allocations, whereas earlier versions used - calloc(), which zeros out the allocated memory. Even though the code was - correct, versions 1.2.4 and later was changed to not stimulate these - checkers. - -37. Will zlib read the (insert any ancient or arcane format here) compressed - data format? - - Probably not. Look in the comp.compression FAQ for pointers to various - formats and associated software. - -38. How can I encrypt/decrypt zip files with zlib? - - zlib doesn't support encryption. The original PKZIP encryption is very - weak and can be broken with freely available programs. To get strong - encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib - compression. For PKZIP compatible "encryption", look at - http://www.info-zip.org/ - -39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? - - "gzip" is the gzip format, and "deflate" is the zlib format. They should - probably have called the second one "zlib" instead to avoid confusion with - the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 - correctly points to the zlib specification in RFC 1950 for the "deflate" - transfer encoding, there have been reports of servers and browsers that - incorrectly produce or expect raw deflate data per the deflate - specification in RFC 1951, most notably Microsoft. So even though the - "deflate" transfer encoding using the zlib format would be the more - efficient approach (and in fact exactly what the zlib format was designed - for), using the "gzip" transfer encoding is probably more reliable due to - an unfortunate choice of name on the part of the HTTP 1.1 authors. - - Bottom line: use the gzip format for HTTP 1.1 encoding. - -40. Does zlib support the new "Deflate64" format introduced by PKWare? - - No. PKWare has apparently decided to keep that format proprietary, since - they have not documented it as they have previous compression formats. In - any case, the compression improvements are so modest compared to other more - modern approaches, that it's not worth the effort to implement. - -41. I'm having a problem with the zip functions in zlib, can you help? - - There are no zip functions in zlib. You are probably using minizip by - Giles Vollant, which is found in the contrib directory of zlib. It is not - part of zlib. In fact none of the stuff in contrib is part of zlib. The - files in there are not supported by the zlib authors. You need to contact - the authors of the respective contribution for help. - -42. The match.asm code in contrib is under the GNU General Public License. - Since it's part of zlib, doesn't that mean that all of zlib falls under the - GNU GPL? - - No. The files in contrib are not part of zlib. They were contributed by - other authors and are provided as a convenience to the user within the zlib - distribution. Each item in contrib has its own license. - -43. Is zlib subject to export controls? What is its ECCN? - - zlib is not subject to export controls, and so is classified as EAR99. - -44. Can you please sign these lengthy legal documents and fax them back to us - so that we can use your software in our product? - - No. Go away. Shoo. diff --git a/libraries/zlib/INDEX b/libraries/zlib/INDEX deleted file mode 100644 index 2ba064120..000000000 --- a/libraries/zlib/INDEX +++ /dev/null @@ -1,68 +0,0 @@ -CMakeLists.txt cmake build file -ChangeLog history of changes -FAQ Frequently Asked Questions about zlib -INDEX this file -Makefile dummy Makefile that tells you to ./configure -Makefile.in template for Unix Makefile -README guess what -configure configure script for Unix -make_vms.com makefile for VMS -test/example.c zlib usages examples for build testing -test/minigzip.c minimal gzip-like functionality for build testing -test/infcover.c inf*.c code coverage for build coverage testing -treebuild.xml XML description of source file dependencies -zconf.h.cmakein zconf.h template for cmake -zconf.h.in zconf.h template for configure -zlib.3 Man page for zlib -zlib.3.pdf Man page in PDF format -zlib.map Linux symbol information -zlib.pc.in Template for pkg-config descriptor -zlib.pc.cmakein zlib.pc template for cmake -zlib2ansi perl script to convert source files for C++ compilation - -amiga/ makefiles for Amiga SAS C -as400/ makefiles for AS/400 -doc/ documentation for formats and algorithms -msdos/ makefiles for MSDOS -nintendods/ makefile for Nintendo DS -old/ makefiles for various architectures and zlib documentation - files that have not yet been updated for zlib 1.2.x -qnx/ makefiles for QNX -watcom/ makefiles for OpenWatcom -win32/ makefiles for Windows - - zlib public header files (required for library use): -zconf.h -zlib.h - - private source files used to build the zlib library: -adler32.c -compress.c -crc32.c -crc32.h -deflate.c -deflate.h -gzclose.c -gzguts.h -gzlib.c -gzread.c -gzwrite.c -infback.c -inffast.c -inffast.h -inffixed.h -inflate.c -inflate.h -inftrees.c -inftrees.h -trees.c -trees.h -uncompr.c -zutil.c -zutil.h - - source files for sample programs -See examples/README.examples - - unsupported contributions by third parties -See contrib/README.contrib diff --git a/libraries/zlib/README b/libraries/zlib/README deleted file mode 100644 index e02fc5aa2..000000000 --- a/libraries/zlib/README +++ /dev/null @@ -1,117 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.3 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 , or to Gilles Vollant - 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 wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available at -https://marknelson.us/posts/1997/01/01/zlib-engine.html . - -The changes made in version 1.3 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. Follow the API -Documentation link at: https://docs.oracle.com/search/?q=java.util.zip . - -A Perl interface to zlib and bzip2 written by Paul Marquess -can be found at https://github.com/pmqs/IO-Compress . - -A Python interface to zlib written by A.M. Kuchling 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 , 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 (formerly 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-2023 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. We make all -contributions to and distributions of this project solely in our personal -capacity, and are not conveying any rights to any intellectual property of -any third parties. - -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/libraries/zlib/adler32.c b/libraries/zlib/adler32.c deleted file mode 100644 index 04b81d29b..000000000 --- a/libraries/zlib/adler32.c +++ /dev/null @@ -1,164 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#define BASE 65521U /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32_z(uLong adler, const Bytef *buf, z_size_t len) { - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len) { - return adler32_z(adler, buf, len); -} - -/* ========================================================================= */ -local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2) { - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, z_off_t len2) { - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(uLong adler1, uLong adler2, z_off64_t len2) { - return adler32_combine_(adler1, adler2, len2); -} diff --git a/libraries/zlib/algorithm.txt b/libraries/zlib/algorithm.txt deleted file mode 100644 index c97f49502..000000000 --- a/libraries/zlib/algorithm.txt +++ /dev/null @@ -1,209 +0,0 @@ -1. Compression algorithm (deflate) - -The deflation algorithm used by gzip (also zip and zlib) is a variation of -LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in -the input data. The second occurrence of a string is replaced by a -pointer to the previous string, in the form of a pair (distance, -length). Distances are limited to 32K bytes, and lengths are limited -to 258 bytes. When a string does not occur anywhere in the previous -32K bytes, it is emitted as a sequence of literal bytes. (In this -description, `string' must be taken as an arbitrary sequence of bytes, -and is not restricted to printable characters.) - -Literals or match lengths are compressed with one Huffman tree, and -match distances are compressed with another tree. The trees are stored -in a compact form at the start of each block. The blocks can have any -size (except that the compressed data for one block must fit in -available memory). A block is terminated when deflate() determines that -it would be useful to start another block with fresh trees. (This is -somewhat similar to the behavior of LZW-based _compress_.) - -Duplicated strings are found using a hash table. All input strings of -length 3 are inserted in the hash table. A hash index is computed for -the next 3 bytes. If the hash chain for this index is not empty, all -strings in the chain are compared with the current input string, and -the longest match is selected. - -The hash chains are searched starting with the most recent strings, to -favor small distances and thus take advantage of the Huffman encoding. -The hash chains are singly linked. There are no deletions from the -hash chains, the algorithm simply discards matches that are too old. - -To avoid a worst-case situation, very long hash chains are arbitrarily -truncated at a certain length, determined by a runtime option (level -parameter of deflateInit). So deflate() does not always find the longest -possible match but generally finds a match which is long enough. - -deflate() also defers the selection of matches with a lazy evaluation -mechanism. After a match of length N has been found, deflate() searches for -a longer match at the next input byte. If a longer match is found, the -previous match is truncated to a length of one (thus producing a single -literal byte) and the process of lazy evaluation begins again. Otherwise, -the original match is kept, and the next match search is attempted only N -steps later. - -The lazy match evaluation is also subject to a runtime parameter. If -the current match is long enough, deflate() reduces the search for a longer -match, thus speeding up the whole process. If compression ratio is more -important than speed, deflate() attempts a complete second search even if -the first match is already long enough. - -The lazy match evaluation is not performed for the fastest compression -modes (level parameter 1 to 3). For these fast modes, new strings -are inserted in the hash table only when no match was found, or -when the match is not too long. This degrades the compression ratio -but saves time since there are both fewer insertions and fewer searches. - - -2. Decompression algorithm (inflate) - -2.1 Introduction - -The key question is how to represent a Huffman code (or any prefix code) so -that you can decode fast. The most important characteristic is that shorter -codes are much more common than longer codes, so pay attention to decoding the -short codes fast, and let the long codes take longer to decode. - -inflate() sets up a first level table that covers some number of bits of -input less than the length of longest code. It gets that many bits from the -stream, and looks it up in the table. The table will tell if the next -code is that many bits or less and how many, and if it is, it will tell -the value, else it will point to the next level table for which inflate() -grabs more bits and tries to decode a longer code. - -How many bits to make the first lookup is a tradeoff between the time it -takes to decode and the time it takes to build the table. If building the -table took no time (and if you had infinite memory), then there would only -be a first level table to cover all the way to the longest code. However, -building the table ends up taking a lot longer for more bits since short -codes are replicated many times in such a table. What inflate() does is -simply to make the number of bits in the first table a variable, and then -to set that variable for the maximum speed. - -For inflate, which has 286 possible codes for the literal/length tree, the size -of the first table is nine bits. Also the distance trees have 30 possible -values, and the size of the first table is six bits. Note that for each of -those cases, the table ended up one bit longer than the ``average'' code -length, i.e. the code length of an approximately flat code which would be a -little more than eight bits for 286 symbols and a little less than five bits -for 30 symbols. - - -2.2 More details on the inflate table lookup - -Ok, you want to know what this cleverly obfuscated inflate tree actually -looks like. You are correct that it's not a Huffman tree. It is simply a -lookup table for the first, let's say, nine bits of a Huffman symbol. The -symbol could be as short as one bit or as long as 15 bits. If a particular -symbol is shorter than nine bits, then that symbol's translation is duplicated -in all those entries that start with that symbol's bits. For example, if the -symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a -symbol is nine bits long, it appears in the table once. - -If the symbol is longer than nine bits, then that entry in the table points -to another similar table for the remaining bits. Again, there are duplicated -entries as needed. The idea is that most of the time the symbol will be short -and there will only be one table look up. (That's whole idea behind data -compression in the first place.) For the less frequent long symbols, there -will be two lookups. If you had a compression method with really long -symbols, you could have as many levels of lookups as is efficient. For -inflate, two is enough. - -So a table entry either points to another table (in which case nine bits in -the above example are gobbled), or it contains the translation for the symbol -and the number of bits to gobble. Then you start again with the next -ungobbled bit. - -You may wonder: why not just have one lookup table for how ever many bits the -longest symbol is? The reason is that if you do that, you end up spending -more time filling in duplicate symbol entries than you do actually decoding. -At least for deflate's output that generates new trees every several 10's of -kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code -would take too long if you're only decoding several thousand symbols. At the -other extreme, you could make a new table for every bit in the code. In fact, -that's essentially a Huffman tree. But then you spend too much time -traversing the tree while decoding, even for short symbols. - -So the number of bits for the first lookup table is a trade of the time to -fill out the table vs. the time spent looking at the second level and above of -the table. - -Here is an example, scaled down: - -The code being decoded, with 10 symbols, from 1 to 6 bits long: - -A: 0 -B: 10 -C: 1100 -D: 11010 -E: 11011 -F: 11100 -G: 11101 -H: 11110 -I: 111110 -J: 111111 - -Let's make the first table three bits long (eight entries): - -000: A,1 -001: A,1 -010: A,1 -011: A,1 -100: B,2 -101: B,2 -110: -> table X (gobble 3 bits) -111: -> table Y (gobble 3 bits) - -Each entry is what the bits decode as and how many bits that is, i.e. how -many bits to gobble. Or the entry points to another table, with the number of -bits to gobble implicit in the size of the table. - -Table X is two bits long since the longest code starting with 110 is five bits -long: - -00: C,1 -01: C,1 -10: D,2 -11: E,2 - -Table Y is three bits long since the longest code starting with 111 is six -bits long: - -000: F,2 -001: F,2 -010: G,2 -011: G,2 -100: H,2 -101: H,2 -110: I,3 -111: J,3 - -So what we have here are three tables with a total of 20 entries that had to -be constructed. That's compared to 64 entries for a single table. Or -compared to 16 entries for a Huffman tree (six two entry tables and one four -entry table). Assuming that the code ideally represents the probability of -the symbols, it takes on the average 1.25 lookups per symbol. That's compared -to one lookup for the single table, or 1.66 lookups per symbol for the -Huffman tree. - -There, I think that gives you a picture of what's going on. For inflate, the -meaning of a particular symbol is often more than just a letter. It can be a -byte (a "literal"), or it can be either a length or a distance which -indicates a base value and a number of bits to fetch after the code that is -added to the base value. Or it might be the special end-of-block code. The -data structures created in inftrees.c try to encode all that information -compactly in the tables. - - -Jean-loup Gailly Mark Adler -jloup@gzip.org madler@alumni.caltech.edu - - -References: - -[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data -Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, -pp. 337-343. - -``DEFLATE Compressed Data Format Specification'' available in -http://tools.ietf.org/html/rfc1951 diff --git a/libraries/zlib/compress.c b/libraries/zlib/compress.c deleted file mode 100644 index f43bacf7a..000000000 --- a/libraries/zlib/compress.c +++ /dev/null @@ -1,75 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - 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 0.1% larger than sourceLen plus - 12 bytes. 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. -*/ -int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen, int level) { - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong left; - - left = *destLen; - *destLen = 0; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; - sourceLen -= stream.avail_in; - } - err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); - } while (err == Z_OK); - - *destLen = stream.total_out; - deflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : err; -} - -/* =========================================================================== - */ -int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen) { - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound(uLong sourceLen) { - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/libraries/zlib/crc32.c b/libraries/zlib/crc32.c deleted file mode 100644 index 6c38f5c04..000000000 --- a/libraries/zlib/crc32.c +++ /dev/null @@ -1,1049 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * This interleaved implementation of a CRC makes use of pipelined multiple - * arithmetic-logic units, commonly found in modern CPU cores. It is due to - * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - MAKECRCH can be #defined to write out crc32.h. A main() routine is also - produced, so that this one source file can be compiled to an executable. - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for Z_U4, Z_U8, z_crc_t, and FAR definitions */ - - /* - A CRC of a message is computed on N braids of words in the message, where - each word consists of W bytes (4 or 8). If N is 3, for example, then three - running sparse CRCs are calculated respectively on each braid, at these - indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... - This is done starting at a word boundary, and continues until as many blocks - of N * W bytes as are available have been processed. The results are combined - into a single CRC at the end. For this code, N must be in the range 1..6 and - W must be 4 or 8. The upper limit on N can be increased if desired by adding - more #if blocks, extending the patterns apparent in the code. In addition, - crc32.h would need to be regenerated, if the maximum N value is increased. - - N and W are chosen empirically by benchmarking the execution time on a given - processor. The choices for N and W below were based on testing on Intel Kaby - Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 - Octeon II processors. The Intel, AMD, and ARM processors were all fastest - with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. - They were all tested with either gcc or clang, all using the -O3 optimization - level. Your mileage may vary. - */ - -/* Define N */ -#ifdef Z_TESTN -# define N Z_TESTN -#else -# define N 5 -#endif -#if N < 1 || N > 6 -# error N must be in 1..6 -#endif - -/* - z_crc_t must be at least 32 bits. z_word_t must be at least as long as - z_crc_t. It is assumed here that z_word_t is either 32 bits or 64 bits, and - that bytes are eight bits. - */ - -/* - Define W and the associated z_word_t type. If W is not defined, then a - braided calculation is not used, and the associated tables and code are not - compiled. - */ -#ifdef Z_TESTW -# if Z_TESTW-1 != -1 -# define W Z_TESTW -# endif -#else -# ifdef MAKECRCH -# define W 8 /* required for MAKECRCH */ -# else -# if defined(__x86_64__) || defined(__aarch64__) -# define W 8 -# else -# define W 4 -# endif -# endif -#endif -#ifdef W -# if W == 8 && defined(Z_U8) - typedef Z_U8 z_word_t; -# elif defined(Z_U4) -# undef W -# define W 4 - typedef Z_U4 z_word_t; -# else -# undef W -# endif -#endif - -/* If available, use the ARM processor CRC32 instruction. */ -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 -# define ARMCRC32 -#endif - -#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE)) -/* - Swap the bytes in a z_word_t to convert between little and big endian. Any - self-respecting compiler will optimize this to a single machine byte-swap - instruction, if one is available. This assumes that word_t is either 32 bits - or 64 bits. - */ -local z_word_t byte_swap(z_word_t word) { -# if W == 8 - return - (word & 0xff00000000000000) >> 56 | - (word & 0xff000000000000) >> 40 | - (word & 0xff0000000000) >> 24 | - (word & 0xff00000000) >> 8 | - (word & 0xff000000) << 8 | - (word & 0xff0000) << 24 | - (word & 0xff00) << 40 | - (word & 0xff) << 56; -# else /* W == 4 */ - return - (word & 0xff000000) >> 24 | - (word & 0xff0000) >> 8 | - (word & 0xff00) << 8 | - (word & 0xff) << 24; -# endif -} -#endif - -#ifdef DYNAMIC_CRC_TABLE -/* ========================================================================= - * Table of powers of x for combining CRC-32s, filled in by make_crc_table() - * below. - */ - local z_crc_t FAR x2n_table[32]; -#else -/* ========================================================================= - * Tables for byte-wise and braided CRC-32 calculations, and a table of powers - * of x for combining CRC-32s, all made by make_crc_table(). - */ -# include "crc32.h" -#endif - -/* CRC polynomial. */ -#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ - -/* - Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, - reflected. For speed, this requires that a not be zero. - */ -local z_crc_t multmodp(z_crc_t a, z_crc_t b) { - z_crc_t m, p; - - m = (z_crc_t)1 << 31; - p = 0; - for (;;) { - if (a & m) { - p ^= b; - if ((a & (m - 1)) == 0) - break; - } - m >>= 1; - b = b & 1 ? (b >> 1) ^ POLY : b >> 1; - } - return p; -} - -/* - Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been - initialized. - */ -local z_crc_t x2nmodp(z_off64_t n, unsigned k) { - z_crc_t p; - - p = (z_crc_t)1 << 31; /* x^0 == 1 */ - while (n) { - if (n & 1) - p = multmodp(x2n_table[k & 31], p); - n >>= 1; - k++; - } - return p; -} - -#ifdef DYNAMIC_CRC_TABLE -/* ========================================================================= - * Build the tables for byte-wise and braided CRC-32 calculations, and a table - * of powers of x for combining CRC-32s. - */ -local z_crc_t FAR crc_table[256]; -#ifdef W - local z_word_t FAR crc_big_table[256]; - local z_crc_t FAR crc_braid_table[W][256]; - local z_word_t FAR crc_braid_big_table[W][256]; - local void braid(z_crc_t [][256], z_word_t [][256], int, int); -#endif -#ifdef MAKECRCH - local void write_table(FILE *, const z_crc_t FAR *, int); - local void write_table32hi(FILE *, const z_word_t FAR *, int); - local void write_table64(FILE *, const z_word_t FAR *, int); -#endif /* MAKECRCH */ - -/* - Define a once() function depending on the availability of atomics. If this is - compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in - multiple threads, and if atomics are not available, then get_crc_table() must - be called to initialize the tables and must return before any threads are - allowed to compute or combine CRCs. - */ - -/* Definition of once functionality. */ -typedef struct once_s once_t; - -/* Check for the availability of atomics. */ -#if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \ - !defined(__STDC_NO_ATOMICS__) - -#include - -/* Structure for once(), which must be initialized with ONCE_INIT. */ -struct once_s { - atomic_flag begun; - atomic_int done; -}; -#define ONCE_INIT {ATOMIC_FLAG_INIT, 0} - -/* - Run the provided init() function exactly once, even if multiple threads - invoke once() at the same time. The state must be a once_t initialized with - ONCE_INIT. - */ -local void once(once_t *state, void (*init)(void)) { - if (!atomic_load(&state->done)) { - if (atomic_flag_test_and_set(&state->begun)) - while (!atomic_load(&state->done)) - ; - else { - init(); - atomic_store(&state->done, 1); - } - } -} - -#else /* no atomics */ - -/* Structure for once(), which must be initialized with ONCE_INIT. */ -struct once_s { - volatile int begun; - volatile int done; -}; -#define ONCE_INIT {0, 0} - -/* Test and set. Alas, not atomic, but tries to minimize the period of - vulnerability. */ -local int test_and_set(int volatile *flag) { - int was; - - was = *flag; - *flag = 1; - return was; -} - -/* Run the provided init() function once. This is not thread-safe. */ -local void once(once_t *state, void (*init)(void)) { - if (!state->done) { - if (test_and_set(&state->begun)) - while (!state->done) - ; - else { - init(); - state->done = 1; - } - } -} - -#endif - -/* State for once(). */ -local once_t made = ONCE_INIT; - -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x - (which is shifting right by one and adding x^32 mod p if the bit shifted out - is a one). We start with the highest power (least significant bit) of q and - repeat for all eight bits of q. - - The table is simply the CRC of all possible eight bit values. This is all the - information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. - */ - -local void make_crc_table(void) { - unsigned i, j, n; - z_crc_t p; - - /* initialize the CRC of bytes tables */ - for (i = 0; i < 256; i++) { - p = i; - for (j = 0; j < 8; j++) - p = p & 1 ? (p >> 1) ^ POLY : p >> 1; - crc_table[i] = p; -#ifdef W - crc_big_table[i] = byte_swap(p); -#endif - } - - /* initialize the x^2^n mod p(x) table */ - p = (z_crc_t)1 << 30; /* x^1 */ - x2n_table[0] = p; - for (n = 1; n < 32; n++) - x2n_table[n] = p = multmodp(p, p); - -#ifdef W - /* initialize the braiding tables -- needs x2n_table[] */ - braid(crc_braid_table, crc_braid_big_table, N, W); -#endif - -#ifdef MAKECRCH - { - /* - The crc32.h header file contains tables for both 32-bit and 64-bit - z_word_t's, and so requires a 64-bit type be available. In that case, - z_word_t must be defined to be 64-bits. This code then also generates - and writes out the tables for the case that z_word_t is 32 bits. - */ -#if !defined(W) || W != 8 -# error Need a 64-bit integer type in order to generate crc32.h. -#endif - FILE *out; - int k, n; - z_crc_t ltl[8][256]; - z_word_t big[8][256]; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - - /* write out little-endian CRC table to crc32.h */ - fprintf(out, - "/* crc32.h -- tables for rapid CRC calculation\n" - " * Generated automatically by crc32.c\n */\n" - "\n" - "local const z_crc_t FAR crc_table[] = {\n" - " "); - write_table(out, crc_table, 256); - fprintf(out, - "};\n"); - - /* write out big-endian CRC table for 64-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#ifdef W\n" - "\n" - "#if W == 8\n" - "\n" - "local const z_word_t FAR crc_big_table[] = {\n" - " "); - write_table64(out, crc_big_table, 256); - fprintf(out, - "};\n"); - - /* write out big-endian CRC table for 32-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#else /* W == 4 */\n" - "\n" - "local const z_word_t FAR crc_big_table[] = {\n" - " "); - write_table32hi(out, crc_big_table, 256); - fprintf(out, - "};\n" - "\n" - "#endif\n"); - - /* write out braid tables for each value of N */ - for (n = 1; n <= 6; n++) { - fprintf(out, - "\n" - "#if N == %d\n", n); - - /* compute braid tables for this N and 64-bit word_t */ - braid(ltl, big, n, 8); - - /* write out braid tables for 64-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#if W == 8\n" - "\n" - "local const z_crc_t FAR crc_braid_table[][256] = {\n"); - for (k = 0; k < 8; k++) { - fprintf(out, " {"); - write_table(out, ltl[k], 256); - fprintf(out, "}%s", k < 7 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); - for (k = 0; k < 8; k++) { - fprintf(out, " {"); - write_table64(out, big[k], 256); - fprintf(out, "}%s", k < 7 ? ",\n" : ""); - } - fprintf(out, - "};\n"); - - /* compute braid tables for this N and 32-bit word_t */ - braid(ltl, big, n, 4); - - /* write out braid tables for 32-bit z_word_t to crc32.h */ - fprintf(out, - "\n" - "#else /* W == 4 */\n" - "\n" - "local const z_crc_t FAR crc_braid_table[][256] = {\n"); - for (k = 0; k < 4; k++) { - fprintf(out, " {"); - write_table(out, ltl[k], 256); - fprintf(out, "}%s", k < 3 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "local const z_word_t FAR crc_braid_big_table[][256] = {\n"); - for (k = 0; k < 4; k++) { - fprintf(out, " {"); - write_table32hi(out, big[k], 256); - fprintf(out, "}%s", k < 3 ? ",\n" : ""); - } - fprintf(out, - "};\n" - "\n" - "#endif\n" - "\n" - "#endif\n"); - } - fprintf(out, - "\n" - "#endif\n"); - - /* write out zeros operator table to crc32.h */ - fprintf(out, - "\n" - "local const z_crc_t FAR x2n_table[] = {\n" - " "); - write_table(out, x2n_table, 32); - fprintf(out, - "};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH - -/* - Write the 32-bit values in table[0..k-1] to out, five per line in - hexadecimal separated by commas. - */ -local void write_table(FILE *out, const z_crc_t FAR *table, int k) { - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); -} - -/* - Write the high 32-bits of each value in table[0..k-1] to out, five per line - in hexadecimal separated by commas. - */ -local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) { - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : " ", - (unsigned long)(table[n] >> 32), - n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); -} - -/* - Write the 64-bit values in table[0..k-1] to out, three per line in - hexadecimal separated by commas. This assumes that if there is a 64-bit - type, then there is also a long long integer type, and it is at least 64 - bits. If not, then the type cast and format string can be adjusted - accordingly. - */ -local void write_table64(FILE *out, const z_word_t FAR *table, int k) { - int n; - - for (n = 0; n < k; n++) - fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : " ", - (unsigned long long)(table[n]), - n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); -} - -/* Actually do the deed. */ -int main(void) { - make_crc_table(); - return 0; -} - -#endif /* MAKECRCH */ - -#ifdef W -/* - Generate the little and big-endian braid tables for the given n and z_word_t - size w. Each array must have room for w blocks of 256 elements. - */ -local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) { - int k; - z_crc_t i, p, q; - for (k = 0; k < w; k++) { - p = x2nmodp((n * w + 3 - k) << 3, 0); - ltl[k][0] = 0; - big[w - 1 - k][0] = 0; - for (i = 1; i < 256; i++) { - ltl[k][i] = q = multmodp(i << 24, p); - big[w - 1 - k][i] = byte_swap(q); - } - } -} -#endif - -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32(), and to force the - * generation of the CRC tables in a threaded application. - */ -const z_crc_t FAR * ZEXPORT get_crc_table(void) { -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return (const z_crc_t FAR *)crc_table; -} - -/* ========================================================================= - * Use ARM machine instructions if available. This will compute the CRC about - * ten times faster than the braided calculation. This code does not check for - * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will - * only be defined if the compilation specifies an ARM processor architecture - * that has the instructions. For example, compiling with -march=armv8.1-a or - * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 - * instructions. - */ -#ifdef ARMCRC32 - -/* - Constants empirically determined to maximize speed. These values are from - measurements on a Cortex-A57. Your mileage may vary. - */ -#define Z_BATCH 3990 /* number of words in a batch */ -#define Z_BATCH_ZEROS 0xa10d3d0c /* computed from Z_BATCH = 3990 */ -#define Z_BATCH_MIN 800 /* fewest words in a final batch */ - -unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, - z_size_t len) { - z_crc_t val; - z_word_t crc1, crc2; - const z_word_t *word; - z_word_t val0, val1, val2; - z_size_t last, last2, i; - z_size_t num; - - /* Return initial CRC, if requested. */ - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ - crc = (~crc) & 0xffffffff; - - /* Compute the CRC up to a word boundary. */ - while (len && ((z_size_t)buf & 7) != 0) { - len--; - val = *buf++; - __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); - } - - /* Prepare to compute the CRC on full 64-bit words word[0..num-1]. */ - word = (z_word_t const *)buf; - num = len >> 3; - len &= 7; - - /* Do three interleaved CRCs to realize the throughput of one crc32x - instruction per cycle. Each CRC is calculated on Z_BATCH words. The - three CRCs are combined into a single CRC after each set of batches. */ - while (num >= 3 * Z_BATCH) { - crc1 = 0; - crc2 = 0; - for (i = 0; i < Z_BATCH; i++) { - val0 = word[i]; - val1 = word[i + Z_BATCH]; - val2 = word[i + 2 * Z_BATCH]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); - } - word += 3 * Z_BATCH; - num -= 3 * Z_BATCH; - crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc1; - crc = multmodp(Z_BATCH_ZEROS, crc) ^ crc2; - } - - /* Do one last smaller batch with the remaining words, if there are enough - to pay for the combination of CRCs. */ - last = num / 3; - if (last >= Z_BATCH_MIN) { - last2 = last << 1; - crc1 = 0; - crc2 = 0; - for (i = 0; i < last; i++) { - val0 = word[i]; - val1 = word[i + last]; - val2 = word[i + last2]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc1) : "r"(val1)); - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc2) : "r"(val2)); - } - word += 3 * last; - num -= 3 * last; - val = x2nmodp(last, 6); - crc = multmodp(val, crc) ^ crc1; - crc = multmodp(val, crc) ^ crc2; - } - - /* Compute the CRC on any remaining words. */ - for (i = 0; i < num; i++) { - val0 = word[i]; - __asm__ volatile("crc32x %w0, %w0, %x1" : "+r"(crc) : "r"(val0)); - } - word += num; - - /* Complete the CRC on any remaining bytes. */ - buf = (const unsigned char FAR *)word; - while (len) { - len--; - val = *buf++; - __asm__ volatile("crc32b %w0, %w0, %w1" : "+r"(crc) : "r"(val)); - } - - /* Return the CRC, post-conditioned. */ - return crc ^ 0xffffffff; -} - -#else - -#ifdef W - -/* - Return the CRC of the W bytes in the word_t data, taking the - least-significant byte of the word as the first byte of data, without any pre - or post conditioning. This is used to combine the CRCs of each braid. - */ -local z_crc_t crc_word(z_word_t data) { - int k; - for (k = 0; k < W; k++) - data = (data >> 8) ^ crc_table[data & 0xff]; - return (z_crc_t)data; -} - -local z_word_t crc_word_big(z_word_t data) { - int k; - for (k = 0; k < W; k++) - data = (data << 8) ^ - crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; - return data; -} - -#endif - -/* ========================================================================= */ -unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf, - z_size_t len) { - /* Return initial CRC, if requested. */ - if (buf == Z_NULL) return 0; - -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - - /* Pre-condition the CRC */ - crc = (~crc) & 0xffffffff; - -#ifdef W - - /* If provided enough bytes, do a braided CRC calculation. */ - if (len >= N * W + W - 1) { - z_size_t blks; - z_word_t const *words; - unsigned endian; - int k; - - /* Compute the CRC up to a z_word_t boundary. */ - while (len && ((z_size_t)buf & (W - 1)) != 0) { - len--; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - - /* Compute the CRC on as many N z_word_t blocks as are available. */ - blks = len / (N * W); - len -= blks * N * W; - words = (z_word_t const *)buf; - - /* Do endian check at execution time instead of compile time, since ARM - processors can change the endianness at execution time. If the - compiler knows what the endianness will be, it can optimize out the - check and the unused branch. */ - endian = 1; - if (*(unsigned char *)&endian) { - /* Little endian. */ - - z_crc_t crc0; - z_word_t word0; -#if N > 1 - z_crc_t crc1; - z_word_t word1; -#if N > 2 - z_crc_t crc2; - z_word_t word2; -#if N > 3 - z_crc_t crc3; - z_word_t word3; -#if N > 4 - z_crc_t crc4; - z_word_t word4; -#if N > 5 - z_crc_t crc5; - z_word_t word5; -#endif -#endif -#endif -#endif -#endif - - /* Initialize the CRC for each braid. */ - crc0 = crc; -#if N > 1 - crc1 = 0; -#if N > 2 - crc2 = 0; -#if N > 3 - crc3 = 0; -#if N > 4 - crc4 = 0; -#if N > 5 - crc5 = 0; -#endif -#endif -#endif -#endif -#endif - - /* - Process the first blks-1 blocks, computing the CRCs on each braid - independently. - */ - while (--blks) { - /* Load the word for each braid into registers. */ - word0 = crc0 ^ words[0]; -#if N > 1 - word1 = crc1 ^ words[1]; -#if N > 2 - word2 = crc2 ^ words[2]; -#if N > 3 - word3 = crc3 ^ words[3]; -#if N > 4 - word4 = crc4 ^ words[4]; -#if N > 5 - word5 = crc5 ^ words[5]; -#endif -#endif -#endif -#endif -#endif - words += N; - - /* Compute and update the CRC for each word. The loop should - get unrolled. */ - crc0 = crc_braid_table[0][word0 & 0xff]; -#if N > 1 - crc1 = crc_braid_table[0][word1 & 0xff]; -#if N > 2 - crc2 = crc_braid_table[0][word2 & 0xff]; -#if N > 3 - crc3 = crc_braid_table[0][word3 & 0xff]; -#if N > 4 - crc4 = crc_braid_table[0][word4 & 0xff]; -#if N > 5 - crc5 = crc_braid_table[0][word5 & 0xff]; -#endif -#endif -#endif -#endif -#endif - for (k = 1; k < W; k++) { - crc0 ^= crc_braid_table[k][(word0 >> (k << 3)) & 0xff]; -#if N > 1 - crc1 ^= crc_braid_table[k][(word1 >> (k << 3)) & 0xff]; -#if N > 2 - crc2 ^= crc_braid_table[k][(word2 >> (k << 3)) & 0xff]; -#if N > 3 - crc3 ^= crc_braid_table[k][(word3 >> (k << 3)) & 0xff]; -#if N > 4 - crc4 ^= crc_braid_table[k][(word4 >> (k << 3)) & 0xff]; -#if N > 5 - crc5 ^= crc_braid_table[k][(word5 >> (k << 3)) & 0xff]; -#endif -#endif -#endif -#endif -#endif - } - } - - /* - Process the last block, combining the CRCs of the N braids at the - same time. - */ - crc = crc_word(crc0 ^ words[0]); -#if N > 1 - crc = crc_word(crc1 ^ words[1] ^ crc); -#if N > 2 - crc = crc_word(crc2 ^ words[2] ^ crc); -#if N > 3 - crc = crc_word(crc3 ^ words[3] ^ crc); -#if N > 4 - crc = crc_word(crc4 ^ words[4] ^ crc); -#if N > 5 - crc = crc_word(crc5 ^ words[5] ^ crc); -#endif -#endif -#endif -#endif -#endif - words += N; - } - else { - /* Big endian. */ - - z_word_t crc0, word0, comb; -#if N > 1 - z_word_t crc1, word1; -#if N > 2 - z_word_t crc2, word2; -#if N > 3 - z_word_t crc3, word3; -#if N > 4 - z_word_t crc4, word4; -#if N > 5 - z_word_t crc5, word5; -#endif -#endif -#endif -#endif -#endif - - /* Initialize the CRC for each braid. */ - crc0 = byte_swap(crc); -#if N > 1 - crc1 = 0; -#if N > 2 - crc2 = 0; -#if N > 3 - crc3 = 0; -#if N > 4 - crc4 = 0; -#if N > 5 - crc5 = 0; -#endif -#endif -#endif -#endif -#endif - - /* - Process the first blks-1 blocks, computing the CRCs on each braid - independently. - */ - while (--blks) { - /* Load the word for each braid into registers. */ - word0 = crc0 ^ words[0]; -#if N > 1 - word1 = crc1 ^ words[1]; -#if N > 2 - word2 = crc2 ^ words[2]; -#if N > 3 - word3 = crc3 ^ words[3]; -#if N > 4 - word4 = crc4 ^ words[4]; -#if N > 5 - word5 = crc5 ^ words[5]; -#endif -#endif -#endif -#endif -#endif - words += N; - - /* Compute and update the CRC for each word. The loop should - get unrolled. */ - crc0 = crc_braid_big_table[0][word0 & 0xff]; -#if N > 1 - crc1 = crc_braid_big_table[0][word1 & 0xff]; -#if N > 2 - crc2 = crc_braid_big_table[0][word2 & 0xff]; -#if N > 3 - crc3 = crc_braid_big_table[0][word3 & 0xff]; -#if N > 4 - crc4 = crc_braid_big_table[0][word4 & 0xff]; -#if N > 5 - crc5 = crc_braid_big_table[0][word5 & 0xff]; -#endif -#endif -#endif -#endif -#endif - for (k = 1; k < W; k++) { - crc0 ^= crc_braid_big_table[k][(word0 >> (k << 3)) & 0xff]; -#if N > 1 - crc1 ^= crc_braid_big_table[k][(word1 >> (k << 3)) & 0xff]; -#if N > 2 - crc2 ^= crc_braid_big_table[k][(word2 >> (k << 3)) & 0xff]; -#if N > 3 - crc3 ^= crc_braid_big_table[k][(word3 >> (k << 3)) & 0xff]; -#if N > 4 - crc4 ^= crc_braid_big_table[k][(word4 >> (k << 3)) & 0xff]; -#if N > 5 - crc5 ^= crc_braid_big_table[k][(word5 >> (k << 3)) & 0xff]; -#endif -#endif -#endif -#endif -#endif - } - } - - /* - Process the last block, combining the CRCs of the N braids at the - same time. - */ - comb = crc_word_big(crc0 ^ words[0]); -#if N > 1 - comb = crc_word_big(crc1 ^ words[1] ^ comb); -#if N > 2 - comb = crc_word_big(crc2 ^ words[2] ^ comb); -#if N > 3 - comb = crc_word_big(crc3 ^ words[3] ^ comb); -#if N > 4 - comb = crc_word_big(crc4 ^ words[4] ^ comb); -#if N > 5 - comb = crc_word_big(crc5 ^ words[5] ^ comb); -#endif -#endif -#endif -#endif -#endif - words += N; - crc = byte_swap(comb); - } - - /* - Update the pointer to the remaining bytes to process. - */ - buf = (unsigned char const *)words; - } - -#endif /* W */ - - /* Complete the computation of the CRC on any remaining bytes. */ - while (len >= 8) { - len -= 8; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - while (len) { - len--; - crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; - } - - /* Return the CRC, post-conditioned. */ - return crc ^ 0xffffffff; -} - -#endif - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, - uInt len) { - return crc32_z(crc, buf, len); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) { -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) { - return crc32_combine64(crc1, crc2, (z_off64_t)len2); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) { -#ifdef DYNAMIC_CRC_TABLE - once(&made, make_crc_table); -#endif /* DYNAMIC_CRC_TABLE */ - return x2nmodp(len2, 3); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_gen(z_off_t len2) { - return crc32_combine_gen64((z_off64_t)len2); -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) { - return multmodp(op, crc1) ^ (crc2 & 0xffffffff); -} diff --git a/libraries/zlib/crc32.h b/libraries/zlib/crc32.h deleted file mode 100644 index 137df68d6..000000000 --- a/libraries/zlib/crc32.h +++ /dev/null @@ -1,9446 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const z_crc_t FAR crc_table[] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}; - -#ifdef W - -#if W == 8 - -local const z_word_t FAR crc_big_table[] = { - 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, - 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, - 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, - 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, - 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, - 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, - 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, - 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, - 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, - 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, - 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, - 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, - 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, - 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, - 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, - 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, - 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, - 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, - 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, - 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, - 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, - 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, - 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, - 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, - 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, - 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, - 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, - 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, - 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, - 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, - 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, - 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, - 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, - 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, - 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, - 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, - 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, - 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, - 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, - 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, - 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, - 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, - 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, - 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, - 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, - 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, - 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, - 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, - 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, - 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, - 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, - 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, - 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, - 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, - 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, - 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, - 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, - 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, - 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, - 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, - 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, - 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, - 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, - 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, - 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, - 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, - 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, - 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, - 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, - 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, - 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, - 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, - 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, - 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, - 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, - 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, - 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, - 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, - 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, - 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, - 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, - 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, - 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, - 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, - 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, - 0x8def022d00000000}; - -#else /* W == 4 */ - -local const z_word_t FAR crc_big_table[] = { - 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d}; - -#endif - -#if N == 1 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, - 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, - 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, - 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, - 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, - 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, - 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, - 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, - 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, - 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, - 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, - 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, - 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, - 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, - 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, - 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, - 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, - 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, - 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, - 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, - 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, - 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, - 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, - 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, - 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, - 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, - 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, - 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, - 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, - 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, - 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, - 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, - 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, - 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, - 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, - 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, - 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, - 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, - 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, - 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, - 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, - 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, - 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, - 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, - 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, - 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, - 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, - 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, - 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, - 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, - 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, - 0x264b06e6}, - {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, - 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, - 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, - 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, - 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, - 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, - 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, - 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, - 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, - 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, - 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, - 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, - 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, - 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, - 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, - 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, - 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, - 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, - 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, - 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, - 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, - 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, - 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, - 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, - 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, - 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, - 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, - 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, - 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, - 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, - 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, - 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, - 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, - 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, - 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, - 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, - 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, - 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, - 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, - 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, - 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, - 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, - 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, - 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, - 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, - 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, - 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, - 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, - 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, - 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, - 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, - 0x92364a30}, - {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, - 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, - 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, - 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, - 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, - 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, - 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, - 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, - 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, - 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, - 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, - 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, - 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, - 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, - 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, - 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, - 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, - 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, - 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, - 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, - 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, - 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, - 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, - 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, - 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, - 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, - 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, - 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, - 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, - 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, - 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, - 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, - 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, - 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, - 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, - 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, - 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, - 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, - 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, - 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, - 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, - 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, - 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, - 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, - 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, - 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, - 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, - 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, - 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, - 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, - 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, - 0xe4c4abcc}, - {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, - 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, - 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, - 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, - 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, - 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, - 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, - 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, - 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, - 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, - 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, - 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, - 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, - 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, - 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, - 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, - 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, - 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, - 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, - 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, - 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, - 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, - 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, - 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, - 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, - 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, - 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, - 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, - 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, - 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, - 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, - 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, - 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, - 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, - 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, - 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, - 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, - 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, - 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, - 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, - 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, - 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, - 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, - 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, - 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, - 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, - 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, - 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, - 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, - 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, - 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, - 0xca64c78c}, - {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1}, - {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed}, - {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72}, - {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, - 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, - 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, - 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, - 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, - 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, - 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, - 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, - 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, - 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, - 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, - 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, - 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, - 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, - 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, - 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, - 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, - 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, - 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, - 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, - 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, - 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, - 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, - 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, - 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, - 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, - 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, - 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, - 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, - 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, - 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, - 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, - 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, - 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, - 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, - 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, - 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, - 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, - 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, - 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, - 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, - 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, - 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, - 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, - 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, - 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, - 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, - 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, - 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, - 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, - 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, - 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, - 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, - 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, - 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, - 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, - 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, - 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, - 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, - 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, - 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, - 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, - 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, - 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, - 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, - 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, - 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, - 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, - 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, - 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, - 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, - 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, - 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, - 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, - 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, - 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, - 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, - 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, - 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, - 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, - 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, - 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, - 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, - 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, - 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, - 0x8def022d00000000}, - {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, - 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, - 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, - 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, - 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, - 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, - 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, - 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, - 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, - 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, - 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, - 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, - 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, - 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, - 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, - 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, - 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, - 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, - 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, - 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, - 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, - 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, - 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, - 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, - 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, - 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, - 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, - 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, - 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, - 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, - 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, - 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, - 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, - 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, - 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, - 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, - 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, - 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, - 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, - 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, - 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, - 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, - 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, - 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, - 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, - 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, - 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, - 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, - 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, - 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, - 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, - 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, - 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, - 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, - 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, - 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, - 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, - 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, - 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, - 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, - 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, - 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, - 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, - 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, - 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, - 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, - 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, - 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, - 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, - 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, - 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, - 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, - 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, - 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, - 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, - 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, - 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, - 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, - 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, - 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, - 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, - 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, - 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, - 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, - 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, - 0x72fd249300000000}, - {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, - 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, - 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, - 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, - 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, - 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, - 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, - 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, - 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, - 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, - 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, - 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, - 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, - 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, - 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, - 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, - 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, - 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, - 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, - 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, - 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, - 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, - 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, - 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, - 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, - 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, - 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, - 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, - 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, - 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, - 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, - 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, - 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, - 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, - 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, - 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, - 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, - 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, - 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, - 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, - 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, - 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, - 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, - 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, - 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, - 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, - 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, - 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, - 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, - 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, - 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, - 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, - 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, - 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, - 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, - 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, - 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, - 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, - 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, - 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, - 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, - 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, - 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, - 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, - 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, - 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, - 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, - 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, - 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, - 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, - 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, - 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, - 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, - 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, - 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, - 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, - 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, - 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, - 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, - 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, - 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, - 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, - 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, - 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, - 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, - 0xed3498be00000000}, - {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, - 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, - 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, - 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, - 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, - 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, - 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, - 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, - 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, - 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, - 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, - 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, - 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, - 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, - 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, - 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, - 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, - 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, - 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, - 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, - 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, - 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, - 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, - 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, - 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, - 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, - 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, - 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, - 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, - 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, - 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, - 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, - 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, - 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, - 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, - 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, - 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, - 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, - 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, - 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, - 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, - 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, - 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, - 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, - 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, - 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, - 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, - 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, - 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, - 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, - 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, - 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, - 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, - 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, - 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, - 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, - 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, - 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, - 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, - 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, - 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, - 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, - 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, - 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, - 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, - 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, - 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, - 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, - 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, - 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, - 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, - 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, - 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, - 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, - 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, - 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, - 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, - 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, - 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, - 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, - 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, - 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, - 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, - 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, - 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, - 0xf10605de00000000}, - {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, - 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, - 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, - 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, - 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, - 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, - 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, - 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, - 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, - 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, - 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, - 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, - 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, - 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, - 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, - 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, - 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, - 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, - 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, - 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, - 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, - 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, - 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, - 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, - 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, - 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, - 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, - 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, - 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, - 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, - 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, - 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, - 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, - 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, - 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, - 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, - 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, - 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, - 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, - 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, - 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, - 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, - 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, - 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, - 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, - 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, - 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, - 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, - 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, - 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, - 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, - 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, - 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, - 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, - 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, - 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, - 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, - 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, - 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, - 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, - 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, - 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, - 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, - 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, - 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, - 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, - 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, - 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, - 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, - 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, - 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, - 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, - 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, - 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, - 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, - 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, - 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, - 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, - 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, - 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, - 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, - 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, - 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, - 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, - 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, - 0x8cc764ca00000000}, - {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, - 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, - 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, - 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, - 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, - 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, - 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, - 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, - 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, - 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, - 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, - 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, - 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, - 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, - 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, - 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, - 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, - 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, - 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, - 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, - 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, - 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, - 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, - 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, - 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, - 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, - 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, - 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, - 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, - 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, - 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, - 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, - 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, - 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, - 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, - 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, - 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, - 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, - 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, - 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, - 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, - 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, - 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, - 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, - 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, - 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, - 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, - 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, - 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, - 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, - 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, - 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, - 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, - 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, - 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, - 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, - 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, - 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, - 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, - 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, - 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, - 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, - 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, - 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, - 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, - 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, - 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, - 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, - 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, - 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, - 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, - 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, - 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, - 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, - 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, - 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, - 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, - 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, - 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, - 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, - 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, - 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, - 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, - 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, - 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, - 0xccabc4e400000000}, - {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, - 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, - 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, - 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, - 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, - 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, - 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, - 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, - 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, - 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, - 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, - 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, - 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, - 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, - 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, - 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, - 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, - 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, - 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, - 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, - 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, - 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, - 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, - 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, - 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, - 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, - 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, - 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, - 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, - 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, - 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, - 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, - 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, - 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, - 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, - 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, - 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, - 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, - 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, - 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, - 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, - 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, - 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, - 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, - 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, - 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, - 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, - 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, - 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, - 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, - 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, - 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, - 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, - 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, - 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, - 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, - 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, - 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, - 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, - 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, - 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, - 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, - 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, - 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, - 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, - 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, - 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, - 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, - 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, - 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, - 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, - 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, - 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, - 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, - 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, - 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, - 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, - 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, - 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, - 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, - 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, - 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, - 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, - 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, - 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, - 0x304a369200000000}, - {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, - 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, - 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, - 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, - 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, - 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, - 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, - 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, - 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, - 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, - 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, - 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, - 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, - 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, - 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, - 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, - 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, - 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, - 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, - 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, - 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, - 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, - 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, - 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, - 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, - 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, - 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, - 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, - 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, - 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, - 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, - 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, - 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, - 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, - 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, - 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, - 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, - 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, - 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, - 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, - 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, - 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, - 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, - 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, - 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, - 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, - 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, - 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, - 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, - 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, - 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, - 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, - 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, - 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, - 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, - 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, - 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, - 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, - 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, - 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, - 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, - 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, - 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, - 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, - 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, - 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, - 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, - 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, - 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, - 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, - 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, - 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, - 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, - 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, - 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, - 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, - 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, - 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, - 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, - 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, - 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, - 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, - 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, - 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, - 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, - 0xe6064b2600000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1}, - {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed}, - {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72}, - {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d}, - {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, - 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, - 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, - 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, - 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, - 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, - 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, - 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, - 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, - 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, - 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, - 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, - 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, - 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, - 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, - 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, - 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, - 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, - 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, - 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, - 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, - 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, - 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, - 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, - 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, - 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, - 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, - 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, - 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, - 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, - 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, - 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, - 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, - 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, - 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, - 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, - 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, - 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, - 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, - 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, - 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, - 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, - 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, - 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, - 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, - 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, - 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, - 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, - 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, - 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, - 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, - 0x72fd2493}, - {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, - 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, - 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, - 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, - 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, - 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, - 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, - 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, - 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, - 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, - 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, - 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, - 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, - 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, - 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, - 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, - 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, - 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, - 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, - 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, - 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, - 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, - 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, - 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, - 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, - 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, - 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, - 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, - 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, - 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, - 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, - 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, - 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, - 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, - 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, - 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, - 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, - 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, - 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, - 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, - 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, - 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, - 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, - 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, - 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, - 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, - 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, - 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, - 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, - 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, - 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, - 0xed3498be}, - {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, - 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, - 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, - 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, - 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, - 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, - 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, - 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, - 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, - 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, - 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, - 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, - 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, - 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, - 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, - 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, - 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, - 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, - 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, - 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, - 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, - 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, - 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, - 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, - 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, - 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, - 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, - 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, - 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, - 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, - 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, - 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, - 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, - 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, - 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, - 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, - 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, - 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, - 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, - 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, - 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, - 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, - 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, - 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, - 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, - 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, - 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, - 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, - 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, - 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, - 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, - 0xf10605de}}; - -#endif - -#endif - -#if N == 2 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, - 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, - 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, - 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, - 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, - 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, - 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, - 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, - 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, - 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, - 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, - 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, - 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, - 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, - 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, - 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, - 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, - 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, - 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, - 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, - 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, - 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, - 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, - 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, - 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, - 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, - 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, - 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, - 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, - 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, - 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, - 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, - 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, - 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, - 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, - 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, - 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, - 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, - 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, - 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, - 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, - 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, - 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, - 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, - 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, - 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, - 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, - 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, - 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, - 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, - 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, - 0x0d7139d7}, - {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, - 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, - 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, - 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, - 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, - 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, - 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, - 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, - 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, - 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, - 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, - 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, - 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, - 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, - 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, - 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, - 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, - 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, - 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, - 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, - 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, - 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, - 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, - 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, - 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, - 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, - 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, - 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, - 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, - 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, - 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, - 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, - 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, - 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, - 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, - 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, - 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, - 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, - 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, - 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, - 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, - 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, - 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, - 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, - 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, - 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, - 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, - 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, - 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, - 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, - 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, - 0x1c53e98a}, - {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, - 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, - 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, - 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, - 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, - 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, - 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, - 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, - 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, - 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, - 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, - 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, - 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, - 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, - 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, - 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, - 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, - 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, - 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, - 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, - 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, - 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, - 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, - 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, - 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, - 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, - 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, - 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, - 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, - 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, - 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, - 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, - 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, - 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, - 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, - 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, - 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, - 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, - 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, - 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, - 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, - 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, - 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, - 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, - 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, - 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, - 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, - 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, - 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, - 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, - 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, - 0x3f88e851}, - {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, - 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, - 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, - 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, - 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, - 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, - 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, - 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, - 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, - 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, - 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, - 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, - 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, - 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, - 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, - 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, - 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, - 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, - 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, - 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, - 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, - 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, - 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, - 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, - 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, - 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, - 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, - 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, - 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, - 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, - 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, - 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, - 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, - 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, - 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, - 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, - 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, - 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, - 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, - 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, - 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, - 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, - 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, - 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, - 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, - 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, - 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, - 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, - 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, - 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, - 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, - 0x3dee8ca6}, - {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, - 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, - 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, - 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, - 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, - 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, - 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, - 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, - 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, - 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, - 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, - 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, - 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, - 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, - 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, - 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, - 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, - 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, - 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, - 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, - 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, - 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, - 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, - 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, - 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, - 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, - 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, - 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, - 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, - 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, - 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, - 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, - 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, - 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, - 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, - 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, - 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, - 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, - 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, - 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, - 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, - 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, - 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, - 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, - 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, - 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, - 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, - 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, - 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, - 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, - 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, - 0x36197165}, - {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, - 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, - 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, - 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, - 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, - 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, - 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, - 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, - 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, - 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, - 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, - 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, - 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, - 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, - 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, - 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, - 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, - 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, - 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, - 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, - 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, - 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, - 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, - 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, - 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, - 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, - 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, - 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, - 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, - 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, - 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, - 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, - 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, - 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, - 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, - 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, - 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, - 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, - 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, - 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, - 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, - 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, - 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, - 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, - 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, - 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, - 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, - 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, - 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, - 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, - 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, - 0x1a3b93aa}, - {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, - 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, - 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, - 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, - 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, - 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, - 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, - 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, - 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, - 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, - 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, - 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, - 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, - 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, - 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, - 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, - 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, - 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, - 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, - 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, - 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, - 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, - 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, - 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, - 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, - 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, - 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, - 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, - 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, - 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, - 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, - 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, - 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, - 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, - 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, - 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, - 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, - 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, - 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, - 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, - 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, - 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, - 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, - 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, - 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, - 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, - 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, - 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, - 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, - 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, - 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, - 0xe147d714}, - {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, - 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, - 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, - 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, - 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, - 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, - 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, - 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, - 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, - 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, - 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, - 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, - 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, - 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, - 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, - 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, - 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, - 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, - 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, - 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, - 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, - 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, - 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, - 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, - 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, - 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, - 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, - 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, - 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, - 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, - 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, - 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, - 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, - 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, - 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, - 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, - 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, - 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, - 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, - 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, - 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, - 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, - 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, - 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, - 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, - 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, - 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, - 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, - 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, - 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, - 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, - 0x494f0c4b}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, - 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, - 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, - 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, - 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, - 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, - 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, - 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, - 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, - 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, - 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, - 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, - 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, - 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, - 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, - 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, - 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, - 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, - 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, - 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, - 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, - 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, - 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, - 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, - 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, - 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, - 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, - 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, - 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, - 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, - 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, - 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, - 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, - 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, - 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, - 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, - 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, - 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, - 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, - 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, - 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, - 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, - 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, - 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, - 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, - 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, - 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, - 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, - 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, - 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, - 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, - 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, - 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, - 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, - 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, - 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, - 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, - 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, - 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, - 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, - 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, - 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, - 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, - 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, - 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, - 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, - 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, - 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, - 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, - 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, - 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, - 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, - 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, - 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, - 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, - 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, - 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, - 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, - 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, - 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, - 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, - 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, - 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, - 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, - 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, - 0x4b0c4f4900000000}, - {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, - 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, - 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, - 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, - 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, - 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, - 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, - 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, - 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, - 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, - 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, - 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, - 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, - 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, - 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, - 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, - 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, - 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, - 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, - 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, - 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, - 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, - 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, - 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, - 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, - 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, - 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, - 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, - 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, - 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, - 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, - 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, - 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, - 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, - 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, - 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, - 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, - 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, - 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, - 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, - 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, - 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, - 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, - 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, - 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, - 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, - 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, - 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, - 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, - 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, - 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, - 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, - 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, - 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, - 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, - 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, - 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, - 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, - 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, - 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, - 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, - 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, - 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, - 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, - 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, - 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, - 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, - 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, - 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, - 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, - 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, - 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, - 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, - 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, - 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, - 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, - 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, - 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, - 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, - 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, - 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, - 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, - 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, - 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, - 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, - 0x14d747e100000000}, - {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, - 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, - 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, - 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, - 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, - 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, - 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, - 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, - 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, - 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, - 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, - 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, - 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, - 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, - 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, - 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, - 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, - 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, - 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, - 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, - 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, - 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, - 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, - 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, - 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, - 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, - 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, - 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, - 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, - 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, - 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, - 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, - 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, - 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, - 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, - 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, - 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, - 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, - 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, - 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, - 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, - 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, - 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, - 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, - 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, - 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, - 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, - 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, - 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, - 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, - 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, - 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, - 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, - 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, - 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, - 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, - 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, - 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, - 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, - 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, - 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, - 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, - 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, - 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, - 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, - 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, - 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, - 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, - 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, - 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, - 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, - 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, - 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, - 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, - 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, - 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, - 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, - 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, - 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, - 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, - 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, - 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, - 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, - 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, - 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, - 0xaa933b1a00000000}, - {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, - 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, - 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, - 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, - 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, - 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, - 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, - 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, - 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, - 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, - 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, - 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, - 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, - 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, - 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, - 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, - 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, - 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, - 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, - 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, - 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, - 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, - 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, - 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, - 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, - 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, - 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, - 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, - 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, - 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, - 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, - 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, - 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, - 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, - 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, - 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, - 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, - 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, - 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, - 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, - 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, - 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, - 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, - 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, - 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, - 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, - 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, - 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, - 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, - 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, - 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, - 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, - 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, - 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, - 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, - 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, - 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, - 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, - 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, - 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, - 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, - 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, - 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, - 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, - 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, - 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, - 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, - 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, - 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, - 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, - 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, - 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, - 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, - 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, - 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, - 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, - 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, - 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, - 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, - 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, - 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, - 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, - 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, - 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, - 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, - 0x6571193600000000}, - {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, - 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, - 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, - 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, - 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, - 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, - 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, - 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, - 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, - 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, - 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, - 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, - 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, - 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, - 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, - 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, - 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, - 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, - 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, - 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, - 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, - 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, - 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, - 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, - 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, - 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, - 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, - 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, - 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, - 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, - 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, - 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, - 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, - 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, - 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, - 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, - 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, - 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, - 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, - 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, - 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, - 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, - 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, - 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, - 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, - 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, - 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, - 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, - 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, - 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, - 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, - 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, - 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, - 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, - 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, - 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, - 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, - 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, - 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, - 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, - 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, - 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, - 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, - 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, - 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, - 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, - 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, - 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, - 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, - 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, - 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, - 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, - 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, - 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, - 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, - 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, - 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, - 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, - 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, - 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, - 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, - 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, - 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, - 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, - 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, - 0xa68cee3d00000000}, - {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, - 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, - 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, - 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, - 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, - 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, - 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, - 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, - 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, - 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, - 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, - 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, - 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, - 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, - 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, - 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, - 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, - 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, - 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, - 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, - 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, - 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, - 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, - 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, - 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, - 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, - 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, - 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, - 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, - 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, - 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, - 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, - 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, - 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, - 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, - 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, - 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, - 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, - 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, - 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, - 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, - 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, - 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, - 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, - 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, - 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, - 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, - 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, - 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, - 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, - 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, - 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, - 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, - 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, - 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, - 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, - 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, - 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, - 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, - 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, - 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, - 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, - 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, - 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, - 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, - 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, - 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, - 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, - 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, - 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, - 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, - 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, - 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, - 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, - 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, - 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, - 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, - 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, - 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, - 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, - 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, - 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, - 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, - 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, - 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, - 0x51e8883f00000000}, - {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, - 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, - 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, - 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, - 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, - 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, - 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, - 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, - 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, - 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, - 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, - 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, - 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, - 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, - 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, - 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, - 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, - 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, - 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, - 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, - 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, - 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, - 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, - 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, - 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, - 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, - 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, - 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, - 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, - 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, - 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, - 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, - 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, - 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, - 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, - 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, - 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, - 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, - 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, - 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, - 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, - 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, - 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, - 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, - 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, - 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, - 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, - 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, - 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, - 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, - 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, - 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, - 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, - 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, - 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, - 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, - 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, - 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, - 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, - 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, - 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, - 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, - 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, - 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, - 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, - 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, - 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, - 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, - 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, - 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, - 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, - 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, - 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, - 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, - 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, - 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, - 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, - 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, - 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, - 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, - 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, - 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, - 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, - 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, - 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, - 0x8ae9531c00000000}, - {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, - 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, - 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, - 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, - 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, - 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, - 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, - 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, - 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, - 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, - 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, - 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, - 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, - 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, - 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, - 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, - 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, - 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, - 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, - 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, - 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, - 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, - 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, - 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, - 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, - 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, - 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, - 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, - 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, - 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, - 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, - 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, - 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, - 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, - 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, - 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, - 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, - 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, - 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, - 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, - 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, - 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, - 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, - 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, - 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, - 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, - 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, - 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, - 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, - 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, - 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, - 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, - 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, - 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, - 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, - 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, - 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, - 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, - 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, - 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, - 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, - 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, - 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, - 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, - 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, - 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, - 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, - 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, - 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, - 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, - 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, - 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, - 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, - 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, - 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, - 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, - 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, - 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, - 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, - 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, - 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, - 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, - 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, - 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, - 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, - 0xd739710d00000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, - 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, - 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, - 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, - 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, - 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, - 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, - 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, - 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, - 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, - 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, - 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, - 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, - 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, - 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, - 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, - 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, - 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, - 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, - 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, - 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, - 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, - 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, - 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, - 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, - 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, - 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, - 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, - 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, - 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, - 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, - 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, - 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, - 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, - 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, - 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, - 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, - 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, - 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, - 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, - 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, - 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, - 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, - 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, - 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, - 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, - 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, - 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, - 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, - 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, - 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, - 0x264b06e6}, - {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, - 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, - 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, - 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, - 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, - 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, - 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, - 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, - 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, - 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, - 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, - 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, - 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, - 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, - 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, - 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, - 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, - 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, - 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, - 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, - 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, - 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, - 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, - 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, - 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, - 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, - 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, - 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, - 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, - 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, - 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, - 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, - 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, - 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, - 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, - 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, - 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, - 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, - 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, - 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, - 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, - 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, - 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, - 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, - 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, - 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, - 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, - 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, - 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, - 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, - 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, - 0x92364a30}, - {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, - 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, - 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, - 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, - 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, - 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, - 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, - 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, - 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, - 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, - 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, - 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, - 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, - 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, - 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, - 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, - 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, - 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, - 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, - 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, - 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, - 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, - 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, - 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, - 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, - 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, - 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, - 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, - 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, - 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, - 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, - 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, - 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, - 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, - 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, - 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, - 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, - 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, - 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, - 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, - 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, - 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, - 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, - 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, - 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, - 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, - 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, - 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, - 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, - 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, - 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, - 0xe4c4abcc}, - {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, - 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, - 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, - 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, - 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, - 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, - 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, - 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, - 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, - 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, - 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, - 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, - 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, - 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, - 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, - 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, - 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, - 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, - 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, - 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, - 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, - 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, - 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, - 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, - 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, - 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, - 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, - 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, - 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, - 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, - 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, - 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, - 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, - 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, - 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, - 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, - 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, - 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, - 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, - 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, - 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, - 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, - 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, - 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, - 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, - 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, - 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, - 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, - 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, - 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, - 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, - 0xca64c78c}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, - 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, - 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, - 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, - 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, - 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, - 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, - 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, - 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, - 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, - 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, - 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, - 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, - 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, - 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, - 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, - 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, - 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, - 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, - 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, - 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, - 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, - 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, - 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, - 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, - 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, - 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, - 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, - 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, - 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, - 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, - 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, - 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, - 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, - 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, - 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, - 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, - 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, - 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, - 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, - 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, - 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, - 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, - 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, - 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, - 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, - 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, - 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, - 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, - 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, - 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, - 0x8cc764ca}, - {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, - 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, - 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, - 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, - 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, - 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, - 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, - 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, - 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, - 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, - 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, - 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, - 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, - 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, - 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, - 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, - 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, - 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, - 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, - 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, - 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, - 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, - 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, - 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, - 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, - 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, - 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, - 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, - 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, - 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, - 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, - 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, - 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, - 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, - 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, - 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, - 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, - 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, - 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, - 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, - 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, - 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, - 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, - 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, - 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, - 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, - 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, - 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, - 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, - 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, - 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, - 0xccabc4e4}, - {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, - 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, - 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, - 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, - 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, - 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, - 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, - 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, - 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, - 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, - 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, - 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, - 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, - 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, - 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, - 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, - 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, - 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, - 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, - 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, - 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, - 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, - 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, - 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, - 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, - 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, - 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, - 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, - 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, - 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, - 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, - 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, - 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, - 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, - 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, - 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, - 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, - 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, - 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, - 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, - 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, - 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, - 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, - 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, - 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, - 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, - 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, - 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, - 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, - 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, - 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, - 0x304a3692}, - {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, - 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, - 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, - 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, - 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, - 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, - 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, - 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, - 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, - 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, - 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, - 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, - 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, - 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, - 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, - 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, - 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, - 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, - 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, - 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, - 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, - 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, - 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, - 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, - 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, - 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, - 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, - 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, - 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, - 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, - 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, - 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, - 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, - 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, - 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, - 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, - 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, - 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, - 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, - 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, - 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, - 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, - 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, - 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, - 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, - 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, - 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, - 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, - 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, - 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, - 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, - 0xe6064b26}}; - -#endif - -#endif - -#if N == 3 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, - 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, - 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, - 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, - 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, - 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, - 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, - 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, - 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, - 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, - 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, - 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, - 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, - 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, - 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, - 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, - 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, - 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, - 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, - 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, - 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, - 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, - 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, - 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, - 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, - 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, - 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, - 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, - 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, - 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, - 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, - 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, - 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, - 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, - 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, - 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, - 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, - 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, - 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, - 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, - 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, - 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, - 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, - 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, - 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, - 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, - 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, - 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, - 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, - 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, - 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, - 0x09cd8551}, - {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, - 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, - 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, - 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, - 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, - 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, - 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, - 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, - 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, - 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, - 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, - 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, - 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, - 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, - 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, - 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, - 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, - 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, - 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, - 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, - 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, - 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, - 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, - 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, - 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, - 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, - 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, - 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, - 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, - 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, - 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, - 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, - 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, - 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, - 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, - 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, - 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, - 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, - 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, - 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, - 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, - 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, - 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, - 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, - 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, - 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, - 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, - 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, - 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, - 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, - 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, - 0x7bc97a0c}, - {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, - 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, - 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, - 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, - 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, - 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, - 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, - 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, - 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, - 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, - 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, - 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, - 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, - 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, - 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, - 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, - 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, - 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, - 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, - 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, - 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, - 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, - 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, - 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, - 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, - 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, - 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, - 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, - 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, - 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, - 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, - 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, - 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, - 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, - 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, - 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, - 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, - 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, - 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, - 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, - 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, - 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, - 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, - 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, - 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, - 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, - 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, - 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, - 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, - 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, - 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, - 0x7851a2ca}, - {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, - 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, - 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, - 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, - 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, - 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, - 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, - 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, - 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, - 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, - 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, - 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, - 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, - 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, - 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, - 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, - 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, - 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, - 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, - 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, - 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, - 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, - 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, - 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, - 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, - 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, - 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, - 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, - 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, - 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, - 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, - 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, - 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, - 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, - 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, - 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, - 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, - 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, - 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, - 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, - 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, - 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, - 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, - 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, - 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, - 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, - 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, - 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, - 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, - 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, - 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, - 0x566b6848}, - {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, - 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, - 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, - 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, - 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, - 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, - 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, - 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, - 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, - 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, - 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, - 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, - 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, - 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, - 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, - 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, - 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, - 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, - 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, - 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, - 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, - 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, - 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, - 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, - 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, - 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, - 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, - 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, - 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, - 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, - 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, - 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, - 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, - 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, - 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, - 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, - 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, - 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, - 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, - 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, - 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, - 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, - 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, - 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, - 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, - 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, - 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, - 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, - 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, - 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, - 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, - 0xd8ac6b35}, - {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, - 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, - 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, - 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, - 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, - 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, - 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, - 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, - 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, - 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, - 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, - 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, - 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, - 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, - 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, - 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, - 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, - 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, - 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, - 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, - 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, - 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, - 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, - 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, - 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, - 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, - 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, - 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, - 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, - 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, - 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, - 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, - 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, - 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, - 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, - 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, - 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, - 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, - 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, - 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, - 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, - 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, - 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, - 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, - 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, - 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, - 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, - 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, - 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, - 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, - 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, - 0xa140efa8}, - {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, - 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, - 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, - 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, - 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, - 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, - 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, - 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, - 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, - 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, - 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, - 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, - 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, - 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, - 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, - 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, - 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, - 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, - 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, - 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, - 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, - 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, - 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, - 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, - 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, - 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, - 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, - 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, - 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, - 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, - 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, - 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, - 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, - 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, - 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, - 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, - 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, - 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, - 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, - 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, - 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, - 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, - 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, - 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, - 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, - 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, - 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, - 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, - 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, - 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, - 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, - 0x917cd6a1}, - {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, - 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, - 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, - 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, - 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, - 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, - 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, - 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, - 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, - 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, - 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, - 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, - 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, - 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, - 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, - 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, - 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, - 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, - 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, - 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, - 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, - 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, - 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, - 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, - 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, - 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, - 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, - 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, - 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, - 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, - 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, - 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, - 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, - 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, - 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, - 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, - 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, - 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, - 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, - 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, - 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, - 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, - 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, - 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, - 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, - 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, - 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, - 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, - 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, - 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, - 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, - 0x18ba364e}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, - 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, - 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, - 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, - 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, - 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, - 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, - 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, - 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, - 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, - 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, - 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, - 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, - 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, - 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, - 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, - 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, - 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, - 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, - 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, - 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, - 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, - 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, - 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, - 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, - 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, - 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, - 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, - 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, - 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, - 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, - 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, - 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, - 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, - 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, - 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, - 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, - 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, - 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, - 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, - 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, - 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, - 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, - 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, - 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, - 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, - 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, - 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, - 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, - 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, - 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, - 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, - 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, - 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, - 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, - 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, - 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, - 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, - 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, - 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, - 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, - 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, - 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, - 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, - 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, - 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, - 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, - 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, - 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, - 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, - 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, - 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, - 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, - 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, - 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, - 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, - 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, - 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, - 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, - 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, - 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, - 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, - 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, - 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, - 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, - 0x4e36ba1800000000}, - {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, - 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, - 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, - 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, - 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, - 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, - 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, - 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, - 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, - 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, - 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, - 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, - 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, - 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, - 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, - 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, - 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, - 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, - 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, - 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, - 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, - 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, - 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, - 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, - 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, - 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, - 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, - 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, - 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, - 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, - 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, - 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, - 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, - 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, - 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, - 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, - 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, - 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, - 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, - 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, - 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, - 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, - 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, - 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, - 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, - 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, - 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, - 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, - 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, - 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, - 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, - 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, - 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, - 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, - 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, - 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, - 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, - 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, - 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, - 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, - 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, - 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, - 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, - 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, - 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, - 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, - 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, - 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, - 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, - 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, - 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, - 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, - 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, - 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, - 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, - 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, - 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, - 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, - 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, - 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, - 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, - 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, - 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, - 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, - 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, - 0xa1d67c9100000000}, - {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, - 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, - 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, - 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, - 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, - 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, - 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, - 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, - 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, - 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, - 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, - 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, - 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, - 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, - 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, - 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, - 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, - 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, - 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, - 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, - 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, - 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, - 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, - 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, - 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, - 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, - 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, - 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, - 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, - 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, - 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, - 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, - 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, - 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, - 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, - 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, - 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, - 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, - 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, - 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, - 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, - 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, - 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, - 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, - 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, - 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, - 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, - 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, - 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, - 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, - 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, - 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, - 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, - 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, - 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, - 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, - 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, - 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, - 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, - 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, - 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, - 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, - 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, - 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, - 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, - 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, - 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, - 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, - 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, - 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, - 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, - 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, - 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, - 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, - 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, - 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, - 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, - 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, - 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, - 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, - 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, - 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, - 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, - 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, - 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, - 0xa8ef40a100000000}, - {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, - 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, - 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, - 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, - 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, - 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, - 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, - 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, - 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, - 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, - 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, - 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, - 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, - 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, - 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, - 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, - 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, - 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, - 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, - 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, - 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, - 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, - 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, - 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, - 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, - 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, - 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, - 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, - 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, - 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, - 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, - 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, - 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, - 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, - 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, - 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, - 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, - 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, - 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, - 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, - 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, - 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, - 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, - 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, - 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, - 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, - 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, - 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, - 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, - 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, - 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, - 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, - 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, - 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, - 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, - 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, - 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, - 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, - 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, - 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, - 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, - 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, - 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, - 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, - 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, - 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, - 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, - 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, - 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, - 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, - 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, - 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, - 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, - 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, - 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, - 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, - 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, - 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, - 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, - 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, - 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, - 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, - 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, - 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, - 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, - 0x356bacd800000000}, - {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, - 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, - 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, - 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, - 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, - 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, - 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, - 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, - 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, - 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, - 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, - 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, - 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, - 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, - 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, - 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, - 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, - 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, - 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, - 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, - 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, - 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, - 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, - 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, - 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, - 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, - 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, - 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, - 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, - 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, - 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, - 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, - 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, - 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, - 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, - 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, - 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, - 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, - 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, - 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, - 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, - 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, - 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, - 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, - 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, - 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, - 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, - 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, - 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, - 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, - 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, - 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, - 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, - 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, - 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, - 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, - 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, - 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, - 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, - 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, - 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, - 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, - 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, - 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, - 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, - 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, - 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, - 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, - 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, - 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, - 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, - 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, - 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, - 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, - 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, - 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, - 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, - 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, - 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, - 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, - 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, - 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, - 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, - 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, - 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, - 0x48686b5600000000}, - {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, - 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, - 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, - 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, - 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, - 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, - 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, - 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, - 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, - 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, - 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, - 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, - 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, - 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, - 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, - 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, - 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, - 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, - 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, - 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, - 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, - 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, - 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, - 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, - 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, - 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, - 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, - 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, - 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, - 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, - 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, - 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, - 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, - 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, - 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, - 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, - 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, - 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, - 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, - 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, - 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, - 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, - 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, - 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, - 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, - 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, - 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, - 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, - 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, - 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, - 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, - 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, - 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, - 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, - 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, - 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, - 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, - 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, - 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, - 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, - 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, - 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, - 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, - 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, - 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, - 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, - 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, - 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, - 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, - 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, - 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, - 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, - 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, - 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, - 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, - 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, - 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, - 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, - 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, - 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, - 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, - 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, - 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, - 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, - 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, - 0xcaa2517800000000}, - {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, - 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, - 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, - 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, - 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, - 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, - 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, - 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, - 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, - 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, - 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, - 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, - 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, - 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, - 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, - 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, - 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, - 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, - 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, - 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, - 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, - 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, - 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, - 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, - 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, - 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, - 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, - 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, - 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, - 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, - 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, - 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, - 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, - 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, - 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, - 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, - 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, - 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, - 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, - 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, - 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, - 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, - 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, - 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, - 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, - 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, - 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, - 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, - 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, - 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, - 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, - 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, - 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, - 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, - 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, - 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, - 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, - 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, - 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, - 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, - 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, - 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, - 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, - 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, - 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, - 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, - 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, - 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, - 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, - 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, - 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, - 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, - 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, - 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, - 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, - 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, - 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, - 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, - 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, - 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, - 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, - 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, - 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, - 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, - 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, - 0x0c7ac97b00000000}, - {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, - 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, - 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, - 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, - 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, - 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, - 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, - 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, - 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, - 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, - 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, - 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, - 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, - 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, - 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, - 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, - 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, - 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, - 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, - 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, - 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, - 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, - 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, - 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, - 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, - 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, - 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, - 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, - 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, - 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, - 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, - 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, - 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, - 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, - 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, - 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, - 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, - 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, - 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, - 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, - 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, - 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, - 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, - 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, - 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, - 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, - 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, - 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, - 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, - 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, - 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, - 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, - 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, - 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, - 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, - 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, - 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, - 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, - 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, - 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, - 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, - 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, - 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, - 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, - 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, - 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, - 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, - 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, - 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, - 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, - 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, - 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, - 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, - 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, - 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, - 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, - 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, - 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, - 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, - 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, - 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, - 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, - 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, - 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, - 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, - 0x5185cd0900000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, - 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, - 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, - 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, - 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, - 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, - 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, - 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, - 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, - 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, - 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, - 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, - 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, - 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, - 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, - 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, - 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, - 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, - 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, - 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, - 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, - 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, - 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, - 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, - 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, - 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, - 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, - 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, - 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, - 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, - 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, - 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, - 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, - 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, - 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, - 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, - 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, - 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, - 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, - 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, - 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, - 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, - 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, - 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, - 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, - 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, - 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, - 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, - 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, - 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, - 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, - 0x36197165}, - {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, - 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, - 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, - 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, - 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, - 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, - 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, - 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, - 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, - 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, - 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, - 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, - 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, - 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, - 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, - 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, - 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, - 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, - 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, - 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, - 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, - 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, - 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, - 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, - 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, - 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, - 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, - 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, - 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, - 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, - 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, - 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, - 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, - 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, - 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, - 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, - 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, - 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, - 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, - 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, - 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, - 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, - 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, - 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, - 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, - 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, - 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, - 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, - 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, - 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, - 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, - 0x1a3b93aa}, - {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, - 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, - 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, - 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, - 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, - 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, - 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, - 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, - 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, - 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, - 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, - 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, - 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, - 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, - 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, - 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, - 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, - 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, - 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, - 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, - 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, - 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, - 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, - 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, - 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, - 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, - 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, - 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, - 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, - 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, - 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, - 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, - 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, - 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, - 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, - 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, - 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, - 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, - 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, - 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, - 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, - 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, - 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, - 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, - 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, - 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, - 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, - 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, - 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, - 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, - 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, - 0xe147d714}, - {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, - 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, - 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, - 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, - 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, - 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, - 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, - 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, - 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, - 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, - 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, - 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, - 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, - 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, - 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, - 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, - 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, - 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, - 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, - 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, - 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, - 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, - 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, - 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, - 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, - 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, - 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, - 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, - 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, - 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, - 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, - 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, - 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, - 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, - 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, - 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, - 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, - 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, - 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, - 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, - 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, - 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, - 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, - 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, - 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, - 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, - 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, - 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, - 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, - 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, - 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, - 0x494f0c4b}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, - 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, - 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, - 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, - 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, - 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, - 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, - 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, - 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, - 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, - 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, - 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, - 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, - 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, - 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, - 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, - 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, - 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, - 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, - 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, - 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, - 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, - 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, - 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, - 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, - 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, - 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, - 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, - 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, - 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, - 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, - 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, - 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, - 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, - 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, - 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, - 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, - 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, - 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, - 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, - 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, - 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, - 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, - 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, - 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, - 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, - 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, - 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, - 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, - 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, - 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, - 0x4b0c4f49}, - {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, - 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, - 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, - 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, - 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, - 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, - 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, - 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, - 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, - 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, - 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, - 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, - 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, - 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, - 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, - 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, - 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, - 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, - 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, - 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, - 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, - 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, - 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, - 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, - 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, - 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, - 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, - 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, - 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, - 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, - 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, - 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, - 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, - 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, - 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, - 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, - 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, - 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, - 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, - 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, - 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, - 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, - 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, - 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, - 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, - 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, - 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, - 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, - 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, - 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, - 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, - 0x14d747e1}, - {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, - 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, - 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, - 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, - 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, - 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, - 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, - 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, - 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, - 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, - 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, - 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, - 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, - 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, - 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, - 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, - 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, - 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, - 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, - 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, - 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, - 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, - 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, - 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, - 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, - 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, - 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, - 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, - 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, - 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, - 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, - 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, - 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, - 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, - 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, - 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, - 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, - 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, - 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, - 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, - 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, - 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, - 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, - 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, - 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, - 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, - 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, - 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, - 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, - 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, - 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, - 0xaa933b1a}, - {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, - 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, - 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, - 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, - 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, - 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, - 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, - 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, - 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, - 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, - 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, - 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, - 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, - 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, - 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, - 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, - 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, - 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, - 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, - 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, - 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, - 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, - 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, - 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, - 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, - 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, - 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, - 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, - 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, - 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, - 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, - 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, - 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, - 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, - 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, - 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, - 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, - 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, - 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, - 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, - 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, - 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, - 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, - 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, - 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, - 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, - 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, - 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, - 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, - 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, - 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, - 0x65711936}}; - -#endif - -#endif - -#if N == 4 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, - 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, - 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, - 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, - 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, - 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, - 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, - 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, - 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, - 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, - 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, - 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, - 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, - 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, - 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, - 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, - 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, - 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, - 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, - 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, - 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, - 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, - 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, - 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, - 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, - 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, - 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, - 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, - 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, - 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, - 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, - 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, - 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, - 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, - 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, - 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, - 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, - 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, - 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, - 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, - 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, - 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, - 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, - 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, - 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, - 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, - 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, - 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, - 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, - 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, - 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, - 0xe3c45916}, - {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, - 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, - 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, - 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, - 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, - 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, - 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, - 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, - 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, - 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, - 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, - 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, - 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, - 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, - 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, - 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, - 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, - 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, - 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, - 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, - 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, - 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, - 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, - 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, - 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, - 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, - 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, - 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, - 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, - 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, - 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, - 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, - 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, - 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, - 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, - 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, - 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, - 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, - 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, - 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, - 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, - 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, - 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, - 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, - 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, - 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, - 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, - 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, - 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, - 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, - 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, - 0xa7520488}, - {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, - 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, - 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, - 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, - 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, - 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, - 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, - 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, - 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, - 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, - 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, - 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, - 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, - 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, - 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, - 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, - 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, - 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, - 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, - 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, - 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, - 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, - 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, - 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, - 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, - 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, - 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, - 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, - 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, - 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, - 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, - 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, - 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, - 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, - 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, - 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, - 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, - 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, - 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, - 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, - 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, - 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, - 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, - 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, - 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, - 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, - 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, - 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, - 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, - 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, - 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, - 0x3522e9e4}, - {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, - 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, - 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, - 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, - 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, - 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, - 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, - 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, - 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, - 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, - 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, - 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, - 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, - 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, - 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, - 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, - 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, - 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, - 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, - 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, - 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, - 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, - 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, - 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, - 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, - 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, - 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, - 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, - 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, - 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, - 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, - 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, - 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, - 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, - 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, - 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, - 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, - 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, - 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, - 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, - 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, - 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, - 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, - 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, - 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, - 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, - 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, - 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, - 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, - 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, - 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, - 0x97411e28}, - {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, - 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, - 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, - 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, - 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, - 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, - 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, - 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, - 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, - 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, - 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, - 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, - 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, - 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, - 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, - 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, - 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, - 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, - 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, - 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, - 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, - 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, - 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, - 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, - 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, - 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, - 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, - 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, - 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, - 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, - 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, - 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, - 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, - 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, - 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, - 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, - 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, - 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, - 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, - 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, - 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, - 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, - 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, - 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, - 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, - 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, - 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, - 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, - 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, - 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, - 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, - 0x93c7a00b}, - {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, - 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, - 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, - 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, - 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, - 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, - 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, - 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, - 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, - 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, - 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, - 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, - 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, - 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, - 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, - 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, - 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, - 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, - 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, - 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, - 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, - 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, - 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, - 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, - 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, - 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, - 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, - 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, - 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, - 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, - 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, - 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, - 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, - 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, - 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, - 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, - 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, - 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, - 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, - 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, - 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, - 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, - 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, - 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, - 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, - 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, - 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, - 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, - 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, - 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, - 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, - 0xce5f968d}, - {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, - 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, - 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, - 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, - 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, - 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, - 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, - 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, - 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, - 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, - 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, - 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, - 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, - 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, - 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, - 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, - 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, - 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, - 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, - 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, - 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, - 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, - 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, - 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, - 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, - 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, - 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, - 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, - 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, - 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, - 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, - 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, - 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, - 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, - 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, - 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, - 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, - 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, - 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, - 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, - 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, - 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, - 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, - 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, - 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, - 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, - 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, - 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, - 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, - 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, - 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, - 0x3e721277}, - {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, - 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, - 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, - 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, - 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, - 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, - 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, - 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, - 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, - 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, - 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, - 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, - 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, - 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, - 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, - 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, - 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, - 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, - 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, - 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, - 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, - 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, - 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, - 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, - 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, - 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, - 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, - 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, - 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, - 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, - 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, - 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, - 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, - 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, - 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, - 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, - 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, - 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, - 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, - 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, - 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, - 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, - 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, - 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, - 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, - 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, - 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, - 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, - 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, - 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, - 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, - 0x1c65ace7}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, - 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, - 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, - 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, - 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, - 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, - 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, - 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, - 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, - 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, - 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, - 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, - 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, - 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, - 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, - 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, - 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, - 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, - 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, - 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, - 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, - 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, - 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, - 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, - 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, - 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, - 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, - 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, - 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, - 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, - 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, - 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, - 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, - 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, - 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, - 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, - 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, - 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, - 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, - 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, - 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, - 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, - 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, - 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, - 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, - 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, - 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, - 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, - 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, - 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, - 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, - 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, - 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, - 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, - 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, - 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, - 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, - 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, - 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, - 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, - 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, - 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, - 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, - 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, - 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, - 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, - 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, - 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, - 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, - 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, - 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, - 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, - 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, - 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, - 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, - 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, - 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, - 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, - 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, - 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, - 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, - 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, - 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, - 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, - 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, - 0xe7ac651c00000000}, - {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, - 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, - 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, - 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, - 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, - 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, - 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, - 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, - 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, - 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, - 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, - 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, - 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, - 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, - 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, - 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, - 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, - 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, - 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, - 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, - 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, - 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, - 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, - 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, - 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, - 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, - 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, - 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, - 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, - 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, - 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, - 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, - 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, - 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, - 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, - 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, - 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, - 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, - 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, - 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, - 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, - 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, - 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, - 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, - 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, - 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, - 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, - 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, - 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, - 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, - 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, - 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, - 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, - 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, - 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, - 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, - 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, - 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, - 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, - 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, - 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, - 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, - 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, - 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, - 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, - 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, - 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, - 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, - 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, - 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, - 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, - 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, - 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, - 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, - 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, - 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, - 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, - 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, - 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, - 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, - 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, - 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, - 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, - 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, - 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, - 0x7712723e00000000}, - {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, - 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, - 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, - 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, - 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, - 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, - 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, - 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, - 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, - 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, - 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, - 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, - 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, - 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, - 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, - 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, - 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, - 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, - 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, - 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, - 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, - 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, - 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, - 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, - 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, - 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, - 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, - 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, - 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, - 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, - 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, - 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, - 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, - 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, - 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, - 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, - 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, - 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, - 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, - 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, - 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, - 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, - 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, - 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, - 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, - 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, - 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, - 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, - 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, - 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, - 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, - 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, - 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, - 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, - 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, - 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, - 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, - 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, - 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, - 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, - 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, - 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, - 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, - 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, - 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, - 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, - 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, - 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, - 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, - 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, - 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, - 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, - 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, - 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, - 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, - 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, - 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, - 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, - 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, - 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, - 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, - 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, - 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, - 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, - 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, - 0x8d965fce00000000}, - {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, - 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, - 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, - 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, - 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, - 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, - 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, - 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, - 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, - 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, - 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, - 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, - 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, - 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, - 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, - 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, - 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, - 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, - 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, - 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, - 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, - 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, - 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, - 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, - 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, - 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, - 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, - 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, - 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, - 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, - 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, - 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, - 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, - 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, - 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, - 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, - 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, - 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, - 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, - 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, - 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, - 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, - 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, - 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, - 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, - 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, - 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, - 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, - 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, - 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, - 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, - 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, - 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, - 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, - 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, - 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, - 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, - 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, - 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, - 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, - 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, - 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, - 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, - 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, - 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, - 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, - 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, - 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, - 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, - 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, - 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, - 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, - 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, - 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, - 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, - 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, - 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, - 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, - 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, - 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, - 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, - 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, - 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, - 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, - 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, - 0x0ba0c79300000000}, - {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, - 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, - 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, - 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, - 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, - 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, - 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, - 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, - 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, - 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, - 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, - 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, - 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, - 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, - 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, - 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, - 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, - 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, - 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, - 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, - 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, - 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, - 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, - 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, - 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, - 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, - 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, - 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, - 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, - 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, - 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, - 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, - 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, - 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, - 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, - 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, - 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, - 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, - 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, - 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, - 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, - 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, - 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, - 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, - 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, - 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, - 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, - 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, - 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, - 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, - 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, - 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, - 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, - 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, - 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, - 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, - 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, - 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, - 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, - 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, - 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, - 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, - 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, - 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, - 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, - 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, - 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, - 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, - 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, - 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, - 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, - 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, - 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, - 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, - 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, - 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, - 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, - 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, - 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, - 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, - 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, - 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, - 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, - 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, - 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, - 0x281e419700000000}, - {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, - 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, - 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, - 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, - 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, - 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, - 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, - 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, - 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, - 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, - 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, - 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, - 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, - 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, - 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, - 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, - 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, - 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, - 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, - 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, - 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, - 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, - 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, - 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, - 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, - 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, - 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, - 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, - 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, - 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, - 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, - 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, - 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, - 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, - 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, - 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, - 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, - 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, - 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, - 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, - 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, - 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, - 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, - 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, - 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, - 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, - 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, - 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, - 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, - 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, - 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, - 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, - 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, - 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, - 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, - 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, - 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, - 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, - 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, - 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, - 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, - 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, - 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, - 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, - 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, - 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, - 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, - 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, - 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, - 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, - 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, - 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, - 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, - 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, - 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, - 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, - 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, - 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, - 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, - 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, - 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, - 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, - 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, - 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, - 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, - 0xe4e9223500000000}, - {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, - 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, - 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, - 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, - 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, - 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, - 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, - 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, - 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, - 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, - 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, - 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, - 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, - 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, - 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, - 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, - 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, - 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, - 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, - 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, - 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, - 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, - 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, - 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, - 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, - 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, - 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, - 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, - 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, - 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, - 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, - 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, - 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, - 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, - 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, - 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, - 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, - 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, - 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, - 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, - 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, - 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, - 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, - 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, - 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, - 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, - 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, - 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, - 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, - 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, - 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, - 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, - 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, - 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, - 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, - 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, - 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, - 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, - 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, - 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, - 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, - 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, - 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, - 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, - 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, - 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, - 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, - 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, - 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, - 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, - 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, - 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, - 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, - 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, - 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, - 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, - 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, - 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, - 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, - 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, - 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, - 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, - 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, - 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, - 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, - 0x880452a700000000}, - {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, - 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, - 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, - 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, - 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, - 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, - 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, - 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, - 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, - 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, - 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, - 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, - 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, - 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, - 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, - 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, - 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, - 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, - 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, - 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, - 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, - 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, - 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, - 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, - 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, - 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, - 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, - 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, - 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, - 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, - 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, - 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, - 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, - 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, - 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, - 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, - 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, - 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, - 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, - 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, - 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, - 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, - 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, - 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, - 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, - 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, - 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, - 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, - 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, - 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, - 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, - 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, - 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, - 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, - 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, - 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, - 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, - 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, - 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, - 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, - 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, - 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, - 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, - 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, - 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, - 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, - 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, - 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, - 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, - 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, - 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, - 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, - 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, - 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, - 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, - 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, - 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, - 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, - 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, - 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, - 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, - 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, - 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, - 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, - 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, - 0x1659c4e300000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, - 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, - 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, - 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, - 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, - 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, - 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, - 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, - 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, - 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, - 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, - 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, - 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, - 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, - 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, - 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, - 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, - 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, - 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, - 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, - 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, - 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, - 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, - 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, - 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, - 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, - 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, - 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, - 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, - 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, - 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, - 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, - 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, - 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, - 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, - 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, - 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, - 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, - 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, - 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, - 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, - 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, - 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, - 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, - 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, - 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, - 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, - 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, - 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, - 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, - 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, - 0x0d7139d7}, - {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, - 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, - 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, - 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, - 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, - 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, - 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, - 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, - 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, - 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, - 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, - 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, - 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, - 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, - 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, - 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, - 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, - 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, - 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, - 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, - 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, - 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, - 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, - 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, - 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, - 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, - 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, - 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, - 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, - 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, - 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, - 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, - 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, - 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, - 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, - 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, - 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, - 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, - 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, - 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, - 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, - 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, - 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, - 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, - 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, - 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, - 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, - 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, - 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, - 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, - 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, - 0x1c53e98a}, - {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, - 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, - 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, - 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, - 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, - 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, - 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, - 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, - 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, - 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, - 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, - 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, - 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, - 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, - 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, - 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, - 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, - 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, - 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, - 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, - 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, - 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, - 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, - 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, - 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, - 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, - 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, - 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, - 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, - 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, - 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, - 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, - 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, - 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, - 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, - 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, - 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, - 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, - 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, - 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, - 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, - 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, - 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, - 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, - 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, - 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, - 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, - 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, - 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, - 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, - 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, - 0x3f88e851}, - {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, - 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, - 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, - 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, - 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, - 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, - 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, - 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, - 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, - 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, - 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, - 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, - 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, - 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, - 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, - 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, - 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, - 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, - 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, - 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, - 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, - 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, - 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, - 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, - 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, - 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, - 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, - 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, - 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, - 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, - 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, - 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, - 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, - 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, - 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, - 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, - 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, - 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, - 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, - 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, - 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, - 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, - 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, - 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, - 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, - 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, - 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, - 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, - 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, - 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, - 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, - 0x3dee8ca6}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, - 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, - 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, - 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, - 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, - 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, - 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, - 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, - 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, - 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, - 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, - 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, - 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, - 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, - 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, - 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, - 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, - 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, - 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, - 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, - 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, - 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, - 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, - 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, - 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, - 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, - 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, - 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, - 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, - 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, - 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, - 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, - 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, - 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, - 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, - 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, - 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, - 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, - 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, - 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, - 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, - 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, - 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, - 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, - 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, - 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, - 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, - 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, - 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, - 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, - 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, - 0xa68cee3d}, - {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, - 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, - 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, - 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, - 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, - 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, - 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, - 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, - 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, - 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, - 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, - 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, - 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, - 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, - 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, - 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, - 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, - 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, - 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, - 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, - 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, - 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, - 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, - 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, - 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, - 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, - 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, - 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, - 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, - 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, - 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, - 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, - 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, - 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, - 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, - 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, - 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, - 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, - 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, - 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, - 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, - 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, - 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, - 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, - 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, - 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, - 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, - 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, - 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, - 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, - 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, - 0x51e8883f}, - {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, - 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, - 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, - 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, - 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, - 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, - 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, - 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, - 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, - 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, - 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, - 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, - 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, - 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, - 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, - 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, - 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, - 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, - 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, - 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, - 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, - 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, - 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, - 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, - 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, - 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, - 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, - 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, - 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, - 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, - 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, - 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, - 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, - 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, - 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, - 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, - 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, - 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, - 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, - 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, - 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, - 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, - 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, - 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, - 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, - 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, - 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, - 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, - 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, - 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, - 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, - 0x8ae9531c}, - {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, - 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, - 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, - 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, - 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, - 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, - 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, - 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, - 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, - 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, - 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, - 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, - 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, - 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, - 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, - 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, - 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, - 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, - 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, - 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, - 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, - 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, - 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, - 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, - 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, - 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, - 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, - 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, - 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, - 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, - 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, - 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, - 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, - 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, - 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, - 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, - 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, - 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, - 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, - 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, - 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, - 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, - 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, - 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, - 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, - 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, - 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, - 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, - 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, - 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, - 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, - 0xd739710d}}; - -#endif - -#endif - -#if N == 5 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, - 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, - 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, - 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, - 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, - 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, - 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, - 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, - 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, - 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, - 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, - 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, - 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, - 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, - 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, - 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, - 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, - 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, - 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, - 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, - 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, - 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, - 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, - 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, - 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, - 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, - 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, - 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, - 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, - 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, - 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, - 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, - 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, - 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, - 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, - 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, - 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, - 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, - 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, - 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, - 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, - 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, - 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, - 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, - 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, - 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, - 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, - 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, - 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, - 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, - 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, - 0xe9947565}, - {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, - 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, - 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, - 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, - 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, - 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, - 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, - 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, - 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, - 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, - 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, - 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, - 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, - 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, - 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, - 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, - 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, - 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, - 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, - 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, - 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, - 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, - 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, - 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, - 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, - 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, - 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, - 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, - 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, - 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, - 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, - 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, - 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, - 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, - 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, - 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, - 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, - 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, - 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, - 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, - 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, - 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, - 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, - 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, - 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, - 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, - 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, - 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, - 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, - 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, - 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, - 0xf7d05006}, - {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, - 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, - 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, - 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, - 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, - 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, - 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, - 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, - 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, - 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, - 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, - 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, - 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, - 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, - 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, - 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, - 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, - 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, - 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, - 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, - 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, - 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, - 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, - 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, - 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, - 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, - 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, - 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, - 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, - 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, - 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, - 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, - 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, - 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, - 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, - 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, - 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, - 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, - 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, - 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, - 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, - 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, - 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, - 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, - 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, - 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, - 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, - 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, - 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, - 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, - 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, - 0xb2075b94}, - {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, - 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, - 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, - 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, - 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, - 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, - 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, - 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, - 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, - 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, - 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, - 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, - 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, - 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, - 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, - 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, - 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, - 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, - 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, - 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, - 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, - 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, - 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, - 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, - 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, - 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, - 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, - 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, - 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, - 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, - 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, - 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, - 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, - 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, - 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, - 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, - 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, - 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, - 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, - 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, - 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, - 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, - 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, - 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, - 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, - 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, - 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, - 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, - 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, - 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, - 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, - 0xba50bcb9}, - {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, - 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, - 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, - 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, - 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, - 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, - 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, - 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, - 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, - 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, - 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, - 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, - 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, - 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, - 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, - 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, - 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, - 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, - 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, - 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, - 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, - 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, - 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, - 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, - 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, - 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, - 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, - 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, - 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, - 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, - 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, - 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, - 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, - 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, - 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, - 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, - 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, - 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, - 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, - 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, - 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, - 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, - 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, - 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, - 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, - 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, - 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, - 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, - 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, - 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, - 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, - 0x808abcf4}, - {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, - 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, - 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, - 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, - 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, - 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, - 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, - 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, - 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, - 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, - 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, - 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, - 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, - 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, - 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, - 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, - 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, - 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, - 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, - 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, - 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, - 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, - 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, - 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, - 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, - 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, - 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, - 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, - 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, - 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, - 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, - 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, - 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, - 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, - 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, - 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, - 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, - 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, - 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, - 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, - 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, - 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, - 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, - 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, - 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, - 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, - 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, - 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, - 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, - 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, - 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, - 0xefdb3f95}, - {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, - 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, - 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, - 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, - 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, - 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, - 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, - 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, - 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, - 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, - 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, - 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, - 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, - 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, - 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, - 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, - 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, - 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, - 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, - 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, - 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, - 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, - 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, - 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, - 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, - 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, - 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, - 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, - 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, - 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, - 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, - 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, - 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, - 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, - 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, - 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, - 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, - 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, - 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, - 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, - 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, - 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, - 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, - 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, - 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, - 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, - 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, - 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, - 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, - 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, - 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, - 0x0e2fbf43}, - {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, - 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, - 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, - 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, - 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, - 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, - 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, - 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, - 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, - 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, - 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, - 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, - 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, - 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, - 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, - 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, - 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, - 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, - 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, - 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, - 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, - 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, - 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, - 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, - 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, - 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, - 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, - 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, - 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, - 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, - 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, - 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, - 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, - 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, - 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, - 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, - 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, - 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, - 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, - 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, - 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, - 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, - 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, - 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, - 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, - 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, - 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, - 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, - 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, - 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, - 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, - 0xf4377108}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, - 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, - 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, - 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, - 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, - 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, - 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, - 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, - 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, - 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, - 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, - 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, - 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, - 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, - 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, - 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, - 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, - 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, - 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, - 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, - 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, - 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, - 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, - 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, - 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, - 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, - 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, - 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, - 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, - 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, - 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, - 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, - 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, - 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, - 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, - 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, - 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, - 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, - 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, - 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, - 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, - 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, - 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, - 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, - 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, - 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, - 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, - 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, - 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, - 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, - 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, - 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, - 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, - 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, - 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, - 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, - 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, - 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, - 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, - 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, - 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, - 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, - 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, - 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, - 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, - 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, - 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, - 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, - 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, - 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, - 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, - 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, - 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, - 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, - 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, - 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, - 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, - 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, - 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, - 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, - 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, - 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, - 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, - 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, - 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, - 0x087137f400000000}, - {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, - 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, - 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, - 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, - 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, - 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, - 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, - 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, - 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, - 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, - 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, - 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, - 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, - 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, - 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, - 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, - 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, - 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, - 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, - 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, - 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, - 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, - 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, - 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, - 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, - 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, - 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, - 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, - 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, - 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, - 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, - 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, - 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, - 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, - 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, - 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, - 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, - 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, - 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, - 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, - 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, - 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, - 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, - 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, - 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, - 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, - 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, - 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, - 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, - 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, - 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, - 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, - 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, - 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, - 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, - 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, - 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, - 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, - 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, - 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, - 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, - 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, - 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, - 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, - 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, - 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, - 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, - 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, - 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, - 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, - 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, - 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, - 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, - 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, - 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, - 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, - 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, - 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, - 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, - 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, - 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, - 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, - 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, - 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, - 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, - 0x43bf2f0e00000000}, - {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, - 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, - 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, - 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, - 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, - 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, - 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, - 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, - 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, - 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, - 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, - 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, - 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, - 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, - 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, - 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, - 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, - 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, - 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, - 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, - 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, - 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, - 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, - 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, - 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, - 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, - 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, - 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, - 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, - 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, - 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, - 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, - 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, - 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, - 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, - 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, - 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, - 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, - 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, - 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, - 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, - 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, - 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, - 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, - 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, - 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, - 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, - 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, - 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, - 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, - 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, - 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, - 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, - 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, - 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, - 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, - 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, - 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, - 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, - 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, - 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, - 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, - 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, - 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, - 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, - 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, - 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, - 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, - 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, - 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, - 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, - 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, - 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, - 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, - 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, - 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, - 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, - 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, - 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, - 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, - 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, - 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, - 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, - 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, - 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, - 0x953fdbef00000000}, - {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, - 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, - 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, - 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, - 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, - 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, - 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, - 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, - 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, - 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, - 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, - 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, - 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, - 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, - 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, - 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, - 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, - 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, - 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, - 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, - 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, - 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, - 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, - 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, - 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, - 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, - 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, - 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, - 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, - 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, - 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, - 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, - 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, - 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, - 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, - 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, - 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, - 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, - 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, - 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, - 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, - 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, - 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, - 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, - 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, - 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, - 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, - 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, - 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, - 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, - 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, - 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, - 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, - 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, - 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, - 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, - 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, - 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, - 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, - 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, - 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, - 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, - 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, - 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, - 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, - 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, - 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, - 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, - 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, - 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, - 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, - 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, - 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, - 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, - 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, - 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, - 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, - 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, - 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, - 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, - 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, - 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, - 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, - 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, - 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, - 0xf4bc8a8000000000}, - {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, - 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, - 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, - 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, - 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, - 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, - 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, - 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, - 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, - 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, - 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, - 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, - 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, - 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, - 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, - 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, - 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, - 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, - 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, - 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, - 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, - 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, - 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, - 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, - 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, - 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, - 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, - 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, - 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, - 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, - 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, - 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, - 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, - 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, - 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, - 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, - 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, - 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, - 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, - 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, - 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, - 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, - 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, - 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, - 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, - 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, - 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, - 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, - 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, - 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, - 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, - 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, - 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, - 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, - 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, - 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, - 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, - 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, - 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, - 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, - 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, - 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, - 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, - 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, - 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, - 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, - 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, - 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, - 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, - 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, - 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, - 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, - 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, - 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, - 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, - 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, - 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, - 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, - 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, - 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, - 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, - 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, - 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, - 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, - 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, - 0xb9bc50ba00000000}, - {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, - 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, - 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, - 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, - 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, - 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, - 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, - 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, - 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, - 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, - 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, - 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, - 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, - 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, - 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, - 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, - 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, - 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, - 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, - 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, - 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, - 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, - 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, - 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, - 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, - 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, - 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, - 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, - 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, - 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, - 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, - 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, - 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, - 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, - 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, - 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, - 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, - 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, - 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, - 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, - 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, - 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, - 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, - 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, - 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, - 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, - 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, - 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, - 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, - 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, - 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, - 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, - 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, - 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, - 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, - 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, - 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, - 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, - 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, - 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, - 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, - 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, - 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, - 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, - 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, - 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, - 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, - 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, - 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, - 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, - 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, - 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, - 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, - 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, - 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, - 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, - 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, - 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, - 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, - 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, - 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, - 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, - 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, - 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, - 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, - 0x945b07b200000000}, - {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, - 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, - 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, - 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, - 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, - 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, - 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, - 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, - 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, - 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, - 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, - 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, - 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, - 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, - 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, - 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, - 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, - 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, - 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, - 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, - 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, - 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, - 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, - 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, - 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, - 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, - 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, - 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, - 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, - 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, - 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, - 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, - 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, - 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, - 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, - 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, - 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, - 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, - 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, - 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, - 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, - 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, - 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, - 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, - 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, - 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, - 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, - 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, - 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, - 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, - 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, - 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, - 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, - 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, - 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, - 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, - 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, - 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, - 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, - 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, - 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, - 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, - 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, - 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, - 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, - 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, - 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, - 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, - 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, - 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, - 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, - 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, - 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, - 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, - 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, - 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, - 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, - 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, - 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, - 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, - 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, - 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, - 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, - 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, - 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, - 0x0650d0f700000000}, - {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, - 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, - 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, - 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, - 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, - 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, - 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, - 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, - 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, - 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, - 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, - 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, - 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, - 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, - 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, - 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, - 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, - 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, - 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, - 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, - 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, - 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, - 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, - 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, - 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, - 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, - 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, - 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, - 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, - 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, - 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, - 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, - 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, - 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, - 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, - 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, - 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, - 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, - 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, - 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, - 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, - 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, - 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, - 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, - 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, - 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, - 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, - 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, - 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, - 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, - 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, - 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, - 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, - 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, - 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, - 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, - 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, - 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, - 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, - 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, - 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, - 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, - 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, - 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, - 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, - 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, - 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, - 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, - 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, - 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, - 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, - 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, - 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, - 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, - 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, - 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, - 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, - 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, - 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, - 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, - 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, - 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, - 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, - 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, - 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, - 0x657594e900000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, - 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, - 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, - 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, - 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, - 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, - 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, - 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, - 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, - 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, - 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, - 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, - 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, - 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, - 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, - 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, - 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, - 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, - 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, - 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, - 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, - 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, - 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, - 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, - 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, - 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, - 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, - 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, - 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, - 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, - 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, - 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, - 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, - 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, - 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, - 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, - 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, - 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, - 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, - 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, - 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, - 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, - 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, - 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, - 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, - 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, - 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, - 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, - 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, - 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, - 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, - 0xd8ac6b35}, - {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, - 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, - 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, - 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, - 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, - 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, - 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, - 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, - 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, - 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, - 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, - 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, - 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, - 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, - 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, - 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, - 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, - 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, - 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, - 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, - 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, - 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, - 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, - 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, - 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, - 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, - 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, - 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, - 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, - 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, - 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, - 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, - 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, - 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, - 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, - 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, - 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, - 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, - 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, - 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, - 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, - 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, - 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, - 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, - 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, - 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, - 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, - 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, - 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, - 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, - 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, - 0xa140efa8}, - {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, - 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, - 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, - 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, - 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, - 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, - 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, - 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, - 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, - 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, - 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, - 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, - 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, - 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, - 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, - 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, - 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, - 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, - 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, - 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, - 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, - 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, - 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, - 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, - 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, - 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, - 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, - 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, - 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, - 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, - 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, - 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, - 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, - 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, - 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, - 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, - 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, - 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, - 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, - 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, - 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, - 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, - 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, - 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, - 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, - 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, - 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, - 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, - 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, - 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, - 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, - 0x917cd6a1}, - {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, - 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, - 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, - 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, - 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, - 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, - 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, - 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, - 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, - 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, - 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, - 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, - 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, - 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, - 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, - 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, - 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, - 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, - 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, - 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, - 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, - 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, - 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, - 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, - 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, - 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, - 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, - 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, - 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, - 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, - 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, - 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, - 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, - 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, - 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, - 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, - 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, - 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, - 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, - 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, - 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, - 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, - 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, - 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, - 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, - 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, - 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, - 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, - 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, - 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, - 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, - 0x18ba364e}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, - 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, - 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, - 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, - 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, - 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, - 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, - 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, - 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, - 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, - 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, - 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, - 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, - 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, - 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, - 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, - 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, - 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, - 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, - 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, - 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, - 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, - 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, - 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, - 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, - 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, - 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, - 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, - 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, - 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, - 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, - 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, - 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, - 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, - 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, - 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, - 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, - 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, - 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, - 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, - 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, - 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, - 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, - 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, - 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, - 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, - 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, - 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, - 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, - 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, - 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, - 0x4e36ba18}, - {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, - 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, - 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, - 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, - 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, - 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, - 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, - 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, - 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, - 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, - 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, - 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, - 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, - 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, - 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, - 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, - 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, - 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, - 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, - 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, - 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, - 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, - 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, - 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, - 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, - 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, - 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, - 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, - 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, - 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, - 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, - 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, - 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, - 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, - 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, - 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, - 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, - 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, - 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, - 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, - 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, - 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, - 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, - 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, - 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, - 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, - 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, - 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, - 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, - 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, - 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, - 0xa1d67c91}, - {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, - 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, - 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, - 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, - 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, - 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, - 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, - 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, - 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, - 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, - 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, - 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, - 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, - 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, - 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, - 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, - 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, - 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, - 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, - 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, - 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, - 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, - 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, - 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, - 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, - 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, - 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, - 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, - 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, - 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, - 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, - 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, - 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, - 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, - 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, - 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, - 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, - 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, - 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, - 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, - 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, - 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, - 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, - 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, - 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, - 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, - 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, - 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, - 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, - 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, - 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, - 0xa8ef40a1}, - {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, - 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, - 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, - 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, - 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, - 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, - 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, - 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, - 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, - 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, - 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, - 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, - 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, - 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, - 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, - 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, - 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, - 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, - 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, - 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, - 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, - 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, - 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, - 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, - 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, - 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, - 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, - 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, - 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, - 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, - 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, - 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, - 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, - 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, - 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, - 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, - 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, - 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, - 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, - 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, - 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, - 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, - 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, - 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, - 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, - 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, - 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, - 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, - 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, - 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, - 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, - 0x356bacd8}}; - -#endif - -#endif - -#if N == 6 - -#if W == 8 - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, - 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, - 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, - 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, - 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, - 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, - 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, - 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, - 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, - 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, - 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, - 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, - 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, - 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, - 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, - 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, - 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, - 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, - 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, - 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, - 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, - 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, - 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, - 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, - 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, - 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, - 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, - 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, - 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, - 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, - 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, - 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, - 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, - 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, - 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, - 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, - 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, - 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, - 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, - 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, - 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, - 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, - 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, - 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, - 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, - 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, - 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, - 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, - 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, - 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, - 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, - 0x8568a0a8}, - {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, - 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, - 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, - 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, - 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, - 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, - 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, - 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, - 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, - 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, - 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, - 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, - 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, - 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, - 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, - 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, - 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, - 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, - 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, - 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, - 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, - 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, - 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, - 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, - 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, - 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, - 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, - 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, - 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, - 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, - 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, - 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, - 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, - 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, - 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, - 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, - 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, - 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, - 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, - 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, - 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, - 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, - 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, - 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, - 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, - 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, - 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, - 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, - 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, - 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, - 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, - 0x0d907052}, - {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, - 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, - 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, - 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, - 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, - 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, - 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, - 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, - 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, - 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, - 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, - 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, - 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, - 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, - 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, - 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, - 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, - 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, - 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, - 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, - 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, - 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, - 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, - 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, - 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, - 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, - 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, - 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, - 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, - 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, - 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, - 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, - 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, - 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, - 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, - 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, - 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, - 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, - 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, - 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, - 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, - 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, - 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, - 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, - 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, - 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, - 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, - 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, - 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, - 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, - 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, - 0xfd1a6c8a}, - {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, - 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, - 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, - 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, - 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, - 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, - 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, - 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, - 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, - 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, - 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, - 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, - 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, - 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, - 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, - 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, - 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, - 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, - 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, - 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, - 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, - 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, - 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, - 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, - 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, - 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, - 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, - 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, - 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, - 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, - 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, - 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, - 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, - 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, - 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, - 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, - 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, - 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, - 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, - 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, - 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, - 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, - 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, - 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, - 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, - 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, - 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, - 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, - 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, - 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, - 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, - 0x7895f01a}, - {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, - 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, - 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, - 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, - 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, - 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, - 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, - 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, - 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, - 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, - 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, - 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, - 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, - 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, - 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, - 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, - 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, - 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, - 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, - 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, - 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, - 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, - 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, - 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, - 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, - 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, - 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, - 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, - 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, - 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, - 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, - 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, - 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, - 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, - 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, - 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, - 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, - 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, - 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, - 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, - 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, - 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, - 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, - 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, - 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, - 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, - 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, - 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, - 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, - 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, - 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, - 0x9239b848}, - {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, - 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, - 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, - 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, - 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, - 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, - 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, - 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, - 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, - 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, - 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, - 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, - 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, - 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, - 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, - 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, - 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, - 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, - 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, - 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, - 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, - 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, - 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, - 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, - 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, - 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, - 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, - 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, - 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, - 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, - 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, - 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, - 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, - 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, - 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, - 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, - 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, - 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, - 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, - 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, - 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, - 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, - 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, - 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, - 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, - 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, - 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, - 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, - 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, - 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, - 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, - 0xeb36d3cc}, - {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, - 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, - 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, - 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, - 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, - 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, - 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, - 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, - 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, - 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, - 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, - 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, - 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, - 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, - 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, - 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, - 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, - 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, - 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, - 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, - 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, - 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, - 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, - 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, - 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, - 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, - 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, - 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, - 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, - 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, - 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, - 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, - 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, - 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, - 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, - 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, - 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, - 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, - 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, - 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, - 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, - 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, - 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, - 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, - 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, - 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, - 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, - 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, - 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, - 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, - 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, - 0x38e5f3c5}, - {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, - 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, - 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, - 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, - 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, - 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, - 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, - 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, - 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, - 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, - 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, - 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, - 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, - 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, - 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, - 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, - 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, - 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, - 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, - 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, - 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, - 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, - 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, - 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, - 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, - 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, - 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, - 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, - 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, - 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, - 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, - 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, - 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, - 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, - 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, - 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, - 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, - 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, - 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, - 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, - 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, - 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, - 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, - 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, - 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, - 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, - 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, - 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, - 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, - 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, - 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, - 0x3d3101a2}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, - 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, - 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, - 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, - 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, - 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, - 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, - 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, - 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, - 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, - 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, - 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, - 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, - 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, - 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, - 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, - 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, - 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, - 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, - 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, - 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, - 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, - 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, - 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, - 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, - 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, - 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, - 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, - 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, - 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, - 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, - 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, - 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, - 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, - 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, - 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, - 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, - 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, - 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, - 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, - 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, - 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, - 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, - 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, - 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, - 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, - 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, - 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, - 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, - 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, - 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, - 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, - 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, - 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, - 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, - 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, - 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, - 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, - 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, - 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, - 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, - 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, - 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, - 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, - 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, - 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, - 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, - 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, - 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, - 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, - 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, - 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, - 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, - 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, - 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, - 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, - 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, - 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, - 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, - 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, - 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, - 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, - 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, - 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, - 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, - 0xa201313d00000000}, - {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, - 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, - 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, - 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, - 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, - 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, - 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, - 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, - 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, - 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, - 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, - 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, - 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, - 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, - 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, - 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, - 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, - 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, - 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, - 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, - 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, - 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, - 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, - 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, - 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, - 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, - 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, - 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, - 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, - 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, - 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, - 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, - 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, - 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, - 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, - 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, - 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, - 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, - 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, - 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, - 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, - 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, - 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, - 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, - 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, - 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, - 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, - 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, - 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, - 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, - 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, - 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, - 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, - 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, - 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, - 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, - 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, - 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, - 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, - 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, - 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, - 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, - 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, - 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, - 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, - 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, - 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, - 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, - 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, - 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, - 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, - 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, - 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, - 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, - 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, - 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, - 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, - 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, - 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, - 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, - 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, - 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, - 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, - 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, - 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, - 0xc5f3e53800000000}, - {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, - 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, - 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, - 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, - 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, - 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, - 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, - 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, - 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, - 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, - 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, - 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, - 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, - 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, - 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, - 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, - 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, - 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, - 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, - 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, - 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, - 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, - 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, - 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, - 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, - 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, - 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, - 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, - 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, - 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, - 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, - 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, - 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, - 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, - 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, - 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, - 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, - 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, - 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, - 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, - 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, - 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, - 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, - 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, - 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, - 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, - 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, - 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, - 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, - 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, - 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, - 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, - 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, - 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, - 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, - 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, - 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, - 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, - 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, - 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, - 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, - 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, - 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, - 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, - 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, - 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, - 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, - 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, - 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, - 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, - 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, - 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, - 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, - 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, - 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, - 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, - 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, - 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, - 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, - 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, - 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, - 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, - 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, - 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, - 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, - 0xccd336eb00000000}, - {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, - 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, - 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, - 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, - 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, - 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, - 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, - 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, - 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, - 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, - 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, - 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, - 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, - 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, - 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, - 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, - 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, - 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, - 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, - 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, - 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, - 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, - 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, - 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, - 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, - 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, - 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, - 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, - 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, - 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, - 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, - 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, - 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, - 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, - 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, - 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, - 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, - 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, - 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, - 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, - 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, - 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, - 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, - 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, - 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, - 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, - 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, - 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, - 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, - 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, - 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, - 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, - 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, - 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, - 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, - 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, - 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, - 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, - 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, - 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, - 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, - 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, - 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, - 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, - 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, - 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, - 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, - 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, - 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, - 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, - 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, - 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, - 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, - 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, - 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, - 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, - 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, - 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, - 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, - 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, - 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, - 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, - 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, - 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, - 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, - 0x48b8399200000000}, - {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, - 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, - 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, - 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, - 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, - 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, - 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, - 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, - 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, - 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, - 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, - 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, - 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, - 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, - 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, - 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, - 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, - 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, - 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, - 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, - 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, - 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, - 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, - 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, - 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, - 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, - 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, - 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, - 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, - 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, - 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, - 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, - 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, - 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, - 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, - 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, - 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, - 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, - 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, - 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, - 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, - 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, - 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, - 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, - 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, - 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, - 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, - 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, - 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, - 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, - 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, - 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, - 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, - 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, - 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, - 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, - 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, - 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, - 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, - 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, - 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, - 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, - 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, - 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, - 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, - 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, - 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, - 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, - 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, - 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, - 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, - 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, - 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, - 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, - 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, - 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, - 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, - 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, - 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, - 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, - 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, - 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, - 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, - 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, - 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, - 0x1af0957800000000}, - {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, - 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, - 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, - 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, - 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, - 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, - 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, - 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, - 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, - 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, - 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, - 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, - 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, - 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, - 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, - 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, - 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, - 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, - 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, - 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, - 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, - 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, - 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, - 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, - 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, - 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, - 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, - 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, - 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, - 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, - 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, - 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, - 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, - 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, - 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, - 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, - 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, - 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, - 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, - 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, - 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, - 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, - 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, - 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, - 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, - 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, - 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, - 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, - 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, - 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, - 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, - 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, - 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, - 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, - 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, - 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, - 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, - 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, - 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, - 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, - 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, - 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, - 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, - 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, - 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, - 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, - 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, - 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, - 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, - 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, - 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, - 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, - 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, - 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, - 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, - 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, - 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, - 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, - 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, - 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, - 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, - 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, - 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, - 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, - 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, - 0x8a6c1afd00000000}, - {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, - 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, - 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, - 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, - 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, - 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, - 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, - 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, - 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, - 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, - 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, - 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, - 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, - 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, - 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, - 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, - 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, - 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, - 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, - 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, - 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, - 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, - 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, - 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, - 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, - 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, - 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, - 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, - 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, - 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, - 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, - 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, - 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, - 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, - 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, - 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, - 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, - 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, - 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, - 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, - 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, - 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, - 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, - 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, - 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, - 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, - 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, - 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, - 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, - 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, - 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, - 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, - 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, - 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, - 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, - 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, - 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, - 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, - 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, - 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, - 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, - 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, - 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, - 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, - 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, - 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, - 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, - 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, - 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, - 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, - 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, - 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, - 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, - 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, - 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, - 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, - 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, - 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, - 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, - 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, - 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, - 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, - 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, - 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, - 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, - 0x5270900d00000000}, - {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, - 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, - 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, - 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, - 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, - 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, - 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, - 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, - 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, - 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, - 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, - 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, - 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, - 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, - 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, - 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, - 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, - 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, - 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, - 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, - 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, - 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, - 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, - 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, - 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, - 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, - 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, - 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, - 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, - 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, - 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, - 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, - 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, - 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, - 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, - 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, - 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, - 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, - 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, - 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, - 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, - 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, - 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, - 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, - 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, - 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, - 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, - 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, - 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, - 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, - 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, - 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, - 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, - 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, - 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, - 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, - 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, - 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, - 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, - 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, - 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, - 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, - 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, - 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, - 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, - 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, - 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, - 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, - 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, - 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, - 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, - 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, - 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, - 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, - 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, - 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, - 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, - 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, - 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, - 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, - 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, - 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, - 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, - 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, - 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, - 0xa8a0688500000000}}; - -#else /* W == 4 */ - -local const z_crc_t FAR crc_braid_table[][256] = { - {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, - 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, - 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, - 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, - 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, - 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, - 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, - 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, - 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, - 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, - 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, - 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, - 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, - 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, - 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, - 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, - 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, - 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, - 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, - 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, - 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, - 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, - 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, - 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, - 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, - 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, - 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, - 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, - 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, - 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, - 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, - 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, - 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, - 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, - 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, - 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, - 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, - 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, - 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, - 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, - 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, - 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, - 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, - 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, - 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, - 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, - 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, - 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, - 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, - 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, - 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, - 0x09cd8551}, - {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, - 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, - 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, - 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, - 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, - 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, - 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, - 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, - 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, - 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, - 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, - 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, - 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, - 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, - 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, - 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, - 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, - 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, - 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, - 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, - 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, - 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, - 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, - 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, - 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, - 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, - 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, - 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, - 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, - 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, - 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, - 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, - 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, - 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, - 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, - 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, - 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, - 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, - 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, - 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, - 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, - 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, - 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, - 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, - 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, - 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, - 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, - 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, - 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, - 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, - 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, - 0x7bc97a0c}, - {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, - 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, - 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, - 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, - 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, - 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, - 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, - 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, - 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, - 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, - 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, - 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, - 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, - 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, - 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, - 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, - 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, - 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, - 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, - 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, - 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, - 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, - 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, - 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, - 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, - 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, - 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, - 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, - 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, - 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, - 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, - 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, - 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, - 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, - 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, - 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, - 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, - 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, - 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, - 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, - 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, - 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, - 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, - 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, - 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, - 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, - 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, - 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, - 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, - 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, - 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, - 0x7851a2ca}, - {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, - 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, - 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, - 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, - 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, - 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, - 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, - 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, - 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, - 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, - 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, - 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, - 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, - 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, - 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, - 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, - 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, - 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, - 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, - 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, - 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, - 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, - 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, - 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, - 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, - 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, - 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, - 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, - 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, - 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, - 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, - 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, - 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, - 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, - 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, - 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, - 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, - 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, - 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, - 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, - 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, - 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, - 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, - 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, - 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, - 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, - 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, - 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, - 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, - 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, - 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, - 0x566b6848}}; - -local const z_word_t FAR crc_braid_big_table[][256] = { - {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, - 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, - 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, - 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, - 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, - 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, - 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, - 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, - 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, - 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, - 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, - 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, - 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, - 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, - 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, - 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, - 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, - 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, - 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, - 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, - 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, - 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, - 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, - 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, - 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, - 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, - 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, - 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, - 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, - 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, - 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, - 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, - 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, - 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, - 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, - 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, - 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, - 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, - 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, - 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, - 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, - 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, - 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, - 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, - 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, - 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, - 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, - 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, - 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, - 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, - 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, - 0x48686b56}, - {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, - 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, - 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, - 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, - 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, - 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, - 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, - 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, - 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, - 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, - 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, - 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, - 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, - 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, - 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, - 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, - 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, - 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, - 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, - 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, - 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, - 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, - 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, - 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, - 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, - 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, - 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, - 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, - 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, - 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, - 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, - 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, - 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, - 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, - 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, - 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, - 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, - 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, - 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, - 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, - 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, - 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, - 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, - 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, - 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, - 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, - 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, - 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, - 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, - 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, - 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, - 0xcaa25178}, - {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, - 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, - 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, - 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, - 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, - 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, - 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, - 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, - 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, - 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, - 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, - 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, - 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, - 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, - 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, - 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, - 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, - 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, - 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, - 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, - 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, - 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, - 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, - 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, - 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, - 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, - 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, - 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, - 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, - 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, - 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, - 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, - 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, - 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, - 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, - 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, - 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, - 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, - 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, - 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, - 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, - 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, - 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, - 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, - 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, - 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, - 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, - 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, - 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, - 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, - 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, - 0x0c7ac97b}, - {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, - 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, - 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, - 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, - 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, - 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, - 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, - 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, - 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, - 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, - 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, - 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, - 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, - 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, - 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, - 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, - 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, - 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, - 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, - 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, - 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, - 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, - 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, - 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, - 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, - 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, - 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, - 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, - 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, - 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, - 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, - 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, - 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, - 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, - 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, - 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, - 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, - 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, - 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, - 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, - 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, - 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, - 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, - 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, - 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, - 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, - 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, - 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, - 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, - 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, - 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, - 0x5185cd09}}; - -#endif - -#endif - -#endif - -local const z_crc_t FAR x2n_table[] = { - 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, - 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, - 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, - 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, - 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, - 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, - 0xc40ba6d0, 0xc4e22c3c}; diff --git a/libraries/zlib/deflate.c b/libraries/zlib/deflate.c deleted file mode 100644 index bd0117519..000000000 --- a/libraries/zlib/deflate.c +++ /dev/null @@ -1,2114 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://tools.ietf.org/html/rfc1951 - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.3 Copyright 1995-2023 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func)(deflate_state *s, int flush); -/* Compression function. Returns the block state after the call. */ - -local block_state deflate_stored(deflate_state *s, int flush); -local block_state deflate_fast(deflate_state *s, int flush); -#ifndef FASTEST -local block_state deflate_slow(deflate_state *s, int flush); -#endif -local block_state deflate_rle(deflate_state *s, int flush); -local block_state deflate_huff(deflate_state *s, int flush); - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to UPDATE_HASH are made with consecutive input - * characters, so that a running hash key can be computed from the previous - * key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to INSERT_STRING are made with consecutive input - * characters and the first MIN_MATCH bytes of str are valid (except for - * the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - do { \ - s->head[s->hash_size - 1] = NIL; \ - zmemzero((Bytef *)s->head, \ - (unsigned)(s->hash_size - 1)*sizeof(*s->head)); \ - } while (0) - -/* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ -#if defined(__has_feature) -# if __has_feature(memory_sanitizer) - __attribute__((no_sanitize("memory"))) -# endif -#endif -local void slide_hash(deflate_state *s) { - unsigned n, m; - Posf *p; - uInt wsize = s->w_size; - - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - } while (--n); - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local unsigned read_buf(z_streamp strm, Bytef *buf, unsigned size) { - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return len; -} - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(deflate_state *s) { - unsigned n; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize + MAX_DIST(s)) { - - zmemcpy(s->window, s->window + wsize, (unsigned)wsize - more); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - if (s->insert > s->strstart) - s->insert = s->strstart; - slide_hash(s); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - -/* ========================================================================= */ -int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, - int stream_size) { - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, - int windowBits, int memLevel, int strategy, - const char *version, int stream_size) { - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - if (windowBits < -15) - return Z_STREAM_ERROR; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - s->status = INIT_STATE; /* to pass state test in deflateReset() */ - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = (uInt)windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = (uInt)memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits + MIN_MATCH-1) / MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - /* We overlay pending_buf and sym_buf. This works since the average size - * for length/distance pairs over any compressed block is assured to be 31 - * bits or less. - * - * Analysis: The longest fixed codes are a length code of 8 bits plus 5 - * extra bits, for lengths 131 to 257. The longest fixed distance codes are - * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest - * possible fixed-codes length/distance pair is then 31 bits total. - * - * sym_buf starts one-fourth of the way into pending_buf. So there are - * three bytes in sym_buf for every four bytes in pending_buf. Each symbol - * in sym_buf is three bytes -- two for the distance and one for the - * literal/length. As each symbol is consumed, the pointer to the next - * sym_buf value to read moves forward three bytes. From that symbol, up to - * 31 bits are written to pending_buf. The closest the written pending_buf - * bits gets to the next sym_buf symbol to read is just before the last - * code is written. At that time, 31*(n - 2) bits have been written, just - * after 24*(n - 2) bits have been consumed from sym_buf. sym_buf starts at - * 8*n bits into pending_buf. (Note that the symbol buffer fills when n - 1 - * symbols are written.) The closest the writing gets to what is unread is - * then n + 14 bits. Here n is lit_bufsize, which is 16384 by default, and - * can range from 128 to 32768. - * - * Therefore, at a minimum, there are 142 bits of space between what is - * written and what is read in the overlain buffers, so the symbols cannot - * be overwritten by the compressed data. That space is actually 139 bits, - * due to the three-bit fixed-code block header. - * - * That covers the case where either Z_FIXED is specified, forcing fixed - * codes, or when the use of fixed codes is chosen, because that choice - * results in a smaller compressed block than dynamic codes. That latter - * condition then assures that the above analysis also covers all dynamic - * blocks. A dynamic-code block will only be chosen to be emitted if it has - * fewer bits than a fixed-code block would for the same set of symbols. - * Therefore its average symbol length is assured to be less than 31. So - * the compressed data for a dynamic block also cannot overwrite the - * symbols from which it is being constructed. - */ - - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); - s->pending_buf_size = (ulg)s->lit_bufsize * 4; - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->sym_buf = s->pending_buf + s->lit_bufsize; - s->sym_end = (s->lit_bufsize - 1) * 3; - /* We avoid equality with lit_bufsize*3 because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ -local int deflateStateCheck(z_streamp strm) { - deflate_state *s; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - s = strm->state; - if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && -#ifdef GZIP - s->status != GZIP_STATE && -#endif - s->status != EXTRA_STATE && - s->status != NAME_STATE && - s->status != COMMENT_STATE && - s->status != HCRC_STATE && - s->status != BUSY_STATE && - s->status != FINISH_STATE)) - return 1; - return 0; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary(z_streamp strm, const Bytef *dictionary, - uInt dictLength) { - deflate_state *s; - uInt str, n; - int wrap; - unsigned avail; - z_const unsigned char *next; - - if (deflateStateCheck(strm) || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } - - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (z_const Bytef *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH-1); - do { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - } while (--n); - s->strstart = str; - s->lookahead = MIN_MATCH-1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateGetDictionary(z_streamp strm, Bytef *dictionary, - uInt *dictLength) { - deflate_state *s; - uInt len; - - if (deflateStateCheck(strm)) - return Z_STREAM_ERROR; - s = strm->state; - len = s->strstart + s->lookahead; - if (len > s->w_size) - len = s->w_size; - if (dictionary != Z_NULL && len) - zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); - if (dictLength != Z_NULL) - *dictLength = len; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateResetKeep(z_streamp strm) { - deflate_state *s; - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = -#ifdef GZIP - s->wrap == 2 ? GZIP_STATE : -#endif - INIT_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = -2; - - _tr_init(s); - - return Z_OK; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init(deflate_state *s) { - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset(z_streamp strm) { - int ret; - - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader(z_streamp strm, gz_headerp head) { - if (deflateStateCheck(strm) || strm->state->wrap != 2) - return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePending(z_streamp strm, unsigned *pending, int *bits) { - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { - deflate_state *s; - int put; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - if (bits < 0 || bits > 16 || - s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(z_streamp strm, int level, int strategy) { - deflate_state *s; - compress_func func; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - s->last_flush != -2) { - /* Flush the last buffer: */ - int err = deflate(strm, Z_BLOCK); - if (err == Z_STREAM_ERROR) - return err; - if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead) - return Z_BUF_ERROR; - } - if (s->level != level) { - if (s->level == 0 && s->matches != 0) { - if (s->matches == 1) - slide_hash(s); - else - CLEAR_HASH(s); - s->matches = 0; - } - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, - int nice_length, int max_chain) { - deflate_state *s; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = (uInt)good_length; - s->max_lazy_match = (uInt)max_lazy; - s->nice_match = nice_length; - s->max_chain_length = (uInt)max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns a - * close to exact, as well as small, upper bound on the compressed size. This - * is an expansion of ~0.03%, plus a small constant. - * - * For any setting other than those defaults for windowBits and memLevel, one - * of two worst case bounds is returned. This is at most an expansion of ~4% or - * ~13%, plus a small constant. - * - * Both the 0.03% and 4% derive from the overhead of stored blocks. The first - * one is for stored blocks of 16383 bytes (memLevel == 8), whereas the second - * is for stored blocks of 127 bytes (the worst case memLevel == 1). The - * expansion results from five bytes of header for each stored block. - * - * The larger expansion of 13% results from a window size less than or equal to - * the symbols buffer size (windowBits <= memLevel + 7). In that case some of - * the data being compressed may have slid out of the sliding window, impeding - * a stored block from being emitted. Then the only choice is a fixed or - * dynamic block, where a fixed block limits the maximum expansion to 9 bits - * per 8-bit byte, plus 10 bits for every block. The smallest block size for - * which this can occur is 255 (memLevel == 2). - * - * Shifts are used to approximate divisions, for speed. - */ -uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen) { - deflate_state *s; - uLong fixedlen, storelen, wraplen; - - /* upper bound for fixed blocks with 9-bit literals and length 255 - (memLevel == 2, which is the lowest that may not use stored blocks) -- - ~13% overhead plus a small constant */ - fixedlen = sourceLen + (sourceLen >> 3) + (sourceLen >> 8) + - (sourceLen >> 9) + 4; - - /* upper bound for stored blocks with length 127 (memLevel == 1) -- - ~4% overhead plus a small constant */ - storelen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + - (sourceLen >> 11) + 7; - - /* if can't get parameters, return larger bound plus a zlib wrapper */ - if (deflateStateCheck(strm)) - return (fixedlen > storelen ? fixedlen : storelen) + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; -#ifdef GZIP - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - Bytef *str; - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; -#endif - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return one of the conservative bounds */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return (s->w_bits <= s->hash_bits && s->level ? fixedlen : storelen) + - wraplen; - - /* default settings: return tight bound for that case -- ~0.03% overhead - plus a small constant */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB(deflate_state *s, uInt b) { - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ -local void flush_pending(z_streamp strm) { - unsigned len; - deflate_state *s = strm->state; - - _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* =========================================================================== - * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. - */ -#define HCRC_UPDATE(beg) \ - do { \ - if (s->gzhead->hcrc && s->pending > (beg)) \ - strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ - s->pending - (beg)); \ - } while (0) - -/* ========================================================================= */ -int ZEXPORT deflate(z_streamp strm, int flush) { - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->avail_in != 0 && strm->next_in == Z_NULL) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - old_flush = s->last_flush; - s->last_flush = flush; - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Write the header */ - if (s->status == INIT_STATE && s->wrap == 0) - s->status = BUSY_STATE; - if (s->status == INIT_STATE) { - /* zlib header */ - uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#ifdef GZIP - if (s->status == GZIP_STATE) { - /* gzip header */ - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; - while (s->pending + left > s->pending_buf_size) { - uInt copy = s->pending_buf_size - s->pending; - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, copy); - s->pending = s->pending_buf_size; - HCRC_UPDATE(beg); - s->gzindex += copy; - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - left -= copy; - } - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, left); - s->pending += left; - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - } - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) { - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - } - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#endif - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->level == 0 ? deflate_stored(s, flush) : - s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd(z_streamp strm) { - int status; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - - status = strm->state->status; - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { -#ifdef MAXSEG_64K - (void)dest; - (void)source; - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - - - if (deflateStateCheck(source) || dest == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->sym_buf = ds->pending_buf + ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -local uInt longest_match(deflate_state *s, IPos cur_match) { - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = (int)s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan + best_len - 1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len - 1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match + best_len - 1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart + 3, + 5, up to strstart + 257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart + 257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan += 2) == *(ushf*)(match += 2) && - *(ushf*)(scan += 2) == *(ushf*)(match += 2) && - *(ushf*)(scan += 2) == *(ushf*)(match += 2) && - *(ushf*)(scan += 2) == *(ushf*)(match += 2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window + strstart + 257 */ - Assert(scan <= s->window + (unsigned)(s->window_size - 1), - "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend - scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len - 1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len - 1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart + 258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window + (unsigned)(s->window_size - 1), - "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan + best_len - 1); -#else - scan_end1 = scan[best_len - 1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(deflate_state *s, IPos cur_match) { - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len - 1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart + 258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef ZLIB_DEBUG - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(deflate_state *s, IPos start, IPos match, int length) { - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start - match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* ZLIB_DEBUG */ - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* Maximum stored block length in deflate format (not including header). */ -#define MAX_STORED 65535 - -/* Minimum of a and b. */ -#define MIN(a, b) ((a) > (b) ? (b) : (a)) - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunities to have a single copy from next_in to next_out. - */ -local block_state deflate_stored(deflate_state *s, int flush) { - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - unsigned len, left, have, last = 0; - unsigned used = s->strm->avail_in; - do { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = MAX_STORED; /* maximum deflate stored block length */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - if (s->strm->avail_out < have) /* need room for header */ - break; - /* maximum stored block length that will fit in avail_out: */ - have = s->strm->avail_out - have; - left = s->strstart - s->block_start; /* bytes left in window */ - if (len > (ulg)left + s->strm->avail_in) - len = left + s->strm->avail_in; /* limit len to the input */ - if (len > have) - len = have; /* limit len to the output */ - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && ((len == 0 && flush != Z_FINISH) || - flush == Z_NO_FLUSH || - len != left + s->strm->avail_in)) - break; - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; - _tr_stored_block(s, (char *)0, 0L, last); - - /* Replace the lengths in the dummy stored block with len. */ - s->pending_buf[s->pending - 4] = len; - s->pending_buf[s->pending - 3] = len >> 8; - s->pending_buf[s->pending - 2] = ~len; - s->pending_buf[s->pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending(s->strm); - -#ifdef ZLIB_DEBUG - /* Update debugging counts for the data about to be copied. */ - s->compressed_len += len << 3; - s->bits_sent += len << 3; -#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - if (left > len) - left = len; - zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s->strm->next_out += left; - s->strm->avail_out -= left; - s->strm->total_out += left; - s->block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf(s->strm, s->strm->next_out, len); - s->strm->next_out += len; - s->strm->avail_out -= len; - s->strm->total_out += len; - } - } while (last == 0); - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s->strm->avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s->w_size) { /* supplant the previous history */ - s->matches = 2; /* clear hash */ - zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s->strstart = s->w_size; - s->insert = s->strstart; - } - else { - if (s->window_size - s->strstart <= used) { - /* Slide the window down. */ - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - if (s->insert > s->strstart) - s->insert = s->strstart; - } - zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s->strstart += used; - s->insert += MIN(used, s->w_size - s->insert); - } - s->block_start = s->strstart; - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* If the last block was written to next_out, then done. */ - if (last) - return finish_done; - - /* If flushing and all input has been consumed, then done. */ - if (flush != Z_NO_FLUSH && flush != Z_FINISH && - s->strm->avail_in == 0 && (long)s->strstart == s->block_start) - return block_done; - - /* Fill the window with any remaining input. */ - have = s->window_size - s->strstart; - if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { - /* Slide the window down. */ - s->block_start -= s->w_size; - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - have += s->w_size; /* more space now */ - if (s->insert > s->strstart) - s->insert = s->strstart; - } - if (have > s->strm->avail_in) - have = s->strm->avail_in; - if (have) { - read_buf(s->strm, s->window + s->strstart, have); - s->strstart += have; - s->insert += MIN(have, s->w_size - s->insert); - } - if (s->high_water < s->strstart) - s->high_water = s->strstart; - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = MIN(s->pending_buf_size - have, MAX_STORED); - min_block = MIN(have, s->w_size); - left = s->strstart - s->block_start; - if (left >= min_block || - ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && - s->strm->avail_in == 0 && left <= have)) { - len = MIN(left, have); - last = flush == Z_FINISH && s->strm->avail_in == 0 && - len == left ? 1 : 0; - _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); - s->block_start += len; - flush_pending(s->strm); - } - - /* We've done all we can with the available input and output. */ - return last ? finish_started : need_more; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(deflate_state *s, int flush) { - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart + 2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(deflate_state *s, int flush) { - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart + 2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart - 1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart - 1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart - 1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length - 1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart - 1])); - _tr_tally_lit(s, s->window[s->strstart - 1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart - 1])); - _tr_tally_lit(s, s->window[s->strstart - 1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(deflate_state *s, int flush) { - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (uInt)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window + (uInt)(s->window_size - 1), - "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(deflate_state *s, int flush) { - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit(s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->sym_next) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/libraries/zlib/deflate.h b/libraries/zlib/deflate.h deleted file mode 100644 index 869679142..000000000 --- a/libraries/zlib/deflate.h +++ /dev/null @@ -1,346 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2018 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 /* zlib header -> BUSY_STATE */ -#ifdef GZIP -# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ -#endif -#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ -#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ -#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ -#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ -#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ -#define FINISH_STATE 666 /* stream complete */ -/* 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 */ - const 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 */ - ulg 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 */ - ulg 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 *sym_buf; /* buffer for distances and literals/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 sym_next; /* running index in sym_buf */ - uInt sym_end; /* symbol table full when sym_next reaches this */ - - 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 ZLIB_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++] = (Bytef)(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(deflate_state *s); -int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc); -void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, - ulg stored_len, int last); -void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s); -void ZLIB_INTERNAL _tr_align(deflate_state *s); -void ZLIB_INTERNAL _tr_stored_block(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 ZLIB_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->sym_buf[s->sym_next++] = 0; \ - s->sym_buf[s->sym_next++] = 0; \ - s->sym_buf[s->sym_next++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ - s->sym_buf[s->sym_next++] = (uch)dist; \ - s->sym_buf[s->sym_next++] = (uch)(dist >> 8); \ - s->sym_buf[s->sym_next++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->sym_next == s->sym_end); \ - } -#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/libraries/zlib/example.c b/libraries/zlib/example.c deleted file mode 100644 index 604736f15..000000000 --- a/libraries/zlib/example.c +++ /dev/null @@ -1,565 +0,0 @@ -/* example.c -- usage example of the zlib compression library - * Copyright (C) 1995-2006 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zlib.h" -#include - -#ifdef STDC -# include -# include -#endif - -#if defined(VMS) || defined(RISCOS) -# define TESTFILE "foo-gz" -#else -# define TESTFILE "foo.gz" -#endif - -#define CHECK_ERR(err, msg) { \ - if (err != Z_OK) { \ - fprintf(stderr, "%s error: %d\n", msg, err); \ - exit(1); \ - } \ -} - -const char hello[] = "hello, hello!"; -/* "hello world" would be more standard, but the repeated "hello" - * stresses the compression code better, sorry... - */ - -const char dictionary[] = "hello"; -uLong dictId; /* Adler32 value of the dictionary */ - -void test_compress OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_gzio OF((const char *fname, - Byte *uncompr, uLong uncomprLen)); -void test_deflate OF((Byte *compr, uLong comprLen)); -void test_inflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_large_deflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_large_inflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_flush OF((Byte *compr, uLong *comprLen)); -void test_sync OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_dict_deflate OF((Byte *compr, uLong comprLen)); -void test_dict_inflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -int main OF((int argc, char *argv[])); - -/* =========================================================================== - * Test compress() and uncompress() - */ -void test_compress(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - uLong len = (uLong)strlen(hello)+1; - - err = compress(compr, &comprLen, (const Bytef*)hello, len); - CHECK_ERR(err, "compress"); - - strcpy((char*)uncompr, "garbage"); - - err = uncompress(uncompr, &uncomprLen, compr, comprLen); - CHECK_ERR(err, "uncompress"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad uncompress\n"); - exit(1); - } else { - printf("uncompress(): %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Test read/write of .gz files - */ -void test_gzio(fname, uncompr, uncomprLen) - const char *fname; /* compressed file name */ - Byte *uncompr; - uLong uncomprLen; -{ -#ifdef NO_GZCOMPRESS - fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); -#else - int err; - int len = (int)strlen(hello)+1; - gzFile file; - z_off_t pos; - - file = gzopen(fname, "wb"); - if (file == NULL) { - fprintf(stderr, "gzopen error\n"); - exit(1); - } - gzputc(file, 'h'); - if (gzputs(file, "ello") != 4) { - fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); - exit(1); - } - if (gzprintf(file, ", %s!", "hello") != 8) { - fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); - exit(1); - } - gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ - gzclose(file); - - file = gzopen(fname, "rb"); - if (file == NULL) { - fprintf(stderr, "gzopen error\n"); - exit(1); - } - strcpy((char*)uncompr, "garbage"); - - if (gzread(file, uncompr, (unsigned)uncomprLen) != len) { - fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); - exit(1); - } - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); - exit(1); - } else { - printf("gzread(): %s\n", (char*)uncompr); - } - - pos = gzseek(file, -8L, SEEK_CUR); - if (pos != 6 || gztell(file) != pos) { - fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", - (long)pos, (long)gztell(file)); - exit(1); - } - - if (gzgetc(file) != ' ') { - fprintf(stderr, "gzgetc error\n"); - exit(1); - } - - if (gzungetc(' ', file) != ' ') { - fprintf(stderr, "gzungetc error\n"); - exit(1); - } - - gzgets(file, (char*)uncompr, (int)uncomprLen); - if (strlen((char*)uncompr) != 7) { /* " hello!" */ - fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); - exit(1); - } - if (strcmp((char*)uncompr, hello + 6)) { - fprintf(stderr, "bad gzgets after gzseek\n"); - exit(1); - } else { - printf("gzgets() after gzseek: %s\n", (char*)uncompr); - } - - gzclose(file); -#endif -} - -/* =========================================================================== - * Test deflate() with small buffers - */ -void test_deflate(compr, comprLen) - Byte *compr; - uLong comprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - uLong len = (uLong)strlen(hello)+1; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_in = (Bytef*)hello; - c_stream.next_out = compr; - - while (c_stream.total_in != len && c_stream.total_out < comprLen) { - c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - } - /* Finish the stream, still forcing small buffers: */ - for (;;) { - c_stream.avail_out = 1; - err = deflate(&c_stream, Z_FINISH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "deflate"); - } - - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with small buffers - */ -void test_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = 0; - d_stream.next_out = uncompr; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { - d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "inflate"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad inflate\n"); - exit(1); - } else { - printf("inflate(): %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Test deflate() with large buffers and dynamic change of compression level - */ -void test_large_deflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_BEST_SPEED); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_out = compr; - c_stream.avail_out = (uInt)comprLen; - - /* At this point, uncompr is still mostly zeroes, so it should compress - * very well: - */ - c_stream.next_in = uncompr; - c_stream.avail_in = (uInt)uncomprLen; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - if (c_stream.avail_in != 0) { - fprintf(stderr, "deflate not greedy\n"); - exit(1); - } - - /* Feed in already compressed data and switch to no compression: */ - deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); - c_stream.next_in = compr; - c_stream.avail_in = (uInt)comprLen/2; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - - /* Switch back to compressing mode: */ - deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); - c_stream.next_in = uncompr; - c_stream.avail_in = (uInt)uncomprLen; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - fprintf(stderr, "deflate should report Z_STREAM_END\n"); - exit(1); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with large buffers - */ -void test_large_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = (uInt)comprLen; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - for (;;) { - d_stream.next_out = uncompr; /* discard the output */ - d_stream.avail_out = (uInt)uncomprLen; - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "large inflate"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (d_stream.total_out != 2*uncomprLen + comprLen/2) { - fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); - exit(1); - } else { - printf("large_inflate(): OK\n"); - } -} - -/* =========================================================================== - * Test deflate() with full flush - */ -void test_flush(compr, comprLen) - Byte *compr; - uLong *comprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - uInt len = (uInt)strlen(hello)+1; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_in = (Bytef*)hello; - c_stream.next_out = compr; - c_stream.avail_in = 3; - c_stream.avail_out = (uInt)*comprLen; - err = deflate(&c_stream, Z_FULL_FLUSH); - CHECK_ERR(err, "deflate"); - - compr[3]++; /* force an error in first compressed block */ - c_stream.avail_in = len - 3; - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - CHECK_ERR(err, "deflate"); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); - - *comprLen = c_stream.total_out; -} - -/* =========================================================================== - * Test inflateSync() - */ -void test_sync(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = 2; /* just read the zlib header */ - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - d_stream.next_out = uncompr; - d_stream.avail_out = (uInt)uncomprLen; - - inflate(&d_stream, Z_NO_FLUSH); - CHECK_ERR(err, "inflate"); - - d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ - err = inflateSync(&d_stream); /* but skip the damaged part */ - CHECK_ERR(err, "inflateSync"); - - err = inflate(&d_stream, Z_FINISH); - if (err != Z_DATA_ERROR) { - fprintf(stderr, "inflate should report DATA_ERROR\n"); - /* Because of incorrect adler32 */ - exit(1); - } - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - printf("after inflateSync(): hel%s\n", (char *)uncompr); -} - -/* =========================================================================== - * Test deflate() with preset dictionary - */ -void test_dict_deflate(compr, comprLen) - Byte *compr; - uLong comprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_BEST_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - err = deflateSetDictionary(&c_stream, - (const Bytef*)dictionary, sizeof(dictionary)); - CHECK_ERR(err, "deflateSetDictionary"); - - dictId = c_stream.adler; - c_stream.next_out = compr; - c_stream.avail_out = (uInt)comprLen; - - c_stream.next_in = (Bytef*)hello; - c_stream.avail_in = (uInt)strlen(hello)+1; - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - fprintf(stderr, "deflate should report Z_STREAM_END\n"); - exit(1); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with a preset dictionary - */ -void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = (uInt)comprLen; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - d_stream.next_out = uncompr; - d_stream.avail_out = (uInt)uncomprLen; - - for (;;) { - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - if (err == Z_NEED_DICT) { - if (d_stream.adler != dictId) { - fprintf(stderr, "unexpected dictionary"); - exit(1); - } - err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, - sizeof(dictionary)); - } - CHECK_ERR(err, "inflate with dict"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad inflate with dict\n"); - exit(1); - } else { - printf("inflate with dictionary: %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Usage: example [output.gz [input.gz]] - */ - -int main(argc, argv) - int argc; - char *argv[]; -{ - Byte *compr, *uncompr; - uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ - uLong uncomprLen = comprLen; - static const char* myVersion = ZLIB_VERSION; - - if (zlibVersion()[0] != myVersion[0]) { - fprintf(stderr, "incompatible zlib version\n"); - exit(1); - - } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { - fprintf(stderr, "warning: different zlib version\n"); - } - - printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", - ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); - - compr = (Byte*)calloc((uInt)comprLen, 1); - uncompr = (Byte*)calloc((uInt)uncomprLen, 1); - /* compr and uncompr are cleared to avoid reading uninitialized - * data and to ensure that uncompr compresses well. - */ - if (compr == Z_NULL || uncompr == Z_NULL) { - printf("out of memory\n"); - exit(1); - } - test_compress(compr, comprLen, uncompr, uncomprLen); - - test_gzio((argc > 1 ? argv[1] : TESTFILE), - uncompr, uncomprLen); - - test_deflate(compr, comprLen); - test_inflate(compr, comprLen, uncompr, uncomprLen); - - test_large_deflate(compr, comprLen, uncompr, uncomprLen); - test_large_inflate(compr, comprLen, uncompr, uncomprLen); - - test_flush(compr, &comprLen); - test_sync(compr, comprLen, uncompr, uncomprLen); - comprLen = uncomprLen; - - test_dict_deflate(compr, comprLen); - test_dict_inflate(compr, comprLen, uncompr, uncomprLen); - - free(compr); - free(uncompr); - - return 0; -} diff --git a/libraries/zlib/gzguts.h b/libraries/zlib/gzguts.h deleted file mode 100644 index f9375047e..000000000 --- a/libraries/zlib/gzguts.h +++ /dev/null @@ -1,218 +0,0 @@ -/* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2019 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 -# undef _FILE_OFFSET_BITS -# undef _TIME_BITS -#endif - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include -#include "zlib.h" -#ifdef STDC -# include -# include -# include -#endif - -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif -#include - -#ifdef _WIN32 -# include -#endif - -#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) -# include -#endif - -#if defined(_WIN32) -# define WIDECHAR -#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), _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 */ -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -/* gz* functions always use library allocation functions */ -#ifndef STDC - extern voidp malloc(uInt size); - extern void free(voidpf ptr); -#endif - -/* get errno and strerror definition */ -#if defined UNDER_CE -# include -# define zstrerror() gz_strwinerror((DWORD)GetLastError()) -#else -# ifndef NO_STRERROR -# include -# 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(const char *, const char *); - ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); - ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off64_t ZEXPORT gzoffset64(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 (double-sized when writing) */ - 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 */ - int reset; /* true if a reset is pending after a Z_FINISH */ - /* 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(gz_statep, int, const char *); -#if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror(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(void); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif diff --git a/libraries/zlib/infback.c b/libraries/zlib/infback.c deleted file mode 100644 index e7b25b307..000000000 --- a/libraries/zlib/infback.c +++ /dev/null @@ -1,628 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, - unsigned char FAR *window, const char *version, - int stream_size) { - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = (uInt)windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - state->sane = 1; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(struct inflate_state FAR *state) { -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc) { - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - /* fallthrough */ - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly */ - ret = Z_STREAM_END; - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: - /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Write leftover output and return unused input */ - inf_leave: - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left) && - ret == Z_STREAM_END) - ret = Z_BUF_ERROR; - } - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(z_streamp strm) { - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/libraries/zlib/inffast.c b/libraries/zlib/inffast.c deleted file mode 100644 index 9354676e7..000000000 --- a/libraries/zlib/inffast.c +++ /dev/null @@ -1,320 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2017 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef ASMINF -# pragma message("Assembler code may have bugs -- use at your own risk") -#else - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { - struct inflate_state FAR *state; - z_const unsigned char FAR *in; /* local strm->next_in */ - z_const unsigned char FAR *last; /* have enough input while in < last */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - 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 wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code const *here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in; - last = in + (strm->avail_in - 5); - out = strm->next_out; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = lcode + (hold & lmask); - dolen: - op = (unsigned)(here->bits); - hold >>= op; - bits -= op; - op = (unsigned)(here->op); - if (op == 0) { /* literal */ - Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here->val)); - *out++ = (unsigned char)(here->val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here->val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = dcode + (hold & dmask); - dodist: - op = (unsigned)(here->bits); - hold >>= op; - bits -= op; - op = (unsigned)(here->op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here->val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - *out++ = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - *out++ = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - *out++ = *from++; - } while (--len); - continue; - } -#endif - } - from = window; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = window; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } while (len > 2); - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode + here->val + (hold & ((1U << op) - 1)); - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode + here->val + (hold & ((1U << op) - 1)); - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in; - strm->next_out = out; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/libraries/zlib/inffast.h b/libraries/zlib/inffast.h deleted file mode 100644 index 49c6d156c..000000000 --- a/libraries/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* 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(z_streamp strm, unsigned start); diff --git a/libraries/zlib/inffixed.h b/libraries/zlib/inffixed.h deleted file mode 100644 index d62832776..000000000 --- a/libraries/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* 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/libraries/zlib/inflate.c b/libraries/zlib/inflate.c deleted file mode 100644 index b0757a9b2..000000000 --- a/libraries/zlib/inflate.c +++ /dev/null @@ -1,1526 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2022 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -local int inflateStateCheck(z_streamp strm) { - struct inflate_state FAR *state; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - state = (struct inflate_state FAR *)strm->state; - if (state == Z_NULL || state->strm != strm || - state->mode < HEAD || state->mode > SYNC) - return 1; - return 0; -} - -int ZEXPORT inflateResetKeep(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->flags = -1; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - if (windowBits < -15) - return Z_STREAM_ERROR; - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, - const char *version, int stream_size) { - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->strm = strm; - state->window = Z_NULL; - state->mode = HEAD; /* to pass state test in inflateReset2() */ - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(z_streamp strm, const char *version, - int stream_size) { - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - if (bits == 0) - return Z_OK; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += (unsigned)value << state->bits; - state->bits += (uInt)bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(struct inflate_state FAR *state) { -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed(void) -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { - struct inflate_state FAR *state; - unsigned dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { - zmemcpy(state->window, end - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, end - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, end - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE_CHECK(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(z_streamp strm, int flush) { - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (inflateStateCheck(strm) || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - if (state->wbits == 0) - state->wbits = 15; - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - state->flags = 0; /* indicate zlib header */ - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - /* fallthrough */ - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - /* fallthrough */ - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - /* fallthrough */ - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - /* fallthrough */ - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL && - (len = state->head->extra_len - state->length) < - state->head->extra_max) { - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - /* fallthrough */ - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - /* fallthrough */ - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - /* fallthrough */ - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if ((state->wrap & 4) && hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); - INITBITS(); - state->mode = DICT; - /* fallthrough */ - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - /* fallthrough */ - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case COPY_: - state->mode = COPY; - /* fallthrough */ - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - /* fallthrough */ - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - /* fallthrough */ - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (const code FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - /* fallthrough */ - case LEN_: - state->mode = LEN; - /* fallthrough */ - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - /* fallthrough */ - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - /* fallthrough */ - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - /* fallthrough */ - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - /* fallthrough */ - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE_CHECK(state->check, put - out, out); - out = left; - if ((state->wrap & 4) && ( -#ifdef GUNZIP - state->flags ? hold : -#endif - ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - /* fallthrough */ - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - /* fallthrough */ - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - /* fallthrough */ - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE_CHECK(state->check, strm->next_out - out, out); - strm->data_type = (int)state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(z_streamp strm) { - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, - uInt *dictLength) { - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - zmemcpy(dictionary, state->window + state->wnext, - state->whave - state->wnext); - zmemcpy(dictionary + state->whave - state->wnext, - state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, - uInt dictLength) { - struct inflate_state FAR *state; - unsigned long dictid; - int ret; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary identifier */ - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, - unsigned len) { - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(z_streamp strm) { - unsigned len; /* number of bytes to look at or looked at */ - int flags; /* temporary to save header status */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - if (state->flags == -1) - state->wrap = 0; /* if no header yet, treat as raw */ - else - state->wrap &= ~4; /* no point in computing a check value now */ - flags = state->flags; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->flags = flags; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (inflateStateCheck(source) || dest == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - copy->strm = dest; - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - state->sane = !subvert; - return Z_OK; -#else - (void)subvert; - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -int ZEXPORT inflateValidate(z_streamp strm, int check) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (check && state->wrap) - state->wrap |= 4; - else - state->wrap &= ~4; - return Z_OK; -} - -long ZEXPORT inflateMark(z_streamp strm) { - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) - return -(1L << 16); - state = (struct inflate_state FAR *)strm->state; - return (long)(((unsigned long)((long)state->back)) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} - -unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return (unsigned long)-1; - state = (struct inflate_state FAR *)strm->state; - return (unsigned long)(state->next - state->codes); -} diff --git a/libraries/zlib/inflate.h b/libraries/zlib/inflate.h deleted file mode 100644 index f127b6b1f..000000000 --- a/libraries/zlib/inflate.h +++ /dev/null @@ -1,126 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2019 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 = 16180, /* 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 7K bytes, not - including the allocated sliding window, which is up to 32K bytes. */ -struct inflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - 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, - bit 2 true to validate check value */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags, 0 if zlib, or - -1 if raw or no header yet */ - 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/libraries/zlib/inftrees.c b/libraries/zlib/inftrees.c deleted file mode 100644 index 8a208c2da..000000000 --- a/libraries/zlib/inftrees.c +++ /dev/null @@ -1,299 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2023 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.3 Copyright 1995-2023 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work) { - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - unsigned match; /* use base and extra for symbol >= match */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - match = 20; - break; - case LENS: - base = lbase; - extra = lext; - match = 257; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - match = 0; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if (work[sym] + 1U < match) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if (work[sym] >= match) { - here.op = (unsigned char)(extra[work[sym] - match]); - here.val = base[work[sym] - match]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/libraries/zlib/inftrees.h b/libraries/zlib/inftrees.h deleted file mode 100644 index a10712d8c..000000000 --- a/libraries/zlib/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* 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 distribution. 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(codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work); diff --git a/libraries/zlib/trees.c b/libraries/zlib/trees.c deleted file mode 100644 index 8dbdc40ba..000000000 --- a/libraries/zlib/trees.c +++ /dev/null @@ -1,1103 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2021 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef ZLIB_DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -#ifdef NO_INIT_GLOBAL_POINTERS -# define TCONST -#else -# define TCONST const -#endif - -local TCONST static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local TCONST static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local TCONST static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(unsigned code, int len) { - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(deflate_state *s) { - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(deflate_state *s) { - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent + 7) & ~7; -#endif -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) { - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - unsigned code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits - 1]) << 1; - next_code[bits] = (ush)code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = (ush)bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1)); - } -} - -#ifdef GEN_TREES_H -local void gen_trees_header(void); -#endif - -#ifndef ZLIB_DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* !ZLIB_DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef ZLIB_DEBUG -local void send_bits(deflate_state *s, int value, int length) { - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16 - bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !ZLIB_DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = (int)value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* ZLIB_DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init(void) { -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1 << extra_lbits[code]); n++) { - _length_code[length++] = (uch)code; - } - } - Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length - 1] = (uch)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1 << extra_dbits[code]); n++) { - _dist_code[dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256 + dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Generate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef ZLIB_DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width) - 1 ? ",\n" : ", ")) - -void gen_trees_header(void) { - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(deflate_state *s) { - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->sym_next = s->matches = 0; -} - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(deflate_state *s) { - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(deflate_state *s, ct_data *tree, int k) { - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(deflate_state *s, tree_desc *desc) { - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n - base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (unsigned)(bits + xbits); - if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); - } - if (overflow == 0) return; - - Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length - 1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -#ifdef DUMP_BL_TREE -# include -#endif - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -local void build_tree(deflate_state *s, tree_desc *desc) { - ct_data *tree = desc->dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n + 1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2 + 1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree(deflate_state *s, ct_data *tree, int max_code) { - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code + 1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n + 1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree(deflate_state *s, ct_data *tree, int max_code) { - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code + 1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n + 1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count - 3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count - 3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count - 11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(deflate_state *s) { - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except the - * lengths of the bit lengths codes and the 5 + 5 + 4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(deflate_state *s, int lcodes, int dcodes, - int blcodes) { - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes - 1, 5); - send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, - ulg stored_len, int last) { - send_bits(s, (STORED_BLOCK<<1) + last, 3); /* send block type */ - bi_windup(s); /* align on byte boundary */ - put_short(s, (ush)stored_len); - put_short(s, (ush)~stored_len); - if (stored_len) - zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); - s->pending += stored_len; -#ifdef ZLIB_DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; - s->bits_sent += 2*16; - s->bits_sent += stored_len << 3; -#endif -} - -/* =========================================================================== - * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) - */ -void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) { - bi_flush(s); -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -void ZLIB_INTERNAL _tr_align(deflate_state *s) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef ZLIB_DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(deflate_state *s, const ct_data *ltree, - const ct_data *dtree) { - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->sym_next != 0) do { - dist = s->sym_buf[sx++] & 0xff; - dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; - lc = s->sym_buf[sx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code + LITERALS + 1, ltree); /* send length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= (unsigned)base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and sym_buf is ok: */ - Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); - - } while (sx < s->sym_next); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "block list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(deflate_state *s) { - /* block_mask is the bit mask of block-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long block_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("block-listed") bytes. */ - for (n = 0; n <= 31; n++, block_mask >>= 1) - if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("allow-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "block-listed" or "allow-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and write out the encoded block. - */ -void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, - ulg stored_len, int last) { - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len + 3 + 7) >> 3; - static_lenb = (s->static_len + 3 + 7) >> 3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->sym_next / 3)); - -#ifndef FORCE_STATIC - if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) -#endif - opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len + 4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - - } else if (static_lenb == opt_lenb) { - send_bits(s, (STATIC_TREES<<1) + last, 3); - compress_block(s, (const ct_data *)static_ltree, - (const ct_data *)static_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1) + last, 3); - send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1, - max_blindex + 1); - compress_block(s, (const ct_data *)s->dyn_ltree, - (const ct_data *)s->dyn_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef ZLIB_DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len >> 3, - s->compressed_len - 7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { - s->sym_buf[s->sym_next++] = (uch)dist; - s->sym_buf[s->sym_next++] = (uch)(dist >> 8); - s->sym_buf[s->sym_next++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - return (s->sym_next == s->sym_end); -} diff --git a/libraries/zlib/trees.h b/libraries/zlib/trees.h deleted file mode 100644 index d35639d82..000000000 --- a/libraries/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* 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/libraries/zlib/uncompr.c b/libraries/zlib/uncompr.c deleted file mode 100644 index 5e256663b..000000000 --- a/libraries/zlib/uncompr.c +++ /dev/null @@ -1,85 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - 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 size of the decompressed data and *sourceLen is the number - of source bytes consumed. Upon return, source + *sourceLen points to the - first unused input byte. - - 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, including if the input data is - an incomplete zlib stream. -*/ -int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong *sourceLen) { - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong len, left; - Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ - - len = *sourceLen; - if (*destLen) { - left = *destLen; - *destLen = 0; - } - else { - left = 1; - dest = buf; - } - - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = len > (uLong)max ? max : (uInt)len; - len -= stream.avail_in; - } - err = inflate(&stream, Z_NO_FLUSH); - } while (err == Z_OK); - - *sourceLen -= len + stream.avail_in; - if (dest != buf) - *destLen = stream.total_out; - else if (stream.total_out && err == Z_BUF_ERROR) - left = 1; - - inflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : - err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : - err; -} - -int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, - uLong sourceLen) { - return uncompress2(dest, destLen, source, &sourceLen); -} diff --git a/libraries/zlib/win32/zlib.def b/libraries/zlib/win32/zlib.def deleted file mode 100644 index 666bc6fbb..000000000 --- a/libraries/zlib/win32/zlib.def +++ /dev/null @@ -1,97 +0,0 @@ -; zlib data compression library -EXPORTS -; basic functions - zlibVersion - deflate - deflateEnd - inflate - inflateEnd -; advanced functions - deflateSetDictionary - deflateGetDictionary - deflateCopy - deflateReset - deflateParams - deflateTune - deflateBound - deflatePending - deflatePrime - deflateSetHeader - inflateSetDictionary - inflateGetDictionary - inflateSync - inflateCopy - inflateReset - inflateReset2 - inflatePrime - inflateMark - inflateGetHeader - inflateBack - inflateBackEnd - zlibCompileFlags -; utility functions - compress - compress2 - compressBound - uncompress - uncompress2 - gzopen - gzdopen - gzbuffer - gzsetparams - gzread - gzfread - gzwrite - gzfwrite - gzprintf - gzvprintf - gzputs - gzgets - gzputc - gzgetc - gzungetc - gzflush - gzseek - gzrewind - gztell - gzoffset - gzeof - gzdirect - gzclose - gzclose_r - gzclose_w - gzerror - gzclearerr -; large file functions - gzopen64 - gzseek64 - gztell64 - gzoffset64 - adler32_combine64 - crc32_combine64 - crc32_combine_gen64 -; checksum functions - adler32 - adler32_z - crc32 - crc32_z - adler32_combine - crc32_combine - crc32_combine_gen - crc32_combine_op -; various hacks, don't look :) - deflateInit_ - deflateInit2_ - inflateInit_ - inflateInit2_ - inflateBackInit_ - gzgetc_ - zError - inflateSyncPoint - get_crc_table - inflateUndermine - inflateValidate - inflateCodesUsed - inflateResetKeep - deflateResetKeep - gzopen_w diff --git a/libraries/zlib/win32/zlib1.rc b/libraries/zlib/win32/zlib1.rc deleted file mode 100644 index ceb4ee5c6..000000000 --- a/libraries/zlib/win32/zlib1.rc +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include "../zlib.h" - -#ifdef GCC_WINDRES -VS_VERSION_INFO VERSIONINFO -#else -VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE -#endif - FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 - PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS 1 -#else - FILEFLAGS 0 -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE 0 // not used -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904E4" - //language ID = U.S. English, char set = Windows, Multilingual - BEGIN - VALUE "FileDescription", "zlib data compression library\0" - VALUE "FileVersion", ZLIB_VERSION "\0" - VALUE "InternalName", "zlib1.dll\0" - VALUE "LegalCopyright", "(C) 1995-2022 Jean-loup Gailly & Mark Adler\0" - VALUE "OriginalFilename", "zlib1.dll\0" - VALUE "ProductName", "zlib\0" - VALUE "ProductVersion", ZLIB_VERSION "\0" - VALUE "Comments", "For more information visit http://www.zlib.net/\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0409, 1252 - END -END diff --git a/libraries/zlib/zconf.h b/libraries/zlib/zconf.h deleted file mode 100644 index fb76ffe31..000000000 --- a/libraries/zlib/zconf.h +++ /dev/null @@ -1,551 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * 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 and init macros */ -# 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 -# define adler32_z z_adler32_z -# 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 crc32_combine_gen z_crc32_combine_gen -# define crc32_combine_gen64 z_crc32_combine_gen64 -# define crc32_combine_op z_crc32_combine_op -# define crc32_z z_crc32_z -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateGetDictionary z_deflateGetDictionary -# define deflateInit z_deflateInit -# define deflateInit2 z_deflateInit2 -# 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 gzfread z_gzfread -# define gzfwrite z_gzfwrite -# 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 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 gzvprintf z_gzvprintf -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit z_inflateBackInit -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCodesUsed z_inflateCodesUsed -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetDictionary z_inflateGetDictionary -# define inflateGetHeader z_inflateGetHeader -# define inflateInit z_inflateInit -# define inflateInit2 z_inflateInit2 -# 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 inflateResetKeep z_inflateResetKeep -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateValidate z_inflateValidate -# 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 -# define uncompress2 z_uncompress2 -# 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 - -#ifdef Z_SOLO -# ifdef _WIN64 - typedef unsigned long long z_size_t; -# else - typedef unsigned long z_size_t; -# endif -#else -# define z_longlong long long -# if defined(NO_SIZE_T) - typedef unsigned NO_SIZE_T z_size_t; -# elif defined(STDC) -# include - typedef size_t z_size_t; -# else - typedef unsigned long z_size_t; -# endif -# undef z_longlong -#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 about 7 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 -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include - /* 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 -# 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 /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* 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 - -#ifndef Z_HAVE_UNISTD_H -# ifdef __WATCOMC__ -# define Z_HAVE_UNISTD_H -# endif -#endif -#ifndef Z_HAVE_UNISTD_H -# if defined(_LARGEFILE64_SOURCE) && !defined(_WIN32) -# define Z_HAVE_UNISTD_H -# endif -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* 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__) -# 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/libraries/zlib/zlib.3 b/libraries/zlib/zlib.3 deleted file mode 100644 index 4dd289675..000000000 --- a/libraries/zlib/zlib.3 +++ /dev/null @@ -1,149 +0,0 @@ -.TH ZLIB 3 "18 Aug 2023" -.SH NAME -zlib \- compression/decompression library -.SH SYNOPSIS -[see -.I zlib.h -for full description] -.SH DESCRIPTION -The -.I zlib -library is a general purpose data compression library. -The code is thread safe, assuming that the standard library functions -used are thread safe, such as memory allocation routines. -It 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 may be added later -with the same stream interface. -.LP -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. -.LP -The library also supports reading and writing files in -.IR gzip (1) -(.gz) format -with an interface similar to that of stdio. -.LP -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 the case of corrupted input. -.LP -All functions of the compression library are documented in the file -.IR zlib.h . -The distribution source includes examples of use of the library -in the files -.I test/example.c -and -.IR test/minigzip.c, -as well as other examples in the -.IR examples/ -directory. -.LP -Changes to this version are documented in the file -.I ChangeLog -that accompanies the source. -.LP -.I zlib -is built in to many languages and operating systems, including but not limited to -Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. -.LP -An experimental package to read and write files in the .zip format, -written on top of -.I zlib -by Gilles Vollant (info@winimage.com), -is available at: -.IP -http://www.winimage.com/zLibDll/minizip.html -and also in the -.I contrib/minizip -directory of the main -.I zlib -source distribution. -.SH "SEE ALSO" -The -.I zlib -web site can be found at: -.IP -http://zlib.net/ -.LP -The data format used by the -.I zlib -library is described by RFC -(Request for Comments) 1950 to 1952 in the files: -.IP -http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) -.br -http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) -.br -http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) -.LP -Mark Nelson wrote an article about -.I zlib -for the Jan. 1997 issue of Dr. Dobb's Journal; -a copy of the article is available at: -.IP -http://marknelson.us/1997/01/01/zlib-engine/ -.SH "REPORTING PROBLEMS" -Before reporting a problem, -please check the -.I zlib -web site to verify that you have the latest version of -.IR zlib ; -otherwise, -obtain the latest version and see if the problem still exists. -Please read the -.I zlib -FAQ at: -.IP -http://zlib.net/zlib_faq.html -.LP -before asking for help. -Send questions and/or comments to zlib@gzip.org, -or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). -.SH AUTHORS AND LICENSE -Version 1.3 -.LP -Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler -.LP -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. -.LP -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: -.LP -.nr step 1 1 -.IP \n[step]. 3 -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. -.IP \n+[step]. -Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. -.IP \n+[step]. -This notice may not be removed or altered from any source distribution. -.LP -Jean-loup Gailly Mark Adler -.br -jloup@gzip.org madler@alumni.caltech.edu -.LP -The deflate format used by -.I zlib -was defined by Phil Katz. -The deflate and -.I zlib -specifications were written by L. Peter Deutsch. -Thanks to all the people who reported problems and suggested various -improvements in -.IR zlib ; -who are too numerous to cite here. -.LP -UNIX manual page by R. P. C. Rodgers, -U.S. National Library of Medicine (rodgers@nlm.nih.gov). -.\" end of man page diff --git a/libraries/zlib/zlib.3.pdf b/libraries/zlib/zlib.3.pdf deleted file mode 100644 index da12d37183a7371513c0991fd14a7d932fd42e84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19505 zcmY!laBRKOW=W+_YFTQIt)ZTYf^H#Hou7YzV`#9ef^LeFV~Dedf^M;kYnZ3A zt8GC_T6s}sNveWwadAmXerbuVy@GDBe`!fUX^C5APAZ5?lucZw3I+=KNm*PrHu^rP zdFdq?3T6rh3PJjAnK>n?MGE?EIf*5yE~&}+DXDgLT*W0tsfoE<6?2wG-7dO)La_FF z_?g>Hp^q~3cD&oSMnCGf-py-XYkXBNg>k7U3L0`;U`d$yukA_jr~a4oq}ddn=1lq& zmZ{5NYW*!maEiw+V$JzyO>HZy^zTn@ zu9CW}bM8#?GP%E(uCHE~^J?0j^Vv1(eGjyceYHLuRvRa{U3Oo2;pE0vlkN*Ac6ubu zYD>{e{-g8b!=t}T>rTos%bnRN@$GNeRPRsvo3gg;uD!S|;o#9-AO5*%RWGtwT=?lu zr&`zsj{9>DTLz~de;aRCvu9sz_3t^l2VPwsTHm7tX%iw>+ElT9aGmj2veq5gA2h0o#}dU9KG_v^lP-`dsU;wv;= zc*gWspYtY{Z%B5$rMLe2&$_olijzMCDeZgw*@y4>hS#<`{=B=LT&Vyd|&dCQRT8saOhbr_vDlN zUhdwccjedvr>TXWEREYfR$J?+YDhEPUa8#5Aa~H1{rBCtRMmG`+kF;!y#2YfWr}jD z?f0JkCEM(nwRq=#U7hItwd*V=|5O1(qcp?k|1O@g>CM!6n|RK-&bTNrC!vOg z@p=VQbMIdU@iW$|4ott)5*>7;eCN4qN7;m)oc3w4itOHNwe{X{?;y4dn{vvTc4>+V z%1_Y!`gq&@x3g?tPI>R-7<_IS8;ftOtVgi8a?uU3yUQXc|4xYgV?1Bmh2u+v%{s>i zN)^&w&x_b}PE<@`t#y~$P~-pU)ka6Tw&GMJ&Qp1tS!vnJ-I4@#4aR`BsJY%(W^pZS>TY!tw(fra08!yaXot7`mtyQ_-IY}pb0dug3%Zz}dhU+w1R*K!#XRvB!vvFK}?rEUg z{HYgZrcd{Kee38(oi(#XH-xX%4O;Dd%zqXS-&a$f`PnOzG6a^{PW`gGZ)4Q?B_8a~ zOF~~~H_X45AJE=%v9d8QUEyfZv7Aj`x{lmlc7J`z50xWKJ90D}Gi6?u=uc&7_R$f! zzD$vS-?Q7YK~g(5T|X%4JvZXy&F6n-SUr95jg#&8R^jullD?Bqc8)yhO;X;N}#>T$3911<%2vGO6?7AM&F=5V=s z&r8ct=AOL3;awK*@}_sZk8=*Kj4BjeH!G4qd%e%DymT9lpl6d*HTLldH0H=mid$c5 z__9NI>ha4OYfsm1d?h8U-Px7&LP9jCLaX$8+Gn5n4@5t_QjS=&>aaowqpq8P{d|qd zn=~FcC!UPZufA&2x3+)5>PgJLE2^ffH(368myU_Nbcu3%a_QpBwGPu9c6sO56zuw% z-g$lDY%VVL7^{EpPp=Aop1I)NH8=U?F&pEU*3QhH%r{kDQ7tx_BmGVB7r9sMY0Fm& zGqAq-wyS9E^CDHvTg)M|a#wSjJ@q*| zG68#cd0jj+_wd>p@fs$U#3xr$4vR0^Rjs{-C-kIa<9!DgtzB(m3VrRn%!4MLDxOq5 z#WvzM%QmOrg|3ndE=)By(K6br8L_3A%kXIl=iAk%xo4M)7@L|MdwD`vLK9QQe_@?`t5b{~u0?9ivC+vHRKKH!S`{8{))i>^h*0%3*Ozi(Rd z9WR=$mDa(scCv8H&iPvV7?@`6EotV=@c#VHomtNCU7jOr>D_n7yStY!Umlsl#UjgN z)WyNO>ql9rUVQjet;C3fB{jh(oUBa~W|k@5ExGM=(B-SivI{+nr!;0H+|#&wM7AZ5 zePR5rShp#iqSM>mi!T-?ax$j9Tk3F_`32J{U!7x8k_UI4Jzd46!0~Is8TC%<#>o#A)NcqQK$LFv&tAiOMOH?d>6XGtk&P!cPIzZ*^Ia;)nKN;&Tj##O z*|Wosz4}paFnPX_aQec#7kZR5FB->?=A8DWCdxyQ%weGr8 zXSn6OC9)pBZ4-V?_Bz_3miORz#*`U`-`bg8Iq)u8$SD4F#r5>!%qNNA>oz#)&faG& zmE;+tZ?(+4GUO!tq3h-?2Vw>73tcUq)UY`O8L)K5)EmV=)h}2^2cO`4VSRer zTW)2`JB!wTFLPhL@2>5s*MhTmxowWzCHVXk`{WznULCr(kmc>}VEO8UFTXE2w|f4c zv#Qg|-M{>N;ioFSrDXH$h&P?roj;#(=U@J=jwe7c#cYK~q}7V!zgTZ|JPiB9&nXe$ zv9Dp`f@%Ja7gA1%O^ndqa&h0@12bX``u;0cJ#+mVajo@b*k7+X9gCNJe)j3tHKW$-x?W$CD73NKKCewHh-#eex zHo-`+TK(G3=39)r*stDVH2ql~>Z~4WC-bGZQ!1@5+#vUd<8L;VqRW%dvP27hZp)~s zUjO|cQ}pkvhF#0L*?(~{dp{9Zwh&VHJ!n)skx9<;(nGs`&RW;ByeDdTZ7w{q(QoeX zxX$+dD^t07(gSt*+mg2n#4p`d+Y%iuuD=k}}u<(1sPAPfMlH1d4m1~~g$=VPfHzB@V&i}`M7v`C6SCc2ScuxDH zsN22&r?l8zh5u`+<|h|Q>+q_2y!yws!X5BVxwI$`X=kXF9b^JTdBiqS~UP_P3)I4>GK27ML0o-FoVgOuo|G1sulO z8vkOhy*_rwmbr7+v@a`dCu+9^#K*@^>xrlDKQzCdS@Z4+qtv_(BdY)mfe{ zo4&?(snI!R_d^*O!As7Z*7#(e^UrcQBh!*6JDxd831yVbx2xT?P+#X!lj|4r+C2W% z9dE{d#=e#X5w_3WR*EqSsZTh8P^%w~+QoH${3_ROU={WqhQrYP+AIakbmi=Rr&GOg%& z`+mN@|ITj1>~j0fx3{mqzvuUdv`scQOC?Tpq-%xd=q@q*#cwMuY7=(u?t<5XT*5Ju z*6;306+VCV_w~1of)kZXy6zlix%}kp&g85AG8c#%JwCNKq4uxD9<~dMG$w8BS(3E> z#iq#XZ!1#jHCOMl+q~%}qswHrlg7eLCyM5&OfH_EpSC_(ZujxsQL}BcR~E^gzImHN z@50IN2cNBc6?xx|Z@GYio08^)ptB!7+}Qf>V)53?*54MrxgPrek*am*;b3dN0_{KF zpG}|oC?ffs9?N-kK9=XKle&&qn75t@4V$syfAO1=`xpr z?bE-x#i$~#f-m1yWx4p-h6}G}@%qo2`uLW^Y9q$FDkfL4um_jFzH!{F9{WBbb}IkE zo~EeH$1m*Q@e%yiGT&cQhAm$0N16AJDbGa&ET>f8HNKG8n<8E*#2y-NTK(5A=$JE%vl^<{W(d-RuXaM8y={tOpx(`VKKSU%iyF<(2Q$2RHtP zbLIek-jKu zWIU&iCpGc^?1kaS1mj{Er2aT{r%#)J_#&Y`GLvFca^!3~q z6;+E~1b#U@Y4RIrjsZAghGC=`q}p3TZPvjMV%KK zQ(2PjH!PD~VZa}HKT}A-cgt_VSf5F!QnWJMcQ2lh`K~?QQ|?he_wCjK>dqUIZm%*a>q&3+hH^7%o?>%0FL=A2+lE#Gvg z?CrIn@MkOf9(ggl-%5($i4~WNd7=1#{k?TB*Mdp)A1*9jejxYI?#uDVxLW2u;rcmW zQ*ph<#3jLR%#V~wyt%#ccGfqUNjsiK%4J;MTm9tfR-seccPy0F@=Cp7%z9F#ax<@fu`lcxR+ z5j!%^BTn(pf|c{w;yI@IO)KPPT%xr*atTku5J(qnUH z|Gz(*N!oci|JvY!%dU@lmY;Mj{`zRsoAnKwcvUZ5oysjC?C{)wo=}d}++5*vL0*qu z$Xe=`bcOA(TKG#L%R(5i4uk1o?kk?HE&d}sAvb)#Qd|F;_5Ro62(XBD!+e$(IP?RVum6{Xjos`?d6ANzM71EDvzr?dDpx|Lkq8W4H!mg#? zCDt!GQp(nRl)v1`r@6FIQLi(`Zr`=5&9gZs<*OA;tT0x;d^Nx~(@0f+ZgkxK8J!2R zUnX3wH#w)dKloy+%D0*d`}aPE3)R=%wGTD@y;WwPl;^<}jfbDe6jk-gy!xhfPUmq@ zOnas5+{O9zEzkaL%y^sUv?=+?nfA$XpUh)l)TEp&kaxJ`zpi&t+N#70yaolK+3Cxf zn#!3{n8Q(E{|gu43;texFG%Z^>N#@h&{XJ91ff?$-8*{CJUR}is?#cpPJk| zJ2~u-{=2%jH!e?Iv^z-A^!v{DeLt>j-mr7$siGdq^Wxq9n=j8hI@QWh`0bW=$1i^m z;ou1Lm%BC1bf5X6#Ih$=0(Zlh@5<`AMk~%PPJNyhwZP@izjtr#1GiigC}r3cC|~F~ zskN(sXQ93-Y>4k#G6~1!ie^w$!o8sT6O?nWvY?DQ))Bf9wm(MbL z)9bAN=%|d%{c}qrri31_kIB>Cu|D}<-cI$;)fyp*^?3_UIhMS0=RC7)$NZY_;hYB6 z<(psUuuOiGFVVU^bn$cTm^a<;<-UJB$M$2@O8z}7=l!Ugm6$AOQ_qv@qIUW~=u=3vL8I0xKPLUs?x$)FIku~EB zVo9QckrB*Uu+|$$1;h>dL57B0hK3*o`azalmJo(H7uY9Afe7N0rUPUqREJYyaVjXj z^xeV({2e2;JyLVZQcE(E6LtNQaxx1`Q^B$6l3JWxlvz-cU!-6Nb}=}3z*1cLZka{J zCC(X%MGD47`aX$JwxN-cet2d|Nk(xrmyx-J0w`%=Vu%cgG%~l~!jwl5fy$eM0}Vw+ z!PFGg#5GVbfT}^2MdEQ8fYpN3n;L+`K`exr5!7rDZDDK-Q_BTWWegHAFi-%w7o^uf z0cwVUK`fWPYhH4GN@iZVet2e{V_tD4oF818R07Iupd@98h&WJ$qQ`=-f0(yxI8rP) z<>#b;!x=dWKz0WajsgoyB4Pk!7IEPQ3U_2|W(G=m=H?a(AW>MDm>C)>fI%*?@|2nri`I3a~BD4l`CK?cD> z*8m*0u1KgXPUFAUVar0PG8p7z~4g3XE~)OeB>!)qqXFo4ZXdOpwx&f)S{U3)07t z^}w>wGz7|(h`b9b58)XXJtMnhrlqA8rRF847Dsa#Tk02<=9i=vWu|A8a2c8y=%;1s zr{!>g(ok+@UTJYGBCCT7O=SB(MJ^&ogHx+tVs0w_QrO8Uzam=K&`3eo$k0N;!qiB? z+{7>zH0_*TtYB=!rSDjr463KiO$@p8of8W@QbA4wDdN%xSq72=Y30)QEJ@7COm@sm z&q-A<;L;B+NzDyYFf=mf()Z0QF3!wL2bbKSRKuko0X4?d*pf>hRLlpbmT2fZ>-*>@ z>L=+Z>nG>u<|gW=>Zj{x=x6HZ=;!L^>F4Vg=oh3GW#*^o7wH%47w04vXXqCfBqpco zm*`jMS80NM44Qp6RxkwTO{A~_@u6V_nOO(<5H_*Sg&L*Ku$g!xBST9&JLu?0#hkgJ znE}C(Vs-r!jt6I!_$=q?RbDB%JN?deshskoWe%xFP}?Ctunv+7U9*M@Dj=f`XFYoGD71&Yw%Q@km=H{5joEOk1+vSns*f<`~X` zrwyx%ub%OYy?k-1z2f5#mHBQKlb1}-5BPY$x%|y6=fW-wf*xnowh3EzDk#mk;qgXsPbcdUwIunC zGe0QSbn3RqKlJxeT_&jVQBv_hjNrK=j*l!QJ@*v|S=l~bQ~vK#W&dYwz4q15<}KZ~ zByPu=f}8J^7F&LK{>7<^b1%E;F2m^u551A;+31sg$vyo;)I|N@v+0(?SMQ{U$Y(wN z^iEOz_JOF(yp?pvbq5>lMh>c@Vz7I z^jU2By@!wPY)VY~XYjK^#8%>|!F*%gnliZ>Q}d>~)1+5-HdoAg%Cp}2oV~r3c}?!M zqwi-4aM~X@?ELp%Dd)46MHvf>uYan3=oD1hVt94}+sOk#iaI;vrp%eTX4-)`i;&eB zr?+OTTFAD`XK!fiwbjd`t=DWho1?pm`Btut*SD6RPdPjNAN0(Yc#wVjbJkSemFDGN ze}t>aO&2+G(CLT!ooNTAN^k$K+F5$G^HPU`)Qywo&;Ci=o^f}P9s8I355Mlr{r&uw ze|&D8)A@x$dnM;?^z1v+-qtC-Z`sD>_8`&w{aWq6XOlm0_r}!9aa~_y zwZphjEWhxn@jEZB>kl@_@0X4W)>8IPX+5dXxZ#a$=I^DqlU*OW2Tff$D`kPX%!|sN z6|Xz0Zam7=+$eIxfbj*ZUfwL#^G0*aC4bgvz2Oas?pFK${jc~P?-i$>XW33yzp}dM zi&p#zP86E2$N zx8lUc9iQc1@a$?jq<vWoJv zY_yCz(PDDKD9fvq?Lspn&o8IiiyVgq_bhpHR5oQA&*XBqizl@CF5f*Jo@u(EG312F zv)Lcnm_=^X?|o>tOXa6vUAs*nw<*Y1H9U{|H@yr;m(U5-Af-fEWZ8Oc&ntu-M(MVcVAA6 zS$&LaZNa@8QMWQyY3#h<^n6!Fj6;y#=BG1Emfi|7NLJaV#9m{2Rw%>R{&Ifg38Rk2 zC69WzrfRO|(OR%_)yjpJ!s=dC^nZ+b8|O^wT(AFO3GhQbx`}- zq5Ukn^Wzv^Z<(ul-R0)h`7FN`cexeDh4y-GU|O{PkJ+WR`wog>6ZRgol`TK`V}23? zw+1^)nttoovwi{cs(yA-uGcsE=q)U-skQv)lTgt9nmvy#bg9H-ZlOfZH6pD!d|$;k ztLQX^%1Y;Xu3hzO4_gJ-cfZ&@MVl5b+WAQ8t?SWxS&?VF4+UbU)>*A~s}*|nuXrH@loQZo9}JEs-1c=y;mZqU{>Akqz=_->pMQ&wAC(& z7CGIzUh#%liP@{39nOWa6SRAHO_i9Ed+x~yy=DILiuvyO>@P=IpU#`w{Acp|_B{JW zI}7=2K8s~nv>iFMV*A1ppZ8DYQTmrKVeh;h{k#veb{UyUD=Sx1&h~x-=yZNkeJ@a!rk~UJtcN| z`oznAmbcV!*vVHpC!St=dVTwGgM`;P?{|h=4{xu?pRtxHPGI$?$J-A^W>#)7 zTzepoweC|dXLZtFW>-ds-!0|#?=)Yo+xH}M_q7Xm^498Z6}k35u6p;*MA1n-e^l9* z)?8U|_;${T%m?rKAKbgGb8jx|0>3YJPW=1Bo^HI`IsVPj*riN*YxnkFwzn2~hE+u5=c{L(xR#b>e0|e<*1j2C6RXYH5AJ zXaD7V|8L&R6a&dw2cGbiMt*hA3d-?RUHE|8dNNbFMs!g2ki}8W}5?o11|efUs7gnW?Fn1(6L!V_fY-Lo;mc zM0nHCQQt}5S>Hw9Ro`9TL*G;1N8eZ9Pv2iZKtD)7SU*HRR6i2Z7DQ=$#8Za~CvZBuw^Akv{xABtT;34*pFNAGiL`^z$s!GcBC| z{o%6h&;R`EzyG+%<6Wag-)A3_r=qiSp7Ba9lZTA-S6n|JJ}2Jx~BtC0%an7%f4Id(Z z`Rx98wzqEL$`feg0$7ieT%_8<@8& zQ1q6Oxyjm?q|N)}pvHw-KW_hIma2>+hn!bjV0*Je#6-zgwC#b6zGxF$&<$Z;sr7XR z4!l1C{XfiJPRZtR4yH;joZDZmT^*hp{kYV`Yk`!d3dgPR{qs-9&PzEJyI?VA(=AJ8>p36! z`pz1i@DQ0J@GyANxyu%fuU^3$kJ z-~5^B(!0F*i)3cc^W2-MaMy2p<1{u0D;?IW+8t}JTx3XWH+;&h+^iuy?|@Iop1v--1-p!JG8U(Yab*xpL>{>N3OTlf$i93Nib}Crgu2q=I8|uCbVLCo#YtmW6weT%;+%l+`b&>hB~y=Q-2 zdRW@LH7hBU&A{h^omzFG!xCmLUB>3iPR<#+xlK`75*rO}G%RSd+8!AzB)|Ex(ysL^ zri`9@?byEu?7I2uSzCxl&dme6-)+iHP;ld%;J(Xs#)DVSB6T~K%q}nO=hF!b$PeeQ zo&M#+m1pmCbhWQ~b;nIo`gHY2;EID=gBP4lQTOi^n((GlS?T6+mYfuJMxlyHm-T)< z)+i2obm@mq{h3FOJK6TXI~vRRS33UD^d0|wuJ^8c{XG7$_?f$F#J%(Nc1u=QafQ8G zcu%R~8`~w0tPaj4TC4i1+1w25D%f5H7Rzp!%$bpT?_PSh>;w-{=cydpEHl157hrKb zFsHr5%KL)`x6&!eu=N!;CK%Vph54;H_tud&d*Z1mgNq9aLo71H66am0U6s&!Zqbd{ zrneQ=aeKD^i0Bhi^5@#NYSZB#C9F@vWDLx{&Ch#vr2pep-M5xsrT72-;UN^ZtLDyS zr6+6N3LRyw+4893<;F{=oN|s?riN9&ymsE})b(Ul8>v{CNsU{I0Pj#Nmj77L(tvk)Z8++a6h4-l$uT!~XVkcjkc5mOd*wdCf<{t6(=T9K3P3D~ z9nj&GLZm?`$XH8iZf0^m$oAsYveZ1Zv6qsJqSRFVlJb20QvK4rl+>c) z{R;g`{VM&c)S`Ukdf5on8bPX;!F-bIWfL<~bL4tCoHIlu{Mx#0FINdgw)k~+lqqW{ zZQ|5W@MgK05+5oMk`kKf;3A;p88bhn-{a+7=8w+UH(g;Bs++~vT5`n0eRYzSc*==t=>y@vHY6#jignJ}yFKcd zi{4z@^uDi)*1Tz&W19JL=Q6%;#dCea#b@lRO?owXQ=)IwvX!inPnM>nq-qBl6+2(o z2+O~dAT@Qy&WG{(|Ni>~iikd$y7P>6c3|0@^Huj{_VfPR$tW%Uob{PHTW*wW%mk63 z88WjbNzD_RD7RBBEBDK;89l09OLq(9b4dA_t@PWr1ik9Hl%o%VF+P44N_BZ8+$ zin{F#dKO|~+T69^&Wf2KDyfdHfty!koSM|NFfG_yLpw{;v^~nLGWc4E&eo1i3m<97 zpPCls_cN$$iu_amvrCyY*s~0udawrhg$S7Tb1i!otT@G3)N5zJ%qi+i-CqWCuk4({ znCjuVvV4W-l#W?GlEJ|m!dY5JgC4J(JjKj(Zqag)DSDzlO|F@N+$)@3P0CoO;r}IN z&g&hbkNNt4`{wBM2|e%ry|rn}w(Pmrf30@W**HPP^V{WVB}{)M|Mpx=YMR09qx@M~ z`cPid?Bo6N@>c)UbIsp=-|}1CK=_+a#tefc$!mmHPhPq?{Q1&%Id^UD*6vC#S^wJX z<-bMG*G*p#zWn{F{r>+O{>|--6JD)m<|kulU>cFN;n;#Z1$!UL9kyG^aqh*+w*itm z?;pH9?NXzbQkZMu{b|;*-&eReuPyv|P_Xq$_%7K^Djy=*+s!X8VBRZayN_?`$BAoS zrnc$6ooBmY_ic}=ZLRvxO`h5o%$#WU@2#JA{N<-h5+wgso9CbU!hUb#1kbm&0c(^F z&X!GZ+rR3Y>U@)jTP-!%CL|d49xgQHYtG`FcHx5|+n)Hvx{RCp+IMe|xj&V`nLA%A zv0unco7Xz@!b+}CNzeNweoU%=8SYvH)&4wmbkpn?dQu*%Ht#*)_49Z7xvN`!9k+kl z?`t`|#_k<={E!eri@ldH;@za7)XwJnQ_sdb=+0m;Oz%I2Zq5!_vi)-wy6$er6!8!+!sO6UUtI zT+ye!ZFVj%xA~}IV|eKDIkQc&OBD9rUN`CW%HZOue>Mb_#Hxlxf9yETqQ0B&O-q{c z_nsLWj&@%dng8lt(!0Gt?K-pi3vEMF=~;r@ z!R!t!c@K>Fk0tJm$$HZR|`)`|i z6fi7#QXkOugKuloWtq~axtYETp0Rgo*9WiUO!>jE&(Z0e<+jX#qyC|t?CJ+CrJ5X> zj83%MtYI~hQ9AxS<7x-z@&63mk~2Qu;A(#~p?vKJo}c@F)-RIJoAjsX;da6AS6k!u z^=$cDR`es&URY;#x9Sb)>Tk0e_iX)k*3aMxKugWe+rMgEUZ_f5S&Lw@>h*^mE~K5MKp zTKDr=$>+b^GcWE=sd}Zn)9c2Xg&@ zY2Owriv6i)&fUOT7{0`J<{QbqaylEs^vj(2G6M5b{?y#B&~d!cadf8v?``Kd>t#dd z@~4W1O{!|TG4oE?y;YG{ZtJ$~Wm!{caG3S{hmZd~lf90|oXD~H^>p3-kW*1J_{(Y{ zVmfYY(Onu^bfC6pg6iUiSbgEr)jv434D076v{i>@wd&?w^Jz$nW|I11XmdyUK$FpW9_qx<2;l7J&=8CD;{axIX9%C}CCph^^zR^m5>s6MKpBuiW zb+ji>`TS_5#Iy-pwn_%th$b0IWeUd3Vd1RVd8F;wG%5a^Q`HkxS+Y;5I_sUO0X_f5+tT`d0e?d_t|e+xE5pQ#T$ zoO|~t=P!wkGvCWvDYn0toLaB@%*NSVZTU&Fl>ERqF{i#=sD2-7bG7lt@#&kAo=VSr zw593$-|b0n&$7;6Q*B>T>&EmceeLW+b@{7S?+DfZZSu_Jo$eRaTl-fR>38cMnC~2U zo2$6!ddiwQeZGy2n(43d;#bI6X~^3YRQNx2{N}&yoyzfej`@WKjen+aJ+bLKR=S7( ziqqSS?LT(ADLqtmIxwSNv0AjR@B#CDt{YO1JaRZD3S~=)Jq(g*I<0a(!=R1D;1K7e z#HuZC7N7nxf$xLLnXA0!ocTxZD^2Lvxb@EX(yR;XUmHdHI+(e19FewpzW?AS*VCI0 zPkvg^#mF6VZsjo!?I-nuVX{H1W*P;GTQ-Vsbc=bCJT*dDh2dPts{4w9vwSXzoxc+C zSW`ud&*Vpz*0r4?OT|Q%DnC~Ga&TRf?Hi|OAFdsqFXO6yab>Ohev85<7cT1SIZuqr z|1{sUwoT-VRmI8LqQ{3f|6G14tI5A|@+z~<$D>-7+qC%{!m&BT@N$pzbaKUA|HsrjYi@x*aaBjZ-4Vje&Fi^nCiYB|+r z@O*G^p2XIo_C*8yo7^0fOWKQpzRA2S`<)hhe)}`gW zFZkPU+wpd7e2%jG+JbpAOfyA!1*C5IHxvY2dfs0XxwqV0%TB5KK+dhtiJXb@=Ub+7 zKjqu^Pj}XjJiC4MK79vLRo?`6)rB2=uwjPDDtQZy1@9NFZeM*q{^zd~rX}-RGr4bl z+PUDE}ch2UXEMiwYUXaEu!I9~(>)Ovci~D&hb5BJJncquYa@bx? zEkw`kV37No-n+7=o7d@03|GJM?2eQDqSaHwXWhtQo2{mA`rUJF&JDHM{`F~B<+x0; z+`sqD-~Ffb>_Rt|Upj{3Cp?Tlv$UpAeR1E8c{T|@G?*^% zRU;+z-mSOV6Aib`cDxeDz_Lf_|C@vFOs^gMcg?ap$?55Tkp`817u~xq|2w1IvbW4$ zVej}mbl#0^JAKO5EHGhTx+z(zK;g$XpY@_U9Se;t{!aV0p3}>3NzlhAmX84nvvREO z#!fW}kCW*LtJ(Hx!66A1(UM;q->R4Ki8r5H#{KU3l77K zOS*H0_1?8g|10ht+?pZ!dW+G`pk?fqi&efn>P-yp=k_cUjhI-lBjeQW%$MFu%a-Y~i^N3rmHxUPm46WMw(tCX>*-gF|8rea*L<1svP<1Mrn_pMa{JNKq0)Lw z7kMO4nKOOLMnhx$L~n~CXYalx@#p@%YW}Pm?pdwJX|dx|NYL7Nf2)o_`(G>H+-jZm z%D7kMigTdvH1)!Ovnj`uUu#{I{T7&fHoh@8#%j4sfmr&sRm%nQIhQ>Ow6r~=Q@g(4 zrMq>&$#x_8WhKw!yZDv9W%^!q-WfH$(M4B$b6!`2j`kyj&iU&VVZuf1qP1pnIf>uWw3?XgNcmvj4v_y(D2@zQl> zZVXBm1`2J=OX5t}*{);?`ml*T&p#H-eM7-<-PA81%Q+73=Ii`<_wSrEo4xBFuI~O@ zs{hXC-`8)w?im86IXfmt%&jPVIh`>>k4s^(yWgpH?XpRX6Ys@-ez}tQxYoLw>P>tb zV|fMT1hbQyFFz?WyixQ|>woTzgEP)c2y_2&*sZ89|4G_tl3l~s3&-CsU;W~_d6>mb zclX=TN3Z|+H*wC1ryZB39Dcp3Mt%vu@X4HyB@D~{PKvYsza{3@?UGM9xvxcL>{!4% zJK=Nr-3@2?ZZgCcrJn!z*Zs6!tYw+>M%n9+Y^RB)sED63&x!o*nep*P0qbAcgzNf` z?wFUNgX)=3Vj6FZK>hfb98AKI(B^$^3sN%5RHl>b|kO z#PkXOp`d~$(|p^Nbu6v2ZK2MM&H+CECfrde-pcs>Mb=T)D`%MAUh!<1-niI$+Km(nmp2$lqx7MwXcp|_3Q1-)5t95m+ zuitiZ>G}_`Ya81*(wBem_+6R!)wcF)Is5T8laBWd%gQbuRow9-CWd|8oy0YNZ-{GL z>5S5g%iHrQ_$C9BGD{Wf+s^NkUOS)TXkOhpmDTL%F=w+6=lpOesP>w2}@s)cU-qr=p(lv{b$!_PU=|n z=1c#{d2P1o>lf;MQ@wdfT_ohSuwjkIw=;*_4q6C2+{t16r-M0ug69jfw;az3AM_pI zY)s~@;AxQTJSp6fEBJBxf}YD$etc5>679UoaCo+%Y@v>k{{IO2Ah z`Nkf$-O6uTHYCe@D>!oGf;`9Ut<7=X4{TrTWlwwC_Pi?bnZW+(8A<6|dG}Agy~E=9 z?jyk$mxTHs{8eEzFZ14`b*p|q%XquJDD(WL+R)eUXKq>87Hlq+ci;MQt5sw~Yw`hE z@rRr@49=YmG`p?H<1Z=uvM7P|TeH7>shrhKt<$^SPmRvoOxDzDfIB&@Hl09I0xZL1#P8=z2XQpn)WmA-rW)DGlAF$)&^B&qYnyHBu^6=42cE4zW4(oHy4z& zKz*Q}aqZU2N4$OEXifEX|UV3`|libj?kZ(sT_C(=2rj3=9l(lZ*^4O%e^v zEX>j@iH(tzWVkyDN{e#9i7zEtKQ$*6WM#3wp`M|>xahwBu5s5}=+zh|(xEFU3~998}g|?BoEg zxQ7;Yu>7TgBYSCb>4Q^UW_}(hVQaWpfpUd`g`tIkp@|_lL#P`VsB3cR`{t(*Pyse5 zzeodH0@t*&gDzL7C`wJ^GEguw<^rWG2v#sNH8nO>NK=4{nHifIDuAUF@}Odd7Usq# zXkrFtMwX@+Vg?45=wb$j7Dnh|#+IN(wjfL3b{Lo&8KLVnG%_;5wAa$m9L+pK15+bR zb*4sUXzC2iEkRQvsP>wfV5&1SG(`^s17k~L41btfT3DdlVP;~EVXuV|hP{Rc<`(Gc z42{f<4baUqw=h7r!_eHs9LX&uMTwa?sYP6%oiM?fRjCR_#tQmD`S~RZ;C0ms`kr}d z`3j(f8N{XU>7o#AV`AWJVQ%W;Spd}ZtCc0Y2aeyWZ~>$ZeVWUYDZW_ENCN5 YaYba;d7i`nz!f05e+1-2eap diff --git a/libraries/zlib/zlib.h b/libraries/zlib/zlib.h deleted file mode 100644 index 6b7244f99..000000000 --- a/libraries/zlib/zlib.h +++ /dev/null @@ -1,1938 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.3, August 18th, 2023 - - Copyright (C) 1995-2023 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.3" -#define ZLIB_VERNUM 0x1300 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 3 -#define ZLIB_VER_REVISION 0 -#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 and raw deflate 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 the case of corrupted input. -*/ - -typedef voidpf (*alloc_func)(voidpf opaque, uInt items, uInt size); -typedef void (*free_func)(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 will go here */ - 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 - for deflate, or the decoding state for inflate */ - uLong adler; /* Adler-32 or CRC-32 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. In that case, zlib is thread-safe. When zalloc and zfree are - Z_NULL on entry to the initialization function, they are set to internal - routines that use the standard library functions malloc() and free(). - - 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 by 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 for deflate() */ - -#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(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(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. total_in, total_out, adler, and msg are initialized. - - 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(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(). - - - Generate 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. Some output may be provided even if - flush is zero. - - 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. See deflatePending(), - which can be used if desired to determine whether or not there is more output - in that case. - - 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 - codes 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 when the flush marker begins, in order to avoid - repeated flush markers upon calling deflate() again when avail_out == 0. - - 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 or Z_BUF_ERROR, 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 in the first deflate call after deflateInit if all the - compression is to be done in a single step. In order to complete in one - call, 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 Adler-32 checksum of all input read - so far (that is, total_in bytes). If a gzip stream is being generated, then - strm->adler will be the CRC-32 checksum of the input read so far. (See - deflateInit2 below.) - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). If 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 or the state was inadvertently written over - by the application), or 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(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(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. In the current version of inflate, the provided input is not - read or consumed. The allocation of a sliding window will be deferred to - the first call of inflate (if the decompression does not complete on the - first call). If zalloc and zfree are set to Z_NULL, inflateInit updates - them to use default allocation functions. total_in, total_out, adler, and - msg are initialized. - - 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. - Actual decompression will be done by inflate(). So next_in, and avail_in, - 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(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), then next_in and avail_in are updated - accordingly, and processing will resume at this point for the next call of - inflate(). - - - Generate 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. If the - caller of inflate() does not provide both available input and available - output space, it is possible that there will be no progress made. 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. - To assist in this, on return inflate() always sets 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 Adler-32 - 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 unless inflateGetHeader() is used. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - produced so far. The CRC-32 is checked against the gzip trailer, as is the - uncompressed length, modulo 2^32. - - 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, in which case strm->msg points to a string with a more specific - error), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL, or the state was inadvertently written over - by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR - if no progress was 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 to be attempted. -*/ - - -ZEXTERN int ZEXPORT inflateEnd(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, or Z_STREAM_ERROR if the stream state - was inconsistent. -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2(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 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. - - For the current implementation of deflate(), a windowBits value of 8 (a - window size of 256 bytes) is not supported. As a result, a request for 8 - will result in 9 (a 512-byte window). In that case, providing 8 to - inflateInit2() will result in an error when the zlib header with 9 is - checked against the initialization of inflate(). The remedy is to not use 8 - with deflateInit2() with this initialization, or at least in that case use 9 - with inflateInit2(). - - 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 a 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 the appropriate value, - if the operating system was determined at compile time. If a gzip stream is - being written, strm->adler is a CRC-32 instead of an Adler-32. - - For raw deflate or gzip encoding, a request for a 256-byte window is - rejected as invalid, since only the zlib header provides a means of - transmitting the window size to the decompressor. - - 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(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 Adler-32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler-32 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 - Adler-32 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 deflateGetDictionary(z_streamp strm, - Bytef *dictionary, - uInt *dictLength); -/* - Returns the sliding dictionary being maintained by deflate. 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 deflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similarly, if dictLength is Z_NULL, then it is not set. - - deflateGetDictionary() may return a length less than the window size, even - when more than the window size in input has been provided. It may return up - to 258 bytes less in that case, due to how zlib's implementation of deflate - manages the sliding window and lookahead for matches, where matches can be - up to 258 bytes long. If the application needs the last window-size bytes of - input, then that would need to be saved by the application outside of zlib. - - deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateCopy(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(z_streamp strm); -/* - This function is equivalent to deflateEnd followed by deflateInit, but - does not free and reallocate the internal compression state. The stream - will leave the compression level and any other attributes that may have been - set unchanged. total_in, total_out, adler, and msg are initialized. - - 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(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 approach (which is a function of the level) or the - strategy is changed, and if there have been any deflate() calls since the - state was initialized or reset, then the input available so far is - compressed with the old level and strategy using deflate(strm, Z_BLOCK). - There are three approaches for the compression levels 0, 1..3, and 4..9 - respectively. The new level and strategy will take effect at the next call - of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not - take effect. In this case, deflateParams() can be called again with the - same parameters and more output space to try again. - - In order to assure a change in the parameters on the first try, the - deflate stream should be flushed using deflate() with Z_BLOCK or other flush - request until strm.avail_out is not zero, before calling deflateParams(). - Then no more input data should be provided before the deflateParams() call. - If this is done, the old level and strategy will be applied to the data - compressed before deflateParams(), and the new level and strategy will be - applied to the data compressed after deflateParams(). - - deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream - state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression of the - available input data before a change in the strategy or approach. Note that - in the case of a Z_BUF_ERROR, the parameters are not changed. A return - value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be - retried with more output space. -*/ - -ZEXTERN int ZEXPORT deflateTune(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(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(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(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(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 the current operating system, 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(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 Adler-32 or a CRC-32 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 - CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will *not* automatically decode concatenated gzip members. - inflate() will return Z_STREAM_END at the end of the gzip member. The state - would need to be reset to continue decoding a subsequent gzip member. This - *must* be done if there is more data after a gzip member, in order for the - decompression to be compliant with the gzip standard (RFC 1952). - - 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(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 Adler-32 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 Adler-32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary(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. - Similarly, 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(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(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(z_streamp strm); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - total_in, total_out, adler, and msg are initialized. - - 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(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. If the window size is changed, then the - memory allocated for the window is freed, and the window will be reallocated - by inflate() if needed. - - 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(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(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 -65536 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader(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(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)(void FAR *, - z_const unsigned char FAR * FAR *); -typedef int (*out_func)(void FAR *, unsigned char FAR *, unsigned); - -ZEXTERN int ZEXPORT inflateBack(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 default - behavior of inflate(), which expects a zlib 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(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(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: ZLIB_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(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 data. compress() is equivalent to compress2() with a level - parameter of Z_DEFAULT_COMPRESSION. - - 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(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 data. - - 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(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(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 data. - - 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. -*/ - -ZEXTERN int ZEXPORT uncompress2(Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen); -/* - Same as uncompress, except that sourceLen is a pointer, where the - length of the source is *sourceLen. On return, *sourceLen is the number of - source bytes consumed. -*/ - - /* 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(const char *path, const char *mode); - - Open the gzip (.gz) file at path for reading and decompressing, or - compressing and 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(int fd, const char *mode); -/* - Associate 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(gzFile file, unsigned size); -/* - Set the internal buffer size used by this library's functions for file to - size. 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. Three times that size in buffer space is allocated. 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(gzFile file, int level, int strategy); -/* - Dynamically update the compression level and strategy for file. See the - description of deflateInit2 for the meaning of these parameters. Previously - provided data is flushed before applying the parameter changes. - - gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not - opened for writing, Z_ERRNO if there is an error writing the flushed data, - or Z_MEM_ERROR if there is a memory allocation error. -*/ - -ZEXTERN int ZEXPORT gzread(gzFile file, voidp buf, unsigned len); -/* - Read and decompress up to len uncompressed bytes from file into buf. 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. If len is too large to fit in an int, - then nothing is read, -1 is returned, and the error state is set to - Z_STREAM_ERROR. -*/ - -ZEXTERN z_size_t ZEXPORT gzfread(voidp buf, z_size_t size, z_size_t nitems, - gzFile file); -/* - Read and decompress up to nitems items of size size from file into buf, - otherwise operating as gzread() does. This duplicates the interface of - stdio's fread(), with size_t request and return types. If the library - defines size_t, then z_size_t is identical to size_t. If not, then z_size_t - is an unsigned integer type that can contain a pointer. - - gzfread() returns the number of full items read of size size, or zero if - the end of the file was reached and a full item could not be read, or if - there was an error. gzerror() must be consulted if zero is returned in - order to determine if there was an error. If the multiplication of size and - nitems overflows, i.e. the product does not fit in a z_size_t, then nothing - is read, zero is returned, and the error state is set to Z_STREAM_ERROR. - - In the event that the end of file is reached and only a partial item is - available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevertheless read into buf - and the end-of-file flag is set. The length of the partial item read is not - provided, but could be inferred from the result of gztell(). This behavior - is the same as the behavior of fread() implementations in common libraries, - but it prevents the direct use of gzfread() to read a concurrently written - file, resetting and retrying on end-of-file, when size is not 1. -*/ - -ZEXTERN int ZEXPORT gzwrite(gzFile file, voidpc buf, unsigned len); -/* - Compress and write the len uncompressed bytes at buf to file. gzwrite - returns the number of uncompressed bytes written or 0 in case of error. -*/ - -ZEXTERN z_size_t ZEXPORT gzfwrite(voidpc buf, z_size_t size, - z_size_t nitems, gzFile file); -/* - Compress and write nitems items of size size from buf to file, duplicating - the interface of stdio's fwrite(), with size_t request and return types. If - the library defines size_t, then z_size_t is identical to size_t. If not, - then z_size_t is an unsigned integer type that can contain a pointer. - - gzfwrite() returns the number of full items written of size size, or zero - if there was an error. If the multiplication of size and nitems overflows, - i.e. the product does not fit in a z_size_t, then nothing is written, zero - is returned, and the error state is set to Z_STREAM_ERROR. -*/ - -ZEXTERN int ZEXPORTVA gzprintf(gzFile file, const char *format, ...); -/* - Convert, format, compress, and write the arguments (...) to file under - control of the string format, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or a negative zlib error code 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(gzFile file, const char *s); -/* - Compress and write the given null-terminated string s to file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets(gzFile file, char *buf, int len); -/* - Read and decompress bytes from file into buf, until len-1 characters are - read, or until 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 - is one, the string is terminated with a null character. If no characters - are read due to an end-of-file or len is less than one, 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(gzFile file, int c); -/* - Compress and write c, converted to an unsigned char, into file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc(gzFile file); -/* - Read and decompress one byte from 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(int c, gzFile file); -/* - Push c back onto the stream for file to be read as the first character on - the next read. At least one character of push-back is always 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(gzFile file, int flush); -/* - Flush all pending output to 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 - concatenated 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(gzFile file, - z_off_t offset, int whence); - - Set the starting position to offset relative to whence for the next gzread - or gzwrite on 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(gzFile file); -/* - Rewind 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(gzFile file); - - Return the starting position for the next gzread or gzwrite on 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(gzFile file); - - Return the current compressed (actual) read or write offset of file. 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(gzFile file); -/* - Return true (1) if the end-of-file indicator for file 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(gzFile file); -/* - Return 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(gzFile file); -/* - Flush all pending output for file, if necessary, close file and - deallocate 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(gzFile file); -ZEXTERN int ZEXPORT gzclose_w(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(gzFile file, int *errnum); -/* - Return the error message for the last error which occurred on 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(gzFile file); -/* - Clear 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(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. An Adler-32 value is in the range of a 32-bit - unsigned integer. 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 CRC-32 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_z(uLong adler, const Bytef *buf, - z_size_t len); -/* - Same as adler32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine(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(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. A CRC-32 value is in the range of a 32-bit unsigned integer. - 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_z(uLong crc, const Bytef *buf, - z_size_t len); -/* - Same as crc32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine(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. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); - - Return the operator corresponding to length len2, to be used with - crc32_combine_op(). -*/ - -ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); -/* - Give the same result as crc32_combine(), using op in place of len2. op is - is generated from len2 by crc32_combine_gen(). This will be faster than - crc32_combine() if the generated op is used more than once. -*/ - - - /* 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_(z_streamp strm, int level, - const char *version, int stream_size); -ZEXTERN int ZEXPORT inflateInit_(z_streamp strm, - const char *version, int stream_size); -ZEXTERN int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size); -ZEXTERN int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, - const char *version, int stream_size); -ZEXTERN int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size); -#ifdef Z_PREFIX_SET -# define z_deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define z_inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#else -# 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)) -#endif - -#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_(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(const char *, const char *); - ZEXTERN z_off64_t ZEXPORT gzseek64(gzFile, z_off64_t, int); - ZEXTERN z_off64_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off64_t ZEXPORT gzoffset64(gzFile); - ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off64_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off64_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(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 -# define z_crc32_combine_gen z_crc32_combine_gen64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# define crc32_combine_gen crc32_combine_gen64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64(const char *, const char *); - ZEXTERN z_off_t ZEXPORT gzseek64(gzFile, z_off_t, int); - ZEXTERN z_off_t ZEXPORT gztell64(gzFile); - ZEXTERN z_off_t ZEXPORT gzoffset64(gzFile); - ZEXTERN uLong ZEXPORT adler32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen(const char *, const char *); - ZEXTERN z_off_t ZEXPORT gzseek(gzFile, z_off_t, int); - ZEXTERN z_off_t ZEXPORT gztell(gzFile); - ZEXTERN z_off_t ZEXPORT gzoffset(gzFile); - ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); -#endif - -#else /* Z_SOLO */ - - ZEXTERN uLong ZEXPORT adler32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t); - -#endif /* !Z_SOLO */ - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError(int); -ZEXTERN int ZEXPORT inflateSyncPoint(z_streamp); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table(void); -ZEXTERN int ZEXPORT inflateUndermine(z_streamp, int); -ZEXTERN int ZEXPORT inflateValidate(z_streamp, int); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed(z_streamp); -ZEXTERN int ZEXPORT inflateResetKeep(z_streamp); -ZEXTERN int ZEXPORT deflateResetKeep(z_streamp); -#if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w(const wchar_t *path, - const char *mode); -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf(gzFile file, - const char *format, - va_list va); -# endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/libraries/zlib/zutil.c b/libraries/zlib/zutil.c deleted file mode 100644 index b1c5d2d3c..000000000 --- a/libraries/zlib/zutil.c +++ /dev/null @@ -1,299 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2017 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" -#ifndef Z_SOLO -# include "gzguts.h" -#endif - -z_const char * const z_errmsg[10] = { - (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ - (z_const char *)"stream end", /* Z_STREAM_END 1 */ - (z_const char *)"", /* Z_OK 0 */ - (z_const char *)"file error", /* Z_ERRNO (-1) */ - (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ - (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ - (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ - (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ - (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ - (z_const char *)"" -}; - - -const char * ZEXPORT zlibVersion(void) { - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags(void) { - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef ZLIB_DEBUG - flags += 1 << 8; -#endif - /* -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif - */ -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef ZLIB_DEBUG -#include -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error(char *m) { - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(int err) { - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800 - /* The older Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(Bytef* dest, const Bytef* source, uInt len) { - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len) { - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len) { - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifndef Z_SOLO - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { - voidpf buf; - ulg bsize = (ulg)items*size; - - (void)opaque; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - int n; - - (void)opaque; - - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { - (void)opaque; - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - (void)opaque; - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc(uInt size); -extern voidp calloc(uInt items, uInt size); -extern void free(voidpf ptr); -#endif - -voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { - (void)opaque; - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - (void)opaque; - free(ptr); -} - -#endif /* MY_ZCALLOC */ - -#endif /* !Z_SOLO */ diff --git a/libraries/zlib/zutil.h b/libraries/zlib/zutil.h deleted file mode 100644 index 902a304cc..000000000 --- a/libraries/zlib/zutil.h +++ /dev/null @@ -1,275 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2022 Jean-loup Gailly, 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. - */ - -/* @(#) $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 -# endif -# include -# include -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (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; - -#if !defined(Z_U8) && !defined(Z_SOLO) && defined(STDC) -# include -# if (ULONG_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned long -# elif (ULLONG_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned long long -# elif (UINT_MAX == 0xffffffffffffffff) -# define Z_U8 unsigned -# endif -#endif - -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 -# endif -# else /* MSC or DJGPP */ -# include -# endif -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 1 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 2 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#ifdef __370__ -# if __TARGET_LIB__ < 0x20000000 -# define OS_CODE 4 -# elif __TARGET_LIB__ < 0x40000000 -# define OS_CODE 11 -# else -# define OS_CODE 8 -# endif -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 5 -#endif - -#ifdef OS2 -# define OS_CODE 6 -# if defined(M_I86) && !defined(Z_SOLO) -# include -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif -#endif - -#ifdef __acorn -# define OS_CODE 13 -#endif - -#if defined(WIN32) && !defined(__CYGWIN__) -# define OS_CODE 10 -#endif - -#ifdef _BEOS_ -# define OS_CODE 16 -#endif - -#ifdef __TOS_OS400__ -# define OS_CODE 18 -#endif - -#ifdef __APPLE__ -# define OS_CODE 19 -#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() */ -# 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(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine64(uLong, uLong, z_off_t); - ZEXTERN uLong ZEXPORT crc32_combine_gen64(z_off_t); -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 3 /* 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(Bytef* dest, const Bytef* source, uInt len); - int ZLIB_INTERNAL zmemcmp(const Bytef* s1, const Bytef* s2, uInt len); - void ZLIB_INTERNAL zmemzero(Bytef* dest, uInt len); -#endif - -/* Diagnostic functions */ -#ifdef ZLIB_DEBUG -# include - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error(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(voidpf opaque, unsigned items, - unsigned size); - void ZLIB_INTERNAL zcfree(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/src/CMakeLists.txt b/src/CMakeLists.txt index 7072b143e..5b0a3eac8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -319,7 +319,7 @@ add_custom_target( revision_check ALL # required libraries -set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} "${ZLIB_LIBRARIES}" "${BZIP2_LIBRARIES}" "${CMAKE_DL_LIBS}" "${DRPC_LIBRARIES}") +set( PROJECT_LIBRARIES ${PROJECT_LIBRARIES} miniz "${BZIP2_LIBRARIES}" "${CMAKE_DL_LIBS}" "${DRPC_LIBRARIES}") if (HAVE_VULKAN) list( APPEND PROJECT_LIBRARIES "zvulkan" ) endif() @@ -387,7 +387,7 @@ if (TARGET WebP::webp) endif() endif() -include_directories( SYSTEM "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${ZMUSIC_INCLUDE_DIR}" "${DRPC_INCLUDE_DIR}") +include_directories( SYSTEM "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" "${ZMUSIC_INCLUDE_DIR}" "${DRPC_INCLUDE_DIR}") if( ${HAVE_VM_JIT} ) add_definitions( -DHAVE_VM_JIT ) diff --git a/src/common/audio/music/i_music.cpp b/src/common/audio/music/i_music.cpp index 2e0f83319..b3f0a3d0d 100644 --- a/src/common/audio/music/i_music.cpp +++ b/src/common/audio/music/i_music.cpp @@ -37,7 +37,7 @@ #include #endif -#include +#include #include #include "filesystem.h" diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index 11eab7b9f..3ea5bdb0b 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -37,7 +37,7 @@ #define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 #define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseFullPrecisionFlag -#include +#include #include "rapidjson/rapidjson.h" #include "rapidjson/writer.h" #include "rapidjson/prettywriter.h" diff --git a/src/common/filesystem/source/files_decompress.cpp b/src/common/filesystem/source/files_decompress.cpp index 0be5abdaa..a49906a1f 100644 --- a/src/common/filesystem/source/files_decompress.cpp +++ b/src/common/filesystem/source/files_decompress.cpp @@ -36,7 +36,7 @@ // Caution: LzmaDec also pulls in windows.h! #define NOMINMAX #include "LzmaDec.h" -#include +#include #include #include #include diff --git a/src/common/filesystem/source/filesystem.cpp b/src/common/filesystem/source/filesystem.cpp index cc810cc2e..1cdb6692b 100644 --- a/src/common/filesystem/source/filesystem.cpp +++ b/src/common/filesystem/source/filesystem.cpp @@ -36,7 +36,7 @@ // HEADER FILES ------------------------------------------------------------ -#include +#include #include #include #include diff --git a/src/common/filesystem/source/resourcefile.cpp b/src/common/filesystem/source/resourcefile.cpp index c86d4e11f..1da4aa04d 100644 --- a/src/common/filesystem/source/resourcefile.cpp +++ b/src/common/filesystem/source/resourcefile.cpp @@ -34,7 +34,7 @@ ** */ -#include +#include #include "resourcefile_internal.h" #include "md5.hpp" #include "fs_stringpool.h" diff --git a/src/common/models/model.cpp b/src/common/models/model.cpp index a7dccfc09..f8eb12feb 100644 --- a/src/common/models/model.cpp +++ b/src/common/models/model.cpp @@ -25,6 +25,7 @@ ** General model handling code ** **/ +#include // offsetof() macro. #include "filesystem.h" #include "cmdlib.h" @@ -132,17 +133,7 @@ FTextureID LoadSkin(const char * path, const char * fn) int ModelFrameHash(FSpriteModelFrame * smf) { - const uint32_t *table = GetCRCTable (); - uint32_t hash = 0xffffffff; - - const char * s = (const char *)(&smf->type); // this uses type, sprite and frame for hashing - const char * se= (const char *)(&smf->hashnext); - - for (; stype), offsetof(FSpriteModelFrame, hashnext) - offsetof(FSpriteModelFrame, type)); } //=========================================================================== diff --git a/src/common/platform/win32/i_crash.cpp b/src/common/platform/win32/i_crash.cpp index b90663597..ab65b2ea5 100644 --- a/src/common/platform/win32/i_crash.cpp +++ b/src/common/platform/win32/i_crash.cpp @@ -68,7 +68,7 @@ #include "i_mainwindow.h" #include -#include +#include // MACROS ------------------------------------------------------------------ diff --git a/src/common/textures/m_png.cpp b/src/common/textures/m_png.cpp index 07cc1ab74..43e548e6c 100644 --- a/src/common/textures/m_png.cpp +++ b/src/common/textures/m_png.cpp @@ -36,7 +36,7 @@ #include #include -#include +#include #include #ifdef _MSC_VER #include // for alloca() diff --git a/src/common/thirdparty/m_crc32.h b/src/common/thirdparty/m_crc32.h index 2930b8cbd..d2de074fc 100644 --- a/src/common/thirdparty/m_crc32.h +++ b/src/common/thirdparty/m_crc32.h @@ -32,12 +32,11 @@ ** */ #pragma once -#include +#include #include -// zlib includes some CRC32 stuff, so just use that +// miniz includes some CRC32 stuff, so just use that -inline const uint32_t *GetCRCTable () { return (const uint32_t *)get_crc_table(); } inline uint32_t CalcCRC32 (const uint8_t *buf, unsigned int len) { return crc32 (0, buf, len); diff --git a/src/g_pch.h b/src/g_pch.h index cf3dfdbd5..a6623a2da 100644 --- a/src/g_pch.h +++ b/src/g_pch.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/g_pch2.h b/src/g_pch2.h index f5871488a..5ac06f8f0 100644 --- a/src/g_pch2.h +++ b/src/g_pch2.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index 1a6d67084..63f738dde 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -42,7 +42,7 @@ #endif -#include +#include #include "m_argv.h" #include "c_dispatch.h" diff --git a/src/serializer_doom.cpp b/src/serializer_doom.cpp index 63dc08b07..2ec1c8b86 100644 --- a/src/serializer_doom.cpp +++ b/src/serializer_doom.cpp @@ -38,7 +38,7 @@ #define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 #define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseFullPrecisionFlag -#include +#include #include "rapidjson/rapidjson.h" #include "rapidjson/writer.h" #include "rapidjson/prettywriter.h" diff --git a/tools/zipdir/CMakeLists.txt b/tools/zipdir/CMakeLists.txt index 17c3af223..d08ca093c 100644 --- a/tools/zipdir/CMakeLists.txt +++ b/tools/zipdir/CMakeLists.txt @@ -1,9 +1,9 @@ cmake_minimum_required( VERSION 3.16 ) if( NOT CMAKE_CROSSCOMPILING ) - include_directories( SYSTEM "${ZLIB_INCLUDE_DIR}" "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" ) + include_directories( SYSTEM "${BZIP2_INCLUDE_DIR}" "${LZMA_INCLUDE_DIR}" ) add_executable( zipdir zipdir.c ) - target_link_libraries( zipdir ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} lzma ) + target_link_libraries( zipdir miniz ${BZIP2_LIBRARIES} lzma ) set( CROSS_EXPORTS ${CROSS_EXPORTS} zipdir PARENT_SCOPE ) endif() diff --git a/tools/zipdir/zipdir.c b/tools/zipdir/zipdir.c index dab0dac04..4ae81d8e3 100644 --- a/tools/zipdir/zipdir.c +++ b/tools/zipdir/zipdir.c @@ -46,7 +46,7 @@ #include #include #include -#include "zlib.h" +#include #include "bzlib.h" #include "LzmaEnc.h" #include "7zVersion.h" diff --git a/vcpkg.json b/vcpkg.json index edf05d241..723cbb0e2 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -27,10 +27,6 @@ } }, "dependencies": [ - { - "name": "zlib", - "platform": "!windows | (windows & static & staticcrt)" - }, { "name": "bzip2", "platform": "!windows | (windows & static & staticcrt)" From cfe30c1d477e5cc8339226ebbb37f37b5bd2f019 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 18 Sep 2023 09:54:24 +0200 Subject: [PATCH 145/223] Fix stdexcept include errors --- libraries/ZVulkan/src/vulkanbuilders.cpp | 11 ++++--- libraries/ZVulkan/src/vulkanswapchain.cpp | 35 ++++++++++++----------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/libraries/ZVulkan/src/vulkanbuilders.cpp b/libraries/ZVulkan/src/vulkanbuilders.cpp index 013c34c22..df84e6546 100644 --- a/libraries/ZVulkan/src/vulkanbuilders.cpp +++ b/libraries/ZVulkan/src/vulkanbuilders.cpp @@ -1,4 +1,3 @@ -#include #include "vulkanbuilders.h" #include "vulkansurface.h" #include "vulkancompatibledevice.h" @@ -281,7 +280,7 @@ std::unique_ptr ShaderBuilder::Create(const char *shadername, Vulk bool compileSuccess = shader.parse(&resources, 110, false, EShMsgVulkanRules, includer); if (!compileSuccess) { - throw std::runtime_error(std::string("Shader compile failed: ") + shader.getInfoLog()); + VulkanError((std::string("Shader compile failed: ") + shader.getInfoLog()).c_str()); } glslang::TProgram program; @@ -289,13 +288,13 @@ std::unique_ptr ShaderBuilder::Create(const char *shadername, Vulk bool linkSuccess = program.link(EShMsgDefault); if (!linkSuccess) { - throw std::runtime_error(std::string("Shader link failed: ") + program.getInfoLog()); + VulkanError((std::string("Shader link failed: ") + program.getInfoLog()).c_str()); } glslang::TIntermediate *intermediate = program.getIntermediate(stage); if (!intermediate) { - throw std::runtime_error("Internal shader compiler error"); + VulkanError("Internal shader compiler error"); } glslang::SpvOptions spvOptions; @@ -315,7 +314,7 @@ std::unique_ptr ShaderBuilder::Create(const char *shadername, Vulk VkShaderModule shaderModule; VkResult result = vkCreateShaderModule(device->device, &createInfo, nullptr, &shaderModule); if (result != VK_SUCCESS) - throw std::runtime_error("Could not create vulkan shader module"); + VulkanError("Could not create vulkan shader module"); auto obj = std::make_unique(device, shaderModule); if (debugName) @@ -704,7 +703,7 @@ std::unique_ptr AccelerationStructureBuilder::Creat VkAccelerationStructureKHR hande = {}; VkResult result = vkCreateAccelerationStructureKHR(device->device, &createInfo, nullptr, &hande); if (result != VK_SUCCESS) - throw std::runtime_error("vkCreateAccelerationStructureKHR failed"); + VulkanError("vkCreateAccelerationStructureKHR failed"); auto obj = std::make_unique(device, hande); if (debugName) obj->SetDebugName(debugName); diff --git a/libraries/ZVulkan/src/vulkanswapchain.cpp b/libraries/ZVulkan/src/vulkanswapchain.cpp index 495c68416..12e0987c6 100644 --- a/libraries/ZVulkan/src/vulkanswapchain.cpp +++ b/libraries/ZVulkan/src/vulkanswapchain.cpp @@ -34,13 +34,13 @@ void VulkanSwapChain::Create(int width, int height, int imageCount, bool vsync, uint32_t imageCount; VkResult result = vkGetSwapchainImagesKHR(device->device, swapchain, &imageCount, nullptr); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetSwapchainImagesKHR failed"); + VulkanError("vkGetSwapchainImagesKHR failed"); std::vector swapchainImages; swapchainImages.resize(imageCount); result = vkGetSwapchainImagesKHR(device->device, swapchain, &imageCount, swapchainImages.data()); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetSwapchainImagesKHR failed (2)"); + VulkanError("vkGetSwapchainImagesKHR failed (2)"); for (VkImage vkimage : swapchainImages) { @@ -103,7 +103,7 @@ bool VulkanSwapChain::CreateSwapchain(int width, int height, int imageCount, boo } if (caps.PresentModes.empty()) - throw std::runtime_error("No surface present modes supported"); + VulkanError("No surface present modes supported"); bool supportsFifoRelaxed = std::find(caps.PresentModes.begin(), caps.PresentModes.end(), VK_PRESENT_MODE_FIFO_RELAXED_KHR) != caps.PresentModes.end(); bool supportsMailbox = std::find(caps.PresentModes.begin(), caps.PresentModes.end(), VK_PRESENT_MODE_MAILBOX_KHR) != caps.PresentModes.end(); @@ -241,7 +241,8 @@ int VulkanSwapChain::AcquireImage(VulkanSemaphore* semaphore, VulkanFence* fence } else { - throw std::runtime_error("Failed to acquire next image!"); + VulkanError("Failed to acquire next image!"); + return -1; } } @@ -270,15 +271,15 @@ void VulkanSwapChain::QueuePresent(int imageIndex, VulkanSemaphore* semaphore) // The spec says we can recover from this. // However, if we are out of memory it is better to crash now than in some other weird place further away from the source of the problem. - throw std::runtime_error("vkQueuePresentKHR failed: out of memory"); + VulkanError("vkQueuePresentKHR failed: out of memory"); } else if (result == VK_ERROR_DEVICE_LOST) { - throw std::runtime_error("vkQueuePresentKHR failed: device lost"); + VulkanError("vkQueuePresentKHR failed: device lost"); } else { - throw std::runtime_error("vkQueuePresentKHR failed"); + VulkanError("vkQueuePresentKHR failed"); } } @@ -332,7 +333,7 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive VkResult result = vkGetPhysicalDeviceSurfaceCapabilities2KHR(device->PhysicalDevice.Device, &surfaceInfo, &caps2); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceCapabilities2KHR failed"); + VulkanError("vkGetPhysicalDeviceSurfaceCapabilities2KHR failed"); caps.Capabilites = caps2.surfaceCapabilities; } @@ -340,7 +341,7 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive { VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &caps.Capabilites); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed"); + VulkanError("vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed"); } #ifdef WIN32 @@ -351,14 +352,14 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive uint32_t presentModeCount = 0; VkResult result = vkGetPhysicalDeviceSurfacePresentModes2EXT(device->PhysicalDevice.Device, &surfaceInfo, &presentModeCount, nullptr); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModes2EXT failed"); + VulkanError("vkGetPhysicalDeviceSurfacePresentModes2EXT failed"); if (presentModeCount > 0) { caps.PresentModes.resize(presentModeCount); result = vkGetPhysicalDeviceSurfacePresentModes2EXT(device->PhysicalDevice.Device, &surfaceInfo, &presentModeCount, caps.PresentModes.data()); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModes2EXT failed"); + VulkanError("vkGetPhysicalDeviceSurfacePresentModes2EXT failed"); } } else @@ -367,14 +368,14 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive uint32_t presentModeCount = 0; VkResult result = vkGetPhysicalDeviceSurfacePresentModesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &presentModeCount, nullptr); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModesKHR failed"); + VulkanError("vkGetPhysicalDeviceSurfacePresentModesKHR failed"); if (presentModeCount > 0) { caps.PresentModes.resize(presentModeCount); result = vkGetPhysicalDeviceSurfacePresentModesKHR(device->PhysicalDevice.Device, device->Surface->Surface, &presentModeCount, caps.PresentModes.data()); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfacePresentModesKHR failed"); + VulkanError("vkGetPhysicalDeviceSurfacePresentModesKHR failed"); } } @@ -383,14 +384,14 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive uint32_t surfaceFormatCount = 0; VkResult result = vkGetPhysicalDeviceSurfaceFormats2KHR(device->PhysicalDevice.Device, &surfaceInfo, &surfaceFormatCount, nullptr); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormats2KHR failed"); + VulkanError("vkGetPhysicalDeviceSurfaceFormats2KHR failed"); if (surfaceFormatCount > 0) { std::vector formats(surfaceFormatCount, { VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR }); result = vkGetPhysicalDeviceSurfaceFormats2KHR(device->PhysicalDevice.Device, &surfaceInfo, &surfaceFormatCount, formats.data()); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormats2KHR failed"); + VulkanError("vkGetPhysicalDeviceSurfaceFormats2KHR failed"); for (VkSurfaceFormat2KHR& fmt : formats) caps.Formats.push_back(fmt.surfaceFormat); @@ -401,14 +402,14 @@ VulkanSurfaceCapabilities VulkanSwapChain::GetSurfaceCapabilities(bool exclusive uint32_t surfaceFormatCount = 0; VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(device->PhysicalDevice.Device, device->Surface->Surface, &surfaceFormatCount, nullptr); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormatsKHR failed"); + VulkanError("vkGetPhysicalDeviceSurfaceFormatsKHR failed"); if (surfaceFormatCount > 0) { caps.Formats.resize(surfaceFormatCount); result = vkGetPhysicalDeviceSurfaceFormatsKHR(device->PhysicalDevice.Device, device->Surface->Surface, &surfaceFormatCount, caps.Formats.data()); if (result != VK_SUCCESS) - throw std::runtime_error("vkGetPhysicalDeviceSurfaceFormatsKHR failed"); + VulkanError("vkGetPhysicalDeviceSurfaceFormatsKHR failed"); } } From ce893d2cd4789434535b41e44a926d913bd4ab6a Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Tue, 19 Sep 2023 07:29:36 -0400 Subject: [PATCH 146/223] - remove some double semicolons --- wadsrc/static/zscript/actors/doom/doomdecorations.zs | 6 +++--- wadsrc/static/zscript/actors/inventory/powerups.zs | 2 +- wadsrc/static/zscript/ui/statscreen/statscreen.zs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/wadsrc/static/zscript/actors/doom/doomdecorations.zs b/wadsrc/static/zscript/actors/doom/doomdecorations.zs index 8eec812f6..ab5bd5b4f 100644 --- a/wadsrc/static/zscript/actors/doom/doomdecorations.zs +++ b/wadsrc/static/zscript/actors/doom/doomdecorations.zs @@ -82,7 +82,7 @@ class ShortGreenColumn : Actor Default { Radius 16; - Height 40;; + Height 40; ProjectilePassHeight -16; +SOLID } @@ -234,7 +234,7 @@ class BlueTorch : Actor Default { Radius 16; - Height 68;; + Height 68; ProjectilePassHeight -16; +SOLID } @@ -594,7 +594,7 @@ class HeadsOnAStick : Actor Default { Radius 16; - Height 64;; + Height 64; ProjectilePassHeight -16; +SOLID } diff --git a/wadsrc/static/zscript/actors/inventory/powerups.zs b/wadsrc/static/zscript/actors/inventory/powerups.zs index 67983aae8..9c4903d01 100644 --- a/wadsrc/static/zscript/actors/inventory/powerups.zs +++ b/wadsrc/static/zscript/actors/inventory/powerups.zs @@ -956,7 +956,7 @@ class PowerFlight : Powerup Owner.bNoGravity = true; if (Owner.pos.Z <= Owner.floorz) { - Owner.Vel.Z = 4;; // thrust the player in the air a bit + Owner.Vel.Z = 4; // thrust the player in the air a bit } if (Owner.Vel.Z <= -35) { // stop falling scream diff --git a/wadsrc/static/zscript/ui/statscreen/statscreen.zs b/wadsrc/static/zscript/ui/statscreen/statscreen.zs index 500185ee0..4b50f0cf7 100644 --- a/wadsrc/static/zscript/ui/statscreen/statscreen.zs +++ b/wadsrc/static/zscript/ui/statscreen/statscreen.zs @@ -148,7 +148,7 @@ class StatusScreen : ScreenJob abstract version("2.5") scalemode = FSMode_ScaleToFit43; scalefactorx = 1; scalefactory = 1; - wrapwidth = wrapw == -1 ? width : wrapw;; + wrapwidth = wrapw == -1 ? width : wrapw; } //==================================================================== From 0b3e9b10256c3828d58a1c6e9698cf87a3f7a044 Mon Sep 17 00:00:00 2001 From: nashmuhandes Date: Tue, 19 Sep 2023 21:53:04 +0800 Subject: [PATCH 147/223] Add ZScript constants used by FallAndSink --- wadsrc/static/zscript/constants.zs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wadsrc/static/zscript/constants.zs b/wadsrc/static/zscript/constants.zs index 23252932c..4488b223f 100644 --- a/wadsrc/static/zscript/constants.zs +++ b/wadsrc/static/zscript/constants.zs @@ -1456,3 +1456,9 @@ const M_2_PI = 0.63661977236758134308; // 2/pi const M_2_SQRTPI = 1.12837916709551257390; // 2/sqrt(pi) const M_SQRT2 = 1.41421356237309504880; // sqrt(2) const M_SQRT1_2 = 0.70710678118654752440; // 1/sqrt(2) + +// Used by Actor.FallAndSink +const WATER_SINK_FACTOR = 0.125; +const WATER_SINK_SMALL_FACTOR = 0.25; +const WATER_SINK_SPEED = 0.5; +const WATER_JUMP_SPEED = 3.5; From e3e50714759a02bda565c7fdaffbb3c7069b2dc0 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 20 Sep 2023 10:26:06 +0300 Subject: [PATCH 148/223] - updated continuous integration workflow * bump GCC targets to 9 and 12 * bump Clang targets to 11 and 15 * use Ubuntu 22.04 images * use actual versions of checkout and upload-artifact actions * remove lots of needless formatting, double quotes in particular * remove unused dependencies * remove obsolete Strawberry Perl workaround --- .github/workflows/continuous_integration.yml | 120 ++++++++----------- 1 file changed, 53 insertions(+), 67 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 30bf10df1..aa323c939 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -10,73 +10,63 @@ jobs: fail-fast: false matrix: config: - - { - name: "Visual Studio 2022", - os: windows-2022, - extra_options: "-A x64 -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake", - build_type: "Release" - } - - { - name: "Visual Studio 2019", - os: windows-2019, - extra_options: "-A x64 -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake", - build_type: "Release" - } - - { - name: "Visual Studio 2019", - os: windows-2019, - extra_options: "-A x64 -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake", - build_type: "Debug" - } - - { - name: "macOS", - os: macos-12, - deps_cmdline: "brew install libvpx webp", - build_type: "Release" - } - - { - name: "macOS", - os: macos-12, - extra_options: "-G Xcode -DDYN_OPENAL=OFF", - deps_cmdline: "brew install libvpx fluidsynth mpg123 libsndfile webp", - build_type: "Debug" - } - - { - name: "Linux GCC 7", - os: ubuntu-20.04, - extra_options: "-DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7", - deps_cmdline: "sudo apt update && sudo apt install g++-7 libsdl2-dev libvpx-dev libgtk2.0-dev libwebp-dev", - build_type: "RelWithDebInfo" - } - - { - name: "Linux GCC 11", - os: ubuntu-20.04, - extra_options: "-DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11", - deps_cmdline: "sudo apt update && sudo apt install g++-11 libsdl2-dev libvpx-dev libgtk-3-dev libwebp-dev", - build_type: "MinSizeRel" - } - - { - name: "Linux Clang 10", - os: ubuntu-20.04, - extra_options: "-DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 -DDYN_OPENAL=OFF", - deps_cmdline: "sudo apt update && sudo apt install clang-9 libsdl2-dev libvpx-dev libopenal-dev libfluidsynth-dev libmpg123-dev libsndfile1-dev libwebp-dev", - build_type: "Debug" - } - - { - name: "Linux Clang 12", - os: ubuntu-20.04, - extra_options: "-DCMAKE_C_COMPILER=clang-12 -DCMAKE_CXX_COMPILER=clang++-12", - deps_cmdline: "sudo apt update && sudo apt install clang-12 libsdl2-dev libvpx-dev libwebp-dev", - build_type: "Release" - } + - name: Visual Studio 2022 + os: windows-2022 + extra_options: -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake + build_type: Release + + - name: Visual Studio 2022 + os: windows-2022 + extra_options: -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake + build_type: Debug + + - name: Visual Studio 2019 + os: windows-2019 + extra_options: -DCMAKE_TOOLCHAIN_FILE=build/vcpkg/scripts/buildsystems/vcpkg.cmake + build_type: Release + + - name: macOS + os: macos-12 + deps_cmdline: brew install libvpx webp + build_type: Release + + - name: macOS + os: macos-12 + extra_options: -G Xcode -DDYN_OPENAL=OFF + deps_cmdline: brew install libvpx webp + build_type: Debug + + - name: Linux GCC 9 + os: ubuntu-22.04 + extra_options: -DCMAKE_C_COMPILER=gcc-9 -DCMAKE_CXX_COMPILER=g++-9 + deps_cmdline: sudo apt update && sudo apt install libsdl2-dev libvpx-dev libgtk2.0-dev libwebp-dev + build_type: RelWithDebInfo + + - name: Linux GCC 12 + os: ubuntu-22.04 + extra_options: -DCMAKE_C_COMPILER=gcc-12 -DCMAKE_CXX_COMPILER=g++-12 + deps_cmdline: sudo apt update && sudo apt install libsdl2-dev libvpx-dev libgtk-3-dev libwebp-dev + build_type: MinSizeRel + + - name: Linux Clang 11 + os: ubuntu-22.04 + extra_options: -DCMAKE_C_COMPILER=clang-11 -DCMAKE_CXX_COMPILER=clang++-11 -DDYN_OPENAL=OFF + deps_cmdline: sudo apt update && sudo apt install clang-11 libsdl2-dev libvpx-dev libopenal-dev libwebp-dev + build_type: Debug + + - name: Linux Clang 15 + os: ubuntu-22.04 + extra_options: -DCMAKE_C_COMPILER=clang-15 -DCMAKE_CXX_COMPILER=clang++-15 + deps_cmdline: sudo apt update && sudo apt install clang-15 libsdl2-dev libvpx-dev libwebp-dev + build_type: Release steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Install Dependencies shell: bash run: | - if [[ ! -z "${{ matrix.config.deps_cmdline }}" ]]; then + if [[ -n "${{ matrix.config.deps_cmdline }}" ]]; then eval ${{ matrix.config.deps_cmdline }} fi mkdir build @@ -85,7 +75,7 @@ jobs: elif [[ "${{ runner.os }}" == 'Linux' ]]; then export ZMUSIC_PACKAGE=zmusic-1.1.9-linux.tar.xz fi - if [[ ! -z "${ZMUSIC_PACKAGE}" ]]; then + if [[ -n "${ZMUSIC_PACKAGE}" ]]; then cd build wget -q "https://github.com/coelckers/gzdoom/releases/download/ci_deps/${ZMUSIC_PACKAGE}" tar -xf "${ZMUSIC_PACKAGE}" @@ -101,10 +91,6 @@ jobs: - name: Configure shell: bash run: | - if [[ "${{ runner.os }}" == 'Windows' ]]; then - # Remove Strawberry Perl from PATH environment variable to avoid usage of libraries it provides - export PATH=`echo $PATH | tr ":" "\n" | grep -v "Strawberry" | tr "\n" ":"` - fi cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} -DCMAKE_PREFIX_PATH=`pwd`/build/zmusic -DPK3_QUIET_ZIPDIR=ON ${{ matrix.config.extra_options }} . - name: Build @@ -129,7 +115,7 @@ jobs: - name: Upload Package if: runner.os == 'Windows' # Remove to store packages of all targets - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v3 with: path: build/package name: ${{ matrix.config.name }} ${{ matrix.config.build_type }} From 69e67037f84f27beda7fab8f9afb66b9e49b1ade Mon Sep 17 00:00:00 2001 From: inkoalawetrust <56005600+inkoalawetrust@users.noreply.github.com> Date: Wed, 20 Sep 2023 01:56:46 +0300 Subject: [PATCH 149/223] Changed the variable type of Crossed3DWater. Seems like there was some kind of oversight. Crossed3DWater is an F3DFloor pointer, not sector_t. --- wadsrc/static/zscript/doombase.zs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/doombase.zs b/wadsrc/static/zscript/doombase.zs index 6ed46159a..1ff7cead3 100644 --- a/wadsrc/static/zscript/doombase.zs +++ b/wadsrc/static/zscript/doombase.zs @@ -292,7 +292,7 @@ struct TraceResults native native Sector CrossedWater; // For Boom-style, Transfer_Heights-based deep water native vector3 CrossedWaterPos; // remember the position so that we can use it for spawning the splash - native Sector Crossed3DWater; // For 3D floor-based deep water + native F3DFloor Crossed3DWater; // For 3D floor-based deep water native vector3 Crossed3DWaterPos; } From b3cb2fafc732a0af1f9ce63b76627cc4603028f2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 20 Sep 2023 19:49:43 +0200 Subject: [PATCH 150/223] stats --- src/common/platform/posix/cocoa/i_main.mm | 4 +++ src/common/platform/posix/sdl/i_main.cpp | 2 ++ src/common/platform/win32/i_system.cpp | 9 ++---- src/d_anonstats.cpp | 39 ++++++----------------- 4 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/common/platform/posix/cocoa/i_main.mm b/src/common/platform/posix/cocoa/i_main.mm index 8c58ca419..50353ba3d 100644 --- a/src/common/platform/posix/cocoa/i_main.mm +++ b/src/common/platform/posix/cocoa/i_main.mm @@ -47,6 +47,7 @@ #include "printf.h" #include "s_music.h" #include "engineerrors.h" +#include "zstring.h" #define ZD_UNUSED(VARIABLE) ((void)(VARIABLE)) @@ -130,6 +131,7 @@ static bool ReadSystemVersionFromPlist(NSOperatingSystemVersion& version) return false; } +FString sys_ostype; void I_DetectOS() { NSOperatingSystemVersion version = {}; @@ -192,6 +194,8 @@ void I_DetectOS() Printf("%s running macOS %s %d.%d.%d (%s) %s\n", model, name, int(version.majorVersion), int(version.minorVersion), int(version.patchVersion), release, architecture); + + sys_ostype.Format("macOS %d.%d %s", int(version.majorVersion), int(version.minorVersion), name); } diff --git a/src/common/platform/posix/sdl/i_main.cpp b/src/common/platform/posix/sdl/i_main.cpp index 196504b54..4f29bb76e 100644 --- a/src/common/platform/posix/sdl/i_main.cpp +++ b/src/common/platform/posix/sdl/i_main.cpp @@ -77,6 +77,7 @@ int GameMain(); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- // PUBLIC DATA DEFINITIONS ------------------------------------------------- +FString sys_ostype; // The command line arguments. FArgs *Args; @@ -136,6 +137,7 @@ void I_DetectOS() { const char* const separator = operatingSystem.Len() > 0 ? ", " : ""; operatingSystem.AppendFormat("%s%s %s on %s", separator, unameInfo.sysname, unameInfo.release, unameInfo.machine); + sys_ostype.Format("%s %s on %s", unameInfo.sysname, unameInfo.release, unameInfo.machine); } if (operatingSystem.Len() > 0) diff --git a/src/common/platform/win32/i_system.cpp b/src/common/platform/win32/i_system.cpp index 8b39061a6..0a9843e94 100644 --- a/src/common/platform/win32/i_system.cpp +++ b/src/common/platform/win32/i_system.cpp @@ -128,7 +128,7 @@ double PerfToSec, PerfToMillisec; UINT TimerPeriod; -int sys_ostype = 0; +const char* sys_ostype = ""; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -168,12 +168,10 @@ void I_DetectOS(void) if (info.dwMinorVersion == 0) { osname = (info.wProductType == VER_NT_WORKSTATION) ? "Vista" : "Server 2008"; - sys_ostype = 2; // legacy OS } else if (info.dwMinorVersion == 1) { osname = (info.wProductType == VER_NT_WORKSTATION) ? "7" : "Server 2008 R2"; - sys_ostype = 2; // supported OS } else if (info.dwMinorVersion == 2) { @@ -181,12 +179,10 @@ void I_DetectOS(void) // the highest version of Windows you support, which will also be the // highest version of Windows this function returns. osname = (info.wProductType == VER_NT_WORKSTATION) ? "8" : "Server 2012"; - sys_ostype = 2; // supported OS } else if (info.dwMinorVersion == 3) { osname = (info.wProductType == VER_NT_WORKSTATION) ? "8.1" : "Server 2012 R2"; - sys_ostype = 2; // supported OS } else if (info.dwMinorVersion == 4) { @@ -196,7 +192,6 @@ void I_DetectOS(void) else if (info.dwMajorVersion == 10) { osname = (info.wProductType == VER_NT_WORKSTATION) ? (info.dwBuildNumber >= 22000 ? "11 (or higher)" : "10") : "Server 2016 (or higher)"; - sys_ostype = 3; // modern OS } break; @@ -209,6 +204,8 @@ void I_DetectOS(void) osname, info.dwMajorVersion, info.dwMinorVersion, info.dwBuildNumber, info.szCSDVersion); + + sys_ostype = osname; } //========================================================================== diff --git a/src/d_anonstats.cpp b/src/d_anonstats.cpp index 5c15d8cf0..fe42633cf 100644 --- a/src/d_anonstats.cpp +++ b/src/d_anonstats.cpp @@ -1,4 +1,4 @@ -#define NO_SEND_STATS +//#define NO_SEND_STATS #ifdef NO_SEND_STATS void D_DoAnonStats() @@ -16,10 +16,11 @@ void D_ConfirmSendStats() #define WIN32_LEAN_AND_MEAN #include #include -extern int sys_ostype; +extern const char* sys_ostype; #else #ifdef __APPLE__ #include +extern FString sys_ostype; #else // !__APPLE__ #include #endif // __APPLE__ @@ -168,48 +169,28 @@ bool I_HTTPRequest(const char* request) } #endif -static int GetOSVersion() +static FString GetOSVersion() { #ifdef _WIN32 #ifndef _M_ARM64 - if (sizeof(void*) == 4) // 32 bit - { - BOOL res; - if (IsWow64Process(GetCurrentProcess(), &res) && res) - { - return 1; - } - return 0; - } - else - { - if (sys_ostype == 2) return 2; - else return 3; - } + return FStringf("Windows %s", sys_ostype); #else - return 4; + return FStringf("Windows %s ARM", sys_ostype); #endif #elif defined __APPLE__ #if defined(__aarch64__) - return 6; + return sys_ostype + " ARM"; #else - return 5; + return sys_ostype + " x64"; #endif #else // fall-through linux stuff here #ifdef __arm__ - return 9; + return sys_ostype + " ARM"; #else - if (sizeof(void*) == 4) // 32 bit - { - return 7; - } - else - { - return 8; - } + return sys_ostype; #endif From 7f9df1243102bee41a3831b034615b29ae0d56c1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 20 Sep 2023 20:03:07 +0200 Subject: [PATCH 151/223] - Survey: return more meaningful info for current OS and Vulkan version. --- src/common/rendering/vulkan/system/vk_renderdevice.cpp | 2 ++ src/d_anonstats.cpp | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/common/rendering/vulkan/system/vk_renderdevice.cpp b/src/common/rendering/vulkan/system/vk_renderdevice.cpp index ecc9a5ffe..91686de6a 100644 --- a/src/common/rendering/vulkan/system/vk_renderdevice.cpp +++ b/src/common/rendering/vulkan/system/vk_renderdevice.cpp @@ -76,6 +76,7 @@ CVAR(Bool, vk_raytrace, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // Physical device info static std::vector SupportedDevices; +int vkversion; CUSTOM_CVAR(Bool, vk_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { @@ -513,6 +514,7 @@ void VulkanRenderDevice::PrintStartupLog() FString apiVersion, driverVersion; apiVersion.Format("%d.%d.%d", VK_VERSION_MAJOR(props.apiVersion), VK_VERSION_MINOR(props.apiVersion), VK_VERSION_PATCH(props.apiVersion)); driverVersion.Format("%d.%d.%d", VK_VERSION_MAJOR(props.driverVersion), VK_VERSION_MINOR(props.driverVersion), VK_VERSION_PATCH(props.driverVersion)); + vkversion = VK_API_VERSION_MAJOR(props.apiVersion) * 100 + VK_API_VERSION_MINOR(props.apiVersion); Printf("Vulkan device: " TEXTCOLOR_ORANGE "%s\n", props.deviceName); Printf("Vulkan device type: %s\n", deviceType.GetChars()); diff --git a/src/d_anonstats.cpp b/src/d_anonstats.cpp index fe42633cf..440f54d4e 100644 --- a/src/d_anonstats.cpp +++ b/src/d_anonstats.cpp @@ -48,6 +48,7 @@ CVAR(Int, anonstats_port, 80, CVAR_NOSET) CVAR(Int, sentstats_hwr_done, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) std::pair gl_getInfo(); +extern int vkversion; @@ -243,7 +244,7 @@ static int GetCoreInfo() static int GetRenderInfo() { - if (screen->Backend() == 0) return 1; + if (screen->Backend() == 2) return 1; if (screen->Backend() == 1) return 4; auto info = gl_getInfo(); if (!info.second) @@ -255,7 +256,7 @@ static int GetRenderInfo() static int GetGLVersion() { - if (screen->Backend() == 1) return 50; + if (screen->Backend() == 1) return vkversion; auto info = gl_getInfo(); return int(info.first * 10); } From 5870ec2e7ad0f1887a923834ac4090e1185c72da Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 20 Sep 2023 23:58:01 +0200 Subject: [PATCH 152/223] - fix missing prototype in Linux --- src/d_anonstats.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_anonstats.cpp b/src/d_anonstats.cpp index 440f54d4e..edd3ded7c 100644 --- a/src/d_anonstats.cpp +++ b/src/d_anonstats.cpp @@ -18,9 +18,9 @@ void D_ConfirmSendStats() #include extern const char* sys_ostype; #else +extern FString sys_ostype; #ifdef __APPLE__ #include -extern FString sys_ostype; #else // !__APPLE__ #include #endif // __APPLE__ From ffcfec66b398f8af97744801d1d8d25368639c61 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Thu, 21 Sep 2023 01:57:21 +0200 Subject: [PATCH 153/223] Store kills/items/secrets in save comment only if visible on HUD This prevents spoiling levels when the HUD information is disabled. This change is not retroactive: it has no effect on existing savegames. You need to save again for this change to have an effect. --- src/g_game.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 5a4a51eec..3339a072d 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2275,6 +2275,9 @@ static void PutSaveWads (FSerializer &arc) } } +EXTERN_CVAR(Bool, hud_showmonsters) +EXTERN_CVAR(Bool, hud_showitems) +EXTERN_CVAR(Bool, hud_showsecrets) static void PutSaveComment (FSerializer &arc) { int levelTime; @@ -2291,8 +2294,30 @@ static void PutSaveComment (FSerializer &arc) levelTime = primaryLevel->time / TICRATE; comment.AppendFormat("%s: %02d:%02d:%02d\n", time, levelTime/3600, (levelTime%3600)/60, levelTime%60); - // Append kills/items/secrets - comment.AppendFormat("K: %d/%d - I: %d/%d - S: %d/%d\n", primaryLevel->killed_monsters, primaryLevel->total_monsters, primaryLevel->found_items, primaryLevel->total_items, primaryLevel->found_secrets, primaryLevel->total_secrets); + // Append kills/items/secrets (only if visible on HUD to avoid spoiling levels) + bool hasStatOnLine = false; + if (hud_showmonsters) { + comment.AppendFormat("K: %d/%d", primaryLevel->killed_monsters, primaryLevel->total_monsters); + hasStatOnLine = true; + } + if (hud_showitems) { + if (hasStatOnLine) { + comment.AppendFormat(" - "); + } + comment.AppendFormat("I: %d/%d", primaryLevel->found_items, primaryLevel->total_items); + hasStatOnLine = true; + } + if (hud_showsecrets) { + if (hasStatOnLine) { + comment.AppendFormat(" - "); + } + comment.AppendFormat("S: %d/%d", primaryLevel->found_secrets, primaryLevel->total_secrets); + hasStatOnLine = true; + } + + if (hasStatOnLine) { + comment.AppendFormat("\n"); + } // Append player health and armor const char* const health = "Health";// GStrings("SAVECOMMENT_HEALTH"); From 00e0a9fd76ca3b03b72731e23ab2371e86b379da Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Wed, 20 Sep 2023 23:58:30 -0400 Subject: [PATCH 154/223] - address GCC error in d_anonstats.cpp --- src/d_anonstats.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/d_anonstats.cpp b/src/d_anonstats.cpp index edd3ded7c..00bf78d8b 100644 --- a/src/d_anonstats.cpp +++ b/src/d_anonstats.cpp @@ -71,6 +71,12 @@ FString URLencode(const char *s) return out; } +// accept FString inputs too +FString URLencode(FString s) +{ + return URLencode(s.GetChars()); +} + #ifdef _WIN32 bool I_HTTPRequest(const char* request) @@ -285,8 +291,8 @@ void D_DoAnonStats() static char requeststring[1024]; - mysnprintf(requeststring, sizeof requeststring, "GET /stats_202309.py?render=%i&cores=%i&os=%i&glversion=%i&vendor=%s&model=%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\nUser-Agent: %s %s\r\n\r\n", - GetRenderInfo(), GetCoreInfo(), GetOSVersion(), GetGLVersion(), URLencode(screen->vendorstring).GetChars(), URLencode(screen->DeviceName()).GetChars(), *anonstats_host, GAMENAME, VERSIONSTR); + mysnprintf(requeststring, sizeof requeststring, "GET /stats_202309.py?render=%i&cores=%i&os=%s&glversion=%i&vendor=%s&model=%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\nUser-Agent: %s %s\r\n\r\n", + GetRenderInfo(), GetCoreInfo(), URLencode(GetOSVersion()).GetChars(), GetGLVersion(), URLencode(screen->vendorstring).GetChars(), URLencode(screen->DeviceName()).GetChars(), *anonstats_host, GAMENAME, VERSIONSTR); DPrintf(DMSG_NOTIFY, "Sending %s", requeststring); #if 1//ndef _DEBUG // Don't send info in debug builds From 955b8bae1a16a6114815ffead1235a5f39ba37ac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 21 Sep 2023 19:26:56 +0200 Subject: [PATCH 155/223] Revert "Add more information in saved game comments" This reverts commit 56c2bd018d9b32ac7abf855f70aefd8c3189673f. Considering the follow-up I think it's best to scrap this. --- src/g_game.cpp | 45 +-------------------------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 3339a072d..f68fca225 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2275,9 +2275,6 @@ static void PutSaveWads (FSerializer &arc) } } -EXTERN_CVAR(Bool, hud_showmonsters) -EXTERN_CVAR(Bool, hud_showitems) -EXTERN_CVAR(Bool, hud_showsecrets) static void PutSaveComment (FSerializer &arc) { int levelTime; @@ -2292,47 +2289,7 @@ static void PutSaveComment (FSerializer &arc) // Append elapsed time const char *const time = GStrings("SAVECOMMENT_TIME"); levelTime = primaryLevel->time / TICRATE; - comment.AppendFormat("%s: %02d:%02d:%02d\n", time, levelTime/3600, (levelTime%3600)/60, levelTime%60); - - // Append kills/items/secrets (only if visible on HUD to avoid spoiling levels) - bool hasStatOnLine = false; - if (hud_showmonsters) { - comment.AppendFormat("K: %d/%d", primaryLevel->killed_monsters, primaryLevel->total_monsters); - hasStatOnLine = true; - } - if (hud_showitems) { - if (hasStatOnLine) { - comment.AppendFormat(" - "); - } - comment.AppendFormat("I: %d/%d", primaryLevel->found_items, primaryLevel->total_items); - hasStatOnLine = true; - } - if (hud_showsecrets) { - if (hasStatOnLine) { - comment.AppendFormat(" - "); - } - comment.AppendFormat("S: %d/%d", primaryLevel->found_secrets, primaryLevel->total_secrets); - hasStatOnLine = true; - } - - if (hasStatOnLine) { - comment.AppendFormat("\n"); - } - - // Append player health and armor - const char* const health = "Health";// GStrings("SAVECOMMENT_HEALTH"); - const char* const armor = "Armor"; // GStrings("SAVECOMMENT_ARMOR"); - int armorAmount = 0; - auto basicArmorItem = primaryLevel->Players[consoleplayer]->mo->FindInventory(NAME_BasicArmor); - if (basicArmorItem) { - armorAmount += basicArmorItem->IntVar(NAME_Amount); - } - auto hexenArmorItem = primaryLevel->Players[consoleplayer]->mo->FindInventory(NAME_HexenArmor); - if (hexenArmorItem) { - double *Slots = (double*)hexenArmorItem->ScriptVar(NAME_Slots, nullptr); - armorAmount += Slots[0] + Slots[1] + Slots[2] + Slots[3] + Slots[4]; - } - comment.AppendFormat("%s: %d - %s: %d", health, primaryLevel->Players[consoleplayer]->mo->health, armor, armorAmount); + comment.AppendFormat("%s: %02d:%02d:%02d", time, levelTime/3600, (levelTime%3600)/60, levelTime%60); // Write out the comment arc.AddString("Comment", comment); From 74913618639aceb1f38e3a3e0995a96ab0cc2066 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Sep 2023 22:20:50 +0200 Subject: [PATCH 156/223] - do some cleansing of the GPU string and add CPU name when only getting an anonymous series name. The cleansing is mainly for AMD's Linux drivers which report too much extraneous info here. The CPU name helps when classifying anonymous iGPU series. --- src/common/utility/x86.cpp | 2 +- src/common/utility/x86.h | 2 +- src/d_anonstats.cpp | 48 +++++++++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/common/utility/x86.cpp b/src/common/utility/x86.cpp index 76e880834..78d74fff9 100644 --- a/src/common/utility/x86.cpp +++ b/src/common/utility/x86.cpp @@ -161,7 +161,7 @@ void CheckCPUID(CPUInfo *cpu) } } -FString DumpCPUInfo(const CPUInfo *cpu) +FString DumpCPUInfo(const CPUInfo *cpu, bool brief) { char cpustring[4*4*3+1]; diff --git a/src/common/utility/x86.h b/src/common/utility/x86.h index 25e698d81..8a009efa0 100644 --- a/src/common/utility/x86.h +++ b/src/common/utility/x86.h @@ -229,7 +229,7 @@ struct CPUInfo // 92 bytes extern CPUInfo CPU; void CheckCPUID (CPUInfo *cpu); -FString DumpCPUInfo (const CPUInfo *cpu); +FString DumpCPUInfo (const CPUInfo *cpu, bool brief = false); #endif diff --git a/src/d_anonstats.cpp b/src/d_anonstats.cpp index 00bf78d8b..1c3a240b6 100644 --- a/src/d_anonstats.cpp +++ b/src/d_anonstats.cpp @@ -275,6 +275,52 @@ static void D_DoHTTPRequest(const char *request) } } + +static FString GetDeviceName() +{ + FString device = screen->DeviceName(); + if (device.Compare("AMD Radeon(TM) Graphics") == 0 || + device.Compare("Intel(R) UHD Graphics") == 0 || + //device.Compare("Intel(R) HD Graphics") == 0 || these are not that interesting so leave them alone + device.Compare("Intel(R) Iris(R) Plus Graphics") == 0 || + device.Compare("Intel(R) Iris(R) Xe Graphics") == 0 || + device.Compare("Radeon RX Vega") == 0 || + device.Compare("AMD Radeon Series") == 0) + { + // for these anonymous series names add the CPU name to get an idea what GPU we really have + auto ci = DumpCPUInfo(&CPU, true); + device.AppendFormat(" * %s", ci.GetChars()); + } + // cleanse the GPU info string to allow better searches on the database. + device.Substitute("/SSE2", ""); + device.Substitute("/PCIe", ""); + device.Substitute("/PCI", ""); + device.Substitute("(TM) ", ""); + device.Substitute("Mesa ", ""); + device.Substitute("DRI ", ""); + auto pos = device.IndexOf("Intel(R)"); + if (pos >= 0) + { + device.Substitute("(R) ", ""); + auto pos = device.IndexOf("("); + if (pos >= 0) device.Truncate(pos); + } + + auto pos = device.IndexOf("(LLVM"); + if (pos >= 0) device.Truncate(pos); + pos = device.IndexOf("(DRM"); + if (pos >= 0) device.Truncate(pos); + pos = device.IndexOf("(RADV"); + if (pos >= 0) device.Truncate(pos); + pos = device.IndexOf(", LLVM"); + if (pos >= 0) + { + device.Truncate(pos); + device << ')'; + } + device.StripLeftRight(); + return device; +} void D_DoAnonStats() { #ifndef _DEBUG @@ -292,7 +338,7 @@ void D_DoAnonStats() static char requeststring[1024]; mysnprintf(requeststring, sizeof requeststring, "GET /stats_202309.py?render=%i&cores=%i&os=%s&glversion=%i&vendor=%s&model=%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\nUser-Agent: %s %s\r\n\r\n", - GetRenderInfo(), GetCoreInfo(), URLencode(GetOSVersion()).GetChars(), GetGLVersion(), URLencode(screen->vendorstring).GetChars(), URLencode(screen->DeviceName()).GetChars(), *anonstats_host, GAMENAME, VERSIONSTR); + GetRenderInfo(), GetCoreInfo(), URLencode(GetOSVersion()).GetChars(), GetGLVersion(), URLencode(screen->vendorstring).GetChars(), URLencode(GetDeviceName()).GetChars(), *anonstats_host, GAMENAME, VERSIONSTR); DPrintf(DMSG_NOTIFY, "Sending %s", requeststring); #if 1//ndef _DEBUG // Don't send info in debug builds From 30c49fb769f1b85b47724fa48f86789ccf7c9d3c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Sep 2023 23:02:57 +0200 Subject: [PATCH 157/223] - language update --- wadsrc/static/language.0 | 1245 ++--- wadsrc/static/language.csv | 3328 ++++++------- wadsrc/static/lmacros.csv | 13 +- .../static/filter/chex.chex3/language.csv | 190 +- .../filter/hacx.hacx1/after_iwad/language.csv | 368 +- .../static/filter/harmony/language.csv | 135 +- wadsrc_extra/static/language.csv | 4099 +++++++++-------- 7 files changed, 4998 insertions(+), 4380 deletions(-) diff --git a/wadsrc/static/language.0 b/wadsrc/static/language.0 index 549283172..441abb7ba 100644 --- a/wadsrc/static/language.0 +++ b/wadsrc/static/language.0 @@ -1,9 +1,9 @@ -default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,ja jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,tr,uk,bg -,,Miscellaneous,,,,,,,,,,,,,,,,,,,,,,,,,, +default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,ja jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,sv,tr,uk,bg +,,Miscellaneous,,,,,,,,,,,,,,,,,,,,,,,,,,, Press Y or N.,PRESSYN,,,,Stiskni Y nebo N.,Tryk på Y eller N.,Drücke Y oder N.,"Πάτα Y ή N -",Premu Y aŭ N.,Presiona Y o N.,,Paina Y tai N.,Appuyez sur Y ou N.,Nyomj Y-t vagy N-t.,Premi Y oppure N.,YかNで答えろ,Y키 또는 N키를 누르시오.,Druk op Y of N.,Trykk på Y eller N.,Wciśnij Y lub N.,Aperte Y ou N.,Carrega Y ou N.,Apasă Y sau N.,Нажмите Y или N.,Притисните Y или N.,Y veya N tuşuna basın.,Натисніть Y або N.,Натисни Y или N. -Yes,TXT_YES,,,,Ano,Ja,Ja,Ναι,Jes,Sí,,Kyllä,Oui,Igen,Si,はい,네,Ja,Ja,Tak,Sim,,Da,Да,Да,Evet,Так,Да -No,TXT_NO,,,,Ne,Nej,Nein,Όχι,Ne,No,,Ei,Non,Nem,No,いいえ,아니요,Nee,Nei,Nie,Não,,Nu,Нет,Не,Hayır,Ні,Не +",Premu Y aŭ N.,Presiona Y o N.,,Paina Y tai N.,Appuyez sur Y ou N.,Nyomj Y-t vagy N-t.,Premi Y oppure N.,YかNで答えろ,Y키 또는 N키를 누르시오.,Druk op Y of N.,Trykk på Y eller N.,Wciśnij Y lub N.,Aperte Y ou N.,Carrega Y ou N.,Apasă Y sau N.,Нажмите Y или N.,Притисните Y или N.,Tryck på Y eller N.,Y veya N tuşuna basın.,Натисніть Y або N.,Натисни Y или N. +Yes,TXT_YES,,,,Ano,Ja,Ja,Ναι,Jes,Sí,,Kyllä,Oui,Igen,Si,はい,네,Ja,Ja,Tak,Sim,,Da,Да,Да,Ja,Evet,Так,Да +No,TXT_NO,,,,Ne,Nej,Nein,Όχι,Ne,,,Ei,Non,Nem,,いいえ,아니요,Nee,Nei,Nie,Não,,Nu,Нет,Не,Nej,Hayır,Ні,Не "You can't save if you aren't playing! Press a key.",SAVEDEAD,,,,"Mimo hru nelze ukládat! @@ -46,15 +46,15 @@ Apasă o tastă.","Невозможно сохранить игру, не нач Нажмите любую клавишу.","Не можете сачувати игру ако не играте! -Притисните тастер.","Eğer oynamıyorsanız kaydedemezsiniz! +Притисните тастер.",Du kan inte spara om du inte spelar! Tryck på en tangent.,"Eğer oynamıyorsanız kaydedemezsiniz! Bir tuşa bas.","Ви не можете зберегти гру, не почавши її! Натисніть будь яку клавішу.","Не може да запазите играта, ако не играете! Натиснете клавиш." -Do you really want to do this?,SAFEMESSAGE,,,,Vážně to chceš udělat?,Vil du virkelig gøre dette?,Möchtest du das wirklich tun?,,Ĉu vi vere volas fari ĉi tion?,¿Realmente quieres hacer esto?,¿Realmente quieres hacerlo?,Haluatko varmasti tehdä tämän?,Voulez-vous vraiment faire ça?,Biztos ezt akarod tenni?,Sei sicuro di volerlo fare?,本当に実行するのか?,정말로 정하시겠습니까?,Wil je dit echt doen?,Vil du virkelig gjøre dette?,Naprawdę chcesz to zrobić?,Você deseja mesmo fazer isso?,Desejas mesmo fazer isso?,Ești sigur că vrei să faci asta?,Вы уверены?,Да ли заиста желите то да урадите?,Bunu gerçekten yapmak istiyor musun?,Ви дійсно хочете цього?,Наистина ли искаш да направиш това? -Not set,NOTSET,,,,Není nastavené,Ikke indstillet,Nicht gesetzt,,Ne agordita,No asignado,,Ei asetettu,Pas paramétré,Nincs beállítva,Non assegnato,セットされてない,정하지 않음,Niet ingesteld,Ikke innstilt,Nie ustawiono,Não definido,,Nesetat,Не задан,Није намештено,Ayarlanmamış,Не встановлено,Не е зададено +Do you really want to do this?,SAFEMESSAGE,,,,Vážně to chceš udělat?,Vil du virkelig gøre dette?,Möchtest du das wirklich tun?,Θέλετε πραγματικά να το κάνετε αυτό;,Ĉu vi vere volas fari ĉi tion?,¿Realmente quieres hacer esto?,¿Realmente quieres hacerlo?,Haluatko varmasti tehdä tämän?,Voulez-vous vraiment faire ça?,Biztos ezt akarod tenni?,Sei sicuro di volerlo fare?,本当に実行するのか?,정말로 정하시겠습니까?,Wil je dit echt doen?,Vil du virkelig gjøre dette?,Naprawdę chcesz to zrobić?,Você deseja mesmo fazer isso?,Desejas mesmo fazer isso?,Ești sigur că vrei să faci asta?,Вы уверены?,Да ли заиста желите то да урадите?,Vill du verkligen göra det här?,Bunu gerçekten yapmak istiyor musun?,Ви дійсно хочете цього?,Наистина ли искаш да направиш това? +Not set,NOTSET,,,,Není nastavené,Ikke indstillet,Nicht gesetzt,Δεν έχει οριστεί,Ne agordita,No asignado,,Ei asetettu,Pas paramétré,Nincs beállítva,Non assegnato,セットされてない,정하지 않음,Niet ingesteld,Ikke innstilt,Nie ustawiono,Não definido,,Nesetat,Не задан,Није намештено,Inte inställd,Ayarlanmamış,Не встановлено,Не е зададено "Quicksave over your game named '%s'? @@ -69,7 +69,9 @@ Stiskni Y nebo N.","Quicksave over dit spil navngivet Tryk på Y eller N.","Überschreibe %s mit einem Schnellspeicherspielstand? -Drücke Y oder N.",,"Ĉu rapidkonservi anstataŭigante vian ludadon nomitan +Drücke Y oder N.","Γρήγορη αποθήκευση πάνω από το παιχνίδι σας με το όνομα '%s'; + +Πατήστε Y ή N.","Ĉu rapidkonservi anstataŭigante vian ludadon nomitan '%s'? @@ -129,7 +131,8 @@ Apasă Y sau N.","Перезаписать быстрое сохранение „%s“? -Притисните Y или N.","%s' +Притисните Y или N.","Snabbspara över ditt spel som heter %s? +Tryck på Y eller N.","%s' adlı oyununuzun üzerine hızlı kaydetme? @@ -156,7 +159,9 @@ Stiskni Y nebo N.","Ønsker du at quickloade spillet ved navn Tryk på Y eller N.","Möchtest du den Spielstand %s schnellladen? -Drücke Y oder N.",,"Ĉu vi volas rapidŝargi la ludadon nomitan +Drücke Y oder N.","Θέλετε να κάνετε γρήγορη φόρτωση του παιχνιδιού με το όνομα '%s'; + +Πατήστε Y ή N.","Ĉu vi volas rapidŝargi la ludadon nomitan '%s'? @@ -216,7 +221,8 @@ Apasă Y sau N.","Загрузить быстрое сохранение „%s“? -Притисните Y или N.","%s' +Притисните Y или N.","Vill du snabbladda spelet som heter ""%s""? +Tryck på Y eller N.","%s' adlı oyunu hızlı yüklemek istiyor musunuz? @@ -229,620 +235,627 @@ Y veya N tuşuna basın.","Завантажити швидке збережен '%s'? Натисни Y или N." -%s cheats,TXT_X_CHEATS,This is a gender sensitive message where %s represents the player,,,%s podvádí,%s snyder,%s schummelt,@[art_gr] %s απατάει,%s trompas,%s hace trampas,%s hace trampa,%s huijaa,%s triche.,%s csal,%s imbroglia,%s はチート使用,%s 이(가) 치트를 사용 함,%s bedriegt,%s jukser,%s oszukuje,%s está trapaceando,%s está a fazer batota,%s trișează,%s использует чит-коды,%s вара,%s hileleri,%s чітерить,%s измамен код -Messages: OFF,MSGOFF,,,,Oznámení ZAP.,Meddelelser: FRA,Meldungen AUS,Μηνύματα ΚΛΕΙΣΤΑ,Mesaĝoj: MALŜALTITA,Mensajes DESACTIVADOS,,Viestit POIS PÄÄLTÄ,Messages désactivés.,Üzenetek: KI,Messaggi DISATTIVATI,メッセージ: オフ,메시지 끔,Berichten UIT,Meldinger: AV,Wiadomości WYŁĄCZONE,Mensagens DESATIVADAS,,Mesaje OPRITE,Сообщения ОТКЛЮЧЕНЫ,Поруке ИСКЉУЧЕНЕ,Mesajlar: KAPALI,Повідомлення: ВІДКЛЮЧЕНІ,Съобщения: Изкл -Messages: ON,MSGON,,,,Oznámení VYP.,Meddelelser: TIL,Meldungen AN,Μηνύματα ΑΝΟΙΧΤΑ,Mesaĝoj: ŜALTITA,Mensajes ACTIVADOS,,Viestit PÄÄLLÄ,Messages activés.,Üzenetek: BE,Messaggi ATTIVATI,メッセージ: オン,메시지 켬,Berichten AAN,Meldinger: PÅ,Wiadomości WŁĄCZONE,Mensagens ATIVADAS,,Mesaje PORNITE,Сообщения ВКЛЮЧЕНЫ,Поруке УКЉУЧЕНЕ,Mesajlar: AÇIK,Повідомлення: ВКЛЮЧЕНІ,Съобщения: Вкл -Say:,TXT_SAY,,,,Říct:,Sig:,Sage:,Πές:,Diri:,,,Sano:,Parler:,Üzenet:,Parla:,発言:,,Zeg:,Si:,Powiedz:,Dizer:,Diz:,Vorbește:,Чат:,Пиши:,Söyle:,Чат:,Пиши: -Press any key or click anywhere in the window to quit.,TXT_QUITENDOOM,,,,"Pro ukončení stiskni libovolnou klávesu, nebo klikni kdekoliv v okně.",Tryk på en vilkårlig tast eller klik et vilkårligt sted i vinduet for at afslutte.,Drücke eine Taste oder klicke mit der Maus ins Fenster zum Beenden.,Πάτα οποιοδήποτε πλήκτρο ή πάτα οπουδήποτε για να κάνεις έξοδο,Premu ajnan klavon aŭ alklaku ie ajn en la fenestro por forlasi.,Presiona una tecla o haz clic en cualquier lugar de la ventana para salir.,Presiona una tecla o cliquea en cualquier lugar de la ventana para salir.,Paina mitä tahansa näppäintä tai napsauta minne tahansa ikkunaa lopettaaksesi.,Appuyez sur une touche ou cliquez pour quitter.,Nyomjon egy gombot vagy kattintson valahova a kilépéshez.,Premi un qualunque tasto o fai un click ovunque nella finestra per uscire.,何かのキーを押すか、ウィンドウのどこかをクリックすると終了する。,아무 키를 누르거나 아무 곳이나 클릭하면 종료됩니다.,Druk op een willekeurige toets of klik ergens in het venster om te stoppen.,Trykk på en hvilken som helst tast eller klikk hvor som helst i vinduet for å avslutte.,Wciśnij dowolny klawisz lub gdziekolwiek kliknij myszką aby wyjść.,Aperte uma tecla ou clique em qualquer lugar na janela para sair.,Carrega numa tecla ou clique em qualquer lugar na janela para sair.,Apasă orice tastă sau apasă click oriunde în fereastră pentru a ieși.,"Нажмите любую клавишу или нажмите по окну, чтобы выйти.",Притисните било који тастер или кликните било где на екрану да одустанете.,Çıkmak için herhangi bir tuşa basın veya pencerede herhangi bir yere tıklayın.,"Натисніть будь яку клавішу чи натисніть по вікну, щоб вийти.","Натиснете който и да е клавиш или щракнете където и да е в прозореца, за да излезете." -,,Savegame,,,,,,,,,,,,,,,,,,,,,,,,,, -,NEWSAVE,,,,,,,,,,,,,<Új mentés>,,<新規セーブ>,<새로운 게임 저장>,,,,,,,<Новое сохранение>,<Нова сачувана игра>,,<Нове збереження>,<Нов запис на играта> -Game saved.,GGSAVED,,,,Hra uložena.,Spillet er gemt.,Spielstand gespeichert.,Παχνίδι αποθηκέυτηκε.,Ludado konservita.,Partida guardada.,,Peli tallennettu.,Partie sauvegardée.,Játék mentve.,Partita salvata.,セーブ完了。,게임이 저장됨.,Spel opgeslagen.,Spillet er lagret.,Gra zapisana.,Jogo salvo.,Jogo gravado.,Joc salvat.,Игра сохранена.,Игра сачувана.,Oyun kaydedildi.,Гру збережено.,Играта е записана +%s cheats,TXT_X_CHEATS,This is a gender sensitive message where %s represents the player,,,%s podvádí,%s snyder,%s schummelt,@[art_gr] %s απατάει,%s trompas,%s hace trampas,%s hace trampa,%s huijaa,%s triche.,%s csal,%s imbroglia,%s はチート使用,%s 이(가) 치트를 사용 함,%s bedriegt,%s jukser,%s oszukuje,%s está trapaceando,%s está a fazer batota,%s trișează,%s использует чит-коды,%s вара,%s fuskar,%s hileleri,%s чітерить,%s измамен код +Messages: OFF,MSGOFF,,,,Oznámení ZAP.,Meddelelser: FRA,Meldungen AUS,Μηνύματα ΚΛΕΙΣΤΑ,Mesaĝoj: MALŜALTITA,Mensajes DESACTIVADOS,,Viestit POIS PÄÄLTÄ,Messages désactivés.,Üzenetek: KI,Messaggi DISATTIVATI,メッセージ: オフ,메시지 끔,Berichten UIT,Meldinger: AV,Wiadomości WYŁĄCZONE,Mensagens DESATIVADAS,,Mesaje OPRITE,Сообщения ОТКЛЮЧЕНЫ,Поруке ИСКЉУЧЕНЕ,Meddelanden: Av,Mesajlar: KAPALI,Повідомлення: ВІДКЛЮЧЕНІ,Съобщения: Изкл +Messages: ON,MSGON,,,,Oznámení VYP.,Meddelelser: TIL,Meldungen AN,Μηνύματα ΑΝΟΙΧΤΑ,Mesaĝoj: ŜALTITA,Mensajes ACTIVADOS,,Viestit PÄÄLLÄ,Messages activés.,Üzenetek: BE,Messaggi ATTIVATI,メッセージ: オン,메시지 켬,Berichten AAN,Meldinger: PÅ,Wiadomości WŁĄCZONE,Mensagens ATIVADAS,,Mesaje PORNITE,Сообщения ВКЛЮЧЕНЫ,Поруке УКЉУЧЕНЕ,Meddelanden: På,Mesajlar: AÇIK,Повідомлення: ВКЛЮЧЕНІ,Съобщения: Вкл +Say:,TXT_SAY,,,,Říct:,Sig:,Sage:,Πές:,Diri:,,,Sano:,Parler:,Üzenet:,Parla:,発言:,,Zeg:,Si:,Powiedz:,Dizer:,Diz:,Vorbește:,Чат:,Пиши:,Säg:,Söyle:,Чат:,Пиши: +Press any key or click anywhere in the window to quit.,TXT_QUITENDOOM,,,,"Pro ukončení stiskni libovolnou klávesu, nebo klikni kdekoliv v okně.",Tryk på en vilkårlig tast eller klik et vilkårligt sted i vinduet for at afslutte.,Drücke eine Taste oder klicke mit der Maus ins Fenster zum Beenden.,Πάτα οποιοδήποτε πλήκτρο ή πάτα οπουδήποτε για να κάνεις έξοδο,Premu ajnan klavon aŭ alklaku ie ajn en la fenestro por forlasi.,Presiona una tecla o haz clic en cualquier lugar de la ventana para salir.,Presiona una tecla o cliquea en cualquier lugar de la ventana para salir.,Paina mitä tahansa näppäintä tai napsauta minne tahansa ikkunaa lopettaaksesi.,Appuyez sur une touche ou cliquez pour quitter.,Nyomjon egy gombot vagy kattintson valahova a kilépéshez.,Premi un qualunque tasto o fai un click ovunque nella finestra per uscire.,何かのキーを押すか、ウィンドウのどこかをクリックすると終了する。,아무 키를 누르거나 아무 곳이나 클릭하면 종료됩니다.,Druk op een willekeurige toets of klik ergens in het venster om te stoppen.,Trykk på en hvilken som helst tast eller klikk hvor som helst i vinduet for å avslutte.,Wciśnij dowolny klawisz lub gdziekolwiek kliknij myszką aby wyjść.,Aperte uma tecla ou clique em qualquer lugar na janela para sair.,Carrega numa tecla ou clique em qualquer lugar na janela para sair.,Apasă orice tastă sau apasă click oriunde în fereastră pentru a ieși.,"Нажмите любую клавишу или нажмите по окну, чтобы выйти.",Притисните било који тастер или кликните било где на екрану да одустанете.,Tryck på någon tangent eller klicka någonstans i fönstret för att avsluta.,Çıkmak için herhangi bir tuşa basın veya pencerede herhangi bir yere tıklayın.,"Натисніть будь яку клавішу чи натисніть по вікну, щоб вийти.","Натиснете който и да е клавиш или щракнете където и да е в прозореца, за да излезете." +,,Savegame,,,,,,,,,,,,,,,,,,,,,,,,,,, +,NEWSAVE,,,,,,,<Νέο παιχνίδι αποθήκευσης>,,,,,,<Új mentés>,,<新規セーブ>,<새로운 게임 저장>,,,,,,,<Новое сохранение>,<Нова сачувана игра>,,,<Нове збереження>,<Нов запис на играта> +Game saved.,GGSAVED,,,,Hra uložena.,Spillet er gemt.,Spielstand gespeichert.,Παχνίδι αποθηκέυτηκε.,Ludado konservita.,Partida guardada.,,Peli tallennettu.,Partie sauvegardée.,Játék mentve.,Partita salvata.,セーブ完了。,게임이 저장됨.,Spel opgeslagen.,Spillet er lagret.,Gra zapisana.,Jogo salvo.,Jogo gravado.,Joc salvat.,Игра сохранена.,Игра сачувана.,Spelet är sparat.,Oyun kaydedildi.,Гру збережено.,Играта е записана Time,SAVECOMMENT_TIME,,,,Čas,Tid,Zeit,Χρόνος,Tempo,Tiempo,,Aika,Temps,Idő,Tempo,"時間 -",시간,Tijd,Tid,Czas,Tempo,,Timp,Время,Време,Zaman,Час,Време -Load Game,MNU_LOADGAME,,,,Načíst hru,Indlæs spil,Spiel laden,Φώρτωσε παιχνίδι,Ŝargi ludadon,Cargar cartida,,Lataa peli,Chargement,Játék betöltése,Carica partita,ロード,게임 불러오기,Laden spel,Last inn spill,Wczytaj Grę,Carregar jogo,,Încărcare Joc,Загрузка,Учитај игру,Oyun Yükle,Завантажити,Зареди игра -Save Game,MNU_SAVEGAME,,,,Uložit hru,Gem spil,Spiel sichern,Αποθήκευσε παιχνίδι,Konservi ludadon,Guardar partida,,Tallenna peli,Sauvegarde,Játék mentése,Salva partita,セーブ,게임 저장하기,Opslaan spel,Lagre spill,Zapisz Grę,Salvar jogo,Gravar,Salvare Joc,Сохранение,Сачувај игру,Oyunu Kaydet,Зберегти,Запази игра +",시간,Tijd,Tid,Czas,Tempo,,Timp,Время,Време,Tid,Zaman,Час,Време +Load Game,MNU_LOADGAME,,,,Načíst hru,Indlæs spil,Spiel laden,Φώρτωσε παιχνίδι,Ŝargi ludadon,Cargar cartida,,Lataa peli,Chargement,Játék betöltése,Carica partita,ロード,게임 불러오기,Laden spel,Last inn spill,Wczytaj Grę,Carregar jogo,,Încărcare Joc,Загрузка,Учитај игру,Ladda spelet,Oyun Yükle,Завантажити,Зареди игра +Save Game,MNU_SAVEGAME,,,,Uložit hru,Gem spil,Spiel sichern,Αποθήκευσε παιχνίδι,Konservi ludadon,Guardar partida,,Tallenna peli,Sauvegarde,Játék mentése,Salva partita,セーブ,게임 저장하기,Opslaan spel,Lagre spill,Zapisz Grę,Salvar jogo,Gravar,Salvare Joc,Сохранение,Сачувај игру,Spara spelet,Oyunu Kaydet,Зберегти,Запази игра No Picture,MNU_NOPICTURE,,,,Bez obrázku,Intet billede,Kein Bild,Καμία εικόνα,Neniu bildo,Sin imagen,,Ei kuvaa,Pas d'image,Nincs kép,Nessuna immagine,画像無し,사진 없음,Geen beeld,Ingen bilde,Brak obrazka,Sem imagem,,Lipsă Imagine,"Нет -изображения",Нема слике,Resim yok,Немає зображення,Без изображение +изображения",Нема слике,Ingen bild,Resim yok,Немає зображення,Без изображение Different Version,MNU_DIFFVERSION,,,,Jiná verze,Anderledes version,Falsche Version,Διαφορετική έκδοση,Malsama versio,Versión diferente,,Eri versio,Version Différente,Eltérő verzió,Versione differente,"別バージョンの -データ",다른 버젼,Anders Versie,Annen versjon,Inna Wersja,Versão diferente,,Versiune Diferită,Другая версия,Другачија верзија,Farklı Versiyon,Інша версія,Различна версия -No files,MNU_NOFILES,,,,Žádné soubory,Ingen filer,Keine Dateien,Καθ΄λου αρχεία ,Neniu dosiero,Sin archivos,,Ei tiedostoja,Pas de fichiers,Nincsenek fájlok,Nessun file,ファイル無し,파일 없음,Geen bestanden,Ingen filer,Brak plików,Vazio,,Niciun fișier,Нет файлов,Нема фајлова,Dosya yok,Немає файлів,Няма файлове +データ",다른 버젼,Anders Versie,Annen versjon,Inna Wersja,Versão diferente,,Versiune Diferită,Другая версия,Другачија верзија,Annan version,Farklı Versiyon,Інша версія,Различна версия +No files,MNU_NOFILES,,,,Žádné soubory,Ingen filer,Keine Dateien,Καθ΄λου αρχεία ,Neniu dosiero,Sin archivos,,Ei tiedostoja,Pas de fichiers,Nincsenek fájlok,Nessun file,ファイル無し,파일 없음,Geen bestanden,Ingen filer,Brak plików,Vazio,,Niciun fișier,Нет файлов,Нема фајлова,Inga filer,Dosya yok,Немає файлів,Няма файлове "Do you really want to delete the savegame? ",MNU_DELETESG,,,,Opravdu smazat tuto uloženou hru?,Ønsker du virkelig at slette det gemte spil?,Willst du diesen Spielstand wirklich löschen?,Θέλεις όντος να διαγράξεις το αποθηκευμένο παιχνίδι;,Ĉu vi vere volas forigi la konservitan ludadon?,"¿Realmente deseas borrar la partida? ",,Haluatko varmasti poistaa tallennetun pelin ,"Voulez vous vraiment effacer cette sauvegarde? -",Biztosan törlöd a mentést?,Vuoi veramente cancellare il salvataggio?,本当にこのセーブを消すのか?,저장된 게임을 정말로 삭제하시겠습니까?,Wil je echt de opgeslagen spel verwijderen?,Vil du virkelig slette lagringsspillet?,Czy naprawdę chcesz usunąć zapis gry?,Deseja mesmo excluir o jogo salvo?,Deseja mesmo apagar o jogo,Vrei să ștergi salvarea?,Вы действительно хотите удалить сохранение?,Да ли стварно желите да избришете сачувану игру,"Gerçekten kayıt oyununu silmek istiyor musunuz? +",Biztosan törlöd a mentést?,Vuoi veramente cancellare il salvataggio?,本当にこのセーブを消すのか?,저장된 게임을 정말로 삭제하시겠습니까?,Wil je echt de opgeslagen spel verwijderen?,Vil du virkelig slette lagringsspillet?,Czy naprawdę chcesz usunąć zapis gry?,Deseja mesmo excluir o jogo salvo?,Deseja mesmo apagar o jogo,Vrei să ștergi salvarea?,Вы действительно хотите удалить сохранение?,Да ли стварно желите да избришете сачувану игру,Vill du verkligen radera sparfilen?,"Gerçekten kayıt oyununu silmek istiyor musunuz? ",Ви дійсно хочете видалити це збереження?,Найстина ли искаш да изтриеш запазената игра -,,General,,,,,,,,,,,,,,,,,,,,,,,,,, -Off,OPTVAL_OFF,,,,Vyp.,Fra,Aus,,Malŝaltita,Desactivado,,Pois,,Ki,Disattivo,オフ,끔,Uit,Av,Wyłączone,Não,,Pornit,Откл.,Искљ.,Kapalı,Вимк.,Изкл. -On,OPTVAL_ON,,,,Zap.,Til,An,,Ŝaltita,Activado,,Päällä,,Be,Attivo,オン,켬,Aan,På,Włączone,Sim,,Oprit,Вкл.,Укљ.,Açık,Увім.,Вкл. -Auto,OPTVAL_AUTO,,,,,Automatisk,,,Aŭtomata,Automático,,Automaattinen,,Automatikus,Automatico,自動,자동,,Auto,Automatycznie,Automático,,,Авто,Аутоматски,Otomatik,Авто,Автоматично -Options,OPTMNU_TITLE,,,,Možnosti,Indstillinger,Optionen,Ρυθμίσεις,Agordoj,Opciones,,Asetukset,Options,Beállítások,Opzioni,オプション,설정,Opties,Alternativer,Opcje,Opções,,Opțiuni,Настройки,Подешавања,Seçenekler,Налаштування,Настройки -Customize Controls,OPTMNU_CONTROLS,,,,Ovládání,Tilpas kontrolelementer,Steuerung einstellen,,Adapti regilojn,Personalizar controles,,Ohjausasetukset,Modifier les Contrôles,Irányítás testreszabása,Personalizza i controlli,キー配置変更,조작 사용자 지정,Instellen van de controle,Tilpass kontroller,Ustaw Klawisze,Personalizar comandos,Configurar Controlos,Personalizare Setări Control,Управление,Контроле,Kontrolleri Özelleştir,Керування,Управление -Mouse Options,OPTMNU_MOUSE,,,,Myš,Indstillinger for mus,Mauseinstellungen,Ρυθμίσεις ποντικίου,Muso-agordoj,Opciones de ratón,,Hiiriasetukset,Options de la Souris,Egér beállítások,Opzioni Mouse,マウス オプション,마우스 설정,Muis opties,Alternativer for mus,Opcje Myszki,Opções de mouse,Opções do rato,Setări Mouse,Мышь,Миш,Fare Seçenekleri,Миш,Мишка -Controller Options,OPTMNU_JOYSTICK,,,,Ovladač,Indstillinger for controller,Joystickeinstellungen,,Ludregilo-agordoj,Opciones de mando,,Peliohjainasetukset,Options de la Manette,Játékvezérlő beállítások,Opzioni Joystick,コントローラーオプション,조이스틱 설정,Controller opties,Kontrollalternativer,Opcje Kontrolera,Opções de controle,,Setări Controller,Контроллер,Контролер,Kontrolör Seçenekleri,Контролер,Контролер -Player Setup,OPTMNU_PLAYER,,,,Hráč,Spilleropsætning,Spieler einrichten,Ρυθμίσεις παίχτη,Ludanto-agordaĵo,Config. del jugador,,Pelaaja-asetukset,Options du Joueur,Játékos testreszabása,Settaggio giocatore,プレイヤーの特徴,플레이어 설정,Speler instellen,Spilleroppsett,Ustawienia Gracza,Configurações de jogador,Configurações do Jogador,Personalizare Jucător,Игрок,Играч,Oyuncu Kurulumu,Гравець,Играч -Gameplay Options,OPTMNU_GAMEPLAY,,,,Herní mechaniky,Indstillinger for gameplay,Spieleinstellungen,,Ludado-agordoj,Opciones de jugabilidad,,Pelattavuusasetukset,Options du Gameplay,Játékmenet beállítások,Opzioni Gameplay,ゲームプレイ オプション,게임 설정,Gameplay-opties,Spillalternativer,Opcje Rozgrywki,Opções de jogabilidade,,Setări pe timp de joc,Игра,Гејмплеј,Oynanış Seçenekleri,Гра,Игра -Automap Options,OPTMNU_AUTOMAP,,,,Automapa,Automap-indstillinger,Automapeinstellungen,,Aŭtomapo-agordoj,Opciones del automapa,,Automaattikartan asetukset,Options de la Carte,Térkép beállítások,Opzioni Automappa,オートマップ オプション,오토맵 설정,Automap-opties,Automap-alternativer,Opcje Mapy,Opções de automapa,,Hartă computerizată,Автокарта,Аутомапа,Otomatik Harita Seçenekleri,Автокарта,Автокарта -HUD Options,OPTMNU_HUD,,,,Rozhraní a HUD,HUD-indstillinger,HUD Einstellungen,Ρυθμίσεις HUD,Agordoj de HUD,Opciones del HUD,,Tilanäytön asetukset,Options de l'ATH,HUD beállítások,Opzioni HUD,HUD オプション,HUD 설정,HUD opties,HUD-alternativer,Opcje HUD,Opções de HUD,,Setări HUD,Интерфейс,HUD,HUD Seçenekleri,Ігровий інтерфейс,Интерфейс -Miscellaneous Options,OPTMNU_MISCELLANEOUS,,,,Ostatní,Diverse indstillinger,Verschiedene Einstellungen,Διάφορες ρυθμίσεις,Diversaĵaj agordoj,Opciones misceláneas,,Sekalaiset asetukset,Options Annexes,Egyéb beállítások,Opzioni Miste,その他のオプション,그 외 설정,Diverse opties,Diverse alternativer,Różne Opcje,Outras opções,,Setări diverse,Дополнительно,Разно,Çeşitli Seçenekler,Різне,Други настройки -Sound Options,OPTMNU_SOUND,,,,Zvuk,Lydindstillinger,Soundeinstellungen,Ρυθμίσεις ήχου,Sono-agordoj,Opciones de sonido,,Ääniasetukset,Options du Son,Hang beállítások,Opzioni Suono,サウンド オプション,음향 설정,Geluidsopties,Lydalternativer,Opcje Dźwięku,Opções de som,,Setări sunet,Звук,Звук,Ses Seçenekleri,Звук,Звука -Display Options,OPTMNU_DISPLAY,,,,Grafika,Visningsindstillinger,Anzeigeeinstellungen,,Ekrano-agordoj,Opciones de visualización,,Näyttöasetukset,Options de l'Affichage,Megjelenítés beállítások,Opzioni Display,ディスプレイ オプション,디스플레이 설정,Weergaveopties,Visningsalternativer,Opcje Wyświetlania,Opções de vídeo,,Setări afișare,Экран,Приказ,Görüntüleme Seçenekleri,Екран,Екрана -Set video mode,OPTMNU_VIDEO,,,,Obrazový výstup,Indstil videomodus,Videomodus,Άλλαξε λειτουργία βίντεο,Agordi videoreĝimon,Modos de vídeo,Modos de video,Aseta videotila,Choisir Mode D'Affichage,Videó beállítások,Settaggio modalità video,ビデオ 調整,화면 설정,Videomodus instellen,Angi videomodus,Ustaw tryb wideo,Definir modo de vídeo,,Setare mod video,Видеорежим,Видео мод,Video modunu ayarlama,Відеорежим,Видеорежим -Reset to defaults,OPTMNU_DEFAULTS,,,,Obnovit původní,Nulstil til standardindstillingerne,Auf Vorgaben zurücksetzen,Επαναφορά σε προεπιλεγμένες ρυθμίσεις,Restarigi al defaŭltoj,Valores por defecto,,Palauta oletusasetukset,Réinitialiser les paramètres,Alapértelmezett beállítások használata,Reimposta ai valori di default,初期設定に戻す,초기화,Terugzetten naar standaardinstellingen,Tilbakestill til standardinnstillinger,Resetuj do domyślnych,Redefinir para configurações padrão,,Revenire la setări implicite,Сбросить все настройки,Врати подразумевано,Varsayılanlara sıfırla,Скинути налаштування,Нулирай до стандартни -Reset to last saved,OPTMNU_RESETTOSAVED,,,,Obnovit naposledy uložené,Nulstil til sidst gemte,Auf gespeicherte Werte zurücksetzen,,Restarigi al lasta konservita,Últimos valores guardados,,Palauta viimeksi tallennettu tila,Recharger dernière config.,Legutóbbi mentett beállítások használata,Reimposta ai valori salvati l'ultima volta,最後に保存した設定に戻す,이전 설정으로 초기화,Reset naar laatste opgeslagen,Tilbakestill til sist lagret,Resetuj do ostatnio zapisanych,Redefinir para a última configuração salva,Redefinir para última configuração gravada,Revenire la ultimele setări salvate,Возврат к сохранённым настройкам,Врати задње сачувано,Son kaydedilene sıfırla,Відновити останні збережені налаштування,Нулирай до последно запазената игра -Save current settings,OPTMNU_WRITEINI,,,,Uložit současná nastavení,Gem de aktuelle indstillinger,Aktuelle Einstellungen speichern,Αποθήκευσε της τορινές ρυθμίσεις,Konservi nunajn reĝimojn,Guardar los ajustes de ahora,,Tallenna nykyiset asetukset,,Jelenlegi beállítások mentése,Salva le impostazioni correnti,現在の設定を保存,현재 설정 적용,Huidige instellingen opslaan ,Lagre gjeldende innstillinger,Zapisz aktualne opcje,Salvar configurações atuais,,Salvează setările curente,Сохранить текущие настройки,,Geçerli ayarları kaydet,Зберегти поточні налаштування,Запази сегашните настройки -Go to console,OPTMNU_CONSOLE,,,,Otevřít konzoli,Gå til konsol,Öffne Konsole,Μπές στη κονσόλα,Iri al konzolo,Ir a la consola,,Mene konsoliin,Ouvrir la console,Konzol megnyitása,Vai alla console,コンソールを開く,콘솔로 이동,Ga naar de console,Gå til konsoll,Przejdź do konsoli,Abrir console,Abrir consola,Mergi la consolă,Открыть консоль,Отвори конзолу,Konsola git,Відкрити консоль,Отвори конзолата -Network Options,OPTMNU_NETWORK,,,,Síť,Netværksindstillinger,Netzwerkeinstellungen,Ρυθμίσεις Δικτύου,Reto-agordoj,Opciones de red,,Verkkoasetukset,Options Réseau,Hálózati beállítások,Opzioni Network,ネットワーク オプション,네트워크 설정,Netwerkopties,Nettverksalternativer,Opcje Sieciowe,Opções de rede,,Setări de Rețea,Сеть,Мрежа,Ağ Seçenekleri,Мережа,Мрежа -Reverb environment editor,OPTMNU_REVERB,,,,Editor zvukové ozvěny,Reverb editor,Hall-Editor,Επεξεργαστής περιβαλλόντων απόσβεσης,Redaktoro pri resonmedio,Editor de amb. de reverberación,,Kaikutilaeditori,Editeur environement de révérb.,Visszhangkörnyezet-szerkesztő,Editor ambiente reverb,リバーブ環境エディタ,울림 환경 편집기,Reverb-omgeving editor,Reverb-miljøredigering,Edytor pogłosu środowiska,Editor de ambiente de reverberação,,Setări Reverb,Редактор реверберации,Уредник одјека у околини,Reverb ortam düzenleyicisi,Редактор ревербації,Редактор на среда за реверберация -,,Customize controls,,,,,,,,,,,,,,,,,,,,,,,,,, -"ENTER to change, BACKSPACE to clear",CNTRLMNU_SWITCHTEXT1,,,,"ENTER pro změnu, BACKSPACE pro smazání","ENTER for at ændre, BACKSPACE for at slette",ENTER: Editieren BACKSPACE: Löschen,,"ENTER por ŝanĝi, BACKSPACE por forigi","ENTER para cambiar, RETROCESO para borrar","ENTER para cambiar, BACKSPACE para borrar","Aseta ENTERILLÄ, tyhjennä ASKELPALAUTTIMELLA","ENTREE pour changer, RET. ARRIERE pour effacer.","ENTER a változtatáshoz, BACKSPACE a törléshez","INVIO per modificare, BACKSPACE per ripulire",Enter で決定、BackSpaceで無効化,"바꿀려면 ENTER키, 지울려면 BACKSPACE키를 누르시오","ENTER om te veranderen, BACKSPACE om te wissen.","ENTER for å endre, BACKSPACE for å slette","ENTER by zmienić, BACKSPACE by wyczyścić",Aperte ENTER para alterar e BACKSPACE para remover,,"ENTER pentru a schimba, BACKSPACE pentru ștergere","ENTER — изменить, BACKSPACE — очистить","ENTER за промену, BACKSPACE за чишћење","Değiştirmek için ENTER, silmek için BACKSPACE","ENTER — змінити, BACKSPACE — очистити","ENTER — промяна, BACKSPACE — изчистване" -"Press new key for control, ESC to cancel",CNTRLMNU_SWITCHTEXT2,,,,"Zmáčkni novou klávesu, nebo ESC pro storno","Tryk på ny tast for kontrol, ESC for at annullere",Drücke eine Taste oder ESC um abzubrechen,,"Premu novan klavon por regilo, ESC por nuligi","Presiona una tecla para el control, ESC para cancelar",,"Valitse näppäin toiminnolle, ESC peruuttaa","Appuyez sur la nouvelle touche pour l'assigner, -Appuyez sur ECHAP pour annuler.","Nyomj meg egy gombot, ESC a törléshez","Premi un nuovo tasto per il controllo, ESC per cancellare","登録したいキーを押すか, Escでキャンセル","명령을 얽으려면 아무 키를, 취소는 ESC키를 누르시오","Druk op de nieuwe toets voor controle, ESC om te annuleren.","Trykk på ny tast for kontroll, ESC for å avbryte","Wciśnij nowy przycisk by zmienić klawisz, ESC by anulować",Aperte uma nova tecla para o comando e ESC para cancelar,"Carrega a nova tecla para o comando, ESC para cancelar","Apasă tasta nouă, sau ESC pentru anulare","Нажмите новую клавишу, ESC для отмены","Притисните ново тастер за одређивање контроле, ESC за отказивање","Kontrol için yeni tuşa, iptal etmek için ESC'ye basın","Натисніть на клавішу для її призначення, ESC для скасування","Натисни нов клавиш за управление, ESC за отмяна" -Controls,CNTRLMNU_CONTROLS,,,,Ovládání,Kontrolelementer,Steuerung,,Regiloj,Controles,,Ohjaimet,Contrôles,Irányítás,Controlli,操作系統,조작,Bedieningselementen,Kontroller,Klawisze,Comandos,Controlos,Control,Управление,Контроле,Kontroller,Керування,Управление -Fire,CNTRLMNU_ATTACK,,,,Střelba,Ild,Feuer,Πυροβόλα,Pafi,Fuego,,Tuli,Tirer,Tűz,Fuoco,撃つ,공격,Vuur,Brann,Strzał,Atirar,,Foc,Атака,Нападни,Yangın,Атака,Атака -Secondary Fire,CNTRLMNU_ALTATTACK,,,,Sekundární střelba,Sekundær ild,Alternativfeuer,,Pafi duarange,Fuego secundario,,Vaihtoehtoistuli,Tir Secondaire,Másodlagos tüzelés,Fuoco secondario,セカンダリ,보조 공격,Secundaire vuur,Sekundær ild,Strzał Alternatywny,Tiro secundário,,Foc Secundar,Дополнительная атака,Секундарни напад,İkincil Yangın,Додаткова атака,Допълнителна атака -Weapon Reload,CNTRLMNU_RELOAD,,,,Přebít zbraň,Våben Genopladning,Waffe nachladen,Επαναφόρτωση Όπλου,Reŝargi armilon,Recargar Arma,,Aseen lataus,Recharger Arme,Fegyver újratöltése,Ricarica dell'arma,リロード,무기 장전,Wapenherladen,Våpen Reload,Przeładowanie Broni,Recarregar arma,,Încărcare Armă,Перезарядка,Напуни,Silah Yeniden Doldurma,Перезарядка,Презареди -Use / Open,CNTRLMNU_USE,,,,Použít/otevřít,Brug / Åbn,Benutzen / Öffnen,,Uzi/Malfermi,Usar/Abrir,,Käytä / Avaa,Utiliser/Ouvrir,Akciógomb/Nyitás,Usa/Apri,開く / スイッチ等使用,사용/열기,Gebruik / Openen,Bruk / Åpne,Użyj / Otwórz,Usar / Abrir,,Folosește / Deschide,Использовать/открыть,Користи / Отвори,Kullan / Aç,Відкрити / Використати,Използвай / Отвори -Move forward,CNTRLMNU_FORWARD,,,,Vpřed,Flyt fremad,Vorwärts bewegen,,Movi anatŭen,Avanzar,,Liiku eteenpäin,Avancer,Előre mozgás,Movimento in avanti,前進,앞으로 이동,Voorwaarts bewegen,Gå fremover,Idź do przodu,Mover-se para frente,,Deplasare în față,Движение вперёд,Крећи се напред,İlerleyin,Рухатись вперед,Движение напред -Move backward,CNTRLMNU_BACK,,,,Vzad,Bevæge sig bagud,Rückwarts bewegen,,Movi malantaŭen,Retroceder,,Liiku taaksepäin,Reculer,Hátra mozgás,Movimento in indietro,後退,뒤로 이동,Achteruit bewegen,Gå bakover,Idź do tyłu,Mover-se para trás,,Deplasare în spate,Движение назад,Крећи се уназад,Geriye doğru hareket et,Рухатись назад,Движение назад -Strafe left,CNTRLMNU_MOVELEFT,,,,Úkrok vlevo,Flyt til venstre,Nach links bewegen,,Flankmovi maldekstren,Moverse a la izquierda,,Astu sivuun vasemmalle,Aller à Gauche,Balra oldalazás,Movimento laterale a sinistra,左移動,왼쪽으로 이동,Verplaats naar links,Strafe venstre,Unik w lewo,Mover-se para a esquerda,,Deplasare diagonală stânga,Движение влево,Крећи се лево,Strafe sola,Рухатись вліво,Движение в ляво -Strafe right,CNTRLMNU_MOVERIGHT,,,,Úkrok vpravo,Flyt til højre,Nach rechts bewegen,,Flankmovi dekstren,Moverse a la derecha,,Astu sivuun oikealle,Aller à Droite,Jobbra oldalazás,Movimento laterale a destra,右移動,오른쪽으로 이동,Verplaats naar rechts,Strafe til høyre,Unik w prawo,Mover-se para a direita,,Deplasare diagonală dreapta,Движение вправо,Крећи се десно,Strafe sağa,Рухатись вправо,Движение в дясно +,,General,,,,,,,,,,,,,,,,,,,,,,,,,,, +Off,OPTVAL_OFF,,,,Vyp.,Fra,Aus,ενεργοποιημένη,Malŝaltita,Desactivado,,Pois,,Ki,Disattivo,オフ,끔,Uit,Av,Wyłączone,Não,,Pornit,Откл.,Искљ.,Av,Kapalı,Вимк.,Изкл. +On,OPTVAL_ON,,,,Zap.,Til,An,άπενεργοποιημένη,Ŝaltita,Activado,,Päällä,,Be,Attivo,オン,켬,Aan,På,Włączone,Sim,,Oprit,Вкл.,Укљ.,På,Açık,Увім.,Вкл. +Auto,OPTVAL_AUTO,,,,,Automatisk,,Αυτό,Aŭtomata,Automático,,Automaattinen,,Automatikus,Automatico,自動,자동,,,Automatycznie,Automático,,,Авто,Аутоматски,Automatiskt,Otomatik,Авто,Автоматично +Options,OPTMNU_TITLE,,,,Možnosti,Indstillinger,Optionen,Ρυθμίσεις,Agordoj,Opciones,,Asetukset,,Beállítások,Opzioni,オプション,설정,Opties,Alternativer,Opcje,Opções,,Opțiuni,Настройки,Подешавања,Alternativ,Seçenekler,Налаштування,Настройки +Customize Controls,OPTMNU_CONTROLS,,,,Ovládání,Tilpas kontrolelementer,Steuerung einstellen,Προσαρμογή χειριστηρίων,Adapti regilojn,Personalizar controles,,Ohjausasetukset,Modifier les Contrôles,Irányítás testreszabása,Personalizza i controlli,キー配置変更,조작 사용자 지정,Instellen van de controle,Tilpass kontroller,Ustaw Klawisze,Personalizar comandos,Configurar Controlos,Personalizare Setări Control,Управление,Контроле,Anpassa kontrollerna,Kontrolleri Özelleştir,Керування,Управление +Mouse Options,OPTMNU_MOUSE,,,,Myš,Indstillinger for mus,Mauseinstellungen,Ρυθμίσεις ποντικίου,Muso-agordoj,Opciones de ratón,,Hiiriasetukset,Options de la Souris,Egér beállítások,Opzioni Mouse,マウス オプション,마우스 설정,Muis opties,Alternativer for mus,Opcje Myszki,Opções de mouse,Opções do rato,Setări Mouse,Мышь,Миш,Alternativ för musen,Fare Seçenekleri,Миш,Мишка +Controller Options,OPTMNU_JOYSTICK,,,,Ovladač,Indstillinger for controller,Joystickeinstellungen,Επιλογές ελεγκτή,Ludregilo-agordoj,Opciones de mando,,Peliohjainasetukset,Options de la Manette,Játékvezérlő beállítások,Opzioni Joystick,コントローラーオプション,조이스틱 설정,Controller opties,Kontrollalternativer,Opcje Kontrolera,Opções de controle,,Setări Controller,Контроллер,Контролер,Alternativ för styrenhet,Kontrolör Seçenekleri,Контролер,Контролер +Player Setup,OPTMNU_PLAYER,,,,Hráč,Spilleropsætning,Spieler einrichten,Ρυθμίσεις παίχτη,Ludanto-agordaĵo,Config. del jugador,,Pelaaja-asetukset,Options du Joueur,Játékos testreszabása,Settaggio giocatore,プレイヤーの特徴,플레이어 설정,Speler instellen,Spilleroppsett,Ustawienia Gracza,Configurações de jogador,Configurações do Jogador,Personalizare Jucător,Игрок,Играч,Inställning av spelare,Oyuncu Kurulumu,Гравець,Играч +Gameplay Options,OPTMNU_GAMEPLAY,,,,Herní mechaniky,Indstillinger for gameplay,Spieleinstellungen,Επιλογές παιχνιδιού,Ludado-agordoj,Opciones de jugabilidad,,Pelattavuusasetukset,Options du Gameplay,Játékmenet beállítások,Opzioni Gameplay,ゲームプレイ オプション,게임 설정,Gameplay-opties,Spillalternativer,Opcje Rozgrywki,Opções de jogabilidade,,Setări pe timp de joc,Игра,Гејмплеј,Spelalternativ,Oynanış Seçenekleri,Гра,Игра +Automap Options,OPTMNU_AUTOMAP,,,,Automapa,Automap-indstillinger,Automapeinstellungen,Επιλογές Automap,Agordoj de la aŭtomata mapo,Opciones del automapa,,Automaattikartan asetukset,Options de la Carte,Térkép beállítások,Opzioni Automappa,オートマップ オプション,오토맵 설정,Automap-opties,Automap-alternativer,Opcje Mapy,Opções de automapa,,Hartă computerizată,Автокарта,Аутомапа,Automap-alternativ,Otomatik Harita Seçenekleri,Автокарта,Автокарта +HUD Options,OPTMNU_HUD,,,,Rozhraní a HUD,HUD-indstillinger,HUD Einstellungen,Ρυθμίσεις HUD,Agordoj de HUD,Opciones del HUD,,Tilanäytön asetukset,Options de l'ATH,HUD beállítások,Opzioni HUD,HUD オプション,HUD 설정,HUD opties,HUD-alternativer,Opcje HUD,Opções de HUD,,Setări HUD,Интерфейс,,HUD-alternativ,HUD Seçenekleri,Ігровий інтерфейс,Интерфейс +Miscellaneous Options,OPTMNU_MISCELLANEOUS,,,,Ostatní,Diverse indstillinger,Verschiedene Einstellungen,Διάφορες ρυθμίσεις,Diversaĵaj agordoj,Opciones misceláneas,,Sekalaiset asetukset,Options Annexes,Egyéb beállítások,Opzioni Miste,その他のオプション,그 외 설정,Diverse opties,Diverse alternativer,Różne Opcje,Outras opções,,Setări diverse,Дополнительно,Разно,Diverse alternativ,Çeşitli Seçenekler,Різне,Други настройки +Sound Options,OPTMNU_SOUND,,,,Zvuk,Lydindstillinger,Soundeinstellungen,Ρυθμίσεις ήχου,Sono-agordoj,Opciones de sonido,,Ääniasetukset,Options du Son,Hang beállítások,Opzioni Suono,サウンド オプション,음향 설정,Geluidsopties,Lydalternativer,Opcje Dźwięku,Opções de som,,Setări sunet,Звук,Звук,Ljudalternativ,Ses Seçenekleri,Звук,Звука +Display Options,OPTMNU_DISPLAY,,,,Grafika,Visningsindstillinger,Anzeigeeinstellungen,Επιλογές οθόνης,Ekrano-agordoj,Opciones de visualización,,Näyttöasetukset,Options de l'Affichage,Megjelenítés beállítások,Opzioni Display,ディスプレイ オプション,디스플레이 설정,Weergaveopties,Visningsalternativer,Opcje Wyświetlania,Opções de vídeo,,Setări afișare,Экран,Приказ,Visningsalternativ,Görüntüleme Seçenekleri,Екран,Екрана +Set video mode,OPTMNU_VIDEO,,,,Obrazový výstup,Indstil videomodus,Videomodus,Άλλαξε λειτουργία βίντεο,Agordi videoreĝimon,Modos de vídeo,Modos de video,Aseta videotila,Choisir Mode D'Affichage,Videó beállítások,Settaggio modalità video,ビデオ 調整,화면 설정,Videomodus instellen,Angi videomodus,Ustaw tryb wideo,Definir modo de vídeo,,Setare mod video,Видеорежим,Видео мод,Ställ in videoläge,Video modunu ayarlama,Відеорежим,Видеорежим +Reset to defaults,OPTMNU_DEFAULTS,,,,Obnovit původní,Nulstil til standardindstillingerne,Auf Vorgaben zurücksetzen,Επαναφορά σε προεπιλεγμένες ρυθμίσεις,Restarigi al defaŭltoj,Valores por defecto,,Palauta oletusasetukset,Réinitialiser les paramètres,Alapértelmezett beállítások használata,Reimposta ai valori di default,初期設定に戻す,초기화,Terugzetten naar standaardinstellingen,Tilbakestill til standardinnstillinger,Resetuj do domyślnych,Redefinir para configurações padrão,,Revenire la setări implicite,Сбросить все настройки,Врати подразумевано,Återställ till standardvärden,Varsayılanlara sıfırla,Скинути налаштування,Нулирай до стандартни +Reset to last saved,OPTMNU_RESETTOSAVED,,,,Obnovit naposledy uložené,Nulstil til sidst gemte,Auf gespeicherte Werte zurücksetzen,Επαναφορά στην τελευταία αποθήκευση,Restarigi al lasta konservita,Últimos valores guardados,,Palauta viimeksi tallennettu tila,Recharger dernière config.,Legutóbbi mentett beállítások használata,Reimposta ai valori salvati l'ultima volta,最後に保存した設定に戻す,이전 설정으로 초기화,Reset naar laatste opgeslagen,Tilbakestill til sist lagret,Resetuj do ostatnio zapisanych,Redefinir para a última configuração salva,Redefinir para última configuração gravada,Revenire la ultimele setări salvate,Возврат к сохранённым настройкам,Врати задње сачувано,Återställ till senast sparade,Son kaydedilene sıfırla,Відновити останні збережені налаштування,Нулирай до последно запазената игра +Save current settings,OPTMNU_WRITEINI,,,,Uložit současná nastavení,Gem de aktuelle indstillinger,Aktuelle Einstellungen speichern,Αποθήκευσε της τορινές ρυθμίσεις,Konservi nunajn reĝimojn,Guardar los ajustes de ahora,,Tallenna nykyiset asetukset,Sauvegarde des Paramètres Actuels,Jelenlegi beállítások mentése,Salva le impostazioni correnti,現在の設定を保存,현재 설정 적용,Huidige instellingen opslaan ,Lagre gjeldende innstillinger,Zapisz aktualne opcje,Salvar configurações atuais,,Salvează setările curente,Сохранить текущие настройки,,Spara aktuella inställningar,Geçerli ayarları kaydet,Зберегти поточні налаштування,Запази сегашните настройки +Go to console,OPTMNU_CONSOLE,,,,Otevřít konzoli,Gå til konsol,Öffne Konsole,Μπές στη κονσόλα,Iri al konzolo,Ir a la consola,,Mene konsoliin,Ouvrir la console,Konzol megnyitása,Vai alla console,コンソールを開く,콘솔로 이동,Ga naar de console,Gå til konsoll,Przejdź do konsoli,Abrir console,Abrir consola,Mergi la consolă,Открыть консоль,Отвори конзолу,Gå till konsolen,Konsola git,Відкрити консоль,Отвори конзолата +Network Options,OPTMNU_NETWORK,,,,Síť,Netværksindstillinger,Netzwerkeinstellungen,Ρυθμίσεις Δικτύου,Reto-agordoj,Opciones de red,,Verkkoasetukset,Options Réseau,Hálózati beállítások,Opzioni Network,ネットワーク オプション,네트워크 설정,Netwerkopties,Nettverksalternativer,Opcje Sieciowe,Opções de rede,,Setări de Rețea,Сеть,Мрежа,Nätverksalternativ,Ağ Seçenekleri,Мережа,Мрежа +Reverb environment editor,OPTMNU_REVERB,,,,Editor zvukové ozvěny,Reverb editor,Hall-Editor,Επεξεργαστής περιβαλλόντων απόσβεσης,Redaktoro pri resonmedio,Editor de amb. de reverberación,,Kaikutilaeditori,Editeur environement de révérb.,Visszhangkörnyezet-szerkesztő,Editor ambiente reverb,リバーブ環境エディタ,울림 환경 편집기,Reverb-omgeving editor,Reverb-miljøredigering,Edytor pogłosu środowiska,Editor de ambiente de reverberação,,Setări Reverb,Редактор реверберации,Уредник одјека у околини,Redigerare för reverbmiljö,Reverb ortam düzenleyicisi,Редактор ревербації,Редактор на среда за реверберация +,,Customize controls,,,,,,,,,,,,,,,,,,,,,,,,,,, +"ENTER to change, BACKSPACE to clear",CNTRLMNU_SWITCHTEXT1,,,,"ENTER pro změnu, BACKSPACE pro smazání","ENTER for at ændre, BACKSPACE for at slette",ENTER: Editieren BACKSPACE: Löschen,"ENTER για αλλαγή, BACKSPACE για διαγραφή","ENTER por ŝanĝi, BACKSPACE por forigi","ENTER para cambiar, RETROCESO para borrar","ENTER para cambiar, BACKSPACE para borrar","Aseta ENTERILLÄ, tyhjennä ASKELPALAUTTIMELLA","ENTREE pour changer, RET. ARRIERE pour effacer.","ENTER a változtatáshoz, BACKSPACE a törléshez","INVIO per modificare, BACKSPACE per ripulire",Enter で決定、BackSpaceで無効化,"바꿀려면 ENTER키, 지울려면 BACKSPACE키를 누르시오","ENTER om te veranderen, BACKSPACE om te wissen.","ENTER for å endre, BACKSPACE for å slette","ENTER by zmienić, BACKSPACE by wyczyścić",Aperte ENTER para alterar e BACKSPACE para remover,,"ENTER pentru a schimba, BACKSPACE pentru ștergere","ENTER — изменить, BACKSPACE — очистить","ENTER за промену, BACKSPACE за чишћење","ENTER för att ändra, BACKSPACE för att radera","Değiştirmek için ENTER, silmek için BACKSPACE","ENTER — змінити, BACKSPACE — очистити","ENTER — промяна, BACKSPACE — изчистване" +"Press new key for control, ESC to cancel",CNTRLMNU_SWITCHTEXT2,,,,"Zmáčkni novou klávesu, nebo ESC pro storno","Tryk på ny tast for kontrol, ESC for at annullere",Drücke eine Taste oder ESC um abzubrechen,"Πατήστε το νέο πλήκτρο για έλεγχο, ESC για ακύρωση","Premu novan klavon por regilo, ESC por nuligi","Presiona una tecla para el control, ESC para cancelar",,"Valitse näppäin toiminnolle, ESC peruuttaa","Appuyez sur la nouvelle touche pour l'assigner, +Appuyez sur ECHAP pour annuler.","Nyomj meg egy gombot, ESC a törléshez","Premi un nuovo tasto per il controllo, ESC per cancellare","登録したいキーを押すか, Escでキャンセル","명령을 얽으려면 아무 키를, 취소는 ESC키를 누르시오","Druk op de nieuwe toets voor controle, ESC om te annuleren.","Trykk på ny tast for kontroll, ESC for å avbryte","Wciśnij nowy przycisk by zmienić klawisz, ESC by anulować",Aperte uma nova tecla para o comando e ESC para cancelar,"Carrega a nova tecla para o comando, ESC para cancelar","Apasă tasta nouă, sau ESC pentru anulare","Нажмите новую клавишу, ESC для отмены","Притисните ново тастер за одређивање контроле, ESC за отказивање","Tryck på ny tangent för kontroll, ESC för att avbryta","Kontrol için yeni tuşa, iptal etmek için ESC'ye basın","Натисніть на клавішу для її призначення, ESC для скасування","Натисни нов клавиш за управление, ESC за отмяна" +Controls,CNTRLMNU_CONTROLS,,,,Ovládání,Kontrolelementer,Steuerung,Έλεγχοι,Regiloj,Controles,,Ohjaimet,Contrôles,Irányítás,Controlli,操作系統,조작,Bedieningselementen,Kontroller,Klawisze,Comandos,Controlos,Control,Управление,Контроле,Kontroller,Kontroller,Керування,Управление +Fire,CNTRLMNU_ATTACK,,,,Střelba,Ild,Feuer,Πυροβόλα,Pafi,Fuego,,Tuli,Tirer,Tűz,Fuoco,撃つ,공격,Vuur,Brann,Strzał,Atirar,,Foc,Атака,Нападни,Eld,Yangın,Атака,Атака +Secondary Fire,CNTRLMNU_ALTATTACK,,,,Sekundární střelba,Sekundær ild,Alternativfeuer,Δευτερεύουσα Πυροβόλα,Pafi duarange,Fuego secundario,,Vaihtoehtoistuli,Tir Secondaire,Másodlagos tüzelés,Fuoco secondario,セカンダリ,보조 공격,Secundaire vuur,Sekundær ild,Strzał Alternatywny,Tiro secundário,,Foc Secundar,Дополнительная атака,Секундарни напад,Sekundär eld,İkincil Yangın,Додаткова атака,Допълнителна атака +Weapon Reload,CNTRLMNU_RELOAD,,,,Přebít zbraň,Våben Genopladning,Waffe nachladen,Επαναφόρτωση Όπλου,Reŝargi armilon,Recargar Arma,,Aseen lataus,Recharger Arme,Fegyver újratöltése,Ricarica dell'arma,リロード,무기 장전,Wapenherladen,Våpen Reload,Przeładowanie Broni,Recarregar arma,,Încărcare Armă,Перезарядка,Напуни,Ladda om vapen,Silah Yeniden Doldurma,Перезарядка,Презареди +Use / Open,CNTRLMNU_USE,,,,Použít/otevřít,Brug / Åbn,Benutzen / Öffnen,Χρήση / Άνοιγμα,Uzi/Malfermi,Usar/Abrir,,Käytä / Avaa,Utiliser/Ouvrir,Akciógomb/Nyitás,Usa/Apri,開く / スイッチ等使用,사용/열기,Gebruik / Openen,Bruk / Åpne,Użyj / Otwórz,Usar / Abrir,,Folosește / Deschide,Использовать/открыть,Користи / Отвори,Användning/öppna,Kullan / Aç,Відкрити / Використати,Използвай / Отвори +Move forward,CNTRLMNU_FORWARD,,,,Vpřed,Flyt fremad,Vorwärts bewegen,Μετακίνηση προς τα εμπρός,Movi anatŭen,Avanzar,,Liiku eteenpäin,Avancer,Előre mozgás,Movimento in avanti,前進,앞으로 이동,Voorwaarts bewegen,Gå fremover,Idź do przodu,Mover-se para frente,,Deplasare în față,Движение вперёд,Крећи се напред,Flytta framåt,İlerleyin,Рухатись вперед,Движение напред +Move backward,CNTRLMNU_BACK,,,,Vzad,Bevæge sig bagud,Rückwarts bewegen,Μετακίνηση προς τα πίσω,Movi malantaŭen,Retroceder,,Liiku taaksepäin,Reculer,Hátra mozgás,Movimento in indietro,後退,뒤로 이동,Achteruit bewegen,Gå bakover,Idź do tyłu,Mover-se para trás,,Deplasare în spate,Движение назад,Крећи се уназад,Flytta bakåt,Geriye doğru hareket et,Рухатись назад,Движение назад +Strafe left,CNTRLMNU_MOVELEFT,,,,Úkrok vlevo,Flyt til venstre,Nach links bewegen,Μετακίνηση προς τα αριστερά,Flankmovi maldekstren,Moverse a la izquierda,,Astu sivuun vasemmalle,Aller à Gauche,Balra oldalazás,Movimento laterale a sinistra,左移動,왼쪽으로 이동,Verplaats naar links,Strafe venstre,Unik w lewo,Mover-se para a esquerda,,Deplasare diagonală stânga,Движение влево,Крећи се лево,Strafe till vänster,Strafe sola,Рухатись вліво,Движение в ляво +Strafe right,CNTRLMNU_MOVERIGHT,,,,Úkrok vpravo,Flyt til højre,Nach rechts bewegen,Μετακίνηση προς τα δεξιά,Flankmovi dekstren,Moverse a la derecha,,Astu sivuun oikealle,Aller à Droite,Jobbra oldalazás,Movimento laterale a destra,右移動,오른쪽으로 이동,Verplaats naar rechts,Strafe til høyre,Unik w prawo,Mover-se para a direita,,Deplasare diagonală dreapta,Движение вправо,Крећи се десно,Strafe till höger,Strafe sağa,Рухатись вправо,Движение в дясно Turn left,CNTRLMNU_TURNLEFT,,,,Otočení vlevo,Drej til venstre,Nach links drehen,Γύρνα αριστερά,Turni maldekstren,Girar a la izquierda,,Käänny vasemmalle,Tourner à Gauche,Balra fordul,"Gira a sinistra -",左を向く,왼쪽으로 회전,Draai naar links,Sving til venstre,Obróć się w lewo,Girar para a esquerda,,Întoarcere stânga,Поворот налево,Окрени се лево,Sola dön,Повернутись ліворуч,Обръщане в ляво -Turn right,CNTRLMNU_TURNRIGHT,,,,Otočení vpravo,Drej til højre,Nach rechts drehen,Γύρνα δεξιά,Turni dekstren,Girar a la derecha,,Käänny oikealle,Tourner à Droite,Jobbra fordul,Gira a destra,右を向く,오른쪽으로 회전,Draai naar rechts,Sving til høyre,Obróć się w prawo,Girar para a direita,,Întoarcere dreapta,Поворот направо,Окрени се десно,Sağa dön,Повернутись праворуч,Обръщане в дясно -Quick Turn,CNTRLMNU_TURN180,,,,Rychlé otočení,Hurtig drejning,Schnelle Drehung,Γρήγορη γύριση,Rapida turno,Giro rápido,,Pikakäännös,Faire un 180,Megfordulás,Rotazione rapida,背後を向く,빠른 회전,Snelle draai,Rask sving,Szybki Obrót,Giro rápido,,Întoarcere rapidă,Быстрый разворот,Брзи окрет,Hızlı Dönüş,Швидкий розворот,Бързо обръщане -Jump,CNTRLMNU_JUMP,,,,Skok,Hop,Springen,Πήδα,Salti,Saltar,,Hyppää,Sauter,Ugrás,Salto,ジャンプ,점프,Springen,Hopp,Skok,Pular,Saltar,Salt,Прыжок,Скок,Atlama,Стрибок,Скок -Crouch,CNTRLMNU_CROUCH,,,,Kleknutí,Kryb,Ducken,,Kaŭri,Agacharse,,Kyyristy,S'accroupir (tenir),Guggolás,Abbassarsi,屈む,숙이기,Hurken,Huk,Kucnięcie,Agachar,,Ghemuire,Присесть,Чучни,Çömelme,Присісти,Клякане -Crouch Toggle,CNTRLMNU_TOGGLECROUCH,,,,Přepnout kleknutí,Krybbe omskifter,Ducken an/aus,,Kaŭrobaskuli,Alternar agachado,,Kyyristymisen vaihtokytkin,S'accroupir (alterner),Guggolási kapcsoló,Attivare/disattivare abbassamento,屈む切替,숙이기 토글,Hurken Toggle,Crouch Toggle,Przełącz kucnięcie,Agachar (alternar),,Comutator ghemuire,Присесть/встать,Чучни (без држања),Çömelme anahtarı,Лазити,Клякане постоянно -Mouse look,CNTRLMNU_MOUSELOOK,,,,Pohled myší,Musens udseende,Maus-Blick,Κοίτα με το ποντίκι,Musrigardo,Vista con ratón,,Hiirikatselu,Vue à la souris,Egérrel való nézelődés,Modalità vista col mouse,マウス視点上下化,마우스 룩,Muis-look,Museblikk,Rozglądanie się myszką,Visão com o mouse,Vista com o rato,Privire în jur cu mouse,Обзор мышью,Гледај мишем,Fare bakışı,Огляд мишкою,Поглед с мишката -Look up,CNTRLMNU_LOOKUP,Look doesn't change the aim! It only alters the view pitch,,,Pohled vzhůru,Se op,Nach oben schauen,Κοίτα απάνω,Rigardi supren,Mirar arriba,,Katso ylös,Regarder en haut,Felfele nézés,Guarda sopra,視点を上げる,위로 보기,Kijk omhoog,Se opp,Patrz w górę,Olhar para cima,,Privire în sus,Смотреть вверх,Гледај горе,Yukarı bak.,Подивитись вверх,Поглед нагоре -Look down,CNTRLMNU_LOOKDOWN,,,,Pohled dolů,Se nedad,Nach unten schauen,Κοίτα κάτω,Rigardi malsupren,Mirar abajo,,Katso alas,Regarder en bas,Lefele nézés,Guarda sotto,視点を下げる,아래로 보기,Kijk naar beneden,Se nedover,Patrz w dół,Olhar para baixo,,Privire în jos,Смотреть вниз,Гледај доле,Aşağı bak.,Подивитись вниз,Поглед надолу -Center view,CNTRLMNU_CENTERVIEW,,,Centre view,Vystředit pohled,Centreret visning,Ansicht zentrieren,,Centrigi vidon,Centrar vista,,Keskitä katse,Recentrer Vue,Nézet középreigazítása,Sguardo centrato,視点を戻す,중앙 시점으로 보기,Middenaanzicht,Midtstilt visning,Wyśrodkuj widok,Olhar para o centro,,Centrare privire,Отцентрировать взгляд,Централизирај поглед,Merkezden görünüm,Центрувати погляд,Центриране на погледа -Run,CNTRLMNU_RUN,,,,Běh,Kør,Rennen,Τρέχα,Kuri,Correr,,Juokse,Courir (tenir),Futás,Corri,駆け足,달리기,Rennen,Kjør,Bieg,Correr,,Fugă,Бежать,Трчи,Koşmak,Біг,Бягане -Toggle Run,CNTRLMNU_TOGGLERUN,,,,Přepnout běh,Skift Kør,Rennen an/aus,Ενεργοποίηση τρέξιμου,Baskuligi kuron,Alternar «Correr»,,Juoksun vaihtokytkin,Courir (alterner),Futás kapcsoló,Abilita/disabilita corsa,常時駆け足切替,달리기 토글,Rennen aan/uit,Veksle Kjør,Przełącz bieg,Correr (alternar),,Comutator fugă,Бежать/идти,Трчи (без држања),Değiştir Çalıştır,Бігти / ходити,Бягане постоянно -Strafe,CNTRLMNU_STRAFE,,,,Pohyb do stran,Strafe,Seitwärts,,Flankmovi,Desplazamiento,,Astu sivuttain,Pas de côté,Oldalazás,Spostamento laterale,横移動化,양옆으로 이동,Zijdelings bewegen,Strafe,Uniki,Deslocamento lateral,,Deplasare în diagonală,Движение боком,Кретање у страну,Strafe,Рухатись боком,Странично движение -Show Scoreboard,CNTRLMNU_SCOREBOARD,,,,Zobrazit tabulku skóre,Vis resultattavle,Punktetafel anzeigen,,Montri poentotabulon,Mostrar marcador,,Näytä pistetaulu,Afficher Scores (tenir),Eredményjelző megjelenítése,Mostra la tabella punteggio,スコアボード表示,점수창 표시,Scorebord tonen,Vis resultattavle,Pokaż tablicę wyników,Exibir placar,,Afișare tabelă de marcaj,Таблица очков,Табела,Skor Tablosunu Göster,Таблиця очків,Покажи резултати -Action,CNTRLMNU_ACTION,,,,Akce,Handling,Aktion,Δράσεις,Ago,Acción,,Toiminta,,Akció,Azione,アクション,동작,Actie,Handling,Akcja,Ação,,Acțiuni,Основное,Радња,Eylem,Дії,Действие -Customize Action Controls,CNTRLMNU_ACTION_TITLE,,,,Nastavení ovládání akcí,Tilpas handlingskontroller,Aktions-Steuerung einstellen,,Adapti agajn regilojn,Cambiar controles de acción,,Toimintaohjausasetukset,Changer Contrôles Action,Akció beállítások testreszabása,Personalizza i controlli di azione,アクション操作設定,사용자 지정 동작 컨트롤,Aanpassen van de actiecontroles,Tilpass handlingskontroller,Ustaw Klawisze Akcji,Personalizar comandos de ação,Configurar Controlos de Ação,Personalizare schemă acțiuni,Основные клавиши управления,Контроле радње,Eylem Kontrollerini Özelleştirme,Налаштування елементів дій,Персонализиране на контролите за действие -Chat,CNTRLMNU_CHAT,,,,Chat,Chat,Chat,Μίλα,Babili,Chat,,Keskustelu,Chat,Chat,Chat,チャット,채팅,Chat,Chat,Czat,Bate-papo,Conversar,Conversație,Чат,Ћаскање,Sohbet,Чат,Чат -Multiplayer,MNU_MULTIPLAYER,,,,,,Mehrspieler,,Plurludanta,Multijugador,,Moninpeli,Multijoueur,Többjátékos,Multigiocatore,マルチプレイヤー,,,Flerspiller,Tryb Wieloosobowy,Multijogador,,Joc Online,Сетевая игра,,Çok Oyunculu,Гра в мережі,Онлайн игра -Say,CNTRLMNU_SAY,,,,Říct,Sig,Reden,Πές,Diri,Hablar,,Sano,Parler,Üzenet ,Parla,発言,채팅하기,Zeg,Si,Powiedz,Dizer,,Vorbește,Сообщение,Пиши,Söyle,Написати повідомлення,Съобщение -Customize Chat Controls,CNTRLMNU_CHAT_TITLE,,,,Nastavení ovládání chatu,Tilpas chat-kontrollerne,Chat-Steuerung einstellen,,Adapti babilajn regilojn,Cambiar controles de chat,,Keskusteluohjausasetukset,Changer Contrôles Chat,Chatbeállítások testreszabása,Personalizza i controlli della chat,チャット操作設定,사용자 지정 채팅 컨트롤,Chat-controles aanpassen aan uw wensen,Tilpass chattekontroller,Ustaw Klawisze Czatu,Personalizar comandos do bate-papo,Configurar Controlos de Chat,Personalizare control scriere,Клавиши управления чатом,Контроле ћаскања,Sohbet Kontrollerini Özelleştirme,Клавіші керування чатом,Персонализиране на контролите за чата -Customize Weapon Controls,CNTRLMNU_WEAPONS_TITLE,,,,Nastavení ovládání zbraní,Tilpas våbenkontroller,Waffen-Steuerung einstellen,,Adapti armilojn regilojn,Cambiar controles de armas,,Aseohjausasetukset,Changer Contrôles Armes,Fegyverbeállítások testreszabása,Personalizza i controlli delle armi,武器操作設定,사용자 지정 무기 컨트롤,Wapencontroles aanpassen aan uw eigen wensen,Tilpass våpenkontroller,Ustaw Klawisze Broni,Personalizar comandos de arma,Configurar Controlos de Armas,Personalizare control arme,Клавиши управления оружием,Контроле оружја,Silah Kontrollerini Özelleştirme,Клавіші керування зброєю,Персонализиране на контролите за оръжия -Customize Inventory Controls,CNTRLMNU_INVENTORY_TITLE,,,,Nastavení ovládání inventáře,Tilpas kontrol af inventar,Inventar-Steuerung einstellen,,Adapti inventarajn regilojn,Cambiar controles de inventario,,Varusteohjausasetukset,Changer Contrôles Inventaires,Eszköztár beállítások testreszabása,Personalizza i controlli dell'inventario,インベントリ操作設定,사용자 지정 인벤토리 컨트롤,Inventariscontroles aanpassen aan uw wensen,Tilpass beholdningskontroller,Ustaw Klawisze Ekwipunku,Personalizar comandos do inventário,Configurar Controlos de Inventário,Personalizare control inventar,Клавиши управления инвентарём,Контроле складишта,Envanter Kontrollerini Özelleştirme,Клавіші керування інвентарем,Персонализиране на контролите за инвентара -Customize Other Controls,CNTRLMNU_OTHER_TITLE,,,,Nastavení ostatních ovládání,Tilpas andre kontrolelementer,Sonstige Steuerung einstellen,,Adapti ekstrajn regilojn,Cambiar otros controles,,Muut ohjausasetukset,Changer Autres Contrôles,Egyéb irányítás testreszabása,Personalizza altri controlli,その他の操作設定,사용자 지정 그 외 컨트롤,Andere bedieningselementen aanpassen,Tilpass andre kontroller,Ustaw Inne Klawisze,Personalizar outros comandos,Configurar Outros Controlos,Personalizare scheme de control diverse,Прочие клавиши,Друге контроле,Diğer Kontrolleri Özelleştirme,Інші клавіші,Персонализиране на други контроли -Weapons,CNTRLMNU_WEAPONS,,,,Zbraně,Våben,Waffen,Όπλα,Armiloj,Armas,,Aseet,Armes,Fegyverek,Armi,武器,무기,Wapens,Våpen,Bronie,Armas,,Arme,Оружие,Оружје,Silahlar,Зброя,Оръжия -Next weapon,CNTRLMNU_NEXTWEAPON,,,,Další zbraň,Næste våben,Nächste Waffe,Επόμενο όπλο,Sekva armilo,Arma siguiente,,Seuraava ase,Arme Suivante,Következő fegyver,Arma successiva,次の武器,다음 무기,Volgende wapen,Neste våpen,Następna broń,Arma seguinte,,Arma următoare,Следующее оружие,Следеће оружје,Sonraki silah,Наступна зброя,Следващо оръжие -Previous weapon,CNTRLMNU_PREVIOUSWEAPON,,,,Předchozí zbraň,Forrige våben,Vorherige Waffe,Προηγούμενο όπλο,Antaŭa armilo,Arma anterior,,Edellinen ase,Arme Précédente,Előző fegyver,Arma precedente,前の武器,이전 무기,Vorige wapen,Forrige våpen,Poprzednia broń,Arma anterior,,Arma anterioară,Предыдущее оружие,Претходно оружје,Önceki silah,Попередня зброя,Предишно оръжие -Weapon 1,CNTRLMNU_SLOT1,Todo - make game specific,,,Slot zbraně 1,Våben 1,Waffe 1,Όπλο 1,Armilo 1,Arma 1,,Aselokero 1,Emplacement D'Arme 1,1. fegyver,Slot arma 1,武器スロット 1,무기 슬롯 1,Wapenslot 1,Våpen 1,Broń 1,Arma 1,,Arma 1,Первое оружие,Оружје 1,Silah 1,Зброя 1,Оръжие 1 +",左を向く,왼쪽으로 회전,Draai naar links,Sving til venstre,Obróć się w lewo,Girar para a esquerda,,Întoarcere stânga,Поворот налево,Окрени се лево,Sväng vänster,Sola dön,Повернутись ліворуч,Обръщане в ляво +Turn right,CNTRLMNU_TURNRIGHT,,,,Otočení vpravo,Drej til højre,Nach rechts drehen,Γύρνα δεξιά,Turni dekstren,Girar a la derecha,,Käänny oikealle,Tourner à Droite,Jobbra fordul,Gira a destra,右を向く,오른쪽으로 회전,Draai naar rechts,Sving til høyre,Obróć się w prawo,Girar para a direita,,Întoarcere dreapta,Поворот направо,Окрени се десно,Sväng höger,Sağa dön,Повернутись праворуч,Обръщане в дясно +Quick Turn,CNTRLMNU_TURN180,,,,Rychlé otočení,Hurtig drejning,Schnelle Drehung,Γρήγορη γύριση,Rapida turno,Giro rápido,,Pikakäännös,Faire un 180,Megfordulás,Rotazione rapida,背後を向く,빠른 회전,Snelle draai,Rask sving,Szybki Obrót,Giro rápido,,Întoarcere rapidă,Быстрый разворот,Брзи окрет,Snabb vändning,Hızlı Dönüş,Швидкий розворот,Бързо обръщане +Jump,CNTRLMNU_JUMP,,,,Skok,Hop,Springen,Πήδα,Salti,Saltar,,Hyppää,Sauter,Ugrás,Salto,ジャンプ,점프,Springen,Hopp,Skok,Pular,Saltar,Salt,Прыжок,Скок,Hoppa,Atlama,Стрибок,Скок +Crouch,CNTRLMNU_CROUCH,,,,Kleknutí,Kryb,Ducken,Σκύψιμο,Kaŭri,Agacharse,,Kyyristy,S'accroupir (tenir),Guggolás,Abbassarsi,屈む,숙이기,Hurken,Huk,Kucnięcie,Agachar,,Ghemuire,Присесть,Чучни,Huk,Çömelme,Присісти,Клякане +Crouch Toggle,CNTRLMNU_TOGGLECROUCH,,,,Přepnout kleknutí,Krybbe omskifter,Ducken an/aus,Εναλλαγή σκύψιμο,Kaŭrobaskuli,Alternar agachado,,Kyyristymisen vaihtokytkin,S'accroupir (alterner),Guggolási kapcsoló,Attivare/disattivare abbassamento,屈む切替,숙이기 토글,Hurken Toggle,,Przełącz kucnięcie,Agachar (alternar),,Comutator ghemuire,Присесть/встать,Чучни (без држања),Växla huk,Çömelme anahtarı,Лазити,Клякане постоянно +Mouse look,CNTRLMNU_MOUSELOOK,,,,Pohled myší,Musens udseende,Maus-Blick,Κοίτα με το ποντίκι,Musrigardo,Vista con ratón,,Hiirikatselu,Vue à la souris,Egérrel való nézelődés,Modalità vista col mouse,マウス視点上下化,마우스 룩,Muis-look,Museblikk,Rozglądanie się myszką,Visão com o mouse,Vista com o rato,Privire în jur cu mouse,Обзор мышью,Гледај мишем,Musens utseende,Fare bakışı,Огляд мишкою,Поглед с мишката +Look up,CNTRLMNU_LOOKUP,Look doesn't change the aim! It only alters the view pitch,,,Pohled vzhůru,Se op,Nach oben schauen,Κοίτα απάνω,Rigardi supren,Mirar arriba,,Katso ylös,Regarder en haut,Felfele nézés,Guarda sopra,視点を上げる,위로 보기,Kijk omhoog,Se opp,Patrz w górę,Olhar para cima,,Privire în sus,Смотреть вверх,Гледај горе,Titta uppåt,Yukarı bak.,Подивитись вверх,Поглед нагоре +Look down,CNTRLMNU_LOOKDOWN,,,,Pohled dolů,Se nedad,Nach unten schauen,Κοίτα κάτω,Rigardi malsupren,Mirar abajo,,Katso alas,Regarder en bas,Lefele nézés,Guarda sotto,視点を下げる,아래로 보기,Kijk naar beneden,Se nedover,Patrz w dół,Olhar para baixo,,Privire în jos,Смотреть вниз,Гледај доле,Titta ner,Aşağı bak.,Подивитись вниз,Поглед надолу +Center view,CNTRLMNU_CENTERVIEW,,,Centre view,Vystředit pohled,Centreret visning,Ansicht zentrieren,Προβολή στο κέντρο,Centrigi vidon,Centrar vista,,Keskitä katse,Recentrer Vue,Nézet középreigazítása,Sguardo centrato,視点を戻す,중앙 시점으로 보기,Middenaanzicht,Midtstilt visning,Wyśrodkuj widok,Olhar para o centro,,Centrare privire,Отцентрировать взгляд,Централизирај поглед,Centrerad vy,Merkezden görünüm,Центрувати погляд,Центриране на погледа +Run,CNTRLMNU_RUN,,,,Běh,Kør,Rennen,Τρέχα,Kuri,Correr,,Juokse,Courir (tenir),Futás,Corri,駆け足,달리기,Rennen,Kjør,Bieg,Correr,,Fugă,Бежать,Трчи,Spring,Koşmak,Біг,Бягане +Toggle Run,CNTRLMNU_TOGGLERUN,,,,Přepnout běh,Skift Kør,Rennen an/aus,Ενεργοποίηση τρέξιμου,Baskuligi kuron,Alternar «Correr»,,Juoksun vaihtokytkin,Courir (alterner),Futás kapcsoló,Abilita/disabilita corsa,常時駆け足切替,달리기 토글,Rennen aan/uit,Veksle Kjør,Przełącz bieg,Correr (alternar),,Comutator fugă,Бежать/идти,Трчи (без држања),Växla springa,Değiştir Çalıştır,Бігти / ходити,Бягане постоянно +Strafe,CNTRLMNU_STRAFE,,,,Pohyb do stran,Strafe,Seitwärts,,Flankmovi,Desplazamiento,,Astu sivuttain,Pas de côté,Oldalazás,Spostamento laterale,横移動化,양옆으로 이동,Zijdelings bewegen,,Uniki,Deslocamento lateral,,Deplasare în diagonală,Движение боком,Кретање у страну,Strafe,,Рухатись боком,Странично движение +Show Scoreboard,CNTRLMNU_SCOREBOARD,,,,Zobrazit tabulku skóre,Vis resultattavle,Punktetafel anzeigen,Εμφάνιση πίνακα αποτελεσμάτων,Montri poentotabulon,Mostrar marcador,,Näytä pistetaulu,Afficher Scores (tenir),Eredményjelző megjelenítése,Mostra la tabella punteggio,スコアボード表示,점수창 표시,Scorebord tonen,Vis resultattavle,Pokaż tablicę wyników,Exibir placar,,Afișare tabelă de marcaj,Таблица очков,Табела,Visa resultattavlan,Skor Tablosunu Göster,Таблиця очків,Покажи резултати +Action,CNTRLMNU_ACTION,,,,Akce,Handling,Aktion,Δράσεις,Ago,Acción,,Toiminta,,Akció,Azione,アクション,동작,Actie,Handling,Akcja,Ação,,Acțiuni,Основное,Радња,Åtgärd,Eylem,Дії,Действие +Customize Action Controls,CNTRLMNU_ACTION_TITLE,,,,Nastavení ovládání akcí,Tilpas handlingskontroller,Aktions-Steuerung einstellen,Προσαρμογή των χειριστηρίων δράσης,Adapti agajn regilojn,Cambiar controles de acción,,Toimintaohjausasetukset,Changer Contrôles Action,Akció beállítások testreszabása,Personalizza i controlli di azione,アクション操作設定,사용자 지정 동작 컨트롤,Aanpassen van de actiecontroles,Tilpass handlingskontroller,Ustaw Klawisze Akcji,Personalizar comandos de ação,Configurar Controlos de Ação,Personalizare schemă acțiuni,Основные клавиши управления,Контроле радње,Anpassa kontrollerna för åtgärder,Eylem Kontrollerini Özelleştirme,Налаштування елементів дій,Персонализиране на контролите за действие +Chat,CNTRLMNU_CHAT,,,,,,,Μίλα,Babili,,,Keskustelu,,,,チャット,채팅,,,Czat,Bate-papo,Conversar,Conversație,Чат,Ћаскање,Chatt,Sohbet,Чат,Чат +Multiplayer,MNU_MULTIPLAYER,,,,,,Mehrspieler,,Plurludanta,Multijugador,,Moninpeli,Multijoueur,Többjátékos,Multigiocatore,マルチプレイヤー,,,Flerspiller,Tryb Wieloosobowy,Multijogador,,Joc Online,Сетевая игра,,Flera spelare,Çok Oyunculu,Гра в мережі,Онлайн игра +Say,CNTRLMNU_SAY,,,,Říct,Sig,Reden,Πές,Diri,Hablar,,Sano,Parler,Üzenet ,Parla,発言,채팅하기,Zeg,Si,Powiedz,Dizer,,Vorbește,Сообщение,Пиши,Säg,Söyle,Написати повідомлення,Съобщение +Customize Chat Controls,CNTRLMNU_CHAT_TITLE,,,,Nastavení ovládání chatu,Tilpas chat-kontrollerne,Chat-Steuerung einstellen,Προσαρμογή ελέγχου συνομιλίας,Adapti babilajn regilojn,Cambiar controles de chat,,Keskusteluohjausasetukset,Changer Contrôles Chat,Chatbeállítások testreszabása,Personalizza i controlli della chat,チャット操作設定,사용자 지정 채팅 컨트롤,Chat-controles aanpassen aan uw wensen,Tilpass chattekontroller,Ustaw Klawisze Czatu,Personalizar comandos do bate-papo,Configurar Controlos de Chat,Personalizare control scriere,Клавиши управления чатом,Контроле ћаскања,Anpassa kontrollerna för chatt,Sohbet Kontrollerini Özelleştirme,Клавіші керування чатом,Персонализиране на контролите за чата +Customize Weapon Controls,CNTRLMNU_WEAPONS_TITLE,,,,Nastavení ovládání zbraní,Tilpas våbenkontroller,Waffen-Steuerung einstellen,Προσαρμογή ελέγχου όπλων,Adapti armilojn regilojn,Cambiar controles de armas,,Aseohjausasetukset,Changer Contrôles Armes,Fegyverbeállítások testreszabása,Personalizza i controlli delle armi,武器操作設定,사용자 지정 무기 컨트롤,Wapencontroles aanpassen aan uw eigen wensen,Tilpass våpenkontroller,Ustaw Klawisze Broni,Personalizar comandos de arma,Configurar Controlos de Armas,Personalizare control arme,Клавиши управления оружием,Контроле оружја,Anpassa vapenkontroller,Silah Kontrollerini Özelleştirme,Клавіші керування зброєю,Персонализиране на контролите за оръжия +Customize Inventory Controls,CNTRLMNU_INVENTORY_TITLE,,,,Nastavení ovládání inventáře,Tilpas kontrol af inventar,Inventar-Steuerung einstellen,Προσαρμογή Ελέγχου Απογραφής,Adapti inventarajn regilojn,Cambiar controles de inventario,,Varusteohjausasetukset,Changer Contrôles Inventaires,Eszköztár beállítások testreszabása,Personalizza i controlli dell'inventario,インベントリ操作設定,사용자 지정 인벤토리 컨트롤,Inventariscontroles aanpassen aan uw wensen,Tilpass beholdningskontroller,Ustaw Klawisze Ekwipunku,Personalizar comandos do inventário,Configurar Controlos de Inventário,Personalizare control inventar,Клавиши управления инвентарём,Контроле складишта,Anpassa kontrollerna för inventarier,Envanter Kontrollerini Özelleştirme,Клавіші керування інвентарем,Персонализиране на контролите за инвентара +Customize Other Controls,CNTRLMNU_OTHER_TITLE,,,,Nastavení ostatních ovládání,Tilpas andre kontrolelementer,Sonstige Steuerung einstellen,Προσαρμογή άλλων ελέγχων,Adapti ekstrajn regilojn,Cambiar otros controles,,Muut ohjausasetukset,Changer Autres Contrôles,Egyéb irányítás testreszabása,Personalizza altri controlli,その他の操作設定,사용자 지정 그 외 컨트롤,Andere bedieningselementen aanpassen,Tilpass andre kontroller,Ustaw Inne Klawisze,Personalizar outros comandos,Configurar Outros Controlos,Personalizare scheme de control diverse,Прочие клавиши,Друге контроле,Anpassa andra kontroller,Diğer Kontrolleri Özelleştirme,Інші клавіші,Персонализиране на други контроли +Weapons,CNTRLMNU_WEAPONS,,,,Zbraně,Våben,Waffen,Όπλα,Armiloj,Armas,,Aseet,Armes,Fegyverek,Armi,武器,무기,Wapens,Våpen,Bronie,Armas,,Arme,Оружие,Оружје,Vapen,Silahlar,Зброя,Оръжия +Next weapon,CNTRLMNU_NEXTWEAPON,,,,Další zbraň,Næste våben,Nächste Waffe,Επόμενο όπλο,Sekva armilo,Arma siguiente,,Seuraava ase,Arme Suivante,Következő fegyver,Arma successiva,次の武器,다음 무기,Volgende wapen,Neste våpen,Następna broń,Arma seguinte,,Arma următoare,Следующее оружие,Следеће оружје,Nästa vapen,Sonraki silah,Наступна зброя,Следващо оръжие +Previous weapon,CNTRLMNU_PREVIOUSWEAPON,,,,Předchozí zbraň,Forrige våben,Vorherige Waffe,Προηγούμενο όπλο,Antaŭa armilo,Arma anterior,,Edellinen ase,Arme Précédente,Előző fegyver,Arma precedente,前の武器,이전 무기,Vorige wapen,Forrige våpen,Poprzednia broń,Arma anterior,,Arma anterioară,Предыдущее оружие,Претходно оружје,Föregående vapen,Önceki silah,Попередня зброя,Предишно оръжие +Weapon 1,CNTRLMNU_SLOT1,Todo - make game specific,,,Slot zbraně 1,Våben 1,Waffe 1,Όπλο 1,Armilo 1,Arma 1,,Aselokero 1,Emplacement D'Arme 1,1. fegyver,Slot arma 1,武器スロット 1,무기 슬롯 1,Wapenslot 1,Våpen 1,Broń 1,Arma 1,,Arma 1,Первое оружие,Оружје 1,Vapen 1,Silah 1,Зброя 1,Оръжие 1 Weapon 2,CNTRLMNU_SLOT2,"only show appropriate slots per game -",,,Slot zbraně 2,Våben 2,Waffe 2,Όπλο 2,Armilo 2,Arma 2,,Aselokero 2,Emplacement D'Arme 2,2. fegyver,Slot arma 2,武器スロット 2,무기 슬롯 2,Wapenslot 2,Våpen 2,Broń 2,Arma 2,,Arma 2,Второе оружие,Оружје 2,Silah 2,Зброя 2,Оръжие 2 -Weapon 3,CNTRLMNU_SLOT3,,,,Slot zbraně 3,Våben 3,Waffe 3,Όπλο 3,Armilo 3,Arma 3,,Aselokero 3,Emplacement D'Arme 3,3. fegyver,Slot arma 3,武器スロット 3,무기 슬롯 3,Wapenslot 3,Våpen 3,Broń 3,Arma 3,,Arma 3,Третье оружие,Оружје 3,Silah 3,Зброя 3,Оръжие 3 -Weapon 4,CNTRLMNU_SLOT4,,,,Slot zbraně 4,Våben 4,Waffe 4,Όπλο 4,Armilo 4,Arma 4,,Aselokero 4,Emplacement D'Arme 4,4. fegyver,Slot arma 4,武器スロット 4,무기 슬롯 4,Wapenslot 4,Våpen 4,Broń 4,Arma 4,,Arma 4,Четвёртое оружие,Оружје 4,Silah 4,Зброя 4,Оръжие 4 -Weapon 5,CNTRLMNU_SLOT5,,,,Slot zbraně 5,Våben 5,Waffe 5,Όπλο 5,Armilo 5,Arma 5,,Aselokero 5,Emplacement D'Arme 5,5. fegyver,Slot arma 5,武器スロット 5,무기 슬롯 5,Wapenslot 5,Våpen 5,Broń 5,Arma 5,,Arma 5,Пятое оружие,Оружје 5,Silah 5,Зброя 5,Оръжие 5 -Weapon 6,CNTRLMNU_SLOT6,,,,Slot zbraně 6,Våben 6,Waffe 6,Όπλο 6,Armilo 6,Arma 6,,Aselokero 6,Emplacement D'Arme 6,6. fegyver,Slot arma 6,武器スロット 6,무기 슬롯 6,Wapenslot 6,Våpen 6,Broń 6,Arma 6,,Arma 6,Шестое оружие,Оружје 6,Silah 6,Зброя 6,Оръжие 6 -Weapon 7,CNTRLMNU_SLOT7,,,,Slot zbraně 7,Våben 7,Waffe 7,Όπλο 7,Armilo 7,Arma 7,,Aselokero 7,Emplacement D'Arme 7,7. fegyver,Slot arma 7,武器スロット 7,무기 슬롯 7,Wapenslot 7,Våpen 7,Broń 7,Arma 7,,Arma 7,Седьмое оружие,Оружје 7,Silah 7,Зброя 7,Оръжие 7 -Weapon 8,CNTRLMNU_SLOT8,,,,Slot zbraně 8,Våben 8,Waffe 8,Όπλο 8,Armilo 8,Arma 8,,Aselokero 8,Emplacement D'Arme 8,8. fegyver,Slot arma 8,武器スロット 8,무기 슬롯 8,Wapenslot 8,Våpen 8,Broń 8,Arma 8,,Arma 8,Восьмое оружие,Оружје 8,Silah 8,Зброя 8,Оръжие 8 -Weapon 9,CNTRLMNU_SLOT9,,,,Slot zbraně 9,Våben 9,Waffe 9,Όπλο 9,Armilo 9,Arma 9,,Aselokero 9,Emplacement D'Arme 9,9. fegyver,Slot arma 9,武器スロット 9,무기 슬롯 9,Wapenslot 9,Våpen 9,Broń 9,Arma 9,,Arma 9,Девятое оружие,Оружје 9,Silah 9,Зброя 9,Оръжие 9 -Weapon 10,CNTRLMNU_SLOT0,,,,Slot zbraně 10,Våben 10,Waffe 10,Όπλο 0,Armilo 10,Arma 10,,Aselokero 0,Emplacement D'Arme 0,0. fegyver,Slot arma 0,武器スロット 0,무기 슬롯 0,Wapenslot 0,Våpen 10,Broń 10,Arma 10,,Arma 0,Десятое оружие,Оружје 0,Silah 10,Зброя 0,Оръжие 10 -Inventory,CNTRLMNU_INVENTORY,,,,Inventář,Inventar,Inventar,Άντικείμενα,Inventaro,Inventario,,Varusteet,Inventaire,Eszköztár beállítások testreszabása,Inventario,所持品,인벤토리,Inventaris,Inventar,Ekwipunek,Inventário,,Inventar,Инвентарь,Инвентар,Envanter,Інвентар,Инвентар -Activate item,CNTRLMNU_USEITEM,,,,Aktivovat předmět,Aktiver genstand,Gegenstand aktivieren,Ενεργοποίηση αντικείμενου,Aktivigi objekton,Activar objeto,,Aktivoi varuste,Activer objet,Eszköz használata,Attiva oggetto,アイテムを使用,선택한 아이템 사용,Item activeren,Aktiver gjenstand,Użyj przedmiot,Ativar item,,Activează obiectul,Использовать предмет,Активирај предмет,Öğeyi etkinleştir,Активувати предмет,Използвай предмета -Activate all items,CNTRLMNU_USEALLITEMS,,,,Aktivovat všechny předměty,Aktivering af alle genstande,Alle Gegenstände aktivieren,Ενεργοποίησε όλα τα αντικείμενα,Aktivigi ĉiujn objektojn,Activar todos los objetos,,Aktivoi kaikki varusteet,Activer tous les objets,Minden eszköz használata,Attiva tutti gli oggetti,全てのアイテムを使用,모든 아이템 사용,Activeer alle items,Aktiver alle gjenstander,Użyj wszystkie przedmioty,Ativar todos os itens,,Activează tot inventarul,Использовать все предметы,Активирај све предмете,Tüm öğeleri etkinleştirin,Активувати усі предмети,Използвай всички предмети -Next item,CNTRLMNU_NEXTITEM,,,,Další předmět,Næste genstand,Nächster Gegenstand,Επόμενο αντικείμενο,Sekva objekto,Objeto siguiente,,Seuraava varuste,Objet suivant,Következő eszköz,Oggetto successivo,次のアイテム,다음 아이템,Volgende item,Neste element,Następny przedmiot,Item seguinte,,Următorul obiect,Следующий предмет,Следећи предмет,Sonraki madde,Наступний предмет,Следващ предмет -Previous item,CNTRLMNU_PREVIOUSITEM,,,,Předchozí předmět,Forrige genstand,Vorheriger Gegenstand,Προηγούμενο αντικείμενο,Antaŭa objekto,Objeto anterior,,Edellinen varuste,Objet précédent,Előző eszköz,Oggetto precedente,前のアイテム,이전 아이템,Vorige item,Forrige element,Poprzedni przedmiot,Item anterior,,Obiect anterior,Предыдущий предмет,Претходни предмет,Önceki madde,Попередній предмет,Предишен предмет -Customize Map Controls,MAPCNTRLMNU_TITLE,most are not used yet but will be,,,Nastavení ovládání mapy,Tilpas kontrolelementer til kortet,Automapsteuerung einstellen,,Adapti map-regilojn,Cambiar controles del mapa,,Kartanohjausasetukset,Contrôles Carte,Térkép irányításának testreszabása,Personalizza i controlli mappa,マップコントロール カスタマイズ,미니맵 단축키 설정,Kaartcontroles aanpassen,Tilpass kartkontroller,Ustaw klawisze mapy,Peronalizar comandos do mapa,,Personalizare schemă de control a hărții,Клавиши управления автокартой,Промени контроле мапе,Harita Kontrollerini Özelleştirme,Клавіші керування автокартою,Персонализиране контролите за картата -Map Controls,MAPCNTRLMNU_CONTROLS,,,,Mapa,Kontrolelementer til kort,Automapsteuerung,,Map-regiloj,Controles del mapa,,Kartanohjaus,Contrôles de la carte,Térkép irányítása,Controlli mappa,マップコントロール,미니맵 조정,Kaartcontroles,Kartkontroller,Klawisze mapy,Comandos do mapa,,Schemă de control a hărtii,Автокарта,Контроле мапе,Harita Kontrolleri,Автокарта,Контроли за карта -Pan left,MAPCNTRLMNU_PANLEFT,,,,Doleva,Panorere til venstre,Nach links,,Alturni maldekstren,Mover a la izquierda,,Panoroi vasemmalle,Aller à gauche,Balra igazítás,Sposta a sinistra,左に振る,왼쪽으로 이동,Pan links,Panorer til venstre,Przesuń w lewo,Mover para a esquerda,,Mutare spre stânga,Сдвиг влево,Лево,Sola kaydırın,Зсув вліво,Преместване наляво -Pan right,MAPCNTRLMNU_PANRIGHT,,,,Doprava,Panorering til højre,Nach rechts,,Alturni dekstren,Mover a la derecha,,Panoroi oikealle,Aller à droite,Jobbra igazítás,Sposta a destra,右に振る,오른쪽으로 이동,Pan rechts,Panorer til høyre,Przesuń w prawo,Mover para a direita,,Mutare spre dreapta,Сдвиг вправо,Десно,Sağa kaydırın,Зсув вправо,Преместване на дясно -Pan up,MAPCNTRLMNU_PANUP,,,,Nahoru,Panorere op,Nach oben,,Alturni supren,Mover hacia arriba,,Panoroi ylös,Aller en haut,Felfele igazítás,Sposta sopra,上に振る,위쪽으로 이동,Pan omhoog,Panorer opp,Przesuń w górę,Mover para cima,,Mutare în sus,Сдвиг вверх,Горе,Yukarı kaydırın,Зсув вверх,Преместване на горе -Pan down,MAPCNTRLMNU_PANDOWN,,,,Dolů,Panorere ned,Nach unten,,Alturni malsupren,Mover hacia abajo,,Panoroi alas,Aller en bas,Lefele igazítás,Sposta sotto,下に振る,아래쪽으로 이동,Pan neer,Panorer ned,Przesuń w dół,Mover para baixo,,Mutare în jos,Сдвиг вниз,Доле,Aşağı kaydırın,Зсув вниз,Преместване на долу -Zoom in,MAPCNTRLMNU_ZOOMIN,,,,Přiblížit,Zoom ind,Reinzoomen,,Zomi,Acercar,,Lähennä,Zoom avant,Ráközelítés,Ingrandisci,ズームイン,줌 확대,Inzoomen,Zoom inn,Przybliż,Ampliar,,Apropriere Cameră,Приблизить,Увеличати,Yakınlaştır,Наблизити,Приближи -Zoom out,MAPCNTRLMNU_ZOOMOUT,,,,Oddálit,Zoom ud,Rauszoomen,,Malzomi,Alejar,,Loitonna,Zoom arrière,Távolítás,Rimpicciolisci,ズームアウト,줌 축소,Uitzoomen,Zoom ut,Oddal,Afastar,,Depărtare Cameră,Отдалить,Одзумирати,Uzaklaştır,Віддалити,Отдалечи -Toggle zoom,MAPCNTRLMNU_TOGGLEZOOM,,,,Přiblížení vyp./zap.,Skift mellem zoom,Zoom an/aus,,Baskuligi zomon,Alternar zoom,,Zoomauksen vaihtokytkin,Alterner zoom,Közelítés átkapcsolása,Abilita/disabilita zoom,ズーム切替,표준배율 조정,Omschakelen van de zoom,Veksle mellom zoom,Przełącz przybliżanie,Ativar/desativar zoom,,Comutator Zoom,Приближение (перекл.),Укључи зум,Yakınlaştırmayı aç / kapat,Перемикач наближення,Приближи постоянно -Toggle follow,MAPCNTRLMNU_TOGGLEFOLLOW,,,,Sledování hráče vyp./zap.,Skift følge,Folgen an/aus,,Baskuligi sekvon,Alternar seguimiento,,Seuraamistilan vaihtokytkin,Alterner suivi,Követés átkapcsolása,Abilita/disabilita scorrimento mappa,追従切替,추적모드 조정,Schakelen volgen,Veksle følge,Przełącz śledzenie,Ativar/desativar seguimento,,Comutator urmărire jucător,Привязка к игроку (перекл.),Укључи праћење,Takip etmeyi değiştir,Перемикач слідування за гравцем,Следвай постаянно -Toggle grid,MAPCNTRLMNU_TOGGLEGRID,,,,Mřížka vyp./zap.,Skift gitter,Gitter an/aus,,Baskuligi kradon,Alternar cuadrícula,,Ruudukon vaihtokytkin,Alterner grille,Rács kapcsolása,Abilita/disabilita la griglia,グリッド切替,그리드 조정,Kiesnet,Veksle rutenett,Przełącz siatkę,Ativar/desativar grade,,Comutator grilă,Сетка (перекл.),Укључи координатну мрежу,Izgarayı değiştir,Перемикач сітки,Включи координатна мрежа -Toggle rotate,MAPCNTRLMNU_ROTATE,,,,Otáčení vyp./zap.,Skift til rotere,Rotation an/aus,,Baskuligi turnadon,Alternar rotación,,Kääntämisen vaihtokytkin,Alterner rotation,Forgás kapcsolása,Abilita/disabilita la rotazione,回転切替,,Toggle rotatie,Veksle mellom rotasjon,Przełącz obracanie,Ativar/desativar rotação,,Comutator rotire,Вращение (перекл.),Укључи ротацију,Döndürmeyi değiştir,Перемикач обертання,Завъртане (превключване) -Toggle texture,MAPCNTRLMNU_TOGGLETEXTURE,,,,Textury vyp./zap.,Skift tekstur,Texturen an/aus,,Baskuligi teksturon,Alternar textura,,Pintakuvioinnin vaihtokytkin,Alterner texture,Textúra kapcsolása,Abilita/disabilita le texture,テクスチャ切替,미니맵 텍스쳐 조정,Toggle textuur,Veksle tekstur,Przełącz tekstury,Ativar/desativar texturas,,Comutator mod texturat,Текстуры (перекл.),Укључи текстуру,Dokuyu değiştir,Перемикач текстур, -Toggle automap,CNTRLMNU_AUTOMAP,,,,Otevřít/zavřít automapu,Skift til automap,Automap an/aus,,Baskuligi aŭtomapo,Alternar automapa,,Kytke automaattikartta päälle/pois,Activer Carte,Térkép ki/bekapcsolása,Abilita/disabilita l'automappa,オートマップの切替,오토맵 조정,Automap aan/uit,Veksle mellom automap,Włącz mapę,Ativar/desativar automapa,,Comutator hartă computerizată,Автокарта (перекл.),Прикажи аутомапу,Otomatik haritayı değiştir,Перемикач автокарти, -Chasecam,CNTRLMNU_CHASECAM,,,,Kamera z třetí osoby,Chasecam,Verfolgerkamera,,Ĉaskamerao,Cámara de seguimiento,,Seurantakamera,Caméra 3ième personne,Külsőnézetű kamera,Telecamera di inseguimento,背後視点,3인칭 카메라,,,Kamera Śledzenia,Câmera em terceira pessoa,Câmera em terceira-pessoa,Cameră urmăritoare,Вид от 3-го лица,Чејс-кем,Chasecam,Вид від 3-го лиця, -Screenshot,CNTRLMNU_SCREENSHOT,,,,Pořídit snímek obrazovky,Skærmbillede,,,Ekrankopio,Captura de pantalla,,Kuvakaappaus,Capture d'écran,Képernyő lefényképezése,Cattura schermo,画面キャプチャ,스크린샷,,Skjermbilde,Zrzut ekranu,Captura de tela,,Captură ecran,Снимок экрана,Усликај,Ekran görüntüsü,Скріншот, -Open console,CNTRLMNU_CONSOLE,,,,Otevřít konzoli,Åbn konsollen,Konsole öffnen,,Malfermi konzolon,Abrir consola,,Avaa konsoli,Ouvrir Console,Konzol megnyitása,Apri la console,コンソールを開く,콘솔 열기,Open console,Åpne konsoll,Otwórz konsolę,Abrir console,Abrir consola,Deschide consola,Открыть консоль,Отвори консолу,Açık konsol,Відкрити консоль, -Pause,CNTRLMNU_PAUSE,,,,Pauza,Pause,,Πάυση,Paŭzo,Pausa,,Tauko,,Szünet,Pausa,ポーズ,일시정지,Pauze,Pause,Pauza,Pausar,,Pauză,Пауза,Пауза,Duraklat,Пауза, -Increase Display Size,CNTRLMNU_DISPLAY_INC,,,,Zvětšit velikost obrazovky,Forøg visningsstørrelsen,Anzeige vergrößern,,Kreskigi ekrangrandon,Agrandar ventana,,Suurenna näytön kokoa,Agrandir l'affichage,Képméret növelése,Aumenta la dimensione del display,画面サイズを拡大,화면 크기 늘리기,Vergroot het display,Øk visningsstørrelse,Powiększ Rozmiar Wyświetlania,Aumentar tamanho da exibição,Aumentar Tamanho do Ecrã,Mărire ecran,Увеличить размер экрана,Повећајте величину екрана,Ekran Boyutunu Artırın,Збільшити розмір екрану, -Decrease Display Size,CNTRLMNU_DISPLAY_DEC,,,,Zmenšit velikost obrazovky,Formindsk skærmstørrelse,Anzeige verkleinern,,Malkreskigi ekrangrandon,Reducir ventana,,Pienennä näytön kokoa,Réduire l'affichage,Képméret csökkentése,Riduci la dimensione del display,画面サイズを縮小,화면 크기 줄이기,Verlaag het display,Reduser visningsstørrelse,Pomniejsz Rozmiar Wyświetlania,Reduzir tamanho da exibição,Diminuir Tamanho do Ecrã,Micșorare ecran,Уменьшить размер экрана,Смањите величину екрана,Ekran Boyutunu Azaltma,Зменшити розмір екрану, +",,,Slot zbraně 2,Våben 2,Waffe 2,Όπλο 2,Armilo 2,Arma 2,,Aselokero 2,Emplacement D'Arme 2,2. fegyver,Slot arma 2,武器スロット 2,무기 슬롯 2,Wapenslot 2,Våpen 2,Broń 2,Arma 2,,Arma 2,Второе оружие,Оружје 2,Vapen 2,Silah 2,Зброя 2,Оръжие 2 +Weapon 3,CNTRLMNU_SLOT3,,,,Slot zbraně 3,Våben 3,Waffe 3,Όπλο 3,Armilo 3,Arma 3,,Aselokero 3,Emplacement D'Arme 3,3. fegyver,Slot arma 3,武器スロット 3,무기 슬롯 3,Wapenslot 3,Våpen 3,Broń 3,Arma 3,,Arma 3,Третье оружие,Оружје 3,Vapen 3,Silah 3,Зброя 3,Оръжие 3 +Weapon 4,CNTRLMNU_SLOT4,,,,Slot zbraně 4,Våben 4,Waffe 4,Όπλο 4,Armilo 4,Arma 4,,Aselokero 4,Emplacement D'Arme 4,4. fegyver,Slot arma 4,武器スロット 4,무기 슬롯 4,Wapenslot 4,Våpen 4,Broń 4,Arma 4,,Arma 4,Четвёртое оружие,Оружје 4,Vapen 4,Silah 4,Зброя 4,Оръжие 4 +Weapon 5,CNTRLMNU_SLOT5,,,,Slot zbraně 5,Våben 5,Waffe 5,Όπλο 5,Armilo 5,Arma 5,,Aselokero 5,Emplacement D'Arme 5,5. fegyver,Slot arma 5,武器スロット 5,무기 슬롯 5,Wapenslot 5,Våpen 5,Broń 5,Arma 5,,Arma 5,Пятое оружие,Оружје 5,Vapen 5,Silah 5,Зброя 5,Оръжие 5 +Weapon 6,CNTRLMNU_SLOT6,,,,Slot zbraně 6,Våben 6,Waffe 6,Όπλο 6,Armilo 6,Arma 6,,Aselokero 6,Emplacement D'Arme 6,6. fegyver,Slot arma 6,武器スロット 6,무기 슬롯 6,Wapenslot 6,Våpen 6,Broń 6,Arma 6,,Arma 6,Шестое оружие,Оружје 6,Vapen 6,Silah 6,Зброя 6,Оръжие 6 +Weapon 7,CNTRLMNU_SLOT7,,,,Slot zbraně 7,Våben 7,Waffe 7,Όπλο 7,Armilo 7,Arma 7,,Aselokero 7,Emplacement D'Arme 7,7. fegyver,Slot arma 7,武器スロット 7,무기 슬롯 7,Wapenslot 7,Våpen 7,Broń 7,Arma 7,,Arma 7,Седьмое оружие,Оружје 7,Vapen 7,Silah 7,Зброя 7,Оръжие 7 +Weapon 8,CNTRLMNU_SLOT8,,,,Slot zbraně 8,Våben 8,Waffe 8,Όπλο 8,Armilo 8,Arma 8,,Aselokero 8,Emplacement D'Arme 8,8. fegyver,Slot arma 8,武器スロット 8,무기 슬롯 8,Wapenslot 8,Våpen 8,Broń 8,Arma 8,,Arma 8,Восьмое оружие,Оружје 8,Vapen 8,Silah 8,Зброя 8,Оръжие 8 +Weapon 9,CNTRLMNU_SLOT9,,,,Slot zbraně 9,Våben 9,Waffe 9,Όπλο 9,Armilo 9,Arma 9,,Aselokero 9,Emplacement D'Arme 9,9. fegyver,Slot arma 9,武器スロット 9,무기 슬롯 9,Wapenslot 9,Våpen 9,Broń 9,Arma 9,,Arma 9,Девятое оружие,Оружје 9,Vapen 9,Silah 9,Зброя 9,Оръжие 9 +Weapon 10,CNTRLMNU_SLOT0,,,,Slot zbraně 10,Våben 10,Waffe 10,Όπλο 0,Armilo 10,Arma 10,,Aselokero 0,Emplacement D'Arme 0,0. fegyver,Slot arma 0,武器スロット 0,무기 슬롯 0,Wapenslot 0,Våpen 10,Broń 10,Arma 10,,Arma 0,Десятое оружие,Оружје 0,Vapen 10,Silah 10,Зброя 0,Оръжие 10 +Inventory,CNTRLMNU_INVENTORY,,,,Inventář,Inventar,Inventar,Άντικείμενα,Inventaro,Inventario,,Varusteet,Inventaire,Eszköztár beállítások testreszabása,Inventario,所持品,인벤토리,Inventaris,Inventar,Ekwipunek,Inventário,,Inventar,Инвентарь,Инвентар,Inventarium,Envanter,Інвентар,Инвентар +Activate item,CNTRLMNU_USEITEM,,,,Aktivovat předmět,Aktiver genstand,Gegenstand aktivieren,Ενεργοποίηση αντικείμενου,Aktivigi objekton,Activar objeto,,Aktivoi varuste,Activer objet,Eszköz használata,Attiva oggetto,アイテムを使用,선택한 아이템 사용,Item activeren,Aktiver gjenstand,Użyj przedmiot,Ativar item,,Activează obiectul,Использовать предмет,Активирај предмет,Aktivera föremål,Öğeyi etkinleştir,Активувати предмет,Използвай предмета +Activate all items,CNTRLMNU_USEALLITEMS,,,,Aktivovat všechny předměty,Aktivering af alle genstande,Alle Gegenstände aktivieren,Ενεργοποίησε όλα τα αντικείμενα,Aktivigi ĉiujn objektojn,Activar todos los objetos,,Aktivoi kaikki varusteet,Activer tous les objets,Minden eszköz használata,Attiva tutti gli oggetti,全てのアイテムを使用,모든 아이템 사용,Activeer alle items,Aktiver alle gjenstander,Użyj wszystkie przedmioty,Ativar todos os itens,,Activează tot inventarul,Использовать все предметы,Активирај све предмете,Aktivera alla föremål,Tüm öğeleri etkinleştirin,Активувати усі предмети,Използвай всички предмети +Next item,CNTRLMNU_NEXTITEM,,,,Další předmět,Næste genstand,Nächster Gegenstand,Επόμενο αντικείμενο,Sekva objekto,Objeto siguiente,,Seuraava varuste,Objet suivant,Következő eszköz,Oggetto successivo,次のアイテム,다음 아이템,Volgende item,Neste element,Następny przedmiot,Item seguinte,,Următorul obiect,Следующий предмет,Следећи предмет,Nästa objekt,Sonraki madde,Наступний предмет,Следващ предмет +Previous item,CNTRLMNU_PREVIOUSITEM,,,,Předchozí předmět,Forrige genstand,Vorheriger Gegenstand,Προηγούμενο αντικείμενο,Antaŭa objekto,Objeto anterior,,Edellinen varuste,Objet précédent,Előző eszköz,Oggetto precedente,前のアイテム,이전 아이템,Vorige item,Forrige element,Poprzedni przedmiot,Item anterior,,Obiect anterior,Предыдущий предмет,Претходни предмет,Föregående objekt,Önceki madde,Попередній предмет,Предишен предмет +Customize Map Controls,MAPCNTRLMNU_TITLE,most are not used yet but will be,,,Nastavení ovládání mapy,Tilpas kontrolelementer til kortet,Automapsteuerung einstellen,Προσαρμογή στοιχείων ελέγχου χάρτη,Adapti map-regilojn,Cambiar controles del mapa,,Kartanohjausasetukset,Contrôles Carte,Térkép irányításának testreszabása,Personalizza i controlli mappa,マップコントロール カスタマイズ,미니맵 단축키 설정,Kaartcontroles aanpassen,Tilpass kartkontroller,Ustaw klawisze mapy,Peronalizar comandos do mapa,,Personalizare schemă de control a hărții,Клавиши управления автокартой,Промени контроле мапе,Anpassa kartkontroller,Harita Kontrollerini Özelleştirme,Клавіші керування автокартою,Персонализиране контролите за картата +Map Controls,MAPCNTRLMNU_CONTROLS,,,,Mapa,Kontrolelementer til kort,Automapsteuerung,Έλεγχοι χάρτη,Map-regiloj,Controles del mapa,,Kartanohjaus,Contrôles de la carte,Térkép irányítása,Controlli mappa,マップコントロール,미니맵 조정,Kaartcontroles,Kartkontroller,Klawisze mapy,Comandos do mapa,,Schemă de control a hărtii,Автокарта,Контроле мапе,Kontroller för kartor,Harita Kontrolleri,Автокарта,Контроли за карта +Pan left,MAPCNTRLMNU_PANLEFT,,,,Doleva,Panorere til venstre,Nach links,Μετακίνηση προς τα αριστερά,Alturni maldekstren,Mover a la izquierda,,Panoroi vasemmalle,Aller à gauche,Balra igazítás,Sposta a sinistra,左に振る,왼쪽으로 이동,Pan links,Panorer til venstre,Przesuń w lewo,Mover para a esquerda,,Mutare spre stânga,Сдвиг влево,Лево,Panorera till vänster,Sola kaydırın,Зсув вліво,Преместване наляво +Pan right,MAPCNTRLMNU_PANRIGHT,,,,Doprava,Panorering til højre,Nach rechts,Μετακίνηση προς τα δεξιά,Alturni dekstren,Mover a la derecha,,Panoroi oikealle,Aller à droite,Jobbra igazítás,Sposta a destra,右に振る,오른쪽으로 이동,Pan rechts,Panorer til høyre,Przesuń w prawo,Mover para a direita,,Mutare spre dreapta,Сдвиг вправо,Десно,Panorera till höger,Sağa kaydırın,Зсув вправо,Преместване на дясно +Pan up,MAPCNTRLMNU_PANUP,,,,Nahoru,Panorere op,Nach oben,Μετακίνηση προς τα πάνω,Alturni supren,Mover hacia arriba,,Panoroi ylös,Aller en haut,Felfele igazítás,Sposta sopra,上に振る,위쪽으로 이동,Pan omhoog,Panorer opp,Przesuń w górę,Mover para cima,,Mutare în sus,Сдвиг вверх,Горе,Panorera uppåt,Yukarı kaydırın,Зсув вверх,Преместване на горе +Pan down,MAPCNTRLMNU_PANDOWN,,,,Dolů,Panorere ned,Nach unten,Μετακίνηση προς τα κάτω,Alturni malsupren,Mover hacia abajo,,Panoroi alas,Aller en bas,Lefele igazítás,Sposta sotto,下に振る,아래쪽으로 이동,Pan neer,Panorer ned,Przesuń w dół,Mover para baixo,,Mutare în jos,Сдвиг вниз,Доле,Panorera ner,Aşağı kaydırın,Зсув вниз,Преместване на долу +Zoom in,MAPCNTRLMNU_ZOOMIN,,,,Přiblížit,Zoom ind,Reinzoomen,Μεγέθυνση,Zomi,Acercar,,Lähennä,Zoom avant,Ráközelítés,Ingrandisci,ズームイン,줌 확대,Inzoomen,Zoom inn,Przybliż,Ampliar,,Apropriere Cameră,Приблизить,Увеличати,Zooma in,Yakınlaştır,Наблизити,Приближи +Zoom out,MAPCNTRLMNU_ZOOMOUT,,,,Oddálit,Zoom ud,Rauszoomen,Σμίκρυνση,Malzomi,Alejar,,Loitonna,Zoom arrière,Távolítás,Rimpicciolisci,ズームアウト,줌 축소,Uitzoomen,Zoom ut,Oddal,Afastar,,Depărtare Cameră,Отдалить,Одзумирати,Zooma ut,Uzaklaştır,Віддалити,Отдалечи +Toggle zoom,MAPCNTRLMNU_TOGGLEZOOM,,,,Přiblížení vyp./zap.,Skift mellem zoom,Zoom an/aus,Εναλλαγή ζουμ,Baskuligi zomon,Alternar zoom,,Zoomauksen vaihtokytkin,Zoom On/Off,Közelítés átkapcsolása,Abilita/disabilita zoom,ズーム切替,표준배율 조정,Omschakelen van de zoom,Veksle mellom zoom,Przełącz przybliżanie,Ativar/desativar zoom,,Comutator Zoom,Приближение (перекл.),Укључи зум,Växla zoom,Yakınlaştırmayı aç / kapat,Перемикач наближення,Приближи постоянно +Toggle follow,MAPCNTRLMNU_TOGGLEFOLLOW,,,,Sledování hráče vyp./zap.,Skift følge,Folgen an/aus,Εναλλαγή ακολουθίας,Baskuligi sekvon,Alternar seguimiento,,Seuraamistilan vaihtokytkin,Suivi On/Off,Követés átkapcsolása,Abilita/disabilita scorrimento mappa,追従切替,추적모드 조정,Schakelen volgen,Veksle følge,Przełącz śledzenie,Ativar/desativar seguimento,,Comutator urmărire jucător,Привязка к игроку (перекл.),Укључи праћење,Växla följning,Takip etmeyi değiştir,Перемикач слідування за гравцем,Следвай постаянно +Toggle grid,MAPCNTRLMNU_TOGGLEGRID,,,,Mřížka vyp./zap.,Skift gitter,Gitter an/aus,Εναλλαγή πλέγματος,Baskuligi kradon,Alternar cuadrícula,,Ruudukon vaihtokytkin,Grille On/Off,Rács kapcsolása,Abilita/disabilita la griglia,グリッド切替,그리드 조정,Kiesnet,Veksle rutenett,Przełącz siatkę,Ativar/desativar grade,,Comutator grilă,Сетка (перекл.),Укључи координатну мрежу,Växla rutnät,Izgarayı değiştir,Перемикач сітки,Включи координатна мрежа +Toggle rotate,MAPCNTRLMNU_ROTATE,,,,Otáčení vyp./zap.,Skift til rotere,Rotation an/aus,Εναλλαγή περιστροφής,Baskuligi turnadon,Alternar rotación,,Kääntämisen vaihtokytkin,Rotation On/Off,Forgás kapcsolása,Abilita/disabilita la rotazione,回転切替,,Toggle rotatie,Veksle mellom rotasjon,Przełącz obracanie,Ativar/desativar rotação,,Comutator rotire,Вращение (перекл.),Укључи ротацију,Växla rotera,Döndürmeyi değiştir,Перемикач обертання,Завъртане (превключване) +Toggle texture,MAPCNTRLMNU_TOGGLETEXTURE,,,,Textury vyp./zap.,Skift tekstur,Texturen an/aus,Εναλλαγή υφής,Baskuligi teksturon,Alternar textura,,Pintakuvioinnin vaihtokytkin,Textures On/Off,Textúra kapcsolása,Abilita/disabilita le texture,テクスチャ切替,미니맵 텍스쳐 조정,Toggle textuur,Veksle tekstur,Przełącz tekstury,Ativar/desativar texturas,,Comutator mod texturat,Текстуры (перекл.),Укључи текстуру,Växla textur,Dokuyu değiştir,Перемикач текстур, +Toggle automap,CNTRLMNU_AUTOMAP,,,,Otevřít/zavřít automapu,Skift til automap,Automap an/aus,Εναλλαγή automap,Baskuligi aŭtomatan mapon,Alternar automapa,,Kytke automaattikartta päälle/pois,Ouvrir/Fermer Carte,Térkép ki/bekapcsolása,Abilita/disabilita l'automappa,オートマップの切替,오토맵 조정,Automap aan/uit,Veksle mellom automap,Włącz mapę,Ativar/desativar automapa,,Comutator hartă computerizată,Автокарта (перекл.),Прикажи аутомапу,Växla automap,Otomatik haritayı değiştir,Перемикач автокарти, +Chasecam,CNTRLMNU_CHASECAM,,,,Kamera z třetí osoby,Chasecam,Verfolgerkamera,,Ĉaskamerao,Cámara de seguimiento,,Seurantakamera,Caméra 3ième personne,Külsőnézetű kamera,Telecamera di inseguimento,背後視点,3인칭 카메라,,,Kamera Śledzenia,Câmera em terceira pessoa,Câmera em terceira-pessoa,Cameră urmăritoare,Вид от 3-го лица,Чејс-кем,,,Вид від 3-го лиця, +Screenshot,CNTRLMNU_SCREENSHOT,,,,Pořídit snímek obrazovky,Skærmbillede,,Στιγμιότυπο,Ekrankopio,Captura de pantalla,,Kuvakaappaus,Capture d'écran,Képernyő lefényképezése,Cattura schermo,画面キャプチャ,스크린샷,,Skjermbilde,Zrzut ekranu,Captura de tela,,Captură ecran,Снимок экрана,Усликај,Skärmdump,Ekran görüntüsü,Скріншот, +Open console,CNTRLMNU_CONSOLE,,,,Otevřít konzoli,Åbn konsollen,Konsole öffnen,Ανοίξτε την κονσόλα,Malfermi konzolon,Abrir consola,,Avaa konsoli,Ouvrir Console,Konzol megnyitása,Apri la console,コンソールを開く,콘솔 열기,Open console,Åpne konsoll,Otwórz konsolę,Abrir console,Abrir consola,Deschide consola,Открыть консоль,Отвори консолу,Öppna konsolen,Açık konsol,Відкрити консоль, +Pause,CNTRLMNU_PAUSE,,,,Pauza,,,Πάυση,Paŭzo,Pausa,,Tauko,,Szünet,Pausa,ポーズ,일시정지,Pauze,,Pauza,Pausar,,Pauză,Пауза,Пауза,Pausa,Duraklat,Пауза, +Increase Display Size,CNTRLMNU_DISPLAY_INC,,,,Zvětšit velikost obrazovky,Forøg visningsstørrelsen,Anzeige vergrößern,Αύξηση μεγέθους οθόνης,Kreskigi ekrangrandon,Agrandar ventana,,Suurenna näytön kokoa,Agrandir l'affichage,Képméret növelése,Aumenta la dimensione del display,画面サイズを拡大,화면 크기 늘리기,Vergroot het display,Øk visningsstørrelse,Powiększ Rozmiar Wyświetlania,Aumentar tamanho da exibição,Aumentar Tamanho do Ecrã,Mărire ecran,Увеличить размер экрана,Повећајте величину екрана,Öka skärmstorleken,Ekran Boyutunu Artırın,Збільшити розмір екрану, +Decrease Display Size,CNTRLMNU_DISPLAY_DEC,,,,Zmenšit velikost obrazovky,Formindsk skærmstørrelse,Anzeige verkleinern,Μείωση μεγέθους οθόνης,Malkreskigi ekrangrandon,Reducir ventana,,Pienennä näytön kokoa,Réduire l'affichage,Képméret csökkentése,Riduci la dimensione del display,画面サイズを縮小,화면 크기 줄이기,Verlaag het display,Reduser visningsstørrelse,Pomniejsz Rozmiar Wyświetlania,Reduzir tamanho da exibição,Diminuir Tamanho do Ecrã,Micșorare ecran,Уменьшить размер экрана,Смањите величину екрана,Minska visningsstorleken,Ekran Boyutunu Azaltma,Зменшити розмір екрану, Open Help,CNTRLMNU_OPEN_HELP,,,,Nápověda,Åbn hjælp,Hilfe öffnen,Άνοιγμα βοήθειας,Malfermi helpon,Abrir ayuda,,Avaa ohje,Ouvrir Aide,Segítség előhozása,Apri la guida,"ヘルプを開く -",도움말 열기,Open hulp,Åpne Hjelp,Otwórz Pomoc,Abrir ajuda,,Deschide Ajutor,Экран помощи,Отвори помоћ,Açık Yardım,Відкрити екран допомоги, -Open Save Menu,CNTRLMNU_OPEN_SAVE,,,,Uložit hru,Åbn menuen Gem,Speichermenü öffnen,,Malfermi konservmenuon,Menú de guardar partida,,Avaa tallennusvalikko,Ouvrir Menu Sauvegarde,Mentés menü előhozása,Apri il menu di salvataggio,セーブメニューを開く,저장 화면 열기,Menu opslaan openen,Åpne Lagre-menyen,Otwórz Menu Zapisu,Abrir menu de salvar,Abrir Menu de Gravação,Deschide meniul de salvare,Меню сохранения игры,Отвори сачуване игре,Kaydet Menüsünü Aç,Меню збереженнь, -Open Load Menu,CNTRLMNU_OPEN_LOAD,,,,Načíst hru,Åbn indlæsningsmenuen,Lademenü öffnen,,Malfermi ŝargmenuon,Menú de cargar partida,,Avaa latausvalikko,Ouvrir Menu Chargement,Betöltés menü előhozása,Apri il menu di caricamento,ロードメニューを開く,불러오기 화면 열기,Menu laden openen,Åpne Last-menyen,Otwórz Menu Wczytania,Abrir menu de carregar,,Deschide meniul de încărcare,Меню загрузки игры,Отвори игре за учитати,Yük Menüsünü Aç,Меню завантаженнь, -Open Options Menu,CNTRLMNU_OPEN_OPTIONS,,,,Nastavení,Åbn menuen Indstillinger,Optionsmenü öffnen,,Malfermi agordmenuon,Menú de opciones,,Avaa asetusvalikko,Ouvrir Menu Options,Beállítások menü előhozása,Apri il menu delle opzioni,オプションメニューを開く,설정 화면 열기,Menu Opties openen,Åpne Alternativer-menyen,Otwórz Menu Opcji,Abrir menu de opções,,Deschide setările,Главное меню настроек,Отвори мени опција,Seçenekler Menüsünü Aç,Головне меню параметрів, -Open Display Menu,CNTRLMNU_OPEN_DISPLAY,,,,Nastavení grafiky,Åbn menuen Visning,Anzeigemenü öffnen,,Malfermi ekranmenuon,Menú de opciones de visualización,,Avaa näyttövalikko,Ouvrir Menu Affichage,Megjelenítés menü előhozása,Apri il menu del display,ディスプレイメニューを開く,디스플레이 화면 열기,Displaymenu openen,Åpne visningsmeny,Otwórz Menu Wyświetlania,Abrir menu de vídeo,,Deschide setările de afișare,Меню настроек видео,Отвори мени приказа,Ekran Menüsünü Aç,Параметри відео, -Quicksave,CNTRLMNU_QUICKSAVE,,,,Rychlé uložení,Quicksave,Schnellspeichern,,Rapidkonservo,Guardado rápido,,Pikatallenna,Sauv. Rapide,Gyorsmentés,Salvataggio rapido,クイックセーブ,빠른 저장,Snel opslaan,Hurtiglagring,Szybki Zapis,Salvar rapidamente,Gravação rápida,Salvare rapidă,Быстрое сохранение,Брзо-сачувај,Hızlı Tasarruf,Швидке збереження, -Quickload,CNTRLMNU_QUICKLOAD,,,,Rychlé načtení,Quickload,Schnellladen,,Rapidŝargo,Cargado rápido,,Pikalataa,Charg. Rapide,Gyorstöltés,Caricamento rapido,クイックロード,빠른 불러오기,Snel laden,Hurtiglasting,Szybkie Wczytanie,Carregar rapidamente,,Încărcare rapidă,Быстрая загрузка,Брзо-учитај,Hızlı Yükleme,Швидке завантаження, -Exit to Main Menu,CNTRLMNU_EXIT_TO_MAIN,,,,Odejít do hlavního menu,Afslut til hovedmenu,Zurück zum Hauptmenü,,Eliri al ĉefa menuo,Salir al menú principal,,Poistu päävalikkoon,Sortie Menu Principal,Kilépés a főmenübe,Esci dal menu principale,メインメニューに戻る,메뉴로 나오기,Afsluiten naar het hoofdmenu,Avslutt til hovedmeny,Wyjdź do Głównego Menu,Sair para o menu principal,,Revenire la meniul principal,Выход в главное меню,Изађи у главни мени,Ana Menüden Çıkış,Вихід в головне меню, -Toggle Messages,CNTRLMNU_TOGGLE_MESSAGES,,,,Povolit/skrýt oznámení,Skift mellem meddelelser,Nachrichten an/aus,,Baskuligi mesaĝojn,Alternar mensajes,,Kytke viestit päälle tai pois,Act./Déasct. Messages,Üzenetek kapcsolása,Toggle messaggi,メッセージ表示の切替,메시지 토글,Berichten aan/uit,Veksle meldinger,Włącz / Wyłącz Wiadomości,Ativar/desativar mensagens,,Comutator mesaje,Переключение сообщений,Таглави поруке,Mesajları Değiştir,Перемикач повідомлень, -Quit Game,CNTRLMNU_MENU_QUIT,,,,Ukončit hru,Afslut spil,Spiel beenden,Στάματα το παιχνίδι,Mallanĉi ludon,Salir del juego,,Lopeta peli,Quitter le Jeu,Kilépés a játékból,Esci dal gioco,ゲームを終了,게임 종료,Stop het spel,Avslutt spill,Wyjdź z Gry,Sair do jogo,,Ieși din Joc,Выход,Изађи из игре,Oyundan Çık,Вихід, -Adjust Gamma,CNTRLMNU_ADJUST_GAMMA,,,,Nastavit gamu,Juster Gamma,Gamma-Anpassung,,Agordi gamaon,Ajustar gama,,Säädä gammaa,Ajuster Gamma,Gamma állítása,Aggiustamento Gamma,ガンマ値を調整,감마 조정,Gamma aanpassen,Juster gamma,Dostosuj Gammę,Ajustar gama,,Ajustare gamma,Настройка гаммы,Подесите осветљење,Gama Ayarlama,Парамети гамми, -,,Mouse,,,,,,,,,,,,,,,,,,,,,,,,,, -Enable mouse,MOUSEMNU_ENABLEMOUSE,,,,Povolit myš,Aktiver mus,Maus aktiv,Ενεργοποίηση ποντικιόυ,Ebligi muson,Habilitar ratón,,Ota hiiri käyttöön,Activer Souris,Egér engedélyezése,Abilita il mouse,マウスの使用,마우스 사용,Muis inschakelen,Aktiver mus,Włącz myszkę,Ativar mouse,Permitir uso do rato,Activare mouse,Использовать мышь,Укључи миш,Fareyi etkinleştir,Використовувати миш, -Enable mouse in menus,MOUSEMNU_MOUSEINMENU,,,,Povolit myš v nabídkách,Aktiver mus i menuer,Maus aktiv in Menüs,Ενεργοποίηση ποντικιόυ στα μενού,Ebligi muson en menuoj,Usa ratón en los menús,,Ota hiiri käyttöön valikoissa,Activer Souris dans les Menus,Egér engedélyezése a menüben,Abilita il mouse nei menu,メニューでのマウスの使用,메뉴에서 마우스 사용,Muis in menu's inschakelen,Aktiver mus i menyer,Włącz myszkę w menu,Ativar mouse nos menus,Permitir rato nos menus,Activare mouse în meniuri,Использовать мышь в меню,Укључи миш у менијима,Menülerde fareyi etkinleştir,Використовувати миш в меню, -Show back button,MOUSEMNU_SHOWBACKBUTTON,,,,Zobrazit tlačítko zpět,Vis tilbage-knappen,Zeige Zurück-Knopf,,Montri reen-butonon,Mostrar botón de retroceso,,Näytä taaksenäppäin,Afficher le bouton retour,Vissza gomb mutatása,Mostra il bottone per tornare indietro,戻るボタンを表示,뒤로가기 버튼 보이기,Toon terug knop,Vis tilbake-knapp,Pokaż przycisk powrotu,Exibir botão de voltar,,Afișare buton de întoarcere,Расположение кнопки «назад»,Прикажи тастер за назад,Geri düğmesini göster,"Положення кнопки ""назад""", -Cursor,MOUSEMNU_CURSOR,,,,Kurzor,Markør,,,Musmontrilo,,,Osoitin,Curseur,Egérmutató,Cursore,カーソル,커서,,Markør,Kursor,Cursor,,,Курсор,Курсор,İmleç,Курсор, -Horizontal sensitivity,MOUSEMNU_SENSITIVITY_X,,,,Horizontální citlivost,Vandret følsomhed,Horizontale Empfindlichkeit,Οριζόντια ευαισθησία,Horizontala sentemo,Sensibilidad horizontal,,Vaakasuuntainen herkkyys,Sensibilité horizontale,Vízszintes érzékenység,Sensibilità orizzontale,水平感度,수평 감도,Horizontale gevoeligheid,Horisontal følsomhet,Czułość pozioma,Sensibilidade horizontal,,Sensibilitate orizontală,Горизонтальная чувствительность,Хоризонтална осетљивост,Yatay hassasiyet,Горизонтальна чутливість, -Vertical sensitivity,MOUSEMNU_SENSITIVITY_Y,,,,Vertikální citlivost,Lodret følsomhed,Vertikale Empfindlichkeit,Κάθετη ευαισθησία,Vertikala sentemo,Sensibilidad vertical,,Pystysuuntainen herkkyys,Sensibilité verticale,Függőleges érzékenység,Sensibilità verticale,垂直感度,수직 감도,Verticale gevoeligheid,Vertikal følsomhet,Czułość pionowa,Sensibilidade vertical,,Sensibilitate verticală,Вертикальная чувствительность,Вертикална осетљивост,Dikey hassasiyet,Вертикальна чутливість, -Smooth mouse movement,MOUSEMNU_SMOOTHMOUSE,,,,Vyhladit pohyb myši,Jævn bevægelse af musen,Mausbewegung glätten,,Glata musmovo,Mov. fluido del ratón,,Sulava hiiren liike,Lissage Souris,Egérmozgás simítása,Movimento del mouse liscio,マウス操作を滑らかにする,부드러운 움직임,Vlotte muisbeweging,Jevn musebevegelse,Gładki ruch myszki,Suavizar movimento do mouse,Movimento fluído do rato,Mișcare mouse fină,Плавное перемещение,Глатки окрет,Pürüzsüz fare hareketi,Плавний рух миші, -Turning speed,MOUSEMNU_TURNSPEED,,,,Rychlost otáčení,Drejehastighed,Umdrehgeschwindigkeit,,Turnorapido,Velocidad de giro,,Kääntymisnopeus,Vitesse pour tourner,Fordulás sebessége,Velocità di rotazione,旋回速度,회전 속도,Draaisnelheid,Dreiehastighet,Szybkość obracania się,Velocidade de giro,,Viteză rotire,Скорость поворота,Брзина окрета,Dönüş hızı,Швидкість повороту, -Mouselook speed,MOUSEMNU_MOUSELOOKSPEED,,,,Rychlost pohledu nahoru/dolů,Hastighed for mus-look,Mausblick-Geschwindigkeit,,Musrigarda rapido,Veloc. de vista con ratón,,Katselunopeus,Vitesse Vue Souris,Egérnézés sebessége,Velocità di rotazione della vista,上下視点速度,마우스룩 속도,Mouselook snelheid,Muselook-hastighet,Szybkość rozglądania się myszką,Velocidade da visão com mouse,Velocidade de vista com rato,Viteză privire în jur cu mouse,Скорость обзора,Брзина гледања мишем,Mouselook hızı,Швидкість огляду, -Forward/Backward speed,MOUSEMNU_FORWBACKSPEED,,,,Rychlost pohybu vpřed/vzad,Hastighed fremad/tilbage,Vor/Rückwärtsgeschwindigkeit,,Antaŭa/Malantaŭa rapido,Veloc. de avance/retroceso,,Eteen-/taaksepäin liikkeen nopeus,Vitesse Avancer/reculer,Előre/Hátra sebesség,Velocità avanti/indietro,"前進/後退速度 -",전진/후진 속도,Voorwaartse/achterwaartse snelheid,Hastighet forover/bakover,Szybkość chodzenia do przodu/do tyłu,Velocidade de deslocamento para frente/trás,,Viteză deplasare față/spate,Скорость передвижения,Брзина окрета напред/уназад,İleri/Geri hız,Швидкість руху вперед/назад, -Strafing speed,MOUSEMNU_STRAFESPEED,,,,Rychlost pohybu do stran,Strafing-hastighed,Seitwärtsgeschwindigkeit,,Flankmova rapido,Veloc. de mov. lateral,,Sivuttaisastunnan nopeus,Vitesse Gauche/Droite,Oldalazás sebessége,Velocità movimento laterale,横移動速度,좌진/우진 속도,Zijdelings snelheid,Hastigheten for stansing,Szybkość uników,Velocidade de deslocamento lateral,,Viteză deplasare în diagonală,Скорость движения боком,Брзина стрејфа,Strafe hızı,Швидкість руху боком, -Always Mouselook,MOUSEMNU_ALWAYSMOUSELOOK,,,,Vždy se rozhlížet myší,Altid mus-look,Mausblick immer an,Πάντα κοίτα με το ποντίκι,Ĉiam musrigardi,Siempre mirar con ratón,,Jatkuva hiirikatselu,Toujours vue Souris,Mindig egérrel nézelődés,Vista col mouse,常に上下視点をオン,마우스룩 사용,Altijd Mouselook,Alltid muselook,Zawsze zezwalaj na rozglądanie się myszką,Visão com mouse sempre ativada,Vista com rato sempre ligada,Privire în jur cu mouse permanentă,Обзор мышью,Гледање мишем,Her zaman Mouselook,Огляд мишкою, -Invert Mouse Y,MOUSEMNU_INVERTMOUSE,,,,Vertikálně obrátit myš,Inverter mus Y,Maus Y invertieren,,Inversi muson Y,Invertir ratón Y,,Käännä hiiri Y,Inverser Souris Y,Y tengely megfordítása,Mouse Y invertito,視点操作反転,마우스 방향 전환,Muis-Y-as omkeren,Inverter mus Y,Odwróć Myszkę - Oś Y,Inverter eixo Y do mouse,Inverter rato,Inversare axă mouse Y,Инверт. мышь по вертикали,Инвертуј миш Y,Fare Y'yi Ters Çevir,Інвертувати мишу Y, -Invert Mouse X,MOUSEMNU_INVERTMOUSEX,,,,Horizontálně obrátit myš,Inverter mus X,Maus X invertieren,,Inversi muson X,Invertir ratón X,,Käännä hiiri X,Inverser Souris X,X tengely megfordítása,Mouse X invertito,視点操作反転,마우스 방향 전환,Muis-X-as omkeren,Inverter mus X,Odwróć Myszkę - Oś X,Inverter eixo X do mouse,Inverter rato X,Inversare axă mouse X,Инверт. мышь по горизонтали,Инвертуј миш X,Fare X'i Ters Çevir,Інвертувати мишу Х, -Upper left,OPTVAL_UPPERLEFT,,,,Vlevo nahoře,Øverste venstre,Oben links,,Supra maldekstre,Sup. izquierda,,Ylävasemmalla,Supérieur gauche,Bal fent,Superiore sinistro,左上,왼쪽 위,Linksboven,Øvre venstre,Lewy górny róg,Esquerda superior,,Stânga sus,Вверху слева,Горње лево,Sol üst,Вгорі ліворуч, -Upper right,OPTVAL_UPPERRIGHT,,,,Vpravo nahoře,Øvre højre,Oben rechts,,Supra dekstre,Sup. derecha,,Yläoikealla,Supérieur droite,Jobb fent,Superiore destro,右上,오른쪽 위,Rechtsboven,Øverst til høyre,Prawy górny róg,Direita superior,,Dreapta sus,Вверху справа,Горње десно,Sağ üst,Вгорі праворуч, -Lower left,OPTVAL_LOWERLEFT,,,,Vlevo dole,Nederste venstre,Unten links ,,Suba maldekstre,Inf. izquierda,,Alavasemmalla,Inférieur gauche,Bal lent,Inferiore sinistro,左下,왼쪽 밑,Linksonder,Nedre venstre,Lewy dolny róg,Esquerda inferior,,Stânga jos,Внизу слева,Доње лево,Sol alt,Внизу ліворуч, -Lower right,OPTVAL_LOWERRIGHT,,,,Vpravo dole,Nederste højre,Unten rechts,,Suba dekstre,Inf. derecha,,Alaoikealla,Inférieur droite,Jobb lent,Inferiore destro,右下,오른쪽 밑,Rechtsonder,Nedre høyre,Prawy dolny róg,Direita inferior,,Dreapta jos,Внизу справа,Доње десно,Sağ alt,Внизу праворуч, -Touchscreen-like,OPTVAL_TOUCHSCREENLIKE,,,,Jako dotyková obrazovka,Touchscreen-lignende,Wie auf einem Touchscreen,,Tuŝekraneca,Pant. táctil,,Kosketusnäyttömäinen,Style écran tactile,Érintőképernyő-szerű,Come il Touchscreen,タッチスクリーン式,터치스크린 같게,Touchscreen-achtige,Berøringsskjerm-lignende,Jak ekrean dotykowy,Estilo touchscreen,,Precum touchscreen,Как сенсорный экран,Као додирни екран,Dokunmatik ekran benzeri,Як сенсорний екран, -Simple arrow,OPTSTR_SIMPLEARROW,,,,Jednoduchý kurzor,Simpel pil,Einfacher Pfeil,,Simpla sago,Flecha simple,,Yksinkertainen nuoli,Flèche simple,Sima nyíl,Freccia semplice,シンプル,기본 커서,Eenvoudige pijl,Enkel pil,Prosta strzałka,Seta simples,Cursor simples,Săgeată simplă,Стрелка,Стрелица,Basit ok,Стрілка, -System cursor,OPTSTR_SYSTEMCURSOR,,,,Systémový kurzor,Systemcursor,Systemcursor,Δείκτης συστήματος,Sistema kursoro,Cursor del sistema,,Järjestelmän osoitin,Curseur Système,Rendszer egérmutatója,Cursore di sistema,システム,시스템 커서,Systeemcursor,Systemmarkør,Kursor systemu,Cursor do sistema,,Cursor simplu,Системный курсор,Системска стрелица,Sistem imleci,Системний курсор, -Default,OPTVAL_DEFAULT,,,,Výchozí,Standard,Standard,Προεπιλογή,Defaŭlta,Por defecto,,Oletus,Défaut,Alapbeállítás,Predefinito,デフォルト,기본 설정,Standaard,Standard,Domyślne,Padrão,,Implicit,По умолчанию,Подраз.,Varsayılan,За замовчуванням, -,,Controller,,,,,,,,,,,,,,,,,,,,,,,,,, -Configure Controller,JOYMNU_TITLE,,,,Konfigurace ovladače,Konfigurer controller,Controller konfigurieren,,Agordi ludregilon,Configurar mando,,Peliohjainasetukset,Configurer Mannette,Kontroller testreszabása,Configura il controller,コントローラー構成:,컨트롤러 구성,Controller configureren,Konfigurer kontrolleren,Konfiguruj Kontroler,Configurar controle,Configurar Comando,Configurare controller,Настроить контроллер,Конфигурација контролера,Denetleyiciyi Yapılandırma,Параметри контролера, -Controller Options,JOYMNU_OPTIONS,,,,Ovladač,Indstillinger for styreenhed,Controlleroptionen,,Ludregilo-agordoj,Opciones del mando,,Peliohjainasetukset,Options Mannette,Kontroller beállítások,Opzioni del controller,コントローラー設定,컨트롤러 설정,Controller opties,Alternativer for styreenhet,Opcje Kontrolera,Opções de controle,Opções do Comando,Setări controller,Настройки контроллера,Подешавања контролера,Kontrolör Seçenekleri,Налаштування контролера, -Block controller input in menu,JOYMNU_NOMENU,,,,Zakázat ovladač v nabídkách,Bloker controller input i menuen,Blockiere Controllereingabe im Menü,,Blokigi ludregilan enigon en menuo,Bloq. entrada de mando en menú,,Estä ohjainsyötteet valikoissa,Bloquer manette dans les menus,Kontroller ne működjön a menüben,Blocca l'input del controller nei menu,メニューではコントローラーを無視,메뉴에서 컨트롤러 끄기,Blokkeer de controller in het menu,Blokker kontrollerinngang i menyen,Blokuj wejście kontrolera w menu,Bloquear controle no menu,Bloquear comando no menu,Blocare comenzi controller în meniu,Отключить контроллер в меню,Блокирај улаз контролера у менију,Menüde kontrolör girişini engelle,Відключити контролер в меню, -Enable controller support,JOYMNU_ENABLE,,,,Povolit podporu pro ovladače,Aktivering af controllerunderstøttelse,Erlaube Controllerunterstützung,,Ŝalti ludregilan subtenon,Activar soporte de mandos,,Ota käyttöön peliohjaintuki,Activer support contrôleur,Kontroller támogatás engedélyezése,Abilita il supporto del controller,コントローラーサポート許可,컨트롤러 지원 허용,Controllerondersteuning inschakelen,Aktiver støtte for styreenhet,Włącz wsparcie kontrolera,Ativar detecção de controles,,Activare support controller,Включить поддержку контроллера,Омогући подршку за контролере,Denetleyici desteğini etkinleştir,Увімкнути підтримку контролера, -Enable DirectInput controllers,JOYMNU_DINPUT,,,,Povolit ovladače DirectInput,Aktivering af DirectInput-controllere,Erlaube DirectInput-Controller,,Ŝalti DirectInput ludregilojn,Usa controles DirectInput,,Ota käyttöön DirectInput-ohjaimet,Activer contrôleurs DirectInput,DirectInput kontrollerek engedélyezése,Abilita i controlli DirectInput,ダイレクトインプットコントローラー許可,다이렉트 인풋 컨트롤러 허용,DirectInput-controllers inschakelen,Aktiver DirectInput-kontrollere,Włącz kontrolery DirectInput,Ativar controles DirectInput,,Activare controlere DirectInput,Включить контроллеры через DirectInput,Омогући директинпут контролере,DirectInput denetleyicilerini etkinleştirin,Увімкнути контролери DirectInput, -Enable XInput controllers,JOYMNU_XINPUT,,,,Povolit ovladače XInput,Aktiver XInput-controllere,Erlaube XInput-Controller,,Ŝalti XInput ludregilojn,Usa controles XInput,,Ota käyttöön XInput-ohjaimet,Activer contrôleurs XInput,XInput kontrollerek engedélyezése,Abilita i controlli XInput,Xinput コントローラー許可,X인풋 컨트롤러 허용,XInput-controllers inschakelen,Aktiver XInput-kontrollere,Włącz kontrolery XInput,Ativar controles XInput,,Activare controlere XInput,Включить контроллеры через XInput,Омогући Иксинпут контролере,XInput denetleyicilerini etkinleştirin,Увімкнути контролери XInput, -Enable raw PlayStation 2 adapters,JOYMNU_PS2,,,,Povolit ovladače PlayStation 2,Aktiver rå PlayStation 2-adaptere,Erlaube Playstation 2-Controller,,Ŝalti krudajn adaptilojn de PlayStation 2 ,Usa adaptadores de PlayStation 2,,Ota käyttöön raa'at PlayStation 2 -adapterit,Activer adaptateurs PS2 bruts,PlayStation 2 adapterek engedélyezése,Abilita gli adattatori raw PlayStation 2,PlayStation2 アダプター許可,PS2 어뎁터 허용,Raw PlayStation 2-adapters inschakelen,Aktiver rå PlayStation 2-adaptere,Włącz adaptery PlayStation 2,Ativar adaptadores de PlayStation 2,,Activare adaptoare PS2,Использовать адаптеры PlayStation 2 напрямую,Омогући сирове Плејстејшн 2 адаптере,Ham PlayStation 2 adaptörlerini etkinleştirin,Використовувати адаптери PlayStation 2 напряму, -No controllers detected,JOYMNU_NOCON,,,,Nenalezeny žádné ovladače.,Ingen controllere er fundet,Keine Controller gefunden,,Neniu ludregilo detektita,No hay mandos detectados,,Ei havaittuja ohjaimia,Aucun Contrôleur détecté.,Nem érzékelhető kontroller,Nessun controller trovato,コントローラーが見つかりません,인식된 컨트롤러 없음,Geen controllers gedetecteerd,Ingen kontrollere oppdaget,Nie wykryto kontrolerów,Nenhum controle detectado.,Nenhum comando foi detectado,Niciun controller detectat,Контроллеры не обнаружены,Нема детектованих контролера,Denetleyici algılanmadı,Контролерів не виявлено, -Configure controllers:,JOYMNU_CONFIG,,,,Nastavit ovladače:,Konfigurer controllere:,Controller konfigurieren,,Agordi ludregilojn:,Configurar controles:,,Mukauta ohjaimia:,Configurer contrôleurs:,Kontrollerek konfigurációja:,Configura i controller:,コントローラー構成:,컨트롤러 설정:,Configureer controllers:,Konfigurer kontrollere:,Konfiguruj kontrolery:,Configurar controles:,Configurar comandos,Configurare controlere:,Настроить контроллер:,Подешавања контролере:,Denetleyicileri yapılandırın:,Налаштувати контролери, -Controller support must be,JOYMNU_DISABLED1,,,,Pro nalezení ovladačů musí,Der skal være støtte til controlleren,Controllerunterstütung muss aktiviert sein,,Ludregilo-subteno devas esti,El soporte de mandos debe estar,,Ohjaintuen täytyy olla otettu,Le Support de contrôleur doit être activé,A kontroller támogatásnak,Il supporto ai controller deve essere,コントローラーサポートは,감지하려면 컨트롤러 지원을,Controller ondersteuning moet ingeschakeld zijn,Støtte for kontrollere må være,Wsparcie kontrolera musi być,A detecção de controles deve,Suporte a comandos devem ser,Supportul pentru controller trebuie,Включите поддержку контроллера,Омогућите подржавање контролера,Denetleyici desteği şu şekilde olmalıdır,Включіть підтримку контролерів, -enabled to detect any,JOYMNU_DISABLED2,Supposed to be empty in Russian and Serbian.,,,být zapnuta jejich podpora.,aktiveret for at registrere enhver,um welche zu finden,,ŝaltita por detekti iun ajn,activado para detectar alguno,,käyttöön ohjainten havaitsemiseksi,avant de pouvoir en détecter un.,"engedélyezve kell lenni, hogy érzékeljen bármit is.",abilitato a trovare ogni,検出しました,활성화 해야합니다.,om eventuele regelaars te detecteren.,aktivert for å oppdage en hvilken som helst,Włączony by wykryć jakikolwiek,ser ativada para exibi-los.,,activat pentru a putea fi detectate, \n, \n,tespit etmek için etkinleştirildi, \n, -Invalid controller specified for menu,JOYMNU_INVALID,,,,Vybrán nesprávný ovladač pro nabídky,Ugyldig controller angivet til menuen,Ungültiger Controller für Menü ausgewählt,,Nevalida ludregilo specifigita por menuo,Mando inválido especificado para el menú,,Epäkelpo ohjain määritetty valikolle,Contrôleur invalide spécifé dans le menu.,Hibás kontroller van a menühöz osztva,Controller invalido specificato per il menu,メニューではコントローラーを使用しない,메뉴에 특정된 컨트롤러가 아닙니다.,Ongeldige regelaar gespecificeerd voor het menu,Ugyldig kontroller spesifisert for menyen,Niewłaściwy kontroler określony dla menu,Controle inválido especificado para o menu.,Comando inválido,Controller pentru meniu invalid,Недопустимый контроллер выбран для меню,Невалидан контролер специфиран за мени,Menü için geçersiz denetleyici belirtildi,Для меню вибрано невідповідний контролер, -Overall sensitivity,JOYMNU_OVRSENS,,,,Celková citlivost,Samlet følsomhed,Allgemeine Empfindlichkeit,,Tuta sentemeco,Sensibilidad general,,Yleisherkkyys,Sensibilité générale,Teljes érzékenység,Sensibilità generale,全体的な感度,전체 민감도,Algemene gevoeligheid,Samlet følsomhet,Ogólna Czułość,Sensibilidade geral,,Sensibilitate în ansamblu,Общая чувствительность,Уупна сензитивност,Genel hassasiyet,Загальна чутливість, -Axis Configuration,JOYMNU_AXIS,,,,Nastavení os,Konfiguration af akserne,Achsenkonfiguration,,Akso-agordoj,Configuración del eje,,Akseleiden säätäminen,Configuration des axes,Tengely konfigurálása,Configurazione assi,軸構成,축 구성,Asconfiguratie,Konfigurasjon av akse,Konfiguruj Oś,Configuração de eixo,,Configurare axă,Конфигурация осей,Конфигурација осе,Eksen Konfigürasyonu,Конфігурація осей, -Invert,JOYMNU_INVERT,,,,Obrátit,Invert,Invertieren,,Inversigi,Invertir,,Käännä,Inverser,Megfordítás,Inverti,反転,순서 바꿈,Omkeren,Invertering,Odwróć,Inverter,,Inversare,Инвертировать,Инвертовано,Ters çevir,Інвертувати, -Dead zone,JOYMNU_DEADZONE,,,,Mrtvá zóna,Dødzone,Totzone,,Mortozono,Zona muerta,,Kuollut alue,Zone neutre,Holttér,Zona cieca,デッドゾーン,불감대,Dode zone,Død sone,Martwa strefa,Zona morta,,Zonă moartă,Мёртвая зона,Мртва зона,Ölü bölge,Мертва зона, -No configurable axes,JOYMNU_NOAXES,,,,Žádné nastavitelné osy,Ingen konfigurerbare akser,Keine konfigurierbaren Achsen,,Neniuj agordeblaj aksoj,No hay ejes configurables,,Ei säädettäviä akseleita,Aucun axe à configurer,Nincs beállítható tengely,Nessun asse configurabile,軸構成を無効,설정할 방향키가 없습니다.,Geen configureerbare assen,Ingen konfigurerbare akser,Brak osi do skonfigurowania,Nenhum eixo configurável,,Nicio axă configurabilă,Нет настраиваемых осей,Нема конфигурационих оса,Yapılandırılabilir eksen yok,Немає настроюваних осей, -None,OPTVAL_NONE,,,,Žádný,Ingen,Kein,,Neniu,Ninguno,,Ei mitään,Aucun,Nincs,Nessuno,無し,없음,Geen,Ingen,Żaden,Nenhum,,Niciuna,Откл.,Ништа,Hiçbiri,Вимк., -Turning,OPTVAL_TURNING,,,,Otáčení,Drejning,Umdrehen,,Turnanta,Girar,,Kääntyminen,Tourner,Fordulás,Rotazione,旋回,회전,Draaien,Dreie,Obracanie się,Girar,,Rotire,Поворот,Скретање,Dönüş,Поворот, -Looking Up/Down,OPTVAL_LOOKINGUPDOWN,,,,Dívání se nahoru/dolů,Kigger op/ned,Hoch/runterblicken,,Rigardanta (mal)supren,Mirar hacia arriba/abajo,,Ylös/Alas katsominen,Vue haut/bas,Fel-/lenézés,Sguardo Sopra/Sotto,視点上下,위/아래로 보기,Omhoog/omlaag zoeken,Ser opp/ned,Patrzenie w górę/w dół,Olhar para cima/baixo,,Privire Sus/Jos,Взгляд вверх/вниз,Гледање горе/доле,Yukarı/Aşağı Bakmak,Дивитись вгору, -Moving Forward,OPTVAL_MOVINGFORWARD,,,,Pohyb vpřed,Bevæger sig fremad,Vorwärtsbewegung,,Movanta antaŭen,Avanzar,,Eteenpäin liikkuminen,Avancer,Előre mozgás,Movimento in avanti,前進,앞으로 전진,Voorwaarts bewegen,Beveger seg fremover,Poruszanie się do przodu,Mover-se para a frente,,Deplasare în Față,Движение вперёд,Кретање напред,İleriye Doğru,Рухатись вперед, -Strafing,OPTVAL_STRAFING,,,,Pohyb do stran,Strafing,Seitwärtsbewegung,,Flankmovanta,Desplazarse,,Sivuttaisastunta,Pas de côté,Oldalazás,Movimento laterale,横移動,양옆으로 이동,Strafelen,Straffe,Uniki,Deslocamento lateral,,Deplasare în Diagonală,Движение боком,Кретање у страну,Strafing,Рухатись боком, -Moving Up/Down,OPTVAL_MOVINGUPDOWN,,,,Pohyb nahoru/dolů,Bevægelse op/ned,Auf/abwärtsbewegung,,Movanta (mal)supren,Moverse hacia arriba/abajo,,Ylös/Alas liikkuminen,Mouvement haut/bas,Felfele/Lefele mozgás,Movimento Sopra/Sotto,前進後退,위/아래로 이동,Naar boven/beneden bewegen,Beveger seg opp/ned,Poruszanie się w górę/w dół,Mover-se para cima/baixo,,Mișcare Sus/Jos,Движение вверх/вниз,Кретање горе/доле,Yukarı/Aşağı Hareket Etme,Рухатись вгору/вниз, -Inverted,OPTVAL_INVERTED,,,,Inverzní,Omvendt,Invertiert,,Inversigita,Invertido,,Käännetty,Inversé,Felcserélve,Invertito,反転する,반전,Omgekeerd,Invertert,Odwrócony,Invertido,,Inversat,Инвертировано,Обрнуто,Ters çevrilmiş,Інвертовано, -Not Inverted,OPTVAL_NOTINVERTED,,,,Neinverzní,Ikke omvendt,nicht invertiert,,Ne inversigita,No invertido,,Ei käännetty,Non Inversé,Nincs felcserélve,Non invertito,反転しない,반전되지 않음,Niet omgekeerd,Ikke invertert,Nieodwrócony,Não invertido,,Neinversat,Прямо,Не обрнуто,Ters Çevrilmemiş,Не інвертовано, -,,Player Menu,,,,,,,,,,,,,,,,,,,,,,,,,, -Blue,TXT_COLOR_BLUE,,,,Modrá,Blå,Blau,Μπλέ,Blua,Azul,,Sininen,Bleu,Kék,Blu,青,청색,Blauw,Blå,Niebieski,Azul,,Albastru,Синий,Плава,Mavi,Синій, -Red,TXT_COLOR_RED,,,,Červená,Rød,Rot,Κόκκινο,Ruĝa,Rojo,,Punainen,Rouge,Vörös,Rosso,赤,적색,Rood,Rød,Czerwony,Vermelho,,Roșu,Красный,Црвена,Kırmızı,Червоний, -Green,TXT_COLOR_GREEN,,,,Zelená,Grøn,Grün,Πράσινο,Verda,Verde,,Vihreä,Vert,Zöld,Verde,緑,녹색,Groen,Grønn,Zielony,Verde,,Verde,Зелёный,Зелена,Yeşil,Зелений, -Gray,TXT_COLOR_GRAY,,,Grey,Šedá,Grå,Grau,Γκρί,Griza,Gris,,Harmaa,Gris,Szürke,Grigio,灰,회색,Grijs,Grå,Szary,Cinza,,Gri,Серый,Сива,Gri,Сірий, +",도움말 열기,Open hulp,Åpne Hjelp,Otwórz Pomoc,Abrir ajuda,,Deschide Ajutor,Экран помощи,Отвори помоћ,Öppna hjälp,Açık Yardım,Відкрити екран допомоги, +Open Save Menu,CNTRLMNU_OPEN_SAVE,,,,Uložit hru,Åbn menuen Gem,Speichermenü öffnen,Άνοιγμα μενού αποθήκευσης,Malfermi konservmenuon,Menú de guardar partida,,Avaa tallennusvalikko,Ouvrir Menu Sauvegarde,Mentés menü előhozása,Apri il menu di salvataggio,セーブメニューを開く,저장 화면 열기,Menu opslaan openen,Åpne Lagre-menyen,Otwórz Menu Zapisu,Abrir menu de salvar,Abrir Menu de Gravação,Deschide meniul de salvare,Меню сохранения игры,Отвори сачуване игре,Öppna sparmenyn,Kaydet Menüsünü Aç,Меню збереженнь, +Open Load Menu,CNTRLMNU_OPEN_LOAD,,,,Načíst hru,Åbn indlæsningsmenuen,Lademenü öffnen,Άνοιγμα μενού φόρτωσης,Malfermi ŝargmenuon,Menú de cargar partida,,Avaa latausvalikko,Ouvrir Menu Chargement,Betöltés menü előhozása,Apri il menu di caricamento,ロードメニューを開く,불러오기 화면 열기,Menu laden openen,Åpne Last-menyen,Otwórz Menu Wczytania,Abrir menu de carregar,,Deschide meniul de încărcare,Меню загрузки игры,Отвори игре за учитати,Öppna laddningsmenyn,Yük Menüsünü Aç,Меню завантаженнь, +Open Options Menu,CNTRLMNU_OPEN_OPTIONS,,,,Nastavení,Åbn menuen Indstillinger,Optionsmenü öffnen,Άνοιγμα μενού επιλογών,Malfermi agordmenuon,Menú de opciones,,Avaa asetusvalikko,Ouvrir Menu Options,Beállítások menü előhozása,Apri il menu delle opzioni,オプションメニューを開く,설정 화면 열기,Menu Opties openen,Åpne Alternativer-menyen,Otwórz Menu Opcji,Abrir menu de opções,,Deschide setările,Главное меню настроек,Отвори мени опција,Öppna alternativmenyn,Seçenekler Menüsünü Aç,Головне меню параметрів, +Open Display Menu,CNTRLMNU_OPEN_DISPLAY,,,,Nastavení grafiky,Åbn menuen Visning,Anzeigemenü öffnen,Άνοιγμα μενού οθόνης,Malfermi ekranmenuon,Menú de opciones de visualización,,Avaa näyttövalikko,Ouvrir Menu Affichage,Megjelenítés menü előhozása,Apri il menu del display,ディスプレイメニューを開く,디스플레이 화면 열기,Displaymenu openen,Åpne visningsmeny,Otwórz Menu Wyświetlania,Abrir menu de vídeo,,Deschide setările de afișare,Меню настроек видео,Отвори мени приказа,Öppna visningsmenyn,Ekran Menüsünü Aç,Параметри відео, +Quicksave,CNTRLMNU_QUICKSAVE,,,,Rychlé uložení,Quicksave,Schnellspeichern,Γρήγορη αποθήκευση,Rapidkonservo,Guardado rápido,,Pikatallenna,Sauv. Rapide,Gyorsmentés,Salvataggio rapido,クイックセーブ,빠른 저장,Snel opslaan,Hurtiglagring,Szybki Zapis,Salvar rapidamente,Gravação rápida,Salvare rapidă,Быстрое сохранение,Брзо-сачувај,Snabbspara,Hızlı Tasarruf,Швидке збереження, +Quickload,CNTRLMNU_QUICKLOAD,,,,Rychlé načtení,Quickload,Schnellladen,Γρήγορη φόρτωση,Rapidŝargo,Cargado rápido,,Pikalataa,Charg. Rapide,Gyorstöltés,Caricamento rapido,クイックロード,빠른 불러오기,Snel laden,Hurtiglasting,Szybkie Wczytanie,Carregar rapidamente,,Încărcare rapidă,Быстрая загрузка,Брзо-учитај,Snabbladdning,Hızlı Yükleme,Швидке завантаження, +Exit to Main Menu,CNTRLMNU_EXIT_TO_MAIN,,,,Odejít do hlavního menu,Afslut til hovedmenu,Zurück zum Hauptmenü,Έξοδος στο κύριο μενού,Eliri al ĉefa menuo,Salir al menú principal,,Poistu päävalikkoon,Sortie Menu Principal,Kilépés a főmenübe,Esci dal menu principale,メインメニューに戻る,메뉴로 나오기,Afsluiten naar het hoofdmenu,Avslutt til hovedmeny,Wyjdź do Głównego Menu,Sair para o menu principal,,Revenire la meniul principal,Выход в главное меню,Изађи у главни мени,Avsluta till huvudmenyn,Ana Menüden Çıkış,Вихід в головне меню, +Toggle Messages,CNTRLMNU_TOGGLE_MESSAGES,,,,Povolit/skrýt oznámení,Skift mellem meddelelser,Nachrichten an/aus,Εναλλαγή μηνυμάτων,Baskuligi mesaĝojn,Alternar mensajes,,Kytke viestit päälle tai pois,Messages On/Off,Üzenetek kapcsolása,Toggle messaggi,メッセージ表示の切替,메시지 토글,Berichten aan/uit,Veksle meldinger,Włącz / Wyłącz Wiadomości,Ativar/desativar mensagens,,Comutator mesaje,Переключение сообщений,Таглави поруке,Växla meddelanden,Mesajları Değiştir,Перемикач повідомлень, +Quit Game,CNTRLMNU_MENU_QUIT,,,,Ukončit hru,Afslut spil,Spiel beenden,Στάματα το παιχνίδι,Mallanĉi ludon,Salir del juego,,Lopeta peli,Quitter le Jeu,Kilépés a játékból,Esci dal gioco,ゲームを終了,게임 종료,Stop het spel,Avslutt spill,Wyjdź z Gry,Sair do jogo,,Ieși din Joc,Выход,Изађи из игре,Avsluta spelet,Oyundan Çık,Вихід, +Adjust Gamma,CNTRLMNU_ADJUST_GAMMA,,,,Nastavit gamu,Juster Gamma,Gamma-Anpassung,Ρύθμιση Γάμμα,Agordi gamaon,Ajustar gama,,Säädä gammaa,Ajuster Gamma,Gamma állítása,Aggiustamento Gamma,ガンマ値を調整,감마 조정,Gamma aanpassen,Juster gamma,Dostosuj Gammę,Ajustar gama,,Ajustare gamma,Настройка гаммы,Подесите осветљење,Justera Gamma,Gama Ayarlama,Парамети гамми, +,,Mouse,,,,,,,,,,,,,,,,,,,,,,,,,,, +Enable mouse,MOUSEMNU_ENABLEMOUSE,,,,Povolit myš,Aktiver mus,Maus aktiv,Ενεργοποίηση ποντικιόυ,Ebligi muson,Habilitar ratón,,Ota hiiri käyttöön,Activer Souris,Egér engedélyezése,Abilita il mouse,マウスの使用,마우스 사용,Muis inschakelen,Aktiver mus,Włącz myszkę,Ativar mouse,Permitir uso do rato,Activare mouse,Использовать мышь,Укључи миш,Aktivera musen,Fareyi etkinleştir,Використовувати миш, +Enable mouse in menus,MOUSEMNU_MOUSEINMENU,,,,Povolit myš v nabídkách,Aktiver mus i menuer,Maus aktiv in Menüs,Ενεργοποίηση ποντικιόυ στα μενού,Ebligi muson en menuoj,Usa ratón en los menús,,Ota hiiri käyttöön valikoissa,Activer Souris dans les Menus,Egér engedélyezése a menüben,Abilita il mouse nei menu,メニューでのマウスの使用,메뉴에서 마우스 사용,Muis in menu's inschakelen,Aktiver mus i menyer,Włącz myszkę w menu,Ativar mouse nos menus,Permitir rato nos menus,Activare mouse în meniuri,Использовать мышь в меню,Укључи миш у менијима,Aktivera musen i menyer,Menülerde fareyi etkinleştir,Використовувати миш в меню, +Show back button,MOUSEMNU_SHOWBACKBUTTON,,,,Zobrazit tlačítko zpět,Vis tilbage-knappen,Zeige Zurück-Knopf,Εμφάνιση του κουμπιού επιστροφής,Montri reen-butonon,Mostrar botón de retroceso,,Näytä taaksenäppäin,Afficher le bouton retour,Vissza gomb mutatása,Mostra il bottone per tornare indietro,戻るボタンを表示,뒤로가기 버튼 보이기,Toon terug knop,Vis tilbake-knapp,Pokaż przycisk powrotu,Exibir botão de voltar,,Afișare buton de întoarcere,Расположение кнопки «назад»,Прикажи тастер за назад,Visa bakåtknappen,Geri düğmesini göster,"Положення кнопки ""назад""", +Cursor,MOUSEMNU_CURSOR,,,,Kurzor,Markør,,Δρομέας,Musmontrilo,,,Osoitin,Curseur,Egérmutató,Cursore,カーソル,커서,,Markør,Kursor,Cursor,,,Курсор,Курсор,Markör,İmleç,Курсор, +Horizontal sensitivity,MOUSEMNU_SENSITIVITY_X,,,,Horizontální citlivost,Vandret følsomhed,Horizontale Empfindlichkeit,Οριζόντια ευαισθησία,Horizontala sentemo,Sensibilidad horizontal,,Vaakasuuntainen herkkyys,Sensibilité horizontale,Vízszintes érzékenység,Sensibilità orizzontale,水平感度,수평 감도,Horizontale gevoeligheid,Horisontal følsomhet,Czułość pozioma,Sensibilidade horizontal,,Sensibilitate orizontală,Горизонтальная чувствительность,Хоризонтална осетљивост,Horisontell känslighet,Yatay hassasiyet,Горизонтальна чутливість, +Vertical sensitivity,MOUSEMNU_SENSITIVITY_Y,,,,Vertikální citlivost,Lodret følsomhed,Vertikale Empfindlichkeit,Κάθετη ευαισθησία,Vertikala sentemo,Sensibilidad vertical,,Pystysuuntainen herkkyys,Sensibilité verticale,Függőleges érzékenység,Sensibilità verticale,垂直感度,수직 감도,Verticale gevoeligheid,Vertikal følsomhet,Czułość pionowa,Sensibilidade vertical,,Sensibilitate verticală,Вертикальная чувствительность,Вертикална осетљивост,Vertikal känslighet,Dikey hassasiyet,Вертикальна чутливість, +Smooth mouse movement,MOUSEMNU_SMOOTHMOUSE,,,,Vyhladit pohyb myši,Jævn bevægelse af musen,Mausbewegung glätten,Ομαλή κίνηση του ποντικιού,Glata musmovo,Mov. fluido del ratón,,Sulava hiiren liike,Lissage Souris,Egérmozgás simítása,Movimento del mouse liscio,マウス操作を滑らかにする,부드러운 움직임,Vlotte muisbeweging,Jevn musebevegelse,Gładki ruch myszki,Suavizar movimento do mouse,Movimento fluído do rato,Mișcare mouse fină,Плавное перемещение,Глатки окрет,Smidig musrörelse,Pürüzsüz fare hareketi,Плавний рух миші, +Turning speed,MOUSEMNU_TURNSPEED,,,,Rychlost otáčení,Drejehastighed,Umdrehgeschwindigkeit,Ταχύτητα περιστροφής,Turnorapido,Velocidad de giro,,Kääntymisnopeus,Vitesse pour tourner,Fordulás sebessége,Velocità di rotazione,旋回速度,회전 속도,Draaisnelheid,Dreiehastighet,Szybkość obracania się,Velocidade de giro,,Viteză rotire,Скорость поворота,Брзина окрета,Vändningshastighet,Dönüş hızı,Швидкість повороту, +Mouselook speed,MOUSEMNU_MOUSELOOKSPEED,,,,Rychlost pohledu nahoru/dolů,Hastighed for mus-look,Mausblick-Geschwindigkeit,Ταχύτητα εμφάνισης ποντικιού,Musrigarda rapido,Veloc. de vista con ratón,,Katselunopeus,Vitesse Vue Souris,Egérnézés sebessége,Velocità di rotazione della vista,上下視点速度,마우스룩 속도,Mouselook snelheid,Muselook-hastighet,Szybkość rozglądania się myszką,Velocidade da visão com mouse,Velocidade de vista com rato,Viteză privire în jur cu mouse,Скорость обзора,Брзина гледања мишем,Hastighet för muspekning,Mouselook hızı,Швидкість огляду, +Forward/Backward speed,MOUSEMNU_FORWBACKSPEED,,,,Rychlost pohybu vpřed/vzad,Hastighed fremad/tilbage,Vor/Rückwärtsgeschwindigkeit,Ταχύτητα προς τα εμπρός/πίσω,Antaŭa/Malantaŭa rapido,Veloc. de avance/retroceso,,Eteen-/taaksepäin liikkeen nopeus,Vitesse Avancer/reculer,Előre/Hátra sebesség,Velocità avanti/indietro,"前進/後退速度 +",전진/후진 속도,Voorwaartse/achterwaartse snelheid,Hastighet forover/bakover,Szybkość chodzenia do przodu/do tyłu,Velocidade de deslocamento para frente/trás,,Viteză deplasare față/spate,Скорость передвижения,Брзина окрета напред/уназад,Hastighet framåt/bakåt,İleri/Geri hız,Швидкість руху вперед/назад, +Strafing speed,MOUSEMNU_STRAFESPEED,,,,Rychlost pohybu do stran,Strafing-hastighed,Seitwärtsgeschwindigkeit,Ταχύτητα καταδίωξης,Flankmova rapido,Veloc. de mov. lateral,,Sivuttaisastunnan nopeus,Vitesse Gauche/Droite,Oldalazás sebessége,Velocità movimento laterale,横移動速度,좌진/우진 속도,Zijdelings snelheid,Hastigheten for stansing,Szybkość uników,Velocidade de deslocamento lateral,,Viteză deplasare în diagonală,Скорость движения боком,Брзина стрејфа,Hastighet för strafe,Strafe hızı,Швидкість руху боком, +Always Mouselook,MOUSEMNU_ALWAYSMOUSELOOK,,,,Vždy se rozhlížet myší,Altid mus-look,Mausblick immer an,Πάντα κοίτα με το ποντίκι,Ĉiam musrigardi,Siempre mirar con ratón,,Jatkuva hiirikatselu,Toujours vue Souris,Mindig egérrel nézelődés,Vista col mouse,常に上下視点をオン,마우스룩 사용,Altijd Mouselook,Alltid muselook,Zawsze zezwalaj na rozglądanie się myszką,Visão com mouse sempre ativada,Vista com rato sempre ligada,Privire în jur cu mouse permanentă,Обзор мышью,Гледање мишем,Alltid muspekande,Her zaman Mouselook,Огляд мишкою, +Invert Mouse Y,MOUSEMNU_INVERTMOUSE,,,,Vertikálně obrátit myš,Inverter mus Y,Maus Y invertieren,Αντιστροφή ποντικιού Y,Inversi muson Y,Invertir ratón Y,,Käännä hiiri Y,Inverser Souris Y,Y tengely megfordítása,Mouse Y invertito,視点操作反転,마우스 방향 전환,Muis-Y-as omkeren,Inverter mus Y,Odwróć Myszkę - Oś Y,Inverter eixo Y do mouse,Inverter rato,Inversare axă mouse Y,Инверт. мышь по вертикали (Y),Инвертуј миш Y,Invertera mus Y,Fare Y'yi Ters Çevir,Інвертувати мишу Y, +Invert Mouse X,MOUSEMNU_INVERTMOUSEX,,,,Horizontálně obrátit myš,Inverter mus X,Maus X invertieren,Αντιστροφή ποντικιού X,Inversi muson X,Invertir ratón X,,Käännä hiiri X,Inverser Souris X,X tengely megfordítása,Mouse X invertito,視点操作反転,마우스 방향 전환,Muis-X-as omkeren,Inverter mus X,Odwróć Myszkę - Oś X,Inverter eixo X do mouse,Inverter rato X,Inversare axă mouse X,Инверт. мышь по горизонтали (X),Инвертуј миш X,Invertera mus X,Fare X'i Ters Çevir,Інвертувати мишу Х, +Upper left,OPTVAL_UPPERLEFT,,,,Vlevo nahoře,Øverste venstre,Oben links,Πάνω αριστερά,Supra maldekstre,Sup. izquierda,,Ylävasemmalla,Supérieur gauche,Bal fent,Superiore sinistro,左上,왼쪽 위,Linksboven,Øvre venstre,Lewy górny róg,Esquerda superior,,Stânga sus,Вверху слева,Горње лево,Övre vänster,Sol üst,Вгорі ліворуч, +Upper right,OPTVAL_UPPERRIGHT,,,,Vpravo nahoře,Øvre højre,Oben rechts,Πάνω δεξιά,Supra dekstre,Sup. derecha,,Yläoikealla,Supérieur droite,Jobb fent,Superiore destro,右上,오른쪽 위,Rechtsboven,Øverst til høyre,Prawy górny róg,Direita superior,,Dreapta sus,Вверху справа,Горње десно,Övre höger,Sağ üst,Вгорі праворуч, +Lower left,OPTVAL_LOWERLEFT,,,,Vlevo dole,Nederste venstre,Unten links ,Κάτω αριστερά,Suba maldekstre,Inf. izquierda,,Alavasemmalla,Inférieur gauche,Bal lent,Inferiore sinistro,左下,왼쪽 밑,Linksonder,Nedre venstre,Lewy dolny róg,Esquerda inferior,,Stânga jos,Внизу слева,Доње лево,Nedre vänster,Sol alt,Внизу ліворуч, +Lower right,OPTVAL_LOWERRIGHT,,,,Vpravo dole,Nederste højre,Unten rechts,Κάτω δεξιά,Suba dekstre,Inf. derecha,,Alaoikealla,Inférieur droite,Jobb lent,Inferiore destro,右下,오른쪽 밑,Rechtsonder,Nedre høyre,Prawy dolny róg,Direita inferior,,Dreapta jos,Внизу справа,Доње десно,Nedre höger,Sağ alt,Внизу праворуч, +Touchscreen-like,OPTVAL_TOUCHSCREENLIKE,,,,Jako dotyková obrazovka,Touchscreen-lignende,Wie auf einem Touchscreen,Οθόνη αφής,Tuŝekraneca,Pant. táctil,,Kosketusnäyttömäinen,Style écran tactile,Érintőképernyő-szerű,Come il Touchscreen,タッチスクリーン式,터치스크린 같게,Touchscreen-achtige,Berøringsskjerm-lignende,Jak ekrean dotykowy,Estilo touchscreen,,Precum touchscreen,Как сенсорный экран,Као додирни екран,Pekskärmsliknande,Dokunmatik ekran benzeri,Як сенсорний екран, +Simple arrow,OPTSTR_SIMPLEARROW,,,,Jednoduchý kurzor,Simpel pil,Einfacher Pfeil,Απλό βέλος,Simpla sago,Flecha simple,,Yksinkertainen nuoli,Flèche simple,Sima nyíl,Freccia semplice,シンプル,기본 커서,Eenvoudige pijl,Enkel pil,Prosta strzałka,Seta simples,Cursor simples,Săgeată simplă,Стрелка,Стрелица,Enkel pil,Basit ok,Стрілка, +System cursor,OPTSTR_SYSTEMCURSOR,,,,Systémový kurzor,Systemcursor,Systemcursor,Δείκτης συστήματος,Sistema kursoro,Cursor del sistema,,Järjestelmän osoitin,Curseur Système,Rendszer egérmutatója,Cursore di sistema,システム,시스템 커서,Systeemcursor,Systemmarkør,Kursor systemu,Cursor do sistema,,Cursor simplu,Системный курсор,Системска стрелица,Systemmarkör,Sistem imleci,Системний курсор, +Default,OPTVAL_DEFAULT,,,,Výchozí,Standard,Standard,Προεπιλογή,Defaŭlta,Por defecto,,Oletus,Défaut,Alapbeállítás,Predefinito,デフォルト,기본 설정,Standaard,Standard,Domyślne,Padrão,,Implicit,По умолчанию,Подраз.,Standard,Varsayılan,За замовчуванням, +,,Controller,,,,,,,,,,,,,,,,,,,,,,,,,,, +Configure Controller,JOYMNU_TITLE,,,,Konfigurace ovladače,Konfigurer controller,Controller konfigurieren,,Agordi ludregilon,Configurar mando,,Peliohjainasetukset,Configurer Mannette,Kontroller testreszabása,Configura il controller,コントローラー構成:,컨트롤러 구성,Controller configureren,Konfigurer kontrolleren,Konfiguruj Kontroler,Configurar controle,Configurar Comando,Configurare controller,Настроить контроллер,Конфигурација контролера,Konfigurera kontroller,Denetleyiciyi Yapılandırma,Параметри контролера, +Controller Options,JOYMNU_OPTIONS,,,,Ovladač,Indstillinger for styreenhed,Controlleroptionen,,Ludregilo-agordoj,Opciones del mando,,Peliohjainasetukset,Options Mannette,Kontroller beállítások,Opzioni del controller,コントローラー設定,컨트롤러 설정,Controller opties,Alternativer for styreenhet,Opcje Kontrolera,Opções de controle,Opções do Comando,Setări controller,Настройки контроллера,Подешавања контролера,Alternativ för kontroller,Kontrolör Seçenekleri,Налаштування контролера, +Block controller input in menu,JOYMNU_NOMENU,,,,Zakázat ovladač v nabídkách,Bloker controller input i menuen,Blockiere Controllereingabe im Menü,,Blokigi ludregilan enigon en menuo,Bloq. entrada de mando en menú,,Estä ohjainsyötteet valikoissa,Bloquer manette dans les menus,Kontroller ne működjön a menüben,Blocca l'input del controller nei menu,メニューではコントローラーを無視,메뉴에서 컨트롤러 끄기,Blokkeer de controller in het menu,Blokker kontrollerinngang i menyen,Blokuj wejście kontrolera w menu,Bloquear controle no menu,Bloquear comando no menu,Blocare comenzi controller în meniu,Отключить контроллер в меню,Блокирај улаз контролера у менију,Blockera inmatning av kontroller i menyn,Menüde kontrolör girişini engelle,Відключити контролер в меню, +Enable controller support,JOYMNU_ENABLE,,,,Povolit podporu pro ovladače,Aktivering af controllerunderstøttelse,Erlaube Controllerunterstützung,,Ŝalti ludregilan subtenon,Activar soporte de mandos,,Ota käyttöön peliohjaintuki,Activer support contrôleur,Kontroller támogatás engedélyezése,Abilita il supporto del controller,コントローラーサポート許可,컨트롤러 지원 허용,Controllerondersteuning inschakelen,Aktiver støtte for styreenhet,Włącz wsparcie kontrolera,Ativar detecção de controles,,Activare support controller,Включить поддержку контроллера,Омогући подршку за контролере,Aktivera stöd för kontroller,Denetleyici desteğini etkinleştir,Увімкнути підтримку контролера, +Enable DirectInput controllers,JOYMNU_DINPUT,,,,Povolit ovladače DirectInput,Aktivering af DirectInput-controllere,Erlaube DirectInput-Controller,,Ŝalti DirectInput ludregilojn,Usa controles DirectInput,,Ota käyttöön DirectInput-ohjaimet,Activer contrôleurs DirectInput,DirectInput kontrollerek engedélyezése,Abilita i controlli DirectInput,ダイレクトインプットコントローラー許可,다이렉트 인풋 컨트롤러 허용,DirectInput-controllers inschakelen,Aktiver DirectInput-kontrollere,Włącz kontrolery DirectInput,Ativar controles DirectInput,,Activare controlere DirectInput,Включить контроллеры через DirectInput,Омогући директинпут контролере,Aktivera DirectInput-kontroller,DirectInput denetleyicilerini etkinleştirin,Увімкнути контролери DirectInput, +Enable XInput controllers,JOYMNU_XINPUT,,,,Povolit ovladače XInput,Aktiver XInput-controllere,Erlaube XInput-Controller,,Ŝalti XInput ludregilojn,Usa controles XInput,,Ota käyttöön XInput-ohjaimet,Activer contrôleurs XInput,XInput kontrollerek engedélyezése,Abilita i controlli XInput,Xinput コントローラー許可,X인풋 컨트롤러 허용,XInput-controllers inschakelen,Aktiver XInput-kontrollere,Włącz kontrolery XInput,Ativar controles XInput,,Activare controlere XInput,Включить контроллеры через XInput,Омогући Иксинпут контролере,Aktivera XInput-kontroller,XInput denetleyicilerini etkinleştirin,Увімкнути контролери XInput, +Enable raw PlayStation 2 adapters,JOYMNU_PS2,,,,Povolit ovladače PlayStation 2,Aktiver rå PlayStation 2-adaptere,Erlaube Playstation 2-Controller,,Ŝalti krudajn adaptilojn de PlayStation 2 ,Usa adaptadores de PlayStation 2,,Ota käyttöön raa'at PlayStation 2 -adapterit,Activer adaptateurs PS2 bruts,PlayStation 2 adapterek engedélyezése,Abilita gli adattatori raw PlayStation 2,PlayStation2 アダプター許可,PS2 어뎁터 허용,Raw PlayStation 2-adapters inschakelen,Aktiver rå PlayStation 2-adaptere,Włącz adaptery PlayStation 2,Ativar adaptadores de PlayStation 2,,Activare adaptoare PS2,Использовать адаптеры PlayStation 2 напрямую,Омогући сирове Плејстејшн 2 адаптере,Aktivera råa PlayStation 2-adaptrar,Ham PlayStation 2 adaptörlerini etkinleştirin,Використовувати адаптери PlayStation 2 напряму, +No controllers detected,JOYMNU_NOCON,,,,Nenalezeny žádné ovladače.,Ingen controllere er fundet,Keine Controller gefunden,,Neniu ludregilo detektita,No hay mandos detectados,,Ei havaittuja ohjaimia,Aucun Contrôleur détecté.,Nem érzékelhető kontroller,Nessun controller trovato,コントローラーが見つかりません,인식된 컨트롤러 없음,Geen controllers gedetecteerd,Ingen kontrollere oppdaget,Nie wykryto kontrolerów,Nenhum controle detectado.,Nenhum comando foi detectado,Niciun controller detectat,Контроллеры не обнаружены,Нема детектованих контролера,Inga kontroller upptäcks,Denetleyici algılanmadı,Контролерів не виявлено, +Configure controllers:,JOYMNU_CONFIG,,,,Nastavit ovladače:,Konfigurer controllere:,Controller konfigurieren,,Agordi ludregilojn:,Configurar controles:,,Mukauta ohjaimia:,Configurer contrôleurs:,Kontrollerek konfigurációja:,Configura i controller:,コントローラー構成:,컨트롤러 설정:,Configureer controllers:,Konfigurer kontrollere:,Konfiguruj kontrolery:,Configurar controles:,Configurar comandos,Configurare controlere:,Настроить контроллер:,Подешавања контролере:,Konfigurera kontroller:,Denetleyicileri yapılandırın:,Налаштувати контролери, +Controller support must be,JOYMNU_DISABLED1,,,,Pro nalezení ovladačů musí,Der skal være støtte til controlleren,Controllerunterstütung muss aktiviert sein,,Ludregilo-subteno devas esti,El soporte de mandos debe estar,,Ohjaintuen täytyy olla otettu,Le Support de contrôleur doit être activé,A kontroller támogatásnak,Il supporto ai controller deve essere,コントローラーサポートは,감지하려면 컨트롤러 지원을,Controller ondersteuning moet ingeschakeld zijn,Støtte for kontrollere må være,Wsparcie kontrolera musi być,A detecção de controles deve,Suporte a comandos devem ser,Supportul pentru controller trebuie,Включите поддержку контроллера,Омогућите подржавање контролера,Stöd för kontroller måste vara aktiverat,Denetleyici desteği şu şekilde olmalıdır,Включіть підтримку контролерів, +enabled to detect any,JOYMNU_DISABLED2,Supposed to be empty in Russian and Serbian.,,,být zapnuta jejich podpora.,aktiveret for at registrere enhver,um welche zu finden,,ŝaltita por detekti iun ajn,activado para detectar alguno,,käyttöön ohjainten havaitsemiseksi,avant de pouvoir en détecter un.,"engedélyezve kell lenni, hogy érzékeljen bármit is.",abilitato a trovare ogni,検出しました,활성화 해야합니다.,om eventuele regelaars te detecteren.,aktivert for å oppdage en hvilken som helst,Włączony by wykryć jakikolwiek,ser ativada para exibi-los.,,activat pentru a putea fi detectate, \n, \n,för att det ska gå att upptäcka några,tespit etmek için etkinleştirildi, \n, +Invalid controller specified for menu,JOYMNU_INVALID,,,,Vybrán nesprávný ovladač pro nabídky,Ugyldig controller angivet til menuen,Ungültiger Controller für Menü ausgewählt,,Nevalida ludregilo specifigita por menuo,Mando inválido especificado para el menú,,Epäkelpo ohjain määritetty valikolle,Contrôleur invalide spécifé dans le menu.,Hibás kontroller van a menühöz osztva,Controller invalido specificato per il menu,メニューではコントローラーを使用しない,메뉴에 특정된 컨트롤러가 아닙니다.,Ongeldige regelaar gespecificeerd voor het menu,Ugyldig kontroller spesifisert for menyen,Niewłaściwy kontroler określony dla menu,Controle inválido especificado para o menu.,Comando inválido,Controller pentru meniu invalid,Недопустимый контроллер выбран для меню,Невалидан контролер специфиран за мени,Ogiltig kontroller har angetts för menyn,Menü için geçersiz denetleyici belirtildi,Для меню вибрано невідповідний контролер, +Overall sensitivity,JOYMNU_OVRSENS,,,,Celková citlivost,Samlet følsomhed,Allgemeine Empfindlichkeit,,Tuta sentemeco,Sensibilidad general,,Yleisherkkyys,Sensibilité générale,Teljes érzékenység,Sensibilità generale,全体的な感度,전체 민감도,Algemene gevoeligheid,Samlet følsomhet,Ogólna Czułość,Sensibilidade geral,,Sensibilitate în ansamblu,Общая чувствительность,Уупна сензитивност,Övergripande känslighet,Genel hassasiyet,Загальна чутливість, +Axis Configuration,JOYMNU_AXIS,,,,Nastavení os,Konfiguration af akserne,Achsenkonfiguration,,Akso-agordoj,Configuración del eje,,Akseleiden säätäminen,Configuration des axes,Tengely konfigurálása,Configurazione assi,軸構成,축 구성,Asconfiguratie,Konfigurasjon av akse,Konfiguruj Oś,Configuração de eixo,,Configurare axă,Конфигурация осей,Конфигурација осе,Konfiguration av axlar,Eksen Konfigürasyonu,Конфігурація осей, +Invert,JOYMNU_INVERT,,,,Obrátit,Invert,Invertieren,,Inversigi,Invertir,,Käännä,Inverser,Megfordítás,Inverti,反転,순서 바꿈,Omkeren,Invertering,Odwróć,Inverter,,Inversare,Инвертировать,Инвертовано,Invertera,Ters çevir,Інвертувати, +Dead zone,JOYMNU_DEADZONE,,,,Mrtvá zóna,Dødzone,Totzone,,Mortozono,Zona muerta,,Kuollut alue,Zone neutre,Holttér,Zona cieca,デッドゾーン,불감대,Dode zone,Død sone,Martwa strefa,Zona morta,,Zonă moartă,Мёртвая зона,Мртва зона,Dödzon,Ölü bölge,Мертва зона, +No configurable axes,JOYMNU_NOAXES,,,,Žádné nastavitelné osy,Ingen konfigurerbare akser,Keine konfigurierbaren Achsen,,Neniuj agordeblaj aksoj,No hay ejes configurables,,Ei säädettäviä akseleita,Aucun axe à configurer,Nincs beállítható tengely,Nessun asse configurabile,軸構成を無効,설정할 방향키가 없습니다.,Geen configureerbare assen,Ingen konfigurerbare akser,Brak osi do skonfigurowania,Nenhum eixo configurável,,Nicio axă configurabilă,Нет настраиваемых осей,Нема конфигурационих оса,Inga konfigurerbara axlar,Yapılandırılabilir eksen yok,Немає настроюваних осей, +None,OPTVAL_NONE,,,,Žádný,Ingen,Kein,,Neniu,Ninguno,,Ei mitään,Aucun,Nincs,Nessuno,無し,없음,Geen,Ingen,Żaden,Nenhum,,Niciuna,Откл.,Ништа,Ingen,Hiçbiri,Вимк., +Turning,OPTVAL_TURNING,,,,Otáčení,Drejning,Umdrehen,,Turnanta,Girar,,Kääntyminen,Tourner,Fordulás,Rotazione,旋回,회전,Draaien,Dreie,Obracanie się,Girar,,Rotire,Поворот,Скретање,Vridning,Dönüş,Поворот, +Looking Up/Down,OPTVAL_LOOKINGUPDOWN,,,,Dívání se nahoru/dolů,Kigger op/ned,Hoch/runterblicken,,Rigardanta (mal)supren,Mirar hacia arriba/abajo,,Ylös/Alas katsominen,Vue haut/bas,Fel-/lenézés,Sguardo Sopra/Sotto,視点上下,위/아래로 보기,Omhoog/omlaag zoeken,Ser opp/ned,Patrzenie w górę/w dół,Olhar para cima/baixo,,Privire Sus/Jos,Взгляд вверх/вниз,Гледање горе/доле,Titta uppåt/nedåt,Yukarı/Aşağı Bakmak,Дивитись вгору, +Moving Forward,OPTVAL_MOVINGFORWARD,,,,Pohyb vpřed,Bevæger sig fremad,Vorwärtsbewegung,,Movanta antaŭen,Avanzar,,Eteenpäin liikkuminen,Avancer,Előre mozgás,Movimento in avanti,前進,앞으로 전진,Voorwaarts bewegen,Beveger seg fremover,Poruszanie się do przodu,Mover-se para a frente,,Deplasare în Față,Движение вперёд,Кретање напред,Rör sig framåt,İleriye Doğru,Рухатись вперед, +Strafing,OPTVAL_STRAFING,,,,Pohyb do stran,Strafing,Seitwärtsbewegung,,Flankmovanta,Desplazarse,,Sivuttaisastunta,Pas de côté,Oldalazás,Movimento laterale,横移動,양옆으로 이동,Strafelen,Straffe,Uniki,Deslocamento lateral,,Deplasare în Diagonală,Движение боком,Кретање у страну,Strafing,Strafing,Рухатись боком, +Moving Up/Down,OPTVAL_MOVINGUPDOWN,,,,Pohyb nahoru/dolů,Bevægelse op/ned,Auf/abwärtsbewegung,,Movanta (mal)supren,Moverse hacia arriba/abajo,,Ylös/Alas liikkuminen,Mouvement haut/bas,Felfele/Lefele mozgás,Movimento Sopra/Sotto,前進後退,위/아래로 이동,Naar boven/beneden bewegen,Beveger seg opp/ned,Poruszanie się w górę/w dół,Mover-se para cima/baixo,,Mișcare Sus/Jos,Движение вверх/вниз,Кретање горе/доле,Rör sig uppåt/nedåt,Yukarı/Aşağı Hareket Etme,Рухатись вгору/вниз, +Inverted,OPTVAL_INVERTED,,,,Inverzní,Omvendt,Invertiert,,Inversigita,Invertido,,Käännetty,Inversé,Felcserélve,Invertito,反転する,반전,Omgekeerd,Invertert,Odwrócony,Invertido,,Inversat,Инвертировано,Обрнуто,Inverterad,Ters çevrilmiş,Інвертовано, +Not Inverted,OPTVAL_NOTINVERTED,,,,Neinverzní,Ikke omvendt,nicht invertiert,,Ne inversigita,No invertido,,Ei käännetty,Non Inversé,Nincs felcserélve,Non invertito,反転しない,반전되지 않음,Niet omgekeerd,Ikke invertert,Nieodwrócony,Não invertido,,Neinversat,Прямо,Не обрнуто,Inte inverterad,Ters Çevrilmemiş,Не інвертовано, +,,Player Menu,,,,,,,,,,,,,,,,,,,,,,,,,,, +Blue,TXT_COLOR_BLUE,,,,Modrá,Blå,Blau,Μπλέ,Blua,Azul,,Sininen,Bleu,Kék,Blu,青,청색,Blauw,Blå,Niebieski,Azul,,Albastru,Синий,Плава,Blå,Mavi,Синій, +Red,TXT_COLOR_RED,,,,Červená,Rød,Rot,Κόκκινο,Ruĝa,Rojo,,Punainen,Rouge,Vörös,Rosso,赤,적색,Rood,Rød,Czerwony,Vermelho,,Roșu,Красный,Црвена,Röd,Kırmızı,Червоний, +Green,TXT_COLOR_GREEN,,,,Zelená,Grøn,Grün,Πράσινο,Verda,Verde,,Vihreä,Vert,Zöld,Verde,緑,녹색,Groen,Grønn,Zielony,Verde,,Verde,Зелёный,Зелена,Grön,Yeşil,Зелений, +Gray,TXT_COLOR_GRAY,,,Grey,Šedá,Grå,Grau,Γκρί,Griza,Gris,,Harmaa,Gris,Szürke,Grigio,灰,회색,Grijs,Grå,Szary,Cinza,,Gri,Серый,Сива,Grå,Gri,Сірий, Dark gray,TXT_COLOR_DARKGRAY,,,"Dark grey -",Tmavě šedá,Mørkegrå,Dunkelgrau,Σκοτεινό γρκί,Malhelgriza,Gris oscuro,,Tummanharmaa,Gris sombre,Sötétszürke,Grigio scuro,鉛,치색,Donkergrijs,Mørkegrå,Ciemnoszary,Cinza escuro,,Gri închis,Тёмно-серый,Тамно сива,Koyu gri,Темно-сірий, -Dark Green,TXT_COLOR_DARKGREEN,,,,Tmavě zelená,Mørkegrøn,Dunkelgrün,Σκοτεινό πράσινο,Malhelverda,Verde oscuro,,Tummanvihreä,Vert sombre,Sötétzöld,Verde scuro,深,흑녹색,Donkergroen,Mørkegrønn,Ciemnozielony,Verde escuro,,Verde închis,Тёмно-зелёный,Тамна зелена,Koyu Yeşil,Темно-зелений, -Brown,TXT_COLOR_BROWN,,,,Hnědá,Brun,Braun,Σκούρο,Bruna,Marrón,,Ruskea,Brun,Barna,Marrone,茶,갈색,Bruin,Brun,Brązowy,Marrom,,Maro,Коричневый,Браон,Kahverengi,Коричневий, -Dark Blue,TXT_COLOR_DARKBLUE,,,,Tmavě modrá,Mørk blå,Dunkelblau,Σκοτεινό μπλέ,Malhelblua,Azul oscuro,,Tummansininen,Bleu sombre,Sötétkék,Blu scuro,紺,,Donkerblauw,Mørkeblå,Ciemnoniebieski,Azul escuro,,Albastru închis,Тёмно-синий,Тамна Плава,Koyu Mavi,Темно-синій, -Light Red,TXT_COLOR_LIGHTRED,,,,Světle červená,Lysrød,Hellrot,Ανοιχτό κόκκινο,Helruĝa,Rojo claro,,Vaaleanpunainen,Rouge clair,Világospiros,Rosso chiaro,丹,옅은 적색,Licht Rood,Lys rød,Jasnoczerwony,Vermelho claro,,Roșu deschis,Светло-красный,Светло црвена,Açık Kırmızı,Світло-червоний, -Yellow,TXT_COLOR_YELLOW,,,,Žlutá,Gul,Gelb,Κίτρινο,Flava,Amarillo,,Keltainen,Jaune,Sárga,Giallo,黄,노란색,Geel,Gul,Żółty,Amarelo,,Galben,Жёлтый,Жута,Sarı,Жовтий, -Purple,TXT_COLOR_PURPLE,,,,Fialová,Lilla,Violett,Μόβ,Purpura,Morado,,Purppura,Violet,Lila,Viola,紫,보라색,Paars,Lilla,Fioletowy,Roxo,,Mov,Фиолетовый,Љубичаста,Mor,Фіолетовий, -Olive,TXT_COLOR_DULLGREEN,,,,Bledě zelená,Oliven,Blassgrün,,Olivkolora,Oliva,,Haaleanvihreä,Vert pâle,Olíva,Verde pallido,苔,암녹색,Saaie groen,Oliven,Matowa Zieleń,Verde oliva,,Măsliniu,Мутно-зелёный,Тупа зелена,Zeytin,Темний жовто-зелений, -Beige,TXT_COLOR_BEIGE,,,,Béžová,Beige,,Μπέζ,Flavgriza,Beis,Beige,Beesi,,Bézs,,淡,담갈색,Beige,Beige,Beżowy,Bege,,Bej,Бежевый,Беж,Bej,Бежевий, -Light Green,TXT_COLOR_LIGHTGREEN,,,,Světle zelená,Lysegrøn,Hellgrün,Ανοιχτό Πράσινο,Helverda,Verde claro,,Vaaleanvihreä,Vert clair,Világoszöld,Verde chiaro,葵,옅은 녹색,Licht groen,Lysegrønn,Jasonzielony,Verde claro,,Verde Deschis,Светло-зелёный,Светло зелена,Açık Yeşil,Світло-зелений, -Light Blue,TXT_COLOR_LIGHTBLUE,,,,Světle modrá,Lys blå,Hellblau,Γαλάζιο,Helblua,Azul claro,,Vaaleansininen,Bleu clair,Világoskék,Blu chiaro,空,옅은 청색,Licht blauw,Lyseblå,Jasnoniebieski,Azul claro,,Albastru Deschis,Светло-синий,Светло плава,Açık Mavi,Світло-синій, -Light Gray,TXT_COLOR_LIGHTGRAY,,,Light Grey,Světle šedá,Lysegrå,Hellgrau,Ανοιχτό Γκρι,Helgriza,Gris claro,,Vaaleanharmaa,Gris clair,Világosszürke,Grigio chiaro,鉛,옅은 회색,Lichtgrijs,Lysegrå,Jasnoszary,Cinza claro,,Gri Deschis,Светло-серый,Светло сива,Açık Gri,Світло-сірий, -Light Brown,TXT_COLOR_LIGHTBROWN,,,,Světle hnědá,Lys brun,Hellbraun,Ανοιχτό Καφέ,Helbruna,Marrón claro,,Vaaleanruskea,Brun clair,Világosbarna,Marrone chiaro,褐,옅은 고동색,Lichtbruin,Lysebrun,Jasnobrązowy,Marrom claro,,Maro Deschis,Светло-коричневый,Светло браон,Açık Kahverengi,Світло-коричневий, -Gold,TXT_COLOR_GOLD,,,,Zlatá,Guld,,Χρυσό,Orkolora,Dorado,,Kulta,Or,Arany,Oro,金,금색,Goud,Gull,Złoty,Dourado,,Auriu,Золотой,Златна,Altın,Золотий, -Bright Green,TXT_COLOR_BRIGHTGREEN,,,,Jasně zelená,Lysegrøn,Hellgrün,Φωτινό Πράσινο,Brilverda,Verde claro,,Vaaleanvihreä,Vert clair,Fényeszöld,Verde chiaro,鮮,밝은 녹색,Helder groen,Lysegrønn,Jasnozielony,Verde claro,,Verde Deschis,Ярко-зелёный,Светла зелена,Parlak Yeşil,Яскраво-зелений, -Rust,TXT_COLOR_RUST,,,,Rezavá,Rust,Rostbraun,Σκουριά,Rustokolora,Óxido,,Ruoste,Rouille,Rozsda,Arrugginito,錆,주황 적갈색,Roest,Rust,Rdzawy,Ferrugem,,Ruginiu,Ржавый,Рђа,Pas,Іржавий, -Name,PLYRMNU_NAME,,,,Jméno,Navn,,Όνομα,Nomo,Nombre,,Nimi,Nom,Név,Nome,名前,이름,Naam,Navn,Imię,Nome,,Nume,Имя,Надимак,İsim,Ім'я, -Team,PLYRMNU_TEAM,,,,Tým,,,Ομάδα,Teamo,Equipo,,Joukkue,Equipe,Csapat,Squadra,チーム,팀,Team,Lag,Drużyna,Equipe,Equipa,Echipă,Команда,Тим,Takım,Команда, -Color,PLYRMNU_PLAYERCOLOR,,,Colour,Barva,Farve,Farbe,Χρώμα,Koloro,,,Väri,Couleur,Szín,Colore,色,색상,Kleur,Farge,Kolor,Cor,,Culoare,Цвет,Боја,Renk,Колір, -Gender,PLYRMNU_PLAYERGENDER,,,,Pohlaví,Køn,Geschlecht,Φύλο,Genro,Género,,Sukupuoli,Genre,Nem,Sesso,性別,성별,Geslacht,Kjønn,Płeć,Gênero,,Sex,Пол,Пол,Cinsiyet,Стать, -Male,OPTVAL_MALE,,,,Muž,Mand,Männlich,Αρσενικό,Vira,Masculino,,Miespuolinen,Masculin,Férfi,Maschio,男,남성,Man,Mannlig,Mężczyzna,Masculino,,Masculin,Мужской,Мушко,Erkek,Чоловіча, -Female,OPTVAL_FEMALE,,,,Žena,Kvinde,Weiblich,Θηλυκό,Ina,Femenino,,Naispuolinen,Féminin,Nő,Femmina,女,여성,Vrouw,Kvinne,Kobieta,Feminino,,Feminin,Женский,Женско,Kadın,Жіноча, -Neutral,OPTVAL_NEUTRAL,,,,Neutrální,Neutral,Neutral,Ουδέτερο,Neŭtra (Ri),Neutro,,Sukupuoleton,Neutre,Semleges,Neutrale,中間,중성,Neutraal,Nøytral,Neutralne,Neutro,,Neutru,Нейтральный,Неутрално,Nötr,Нейтральна, -Object,OPTVAL_OTHER,,,,Objekt,Objekt,Objekt,Αντικείμενο,Objekto (Ĝi),Objeto,,Olio,Objet,Tárgy,Oggetto,物体,기타,Doel,Gjenstand,Obiekt,Objeto,,Obiect,Предмет,Предмет,Nesne,Предмет, -Gameplay Options,GMPLYMNU_TITLE,,,,Nastavení herních mechanik,Gameplay-muligheder,Gameplay-Optionen,,Ludado-agordoj,Opciones de jugabilidad,,Pelattavuusasetukset,Options Gameplay,Játékmenet beállításai,Opzioni gameplay,ゲームプレイ オプション,게임플레이 설정,Gameplay-opties,Spillalternativer,Opcje Rozgrywki,Opções de jogabilidade,,Setări de Joc,Настройки игры,Подешавања гејмплеја,Oynanış Seçenekleri,Налаштування гри, -Always,OPTVAL_ALWAYS,,,,Vždy,Altid,Immer,Πάντα,Ĉiam,Siempre,,Aina,Toujours,Mindig,Sempre,常に,언제나,Altijd,Alltid,Zawsze,Sempre,,Mereu,Всегда,Увек,Her zaman,Завжди, -Never,OPTVAL_NEVER,,,,Nikdy,Aldrig,Nie,Ποτέ,Neniam,Nunca,,Ei koskaan,Jamais,Soha,Mai,しない,없음,Nooit,Aldri,Nigdy,Nunca,,Niciodată,Никогда,Никад,Asla,Ніколи, -Autoaim,PLYRMNU_AUTOAIM,,,,Automatické míření,Autoaim,Automatisch zielen,,Celasisto,Autoapuntar,,Automaattitähtäys,Auto-visée,Automatikus célzás,Mira automatica,自動照準,자동 조준,Autoaim,Autoaim,Auto-celowanie,Mira automática,,Autoțintire,Автоприцеливание,Аутоматско циљање,Autoaim,Автонаведення, -Always Run,PLYRMNU_ALWAYSRUN,,,,Vždy běžet,Altid løbe,Immer Rennen,Πάντα τρέχα,Ĉiam kuri,Siempre correr,,Jatkuva juoksu,Toujours courir,Mindig fusson,Corri sempre,常に駆け足,달리기 토글,Altijd lopen,Kjør alltid,Zawsze Biegaj,Sempre correr,Correr Sempre,Fugă în permanență,Постоянный бег,Увек трчи,Daima Koş,Постійно бігти, -,,Display,,,,,,,,,,,,,,,,,,,,,,,,,, -Screen size,DSPLYMNU_SCREENSIZE,,,,Velikost obrazovky,Skærmstørrelse,Bildschirmgröße,Μέγεθος οθόνης,Ekrangrando,Tamaño de pantalla,,Näytön koko,Taille de l'écran,Képernyő mérete,Dimensione della schermata,画面サイズ,화면 크기,Schermgrootte,Skjermstørrelse,Rozmiar Ekranu,Tamanho da tela,Tamanho do ecrã,Mărime ecran,Размер экрана,Величина екрана,Ekran boyutu,Розмір екрану, -Vertical Sync,DSPLYMNU_VSYNC,,,,Vertikální synchronizace,Lodret synkronisering,Vertikale Synchronisation,,Vertikala-sinkronigo,Sincronización vertical,,Pystytahdistys,Synchronisation Verticale,Függőleges szinkronizálás,Sincronia verticale,垂直同期,수직 동기화,Verticale Sync,Vertikal synkronisering,Synchronizacja Pionowa,Sincronização vertical,,Sincronizare Verticală,Вертикальная синхронизация,Вертикална синхорнизација,Dikey Senkronizasyon,Вертикальна синхронізація, -Models,DSPLYMNU_MODELS,,,,Modely,Modeller,Modelle,Μοντέλα,Modeloj,Modelos,,Mallit,Modèles,3D modellek,Modelli,モデル,모델,Modellen,Modeller,Modele,Modelos,,Modele,Модели,Модели,Modeller,3D Моделі, -Scale crosshair,DSPLYMNU_CROSSHAIRSCALE,,,,Velikost zaměřovače,Skalerer trådkorset,Fadenkreuz skalieren,,Skali reteton,Escalar retícula,,Skaalaa tähtäintä,Mise à l'échelle du viseur,Célkereszt méret,Scala del mirino,照準スケール,조준점 크기,Dradenkruis schalen,Skala trådkors,Skala celownika,Escala da mira,,Scară țintă,Размер прицела,Размера нишана,Ölçekli artı işareti,Розмір прицілу, -Brightness,DSPLYMNU_BRIGHTNESS,,,,Jas,Lysstyrke,Helligkeit,Φωτηνότητα,Brileco,Brillo,,Kirkkaus,Luminosité,Fényerő,Luminosità,明るさ,밝기,Helderheid,Lysstyrke,Jasność,Brilho,,Luminozitate,Яркость,Осветљење,Parlaklık,Яскравість, -Gamma correction,DSPLYMNU_GAMMA,,,,Korekce gama,Gammakorrektion,Gammakorrektur,,Gamaa korektado,Corrección gamma,,Gammakorjaus,Correction Gamma,Gamma korrekció,Correzione gamma,ガンマ値,감마 조정,Gamma correctie,Gammakorreksjon,Korekta gammy,Correção de gama,,Gamma,Гамма-коррекция,Корекција светлости,Gama düzeltme,Гамма-корекція, -Contrast,DSPLYMNU_CONTRAST,,,,Kontrast,Kontrast,Kontrast,,Kontrasto,Contraste,,Sävykkyys,Contraste,Kontraszt,Contrasto,コントラスト,대비,,Kontrast,Kontrast,Contraste,,,Контраст,Контраст,Kontrast,Контраст, -Saturation,DSPLYMNU_SATURATION,,,,Sytost,Mætning,Sättigung,,Satureco,Saturación,,Värikylläisyys,,Telítettség,Saturazione,サチュレーション,채도,Verzadiging,Metning,Nasycenie,Saturação,,Saturație,Насыщенность,Сатурација,Doygunluk,Насиченість, -Status Bar Scale,DSPLYMNU_SBSCALE,,,,Velikost stavového panelu,Skala for statuslinje,Statusleistengröße,,Skalo de stata breto,Escala de barra de estado,,Tilapalkin skaalaus,Mise à l'échelle HUD,Állapotjelző mérete,Dimensioni Status Bar,ステータススケール,,Statusbalkschaal,Statuslinjeskala,Skala paska statusu,Escala da barra de estado,,Scară bară de stare,Размер строки состояния,,Durum Çubuğu Ölçeği,Розмір строки стану, -Messages,DSPLYMNU_MESSAGES,,,,Oznámení,Meddelelser,Nachrichten,Μηνύματα,Mesaĝoj,Mensajes,,Viestit,Messages,Üzenetek,Messaggi,メッセージ類,메시지,Berichten,Meldinger,Wiadomości,Mensagens,,Mesaje,Сообщения,Поруке,Mesajlar,Повідомлення, -Center messages,MSGMNU_CENTERMESSAGES,,,Centre messages,Oznámení na střed,Centrerede meddelelser,Nachrichten zentrieren,,Centrigi mesaĝojn,Centrar mensajes,,Keskitä viestit,Messages centrés,Üzenetek középre helyezése,Messaggi centrati,メッセージを中央に,메시지 중간에 위치,Berichten centreren,Sentrumsmeldinger,Wyśrodkuj wiadomości,Centralizar mensagens,Centrar mensagens,Mesaje centrate,Центрирование сообщений,Централне поруке,Merkez mesajları,Центрування повідомлень, -Pulsating message Display,MSGMNU_PULSEMESSAGES,,,,Pulzující oznámení,Pulserende meddelelser Visning,Pulsierende Nachrichtenanzeige,,Pulsanta mesaĝ-montrejo,Mostrar mensajes pulsantes,,Sykkivät viestit,Messages pulsés,Pulzáló üzenet,Mostra messaggi pulsanti,取得時等の文を明滅,,Pulserende berichtendisplay,Pulserende melding Display,Pulsujące wyświetlanie wiadomości,Exibir mensagem pulsante,,Afișare Mesaje Pulsante,Пульсация сообщений,,Titreşimli mesaj Ekranı,Пульсація повідомлень, -Message Scale,MSGMNU_MESSAGESCALE,,,,Velikost oznámení,Skala for meddelelser,Nachrichtengröße,Μέγεθος μηνύματον,Skalo de mesaĝoj,Escala de mensajes,,Viestien skaalaus,Mise à l'échelle Messages,Üzenet mérete,Dimensioni Messaggi,メッセージスケール,,Berichtschaal,Meldingsskala,Skalowanie Wiadomości,Escala de mensagem,,Scară Mesaje,Размер сообщений,,Mesaj Ölçeği,Розмір повідомлень, -,,Automap,,,,,,,,,,,,,,,,,,,,,,,,,, -Select Color,MNU_COLORPICKER,,,Select Colour,Výběr barvy,Vælg farve,Farbe auswählen,Επιλογή Χρώματος,Elektu koloron:,Elige un color,,Valitse väri,Choisir Couleur,Szín választása,Scegli il colore,色選択,색상을 고르시오,Selecteer Kleur,Velg farge,Wybierz Kolor,Selecione uma cor,,Alege o Culoare,Выбор цвета,Изабери боју,Renk Seçiniz,Вибір кольору, -Rotate automap,AUTOMAPMNU_ROTATE,,,,Otáčet automapu,Rotere automap,Rotiere Automap,,Turni aŭtomapon,Rotar automapa,,Kiertyvä automaattikartta,Rotation de la Carte,Térkép forgatása,Ruota l'automappa,オートマップの回転表示,오토맵 회전,Automatisch roteren,Roter automatisk kart,Obracaj mapę,Girar automapa,,Rotire hartă computerizată,Вращающаяся автокарта,Ротирај аутомапу,Otomatik haritayı döndür,Обертання автокарти, -Follow player,AUTOMAPMNU_FOLLOW,,,,Následovat hráče,Følg spilleren,Folge dem Spieler,Ακουλούθα το παίχτη,Sekvi ludanton,Seguir jugador,,Seuraa pelaajaa,Suivre le joueur,Kövesse a játékost,Segui il giocatore,プレイヤー追従,플레이어 추적,Volg de speler,Følg spiller,Podążaj za graczem,Seguir jogador,,Urmărire jucător,Привязка к игроку,Прати играча,Oyuncuyu takip et,Прив'язка до гравця, -Line alpha,AUTOMAPMNU_LINEALPHA,,,,Průhlednost čar,Linje alfa,Alpha für Linien,,Travidebleca de linio,Transparencia de línea,,Viivan alpha,Translucidité des lignes,Vonal áttetszóség,Traslucenza delle linee,線の半透明度,선 반투명도,Doorschijnendheid van lijnen,Linje alfa,Przezroczystość Linii,Transparência da linha,,Transparență linii,Прозрачность линий,Транслуценција линија,Çizgi alfa,Прозорість ліній, -Line thickness,AUTOMAPMNU_LINETHICKNESS,,,,Tloušťka čar,Linjetykkelse,Dicke der Linien,,Dikeca de linio,Grosor de línea,,Viivan paksuus,Épaisseur des lignes,Vonal vastagság,Spessore delle linee,線の太さ,선 두께,Dikte van lijnen,Linjetykkelse,Grubość Linii,Espessura da linha,,Grosime linii,Толщина линий,Дебљина линија,Çizgi kalınlığı,Товщина ліній, -Customize Map Colors,MAPCOLORMNU_TITLE,,,Customize Map Colours,Nastavení barev mapy,Tilpas kortfarver,Automapfarben einstellen,,Adapti mapkolorojn,Personalizar colores (mapa),,Värien mukautus,Couleurs Carte Personnalisées,Térkép színeinek testreszabása,Personalizza i colori della mappa,カスタム色を決める,미니맵 색상 설정,Kaartkleuren aanpassen,Tilpass kartfarger,Ustaw kolory mapy,Personalizar cores do mapa,,Personalizare culori hartă,Настройки цветов автокарты,Промени боју мапе,Harita Renklerini Özelleştirin,Налаштування кольорів автокарти, -Restore default custom colors,MAPCOLORMNU_DEFAULTMAPCOLORS,,,Restore default custom colours,Obnovit původní vlastní barvy,Gendan standard brugerdefinerede farver,Standardfarben wiederherstellen,,Restaŭri defaŭltajn laŭmendajn kolorojn,Restaurar colores personalizados,,Palauta oletusvärit,Couleurs par défaut,Eredeti színek visszaállítása,Reimposta i colori personalizzati al default,カスタム色を初期化,기본 색상으로 복구,Standaard aangepaste kleuren herstellen,Gjenopprett egendefinerte standardfarger,Przywróć domyślne kolory,Restaurar cores personalizadas padrão,,Revenire la culorile implicite,Вернуть стандартные цвета,Врати уобичајене разне боје,Varsayılan özel renkleri geri yükleme,Повернути стандартні кольори, -,,Sound,,,,,,,,,,,,,,,,,,,,,,,,,, -Sound enabled,SNDMNU_SNDENABLED,,,,Zvuk zapnut,Lyd aktiveret,Sound aktiv,Ήχος ενεργοποιημένος,Sono ŝaltita,Sonido activado,,Ääni päällä,Son activé,Hang engedélyezve,Abilita gli effetti sonori,サウンド有効,,Geluid actief,Lyd aktivert,Dźwięk włączony,Som ativado,,Sunet activat,Звук включён,,Ses etkin,Звук вимкнено, -Music enabled,SNDMNU_MUSENABLED,,,,Hudba zapnuta,Musik aktiveret,Musik aktiv,Μουσική ενεργοποιημένη,Muziko ŝaltita,Música activada,,Musiikki päällä,Musique activée,Zene engedélyezve,Abilita la musica,音楽有効,,Muziek actief ,Musikk aktivert,Muzyka włączona,Música ativada,,Muzică activată,Музыка включена,,Müzik etkin,Музику вимкнено, -4000 Hz,OPTVAL_4000HZ,,,,,,,,,,,,,,,,,,,,,,,4000 Гц,,,4000 Гц, -8000 Hz,OPTVAL_8000HZ,,,,,,,,,,,,,,,,,,,,,,,8000 Гц,,,8000 Гц, -11025 Hz,OPTVAL_11025HZ,,,,,,,,,,,,,,,,,,,,,,,11025 Гц,,,11025 Гц, -22050 Hz,OPTVAL_22050HZ,,,,,,,,,,,,,,,,,,,,,,,22050 Гц,,,22050 Гц, -32000 Hz,OPTVAL_32000HZ,,,,,,,,,,,,,,,,,,,,,,,32000 Гц,,,32000 Гц, -44100 Hz,OPTVAL_44100HZ,,,,,,,,,,,,,,,,,,,,,,,44100 Гц,,,44100 Гц, -48000 Hz,OPTVAL_48000HZ,,,,,,,,,,,,,,,,,,,,,,,48000 Гц,,,48000 Гц, -64 samples,OPTVAL_64SAMPLES,,,,64 vzorků,,,64 δείγματα,64 specimenoj,64 muestras,,64 näytettä,,,,,64 샘플,,64 samplinger,64 sample,64 amostras,,64 monstre,64 семпла,64 узорка,64 örnek,64 семпла, -128 samples,OPTVAL_128SAMPLES,,,,128 vzorků,,,128 δείγματα,128 specimenoj,128 muestras,,128 näytettä,,,,,128 샘플,,128 samplinger,128 sampli,128 amostras,,128 monstre,128 семплов,128 узорка,128 örnek,128 семплів, -256 samples,OPTVAL_256SAMPLES,,,,256 vzorků,,,256 δείγματα,256 specimenoj,256 muestras,,256 näytettä,,,,,256 샘플,,256 samplinger,256 sampli,256 amostras,,256 monstre,256 семплов,256 узорка,256 örnek,256 семплів, -512 samples,OPTVAL_512SAMPLES,,,,512 vzorků,,,512 δείγματα,512 specimenoj,512 muestras,,512 näytettä,,,,,512 샘플,,512 samplinger,512 sampli,512 amostras,,512 monstre,512 семплов,512 узорка,512 örnek,512 семплів, -1024 samples,OPTVAL_1024SAMPLES,,,,1024 vzorků,,,1024 δείγματα,1024 specimenoj,1024 muestras,,1024 näytettä,,,,,1024 샘플,,1024 samplinger,1024 sampli,1.024 amostras,,1024 monstre,1024 семпла,1024 узорка,1024 örnek,1024 семплів, -2048 samples,OPTVAL_2048SAMPLES,,,,2048 vzorků,,,2048 δείγματα,2048 specimenoj,2048 muestras,,2048 näytettä,,,,,2048 샘플,,2048 samplinger,2048 sampli,2.048 amostras,,2048 monstre,2048 семплов,2048 узорка,2048 örnek,2048 семплів, -4096 samples,OPTVAL_4096SAMPLES,,,,4096 vzorků,,,4096 δείγματα,4096 specimenoj,4096 muestras,,4096 näytettä,,,,,4096 샘플,,4096 samplinger,4096 sampli,4.096 amostras,,4096 monstre,4096 семплов,4096 узорка,4096 örnek,4096 семплів, -Auto,OPTSTR_AUTO,,,,,Automatisk,,,Aŭtomata,Automático,,Automaattinen,,Automatikus,Automatico,自動,오토,,,Automatycznie,Automático,,,Авто,Аутоматски,Otomatik,Авто, -Mono,OPTSTR_MONO,,,,,,,,Monofonia,,,,,Monó,,モノラル,모노,,,,,,,Моно,Монотоно,,Моно, -Stereo,OPTSTR_STEREO,,,,,,,,Stereofonia,Estéreo,,,Stéréo,Sztereó,,ステレオ,스테레오,,,,Estéreo,,,Стерео,Стереотоно,,Стерео, -Dolby Pro Logic Decoder,OPTSTR_PROLOGIC,,,,,Dolby Pro Logic-dekoder,,,Malkodilo de Dolby Pro Logic ,,,,,,,ドルビー プロロジック デコーダー,돌비 프로 로직 디코더,,Dolby Pro Logic Dekoder,,Decodificador Dolby Pro Logic,,Decodor Pro Logic Dolby,Декодер Dolby Pro Logic,,Dolby Pro Logic Dekoder,Декодер Dolby Pro Logic, -Quad,OPTSTR_QUAD,,,,,,,,Kvadratofonia,Cuádruple,,Dolby Pro Logic -dekooderi,,,,クァッド,쿼드,,,Cztery kanały,Quadrifônico,,,Четырёхканальный,Четвородупло,Dörtlü,Чотирьохканальний, -5 speakers,OPTSTR_SURROUND,,,,5 reproduktorů,5 højttalere,5 Lautsprecher,,5 Laŭtparoliloj,5 altavoces,,5 kaiutinta,5 enceintes,5 hangfal,Surround,5 スピーカー,5 스피커,5 luidsprekers,5 høyttalere,Głośniki 5,5 alto-falantes,,5 boxe,5 динамиков,5 спикер,5 hoparlörler,5 динаміків, -5.1 speakers,OPTSTR_5POINT1,,,,Reproduktory 5.1,5.1-højttalere,5.1 Lautsprecher,,5.1 Laŭtparoliloj,Altavoces 5.1,,5.1 kaiutinta,Enceintes 5.1,5.1 hangrendszer,Surround 5.1,5.1 スピーカー,5.1 스피커,5.1 luidsprekers,5.1 høyttalere,Głośniki 5.1,Auto-falantes 5.1,,Boxe 5.1,Динамики 5.1,5.1 спикер,5.1 hoparlörler,Динаміки 5.1, -7.1 speakers,OPTSTR_7POINT1,,,,Reproduktory 7.1,7.1-højttalere,7.1 Lautsprecher,,7.1 Laŭtparoliloj,Altavoces 7.1,,7.1 kaiutinta,Enceintes 7.1,7.1 hangrendszer,Surround 7.1,7.1 スピーカー,7.1스피커,7.1 luidsprekers,7.1-høyttalere,Głośniki 7.1,Auto-falantes 7.1,,Boxe 7.1,Динамики 7.1,7.1 спикер,7.1 hoparlörler,Динаміки 7.1, -Playback device,OPENALMNU_PLAYBACKDEVICE,,,,Přehravací zařízení,Afspilningsenhed,Wiedergabegerät,,Ludado-aparato,Dispositivo de reproducción,,Äänitoistolaite,Sortie sonore,Visszajátszó eszköz,Dispositivo di playback,プレイバック デバイス,재생 장치,Afspeelapparaat,Avspillingsenhet,Urządzenie odtwarzania,Dispositivo de reprodução,,Dispozitiv de redare,Устройство воспроизведения,Аудио уређај,Oynatma cihazı,Пристрій відтворення, -Enable EFX,OPENALMNU_ENABLEEFX,,,,Povolit EFX,Aktiver EFX,EFX aktiv,,Ŝalti EFX,Permitir EFX,,Ota käyttöön EFX,Activer EFX,EFX engedélyezése,Abilita EFX,EFXを有効化,EFX 켬,EFX inschakelen,Aktiver EFX,Pozwól na EFX,Ativar EFX,,Activare EFX,Включить EFX,Укључи EFX,EFX'i Etkinleştir,Увімкнути EFX, -Resampler,OPENALMNU_RESAMPLER,,,,,Resampler,,,Respecimenilo,,,Näytteenottotaajuusmuunnin,,,,リサンプラー,재배열 기기,,,Resampler,Reamostrador,,,Передискретизатор,Ресемплер,Yeniden Örnekleyici,Ресемплер, -Sounds volume,SNDMNU_SFXVOLUME,,,,Hlasitost zvuků,Lydstyrke,Effektlautstärke,Φονή ήχων,Sona laŭteco,Volumen de sonido,,Äänitehosteiden voimakkuus,Volume des Sons,Effektek hangereje,Volume suoni,効果音音量,효과음 음량,Geluidsvolume,Lydvolum,Głośność Dźwięku,Volume de sons,,Volum efecte,Громкость звука,Јачина звука,Ses seviyesi,Гучність звуків, -Menu volume,SNDMNU_MENUVOLUME,,,,Hlasitost nabídek,Menu-volumen,Menülautstärke,Φονή μενού,Menuo-laŭteco,Volumen del menú,,Valikon äänenvoimakkuus,Volume du Menu,Menü hangereje,Volume menù,メニュー音量,메뉴 음량,Menu volume,Menyvolum,Głośność Menu,Volume do menu,,Volum meniu,Громкость меню,Јачина менија,Menü ses seviyesi,Гучність меню, -Music volume,SNDMNU_MUSICVOLUME,,,,Hlasitost hudby,Lydstyrke for musik,Musiklautstärke,Φονή μουσικής,Muzika laŭteco,Volumen de la música,,Musiikin äänenvoimakkuus,Volume Musique,Zene hangereje,Volume musica,音楽音量,배경음 음량,Muziekvolume,Musikkvolum,Głośność Muzyki,Volume da música,,Volum muzică,Громкость музыки,Јачина музике,Müzik sesi,Гучність музики, -MIDI device,SNDMNU_MIDIDEVICE,,,,MIDI zařízení,MIDI-enhed,MIDI-Gerät,MIDI συσκεύη,MIDI-aparato,Dispositivo MIDI,,MIDI-laite,Sortie MIDI,MIDI eszköz,Dispositivo MIDI,MIDIデバイス,MIDI 장치,MIDI-apparaat,MIDI-enhet,Urządzenie MIDI,Dispositivo MIDI,,Dispozitiv MIDI,MIDI-проигрыватель,MIDI уређај,MIDI cihazı,MIDI програвач, -Sound in Background,SNDMNU_BACKGROUND,,,,Zvuk na pozadí,Lyd i baggrunden,Sound im Hintergrund,Ήχος στο παρασκήνιο,Sono en fono,Sonido en segundo plano,,Ääni taustalla,Son activé en arrière plan,Háttérhangok,Suono di sottofondo,バックグラウンドでのサウンド,배경화면에서도 소리 재생,Geluid in de achtergrond,Lyd i bakgrunnen,Dźwięk w Tle,Som em segundo plano,,Sunet pe fundal,Звук в фоне,Звуци у позадини,Arka Planda Ses,Звуки на фоні, -Underwater reverb,SNDMNU_UNDERWATERREVERB,,,,Ozvěna pod vodou,Undervandsreverb,Unterwasserhall,,Subakva resono,Reverberación bajo el agua,,Vedenalaiskaiku,Reverbération sous l'eau,Vízalatti visszaverődés,Reverb sott'acqua,水中反響音,수중 울림효과,Onderwater nagalm,Undervanns romklang,Pogłos pod wodą,Reverberação debaixo d'água,Reverberação debaixo de água,Reverb subacvatic,Эффект затухания под водой,Подводни одјек,Su altı yankısı,Підводний ефект, -Randomize pitches,SNDMNU_RANDOMIZEPITCHES,,,,Náhodné výšky tónu,Randomisere tonehøjder,Zufällige Tonhöhe,,Malcertigi son-peĉojn,Tonos aleatorios,,Satunnaista äänenkorkeuksia,Tons sonores aléatoires,Hangmagasság keverése,Rendi casuale il tono,ランダマイズ ピッチ,음높이 무작위화,Willekeurige plaatsen,Tilfeldig tonehøyde,Losuj tonacje,Tons aleatórios,Tons aleatórios,Ton sunete aleatoriu,Случайная высота,Рандомизација тонова,Sahaları rastgele ayarlayın,Випадкова висота, -Sound channels,SNDMNU_CHANNELS,,,,Počet zvukových kanálů,Lydkanaler,Soundkanäle,Κανάλια ήχου,Sonokanaloj,Canales de sonido,,Äänikanavat,Canaux sonores,Hangcsatorna,Numero canali del suono,サウンド チャンネル,음향 채널,Geluidskanalen,Lydkanaler,Kanały dźwiękowe,Canais de som,,Canale de sunet,Количество каналов,Звучни канали,Ses kanalları,Кількість каналів, -Sound backend,SNDMNU_BACKEND,,,,Zvukový systém,Lyd backend,Soundsystem,,Sonoservilo,Sistema de sonido,,Äänijärjestelmä,Traitement Son,Hang backend,Backend suono,サウンド バックエンド,음향 말미,Geluidsarme achterkant,Lyd backend,System dźwiękowy,Sistema de som,,Sistem de sunet,Звуковая подсистема,Звучни бекенд,Ses arka ucu,Звукова система, -OpenAL options,SNDMNU_OPENAL,,,,Nastavení OpenAL,OpenAL-muligheder,OpenAL Optionen,OpenAL ρυθμίσεις,OpenAL agordoj,Opciones de OpenAL,,OpenAL-asetukset,Options OpenAL,OpenAL beállításai,Opzioni OpenAL,OpenAL オプション,오픈에이엘 설정,OpenAL opties,OpenAL-alternativer,Opcje OpenAL,Opções de OpenAL,,Setări OpenAL,Настройки OpenAL,OpenAL подешавања,OpenAL seçenekleri,Параметри OpenAL, -Restart sound,SNDMNU_RESTART,,,,Restartovat zvuk,Genstart af lyd,Sound neu starten,,Rekomenci sonon,Reiniciar sonido,,Käynnistä ääni uudelleen,Redémarrer moteur sonore,Hang újraindítása,Resetta il suono,サウンド再起動,음향 재시작,Herstart geluid,Start lyd på nytt,Zresetuj dźwięk,Reiniciar som,,Reinițializare sunet,Перезапустить звук,Поново покрени звук,Sesi yeniden başlat,Перезавантажити звук, -Advanced options,SNDMNU_ADVANCED,,,,Pokročilá nastavení,Avancerede indstillinger,Erweiterte Optionen,Προχήρημενες ρυθμίσεις,Altnivelaj agordoj,Opciones avanzadas,,Edistyneet asetukset,Options avancées,Haladó beállítások,Opzioni avanzate,高度なオプション,고급 설정,Geavanceerde opties,Avanserte alternativer,Zaawansowane Opcje,Opções avançadas,,Setări avansate,Расширенные настройки,Напредна подешавања,Gelişmiş seçenekler,Розширені налаштування, -Module replayer options,SNDMNU_MODREPLAYER,,,,Nastavení přehrávače modulů,Indstillinger for modulafspiller,Modul-Spieler-Optionen,,Agordoj por modulreludilo,Opciones reproductor de módulos,,Moduulisoitinasetukset,Options lecteur de module,Modul lejátszó beállításai,Opzioni Module replayer,モジュールリプレイヤー オプション,모듈 재생 설정,Module replayer opties,Alternativer for modulavspiller,Opcje Modułu Odtwarzacza,Opções de reprodutor de módulos,,Setări de redare a modulelor,Параметры воспроизведения модулей,Подешавања модулног риплејера,Modül yeniden oynatıcı seçenekleri,Параметри відтворення модулів, -Midi player options,SNDMNU_MIDIPLAYER,,,,Nastavení MIDI přehrávače,Indstillinger for Midi-afspiller,MIDI-Spieler-Optionen,,Agordoj por MIDI-ludilo,Opciones de reproductor MIDI,,MIDI-soitinasetukset,Option lecteur MIDI,Midi lejátszó beállításai,Opzioni Midi player,Midi再生のオプション,MIDI 플레이어 설정,Midi speler opties,Alternativer for midispiller,Opcje Odtwarzacza Midi,Opções de reprodutor MIDI,,Setări player MIDI,Настройки MIDI-проигрывателя,MIDI плејер подешавања,Midi oynatıcı seçenekleri,Параметри MIDI-програвача, -Sound in Menus,SNDMNU_MENUSOUND,,,,Zvuk v menu,Lyd i menuer,Sound in Menüs,,Sono en menuoj,,,Ääni valikoissa,,Hang a menükben,Suono nei menù,メニューでのサウンド,,Geluid in menu's,Lyd i menyer,Dźwięk w Menu,Som em menus,,Sunet in meniuri,Звук в меню,,Menülerde Ses,Звук в меню, -Advanced Sound Options,ADVSNDMNU_TITLE,,,,Pokročilá nastavení zvuku,Avancerede lydindstillinger,Erweiterte Soundoptionen,,Altnivelaj sonaj agordoj,Opciones avanzadas de sonido,,Edistyneet ääniasetukset,Options Sonores Avancées,Haladó hangbeállítások,Opzioni avanzate dei suoni,高度なサウンドオプション,고급 음향 설정,Geavanceerde geluidsopties,Avanserte lydalternativer,Zaawansowane Opcje Dźwięku,Opções de áudio avançadas,,Setări de sunet avansate,Расширенные настройки,Напредна подешавања звука,Gelişmiş Ses Seçenekleri,Розширені налаштування звуку, -Sample rate,ADVSNDMNU_SAMPLERATE,,,,Vzorkovací frekvence,Samplerate,Samplerate,,Specimenrapideco,Frecuencia de muestreo,,Näytteenottotaajuus,Cadence de Sampling,Mintavételezési ráta,,サンプルレート,샘플링레이트,Steekproeftarief,Samplingsfrekvens,Częstotliwość próbkowania,Taxa de amostragem,,Frecvență de eșantionare,Частота дискретизации,Фреквенција узорковања,Örnek oranı,Частота дискретизації, -HRTF,ADVSNDMNU_HRTF,,,,,,,,,,,,,,,,머리전달함수,,,,,,,,,,, -OPL Synthesis,ADVSNDMNU_OPLSYNTHESIS,,,,Emulace OPL,OPL-syntese,OPL Synthese,,OPL-sintezo,Síntesis OPL,,OPL-synteesi,Synthèse OPL,OPL szintézis,,OPLシンセサイズ,OPL 합성,OPL synthese,OPL-syntese,Synteza OPL,Síntese OPL,,Sinteză OPL,Синтез OPL,OPL синтеза,OPL Sentezi,Синтез OPL, -Number of emulated OPL chips,ADVSNDMNU_OPLNUMCHIPS,,,,Počet emulovaných OPL čipů,Antal emulerede OPL-chips,Anzahl OPL Chips,,Nombro da imititaj OPL-blatoj,Número de chips OPL emulados,,Emuloitavien OPL-piirien lukumäärä,Puces OPL émulées,Emulált OPL csipek száma,Numero di chip OPL emulati,OPLチップエミュレートの番号,에뮬레이트된 OPL 칩 수,Aantal geëmuleerde OPL chips,Antall emulerte OPL-brikker,Liczba emulowanych czipów OPL,Número de chips OPL emulados,,Număr de cipuri OPL emulate,Количество эмулируемых чипов OPL,Број емулираних OPL чипа,Taklit edilen OPL çiplerinin sayısı,Кількість емульованих OPL-чіпів, -Full MIDI stereo panning,ADVSNDMNU_OPLFULLPAN,,,,Plné MIDI stereo,Fuld MIDI stereo panorering,Echte MIDI-Stereoeffekte,,Tuta MIDI-sterepanoramado,Balance estéreo MIDI completo,,Täysi MIDI-stereopanorointi,Latéralisation complète MIDI,Teljes MIDI sztereó tájolás,,Full MIDIステレオパンニング,완전한 MIDI 스테레오 패닝,Volledige MIDI stereo panning,Full MIDI stereo panorering,Pełne efekty stereo dla MIDI,Lateralidade estéreo completa para MIDI,,Panoramă stereo pentru MIDI,Полная стереопанорама для MIDI,Пуно MIDI стерео каналисање,Tam MIDI stereo kaydırma,Повна стереопанорама для MIDI, -OPL Emulator Core,ADVSNDMNU_OPLCORES,,,,Emulační jádro OPL,OPL-emulatorkerne,OPL Emulatorkern,,OPL-imitilkerno,Núcleo de emulador OPL,,OPL-emulaattoriydin,Cœur émulateur OPL,,,OPL エミュレート コア,OPL 에뮬레이터 코어,OPL Emulator Kern,OPL-emulatorkjerne,Rdzeń Emulatora OPL,Núcleo do emulador de OPL,,Nucleu de emulare OPL,Ядро эмуляции OPL,OPL језгро емулације,OPL Emülatör Çekirdeği,Ядро емуляції OPL, -MIDI voices,ADVSNDMNU_MIDIVOICES,,,,Počet MIDI hlasů,MIDI-stemmer,MIDI Stimmen,,MIDI-voĉoj,Voces MIDI,,MIDI-äänet,Voix MIDI,MIDI hangok,Voci MIDI,MIDI ボイス,MIDI 최대 음색 양,MIDI-stemmen,MIDI stemmer,Głosy MIDI,Vozes MIDI,,Voci MIDI,MIDI-голоса,MIDI гласови,MIDI sesleri,MIDI-голоси, -FluidSynth,ADVSNDMNU_FLUIDSYNTH,,,,,,,,,,,,,,,,,,,,,,,,,,, -Global,ADVSNDMNU_GLOBAL,,,,Globální,,,,Malloka,Global,,Yleinen,,,Globale,グローバル,전반적,Globaal,,Globalne,,,,Общие,Глобално,Küresel,Загальні, -Freeverb,ADVSNDMNU_FREEVERB,,,,,,,,,,,,,,,フリーバーブ,프리버브,,,,,,,,,Freeverb,, -Global Freeverb,ADVSNDMNU_GLOBAL_FREEVERB,,,,Globální Freeverb,Global Freeverb,Globales Freeverb,,Malloka Freeverb,Freeverb Global,,Yleinen Freeverb,Freeverb Global,,Freeverb globale,グローバル フリーバーブ,전반적 프리버브,Globale Freeverb,,Globalny Freeverb,Freeverb global,,Freeverb Global,Глобальный Freeverb,Глобални Freeverb,Küresel Freeverb,Глобальний Freeverb, -Patch set,ADVSNDMNU_FLUIDPATCHSET,,,,Nástrojová sada,Patch-sæt,Patch-Set,,Flikaro,Set de parche,,Patch-asetus,Banque de Sons,,,パッチ セット,패치 세트,,Patch-sett,Zestaw łatek,Banco de sons,,Set patch,Патч-набор,Печ сет,Yama seti,Патч-набір, -Gain,ADVSNDMNU_FLUIDGAIN,,,,Zesílení,,Relative Lautstärke,,Akiro,Ganancia,,Vahvistus,,Visszaverődés,,ゲイン,쌓기,Relatief volume,,Wzmocnienie,Ganho,,Amplificare,Усиление,Појачање,Kazanç,Підсилення, -Reverb,ADVSNDMNU_REVERB,,,,Ozvěna,,Hall,,Resono,Reverberación,,Kaiku,Réverbération,Visszhang,,リバーブ,리버브,Nagalm,,Pogłos,Reverberação,,,Реверберация,Одјек,Reverb,Ревербація, -Reverb Level,ADVSNDMNU_REVERB_LEVEL,,,,Intenzita ozvěny,,Hallintensität,,Nivelo de resono,Nivel de reverberación,,Kaiunvoimakkuus,Niveau Réverb.,Visszhang szintje,,リバーブ量,리버브 강도,Nagalm niveau,Reverb-nivå,Poziom pogłosu,Nível de reverberação,,Nivel Reverb,Уровень реверберации,Ниво одјека,Reverb Seviyesi,Рівень ревербації, -Chorus,ADVSNDMNU_CHORUS,,,,,,,,Koruso,,,,,,,コーラス,코러스,,,,,,Cor,Хор,Корус,Koro,Хорус, -Timidity++,ADVSNDMNU_TIMIDITY,,,,,,,,,,,,,,,,,,,,,,,,,,, -ADLMidi,ADVSNDMNU_ADLMIDI,,,,,,,,,,,,,,,,,,,,,,,,,,, -OPNMidi,ADVSNDMNU_OPNMIDI,,,,,,,,,,,,,,,,,,,,,,,,,,, -Timidity config file,ADVSNDMNU_TIMIDITYCONFIG,,,,Konfigurační soubor Timidity,Timidity-konfigurationsfil,Timidity Konfigurationsdatei,,Agorda dosiero de Timidity,Ruta al archivo config. Timidity,,Timidity-config-tiedosto,Fichier de config. TiMidity,Timidity konfigurációs fájl,File configurazione Timidity,Timidity コンフィグファイル,Timidity 코딩 파일,Timidity++ configuratiebestand,Timidity konfigurasjonsfil,Plik konfiguracyjny Timidity,Arquivo de configuração do Timidity,,Fișier configurație Timidity,Файл конфигурации Timidity,Timidity конфигурациона датотека,Timidity yapılandırma dosyası,Файл конфігурації Timidity, -Relative volume,ADVSNDMNU_TIMIDITYVOLUME,,,,Relativní hlasitost,Relativ lydstyrke,Relative Lautstärke,,Relativa laŭteco,Volumen relativo,,Suhteellinen äänenvoimakkuus,Volume Relatif,Relatív hangerő,Volume relativo,相対音量,비교적인 볼륨,Relatief volume,Relativt volum,Względna głośność,Volume relativo,,Volum relativ,Относительная громкость,Релативна јачина,Bağıl hacim,Відносна гучність, -WildMidi,ADVSNDMNU_WILDMIDI,,,,,,,,,,,,,,,,,,,,WildMidi,,,,,,, -WildMidi config file,ADVSNDMNU_WILDMIDICONFIG,,,,Konfigurační soubor WildMidi,WildMidi konfigurationsfil,WilfMidi Konfigurationsdatei,,Agorda dosiero de WildMidi,Archivo de config. WildMidi,,WildMidi-config-tiedosto,Fichier config. WildMidi,WildMidi konfigurációs fájl,File WildMidi config,WildMidi コンフィグファイル,WildMidi 코딩 파일,WildMidi configuratiebestand,WildMidi konfigurasjonsfil,Plik konfiguracyjny WildMidi,Arquivo de configuração do WildMidi,,Fișier configurație WildMidi,Файл конфигурации WildMidi,WildMidi конфигурациона датотека,WildMidi yapılandırma dosyası,Файл конфігурації WildMidi, -Select configuration,ADVSNDMNU_SELCONFIG,,,,Vybrat konfiguraci,Vælg konfiguration,Konfiguration wählen,,Elekti agordojn,Seleccionar configuración,,Valitse kokoonpano,Sélectionner configuration,Konfiguráció kiválasztása,Seleziona la configurazione,構成選択,설정을 고르시오,Selecteer configuratie,Velg konfigurasjon,Wybierz konfigurację,Selecionar configuração,,Selectare configurație,Выбор конфигурации,Изабери конфигурацију,Yapılandırma seçin,Вибір конфігурації, -Advanced Resampling,ADVSNDMNU_ADVRESAMPLING,,,,Pokročilé převzorkování,Avanceret resampling,Erweitertes Resampling,,Altnivela respecimenado,Resampleo avanzado,,Kehittynyt näytteenottotaajuuden muuntaminen,Resampling Avancé,Fejlett Resmapling,Resampling avanzato,高度なリサンプリング,향상된 리샘플링,Geavanceerde herbemonstering,Avansert resampling,Zaawansowane Próbkowanie,Reamostragem avançada,,Resempling avansat,Продвинутый ресэмплинг,Напредно ресампловање,Gelişmiş Yeniden Örnekleme,Розширений ресемплінг, -OPL Bank,ADVSNDMNU_OPLBANK,,,,OPL sada,OPL Bank,,,Banko por OPL,Banco OPL,,OPL-pankki,Banque OPL,,,,OPL 뱅크,,,Bank OPL,Banco OPL,,Bancă OPL,Банк OPL,OPL банка,OPL Bank,Банк OPL, -OPL Emulator Core,ADVSNDMNU_ADLOPLCORES,,,,Emulační jádro OPL,OPL-emulatorkerne,OPL Emulatorkern,,Imitilkerno por OPL,Núcleos de emulador OPL,,OPL-emulaattoriydin,Cœur Emulateur OPL,OPL emulátor mag,,OPL エミュレートコア,OPL 에뮬레이터 코어,OPL Emulator Kern,OPL-emulatorkjerne,Rdzeń Emulatora OPL,Núcleo do emulador de OPL,,Nucleu de emulare OPL,Ядро эмуляции OPL,OPL емулационо језгро,OPL Emülatör Çekirdeği,Ядро емуляції OPL, -Run emulator at PCM rate,ADVSNDMNU_RUNPCMRATE,,,,Emulátor používá PCM vzorkovací frekvenci,Kør emulator ved PCM-hastighed,Emulator benutzt PCM Samplerate,,Kurigi imitilon laŭ rapido de PCM,Ejecutar emulador a velocidad PCM,,Aja emulaattoria PCM-taajuudella,Emulateur utilise cadence PCM,Emulátor futtatása PCM rátán,Esegui l'emulatore con rate PCM,PCMレートでエミュレート実行,PCM 속도로 에뮬레이터 실행,Emulator maakt gebruik van PCM Samplerate,Kjør emulator med PCM-hastighet,Uruchom emulator w częstotliwości PCM,Rodar emulador em taxa PCM,,Utilizare cu frecvența PCM,Использовать с частотой PCM,Покрени емулацију на PCM стопи,Emülatörü PCM hızında çalıştırın,Використовувати з частотою PCM, -Number of emulated OPL chips,ADVSNDMNU_ADLNUMCHIPS,,,,Počet emulovaných OPL čipů,Antal emulerede OPL-chips,Anzahl OPL Chips,,Numbro da imitaj OPL-blatoj,Número de chips OPL emulados,,Emuloitavien OPL-piirien lukumäärä,Puces OPL émulées,Emulált OPL csipek száma,Numero di chip OPL emulati,OPLチップエミュレートの番号,에뮬레이트된 OPL 칩 개수,Aantal geëmuleerde OPL chips,Antall emulerte OPL-brikker,Liczba emulowanych czipów OPL,Número de chips OPL emulados,,Număr de cipuri GUS emulate,Количество эмулируемых чипов OPL,Број емулираних OPL чипова,Taklit edilen OPL çiplerinin sayısı,Кількість емульованих OPL-чіпів, -Volume model,ADVSNDMNU_VLMODEL,,,,Model hlasitosti,Volumenmodel,Lautstärkemodell,,Modelo de laŭteco,Modelo de volumen,,Äänenvoimakkuusmalli,Modèle de Volume,Hangmodell,Modello di volume,音量モデル,모델 볼륨,Volume model,Volummodell,Model głośności,Modelo de volume,,Model volum,Модель громкости,Волумски модел,Hacim modeli,Модель гучності, -OPN2 Emulator Core,ADVSNDMNU_OPNCORES,,,,Emulační jádro OPN2,OPN2-emulatorkerne,OPN2 Emulatorkern,,OPN2 Imitilkerno,Núcleo de emulador OPN2,,OPN2-emulaattoriydin,Cœur émulateur OPN2,OPN2 Emulátor Mag,,OPN2 エミュレート コア,OPN2 에뮬레이터 코어,OPN2 Emulatorkern van de OPN2-emulator,OPN2 Emulatorkjerne,Rdzeń Emulatora OPN2,Núcleo do emulador de OPN2,,Nucleu de emulare OPN2,Ядро эмуляции OPN2,OPN2 језгро емулације,OPN2 Emülatör Çekirdeği,Ядро емуляції OPN2, -GUS Emulation,ADVSNDMNU_GUSEMULATION,,,,Emulace GUS,GUS-emulering,GUS Emulation,,GUS Imitado,Emulación GUS,,GUS-emulaatio,Emulation GUS,GUS Emuláció,,GUS エミュレーション,GUS 에뮬레이션,GUS-emulatie,GUS-emulering,Emulacja GUS,Emulação de GUS,,Emulare GUS,Эмуляция GUS,GUS емулација,GUS Emülasyonu,Емуляція GUS, -GUS config file,ADVSNDMNU_GUSCONFIG,,,,Konfigurační soubor GUS,GUS-konfigurationsfil,GUS Konfigurationsdatei,,Agorda dosiero de GUS,Archivo de config. GUS,,GUS-config-tiedosto,Fichier Config. GUS,GUS konfigurációs fájl,File GUS config,GUS コンフィグファイル,GUS 코딩 파일,GUS-configuratiebestand,GUS konfigurasjonsfil,Plik konfiguracyjny GUS,Arquivo de configuração do GUS,,Fișier configurație GUS,Файл конфигурации для GUS,GUS конфигурациона датотека,GUS yapılandırma dosyası,Файл конфігурації для GUS, -Read DMXGUS lumps,ADVSNDMNU_DMXGUS,,,,Načíst DMXGUS soubory,Læs DMXGUS-klumper,Lese DMXGUS,,Legi DMXGUS Masojn,Leer archivos DMXGUS,,Lue DMXGUS-tietoja,Lire fichiers DMXGUS,DMXGUS lumpok beolvasása,Leggi i lump DMXGUS,DMXGUS ランプを読む,DMXGUS 럼프 읽기,DMXGUS-klonten lezen,Les DMXGUS-filer,Czytaj pliki DMXGUS,Ler lumps DMXGUS,,Citire fișiere DMXGUS,Читать файлы DMXGUS,Читај DMXGUS фајлове,DMXGUS dosyalarını okuma,Читати файли DMXGUS, -GUS memory size,ADVSNDMNU_GUSMEMSIZE,,,,Velikost paměti GUS,GUS-hukommelsesstørrelse,GUS Speichergröße,,GUS Memorampleksoj,Tamaño de memoria de GUS,,GUS-muistikoko,Taille mémoire GUS,GUS memória mérete,Dimensione della memoria per GUS,GUS メモリーサイズ,GUS 메모리 크기,GUS-geheugengrootte,GUS-minne størrelse,Rozmiar pamięci GUS,Tamanho de memória do GUS,,Memorie alocată pentru GUS,Размер памяти GUS,GUS величина памћења,GUS bellek boyutu,Розмір пам'яті GUS, -Number of emulated OPN chips,ADVSNDMNU_OPNNUMCHIPS,,,,Počet emulovaných OPN čipů,Antal emulerede OPN-chips,Anzahl OPN Chips,,Nombro da imititaj OPL-blatoj,Número de chip OPN emulados,,Emuloitavien OPN-piirien lukumäärä,Puces OPN émulées,Emulált OPL csipek száma,Numero di chip OPN emulati,OPNチップエミュレートの番号,에뮬레이트된 OPN 칩 개수,Aantal geëmuleerde OPL chips,Antall emulerte OPN-brikker,Liczba emulowanych czipów OPN,Número de chips OPN emulados,,Număr de cipuri OPN emulate,Количество эмулируемых чипов OPN,Број емулираних OPN чипова,Taklit edilen OPN çiplerinin sayısı,Кількість емульованих OPN-чіпів, -Use custom WOPL bank,ADVSNDMNU_ADLCUSTOMBANK,,,,Použít vlastní WOPL sadu,Brug af brugerdefineret WOPL-bank,Benutzerdefinierte WOPL Bank,,Uzi laŭmendan WOPL-bankon,Utilizar banco WOPL personalizado,,Käytä mukautettua WOPL-pankkia,Utiliser Banque WOPL perso,Saját WOPL bank használata,Usa WOPL bank personalizzato,カスタムWOPL bankを使用,사용자 지정 WOPL 뱅크 사용,Gebruik de aangepaste WOPL bank,Bruk egendefinert WOPL-bank,Użyj niestandardowego banku WOPL,Usar banco WOPL personalizado,,Utilizați propriul bank WOPN,Использовать собственный банк WOPL,Користи прилагођенуу WOPL банку,Özel WOPL bankası kullanın,Використовувати власний банк WOPL, -WOPL Bank file,ADVSNDMNU_OPLBANKFILE,,,,Soubor WOPL sady,WOPL Bank-fil,WOPL Bank-Datei,,WOPL-Bankodosiero,Archivo de banco WOPL,,WOPL-pankkitiedosto,Banque WOPL,WOPL Bank fájl,File WOPL Bank,WOPL bankファイル,WOPL 뱅크 파일,WOPL Bank-bestand,WOPL Bank-fil,Plik banku WOPL,Banco WOPL,,Fișier WOPN bank,Файл с банком WOPL,WOPL фајл банка,WOPL Bank dosyası,Файл з банком WOPL, -Use custom WOPN bank,ADVSNDMNU_OPNCUSTOMBANK,,,,Použít vlastní WOPN sadu,Brug af brugerdefineret WOPN-bank,Benutzerdefinierte WOPN Bank,,Uzi laŭmendan WOPN-bankon,Utilizar banco WOPN personalizado,,Käytä mukautettua WOPN-pankkia,Utiliser Banque WOPL perso,Saját WOPN bank használata,Usa WOPN bank personalizzato,カスタムWOPN bankを使用,사용자 지정 WOPN 뱅크 사용,Gebruik aangepaste WOPN-bank op maat,Bruk egendefinert WOPN-bank,Użyj niestandardowego banku WOPN,Usar banco WOPN personalizado,,Utilizați propriul bank WOPN,Использовать собственный банк WOPN,Користи прилагођену WOPN банку,Özel WOPN bankası kullanın,Використовувати власний банк WOPN, -WOPN Bank file,ADVSNDMNU_OPNBANKFILE,,,,Soubor WOPN sady,WOPN Bank-fil,WOPN Bank-Datei,,WOPN-Bankodosiero,Archivo de banco WOPN,,WOPN-pankkitiedosto,Banque WOPL,WOPN Bank fájl,File WOPN Bank,WOPN bankファイル,WOPN 뱅크 파일,WOPN Bank-bestand,WOPN-bankfil,Plik banku WOPN,Banco WOPN,,Fișier WOPN bank,Файл с банком WOPN,WOPN фајл банка,WOPN Banka dosyası,Файл з банком WOPN, -Aliasing,OPTVAL_ALIASING,,,,,Aliasing,,,Krenelaro,,,,,,,エイリアシング,에일리어싱,,,,,,Dedublare,Сглаживание,Преклапање,Takma Adlandırma,Згладжування, -Linear,OPTVAL_LINEAR_1,This setting is duplicated threefold in order to allow for different grammatical gender endings,,,Lineární,Lineær,,,Lineara,Lineal,,Lineaarinen,Linéaire,Lineáris,Lineare,リニア,선형,Lineair,Lineær,Liniowy,Linear,,Liniar,Линейное,Линеаран,Doğrusal,Лінійне, -Linear,OPTVAL_LINEAR_2,,,,Lineární,Lineær,,,Lineara,Lineal,,Lineaarinen,Linéaire,Lineáris,Lineare,リニア,선형,Lineair,Lineær,Liniowa,Linear,,Liniar,Линейная,Линеаран,Doğrusal,Лінійна, -Linear,OPTVAL_LINEAR_3,,,,Lineární,Lineær,,,Lineara,Lineal,,Lineaarinen,Linéaire,Lineáris,Lineare,リニア,선형,Lineair,Lineær Lineær,Liniowe,Linear,,Liniar,Линейный,Линеаран,Doğrusal,Лінійний, -Nearest,OPTVAL_NEAREST,,,,Nejbližší,Nærmeste,Nächster Nachbar,,Plej proksima,Cercano,,Lähin,Nearest,Legközelebbi,Il più vicino,最寄り,가까이,Naast,Nærmeste,Najbiższe,Mais próximo,,Cel mai apropriat,Ближайший,Најближе,En yakın,Найближчий, -PCF (Low),OPTVAL_PCF_LOW,,,,PCF (nízké),PCF (lav),PCF (niedrig),,PCF (Malalta),PCF (Bajo),,PCF (matala),PCF (Low),PCF (Alacsony),PCF (basso),PCF (低),PCF (하급),PCF (Laag),PCF (lav),PCF (Niski),PCF (Baixo),,PCF (Scăzut),PCF (низкий),PCF (ниско),PCF (Düşük),PCF (низький), -PCF (Medium),OPTVAL_PCF_MEDIUM,,,,PCF (střední),PCF (medium),PCF (mittel),,PCF (Meza),PCF (Medio),,PCF (keskitaso),PCF (Medium),PCF (Közepes),PCF (medio),PCF (中),PCF (중급),PCF (Medium),PCF (middels),PCF (Średni),PCF (Médio),,PCF (Mediu),PCF (средний),PCF (средње),PCF (Orta),PCF (средній), -PCF (High),OPTVAL_PCF_HIGH,,,,PCF (vysoké),PCF (høj),PCF (hoch),,PCF (Alta),PCF (Alto),,PCF (korkea),PCF (High),PCF (Magas),PCF (alto),PCF (高),PCF (상급),PCF (Hoog),PCF (høy),PCF (Wysoki),PCF (Alto),,PCF (Ridicat),PCF (высокий),PCF (високо),PCF (Yüksek),PCF (високий), -Cubic,OPTVAL_CUBIC,,,,Kubická,Kubisk,Kubisch,,Kuba,Cúbico,,Kuutio,Cubique,Négyzetes,Cubico,キュービック,큐빅,Kubieke,Kubisk,Sześcienny,Cúbico,,Cub,Кубическое,Кубан,Kübik,Кубічне, -Band-limited step,OPTVAL_BLEP,,,,Omezené krokování,Båndbegrænset trin,Bandbegrenzte Schritte,,Bendo-limigita paŝo,Paso limitado por banda,,Kaistarajoitettu askel,Step limité par bande,Sáv-limitált lépés,Passo limitato dalla banda,帯域制限ステップ,제한된 단계별 밴드,Bandbeperkte stap,Båndbegrenset trinn,Krok ograniczony pasmem,Passo limitado por banda,,Limitare frecvență pas-cu-pas,Ограниченный полосой пропускания шаг,Постепено ограничење фреквенције,Bant sınırlı adım,Покрокове обмеження частоти, -Linear (Slower),OPTVAL_LINEARSLOW,,,,Lineární (pomalejší),Lineær (langsommere),Linear (langsamer),,Lineara (Pli malrapida),Lineal (más lento),,Lineaarinen (hitaampi),Linéaire (Lent),Lineáris (Lassabb),Lineare (più lento),リニア(遅め),선형 (느리게),Lineair (langzamer),Lineær (langsommere),Liniowy (wolniejszy),Linear (mais lento),,Liniar (Mai lent),Линейное (медленнее),Линеаран (спорије),Doğrusal (Daha Yavaş),Лінійне (повільніше), -Band-limited linear,OPTVAL_BLAM,,,,Omezená lineární,Båndbegrænset lineær,Bandbegrenzt linear,,Bendo-limigita lineara,Lineal limitado por banda,,Kaistarajoitettu lineaarinen,Linéaire limité par bande,Sáv-limitált lineáris,Lineare limitato dalla banda,帯域制限リニア,밴드 제한 식 선형,Band-beperkt lineair,Båndbegrenset lineær,Liniowy ograniczony pasmem,Linear limitado por banda,,Limitare frecvență liniară,Ограниченное полосой пропускания линейное,Линеарно ограничење фреквенције,Bant sınırlı doğrusal,Лінійне обмеження частоти, -Cubic (Slower),OPTVAL_CUBICSLOW,,,,Kubická (pomalejší),Kubisk (langsommere),Kubisch (langsamer),,Kuba (Pli malrapida),Cúbico (más lento),,Kuutio (hitaampi),Cubique (Lent),Négyzetes (Lassabb),Cubico (più lento),キュービック (遅め),큐빅 (느리게),Kubieke (langzamer),Kubisk (langsommere),Sześcienny (wolniejszy),Cúbico (mais lento),,Cub (Mai lent),Кубическое (медленнее),Кубан (спорије),Kübik (Daha Yavaş),Кубічне (повільніше), -Sinc,OPTVAL_SINC,,,,,Sinc,,,,Seno cardinal,,,,,,シンク,싱크,,,,Seno cardinal,,Sinus cardinal,Кардинальный синус,Синк,,Функція sinc, -Note on/off only,OPTVAL_NOTEONOFFONLY,,,,Pouze začátek/konec noty,Kun note on/off,Nur für Note an/aus ,,Nur noto ek/for,Solo notas de Activ./Desact.,,Vain nuotti päällä/pois,Note on/off seulement,Hangjegy ki/be csak,Note solamente ON/OFF,ノート オン/オフ のみ,노트를 끄거나 켰을 때,Alleen toon aan/uit,Merk kun på/av,Tylko dla włączonych/wyłączonych notatek,Somente notas ligadas/desligadas,,Numai la activarea/oprirea notelor,Только при включении/отключении нот,Само током укључења/искључења ноте,Yalnızca not açma/kapama,Тільки при ввімкненні/вимкненні нот, -Full ramping,OPTVAL_FULLRAMPING,,,,Plný náběh,Fuld rampe,,,Plena pligrandigado,Aumento completo,,Täysi kerrytys,Rampe complète,Teljes ramping,Ramping completo,フルランピング,최대 램핑,Volledige helling,Full ramping,Pełne zwiększenie,Rampa completa,,Creștere completă,Полное наращивание,Пуно појачање,Tam rampa,Повне нарощування, -Master volume,MODMNU_MASTERVOLUME,,,,Celková hlasitost,Master-volumen,Grundlautstärke,,Ĉeflaŭteco,Volumen maestro,,Yleisäänenvoimakkuus,Volume maître,Fő hangerő,Volume master,全体音量,마스터 볼륨,Hoofdvolume,Hovedvolum,Całkowita głośność,Volume geral,,Volum general,Общая громкость,Глацни звук,Ana ses seviyesi,Загальна гучність, -Quality,MODMNU_QUALITY,,,,Kvalita,Kvalitet,Qualität,,Kvaliteco,Calidad,,Laatu,Qualité,Minőség,Qualità,クオリティ,품질,Kwaliteit,Kvalitet,Jakość,Qualidade,,Calitate,Качество,Квалитет,Kalite,Якість, -Volume ramping,MODMNU_VOLUMERAMPING,,,,Křivka hlasitosti,Lydstyrke-rampe,Lautstärkeverhalten,,Laŭteco-pligrandigado,Aumento gradual de Volumen,,Äänenvoimakkuuden kertyminen,Rampe du volume,,Ramping volume,音量ランピング,볼륨 램핑,Volume-aanvulling,Volumramping,Zwiększenie głośności,Rampa de volume,,Creștere volum,Наращивание громкости,Појачавање звука,Hacim artırma,Нарощування гучності, -Chip-o-matic,MODMNU_CHIPOMATIC,,,,,,,,,,,,,,,チップ オー マチック,칩-오-매틱,,,,,,,,,,, -MAME OPL2,OPTVAL_MAMEOPL2,,,,,,,,,,,,,,,,마메 OPL2,,,,,,,,,,, -DOSBox OPL3,OPTVAL_DOSBOXOPL3,,,,,,,,,,,,,,,,도스박스 OPL3,,,,,,,,,,, -Java OPL3,OPTVAL_JAVAOPL3,,,,,,,,,,,,,,,,자바 OPL3,,,,,,,,,,, -Nuked OPL3,OPTVAL_NUKEDOPL3,,,,,,,,,,,,,,,,,,,,,,,,,,, -MAME YM2612,OPTVAL_MAMEOPN2,,,,,,,,,,,,,,,,마메 YM2612,,,,,,,,,,, -Neko Project II Kai OPNA,OPTVAL_NP2OPNA,,,,,,,,,,,,,,,,,,,,,,,,,,, -MAME YM2608,OPTVAL_MAMEOPNA,,,,,,,,,,,,,,,,마메 YM2608,,,,,,,,,,, -PMDWin OPNA,OPTVAL_PMDWINOPNA,,,,,,,,,,,,,,,,,,,,,,,,,,, -Opal OPL3,OPTVAL_OPALOPL3,,,,,,,,,,,,,,,,,,,,,,,,,,, -Nuked OPL3 v1.7.4,OPTVAL_NUKEDOPL3174,,,,,,,,,,,,,,,,,,,,,,,,,,, -Nuked OPN2,OPTVAL_NUKEDOPN2,,,,,,,,,,,,,,,,,,,,,,,,,,, -GENS YM2612,OPTVAL_GENSOPN2,,,,,,,,,,,,,,,,,,,,,,,,,,, -Auto (Use setup of bank),ADLVLMODEL_AUTO,,,,Auto (použít nastavení sady),Auto (Brug opsætning af bank),Auto (Benutze Einstelliung der Bank),,Aŭtomata (Uzi bankagordaĵon),Auto (Usar config. del banco),,Automaattinen (käytä pankin asetuksia),Auto (Utiliser paramètre banque),Automatikus (Beállított bank használata),Automatico (Usa le impostazioni del bank),自動(bankのセットアップ使用),자동(뱅크 셋업 사용),Auto (gebruik instelling van de bank),Auto (Bruk oppsett av bank),Automatycznie (Użyj ustawień banku),Automático (usar definições de banco),,Auto (configurare din bancă),Авто (настройка из банка),Аутоматски (користи намештену банку),Otomatik (Banka kurulumunu kullan),Авто (налаштування з банку), -Generic,ADLVLMODEL_GENERIC,,,,Standardní,Generisk,Allgemein,,Komuna,Genérico,,Yleinen,Générique,Általános,Generico,一般的,전형적,Algemeen,Generisk,Ogólne,Genérico,,,Общий,Генерично,Jenerik,Загальний, -OPL Native,ADLVLMODEL_NATIVE,,,,Nativní OPL,OPL Native,OPL Nativ,,Nativa OPL,Nativo OPL,,Luontainen OPL,OPL Natif,Natív OPL,,OPLネイティブ,고유 OPL,,,Natywne OPL,Nativo OPL,,OPL propriu,Встроенная OPL,OPL домаћи,OPL Yerli,Вбудована OPL, -"DMX (Accurate, with AM bug)",ADLVLMODEL_DMX,,,,"DMX (Přesný, s AM chybou)","DMX (nøjagtig, med AM-fejl)",,,,,,,,"DMX (Pontos, de AM buggal)",,,데이터 마이닝 확장,"DMX (accuraat, met AM bug)","DMX (Nøyaktig, med AM-feil)",,"DMX (preciso, com bug de AM)",,"DMX (Precis, cu probleme în AM)","DMX (Точная, с ошибкой АМ)",,"DMX (Doğru, AM hatalı)","DMX (Точна, з помилкою АМ)", -"Apogee (Accurate, with AM bug)",ADLVLMODEL_APOGEE,,,,"Apogee (Přesný, s AM chybou)","Apogee (nøjagtig, med AM-fejl)",,,,,,,,"Apogee (Pontos, de AM buggal)",,,어포지,"Apogee (accuraat, met AM bug)","Apogee (Nøyaktig, med AM-feil)",,"Apogee (preciso, com bug de AM)",,"Apogee (Precis, cu probleme în AM)","Apogee (Точная, с ошибкой АМ)",,"Apogee (Doğru, AM hatası ile)","Apogee (Точна, з помилкою АМ)", -Win9X-like (SB16),ADLVLMODEL_WIN9X,,,,Jako Windows 9X (SB16),Win9X-lignende (SB16),Wie Windows 9X (SB16),,Kiel Win9X (SB16),Como Win9X (SB16),,Win9x-kaltainen (SB16),,Win9X szerű (SB16),,Win9X式 (SB16),Win9X 같게 (SB16),Win9X-achtig (SB16),Win9X-lignende (SB16),Jak w Win9X (SB16),Estilo Win9X (SB16),,Similar cu Win9X (SB16),Похожая на Win9X (Вариант SB16),Као у Win9X-у (SB16),Win9X benzeri (SB16),Схожа на Win9X (Варіант SB16), -Win9X-like (Generic FM),ADLVLMODEL_WIN9XGENERIC,,,,Jako Windows 9X (Generic FM),Win9X-lignende (generisk FM),Wie Windows 9X (Generic FM),,Kiel Win9X (Generic FM),Como Win9X (Generic FM),,Win9x-kaltainen (Generic FM),,Win9X szerű (Általános FM),,Win9X式 (Generic FM),Win9X 같게 (Generic FM),Win9X-achtig (Generic FM),Win9X-lignende (Generisk FM),Jak w Win9X (Generic FM),Estilo Win9X (FM genérico),,Similar cu Win9X (Generic FM),Похожая на Win9X (Вариант Generic FM),Као у Win9X-у (Generic FM),Win9X benzeri (Jenerik FM),Схожа на Win9X (Варіант Generic FM), -DMX (Without AM voice bug),ADLVLMODEL_DMX_FIXED,,,,DMX (Bez AM hlasové chyby),DMX (uden AM-stemmefejl),DMX (Ohne AM-Stimmenfehler),,DMX (Sen cimo de AM-voĉo),DMX (Sin bug de voz AM),,DMX (ilman AM-äänivikaa),DMX (Sans bug canaux AM),DMX (AM hanghiba nélkül),,DMX(AMボイスバグ無し),,DMX (zonder AM voice bug),DMX (uten AM-stemmefeil),DMX (bez głosowego błędu AM),DMX (sem bug de voz de AM),,DMX (Fără probleme în AM),DMX (Без ошибки АМ),,DMX (AM ses hatası olmadan),DMX (Без помилки АМ), -Apogee (Without AM voice bug),ADLVLMODEL_APOGEE_FIXED,,,,Apogee (Bez AM hlasové chyby),Apogee (uden AM-stemmefejl),Apogee (Ohne AM-Stimmenfehler),,Apogee (Sen cimo de AM-voĉo),Apogee (Sin bug de voz AM),,Apogee (ilman AM-äänivikaa),Apogee (avec bug canaux AM),Apogee (AM hanghiba nélkül),,Apogee(AMボイスバグ無し),,Apogee (zonder AM voice bug),Apogee (uten AM-stemmefeil),Apogee (bez głosowego błędu AM),Apogee (sem bug de voz de AM),,Apogee (Fără probleme în AM),Apogee (Без ошибки АМ),,Apogee (AM ses hatası olmadan),Apogee (Без помилки АМ), -IBM Audio Library Interface,ADLVLMODEL_AIL,,,,,,,,IBM Aŭdbibiloteka Interfaco,,,,,IBM Hang Könyvtár Interfész,,,,,,Interfejs Biblioteki Dźwięków IBM,Interface de Biblioteca de Áudio IBM,,Interfață de Bibliotecă IBM,IBM AIL,,IBM Ses Kitaplığı Arayüzü,, -HMI Sound Operating System,ADLVLMODEL_HMI,,,,,,,,HMI Sonoperaciumo,,,,,HMI Hang Operációs Rendszer,,,,,,System Operacyjny Dźwięków HMI,Sistema Operacional de Som HMI,,Sistem Sonor HMI,HMI SOS,,HMI Ses İşletim Sistemi,, -"HMI SOS (Old, with bugs)",ADLVLMODEL_HMIOLD,,,,"HMI SOS (Starý, s chybami)","HMI SOS (gammelt, med fejl)","HMI SOS (alt, mit Fehlern)",,"HMI SOS (Malnova, kun cimoj)","HMI SOS (Viejo, con bugs)",,"HMI SOS (vanha, vikainen)",HMI SOS (vieux et buggé),"HMI SOS (Régi, bugokkal)",,"HMI SOS(旧式,バグ含む)",,"HMI SOS (oud, met bugs)","HMI SOS (gammel, med feil)","HMI SOS (Stare, z błędami)","SOS HMI (antigo, com bugs)",,"HMI SOS (Vechi, cu probleme)",HMI SOS (Старый вариант с ошибками),,"HMI SOS (Eski, hatalı)",HMI SOS (Старий варіант з помилками), -Unlimited,OPTVAL_UNLIMITED,,,,Neomezené,Ubegrænset,Unlimitiert,,Senlima,Ilimitado,,Rajoittamaton,Illimité,Végtelen,Illimitato,無制限,무제한,Onbeperkt,Ubegrenset,Nieskończone,Sem limites,,Nelimitat,Без ограничений,Бескрајно,Sınırsız,Безмежно, -256K,OPTVAL_256K,,,,,,,,,,,,,,,,,,,,,,,,,,, -512K,OPTVAL_512K,,,,,,,,,,,,,,,,,,,,,,,,,,, -768K,OPTVAL_768K,,,,,,,,,,,,,,,,,,,,,,,,,,, -1024K,OPTVAL_1024K,,,,,,,,,,,,,,,,,,,,,,,,,,, -,,Postprocessing,,,,,,,,,,,,,,,,,,,,,,,,,, -Uncharted 2,OPTVAL_UNCHARTED2,,,,,,,,,,,,,,,,,,,,,,,,,,, -Hejl Dawson,OPTVAL_HEJLDAWSON,,,,,,,,,,,,,,,,,,,,,,,,,,, -Reinhard,OPTVAL_REINHARD,,,,,,,,,,,,,,,,,,,,,,,,,,, -Palette,OPTVAL_PALETTE,,,,Paleta,Palet,,Παλέτα,Paletro,Paleta,,Paletti,,Paletta,Palette,パレット,팔레트,Palet,Palette,Paleta,Paleta,Palete,Paletă,Палитра игры,Палет,Palet,Палітра гри, -Low,OPTVAL_LOW,,,,Nízká,Lav,Niedrig,Χαμηλό,Malalta,Bajo,,Matala,Bas,Alacsony,Basso,低,낮음,Laag,Lav,Niskie,Baixo,,Scăzut,Низкое,Ниско,Düşük,Низьке, -Medium,OPTVAL_MEDIUM,,,,Střední,Medium,Mittel,Μεσαίο,Meza,Medio,,Keskitaso,Moyen,Közepes,Medio,中,중간,Middel,Middels,Średnie,Médio,,Mediu,Среднее,Средње,Orta,Середнє, -High,OPTVAL_HIGH,,,,Vysoká,Høj,Hoch,Υψηλό,Alta,Alto,,Korkea,Haut,Magas,Alto,高,높음,Hoog,Høy,Wysokie,Alto,,Ridicat,Высокое,Високо,Yüksek,Високе, -Extreme,OPTVAL_EXTREME,,,,Extrémní,Ekstrem,Extrem,Ακράιο,Ekstrema,Extremo,,Äärimmäinen,Extrême,Extrém,Estremo,最高,매우 높음,Extreem,Ekstrem,Ekstremalne,Extremo,,Extrem,Максимальное,Екстремно,Aşırı,Максимальне, -Obverse,OPTVAL_OBVERSEFIRST,,,,Vpřed (obvers),Forside,Obvers,Παρατήρησε,Antaŭa,Anverso,,Etupuoli,,Ellentétes,Dritto,正面,앞면,Obvers,Forside,Awers,Obverso,,Avers,Прямой,Супротно,Ön yüz,Прямий, -Reverse,OPTVAL_REVERSEFIRST,,,,Vzad (revers),Bagside,Revers,Αντίστροφο,Inversa,Inverso,,Käänteinen,Inverse,Fordított,Contrario,反転,반전,Revers,Baksiden,Rewers,Reverso,,Invers,Обратный,Обрнуто,Ters,Зворотний, -Postprocessing,GLMNU_POSTPROCESS,,,,,Efterbehandling,,Μετα-επεξεργασία,Postprocezado,Postprocesado,,Jälkikäsittely,,,,ポストプロセッシング,포스트프로세싱 적용,Nabewerking,Etterbehandling,Przetwarzanie końcowe,Pós-processamento,,Postprocesare,Постобработка,Пост обрада,İşlem sonrası,Постобробка, -Tonemap Mode,GLPREFMNU_TONEMAP,,,,Režim tónovací mapy,Tonemap-tilstand,Tonemap Modus,,Reĝimo de Tonmapo,Modo de mapa de tonos,,Sävykarttatila,Mode Tonemap,Színleképzés módja,Modalità Tonemap,トーンマップ モード,톤맵 모드,Tonemap modus,Tonemap-modus,Tryb Mapowania Tonów,Tipo de tonemap,,Mod Tonemap,Режим тонового отображения,Тонирано-мапни мод,Ton Haritası Modu,Режим тонального відображення, -Lens distortion effect,GLPREFMNU_LENS,,,,Efekt distorze čočky,Objektivforvrængningseffekt,Optischer Verzerrungseffekt,,Lensdistorto-efiko,Efecto de distorsión de lente,,Linssinvääristystehoste,Effet distorsion de lentille,Lencsetorzulás effekt,Effetto distorsione della lente,レンズの歪みエフェクト,렌즈 왜곡 효과,Effect van de lensvervorming,Linseforvrengningseffekt,Efekt zniekształcenia obiektywu,Distorção de lente,Efeito de distorção da lente,Efect de distorsionare,Эффект искажения линзы,Дисторзија објектива ефект,Lens bozulma efekti,Ефект деформації лінзи, -FXAA Quality,GLPREFMNU_FXAA,,,,Kvalita FXAA,FXAA-kvalitet,FXAA Qualität,FXAA ποίοτητα,Kvaliteco de FXAA,Calidad FXAA,,FXAA-laatu,Qualité FXAA,FXAA minősége,Qualità FXAA,FXAA品質,FXAA 품질,FXAA-kwaliteit,FXAA-kvalitet,Jakość FXAA,Qualidade de FXAA,,Calitate FXAA,Качество FXAA,FXAA квалитет,FXAA Kalitesi,Якість FXAA, -Dither output,GLPREFMNU_DITHER,,,,Dithering,Dither-udgang,Dithering,,Apliki punktojn al eligo,Dither de salida,,Sekoitussävytyksen (dithering) ulostulo,Dithering,Árnyalás kimenet,Dithering,ディザー出力,떨림 효과 출력,Dither output,Dither-utgang,Dygotanie,Dithering,,Putere Dithering,Дизеринг,Учестаност трептања,Dither çıkışı,Дитеринг, -Tonemap Palette Order,GLPREFMNU_PALTONEMAPORDER,,,,Pořadí palety tónovací mapy,Tonemap-palettens rækkefølge,Palettensortierung für Tonemap,,Ordo de Kolormapo-Paletro,Orden de la paleta en mapa de tonos,,Sävykartan paletin järjestys,Ordre des palettes tonemap,Színleképzés paletta sorrend,Ordine della Palette Tonemap,トーンマップパレット順序,톤맵 팔레트 순서,Tonemap Palet Orde van het Tonemap-palet,Tonemap-palettrekkefølge,Kolejność Palet Mapowania Tonów,Ordem da paleta tonemap,,Ordine paletă Tonemap,Порядок палитры тонового отображения,Тонирано-мапни палетни ред,Ton Haritası Palet Sırası,Порядок палітри тонального відображення, -Tonemap Palette Exponent,GLPREFMNU_PALTONEMAPPOWER,,,,Exponent palety tónovací mapy,Tonemap-palettens eksponent,Palettenexponent für Tonemap,,Exponeto de Kolormapo-Paletro,Exponente paleta en mapa de tonos,,Sävykartan paletin eksponentti,Exponent des palettes tonemap,Tonemap Paletta Exponens,Esponente della Palette Tonemap,トーンマップパレット指数,톤맵 팔레트 지수,Tonemap Palet Exponent,Tonemap Palette Eksponent,Wykładnik Palet Mapowania Tonów,Expoente da paleta tonemap,,Exponent paletă Tonemap,Экспонента палитры тонового отображения,Тонирано-мапни палетни експонент,Ton Haritası Paleti Üsteli,Експонента палітри тонального відображення, -Multisample,GLPREFMNU_MULTISAMPLE,,,,Multisampling,Multisample,Multisampling,,Plurspecimeno,Multisampling,,Moninäytteistys,,,,マルチサンプル,멀티샘플,,,Multipróbkowanie,Multiamostragem,,Multisampling,Мультисэмплинг,Мулти-узорак,Çoklu Örneklem,Багатовибіркове згладжування, -Bloom effect,GLPREFMNU_BLOOM,,,,Efekt bloom,Bloom-effekt,Bloom Effekt,,Lumŝmiro-efiko,Efecto Bloom,,Hehkutehoste (bloom),Effet surbrillance,Bloom effekt,Effetto Bloom,ブルーム エフェクト,블룸 효과,Bloom-effect,Bloom-effekt,Effekt Bloom,Bloom,,Efect Bloom,Свечение,Мутан вид ефект,Çiçeklenme etkisi,Ефект сяйва, -Ambient occlusion quality,GLPREFMNU_SSAO,,,,Kvalita ambient occlusion,Omgivende okklusionskvalitet,Ambient Occlusion Qualität,,Kvaliteco de media obstrukceco,Calidad de oclusión ambiental,,Yleisvarjostuksen (ambient occlusion) laatu,Qualité Occlusion Ambiente,Ambient occlusion minősége,Qualità occlusione ambientale,アンビエント オクルージョンの品質,주변 환경 가림 효과 품질,Kwaliteit van omgevingsverduistering,Omgivende okklusjonskvalitet,Jakość okluzji otoczenia,Qualidade de oclusão de ambiente,,Calitate ocluzie ambientală,Качество глобального затенения,Оклузија амбијента ефект,Ortam oklüzyon kalitesi,Якість глобального затінення, -Portals with AO,GLPREFMNU_SSAO_PORTALS,,,,Portály s AO,Portaler med AO,Portale mit AO,,Portaloj kun Media obstrukceco,Portales con OA,,Yleisvarjostuksen portaalit,OA pour les portails,Portálok AO-val,Portali con l'OA,AOを伴うポータル,주변 환경 가려진 포탈,Portals met AO,Portaler med AO,Portale z okluzją otoczenia,Portais com oclusão de ambiente,,Portaluri cu ocluzie ambientală,Порталы с глобальным затенением,Портали са AO,AO'lu Portallar,Портали з глобальним затіненням, -Menu Blur,GLPREFMNU_MENUBLUR,,,,Rozostření pozadí v menu,Menu sløring,Menüunschärfe,Θόλοση μενού,Malklarigo de menuo ,Difuminación de menú,,Valikon sumennus,Flou menu,Menü mosódás,Blur del menu,メニューブラー,메뉴 흐림 효과,Menu vervagen,Meny uskarphet,Rozmycie w Menu,Desfoque do menu,Desfocagem do Menu,Neclaritate Meniu,Размытие фона меню,Блур мениа,Menü Bulanıklığı,Розмиття фону в меню, -Environment map on mirrors,GLPREFMNU_ENVIRONMENTMAPMIRROR,,,,Mapa prostředí na zrcadlech,Miljøkort på spejle,Lichteffekt auf Spiegeln,,Medimapo sur speguloj,Mapa de entorno en espejos,,Ympäristökartta peileissä,Mappage environment sur les miroirs,Környezet tükröződés,Ambiente mappa sugli specchi,マップオンミラーの画像表示,거울 주변의지도 활성,Milieukaart op spiegels,Omgivelseskart på speil,Mapa środowiska w lustrach,Mapa de ambiente em espelhos,,Efecte suplimentare pentru oglinzi,Карта окружения на зеркалах,Околинска мапа на прозорима,Aynalar üzerinde çevre haritası,Карта оточення на дзеркалах, -Rendering quality,GLPREFMNU_RENDERQUALITY,,,,Kvalita vykreslování,Renderingskvalitet,Renderqualität,,Kvalito de bildigado,Calidad de renderizado,,Hahmonnuslaatu,Qualité du rendu,Renderelés minősége,Qualità resa grafica,レンダリング品質,렌더링 품질,Het teruggeven van kwaliteit,Renderingskvalitet,Jakość Renderowania,Qualidade de renderização,,Calitate video,Качество отрисовки,Квалитет рендовања,Render kalitesi,Якість візуалізації, -Speed,OPTVAL_SPEED,,,,Rychlost,Hastighed,Geschwindigkeit,Ταχύτητα,Rapido,Velocidad,,Nopeus,Vitesse,Sebesség,Prestazioni,速度寄り,성능,Snelheid,Hastighet,Szybkość,Velocidade,,Viteză,Скорость,Брзина,Hız,Швидкість, -Quality,OPTVAL_QUALITY,,,,Kvalita,Kvalitet,Qualität,Ποιότητα,Kvalito,Calidad,,Laatu,Qualité,Minőség,Qualità,品質寄り,고품질,Kwaliteit,Kvalitet,Jakość,Qualidade,,Calitate,Качество,Квалитет,Kalite,Якість, -Sector light mode,GLPREFMNU_SECLIGHTMODE,,,,Režim osvětlení sektorů,Sektorlystilstand,Sektorlichtmodus,,Reĝimo de sektorlumo,Modo de luz de sector,,Sektorivalojen tila,Mode de lumière Secteur,Szektor fény mód,Modalità luce di settore,セクターライトモード,섹터 조명 모드,Sector lichte wijze,Sektorlysmodus,Tryb oświetlenia sektorów,Modo de luz de setor,,Mod iluminare sectorială,Режим освещения секторов,Секторско светло мод,Sektör ışığı modu,Режим освітлення секторів, -Fog mode,GLPREFMNU_FOGMODE,,,,Režim mlhy,Tågetilstand,Nebelmodus,Λειτουργία ομίχλης,Reĝimo de nebulo,Modo de niebla,,Sumutila,Mode du broullard,Köd mód,Effetto nebbia,フォグモード,안개 모드,Mistmodus,Tåkemodus,Tryb mgły,Modo de neblina,,Mod ceață,Режим тумана,Магла мод,Sis modu,Режим туману, -Radial,OPTVAL_RADIAL,,,,Radiální,Radial,,Ακτινικό,Radiusa,,,Säteittäinen,,Sugaras,Radiale,放射状,방사형,Radiaal,,Promieniowe,,,Radială,Круговой,Радијално,Radyal,Радіальний, -Standard,OPTVAL_STANDARD,,,,Standardní,,,,Norma,Estándar,,Normaali,,Szabvány,Standard,標準,기본,Standaard,,Standard,Padrão,,,Стандартный,Стандардно,Standart,Стандартний, -,,Texture options,,,,,,,,,,,,,,,,,,,,,,,,,, -Texture Filter mode,GLTEXMNU_TEXFILTER,,,,Režim filtrování textur,Tilstand for teksturfilter,Texturfiltermodus,,Reĝimo por Teksturfiltrado,Modo de filtro de texturas,,Pintakuviointien suodatustapa,Mode de Filtrage Texture,Textúrafilter módja,Modalità filtro texture,テクスチャーフィルター モード,텍스쳐 필터 모드,Textuurfiltermodus,Teksturfilter-modus,Tryb Filtrowania Tekstur,Modo de filtro de textura,,Mod Filtrare Texturi,Фильтрация текстур,Текстурни филтер мод,Doku Filtresi modu,Тип фільтрації текстур, -Anisotropic filter,GLTEXMNU_ANISOTROPIC,,,,Anisotropické filtrování,Anisotropisk filter,Anisotropische Filterung,,Anizotropa filtro,Filtro anisotrópico,,Anisotrooppinen suodatus,Filtre Anisotropique,Anizotropikus filter,Filtro anisotropico,異方性フィルター,이방성 필터,Anisotroopfilter,Anisotropisk filter,Filtr anizotropowy,Filtro anisotrópico,,Filtrare Anizotropică,Анизотропная фильтрация,Анизотропни фолтер,Anizotropik filtre,Анізотропна фільтрація, -None (nearest mipmap),OPTVAL_NONENEARESTMIPMAP,,,,Žádné (mipmapa - nejbližší soused),Ingen (nærmeste mipmap),Aus (nächste Mipmap),,Nenio (plej proksima mipmapo),Ninguno (mipmap cercano),,Ei mitään (lähin mipkartta),Aucun (mipmap proche voisin),Semmilyen (közeli mipmap),Nessuno (mipmap più vicina),なし(最寄りミップマップ),없음 (밉멥에 가까움),Geen (dichtstbijzijnde mipmap),Ingen (nærmeste mipmap),Brak (najbliższa mipmapa),Nenhum (mipmap mais próximo),,Niciuna (mipmap de apropriere),Нет (ближайший MIP-уровень),Ништа (најближи мипмап),Yok (en yakın mipmap),Ніякий (найближчий міпмап), -None (linear mipmap),OPTVAL_NONELINEARMIPMAP,,,,Žádné (mipmapa - lineární),Ingen (lineær mipmap),Aus (lineare Mipmap),,Nenio (linia mipmapo),Ninguno (mipmap lineal),,Ei mitään (lin. mipkartta),Aucun (mipmap linéaire),Semmilyen (lineáris mipmap),Nessuno (mipmap lineare),なし(リニアミップマップ),없음 (선형 밉맵),Geen (lineaire mipmap),Ingen (lineær mipmap),Brak (liniowa mipmapa),Nenhum (mipmap linear),,Niciuna (mipmap liniar),Нет (линейный MIP-уровень),Ништа (линеаран мипмап),Yok (doğrusal mipmap),Ніякий (лінійний міпмап), -None (trilinear),OPTVAL_NONETRILINEAR,,,,Žádné (trilineární),Ingen (trilineær),Aus (trilinear),,Nenio (trilinia),Ninguno (trilineal),,Ei mitään (trilineaarinen),Aucun (mipmap trilinéaire),Semmilyen (trilineáris),Nessuno (mipmap trilineare),なし(トライリニア),없음 (삼선형),Geen (trilineair),Ingen (trilineær),Brak (trzyliniowe),Nenhum (trilinear),,Niciuna (trilinar),Нет (трилинейная),Ништа (трилинеарно),Yok (trilineer),Ніякий (трилінійний), -Bilinear,OPTVAL_BILINEAR,,,,Bilineární,Bilineær,,,Dulinia,Bilineal,,Bilineaarinen,Bilinéaire,Bilineáris,Bilineare,バイリニア,쌍선형,Bilineair,Bilineær,Dwuliniowe,Bilinear,,Biliniar,Билинейная,Билинеарно,Bilineer,Білінійний, -Trilinear,OPTVAL_TRILINEAR,,,,Trilineární,Trilineær,,,Trilinia,Trilineal,,Trilineaarinen,Trilinéaire,Trilineáris,Trilineare,トライリニア,삼선형,Trilineair,Trilineær,Trzyliniowe,Trilinear,,Triliniar,Трилинейная,Трилинеарно,Trilineer,Трилінійний, -2x,OPTVAL_2X,,,,,,,,2-oble,,,,,,,,,,,,,,,,,,, -4x,OPTVAL_4X,,,,,,,,4-oble,,,,,,,,,,,,,,,,,,, -8x,OPTVAL_8X,,,,,,,,8-oble,,,,,,,,,,,,,,,,,,, -16x,OPTVAL_16X,,,,,,,,16-oble,,,,,,,,,,,,,,,,,,, -32x,OPTVAL_32X,,,,,,,,32-oble,,,,,,,,,,,,,,,,,,, -Texture Options,GLTEXMNU_TITLE,,,,Nastavení textur,Indstillinger for teksturer,Texturoptionen,,Agordoj de Teksturoj,Opciones de texturas,,Pintakuviointiasetukset,Options Textures,Textúra Beállítások,Opzioni Texture,テクスチャー オプション,텍스쳐 설정,Textuur Opties,Teksturalternativer,Opcje Tekstur,Opções de Textura,,Setări Texturi,Настройки текстур,Подешавања текстура,Doku Seçenekleri,Параметри текстур, -Textures enabled,GLTEXMNU_TEXENABLED,,,,Povolit textury,Teksturer aktiveret,Texturen an,,Teksturoj ŝaltitaj,Texturas activadas,,Pintakuvioinnit otettu käyttöön,Textures activées,Textúrák bekapcsolása,Texture abilitate,テクスチャー有効,텍스쳐 사용,Texturen ingeschakeld,Teksturer aktivert,Tekstury włączone,Texturas ativadas,,Texturi Activate,Включить текстуры,Текстуре омогућене,Dokular etkinleştirildi,Увімкнути текстури, -Enable hires textures,GLTEXMNU_ENABLEHIRES,,,,Povolit textury ve vysokém rozlišení,Aktivere hi-res teksturer,Hochauflösende Texturen an,,Ŝalti Altdistingivajn Teksturojn,Activar texturas de alta resolución,,Salli korkean erotuskyvyn pintakuvioinnit,Activer Textures haute résolution,Magas felbontású textúrák bekapcsolása,Abilita texture alta qualità,ハイレゾ テクスチャー有効,고해상도 텍스쳐 사용,Hoge-resolutie texturen op,Aktivere høyoppløselige teksturer,Włącz tekstury wysokiej jakości,Habilitar texturas de alta resolução,,Texturi de înaltă rezoluție,Текстуры высокого разрешения,Омогући текстуре велике резолуције,Yüksek çözünürlüklü dokuları etkinleştir,Увімкнути текстури високого розширення, -High Quality Resize mode,GLTEXMNU_HQRESIZE,,,,Režim zvětšovače textur,Tilstand til ændring af størrelse i høj kvalitet,Texturskalierungsmodus,,Reĝimo de Altdistingivigo-Skalilo,Modo de ajuste de alta calidad,,Korkealaatuinen kuvakoon muutostapa,Mise à l'échelle haute résolution,Magas minőségű újraméretező mód,Modalità resize alta qualità,高品質リサイズ モード,고퀄리티 리사이즈 모드,Textuurschaalmodus,Høy kvalitet Endre størrelse-modus,Tryb Wysokiej Jakości Zmieniania Rozmiaru,Modo de Redimensionamento de Alta Qualidade,,Mod Redimensionare de Înaltă Calitate,Режим высококачественного масштабирования текстур,Промена величине високог квалитета мод,Yüksek Kalite Yeniden Boyutlandırma modu,Масштабування текстур, -High Quality Resize multiplier,GLTEXMNU_HQRESIZEMULT,,,,Faktor zvětšovače textur,Multiplikator for ændring af størrelse i høj kvalitet,Texturskaluerungsfaktor,,Obligilo de Altdistingivigo-Skalilo,Multiplicador de ajuste de alta calidad,,Korkealaatuisen kuvakokomuutoksen kerroin,Multiplicateur de mise à l'échelle,Magas minőségű újraméretezés szorzó,Moltiplicatore resize alta qualità,高品質リサイズ乗数,고퀄리티 리사이징 승수,Textuurschaalfactor,Multiplikator for størrelsesendring av høy kvalitet,Mnożnik Wysokiej Jakośći Rozmiaru,Multiplicador de Redimensionamento de Alta Qualidade,,Factor de Scalare,Множитель высококачественного масштабирования,Промена величине високог квалитета мултипликатор,Yüksek Kalite Yeniden Boyutlandırma çarpanı,Множник масштабування, -This mode requires %d times more video memory,GLTEXMNU_HQRESIZEWARN,,,,Tento režim potřebuje %dkrát více paměti,Denne tilstand kræver %d gange mere videohukommelse,Dieser Modus benötigt das %d-fache an Videospeicher,Αυτή η λειτουργία χρειάζετε %d περισσότερες φορές μνήμη βίντεο,Ĉi tiu reĝimo bezonas %d-oble pli da ekranmemoro.,Este modo requiere %d veces más memoria de vídeo,,Tämä tila vaatii %d kertaa enemmän videomuistia,Ce mode nécessite %d fois plus de mémoire vidéo,Ez a mód a jelenlegi videó memória %d-szeresét igényli,Questa modalità richiede %d volte la memoria video,このモードでは %d 倍以上のビデオメモリが必要です!,이 설정은 비디오 메모리의 %d 배가 더 필요합니다.,Deze modus vereist %d keer meer videogeheugen.,Denne modusen krever %d ganger mer videominne,Ten tryb wymaga %d razy więcej pamięci wideo,Este modo precisa de %d vezes mais memória de vídeo,,Acest mod necesită de %d mai multă memorie video,Данный режим требует в %d раз больше видеопамяти,Овај мод тражи %d пута више видео меморије,Bu mod %d kat daha fazla video belleği gerektirir,Цьому типу потрібно в %d більше відеопам'яті, -Resize textures,GLTEXMNU_RESIZETEX,,,,Škálovat textury,Ændre størrelse på teksturer,Texturen skalieren,,Regrandigi teksturojn,Ajustar texturas,,Muuta pintakuviointien kokoa,Mise à l'échelle textures,Textúrák újraméretezése,Resize delle texture,リサイズ テクスチャー,텍스쳐 리사이징,Texturen schalen,Endre størrelse på teksturer,Zmień rozmiar tekstur,Redimensionar texturas,,Redimensionare texturi,Масштабирование текстур,Промена величине текстура,Dokuları yeniden boyutlandırma,Масштабування текстур, -Resize sprites,GLTEXMNU_RESIZESPR,,,,Škálovat sprity,Ændre størrelse på sprites,Sprites skalieren,,Regrandigi spritojn,Ajustar sprites,,Muuta spritejen kokoa,Mise à l'échelle sprites,Sprite-ok újraméretezése,Resize degli sprite,リサイズ スプライト,스프라이트 리사이징,Sprites schalen,Endre størrelse på sprites,Zmień rozmiar sprite'ów,Redimensionar sprites,,Redimensionare sprite-uri,Масштабирование спрайтов,Промена величине спрајтова,Sprite'ları yeniden boyutlandırma,Масштабування спрайтів, -Resize fonts,GLTEXMNU_RESIZEFNT,,,,Škálovat fonty,Ændre størrelse på skrifttyper,Zeichensätze skalieren,,Regrandigi tiparojn,Ajustar fuentes,,Muuta kirjasinten kokoa,Mise à l'échelle texte,Betűk újraméretezése,Resize dei font,リサイズ フォント,폰트 리사이징,Lettertypen schalen,Endre størrelse på skrifter,Zmień rozmiar czcionek,Redimensionar fontes,,Redimensionare fonturi,Масштабирование шрифтов,Промена величине фонта,Yazı tiplerini yeniden boyutlandırma,Масштабування шрифтів, -Resize model skins,GLTEXMNU_RESIZESKN,,,,Škálovat skiny modelů,Ændre størrelsen på modelskins,,,Regrandigi haŭtojn de modeloj,Ajustar texturas de modelo,,Muuta ulkoasujen kokoa,,Model fazon újraméretezése,Ridimensiona skin modello,リサイズ モデルスキン,,,Endre størrelse på modellskinn,Zmień rozmiar modelu,Redimensionar skins de modelos,,Redimensionare modele,Масштабирование обликов моделей,,Model kaplamalarını yeniden boyutlandırma,Масштабування текстур моделей, -Precache GL textures,GLTEXMNU_PRECACHETEX,,,,Přednačíst GL textury do cache,Precache GL-teksturer,GL Texturen zwischenspeichern,,Antaŭkaŝmemorigi GL-teksturojn,Precaché de texturas GL,,Kirjoita GL-pintakuvioinnit välimuistiin,Mise en cache des textures,Előcachelt GL textúrák,Precache texture GL,プリキャッシュ GLテクスチャー,지엘 텍스쳐 미리 캐싱함,Precache GL texturen,Precache GL-teksturer,Tekstury GL pamięci podręcznej,Precachê de texturas GL,,Preîncărcarcă texturile GL,Кэшировать GL-текстуры,Прикеширане GL текстуре,GL dokularını önceden önbelleğe alma,Кешувати GL-текстури, -Video Mode,VIDMNU_TITLE,,,,Režim displeje,Videotilstand,Videomodus,Λειτουργία βίντεο,Video-reĝimo,Modos de vídeo,Modos de video,Videotila,Mode Vidéo,Videó mód,Modalità video,ビデオ 調整,화면 설정,Videomodus,Videomodus,Tryb Wideo,Modo de vídeo,,Mod Video,Настройки видеорежима,Видео мод,Video Modu,Налаштування відеорежиму, -Notebook Switchable GPU,DSPLYMNU_GPUSWITCH,,,,Přepínatelné GPU pro notebooky,Notebook Switchable GPU,GPU Umschaltung für Notebooks,,Kajero-ŝanĝebla GPU,GPU switching de portátil,,Kannettavan kytkettävä grafiikkapiiri,GPU alternatif sur PC Portable,Laptop Váltható GPU,Scheda GPU Switchable per notebook,ノートブックGPU切替,노트북 성능 조정,Notitieboekje schakelbare GPU,Notatbok Byttbar GPU,Zmiana GPU Notebooka,Placa de vídeo alternável de notebook,,Placă Video Alternativă pentru Notebook,Использование видеокарты ноутбука,Користи GPU ноутбук,Dizüstü Bilgisayar Değiştirilebilir GPU,Використання GPU ноутбука, -Scaled (Nearest),OPTVAL_SCALENEAREST,,,,Škálován (nejbližší),Skaleret (Nærmeste),Skaliert (nächster Nachbar),,Skalita (Plej proksime),Escalado (Lo más cerca),,Skaalattu (läheisin),Mis à l'échelle (Proche Voisin),Átméretezett (Közeli),Scalato (più vicino),スケーリング (最寄り),확대 (가깝게),Geschaald (Dichtstbijzijnd),Skalert (nærmeste),Przeskalowany (Najbliższy),Redimensionado (mais próximo),Redimensionado (Apróximado),Redimensionat (Cel mai aproape),Масштабировать (ближайшее),Скалиран (најближи),Ölçeklendirilmiş (En Yakın),Збільшення (ближнє), -Scaled (Linear),OPTVAL_SCALELINEAR,,,,Škálován (lineární),Skaleret (lineær),Skaliert(linear),,Skalita (Linie),Escalado (Lineal),,Skaalattu (lineaarinen),Mis à l'échelle (Linéaire),Átméretezett (Lineáris),Scalato (lineare),スケーリング (リニア),확대 (선형 식),Geschaald (Lineair),Skalert (lineær),Przeskalowany (Liniowy),Redimensionado (linear),,Redimensionat (Liniar),Масштабировать (линейное),Скалиран (линеарно),Ölçeklendirilmiş (Doğrusal),Збільшення (лінійне), -Letterbox,OPTVAL_LETTERBOX,,,,,,,,Leterkesto,Barras negras,,Mustat reunat,,Levágott,Bande nere,レターボックス,레터박스,,,,Barras pretas,,Ecran Parțial,Экранное каше,Поштанско сандуче,,Техніка каше, -Stretch,OPTVAL_STRETCH,,,,Roztažený,Stræk,Strecken,,Streĉi,Estrechado,Estrecho,Venytetty,Etirer,Nyújtott,Disteso,伸縮,늘림,Rek,Strekk,Rozciągnięty,Esticado,,Lărgire,Растянутый,Растегнуто,Esneme,Розтягнутий, -Render Mode,VIDMNU_RENDERMODE,,,,Režim rendereru,Rendertilstand,Rendermodus,,Bildigo-reĝimo,Modo de renderizado,,Hahmonnustila,Mode de Rendu,Render Mód,Modalità rendering,レンダラー,렌더링 설정,Rendermodus,Gjengivelsesmodus,Tryb Renderowania,Modo de renderização,,Mod Video,Режим отрисовки,Рендер мод,İşleme Modu,Режим візуалізації, -Fullscreen,VIDMNU_FULLSCREEN,,,,Přes celou obrazovku,Fuld skærm,Vollbild,Πλήρης οθόνη,Plena ekrano,Pantalla completa,,Koko näyttö,Plein écran,Teljes Képernyő,Schermata piena,全画面,전체화면,Volledig scherm,Fullskjerm,Pełen Ekran,Tela cheia,Ecrã cheio,Ecran Complet,Полный экран,Цео екран,Tam Ekran,Повноекранний, -Retina/HiDPI support,VIDMNU_HIDPI,,,,Podpora Retiny/HiDPI,Retina/HiDPI-understøttelse,Retina/HDPI-Unterstützung,,Retino/HiDPI subteno,Soporte para Retina/HiDPI,,Retina/HiDPI-tuki,Support Retina/HiDPI ,Retina/HiDPI támogatás,Supporto Retina/HiDPi,Retina/HiDPI サポート,망막/하이DPI 활성화,Retina / HiDPI-ondersteuning,Retina/HiDPI-støtte,Wsparcie Retina/HiDPI,Suporte para Retina/HiDPI,,Suport Retina/HiDPI,Поддержка Retina/HiDPI,Retina/HiDPI подршка,Retina/HiDPI desteği,Підтримка Retina/HiDPI, -Aspect ratio,VIDMNU_ASPECTRATIO,,,,Poměr stran,Aspektforhold,Seitenverhältnis,,Ekran-proporcio,Relación de aspecto,,Kuvasuhde,Rapport D'Aspect,Képarány,Proporzioni,アスペクト比,종횡비,Beeldverhouding,Bildeforhold,Wpółczynnik proporcji,Proporção de tela,Proporção de ecrã,Aspect Imagine,Соотношение сторон,Однос гледишта,En boy oranı,Співвідношення сторін, -Force aspect ratio,VIDMNU_FORCEASPECT,,,,Vynutit poměr stran,Tvinge formatforhold,Erzwinge Seitenverhältnis,,Devigi ekran-proporcion,Forzar relación de aspecto,,Pakota kuvasuhde,Forcer Rapport,Képarány kényszerítése,Forza le proporzioni video,アスペクト比に従う,강제 종횡비,Geforceerde beeldverhouding,Tving sideforhold,Wymuś współczynnik proporcji,Forçar proporção de tela,Forçar proporcção de ecrã,Forțează aspectul imaginii,Принудительное соотношение сторон,Присили однос гледишта,Kuvvet en-boy oranı,Примусове співвідношення сторін, -Forced ratio style,VIDMNU_CROPASPECT,,,,Vynucený poměr stran,Stil med tvunget forhold,Modus für erzwungenes Seitenverhältnis,,Stilo por devigita proporcio,Relación de aspecto forzada,,Kuvasuhteen pakotustapa,Style de Ratio forcé,Kényszerített képarány stílusa,Forza lo stile delle proporzioni,比率の形式,강제 비율 스타일,Geforceerde verhoudingsstijl,Tvunget formatforhold-stil,Wymuszony styl współczynnika,Estilo de proporção forçado,,Forțează tipul proporțiilor,Тип принудительного соотношения сторон,Присиљен стил односа,Zorlanmış oran stili,Тип примусового співвідношення сторін, -Enable 5:4 aspect ratio,VIDMNU_5X4ASPECTRATIO,,,,Povolit poměr stran 5:4,Aktiver 5:4-billedformat,Erlaube 5:4 Seitenverhältnis,,Ŝalti 5:4 ekran-proporcion,Activar relación de aspecto 5:4,,Ota käyttöön 5:4-kuvasuhde,Activer Rapport 5:4,5:4 képarány engedélyezése,Abilita le proporzioni 5:4,5:4アスペクト比を可能にする,5:4 비율 사용,Schakel 5:4 beeldverhouding in,Aktiver 5:4 sideforhold,Włącz współczynnik proporcji 5:4,Ativar proporção de tela 5:4,,Activează formatul 5:4,Включить соотношение сторон 5:4,Омогући 5:4 однос гледишта,5:4 en boy oranını etkinleştirin,Увімкнути співвідношення сторін 5:4, -Resolution scale,VIDMNU_SCALEMODE,,,,Škálování rozlišení,Opløsningsskala,Skalierung,,Distingivo-skalo,Escala de resolución,,Resoluution skaalaus,Echelle de Résolution,Felbontás mérete,Scala di risoluzione,画面スケール,해상도 크기,Resolutieschaal,Oppløsningsskala,Skala rozdzielczości,Escala de resolução,,Scară rezoluție,Масштабирование,Резолуцијска скала,Çözünürlük ölçeği,Масштабування, -Scale Factor,VIDMNU_SCALEFACTOR,,,,Faktor rozlišení,Skalafaktor,Skalierungsfaktor,,Skalfaktoro,Factor de escala,,Skaalauskerroin,Facteur d'échelle,Méretezési Faktor,Fattore di scala,スケール倍率,축척 펙터,Schaalfactor,Skaleringsfaktor,Współczynnik Skali,Fator de escala,,Factor Scalare,Значение масштаба,Фактор скалирања,Ölçek Faktörü,Значення масштабування, -Use Linear Scaling (Fullscreen),VIDMNU_USELINEAR,,,,Použít lineární škálování (přes celou obrazovku),Brug lineær skalering (fuld skærm),Lineare Skalierung (Vollbild),,Uzi linian skaladon (Plenekrane),Usar escalado linear (Pant. completa),,Lineaarinen skaalaus (koko näyttö),Mise à l'échelle Linéaire (Plein écran),Lineáris Méretezés Használata (Teljes képernyő),Usa lo scaling lineare (a schermo pieno),リニアスケールを使う(全画面),선형 스케일링 사용 (전체화면),Lineaire schaalverdeling gebruiken (volledig scherm),Bruk lineær skalering (fullskjerm),Użyj Liniowego Skalowania (Pełen Ekran),Usar escala linear (tela cheia),Usar escala linear (ecrã cheio),Folosește Scalarea Liniară (Ecran Complet),Линейное масштабирование (полный экран),Користи линеарно скалирање (цео екран),Doğrusal Ölçeklemeyi Kullan (Tam Ekran),Лінійне масштабування (повний екран), -Custom Pixel Scaling,VIDMNU_CUSTOMRES,,,,Vlastní škálování pixelů,Brugerdefineret pixelskalering,Benutzerdefinierte Skalierung,,Adaptita rastrumero-skalo,Escalado de píxel personalizado,,Mukautettu skaalaus,Résolution Personalisée,Egyéni Pixelméretezés,Scaling dei pixel personalizzato,カスタム ピクセルスケール,사용자 지정 픽셀 크기 조정,Aangepaste pixelschaalvergroting,Egendefinert pikselskalering,Niestandardowe Skalowanie Pikseli,Escala de pixels personalizada,,Scară Pixeli Personalizată,Масштабирование пикселей,Пиксел скалирање,Özel Piksel Ölçeklendirme,Масштабування пікселів, -Custom Width,VIDMNU_CUSTOMX,,,,Vlastní šířka,Brugerdefineret bredde,Benutzerdefinierte Breite,,Adaptita larĝeco,Ancho personalizado,,Mukautettu leveys,Largeur Personalisée,Egyéni szélesség,Lunghezza,カスタム 幅,사용자 지정 너비,Aangepaste breedte,Egendefinert bredde,Niestandardowa Szerokość,Largura personalizada,,Lățime Personalizată,Длина,Ширина,Özel Genişlik,Довжина, -Custom Height,VIDMNU_CUSTOMY,,,,Vlastní výška,Brugerdefineret højde,Benutzerdefinierte Höhe,,Adaptita alteco,Alto personalizado,,Mukautettu korkeus,Hauteur Personalisée,Egyéni magasság,Altezza,カスタム 高さ,사용자 지정 높이,Aangepaste hoogte,Egendefinert høyde,Niestandardowa Wysokość,Altura personalizada,,Înălțime Personalizată,Высота,Висина,Özel Yükseklik,Висота, -Apply Changes (Windowed),VIDMNU_APPLYW,,,,Použít změny (v okně),Anvend ændringer (vindue),Änderungen anwenden (Fenster),,Apliki ŝanĝojn (Fenestrite),Aplicar cambios (Ventana),,Ota käyttöön muutokset (ikkuna),Appliquer Changements (Fenêtre),Változtatások Elfogadása (Ablak),Applica le modifiche (a finestra),変更を適用(ウィンドウ化),변경 적용 (윈도우),Wijzigingen toepassen (in venster),Bruk endringer (vindusbasert),Zatwierdź Zmiany (Okno),Aplicar alterações (janela),,Aplică Schimbările (Mod Fereastră),Сохранить изменения (оконный режим),Примени промене (прозор),Değişiklikleri Uygula (Pencereli),Зберегти зміни (віконний режим), -Apply Changes (Fullscreen),VIDMNU_APPLYFS,,,,Použít změny (přes celou obrazovku),Anvend ændringer (fuld skærm),Änderungen anwenden (Vollbild),,Apliki ŝanĝojn (Plenekrane),Aplicar cambios (Pant. completa),,Ota käyttöön muutokset (koko näyttö),Appliquer Changements (Plein écran),Változtatások Elfogadása (Teljes képernyő),Applica le modifiche (a schermo pieno),変更を適用(全画面化),변경 적용 (전체화면),Wijzigingen toepassen (Volledig scherm),Bruk endringer (fullskjerm),Zatwierdź Zmiany (Pełen Ekran),Aplicar alterações (tela cheia),Aplicar alterações (ecrã cheio),Aplică Schimbările (Mod Ecran Complet),Сохранить изменения (полный экран),Примени промене (цели екран),Değişiklikleri Uygula (Tam Ekran),Зберегти зміни (повноекранний режим), -Choose Resolution Preset,VIDMNU_RESPRESET,,,,Vybrat přednastavené rozlišení,Vælg forindstillet opløsning,Auflösungsvoreinstellung,,Elekti antaŭagorditan distingivon,Elegir resolución predefinida,,Valitse ennalta määritetty resoluutio,Choisir paramètre personalisé,Felbontási Sablon Kiválasztása,Scegli preset di risoluzione,解像度プリセットを選ぶ,해상도 사전 설정 선택,Kies een vooraf ingestelde resolutie,Velg forhåndsinnstilt oppløsning,Wybierz Zestaw Rozdzielczości,Escolher resolução predefinida,,Alege Rezoluția Predefinită,Выбор шаблона разрешения,Резолуцијска подешавања,Çözünürlük Ön Ayarını Seçin,Вибір пресету роздільної здатності, -Custom Resolution Presets,VIDMNU_RESPRESETTTL,,,,Vlastní přednastavení rozlišení,Brugerdefinerede opløsningsforudindstillinger,Benutzerdefinierte Auflösungsvoreinstellungen,,Viaj antaŭagorditaj distingivoj,Resoluciones predefinidas personalizadas,,Ennalta määritetyt mukautetut resoluutiot,Résolutions Personalisée,Egyéni Felbontási Sablonok,Preset di risoluzione personalizzati,カスタム解像度プリセット,사용자 지정 해상도 미리 조정,Vooraf ingestelde aangepaste resoluties,Egendefinerte forhåndsinnstillinger for oppløsning,Niestandardowe Zestawy Rozdzielczości,Predefinições de resolução personalizadas,,Rezoluții Personalizate,Пользовательские шаблоны,Резолуцијска подешавања,Özel Çözünürlük Ön Ayarları,Користувацькі пресети, -Preset Resolution Modes,VIDMNU_RESPRESETHEAD,,,,Přednastavená rozlišení,Forindstillede opløsningsmodes,Vordefinierte Auflösungsmodi,,Reĝimoj pri antaŭagordita distingivo,Modos de resolución predefinida,,Ennalta määritetyt resoluutiotilat,Choisir mode de Résolution,Felbontási Sablon Módok,Modalità preset di risoluzione,解像度モードの調整,해상도 미리 조정 모드,Vooraf ingestelde resolutiemodi,Forhåndsinnstilte oppløsningsmoduser,Tryby Zestawów Rozdzielczości,Modos de resolução predefinidas,,Rezoluții Predefinite,Доступные разрешения,Постављени резолуцијски модови,Önceden Ayarlanmış Çözünürlük Modları,Доступні роздільні здатності, -4:3 Aspect,VIDMNU_ASPECT43,,,,Poměr stran 4:3,4:3 Aspekt,4:3 Seitenverhältnis,,4:3 proporcio,Aspecto 4:3,,4:3-tilat,Rapport 4:3,4:3 Arány,Aspetto 4:3,4:3アスペクト比,4:3 비율,Beeldverhouding 4:3,4:3 Aspekt,Proporcje 4:3,Proporção 4:3,,Aspect 4:3,Соотношение сторон 4:3,4:3 гледиште,4:3 Görüntü,Співвідношення сторін 4:3, -5:4 Aspect,VIDMNU_ASPECT54,,,,Poměr stran 5:4,5:4 Aspekt,5:4 Seitenverhältnis,,5:4 proporcio,Aspecto 5:4,,5:4-tilat,Rapport 5:4,5:4 Arány,Aspetto 5:4,5:4アスペクト比,5:4 비율,Beeldverhouding 5:4,5:4 Aspekt,Proporcje 5:4,Proporção 5:4,,Aspect 5:4,Соотношение сторон 5:4,5:4 гледиште,5:4 Görüntü,Співвідношення сторін 5:4, -16:9 Aspect,VIDMNU_ASPECT169,,,,Poměr stran 16:9,16:9 Aspekt,16:9 Seitenverhältnis,,16:9 proporcio,Aspecto 16:9,,16:9-tilat,Rapport 16:9,16:9 Arány,Aspetto 16:9,16:9アスペクト比,16:9 비율,Beeldverhouding 16:9,16:9 Aspekt,Proporcje 16:9,Proporção 16:9,,Aspect 16:9,Соотношение сторон 16:9,16:9 гледиште,16:9 Görüntü,Співвідношення сторін 16:9, -16:10 Aspect,VIDMNU_ASPECT1610,,,,Poměr stran 16:10,16:10 Aspekt,16.10 Seitenverhältnis,,16:10 proporcio,Aspecto 16:10,,16:10-tilat,Rapport 16:10,16:10 Arány,Aspetto 16:10,16:10アスペクト比,16:10 비율,Beeldverhouding 16:10,16:10 Aspekt,Proporcje 16:10,Proporção 16:10,,Aspect 16:10,Соотношение сторон 16:10,16:10 гледиште,16:10 Aspect,Співвідношення сторін 16:10, -21:9 Aspect,VIDMNU_ASPECT219,,,,Poměr stran 21:9,21:9 Aspekt,21.9 Seitenverhältnis,,21:9 proporcio,Aspecto 21:9,,21:9-tilat,Rapport 21:9,21:9 Arány,Aspetto 21:9,21:9アスペクト比,21:9 비율,Beeldverhouding 21:9,21:9 Aspekt,Proporcje 21:9,Proporção 21:9,,Aspect 21:9,Соотношение сторон 21:9,21:9 гледиште,21:9 Görüntü,Співвідношення сторін 21:9, -Normal,OPTVAL_NORMAL,,,,Normální,,,,Normala,,,Normaali,,Normál,Normale,通常,기본형,Normaal,,Normalny,Normal,,,Обычный,Нормално,Normal,Нормальний, -Lowest Possible Scale,OPTVAL_LOWEST,"This describes vid_scalemode 1, which represents the lowest possible scaling to fill the allocated screen area",,,Nejmenší možná velikost,Lavest mulige skala,Kleinstmögliche Auflösung,,Plej malalta ebla skalo,Menor escala posible,,Pienin mahdollinen skaalaus,Echelle la plus faible,Lehető legkisebb méret,Scala minima,可能な限り最小,,Laagst mogelijk schaal,Lavest mulig skala,Najniższa możliwa skala,Menor escala possível,,Cea mai Mică Scară Posibilă,Наименьший возможный масштаб,,Mümkün Olan En Düşük Ölçek,Найменш можливий масштаб, -Custom,OPTVAL_CUSTOM,,,,Vlastní,Brugerdefineret,Benutzerdefiniert,,Agordita de vi,Personalizado,,Mukautettu,Modifié,Egyéni,Personalizzato,カスタム,사용자 지정,Gebruikergedefinieerd,Egendefinert,Niestandardowe,Personalizado,,Personalizat,Польз.,Прилагођ.,Özel,Корист., -Max FPS,VIDMNU_MAXFPS,,,,Maximální FPS,,,,Maksimumaj kadroj laŭ sekundo,Límite de FPS,,Kuvataajuuden rajoitin,,,FPS Massimi,最大FPS値,,Max FPS,Maks FPS,Maksymalna ilość klatek,FPS máximo,,Cadre pe secundă,Максимальная частота кадров,,Maksimum FPS,Макс. частота кадрів, -60 fps,OPTVAL_60FPS,,,,,,,,,,,60 kuvaa/s,,,,,,,,,60 FPS,,,60 к/с,,,60 кадрів, -75 fps,OPTVAL_75FPS,,,,,,,,,,,75 kuvaa/s,,,,,,,,,75 FPS,,,75 к/с,,,75 кадрів, -90 fps,OPTVAL_90FPS,,,,,,,,,,,90 kuvaa/s,,,,,,,,,90 FPS,,,90 к/с,,,90 кадрів, -120 fps,OPTVAL_120FPS,,,,,,,,,,,120 kuvaa/s,,,,,,,,,120 FPS,,,120 к/с,,,120 кадрів, -144 fps,OPTVAL_144FPS,,,,,,,,,,,144 kuvaa/s,,,,,,,,,144 FPS,,,144 к/с,,,144 кадри, -200 fps,OPTVAL_200FPS,,,,,,,,,,,200 kuvaa/s,,,,,,,,,200 FPS,,,200 к/с,,,200 кадрів, -Preferred Rendering API,VIDMNU_PREFERBACKEND,,,,Upřednostňované render API,Foretrukken Rendering API,Bevorzugtes Render API,Προτιμούμενο Rendering API,Preferita bildigado de API,API de renderizado preferida,,Ensisijainen hahmonnuksen ohjelmointirajapinta,API de rendu préférée,Előnyben részesített renderelő API,API di rendering preferita,優先レンダリングAPI,기본적인 API 랜더링,Voorkeur rendering API,Foretrukket Rendering API,Preferowany interfejs API renderowania,API de renderização preferida,,API Video Preferat,Предпочтительный API отрисовки,Преферред АПИ приказивања,Tercih Edilen Rendering API,Бажаний інтерфейс візуалізації, -OpenGL,OPTVAL_OPENGL,,,,,,,,,,,,,,,,,,,,,,,,,,, -Vulkan,OPTVAL_VULKAN,,,,,,,,,,,,,,,,,,,,,,,,,,, -OpenGL ES,OPTVAL_OPENGLES,Rendering backend,,,,,,,,,,,,,,,,,,,,,,,,,, -,,Miscellaneous Options,,,,,,,,,,,,,,,,,,,,,,,,,, -Merge left+right Alt/Ctrl/Shift,MISCMNU_MERGEKEYS,,,,Kombinovat pravý a levý Alt/Ctrl/Shift,Flette venstre+højre Alt/Ctrl/Shift,Linke und rechte Umschalt/Strg/Alt zusammenfassen,,Kunigi maldekstran kaj dekstran Alt/Ctrl/Shift,Combinar Alt/Ctrl/Mayús izq. y der.,Combinar Alt/Ctrl/Shift izq. y der.,Yhdistä vasen ja oikea Alt/Ctrl/Vaihto,Combiner Alt/Ctrl/maj gauche & droite,Bal és jobb Ctrl/Alt/Shift egyként érzékelése,Unisci sinistra+destra Alt/Control/Maiusc,左と右のALT/CTRL/SHIFTキーを統合,양쪽 ALT/CTRL/SHIFT키 합병,Samenvoegen links+rechts Alt/Ctrl/Shift,Slå sammen venstre+høyre Alt/Ctrl/Shift,Połącz przyciski lewo+prawo Alt/Ctrl/Shift,"Unir as teclas Alt, Ctrl e Shift esquerdos e direitos",Juntar Alt/Ctrl/Shift esquerdo+direito,Combină Alt/Ctrl/Shift stâng+drept,Не различать левую/правую ALT/CTRL/SHIFT,Споји лево+десно Аlt/Ctrl/Shift,Sol+sağ birleştirme Alt/Ctrl/Shift,Не розділяти лівий/правий ALT/CTRL/SHIFT, -Alt-Enter toggles fullscreen,MISCMNU_WINFULLSCREENTOGGLE,,,,Alt-Enter přepíná celou obrazovku,Alt-Enter skifter til fuld skærm,Alt-Enter schaltet Vollbild an/aus,,Alt+Enter baskuligas tutekranan reĝimon,Alt+Enter alterna pantalla completa,,Alt-Enter kytkee täyden ruudun päälle/pois,Alt-Entrée alterne plein écran,Alt-Enter teljes képernyőre kapcsol,Alt-Invio attiva/disattiva lo schermo pieno,ALTとENTERで全画面に切り替え,ALT+ENTER키로 전체화면 조정,Alt-Enter schakelt het volledige scherm aan/uit,Alt-Enter veksler til fullskjerm,Alt-Enter przełącza na pełen ekran,Alt+Enter ativa tela cheia,Alt-Enter ativa ecrã cheio,Alt-Enter comută modul ecran complet,Переключение полного экрана по ALT+ENTER,Alt-Enter пребацује на цео екран,Alt-Enter tam ekrana geçiş yapar,Перемикання повного екрану на ALT+ENTER, -Command-F toggles fullscreen,MISCMNU_MACFULLSCREENTOGGLE,,,,Command-F přepíná celou obrazovku,Command-F skifter til fuld skærm,Cmd-F schaltet Vollbild an/aus,,Komando-F baskuligas tutekranan reĝimon,Cmd-F alterna pantalla completa,,Komento-F kytkee täyden ruudun päälle/pois,Command-F alterne plein écran,Command-F teljes képernyőre kapcsol,Command-F attiva/disattiva lo schermo pieno,Ctrl + Fキーで全画面表示,COMMAND+F키로 전체화면 조정,Command-F schakelt het volledige scherm aan/uit,Kommando-F veksler til fullskjerm,Command-F przełącza pełny ekran,Command+F ativa tela cheia,Command-F ativa ecrã cheio,Command-F comută modul ecran complet,Переключение полного экрана по Command+F,Command-F пребацује на цео екран,Command-F tam ekrana geçiş yapar,Перемикання повного екрану на Command+F, -Enable autosaves,MISCMNU_ENABLEAUTOSAVES,,,,Povolit automatické ukládání,Aktiver autosaves,Automatisches Speichern,,Ŝalti aŭtomatajn konservojn de ludadoj,Activar autoguardado,,Ota käyttöön automaattiset tallennukset,Activer Sauvegardes auto,Automentések engedélyezése,Abilita i salvataggi automatici,オートセーブを有効化,빠른 저장 허용,Automatisch opslaan inschakelen,Aktiver automatisk lagring,Włącz autozapis,Ativar salvamento automático,Permitir gravação automática,Permite salvări automate,Автосохранения,Омогући аутосејвове,Otomatik kaydetmeyi etkinleştir,Автозбереження, -Number of autosaves,MISCMNU_AUTOSAVECOUNT,,,,Počet automaticky uložených her,Antal autosaves,Anzahl von automatischen Speicherständen,,Maksimuma kvanto da aŭtomataj konservoj,Cantidad máxima de autoguardados,,Automaattisten tallennusten lukumäärä,Total de sauvegardes auto,Automentések száma,Numero di salvataggi automatici,オートセーブの最大数,빠른 저장 수,Aantal auto-opslagen,Antall autolagringer,Liczba autozapisów,Número de salvamentos automáticos,Número de gravações automáticas,Număr salvări automate,Количество автосохранений,Број аутоматских чувања,Otomatik kaydetme sayısı,Кількість автозбрежень, -Save/Load confirmation,MISCMNU_SAVELOADCONFIRMATION,,,,Potvrzení o uložení/načtení,Bekræftelse af gem/indlæsning,Laden/Speichern bestätigen,,Konfirmo de konservo/ŝargo,Confirmación al guardar/cargar,,Tallennuksen/Latauksen vahvistus,Confirmation C/S,Mentés/betöltés megerősítése,Conferma Salvataggio/Caricamento,セーブ/ロード時に確認,스크립트로 스크린샷 생성 허용,Opslaan/Laad bevestiging,Bekreftelse for lagring/innlasting,Potwierdzenie zapisu/wczytania,Confirmação ao salvar/carregar,Confirmação ao gravar/carregar,Dialog de confirmare la Salvare/Încărcare,Подтверждение при сохранении/загрузке,Потврђивање током чувања/учитавања,Kaydet/Yükle onayı,Підтвердження при збереженні/завантаженні, -Disable keyboard cheats,MISCMNU_NOCHEATS,,,,Vypnout cheaty z klávesnice,Deaktivere snyderier med tastaturet,Tastatur-Cheats deaktivieren,,Malvalidigi klavarajn trompojn,Desactivar trucos por teclado,,Poista näppäinhuijaukset,,Billentyűs csalások letiltása,Disabilita i trucchi classici,キーボードからのチート無効,,Schakel cheats uit,Deaktiver tastaturjuks,Wyłącz Oszustwa z Klawiatury,Desativar trapaças de teclado,,Dezactivează codurile din tastatură,Отключить клавиатурные чит-коды,,Klavye hilelerini devre dışı bırak,Вимкнути клавіатурні чіт-коди, -Quicksave rotation,MISCMNU_QUICKSAVEROTATION,,,,Rotace rychle uložených her,Quicksave-rotation,Schnellspeicherrotation,,Rotacio de rapidkonservo,Rotación al hacer un guardado rápido,,Pikatallennuskierto,Rotation Sauvegardes Rapides,Gyorsmentés forgás,Rotazione del quicksave,クイックセーブ間隔,빠른 저장 간격,Rouleer snelopslag,Hurtiglagring-rotasjon,Rotacja szybkich zapisów,Rotação de salvamentos rápidos,Rotação de gravações rápidas,Rotație salvări automate,Менять ячейки для быстрых сохранений,Окретање брзих чувања,Hızlı kaydetme rotasyonu,Чергування слотів швидких збережень, -Number of quicksaves in rotation,MISCMNU_QUICKSAVECOUNT,,,,Počet rychle uložených her v rotaci,Antal quicksaves i rotation,Anzahl Schnellspeicherplätze,,Kvanto da rapidkonservoj en rotaciado,Cantidad de guardados rápidos en rotación,,Pikatallennusten määrä kierrossa,Nombre de sauvegardes en rotation,Gyorsmentések száma a forgásban,Numero di quicksave in rotazione,間隔クイックセーブの数,빠른 저장 간격의 수,Aantal roulerende snelopslagplekken,Antall hurtiglagringer i rotasjon,Ilość szybkich zapisów w rotacji,Número de salvamentos rápidos em rotação,Número de gravações rápidas em rotação,Număr salvări rapide în rotație,Кол-во ячеек для быстрых сохранений,Број брзих чувања у окретању,Rotasyondaki quicksave sayısı,Кількість слотів для швидких збережень, -Disable Menu Clean Scaling,MISCMNU_CLEANMENU,,,,Zakázat čisté škálování nabídek,Deaktivere Menu Clean Scaling,Gleichmäßige Menüskalierung deaktivieren,,Malebligi puran skaladon en la ĉefmenuo,El menú principal no ocupa toda la pantalla,,Poista käytöstä valikon siisti skaalautuminen,Ne pas utilisé mise à l'échelle menu propre,Menü Tisztaarányítás kikapcsolása,Disabilita il fattore di scala pulito del menu,メニュー画面を伸縮させない,,Schakel uniforme menuschaling uit,Deaktiver ren skalering av meny,Wyłącz Czyste Skalowanie Menu,Desativar escala limpa do menu,,Dezactivează Scara Nouă a Meniurilor,Отключить чистое масштабирование меню,,Menü Temiz Ölçeklendirmeyi Devre Dışı Bırak,Вимкнути чисте масштабування меню, -Pause game in background,MISCMNU_PAUSEINBACKGROUND,,,,Pozastavit hru na pozadí,Pause spil i baggrunden,Spiel pausieren wenn im Hintergrund,,Paŭzigi ludon fone,Pausar el juego en segundo plano,,Pysäytä peli taustalla,Mettre le jeu en pause en arrière-plan,Játék megállítása a háttérben,Pausa il gioco in background,バックグラウンド時に一時停止,백그라운드에서 게임 일시 중지,Pauzeer het spel op de achtergrond,Pauser spillet i bakgrunnen,Zapauzuj grę w tle,Pausar jogo ao minimizar,,Pauză dacă jocul este minimizat.,Пауза при сворачивании окна,Паузирајте игру у позадини,Oyunu arka planda duraklat,Пауза при згортуванні вікна, -Default Crosshair,HUDMNU_CROSSHAIR,,,,Výchozí zaměřovač,Standardtrådkorset,Standard-Fadenkreuz,,Defaŭlta reteto,Retícula por defecto,,Oletustähtäin,Viseur par défaut,Alap célkereszt,Mirino di default,デフォルトの照準,기본 조준점,Standaard dradenkruis,Standard trådkors,Domyślny celownik,Mira padrão,,Țintă implicită,Прицел по умолчанию,Уобичајени нишан,Varsayılan Nişangah,Типи прицілів, -Crosshair color,HUDMNU_CROSSHAIRCOLOR,,,Crosshair colour,Barva zaměřovače,Trådkors farve,Fadenkreuzfarbe,,Retetokoloro,Color de la retícula,,Tähtäimen väri,Couleur Viseur,Célkereszt színe,Colore mirino,照準色,조준점 색깔,Dradenkruis kleur,Farge på trådkors,Kolor celownika,Cor da mira,,Culoare țintă,Цвет прицела,Боја нишана,Nişangah rengi,Колір прицілу, -Crosshair shows health,HUDMNU_CROSSHAIRHEALTH,,,,Zaměřovač zobrazuje zdraví,Trådkors viser helbred,Fadenkreuz zeigt Gesundheit,,Reteto montras sanon,Mostrar salud en retícula,,Tähtäin näyttää terveyden,Couleur Viseur selon santé,Életerő jelzése a célkereszten,Il mirino mostra la salute,照準のヘルス表示,조준점과 체력 연동,Dradenkruis toont gezondheid,Trådkorset viser helse,Celownik pokazuje zdrowie,Exibir saúde na mira,Mostra vida na mira,Ținta afișează starea sănătății,Прицел отображает здоровье,Нишан приказује здравље,Artı işareti sağlığı gösterir,Колір прицілу за станом здоров'я, -Scale crosshair,HUDMNU_CROSSHAIRSCALE,,,,Velikost zaměřovače,Skalerer trådkorset,Fadenkreuz skalieren,,Skali reteton,Escalar retícula,,Skaalaa tähtäintä,Mise à l'échelle du viseur,Célkereszt mérete,Fattore di scala del mirino,照準サイズ,조준점 크기,Dradenkruis schalen,Skalere trådkors,Skala celownika,Redimensionar mira,,Dimensiune țintă,Размер прицела,Размера нишана,Ölçekli artı işareti,Розмір прицілу, -Standard,OPTVAL_YES_STANDARD,copied from elsewhere,,,Standardní,,,Πρότυπο,Norma,Estándar,,Normaali,,Alap,,標準,기본,Standaard,,Standard,Padrão,,,Стандартный,Стандардни,Standart,Стандартний, -Enhanced,OPTVAL_YES_ENHANCED,,,,Vylepšené,Forbedret,Verbessert,Ενισχυομένο,Bonigita,Mejorado,,Paranneltu,Amélioré,Fejlesztett,Migliorata,強調,고급,Verbeterd,Forbedret,Ulepszone,Melhorado,,Îmbunătățită,Улучшенный,Побољшани,Geliştirilmiş,Покращений, -Language,OPTMNU_LANGUAGE,,,,Jazyk,Sprog,Sprache,Γλώσσα,Lingvo,Idioma,,Kieli,Langage,Nyelv,Lingua,言語設定,언어,Taal,Språk,Język,Idioma,,Limbă,Язык,Језик,Dil,Мова, -,,Reverb editor,,,,,,,,,,,,,,,,,,,,,,,,,, -Undo Changes,TXT_UNDOCHANGES,,,,Zrušit změny,Fortryd ændringer,Rückgängig machen,Αναίρεση Αλλαγών,Malfari ŝanĝojn,Anular cambios,,Peruuttaa muutokset,Révoquer les changements,Változtatások Visszavonása,Revocare le modifiche,変更を戻す,변경 사항 취소,Wijzigingen ongedaan maken,Angre endringer,Cofnij Zmiany,Desfazer alterações,,Anulează Modificările,Отменить изменения,Поништи промене,Değişiklikleri Geri Al,Відмінити зміни, -Select Environment,REVMNU_SELECT,,,,Vybrat prostředí,Vælg miljø,Umgebung wählen,Επιλογή Περιβάλλοντος,Elekti medion,Seleccionar ambiente,,Valitse tila,Sélectionner un environnement,Környezet Kiválasztása,Seleziona ambiente,反響選択,환경 선택,Selecteer omgeving,Velg miljø,Wybierz Środowisko,Selecione o ambiente,,Alegere Mediu,Выбрать окружение,Изабери окружење,Ortam Seçiniz,Вибрати оточення, -Test Environment,REVMNU_TEST,,,,Testovat prostředí,Test miljø,Umgebung testen,Δοκιμαστκό Περιβάλλον,Provi medion,Probar ambiente,,Testaa tilaa,Tester un environnement,Környezet Tesztelése,Testa ambiente,反響テスト,환경 테스트,Test omgeving,Test miljø,Testuj Środowisko,Testar ambiente,,Testare Mediu,Тестировать окружение,Тестирај окружење,Test Ortamı,Тестувати оточення, -Edit Environment,REVMNU_EDIT,,,,Upravit prostředí,Rediger miljø,Umgebung editieren,Επεξεργασία Περιβάλλοντος,Modifi medion,Editar ambiente,,Muokkaa tilaa,Modifier un environnement,Környezet Szerkesztése,Modifica ambiente,反響編集,환경 편집,Omgeving bewerken,Rediger miljø,Edytuj Środowisko,Editar ambiente,,Editare Mediu,Редактировать окружение,Уреди окружење,Ortamı Düzenle,Редагувати оточення, -New Environment,REVMNU_NEW,,,,Nové prostředí,Nyt miljø,Neue Umgebung,Νέο Περιβάλλον,Nova medio,Nuevo ambiente,,Uusi tila,Nouveau environnement,Új Környezet,Nuovo ambiente,新規反響設定,새로운 환경 생성,Nieuwe omgeving,Nytt miljø,Nowe Środowisko,Novo ambiente,,Mediu Nou,Новое окружение,Ново окружење,Yeni Çevre,Нове оточення, -Revert settings,REVMNU_REVERT,,,,Obnovit nastavení,Tilbageføre indstillinger,Zurücksetzen,Επαναφορά Ρυθμίσεων,Malfari agordojn,Revertir configuración,,Palauta asetukset,Réinitialiser les paramètres,Változtatások elvetése,Ripristina le impostazioni,設定を戻す,설정 되돌리기,Instellingen terugzetten,Tilbake innstillinger,Przywróć ustawienia,Reverter configurações,,Revenire la setările precedente,Сбросить настройки,Врати подешавања,Ayarları geri döndür,Налаштування за замовчуванням, -Environment Size,REVMNU_ENVIRONMENT_SIZE,Please translate only if you know how to properly name this technical jargon!,,,,,,Μέγεθος Περιβάλλοντος,Mediamplekso,Tamaño de ambiente,,Tilan koko,Taille Environnement,,Dimensioni dell'ambiente,反響サイズ,공간 크기,,,Rozmiar Środowiska,Tamanho do ambiente,,,,,,, -Environment Diffusion,REVMNU_ENVIRONMENT_DIFFUSION,,,,,,,Διάχυση Περιβάλλοντος,Medidifuzo,Difusión de ambiente,,Tilan äänen hajautuminen,Diffusion Environnement,,Diffusione dell'ambiente,反響伝播,공간 잔향 확산,,,Dyfuzja Środowiska,Difusão do ambiente,,,,,,, -Room,REVMNU_ROOM,,,,,,,Δωμάτιο,Ĉambro,Sala,,Tilan keskitaajuudet,Salle,,,,룸 효과,,,Pokój,Sala,,,,,,, -Room HF,REVMNU_ROOM_HF,,,,,,,Δωμάτιο HF,Ĉambro (AF),Sala (Frecuencia alta),,Tilan korkeat taajuudet,HF Salle,,,,룸 효과 HF,,,Pokój (wysokie częstotliwości),Sala (alta frequência),,,,,,, -Room LF,REVMNU_ROOM_LF,,,,,,,Δωμάτιο LF,Ĉambro (MaF),Sala (Frecuencia baja),,Tilan matalat taajuudet,LF Salle,,,,룸 효과 LF,,,Pokój (niskie częstotliwości),Sala (baixa frequência),,,,,,, -Decay Time,REVMNU_DECAY_TIME,,,,,,,,Putriĝo-tempo,Tiempo de decadencia,,Häipymäaika,Temps Decay,,,,잔향 감쇠 시간,,,Czas Rozkładu,Tempo de decaimento,,,,,,, -Decay HF Ratio,REVMNU_DECAY_HF_RATIO,,,,,,,,Putriĝo-proporcio (AF),Ratio de decadencia (Frecuencia alta),,Korkeiden taajuuksien (HF) häipymissuhdeluku,,,,Decay HF比率,잔향 감쇠 HF 비율,,,Wskażnik Rozkładu dla wysokich częstotliwości,Taxa de decaimento (alta freq.),,,,,,, -Decay LF Ratio,REVMNU_DECAY_LF_RATIO,,,,,,,,Putriĝo-proporcio (MaF),Ratio de decadencia (Frecuencia baja),,Matalien taajuuksien (LF) häipymissuhdeluku,,,,Decay LF比率,잔향 감쇠 LF 비율,,,Wskaźnik Rozkładu dla niskich częstotliwości,Taxa de decaimento (baixa freq.),,,,,,, -Reflections,REVMNU_REFLECTIONS,,,,,,,Αντανακλάσεις,Reflektoj,Reflejos,,Ensiheijastukset,,,,,룸 반사,,,Obicia,Reflexos,,,,,,, -Reflections Delay,REVMNU_REFLECTIONS_DELAY,,,,,,,Καθυστέρηση Αντανακλάσεων,Prokrasto de reflektoj,Retraso de reflejos,,Ensiheijastusten viive,Délai Reflections,,,,룸 반사 딜레이 시간,,,Opóźnienie Odbić,Atraso de reflexos,,,,,,, -Reflections Pan X,REVMNU_REFLECTIONS_PAN_X,,,,,,,,Reflektoj alturnas tra X,Desplazamiento en X de reflejos,,Ensiheijastusten X-panorointi,Orientation Reflections X,,,Reflections X定位,X축 룸 반사,,,Odbicia Osi X,Deslocamento X de reflexos,,,,,,, -Reflections Pan Y,REVMNU_REFLECTIONS_PAN_Y,,,,,,,,Reflektoj alturnas tra Y,Desplazamiento en Y de reflejos,,Ensiheijastusten Y-panorointi,Orientation Reflections Y,,,Reflections Y定位,Y축 룸 반사,,,Odbicia Osi Y,Deslocamento Y de reflexos,,,,,,, -Reflections Pan Z,REVMNU_REFLECTIONS_PAN_Z,,,,,,,,Reflektoj alturnas tra Z,Desplazamiento en Z de reflejos,,Ensiheijastusten Z-panorointi,Orientation Reflections Z,,,Reflections Z定位,Z축 룸 반사,,,Odbicia Osi Z,Deslocamento Z de reflexos,,,,,,, -Reverb,REVMNU_REVERB,,,,,,,,Resono,Reverberación,,Jälkikaiunta,,,,,리버브,,,Pogłos,Reverberação,,,,,,, -Reverb Delay,REVMNU_REVERB_DELAY,,,,,,,,Prokrasto de resono,Retraso de reverberación,,Jälkikaiunnan viive,Délai Reverb,,,,리버브 지연,,,Opóźnienie Pogłosu,Atraso de reverberação,,,,,,, -Reverb Pan X,REVMNU_REVERB_PAN_X,,,,,,,,Resono alturnas tra X,Desplazamiento en X de reverberación,,Jälkikaiunnan X-panorointi,Orientation Reverb X,,,Reverb X定位,X축 리버브,,,Pogłos Osi X,Deslocamento X de reverberação,,,,,,, -Reverb Pan Y,REVMNU_REVERB_PAN_Y,,,,,,,,Resono alturnas tra Y,Desplazamiento en Y de reverberación,,Jälkikaiunnan Y-panorointi,Orientation Reverb Y,,,Reverb Y定位,Y축 리버브,,,Pogłos Osi Y,Deslocamento Y de reverberação,,,,,,, -Reverb Pan Z,REVMNU_REVERB_PAN_Z,,,,,,,,Resono alturnas tra Z,Desplazamiento en Z de reverberación,,Jälkikaiunnan Z-panorointi,Orientation Reverb Z,,,Reverb Z定位,Z축 리버브,,,Pogłos Osi Z,Deslocamento Z de reverberação,,,,,,, -Echo Time,REVMNU_ECHO_TIME,,,,,,,,Tempo de eĥo,Tiempo de eco,,Kaikuaika,Longueur écho,,,,에코 시간,,,Czas Echa,Tempo de eco,,,,,,, -Echo Depth,REVMNU_ECHO_DEPTH,,,,,,,,Produndo de eĥo,Profundidad de eco,,Kaiun syvyys,Profondeur écho,,,,에코 깊이,,,Głębokość Echa,Profundidade de eco,,,,,,, -Modulation Time,REVMNU_MODULATION_TIME,,,,,,,,Tempo de modulado,Tiempo de modulación,,Modulaatioaika,Longueur Modulation,,,,전조 시간,,,Czas Modulacji,Tempo de modulação,,,,,,, -Modulation Depth,REVMNU_MODULATION_DEPTH,,,,,,,,Produndo de modulado,Profundidad de modulación,,Modulaation syvyys,Profondeur Modulation,,,,전조 깊이,,,Głębokość Modulacji,Profundidade de modulação,,,,,,, -Air Absorption HF,REVMNU_AIR_ABSORPTION_HF,,,,,,,,Aer-absorbo AF,Absorción en aire de frecuencia alta,,Korkeiden taajuuksien (HF) ilma-absorptio,,,,,대기 흡수 HF,,,Absorbcja Powietrza (wysokie częstotliwości),Absorção de ar de alta freq.,,,,,,, -HF Reference,REVMNU_HF_REFERENCE,,,,,,,,AF referenco,Referencia de frecuencia alta,,Korkeiden taajuuksien vertausarvo,,,,HF参照値,HF 참조치,,,Odniesienie wysokich częstotliwości,Referência de alta freq.,,,,,,, -LF Reference,REVMNU_LF_REFERENCE,,,,,,,,MaF referenco,Referencia de frecuencia baja,,Matalien taajuuksien vertausarvo,,,,LF参照値,LF 참조치,,,Odniesienie niskich częstotliwości,Referência de baixa freq.,,,,,,, -Room Rolloff Factor,REVMNU_ROOM_ROLLOFF_FACTOR,,,,,,,,Ĉambro-Rolloff-faktoro,Factor de Roll-off de sala,,Tilan vaimenemiskerroin,Facteur de rolloff Salle,,,,룸 감쇠 양,,,Czynnik Zejścia,Fator de roll-off de sala,,,,,,, -Diffusion,REVMNU_DIFFUSION,,,,,,,,Difuzo,Difusión,,Diffuusio,,,,,잔향 확산,,,Dyfuzja,Difusão,,,,,,, -Density,REVMNU_DENSITY,,,,,,,,Denseco,Densidad,,Tiheys,Densité,,,密度,잔향 밀도,,,Zagęszczenie,Densidade,,,,,,, -Reflections Scale,REVMNU_Reflections_Scale,,,,,,,,Skalo de reflektoj,Escala de reflejos,,Ensiheijastusten skaala,Echelle Reflections,,,Reflections音階,룸 반사 음계,,,Rozmiar Odbić,Escala de reflexos,,,,,,, -Reflections Delay Scale,REVMNU_Reflections_Delay_Scale,,,,,,,,Prokrastskalo de reflektoj,Escala de retraso de reflejos,,Ensiheijastusten viiveen skaala,Délai d'échelle reflections,,,Reflections Delay音階,룸 반사 딜레이 음계,,,Skala Opóźnienia Odbić,Escala de atraso de reflexos,,,,,,, -Decay Time Scale,REVMNU_Decay_Time_Scale,,,,,,,,Tempskalo de purtiĝo,Escala de tiempo de decadencia,,Häipymäajan skaala,Echelle temporelle Decay,,,Decay Time音階,잔향 감쇠시간 음계,,,Skala Czasu Rozkładu,Escala de tempo de decaimento,,,,,,, -Decay HF Limit,REVMNU_Decay_HF_Limit,,,,,,,,AF-Limito de purtiĝo,Limite de decadencia de alta frecuencia,,Häipymän korkeiden taajuuksien raja-arvo,,,,Decay HF限度,잔향 감쇠 HF 한도,,,Limit Rozkładu Wysokich Częstotliwości,Limite de decaimento em alta freq.,,,,,,, -Reverb Scale,REVMNU_Reverb_Scale,,,,,,,,Skalo de resono,Escala de reverberación,,Jälkikaiunnan skaala,Echelle Reverb,,,Reverb音階,리버브 음계,,,Skala Pogłosu,Escala de reverberação,,,,,,, -Reverb Delay Scale,REVMNU_Reverb_Delay_Scale,,,,,,,,Prokrastskalo de resono,Escala de retraso de reverberación,,Jälkikaiunnan viiveen skaala,Délai d'échelle Reverb,,,Reverb Delay音階,리버브 딜레이 음계,,,Skala Opóźnienia Pogłosu,Escala de atraso de reverberação,,,,,,, -Echo Time Scale,REVMNU_Echo_Time_Scale,,,,,,,,Tempskalo de eĥo,Escala de tiempo de eco,,Kaikuajan skaala,Echelle temporelle Echo,,,Echo Time音階,에코 시간 음계,,,Skala Czasu Echa,Escala de tempo de eco,,,,,,, -Modulation Time Scale,REVMNU_Modulation_Time_Scale,,,,,,,,Tempskalo de modulado,Escala de tiempo de modulación,,Modulaatioajan skaala,Echelle temporelle Modulation,,,Modulation Time音階,전조 시간 음계,,,Skala Modulacji Czasu,Escala de tempo de modulação,,,,,,, -Based on,REVMNU_Based_on,,,,Založeno na,Baseret på,Basierend auf,Βασισμένο σε,Bazita de,Basado en,,Perustana,Basé sur,Minta,Basato su,音響の元,음향 원본,Gebaseerd op,Basert på,Bazowane na,Baseado em,,Bazat pe,Основано на,Засновано на,Buna göre,Засновано на, -Name,REVMNU_Name,,,,Název,Navn,,Όνομα,Nomo,Nombre,,Nimi,Nom,Név,Nome,名前,이름,Naam,Navn,Nazwa,Nome,,Nume,Название,Назив,İsim,Назва, -ID #1,REVMNU_ID_1,,,,,,,ID #1,Identigo #1,ID Nº1,,,,,ID N°1,,아이디 #1,,,ID #1,ID #1,,,ИД №1,,,, -ID #2,REVMNU_ID_2,,,,,,,ID #2,Identigo #2,ID Nº2,,,,,ID N°2,,아이디 #2,,,ID #2,ID #2,,,ИД №2,,,, -Create,REVMNU_Create,,,,Vytvořit,Opret,Erstellen,Δημιουργία,Krei,Crear,,Luo,Créer,Készítés,Creare,作成,생성,Aanmaken,Opprett,Stwórz,Criar,,Creare,Создать,Направи,Oluştur,Створити, -Save...,REVMNU_Save,,,,Uložit...,Gem...,Speichern...,Αποθήκευση,Konservi...,Guardar...,,Tallenna...,Sauvegarder...,Mentés...,Salvare...,セーブする...,저장 하기...,Opslaan...,Lagre...,Zapisz...,Salvar...,,Salvare...,Сохранить...,Сачувај...,Kaydet...,Зберегти..., -File name,REVMNU_File_name,,,,Název souboru,Filnavn,Dateiname,Όνομα αρχείου,Dosiernomo,Nombre de archivo,,Tiedostonimi,Nom de fichier,Fájlnév,Nome del file,ファイル名,파일 이름,Bestandsnaam,Filnavn,Nazwa pliku,Nome do arquivo,,Nume fișier,Имя файла,Назив фајла,Dosya adı,Назва файлу, -Environments to save,REVMNU_Environments_to_save,,,,Prostředí k uložení,"Miljøer, der skal gemmes",Zu speichernde Umgebungen,Περιβάλλοντα για αποθήκευση,Medioj por konservi,Ambientes para guardar,,Tallennettavat tilat,Environnements à sauvegarder,Mentendő Környezetek,Ambienti da salvare,音響を保存,저장할 공간,Omgevingen om op te slaan,Miljøer som skal lagres,Środowiska do zapisu,Ambientes para salvar,,Medii de salvat,Сохранить окружения...,Окружења за чување,Kurtarılacak ortamlar,Зберегти оточення..., -,,Vulkan,,,,,,,,,,,,,,,,,,,,,,,,,, -Vulkan Options (Experimental),DSPLYMNU_VKOPT,,,,Nastavení Vulkanu (Experimentální),Vulkan-indstillinger (eksperimentelt),Vulkan Optionen (Experimentell),Vulka Ρυθμίσεις (Πειραματικές),Agordoj por Vulkan (Eksperimenta),Opciones de Vulkan (Experimental),,Vulkan-asetukset (kokeellinen),Options Vulkan (Expérimental),Vulkan Beállítások (Kísérleti),Opzioni Vulkan (Sperimentale),Vulkan機能オプション(実験的),벌칸 설정(실험적),Vulkan-opties (Experimenteel),Vulkan Alternativer (Eksperimentell),Opcje Vulkan (Eksperymentalne),Opções de Vulkan (experimental),,Setări Mod Vulkan (În curs de testare),Настройки Vulkan (экспериментальные),Vulkan подешавања (експериментална),Vulkan Seçenekleri (Deneysel),Налаштування Vulkan (експериментальні), -Vulkan Options,VK_TITLE,,,,Nastavení Vulkanu,Vulkan-indstillinger,Vulkan Optionen,Vulkan Ρυθμίσεις,Agordoj por Vulkan,Opciones de Vulkan,,Vulkan-asetukset,Options Vulkan,Vulkan Beállítások,Opzioni Vulkan,Vulkan機能オプション,벌칸 설정,Vulkan-opties,Vulkan-alternativer,Opcje Vulkan,Opções de Vulkan,,Setări Mod Vulkan,Настройки Vulkan,Vulkan подешавања,Vulkan Seçenekleri,Налаштування Vulkan, -Enable Vulkan,VKMNU_ENABLE,,,,Povolit Vulkan,Aktiver Vulkan,Aktiviere Vulkan,Ενεργοποιηση του Vulkan,Ŝalti Vulkan,Activar Vulkan,,Ota käyttöön Vulkan,Activer Vulkan,Vulkan Engedélyezése,Abilita Vulkan,Vulkanを有効化,벌칸 렌더러 사용,Vulkan inschakelen,Aktiver Vulkan,Włącz Vulkan,Ativar Vulkan,,Activează modul video Vulkan,Использовать Vulkan,Омогући Vulkan,Vulkan'ı Etkinleştir,Увімкнути Vulkan, -Vulkan Device ID,VKMNU_DEVICE,,,,ID zařízení Vulkanu,Vulkan-enheds-id,Vulkan Geräte ID,Vulkan ID Συσκευής,Identigo de Vulkan-aparato,ID de dispositivo Vulkan,,Vulkan-laitetunniste,ID du périphérique Vulkan,Vulkan Eszköz ID,Dispositivo ID Vulkan,Vulkanデバイス ID,벌칸 장치 아이디,Vulkan apparaat-ID,Vulkan Enhets-ID,ID urządzenia Vulkan,ID do dispositivo Vulkan,,ID Dispozitiv Vulkan,ИД устройства Vulkan,Vulkan ID уређаја,Vulkan Cihaz Kimliği,ID пристрою Vulkan, -High Dynamic Range,VKMNU_HDR,,,,Vysoký dynamický rozsah (HDR),Høj dynamisk rækkevidde,,Υψηλό Δυναμική Εμβέλεια,Alta dinamika intervalo,Alto rango dinámico,,Korkea dynamiikka-alue (HDR),,,,ハイダイナミックレンジ,하이 다이나믹 레인지,Hoog dynamisch bereik,Høyt dynamisk område,Obraz HDR,Alto alcance dinâmico (HDR),,HDR,Расширенный динамический диапазон (HDR),HDR,Yüksek Dinamik Aralık,HDR, -Warning: The Vulkan renderer is highly experimental!,VK_WARNING,,,,Varování: Vulkan renderer je velmi experimentální!,Advarsel: Vulkan-rendereren er meget eksperimentel!,Achtung: Der Vulkan Renderer ist noch sehr experimentell!,Προειδοποίηση: Ο Vulkan renderer είναι υψηλά πειραματικός!,Averto: La bildigilo de Vulkan estas alte eksperimenta!,Advertencia: ¡El renderizado por Vulkan es altamente experimental!,,Varoitus: Vulkan-hahmonnin on hyvin kokeellinen!,Attention: Le moteur de rendu Vulkan est très expérimental!,Vigyázat: A Vulkan renderer még teljesen kísérleti!,Attenzione: il motore grafico Vulkan è altamente sperimentale!,警告:Vulkanレンダラーは実験段階です!,경고: 벌칸 렌더러는 매우 실험적입니다!,Waarschuwing: De Vulkan renderer is zeer experimenteel!,Advarsel: Vulkan-rendereren er svært eksperimentell!,Uwaga: Renderer Vulkan jest bardzo eksperymentalny!,Atenção: o renderizador Vulkan é altamente experimental!,,Atenție: Modul Vulkan este încă în curs de testare!,Внимание: рендерер Vulkan в стадии тестирования!,УПОЗОРЕЊЕ: Vulkan рендерер је врло експерименталан!,Uyarı: Vulkan işleyici son derece deneyseldir!,Увага: рендер Vulkan на стадії тестування!, -These options will require a restart to take effect.,VK_RESTART,,,,Tato nastavení vyžadují restart hry.,Disse indstillinger kræver en genstart for at få effekt.,Diese Option erfordert einen Neustart!,Αυτές η ρυθμίσεις θα χρειαστούνε επανεκκίνηση για να ισχύσουν,Ĉi tiuj agordoj bezonos relanĉon por efikiĝi.,Estas opciones requieren reiniciar para tener efecto.,,Nämä asetukset vaativat uudelleenkäynnistyksen astuakseen voimaan.,Ces options nécessitent un redémarrage.,Ezen beállítások életbelépéséhez újraindítás szükséges.,Queste opzioni richiedono il riavvio per avere effetto.,これらのオプションを有効にするには再起動が必要です。,이 설정을 적용하려면 게임을 재시작해야 합니다.,Deze opties vereisen een herstart om van kracht te worden.,Disse alternativene krever en omstart for å tre i kraft.,"Te opcje będą wymagały ponownego włączenia, aby miały efekt.",É necessário reiniciar para que essas configurações surtam efeito.,É necessário reiniciar para estas configurações fazerem efeito.,Aceste setări necesită o repornire pentru a putea fi aplicate,Для применения этих изменений требуется перезапуск игры.,Морате поново покренути GZDoom да би промене ступиле на снагу.,Bu seçeneklerin etkili olması için yeniden başlatılması gerekecektir.,Для застосування змін протрібно перезапустити гру., -Select Vulkan Device,VKMNU_DEVICESELECT,This is not yet implemented - but it is planned,,,Vybrat zařízení Vulkanu,Vælg Vulkan-enhed,Vulkan Gerät auswählen,Επιλογή Vulkan Συσκευής,Elekti Vulkan-aparaton,Seleccionar dispositivo Vulkan,,Valitse Vulkan-laite,Sélectionner périphérique Vulkan,Vulkan eszköz kiválasztása,Seleziona il Dispositivo Vulkan,Vulkanデバイスの選択,벌칸 장치를 고르시오,Selecteer Vulkan Apparaat,Velg Vulkan-enhet,Wybierz Urządzenie Vulkan,Selecione o dispositivo Vulkan,,Selectare Dispozitiv Vulkan,Выбрать устройство Vulkan,Изаберите Vulkan уређај,Vulkan Aygıtını Seçin,Виберіть пристрій Vulkan, -,,Texture scaling,,,,,,,,,,,,,,,,,,,,,,,,,, -ScaleNx,OPTVAL_SCALENX,,,,,,,,,,,,,,,,,,,,,,,,,,, -NormalNx,OPTVAL_NORMALNX,,,,,,,,,,,,,,,,,,,,,,,,,,, -hqNx,OPTVAL_HQNX,,,,,,,,,,,,,,,,,,,,,,,,,,, -hqNx MMX,OPTVAL_HQNXMMX,,,,,,,,,,,,,,,,,,,,,,,,,,, -xBRZ,OPTVAL_NXBRZ,,,,,,,,,,,,,,,,,,,,,,,,,,, -Old xBRZ,OPTVAL_OLD_NXBRZ,,,,xBRZ (starší),Gamle xBRZ,xBRZ alt,Παλίο xBRZ,Malnova xBRZ,Antiguo xBRZ,,Vanha xBRZ,Ancien xBRZ,Régi xBRZ,Vecchio xBRZ,旧xBRZ,구형 xBRZ,Oud xBRZ,Gammel xBRZ,Stare xBRZ,Antigo xBRZ,,Vechiul xBRZ,Старый xBRZ,Стари xBRZ,Eski xBRZ,Старий xBRZ, -,,Option Search,,,,,,,,,,,,,,,,,,,,,,,,,, -Option Search,OS_TITLE,,,,Vyhledávání možností,Mulighed Søgning,Optionssuche,Αναζήτηση Ρυθμίσεων,Serĉi agordojn,Buscar opciones,,Asetushaku,Recherche Option,Beállítások keresése,Opzioni di ricerca,オプション検索,옵션 검색,Optie zoeken,Alternativt søk,Szukanie Opcji,Buscar opção,Procurar opção,Căutare Setări,Поиск настройки,Претрага,Seçenek Arama,Пошук налаштування, -Search for any term,OS_ANY,,,,Hledat jakékoli klíčové slovo,Søg efter et vilkårligt begreb,Suche nach beliebigem Begriff,Αναζήτηση για όποιαδηποτε λέξη,Serĉi por iu ajn termino,Buscar cualquier término,,Etsi mitä tahansa sanaa,N'importe quel mot,Keresés bármely kifejezésre,Cerca per ciascun termine,いずれかの用語を探す,용어 검색,Zoek naar eender welke term,Søk etter en hvilken som helst term,Szukaj jakiegokolwiek wyrażenia,Buscar por qualquer termo,Procurar por um termo qualquer,Căutare după orice termen,Искать любое из слов,Тражи било који термин,Herhangi bir terim için arama yapın,Шукати будь яке з слів, -Search for all terms,OS_ALL,,,,Hledat všechna klíčová slova,Søg efter alle udtryk,Suche nach allen Begriffen,Αναζήτηση για όλες της λέξεις,Serĉi por ĉiuj terminoj,Buscar todos los términos,,Etsi kaikki sanat,Tous les mots,Keresés minden kifejezésre,Cerca per tutti i termini,全ての用語を探す,모든 조건 검색,Zoek naar alle termen,Søk etter alle termer,Szukaj wszystkich wyrażeń,Buscar por todos os termos,Procurar por todos os termos,Căutare după toți termenii,Искать все слова,Тражи сваки термин,Tüm terimler için arama yapın,Шукати всі слова, -No results found.,OS_NO_RESULTS,,,,Nic nenalezeno.,Ingen resultater fundet.,Keine Resultate,Δέν βρέθηκαν αποτελέσματα,Neniu trafo.,Ningún resultado.,,Ei tuloksia.,Pas de résultat trouvé,Nincs találat,Nessun risultato trovato.,見つかりませんでした。,검색 결과 없음.,Geen resultaten gevonden.,Ingen resultater funnet.,Brak wyników,Nenhum resultado encontrado.,,Niciun rezultat găsit.,Результаты не найдены.,Нема резултата.,Sonuç bulunamadı.,Нічого не знайдено., -Search:,OS_LABEL,,,,Hledat:,Søg:,Suche:,Αναζήτηση:,Serĉi:,Buscar:,,Etsi:,Recherche:,Keresés:,Trova:,検索:,검색:,Zoeken:,Søk:,Szukaj:,Busca:,Procura:,Caută:,Поиск:,Претрага:,Ara:,Пошук:, -,,Blood Bath Announcer,,,,,,,,,,,,,,,,,,,,,,,,,, -%k boned %o like a fish,TXT_OBITUARY1,,,,%o byl@[ao_cs] vykoštěn@[ao_cs] jako ryba hráčem %k,%k udbenede %o som en fisk,%k hat %o zerlegt wie einen Fisch,Ο/Η %k ξεκοκάλοσε @[pro2_gr] %o σα ψάρι,%k senostigis %o kiel fiŝon,%k ha deshuesado a %o como a un pescado,%k deshuesó a %o como a un pescado,%k perkasi %o paran kuin kalan,%k a désossé %o comme un poisson,%k kifilézte %o -t mint a halat,%k ha dissossato %o come un pesce,%k は %o の骨を魚のように引っこ抜いた。,%k 은(는) %o 의 뼈를 발랐다.,%k mergelde %o als een vis,%k utbeinet %o som en fisk,%k odfiletował@[ao_pl] %o jak rybę,%k desossou %o como um peixe,,%k l-a dezosat pe %o ca pe un pește,%k пересчитал косточки игрока %o,%k је очистио %o као рибу,"%o, %k tarafından balık gibi kemirildi.",%k порахував ребра %o, -%k castrated %o,TXT_OBITUARY2,,,,%o byl@[ao_cs] vykastrován@[ao_cs] hráčem %k,%k kastrerede %o,%k hat %o kastriert,Ο/Η %k ευνούχισε %o,%k kastris %o,%k ha castrado a %o,%k castró a %o,%k kastroi %o paran,%k a castré %o,%k kasztrálta %o -t,%k ha castrato %o,%k は %o を去勢した。,%k 은(는) %o 을(를) 거세시켰다.,%k castreerde %o,%k kastrert %o,%k wykastrował@[ao_pl] %o,%k castrou %o,,%k l-a castrat pe %o,%k кастрировал игрока %o,%k је кастрирао %o,"%o, %k tarafından hadım edildi.",%k кастрував %o, -%k creamed %o,TXT_OBITUARY3,,,,%o byl@[ao_cs] rozšlehán@[ao_cs] hráčem %k,%k smurte %o,%k hat %o eingeseift,Ο/Η %k κρέμασε @[pro2_gr] %o,%k kremigis %o,%k ha cremado a %o,%k cremó a %o,%k kermasi %o paran,%k a battu %o à plate couture ,%k elkente %o -t,%k ha cremato %o,%k は %o に反吐ブチ撒けさせた。,%k 은(는) %o 을(를) 양념시켰다.,%k pureerde %o,%k fløtet %o,%k spienił@[ao_pl] %o,%k fez creme de %o,,%k l-a transformat în cremă pe %o,%k взбил игрока %o,%k је истукао %o,,%k розпушив %o, -%k decimated %o,TXT_OBITUARY4,,,,%o byl@[ao_cs] zdecimován@[ao_cs] hráčem %k,%k decimerede %o,%k hat %o dezimiert,Ο/Η %k αποδεκάτισε @[pro2_gr] %o,%k detruegis %o,%k ha diezmado a %o,%k diezmó a %o,%k hävitti %o paran,%k a décimé %o,%k megtizedelte %o -t,%k ha decimato %o,%k は %o の居場所を間引いた。,%k 은(는) %o 을(를) 망가뜨렸다.,%k decimeerde %o,%k desimert %o,%k przetrzebił@[ao_pl] %o,%k decimou %o,,%k l-a decimat pe %o,%k скосил игрока %o,%k је десетковао %o,"%o, %k tarafından yok edildi.",%k зітнув %o, -%k destroyed %o,TXT_OBITUARY5,,,,%o byl@[ao_cs] zničen@[ao_cs] hráčem %k,%k ødelagde %o,%k hat %o zerstört,Ο/Η %k κατέστεψε @[pro2_gr] %o,%k detruis %o,%k ha destruido a %o,%k destruyó a %o,%k tuhosi %o paran,%k a détruit %o,%k elpusztította %o -t,%k ha distrutto %o,%k は %o を完全に破壊した。,%k 은(는) %o 을(를) 파괴했다.,%k vernietigde %o,%k destruert %o,%k zniszczył@[ao_pl] %o,%k destruiu %o,,%k l-a distrus pe %o,%k уничтожил игрока %o,%k је уништио %o,,%k знищив %o, -%k diced %o,TXT_OBITUARY6,,,,%o byl@[ao_cs] nakrájen@[ao_cs] na kostičky hráčem %k,%k skar %o i tern,%k hat %o in Würfel zerteilt,Ο/Η %k τεμάχησε @[pro2_gr] %o,%k diskubigis %o,%k ha picado en cubitos a %o,%k picó en cubitos a %o,%k pilkkosi %o paran,%k a coupé en dés %o,%k kockára vágta %o -t,%k ha tagliato a cubetti %o,%k は %o を賽の目に切った。,%k 은(는) %o 을(를) 잘게 잘게 썰었다.,%k sneed %o in stukjes,%k skåret %o i terninger,%k pokroił@[ao_pl] w kostkę %o,%k fez picadinho de %o,%k cortou %o,%k l-a feliat pe %o,%k разрезал игрока %o,%k је исецкао %o,"%o, %k tarafından doğrandı.",%k нарізав %o, -%k disembowled %o,TXT_OBITUARY7,,,,%o byl@[ao_cs] vykuchán@[ao_cs] hráčem %k,%k udkløvede %o,%k hat %o ausgeweidet,Ο/Η %k ισοπέδοσε @[pro2_gr] %o,%k sentripigis %o,%k ha destripado a %o,%k destripó a %o,%k suolisti %o paran,%k a étripé %o,%k kibelezte %o -t,%k ha smembrato %o,%k は %o の臓物を引きずり出した。,%k 은(는) %o 의 내장을 도려냈다.,%k ontleedde %o,%k sprettet opp %o,%k wypatroszył@[ao_pl] %o,%k estripou %o,,%k l-a eviscerat pe %o,%k выпотрошил игрока %o,%k је ампутирао %o,,%k випотрошив %o, -%k flattened %o,TXT_OBITUARY8,,,,%o byl@[ao_cs] zplacatěn@[ao_cs] hráčem %k,%k smadrede %o,%k hat %o dem Erdboden gleichgemacht,Ο/Η %k ησοπέδοσε @[pro2_gr] %o,%k platigis %o,%k ha aplanado a %o,%k aplanó a %o,%k lyttäsi %o paran,%k a aplati %o,%k kilapította %o -t,%k ha schiacciato %o,%k は %o をぶっ潰した。,%k 은(는) %o 의 코를 납작하게 만들었다.,%k plette %o,%k flatet ut %o,%k rozpłaszczył@[ao_pl] %o,%k achatou %o,%k espalmou %o,%k l-a făcut plat pe %o,%k сплюснул игрока %o,%k је изравнао %o,"%o, %k tarafından dümdüz edildi.",%k сплющив %o, -%k gave %o Anal Justice,TXT_OBITUARY9,,,,%o utržil@[ao_cs] anální spravedlnost od hráče %k,%k lemlæstede %o,%k hat %o anale Gerechtigkeit gegeben,Ο/Η %k γάμησε @[pro2_gr] %o @[pro3_gr] κόλο,%k donis pugan juston al %o,%k le ha dado justicia anal a %o,%k le dió justicia anal a %o,%k jakoi %o paralle anaalioikeutta,%k a rendu une justice anale a %o,%k Anális Igazságot adott %o -nak ,%k ha dato a %o Giustizia Anale,%k は %o のケツにぶち込んだ。,%k 은(는) %o 에게 홍콩행을 보냈다.,%k gaf %o anale rechtvaardigheid,%k ga %o anal rettferdighet,%k dał@[ao_pl] %o Analną Sprawiedliwość,%k deu Justiça Anal para %o,,%k i-a făcut jucătorului %o o Justiție Anală,%k устроил анальное правосудие игроку %o,%k је дао %o аналну правду,"%o, %k tarafından dümdüz edildi.",%k влаштував анальне правосуддя %o, -%k gave AnAl MaDnEsS to %o,TXT_OBITUARY10,,,,%o utrpěl@[ao_cs] AnÁlNí ŠíLeNsTvÍ od hráče %k,%k spildte %o,%k gab %o AnAlEn WaHnSiNn,Ο/Η %k έσκισε τον κόλο του/της] %o,%k donis pUgAn frEnEzOn al %o,%k le ha dado LoCuRa AnAl a %o,%k le dió LoCuRa AnAl a %o,%k teki %o paran AnAaLiHuLlUkSi,%k a donné la FOLIE ANALE a %o,%k SeGgBe KüLDtE %o -t,%k ha dato FoLlIa AnAle a %o,%k は %o のケツをガバガバにした。,%o 은(는) %k 의 찰진 맛을 보았다.,%k gaf aNaLe DoLhEiD aan %o,%k ga %o anal rettferdighet,%k dał@[ao_pl] %o AnAlNe SzAlEńStWo ,%k deu LoUcUrA aNaL para %o,,%k i-a dat NeBuNiE AnAlĂ jucătorului %o,%k устроил АнАЛ КаРнаВаЛ игроку %o,%k је дао АнАлНо ЛуДиЛо %o,"%o, %k tarafından dümdüz edildi.",%k влаштував АнАЛ ГуЛяНнЯ %o, -%k killed %o,TXT_OBITUARY11,,,,%o byl@[ao_cs] zabit@[ao_cs] hráčem %k,%k dræbte %o,%k hat %o getötet,Ο/Η %k σκότωσε @[pro2_gr] %o,%k mortigis %o,%k ha matado a %o,%k mató a %o,%k tappoi %o paran,%k a tué %o,%k kicsinálta %o -t,%k ha ucciso %o,%k は %o をブッ殺した。,%k 은(는) %o 을(를) 죽였다.,%k doodde %o,%k drepte %o,%k zabił@[ao_pl] %o,%k matou %o,,%k l-a omorât pe %o,%k убил игрока %o,%k је убио %o,"%o, %k tarafından öldürüldü.",%k вбив %o, -%k made mincemeat out of %o,TXT_OBITUARY12,,,,%o byl@[ao_cs] namelen@[ao_cs] hráčem %k,%k gjorde hakket kød af %o,%k hat %o zu Hackfleisch verarbeitet,Ο/Η %k έφτιαξε κυμά με @[pro2_gr] %o,%k farigis farĉon el %o,%k ha hecho picadillo de %o,%k hizo picadillo de %o,%k teki jauhelihaa %o parasta,%k a fait de la viande hachée de %o,%k ledarálta %o -t,%k ha triturato %o,%k は %o をミンチにした。,%o 은(는) %k 에 의해 분쇄됐다.,%k maakte gehakt van %o,%k laget kjøttdeig av %o,%k zrobił@[ao_pl] mięso mielone z %o,%k fez carne moída de %o,%k fez carne picada do %o,%k a facut tocătură din %o,%k сделал отбивную из игрока %o,%k је направио млевено месо од %o,"%o, %k tarafından kıyma haline getirildi.",%k зробив відбивну з %o, -%k massacred %o,TXT_OBITUARY13,,,,%o byl@[ao_cs] zmasakrován@[ao_cs] hráčem %k,%k massakrerede %o,%k hat %o niedergemetzelt,Ο/Η %k δολοφώνησε @[pro2_gr] %o,%k masakris %o,%k ha masacrado a %o,%k masacró a %o,%k verilöylytti %o parkaa,%k a massacré %o,%k lemészárolta %o -t,%k ha fatto di %o carne tritata,%k は %o を虐殺した。,%k 은(는) %o 을(를) 참살했다.,%k slachtte %o af,%k massakrerte %o,%k zmasakrował@[ao_pl] %o,%k massacrou %o,,%k a fost masacrat de către %o,%k устроил бойню игроку %o,%k је масакрирао %o,"%o, %k tarafından katledildi",%k влаштував для %o бійню, -%k mutilated %o,TXT_OBITUARY14,,,,%o byl@[ao_cs] zmrzačen@[ao_cs] hráčem %k,%k lemlæstede %o,%k hat %o verstümmelt,Ο/Η %k ακρωτηριάσε @[pro2_gr] %o,%k mutilis %o,%k ha mutilado a %o,%k mutiló a %o,%k silpoi %o paran,%k a mutilé %o,%k megcsonkította %o -t,%k ha massacrato %o,%k は %o をバラバラ死体にした。,%k 은(는) %o 의 팔다리를 절단했다.,%k verminkte %o,%k lemlestet %o,%k rozszarpał@[ao_pl] %o,%k mutilou %o,,%k l-a mutilat pe %o,%k изуродовал игрока %o,%k је мутилирао %o,"%o, %k tarafından sakat bırakıldı.",%k знівечив %o, -%k reamed %o,TXT_OBITUARY15,,,,%o byl@[ao_cs] proděravěn@[ao_cs] hráčem %k,%k skændede %o,%k hat %o aufgerieben,Ο/Η %k δέσμισε @[pro2_gr] %o,%k alezis %o,%k ha escariado a %o,%k escarió a %o,%k porasi %o paran,%k a découpé en fines lamelles %o,%k seggbe rakta %o -t,%k ha squartato %o,%k は %o の穴を大きく広げた。,%k 은(는) %o 을(를) 크게 혼냈다.,%k holde %o uit,%k maltraktert %o,%k rozwiercił@[ao_pl] %o,%k esquartejou %o,,%k l-a transformat într-un top de hârtie pe %o,%k рассверлил игрока %o,%k је наоружао %o,"%o, %k tarafından öldürüldü.",%k просверлив %o, -%k ripped %o a new orifice,TXT_OBITUARY16,,,,%o má novou díru od hráče %k,%k flåede %o en ny åbning,%k hat %o eine neue Körperöffnung verpasst,Ο/Η άνοιξε μια νέα τρύπα @[pro3_gr] %o,%k ŝiris novan truon en %o,%k le ha hecho a %o un nuevo orificio,%k le hizo a %o un nuevo orificio,%k repi %o paralle uuden aukon,%k a ouvert un nouvel orifice a %o,%k új szájat csinált %o -nak,%k ha aperto a %o un altro orifizio,%k は %o を切り裂いて新しい穴を作ってあげた。,%k 은(는) %o 을(를) 죽여 뜯어서 작품을 만들었다.,%k scheurde een opening uit %o,%k revet %o en ny kroppsåpning,%k rozerwał@[ao_pl] %o nowy otwór,%k abriu um novo orifício em %o,,%k i-a făcut jucătorului %o un nou orificiu,%k проделал новое отверстие в игроке %o,%k је исцепао %o нови отвор,"%o, %k tarafından yeni bir delik açıldı.",%k зробив в %o нову дірку, -%k slaughtered %o,TXT_OBITUARY17,,,,%o byl@[ao_cs] zavražděn@[ao_cs] hráčem %k,%k slagtede %o,%k hat %o geschlachtet,Ο/Η %k έσφαξε @[pro2_gr] %o,%k buĉis %o,%k ha sacrificado a %o,%k sacrificó a %o,%k teurasti %o paran,%k a meurtri %o,%k lemészárolta %o -t,%k ha macellato %o,%k は %o を屠殺した。,%o 은(는) %k 에 의해 도살당했다.,%k slachtte %o,%k slaktet %o,%k zarżn@[irreg_2_pl] %o,%k abateu %o,,%k l-a măcelărit pe %o,%k устроил резню игроку %o,%k је заклао %o,"%o, %k tarafından katledildi.",%k провів різню %o, -%k smashed %o,TXT_OBITUARY18,,,,%o byl@[ao_cs] zmlácen@[ao_cs] hráčem %k,%k smadrede %o,%k hat %o zerklatscht,Ο/Η %k τσάκισε @[pro2_gr] %o,%k frakasis %o,%k ha destrozado a %o,%k destrozó a %o,%k murskasi %o paran,%k a enfoncé %o,%k földbe döngölte %o -t,%k ha distrutto %o,%k は %o をぶっ飛ばした。,%k 은(는) %o 을(를) 내팽개쳤다.,%k vermorzelde %o,%k knust %o,%k stłukł@[ao_pl] %o,%k esmagou %o,,%k l-a spart pe %o,%k размазал игрока %o,%k је поломио %o,"%o, %k tarafından ezildi.",%k розмазав %o, -%k sodomized %o,TXT_OBITUARY19,,,,Hráč %k se dopustil sodomie na hráči %o,%k sodomiserede %o,%k hat %o sodomisiert,Ο/Η %k γάμησε @[pro2_gr] %o,%k sodomizis %o,%k ha sodomizado a %o,%k sodomizó a %o,%k anaaliraiskasi %o paran,%k y a sodomisé n %o,%k szodomizálta %o -t,%k ha sodomizzato %o,%o は %k にカマを掘られた。 ,%o 은(는) %k 을(를) 위해 등을 보였다.,%k sodomiseerde %o,%k sodomisert %o,%k spenetrował@[ao_pl] %o,%k sodomizou %o,,%k l-a sodomizat pe %o,%k содомировал игрока %o,%k је изјебао %o,"%o, %k tarafından sodomize edildi.",%k зґвалтував %o, -%k splattered %o,TXT_OBITUARY20,,,,%o byl@[ao_cs] rozplesknut@[ao_cs] hráčem %k,%k sprøjtede %o,%k hat %o zerspritzt,Ο/Η %k έσκασε @[pro2_gr] %o,%k disĵetis %o,%k ha rociado a %o,%k roció a %o,%k roiski %o paran yltympäri,%k a explosé de %o,%k szétloccsantotta %o -t,%k ha spiaccicato %o,%k は %o にばら撒かれた。,%k 은(는) %o 을(를) 박살냈다.,%k splette %o,%k sprutet %o,%k rozbryzgał@[ao_pl] %o,%k explodiu %o,,%k l-a împrăștiat pe %o,%k разбрызгал игрока %o,%k је спљоштио %o,"%o, %k tarafından parçalandı.",%k розбризкав %o, -%k squashed %o,TXT_OBITUARY21,,,,%o byl@[ao_cs] rozmáčknut@[ao_cs] hráčem %k,%k kværnede %o,%k hat %o zerquetscht,Ο/Η %k πάτησε @[pro2_gr] %o,%k premplatigis %o,%k ha aplastado a %o,%k aplastó a %o,%k litisti %o paran,%k a écrabouillé %o,%k eltaposta %o -t,%k ha schiacciato %o,%k は %o に潰された。,%k 은(는) %o 을(를) 짓이겼다.,%k plette %o,%k knust %o,%k zmiażdżył@[ao_pl] %o,%k espatifou %o,,%k l-a strivit pe %o,%k расплющил игрока %o,%k је згњечио %o,"%o, %k tarafından ezildi.",%k розчавив %o, +",Tmavě šedá,Mørkegrå,Dunkelgrau,Σκοτεινό γρκί,Malhelgriza,Gris oscuro,,Tummanharmaa,Gris sombre,Sötétszürke,Grigio scuro,鉛,치색,Donkergrijs,Mørkegrå,Ciemnoszary,Cinza escuro,,Gri închis,Тёмно-серый,Тамно сива,Mörkgrått,Koyu gri,Темно-сірий, +Dark Green,TXT_COLOR_DARKGREEN,,,,Tmavě zelená,Mørkegrøn,Dunkelgrün,Σκοτεινό πράσινο,Malhelverda,Verde oscuro,,Tummanvihreä,Vert sombre,Sötétzöld,Verde scuro,深,흑녹색,Donkergroen,Mørkegrønn,Ciemnozielony,Verde escuro,,Verde închis,Тёмно-зелёный,Тамна зелена,Mörkgrön,Koyu Yeşil,Темно-зелений, +Brown,TXT_COLOR_BROWN,,,,Hnědá,Brun,Braun,Σκούρο,Bruna,Marrón,,Ruskea,Brun,Barna,Marrone,茶,갈색,Bruin,Brun,Brązowy,Marrom,,Maro,Коричневый,Браон,Brun,Kahverengi,Коричневий, +Dark Blue,TXT_COLOR_DARKBLUE,,,,Tmavě modrá,Mørk blå,Dunkelblau,Σκοτεινό μπλέ,Malhelblua,Azul oscuro,,Tummansininen,Bleu sombre,Sötétkék,Blu scuro,紺,,Donkerblauw,Mørkeblå,Ciemnoniebieski,Azul escuro,,Albastru închis,Тёмно-синий,Тамна Плава,Mörkblå,Koyu Mavi,Темно-синій, +Light Red,TXT_COLOR_LIGHTRED,,,,Světle červená,Lysrød,Hellrot,Ανοιχτό κόκκινο,Helruĝa,Rojo claro,,Vaaleanpunainen,Rouge clair,Világospiros,Rosso chiaro,丹,옅은 적색,Licht Rood,Lys rød,Jasnoczerwony,Vermelho claro,,Roșu deschis,Светло-красный,Светло црвена,Ljusröd,Açık Kırmızı,Світло-червоний, +Yellow,TXT_COLOR_YELLOW,,,,Žlutá,Gul,Gelb,Κίτρινο,Flava,Amarillo,,Keltainen,Jaune,Sárga,Giallo,黄,노란색,Geel,Gul,Żółty,Amarelo,,Galben,Жёлтый,Жута,Gul,Sarı,Жовтий, +Purple,TXT_COLOR_PURPLE,,,,Fialová,Lilla,Violett,Μόβ,Purpura,Morado,,Purppura,Violet,Lila,Viola,紫,보라색,Paars,Lilla,Fioletowy,Roxo,,Mov,Фиолетовый,Љубичаста,Lila,Mor,Фіолетовий, +Olive,TXT_COLOR_DULLGREEN,,,,Bledě zelená,Oliven,Blassgrün,,Olivkolora,Oliva,,Haaleanvihreä,Vert pâle,Olíva,Verde pallido,苔,암녹색,Saaie groen,Oliven,Matowa Zieleń,Verde oliva,,Măsliniu,Мутно-зелёный,Тупа зелена,Oliv,Zeytin,Темний жовто-зелений, +Beige,TXT_COLOR_BEIGE,,,,Béžová,Beige,,Μπέζ,Flavgriza,Beis,Beige,Beesi,,Bézs,,淡,담갈색,Beige,Beige,Beżowy,Bege,,Bej,Бежевый,Беж,Beige,Bej,Бежевий, +Light Green,TXT_COLOR_LIGHTGREEN,,,,Světle zelená,Lysegrøn,Hellgrün,Ανοιχτό Πράσινο,Helverda,Verde claro,,Vaaleanvihreä,Vert clair,Világoszöld,Verde chiaro,葵,옅은 녹색,Licht groen,Lysegrønn,Jasonzielony,Verde claro,,Verde Deschis,Светло-зелёный,Светло зелена,Ljusgrön,Açık Yeşil,Світло-зелений, +Light Blue,TXT_COLOR_LIGHTBLUE,,,,Světle modrá,Lys blå,Hellblau,Γαλάζιο,Helblua,Azul claro,,Vaaleansininen,Bleu clair,Világoskék,Blu chiaro,空,옅은 청색,Licht blauw,Lyseblå,Jasnoniebieski,Azul claro,,Albastru Deschis,Светло-синий,Светло плава,Ljusblå,Açık Mavi,Світло-синій, +Light Gray,TXT_COLOR_LIGHTGRAY,,,Light Grey,Světle šedá,Lysegrå,Hellgrau,Ανοιχτό Γκρι,Helgriza,Gris claro,,Vaaleanharmaa,Gris clair,Világosszürke,Grigio chiaro,鉛,옅은 회색,Lichtgrijs,Lysegrå,Jasnoszary,Cinza claro,,Gri Deschis,Светло-серый,Светло сива,Ljusgrå,Açık Gri,Світло-сірий, +Light Brown,TXT_COLOR_LIGHTBROWN,,,,Světle hnědá,Lys brun,Hellbraun,Ανοιχτό Καφέ,Helbruna,Marrón claro,,Vaaleanruskea,Brun clair,Világosbarna,Marrone chiaro,褐,옅은 고동색,Lichtbruin,Lysebrun,Jasnobrązowy,Marrom claro,,Maro Deschis,Светло-коричневый,Светло браон,Ljusbrun,Açık Kahverengi,Світло-коричневий, +Gold,TXT_COLOR_GOLD,,,,Zlatá,Guld,,Χρυσό,Orkolora,Dorado,,Kulta,Or,Arany,Oro,金,금색,Goud,Gull,Złoty,Dourado,,Auriu,Золотой,Златна,Guld,Altın,Золотий, +Bright Green,TXT_COLOR_BRIGHTGREEN,,,,Jasně zelená,Lysegrøn,Hellgrün,Φωτινό Πράσινο,Brilverda,Verde claro,,Vaaleanvihreä,Vert clair,Fényeszöld,Verde chiaro,鮮,밝은 녹색,Helder groen,Lysegrønn,Jasnozielony,Verde claro,,Verde Deschis,Ярко-зелёный,Светла зелена,Ljusgrön,Parlak Yeşil,Яскраво-зелений, +Rust,TXT_COLOR_RUST,,,,Rezavá,,Rostbraun,Σκουριά,Rustokolora,Óxido,,Ruoste,Rouille,Rozsda,Arrugginito,錆,주황 적갈색,Roest,,Rdzawy,Ferrugem,,Ruginiu,Ржавый,Рђа,Rost,Pas,Іржавий, +Name,PLYRMNU_NAME,,,,Jméno,Navn,,Όνομα,Nomo,Nombre,,Nimi,Nom,Név,Nome,名前,이름,Naam,Navn,Imię,Nome,,Nume,Имя,Надимак,Namn,İsim,Ім'я, +Team,PLYRMNU_TEAM,,,,Tým,,,Ομάδα,Teamo,Equipo,,Joukkue,Equipe,Csapat,Squadra,チーム,팀,,Lag,Drużyna,Equipe,Equipa,Echipă,Команда,Тим,Lag,Takım,Команда, +Color,PLYRMNU_PLAYERCOLOR,,,Colour,Barva,Farve,Farbe,Χρώμα,Koloro,,,Väri,Couleur,Szín,Colore,色,색상,Kleur,Farge,Kolor,Cor,,Culoare,Цвет,Боја,Färg,Renk,Колір, +Gender,PLYRMNU_PLAYERGENDER,,,,Pohlaví,Køn,Geschlecht,Φύλο,Genro,Género,,Sukupuoli,Genre,Nem,Sesso,性別,성별,Geslacht,Kjønn,Płeć,Gênero,,Sex,Пол,Пол,Kön,Cinsiyet,Стать, +Male,OPTVAL_MALE,,,,Muž,Mand,Männlich,Αρσενικό,Vira,Masculino,,Miespuolinen,Masculin,Férfi,Maschio,男,남성,Man,Mannlig,Mężczyzna,Masculino,,Masculin,Мужской,Мушко,Man,Erkek,Чоловіча, +Female,OPTVAL_FEMALE,,,,Žena,Kvinde,Weiblich,Θηλυκό,Ina,Femenino,,Naispuolinen,Féminin,Nő,Femmina,女,여성,Vrouw,Kvinne,Kobieta,Feminino,,Feminin,Женский,Женско,Kvinna,Kadın,Жіноча, +Neutral,OPTVAL_NEUTRAL,,,,Neutrální,,,Ουδέτερο,Neŭtra (Ri),Neutro,,Sukupuoleton,Neutre,Semleges,Neutrale,中間,중성,Neutraal,Nøytral,Neutralne,Neutro,,Neutru,Нейтральный,Неутрално,Neutral,Nötr,Нейтральна, +Object,OPTVAL_OTHER,,,,Objekt,Objekt,Objekt,Αντικείμενο,Objekto (Ĝi),Objeto,,Olio,Objet,Tárgy,Oggetto,物体,기타,Doel,Gjenstand,Obiekt,Objeto,,Obiect,Предмет,Предмет,Objekt,Nesne,Предмет, +Gameplay Options,GMPLYMNU_TITLE,,,,Nastavení herních mechanik,Gameplay-muligheder,Gameplay-Optionen,,Ludado-agordoj,Opciones de jugabilidad,,Pelattavuusasetukset,Options Gameplay,Játékmenet beállításai,Opzioni gameplay,ゲームプレイ オプション,게임플레이 설정,Gameplay-opties,Spillalternativer,Opcje Rozgrywki,Opções de jogabilidade,,Setări de Joc,Настройки игры,Подешавања гејмплеја,Spelalternativ,Oynanış Seçenekleri,Налаштування гри, +Always,OPTVAL_ALWAYS,,,,Vždy,Altid,Immer,Πάντα,Ĉiam,Siempre,,Aina,Toujours,Mindig,Sempre,常に,언제나,Altijd,Alltid,Zawsze,Sempre,,Mereu,Всегда,Увек,Alltid,Her zaman,Завжди, +Never,OPTVAL_NEVER,,,,Nikdy,Aldrig,Nie,Ποτέ,Neniam,Nunca,,Ei koskaan,Jamais,Soha,Mai,しない,없음,Nooit,Aldri,Nigdy,Nunca,,Niciodată,Никогда,Никад,Aldrig,Asla,Ніколи, +Autoaim,PLYRMNU_AUTOAIM,,,,Automatické míření,,Automatisch zielen,,Celasisto,Autoapuntar,,Automaattitähtäys,Auto-visée,Automatikus célzás,Mira automatica,自動照準,자동 조준,,,Auto-celowanie,Mira automática,,Autoțintire,Автоприцеливание,Аутоматско циљање,,,Автонаведення, +Always Run,PLYRMNU_ALWAYSRUN,,,,Vždy běžet,Altid løbe,Immer Rennen,Πάντα τρέχα,Ĉiam kuri,Siempre correr,,Jatkuva juoksu,Toujours courir,Mindig fusson,Corri sempre,常に駆け足,달리기 토글,Altijd lopen,Kjør alltid,Zawsze Biegaj,Sempre correr,Correr Sempre,Fugă în permanență,Постоянный бег,Увек трчи,Alltid springa,Daima Koş,Постійно бігти, +,,Display,,,,,,,,,,,,,,,,,,,,,,,,,,, +Screen size,DSPLYMNU_SCREENSIZE,,,,Velikost obrazovky,Skærmstørrelse,Bildschirmgröße,Μέγεθος οθόνης,Ekrangrando,Tamaño de pantalla,,Näytön koko,Taille de l'écran,Képernyő mérete,Dimensione della schermata,画面サイズ,화면 크기,Schermgrootte,Skjermstørrelse,Rozmiar Ekranu,Tamanho da tela,Tamanho do ecrã,Mărime ecran,Размер экрана,Величина екрана,Skärmstorlek,Ekran boyutu,Розмір екрану, +Vertical Sync,DSPLYMNU_VSYNC,,,,Vertikální synchronizace,Lodret synkronisering,Vertikale Synchronisation,,Vertikala-sinkronigo,Sincronización vertical,,Pystytahdistys,Synchronisation Verticale,Függőleges szinkronizálás,Sincronia verticale,垂直同期,수직 동기화,Verticale Sync,Vertikal synkronisering,Synchronizacja Pionowa,Sincronização vertical,,Sincronizare Verticală,Вертикальная синхронизация,Вертикална синхорнизација,Vertikal synkronisering,Dikey Senkronizasyon,Вертикальна синхронізація, +Models,DSPLYMNU_MODELS,,,,Modely,Modeller,Modelle,Μοντέλα,Modeloj,Modelos,,Mallit,Modèles,3D modellek,Modelli,モデル,모델,Modellen,Modeller,Modele,Modelos,,Modele,Модели,Модели,Modeller,Modeller,3D Моделі, +Scale crosshair,DSPLYMNU_CROSSHAIRSCALE,,,,Velikost zaměřovače,Skalerer trådkorset,Fadenkreuz skalieren,,Skali reteton,Escalar retícula,,Skaalaa tähtäintä,Mise à l'échelle du viseur,Célkereszt méret,Scala del mirino,照準スケール,조준점 크기,Dradenkruis schalen,Skala trådkors,Skala celownika,Escala da mira,,Scară țintă,Размер прицела,Размера нишана,Skala hårkorset,Ölçekli artı işareti,Розмір прицілу, +Brightness,DSPLYMNU_BRIGHTNESS,,,,Jas,Lysstyrke,Helligkeit,Φωτηνότητα,Brileco,Brillo,,Kirkkaus,Luminosité,Fényerő,Luminosità,明るさ,밝기,Helderheid,Lysstyrke,Jasność,Brilho,,Luminozitate,Яркость,Осветљење,Ljusstyrka,Parlaklık,Яскравість, +Gamma correction,DSPLYMNU_GAMMA,,,,Korekce gama,Gammakorrektion,Gammakorrektur,,Gamaa korektado,Corrección gamma,,Gammakorjaus,Correction Gamma,Gamma korrekció,Correzione gamma,ガンマ値,감마 조정,Gamma correctie,Gammakorreksjon,Korekta gammy,Correção de gama,,Gamma,Гамма-коррекция,Корекција светлости,Gammakorrigering,Gama düzeltme,Гамма-корекція, +Contrast,DSPLYMNU_CONTRAST,,,,Kontrast,Kontrast,Kontrast,,Kontrasto,Contraste,,Sävykkyys,Contraste,Kontraszt,Contrasto,コントラスト,대비,,Kontrast,Kontrast,Contraste,,,Контраст,Контраст,Kontrast,Kontrast,Контраст, +Saturation,DSPLYMNU_SATURATION,,,,Sytost,Mætning,Sättigung,,Satureco,Saturación,,Värikylläisyys,,Telítettség,Saturazione,サチュレーション,채도,Verzadiging,Metning,Nasycenie,Saturação,,Saturație,Насыщенность,Сатурација,Mättnad,Doygunluk,Насиченість, +Status Bar Scale,DSPLYMNU_SBSCALE,,,,Velikost stavového panelu,Skala for statuslinje,Statusleistengröße,,Skalo de stata breto,Escala de barra de estado,,Tilapalkin skaalaus,Mise à l'échelle HUD,Állapotjelző mérete,Dimensioni Status Bar,ステータススケール,,Statusbalkschaal,Statuslinjeskala,Skala paska statusu,Escala da barra de estado,,Scară bară de stare,Размер строки состояния,,Skala för statusfältet,Durum Çubuğu Ölçeği,Розмір строки стану, +Messages,DSPLYMNU_MESSAGES,,,,Oznámení,Meddelelser,Nachrichten,Μηνύματα,Mesaĝoj,Mensajes,,Viestit,,Üzenetek,Messaggi,メッセージ類,메시지,Berichten,Meldinger,Wiadomości,Mensagens,,Mesaje,Сообщения,Поруке,Meddelanden,Mesajlar,Повідомлення, +Center messages,MSGMNU_CENTERMESSAGES,,,Centre messages,Oznámení na střed,Centrerede meddelelser,Nachrichten zentrieren,,Centrigi mesaĝojn,Centrar mensajes,,Keskitä viestit,Messages centrés,Üzenetek középre helyezése,Messaggi centrati,メッセージを中央に,메시지 중간에 위치,Berichten centreren,Sentrumsmeldinger,Wyśrodkuj wiadomości,Centralizar mensagens,Centrar mensagens,Mesaje centrate,Центрирование сообщений,Централне поруке,Centrerade meddelanden,Merkez mesajları,Центрування повідомлень, +Pulsating message Display,MSGMNU_PULSEMESSAGES,,,,Pulzující oznámení,Pulserende meddelelser Visning,Pulsierende Nachrichtenanzeige,,Pulsanta mesaĝ-montrejo,Mostrar mensajes pulsantes,,Sykkivät viestit,Messages pulsés,Pulzáló üzenet,Mostra messaggi pulsanti,取得時等の文を明滅,,Pulserende berichtendisplay,Pulserende melding Display,Pulsujące wyświetlanie wiadomości,Exibir mensagem pulsante,,Afișare Mesaje Pulsante,Пульсация сообщений,,Pulserande meddelande Visning,Titreşimli mesaj Ekranı,Пульсація повідомлень, +Message Scale,MSGMNU_MESSAGESCALE,,,,Velikost oznámení,Skala for meddelelser,Nachrichtengröße,Μέγεθος μηνύματον,Skalo de mesaĝoj,Escala de mensajes,,Viestien skaalaus,Mise à l'échelle Messages,Üzenet mérete,Dimensioni Messaggi,メッセージスケール,,Berichtschaal,Meldingsskala,Skalowanie Wiadomości,Escala de mensagem,,Scară Mesaje,Размер сообщений,,Meddelandeskala,Mesaj Ölçeği,Розмір повідомлень, +,,Automap,,,,,,,,,,,,,,,,,,,,,,,,,,, +Select Color,MNU_COLORPICKER,,,Select Colour,Výběr barvy,Vælg farve,Farbe auswählen,Επιλογή Χρώματος,Elektu koloron:,Elige un color,,Valitse väri,Choisir Couleur,Szín választása,Scegli il colore,色選択,색상을 고르시오,Selecteer Kleur,Velg farge,Wybierz Kolor,Selecione uma cor,,Alege o Culoare,Выбор цвета,Изабери боју,Välj färg,Renk Seçiniz,Вибір кольору, +Rotate automap,AUTOMAPMNU_ROTATE,,,,Otáčet automapu,Rotere automap,Rotiere Automap,,Turni aŭtomatan mapon,Rotar automapa,,Kiertyvä automaattikartta,Rotation de la Carte,Térkép forgatása,Ruota l'automappa,オートマップの回転表示,오토맵 회전,Automatisch roteren,Roter automatisk kart,Obracaj mapę,Girar automapa,,Rotire hartă computerizată,Вращающаяся автокарта,Ротирај аутомапу,Rotera automap,Otomatik haritayı döndür,Обертання автокарти, +Follow player,AUTOMAPMNU_FOLLOW,,,,Následovat hráče,Følg spilleren,Folge dem Spieler,Ακουλούθα το παίχτη,Sekvi ludanton,Seguir jugador,,Seuraa pelaajaa,Suivre le joueur,Kövesse a játékost,Segui il giocatore,プレイヤー追従,플레이어 추적,Volg de speler,Følg spiller,Podążaj za graczem,Seguir jogador,,Urmărire jucător,Привязка к игроку,Прати играча,Följ spelaren,Oyuncuyu takip et,Прив'язка до гравця, +Line alpha,AUTOMAPMNU_LINEALPHA,,,,Průhlednost čar,Linje alfa,Alpha für Linien,,Travidebleca de linio,Transparencia de línea,,Viivan alpha,Translucidité des lignes,Vonal áttetszóség,Traslucenza delle linee,線の半透明度,선 반투명도,Doorschijnendheid van lijnen,Linje alfa,Przezroczystość Linii,Transparência da linha,,Transparență linii,Прозрачность линий,Транслуценција линија,Linje alfa,Çizgi alfa,Прозорість ліній, +Line thickness,AUTOMAPMNU_LINETHICKNESS,,,,Tloušťka čar,Linjetykkelse,Dicke der Linien,,Dikeca de linio,Grosor de línea,,Viivan paksuus,Épaisseur des lignes,Vonal vastagság,Spessore delle linee,線の太さ,선 두께,Dikte van lijnen,Linjetykkelse,Grubość Linii,Espessura da linha,,Grosime linii,Толщина линий,Дебљина линија,Linjens tjocklek,Çizgi kalınlığı,Товщина ліній, +Customize Map Colors,MAPCOLORMNU_TITLE,,,Customize Map Colours,Nastavení barev mapy,Tilpas kortfarver,Automapfarben einstellen,,Adapti mapkolorojn,Personalizar colores (mapa),,Värien mukautus,Couleurs Carte Personnalisées,Térkép színeinek testreszabása,Personalizza i colori della mappa,カスタム色を決める,미니맵 색상 설정,Kaartkleuren aanpassen,Tilpass kartfarger,Ustaw kolory mapy,Personalizar cores do mapa,,Personalizare culori hartă,Настройки цветов автокарты,Промени боју мапе,Anpassa kartans färger,Harita Renklerini Özelleştirin,Налаштування кольорів автокарти, +Restore default custom colors,MAPCOLORMNU_DEFAULTMAPCOLORS,,,Restore default custom colours,Obnovit původní vlastní barvy,Gendan standard brugerdefinerede farver,Standardfarben wiederherstellen,,Restaŭri defaŭltajn laŭmendajn kolorojn,Restaurar colores personalizados,,Palauta oletusvärit,Couleurs par défaut,Eredeti színek visszaállítása,Reimposta i colori personalizzati al default,カスタム色を初期化,기본 색상으로 복구,Standaard aangepaste kleuren herstellen,Gjenopprett egendefinerte standardfarger,Przywróć domyślne kolory,Restaurar cores personalizadas padrão,,Revenire la culorile implicite,Вернуть стандартные цвета,Врати уобичајене разне боје,Återställ anpassade standardfärger,Varsayılan özel renkleri geri yükleme,Повернути стандартні кольори, +,,Sound,,,,,,,,,,,,,,,,,,,,,,,,,,, +Sound enabled,SNDMNU_SNDENABLED,,,,Zvuk zapnut,Lyd aktiveret,Sound aktiv,Ήχος ενεργοποιημένος,Sono ŝaltita,Sonido activado,,Ääni päällä,Son activé,Hang engedélyezve,Abilita gli effetti sonori,サウンド有効,,Geluid actief,Lyd aktivert,Dźwięk włączony,Som ativado,,Sunet activat,Звук включён,,Ljud aktiverat,Ses etkin,Звук вимкнено, +Music enabled,SNDMNU_MUSENABLED,,,,Hudba zapnuta,Musik aktiveret,Musik aktiv,Μουσική ενεργοποιημένη,Muziko ŝaltita,Música activada,,Musiikki päällä,Musique activée,Zene engedélyezve,Abilita la musica,音楽有効,,Muziek actief ,Musikk aktivert,Muzyka włączona,Música ativada,,Muzică activată,Музыка включена,,Musik aktiverad,Müzik etkin,Музику вимкнено, +4000 Hz,OPTVAL_4000HZ,,,,,,,,,,,,,,,,,,,,,,,4000 Гц,,,,4000 Гц, +8000 Hz,OPTVAL_8000HZ,,,,,,,,,,,,,,,,,,,,,,,8000 Гц,,,,8000 Гц, +11025 Hz,OPTVAL_11025HZ,,,,,,,,,,,,,,,,,,,,,,,11025 Гц,,,,11025 Гц, +22050 Hz,OPTVAL_22050HZ,,,,,,,,,,,,,,,,,,,,,,,22050 Гц,,,,22050 Гц, +32000 Hz,OPTVAL_32000HZ,,,,,,,,,,,,,,,,,,,,,,,32000 Гц,,,,32000 Гц, +44100 Hz,OPTVAL_44100HZ,,,,,,,,,,,,,,,,,,,,,,,44100 Гц,,,,44100 Гц, +48000 Hz,OPTVAL_48000HZ,,,,,,,,,,,,,,,,,,,,,,,48000 Гц,,,,48000 Гц, +64 samples,OPTVAL_64SAMPLES,,,,64 vzorků,,,64 δείγματα,64 specimenoj,64 muestras,,64 näytettä,,,,,64 샘플,,64 samplinger,64 sample,64 amostras,,64 monstre,64 семпла,64 узорка,64 samplingar,64 örnek,64 семпла, +128 samples,OPTVAL_128SAMPLES,,,,128 vzorků,,,128 δείγματα,128 specimenoj,128 muestras,,128 näytettä,,,,,128 샘플,,128 samplinger,128 sampli,128 amostras,,128 monstre,128 семплов,128 узорка,128 samplingar,128 örnek,128 семплів, +256 samples,OPTVAL_256SAMPLES,,,,256 vzorků,,,256 δείγματα,256 specimenoj,256 muestras,,256 näytettä,,,,,256 샘플,,256 samplinger,256 sampli,256 amostras,,256 monstre,256 семплов,256 узорка,256 samplingar,256 örnek,256 семплів, +512 samples,OPTVAL_512SAMPLES,,,,512 vzorků,,,512 δείγματα,512 specimenoj,512 muestras,,512 näytettä,,,,,512 샘플,,512 samplinger,512 sampli,512 amostras,,512 monstre,512 семплов,512 узорка,512 samplingar,512 örnek,512 семплів, +1024 samples,OPTVAL_1024SAMPLES,,,,1024 vzorků,,,1024 δείγματα,1024 specimenoj,1024 muestras,,1024 näytettä,,,,,1024 샘플,,1024 samplinger,1024 sampli,1.024 amostras,,1024 monstre,1024 семпла,1024 узорка,1024 samplingar,1024 örnek,1024 семплів, +2048 samples,OPTVAL_2048SAMPLES,,,,2048 vzorků,,,2048 δείγματα,2048 specimenoj,2048 muestras,,2048 näytettä,,,,,2048 샘플,,2048 samplinger,2048 sampli,2.048 amostras,,2048 monstre,2048 семплов,2048 узорка,2048 samplingar,2048 örnek,2048 семплів, +4096 samples,OPTVAL_4096SAMPLES,,,,4096 vzorků,,,4096 δείγματα,4096 specimenoj,4096 muestras,,4096 näytettä,,,,,4096 샘플,,4096 samplinger,4096 sampli,4.096 amostras,,4096 monstre,4096 семплов,4096 узорка,4096 samplingar,4096 örnek,4096 семплів, +Auto,OPTSTR_AUTO,,,,,Automatisk,,,Aŭtomata,Automático,,Automaattinen,,Automatikus,Automatico,自動,오토,,,Automatycznie,Automático,,,Авто,Аутоматски,Automatisk,Otomatik,Авто, +Mono,OPTSTR_MONO,,,,,,,,Monofonia,,,,,Monó,,モノラル,모노,,,,,,,Моно,Монотоно,,,Моно, +Stereo,OPTSTR_STEREO,,,,,,,,Stereofonia,Estéreo,,,Stéréo,Sztereó,,ステレオ,스테레오,,,,Estéreo,,,Стерео,Стереотоно,,,Стерео, +Dolby Pro Logic Decoder,OPTSTR_PROLOGIC,,,,,Dolby Pro Logic-dekoder,,,Malkodilo de Dolby Pro Logic ,,,,,,,ドルビー プロロジック デコーダー,돌비 프로 로직 디코더,,Dolby Pro Logic Dekoder,,Decodificador Dolby Pro Logic,,Decodor Pro Logic Dolby,Декодер Dolby Pro Logic,,Dolby Pro Logic-dekoder,Dolby Pro Logic Dekoder,Декодер Dolby Pro Logic, +Quad,OPTSTR_QUAD,,,,,,,,Kvadratofonia,Cuádruple,,Dolby Pro Logic -dekooderi,,,,クァッド,쿼드,,,Cztery kanały,Quadrifônico,,,Четырёхканальный,Четвородупло,,Dörtlü,Чотирьохканальний, +5 speakers,OPTSTR_SURROUND,,,,5 reproduktorů,5 højttalere,5 Lautsprecher,,5 Laŭtparoliloj,5 altavoces,,5 kaiutinta,5 enceintes,5 hangfal,Surround,5 スピーカー,5 스피커,5 luidsprekers,5 høyttalere,Głośniki 5,5 alto-falantes,,5 boxe,5 динамиков,5 спикер,5 högtalare,5 hoparlörler,5 динаміків, +5.1 speakers,OPTSTR_5POINT1,,,,Reproduktory 5.1,5.1-højttalere,5.1 Lautsprecher,,5.1 Laŭtparoliloj,Altavoces 5.1,,5.1 kaiutinta,Enceintes 5.1,5.1 hangrendszer,Surround 5.1,5.1 スピーカー,5.1 스피커,5.1 luidsprekers,5.1 høyttalere,Głośniki 5.1,Auto-falantes 5.1,,Boxe 5.1,Динамики 5.1,5.1 спикер,5.1-högtalare,5.1 hoparlörler,Динаміки 5.1, +7.1 speakers,OPTSTR_7POINT1,,,,Reproduktory 7.1,7.1-højttalere,7.1 Lautsprecher,,7.1 Laŭtparoliloj,Altavoces 7.1,,7.1 kaiutinta,Enceintes 7.1,7.1 hangrendszer,Surround 7.1,7.1 スピーカー,7.1스피커,7.1 luidsprekers,7.1-høyttalere,Głośniki 7.1,Auto-falantes 7.1,,Boxe 7.1,Динамики 7.1,7.1 спикер,7.1-högtalare,7.1 hoparlörler,Динаміки 7.1, +Playback device,OPENALMNU_PLAYBACKDEVICE,,,,Přehravací zařízení,Afspilningsenhed,Wiedergabegerät,,Ludado-aparato,Dispositivo de reproducción,,Äänitoistolaite,Sortie sonore,Visszajátszó eszköz,Dispositivo di playback,プレイバック デバイス,재생 장치,Afspeelapparaat,Avspillingsenhet,Urządzenie odtwarzania,Dispositivo de reprodução,,Dispozitiv de redare,Устройство воспроизведения,Аудио уређај,Uppspelningsenhet,Oynatma cihazı,Пристрій відтворення, +Enable EFX,OPENALMNU_ENABLEEFX,,,,Povolit EFX,Aktiver EFX,EFX aktiv,,Ŝalti EFX,Permitir EFX,,Ota käyttöön EFX,Activer EFX,EFX engedélyezése,Abilita EFX,EFXを有効化,EFX 켬,EFX inschakelen,Aktiver EFX,Pozwól na EFX,Ativar EFX,,Activare EFX,Включить EFX,Укључи EFX,Aktivera EFX,EFX'i Etkinleştir,Увімкнути EFX, +Resampler,OPENALMNU_RESAMPLER,,,,,Resampler,,,Respecimenilo,,,Näytteenottotaajuusmuunnin,,,,リサンプラー,재배열 기기,,,,Reamostrador,,,Передискретизатор,Ресемплер,,Yeniden Örnekleyici,Ресемплер, +Sounds volume,SNDMNU_SFXVOLUME,,,,Hlasitost zvuků,Lydstyrke,Effektlautstärke,Φονή ήχων,Sona laŭteco,Volumen de sonido,,Äänitehosteiden voimakkuus,Volume des Sons,Effektek hangereje,Volume suoni,効果音音量,효과음 음량,Geluidsvolume,Lydvolum,Głośność Dźwięku,Volume de sons,,Volum efecte,Громкость звука,Јачина звука,Ljudvolym,Ses seviyesi,Гучність звуків, +Menu volume,SNDMNU_MENUVOLUME,,,,Hlasitost nabídek,Menu-volumen,Menülautstärke,Φονή μενού,Menuo-laŭteco,Volumen del menú,,Valikon äänenvoimakkuus,Volume du Menu,Menü hangereje,Volume menù,メニュー音量,메뉴 음량,Menu volume,Menyvolum,Głośność Menu,Volume do menu,,Volum meniu,Громкость меню,Јачина менија,Volym för menyer,Menü ses seviyesi,Гучність меню, +Music volume,SNDMNU_MUSICVOLUME,,,,Hlasitost hudby,Lydstyrke for musik,Musiklautstärke,Φονή μουσικής,Muzika laŭteco,Volumen de la música,,Musiikin äänenvoimakkuus,Volume Musique,Zene hangereje,Volume musica,音楽音量,배경음 음량,Muziekvolume,Musikkvolum,Głośność Muzyki,Volume da música,,Volum muzică,Громкость музыки,Јачина музике,Musikvolym,Müzik sesi,Гучність музики, +MIDI device,SNDMNU_MIDIDEVICE,,,,MIDI zařízení,MIDI-enhed,MIDI-Gerät,MIDI συσκεύη,MIDI-aparato,Dispositivo MIDI,,MIDI-laite,Sortie MIDI,MIDI eszköz,Dispositivo MIDI,MIDIデバイス,MIDI 장치,MIDI-apparaat,MIDI-enhet,Urządzenie MIDI,Dispositivo MIDI,,Dispozitiv MIDI,MIDI-проигрыватель,MIDI уређај,MIDI-enhet,MIDI cihazı,MIDI програвач, +Sound in Background,SNDMNU_BACKGROUND,,,,Zvuk na pozadí,Lyd i baggrunden,Sound im Hintergrund,Ήχος στο παρασκήνιο,Sono en fono,Sonido en segundo plano,,Ääni taustalla,Son activé en arrière plan,Háttérhangok,Suono di sottofondo,バックグラウンドでのサウンド,배경화면에서도 소리 재생,Geluid in de achtergrond,Lyd i bakgrunnen,Dźwięk w Tle,Som em segundo plano,,Sunet pe fundal,Звук в фоне,Звуци у позадини,Ljud i bakgrunden,Arka Planda Ses,Звуки на фоні, +Underwater reverb,SNDMNU_UNDERWATERREVERB,,,,Ozvěna pod vodou,Undervandsreverb,Unterwasserhall,,Subakva resono,Reverberación bajo el agua,,Vedenalaiskaiku,Reverbération sous l'eau,Vízalatti visszaverődés,Reverb sott'acqua,水中反響音,수중 울림효과,Onderwater nagalm,Undervanns romklang,Pogłos pod wodą,Reverberação debaixo d'água,Reverberação debaixo de água,Reverb subacvatic,Эффект затухания под водой,Подводни одјек,Undervattensreverb,Su altı yankısı,Підводний ефект, +Randomize pitches,SNDMNU_RANDOMIZEPITCHES,,,,Náhodné výšky tónu,Randomisere tonehøjder,Zufällige Tonhöhe,,Malcertigi son-peĉojn,Tonos aleatorios,,Satunnaista äänenkorkeuksia,Tons sonores aléatoires,Hangmagasság keverése,Rendi casuale il tono,ランダマイズ ピッチ,음높이 무작위화,Willekeurige plaatsen,Tilfeldig tonehøyde,Losuj tonacje,Tons aleatórios,Tons aleatórios,Ton sunete aleatoriu,Случайная высота,Рандомизација тонова,Slumpmässiga tonhöjder,Sahaları rastgele ayarlayın,Випадкова висота, +Sound channels,SNDMNU_CHANNELS,,,,Počet zvukových kanálů,Lydkanaler,Soundkanäle,Κανάλια ήχου,Sonokanaloj,Canales de sonido,,Äänikanavat,Canaux sonores,Hangcsatorna,Numero canali del suono,サウンド チャンネル,음향 채널,Geluidskanalen,Lydkanaler,Kanały dźwiękowe,Canais de som,,Canale de sunet,Количество каналов,Звучни канали,Ljudkanaler,Ses kanalları,Кількість каналів, +Sound backend,SNDMNU_BACKEND,,,,Zvukový systém,Lyd backend,Soundsystem,,Sonoservilo,Sistema de sonido,,Äänijärjestelmä,Traitement Son,Hang backend,Backend suono,サウンド バックエンド,음향 말미,Geluidsarme achterkant,Lyd backend,System dźwiękowy,Sistema de som,,Sistem de sunet,Звуковая подсистема,Звучни бекенд,Ljudbakgrund,Ses arka ucu,Звукова система, +OpenAL options,SNDMNU_OPENAL,,,,Nastavení OpenAL,OpenAL-muligheder,OpenAL Optionen,OpenAL ρυθμίσεις,OpenAL agordoj,Opciones de OpenAL,,OpenAL-asetukset,Options OpenAL,OpenAL beállításai,Opzioni OpenAL,OpenAL オプション,오픈에이엘 설정,OpenAL opties,OpenAL-alternativer,Opcje OpenAL,Opções de OpenAL,,Setări OpenAL,Настройки OpenAL,OpenAL подешавања,OpenAL-alternativ,OpenAL seçenekleri,Параметри OpenAL, +Restart sound,SNDMNU_RESTART,,,,Restartovat zvuk,Genstart af lyd,Sound neu starten,,Rekomenci sonon,Reiniciar sonido,,Käynnistä ääni uudelleen,Redémarrer moteur sonore,Hang újraindítása,Resetta il suono,サウンド再起動,음향 재시작,Herstart geluid,Start lyd på nytt,Zresetuj dźwięk,Reiniciar som,,Reinițializare sunet,Перезапустить звук,Поново покрени звук,Starta om ljudet,Sesi yeniden başlat,Перезавантажити звук, +Advanced options,SNDMNU_ADVANCED,,,,Pokročilá nastavení,Avancerede indstillinger,Erweiterte Optionen,Προχήρημενες ρυθμίσεις,Altnivelaj agordoj,Opciones avanzadas,,Edistyneet asetukset,Options avancées,Haladó beállítások,Opzioni avanzate,高度なオプション,고급 설정,Geavanceerde opties,Avanserte alternativer,Zaawansowane Opcje,Opções avançadas,,Setări avansate,Расширенные настройки,Напредна подешавања,Avancerade alternativ,Gelişmiş seçenekler,Розширені налаштування, +Module replayer options,SNDMNU_MODREPLAYER,,,,Nastavení přehrávače modulů,Indstillinger for modulafspiller,Modul-Spieler-Optionen,,Agordoj por modulreludilo,Opciones reproductor de módulos,,Moduulisoitinasetukset,Options lecteur de module,Modul lejátszó beállításai,Opzioni Module replayer,モジュールリプレイヤー オプション,모듈 재생 설정,Module replayer opties,Alternativer for modulavspiller,Opcje Modułu Odtwarzacza,Opções de reprodutor de módulos,,Setări de redare a modulelor,Параметры воспроизведения модулей,Подешавања модулног риплејера,Alternativ för modulåterspelare,Modül yeniden oynatıcı seçenekleri,Параметри відтворення модулів, +Midi player options,SNDMNU_MIDIPLAYER,,,,Nastavení MIDI přehrávače,Indstillinger for Midi-afspiller,MIDI-Spieler-Optionen,,Agordoj por MIDI-ludilo,Opciones de reproductor MIDI,,MIDI-soitinasetukset,Option lecteur MIDI,Midi lejátszó beállításai,Opzioni Midi player,Midi再生のオプション,MIDI 플레이어 설정,Midi speler opties,Alternativer for midispiller,Opcje Odtwarzacza Midi,Opções de reprodutor MIDI,,Setări player MIDI,Настройки MIDI-проигрывателя,MIDI плејер подешавања,Alternativ för Midi-spelare,Midi oynatıcı seçenekleri,Параметри MIDI-програвача, +Sound in Menus,SNDMNU_MENUSOUND,,,,Zvuk v menu,Lyd i menuer,Sound in Menüs,,Sono en menuoj,,,Ääni valikoissa,Son dans les menus,Hang a menükben,Suono nei menù,メニューでのサウンド,,Geluid in menu's,Lyd i menyer,Dźwięk w Menu,Som em menus,,Sunet in meniuri,Звук в меню,,Ljud i menyer,Menülerde Ses,Звук в меню, +Advanced Sound Options,ADVSNDMNU_TITLE,,,,Pokročilá nastavení zvuku,Avancerede lydindstillinger,Erweiterte Soundoptionen,,Altnivelaj sonaj agordoj,Opciones avanzadas de sonido,,Edistyneet ääniasetukset,Options Sonores Avancées,Haladó hangbeállítások,Opzioni avanzate dei suoni,高度なサウンドオプション,고급 음향 설정,Geavanceerde geluidsopties,Avanserte lydalternativer,Zaawansowane Opcje Dźwięku,Opções de áudio avançadas,,Setări de sunet avansate,Расширенные настройки,Напредна подешавања звука,Avancerade ljudalternativ,Gelişmiş Ses Seçenekleri,Розширені налаштування звуку, +Sample rate,ADVSNDMNU_SAMPLERATE,,,,Vzorkovací frekvence,Samplerate,Samplerate,,Specimenrapideco,Frecuencia de muestreo,,Näytteenottotaajuus,Cadence de Sampling,Mintavételezési ráta,,サンプルレート,샘플링레이트,Steekproeftarief,Samplingsfrekvens,Częstotliwość próbkowania,Taxa de amostragem,,Frecvență de eșantionare,Частота дискретизации,Фреквенција узорковања,Samplingsfrekvens,Örnek oranı,Частота дискретизації, +HRTF,ADVSNDMNU_HRTF,,,,,,,,,,,,,,,,머리전달함수,,,,,,,,,,,, +OPL Synthesis,ADVSNDMNU_OPLSYNTHESIS,,,,Emulace OPL,OPL-syntese,OPL Synthese,,OPL-sintezo,Síntesis OPL,,OPL-synteesi,Synthèse OPL,OPL szintézis,,OPLシンセサイズ,OPL 합성,OPL synthese,OPL-syntese,Synteza OPL,Síntese OPL,,Sinteză OPL,Синтез OPL,OPL синтеза,OPL-syntes,OPL Sentezi,Синтез OPL, +Number of emulated OPL chips,ADVSNDMNU_OPLNUMCHIPS,,,,Počet emulovaných OPL čipů,Antal emulerede OPL-chips,Anzahl OPL Chips,,Nombro da imititaj OPL-blatoj,Número de chips OPL emulados,,Emuloitavien OPL-piirien lukumäärä,Puces OPL émulées,Emulált OPL csipek száma,Numero di chip OPL emulati,OPLチップエミュレートの番号,에뮬레이트된 OPL 칩 수,Aantal geëmuleerde OPL chips,Antall emulerte OPL-brikker,Liczba emulowanych czipów OPL,Número de chips OPL emulados,,Număr de cipuri OPL emulate,Количество эмулируемых чипов OPL,Број емулираних OPL чипа,Antal emulerade OPL-chips,Taklit edilen OPL çiplerinin sayısı,Кількість емульованих OPL-чіпів, +Full MIDI stereo panning,ADVSNDMNU_OPLFULLPAN,,,,Plné MIDI stereo,Fuld MIDI stereo panorering,Echte MIDI-Stereoeffekte,,Tuta MIDI-sterepanoramado,Balance estéreo MIDI completo,,Täysi MIDI-stereopanorointi,Latéralisation complète MIDI,Teljes MIDI sztereó tájolás,,Full MIDIステレオパンニング,완전한 MIDI 스테레오 패닝,Volledige MIDI stereo panning,Full MIDI stereo panorering,Pełne efekty stereo dla MIDI,Lateralidade estéreo completa para MIDI,,Panoramă stereo pentru MIDI,Полная стереопанорама для MIDI,Пуно MIDI стерео каналисање,Full MIDI-stereopanorering,Tam MIDI stereo kaydırma,Повна стереопанорама для MIDI, +OPL Emulator Core,ADVSNDMNU_OPLCORES,,,,Emulační jádro OPL,OPL-emulatorkerne,OPL Emulatorkern,,OPL-imitilkerno,Núcleo de emulador OPL,,OPL-emulaattoriydin,Cœur émulateur OPL,,,OPL エミュレート コア,OPL 에뮬레이터 코어,OPL Emulator Kern,OPL-emulatorkjerne,Rdzeń Emulatora OPL,Núcleo do emulador de OPL,,Nucleu de emulare OPL,Ядро эмуляции OPL,OPL језгро емулације,OPL-emulatorns kärna,OPL Emülatör Çekirdeği,Ядро емуляції OPL, +MIDI voices,ADVSNDMNU_MIDIVOICES,,,,Počet MIDI hlasů,MIDI-stemmer,MIDI Stimmen,,MIDI-voĉoj,Voces MIDI,,MIDI-äänet,Voix MIDI,MIDI hangok,Voci MIDI,MIDI ボイス,MIDI 최대 음색 양,MIDI-stemmen,MIDI stemmer,Głosy MIDI,Vozes MIDI,,Voci MIDI,MIDI-голоса,MIDI гласови,MIDI-stämmor,MIDI sesleri,MIDI-голоси, +FluidSynth,ADVSNDMNU_FLUIDSYNTH,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Global,ADVSNDMNU_GLOBAL,,,,Globální,,,,Malloka,,,Yleinen,,,Globale,グローバル,전반적,Globaal,,Globalne,,,,Общие,Глобално,,Küresel,Загальні, +Freeverb,ADVSNDMNU_FREEVERB,,,,,,,,,,,,,,,フリーバーブ,프리버브,,,,,,,,,,Freeverb,, +Global Freeverb,ADVSNDMNU_GLOBAL_FREEVERB,,,,Globální Freeverb,Global Freeverb,Globales Freeverb,,Malloka Freeverb,Freeverb Global,,Yleinen Freeverb,Freeverb Global,,Freeverb globale,グローバル フリーバーブ,전반적 프리버브,Globale Freeverb,,Globalny Freeverb,Freeverb global,,Freeverb Global,Глобальный Freeverb,Глобални Freeverb,,Küresel Freeverb,Глобальний Freeverb, +Patch set,ADVSNDMNU_FLUIDPATCHSET,,,,Nástrojová sada,Patch-sæt,Patch-Set,,Flikaro,Set de parche,,Patch-asetus,Banque de Sons,,,パッチ セット,패치 세트,,Patch-sett,Zestaw łatek,Banco de sons,,Set patch,Патч-набор,Печ сет,Patch-uppsättning,Yama seti,Патч-набір, +Gain,ADVSNDMNU_FLUIDGAIN,,,,Zesílení,,Relative Lautstärke,,Akiro,Ganancia,,Vahvistus,,Visszaverődés,,ゲイン,쌓기,Relatief volume,,Wzmocnienie,Ganho,,Amplificare,Усиление,Појачање,Relativ volym,Kazanç,Підсилення, +Reverb,ADVSNDMNU_REVERB,,,,Ozvěna,,Hall,,Resono,Reverberación,,Kaiku,Réverbération,Visszhang,,リバーブ,리버브,Nagalm,,Pogłos,Reverberação,,,Реверберация,Одјек,,,Ревербація, +Reverb Level,ADVSNDMNU_REVERB_LEVEL,,,,Intenzita ozvěny,,Hallintensität,,Nivelo de resono,Nivel de reverberación,,Kaiunvoimakkuus,Niveau Réverb.,Visszhang szintje,,リバーブ量,리버브 강도,Nagalm niveau,Reverb-nivå,Poziom pogłosu,Nível de reverberação,,Nivel Reverb,Уровень реверберации,Ниво одјека,Reverb-nivå,Reverb Seviyesi,Рівень ревербації, +Chorus,ADVSNDMNU_CHORUS,,,,,,,,Koruso,,,,,,,コーラス,코러스,,,,,,Cor,Хор,Корус,,Koro,Хорус, +Timidity++,ADVSNDMNU_TIMIDITY,,,,,,,,,,,,,,,,,,,,,,,,,,,, +ADLMidi,ADVSNDMNU_ADLMIDI,,,,,,,,,,,,,,,,,,,,,,,,,,,, +OPNMidi,ADVSNDMNU_OPNMIDI,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Timidity config file,ADVSNDMNU_TIMIDITYCONFIG,,,,Konfigurační soubor Timidity,Timidity-konfigurationsfil,Timidity Konfigurationsdatei,,Agorda dosiero de Timidity,Ruta al archivo config. Timidity,,Timidity-config-tiedosto,Fichier de config. TiMidity,Timidity konfigurációs fájl,File configurazione Timidity,Timidity コンフィグファイル,Timidity 코딩 파일,Timidity++ configuratiebestand,Timidity konfigurasjonsfil,Plik konfiguracyjny Timidity,Arquivo de configuração do Timidity,,Fișier configurație Timidity,Файл конфигурации Timidity,Timidity конфигурациона датотека,Timidity-konfigurationsfil,Timidity yapılandırma dosyası,Файл конфігурації Timidity, +Relative volume,ADVSNDMNU_TIMIDITYVOLUME,,,,Relativní hlasitost,Relativ lydstyrke,Relative Lautstärke,,Relativa laŭteco,Volumen relativo,,Suhteellinen äänenvoimakkuus,Volume Relatif,Relatív hangerő,Volume relativo,相対音量,비교적인 볼륨,Relatief volume,Relativt volum,Względna głośność,Volume relativo,,Volum relativ,Относительная громкость,Релативна јачина,Relativ volym,Bağıl hacim,Відносна гучність, +WildMidi,ADVSNDMNU_WILDMIDI,,,,,,,,,,,,,,,,,,,,,,,,,,,, +WildMidi config file,ADVSNDMNU_WILDMIDICONFIG,,,,Konfigurační soubor WildMidi,WildMidi konfigurationsfil,WilfMidi Konfigurationsdatei,,Agorda dosiero de WildMidi,Archivo de config. WildMidi,,WildMidi-config-tiedosto,Fichier config. WildMidi,WildMidi konfigurációs fájl,File WildMidi config,WildMidi コンフィグファイル,WildMidi 코딩 파일,WildMidi configuratiebestand,WildMidi konfigurasjonsfil,Plik konfiguracyjny WildMidi,Arquivo de configuração do WildMidi,,Fișier configurație WildMidi,Файл конфигурации WildMidi,WildMidi конфигурациона датотека,WildMidi-konfigurationsfil,WildMidi yapılandırma dosyası,Файл конфігурації WildMidi, +Select configuration,ADVSNDMNU_SELCONFIG,,,,Vybrat konfiguraci,Vælg konfiguration,Konfiguration wählen,,Elekti agordojn,Seleccionar configuración,,Valitse kokoonpano,Sélectionner configuration,Konfiguráció kiválasztása,Seleziona la configurazione,構成選択,설정을 고르시오,Selecteer configuratie,Velg konfigurasjon,Wybierz konfigurację,Selecionar configuração,,Selectare configurație,Выбор конфигурации,Изабери конфигурацију,Välj konfiguration,Yapılandırma seçin,Вибір конфігурації, +Advanced Resampling,ADVSNDMNU_ADVRESAMPLING,,,,Pokročilé převzorkování,Avanceret resampling,Erweitertes Resampling,,Altnivela respecimenado,Resampleo avanzado,,Kehittynyt näytteenottotaajuuden muuntaminen,Resampling Avancé,Fejlett Resmapling,Resampling avanzato,高度なリサンプリング,향상된 리샘플링,Geavanceerde herbemonstering,Avansert resampling,Zaawansowane Próbkowanie,Reamostragem avançada,,Resempling avansat,Продвинутый ресэмплинг,Напредно ресампловање,Avancerad återampling,Gelişmiş Yeniden Örnekleme,Розширений ресемплінг, +OPL Bank,ADVSNDMNU_OPLBANK,,,,OPL sada,,,,Banko por OPL,Banco OPL,,OPL-pankki,Banque OPL,,,,OPL 뱅크,,,Bank OPL,Banco OPL,,Bancă OPL,Банк OPL,OPL банка,OPL-bank,,Банк OPL, +OPL Emulator Core,ADVSNDMNU_ADLOPLCORES,,,,Emulační jádro OPL,OPL-emulatorkerne,OPL Emulatorkern,,Imitilkerno por OPL,Núcleos de emulador OPL,,OPL-emulaattoriydin,Cœur Emulateur OPL,OPL emulátor mag,,OPL エミュレートコア,OPL 에뮬레이터 코어,OPL Emulator Kern,OPL-emulatorkjerne,Rdzeń Emulatora OPL,Núcleo do emulador de OPL,,Nucleu de emulare OPL,Ядро эмуляции OPL,OPL емулационо језгро,OPL-emulatorns kärna,OPL Emülatör Çekirdeği,Ядро емуляції OPL, +Run emulator at PCM rate,ADVSNDMNU_RUNPCMRATE,,,,Emulátor používá PCM vzorkovací frekvenci,Kør emulator ved PCM-hastighed,Emulator benutzt PCM Samplerate,,Kurigi imitilon laŭ rapido de PCM,Ejecutar emulador a velocidad PCM,,Aja emulaattoria PCM-taajuudella,Emulateur utilise cadence PCM,Emulátor futtatása PCM rátán,Esegui l'emulatore con rate PCM,PCMレートでエミュレート実行,PCM 속도로 에뮬레이터 실행,Emulator maakt gebruik van PCM Samplerate,Kjør emulator med PCM-hastighet,Uruchom emulator w częstotliwości PCM,Rodar emulador em taxa PCM,,Utilizare cu frecvența PCM,Использовать с частотой PCM,Покрени емулацију на PCM стопи,Kör emulatorn med PCM-frekvens,Emülatörü PCM hızında çalıştırın,Використовувати з частотою PCM, +Number of emulated OPL chips,ADVSNDMNU_ADLNUMCHIPS,,,,Počet emulovaných OPL čipů,Antal emulerede OPL-chips,Anzahl OPL Chips,,Numbro da imitaj OPL-blatoj,Número de chips OPL emulados,,Emuloitavien OPL-piirien lukumäärä,Puces OPL émulées,Emulált OPL csipek száma,Numero di chip OPL emulati,OPLチップエミュレートの番号,에뮬레이트된 OPL 칩 개수,Aantal geëmuleerde OPL chips,Antall emulerte OPL-brikker,Liczba emulowanych czipów OPL,Número de chips OPL emulados,,Număr de cipuri GUS emulate,Количество эмулируемых чипов OPL,Број емулираних OPL чипова,Antal emulerade OPL-chips,Taklit edilen OPL çiplerinin sayısı,Кількість емульованих OPL-чіпів, +Volume model,ADVSNDMNU_VLMODEL,,,,Model hlasitosti,Volumenmodel,Lautstärkemodell,,Modelo de laŭteco,Modelo de volumen,,Äänenvoimakkuusmalli,Modèle de Volume,Hangmodell,Modello di volume,音量モデル,모델 볼륨,Volume model,Volummodell,Model głośności,Modelo de volume,,Model volum,Модель громкости,Волумски модел,Volymmodell,Hacim modeli,Модель гучності, +OPN2 Emulator Core,ADVSNDMNU_OPNCORES,,,,Emulační jádro OPN2,OPN2-emulatorkerne,OPN2 Emulatorkern,,OPN2 Imitilkerno,Núcleo de emulador OPN2,,OPN2-emulaattoriydin,Cœur émulateur OPN2,OPN2 Emulátor Mag,,OPN2 エミュレート コア,OPN2 에뮬레이터 코어,OPN2 Emulatorkern van de OPN2-emulator,OPN2 Emulatorkjerne,Rdzeń Emulatora OPN2,Núcleo do emulador de OPN2,,Nucleu de emulare OPN2,Ядро эмуляции OPN2,OPN2 језгро емулације,OPN2-emulatorkärna,OPN2 Emülatör Çekirdeği,Ядро емуляції OPN2, +GUS Emulation,ADVSNDMNU_GUSEMULATION,,,,Emulace GUS,GUS-emulering,GUS Emulation,,GUS Imitado,Emulación GUS,,GUS-emulaatio,Emulation GUS,GUS Emuláció,,GUS エミュレーション,GUS 에뮬레이션,GUS-emulatie,GUS-emulering,Emulacja GUS,Emulação de GUS,,Emulare GUS,Эмуляция GUS,GUS емулација,GUS-emulering,GUS Emülasyonu,Емуляція GUS, +GUS config file,ADVSNDMNU_GUSCONFIG,,,,Konfigurační soubor GUS,GUS-konfigurationsfil,GUS Konfigurationsdatei,,Agorda dosiero de GUS,Archivo de config. GUS,,GUS-config-tiedosto,Fichier Config. GUS,GUS konfigurációs fájl,File GUS config,GUS コンフィグファイル,GUS 코딩 파일,GUS-configuratiebestand,GUS konfigurasjonsfil,Plik konfiguracyjny GUS,Arquivo de configuração do GUS,,Fișier configurație GUS,Файл конфигурации для GUS,GUS конфигурациона датотека,GUS-konfigurationsfil,GUS yapılandırma dosyası,Файл конфігурації для GUS, +Read DMXGUS lumps,ADVSNDMNU_DMXGUS,,,,Načíst DMXGUS soubory,Læs DMXGUS-klumper,Lese DMXGUS,,Legi DMXGUS Masojn,Leer archivos DMXGUS,,Lue DMXGUS-tietoja,Lire fichiers DMXGUS,DMXGUS lumpok beolvasása,Leggi i lump DMXGUS,DMXGUS ランプを読む,DMXGUS 럼프 읽기,DMXGUS-klonten lezen,Les DMXGUS-filer,Czytaj pliki DMXGUS,Ler lumps DMXGUS,,Citire fișiere DMXGUS,Читать файлы DMXGUS,Читај DMXGUS фајлове,Läsa DMXGUS-filer,DMXGUS dosyalarını okuma,Читати файли DMXGUS, +GUS memory size,ADVSNDMNU_GUSMEMSIZE,,,,Velikost paměti GUS,GUS-hukommelsesstørrelse,GUS Speichergröße,,GUS Memorampleksoj,Tamaño de memoria de GUS,,GUS-muistikoko,Taille mémoire GUS,GUS memória mérete,Dimensione della memoria per GUS,GUS メモリーサイズ,GUS 메모리 크기,GUS-geheugengrootte,GUS-minne størrelse,Rozmiar pamięci GUS,Tamanho de memória do GUS,,Memorie alocată pentru GUS,Размер памяти GUS,GUS величина памћења,GUS minnesstorlek,GUS bellek boyutu,Розмір пам'яті GUS, +Number of emulated OPN chips,ADVSNDMNU_OPNNUMCHIPS,,,,Počet emulovaných OPN čipů,Antal emulerede OPN-chips,Anzahl OPN Chips,,Nombro da imititaj OPL-blatoj,Número de chip OPN emulados,,Emuloitavien OPN-piirien lukumäärä,Puces OPN émulées,Emulált OPL csipek száma,Numero di chip OPN emulati,OPNチップエミュレートの番号,에뮬레이트된 OPN 칩 개수,Aantal geëmuleerde OPL chips,Antall emulerte OPN-brikker,Liczba emulowanych czipów OPN,Número de chips OPN emulados,,Număr de cipuri OPN emulate,Количество эмулируемых чипов OPN,Број емулираних OPN чипова,Antal emulerade OPN-chips,Taklit edilen OPN çiplerinin sayısı,Кількість емульованих OPN-чіпів, +Use custom WOPL bank,ADVSNDMNU_ADLCUSTOMBANK,,,,Použít vlastní WOPL sadu,Brug af brugerdefineret WOPL-bank,Benutzerdefinierte WOPL Bank,,Uzi laŭmendan WOPL-bankon,Utilizar banco WOPL personalizado,,Käytä mukautettua WOPL-pankkia,Utiliser Banque WOPL perso,Saját WOPL bank használata,Usa WOPL bank personalizzato,カスタムWOPL bankを使用,사용자 지정 WOPL 뱅크 사용,Gebruik de aangepaste WOPL bank,Bruk egendefinert WOPL-bank,Użyj niestandardowego banku WOPL,Usar banco WOPL personalizado,,Utilizați propriul bank WOPN,Использовать собственный банк WOPL,Користи прилагођенуу WOPL банку,Använd anpassad WOPL-bank,Özel WOPL bankası kullanın,Використовувати власний банк WOPL, +WOPL Bank file,ADVSNDMNU_OPLBANKFILE,,,,Soubor WOPL sady,WOPL Bank-fil,WOPL Bank-Datei,,WOPL-Bankodosiero,Archivo de banco WOPL,,WOPL-pankkitiedosto,Banque WOPL,WOPL Bank fájl,File WOPL Bank,WOPL bankファイル,WOPL 뱅크 파일,WOPL Bank-bestand,WOPL Bank-fil,Plik banku WOPL,Banco WOPL,,Fișier WOPN bank,Файл с банком WOPL,WOPL фајл банка,WOPL Bank-fil,WOPL Bank dosyası,Файл з банком WOPL, +Use custom WOPN bank,ADVSNDMNU_OPNCUSTOMBANK,,,,Použít vlastní WOPN sadu,Brug af brugerdefineret WOPN-bank,Benutzerdefinierte WOPN Bank,,Uzi laŭmendan WOPN-bankon,Utilizar banco WOPN personalizado,,Käytä mukautettua WOPN-pankkia,Utiliser Banque WOPN perso,Saját WOPN bank használata,Usa WOPN bank personalizzato,カスタムWOPN bankを使用,사용자 지정 WOPN 뱅크 사용,Gebruik aangepaste WOPN-bank op maat,Bruk egendefinert WOPN-bank,Użyj niestandardowego banku WOPN,Usar banco WOPN personalizado,,Utilizați propriul bank WOPN,Использовать собственный банк WOPN,Користи прилагођену WOPN банку,Använd anpassad WOPN-bank,Özel WOPN bankası kullanın,Використовувати власний банк WOPN, +WOPN Bank file,ADVSNDMNU_OPNBANKFILE,,,,Soubor WOPN sady,WOPN Bank-fil,WOPN Bank-Datei,,WOPN-Bankodosiero,Archivo de banco WOPN,,WOPN-pankkitiedosto,Banque WOPN,WOPN Bank fájl,File WOPN Bank,WOPN bankファイル,WOPN 뱅크 파일,WOPN Bank-bestand,WOPN-bankfil,Plik banku WOPN,Banco WOPN,,Fișier WOPN bank,Файл с банком WOPN,WOPN фајл банка,WOPN Bank-fil,WOPN Banka dosyası,Файл з банком WOPN, +Aliasing,OPTVAL_ALIASING,,,,,,,,Krenelaro,,,,,,,エイリアシング,에일리어싱,,,,,,Dedublare,Сглаживание,Преклапање,,Takma Adlandırma,Згладжування, +Linear,OPTVAL_LINEAR_1,This setting is duplicated threefold in order to allow for different grammatical gender endings,,,Lineární,Lineær,,,Lineara,Lineal,,Lineaarinen,Linéaire,Lineáris,Lineare,リニア,선형,Lineair,Lineær,Liniowy,,,Liniar,Линейное,Линеаран,Linjär,Doğrusal,Лінійне, +Linear,OPTVAL_LINEAR_2,,,,Lineární,Lineær,,,Lineara,Lineal,,Lineaarinen,Linéaire,Lineáris,Lineare,リニア,선형,Lineair,Lineær,Liniowa,,,Liniar,Линейная,Линеаран,Linjär,Doğrusal,Лінійна, +Linear,OPTVAL_LINEAR_3,,,,Lineární,Lineær,,,Lineara,Lineal,,Lineaarinen,Linéaire,Lineáris,Lineare,リニア,선형,Lineair,Lineær Lineær,Liniowe,,,Liniar,Линейный,Линеаран,Linjär,Doğrusal,Лінійний, +Nearest,OPTVAL_NEAREST,,,,Nejbližší,Nærmeste,Nächster Nachbar,,Plej proksima,Cercano,,Lähin,Nearest,Legközelebbi,Il più vicino,最寄り,가까이,Naast,Nærmeste,Najbiższe,Mais próximo,,Cel mai apropriat,Ближайший,Најближе,Närmaste,En yakın,Найближчий, +PCF (Low),OPTVAL_PCF_LOW,,,,PCF (nízké),PCF (lav),PCF (niedrig),,PCF (Malalta),PCF (Bajo),,PCF (matala),PCF (Low),PCF (Alacsony),PCF (basso),PCF (低),PCF (하급),PCF (Laag),PCF (lav),PCF (Niski),PCF (Baixo),,PCF (Scăzut),PCF (низкий),PCF (ниско),PCF (låg),PCF (Düşük),PCF (низький), +PCF (Medium),OPTVAL_PCF_MEDIUM,,,,PCF (střední),PCF (medium),PCF (mittel),,PCF (Meza),PCF (Medio),,PCF (keskitaso),PCF (Medium),PCF (Közepes),PCF (medio),PCF (中),PCF (중급),,PCF (middels),PCF (Średni),PCF (Médio),,PCF (Mediu),PCF (средний),PCF (средње),PCF (medelhög),PCF (Orta),PCF (средній), +PCF (High),OPTVAL_PCF_HIGH,,,,PCF (vysoké),PCF (høj),PCF (hoch),,PCF (Alta),PCF (Alto),,PCF (korkea),PCF (High),PCF (Magas),PCF (alto),PCF (高),PCF (상급),PCF (Hoog),PCF (høy),PCF (Wysoki),PCF (Alto),,PCF (Ridicat),PCF (высокий),PCF (високо),PCF (hög),PCF (Yüksek),PCF (високий), +Cubic,OPTVAL_CUBIC,,,,Kubická,Kubisk,Kubisch,,Kuba,Cúbico,,Kuutio,Cubique,Négyzetes,Cubico,キュービック,큐빅,Kubieke,Kubisk,Sześcienny,Cúbico,,Cub,Кубическое,Кубан,Kubisk,Kübik,Кубічне, +Band-limited step,OPTVAL_BLEP,,,,Omezené krokování,Båndbegrænset trin,Bandbegrenzte Schritte,,Bendo-limigita paŝo,Paso limitado por banda,,Kaistarajoitettu askel,Step limité par bande,Sáv-limitált lépés,Passo limitato dalla banda,帯域制限ステップ,제한된 단계별 밴드,Bandbeperkte stap,Båndbegrenset trinn,Krok ograniczony pasmem,Passo limitado por banda,,Limitare frecvență pas-cu-pas,Ограниченный полосой пропускания шаг,Постепено ограничење фреквенције,Bandbegränsat steg,Bant sınırlı adım,Покрокове обмеження частоти, +Linear (Slower),OPTVAL_LINEARSLOW,,,,Lineární (pomalejší),Lineær (langsommere),Linear (langsamer),,Lineara (Pli malrapida),Lineal (más lento),,Lineaarinen (hitaampi),Linéaire (Lent),Lineáris (Lassabb),Lineare (più lento),リニア(遅め),선형 (느리게),Lineair (langzamer),Lineær (langsommere),Liniowy (wolniejszy),Linear (mais lento),,Liniar (Mai lent),Линейное (медленнее),Линеаран (спорије),Linjär (långsammare),Doğrusal (Daha Yavaş),Лінійне (повільніше), +Band-limited linear,OPTVAL_BLAM,,,,Omezená lineární,Båndbegrænset lineær,Bandbegrenzt linear,,Bendo-limigita lineara,Lineal limitado por banda,,Kaistarajoitettu lineaarinen,Linéaire limité par bande,Sáv-limitált lineáris,Lineare limitato dalla banda,帯域制限リニア,밴드 제한 식 선형,Band-beperkt lineair,Båndbegrenset lineær,Liniowy ograniczony pasmem,Linear limitado por banda,,Limitare frecvență liniară,Ограниченное полосой пропускания линейное,Линеарно ограничење фреквенције,Bandbegränsad linjär,Bant sınırlı doğrusal,Лінійне обмеження частоти, +Cubic (Slower),OPTVAL_CUBICSLOW,,,,Kubická (pomalejší),Kubisk (langsommere),Kubisch (langsamer),,Kuba (Pli malrapida),Cúbico (más lento),,Kuutio (hitaampi),Cubique (Lent),Négyzetes (Lassabb),Cubico (più lento),キュービック (遅め),큐빅 (느리게),Kubieke (langzamer),Kubisk (langsommere),Sześcienny (wolniejszy),Cúbico (mais lento),,Cub (Mai lent),Кубическое (медленнее),Кубан (спорије),Kubisk (långsammare),Kübik (Daha Yavaş),Кубічне (повільніше), +Sinc,OPTVAL_SINC,,,,,Sinc,,,,Seno cardinal,,,,,,シンク,싱크,,,,Seno cardinal,,Sinus cardinal,Кардинальный синус,Синк,,,Функція sinc, +Note on/off only,OPTVAL_NOTEONOFFONLY,,,,Pouze začátek/konec noty,Kun note on/off,Nur für Note an/aus ,,Nur noto ek/for,Solo notas de Activ./Desact.,,Vain nuotti päällä/pois,Note on/off seulement,Hangjegy ki/be csak,Note solamente ON/OFF,ノート オン/オフ のみ,노트를 끄거나 켰을 때,Alleen toon aan/uit,Merk kun på/av,Tylko dla włączonych/wyłączonych notatek,Somente notas ligadas/desligadas,,Numai la activarea/oprirea notelor,Только при включении/отключении нот,Само током укључења/искључења ноте,Endast anteckning på/av,Yalnızca not açma/kapama,Тільки при ввімкненні/вимкненні нот, +Full ramping,OPTVAL_FULLRAMPING,,,,Plný náběh,Fuld rampe,,,Plena pligrandigado,Aumento completo,,Täysi kerrytys,Rampe complète,Teljes ramping,Ramping completo,フルランピング,최대 램핑,Volledige helling,,Pełne zwiększenie,Rampa completa,,Creștere completă,Полное наращивание,Пуно појачање,Full rampning,Tam rampa,Повне нарощування, +Master volume,MODMNU_MASTERVOLUME,,,,Celková hlasitost,Master-volumen,Grundlautstärke,,Ĉeflaŭteco,Volumen maestro,,Yleisäänenvoimakkuus,Volume maître,Fő hangerő,Volume master,全体音量,마스터 볼륨,Hoofdvolume,Hovedvolum,Całkowita głośność,Volume geral,,Volum general,Общая громкость,Глацни звук,Huvudvolym,Ana ses seviyesi,Загальна гучність, +Quality,MODMNU_QUALITY,,,,Kvalita,Kvalitet,Qualität,,Kvaliteco,Calidad,,Laatu,Qualité,Minőség,Qualità,クオリティ,품질,Kwaliteit,Kvalitet,Jakość,Qualidade,,Calitate,Качество,Квалитет,Kvalitet,Kalite,Якість, +Volume ramping,MODMNU_VOLUMERAMPING,,,,Křivka hlasitosti,Lydstyrke-rampe,Lautstärkeverhalten,,Laŭteco-pligrandigado,Aumento gradual de Volumen,,Äänenvoimakkuuden kertyminen,Rampe du volume,,Ramping volume,音量ランピング,볼륨 램핑,Volume-aanvulling,Volumramping,Zwiększenie głośności,Rampa de volume,,Creștere volum,Наращивание громкости,Појачавање звука,Volymrampning,Hacim artırma,Нарощування гучності, +Chip-o-matic,MODMNU_CHIPOMATIC,,,,,,,,,,,,,,,チップ オー マチック,칩-오-매틱,,,,,,,,,,,, +MAME OPL2,OPTVAL_MAMEOPL2,,,,,,,,,,,,,,,,마메 OPL2,,,,,,,,,,,, +DOSBox OPL3,OPTVAL_DOSBOXOPL3,,,,,,,,,,,,,,,,도스박스 OPL3,,,,,,,,,,,, +Java OPL3,OPTVAL_JAVAOPL3,,,,,,,,,,,,,,,,자바 OPL3,,,,,,,,,,,, +Nuked OPL3,OPTVAL_NUKEDOPL3,,,,,,,,,,,,,,,,,,,,,,,,,,,, +MAME YM2612,OPTVAL_MAMEOPN2,,,,,,,,,,,,,,,,마메 YM2612,,,,,,,,,,,, +Neko Project II Kai OPNA,OPTVAL_NP2OPNA,,,,,,,,,,,,,,,,,,,,,,,,,,,, +MAME YM2608,OPTVAL_MAMEOPNA,,,,,,,,,,,,,,,,마메 YM2608,,,,,,,,,,,, +PMDWin OPNA,OPTVAL_PMDWINOPNA,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Opal OPL3,OPTVAL_OPALOPL3,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Nuked OPL3 v1.7.4,OPTVAL_NUKEDOPL3174,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Nuked OPN2,OPTVAL_NUKEDOPN2,,,,,,,,,,,,,,,,,,,,,,,,,,,, +GENS YM2612,OPTVAL_GENSOPN2,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Auto (Use setup of bank),ADLVLMODEL_AUTO,,,,Auto (použít nastavení sady),Auto (Brug opsætning af bank),Auto (Benutze Einstelliung der Bank),,Aŭtomata (Uzi bankagordaĵon),Auto (Usar config. del banco),,Automaattinen (käytä pankin asetuksia),Auto (Utiliser paramètre banque),Automatikus (Beállított bank használata),Automatico (Usa le impostazioni del bank),自動(bankのセットアップ使用),자동(뱅크 셋업 사용),Auto (gebruik instelling van de bank),Auto (Bruk oppsett av bank),Automatycznie (Użyj ustawień banku),Automático (usar definições de banco),,Auto (configurare din bancă),Авто (настройка из банка),Аутоматски (користи намештену банку),Auto (använder bankens inställning),Otomatik (Banka kurulumunu kullan),Авто (налаштування з банку), +Generic,ADLVLMODEL_GENERIC,,,,Standardní,Generisk,Allgemein,,Komuna,Genérico,,Yleinen,Générique,Általános,Generico,一般的,전형적,Algemeen,Generisk,Ogólne,Genérico,,,Общий,Генерично,Generisk,Jenerik,Загальний, +OPL Native,ADLVLMODEL_NATIVE,,,,Nativní OPL,OPL Native,OPL Nativ,,Nativa OPL,Nativo OPL,,Luontainen OPL,OPL Natif,Natív OPL,,OPLネイティブ,고유 OPL,,,Natywne OPL,Nativo OPL,,OPL propriu,Встроенная OPL,OPL домаћи,OPL inhemsk,OPL Yerli,Вбудована OPL, +"DMX (Accurate, with AM bug)",ADLVLMODEL_DMX,,,,"DMX (Přesný, s AM chybou)","DMX (nøjagtig, med AM-fejl)",,,,,,,,"DMX (Pontos, de AM buggal)",,,데이터 마이닝 확장,"DMX (accuraat, met AM bug)","DMX (Nøyaktig, med AM-feil)",,"DMX (preciso, com bug de AM)",,"DMX (Precis, cu probleme în AM)","DMX (Точная, с ошибкой АМ)",,"DMX (exakt, med AM-bugg)","DMX (Doğru, AM hatalı)","DMX (Точна, з помилкою АМ)", +"Apogee (Accurate, with AM bug)",ADLVLMODEL_APOGEE,,,,"Apogee (Přesný, s AM chybou)","Apogee (nøjagtig, med AM-fejl)",,,,,,,,"Apogee (Pontos, de AM buggal)",,,어포지,"Apogee (accuraat, met AM bug)","Apogee (Nøyaktig, med AM-feil)",,"Apogee (preciso, com bug de AM)",,"Apogee (Precis, cu probleme în AM)","Apogee (Точная, с ошибкой АМ)",,"Apogee (Exakt, med AM-bugg)","Apogee (Doğru, AM hatası ile)","Apogee (Точна, з помилкою АМ)", +Win9X-like (SB16),ADLVLMODEL_WIN9X,,,,Jako Windows 9X (SB16),Win9X-lignende (SB16),Wie Windows 9X (SB16),,Kiel Win9X (SB16),Como Win9X (SB16),,Win9x-kaltainen (SB16),,Win9X szerű (SB16),,Win9X式 (SB16),Win9X 같게 (SB16),Win9X-achtig (SB16),Win9X-lignende (SB16),Jak w Win9X (SB16),Estilo Win9X (SB16),,Similar cu Win9X (SB16),Похожая на Win9X (Вариант SB16),Као у Win9X-у (SB16),Win9X-liknande (SB16),Win9X benzeri (SB16),Схожа на Win9X (Варіант SB16), +Win9X-like (Generic FM),ADLVLMODEL_WIN9XGENERIC,,,,Jako Windows 9X (Generic FM),Win9X-lignende (generisk FM),Wie Windows 9X (Generic FM),,Kiel Win9X (Generic FM),Como Win9X (Generic FM),,Win9x-kaltainen (Generic FM),,Win9X szerű (Általános FM),,Win9X式 (Generic FM),Win9X 같게 (Generic FM),Win9X-achtig (Generic FM),Win9X-lignende (Generisk FM),Jak w Win9X (Generic FM),Estilo Win9X (FM genérico),,Similar cu Win9X (Generic FM),Похожая на Win9X (Вариант Generic FM),Као у Win9X-у (Generic FM),Win9X-liknande (generisk FM),Win9X benzeri (Jenerik FM),Схожа на Win9X (Варіант Generic FM), +DMX (Without AM voice bug),ADLVLMODEL_DMX_FIXED,,,,DMX (Bez AM hlasové chyby),DMX (uden AM-stemmefejl),DMX (Ohne AM-Stimmenfehler),,DMX (Sen cimo de AM-voĉo),DMX (Sin bug de voz AM),,DMX (ilman AM-äänivikaa),DMX (Sans bug canaux AM),DMX (AM hanghiba nélkül),,DMX(AMボイスバグ無し),,DMX (zonder AM voice bug),DMX (uten AM-stemmefeil),DMX (bez głosowego błędu AM),DMX (sem bug de voz de AM),,DMX (Fără probleme în AM),DMX (Без ошибки АМ),,DMX (utan AM-röstfel),DMX (AM ses hatası olmadan),DMX (Без помилки АМ), +Apogee (Without AM voice bug),ADLVLMODEL_APOGEE_FIXED,,,,Apogee (Bez AM hlasové chyby),Apogee (uden AM-stemmefejl),Apogee (Ohne AM-Stimmenfehler),,Apogee (Sen cimo de AM-voĉo),Apogee (Sin bug de voz AM),,Apogee (ilman AM-äänivikaa),Apogee (avec bug canaux AM),Apogee (AM hanghiba nélkül),,Apogee(AMボイスバグ無し),,Apogee (zonder AM voice bug),Apogee (uten AM-stemmefeil),Apogee (bez głosowego błędu AM),Apogee (sem bug de voz de AM),,Apogee (Fără probleme în AM),Apogee (Без ошибки АМ),,Apogee (utan AM-röstfel),Apogee (AM ses hatası olmadan),Apogee (Без помилки АМ), +IBM Audio Library Interface,ADLVLMODEL_AIL,,,,,,,,IBM Aŭdbibiloteka Interfaco,,,,,IBM Hang Könyvtár Interfész,,,,,,Interfejs Biblioteki Dźwięków IBM,Interface de Biblioteca de Áudio IBM,,Interfață de Bibliotecă IBM,IBM AIL,,IBM Audio Library Interface (gränssnitt för ljudbibliotek),IBM Ses Kitaplığı Arayüzü,, +HMI Sound Operating System,ADLVLMODEL_HMI,,,,,,,,HMI Sonoperaciumo,,,,,HMI Hang Operációs Rendszer,,,,,,System Operacyjny Dźwięków HMI,Sistema Operacional de Som HMI,,Sistem Sonor HMI,HMI SOS,,HMI-ljud Operativsystem,HMI Ses İşletim Sistemi,, +"HMI SOS (Old, with bugs)",ADLVLMODEL_HMIOLD,,,,"HMI SOS (Starý, s chybami)","HMI SOS (gammelt, med fejl)","HMI SOS (alt, mit Fehlern)",,"HMI SOS (Malnova, kun cimoj)","HMI SOS (Viejo, con bugs)",,"HMI SOS (vanha, vikainen)",HMI SOS (vieux et buggé),"HMI SOS (Régi, bugokkal)",,"HMI SOS(旧式,バグ含む)",,"HMI SOS (oud, met bugs)","HMI SOS (gammel, med feil)","HMI SOS (Stare, z błędami)","SOS HMI (antigo, com bugs)",,"HMI SOS (Vechi, cu probleme)",HMI SOS (Старый вариант с ошибками),,"HMI SOS (gammalt, med fel)","HMI SOS (Eski, hatalı)",HMI SOS (Старий варіант з помилками), +Unlimited,OPTVAL_UNLIMITED,,,,Neomezené,Ubegrænset,Unlimitiert,,Senlima,Ilimitado,,Rajoittamaton,Illimité,Végtelen,Illimitato,無制限,무제한,Onbeperkt,Ubegrenset,Nieskończone,Sem limites,,Nelimitat,Без ограничений,Бескрајно,Obegränsad,Sınırsız,Безмежно, +256K,OPTVAL_256K,,,,,,,,,,,,,,,,,,,,,,,,,,,, +512K,OPTVAL_512K,,,,,,,,,,,,,,,,,,,,,,,,,,,, +768K,OPTVAL_768K,,,,,,,,,,,,,,,,,,,,,,,,,,,, +1024K,OPTVAL_1024K,,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,Postprocessing,,,,,,,,,,,,,,,,,,,,,,,,,,, +Uncharted 2,OPTVAL_UNCHARTED2,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Hejl Dawson,OPTVAL_HEJLDAWSON,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Reinhard,OPTVAL_REINHARD,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Palette,OPTVAL_PALETTE,,,,Paleta,Palet,,Παλέτα,Paletro,Paleta,,Paletti,,Paletta,Palette,パレット,팔레트,Palet,,Paleta,Paleta,Palete,Paletă,Палитра игры,Палет,Palett,Palet,Палітра гри, +Low,OPTVAL_LOW,,,,Nízká,Lav,Niedrig,Χαμηλό,Malalta,Bajo,,Matala,Bas,Alacsony,Basso,低,낮음,Laag,Lav,Niskie,Baixo,,Scăzut,Низкое,Ниско,Låg,Düşük,Низьке, +Medium,OPTVAL_MEDIUM,,,,Střední,,Mittel,Μεσαίο,Meza,Medio,,Keskitaso,Moyen,Közepes,Medio,中,중간,Middel,Middels,Średnie,Médio,,Mediu,Среднее,Средње,Medelstor,Orta,Середнє, +High,OPTVAL_HIGH,,,,Vysoká,Høj,Hoch,Υψηλό,Alta,Alto,,Korkea,Elevé,Magas,Alto,高,높음,Hoog,Høy,Wysokie,Alto,,Ridicat,Высокое,Високо,Hög,Yüksek,Високе, +Extreme,OPTVAL_EXTREME,,,,Extrémní,Ekstrem,Extrem,Ακράιο,Ekstrema,Extremo,,Äärimmäinen,Extrême,Extrém,Estremo,最高,매우 높음,Extreem,Ekstrem,Ekstremalne,Extremo,,Extrem,Максимальное,Екстремно,Extremt,Aşırı,Максимальне, +Obverse,OPTVAL_OBVERSEFIRST,,,,Vpřed (obvers),Forside,Obvers,Παρατήρησε,Antaŭa,Anverso,,Etupuoli,,Ellentétes,Dritto,正面,앞면,Obvers,Forside,Awers,Obverso,,Avers,Прямой,Супротно,Framsida,Ön yüz,Прямий, +Reverse,OPTVAL_REVERSEFIRST,,,,Vzad (revers),Bagside,Revers,Αντίστροφο,Inversa,Inverso,,Käänteinen,Inverse,Fordított,Contrario,反転,반전,Revers,Baksiden,Rewers,Reverso,,Invers,Обратный,Обрнуто,Baksida,Ters,Зворотний, +Postprocessing,GLMNU_POSTPROCESS,,,,,Efterbehandling,,Μετα-επεξεργασία,Postprocezado,Postprocesado,,Jälkikäsittely,,,,ポストプロセッシング,포스트프로세싱 적용,Nabewerking,Etterbehandling,Przetwarzanie końcowe,Pós-processamento,,Postprocesare,Постобработка,Пост обрада,Efterbehandling,İşlem sonrası,Постобробка, +Tonemap Mode,GLPREFMNU_TONEMAP,,,,Režim tónovací mapy,Tonemap-tilstand,Tonemap Modus,,Reĝimo de Tonmapo,Modo de mapa de tonos,,Sävykarttatila,Mode Tonemap,Színleképzés módja,Modalità Tonemap,トーンマップ モード,톤맵 모드,Tonemap modus,Tonemap-modus,Tryb Mapowania Tonów,Tipo de tonemap,,Mod Tonemap,Режим тонового отображения,Тонирано-мапни мод,Tonemap-läge,Ton Haritası Modu,Режим тонального відображення, +Lens distortion effect,GLPREFMNU_LENS,,,,Efekt distorze čočky,Objektivforvrængningseffekt,Optischer Verzerrungseffekt,,Lensdistorto-efiko,Efecto de distorsión de lente,,Linssinvääristystehoste,Effet distorsion de lentille,Lencsetorzulás effekt,Effetto distorsione della lente,レンズの歪みエフェクト,렌즈 왜곡 효과,Effect van de lensvervorming,Linseforvrengningseffekt,Efekt zniekształcenia obiektywu,Distorção de lente,Efeito de distorção da lente,Efect de distorsionare,Эффект искажения линзы,Дисторзија објектива ефект,Linsförvrängningseffekt,Lens bozulma efekti,Ефект деформації лінзи, +FXAA Quality,GLPREFMNU_FXAA,,,,Kvalita FXAA,FXAA-kvalitet,FXAA Qualität,FXAA ποίοτητα,Kvaliteco de FXAA,Calidad FXAA,,FXAA-laatu,Qualité FXAA,FXAA minősége,Qualità FXAA,FXAA品質,FXAA 품질,FXAA-kwaliteit,FXAA-kvalitet,Jakość FXAA,Qualidade de FXAA,,Calitate FXAA,Качество FXAA,FXAA квалитет,FXAA-kvalitet,FXAA Kalitesi,Якість FXAA, +Dither output,GLPREFMNU_DITHER,,,,Dithering,Dither-udgang,Dithering,,Apliki punktojn al eligo,Dither de salida,,Sekoitussävytyksen (dithering) ulostulo,Dithering,Árnyalás kimenet,Dithering,ディザー出力,떨림 효과 출력,Dither output,Dither-utgang,Dygotanie,Dithering,,Putere Dithering,Дизеринг,Учестаност трептања,Dither-utgång,Dither çıkışı,Дитеринг, +Tonemap Palette Order,GLPREFMNU_PALTONEMAPORDER,,,,Pořadí palety tónovací mapy,Tonemap-palettens rækkefølge,Palettensortierung für Tonemap,,Ordo de Kolormapo-Paletro,Orden de la paleta en mapa de tonos,,Sävykartan paletin järjestys,Ordre des palettes tonemap,Színleképzés paletta sorrend,Ordine della Palette Tonemap,トーンマップパレット順序,톤맵 팔레트 순서,Tonemap Palet Orde van het Tonemap-palet,Tonemap-palettrekkefølge,Kolejność Palet Mapowania Tonów,Ordem da paleta tonemap,,Ordine paletă Tonemap,Порядок палитры тонового отображения,Тонирано-мапни палетни ред,Tonemappalettordning,Ton Haritası Palet Sırası,Порядок палітри тонального відображення, +Tonemap Palette Exponent,GLPREFMNU_PALTONEMAPPOWER,,,,Exponent palety tónovací mapy,Tonemap-palettens eksponent,Palettenexponent für Tonemap,,Exponeto de Kolormapo-Paletro,Exponente paleta en mapa de tonos,,Sävykartan paletin eksponentti,Exponent des palettes tonemap,Tonemap Paletta Exponens,Esponente della Palette Tonemap,トーンマップパレット指数,톤맵 팔레트 지수,Tonemap Palet Exponent,Tonemap Palette Eksponent,Wykładnik Palet Mapowania Tonów,Expoente da paleta tonemap,,Exponent paletă Tonemap,Экспонента палитры тонового отображения,Тонирано-мапни палетни експонент,Exponent för tonemappalett,Ton Haritası Paleti Üsteli,Експонента палітри тонального відображення, +Multisample,GLPREFMNU_MULTISAMPLE,,,,Multisampling,,Multisampling,,Plurspecimeno,Multisampling,,Moninäytteistys,,,,マルチサンプル,멀티샘플,,,Multipróbkowanie,Multiamostragem,,Multisampling,Мультисэмплинг,Мулти-узорак,,Çoklu Örneklem,Багатовибіркове згладжування, +Bloom effect,GLPREFMNU_BLOOM,,,,Efekt bloom,Bloom-effekt,Bloom Effekt,,Lumŝmiro-efiko,Efecto Bloom,,Hehkutehoste (bloom),Effet surbrillance,Bloom effekt,Effetto Bloom,ブルーム エフェクト,블룸 효과,Bloom-effect,Bloom-effekt,Effekt Bloom,Bloom,,Efect Bloom,Свечение,Мутан вид ефект,Bloom-effekt,Çiçeklenme etkisi,Ефект сяйва, +Ambient occlusion quality,GLPREFMNU_SSAO,,,,Kvalita ambient occlusion,Omgivende okklusionskvalitet,Ambient Occlusion Qualität,,Kvaliteco de media obstrukceco,Calidad de oclusión ambiental,,Yleisvarjostuksen (ambient occlusion) laatu,Qualité Occlusion Ambiente,Ambient occlusion minősége,Qualità occlusione ambientale,アンビエント オクルージョンの品質,주변 환경 가림 효과 품질,Kwaliteit van omgevingsverduistering,Omgivende okklusjonskvalitet,Jakość okluzji otoczenia,Qualidade de oclusão de ambiente,,Calitate ocluzie ambientală,Качество глобального затенения,Оклузија амбијента ефект,Kvalitet för omgivande ocklusion,Ortam oklüzyon kalitesi,Якість глобального затінення, +Portals with AO,GLPREFMNU_SSAO_PORTALS,,,,Portály s AO,Portaler med AO,Portale mit AO,,Portaloj kun Media obstrukceco,Portales con OA,,Yleisvarjostuksen portaalit,OA pour les portails,Portálok AO-val,Portali con l'OA,AOを伴うポータル,주변 환경 가려진 포탈,Portals met AO,Portaler med AO,Portale z okluzją otoczenia,Portais com oclusão de ambiente,,Portaluri cu ocluzie ambientală,Порталы с глобальным затенением,Портали са AO,Portaler med omgivande ocklusion,AO'lu Portallar,Портали з глобальним затіненням, +Menu Blur,GLPREFMNU_MENUBLUR,,,,Rozostření pozadí v menu,Menu sløring,Menüunschärfe,Θόλοση μενού,Malklarigo de menuo ,Difuminación de menú,,Valikon sumennus,Flou menu,Menü mosódás,Blur del menu,メニューブラー,메뉴 흐림 효과,Menu vervagen,Meny uskarphet,Rozmycie w Menu,Desfoque do menu,Desfocagem do Menu,Neclaritate Meniu,Размытие фона меню,Блур мениа,Menyns oskärpa,Menü Bulanıklığı,Розмиття фону в меню, +Environment map on mirrors,GLPREFMNU_ENVIRONMENTMAPMIRROR,,,,Mapa prostředí na zrcadlech,Miljøkort på spejle,Lichteffekt auf Spiegeln,,Medimapo sur speguloj,Mapa de entorno en espejos,,Ympäristökartta peileissä,Mappage environment sur les miroirs,Környezet tükröződés,Ambiente mappa sugli specchi,マップオンミラーの画像表示,거울 주변의지도 활성,Milieukaart op spiegels,Omgivelseskart på speil,Mapa środowiska w lustrach,Mapa de ambiente em espelhos,,Efecte suplimentare pentru oglinzi,Карта окружения на зеркалах,Околинска мапа на прозорима,Miljökarta på speglar,Aynalar üzerinde çevre haritası,Карта оточення на дзеркалах, +Rendering quality,GLPREFMNU_RENDERQUALITY,,,,Kvalita vykreslování,Renderingskvalitet,Renderqualität,,Kvalito de bildigado,Calidad de renderizado,,Hahmonnuslaatu,Qualité du rendu,Renderelés minősége,Qualità resa grafica,レンダリング品質,렌더링 품질,Het teruggeven van kwaliteit,Renderingskvalitet,Jakość Renderowania,Qualidade de renderização,,Calitate video,Качество обработки,Квалитет рендовања,Renderingskvalitet,Render kalitesi,Якість візуалізації, +Speed,OPTVAL_SPEED,,,,Rychlost,Hastighed,Geschwindigkeit,Ταχύτητα,Rapido,Velocidad,,Nopeus,Vitesse,Sebesség,Prestazioni,速度寄り,성능,Snelheid,Hastighet,Szybkość,Velocidade,,Viteză,Скорость,Брзина,Hastighet,Hız,Швидкість, +Quality,OPTVAL_QUALITY,,,,Kvalita,Kvalitet,Qualität,Ποιότητα,Kvalito,Calidad,,Laatu,Qualité,Minőség,Qualità,品質寄り,고품질,Kwaliteit,Kvalitet,Jakość,Qualidade,,Calitate,Качество,Квалитет,Kvalitet,Kalite,Якість, +Sector light mode,GLPREFMNU_SECLIGHTMODE,,,,Režim osvětlení sektorů,Sektorlystilstand,Sektorlichtmodus,,Reĝimo de sektorlumo,Modo de luz de sector,,Sektorivalojen tila,Mode de lumière Secteur,Szektor fény mód,Modalità luce di settore,セクターライトモード,섹터 조명 모드,Sector lichte wijze,Sektorlysmodus,Tryb oświetlenia sektorów,Modo de luz de setor,,Mod iluminare sectorială,Режим освещения секторов,Секторско светло мод,Sektorljusläge,Sektör ışığı modu,Режим освітлення секторів, +Fog mode,GLPREFMNU_FOGMODE,,,,Režim mlhy,Tågetilstand,Nebelmodus,Λειτουργία ομίχλης,Reĝimo de nebulo,Modo de niebla,,Sumutila,Mode du broullard,Köd mód,Effetto nebbia,フォグモード,안개 모드,Mistmodus,Tåkemodus,Tryb mgły,Modo de neblina,,Mod ceață,Режим тумана,Магла мод,Dimläge,Sis modu,Режим туману, +Radial,OPTVAL_RADIAL,,,,Radiální,Radial,,Ακτινικό,Radiusa,,,Säteittäinen,,Sugaras,Radiale,放射状,방사형,Radiaal,,Promieniowe,,,Radială,Круговой,Радијално,,Radyal,Радіальний, +Standard,OPTVAL_STANDARD,,,,Standardní,,,,Norma,Estándar,,Normaali,,Szabvány,,標準,기본,Standaard,,,Padrão,,,Стандартный,Стандардно,,Standart,Стандартний, +,,Texture options,,,,,,,,,,,,,,,,,,,,,,,,,,, +Texture Filter mode,GLTEXMNU_TEXFILTER,,,,Režim filtrování textur,Tilstand for teksturfilter,Texturfiltermodus,,Reĝimo por Teksturfiltrado,Modo de filtro de texturas,,Pintakuviointien suodatustapa,Mode de Filtrage Texture,Textúrafilter módja,Modalità filtro texture,テクスチャーフィルター モード,텍스쳐 필터 모드,Textuurfiltermodus,Teksturfilter-modus,Tryb Filtrowania Tekstur,Modo de filtro de textura,,Mod Filtrare Texturi,Фильтрация текстур,Текстурни филтер мод,Texturfilterläge,Doku Filtresi modu,Тип фільтрації текстур, +Anisotropic filter,GLTEXMNU_ANISOTROPIC,,,,Anisotropické filtrování,Anisotropisk filter,Anisotropische Filterung,,Anizotropa filtro,Filtro anisotrópico,,Anisotrooppinen suodatus,Filtre Anisotropique,Anizotropikus filter,Filtro anisotropico,異方性フィルター,이방성 필터,Anisotroopfilter,Anisotropisk filter,Filtr anizotropowy,Filtro anisotrópico,,Filtrare Anizotropică,Анизотропная фильтрация,Анизотропни фолтер,Anisotropt filter,Anizotropik filtre,Анізотропна фільтрація, +None (nearest mipmap),OPTVAL_NONENEARESTMIPMAP,,,,Žádné (mipmapa - nejbližší soused),Ingen (nærmeste mipmap),Aus (nächste Mipmap),,Nenio (plej proksima mipmapo),Ninguno (mipmap cercano),,Ei mitään (lähin mipkartta),Aucun (mipmap proche voisin),Semmilyen (közeli mipmap),Nessuno (mipmap più vicina),なし(最寄りミップマップ),없음 (밉멥에 가까움),Geen (dichtstbijzijnde mipmap),Ingen (nærmeste mipmap),Brak (najbliższa mipmapa),Nenhum (mipmap mais próximo),,Niciuna (mipmap de apropriere),Нет (ближайший MIP-уровень),Ништа (најближи мипмап),Ingen (närmaste mipmap),Yok (en yakın mipmap),Ніякий (найближчий міпмап), +None (linear mipmap),OPTVAL_NONELINEARMIPMAP,,,,Žádné (mipmapa - lineární),Ingen (lineær mipmap),Aus (lineare Mipmap),,Nenio (linia mipmapo),Ninguno (mipmap lineal),,Ei mitään (lin. mipkartta),Aucun (mipmap linéaire),Semmilyen (lineáris mipmap),Nessuno (mipmap lineare),なし(リニアミップマップ),없음 (선형 밉맵),Geen (lineaire mipmap),Ingen (lineær mipmap),Brak (liniowa mipmapa),Nenhum (mipmap linear),,Niciuna (mipmap liniar),Нет (линейный MIP-уровень),Ништа (линеаран мипмап),Ingen (linjär mipmap),Yok (doğrusal mipmap),Ніякий (лінійний міпмап), +None (trilinear),OPTVAL_NONETRILINEAR,,,,Žádné (trilineární),Ingen (trilineær),Aus (trilinear),,Nenio (trilinia),Ninguno (trilineal),,Ei mitään (trilineaarinen),Aucun (mipmap trilinéaire),Semmilyen (trilineáris),Nessuno (mipmap trilineare),なし(トライリニア),없음 (삼선형),Geen (trilineair),Ingen (trilineær),Brak (trzyliniowe),Nenhum (trilinear),,Niciuna (trilinar),Нет (трилинейная),Ништа (трилинеарно),Ingen (trilinjär),Yok (trilineer),Ніякий (трилінійний), +Bilinear,OPTVAL_BILINEAR,,,,Bilineární,Bilineær,,,Dulinia,Bilineal,,Bilineaarinen,Bilinéaire,Bilineáris,Bilineare,バイリニア,쌍선형,Bilineair,Bilineær,Dwuliniowe,,,Biliniar,Билинейная,Билинеарно,Bilinjär,Bilineer,Білінійний, +Trilinear,OPTVAL_TRILINEAR,,,,Trilineární,Trilineær,,,Trilinia,Trilineal,,Trilineaarinen,Trilinéaire,Trilineáris,Trilineare,トライリニア,삼선형,Trilineair,Trilineær,Trzyliniowe,,,Triliniar,Трилинейная,Трилинеарно,Trilinjär,Trilineer,Трилінійний, +2x,OPTVAL_2X,,,,,,,,2-oble,,,,,,,,,,,,,,,,,,,, +4x,OPTVAL_4X,,,,,,,,4-oble,,,,,,,,,,,,,,,,,,,, +8x,OPTVAL_8X,,,,,,,,8-oble,,,,,,,,,,,,,,,,,,,, +16x,OPTVAL_16X,,,,,,,,16-oble,,,,,,,,,,,,,,,,,,,, +32x,OPTVAL_32X,,,,,,,,32-oble,,,,,,,,,,,,,,,,,,,, +Texture Options,GLTEXMNU_TITLE,,,,Nastavení textur,Indstillinger for teksturer,Texturoptionen,,Agordoj de Teksturoj,Opciones de texturas,,Pintakuviointiasetukset,Options Textures,Textúra Beállítások,Opzioni Texture,テクスチャー オプション,텍스쳐 설정,Textuur Opties,Teksturalternativer,Opcje Tekstur,Opções de Textura,,Setări Texturi,Настройки текстур,Подешавања текстура,Alternativ för textur,Doku Seçenekleri,Параметри текстур, +Textures enabled,GLTEXMNU_TEXENABLED,,,,Povolit textury,Teksturer aktiveret,Texturen an,,Teksturoj ŝaltitaj,Texturas activadas,,Pintakuvioinnit otettu käyttöön,Textures activées,Textúrák bekapcsolása,Texture abilitate,テクスチャー有効,텍스쳐 사용,Texturen ingeschakeld,Teksturer aktivert,Tekstury włączone,Texturas ativadas,,Texturi Activate,Включить текстуры,Текстуре омогућене,Texturer aktiverade,Dokular etkinleştirildi,Увімкнути текстури, +Enable hires textures,GLTEXMNU_ENABLEHIRES,,,,Povolit textury ve vysokém rozlišení,Aktivere hi-res teksturer,Hochauflösende Texturen an,,Ŝalti Altdistingivajn Teksturojn,Activar texturas de alta resolución,,Salli korkean erotuskyvyn pintakuvioinnit,Activer Textures haute résolution,Magas felbontású textúrák bekapcsolása,Abilita texture alta qualità,ハイレゾ テクスチャー有効,고해상도 텍스쳐 사용,Hoge-resolutie texturen op,Aktivere høyoppløselige teksturer,Włącz tekstury wysokiej jakości,Habilitar texturas de alta resolução,,Texturi de înaltă rezoluție,Текстуры высокого разрешения,Омогући текстуре велике резолуције,Aktivera texturer med högre upplösning,Yüksek çözünürlüklü dokuları etkinleştir,Увімкнути текстури високого розширення, +High Quality Resize mode,GLTEXMNU_HQRESIZE,,,,Režim zvětšovače textur,Tilstand til ændring af størrelse i høj kvalitet,Texturskalierungsmodus,,Reĝimo de Altdistingivigo-Skalilo,Modo de ajuste de alta calidad,,Korkealaatuinen kuvakoon muutostapa,Mise à l'échelle haute résolution,Magas minőségű újraméretező mód,Modalità resize alta qualità,高品質リサイズ モード,고퀄리티 리사이즈 모드,Textuurschaalmodus,Høy kvalitet Endre størrelse-modus,Tryb Wysokiej Jakości Zmieniania Rozmiaru,Modo de Redimensionamento de Alta Qualidade,,Mod Redimensionare de Înaltă Calitate,Режим высококачественного масштабирования текстур,Промена величине високог квалитета мод,Högkvalitativt storleksanpassningsläge,Yüksek Kalite Yeniden Boyutlandırma modu,Масштабування текстур, +High Quality Resize multiplier,GLTEXMNU_HQRESIZEMULT,,,,Faktor zvětšovače textur,Multiplikator for ændring af størrelse i høj kvalitet,Texturskaluerungsfaktor,,Obligilo de Altdistingivigo-Skalilo,Multiplicador de ajuste de alta calidad,,Korkealaatuisen kuvakokomuutoksen kerroin,Multiplicateur de mise à l'échelle,Magas minőségű újraméretezés szorzó,Moltiplicatore resize alta qualità,高品質リサイズ乗数,고퀄리티 리사이징 승수,Textuurschaalfactor,Multiplikator for størrelsesendring av høy kvalitet,Mnożnik Wysokiej Jakośći Rozmiaru,Multiplicador de Redimensionamento de Alta Qualidade,,Factor de Scalare,Множитель высококачественного масштабирования,Промена величине високог квалитета мултипликатор,Multiplikator för storleksändring av hög kvalitet,Yüksek Kalite Yeniden Boyutlandırma çarpanı,Множник масштабування, +This mode requires %d times more video memory,GLTEXMNU_HQRESIZEWARN,,,,Tento režim potřebuje %dkrát více paměti,Denne tilstand kræver %d gange mere videohukommelse,Dieser Modus benötigt das %d-fache an Videospeicher,Αυτή η λειτουργία χρειάζετε %d περισσότερες φορές μνήμη βίντεο,Ĉi tiu reĝimo bezonas %d-oble pli da ekranmemoro.,Este modo requiere %d veces más memoria de vídeo,,Tämä tila vaatii %d kertaa enemmän videomuistia,Ce mode nécessite %d fois plus de mémoire vidéo,Ez a mód a jelenlegi videó memória %d-szeresét igényli,Questa modalità richiede %d volte la memoria video,このモードでは %d 倍以上のビデオメモリが必要です!,이 설정은 비디오 메모리의 %d 배가 더 필요합니다.,Deze modus vereist %d keer meer videogeheugen.,Denne modusen krever %d ganger mer videominne,Ten tryb wymaga %d razy więcej pamięci wideo,Este modo precisa de %d vezes mais memória de vídeo,,Acest mod necesită de %d mai multă memorie video,Данный режим требует в %d раз больше видеопамяти,Овај мод тражи %d пута више видео меморије,Det här läget kräver %d gånger mer videominne,Bu mod %d kat daha fazla video belleği gerektirir,Цьому типу потрібно в %d більше відеопам'яті, +Resize textures,GLTEXMNU_RESIZETEX,,,,Škálovat textury,Ændre størrelse på teksturer,Texturen skalieren,,Regrandigi teksturojn,Ajustar texturas,,Muuta pintakuviointien kokoa,Mise à l'échelle textures,Textúrák újraméretezése,Resize delle texture,リサイズ テクスチャー,텍스쳐 리사이징,Texturen schalen,Endre størrelse på teksturer,Zmień rozmiar tekstur,Redimensionar texturas,,Redimensionare texturi,Масштабирование текстур,Промена величине текстура,Ändra storlek på texturer,Dokuları yeniden boyutlandırma,Масштабування текстур, +Resize sprites,GLTEXMNU_RESIZESPR,,,,Škálovat sprity,Ændre størrelse på sprites,Sprites skalieren,,Regrandigi mov-rastrumojn,Ajustar sprites,,Muuta spritejen kokoa,Mise à l'échelle sprites,Sprite-ok újraméretezése,Resize degli sprite,リサイズ スプライト,스프라이트 리사이징,Sprites schalen,Endre størrelse på sprites,Zmień rozmiar sprite'ów,Redimensionar sprites,,Redimensionare sprite-uri,Масштабирование спрайтов,Промена величине спрајтова,Ändra storlek på sprites,Sprite'ları yeniden boyutlandırma,Масштабування спрайтів, +Resize fonts,GLTEXMNU_RESIZEFNT,,,,Škálovat fonty,Ændre størrelse på skrifttyper,Zeichensätze skalieren,,Regrandigi tiparojn,Ajustar fuentes,,Muuta kirjasinten kokoa,Mise à l'échelle texte,Betűk újraméretezése,Resize dei font,リサイズ フォント,폰트 리사이징,Lettertypen schalen,Endre størrelse på skrifter,Zmień rozmiar czcionek,Redimensionar fontes,,Redimensionare fonturi,Масштабирование шрифтов,Промена величине фонта,Ändra storlek på teckensnitt,Yazı tiplerini yeniden boyutlandırma,Масштабування шрифтів, +Resize model skins,GLTEXMNU_RESIZESKN,,,,Škálovat skiny modelů,Ændre størrelsen på modelskins,,,Regrandigi haŭtojn de modeloj,Ajustar texturas de modelo,,Muuta ulkoasujen kokoa,Mise à l'échelle des skins des modèles 3D,Model fazon újraméretezése,Ridimensiona skin modello,リサイズ モデルスキン,,,Endre størrelse på modellskinn,Zmień rozmiar modelu,Redimensionar skins de modelos,,Redimensionare modele,Масштабирование обликов моделей,,Ändra storlek på modellskinn,Model kaplamalarını yeniden boyutlandırma,Масштабування текстур моделей, +Precache GL textures,GLTEXMNU_PRECACHETEX,,,,Přednačíst GL textury do cache,Precache GL-teksturer,GL Texturen zwischenspeichern,,Antaŭkaŝmemorigi GL-teksturojn,Precaché de texturas GL,,Kirjoita GL-pintakuvioinnit välimuistiin,Mise en cache des textures,Előcachelt GL textúrák,Precache texture GL,プリキャッシュ GLテクスチャー,지엘 텍스쳐 미리 캐싱함,Precache GL texturen,Precache GL-teksturer,Tekstury GL pamięci podręcznej,Precachê de texturas GL,,Preîncărcarcă texturile GL,Кэшировать GL-текстуры,Прикеширане GL текстуре,Precache GL-texturer,GL dokularını önceden önbelleğe alma,Кешувати GL-текстури, +Video Mode,VIDMNU_TITLE,,,,Režim displeje,Videotilstand,Videomodus,Λειτουργία βίντεο,Video-reĝimo,Modos de vídeo,Modos de video,Videotila,Mode Vidéo,Videó mód,Modalità video,ビデオ 調整,화면 설정,Videomodus,Videomodus,Tryb Wideo,Modo de vídeo,,Mod Video,Настройки видеорежима,Видео мод,Videoläge,Video Modu,Налаштування відеорежиму, +Scaled (Nearest),OPTVAL_SCALENEAREST,,,,Škálován (nejbližší),Skaleret (Nærmeste),Skaliert (nächster Nachbar),,Skalita (Plej proksime),Escalado (Lo más cerca),,Skaalattu (läheisin),Mis à l'échelle (Proche Voisin),Átméretezett (Közeli),Scalato (più vicino),スケーリング (最寄り),확대 (가깝게),Geschaald (Dichtstbijzijnd),Skalert (nærmeste),Przeskalowany (Najbliższy),Redimensionado (mais próximo),Redimensionado (Apróximado),Redimensionat (Cel mai aproape),Масштабировать (ближайшее),Скалиран (најближи),Skalad (närmast),Ölçeklendirilmiş (En Yakın),Збільшення (ближнє), +Scaled (Linear),OPTVAL_SCALELINEAR,,,,Škálován (lineární),Skaleret (lineær),Skaliert(linear),,Skalita (Linie),Escalado (Lineal),,Skaalattu (lineaarinen),Mis à l'échelle (Linéaire),Átméretezett (Lineáris),Scalato (lineare),スケーリング (リニア),확대 (선형 식),Geschaald (Lineair),Skalert (lineær),Przeskalowany (Liniowy),Redimensionado (linear),,Redimensionat (Liniar),Масштабировать (линейное),Скалиран (линеарно),Skalad (linjär),Ölçeklendirilmiş (Doğrusal),Збільшення (лінійне), +Letterbox,OPTVAL_LETTERBOX,,,,,,,,Leterkesto,Barras negras,,Mustat reunat,,Levágott,Bande nere,レターボックス,레터박스,,,,Barras pretas,,Ecran Parțial,Экранное каше,Поштанско сандуче,,,Техніка каше, +Stretch,OPTVAL_STRETCH,,,,Roztažený,Stræk,Strecken,,Streĉi,Estrechado,Estrecho,Venytetty,Etirer,Nyújtott,Disteso,伸縮,늘림,Rek,Strekk,Rozciągnięty,Esticado,,Lărgire,Растянутый,Растегнуто,Sträcka,Esneme,Розтягнутий, +Render Mode,VIDMNU_RENDERMODE,,,,Režim rendereru,Rendertilstand,Rendermodus,,Bildigo-reĝimo,Modo de renderizado,,Hahmonnustila,Mode de Rendu,Render Mód,Modalità rendering,レンダラー,렌더링 설정,Rendermodus,Gjengivelsesmodus,Tryb Renderowania,Modo de renderização,,Mod Video,Режим обработки,Рендер мод,Renderläge,İşleme Modu,Режим візуалізації, +Fullscreen,VIDMNU_FULLSCREEN,,,,Přes celou obrazovku,Fuld skærm,Vollbild,Πλήρης οθόνη,Plena ekrano,Pantalla completa,,Koko näyttö,Plein écran,Teljes Képernyő,Schermata piena,全画面,전체화면,Volledig scherm,Fullskjerm,Pełen Ekran,Tela cheia,Ecrã cheio,Ecran Complet,Полный экран,Цео екран,Fullskärm,Tam Ekran,Повноекранний, +Retina/HiDPI support,VIDMNU_HIDPI,,,,Podpora Retiny/HiDPI,Retina/HiDPI-understøttelse,Retina/HDPI-Unterstützung,,Retino/HiDPI subteno,Soporte para Retina/HiDPI,,Retina/HiDPI-tuki,Support Retina/HiDPI ,Retina/HiDPI támogatás,Supporto Retina/HiDPi,Retina/HiDPI サポート,망막/하이DPI 활성화,Retina / HiDPI-ondersteuning,Retina/HiDPI-støtte,Wsparcie Retina/HiDPI,Suporte para Retina/HiDPI,,Suport Retina/HiDPI,Поддержка Retina/HiDPI,Retina/HiDPI подршка,Retina/HiDPI-stöd,Retina/HiDPI desteği,Підтримка Retina/HiDPI, +Aspect ratio,VIDMNU_ASPECTRATIO,,,,Poměr stran,Aspektforhold,Seitenverhältnis,,Ekran-proporcio,Relación de aspecto,,Kuvasuhde,Rapport D'Aspect,Képarány,Proporzioni,アスペクト比,종횡비,Beeldverhouding,Bildeforhold,Wpółczynnik proporcji,Proporção de tela,Proporção de ecrã,Aspect Imagine,Соотношение сторон,Однос гледишта,Bildförhållande,En boy oranı,Співвідношення сторін, +Force aspect ratio,VIDMNU_FORCEASPECT,,,,Vynutit poměr stran,Tvinge formatforhold,Erzwinge Seitenverhältnis,,Devigi ekran-proporcion,Forzar relación de aspecto,,Pakota kuvasuhde,Forcer Rapport,Képarány kényszerítése,Forza le proporzioni video,アスペクト比に従う,강제 종횡비,Geforceerde beeldverhouding,Tving sideforhold,Wymuś współczynnik proporcji,Forçar proporção de tela,Forçar proporcção de ecrã,Forțează aspectul imaginii,Принудительное соотношение сторон,Присили однос гледишта,Forcerat bildförhållande,Kuvvet en-boy oranı,Примусове співвідношення сторін, +Forced ratio style,VIDMNU_CROPASPECT,,,,Vynucený poměr stran,Stil med tvunget forhold,Modus für erzwungenes Seitenverhältnis,,Stilo por devigita proporcio,Relación de aspecto forzada,,Kuvasuhteen pakotustapa,Style de Ratio forcé,Kényszerített képarány stílusa,Forza lo stile delle proporzioni,比率の形式,강제 비율 스타일,Geforceerde verhoudingsstijl,Tvunget formatforhold-stil,Wymuszony styl współczynnika,Estilo de proporção forçado,,Forțează tipul proporțiilor,Тип принудительного соотношения сторон,Присиљен стил односа,Stil för tvingat förhållande,Zorlanmış oran stili,Тип примусового співвідношення сторін, +Enable 5:4 aspect ratio,VIDMNU_5X4ASPECTRATIO,,,,Povolit poměr stran 5:4,Aktiver 5:4-billedformat,Erlaube 5:4 Seitenverhältnis,,Ŝalti 5:4 ekran-proporcion,Activar relación de aspecto 5:4,,Ota käyttöön 5:4-kuvasuhde,Activer Rapport 5:4,5:4 képarány engedélyezése,Abilita le proporzioni 5:4,5:4アスペクト比を可能にする,5:4 비율 사용,Schakel 5:4 beeldverhouding in,Aktiver 5:4 sideforhold,Włącz współczynnik proporcji 5:4,Ativar proporção de tela 5:4,,Activează formatul 5:4,Включить соотношение сторон 5:4,Омогући 5:4 однос гледишта,Aktivera bildförhållandet 5:4,5:4 en boy oranını etkinleştirin,Увімкнути співвідношення сторін 5:4, +Resolution scale,VIDMNU_SCALEMODE,,,,Škálování rozlišení,Opløsningsskala,Skalierung,,Distingivo-skalo,Escala de resolución,,Resoluution skaalaus,Echelle de Résolution,Felbontás mérete,Scala di risoluzione,画面スケール,해상도 크기,Resolutieschaal,Oppløsningsskala,Skala rozdzielczości,Escala de resolução,,Scară rezoluție,Масштабирование,Резолуцијска скала,Upplösningsskala,Çözünürlük ölçeği,Масштабування, +Scale Factor,VIDMNU_SCALEFACTOR,,,,Faktor rozlišení,Skalafaktor,Skalierungsfaktor,,Skalfaktoro,Factor de escala,,Skaalauskerroin,Facteur d'échelle,Méretezési Faktor,Fattore di scala,スケール倍率,축척 펙터,Schaalfactor,Skaleringsfaktor,Współczynnik Skali,Fator de escala,,Factor Scalare,Значение масштаба,Фактор скалирања,Skalfaktor,Ölçek Faktörü,Значення масштабування, +Use Linear Scaling (Fullscreen),VIDMNU_USELINEAR,,,,Použít lineární škálování (přes celou obrazovku),Brug lineær skalering (fuld skærm),Lineare Skalierung (Vollbild),,Uzi linian skaladon (Plenekrane),Usar escalado linear (Pant. completa),,Lineaarinen skaalaus (koko näyttö),Mise à l'échelle Linéaire (Plein écran),Lineáris Méretezés Használata (Teljes képernyő),Usa lo scaling lineare (a schermo pieno),リニアスケールを使う(全画面),선형 스케일링 사용 (전체화면),Lineaire schaalverdeling gebruiken (volledig scherm),Bruk lineær skalering (fullskjerm),Użyj Liniowego Skalowania (Pełen Ekran),Usar escala linear (tela cheia),Usar escala linear (ecrã cheio),Folosește Scalarea Liniară (Ecran Complet),Линейное масштабирование (полный экран),Користи линеарно скалирање (цео екран),Använd linjär skalning (helskärm),Doğrusal Ölçeklemeyi Kullan (Tam Ekran),Лінійне масштабування (повний екран), +Custom Pixel Scaling,VIDMNU_CUSTOMRES,,,,Vlastní škálování pixelů,Brugerdefineret pixelskalering,Benutzerdefinierte Skalierung,,Adaptita rastrumero-skalo,Escalado de píxel personalizado,,Mukautettu skaalaus,Résolution Personalisée,Egyéni Pixelméretezés,Scaling dei pixel personalizzato,カスタム ピクセルスケール,사용자 지정 픽셀 크기 조정,Aangepaste pixelschaalvergroting,Egendefinert pikselskalering,Niestandardowe Skalowanie Pikseli,Escala de pixels personalizada,,Scară Pixeli Personalizată,Масштабирование пикселей,Пиксел скалирање,Anpassad pixelskalning,Özel Piksel Ölçeklendirme,Масштабування пікселів, +Custom Width,VIDMNU_CUSTOMX,,,,Vlastní šířka,Brugerdefineret bredde,Benutzerdefinierte Breite,,Adaptita larĝeco,Ancho personalizado,,Mukautettu leveys,Largeur Personalisée,Egyéni szélesség,Lunghezza,カスタム 幅,사용자 지정 너비,Aangepaste breedte,Egendefinert bredde,Niestandardowa Szerokość,Largura personalizada,,Lățime Personalizată,Длина,Ширина,Anpassad bredd,Özel Genişlik,Довжина, +Custom Height,VIDMNU_CUSTOMY,,,,Vlastní výška,Brugerdefineret højde,Benutzerdefinierte Höhe,,Adaptita alteco,Alto personalizado,,Mukautettu korkeus,Hauteur Personalisée,Egyéni magasság,Altezza,カスタム 高さ,사용자 지정 높이,Aangepaste hoogte,Egendefinert høyde,Niestandardowa Wysokość,Altura personalizada,,Înălțime Personalizată,Высота,Висина,Anpassad höjd,Özel Yükseklik,Висота, +Apply Changes (Windowed),VIDMNU_APPLYW,,,,Použít změny (v okně),Anvend ændringer (vindue),Änderungen anwenden (Fenster),,Apliki ŝanĝojn (Fenestrite),Aplicar cambios (Ventana),,Ota käyttöön muutokset (ikkuna),Appliquer Changements (Fenêtre),Változtatások Elfogadása (Ablak),Applica le modifiche (a finestra),変更を適用(ウィンドウ化),변경 적용 (윈도우),Wijzigingen toepassen (in venster),Bruk endringer (vindusbasert),Zatwierdź Zmiany (Okno),Aplicar alterações (janela),,Aplică Schimbările (Mod Fereastră),Сохранить изменения (оконный режим),Примени промене (прозор),Tillämpa ändringarna (fönsterskärm),Değişiklikleri Uygula (Pencereli),Зберегти зміни (віконний режим), +Apply Changes (Fullscreen),VIDMNU_APPLYFS,,,,Použít změny (přes celou obrazovku),Anvend ændringer (fuld skærm),Änderungen anwenden (Vollbild),,Apliki ŝanĝojn (Plenekrane),Aplicar cambios (Pant. completa),,Ota käyttöön muutokset (koko näyttö),Appliquer Changements (Plein écran),Változtatások Elfogadása (Teljes képernyő),Applica le modifiche (a schermo pieno),変更を適用(全画面化),변경 적용 (전체화면),Wijzigingen toepassen (Volledig scherm),Bruk endringer (fullskjerm),Zatwierdź Zmiany (Pełen Ekran),Aplicar alterações (tela cheia),Aplicar alterações (ecrã cheio),Aplică Schimbările (Mod Ecran Complet),Сохранить изменения (полный экран),Примени промене (цели екран),Tillämpa ändringar (helskärm),Değişiklikleri Uygula (Tam Ekran),Зберегти зміни (повноекранний режим), +Choose Resolution Preset,VIDMNU_RESPRESET,,,,Vybrat přednastavené rozlišení,Vælg forindstillet opløsning,Auflösungsvoreinstellung,,Elekti antaŭagorditan distingivon,Elegir resolución predefinida,,Valitse ennalta määritetty resoluutio,Choisir paramètre personalisé,Felbontási Sablon Kiválasztása,Scegli preset di risoluzione,解像度プリセットを選ぶ,해상도 사전 설정 선택,Kies een vooraf ingestelde resolutie,Velg forhåndsinnstilt oppløsning,Wybierz Zestaw Rozdzielczości,Escolher resolução predefinida,,Alege Rezoluția Predefinită,Выбор шаблона разрешения,Резолуцијска подешавања,Välj förinställning för upplösning,Çözünürlük Ön Ayarını Seçin,Вибір пресету роздільної здатності, +Custom Resolution Presets,VIDMNU_RESPRESETTTL,,,,Vlastní přednastavení rozlišení,Brugerdefinerede opløsningsforudindstillinger,Benutzerdefinierte Auflösungsvoreinstellungen,,Viaj antaŭagorditaj distingivoj,Resoluciones predefinidas personalizadas,,Ennalta määritetyt mukautetut resoluutiot,Résolutions Personalisée,Egyéni Felbontási Sablonok,Preset di risoluzione personalizzati,カスタム解像度プリセット,사용자 지정 해상도 미리 조정,Vooraf ingestelde aangepaste resoluties,Egendefinerte forhåndsinnstillinger for oppløsning,Niestandardowe Zestawy Rozdzielczości,Predefinições de resolução personalizadas,,Rezoluții Personalizate,Пользовательские шаблоны,Резолуцијска подешавања,Anpassade förinställningar för upplösning,Özel Çözünürlük Ön Ayarları,Користувацькі пресети, +Preset Resolution Modes,VIDMNU_RESPRESETHEAD,,,,Přednastavená rozlišení,Forindstillede opløsningsmodes,Vordefinierte Auflösungsmodi,,Reĝimoj pri antaŭagordita distingivo,Modos de resolución predefinida,,Ennalta määritetyt resoluutiotilat,Choisir mode de Résolution,Felbontási Sablon Módok,Modalità preset di risoluzione,解像度モードの調整,해상도 미리 조정 모드,Vooraf ingestelde resolutiemodi,Forhåndsinnstilte oppløsningsmoduser,Tryby Zestawów Rozdzielczości,Modos de resolução predefinidas,,Rezoluții Predefinite,Доступные разрешения,Постављени резолуцијски модови,Förinställda upplösningslägen,Önceden Ayarlanmış Çözünürlük Modları,Доступні роздільні здатності, +4:3 Aspect,VIDMNU_ASPECT43,,,,Poměr stran 4:3,4:3 Aspekt,4:3 Seitenverhältnis,,4:3 proporcio,Aspecto 4:3,,4:3-tilat,Rapport 4:3,4:3 Arány,Aspetto 4:3,アスペクト比 4:3,4:3 비율,Beeldverhouding 4:3,4:3 Aspekt,Proporcje 4:3,Proporção 4:3,,Aspect 4:3,Соотношение сторон 4:3,4:3 гледиште,4:3 aspekt,4:3 Görüntü,Співвідношення сторін 4:3, +5:4 Aspect,VIDMNU_ASPECT54,,,,Poměr stran 5:4,5:4 Aspekt,5:4 Seitenverhältnis,,5:4 proporcio,Aspecto 5:4,,5:4-tilat,Rapport 5:4,5:4 Arány,Aspetto 5:4,アスペクト比 5:4,5:4 비율,Beeldverhouding 5:4,5:4 Aspekt,Proporcje 5:4,Proporção 5:4,,Aspect 5:4,Соотношение сторон 5:4,5:4 гледиште,5:4 Aspekt,5:4 Görüntü,Співвідношення сторін 5:4, +16:9 Aspect,VIDMNU_ASPECT169,,,,Poměr stran 16:9,16:9 Aspekt,16:9 Seitenverhältnis,,16:9 proporcio,Aspecto 16:9,,16:9-tilat,Rapport 16:9,16:9 Arány,Aspetto 16:9,アスペクト比 16:9,16:9 비율,Beeldverhouding 16:9,16:9 Aspekt,Proporcje 16:9,Proporção 16:9,,Aspect 16:9,Соотношение сторон 16:9,16:9 гледиште,16:9 aspekt,16:9 Görüntü,Співвідношення сторін 16:9, +16:10 Aspect,VIDMNU_ASPECT1610,,,,Poměr stran 16:10,16:10 Aspekt,16.10 Seitenverhältnis,,16:10 proporcio,Aspecto 16:10,,16:10-tilat,Rapport 16:10,16:10 Arány,Aspetto 16:10,アスペクト比 16:10,16:10 비율,Beeldverhouding 16:10,16:10 Aspekt,Proporcje 16:10,Proporção 16:10,,Aspect 16:10,Соотношение сторон 16:10,16:10 гледиште,16:10 aspekt,16:10 Aspect,Співвідношення сторін 16:10, +21:9 Aspect,VIDMNU_ASPECT219,,,,Poměr stran 21:9,21:9 Aspekt,21.9 Seitenverhältnis,,21:9 proporcio,Aspecto 21:9,,21:9-tilat,Rapport 21:9,21:9 Arány,Aspetto 21:9,アスペクト比 21:9,21:9 비율,Beeldverhouding 21:9,21:9 Aspekt,Proporcje 21:9,Proporção 21:9,,Aspect 21:9,Соотношение сторон 21:9,21:9 гледиште,21:9 Aspekt,21:9 Görüntü,Співвідношення сторін 21:9, +Normal,OPTVAL_NORMAL,,,,Normální,,,,Normala,,,Normaali,,Normál,Normale,通常,기본형,Normaal,,Normalny,,,,Обычный,Нормално,,,Нормальний, +Lowest Possible Scale,OPTVAL_LOWEST,"This describes vid_scalemode 1, which represents the lowest possible scaling to fill the allocated screen area",,,Nejmenší možná velikost,Lavest mulige skala,Kleinstmögliche Auflösung,,Plej malalta ebla skalo,Menor escala posible,,Pienin mahdollinen skaalaus,Echelle la plus faible,Lehető legkisebb méret,Scala minima,可能な限り最小,,Laagst mogelijk schaal,Lavest mulig skala,Najniższa możliwa skala,Menor escala possível,,Cea mai Mică Scară Posibilă,Наименьший возможный масштаб,,Lägsta möjliga skala,Mümkün Olan En Düşük Ölçek,Найменш можливий масштаб, +Custom,OPTVAL_CUSTOM,,,,Vlastní,Brugerdefineret,Benutzerdefiniert,,Agordita de vi,Personalizado,,Mukautettu,Modifié,Egyéni,Personalizzato,カスタム,사용자 지정,Gebruikergedefinieerd,Egendefinert,Niestandardowe,Personalizado,,Personalizat,Польз.,Прилагођ.,Anpassad,Özel,Корист., +Max FPS,VIDMNU_MAXFPS,,,,Maximální FPS,,,,Maksimumaj kadroj laŭ sekundo,Límite de FPS,,Kuvataajuuden rajoitin,,,FPS Massimi,最大FPS値,,,Maks FPS,Maksymalna ilość klatek,FPS máximo,,Cadre pe secundă,Максимальная частота кадров,,,Maksimum FPS,Макс. частота кадрів, +60 fps,OPTVAL_60FPS,,,,,,,,,,,60 kuvaa/s,,,,,,,,,60 FPS,,,60 к/с,,,,60 кадрів, +75 fps,OPTVAL_75FPS,,,,,,,,,,,75 kuvaa/s,,,,,,,,,75 FPS,,,75 к/с,,,,75 кадрів, +90 fps,OPTVAL_90FPS,,,,,,,,,,,90 kuvaa/s,,,,,,,,,90 FPS,,,90 к/с,,,,90 кадрів, +120 fps,OPTVAL_120FPS,,,,,,,,,,,120 kuvaa/s,,,,,,,,,120 FPS,,,120 к/с,,,,120 кадрів, +144 fps,OPTVAL_144FPS,,,,,,,,,,,144 kuvaa/s,,,,,,,,,144 FPS,,,144 к/с,,,,144 кадри, +200 fps,OPTVAL_200FPS,,,,,,,,,,,200 kuvaa/s,,,,,,,,,200 FPS,,,200 к/с,,,,200 кадрів, +Preferred Rendering API,VIDMNU_PREFERBACKEND,,,,Upřednostňované renderovací API,Foretrukken Rendering API,Bevorzugtes Render API,Προτιμούμενο Rendering API,Preferita bildigado de API,API de renderizado preferida,,Ensisijainen hahmonnuksen ohjelmointirajapinta,API de rendu préférée,Előnyben részesített renderelő API,API di rendering preferita,優先レンダリングAPI,기본적인 API 랜더링,Voorkeur rendering API,Foretrukket Rendering API,Preferowany interfejs API renderowania,API de renderização preferida,,API Video Preferat,Предпочтительный API обработки,Преферред АПИ приказивања,Företrädesvis API för rendering,Tercih Edilen Rendering API,Бажаний інтерфейс візуалізації, +OpenGL,OPTVAL_OPENGL,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Vulkan,OPTVAL_VULKAN,,,,,,,,,,,,,,,,,,,,,,,,,,,, +OpenGL ES,OPTVAL_OPENGLES,Rendering backend,,,,,,,,,,,,,,,,,,,,,,,,,,, +,,Miscellaneous Options,,,,,,,,,,,,,,,,,,,,,,,,,,, +Merge left+right Alt/Ctrl/Shift,MISCMNU_MERGEKEYS,,,,Kombinovat pravý a levý Alt/Ctrl/Shift,Flette venstre+højre Alt/Ctrl/Shift,Linke und rechte Umschalt/Strg/Alt zusammenfassen,,Kunigi maldekstran kaj dekstran Alt/Ctrl/Shift,Combinar Alt/Ctrl/Mayús izq. y der.,Combinar Alt/Ctrl/Shift izq. y der.,Yhdistä vasen ja oikea Alt/Ctrl/Vaihto,Combiner Alt/Ctrl/maj gauche & droite,Bal és jobb Ctrl/Alt/Shift egyként érzékelése,Unisci sinistra+destra Alt/Control/Maiusc,左と右のALT/CTRL/SHIFTキーを統合,양쪽 ALT/CTRL/SHIFT키 합병,Samenvoegen links+rechts Alt/Ctrl/Shift,Slå sammen venstre+høyre Alt/Ctrl/Shift,Połącz przyciski lewo+prawo Alt/Ctrl/Shift,"Unir as teclas Alt, Ctrl e Shift esquerdos e direitos",Juntar Alt/Ctrl/Shift esquerdo+direito,Combină Alt/Ctrl/Shift stâng+drept,Не различать левую/правую ALT/CTRL/SHIFT,Споји лево+десно Аlt/Ctrl/Shift,Sammanfoga vänster+höger Alt/Ctrl/Shift,Sol+sağ birleştirme Alt/Ctrl/Shift,Не розділяти лівий/правий ALT/CTRL/SHIFT, +Alt-Enter toggles fullscreen,MISCMNU_WINFULLSCREENTOGGLE,,,,Alt-Enter přepíná celou obrazovku,Alt-Enter skifter til fuld skærm,Alt-Enter schaltet Vollbild an/aus,,Alt+Enter baskuligas tutekranan reĝimon,Alt+Enter alterna pantalla completa,,Alt-Enter kytkee täyden ruudun päälle/pois,Alt-Entrée alterne plein écran,Alt-Enter teljes képernyőre kapcsol,Alt-Invio attiva/disattiva lo schermo pieno,ALTとENTERで全画面に切り替え,ALT+ENTER키로 전체화면 조정,Alt-Enter schakelt het volledige scherm aan/uit,Alt-Enter veksler til fullskjerm,Alt-Enter przełącza na pełen ekran,Alt+Enter ativa tela cheia,Alt-Enter ativa ecrã cheio,Alt-Enter comută modul ecran complet,Переключение полного экрана по ALT+ENTER,Alt-Enter пребацује на цео екран,Alt-Enter växlar till fullskärm,Alt-Enter tam ekrana geçiş yapar,Перемикання повного екрану на ALT+ENTER, +Command-F toggles fullscreen,MISCMNU_MACFULLSCREENTOGGLE,,,,Command-F přepíná celou obrazovku,Command-F skifter til fuld skærm,Cmd-F schaltet Vollbild an/aus,,Komando-F baskuligas tutekranan reĝimon,Cmd-F alterna pantalla completa,,Komento-F kytkee täyden ruudun päälle/pois,Command-F alterne plein écran,Command-F teljes képernyőre kapcsol,Command-F attiva/disattiva lo schermo pieno,Ctrl + Fキーで全画面表示,COMMAND+F키로 전체화면 조정,Command-F schakelt het volledige scherm aan/uit,Kommando-F veksler til fullskjerm,Command-F przełącza pełny ekran,Command+F ativa tela cheia,Command-F ativa ecrã cheio,Command-F comută modul ecran complet,Переключение полного экрана по Cmd+F,Command-F пребацује на цео екран,Command-F växlar till fullskärm,Command-F tam ekrana geçiş yapar,Перемикання повного екрану на Command+F, +Enable autosaves,MISCMNU_ENABLEAUTOSAVES,,,,Povolit automatické ukládání,Aktiver autosaves,Automatisches Speichern,,Ŝalti aŭtomatajn konservojn de ludadoj,Activar autoguardado,,Ota käyttöön automaattiset tallennukset,Activer Sauvegardes auto,Automentések engedélyezése,Abilita i salvataggi automatici,オートセーブを有効化,빠른 저장 허용,Automatisch opslaan inschakelen,Aktiver automatisk lagring,Włącz autozapis,Ativar salvamento automático,Permitir gravação automática,Permite salvări automate,Автосохранения,Омогући аутосејвове,Aktivera autosparande,Otomatik kaydetmeyi etkinleştir,Автозбереження, +Number of autosaves,MISCMNU_AUTOSAVECOUNT,,,,Počet automaticky uložených her,Antal autosaves,Anzahl von automatischen Speicherständen,,Maksimuma kvanto da aŭtomataj konservoj,Cantidad máxima de autoguardados,,Automaattisten tallennusten lukumäärä,Total de sauvegardes auto,Automentések száma,Numero di salvataggi automatici,オートセーブの最大数,빠른 저장 수,Aantal auto-opslagen,Antall autolagringer,Liczba autozapisów,Número de salvamentos automáticos,Número de gravações automáticas,Număr salvări automate,Количество автосохранений,Број аутоматских чувања,Antal autosparande,Otomatik kaydetme sayısı,Кількість автозбрежень, +Save/Load confirmation,MISCMNU_SAVELOADCONFIRMATION,,,,Potvrzení o uložení/načtení,Bekræftelse af gem/indlæsning,Laden/Speichern bestätigen,,Konfirmo de konservo/ŝargo,Confirmación al guardar/cargar,,Tallennuksen/Latauksen vahvistus,Confirmation C/S,Mentés/betöltés megerősítése,Conferma Salvataggio/Caricamento,セーブ/ロード時に確認,스크립트로 스크린샷 생성 허용,Opslaan/Laad bevestiging,Bekreftelse for lagring/innlasting,Potwierdzenie zapisu/wczytania,Confirmação ao salvar/carregar,Confirmação ao gravar/carregar,Dialog de confirmare la Salvare/Încărcare,Подтверждение при сохранении/загрузке,Потврђивање током чувања/учитавања,Bekräftelse av sparande/laddning,Kaydet/Yükle onayı,Підтвердження при збереженні/завантаженні, +Disable keyboard cheats,MISCMNU_NOCHEATS,,,,Vypnout cheaty z klávesnice,Deaktivere snyderier med tastaturet,Tastatur-Cheats deaktivieren,,Malvalidigi klavarajn trompojn,Desactivar trucos por teclado,,Poista näppäinhuijaukset,Déasctiver les codes de triche au clavier,Billentyűs csalások letiltása,Disabilita i trucchi classici,キーボードからのチート無効,,Schakel cheats uit,Deaktiver tastaturjuks,Wyłącz Oszustwa z Klawiatury,Desativar trapaças de teclado,,Dezactivează codurile din tastatură,Отключить клавиатурные чит-коды,,Inaktivera fusk med tangentbordet,Klavye hilelerini devre dışı bırak,Вимкнути клавіатурні чіт-коди, +Quicksave rotation,MISCMNU_QUICKSAVEROTATION,,,,Rotace rychle uložených her,Quicksave-rotation,Schnellspeicherrotation,,Rotacio de rapidkonservo,Rotación al hacer un guardado rápido,,Pikatallennuskierto,Rotation Sauvegardes Rapides,Gyorsmentés forgás,Rotazione del quicksave,クイックセーブ間隔,빠른 저장 간격,Rouleer snelopslag,Hurtiglagring-rotasjon,Rotacja szybkich zapisów,Rotação de salvamentos rápidos,Rotação de gravações rápidas,Rotație salvări automate,Менять ячейки для быстрых сохранений,Окретање брзих чувања,Rotation av snabbregistrering,Hızlı kaydetme rotasyonu,Чергування слотів швидких збережень, +Number of quicksaves in rotation,MISCMNU_QUICKSAVECOUNT,,,,Počet rychle uložených her v rotaci,Antal quicksaves i rotation,Anzahl Schnellspeicherplätze,,Kvanto da rapidkonservoj en rotaciado,Cantidad de guardados rápidos en rotación,,Pikatallennusten määrä kierrossa,Nombre de sauvegardes en rotation,Gyorsmentések száma a forgásban,Numero di quicksave in rotazione,間隔クイックセーブの数,빠른 저장 간격의 수,Aantal roulerende snelopslagplekken,Antall hurtiglagringer i rotasjon,Ilość szybkich zapisów w rotacji,Número de salvamentos rápidos em rotação,Número de gravações rápidas em rotação,Număr salvări rapide în rotație,Кол-во ячеек для быстрых сохранений,Број брзих чувања у окретању,Antal quicksaves i rotation,Rotasyondaki quicksave sayısı,Кількість слотів для швидких збережень, +Disable Menu Clean Scaling,MISCMNU_CLEANMENU,,,,Zakázat čisté škálování nabídek,Deaktivere Menu Clean Scaling,Gleichmäßige Menüskalierung deaktivieren,,Malebligi puran skaladon en la ĉefmenuo,El menú principal no ocupa toda la pantalla,,Poista käytöstä valikon siisti skaalautuminen,Ne pas utilisé mise à l'échelle menu propre,Menü Tisztaarányítás kikapcsolása,Disabilita il fattore di scala pulito del menu,メニュー画面を伸縮させない,,Schakel uniforme menuschaling uit,Deaktiver ren skalering av meny,Wyłącz Czyste Skalowanie Menu,Desativar escala limpa do menu,,Dezactivează Scara Nouă a Meniurilor,Отключить чистое масштабирование меню,,Inaktivera ren menyskalning,Menü Temiz Ölçeklendirmeyi Devre Dışı Bırak,Вимкнути чисте масштабування меню, +Pause game in background,MISCMNU_PAUSEINBACKGROUND,,,,Pozastavit hru na pozadí,Pause spil i baggrunden,Spiel pausieren wenn im Hintergrund,,Paŭzigi ludon fone,Pausar el juego en segundo plano,,Pysäytä peli taustalla,Mettre le jeu en pause en arrière-plan,Játék megállítása a háttérben,Pausa il gioco in background,バックグラウンド時に一時停止,백그라운드에서 게임 일시 중지,Pauzeer het spel op de achtergrond,Pauser spillet i bakgrunnen,Zapauzuj grę w tle,Pausar jogo ao minimizar,,Pauză dacă jocul este minimizat.,Пауза при сворачивании окна,Паузирајте игру у позадини,Pausa spelet i bakgrunden,Oyunu arka planda duraklat,Пауза при згортуванні вікна, +Default Crosshair,HUDMNU_CROSSHAIR,,,,Výchozí zaměřovač,Standardtrådkorset,Standard-Fadenkreuz,,Defaŭlta reteto,Retícula por defecto,,Oletustähtäin,Viseur par défaut,Alap célkereszt,Mirino di default,デフォルトの照準,기본 조준점,Standaard dradenkruis,Standard trådkors,Domyślny celownik,Mira padrão,,Țintă implicită,Прицел по умолчанию,Уобичајени нишан,Standardkorshår,Varsayılan Nişangah,Типи прицілів, +Crosshair color,HUDMNU_CROSSHAIRCOLOR,,,Crosshair colour,Barva zaměřovače,Trådkors farve,Fadenkreuzfarbe,,Retetokoloro,Color de la retícula,,Tähtäimen väri,Couleur Viseur,Célkereszt színe,Colore mirino,照準色,조준점 색깔,Dradenkruis kleur,Farge på trådkors,Kolor celownika,Cor da mira,,Culoare țintă,Цвет прицела,Боја нишана,Färg på hårkorset,Nişangah rengi,Колір прицілу, +Crosshair shows health,HUDMNU_CROSSHAIRHEALTH,,,,Zaměřovač zobrazuje zdraví,Trådkors viser helbred,Fadenkreuz zeigt Gesundheit,,Reteto montras sanon,Mostrar salud en retícula,,Tähtäin näyttää terveyden,Couleur Viseur selon santé,Életerő jelzése a célkereszten,Il mirino mostra la salute,照準のヘルス表示,조준점과 체력 연동,Dradenkruis toont gezondheid,Trådkorset viser helse,Celownik pokazuje zdrowie,Exibir saúde na mira,Mostra vida na mira,Ținta afișează starea sănătății,Прицел отображает здоровье,Нишан приказује здравље,Hårkorset visar hälsa,Artı işareti sağlığı gösterir,Колір прицілу за станом здоров'я, +Scale crosshair,HUDMNU_CROSSHAIRSCALE,,,,Velikost zaměřovače,Skalerer trådkorset,Fadenkreuz skalieren,,Skali reteton,Escalar retícula,,Skaalaa tähtäintä,Mise à l'échelle du viseur,Célkereszt mérete,Fattore di scala del mirino,照準サイズ,조준점 크기,Dradenkruis schalen,Skalere trådkors,Skala celownika,Redimensionar mira,,Dimensiune țintă,Размер прицела,Размера нишана,Skala hårkorset,Ölçekli artı işareti,Розмір прицілу, +Standard,OPTVAL_YES_STANDARD,copied from elsewhere,,,Standardní,,,Πρότυπο,Norma,Estándar,,Normaali,,Alap,,標準,기본,Standaard,,,Padrão,,,Стандартный,Стандардни,,Standart,Стандартний, +Enhanced,OPTVAL_YES_ENHANCED,,,,Vylepšené,Forbedret,Verbessert,Ενισχυομένο,Bonigita,Mejorado,,Paranneltu,Amélioré,Fejlesztett,Migliorata,強調,고급,Verbeterd,Forbedret,Ulepszone,Melhorado,,Îmbunătățită,Улучшенный,Побољшани,Förbättrad,Geliştirilmiş,Покращений, +Language,OPTMNU_LANGUAGE,,,,Jazyk,Sprog,Sprache,Γλώσσα,Lingvo,Idioma,,Kieli,Langage,Nyelv,Lingua,言語設定,언어,Taal,Språk,Język,Idioma,,Limbă,Язык,Језик,Språk,Dil,Мова, +,,Reverb editor,,,,,,,,,,,,,,,,,,,,,,,,,,, +Undo Changes,TXT_UNDOCHANGES,,,,Zrušit změny,Fortryd ændringer,Rückgängig machen,Αναίρεση Αλλαγών,Malfari ŝanĝojn,Anular cambios,,Peruuttaa muutokset,Révoquer les changements,Változtatások Visszavonása,Revocare le modifiche,変更を戻す,변경 사항 취소,Wijzigingen ongedaan maken,Angre endringer,Cofnij Zmiany,Desfazer alterações,,Anulează Modificările,Отменить изменения,Поништи промене,Ångra ändringar,Değişiklikleri Geri Al,Відмінити зміни, +Select Environment,REVMNU_SELECT,,,,Vybrat prostředí,Vælg miljø,Umgebung wählen,Επιλογή Περιβάλλοντος,Elekti medion,Seleccionar ambiente,,Valitse tila,Sélectionner un environnement,Környezet Kiválasztása,Seleziona ambiente,反響選択,환경 선택,Selecteer omgeving,Velg miljø,Wybierz Środowisko,Selecione o ambiente,,Alegere Mediu,Выбрать окружение,Изабери окружење,Välj miljö,Ortam Seçiniz,Вибрати оточення, +Test Environment,REVMNU_TEST,,,,Testovat prostředí,Test miljø,Umgebung testen,Δοκιμαστκό Περιβάλλον,Provi medion,Probar ambiente,,Testaa tilaa,Tester un environnement,Környezet Tesztelése,Testa ambiente,反響テスト,환경 테스트,Test omgeving,Test miljø,Testuj Środowisko,Testar ambiente,,Testare Mediu,Проверка окружения,Тестирај окружење,Testa miljön,Test Ortamı,Тестувати оточення, +Edit Environment,REVMNU_EDIT,,,,Upravit prostředí,Rediger miljø,Umgebung editieren,Επεξεργασία Περιβάλλοντος,Modifi medion,Editar ambiente,,Muokkaa tilaa,Modifier un environnement,Környezet Szerkesztése,Modifica ambiente,反響編集,환경 편집,Omgeving bewerken,Rediger miljø,Edytuj Środowisko,Editar ambiente,,Editare Mediu,Редактировать окружение,Уреди окружење,Redigera miljön,Ortamı Düzenle,Редагувати оточення, +New Environment,REVMNU_NEW,,,,Nové prostředí,Nyt miljø,Neue Umgebung,Νέο Περιβάλλον,Nova medio,Nuevo ambiente,,Uusi tila,Nouveau environnement,Új Környezet,Nuovo ambiente,新規反響設定,새로운 환경 생성,Nieuwe omgeving,Nytt miljø,Nowe Środowisko,Novo ambiente,,Mediu Nou,Новое окружение,Ново окружење,Ny miljö,Yeni Çevre,Нове оточення, +Revert settings,REVMNU_REVERT,,,,Obnovit nastavení,Tilbageføre indstillinger,Zurücksetzen,Επαναφορά Ρυθμίσεων,Malfari agordojn,Revertir configuración,,Palauta asetukset,Réinitialiser les paramètres,Változtatások elvetése,Ripristina le impostazioni,設定を戻す,설정 되돌리기,Instellingen terugzetten,Tilbake innstillinger,Przywróć ustawienia,Reverter configurações,,Revenire la setările precedente,Сбросить настройки,Врати подешавања,Återkalla inställningar,Ayarları geri döndür,Налаштування за замовчуванням, +Environment Size,REVMNU_ENVIRONMENT_SIZE,Please translate only if you know how to properly name this technical jargon!,,,,,,Μέγεθος Περιβάλλοντος,Mediamplekso,Tamaño de ambiente,,Tilan koko,Taille Environnement,,Dimensioni dell'ambiente,反響サイズ,공간 크기,,,Rozmiar Środowiska,Tamanho do ambiente,,,,,Miljö storlek,,, +Environment Diffusion,REVMNU_ENVIRONMENT_DIFFUSION,,,,,,,Διάχυση Περιβάλλοντος,Medidifuzo,Difusión de ambiente,,Tilan äänen hajautuminen,Diffusion Environnement,,Diffusione dell'ambiente,反響伝播,공간 잔향 확산,,,Dyfuzja Środowiska,Difusão do ambiente,,,,,Miljö spridning,,, +Room,REVMNU_ROOM,,,,,,,Δωμάτιο,Ĉambro,Sala,,Tilan keskitaajuudet,Salle,,,,룸 효과,,,Pokój,Sala,,,,,,,, +Room HF,REVMNU_ROOM_HF,,,,,,,Δωμάτιο HF,Ĉambro (AF),Sala (Frecuencia alta),,Tilan korkeat taajuudet,HF Salle,,,,룸 효과 HF,,,Pokój (wysokie częstotliwości),Sala (alta frequência),,,,,,,, +Room LF,REVMNU_ROOM_LF,,,,,,,Δωμάτιο LF,Ĉambro (MaF),Sala (Frecuencia baja),,Tilan matalat taajuudet,LF Salle,,,,룸 효과 LF,,,Pokój (niskie częstotliwości),Sala (baixa frequência),,,,,,,, +Decay Time,REVMNU_DECAY_TIME,,,,,,,,Putriĝo-tempo,Tiempo de decadencia,,Häipymäaika,Temps Decay,,,,잔향 감쇠 시간,,,Czas Rozkładu,Tempo de decaimento,,,,,,,, +Decay HF Ratio,REVMNU_DECAY_HF_RATIO,,,,,,,,Putriĝo-proporcio (AF),Ratio de decadencia (Frecuencia alta),,Korkeiden taajuuksien (HF) häipymissuhdeluku,,,,Decay HF比率,잔향 감쇠 HF 비율,,,Wskażnik Rozkładu dla wysokich częstotliwości,Taxa de decaimento (alta freq.),,,,,,,, +Decay LF Ratio,REVMNU_DECAY_LF_RATIO,,,,,,,,Putriĝo-proporcio (MaF),Ratio de decadencia (Frecuencia baja),,Matalien taajuuksien (LF) häipymissuhdeluku,,,,Decay LF比率,잔향 감쇠 LF 비율,,,Wskaźnik Rozkładu dla niskich częstotliwości,Taxa de decaimento (baixa freq.),,,,,,,, +Reflections,REVMNU_REFLECTIONS,,,,,,,Αντανακλάσεις,Reflektoj,Reflejos,,Ensiheijastukset,,,,,룸 반사,,,Obicia,Reflexos,,,,,,,, +Reflections Delay,REVMNU_REFLECTIONS_DELAY,,,,,,,Καθυστέρηση Αντανακλάσεων,Prokrasto de reflektoj,Retraso de reflejos,,Ensiheijastusten viive,Délai Reflections,,,,룸 반사 딜레이 시간,,,Opóźnienie Odbić,Atraso de reflexos,,,,,,,, +Reflections Pan X,REVMNU_REFLECTIONS_PAN_X,,,,,,,,Reflektoj alturnas tra X,Desplazamiento en X de reflejos,,Ensiheijastusten X-panorointi,Orientation Reflections X,,,Reflections X定位,X축 룸 반사,,,Odbicia Osi X,Deslocamento X de reflexos,,,,,,,, +Reflections Pan Y,REVMNU_REFLECTIONS_PAN_Y,,,,,,,,Reflektoj alturnas tra Y,Desplazamiento en Y de reflejos,,Ensiheijastusten Y-panorointi,Orientation Reflections Y,,,Reflections Y定位,Y축 룸 반사,,,Odbicia Osi Y,Deslocamento Y de reflexos,,,,,,,, +Reflections Pan Z,REVMNU_REFLECTIONS_PAN_Z,,,,,,,,Reflektoj alturnas tra Z,Desplazamiento en Z de reflejos,,Ensiheijastusten Z-panorointi,Orientation Reflections Z,,,Reflections Z定位,Z축 룸 반사,,,Odbicia Osi Z,Deslocamento Z de reflexos,,,,,,,, +Reverb,REVMNU_REVERB,,,,,,,,Resono,Reverberación,,Jälkikaiunta,,,,,리버브,,,Pogłos,Reverberação,,,,,,,, +Reverb Delay,REVMNU_REVERB_DELAY,,,,,,,,Prokrasto de resono,Retraso de reverberación,,Jälkikaiunnan viive,Délai Reverb,,,,리버브 지연,,,Opóźnienie Pogłosu,Atraso de reverberação,,,,,,,, +Reverb Pan X,REVMNU_REVERB_PAN_X,,,,,,,,Resono alturnas tra X,Desplazamiento en X de reverberación,,Jälkikaiunnan X-panorointi,Orientation Reverb X,,,Reverb X定位,X축 리버브,,,Pogłos Osi X,Deslocamento X de reverberação,,,,,,,, +Reverb Pan Y,REVMNU_REVERB_PAN_Y,,,,,,,,Resono alturnas tra Y,Desplazamiento en Y de reverberación,,Jälkikaiunnan Y-panorointi,Orientation Reverb Y,,,Reverb Y定位,Y축 리버브,,,Pogłos Osi Y,Deslocamento Y de reverberação,,,,,,,, +Reverb Pan Z,REVMNU_REVERB_PAN_Z,,,,,,,,Resono alturnas tra Z,Desplazamiento en Z de reverberación,,Jälkikaiunnan Z-panorointi,Orientation Reverb Z,,,Reverb Z定位,Z축 리버브,,,Pogłos Osi Z,Deslocamento Z de reverberação,,,,,,,, +Echo Time,REVMNU_ECHO_TIME,,,,,,,,Tempo de eĥo,Tiempo de eco,,Kaikuaika,Longueur écho,,,,에코 시간,,,Czas Echa,Tempo de eco,,,,,,,, +Echo Depth,REVMNU_ECHO_DEPTH,,,,,,,,Produndo de eĥo,Profundidad de eco,,Kaiun syvyys,Profondeur écho,,,,에코 깊이,,,Głębokość Echa,Profundidade de eco,,,,,,,, +Modulation Time,REVMNU_MODULATION_TIME,,,,,,,,Tempo de modulado,Tiempo de modulación,,Modulaatioaika,Longueur Modulation,,,,전조 시간,,,Czas Modulacji,Tempo de modulação,,,,,,,, +Modulation Depth,REVMNU_MODULATION_DEPTH,,,,,,,,Produndo de modulado,Profundidad de modulación,,Modulaation syvyys,Profondeur Modulation,,,,전조 깊이,,,Głębokość Modulacji,Profundidade de modulação,,,,,,,, +Air Absorption HF,REVMNU_AIR_ABSORPTION_HF,,,,,,,,Aer-absorbo AF,Absorción en aire de frecuencia alta,,Korkeiden taajuuksien (HF) ilma-absorptio,,,,,대기 흡수 HF,,,Absorbcja Powietrza (wysokie częstotliwości),Absorção de ar de alta freq.,,,,,,,, +HF Reference,REVMNU_HF_REFERENCE,,,,,,,,AF referenco,Referencia de frecuencia alta,,Korkeiden taajuuksien vertausarvo,,,,HF参照値,HF 참조치,,,Odniesienie wysokich częstotliwości,Referência de alta freq.,,,,,,,, +LF Reference,REVMNU_LF_REFERENCE,,,,,,,,MaF referenco,Referencia de frecuencia baja,,Matalien taajuuksien vertausarvo,,,,LF参照値,LF 참조치,,,Odniesienie niskich częstotliwości,Referência de baixa freq.,,,,,,,, +Room Rolloff Factor,REVMNU_ROOM_ROLLOFF_FACTOR,,,,,,,,Ĉambro-Rolloff-faktoro,Factor de Roll-off de sala,,Tilan vaimenemiskerroin,Facteur de rolloff Salle,,,,룸 감쇠 양,,,Czynnik Zejścia,Fator de roll-off de sala,,,,,,,, +Diffusion,REVMNU_DIFFUSION,,,,,,,,Difuzo,Difusión,,Diffuusio,,,,,잔향 확산,,,Dyfuzja,Difusão,,,,,,,, +Density,REVMNU_DENSITY,,,,,,,,Denseco,Densidad,,Tiheys,Densité,,,密度,잔향 밀도,,,Zagęszczenie,Densidade,,,,,,,, +Reflections Scale,REVMNU_Reflections_Scale,,,,,,,,Skalo de reflektoj,Escala de reflejos,,Ensiheijastusten skaala,Echelle Reflections,,,Reflections音階,룸 반사 음계,,,Rozmiar Odbić,Escala de reflexos,,,,,,,, +Reflections Delay Scale,REVMNU_Reflections_Delay_Scale,,,,,,,,Prokrastskalo de reflektoj,Escala de retraso de reflejos,,Ensiheijastusten viiveen skaala,Délai d'échelle reflections,,,Reflections Delay音階,룸 반사 딜레이 음계,,,Skala Opóźnienia Odbić,Escala de atraso de reflexos,,,,,,,, +Decay Time Scale,REVMNU_Decay_Time_Scale,,,,,,,,Tempskalo de purtiĝo,Escala de tiempo de decadencia,,Häipymäajan skaala,Echelle temporelle Decay,,,Decay Time音階,잔향 감쇠시간 음계,,,Skala Czasu Rozkładu,Escala de tempo de decaimento,,,,,,,, +Decay HF Limit,REVMNU_Decay_HF_Limit,,,,,,,,AF-Limito de purtiĝo,Limite de decadencia de alta frecuencia,,Häipymän korkeiden taajuuksien raja-arvo,Limite HF Decay,,,Decay HF限度,잔향 감쇠 HF 한도,,,Limit Rozkładu Wysokich Częstotliwości,Limite de decaimento em alta freq.,,,,,,,, +Reverb Scale,REVMNU_Reverb_Scale,,,,,,,,Skalo de resono,Escala de reverberación,,Jälkikaiunnan skaala,Echelle Reverb,,,Reverb音階,리버브 음계,,,Skala Pogłosu,Escala de reverberação,,,,,,,, +Reverb Delay Scale,REVMNU_Reverb_Delay_Scale,,,,,,,,Prokrastskalo de resono,Escala de retraso de reverberación,,Jälkikaiunnan viiveen skaala,Délai d'échelle Reverb,,,Reverb Delay音階,리버브 딜레이 음계,,,Skala Opóźnienia Pogłosu,Escala de atraso de reverberação,,,,,,,, +Echo Time Scale,REVMNU_Echo_Time_Scale,,,,,,,,Tempskalo de eĥo,Escala de tiempo de eco,,Kaikuajan skaala,Echelle temporelle Echo,,,Echo Time音階,에코 시간 음계,,,Skala Czasu Echa,Escala de tempo de eco,,,,,,,, +Modulation Time Scale,REVMNU_Modulation_Time_Scale,,,,,,,,Tempskalo de modulado,Escala de tiempo de modulación,,Modulaatioajan skaala,Echelle temporelle Modulation,,,Modulation Time音階,전조 시간 음계,,,Skala Modulacji Czasu,Escala de tempo de modulação,,,,,,,, +Based on,REVMNU_Based_on,,,,Založeno na,Baseret på,Basierend auf,Βασισμένο σε,Bazita de,Basado en,,Perustana,Basé sur,Minta,Basato su,音響の元,음향 원본,Gebaseerd op,Basert på,Bazowane na,Baseado em,,Bazat pe,Основано на,Засновано на,Baserat på,Buna göre,Засновано на, +Name,REVMNU_Name,,,,Název,Navn,,Όνομα,Nomo,Nombre,,Nimi,Nom,Név,Nome,名前,이름,Naam,Navn,Nazwa,Nome,,Nume,Название,Назив,Namn,İsim,Назва, +ID #1,REVMNU_ID_1,,,,,,,,Identigo #1,ID Nº1,,,,,ID N°1,,아이디 #1,,,,,,,ИД №1,,,,, +ID #2,REVMNU_ID_2,,,,,,,,Identigo #2,ID Nº2,,,,,ID N°2,,아이디 #2,,,,,,,ИД №2,,,,, +Create,REVMNU_Create,,,,Vytvořit,Opret,Erstellen,Δημιουργία,Krei,Crear,,Luo,Créer,Készítés,Creare,作成,생성,Aanmaken,Opprett,Stwórz,Criar,,Creare,Создать,Направи,Skapa,Oluştur,Створити, +Save...,REVMNU_Save,,,,Uložit...,Gem...,Speichern...,Αποθήκευση,Konservi...,Guardar...,,Tallenna...,Sauvegarder...,Mentés...,Salvare...,セーブする...,저장 하기...,Opslaan...,Lagre...,Zapisz...,Salvar...,,Salvare...,Сохранить...,Сачувај...,Spara...,Kaydet...,Зберегти..., +File name,REVMNU_File_name,,,,Název souboru,Filnavn,Dateiname,Όνομα αρχείου,Dosiernomo,Nombre de archivo,,Tiedostonimi,Nom de fichier,Fájlnév,Nome del file,ファイル名,파일 이름,Bestandsnaam,Filnavn,Nazwa pliku,Nome do arquivo,,Nume fișier,Имя файла,Назив фајла,Filnamn,Dosya adı,Назва файлу, +Environments to save,REVMNU_Environments_to_save,,,,Prostředí k uložení,"Miljøer, der skal gemmes",Zu speichernde Umgebungen,Περιβάλλοντα για αποθήκευση,Medioj por konservi,Ambientes para guardar,,Tallennettavat tilat,Environnements à sauvegarder,Mentendő Környezetek,Ambienti da salvare,音響を保存,저장할 공간,Omgevingen om op te slaan,Miljøer som skal lagres,Środowiska do zapisu,Ambientes para salvar,,Medii de salvat,Сохранить окружения...,Окружења за чување,Miljöer som ska sparas,Kurtarılacak ortamlar,Зберегти оточення..., +,,Vulkan,,,,,,,,,,,,,,,,,,,,,,,,,,, +Vulkan Options (Experimental),DSPLYMNU_VKOPT,,,,Nastavení Vulkanu (Experimentální),Vulkan-indstillinger (eksperimentelt),Vulkan Optionen (Experimentell),Vulka Ρυθμίσεις (Πειραματικές),Agordoj por Vulkan (Eksperimenta),Opciones de Vulkan (Experimental),,Vulkan-asetukset (kokeellinen),Options Vulkan (Expérimental),Vulkan Beállítások (Kísérleti),Opzioni Vulkan (Sperimentale),Vulkan機能オプション(実験的),벌칸 설정(실험적),Vulkan-opties (Experimenteel),Vulkan Alternativer (Eksperimentell),Opcje Vulkan (Eksperymentalne),Opções de Vulkan (experimental),,Setări Mod Vulkan (În curs de testare),Настройки Vulkan (экспериментальные),Vulkan подешавања (експериментална),Vulkan-alternativ (experimentellt),Vulkan Seçenekleri (Deneysel),Налаштування Vulkan (експериментальні), +Vulkan Options,VK_TITLE,,,,Nastavení Vulkanu,Vulkan-indstillinger,Vulkan Optionen,Vulkan Ρυθμίσεις,Agordoj por Vulkan,Opciones de Vulkan,,Vulkan-asetukset,Options Vulkan,Vulkan Beállítások,Opzioni Vulkan,Vulkan機能オプション,벌칸 설정,Vulkan-opties,Vulkan-alternativer,Opcje Vulkan,Opções de Vulkan,,Setări Mod Vulkan,Настройки Vulkan,Vulkan подешавања,Vulkan-alternativ,Vulkan Seçenekleri,Налаштування Vulkan, +Enable Vulkan,VKMNU_ENABLE,,,,Povolit Vulkan,Aktiver Vulkan,Aktiviere Vulkan,Ενεργοποιηση του Vulkan,Ŝalti Vulkan,Activar Vulkan,,Ota käyttöön Vulkan,Activer Vulkan,Vulkan Engedélyezése,Abilita Vulkan,Vulkanを有効化,벌칸 렌더러 사용,Vulkan inschakelen,Aktiver Vulkan,Włącz Vulkan,Ativar Vulkan,,Activează modul video Vulkan,Использовать Vulkan,Омогући Vulkan,Aktivera Vulkan,Vulkan'ı Etkinleştir,Увімкнути Vulkan, +Vulkan Device ID,VKMNU_DEVICE,,,,ID zařízení Vulkanu,Vulkan-enheds-id,Vulkan Geräte ID,Vulkan ID Συσκευής,Identigo de Vulkan-aparato,ID de dispositivo Vulkan,,Vulkan-laitetunniste,ID du périphérique Vulkan,Vulkan Eszköz ID,Dispositivo ID Vulkan,Vulkanデバイス ID,벌칸 장치 아이디,Vulkan apparaat-ID,Vulkan Enhets-ID,ID urządzenia Vulkan,ID do dispositivo Vulkan,,ID Dispozitiv Vulkan,ИД устройства Vulkan,Vulkan ID уређаја,Vulkan-enhets-ID,Vulkan Cihaz Kimliği,ID пристрою Vulkan, +High Dynamic Range,VKMNU_HDR,,,,Vysoký dynamický rozsah (HDR),Høj dynamisk rækkevidde,,Υψηλό Δυναμική Εμβέλεια,Alta dinamika intervalo,Alto rango dinámico,,Korkea dynamiikka-alue (HDR),,,,ハイダイナミックレンジ,하이 다이나믹 레인지,Hoog dynamisch bereik,Høyt dynamisk område,Obraz HDR,Alto alcance dinâmico (HDR),,HDR,Расширенный динамический диапазон (HDR),HDR,Högt dynamiskt omfång,Yüksek Dinamik Aralık,HDR, +Warning: The Vulkan renderer is highly experimental!,VK_WARNING,,,,Varování: Vulkan renderer je velmi experimentální!,Advarsel: Vulkan-rendereren er meget eksperimentel!,Achtung: Der Vulkan Renderer ist noch sehr experimentell!,Προειδοποίηση: Ο Vulkan renderer είναι υψηλά πειραματικός!,Averto: La bildigilo de Vulkan estas alte eksperimenta!,Advertencia: ¡El renderizado por Vulkan es altamente experimental!,,Varoitus: Vulkan-hahmonnin on hyvin kokeellinen!,Attention: Le moteur de rendu Vulkan est très expérimental!,Vigyázat: A Vulkan renderer még teljesen kísérleti!,Attenzione: il motore grafico Vulkan è altamente sperimentale!,警告:Vulkanレンダラーは実験段階です!,경고: 벌칸 렌더러는 매우 실험적입니다!,Waarschuwing: De Vulkan renderer is zeer experimenteel!,Advarsel: Vulkan-rendereren er svært eksperimentell!,Uwaga: Renderer Vulkan jest bardzo eksperymentalny!,Atenção: o renderizador Vulkan é altamente experimental!,,Atenție: Modul Vulkan este încă în curs de testare!,Внимание: обработчик Vulkan в стадии тестирования!,УПОЗОРЕЊЕ: Vulkan рендерер је врло експерименталан!,Varning: Vulkan-renderaren är mycket experimentell!,Uyarı: Vulkan işleyici son derece deneyseldir!,Увага: рендер Vulkan на стадії тестування!, +These options will require a restart to take effect.,VK_RESTART,,,,Tato nastavení vyžadují restart hry.,Disse indstillinger kræver en genstart for at få effekt.,Diese Option erfordert einen Neustart!,Αυτές η ρυθμίσεις θα χρειαστούνε επανεκκίνηση για να ισχύσουν,Ĉi tiuj agordoj bezonos relanĉon por efikiĝi.,Estas opciones requieren reiniciar para tener efecto.,,Nämä asetukset vaativat uudelleenkäynnistyksen astuakseen voimaan.,Ces options nécessitent un redémarrage.,Ezen beállítások életbelépéséhez újraindítás szükséges.,Queste opzioni richiedono il riavvio per avere effetto.,これらのオプションを有効にするには再起動が必要です。,이 설정을 적용하려면 게임을 재시작해야 합니다.,Deze opties vereisen een herstart om van kracht te worden.,Disse alternativene krever en omstart for å tre i kraft.,"Te opcje będą wymagały ponownego włączenia, aby miały efekt.",É necessário reiniciar para que essas configurações surtam efeito.,É necessário reiniciar para estas configurações fazerem efeito.,Aceste setări necesită o repornire pentru a putea fi aplicate,Для применения этих изменений требуется перезапуск игры.,Морате поново покренути GZDoom да би промене ступиле на снагу.,De här alternativen kräver en omstart för att få effekt.,Bu seçeneklerin etkili olması için yeniden başlatılması gerekecektir.,Для застосування змін протрібно перезапустити гру., +Select Vulkan Device,VKMNU_DEVICESELECT,This is not yet implemented - but it is planned,,,Vybrat zařízení Vulkanu,Vælg Vulkan-enhed,Vulkan Gerät auswählen,Επιλογή Vulkan Συσκευής,Elekti Vulkan-aparaton,Seleccionar dispositivo Vulkan,,Valitse Vulkan-laite,Sélectionner périphérique Vulkan,Vulkan eszköz kiválasztása,Seleziona il Dispositivo Vulkan,Vulkanデバイスの選択,벌칸 장치를 고르시오,Selecteer Vulkan Apparaat,Velg Vulkan-enhet,Wybierz Urządzenie Vulkan,Selecione o dispositivo Vulkan,,Selectare Dispozitiv Vulkan,Выбрать устройство Vulkan,Изаберите Vulkan уређај,Välj Vulkan-enhet,Vulkan Aygıtını Seçin,Виберіть пристрій Vulkan, +,,Texture scaling,,,,,,,,,,,,,,,,,,,,,,,,,,, +ScaleNx,OPTVAL_SCALENX,,,,,,,,,,,,,,,,,,,,,,,,,,,, +NormalNx,OPTVAL_NORMALNX,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hqNx,OPTVAL_HQNX,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hqNx MMX,OPTVAL_HQNXMMX,,,,,,,,,,,,,,,,,,,,,,,,,,,, +xBRZ,OPTVAL_NXBRZ,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Old xBRZ,OPTVAL_OLD_NXBRZ,,,,xBRZ (starší),Gamle xBRZ,xBRZ alt,Παλίο xBRZ,Malnova xBRZ,Antiguo xBRZ,,Vanha xBRZ,Ancien xBRZ,Régi xBRZ,Vecchio xBRZ,旧xBRZ,구형 xBRZ,Oud xBRZ,Gammel xBRZ,Stare xBRZ,Antigo xBRZ,,Vechiul xBRZ,Старый xBRZ,Стари xBRZ,Gamla xBRZ,Eski xBRZ,Старий xBRZ, +,,Option Search,,,,,,,,,,,,,,,,,,,,,,,,,,, +Option Search,OS_TITLE,,,,Vyhledávání možností,Mulighed Søgning,Optionssuche,Αναζήτηση Ρυθμίσεων,Serĉi agordojn,Buscar opciones,,Asetushaku,Recherche Option,Beállítások keresése,Opzioni di ricerca,オプション検索,옵션 검색,Optie zoeken,Alternativt søk,Szukanie Opcji,Buscar opção,Procurar opção,Căutare Setări,Поиск настройки,Претрага,Sökning av alternativ,Seçenek Arama,Пошук налаштування, +Search for any term,OS_ANY,,,,Hledat jakékoli klíčové slovo,Søg efter et vilkårligt begreb,Suche nach beliebigem Begriff,Αναζήτηση για όποιαδηποτε λέξη,Serĉi por iu ajn termino,Buscar cualquier término,,Etsi mitä tahansa sanaa,N'importe quel mot,Keresés bármely kifejezésre,Cerca per ciascun termine,いずれかの用語を探す,용어 검색,Zoek naar eender welke term,Søk etter en hvilken som helst term,Szukaj jakiegokolwiek wyrażenia,Buscar por qualquer termo,Procurar por um termo qualquer,Căutare după orice termen,Искать любое из слов,Тражи било који термин,Sök efter valfri term,Herhangi bir terim için arama yapın,Шукати будь яке з слів, +Search for all terms,OS_ALL,,,,Hledat všechna klíčová slova,Søg efter alle udtryk,Suche nach allen Begriffen,Αναζήτηση για όλες της λέξεις,Serĉi por ĉiuj terminoj,Buscar todos los términos,,Etsi kaikki sanat,Tous les mots,Keresés minden kifejezésre,Cerca per tutti i termini,全ての用語を探す,모든 조건 검색,Zoek naar alle termen,Søk etter alle termer,Szukaj wszystkich wyrażeń,Buscar por todos os termos,Procurar por todos os termos,Căutare după toți termenii,Искать все слова,Тражи сваки термин,Sök efter alla termer,Tüm terimler için arama yapın,Шукати всі слова, +No results found.,OS_NO_RESULTS,,,,Nic nenalezeno.,Ingen resultater fundet.,Keine Resultate,Δέν βρέθηκαν αποτελέσματα,Neniu trafo.,Ningún resultado.,,Ei tuloksia.,Pas de résultat trouvé,Nincs találat,Nessun risultato trovato.,見つかりませんでした。,검색 결과 없음.,Geen resultaten gevonden.,Ingen resultater funnet.,Brak wyników,Nenhum resultado encontrado.,,Niciun rezultat găsit.,Результаты не найдены.,Нема резултата.,Inga resultat hittades.,Sonuç bulunamadı.,Нічого не знайдено., +Search:,OS_LABEL,,,,Hledat:,Søg:,Suche:,Αναζήτηση:,Serĉi:,Buscar:,,Etsi:,Recherche:,Keresés:,Trova:,検索:,검색:,Zoeken:,Søk:,Szukaj:,Busca:,Procura:,Caută:,Поиск:,Претрага:,Sök:,Ara:,Пошук:, +,,Blood Bath Announcer,,,,,,,,,,,,,,,,,,,,,,,,,,, +%k boned %o like a fish,TXT_OBITUARY1,,,,%o byl@[ao_cs] vykoštěn@[ao_cs] jako ryba hráčem %k,%k udbenede %o som en fisk,%k hat %o zerlegt wie einen Fisch,Ο/Η %k ξεκοκάλοσε @[pro2_gr] %o σα ψάρι,%k senostigis %o kiel fiŝon,%k ha deshuesado a %o como a un pescado,%k deshuesó a %o como a un pescado,%k perkasi %o paran kuin kalan,%k a désossé %o comme un poisson,%k kifilézte %o -t mint a halat,%k ha dissossato %o come un pesce,%k は %o の骨を魚のように引っこ抜いた。,%k 은(는) %o 의 뼈를 발랐다.,%k mergelde %o als een vis,%k utbeinet %o som en fisk,%k odfiletował@[ao_pl] %o jak rybę,%k desossou %o como um peixe,,%k l-a dezosat pe %o ca pe un pește,%k пересчитал косточки игрока %o,%k је очистио %o као рибу,%k benade %o som en fisk,"%o, %k tarafından balık gibi kemirildi.",%k порахува@[adj_1_ua] ребра %o, +%k castrated %o,TXT_OBITUARY2,,,,%o byl@[ao_cs] vykastrován@[ao_cs] hráčem %k,%k kastrerede %o,%k hat %o kastriert,Ο/Η %k ευνούχισε %o,%k kastris %o,%k ha castrado a %o,%k castró a %o,%k kastroi %o paran,%k a castré %o,%k kasztrálta %o -t,%k ha castrato %o,%k は %o を去勢した。,%k 은(는) %o 을(를) 거세시켰다.,%k castreerde %o,%k kastrert %o,%k wykastrował@[ao_pl] %o,%k castrou %o,,%k l-a castrat pe %o,%k кастрировал игрока %o,%k је кастрирао %o,%k kastrerade %o,"%o, %k tarafından hadım edildi.",%k каструва@[adj_1_ua] %o, +%k creamed %o,TXT_OBITUARY3,,,,%o byl@[ao_cs] rozšlehán@[ao_cs] hráčem %k,%k smurte %o,%k hat %o eingeseift,Ο/Η %k κρέμασε @[pro2_gr] %o,%k kremigis %o,%k ha cremado a %o,%k cremó a %o,%k kermasi %o paran,%k a battu %o à plate couture ,%k elkente %o -t,%k ha cremato %o,%k は %o に反吐ブチ撒けさせた。,%k 은(는) %o 을(를) 양념시켰다.,%k pureerde %o,%k fløtet %o,%k spienił@[ao_pl] %o,%k fez creme de %o,,%k l-a transformat în cremă pe %o,%k взбил игрока %o,%k је истукао %o,%k gräddade %o,,%k розпуши@[adj_1_ua] %o, +%k decimated %o,TXT_OBITUARY4,,,,%o byl@[ao_cs] zdecimován@[ao_cs] hráčem %k,%k decimerede %o,%k hat %o dezimiert,Ο/Η %k αποδεκάτισε @[pro2_gr] %o,%k detruegis %o,%k ha diezmado a %o,%k diezmó a %o,%k hävitti %o paran,%k a décimé %o,%k megtizedelte %o -t,%k ha decimato %o,%k は %o の居場所を間引いた。,%k 은(는) %o 을(를) 망가뜨렸다.,%k decimeerde %o,%k desimert %o,%k przetrzebił@[ao_pl] %o,%k decimou %o,,%k l-a decimat pe %o,%k скосил игрока %o,%k је десетковао %o,%k decimerade %o,"%o, %k tarafından yok edildi.",%k зітну@[adj_1_ua] %o, +%k destroyed %o,TXT_OBITUARY5,,,,%o byl@[ao_cs] zničen@[ao_cs] hráčem %k,%k ødelagde %o,%k hat %o zerstört,Ο/Η %k κατέστεψε @[pro2_gr] %o,%k detruis %o,%k ha destruido a %o,%k destruyó a %o,%k tuhosi %o paran,%k a détruit %o,%k elpusztította %o -t,%k ha distrutto %o,%k は %o を完全に破壊した。,%k 은(는) %o 을(를) 파괴했다.,%k vernietigde %o,%k destruert %o,%k zniszczył@[ao_pl] %o,%k destruiu %o,,%k l-a distrus pe %o,%k уничтожил игрока %o,%k је уништио %o,%k förstörde %o,,%k знищи@[adj_1_ua] %o, +%k diced %o,TXT_OBITUARY6,,,,%o byl@[ao_cs] nakrájen@[ao_cs] na kostičky hráčem %k,%k skar %o i tern,%k hat %o in Würfel zerteilt,Ο/Η %k τεμάχησε @[pro2_gr] %o,%k diskubigis %o,%k ha picado en cubitos a %o,%k picó en cubitos a %o,%k pilkkosi %o paran,%k a coupé en dés %o,%k kockára vágta %o -t,%k ha tagliato a cubetti %o,%k は %o を賽の目に切った。,%k 은(는) %o 을(를) 잘게 잘게 썰었다.,%k sneed %o in stukjes,%k skåret %o i terninger,%k pokroił@[ao_pl] w kostkę %o,%k fez picadinho de %o,%k cortou %o,%k l-a feliat pe %o,%k разрезал игрока %o,%k је исецкао %o,%k skar %o i tärningar,"%o, %k tarafından doğrandı.",%k наріза@[adj_1_ua] %o, +%k disembowled %o,TXT_OBITUARY7,,,,%o byl@[ao_cs] vykuchán@[ao_cs] hráčem %k,%k udkløvede %o,%k hat %o ausgeweidet,Ο/Η %k ισοπέδοσε @[pro2_gr] %o,%k sentripigis %o,%k ha destripado a %o,%k destripó a %o,%k suolisti %o paran,%k a étripé %o,%k kibelezte %o -t,%k ha smembrato %o,%k は %o の臓物を引きずり出した。,%k 은(는) %o 의 내장을 도려냈다.,%k ontleedde %o,%k sprettet opp %o,%k wypatroszył@[ao_pl] %o,%k estripou %o,,%k l-a eviscerat pe %o,%k выпотрошил игрока %o,%k је ампутирао %o,%k tog upp %o i bitar,,%k випотроши@[adj_1_ua] %o, +%k flattened %o,TXT_OBITUARY8,,,,%o byl@[ao_cs] zplacatěn@[ao_cs] hráčem %k,%k smadrede %o,%k hat %o dem Erdboden gleichgemacht,Ο/Η %k ησοπέδοσε @[pro2_gr] %o,%k platigis %o,%k ha aplanado a %o,%k aplanó a %o,%k lyttäsi %o paran,%k a aplati %o,%k kilapította %o -t,%k ha schiacciato %o,%k は %o をぶっ潰した。,%k 은(는) %o 의 코를 납작하게 만들었다.,%k plette %o,%k flatet ut %o,%k rozpłaszczył@[ao_pl] %o,%k achatou %o,%k espalmou %o,%k l-a făcut plat pe %o,%k сплюснул игрока %o,%k је изравнао %o,%k plattade %o,"%o, %k tarafından dümdüz edildi.",%k сплющи@[adj_1_ua] %o, +%k gave %o Anal Justice,TXT_OBITUARY9,,,,%o utržil@[ao_cs] anální spravedlnost od hráče %k,%k lemlæstede %o,%k hat %o anale Gerechtigkeit gegeben,Ο/Η %k γάμησε @[pro2_gr] %o @[pro3_gr] κόλο,%k donis pugan juston al %o,%k le ha dado justicia anal a %o,%k le dió justicia anal a %o,%k jakoi %o paralle anaalioikeutta,%k a rendu une justice anale a %o,%k Anális Igazságot adott %o -nak ,%k ha dato a %o Giustizia Anale,%k は %o のケツにぶち込んだ。,%k 은(는) %o 에게 홍콩행을 보냈다.,%k gaf %o anale rechtvaardigheid,%k ga %o anal rettferdighet,%k dał@[ao_pl] %o Analną Sprawiedliwość,%k deu Justiça Anal para %o,,%k i-a făcut jucătorului %o o Justiție Anală,%k устроил анальное правосудие игроку %o,%k је дао %o аналну правду,%k gav %o anal rättvisa,"%o, %k tarafından dümdüz edildi.",%k влаштува@[adj_1_ua] анальне правосуддя %o, +%k gave AnAl MaDnEsS to %o,TXT_OBITUARY10,,,,%o utrpěl@[ao_cs] AnÁlNí ŠíLeNsTvÍ od hráče %k,%k spildte %o,%k gab %o AnAlEn WaHnSiNn,Ο/Η %k έσκισε τον κόλο του/της] %o,%k donis pUgAn frEnEzOn al %o,%k le ha dado LoCuRa AnAl a %o,%k le dió LoCuRa AnAl a %o,%k teki %o paran AnAaLiHuLlUkSi,%k a donné la FOLIE ANALE a %o,%k SeGgBe KüLDtE %o -t,%k ha dato FoLlIa AnAle a %o,%k は %o のケツをガバガバにした。,%o 은(는) %k 의 찰진 맛을 보았다.,%k gaf aNaLe DoLhEiD aan %o,%k ga %o anal rettferdighet,%k dał@[ao_pl] %o AnAlNe SzAlEńStWo ,%k deu LoUcUrA aNaL para %o,,%k i-a dat NeBuNiE AnAlĂ jucătorului %o,%k устроил АнАЛ КаРнаВаЛ игроку %o,%k је дао АнАлНо ЛуДиЛо %o,%k gav %o anal rättvisa,"%o, %k tarafından dümdüz edildi.",%k влаштува@[adj_1_ua] АнАЛ ГуЛяНнЯ %o, +%k killed %o,TXT_OBITUARY11,,,,%o byl@[ao_cs] zabit@[ao_cs] hráčem %k,%k dræbte %o,%k hat %o getötet,Ο/Η %k σκότωσε @[pro2_gr] %o,%k mortigis %o,%k ha matado a %o,%k mató a %o,%k tappoi %o paran,%k a tué %o,%k kicsinálta %o -t,%k ha ucciso %o,%k は %o をブッ殺した。,%k 은(는) %o 을(를) 죽였다.,%k doodde %o,%k drepte %o,%k zabił@[ao_pl] %o,%k matou %o,,%k l-a omorât pe %o,%k убил игрока %o,%k је убио %o,%k dödade %o,"%o, %k tarafından öldürüldü.",%k вби@[adj_1_ua] %o, +%k made mincemeat out of %o,TXT_OBITUARY12,,,,%o byl@[ao_cs] namelen@[ao_cs] hráčem %k,%k gjorde hakket kød af %o,%k hat %o zu Hackfleisch verarbeitet,Ο/Η %k έφτιαξε κυμά με @[pro2_gr] %o,%k farigis farĉon el %o,%k ha hecho picadillo de %o,%k hizo picadillo de %o,%k teki jauhelihaa %o parasta,%k a fait de la viande hachée de %o,%k ledarálta %o -t,%k ha triturato %o,%k は %o をミンチにした。,%o 은(는) %k 에 의해 분쇄됐다.,%k maakte gehakt van %o,%k laget kjøttdeig av %o,%k zrobił@[ao_pl] mięso mielone z %o,%k fez carne moída de %o,%k fez carne picada do %o,%k a facut tocătură din %o,%k сделал отбивную из игрока %o,%k је направио млевено месо од %o,%k gjorde köttfärs av %o,"%o, %k tarafından kıyma haline getirildi.",%k зроби@[adj_1_ua] відбивну з %o, +%k massacred %o,TXT_OBITUARY13,,,,%o byl@[ao_cs] zmasakrován@[ao_cs] hráčem %k,%k massakrerede %o,%k hat %o niedergemetzelt,Ο/Η %k δολοφώνησε @[pro2_gr] %o,%k masakris %o,%k ha masacrado a %o,%k masacró a %o,%k verilöylytti %o parkaa,%k a massacré %o,%k lemészárolta %o -t,%k ha fatto di %o carne tritata,%k は %o を虐殺した。,%k 은(는) %o 을(를) 참살했다.,%k slachtte %o af,%k massakrerte %o,%k zmasakrował@[ao_pl] %o,%k massacrou %o,,%k a fost masacrat de către %o,%k устроил бойню игроку %o,%k је масакрирао %o,%k massakrerade %o,"%o, %k tarafından katledildi",%k влаштува@[adj_1_ua] для %o бійню, +%k mutilated %o,TXT_OBITUARY14,,,,%o byl@[ao_cs] zmrzačen@[ao_cs] hráčem %k,%k lemlæstede %o,%k hat %o verstümmelt,Ο/Η %k ακρωτηριάσε @[pro2_gr] %o,%k mutilis %o,%k ha mutilado a %o,%k mutiló a %o,%k silpoi %o paran,%k a mutilé %o,%k megcsonkította %o -t,%k ha massacrato %o,%k は %o をバラバラ死体にした。,%k 은(는) %o 의 팔다리를 절단했다.,%k verminkte %o,%k lemlestet %o,%k rozszarpał@[ao_pl] %o,%k mutilou %o,,%k l-a mutilat pe %o,%k изуродовал игрока %o,%k је мутилирао %o,%k lemlästade %o,"%o, %k tarafından sakat bırakıldı.",%k знівечи@[adj_1_ua] %o, +%k reamed %o,TXT_OBITUARY15,,,,%o byl@[ao_cs] proděravěn@[ao_cs] hráčem %k,%k skændede %o,%k hat %o aufgerieben,Ο/Η %k δέσμισε @[pro2_gr] %o,%k alezis %o,%k ha escariado a %o,%k escarió a %o,%k porasi %o paran,%k a découpé en fines lamelles %o,%k seggbe rakta %o -t,%k ha squartato %o,%k は %o の穴を大きく広げた。,%k 은(는) %o 을(를) 크게 혼냈다.,%k holde %o uit,%k maltraktert %o,%k rozwiercił@[ao_pl] %o,%k esquartejou %o,,%k l-a transformat într-un top de hârtie pe %o,%k рассверлил игрока %o,%k је наоружао %o,%k har gjort %o illa.,"%o, %k tarafından öldürüldü.",%k просверли@[adj_1_ua] %o, +%k ripped %o a new orifice,TXT_OBITUARY16,,,,%o má novou díru od hráče %k,%k flåede %o en ny åbning,%k hat %o eine neue Körperöffnung verpasst,Ο/Η άνοιξε μια νέα τρύπα @[pro3_gr] %o,%k ŝiris novan truon en %o,%k le ha hecho a %o un nuevo orificio,%k le hizo a %o un nuevo orificio,%k repi %o paralle uuden aukon,%k a ouvert un nouvel orifice a %o,%k új szájat csinált %o -nak,%k ha aperto a %o un altro orifizio,%k は %o を切り裂いて新しい穴を作ってあげた。,%k 은(는) %o 을(를) 죽여 뜯어서 작품을 만들었다.,%k scheurde een opening uit %o,%k revet %o en ny kroppsåpning,%k rozerwał@[ao_pl] %o nowy otwór,%k abriu um novo orifício em %o,,%k i-a făcut jucătorului %o un nou orificiu,%k проделал новое отверстие в игроке %o,%k је исцепао %o нови отвор,%k slet upp en ny öppning i %o,"%o, %k tarafından yeni bir delik açıldı.",%k зроби@[adj_1_ua] в %o нову дірку, +%k slaughtered %o,TXT_OBITUARY17,,,,%o byl@[ao_cs] zavražděn@[ao_cs] hráčem %k,%k slagtede %o,%k hat %o geschlachtet,Ο/Η %k έσφαξε @[pro2_gr] %o,%k buĉis %o,%k ha sacrificado a %o,%k sacrificó a %o,%k teurasti %o paran,%k a meurtri %o,%k lemészárolta %o -t,%k ha macellato %o,%k は %o を屠殺した。,%o 은(는) %k 에 의해 도살당했다.,%k slachtte %o,%k slaktet %o,%k zarżn@[irreg_2_pl] %o,%k abateu %o,,%k l-a măcelărit pe %o,%k устроил резню игроку %o,%k је заклао %o,%k slaktade %o,"%o, %k tarafından katledildi.",%k прові@[adj_1_ua] різню %o, +%k smashed %o,TXT_OBITUARY18,,,,%o byl@[ao_cs] zmlácen@[ao_cs] hráčem %k,%k smadrede %o,%k hat %o zerklatscht,Ο/Η %k τσάκισε @[pro2_gr] %o,%k frakasis %o,%k ha destrozado a %o,%k destrozó a %o,%k murskasi %o paran,%k a enfoncé %o,%k földbe döngölte %o -t,%k ha distrutto %o,%k は %o をぶっ飛ばした。,%k 은(는) %o 을(를) 내팽개쳤다.,%k vermorzelde %o,%k knust %o,%k stłukł@[ao_pl] %o,%k esmagou %o,,%k l-a spart pe %o,%k размазал игрока %o,%k је поломио %o,%k krossade %o,"%o, %k tarafından ezildi.",%k розмаза@[adj_1_ua] %o, +%k sodomized %o,TXT_OBITUARY19,,,,Hráč %k se dopustil sodomie na hráči %o,%k sodomiserede %o,%k hat %o sodomisiert,Ο/Η %k γάμησε @[pro2_gr] %o,%k sodomizis %o,%k ha sodomizado a %o,%k sodomizó a %o,%k anaaliraiskasi %o paran,%k y a sodomisé n %o,%k szodomizálta %o -t,%k ha sodomizzato %o,%o は %k にカマを掘られた。 ,%o 은(는) %k 을(를) 위해 등을 보였다.,%k sodomiseerde %o,%k sodomisert %o,%k spenetrował@[ao_pl] %o,%k sodomizou %o,,%k l-a sodomizat pe %o,%k содомировал игрока %o,%k је изјебао %o,%k sodomiserade %o,"%o, %k tarafından sodomize edildi.",%k зґвалтува@[adj_1_ua] %o, +%k splattered %o,TXT_OBITUARY20,,,,%o byl@[ao_cs] rozplesknut@[ao_cs] hráčem %k,%k sprøjtede %o,%k hat %o zerspritzt,Ο/Η %k έσκασε @[pro2_gr] %o,%k disĵetis %o,%k ha rociado a %o,%k roció a %o,%k roiski %o paran yltympäri,%k a explosé de %o,%k szétloccsantotta %o -t,%k ha spiaccicato %o,%k は %o にばら撒かれた。,%k 은(는) %o 을(를) 박살냈다.,%k splette %o,%k sprutet %o,%k rozbryzgał@[ao_pl] %o,%k explodiu %o,,%k l-a împrăștiat pe %o,%k разбрызгал игрока %o,%k је спљоштио %o,%k sprutade %o.,"%o, %k tarafından parçalandı.",%k розбризка@[adj_1_ua] %o, +%k squashed %o,TXT_OBITUARY21,,,,%o byl@[ao_cs] rozmáčknut@[ao_cs] hráčem %k,%k kværnede %o,%k hat %o zerquetscht,Ο/Η %k πάτησε @[pro2_gr] %o,%k premplatigis %o,%k ha aplastado a %o,%k aplastó a %o,%k litisti %o paran,%k a écrabouillé %o,%k eltaposta %o -t,%k ha schiacciato %o,%k は %o に潰された。,%k 은(는) %o 을(를) 짓이겼다.,%k plette %o,%k knust %o,%k zmiażdżył@[ao_pl] %o,%k espatifou %o,,%k l-a strivit pe %o,%k расплющил игрока %o,%k је згњечио %o,%k krossade %o,"%o, %k tarafından ezildi.",%k розчави@[adj_1_ua] %o, %k throttled %o,TXT_OBITUARY22,,,,%o byl@[ao_cs] zaškrcen@[ao_cs] hráčem %k,%k kvæler %o,%k hat %o erdrosselt,Ο/Η %k κομμάτιασε @[pro2_gr] %o,%k strangolis %o,%k ha estrangulado a %o,%k ahorcó a %o,%k polki %o paran,%k a étouffé %o,%k megfolytotta %o -t,%k ha strozzato %o,%k は %o に絞られた。,%k 은(는) %o 을(를) 목 졸라 죽였다.,%k wurgde %o,%k kvalt %o,"%k udusił@[ao_pl] %o -",%k estrangulou %o,,%k l-a strâns de gât pe %o,%k задушил игрока %o,%k је угушио %o,"%o, %k tarafından boğazlandı.",%k вдушив %o, -%k wasted %o,TXT_OBITUARY23,,,,%o byl@[ao_cs] zničen@[ao_cs] hráčem %k,%k spildte %o,%k hat %o verbraucht,Ο/Η %k σκότωσε @[pro2_gr] %o,%k malŝparis %o,%k ha desechado a %o,%k desechó a %o,%k kulutti %o paran,%k a décharné %o,%k elpusztította %o -t,%k ha distrutto %o,%k は %o に消された。,%k 은(는) %o 을(를) 쓰레기처럼 내다 버렸다.,%k maakte %o koud,%k bortkastet %o,%k roztrwonił@[ao_pl] %o,%k detonou %o,,%k l-a risipit pe %o,%k замочил игрока %o,%k је убио %o,"%o, %k tarafından harcandı.",%k загнав у могилу %o, -%k body bagged %o,TXT_OBITUARY24,,,,Hráč %k narval %o@[psn1_cs] tělo do pytle,%k tog %o i en pose med kroppen,%k hat %o eingesackt,Ο/Η %k έχωσε @[pro2_gr] %o στη κάσα του/της,%k ensakigis %o,%k ha embolsado a %o,%k embolsó a %o,%k kääri %o paran ruumispussiin,%k a placé %o dans son linceul,%k összecsomagolta %o -t,%k ha mandato %o all'obitorio,%k は %o を死体袋にした。,%k 은(는) %o 의 장례식을 치렀다.,%k stopte %o in een lijkzak,%k lagt %o i likpose,%k spakował@[ao_pl] %o do torby na zwłoki,%k mandou %o para o necrotério,,%k l-a băgat în sac pe %o,%k упаковал игрока %o в мешок для трупов,%k је умртвио %o,"%o, %k tarafından öldürüldü.",%k запакував %o в мішок для трупів, -%k sent %o to Hell,TXT_OBITUARY25,,,,%o byl@[ao_cs] poslán@[ao_cs] do pekla hráčem %k,%k sendte %o til helvede,%k hat %o zur Hölle fahren lassen,Ο/Η %k έστειλε @[pro2_gr] %o στο δίαολο,%k sendis %o al Infero,%k ha enviado a %o al infierno,%k mandó a %o al infierno,%k lähetti %o paran helvettiin,%k a envoyé %o en enfer,%k elküldte %o -t a Pokolba,%k ha spedito %o all'Inferno,%k は %o を地獄に送った。,%o 은(는) %k 덕에 지옥으로 돌아갔다.,%k zond %o naar de hel,%k sendt %o til helvete,%k wysłał@[ao_pl] %o do Piekła,%k mandou %o para o Inferno,,%k l-a trimis pe %o în Infern,%k отправил в ад игрока %o,%k је послао %o до Врага,"%o, %k tarafından cehenneme gönderildi.",%k послав %o до дідька лисого, -%k toasted %o,TXT_OBITUARY26,,,,%o byl@[ao_cs] upečen@[ao_cs] hráčem %k,%k skålede %o,%k hat %o geröstet,Ο/Η %k έψησε @[pro2_gr] %o,%k tostis %o,%k ha tostado a %o,%k tostó a %o,%k käristi %o paran,%k a grillé %o,%k megpirította %o -t,%k ha arrostito %o,%k は %o を焼却した。,%o 은(는) %k 덕에 맛있게 구워졌다.,%k roosterde %o,%k ristet %o,%k stostował@[ao_pl] %o,%k tostou %o,,%k l-a prăjit pe %o,%k поджарил игрока %o,%k је тостирао %o,"%o, %k tarafından öldürüldü.",%k піджарив %o, -%k snuffed %o,TXT_OBITUARY27,,,,%o byl@[ao_cs] rozsápán@[ao_cs] hráčem %k,%k snusede %o,%k hat %o vernichtet,Ο/Η %k έσβησε @[pro2_gr] %o,%k snufis %o,%k ha aspirado a %o,%k aspiró a %o,%k sammutti %o paran,%k a crevé %o,%k kinyiffantotta %o -t,%k ha spento %o,%k は %o を処刑した。,%o 은(는) %k 에 의해 짓눌려졌다.,%k legde %o om,%k snuffet %o,%k powąchał@[ao_pl] %o,%k apagou %o,,%k l-a mirosit pe %o,%k прикончил игрока %o,%k је угасио %o,"%o, %k tarafından öldürüldü.",%k загасив %o, -%k hosed %o,TXT_OBITUARY28,,,,%o byl@[ao_cs] odstříknut@[ao_cs] hráčem %k,%k sprøjtede %o,%k hat %o eingetütet,Ο/Η %k έονιξε @[pro2_gr] %o σε σφαίρες,%k hosis %o,%k se ha cargado a %o,%k se cargó a %o,%k pesi %o paran,%k a arrosé %o,%k felhúzta %o gatyáját,%k l'ha fatta sopra %o,%k は %o にぶっかけた。,%k 은(는) %o 을(를) 패배로 씻겼다.,%k bespoot %o,%k spylt med vann %o,%k załatwił@[ao_pl] %o,%k metralhou %o,,%k a pus furtunul pe %o,%k расстрелял игрока %o,%k је упскао %o,"%o, %k'in hışmına uğradı.",%o перепало від %k, -%k sprayed %o,TXT_OBITUARY29,,,,%o byl@[ao_cs] postříkán@[ao_cs] hráčem %k,%k sprøjtede %o,%k hat %o pulverisiert,Ο/Η %k ψέκασε @[pro2_gr] %o,%k ŝprucigis %o,%k ha pulverizado a %o,%k pulverizó a %o,%k ruiskutti %o paran,%k a pulvérise %o,%k szétporlasztotta %o -t,%k ha vaporizzato %o,%k は %o を撒き散らした。,%o 의 피는 %k 의 물감으로 쓰였다.,%k besproeide %o,%k sprayet %o,%k rozpryskał@[ao_pl] %o,%k pulverizou %o,,%k l-a pulverizat pe %o,%k распылил игрока %o,%k је испрскао %o,"%o, %k tarafından püskürtüldü.",%k розпилили %o, -%k made dog meat out of %o,TXT_OBITUARY30,,,,%o byl@[ao_cs] hozen@[ao_cs] psům hráčem %k,%k lavede hundekød ud af %o,%k hat Hundefutter aus %o gemacht,Ο/Η %k γύρισε @[pro2_gr] %o σε κιμά,%k farigis hundan viandon el %o,%k ha hecho comida para perros de %o,%k hizo alimento para perros de %o,%k teki %o parasta koiranruokaa,%k a fait de la pâtée pour chien de %o,%k döghúst csinált %o -ból,%k ha fatto di %o polpette,%k は %o を犬の餌にした。,%k 은(는) %o 로 개밥을 만들었다.,%k maakte hondenvlees van %o,%k laget hundekjøtt av %o,%k zrobił@[ao_pl] mięso dla psów z %o,%k fez almôndegas de %o,,%k l-a transformat în mâncare de câini pe %o,%k скормил псам игрока %o,%k је направио псеће месо од %o,"%o, %k tarafından köpek etine dönüştürüldü.",%k зтовк %o до псєчих харчів, -%k beat %o like a cur,TXT_OBITUARY31,,,,%o byl@[ao_cs] zmlácen@[ao_cs] jako pes hráčem %k,%k bankede %o som en skiderik,%k hat %o wie einen Hund geschlagen,Ο/Η %k πλάκοσε @[pro2_gr] %o σαν κοπρίτης,%k batis %o kiel hundaĉon,%k ha pateado a %o como a un perro callejero,,%k huitoi %o parkaa kuin rakkia,%k a battu %o,%k szétverte %o -t mint egy korcsot,%k ha battuto %o come un cane,%k は %o を狂犬の様に扱った。,%o 은(는) %k 에게 똥개처럼 맞았다.,%k sloeg %o als een hond,%k slått %o som en hund,%k pobił@[ao_pl] %o jak kundla,%k espancou %o como um cachorro,%k espancou %o como um cão,%k îl bate pe %o ca pe o jigodie,%k сделал игрока %o как худую свинью,%k је превио %o ко мачку,"%o, %k tarafından dövüldü.",%k відбив печінки %o, -%o is excrement,TXT_SELFOBIT1,,,,%o je exkrement,%o er ekskrementer,%o wurde zu Exkrement verarbeitet,@[art_gr] %o είναι κόπρανα,%o estas ekskremento,%o es excremento,,%o on ulostetta,%o est une merde,%o ürülék lett,%o è un escremento,%o はもはや排泄物のようだ。,%o 은(는) 배설물이 되었다.,%o is uitschot,%o er ekskrementer,%o został@[ao_pl] odpadkami,%o virou escremento,,%o e excrement,%o теперь экскремент,%o је сада измет,%o dışkıdır,%o тепер екскремент, -%o is hamburger,TXT_SELFOBIT2,,,,%o je hamburger,%o er en hamburger,%o ist Hamburger,@[art_gr] %o είναι χάμπουργκερ,%o estas hamburgero,%o es una hamburguesa,,%o on hakkelusta,%o est un hamburger,%o hamburger lett,%o è un hamburger,%o はハンバーガーになった。,%o 은(는) 고기 반죽이 되었다.,%o is hamburger,%o er hamburger,%o został@[ao_pl] hamburgerem,%o virou hambúrguer,,%o e hamburger,%o теперь гамбургер,%o је сада пљескавица,%o hamburgerdir,%o тепер гамбургер, -%o suffered scrotum separation,TXT_SELFOBIT3,,,,%o prodělal@[ao_cs] separaci šourku,%o fik skrotumskæring,%os Eier wurden gebraten,Οι όρχις @[pro4_gr] %o βγήκανε,%o suferis skrotan disigon,%o ha sufrido separación de escroto,%o sufrió separación de escroto,%o kärsii kivespussin erotuksesta,%o a souffert d'une séparation du scrotum,%o heréi szétváltak,%o ha subito la separazione dello scroto,%o の陰嚢は剥離していた。,%o 은(는) 고자가 되었다.,%o onderging scrotumscheiding,%o led pungseparasjon,%o doznał@[ao_pl] oddzielenia moszny,%o sofreu separação escrotal,,%o a suferit o separație de șcrot,%o страдает от потери тестикул,%o му је исечена патка,%o skrotum ayrılması yaşadı,%o постраждав від втрати мошонки, -%o volunteered for population control,TXT_SELFOBIT4,,,,%o se zúčastnil@[ao_cs] čistky obyvatelstva,%o meldte sig frivilligt til befolkningskontrol,%o hat sich freiwillig zur Bevölkerungskontrolle gemeldet,@[art_gr] %o εθελώντησε για έλεγχο του πληθυσμού,%o volontulis por loĝantara regado,%o se ha hecho voluntario para control de población,%o se hizo voluntario para control de población,%o ilmoittautui vapaaehtoiseksi väestönhallintaan,%o s'est proposé pour un contrôle de la population,%o önként jelentkezett népességszabályozásra,%o si è offerto per il controllo della popolazione,%o は人口削減政策の実験台に志願した。,%o 은(는) 자연에 의해 낙태 당했다.,%o was vrijwilliger voor bevolkingsbeperking,%o meldte seg frivillig til befolkningskontroll,%o zgłosił@[ao_pl] się na kontrolę ludności,%o se voluntariou para o controle populacional,%o se voluntariou para o controlo populacional,%o a voluntariat pentru controlul populației,%o стал добровольцем в борьбе с перенаселением,%o је волунтирао за контролу популације,Nüfus kontrolü için %o gönüllü oldu,%o борется з перенаселенням, -%o has suicided,TXT_SELFOBIT5,,,,%o spáchal@[ao_cs] sebevraždu,%o har begået selvmord,%o hat Selbstmord begangen,@[art_gr] %o έχει αυτοκτονήση,%o sin mortigis,%o se ha suicidado,%o se suicidó,%o on tehnyt itsemurhan,%o s'est suicidé,%o öngyilkos lett,%o si è suicidato,%o は勝手にくたばった。,%o 은(는) 한심하게 자살했다.,%o heeft zelfmoord gepleegd,%o har begått selvmord,%o popełnił@[ao_pl] samobójstwo,%o se suicidou,%o suicidou-se,%o s-a sinucis,Игрок %o самоубился,%o је убио самог себе,%o intihar etti,%o самовбився, -%o received the Darwin Award,TXT_SELFOBIT6,,,,%o dostal@[ao_cs] Darwinovu cenu,%o modtog Darwin-prisen,%o hat den Darwinpreis erhalten,@[art_gr] %o κέρδισε το Darwin βραβείο,%o ricevis la Darwin-premion,%o ha recibido el Premio Darwin,%o recibió el Premio Darwin,%o sai Darwin-palkinnon,%o a recu la médaille Darwin,És a Darwin-díj nyertese: %o,%o ha ricevuto il Darwin Award,%o にはダーウィン賞が授与された。,%o 은(는) 다윈상을 받을 자격이 있다.,%o ontving de Darwin Award,%o mottok Darwin-prisen,%o otrzymał@[ao_pl] Nagrodę Darwina,%o ganhou o Prêmio Darwin,,%o a primit Premiul Darwin,Игрок %o получил премию Дарвина,%o је добио Дарвиново признање,%o Darwin Ödülü'nü aldı,%o отримав премію Дарвіна, -,USE_GENERIC_FONT,This is not a text to be translated but an engine switch for complex languages.,,,,,,,,,,,,,,1,1,,,,,,,,,,, +",%k estrangulou %o,,%k l-a strâns de gât pe %o,%k задушил игрока %o,%k је угушио %o,%k tog strypgrepp på %o,"%o, %k tarafından boğazlandı.",%k вдуши@[adj_1_ua] %o, +%k wasted %o,TXT_OBITUARY23,,,,%o byl@[ao_cs] zničen@[ao_cs] hráčem %k,%k spildte %o,%k hat %o verbraucht,Ο/Η %k σκότωσε @[pro2_gr] %o,%k malŝparis %o,%k ha desechado a %o,%k desechó a %o,%k kulutti %o paran,%k a décharné %o,%k elpusztította %o -t,%k ha distrutto %o,%k は %o に消された。,%k 은(는) %o 을(를) 쓰레기처럼 내다 버렸다.,%k maakte %o koud,%k bortkastet %o,%k roztrwonił@[ao_pl] %o,%k detonou %o,,%k l-a risipit pe %o,%k замочил игрока %o,%k је убио %o,%k slösade bort %o,"%o, %k tarafından harcandı.",%k загна@[adj_1_ua] у могилу %o, +%k body bagged %o,TXT_OBITUARY24,,,,Hráč %k narval %o@[psn1_cs] tělo do pytle,%k tog %o i en pose med kroppen,%k hat %o eingesackt,Ο/Η %k έχωσε @[pro2_gr] %o στη κάσα του/της,%k ensakigis %o,%k ha embolsado a %o,%k embolsó a %o,%k kääri %o paran ruumispussiin,%k a placé %o dans son linceul,%k összecsomagolta %o -t,%k ha mandato %o all'obitorio,%k は %o を死体袋にした。,%k 은(는) %o 의 장례식을 치렀다.,%k stopte %o in een lijkzak,%k lagt %o i likpose,%k spakował@[ao_pl] %o do torby na zwłoki,%k mandou %o para o necrotério,,%k l-a băgat în sac pe %o,%k упаковал игрока %o в мешок для трупов,%k је умртвио %o,%k dödade %o,"%o, %k tarafından öldürüldü.",%k запакува@[adj_1_ua] %o в мішок для трупів, +%k sent %o to Hell,TXT_OBITUARY25,,,,%o byl@[ao_cs] poslán@[ao_cs] do pekla hráčem %k,%k sendte %o til helvede,%k hat %o zur Hölle fahren lassen,Ο/Η %k έστειλε @[pro2_gr] %o στο δίαολο,%k sendis %o al Infero,%k ha enviado a %o al infierno,%k mandó a %o al infierno,%k lähetti %o paran helvettiin,%k a envoyé %o en enfer,%k elküldte %o -t a Pokolba,%k ha spedito %o all'Inferno,%k は %o を地獄に送った。,%o 은(는) %k 덕에 지옥으로 돌아갔다.,%k zond %o naar de hel,%k sendt %o til helvete,%k wysłał@[ao_pl] %o do Piekła,%k mandou %o para o Inferno,,%k l-a trimis pe %o în Infern,%k отправил в ад игрока %o,%k је послао %o до Врага,%k skickade %o till helvetet,"%o, %k tarafından cehenneme gönderildi.",%k посла@[adj_1_ua] %o до дідька лисого, +%k toasted %o,TXT_OBITUARY26,,,,%o byl@[ao_cs] upečen@[ao_cs] hráčem %k,%k skålede %o,%k hat %o geröstet,Ο/Η %k έψησε @[pro2_gr] %o,%k tostis %o,%k ha tostado a %o,%k tostó a %o,%k käristi %o paran,%k a grillé %o,%k megpirította %o -t,%k ha arrostito %o,%k は %o を焼却した。,%o 은(는) %k 덕에 맛있게 구워졌다.,%k roosterde %o,%k ristet %o,%k stostował@[ao_pl] %o,%k tostou %o,,%k l-a prăjit pe %o,%k поджарил игрока %o,%k је тостирао %o,%k rostade %o,"%o, %k tarafından öldürüldü.",%k піджари@[adj_1_ua] %o, +%k snuffed %o,TXT_OBITUARY27,,,,%o byl@[ao_cs] rozsápán@[ao_cs] hráčem %k,%k snusede %o,%k hat %o vernichtet,Ο/Η %k έσβησε @[pro2_gr] %o,%k snufis %o,%k ha aspirado a %o,%k aspiró a %o,%k sammutti %o paran,%k a crevé %o,%k kinyiffantotta %o -t,%k ha spento %o,%k は %o を処刑した。,%o 은(는) %k 에 의해 짓눌려졌다.,%k legde %o om,%k snuffet %o,%k powąchał@[ao_pl] %o,%k apagou %o,,%k l-a mirosit pe %o,%k прикончил игрока %o,%k је угасио %o,%k snusade %o,"%o, %k tarafından öldürüldü.",%k загаси@[adj_1_ua] %o, +%k hosed %o,TXT_OBITUARY28,,,,%o byl@[ao_cs] odstříknut@[ao_cs] hráčem %k,%k sprøjtede %o,%k hat %o eingetütet,Ο/Η %k έονιξε @[pro2_gr] %o σε σφαίρες,%k hosis %o,%k se ha cargado a %o,%k se cargó a %o,%k pesi %o paran,%k a arrosé %o,%k felhúzta %o gatyáját,%k l'ha fatta sopra %o,%k は %o にぶっかけた。,%k 은(는) %o 을(를) 패배로 씻겼다.,%k bespoot %o,%k spylt med vann %o,%k załatwił@[ao_pl] %o,%k metralhou %o,,%k a pus furtunul pe %o,%k расстрелял игрока %o,%k је упскао %o,%k sprutade %o,"%o, %k'in hışmına uğradı.",%o перепало від %k, +%k sprayed %o,TXT_OBITUARY29,,,,%o byl@[ao_cs] postříkán@[ao_cs] hráčem %k,%k sprøjtede %o,%k hat %o pulverisiert,Ο/Η %k ψέκασε @[pro2_gr] %o,%k ŝprucigis %o,%k ha pulverizado a %o,%k pulverizó a %o,%k ruiskutti %o paran,%k a pulvérise %o,%k szétporlasztotta %o -t,%k ha vaporizzato %o,%k は %o を撒き散らした。,%o 의 피는 %k 의 물감으로 쓰였다.,%k besproeide %o,%k sprayet %o,%k rozpryskał@[ao_pl] %o,%k pulverizou %o,,%k l-a pulverizat pe %o,%k распылил игрока %o,%k је испрскао %o,%k sprayade %o,"%o, %k tarafından püskürtüldü.",%k розпили@[adj_1_ua] %o, +%k made dog meat out of %o,TXT_OBITUARY30,,,,%o byl@[ao_cs] hozen@[ao_cs] psům hráčem %k,%k lavede hundekød ud af %o,%k hat Hundefutter aus %o gemacht,Ο/Η %k γύρισε @[pro2_gr] %o σε κιμά,%k farigis hundan viandon el %o,%k ha hecho comida para perros de %o,%k hizo alimento para perros de %o,%k teki %o parasta koiranruokaa,%k a fait de la pâtée pour chien de %o,%k döghúst csinált %o -ból,%k ha fatto di %o polpette,%k は %o を犬の餌にした。,%k 은(는) %o 로 개밥을 만들었다.,%k maakte hondenvlees van %o,%k laget hundekjøtt av %o,%k zrobił@[ao_pl] mięso dla psów z %o,%k fez almôndegas de %o,,%k l-a transformat în mâncare de câini pe %o,%k скормил псам игрока %o,%k је направио псеће месо од %o,%k gjorde hundkött av %o,"%o, %k tarafından köpek etine dönüştürüldü.",%k зтовк@[adj_3_ua] %o до псєчих харчів, +%k beat %o like a cur,TXT_OBITUARY31,,,,%o byl@[ao_cs] zmlácen@[ao_cs] jako pes hráčem %k,%k bankede %o som en skiderik,%k hat %o wie einen Hund geschlagen,Ο/Η %k πλάκοσε @[pro2_gr] %o σαν κοπρίτης,%k batis %o kiel hundaĉon,%k ha pateado a %o como a un perro callejero,,%k huitoi %o parkaa kuin rakkia,%k a battu %o,%k szétverte %o -t mint egy korcsot,%k ha battuto %o come un cane,%k は %o を狂犬の様に扱った。,%o 은(는) %k 에게 똥개처럼 맞았다.,%k sloeg %o als een hond,%k slått %o som en hund,%k pobił@[ao_pl] %o jak kundla,%k espancou %o como um cachorro,%k espancou %o como um cão,%k îl bate pe %o ca pe o jigodie,%k сделал игрока %o как худую свинью,%k је превио %o ко мачку,%k rostade %o,"%o, %k tarafından dövüldü.",%k відби@[adj_1_ua] печінки %o, +%o is excrement,TXT_SELFOBIT1,,,,%o je exkrement,%o er ekskrementer,%o wurde zu Exkrement verarbeitet,@[art_gr] %o είναι κόπρανα,%o estas ekskremento,%o es excremento,,%o on ulostetta,%o est une merde,%o ürülék lett,%o è un escremento,%o はもはや排泄物のようだ。,%o 은(는) 배설물이 되었다.,%o is uitschot,%o er ekskrementer,%o został@[ao_pl] odpadkami,%o virou escremento,,%o e excrement,%o теперь экскремент,%o је сада измет,%o är avföring,%o dışkıdır,%o тепер екскремент, +%o is hamburger,TXT_SELFOBIT2,,,,%o je hamburger,%o er en hamburger,%o ist Hamburger,@[art_gr] %o είναι χάμπουργκερ,%o estas hamburgero,%o es una hamburguesa,,%o on hakkelusta,%o est un hamburger,%o hamburger lett,%o è un hamburger,%o はハンバーガーになった。,%o 은(는) 고기 반죽이 되었다.,%o is hamburger,%o er hamburger,%o został@[ao_pl] hamburgerem,%o virou hambúrguer,,%o e hamburger,%o теперь гамбургер,%o је сада пљескавица,%o är hamburgare,%o hamburgerdir,%o тепер гамбургер, +%o suffered scrotum separation,TXT_SELFOBIT3,,,,%o prodělal@[ao_cs] separaci šourku,%o fik skrotumskæring,%os Eier wurden gebraten,Οι όρχις @[pro4_gr] %o βγήκανε,%o suferis skrotan disigon,%o ha sufrido separación de escroto,%o sufrió separación de escroto,%o kärsii kivespussin erotuksesta,%o a souffert d'une séparation du scrotum,%o heréi szétváltak,%o ha subito la separazione dello scroto,%o の陰嚢は剥離していた。,%o 은(는) 고자가 되었다.,%o onderging scrotumscheiding,%o led pungseparasjon,%o doznał@[ao_pl] oddzielenia moszny,%o sofreu separação escrotal,,%o a suferit o separație de șcrot,%o страдает от потери тестикул,%o му је исечена патка,%o fick pungen separerad,%o skrotum ayrılması yaşadı,%o постражда@[adj_1_ua] від втрати мошонки, +%o volunteered for population control,TXT_SELFOBIT4,,,,%o se zúčastnil@[ao_cs] čistky obyvatelstva,%o meldte sig frivilligt til befolkningskontrol,%o hat sich freiwillig zur Bevölkerungskontrolle gemeldet,@[art_gr] %o εθελώντησε για έλεγχο του πληθυσμού,%o volontulis por loĝantara regado,%o se ha hecho voluntario para control de población,%o se hizo voluntario para control de población,%o ilmoittautui vapaaehtoiseksi väestönhallintaan,%o s'est proposé pour un contrôle de la population,%o önként jelentkezett népességszabályozásra,%o si è offerto per il controllo della popolazione,%o は人口削減政策の実験台に志願した。,%o 은(는) 자연에 의해 낙태 당했다.,%o was vrijwilliger voor bevolkingsbeperking,%o meldte seg frivillig til befolkningskontroll,%o zgłosił@[ao_pl] się na kontrolę ludności,%o se voluntariou para o controle populacional,%o se voluntariou para o controlo populacional,%o a voluntariat pentru controlul populației,%o стал добровольцем в борьбе с перенаселением,%o је волунтирао за контролу популације,%o anmälde sig frivilligt till befolkningskontroll,Nüfus kontrolü için %o gönüllü oldu,%o борется з перенаселенням, +%o has suicided,TXT_SELFOBIT5,,,,%o spáchal@[ao_cs] sebevraždu,%o har begået selvmord,%o hat Selbstmord begangen,@[art_gr] %o έχει αυτοκτονήση,%o sin mortigis,%o se ha suicidado,%o se suicidó,%o on tehnyt itsemurhan,%o s'est suicidé,%o öngyilkos lett,%o si è suicidato,%o は勝手にくたばった。,%o 은(는) 한심하게 자살했다.,%o heeft zelfmoord gepleegd,%o har begått selvmord,%o popełnił@[ao_pl] samobójstwo,%o se suicidou,%o suicidou-se,%o s-a sinucis,Игрок %o самоубился,%o је убио самог себе,%o har begått självmord,%o intihar etti,%o самовби@[adj_2_ua], +%o received the Darwin Award,TXT_SELFOBIT6,,,,%o dostal@[ao_cs] Darwinovu cenu,%o modtog Darwin-prisen,%o hat den Darwinpreis erhalten,@[art_gr] %o κέρδισε το Darwin βραβείο,%o ricevis la Darwin-premion,%o ha recibido el Premio Darwin,%o recibió el Premio Darwin,%o sai Darwin-palkinnon,%o a recu la médaille Darwin,És a Darwin-díj nyertese: %o,%o ha ricevuto il Darwin Award,%o にはダーウィン賞が授与された。,%o 은(는) 다윈상을 받을 자격이 있다.,%o ontving de Darwin Award,%o mottok Darwin-prisen,%o otrzymał@[ao_pl] Nagrodę Darwina,%o ganhou o Prêmio Darwin,,%o a primit Premiul Darwin,Игрок %o получил премию Дарвина,%o је добио Дарвиново признање,%o fick Darwinpriset,%o Darwin Ödülü'nü aldı,%o отрима@[adj_1_ua] премію Дарвіна, +,USE_GENERIC_FONT,This is not a text to be translated but an engine switch for complex languages.,,,,,,,,,,,,,,1,1,,,,,,,,,,,, ,REQUIRED_CHARACTERS,This should list all uppercase characters that are REQUIRED for proper language display. If it is acceptable that accents get omitted a character should NOT be listed here!,,,ÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ,ÅÆØÉ,ÄÖÜẞ,ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ,ĈĜĤĴŜŬ,ÁÉÍÓÚÑÜ,,ÄÖ,ÀÂÇÉÈÊËÎÏÔŒÙÛŸ,ÁÉÍÓÖÚÜŐŰ,ÀÈÉÌÒÙ,,,"ÉËÖ -",ÅÆØÉ,ĄĆĘŁŃÓŚŹŻ,ÁÉÍÓÚÀÃÕÂÊÔÇ,,ĂÎȚÂȘ,АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ,АБВГДЂЕЖЗИЈКЛЉМНЊОПРСТЋУФХЦЧЏШ,ÖÜÇĞİŞ,АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ, -Full options menu,OPTMNU_FULLOPTIONS,,,,Úplná nastavení,Fuld menu med indstillinger,Alle Optionen,Πλήρες μενού ρυθμίσεον,Plena agordo-menuo,Menú de opciones completo,,Täysi asetusvalikko,Menu options complet,Teljes beállításmenü,Opzioni complete,全オプション欄,전체 옵션 메뉴,Alle opties tonen,Full alternativmeny,Pełne Menu Opcji,Menu de opções completo,,Meniu Setări Complet,Полное меню настроек,,Tam seçenekler menüsü,Повне меню налаштувань, -Simple options menu,OPTMNU_SIMPLEON,,,,Zjednodušená nastavení,Enkel menu med indstillinger,Einfaches Optionsmenü,Απλό μενού ρυθμίσεον,Simpla agordo-menuo,Menú de opciones simplificado,,Yksinkertainen asetusvalikko,Menu options simplifié,Egyszerű beállításmenü,Opzioni base,必要なオプションのみ,간단한 옵션 메뉴,Eenvoudig optiemenu,Enkel meny med alternativer,Proste Menu Opcji,Menu de opções simples,,Meniu Setări Simplificat,Упрощённое меню настроек,,Basit seçenekler menüsü,Спрощене меню налаштувань, -Browse Game Config,OPTMNU_OPENCONFIG,,,,Procházet konfigurační soubory,Gennemse spilkonfiguration,Konfigurationsdatei anzeigen,,Foliumi agordojn de ludo,Abrir carpeta de configuración de juego,,Selaa pelin asetuksia,Parcourir configuration,Játék konfiguráció böngészése,Apri le Configurazioni di Gioco,ゲームコンフィグ参照,게임 환경설정 찾아보기,Door gameconfiguratie bladeren,Bla gjennom spillkonfigurasjon,Przeglądaj Ustawienia Gry,Abrir pasta de configuração de jogo,,Caută Configurația Jocului,Открыть файл настроек игры,,Oyun Yapılandırmasına Gözat,Перегляд налаштувань гри, -Browse Screenshots,OPTMNU_OPENSCREENSHOTS,,,,Procházet snímky obrazovky,Gennemse skærmbilleder,Screenshots anzeigen,,Foliumi ekrankopiojn,Abrir carpeta de capturas de pantalla,,Selaa kuvakaappauksia,Parcourir les captures d'écran,Képernyőképek böngészése,Apri gli Screenshot,クリーンショット参照,스크린샷 찾아보기,Door schermafbeeldingen bladeren,Bla gjennom skjermbilder,Przeglądaj Zrzuty Ekranu,Abrir pasta de capturas de tela,,Caută Capturi de Ecran,Просмотр снимков экрана,,Ekran Görüntülerine Gözat,Перегляд скріншотів, -Browse Saved Games,OPTMNU_OPENSAVES,,,,Procházet uložené hry,Gennemse gemte spil,Spielstände anzeigen,,Foliumi konservitajn ludadojn,Abrir carpeta de partidas guardadas,,Selaa tallennettuja pelejä,Parcourir sauvegardes,Elmentett játékok böngészése,Apri i Giochi Salvati,セーブしたゲーム参照,저장된 게임 찾아보기,Door opgeslagen games bladeren,Bla gjennom lagrede spill,Przeglądaj Zapisy Gry,Abrir pasta de jogos salvos,,Caută Salvări,Просмотр сохранённых игр,,Kaydedilen Oyunlara Gözat,Перегляд збережень ігр, -Swap mouse buttons,MOUSEMNU_SWAPBUTTONS,,,,Prohodit tlačítka myši,Udskift museknapper,Maustasten vertauschen,,Permuti musbutonojn,Alternar botones de ratón,,Vaihda hiiren painikkeita,Permuter les boutons de la souris,Egérgombok felcserélése,Inverti i comandi del mouse,マウスボタンを反転,마우스 버튼 바꾸기,Muisknoppen verwisselen,Bytt museknapper,Zamień Przyciski Myszki,Trocar botões do mouse,,Schimbă Butoanele Mouse-ului între Ele,Поменять местами кнопки мыши,,Fare düğmelerini değiştirme,Поміняти місцями кнопки миші, -,,,,,,,,,,,,,,,,,,,,,,,,,,,, -Only modified,OPTVAL_ONLYMODIFIED,,,,Pouze upravené,Kun ændret,Nur modfizierte,,Nur modifitaj,Solo modificados,,Vain muunneltu,Modifié seulement,Csak módosított,Solo modificato,モディファイのみ,수정된 것만,Alleen gewijzigd,Bare endret,Tylko zmodyfikowane,Somente modificado,,Numai modificat,Только изменённый,Само модификовано,Yalnızca değiştirilmiş,Тільки в модифікаціях, -Unknown,TXT_UNKNOWN,,,,Neznámé,Ukendt,Unbekannt,Άχνωστο,Nekonata,Desconocido,,Tuntematon,Inconnue,Ismeretlen,Sconosciuto,不明,알 수 없음,Onbekend,Ukjent,Nieznane,Desconhecido,,Necunoscut,Неизвестно,Непознат,Bilinmiyor,Невідомо, -HUD,OPTVAL_HUD,,,,,,,,,,,,ATH,,,,,,,,HUD,,,Отображение информации,,,Інтерфейс, -Automap,OPTVAL_AUTOMAP,,,,Automapa,,,,Aŭtomapo,Automapa,,,Carte,,Automappa,オートマップ,오토맵,,,Automapa,Automapa,,Hartă Computerizată,Автокарта,Аутомап,,Автокарта, -HUD + Automap,OPTVAL_HUDANDMAP,,,,HUD + Automapa,,,,HUD + Aŭtomapo,HUD + Automapa,,,ATH + Carte,,HUD + Automappa,HUD+オートマップ,HUD + 오토맵,,,HUD + Automapa,HUD + Automapa,,Interfață + Hartă Computerizată,Интерфейс + автокарта,HUD + Аутомап,,Інтерфейс + Автокарта, -This savegame needs these files,TXT_SAVEGAMENEEDS,,,,Uložená hra potřebuje tyto soubory,Dette savegame har brug for disse filer,Dieser Spielstand benötigt die folgenden Dateien,Το αρχείο αποθήκευσης χριάζετε αυτά τα αρχεία,Ĉi tiu konservita ludo bezonas ĉi tiujn dosierojn,Esta partida guardada necesita los siguientes archivos,,Tämä pelitallenne tarvitsee nämä tiedostot,Cette sauvegarde nécessite les fichiers suivants:,Ehhez a mentéshez a következő fájlok kellenek:,Questo salvataggio ha bisogno di questi file,このセーブデータには 必要なファイルがある,이 저장 된 게임은 해당 파일이 필요합니다.,Dit spel heeft de volgende bestanden nodig,Dette lagringsspillet trenger disse filene,Ten zapis gry potrzebuje tych plików,Este jogo salvo precisa destes arquivos,Este jogo guardado precisa destes arquivos,Acest joc salvat necesită următoarele fișiere,Данное сохранение требует следующие файлы,Овој сачуваној игри требају ови фајлови,Bu kayıt oyunu şu dosyalara ihtiyaç duyar,Цій грі потрібні такі файли, \ No newline at end of file +",ÅÆØÉ,ĄĆĘŁŃÓŚŹŻ,ÁÉÍÓÚÀÃÕÂÊÔÇ,,ĂÎȚÂȘ,АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ,АБВГДЂЕЖЗИЈКЛЉМНЊОПРСТЋУФХЦЧЏШ,ÄÖÅÉ,ÖÜÇĞİŞ,АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ, +Full options menu,OPTMNU_FULLOPTIONS,,,,Úplná nastavení,Fuld menu med indstillinger,Alle Optionen,Πλήρες μενού ρυθμίσεον,Plena agordo-menuo,Menú de opciones completo,,Täysi asetusvalikko,Menu options complet,Teljes beállításmenü,Opzioni complete,全オプション欄,전체 옵션 메뉴,Alle opties tonen,Full alternativmeny,Pełne Menu Opcji,Menu de opções completo,,Meniu Setări Complet,Полное меню настроек,,Fullständig alternativmeny,Tam seçenekler menüsü,Повне меню налаштувань, +Simple options menu,OPTMNU_SIMPLEON,,,,Zjednodušená nastavení,Enkel menu med indstillinger,Einfaches Optionsmenü,Απλό μενού ρυθμίσεον,Simpla agordo-menuo,Menú de opciones simplificado,,Yksinkertainen asetusvalikko,Menu options simplifié,Egyszerű beállításmenü,Opzioni base,必要なオプションのみ,간단한 옵션 메뉴,Eenvoudig optiemenu,Enkel meny med alternativer,Proste Menu Opcji,Menu de opções simples,,Meniu Setări Simplificat,Упрощённое меню настроек,,Enkel alternativmeny,Basit seçenekler menüsü,Спрощене меню налаштувань, +Browse Game Config,OPTMNU_OPENCONFIG,,,,Procházet konfigurační soubory,Gennemse spilkonfiguration,Konfigurationsdatei anzeigen,,Foliumi agordojn de ludo,Abrir carpeta de configuración de juego,,Selaa pelin asetuksia,Parcourir configuration,Játék konfiguráció böngészése,Apri le Configurazioni di Gioco,ゲームコンフィグ参照,게임 환경설정 찾아보기,Door gameconfiguratie bladeren,Bla gjennom spillkonfigurasjon,Przeglądaj Ustawienia Gry,Abrir pasta de configuração de jogo,,Caută Configurația Jocului,Открыть файл настроек игры,,Bläddra i spelkonfigurationen,Oyun Yapılandırmasına Gözat,Перегляд налаштувань гри, +Browse Screenshots,OPTMNU_OPENSCREENSHOTS,,,,Procházet snímky obrazovky,Gennemse skærmbilleder,Screenshots anzeigen,,Foliumi ekrankopiojn,Abrir carpeta de capturas de pantalla,,Selaa kuvakaappauksia,Parcourir les captures d'écran,Képernyőképek böngészése,Apri gli Screenshot,クリーンショット参照,스크린샷 찾아보기,Door schermafbeeldingen bladeren,Bla gjennom skjermbilder,Przeglądaj Zrzuty Ekranu,Abrir pasta de capturas de tela,,Caută Capturi de Ecran,Просмотр снимков экрана,,Bläddra bland skärmdumpar,Ekran Görüntülerine Gözat,Перегляд скріншотів, +Browse Saved Games,OPTMNU_OPENSAVES,,,,Procházet uložené hry,Gennemse gemte spil,Spielstände anzeigen,,Foliumi konservitajn ludadojn,Abrir carpeta de partidas guardadas,,Selaa tallennettuja pelejä,Parcourir sauvegardes,Elmentett játékok böngészése,Apri i Giochi Salvati,セーブしたゲーム参照,저장된 게임 찾아보기,Door opgeslagen games bladeren,Bla gjennom lagrede spill,Przeglądaj Zapisy Gry,Abrir pasta de jogos salvos,,Caută Salvări,Просмотр сохранённых игр,,Bläddra bland sparade spel,Kaydedilen Oyunlara Gözat,Перегляд збережень ігр, +Swap mouse buttons,MOUSEMNU_SWAPBUTTONS,,,,Prohodit tlačítka myši,Udskift museknapper,Maustasten vertauschen,,Permuti musbutonojn,Alternar botones de ratón,,Vaihda hiiren painikkeita,Permuter les boutons de la souris,Egérgombok felcserélése,Inverti i comandi del mouse,マウスボタンを反転,마우스 버튼 바꾸기,Muisknoppen verwisselen,Bytt museknapper,Zamień Przyciski Myszki,Trocar botões do mouse,,Schimbă Butoanele Mouse-ului între Ele,Поменять местами кнопки мыши,,Byta musknappar,Fare düğmelerini değiştirme,Поміняти місцями кнопки миші, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +Only modified,OPTVAL_ONLYMODIFIED,,,,Pouze upravené,Kun ændret,Nur modfizierte,,Nur modifitaj,Solo modificados,,Vain muunneltu,Modifié seulement,Csak módosított,Solo modificato,モディファイのみ,수정된 것만,Alleen gewijzigd,Bare endret,Tylko zmodyfikowane,Somente modificado,,Numai modificat,Только изменённый,Само модификовано,Endast ändrat,Yalnızca değiştirilmiş,Тільки в модифікаціях, +Unknown,TXT_UNKNOWN,,,,Neznámé,Ukendt,Unbekannt,Άχνωστο,Nekonata,Desconocido,,Tuntematon,Inconnue,Ismeretlen,Sconosciuto,不明,알 수 없음,Onbekend,Ukjent,Nieznane,Desconhecido,,Necunoscut,Неизвестно,Непознат,Okänd,Bilinmiyor,Невідомо, +HUD,OPTVAL_HUD,,,,,,,,,,,,ATH,,,,,,,,,,,Отображение информации,,,,Інтерфейс, +Automap,OPTVAL_AUTOMAP,,,,Automapa,,,,Aŭtomata mapo,Automapa,,,Carte,Auto-térkép,Automappa,オートマップ,오토맵,,,Automapa,Automapa,,Hartă Computerizată,Автокарта,Аутомап,,,Автокарта, +HUD + Automap,OPTVAL_HUDANDMAP,,,,HUD + Automapa,,,,HUD + Aŭtomata mapo,HUD + Automapa,,,ATH + Carte,HUD + Auto-térkép,HUD + Automappa,HUD+オートマップ,HUD + 오토맵,,,HUD + Automapa,HUD + Automapa,,Interfață + Hartă Computerizată,Интерфейс + автокарта,HUD + Аутомап,,,Інтерфейс + Автокарта, +This savegame needs these files,TXT_SAVEGAMENEEDS,,,,Uložená hra potřebuje tyto soubory,Dette savegame har brug for disse filer,Dieser Spielstand benötigt die folgenden Dateien,Το αρχείο αποθήκευσης χριάζετε αυτά τα αρχεία,Ĉi tiu konservita ludo bezonas ĉi tiujn dosierojn,Esta partida guardada necesita los siguientes archivos,,Tämä pelitallenne tarvitsee nämä tiedostot,Cette sauvegarde nécessite les fichiers suivants:,Ehhez a mentéshez a következő fájlok kellenek:,Questo salvataggio ha bisogno di questi file,このセーブデータには 必要なファイルがある,이 저장 된 게임은 해당 파일이 필요합니다.,Dit spel heeft de volgende bestanden nodig,Dette lagringsspillet trenger disse filene,Ten zapis gry potrzebuje tych plików,Este jogo salvo precisa destes arquivos,Este jogo guardado precisa destes arquivos,Acest joc salvat necesită următoarele fișiere,Данное сохранение требует следующие файлы,Овој сачуваној игри требају ови фајлови,Detta sparande behöver dessa filer,Bu kayıt oyunu şu dosyalara ihtiyaç duyar,Цій грі потрібні такі файли, +Multiplayer Options,OPTMNU_MULTIPLAYER,,,,Multiplayer,Multiplayer-indstillinger,Mehrspieleroptionen,,Agordoj de la plurludanta reĝimo,Opciones del multijugador,,,,,,,,Multiplayer Opties,Alternativer for flerspiller,,Opções de multijogador,,,Настройки сетевой игры,,Alternativ för flera spelare,Çok Oyunculu Seçenekler,Параметри багатокористувацької гри, +Input Options,OPTMNU_INPUT,,,,Vstupní zařízení,Input-indstillinger,Eingabeoptionen,,Enig-agordoj,Opciones de entrada (input),,,,,,,,In1voeropties,Alternativer for inndata,,Opções de entrada,,,Настройки ввода,,Inmatningsalternativ,Girdi Seçenekleri,Параметри введення, +System Options,OPTMNU_SYSTEM,,,,Systém,Systemindstillinger,Systemoptionen,,Agordoj de la sistemo,Opciones del sistema,,,,,,,,Systeem Opties,Systemalternativer,,Opções de sistema,,,Настройки системы,,Systemalternativ,Sistem Seçenekleri,Системні налаштування, +Light Options,OPTMNU_LIGHT,,,,Osvětlení,Lysindstillinger,Beleuchtungsoptionen,,Lum-agordoj,Opciones de iluminación,,,,,,,,Licht Opties,Alternativer for lys,,Opções de iluminação,,,Настройки освещения,,Alternativ för ljus,Işık Seçenekleri,Параметри освітлення, +Sprite Options,OPTMNU_SPRITE,,,,Sprity,Sprite-indstillinger,Spriteoptionen,,Agordoj de la mov-rastrumoj,Opciones de los «sprites»,,,,,,,,Sprite-opties,Sprite-alternativer,,Opções de sprite,,,Настройки спрайтов,,Alternativ för sprite,Sprite Seçenekleri,Параметри спрайтів, +Coronas,GLPREFMNU_CORONAS,,,,Záře,Coronas,,,Lum-ampoloj,Focos de luz,,,,,,,,Corona's,Koronaer,,,,,Лампы,,Koronor,Koronalar,Корони, +Appearance,DSPLYMNU_APPEARANCE,,,,Vzhled,Udseende,Spieldarstellung,,Aspekto,Apariencia,,,,,,,,Uiterlijk,Utseende,,Aparência,,,Внешность,,Utseende,Görünüş,Зовнішній вигляд, +Advanced Display Options,DSPLYMNU_ADVANCED,,,,Grafika (pokročilé),Avancerede visningsindstillinger,Erweiterte Anzeigeoptionen,,Altnivelaj ekran-agordoj,Opciones avanzadas de visualización,,,,,,,,Geavanceerde Weergave Opties,Avanserte visningsalternativer,,Opções avançadas de vídeo,,,Расширенные настройки экрана,,Avancerade visningsalternativ,Gelişmiş Görüntüleme Seçenekleri,Додаткові параметри відображення, \ No newline at end of file diff --git a/wadsrc/static/language.csv b/wadsrc/static/language.csv index c1179d374..4d2d803e6 100644 --- a/wadsrc/static/language.csv +++ b/wadsrc/static/language.csv @@ -1,14 +1,15 @@ -default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,tr -,,Miscellaneous,,,,,,,,,,,,,,,,,,,,,,,, -Press a key.,PRESSKEY,,,,Stiskni klávesu.,Tryk på en tast.,Drücke eine Taste,Πάτα οποιοδήποτε πλήκτρο.,Premu klavon.,Presiona una tecla.,,Paina jotain näppäintä.,Appuyez sur une touche.,Nyomjon meg egy gombot.,Premi un tasto.,何かキーを押せ,키를 누르시오.,Druk op een toets.,Trykk på en tast.,Wciśnij dowolny klawisz.,Aperte uma tecla.,Carrega numa tecla qualquer.,Apasă o tastă.,Нажмите любую клавишу.,Притисните било који тастер.,Bir tuşa bas. -A secret is revealed!,SECRETMESSAGE,,,,Nalezl[@ao_cs] jsi skrýš!,En hemmelighed bliver afsløret!,Ein Geheimnis wurde enthüllt!,Ένα μυστικό αποκαλύφθηκε!,Sekretejo estas malkaŝita!,¡Se ha revelado un secreto!,,Sala löydetty!,Vous avez découvert un secret!,Egy rejtekhely feltárva!,È stato svelato un segreto! ,シークレットを解き明かした!,비밀 발견!,Een geheim is onthuld!,En hemmelighet er avslørt!,Znaleziono sekret!,Segredo revelado!,,Ai găsit un secret!,Обнаружен тайник!,Откривена тајна!,Bir sır açığa çıkıyor! +default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,sv,tr +,,Miscellaneous,,,,,,,,,,,,,,,,,,,,,,,,, +Press a key.,PRESSKEY,,,,Stiskni klávesu.,Tryk på en tast.,Drücke eine Taste,Πάτα οποιοδήποτε πλήκτρο.,Premu klavon.,Presiona una tecla.,,Paina jotain näppäintä.,Appuyez sur une touche.,Nyomjon meg egy gombot.,Premi un tasto.,何かキーを押せ,키를 누르시오.,Druk op een toets.,Trykk på en tast.,Wciśnij dowolny klawisz.,Aperte uma tecla.,Carrega numa tecla qualquer.,Apasă o tastă.,Нажмите любую клавишу.,Притисните било који тастер.,Tryck på en tangent.,Bir tuşa bas. +A secret is revealed!,SECRETMESSAGE,,,,Nalezl[@ao_cs] jsi skrýš!,En hemmelighed bliver afsløret!,Ein Geheimnis wurde enthüllt!,Ένα μυστικό αποκαλύφθηκε!,Sekretejo estas malkaŝita!,¡Se ha revelado un secreto!,,Sala löydetty!,Vous avez découvert un secret!,Egy rejtekhely feltárva!,È stato svelato un segreto! ,シークレットを解き明かした!,비밀 발견!,Een geheim is onthuld!,En hemmelighet er avslørt!,Znaleziono sekret!,Segredo revelado!,,Ai găsit un secret!,Обнаружен тайник!,Откривена тајна!,En hemlighet avslöjas!,Bir sır açığa çıkıyor! "Useless mode ON. ",D_DEVSTR,,,,Zbytečný režim ZAP.,Ubrugelig tilstand slået til.,Nutzloser Modus EIN.,Άχρηστη λειτουργία είναι ΑΝΟΙΧΤΗ,Senutila reĝimo ŜALTITA.,"Modo inútil ACTIVADO. ",,Hyödytön tila PÄÄLLÄ.,"Mode inutile ON. ",Haszontalan mód BE.,"Modalità inutile ATTIVATA. ",このモードは使わないでおけ,쓸모없는 모드 켬.,Nutteloze modus AAN.,"Ubrukelig modus PÅ. ",Tryb bezużyteczny WŁĄCZONY.,"Modo inútil ATIVADO. -",,Modul inutil ACTIVAT.,Бесполезный режим ВКЛЮЧЁН.,Програмерски режим УКЉУЧЕН.,"Yararsız mod AÇIK. +",,Modul inutil ACTIVAT.,Бесполезный режим ВКЛЮЧЁН.,Програмерски режим УКЉУЧЕН.,"Oanvändbart läge på. +","Yararsız mod AÇIK. " "Are you sure you want to quit this great game?",QUITMSG,,,,"Jsi si jist@[adj_cs], že chceš opustit tuto skvělou hru?","Er du sikker på, at du vil forlade @@ -24,7 +25,7 @@ met dit geweldige spel?",Er du sikker på at du vil avslutte dette flotte spille wyjść z tej świetnej gry?","Deseja mesmo sair deste excelente jogo?","Tem a certeza que deseja sair deste excelente jogo?",Ești sigur că vrei să ieși din acest joc grozav?,"Ты действительно хочешь выйти -из этой замечательной игры?",Желиш ли заиста да изађеш из ове чудесне игре?,Bu harika oyunu bırakmak istediğine emin misin? +из этой замечательной игры?",Желиш ли заиста да изађеш из ове чудесне игре?,Är du säker på att du vill sluta med detta fantastiska spel?,Bu harika oyunu bırakmak istediğine emin misin? "You can't do load while in a net game! Press a key.",LOADNET,"In some languages, it may make more sense to translate “Press a key” as “Press any key.”",,,"Během síťové hry nelze načíst hru! @@ -69,7 +70,8 @@ Apasă orice tastă.","Невозможно загрузить сохранен Нажмите любую клавишу.","Не можете да учитате чување током мрежне игре! -Притисните тастер.",Bir ağ oyunundayken yükleme yapamazsınız! Bir tuşa basın. +Притисните тастер.","Du kan inte göra lastning när du är i ett nätspel! +Tryck på en tangent.",Bir ağ oyunundayken yükleme yapamazsınız! Bir tuşa basın. "You can't quickload during a netgame! Press a key.",QLOADNET,,,,"Během síťové hry nelze rychle načíst hru! @@ -114,7 +116,8 @@ Apasă orice tastă.","Невозможно загрузить быстрое с Нажмите любую клавишу.","Не можете да учитате брзо чување током мрежне игре! -Притисните тастер.","Bir ağ oyunu sırasında hızlı yükleme yapamazsınız! +Притисните тастер.","Du kan inte snabblasta under ett nätspel! +Tryck på en tangent.","Bir ağ oyunu sırasında hızlı yükleme yapamazsınız! Bir tuşa basın." "You haven't picked a quicksave slot yet! @@ -155,11 +158,12 @@ Aperte uma tecla.","Você ainda não escolheu um slot de quicksave! Carrega numa tecla qualquer.","Nu ai ales un slot pentru încărcare rapidă încă! -Apasă orice tastă.","Не выбран слот быстрого сохранения! +Apasă orice tastă.","Не выбрана ячейка быстрого сохранения! Нажмите любую клавишу.","Нисте још изабрали слот за брзо чување! -Притисните тастер.","Henüz bir hızlı kaydetme yuvası seçmediniz! +Притисните тастер.","Du har inte valt en plats för snabbsparning ännu! +Tryck på en tangent.","Henüz bir hızlı kaydetme yuvası seçmediniz! Bir tuşa basın." "You can't start a new game while in a network game. @@ -214,7 +218,8 @@ Apasă orice tastă.","Невозможно начать новую игру Нажмите любую клавишу.","Не можете да започнете нову игру током мрежне игре. -Притисните тастер.","Bir ağ oyunundayken yeni bir oyun başlatamazsınız. +Притисните тастер.","Du kan inte starta ett nytt spel när du är i ett nätspel. +Tryck på en tangent.","Bir ağ oyunundayken yeni bir oyun başlatamazsınız. Bir tuşa basın." "Are you sure? This skill level isn't even remotely fair. @@ -274,7 +279,9 @@ Apasă Y sau N.","Уверены? Этот уровень сложности Нажмите Y или N.","Сигурни сте? Овај ниво тежине није нимали фер. -Притисните Y или N.","Emin misiniz? Bu beceri seviyesi +Притисните Y или N.","Är du säker? Den här färdighetsnivån +är inte ens tillnärmelsevis rättvis. +Tryck på Y eller N.","Emin misiniz? Bu beceri seviyesi hiç adil değil. Y veya N'ye basın." @@ -361,7 +368,8 @@ Apasă orice tastă.","Это условно-бесплатная версия D Потребно је да наручите целу трилогију. -Притисните било који тастер.",Bu Doom'un shareware versiyonu. Tüm üçlemeyi sipariş etmeniz gerekiyor. Bir tuşa bas. +Притисните било који тастер.","Detta är sharewareversionen av Doom. Du måste beställa hela trilogin. +Tryck på en tangent.",Bu Doom'un shareware versiyonu. Tüm üçlemeyi sipariş etmeniz gerekiyor. Bir tuşa bas. "You can't end a netgame! Press a key.",NETEND,,,,"Síťovou hru nelze ukončit! @@ -404,7 +412,8 @@ Apasă orice tastă.","Невозможно закончить сетевую и Нажмите любую клавишу.","Не можете да завршите мрежну игру! -Притисните било који тастер.",Net oyununu bitiremezsin! Bir tuşa basın. +Притисните било који тастер.","Du kan inte avsluta ett nätspel! +Tryck på en tangent.",Net oyununu bitiremezsin! Bir tuşa basın. "Are you sure you want to end the game? Press Y or N.",ENDGAME,,,,"Opravdu si přeješ ukončit hru? @@ -447,12 +456,13 @@ Apasă Y sau N.","Вы действительно хотите закончит Нажмите Y или N.","Желите ли сигурно да завршите игру? -Притисните Y или N.",Oyunu bitirmek istediğinizden emin misiniz? Y veya N'ye basın. +Притисните Y или N.","Är du säker på att du vill avsluta spelet? +Tryck på Y eller N.",Oyunu bitirmek istediğinizden emin misiniz? Y veya N'ye basın. Are you sure you want to quit?,RAVENQUITMSG,,,,Přeješ si odejít?,"Er du sikker på, at du vil holde op?","Bist du dir sicher, dass du gehen willst?","Είσαι σίγουρος ότι θέλεις να φύγεις? -","Ĉu vi certas, ke vi volas forlasi?",¿Estás segur@[ao_esp] de que quieres salir?,,Haluatko varmasti lopettaa?,Êtes vous sûr de vouloir quitter ?,Biztosan ki akarsz lépni?,Sei sicuro di voler abbandonare?,本当に終了するのか?,정말 종료하시겠습니까?,Weet je zeker dat je wilt stoppen?,Er du sikker på at du vil avslutte?,Czy jesteś pewien że chcesz wyjść?,Deseja mesmo sair?,Tens a certeza que queres sair?,Ești sigur că vrei să ieși din joc?,Вы действительно желаете выйти?,Желите ли сигурно да изађете?,Çıkmak istediğinizden emin misiniz? -Only available in the registered version,SWSTRING,,heretic,,Dostupné pouze v registrované verzi,Kun tilgængelig i den registrerede version,Nur in der registrierten Version verfügbar,Μόνο διαθέσιμο στήν εχγραμμένη έκδοση.,Nur havebla en la komercaĵa versio,Solo disponible en la versión registrada,,Käytettävissä vain rekisteröidyssä versiossa,Disponible uniquement dans la version enregistrée,Csak a teljes verzióban érhető el,Disponibile solamente nella versione registrata,製品版でのみ可能だ。,정품 버전에서만 가능합니다,Alleen beschikbaar in de geregistreerde versie,Bare tilgjengelig i den registrerte versjonen,Dostępne tylko w zarejestrowanej wersji,Disponível somente na versão registrada,Apenas disponível na versão registrada,Disponibil doar în versiunea înregistrată.,Эпизод доступен только в полной версии,Само могуће у регистрованој верзији,Sadece kayıtlı sürümde mevcuttur -(Press Y to quit),DOSY,,,,(Stiskni Y pro odchod),(Tryk på Y for at afslutte),(Drücke Y zum Verlassen.),(Πάτα Y για να φύγεις),(Premu Y por forlasi),(Presiona Y para salir),,(Paina Y lopettaaksesi),(Appuyez sur Y pour revenir à votre OS.),(Nyomj Y-t a kilépéshez.),(Premi Y per uscire),(Y で終了),(Y을 누르시면 종료합니다),(Druk op Y om te stoppen),(Trykk Y for å avslutte),"(Wciśnij Y, aby wyjść)",(Aperte Y para sair),(Carrega Y para sair),(Apasă Y pentru a ieși),"(нажмите Y, чтобы выйти)",(Притисните Y да завршите),(Çıkmak için Y'ye basın) -,,Quit messages,,,,,,,,,,,,,,,,,,,,,,,, +","Ĉu vi certas, ke vi volas forlasi?",¿Estás segur@[ao_esp] de que quieres salir?,,Haluatko varmasti lopettaa?,Êtes vous sûr de vouloir quitter ?,Biztosan ki akarsz lépni?,Sei sicuro di voler abbandonare?,本当に終了するのか?,정말 종료하시겠습니까?,Weet je zeker dat je wilt stoppen?,Er du sikker på at du vil avslutte?,Czy jesteś pewien że chcesz wyjść?,Deseja mesmo sair?,Tens a certeza que queres sair?,Ești sigur că vrei să ieși din joc?,Вы действительно желаете выйти?,Желите ли сигурно да изађете?,Är du säker på att du vill avsluta?,Çıkmak istediğinizden emin misiniz? +Only available in the registered version,SWSTRING,,heretic,,Dostupné pouze v registrované verzi,Kun tilgængelig i den registrerede version,Nur in der registrierten Version verfügbar,Μόνο διαθέσιμο στήν εχγραμμένη έκδοση.,Nur havebla en la komercaĵa versio,Solo disponible en la versión registrada,,Käytettävissä vain rekisteröidyssä versiossa,Disponible uniquement dans la version enregistrée,Csak a teljes verzióban érhető el,Disponibile solamente nella versione registrata,製品版でのみ可能だ。,정품 버전에서만 가능합니다,Alleen beschikbaar in de geregistreerde versie,Bare tilgjengelig i den registrerte versjonen,Dostępne tylko w zarejestrowanej wersji,Disponível somente na versão registrada,Apenas disponível na versão registrada,Disponibil doar în versiunea înregistrată.,Эпизод доступен только в полной версии,Само могуће у регистрованој верзији,Endast tillgänglig i den registrerade versionen,Sadece kayıtlı sürümde mevcuttur +(Press Y to quit),DOSY,,,,(Stiskni Y pro odchod),(Tryk på Y for at afslutte),(Drücke Y zum Verlassen.),(Πάτα Y για να φύγεις),(Premu Y por forlasi),(Presiona Y para salir),,(Paina Y lopettaaksesi),(Appuyez sur Y pour revenir à votre OS.),(Nyomj Y-t a kilépéshez.),(Premi Y per uscire),(Y で終了),(Y을 누르시면 종료합니다),(Druk op Y om te stoppen),(Trykk Y for å avslutte),"(Wciśnij Y, aby wyjść)",(Aperte Y para sair),(Carrega Y para sair),(Apasă Y pentru a ieși),"(нажмите Y, чтобы выйти)",(Притисните Y да завршите),(Tryck på Y för att avsluta),(Çıkmak için Y'ye basın) +,,Quit messages,,,,,,,,,,,,,,,,,,,,,,,,, "Please don't leave, there's more demons to toast!",QUITMSG1,,,,"Nenechávej mě tu, je tu víc démonů k vymletí!","Du må ikke gå, der er flere @@ -467,7 +477,7 @@ demonów do stostowania!","Por favor, não vá embora. Tem mais demônios para torrar!","Por favor não te vás embora, há mais demônios para matar!","Te rog nu ieși, mai sunt demoni care trebuie prăjiți!","Пожалуйста, не уходи, тут ещё полно демонов для поджарки!","Молим те, не одлази! -Има још демона да се побије!","Lütfen gitmeyin, kadeh kaldıracak daha çok iblis var!" +Има још демона да се побије!","Lämna inte spelet, det finns fler demoner att skåla för!","Lütfen gitmeyin, kadeh kaldıracak daha çok iblis var!" "Let's beat it -- this is turning into a bloodbath!",QUITMSG2,,,,"Utečme -- začíná tu téct krev!","Lad os smutte - det her er @@ -481,7 +491,7 @@ um banho de sangue!","Falando a sério -- Isto está se a tornar num banho de sangue!","S-o lăsăm baltă -- situația degenerează într-o baie de sânge!","Давай покончим с этим — оно превращается в кровавую баню!","Хајде, бриши одавде -ако ти је ово одвећ крваво!","Hadi gidelim, ortalık kan gölüne dönüyor!" +ако ти је ово одвећ крваво!",Vi sticker - det här håller på att bli ett blodbad!,"Hadi gidelim, ortalık kan gölüne dönüyor!" "I wouldn't leave if I were you. DOS is much worse.",QUITMSG3,,,,"Být tebou, neodcházel bych. DOS je mnohem horší.","Jeg ville ikke gå, hvis jeg var dig. @@ -499,7 +509,7 @@ O DOS é bem pior.","Se fosse a ti não saia daqui. O DOS é bem pior.","Eu n-aș pleca în locul tău - sistemul DOS e mult mai rău.","На твоём месте я бы не уходил. DOS намного скучнее.","Да сам на твом месту, не бих одлазио. -DOS је много досаднији.",Yerinde olsam gitmezdim. DOS çok daha kötü. +DOS је много досаднији.",Jag skulle inte lämna om jag var du. DOS är mycket värre.,Yerinde olsam gitmezdim. DOS çok daha kötü. "You're trying to say you like DOS better than me, right?",QUITMSG4,,,,"Chceš mi říct, že máš radši DOS než mě?","Du prøver at sige, at du bedre @@ -515,7 +525,7 @@ ode mnie, prawda?","Tá querendo dizer que você gosta mais do DOS do que eu, é isso?","Estás a tentar dizer que gostas mais do do DOS do que eu, é isso?","Încerci să spui că-ți place de sistemul DOS mai mult decât de mine, așa-i?","Ты хочешь сказать, что DOS тебе нравится больше, чем я, а?","Више ти допада DOS -него ја, је ли?","DOS'u benden daha çok sevdiğini söylemeye çalışıyorsun, değil mi?" +него ја, је ли?","Du försöker säga att du gillar DOS bättre än mig, eller hur?","DOS'u benden daha çok sevdiğini söylemeye çalışıyorsun, değil mi?" "Don't leave yet -- there's a demon around that corner!",QUITMSG5,,,,"Ještě nechoď -- tam za rohem je démon!","Du må ikke gå endnu - der er en @@ -530,7 +540,7 @@ się w tamtym zaułku!","Não vá embora ainda, tem um demônio naquele canto!","Não te vás embora agora -- Está um demônio ao virar da esquina!",Nu pleca încă -- e un demon după colțul acela!,"Не уходи! За тем углом притаился ещё один монстр!","Немој да одеш -- -иза угла има још један демон!","Hemen gitme, şu köşede bir iblis var!" +иза угла има још један демон!",Gå inte än -- det finns en demon runt hörnet!,"Hemen gitme, şu köşede bir iblis var!" "Ya know, next time you come in here I'm gonna toast ya.",QUITMSG6,,,,"Tak hele, až se vrátíš, dostanu tě.","Ved du hvad, næste gang du @@ -546,11 +556,11 @@ stostuje cię.","Na próxima vez que você vier aqui, eu vou te detonar em pedaços.","Sabes, da próxima vez que vieres para aqui vou te fazer explodir em bocadinhos.","Să știi, data viitoare când treci pe-aici o să te prăjesc!","Знаешь, по возвращении тебя будут ждать большие неприятности.","Знаш, по повратку ће те -чекати велике невоље.","Biliyor musun, bir dahaki sefere buraya geldiğinde seni tost yapacağım." +чекати велике невоље.",Nästa gång du kommer hit ska jag skåla för dig.,"Biliyor musun, bir dahaki sefere buraya geldiğinde seni tost yapacağım." Go ahead and leave. see if I care.,QUITMSG7,,,,"Jen do toho, odejdi; schválně, jestli mi to bude jedno.",Gå bare. Se om jeg er ligeglad.,"Dann geh doch! Interessiert mich nicht.","Φύγε, δες αν νιάζομαι.",Ja foriru. Mi fajfas pri tio.,Ya vete. A ver si me importa.,,"Ole hyvä vain ja lähde. Arvaa, välitänkö.","Allez y, partez, allez voir si j'y suis.","Menj nyugodtan, nem mintha bárkit érdekelne.","Esci pure, sai che mi frega.",置いて行っちゃうんだ。勝手にしろ。,그럼 나가버려. 난 신경 안 써.,"Ga maar, eens kijken of het me interesseert.",Bare gå. Jeg bryr meg ikke.,"No dalej, odejdź. Zobaczymy czy -mnie to obchodzi.","Vai, pode ir embora. Tô nem aí.",Vai te em embora. Vê lá se eu quero saber.,"Hai, pleacă, vezi dacă-mi pasă.","Давай, уходи. Мне совершенно всё равно.","Хајде, одлази. Уопште ме није брига.",Devam et ve git. Bakalım umurumda olacak mı? +mnie to obchodzi.","Vai, pode ir embora. Tô nem aí.",Vai te em embora. Vê lá se eu quero saber.,"Hai, pleacă, vezi dacă-mi pasă.","Давай, уходи. Мне совершенно всё равно.","Хајде, одлази. Уопште ме није брига.",Gå du bara och se om jag bryr mig.,Devam et ve git. Bakalım umurumda olacak mı? "You want to quit? Then, thou hast lost an eighth!",QUITMSG8,More info here.,,,"Chceš odejít? Nuže, přišel jsi o přízeň boží!","Vil du gå? @@ -568,7 +578,7 @@ Só pode ter perdido a cabeça!","Queres sair? Só podes ter perdido a cabeça!","Vrei să ieși? Atunci, ai pierdut o virtute!","Всерьёз задумываешь выйти? Тем самым ты упустил что-то важное!","Озбиљно желиш да изађеш? -Није то нимало паметно!",Bırakmak mı istiyorsun? O zaman sekizde birini kaybettin! +Није то нимало паметно!",Vill du sluta? Då har du förlorat en åttondel!,Bırakmak mı istiyorsun? O zaman sekizde birini kaybettin! "Don't go now, there's a dimensional shambler waiting at the DOS prompt!",QUITMSG9,A “dimensional shambler” is a creature appearing in the works of H. P. Lovecraft.,,,"Teď neodcházej, na příkazové řádce @@ -595,7 +605,7 @@ te așteaptă la promptul DOS!","Не уходи сейчас, межпрост бродяга поджидает в DOS!","Немој да одеш! Међудимензионално чудовиште -чека код DOS промпта!","Şimdi gitme, DOS komut isteminde bekleyen boyutsal bir shambler var!" +чека код DOS промпта!","Gå inte nu, det finns en dimensionell shambler som väntar vid DOS-prompten!","Şimdi gitme, DOS komut isteminde bekleyen boyutsal bir shambler var!" "Get outta here and go back to your boring programs.",QUITMSG10,,,,"Vypadni odsud a vrať se ke svým nudným programům.","Forsvind herfra og gå tilbage @@ -612,7 +622,7 @@ os seus programas chatos.","Desaparece daqui e volta para os teus programas chatos.","Cară-te de aici și întoarce-te la programele tale plictisitoare.","Вот и убирайся отсюда к своим скучным программам.","Губи се одавде -својим досадним програмима.",Git buradan ve sıkıcı programlarına geri dön. +својим досадним програмима.",Försvinn härifrån och gå tillbaka till dina tråkiga program.,Git buradan ve sıkıcı programlarına geri dön. "If I were your boss, I'd deathmatch ya in a minute!",QUITMSG11,,,,"Být tvým šéfem, v deathmatchi bych tě zabil do minuty!","Hvis jeg var din chef, ville jeg @@ -628,7 +638,7 @@ para um mata-mata rapidinho!","Se eu fosse o teu chefe, lutava num deathmatch contigo agora mesmo!","Dacă eram șeful tău, te-aș fi luat la o rundă de deathmatch!","Будь я твоим боссом, я бы разобрался бы с тобой за минуту!","Да сам твој шеф, -средио бих те за један минут!","Patronun olsaydım, seni bir dakika içinde öldürürdüm!" +средио бих те за један минут!",Om jag var din chef skulle jag döda dig på en minut!,"Patronun olsaydım, seni bir dakika içinde öldürürdüm!" "Look, bud. you leave now and you forfeit your body count!",QUITMSG12,,,,"Hele, kámo, když teď odejdeš, přijdeš o svoje skóre!","Så, kammerat, hvis du flygter nu, @@ -645,7 +655,7 @@ a sua contagem de vítimas!","Olha, se saires agora perdes a tua contagem de mortes!","Uite, amice, pleci acum și renunți la numărul de cadavre!","Послушай, дружище. Выйдешь — и сбросишь свой счётчик убийств!","Чуј, ортак. Одеш ли, -изгубићеш свој број убистава!","Bak, dostum. Şimdi gidersen ceset sayını kaybedersin!" +изгубићеш свој број убистава!","Lyssna, kompis. Om du går nu förlorar du antalet döda!","Bak, dostum. Şimdi gidersen ceset sayını kaybedersin!" "Just leave. when you come back, I'll be waiting with a bat.",QUITMSG13,,,,"Jen odejdi. Až se vrátíš, budu čekat s baseballkou.","Bare gå. Når du kommer tilbage, @@ -662,7 +672,7 @@ vou estar te esperando com um taco.","Vá lá, sai. Quando voltares eu estarei a tua espera com uma moca.","Doar pleacă. Când te intorci o să te aștept cu o bâtă.","Уходи, уходи... но когда вернёшься, я буду ждать тебя с битой.","Иди, иди... али када се вратиш, -чекаћу те са палицом.",Sadece git. Geri döndüğünde bir sopayla bekliyor olacağım. +чекаћу те са палицом.",Gå bara. När du kommer tillbaka väntar jag med ett slagträ.,Sadece git. Geri döndüğünde bir sopayla bekliyor olacağım. "You're lucky I don't smack you for thinking about leaving.",QUITMSG14,,,,"Máš štěstí, že tě neprofackuju za to, že přemýšlíš o odchodu.","Du er heldig, at jeg ikke slår dig, @@ -680,7 +690,7 @@ uma surra por pensar em sair.","Tens muita sorte em eu não te dar um excerto de porrada por teres pensado em sair.","Ai noroc că nu-ți trag una pentru că te gândești să pleci.","Тебе повезло, что я не вмажу тебе за то, что ты выходишь.","Имаш среће што те не ошамарим -због тога што одлазиш.",Gitmeyi düşündüğün için seni tokatlamadığım için şanslısın. +због тога што одлазиш.",Du har tur att jag inte slår dig för att du funderar på att gå.,Gitmeyi düşündüğün için seni tokatlamadığım için şanslısın. "Where are you going?! What about the rebellion?",QUITMSG15,,,,"Kam jdeš?! A co bude s odbojem?","Hvor skal du hen?! @@ -698,7 +708,7 @@ E a rebelião?","Para onde estás a ir?! E então a rebelião?","Unde pleci?! Cu rebeliunea cum rămâne?","Куда ты собрался? А как же восстание?!","Где ћеш? -Шта ће бити са устанком?!",Nereye gidiyorsun?! İsyan ne olacak? +Шта ће бити са устанком?!",Vart är du på väg?! Hur blir det med upproret?,Nereye gidiyorsun?! İsyan ne olacak? "Carnage interruptus... What a tease!",QUITMSG16,,,,"Masakr přerušus... Takhle mě neškádli!","Carnage interruptus... @@ -716,7 +726,7 @@ Co za złośliwość!","Massacre interrompido... Que provocante!",,"Carnagiu întrerupt... Ce mai tachinare!","Вот так всегда... На самом интересном месте!","Покољ се прекида... -на најзанимљивијем месту!",Katliam kesintisi. Ne alay ama! +на најзанимљивијем месту!",Carnage interruptus... Vilket hångel!,Katliam kesintisi. Ne alay ama! "But you're the hope -- my only chance!!",QUITMSG17,,,,"Ale ty jsi naše naděje -- moje jediná šance!","Men du er håbet @@ -726,19 +736,19 @@ Mia ununura ŝanco!!","Pero tú eres la esperanza... -- ainoa mahdollisuuteni!!","Mais vous êtes l'espoir, notre unique chance!","Te vagy a remény -- az egyetlen esélyem!","Ma tu sei la speranza --- la mia unica possibilità!!","だがお前が希望なんだ --- 唯一の可能性だ!!",하지만 넌 희망이야- 나의 유일한 기회라고!!,Maar jij bent de hoop - Mijn enige kans!!,Men du er håpet... min eneste sjanse!!!,"Ale ty jesteś nadzieją +-- la mia unica possibilità!!","それでもお前を信じている +-- 唯一の希望なんだ!!",하지만 넌 희망이야- 나의 유일한 기회라고!!,Maar jij bent de hoop - Mijn enige kans!!,Men du er håpet... min eneste sjanse!!!,"Ale ty jesteś nadzieją -- moją jedyną szansą!!","Mas você é a esperança — minha única chance!","Mas tu és a nossa esperança -- a minha única chance!!","Dar tu ești speranța -- singura mea șansă!!","Но на тебя вся надежда — ты мой единственный шанс!","Али на тебе је сва нада -- -ти си моја једина шанса!","Ama sen umudumsun, tek şansımsın!" -Nobody walks out on Blackbird.,QUITMSG18,,,,Nikdo se neobrací zády ke Strace.,Ingen går ud fra Blackbird. ,Niemand lässt Blackbird stehen.,Κανένας δεν παρατάει τον Μπλακμπερτ.,Neniu forlasas BlackBird.,Nadie abandona a BlackBird.,,Kukaan ei käännä selkäänsä Blackbirdille.,Personne n'abandonne Blackbird!,Senki nem kezdhet ki a Feketerigóval!,Nessuno gira le spalle a Blackbird.,ブラックバードに気付かれず抜け出せるのか。,그 누구도 블랙버드를 내 버릴 수 없지.,Niemand loopt weg van Blackbird.,Ingen forlater Blackbird.,Nikt nie opuszcza Blackbird.,Ninguém vira as costas para a Blackbird.,,Nimeni nu iese afară pe Blackbird.,Ещё никто не ушёл от «Чёрного дрозда».,Нико још није побегао од Црне птице.,Kimse Karatavuk'ü bırakıp gidemez. -I thought you were different...,QUITMSG19,,,,"Myslela jsem, že jsi jin@[adj_cs]...","Jeg troede, du var anderledes...","Ich dachte, du wärst anders...",Νόμιζα οτι είσουν διαφορετικός...,"Mi pensis, ke vi estas malsama...",Pensé que eras diferente...,Creí que eras diferente...,"Luulin, että olit erilainen kuin muut...",Je vous croyais différent...,Azt hittem te más vagy...,Pensavo tu fossi diverso...,私は あなたは特別だと思っていた...,난 네가 다를 줄 알았는데...,Ik dacht dat je anders was....,Jeg trodde du var annerledes...,"Myślałam, że jesteś inny...",Eu achei que você era diferente...,Eu achei que eras diferente...,Am crezut că tu ești diferit...,Я думал о тебе иначе...,О теби сам мислила другачије...,Senin farklı olduğunu sanıyordum. +ти си моја једина шанса!",Men du är hoppet - min enda chans!!,"Ama sen umudumsun, tek şansımsın!" +Nobody walks out on Blackbird.,QUITMSG18,,,,Nikdo se neobrací zády ke Strace.,Ingen går ud fra Blackbird. ,Niemand lässt Blackbird stehen.,Κανένας δεν παρατάει τον Μπλακμπερτ.,Neniu forlasas BlackBird.,Nadie abandona a BlackBird.,,Kukaan ei käännä selkäänsä Blackbirdille.,Personne n'abandonne Blackbird!,Senki nem kezdhet ki a Feketerigóval!,Nessuno gira le spalle a Blackbird.,ブラックバードに気付かれず抜け出せるのか。,그 누구도 블랙버드를 내 버릴 수 없지.,Niemand loopt weg van Blackbird.,Ingen forlater Blackbird.,Nikt nie opuszcza Blackbird.,Ninguém vira as costas para a Blackbird.,,Nimeni nu iese afară pe Blackbird.,Ещё никто не ушёл от «Чёрного дрозда».,Нико још није побегао од Црне птице.,Ingen lämnar Blackbird.,Kimse Karatavuk'ü bırakıp gidemez. +I thought you were different...,QUITMSG19,,,,"Myslela jsem, že jsi jin@[adj_cs]...","Jeg troede, du var anderledes...","Ich dachte, du wärst anders...",Νόμιζα οτι είσουν διαφορετικός...,"Mi pensis, ke vi estas malsama...",Pensé que eras diferente...,Creí que eras diferente...,"Luulin, että olit erilainen kuin muut...",Je vous croyais différent...,Azt hittem te más vagy...,Pensavo tu fossi diverso...,私は あなたは特別だと思っていた...,난 네가 다를 줄 알았는데...,Ik dacht dat je anders was....,Jeg trodde du var annerledes...,"Myślałam, że jesteś inny...",Eu achei que você era diferente...,Eu achei que eras diferente...,Am crezut că tu ești diferit...,Я думал о тебе иначе...,О теби сам мислила другачије...,Jag trodde att du var annorlunda...,Senin farklı olduğunu sanıyordum. Fine! just kill and run!,QUITMSG20,,,,Fajn! Prostě zab a uteč!,Fint! Bare dræb og løb!,"Na toll! Töten und dann wegrennen.",Καλά! Απλώς σκότοσε και φύγε!,Bone! Nur mortigu kaj fuĝu!,¡Bien! ¡Matas y huyes!,,Hyvä! Senkun vain tapat ja lähdet!,"C'est ça! Tuez n'importe-qui -et barrez-vous comme ça!",Oké! Csak ölj és fuss!,Ma bravo! Uccidi e scappi!,いいぞ! ゲリラ戦の時間だ!,그래그래 알았다! 그럼 그냥 뛰고 죽이기나 해!,"Goed hoor, schieten en meteen wegrennen!",Greit! Bare drep og løp!,Dobra! Zabijaj i biegaj!,Ótimo! Mate e fuja!,Pronto! Mata e foge!,Fie! Doar omoară și fugi!,Отлично! Пострелял и смылся!,Добро! Само убијај и бежи!,İyi! Sadece öldür ve kaç! +et barrez-vous comme ça!",Oké! Csak ölj és fuss!,Ma bravo! Uccidi e scappi!,いいぞ! ゲリラ戦の時間だ!,그래그래 알았다! 그럼 그냥 뛰고 죽이기나 해!,"Goed hoor, schieten en meteen wegrennen!",Greit! Bare drep og løp!,Dobra! Zabijaj i biegaj!,Ótimo! Mate e fuja!,Pronto! Mata e foge!,Fie! Doar omoară și fugi!,Отлично! Пострелял и смылся!,Добро! Само убијај и бежи!,Okej! Döda bara och spring!,İyi! Sadece öldür ve kaç! "You can quit... but you can't hide...",QUITMSG21,,,,"Můžeš odejít... ale nemůžeš se skrýt...","Du kan stoppe... @@ -757,7 +767,8 @@ mas não pode se esconder...","Podes sair... mas não te podes esconder...","Poți să ieși... dar nu te poți ascunde...","Ты можешь уйти... но не можешь спрятаться...","Можеш да одеш... -али не можеш да се кријеш...",Bırakabilirsin... ama saklanamazsın... +али не можеш да се кријеш...","Du kan sluta... +men du kan inte gömma dig...",Bırakabilirsin... ama saklanamazsın... "Whaaa, what's the matter? Mommy says dinnertime?",QUITMSG22,,,,"Cóó, copak je? Maminka volá na večeři?","Whaaa, hvad er der i vejen? Mor siger spisetid?","Hey, was ist los? @@ -775,7 +786,8 @@ A mamãe disse que tá na hora da janta?","Qual é o problema? A mamã chamou para o jantar?","Ceee, ce s-a întâmplat? Mami zice că e timpul pentru cină?","Ха! В чём дело? Мама зовёт обедать?","Ха! Шта је било? -Мама те зове на вечеру?",Ne oldu? Annem yemek vakti mi dedi? +Мама те зове на вечеру?","Vad är det för fel? +Mamma säger att det är dags för middag?",Ne oldu? Annem yemek vakti mi dedi? "Don't quit now, there are still flemoids on the loose!",QUITMSG23,,,,"Teď neodcházej, stále tu pobíhají slizouni!","Du må ikke give op nu, der er stadig flemoider på fri fod!","Bitte gehe nicht, es laufen noch mehr @@ -788,7 +800,7 @@ flemoidi a piede libero!","まだやめないでくれ、 Ainda tem flemoides à solta!","Não desistas agora! Ainda há flemoids à solta!","Nu ieși acum, încă mai sunt flemoizi liberi!","Не выходи сейчас! Здесь есть ещё много флемоидов!","Немој сада да одустајеш! -Има још много љигавца! ","Şimdi pes etme, hala serbest flemoidler var!" +Има још много љигавца! ","Ge inte upp nu, det finns fortfarande flemoider på fri fot!","Şimdi pes etme, hala serbest flemoidler var!" "Don't give up -- the flemoids will get the upper hand!",QUITMSG24,,,,"Teď to nevzdávej - slizouni budou mít výhodu!","Du må ikke give op - Flemoiderne @@ -804,7 +816,7 @@ ci sopraffaranno!","あきらめてはダメだ、 vão levar a melhor!","Não desistas -- os flemóides estão a ganhar!",Nu renunța - flemoizii vor avea avantajul!,"Не сдавайся — не то флемоиды получат преимущество!","Немој да одустајеш -- -љигавци ће добити предност!","Sakın pes etme, flemoidler üstünlüğü ele geçirecek!" +љигавци ће добити предност!",Ge inte upp - flemoiderna kommer att ta överhanden!,"Sakın pes etme, flemoidler üstünlüğü ele geçirecek!" "Don't leave now. We need your help!",QUITMSG25,,,,"Teď neodcházej. Potřebujeme tvoji pomoc!",Du må ikke gå nu. Vi har brug for din hjælp!,"Bitte geh nicht. @@ -823,7 +835,7 @@ Precisamos da sua ajuda!","Não te vás embora agora. Nós precisamos da tua ajuda!","Nu pleca. Avem nevoie de ajutorul tău!","Не уходи сейчас. Нам нужна твоя помощь!","Не излази сада. -Треба нам твоја помоћ!",Şimdi gitmeyin. Yardımınıza ihtiyacımız var! +Треба нам твоја помоћ!",Gå inte nu. Vi behöver din hjälp!,Şimdi gitmeyin. Yardımınıza ihtiyacımız var! "I hope you're just taking a break for Chex(R) party mix.",QUITMSG26,,,,"Doufám, že si jen dáváš pauzu na Chex(R) Party Mix.","Jeg håber, at du bare holder en pause for Chex(R) party mix.","Ich hoffe mal, dass du nur eine @@ -839,7 +851,7 @@ pausa pra um Chex(R) Party Mix.","Espero que só estejas a fazer uma pausa pra um Chex(R) Party Mix.","Sper că iei doar o pauză cu un bol de cereale Chex(R).","Надеюсь, ты лишь делаешь перерыв на тарелку хлопьев Chex(R).","Надам се да само паузираш -за Chex житарице.",Umarım Chex(R) parti karışımı için ara vermişsinizdir. +за Chex житарице.",Jag hoppas att du bara tar en paus för Chex(R) party mix.,Umarım Chex(R) parti karışımı için ara vermişsinizdir. "Don't quit now! We need your help!",QUITMSG27,,,,"Teď neodcházej. Potřebujeme tvoji pomoc!",Du må ikke give op nu! Vi har brug for din hjælp!,"Bitte verlasse uns nicht. @@ -858,7 +870,7 @@ Precisamos da sua ajuda!","Não saias agora! Nós precisamos da tua ajuda!","Nu abandona acum! Avem nevoie de ajutorul tău!","Не бросай всё сейчас! Нам нужна твоя помощь!","Не одустај сада! -Треба нам твоја помоћ!",Şimdi bırakmayın! Yardımınıza ihtiyacımız var! +Треба нам твоја помоћ!",Sluta inte nu! Vi behöver din hjälp!,Şimdi bırakmayın! Yardımınıza ihtiyacımız var! "Don't abandon the Intergalactic Federation of Cereals!",QUITMSG28,,,,"Neopouštěj Intergalaktickou federaci cereálií!",Forlad ikke den Intergalaktiske Føderation af Cerealprodukter!,"Bitte lasse die Intergalaktische @@ -871,7 +883,7 @@ Federazione Intergalattica dei Cereali!","ぎんがシリアルれんぽう を みすてないでくれ!",은하연합시리얼국을 위해서라도 부디 떠나지 말아 주시길 바랍니다!,Laat de Intergalactische Federatie van Granen niet in de steek!,Ikke forlat Den intergalaktiske kornføderasjonen!,Nie opuszczaj Międzygalaktycznej Federacji Płatków!,"Não abandone a Federação Intergaláctica de Cereais!",,Nu abandona Federația Intergalactică a Cerealelor!,"Не оставляй Межгалактическую Федерацию Хлопьев!","Не напуштај Интергалактичку -федерацију овсених пахуљица!",Galaksilerarası Tahıl Federasyonu'nu terk etmeyin! +федерацију овсених пахуљица!",Överge inte Intergalactic Federation of Cereals!,Galaksilerarası Tahıl Federasyonu'nu terk etmeyin! "The real Chex(R) Warrior wouldn't give up so fast!",QUITMSG29,,,,"Skutečný Chex(R) bojovník by se tak rychle nevzdal!",Den rigtige Chex(R)-kriger ville ikke give op så hurtigt!,"Der echte Chex(R) Krieger @@ -886,1008 +898,970 @@ nie poddałby się tak szybko!","O verdadeiro Guerreiro Chex(R) não desistiria tão rapido!",,"Adevăratul Luptător Chex(R) nu s-ar da bătut atât de ușor!","Настоящий воин Chex(R) не сдастся так быстро!","Прави Чекс ратници не -би одустали тако лако!",Gerçek Chex(R) Savaşçısı bu kadar çabuk pes etmez! -,,Pickups,,,,,,,,,,,,,,,,,,,,,,,, -You got a pickup,TXT_DEFAULTPICKUPMSG,,,,Dostal@[ao_cs] jsi věc,Du har samlet noget op,Du hast etwas aufgesammelt,Πήρες ένα πράγμα.,Vi trovis aĵon,Encuentras un objeto.,Hallaste un objeto,Sait jotakin,Quelque chose récupéré.,Felvettél egy tárgyat.,Hai raccolto qualcosa ,何か拾った,무언가를 집어냈다,Je hebt iets opgepakt...,Du har en henting,Zebrano przedmiot,Você pegou um item,Apanhaste um item,Ai ridicat un obiect.,Что-то получено,Покупили сте нешто,Bir pikabın var -,,Locks,,,,,,,,,,,,,,,,,,,,,,,, -Any key will open this door,PD_ANY,,,,Tyto dveře otevře jakýkoliv klíč,Enhver nøgle kan åbne denne dør,Jeder Schlüssel wird diese Tür öffnen,Οποιδήποτε κλειδί θα ανοίξει τη πόρτα,Iu ajn ŝlosilo povas malfermi ĉi tiun pordon,Cualquier llave puede abrir esta puerta,,Mikä tahansa avain avaa tämän oven,N'importe quelle clé peut ouvrir cette porte.,Bármilyen kulcs kinyitja ezt az ajtót.,Una chiave qualunque aprirà questa porta,いずれかのキーで開けることができる。,어느 열쇠든 이 문을 열 수 있습니다,Elke sleutel zal deze deur openen,Hvilken som helst nøkkel åpner denne døren,Dowolny klucz otworzy te drzwi,Qualquer chave abre esta porta,Qualquer chave pode abrir esta porta,Orice cheie va deschide ușa aceasta.,Для открытия нужен любой ключ,За отварање потребан је било који кључ,Herhangi bir anahtar bu kapıyı açar -Any key will activate this object,PD_ANYOBJ,,,,Tento objekt aktivuje jakýkoliv klíč,Enhver nøgle vil aktivere dette objekt,Jeder Schlüssel wird dieses Objekt aktivieren,Οποιδήποτε κλειδί θα ενεργοποιήσει αυτό το αντικείμενο,Iu ajn ŝlosilo povas aktivigi ĉi tiun objekton,Cualquier llave puede activar este objeto,,Mikä tahansa avain aktivoi tämän kappaleen,N'importe quelle clé peut activer cet objet.,Bármilyen kulcs aktiválja ezt a tárgyat.,Una chiave qualunque attiverà questo oggetto,いずれかのキーで起動させることができる。,어느 열쇠든 이 물체를 작동 시킬 것입니다,Elke sleutel zal dit object activeren,Hvilken som helst nøkkel vil aktivere dette objektet,Dowolny klucz aktywuje ten przedmiot,Qualquer chave ativa este objeto,Qualquer chave pode ativar este objeto,Orice cheie va activa obiectul acesta.,Для включения нужен любой ключ,За активирање потребан је било који кључ,Herhangi bir tuş bu nesneyi etkinleştirir +би одустали тако лако!",Den riktiga Chex(R)-krigaren skulle inte ge upp så snabbt!,Gerçek Chex(R) Savaşçısı bu kadar çabuk pes etmez! +,,Pickups,,,,,,,,,,,,,,,,,,,,,,,,, +You got a pickup,TXT_DEFAULTPICKUPMSG,,,,Dostal@[ao_cs] jsi věc,Du har samlet noget op,Du hast etwas aufgesammelt,Πήρες ένα πράγμα.,Vi trovis aĵon,Encuentras un objeto.,Hallaste un objeto,Sait jotakin,Quelque chose récupéré.,Felvettél egy tárgyat.,Hai raccolto qualcosa ,何か拾った,무언가를 집어냈다,Je hebt iets opgepakt...,Du har en henting,Zebrano przedmiot,Você pegou um item,Apanhaste um item,Ai ridicat un obiect.,Что-то получено,Покупили сте нешто,Du har en pickup,Bir pikabın var +,,Locks,,,,,,,,,,,,,,,,,,,,,,,,, +Any key will open this door,PD_ANY,,,,Tyto dveře otevře jakýkoliv klíč,Enhver nøgle kan åbne denne dør,Jeder Schlüssel wird diese Tür öffnen,Οποιδήποτε κλειδί θα ανοίξει τη πόρτα,Iu ajn ŝlosilo povas malfermi ĉi tiun pordon,Cualquier llave puede abrir esta puerta,,Mikä tahansa avain avaa tämän oven,N'importe quelle clé peut ouvrir cette porte.,Bármilyen kulcs kinyitja ezt az ajtót.,Una chiave qualunque aprirà questa porta,いずれかのキーで開けることができる。,어느 열쇠든 이 문을 열 수 있습니다,Elke sleutel zal deze deur openen,Hvilken som helst nøkkel åpner denne døren,Dowolny klucz otworzy te drzwi,Qualquer chave abre esta porta,Qualquer chave pode abrir esta porta,Orice cheie va deschide ușa aceasta.,Для открытия нужен любой ключ,За отварање потребан је било који кључ,Vilken nyckel som helst kan öppna den här dörren.,Herhangi bir anahtar bu kapıyı açar +Any key will activate this object,PD_ANYOBJ,,,,Tento objekt aktivuje jakýkoliv klíč,Enhver nøgle vil aktivere dette objekt,Jeder Schlüssel wird dieses Objekt aktivieren,Οποιδήποτε κλειδί θα ενεργοποιήσει αυτό το αντικείμενο,Iu ajn ŝlosilo povas aktivigi ĉi tiun objekton,Cualquier llave puede activar este objeto,,Mikä tahansa avain aktivoi tämän kappaleen,N'importe quelle clé peut activer cet objet.,Bármilyen kulcs aktiválja ezt a tárgyat.,Una chiave qualunque attiverà questo oggetto,いずれかのキーで起動させることができる。,어느 열쇠든 이 물체를 작동 시킬 것입니다,Elke sleutel zal dit object activeren,Hvilken som helst nøkkel vil aktivere dette objektet,Dowolny klucz aktywuje ten przedmiot,Qualquer chave ativa este objeto,Qualquer chave pode ativar este objeto,Orice cheie va activa obiectul acesta.,Для включения нужен любой ключ,За активирање потребан је било који кључ,Alla nycklar aktiverar det här objektet,Herhangi bir tuş bu nesneyi etkinleştirir You need all three keys to open this door,PD_ALL3,,,,K otevření těchto dveří jsou potřeba všechny tři klíče,Du skal bruge alle tre nøgler for at åbne denne dør,"Du brauchst alle drei Schlüssel, um diese Tür zu öffnen",Χρειάζεσαι όλα τα τρία κλειδία για να ανοίξεις αυτή τη πόρτα,Vi bezonas ĉiujn tri ŝlosilojn por malfermi ĉi tiun pordon,Necesitas las tres llaves para abrir esta puerta,,Kaikki kolme avainta tarvitaan tämän oven avaamiseksi,Il vous faut une clé de chaque couleur pour ouvrir cette porte.,"Mind a 3 kulcs szükséges, hogy kinyisd ezt az ajtót.",Ti servono tutte e tre le chiavi per aprire questa porta,3つのキー全てが無ければ開かない。,이 문을 열기 위해선 3 종류의 열쇠가 필요합니다,Je hebt alle drie de sleutels nodig om deze deur te openen,Du trenger alle tre nøklene for å åpne denne døren,"Potrzebujesz wszystkich trzech kluczy, aby otworzyć te drzwi",Você precisa de todas as três chaves para abrir esta porta,Precisas de todas as três chaves para abrir esta porta,"Ai nevoie de toate cele trei chei pentru a deschide -ușa aceasta.",Для открытия требуются все три ключа,За отварање потребна су сва три кључа ,Bu kapıyı açmak için üç anahtara da ihtiyacınız var +ușa aceasta.",Для открытия требуются все три ключа,За отварање потребна су сва три кључа ,Du behöver alla tre nycklarna för att öppna den här dörren.,Bu kapıyı açmak için üç anahtara da ihtiyacınız var You need all three keys to activate this object,PD_ALL3O,,,,K aktivaci tohoto objektu jsou potřeba všechny tři klíče,Du skal bruge alle tre nøgler for at aktivere dette objekt,"Du brauchst alle drei Schlüssel, um dieses Objekt zu aktivieren",Χρειάζεσε όλα τα τρία κλειδιά για να ενεργοποιήσεις αυτό το αντικείμενο,Vi bezonas ĉiujn tri ŝlosilojn por aktivigi ĉi tiun objekton,Necesitas las tres llaves para activar este objeto,,Kaikki kolme avainta tarvitaan tämän kappaleen aktivoimiseksi,Il vous faut une clé de chaque couleur pour activer cet objet.,Mind a 3 kulcs kell hogy aktiváld ezt a tárgyat.,Ti servono tutte e tre le chiavi per attivare questo oggetto ,3つのキー全てが必要だ。,이 물체를 작동시키기 위해선 3 종류의 열쇠가 필요합니다,Je hebt alle drie de sleutels nodig om dit object te activeren,Du trenger alle tre nøklene for å aktivere dette objektet,"Potrzebujesz wszystkich trzech kluczy, aby aktywować ten przedmiot",Você precisa de todas as três chaves para ativar este objeto,Precisas de todas as três chaves para ativar este objeto,"Ai nevoie de toate cele trei chei pentru a activa -acest obiect.",Для включения требуются все три ключа,За активирање потребна су сва три кључа,Bu nesneyi etkinleştirmek için üç tuşa da ihtiyacınız var +acest obiect.",Для включения требуются все три ключа,За активирање потребна су сва три кључа,Du behöver alla tre nycklarna för att aktivera det här föremålet.,Bu nesneyi etkinleştirmek için üç tuşa da ihtiyacınız var You need all six keys to open this door,PD_ALL6,,,,K otevření těchto dveří je potřeba všech šest klíčů,Du skal bruge alle seks nøgler for at åbne denne dør,"Du brauchst alle sechs Schlüssel, um diese Tür zu öffnen",Χρειάζεσαι όλα τα έξι κλειδία για να ανοίξεις αυτή τη πόρτα,Vi bezonas ĉiujn ses ŝlosilojn por malfermi ĉi tiun pordon,Necesitas las seis llaves para abrir esta puerta,,Kaikki kuusi avainta tarvitaan tämän oven avaamiseksi,Il vous faut les six clés pour ouvrir cette porte.,Mind a 6 kulcsnak meg kell lennie az ajtó kinyitásához.,Ti servono tutte e sei le chiavi per aprire questa porta,6つ全てのキーが無ければ開かない。,이 문을 열기 위해선 6 종류의 열쇠가 필요합니다,Je hebt alle zes de sleutels nodig om deze deur te openen,Du trenger alle seks nøklene for å åpne denne døren,"Potrzebujesz wszystkich sześciu kluczy, aby otworzyć te drzwi",Você precisa de todas as seis chaves para abrir esta porta,Precisas de todas as seis chaves para abrir esta porta,"Ai nevoie de toate cele sase chei pentru a deschide -aceasta usa.",Для открытия требуются все шесть ключей,За отварање потребна су свих шест кључева,Bu kapıyı açmak için altı anahtara da ihtiyacınız var +aceasta usa.",Для открытия требуются все шесть ключей,За отварање потребна су свих шест кључева,Du behöver alla sex nycklar för att öppna den här dörren.,Bu kapıyı açmak için altı anahtara da ihtiyacınız var You need all six keys to activate this object,PD_ALL6O,,,,K aktivaci tohoto objektu je potřeba všech šest klíčů,Du skal bruge alle seks nøgler for at aktivere dette objekt,"Du brauchst alle sechs Schlüssel, um dieses Objekt zu aktivieren",Χρειάζεσε όλα τα έξι κλειδιά για να ενεργοποιήσεις αυτό το αντικείμενο,Vi bezonas ĉiujn ses ŝlosilojn por aktivigi ĉi tiun objekton,Necesitas las seis llaves para activar este objeto,,Kaikki kuusi avainta tarvitaan tämän kappaleen aktivoimiseksi,Il vous faut les six clés pour activer cet objet.,"Mind a 6 kulcs kell, hogy aktiváld ezt az objektumot.",Ti servono tutte e tre le chiavi per attivare questo oggetto ,6つ全てのキーが必要だ。,이 물체를 작동시키기 위해선 6 종류의 열쇠가 필요합니다,Je hebt alle zes de sleutels nodig om dit object te activeren,Du trenger alle seks nøklene for å aktivere dette objektet,"Potrzebujesz wszystkich sześciu kluczy, aby aktywować ten przedmiot",Você precisa de todas as seis chaves para ativar este objeto,Precisas de todas as seis chaves para ativar este objeto,"Ai nevoie de toate cele șase chei pentru a activa -acest obiect.",Для включения требуются все шесть ключей,За активирање потребна су свих шест кључева,Bu nesneyi etkinleştirmek için altı tuşa da ihtiyacınız var -You need all the keys,PD_ALLKEYS,,,,Potřebuješ všechny klíče,Du skal bruge alle nøglerne,Du brauchst alle Schlüssel,Χρειάζεσαι όλα τα κλειδία,Vi bezonas ĉiujn ŝlosilojn,Necesitas todas las llaves,,Kaikki avaimet tarvitaan,Vous avez besoin de toutes les six clés.,Az összes kulcsra szükséged van.,Ti servono tutte le chiavi,全てのキーが必要だ。,모든 열쇠가 필요합니다,Je hebt alle sleutels nodig,Du trenger alle nøklene,Potrzebujesz wszystkich kluczy,Você precisa de todas as chaves,Precisas de todas as chaves,Ai nevoie de toate cheile.,Требуются все ключи,Потребни су сви кључеви,Tüm anahtarlara ihtiyacın var -,,Chat,,,,,,,,,,,,,,,,,,,,,,,, -[Message unsent],HUSTR_MSGU,,,,[Zpráva neposlána],[Besked ikke sendt],[Nachricht nicht gesendet],[Δέν στάλθηκε],[Mesaĝo ne sendita],[Mensaje sin enviar],,[Viestiä ei lähetetty],[Message Non Envoyé],[Üzenet nincs elküldve],[Messaggio non inviato],[メッセージ未送信],[메시지가 전달되지 않음],[Bericht niet verzonden],[Melding ikke sendt],[Wiadomość niewysłana],[Mensagem não enviada],,[Mesaj netrimis],[Сообщение не отправлено],[Порука непослата],[Mesaj gönderilmemiş] -You mumble to yourself,HUSTR_TALKTOSELF1,,,,Něco si zamumláš pro sebe.,Du mumler for dig selv,Du murmelst zu dir selbst,Μουρμουράς στον εαυτό σου,Vi murmuras al vi mem,Te murmuras a ti mism@[ao_esp],,Mutiset itseksesi,Vous parlez tout seul.,Magadban motyogsz,Pensi fra te e te,ネタにならない呟きだ,자기 혼자서 중얼거렸다,Je mompelt in jezelf,Du mumler for deg selv,Mamroczesz do siebie,Você resmunga para si mesm@[ao_ptb]...,Tu resmungas contigo própri@[ao_ptb]...,Bolborosești în sine,Неразборчивое бормотание,Промумљате себи,Kendi kendine mırıldanıyorsun -Who's there?,HUSTR_TALKTOSELF2,,,,Kdo je tam?,Hvem er der?,Wer ist da?,Πιός είναι εκεί?,Kiu estas tie?,¿Quién está ahí?,,Kuka siellä?,Qui est là?,Ki van ott?,Chi c'è lì?,誰かいるか?,거기 누구 있나?,Wie is daar?,Hvem er der?,Kto tam?,Quem está aí?,,Cine-i acolo?,Кто там?,Ко је то?,Kim var orada? +acest obiect.",Для включения требуются все шесть ключей,За активирање потребна су свих шест кључева,Du behöver alla sex nycklar för att aktivera detta objekt.,Bu nesneyi etkinleştirmek için altı tuşa da ihtiyacınız var +You need all the keys,PD_ALLKEYS,,,,Potřebuješ všechny klíče,Du skal bruge alle nøglerne,Du brauchst alle Schlüssel,Χρειάζεσαι όλα τα κλειδία,Vi bezonas ĉiujn ŝlosilojn,Necesitas todas las llaves,,Kaikki avaimet tarvitaan,Vous avez besoin de toutes les six clés.,Az összes kulcsra szükséged van.,Ti servono tutte le chiavi,全てのキーが必要だ。,모든 열쇠가 필요합니다,Je hebt alle sleutels nodig,Du trenger alle nøklene,Potrzebujesz wszystkich kluczy,Você precisa de todas as chaves,Precisas de todas as chaves,Ai nevoie de toate cheile.,Требуются все ключи,Потребни су сви кључеви,Du behöver alla nycklar,Tüm anahtarlara ihtiyacın var +,,Chat,,,,,,,,,,,,,,,,,,,,,,,,, +[Message unsent],HUSTR_MSGU,,,,[Zpráva neposlána],[Besked ikke sendt],[Nachricht nicht gesendet],[Δέν στάλθηκε],[Mesaĝo ne sendita],[Mensaje sin enviar],,[Viestiä ei lähetetty],[Message Non Envoyé],[Üzenet nincs elküldve],[Messaggio non inviato],[メッセージ未送信],[메시지가 전달되지 않음],[Bericht niet verzonden],[Melding ikke sendt],[Wiadomość niewysłana],[Mensagem não enviada],,[Mesaj netrimis],[Сообщение не отправлено],[Порука непослата],[Meddelande ej skickat],[Mesaj gönderilmemiş] +You mumble to yourself,HUSTR_TALKTOSELF1,,,,Něco si zamumláš pro sebe.,Du mumler for dig selv,Du murmelst zu dir selbst,Μουρμουράς στον εαυτό σου,Vi murmuras al vi mem,Te murmuras a ti mism@[ao_esp],,Mutiset itseksesi,Vous parlez tout seul.,Magadban motyogsz,Pensi fra te e te,ネタにならない呟きだ,자기 혼자서 중얼거렸다,Je mompelt in jezelf,Du mumler for deg selv,Mamroczesz do siebie,Você resmunga para si mesm@[ao_ptb]...,Tu resmungas contigo própri@[ao_ptb]...,Bolborosești în sine,Неразборчивое бормотание,Промумљате себи,Du mumlar för dig själv,Kendi kendine mırıldanıyorsun +Who's there?,HUSTR_TALKTOSELF2,,,,Kdo je tam?,Hvem er der?,Wer ist da?,Πιός είναι εκεί?,Kiu estas tie?,¿Quién está ahí?,,Kuka siellä?,Qui est là?,Ki van ott?,Chi c'è lì?,誰かいるか?,거기 누구 있나?,Wie is daar?,Hvem er der?,Kto tam?,Quem está aí?,,Cine-i acolo?,Кто там?,Ко је то?,Vem är där?,Kim var orada? You scare yourself,HUSTR_TALKTOSELF3,,,,Vystrašíš se.,Du skræmmer dig selv,Du machst dir Angst,Φοβήζεις τον εαυτό σου,Vi timigas vin mem,Te asustas a ti mism@[ao_esp],,Pelotat itseäsi,Vous vous surprenez.,Megijeszted magad,Ti spaventi da solo,"怯えているな -",자기 혼자서 벌벌 떨고 있다,Je wordt bang van jezelf,Du skremmer deg selv,Przestraszyłeś się,Você se assusta,Assustas-te a ti propri@[ao_ptb],Te speri pe tine însuți,Что это было?,Плашите самог себе,Kendini korkutuyorsun. -You start to rave,HUSTR_TALKTOSELF4,,,,Začneš pařit.,Du begynder at rave,Du beginnst zu toben,Αρχίζεις να ουρλίαζεις,Vi komencas frenezi,Empiezas a delirar,,Alat hourailla,Vous commencez à délirer!,Reszketni kezdesz,Inizi a delirare,イカレ始めた,횡설수설하기 시작했다,Je begint te razen,Du begynner å rave,Zaczynasz wariować,Você começa a delirar,Começas a delirar,Începi să aiurezi,Вы бредите.,Брбљате,Çıldırmaya başlıyorsun -You've lost it...,HUSTR_TALKTOSELF5,,,,Kleplo ti...,Du har mistet den...,Du verlierst den Verstand...,Το έχασες,Vi freneziĝis...,Te has vuelto loc@[ao_esp]...,Te volviste loc@[ao_esp]...,Olet seonnut...,Vous avez perdu les pédales...,Eldobod az agyad...,Sei andato...,我を失った...,미치기 시작했다...,Je bent het kwijt,You've lost it...,Oszalałeś...,Você enlouqueceu...,Enlouqueceste,Ai luat-o pe ulei...,Какая досада...,Лудите...,Kaybettin... -[Message Sent],HUSTR_MESSAGESENT,,,,[Zpráva odeslána],[besked sendt],[Nachricht gesendet],[Στάλθηκε],[Mesaĝo sendita],[Mensaje enviado],,[Viesti lähetetty],[Message Envoyé],[Üzenet elküldve],[Messaggio Inviato],[メッセージ送信],[메시지가 전달됨],[Bericht verzonden],[Melding sendt],[Wiadomość wysłana],[Mensagem enviada],,[Mesaj Trimis],[Сообщение отправлено],[Порука послата],[Mesaj Gönderildi] -,,Cheats,,,,,,,,,,,,,,,,,,,,,,,, -Music Change,STSTR_MUS,,,,Změna hudby,Musik Ændring,Musikwechsel,Άλλαξε μουσική,Muzikŝanĝo,Cambio de música,,Musiikin vaihtaminen,Changement de Musique,Zene Váltás,Cambio di musica,music変更,음악 전환,Muziek veranderen,Music Change,Zmieniono muzykę,Trocando música,Mudar a música,Schimbare muzică...,Смена музыки,Промена музике,Müzik Değişimi -Impossible Selection,STSTR_NOMUS,,,,Nemožný výběr,Umuligt valg,Falsche Auswahl,Αδήνατη επιλογή,Malebla Elektaĵo,Selección impossible,,Valinta ei mahdollinen,Séléction Impossible!,Lehetetlen Kiválasztás,Selezione impossibile,その変更は不可能だ,불가능한 선택입니다,Onmogelijke selectie,Umulig valg,Niemożliwy wybór,Seleção impossível,,Selectare Imposibilă,Неверный выбор,НЕМОГУЋИ ИЗБОР,İmkansız Seçim -Degreelessness Mode ON,STSTR_DQDON,,,,Nesmrtelnost ZAP,Gradeløs tilstand TIL,Unverwundbarkeit AN,Θεική λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Nevundebla Reĝimo ŜALTITA,Modo de estado sin grado ACTIVADO,,Kuolemattomuustila PÄÄLLÄ,Invulnérabilité ON ,Sérthetetlenség Mód BE,Modalità Invincibilità ATTIVATA,無敵モード: オン,무미건조한 모드 켬,Gegradeloosheid modus AAN,Gradløshetsmodus PÅ,Niewrażliwość WŁĄCZONA,Modo invencível ATIVADO,,Modul invincibil ACTIVAT,Безграмотность ВКЛЮЧЕНА,Нерањивост УКЉУЧЕНА,Dokunulmazlık Modu AÇIK -Degreelessness Mode OFF,STSTR_DQDOFF,,,,Nesmrtelnost VYP,Gradeløs tilstand FRA,Unverwundbarkeit AUS,Θεική λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Nevundebla Reĝimo MALŜALTITA,Modo de estado sin grado DESACTIVADO,,Kuolemattomuustila POIS PÄÄLTÄ,Invulnérabilité OFF,Sérthetetlenség Mód KI,Modalità Invincibilità DISATTIVATA,無敵モード: オフ,무미건조한 모드 끔,Gegradeloosheid modus UIT,Gradløshetsmodus AV,Niewrażliwość WYŁĄCZONA,Modo invencível DESATIVADO,,Modul Invincibil DEZACTIVAT,Безграмотность ОТКЛЮЧЕНА,Нерањивост ИСКЉУЧЕНА,Dokunulmazlık Modu KAPALI -Ultimate Degreelessness Mode ON,STSTR_DQD2ON,,,,Supernesmrtelnost ZAP,Ultimativ gradløs tilstand TIL,Ultimative Unverwundbarkeit AN,Απόλητη θεική λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Pleja Nevundebla Reĝimo ŜALTITA,Modo de estado sin grado final ACTIVADO,,Varma kuolemattomuustila PÄÄLLÄ,Parfaite Invulnérabilité ON,Tökéletes Sérthetetlenség Mód BE,Modalità Invincibilità Ultima ATTIVATA,究極無敵モード: オン,엄청나게 무미건조한 모드 켬,Uiteindelijke Gegradeloosheid modus AAN,Ultimativ gradløshetsmodus PÅ,Maksymalna niewrażliwość WŁĄCZONA,Modo invencível supremo ATIVADO,,Modul Invincibilitate Supremă ACTIVAT,Полная безграмотность ВКЛЮЧЕНА,Ултимативна нерањивост УКЉУЧЕНА,Nihai Dokunulmazlık Modu AÇIK -Ultimate Degreelessness Mode OFF,STSTR_DQD2OFF,,,,Supernesmrtelnost VYP,Ultimativ gradløs tilstand FRA,Ultimative Unverwundbarkeit AUS,Απόλητη θεική λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Pleja Nevundebla Reĝimo MALŜALTITA,Modo de estado sin grado final DESACTIVADO,,Varma kuolemattomuustila POIS PÄÄLTÄ,Parfaite Invulnérabilité OFF,Tökéletes Sérthetetlenség Mód KI,Modalità Invincibilità Ultima DISATTIVATA,究極無敵モード: オフ,엄청나게 무미건조한 모드 끔,Uiteindelijke Gegradeloosheid modus UIT,Ultimativ gradløshetsmodus AV,Maksymalna niewrażliwość WYŁĄCZONA,Modo invencível supremo DESATIVADO,,Modul Invincibilitate Supremă DEZACTIVAT,Полная безграмотность ОТКЛЮЧЕНА,Ултимативна нерањивост ИСКЉУЧЕНА,Nihai Dokunulmazlık Modu KAPALI -Very Happy Ammo Added,STSTR_KFAADDED,,,,Velmi veselá munice přidána,Meget lykkelig Ammo tilføjet,Munition hinzugefügt,Πάρα Πολύ Χαρούμενα Πυρομαχηκά Προστέθηκαν,Tre Feliĉa Municio Aldonita,Munición añadida hasta el tope,,Täysaseistus,Armement Maximum!,Összes Lőszer Megadva,Equipaggiamento Completato,とても満足する武器弾薬を受け取った,아주 행복한 탄약 추가됨,Zeer gelukkige munitie toegevoegd,Veldig glad ammunisjon lagt til,Bardzo szczęśliwa amunicja dodana,Equipamento completo,,Echipament complet,Боезапас на счастье пополнен,Веома Срећна Муниција Додана,Çok Mutlu Cephane Eklendi -Ammo (no keys) Added,STSTR_FAADDED,,,,Munice (bez klíčú) přidána,Ammo (ingen nøgler) Tilføjet,Munition (keine Schlüssel) hinzugefügt,Πυρομαχικά (Όχι κλειδία) προστέθηκαν,Municio (neniuj ŝlosiloj) Aldonita,Munición añadida (sin llaves),,Täysaseistus (ilman avaimia),Arsenal ajouté. (Pas de clés!),Lőszer (nincsenek kulcsok) Megadva,Equipaggiamento Completato (senza chiavi),武器弾薬(鍵なし)を受け取った,탄약(열쇠 없이) 추가됨,Munitie (geen sleutels) toegevoegd,Ammo (ingen nøkler) Lagt til,Amunicja (bez kluczy) dodana,Equipamento completo (sem chaves),,Echipament complet (fără muniție),Боезапас пополнен (без ключей),Муниција (без кључева) Додана,Cephane (anahtar yok) Eklendi -No Clipping Mode ON,STSTR_NCON,,,,Bezkolizní režim ZAP,Ikke-kollisionstilstand TIL,Nicht-Kollisionsmodus AN,Noclip λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Reĝimo de Neniu Tondado ŜALTITA,Modo de traspaso ACTIVADO,,Seinänläpikulkutila PÄÄLLÄ,Collisions OFF,Falonátmenés Mód BE,No Clipping ATTIVATO,壁抜けモード: オン,노 클립 모드 켬,Geen Clipping Modus AAN,Ingen klipping-modus PÅ,Tryb no-clip WŁĄCZONY,Modo sem colisão ATIVADO,,Modul fără coliziune ACTIVAT,Режим без столкновений ВКЛЮЧЕН,Пролажење кроз зидове УКЉУЧЕНО,Klipsleme Yok Modu AÇIK -No Clipping Mode OFF,STSTR_NCOFF,,,,Bezkolizní režim VYP,Ikke-kollisionstilstand FRA,Nicht-Kollisionsmodus AUS,Noclip λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Reĝimo de Neniu Tondado MALŜALTITA,Modo de traspaso DESACTIVADO,,Seinänläpikulkutila POIS PÄÄLTÄ,Collisions ON,Falonátmenés Mód KI,No Clipping DISATTIVATO,壁抜けモード: オフ,노 클립 모드 끔,Geen Clipping Modus OFF,Ingen klippemodus AV,Tryb no-clip WYŁĄCZONY,Modo sem colisão DESATIVADO,,Modul fără coliziune DEZACTIVAT,Режим без столкновений ОТКЛЮЧЕН,Пролажење кроз зидове ИСКЉУЧЕНО,Klipsleme Yok Modu KAPALI -No Clipping Mode 2 ON,STSTR_NC2ON,,,,Bezkolizní režim 2 ZAP,Ikke-kollisionstilstand 2 TIL,Nicht-Kollisionsmodus 2 AN,Δέυτερη noclip λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Reĝimo de Neniu Tondado 2 ŜALTITA,Modo de traspaso 2 ACTIVADO,,Seinänläpikulkutila 2 PÄÄLLÄ,Collisions 3D OFF,Falonátmenés 2. Mód BE,No Clipping 2 ATTIVATO,壁抜けモード2: オン,노 클립 모드 2 켬,Geen Clipping Modus 2 AAN,No Clipping Mode 2 PÅ,Drugi tryb no-clip WŁĄCZONY,Modo sem colisão 2 ATIVADO,,Modul fără coliziune 2 ACTIVAT,Режим без столкновений 2 ВКЛЮЧЁН,Секундарни режим пролажења кроз зидове УКЉУЧЕНО,Klipsleme Yok Modu 2 AÇIK -No Clipping Mode 2 OFF,STSTR_NC2OFF,,,,Bezkolizní režim 2 VYP,Ikke-kollisionstilstand 2 FRA,Nicht-Kollisionsmodus 2 AUS,Noclip λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Reĝimo de Neniu Tondado 2 MALŜALTITA,Modo de traspaso 2 DESACTIVADO,,Seinänläpikulkutila 2 POIS PÄÄLTÄ,Collisions 3D ON,Falonátmenés 2 Mód KI,No Clipping 2 DISATTIVATO,壁抜けモード2: オフ,노 클립 모드 2 끔,Geen Clipping Modus 2 OFF,Ingen klippemodus 2 AV,Drugy tryb no-clip WYŁĄCZONY,Modo sem colisão 2 DESATIVADO,,Modul fără coliziune 2 DEZACTIVAT,Режим без столкновений 2 ОТКЛЮЧЁН,Секундарни режим пролажења кроз зидове ИСКЉУЧЕНО,Klipsleme Yok Modu 2 KAPALI +",자기 혼자서 벌벌 떨고 있다,Je wordt bang van jezelf,Du skremmer deg selv,Przestraszyłeś się,Você se assusta,Assustas-te a ti propri@[ao_ptb],Te speri pe tine însuți,Что это было?,Плашите самог себе,Du skrämmer dig själv.,Kendini korkutuyorsun. +You start to rave,HUSTR_TALKTOSELF4,,,,Začneš pařit.,Du begynder at rave,Du beginnst zu toben,Αρχίζεις να ουρλίαζεις,Vi komencas frenezi,Empiezas a delirar,,Alat hourailla,Vous commencez à délirer!,Reszketni kezdesz,Inizi a delirare,イカレ始めた,횡설수설하기 시작했다,Je begint te razen,Du begynner å rave,Zaczynasz wariować,Você começa a delirar,Começas a delirar,Începi să aiurezi,Вы бредите.,Брбљате,Du börjar rasa.,Çıldırmaya başlıyorsun +You've lost it...,HUSTR_TALKTOSELF5,,,,Kleplo ti...,Du har mistet den...,Du verlierst den Verstand...,Το έχασες,Vi freneziĝis...,Te has vuelto loc@[ao_esp]...,Te volviste loc@[ao_esp]...,Olet seonnut...,Vous avez perdu les pédales...,Eldobod az agyad...,Sei andato...,我を失った...,미치기 시작했다...,Je bent het kwijt,You've lost it...,Oszalałeś...,Você enlouqueceu...,Enlouqueceste,Ai luat-o pe ulei...,Какая досада...,Лудите...,Du har förlorat det...,Kaybettin... +[Message Sent],HUSTR_MESSAGESENT,,,,[Zpráva odeslána],[besked sendt],[Nachricht gesendet],[Στάλθηκε],[Mesaĝo sendita],[Mensaje enviado],,[Viesti lähetetty],[Message Envoyé],[Üzenet elküldve],[Messaggio Inviato],[メッセージ送信],[메시지가 전달됨],[Bericht verzonden],[Melding sendt],[Wiadomość wysłana],[Mensagem enviada],,[Mesaj Trimis],[Сообщение отправлено],[Порука послата],[Meddelande skickat],[Mesaj Gönderildi] +,,Cheats,,,,,,,,,,,,,,,,,,,,,,,,, +Music Change,STSTR_MUS,,,,Změna hudby,Musik Ændring,Musikwechsel,Άλλαξε μουσική,Muzikŝanĝo,Cambio de música,,Musiikin vaihtaminen,Changement de Musique,Zene Váltás,Cambio di musica,music変更,음악 전환,Muziek veranderen,Music Change,Zmieniono muzykę,Trocando música,Mudar a música,Schimbare muzică...,Смена музыки,Промена музике,Musikbyte,Müzik Değişimi +Impossible Selection,STSTR_NOMUS,,,,Nemožný výběr,Umuligt valg,Falsche Auswahl,Αδήνατη επιλογή,Malebla Elektaĵo,Selección impossible,,Valinta ei mahdollinen,Séléction Impossible!,Lehetetlen Kiválasztás,Selezione impossibile,その変更は不可能だ,불가능한 선택입니다,Onmogelijke selectie,Umulig valg,Niemożliwy wybór,Seleção impossível,,Selectare Imposibilă,Неверный выбор,НЕМОГУЋИ ИЗБОР,Omöjligt val,İmkansız Seçim +Degreelessness Mode ON,STSTR_DQDON,,,,Nesmrtelnost ZAP,Gradeløs tilstand TIL,Unverwundbarkeit AN,Θεική λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Nevundebla Reĝimo ŜALTITA,Modo de estado sin grado ACTIVADO,,Kuolemattomuustila PÄÄLLÄ,Invulnérabilité ON ,Sérthetetlenség Mód BE,Modalità Invincibilità ATTIVATA,無敵モード: オン,무미건조한 모드 켬,Gegradeloosheid modus AAN,Gradløshetsmodus PÅ,Niewrażliwość WŁĄCZONA,Modo invencível ATIVADO,,Modul invincibil ACTIVAT,Безграмотность ВКЛЮЧЕНА,Нерањивост УКЉУЧЕНА,Gradlöshetsläge på,Dokunulmazlık Modu AÇIK +Degreelessness Mode OFF,STSTR_DQDOFF,,,,Nesmrtelnost VYP,Gradeløs tilstand FRA,Unverwundbarkeit AUS,Θεική λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Nevundebla Reĝimo MALŜALTITA,Modo de estado sin grado DESACTIVADO,,Kuolemattomuustila POIS PÄÄLTÄ,Invulnérabilité OFF,Sérthetetlenség Mód KI,Modalità Invincibilità DISATTIVATA,無敵モード: オフ,무미건조한 모드 끔,Gegradeloosheid modus UIT,Gradløshetsmodus AV,Niewrażliwość WYŁĄCZONA,Modo invencível DESATIVADO,,Modul Invincibil DEZACTIVAT,Безграмотность ОТКЛЮЧЕНА,Нерањивост ИСКЉУЧЕНА,Gradlöshetsläge av,Dokunulmazlık Modu KAPALI +Ultimate Degreelessness Mode ON,STSTR_DQD2ON,,,,Supernesmrtelnost ZAP,Ultimativ gradløs tilstand TIL,Ultimative Unverwundbarkeit AN,Απόλητη θεική λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Pleja Nevundebla Reĝimo ŜALTITA,Modo de estado sin grado final ACTIVADO,,Varma kuolemattomuustila PÄÄLLÄ,Parfaite Invulnérabilité ON,Tökéletes Sérthetetlenség Mód BE,Modalità Invincibilità Ultima ATTIVATA,究極無敵モード: オン,엄청나게 무미건조한 모드 켬,Uiteindelijke Gegradeloosheid modus AAN,Ultimativ gradløshetsmodus PÅ,Maksymalna niewrażliwość WŁĄCZONA,Modo invencível supremo ATIVADO,,Modul Invincibilitate Supremă ACTIVAT,Полная безграмотность ВКЛЮЧЕНА,Ултимативна нерањивост УКЉУЧЕНА,Ultimat gradlöshetsläge på,Nihai Dokunulmazlık Modu AÇIK +Ultimate Degreelessness Mode OFF,STSTR_DQD2OFF,,,,Supernesmrtelnost VYP,Ultimativ gradløs tilstand FRA,Ultimative Unverwundbarkeit AUS,Απόλητη θεική λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Pleja Nevundebla Reĝimo MALŜALTITA,Modo de estado sin grado final DESACTIVADO,,Varma kuolemattomuustila POIS PÄÄLTÄ,Parfaite Invulnérabilité OFF,Tökéletes Sérthetetlenség Mód KI,Modalità Invincibilità Ultima DISATTIVATA,究極無敵モード: オフ,엄청나게 무미건조한 모드 끔,Uiteindelijke Gegradeloosheid modus UIT,Ultimativ gradløshetsmodus AV,Maksymalna niewrażliwość WYŁĄCZONA,Modo invencível supremo DESATIVADO,,Modul Invincibilitate Supremă DEZACTIVAT,Полная безграмотность ОТКЛЮЧЕНА,Ултимативна нерањивост ИСКЉУЧЕНА,Ultimat gradlöshetsläge av,Nihai Dokunulmazlık Modu KAPALI +Very Happy Ammo Added,STSTR_KFAADDED,,,,Velmi veselá munice přidána,Meget lykkelig Ammo tilføjet,Munition hinzugefügt,Πάρα Πολύ Χαρούμενα Πυρομαχηκά Προστέθηκαν,Tre Feliĉa Municio Aldonita,Munición añadida hasta el tope,,Täysaseistus,Armement Maximum!,Összes Lőszer Megadva,Equipaggiamento Completato,とても満足する武器弾薬を受け取った,아주 행복한 탄약 추가됨,Zeer gelukkige munitie toegevoegd,Veldig glad ammunisjon lagt til,Bardzo szczęśliwa amunicja dodana,Equipamento completo,,Echipament complet,Боезапас на счастье пополнен,Веома Срећна Муниција Додана,Mycket lycklig ammunition har lagts till,Çok Mutlu Cephane Eklendi +Ammo (no keys) Added,STSTR_FAADDED,,,,Munice (bez klíčú) přidána,Ammo (ingen nøgler) Tilføjet,Munition (keine Schlüssel) hinzugefügt,Πυρομαχικά (Όχι κλειδία) προστέθηκαν,Municio (neniuj ŝlosiloj) Aldonita,Munición añadida (sin llaves),,Täysaseistus (ilman avaimia),Arsenal ajouté. (Pas de clés!),Lőszer (nincsenek kulcsok) Megadva,Equipaggiamento Completato (senza chiavi),武器弾薬(鍵なし)を受け取った,탄약(열쇠 없이) 추가됨,Munitie (geen sleutels) toegevoegd,Ammo (ingen nøkler) Lagt til,Amunicja (bez kluczy) dodana,Equipamento completo (sem chaves),,Echipament complet (fără muniție),Боезапас пополнен (без ключей),Муниција (без кључева) Додана,Ammo (inga nycklar) Tillagd,Cephane (anahtar yok) Eklendi +No Clipping Mode ON,STSTR_NCON,,,,Bezkolizní režim ZAP,Ikke-kollisionstilstand TIL,Nicht-Kollisionsmodus AN,Noclip λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Reĝimo de Neniu Tondado ŜALTITA,Modo de traspaso ACTIVADO,,Seinänläpikulkutila PÄÄLLÄ,Collisions OFF,Falonátmenés Mód BE,No Clipping ATTIVATO,壁抜けモード: オン,노 클립 모드 켬,Geen Clipping Modus AAN,Ingen klipping-modus PÅ,Tryb no-clip WŁĄCZONY,Modo sem colisão ATIVADO,,Modul fără coliziune ACTIVAT,Режим без столкновений ВКЛЮЧЕН,Пролажење кроз зидове УКЉУЧЕНО,Inget klippningsläge på,Klipsleme Yok Modu AÇIK +No Clipping Mode OFF,STSTR_NCOFF,,,,Bezkolizní režim VYP,Ikke-kollisionstilstand FRA,Nicht-Kollisionsmodus AUS,Noclip λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Reĝimo de Neniu Tondado MALŜALTITA,Modo de traspaso DESACTIVADO,,Seinänläpikulkutila POIS PÄÄLTÄ,Collisions ON,Falonátmenés Mód KI,No Clipping DISATTIVATO,壁抜けモード: オフ,노 클립 모드 끔,Geen Clipping Modus OFF,Ingen klippemodus AV,Tryb no-clip WYŁĄCZONY,Modo sem colisão DESATIVADO,,Modul fără coliziune DEZACTIVAT,Режим без столкновений ОТКЛЮЧЕН,Пролажење кроз зидове ИСКЉУЧЕНО,Inget klippningsläge av,Klipsleme Yok Modu KAPALI +No Clipping Mode 2 ON,STSTR_NC2ON,,,,Bezkolizní režim 2 ZAP,Ikke-kollisionstilstand 2 TIL,Nicht-Kollisionsmodus 2 AN,Δέυτερη noclip λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Reĝimo de Neniu Tondado 2 ŜALTITA,Modo de traspaso 2 ACTIVADO,,Seinänläpikulkutila 2 PÄÄLLÄ,Collisions 3D OFF,Falonátmenés 2. Mód BE,No Clipping 2 ATTIVATO,壁抜けモード2: オン,노 클립 모드 2 켬,Geen Clipping Modus 2 AAN,No Clipping Mode 2 PÅ,Drugi tryb no-clip WŁĄCZONY,Modo sem colisão 2 ATIVADO,,Modul fără coliziune 2 ACTIVAT,Режим без столкновений 2 ВКЛЮЧЁН,Секундарни режим пролажења кроз зидове УКЉУЧЕНО,Inget klippningsläge 2 på,Klipsleme Yok Modu 2 AÇIK +No Clipping Mode 2 OFF,STSTR_NC2OFF,,,,Bezkolizní režim 2 VYP,Ikke-kollisionstilstand 2 FRA,Nicht-Kollisionsmodus 2 AUS,Noclip λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Reĝimo de Neniu Tondado 2 MALŜALTITA,Modo de traspaso 2 DESACTIVADO,,Seinänläpikulkutila 2 POIS PÄÄLTÄ,Collisions 3D ON,Falonátmenés 2 Mód KI,No Clipping 2 DISATTIVATO,壁抜けモード2: オフ,노 클립 모드 2 끔,Geen Clipping Modus 2 OFF,Ingen klippemodus 2 AV,Drugy tryb no-clip WYŁĄCZONY,Modo sem colisão 2 DESATIVADO,,Modul fără coliziune 2 DEZACTIVAT,Режим без столкновений 2 ОТКЛЮЧЁН,Секундарни режим пролажења кроз зидове ИСКЉУЧЕНО,Inget klippningsläge 2 av,Klipsleme Yok Modu 2 KAPALI "inVuln, Str, Inviso, Rad, Allmap, or Lite-amp",STSTR_BEHOLD,"“inVuln”: Invulnerability sphere “Str”: Berserk “Inviso”: Blur sphere “Rad”: Radiation-shielding suit “Allmap”: Computer area map “Lite-amp”: Light-amplification visor",,,"nesmrt(V), (S)íla, nev(I)d, (R)ad, m(A)pa nebo svět(L)o","inVuln, Str, Inviso, Rad, Allmap, eller Lite-amp","inVuln, Str, Inviso, Rad, Allmap, oder Lite-amp",,"inVuln, Str, Inviso, Rad, Allmap, aŭ Lite-amp","inVuln, Str, Inviso, Rad, Allmap, o Lite-amp.",,"haavoittumattomuus (V), voima (S), näkymättömyys (I), koko kartta (A) tai valonvahvistus (L)","in V ulnérable, S urpuissance, I nvisible, p R otection, c A rte, où L umière?","Sérthetetlenség (V), berzerker mód (S), láthatatlanság (i), védőRuha, térkép (A), vagy éjjelLátó sisak","inVuln, berSerk, Invisib, tuta anti-Rad, mAppa tutta, o amplif-Luce","v,i,s,a,r,l の何れかを選べ","무적, 광전사, 투명, 보호복, 지도, 아니면 바이저","onSterv, Bzk, Inviso, Rad, Allmap, of Lvizier","inVuln, Str, Inviso, Rad, Allmap eller Lite-forsterker","niezniszczalność (V), siła (S), niewidzialność (I), kombinezon (R), mapa (A) lub gogle noktowizyjne (L)","Invulnerabilidade (V), Frenesi (S), Invisibilidade (I), Antirradiação (R), Mapa Completo (A) ou Amplificação de Luz (L)",,"InVinc, Forță amplificată, Invizib, Hartă completă, sau -Vedere amplificată","Бессм. (V), сила (S), невид. (I), кост. (R), п. карта (A), ус. света (L).","нерањ., снага, невидљ., радиј., мапа или ноћ. визор", -Power-up Toggled,STSTR_BEHOLDX,,,,Power-up vybrán,Strømoptagelse Skiftet,Verbesserung umgeschaltet!,,Plifortigaĵo Baskuligita,Poder alternado,,Tehostin kytketty,Amélioration Activée!,Képesség hozzáadva,Power-up concesso/tolto,パワーアップ 適用,파워-업 전환됨,Versterking ingeschakeld,Oppstart aktivert,Wzmocnienie aktywowane,Potencializador ativado,,Putere Activată,Усиление включено,Супер моћи заглављене,Güç Açma Değiştirildi -... doesn't suck - GM,STSTR_CHOPPERS,"Printed when entering the idchoppers cheat, which gives the player a chainsaw",,,... není cucák - GM,... er ikke dårlig - GM,... gar nicht übel - GM,... δέν είναι χάλια - GW,... ne aĉas - GM,... no apesta - GM,,... ei ole syvältä - GM,... C'est pas de la merde. - GM,... nem annyira gáz - GM,... non fa schifo - GM,...わるかぁねえぞ --gm,... 후진 건 아니지만 - GM,.... is niet slecht - GM,... suger ikke - GM,... nie ssie - GM,... não tá ruim — GM,,... nu e jalnic - GM,...не отстой — GM,... није лоша - GM,... berbat değil - GM +Vedere amplificată","Бессм. (V), сила (S), невид. (I), кост. (R), п. карта (A), ус. света (L).","нерањ., снага, невидљ., радиј., мапа или ноћ. визор","inVuln, Str, Inviso, Rad, Allmap eller Lite-amp", +Power-up Toggled,STSTR_BEHOLDX,,,,Power-up vybrán,Strømoptagelse Skiftet,Verbesserung umgeschaltet!,,Plifortigaĵo Baskuligita,Poder alternado,,Tehostin kytketty,Amélioration Activée!,Képesség hozzáadva,Power-up concesso/tolto,パワーアップ 適用,파워-업 전환됨,Versterking ingeschakeld,Oppstart aktivert,Wzmocnienie aktywowane,Potencializador ativado,,Putere Activată,Усиление включено,Супер моћи заглављене,Start av strömmen växlade,Güç Açma Değiştirildi +... doesn't suck - GM,STSTR_CHOPPERS,"Printed when entering the idchoppers cheat, which gives the player a chainsaw",,,... není cucák - GM,... er ikke dårlig - GM,... gar nicht übel - GM,... δέν είναι χάλια - GW,... ne aĉas - GM,... no apesta - GM,,... ei ole syvältä - GM,... C'est pas de la merde. - GM,... nem annyira gáz - GM,... non fa schifo - GM,...わるかぁねえぞ --gm,... 후진 건 아니지만 - GM,.... is niet slecht - GM,... suger ikke - GM,... nie ssie - GM,... não tá ruim — GM,,... nu e jalnic - GM,...не отстой — GM,... није лоша - GM,... suger inte - GM,... berbat değil - GM Changing Level...,STSTR_CLEV,,,,Měním level...,Ændring af niveau ...,Wechsle Level...,Αλλαγή πίστας...,Ŝanĝante Nivelon...,"Cambiando de nivel... ",,Vaihdetaan tasoa...,Changement de niveau...,Pályaváltás...,"Cambio di livello... ",場所を変更...,레벨 변경 중...,Level veranderen...,Endre nivå ...,Zmienianie poziomu...,Trocando de fase...,"A mudar de nível... ",Schimbare hartă...,"Смена уровня... -",Мењам ниво...,Seviye Değiştirme... -Buddha mode ON,TXT_BUDDHAON,,,,Buddha mód ZAP,Buddha-tilstand TIL,Buddhamodus AN,Λειτουργία Βουδα ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Budha reĝimo ŜALTITA,Modo Buda ACTIVADO,,Buddhatila PÄÄLLÄ,Mode Bouddha ON,Buddha Mód BE,Modalità Buddha ATTIVATA,ブッダモード: オン,부처 모드 켬,Boeddha-modus AAN,Buddha-modus PÅ,Tryb Buddy WŁĄCZONY,Modo Buda ATIVADO,,Modul Buddha ACTIVAT,Режим Будды ВКЛЮЧЁН,Буда Мод УКЉУЧЕН,Buda modu AÇIK -Buddha mode OFF,TXT_BUDDHAOFF,,,,Buddha mód VYP,Buddha-tilstand FRA,Buddhamodus AUS,Λειτουργία Βουδα ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Budha reĝimo MALŜALTITA,Modo Buda DESACTIVADO,,Buddhatila POIS PÄÄLTÄ,Mode Bouddha OFF,Buddha Mód KI,Modalità Buddha DISATTIVATA,ブッダモード: オフ,부처 모드 끔,Boeddha-modus UIT,Buddha-modus AV,Tryb Buddy WYŁĄCZONY,Modo Buda DESATIVADO,,Modul Buddha DEZACTIVAT,Режим Будды ОТКЛЮЧЁН,Буда Мод ИСКЉУЧЕН,Buda modu KAPALI -Ultimate Buddha Mode ON,TXT_BUDDHA2ON,,,,Super Buddha mód ZAP,Ultimate Buddha-tilstand TIL,Ultimativer Buddhamodus AN,Λειτουργία Απόλητου Βουδα ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Pleja Budha Reĝimo ŜALTITA,Modo Buda Supremo ACTIVADO,,Korkein buddhatila PÄÄLLÄ,Mode Bouddha Ultime ON,Tökéletes Buddha Mód BE,Modalità Ultimo Buddha ATTIVATA,究極ブッダモード: オン,나무 아미타불 모드 켬,Ultieme Boeddha-modus AAN,Ultimativ Buddha-modus PÅ,Maksymalny Tryb Buddy WŁĄCZONY,Modo Buda supremo ATIVADO,,Modul Buddha Suprem ACTIVAT,Окончательный режим Будды ВКЛЮЧЁН,Ултимативни Буда Мод УКЉУЧЕН,Nihai Buda Modu AÇIK -Ultimate Buddha Mode OFF,TXT_BUDDHA2OFF,,,,Super Buddha mód VYP,Ultimate Buddha-tilstand FRA,Ultimativer Buddhamodus AUS,Λειτουργία Απόλητου Βουδα ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Pleja Budha Reĝimo MALŜALTITA,Modo Buda Supremo DESACTIVADO,,Korkein buddhatila POIS PÄÄLTÄ,Mode Bouddha Ultime OFF,Tökéletes Buddha Mód KI,Modalità Ultimo Buddha DISATTIVATA,究極ブッダモード: オフ,나무 아미타불 모드 끔,Ultieme Boeddha-modus UIT,Ultimativ Buddha-modus AV,Maksymalny Tryb Buddy WYŁĄCZONY,Modo Buda supremo DESATIVADO,,Modul Buddha Suprem DEZACTIVAT,Окончательный режим Будды ОТКЛЮЧЁН,Ултимативни Буда Мод ИСКЉУЧЕН,Nihai Buda Modu KAPALI -Power on,TXT_CHEATPOWERON,,,,Energie ZAP,Evne TIL,Fähigkeit AN,Δύναμη ενεργοποιημένη,Povo ŝaltita,Poder activado,,Voima päällä,Pouvoir Activée,Energia BE,Potere ATTIVATO,パワー オン,파워 켬,Vermogen aan,Strøm PÅ,Zasilanie włączone,Poder ativado,,Putere activată,Сила активирована,Моћ УКЉУЧЕНА,Güç açık -Power off,TXT_CHEATPOWEROFF,,,,Energie VYP,Evne FRA,Fähigkeit AUS,Δύναμη άπενεργοποιημένη,Povo malŝaltita,Poder desactivado,,Voima pois päältä,Pouvoir Désactivée,Energia KI,Potere DISATTIVATO,パワー オフ,파워 끔,Vermogen uit,Slå AV,Zasilanie wyłączone,Poder desativado,,Putere dezactivată,Сила деактивирована,Моћ ИСКЉУЧЕНА,Güç kapalı -Full health,TXT_CHEATHEALTH,,,,Plné zdraví,Fuldt helbred,Volle Lebensenergie,Ολόκληρη υγεία,Plena sano,Salud al máximo,,Täysi terveys,Pleine Santé,Teljes életerő,Piena salute,ヘルス全回復,체력 완전 회복,Volledige gezondheid,Full helse,Pełne zdrowie,Saúde completa,Vida totalmente cheia,Sănătate completă,Полное здоровье,Здравље напуњено,Tam sağlık -All keys,TXT_CHEATKEYS,,,,Všechny klíče,Alle taster,Alle Schlüssel,Όλα τα κλειδία,Ĉiuj ŝlosiloj,Todas las llaves,,Kaikki avaimet,Toutes les Clés,Összes kulcs,Tutte le chiavi,キー全部,모든 열쇠,Alle sleutels,Alle taster,Wszystkie klucze,Todas as chaves,,Toate cheile,Все ключи,Сви кључеви,Tüm anahtarlar -Sound debug on,TXT_CHEATSOUNDON,,,,Debug zvuku ZAP,Sound debug TIL,Sound Debug AN,Debug ήχου ενεργοποιημένη,Sono-sencimiga reĝimo ŝaltita,Depuración de sonido activada,,Äänen vianmääritystila päällä,Débogage du son activé.,Hang debug BE,Debug del suono attivato,サウンドデバッグ オン,효과음 디버그 켬,Geluid debug aan,Lyd feilsøking PÅ,Debugowanie dźwięku włączone,Depuração de som ativada,,Debug sunet activat,Отладка звука включена,Дебаговање звука УКЉУЧЕНО,Ses hata ayıklama açık -Sound debug off,TXT_CHEATSOUNDOFF,,,,Debug zvuku VYP,Sound debug FRA,Sound Debug AUS,Debug ήχου άπενεργοποιημένη,Sono-sencimiga reĝimo malŝaltita,Depuración de sonido desactivada,,Äänen vianmääritystila pois päältä,Débogage du son désactivé.,Hang debug KI,Debug del suono disattivato,サウンドデバッグ オフ,효과음 디버그 끔,Geluid debug uit,Lyd feilsøking AV,Debugowanie dźwięku wyłączone,Depuração de som desativada,,Debug sunet dezactivat,Отладка звука отключена,Дебаговање звука ИСКЉУЧЕНО,Ses hata ayıklama kapalı -"Trying to cheat, eh? Now you die!",TXT_CHEATIDDQD,,,,"Pokoušíš se cheatovat, co? Teď zemřeš!","Prøver du at snyde, hva'? Nu dør du!","Versuchst zu betrügen, was? Nun stirbst du!","Προσπαθείς να εξαπατήσεις, ε? Τώρα πεθένεις!","Provas trompi, ĉu vi? Nun vi mortas! ","¿Tratando de hacer trampas, eh? ¡Muere!",,"Yrität huijata, vai? Nyt kuolet!","Tu essaie de tricher, hein? Maintenant tu meurs!","Csalni akarsz, mi? Most meghalsz!","Cerchi di barare, eh? Allora muori!",その名を唱えたな? 褒美に死をやろう!,치트 쓸려고? 그럼 죽어야지!,"Je wou valsspelen, hè? Nu ga je dood!",Prøver du å jukse? Nå dør du!,"Próbujesz oszukiwać, co? Teraz giń!","Tentando trapacear, né? Morra!","A fazer batota, é? Morre!","Încerci să trișezi, ei? Acum mori!","Жульничаешь, э? Так умри!","Покушаваш да вараш, ех? Сада умиреш!","Hile yapmaya çalışıyorsun, ha? Şimdi öleceksin!" -Cheater - you don't deserve weapons,TXT_CHEATIDKFA,,,,Podvodníku - nezasloužíš si zbraně,Snyder - du fortjener ikke våben,Betrüger - du verdienst keine Waffen,Απατεόνα δέν σου αξήζουν όπλα,Trompanto - vi ne meritas armilojn,Trampos@[ao_esp] - No mereces tener armas,,Huijari - et ansaitse aseita,Tricheur- Tu ne mérite pas d'armes!,Csaló - nem érdemelsz fegyvert!,Imbroglione - non meriti armi,不届き者め、貴様が偉業を成すはずがない,사기꾼놈! 너는 무기를 가질 자격이 없어!,Valsspeler - je verdient geen wapens.,Juksemaker - du fortjener ikke våpen,Oszust - nie zasługujesz na bronie,Trapaceiros não merecem armas,Batoteir@[ao_ptb] - Não mereces armamento,Trișor - Nu meriți arme,Жулик — ты не заслуживаешь оружия,Варалице - ти не заслужујеш оружје,"Hileci, silahları hak etmiyorsun." -Ticker on,TXT_CHEATTICKERON,,,,Počítadlo ZAP,Ticker TIL,Zähler AN,Χρονόμετρο ενεργοποιημένο,Nombrilo ŝaltita,Contador activado,,Laskuri päällä,Compteur allumé,Számláló BE,Ticker attivato,ティッカー オン,프레임 속도 표시 켬,Ticker aan,Ticker PÅ,Wskaźnik włączony,Contador ativado,,Ticăitoare activată,Счётчик включён,Бројач укључен,Ticker açık -Ticker off,TXT_CHEATTICKEROFF,,,,Počítadlo VYP,Ticker FRA,Zähler AUS,Χρονόμετρο άπενεργοποιημένο,Nombrilo malŝaltita,Contador desactivado,,Laskuri pois päältä,Compteur éteint,Számláló KI,Ticker disattivato,ティッカー オフ,프레임 속도 표시 끔,Ticker uit,Ticker AV,Wskaźnik wyłączony,Contador desativado,,Ticăitoare dezactivată,Счётчик отключён,Бројач искључен,Ticker kapalı -You got it,TXT_CHEATARTIFACTS3,,,,Máš to mít,Du fik det,Du hast es,Το πήρες,Vi akiris ĝin,Lo tienes,,Saamasi pitää,C'est à vous!,Megkaptad,Concesso,それを渡そう。,얻었다,Je hebt het,Du har det,Udało ci się,Concedido,,Ai ce-ți trebuie,Вы получили это,Уреду,Tamamdır. -"You got the Midas Touch, baby",TXT_MIDASTOUCH,,,,"Máš Midasův dotek, zlato","Du har Midas Touch, baby",Dagobert Duck lässt grüßen!,"Έχεις το αγγιγμα το Μίδα, μωρό.","Vi akiris la Tuŝon de Midas, kara","Tienes el toque de Midas, muchach@[ao_esp]",,"Kulta, sinulla on Midaksen kosketus",,"Minden arannyá válik amit megérintesz, öreg","Hai avuto il Tocco di Mida, baby",ミダス王の様だな、ベイビー,넌 미다스의 손을 얻었어 베이베!,"Je hebt de Midas Touch, schatje","Du har Midas Touch, baby","Zdobył@[irreg_3_pl] dotyk Midasa, skarbie","Você tem o Toque de Midas, baby","Tens o Toque de Midas, baby","Ai Atingerea lui Midas, dragule","Ты превращаешь всё в золото, детка!","Имаш златке руке, душо","Sende Midas Dokunuşu var, bebeğim" -You got the stuff!,TXT_GOTSTUFF,,,,Dostal jsi věci!,Du har det hele!,Du hast den Kram erhalten,Πήρες τηατ πράγματα !,Vi akiris la aĵojn!,¡Tienes un montón de cosas!,¡Tienes muchas cosas!,Sait kamppeet!,Voilà ton équipement!,Megkaptad a cuccot!,Hai avuto il materiale!,スタッフを手に入れた!,무언가를 얻었다!,Je hebt het spul!,Du har greiene!,Zdobył@[irreg_3_pl] parę rzeczy!,Você ganhou muitas coisas!,ganhaste muitas coisas!,Ai tot ce-ți trebuie!,Получены предметы!,Покупили сте ствари!,Mal sende! -Freeze mode on,TXT_FREEZEON,,,,Režim zamrznutí ZAP,Frysetilstand TIL,Gefriermodus AN,Παγομένη λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Movhalta reĝimo ŝaltita,Modo suspendido activado,,Jäädytystila päällä,Temps arrêté.,Fagyasztás BE,Modalità arresto del tempo attivata,フリーズモード オン,시간정지 켬,Bevriesmodus aan,Frysemodus PÅ,Tryb zamrożenia włączony,Modo congelado ativado,,Modul înghețat activat,Режим заморозки включён,Мод замрзавања УКЉУЧЕН,Dondurma modu açık -Freeze mode off,TXT_FREEZEOFF,,,,Režim zamrznutí VYP,Frysetilstand FRA,Gefriermodus AUS,Παγομένη λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Movhalta reĝimo malŝaltita,Modo suspendido desactivado,,Jäädytystila pois päältä,Le temps reprend son cours..,Fagyasztás KI,Modalità arresto del tempo disattivata,フリーズモード オフ,시간정지 끔,Bevriesmodus uit,Frysemodus AV,Tryb zamrożenia wyłączony,Modo congelado desativado,,Modul înghețat dezactivat,Режим заморозки отключён,Мод замрзавања ИСКЉУЧЕН,Dondurma modu kapalı -You feel strange...,TXT_STRANGE,,,,Cítíš se divně...,Du føler dig mærkelig...,Du fühlst dich merkwürdig...,Νιώθης περίεργα...,Vi sentas vin strange...,Te sientes extrañ@[ao_esp]...,,Sinulla on kummallinen olo...,Vous vous sentez mal à l'aise...,Furán érzed magad...,Ti senti strano...,これは奇妙な感じだな...,뭔가 이상한 기분이...,Je voelt je vreemd...,Du føler deg rar...,Dziwnie się czujesz...,Você está com uma sensação estranha...,Tu sentes-te estranh@[ao_ptb].,Te simți ciudat...,Вы чувствуете себя странно...,Осећате се чудно...,Garip hissediyorsun. -You feel even stranger.,TXT_STRANGER,,,,Cítíš se ještě divněji...,Du føler dig endnu mere mærkelig.,Du fühlst dich noch merkwürdiger,Νιώθης ακόμα πιό περίεργα...,Vi sentas vin eĉ pli strange.,Te sientes aún más extrañ@[ao_esp],,Olosi on vieläkin kummempi.,Vous vous sentez très mal à l'aise...,Még furábban érzed magad.,Ti senti ancora più strano.,これはかなり奇妙だ。,기분이 더더욱 이상해졌다.,Je voelt je nog vreemder.,Du føler deg enda merkeligere.,Czujesz się jeszcze dziwniej.,Você está com uma sensação mais estranha ainda.,Tu sentes-te ainda mais estranh@[ao_ptb].,Te simți și mai ciudat.,Вы чувствуете себя очень странно.,Осећате се врло чудно.,Daha da garip hissediyorsun. -You feel like yourself again.,TXT_NOTSTRANGE,,,,Cítíš se opět jako ty.,Du føler dig som dig selv igen.,Du fühlst dich wieder wie du selbst,Νιώθης σάν τον εαύτο σου ξανά...,Vi denove sentas vin kiel vi mem.,Te sientes como tu mism@[ao_esp] otra vez.,,Tunnet olevasi jälleen oma itsesi.,Vous vous sentez mieux.,Magadhoz tértél.,Ti senti di nuovo te stesso.,自分自身の様に感じている。,자기 자신처럼 생각하게 됐다.,Je voelt je weer als jezelf.,Du føler deg som deg selv igjen.,Znów czujesz się sobą.,Você se sente normal novamente.,Tu sentes-te normal novamente.,Ți-ai revenit în simțiri.,Вы снова чувствуете себя собой.,Поново се осећате као ви.,Tekrar kendin gibi hissediyorsun. -Lead boots on,TXT_LEADBOOTSON,,,,Olověné boty ZAP,Blystøvler TIL,Bleistiefel AN,Μολυβδένιες μπότες ΕΝΕΡΓΟΠΟΙΗΜΈΝΕΣ,Botoj el plumbo ŝaltita,Botas de plomo activadas,,Lyijysaappaat päällä,Bottes en plomb ON,Ólomcsizma BE,Stivali di Piombo ON,足枷 オン,납 부츠 켬,Loden laarzen aan,Blystøvler PÅ,Ołowiane buty włączone,Botas de chumbo ativadas,,Bocanci de plumb activați,Свинцовые сапоги надеты,Оловне чизме УКЉУЧЕНЕ,Kurşun çizmeler -Lead boots off,TXT_LEADBOOTSOFF,,,,Olověné boty VYP,Blystøvler FRA,Bleistiefel AUS,Μολυβδένιες μπότες ΆΠΕΝΕΡΓΟΠΟΙΗΜΕΝΕΣ,Botoj el plumbo malŝaltita,Botas de plomo desactivadas,,Lyijysaappaat pois päältä,Bottes en plomb OFF,Ólomcsizma KI,Stivali di Piombo OFF,足枷 オフ,납 부츠 끔,Loden laarzen uit,Blystøvler AV,Ołowiane buty wyłączone,Botas de chumbo desativadas,,Bocanci de plumb dezactivați,Свинцовые сапоги сняты,Оловне чизме ИСКЉУЧЕНЕ,Kurşun çizmeler kapalı -You feel lighter,TXT_LIGHTER,,,,Cítíš se lehčí,Du føler dig lettere,Du fühlst dich leichter,Νιώθης πιο ελαφρής,Vi sentas vin pli malpeze,Te sientes más liger@[ao_esp],,Tunnet olosi kevyemmäksi,Vous vous sentez très léger.,Könnyűnek érzed magad,Ti senti più leggero,体が軽くなった,가벼운 느낌이 든다,Je voelt je lichter,Du føler deg lettere,Czujesz się lżejsz@[adj_pl],Você se sente mais leve,Tu sentes-te mais leve,Te simți mai ușor,Вы чувствуете лёгкость.,Осећате лакоћу.,Daha hafif hissediyorsun -Gravity weighs you down,TXT_GRAVITY,,,,Gravitace tě táhne dolů,Tyngdekraften tynger dig ned,Schwerkraft belastet dich,Η βαρύτητα σε πιάνει.,Gravito pezigas vin,La gravedad te hace descender,,Painovoima painaa sinua alas,La gravité vous ramène au sol.,A gravitáció lehúz téged,La gravità ti riporta a terra,重力に従った,중력이 당신을 붙잡았다,Zwaartekracht werkt op je...,Tyngdekraften tynger deg ned,Grawitacja znów cię przyciąga,A gravidade volta a funcionar normalmente,A gravidade voltou ao normal,Gravitația te trage în jos,Гравитация тянет вас вниз.,Гравитација Вас вуче надоле.,Yerçekimi seni ağırlaştırır -No Target ON,TXT_NOTARGET_ON,,,,Neútočící příšery ZAP,Ingen mål TIL,notarget AN,Αστόχευτη λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Neniu Celo ŜALTITA,No Objetivo ACTIVADO,,Hyökkäämättömyystila PÄÄLLÄ,Monstres aveugles et sourds ON,Nem támadnak a szörnyek BE,Modalità Mostri ciechi e sordi ATTIVATA,ノーターゲット オン,적 표적 감지 켬,Geen doelwit AAN,No Target PÅ,Głuche i Ślepe Potwory WŁĄCZONE,Sem alvos ATIVADO,,Modul Inamici fără Țintă ACTIVAT,Незаметность ВКЛЮЧЕНА,Нема мете УКЉУЧЕНО,Hedef Yok AÇIK -No Target OFF,TXT_NOTARGET_OFF,,,,Neútočící příšery VYP,Ingen mål FRA,notarget AUS,Αστόχευτη λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Neniu Celo MALŜALTITA,No Objetivo DESACTIVADO,,Hyökkäämättömyystila POIS PÄÄLTÄ,Monstres aveugles et sourds OFF,Nem támadnak a szörnyek KI,Modalità Mostri ciechi e sordi DISATTIVATA,ノーターゲット オフ,적 표적 감지 끔,Geen doelwit UIT,No Target AV,Głuche i Ślepe Potwory WYŁĄCZONE,Sem alvos DESATIVADO,,Modul Inamici fără Țintă DEZACTIVAT,Незаметность ОТКЛЮЧЕНА,Нема мете ИСКЉУЧЕНО,Hedef Yok KAPALI -"""Quake with fear!""",TXT_ANUBIS_ON,,,,„Třeste se strachy!“,"""Skælv af frygt!""","""Bebe vor Angst!""","""Τρέμε με φόβο!""","""Tremu pro timo!""","""¡Temblad de miedo!""","""Estremecete de Miedo!""","""Vapise pelosta!""",« Tremblez de terreur! »,"""Reszkess, halandó!""","""Trema con terrore!""",恐れおののけ!,공포에 떨어라!,„Beving van angst!“,Skjelv av frykt!,"""Trzęś się ze strachu""","""Trema de medo!""","""Trema com medo!""","""Tremură de Frică!""",«Дрожите от страха!»,„Дрхтите у страху!“,Korkudan titre! -No more Ogre Armor,TXT_ANUBIS_OFF,,,,Už žádné zlobří brnění,Ikke mere troldepanser,Keine Ogerrüstung mehr,Καθόλου δρακοντική πανοπλία πια,Ne plu Ogrokiraso,No más armadura de Ogro,,Ei enää örkkipanssaria,Plus d'armure d'ogre,Ogre pajzs lejárt,Niente più armatura Ogre,オーガアーマーはもう嫌,오거 갑옷은 이제 없다.,Geen Ogre Pantser meer,Ikke mer Ogre Armor,Nigdy więcej Pancerza Ogrów,Chega de Armadura de Ogro,Chega de Armadura de Ogre,Gata cu Armura de Căpcăun,Броня огра снята,Нема више бауков оклоп,Artık Ogre Zırhı yok -chasecam ON,TXT_CHASECAM_ON,,,,Pohled z třetí osoby ZAP,chasecam TIL,chasecam AN,Κάμερα τρίτου πρωσώπου ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Ĉaskamerao ŜALTITA,Cámara de seguimiento ACTIVADA,,Seurantakamera PÄÄLLÄ,,követő kamera BE,Modalità camera da inseguimento ATTIVATA,チェイスカメラ オン,3인칭 카메라 켬,Chasecam AAN,chasecam PÅ,kamera śledzenia WŁĄCZONA,Câmera em terceira pessoa ATIVADA,Câmara em Terceira Pessoa ATIVADA,Perspectivă la Persoana a 3-a ACTIVATĂ,Вид от третьего лица ВКЛЮЧЁН,Чејс-кам УКЉУЧЕН,Chasecam AÇIK -chasecam OFF,TXT_CHASECAM_OFF,,,,Pohled z třetí osoby VYP,chasecam FRA,chasecam AUS,Κάμερα τρίτου πρωσώπου ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Ĉaskamerao MALŜALTITA,Cámara de seguimiento DESACTIVADA,,Seurantakamera POIS PÄÄLTÄ,,követő kamera KI,Modalità camera da inseguimento DISATTIVATA,チェイスカメラ オフ,3인칭 카메라 끔,Chasecam UIT,chasecam AV,kamera śledzenia WYŁĄCZONA,Câmera em terceira pessoa DESATIVADA,Câmara em Terceira Pessoa DESATIVADA,Perspectivă la Persoana a 3-a DEZACTIVATĂ,Вид от третьего лица ОТКЛЮЧЁН,Чејс-кам ИСКЉУЧЕН,Chasecam KAPALI -1 baddie killed,TXT_BADDIE_KILLED,,,,1 zloun zabit,1 baddie dræbt,1 Bösewicht getötet,Ενας κακός πέθανε,1 malbonulo mortigita,1 malo matado,,1 pahis tapettu,1 enemi tué,1 rosszfiú kinyírva,Ucciso 1 maligno,1 体 殺した,1 명의 나쁜놈이 사살됨.,1 slechterik gedood,1 skurk drept,1 zabity przeciwnik,1 inimigo morto,,1 slab ucis,1 плохиш убит,Један зликовац убијен,1 kötü öldürüldü -%d baddies killed,TXT_BADDIES_KILLED,,,,%d zlounů zabito,%d baddies dræbt,%d Bösewichte getötet,%d τον κακόν πέθαναν,%d malbonuloj mortigitaj,%d malos matados,,%d pahista tapettu,%d enemis tués,%d rosszfiú kinyírva,Uccisi %d maligni,%d 体 殺した,%d 명의 나쁜놈들이 사살됨.,%d slechteriken gedood,%d skurker drept,%d zabitych przeciwników,%d inimigos mortos,,%d slabi uciși,Плохишей убито: %d,%d зликовца убијено,%d kötüler öldürüldü -1 monster killed,TXT_MONSTER_KILLED,,,,1 příšera zabita,1 monster dræbt,1 Monster getötet,Ένα τέρας πέθανε,1 monstro mortigita,1 monstruo matado,,1 hirviö tapettu,1 monstre tué,1 szörny kinyírva,Ucciso 1 mostro,1 匹 殺した,1 마리의 몬스터가 사살됨.,1 monster gedood,1 monster drept,1 zabity potwór,1 monstro morto,,1 monstru ucis,1 монстр убит,Једно чудовиште убијено,1 canavar öldürüldü -%d monsters killed,TXT_MONSTERS_KILLED,,,,%d příšer zabito,%d monster dræbt,%d Monster getötet,%d τον τεράτων πέθαναν,%d monstroj mortigitaj,%d monstruos matados,,%d hirviötä tapettu,%d monstres tués,%d szörny kinyírva,Uccisi %d mostri,%d 匹 殺した,%d 마리의 몬스터들이 사살됨.,%d monsters gedood,%d monstre drept,%d zabitych potworów,%d monstros mortos,,%d monștri uciși,Убито монстров: %d,%d чудовишта убијено,öldürülen %d canavar -Unable to resurrect. Player is no longer connected to its body.,TXT_NO_RESURRECT,,,,"Oživení není možno, hráč už není spojen se svým tělem.",Kan ikke genoplive. Spilleren er ikke længere forbundet med sin krop.,Kann nicht wiederbeleben. Der Spieler ist nicht mehr mit seinem Körper verbunden.,"Ανάσταση αδύνατη, ο παίχτης δεν είναι πια στο σώμα @[pro4_gr]","Ne kapablas revivi. Ludanto ne plu -estas konektita al sia korpo.",Imposible resucitar. El jugador ya no está conectado a su cuerpo.,,Ei mahdollista herätä henkiin. Pelaaja ei ole enää yhteydessä ruumiiseensa.,Impossible de ressuciter. Le joueur n'est plus connecté à son corps.,Nem sikerült a felélesztés. A játékos nincs összekötve a testtel.,Impossibile resuscitarsi. Il giocatore non è più connesso al suo corpo.,復活できない。プレイヤーはこの体に宿っていない。,부활할 수 없습니다. 플레이어는 더 이상 육체와 연결돼있지 않습니다.,Kan niet reanimeren. De speler is niet langer verbonden met zijn lichaam.,Kan ikke gjenoppstå. Spilleren er ikke lenger koblet til kroppen sin.,Nie można wskrzesić. Gracz nie jest już połączony z resztą swojego ciała.,"Impossível ressuscitar. O jogador não -está mais ligado ao próprio corpo.",,Imposibil de înviat. Jucătorul nu mai e conectat la cadavru.,Воскрешение невозможно. Игрок больше не соединён с трупом.,Немогуће оживети. Играч није више повезан са својим телом.,Diriltilemiyor. Oyuncu artık bedenine bağlı değil. -All Artifacts!,TXT_ALL_ARTIFACTS,,,All Artefacts!,Všechny artefakty!,Alle artefakter!,Alle Artefakte!,Όλα τα τεχνουργίματα!,Ĉiuj Artefaktoj!,¡Todos los Artefactos!,,Kaikki artefaktit!,Tous les artéfacts!,Összes értéktárgy!,Tutti gli Artefatti!,全アーティファクト!,모든 유물들!,Alle artefacten!,Alle artefakter!,Wszystkie Artefakty!,Todos os artefatos!,,Toate Artefactele!,Все артефакты!,Сви артифакти!,Tüm eserler! -What do you want to kill outside of a game?,TXT_WHAT_KILL,,,,"Co chceš zabít, když nejsi ve hře?",Hvad vil du dræbe uden for et spil?,Was willst du eigentlich außerhalb eines Spiels töten?,Τί θέλεις να σκοτώσεις έξω απο ένα παιχνίδι ?,Kion vi volas mortigi ekster ludo?,¿Qué intentas matar fuera de una partida?,,Mitä haluat tappaa pelin ulkopuolella?,Que voulez-vous tuer en dehors d'une partie?,Mit tudnál megölni játékon kívül?,Cosa vorresti uccidere fuori dal gioco?,ゲーム外で何を殺す気だ?,게임 밖에서 무엇을 죽이고 싶습니까?,Wat wil je buiten een spel om doden?,Hva vil du drepe utenfor et spill?,Co ty chcesz zabić poza grą?,O que você gostaria de matar fora de um jogo?,,Ce vrei să ucizi în afara unui joc?,Что вы хотите убить вне игры?,Шта желите да убијете ван игре?,Oyun dışında ne öldürmek istiyorsun? -Frozen player properties turned off,TXT_NOT_FROZEN,,,,Vlastnosti držící hráče na místě vypnuty,Frysningstilstand er slået fra.,Gefrier-Modus abgeschaltet.,Η ιδιότητες ενος παγομένου παίχτη απενεργοποίθηκαν,Atributoj de movhaltitaj ludantoj malŝaltitaj,Propiedades de jugador congelado desactivadas,,Jäätyneen pelaajan ominaisuudet kytketty pois päältä,Propriété gelée du joueur annulée.,Fagyasztott játékos tulajdonságai kikapcsolva,Proprietà del giocatore ghiacciato disattivate,凍ったプレイヤーのプロパティを無効化,플레이어 정지 속성이 꺼졌습니다.,Eigenschappen van de bevroren speler uitgeschakeld,Frosne spilleregenskaper slått av,Właściwości zamrożonego gracza wyłączone,Propriedades de jogador congelado desativadas,,Proprietăți jucători înghețați DEZACTIVATE,Свойства замороженного игрока отключены,Смрзнути играчи искључени,Dondurulmuş oyuncu özellikleri kapatıldı -,,Automap,,,,,,,,,,,,,,,,,,,,,,,, -Follow Mode OFF,AMSTR_FOLLOWOFF,,,,Režim sledování VYP,Følg-tilstand TIL,Folgen-Modus AUS,Ακολούθηση ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Sekvigreĝimo MALŜALTITA,Modo de seguimiento DESACTIVADO,,Seuraamistila POIS PÄÄLTÄ,Suivi du Joueur OFF,Követés mód KI,Mappa scorribile ATTIVATA,追従モード: オフ,추적 모드 끔,Volgmodus UIT,Følgemodus AV,Tryb śledzenia WYŁĄCZONY,Modo de seguimento DESATIVADO,,Mod Urmărire DEZACTIVAT,Привязка к игроку ОТКЛЮЧЕНА,Праћење ИСКЉУЧЕНО,Takip Modu KAPALI -Follow Mode ON,AMSTR_FOLLOWON,,,,Režim sledování ZAP,Følg-tilstand FRA,Folgen-Modus AN,Ακολούθηση ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Sekvigreĝimo ŜALTITA,Modo de seguimiento ACTIVADO,,Seuraamistila PÄÄLLÄ,Suivi du Joueur ON,Követés mód BE,Mappa scorribile DISATTIVATA,追従モード: オン,추적 모드 켬,Volgmodus AAN,Følgemodus PÅ,Tryb śledzenia WŁĄCZONY,Modo de seguimento ATIVADO,,Mod Urmărire ACTIVAT,Привязка к игроку ВКЛЮЧЕНА,Праћење УКЉУЧЕНО,Takip Modu AÇIK -Grid ON,AMSTR_GRIDON,,,,Mřížka ZAP,Raster TIL,Gitter AN,Πλέχμα ΕΝΕΡΓΟΠΟΙΜΈΝΟ,Krado ŜALTITA,Cuadrícula ACTIVADA,,Ruudukko PÄÄLLÄ,Quadrillage ON,Rács BE,Griglia ATTIVATA,グリッド: オン,격자 켬,Raster AAN,Rutenett PÅ,Siatka WŁĄCZONA,Grade ATIVADA,Grelha ATIVADA,Grilă ACTIVATĂ,Сетка ВКЛЮЧЕНА,Мрежа УКЉУЧЕНА,Izgara AÇIK -Grid OFF,AMSTR_GRIDOFF,,,,Mrizka VYP,Raster FRA,Gitter AUS,Πλέχμα ΆΠΕΝΕΡΓΟΠΟΙΜΈΝΟ,Krado MALŜALTITA,Cuadrícula DESACTIVADA,,Ruudukko POIS PÄÄLTÄ,Quadrillage OFF,Rács KI,Griglia DISATTIVATA,グリッド: オフ,격자 끔,Raster UIT,Rutenett AV,Siatka WYŁĄCZONA,Grade DESATIVADA,Grelha DESATIVADA,Grilă DEZACTIVATĂ,Сетка ОТКЛЮЧЕНА,Мрежа ИСКЉУЧЕНА,Izgara KAPALI -Texture Mode ON,AMSTR_TEXON,,,,Texturovaný režim ZAP,Teksturtilstand TIL,Texturmodus AN,Γραφικός χάρτης ΕΝΕΡΓΟΠΟΙΜΈΝΟΣ,Tekstura Reĝimo ŜALTITA,Modo de texturas ACTIVADO,,Pintakuviointitila PÄÄLLÄ,Mode Texturé ON,Textúrák mód BE,Modalità Texture ATTIVATA,テクスチャーモード: オン,텍스쳐 모드 켬,Textuurmodus AAN,Teksturmodus PÅ,Tekstury WŁĄCZONE,Modo de textura ATIVADO,,Mod Texturat ACTIVAT,Текстурный режим ВКЛЮЧЁН,Текстуре УКЉУЧЕНЕ,Doku Modu AÇIK -Texture Mode OFF,AMSTR_TEXOFF,,,,Texturovaný režim VYP,Teksturtilstand FRA,Texturmodus AUS,Γραφικός χάρτης ΑΠΕΝΕΡΓΟΠΟΙΜΈΝΟΣ,Tekstura Reĝimo MALŜALTITA,Modo de texturas DESACTIVADO,,Pintakuviointitila POIS PÄÄLTÄ,Mode Texturé OFF,Textúrák mód KI,Modalità Texture DISATTIVATA,テクスチャーモード: オフ,텍스쳐 모드 끔,Textuurmodus UIT,Teksturmodus AV,Tekstury WYŁĄCZONE,Modo de textura DESATIVADO,,Mod Netexturat DEZACTIVAT,Текстурный режим ОТКЛЮЧЁН,Текстуре ИСКЉУЧЕНЕ,Doku Modu KAPALI -Marked Spot,AMSTR_MARKEDSPOT,,,,Značka,Markeret placering,Punkt markiert,Μαρκαρησμένη τοποθεσεία,Loko Markita,Punto marcado,,Merkitty paikka,Repère marqué.,Megjelölt hely,Posizione segnata,目標をマークした,지점 추가,Gemarkeerde plek,Markert punkt,Oznaczono miejsce,Posição marcada,,Loc Marcat,Отметка,Означено место,İşaretli Nokta -All Marks Cleared,AMSTR_MARKSCLEARED,,,,Všechny značky smazány,Alle markeringer slettes,Alle Markierungen gelöscht,Όλες η μαρκαρησμένη τοποθεσείες είναι καθαρησμένες,Ĉiuj Markoj Forigitaj,Todas las marcas eliminadas,,Kaikki merkit pyyhitty,Repères éffacés.,Összes jelölés törölve,Cancellati tutti i segni,全目標を解除した,모든 지점 지워짐,Alle markingen gewist,Alle merker fjernet,Wszystkie miejsca wyczyszczone,Todas as marcas removidas,,Toate Marcările Șterse,Отметки очищены,Ознаке избрисане,Tüm İşaretler Temizlendi -,,Multiplayer,,,,,,,,,,,,,,,,,,,,,,,, -Fraglimit hit.,TXT_FRAGLIMIT,,,,Fraglimit dosáhnut.,Fraggrænse nået,Fraglimit erreicht,Το όριο κοματιασμόν έχει φτάσει.,Ludmurdo-limo trafita.,Límite de bajas alcanzado.,,Frägiraja saavutettu.,Limite de frags atteinte.,Fraghatár elérve.,Fraglimit raggiunto.,フラグリミット!,킬제한에 도달했습니다.,Fraglimiet bereikt.,Fraglimit treff.,Limit fragów wyczerpany.,Limite de frags atingido.,,Limita de ucideri atinsă.,Достигнут лимит фрагов.,Фраг-лимит достигнут.,Frag limiti vuruldu. -Timelimit hit.,TXT_TIMELIMIT,,,,Časový limit dosáhnut.,Tidsgrænse nået,Zeitlimit erreicht,Το χρονικό όριο έχει φτάσει.,Tempolimo trafita.,Límite de tiempo alcanzado.,,Aikaraja saavutettu.,Limite de temps atteinte.,Időhatár elérve.,Timelimit raggiunto.,ゲームセット!,시간제한에 도달했습니다.,Tijdslimiet bereikt.,Tidsbegrensningen er nådd.,Limit czasowy wyczerpany.,Limite de tempo atingido.,,Limita de timp atinsă.,Достигнут лимит времени.,Временско ограничење достигнуто.,Zaman limiti vuruldu. -%o was looking good until %g killed %hself!,SPREEKILLSELF,,,,%o vypadal@[ao_cs] dobře dokud se @[self_cs] nezabil@[ao_cs]!,"%o så godt ud, indtil @[pro_dk] dræbte sig selv!","%o sah gut aus, bis das Unglück geschah.",@[art_gr] %o πήγενε μια χαρά μέχρι που αυτοκτόνησε!,"%o estis faranta bone, ĝis @[pro_eo] mortigis sin!",¡%o se veía bien hasta que %g se mató a si mism@[ao_esp]!,,"%o oli liekeissä, kunnes meni tappamaan itsensä!",%o était en pleine folie meurtrière avant qu' %g ne se bute!,%o jól nézett ki még mielőtt megölte magát!,%o stava andando bene finchè non si è ucciso da solo!,%o は自滅するまでなかなか良かったぞ!,%o 이(가) 잘 나가려던 참에 자살했습니다!,%o zag er goed uit tot %g zelfmoord pleegde!,%o så bra ut helt til %g tok livet av seg!,%o wyglądał dobrze dopóki się nie zabił@[ao_pl],%o estava indo bem até se matar!,,%o arăta atât de bine până să se sinucidă,"%o неплохо выглядел@[ao_rus], пока не покончил@[ao_rus] с собой!",%o је изгледа@[ao_1_sr] добро док није уби@[ao_1_sr] сам@[ao_3_sr] себе!,%o kendini öldürene kadar iyi görünüyordu! -%o's killing spree was ended by %k,SPREEOVER,,,,%o@[psn1_cs] vraždící řádění ukončil hráč %k.,%os drabstog blev afsluttet af %k,%os Amoklauf wurde von %k beendet.,Ο/Η %k σταμάτησε την ανθρωποκτονία %h %o.,La mortigado de %o estis finita de %k,%k acabó con la racha de muerte de %o,,%k päätti pelaajan %o tapposarjan,La folie meurtrière de %o à été terminée par %k!,%o ámokfutását %k megállította.,La sequela di frag di %o è stata terminata da %k,%k が %o の快進撃を断ち切った!,%k 이(가) %o 의 연속 킬을 처단했습니다,%o's moordpartij werd beëindigd door %k.,%o's drapsturné ble avsluttet av %k.,Seria zabójstw %o zakończona przez %k,A matança de %o foi interrompida por %k,,Pofta de ucis a lui %o a fost pusă în cui de către %k,Игрок %k прервал череду убийств игрока %o,Серијско убијање играча %o је завршио играч %k,%o onu öldürene kadar %k iyi görünüyordu. -%k is on a killing spree!,SPREE5,,,,%k začal@[ao_cs] řádit!,%k er i gang med en mordserie!,%k läuft Amok!,Ο/Η %k άρχισε μια ανθρωποκτονία!,%k estas sur mortigado!,¡%k está atacando de lo lindo!,,%k on sarjamurhaaja!,%k est en folie meurtrière!,%o egy Ámokfutó!,%k è preda di un momento omicida!,%k が連続キル!,%k 연속 킬!,%k is op een moordpartij!,%k er på drapsturné!,%k popełnia serię morderstw!,%k está cometendo uma matança!,,%k are chef de ucis!,Игрок %k совершил череду убийств!,%k је серијални убица!,%k bir ölüm çılgınlığında! -%k is on a rampage!,SPREE10,,,,%k zuří!,%k er på et amokløb!,%k tobt sich aus!,Ο/Η %k είναι σε ξέσπασμα!,%k estas sur furiozado!,¡%k está en medio de una aniquilación!,,%k riehuu valtoimenaan!,%k est en plein massacre!,%o Tombol!,%k sta facendo un massacro!,%k が大暴れだ!,%k 이(가) 미쳐 날뛰고 있습니다!,%k heeft razernij!,%k går amok!,%k doznaje szału!,%k está massacrando!,,%k e înverșunat!,Игрок %k в неистовстве!,%k дивља!,%k kudurmuş durumda! -%k is dominating!,SPREE15,,,,%k dominuje!,%k er dominerende!,%k dominiert!,Ο/Η %k κατακτεί.,%k estas dominanta!,¡%k está dominando!,,%k hallitsee suvereenisti!,%k domine!,%o Uralkodik!,%k sta dominando tutti!,%k が圧倒している!,%k 이(가) 우세하고 있습니다!,%k domineert!,%k dominerer!,%k dominuje!,%k está dominando!,,%k domină!,Игрок %k господствует!,%k доминира!,%k hükmediyor! -%k is unstoppable!,SPREE20,,,,%k je nezastaviteln@[adj_cs]!,%k er ustoppelig!,%k kann nicht gestoppt werden!,Ο/Η %k είναι ασταμάτητος/η!,%k estas nehaltigebla!,¡%k es imparable!,,%k on pysäyttämätön!,%k est inarrétable!,%o Megállíthatatlan!,%k è inarrestabile!,%k が止まらない!,%k 을(를) 막을 수없습니다!,%k is niet te stoppen!,%k er ustoppelig!,%k jest niepowstrzymany!,%k é implacável!,,%k e de neoprit!,Игрок %k неостановим!,Играч %k је незаустављив!,%k durdurulamaz! -%k is Godlike!,SPREE25,,,,%k je boží!,%k er som en gud!,%k ist wie Gott!,Ο/Η %k είναι σαν θεός/θεά!,%k estas Dia!,¡%k es una máquina de matar!,,%k on kuin jumala!,%k est un dieu!,%o Istencsászár!,%k è un dio!,%k が神の様だ!,%k 은(는) 신적입니다! ,%k is Goddelijk!,%k er guddommelig!,%k jest Bogem!,%k é um deus da matança!,,%k e precum un Zeu!,Игрок %k богоподобен!,Играч %k је божанствен!,%k tanrı gibi! -Double kill!,MULTI2,,,,Dvoj-zabití!,Dobbelt drab!,Doppel-Kill!,Δυπλός Θάνατος!,Duobla mortigo!,¡Dos menos!,,Tuplatappo!,Double meurtre!,Dupla gyilok!,Doppia uccisione!,ダブルキル!,더블 킬!,Dubbele kill!,Dobbeltdrap!,Podwójne zabójstwo!,Morte dupla!,,Dublă ucidere!,Двойное убийство!,Дупло убиство!,Çifte öldürme! -Multi kill!,MULTI3,,,,Multi-zabití!,Multi-drab!,Multi-Kill!,Πολυθάνατος!,Pluraj mortigoj!,¡Multidestrucción!,,Multitappo!,Multi meurtre!,Multi gyilok!,Tripla uccisione!,マルチキル!,멀티 킬!,,Multidrap!,Multi-zabójstwo!,Morte tripla!,,Ucidere multiplă!,Массовое убийство!,Вишеструко убиство!,Çoklu öldürme! -Ultra kill!,MULTI4,,,,Ultra-zabití!,Ultra-drab!,Ultra-Kill!,Υπερθάνατος!,Ekstremaj mortigoj!,¡¡HIPERDESTRUCCIÓN!!,,Ultratappo!,Ultra meurtre!,Ultra gyilok!,Ultra uccisione!,ウルトラキル!,울트라 킬!,,Ultra drep!,Ultra-zabójstwo!,Ultra matança!,,Ultra ucidere!,Ультра-убийство!,Ултра убиство!,Ultra öldürme! -Monster kill!,MULTI5,,,,Monstr-zabití!,Monster-drab!,Monster-Kill!,Τερατόδες σκοτωμός!,Monstraj mortigoj!,¡¡¡S.U.P.E.R.D.E.S.T.R.U.C.C.I.Ó.N!!!,,Hirviömäinen tappo!,,Szörnyű gyilkolás!,Uccisione Mostruosa!,モンスターキル!,몬스터 킬!,,Monster drep!,Potworne zabójstwo!,Matança monstro!,Matança monstruosa!,Ucidere monstruoasă!,Чудовищное убийство!,Монструозно убиство!,Canavar öldürme! -,,Scoreboard,,,,,,,,,,,,,,,,,,,,,,,, -Items,SCORE_ITEMS,,,,Předměty,Genstande,Gegenstände,Αντεικείμενα,Objektoj,Objetos,,Esineet,Objets,Tárgyak,Oggetti,アイテム,획득한 아이템,Items,Gjenstander,Przedmioty,Itens,,Obiecte,Предметы,Предмети,Eşyalar -Bonus,SCORE_BONUS,,,,,,Bonus,Bonus,Bonuso,Bonificaciones,,Lisäedut,,Bónusz,Bonus,ボーナス,보너스,Bonus,,Bonusy,Bônus,,Bonus,Бонус,Бонус,Bonus -Color,SCORE_COLOR,,,Colour,Barva,Farve,Farbe,Χρώμα,Koloro,,,Väri,Couleur,Szín,Colore ,色,색상,Kleur,Farge,Kolor,Cor,,Culoare,Цвет,Боја,Renk -Secret,SCORE_SECRET,,,,Skrýše,Hemmeligt,Geheimnis,Μυστικό,Sekreto,Secreto,,Salat,,Titok,Segreto,シークレット,밝혀낸 비밀,Geheim,Hemmelig,Sekret,Segredo,,Secret,Тайники,Тајна,Sır -Name,SCORE_NAME,,,,Jméno,Navn,Name,Όνομα,Nomo,Nombre,,Nimi,Nom,Név,Nome,名前,이름,Naam,Navn,Nazwa,Nome,,Nume,Игрок,Име,İsim -Delay (ms),SCORE_DELAY,,,,Zpoždění (ms),Forsinkelse (ms),Verzögerung (ms),Kαθυστέρηση (μδ),Prokrasto (ms),Retraso (ms),,Viive (ms),Délai (ms),Késleltetés (ms),Ritardo (ms) ,ping,핑 (밀리초당),Vertraging (ms),Forsinkelse (ms),Opóźnienie (ms),Atraso (ms),,Întârziere (ms),Задержка (мс),Кашњење (мс),Gecikme (ms) -Kills,SCORE_KILLS,,,,Zabití,Dræber,,Σκοτομοί,Mortigoj,Asesinatos,,Tapot,Victimes,Áldozatok,Uccisioni,キル,킬수,Dood,Drepte,Zabici,Vítimas,,Ucideri,Убийства,Убиства,Öldürür -Frags,SCORE_FRAGS,,,,Fragy,,,Κοματιασμοί,Ludmurdoj,Bajas,,Frägit,,Frag-ek,Frags,フラグ,플레이어 킬수,,,Fragi,Frags,,Victime,Фраги,Фрагови,Frags -Deaths,SCORE_DEATHS,,,,Smrti,Dødsfald,Tode,Θάνατοι,Mortoj,Muertes,,Kuolemat,Morts,Halálok,Morti,デス,사망한 횟수,Sterfgevallen,Dødsfall,Śmierci,Mortes,,Decese,Смерти,Смрти,Ölümler -Other,SCORE_OTHER,,,,Ostatní,Andre,Andere,,Alia,Demás,,Muu,,Egyéb,Altro,その他,,Anders,Andre,Inne,Outro,,Altele,Прочее,,Diğer -Missed,SCORE_MISSED,,,,Minuto,Forpasset,Verfehlt,Ξεχάστηκαν,Mankita,Pérdidas,,Hudit,Ratés,Kihagyva,Mancati ,ミス,놓친 수,Gemist,Ubesvarte,Ominięte,Perdido,,Ratate,Пропущено,Пропуштено,Cevapsız -Total,SCORE_TOTAL,,,,Celkem,,Gesamt,Συνολικό,Tuto,,,Yhteensä,Total,Összesen,Totale,合計,총점,Totaal,Totalt,Totalne,Total,,Total,Всего,Укупно,Toplam -Level Time,SCORE_LVLTIME,,,,Čas v levelu,Niveau Tid,Levelzeit,Χρόνος Πίστας,Daŭro de Nivelo,Tiempo de nivel,,Tasoaika,Temps niveau,Pályaidő,Tempo Livello ,時間,레벨 시간,Leveltijd,Nivå Tid,Czas,Tempo de fase,Tempo do Nível,Timp Petrecut,Время уровня,Време нивоа,Seviye Zaman -,,Level Summary,,,,,,,,,,,,,,,,,,,,,,,, -Kills,TXT_IMKILLS,,,,Zabití,Dræber,,Σκοτομοί,Mortigoj,Muertes,,Tapot,Morts,Áldozatok,Uccisioni,キル,킬수,Dood,Drepte,Zabici,Vítimas,,Ucideri,Убийств,Непријатељи,Öldürür -Items,TXT_IMITEMS,,,,Předměty,Genstande,Gegenstände,Αντεικείμενα,Objektoj,Objetos,,Esineet,Objets,Tárgyak,Oggetti,アイテム,획득한 아이템,Items,Gjenstander,Przedmioty,Itens,,Obiecte,Предметов,Ставке,Eşyalar -Secrets,TXT_IMSECRETS,,,,Skrýše,Hemmeligheder,Geheimnisse,Μυστικά,Sekretoj,Secretos,,Salat,,Titkok,Segreti,シークレット,밝혀낸 비밀,Geheimen,Hemmeligheter,Sekrety,Segredos,,Secrete,Тайников,Тајне,Sırlar -Time,TXT_IMTIME,,,,Čas,Tid,Zeit,Χρόνος,Daŭro,Tiempo,,Aika,Temps,Idő,Tempo,経過時間,소모한 시간,Tijd,Tid,Czas,Tempo,,Timp,Время,Време,Zaman -Par,TXT_IMPAR,,,,,,,Μέσος Όρος,Alparo,,,,,Átlag,Media,最速時間,기준 시간,,,Par,Média,,Record,Рекорд,Рекорд,Par -Finished,WI_FINISHED,,,,Dokončeno,Færdig,Abgeschlossen,Ολοκληρώθηκε,Finita,Completado,,Suoritettu,Terminé,Teljesítve,Finito,攻略,완료,Klaar,Ferdig,Ukończono,Finalizado,,Terminat,Уровень завершён,Ниво завршен,Bitti -Entering,WI_ENTERING,,,,Vstupuješ do,Indtastning af,Betrete,Είσοδος,Enirante,Entrando a:,,Seuraava kohde,Niveau Suivant,Következik,Prossimo livello,突入開始,입장,Volgende,Går inn,Wchodzisz do:,Próxima fase,Próximo nível,Începe,Переход,Следећи ниво,Giriş -Now entering:,WI_ENTERING,,heretic hexen,,Nyní vstupuješ do:,Indtastning af:,Betrete:,Τώρα εισέρχεσε στο:,Nun enirante:,Ahora entrando a:,,Seuraava kohde:,Vous entrez dans:,Következik:,Entrando adesso in:,突入中:,입장합니다:,Volgende:,Går nå inn:,Teraz wchodzisz do:,Entrando em:,A entrar em:,Acum începe:,Переход на:,Следећи ниво:,Şimdi giriyoruz: -,,HUD,,,,,,,,,,,,,,,,,,,,,,,, -Monsters:,AM_MONSTERS,,,,Příšery:,Monstre:,Monster:,Τέρατα,Monstroj:,Monstruos:,,Hirviöt:,Monstres:,Szörnyek:,Mostri,奴等:,죽인 적들:,Monsters:,Monstre:,Potwory:,Monstros:,,Monștri:,Монстры:,Чудовишта:,Canavarlar: -Secrets:,AM_SECRETS,,,,Skrýše:,Hemmeligheder:,Geheimnisse:,Μυστικά,Sekretoj:,Secretos:,,Salat:,,Titkos helyek:,Segreti,隠場:,찾은 비밀:,Geheimen:,Hemmeligheter:,Sekrety:,Segredos:,,Secrete:,Тайники:,Тајне:,Sırlar: -Items:,AM_ITEMS,,,,Věci:,Genstande:,Gegenstände:,Αντεικείμενα,Objektoj:,Objetos:,,Esineet:,Objets:,Tárgyak:,Oggetti,物資:,얻은 아이템:,Items:,Gjenstander:,Przedmioty:,Itens:,,Obiecte:,Предметы:,Предмети:,Eşyalar: -,,Obituaries,,,,,,,,,,,,,,,,,,,,,,,, -%o suicides.,OB_SUICIDE,,,,%o spáchal@[ao_cs] sebevraždu.,%o begår selvmord.,%o begeht Selbstmord.,@[art_gr] %o αυτοκτόνησε,%o sinmortigis.,%o se ha suicidado.,%o se suicidó.,%o teki itsemurhan.,%o se suicide.,%o öngyilkos lett.,%o si è suicidato.,%o は自殺した。,%o 은(는) 자살했다.,%o pleegt zelfmoord.,%o begår selvmord.,%o popełnił@[ao_pl] samobójstwo.,%o se suicidou.,,%o se sinucide.,Игрок %o покончил с собой.,%o самоубиства.,%o intihar eder. -%o fell too far.,OB_FALLING,,,,%o spadl@[ao_cs] příliš daleko.,%o faldt for langt ned.,%o fiel zu tief.,@[art_gr] %o έπεσε,%o falis tro fore.,%o se ha caído desde muy alto.,%o se cayó desde muy alto.,%o putosi liian kaukaa.,%o est tombé@[e_fr] trop loin.,%o túl messze esett.,%o è caduto troppo in basso.,%o はあまりにも高い所から転落した。,%o 은(는) 높은 곳에서 떨어져 사망했다.,%o viel te ver.,%o falt for langt.,%o spadł@[ao_pl] za daleko.,%o caiu de um lugar alto.,,%o a căzut prea departe.,Игрок %o упал слишком далеко.,%o је па@[ao_1_sr] до сад.,%o çok uzağa düştü. -%o was squished.,OB_CRUSH,,,,%o byl@[ao_cs] rozdrcen@[ao_cs].,%o blev mast.,%o wurde zerquetscht,@[art_gr] %o συνθλίφτηκε,%o estis dispremita.,%o ha sido aplastad@[ao_esp].,%o fue aplastad@[ao_esp].,%o liiskautui.,%o a été écrasé@[e_fr].,%o össze lett lapítva.,%o è stato schiacciato.,%o は潰された。,%o 은(는) 뭉게졌다.,%o werd geplet.,%o ble knust.,%o spłaszczył@[ao_pl] się.,%o foi esmagad@[ao_ptb].,,%o a fost strivit.,Игрок %o был раздавлен.,%o је здробљен@[adj_1_sr].,%o ezildi. -%o tried to leave.,OB_EXIT,,,,%o se pokusil@[ao_cs] odejít.,%o forsøgte at gå.,%o wollte gehen.,@[art_gr] %o προσπάθησε να φύγει,%o provis foriri.,%o ha tratado de huir.,%o trató de huir.,%o yritti häipyä.,%o a tenté de partir.,%o megpróbált lelépni.,%o ha provato a uscire.,%o は逃げようとした。,%o 은(는) 나가려고 발버둥 쳤다.,%o probeerde te vertrekken.,%o prøvde å dra.,%o spróbował@[ao_pl] odejść.,%o tentou sair.,,%o a încercat să plece.,Игрок %o попытался уйти.,%o покуша@[ao_1_sr] да оде.,%o gitmeye çalıştı. -%o can't swim.,OB_WATER,,,,%o neumí plavat.,%o kan ikke svømme.,%o kann nicht schwimmen.,@[art_gr] %o δέν μπορεί να κολυμπήσει,%o ne scipovas naĝi.,%o no sabe nadar.,,%o ei osaa uida.,%o ne sait pas nager.,%o nem tud úszni.,%o non sapeva nuotare.,%o は泳げなかった。,%o 은(는) 익사했다.,%o kan niet zwemmen.,%o kan ikke svømme.,%o nie umie pływać.,%o não sabe nadar.,,%o nu poate înota.,Игрок %o не умел плавать.,%o не може да плива.,%o yüzme bilmiyor. -%o mutated.,OB_SLIME,,,,%o zmutoval@[ao_cs].,%o muterede.,%o mutierte.,@[art_gr] %o μεταλάχθηκε,%o mutaciis.,%o ha mutado.,%o mutó.,%o mutatoitui.,%o a muté.,%o mutánssá alakult.,%o è mutato.,%o は変異した。,%o 은(는) 돌연사를 당했다.,%o muteerde.,%o muterte.,%o zmutował@[ao_pl].,%o sofreu mutação.,,%o a avut parte de o mutație.,Игрок %o мутировал.,%o је мутиран@[adj_1_sr].,%o mutasyona uğradı. -%o melted.,OB_LAVA,,,,%o se rozpustil@[ao_cs].,%o smeltede.,%o schmolz.,@[art_gr] %o έλειοσε,%o fandiĝis.,%o se ha fundido.,%o se fundió.,%o suli.,%o a fondu.,%o megolvadt.,%o si è sciolto.,%o は溶かされた。,%o 은(는) 녹아버렸다.,%o smolt.,%o smeltet.,%o stopił@[ao_pl] się.,%o derreteu.,%o derreteu-se.,%o s-a topit.,Игрок %o расплавился.,%o је отопљен@[adj_1_sr].,%o eridi. -%o went boom.,OB_BARREL,,,,%o udělal@[ao_cs] bum.,%o gik bum.,%o explodierte.,@[art_gr] %o έσκασε,%o eksplodis.,%o ha explotado en mil pedazos.,%o explotó en mil pedazos.,%o poksahti.,%o s'est pété@[e_fr] la face.,%o felrobbant.,%o ha fatto bum.,%o は爆発で吹き飛ばされた。,%o 은(는) 폭사했다.,%o ging boem.,%o gikk i lufta.,%o zrobił@[ao_pl] bum.,%o explodiu.,,%o a explodat.,Игрок %o взорвался.,%o је отиш@[ao_2_sr] бум.,%o patladı. -%o stood in the wrong spot.,OB_SPLASH,,,,%o stál@[ao_cs] na špatném místě.,%o stod på det forkerte sted.,%o war am falschen Ort.,@[art_gr] %o έκατσε στο λάθος σημείο,%o staris en la malĝusta loko.,%o estaba en el sitio equivocado.,,%o seisoi väärässä paikassa.,%o s'est tenu@[e_fr] au mauvais endroit.,%o rossz helyre állt.,%o si è trovato nel posto sbagliato.,%o はいけない場所に立っていた。,%o 은(는) 위험한 곳에 서 있었다.,%o stond op de verkeerde plek.,%o sto på feil sted.,%o stan@[irreg_2_pl] w złym miejscu.,%o ficou no lugar errado.,,%o a stat în locul nepotrivit.,Игрок %o стоял в неверной точке.,%o је стаја@[ao_1_sr] на погрешно место.,%o yanlış yerde durdu. -%o should have stood back.,OB_R_SPLASH,,,,%o měl@[ao_cs] stát o trochu dál.,%o skulle have stået tilbage.,%o hätte Abstand halten sollen.,@[art_gr] %o έπρεπε να είχε κάτσι πίσω,%o devintus forstarinta.,%o debería haberse apartado.,,%o oli liian likellä.,%o aurait dû garder ses distances.,%o túl közel állt.,%o si sarebbe dovuto allontanare.,%o は後ろへ引くべきだった。,%o 은(는) 좀 더 떨어져야만 했다.,%o had afstand moeten houden.,%o burde ha stått tilbake.,%o nie ustąpił@[ao_pl] na bok.,%o deveria ter se afastado.,,%o ar fi trebuit să stea deoparte.,Игрок %o не отступил в сторону.,Играчу %o је требало да стоји назад.,%o geri çekilmeliydi. -%o should have stood back.,OB_ROCKET,,,,%o měl@[ao_cs] stát o trochu dál.,%o skulle have stået tilbage.,%o hätte Abstand halten sollen.,@[art_gr] %o έπρεπε να είχε κάτσι πίσω,%o devintus forstarinta.,%o debería haberse apartado.,,%o oli liian likellä.,%o aurait dû garder ses distances.,%o túl közel állt.,%o si sarebbe dovuto allontanare.,%o は後ろへ引くべきだった。,%o 은(는) 더 멀리 떨어져야만 했다.,%o had afstand moeten houden.,%o burde ha stått tilbake.,%o nie ustąpił@[ao_pl] na bok.,%o deveria ter se afastado.,,%o ar fi trebuit să stea deoparte.,Игрок %o не отступил в сторону.,Играчу %o је требало да стоји назад.,%o geri çekilmeliydi. -%o killed %hself.,OB_KILLEDSELF,,,,%o se zabil@[ao_cs].,%o begik selvmord.,%o tötete sich selbst.,@[art_gr] %o αυτοκτόνησε,%o mortigis sin.,%o se ha matado a sí mism@[ao_esp].,%o se mató a sí mism@[ao_esp].,%o tappoi itsensä.,%o s'est tué@[e_fr].,%o megölte magát.,%o ha ucciso se stesso.,%o は自滅した。,%o 은(는) 자멸했다.,%o bracht zichzelf om.,%o begår selvmord.,%o zabił@[ao_pl] się.,%o se matou.,%o matou-se,%o s-a sinucis.,Игрок %o убил себя.,%o је уби@[ao_1_sr] себе.,%o kendini öldürdü. -%o was killed by the power of voodoo.,OB_VOODOO,,,,%o byl@[ao_cs] zabit@[ao_cs] sílou voodoo.,%o blev dræbt af voodooens magt.,%o wurde durch Voodoo getötet.,@[art_gr] %o πέθανε απο τη δύναμη του βουντου,%o estis mortigita de la povo de voduo.,%o ha sido asesinad@[ao_esp] con el poder del vudú.,%o fue asesinad@[ao_esp] con el poder del vudú.,%o kuoli voodoon voimasta.,%o a succombé au pouvoir du Vaudou.,%o meghalt a voodoo erejének köszönhetően.,%o è stato ucciso dalla potenza del voodoo.,%o はブードゥー人形で殺された。,%o 은(는) 부두 마법의 저주를 받았다.,%o werd gedood door de kracht van voodoo.,%o ble drept av voodooens kraft.,%o umarł@[ao_pl] od mocy voodoo.,%o morreu pelo poder do voodoo.,,%o a fost omorât prin puterea voodoo.,Игрок %o убит силой Вуду.,%o је убијен@[adj_1_sr] од стране моћи Voodoo-а.,%o voodoo'nun gücü tarafından öldürüldü. -%o was telefragged by %k.,OB_MPTELEFRAG,,,,%o byl@[ao_cs] telefraggnut %kem.,%o blev telefragged af %k.,%o stand %k im Wege.,@[art_gr] %o κοματιάστηκε μέσω τηλεμεταφοράς απο τον/την %k,%o estis teleportumita de %k.,%o ha sido telefragmentad@[ao_esp] por %k.,%o fue telefragmentad@[ao_esp] por %k.,%k telefräggäsi %o paran.,%o a été téléfragué@[e_fr] par %k.,%o telefrag-et kapott %k által.,%o è stato telefraggato da %k.,%o は %k にテレフラグされた。,%o 은(는) %k 에 의해 텔레프랙을 당했다.,%o werd getelefragged door %k.,%o ble telefragget av %k.,%o został@[ao_pl] ztelefragowan@[adj_pl] przez %k.,%o foi telefragad@[ao_ptb] por %k.,,%o a fost omorât prin teleportare de către %k.,Игрок %o стал жертвой телепортации игрока %k.,%o је телефрагован@[adj_1_sr] од стране %k.,"%o, %k tarafından telefrag edildi." -%o was telefragged.,OB_MONTELEFRAG,,,,%o byl@[ao_cs] telefraggnut@[ao_cs].,%o blev telefragged.,%o stand jemandem im Wege.,@[art_gr] %o κοματιάστηκε μέσω τηλεμεταφοράς,%o estis teleportumita.,%o ha sido telefragmentad@[ao_esp].,%o fue telefragmentad@[ao_esp].,%o telefrägättiin.,%o a été téléfragué@[e_fr].,%o telefraggelve lett.,%o si è fatto telefraggare.,%o はテレフラグされた。,%o 은(는) 텔레프랙을 당했다.,%o werd getelefragged.,%o ble telefragget.,%o został@[ao_pl] ztelefragowan@[adj_pl].,%o foi telefragad@[ao_ptb] por um monstro.,,%o a fost omorât prin teleportare.,Игрок %o стал жертвой телепортации.,%o је телефрагован@[adj_1_sr].,%o telefragged edildi. +",Мењам ниво...,Ändrad nivå ...,Seviye Değiştirme... +Buddha mode ON,TXT_BUDDHAON,,,,Buddha mód ZAP,Buddha-tilstand TIL,Buddhamodus AN,Λειτουργία Βουδα ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Budha reĝimo ŜALTITA,Modo Buda ACTIVADO,,Buddhatila PÄÄLLÄ,Mode Bouddha ON,Buddha Mód BE,Modalità Buddha ATTIVATA,ブッダモード: オン,부처 모드 켬,Boeddha-modus AAN,Buddha-modus PÅ,Tryb Buddy WŁĄCZONY,Modo Buda ATIVADO,,Modul Buddha ACTIVAT,Режим Будды ВКЛЮЧЁН,Буда Мод УКЉУЧЕН,Buddha-läge på,Buda modu AÇIK +Buddha mode OFF,TXT_BUDDHAOFF,,,,Buddha mód VYP,Buddha-tilstand FRA,Buddhamodus AUS,Λειτουργία Βουδα ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Budha reĝimo MALŜALTITA,Modo Buda DESACTIVADO,,Buddhatila POIS PÄÄLTÄ,Mode Bouddha OFF,Buddha Mód KI,Modalità Buddha DISATTIVATA,ブッダモード: オフ,부처 모드 끔,Boeddha-modus UIT,Buddha-modus AV,Tryb Buddy WYŁĄCZONY,Modo Buda DESATIVADO,,Modul Buddha DEZACTIVAT,Режим Будды ОТКЛЮЧЁН,Буда Мод ИСКЉУЧЕН,Buddha-läge avstängt,Buda modu KAPALI +Ultimate Buddha Mode ON,TXT_BUDDHA2ON,,,,Super Buddha mód ZAP,Ultimate Buddha-tilstand TIL,Ultimativer Buddhamodus AN,Λειτουργία Απόλητου Βουδα ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Pleja Budha Reĝimo ŜALTITA,Modo Buda Supremo ACTIVADO,,Korkein buddhatila PÄÄLLÄ,Mode Bouddha Ultime ON,Tökéletes Buddha Mód BE,Modalità Ultimo Buddha ATTIVATA,究極ブッダモード: オン,나무 아미타불 모드 켬,Ultieme Boeddha-modus AAN,Ultimativ Buddha-modus PÅ,Maksymalny Tryb Buddy WŁĄCZONY,Modo Buda supremo ATIVADO,,Modul Buddha Suprem ACTIVAT,Окончательный режим Будды ВКЛЮЧЁН,Ултимативни Буда Мод УКЉУЧЕН,Ultimat Buddha-läge på,Nihai Buda Modu AÇIK +Ultimate Buddha Mode OFF,TXT_BUDDHA2OFF,,,,Super Buddha mód VYP,Ultimate Buddha-tilstand FRA,Ultimativer Buddhamodus AUS,Λειτουργία Απόλητου Βουδα ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Pleja Budha Reĝimo MALŜALTITA,Modo Buda Supremo DESACTIVADO,,Korkein buddhatila POIS PÄÄLTÄ,Mode Bouddha Ultime OFF,Tökéletes Buddha Mód KI,Modalità Ultimo Buddha DISATTIVATA,究極ブッダモード: オフ,나무 아미타불 모드 끔,Ultieme Boeddha-modus UIT,Ultimativ Buddha-modus AV,Maksymalny Tryb Buddy WYŁĄCZONY,Modo Buda supremo DESATIVADO,,Modul Buddha Suprem DEZACTIVAT,Окончательный режим Будды ОТКЛЮЧЁН,Ултимативни Буда Мод ИСКЉУЧЕН,Ultimat Buddha-läge av,Nihai Buda Modu KAPALI +Power on,TXT_CHEATPOWERON,,,,Energie ZAP,Evne TIL,Fähigkeit AN,Δύναμη ενεργοποιημένη,Povo ŝaltita,Poder activado,,Voima päällä,Pouvoir Activée,Energia BE,Potere ATTIVATO,パワー オン,파워 켬,Vermogen aan,Strøm PÅ,Zasilanie włączone,Poder ativado,,Putere activată,Сила активирована,Моћ УКЉУЧЕНА,Makt på,Güç açık +Power off,TXT_CHEATPOWEROFF,,,,Energie VYP,Evne FRA,Fähigkeit AUS,Δύναμη άπενεργοποιημένη,Povo malŝaltita,Poder desactivado,,Voima pois päältä,Pouvoir Désactivée,Energia KI,Potere DISATTIVATO,パワー オフ,파워 끔,Vermogen uit,Slå AV,Zasilanie wyłączone,Poder desativado,,Putere dezactivată,Сила деактивирована,Моћ ИСКЉУЧЕНА,Makt av,Güç kapalı +Full health,TXT_CHEATHEALTH,,,,Plné zdraví,Fuldt helbred,Volle Lebensenergie,Ολόκληρη υγεία,Plena sano,Salud al máximo,,Täysi terveys,Pleine Santé,Teljes életerő,Piena salute,ヘルス全回復,체력 완전 회복,Volledige gezondheid,Full helse,Pełne zdrowie,Saúde completa,Vida totalmente cheia,Sănătate completă,Полное здоровье,Здравље напуњено,Full hälsa,Tam sağlık +All keys,TXT_CHEATKEYS,,,,Všechny klíče,Alle taster,Alle Schlüssel,Όλα τα κλειδία,Ĉiuj ŝlosiloj,Todas las llaves,,Kaikki avaimet,Toutes les Clés,Összes kulcs,Tutte le chiavi,キー全部,모든 열쇠,Alle sleutels,Alle taster,Wszystkie klucze,Todas as chaves,,Toate cheile,Все ключи,Сви кључеви,Alla tangenter,Tüm anahtarlar +Sound debug on,TXT_CHEATSOUNDON,,,,Debug zvuku ZAP,Sound debug TIL,Sound Debug AN,Debug ήχου ενεργοποιημένη,Sono-sencimiga reĝimo ŝaltita,Depuración de sonido activada,,Äänen vianmääritystila päällä,Débogage du son activé.,Hang debug BE,Debug del suono attivato,サウンドデバッグ オン,효과음 디버그 켬,Geluid debug aan,Lyd feilsøking PÅ,Debugowanie dźwięku włączone,Depuração de som ativada,,Debug sunet activat,Отладка звука включена,Дебаговање звука УКЉУЧЕНО,Ljud felsökning på,Ses hata ayıklama açık +Sound debug off,TXT_CHEATSOUNDOFF,,,,Debug zvuku VYP,Sound debug FRA,Sound Debug AUS,Debug ήχου άπενεργοποιημένη,Sono-sencimiga reĝimo malŝaltita,Depuración de sonido desactivada,,Äänen vianmääritystila pois päältä,Débogage du son désactivé.,Hang debug KI,Debug del suono disattivato,サウンドデバッグ オフ,효과음 디버그 끔,Geluid debug uit,Lyd feilsøking AV,Debugowanie dźwięku wyłączone,Depuração de som desativada,,Debug sunet dezactivat,Отладка звука отключена,Дебаговање звука ИСКЉУЧЕНО,Ljud felsökning av,Ses hata ayıklama kapalı +"Trying to cheat, eh? Now you die!",TXT_CHEATIDDQD,,,,"Pokoušíš se cheatovat, co? Teď zemřeš!","Prøver du at snyde, hva'? Nu dør du!","Versuchst zu betrügen, was? Nun stirbst du!","Προσπαθείς να εξαπατήσεις, ε? Τώρα πεθένεις!","Provas trompi, ĉu vi? Nun vi mortas! ","¿Tratando de hacer trampas, eh? ¡Muere!",,"Yrität huijata, vai? Nyt kuolet!","Tu essaie de tricher, hein? Maintenant tu meurs!","Csalni akarsz, mi? Most meghalsz!","Cerchi di barare, eh? Allora muori!",その名を唱えたな? 褒美に死をやろう!,치트 쓸려고? 그럼 죽어야지!,"Je wou valsspelen, hè? Nu ga je dood!",Prøver du å jukse? Nå dør du!,"Próbujesz oszukiwać, co? Teraz giń!","Tentando trapacear, né? Morra!","A fazer batota, é? Morre!","Încerci să trișezi, ei? Acum mori!","Жульничаешь, э? Так умри!","Покушаваш да вараш, ех? Сада умиреш!",Försöker du fuska? Nu dör du!,"Hile yapmaya çalışıyorsun, ha? Şimdi öleceksin!" +Cheater - you don't deserve weapons,TXT_CHEATIDKFA,,,,Podvodníku - nezasloužíš si zbraně,Snyder - du fortjener ikke våben,Betrüger - du verdienst keine Waffen,Απατεόνα δέν σου αξήζουν όπλα,Trompanto - vi ne meritas armilojn,Trampos@[ao_esp] - No mereces tener armas,,Huijari - et ansaitse aseita,Tricheur- Tu ne mérite pas d'armes!,Csaló - nem érdemelsz fegyvert!,Imbroglione - non meriti armi,不届き者め、貴様が偉業を成すはずがない,사기꾼놈! 너는 무기를 가질 자격이 없어!,Valsspeler - je verdient geen wapens.,Juksemaker - du fortjener ikke våpen,Oszust - nie zasługujesz na bronie,Trapaceiros não merecem armas,Batoteir@[ao_ptb] - Não mereces armamento,Trișor - Nu meriți arme,Жулик — ты не заслуживаешь оружия,Варалице - ти не заслужујеш оружје,Fuskare - du förtjänar inte vapen.,"Hileci, silahları hak etmiyorsun." +Ticker on,TXT_CHEATTICKERON,,,,Počítadlo ZAP,Ticker TIL,Zähler AN,Χρονόμετρο ενεργοποιημένο,Nombrilo ŝaltita,Contador activado,,Laskuri päällä,Compteur allumé,Számláló BE,Ticker attivato,ティッカー オン,프레임 속도 표시 켬,Ticker aan,Ticker PÅ,Wskaźnik włączony,Contador ativado,,Ticăitoare activată,Счётчик включён,Бројач укључен,Ticker på,Ticker açık +Ticker off,TXT_CHEATTICKEROFF,,,,Počítadlo VYP,Ticker FRA,Zähler AUS,Χρονόμετρο άπενεργοποιημένο,Nombrilo malŝaltita,Contador desactivado,,Laskuri pois päältä,Compteur éteint,Számláló KI,Ticker disattivato,ティッカー オフ,프레임 속도 표시 끔,Ticker uit,Ticker AV,Wskaźnik wyłączony,Contador desativado,,Ticăitoare dezactivată,Счётчик отключён,Бројач искључен,Ticker av,Ticker kapalı +You got it,TXT_CHEATARTIFACTS3,,,,Máš to mít,Du fik det,Du hast es,Το πήρες,Vi akiris ĝin,Lo tienes,,Saamasi pitää,C'est à vous!,Megkaptad,Concesso,それを渡そう。,얻었다,Je hebt het,Du har det,Udało ci się,Concedido,,Ai ce-ți trebuie,Вы получили это,Уреду,Du fick det,Tamamdır. +"You got the Midas Touch, baby",TXT_MIDASTOUCH,,,,"Máš Midasův dotek, zlato","Du har Midas Touch, baby",Dagobert Duck lässt grüßen!,"Έχεις το αγγιγμα το Μίδα, μωρό.","Vi akiris la Tuŝon de Midas, kara","Tienes el toque de Midas, muchach@[ao_esp]",,"Kulta, sinulla on Midaksen kosketus",,"Minden arannyá válik amit megérintesz, öreg","Hai avuto il Tocco di Mida, baby",ミダス王の様だな、ベイビー,넌 미다스의 손을 얻었어 베이베!,"Je hebt de Midas Touch, schatje","Du har Midas Touch, baby","Zdobył@[irreg_3_pl] dotyk Midasa, skarbie","Você tem o Toque de Midas, baby","Tens o Toque de Midas, baby","Ai Atingerea lui Midas, dragule","Ты превращаешь всё в золото, детка!","Имаш златке руке, душо","Du har Midas Touch, baby","Sende Midas Dokunuşu var, bebeğim" +You got the stuff!,TXT_GOTSTUFF,,,,Dostal jsi věci!,Du har det hele!,Du hast den Kram erhalten,Πήρες τηατ πράγματα !,Vi akiris la aĵojn!,¡Tienes un montón de cosas!,¡Tienes muchas cosas!,Sait kamppeet!,Voilà ton équipement!,Megkaptad a cuccot!,Hai avuto il materiale!,スタッフを手に入れた!,무언가를 얻었다!,Je hebt het spul!,Du har greiene!,Zdobył@[irreg_3_pl] parę rzeczy!,Você ganhou muitas coisas!,ganhaste muitas coisas!,Ai tot ce-ți trebuie!,Получены предметы!,Покупили сте ствари!,Du har grejerna!,Mal sende! +Freeze mode on,TXT_FREEZEON,,,,Režim zamrznutí ZAP,Frysetilstand TIL,Gefriermodus AN,Παγομένη λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Movhalta reĝimo ŝaltita,Modo suspendido activado,,Jäädytystila päällä,Temps arrêté.,Fagyasztás BE,Modalità arresto del tempo attivata,フリーズモード オン,시간정지 켬,Bevriesmodus aan,Frysemodus PÅ,Tryb zamrożenia włączony,Modo congelado ativado,,Modul înghețat activat,Режим заморозки включён,Мод замрзавања УКЉУЧЕН,Frysningsläge på,Dondurma modu açık +Freeze mode off,TXT_FREEZEOFF,,,,Režim zamrznutí VYP,Frysetilstand FRA,Gefriermodus AUS,Παγομένη λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Movhalta reĝimo malŝaltita,Modo suspendido desactivado,,Jäädytystila pois päältä,Le temps reprend son cours..,Fagyasztás KI,Modalità arresto del tempo disattivata,フリーズモード オフ,시간정지 끔,Bevriesmodus uit,Frysemodus AV,Tryb zamrożenia wyłączony,Modo congelado desativado,,Modul înghețat dezactivat,Режим заморозки отключён,Мод замрзавања ИСКЉУЧЕН,Frysningsläge av,Dondurma modu kapalı +You feel strange...,TXT_STRANGE,,,,Cítíš se divně...,Du føler dig mærkelig...,Du fühlst dich merkwürdig...,Νιώθης περίεργα...,Vi sentas vin strange...,Te sientes extrañ@[ao_esp]...,,Sinulla on kummallinen olo...,Vous vous sentez mal à l'aise...,Furán érzed magad...,Ti senti strano...,これは奇妙な感じだな...,뭔가 이상한 기분이...,Je voelt je vreemd...,Du føler deg rar...,Dziwnie się czujesz...,Você está com uma sensação estranha...,Tu sentes-te estranh@[ao_ptb].,Te simți ciudat...,Вы чувствуете себя странно...,Осећате се чудно...,Du känner dig konstig...,Garip hissediyorsun. +You feel even stranger.,TXT_STRANGER,,,,Cítíš se ještě divněji...,Du føler dig endnu mere mærkelig.,Du fühlst dich noch merkwürdiger,Νιώθης ακόμα πιό περίεργα...,Vi sentas vin eĉ pli strange.,Te sientes aún más extrañ@[ao_esp],,Olosi on vieläkin kummempi.,Vous vous sentez très mal à l'aise...,Még furábban érzed magad.,Ti senti ancora più strano.,これはかなり奇妙だ。,기분이 더더욱 이상해졌다.,Je voelt je nog vreemder.,Du føler deg enda merkeligere.,Czujesz się jeszcze dziwniej.,Você está com uma sensação mais estranha ainda.,Tu sentes-te ainda mais estranh@[ao_ptb].,Te simți și mai ciudat.,Вы чувствуете себя очень странно.,Осећате се врло чудно.,Du känner dig ännu konstigare.,Daha da garip hissediyorsun. +You feel like yourself again.,TXT_NOTSTRANGE,,,,Cítíš se opět jako ty.,Du føler dig som dig selv igen.,Du fühlst dich wieder wie du selbst,Νιώθης σάν τον εαύτο σου ξανά...,Vi denove sentas vin kiel vi mem.,Te sientes como tu mism@[ao_esp] otra vez.,,Tunnet olevasi jälleen oma itsesi.,Vous vous sentez mieux.,Magadhoz tértél.,Ti senti di nuovo te stesso.,自分自身の様に感じている。,자기 자신처럼 생각하게 됐다.,Je voelt je weer als jezelf.,Du føler deg som deg selv igjen.,Znów czujesz się sobą.,Você se sente normal novamente.,Tu sentes-te normal novamente.,Ți-ai revenit în simțiri.,Вы снова чувствуете себя собой.,Поново се осећате као ви.,Du känner dig som dig själv igen.,Tekrar kendin gibi hissediyorsun. +Lead boots on,TXT_LEADBOOTSON,,,,Olověné boty ZAP,Blystøvler TIL,Bleistiefel AN,Μολυβδένιες μπότες ΕΝΕΡΓΟΠΟΙΗΜΈΝΕΣ,Botoj el plumbo ŝaltita,Botas de plomo activadas,,Lyijysaappaat päällä,Bottes en plomb ON,Ólomcsizma BE,Stivali di Piombo ON,足枷 オン,납 부츠 켬,Loden laarzen aan,Blystøvler PÅ,Ołowiane buty włączone,Botas de chumbo ativadas,,Bocanci de plumb activați,Свинцовые сапоги надеты,Оловне чизме УКЉУЧЕНЕ,Blystövlar på,Kurşun çizmeler +Lead boots off,TXT_LEADBOOTSOFF,,,,Olověné boty VYP,Blystøvler FRA,Bleistiefel AUS,Μολυβδένιες μπότες ΆΠΕΝΕΡΓΟΠΟΙΗΜΕΝΕΣ,Botoj el plumbo malŝaltita,Botas de plomo desactivadas,,Lyijysaappaat pois päältä,Bottes en plomb OFF,Ólomcsizma KI,Stivali di Piombo OFF,足枷 オフ,납 부츠 끔,Loden laarzen uit,Blystøvler AV,Ołowiane buty wyłączone,Botas de chumbo desativadas,,Bocanci de plumb dezactivați,Свинцовые сапоги сняты,Оловне чизме ИСКЉУЧЕНЕ,Blykängor av,Kurşun çizmeler kapalı +You feel lighter,TXT_LIGHTER,,,,Cítíš se lehčí,Du føler dig lettere,Du fühlst dich leichter,Νιώθης πιο ελαφρής,Vi sentas vin pli malpeze,Te sientes más liger@[ao_esp],,Tunnet olosi kevyemmäksi,Vous vous sentez très léger.,Könnyűnek érzed magad,Ti senti più leggero,体が軽くなった,가벼운 느낌이 든다,Je voelt je lichter,Du føler deg lettere,Czujesz się lżejsz@[adj_pl],Você se sente mais leve,Tu sentes-te mais leve,Te simți mai ușor,Вы чувствуете лёгкость.,Осећате лакоћу.,Du känner dig lättare.,Daha hafif hissediyorsun +Gravity weighs you down,TXT_GRAVITY,,,,Gravitace tě táhne dolů,Tyngdekraften tynger dig ned,Schwerkraft belastet dich,Η βαρύτητα σε πιάνει.,Gravito pezigas vin,La gravedad te hace descender,,Painovoima painaa sinua alas,La gravité vous ramène au sol.,A gravitáció lehúz téged,La gravità ti riporta a terra,重力に従った,중력이 당신을 붙잡았다,Zwaartekracht werkt op je...,Tyngdekraften tynger deg ned,Grawitacja znów cię przyciąga,A gravidade volta a funcionar normalmente,A gravidade voltou ao normal,Gravitația te trage în jos,Гравитация тянет вас вниз.,Гравитација Вас вуче надоле.,Tyngdkraften tynger ner dig,Yerçekimi seni ağırlaştırır +No Target ON,TXT_NOTARGET_ON,,,,Neútočící příšery ZAP,Ingen mål TIL,notarget AN,Αστόχευτη λειτουργία ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Neniu Celo ŜALTITA,No Objetivo ACTIVADO,,Hyökkäämättömyystila PÄÄLLÄ,Monstres aveugles et sourds ON,Nem támadnak a szörnyek BE,Modalità Mostri ciechi e sordi ATTIVATA,ノーターゲット オン,적 표적 감지 켬,Geen doelwit AAN,No Target PÅ,Głuche i Ślepe Potwory WŁĄCZONE,Sem alvos ATIVADO,,Modul Inamici fără Țintă ACTIVAT,Незаметность ВКЛЮЧЕНА,Нема мете УКЉУЧЕНО,Inget mål på,Hedef Yok AÇIK +No Target OFF,TXT_NOTARGET_OFF,,,,Neútočící příšery VYP,Ingen mål FRA,notarget AUS,Αστόχευτη λειτουργία ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Neniu Celo MALŜALTITA,No Objetivo DESACTIVADO,,Hyökkäämättömyystila POIS PÄÄLTÄ,Monstres aveugles et sourds OFF,Nem támadnak a szörnyek KI,Modalità Mostri ciechi e sordi DISATTIVATA,ノーターゲット オフ,적 표적 감지 끔,Geen doelwit UIT,No Target AV,Głuche i Ślepe Potwory WYŁĄCZONE,Sem alvos DESATIVADO,,Modul Inamici fără Țintă DEZACTIVAT,Незаметность ОТКЛЮЧЕНА,Нема мете ИСКЉУЧЕНО,Inget mål av,Hedef Yok KAPALI +"""Quake with fear!""",TXT_ANUBIS_ON,,,,„Třeste se strachy!“,"""Skælv af frygt!""","""Bebe vor Angst!""","""Τρέμε με φόβο!""","""Tremu pro timo!""","""¡Temblad de miedo!""","""Estremecete de Miedo!""","""Vapise pelosta!""",« Tremblez de terreur! »,"""Reszkess, halandó!""","""Trema con terrore!""",恐れおののけ!,공포에 떨어라!,„Beving van angst!“,Skjelv av frykt!,"""Trzęś się ze strachu""","""Trema de medo!""","""Trema com medo!""","""Tremură de Frică!""",«Дрожите от страха!»,„Дрхтите у страху!“,Skräck skakar av rädsla!,Korkudan titre! +No more Ogre Armor,TXT_ANUBIS_OFF,,,,Už žádné zlobří brnění,Ikke mere troldepanser,Keine Ogerrüstung mehr,Καθόλου δρακοντική πανοπλία πια,Ne plu Ogrokiraso,No más armadura de Ogro,,Ei enää örkkipanssaria,Plus d'armure d'ogre,Ogre pajzs lejárt,Niente più armatura Ogre,オーガアーマーはもう嫌,오거 갑옷은 이제 없다.,Geen Ogre Pantser meer,Ikke mer Ogre Armor,Nigdy więcej Pancerza Ogrów,Chega de Armadura de Ogro,Chega de Armadura de Ogre,Gata cu Armura de Căpcăun,Броня огра снята,Нема више бауков оклоп,Inget mer träsktorns rustning,Artık Ogre Zırhı yok +chasecam ON,TXT_CHASECAM_ON,,,,Pohled z třetí osoby ZAP,chasecam TIL,chasecam AN,Κάμερα τρίτου πρωσώπου ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Ĉaskamerao ŜALTITA,Cámara de seguimiento ACTIVADA,,Seurantakamera PÄÄLLÄ,,követő kamera BE,Modalità camera da inseguimento ATTIVATA,チェイスカメラ オン,3인칭 카메라 켬,Chasecam AAN,chasecam PÅ,kamera śledzenia WŁĄCZONA,Câmera em terceira pessoa ATIVADA,Câmara em Terceira Pessoa ATIVADA,Perspectivă la Persoana a 3-a ACTIVATĂ,Вид от третьего лица ВКЛЮЧЁН,Чејс-кам УКЉУЧЕН,chasecam på,Chasecam AÇIK +chasecam OFF,TXT_CHASECAM_OFF,,,,Pohled z třetí osoby VYP,chasecam FRA,chasecam AUS,Κάμερα τρίτου πρωσώπου ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Ĉaskamerao MALŜALTITA,Cámara de seguimiento DESACTIVADA,,Seurantakamera POIS PÄÄLTÄ,,követő kamera KI,Modalità camera da inseguimento DISATTIVATA,チェイスカメラ オフ,3인칭 카메라 끔,Chasecam UIT,chasecam AV,kamera śledzenia WYŁĄCZONA,Câmera em terceira pessoa DESATIVADA,Câmara em Terceira Pessoa DESATIVADA,Perspectivă la Persoana a 3-a DEZACTIVATĂ,Вид от третьего лица ОТКЛЮЧЁН,Чејс-кам ИСКЉУЧЕН,chasecam av,Chasecam KAPALI +1 baddie killed,TXT_BADDIE_KILLED,,,,1 zloun zabit,1 baddie dræbt,1 Bösewicht getötet,Ενας κακός πέθανε,1 malbonulo mortigita,1 malo matado,,1 pahis tapettu,1 enemi tué,1 rosszfiú kinyírva,Ucciso 1 maligno,1 体 殺した,1 명의 나쁜놈이 사살됨.,1 slechterik gedood,1 skurk drept,1 zabity przeciwnik,1 inimigo morto,,1 slab ucis,1 плохиш убит,Један зликовац убијен,1 skurk dödad,1 kötü öldürüldü +%d baddies killed,TXT_BADDIES_KILLED,,,,%d zlounů zabito,%d baddies dræbt,%d Bösewichte getötet,%d τον κακόν πέθαναν,%d malbonuloj mortigitaj,%d malos matados,,%d pahista tapettu,%d enemis tués,%d rosszfiú kinyírva,Uccisi %d maligni,%d 体 殺した,%d 명의 나쁜놈들이 사살됨.,%d slechteriken gedood,%d skurker drept,%d zabitych przeciwników,%d inimigos mortos,,%d slabi uciși,Плохишей убито: %d,%d зликовца убијено,%d skurkar dödade,%d kötüler öldürüldü +1 monster killed,TXT_MONSTER_KILLED,,,,1 příšera zabita,1 monster dræbt,1 Monster getötet,Ένα τέρας πέθανε,1 monstro mortigita,1 monstruo matado,,1 hirviö tapettu,1 monstre tué,1 szörny kinyírva,Ucciso 1 mostro,1 匹 殺した,1 마리의 몬스터가 사살됨.,1 monster gedood,1 monster drept,1 zabity potwór,1 monstro morto,,1 monstru ucis,1 монстр убит,Једно чудовиште убијено,1 monster dödat,1 canavar öldürüldü +%d monsters killed,TXT_MONSTERS_KILLED,,,,%d příšer zabito,%d monster dræbt,%d Monster getötet,%d τον τεράτων πέθαναν,%d monstroj mortigitaj,%d monstruos matados,,%d hirviötä tapettu,%d monstres tués,%d szörny kinyírva,Uccisi %d mostri,%d 匹 殺した,%d 마리의 몬스터들이 사살됨.,%d monsters gedood,%d monstre drept,%d zabitych potworów,%d monstros mortos,,%d monștri uciși,Убито монстров: %d,%d чудовишта убијено,%d monster dödade,öldürülen %d canavar +Unable to resurrect. Player is no longer connected to its body.,TXT_NO_RESURRECT,,,,"Oživení není možno, hráč už není spojen se svým tělem.",Kan ikke genoplive. Spilleren er ikke længere forbundet med sin krop.,Kann nicht wiederbeleben. Der Spieler ist nicht mehr mit seinem Körper verbunden.,"Ανάσταση αδύνατη, ο παίχτης δεν είναι πια στο σώμα @[pro4_gr]","Nerevivigebla. La ludanto ne plu +estas konektita al sia korpo.",Imposible de resucitar. El jugador ya no está conectado a su cuerpo.,,Ei mahdollista herätä henkiin. Pelaaja ei ole enää yhteydessä ruumiiseensa.,Impossible de ressuciter. Le joueur n'est plus connecté à son corps.,Nem sikerült a felélesztés. A játékos nincs összekötve a testtel.,Impossibile resuscitarsi. Il giocatore non è più connesso al suo corpo.,復活できない。プレイヤーはこの体に宿っていない。,부활할 수 없습니다. 플레이어는 더 이상 육체와 연결돼있지 않습니다.,Kan niet reanimeren. De speler is niet langer verbonden met zijn lichaam.,Kan ikke gjenoppstå. Spilleren er ikke lenger koblet til kroppen sin.,Nie można wskrzesić. Gracz nie jest już połączony z resztą swojego ciała.,"Impossível ressuscitar. O jogador não +está mais ligado ao próprio corpo.",,Imposibil de înviat. Jucătorul nu mai e conectat la cadavru.,Воскрешение невозможно. Игрок больше не соединён с трупом.,Немогуће оживети. Играч није више повезан са својим телом.,Det går inte att återuppliva. Spelaren är inte längre ansluten till sin kropp.,Diriltilemiyor. Oyuncu artık bedenine bağlı değil. +All Artifacts!,TXT_ALL_ARTIFACTS,,,All Artefacts!,Všechny artefakty!,Alle artefakter!,Alle Artefakte!,Όλα τα τεχνουργίματα!,Ĉiuj Artefaktoj!,¡Todos los Artefactos!,,Kaikki artefaktit!,Tous les artéfacts!,Összes értéktárgy!,Tutti gli Artefatti!,全アーティファクト!,모든 유물들!,Alle artefacten!,Alle artefakter!,Wszystkie Artefakty!,Todos os artefatos!,,Toate Artefactele!,Все артефакты!,Сви артифакти!,Alla artefakter!,Tüm eserler! +What do you want to kill outside of a game?,TXT_WHAT_KILL,,,,"Co chceš zabít, když nejsi ve hře?",Hvad vil du dræbe uden for et spil?,Was willst du eigentlich außerhalb eines Spiels töten?,Τί θέλεις να σκοτώσεις έξω απο ένα παιχνίδι ?,Kion vi volas mortigi ekster ludo?,¿Qué intentas matar fuera de una partida?,,Mitä haluat tappaa pelin ulkopuolella?,Que voulez-vous tuer en dehors d'une partie?,Mit tudnál megölni játékon kívül?,Cosa vorresti uccidere fuori dal gioco?,ゲーム外で何を殺す気だ?,게임 밖에서 무엇을 죽이고 싶습니까?,Wat wil je buiten een spel om doden?,Hva vil du drepe utenfor et spill?,Co ty chcesz zabić poza grą?,O que você gostaria de matar fora de um jogo?,,Ce vrei să ucizi în afara unui joc?,Что вы хотите убить вне игры?,Шта желите да убијете ван игре?,Vad vill du döda utanför ett spel?,Oyun dışında ne öldürmek istiyorsun? +Frozen player properties turned off,TXT_NOT_FROZEN,,,,Vlastnosti držící hráče na místě vypnuty,Frysningstilstand er slået fra.,Gefrier-Modus abgeschaltet.,Η ιδιότητες ενος παγομένου παίχτη απενεργοποίθηκαν,Atributoj de movhaltitaj ludantoj malŝaltitaj,Propiedades de jugador congelado desactivadas,,Jäätyneen pelaajan ominaisuudet kytketty pois päältä,Propriété gelée du joueur annulée.,Fagyasztott játékos tulajdonságai kikapcsolva,Proprietà del giocatore ghiacciato disattivate,凍ったプレイヤーのプロパティを無効化,플레이어 정지 속성이 꺼졌습니다.,Eigenschappen van de bevroren speler uitgeschakeld,Frosne spilleregenskaper slått av,Właściwości zamrożonego gracza wyłączone,Propriedades de jogador congelado desativadas,,Proprietăți jucători înghețați DEZACTIVATE,Свойства замороженного игрока отключены,Смрзнути играчи искључени,Frysta spelaregenskaper avstängda,Dondurulmuş oyuncu özellikleri kapatıldı +,,Automap,,,,,,,,,,,,,,,,,,,,,,,,, +Follow Mode OFF,AMSTR_FOLLOWOFF,,,,Režim sledování VYP,Følg-tilstand TIL,Folgen-Modus AUS,Ακολούθηση ΆΠΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Sekvigreĝimo MALŜALTITA,Modo de seguimiento DESACTIVADO,,Seuraamistila POIS PÄÄLTÄ,Suivi du Joueur OFF,Követés mód KI,Mappa scorribile ATTIVATA,追従モード: オフ,추적 모드 끔,Volgmodus UIT,Følgemodus AV,Tryb śledzenia WYŁĄCZONY,Modo de seguimento DESATIVADO,,Mod Urmărire DEZACTIVAT,Привязка к игроку ОТКЛЮЧЕНА,Праћење ИСКЉУЧЕНО,Följningsläget av,Takip Modu KAPALI +Follow Mode ON,AMSTR_FOLLOWON,,,,Režim sledování ZAP,Følg-tilstand FRA,Folgen-Modus AN,Ακολούθηση ΕΝΕΡΓΟΠΟΙΗΜΈΝΗ,Sekvigreĝimo ŜALTITA,Modo de seguimiento ACTIVADO,,Seuraamistila PÄÄLLÄ,Suivi du Joueur ON,Követés mód BE,Mappa scorribile DISATTIVATA,追従モード: オン,추적 모드 켬,Volgmodus AAN,Følgemodus PÅ,Tryb śledzenia WŁĄCZONY,Modo de seguimento ATIVADO,,Mod Urmărire ACTIVAT,Привязка к игроку ВКЛЮЧЕНА,Праћење УКЉУЧЕНО,Följningsläget på,Takip Modu AÇIK +Grid ON,AMSTR_GRIDON,,,,Mřížka ZAP,Raster TIL,Gitter AN,Πλέχμα ΕΝΕΡΓΟΠΟΙΜΈΝΟ,Krado ŜALTITA,Cuadrícula ACTIVADA,,Ruudukko PÄÄLLÄ,Quadrillage ON,Rács BE,Griglia ATTIVATA,グリッド: オン,격자 켬,Raster AAN,Rutenett PÅ,Siatka WŁĄCZONA,Grade ATIVADA,Grelha ATIVADA,Grilă ACTIVATĂ,Сетка ВКЛЮЧЕНА,Мрежа УКЉУЧЕНА,Rutnät på,Izgara AÇIK +Grid OFF,AMSTR_GRIDOFF,,,,Mrizka VYP,Raster FRA,Gitter AUS,Πλέχμα ΆΠΕΝΕΡΓΟΠΟΙΜΈΝΟ,Krado MALŜALTITA,Cuadrícula DESACTIVADA,,Ruudukko POIS PÄÄLTÄ,Quadrillage OFF,Rács KI,Griglia DISATTIVATA,グリッド: オフ,격자 끔,Raster UIT,Rutenett AV,Siatka WYŁĄCZONA,Grade DESATIVADA,Grelha DESATIVADA,Grilă DEZACTIVATĂ,Сетка ОТКЛЮЧЕНА,Мрежа ИСКЉУЧЕНА,Rutnät av,Izgara KAPALI +Texture Mode ON,AMSTR_TEXON,,,,Texturovaný režim ZAP,Teksturtilstand TIL,Texturmodus AN,Γραφικός χάρτης ΕΝΕΡΓΟΠΟΙΜΈΝΟΣ,Tekstura Reĝimo ŜALTITA,Modo de texturas ACTIVADO,,Pintakuviointitila PÄÄLLÄ,Mode Texturé ON,Textúrák mód BE,Modalità Texture ATTIVATA,テクスチャーモード: オン,텍스쳐 모드 켬,Textuurmodus AAN,Teksturmodus PÅ,Tekstury WŁĄCZONE,Modo de textura ATIVADO,,Mod Texturat ACTIVAT,Текстурный режим ВКЛЮЧЁН,Текстуре УКЉУЧЕНЕ,Texturläge på,Doku Modu AÇIK +Texture Mode OFF,AMSTR_TEXOFF,,,,Texturovaný režim VYP,Teksturtilstand FRA,Texturmodus AUS,Γραφικός χάρτης ΑΠΕΝΕΡΓΟΠΟΙΜΈΝΟΣ,Tekstura Reĝimo MALŜALTITA,Modo de texturas DESACTIVADO,,Pintakuviointitila POIS PÄÄLTÄ,Mode Texturé OFF,Textúrák mód KI,Modalità Texture DISATTIVATA,テクスチャーモード: オフ,텍스쳐 모드 끔,Textuurmodus UIT,Teksturmodus AV,Tekstury WYŁĄCZONE,Modo de textura DESATIVADO,,Mod Netexturat DEZACTIVAT,Текстурный режим ОТКЛЮЧЁН,Текстуре ИСКЉУЧЕНЕ,Texturläge av,Doku Modu KAPALI +Marked Spot,AMSTR_MARKEDSPOT,,,,Značka,Markeret placering,Punkt markiert,Μαρκαρησμένη τοποθεσεία,Loko Markita,Punto marcado,,Merkitty paikka,Repère marqué.,Megjelölt hely,Posizione segnata,目標をマークした,지점 추가,Gemarkeerde plek,Markert punkt,Oznaczono miejsce,Posição marcada,,Loc Marcat,Отметка,Означено место,Markerad punkt,İşaretli Nokta +All Marks Cleared,AMSTR_MARKSCLEARED,,,,Všechny značky smazány,Alle markeringer slettes,Alle Markierungen gelöscht,Όλες η μαρκαρησμένη τοποθεσείες είναι καθαρησμένες,Ĉiuj Markoj Forigitaj,Todas las marcas eliminadas,,Kaikki merkit pyyhitty,Repères éffacés.,Összes jelölés törölve,Cancellati tutti i segni,全目標を解除した,모든 지점 지워짐,Alle markingen gewist,Alle merker fjernet,Wszystkie miejsca wyczyszczone,Todas as marcas removidas,,Toate Marcările Șterse,Отметки очищены,Ознаке избрисане,Alla markeringar raderas,Tüm İşaretler Temizlendi +,,Multiplayer,,,,,,,,,,,,,,,,,,,,,,,,, +Fraglimit hit.,TXT_FRAGLIMIT,,,,Fraglimit dosáhnut.,Fraggrænse nået,Fraglimit erreicht,Το όριο κοματιασμόν έχει φτάσει.,Ludmurdo-limo trafita.,Límite de bajas alcanzado.,,Frägiraja saavutettu.,Limite de frags atteinte.,Fraghatár elérve.,Fraglimit raggiunto.,フラグリミット!,킬제한에 도달했습니다.,Fraglimiet bereikt.,Fraglimit treff.,Limit fragów wyczerpany.,Limite de frags atingido.,,Limita de ucideri atinsă.,Достигнут лимит фрагов.,Фраг-лимит достигнут.,Fragbegränsning träffad.,Frag limiti vuruldu. +Timelimit hit.,TXT_TIMELIMIT,,,,Časový limit dosáhnut.,Tidsgrænse nået,Zeitlimit erreicht,Το χρονικό όριο έχει φτάσει.,Tempolimo trafita.,Límite de tiempo alcanzado.,,Aikaraja saavutettu.,Limite de temps atteinte.,Időhatár elérve.,Timelimit raggiunto.,ゲームセット!,시간제한에 도달했습니다.,Tijdslimiet bereikt.,Tidsbegrensningen er nådd.,Limit czasowy wyczerpany.,Limite de tempo atingido.,,Limita de timp atinsă.,Достигнут лимит времени.,Временско ограничење достигнуто.,Tidsbegränsning träffad.,Zaman limiti vuruldu. +%o was looking good until %g killed %hself!,SPREEKILLSELF,,,,%o vypadal@[ao_cs] dobře dokud se @[self_cs] nezabil@[ao_cs]!,"%o så godt ud, indtil @[pro_dk] dræbte sig selv!","%o sah gut aus, bis das Unglück geschah.",@[art_gr] %o πήγενε μια χαρά μέχρι που αυτοκτόνησε!,"%o estis faranta bone, ĝis @[pro_eo] mortigis sin!",¡%o se veía bien hasta que %g se mató a si mism@[ao_esp]!,,"%o oli liekeissä, kunnes meni tappamaan itsensä!",%o était en pleine folie meurtrière avant qu' %g ne se bute!,%o jól nézett ki még mielőtt megölte magát!,%o stava andando bene finchè non si è ucciso da solo!,%o は自滅するまでなかなか良かったぞ!,%o 이(가) 잘 나가려던 참에 자살했습니다!,%o zag er goed uit tot %g zelfmoord pleegde!,%o så bra ut helt til %g tok livet av seg!,%o wyglądał dobrze dopóki się nie zabił@[ao_pl],%o estava indo bem até se matar!,,%o arăta atât de bine până să se sinucidă,"%o неплохо выглядел@[ao_rus], пока не покончил@[ao_rus] с собой!",%o је изгледа@[ao_1_sr] добро док није уби@[ao_1_sr] сам@[ao_3_sr] себе!,%o såg bra ut tills han tog livet av sig!,%o kendini öldürene kadar iyi görünüyordu! +%o's killing spree was ended by %k,SPREEOVER,,,,%o@[psn1_cs] vraždící řádění ukončil hráč %k.,%os drabstog blev afsluttet af %k,%os Amoklauf wurde von %k beendet.,Ο/Η %k σταμάτησε την ανθρωποκτονία %h %o.,La mortigado de %o estis finita de %k,%k acabó con la racha de muerte de %o,,%k päätti pelaajan %o tapposarjan,La folie meurtrière de %o à été terminée par %k!,%o ámokfutását %k megállította.,La sequela di frag di %o è stata terminata da %k,%k が %o の快進撃を断ち切った!,%k 이(가) %o 의 연속 킬을 처단했습니다,%o's moordpartij werd beëindigd door %k.,%o's drapsturné ble avsluttet av %k.,Seria zabójstw %o zakończona przez %k,A matança de %o foi interrompida por %k,,Pofta de ucis a lui %o a fost pusă în cui de către %k,Игрок %k прервал череду убийств игрока %o,Серијско убијање играча %o је завршио играч %k,%os dödskampanj avslutades av %k.,%o onu öldürene kadar %k iyi görünüyordu. +%k is on a killing spree!,SPREE5,,,,%k začal@[ao_cs] řádit!,%k er i gang med en mordserie!,%k läuft Amok!,Ο/Η %k άρχισε μια ανθρωποκτονία!,%k estas sur mortigado!,¡%k está atacando de lo lindo!,,%k on sarjamurhaaja!,%k est en folie meurtrière!,%o egy Ámokfutó!,%k è preda di un momento omicida!,%k が連続キル!,%k 연속 킬!,%k is op een moordpartij!,%k er på drapsturné!,%k popełnia serię morderstw!,%k está cometendo uma matança!,,%k are chef de ucis!,Игрок %k совершил череду убийств!,%k је серијални убица!,%k är på en mordresa!,%k bir ölüm çılgınlığında! +%k is on a rampage!,SPREE10,,,,%k zuří!,%k er på et amokløb!,%k tobt sich aus!,Ο/Η %k είναι σε ξέσπασμα!,%k estas sur furiozado!,¡%k está en medio de una aniquilación!,,%k riehuu valtoimenaan!,%k est en plein massacre!,%o Tombol!,%k sta facendo un massacro!,%k が大暴れだ!,%k 이(가) 미쳐 날뛰고 있습니다!,%k heeft razernij!,%k går amok!,%k doznaje szału!,%k está massacrando!,,%k e înverșunat!,Игрок %k в неистовстве!,%k дивља!,%k är på en våldsam resa!,%k kudurmuş durumda! +%k is dominating!,SPREE15,,,,%k dominuje!,%k er dominerende!,%k dominiert!,Ο/Η %k κατακτεί.,%k estas dominanta!,¡%k está dominando!,,%k hallitsee suvereenisti!,%k domine!,%o Uralkodik!,%k sta dominando tutti!,%k が圧倒している!,%k 이(가) 우세하고 있습니다!,%k domineert!,%k dominerer!,%k dominuje!,%k está dominando!,,%k domină!,Игрок %k господствует!,%k доминира!,%k dominerar!,%k hükmediyor! +%k is unstoppable!,SPREE20,,,,%k je nezastaviteln@[adj_cs]!,%k er ustoppelig!,%k kann nicht gestoppt werden!,Ο/Η %k είναι ασταμάτητος/η!,%k estas nehaltigebla!,¡%k es imparable!,,%k on pysäyttämätön!,%k est inarrétable!,%o Megállíthatatlan!,%k è inarrestabile!,%k が止まらない!,%k 을(를) 막을 수없습니다!,%k is niet te stoppen!,%k er ustoppelig!,%k jest niepowstrzymany!,%k é implacável!,,%k e de neoprit!,Игрок %k неостановим!,Играч %k је незаустављив!,%k är ostoppbar!,%k durdurulamaz! +%k is Godlike!,SPREE25,,,,%k je boží!,%k er som en gud!,%k ist wie Gott!,Ο/Η %k είναι σαν θεός/θεά!,%k estas Dia!,¡%k es una máquina de matar!,,%k on kuin jumala!,%k est un dieu!,%o Istencsászár!,%k è un dio!,%k が神の様だ!,%k 은(는) 신적입니다! ,%k is Goddelijk!,%k er guddommelig!,%k jest Bogem!,%k é um deus da matança!,,%k e precum un Zeu!,Игрок %k богоподобен!,Играч %k је божанствен!,%k är som en gud!,%k tanrı gibi! +Double kill!,MULTI2,,,,Dvoj-zabití!,Dobbelt drab!,Doppel-Kill!,Δυπλός Θάνατος!,Duobla mortigo!,¡Dos menos!,,Tuplatappo!,,Dupla gyilok!,Doppia uccisione!,ダブルキル!,더블 킬!,Dubbele kill!,Dobbeltdrap!,Podwójne zabójstwo!,Morte dupla!,,Dublă ucidere!,Двойное убийство!,Дупло убиство!,Dubbeldödning!,Çifte öldürme! +Multi kill!,MULTI3,,,,Multi-zabití!,Multi-drab!,Multi-Kill!,Πολυθάνατος!,Pluraj mortigoj!,¡Multidestrucción!,,Multitappo!,,Multi gyilok!,Tripla uccisione!,マルチキル!,멀티 킬!,,Multidrap!,Multi-zabójstwo!,Morte tripla!,,Ucidere multiplă!,Массовое убийство!,Вишеструко убиство!,Flera dödar!,Çoklu öldürme! +Ultra kill!,MULTI4,,,,Ultra-zabití!,Ultra-drab!,Ultra-Kill!,Υπερθάνατος!,Ekstremaj mortigoj!,¡¡HIPERDESTRUCCIÓN!!,,Ultratappo!,,Ultra gyilok!,Ultra uccisione!,ウルトラキル!,울트라 킬!,,Ultra drep!,Ultra-zabójstwo!,Ultra matança!,,Ultra ucidere!,Ультра-убийство!,Ултра убиство!,Ultra-död!,Ultra öldürme! +Monster kill!,MULTI5,,,,Monstr-zabití!,Monster-drab!,Monster-Kill!,Τερατόδες σκοτωμός!,Monstraj mortigoj!,¡¡¡S.U.P.E.R.D.E.S.T.R.U.C.C.I.Ó.N!!!,,Hirviömäinen tappo!,,Szörnyű gyilkolás!,Uccisione Mostruosa!,モンスターキル!,몬스터 킬!,,Monster drep!,Potworne zabójstwo!,Matança monstro!,Matança monstruosa!,Ucidere monstruoasă!,Чудовищное убийство!,Монструозно убиство!,Monsterdöd!,Canavar öldürme! +,,Scoreboard,,,,,,,,,,,,,,,,,,,,,,,,, +Bonus,SCORE_BONUS,,,,,,,,Bonuso,Bonificaciones,,Lisäedut,,Bónusz,,ボーナス,보너스,Bonus,,Bonusy,Bônus,,,Бонус,Бонус,, +Color,SCORE_COLOR,,,Colour,Barva,Farve,Farbe,Χρώμα,Koloro,,,Väri,Couleur,Szín,Colore ,色,색상,Kleur,Farge,Kolor,Cor,,Culoare,Цвет,Боја,Färg,Renk +Secret,SCORE_SECRET,,,,Skrýše,Hemmeligt,Geheimnis,Μυστικό,Sekreto,Secreto,,Salat,,Titok,Segreto,シークレット,밝혀낸 비밀,Geheim,Hemmelig,Sekret,Segredo,,,Тайники,Тајна,Hemlig,Sır +Name,SCORE_NAME,,,,Jméno,Navn,Name,Όνομα,Nomo,Nombre,,Nimi,Nom,Név,Nome,名前,이름,Naam,Navn,Nazwa,Nome,,Nume,Игрок,Име,Namn,İsim +Delay (ms),SCORE_DELAY,,,,Zpoždění (ms),Forsinkelse (ms),Verzögerung (ms),Kαθυστέρηση (μδ),Prokrasto (ms),Retraso (ms),,Viive (ms),Délai (ms),Késleltetés (ms),Ritardo (ms) ,ping,핑 (밀리초당),Vertraging (ms),Forsinkelse (ms),Opóźnienie (ms),Atraso (ms),,Întârziere (ms),Задержка (мс),Кашњење (мс),Fördröjning (ms),Gecikme (ms) +Frags,SCORE_FRAGS,,,,Fragy,,,Κοματιασμοί,Ludmurdoj,Bajas,,Frägit,,Frag-ek,,フラグ,플레이어 킬수,,,Fragi,,,Victime,Фраги,Фрагови,, +Deaths,SCORE_DEATHS,,,,Smrti,Dødsfald,Tode,Θάνατοι,Mortoj,Muertes,,Kuolemat,Morts,Halálok,Morti,デス,사망한 횟수,Sterfgevallen,Dødsfall,Śmierci,Mortes,,Decese,Смерти,Смрти,Dödsfall,Ölümler +Other,SCORE_OTHER,,,,Ostatní,Andre,Andere,,Alia,Demás,,Muu,Autre,Egyéb,Altro,その他,,Anders,Andre,Inne,Outro,,Altele,Прочее,,Andra,Diğer +Missed,SCORE_MISSED,,,,Minuto,Forpasset,Verfehlt,Ξεχάστηκαν,Mankita,Pérdidas,,Hudit,Ratés,Kihagyva,Mancati ,ミス,놓친 수,Gemist,Ubesvarte,Ominięte,Perdido,,Ratate,Пропущено,Пропуштено,Missade,Cevapsız +Total,SCORE_TOTAL,,,,Celkem,,Gesamt,Συνολικό,Tuto,,,Yhteensä,,Összesen,Totale,合計,총점,Totaal,Totalt,Totalne,,,,Всего,Укупно,Totalt,Toplam +Level Time,SCORE_LVLTIME,,,,Čas v levelu,Niveau Tid,Levelzeit,Χρόνος Πίστας,Daŭro de Nivelo,Tiempo de nivel,,Tasoaika,Temps niveau,Pályaidő,Tempo Livello ,時間,레벨 시간,Leveltijd,Nivå Tid,Czas,Tempo de fase,Tempo do Nível,Timp Petrecut,Время уровня,Време нивоа,Nivå Tid,Seviye Zaman +,,Level Summary,,,,,,,,,,,,,,,,,,,,,,,,, +Kills,TXT_IMKILLS,,,,Zabití,Dræber,,Σκοτομοί,Mortigoj,Muertes,,Tapot,Morts,Áldozatok,Uccisioni,キル,킬수,Dood,Drepte,Zabici,Vítimas,,Ucideri,Убийств,Непријатељи,Dödade,Öldürür +Items,TXT_IMITEMS,,,,Předměty,Genstande,Gegenstände,Αντεικείμενα,Objektoj,Objetos,,Esineet,Objets,Tárgyak,Oggetti,アイテム,획득한 아이템,,Gjenstander,Przedmioty,Itens,,Obiecte,Предметов,Ставке,Föremål,Eşyalar +Secrets,TXT_IMSECRETS,,,,Skrýše,Hemmeligheder,Geheimnisse,Μυστικά,Sekretoj,Secretos,,Salat,,Titkok,Segreti,シークレット,밝혀낸 비밀,Geheimen,Hemmeligheter,Sekrety,Segredos,,Secrete,Тайников,Тајне,Hemligheter,Sırlar +Time,TXT_IMTIME,,,,Čas,Tid,Zeit,Χρόνος,Daŭro,Tiempo,,Aika,Temps,Idő,Tempo,経過時間,소모한 시간,Tijd,Tid,Czas,Tempo,,Timp,Время,Време,Tid,Zaman +Par,TXT_IMPAR,,,,,,,Μέσος Όρος,Alparo,,,,,Átlag,Media,最速時間,기준 시간,,,,Média,,Record,Рекорд,Рекорд,, +Finished,WI_FINISHED,,,,Dokončeno,Færdig,Abgeschlossen,Ολοκληρώθηκε,Finita,Completado,,Suoritettu,Terminé,Teljesítve,Finito,攻略,완료,Klaar,Ferdig,Ukończono,Finalizado,,Terminat,Уровень завершён,Ниво завршен,Avslutad,Bitti +Entering,WI_ENTERING,,,,Vstupuješ do,Indtastning af,Betrete,Είσοδος,Enirante,Entrando a:,,Seuraava kohde,Niveau Suivant,Következik,Prossimo livello,突入開始,입장,Volgende,Går inn,Wchodzisz do:,Próxima fase,Próximo nível,Începe,Переход,Следећи ниво,Ingång till,Giriş +Now entering:,WI_ENTERING,,heretic hexen,,Nyní vstupuješ do:,Indtastning af:,Betrete:,Τώρα εισέρχεσε στο:,Nun enirante:,Ahora entrando a:,,Seuraava kohde:,Vous entrez dans:,Következik:,Entrando adesso in:,突入中:,입장합니다:,Volgende:,Går nå inn:,Teraz wchodzisz do:,Entrando em:,A entrar em:,Acum începe:,Переход на:,Следећи ниво:,Ingång till,Şimdi giriyoruz: +,,HUD,,,,,,,,,,,,,,,,,,,,,,,,, +Monsters:,AM_MONSTERS,,,,Příšery:,Monstre:,Monster:,Τέρατα,Monstroj:,Monstruos:,,Hirviöt:,Monstres:,Szörnyek:,Mostri,奴等:,죽인 적들:,,Monstre:,Potwory:,Monstros:,,Monștri:,Монстры:,Чудовишта:,Monster:,Canavarlar: +Secrets:,AM_SECRETS,,,,Skrýše:,Hemmeligheder:,Geheimnisse:,Μυστικά,Sekretoj:,Secretos:,,Salat:,,Titkos helyek:,Segreti,隠場:,찾은 비밀:,Geheimen:,Hemmeligheter:,Sekrety:,Segredos:,,Secrete:,Тайники:,Тајне:,Hemligheter:,Sırlar: +Items:,AM_ITEMS,,,,Věci:,Genstande:,Gegenstände:,Αντεικείμενα,Objektoj:,Objetos:,,Esineet:,Objets:,Tárgyak:,Oggetti,物資:,얻은 아이템:,,Gjenstander:,Przedmioty:,Itens:,,Obiecte:,Предметы:,Предмети:,Föremål:,Eşyalar: +,,Obituaries,,,,,,,,,,,,,,,,,,,,,,,,, +%o suicides.,OB_SUICIDE,,,,%o spáchal@[ao_cs] sebevraždu.,%o begår selvmord.,%o begeht Selbstmord.,@[art_gr] %o αυτοκτόνησε,%o sinmortigis.,%o se ha suicidado.,%o se suicidó.,%o teki itsemurhan.,%o se suicide.,%o öngyilkos lett.,%o si è suicidato.,%o は自殺した。,%o 은(는) 자살했다.,%o pleegt zelfmoord.,%o begår selvmord.,%o popełnił@[ao_pl] samobójstwo.,%o se suicidou.,,%o se sinucide.,Игрок %o покончил с собой.,%o самоубиства.,%o tar självmord.,%o intihar eder. +%o fell too far.,OB_FALLING,,,,%o spadl@[ao_cs] příliš daleko.,%o faldt for langt ned.,%o fiel zu tief.,@[art_gr] %o έπεσε,%o falis tro fore.,%o se ha caído desde muy alto.,%o se cayó desde muy alto.,%o putosi liian kaukaa.,%o est tombé@[e_fr] trop loin.,%o túl messze esett.,%o è caduto troppo in basso.,%o はあまりにも高い所から転落した。,%o 은(는) 높은 곳에서 떨어져 사망했다.,%o viel te ver.,%o falt for langt.,%o spadł@[ao_pl] za daleko.,%o caiu de um lugar alto.,,%o a căzut prea departe.,Игрок %o упал слишком далеко.,%o је па@[ao_1_sr] до сад.,%o föll för långt.,%o çok uzağa düştü. +%o was squished.,OB_CRUSH,,,,%o byl@[ao_cs] rozdrcen@[ao_cs].,%o blev mast.,%o wurde zerquetscht,@[art_gr] %o συνθλίφτηκε,%o estis dispremita.,%o ha quedado aplastad@[ao_esp].,%o quedó aplastad@[ao_esp].,%o liiskautui.,%o a été écrasé@[e_fr].,%o össze lett lapítva.,%o è stato schiacciato.,%o は潰された。,%o 은(는) 뭉게졌다.,%o werd geplet.,%o ble knust.,%o spłaszczył@[ao_pl] się.,%o foi esmagad@[ao_ptb].,,%o a fost strivit.,Игрок %o был раздавлен.,%o је здробљен@[adj_1_sr].,%o blev mosad.,%o ezildi. +%o tried to leave.,OB_EXIT,,,,%o se pokusil@[ao_cs] odejít.,%o forsøgte at gå.,%o wollte gehen.,@[art_gr] %o προσπάθησε να φύγει,%o provis foriri.,%o ha tratado de huir.,%o trató de huir.,%o yritti häipyä.,%o a tenté de partir.,%o megpróbált lelépni.,%o ha provato a uscire.,%o は逃げようとした。,%o 은(는) 나가려고 발버둥 쳤다.,%o probeerde te vertrekken.,%o prøvde å dra.,%o spróbował@[ao_pl] odejść.,%o tentou sair.,,%o a încercat să plece.,Игрок %o попытался уйти.,%o покуша@[ao_1_sr] да оде.,%o försökte lämna.,%o gitmeye çalıştı. +%o can't swim.,OB_WATER,,,,%o neumí plavat.,%o kan ikke svømme.,%o kann nicht schwimmen.,@[art_gr] %o δέν μπορεί να κολυμπήσει,%o ne scipovas naĝi.,%o no sabe nadar.,,%o ei osaa uida.,%o ne sait pas nager.,%o nem tud úszni.,%o non sapeva nuotare.,%o は泳げなかった。,%o 은(는) 익사했다.,%o kan niet zwemmen.,%o kan ikke svømme.,%o nie umie pływać.,%o não sabe nadar.,,%o nu poate înota.,Игрок %o не умел плавать.,%o не може да плива.,%o kan inte simma.,%o yüzme bilmiyor. +%o mutated.,OB_SLIME,,,,%o zmutoval@[ao_cs].,%o muterede.,%o mutierte.,@[art_gr] %o μεταλάχθηκε,%o mutaciis.,%o ha mutado.,%o mutó.,%o mutatoitui.,%o a muté.,%o mutánssá alakult.,%o è mutato.,%o は変異した。,%o 은(는) 돌연사를 당했다.,%o muteerde.,%o muterte.,%o zmutował@[ao_pl].,%o sofreu mutação.,,%o a avut parte de o mutație.,Игрок %o мутировал.,%o је мутиран@[adj_1_sr].,%o muterade.,%o mutasyona uğradı. +%o melted.,OB_LAVA,,,,%o se rozpustil@[ao_cs].,%o smeltede.,%o schmolz.,@[art_gr] %o έλειοσε,%o fandiĝis.,%o se ha fundido.,%o se fundió.,%o suli.,%o a fondu.,%o megolvadt.,%o si è sciolto.,%o は溶かされた。,%o 은(는) 녹아버렸다.,%o smolt.,%o smeltet.,%o stopił@[ao_pl] się.,%o derreteu.,%o derreteu-se.,%o s-a topit.,Игрок %o расплавился.,%o је отопљен@[adj_1_sr].,%o smälte.,%o eridi. +%o went boom.,OB_BARREL,,,,%o udělal@[ao_cs] bum.,%o gik bum.,%o explodierte.,@[art_gr] %o έσκασε,%o eksplodis.,%o ha explotado en mil pedazos.,%o explotó en mil pedazos.,%o poksahti.,%o s'est pété@[e_fr] la face.,%o felrobbant.,%o ha fatto bum.,%o は爆発で吹き飛ばされた。,%o 은(는) 폭사했다.,%o ging boem.,%o gikk i lufta.,%o zrobił@[ao_pl] bum.,%o explodiu.,,%o a explodat.,Игрок %o взорвался.,%o је отиш@[ao_2_sr] бум.,%o blev boom.,%o patladı. +%o stood in the wrong spot.,OB_SPLASH,,,,%o stál@[ao_cs] na špatném místě.,%o stod på det forkerte sted.,%o war am falschen Ort.,@[art_gr] %o έκατσε στο λάθος σημείο,%o staris en la malĝusta loko.,%o estaba en el sitio equivocado.,,%o seisoi väärässä paikassa.,%o s'est tenu@[e_fr] au mauvais endroit.,%o rossz helyre állt.,%o si è trovato nel posto sbagliato.,%o はいけない場所に立っていた。,%o 은(는) 위험한 곳에 서 있었다.,%o stond op de verkeerde plek.,%o sto på feil sted.,%o stan@[irreg_2_pl] w złym miejscu.,%o ficou no lugar errado.,,%o a stat în locul nepotrivit.,Игрок %o стоял в неверной точке.,%o је стаја@[ao_1_sr] на погрешно место.,%o stod på fel plats.,%o yanlış yerde durdu. +%o should have stood back.,OB_R_SPLASH,,,,%o měl@[ao_cs] stát o trochu dál.,%o skulle have stået tilbage.,%o hätte Abstand halten sollen.,@[art_gr] %o έπρεπε να είχε κάτσι πίσω,%o devintus forstarinta.,%o debería haberse apartado.,,%o oli liian likellä.,%o aurait dû garder ses distances.,%o túl közel állt.,%o si sarebbe dovuto allontanare.,%o は後ろへ引くべきだった。,%o 은(는) 좀 더 떨어져야만 했다.,%o had afstand moeten houden.,%o burde ha stått tilbake.,%o nie ustąpił@[ao_pl] na bok.,%o deveria ter se afastado.,,%o ar fi trebuit să stea deoparte.,Игрок %o не отступил в сторону.,Играчу %o је требало да стоји назад.,%o borde ha stått tillbaka.,%o geri çekilmeliydi. +%o should have stood back.,OB_ROCKET,,,,%o měl@[ao_cs] stát o trochu dál.,%o skulle have stået tilbage.,%o hätte Abstand halten sollen.,@[art_gr] %o έπρεπε να είχε κάτσι πίσω,%o devintus forstarinta.,%o debería haberse apartado.,,%o oli liian likellä.,%o aurait dû garder ses distances.,%o túl közel állt.,%o si sarebbe dovuto allontanare.,%o は後ろへ引くべきだった。,%o 은(는) 더 멀리 떨어져야만 했다.,%o had afstand moeten houden.,%o burde ha stått tilbake.,%o nie ustąpił@[ao_pl] na bok.,%o deveria ter se afastado.,,%o ar fi trebuit să stea deoparte.,Игрок %o не отступил в сторону.,Играчу %o је требало да стоји назад.,%o borde ha stått tillbaka.,%o geri çekilmeliydi. +%o killed %hself.,OB_KILLEDSELF,,,,%o se zabil@[ao_cs].,%o begik selvmord.,%o tötete sich selbst.,@[art_gr] %o αυτοκτόνησε,%o mortigis sin.,%o se ha matado a sí mism@[ao_esp].,%o se mató a sí mism@[ao_esp].,%o tappoi itsensä.,%o s'est tué@[e_fr].,%o megölte magát.,%o ha ucciso se stesso.,%o は自滅した。,%o 은(는) 자멸했다.,%o bracht zichzelf om.,%o begår selvmord.,%o zabił@[ao_pl] się.,%o se matou.,%o matou-se,%o s-a sinucis.,Игрок %o убил себя.,%o је уби@[ao_1_sr] себе.,%o tog livet av sig.,%o kendini öldürdü. +%o was killed by the power of voodoo.,OB_VOODOO,,,,%o byl@[ao_cs] zabit@[ao_cs] sílou voodoo.,%o blev dræbt af voodooens magt.,%o wurde durch Voodoo getötet.,@[art_gr] %o πέθανε απο τη δύναμη του βουντου,%o estis mortigita de la povo de voduo.,A %o l@[ao_esp] ha matado el poder del vudú.,A %o l@[ao_esp] mató el poder del vudú.,%o kuoli voodoon voimasta.,%o a succombé au pouvoir du Vaudou.,%o meghalt a voodoo erejének köszönhetően.,%o è stato ucciso dalla potenza del voodoo.,%o はブードゥー人形で殺された。,%o 은(는) 부두 마법의 저주를 받았다.,%o werd gedood door de kracht van voodoo.,%o ble drept av voodooens kraft.,%o umarł@[ao_pl] od mocy voodoo.,%o morreu pelo poder do voodoo.,,%o a fost omorât prin puterea voodoo.,Игрок %o убит силой Вуду.,%o је убијен@[adj_1_sr] од стране моћи Voodoo-а.,%o dödades av voodoo-kraften.,%o voodoo'nun gücü tarafından öldürüldü. +%o was telefragged by %k.,OB_MPTELEFRAG,,,,%o byl@[ao_cs] telefraggnut %kem.,%o blev telefragged af %k.,%o stand %k im Wege.,@[art_gr] %o κοματιάστηκε μέσω τηλεμεταφοράς απο τον/την %k,%o estis teleportumita de %k.,A %o l@[ao_esp] ha telefragmentado %k.,A %o l@[ao_esp] telefragmentó %k.,%k telefräggäsi %o paran.,%o a été téléfragué@[e_fr] par %k.,%o telefrag-et kapott %k által.,%o è stato telefraggato da %k.,%o は %k にテレフラグされた。,%o 은(는) %k 에 의해 텔레프랙을 당했다.,%o werd getelefragged door %k.,%o ble telefragget av %k.,%o został@[ao_pl] ztelefragowan@[adj_pl] przez %k.,%o foi telefragad@[ao_ptb] por %k.,,%o a fost omorât prin teleportare de către %k.,Игрок %o стал жертвой телепортации игрока %k.,%o је телефрагован@[adj_1_sr] од стране %k.,%o blev telefragged av %k.,"%o, %k tarafından telefrag edildi." +%o was telefragged.,OB_MONTELEFRAG,,,,%o byl@[ao_cs] telefraggnut@[ao_cs].,%o blev telefragged.,%o stand jemandem im Wege.,@[art_gr] %o κοματιάστηκε μέσω τηλεμεταφοράς,%o estis teleportumita.,A %o l@[ao_esp] han telefragmentado.,A %o l@[ao_esp] telefragmentaron.,%o telefrägättiin.,%o a été téléfragué@[e_fr].,%o telefraggelve lett.,%o si è fatto telefraggare.,%o はテレフラグされた。,%o 은(는) 텔레프랙을 당했다.,%o werd getelefragged.,%o ble telefragget.,%o został@[ao_pl] ztelefragowan@[adj_pl].,%o foi telefragad@[ao_ptb] por um monstro.,,%o a fost omorât prin teleportare.,Игрок %o стал жертвой телепортации.,%o је телефрагован@[adj_1_sr].,%o blev telefragged.,%o telefragged edildi. %o died.,OB_DEFAULT,,,,"%o zemřel@[ao_cs]. -",%o døde.,%o ist gestorben.,@[art_gr] %o πέθανε,%o mortis.,%o ha muerto.,%o acaba de morir.,%o kuoli.,%o est mort@[e_fr].,%o meghalt.,%o è morto.,%o は死亡した。,%o 은(는) 죽었다.,%o ging dood.,%o døde.,%o umarł@[ao_pl].,%o morreu.,,%o a murit.,Игрок %o погиб.,%o је умр@[ao_1_sr].,%o öldü. -%o was killed by %k.,OB_MPDEFAULT,,,,%o byl@[ao_cs] zabit@[ao_cs] hráčem %k.,%o blev dræbt af %k.,%o wurde von %k getötet.,@[art_gr] %o στοτώθηκε απο τον/την %k,%o estis mortigita de %k.,%o ha sido asesinad@[ao_esp] por %k.,%o fue asesinad@[ao_esp] por %k.,%k tappoi %o paran.,%o a été tué@[e_fr] par %k.,%k megölte %o-t.,%o è stato ucciso da %k,%o は %k によって殺された。,%o 은(는) %k 에 의해 죽임을 당했다.,%o werd gedood door %k.,%o ble drept av %k.,%o został@[ao_pl] zabit@[adj_pl] przez %k.,%o foi mort@[ao_ptb] por %k.,,%o a fost omorât de către %k.,Игрока %o убил игрок %k.,Играча %o је уби@[ao_1_sr] %k.,"%o, %k tarafından öldürüldü." -%k mows down a teammate.,OB_FRIENDLY1,,,,%o rozsekal@[ao_cs] spoluhráče.,%k mejer en holdkammerat ned.,%o wurde von einem Teamkameraden niedergestreckt.,Ο/Η %k σκότωσε έναν σύμαχο,%k buĉas teamanon.,%k acribilla a un compañero.,,%k niitti joukkuetoverin.,%k élimine un de ses équipiers.,%k lekaszabolta a csapattársát.,%k falcia via un compagno.,%k は仲間を無慈悲に殺した。,%o 은(는) 자신의 팀원을 죽였다.,%k maait een teamgenoot neer.,%k meier ned en lagkamerat.,%k kosi kompana.,%k matou um colega de equipe.,%k matou um companheiro de equipa.,%k face pulbere pe un coechipier.,Игрок %k сбивает союзника.,%k је обори@[ao_1_sr] саиграча.,%k bir takım arkadaşını biçti. -%k seems to need glasses.,OB_FRIENDLY2,English was changed to remove problematic pronoun referencing the killer,,,%k nejspíš potřebuje brýle.,%k har tilsyneladende brug for briller.,%k sollte eine Brille benutzen.,Ο/Η %k φαίνεται να χρειάζετε γυαλία,%o ŝajnas bezoni okulvitrojn.,%k parece necesitar gafas.,%k parece necesitar lentes.,%k näyttää tarvitsevan laseja.,%k vérifie ses lunettes.,%k-nak szemüvegre van szüksége.,%k sembra che abbia bisogno di occhiali.,%k には眼鏡が必要なようだ。,%o 은(는) 자신의 안경을 확인했다.,%k lijkt een bril nodig te hebben.,%k ser ut til å trenge briller.,%k wydaje się potrzebować okularów.,%k parece que precisa de óculos.,,%k pare să aibă nevoie de ochelari.,Игроку %k следует носить свои очки.,Играчу %k би приличиле наочаре.,%k net göremiyor -%k gets a frag for the other team.,OB_FRIENDLY3,,,,%k dostal@[ao_cs] frag pro další tým.,%k får en fragment til det andet hold.,%k macht für das andere Team einen Punkt.,Ο/Η %k πάιρνει έναν κοματιασμό για την άλλη ομάδα.,%k gajnas ludmurdon por la alia teamo.,%k marca una baja para el otro equipo.,,%k teki frägin vieraalle joukkueelle.,%k marque un point pour l'autre équipe.,%k szerez egy frag-et a másik csapatnak.,%k regala un frag all'altro team.,%k は敵チームに得点を入れた。,%o 은(는) 의도치 않게 상대방 팀을 도왔다.,%k doet een frag voor het andere team.,%k får en frag for det andre laget.,%k zdobywa fraga dla przeciwnej drużyny.,%k dá um frag para o outro time.,%k dá um frag para a outra equipa.,%k face o victimă pentru echipa adversă.,Игрок %k преподнёс другой команде фраг.,%k осваја фраг за други тим.,%k diğer takım için bir parça aldı. -%k loses another friend.,OB_FRIENDLY4,,,,%k ztratil@[ao_cs] dalšího přítele.,%k mister endnu en ven.,%k hat wieder einen Freund verloren.,Ο/Η %k χάνει ακόμα έναν αλλο φίλο,%k perdis alian amikon.,%k pierde otro amigo.,,%k menetti jälleen ystävän.,%k a perdu un autre ami.,%k elveszít egy másik barátot.,%k perde un altro amico.,%k はまた友達を失った。,%o 은(는) 친구를 원치 않았다.,%k verliest nog een vriend.,%k mister enda en venn.,%k tracil kolejnego przyjaciela.,%k perde mais um amigo.,,%k mai pierde un prieten.,Игрок %k потерял ещё одного друга.,%k је изгуби@[ao_1_sr] још једног пријатеља.,%k başka bir arkadaşını kaybetti. -,,Pickup,,,,,,,,,,,,,,,,,,,,,,,, -Picked up the armor.,GOTARMOR,,,Picked up the armour.,Sebráno brnění.,Hentede rustningen.,Panzer genommen.,Πήρες την πανοπλία.,Vi trovis armaĵon.,Encuentras una armadura.,Hallaste una armadura.,Poimit panssarin.,Armure récupérée.,Felvettél egy páncélt.,Raccolto un'armatura.,アーマーを身に着けた。,방호구를 얻었다.,Je hebt het harnas opgepakt.,Plukket opp rustningen.,Zebrano zbroję.,Pegou uma armadura.,Apanhaste uma armadura.,Ai ridicat o armură.,Получена броня.,Покупили сте панцир.,Zırhı aldım. -Picked up the MegaArmor!,GOTMEGA,,,Picked up the MegaArmour!,Sebráno MegaBrnění!,Hentede Mega-rustningen!,MegaPanzer genommen!,Πήρες την μέγα πανοπλία!,Vi trovis superan armaĵon!,¡Encuentras una Megaarmadura!,¡Hallaste una Megaarmadura!,Poimit megapanssarin!,Méga-Armure récupérée!,Felvettél egy MegaPáncélt!,Raccolto una MegaArmatura!,メガアーマーを身に着けた!,메가아머를 얻었다!,Je hebt het megaharnas opgepakt!,Plukket opp mega rustningen!,Zebrano megazbroję!,Pegou uma Mega-armadura!,Apanhaste uma MegaArmadura.,Ai ridicat o MegaArmură!,Получена мегаброня!,Покупили сте мегапанцир!,MegaZırhı aldı! -Picked up a health bonus.,GOTHTHBONUS,,,,Sebráno bonusové zdraví.,Hentede en sundhedsbonus.,Gesundheitsbonus genommen.,Πήρες ένα bonus υγείας.,Vi trovis aldonan sanon.,Encuentras salud extra.,Hallaste salud extra.,Poimit terveyslisän.,Bonus de Santé récupéré.,Felvettél egy életbónuszt.,Raccolto un bonus di salute.,ヘルスボーナスを拾った。,체력 보너스를 얻었다.,Je hebt een gezondheidsbonus opgepakt.,Plukket opp en helsebonus.,Zebrano bonus do zdrowia.,Pegou um bônus de saúde.,Apanhaste um bônus de vida.,Ai ridicat un bonus de sănătate.,Получен бонус к здоровью.,Покупили сте бонус здравља.,Bir sağlık bonusu aldı. -Picked up an armor bonus.,GOTARMBONUS,,,Picked up an armour bonus.,Sebráno bonusové brnění.,Hentede en rustningsbonus.,Panzerbonus genommen.,Πήρες ένα bonus πανο.πλίας.,Vi trovis aldonan kirason.,Encuentras blindaje extra.,Hallaste blindaje extra.,Poimit panssarilisän.,Bonus d'Armure récupéré.,Felvettél egy páncélbónuszt.,Raccolto un bonus d'armatura.,アーマーボーナスを拾った。,보호 보너스를 얻었다.,Je hebt een harnasbonus opgepakt.,Plukket opp en rustningsbonus.,Zebrano bonus do zbroi.,Pegou um bônus de armadura.,Apanhaste um bônus de armadura.,Ai ridicat un bonus de armură.,Получен бонус к броне.,Покупили сте бонус панцира.,Bir zırh bonusu aldı. -Picked up a stimpack.,GOTSTIM,,,,Sebrán stimulant.,Hentede en stimpack.,Stimpack genommen.,Πήρες ένα μικρό πακέτο υγείας.,Vi trovis stimulilo-pakon.,Encuentras un estimulante.,Hallaste un estimulante.,Poimit piristeruiskeen.,Stimpack récupéré.,Felvettél egy szurit.,Raccolto uno stimpack.,スティムパックを拾った。,스팀팩을 사용했다.,Je hebt een opwekpakket opgepakt.,Plukket opp en stimpack.,Zebrano małą apteczkę.,Pegou um estimulante.,Apanhaste um kit de primeiros socorros.,Ai ridicat un kit de prim-ajutor mic.,Получен стимулятор.,Покупили сте стимпак.,Bir uyarıcı aldı. +",%o døde.,%o ist gestorben.,@[art_gr] %o πέθανε,%o mortis.,%o ha muerto.,%o murió.,%o kuoli.,%o est mort@[e_fr].,%o meghalt.,%o è morto.,%o は死亡した。,%o 은(는) 죽었다.,%o ging dood.,%o døde.,%o umarł@[ao_pl].,%o morreu.,,%o a murit.,Игрок %o погиб.,%o је умр@[ao_1_sr].,%o dog.,%o öldü. +%o was killed by %k.,OB_MPDEFAULT,,,,%o byl@[ao_cs] zabit@[ao_cs] hráčem %k.,%o blev dræbt af %k.,%o wurde von %k getötet.,@[art_gr] %o στοτώθηκε απο τον/την %k,%o estis mortigita de %k.,A %o l@[ao_esp] ha matado %k.,A %o l@[ao_esp] mató %k.,%k tappoi %o paran.,%o a été tué@[e_fr] par %k.,%k megölte %o-t.,%o è stato ucciso da %k,%o は %k によって殺された。,%o 은(는) %k 에 의해 죽임을 당했다.,%o werd gedood door %k.,%o ble drept av %k.,%o został@[ao_pl] zabit@[adj_pl] przez %k.,%o foi mort@[ao_ptb] por %k.,,%o a fost omorât de către %k.,Игрока %o убил игрок %k.,Играча %o је уби@[ao_1_sr] %k.,%o dödades av %k.,"%o, %k tarafından öldürüldü." +%k mows down a teammate.,OB_FRIENDLY1,,,,%o rozsekal@[ao_cs] spoluhráče.,%k mejer en holdkammerat ned.,%o wurde von einem Teamkameraden niedergestreckt.,Ο/Η %k σκότωσε έναν σύμαχο,%k buĉas teamanon.,%k ha acribillado a un compañero.,%k acribilló a un compañero.,%k niitti joukkuetoverin.,%k élimine un de ses équipiers.,%k lekaszabolta a csapattársát.,%k falcia via un compagno.,%k は仲間を無慈悲に殺した。,%o 은(는) 자신의 팀원을 죽였다.,%k maait een teamgenoot neer.,%k meier ned en lagkamerat.,%k kosi kompana.,%k matou um colega de equipe.,%k matou um companheiro de equipa.,%k face pulbere pe un coechipier.,Игрок %k сбивает союзника.,%k је обори@[ao_1_sr] саиграча.,%k mejar ner en lagkamrat.,%k bir takım arkadaşını biçti. +%k seems to need glasses.,OB_FRIENDLY2,English was changed to remove problematic pronoun referencing the killer,,,%k nejspíš potřebuje brýle.,%k har tilsyneladende brug for briller.,%k sollte eine Brille benutzen.,Ο/Η %k φαίνεται να χρειάζετε γυαλία,%o ŝajnas bezoni okulvitrojn.,%k parece necesitar gafas.,%k parece necesitar lentes.,%k näyttää tarvitsevan laseja.,%k vérifie ses lunettes.,%k-nak szemüvegre van szüksége.,%k sembra che abbia bisogno di occhiali.,%k には眼鏡が必要なようだ。,%o 은(는) 자신의 안경을 확인했다.,%k lijkt een bril nodig te hebben.,%k ser ut til å trenge briller.,%k wydaje się potrzebować okularów.,%k parece que precisa de óculos.,,%k pare să aibă nevoie de ochelari.,Игроку %k следует носить свои очки.,Играчу %k би приличиле наочаре.,%k verkar behöva glasögon.,%k net göremiyor +%k gets a frag for the other team.,OB_FRIENDLY3,,,,%k dostal@[ao_cs] frag pro další tým.,%k får en fragment til det andet hold.,%k macht für das andere Team einen Punkt.,Ο/Η %k πάιρνει έναν κοματιασμό για την άλλη ομάδα.,%k gajnas ludmurdon por la alia teamo.,%k ha marcado una baja para el otro equipo.,%k marcó una baja para el otro equipo.,%k teki frägin vieraalle joukkueelle.,%k marque un point pour l'autre équipe.,%k szerez egy frag-et a másik csapatnak.,%k regala un frag all'altro team.,%k は敵チームに得点を入れた。,%o 은(는) 의도치 않게 상대방 팀을 도왔다.,%k doet een frag voor het andere team.,%k får en frag for det andre laget.,%k zdobywa fraga dla przeciwnej drużyny.,%k dá um frag para o outro time.,%k dá um frag para a outra equipa.,%k face o victimă pentru echipa adversă.,Игрок %k преподнёс другой команде фраг.,%k осваја фраг за други тим.,%k får ett frag till det andra laget.,%k diğer takım için bir parça aldı. +%k loses another friend.,OB_FRIENDLY4,,,,%k ztratil@[ao_cs] dalšího přítele.,%k mister endnu en ven.,%k hat wieder einen Freund verloren.,Ο/Η %k χάνει ακόμα έναν αλλο φίλο,%k perdis alian amikon.,%k ha perdido a otro amigo.,%k perdió a otro amigo.,%k menetti jälleen ystävän.,%k a perdu un autre ami.,%k elveszít egy másik barátot.,%k perde un altro amico.,%k はまた友達を失った。,%o 은(는) 친구를 원치 않았다.,%k verliest nog een vriend.,%k mister enda en venn.,%k tracil kolejnego przyjaciela.,%k perde mais um amigo.,,%k mai pierde un prieten.,Игрок %k потерял ещё одного друга.,%k је изгуби@[ao_1_sr] још једног пријатеља.,%k förlorar ännu en vän.,%k başka bir arkadaşını kaybetti. +,,Pickup,,,,,,,,,,,,,,,,,,,,,,,,, +Picked up the armor.,GOTARMOR,,,Picked up the armour.,Sebráno brnění.,Hentede rustningen.,Panzer genommen.,Πήρες την πανοπλία.,Vi trovis armaĵon.,Encuentras una armadura.,Hallaste una armadura.,Poimit panssarin.,Armure récupérée.,Felvettél egy páncélt.,Raccolto un'armatura.,アーマーを身に着けた。,방호구를 얻었다.,Je hebt het harnas opgepakt.,Plukket opp rustningen.,Zebrano zbroję.,Pegou uma armadura.,Apanhaste uma armadura.,Ai ridicat o armură.,Получена броня.,Покупили сте панцир.,Plockade upp rustningen.,Zırhı aldım. +Picked up the MegaArmor!,GOTMEGA,,,Picked up the MegaArmour!,Sebráno MegaBrnění!,Hentede Mega-rustningen!,MegaPanzer genommen!,Πήρες την μέγα πανοπλία!,Vi trovis superan armaĵon!,¡Encuentras una Megaarmadura!,¡Hallaste una Megaarmadura!,Poimit megapanssarin!,Méga-Armure récupérée!,Felvettél egy MegaPáncélt!,Raccolto una MegaArmatura!,メガアーマーを身に着けた!,메가아머를 얻었다!,Je hebt het megaharnas opgepakt!,Plukket opp mega rustningen!,Zebrano megazbroję!,Pegou uma Mega-armadura!,Apanhaste uma MegaArmadura.,Ai ridicat o MegaArmură!,Получена мегаброня!,Покупили сте мегапанцир!,Plockade upp mega rustningen!,MegaZırhı aldı! +Picked up a health bonus.,GOTHTHBONUS,,,,Sebráno bonusové zdraví.,Hentede en sundhedsbonus.,Gesundheitsbonus genommen.,Πήρες ένα bonus υγείας.,Vi trovis aldonan sanon.,Encuentras salud extra.,Hallaste salud extra.,Poimit terveyslisän.,Bonus de Santé récupéré.,Felvettél egy életbónuszt.,Raccolto un bonus di salute.,ヘルスボーナスを拾った。,체력 보너스를 얻었다.,Je hebt een gezondheidsbonus opgepakt.,Plukket opp en helsebonus.,Zebrano bonus do zdrowia.,Pegou um bônus de saúde.,Apanhaste um bônus de vida.,Ai ridicat un bonus de sănătate.,Получен бонус к здоровью.,Покупили сте бонус здравља.,Plockade upp en hälsobonus.,Bir sağlık bonusu aldı. +Picked up an armor bonus.,GOTARMBONUS,,,Picked up an armour bonus.,Sebráno bonusové brnění.,Hentede en rustningsbonus.,Panzerbonus genommen.,Πήρες ένα bonus πανο.πλίας.,Vi trovis aldonan kirason.,Encuentras blindaje extra.,Hallaste blindaje extra.,Poimit panssarilisän.,Bonus d'Armure récupéré.,Felvettél egy páncélbónuszt.,Raccolto un bonus d'armatura.,アーマーボーナスを拾った。,보호 보너스를 얻었다.,Je hebt een harnasbonus opgepakt.,Plukket opp en rustningsbonus.,Zebrano bonus do zbroi.,Pegou um bônus de armadura.,Apanhaste um bônus de armadura.,Ai ridicat un bonus de armură.,Получен бонус к броне.,Покупили сте бонус панцира.,Plockade upp en rustningsbonus.,Bir zırh bonusu aldı. +Picked up a stimpack.,GOTSTIM,,,,Sebrán stimulant.,Hentede en stimpack.,Stimpack genommen.,Πήρες ένα μικρό πακέτο υγείας.,Vi trovis stimulilo-pakon.,Encuentras un estimulante.,Hallaste un estimulante.,Poimit piristeruiskeen.,Stimpack récupéré.,Felvettél egy szurit.,Raccolto uno stimpack.,スティムパックを拾った。,스팀팩을 사용했다.,Je hebt een opwekpakket opgepakt.,Plukket opp en stimpack.,Zebrano małą apteczkę.,Pegou um estimulante.,Apanhaste um kit de primeiros socorros.,Ai ridicat un kit de prim-ajutor mic.,Получен стимулятор.,Покупили сте стимпак.,Plockade upp en stimpack.,Bir uyarıcı aldı. Picked up a medikit that you REALLY need!,GOTMEDINEED,,,,"Sebrána lékárnička, kterou jsi FAKT potřeboval@[ao_cs].","Hentede en medikit, som du VIRKELIG har brug for!","Medikit genommen, das du WIRKLICH brauchst!",Πήρες πρώτες βοήθειες που χρειαζόσουνα ΠΆΡΑ ΠΟΛΥ!,"Vi trovis sukurkeston, kiun vi VERE bezonas!",¡Encuentras un botiquín que REALMENTE necesitabas!,¡Hallaste un botiquín que REALMENTE necesitabas!,"Poimit lääkintälaukun, jota TODELLA tarvitsit!","Médikit récupéré, et vous en aviez vraiment besoin!",Felvettél egy életcsomagot amire NAGYON szükséged volt már!,Hai raccolto un kit medico di cui avevi PROPRIO bisogno!,本当に必要なメディキットを手に入れた!,메디킷을 필요한 순간에 사용했다!,"Je hebt een verbandsdoos, die je ECHT nodig had, opgepakt!",Plukket opp en medikit som du virkelig trenger!,"Zebrano apteczkę, w OSTATNIEJ chwili!","Pegou um kit médico que você REALMENTE precisava!","Apanhaste um kit médico que estavas MESMO a precisar!","Ai ridicat un kit de prim-ajutor de care CHIAR aveai -nevoie!",Получена КРАЙНЕ необходимая аптечка!,Покупили сте медикит који вам је СТВАРНО потребан!,GERÇEKTEN ihtiyacın olan bir medikit aldı! -Picked up a medikit.,GOTMEDIKIT,,,,Sebrána lékárnička.,Samlede en medikit op.,Medikit genommen.,Πήρες πρώτες βοήθειες.,Vi trovis sukurkeston.,Encuentras un botiquín.,Hallaste un botiquín.,Poimit lääkintälaukun.,Médikit récupéré.,Felvettél egy életcsomagot.,Raccolto un kit medico.,メディキットを拾った。,메디킷을 사용했다.,Je hebt een verbandsdoos opgepakt.,Plukket opp en medikit.,Zebrano apteczkę.,Pegou um kit médico.,Apanhaste um kit médico.,Ai ridicat un kit de prim-ajutor.,Получена аптечка.,Покупили сте медикит.,Bir medikit aldı. -Supercharge!,GOTSUPER,,,,Superzdraví!,,Super-Ladung!,Υπερφόρτοση!,Superŝargo!,¡Supercarga!,,Supervaraus!,,Szupertöltés!,Sfera dell'Anima!,スーパーチャージ!,슈퍼차지!,,,Supernaładowanie!,Supercarga!,,Superîncărcătură!,Сверхзаряд!,Супернабој!,Süper şarj! -Picked up a blue keycard.,GOTBLUECARD,,,,Sebrána modrá karta.,Samlede et blåt nøglekort op.,Blaue Schlüsselkarte genommen.,Πήρες ένα μπλε κλειδί.,Vi trovis bluan ŝlosilkarton.,Encuentras una tarjeta de acceso azul.,Hallaste una tarjeta de acceso azul.,Poimit sinisen avainkortin.,Carte d'accès BLEUE récupérée.,Felvettél egy kék kulcskártyát.,Raccolta una card d'accesso blu.,ブルー キーカードを手に入れた。,청색 키카드를 얻었다.,Je hebt een blauwe sleutelkaart opgepakt.,Plukket opp et blått nøkkelkort.,Zebrano niebieską kartę klucz.,Pegou um cartão de acesso azul.,Apanhaste um cartão de acesso azul.,Ai ridicat un card cheie albastru.,Получена синяя ключ-карта.,Покупили сте плаву кључну карту.,Mavi bir anahtar kartı aldı. -Picked up a yellow keycard.,GOTYELWCARD,,,,Sebrána žlutá karta.,Samlede et gult nøglekort op.,Gelbe Schlüsselkarte genommen.,Πήρες ένα κύτρινο κλειδί.,Vi trovis flavan ŝlosilkarton.,Encuentras una tarjeta de acceso amarilla.,Hallaste una tarjeta de acceso amarilla.,Poimit keltaisen avainkortin.,Carte d'accès JAUNE récupérée.,Felvettél egy sárga kulcskártyát.,Raccolta una card d'accesso gialla.,イエローキーカードを手に入れた。,황색 키카드를 얻었다.,Je hebt een gele sleutelkaart opgepakt.,Plukket opp et gult nøkkelkort.,Zebrano żółtą kartę klucz.,Pegou um cartão de acesso amarelo.,Apanhaste um cartão de acesso amarelo.,Ai ridicat un card cheie galben.,Получена жёлтая ключ-карта,Покупили сте жуту кључну карту.,Sarı bir anahtar kartı aldı. -Picked up a red keycard.,GOTREDCARD,,,,Sebrána červená karta.,Samlede et rødt nøglekort op.,Rote Schlüsselkarte genommen.,Πήρες ένα κόκινο κλειδί.,Vi trovis ruĝan ŝlosilkarton.,Encuentras una tarjeta de acceso roja.,Hallaste una tarjeta de acceso roja.,Poimit punaisen avainkortin.,Carte d'accès ROUGE récupérée.,Felvettél egy piros kulcskártyát.,Raccolta una card d'accesso rossa.,レッド キーカードを手に入れた。,적색 키카드를 얻었다.,Je hebt een rode sleutelkaart opgepakt.,Plukket opp et rødt nøkkelkort.,Zebrano czerwoną kartę klucz.,Pegou um cartão de acesso vermelho.,Apanhaste um cartão de acesso vermelho.,Ai ridicat un card cheie roșu.,Получена красная ключ-карта.,Покупили сте црвену кључну карту.,Kırmızı bir anahtar kartı aldı. -Picked up a blue skull key.,GOTBLUESKUL,,,,Sebrána modrá lebka.,Samlede en blå kranie-nøgle op.,Blauen Schädel-Schlüssel genommen.,Πήρες ένα μπλε κρανίο.,Vi trovis bluan kraniŝlosilon.,Encuentras una llave de calavera azul.,Hallaste una llave de calavera azul.,Poimit sinisen kalloavaimen.,Clef Crâne BLEUE récupérée.,Felvettél egy kék koponyakulcsot.,Raccolta una chiave-teschio blu.,ブルー スカルキーを手に入れた。,청색 해골열쇠를 얻었다.,Je hebt een blauwe schedelsleutel opgepakt.,Plukket opp en blå hodeskallenøkkel.,Zebrano niebieską czaszkę.,Pegou uma chave-crânio azul.,Apanhaste uma chave crânio azul.,Ai ridicat o cheie craniu albastră.,Получен синий череп-ключ.,Покупили сте плави кључ лобање.,Mavi bir kafatası anahtarı aldı. -Picked up a yellow skull key.,GOTYELWSKUL,,,,Sebrána žlutá lebka.,Samlede en gul kranie-nøgle op.,Geben Schädel-Schlüssel genommen.,Πήρες ένα κύτρινο κρανίο.,Vi trovis flavan kraniŝlosilon.,Encuentras una llave de calavera amarilla,Hallaste una llave de calavera amarilla,Poimit keltaisen kalloavaimen.,Clef Crâne JAUNE récupérée.,Felvettél egy sárga koponyakulcsot.,Raccolta una chiave-teschio gialla.,イエロースカルキーを手に入れた。,황색 해골열쇠를 얻었다.,Je hebt een gele schedelsleutel opgepakt.,Plukket opp en gul hodeskallenøkkel.,Zebrano żółtą czaszkę.,Pegou uma chave-crânio amarela.,Apanhaste uma chave crânio amarela.,Ai ridicat o cheie craniu galbenă.,Получен жёлтый череп-ключ.,Покупили сте жути кључ лобање.,Sarı bir kafatası anahtarı aldı. -Picked up a red skull key.,GOTREDSKUL,,,,Sebrána červená lebka.,Samlede en rød kranie-nøgle op.,Roten Schädel-Schlüssel genommen.,Πήρες ένα κοκινο κρανίο.,Vi trovis ruĝan kraniŝlosilon.,Encuentras una llave de calavera roja.,Hallaste una llave de calavera roja.,Poimit punaisen kalloavaimen.,Clef Crâne ROUGE récupérée.,Felvettél egy piros koponyakulcsot.,Raccolta una chiave-teschio rossa.,レッド スカルキーを手に入れた。,적색 해골열쇠를 얻었다.,Je hebt een rode schedelsleutel opgepakt.,Plukket opp en rød hodeskallenøkkel.,Zebrano czerwoną czaszkę.,Pegou uma chave-crânio vermelha.,Apanhaste uma chave crânio vermelha.,Ai ridicat o cheie craniu roșie.,Получен красный череп-ключ.,Покупили сте црвени кључ лобање.,Kırmızı kafatası anahtarı aldı. -Invulnerability!,GOTINVUL,,,,Nezranitelnost!,Udsårbarhed!,Unverwundbarkeit!,Αθανασία!,Nevundebleco!,¡Invulnerabilidad!,,Haavoittumattomuus!,Invulnérabilité!,Sérthetetlenség!,Invulnerabilità!,不死身だ!,무적!,Onkwetsbaarheid!,Usårbarhet!,Niezniszczalność!,Invulnerabilidade!,,Invincibilitate!,Неуязвимость!,Нерањивост!,Dokunulmazlık! -Berserk!,GOTBERSERK,,,,,,,Μανία!,Furiozigaĵo!,¡Berserker!,,Raivo!,,Dühödt mód!,,バーサーク!,광전사!,,,Szał!,Frenesi!,,Forță amplificată!,Берсерк!,Берсерк!,Berserk! -Partial Invisibility,GOTINVIS,,,,Částečná neviditelnost,Delvis usynlighed,Teilweise Unsichtbarkeit,Ημη-αoρατότητα,Parta nevidebleco,Invisibilidad parcial,,Osittainen näkymättömyys,Invisibilité Partielle,Részleges láthatatlanság,Invisibilità parziale,半透明化スフィア,일시적 투명 효과!,Gedeeltelijke onzichtbaarheid,Delvis usynlighet,Częściowa niewidzialność,Invisibilidade parcial,,Invizibilitate parțială,Частичная невидимость.,Делимична невидљивост,Kısmi Görünmezlik -Radiation Shielding Suit,GOTSUIT,,,,Ochranný oblek proti radioaktivitě,Stråleafskærmningsdragt,Strahlenschutzanzug.,Προστατευτηκή Στολή,Radiado-ŝirma vesto,Traje antiradiación,,Säteilysuojapuku,Combinaison Hazmat,Védőruha,Tuta anti-radiazioni,放射線防護服 ,방사능 보호복,Stralingsbeschermingspak,Strålingsskjermingsdrakt,Kombinezon przeciwradiacyjny,Traje antirradiação,Fato anti-radiação,Costum de protecție împotriva radiaților,Костюм радиационной защиты.,Одело против радијације,Radyasyon Koruyucu Giysi -Computer Area Map,GOTMAP,,,,Počítačová mapa,Computerkort.,Computerkarte.,Τοπικός Χάρτης,Komputila mapo de areo,Mapa ordenador del área,Mapa computadora del área,Alueen tietokonekartta,Carte Informatique,Térkép,Mappa Completata,コンピューターエリアマップ,구역 지도 컴퓨터,Computerkaart,Datakart,Komputerowa mapa obszaru,Mapa completo,,Hartă completă,Компьютерная карта уровня.,Компјутерска мапа нивоа,Bilgisayar Alanı Haritası +nevoie!",Получена КРАЙНЕ необходимая аптечка!,Покупили сте медикит који вам је СТВАРНО потребан!,Plockade upp en medikit som du VÄLDIGT behöver!,GERÇEKTEN ihtiyacın olan bir medikit aldı! +Picked up a medikit.,GOTMEDIKIT,,,,Sebrána lékárnička.,Samlede en medikit op.,Medikit genommen.,Πήρες πρώτες βοήθειες.,Vi trovis sukurkeston.,Encuentras un botiquín.,Hallaste un botiquín.,Poimit lääkintälaukun.,Médikit récupéré.,Felvettél egy életcsomagot.,Raccolto un kit medico.,メディキットを拾った。,메디킷을 사용했다.,Je hebt een verbandsdoos opgepakt.,Plukket opp en medikit.,Zebrano apteczkę.,Pegou um kit médico.,Apanhaste um kit médico.,Ai ridicat un kit de prim-ajutor.,Получена аптечка.,Покупили сте медикит.,Plockade upp en medikit.,Bir medikit aldı. +Supercharge!,GOTSUPER,,,,Superzdraví!,,Super-Ladung!,Υπερφόρτοση!,Superŝargo!,¡Supercarga!,,Supervaraus!,,Szupertöltés!,Sfera dell'Anima!,スーパーチャージ!,슈퍼차지!,,,Supernaładowanie!,Supercarga!,,Superîncărcătură!,Сверхзаряд!,Супернабој!,Superladdning!,Süper şarj! +Picked up a blue keycard.,GOTBLUECARD,,,,Sebrána modrá karta.,Samlede et blåt nøglekort op.,Blaue Schlüsselkarte genommen.,Πήρες ένα μπλε κλειδί.,Vi trovis bluan ŝlosilkarton.,Encuentras una tarjeta de acceso azul.,Hallaste una tarjeta de acceso azul.,Poimit sinisen avainkortin.,Carte d'accès BLEUE récupérée.,Felvettél egy kék kulcskártyát.,Raccolta una card d'accesso blu.,ブルー キーカードを手に入れた。,청색 키카드를 얻었다.,Je hebt een blauwe sleutelkaart opgepakt.,Plukket opp et blått nøkkelkort.,Zebrano niebieską kartę klucz.,Pegou um cartão de acesso azul.,Apanhaste um cartão de acesso azul.,Ai ridicat un card cheie albastru.,Получена синяя ключ-карта.,Покупили сте плаву кључну карту.,Plockade upp ett blått nyckelkort.,Mavi bir anahtar kartı aldı. +Picked up a yellow keycard.,GOTYELWCARD,,,,Sebrána žlutá karta.,Samlede et gult nøglekort op.,Gelbe Schlüsselkarte genommen.,Πήρες ένα κύτρινο κλειδί.,Vi trovis flavan ŝlosilkarton.,Encuentras una tarjeta de acceso amarilla.,Hallaste una tarjeta de acceso amarilla.,Poimit keltaisen avainkortin.,Carte d'accès JAUNE récupérée.,Felvettél egy sárga kulcskártyát.,Raccolta una card d'accesso gialla.,イエローキーカードを手に入れた。,황색 키카드를 얻었다.,Je hebt een gele sleutelkaart opgepakt.,Plukket opp et gult nøkkelkort.,Zebrano żółtą kartę klucz.,Pegou um cartão de acesso amarelo.,Apanhaste um cartão de acesso amarelo.,Ai ridicat un card cheie galben.,Получена жёлтая ключ-карта.,Покупили сте жуту кључну карту.,Plockade upp ett gult nyckelkort.,Sarı bir anahtar kartı aldı. +Picked up a red keycard.,GOTREDCARD,,,,Sebrána červená karta.,Samlede et rødt nøglekort op.,Rote Schlüsselkarte genommen.,Πήρες ένα κόκινο κλειδί.,Vi trovis ruĝan ŝlosilkarton.,Encuentras una tarjeta de acceso roja.,Hallaste una tarjeta de acceso roja.,Poimit punaisen avainkortin.,Carte d'accès ROUGE récupérée.,Felvettél egy piros kulcskártyát.,Raccolta una card d'accesso rossa.,レッド キーカードを手に入れた。,적색 키카드를 얻었다.,Je hebt een rode sleutelkaart opgepakt.,Plukket opp et rødt nøkkelkort.,Zebrano czerwoną kartę klucz.,Pegou um cartão de acesso vermelho.,Apanhaste um cartão de acesso vermelho.,Ai ridicat un card cheie roșu.,Получена красная ключ-карта.,Покупили сте црвену кључну карту.,Plockade upp ett rött nyckelkort.,Kırmızı bir anahtar kartı aldı. +Picked up a blue skull key.,GOTBLUESKUL,,,,Sebrána modrá lebka.,Samlede en blå kranie-nøgle op.,Blauen Schädel-Schlüssel genommen.,Πήρες ένα μπλε κρανίο.,Vi trovis bluan kraniŝlosilon.,Encuentras una llave de calavera azul.,Hallaste una llave de calavera azul.,Poimit sinisen kalloavaimen.,Clef Crâne BLEUE récupérée.,Felvettél egy kék koponyakulcsot.,Raccolta una chiave-teschio blu.,ブルー スカルキーを手に入れた。,청색 해골열쇠를 얻었다.,Je hebt een blauwe schedelsleutel opgepakt.,Plukket opp en blå hodeskallenøkkel.,Zebrano niebieską czaszkę.,Pegou uma chave-crânio azul.,Apanhaste uma chave crânio azul.,Ai ridicat o cheie craniu albastră.,Получен синий череп-ключ.,Покупили сте плави кључ лобање.,Plockade upp en blå dödskalle-nyckel.,Mavi bir kafatası anahtarı aldı. +Picked up a yellow skull key.,GOTYELWSKUL,,,,Sebrána žlutá lebka.,Samlede en gul kranie-nøgle op.,Geben Schädel-Schlüssel genommen.,Πήρες ένα κύτρινο κρανίο.,Vi trovis flavan kraniŝlosilon.,Encuentras una llave de calavera amarilla,Hallaste una llave de calavera amarilla,Poimit keltaisen kalloavaimen.,Clef Crâne JAUNE récupérée.,Felvettél egy sárga koponyakulcsot.,Raccolta una chiave-teschio gialla.,イエロースカルキーを手に入れた。,황색 해골열쇠를 얻었다.,Je hebt een gele schedelsleutel opgepakt.,Plukket opp en gul hodeskallenøkkel.,Zebrano żółtą czaszkę.,Pegou uma chave-crânio amarela.,Apanhaste uma chave crânio amarela.,Ai ridicat o cheie craniu galbenă.,Получен жёлтый череп-ключ.,Покупили сте жути кључ лобање.,Plockade upp en gul dödskalle-nyckel.,Sarı bir kafatası anahtarı aldı. +Picked up a red skull key.,GOTREDSKUL,,,,Sebrána červená lebka.,Samlede en rød kranie-nøgle op.,Roten Schädel-Schlüssel genommen.,Πήρες ένα κοκινο κρανίο.,Vi trovis ruĝan kraniŝlosilon.,Encuentras una llave de calavera roja.,Hallaste una llave de calavera roja.,Poimit punaisen kalloavaimen.,Clef Crâne ROUGE récupérée.,Felvettél egy piros koponyakulcsot.,Raccolta una chiave-teschio rossa.,レッド スカルキーを手に入れた。,적색 해골열쇠를 얻었다.,Je hebt een rode schedelsleutel opgepakt.,Plukket opp en rød hodeskallenøkkel.,Zebrano czerwoną czaszkę.,Pegou uma chave-crânio vermelha.,Apanhaste uma chave crânio vermelha.,Ai ridicat o cheie craniu roșie.,Получен красный череп-ключ.,Покупили сте црвени кључ лобање.,Plockade upp en röd dödskalle-nyckel.,Kırmızı kafatası anahtarı aldı. +Invulnerability!,GOTINVUL,,,,Nezranitelnost!,Udsårbarhed!,Unverwundbarkeit!,Αθανασία!,Nevundebleco!,¡Invulnerabilidad!,,Haavoittumattomuus!,Invulnérabilité!,Sérthetetlenség!,Invulnerabilità!,不死身だ!,무적!,Onkwetsbaarheid!,Usårbarhet!,Niezniszczalność!,Invulnerabilidade!,,Invincibilitate!,Неуязвимость!,Нерањивост!,Osårbarhet!,Dokunulmazlık! +Berserk!,GOTBERSERK,,,,,,,Μανία!,Furiozigaĵo!,¡Berserker!,,Raivo!,,Dühödt mód!,,バーサーク!,광전사!,,,Szał!,Frenesi!,,Forță amplificată!,Берсерк!,Берсерк!,, +Partial Invisibility,GOTINVIS,,,,Částečná neviditelnost,Delvis usynlighed,Teilweise Unsichtbarkeit,Ημη-αoρατότητα,Parta nevidebleco,Invisibilidad parcial,,Osittainen näkymättömyys,Invisibilité Partielle,Részleges láthatatlanság,Invisibilità parziale,半透明化スフィア,일시적 투명 효과!,Gedeeltelijke onzichtbaarheid,Delvis usynlighet,Częściowa niewidzialność,Invisibilidade parcial,,Invizibilitate parțială,Частичная невидимость.,Делимична невидљивост,Partiell osynlighet,Kısmi Görünmezlik +Radiation Shielding Suit,GOTSUIT,,,,Ochranný oblek proti radioaktivitě,Stråleafskærmningsdragt,Strahlenschutzanzug.,Προστατευτηκή Στολή,Radiado-ŝirma vesto,Traje antiradiación,,Säteilysuojapuku,Combinaison Hazmat,Védőruha,Tuta anti-radiazioni,放射線防護服 ,방사능 보호복,Stralingsbeschermingspak,Strålingsskjermingsdrakt,Kombinezon przeciwradiacyjny,Traje antirradiação,Fato anti-radiação,Costum de protecție împotriva radiaților,Костюм радиационной защиты.,Одело против радијације,Strålningsskyddande dräkt,Radyasyon Koruyucu Giysi +Computer Area Map,GOTMAP,,,,Počítačová mapa,Computerkort.,Computerkarte.,Τοπικός Χάρτης,Komputila mapo de areo,Mapa ordenador del área,Mapa computadora del área,Alueen tietokonekartta,Carte Informatique,Térkép,Mappa Completata,コンピューターエリアマップ,구역 지도 컴퓨터,Computerkaart,Datakart,Komputerowa mapa obszaru,Mapa completo,,Hartă completă,Компьютерная карта уровня.,Компјутерска мапа нивоа,Karta över datorområdet,Bilgisayar Alanı Haritası Light Amplification Visor,GOTVISOR,,,,Noktovizor,Lysforstærkningsvisir,Lichtverstärkungsgerät,Νυχτερινή Όραση,Vizilo de luma amplifikado,Visor de amplificación de luz,,Valonvahvistusvisiiri,Lunettes de Vision Nocturne,Éjjellátó sisak,Amplificatore di luce,"暗視バイザー -",야간투시 바이저,Lichtversterkingsvizier,Lysforsterkende visir,Gogle noktowizyjne,Visor de amplificação de luz,Visor de amplificação luminosa,Vedere amplificată,Очки ночного видения.,Ноћни визир,Işık Amplifikasyon Vizörü -MegaSphere!,GOTMSPHERE,,,,MegaSféra!,,MegaSphäre!,Μεγασφαίρα!,Supera sfero!,¡MegaEsfera!,,Megakuula!,Mégasphère!,MegaGömb!,MegaSfera!,メガスフィアー!,메가스피어!,,,Megasfera!,Megaesfera!,,Megasferă!,Мегасфера!,Мегасфера!,MegaSfer! -Picked up a clip.,GOTCLIP,,,,Sebrán zásobník.,Hentede et magasin med kugler.,Magazin genommen.,Πήρες ένα κουτάκι σφαιρών.,Vi trovis magazenon.,Encuentras un cargador.,Hallaste un cargador.,Poimit lippaan.,Chargeur récupéré.,Felvettél egy töltényt.,Raccolto un caricatore.,弾倉を拾った。,탄창을 얻었다.,Je hebt een patroon opgepakt.,Plukket opp et magasin.,Zebrano magazynek.,Pegou um carregador.,Apanhaste um carregador,Ai ridicat un cartuș.,Получен магазин.,Покупили сте оквир.,Bir şarjör aldım. -Picked up a box of bullets.,GOTCLIPBOX,,,,Sebrána krabice s kulkami.,Hentede en kasse med kugler.,Kiste mit Pistolenkugeln genommen.,Πήρες ένα κουτί με σφαίρες.,Vi trovis skatolon da kugloj.,Encuentras una caja de balas.,Hallaste una caja de balas.,Poimit laatikollisen luoteja.,Boîte de balles récupérée.,Felvettél egy doboz töltényt.,Raccolta una scatola di proiettili.,弾薬箱を拾った。,실탄 탄통을 얻었다.,Je hebt een doos kogels opgepakt.,Plukket opp en eske med kuler.,Zebrano pudełko z nabojami.,Pegou uma caixa de balas.,Apanhaste uma caixa de balas,Ai ridicat o cutie cu gloanțe.,Получена коробка патронов.,Покупили сте кутију метака.,Bir kutu mermi aldı. -Picked up a rocket.,GOTROCKET,,,,Sebrána raketa.,Hentede en raket.,Rakete genommen,Πήρες ένα πύραυλο.,Vi trovis misilon.,Encuentras un misil.,Hallaste un misil.,Poimit raketin.,Roquette récupérée.,Felvettél egy rakétát.,Raccolto un razzo.,ロケットを拾った。,로켓을 얻었다.,Je hebt een raket opgepakt.,Plukket opp en rakett.,Zebrano rakietę.,Pegou um foguete.,Apanhaste um míssil,Ai ridicat o rachetă.,Получена ракета.,Покупили сте ракету.,Bir roket aldı. -Picked up a box of rockets.,GOTROCKBOX,,,,Sebrána krabice s raketami.,Hentede en kasse med raketter.,Kiste mit Raketen genommen.,Πήρες ένα κουτί με πυράυλους.,Vi trovis keston da misiloj.,Encuentras una caja de misiles.,Hallaste una caja de misiles.,Poimit laatikollisen raketteja.,Caisse de roquettes récupérée.,Felvettél egy doboz rakétát.,Raccolta una cassa di razzi.,ロケット箱を拾った。,로켓 상자를 얻었다.,Je hebt een doos raketten opgepakt.,Plukket opp en eske med raketter.,Zebrano pudełko z rakietami.,Pegou uma caixa de foguetes.,Apanhaste uma caixa de mísseis,Ai ridicat o cutie cu rachete.,Получен ящик ракет.,Покупили сте кутију ракета.,Bir kutu roket aldı. -Picked up an energy cell.,GOTCELL,,,,Sebrán energetický článek.,Hentede en energicelle.,Energiezelle genommen.,Πήρες ένα κύτταρο ενέργιας.,Vi trovis energiĉelon.,Encuentras una célula de energía.,Hallaste una célula de energía.,Poimit energia-akun.,Cellule énergétique récupérée.,Felvettél egy energia cellát.,Raccolta una batteria.,エネルギーセルを拾った。,에너지 셀을 얻었다.,Je hebt een energiecel opgepakt.,Plukket opp en energicelle.,Zebrano ogniwo energetyczne.,Pegou uma célula de energia.,Apanhaste uma célula de energia,Ai ridicat o celulă cu energie.,Получена энергобатарея.,Покупили сте енергетску ћелију.,Bir enerji hücresi aldı. -Picked up an energy cell pack.,GOTCELLBOX,,,,Sebrán svazek energetických článků.,Hentede en energicellepakke.,Energiezellenpackung genommen.,Πήρες ένα πακέτο κύτταρων ενέργιας.,Vi trovis energiĉelo-pakon.,Encuentras un paquete de células de energía.,Hallaste un paquete de células de energía.,Poimit energia-akkupaketin.,Pack de cellules énergétiques récupéré.,Felvettél egy doboznyi energia cellát.,Raccolta una confezione di batterie.,エネルギーセルパックを拾った。,대용량 에너지 셀을 얻었다.,Je hebt een energiecelpakket opgepakt.,Plukket opp en energipakke.,Zebrano paczkę ogniw energetycznych.,Pegou um pacote de células de energia.,Apanhaste um pacote de células de energia.,Ai ridicat un pachet de celule cu energie.,Получен комплект энергобатарей.,Покупили сте паковање енергетских ћелија.,Bir enerji hücresi paketi aldı. -Picked up 4 shotgun shells.,GOTSHELLS,,,,Sebrány 4 broky.,Hentede 4 haglpatroner.,4 Schrotflintenpatronen genommen,Πήρες τέσσερεις σφάιρες ντουγεκιόυ.,Vi trovis 4 kartoĉojn.,Encuentras 4 cartuchos de escopeta.,Hallaste 4 cartuchos de escopeta.,Poimit 4 haulikon patruunaa.,4 cartouches récupérées.,Felvettél 4 sörétes töltényt.,Raccolte 4 cartucce per fucile.,4発の散弾を拾った。,샷건 쉘 4개를 얻었다.,Je hebt 4 jachtgeweerkogels opgepakt.,Plukket opp 4 haglpatroner.,Zebrano 4 loftki do strzelby.,Pegou 4 cartuchos de espingarda.,Apanhaste 4 cartuchos de espingarda.,Ai ridicat 4 proiectile pentru pușcă.,Получено 4 патрона для дробовика.,Покупили сте 4 патроне од пумпарице.,4 av tüfeği mermisi aldı. -Picked up a box of shotgun shells.,GOTSHELLBOX,,,,Sebrána krabice s broky.,Hentede en kasse med haglpatroner.,Kiste mit Schrotflintenpatronen genommen.,Πήρες ένα κουτί με σφάιρες ντουγεκιόυ.,Vi trovis skatolon da kartoĉoj.,Encuentras una caja de cartuchos de escopeta.,Hallaste una caja de cartuchos de escopeta.,Poimit laatikollisen haulikon patruunoita.,Boîte de cartouches récupérée.,Felvettél egy doboz sörétes töltényt.,Raccolta una scatola di cartucce per fucile.,散弾箱を拾った。,샷건 쉘 보관함을 얻었다.,Je hebt een doos jachtgeweerkogels opgepakt.,Plukket opp en eske med haglepatroner.,Zebrano pudełko loftek do strzelby.,Pegou uma caixa de cartuchos de espingarda.,Apanhaste uma caixa de cartuchos de espingarda,Ai ridicat o cutie cu proiectile pentru pușcă.,Получена коробка патронов для дробовика.,Покупили сте кутију патрона од пумпарице.,Bir kutu av tüfeği mermisi aldı. -Picked up a backpack full of ammo!,GOTBACKPACK,,,,Sebrán batoh s haldou munice!,Hentede en rygsæk fuld af ammunition!,Rucksack mit Munition genommen.,Πήρες μια τσάντα γεμάτη με πυρομαχικά!,Vi trovis tornistron plena de municioj!,¡Encuentras una mochila llena de munición!,¡Hallaste una mochila llena de munición!,Poimit repun täynnä ammuksia!,Sac à dos plein de munitions récupéré!,Felvettél egy tölténnyel teli hátizsákot!,Raccolto uno zaino zeppo di munizioni!,弾薬の入ったバックパックを手に入れた!,탄약이 들어있는 배낭을 얻었다!,Je hebt een rugzak vol munitie opgepakt!,Plukket opp en ryggsekk full av ammunisjon!,Zebrano plecak pełen amunicji!,Pegou uma mochila cheia de munição!,Apanhaste uma mochila cheia de munição,Ai ridicat o raniță plină cu muniție!,"Получен рюкзак, полный патронов!",Покупили сте ранац с патронама!,Cephane dolu bir sırt çantası aldı! -"You got the BFG9000! Oh, yes.",GOTBFG9000,,,,"Sebráno BFG9000! Ó, ano!","Du fik BFG9000! Åh, ja.","Das BFG9000! Oh, ja!","Πήρες το BFG9000! ο, ΝΑΊ.","Vi trovis BFG9000! Ho, jes.",¡Encuentras una BFG9000! Qué guay.,¡Hallaste una BFG9000! Genial.,Sait BFG9000:n! Voi kyllä.,"UN BFG9000! OH, OUI!",Felvetted a BFG9000-et! Ezaz.,"Hai trovato il BFG9000! Eh, sì!",BFG9000を手に入れた!やったぜ。,당신은 BFG9000을 습득했다! 오우 예.,Je hebt de BFG9000! Jawel.,"Du har BFG9000! Å, ja.","Zebrano BFG9000! O, tak.","Você pegou a BFG! Ah, que delícia!","Apanhaste a BFG9000! Oh, SIM!","Ai pus mâna pe BFG9000! Oh, da.","У вас BFG9000! О, да!","Покупили сте ВЈП9000! О, да.","BFG9000'i aldın! Oh, evet." -You got the chaingun!,GOTCHAINGUN,,,,Sebrán kulomet.,Du har et maskingevær!,Maschinengewehr genommen.,Πήρες το πολυβόλο.,Vi trovis maŝinpafilon!,¡Encuentras una ametralladora!,¡Hallaste una ametralladora!,Sait Gatling-konekiväärin!,Une MITRAILLEUSE!,Felvetted a golyószórót!,Hai trovato un mitragliatore!,チェーンガンを手に入れた!,당신은 체인건을 습득했다!,Je hebt het machinegeweer!,Du har en maskinpistol!,Zebrano karabin maszynowy!,Você pegou a metralhadora!,Apanhaste a metrelhadora!,Ai pus mâna pe mitraliera rotativă!,Получен пулемёт!,Покупили сте митраљез!,Silahı aldın! -A chainsaw! Find some meat!,GOTCHAINSAW,,,,Motorová pila! Najdi maso!,En motorsav! Find noget kød!,Eine Kettensäge. Such mir etwas Fleisch!,Ένα αλυσοπρίονο! Βρες κρέας!,Ĉensegilo! Trovu ian karnon!,¡Una motosierra! ¡Busca algo de carne!,,Moottorisaha! Mene etsimään lihaa!,Une TRONCONNEUSE! Viande frâiche!,Egy láncfűrész! Keress valami aprítanivalót!,Una motosega! Trova un pò di carne!,チェーンソウだ!肉を寄越せ!,당신은 전기톱을 습득했다! 도륙할 시간!,Een kettingzaag! Vind vlees!,En motorsag! Finn litt kjøtt!,Piła łańcuchowa! Znajdź trochę mięsa!,Uma motoserra! Encontre alguma carne!,Uma motoserra! Bora encontrar alguma carne!,O drujbă! Găsește niște carne!,Бензопила! Найди немного мяса!,Тестера! Нађи месо!,Elektrikli testere! Biraz et bul! -You got the rocket launcher!,GOTLAUNCHER,,,,Sebrán raketomet.,Du har en raketkaster!,Raketenwerfer genommen.,Πήρες το πυραβλοβόλο.,Vi trovis misilpafilon!,¡Encuentras un lanzamisiles!,¡Hallaste un lanzamisiles!,Sait singon!,Un LANCE-ROQUETTES!,Felvetted a rakétavetőt!,Hai trovato un lanciarazzi!,ロケットランチャーを手に入れた!,당신은 로켓 런쳐를 습득했다!,Je hebt de raketwerper!,Du har rakettkasteren!,Zebrano wyrzutnię rakiet!,Você pegou um lança-foguetes!,Apanhaste um lança-mísseis!,Ai pus mâna pe lansatorul de rachete!,Получен ракетомёт!,Покупили сте ракетни бацач!,Roketatarı aldın! -You got the plasma gun!,GOTPLASMA,,,,Sebrána plazmová puška.,Du har plasmapistolen!,Plasma-Gewehr genommen.,Πήρες το όπλο πλάσματος!,Vi trovis plasmo-pafilon!,¡Encuentras un fusil de plasma!,¡Hallaste un fusil de plasma!,Sait plasmapyssyn!,Un FUSIL A PLASMA!,Felvetted a plazmafegyvert!,Hai trovato un fucile al plasma!,プラズマライフルを手に入れた!,당신은 플라즈마 건을 습득했다!,Je hebt het plasmageweer!,Du har plasmapistolen!,Zebrano karabin plazmowy!,Você pegou o fuzil de plasma!,Apanhaste uma pistola de plasma!,Ai pus mâna pe arma cu plasmă!,Получен плазмомёт!,Покупили сте плазма оружје!,Plazma silahın var! -You got the shotgun!,GOTSHOTGUN,,,,Sebrána brokovnice.,Du har et haglgevær!,Schrotflinte genommen.,Πήρες το ντουφέκι!,Vi trovis kartoĉan fusilon!,¡Encuentras una escopeta!,¡Hallaste una escopeta!,Sait haulikon!,Un FUSIL A POMPE!,Felvetted a puskát!,Hai trovato un fucile!,ショットガンを手に入れた!,당신은 샷건을 습득했다!,Je hebt het jachtgeweer!,Du har haglen!,Zebrano strzelbę!,Você pegou a espingarda!,Apanhaste uma espingarda.,Ai pus mâna pe pușcă!,Получен дробовик!,Покупили сте пумпарицу!,Pompalı tüfeğin var! -You got the super shotgun!,GOTSHOTGUN2,,,,Sebrána superbrokovnice.,Du har et super-haglgevær!,Super-Schrotflinte genommen.,Πήρες το διπλό ντουφέκι!,Vi trovis dutuban fusilon!,¡Encuentras una superescopeta!,¡Hallaste una superescopeta!,Sait superhaulikon!,Un SUPER FUSIL DE CHASSE!,Felvetted a Szuper puskát!,Hai trovato una doppietta!,スーパーショットガンを手に入れた!,당신은 슈퍼 샷건을 습득했다!,Je hebt het superjachtgeweer!,Du har supergeværet!,Zebrano super strzelbę!,Você pegou uma espingarda de cano duplo!,Apanhaste uma espingarda de cano duplo!,Ai pus mâna pe super pușcă!,Получен супердробовик!,Покупили сте двоцевку!,Süper av tüfeğini aldın! -Picked up a pistol.,PICKUP_PISTOL_DROPPED,,,,Sebrána pistole.,Du har fået en pistol.,Pistole genommen.,Πήρες ενα πιστόλι.,Prenis pistolon.,Una pistola.,,Poimit pistoolin.,Un PISTOLET.,Felvettél egy pisztolyt.,Raccolta una pistola.,ピストルを拾った。,권총을 주웠다.,Je hebt het pistool opgepakt.,Plukket opp en pistol.,Zebrano pistolet.,Pegou uma pistola.,Apanhaste uma pistola.,Ai ridicat un pistol.,Получен пистолет.,Покупили сте пиштољ.,Bir tabanca aldın. -You pick up a demonic dagger.,BETA_BONUS1,,,,Sebrána démonická dýka.,Du har samlet en dæmonisk dolk op.,Dämonischen Dolch genommen.,Πήρες ένα δαιμονικό μαχαίρι.,Vi trovis demonan ponardon.,Encuentras una daga demoníaca.,Hallaste una daga demoníaca.,Poimit demonisen tikarin.,Dague diabolique récupérée.,Felvettél egy démoni tőrt.,Hai raccolto un pugnale demoniaco.,デモニックダガーを拾った。,당신은 마귀내린 단검을 얻었다.,Je hebt een demonische dolk opgepakt.,Du plukket opp en demonisk dolk.,Zebrano demoniczny sztylet.,Você pegou uma adaga demoníaca.,Apanhaste uma navalha demoníaca.,Ai ridicat un pumnal demonic.,Вы подобрали демонический кинжал.,Купите демонски бодеж.,Şeytani bir hançer aldın. -You pick up a skullchest.,BETA_BONUS2,,,,Sebrána lebkotruhla.,Du samler en kraniekasse op.,Schädelkiste genommen.,Πήρες ένα κρανομπαούλο.,Vi trovis kraniokeston.,Encuentras un cofre de calaveras.,Hallaste un cofre de calaveras.,Poimit kalloarkun.,Coffre-crâne récupéré.,Felvettél egy skullchest-et.,Hai raccolto un cofanetto del teschio.,スカルチェストを拾った。,당신은 해골상자를 얻었다.,Je hebt een schedelborst opgepakt.,Du plukker opp en hodeskalle.,Zebrano skrzynię czaszki.,Você pegou um cofre-caveira.,Apanhaste um cofre caveira.,Ai ridicat o cutie cu craniu.,Вы подобрали сундук с черепом.,Купите ковчег с лобањом.,Bir kafatası sandığı aldın. -You pick up an evil sceptre.,BETA_BONUS3,,,,Sebráno zlé žezlo.,Du samler et ondt scepter op.,Teuflisches Zepter genommen.,Πήρες το μοχθηρό σκήπτρο.,Vi trovis malbonan sceptron.,Encuentras un cetro del mal.,Hallaste un cetro del mal.,Poimit pahan valtikan.,Sceptre maléfique récupéré.,Felvettél egy gonosz jogart.,Hai raccolto uno scettro del male.,エビルセプターを拾った。,당신은 사악한 홀을 얻었다.,Je hebt een kwaadaardige scepter opgepakt.,Du plukker opp et ondt septer.,Zebrano złe berło.,Você pegou um cetro maligno.,Apanhaste um cetro maligno,Ai ridicat un sceptru malefic.,Вы подобрали скипетр зла.,Купите зли скиптар.,Şeytani bir asa alıyorsun. -You pick up an unholy bible.,BETA_BONUS4,,,,Sebrána bezbožná bible.,Du samler en uhellig bibel op.,Unheilige Bibel genommen,Πήρες τήν ανίερη βίβλο.,Vi trovis malsanktan biblion.,Encuentras una biblia profana.,Hallaste una biblia profana.,Poimit epäpyhän raamatun.,Bible profane récupérée.,Felvettél egy istentelen bibliát.,Hai raccolto una bibbia profana.,アンホーリーバイブルを拾った。,당신은 불경스러운 성서를 얻었다.,Je hebt een onheilige bijbel opgepakt.,Du plukker opp en uhellig bibel.,Zebrano nieświętą biblię.,Você pegou uma bíblia profana.,Apanhaste uma bíblia profana.,Ai ridicat o biblie nesfântă.,Вы подобрали порочную библию.,Купите несвету библију.,Kutsal olmayan bir İncil aldın. -,,Locks,,,,,,,,,,,,,,,,,,,,,,,, +",야간투시 바이저,Lichtversterkingsvizier,Lysforsterkende visir,Gogle noktowizyjne,Visor de amplificação de luz,Visor de amplificação luminosa,Vedere amplificată,Очки ночного видения.,Ноћни визир,Ljusförstärkande visir,Işık Amplifikasyon Vizörü +MegaSphere!,GOTMSPHERE,,,,MegaSféra!,,MegaSphäre!,Μεγασφαίρα!,Supera sfero!,¡MegaEsfera!,,Megakuula!,Mégasphère!,MegaGömb!,MegaSfera!,メガスフィアー!,메가스피어!,,,Megasfera!,Megaesfera!,,Megasferă!,Мегасфера!,Мегасфера!,,MegaSfer! +Picked up a clip.,GOTCLIP,,,,Sebrán zásobník.,Hentede et magasin med kugler.,Magazin genommen.,Πήρες ένα κουτάκι σφαιρών.,Vi trovis magazenon.,Encuentras un cargador.,Hallaste un cargador.,Poimit lippaan.,Chargeur récupéré.,Felvettél egy töltényt.,Raccolto un caricatore.,弾倉を拾った。,탄창을 얻었다.,Je hebt een patroon opgepakt.,Plukket opp et magasin.,Zebrano magazynek.,Pegou um carregador.,Apanhaste um carregador,Ai ridicat un cartuș.,Получен магазин.,Покупили сте оквир.,Plockade upp ett klipp.,Bir şarjör aldım. +Picked up a box of bullets.,GOTCLIPBOX,,,,Sebrána krabice s kulkami.,Hentede en kasse med kugler.,Kiste mit Pistolenkugeln genommen.,Πήρες ένα κουτί με σφαίρες.,Vi trovis skatolon da kugloj.,Encuentras una caja de balas.,Hallaste una caja de balas.,Poimit laatikollisen luoteja.,Boîte de balles récupérée.,Felvettél egy doboz töltényt.,Raccolta una scatola di proiettili.,弾薬箱を拾った。,실탄 탄통을 얻었다.,Je hebt een doos kogels opgepakt.,Plukket opp en eske med kuler.,Zebrano pudełko z nabojami.,Pegou uma caixa de balas.,Apanhaste uma caixa de balas,Ai ridicat o cutie cu gloanțe.,Получена коробка пуль.,Покупили сте кутију метака.,Plockade upp en låda med kulor.,Bir kutu mermi aldı. +Picked up a rocket.,GOTROCKET,,,,Sebrána raketa.,Hentede en raket.,Rakete genommen,Πήρες ένα πύραυλο.,Vi trovis misilon.,Encuentras un misil.,Hallaste un misil.,Poimit raketin.,Roquette récupérée.,Felvettél egy rakétát.,Raccolto un razzo.,ロケットを拾った。,로켓을 얻었다.,Je hebt een raket opgepakt.,Plukket opp en rakett.,Zebrano rakietę.,Pegou um foguete.,Apanhaste um míssil,Ai ridicat o rachetă.,Получена ракета.,Покупили сте ракету.,Plockade upp en raket.,Bir roket aldı. +Picked up a box of rockets.,GOTROCKBOX,,,,Sebrána krabice s raketami.,Hentede en kasse med raketter.,Kiste mit Raketen genommen.,Πήρες ένα κουτί με πυράυλους.,Vi trovis keston da misiloj.,Encuentras una caja de misiles.,Hallaste una caja de misiles.,Poimit laatikollisen raketteja.,Caisse de roquettes récupérée.,Felvettél egy doboz rakétát.,Raccolta una cassa di razzi.,ロケット箱を拾った。,로켓 상자를 얻었다.,Je hebt een doos raketten opgepakt.,Plukket opp en eske med raketter.,Zebrano pudełko z rakietami.,Pegou uma caixa de foguetes.,Apanhaste uma caixa de mísseis,Ai ridicat o cutie cu rachete.,Получен ящик ракет.,Покупили сте кутију ракета.,Plockade upp en låda med raketer.,Bir kutu roket aldı. +Picked up an energy cell.,GOTCELL,,,,Sebrán energetický článek.,Hentede en energicelle.,Energiezelle genommen.,Πήρες ένα κύτταρο ενέργιας.,Vi trovis energiĉelon.,Encuentras una célula de energía.,Hallaste una célula de energía.,Poimit energia-akun.,Cellule énergétique récupérée.,Felvettél egy energia cellát.,Raccolta una batteria.,エネルギーセルを拾った。,에너지 셀을 얻었다.,Je hebt een energiecel opgepakt.,Plukket opp en energicelle.,Zebrano ogniwo energetyczne.,Pegou uma célula de energia.,Apanhaste uma célula de energia,Ai ridicat o celulă cu energie.,Получена энергобатарея.,Покупили сте енергетску ћелију.,Plockade upp en energicell.,Bir enerji hücresi aldı. +Picked up an energy cell pack.,GOTCELLBOX,,,,Sebrán svazek energetických článků.,Hentede en energicellepakke.,Energiezellenpackung genommen.,Πήρες ένα πακέτο κύτταρων ενέργιας.,Vi trovis energiĉelo-pakon.,Encuentras un paquete de células de energía.,Hallaste un paquete de células de energía.,Poimit energia-akkupaketin.,Pack de cellules énergétiques récupéré.,Felvettél egy doboznyi energia cellát.,Raccolta una confezione di batterie.,エネルギーセルパックを拾った。,대용량 에너지 셀을 얻었다.,Je hebt een energiecelpakket opgepakt.,Plukket opp en energipakke.,Zebrano paczkę ogniw energetycznych.,Pegou um pacote de células de energia.,Apanhaste um pacote de células de energia.,Ai ridicat un pachet de celule cu energie.,Получен комплект энергобатарей.,Покупили сте паковање енергетских ћелија.,Plockade upp ett energicellpaket.,Bir enerji hücresi paketi aldı. +Picked up 4 shotgun shells.,GOTSHELLS,,,,Sebrány 4 broky.,Hentede 4 haglpatroner.,4 Schrotflintenpatronen genommen,Πήρες τέσσερεις σφάιρες ντουγεκιόυ.,Vi trovis 4 kartoĉojn.,Encuentras 4 cartuchos de escopeta.,Hallaste 4 cartuchos de escopeta.,Poimit 4 haulikon patruunaa.,4 cartouches récupérées.,Felvettél 4 sörétes töltényt.,Raccolte 4 cartucce per fucile.,4発の散弾を拾った。,샷건 쉘 4개를 얻었다.,Je hebt 4 jachtgeweerkogels opgepakt.,Plukket opp 4 haglpatroner.,Zebrano 4 loftki do strzelby.,Pegou 4 cartuchos de espingarda.,Apanhaste 4 cartuchos de espingarda.,Ai ridicat 4 proiectile pentru pușcă.,Получено 4 патрона дробовика.,Покупили сте 4 патроне од пумпарице.,Plockade upp 4 hagelpatroner.,4 av tüfeği mermisi aldı. +Picked up a box of shotgun shells.,GOTSHELLBOX,,,,Sebrána krabice s broky.,Hentede en kasse med haglpatroner.,Kiste mit Schrotflintenpatronen genommen.,Πήρες ένα κουτί με σφάιρες ντουγεκιόυ.,Vi trovis skatolon da kartoĉoj.,Encuentras una caja de cartuchos de escopeta.,Hallaste una caja de cartuchos de escopeta.,Poimit laatikollisen haulikon patruunoita.,Boîte de cartouches récupérée.,Felvettél egy doboz sörétes töltényt.,Raccolta una scatola di cartucce per fucile.,散弾箱を拾った。,샷건 쉘 보관함을 얻었다.,Je hebt een doos jachtgeweerkogels opgepakt.,Plukket opp en eske med haglepatroner.,Zebrano pudełko loftek do strzelby.,Pegou uma caixa de cartuchos de espingarda.,Apanhaste uma caixa de cartuchos de espingarda,Ai ridicat o cutie cu proiectile pentru pușcă.,Получена коробка патронов дробовика.,Покупили сте кутију патрона од пумпарице.,Plockade upp en låda med hagelpatroner.,Bir kutu av tüfeği mermisi aldı. +Picked up a backpack full of ammo!,GOTBACKPACK,,,,Sebrán batoh s haldou munice!,Hentede en rygsæk fuld af ammunition!,Rucksack mit Munition genommen.,Πήρες μια τσάντα γεμάτη με πυρομαχικά!,Vi trovis tornistron plena de municioj!,¡Encuentras una mochila llena de munición!,¡Hallaste una mochila llena de munición!,Poimit repun täynnä ammuksia!,Sac à dos plein de munitions récupéré!,Felvettél egy tölténnyel teli hátizsákot!,Raccolto uno zaino zeppo di munizioni!,弾薬の入ったバックパックを手に入れた!,탄약이 들어있는 배낭을 얻었다!,Je hebt een rugzak vol munitie opgepakt!,Plukket opp en ryggsekk full av ammunisjon!,Zebrano plecak pełen amunicji!,Pegou uma mochila cheia de munição!,Apanhaste uma mochila cheia de munição,Ai ridicat o raniță plină cu muniție!,"Получен рюкзак, полный патронов!",Покупили сте ранац с патронама!,Plockade upp en ryggsäck full av ammunition!,Cephane dolu bir sırt çantası aldı! +"You got the BFG9000! Oh, yes.",GOTBFG9000,,,,"Sebráno BFG9000! Ó, ano!","Du fik BFG9000! Åh, ja.","Das BFG9000! Oh, ja!","Πήρες το BFG9000! ο, ΝΑΊ.","Vi trovis BFG9000! Ho, jes.",¡Encuentras una BFG9000! Qué guay.,¡Hallaste una BFG9000! Genial.,Sait BFG9000:n! Voi kyllä.,"UN BFG9000! OH, OUI!",Felvetted a BFG9000-et! Ezaz.,"Hai trovato il BFG9000! Eh, sì!",BFG9000を手に入れた!やったぜ。,당신은 BFG9000을 습득했다! 오우 예.,Je hebt de BFG9000! Jawel.,"Du har BFG9000! Å, ja.","Zebrano BFG9000! O, tak.","Você pegou a BFG! Ah, que delícia!","Apanhaste a BFG9000! Oh, SIM!","Ai pus mâna pe BFG9000! Oh, da.","У вас BFG9000! О, да!","Покупили сте ВЈП9000! О, да.","Du fick fått BFG9000! Ja, ja.","BFG9000'i aldın! Oh, evet." +You got the chaingun!,GOTCHAINGUN,,,,Sebrán kulomet.,Du har et maskingevær!,Maschinengewehr genommen.,Πήρες το πολυβόλο.,Vi trovis maŝinpafilon!,¡Encuentras una ametralladora!,¡Hallaste una ametralladora!,Sait Gatling-konekiväärin!,Une MITRAILLEUSE!,Felvetted a golyószórót!,Hai trovato un mitragliatore!,チェーンガンを手に入れた!,당신은 체인건을 습득했다!,Je hebt het machinegeweer!,Du har en maskinpistol!,Zebrano karabin maszynowy!,Você pegou a metralhadora!,Apanhaste a metrelhadora!,Ai pus mâna pe mitraliera rotativă!,Получен пулемёт!,Покупили сте митраљез!,Du fick kedjepistolen!,Silahı aldın! +A chainsaw! Find some meat!,GOTCHAINSAW,,,,Motorová pila! Najdi maso!,En motorsav! Find noget kød!,Eine Kettensäge. Such mir etwas Fleisch!,Ένα αλυσοπρίονο! Βρες κρέας!,Ĉensegilo! Trovu ian karnon!,¡Una motosierra! ¡Busca algo de carne!,,Moottorisaha! Mene etsimään lihaa!,Une TRONCONNEUSE! Viande frâiche!,Egy láncfűrész! Keress valami aprítanivalót!,Una motosega! Trova un pò di carne!,チェーンソウだ!肉を寄越せ!,당신은 전기톱을 습득했다! 도륙할 시간!,Een kettingzaag! Vind vlees!,En motorsag! Finn litt kjøtt!,Piła łańcuchowa! Znajdź trochę mięsa!,Uma motoserra! Encontre alguma carne!,Uma motoserra! Bora encontrar alguma carne!,O drujbă! Găsește niște carne!,Бензопила! Найди немного мяса!,Тестера! Нађи месо!,En motorsåg! Hitta lite kött!,Elektrikli testere! Biraz et bul! +You got the rocket launcher!,GOTLAUNCHER,,,,Sebrán raketomet.,Du har en raketkaster!,Raketenwerfer genommen.,Πήρες το πυραβλοβόλο.,Vi trovis misilpafilon!,¡Encuentras un lanzamisiles!,¡Hallaste un lanzamisiles!,Sait singon!,Un LANCE-ROQUETTES!,Felvetted a rakétavetőt!,Hai trovato un lanciarazzi!,ロケットランチャーを手に入れた!,당신은 로켓 런쳐를 습득했다!,Je hebt de raketwerper!,Du har rakettkasteren!,Zebrano wyrzutnię rakiet!,Você pegou um lança-foguetes!,Apanhaste um lança-mísseis!,Ai pus mâna pe lansatorul de rachete!,Получен ракетомёт!,Покупили сте ракетни бацач!,Du fick raketkastaren!,Roketatarı aldın! +You got the plasma gun!,GOTPLASMA,,,,Sebrána plazmová puška.,Du har plasmapistolen!,Plasma-Gewehr genommen.,Πήρες το όπλο πλάσματος!,Vi trovis plasmo-pafilon!,¡Encuentras un fusil de plasma!,¡Hallaste un fusil de plasma!,Sait plasmapyssyn!,Un FUSIL A PLASMA!,Felvetted a plazmafegyvert!,Hai trovato un fucile al plasma!,プラズマライフルを手に入れた!,당신은 플라즈마 건을 습득했다!,Je hebt het plasmageweer!,Du har plasmapistolen!,Zebrano karabin plazmowy!,Você pegou o fuzil de plasma!,Apanhaste uma pistola de plasma!,Ai pus mâna pe arma cu plasmă!,Получен плазмомёт!,Покупили сте плазма оружје!,Du fick plasmapistolen!,Plazma silahın var! +You got the shotgun!,GOTSHOTGUN,,,,Sebrána brokovnice.,Du har et haglgevær!,Schrotflinte genommen.,Πήρες το ντουφέκι!,Vi trovis kartoĉan fusilon!,¡Encuentras una escopeta!,¡Hallaste una escopeta!,Sait haulikon!,Un FUSIL A POMPE!,Felvetted a puskát!,Hai trovato un fucile!,ショットガンを手に入れた!,당신은 샷건을 습득했다!,Je hebt het jachtgeweer!,Du har haglen!,Zebrano strzelbę!,Você pegou a espingarda!,Apanhaste uma espingarda.,Ai pus mâna pe pușcă!,Получен дробовик!,Покупили сте пумпарицу!,Du fick hagelgeväret!,Pompalı tüfeğin var! +You got the super shotgun!,GOTSHOTGUN2,,,,Sebrána superbrokovnice.,Du har et super-haglgevær!,Super-Schrotflinte genommen.,Πήρες το διπλό ντουφέκι!,Vi trovis dutuban fusilon!,¡Encuentras una superescopeta!,¡Hallaste una superescopeta!,Sait superhaulikon!,Un SUPER FUSIL DE CHASSE!,Felvetted a Szuper puskát!,Hai trovato una doppietta!,スーパーショットガンを手に入れた!,당신은 슈퍼 샷건을 습득했다!,Je hebt het superjachtgeweer!,Du har supergeværet!,Zebrano super strzelbę!,Você pegou uma espingarda de cano duplo!,Apanhaste uma espingarda de cano duplo!,Ai pus mâna pe super pușcă!,Получен супердробовик!,Покупили сте двоцевку!,Du fick super-hagelgeväret!,Süper av tüfeğini aldın! +Picked up a pistol.,PICKUP_PISTOL_DROPPED,,,,Sebrána pistole.,Du har fået en pistol.,Pistole genommen.,Πήρες ενα πιστόλι.,Prenis pistolon.,Una pistola.,,Poimit pistoolin.,Un PISTOLET.,Felvettél egy pisztolyt.,Raccolta una pistola.,ピストルを拾った。,권총을 주웠다.,Je hebt het pistool opgepakt.,Plukket opp en pistol.,Zebrano pistolet.,Pegou uma pistola.,Apanhaste uma pistola.,Ai ridicat un pistol.,Получен пистолет.,Покупили сте пиштољ.,Jag plockade upp en pistol.,Bir tabanca aldın. +You pick up a demonic dagger.,BETA_BONUS1,,,,Sebrána démonická dýka.,Du har samlet en dæmonisk dolk op.,Dämonischen Dolch genommen.,Πήρες ένα δαιμονικό μαχαίρι.,Vi trovis demonan ponardon.,Encuentras una daga demoníaca.,Hallaste una daga demoníaca.,Poimit demonisen tikarin.,Dague diabolique récupérée.,Felvettél egy démoni tőrt.,Hai raccolto un pugnale demoniaco.,デモニックダガーを拾った。,당신은 마귀내린 단검을 얻었다.,Je hebt een demonische dolk opgepakt.,Du plukket opp en demonisk dolk.,Zebrano demoniczny sztylet.,Você pegou uma adaga demoníaca.,Apanhaste uma navalha demoníaca.,Ai ridicat un pumnal demonic.,Вы подобрали демонический кинжал.,Купите демонски бодеж.,Plockade upp en demonisk dolk.,Şeytani bir hançer aldın. +You pick up a skullchest.,BETA_BONUS2,,,,Sebrána lebkotruhla.,Du samler en kraniekasse op.,Schädelkiste genommen.,Πήρες ένα κρανομπαούλο.,Vi trovis kraniokeston.,Encuentras un cofre de calaveras.,Hallaste un cofre de calaveras.,Poimit kalloarkun.,Coffre-crâne récupéré.,Felvettél egy skullchest-et.,Hai raccolto un cofanetto del teschio.,スカルチェストを拾った。,당신은 해골상자를 얻었다.,Je hebt een schedelborst opgepakt.,Du plukker opp en hodeskalle.,Zebrano skrzynię czaszki.,Você pegou um cofre-caveira.,Apanhaste um cofre caveira.,Ai ridicat o cutie cu craniu.,Вы подобрали сундук с черепом.,Купите ковчег с лобањом.,Plockade upp en skalle.,Bir kafatası sandığı aldın. +You pick up an evil sceptre.,BETA_BONUS3,,,,Sebráno zlé žezlo.,Du samler et ondt scepter op.,Teuflisches Zepter genommen.,Πήρες το μοχθηρό σκήπτρο.,Vi trovis malbonan sceptron.,Encuentras un cetro del mal.,Hallaste un cetro del mal.,Poimit pahan valtikan.,Sceptre maléfique récupéré.,Felvettél egy gonosz jogart.,Hai raccolto uno scettro del male.,エビルセプターを拾った。,당신은 사악한 홀을 얻었다.,Je hebt een kwaadaardige scepter opgepakt.,Du plukker opp et ondt septer.,Zebrano złe berło.,Você pegou um cetro maligno.,Apanhaste um cetro maligno,Ai ridicat un sceptru malefic.,Вы подобрали скипетр зла.,Купите зли скиптар.,Plockade upp en ond scepter.,Şeytani bir asa alıyorsun. +You pick up an unholy bible.,BETA_BONUS4,,,,Sebrána bezbožná bible.,Du samler en uhellig bibel op.,Unheilige Bibel genommen,Πήρες τήν ανίερη βίβλο.,Vi trovis malsanktan biblion.,Encuentras una biblia profana.,Hallaste una biblia profana.,Poimit epäpyhän raamatun.,Bible profane récupérée.,Felvettél egy istentelen bibliát.,Hai raccolto una bibbia profana.,アンホーリーバイブルを拾った。,당신은 불경스러운 성서를 얻었다.,Je hebt een onheilige bijbel opgepakt.,Du plukker opp en uhellig bibel.,Zebrano nieświętą biblię.,Você pegou uma bíblia profana.,Apanhaste uma bíblia profana.,Ai ridicat o biblie nesfântă.,Вы подобрали порочную библию.,Купите несвету библију.,Plockade upp en ohelig bibel.,Kutsal olmayan bir İncil aldın. +,,Locks,,,,,,,,,,,,,,,,,,,,,,,,, You need a blue key to activate this object,PD_BLUEO,,,,K aktivaci tohoto objektu potřebuješ modrý klíč.,Du skal bruge en blå nøgle for at aktivere dette objekt,"Du brauchst einen blauen Schlüssel, um dieses Objekt zu aktivieren.",Χρειάζεσε ένα μπλέ κλειδί για να ενεργοποίησεις αυτο το αντικείμενο,Vi bezonas bluan ŝlosilon por aktivigi ĉi tiun objekton,Necesitas una llave azul para activar este objeto,,Tarvitset sinisen avaimen aktivoidaksesi tämän kappaleen,Il vous faut une clé bleue pour activer cet objet.,Egy kék kulcs szükséges az tárgy aktiválásához.,Ti serve una chiave blu per attivare questo oggetto,この装置には ブルーキーが必要だ。,이 물체를 작동시키기 위해선 청색 열쇠가 필요합니다,Je hebt een blauwe sleutel nodig om dit object te activeren.,Du trenger en blå nøkkel for å aktivere denne gjenstanden,"Potrzebujesz niebieskiego klucza, aby aktywować ten przedmiot",Você precisa de uma chave azul para ativar este objeto,Precisas de uma chave azul para ativar este objeto,"Ai nevoie de o cheie albastră pentru a activa acest -obiect",Для применения нужен синий ключ,Треба вам плави кључ да би активирали овај предмет,Bu nesneyi etkinleştirmek için mavi bir anahtara ihtiyacınız var +obiect",Для применения нужен синий ключ,Треба вам плави кључ да би активирали овај предмет,Du behöver en blå nyckel för att aktivera det här föremålet.,Bu nesneyi etkinleştirmek için mavi bir anahtara ihtiyacınız var You need a red key to activate this object,PD_REDO,,,,K aktivaci tohoto objektu potřebuješ červený klíč.,Du skal bruge en rød nøgle for at aktivere dette objekt,"Du brauchst einen roten Schlüssel, um dieses Objekt zu aktivieren.",Χρειάζεσε ένα κόκινο κλειδί για να ενεργοποίησεις αυτο το αντικείμενο,Vi bezonas ruĝan ŝlosilon por aktivigi ĉi tiun objekton,Necesitas una llave roja para activar este objeto,,Tarvitset punaisen avaimen aktivoidaksesi tämän kappaleen,Il vous faut une clé rouge pour activer cet objet.,"Piros kulcs kell, hogy aktiválhasd ezt a tárgyat.",Ti serve una chiave rossa per attivare questo oggetto,この装置には レッドキーが必要だ。,이 물체를 작동시키기 위해선 적색 열쇠가 필요합니다,Je hebt een rode sleutel nodig om dit object te activeren.,Du trenger en rød nøkkel for å aktivere dette objektet,"Potrzebujesz czerwonego klucza, aby aktywować ten przedmiot",Você precisa de uma chave vermelha para ativar este objeto,Precisas de uma chave vermelha para ativar este objeto,"Ai nevoie de o cheie roșie pentru a activa acest -obiect",Для применения нужен красный ключ,Треба вам црвени кључ да би активирали овај предмет,Bu nesneyi etkinleştirmek için kırmızı bir anahtara ihtiyacınız var +obiect",Для применения нужен красный ключ,Треба вам црвени кључ да би активирали овај предмет,Du behöver en röd nyckel för att aktivera det här föremålet.,Bu nesneyi etkinleştirmek için kırmızı bir anahtara ihtiyacınız var You need a yellow key to activate this object,PD_YELLOWO,,,,K aktivaci tohoto objektu potřebuješ žlutý klíč.,Du skal bruge en gul nøgle for at aktivere dette objekt,"Du brauchst einen gelben Schlüssel, um dieses Objekt zu aktivieren.",Χρειάζεσε ένα κύτρινο κλειδί για να ενεργοποίησεις αυτο το αντικείμενο,Vi bezonas flavan ŝlosilon por aktivigi ĉi tiun objekton,Necesitas una llave amarilla para activar este objeto,,Tarvitset keltaisen avaimen aktivoidaksesi tämän kappaleen,Il vous faut une clé jaune pour activer cet objet.,Egy sárga kulccsal aktiválható ez a tárgy,Ti serve una chiave gialla per attivare questo oggetto,この装置にはイエローキーが必要だ。,이 물체를 작동시키기 위해선 황색 열쇠가 필요합니다,Je hebt een gele sleutel nodig om dit object te activeren.,Du trenger en gul nøkkel for å aktivere dette objektet,"Potrzebujesz żółtego klucza, aby aktywować ten przedmiot",Você precisa de uma chave amarela para ativar este objeto,Precisas de uma chave amarela para ativar este objeto,"Ai nevoie de o cheie galbenă pentru a activa acest -obiect",Для применения нужен жёлтый ключ,Треба вам жути кључ да би активирали овај предмет,Bu nesneyi etkinleştirmek için sarı bir anahtara ihtiyacınız var +obiect",Для применения нужен жёлтый ключ,Треба вам жути кључ да би активирали овај предмет,Du behöver en gul nyckel för att aktivera det här föremålet.,Bu nesneyi etkinleştirmek için sarı bir anahtara ihtiyacınız var You need a blue key to open this door,PD_BLUEK,,,,K otevření těchto dveří potřebuješ modrý klíč.,Du skal bruge en blå nøgle for at åbne denne dør,"Du brauchst einen blauen Schlüssel, um diese Tür zu öffnen.",Χρειάζεσε ένα μπλέ κλειδί για να ανοίξεις αυτή τη πόρτα,Vi bezonas bluan ŝlosilon por malfermi ĉi tiun pordon,Necesitas una llave azul para abrir esta puerta,,Tarvitset sinisen avaimen avataksesi tämän oven,Il vous faut une clé bleue pour ouvrir cette porte.,Az ajtót egy kék kulcs nyitja.,Ti serve una chiave blu per aprire questa porta,このドアには ブルーキーが必要だ。,이 문을 열기 위해선 청색 열쇠가 필요합니다,Je hebt een blauwe sleutel nodig om deze deur te openen.,Du trenger en blå nøkkel for å åpne denne døren,"Potrzebujesz niebieskiego klucza, aby otworzyć te drzwi",Você precisa de uma chave azul para abrir esta porta,Precisas de uma chave azul para abrir esta porta,"Ai nevoie de o cheie albastră pentru a deschide -ușa aceasta",Для открытия нужен синий ключ,Треба вам плави кључ да би отворили ова врата,Bu kapıyı açmak için mavi bir anahtara ihtiyacın var. +ușa aceasta",Для открытия нужен синий ключ,Треба вам плави кључ да би отворили ова врата,Du behöver en blå nyckel för att öppna den här dörren,Bu kapıyı açmak için mavi bir anahtara ihtiyacın var. You need a red key to open this door,PD_REDK,,,,K otevření těchto dveří potřebuješ červený klíč.,Du skal bruge en rød nøgle for at åbne denne dør,"Du brauchst einen roten Schlüssel, um diese Tür zu öffnen.",Χρειάζεσε ένα κόκινο κλειδί για να ανοίξεις αυτή τη πόρτα,Vi bezonas ruĝan ŝlosilon por malfermi ĉi tiun pordon,Necesitas una llave roja para abrir esta puerta,,Tarvitset punaisen avaimen avataksesi tämän oven,Il vous faut une clé rouge pour ouvrir cette porte.,"Piros kulcs szükséges, hogy az ajtót kinyithasd.",Ti serve una chiave rossa per aprire questa porta,このドアには レッドキーが必要だ。,이 문을 열기 위해선 적색 열쇠가 필요합니다,Je hebt een rode sleutel nodig om deze deur te openen.,Du trenger en rød nøkkel for å åpne denne døren,"Potrzebujesz czerwonego klucza, aby otworzyć te drzwi",Você precisa de uma chave vermelha para abrir esta porta,Precisas de uma chave vermelha para abrir esta porta,"Ai nevoie de o cheie roșie pentru a deschide ușa -aceasta",Для открытия нужен красный ключ,Треба вам црвени кључ да би отворили ова врата,Bu kapıyı açmak için kırmızı bir anahtara ihtiyacın var. +aceasta",Для открытия нужен красный ключ,Треба вам црвени кључ да би отворили ова врата,Du behöver en röd nyckel för att öppna den här dörren,Bu kapıyı açmak için kırmızı bir anahtara ihtiyacın var. You need a yellow key to open this door,PD_YELLOWK,,,,K otevření těchto dveří potřebuješ žlutý klíč.,Du skal bruge en gul nøgle for at åbne denne dør,"Du brauchst einen gelben Schlüssel, um diese Tür zu öffnen.",Χρειάζεσε ένα κύτρινο κλειδί για να ανοίξεις αυτή τη πόρτα,Vi bezonas flavan ŝlosilon por malfermi ĉi tiun pordon,Necesitas una llave amarilla para abrir esta puerta,,Tarvitset keltaisen avaimen avataksesi tämän oven,Il vous faut une clé jaune pour ouvrir cette porte.,Kell egy sárga kulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave gialla per aprire questa porta,このドアには イエローキー が必要だ。,이 문을 열기 위해선 황색 열쇠가 필요합니다,Je hebt een gele sleutel nodig om deze deur te openen.,Du trenger en gul nøkkel for å åpne denne døren,"Potrzebujesz żółtego klucza, aby otworzyć te drzwi",Você precisa de uma chave amarela para abrir esta porta,Precisas de uma chave amarela para abrir esta porta,"Ai nevoie de o cheie galbena pentru a deschide ușa -aceasta",Для открытия нужен жёлтый ключ,Треба вам жути кључ да би отворили ова врата,Bu kapıyı açmak için sarı bir anahtara ihtiyacınız var +aceasta",Для открытия нужен жёлтый ключ,Треба вам жути кључ да би отворили ова врата,Du behöver en gul nyckel för att öppna den här dörren.,Bu kapıyı açmak için sarı bir anahtara ihtiyacınız var You need a blue card to activate this object,PD_BLUECO,,,,K aktivaci tohoto objektu potřebuješ modrou kartu.,Du skal bruge et blåt kort for at aktivere denne objekt,"Du brauchst eine blaue Schlüsselkarte, um dieses Objekt zu aktivieren.",Χρειάζεσε μια μπλέ κάρτα για να ενεργοποίησεις αυτο το αντικείμενο,Vi bezonas bluan karton por aktivigi ĉi tiun objekton,Necesitas una tarjeta azul para activar este objeto,,Tarvitset sinisen avainkortin aktivoidaksesi tämän kappaleen,Il vous faut une carte bleue pour activer cet objet.,"Egy kék kártya kell, hogy ezt a tárgyat aktiválhasd",Ti serve una card d'accesso blu per attivare questo oggetto ,この装置には ブルーカード が必要だ。,이 물체를 작동시키기 위해선 청색 키카드가 필요합니다,Je hebt een blauwe sleutelkaart nodig om dit voorwerp te activeren.,Du trenger et blått kort for å aktivere dette objektet,"Potrzebujesz niebieskiej karty, aby aktywować ten obiekt",Você precisa de um cartão de acesso azul para ativar este objeto,Precisas de um cartão de acesso azul para ativar este objeto,"Ai nevoie de un card albastru pentru a activa -acest obiect",Для применения нужен синий ключ,Треба вам плава карта да би активирали овај предмет,Bu nesneyi etkinleştirmek için mavi bir karta ihtiyacınız var +acest obiect",Для применения нужна синяя карта,Треба вам плава карта да би активирали овај предмет,Du behöver ett blått kort för att aktivera det här objektet.,Bu nesneyi etkinleştirmek için mavi bir karta ihtiyacınız var You need a red card to activate this object,PD_REDCO,,,,K aktivaci tohoto objektu potřebuješ červenou kartu.,Du skal bruge et rødt kort for at aktivere denne objekt,"Du brauchst eine rote Schlüsselkarte, um dieses Objekt zu aktivieren.",Χρειάζεσε μια κόκινη κάρτα για να ενεργοποίησεις αυτο το αντικείμενο,Vi bezonas ruĝan karton por aktivigi ĉi tiun objekton,Necesitas una tarjeta roja para activar este objeto,,Tarvitset punaisen avainkortin aktivoidaksesi tämän kappaleen,Il vous faut une carte rouge pour activer cet objet.,Piros kártyával aktiválható ez a tárgy,Ti serve una card d'accesso rossa per attivare questo oggetto ,この装置には レッドカード が必要だ。,이 물체를 작동시키기 위해선 적색 키카드가 필요합니다,Je hebt een rode sleutelkaart nodig om dit voorwerp te activeren.,Du trenger et rødt kort for å aktivere dette objektet,"Potrzebujesz czerwonej karty, aby aktywować ten obiekt",Você precisa de um cartão de acesso vermelho para ativar este objeto,Precisas de um cartão de acesso vermelho para ativar este objeto,"Ai nevoie de un card roșu pentru a activa -acest obiect",Для применения нужен красный ключ,Треба вам црвена карта да би активирали овај предмет,Bu nesneyi etkinleştirmek için kırmızı bir karta ihtiyacınız var +acest obiect",Для применения нужна красная карта,Треба вам црвена карта да би активирали овај предмет,Du behöver ett rött kort för att aktivera det här föremålet.,Bu nesneyi etkinleştirmek için kırmızı bir karta ihtiyacınız var You need a yellow card to activate this object,PD_YELLOWCO,,,,K aktivaci tohoto objektu potřebuješ žlutou kartu.,Du skal bruge et gult kort for at aktivere denne objekt,"Du brauchst eine gelbe Schlüsselkarte, um dieses Objekt zu aktivieren.",Χρειάζεσε μια κύτρινη κάρτα για να ενεργοποίησεις αυτο το αντικείμενο,Vi bezonas flavan karton por aktivigi ĉi tiun objekton,Necesitas una tarjeta amarilla para activar este objeto,,Tarvitset keltaisen avainkortin aktivoidaksesi tämän kappaleen,Il vous faut une carte jaune pour activer cet objet.,Kell egy sárga kártya hogy aktiváld ezt a tárgyat,ti serve una card d'accesso gialla per attivare questo oggetto ,この装置には イエローカード が必要だ。,이 물체를 작동시키기 위해선 황색 키카드가 필요합니다,Je hebt een gele sleutelkaart nodig om dit voorwerp te activeren.,Du trenger et gult kort for å aktivere dette objektet,"Potrzebujesz żółtej karty, aby aktywować ten obiekt",Você precisa de um cartão de acesso amarelo para ativar este objeto,Precisas de um cartão de acesso amarelo para ativar este objeto,"Ai nevoie de un card galben pentru a activa -acest obiect",Для применения нужен жёлтый ключ,Треба вам жута карта да би активирали овај предмет,Bu nesneyi etkinleştirmek için sarı bir karta ihtiyacınız var +acest obiect",Для применения нужна жёлтая карта,Треба вам жута карта да би активирали овај предмет,Du behöver ett gult kort för att aktivera det här föremålet.,Bu nesneyi etkinleştirmek için sarı bir karta ihtiyacınız var You need a blue skull to activate this object,PD_BLUESO,,,,K aktivaci tohoto objektu potřebuješ modrou lebku.,Du skal bruge et blåt kranium for at aktivere denne objekt,"Du brauchst einen blauen Schädel-Schlüssel, um dieses Objekt zu aktivieren.",Χρειάζεσε ένα μπλέ κρανιο για να ενεργοποίησεις αυτο το αντικείμενο,Vi bezonas bluan kranion por aktivigi ĉi tiun objekton,Necesitas una calavera azul para activar este objeto,Necesitas un cráneo azul para activar este objeto,Tarvitset sinisen kalloavaimen aktivoidaksesi tämän kappaleen,Il vous faut un crâne bleu pour activer cet objet.,Kell egy kék koponya hogy aktiváld ezt a tárgyat.,ti serve una chiave-teschio blu per attivare questo oggetto ,この装置には ブルースカル が必要だ。,이 물체를 작동시키기 위해선 청색 해골이 필요합니다,Je hebt een blauwe schedel nodig om dit voorwerp te activeren.,Du trenger en blå hodeskalle for å aktivere dette objektet,"Potrzebujesz niebieskiej czaszki, aby aktywować ten obiekt",Você precisa de uma chave-crânio azul para ativar este objeto,Precisas de uma chave crânio azul para ativar este objeto,"Ai nevoie de un craniu albastru pentru a activa -acest obiect",Для применения нужен синий череп,Треба вам плава лобања да би активирали овај предмет,Bu nesneyi etkinleştirmek için mavi bir kafatasına ihtiyacınız var +acest obiect",Для применения нужен синий череп,Треба вам плава лобања да би активирали овај предмет,Du behöver en blå skalle för att aktivera det här objektet.,Bu nesneyi etkinleştirmek için mavi bir kafatasına ihtiyacınız var You need a red skull to activate this object,PD_REDSO,,,,K aktivaci tohoto objektu potřebuješ červenou lebku.,Du skal bruge et rødt kranium for at aktivere denne objekt,"Du brauchst einen roten Schädel-Schlüssel, um dieses Objekt zu aktivieren.",Χρειάζεσε ένα κόκινο κρανιο για να ενεργοποίησεις αυτο το αντικείμενο,Vi bezonas ruĝan kranion por aktivigi ĉi tiun objekton,Necesitas una calavera roja para activar este objeto,Necesitas un cráneo rojo para activar este objeto,Tarvitset punaisen kalloavaimen aktivoidaksesi tämän kappaleen,Il vous faut un crâne rouge pour activer cet objet.,Kell egy piros koponya hogy aktiváld ezt a tárgyat.,ti serve una chiave-teschio rossa per attivare questo oggetto ,この装置には レッドスカル が必要だ。,이 물체를 작동시키기 위해선 적색 해골이 필요합니다,Je hebt een rode schedel nodig om dit voorwerp te activeren.,Du trenger en rød hodeskalle for å aktivere dette objektet,"Potrzebujesz czerwonej czaszki, aby aktywować ten obiekt",Você precisa de uma chave-crânio vermelha para ativar este objeto,Precisas de uma chave crânio vermelha para ativar este objeto,"Ai nevoie de un craniu roșu pentru a activa -acest obiect",Для применения нужен красный череп,Треба вам црвена лобања да би активирали овај предмет,Bu nesneyi etkinleştirmek için kırmızı bir kafatasına ihtiyacınız var +acest obiect",Для применения нужен красный череп,Треба вам црвена лобања да би активирали овај предмет,Du behöver en röd skalle för att aktivera det här föremålet.,Bu nesneyi etkinleştirmek için kırmızı bir kafatasına ihtiyacınız var You need a yellow skull to activate this object,PD_YELLOWSO,,,,K aktivaci tohoto objektu potřebuješ žlutou lebku.,Du skal bruge et gult kranium for at aktivere denne objekt,"Du brauchst einen gelben Schädel-Schlüssel, um dieses Objekt zu aktivieren.",Χρειάζεσε ένα κύτρινο κρανιο για να ενεργοποίησεις αυτο το αντικείμενο,Vi bezonas flavan kranion por aktivigi ĉi tiun objekton,Necesitas una calavera amarilla para activar este objeto,Necesitas un cráneo amarillo para activar este objeto,Tarvitset keltaisen kalloavaimen aktivoidaksesi tämän kappaleen,Il vous faut un crâne jaune pour activer cet objet.,Kell egy sárga koponya hogy aktiváld ezt a tárgyat.,ti serve una chiave-teschio gialla per attivare questo oggetto ,この装置には イエロースカル が必要だ。,이 물체를 작동시키기 위해선 황색 해골이 필요합니다,Je hebt een gele schedel nodig om dit voorwerp te activeren.,Du trenger en gul hodeskalle for å aktivere dette objektet,"Potrzebujesz żółtej czaszki, aby aktywować ten obiekt",Você precisa de uma chave-crânio amarela para ativar este objeto,Precisas de uma chave crânio amarela para ativar este objeto,"Ai nevoie de un craniu galben pentru a activa -acest obiect",Для применения нужен жёлтый череп,Треба вам жута лобања да би активирали овај предмет,Bu nesneyi etkinleştirmek için sarı bir kafatasına ihtiyacınız var +acest obiect",Для применения нужен жёлтый череп,Треба вам жута лобања да би активирали овај предмет,Du behöver en gul skalle för att aktivera detta föremål.,Bu nesneyi etkinleştirmek için sarı bir kafatasına ihtiyacınız var You need a blue card to open this door,PD_BLUEC,,,,K otevření těchto dveří potřebuješ modrou kartu.,Du skal bruge et blåt kort for at åbne denne dør,"Du brauchst eine blaue Schlüsselkarte, um diese Tür zu öffnen",Χρειάζεσε μια μπλέ κάρτα για να ανοίξεις αυτή τη πόρτα,Vi bezonas bluan karton por malfermi ĉi tiun pordon,Necesitas una tarjeta azul para abrir esta puerta,,Tarvitset sinisen avainkortin avataksesi tämän oven,Il vous faut une carte bleue pour ouvrir cette porte.,Ez az ajtó egy kék kártyával nyílik.,Ti serve una card d'accesso blu per aprire questa porta,このドアには ブルーカード が必要だ。,이 문을 열기 위해선 청색 키카드가 필요합니다,Je hebt een blauwe sleutelkaart nodig om deze deur te openen.,Du trenger et blått kort for å åpne denne døren,"Potrzebujesz niebieskiej karty, aby otworzyć te drzwi",Você precisa de um cartão de acesso azul para abrir esta porta,Precisas de um cartão de acesso azul para abrir esta porta,"Ai nevoie de un card albastru pentru a activa -această usă",Для открытия нужна синяя карта,Треба вам плава карта да би отворили ова врата,Bu kapıyı açmak için mavi bir karta ihtiyacınız var +această usă",Для открытия нужна синяя карта,Треба вам плава карта да би отворили ова врата,Du behöver ett blått kort för att öppna den här dörren.,Bu kapıyı açmak için mavi bir karta ihtiyacınız var You need a red card to open this door,PD_REDC,,,,K otevření těchto dveří potřebuješ červenou kartu.,Du skal bruge et rødt kort for at åbne denne dør,"Du brauchst eine rote Schlüsselkarte, um diese Tür zu öffnen",Χρειάζεσε μια κόκινη κάρτα για να ανοίξεις αυτή τη πόρτα,Vi bezonas ruĝan karton por malfermi ĉi tiun pordon,Necesitas una tarjeta roja para abrir esta puerta,,Tarvitset punaisen avainkortin avataksesi tämän oven,Il vous faut une carte rouge pour ouvrir cette porte.,Ez az ajtó egy piros kártyával nyílik.,Ti serve una card d'accesso rossa per aprire questa porta,このドアには レッドカード が必要だ。,이 문을 열기 위해선 적색 키카드가 필요합니다,Je hebt een rode sleutelkaart nodig om deze deur te openen.,Du trenger et rødt kort for å åpne denne døren,"Potrzebujesz czerwonej karty, aby otworzyć te drzwi",Você precisa de um cartão de acesso vermelho para abrir esta porta,Precisas de um cartão de acesso vermelho para abrir esta porta,"Ai nevoie de un card galben pentru a activa -această ușă",Для открытия нужна красная карта,Треба вам црвена карта да би отворили ова врата,Bu kapıyı açmak için kırmızı bir karta ihtiyacınız var. +această ușă",Для открытия нужна красная карта,Треба вам црвена карта да би отворили ова врата,Du behöver ett rött kort för att öppna den här dörren.,Bu kapıyı açmak için kırmızı bir karta ihtiyacınız var. You need a yellow card to open this door,PD_YELLOWC,,,,K otevření těchto dveří potřebuješ žlutou kartu.,Du skal bruge et gult kort for at åbne denne dør,"Du brauchst eine gelbe Schlüsselkarte, um diese Tür zu öffnen",Χρειάζεσε μια κύτρινη κάρτα για να ανοίξεις αυτή τη πόρτα,Vi bezonas flavan karton por malfermi ĉi tiun pordon,Necesitas una tarjeta amarilla para abrir esta puerta,,Tarvitset keltaisen avainkortin avataksesi tämän oven,Il vous faut une carte jaune pour ouvrir cette porte.,Ez az ajtó egy sárga kártyával nyílik.,Ti serve una card d'accesso gialla per aprire questa porta,このドアには イエローカード が必要だ。,이 문을 열기 위해선 황색 키카드가 필요합니다,Je hebt een gele sleutelkaart nodig om deze deur te openen.,Du trenger et gult kort for å åpne denne døren,"Potrzebujesz żółtej karty, aby otworzyć te drzwi",Você precisa de um cartão de acesso amarelo para abrir esta porta,Precisas de um cartão de acesso amarelo para abrir esta porta,"Ai nevoie de un card galben pentru a activa -această ușă",Для открытия нужна жёлтая карта,Треба вам жута карта да би отворили ова врата,Bu kapıyı açmak için sarı bir karta ihtiyacınız var +această ușă",Для открытия нужна жёлтая карта,Треба вам жута карта да би отворили ова врата,Du behöver ett gult kort för att öppna den här dörren.,Bu kapıyı açmak için sarı bir karta ihtiyacınız var You need a blue skull to open this door,PD_BLUES,,,,K otevření těchto dveří potřebuješ modrou lebku.,Du skal bruge et blåt kranium for at åbne denne dør,"Du brauchst einen blauen Schädel-Schlüssel, um diese Tür zu öffnen",Χρειάζεσε ένα μπλέ κρανίο για να ανοίξεις αυτή τη πόρτα,Vi bezonas bluan kranion por malfermi ĉi tiun pordon,Necesitas una calavera azul para abrir esta puerta,Necesitas un cráneo azul para abrir esta puerta,Tarvitset sinisen kalloavaimen avataksesi tämän oven,Il vous faut un crâne bleu pour ouvrir cette porte.,Ez az ajtó egy kék koponyával nyílik.,Ti serve una chiave-teschio blu per aprire questa porta,このドアには ブルースカル が必要だ。,이 문을 열기 위해선 청색 해골이 필요합니다,Je hebt een blauwe schedel nodig om deze deur te openen.,Du trenger en blå hodeskalle for å åpne denne døren,"Potrzebujesz niebieskiej czaszki, aby otworzyć te drzwi",Você precisa de uma chave-crânio azul para abrir esta porta,Precisas de uma chave crânio azul para abrir esta porta,"Ai nevoie de un craniu albastru pentru a activa -această ușă",Для открытия нужен синий череп,Треба вам плава лобања да би отворили ова врата,Bu kapıyı açmak için mavi bir kafatasına ihtiyacın var. +această ușă",Для открытия нужен синий череп,Треба вам плава лобања да би отворили ова врата,Du behöver en blå skalle för att öppna den här dörren.,Bu kapıyı açmak için mavi bir kafatasına ihtiyacın var. You need a red skull to open this door,PD_REDS,,,,K otevření těchto dveří potřebuješ červenou lebku.,Du skal bruge et rødt kranium for at åbne denne dør,"Du brauchst einen roten Schädel-Schlüssel, um diese Tür zu öffnen",Χρειάζεσε ένα κόκινο κρανίο για να ανοίξεις αυτή τη πόρτα,Vi bezonas ruĝan kranion por malfermi ĉi tiun pordon,Necesitas una calavera roja para abrir esta puerta,Necesitas un cráneo rojo para abrir esta puerta,Tarvitset punaisen kalloavaimen avataksesi tämän oven,Il vous faut un crâne rouge pour ouvrir cette porte.,Ez az ajtó egy piros koponyával nyílik.,Ti serve una chiave-teschio rossa per aprire questa porta,このドアには レッドスカル が必要だ。,이 문을 열기 위해선 적색 해골이 필요합니다,Je hebt een rode schedel nodig om deze deur te openen.,Du trenger en rød hodeskalle for å åpne denne døren,"Potrzebujesz czerwonej czaszki, aby otworzyć te drzwi",Você precisa de uma chave-crânio vermelha para abrir esta porta,Precsias de uma chave crânio vermelha para abrir esta porta,"Ai nevoie de un craniu roșu pentru a activa -această ușă",Для открытия нужен красный череп,Треба вам црвена лобања да би отворили ова врата,Bu kapıyı açmak için kırmızı bir kafatasına ihtiyacın var. +această ușă",Для открытия нужен красный череп,Треба вам црвена лобања да би отворили ова врата,Du behöver en röd skalle för att öppna den här dörren.,Bu kapıyı açmak için kırmızı bir kafatasına ihtiyacın var. You need a yellow skull to open this door,PD_YELLOWS,,,,K otevření těchto dveří potřebuješ žlutou lebku.,Du skal bruge et gult kranium for at åbne denne dør,"Du brauchst einen gelben Schädel-Schlüssel, um diese Tür zu öffnen",Χρειάζεσε ένα κύτρινο κρανίο για να ανοίξεις αυτή τη πόρτα,Vi bezonas flavan kranion por malfermi ĉi tiun pordon,Necesitas una calavera amarilla para abrir esta puerta,Necesitas un cráneo amarillo para abrir esta puerta,Tarvitset keltaisen kalloavaimen avataksesi tämän oven,Il vous faut un crâne jaune pour ouvrir cette porte.,Ez az ajtó egy sárga koponyával nyílik.,Ti serve una chiave-teschio gialla per aprire questa porta,このドアには イエロースカル が必要だ。,이 문을 열기 위해선 황색 해골이 필요합니다,Je hebt een gele schedel nodig om deze deur te openen.,Du trenger en gul hodeskalle for å åpne denne døren,"Potrzebujesz żółtej czaszki, aby otworzyć te drzwi",Você precisa de uma chave-crânio amarela para abrir esta porta,Precisas de uma chave crânio amarela para abrir esta porta,"Ai nevoie de un craniu galben pentru a activa -această ușă",Для открытия нужен жёлтый череп,Треба вам жута лобања да би отворили ова врата,Bu kapıyı açmak için sarı bir kafatasına ihtiyacın var. -,,Cast call names,,,,,,,,,,,,,,,,,,,,,,,, -Zombieman,CC_ZOMBIE,,,,Zombie,Zombie,Zombie,Ζόμπι,Zombiviro,Zombi,,Zombimies,Zombie,Zombi,Zombie Marine,ゾンビ兵,좀비맨,Zombie,Zombiemann,Zombie,Zumbi,Homem Zombie,Zombi,Зомби,Зомби,Zombi -Shotgun Guy,CC_SHOTGUN,a.k.a. (former human) sergeant,,,Seržant,Sergent,Schütze,Τύπος με ντουφέκι,Ĉaspafilulo,Tipo de Escopeta,Tipo de la escopeta,Haulikkohemmo,Type au Fusil,Őrmester,Zombie Sergente,ショットガンゾンビ,샷건 가이,Jachtgeweerkerel,Sersjant,Zombie-sierżant,Sargento Possuído,Tipo de Espingarda,Pușcaș,Зомби-сержант,Пумпераш,Çavuş -Heavy Weapon Dude,CC_HEAVY,a.k.a. former commando,,,Kulometčík,,MG-Schütze,Τύπος με βαρί όπλο,Pezarmilulo,Tipo de Armas Pesadas,Ametrallador,Raskasaseäijä,Type au Gros Flingue,Kommandós,Zombie Commando,ヘビーウェポンゾンビ,헤비 웨폰 듀드,Zwarewapenskerel,Maskingeværskyt,Ciężkozbrojny Zombie,Comando Possuído,Gajo das Armas Pesadas,Mitralior,Зомби-пулемётчик,Митраљезац,Ağır Silah Dostum -Imp,CC_IMP,,,,Čert,,Kobold,Διάβολος,Diableto,,,Piru,Diablotin,Tűzkobold,Imp,インプ,임프,,,Diablik,Diabrete,,Drac,Имп,Враг,İmp -Demon,CC_DEMON,,,,Démon,Dæmon,Dämon,Δαίμονας,Demono,Demonio,,Demoni,Démon,Démon,Pinky,デーモン,데몬,Demoon,Demon,Demon,Demônio,,Demon,Демон,Демон,İblis -Lost Soul,CC_LOST,,,,Ztracená duše,Fortabt sjæl,Verlorene Seele,Χαμένη Ξυχή,Perdita Animo,Alma Errante,,Kadonnut sielu,Ame Perdue,Kóbor lélek,Anima Errante,ロストソウル,로스트 소울,Verloren ziel,Fortapt sjel,Zaginiona Dusza,Alma Perdida,Alma Penada,Suflet Pierdut,Потерянная душа,Изгубљена душа,Kayıp Ruh -Cacodemon,CC_CACO,,,,Kakodémon,Cacodæmon,Cacodämon,Κακοδαίμονας,Kakodemono,Cacodemonio,,Kakodemoni,Cacodémon,Kakodémon,Cacodemone,カコデーモン,카코데몬,Cacodemoon,Kacodemon,Kakodemon,Cacodemônio,,Cacodemon,Какодемон,Какодемон,Cacodemon -Hell Knight,CC_HELL,,,,Pekelný rytíř,Helvedesridder,Höllenritter,Ιππότης της Κόλασης,Inferkavaliro,Caballero del Infierno,,Hornanritari,Chevalier Infernal,Pokollovag,Cavaliere Infernale,ヘルナイト,헬 나이트,Helleridder,Helvetesridder,Rycerz Piekła,Cavaleiro Infernal,Cavaleiro Infernal,Cavaler al Infernului,Рыцарь ада,Витез пакла,Cehennem Şövalyesi -Baron of Hell,CC_BARON,,,,Baron pekel,Helvedesbaron,Höllenbaron,Βαρώνος της Κολασης,Barono de Infero,Barón del Infierno,,Hornanparoni,Baron des Enfers,Pokolbáró,Barone Infernale,バロンオブヘル,바론 오브 헬,Baron des Hels,Helvetesbaron,Baron Piekła,Barão do Inferno,,Baron al Infernului,Барон ада,Барон пакла,Cehennem Baronu -Arachnotron,CC_ARACH,,,,,,,Αράχνοτρον,Elektraraneo,Aracnotrón,,Araknotroni,Arachnotron,Póktron,Arachnotron,アラクノトロン,아라크노트론,,,Arachnotron,Aracnotron,,Aracnotron,Арахнотрон,Паукотрон,Araknotron -Pain Elemental,CC_PAIN,,,,Živel trýzně,Smerteelementar,Elementarschmerz,Στοιχείομα του Πόνου,Doloro-Elementulo,Elemental del Dolor,,Kivun henki,Elémentaire de Douleur,Elemi Kín,Elementale del Dolore,ペインエレメンタル,페인 엘리멘탈,Smartelementaal,Smerte Elemental,Żywiołak Bólu,Elemental da Dor,,Elemental al Durerii,Элементаль боли,Елементал патње,Acı Elementi -Revenant,CC_REVEN,,,,Umrlec,Hævnen,Wiederauferstandener,Εκδικητής,Renaskitulo,,,Henkiinpalannut,Revenant,Kísértet,Revenant,レバナント,레버넌트,Wreker,Gjenganger,Zjawa,Insepulto,Renascido,Nemort,Ревенант,Повратник,Revenant -Mancubus,CC_MANCU,,,,Mankubus,,,Χοντρός,Mankubo,,,Mankubus,Mancube,Mankubusz,Mancubus,マンキュバス,맨큐버스,,,Antropokub,,,,Манкубус,Манкубус,Mancubus -Arch-Vile,CC_ARCH,,,,Veleběs,Ærkevile,Scheusal,Νεκρομάντις,Ĉef-Fiulo,,,Arkkihirvitys,Arche-vile,Ősármány,Arch-vile,アーチバイル,아크-바일,Aartsgedrocht,Erkefiende,Arcy-Podlec,Arquivil,,Abject,Архвиль,Арчвајл,Baş Aşağılık -The Spider Mastermind,CC_SPIDER,,,,Pavoučí velevůdce,Edderkoppen Mastermind,Der Spinnenmeister,Το Αραχνό Ιθύνων Νους,La Elektraraneo-Mastro,La Mente-Maestra Arácnida,,Hämähäkkiaivot,L'Araignée Commandante,Pókelme,L'Aracnomente Suprema,スパイダーマスターマインド,스파이더 마스터마인드,Het Spinnenmeesterbrein,Edderkopphjernen,Pajęczy Mistrz,A Aranha-Mestra,,Păianjen Maestru,Паук-предводитель,Паук-руководилац,Örümcek Beyni -The Cyberdemon,CC_CYBER,,,,Kyberdémon,Cyberdæmonen,Der Cyberdämon,Ο Cyber-δαίμονας,La Ciberdemono,El Ciberdemonio,,Kyberdemoni,Le Cyberdémon,A Kiberdémon,Il Cyberdemonio,サイバーデーモン,사이버데몬,Het Cyberdemoon,Kyberdemonen,Cyberdemon,O Ciberdemônio,,Ciberdemon,Кибердемон,Сајбердемон,Siber Şeytan -Our Hero,CC_HERO,,,,Náš hrdina,Vores helt,Unser Held,Ο ήρωας μας,Nia Heroo,Nuestro Héroe,,Sankarimme,Notre Héros,Hősünk,Il Nostro eroe,我らのヒーロー,우리들의 영웅,Onze held,Vår helt,Nasz bohater,Nosso herói,O Nosso Herói,Eroul Nostru,Наш герой,Наш херој,Bizim Kahramanımız -,,Actor tag names,,,,,,,,,,,,,,,,,,,,,,,, -Zombieman,FN_ZOMBIE,,,,Zombie,Zombie,Zombie,Ζόμπι,Zombiviro,Zombi,,Zombi,Zombie,Zombi,Zombie Marine,ゾンビ兵,좀비맨,Zombie,Zombiemannen,Zombie,Zumbi,Homem Zombie,Zombi,Зомби,Зомби,Zombi -Sergeant,FN_SHOTGUN,,,,Seržant,Sergent,Schütze,Λοχίας,Serĝento,Sargento,,Kersantti,Type au Fusil,Őrmester,Zombie Sergente,ゾンビ軍曹,샷건 가이,Sergeant,Sersjant,Zombie-sierżant,Sargento Possuído,Sargento,Sergent,Зомби-сержант,Водник,Çavuş -Chaingunner,FN_HEAVY,,,,Kulometčík,,MG-Schütze,Πολυβόλο Ζόμπι,Maŝinpafilisto,Ametrallador,,Konekiväärimies,Type au Gros Flingue,Kommandós,Zombie Commando,チェーンガンゾンビ,체인거너,Machinegeweerman,Maskingeværskyt,Ciężkozbrojny Zombie,Comando Possuído,Metrelhador,Mitralior,Зомби-пулемётчик,Митраљезац,Ağır Silah Dostum -Imp,FN_IMP,,,,Čert,,Kobold,Διάβολος,Diableto,,,Piru,Diablotin,Tűzkobold,Imp,インプ,임프,,,Diablik,Diabrete,,Drac,Имп,Враг,İmp -Demon,FN_DEMON,,,,Démon,Dæmon,Dämon,Δαίμονας,Demono,Demonio,,Demoni,Démon,Démon,Pinky,デーモン,데몬,Demoon,Demon,Demon,Demônio,,Demon,Демон,Демон,İblis -Spectre,FN_SPECTRE,,,,Přízrak,Spøgelse,Schemen,Φάντασμα,Fantomo,Espectro,,Haamu,,Lidérc,Spettro,スペクトル,스펙터,Spook,Spøkelse,Widmo,Espectro,,Spectru,Призрак,Авет,Hayalet -Lost Soul,FN_LOST,,,,Ztracená duše,Fortabt sjæl,Verlorene Seele,Χαμένη Ξυχή,Perdita Animo,Alma Errante,,Kadonnut sielu,Ame Perdue,Kóbor lélek,Anima Errante,ロストソウル,로스트 소울,Verloren Ziel,Fortapt sjel,Zaginiona Dusza,Alma Perdida,Alma Penada,Suflet Pierdut,Потерянная душа,Изгубљена душа,Kayıp Ruh -Cacodemon,FN_CACO,,,,Kakodémon,Cacodæmon,Cacodämon,Κακοδαίμονας,Kakodemono,Cacodemonio,,Kakodemoni,Cacodémon,Kakodémon,Cacodemone,カコデーモン,카코 데몬,Cacodemoon,Kacodemon,Kakodemon,Cacodemônio,,Cacodemon,Какодемон,Какодемон,Caco İblis -Hell Knight,FN_HELL,,,,Pekelný rytíř,Helvedesridder,Höllenritter,Ιππότης της Κόλασης,Inferkavaliro,Caballero del Infierno,,Hornanritari,Chevalier Infernal,Pokollovag,Cavaliere Infernale,ヘルナイト,헬 나이트,Helleridder,Helvetesridder,Rycerz Piekła,Cavaleiro Infernal,Cavaleiro Infernal,Cavaler al Infernului,Рыцарь ада,Витез пакла,Cehennem Şövalyesi -Baron of Hell,FN_BARON,,,,Baron pekel,Helvedesbaron,Höllenbaron,Βαρώνος της Κολασης,Barono de Infero,Barón del Infierno,,Hornanparoni,Baron des Enfers,Pokolbáró,Barone Infernale,バロンオブヘル,바론 오브 헬,Baron des Hels,Helvetesbaron,Baron Piekła,Barão do Inferno,,Baron al Infernului,Барон ада,Барон пакла,Cehennem Baronu -Arachnotron,FN_ARACH,,,,,,,Αράχνοτρον,Elektraraneo,Aracnotrón,,Araknotroni,,Póktron,Arachnotron,アラクノトロン,아라크노트론,,,,,,Aracnotron,Арахнотрон,Паукотрон,Araknotron -Pain Elemental,FN_PAIN,,,,Živel trýzně,Smerteelementar,Elementarschmerz,Στοιχείομα του Πόνου,Doloro-Elementulo,Elemental del Dolor,,Kivun henki,Elémentaire de Douleur,Elemi Kín,Elementale del Dolore,ペインエレメンタル,페인 엘리멘탈,Smartelementaal,Smerte Elemental,Żywiołak Bólu,Elemental da Dor,,Elemental al Durerii,Элементаль боли,Елементал патње,Acı Elementi -Revenant,FN_REVEN,,,,Umrlec,Hævnen,Wiederauferstandener,Εκδικητής,Renaskitulo,,,Henkiinpalannut,,Kísértet,Revenant,レバナント,레버넌트,Wreker,Gjenganger,Zjawa,Insepulto,Renascido,Nemort,Ревенант,Повратник,İskelet -Mancubus,FN_MANCU,,,,Mankubus,,,Χοντρός,Mankubo,,,Mankubus,Mancube,Mankubusz,Mancubus,マンキュバス,맨큐버스,,,Antropokub,,,,Манкубус,Манкубус,Mancubus -Arch-vile,FN_ARCH,,,,Veleběs,Ærkevile,Scheusal,Νεκρομάντις,Ĉef-fiulo,,,Arkkihirvitys,Arche-vile,Ősármány,Arch-vile,アーチバイル,아크-바일,Aartsgedrocht,Erkefiende,Arcy-Podlec,Arquivil,,Abject,Архвиль,Арчвајл,İğrençlik -Spider Mastermind,FN_SPIDER,,,,Pavoučí velevůdce,Edderkoppen Mastermind,Spinnenmeister,Αραχνό Ιθύνων Νους,Elektraraneo-Mastro,Mente-Maestra Arácnida,,Hämähäkkiaivot,L'Araignée Commandante,Pókelme,L'Aracnomente Suprema,スパイダーマスターマインド,스파이더 마스터마인드,Spinnenmeesterbrein,Edderkopphjerne,Pajęczy Mistrz,A Aranha-Mestra,,Păianjen Maestru,Паук-предводитель,Паук-руководилац,Örümcek Beyni -Cyberdemon,FN_CYBER,,,,Kyberdémon,Cyberdæmon,Cyberdämon,Cyber-δαίμονας,Ciberdemono,Ciberdemonio,,Kyberdemoni,Le Cyberdémon,Kiberdémon,Il Cyberdemonio,サイバーデーモン,사이버데몬,Cyberdemoon,Kyberdemon,Cyberdemon,O Ciberdemônio,,Ciberdemon,Кибердемон,Сајбердемон,Siber İblis -Nazi,FN_WOLFSS,,,,Nácek,,,Ναζιστής,Nazio,,,Natsi,,Náci,Nazista,ナチ兵,나치,,Nazist,Nazista,Nazista,Nazi,Nazist,Нацист,Нациста,Nazi -Dog,FN_DOG,,,,Pes,Hund,Hund,Σκύλος,Hundo,Perro,,Koira,Chien,Kutya,Cane,犬,개,Hond,Hund,Pies,Cão,,Câine,Собака,Пас,Köpek -Brass Knuckles,TAG_FIST,,,,Boxer,Messing knoer,Schlagringe,Γροθιά,Pugningo,Puño americano,Manopla (puño de acero),Nyrkkirauta,Poing Américain,Bokszer,Tirapugni ,ナックルダスター,너클,Boksbeugels,Knokejern,Kastety,Soco Inglês,Soqueira,Rozetă,Латунный кастет,Боксер,Pirinç Muşta -Chainsaw,TAG_CHAINSAW,,,,Motorová pila,Kædesav,Kettensäge,Αλλησοπρίονο,Ĉensegilo,Motosierra,,Moottorisaha,Tronçonneuse,Láncfűrész,Motosega,チェーンソウ,전기톱,Kettingzaag,Motorsag,Piła łańcuchowa,Motosserra,,Drujbă,Бензопила,Моторна тестера,Testere -Pistol,TAG_PISTOL,,,,Pistole,,Pistole,Πιστόλι,Pafileto,Pistola,,Pistooli,Pistolet,Pisztoly,Pistola,ピストル,권총,Pistool,,Pistolet,Pistola,,Pistol,Пистолет,Пиштољ,Tabanca -Shotgun,TAG_SHOTGUN,,,,Brokovnice,Haglgevær,Schrotflinte,Ντουφέκι,Kartoĉa fusilo,Escopeta,,Haulikko,Fusil à pompe,Sörétes Puska,Fucile,ショットガン,샷건,Jachtgeweer,Haglgevær,Strzelba,Espingarda,,Pușcă,Дробовик,Пумпарица,Av Tüfeği -Super Shotgun,TAG_SUPERSHOTGUN,,,,Superbrokovnice,Super-Haglgevær,Super-Schrotflinte,Διπλό Ντουφέκι,Dutuba fusilo,Superescopeta,,Superhaulikko,Super Fusil de chasse,Szuper Sörétes,Fucile a doppia canna ,スーパーショットガン,슈퍼 샷건,Superjachtgeweer,Super-Haglgevær,Super strzelba,Espingarda de cano duplo,,Super Pușcă,Супердробовик,Двоцевка,Süper Av Tüfeği -Chaingun,TAG_CHAINGUN,,,,Kulomet,Maskingevær,Maschinengewehr,Πολυβόλο,Maŝinpafilo,Ametralladora,,Gatling-kk,Mitrailleuse,Golyószóró,Mitragliatore a canne rotanti ,チェーンガン,체인건,Machinegeweer,Maskinpistol,Karabin maszynowy,Metralhadora,,Mitralieră rotativă,Пулемёт,Митраљез,Chaingun -Rocket Launcher,TAG_ROCKETLAUNCHER,,,,Raketomet,Raketkaster,Raketenwerfer,Πυραυλοβόλο,Misilpafilo,Lanzamisiles,,Sinko,Lance-Roquettes,Rakétavető,Lanciamissili,ロケットランチャー,로켓 런쳐,Raketwerper,Rakettkaster,Wyrzutnia rakiet,Lança-foguetes,Lança-Mísseis,Lansator de Rachete,Ракетомёт,Бацач ракета,Roket Fırlatıcı -Plasma Rifle,TAG_PLASMARIFLE,,,,Plazmová puška,Plasma riffel,Plasmagewehr,Πλάσμα Όπλο,Plasmo-pafilo,Fusil de plasma,,Plasmapyssy,Fusil à Plasma,Plazmafegyver,Fucile al Plasma ,プラズマライフル,플라즈마 라이플,Plasmageweer,Plasmagevær,Karabin plazmowy,Fuzil de Plasma,Pistola de Plasma,Pușcă cu Plasmă,Плазменная пушка,Плазма оружје,Plazma Tüfeği -BFG 9000,TAG_BFG9000,,,,,BFG 9000,,,,,,,,,,,,,,,,,,,ВЈП 9000, -Bullets,AMMO_CLIP,,,,Kulky,Kugler,Patronen,Σφαίρες,Kugloj,Balas,,Luodit,Balles,Töltények,Proiettili,銃弾,권총 탄약,Kogels,Kuler,Naboje,Balas,,Gloanțe,Пули,Меци,Kurşunlar -Shotgun Shells,AMMO_SHELLS,,,,Broky,Haglgeværpatroner,Schrotpatronen,Σφαίρες Ντουφεκιού,Kartoĉoj,Cartuchos de escopeta,,Haulikon patruunat,Cartouches,Sörétek,Cartucce per fucile,散弾シェル,샷건 탄약,Jachtgeweerkogels,Haglepatroner,Loftki,Cartuchos de Espingarda,,Proiectile pentru Pușcă,Патроны для дробовика,Патроне за пумпарицу,Av Tüfeği Fişekleri -Rockets,AMMO_ROCKETS,,,,Rakety,Raketter,Raketen,Πύραυλοι,Raketoj,Cohetes,,Raketit,Roquettes,Rakéták,Razzi,ロケット弾,로켓,Raketten,Raketter,Rakiety,Foguetes,Mísseis,Rachete,Ракеты,Ракете,Roketler -Energy Cells,AMMO_CELLS,,,,Energetické články,Energiceller,Energiezellen,Κύτταρα Ενέργιας,Energiĉeloj,Célula de energía,,Energia-akut,Cellules,Energiacellák,Batterie,エネルギーセル,에너지 셀,Energiecellen,Energiceller,Ogniwa energetyczne,Células de Energia,,Celule cu Energie,Энергобатареи,Енергетске ћелије,Enerji Hücreleri -,,Obituaries,,,,,,,,,,,,,,,,,,,,,,,, -%o thought %g saw an arachnotron.,OB_STEALTHBABY,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] arachnotrona.","%o troede, @[pro_dk] så en arachnotron.","%o dachte, ein Arachnotron zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Αραχνοτρόν.,"%o pensis, ke @[pro_eo] vidis elektraraneon.",%o creyó haber visto un aracnotrón.,,%o luuli nähneensä araknotronin.,%o a cru voir un Arachnotron.,"%o azt hitte, hogy látott egy póktront.",a %o sembrava di aver visto un arachnotron.,%o がアラクノトロンを見た気がした。,%o 은(는) 아라크노트론을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een arachnotron zag.,%o trodde @[pro_dk] så et arachnotron.,%o kątem oka zauważył@[ao_pl] arachnotrona.,%o achou que viu uma arachnotron.,,%o a crezut că %g a văzut un aracnotron.,Игрок %o краем глаза заметил арахнотрона.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] паукотрона.,%o bir araknotron gördüğünü sandı. -%o thought %g saw an archvile.,OB_STEALTHVILE,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] veleběsa.","%o troede, @[pro_dk] så en ærkevile.","%o dachte, ein Scheusal zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Νεκρομάντη,"%o pensis, ke @[pro_eo] vidis ĉef-fiulon.",%o creyó haber visto un arch-vile.,,%o luuli nähneensä arkkihirvityksen,%o a cru voir un Arche-Vile.,"%o azt hitte, hogy látott egy ősármányt.",a %o sembrava di aver visto un Arch-Vile.,%o がアーチバイルを見た気がした。,%o 은(는) 아크-바일을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een aartsvijand zag.,%o trodde @[pro_dk] så en erkefiende.,%o kątem oka zauważył@[ao_pl] arcypodleca.,%o achou que viu um arquivil.,,%o a crezut că %g a văzut un abject.,Игрок %o краем глаза заметил архвиля.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] једног арчвајла.,%o bir iğrençlik gördüğünü sandı. -%o thought %g saw a Baron of Hell.,OB_STEALTHBARON,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] barona pekel.","%o troede, @[pro_dk] så en helvedesbaron.","%o dachte, einen Höllenbaron zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Βαρώνο της Κόλασης.,"%o pensis, ke @[pro_eo] vidis Baronon de Infero.",%o creyó haber visto un Barón del Infierno.,,%o luuli nähneensä hornanparonin.,%o a cru voir un Baron des enfers.,"%o azt hitte, hogy látott egy pokolbárót.",a %o sembrava di aver visto un Barone Infernale.,%o がバロンを見た気がした。,%o 은(는) 바론 오브 헬을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een baron van de Hel zag.,%o trodde @[pro_dk] så en helvetesbaron,%o kątem oka zauważył@[ao_pl] Barona Piekła.,%o achou que viu um barão do inferno.,,%o a crezut că %g a văzut un Baron al Infernului.,Игрок %o краем глаза заметил барона ада.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] барона пакла.,%o bir Cehennem Baronu gördüğünü sandı. -%o thought %g saw a cacodemon.,OB_STEALTHCACO,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] kakodémona.","%o troede, @[pro_dk] så en cacodemon.","%o dachte, einen Cacodämonen zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Κακοδαίμονα.,"%o pensis, ke @[pro_eo] vidis kakodemonon.",%o creyó haber visto un cacodemonio.,,%o luuli nähneensä kakodemonin.,%o a cru voir un Cacodémon.,"%o azt hitte, hogy látott egy kakodémont.",a %o sembrava di aver visto un cacodemone.,%o がカコデーモンを見た気がした。,%o 은(는) 카코데몬을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een cacodemon zag.,%o trodde @[pro_dk] så en kakodemon.,%o kątem oka zauważył@[ao_pl] kakodemona.,%o achou que viu um cacodemônio.,,%o a crezut că %g a văzut un cacodemon.,Игрок %o краем глаза заметил какодемона.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] какодемона.,%o bir caco iblisi gördüğünü sandı. -%o thought %g saw a chaingunner.,OB_STEALTHCHAINGUY,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] kulometčíka.","%o troede, @[pro_dk] så en chaingunner.","%o dachte, einen MG-Schützen zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Ζόμπι με ένα πολυβόλο.,"%o pensis, ke @[pro_eo] vidis maŝinpafiliston.",%o creyó haber visto un ametrallador.,,%o luuli nähneensä konekiväärimiehen.,%o a cru voir un mitrailleur.,"%o azt hitte, hogy látott egy kommandóst.",a %o sembrava di aver visto uno zombie commando.,%o がチェインガンナーを見た気がした。,%o 은(는) 체인거너를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een zware wapens kerel zag.,%o trodde @[pro_dk] så en maskingeværskyt.,%o kątem oka zauważył@[ao_pl] ciężkozbrojnego zombie.,%o achou que viu um comando possuído.,%o achou que viu um metrelhador.,%o a crezut că %g a văzut un mitralior.,Игрок %o краем глаза заметил пулемётчика.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] митраљезца.,%o bir ağır silah dostu gördüğünü sandı. -%o thought %g saw a demon.,OB_STEALTHDEMON,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] démona.","%o troede, @[pro_dk] så en dæmon.","%o dachte, einen Dämonen zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα δαίμονα.,"%o pensis, ke @[pro_eo] vidis demonon.",%o creyó haber visto un demonio.,,%o luuli nähneensä demonin.,%o a cru voir un démon.,"%o azt hitte, hogy látott egy démont.",a %o sembrava di aver visto un demone.,%o がデーモンを見た気がした。,%o 은(는) 데몬을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een demon zag.,%o trodde @[pro_dk] så en demon.,%o kątem oka zauważył@[ao_pl] demona.,%o achou que viu um demônio.,,%o a crezut că %g a văzut un demon.,Игрок %o краем глаза заметил демона.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] демона.,%o bir iblis gördüğünü sandı. -%o thought %g saw a Hell Knight.,OB_STEALTHKNIGHT,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] rytíře pekel.","%o troede, @[pro_dk] så en helvedesridder.","%o dachte, einen Höllenritter zu sehen.",@[art_gr] %o νόμιζε οτι είδε έναν Ιππότη της Κόλασης.,"%o pensis, ke @[pro_eo] vidis Inferkavaliron.",%o creyó haber visto un Caballero del Infierno.,,%o luuli nähneensä hornanritarin.,%o a cru voir un chevalier infernal.,"%o azt hitte, hogy látott egy pokollovagot.",a %o sembrava di aver visto un Cavaliere Infernale.,%o がヘルナイトを見た気がした。,%o 은(는) 헬 나이트를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een hel ridder zag.,%o trodde @[pro_dk] så en helvetesridder.,%o kątem oka zauważył@[ao_pl] Rycerza Piekła.,%o achou que viu um cavaleiro infernal.,%o achou que viu um cavaleiro infernal.,%o a crezut că %g a văzut un Cavaler al Infernului.,Игрок %o краем глаза заметил рыцаря ада.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] витеза пакла.,%o bir Cehennem Şövalyesi gördüğünü sandı. -%o thought %g saw an imp.,OB_STEALTHIMP,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] čerta.","%o troede, @[pro_dk] så en imp.","%o dachte, einen Kobold zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Διάβολο.,"%o pensis, ke @[pro_eo] vidis diableton.",%o creyó haber visto un imp.,,%o luuli nähneensä pirun.,%o a cru voir un diablotin.,"%o azt hitte, hogy látott egy tűzkoboldot.",a %o sembrava di aver visto un imp.,%o がインプを見た気がした。,%o 은(는) 임프를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een imp zag.,%o trodde @[pro_dk] så en imp.,%o kątem oka zauważył@[ao_pl] diablika.,%o achou que viu um diabrete.,,%o a crezut că %g a văzut un drac.,Игрок %o краем глаза заметил импа.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] врага.,%o bir impus gördüğünü sandı. -%o thought %g saw a mancubus.,OB_STEALTHFATSO,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] mankuba.","%o troede, @[pro_dk] så en mankubus.","%o dachte, einen Mancubus zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Χοντρό.,"%o pensis, ke @[pro_eo] vidis mankubon.",%o creyó haber visto un mancubus.,,%o luuli nähneensä mankubuksen.,%o a cru voir un mancube.,"%o azt hitte, hogy látott egy mankubuszt.",a %o sembrava di aver visto un mancubus.,%o がマンキュバスを見た気がした。,%o 은(는) 맨큐버스를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een mancubus zag.,%o trodde @[pro_dk] så en mancubus.,%o kątem oka zauważył@[ao_pl] antropokuba.,%o achou que viu um mancubus.,,%o a crezut că %g a văzut un mancubus.,Игрок %o краем глаза заметил манкубуса.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] манкубуса.,%o bir mancubus gördüğünü sandı. -%o thought %g saw a revenant.,OB_STEALTHUNDEAD,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] umrlce.","%o troede, @[pro_dk] så en hævnen.","%o dachte, einen Wiederauferstandenen zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Εκδικητή.,"%o pensis, ke @[pro_eo] vidis renaskitulon.",%o creyó haber visto un revenant.,,%o luuli nähneensä henkiinpalanneen.,%o a cru voir un revenant.,"%o azt hitte, hogy látott egy kísértetet.",a %o sembrava di aver visto un revenant.,%o がレバナントを見た気がした。,%o 은(는) 레버넌트를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een wraakzuchtige zag.,%o trodde @[pro_dk] så en gjenganger.,%o kątem oka zauważył@[ao_pl] zjawę.,%o achou que viu um insepulto.,%o achou que viu um renascido.,%o a crezut că %g a văzut un nemort.,Игрок %o краем глаза заметил ревенанта.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] повратника.,%o bir iskelet gördüğünü sandı. -%o thought %g saw a sergeant.,OB_STEALTHSHOTGUNGUY,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] seržanta.","%o troede, @[pro_dk] så en sergent.","%o dachte, einen Schützen zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Λοχία.,"%o pensis, ke @[pro_eo] vidis serĝenton.",%o creyó haber visto un sargento.,,%o luuli nähneensä kersantin.,%o a cru voir un type au fusil.,"%o azt hitte, hogy látott egy őrmestert.",a %o sembrava di aver visto un zombie sergente.,%o が軍曹を見た気がした。,%o 은(는) 샷건 가이를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een jachtgeweer kerel zag.,%o trodde @[pro_dk] så en sersjant.,%o kątem oka zauważył@[ao_pl] zombie-sierżanta.,%o achou que viu um sargento possuído.,%o achou que viu um sargento.,%o a crezut că %g a văzut un sergent.,Игрок %o краем глаза заметил сержанта.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] водника.,%o bir çavuş gördüğünü sandı. -%o thought %g saw a zombieman.,OB_STEALTHZOMBIE,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] zombíka.","%o troede, @[pro_dk] så en zombie.","%o dachte, einen Zombie zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Ζόμπι.,"%o pensis, ke @[pro_eo] vidis zombiviron.",%o creyó haber visto un zombi.,,%o luuli nähneensä zombin.,%o a cru voir un zombie.,"%o azt hitte, hogy látott egy zombit.",a %o sembrava di aver visto uno zombie marine.,%o がゾンビ兵を見た気がした。,%o 은(는) 좀비맨을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een zombie zag.,%o trodde @[pro_dk] så en zombiemann.,%o kątem oka zauważył@[ao_pl] zombie.,%o achou que viu um zumbi.,%o achou que viu um zombie.,%o a crezut că %g a văzut un zombi.,Игрок %o краем глаза заметил зомби.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] зомбија.,%o bir zombi gördüğünü sandı. -%o was punched by a revenant.,OB_UNDEADHIT,,,,%o byl@[ao_cs] udeřen@[ao_cs] umrlcem.,%o blev slået af en genfødt.,%o wurde von einem Wiederauferstandenen K.O geschlagen.,@[art_gr] %o έφαγε μια μπουνία απο έναν Εκδικητή.,%o estis pugnita de renaskitulo.,%o fue golpead@[ao_esp] por un revenant.,,%o joutui henkiinpalanneen lyömäksi.,%o s'est pris@[e_fr] une raclée de la part d'un revenant.,%o-t kiütötte egy kísértet.,%o è stato colpito dal pugno di un revenant.,%o はレバナントに殴られた。,%o 은(는) 레버넌트에게 맞아 죽었다.,%o werd geslagen door een wraakzuchtige.,%o ble slått av en gjenganger.,%o został@[ao_pl] uderzon@[adj_pl] przez zjawę.,%o foi socad@[ao_ptb] por um insepulto.,%o foi socad@[ao_ptb] por um renascido.,%o a primit un pumn de la un nemort.,Игрока %o ударил ревенант.,%o је ударен@[adj_1_sr] од стане повратника.,%o bir iskelet tarafından yumruklandı. -%o was slashed by an imp.,OB_IMPHIT,,,,%o byl@[ao_cs] rozsápán@[ao_cs] čertem.,%o blev skåret ned af en spøgelse.,%o wurde von einem Kobold gekratzt.,@[art_gr] %o κόπηκε απο ενα Διάβολο.,%o estis tranĉvundita de diableto.,%o fue desgarrad@[ao_esp] por un imp.,,%o joutui pirun sivaltamaksi.,%o a été lacéré@[e_fr] par un diablotin.,%o-t széttépte egy tűzkobold.,%o è stato squarciato da un imp.,%o はインプに切り裂かれた。,%o 은(는) 임프에게 찢겨 죽었다.,%o werd gesneden door een imp.,%o ble kuttet av en imp.,%o został@[ao_pl] rozcięt@[adj_pl] przez diablika.,%o foi dilacerad@[ao_ptb] por um diabrete.,,%o a fost zgâriat de un drac.,Игрока %o расцарапал имп.,Играча %o је пресеко враг.,%o bir imp tarafından kesildi. -%o got too close to a cacodemon.,OB_CACOHIT,,,,%o se dostal@[ao_cs] moc blízko ke kakodémonovi.,%o kom for tæt på en cacodæmon.,%o kam dem Cacodämonen zu nahe.,@[art_gr] %o ήτανε πολυ κοντά σε ένα Κακοδαίμονα.,%o tro proksimiĝis al kakodemono.,%o se acercó demasiado a un cacodemonio.,,%o meni liian lähelle kakodemonia.,%o s'est approché@[e_fr] trop près d'un Cacodémon.,%o túl közel ment egy kakodémonhoz.,%o si è avvicinato troppo a un cacodemone.,%o はカコデーモンに近づきすぎた。,%o 은(는) 카코데몬과 가까웠다.,%o kwam te dicht bij een cacodemon.,%o kom for nær en kakodemon.,%o pod@[irreg_1_pl] zbyt blisko do kakodemona.,%o chegou muito perto de um cacodemônio.,,%o s-a apropiat prea mult de un cacodemon.,Игрок %o слишком сблизился с какодемоном.,%o се превише приближи@[ao_1_sr] какодемону.,%o bir caco iblisiyle çok yakınlaştı. -%o was bit by a demon.,OB_DEMONHIT,,,,%o byl@[ao_cs] rozkousán@[ao_cs] démonem.,%o blev bidt af en dæmon.,%o wurde von einem Dämonen gebissen.,@[art_gr] %o δαγκόθηκε απο ένα Δαίμονα.,%o estis mordita de demono.,%o fue mordid@[ao_esp] por un demonio.,,%o joutui demonin puremaksi.,%o a été mordu@[e_fr] par un démon.,%o-t megharapta egy démon.,%o è stato sbranato da un demone.,%o はデーモンに噛まれた。,%o 은(는) 데몬에게 물렸다.,%o werd gebeten door een demon.,%o ble bitt av en demon.,%o wpada w szczęki demona.,%o foi mordid@[ao_ptb] por um demônio.,,%o a fost mușcat de un demon.,Игрока %o укусил демон.,Играча %o је ујео демон.,%o bir iblis tarafından ısırıldı. -%o was eaten by a spectre.,OB_SPECTREHIT,,,,%o byl@[ao_cs] sežrán@[ao_cs] přízrakem.,%o blev spist af et imp.,%o wurde von dem Schemen gefressen.,Ένα φάντασμα έφαγε @[pro_gr] %o.,%o estis manĝita de fantomo.,%o fue devorad@[ao_esp] por un espectro.,,%o joutui haamun syömäksi.,%o a été dévoré@[e_fr] par un spectre.,%o-t felfalta egy lidérc.,%o è stato divorato da uno spettro.,%o はスペクトルに喰われた。,%o 은(는) 스펙터에게 잡아먹혔다.,%o werd opgegeten door een spook.,%o ble spist av et spøkelse.,%o został@[ao_pl] zjedzon@[adj_pl] przez widmo.,%o foi devorad@[ao_ptb] por um espectro.,,%o a fost mâncat de un spectru.,Игрока %o сожрал призрак.,Играча %o је појео авет.,%o bir hayalet tarafından yenildi. -%o was ripped open by a Baron of Hell.,OB_BARONHIT,,,,%o byl@[ao_cs] rozčtvrcen@[ao_cs] baronem pekel.,%o blev flået op af en helvedesbaron.,%o wurde von dem Höllenbaron aufgerissen.,@[art_gr] %o σχίστηκε απο εναν Βαρώνο της Κόλασης.,%o estis disŝirigita de Barono de Infero.,%o quedó hech@[ao_esp] trizas por un Barón del Infierno.,,%o joutui hornanparonin auki repimäksi.,%o a été déchiré@[e_fr] par un Baron des Enfers.,%o-t széttépte egy pokolbáró.,%o è stato scoperchiato da un Barone dell'Inferno.,%o はバロンオブヘルに体を抉じ開けられた。,%o 은(는) 바론 오브 헬에게 뜯겨 죽었다.,%o werd opengereten door een Baron van de hel.,%o ble revet opp av en helvetesbaron.,%o został@[ao_pl] rozerwan@[adj_pl] przez Barona Piekła.,%o foi rasgad@[ao_ptb] por um Barão do Inferno.,%o foi desventrad@[ao_ptb] por um Barão do Inferno.,%o a fost deschis pe viu de un Baron al Infernului.,Игрока %o разорвал барон ада.,%o је поцеп@[adj_2_sr] од стране барон пакла.,%o bir Cehennem Baronu tarafından parçalandı. -%o was gutted by a Hell Knight.,OB_KNIGHTHIT,,,,%o byl@[ao_cs] vykuchán@[ao_cs] rytířem pekel.,%o blev udtaget af en helvedesridder.,%o wurde von dem Höllenritter ausgenommen.,@[art_gr] %o ξεκοιλιάστηκε απο έναν Ιππότη της Κόλασης.,%o estis senintestigita de Inferkavaliro.,%o fue destripad@[ao_esp] por un Caballero del Infierno.,,%o joutui hornanritarin perkaamaksi.,%o a été étripé@[e_fr] par un un chevalier infernal.,%o-t kibelezte egy pokollovag.,%o è stato sbudellato da un Cavaliere dell'Inferno.,%o はヘルナイトに内臓を抉られた。,%o 은(는) 헬 나이트에게 도륙당했다.,%o werd gestript door een hel ridder.,%o ble sløyet av en helvetesridder.,%o został@[ao_pl] wypatroszon@[adj_pl] przez Rycerza Piekła.,%o foi estripad@[ao_ptb] por um Cavaleiro Infernal.,%o foi estripad@[ao_ptb] por um Cavaleiro Infernal.,%o a fost măcelărit de un Cavaler al Infernului.,Игрока %o распотрошил рыцарь ада.,Играча %o је унаказио витез пакла.,%o bir Cehennem Şövalyesi tarafından parçalandı. -%o was killed by a zombieman.,OB_ZOMBIE,,,,%o byl@[ao_cs] zabit@[ao_cs] zombíkem.,%o blev dræbt af en zombie.,%o wurde von einem Zombie getötet.,@[art_gr] %o σκοτώθηκε απο ένα Ζόμπι.,%o estis mortigita de zombiviro.,%o fue asesinad@[ao_esp] por un zombi.,,%o joutui zombin tappamaksi.,%o a été tué@[e_fr] par un zombie.,%o-t megölte egy zombi.,%o è stato ucciso da uno zombie marine.,%o はゾンビ兵に殺された。,%o 은(는) 좀비맨에게 죽었다.,%o werd gedood door een zombie.,%o ble drept av en zombiemann.,%o został@[ao_pl] zabit@[adj_pl] przez zombie.,%o foi mort@[ao_ptb] por um zumbi.,%o foi mort@[ao_ptb] por um zombie.,%o a fost omorât de un zombi.,Игрока %o убил зомби.,%o је убијен@[adj_1_sr] од стране зомбија.,%o bir zombi tarafından öldürüldü. -%o was shot by a sergeant.,OB_SHOTGUY,,,,%o byl@[ao_cs] zastřelen@[ao_cs] seržantem.,%o blev skudt af en sergent.,%o wurde von einem Schützen erschossen.,Ένας Λοχίας πυροβόλησε @[pro_gr] %o.,%o estis pafita de serĝento.,%o fue fusilad@[ao_esp] por un sargento.,,%o joutui kersantin ampumaksi.,%o s'est fait flinguer par un type au fusil.,%o-t lelőtte egy őrmester.,%o è sato impallinato da uno zombie sergente.,%o はゾンビ軍曹に撃たれた。,%o 은(는) 서전트에게 총을 맞았다.,%o werd neergeschoten door een sergeant.,%o ble skutt av en sersjant.,%o został@[ao_pl] zastrzelon@[adj_pl] przez zombie-sierżanta.,%o levou um tiro de um sargento possuído.,,%o a fost împușcat de un sergent.,Игрока %o застрелил сержант.,Играча %o је погодио водник.,%o bir çavuş tarafından vuruldu. -%o was incinerated by an archvile.,OB_VILE,,,,%o byl@[ao_cs] zpopelněn@[ao_cs] veleběsem.,%o blev brændt af en ærkevile.,%o wurde von einem Scheusal verbrannt.,@[art_gr] %o αποτεφρώθηκε απο ένα Νεκρομάντη.,%o estis cindrigita de ĉef-fiulo.,%o fue calcinad@[ao_esp] por un arch-vile.,,%o joutui arkkihirvityksen kärventämäksi.,%o a été incinéré@[e_fr] par un Arche-Vile.,%o-t megpörkölte egy ősármány.,%o è stato incenerito da un arch-vile.,%o はアーチバイルに焼き尽くされた。,%o 은(는) 아크-바일에 의해 소각되었다.,%o werd verbrand door een aartsvijand.,%o ble brent av en erkefiende.,%o został@[ao_pl] spalon@[adj_pl] przez arcypodleca.,%o foi incinerad@[ao_ptb] pelo arquivil.,,%o a fost incinerat de un abject.,Игрока %o заживо сжёг архвиль.,Играча %o је запалио арчвајл.,%o bir iğrençlik tarafından yakıldı. -%o couldn't evade a revenant's fireball.,OB_UNDEAD,,,,%o se nevyhnul@[ao_cs] umrlčí ohnivé kouli.,%o kunne ikke undvige en ildkugle fra en hævnen.,%o konnte dem Feuerball des Wiederauferstandenen nicht ausweichen.,@[art_gr] %o δέν μπορούσε να αποφείγει τον πύραυλο ενός Εκδικητή.,%o ne povis eviti fajrobulon de renaskitulo.,%o no pudo esquivar la bola de fuego de un revenant.,,%o ei kyennyt väistämään henkiinpalanneen tulipalloa.,%o n'a pas réussi à esquiver un missile de revenant.,%o nem tudta kivédeni egy kísértet tűzgolyóját.,%o non ha potuto evitare il missile di un revenant.,%o はレバナントのファイアボールを回避できなかった。,%o 은(는) 레버넌트의 화염구를 피하지 못했다.,%o kon de vuurbal van een wraakzuchtige niet ontwijken.,%o klarte ikke å unngå en gjengangers ildkule.,%o nie udaje się uniknąć pocisku od zjawy.,%o não conseguiu desviar do míssil do insepulto.,%o não conseguiu desviar do míssil do renascido.,%o n-a putut scăpa de mingea de foc a nemortului.,Игрок %o не успел увернуться от снаряда ревенанта.,%o није мог@[ao_2_sr] да избегне повратникову пламену куглу.,%o bir iskeletin ateş topundan kaçamadı. -%o was squashed by a mancubus.,OB_FATSO,,,,%o byl@[ao_cs] rozmačkán@[ao_cs] mankubem.,%o blev knust af en mankubus.,%o wurde von einem Mancubus plattgemacht.,@[art_gr] %o λιόθηκε απο έναν Χοντρό.,%o estis dispremita de mankubo.,%o fue pulverizad@[ao_esp] por un mancubus.,,%o joutui mankubuksen liiskaamaksi.,%o s'est fait@[e_fr] aplatir par un Mancube.,%o-t szétlapította egy mankubusz.,%o è stato disintegrato da un mancubus.,%o はマンキュバスに潰された。,%o 은(는) 맨큐버스에게 짓이겨졌다.,%o werd verpletterd door een mancubus.,%o ble knust av en mancubus.,%o został@[ao_pl] zmiażdżon@[adj_pl] przez antropokuba.,%o foi esmagad@[ao_ptb] por um mancubus.,,%o a fost strivit de un mancubus.,Игрока %o раздавил манкубус.,Играча %o је изгњечио манкубус.,%o bir mancubus tarafından ezildi. -%o was perforated by a chaingunner.,OB_CHAINGUY,,,,%o byl@[ao_cs] prostřelen@[ao_cs] kulometčíkem.,%o blev perforeret af en chaingunner.,%o wurde von einem MG-Schützen perforiert.,@[art_gr] %o εκτελέστικε απο ένα Ζόμπι με ένα πολυβόλο.,%o estis truigadita de maŝinpafilisto.,%o fue perforad@[ao_esp] por un ametrallador.,,%o joutui konekiväärimiehen rei'ittämäksi.,%o a été perforé@[e_fr] par un mitrailleur.,%o-t szitává lőtte egy kommandós.,%o è stato perforato da uno zombie commando.,%o はチェインガンナーに蜂の巣にされた。,%o 은(는) 체인거너에 의해 벌집이 됐다.,%o werd geperforeerd door een zware wapens kerel.,%o ble perforert av en chaingunner.,%o został@[ao_pl] przedziurawion@[adj_pl] przez ciężkozbrojnego zombie.,%o foi perfurad@[ao_ptb] por um comando possuído.,%o foi perfurad@[ao_ptb] por um metrelhador.,%o a fost perforat de un mitralior.,Игрока %o продырявил пулемётчик.,Играча %o је изрешетао митраљезац.,%o bir ağır silah tarafından delindi. -%o was spooked by a lost soul.,OB_SKULL,,,,%o se lekl@[ao_cs] ztracené duše.,%o blev skræmt af en fortabt sjæl.,%o wurde von einer Verlorenen Seele heimgesucht.,Μια Χαμένη Ξυχή φόβησε @[pro_gr] %o.,%o estis timigita de perdita animo.,%o se murió de miedo ante un alma errante.,,%o joutui kadonneen sielun säikäyttämäksi.,%o s'est fait@[e_fr] surprendre par une âme perdue.,%o-t halálra ijesztette egy kóbor lélek.,%o è stato spaventato a morte da un'Anima Errante.,%o はロストソウルにビビらされた。,%o 은(는) 로스트 소울을 보고 깜짝 놀랐다.,%o werd bang gemaakt door een verloren ziel.,%o ble skremt av en fortapt sjel.,%o został@[ao_pl] przestraszon@[adj_pl] przez zaginioną duszę.,%o se assustou com uma alma perdida.,%o se assustou com uma alma penada.,%o a fost speriat de un suflet pierdut.,Игрок %o запуган до смерти потерянной душой.,%o је уплашен@[adj_1_sr] од изгубљене душе.,%o kayıp bir ruh tarafından korkutuldu. -%o was burned by an imp.,OB_IMP,,,,%o byl@[ao_cs] spálen@[ao_cs] čertem.,%o blev brændt af en spøgelse.,%o wurde von einem Kobold verbrannt.,@[art_gr] %o κάικε απο έναν Διάβολο.,%o estis bruligita de diableto.,%o fue incendiad@[ao_esp] por un imp.,,%o joutui pirun polttamaksi.,%o brûlé@[e_fr] par un diablotin.,%o-t szénné égette egy tűzkobold.,%o è stato bruciato da un imp.,%o はインプに焼かれた。,%o 은(는) 임프에게 불태워졌다.,%o werd verbrand door een imp.,%o ble brent av en imp.,%o został@[ao_pl] spalon@[adj_pl] przez diablika.,%o foi queimad@[ao_ptb] por um diabrete.,,%o a fost ars de un demon.,Игрока %o сжёг имп.,%o је изгорен@[adj_1_sr] од стране врага.,%o bir imp tarafından yakıldı. -%o was smitten by a cacodemon.,OB_CACO,,,,%o byl@[ao_cs] udeřen@[ao_cs] kakodémonem.,%o blev ramt af en cacodæmon.,%o wurde von einem Cacodämonen gequält.,@[art_gr] %o καίκε απο έναν Κακοδαίμονα.,%o estis venkobatita de kakodemono.,%o fue aniquilad@[ao_esp] por un cacodemonio.,,%o joutui kakodemonin iskemäksi.,%o a été terrassé@[e_fr] par un Cacodémon.,%o-ra lesújtott egy kakodémon.,%o è stato abbattuto da un cacodemone.,%o はカコデーモンに裁きを受けた。,%o 은(는) 카코데몬에게 엄습 당했다.,%o werd geslagen door een cacodemon.,%o ble slått av en kakodemon.,%o został@[ao_pl] porażon@[adj_pl] przez kakodemona.,%o foi golpead@[ao_ptb] por um cacodemônio.,,%o a fost lovit de un cacodemon.,Игрока %o поразил какодемон.,Играча %o је ударио какодемон.,%o bir caco iblisi tarafından vuruldu. -%o was bruised by a Baron of Hell.,OB_BARON,,,,%o byl@[ao_cs] pomačkán@[ao_cs] baronem pekel.,%o blev såret af en helvedesbaron.,%o wurde von einem Höllenbaron geröstet.,@[art_gr] %o γρατζουνήθηκε απο ένα Βαρώνο της Κόλασης.,%o estis kontuzita de Barono de Infero.,%o fue vapulead@[ao_esp] por un Barón del Infierno.,,%o joutui hornanparonin ruhjomaksi.,%o a été démoli@[e_fr] par un Baron des Enfers.,%o-t összezúzta egy pokolbáró.,%o è stato scorticato da un Barone Infernale.,%o はバロンオブヘルに痛めつけられた。,%o 은(는) 바론 오브 헬에게 상처받았다.,%o werd gekneusd door een baron van de hel.,%o ble forslått av en helvetesbaron.,%o został@[ao_pl] stłuczon@[adj_pl] Barona Piekła.,%o foi ferid@[ao_ptb] por um Barão do Inferno.,,%o a fost contuzionat de un Baron al Infernului.,Игрок %o зашиблен бароном ада.,%o је мод@[adj_3_sr] због барона пакла.,%o bir Cehennem Baronu tarafından yaralandı. -%o was splayed by a Hell Knight.,OB_KNIGHT,,,,%o byl@[ao_cs] rozpůlen@[ao_cs] rytířem pekel.,%o blev splejset af en helvedesridder.,%o wurde von einem Höllenritter gebraten.,@[art_gr] %o απλώθηκε απο έναν Ιππότη της Κόλασης,%o estis bisekcita de Inferkavaliro.,%o fue partid@[ao_esp] en dos por un Caballero del Infierno.,,%o joutui hornanritarin repimäksi.,%o a été éclaté@[e_fr] par un chevalier infernal.,%o-t kilapította egy pokollovag.,%o è stato squartato da un Cavaliere Infernale.,%o はヘルナイトにバラ撒かれた。,%o 은(는) 헬 나이트에게 갈라졌다.,%o werd gespierd door een hel ridder.,Jeg ble sprettet opp av en helvetesridder.,%o został@[ao_pl] rozcapierzon@[adj_pl] przez Rycerza Piekła.,%o foi espalmad@[ao_ptb] por um Cavaleiro Infernal.,%o foi espalmad@[ao_ptb] por um Cavaleiro Infernal.,%o a fost scrântit de un Cavaler al Infernului.,Игрока %o распластал рыцарь ада.,%o је раширен@[adj_1_sr] због витеза пакла.,%o bir Cehennem Şövalyesi tarafından yere serildi. -%o stood in awe of the spider demon.,OB_SPIDER,,,,%o zůstal@[ao_cs] stát v úžasu před pavoučím démonem.,%o stod i ærefrygt for edderkoppedæmonen.,%o stand in Ehrfurcht vor dem Spinnendämon.,@[art_gr] %o στάθηκε με δέος μπροστά στόν αραχνοδαίμονα.,%o staris mirigita antaŭ la aranedemono.,%o no tuvo oportunidad contra la mente-maestra arácnida.,,%o kunnioitti syvästi hämähäkkidemonia,%o est resté pris@[e_fr] d'admiration devant le Démon Arachnéen.,%o halálra ijedt a Pókelme.,%o è stato soggiogato dal Ragno demoniaco.,%o はスパイダーデーモンに恐れをなした。,%o 은(는) 거미악마의 무자비함을 느꼈다.,%o stond in ontzag voor de spindemon.,%o sto i ærefrykt for edderkoppdemonen.,%o podziwiał@[ao_pl] pajęczego mistrza.,%o ajoelhou-se em frente da Aranha-Mestra.,,%o a stat înfricoșat în fața păianjenului maestru.,Игрок %o стоял в восторге перед пауком-предводителем.,%o се смрзну@[ao_1_sr] у очарању паук-руководилаца.,%o örümcek iblisin karşısında huşu içinde durdu. -%o let an arachnotron get %h.,OB_BABY,,,,%o se nechal@[ao_cs] dostat arachnotronem.,%o blev sprængt af en arachnotron.,%o ließ sich von einem Arachnotron erledigen.,@[art_gr] %o άφησε ένα Αράχνοτρον να @[pro_gr] σκοτώσει.,%o lasis elektraraneon venki @[pro_eo]n.,%o fue alcanzad@[ao_esp] por un aracnotrón.,,%o antoi anaktrotronin saada hänet.,%o a laissé un arachnotron l'avoir@[e_fr].,"%o hagyta, hogy elkapja egy póktron.",%o ha permesso che un arachnotron l'uccidesse.,%o が アラクノトロンに討ち取られた。,%o 은(는) 아라크노트론이 %o를(을) 죽이도록 놔두었다.,%o werd gedood door een arachnotron,%o ble sprengt av et arachnotron.,%o pozwolił@[ao_pl] arachnotronowi się do siebie dobrać.,%o foi peg@[ao_ptb] por uma arachnotron.,%o foi apanhad@[ao_ptb] por uma arachnotron.,%o s-a lăsat prins de un aracnotron.,Игрок %o дал себя на откуп арахнотрону.,%o је допусти@[ao_1_sr] да паукотрон дође до %h.,%o bir araknotronun onu yakalamasına izin verdi. -%o was splattered by a cyberdemon.,OB_CYBORG,,,,%o byl@[ao_cs] rozplesknut@[ao_cs] na kaši kyberdémonem.,%o blev splattet af en cyberdæmon.,%o wurde von einem Cyberdämon zerfetzt.,@[art_gr] %o έσκασε απο ένα Cyber-δαίμονα.,%o estis disŝprucigita de ciberdemono.,%o fue hech@[ao_esp] pedazos por un ciberdemonio.,,%o joutui kyberdemonin yltympäri roiskimaksi.,%o a été pulvérisé@[e_fr] par un Cyberdémon.,%o-t cafatokra tépték a kiberdémon rakétái.,%o è stato spiaccicato da un Cyberdemone.,%o はサイバーデーモンにバラバラにされた。,%o 은(는) 사이버데몬에 의해 산산조각이 났다.,%o werd gespetterd door een cyberdemon.,%o ble sprutet av en kyberdemon.,%o został@[ao_pl] rozbryzgan@[adj_pl] przez cyberdemona.,%o foi arrebentad@[ao_ptb] pelo Ciberdemônio.,,%o a fost împroșcat de ciberdemon.,Игрока %o размазал кибердемон.,%o је спљоштен@[adj_1_sr] од стране сајбердемона,%o bir siber iblis tarafından parçalandı. -%o met a Nazi.,OB_WOLFSS,,,,%o potkal@[ao_cs] nácka.,%o mødte en nazist.,%o traf einen Nazi.,@[art_gr] %o χνώρισε ένα Ναζιστή.,%o renkontis Nazion.,%o se encontró a un Nazi.,,%o tapasi natsin.,%o a rencontré un Nazi.,%o találkozott egy nácival.,%o ha incontrato un Nazista.,%o はナチ兵と遭遇した。,%o 은(는) 나치를 만났다.,%o ontmoette een nazi.,Jeg møtte en nazist.,%o spotkał@[ao_pl] nazistę.,%o encontrou um Nazista.,%o encontrou um Nazi.,%o a întâlnit un Nazist.,Игрок %o встретил нациста.,%o је упозна@[ao_1_sr] нацисту.,%o bir Nazi ile karşılaştı. -%o was mauled by a dog.,OB_DOG,,,,%o byl@[ao_cs] roztrhán@[ao_cs] psem.,%o blev mast af en hund.,%o wurde von einem Hund zerrissen.,@[art_gr] %o φαγόθικε απο ένα σκύλο.,%o estis atakita de hundo.,%o fue magullad@[ao_esp] por un perro.,,%o joutui koiran raatelemaksi.,%o s'est fait mordre par un chien.,%o-t szétmarcangolta egy kutya.,%o è stato sbranato da un cane.,%o は犬に引き裂かれた。,%o 은(는) 개한테 으스러졌다.,%o werd verminkt door een hond.,%o ble maltraktert av en hund.,%o został@[ao_pl] poturbowan@[adj_pl] przez psa.,%o foi mutilad@[ao_ptb] por um cachorro.,%o foi mutilad@[ao_ptb] por um cão.,%o a fost sfâșiat de un câine.,Игрока %o разорвала собака.,Играча %o је удавио пас.,%o bir köpek tarafından parçalandı. -%o chewed on %k's fist.,OB_MPFIST,,,,%o si pochutnal@[ao_cs] na pěsti hráče %k.,%o tyggede på %ks knytnæve.,%o kaute auf %ks Faust herum.,@[art_gr] %o μάσησε τη γροθία του/της %k.,%o maĉis la pugnon de %k.,%o masticó el puño de %k.,,%k rusikoi %o paran.,%o a bouffé le poing de %k.,%o megkóstolta %k ökleit.,%o si è schiantato contro il pugno di %k.,%o は %k の拳を顔面に受けた。,%o 은(는) %k 의 주먹을 물었다.,%o gekauwd op %k's vuist.,%o tygget på %ks knyttneve.,%o przygryza pięść %k.,%o foi espancad@[ao_ptb] até a morte por %k,,%o a mestecat pumnul lui %k.,Игрок %o отведал кулака игрока %k.,Играча %o је сажвакао песницу играча %k.,"%o, %k tarafından öldürüldü." -%o was mowed over by %k's chainsaw.,OB_MPCHAINSAW,,,,%o byl@[ao_cs] zkácen@[ao_cs] motorovkou hráče %k.,%o blev slået ned af %ks motorsav.,%o wurde von %ks Kettensäge zerteilt.,@[art_gr] %o κόπηκε απο το αλλησοπρίονο του/της %k.,%o estis buĉita de la ĉensegilo de %k.,%o fue masacrad@[ao_esp] por la motosierra de %k.,,%k katkoi %o paran.,%o a été tondu@[e_fr] par la tronconneuse de %k.,%o-t kettészelte %k láncfűrésze.,%o è stato falciato dalla motosega di %k.,%o は %k のチェーンソーで刈り取られた。,%o 은(는) %k 의 전기톱에 갈렸다.,%o werd gemaaid met %k's kettingzaag.,%o ble klippet over av %ks motorsag.,%o został@[ao_pl] skoszon@[adj_pl] przez piłę łańcuchową %k.,%o foi picad@[ao_ptb] pela motoserra de %k,,%o a fost tăiat de drujba lui %k.,Игрока %o разрезал бензопилой игрок %k.,%o је исечен@[adj_1_sr] моторном тестером играча %k.,"%o, %k tarafından biçildi" -%o was tickled by %k's pea shooter.,OB_MPPISTOL,,,,%o byl@[ao_cs] polechtán@[ao_cs] pistolkou hráče %k.,%o blev kildet af %ks ærteskytte.,%o wurde von %ks Erbsenpistole gekitzelt.,@[art_gr] %o γαργαλίθηκε απο το οπλάκι του/της %k.,%o estis tiklita de la pafileto de %k.,%o fue cosquillead@[ao_esp] por el tirachinas de %k.,%o ha sido asesinad@[ao_esp] por la pipa de %k.,%o kutitti %o parkaa hernepyssyllään.,%o a été châtouillé@[e_fr] par le pistolet de %k.,%o meg lett csiklandozva %k játékpisztolyával.,%o è stato sforacchiato dalla pistola di %k'.,%o は %k の豆鉄砲でくすぐられた。,%o 은(는) %k 의 권총에 간지럼을 탔다.,%o werd gekieteld door %k's erwtenschutter.,%o ble kilt av %ks ertebøsse.,%o został@[ao_pl] połaskotan@[adj_pl] przez spluwę %k.,%o levou cócegas da pistolinha de %k.,,%o a fost gâdilat de pistolașul lui %k.,Игрока %o защекочен вусмерть из горохострела игрока %k.,%o је заголицан@[adj_1_sr] пиштољем играча %k.,"%o, %k tarafından gıdıklandı" -%o chewed on %k's boomstick.,OB_MPSHOTGUN,,,,%o si pochutnal@[ao_cs] na brokádě hráče %k.,%o tyggede på %ks bommestok.,%o wurde Opfer von %ks Schrotflinte.,@[art_gr] %o έφαγε το ντουφέκι του/της %k.,%o maĉis la ĉaspafilon de %k.,%o mordió@[ao_esp] el trabuco de %k.,%o ha sido agujeread@[ao_esp] por el trabuco de %k.,%k jauhoi %o paran tussarillaan.,%o a s'est mangé@[e_fr] de la chevrotine de la part de %k.,%o megízlelte %k villámbotját.,%o si è trovato davanti il fucile di %k.,%o は %k のブームスティックを顔面に受けた。,%o 은(는) %k 의 붐스틱에 꽂혔다.,%o gekauwd op %k's boomstick.,%o tygget på %ks boomstick.,%o przygryza pukawkę %k.,%o foi mort@[ao_ptb] pela espingarda de %k.,,%o a mestecat pușca lui %k.,Игрока %o накормил дробью игрок %k.,%o је сажвака@[ao_1_sr] на пумпарицу играча %k.,"%o, %k tarafından patlatıldı" -%o was splattered by %k's super shotgun.,OB_MPSSHOTGUN,,,,%o byl@[ao_cs] rozplesknut@[ao_cs] na kaši superbrokovnicí hráče %k.,%o blev sprøjtet af %ks super haglgevær.,%o wurde von %ks Super-Schrotflinte zerfetzt.,@[art_gr] %o διαλύθηκε απο το διπλό ντουφέκι του/της %k,%o estis disŝprucigita de la supera ĉaspafilo de %k.,%o fue reventad@[ao_esp] por la súper escopeta de %k.,,%k roiski %o paran yltympäriinsä superhaulikollaan.,%o s'est fait@[e_fr] gicler par le fusil de chasse de %k.,%o-t cafatokra tépte %k szupersörétese.,%o è stato smembrato dalla doppietta di %k.,%o は %k のスーパーショットガンでバラバラにされた。,%o 은(는) %k 의 슈퍼 샷건에 의해 터졌다.,%o werd gespat door %k's super jachtgeweer.,%o ble skutt med %ks super-haglgevær.,%o został@[ao_pl] rozpryskan@[adj_pl] przez super strzelbę %k.,%o foi estraçalhad@[ao_ptb] pela espingarda de cano duplo de %k.,,%o a fost împroșcat de super pușca lui %k.,Игрока %o размазал из супердробовика игрок %k.,Играча %o је спљоштила двоцевка играча %k.,"%o, %k tarafından sıçratıldı" -%o was mowed down by %k's chaingun.,OB_MPCHAINGUN,,,,%o byl@[ao_cs] prostřílen@[ao_cs] kulometem hráče %k.,%o blev mejet ned af %ks maskingevær.,%o wurde von %ks Maschinengewehr niedergemäht.,@[art_gr] %o κοματίαστηκε απο το πολυβόλο του/της %k.,%o estis kuglo-plenigita de la maŝinpafilo de %k.,%o fue masacrado por la ametralladora de %k.,,%k niitti %o paran konekiväärillään.,%o a été ventilé@[e_fr] par la mitrailleuse de %k.,%k gépágyúval szétszaggatta %o testét.,%o è stato falciato dal mitragliatore di %k.,%o は %k のチェーンガンで蜂の巣にされた。,%o 은(는) %k 의 체인건에 의해 으깨졌다.,%o werd gemaaid met %k's machinegeweer.,%o ble meiet ned av %ks maskinpistol.,%o został@[ao_pl] skoszon@[adj_pl] przez karabin maszynowy %k.,%o foi massacrad@[ao_ptb] pela metralhadora de %k.,,%o a fost secerat de mitraliera rotativă a lui %k.,Игрок %o скошен из пулемёта игрока %k.,%o је покоси@[ao_1_sr] митраљез играча %k.,"%o, %k tarafından biçildi" -%o rode %k's rocket.,OB_MPROCKET,,,,%o se projel@[ao_cs] na raketě hráče %k.,%o red på %ks raket.,%o ritt auf %ks Rakete.,@[art_gr] %o καβάλησε τον πύραυλο του/της %k.,%o rajdis la raketon de %k.,%o se montó en el cohete de %k.,%o quería montarse en el cohete de %k.,%o ratsasti pelaajan %k raketilla.,%o a chevauché la roquette de %k.,%o meglovagolta %k rakétáját.,%o ha cavalcato il razzo di %k.,%o は %k のロケットに乗ってしまった。,%o 은(는) %k 의 로켓을 탔다.,%o reed op %k's raket.,%o red på %ks rakett.,%o ujeżdżał@[ao_pl] rakietę %k.,%o não viu o foguete de %k.,%o não viu o míssil de %k.,%o a călărit racheta lui %k.,Игрок %o прокатился на ракете игрока %k.,%o је ујаха@[ao_1_sr] ракету играча %k.,"%o, %k tarafından sıçratıldı" -%o almost dodged %k's rocket.,OB_MPR_SPLASH,,,,%o se skoro vyhnul@[ao_cs] raketě hráče %k.,%o undgik næsten %ks raket.,"%o schaffte es fast, %ks Rakete auszuweichen.",@[art_gr] %o σχεδόν απόφηγε τον πύραυλο του/της %k.,%o preskaŭ evitis la raketon de %k.,%o casi esquivó el cohete de %k.,%o casi esquiva el cohete de %k.,%o melkein väisti pelaajan %k raketin.,%o a presque esquivé la roquette de %k.,%o majdnem kitért %k rakétája elől.,%o aveva quasi schivato il razzo di %k.,%o は %k のロケットをあと少しで避けられそうだった。,%o 은(는) %k 의 로켓 폭발을 거의 피했다.,%o ontweek bijna %k's raket.,%o unngikk nesten %ks rakett.,%o prawie unika rakiety %k.,%o quase escapou do foguete de %k.,%o quase escapou do míssil de %k.,%o aproape a evitat racheta lui %k.,Игрок %o почти увернулся от ракеты %k.,%o је за длаку избега@[ao_1_sr] ракету играча %k.,"%o, %k tarafından sıçratıldı" -%o was melted by %k's plasma gun.,OB_MPPLASMARIFLE,,,,%o se roztekl@[ao_cs] plazmapuškou hráče %k.,%o blev smeltet af %ks plasma riffel.,%o wurde von %ks Plasmagewehr geschmolzen.,@[art_gr] %o λίοθηκε απο το πλάσμα όπλο του/της %k.,%o estis fandigita de la plasmo-pafilo de %k.,%o fue derretid@[ao_esp] por el rifle de plasma de %k.,,%k sulatti %o paran plasmapyssyllään.,%o a été réduit@[e_fr] en bouillie par le fusil a plasma de %k.,%k plazmafegyverével megolvaszotta %o testét.,%o è stato fuso dal fucile al plasma di %k.,%o は %k のプラズマガンに溶かされた。,%o 은(는) %k 의 플라즈마 건에 의해 융해되었다.,%o was gesmolten door %k's plasmageweer.,%o ble smeltet av %ks plasmakanon.,%o został@[ao_pl] stopion@[adj_pl] przez pistolet plasmowy %k.,%o foi torrad@[ao_ptb] pelo fuzil de plasma de %k.,%o foi torrad@[ao_ptb] pela pistola de plasma de %k.,%o a fost topit de pușca cu plasmă a lui %k.,Игрока %o расплавил из плазмомёта игрок %k.,%o је отопљен@[adj_1_sr] плазма оружјем играча %k.,"%o, %k tarafından eritildi" -%o was splintered by %k's BFG.,OB_MPBFG_BOOM,,,,%o byl@[ao_cs] rozštěpen@[ao_cs] BFGčkem hráče %k.,%o blev splintret af %ks BFG.,%o wurde von %ks BFG in Stücke gerissen.,@[art_gr] %o κοματιάστηκε απο το BFG του/της %k.,%o estis splitigita de la BFG de %k.,%o fue aniquilado por la BFG de %k.,,%k pirstoi %o paran BFG:llään.,%o a été oblitéré@[e_fr] par le BFG de %k.,%o teste atomjaira szakadt %k BFG-jétől.,%o è stato sminuzzato dal BFG di %k.,%o は %k のBFGで木っ端微塵にされた。,%o 은(는) %k 의 BFG덕에 산산조각 났다.,%o was versplinterd door %k's BFG.,%o ble splintret av %ks BFG.,%o został@[ao_pl] rozpryskan@[adj_pl] przez BFG %k.,%o foi vaporizad@[ao_ptb] pela BFG de %k.,,%o a fost despicat de către BFG-ul lui %k.,Игрока %o порвал на осколки выстрел из BFG игрока %k.,%o је расцепан@[adj_1_sr] ВЈП играча %k.,"%o, %k tarafından parçalandı" -%o couldn't hide from %k's BFG.,OB_MPBFG_SPLASH,,,,%o se nemohl@[ao_cs] ukrýt před BFGčkem hráče %k.,%o kunne ikke gemme sig for %ks BFG.,%o konnte sich nicht vor %ks BFG verstecken.,@[art_gr] %o δέν μπόρεσε να κρυφτέι απο το BFG του/της %k.,%o ne povis kaŝi sin de la BFG de %k.,%o no pudo esconderse de la BFG de %k.,,%o ei kyennyt piiloutumaan pelaajan %k BFG:ltä.,%o n a pas pu se couvrir du BFG de %k.,%o nem tudott elmenekülni %k BFG-je elől.,%o non poteva nascondersi dal BFG di %k.,%o は %k のBFGから隠れることはできなかった。,%o 은(는) %k 의 BFG의 일격으로부터 피할 수 없었다.,%o kon zich niet verbergen voor %k's BFG.,%o kunne ikke gjemme seg for %ks BFG.,%o nie może się schować przed BFG %k.,%o não conseguiu se esconder da BFG de %k,,%o nu s-a putut ascunde de BFG-ul lui %k.,Игрок %o не успел спрятаться от BFG игрока %k.,%o се није мог@[ao_2_sr] сакрити од ВЈП играча %k.,"%o, %k tarafından parçalandı" -%o was railed by %k.,OB_RAILGUN,,,,%o byl@[ao_cs] napíchnut@[ao_cs] hráčem %k.,%o blev skudt af %k.,%o stand in %ks Schusslinie.,@[art_gr] %o καρφόθηκε απο τον/την %k.,%o estis traborita de la elektropafilo de %k.,%o fue rielad@[ao_esp] por %k.,,%o lävisti %o paran.,%o a été aligné@[e_fr] par %k.,%o beleállt %k lézerébe.,%o è stato bucherellato dal railgun di %k.,%o は %k のレールガンで死亡した。,%o 은(는) %k 의 레일건에 관통당했다.,%o werd gespaakt door %k.,%o ble skutt av %k.,%o stał@[ao_pl] na linii ognia %k.,%o estava na mira do canhão elétrico de %k.,,%o a fost ocărit de %k.,Игрока %o пробил насквозь игрок %k.,%o је убијен@[adj_1_sr] од играча %k.,%o %k tarafından kovuldu. -%o was burned by %k's BFG.,OB_MPBFG_MBF,,,,%o shořel@[ao_cs] BFGčkem hráče %k.,%o blev brændt af %ks BFG.,%o wurde von %ks BFG verbrannt.,@[art_gr] %o κάικε απο το BFG του/της %k.,%o estis bruligita de la BFG de %k.,%o fue vaporizad@[ao_esp] por la BFG de %k.,,%k korvensi %o paran BFG:llään.,%o a été irradié@[e_fr] par le BFG de %k.,%k hamuvá égette %o testét BFG-vel.,%o è stato bruciato dal BFG di %k.,%o は %k のBFGで焼き殺された。,%o 은(는) %k 의 BFG에 의해 타올랐다.,%o werd verbrand door %k's BFG.,%o ble brent av %ks BFG.,%o został@[ao_pl] spalon@[adj_pl] przez BFG %k.,%o foi cozid@[ao_ptb] pela BFG de %k.,,%o a fost ars de BFG-ul lui %k.,Игрока %o сжёг из BFG игрок %k.,%o је изгоре@[ao_1_sr] од ВЈП играча %k.,%o %k tarafından yakıldı -,,Heretic,,,,,,,,,,,,,,,,,,,,,,,, -,,Pickup ,,,,,,,,,,,,,,,,,,,,,,,, -Blue Key,TXT_GOTBLUEKEY,,,,Modrý klíč,Blå nøgle,Blauer Schlüssel,Μπλέ Κλειδί,Blua Ŝlosilo,Llave Azul,,Sininen avain,Clé Bleue,Kék kulcs,Chiave blu,青の鍵,청색 열쇠,Blauwe sleutel,Blå nøkkel,Niebieski klucz,Chave Azul,,Cheie Albastră,Синий ключ,Плави кључ,Mavi Anahtar -Yellow Key,TXT_GOTYELLOWKEY,,,,Žlutý klíč,Gul nøgle,Gelber Schlüssel,Κύτρινο Κλειδί,Flava Ŝlosilo,Llave Amarilla,,Keltainen avain,Clé Jaune,Sárga kulcs,Chiave gialla,黄の鍵,황색 열쇠,Gele sleutel,Gul nøkkel,Żółty klucz,Chave Amarela,,Cheie Galbenă,Жёлтый ключ,Жути кључ,Sarı Anahtar -Green Key,TXT_GOTGREENKEY,,,,Zelený klíč,Grøn nøgle,Grüner Schlüssel,Πράσινο Κλειδί,Verda Ŝlosilo,Llave Verde,,Vihreä avain,Clé Verte,Zöld kulcs,Chiave verde,緑の鍵,녹색 열쇠,Groene sleutel,Grønn nøkkel,Zielony klucz,Chave Verde,,Cheie Verde,Зелёный ключ,Зелени кључ,Yeşil Anahtar -Quartz Flask,TXT_ARTIHEALTH,,,,Blyštivá baňka,Kvartsflaske,Quarzflasche,Φλάσκα Χαλαζίας,Kvarca Flakono,Frasco de Cuarzo,,Kvartsipullo,Flasque en Quartz,Kvarc flaska,Ampolla di quarzo,石英フラスコ,석영 플라스크,Kwartskolf,Kvartskolbe,Kwarcowa Butelka,Frasco de Quartzo,,Flacon de Quartz,Кварцевый флакон,Кварцна боца,Kuvars Şişesi -Wings of Wrath,TXT_ARTIFLY,,,,Křídla hněvu,Vredens vinger,Flügel des Zorns,Φτερά της Οργής,Flugiloj de Kolero,Alas de Ira,,Kiihtymyksen siivet,Ailes du Courroux,A Harag Szárnyai,Ali iraconde,レイスの翼,분노의 날개,Vleugels der Toorn,Vredens vinger,Skrzydła Gniewu,Asas da Ira,,Aripile Furiei,Крылья гнева,Крила гнева,Gazap Kanatları -Ring of Invincibility,TXT_ARTIINVULNERABILITY,,,,Prsten nesmrtelnosti,Ring af uovervindelighed,Ring der Unverwundbarkeit,Δαχτυλίδι της Αθανασίας,Ringo de Nevenkebleco,Anillo de Invencibilidad,,Näkymättömyyden sormus,Anneau d'Invincibilité,A Sérthetetlenség Gyűrűje,Anello dell'invincibilità,不死の指輪,불멸의 반지,Ring van Onoverwinnelijkheid,Uovervinnelighetens ring,Pierścień Niewrażliwości,Anel da Invencibilidade,,Inelul Invincibilității,Кольцо неуязвимости,Прстен непобедивости,Yenilmezlik Yüzüğü -Tome of Power,TXT_ARTITOMEOFPOWER,,,,Kniha moci,Bog om magt,Buch der Macht,Τομός της Δύναμης,Librego de Forto,Tomo de Poder,,Väkevyyden kirja,Livre du Pouvoir,Az Erő Kódexe,Tomo del potere,力の術書,힘의 서,Boek van de Macht,Maktens bok,Tom Mocy,Livro do Poder,Livro do Poder,Cartea Puterii,Том могущества,Том моћи,Güç Kitabı -Shadowsphere,TXT_ARTIINVISIBILITY,,,,Šerosféra,Skyggesfære,Schattensphäre,Σκιόσφαιρα,Ombrosfero,Esfera de Sombra,,Varjokehrä,Sphère des Ombres,Árnygömb,Sfera dell'ombra,闇の球体,그림자 구체,Schaduwbol,Skyggesfære,Sfera Cieni,Esfera das Sombras,,Sfera Umbrei,Теневая сфера,Сфера сенки,Gölge Küre -Morph Ovum,TXT_ARTIEGG,,,,Měnivejce,Morph Ovum,Transformations-Ei,Μετασχηματίζοντικο Ωάριο,Ovo de Transformado,Huevo de Transformación,,Muodonmuutoksen muna,Ovule de Métamorphose,Alakváltó tojás,Uovo della metamorfosi,変貌の卵子,변신 알,Morfose-Ei,Morph Ovum,Jajko Morfujące,Ovo da Metamorfose,,Oul Metamorfozei,Яйцо превращения,Преображавајуће јајашце,Dönüşümlü Yumurta -Mystic Urn,TXT_ARTISUPERHEALTH,,,,Tajemná urna,Mystisk urne,Mystische Urne,Μυστικό Δοχείο,Mistika Urno,Urna Mística,,Mystinen uurna,Urne Mystique,Misztikus urna,Urna mistica,神秘の骨壷,신비한 항아리,Mystieke Urn,Mystisk urne,Mistyczna Urna,Urna Mística,,Urnă Mistică,Мистическая урна,Мистериозна урна,Mistik Urn -Torch,TXT_ARTITORCH,,,,Pochodeň,Fakkel,Fackel,Πυρσός,Torĉo,Antorcha,,Soihtu,Torche,Fáklya,Torcia,松明,횃불,Fakkel,Fakkel,Pochodnia,Tocha,,Torță,Факел,Бакља,Meşale -Time Bomb of the Ancients,TXT_ARTIFIREBOMB,,,,Časovaná bomba starověku,De ældres tidsbombe,Zeitbombe der Alten,Χρονοβόμβα τον Αρχαίων,Tempobombo de la Antikvuloj,Bomba de tiempo de los Ancestros,,Vanhain aikapommi,Bombe a Retardement des Anciens,Az Ősök Időbombája,Bomba a tempo degli antichi,古代の時限爆薬,고대의 시한폭탄,Tijdbom der Tijden,De eldgamles tidsinnstilte bombe,Starożytna Bomba Czasu,Bomba-relógio dos Anciãos,,Bomba cu Ceas a Anticilor,Часовая бомба древних,Временска бомба древних,Kadimlerin Saatli Bombası +această ușă",Для открытия нужен жёлтый череп,Треба вам жута лобања да би отворили ова врата,Du behöver en gul skalle för att öppna den här dörren.,Bu kapıyı açmak için sarı bir kafatasına ihtiyacın var. +,,Cast call names,,,,,,,,,,,,,,,,,,,,,,,,, +Zombieman,CC_ZOMBIE,,,,Zombie,Zombie,Zombie,Ζόμπι,Zombiviro,Zombi,,Zombimies,Zombie,Zombi,Zombie Marine,ゾンビ兵,좀비맨,Zombie,Zombiemann,Zombie,Zumbi,Homem Zombie,Zombi,Зомби,Зомби,Zombie,Zombi +Shotgun Guy,CC_SHOTGUN,a.k.a. (former human) sergeant,,,Seržant,Sergent,Schütze,Τύπος με ντουφέκι,Ĉaspafilulo,Tipo de Escopeta,Tipo de la escopeta,Haulikkohemmo,Type au Fusil,Őrmester,Zombie Sergente,ショットガンゾンビ,샷건 가이,Jachtgeweerkerel,Sersjant,Zombie-sierżant,Sargento Possuído,Tipo de Espingarda,Pușcaș,Зомби-сержант,Пумпераш,Hagelgevärskille,Çavuş +Heavy Weapon Dude,CC_HEAVY,a.k.a. former commando,,,Kulometčík,,MG-Schütze,Τύπος με βαρί όπλο,Pezarmilulo,Tipo de Armas Pesadas,Ametrallador,Raskasaseäijä,Type au Gros Flingue,Kommandós,Zombie Commando,ヘビーウェポンゾンビ,헤비 웨폰 듀드,Zwarewapenskerel,Maskingeværskyt,Ciężkozbrojny Zombie,Comando Possuído,Gajo das Armas Pesadas,Mitralior,Зомби-пулемётчик,Митраљезац,Tunga vapen kille,Ağır Silah Dostum +Imp,CC_IMP,,,,Čert,,Kobold,Διάβολος,Diableto,,,Piru,Diablotin,Tűzkobold,,インプ,임프,,,Diablik,Diabrete,,Drac,Имп,Враг,,İmp +Demon,CC_DEMON,,,,Démon,Dæmon,Dämon,Δαίμονας,Demono,Demonio,,Demoni,Démon,Démon,Pinky,デーモン,데몬,Demoon,,,Demônio,,,Демон,Демон,,İblis +Lost Soul,CC_LOST,,,,Ztracená duše,Fortabt sjæl,Verlorene Seele,Χαμένη Ξυχή,Perdita Animo,Alma Errante,,Kadonnut sielu,Ame Perdue,Kóbor lélek,Anima Errante,ロストソウル,로스트 소울,Verloren ziel,Fortapt sjel,Zaginiona Dusza,Alma Perdida,Alma Penada,Suflet Pierdut,Потерянная душа,Изгубљена душа,Förlorad själ,Kayıp Ruh +Cacodemon,CC_CACO,,,,Kakodémon,Cacodæmon,Cacodämon,Κακοδαίμονας,Kakodemono,Cacodemonio,,Kakodemoni,Cacodémon,Kakodémon,Cacodemone,カコデーモン,카코데몬,Cacodemoon,Kacodemon,Kakodemon,Cacodemônio,,Cacodemon,Какодемон,Какодемон,Cacodemon,Cacodemon +Hell Knight,CC_HELL,,,,Pekelný rytíř,Helvedesridder,Höllenritter,Ιππότης της Κόλασης,Inferkavaliro,Caballero del Infierno,,Hornanritari,Chevalier Infernal,Pokollovag,Cavaliere Infernale,ヘルナイト,헬 나이트,Helleridder,Helvetesridder,Rycerz Piekła,Cavaleiro Infernal,Cavaleiro Infernal,Cavaler al Infernului,Рыцарь ада,Витез пакла,Helvete riddare,Cehennem Şövalyesi +Baron of Hell,CC_BARON,,,,Baron pekel,Helvedesbaron,Höllenbaron,Βαρώνος της Κολασης,Barono de Infero,Barón del Infierno,,Hornanparoni,Baron des Enfers,Pokolbáró,Barone Infernale,バロンオブヘル,바론 오브 헬,Baron des Hels,Helvetesbaron,Baron Piekła,Barão do Inferno,,Baron al Infernului,Барон ада,Барон пакла,Helvetets baron,Cehennem Baronu +Arachnotron,CC_ARACH,,,,,,,Αράχνοτρον,Elektraraneo,Aracnotrón,,Araknotroni,,Póktron,,アラクノトロン,아라크노트론,,,,Aracnotron,,Aracnotron,Арахнотрон,Паукотрон,,Araknotron +Pain Elemental,CC_PAIN,,,,Živel trýzně,Smerteelementar,Elementarschmerz,Στοιχείομα του Πόνου,Doloro-Elementulo,Elemental del Dolor,,Kivun henki,Elémentaire de Douleur,Elemi Kín,Elementale del Dolore,ペインエレメンタル,페인 엘리멘탈,Smartelementaal,Smerte Elemental,Żywiołak Bólu,Elemental da Dor,,Elemental al Durerii,Элементаль боли,Елементал патње,Smärta elementär,Acı Elementi +Revenant,CC_REVEN,,,,Umrlec,Hævnen,Wiederauferstandener,Εκδικητής,Renaskitulo,,,Henkiinpalannut,,Kísértet,,レバナント,레버넌트,Wreker,Gjenganger,Zjawa,Insepulto,Renascido,Nemort,Ревенант,Повратник,Återfödare, +Mancubus,CC_MANCU,,,,Mankubus,,,Χοντρός,Mankubo,,,Mankubus,Mancube,Mankubusz,,マンキュバス,맨큐버스,,,Antropokub,,,,Манкубус,Манкубус,, +Arch-Vile,CC_ARCH,,,,Veleběs,Ærkevile,Scheusal,Νεκρομάντις,Ĉef-Fiulo,,,Arkkihirvitys,Arche-vile,Ősármány,Arch-vile,アーチバイル,아크-바일,Aartsgedrocht,Erkefiende,Arcy-Podlec,Arquivil,,Abject,Архвиль,Арчвајл,Ärkevild,Baş Aşağılık +The Spider Mastermind,CC_SPIDER,,,,Pavoučí velevůdce,Edderkoppen Mastermind,Der Spinnenmeister,Το Αραχνό Ιθύνων Νους,La Elektraraneo-Mastro,La Mente-Maestra Arácnida,,Hämähäkkiaivot,L'Araignée Commandante,Pókelme,L'Aracnomente Suprema,スパイダーマスターマインド,스파이더 마스터마인드,Het Spinnenmeesterbrein,Edderkopphjernen,Pajęczy Mistrz,A Aranha-Mestra,,Păianjen Maestru,Паук-предводитель,Паук-руководилац,Spindelns hjärna,Örümcek Beyni +The Cyberdemon,CC_CYBER,,,,Kyberdémon,Cyberdæmonen,Der Cyberdämon,Ο Cyber-δαίμονας,La Ciberdemono,El Ciberdemonio,,Kyberdemoni,Le Cyberdémon,A Kiberdémon,Il Cyberdemonio,サイバーデーモン,사이버데몬,Het Cyberdemoon,Kyberdemonen,Cyberdemon,O Ciberdemônio,,Ciberdemon,Кибердемон,Сајбердемон,Cyberdemon,Siber Şeytan +Our Hero,CC_HERO,,,,Náš hrdina,Vores helt,Unser Held,Ο ήρωας μας,Nia Heroo,Nuestro Héroe,,Sankarimme,Notre Héros,Hősünk,Il Nostro eroe,我らのヒーロー,우리들의 영웅,Onze held,Vår helt,Nasz bohater,Nosso herói,O Nosso Herói,Eroul Nostru,Наш герой,Наш херој,Vår hjälte,Bizim Kahramanımız +,,Actor tag names,,,,,,,,,,,,,,,,,,,,,,,,, +Sergeant,FN_SHOTGUN,,,,Seržant,Sergent,Schütze,Λοχίας,Serĝento,Sargento,,Kersantti,Type au Fusil,Őrmester,Zombie Sergente,ゾンビ軍曹,샷건 가이,,Sersjant,Zombie-sierżant,Sargento Possuído,Sargento,Sergent,Зомби-сержант,Водник,Hagelgevärskille,Çavuş +Chaingunner,FN_HEAVY,,,,Kulometčík,,MG-Schütze,Πολυβόλο Ζόμπι,Maŝinpafilisto,Ametrallador,,Konekiväärimies,Type au Gros Flingue,Kommandós,Zombie Commando,チェーンガンゾンビ,체인거너,Machinegeweerman,Maskingeværskyt,Ciężkozbrojny Zombie,Comando Possuído,Metrelhador,Mitralior,Зомби-пулемётчик,Митраљезац,Tunga vapen kille,Ağır Silah Dostum +Spectre,FN_SPECTRE,,,,Přízrak,Spøgelse,Schemen,Φάντασμα,Fantomo,Espectro,,Haamu,,Lidérc,Spettro,スペクトル,스펙터,Spook,Spøkelse,Widmo,Espectro,,Spectru,Фантом,Авет,,Hayalet +Spider Mastermind,FN_SPIDER,,,,Pavoučí velevůdce,Edderkoppen Mastermind,Spinnenmeister,Αραχνό Ιθύνων Νους,Elektraraneo-Mastro,Mente-Maestra Arácnida,,Hämähäkkiaivot,L'Araignée Commandante,Pókelme,L'Aracnomente Suprema,スパイダーマスターマインド,스파이더 마스터마인드,Spinnenmeesterbrein,Edderkopphjerne,Pajęczy Mistrz,A Aranha-Mestra,,Păianjen Maestru,Паук-предводитель,Паук-руководилац,Spindelns hjärna,Örümcek Beyni +Cyberdemon,FN_CYBER,,,,Kyberdémon,Cyberdæmon,Cyberdämon,Cyber-δαίμονας,Ciberdemono,Ciberdemonio,,Kyberdemoni,Le Cyberdémon,Kiberdémon,Il Cyberdemonio,サイバーデーモン,사이버데몬,Cyberdemoon,Kyberdemon,Cyberdemon,O Ciberdemônio,,Ciberdemon,Кибердемон,Сајбердемон,Cyberdemon,Siber İblis +Nazi,FN_WOLFSS,,,,Nácek,,,Ναζιστής,Nazio,,,Natsi,,Náci,Nazista,ナチ兵,나치,,Nazist,Nazista,Nazista,,Nazist,Нацист,Нациста,Nazist, +Dog,FN_DOG,,,,Pes,Hund,Hund,Σκύλος,Hundo,Perro,,Koira,Chien,Kutya,Cane,犬,개,Hond,Hund,Pies,Cão,,Câine,Собака,Пас,Hund,Köpek +Brass Knuckles,TAG_FIST,,,,Boxer,Messing knoer,Schlagringe,Γροθιά,Pugningo,Puño americano,Manopla (puño de acero),Nyrkkirauta,Poing Américain,Bokszer,Tirapugni ,ナックルダスター,너클,Boksbeugels,Knokejern,Kastety,Soco Inglês,Soqueira,Rozetă,Латунный кастет,Боксер,Mässingsknoglar,Pirinç Muşta +Chainsaw,TAG_CHAINSAW,,,,Motorová pila,Kædesav,Kettensäge,Αλλησοπρίονο,Ĉensegilo,Motosierra,,Moottorisaha,Tronçonneuse,Láncfűrész,Motosega,チェーンソウ,전기톱,Kettingzaag,Motorsag,Piła łańcuchowa,Motosserra,,Drujbă,Бензопила,Моторна тестера,Motorsåg,Testere +Pistol,TAG_PISTOL,,,,Pistole,,Pistole,Πιστόλι,Pafileto,Pistola,,Pistooli,Pistolet,Pisztoly,Pistola,ピストル,권총,Pistool,,Pistolet,Pistola,,,Пистолет,Пиштољ,,Tabanca +Shotgun,TAG_SHOTGUN,,,,Brokovnice,Haglgevær,Schrotflinte,Ντουφέκι,Kartoĉa fusilo,Escopeta,,Haulikko,Fusil à pompe,Sörétes Puska,Fucile,ショットガン,샷건,Jachtgeweer,Haglgevær,Strzelba,Espingarda,,Pușcă,Дробовик,Пумпарица,Hagelgevär,Av Tüfeği +Super Shotgun,TAG_SUPERSHOTGUN,,,,Superbrokovnice,Super-Haglgevær,Super-Schrotflinte,Διπλό Ντουφέκι,Dutuba fusilo,Superescopeta,,Superhaulikko,Super Fusil de chasse,Szuper Sörétes,Fucile a doppia canna ,スーパーショットガン,슈퍼 샷건,Superjachtgeweer,Super-Haglgevær,Super strzelba,Espingarda de cano duplo,,Super Pușcă,Супердробовик,Двоцевка,Super hagelgevär,Süper Av Tüfeği +Chaingun,TAG_CHAINGUN,,,,Kulomet,Maskingevær,Maschinengewehr,Πολυβόλο,Maŝinpafilo,Ametralladora,,Gatling-kk,Mitrailleuse,Golyószóró,Mitragliatore a canne rotanti ,チェーンガン,체인건,Machinegeweer,Maskinpistol,Karabin maszynowy,Metralhadora,,Mitralieră rotativă,Пулемёт,Митраљез,Kedjepistol, +Rocket Launcher,TAG_ROCKETLAUNCHER,,,,Raketomet,Raketkaster,Raketenwerfer,Πυραυλοβόλο,Misilpafilo,Lanzamisiles,,Sinko,Lance-Roquettes,Rakétavető,Lanciamissili,ロケットランチャー,로켓 런쳐,Raketwerper,Rakettkaster,Wyrzutnia rakiet,Lança-foguetes,Lança-Mísseis,Lansator de Rachete,Ракетомёт,Бацач ракета,Raketkastare,Roket Fırlatıcı +Plasma Rifle,TAG_PLASMARIFLE,,,,Plazmová puška,Plasma riffel,Plasmagewehr,Πλάσμα Όπλο,Plasmo-pafilo,Fusil de plasma,,Plasmapyssy,Fusil à Plasma,Plazmafegyver,Fucile al Plasma ,プラズマライフル,플라즈마 라이플,Plasmageweer,Plasmagevær,Karabin plazmowy,Fuzil de Plasma,Pistola de Plasma,Pușcă cu Plasmă,Плазменная пушка,Плазма оружје,Plasmagevär,Plazma Tüfeği +BFG 9000,TAG_BFG9000,,,,,,,,,,,,,,,,,,,,,,,,ВЈП 9000,, +Bullets,AMMO_CLIP,,,,Kulky,Kugler,Patronen,Σφαίρες,Kugloj,Balas,,Luodit,Balles,Töltények,Proiettili,銃弾,권총 탄약,Kogels,Kuler,Naboje,Balas,,Gloanțe,Пули,Меци,Kulor,Kurşunlar +Shotgun Shells,AMMO_SHELLS,,,,Broky,Haglgeværpatroner,Schrotpatronen,Σφαίρες Ντουφεκιού,Kartoĉoj,Cartuchos de escopeta,,Haulikon patruunat,Cartouches,Sörétek,Cartucce per fucile,散弾シェル,샷건 탄약,Jachtgeweerkogels,Haglepatroner,Loftki,Cartuchos de Espingarda,,Proiectile pentru Pușcă,Патроны дробовика,Патроне за пумпарицу,Skottgubbar,Av Tüfeği Fişekleri +Rockets,AMMO_ROCKETS,,,,Rakety,Raketter,Raketen,Πύραυλοι,Raketoj,Cohetes,,Raketit,Roquettes,Rakéták,Razzi,ロケット弾,로켓,Raketten,Raketter,Rakiety,Foguetes,Mísseis,Rachete,Ракеты,Ракете,Raketer,Roketler +Energy Cells,AMMO_CELLS,,,,Energetické články,Energiceller,Energiezellen,Κύτταρα Ενέργιας,Energiĉeloj,Célula de energía,,Energia-akut,Cellules,Energiacellák,Batterie,エネルギーセル,에너지 셀,Energiecellen,Energiceller,Ogniwa energetyczne,Células de Energia,,Celule cu Energie,Энергобатареи,Енергетске ћелије,Energiceller,Enerji Hücreleri +,,Obituaries,,,,,,,,,,,,,,,,,,,,,,,,, +%o thought %g saw an arachnotron.,OB_STEALTHBABY,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] arachnotrona.","%o troede, @[pro_dk] så en arachnotron.","%o dachte, ein Arachnotron zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Αραχνοτρόν.,"%o pensis, ke @[pro_eo] vidis elektraraneon.",%o ha creído ver un Aracnotrón.,%o creyó haber visto un Aracnotrón.,%o luuli nähneensä araknotronin.,%o a cru voir un Arachnotron.,"%o azt hitte, hogy látott egy póktront.",a %o sembrava di aver visto un arachnotron.,%o がアラクノトロンを見た気がした。,%o 은(는) 아라크노트론을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een arachnotron zag.,%o trodde @[pro_dk] så et arachnotron.,%o kątem oka zauważył@[ao_pl] arachnotrona.,%o achou que viu uma arachnotron.,,%o a crezut că %g a văzut un aracnotron.,Игрок %o краем глаза заметил арахнотрона.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] паукотрона.,%o trodde att @[pro_sv] såg en arachnotron.,%o bir araknotron gördüğünü sandı. +%o thought %g saw an archvile.,OB_STEALTHVILE,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] veleběsa.","%o troede, @[pro_dk] så en ærkevile.","%o dachte, ein Scheusal zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Νεκρομάντη,"%o pensis, ke @[pro_eo] vidis ĉef-fiulon.",%o ha creído ver un Arch-Vile.,%o creyó haber visto un Arch-Vile.,%o luuli nähneensä arkkihirvityksen,%o a cru voir un Arche-Vile.,"%o azt hitte, hogy látott egy ősármányt.",a %o sembrava di aver visto un Arch-Vile.,%o がアーチバイルを見た気がした。,%o 은(는) 아크-바일을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een aartsvijand zag.,%o trodde @[pro_dk] så en erkefiende.,%o kątem oka zauważył@[ao_pl] arcypodleca.,%o achou que viu um arquivil.,,%o a crezut că %g a văzut un abject.,Игрок %o краем глаза заметил архвиля.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] једног арчвајла.,%o trodde att @[pro_sv] såg en ärkevild.,%o bir iğrençlik gördüğünü sandı. +%o thought %g saw a Baron of Hell.,OB_STEALTHBARON,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] barona pekel.","%o troede, @[pro_dk] så en helvedesbaron.","%o dachte, einen Höllenbaron zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Βαρώνο της Κόλασης.,"%o pensis, ke @[pro_eo] vidis Baronon de Infero.",%o ha creído ver un Barón del Infierno.,%o creyó haber visto un Barón del Infierno.,%o luuli nähneensä hornanparonin.,%o a cru voir un Baron des enfers.,"%o azt hitte, hogy látott egy pokolbárót.",a %o sembrava di aver visto un Barone Infernale.,%o がバロンを見た気がした。,%o 은(는) 바론 오브 헬을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een baron van de Hel zag.,%o trodde @[pro_dk] så en helvetesbaron,%o kątem oka zauważył@[ao_pl] Barona Piekła.,%o achou que viu um barão do inferno.,,%o a crezut că %g a văzut un Baron al Infernului.,Игрок %o краем глаза заметил барона ада.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] барона пакла.,%o trodde att @[pro_sv] såg en helvetets baron.,%o bir Cehennem Baronu gördüğünü sandı. +%o thought %g saw a cacodemon.,OB_STEALTHCACO,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] kakodémona.","%o troede, @[pro_dk] så en cacodemon.","%o dachte, einen Cacodämonen zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Κακοδαίμονα.,"%o pensis, ke @[pro_eo] vidis kakodemonon.",%o ha creído ver un Cacodemonio.,%o creyó haber visto un Cacodemonio.,%o luuli nähneensä kakodemonin.,%o a cru voir un Cacodémon.,"%o azt hitte, hogy látott egy kakodémont.",a %o sembrava di aver visto un cacodemone.,%o がカコデーモンを見た気がした。,%o 은(는) 카코데몬을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een cacodemon zag.,%o trodde @[pro_dk] så en kakodemon.,%o kątem oka zauważył@[ao_pl] kakodemona.,%o achou que viu um cacodemônio.,,%o a crezut că %g a văzut un cacodemon.,Игрок %o краем глаза заметил какодемона.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] какодемона.,%o trodde att @[pro_sv] såg en cacodemon.,%o bir caco iblisi gördüğünü sandı. +%o thought %g saw a chaingunner.,OB_STEALTHCHAINGUY,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] kulometčíka.","%o troede, @[pro_dk] så en chaingunner.","%o dachte, einen MG-Schützen zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Ζόμπι με ένα πολυβόλο.,"%o pensis, ke @[pro_eo] vidis maŝinpafiliston.",%o ha creído ver un Ametrallador.,%o creyó haber visto un Ametrallador.,%o luuli nähneensä konekiväärimiehen.,%o a cru voir un mitrailleur.,"%o azt hitte, hogy látott egy kommandóst.",a %o sembrava di aver visto uno zombie commando.,%o がチェインガンナーを見た気がした。,%o 은(는) 체인거너를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een zware wapens kerel zag.,%o trodde @[pro_dk] så en maskingeværskyt.,%o kątem oka zauważył@[ao_pl] ciężkozbrojnego zombie.,%o achou que viu um comando possuído.,%o achou que viu um metrelhador.,%o a crezut că %g a văzut un mitralior.,Игрок %o краем глаза заметил пулемётчика.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] митраљезца.,%o trodde att @[pro_sv] såg en tunga vapen kille.,%o bir ağır silah dostu gördüğünü sandı. +%o thought %g saw a demon.,OB_STEALTHDEMON,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] démona.","%o troede, @[pro_dk] så en dæmon.","%o dachte, einen Dämonen zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα δαίμονα.,"%o pensis, ke @[pro_eo] vidis demonon.",%o ha creído ver un Demonio.,%o creyó haber visto un Demonio.,%o luuli nähneensä demonin.,%o a cru voir un démon.,"%o azt hitte, hogy látott egy démont.",a %o sembrava di aver visto un demone.,%o がデーモンを見た気がした。,%o 은(는) 데몬을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een demon zag.,%o trodde @[pro_dk] så en demon.,%o kątem oka zauważył@[ao_pl] demona.,%o achou que viu um demônio.,,%o a crezut că %g a văzut un demon.,Игрок %o краем глаза заметил демона.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] демона.,%o trodde att @[pro_sv] såg en demon.,%o bir iblis gördüğünü sandı. +%o thought %g saw a Hell Knight.,OB_STEALTHKNIGHT,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] rytíře pekel.","%o troede, @[pro_dk] så en helvedesridder.","%o dachte, einen Höllenritter zu sehen.",@[art_gr] %o νόμιζε οτι είδε έναν Ιππότη της Κόλασης.,"%o pensis, ke @[pro_eo] vidis Inferkavaliron.",%o ha creído ver un Caballero del Infierno.,%o creyó haber visto un Caballero del Infierno.,%o luuli nähneensä hornanritarin.,%o a cru voir un chevalier infernal.,"%o azt hitte, hogy látott egy pokollovagot.",a %o sembrava di aver visto un Cavaliere Infernale.,%o がヘルナイトを見た気がした。,%o 은(는) 헬 나이트를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een hel ridder zag.,%o trodde @[pro_dk] så en helvetesridder.,%o kątem oka zauważył@[ao_pl] Rycerza Piekła.,%o achou que viu um cavaleiro infernal.,%o achou que viu um cavaleiro infernal.,%o a crezut că %g a văzut un Cavaler al Infernului.,Игрок %o краем глаза заметил рыцаря ада.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] витеза пакла.,%o trodde att @[pro_sv] såg en helvetesriddare.,%o bir Cehennem Şövalyesi gördüğünü sandı. +%o thought %g saw an imp.,OB_STEALTHIMP,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] čerta.","%o troede, @[pro_dk] så en imp.","%o dachte, einen Kobold zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Διάβολο.,"%o pensis, ke @[pro_eo] vidis diableton.",%o ha creído ver un Imp.,%o creyó haber visto un Imp.,%o luuli nähneensä pirun.,%o a cru voir un diablotin.,"%o azt hitte, hogy látott egy tűzkoboldot.",a %o sembrava di aver visto un imp.,%o がインプを見た気がした。,%o 은(는) 임프를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een imp zag.,%o trodde @[pro_dk] så en imp.,%o kątem oka zauważył@[ao_pl] diablika.,%o achou que viu um diabrete.,,%o a crezut că %g a văzut un drac.,Игрок %o краем глаза заметил импа.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] врага.,%o trodde att @[pro_sv] såg en imp.,%o bir impus gördüğünü sandı. +%o thought %g saw a mancubus.,OB_STEALTHFATSO,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] mankuba.","%o troede, @[pro_dk] så en mankubus.","%o dachte, einen Mancubus zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Χοντρό.,"%o pensis, ke @[pro_eo] vidis mankubon.",%o ha creído ver un Mancubus.,%o creyó haber visto un Mancubus.,%o luuli nähneensä mankubuksen.,%o a cru voir un mancube.,"%o azt hitte, hogy látott egy mankubuszt.",a %o sembrava di aver visto un mancubus.,%o がマンキュバスを見た気がした。,%o 은(는) 맨큐버스를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een mancubus zag.,%o trodde @[pro_dk] så en mancubus.,%o kątem oka zauważył@[ao_pl] antropokuba.,%o achou que viu um mancubus.,,%o a crezut că %g a văzut un mancubus.,Игрок %o краем глаза заметил манкубуса.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] манкубуса.,%o trodde att @[pro_sv] såg en mancubus.,%o bir mancubus gördüğünü sandı. +%o thought %g saw a revenant.,OB_STEALTHUNDEAD,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] umrlce.","%o troede, @[pro_dk] så en hævnen.","%o dachte, einen Wiederauferstandenen zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Εκδικητή.,"%o pensis, ke @[pro_eo] vidis renaskitulon.",%o ha creído ver un Revenant.,%o creyó haber visto un Revenant.,%o luuli nähneensä henkiinpalanneen.,%o a cru voir un revenant.,"%o azt hitte, hogy látott egy kísértetet.",a %o sembrava di aver visto un revenant.,%o がレバナントを見た気がした。,%o 은(는) 레버넌트를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een wraakzuchtige zag.,%o trodde @[pro_dk] så en gjenganger.,%o kątem oka zauważył@[ao_pl] zjawę.,%o achou que viu um insepulto.,%o achou que viu um renascido.,%o a crezut că %g a văzut un nemort.,Игрок %o краем глаза заметил ревенанта.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] повратника.,%o trodde att @[pro_sv] såg en återfödare.,%o bir iskelet gördüğünü sandı. +%o thought %g saw a sergeant.,OB_STEALTHSHOTGUNGUY,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] seržanta.","%o troede, @[pro_dk] så en sergent.","%o dachte, einen Schützen zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Λοχία.,"%o pensis, ke @[pro_eo] vidis serĝenton.",%o ha creído ver un Sargento.,%o creyó haber visto un Sargento.,%o luuli nähneensä kersantin.,%o a cru voir un type au fusil.,"%o azt hitte, hogy látott egy őrmestert.",a %o sembrava di aver visto un zombie sergente.,%o が軍曹を見た気がした。,%o 은(는) 샷건 가이를 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een jachtgeweer kerel zag.,%o trodde @[pro_dk] så en sersjant.,%o kątem oka zauważył@[ao_pl] zombie-sierżanta.,%o achou que viu um sargento possuído.,%o achou que viu um sargento.,%o a crezut că %g a văzut un sergent.,Игрок %o краем глаза заметил сержанта.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] водника.,%o trodde att @[pro_sv] såg en hagelgevärskille.,%o bir çavuş gördüğünü sandı. +%o thought %g saw a zombieman.,OB_STEALTHZOMBIE,,,,"%o si myslel@[ao_cs], že viděl@[ao_cs] zombíka.","%o troede, @[pro_dk] så en zombie.","%o dachte, einen Zombie zu sehen.",@[art_gr] %o νόμιζε οτι είδε ένα Ζόμπι.,"%o pensis, ke @[pro_eo] vidis zombiviron.",%o ha creído ver un Zombi.,%o creyó haber visto un Zombi.,%o luuli nähneensä zombin.,%o a cru voir un zombie.,"%o azt hitte, hogy látott egy zombit.",a %o sembrava di aver visto uno zombie marine.,%o がゾンビ兵を見た気がした。,%o 은(는) 좀비맨을 봤다고 생각했다.,%o dacht dat @[hij_ze_nl] een zombie zag.,%o trodde @[pro_dk] så en zombiemann.,%o kątem oka zauważył@[ao_pl] zombie.,%o achou que viu um zumbi.,%o achou que viu um zombie.,%o a crezut că %g a văzut un zombi.,Игрок %o краем глаза заметил зомби.,%o мисли@[ao_1_sr] да је виде@[ao_1_sr] зомбија.,%o trodde att @[pro_sv] såg en zombie.,%o bir zombi gördüğünü sandı. +%o was punched by a revenant.,OB_UNDEADHIT,,,,%o byl@[ao_cs] udeřen@[ao_cs] umrlcem.,%o blev slået af en genfødt.,%o wurde von einem Wiederauferstandenen K.O geschlagen.,@[art_gr] %o έφαγε μια μπουνία απο έναν Εκδικητή.,%o estis pugnita de renaskitulo.,A %o l@[ao_esp] ha golpeado un Revenant.,A %o l@[ao_esp] golpeó un Revenant.,%o joutui henkiinpalanneen lyömäksi.,%o s'est pris@[e_fr] une raclée de la part d'un revenant.,%o-t kiütötte egy kísértet.,%o è stato colpito dal pugno di un revenant.,%o はレバナントに殴られた。,%o 은(는) 레버넌트에게 맞아 죽었다.,%o werd geslagen door een wraakzuchtige.,%o ble slått av en gjenganger.,%o został@[ao_pl] uderzon@[adj_pl] przez zjawę.,%o foi socad@[ao_ptb] por um insepulto.,%o foi socad@[ao_ptb] por um renascido.,%o a primit un pumn de la un nemort.,Игрока %o ударил ревенант.,%o је ударен@[adj_1_sr] од стане повратника.,%o blev slagen av en återfödare.,%o bir iskelet tarafından yumruklandı. +%o was slashed by an imp.,OB_IMPHIT,,,,%o byl@[ao_cs] rozsápán@[ao_cs] čertem.,%o blev skåret ned af en spøgelse.,%o wurde von einem Kobold gekratzt.,@[art_gr] %o κόπηκε απο ενα Διάβολο.,%o estis tranĉvundita de diableto.,A %o l@[ao_esp] ha desgarrado un Imp.,A %o l@[ao_esp] desgarró un Imp.,%o joutui pirun sivaltamaksi.,%o a été lacéré@[e_fr] par un diablotin.,%o-t széttépte egy tűzkobold.,%o è stato squarciato da un imp.,%o はインプに切り裂かれた。,%o 은(는) 임프에게 찢겨 죽었다.,%o werd gesneden door een imp.,%o ble kuttet av en imp.,%o został@[ao_pl] rozcięt@[adj_pl] przez diablika.,%o foi dilacerad@[ao_ptb] por um diabrete.,,%o a fost zgâriat de un drac.,Игрока %o расцарапал имп.,Играча %o је пресеко враг.,%o blev knivhuggen av en imp.,%o bir imp tarafından kesildi. +%o got too close to a cacodemon.,OB_CACOHIT,,,,%o se dostal@[ao_cs] moc blízko ke kakodémonovi.,%o kom for tæt på en cacodæmon.,%o kam dem Cacodämonen zu nahe.,@[art_gr] %o ήτανε πολυ κοντά σε ένα Κακοδαίμονα.,%o tro proksimiĝis al kakodemono.,%o se ha acercado demasiado a un Cacodemonio.,%o se acercó demasiado a un Cacodemonio.,%o meni liian lähelle kakodemonia.,%o s'est approché@[e_fr] trop près d'un Cacodémon.,%o túl közel ment egy kakodémonhoz.,%o si è avvicinato troppo a un cacodemone.,%o はカコデーモンに近づきすぎた。,%o 은(는) 카코데몬과 가까웠다.,%o kwam te dicht bij een cacodemon.,%o kom for nær en kakodemon.,%o pod@[irreg_1_pl] zbyt blisko do kakodemona.,%o chegou muito perto de um cacodemônio.,,%o s-a apropiat prea mult de un cacodemon.,Игрок %o слишком сблизился с какодемоном.,%o се превише приближи@[ao_1_sr] какодемону.,%o kom för nära en cacodemon.,%o bir caco iblisiyle çok yakınlaştı. +%o was bit by a demon.,OB_DEMONHIT,,,,%o byl@[ao_cs] rozkousán@[ao_cs] démonem.,%o blev bidt af en dæmon.,%o wurde von einem Dämonen gebissen.,@[art_gr] %o δαγκόθηκε απο ένα Δαίμονα.,%o estis mordita de demono.,A %o l@[ao_esp] ha mordido un Demonio.,A %o l@[ao_esp] mordió un Demonio.,%o joutui demonin puremaksi.,%o a été mordu@[e_fr] par un démon.,%o-t megharapta egy démon.,%o è stato sbranato da un demone.,%o はデーモンに噛まれた。,%o 은(는) 데몬에게 물렸다.,%o werd gebeten door een demon.,%o ble bitt av en demon.,%o wpada w szczęki demona.,%o foi mordid@[ao_ptb] por um demônio.,,%o a fost mușcat de un demon.,Игрока %o укусил демон.,Играча %o је ујео демон.,%o blev biten av en demon.,%o bir iblis tarafından ısırıldı. +%o was eaten by a spectre.,OB_SPECTREHIT,,,,%o byl@[ao_cs] sežrán@[ao_cs] přízrakem.,%o blev spist af et imp.,%o wurde von dem Schemen gefressen.,Ένα φάντασμα έφαγε @[pro_gr] %o.,%o estis manĝita de fantomo.,A %o l@[ao_esp] ha devorado un Espectro.,A %o l@[ao_esp] devoró un Espectro.,%o joutui haamun syömäksi.,%o a été dévoré@[e_fr] par un spectre.,%o-t felfalta egy lidérc.,%o è stato divorato da uno spettro.,%o はスペクトルに喰われた。,%o 은(는) 스펙터에게 잡아먹혔다.,%o werd opgegeten door een spook.,%o ble spist av et spøkelse.,%o został@[ao_pl] zjedzon@[adj_pl] przez widmo.,%o foi devorad@[ao_ptb] por um espectro.,,%o a fost mâncat de un spectru.,Игрока %o сожрал фантом.,Играча %o је појео авет.,%o blev uppäten av ett spöke.,%o bir hayalet tarafından yenildi. +%o was ripped open by a Baron of Hell.,OB_BARONHIT,,,,%o byl@[ao_cs] rozčtvrcen@[ao_cs] baronem pekel.,%o blev flået op af en helvedesbaron.,%o wurde von dem Höllenbaron aufgerissen.,@[art_gr] %o σχίστηκε απο εναν Βαρώνο της Κόλασης.,%o estis disŝirigita de Barono de Infero.,A %o l@[ao_esp] ha hecho trizas un Barón del Infierno.,A %o l@[ao_esp] hizo trizas un Barón del Infierno.,%o joutui hornanparonin auki repimäksi.,%o a été déchiré@[e_fr] par un Baron des Enfers.,%o-t széttépte egy pokolbáró.,%o è stato scoperchiato da un Barone dell'Inferno.,%o はバロンオブヘルに体を抉じ開けられた。,%o 은(는) 바론 오브 헬에게 뜯겨 죽었다.,%o werd opengereten door een Baron van de hel.,%o ble revet opp av en helvetesbaron.,%o został@[ao_pl] rozerwan@[adj_pl] przez Barona Piekła.,%o foi rasgad@[ao_ptb] por um Barão do Inferno.,%o foi desventrad@[ao_ptb] por um Barão do Inferno.,%o a fost deschis pe viu de un Baron al Infernului.,Игрока %o разорвал барон ада.,%o је поцеп@[adj_2_sr] од стране барон пакла.,%o slets upp av en helvetesbaron.,%o bir Cehennem Baronu tarafından parçalandı. +%o was gutted by a Hell Knight.,OB_KNIGHTHIT,,,,%o byl@[ao_cs] vykuchán@[ao_cs] rytířem pekel.,%o blev udtaget af en helvedesridder.,%o wurde von dem Höllenritter ausgenommen.,@[art_gr] %o ξεκοιλιάστηκε απο έναν Ιππότη της Κόλασης.,%o estis senintestigita de Inferkavaliro.,A %o l@[ao_esp] ha destripado un Caballero del Infierno.,A %o l@[ao_esp] destripó un Caballero del Infierno.,%o joutui hornanritarin perkaamaksi.,%o a été étripé@[e_fr] par un un chevalier infernal.,%o-t kibelezte egy pokollovag.,%o è stato sbudellato da un Cavaliere dell'Inferno.,%o はヘルナイトに内臓を抉られた。,%o 은(는) 헬 나이트에게 도륙당했다.,%o werd gestript door een hel ridder.,%o ble sløyet av en helvetesridder.,%o został@[ao_pl] wypatroszon@[adj_pl] przez Rycerza Piekła.,%o foi estripad@[ao_ptb] por um Cavaleiro Infernal.,%o foi estripad@[ao_ptb] por um Cavaleiro Infernal.,%o a fost măcelărit de un Cavaler al Infernului.,Игрока %o распотрошил рыцарь ада.,Играча %o је унаказио витез пакла.,%o blev uppsliten av en helvetesriddare.,%o bir Cehennem Şövalyesi tarafından parçalandı. +%o was killed by a zombieman.,OB_ZOMBIE,,,,%o byl@[ao_cs] zabit@[ao_cs] zombíkem.,%o blev dræbt af en zombie.,%o wurde von einem Zombie getötet.,@[art_gr] %o σκοτώθηκε απο ένα Ζόμπι.,%o estis mortigita de zombiviro.,A %o se l@[ao_esp] ha cargado un Zombi.,A %o l@[ao_esp] mató un Zombi.,%o joutui zombin tappamaksi.,%o a été tué@[e_fr] par un zombie.,%o-t megölte egy zombi.,%o è stato ucciso da uno zombie marine.,%o はゾンビ兵に殺された。,%o 은(는) 좀비맨에게 죽었다.,%o werd gedood door een zombie.,%o ble drept av en zombiemann.,%o został@[ao_pl] zabit@[adj_pl] przez zombie.,%o foi mort@[ao_ptb] por um zumbi.,%o foi mort@[ao_ptb] por um zombie.,%o a fost omorât de un zombi.,Игрока %o убил зомби.,%o је убијен@[adj_1_sr] од стране зомбија.,%o blev dödad av en zombie.,%o bir zombi tarafından öldürüldü. +%o was shot by a sergeant.,OB_SHOTGUY,,,,%o byl@[ao_cs] zastřelen@[ao_cs] seržantem.,%o blev skudt af en sergent.,%o wurde von einem Schützen erschossen.,Ένας Λοχίας πυροβόλησε @[pro_gr] %o.,%o estis pafita de serĝento.,A %o l@[ao_esp] ha fusilado un Sargento.,A %o l@[ao_esp] fusiló un Sargento.,%o joutui kersantin ampumaksi.,%o s'est fait@[e_fr] flinguer par un type au fusil.,%o-t lelőtte egy őrmester.,%o è sato impallinato da uno zombie sergente.,%o はゾンビ軍曹に撃たれた。,%o 은(는) 서전트에게 총을 맞았다.,%o werd neergeschoten door een sergeant.,%o ble skutt av en sersjant.,%o został@[ao_pl] zastrzelon@[adj_pl] przez zombie-sierżanta.,%o levou um tiro de um sargento possuído.,,%o a fost împușcat de un sergent.,Игрока %o застрелил сержант.,Играча %o је погодио водник.,%o blev skjuten av en hagelgevärskille.,%o bir çavuş tarafından vuruldu. +%o was incinerated by an archvile.,OB_VILE,,,,%o byl@[ao_cs] zpopelněn@[ao_cs] veleběsem.,%o blev brændt af en ærkevile.,%o wurde von einem Scheusal verbrannt.,@[art_gr] %o αποτεφρώθηκε απο ένα Νεκρομάντη.,%o estis cindrigita de ĉef-fiulo.,A %o l@[ao_esp] ha calcinado un Arch-Vile.,A %o l@[ao_esp] calcinó un Arch-Vile.,%o joutui arkkihirvityksen kärventämäksi.,%o a été incinéré@[e_fr] par un Arche-Vile.,%o-t megpörkölte egy ősármány.,%o è stato incenerito da un arch-vile.,%o はアーチバイルに焼き尽くされた。,%o 은(는) 아크-바일에 의해 소각되었다.,%o werd verbrand door een aartsvijand.,%o ble brent av en erkefiende.,%o został@[ao_pl] spalon@[adj_pl] przez arcypodleca.,%o foi incinerad@[ao_ptb] pelo arquivil.,,%o a fost incinerat de un abject.,Игрока %o заживо сжёг архвиль.,Играча %o је запалио арчвајл.,%o blev förbränd av en ärkevilde,%o bir iğrençlik tarafından yakıldı. +%o couldn't evade a revenant's fireball.,OB_UNDEAD,,,,%o se nevyhnul@[ao_cs] umrlčí ohnivé kouli.,%o kunne ikke undvige en ildkugle fra en hævnen.,%o konnte dem Feuerball des Wiederauferstandenen nicht ausweichen.,@[art_gr] %o δέν μπορούσε να αποφείγει τον πύραυλο ενός Εκδικητή.,%o ne povis eviti fajrobulon de renaskitulo.,%o no ha esquivado la bola de fuego de un Revenant.,%o no esquivó la bola de fuego de un Revenant.,%o ei kyennyt väistämään henkiinpalanneen tulipalloa.,%o n'a pas réussi à esquiver un missile de revenant.,%o nem tudta kivédeni egy kísértet tűzgolyóját.,%o non ha potuto evitare il missile di un revenant.,%o はレバナントのファイアボールを回避できなかった。,%o 은(는) 레버넌트의 화염구를 피하지 못했다.,%o kon de vuurbal van een wraakzuchtige niet ontwijken.,%o klarte ikke å unngå en gjengangers ildkule.,%o nie udaje się uniknąć pocisku od zjawy.,%o não conseguiu desviar do míssil do insepulto.,%o não conseguiu desviar do míssil do renascido.,%o n-a putut scăpa de mingea de foc a nemortului.,Игрок %o не успел увернуться от снаряда ревенанта.,%o није мог@[ao_2_sr] да избегне повратникову пламену куглу.,%o kunde inte undvika en återfödds eldklot.,%o bir iskeletin ateş topundan kaçamadı. +%o was squashed by a mancubus.,OB_FATSO,,,,%o byl@[ao_cs] rozmačkán@[ao_cs] mankubem.,%o blev knust af en mankubus.,%o wurde von einem Mancubus plattgemacht.,@[art_gr] %o λιόθηκε απο έναν Χοντρό.,%o estis dispremita de mankubo.,A %o l@[ao_esp] ha pulverizado un Mancubus.,A %o l@[ao_esp] pulverizó un Mancubus.,%o joutui mankubuksen liiskaamaksi.,%o s'est fait@[e_fr] aplatir par un Mancube.,%o-t szétlapította egy mankubusz.,%o è stato disintegrato da un mancubus.,%o はマンキュバスに潰された。,%o 은(는) 맨큐버스에게 짓이겨졌다.,%o werd verpletterd door een mancubus.,%o ble knust av en mancubus.,%o został@[ao_pl] zmiażdżon@[adj_pl] przez antropokuba.,%o foi esmagad@[ao_ptb] por um mancubus.,,%o a fost strivit de un mancubus.,Игрока %o раздавил манкубус.,Играча %o је изгњечио манкубус.,%o blev krossad av en mancubus.,%o bir mancubus tarafından ezildi. +%o was perforated by a chaingunner.,OB_CHAINGUY,,,,%o byl@[ao_cs] prostřelen@[ao_cs] kulometčíkem.,%o blev perforeret af en chaingunner.,%o wurde von einem MG-Schützen perforiert.,@[art_gr] %o εκτελέστικε απο ένα Ζόμπι με ένα πολυβόλο.,%o estis truigadita de maŝinpafilisto.,A %o l@[ao_esp] ha perforado un Ametrallador.,A %o l@[ao_esp] perforó un Ametrallador.,%o joutui konekiväärimiehen rei'ittämäksi.,%o a été perforé@[e_fr] par un mitrailleur.,%o-t szitává lőtte egy kommandós.,%o è stato perforato da uno zombie commando.,%o はチェインガンナーに蜂の巣にされた。,%o 은(는) 체인거너에 의해 벌집이 됐다.,%o werd geperforeerd door een zware wapens kerel.,%o ble perforert av en chaingunner.,%o został@[ao_pl] przedziurawion@[adj_pl] przez ciężkozbrojnego zombie.,%o foi perfurad@[ao_ptb] por um comando possuído.,%o foi perfurad@[ao_ptb] por um metrelhador.,%o a fost perforat de un mitralior.,Игрока %o продырявил пулемётчик.,Играча %o је изрешетао митраљезац.,%o blev perforerad av en tunga vapen kille.,%o bir ağır silah tarafından delindi. +%o was spooked by a lost soul.,OB_SKULL,,,,%o se lekl@[ao_cs] ztracené duše.,%o blev skræmt af en fortabt sjæl.,%o wurde von einer Verlorenen Seele heimgesucht.,Μια Χαμένη Ξυχή φόβησε @[pro_gr] %o.,%o estis timigita de perdita animo.,%o se ha muerto de miedo con un Alma Errante.,%o se murió de miedo con un Alma Errante.,%o joutui kadonneen sielun säikäyttämäksi.,%o s'est fait@[e_fr] surprendre par une âme perdue.,%o-t halálra ijesztette egy kóbor lélek.,%o è stato spaventato a morte da un'Anima Errante.,%o はロストソウルにビビらされた。,%o 은(는) 로스트 소울을 보고 깜짝 놀랐다.,%o werd bang gemaakt door een verloren ziel.,%o ble skremt av en fortapt sjel.,%o został@[ao_pl] przestraszon@[adj_pl] przez zaginioną duszę.,%o se assustou com uma Alma Penada.,%o se assustou com uma alma penada.,%o a fost speriat de un suflet pierdut.,Игрок %o запуган до смерти потерянной душой.,%o је уплашен@[adj_1_sr] од изгубљене душе.,%o blev skrämd av en förlorad själ.,%o kayıp bir ruh tarafından korkutuldu. +%o was burned by an imp.,OB_IMP,,,,%o byl@[ao_cs] spálen@[ao_cs] čertem.,%o blev brændt af en spøgelse.,%o wurde von einem Kobold verbrannt.,@[art_gr] %o κάικε απο έναν Διάβολο.,%o estis bruligita de diableto.,A %o l@[ao_esp] ha calcinado un Imp.,A %o l@[ao_esp] calcinó un Imp.,%o joutui pirun polttamaksi.,%o brûlé@[e_fr] par un diablotin.,%o-t szénné égette egy tűzkobold.,%o è stato bruciato da un imp.,%o はインプに焼かれた。,%o 은(는) 임프에게 불태워졌다.,%o werd verbrand door een imp.,%o ble brent av en imp.,%o został@[ao_pl] spalon@[adj_pl] przez diablika.,%o foi queimad@[ao_ptb] por um diabrete.,,%o a fost ars de un demon.,Игрока %o сжёг имп.,%o је изгорен@[adj_1_sr] од стране врага.,%o blev bränd av en imp.,%o bir imp tarafından yakıldı. +%o was smitten by a cacodemon.,OB_CACO,,,,%o byl@[ao_cs] udeřen@[ao_cs] kakodémonem.,%o blev ramt af en cacodæmon.,%o wurde von einem Cacodämonen gequält.,@[art_gr] %o καίκε απο έναν Κακοδαίμονα.,%o estis venkobatita de kakodemono.,A %o l@[ao_esp] ha aniquilado un Cacodemonio.,A %o l@[ao_esp] aniquiló un Cacodemonio.,%o joutui kakodemonin iskemäksi.,%o a été terrassé@[e_fr] par un Cacodémon.,%o-ra lesújtott egy kakodémon.,%o è stato abbattuto da un cacodemone.,%o はカコデーモンに裁きを受けた。,%o 은(는) 카코데몬에게 엄습 당했다.,%o werd geslagen door een cacodemon.,%o ble slått av en kakodemon.,%o został@[ao_pl] porażon@[adj_pl] przez kakodemona.,%o foi golpead@[ao_ptb] por um cacodemônio.,,%o a fost lovit de un cacodemon.,Игрока %o поразил какодемон.,Играча %o је ударио какодемон.,%o blev förkrossad av en cacodemon.,%o bir caco iblisi tarafından vuruldu. +%o was bruised by a Baron of Hell.,OB_BARON,,,,%o byl@[ao_cs] pomačkán@[ao_cs] baronem pekel.,%o blev såret af en helvedesbaron.,%o wurde von einem Höllenbaron geröstet.,@[art_gr] %o γρατζουνήθηκε απο ένα Βαρώνο της Κόλασης.,%o estis kontuzita de Barono de Infero.,A %o l@[ao_esp] ha magullado un Barón del Infierno.,A %o l@[ao_esp] magulló un Barón del Infierno.,%o joutui hornanparonin ruhjomaksi.,%o a été démoli@[e_fr] par un Baron des Enfers.,%o-t összezúzta egy pokolbáró.,%o è stato scorticato da un Barone Infernale.,%o はバロンオブヘルに痛めつけられた。,%o 은(는) 바론 오브 헬에게 상처받았다.,%o werd gekneusd door een baron van de hel.,%o ble forslått av en helvetesbaron.,%o został@[ao_pl] stłuczon@[adj_pl] Barona Piekła.,%o foi ferid@[ao_ptb] por um Barão do Inferno.,,%o a fost contuzionat de un Baron al Infernului.,Игрок %o зашиблен бароном ада.,%o је мод@[adj_3_sr] због барона пакла.,%o blev skadad av en helvetesbaron.,%o bir Cehennem Baronu tarafından yaralandı. +%o was splayed by a Hell Knight.,OB_KNIGHT,,,,%o byl@[ao_cs] rozpůlen@[ao_cs] rytířem pekel.,%o blev splejset af en helvedesridder.,%o wurde von einem Höllenritter gebraten.,@[art_gr] %o απλώθηκε απο έναν Ιππότη της Κόλασης,%o estis bisekcita de Inferkavaliro.,A %o l@[ao_esp] ha partido en dos un Caballero del Infierno.,A %o l@[ao_esp] partió en dos un Caballero del Infierno.,%o joutui hornanritarin repimäksi.,%o a été éclaté@[e_fr] par un chevalier infernal.,%o-t kilapította egy pokollovag.,%o è stato squartato da un Cavaliere Infernale.,%o はヘルナイトにバラ撒かれた。,%o 은(는) 헬 나이트에게 갈라졌다.,%o werd gespierd door een hel ridder.,Jeg ble sprettet opp av en helvetesridder.,%o został@[ao_pl] rozcapierzon@[adj_pl] przez Rycerza Piekła.,%o foi espalmad@[ao_ptb] por um Cavaleiro Infernal.,%o foi espalmad@[ao_ptb] por um Cavaleiro Infernal.,%o a fost scrântit de un Cavaler al Infernului.,Игрока %o распластал рыцарь ада.,%o је раширен@[adj_1_sr] због витеза пакла.,%o blev spretad av en helvetesriddare.,%o bir Cehennem Şövalyesi tarafından yere serildi. +%o stood in awe of the spider demon.,OB_SPIDER,,,,%o zůstal@[ao_cs] stát v úžasu před pavoučím démonem.,%o stod i ærefrygt for edderkoppedæmonen.,%o stand in Ehrfurcht vor dem Spinnendämon.,@[art_gr] %o στάθηκε με δέος μπροστά στόν αραχνοδαίμονα.,%o staris mirigita antaŭ la aranedemono.,%o no ha podido contra la Mente-Maestra Arácnida.,%o no pudo contra la Mente-Maestra Arácnida.,%o kunnioitti syvästi hämähäkkidemonia,%o est resté pris@[e_fr] d'admiration devant le Démon Arachnéen.,%o halálra ijedt a Pókelme.,%o è stato soggiogato dal Ragno demoniaco.,%o はスパイダーデーモンに恐れをなした。,%o 은(는) 거미악마의 무자비함을 느꼈다.,%o stond in ontzag voor de spindemon.,%o sto i ærefrykt for edderkoppdemonen.,%o podziwiał@[ao_pl] pajęczego mistrza.,%o ajoelhou-se em frente da Aranha-Mestra.,,%o a stat înfricoșat în fața păianjenului maestru.,Игрок %o стоял в восторге перед пауком-предводителем.,%o се смрзну@[ao_1_sr] у очарању паук-руководилаца.,%o stod i vördnad inför spindeldemonen.,%o örümcek iblisin karşısında huşu içinde durdu. +%o let an arachnotron get %h.,OB_BABY,,,,%o se nechal@[ao_cs] dostat arachnotronem.,%o blev sprængt af en arachnotron.,%o ließ sich von einem Arachnotron erledigen.,@[art_gr] %o άφησε ένα Αράχνοτρον να @[pro_gr] σκοτώσει.,%o lasis elektraraneon venki @[pro_eo]n.,A %o l@[ao_esp] ha alcanzado un Aracnotrón.,A %o l@[ao_esp] alcanzó un Aracnotrón.,%o antoi anaktrotronin saada hänet.,%o a laissé un arachnotron l'avoir@[e_fr].,"%o hagyta, hogy elkapja egy póktron.",%o ha permesso che un arachnotron l'uccidesse.,%o が アラクノトロンに討ち取られた。,%o 은(는) 아라크노트론이 %o를(을) 죽이도록 놔두었다.,%o werd gedood door een arachnotron,%o ble sprengt av et arachnotron.,%o pozwolił@[ao_pl] arachnotronowi się do siebie dobrać.,%o foi peg@[ao_ptb] por uma arachnotron.,%o foi apanhad@[ao_ptb] por uma arachnotron.,%o s-a lăsat prins de un aracnotron.,Игрок %o дал себя на откуп арахнотрону.,%o је допусти@[ao_1_sr] да паукотрон дође до %h.,%o lät en arachnotron ta @[ref_sv].,%o bir araknotronun onu yakalamasına izin verdi. +%o was splattered by a cyberdemon.,OB_CYBORG,,,,%o byl@[ao_cs] rozplesknut@[ao_cs] na kaši kyberdémonem.,%o blev splattet af en cyberdæmon.,%o wurde von einem Cyberdämon zerfetzt.,@[art_gr] %o έσκασε απο ένα Cyber-δαίμονα.,%o estis disŝprucigita de ciberdemono.,A %o l@[ao_esp] ha hecho pedazos un Ciberdemonio.,A %o l@[ao_esp] hizo pedazos un Ciberdemonio.,%o joutui kyberdemonin yltympäri roiskimaksi.,%o a été pulvérisé@[e_fr] par un Cyberdémon.,%o-t cafatokra tépték a kiberdémon rakétái.,%o è stato spiaccicato da un Cyberdemone.,%o はサイバーデーモンにバラバラにされた。,%o 은(는) 사이버데몬에 의해 산산조각이 났다.,%o werd gespetterd door een cyberdemon.,%o ble sprutet av en kyberdemon.,%o został@[ao_pl] rozbryzgan@[adj_pl] przez cyberdemona.,%o foi arrebentad@[ao_ptb] pelo Ciberdemônio.,,%o a fost împroșcat de ciberdemon.,Игрока %o размазал кибердемон.,%o је спљоштен@[adj_1_sr] од стране сајбердемона,%o blev sönderslagen av en cyberdemon.,%o bir siber iblis tarafından parçalandı. +%o met a Nazi.,OB_WOLFSS,,,,%o potkal@[ao_cs] nácka.,%o mødte en nazist.,%o traf einen Nazi.,@[art_gr] %o χνώρισε ένα Ναζιστή.,%o renkontis Nazion.,%o se ha topado con un Nazi.,%o se topó con un Nazi.,%o tapasi natsin.,%o a rencontré un Nazi.,%o találkozott egy nácival.,%o ha incontrato un Nazista.,%o はナチ兵と遭遇した。,%o 은(는) 나치를 만났다.,%o ontmoette een nazi.,Jeg møtte en nazist.,%o spotkał@[ao_pl] nazistę.,%o encontrou um Nazista.,%o encontrou um Nazi.,%o a întâlnit un Nazist.,Игрок %o встретил нациста.,%o је упозна@[ao_1_sr] нацисту.,%o mötte en nazist.,%o bir Nazi ile karşılaştı. +%o was mauled by a dog.,OB_DOG,,,,%o byl@[ao_cs] roztrhán@[ao_cs] psem.,%o blev mast af en hund.,%o wurde von einem Hund zerrissen.,@[art_gr] %o φαγόθικε απο ένα σκύλο.,%o estis atakita de hundo.,A %o l@[ao_esp] ha despedazado un Perro.,A %o l@[ao_esp] despedazó un Perro.,%o joutui koiran raatelemaksi.,%o s'est fait mordre par un chien.,%o-t szétmarcangolta egy kutya.,%o è stato sbranato da un cane.,%o は犬に引き裂かれた。,%o 은(는) 개한테 으스러졌다.,%o werd verminkt door een hond.,%o ble maltraktert av en hund.,%o został@[ao_pl] poturbowan@[adj_pl] przez psa.,%o foi mutilad@[ao_ptb] por um cachorro.,%o foi mutilad@[ao_ptb] por um cão.,%o a fost sfâșiat de un câine.,Игрока %o разорвала собака.,Играча %o је удавио пас.,%o blev misshandlad av en hund.,%o bir köpek tarafından parçalandı. +%o chewed on %k's fist.,OB_MPFIST,,,,%o si pochutnal@[ao_cs] na pěsti hráče %k.,%o tyggede på %ks knytnæve.,%o kaute auf %ks Faust herum.,@[art_gr] %o μάσησε τη γροθία του/της %k.,%o maĉis la pugnon de %k.,%o ha masticado el puño de %k.,%o masticó el puño de %k.,%k rusikoi %o paran.,%o a bouffé le poing de %k.,%o megkóstolta %k ökleit.,%o si è schiantato contro il pugno di %k.,%o は %k の拳を顔面に受けた。,%o 은(는) %k 의 주먹을 물었다.,%o gekauwd op %k's vuist.,%o tygget på %ks knyttneve.,%o przygryza pięść %k.,%o foi espancad@[ao_ptb] até a morte por %k,,%o a mestecat pumnul lui %k.,Игрок %o отведал кулака игрока %k.,Играча %o је сажвакао песницу играча %k.,%o tuggade på %ks knytnäve.,"%o, %k tarafından öldürüldü." +%o was mowed over by %k's chainsaw.,OB_MPCHAINSAW,,,,%o byl@[ao_cs] zkácen@[ao_cs] motorovkou hráče %k.,%o blev slået ned af %ks motorsav.,%o wurde von %ks Kettensäge zerteilt.,@[art_gr] %o κόπηκε απο το αλλησοπρίονο του/της %k.,%o estis buĉita de la ĉensegilo de %k.,A %o l@[ao_esp] ha masacrado la motosierra de %k.,A %o l@[ao_esp] masacró la motosierra de %k.,%k katkoi %o paran.,%o a été tondu@[e_fr] par la tronconneuse de %k.,%o-t kettészelte %k láncfűrésze.,%o è stato falciato dalla motosega di %k.,%o は %k のチェーンソーで刈り取られた。,%o 은(는) %k 의 전기톱에 갈렸다.,%o werd gemaaid met %k's kettingzaag.,%o ble klippet over av %ks motorsag.,%o został@[ao_pl] skoszon@[adj_pl] przez piłę łańcuchową %k.,%o foi picad@[ao_ptb] pela motoserra de %k,,%o a fost tăiat de drujba lui %k.,Игрока %o разрезал бензопилой игрок %k.,%o је исечен@[adj_1_sr] моторном тестером играча %k.,%o blev överkörd av %ks motorsåg.,"%o, %k tarafından biçildi" +%o was tickled by %k's pea shooter.,OB_MPPISTOL,,,,%o byl@[ao_cs] polechtán@[ao_cs] pistolkou hráče %k.,%o blev kildet af %ks ærteskytte.,%o wurde von %ks Erbsenpistole gekitzelt.,@[art_gr] %o γαργαλίθηκε απο το οπλάκι του/της %k.,%o estis tiklita de la pistolo de %k.,A %o le ha hecho cosquillas la pistola de %k.,A %o le hizo cosquillas la pistola de %k.,%o kutitti %o parkaa hernepyssyllään.,%o a été châtouillé@[e_fr] par le pistolet de %k.,%o meg lett csiklandozva %k játékpisztolyával.,%o è stato sforacchiato dalla pistola di %k'.,%o は %k の豆鉄砲でくすぐられた。,%o 은(는) %k 의 권총에 간지럼을 탔다.,%o werd gekieteld door %k's erwtenschutter.,%o ble kilt av %ks ertebøsse.,%o został@[ao_pl] połaskotan@[adj_pl] przez spluwę %k.,%o levou cócegas da pistolinha de %k.,,%o a fost gâdilat de pistolașul lui %k.,Игрока %o защекочен вусмерть из горохострела игрока %k.,%o је заголицан@[adj_1_sr] пиштољем играча %k.,%o blev kittlad av %ks ärtskytt.,"%o, %k tarafından gıdıklandı" +%o chewed on %k's boomstick.,OB_MPSHOTGUN,,,,%o si pochutnal@[ao_cs] na brokádě hráče %k.,%o tyggede på %ks bommestok.,%o wurde Opfer von %ks Schrotflinte.,@[art_gr] %o έφαγε το ντουφέκι του/της %k.,%o maĉis la kartoĉan fusilon de %k.,A %o l@[ao_esp] ha agujereado la escopeta de %k.,A %o l@[ao_esp] agujereó la escopeta de %k.,%k jauhoi %o paran tussarillaan.,%o a s'est mangé@[e_fr] de la chevrotine de la part de %k.,%o megízlelte %k villámbotját.,%o si è trovato davanti il fucile di %k.,%o は %k のブームスティックを顔面に受けた。,%o 은(는) %k 의 붐스틱에 꽂혔다.,%o gekauwd op %k's boomstick.,%o tygget på %ks boomstick.,%o przygryza pukawkę %k.,%o foi mort@[ao_ptb] pela espingarda de %k.,,%o a mestecat pușca lui %k.,Игрока %o накормил дробью игрок %k.,%o је сажвака@[ao_1_sr] на пумпарицу играча %k.,%o tuggade på %ks bomstock.,"%o, %k tarafından patlatıldı" +%o was splattered by %k's super shotgun.,OB_MPSSHOTGUN,,,,%o byl@[ao_cs] rozplesknut@[ao_cs] na kaši superbrokovnicí hráče %k.,%o blev sprøjtet af %ks super haglgevær.,%o wurde von %ks Super-Schrotflinte zerfetzt.,@[art_gr] %o διαλύθηκε απο το διπλό ντουφέκι του/της %k,%o estis disŝprucigita de la dutuba fusilo de %k.,A %o l@[ao_esp] reventado la superescopeta de %k.,A %o l@[ao_esp] reventó la superescopeta de %k.,%k roiski %o paran yltympäriinsä superhaulikollaan.,%o s'est fait@[e_fr] gicler par le fusil de chasse de %k.,%o-t cafatokra tépte %k szupersörétese.,%o è stato smembrato dalla doppietta di %k.,%o は %k のスーパーショットガンでバラバラにされた。,%o 은(는) %k 의 슈퍼 샷건에 의해 터졌다.,%o werd gespat door %k's super jachtgeweer.,%o ble skutt med %ks super-haglgevær.,%o został@[ao_pl] rozpryskan@[adj_pl] przez super strzelbę %k.,%o foi estraçalhad@[ao_ptb] pela espingarda de cano duplo de %k.,,%o a fost împroșcat de super pușca lui %k.,Игрока %o размазал из супердробовика игрок %k.,Играча %o је спљоштила двоцевка играча %k.,%o blev besprutat av %ks super-hagelgevär.,"%o, %k tarafından sıçratıldı" +%o was mowed down by %k's chaingun.,OB_MPCHAINGUN,,,,%o byl@[ao_cs] prostřílen@[ao_cs] kulometem hráče %k.,%o blev mejet ned af %ks maskingevær.,%o wurde von %ks Maschinengewehr niedergemäht.,@[art_gr] %o κοματίαστηκε απο το πολυβόλο του/της %k.,%o estis kuglo-plenigita de la maŝinpafilo de %k.,A %o l@[ao_esp] ha dejado hecho colador la ametralladora de %k.,A %o l@[ao_esp] dejó hecho colador la ametralladora de %k.,%k niitti %o paran konekiväärillään.,%o a été ventilé@[e_fr] par la mitrailleuse de %k.,%k gépágyúval szétszaggatta %o testét.,%o è stato falciato dal mitragliatore di %k.,%o は %k のチェーンガンで蜂の巣にされた。,%o 은(는) %k 의 체인건에 의해 으깨졌다.,%o werd gemaaid met %k's machinegeweer.,%o ble meiet ned av %ks maskinpistol.,%o został@[ao_pl] skoszon@[adj_pl] przez karabin maszynowy %k.,%o foi massacrad@[ao_ptb] pela metralhadora de %k.,,%o a fost secerat de mitraliera rotativă a lui %k.,Игрок %o скошен из пулемёта игрока %k.,%o је покоси@[ao_1_sr] митраљез играча %k.,%o blev nedklippt av %ks kedjepistol.,"%o, %k tarafından biçildi" +%o rode %k's rocket.,OB_MPROCKET,,,,%o se projel@[ao_cs] na raketě hráče %k.,%o red på %ks raket.,%o ritt auf %ks Rakete.,@[art_gr] %o καβάλησε τον πύραυλο του/της %k.,%o rajdis la raketon de %k.,%o ha montado el misil de %k.,%o montó el misil de %k.,%o ratsasti pelaajan %k raketilla.,%o a chevauché la roquette de %k.,%o meglovagolta %k rakétáját.,%o ha cavalcato il razzo di %k.,%o は %k のロケットに乗ってしまった。,%o 은(는) %k 의 로켓을 탔다.,%o reed op %k's raket.,%o red på %ks rakett.,%o ujeżdżał@[ao_pl] rakietę %k.,%o não viu o foguete de %k.,%o não viu o míssil de %k.,%o a călărit racheta lui %k.,Игрок %o прокатился на ракете игрока %k.,%o је ујаха@[ao_1_sr] ракету играча %k.,%o åkte på %ks raket.,"%o, %k tarafından sıçratıldı" +%o almost dodged %k's rocket.,OB_MPR_SPLASH,,,,%o se skoro vyhnul@[ao_cs] raketě hráče %k.,%o undgik næsten %ks raket.,"%o schaffte es fast, %ks Rakete auszuweichen.",@[art_gr] %o σχεδόν απόφηγε τον πύραυλο του/της %k.,%o preskaŭ evitis la raketon de %k.,%o casi esquiva el misil de %k.,,%o melkein väisti pelaajan %k raketin.,%o a presque esquivé la roquette de %k.,%o majdnem kitért %k rakétája elől.,%o aveva quasi schivato il razzo di %k.,%o は %k のロケットをあと少しで避けられそうだった。,%o 은(는) %k 의 로켓 폭발을 거의 피했다.,%o ontweek bijna %k's raket.,%o unngikk nesten %ks rakett.,%o prawie unika rakiety %k.,%o quase escapou do foguete de %k.,%o quase escapou do míssil de %k.,%o aproape a evitat racheta lui %k.,Игрок %o почти увернулся от ракеты %k.,%o је за длаку избега@[ao_1_sr] ракету играча %k.,%o undvek nästan %ks raket.,"%o, %k tarafından sıçratıldı" +%o was melted by %k's plasma gun.,OB_MPPLASMARIFLE,,,,%o se roztekl@[ao_cs] plazmapuškou hráče %k.,%o blev smeltet af %ks plasma riffel.,%o wurde von %ks Plasmagewehr geschmolzen.,@[art_gr] %o λίοθηκε απο το πλάσμα όπλο του/της %k.,%o estis fandigita de la plasmo-pafilo de %k.,A %o l@[ao_esp] ha derretido el fusil de plasma de %k.,A %o l@[ao_esp] derritió el fusil de plasma de %k.,%k sulatti %o paran plasmapyssyllään.,%o a été réduit@[e_fr] en bouillie par le fusil a plasma de %k.,%k plazmafegyverével megolvaszotta %o testét.,%o è stato fuso dal fucile al plasma di %k.,%o は %k のプラズマガンに溶かされた。,%o 은(는) %k 의 플라즈마 건에 의해 융해되었다.,%o was gesmolten door %k's plasmageweer.,%o ble smeltet av %ks plasmakanon.,%o został@[ao_pl] stopion@[adj_pl] przez pistolet plasmowy %k.,%o foi torrad@[ao_ptb] pelo fuzil de plasma de %k.,%o foi torrad@[ao_ptb] pela pistola de plasma de %k.,%o a fost topit de pușca cu plasmă a lui %k.,Игрока %o расплавил из плазмомёта игрок %k.,%o је отопљен@[adj_1_sr] плазма оружјем играча %k.,%o smältes av %ks plasmagevär.,"%o, %k tarafından eritildi" +%o was splintered by %k's BFG.,OB_MPBFG_BOOM,,,,%o byl@[ao_cs] rozštěpen@[ao_cs] BFGčkem hráče %k.,%o blev splintret af %ks BFG.,%o wurde von %ks BFG in Stücke gerissen.,@[art_gr] %o κοματιάστηκε απο το BFG του/της %k.,%o estis splitigita de la BFG de %k.,A %o l@[ao_esp] ha astillado la BFG de %k.,A %o l@[ao_esp] astilló la BFG de %k.,%k pirstoi %o paran BFG:llään.,%o a été oblitéré@[e_fr] par le BFG de %k.,%o teste atomjaira szakadt %k BFG-jétől.,%o è stato sminuzzato dal BFG di %k.,%o は %k のBFGで木っ端微塵にされた。,%o 은(는) %k 의 BFG덕에 산산조각 났다.,%o was versplinterd door %k's BFG.,%o ble splintret av %ks BFG.,%o został@[ao_pl] rozpryskan@[adj_pl] przez BFG %k.,%o foi vaporizad@[ao_ptb] pela BFG de %k.,,%o a fost despicat de către BFG-ul lui %k.,Игрока %o порвал на осколки выстрел из BFG игрока %k.,%o је расцепан@[adj_1_sr] ВЈП играча %k.,%o splittrades av %ks BFG.,"%o, %k tarafından parçalandı" +%o couldn't hide from %k's BFG.,OB_MPBFG_SPLASH,,,,%o se nemohl@[ao_cs] ukrýt před BFGčkem hráče %k.,%o kunne ikke gemme sig for %ks BFG.,%o konnte sich nicht vor %ks BFG verstecken.,@[art_gr] %o δέν μπόρεσε να κρυφτέι απο το BFG του/της %k.,%o ne povis kaŝi sin de la BFG de %k.,%o no ha conseguido esconderse de la BFG de %k.,%o no logró esconderse de la BFG de %k.,%o ei kyennyt piiloutumaan pelaajan %k BFG:ltä.,%o n a pas pu se couvrir du BFG de %k.,%o nem tudott elmenekülni %k BFG-je elől.,%o non poteva nascondersi dal BFG di %k.,%o は %k のBFGから隠れることはできなかった。,%o 은(는) %k 의 BFG의 일격으로부터 피할 수 없었다.,%o kon zich niet verbergen voor %k's BFG.,%o kunne ikke gjemme seg for %ks BFG.,%o nie może się schować przed BFG %k.,%o não conseguiu se esconder da BFG de %k,,%o nu s-a putut ascunde de BFG-ul lui %k.,Игрок %o не успел спрятаться от BFG игрока %k.,%o се није мог@[ao_2_sr] сакрити од ВЈП играча %k.,%o kunde inte gömma sig för %ks BFG.,"%o, %k tarafından parçalandı" +%o was railed by %k.,OB_RAILGUN,,,,%o byl@[ao_cs] napíchnut@[ao_cs] hráčem %k.,%o blev skudt af %k.,%o stand in %ks Schusslinie.,@[art_gr] %o καρφόθηκε απο τον/την %k.,%o estis traborita de la elektropafilo de %k.,A %o l@[ao_esp] ha agujereado el cañón de riel de %k.,A %o l@[ao_esp] agujereó el cañón de riel de %k.,%o lävisti %o paran.,%o a été aligné@[e_fr] par %k.,%o beleállt %k lézerébe.,%o è stato bucherellato dal railgun di %k.,%o は %k のレールガンで死亡した。,%o 은(는) %k 의 레일건에 관통당했다.,%o werd gespaakt door %k.,%o ble skutt av %k.,%o stał@[ao_pl] na linii ognia %k.,%o estava na mira do canhão elétrico de %k.,,%o a fost ocărit de %k.,Игрока %o пробил насквозь игрок %k.,%o је убијен@[adj_1_sr] од играча %k.,%o blev fördärvad av %k.,%o %k tarafından kovuldu. +%o was burned by %k's BFG.,OB_MPBFG_MBF,,,,%o shořel@[ao_cs] BFGčkem hráče %k.,%o blev brændt af %ks BFG.,%o wurde von %ks BFG verbrannt.,@[art_gr] %o κάικε απο το BFG του/της %k.,%o estis bruligita de la BFG de %k.,A %o l@[ao_esp] ha calcinado la BFG de %k.,A %o l@[ao_esp] calcinó la BFG de %k.,%k korvensi %o paran BFG:llään.,%o a été irradié@[e_fr] par le BFG de %k.,%k hamuvá égette %o testét BFG-vel.,%o è stato bruciato dal BFG di %k.,%o は %k のBFGで焼き殺された。,%o 은(는) %k 의 BFG에 의해 타올랐다.,%o werd verbrand door %k's BFG.,%o ble brent av %ks BFG.,%o został@[ao_pl] spalon@[adj_pl] przez BFG %k.,%o foi cozid@[ao_ptb] pela BFG de %k.,,%o a fost ars de BFG-ul lui %k.,Игрока %o сжёг из BFG игрок %k.,%o је изгоре@[ao_1_sr] од ВЈП играча %k.,%o blev bränd av %ks BFG.,%o %k tarafından yakıldı +,,Heretic,,,,,,,,,,,,,,,,,,,,,,,,, +,,Pickup ,,,,,,,,,,,,,,,,,,,,,,,,, +Blue Key,TXT_GOTBLUEKEY,,,,Modrý klíč,Blå nøgle,Blauer Schlüssel,Μπλέ Κλειδί,Blua Ŝlosilo,Llave Azul,,Sininen avain,Clé Bleue,Kék kulcs,Chiave blu,青の鍵,청색 열쇠,Blauwe sleutel,Blå nøkkel,Niebieski klucz,Chave Azul,,Cheie Albastră,Синий ключ,Плави кључ,Blå nyckel,Mavi Anahtar +Yellow Key,TXT_GOTYELLOWKEY,,,,Žlutý klíč,Gul nøgle,Gelber Schlüssel,Κύτρινο Κλειδί,Flava Ŝlosilo,Llave Amarilla,,Keltainen avain,Clé Jaune,Sárga kulcs,Chiave gialla,黄の鍵,황색 열쇠,Gele sleutel,Gul nøkkel,Żółty klucz,Chave Amarela,,Cheie Galbenă,Жёлтый ключ,Жути кључ,Gul nyckel,Sarı Anahtar +Green Key,TXT_GOTGREENKEY,,,,Zelený klíč,Grøn nøgle,Grüner Schlüssel,Πράσινο Κλειδί,Verda Ŝlosilo,Llave Verde,,Vihreä avain,Clé Verte,Zöld kulcs,Chiave verde,緑の鍵,녹색 열쇠,Groene sleutel,Grønn nøkkel,Zielony klucz,Chave Verde,,Cheie Verde,Зелёный ключ,Зелени кључ,Grön nyckel,Yeşil Anahtar +Quartz Flask,TXT_ARTIHEALTH,,,,Blyštivá baňka,Kvartsflaske,Quarzflasche,Φλάσκα Χαλαζίας,Kvarca Flakono,Frasco de Cuarzo,,Kvartsipullo,Flasque en Quartz,Kvarc flaska,Ampolla di quarzo,石英フラスコ,석영 플라스크,Kwartskolf,Kvartskolbe,Kwarcowa Butelka,Frasco de Quartzo,,Flacon de Quartz,Кварцевый флакон,Кварцна боца,Kvartsflaska,Kuvars Şişesi +Wings of Wrath,TXT_ARTIFLY,,,,Křídla hněvu,Vredens vinger,Flügel des Zorns,Φτερά της Οργής,Flugiloj de Kolero,Alas de Ira,,Kiihtymyksen siivet,Ailes du Courroux,A Harag Szárnyai,Ali iraconde,レイスの翼,분노의 날개,Vleugels der Toorn,Vredens vinger,Skrzydła Gniewu,Asas da Ira,,Aripile Furiei,Крылья гнева,Крила гнева,Vridsvingar,Gazap Kanatları +Ring of Invincibility,TXT_ARTIINVULNERABILITY,,,,Prsten nesmrtelnosti,Ring af uovervindelighed,Ring der Unverwundbarkeit,Δαχτυλίδι της Αθανασίας,Ringo de Nevenkebleco,Anillo de Invencibilidad,,Näkymättömyyden sormus,Anneau d'Invincibilité,A Sérthetetlenség Gyűrűje,Anello dell'invincibilità,不死の指輪,불멸의 반지,Ring van Onoverwinnelijkheid,Uovervinnelighetens ring,Pierścień Niewrażliwości,Anel da Invencibilidade,,Inelul Invincibilității,Кольцо неуязвимости,Прстен непобедивости,Ring av oövervinnlighet,Yenilmezlik Yüzüğü +Tome of Power,TXT_ARTITOMEOFPOWER,,,,Kniha moci,Bog om magt,Buch der Macht,Τομός της Δύναμης,Librego de Forto,Tomo de Poder,,Väkevyyden kirja,Livre du Pouvoir,Az Erő Kódexe,Tomo del potere,力の術書,힘의 서,Boek van de Macht,Maktens bok,Tom Mocy,Livro do Poder,Livro do Poder,Cartea Puterii,Том могущества,Том моћи,Maktens tome,Güç Kitabı +Shadowsphere,TXT_ARTIINVISIBILITY,,,,Šerosféra,Skyggesfære,Schattensphäre,Σκιόσφαιρα,Ombrosfero,Esfera de Sombra,,Varjokehrä,Sphère des Ombres,Árnygömb,Sfera dell'ombra,闇の球体,그림자 구체,Schaduwbol,Skyggesfære,Sfera Cieni,Esfera das Sombras,,Sfera Umbrei,Теневая сфера,Сфера сенки,Skuggsfär,Gölge Küre +Morph Ovum,TXT_ARTIEGG,,,,Měnivejce,,Transformations-Ei,Μετασχηματίζοντικο Ωάριο,Ovo de Transformado,Huevo de Transformación,,Muodonmuutoksen muna,Ovule de Métamorphose,Alakváltó tojás,Uovo della metamorfosi,変貌の卵子,변신 알,Morfose-Ei,,Jajko Morfujące,Ovo da Metamorfose,,Oul Metamorfozei,Яйцо превращения,Преображавајуће јајашце,,Dönüşümlü Yumurta +Mystic Urn,TXT_ARTISUPERHEALTH,,,,Tajemná urna,Mystisk urne,Mystische Urne,Μυστικό Δοχείο,Mistika Urno,Urna Mística,,Mystinen uurna,Urne Mystique,Misztikus urna,Urna mistica,神秘の骨壷,신비한 항아리,Mystieke Urn,Mystisk urne,Mistyczna Urna,Urna Mística,,Urnă Mistică,Мистическая урна,Мистериозна урна,Mystisk urna,Mistik Urn +Torch,TXT_ARTITORCH,,,,Pochodeň,Fakkel,Fackel,Πυρσός,Torĉo,Antorcha,,Soihtu,Torche,Fáklya,Torcia,松明,횃불,Fakkel,Fakkel,Pochodnia,Tocha,,Torță,Факел,Бакља,Fackel,Meşale +Time Bomb of the Ancients,TXT_ARTIFIREBOMB,,,,Časovaná bomba starověku,De ældres tidsbombe,Zeitbombe der Alten,Χρονοβόμβα τον Αρχαίων,Tempobombo de la Antikvuloj,Bomba de tiempo de los Ancestros,,Vanhain aikapommi,Bombe a Retardement des Anciens,Az Ősök Időbombája,Bomba a tempo degli antichi,古代の時限爆薬,고대의 시한폭탄,Tijdbom der Tijden,De eldgamles tidsinnstilte bombe,Starożytna Bomba Czasu,Bomba-relógio dos Anciãos,,Bomba cu Ceas a Anticilor,Часовая бомба древних,Временска бомба древних,De gamlas tidsbomb,Kadimlerin Saatli Bombası Chaos Device,TXT_ARTITELEPORT,,,,Zmatkostroj,Chaos-enhed,Chaosgerät,Συσκευή του Χάος,Ĥaos-Aparato,Dispositivo del Caos,,Kaaoskoje,Outil du Chaos,Káoszszerkezet,"Dispositivo del Caos -",カオスデバイス,혼돈의 장치,Chaosapparaat,Kaosinnretning,Urządzenie Chaosu,Dispositivo do Caos,,Dispozitiv al Haosolui,Механизм хаоса,Уређај хаоса,Kaos Cihazı -Crystal Vial,TXT_ITEMHEALTH,,,,Křišťálový flakón,Krystalflaske,Kristallfläschchen,Κρυσταλλικό Φιάλιδο,Fiolo de Kristalo,Tubo de Cristal,,Kristallipullo,Fiole de Cristal,Kristályampulla,Fiala di cristallo,水晶瓶,수정 약병,Kristallen Flesje,Krystallflaske,Kryształowa Fiolka,Ampola de Cristal,,Fiolă de Cristal,Кристальный флакон,Кристална бочица,Kristal Şişe -Bag of Holding,TXT_ITEMBAGOFHOLDING,,,,Tlumok,Pose med opbevaringspose,Rucksack,Τσάντα Κρατησης,Taŝo de Tenado,Bolso sin Fondo,,Säilön laukku,Sac sans Fond,A Birtoklás Batyuja,Borsa Portaoggetti,持ち物袋,보관용 가방,Rugzak,Posen som holder,Plecak,Bolsa de Utensílios,,Poșetă,Носильный кошель,Торба носивости,Holding Çantası -Silver Shield,TXT_ITEMSHIELD1,,,,Stříbrný štít,Sølvskjold,Silberner Schild,Ασημένια Ασπίδα,Arĝenta Ŝildo,Escudo Plateado,,Hopeakilpi,Bouclier d'Argent,Ezüst Pajzs,Scudo d'argento,銀の盾,은 방패,Zilveren Schild,Sølvskjold,Srebrna Tarcza,Escudo de Prata,,Scut de Argint,Серебряный щит,Сребрни штит,Gümüş Kalkan -Enchanted Shield,TXT_ITEMSHIELD2,,,,Kouzelný štít,Fortryllet skjold,Verzauberter Schild,,Sorĉita Ŝildo,Escudo Encantado,,Lumottu kilpi,Bouclier Enchanté,Bűvös Pajzs,Scudo incantato,魔法の盾,마력 강화 방패,Betoverd schild,Fortryllet skjold,Zaklęta Tarcza,Escudo Encantado,,Scut Mistificat,Зачарованный щит,Зачарани штит,Büyülü Kalkan -Map Scroll,TXT_ITEMSUPERMAP,,,,Mapa,Kortrulle,Kartenrolle,,Map-volvolibro,Mapa en Pergamino,,Karttakäärö,Rouleau du Cartographe,Térkép Tekercs,Pergamena della Mappa,地図の巻物,두루마리 지도,Kaartrol,Kartrulle,Zwój Mapy,Pergaminho do Mapa,,Hartă Pergament,Свиток карты,Мапа,Harita Kaydırma -Wand Crystal,TXT_AMMOGOLDWAND1,,,,Zlaté krystaly,Stav krystal,Zauberstabkristall,,Kristalo de Sorĉbastono,Cristal para Vara,,Sauvakristalli,Cristal Elfique,Kristálypor,Bacchetta di cristallo,ワンドクリスタル,지팡이 결정,Toverstok van Kristal,Tryllestav-krystall,Kryształ do Różdżki,Cristal para o Cetro,,Cristal pentru Toiag,Кристалл для эльфийского жезла,Кристали за штап,Değnek Kristali -Crystal Geode,TXT_AMMOGOLDWAND2,,,,Shluk krystalů,Krystal-geode,Kristallklumpen,,Kristalgeodo,Geoda de Cristal,,Kristalligeoidi,Géode de Cristal,Kristály Geoda,Geode di cristallo,晶洞石,결정 원석,Kristal Geode,Krystallgeode,Kryształowa Geoda,Geodo de Cristal,,Geodă de Cristal,Жеода кристалла,Кристални камен,Kristal Jeot -Mace Spheres,TXT_AMMOMACE1,,,,Žezlometné koule,Kølle kugler,Keulenkugeln,,Klabsferoj,Esferas de Maza,,Nuijakuulia,Sphère de Masse,Jogargömbök,Sfere per la mazza,メイス球弾,철퇴 포탄,Strijdknotsen,Mace-kuler,Kule do Buzdyganu,Esferas para Clava,,Sfere pentru Buzdugan,Сферы для булавы,Сфере за буздован,Ateş Küreleri -Pile of Mace Spheres,TXT_AMMOMACE2,,,,Hromada žezlometných koulí,Bunke af kølle kugler,Haufen von Keulenkugeln,,Stako de Klabsferoj,Pila de Esferas de Maza,,Nuijakuulakasa,Pile de Sphères de Masse,Egy rakás jogargömb,Pila di sfere per la mazza,メイス球弾の固まり,철퇴 포탄 무더기,Stapel Strijdknotsen,Haug med muskettkuler,Sterta Kul do Buzdyganu,Pilha de Esferas para Clava,,Grămadă de Sfere pentru Buzdugan,Груда сфер для булавы,Гомила сфера за буздован,Ateş Küreleri Yığını -Ethereal Arrows,TXT_AMMOCROSSBOW1,,,,Éterické šípy,Æteriske pile,Ätherische Pfeile,,Eteraj Sagoj,Flechas Etéreas,,Eetterinuolia,Carreaux Ethériques,Éteri nyílvesszők,Frecce eteree,イセリアルの矢,유체 화살,Etherische Pijlen,Eteriske piler,Eteryczne Strzały,Flechas Etéreas,,Săgeți Celeste,Эфирные стрелы,Етеричне стреле,Eterik Oklar -Quiver of Ethereal Arrows,TXT_AMMOCROSSBOW2,,,,Toulec éterických šípů,Kogger af æteriske pile,Köcher mit ätherischen Pfeilen,,Sagujo da Eteraj Sagoj,Carcaj de Flechas Etéreas,Carcaza de Flechas Etéreas,Eetterinuoliviini,Carquois de Carreaux Ethériques,Éteri nyíltok,Faretra di frecce eteree,イセリアルの矢筒,유체 화살집,Koker van Etherische Pijlen,Kogger av eteriske piler,Kołczan Eterycznych Strzał,Aljava de Flechas Etéreas,,Tolbă de Săgeți Celeste,Колчан эфирных стрел,Тоболац етеричних стрела,Eterik Okların Sadağı -Claw Orb,TXT_AMMOBLASTER1,,,,Pazouří střela,Klovkugle,Klauenball,,Kriforbo,Orbe de Garra,,Kynsikehrä,Orbe de Griffe,Karomgömb,Sfera d'artiglio,クローオーブ,발톱 보주,Klauwbal,Klo-kule,Kula do Pazura,Orbe para Garra,Esfera para Garra,Glob pentru Gheară,Когтевой шар,Канџаста сфера,Pençe Küresi -Energy Orb,TXT_AMMOBLASTER2,,,,Silová střela,Energikugle,Energieball,,Energiorbo,Orbe de Energía,,Energiakehrä,Orbe Draconique,Energiagömb,Sfera di energia,エネルギーオーブ,기력의 보주,Energiebal,Energikule,Kula Energii,Orbe de Energia,Esfera de Energia,Glob de Energie,Энергетический шар,Енергетска сфера,Enerji Küresi -Lesser Runes,TXT_AMMOSKULLROD1,,,,Menší runy,Mindre runer,Kleine Runen,,Runetoj,Runas Menores,,Vähäriimut,Runes Mineurs,Gyenge rúnák,Rune inferiori,レッサールーン,룬 조각,Lichte Runen,Mindre runer,Gorsze Runy,Runas Inferiores,,Rune Mici,Младшие руны,Нижа руна,Küçük Rünler -Greater Runes,TXT_AMMOSKULLROD2,,,,Větší runy,Større runer,Große Runen,,Runegoj,Runas Mayores,,Isoriimut,Runes Supérieures,Erős rúnák,Rune superiori,グレータールーン,최상급 룬,Zware Runen,Store runer,Lepsze Runy,Runas Superiores,,Rune Mari,Старшие руны,Већа руна,Büyük Rünler -Flame Orb,TXT_AMMOPHOENIXROD1,,,,Plamenný náboj,Flamme kugle,Flammenkugel,,Flamorbo,Orbe de Flama,,Liekkikehrä,Orbe de Flammes,Tűzgömb,Sfera di fuoco,フレイムオーブ,화염 구슬,Vuurbal,Flammekule,Kula Ognia,Orbe de Chamas,Esfera de Chamas,Glob de Foc,Пламенный шар,Ватрена сфера,Alev Küresi -Inferno Orb,TXT_AMMOPHOENIXROD2,,,,Pekelný náboj,Inferno-kugle,Infernokugel,,Brulorbo,Orbe de Averno,,Infernokehrä,Orbe Infernal,Pokolgömb,Sfera infernale,インフェルノオーブ,지옥불 구슬,Infernobal,Inferno-kule,Kula Piekielna,Orbe Infernal,Esfera Infernal,Glob Infernal,Инфернальный шар,Пламена сфера,Cehennem Küresi -Gold Wand,TXT_WPNGOLDWAND,,,,Zlatá hůl,Guldstav,Goldener Zauberstab,,Ora Sorĉbastono,Vara Dorada,,Kultasauva,Baguette Elfique,Aranypálca,Bacchetta d'oro,ゴールドワンド,황금 지팡이,Gouden Toverstok,Gullstav,Złota Różdżka,Varinha de Ouro,,Toiag cu Aur,Эльфийский жезл,Златни магични штап,Altın Değnek +",カオスデバイス,혼돈의 장치,Chaosapparaat,Kaosinnretning,Urządzenie Chaosu,Dispositivo do Caos,,Dispozitiv al Haosolui,Механизм хаоса,Уређај хаоса,Chaos-enhet,Kaos Cihazı +Crystal Vial,TXT_ITEMHEALTH,,,,Křišťálový flakón,Krystalflaske,Kristallfläschchen,Κρυσταλλικό Φιάλιδο,Fiolo de Kristalo,Tubo de Cristal,,Kristallipullo,Fiole de Cristal,Kristályampulla,Fiala di cristallo,水晶瓶,수정 약병,Kristallen Flesje,Krystallflaske,Kryształowa Fiolka,Ampola de Cristal,,Fiolă de Cristal,Кристальный флакон,Кристална бочица,Kristallflaska,Kristal Şişe +Bag of Holding,TXT_ITEMBAGOFHOLDING,,,,Tlumok,Pose med opbevaringspose,Rucksack,Τσάντα Κρατησης,Taŝo de Tenado,Bolso sin Fondo,,Säilön laukku,Sac sans Fond,A Birtoklás Batyuja,Borsa Portaoggetti,持ち物袋,보관용 가방,Rugzak,Posen som holder,Plecak,Bolsa de Utensílios,,Poșetă,Носильный кошель,Торба носивости,Väska med behållare,Holding Çantası +Silver Shield,TXT_ITEMSHIELD1,,,,Stříbrný štít,Sølvskjold,Silberner Schild,Ασημένια Ασπίδα,Arĝenta Ŝildo,Escudo Plateado,,Hopeakilpi,Bouclier d'Argent,Ezüst Pajzs,Scudo d'argento,銀の盾,은 방패,Zilveren Schild,Sølvskjold,Srebrna Tarcza,Escudo de Prata,,Scut de Argint,Серебряный щит,Сребрни штит,Silversköld,Gümüş Kalkan +Enchanted Shield,TXT_ITEMSHIELD2,,,,Kouzelný štít,Fortryllet skjold,Verzauberter Schild,,Sorĉita Ŝildo,Escudo Encantado,,Lumottu kilpi,Bouclier Enchanté,Bűvös Pajzs,Scudo incantato,魔法の盾,마력 강화 방패,Betoverd schild,Fortryllet skjold,Zaklęta Tarcza,Escudo Encantado,,Scut Mistificat,Зачарованный щит,Зачарани штит,Förtrollad sköld,Büyülü Kalkan +Map Scroll,TXT_ITEMSUPERMAP,,,,Mapa,Kortrulle,Kartenrolle,,Map-volvolibro,Mapa en Pergamino,,Karttakäärö,Rouleau du Cartographe,Térkép Tekercs,Pergamena della Mappa,地図の巻物,두루마리 지도,Kaartrol,Kartrulle,Zwój Mapy,Pergaminho do Mapa,,Hartă Pergament,Свиток карты,Мапа,Kartrulle,Harita Kaydırma +Wand Crystal,TXT_AMMOGOLDWAND1,,,,Zlaté krystaly,Stav krystal,Zauberstabkristall,,Kristalo de Sorĉbastono,Cristal para Vara,,Sauvakristalli,Cristal Elfique,Kristálypor,Bacchetta di cristallo,ワンドクリスタル,지팡이 결정,Toverstok van Kristal,Tryllestav-krystall,Kryształ do Różdżki,Cristal para o Cetro,,Cristal pentru Toiag,Кристалл эльфийского жезла,Кристали за штап,Stavkristall,Değnek Kristali +Crystal Geode,TXT_AMMOGOLDWAND2,,,,Shluk krystalů,Krystal-geode,Kristallklumpen,,Kristalgeodo,Geoda de Cristal,,Kristalligeoidi,Géode de Cristal,Kristály Geoda,Geode di cristallo,晶洞石,결정 원석,Kristal Geode,Krystallgeode,Kryształowa Geoda,Geodo de Cristal,,Geodă de Cristal,Жеода кристалла,Кристални камен,Kristallgeod,Kristal Jeot +Mace Spheres,TXT_AMMOMACE1,,,,Žezlometné koule,Kølle kugler,Keulenkugeln,,Klabsferoj,Esferas de Maza,,Nuijakuulia,Sphère de Masse,Jogargömbök,Sfere per la mazza,メイス球弾,철퇴 포탄,Strijdknotsen,Mace-kuler,Kule do Buzdyganu,Esferas para Clava,,Sfere pentru Buzdugan,Сферы булавы,Сфере за буздован,Eldstötsfärer,Ateş Küreleri +Pile of Mace Spheres,TXT_AMMOMACE2,,,,Hromada žezlometných koulí,Bunke af kølle kugler,Haufen von Keulenkugeln,,Stako de Klabsferoj,Pila de Esferas de Maza,,Nuijakuulakasa,Pile de Sphères de Masse,Egy rakás jogargömb,Pila di sfere per la mazza,メイス球弾の固まり,철퇴 포탄 무더기,Stapel Strijdknotsen,Haug med muskettkuler,Sterta Kul do Buzdyganu,Pilha de Esferas para Clava,,Grămadă de Sfere pentru Buzdugan,Груда сфер булавы,Гомила сфера за буздован,Hög med Eldstötsfärer,Ateş Küreleri Yığını +Ethereal Arrows,TXT_AMMOCROSSBOW1,,,,Éterické šípy,Æteriske pile,Ätherische Pfeile,,Eteraj Sagoj,Flechas Etéreas,,Eetterinuolia,Carreaux Ethériques,Éteri nyílvesszők,Frecce eteree,イセリアルの矢,유체 화살,Etherische Pijlen,Eteriske piler,Eteryczne Strzały,Flechas Etéreas,,Săgeți Celeste,Эфирные стрелы,Етеричне стреле,Eteriska pilar,Eterik Oklar +Quiver of Ethereal Arrows,TXT_AMMOCROSSBOW2,,,,Toulec éterických šípů,Kogger af æteriske pile,Köcher mit ätherischen Pfeilen,,Sagujo da Eteraj Sagoj,Carcaj de Flechas Etéreas,Carcaza de Flechas Etéreas,Eetterinuoliviini,Carquois de Carreaux Ethériques,Éteri nyíltok,Faretra di frecce eteree,イセリアルの矢筒,유체 화살집,Koker van Etherische Pijlen,Kogger av eteriske piler,Kołczan Eterycznych Strzał,Aljava de Flechas Etéreas,,Tolbă de Săgeți Celeste,Колчан эфирных стрел,Тоболац етеричних стрела,Kvant av eteriska pilar,Eterik Okların Sadağı +Claw Orb,TXT_AMMOBLASTER1,,,,Pazouří střela,Klovkugle,Klauenball,,Kriforbo,Orbe de Garra,,Kynsikehrä,Orbe de Griffe,Karomgömb,Sfera d'artiglio,クローオーブ,발톱 보주,Klauwbal,Klo-kule,Kula do Pazura,Orbe para Garra,Esfera para Garra,Glob pentru Gheară,Когтевой шар,Канџаста сфера,Klorör klot,Pençe Küresi +Energy Orb,TXT_AMMOBLASTER2,,,,Silová střela,Energikugle,Energieball,,Energiorbo,Orbe de Energía,,Energiakehrä,Orbe Draconique,Energiagömb,Sfera di energia,エネルギーオーブ,기력의 보주,Energiebal,Energikule,Kula Energii,Orbe de Energia,Esfera de Energia,Glob de Energie,Энергетический шар,Енергетска сфера,Energikulor,Enerji Küresi +Lesser Runes,TXT_AMMOSKULLROD1,,,,Menší runy,Mindre runer,Kleine Runen,,Runetoj,Runas Menores,,Vähäriimut,Runes Mineurs,Gyenge rúnák,Rune inferiori,レッサールーン,룬 조각,Lichte Runen,Mindre runer,Gorsze Runy,Runas Inferiores,,Rune Mici,Младшие руны,Нижа руна,Mindre runor,Küçük Rünler +Greater Runes,TXT_AMMOSKULLROD2,,,,Větší runy,Større runer,Große Runen,,Runegoj,Runas Mayores,,Isoriimut,Runes Supérieures,Erős rúnák,Rune superiori,グレータールーン,최상급 룬,Zware Runen,Store runer,Lepsze Runy,Runas Superiores,,Rune Mari,Старшие руны,Већа руна,Större runor,Büyük Rünler +Flame Orb,TXT_AMMOPHOENIXROD1,,,,Plamenný náboj,Flamme kugle,Flammenkugel,,Flamorbo,Orbe de Flama,,Liekkikehrä,Orbe de Flammes,Tűzgömb,Sfera di fuoco,フレイムオーブ,화염 구슬,Vuurbal,Flammekule,Kula Ognia,Orbe de Chamas,Esfera de Chamas,Glob de Foc,Пламенный шар,Ватрена сфера,Flamkula,Alev Küresi +Inferno Orb,TXT_AMMOPHOENIXROD2,,,,Pekelný náboj,Inferno-kugle,Infernokugel,,Brulorbo,Orbe de Averno,,Infernokehrä,Orbe Infernal,Pokolgömb,Sfera infernale,インフェルノオーブ,지옥불 구슬,Infernobal,Inferno-kule,Kula Piekielna,Orbe Infernal,Esfera Infernal,Glob Infernal,Инфернальный шар,Пламена сфера,Infernokula,Cehennem Küresi +Gold Wand,TXT_WPNGOLDWAND,,,,Zlatá hůl,Guldstav,Goldener Zauberstab,,Ora Sorĉbastono,Vara Dorada,,Kultasauva,Baguette Elfique,Aranypálca,Bacchetta d'oro,ゴールドワンド,황금 지팡이,Gouden Toverstok,Gullstav,Złota Różdżka,Varinha de Ouro,,Toiag cu Aur,Эльфийский жезл,Златни магични штап,Guldstav,Altın Değnek Firemace,TXT_WPNMACE,,,,Žezlomet,Ildspyd,Feuerkeule,,Fajroklabo,Maza de Fuego,,Tulinuija,Masse de Feu,Tűzbuzogány,"Mazza di fuoco -",ファイアメイス,투사철퇴,Vuurfoelie,Ildsted,Buzdygan Ognia,Clava de Fogo,,Buzdugan de Foc,Огненная булава,Ватрени буздован,Ateş Çubuğu -Ethereal Crossbow,TXT_WPNCROSSBOW,,,,Éterická kuše,Æterisk armbrøst,Ätherische Armbrust,,Etera Arbalesto,Ballesta Etérea,,Eetterivarsijousi,Arbalète Ethérique,Éteri számszeríj,Balestra eterea,イセリアルクロスボウ,유체 쇠뇌,Etherische kruisboog,Eterisk armbrøst,Eteryczna Kusza,Besta Etérea,,Arbaletă Celestă,Эфирный арбалет,Етерични самострел,Eterik Arbalet -Dragon Claw,TXT_WPNBLASTER,,,,Drakospár,Drageklo,Drachenklaue,,Drakokrifo,Garra de Dragón,,Lohikäärmeenkynsi,Griffe Draconique,Sárkány karom,Artiglio del drago,ドラゴンクロー,용발톱,Drakenklauw,Drageklo,Smoczy Pazur,Garra de Dragão,,Gheara Dragonului,Коготь дракона,Змајева канџа,Ejder Pençesi -Hellstaff,TXT_WPNSKULLROD,,,,Peklopal,Helvedestav,Höllenrute,,Inferbastono,Bastón Infernal,,Hornansauva,Bâton Infernal,Pokolpálca,Staffa infernale,ヘルスタッフ,지옥지팡이,Hellestaf,Helvetesstav,Piekielny Kostur,Cajado Infernal,,Baston Infernal,Посох Ада,Паклени штап,Cehennem Çubuğu -Phoenix Rod,TXT_WPNPHOENIXROD,,,,Fénixova hůl,Phønix-stang,Phönixstab,,Feniksvergo,Báculo del Fénix,,Feenikssauva,Bâton du Phénix,Főnix Rúd,Asta della fenice,フェニックスロッド,불사조 지팡이,Feniksstaf,Føniksstaven,Różdżka Feniksa,Bastão da Fênix,,Joarda Phoenix,Жезл феникса,Шипка феникса,Anka Kuşu Çubuğu -Gauntlets of the Necromancer,TXT_WPNGAUNTLETS,,,,Nekromancerovy rukavice,Nekromantikernes handsker,Handschuhe des Zauberers,,Fergantoj de la Nekromancisto,Guanteletes del Nigromante,,Manaajan rautakintaat,Gantelets du Nécromancien,Halottidéző Páncélkesztyűi,Guanti del Negromante,ネクロマンサーの篭手,강령술사의 건틀릿,Handschoenen van de Geestenbezweerder,Nekromantens hansker,Rękawice Nekromanty,Manoplas do Necromante,,Mănușile Necromantului,Перчатки некроманта,Рукавице призивача духова,Ölü Çağıranın Eldivenleri -,,Locks,,,,,,,,,,,,,,,,,,,,,,,, +",ファイアメイス,투사철퇴,Vuurfoelie,Ildsted,Buzdygan Ognia,Clava de Fogo,,Buzdugan de Foc,Огненная булава,Ватрени буздован,Eldstöt,Ateş Çubuğu +Ethereal Crossbow,TXT_WPNCROSSBOW,,,,Éterická kuše,Æterisk armbrøst,Ätherische Armbrust,,Etera Arbalesto,Ballesta Etérea,,Eetterivarsijousi,Arbalète Ethérique,Éteri számszeríj,Balestra eterea,イセリアルクロスボウ,유체 쇠뇌,Etherische kruisboog,Eterisk armbrøst,Eteryczna Kusza,Besta Etérea,,Arbaletă Celestă,Эфирный арбалет,Етерични самострел,Eteriskt armborst,Eterik Arbalet +Dragon Claw,TXT_WPNBLASTER,,,,Drakospár,Drageklo,Drachenklaue,,Drakokrifo,Garra de Dragón,,Lohikäärmeenkynsi,Griffe Draconique,Sárkány karom,Artiglio del drago,ドラゴンクロー,용발톱,Drakenklauw,Drageklo,Smoczy Pazur,Garra de Dragão,,Gheara Dragonului,Коготь дракона,Змајева канџа,Drakklocka,Ejder Pençesi +Hellstaff,TXT_WPNSKULLROD,,,,Peklopal,Helvedestav,Höllenrute,,Inferbastono,Bastón Infernal,,Hornansauva,Bâton Infernal,Pokolpálca,Staffa infernale,ヘルスタッフ,지옥지팡이,Hellestaf,Helvetesstav,Piekielny Kostur,Cajado Infernal,,Baston Infernal,Посох Ада,Паклени штап,Helvetesstång,Cehennem Çubuğu +Phoenix Rod,TXT_WPNPHOENIXROD,,,,Fénixova hůl,Phønix-stang,Phönixstab,,Feniksvergo,Báculo del Fénix,,Feenikssauva,Bâton du Phénix,Főnix Rúd,Asta della fenice,フェニックスロッド,불사조 지팡이,Feniksstaf,Føniksstaven,Różdżka Feniksa,Bastão da Fênix,,Joarda Phoenix,Жезл феникса,Шипка феникса,Fenixstång,Anka Kuşu Çubuğu +Gauntlets of the Necromancer,TXT_WPNGAUNTLETS,,,,Nekromancerovy rukavice,Nekromantikernes handsker,Handschuhe des Zauberers,,Fergantoj de la Nekromancisto,Guanteletes del Nigromante,,Manaajan rautakintaat,Gantelets du Nécromancien,Halottidéző Páncélkesztyűi,Guanti del Negromante,ネクロマンサーの篭手,강령술사의 건틀릿,Handschoenen van de Geestenbezweerder,Nekromantens hansker,Rękawice Nekromanty,Manoplas do Necromante,,Mănușile Necromantului,Перчатки некроманта,Рукавице призивача духова,Nekromantikerns handskar,Ölü Çağıranın Eldivenleri +,,Locks,,,,,,,,,,,,,,,,,,,,,,,,, You need a blue key to open this door,TXT_NEEDBLUEKEY,,,,K otevření těchto dveří potřebuješ modrý klíč,Du skal bruge en blå nøgle for at åbne denne dør,Du brauchst einen blauen Schlüssel um diese Tür zu öffnen,Χρειάζεσε ένα μπλέ κλειδί για να ενεργοποίησεις αυτη τη πόρτα,Vi bezonas bluan ŝlosilon por malfermi ĉi tiun pordon,Necesitas una llave azul para abrir esta puerta,,Tarvitset sinisen avaimen avataksesi tämän oven,Cette porte nécessite une clé bleue pour s'ouvrir.,Az ajtó nyitásához szükséged van egy kék kulcsra,"Ti serve una chiave blu per aprire questa porta ",開くには 青の鍵が必要だ,이 문을 열기 위해선 청색 열쇠가 필요하다,Je hebt een blauwe sleutel nodig om deze deur te openen,Du trenger en blå nøkkel for å åpne denne døren,"Potrzebujesz niebieskiego klucza, by otworzyć te drzwi.",Você precisa da chave azul para abrir esta porta,Precisas da chave azul para abrir esta porta,"Ai nevoie de o cheie albastră pentru a deschide -această ușă",Для открытия нужен синий ключ,Треба вам плави кључ да би отворили ова врата,Bu kapıyı açmak için mavi bir anahtara ihtiyacın var. +această ușă",Для открытия нужен синий ключ,Треба вам плави кључ да би отворили ова врата,Du behöver en blå nyckel för att öppna den här dörren.,Bu kapıyı açmak için mavi bir anahtara ihtiyacın var. You need a green key to open this door,TXT_NEEDGREENKEY,,,,K otevření těchto dveří potřebuješ červený klíč,Du skal bruge en grøn nøgle for at åbne denne dør,Du brauchst einen grünen Schlüssel um diese Tür zu öffnen,Χρειάζεσε ένα πράσινο κλειδί για να ενεργοποίησεις αυτη τη πόρτα,Vi bezonas verdan ŝlosilon por malfermi ĉi tiun pordon,Necesitas una llave verde para abrir esta puerta,,Tarvitset vihreän avaimen avataksesi tämän oven,Cette porte nécessite une clé verte pour s'ouvrir.,Az ajtó nyitásához szükséged van egy zöld kulcsra,"Ti serve una chiave verde per aprire questa porta ",開くには 緑の鍵が必要だ,이 문을 열기 위해선 녹색 열쇠가 필요하다,Je hebt een groene sleutel nodig om deze deur te openen,Du trenger en grønn nøkkel for å åpne denne døren,"Potrzebujesz zielonego klucza, by otworzyć te drzwi.",Você precisa da chave verde para abrir esta porta,Precisas da chave verde para abrir esta porta,"Ai nevoie de o cheie verde pentru a deschide -această ușă",Для открытия нужен зелёный ключ,Треба вам зелени кључ да би отворили ова врата,Bu kapıyı açmak için yeşil bir anahtara ihtiyacın var. +această ușă",Для открытия нужен зелёный ключ,Треба вам зелени кључ да би отворили ова врата,Du behöver en grön nyckel för att öppna den här dörren,Bu kapıyı açmak için yeşil bir anahtara ihtiyacın var. You need a yellow key to open this door,TXT_NEEDYELLOWKEY,,,,K otevření těchto dveří potřebuješ žlutý klíč.,Du skal bruge en gul nøgle for at åbne denne dør,Du brauchst einen gleben Schlüssel um diese Tür zu öffnen,Χρειάζεσε ένα κύτρινο κλειδί για να ενεργοποίησεις αυτη τη πόρτα,Vi bezonas flavan ŝlosilon por malfermi ĉi tiun pordon,Necesitas una llave amarilla para abrir esta puerta,,Tarvitset keltaisen avaimen avataksesi tämän oven,Cette porte nécessite une clé jaune pour s'ouvrir.,Az ajtó nyitásához szükséged van egy sárga kulcsra,Ti serve una chiave gialla per aprire questa porta,開くには 黄の鍵が必要だ,이 문을 열기 위해선 황색 열쇠가 필요하다,Je hebt een gele sleutel nodig om deze deur te openen,Du trenger en gul nøkkel for å åpne denne døren,"Potrzebujesz żółtego klucza, by otworzyć te drzwi.",Você precisa da chave amarela para abrir esta porta,Precisas da chave amarela para abrir esta porta,"Ai nevoie de o cheie galbenă pentru a deschide -această ușă",Для открытия нужен жёлтый ключ,Треба вам жути кључ да би отворили ова врата,Bu kapıyı açmak için sarı bir anahtara ihtiyacınız var -,,Actor tag names,,,,,,,,,,,,,,,,,,,,,,,, -Chicken,FN_CHICKEN,,,,Slepice,Kylling,Huhn,Κότα,Koko,Pollo,,Kana,Poulet,Csirke,Pollo,鶏,닭,Kip,Kylling,Kurczak,Galinha,,Găină,Цыплёнок,Кокошка,Tavuk -Weredragon,FN_BEAST,,,,Vlkodrak,Varedrage,Werdrache,Θηρίο,Lupdrako,Bestia dragón,,Ihmislohikäärme,Dragon-garou,Vérsárkány,Drago Mannaro,ウェア ドラゴン,웨어드래곤,Weerdraak,Vardrage,Smokołak,Homem-dragão,,Vârcodragon,Дракон-оборотень,Змајодлак,Kurt ejderha -Sabreclaw,FN_CLINK,,,,Šavlozub,Sabelklo,Säbelklaue,,Sabrokrifo,Garra de sable,,Sapelikynsi,Sabregriffe,Szablyakarom,Lamartiglio,サーベルクロー,세이버클로,Sabelklauw,Sabreklo,Szabloszpon,Unhas-de-sabre,,Gheară de Sabie,Саблекоготь,Тигар,Kılıçpençe -D'Sparil,FN_DSPARIL,,,,,,,,,,,,D'Sparil,,D'Sparil,デ'スパリル,드'스파릴,D'Sparil,,D'Sparil,,,D'Sparil,Д'Спарил,Д'Спарил,D'Sparil -Gargoyle,FN_HERETICIMP,,,,Chrlič,,,,Gargojlo,Gárgola,,Gargoili,Gargouille,Vízköpő,Gargoyle,ガーゴイル,가고일,,,Gargulec,Gárgula,,Garguie,Горгулья,Камена утвара,Gargoyle -Ironlich,FN_IRONLICH,,,,Železný kostěj,Jern lig,Eiserne Leiche,,Ferliĉo,Liche de hierro,,Rautakalmo,Liche de Fer,Ezüst lich,Lich di Ferro,アイアンリッチ,아이언 리치,IJzeren Lijk,Jernlich,Żelazny Lisz,Lich de Ferro,,Cadavru de Fier,Железный лич,Челични лич,Demir Ceset -Undead Warrior,FN_BONEKNIGHT,,,,Nemrtvý válečník,Udøde Kriger,Untoter Krieger,Αθάνατος Πολεμιστής,Malviva Batalisto,Guerrero no-muerto,,Epäkuollut soturi,Guerrier Mort-Vivant,Élőhalott harcos,Guerriero Non Morto,アンデット兵,언데드 전사,Ondode Krijger,Udød kriger,Nieumarły wojownik,Guerreiro Morto-vivo,,Războinic Nemort,Воин-нежить,Немртви ратник,Ölümsüz Savaşçı -Maulotaur,FN_MINOTAUR,,,,Minotaurus,Maulotaurus,Minotaurus,Μινόταυρος,Bategtaŭro,Mazotauro,,Maulotauri,Massetaure,,Maulotauro,マウロタウロス,몰로타우어,Maulotaurus,Maulotaur,Młototaur,Marretauro,,,Избитавр,Минотаур,Maulotor -Golem,FN_MUMMY,,,,Golém,,,,Golemo,,,,Golem,Gólem,Golem,ゴーレム,골렘,,,Golem,,,,Голем,Голем,Golem -Nitrogolem,FN_MUMMYLEADER,,,,Střelgolém,,,,Azotgolemo,,,,Nitrogolem,Nitrógólem,Nitrogolem,ニトロゴーレム,니트로 골렘,,,Nitrogolem,,,,Нитроголем,Нитро голем,Nitrogolem -Ophidian,FN_SNAKE,,,,Šupinatec,,,,Ofidio,Ofidio,,Käärmeolio,Ophidien,Ofidián,Ophidian,オフィディアン,오피디안,Ophidiaan,,Wężowaty,Ofídio,,Ofidian,Офидиан,Змија,Ophidian -Wizard,FN_WIZARD,,,,Čaroděj,Troldmand,Zauberer,Μάγος,Sorĉisto,Mago,,Velho,Magicien,Mágus,Mago,ウィザード,마법사,Tovenaar,Trollmann,Czarownik,Mago,,Vrăjitor,Колдун,Чаробњак,Sihirbaz -Wand Crystals,AMMO_GOLDWAND,,,,Zlaté krystaly,Stav krystaller,Elfenstabkristalle,,Sorĉbastono-Kristaloj,Cristales para vara,,Sauvakristalleja,Cristaux,Pálca kristályok,Cristalli per la bacchetta,ワンド クリスタル,지팡이 결정,Toverstafkristallen,Tryllestavkrystaller,Kryształy do Różdżki,Cristais para o Cetro,,Cristale pentru Toiag,Кристалл для эльфийского жезла,Кристали за штап,Değnek Kristalleri -Ethereal Arrows,AMMO_CROSSBOW,,,,Éterické šípy,Æteriske pile,Ätherische Pfeile,,Eteraj Sagoj,Flechas etéreas,,Eetterinuolia,Carreaux,Éteri nyilak,Frecce eteree,イセリアルの矢,유체 화살,Etherische Pijlen,Eteriske piler,Eteryczne Strzały,Flechas Etéreas,,Săgeți Celeste,Эфирные стрелы,Етеричне стреле,Eterik Oklar -Claw Orbs,AMMO_BLASTER,,,,Pazouří střely,Kugler med kløer,Klauenbälle,,Kriforboj,Orbes de garra,,Kynsikehriä,Orbes,Karom golyók,Sfere di artigli,クロー オーブ,발톱 보주,Klauwbollen,Klo-kuler,Kule do Pazura,Orbes para Garra,,Globuri pentru Gheară,Когтевые шары,Канџаста сфера,Pençe Küreleri -Mace Spheres,AMMO_MACE,,,,Žezlometné koule,Kugler til stridskølle,Energiebälle,,Klabsferoj,Esferas de maza,,Nuijakuulia,Sphères,Buzogány gömbök,Sfere per la mazza,メイス スフィア,철퇴 포탄,Strijdknotsen,Ildsted-kuler,Kule do Buzdyganu,Esferas para Clava,,Sfere pentru Buzdugan,Сферы для булавы,Сфере за буздован,Ateş Küreleri -Hellstaff Runes,AMMO_SKULLROD,,,,Peklopalné runy,Helvedestav-runer,Höllenrutenrunen,,Inferbastono-Runoj,Runas de Vara Infernal,,Hornansauvan riimuja,Runes,Pokolbot rúnák,Rune infernali,ヘルスタッフ ルーン,룬 조각,Hellestafrunen,Helvetesstav-runer,Runy do Piekielnego Kostura,Runas Infernais,,Rune pentru Bastonul Infernal,Руны посоха ада,Пуне за паклени штап,Cehennem Asası Rünleri -Flame Orbs,AMMO_PHOENIXROD,,,,Plamenné náboje,Flammekugler,Flammenkugeln,,Flamorboj,Orbes de llama,Orbes de flama,Liekkikehriä,Orbes de Feu,Tűzgolyók,Sfere di fuoco,フレイム オーブ,화염 구슬,Vuurballen,Flammekuler,Kule Ognia,Orbes de Chamas,,Globuri de Foc,Пламенные шары,Ватрена сфера,Alev Küreleri -Staff,TAG_STAFF,,,,Hole,Stav,Stab,Ράβδος,Bastono,Bastón,,Sauva,Bâton,Bot,Staffa,杖,지팡이,Staf,Stav,Kostur,Bastão,,Baston,Посох,Штап,Çubuk -Gauntlets of the Necromancer,TAG_GAUNTLETS,,,,Nekromancerovy rukavice,Nekromantikernes handsker,Handschuhe des Zauberers,,Fergantoj de la Nekromancisto,Guanteletes del Nigromante,,Manaajan rautakintaat,Gantelets du Nécromancien,Halottidéző páncélkesztyűi,Guanti del Negromante,ネクロマンサーの篭手,강령술사의 건틀릿,Handschoenen van de Geestenbezweerder,Nekromantens hansker,Rękawice Nekromanty,Manoplas do Necromante,,Mănușile Necromantului,Перчатки некроманта,Рукавице призивача духова,Ölü Çağıranın Eldivenleri -Elven Wand,TAG_GOLDWAND,,,,Elfí hůlka,Elverstav,Elfenstab,,Elfa Sorĉbastono,Vara de Elfo,,Haltiasauva,Baguette Elfique,Elf pálca,Scettro Elfico,エルフのワンド,엘프 지팡이,Elvenstokje,Alvestav,Elfia Różdżka,Cetro Élfico,,Toiag,Эльфийский жезл,Вилењачки штапић,Elf Asası -Ethereal Crossbow,TAG_CROSSBOW,,,,Éterická kuše,Æterisk armbrøst,Ätherische Armbrust,,Etera Arbalesto,Ballesta Etérea,,Eetterivarsijousi,Arbalète Etherique,Éteri nyílpuska,Balestra Eterea ,イセリアルクロスボウ,유체 쇠뇌,Etherische Kruisboog,Eterisk armbrøst,Eteryczna Kusza,Besta Etérea,,Arbaletă Celestă,Эфирный арбалет,Етерични самострел,Eterik Arbalet -Dragon Claw,TAG_BLASTER,,,,Drakospár,Drageklo,Drachenklaue,,Drakokrifo,Garra de Dragón,,Lohikäärmeenkynsi,Griffe Draconique,Sárkány karom,Artiglio del Drago ,ドラゴンの鉤爪,용발톱,Drakenklauw,Drageklo,Smoczy Pazur,Garra de Dragão,,Gheara Dragonului,Драконий коготь,Змајева канџа,Ejder Pençesi -Hellstaff,TAG_SKULLROD,,,,Peklopal,Helvedestav,Höllenrute,,Inferbastono,Bastón infernal,,Hornansauva,Bâton Infernal,Pokolbot,Staffa Infernale ,ヘルスタッフ,지옥지팡이,Hellestaf,Helvetesstav,Piekielny Kostur,Cajado Infernal,,Baston Infernal,Посох ада,Паклени штап,Cehennem Çubuğu -Phoenix Rod,TAG_PHOENIXROD,,,,Fénixova hůl,Phønix-stang,Phönixstab,,Feniksvergo,Báculo del Fénix,,Feenikssauva,Bâton du Phénix,Főnix rúd,Bastone della Fenice,フェニックスロッド,불사조 지팡이,Feniksstaf,Føniksstaven,Różdżka Feniksa,Bastão da Fênix,,Joardă Phoenix,Жезл феникса,Шипка феникса,Anka Kuşu Çubuğu -Firemace,TAG_MACE,,,,Žezlomet,Ildspyd,Feuerkeule,,Fajroklabo,Maza de Fuego,,Tulinuija,Masse de Feu,Tűzbuzogány,Mazza del Fuoco ,ファイアメイス,투사철퇴,Vuurknots,Ildsted,Buzdygan Ognia,Clava de Fogo,,Buzdugan de Foc,Огненная булава,Ватрени буздован,Ateş Çubuğu -Staff,TAG_STAFFP,,,,Hůl,Stav,Stab,Ράβδος,Bastono,Bastón,,Sauva,Bâton,Jogar,Staffa ,杖,마법부가 지팡이,Staf,Stav,Kostur,Bastão,,Baston,Посох,Штап,Çubuk -Gauntlets of the Necromancer,TAG_GAUNTLETSP,,,,Nekromancerovy rukavice,Nekromantikernes handsker,Handschuhe des Zauberers,,Fergantoj de la Nekromancisto,Guanteletes del Nigromante,,Manaajan rautakintaat,Gantelets du Nécromancien,Halottidéző páncélkesztyű,Guanti del Negromante,ネクロマンサーの篭手,마법부가 강령술사 건틀릿,Handschoenen van de Geestenbezweerder,Nekromantens hansker,Rękawice Nekromanty,Manoplas do Necromante,,Mănușile Necromantului,Перчатки некроманта,Рукавице некроманцера,Ölü Çağıranın Eldivenleri -Elven Wand,TAG_GOLDWANDP,,,,Elfí hůlka,Elverstav,Elfenstab,,Elfa Sorĉbastono,Vara de Elfo,,Haltiasauva,Baguette Elfique,Elf jogar,Scettro Elfico,エルフのワンド,마법부가 엘프 지팡이,Elvenstokje,Alvestav,Elfia Różdżka,Cetro Élfico,,Toiag,Эльфийский жезл,Вилењачки штапић,Elf Asası -Ethereal Crossbow,TAG_CROSSBOWP,,,,Éterická kuše,Æterisk armbrøst,Ätherische Armbust,,Etera Arbalesto,Ballesta Etérea,,Eetterivarsijousi,Arbalète Etherique,Éteri nyílpuska,Balestra Eterea ,イセリアルクロスボウ,마법부가 유체 쇠뇌,Etherische Kruisboog,Eterisk armbrøst,Eteryczna Kusza,Besta Etérea,,Arbaletă Celestă,Эфирный арбалет,Етерични самострел,Ethereal Arbalet -Dragon Claw,TAG_BLASTERP,,,,Drakospár,Drageklo,Drachenklaue,,Drakokrifo,Garra de Dragón,,Lohikäärmeenkynsi,Griffe Draconique,Sárkány karom,Artiglio del Drago ,ドラゴンの鉤爪,마법부가 용발톱,Drakenklauw,Drageklo,Smoczy Pazur,Garra de Dragão,,Gheara Dragonului,Коготь дракона,Змајева канџа,Ejder Pençesi -Hellstaff,TAG_SKULLRODP,,,,Peklopal,Helvedestav,Höllenrute,,Inferbastono,Bastón infernal,,Hornansauva,Bâton Infernal,Pokolbot,Staffa Infernale ,ヘルスタッフ,마법부가 지옥지팡이,Hellestaf,Helvetesstav,Piekielny Kostur,Cajado Infernal,,Baston Infernal,Посох ада,Мотка пакла,Cehennem Çubuğu -Phoenix Rod,TAG_PHOENIXRODP,,,,Fénixova hůl,Phønix-stav,Phönixstab,,Feniksvergo,Báculo del Fénix,,Feenikssauva,Bâton du Phénix,Főnix rúd,Bastone della Fenice,フェニックスロッド,마법부가 불사조 지팡이,Feniksstaf,Føniksstaven,Różdżka Feniksa,Bastão da Fênix,,Joardă Phoenix,Жезл феникса,Фениксов прут,Anka Kuşu Çubuğu -Firemace,TAG_MACEP,,,,Žezlomet,Ildspyd,Feuerkeule,,Fajrklabo,Maza de Fuego,,Tulinuija,Masse de Feu,Tűzbuzogány,Mazza del Fuoco ,ファイアメイス,마법부가 투사철퇴,Vuurknots,Ildsted,Buzdygan Ognia,Clava de Fogo,,Buzdugan de Foc,Огненная булава,Ватрени буздован,Ateş Çubuğu -Morph Ovum,TAG_ARTIEGG,,,,Měnivejce,Morph Ovum,Transformations-Ei,,Ovo de Transformado,Huevo de Transformación,,Muodonmuutoksen muna,Ovule de Métamorphose,Átváltoztató gömb,Morph Ovum,変貌の卵子,변신 알,Morfose-Ei,Morph Ovum,Jajko Morfujące,Ovo da Metamorfose,,Oul Metamorfozei,Яйцо превращения,Преображајyће јајашце,Dönüşümlü Yumurta -Time Bomb of the Ancients,TAG_ARTIFIREBOMB,,,,Časovaná bomba starověku,De ældgamles tidsbombe,Zeitbombe der Alten,,Tempobombo de la Antikvuloj,Bomba de tiempo de los Ancestros,,Vanhain aikapommi,Bombe a retardement des Anciens,Ősiek időbombája,Bomba a Tempo degli Antichi,古代の時限爆薬,고대의 시한폭탄,Tijdbom der Tijden,De eldgamles tidsinnstilte bombe,Starożytna Bomba Czasu,Bomba-relógio dos Anciãos,,Bomba cu Ceas a Anticilor,Часовая бомба древних,Временска бомба древних,Kadimlerin Saatli Bombası -Wings of Wrath,TAG_ARTIFLY,,,,Křídla hněvu,Vredens vinger,Flügel des Zorns,,Flugiloj de Kolero,Alas de Ira,,Kiihtymyksen siivet,Ailes du Courroux,Harag szárnyai,Ali Iraconde,レイスの翼,분노의 날개,Vleugels der Toorn,Vredens vinger,Skrzydła Gniewu,Asas da Ira,,Aripile Furiei,Крылья гнева,Крила гнева,Gazap Kanatları -Quartz Flask,TAG_ARTIHEALTH,,,,Blyštivá baňka,Kvartsflaske,Quarzflasche,,Kvarca Flakono,Frasco de Cuarzo,,Kvartsipullo,Flasque en Quartz,Kvarc flaska,Fiaschetta al Quarzo,石英フラスコ,석영 플라스크,Kwartskolf,Kvartskolbe,Kwarcowa Butelka,Frasco de Quartzo,,Flacon de Quartz,Кварцевый флакон,Кварцна боца,Kuvars Şişesi -Shadowsphere,TAG_ARTIINVISIBILITY,,,,Šerosféra,Skyggesfære,Schattensphäre,Σκιόσφαιρα,Ombrosfero,Esfera de Sombra,,Varjokehrä,Orbe des Ombres,Sötétgömb,Ombrosfera,闇の球体,그림자 구체,Schaduwbol,Skyggesfære,Sfera Cieni,Esfera das Sombras,,Sfera Umbrei,Теневая сфера,Сфера сенки,Gölge Küre -Ring of Invincibility,TAG_ARTIINVULNERABILITY,,,,Prsten nesmrtelnosti,Ring af uovervindelighed,Ring der Unverwundbarkeit,,Ringo de Nevenkebleco,Anillo de Invencibilidad,,Näkymättömyyden sormus,Anneau d'Invincibilité,Sérthetetlenség gyűrűje,Anello dell'invincibilità,不死の指輪,불멸의 반지,Ring van Onoverwinnelijkheid,Uovervinnelighetens ring,Pierścień Niewrażliwości,Anel da Invencibilidade,,Inelul Invincibilității,Кольцо неуязвимости,Прстен непобедивости,Yenilmezlik Yüzüğü -Mystic Urn,TAG_ARTISUPERHEALTH,,,,Tajemná urna,Mystisk urne,Mystische Urne,,Mistika Urno,Urna Mística,,Mystinen uurna,Urne Mystique,Misztikus urna,Urna Mistica,神秘の骨壷,신비한 항아리,Mystieke Urn,Mystisk urne,Mistyczna Urna,Urna Mística,,Urnă Mistică,Мистическая урна,Мистериозна урна,Mistik Urn -Chaos Device,TAG_ARTITELEPORT,,,,Zmatkostroj,Chaos-enhed,Chaosgerät,Συσκευή του Χάος,Ĥaos-Aparato,Dispositivo del Caos,,Kaaoskoje,Outil du Chaos,Káosz eszköz,Strumento del Caos,カオスデバイス,혼돈의 장치,Chaosapparaat,Kaosinnretning,Urządzenie Chaosu,Dispositivo do Caos,,Dispozitiv al Haosului,Механизм хаоса,Уређај хаоса,Kaos Cihazı -Tome of Power,TAG_ARTITOMEOFPOWER,,,,Kniha moci,Bog om magt,Buch der Macht,Τόμος της Δύναμης,Librego de Potenco,Tomo de Poder,,Väkevyyden kirja,Livre du Pouvoir,Erő kódexe,Tomo del Potere,力の術書,힘의 서,Boek van de Macht,Maktens bok,Tom Mocy,Tomo do Poder,,Cartea Puterii,Том могущества,Табла моћи,Güç Kubbesi -Torch,TAG_ARTITORCH,,,,Pochodeň,Fakkel,Fackel,Πύρσος,Torĉo,Antorcha,,Soihtu,Torche,Fáklya,Torcia ,松明,횃불,Fakkel,Fakkel,Pochodnia,Tocha,Torcha,Torță,Факел,Бакља,Meşale -,,Obituaries,,,,,,,,,,,,,,,,,,,,,,,, -%o was pecked to death.,OB_CHICKEN,,,,%o byl@[ao_cs] uklován@[ao_cs] k smrti.,%o blev hakket ihjel.,%o wurde zu Tode gepickt.,,%o estis bekita ĝis morto.,%o fue picotead@[ao_esp] hasta la muerte.,,%o nokittiin kuoliaaksi.,%o a été picoré@[e_fr] a mort.,%o halálra lett csípve.,%o è stato beccato a morte.,%o はくちばしで突かれ死んだ。,%o 은(는) 쪽팔리게 쪼여 죽었다.,%o werd doodgepikt.,%o ble hakket i hjel.,%o został@[ao_pl] zadzioban@[adj_pl] na śmierć.,%o foi bicad@[ao_ptb] até a morte.,%o foi picad@[ao_ptb] até a morte.,%o a fost ciocănit până la moarte.,Игрок %o заклёван до смерти.,%o је искљуцан@[adj_1_sr] до смрти.,%o gagalanarak öldürüldü. -%o was charred by a weredragon.,OB_BEAST,,,,%o byl@[ao_cs] spálen@[ao_cs] vlkodrakem.,%o blev forkullet af en varedrage.,%o wurde von dem Werdrachen verschmort.,,%o brulegiĝis de lupdrako.,%o fue carbonizad@[ao_esp] por una bestia dragón.,,%o joutui ihmislohikäärmeen kärventämäksi.,%o a été carbonisé@[e_fr] par un dragon-garou.,%o szénné égett egy Vérsárkány által.,%o è stato carbonizzato da una bestia.,%o はウェアドラゴンに黒焦げにされた。,%o 은(는) 웨어드래곤에 의해 검게 탔다.,%o werd verbrand door een weerdraak.,%o ble forkullet av en vardrage.,%o został@[ao_pl] zwęglon@[adj_pl] przez smokołaka.,%o foi carbonizad@[ao_ptb] por um homem-dragão.,,%o a fost ceruit de un vârcodragon.,Игрок %o обуглен драконом-оборотнем.,%o је реш печен@[adj_1_sr] од стране замјодлака.,%o bir kurt ejderha tarafından yakıldı. -%o was slashed by a sabreclaw.,OB_CLINK,,,,%o byl@[ao_cs] rozsápán@[ao_cs] šavlozubem.,%o blev skåret op af en sabreklo.,%o wurde von der Säbelklaue zerschlitzt.,,%o tranĉegiĝis de sabrokrifo.,%o fue acuchillad@[ao_esp] por un garra de sable.,,%o joutui sapelikynnen sivaltamaksi.,%o s'est fait découper par un sabregriffe.,%o meg lett vágva egy Szablyakarom által.,%o è stato squarciato da un lapillo.,%o はサーベルクローに切り裂かれた。,%o 은(는) 세이버클로에게 잘렸다.,%o werd door een sabelklauw gesneden.,%o ble kuttet av en sabelklo.,%o został@[ao_pl] posiekan@[adj_pl] przez szabloszpona.,Um Unhas-de-sabre cortou %o.,,%o a fost tăiat de o gheară de sabie.,Игрока %o нарезал саблекоготь.,Играча %o је исекао тигар.,%o bir kılıç pençe tarafından kesildi. -%o was scalded by D'Sparil's serpent.,OB_DSPARIL1,,,,%o byl@[ao_cs] zpopelněn@[ao_cs] ořem D'Sparila.,%o blev skoldet af D'Sparils slange.,%o wurde von D'Sparils Schlange verbrüht.,,%o varmegiĝis de la serpento de D'Sparil.,%o fue abrasad@[ao_esp] por la serpiente de D'Sparil.,,%o joutui D'Sparilin käärmeen kalttaamaksi.,%o a été ébouillanté@[e_fr] par un serpent de D'Sparil.,%o le lett forrázva D'Sparil Kígyója által.,%o è stato bruciato dal serpente di D'Sparil.,%o はデ'スパリルのサーペントに火傷を負わされた。,%o 은(는) 드'스파릴의 서펜트에 데였다.,%o werd gebroeid door de slang van D'Sparil.,%o ble skåldet av D'Sparils slange.,%o został@[ao_pl] poparzon@[adj_pl] przez węża D'Sparila.,%o foi escaldad@[ao_ptb] pela serpente de D'Sparil.,,%o a fost opărit de șarpele lui D'Sparil.,Игрока %o обжёг змей Д'Спарила.,Играча %o је опекао Д'Спарилова змија.,"%o, D'Sparil'in yılanı tarafından haşlandı." -%o was chewed up by D'Sparil's serpent.,OB_DSPARIL1HIT,,,,%o byl@[ao_cs] rozkousán@[ao_cs] ořem D'Sparila.,%o blev tygget op af D'Sparils slange.,%o wurde von D'Sparils Schlange verspeist.,,%o maĉegiĝis de la serpento de D'Sparil.,%o fue engullid@[ao_esp] por la serpiente de D'Sparil.,,%o joutui D'Sparilin käärmeen pureksimaksi.,%o a été dévoré@[e_fr] par un serpent de D'Sparil.,%o meg lett rágva D'Sparil Kigyója által.,%o è stato masticato dal serpente di D'Sparil.,%o はデ'スパリルのサーペントに噛み砕かれた。,%o 은(는) 드'스파릴의 서펜트에게 씹혔다.,%o werd door de slang van D'Sparil opgekauwd.,%o ble tygd opp av D'Sparils slange.,%o został@[ao_pl] przeżut@[adj_pl] przez węża D'Sparila.,%o foi mastigad@[ao_ptb] pela serpente de D'Sparil.,,%o a fost mestecat de șarpele lui D'Sparil.,Игрока %o пожрал змей Д'Спарила.,%o је сажвакан@[adj_1_sr] од стране Д'Спарилове змије.,"%o, D'Sparil'in yılanı tarafından çiğnendi." -%o was no match for D'Sparil.,OB_DSPARIL2,,,,%o nebyl@[ao_cs] pro D'Sparila žádná výzva.,%o kunne ikke klare D'Sparil.,%o war kein Gegner für D'Sparil.,,%o ne estis rivalo por D'Sparil. ,%o no fue rival para D'Sparil.,,%o ei mahtanut mitään D'Sparilille.,%o n'a pas pu égaler D'Sparil.,%o nem volt méltó ellenfél D'Sparil számára.,%o non era all'altezza di D'Sparil.,%o はデ'スパリルには全く歯が立たなかった。,%o 은(는) 드'스파릴에겐 상대가 되지 못했다.,%o was geen partij voor D'Sparil.,%o var ingen match for D'Sparil.,%o nie miał@[ao_pl] szans z D'Sparilem.,%o não foi páreo para D'Sparil.,%o não foi desafio para D'Sparil.,%o n-a fost nici pe departe pe măsura lui D'Sparil.,Игрок %o был не ровня Д'Спарилу.,%o није ни до колена Д'Спарилу.,"%o, D'Sparil'in dengi değildi." -%o was smacked down by D'Sparil.,OB_DSPARIL2HIT,,,,%o byl@[ao_cs] sražen@[ao_cs] D'Sparilem.,%o blev slået ned af D'Sparil.,%o wurde von D'Sparil zerklatscht.,,%o frapiĝis de D'Sparil.,%o fue vapulead@[ao_esp] por D'Sparil.,%o ha sido golpead@[ao_esp] por D'Sparil.,%o joutui D'Sparilin löylyttämäksi.,%o a été battu@[e_fr] a plate couture par D'Sparil.,%o a földre lett csapva D'Sparil által.,%o è stato abbattuto da D'Sparil.,%o はデ'スパリルに打ち負かされた。,%o 은(는) 드'스파릴의 맹격에 쓰러졌다.,%o werd neergeslagen door D'Sparil.,%o ble slått ned av D'Sparil.,%o został@[ao_pl] roztrzaskan@[adj_pl] przez D'Sparila,%o foi mort@[ao_ptb] por D'Sparil.,,%o a fost pus la pământ de D'Sparil.,Игрок %o сбит с ног Д'Спарилом.,%o је претучен@[adj_1_sr] од стране Д'Спарила.,"%o, D'Sparil tarafından yere serildi." -%o was scarred by a gargoyle.,OB_HERETICIMP,,,,%o byl@[ao_cs] upálen@[ao_cs] chrličem.,%o blev mærket af en gargoyle.,%o wurde von einem Gargoyle zerkratzt.,,%o ĉikartiĝis de gargojlo.,%o fue cicatrizad@[ao_esp] por una gárgola.,,%o joutui gargoilin arpeuttamaksi.,%o a été effrayé@[e_fr] par une gargouille.,%o meg lett sebesítve egy vízköpő által.,%o è stato terrorizzato da un imp.,%o はガーゴイルに傷を負わされた。,%o 은(는) 가고일에 의해 다쳤다.,%o was getekend door een gargoyle.,%o ble arret av en gargoyle.,%o został@[ao_pl] zadrapan@[adj_pl] przez gargulca,%o foi cicatrizad@[ao_ptb] por uma gárgula.,,%o a fost cicatrizat de o garguie.,Игрока %o изуродовала горгулья.,%o је ожиљкан@[adj_1_sr] од стране камене утваре.,%o bir gargoyle tarafından yaralandı. -%o was hacked by a gargoyle.,OB_HERETICIMPHIT,,,,%o byl@[ao_cs] rozsekán@[ao_cs] chrličem.,%o blev hakket af en gargoyle.,%o wurde von einem Gargoyle zerhackt.,,%o hakiĝis de gargojlo.,%o fue arañad@[ao_esp] por una gárgola.,,%o joutui gargoilin pilkkomaksi.,%o a été mis@[e_fr] en pièces par une gargouille.,%o fel lett vágva egy vízköpő által.,%o è stato eliminato da un imp.,%o はガーゴイルに切り刻まれた。,%o 은(는) 가고일에 의해 베였다.,%o werd gehackt door een gargoyle.,%o ble hakket av en gargoyle.,%o został@[ao_pl] pocięt@[adj_pl] przez gargulca,%o foi mutilad@[ao_ptb] por uma gárgula.,,%o a fost tăiat de o garguie.,Игрока %o покалечила горгулья.,Играча %o је исекла камена утвара.,%o bir gargoyle tarafından kesildi. -%o was devastated by an ironlich.,OB_IRONLICH,,,,%o byl@[ao_cs] zničen@[ao_cs] železným kostějem.,%o blev ødelagt af en jern lig.,%o wurde von der Eisernen Leiche zerstört.,,%o ruiniĝis de ferliĉo.,%o fue devastad@[ao_esp] por un liche de hierro.,,%o joutui rautakalmon hävittämäksi.,%o a été dévasté@[e_fr] par une Liche de Fer.,%o elpusztult egy ezüst lich miatt.,%o è stato devastato da un ironlich.,%o はアイアンリッチに吹き飛ばされた。,%o 은(는) 아이언 리치에게 붕괴 당했다.,%o werd verwoest door een ijzeren lijk.,%o ble knust av en jernlich.,%o został@[ao_pl] zdewastowan@[adj_pl] przez żelaznego lisza,%o foi devastad@[ao_ptb] por um lich de ferro.,,%o a fost devastat de un cadavru de fier.,Игрока %o растоптал железный лич.,%o је уништен@[adj_1_sr] од стране челичног лича.,%o demir bir ceset tarafından harap edildi. -%o got up-close and personal with an ironlich.,OB_IRONLICHHIT,,,,%o se dostal@[ao_cs] moc blízko k železnému kostěji.,%o kom helt tæt på en jern lig.,%o kam der Eisernen Leiche zu nahe.,,%o havis proksiman kaj desonan rekonton kun ferliĉo.,%o tuvo un encuentro cercano y personal con un liche de hierro.,,%o meni lähelle rautakalmoa.,%o a fait ami@[e_fr]-ami@[e_fr] avec une Liche de Fer.,%o közel került és személyes volt egy ezüst lichhel szemben.,%o è andato troppo vicino a un ironlich.,%o はアイアンリッチと密接に関わった。,%o 은(는) 사적인 이유로 아이언 리치에게 다가왔다.,%o werd door een ijzeren lijk onheus bejegend.,%o fikk nærkontakt med en jernlich.,%o był@[ao_pl] blisko i na osobności z żelaznym liszem,%o chegou muito perto de um lich de ferro.,,"%o s-a apropiat prea mult de un -cadavru de fier.",Игрок %o близко и лимно узнал железного лича.,%o се лично приближи@[ao_1_sr] челичном личу.,%o demir bir cesede çok yaklaştı. -%o was axed by an undead warrior.,OB_BONEKNIGHT,,,,%o dostal@[ao_cs] sekyrou od nemrtvého válečníka.,%o blev øksehugget af en udød kriger.,%o wurde von dem Untoten Krieger mit der Axt bearbeitet.,,%o hakiliĝis de malviva batalisto.,%o recibió un hachazo de un guerrero no-muerto.,,%o joutui epäkuolleen soturin kirvestämäksi.,%o s'est pris@[e_fr] la hâche d'un guerrier mort-vivant.,%o baltát kapott egy Élőhalott Harcostól.,%o è stato accettato da un guerriero non morto .,%o はアンデッド兵の斧でやられた。,%o 은(는) 언데드 전사에게 도끼질 당했다.,%o werd doorkliefd door een ondode krijger.,%o ble hugget av en udød kriger.,%o został@[ao_pl] rozłupany siekierą przez nieumarłego wojownika,%o foi decepad@[ao_ptb] por um guerreiro morto-vivo.,%o foi decapitad@[ao_ptb] por um guerreiro morto-vivo.,%o a primit un topor de la un războinic nemort.,Игрока %o зарубил воин-нежить.,%o је исечен@[adj_1_sr] од стане немртвог ратника.,%o bir ölümsüz savaşçı tarafından baltalandı. -%o was slain by an undead warrior.,OB_BONEKNIGHTHIT,,,,%o byl@[ao_cs] zabit@[ao_cs] nemrtvým válečníkem.,%o blev dræbt af en udød kriger.,%o wurde von dem Untoten Krieger hingemetzelt.,,%o estis mortigita de malviva batalisto.,%o fue descuartizad@[ao_esp] por un guerrero no-muerto.,,%o joutui epäkuolleen soturin tappamaksi.,%o s'est fait pourfendre par un guerrier mort-vivant.,%o meghalt egy Élőhalott Harcos által.,%o è stato ucciso da un guerriero non morto. ,%o はアンデッド兵の手で葬られた。,%o 은(는) 언데드 전사에게 처단당했다.,%o werd gedood door een ondode krijger.,%o ble drept av en levende død kriger.,%o został@[ao_pl] zgładzon@[adj_pl] przez nieumarłego wojownika,%o foi picotad@[ao_ptb] por um guerreiro morto-vivo.,,%o a fost omorât de un războinic nemort.,Игрока %o сразил воин-нежить.,Играча %o је убио немртви ратник.,%o bir ölümsüz savaşçı tarafından katledildi. -%o was blasted into cinders by a Maulotaur.,OB_MINOTAUR,,,,%o byl@[ao_cs] rozmetán@[ao_cs] na popel Minotaurem.,%o blev sprængt i aske af en Maulotaurus.,%o wurde von dem Minotaurus in Asche verwandelt.,,%o eksplodiĝis en cindrojn de Bategtaŭro.,%o fue volad@[ao_esp] en cenizas por un Mazotauro.,,%o tuhottiin tuusan nuuskaksi maulotaurin toimesta.,%o s'est fait@[e_fr] incinérer par un Massetaure.,%o darabokra robbant egy Maulotaurusz által.,%o è stato incenerito da un Maulotauro. ,%o はマウロタウロスに燃やされ炭化した。,%o 은(는) 몰로타우어에게 잿더미가 되도록 파괴당했다.,%o werd door een Maulotaurus tot sintels geblazen.,%o ble sprengt til aske av en Maulotaur.,%o został@[ao_pl] obrócon@[adj_pl] w popiół przez Młototaura,%o foi incinerad@[ao_ptb] por um Marretauro,,%o a fost făcut cenușă de un Maulotaur.,Игрока %o разнёс на угольки Избитавр.,%o је испуцан@[adj_1_sr] у пепео од стране минотаура.,%o bir Maulotor tarafından kül haline getirildi. -%o was pulped by a Maulotaur.,OB_MINOTAURHIT,,,,%o byl@[ao_cs] rozmáčknut@[ao_cs] Minotaurem.,%o blev knust af en Maulotaurus.,%o wurde von dem Minotaurus zu Brei verarbeitet.,,%o pulpiĝis de Bategtaŭro.,%o fue pulpad@[ao_esp] por un Mazotauro.,,%o joutui maulotaurin möyhentämäksi.,%o s'est fait@[e_fr] éclater par un Massetaure.,%o péppé lett zúzva egy Maulotaurusz által.,%o è stato ridotto in poltiglia da un Maulotauro. ,%o はマウロタウロスにグシャグシャにされた。,%o 은(는) 몰로타우어에 의해 내동댕이쳐졌다.,%o werd verpulverd door een Maulotaurus.,%o ble knust av en maulotaur.,%o został@[ao_pl] roztart@[adj_pl] na miazgę przez Młototaura,%o foi esmagad@[ao_ptb] por um Marretauro,,%o a fost descojit de un Maulotaur.,Игрока %o превратил в кровавое месиво Избитавр.,Играча %o је претукао минотаур.,%o bir Maulotor tarafından ezildi. -%o was smashed by a golem.,OB_MUMMY,,,,%o byl@[ao_cs] umlácen@[ao_cs] golémem.,%o blev smadret af en golem.,%o wurde von einem Golem erschlagen.,,%o frakasiĝis de golemo.,%o fue aplastad@[ao_esp] por un golem.,,%o joutui golemin murskaamaksi.,%o a été défoncé@[e_fr] par un golem.,%o össze lett törve egy Gólem által.,%o è stato schiacciato da un golem.,%o はゴーレムに叩きのめされた。,%o 은(는) 골렘에게 두들겨 맞았다.,%o werd verbrijzeld door een golem.,%o ble knust av en golem.,%o został@[ao_pl] stłuczon@[adj_pl] przez golema,%o foi esmagad@[ao_ptb] por um golem.,,%o a fost lovit de un golem.,Игрока %o разбил голем.,Играча %o је смрвио голем.,%o bir golem tarafından parçalandı. -%o was shrieked to death by a nitrogolem.,OB_MUMMYLEADER,,,,%o byl@[ao_cs] ukřičen@[ao_cs] k smrti střelgolémem.,%o blev skriget til døde af en nitrogolem.,%o wurde von einem Nitrogolem zu Tode gekreischt.,,%o estis kriegita ĝis morto de azotgolemo.,%o fue chillad@[ao_esp] hasta la muerte por un nitrogolem.,%o ha sido aplanad@[ao_esp] hasta la muerte por un nitrogolem.,%o kirkaistiin kuoliaaksi nitrogolemin toimesta.,%o s'est fait@[e_fr] percer les tympans par un nitrogolem.,%o halálra lett ijesztve egy Nitrógólem által.,%o è stato stroncato da un golem.,%o はニトロゴーレムに脅かされた。,%o 은(는) 니트로 골렘에 의해 비명횡사 당했다.,%o werd doodgekrijst door een nitrogolem.,%o ble skreket i hjel av en nitrogolem.,%o został@[ao_pl] zakrzyczan@[adj_pl] na śmierć przez nitrogolema,%o agonizou na frente de um nitrogolem.,,%o a fost chiuit până la moarte de un nitrogolem.,Игрока %o убил криком нитроголем.,Играча %o је извриштао до смрти нитроголем.,%o bir nitrogolem tarafından çığlık çığlığa öldürüldü. -%o was rattled by an ophidian.,OB_SNAKE,,,,%o byl@[ao_cs] zachřestěn@[ao_cs] šupinatcem.,%o blev rystet af en ophidian.,%o hörte das Klappern des Ophidian.,,%o klakiĝis de ofidio.,%o fue agitad@[ao_esp] por un ofidio.,,%o joutui käärmeolion kalkattamaksi.,%o s'est fait@[e_fr] sonner par un ophidien.,%o halálra lett csörgetve egy Ofidián által.,%o è stato stritolato da un serpente.,%o はオフィディアンに動揺した。,%o 은(는) 오피디안에게 흔들렸다.,%o werd gerammeld door een ophidiaan.,%o ble rystet av en ophidian.,%o został@[ao_pl] rozgrzechotan@[adj_pl] przez wężowatego,%o foi sacudid@[ao_ptb] por um ofídio.,,%o a fost bătut până la moarte de un ofidian.,Игрока %o потряс офидиан.,Играча %o је угризла змија.,%o bir ophidian tarafından sarsıldı. -%o was cursed by a wizard.,OB_WIZARD,,,,%o byl@[ao_cs] zaklet@[ao_cs] čarodějem.,%o blev forbandet af en troldmand.,%o wurde von dem Magier verflucht.,,%o malbeniĝis de sorĉisto.,%o fue maldecid@[ao_esp] por un mago.,%o ha sido hechizad@[ao_esp] por un mago.,%o joutui velhon kiroamaksi.,%o a été maudit@[e_fr] par un sorcier.,%o meg lett átkozva egy Varázsló által.,%o è stato maledetto da un mago.,%o はウィザードに呪われた。,%o 은(는) 드'스파릴의 제자에 의해 저주받았다.,%o werd vervloekt door een tovenaar.,%o ble forbannet av en trollmann.,%o został@[ao_pl] przeklęt@[adj_pl] przez czarownika,%o foi amaldiçoad@[ao_ptb] por um mago.,,%o a fost blestemat de un vrăjitor.,Игрока %o проклял колдун.,%o је проклет@[adj_1_sr] од стране чаробњака.,%o bir büyücü tarafından lanetlendi. -%o was palpated by a wizard.,OB_WIZARDHIT,,,,%o byl@[ao_cs] prozkoumán@[ao_cs] čarodějem.,%o blev palperet af en troldmand.,%o spürte den Hauch des Magiers.,,%o palpatiĝis de sorĉisto.,%o fue palpad@[ao_esp] por un mago.,,%o joutui velhon tunnustelemaksi.,%o a été palpé@[e_fr] par un sorcier.,%o meg lett tapogatva egy Varázsló által.,%o è stato toccato da un mago.,%o はウィザードに触診されてしまった。,%o 은(는) 드'스파릴의 제자에게 촉진당했다.,%o werd betast door een tovenaar.,%o ble palpert av en trollmann.,%o został@[ao_pl] przebadan@[adj_pl] przez czarownika,%o foi apalpad@[ao_ptb] por um mago.,,%o a fost palpat de un vrăjitor.,Игрока %o пощупал колдун.,Играча %o је палпатирао чаробњак.,%o bir büyücü tarafından palpe edildi. -%o got staffed by %k.,OB_MPSTAFF,,,,%o dostal@[ao_cs] holí od hráče %k.,%o blev stafferet af %k.,%o wurde von %k verprügelt.,,%o bategiĝis de %k.,%o fue apalead@[ao_esp] por %k.,,%k sauvoi %k paran.,%o s'est fait@[e_fr] matraquer par %k.,%o meg lett botozva %k által.,%o è stato preso a colpi di staffa da %k.,%o は %k の棒でぶん殴られた。,%o 은(는) %k 의 지팡이에 제압당했다.,%o kreeg een tik van %k's staf.,%o ble staffet av %k.,%o został@[ao_pl] walnięt@[adj_pl] laską przez %k,%o levou uma sova do bastão de %k.,,%o a fost bastonat de %k.,Игрок %o дополнил посох игрока %k.,%o је претуцан@[adj_1_sr] штапом од стране %k.,"%o, %k tarafından öldüresiye dövüldü." -%o got a shock from %k's gauntlets.,OB_MPGAUNTLETS,,,,%o byl@[ao_cs] prošokován@[ao_cs] rukavicemi hráče %k.,%o fik et chok af %ks handsker.,%o bekam einen Schock von %ks Handschuhen.,,%o recivis ŝokon de la fergantoj de %k.,%o recibió un choque de los guanteletes de %k.,,%o sai sähköiskun pelaajan %k kintaista.,%o s'est pris@[e_fr] un coup de jus des gantelets de %k.,%o kapott egy sokkot %k által.,%o è stato folgorato dai guanti di %k.,%o は %k の篭手からショックを受けた。,%o 은(는) %k 가 쓰고 있는 건틀릿의 전격을 느꼈다.,%o kreeg een schok van %k's handschoenen.,%o fikk støt av %ks hansker.,%o został@[ao_pl] wstrząśnięt@[adj_pl] rękawicami %k,%o tomou um choque das manoplas de %k.,,%o a primit un șoc de la mănușile lui %k.,Игрок %o шокирован перчатками игрока %k.,%o је доби@[ao_1_sr] шок од %k штапа.,"%o, %k tarafından şoklandı." -%o waved goodbye to %k's elven wand.,OB_MPGOLDWAND,,,,%o zamával@[ao_cs] elfské hůlce hráče %k.,%o vinkede farvel til %ks elverstav.,%o sagte „Tschüß“ zu %ks Elfenstab.,,%o ĝisis al la elfa sorĉbastono de %k.,%o le dijo adiós a la vara de elfo de %k.,,%o heilutti hyvästit pelaajan %k haltiasauvalle.,%o à fait coucou à la baguette magique de %k.,%o integetett egy viszlátot %k Elf Pálcájának.,%o ha fatto ciao ciao allo scettro elfico di %k.,%o は %k のエルフのワンドに別れの挨拶をした。,%o 은(는) %k 의 엘프 지팡이를 보고 작별인사를 했다.,%o zwaaide afscheid van %k's elvenstaf.,%o vinket farvel til %ks alvestav.,%o pomachał@[ao_pl] na do widzenia elfiej różdżce %k,%o deu tchauzinho para o cetro élfico de %k.,%o disse adeuzinho para o cetro élfico de %k.,%o a facut cu mână toiagului lui %k.,Игрок %o узрел прощальный взмах эльфийского жезла игрока %k.,%o је рек@[ao_2_sr] збогом %k вилењачком штапићу.,"%o, %k tarafından delik deşik edildi." -%o was pegged by %k's ethereal crossbow.,OB_MPCROSSBOW,,,,%o byl@[ao_cs] prostřelen@[ao_cs] éterickou kuší hráče %k.,%o blev stukket af %ks æteriske armbrøst.,%o von %ks Armbrustbolzen aufgespießt.,,%o kejlis de la etera arbalesto de %k.,%o fue flechad@[ao_esp] por la ballesta etérea de %k.,,%k ripusti %o paran eteerivarsijousellaan.,%o s'est fait@[e_fr] clouer par l'arbalète étherique de %k.,%o fel lett rögzítve %k Éteri Nyílpuskájának által.,%o è stato inchiodato dalla balestra eterea di %k.,%o は %k のイセリアルクロスボウで釘付けにされた。,%o 은(는) %k 의 유체 쇠뇌에 의해 처박혔다.,%o was vastgepind door %k's etherische kruisboog.,%o ble truffet av %ks eteriske armbrøst.,%o został@[ao_pl] przebit@[adj_pl] przez eteryczną kuszę %k,%o foi esmigalhad@[ao_ptb] pela besta etérea de %k.,,%o a fost prins de arbaleta celestă a lui %k.,Игрок %o изранен болтами эфирного арбалета игрока %k.,%o је упуц@[adj_2_sr] од стране %k етералног самострела.,"%o, %k tarafından çivilendi." -%o was blasted a new one by %k's dragon claw.,OB_MPBLASTER,,,,%o poznal@[ao_cs] středověk drakospárem hráče %k.,%o blev sprængt en ny af %ks drageklo.,%o bekam %ks Drachenklaue zu spüren.,,%o estis diseksplodita de la drakokrifo de %k.,%o quedó bien jodid@[ao_esp] por la garra de dragón de %k.,,%k puhkoi %o parkaan uuden aukon lohikäärmeenkynnellään.,%o s'est fait flinguer par la griffe draconique de %k.,%o újszerűnek látszik %k Sárkány Karomjának köszönhetően.,A %o èstato aperto un buco nuovo dall'Artiglio di Drago di %k.,%o は %k のドラゴンクローで発破体験した。,%o 은(는) %k 의 용발톱에 의해 형태를 잃었다.,%o werd opengescheurd door %k's drakenklauw.,%o fikk en ny en av %ks drageklo.,%o został wysadzony nowy otwór przez %k,%o sentiu o poder da garra de dragão de %k.,,%o a fost aruncat în aer de gheara dragonului a lui %k.,Игрок %o получил новую форму драконьим когтем игрока %k.,Играчу %o је отворена нова рупа змајевском канџом играча %k.,"%o, %k tarafından patlatıldı." -%o got sent down under by %k's hellstaff.,OB_MPSKULLROD,,,,Pod hráčem %o se propadla zem peklopalem hráče %k.,%o blev sendt ned under jorden af %ks helvedestav.,%o brach unter %ks Höllenrute zusammen.,,%o forsendiĝis sub de la inferbastono de %k.,%o se inclinó ante el bastón infernal de %k.,,%k lähetti %o paran maan syövereihin hornansauvallaan.,%o repose six pieds sous terre grâce au Bâton infernal de %k.,%o le lett küldve %k Pokolbotjának köszönhetően.,%o è stato mandato sottoterra dalla Staffa Infernale di %k.,%o は %k のヘルスタッフで冥界に送られた。,%o 은(는) %k 의 지옥지팡이에 의해 저승으로 날아갔다.,%o werd door %k's hellestaf naar beneden gestuurd.,%o ble sendt til helvete av %ks helvetesstav.,%o został@[ao_pl] zesłan@[adj_pl] pod piekielny kostur %k,%o foi mandad@[ao_ptb] pra baixo do solo pelo cajado infernal de %k.,,%o a fost trimis sub bastonul infernal al lui %k.,Игрок %o сослан в самый низ посохом ада игрока %k.,%o је укопан@[adj_1_sr] од стране пакленог штапа играча %k.,"%o, %k tarafından biçildi." -%o was scorched to cinders by %k's phoenix rod.,OB_MPPHOENIXROD,,,,%o byl@[ao_cs] spálen@[ao_cs] na prach fénixovou holí hráče %k.,%o blev brændt til aske af %ks føniksstav.,%o wurde voin %ks Phönixstab verschmort.,,%o brulegiĝis en cindrojn de la feniksvergo de %k.,%o fue reducid@[ao_esp] a cenizas por el báculo del Fénix de %k.,,%k kärvensi %o paran tuhannen päreiksi feenikssauvallaan.,%o s'est fait@[e_fr] réduire en cendres par le Bâton du Phénix de %k.,%o halomra lett égve %k Főnix Rúdjának által.,%o è stato ridotto in cenere dal Bastone della Fenice di %k.,%o は %k のフェニックスロッドで焼かれた。,%o 은(는) %k 의 불사조 지팡이 덕에 검게 익었다.,%o werd door %k's feniksstaf tot sintels verschroeid.,%o ble svidd til aske av %ks føniksstav.,%o został@[ao_pl] spalon@[adj_pl] na popiół przez różdżkę feniksa %k,%o virou cinzas com o bastão da fênix de %k.,,%o a fost făcut cenușă de joarda phoenix a lui %k.,Игрок %o сожжён до пепла жезлом феникса игрока %k.,%o запаљен@[adj_1_sr] у пепео од стране шипке феникса играча %k.,"%o, %k tarafından cayır cayır yakıldı." -%o was bounced by %k's firemace.,OB_MPMACE,,,,%o byl@[ao_cs] odpálen@[ao_cs] žezlometem hráče %k.,%o blev kastet afsted af %ks ildspyd.,%o prallte an %ks Feuerkeule ab.,,%o estis resaltita de la fajroklabo de %k.,%o recibió los rebotes de la maza de fuego de %k.,,%k pomputti %o parkaa tulinuijallaan.,%o a rebondi@[e_fr] sur les balles de la Masse de Feu à %k.,%o pattant egy nagyot %k Tűzbuzogányának köszönhetően.,%o è stato spazzato via dalla Mazza del Fuoco di %k.,%o は %k のファイアメイスで飛ばされた。,%o 은(는) %k 의 투사철퇴의 포탄을 맞고 튕겨져 날아갔다.,%o werd door %k's vuurknots geraakt.,%o ble kastet av %ks ildkule.,%o został@[ao_pl] wybit@[adj_pl] przez buzdygan ognia %k,%o saiu pulando após ver a clava de fogo de %k.,,"%o a fost aruncat de colo colo de buzduganul de -foc al lui %k.",Игрок %o отбит огненной булавой игрока %k.,%o је ударен@[adj_1_sr] са ватреним буздованом играча %k.,"%o, %k tarafından ezildi." -%o got clapped by %k's charged staff.,OB_MPPSTAFF,,,,%o byl@[ao_cs] profackován@[ao_cs] nabitou holí hráče %k.,%o blev klappet af %ks ladede stav.,%o bekam eine Klatsche durch %ks geladenen Stab.,,%o estis aplaŭdita de la ŝargita bastono de %k.,%o recibió los palos del bastón cargado de %k .,,%k jyrisytti %o parkaa varatulla sauvallaan.,%o à été foudroyé@[e_fr] par le bâton chargé de %k.,%o csattant egy nagyot %k Feltöltött Botjának által.,%o è scoppiato a causa della staffa incantata di %k.,%o は %k の魔力を帯びた棒で暖かく迎えられた。,%o 은(는) %k 의 마법부가 지팡이를 얻어맞았다.,%o kreeg een klap van %k's opgeladen staf.,%o ble klappet av %ks ladede stav.,%o został@[ao_pl] trzepnięt@[adj_pl] naładowaną laską %k,%o tomou uma pancada do bastão carregado de %k.,,%o a fost tăiat de bastonul încărcat al lui %k.,Игрок %o отведал заряженного посоха игрока %k.,%o је потапшан@[adj_1_sr] напуњеним штапом играча %k.,"%o, %k tarafından yakıldı." -%o was bled dry by %k's gauntlets.,OB_MPPGAUNTLETS,,,,Rukavicemi hráče %k nezůstala v těle hráče %o ani kapka krve.,%o blev udblødt af %ks handsker.,%o wurde von %ks Handschuhen ausgeblutet.,,%o sensangiĝis de la fergantoj de %k.,%o fue desangrad@[ao_esp] por los guanteletes de %k.,,%k vuodatti %o paran kuiviin kintaillaan.,%o s'est fait@[e_fr] saigner à blanc par les gantelets de %k.,%k megtanította %o-t Páncélkesztyűbe dudálni.,Il sangue di %o è stato prosciugato dai guanti di %k.,%o は %k の篭手で血を絞り取られた。,%o 은(는) %k 의 마법부가 건틀릿에 의해 바싹 말랐다.,%o werd leeggebloed door %k's handschoenen.,%o ble tappet for blod av %ks hansker.,%o wykrwawił@[ao_pl] się przez rękawice %k,%o sangrou nas manoplas de %k.,,"%o a fost stors până la ultima picătură de sânge -de mănușile lui %k.",Игрок %o был обескровлен перчатками игрока %k.,%o је путпуно искрвари@[ao_1_sr] од рукавица играча %k.,"%o, %k tarafından kan kaybından kurutuldu." -%o was assaulted by %k's elven wand.,OB_MPPGOLDWAND,,,,%o byl@[ao_cs] napaden@[ao_cs] elfskou hůlkou hráče %k.,%o blev overfaldet af %ks elverstav.,%o wurde von %ks Elfenstab überwältigt.,,%o atakiĝis de la elfa sorĉbastono de %k.,%o fue asaltad@[ao_esp] por la vara de elfo de %k.,,%o joutui pelaajan %k haltiasauvan pahoinpitelemäksi.,%o à été assailli@[e_fr] par la baguette elfique de %k.,%k megbotozta %o az Elf Botjával.,%o è stato assalito dallo Scettro Elfico di %k.,%o は %k のエルフのワンドで襲われた。,%o 은(는) %k 의 마법부가 엘프 지팡이에 의해 사냥당했다.,%o werd aangevallen door %k's elvenstaf.,%o ble angrepet av %ks alvestav.,%o został@[ao_pl] zaatakowan@[adj_pl] przez elfią różdżkę %k,%o foi atacad@[ao_ptb] pelo cetro élfico de %k.,,%o a fost luat cu asalt de togaiul lui %k.,Игрок %o атакован эльфийским жезлом игрока %k.,%o је нападнут@[adj_1_sr] вилењачким штапом играча %k.,"%o, %k tarafından saldırıya uğradı." -%o was shafted by %k's ethereal crossbow.,OB_MPPCROSSBOW,,,,%o byl@[ao_cs] proděravěn@[ao_cs] éterickou kuší hráče %k.,%o blev ramt af %ks æteriske armbrøst.,%o wurde von %ks Armbrustbolzen durchbohrt.,,%o akiris novan truon de etera arbalesto de %k.,%o fue encañonad@[ao_esp] por la ballesta etérea de %k.,,%k joutui pelaajan %k eteerivarsijousen kepittämäksi.,%o s'est fait@[e_fr] transpercer par l'arbalète éthérique de %k.,%o megkóstolta %k Éteri Nyílpuskáját.,%o è stato impalato dalla balestra eterea di %k.,%o は %k のイセリアルクロスボウで押された。,%o 은(는) %k 의 마법부가 유체 쇠뇌에 의해 무뎌졌다.,%o werd door %k's etherische kruisboog geschaafd.,%o ble truffet av %ks eteriske armbrøst.,%o został@[ao_pl] wykiwan@[adj_pl] przez eteryczną kuszę %k,%o foi flechad@[ao_ptb] pela besta etérea de %k.,,"%o a fost pus la proțap de arbaleta celestă a lui -%k.",Игрок %o пробит эфирным арбалетом игрока %k.,%o је упуцан@[adj_1_sr] етеричним самострелом играча %k.,"%o, %k tarafından şaftlandı." -%o was ripped apart by %k's dragon claw.,OB_MPPBLASTER,,,,%o byl@[ao_cs] roztrhnut@[ao_cs] naskrz drakospárem hráče %k.,%o blev flået i stykker af %ks drageklo.,%o wurde von der Drachenklaue zerrissen.,,%o disrompiĝis de la drakokrifo de %k.,%o fue desgarrad@[ao_esp] por la garra de dragón de %k.,,%k repi %o paran kappaleiksi lohikäärmeenkynnellään.,%o à été mis@[e_fr] en pièces par la griffe draconique de %k.,%o szét lett tépve %k Sárkány Karomja által.,%è stato fatto a brandelli dall'Artiglio di Drago di %k.,%o は %k のドラゴンの鉤爪でバラバラに引き裂かれた。,%o 은(는) %k 의 마법부가 용발톱에 갈기갈기 찢겨졌다.,%o werd uit elkaar gescheurd door %k's drakenklauw.,%o ble revet i filler av %ks drageklo.,%o został@[ao_pl] rozerwan@[adj_pl] przez smoczy pazur %k,%o foi cortad@[ao_ptb] pela garra de dragão de %k.,,%k a fost făcut bucăți de gheara lui %k.,Игрок %o разорван драконьим когтём игрока %k.,%o је поцепан@[adj_1_sr] змајевим канџама играча %k.,"%o, %k tarafından parçalara ayrıldı." -%k poured the hellstaff on %o.,OB_MPPSKULLROD,,,,Hráč %k vylil svůj peklopal na hráče %o.,%k hældte helvedesstaven ud over %o.,%k ließ den Höllenregen auf %o los.,,%k ŝutas la inferbastonon sur %o.,%k virtió su bastón infernal en %o.,,%k vuodatti hornansauvansa %o parkaan.,%k à versé toute la rage des enfers sur %o.,%o nem hozott esernyőt %o Pokolbot zápora ellen.,%k ha fatto sgorgare la sua Staffa Infernale su %o.,%o は %k にヘルスタッフを %p 注ぎ込まれた。,%k의 마법부가 지옥지팡이가 쏟아붓는 비를 %o 이(가) 맞았다.,%k liet de helregen los op %o.,%k helte helvetesstaven over %o.,%k polał@[ao_pl] swoim piekielnym kosturem %o,%k usou seu cajado infernal no %o.,,%k a vărsat bastonul infernal pe %o.,Игрок %k залил игрока %o горячим дождём при помощи посоха ада.,%k је просипа@[ao_1_sr] пламени штап на %o.,"%o, %k tarafından yakıldı." -%o was burned down by %k's phoenix staff.,OB_MPPPHOENIXROD,,,,%o byl@[ao_cs] vyhořen@[ao_cs] fénixovou holí hráče %k.,%o blev brændt ned af %ks Føniks stav.,%o wurde von %ks Phönixstab verbrannt.,,%o torĉiĝis de la feniksvergo de %k.,%o fue rostizad@[ao_esp] por el báculo del Fénix de %k.,,%k poltti %o paran feenikssauvallaan.,%o à été incinéré@[e_fr] par le Bâton du Phénix de %k.,%o elégett %k Főnix Botjának által.,%o è stato incendiato dal Bastone della Fenice di %k.,%o は %k のフェニックスロッドで焼き滅ぼされた。,%o 은(는) %k 의 마법부가 불사조 지팡이에 의해 화장당했다.,%o werd afgebrand door %k's feniksstaf.,%o ble brent ned av %ks føniksstav.,%o został@[ao_pl] spalon@[adj_pl] przez różdżkę feniksa %k,%o foi queimad@[ao_ptb] pelo bastão da fênix de %k.,,%o a fost ars complet de joarda lui %k.,Игрок %o сожжён жезлом феникса игрока %k.,%o је изгоре@[ao_1_sr] шипком феникса играча %k.,"%o, %k tarafından yakıldı." -%o was squished by %k's giant mace sphere.,OB_MPPMACE,,,,%o byl@[ao_cs] rozmačkán@[ao_cs] obrovskou žezlometnou koulí hráče %k.,%o blev mast af %ks ildspyd kugle.,%o wurde von %ks Feuerkeule zerquetscht.,,%o premiĝis de la grandega klubsfero de %k.,%o fue aplastad@[ao_esp] por una esfera gigante de la maza de %k.,,%k liiskasi %o paran jättiläisnuijapallollaan.,%o s'est fait@[e_fr] écraser par la balle de Masse géante de %k.,%o össze lett nyomva %k hatalmas buzogány gömbje által.,%o è stato spiaccicato da una sfera gigante della Mazza del Fuoco di %k.,%o は %k の巨大なメイススフィアで潰された。,%o 은(는) %k 의 마법부가 투사철퇴가 뿜은 거대포탄에 의해 납작해졌다.,%o werd verpletterd door %k's reusachtige strijdknots.,%o ble knust av %ks gigantiske muskatblomstkule.,%o został@[ao_pl] zmiażdżon@[adj_pl] przez ogromną kulę z buzdygana %k,%o foi esmagad@[ao_ptb] pela esfera de clava gigante de %k.,,"%o a fost strivit de globul buzduganului -lui %k.",Игрок %o раздавлен огромной сферой из огненной булавы %k.,%o је смрвљен@[adj_1_sr] од стане огромном сферско буздована играча %k.,"%o, %k tarafından ezildi." -,,Hexen,,,,,,,,,,,,,,,,,,,,,,,, -,,Pickup,,,,,,,,,,,,,,,,,,,,,,,, -Blue Mana,TXT_MANA_1,,,,Modrá mana,Blå Mana,Blaues Mana,,Blua Manao,Maná Azul,Mana Azul,Sininen mana,Mana Bleu,Kék Mana,Mana blu,青マナ,청색 마나,Blauwe Mana,Blå Mana,Niebieska Mana,Mana Azul,,Mană Albastră,Синяя мана,Плава мана,Mavi Mana -Green Mana,TXT_MANA_2,,,,Zelená mana,Grøn Mana,Grünes Mana,,Verda Manao,Maná Verde,Mana Verde,Vihreä mana,Mana Vert,Zöld Mana,Mana verde,緑マナ,녹색 마나,Groene Mana,Grønn Mana,Zielona Mana,Mana Verde,,Mană Verde,Зелёная мана,Зелена мана,Yeşil Mana -Combined Mana,TXT_MANA_BOTH,,,,Smíšená mana,Kombineret Mana,Kombiniertes Mana,,Kuna Manao,Maná Combinado,Mana Combinado,Yhdistetty mana,Mana Combiné,Kombinált Mana,Mana misto,複合マナ,윰합된 마나,Gecombineerde Mana,Kombinert mana,Połączona Mana,Mana Combinado,,Mană Mixtă,Общая мана,Комбинована мана,Kombine Mana -Steel Key,TXT_KEY_STEEL,,,,Ocelový klíč,Stålnøgle,Stahlschlüssel,Ατσάλινο Κλειδί,Ŝtala Ŝlosilo,Llave de Acero,,Teräsavain,Clé d'Acier,Acél Kulcs,Chiave d'acciaio,鋼の鍵,강철 열쇠,Stalen Sleutel,Stålnøkkel,Stalowy Klucz,Chave de Aço,,Cheia din Oțel,Стальной ключ,Челични кључ,Çelik Anahtar -Cave Key,TXT_KEY_CAVE,,,,Klíč od jeskyně,Hule-nøgle,Höhlenschlüssel,,Kavern-Ŝlosilo,Llave de la Caverna,,Luola-avain,Clé de la Cave,Barlang Kulcs,Chiave della caverna,洞窟の鍵,동굴 열쇠,Grotsleutel,Hulenøkkel,Klucz do Jaskini,Chave da Caverna,,Cheia Peșterii,Пещерный ключ,Пећински кључ,Mağara Anahtarı -Axe Key,TXT_KEY_AXE,,,,Sekyrový klíč,Økse-nøgle,Axtschlüssel,,Hakil-Ŝlosilo,Llave de Hacha,,Kirvesavain,Clé de la Hache,Fejsze Kulcs,Chiave dell'ascia,斧の鍵,도끼 열쇠,Bijlsleutel,Økse-nøkkel,Klucz-topór,Chave do Machado,,Cheia Topor,Топор-ключ,Кључ секира,Balta Anahtarı -Fire Key,TXT_KEY_FIRE,,,,Ohnivý klíč,Ild-nøgle,Feuerschlüssel,,Fajro-Ŝlosilo,Llave de Fuego,,Tuliavain,Clé du Feu,Tűz Kulcs,Chiave del fuoco,炎の鍵,불 열쇠,Vuursleutel,Ildnøkkel,Ognisty Klucz,Chave do Fogo,,Cheia de Foc,Огненный ключ,Огњени кључ,Yangın Anahtarı -Emerald Key,TXT_KEY_EMERALD,,,,Smaragdový klíč,Smaragdnøgle,Smaragdschlüssel,,Smerelda Ŝlosilo,Llave Esmeralda,,Smaragdiavain,Clé d'Emeraude,Smaragd Kulcs,Chiave di smeraldo,翠玉の鍵,에메랄드 열쇠,Smaragden Sleutel,Smaragdnøkkel,Szmaragdowy Klucz,Chave de Esmeralda,,Cheia din Smarald,Изумрудный ключ,Смарагдни кључ,Zümrüt Anahtar -Dungeon Key,TXT_KEY_DUNGEON,,,,Klíč od žaláře,Dungeon-nøgle,Kerkerschlüssel,,Karcer-Ŝlosilo,Llave del Calabozo,,Tyrmän avain,Clé du Donjon,Várbörtön Kulcs,Chiave del sotterraneo,迷宮の鍵,지하감옥 열쇠,Kerkersleutel,Dungeon-nøkkel,Klucz do Lochu,Chave da Masmorra,,Cheia Temniței,Ключ от подземелья,Кључ од лагума,Zindan Anahtarı -Silver Key,TXT_KEY_SILVER,,,,Stříbrný klíč,Sølvnøgle,Silberschlüssel,Ασυμένιο Κλειδί,Arĝenta Ŝlosilo,Llave de Plata,,Hopea-avain,Clé d'Argent,Ezüst Kulcs,Chiave d'argento,銀の鍵,은 열쇠,Zilveren Sleutel,Sølvnøkkel,Srebrny Klucz,Chave de Prata,,Cheia din Argint,Серебряный ключ,Сребрни кључ,Gümüş Anahtar -Rusted Key,TXT_KEY_RUSTED,,,,Zrezivělý klíč,Rustet nøgle,Rostiger Schlüssel,Σκουριασμένο Κλειδί,Rusta Ŝlosilo,Llave Oxidada,,Ruosteinen avain,Clé Rouillée,Rozsdás Kulcs,Chiave arrugginita,錆びた鍵,녹슨 열쇠,Geroeste Sleutel,Rustet nøkkel,Zardzewiały Klucz,Chave Enferrujada,,Cheia Ruginită,Ржавый ключ,Зарђали кључ,Paslı Anahtar -Horn Key,TXT_KEY_HORN,,,,Parožní klíč,Hornnøgle,Hornschlüssel,,Hup-Ŝlosilo,Llave de Cuerno,,Sarviavain,Clé Corne,Szarv Kulcs,Chiave del corno,角の鍵,뿔 열쇠,Hoornsleutel,Horn-nøkkel,Rogowy Klucz,Chave do Chifre,,Cheia Corn,Роговой ключ,Рогати кључ,Korna Anahtarı -Swamp Key,TXT_KEY_SWAMP,,,,Klíč od bažiny,Sumpnøgle,Sumpfschlüssel,,Marĉo-Ŝlosilo,Llave del Pantano,,Suoavain,Clé des Marécages,Mocsár Kulcs,Chiave della palude,沼の鍵,늪지대 열쇠,Moerassleutel,Sumpnøkkel,Bagienny Klucz,Chave do Pântano,,Cheia Mlaștinii,Болотный ключ,Мочварни кључ,Bataklık Anahtarı -Castle Key,TXT_KEY_CASTLE,,,,Klíč od hradu,Slotsnøgle,Burgschlüssel,,Kastel-Ŝlosilo,Llave del Castillo,,Linnan avain,Clé du Château,Kastély Kulcs,Chiave del castello,城の鍵,성 열쇠,Kasteelsleutel,Slottsnøkkel,Klucz do Zamku,Chave do Castelo,,Cheia Castelului,Ключ от замка,Кључ од замка,Kale Anahtarı -Icon of the Defender,TXT_ARTIINVULNERABILITY2,,,,Obráncova ikona,Ikon af forsvareren,Ikone des Verteidigers,,Ikono de la Defendanto,Icono del Defensor,Ícono del Defensor,Puolustajan ikoni,Icône du Défenseur,Védelmező Ikonja,Icona del difensore,守護者の像,수호의 성상,Symbool van de Verdediger,Forsvarerens ikon,Ikona Obrońcy,Ícone do Defensor,,Imaginea Apărătorului,Символ защитника,Симбол браниоца,Savunucunun Simgesi -Dark Servant,TXT_ARTISUMMON,,,,Temný služebník,Mørk tjener,Dunkler Diener,,Malluma Servanto,Sirviente Oscuro,,Pimeä palvelija,Serviteur Noir,Árny Szolga,Servitore oscuro,闇の従者,어둠의 하인,Donkere Dienaar,Mørk tjener,Mroczny Sługa,Servo Negro,,Servitor Întunecat,Тёмный слуга,Мрачни слуга,Karanlık Hizmetkar -Porkalator,TXT_ARTIEGG2,,,,Vepřovitel,,,,Porkigilo,Porcinador,,Sikaannuttaja,Porcificateur,Ártányátok,Porchificatore,ポークレイター,돈육기,,,Schabowator,Porquificador,,Porcolator,Свиновизатор,Свињатор,Porkalator -Flechette,TXT_ARTIPOISONBAG,,,,Střelka,,,,Flakono,Flechette,,,Fléchette,Flakon,Fiaschetta,フレチェット,플레셰트,,,Flaszka,,,Flacon,Флешетта,Бочица,Flechette -Banishment Device,TXT_ARTITELEPORTOTHER,,,,Vyhošťovač,Forvisningsanordning,Verbannungsgerät,,Forpelilo,Dispositivo de Desvanecimiento,,Häivytyskoje,Outil de Banissement,Száműző,Artifatto dell'esilio,追放のデバイス,소멸 장치,Verbanningsapparaat,Forvisningsanordning,Urządzenie Wygnania ,Dispositivo do Banimento,,Dispozitiv al Alungării,Устройство изгнания,Амблем прогањања,Sürgün Cihazı -Boots of Speed,TXT_ARTISPEED,,,,Běhuté boty,Støvler af hastighed,Turbo-Stiefel,,Botoj de Rapideco,Botas de Velocidad,,Ripeyssaappaat,Bottes de Célérité,Sebesség Cipője,Stivali della velocità,素早さの靴,속도의 신발,Snelheidslaarzen,Støvler av fart,Buty Szybkości,Botas da Velocidade,,Bocancii Vitezei,Сапоги-скороходы,Брзинске чизме,Hız Çizmeleri -Krater of Might,TXT_ARTIBOOSTMANA,,,,Kalich síly,Krater of Might,Kelch der Macht,,Kratero de Potenco,Vasija de Fuerza,,Mahtikrateeri,Cratère de Pouvoir,Hatalom Krátere,Calice della forza,魔力の盃,힘의 향로,Beker van Macht,Krater av makt,Czara mocy,Cálice do Poder,,Pocal al Puterii,Чаша могущества,Чаша силе,Kudret Krateri -Dragonskin Bracers,TXT_ARTIBOOSTARMOR,,,,Dračí nátepníky,Drageskindsarmbøjler,Drachenhaut-Armschutz,,Brakbendo el Drakhaŭto,Brazaletes de piel de Dragón,,Lohikäärmeennahkarannesuojat,Bracelets en Peau de Dragon,Sárkánybőr Karkötők,Bracciali in pelle di drago,竜皮の小手,용가죽 팔찌,Drakenhuidbescherming,Dragehud-bindinger,Karwasze ze Smoczej Skóry,Braçadeiras de Pele de Dragão,,Brățări din Piele de Dragon,Наручи из драконьей кожи,Наруквице од змајеве коже,Ejderha Derisi Bilezikler -Disc of Repulsion,TXT_ARTIBLASTRADIUS,,,,Kotouč odpuzení,Skive af frastødning,Rückstoßscheibe,,Disko de Repelado,Disco de Repulsión,,Karkotuskiekko,Disque de Répulsion,Visszaverés Lemeze,Disco della repulsione,反発の円盤,방탄의 원반,Schijf van Afstoting,Frastøtelsesskive,Dysk Odpychania,Disco da Repulsão,,Disc al Repulsiei,Диск отторжения,Диск одбијања,İtme Diski -Mystic Ambit Incant,TXT_ARTIHEALINGRADIUS,,,,Tajemný čár koljdoucí,Mystic Ambit Incant,Verbannungsgerät,,Sorĉo de Mistika Sfero,Encanto de Ámbito Místico,,Mystisen piirin loitsu,Incantation Mystique,Misztikus Mágialista,Confine mistico,魅知国の秘法,신비 영역의 주문,,Mystic Ambit-besvergelse,Inkantancja Mistycznego Kręgu,Encanto Místico,,Pergament Mistic,Чары магического единства,Чаролија магичног јединства,Mistik Ambit Büyüsü -Yorick's Skull,TXT_ARTIPUZZSKULL,,,,Jorikova lebka,Yoricks kranium,Yoricks Schädel,,Kranio de Yorick,Calavera de Yorick,,Yorickin kallo,Crâne de Yorick,Yorick Koponyája,Teschio di Yorick,ヨリックの髑髏,요릭의 두개골,Yorick's Schedel,Yoricks hodeskalle,Czaszka Yoricka,Caveira de Yorick,,Craniul lui Yorick,Череп Йорика,Јорикова лобања,Yorick'in Kafatası -Heart of D'sparil,TXT_ARTIPUZZGEMBIG,,,,Srdce D'Sparila,D'sparils hjerte,D'Sparils Herz,,Koro de D'sparil,Corazón de D'Sparil,,D'Sparilin sydän,Cœur de D'Sparil,D'Sparil szíve,Cuore di d'sparil,デ'スパリルの心,드'스파릴의 심장,Hart van D'sparil,D'Sparils hjerte,Serce D'Sparila,Coração de D'Sparil,,Inima lui D'Sparil,Сердце Д'Спарила,Д'Спарилино срце,D'sparil'in Kalbi -Ruby Planet,TXT_ARTIPUZZGEMRED,,,,Rubínová planeta,Rubinplanet,Rubinplanet,,Rubena Planedo,Planeta Rubí,,Rubiiniplaneetta,Planète de Rubis,Rubin Bolygó,Pianeta di rubino,ルビーの宝石,루비 행성석,Robijnrode Planeet,Rubinplaneten,Rubinowa Planeta,Planeta Rubi,,Planetă din Rubin,Рубиновая планета,Планета рубина,Yakut Gezegeni -Emerald Planet,TXT_ARTIPUZZGEMGREEN1,,,,Smaragdová planeta,Smaragdplanet,Smaragdplanet,,Smeralda Planedo,Planeta Esmeralda,,Smaragdiplaneetta,Planète d'Emeraude,Smaragd Bolygó,Pianeta di smeraldo,エメラルドの宝石,에메랄드 행성석 (1),Smaragdgroene Planeet,Smaragdplaneten,Szmaragdowa Planeta,Planeta Esmeralda,,Planetă din Smarald,Изумрудная планета,Смарагдна планета,Zümrüt Gezegen -Emerald Planet,TXT_ARTIPUZZGEMGREEN2,,,,Smaragdová planeta,Smaragdplanet,Smaragdplanet,,Smeralda Planedo,Planeta Esmeralda,,Smaragdiplaneetta,Planète de Saphir,Smaragd Bolygó,Pianeta di smeraldo,エメラルドの宝石,에메랄드 행성석 (2),Smaragdgroene Planeet,Smaragdplaneten,Szmaragdowa Planeta,Planeta Esmeralda,,Planetă din Smarald,Изумрудная планета,Смарагдна планета,Zümrüt Gezegen -Sapphire Planet,TXT_ARTIPUZZGEMBLUE1,,,,Safírová planeta,Safirplanet,Saphirplanet,,Safira Planedo,Planeta Zafiro,,Safiiriplaneetta,Planète de Saphir,Zafír Bolygó,Pianeta di zaffiro,サファイアの宝石,사파이어 행성석 (1),Saffierblauwe Planeet,Safirplaneten,Szafirowa Planeta,Planeta Safira,,Planetă din Safir,Сапфировая планета,Сафирна планета,Safir Gezegen -Sapphire Planet,TXT_ARTIPUZZGEMBLUE2,,,,Safírová planeta,Safirplanet,Saphirplanet,,Safira Planedo,Planeta Zafiro,,Safiiriplaneetta,Planète de Saphir,Zafír Bolygó,Pianeta di zaffiro,サファイアの宝石,사파이어 행성석 (2),Saffierblauwe Planeet,Safirplaneten,Szafirowa Planeta,Planeta Safira,,Planetă din Safir,Сапфировая планета,Сафирна планета,Safir Gezegen -Daemon Codex,TXT_ARTIPUZZBOOK1,,,,,,,,Kodekso de Demono,Códice del Demonio,,Daemon-koodeksi,Codex Démoniaque,Démon Kódex,Codice Demoniaco ,デーモンの写本,악마의 고문서,,,Demoniczny Kodeks,Códice Demoníaco,,Codexul Demonilor,Демонический кодекс,Демонски кодекс, -Liber Oscura,TXT_ARTIPUZZBOOK2,,,,,,,,Liber Oscura,Liber Oscura,,,,,,オスキュラ公文書,어둠의 자유서,,,Liber Oscura,,,,Либер Оскура,Либер Оскура, -Flame Mask,TXT_ARTIPUZZSKULL2,,,,Plamenná maska,Flammemaske,Flammenmaske,,Flamomasko,Máscara de llamas,,Liekkinaamio,Masque de Flammes,Láng Maszk,Maschera delle fiamme,炎の仮面,화염의 가면,Vuurmasker,Flammemaske,Maska Płomieni,Máscara das Chamas,,Mască de Foc,Маска пламени,Маска пламена,Alev Maskesi -Glaive Seal,TXT_ARTIPUZZFWEAPON,,,,Glévská pečeť,Glasur-segl,Schwetsiegel,,Sigelo de Glavo,Sello de Espada,,Miekkasinetti,Sceau du Glaive,Pallos Pecsét,Sigillo della brando,グレイブシール,밀폐된 칼날,Lanszegel,Glaive segl,Pieczęć Glewii,Selo do Gládio,,Sigiliu Spadă,Печать воителя,Војников печат,Glaive Mühür -Holy Relic,TXT_ARTIPUZZCWEAPON,,,,Svatá relikvie,Hellig relikvie,Heiliges Relikt,,Sankta Relikvo,Santa Reliquia,,Pyhä reliikki,Relique Sacrée,Szent Ereklye,Reliquia sacra,聖遺物,신성한 유물,Heilige Relikwie,Hellig relikvie,Święta Relikwia,Relíquia Sagrada,,Relicvă Sfântă,Святая реликвия,Света реликвија,Kutsal Emanet -Sigil of the Magus,TXT_ARTIPUZZMWEAPON,,,,Mágovo sigilium,Magus' segl,Symbol des Magiers,,Sigelo de la Mago,Emblema del Mago,,Taikurin sinetti,Sceau du Mage,Mágus Pecsétje,Suggello del magus,メイガスの印章,마거스의 인장,Sigaar van de Magus,Magusens segl,Emblemat Maga,Sigilo do Mago,,Sigiliul Magului,Печать Мага,Чаробњаков симбол,Büyücünün Sigil'i -Clock Gear,TXT_ARTIPUZZGEAR,,,,Ozubené kolečko,Urværk,Zahnrad,,Dentrado de Horloĝo,Engranaje de reloj,,Kellonratas,Rouage d'Horloge,Óra Szerkezet,Ingranaggio d'orologio,時計の歯車,시계 톱니바퀴,Kloktandwiel,Klokkeutstyr,Mechanizm Zegara,Engrenagem de Relógio,,Mecanism Ceas,Часовая шестерня,Сатни зупчаник,Saat Dişlisi -You Cannot Use This Here,TXT_USEPUZZLEFAILED,,,,Zde se tento předmět použít nedá,Du kan ikke bruge dette her,Das kannst du hier nicht benutzen,,Vi ne povas uzi ĉi tion ĉi tie.,No puedes usar esto aquí,,Et voi käyttää tätä tässä,Vous ne pouvez pas utiliser cela ici.,Ezt Itt Nem Használhatod,Non puoi usare questo oggetto qui,ここでは使用できない,이것은 여기에 사용할 수 없다,Dat kan je hier niet gebruiken,Du kan ikke bruke dette her,Nie możesz użyć tego tutaj,Você não pode usar isso aqui,Não podes usar isto aqui,Nu Poți Folosi Asta Aici,Здесь это невозможно использовать,Ово се не може користити овде,Bunu Burada Kullanamazsınız -Mesh Armor,TXT_ARMOR1,,,Mesh Armour,Kroužkové brnění,Mesh Armor,Kettenrüstung,,Marŝkiraso,Armadura de Malla,,Rengashaarniska,Armure de Mailles,Háló Páncél,Maglia metallica,鎖帷子,사슬 갑옷,Maliënkolder,Nettrustning,Kolczuga,Armadura de Malha,,Armură din Zale,Кольчуга,Верижњача,Örgü Zırh -Falcon Shield,TXT_ARMOR2,,,,Sokolí štít,Falke-skjold,Falkenschild,,Falko-Ŝildo,Escudo de Halcón,,Haukkakilpi,Bouclier du Faucon,Sólyom Pajzs,Scudo del falco,鷹の盾,팔콘 방패,Valkenschild,Falkeskjold,Sokola Tarcza,Escudo do Falcão,,Scut Șoim,Соколиный щит,Соколов штит,Falcon Kalkanı -Platinum Helmet,TXT_ARMOR3,,,,Platinová helma,Platin-hjelm,Platinhelm,,Platena Kasko,Casco de Platino,,Platinakypärä,Casque de Platine,Platina Sisak,Elmo di platino,白金の兜,백금 투구,Platina Helm,Platinahjelm,Platynowy Hełm,Capacete de Platina,,Coif de Platină,Платиновый шлем,Шлем од платине,Platin Kask -Amulet of Warding,TXT_ARMOR4,,,,Amulet uhýbání,Amulet af afværge,Wachamulett,,Amuleto de Gardado,Amuleto de Guarda,,Suojelusamuletti,Amulette de Protection,Oltalom Amulettje,Amuleto di protezione,回避の護符,수호의 부적,Amulet van Bescherming,Amulett av beskyttelse,Amulet Ochrony,Amuleto da Proteção,,Amuleta Protecției,Амулет стража,Амулет страже,Korunma Tılsımı -Timon's Axe,TXT_WEAPON_F2,,,,Timonova sekera,Timons økse,Timons Axt,,Hakilo de Timon,Hacha de Timón,,Timonin kirves,Hache de Timon,Timon Baltája,Ascia di timon,タイモンの斧,티몬의 도끼,Timon's Bijl,Timons øks,Topór Timona,Machado de Timon,,Toporul lui Timon,Топор Тимона,Тимонова секира,Timon'un Baltası -Hammer of Retribution,TXT_WEAPON_F3,,,,Kladivo odplaty,Gengældelsens hammer,Hammer der Rache,,Martelo de Repago,Martillo de Retribución,,Koston vasara,Marteau de la Rétribution,Kárhozat Kalapácsa,Martello del castigo,報復の金槌,징벌의 망치,Hamer der Vergelding,Gjengjeldelsens hammer,Młot Odkupienia,Martelo da Retribuição,,Ciocanul Salvării,Молот возмездия,Чекић одмазде,İntikam Çekici -Quietus Assembled,TXT_WEAPON_F4,,,,Složený Tišitel,Forløser samlet,Erlöser komplettiert,,Kvietus' Muntita,Quietus Ensamblado,,Quietus koottuna,Quietus Assemblée,Némusz Összerakva,Quietus assemblato,組み立てた 死滅の剣,완성된 종언의 검,Quietus in elkaar gezet,Quietus samlet,Złożony Uciszacz,Quietus Montada,,Argument Final Asamblat,Последний довод собран воедино,Самрт је сабрана,Quietus Birleştirildi -Serpent Staff,TXT_WEAPON_C2,,,,Hadí hůl,Slange-stav,Schlangenstab,,Serpentbastono,Vara de Serpiente,,Käärmesauva,Sceptre du Serpent,Kígyó Bot,Bastone del serpente,蛇の杖,뱀 지팡이,Slangenstaf,Slangestav,Laska Węży,Cetro da Serpente,,Bastonul Șarpelui,Змеиный посох,Змијски штап,Yılan Asa -Firestorm,TXT_WEAPON_C3,,,,Ohnivá bouře,Ildstorm,Feuersturm,,Fajroŝtormo,Tormenta de Fuego,,Tulimyrsky,Tempête de Feu,Tűzvihar,Tempesta di fuoco,ファイアストーム,화염폭풍,Vuurstorm,Ildstorm,Burza Ognia,Tempestade-de-Fogo,,Furtună de Foc,Огненный шторм,Огњена олуја,Ateş Fırtınası -Wraithverge Assembled,TXT_WEAPON_C4,,,,Složený Zjevitel,Spirit Bringer samlet,Geisterbringer komplettiert,,Fantomkruc' Muntita,Báculo Fantasmal Ensamblado,Vara Fantasmal Ensamblada,Haamusauva koottuna,Verge Phantasmale Assemblée,Bosszúbot Összerakva,Verga Sconfinaspettri assemblata,組み立てた レイスバージ,완성된 사령의 십자가,Schimroede in elkaar gezet,Wraithverge samlet,Złożony Widmoskraj,Cajado Fantasma Montado,,Toiag Stafie Asamblat,Жезл духов собран воедино,Жезло утвара је сабрано,Wraithverge Birleştirildi -Frost Shards,TXT_WEAPON_M2,,,,Ledové střepy,Frostskår,Frostsplitter,,Frostfragmentoj,Fragmentos de Escarcha,,Pakkassirpaleet,Eclats de Givre,Fagyos Szilánkok,Frantumi gelati,フロスト シャード,얼음 파편,Vorstscherven,Frostskår,Lodowe Odłamki,Fragmentos de Geada,,Cioburi de Gheață,Ледяные осколки,Ледене крхотине,Buz Kırıkları -Arc of Death,TXT_WEAPON_M3,,,,Jiskry smrti,Dødens bue,Todesblitz,,Arko de Morto,Arcos de la Muerte,,Kuolonkaari,Foudre Mortelle,Halál Boltíve,Arco della morte,死の円弧,죽음의 번갯불,Doodsboog,Dødens bue,Łuk Śmierci,Arcos da Morte,,Izvorul Morții,Дуга смерти,Лук смрти,Ölüm Arkı -Bloodscourge Assembled,TXT_WEAPON_M4,,,,Složený Krvehrom,Blodgisel samlet,Blutgeißel komplettiert,,Sangskurĝ' Muntita,Plaga Sangrienta ensamblada,,Veripiiska koottuna,Fléau Sanglant Assemblé,Vérkorbács Összerakva,Flagello di Sangue assemblato,組み立てた 天罰,완성된 피의 재앙,Bloedgesel in elkaar gezet,Bloodscourge samlet,Złożona Krwioplaga,Flagelo de Sangue Montado,,Flagel Sângeros Asamblat,Кровавый бич собран воедино,Крвави бич је сабран,Bloodscourge Birleştirildi -A weapon piece! This is your lucky day!,TXT_WEAPONPIECE,,,,Část zbraně! Dnes je tvůj šťastný den!,Et våbenstykke! Dette er din heldige dag!,Ein Waffensegment. Das ist dein Glückstag!,,Peco de armilo! Estas via bonŝanca tago!,¡Una pieza de un arma! ¡Es tu día de suerte!,,Aseen osa! Tämä on onnenpäiväsi!,Une pièce d'arme! C'est votre jour de chance!,Egy fegyver darab! Szerencés napod van!,Il frammento di un'arma! È il tuo giorno fortunato! ,武器の一片! 今日は吉日だ!,무기의 한 조각이다! 운수 좋은 날인 것 같다!,Een wapenstuk! Dit is je geluksdag!,En våpendel! Dette er lykkedagen din!,Część broni! To twój szczęśliwy dzień!,Um fragmento de arma! Esse é o seu dia de sorte!,Um fragmento de arma! Este é o teu dia de sorte!,O piesă din super armă! E ziua ta norocoasă!,Часть оружия! Сегодня ваш счастливый день!,Део оружја! Данас Вам је срећан дан!,Bir silah parçası! Bugün şanslı gününüz! -Segment of Quietus,TXT_QUIETUS_PIECE,,,,Část Tišitele,Segment af Forløseren,Segment des Erlösers,,Segmento de Kvietus',Segmento de Quietus,,Quietuksen osa,Segment de Quietus,Darab a Némuszból,Parte del Quietus,死滅の剣の切片,종언의 검 조각,Segment van Quietus,Segment av Quietus,Fragment Uciszacza,Segmento de Quietus,,Fragment din Argumentul Final,Часть последнего довода,Део Самрти,Quietus'un bir bölümü -Segment of Wraithverge,TXT_WRAITHVERGE_PIECE,,,,Část Zjevitele,Segment af Spirit Bringer,Segment des Geisterbringers,,Segmento de Fantomkruc',Segmento del Báculo Fantasmal,,Haamusauvan osa,Segment de la Verge Phantasmale,Darab a Bosszúbotból,Parte della Verga Sconfinaspettri,レイスバージの切片,사령의 십자가 조각,Segment van Schimroede,Segment av Wraithverge,Fragment Widmoskraju,Segmento do Cajado Fantasma,,Fragment din Toiagul Stafie,Часть жезла духов,Део Жезла утвара,Wraithverge'in Segmenti -Segment of Bloodscourge,TXT_BLOODSCOURGE_PIECE,,,,Část Krvehromu,Segment af Blodgiselen,Segment der Blutgeißel,,Segmento de Sangskurĝ',Segmento de la Plaga Sangrienta,,Veripiiskan osa,Segment du Fléau Sanglant,Darab a Vérkorbácsból,Parte del Flagello di Sangue,天罰の切片,피의 재앙 조각,Segment van Bloedgesel,Segment av Bloodscourge,Fragment Krwioplagi,Segmento do Flagelo de Sangue,,Fragment din Flagelul Sângeros,Часть кровавого бича,Део Крвавог бича,Bloodscourge'un Segmenti -,,Locks,,,,,,,,,,,,,,,,,,,,,,,, -You need the Steel Key,TXT_NEED_KEY_STEEL,,,,Potřebuješ ocelový klíč,Du skal bruge stålnøglen,Du brauchst den Stahlschlüssel,Χρειάζεσε το Ατσάλινο κλειδί.,Vi bezonas la Ŝtalan Ŝlosilon,Necesitas la Llave de Acero,,Tarvitset teräsavaimen,Vous avez besoin de la Clé d'Acier,Az Acél Kulcsra van szükséged,Ti serve la Chiave d'Acciaio,鋼の鍵が必要だ,강철 열쇠가 필요하다,Je hebt de Stalen Sleutel nodig.,Du trenger stålnøkkelen,Potrzebujesz Stalowego Klucza,Você precisa da Chave de Aço,Precisas da Chave de Aço,Ai nevoie de Cheia din Oțel,Нужен стальной ключ,За отварање је потребан челични кључ,Çelik Anahtara ihtiyacın var -You need the Cave Key,TXT_NEED_KEY_CAVE,,,,Potřebuješ klíč od jeskyně,Du skal bruge hulenøglen,Du brauchst den Höhlenschlüssel,,Vi bezonas la Kavern-Ŝlosilon,Necesitas la Llave de la Caverna,,Tarvitset luola-avaimen,Vous avez besoin de la Clé de la Cave,A Barlang Kulcsra van szükséged,Ti serve la Chiave della Caverna ,洞窟の鍵が必要だ,동굴 열쇠가 필요하다,Je hebt de Grotsleutel nodig.,Du trenger hulenøkkelen,Potrzebujesz Klucza do Jaskini,Você precisa da Chave da Caverna,Precisas da Chave da Caverna,Ai nevoie de Cheia Peșterii,Нужен пещерный ключ,За отварање је потребан пећински кључ,Mağara Anahtarına ihtiyacın var -You need the Axe Key,TXT_NEED_KEY_AXE,,,,Potřebuješ sekyrový klíč,Du skal bruge øksenøglen,Du brauchst den Axtschlüssel,,Vi bezonas la Hakil-Ŝlosilon,Necesitas la Llave de Hacha,,Tarvitset kirvesavaimen,Vous avez besoin de la Clé de la Hache,A Fejsze Kulcsra van szükséged,Ti serve la Chiave dell'Ascia,斧の鍵が必要だ,도끼 열쇠가 필요하다,Je hebt de Bijlsleutel nodig.,Du trenger øksenøkkelen,Potrzebujesz Klucza-Topora,Você precisa da Chave do Machado,Precisas da Chave do Machado,Ai nevoie de Cheia Topor,Нужен ключ-топор,За отварање је потребан кључ секира,Balta Anahtarına ihtiyacın var -You need the Fire Key,TXT_NEED_KEY_FIRE,,,,Potřebuješ ohnivý klíč,Du skal bruge brandnøglen,Du brauchst den Feuerschlüssel,,Vi bezonas la Fajro-Ŝlosilon,Necesitas la Llave de Fuego,,Tarvitset tuliavaimen,Vous avez besoin de la Clé du Feu,A Tűz Kulcsra van szükséged,Ti serve la Chiave del Fuoco ,炎の鍵が必要だ,불 열쇠가 필요하다,Je hebt de Vuursleutel nodig.,Du trenger Ildnøkkelen,Potrzebujesz Ognistego Klucza,Você precisa da Chave do Fogo,Precisas da Chave do Fogo,Ai nevoie de Cheia de Foc,Нужен огненный ключ,За отварање је потребан огњени кључ,Ateş Anahtarına ihtiyacın var -You need the Emerald Key,TXT_NEED_KEY_EMERALD,,,,Potřebuješ smaragdový klíč,Du skal bruge smaragdnøglen,Du brauchst den Smaragdschlüssel,,Vi bezonas la Smeraldan Ŝlosilon,Necesitas la Llave Esmeralda,,Tarvitset smaragdiavaimen,Vous avez besoin de la Clé d'Emeraude,A Smaragd Kulcsra van szükséged,Ti serve la Chiave di Smeraldo ,翠玉の鍵が必要だ,에메랄드 열쇠가 필요하다,Je hebt de Smaragden Sleutel nodig.,Du trenger smaragdnøkkelen,Potrzebujesz Szmaragdowego Klucza,Você precisa da Chave Esmeralda,Precisas da Chave Esmeralda,Ai nevoie de Cheia din Smarald,Нужен изумрудный ключ,За отварање је потребан смарагдни кључ,Zümrüt Anahtarı'na ihtiyacın var. -You need the Dungeon Key,TXT_NEED_KEY_DUNGEON,,,,Potřebuješ klíč od žaláře,Du skal bruge fangehulsnøglen,Du brauchst den Kerkerschlüssel,,Vi bezonas la Karcer-Ŝlosilon,Necesitas la Llave del Calabozo,,Tarvitset tyrmän avaimen,Vous avez besoin de la Clé du Donjon,A Várbörtön Kulcsra van szükséged,Ti serve la Chiave del Sotterraneo ,迷宮の鍵が必要だ,지하감옥 열쇠가 필요하다,Je hebt de Kerkersleutel nodig.,Du trenger fangehullsnøkkelen,Potrzebujesz Klucza do Lochu,Você precisa da Chave da Masmorra,Precisas da Chave das Masmorras,Ai nevoie de Cheia Temniței,Нужен ключ от подземелья,За отварање је потребан кључ од лагума,Zindan Anahtarına ihtiyacın var -You need the Silver Key,TXT_NEED_KEY_SILVER,,,,Potřebuješ stříbrný klíč,Du skal bruge sølvnøglen,Du brauchst den Silberschlüssel,Χρειάζεσε το Ασυμένιο κλειδί.,Vi bezonas la Arĝentan Ŝlosilon,Necesitas la Llave de Plata,,Tarvitset hopea-avaimen,Vous avez besoin de la Clé d'Argent,Az Ezüst Kulcsra van szükséged,Ti serve la Chiave d'Argento ,銀の鍵が必要だ,은 열쇠가 필요하다,Je hebt de Zilveren Sleutel nodig.,Du trenger sølvnøkkelen,Potrzebujesz Srebrnego Klucza,Você precisa da Chave de Prata,Precisas da Chave Prata,Ai nevoie de Cheia din Argint,Нужен серебряный ключ,За отварање је потребан сребрни кључ,Gümüş Anahtara ihtiyacın var -You need the Rusted Key,TXT_NEED_KEY_RUSTED,,,,Potřebuješ zrezivělý klíč,Du skal bruge den rustne nøgle,Du brauchst den rostigen Schlüssel,Χρειάζεσε το Σκουριασμένο κλειδί.,Vi bezonas la Rustan Ŝlosilon,Necesitas la Llave Oxidada,,Tarvitset ruosteisen avaimen,Vous avez besoin de la Clé Rouillée,A Rozsdás Kulcsra van szükséged,Ti serve la Chiave Arrugginita ,錆びた鍵が必要だ,녹슨 열쇠가 필요하다,Je hebt de Geroeste Sleutel nodig.,Du trenger den rustne nøkkelen,Potrzebujesz Zardzewiałego Klucza,Você precisa da Chave Enferrujada,Precisas da Chave Enferrujada,Ai nevoie de Cheia Ruginită,Нужен ржавый ключ,За отварање је потребан зарђали кључ,Paslı Anahtar'a ihtiyacın var. -You need the Horn Key,TXT_NEED_KEY_HORN,,,,Potřebuješ parožní klíč,Du skal bruge hornnøglen,Du brauchst den Hornschlüssel,,Vi bezonas la Hup-Ŝlosilon,Necesitas la Llave de Cuerno,,Tarvitset sarviavaimen,Vous avez besoin de la Clé Corne,A Szarv Kulcsra van szükséged,Ti serve la Chiave del Corno ,角の鍵が必要だ,뿔 열쇠가 필요하다,Je hebt de Hoornsleutel nodig.,Du trenger Horn-nøkkelen,Potrzebujesz Rogowego Klucza,Você precisa da Chave do Chifre,Precisas da Chave do Chifre,Ai nevoie de Cheia Corn,Нужен роговой ключ,За отварање је потребан рогати кључ,Korna Anahtarına ihtiyacınız var -You need the Swamp Key,TXT_NEED_KEY_SWAMP,,,,Potřebuješ klíč od bažiny,Du skal bruge sumpnøglen,Du brauchst den Sumpfschlüssel,,Vi bezonas la Marĉ-Ŝlosilon,Necesitas la Llave del Pantano,,Tarvitset suoavaimen,Vous avez besoin de la Clé des Marécages,A Mocsár Kulcsra van szükséged,Ti serve la Chiave della Palude ,沼の鍵が必要だ,늪지대 열쇠가 필요하다,Je hebt de Moerassleutel nodig.,Du trenger Sump-nøkkelen,Potrzebujesz Bagiennego Klucza,Você precisa da Chave do Pântano,Precisas da Chave do Pântano,Ai nevoie de Cheia Mlaștinii,Нужен болотный ключ,За отварање је потребан мочварни кључ,Bataklık Anahtarına ihtiyacın var. -You need the Castle Key,TXT_NEED_KEY_CASTLE,,,,Potřebuješ klíč od hradu,Du skal bruge slotsnøglen,Du brauchst den Burgschlüssel,,Vi bezonas la Kastel-Ŝlosilon,Necesitas la Llave del Castillo,,Tarvitset linnan avaimen,Vous avez besoin de la Clé du Château,A Kastély Kulcsra van szükséged,Ti serve la Chiave del Castello ,城の鍵が必要だ,성 열쇠가 필요하다,Je hebt de Kasteelsleutel nodig.,Du trenger slottsnøkkelen,Potrzebujesz Klucza do Zamku,Você precisa da Chave do Castelo,Precisas da Chave do Castelo,Ai nevoie de Cheia Castelului,Нужен ключ от замка,За отварање је потребан кључ од замка,Kale Anahtarına ihtiyacın var -,,Actor tag names,,,,,,,,,,,,,,,,,,,,,,,, -Afrit,FN_FIREDEMON,,,,,,,,Afrito,,,,,,Afrit,アフリート,아프리트,Afriet,,Afrit,,,Demon de Foc,Африт,Африт,Afrit -Serpent,FN_DEMON1,,,,Zlohad,Slange,Chaos-Schlange,,Serpento,Serpiente,,Käärme,,Kígyó,Serpente del Caos,サーペント,서펜트,Slang,Slangen,Wąż,Serpente,,Șarpe,Змей,Серпент,Yılan -Ettin,FN_ETTIN,,,,Skřet,,,,Gigantaĉo,,,,,,Ettin,エティン,에틴,,,Ettin,,,Etin,Эттин,Етин,Ettin -Centaur,FN_CENTAUR,,,,Kentaur,Kentaur,Zentaur,,Centaŭro,Centauro,,Kentauri,Centaure,Kentaur,Centauro,ケンタウロス,켄타우로스,Centaurus,Kentaur,Centaur,Centauro,,Centaur,Кентавр,Кентаур,Kentaur -Slaughtaur,FN_SLAUGHTAUR,,,,Ničitaur,Slagtaur,Schlachtaur,,Buĉataŭro,Masacratauro,,Teurastauri,Sangtaure,Vágtaur,Sventrauro,スロアタウル,슬로터로스,Slachttaurus,Slakttaur,Rzeziotaur,Chacinotauro,,Centaur Violent,Убитавр,Кентаур старешина,Katlaur -Bishop,FN_BISHOP,,,,Biskup,Biskop,Bischof,,Episkopo,Obispo,,Piispa,Evèque,Érsek,Vescovo,ビショップ,비숍,Bisschop,Biskop,Biskup,Bispo,,Episcop,Епископ,Епископ,Piskopos -Wendigo,FN_ICEGUY,,,,,,,,Vendiko,,,,,,Wendigo,ウェンディゴ,윈디고,,,Wendigo,,,Vendigo,Вендиго,Вендиго,Wendigo -Stalker,FN_SERPENT,,,,Slídil,,Wasserjäger,,Gvatanto,Acechador,,Vaanija,Chasseur,Orvhalász,Cacciatore,ストーカー,스토커,,,Prześladowca,Caçador,,Vânător,Преследователь,Вребач,Stalker -Reiver,FN_WRAITH,,,,Přízrak,,Phantom,,Fantomo,Saqueador,,Ryöväri,,Martalóc,Incursore,レイバー,리버,Rover,,Rozbójnik,Fantasma,,Pungaș,Грабитель,Грабљивац,Hayalet -Death Wyvern,FN_DRAGON,,,,Smrtidrak,Døden Wyvern,Todesdrache,,Morta viverno,Guiverno de la muerte,,Kuolontraakki,Vouivre de la Mort,A Halál Sárkánya,Viverna Mortale,デス ワイバーン,데스 와이번,Doodsdraak,Døden Wyvern,Wiwerna Śmierci,Serpe da Morte,,Balaur al Morții,Виверна смерти,Змајак смрти,Ölüm Wyvern -Korax,FN_KORAX,,,,,,,,Korax,,,Kooraks,,,Korax,唯一神コラックス,코락스,,,Korax,Korax,,,Коракс,Коракс, -Zedek,FN_FBOSS,,,,,,,,Zedeko,,,Sedek,,,Zedek,ゼデク,제닥,,,Zedek,Zedek,,,Зедек,Зедек, -Menelkir,FN_MBOSS,,,,,,,,Menelkiro,,,Menelkir,,,Menelkir,メネルキル,메넬키어,,,Menelkir,Menelkir,,,Менелкир,Менелкир, -Traductus,FN_CBOSS,,,,Traduktus,,,,Traduktuso,,,Traduktus,,Traduktusz,Traductus,トラダクタス,트라닥투스,,,Traductus,Traductus,,,Традуктус,Традуктус, -Heresiarch,FN_HERESIARCH,,,,Arcikacíř,Heresiark,Erzketzer,,Ĉefherezulo,Heresiarca,,Kerettiarkki,L'Hérésiarche,Főeretnek,Eresiarca,ヘレシアーク,헤러시아크,,Heresiark,Herezjarcha,Heresiarca,,Ereziarh,Ересиарх,Јересијарх,Heresiark -Blue Mana,AMMO_MANA1,,,,Modrá mana,Blå Mana,Blaues Mana,,Blua Manao,Maná azul,,Sininen mana,Mana Bleu,Kék Mana,Mana blu,ブルーマナ,청색 마나,Blauwe Mana,Blå Mana,Niebieska Mana,Mana Azul,,Mană Albastră,Синяя мана,Плава мана,Mavi Mana -Green Mana,AMMO_MANA2,,,,Zelená mana,Grøn Mana,Grünes Mana,,Verda Manao,Maná verde,,Vihreä mana,Mana Vert,Zöld Mana,Mana verde,グリーンマナ,녹색 마나,Groene Mana,Grønn Mana,Zielona Mana,Mana Verde,,Mană Verde,Зелёная мана,Зелена мана,Yeşil Mana -Mace of Contrition,TAG_CWEAPMACE,,,,Palcát kajícnosti,Stridskølle af anger,Streitkolben,,Klabo de Penteco,Maza de Contrición,,Katumuksen nuija,Masse de Pénitence,Bűnbánat Buzogánya,Mazza del Pentimento,懺悔のメイス,참회의 철퇴,Knots van Wroeging,Mace of Contrition,Buzdygan Skruchy,Maça da Contrição,,Buzduganul Remușcării,Булава раскаяния,Буздован покајања,Pişmanlık Topuzu -Serpent Staff,TAG_CWEAPSTAFF,,,,Hadí hůl,Slange-stav,Schlangenstab,,Serpentbastono,Bastón de Serpiente,,Käärmesauva,Sceptre du Serpent,Kígyó Bot,Staffa del Serpente ,蛇の杖,뱀 지팡이,Slangenstaf,Slangestav,Laska Węży,Cetro da Serpente,,Bastonul Șarpelui,Змеиный посох,Змијски штап,Yılan Asa -Firestorm,TAG_CWEAPFLAME,,,,Ohnivá bouře,Ildstorm,Feuersturm,,Fajrŝtormo,Tormenta de Fuego,,Tulimyrsky,Tempête de Feu,Tűzvihar,Tempesta di Fuoco ,ファイアストーム,화염폭풍,Vuurstorm,Ildstorm,Burza Ognia,Tempestade-de-fogo,,Furtună de Foc,Огненный шторм,Огњена олуја,Ateş Fırtınası -Wraithverge,TAG_CWEAPWRAITHVERGE,,,,Zjevitel,Spirit Bringer,Geisterbringer,,Fantomkruc',Báculo Fantasmal,,Haamusauva,Verge Phantasmale,Lidércvég,Verga SconfinaSpettri,レイスバージ,사령의 십자가,Schimroede,Wraithverge,Widmoskraj,Cajado Fantasma,,Toiag Stafie,Жезл духов,Жезло утвара,Wraithverge -Spiked Gauntlets,TAG_FWEAPFIST,,,,Ohrocené rukavice,Spidse handsker,Stachelhandschuhe,,Pintaj Fergantoj,Guanteletes Puntiagudos,,Piikkirautakintaat,Gantelets à Pointes,Tűskés Páncélkesztyűk,Guantoni Spinati,スパイク ガントレット,가시 장갑,Spijkerhandschoenen,Pigghansker,Kolczaste Rękawice,Manoplas Espinhadas,,Mănuși cu Țepi,Шипастые перчатки,Бодљикаве рукавице,Çivili Eldivenler -Timon's Axe,TAG_FWEAPAXE,,,,Timonova sekera,Timons økse,Timons Axt,,Hakilo de Timon,Hacha de Timón,,Timonin kirves,Hache de Timon,Timon Baltája,Ascia di Timon,タイモンの斧,티몬의 도끼,Timon's Bijl,Timons øks,Topór Timona,Machado de Timon,,Toporul lui Timon,Топор Тимона,Тимонова секира,Timon'un Baltası -Hammer of Retribution,TAG_FWEAPHAMMER,,,,Kladivo odplaty,Hævnens hammer,Hammer der Rache,,Martelo de Repago,Martillo de Retribución,,Koston vasara,Marteau de la Rétribution,Kárhozat Kalapácsa,Martello del Castigo,報復の金槌,징벌의 망치,Hamer van Vergelding,Gjengjeldelsens hammer,Młot Odkupienia,Martelo da Retribuição,,Ciocanul Salvării,Молот возмездия,Чекић одмазде,İntikam Çekici -Quietus,TAG_FWEAPQUIETUS,,,,Tišitel,Forløser,Erlöser,,Kvietus',,,,Quietus,Némusz,Quietus,死滅の剣,종언의 검,,Quietus,Uciszacz,Quietus,,Argument Final,Последний довод,Самрт,Quietus -Sapphire Wand,TAG_MWEAPWAND,,,,Safírová hůl,Safir-stav,Saphirstab,,Safirsorĉbastono,Varita de Zafiro,,Safiirisauva,Baguette de Saphir,Zafír Pálca,Scettro di Zaffiro ,サファイア ワンド,사파이어 지팡이,Saffieren Toverstok,Safirstaven,Szafirowa Różdżka,Cetro de Safira,,Toiag cu Safir,Сапфировая волшебная палочка,Сафирни штап,Safir Değnek -Frost Shards,TAG_MWEAPFROST,,,,Ledové střepy,Frostskår,Frostsplitter,,Frostfragmentoj,Fragmentos de Escarcha,,Pakkassirpaleet,Eclats de Givre,Fagyos Szilánkok,Schegge di Ghiaccio ,フロスト シャード,얼음 파편,Vorstscherven,Frostskår,Lodowe Odłamki,Fragmentos de Geada,,Cioburi de Gheață,Замораживающие осколки,Ледене крхотине,Buz Kırıkları -Arcs of Death,TAG_MWEAPLIGHTNING,,,,Jiskry smrti,Dødens buer,Todesblitz,,Arkoj de Morto,Arcos de la Muerte,,Kuolonkaaret,Foudre Mortelle,Halál Boltíve,Archi della Morte ,死の円弧,죽음의 번갯불,Doodsboog,Dødens buer,Łuki Śmierci,Arcos da Morte,,Izvoarele Morții,Дуга смерти,Лук смрти,Ölüm Yayları -Bloodscourge,TAG_MWEAPBLOODSCOURGE,,,,Krvehrom,Blodgisel,Blutgeißel,,Sangskurĝ',Plaga Sangrienta,,Veripiiska,Fléau Sanglant,Vérkorbács,Flagello di Sangue,天罰,피의 재앙,Bloedgesel,Bloodscourge,Krwioplaga,Flagelo de Sangue,,Flagel Sângeros,Кровавый бич,Крвави бич,Bloodscourge -Disc of Repulsion,TAG_ARTIBLASTRADIUS,,,,Kotouč odpuzení,Afstødningsskive,Rückstoßscheibe,,Disko de Repelado,Disco de Repulsión,,Karkotuskiekko,Disque de Répulsion,Visszaverő Pajzs,Disco della Repulsione ,反発の円盤,방탄의 원반,Schijf van Afstoting,Frastøtelsens skive,Dysk Odpychania,Disco da Repulsão,,Disc al Repulsiei,Диск отторжения,Диск одбијања,İtme Diski -Dragonskin Bracers,TAG_ARTIBOOSTARMOR,,,,Dračí nátepníky,Drageskindsarmbøjler,Drachenhaut-Armschutz,,Brakbendo el Drakhaŭto,Brazaletes de piel de Dragón,,Lohikäärmeennahkarannesuojat,Brassards en peau de Dragon,Sárkánybőr Karkötők,Bracciali in Pelle di Drago ,竜皮の小手,용가죽 팔찌,Drakenhuidbescherming,Dragehud-bindinger,Karwasze ze Smoczej Skóry,Braçadeiras de Pele de Dragão,,Brățări din Piele de Dragon,Наручи драконьей кожи,Наруквице од змајеве коже,Ejderha Derisi Bilezikler -Krater of Might,TAG_ARTIBOOSTMANA,,,,Kalich síly,Kraftens bæger,Kelch der Macht,,Kratero de Potenco,Crátera de Poder,,Mahtikrateeri,Cratère de Pouvoir,Hatalom Kráterje,Calice della Forza,魔力の盃,힘의 향로,Beker van Macht,Krater av makt,Czara mocy,Cálice do Poder,,Pocal al Puterii,Кубок могущества,Чаша силе,Kudret Krateri -Flechette,TAG_ARTIPOISONBAG,,,,Střelka,,,,Flakono,,,,Fléchette,Nyílhegy,Fiaschetta ,フレシェット,플레셰트,,,Flaszka,,,Flacon,Флешетта,Бочица,Flechette -Poison Cloud Flechette,TAG_ARTIPOISONBAG1,,,,Otrávená střelka,Flechette (giftig sky),Flechette (Giftwolke),,Venennub-Flakono,Flechette de Nube Venenosa,,Myrkkypilviflechette,Fléchette - Nuage Toxique,Méregfelhő hegy,Fiaschetta Velenosa,毒ガス フレシェット,독구름 플레셰트,Flechette (giftige wolk),Giftsky-flechette,Flaszka Trującej Chmury,Flechette de Nuvem Venenosa,,Flacon cu Otravă,Флешетта ядовитого облака,Бочица отровног облака,Zehirli Bulut Flechette -Timebomb Flechette,TAG_ARTIPOISONBAG2,,,,Časovaná střelka,Flechette (tidsbombe),Flechette (Zeitbombe),,Horloĝbomb-Flakono ,Bomba de Tiempo Flechette,,Aikapommiflechette,Fléchette - Bombe a Retardement,Időbomba hegy,Fiaschetta a Tempo ,時限爆弾フレシェット,시한폭탄 플레셰트,Flechette (tijdbom),Tidsbombe Flechette,Flaszka-Bomba Zegarowa,Flechette Bomba-Relógio,,Bombă cu Ceas,Флешетта часовой бомбы,Бочица временске бомбе,Saatli bomba Flechette -Grenade Flechette,TAG_ARTIPOISONBAG3,,,,Granátová střelka,Flechette (granat),Flechettre (Granate),,Grenad-Flakono,Granada Flechette,,Kranaattiflechette,Fléchette - Grenade,Robbanó hegy,Fiaschetta da Lancio,グレネードフレシェット,폭발성 플레셰트,Flechette (granaat),Granat Flechette,Flaszka-Granat,Flechette Granada,,Flacon-Grenadă,Гранатная флешетта ,Бочица граната,El Bombası Flechette -Mystic Ambit Incant,TAG_ARTIHEALINGRADIUS,,,,Tajemný čár koljdoucí,,,,Sorĉo de Mistika Sfero,Encantamiento de Ámbito Místico,,Mystisen piirin loitsu,Incantation Mystique,Misztikus Mágialista,Incantamento Mistico ,魅知国の秘法,신비 영역의 주문,,,Inkantancja Mistycznego Kręgu,Encantamento Místico,,Pergament Mistic,Мистический зачарованный свиток,Чаролија магичног јединства,Mistik Ambit Büyüsü -Icon of the Defender,TAG_ARTIDEFENDER,,,,Obráncova ikona,Ikon af forsvareren,Ikone des Verteidigers,,Ikono de la Defendanto,Icono del Defensor,Ícono del Defensor,Puolustajan ikoni,Icône du Défenseur,Védelmező Ikonja,Emblema del Difensore ,守護者の像,수호의 성상,,Forsvarerens ikon,Ikona Obrońcy,Ícone do Defensor,,Imaginea Apărătorului,Символ защитника,Симбол браниоца,Savunucunun Simgesi -Porkalator,TAG_ARTIPORK,,,,Vepřovitel,,Porkalator,,Porkigilo,Porcinador,,Sikaannuttaja,Porcificateur,Ártányátok,Porchificatore,ポークレイター,돈육기,,,Schabowator,Porquificador,,Porcolator,Свиновизатор,Свињатор,Porkalator -Boots of Speed,TAG_ARTISPEED,,,,Běhuté boty,Støvler af hastighed,Turbo-Stiefel,,Botoj de Rapideco,Botas de Velocidad,,Ripeyssaappaat,Bottes de Célérité,Sebesség Cipői,Stivali della Fretta,素早さの靴,속도의 부츠,Snelheidslaarzen,Støvler av fart,Buty Szybkości,Botas da Rapidez,,Bocancii Vitezei,Сапоги-скороходы,Брзинске чизме,Hız Çizmeleri -Dark Servant,TAG_ARTISUMMON,,,,Temný služebník,Mørk tjener,Dunkler Diener,,Malluma Servanto,Servidor Oscuro,,Pimeä palvelija,Serviteur Noir,Árny Szolga,Servo Oscuro,闇の従者,어둠의 하인,Donkere Dienaar,Mørk tjener,Mroczny Sługa,Servo Negro,,Servitor Întunecat,Тёмный слуга,Мрачни слуга,Karanlık Hizmetkar -Banishment Device,TAG_ARTITELEPORTOTHER,,,,Vyhošťovač,Forvisningsanordning,Verbannungsgerät,,Forpelilo,Dispositivo de Destierro,,Häivytyskoje,Outil de Banissement,Számüzető Szerkentyű,Congegno dell'Esilio,追放のデバイス,소멸 장치,Verbanningsapparaat,Forvisningsinnretning,Urządzenie Wygnania ,Dispositivo do Banimento,,Dispozitiv al Alungării,Механизм изгнания,Амблем прогањања,Sürgün Cihazı -Yorick's Skull,TAG_ARTIPUZZSKULL,,,,Jorikova lebka,Yoricks kranium,Yoricks Schädel,,Kranio de Yorick,Calavera de Yorick,Cráneo de Yorick,Yorickin kallo,Crâne de Yorick,Yorick Koponyája,Teschio di Yorick,ヨリックの髑髏,요릭의 두개골,Yorick's Schedel,Yoricks hodeskalle,Czaszka Yoricka,Crânio de Yorick,,Craniul lui Yorick,Череп Йорика,Јорикова лобања,Yorick'in Kafatası -Heart of D'Sparil,TAG_ARTIPUZZGEMBIG,,,,Srdce D'Sparila,D'Sparils hjerte,D'Sparils Herz,,Koro de D'Sparil,Corazón de D'Sparil,,D'Sparilin sydän,Cœur de D'Sparil,D'Sparil Szíve,Cuore di D'Sparil,デ'スパリルの心,드'스파릴의 심장,Hart van D'Sparil,D'Sparils hjerte,Serce D'Sparila,Coração de D'Sparil,,Inima lui D'Sparil,Сердце Д'Спарила,Д'Спарилово срце,D'Sparil'in Kalbi -Ruby Planet,TAG_ARTIPUZZGEMRED,,,,Rubínová planeta,Rubinplanet,Rubinplanet,,Rubena Planedo,Planeta Rubí,,Rubiiniplaneetta,Planète en rubis,Rubin Bolygó,Pianeta di Rubino,ルビーの宝石,루비 행성석,Robijnrode Planeet,Rubinplaneten,Rubinowa Planeta,Planeta Rubi,,Planetă din Rubin,Рубиновая планета,Планета рубина,Yakut Gezegeni -Emerald Planet (1),TAG_ARTIPUZZGEMGREEN1,,,,Smaragdová planeta (1),Smaragdplanet (1),Smaragdplanet (1),,Smeralda Planedo (1),Planeta Esmeralda (1),,Smaragdiplaneetta (1),Planète en émeraude (1),Smaragd Bolygó (1),Pianeta di Smeraldo (1),エメラルドの宝石1,에메랄드 행성석 (1),Smaragdgroene Planeet (1),Smaragdplaneten (1),Szmaragdowa Planeta (1),Planeta Esmeralda (1),,Planetă din Smarald (1),Изумрудная планета (1),Смарагдна планета (1),Zümrüt Gezegen (1) -Emerald Planet (2),TAG_ARTIPUZZGEMGREEN2,,,,Smaragdová planeta (2),Smaragdplanet (2),Smaragdplanet (2),,Smeralda Planedo (2),Planeta Esmeralda (2),,Smaragdiplaneetta (2),Planète en émeraude (2),Smaragd Bolygó (2),Pianeta di Smeraldo (2),エメラルドの宝石2,에메랄드 행성석 (2),Smaragdgroene Planeet (2),Smaragdplaneten (2),Szmaragdowa Planeta (2),Planeta Esmeralda (2),,Planetă din Smarald (2),Изумрудная планета (2),Смарагдна планета (2),Zümrüt Gezegen (2) -Sapphire Planet (1),TAG_ARTIPUZZGEMBLUE1,,,,Safírová planeta (1),Safirplanet (1),Saphirplanet (1),,Safira Planedo (1),Planeta Zafiro (1),,Safiiriplaneetta (1),Planète en saphir (1),Zafír Bolygó (1),Pianeta di Zaffiro (1),サファイアの宝石1,사파이어 행성석 (1),Saffierblauwe Planeet (1),Safirplaneten (1),Szafirowa Planeta (1),Planeta Safira (1),,Planetă din Safir (1),Сапфировая планета (1),Сафирна планета (1),Safir Gezegen (1) -Sapphire Planet (2),TAG_ARTIPUZZGEMBLUE2,,,,Safírová planeta (2),Safirplanet (2),Saphirplanet (2),,Safira Planedo (2),Planeta Zafiro (2),,Safiiriplaneetta (2),Planète en saphir (2),Zafír Bolygó (2),Pianeta di Zaffiro (2),サファイアの宝石2,사파이어 행성석 (2),Saffierblauwe Planeet (2),Safirplaneten (2),Szafirowa Planeta (2),Planeta Safira (2),,Planetă din Safir (2),Сапфировая планета (2),Сафирна планета (2),Safir Gezegen (2) -Daemon Codex,TAG_ARTIPUZZBOOK1,,,,,,,,Kodekso de Demono,Códice del Demonio,,Daemon-koodeksi,Codex Démoniaque,Démon Kódex,Codice Demoniaco ,デーモンの写本,악마의 고문서,,,Demoniczny Kodeks,Códice Demoníaco,,Codexul Demonilor,Демонический кодекс,Демонски кодекс, -Liber Oscura,TAG_ARTIPUZZBOOK2,,,,,,,,Liber Oscura,Liber Oscura,,,,,,オスキュラ公文書,어둠의 자유서,,,Liber Oscura,,,Liber Obscura,Либер Оскура,Либер Оскура, -Flame Mask,TAG_ARTIPUZZSKULL2,,,,Plamenná maska,Flamme-maske,Flammenmaske,,Fajrmasko,Mascara de Llamas,Mascara de Flamas,Liekkinaamio,Masque de Flammes,Láng Maszk,Maschera delle Fiamme ,炎の仮面,화염의 가면,Vuurmasker,Flammemaske,Maska Płomieni,Máscara das Chamas,,Mască de Foc,Маска пламени,Маска пламена,Alev Maskesi -Glaive Seal,TAG_ARTIPUZZFWEAPON,,,,Glévská pečeť,Sværdsegl,Schwertsiegel,,Sigelo de Glavo,Sello de Espada,,Miekkasinetti,Sceau du Glaive,Pallos Pecsét,Sigillo del Brando,グレイブシール,밀폐된 칼날,Lanszegel,Glaive segl,Pieczęć Glewii,Selo do Gládio,,Sigiliu Spadă,Печать воителя,Војников печат,Glaive Mühür -Holy Relic,TAG_ARTIPUZZCWEAPON,,,,Svatá relikvie,Hellig relikvie,Heiliges Relikt,,Sankta Relikvo,Santa Reliquia,,Pyhä reliikki,Relique Sacrée,Szent Ereklye,Reliquia Sacra,聖遺物,신성한 유물,Heilige Relikwie,Hellig relikvie,Święta Relikwia,Relíquia Sagrada,,Relicvă Sfântă,Святая реликвия,Света реликвија,Kutsal Emanet -Sigil of the Magus,TAG_ARTIPUZZMWEAPON,,,,Mágovo sigilium,Magus' segl,Symbol des Magiers,,Sigelo de la Mago,Emblema del Mago,,Taikurin sinetti,Sceau du Mage,Mágus Pecsétje,Suggello del Magus,メイガスの印章,마거스의 인장,Sigaar van de Magus,Magusens segl,Emblemat Maga,Sígilo do Mago,,Sigiliul Magului,Печать Мага,Чаробњаков симбол,Büyücünün Sigil'i -Iron gear,TAG_ARTIPUZZGEAR1,,,,Železné kolečko,Tandhjul af jern,Eisenzahnrad,,Fera Dentrado,Engranaje de Hierro,,Rautaratas,Engrenage en Fer,Vas Felszerelés,Ingranaggio di Ferro,鉄の歯車,양철 톱니바퀴,IJzeren uitrusting,Jernutstyr,Żelazna Zębatka,Engrenagem de ferro,,Mecanism din fier,Железная шестерня,Гвожђени зупчаник,Demir dişli -Brass gear,TAG_ARTIPUZZGEAR2,,,,Mosazné kolečko,Tandhjul i messing,Messingzahnrad,,Latuna Dentrado,Engranaje de Bronce,,Messinkiratas,Engrenage en Bronze,Réz Felszerelés,Ingranaggio di Ottone ,真鍮のギア,황동 톱니바퀴,Messing uitrusting,Utstyr av messing,Mosiężna Zębatka,Engrenagem de latão,,Mecanism din alamă,Латунная шестерня,Месингани зупчаник,Pirinç dişli -Brass and iron gear,TAG_ARTIPUZZGEAR3,,,,Mosazno-železné kolečko,Tandhjul af messing og jern,Messing-und-Eisen-Zahnrad,,Latuna Fera Dentrado,Engranaje de Bronce y Hierro,,Messinki- ja rautaratas,Engrenage en Fer et Bronze,Vas és Réz Felszerelés,Ingranaggio di Ferro e Ottone ,鉄と真鍮のギア,황동과 양철 톱니바퀴,Messing en ijzeren uitrusting,Utstyr av messing og jern,Zębatka z mosiądzu i żelaza,Engrenagem de ferro e latão,,Mecanism din alamă și fier,Латунно-железная шестерня,Месинганoгвожђени зупчаник,Pirinç ve demir dişli -Silver and brass gear,TAG_ARTIPUZZGEAR4,,,,Stříbro-mosazné kolečko,Tandhjul af sølv og messing,Silber-und-Messing-Zahnrad,,Arĝenta Latuna Dentrado,Engranaje de Plata y Bronce,,Hopea- ja messinkiratas,Engrenage en Argent et Bronze,Ezüst és Réz Felszerelés,Ingranaggio di Ottone e Argento ,銀と真鍮のギア,은과 황동 톱니바퀴,Zilveren en messing uitrusting,Utstyr av sølv og messing,Zębatka ze srebra i mosiądzu,Engrenagem de prata e latão,,Mecanism din argint și alamă,Серебряно-латунная шестерня,Сребрномесигани зупчаник,Gümüş ve pirinç dişli -,,Obituaries,,,,,,,,,,,,,,,,,,,,,,,, -%o tasted an Afrit's fire.,OB_FIREDEMON,,,,%o okusil@[ao_cs] afritův oheň.,%o smagte en afrits ild.,%o spürte das Feuer des Afrits.,,%o gustis la fajron de Afrito.,%o probó el fuego de un Afrit.,,%o maistoi afritin tulta.,%o a goûté au feu d'un Afrit.,%o megkóstolta a Tűz Szellem parazsát.,%o ha assaggiato il fuoco di un Afrit. ,%o はアフリートの炎を味わった。,%o 은(는) 아프리트의 화염을 맛봤다.,%o proefde het vuur van een Afriet.,%o smakte en Afrits ild.,%o spróbował@[ao_pl] ognia Afrita.,%o provou o fogo de um Afrit.,,%o a gustat flacăra Demonului de Foc.,Игрок %o отведал огня африта.,%o је окуси@[ao_1_sr] Афритов огањ.,%o bir Afrit'in ateşini tattı. -%o was scalded by a Serpent.,OB_DEMON1,,,,%o byl@[ao_cs] upálen@[ao_cs] zlohadem.,%o blev skoldet af en slange.,%o wurde von der Chaos-Schlange gebissen.,,%o brogiĝis de Serpento.,%o fue escaldad@[ao_esp] por una Serpiente.,,%o joutui käärmeen kalttaamaksi.,%o a été brûlé@[e_fr] par un Serpent.,%o testét leforrázta egy Kígyó,%o è stato sciolto da un Serpente del Caos,%o はサーペントに火傷を負わされた。,%o 은(는) 서펜트에 데였다.,%o werd gebroeid door een Slang.,%o ble skåldet av en slange.,%o został@[ao_pl] poparzon@[adj_pl] przez Węża.,Uma Serpente escaldou %o.,,%o a fost opărit de un Șarpe.,Игрока %o спален змеем.,Играча %o је спалио Серпент.,%o bir yılan tarafından haşlandı. -%o was poisoned by a Serpent.,OB_DEMON2,,,,%o byl@[ao_cs] otráven@[ao_cs] zlohadem.,%o blev forgiftet af en slange.,%o wurde von der Chaos-Schlange verbrannt.,,%o veneniĝis de Serpento.,%o fue envenenad@[ao_esp] por una Serpiente.,,%o joutui käärmeen myrkyttämäksi.,%o a été empoisonné@[e_fr] par un Serpent.,%o vérébe mérget juttatott egy Kígyó,%o è stato avvelenato da un Serpente del Caos. ,%o はサーペントの毒にやられた。,%o 은(는) 독 서펜트에게 중독 당했다.,%o werd vergiftigd door een Slang.,%o ble forgiftet av en slange.,%o został@[ao_pl] zatrut@[adj_pl] przez Węża.,%o foi envenenad@[ao_ptb] por uma Serpente.,,%o a fost otrăvit de un Șarpe.,Игрока %o отравлен змеем.,Играча %o је отровао Серпент.,%o bir yılan tarafından zehirlendi. -%o was mashed by an Ettin.,OB_ETTIN,,,,%o byl@[ao_cs] umlácen@[ao_cs] skřetem.,%o blev moset af en Ettin.,%o wurde von dem Ettin zermatscht.,,%o frakasiĝis de Gigantaĉo.,%o fue hech@[ao_esp] puré por un Ettin.,%o quedó hech@[ao_esp] puré por un Ettin.,%o joutui ettinin muhentamaksi.,%o a été réduit@[e_fr] en purée par un Ettin.,%o csillagokat lát az Ettin miatt.,%o è stato schiacciato da un Ettin. ,%o はエティンに潰された。,%o 은(는) 에틴에게 철퇴를 맞았다.,%o werd gepureerd door een Ettin.,%o ble knust av en Ettin.,%o został@[ao_pl] stłuczon@[adj_pl] przez Ettina.,%o foi feito purê por um Ettin.,,%o a fost făcut piure de un Etin.,Игрока %o раздробил эттин.,Играча %o је смрскао Еттин.,%o bir Ettin tarafından ezildi. -%o was cut up by a Centaur.,OB_CENTAUR,,,,%o byl@[ao_cs] rozsekán@[ao_cs] kentaurem.,%o blev skåret op af en kentaur.,%o wurde von dem Zentaur aufgeschlitzt.,,%o distranĉiĝis de Centaŭro.,%o fue partid@[ao_esp] por un Centauro.,,%o joutui kentaurin pilkkomaksi.,%o a été tranché@[e_fr] par un Centaure.,%o fel lett vágva a Kentaur jóvoltából.,%o è stato affettato da un Centauro. ,%o はケンタウロスに切り刻まれた。,%o 은(는) 켄타우로스에 의해 절단됐다.,%o werd versneden door een Centaurus.,%o ble kuttet opp av en Kentaur.,%o został@[ao_pl] pocięt@[adj_pl] przez Centaura.,%o foi fatiad@[ao_ptb] por um Centauro.,,%o a fost tăiat deschis de un Centaur.,Игрока %o разрезал кентавр.,Играча %o је расекао Кентаур.,%o bir Kentaur tarafından kesildi. -%o was cut up by a Slaughtaur.,OB_SLAUGHTAURHIT,,,,%o byl@[ao_cs] rozsekán@[ao_cs] ničitaurem.,%o blev skåret op af en slagtaur.,%o wurde von dem Schlachtaur aufgeschlitzt.,,%o distranĉiĝis de Buĉataŭro.,%o fue partid@[ao_esp] por un Masacratauro.,,%o joutui teurastaurin pilkkomaksi.,%o a été tranché@[e_fr] par un Sangtaure.,%o nagyon felvágott és a Vágtaur is a játékost,%o è stato affettato da uno Sventrauro. ,%o はスロアタウルに切り刻まれた。,%o 은(는) 슬로터로스에 의해 심하게 절단됐다.,%o werd versneden door een Slachtaurus.,%o ble kuttet opp av en Slakttaur.,%o został@[ao_pl] pocięt@[adj_pl] Rzeziotaura.,%o foi fatiad@[ao_ptb] por um Chacinotauro.,,%o a fost tăiat deschis de un Centaur Violent.,Игрока %o разрезал убитавр.,Играча %o је расекао Кентаур старешина.,%o bir Katlaur tarafından kesildi. -%o was struck down by a Slaughtaur's fireball.,OB_SLAUGHTAUR,,,,%o byl@[ao_cs] zabit@[ao_cs] ničitaurovou ohnivou koulí.,%o blev slået ned af en slagtauras ildkugle.,%o wurde von dem Feuerball des Schlachtaurs niedergestreckt.,,%o subite mortiĝis de fajropilko de Buĉataŭro.,%o fue abatid@[ao_esp] por la bola de fuego de un Masacratauro.,,%o joutui teurastaurin tulipallon kaatamaksi.,%o a été touché@[e_fr] par une boule de feu de Sangtaure.,%o másodfokú égési sérüléseket szenvedett el a Vágtaur tűzgolyójától.,%o è stato abbattuto dalla palla di fuoco di uno Sventrauro. ,%o はスロアタウルの火玉に倒された。,%o 은(는) 슬로터로스의 마법구에 의해 피격당했다.,%o werd neergeslagen door een Slachtaurus' vuurbal.,%o ble truffet av en Slakttaurs ildkule.,%o został@[ao_pl] trafion@[adj_pl] przez kulę ognia Rzeziotaura.,%o foi abatid@[ao_ptb] pela bola de fogo de um Chacinotauro.,,"%o a fost răpus de mingea de foc a unui Centaur -Violent.",Игрока %o сбил огненным шаром убитавр.,Играча %o је огњеном куглом оборио Кентаур старешина.,%o bir Katlaur'un ateş topuyla vuruldu. -%o succumbed to a Bishop's dark power.,OB_BISHOP,,,,%o podlehl@[ao_cs] biskupově temné moci.,%o bukkede under for en biskops mørke kraft.,%o fiel der dunklen Macht des Bischofs zum Opfer.,,%o subfaliĝis de malluma potenco de Episkopo.,%o fue sucumbid@[ao_esp] al poder oscuro de un Obispo.,,%o lankesi piispan pimeään voimaan.,%o a succombé au pouvoir obscur d'un évèque.,%o megadta magát a Püspök sötét erejének,%o è stato sottomesso dalla magia oscura di un Vescovo. ,%o はビショップの闇の力に屈した。,%o 은(는) 비숍의 힘에 무릎을 꿇었다.,%o bezweek aan de donkere kracht van een Bisschop.,%o bukket under for en Biskops mørke kraft.,%o uległ@[ao_pl] mrocznej mocy Biskupa.,%o sucumbiu ao poder negro de um Bispo.,,%o a cedat puterii întunecate a Episcopului.,Игрок %o поддался чёрным силам Епископа.,%o је подлег@[ao_2_sr] Епископовим црним силама.,%o bir Piskopos'un karanlık gücüne yenik düştü. -%o was frozen solid by a Wendigo.,OB_ICEGUY,,,,%o byl@[ao_cs] zamrznut@[ao_cs] wendigem.,%o blev frosset fast af en wendigo.,%o wurde von dem Wendigo tiefgefroren.,,%o tute frostiĝis de Vendiko.,%o quedó congelad@[ao_esp] por un Wendigo.,,%o joutui wendigon läpikotaisin jäädyttämäksi.,%o a été gelé@[e_fr] par un Wendigo.,%o testét keményre fagyasztotta egy Wendigo,%o è stato congelato da un Wendigo. ,%o はウェンディゴによって固められた。,%o 은(는) 윈디고에 의해 단단하게 얼려졌다.,%o werd bevroren door een Wendigo.,%o ble frosset fast av en Wendigo.,%o został@[ao_pl] zamrożon@[adj_pl] przez Wendigo.,%o foi congelad@[ao_ptb] por um Wendigo.,,%o a fost făcut statuie de un Vendigo.,Игрока %o полностью заморозил вендиго.,Играча %o је потпуно замрзнуо Вендиго.,%o bir Wendigo tarafından kaskatı donduruldu. -%o was mauled by a Stalker.,OB_SERPENTHIT,,,,%o byl@[ao_cs] umlácen@[ao_cs] slídilem.,%o blev mast af en stalker.,%o wurde von dem Wasserjäger zerfleischt.,,%o vundegiĝis de Gvatanto.,%o fue triturad@[ao_esp] por un Acechador.,,%o joutui vaanijan raatelemaksi.,%o a été mutilé@[e_fr] par un Chasseur.,%o szét lett marcangolva egy Orhalász által.,%o è stato malmenato da un Cacciatore. ,%o はストーカーに引っ掻かれた。,%o 은(는) 스토커에게 발렸다.,%o werd verminkt door een Stalker.,%o ble maltraktert av en Stalker.,%o został@[ao_pl] poturbowan@[adj_pl] przez Prześladowcę.,%o foi mutilad@[ao_ptb] por um Caçador.,,%o a fost sfâșiat de un Vânător.,Игрок %o покусан преследователем.,Играча %o је растргао Вребач.,%o bir Stalker tarafından parçalandı. -%o was melted by a Stalker.,OB_SERPENT,,,,%o byl@[ao_cs] rozpuštěn@[ao_cs] slídilem.,%o blev smeltet af en stalker.,%o wurde von dem Wasserjäger geschmolzen.,,%o fandiĝis de Gvatanto.,%o fue derretid@[ao_esp] por un Acechador.,,%o joutui vaanijan sulattamaksi.,%o a été fondu@[e_fr] par un Chasseur.,%o csontjairól a húst leolvasztotta egy Orvhalász,%o è stato squagliato da un Cacciatore. ,%o はストーカーに溶かされた。,%o 은(는) 스토커에 의해 녹았다.,%o werd gesmolten door een Stalker.,%o ble smeltet av en Stalker.,%o został@[ao_pl] stopion@[adj_pl] przez Prześladowcę.,%o foi derretid@[ao_ptb] por um Caçador.,,%o a fost topit de un Vânător.,Игрока %o расплавил преследователь.,Играча %o је растопио Вребач.,%o bir Takipçi tarafından eritildi. -%o was charred by a Reiver.,OB_WRAITH,,,,%o byl@[ao_cs] zpopelněn@[ao_cs] přízrakem.,%o blev forkullet af en reiver.,%o wurde von dem Phantom verkohlt.,,%o brulegiĝis de Fantomo.,%o fue carbonizad@[ao_esp] por un Saqueador.,,%o joutui ryövärin hiiltämäksi.,%o a été carbonisé@[e_fr] par un Reiver.,%o testét egy Martalóc elszenesítette.,%o è stato carbonizzato da un Incursore. ,%o はレイバーに黒焦げにされた。,%o 은(는) 리버에 의해 그슬렸다.,%o werd verbrand door een Rover.,%o ble forkullet av en Reiver.,%o został@[ao_pl] zwęglon@[adj_pl] przez Rozbójnika.,%o foi carbonizad@[ao_ptb] por um Fantasma.,,%o a fost ceruit de un Pungaș.,Игрока %o обуглил грабитель.,Играча %o је угљенисао Вребач.,%o bir Hayalet tarafından yakıldı. -%o had %p life stolen by a Reiver.,OB_WRAITHHIT,,,,%o si nechal@[ao_cs] ukradnout život přízrakem.,%o fik sit liv stjålet af en reiver.,%o wurde das Leben von dem Phantom gestohlen.,,%o havis sian vivon ŝtelita de Fantomo.,%o fue robad@[ao_esp] de su vida por un Saqueador.,,Ryöväri riisti pelaajan %o hengen.,%o a perdu la vie face à un Reiver.,%o %p életét ellopta egy Martalóc,%o ha permesso che un Incursore prosciugasse la sua vita ,%o はレイバーに命を %p盗まれた。,%o 은(는) 리버에게 영혼을 도둑맞았다.,%o had @[zijn_haar_nl] leven gestolen door een Rover.,%o fikk %p liv stjålet av en Reiver.,"Życie %o zostało skradzione przez Rozbójnika. -",%o teve sua vida roubada por um Fantasma.,,Viața lui %o a fost furată de un Pungaș.,Жизнь игрока %o украл грабитель.,Играчу %o је живот украо Вребач.,%o bir Hayalet tarafından kurutuldu. -%o was incinerated by the Death Wyvern.,OB_DRAGON,,,,%o byl@[ao_cs] upálen@[ao_cs] smrtidrakem.,%o blev forbrændt af wyvern.,%o wurde von dem Todesdrachen verbrannt.,,%o cindriĝis de Mortviverno.,%o fue calcinad@[ao_esp] por el Guiverno de la Muerte.,,%o joutui kuolontraakin polttamaksi.,%o a été incinéré@[e_fr] par une vouivre de la mort.,%o testét porig égette egy Halálsárkány,%o è stato incenerito da una Viverna Mortale. ,%o はダークワイバーンに焼却された。,%o 은(는) 데스 와이번에 의해 분신 당했다.,%o werd verbrand door de Doodsdraak.,%o ble brent opp av en Døden Wyvern.,%o został@[ao_pl] spalon@[adj_pl] przez Wiwernę Śmierci.,%o foi incinerad@[ao_ptb] por uma Serpe da Morte,,%o a fost incinerat de Balaurul Morții.,Игрока %o кремировала виверна Смерти.,Играча %o је кремировао Змајак смрти.,"%o, Ölüm Wyvern tarafından yakıldı." -%o was swept from the board by Korax.,OB_KORAX,,,,%o byl@[ao_cs] odhozen@[ao_cs] ze šachovnice Koraxem.,%o blev fejet væk fra brættet af Korax.,%o wurde von Korax vom Feld gefegt.,,%o estis prenita el la tabulo de Korax.,%o fue barrid@[ao_esp] del tablero por Korax.,,%o pyyhkäistiin laudalta Kooraksen voimasta.,%o a été balayé@[e_fr] de l'échiquier par Korax.,%o el lett söpörve a tábláról Korax által.,%o è stato eliminato dalla scacchiera da Korax. ,%o は唯一神の怒りに触れた。,%o 은(는) 코락스의 체스판에서 사라졌다.,%o werd door Korax van het bord geveegd.,%o ble feid fra brettet av Korax.,%o został@[ao_pl] zmiecion@[adj_pl] z pokładu przez Koraxa.,%o foi eliminad@[ao_ptb] do tabuleiro por Korax.,,%o a fost măturat de pe drum de Korax.,Игрока %o скинул с доски Коракс.,Играча %o је с табле уклонио Коракс.,"%o, Korax tarafından tahtadan süpürüldü." -%o was slain by Zedek.,OB_FBOSS,,,,%o byl@[ao_cs] zabit@[ao_cs] Zedekem.,%o blev dræbt af Zedek.,%o wurde von Zedek hingemetzelt.,,%o mortigis de Zedeko.,%o recibió una puñalada de Zedek.,,%o joutui Sedekin tappamaksi.,%o a été pourfendu@[e_fr] par Zedek.,%o meghalt Zedek által.,%o è stato ammazzato da Zedek. ,%o はゼデクに討ち取られた。,%o 은(는) 제닥의 이름으로 쓰러졌다.,%o werd gedood door Zedek.,%o ble drept av Zedek.,%o został@[ao_pl] zgładzon@[adj_pl] przez Zedeka.,%o foi mort@[ao_ptb] por Zedek.,,%o a fost omorât de Zedek.,Игрока %o сразил Зедек.,Играча %o је оборио Коракс.,"%o, Zedek tarafından öldürüldü." -%o couldn't absorb Menelkir's Mana.,OB_MBOSS,,,,%o nemohl@[ao_cs] pojmout Menelkirovu manu.,%o kunne ikke absorbere Menelkirs Mana.,%o konnte Menelkirs Mana nicht verkraften.,,%o ne povis absorbi la Manaon de Menelkiro.,%o no pudo absorber el maná de Menelkir.,%o No pudo absorber el mana de Menelkir.,%o ei kyennyt ottamaan vastaan Menelkirin manaa.,%o n'aurait pu absorber le mana de Menelkir.,%o nem tudta elnyelni Menelkir manáját.,%o non è riuscito ad assorbire il mana di Menelkir. ,%o はメネルキルのマナを吸収できなかった。,%o 은(는) 메넬키어의 마나를 흡수하지 못했다.,%o kon Menelkir's mana niet absorberen.,%o kunne ikke absorbere Menelkirs Mana.,%o nie m@[irreg_4_pl] wchłonąć Many Menelkira.,%o não conseguiu absorver o Mana de Menelkir.,,%o nu a reușit să absoarbă mana lui Menelkir.,Игрок %o не смог поглотить ману Менелкира.,%o се није узмог@[ao_2_sr] носити с Менелкировом маном.,"%o, Menelkir'in Mana'sını ememedi." -%o was baptized by Traductus.,OB_CBOSS,,,,%o byl@[ao_cs] posvěcen@[ao_cs] Traduktem.,%o blev døbt af Traductus.,%o wurde von Traductus getauft.,,%o baptiĝis de Traduktuso.,%o fue bautizad@[ao_esp] por Traductus.,,%o joutui Traduktuksen kastamaksi.,%o a été baptisé@[e_fr] par Traductus.,%o meg lett keresztelve Traductus által.,%o è stato battezzato da Traductus. ,%o はトラダクタスの洗礼を受けた。,%o 은(는) 트라닥투스에게 침례를 당했다.,%o werd gedoopt door Traductus.,%o ble døpt av Traductus.,%o został@[ao_pl] ochrzczon@[adj_pl] przez Traductusa.,%o foi batizad@[ao_ptb] por Traductus.,,%o a fost botezat de Traductus.,Игрока %o крестил Традуктус.,Играча %o је крстио Традуктус.,"%o, Traductus tarafından vaftiz edildi." -%o had %p bones rolled by the Heresiarch.,OB_HERESIARCH,,,,%o si nechal@[ao_cs] rozmetat kosti Arcikacířem.,%o fik sine knogler rullet af Heresiark.,%os Knochen wurden vom Erzketzer gerollt.,,%o havis siajn ostojn rulis de la Ĉefherezulo.,%o tuvo sus huesos arrollados por el Heresiarca.,,Kerettiarkki jyräsi pelaajan %o luut.,%o s'est fait@[e_fr] rouler les os par l'Hérésiarche.,%o csontváza ki lett forgatva az Eretnek Vezér által.,Le ossa di %o sono state accartocciate dall'Eresiarca. ,%o はヘレシアークに骨を %p本 撒き散らされた。,%o 은(는) 헤러시아크에 의해 뼈와 살이 분리되었다.,%o @[zijn_haar_nl] botten werden opgerold door de Heresiarch.,%o fikk %p bein rullet av Heresiark.,Kości %o zostały porozrzucane przez Herezjarchę.,%o teve seus ossos moídos pelo Heresiarca.,,Oasele lui %o au fost făcute praf de către Ereziarh.,Ересиарх сыграл в кости игрока %o.,На играча %o су пале Јересијархове коцке.,"%o, Heresiark tarafından kutsandı." -%o was beaten to a pulp by %k's bare fists.,OB_MPFWEAPFIST,,,,%o byl@[ao_cs] umlácen@[ao_cs] k smrti holými pěstmi hráče %k.,%o blev slået til plukfisk af %ks bare næver.,%o wurde von %ks nackten Fäusten zu Hackfleisch verarbeitet.,,%o kaĉe draŝiĝis de la nudaj pugnoj de %k.,%o quedó molid@[ao_esp] a golpes por los puños limpios de %k.,,%k hakkasi %o paran muusiksi paljailla nyrkeillään.,%o à été tabassé@[e_fr] à mort par les poings de %k.,%o péppé lett verve %k ökleivel.,%k ha ridotto %o in poltiglia a mani nude.,%o は %k に素手でボコボコにされた。,%o 은(는) %k 의 맨손 타격으로 묵사발이 되었다.,%o werd tot pulp geslagen door %k's blote vuisten.,%o ble slått til mos av %ks bare never.,%o został@[ao_pl] zbit@[adj_pl] na miazgę przez gołe pięści %k.,%o foi espancad@[ao_ptb] até a morte pelos punhos nus de %k.,,%k l-a omorât în bătaie pe %o cu mâinile goale.,Игрок %o избит в мясо голыми руками игрока %k.,%o је пребијен@[adj_1_sr] на смрт голим рукама играч %k.,"%o, %k tarafından eşek sudan gelinceye kadar dövüldü." -%o got the axe from %k.,OB_MPFWEAPAXE,,,,%o dostal@[ao_cs] sekerou od hráče %k.,%o fik øksen af %k.,%o sah %ks Axt.,,%o ricevis la hakilon el %k.,%o recibió el hachazo de %k.,,%o sai pelaajan %k kirveestä.,%o s'est fait@[e_fr] hacher menu par %k.,%o megkapta %k baltáját.,%o ha preso un colpo d'ascia da %k.,%o は %k から斧を受けた。,%o 은(는) %k 의 티몬의 도끼를 어설프게 받아쳤다.,%o kreeg de bijl van %k.,%o fikk øksa av %k.,%o dostał@[ao_pl] z topora %k.,%o recebeu o machado de %k.,,%o a primit un topor de la %k.,Игрок %o словил топорик игрока %k.,%o је добио секиру од %k.,"%o, %k tarafından baltayla dövüldü." -%o had %p head caved in by %k's hammer.,OB_MPFWEAPHAMMERM,,,,%o dostal@[ao_cs] po hlavě kladivem hráče %k.,%o fik sit hoved udhulet af %ks hammer.,%o wurde der Kopf von %ks Hammer eingeschlagen.,,%p havis sian kapon enfalis de la martelo de %k.,%o tuvo su cabeza hundida por el martillo de %k.,,%k painoi vasarallaan %o paran pään kasaan.,%o s'est fait@[e_fr] éclater le crâne par le marteau de %k.,%o kapott egy üreges fejet %k Kalapácsa által.,La testa di %o è stata aperta in due dal martello di %k.,%o は %k のハンマーで頭に空洞を開けられた。,%k 은(는) 징벌의 망치로 %o 의 머리 위에 우물을 만들었다.,%o had @[zijn_haar_nl] kop ingestort met %k's hamer.,%o fikk %p hode knust av %ks hammer.,Głowa %o została zmiażdżona przez młot %k.,%o teve seu crânio afundado pelo martelo de %k.,%o teve seu crânio amolgado pelo martelo de %k.,%k i-a băgat capul lui %o în interior cu ciocanul.,Голова игрока %o была вдолблена в тело молотом игрока %k.,Играч %k је расцепао играчу %o главу.,"%o, %k tarafından dövüldü." -%o's soul was forged anew by %k's hammer.,OB_MPFWEAPHAMMERR,,,,%o@[psf1_cs] duše byla obrozena kladivem hráče %k.,%os sjæl blev smedet på ny af %ks hammer.,%os Seele wurde durch %ks Hammer erneuert.,,La animo de %o nove forĝiĝis de la martelo de %k.,El alma de %o fue forjada de nuevo por el martillo de %k.,,%k uudelleentakoi %o paran sielun vasarallaan.,%o a eu son âme reforgée par le marteau de %k.,%o lelke újra lett kovácsolva %k Kalapácsa által.,L'anima di %o è stata riforgiata dal martello di %k.,%o の魂は %k のハンマーで一から鍛え直された。,%o 의 영혼은 %k 의 징벌의 망치에 의해 철거되었다.,%o's ziel werd omgesmeed door %k's hamer.,%o's sjel ble smidd på nytt av %ks hammer.,Dusza %o została wykuta na nowo przez młot %k.,%o teve sua alma reforjada pelo martelo de %k.,,%k i-a făcut sufletul lui %o ca nou cu ciocanul.,Душа игрока %o была перекована молотом игрока %k.,Играч %k је прековао душу играча %o чекићем.,"%o, %k tarafından dövüldü." -%o was silenced by %k's mighty Quietus.,OB_MPFWEAPQUIETUS,,,,%o byl@[ao_cs] umlčen@[ao_cs] mocným Tišitelem hráče %k.,%o blev bragt til tavshed af %ks mægtige Forløser.,%o wurde durch %ks Erlöser befreit.,,%o slientiĝis de La Pova Kvietus' de %k.,%o fue silenciad@[ao_esp] por el poderoso Quietus de %k.,,%k vaiensi %o paran mahtavalla Quietuksellaan.,%o à été réduit@[e_fr] au silence par le pouvoir de %k et Quietus.,%o el lett némítva %k hatalmas Némusza által.,%o è stato zittito dal potente Quietus di %k.,%o は %k の強靭なクワイエタスで静かにされた。,%o 은(는) %k 의 종언의 검 덕에 침묵을 지킬 수 있었다.,%o werd tot zwijgen gebracht door %k's machtige Quietus.,%o ble brakt til taushet av %ks mektige Quietus.,%o został@[ao_pl] uciszon@[adj_pl] przez %k.,%o foi silenciad@[ao_ptb] pelo poderoso Quietus de %k.,,"%o a fost redus la tăcere de argumentul final al -lui %k.",Игрок %o утихомирен легендарным Последним доводом игрока %k.,%o је утишан@[adj_1_sr] од моћи Куиетуса играч %k.,"%o, %k tarafından susturuldu." -%o got a mace to the face from %k.,OB_MPCWEAPMACE,,,,%o dostal@[ao_cs] palcátem po hlavě od hráče %k.,%o fik en stridskølle i ansigtet af %k.,%o bekam %ks Streitkolben ins Gesicht.,,%o prenis klabon al la vizaĝon el %k.,%o consiguió un mazazo a la cara de parte de %k.,,%o sai pelaajan %k nuijasta naamaansa.,%o s'est fait@[e_fr] casser la figure par la masse de %k.,%o kapott egy buzogányt a fejébe %k által.,%o si è preso una mazzata in faccia da %k.,%o は自らの顔に %k のメイスを受けた。,%o 은(는) %k 의 철퇴를 맞은 뒤에야 철이 들었다.,%o kreeg een %k's gesel in @[zijn_haar_nl] gezicht.,%o ble slått i ansiktet av %k.,%o dostał@[ao_pl] buzdyganem %k w twarz.,%o levou com a maça de %k na cara.,,%o a primit un buzdugan în față de la %k.,Игрок %o получил по морде булавой игрока %k.,%o је доби@[ao_1_sr] буздован у фацу играч %k.,"%o, %k tarafından eşek sudan gelinceye kadar dövüldü." -%o was bitten by %k's serpent staff.,OB_MPCWEAPSTAFFM,,,,%o byl@[ao_cs] kousnut@[ao_cs] hadí holí hráče %k.,%o blev bidt af %ks slange-stav.,%o wurde von %ks Schlangenstab gebissen.,,%o mordiĝis de la serpentbastono de %k.,%o fue mordid@[ao_esp] por el bastón de la serpiente de %k.,,%k puri %o parkaa käärmesauvallaan.,%o s'est fait@[e_fr] mordre par le Bâton du Serpent %k.,%o meg lett harapva %k Kígyó Botja által.,%o è stato morso dalla Staffa del Serpente di %k.,%o は %k の蛇の杖に噛まれた。,%o 은(는) %k 의 뱀 지팡이에 의해 독살당했다.,%o werd gebeten door %k's slangenstaf.,%o ble bitt av %ks slangestav.,%o został@[ao_pl] ugryzion@[adj_pl] laską węży %k.,%o foi mordid@[ao_ptb] pelo Cetro da Serpente de %k.,,%o a fost mușcat de bastonul șarpe al lui %k.,Игрок %o искусан змеиным посохом игрока %k.,%o је угрижен@[adj_1_sr] змијским штапом играч %k.,"%o, %k tarafından zehirlendi." -%o choked on %k's serpent staff.,OB_MPCWEAPSTAFFR,,,,%o se zadusil@[ao_cs] hadí holí hráče %k.,%o blev kvalt af %ks slange stav.,%o verschluckte sich an %ks Schlangenstab.,,%o sufokis la serpentbastonon de %k.,%o se ahogó con el bastón de la serpiente de %k.,,%o tukehtui pelaajan %k käärmesauvaan.,%o s'est étranglé@[e_fr] sur le Bâton du Serpent de %k,%o megfulladt %k Kígyó Botja által.,%o è soffocato a causa della Staffa del Serpente di %k.,%o は %k の蛇の杖に息の根を止められた。,%o 은(는) %k 의 뱀 지팡이 때문에 숨을 쉬지 못했다.,%o stikte in %k's slangenstaf.,%o ble kvalt av %ks slangestav.,%o zakrztusił@[ao_pl] się laską węży %k.,%o se engasgou com o Cetro da Serpente de %k,,%o s-a sufocat pe bastonul șarpe al lui %k.,Игрок %o задушен змеиным посохом игрока %k.,%o је задављен@[adj_1_sr] змијским штапом играч %k.,"%o, %k tarafından kurutuldu." -%o was lit up by %k's flames.,OB_MPCWEAPFLAME,,,,%o vzplanul@[ao_cs] plameny hráče %k.,%o blev tændt af %ks flammer.,%o wurde von %ks Flammen erleuchtet.,,%o ekbruliĝis de la fajroj de %k.,%o fue encendid@[ao_esp] por las llamas de %k.,,%o syttyi pelaajan %k liekeistä.,%o s'est fait@[e_fr] allumer par %k.,%o fel lett gyújtva %k tűze által.,%o è stato illuminato dalle fiamme di %k.,%o は %k によって炎を灯された。,%o 은(는) %k 의 화염폭풍에 휩쓸렸다.,%o werd opgelicht door %k's vlammen.,%o ble opplyst av %ks flammer.,%o został@[ao_pl] oświetlon@[adj_pl] płomieniami %k.,%o foi incendiad@[ao_ptb] pelas chamas de %k.,,%o s-a aprins de la flăcările lui %k.,Игрок %o сгорел в огне игрока %k.,%o је осветљен@[adj_1_sr] пламеном играч %k.,"%o, %k tarafından aydınlatıldı." -%o was cleansed by %k's Wraithverge.,OB_MPCWEAPWRAITHVERGE,,,,%o byl@[ao_cs] očištěn@[ao_cs] Zjevitelem hráče %k.,%o blev renset af %ks Spirit Bringer.,%o wurde durch %ks Geisterbringer geläutert.,,%o puriĝis de la Fantomkruc' de %k.,%o fue limpiad@[ao_esp] por la vara fantasmal de %k.,,%k puhdisti pelaajan %o Haamusauvallaan.,%o a été purifié@[e_fr] par la Verge Phantasmale de %k.,%o meg lett tisztítva %k Bosszúbot által.,%o è stato purificato dalla Verga SconfinaSpettri di %k.,%o は %k のレイスバージによって浄化された。,%o 은(는) %k 의 사령의 지팡이에 의해 정화되었다.,%o werd gereinigd door %k's Schimroede.,%o ble renset av %ks Wraithverge.,%o został@[ao_pl] oczyszczon@[adj_pl] przez Widmoskraj %k.,%o foi purificad@[ao_ptb] pelo Cajado Fantasma de %k.,,%o a fost purificat de Toiagul Stafie al lui %k.,Игрок %o очищен жезлом духов игрока %k.,%o je прочишћен@[adj_1_sr] штапом утваре играч %k.,"%o, %k tarafından temizlendi." -%o took one too many sapphire beams from %k.,OB_MPMWEAPWAND,,,,%o koupil@[ao_cs] přespříliš safírových střel od hráče %k.,%o tog en safirstråle for meget fra %k.,%o bekam zu viele Saphierstrahlen von %k ab.,,%o recivis unu tro da safira radio de %k.,%o recibió demasiados rayos de zafiro de %k.,,%o otti vastaan yhden liikaa pelaajan %k safiirisäteistä.,%o s'est pris@[e_fr] un rayon saphirique en trop de la part de %k.,%o túl sok zafír sugarat kapott %k-tól/től.,%o si è buscato un raggio di zaffiro di troppo da %k.,%o は %k から多量のサファイアビームを受け取った。,%o 은(는) %k 의 사파이어 빛을 너무 많이 째려봤다.,%o kreeg een saffierstraal teveel van %k.,%o fikk en safirstråle for mye fra %k.,%o wzi@[irreg_2_pl] o jeden szafirowy promień od %k za dużo.,%o levou muitos raios de safira de %k.,,%o a primit o rază în plus de la safirul lui %k.,Игрок %o схватил слишком много сапфировых зарядов от игрока %k.,%o је узе@[ao_1_sr] превише сафирских зракова играч %k.,"%o, %k tarafından dönüştürüldü." -%o was turned into a frosty fellow by %k.,OB_MPMWEAPFROST,,,,%o byl@[ao_cs] zchlazen@[ao_cs] hráčem %k.,%o blev forvandlet til en frostklar fyr af %k.,%o wurde von %k schockgefrostet.,,%o farigiĝis frostulon de %k.,%o fue convertid@[ao_esp] en un helado por %k.,%o fue convertid@[ao_esp] en una persona helada por %k.,%k muutti %o paran pakkasveikoksi.,%o s'est fait@[e_fr] transformer en glaçon par %k.,%o jégbaráttá alakult %k által.,%o è stato trasformato in un simpatico pupazzo di neve da %k.,%o は %k によって冷ややかな輩になった。,%o 은(는) %k 의 얼음 파편에 의해 눈사람이 되었다.,%o werd ijskoud veranderd door %k.,%o ble forvandlet til en iskald fyr av %k.,%o został@[ao_pl] zmienion@[adj_pl] w mroźnego koleżkę przez %k.,%o foi transformad@[ao_ptb] em picolé por %k.,,%o a fost transformat într-un amic de gheață de %k.,Игрок %o обращается в ледяную скульптуру игроком %k.,%o је претворен@[adj_1_sr] у лед играч %k.,"%o, %k tarafından soğuk bir adama dönüştürüldü." -%o received a shocking revelation from %k.,OB_MPMWEAPLIGHTNING,,,,%o zjistil@[ao_cs] šokující odhalení hráče %k.,%o fik en chokerende åbenbaring af %k.,%o musste eine schockierende Enthüllung von %k verkraften.,,%o recivis teruran revelacion de %k.,%o recibió una revelación impactante de %k.,,%o sai sähköistävän ilmestyksen pelaajalta %k.,%o a reçu un sacré coup de jus de la part de %k.,%o kapott egy sokkoló relevációt %k-tól/től,"%o ha ricevuto una notizia ""elettrizzante"" da %k.",%o は %k から衝撃的な啓示を受けた。,%o 은(는) %k 의 번갯불 덕에 충격적인 계시를 받았다.,%o kreeg een schokkende openbaring van %k.,%o fikk en sjokkerende åpenbaring fra %k.,%o otrzymał@[ao_pl] szokujące objawienie od %k.,%o recebeu uma revelação chocante de %k.,,%o a avut parte de o revelație șocantă de la %k.,Игрок %o откровенно шокирован игроком %k.,%o је прими@[ao_1_sr] шокантно откриће играч %k.,"%o, %k tarafından şoka uğratıldı." -%o was wiped off the face of the universe by %k's Bloodscourge.,OB_MPMWEAPBLOODSCOURGE,,,,%o byl@[ao_cs] vymýcen@[ao_cs] ze jsoucna vesmíru Krvehromem hráče %k.,%o blev udslettet af universets overflade af %ks Blodgisel.,%o wurde von %ks Blutgeißel aus dem Universum verbannt.,,%o disdetruiĝis el la universo de la Sangskurĝ' de %k.,%o fue borrad@[ao_esp] de la faz del universo por la plaga sangrienta de %k.,,%k pyyhki %o paran maailmankaikkeudesta.,%o s'est fait@[e_fr] effacer de l'univers par le Fléau Sanglant de %k.,%o ki lett törölve az univerzumból %k Vérkorbácsának köszönhetően.,%o è stato cancellato dalla faccia dell'universo dal Flagello di Sangue di %k.,%o は %k の天罰によりこの世から一掃された。,%o 은(는) %k 이(가) 피의 재앙을 씀으로써 전혀 존재하지 않는 존재가 되어버렸다.,%o werd van het gezicht van het universum geveegd door %k's Bloedgesel.,%o ble utslettet fra universets overflate av %ks Bloodscourge.,Twarz %o została zmieciona z wszechświata przez Krwioplagę %k.,%o foi varrid@[ao_ptb] da face do universo pelo Flagelo de Sangue de %k.,,"%o a fost ras de pe fața universului de -Flagelul Sângeros al lui %k.",Игрок %o стёрт с лица вселенной Кровавым бичом игрока %k.,%o је обрисан@[adj_1_sr] са лица свемира од Крвавог зла играч %k.,"%o, %k tarafından evrenden silindi." -,,Strife,,,,,,,,,,,,,,,,,,,,,,,, -,,Pickups,,,,,,,,,,,,,,,,,,,,,,,, -You picked up the Metal Armor.,TXT_METALARMOR,,,You picked up the Metal Armour.,Sebral@[ao_cs] jsi kovové brnění.,Du samlede metalrustningen op.,Du hast die Metallrüstung genommen.,Πήρες τη Μεταληκή Πανοπλία.,Vi trovis metalan armaĵon.,Encuentras una armadura de metal.,Hallaste una armadura de metal.,Poimit metallihaarniskan.,Vous avez pris l'armure de métal.,Felvetted a Fémpáncélt.,Hai raccolto l'Armatura di Metallo.,メタルアーマー 入手。,강철 갑옷을 획득했다.,Je hebt het metalen harnas opgepakt.,Du plukket opp metallrustningen.,Podniosł@[irreg_3_pl] Metalowy Pancerz.,Você pegou a Armadura de Metal.,Apanhaste a Armadura de Metal.,Ai ridicat Armura din Metal.,Получена металлическая броня.,Покупио си метални оклоп.,Metal Zırhı aldın. -You picked up the Leather Armor.,TXT_LEATHERARMOR,,,You picked up the Leather Armour.,Sebral@[ao_cs] jsi kožené brnění.,Du samlede læderrustningen op.,Du hast die Lederrüstung genommen.,Πήρες τη Δερμάτινη Πανοπλία.,Vi trovis ledan armaĵon.,Encuentras una armadura de cuero.,Hallaste una armadura de cuero.,Poimit nahkasuojuksen.,Vous avez pris l'armure de cuir.,Felvetted a Bőrpáncélt.,Hai raccolto l'Armatura di Cuoio.,レザーアーマー 入手。,가죽 갑옷을 획득했다.,Je hebt het leren harnas opgepakt.,Du plukket opp lærrustningen.,Podniosł@[irreg_3_pl] Skórzany Pancerz.,Você pegou a Armadura de Couro.,Apanhaste a Armadura de Couro.,Ai ridicat Armura din Piele.,Получена кожаная броня.,Покупио си кожни оклоп.,Deri Zırhı aldın. -You picked up the Med patch.,TXT_MEDPATCH,,,,Sebral@[ao_cs] jsi obvaz.,Du samlede Med patch op.,Du hast den Verband genommen.,,Vi trovis kuracbendojn.,Encuentras unas tiritas.,Hallaste unas curitas.,Poimit sidekääreen.,Vous avez pris le pansement.,Felvetted a Ragtapaszt.,Hai raccolto le Bende.,医薬パッチ 入手。,의료 붕대를 획득했다.,Je hebt de med-patch opgepakt.,Du plukket opp en Med-patch.,Podniosł@[irreg_3_pl] Bandaż.,Você pegou a compressa médica.,Apanhaste a compressa médica.,Ai ridicat Trusa de Prim-Ajutor.,Получен медицинский бинт.,Покупио си прву помоћ.,Sağlık bandını aldın. -You picked up the Medical kit.,TXT_MEDICALKIT,,,,Sebral@[ao_cs] jsi lékárničku.,Du samlede Medicinsk kit op.,Du hast den Verbandskasten genommen.,,Vi trovis sukurkeston.,Encuentras un botiquín.,Hallaste un botiquín.,Poimit lääkintälaukun.,Vous avez pris le kit médical.,Felvetted az Elsősegélycsomagot.,Hai raccolto il Kit di Pronto Soccorso.,医療用キット 入手。,구급 키트를 획득했다.,Je hebt de medicijndoos opgepakt.,Du plukket opp det medisinske settet.,Podniosł@[irreg_3_pl] Apteczkę.,Você pegou o Kit Médico.,Apanhaste o Kit Médico.,Ai ridicat Kitul de Prim-Ajutor.,Получена аптечка.,Покупио си медицински комплет,Tıbbi kiti aldın. -You picked up the Surgery Kit.,TXT_SURGERYKIT,,,,Sebral@[ao_cs] jsi chirurgickou soupravu.,Du samlede kirurgisættet op.,Du hast den Erste-Hilfe-Kasten genommen.,,Vi trovis kirurgian keston.,Encuentras un kit quirúrgico.,Hallaste un kit quirúrgico.,Poimit kirurgilaukun.,Vous avez pris le kit de chirurgie.,Felvetted az Orvosi Műtőfelszerelést.,Hai raccolto il Kit Chirurgico.,手術キット 入手。,수술 키트를 획득했다.,Je hebt het chirurgenpakket opgepakt.,Du plukket opp Kirurgi-settet.,Podniosł@[irreg_3_pl] Zestaw Chirurga.,Você pegou o Kit de Cirurgia.,Apanhaste o Kit de Cirugia.,Ai ridicat Kitul pentru Operații.,Получен медкомплект.,Покупио си хируршки комплет,Ameliyat setini aldın. -You picked up the map.,TXT_STRIFEMAP,,,,Sebral@[ao_cs] jsi mapu.,Du samlede kortet op.,Du hast die Karte genommen.,Πήρες το χάρτη.,Vi trovis la mapon.,Encuentras el mapa.,Hallaste el mapa.,Poimit kartan.,Vous avez pris la carte,Felvetted a térképet.,Hai raccolto la Mappa.,マップ 取得。,지도를 획득했다.,Je hebt de kaart opgepakt.,Du plukket opp kartet.,Podniosł@[irreg_3_pl] mapę.,Você pegou o mapa.,Apanhaste o mapa.,Ai ridicat harta.,Получена карта.,Покупио си мапу.,Haritayı aldın. -You picked up the ring.,TXT_BELDINSRING,,,,Sebral@[ao_cs] jsi prsten.,Du samlede ringen op.,Du hast den Ring genommen.,Πήρες το Δακτύλιο.,Vi prenis la ringon.,Tienes el anillo.,,Poimit sormuksen.,Vous avez pris l'anneau.,Felvetted a Gyűrűt.,Hai raccolto l'Anello.,指輪 取得。,반지를 획득했다.,Je hebt de ring opgepakt.,Du plukket opp ringen.,Podniosł@[irreg_3_pl] pierścień.,Você pegou o anel.,Apanhaste o anel.,Ai ridicat inelul.,Получено кольцо.,Покупио си прстен.,Yüzüğü aldın. -You picked up the Offering Chalice.,TXT_OFFERINGCHALICE,,,,Sebral@[ao_cs] jsi obětní kalich.,Du samlede offerkalken op.,Du hast den Opferkelch genommen.,,Vi prenis la oferdonan kalikon.,Tienes el cáliz de ofrenda.,,Poimit uhrimaljan.,Vous avez pris le Calice d'obole.,Felvetted az Áldozati Kelyhet.,Hai raccolto il Calice delle Offerte.,寄贈された聖杯 取得。,번제 성배를 훔쳤다.,Je hebt de Offerbeker opgepakt.,Du plukket opp offerbegeret.,Podniosł@[irreg_3_pl] Kielich Ofiarny.,Você pegou o Cálice de Oferenda.,Apanhaste o Cálice de Oferenda.,Ai ridicat Potirul pentru Ofrande.,Получена чаша для подношений.,Покупио си Жртвени пехар.,Adak Kadehini aldın. -You picked up the ear.,TXT_EAR,,,,Sebral@[ao_cs] jsi ucho.,Du samlede øret op.,Du hast das Ohr gernommen.,Πήρες το αυτί.,Vi prenis la orelon.,Tienes la oreja.,,Poimit korvan.,Vous avez pris l'oreille.,Felvetted a Fület.,Hai raccolto l'Orecchio.,耳 取得。,잘린 귀를 주웠다.,Je hebt het oor opgepakt.,Du plukket opp øret.,Podniosł@[irreg_3_pl] ucho.,Você pegou a orelha.,Apanhaste a orelha.,Ai ridicat urechea.,Получено ухо.,Покупио си уво.,Kulağı aldın. -You picked up the broken power coupling.,TXT_BROKENCOUPLING,,,,Sebral@[ao_cs] jsi rozbitou spojku.,Du samlede den ødelagte strømkobling op.,Du hast den defekten Stromabnehmer genommen.,,Vi havas la rompitan energian kuplilon.,Tienes el acoplador de energía roto.,,Poimit rikkinäisen virtaliittimen.,Vous avez pris le coupleur énergétique cassé.,Felvetted a hibás tápcsatlakozót.,Hai raccolto la Coppia Energetica Rotta.,壊れたパワーカップリング 取得。,망가진 동력선 장치를 획득했다.,Je hebt de kapotte stroomkoppeling opgepakt.,Du plukket opp den ødelagte kraftkoblingen.,Podniosł@[irreg_3_pl] zepsute obwody zasilające.,Você pegou o acoplador de energia quebrado.,Apanhaste o acoplador de energia partido.,Ai ridicat cuplajul defect de curent.,Получена повреждённая муфта.,Покупио си неисправну спојницу напајања.,Kırık güç bağlantısını aldın. -You picked up the Shadow armor.,TXT_SHADOWARMOR,,,You picked up the Shadow armour.,Sebral@[ao_cs] jsi krycí brnění.,Du samlede skyggerustningen op.,Du hast die Schattenrüstung genommen.,,Vi trovis ombran armaĵon.,Encuentras una armadura de sombra.,Hallaste una armadura de sombra.,Poimit varjohaarniskan.,Vous avez pris l'armure de l'ombre.,Felvetted az Árnyékpáncélt.,Hai raccolto l'Armatura Ombra.,シャドウアーマー 入手。,그림자 갑옷을 획득했다.,Je hebt het schaduwharnas opgepakt.,Du plukket opp Skygge-rustningen.,Podniosł@[irreg_3_pl] Cienisty Pancerz.,Você pegou a armadura das sombras.,Apanhaste a armadura das sombras.,Ai ridicat Armura Umbrei.,Получена теневая броня.,Покупио си оклоп сенки.,Gölge zırhını aldın. -You picked up the Environmental Suit.,TXT_ENVSUIT,,,,Sebral@[ao_cs] jsi ochranný oděv,Du samlede miljødragten op.,Du hast den Schutzanzug genommen.,,Vi trovis medi-ŝirman veston,Encuentras un traje de protección ambiental.,Hallaste un traje de protección ambiental.,Poimit ympäristösuojapuvun.,Vous avez pris la combinaison hazmat.,Felvetted a Védőruhát.,Hai raccolto la Tuta Ambientale.,耐環境スーツ 入手。,환경 방호복을 획득했다.,Je hebt het beschermende pak opgepakt.,Du plukket opp miljødrakten.,Podniosł@[irreg_3_pl] Skafander Ochronny.,Você pegou o Traje de Proteção.,Apanhaste o Fato Protetor.,Ai ridicat Costumul de Protecție.,Получен защитный костюм.,Покупио си заштитно одело.,Çevresel Kıyafeti aldın. -You picked up the Guard Uniform.,TXT_GUARDUNIFORM,,,,Sebral@[ao_cs] jsi hlídačovu uniformu.,Du samlede vagtuniformen op.,Du hast die Wächteruniform genommen.,,Vi prenis la uniformon de gardisto.,Tienes el uniforme de un guardia.,,Poimit vartijan univormun.,Vous avez pris l'Uniforme du garde.,Felvetted az Őr Egyenruhát.,Hai raccolto l'Uniforme da Guardia.,守衛の制服 入手。,경비 전투복을 획득했다.,Je hebt het wachtersuniform opgepakt.,Du plukket opp vaktuniformen.,Podniosł@[irreg_3_pl] Mundur Strażnika.,Você pegou o Uniforme de Guarda.,Apanhaste o Uniforme de Guarda.,Ai ridicat Uniforma de Paznic.,Получена униформа стражника.,Покупио си стражарску униформу,Muhafız Üniformasını aldın. -You picked up the Officer's Uniform.,TXT_OFFICERSUNIFORM,,,,Sebral@[ao_cs] jsi důstojníkovu uniformu.,Du samlede officersuniformen op.,Du hast die Offiziersuniform genommen.,,Vi trovis oficiran uniformon.,Encuentras un uniforme de oficial.,Hallaste un uniforme de oficial.,Poimit upseerin univormun.,Vous avez pris l'Uniforme de l'officier.,Felvetted a Tiszti Egyenruhát.,Hai raccolto l'Uniforme da Ufficiale.,士官の制服 入手。,장교 전투복을 획득했다.,Je hebt het officiersuniform opgepakt.,Du plukket opp offisersuniformen.,Podniosł@[irreg_3_pl] Mundur Oficera.,Você pegou o Uniforme de Oficial.,Apanhaste o Uniforme de Oficial.,Ai ridicat Uniforma Ofițerului.,Получена униформа офицера.,Покупио си официрску униформу,Subay üniformasını aldın. -You picked up the flame thrower parts.,TXT_FTHROWERPARTS,,,,Sebral@[ao_cs] jsi součásti plamenometu.,Du samlede flammekasterdele op.,Du hast die Flammenwerferteile genommen.,,Vi havas la partojn de flamĵetilo.,Tienes las partes de un lanzallamas.,,Poimit liekinheittimen osat.,Vous avez pris les pièces du lance-flames.,Felvetted a lángszóró részeit.,Hai raccolto delle parti di Lanciafiamme.,火炎放射器の部品 入手。,화염방사기 부품을 획득했다.,Je hebt de vlammenwerperonderdelen opgepakt.,Du plukket opp delene til flammekasteren.,Podniosł@[irreg_3_pl] części miotacza ognia.,Você pegou as partes do lança-chamas.,Apanhaste as peças do lança-chamas.,Ai ridicat bucățile aruncătorului de flăcări.,Получены детали для огнемёта.,Покупио си делове за бацач пламена.,Alev silahının parçalarını aldın. -You picked up the report.,TXT_REPORT,,,,Sebral@[ao_cs] jsi hlášení.,Du samlede rapporten op.,Du hast den Report genommen.,,Vi prenis la raporton.,Recogiste el reporte.,,Poimit raportin.,Vous avez pris le compte-rendu.,Felvetted a jelentést.,Hai raccolto il rapporto.,報告書 取得。,보고서를 획득했다.,Je hebt het rapport opgepakt.,Du plukket opp rapporten.,Podniosł@[irreg_3_pl] raport.,Você pegou o relatório.,Apanhaste o relatório.,Ai ridicat raportul.,Получен отчёт.,Покупио си извештај.,Raporu aldın. -You picked up the info.,TXT_INFO,,,,Sebral@[ao_cs] jsi informace.,Du samlede oplysningerne op.,Du hast die Info genommen.,Πήρες της πληροφορίες,Vi prenis la informon.,Recogiste la información.,,Poimit tiedot.,Vous avez pris l'info.,Felvetted az információt.,Hai raccolto delle Informazioni.,情報 取得。,정보를 획득했다.,Je hebt de informatie opgepakt.,Du plukket opp informasjonen.,Podniosł@[irreg_3_pl] informacje.,Você pegou a informação.,Apanhaste a informação.,Ai recepționat informația.,Получена сводка.,Покупио си инфо.,Bilgiyi aldın. -You picked up the Targeter.,TXT_TARGETER,,,,Sebral@[ao_cs] jsi zaměřovač.,Du samlede targeter op.,Du hast die Zielhilfe genommen.,Πήρες τον Στοχευτή.,Vi prenis la Celilon.,Recogiste el apuntador.,,Poimit tähtäinlaitteen.,Vous avez pris le cibleur.,Felvetted a Célzóberendezést.,Hai raccolto il Puntatore.,照準器 入手。,조준기를 획득했다.,Je hebt het Richter opgepakt.,Du plukket opp Targeteren.,Podniosł@[irreg_3_pl] Namierzacz.,Você pegou a Mira.,Apanhaste a Mira.,Ai ridicat Țintitorul.,Получен целеуказатель.,Покупио си нишанитеља.,Hedefleyiciyi aldın. -You picked up the Communicator.,TXT_COMMUNICATOR,,,,Sebral@[ao_cs] jsi komunikátor.,Du samlede kommunikatoren op.,Du hast den Kommunikator genommen.,,Vi prenis la Komunikilon.,Recogiste el comunicador.,,Poimit viestintälaitteen.,Vous avez pris le Communicateur,Felvetted a Kommunikátort,Hai raccolto il Comunicatore.,コミュニケーター 取得。,연락장치를 획득했다.,Je hebt de Communicator opgepakt.,Du plukket opp kommunikatoren.,Podniosł@[irreg_3_pl] Komunikator.,Você pegou o Comunicador.,Apanhaste o Comunicador.,Ai ridicat Comunicatorul.,Получен передатчик.,Покупио си комуникатор.,İletişim cihazını aldın. -You picked up the coin.,TXT_COIN,,,,Sebral@[ao_cs] jsi minci.,Du samlede mønten op.,Du hast die Münze genommen.,Πήρες το κέρμα.,Vi trovis moneron.,Encuentras una moneda.,,Poimit kolikon.,Vous avez pris la pièce.,Felvetted az érmét.,Hai raccolto la Moneta.,コイン 入手。,동전을 주웠다.,Je hebt de munt opgepakt.,Du plukket opp mynten.,Podniosł@[irreg_3_pl] monetę.,Você pegou a moeda.,Apanhaste a moeda.,Ai ridicat moneda.,Получена монета.,Покупио си новчић.,Parayı aldın. -You picked up %d gold.,TXT_XGOLD,,,,Sebral@[ao_cs] jsi %d zlatých.,Du samlede %d guld op.,Du hast %d Gold genommen.,,Vi trovis %d da oro.,Encuentras %d monedas de oro.,,Poimit kultaa %d arvosta.,Vous avez pris %d pièces.,Felvettél %d aranyat.,Hai raccolto %d pezzi d'oro.,%d ゴールド 入手。,골드 %d 개를 획득했다.,Je hebt %d goud opgepakt.,Du plukket opp %d gull.,Podniosł@[irreg_3_pl] %d monet.,Você pegou %d moedas de ouro.,Apanhaste %d moedas de ouro.,Ai ridicat %g bucăți de aur.,Получено %d золотых.,Покупио си %d златника.,%d altın aldın. -You picked up the Teleporter Beacon.,TXT_BEACON,,,,Sebral@[ao_cs] jsi teleportační maják.,Du samlede Teleporter Beacon op.,Du hast das Teleportersignal genommen.,,Vi prenis la Formovilan Signalilon.,Recogiste un faro de teletransportación.,,Poimit kaukosiirrinmajakan.,Vous avez pris la balise de téléporteur.,Felvetted a Teleport jelzőt.,Hai raccolto il Radiofaro per Teletrasporto.,テレポータービーコン 取得。,텔레포터 비콘을 획득했다.,Je hebt de teleporterbaken opgepakt.,Du plukket opp Teleporter-signalet.,Podniosł@[irreg_3_pl] Nadajnik Teleportera.,Você pegou o Sinalizador de Teletransporte.,Apanhaste o Sinalizador de Teletransporte.,Ai ridicat Luminatorul pentru Teleportor.,Получен телепортационный маяк.,Покупио си одашиљач за телепортовање.,Işınlayıcı İşaretini aldın. -You picked up the Degnin Ore.,TXT_DEGNINORE,,,,Sebral@[ao_cs] jsi degninskou rudu.,Du samlede Degnin Ore op.,Du hast das Degnin-Erz genommen.,,Vi prenis la Degninan Ercon.,Recogiste el Mineral Degnin.,,Poimit Degnin-malmia.,Vous avez pris le minerai de Degnin.,Felvetted a Degnin Ércet.,Hai raccolto il Minerale Degnin.,デグニン鉱石 取得。,데그닌 광석을 획득했다.,Je hebt het Degnin-erts opgepakt.,Du plukket opp Degnin-malmen.,Podniosł@[irreg_3_pl] Rudę Degninu.,Você pegou o Minério Degnin.,Apanhaste o Minério Degnin.,Ai ridicat minereul de Degnin.,Получена дегнинская руда.,Покупио си Дегнинску руду.,Degnin Cevherini aldın. -You picked up the scanner.,TXT_SCANNER,,,,Sebral@[ao_cs] jsi skener.,Du samlede scanneren op.,Du hast den Scanner genommen.,Πήρες το σαρωτή.,Vi prenis la skanilon.,Recogiste el escáner.,,Poimit skannerin.,Vous avez pris l'analyseur.,Felvetted a szkennert.,Hai raccolto lo Scanner.,スキャナー 入手。,탐지기를 획득했다.,Je hebt de scanner opgepakt.,Du plukket opp skanneren.,Podniosł@[irreg_3_pl] skaner.,Você pegou o scanner.,Apanhaste o scanner.,Ai ridicat scannerul.,Получен сканер.,Покупио си скенер.,Tarayıcıyı aldın. +această ușă",Для открытия нужен жёлтый ключ,Треба вам жути кључ да би отворили ова врата,Du behöver en gul nyckel för att öppna den här dörren,Bu kapıyı açmak için sarı bir anahtara ihtiyacınız var +,,Actor tag names,,,,,,,,,,,,,,,,,,,,,,,,, +Chicken,FN_CHICKEN,,,,Slepice,Kylling,Huhn,Κότα,Koko,Pollo,,Kana,Poulet,Csirke,Pollo,鶏,닭,Kip,Kylling,Kurczak,Galinha,,Găină,Цыплёнок,Кокошка,Kyckling,Tavuk +Weredragon,FN_BEAST,Wordplay: werewolf,,,Vlkodrak,Varedrage,Werdrache,Θηρίο,Drakfantomo,Hombre dragón,,Ihmislohikäärme,Dragon-garou,Vérsárkány,Drago Mannaro,ウェア ドラゴン,웨어드래곤,Weerdraak,Vardrage,Smokołak,Homem-dragão,,Vârcodragon,Дракон-оборотень,Змајодлак,Vardrake,Kurt ejderha +Sabreclaw,FN_CLINK,Wordplay: sabre-tooth,,,Šavlozub,Sabelklo,Säbelklaue,,Sabrokrifo,Garras de sable,,Sapelikynsi,Sabregriffe,Szablyakarom,Lamartiglio,サーベルクロー,세이버클로,Sabelklauw,Sabreklo,Szabloszpon,Unhas-de-sabre,,Gheară de Sabie,Саблекоготь,Тигар,Sabelklo,Kılıçpençe +D'Sparil,FN_DSPARIL,,,,,,,,,,,,,,,デ'スパリル,드'스파릴,,,,,,,Д'Спарил,Д'Спарил,, +Gargoyle,FN_HERETICIMP,,,,Chrlič,,,,Gargojlo,Gárgola,,Gargoili,Gargouille,Vízköpő,,ガーゴイル,가고일,,,Gargulec,Gárgula,,Garguie,Горгулья,Камена утвара,, +Ironlich,FN_IRONLICH,,,,Železný kostěj,Jern lig,Eiserne Leiche,,Ferliĉo,Liche de hierro,,Rautakalmo,Liche de Fer,Ezüst lich,Lich di Ferro,アイアンリッチ,아이언 리치,IJzeren Lijk,Jernlich,Żelazny Lisz,Lich de Ferro,,Cadavru de Fier,Железный лич,Челични лич,Järnlich,Demir Ceset +Undead Warrior,FN_BONEKNIGHT,,,,Nemrtvý válečník,Udøde Kriger,Untoter Krieger,Αθάνατος Πολεμιστής,Malmortinta Batalisto,Guerrero no muerto,,Epäkuollut soturi,Guerrier Mort-Vivant,Élőhalott harcos,Guerriero Non Morto,アンデット兵,언데드 전사,Ondode Krijger,Udød kriger,Nieumarły wojownik,Guerreiro Morto-vivo,,Războinic Nemort,Воин-нежить,Немртви ратник,Odöd krigare,Ölümsüz Savaşçı +Maulotaur,FN_MINOTAUR,,,,Minotaurus,Maulotaurus,Minotaurus,Μινόταυρος,Bategtaŭro,Mazotauro,,Maulotauri,Massetaure,,Maulotauro,マウロタウロス,몰로타우어,Maulotaurus,Maulotaur,Młototaur,Marretauro,,,Избитавр,Минотаур,Maulotaurus,Maulotor +Golem,FN_MUMMY,,,,Golém,,,,Golemo,Gólem,,,,Gólem,,ゴーレム,골렘,,,,,,,Голем,Голем,, +Nitrogolem,FN_MUMMYLEADER,,,,Střelgolém,,,,Azotgolemo,Gólem de ázoe,,,,Nitrógólem,,ニトロゴーレム,니트로 골렘,,,,,,,Нитроголем,Нитро голем,, +Ophidian,FN_SNAKE,,,,Šupinatec,,,,Ofidio,Ofidio,,Käärmeolio,Ophidien,Ofidián,,オフィディアン,오피디안,Ophidiaan,,Wężowaty,Ofídio,,Ofidian,Офидиан,Змија,, +Wizard,FN_WIZARD,,,,Čaroděj,Troldmand,Zauberer,Μάγος,Sorĉisto,Mago,Hechicero,Velho,Magicien,Mágus,Mago,ウィザード,마법사,Tovenaar,Trollmann,Czarownik,Mago,,Vrăjitor,Колдун,Чаробњак,Trollkarl,Sihirbaz +Wand Crystals,AMMO_GOLDWAND,,,,Zlaté krystaly,Stav krystaller,Elfenstabkristalle,,Sorĉbastono-Kristaloj,Cristales para vara,,Sauvakristalleja,Cristaux,Pálca kristályok,Cristalli per la bacchetta,ワンド クリスタル,지팡이 결정,Toverstafkristallen,Tryllestavkrystaller,Kryształy do Różdżki,Cristais para o Cetro,,Cristale pentru Toiag,Кристалл эльфийского жезла,Кристали за штап,Stavkristaller,Değnek Kristalleri +Ethereal Arrows,AMMO_CROSSBOW,,,,Éterické šípy,Æteriske pile,Ätherische Pfeile,,Eteraj Sagoj,Flechas etéreas,,Eetterinuolia,Carreaux,Éteri nyilak,Frecce eteree,イセリアルの矢,유체 화살,Etherische Pijlen,Eteriske piler,Eteryczne Strzały,Flechas Etéreas,,Săgeți Celeste,Эфирные стрелы,Етеричне стреле,Eteriska pilar,Eterik Oklar +Claw Orbs,AMMO_BLASTER,,,,Pazouří střely,Kugler med kløer,Klauenbälle,,Kriforboj,Orbes de garra,,Kynsikehriä,Orbes,Karom golyók,Sfere di artigli,クロー オーブ,발톱 보주,Klauwbollen,Klo-kuler,Kule do Pazura,Orbes para Garra,,Globuri pentru Gheară,Когтевые шары,Канџаста сфера,Klor bollar,Pençe Küreleri +Mace Spheres,AMMO_MACE,,,,Žezlometné koule,Kugler til stridskølle,Energiebälle,,Klabsferoj,Esferas de maza,,Nuijakuulia,Sphères,Buzogány gömbök,Sfere per la mazza,メイス スフィア,철퇴 포탄,Strijdknotsen,Ildsted-kuler,Kule do Buzdyganu,Esferas para Clava,,Sfere pentru Buzdugan,Сферы булавы,Сфере за буздован,Eldstötsfärer,Ateş Küreleri +Hellstaff Runes,AMMO_SKULLROD,,,,Peklopalné runy,Helvedestav-runer,Höllenrutenrunen,,Inferbastono-Runoj,Runas de Vara Infernal,,Hornansauvan riimuja,Runes,Pokolbot rúnák,Rune infernali,ヘルスタッフ ルーン,룬 조각,Hellestafrunen,Helvetesstav-runer,Runy do Piekielnego Kostura,Runas Infernais,,Rune pentru Bastonul Infernal,Руны посоха ада,Пуне за паклени штап,Runor för helvetesstång,Cehennem Asası Rünleri +Flame Orbs,AMMO_PHOENIXROD,,,,Plamenné náboje,Flammekugler,Flammenkugeln,,Flamorboj,Orbes de llama,,Liekkikehriä,Orbes de Feu,Tűzgolyók,Sfere di fuoco,フレイム オーブ,화염 구슬,Vuurballen,Flammekuler,Kule Ognia,Orbes de Chamas,,Globuri de Foc,Пламенные шары,Ватрена сфера,Flamkärnor,Alev Küreleri +Staff,TAG_STAFF,,,,Hole,Stav,Stab,Ράβδος,Bastono,Bastón,,Sauva,Bâton,Bot,Staffa,杖,지팡이,Staf,Stav,Kostur,Bastão,,Baston,Посох,Штап,Stav,Çubuk +Elven Wand,TAG_GOLDWAND,,,,Elfí hůlka,Elverstav,Elfenstab,,Elfa Sorĉbastono,Vara de Elfo,,Haltiasauva,Baguette Elfique,Elf pálca,Scettro Elfico,エルフのワンド,엘프 지팡이,Elvenstokje,Alvestav,Elfia Różdżka,Cetro Élfico,,Toiag,Эльфийский жезл,Вилењачки штапић,Elfenstav,Elf Asası +,,Obituaries,,,,,,,,,,,,,,,,,,,,,,,,, +%o was pecked to death.,OB_CHICKEN,,,,%o byl@[ao_cs] uklován@[ao_cs] k smrti.,%o blev hakket ihjel.,%o wurde zu Tode gepickt.,,%o estis bekita ĝis morto.,A %o l@[ao_esp] han picoteado a muerte.,A %o l@[ao_esp] picotearon a muerte.,%o nokittiin kuoliaaksi.,%o a été picoré@[e_fr] a mort.,%o halálra lett csípve.,%o è stato beccato a morte.,%o はくちばしで突かれ死んだ。,%o 은(는) 쪽팔리게 쪼여 죽었다.,%o werd doodgepikt.,%o ble hakket i hjel.,%o został@[ao_pl] zadzioban@[adj_pl] na śmierć.,%o foi bicad@[ao_ptb] até a morte.,%o foi picad@[ao_ptb] até a morte.,%o a fost ciocănit până la moarte.,Игрок %o заклёван до смерти.,%o је искљуцан@[adj_1_sr] до смрти.,%o blev hackad till döds.,%o gagalanarak öldürüldü. +%o was charred by a weredragon.,OB_BEAST,,,,%o byl@[ao_cs] spálen@[ao_cs] vlkodrakem.,%o blev forkullet af en varedrage.,%o wurde von dem Werdrachen verschmort.,,%o brulegiĝis de drakfantomo.,A %o l@[ao_esp] ha carbonizado un hombre dragón.,A %o l@[ao_esp] carbonizó un hombre dragón.,%o joutui ihmislohikäärmeen kärventämäksi.,%o a été carbonisé@[e_fr] par un dragon-garou.,%o szénné égett egy Vérsárkány által.,%o è stato carbonizzato da una bestia.,%o はウェアドラゴンに黒焦げにされた。,%o 은(는) 웨어드래곤에 의해 검게 탔다.,%o werd verbrand door een weerdraak.,%o ble forkullet av en vardrage.,%o został@[ao_pl] zwęglon@[adj_pl] przez smokołaka.,%o foi carbonizad@[ao_ptb] por um homem-dragão.,,%o a fost ceruit de un vârcodragon.,Игрок %o обуглен драконом-оборотнем.,%o је реш печен@[adj_1_sr] од стране замјодлака.,%o blev förkolnad av en vardrake.,%o bir kurt ejderha tarafından yakıldı. +%o was slashed by a sabreclaw.,OB_CLINK,,,,%o byl@[ao_cs] rozsápán@[ao_cs] šavlozubem.,%o blev skåret op af en sabreklo.,%o wurde von der Säbelklaue zerschlitzt.,,%o tranĉegiĝis de sabrokrifo.,A %o l@[ao_esp] ha cortado un garras de sable.,A %o l@[ao_esp] cortó un garras de sable.,%o joutui sapelikynnen sivaltamaksi.,%o s'est fait découper par un sabregriffe.,%o meg lett vágva egy Szablyakarom által.,%o è stato squarciato da un lapillo.,%o はサーベルクローに切り裂かれた。,%o 은(는) 세이버클로에게 잘렸다.,%o werd door een sabelklauw gesneden.,%o ble kuttet av en sabelklo.,%o został@[ao_pl] posiekan@[adj_pl] przez szabloszpona.,Um Unhas-de-sabre cortou %o.,,%o a fost tăiat de o gheară de sabie.,Игрока %o нарезал саблекоготь.,Играча %o је исекао тигар.,%o blev huggen av en sabelklo.,%o bir kılıç pençe tarafından kesildi. +%o was scalded by D'Sparil's serpent.,OB_DSPARIL1,,,,%o byl@[ao_cs] zpopelněn@[ao_cs] ořem D'Sparila.,%o blev skoldet af D'Sparils slange.,%o wurde von D'Sparils Schlange verbrüht.,,%o varmegiĝis de la serpento de D'Sparil.,A %o l@[ao_esp] ha calcinado la serpiente de D'Sparil.,A %o l@[ao_esp] calcinó la serpiente de D'Sparil.,%o joutui D'Sparilin käärmeen kalttaamaksi.,%o a été ébouillanté@[e_fr] par un serpent de D'Sparil.,%o le lett forrázva D'Sparil Kígyója által.,%o è stato bruciato dal serpente di D'Sparil.,%o はデ'スパリルのサーペントに火傷を負わされた。,%o 은(는) 드'스파릴의 서펜트에 데였다.,%o werd gebroeid door de slang van D'Sparil.,%o ble skåldet av D'Sparils slange.,%o został@[ao_pl] poparzon@[adj_pl] przez węża D'Sparila.,%o foi escaldad@[ao_ptb] pela serpente de D'Sparil.,,%o a fost opărit de șarpele lui D'Sparil.,Игрока %o обжёг змей Д'Спарила.,Играча %o је опекао Д'Спарилова змија.,%o blev skållad av D'Sparils orm.,"%o, D'Sparil'in yılanı tarafından haşlandı." +%o was chewed up by D'Sparil's serpent.,OB_DSPARIL1HIT,,,,%o byl@[ao_cs] rozkousán@[ao_cs] ořem D'Sparila.,%o blev tygget op af D'Sparils slange.,%o wurde von D'Sparils Schlange verspeist.,,%o maĉegiĝis de la serpento de D'Sparil.,A %o l@[ao_esp] ha engullido la serpiente de D'Sparil.,A %o l@[ao_esp] tragó la serpiente de D'Sparil.,%o joutui D'Sparilin käärmeen pureksimaksi.,%o a été dévoré@[e_fr] par un serpent de D'Sparil.,%o meg lett rágva D'Sparil Kigyója által.,%o è stato masticato dal serpente di D'Sparil.,%o はデ'スパリルのサーペントに噛み砕かれた。,%o 은(는) 드'스파릴의 서펜트에게 씹혔다.,%o werd door de slang van D'Sparil opgekauwd.,%o ble tygd opp av D'Sparils slange.,%o został@[ao_pl] przeżut@[adj_pl] przez węża D'Sparila.,%o foi mastigad@[ao_ptb] pela serpente de D'Sparil.,,%o a fost mestecat de șarpele lui D'Sparil.,Игрока %o пожрал змей Д'Спарила.,%o је сажвакан@[adj_1_sr] од стране Д'Спарилове змије.,%o blev tuggad av D'Sparils orm.,"%o, D'Sparil'in yılanı tarafından çiğnendi." +%o was no match for D'Sparil.,OB_DSPARIL2,,,,%o nebyl@[ao_cs] pro D'Sparila žádná výzva.,%o kunne ikke klare D'Sparil.,%o war kein Gegner für D'Sparil.,,%o ne estis rivalo por D'Sparil. ,%o no era rival para D'Sparil.,,%o ei mahtanut mitään D'Sparilille.,%o n'a pas pu égaler D'Sparil.,%o nem volt méltó ellenfél D'Sparil számára.,%o non era all'altezza di D'Sparil.,%o はデ'スパリルには全く歯が立たなかった。,%o 은(는) 드'스파릴에겐 상대가 되지 못했다.,%o was geen partij voor D'Sparil.,%o var ingen match for D'Sparil.,%o nie miał@[ao_pl] szans z D'Sparilem.,%o não foi páreo para D'Sparil.,%o não foi desafio para D'Sparil.,%o n-a fost nici pe departe pe măsura lui D'Sparil.,Игрок %o был не ровня Д'Спарилу.,%o није ни до колена Д'Спарилу.,%o var ingen match för D'Sparil.,"%o, D'Sparil'in dengi değildi." +%o was smacked down by D'Sparil.,OB_DSPARIL2HIT,,,,%o byl@[ao_cs] sražen@[ao_cs] D'Sparilem.,%o blev slået ned af D'Sparil.,%o wurde von D'Sparil zerklatscht.,,%o frapiĝis de D'Sparil.,A %o l@[ao_esp] ha humillado D'Sparil.,A %o l@[ao_esp] humilló D'Sparil.,%o joutui D'Sparilin löylyttämäksi.,%o a été battu@[e_fr] a plate couture par D'Sparil.,%o a földre lett csapva D'Sparil által.,%o è stato abbattuto da D'Sparil.,%o はデ'スパリルに打ち負かされた。,%o 은(는) 드'스파릴의 맹격에 쓰러졌다.,%o werd neergeslagen door D'Sparil.,%o ble slått ned av D'Sparil.,%o został@[ao_pl] roztrzaskan@[adj_pl] przez D'Sparila,%o foi mort@[ao_ptb] por D'Sparil.,,%o a fost pus la pământ de D'Sparil.,Игрок %o сбит с ног Д'Спарилом.,%o је претучен@[adj_1_sr] од стране Д'Спарила.,%o blev nedslagen av D'Sparil.,"%o, D'Sparil tarafından yere serildi." +%o was scarred by a gargoyle.,OB_HERETICIMP,,,,%o byl@[ao_cs] upálen@[ao_cs] chrličem.,%o blev mærket af en gargoyle.,%o wurde von einem Gargoyle zerkratzt.,,%o ĉikartiĝis de gargojlo.,"A %o l@[ao_esp] ha marcado, y no de cicatrices, una gárgola.","A %o l@[ao_esp] marcó, y no de cicatrices, una gárgola.",%o joutui gargoilin arpeuttamaksi.,%o a été effrayé@[e_fr] par une gargouille.,%o meg lett sebesítve egy vízköpő által.,%o è stato terrorizzato da un imp.,%o はガーゴイルに傷を負わされた。,%o 은(는) 가고일에 의해 다쳤다.,%o was getekend door een gargoyle.,%o ble arret av en gargoyle.,%o został@[ao_pl] zadrapan@[adj_pl] przez gargulca,%o foi cicatrizad@[ao_ptb] por uma gárgula.,,%o a fost cicatrizat de o garguie.,Игрока %o изуродовала горгулья.,%o је ожиљкан@[adj_1_sr] од стране камене утваре.,%o blev ärrad av en gargoyle.,%o bir gargoyle tarafından yaralandı. +%o was hacked by a gargoyle.,OB_HERETICIMPHIT,,,,%o byl@[ao_cs] rozsekán@[ao_cs] chrličem.,%o blev hakket af en gargoyle.,%o wurde von einem Gargoyle zerhackt.,,%o hakiĝis de gargojlo.,A %o l@[ao_esp] ha arañado una gárgola.,A %o l@[ao_esp] arañó una gárgola.,%o joutui gargoilin pilkkomaksi.,%o a été mis@[e_fr] en pièces par une gargouille.,%o fel lett vágva egy vízköpő által.,%o è stato eliminato da un imp.,%o はガーゴイルに切り刻まれた。,%o 은(는) 가고일에 의해 베였다.,%o werd gehackt door een gargoyle.,%o ble hakket av en gargoyle.,%o został@[ao_pl] pocięt@[adj_pl] przez gargulca,%o foi mutilad@[ao_ptb] por uma gárgula.,,%o a fost tăiat de o garguie.,Игрока %o покалечила горгулья.,Играча %o је исекла камена утвара.,%o blev hackad av en gargoyle.,%o bir gargoyle tarafından kesildi. +%o was devastated by an ironlich.,OB_IRONLICH,,,,%o byl@[ao_cs] zničen@[ao_cs] železným kostějem.,%o blev ødelagt af en jern lig.,%o wurde von der Eisernen Leiche zerstört.,,%o ruiniĝis de ferliĉo.,A %o l@[ao_esp] ha devastado un liche de hierro.,A %o l@[ao_esp] devastó un liche de hierro.,%o joutui rautakalmon hävittämäksi.,%o a été dévasté@[e_fr] par une Liche de Fer.,%o elpusztult egy ezüst lich miatt.,%o è stato devastato da un ironlich.,%o はアイアンリッチに吹き飛ばされた。,%o 은(는) 아이언 리치에게 붕괴 당했다.,%o werd verwoest door een ijzeren lijk.,%o ble knust av en jernlich.,%o został@[ao_pl] zdewastowan@[adj_pl] przez żelaznego lisza,%o foi devastad@[ao_ptb] por um lich de ferro.,,%o a fost devastat de un cadavru de fier.,Игрока %o растоптал железный лич.,%o је уништен@[adj_1_sr] од стране челичног лича.,%o blev förödd av en järnlich,%o demir bir ceset tarafından harap edildi. +%o got up-close and personal with an ironlich.,OB_IRONLICHHIT,,,,%o se dostal@[ao_cs] moc blízko k železnému kostěji.,%o kom helt tæt på en jern lig.,%o kam der Eisernen Leiche zu nahe.,,%o havis proksiman kaj desonan rekonton kun ferliĉo.,%o ha tenido un encuentro cercano y personal con un liche de hierro.,%o tuvo un encuentro cercano y personal con un liche de hierro.,%o meni lähelle rautakalmoa.,%o a fait ami@[e_fr]-ami@[e_fr] avec une Liche de Fer.,%o közel került és személyes volt egy ezüst lichhel szemben.,%o è andato troppo vicino a un ironlich.,%o はアイアンリッチと密接に関わった。,%o 은(는) 사적인 이유로 아이언 리치에게 다가왔다.,%o werd door een ijzeren lijk onheus bejegend.,%o fikk nærkontakt med en jernlich.,%o był@[ao_pl] blisko i na osobności z żelaznym liszem,%o chegou muito perto de um lich de ferro.,,"%o s-a apropiat prea mult de un +cadavru de fier.",Игрок %o близко и лимно узнал железного лича.,%o се лично приближи@[ao_1_sr] челичном личу.,%o kom nära och personligt med en järnlich.,%o demir bir cesede çok yaklaştı. +%o was axed by an undead warrior.,OB_BONEKNIGHT,,,,%o dostal@[ao_cs] sekyrou od nemrtvého válečníka.,%o blev øksehugget af en udød kriger.,%o wurde von dem Untoten Krieger mit der Axt bearbeitet.,,%o hakiliĝis de malmortinta batalisto.,%o ha recibido un hachazo de un guerrero no muerto.,%o recibió un hachazo de un guerrero no muerto.,%o joutui epäkuolleen soturin kirvestämäksi.,%o s'est pris@[e_fr] la hâche d'un guerrier mort-vivant.,%o baltát kapott egy Élőhalott Harcostól.,%o è stato accettato da un guerriero non morto .,%o はアンデッド兵の斧でやられた。,%o 은(는) 언데드 전사에게 도끼질 당했다.,%o werd doorkliefd door een ondode krijger.,%o ble hugget av en udød kriger.,%o został@[ao_pl] rozłupany siekierą przez nieumarłego wojownika,%o foi decepad@[ao_ptb] por um guerreiro morto-vivo.,%o foi decapitad@[ao_ptb] por um guerreiro morto-vivo.,%o a primit un topor de la un războinic nemort.,Игрока %o зарубил воин-нежить.,%o је исечен@[adj_1_sr] од стане немртвог ратника.,%o blev yxad av en odöd krigare.,%o bir ölümsüz savaşçı tarafından baltalandı. +%o was slain by an undead warrior.,OB_BONEKNIGHTHIT,,,,%o byl@[ao_cs] zabit@[ao_cs] nemrtvým válečníkem.,%o blev dræbt af en udød kriger.,%o wurde von dem Untoten Krieger hingemetzelt.,,%o estis mortigita de malmortinta batalisto.,A %o l@[ao_esp] ha descuartizado un guerrero no muerto.,A %o l@[ao_esp] descuartizó un guerrero no muerto.,%o joutui epäkuolleen soturin tappamaksi.,%o s'est fait pourfendre par un guerrier mort-vivant.,%o meghalt egy Élőhalott Harcos által.,%o è stato ucciso da un guerriero non morto. ,%o はアンデッド兵の手で葬られた。,%o 은(는) 언데드 전사에게 처단당했다.,%o werd gedood door een ondode krijger.,%o ble drept av en levende død kriger.,%o został@[ao_pl] zgładzon@[adj_pl] przez nieumarłego wojownika,%o foi picotad@[ao_ptb] por um guerreiro morto-vivo.,,%o a fost omorât de un războinic nemort.,Игрока %o сразил воин-нежить.,Играча %o је убио немртви ратник.,%o blev dödad av en odödlig krigare.,%o bir ölümsüz savaşçı tarafından katledildi. +%o was blasted into cinders by a Maulotaur.,OB_MINOTAUR,,,,%o byl@[ao_cs] rozmetán@[ao_cs] na popel Minotaurem.,%o blev sprængt i aske af en Maulotaurus.,%o wurde von dem Minotaurus in Asche verwandelt.,,%o eksplodiĝis en cindrojn de Bategtaŭro.,A %o l@[ao_esp] ha volado en cenizas un Mazotauro.,A %o l@[ao_esp] voló en cenizas un Mazotauro.,%o tuhottiin tuusan nuuskaksi maulotaurin toimesta.,%o s'est fait@[e_fr] incinérer par un Massetaure.,%o darabokra robbant egy Maulotaurusz által.,%o è stato incenerito da un Maulotauro. ,%o はマウロタウロスに燃やされ炭化した。,%o 은(는) 몰로타우어에게 잿더미가 되도록 파괴당했다.,%o werd door een Maulotaurus tot sintels geblazen.,%o ble sprengt til aske av en Maulotaur.,%o został@[ao_pl] obrócon@[adj_pl] w popiół przez Młototaura,%o foi incinerad@[ao_ptb] por um Marretauro,,%o a fost făcut cenușă de un Maulotaur.,Игрока %o разнёс на угольки Избитавр.,%o је испуцан@[adj_1_sr] у пепео од стране минотаура.,%o blev sprängd till aska av en maulotaurus.,%o bir Maulotor tarafından kül haline getirildi. +%o was pulped by a Maulotaur.,OB_MINOTAURHIT,,,,%o byl@[ao_cs] rozmáčknut@[ao_cs] Minotaurem.,%o blev knust af en Maulotaurus.,%o wurde von dem Minotaurus zu Brei verarbeitet.,,%o pulpiĝis de Bategtaŭro.,A %o l@[ao_esp] ha hecho puré un Mazotauro.,A %o l@[ao_esp] hizo puré un Mazotauro.,%o joutui maulotaurin möyhentämäksi.,%o s'est fait@[e_fr] éclater par un Massetaure.,%o péppé lett zúzva egy Maulotaurusz által.,%o è stato ridotto in poltiglia da un Maulotauro. ,%o はマウロタウロスにグシャグシャにされた。,%o 은(는) 몰로타우어에 의해 내동댕이쳐졌다.,%o werd verpulverd door een Maulotaurus.,%o ble knust av en maulotaur.,%o został@[ao_pl] roztart@[adj_pl] na miazgę przez Młototaura,%o foi esmagad@[ao_ptb] por um Marretauro,,%o a fost descojit de un Maulotaur.,Игрока %o превратил в кровавое месиво Избитавр.,Играча %o је претукао минотаур.,%o blev krossad av en maulotaurus.,%o bir Maulotor tarafından ezildi. +%o was smashed by a golem.,OB_MUMMY,,,,%o byl@[ao_cs] umlácen@[ao_cs] golémem.,%o blev smadret af en golem.,%o wurde von einem Golem erschlagen.,,%o frakasiĝis de golemo.,A %o l@[ao_esp] ha aplastado un gólem.,A %o l@[ao_esp] aplastó un gólem.,%o joutui golemin murskaamaksi.,%o a été défoncé@[e_fr] par un golem.,%o össze lett törve egy Gólem által.,%o è stato schiacciato da un golem.,%o はゴーレムに叩きのめされた。,%o 은(는) 골렘에게 두들겨 맞았다.,%o werd verbrijzeld door een golem.,%o ble knust av en golem.,%o został@[ao_pl] stłuczon@[adj_pl] przez golema,%o foi esmagad@[ao_ptb] por um golem.,,%o a fost lovit de un golem.,Игрока %o разбил голем.,Играча %o је смрвио голем.,%o blev krossad av en golem.,%o bir golem tarafından parçalandı. +%o was shrieked to death by a nitrogolem.,OB_MUMMYLEADER,,,,%o byl@[ao_cs] ukřičen@[ao_cs] k smrti střelgolémem.,%o blev skriget til døde af en nitrogolem.,%o wurde von einem Nitrogolem zu Tode gekreischt.,,%o estis kriegita ĝis morto de azotgolemo.,A %o le ha chillado a muerte un gólem de ázoe.,A %o le gritó a muerte un gólem de ázoe.,%o kirkaistiin kuoliaaksi nitrogolemin toimesta.,%o s'est fait@[e_fr] percer les tympans par un nitrogolem.,%o halálra lett ijesztve egy Nitrógólem által.,%o è stato stroncato da un golem.,%o はニトロゴーレムに脅かされた。,%o 은(는) 니트로 골렘에 의해 비명횡사 당했다.,%o werd doodgekrijst door een nitrogolem.,%o ble skreket i hjel av en nitrogolem.,%o został@[ao_pl] zakrzyczan@[adj_pl] na śmierć przez nitrogolema,%o agonizou na frente de um nitrogolem.,,%o a fost chiuit până la moarte de un nitrogolem.,Игрока %o убил криком нитроголем.,Играча %o је извриштао до смрти нитроголем.,%o skrek ihjäl av en nitrogolem.,%o bir nitrogolem tarafından çığlık çığlığa öldürüldü. +%o was rattled by an ophidian.,OB_SNAKE,,,,%o byl@[ao_cs] zachřestěn@[ao_cs] šupinatcem.,%o blev rystet af en ophidian.,%o hörte das Klappern des Ophidian.,,%o klakiĝis de ofidio.,A %o l@[ao_esp] ha agitado un ofidio.,A %o l@[ao_esp] sacudió un ofidio.,%o joutui käärmeolion kalkattamaksi.,%o s'est fait@[e_fr] sonner par un ophidien.,%o halálra lett csörgetve egy Ofidián által.,%o è stato stritolato da un serpente.,%o はオフィディアンに動揺した。,%o 은(는) 오피디안에게 흔들렸다.,%o werd gerammeld door een ophidiaan.,%o ble rystet av en ophidian.,%o został@[ao_pl] rozgrzechotan@[adj_pl] przez wężowatego,%o foi sacudid@[ao_ptb] por um ofídio.,,%o a fost bătut până la moarte de un ofidian.,Игрока %o потряс офидиан.,Играча %o је угризла змија.,%o blev skrämd av en ophidian.,%o bir ophidian tarafından sarsıldı. +%o was cursed by a wizard.,OB_WIZARD,,,,%o byl@[ao_cs] zaklet@[ao_cs] čarodějem.,%o blev forbandet af en troldmand.,%o wurde von dem Magier verflucht.,,%o malbeniĝis de sorĉisto.,A %o l@[ao_esp] ha maldecido un mago.,A %o l@[ao_esp] maldijo un hechicero.,%o joutui velhon kiroamaksi.,%o a été maudit@[e_fr] par un sorcier.,%o meg lett átkozva egy Varázsló által.,%o è stato maledetto da un mago.,%o はウィザードに呪われた。,%o 은(는) 드'스파릴의 제자에 의해 저주받았다.,%o werd vervloekt door een tovenaar.,%o ble forbannet av en trollmann.,%o został@[ao_pl] przeklęt@[adj_pl] przez czarownika,%o foi amaldiçoad@[ao_ptb] por um mago.,,%o a fost blestemat de un vrăjitor.,Игрока %o проклял колдун.,%o је проклет@[adj_1_sr] од стране чаробњака.,%o blev förbannad av en trollkarl.,%o bir büyücü tarafından lanetlendi. +%o was palpated by a wizard.,OB_WIZARDHIT,,,,%o byl@[ao_cs] prozkoumán@[ao_cs] čarodějem.,%o blev palperet af en troldmand.,%o spürte den Hauch des Magiers.,,%o palpatiĝis de sorĉisto.,A %o l@[ao_esp] ha tocado un mago.,A %o l@[ao_esp] tocó un hechicero.,%o joutui velhon tunnustelemaksi.,%o a été palpé@[e_fr] par un sorcier.,%o meg lett tapogatva egy Varázsló által.,%o è stato toccato da un mago.,%o はウィザードに触診されてしまった。,%o 은(는) 드'스파릴의 제자에게 촉진당했다.,%o werd betast door een tovenaar.,%o ble palpert av en trollmann.,%o został@[ao_pl] przebadan@[adj_pl] przez czarownika,%o foi apalpad@[ao_ptb] por um mago.,,%o a fost palpat de un vrăjitor.,Игрока %o пощупал колдун.,Играча %o је палпатирао чаробњак.,%o blev palperad av en trollkarl.,%o bir büyücü tarafından palpe edildi. +%o got staffed by %k.,OB_MPSTAFF,,,,%o dostal@[ao_cs] holí od hráče %k.,%o blev stafferet af %k.,%o wurde von %k verprügelt.,,%o bategiĝis de %k.,A %o l@[ao_esp] ha apaleado %k.,A %o l@[ao_esp] apaleó %k.,%k sauvoi %k paran.,%o s'est fait@[e_fr] matraquer par %k.,%o meg lett botozva %k által.,%o è stato preso a colpi di staffa da %k.,%o は %k の棒でぶん殴られた。,%o 은(는) %k 의 지팡이에 제압당했다.,%o kreeg een tik van %k's staf.,%o ble staffet av %k.,%o został@[ao_pl] walnięt@[adj_pl] laską przez %k,%o levou uma sova do bastão de %k.,,%o a fost bastonat de %k.,Игрок %o дополнил посох игрока %k.,%o је претуцан@[adj_1_sr] штапом од стране %k.,%o blev bemannad av %k.,"%o, %k tarafından öldüresiye dövüldü." +%o got a shock from %k's gauntlets.,OB_MPGAUNTLETS,,,,%o byl@[ao_cs] prošokován@[ao_cs] rukavicemi hráče %k.,%o fik et chok af %ks handsker.,%o bekam einen Schock von %ks Handschuhen.,,%o recivis ŝokon de la fergantoj de %k.,%o ha recibido un choque de los guanteletes de %k.,%o recibió un choque de los guanteletes de %k.,%o sai sähköiskun pelaajan %k kintaista.,%o s'est pris@[e_fr] un coup de jus des gantelets de %k.,%o kapott egy sokkot %k által.,%o è stato folgorato dai guanti di %k.,%o は %k の篭手からショックを受けた。,%o 은(는) %k 가 쓰고 있는 건틀릿의 전격을 느꼈다.,%o kreeg een schok van %k's handschoenen.,%o fikk støt av %ks hansker.,%o został@[ao_pl] wstrząśnięt@[adj_pl] rękawicami %k,%o tomou um choque das manoplas de %k.,,%o a primit un șoc de la mănușile lui %k.,Игрок %o шокирован перчатками игрока %k.,%o је доби@[ao_1_sr] шок од %k штапа.,%o blev chockad av %ks handskar.,"%o, %k tarafından şoklandı." +%o waved goodbye to %k's elven wand.,OB_MPGOLDWAND,,,,%o zamával@[ao_cs] elfské hůlce hráče %k.,%o vinkede farvel til %ks elverstav.,%o sagte „Tschüß“ zu %ks Elfenstab.,,%o ĝisis al la elfa sorĉbastono de %k.,%o se ha despedido de la vara de elfo de %k.,%o se despidió de la vara de elfo de %k.,%o heilutti hyvästit pelaajan %k haltiasauvalle.,%o à fait coucou à la baguette magique de %k.,%o integetett egy viszlátot %k Elf Pálcájának.,%o ha fatto ciao ciao allo scettro elfico di %k.,%o は %k のエルフのワンドに別れの挨拶をした。,%o 은(는) %k 의 엘프 지팡이를 보고 작별인사를 했다.,%o zwaaide afscheid van %k's elvenstaf.,%o vinket farvel til %ks alvestav.,%o pomachał@[ao_pl] na do widzenia elfiej różdżce %k,%o deu tchauzinho para o cetro élfico de %k.,%o disse adeuzinho para o cetro élfico de %k.,%o a facut cu mână toiagului lui %k.,Игрок %o узрел прощальный взмах эльфийского жезла игрока %k.,%o је рек@[ao_2_sr] збогом %k вилењачком штапићу.,%o vinkade farväl till %ks elviga stav.,"%o, %k tarafından delik deşik edildi." +%o was pegged by %k's ethereal crossbow.,OB_MPCROSSBOW,,,,%o byl@[ao_cs] prostřelen@[ao_cs] éterickou kuší hráče %k.,%o blev stukket af %ks æteriske armbrøst.,%o von %ks Armbrustbolzen aufgespießt.,,%o kejlis de la etera arbalesto de %k.,A %o l@[ao_esp] ha flechado la ballesta etérea de %k.,A %o l@[ao_esp] flechó la ballesta etérea de %k.,%k ripusti %o paran eteerivarsijousellaan.,%o s'est fait@[e_fr] clouer par l'arbalète étherique de %k.,%o fel lett rögzítve %k Éteri Nyílpuskájának által.,%o è stato inchiodato dalla balestra eterea di %k.,%o は %k のイセリアルクロスボウで釘付けにされた。,%o 은(는) %k 의 유체 쇠뇌에 의해 처박혔다.,%o was vastgepind door %k's etherische kruisboog.,%o ble truffet av %ks eteriske armbrøst.,%o został@[ao_pl] przebit@[adj_pl] przez eteryczną kuszę %k,%o foi esmigalhad@[ao_ptb] pela besta etérea de %k.,,%o a fost prins de arbaleta celestă a lui %k.,Игрок %o изранен болтами эфирного арбалета игрока %k.,%o је упуц@[adj_2_sr] од стране %k етералног самострела.,%o blev fast av %ks eteriska armborst.,"%o, %k tarafından çivilendi." +%o was blasted a new one by %k's dragon claw.,OB_MPBLASTER,,,,%o poznal@[ao_cs] středověk drakospárem hráče %k.,%o blev sprængt en ny af %ks drageklo.,%o bekam %ks Drachenklaue zu spüren.,,%o estis diseksplodita de la drakokrifo de %k.,%o ha quedado bien jodid@[ao_esp] por la garra de dragón de %k.,%o quedó irreconocible por la garra de dragón de %k.,%k puhkoi %o parkaan uuden aukon lohikäärmeenkynnellään.,%o s'est fait flinguer par la griffe draconique de %k.,%o újszerűnek látszik %k Sárkány Karomjának köszönhetően.,A %o èstato aperto un buco nuovo dall'Artiglio di Drago di %k.,%o は %k のドラゴンクローで発破体験した。,%o 은(는) %k 의 용발톱에 의해 형태를 잃었다.,%o werd opengescheurd door %k's drakenklauw.,%o fikk en ny en av %ks drageklo.,%o został wysadzony nowy otwór przez %k,%o sentiu o poder da garra de dragão de %k.,,%o a fost aruncat în aer de gheara dragonului a lui %k.,Игрок %o получил новую форму драконьим когтем игрока %k.,Играчу %o је отворена нова рупа змајевском канџом играча %k.,%o blev skjuten på nytt av %ks drakklo.,"%o, %k tarafından patlatıldı." +%o got sent down under by %k's hellstaff.,OB_MPSKULLROD,,,,Pod hráčem %o se propadla zem peklopalem hráče %k.,%o blev sendt ned under jorden af %ks helvedestav.,%o brach unter %ks Höllenrute zusammen.,,%o forsendiĝis sub de la inferbastono de %k.,%o se ha inclinado ante el bastón infernal de %k.,%o se inclinó ante el bastón infernal de %k.,%k lähetti %o paran maan syövereihin hornansauvallaan.,%o repose six pieds sous terre grâce au Bâton infernal de %k.,%o le lett küldve %k Pokolbotjának köszönhetően.,%o è stato mandato sottoterra dalla Staffa Infernale di %k.,%o は %k のヘルスタッフで冥界に送られた。,%o 은(는) %k 의 지옥지팡이에 의해 저승으로 날아갔다.,%o werd door %k's hellestaf naar beneden gestuurd.,%o ble sendt til helvete av %ks helvetesstav.,%o został@[ao_pl] zesłan@[adj_pl] pod piekielny kostur %k,%o foi mandad@[ao_ptb] pra baixo do solo pelo cajado infernal de %k.,,%o a fost trimis sub bastonul infernal al lui %k.,Игрок %o сослан в самый низ посохом ада игрока %k.,%o је укопан@[adj_1_sr] од стране пакленог штапа играча %k.,%o blev nedskjuten av %ks helvetesstång.,"%o, %k tarafından biçildi." +%o was scorched to cinders by %k's phoenix rod.,OB_MPPHOENIXROD,,,,%o byl@[ao_cs] spálen@[ao_cs] na prach fénixovou holí hráče %k.,%o blev brændt til aske af %ks føniksstav.,%o wurde voin %ks Phönixstab verschmort.,,%o brulegiĝis en cindrojn de la feniksvergo de %k.,A %o l@[ao_esp] ha pulverizado el báculo del Fénix de %k.,A %o l@[ao_esp] pulverizó el báculo del Fénix de %k.,%k kärvensi %o paran tuhannen päreiksi feenikssauvallaan.,%o s'est fait@[e_fr] réduire en cendres par le Bâton du Phénix de %k.,%o halomra lett égve %k Főnix Rúdjának által.,%o è stato ridotto in cenere dal Bastone della Fenice di %k.,%o は %k のフェニックスロッドで焼かれた。,%o 은(는) %k 의 불사조 지팡이 덕에 검게 익었다.,%o werd door %k's feniksstaf tot sintels verschroeid.,%o ble svidd til aske av %ks føniksstav.,%o został@[ao_pl] spalon@[adj_pl] na popiół przez różdżkę feniksa %k,%o virou cinzas com o bastão da fênix de %k.,,%o a fost făcut cenușă de joarda phoenix a lui %k.,Игрок %o сожжён до пепла жезлом феникса игрока %k.,%o запаљен@[adj_1_sr] у пепео од стране шипке феникса играча %k.,%o blev bränd till aska av %ks fenixstav.,"%o, %k tarafından cayır cayır yakıldı." +%o was bounced by %k's firemace.,OB_MPMACE,,,,%o byl@[ao_cs] odpálen@[ao_cs] žezlometem hráče %k.,%o blev kastet afsted af %ks ildspyd.,%o prallte an %ks Feuerkeule ab.,,%o estis resaltita de la fajroklabo de %k.,%o ha rebotado en la maza de fuego de %k.,%o rebotó en la maza de fuego de %k.,%k pomputti %o parkaa tulinuijallaan.,%o a rebondi@[e_fr] sur les balles de la Masse de Feu à %k.,%o pattant egy nagyot %k Tűzbuzogányának köszönhetően.,%o è stato spazzato via dalla Mazza del Fuoco di %k.,%o は %k のファイアメイスで飛ばされた。,%o 은(는) %k 의 투사철퇴의 포탄을 맞고 튕겨져 날아갔다.,%o werd door %k's vuurknots geraakt.,%o ble kastet av %ks ildkule.,%o został@[ao_pl] wybit@[adj_pl] przez buzdygan ognia %k,%o saiu pulando após ver a clava de fogo de %k.,,%o a fost aruncat de colo colo de buzduganul de foc al lui %k.,Игрок %o отбит огненной булавой игрока %k.,%o је ударен@[adj_1_sr] са ватреним буздованом играча %k.,%o blev utvisad av %ks eldstöt,"%o, %k tarafından ezildi." +%o got clapped by %k's charged staff.,OB_MPPSTAFF,,,,%o byl@[ao_cs] profackován@[ao_cs] nabitou holí hráče %k.,%o blev klappet af %ks ladede stav.,%o bekam eine Klatsche durch %ks geladenen Stab.,,%o estis aplaŭdita de la ŝargita bastono de %k.,A %o l@[ao_esp] ha apaleado el bastón cargado de %k .,A %o l@[ao_esp] apaleó el bastón cargado de %k .,%k jyrisytti %o parkaa varatulla sauvallaan.,%o à été foudroyé@[e_fr] par le bâton chargé de %k.,%o csattant egy nagyot %k Feltöltött Botjának által.,%o è scoppiato a causa della staffa incantata di %k.,%o は %k の魔力を帯びた棒で暖かく迎えられた。,%o 은(는) %k 의 마법부가 지팡이를 얻어맞았다.,%o kreeg een klap van %k's opgeladen staf.,%o ble klappet av %ks ladede stav.,%o został@[ao_pl] trzepnięt@[adj_pl] naładowaną laską %k,%o tomou uma pancada do bastão carregado de %k.,,%o a fost tăiat de bastonul încărcat al lui %k.,Игрок %o отведал заряженного посоха игрока %k.,%o је потапшан@[adj_1_sr] напуњеним штапом играча %k.,%o fick en klapp av %ks laddade stav.,"%o, %k tarafından yakıldı." +%o was bled dry by %k's gauntlets.,OB_MPPGAUNTLETS,,,,Rukavicemi hráče %k nezůstala v těle hráče %o ani kapka krve.,%o blev udblødt af %ks handsker.,%o wurde von %ks Handschuhen ausgeblutet.,,%o sensangiĝis de la fergantoj de %k.,A %o l@[ao_esp] han dejado exangüe los guanteletes de %k.,A %o l@[ao_esp] dejaron exangüe los guanteletes de %k.,%k vuodatti %o paran kuiviin kintaillaan.,%o s'est fait@[e_fr] saigner à blanc par les gantelets de %k.,%k megtanította %o-t Páncélkesztyűbe dudálni.,Il sangue di %o è stato prosciugato dai guanti di %k.,%o は %k の篭手で血を絞り取られた。,%o 은(는) %k 의 마법부가 건틀릿에 의해 바싹 말랐다.,%o werd leeggebloed door %k's handschoenen.,%o ble tappet for blod av %ks hansker.,%o wykrwawił@[ao_pl] się przez rękawice %k,%o sangrou nas manoplas de %k.,,"%o a fost stors până la ultima picătură de sânge +de mănușile lui %k.",Игрок %o был обескровлен перчатками игрока %k.,%o је путпуно искрвари@[ao_1_sr] од рукавица играча %k.,%o blev blödd av %ks handskar.,"%o, %k tarafından kan kaybından kurutuldu." +%o was assaulted by %k's elven wand.,OB_MPPGOLDWAND,,,,%o byl@[ao_cs] napaden@[ao_cs] elfskou hůlkou hráče %k.,%o blev overfaldet af %ks elverstav.,%o wurde von %ks Elfenstab überwältigt.,,%o atakiĝis de la elfa sorĉbastono de %k.,%o ha sido asaltad@[ao_esp] por la vara de elfo de %k.,%o fue asaltad@[ao_esp] por la vara de elfo de %k.,%o joutui pelaajan %k haltiasauvan pahoinpitelemäksi.,%o à été assailli@[e_fr] par la baguette elfique de %k.,%k megbotozta %o az Elf Botjával.,%o è stato assalito dallo Scettro Elfico di %k.,%o は %k のエルフのワンドで襲われた。,%o 은(는) %k 의 마법부가 엘프 지팡이에 의해 사냥당했다.,%o werd aangevallen door %k's elvenstaf.,%o ble angrepet av %ks alvestav.,%o został@[ao_pl] zaatakowan@[adj_pl] przez elfią różdżkę %k,%o foi atacad@[ao_ptb] pelo cetro élfico de %k.,,%o a fost luat cu asalt de togaiul lui %k.,Игрок %o атакован эльфийским жезлом игрока %k.,%o је нападнут@[adj_1_sr] вилењачким штапом играча %k.,%o blev attackerad av %ks älvstav.,"%o, %k tarafından saldırıya uğradı." +%o was shafted by %k's ethereal crossbow.,OB_MPPCROSSBOW,,,,%o byl@[ao_cs] proděravěn@[ao_cs] éterickou kuší hráče %k.,%o blev ramt af %ks æteriske armbrøst.,%o wurde von %ks Armbrustbolzen durchbohrt.,,%o akiris novan truon de etera arbalesto de %k.,%o ha sido encañonad@[ao_esp] por la ballesta etérea de %k.,%o fue encañonad@[ao_esp] por la ballesta etérea de %k.,%k joutui pelaajan %k eteerivarsijousen kepittämäksi.,%o s'est fait@[e_fr] transpercer par l'arbalète éthérique de %k.,%o megkóstolta %k Éteri Nyílpuskáját.,%o è stato impalato dalla balestra eterea di %k.,%o は %k のイセリアルクロスボウで押された。,%o 은(는) %k 의 마법부가 유체 쇠뇌에 의해 무뎌졌다.,%o werd door %k's etherische kruisboog geschaafd.,%o ble truffet av %ks eteriske armbrøst.,%o został@[ao_pl] wykiwan@[adj_pl] przez eteryczną kuszę %k,%o foi flechad@[ao_ptb] pela besta etérea de %k.,,"%o a fost pus la proțap de arbaleta celestă a lui +%k.",Игрок %o пробит эфирным арбалетом игрока %k.,%o је упуцан@[adj_1_sr] етеричним самострелом играча %k.,%o blev skjuten av %ks eteriska armborst.,"%o, %k tarafından şaftlandı." +%o was ripped apart by %k's dragon claw.,OB_MPPBLASTER,,,,%o byl@[ao_cs] roztrhnut@[ao_cs] naskrz drakospárem hráče %k.,%o blev flået i stykker af %ks drageklo.,%o wurde von der Drachenklaue zerrissen.,,%o disrompiĝis de la drakokrifo de %k.,A %o l@[ao_esp] ha desgarrado la garra de dragón de %k.,A %o l@[ao_esp] desgarró la garra de dragón de %k.,%k repi %o paran kappaleiksi lohikäärmeenkynnellään.,%o à été mis@[e_fr] en pièces par la griffe draconique de %k.,%o szét lett tépve %k Sárkány Karomja által.,%è stato fatto a brandelli dall'Artiglio di Drago di %k.,%o は %k のドラゴンの鉤爪でバラバラに引き裂かれた。,%o 은(는) %k 의 마법부가 용발톱에 갈기갈기 찢겨졌다.,%o werd uit elkaar gescheurd door %k's drakenklauw.,%o ble revet i filler av %ks drageklo.,%o został@[ao_pl] rozerwan@[adj_pl] przez smoczy pazur %k,%o foi cortad@[ao_ptb] pela garra de dragão de %k.,,%k a fost făcut bucăți de gheara lui %k.,Игрок %o разорван драконьим когтём игрока %k.,%o је поцепан@[adj_1_sr] змајевим канџама играча %k.,%o blev sliten i bitar av %ks drakklo.,"%o, %k tarafından parçalara ayrıldı." +%k poured the hellstaff on %o.,OB_MPPSKULLROD,,,,Hráč %k vylil svůj peklopal na hráče %o.,%k hældte helvedesstaven ud over %o.,%k ließ den Höllenregen auf %o los.,,%k ŝutas la inferbastonon sur %o.,%k ha vertido su bastón infernal en %o.,%k vertió su bastón infernal en %o.,%k vuodatti hornansauvansa %o parkaan.,%k à versé toute la rage des enfers sur %o.,%o nem hozott esernyőt %o Pokolbot zápora ellen.,%k ha fatto sgorgare la sua Staffa Infernale su %o.,%o は %k にヘルスタッフを %p 注ぎ込まれた。,%k의 마법부가 지옥지팡이가 쏟아붓는 비를 %o 이(가) 맞았다.,%k liet de helregen los op %o.,%k helte helvetesstaven over %o.,%k polał@[ao_pl] swoim piekielnym kosturem %o,%k usou seu cajado infernal no %o.,,%k a vărsat bastonul infernal pe %o.,Игрок %k залил игрока %o горячим дождём при помощи посоха ада.,%k је просипа@[ao_1_sr] пламени штап на %o.,%k hällde helvetesstången på %o.,"%o, %k tarafından yakıldı." +%o was burned down by %k's phoenix staff.,OB_MPPPHOENIXROD,,,,%o byl@[ao_cs] vyhořen@[ao_cs] fénixovou holí hráče %k.,%o blev brændt ned af %ks Føniks stav.,%o wurde von %ks Phönixstab verbrannt.,,%o torĉiĝis de la feniksvergo de %k.,A %o l@[ao_esp] ha calcinado el báculo del Fénix de %k.,A %o l@[ao_esp] calcinó el báculo del Fénix de %k.,%k poltti %o paran feenikssauvallaan.,%o à été incinéré@[e_fr] par le Bâton du Phénix de %k.,%o elégett %k Főnix Botjának által.,%o è stato incendiato dal Bastone della Fenice di %k.,%o は %k のフェニックスロッドで焼き滅ぼされた。,%o 은(는) %k 의 마법부가 불사조 지팡이에 의해 화장당했다.,%o werd afgebrand door %k's feniksstaf.,%o ble brent ned av %ks føniksstav.,%o został@[ao_pl] spalon@[adj_pl] przez różdżkę feniksa %k,%o foi queimad@[ao_ptb] pelo bastão da fênix de %k.,,%o a fost ars complet de joarda lui %k.,Игрок %o сожжён жезлом феникса игрока %k.,%o је изгоре@[ao_1_sr] шипком феникса играча %k.,%o brändes ner av %ks Fenix-stav.,"%o, %k tarafından yakıldı." +%o was squished by %k's giant mace sphere.,OB_MPPMACE,,,,%o byl@[ao_cs] rozmačkán@[ao_cs] obrovskou žezlometnou koulí hráče %k.,%o blev mast af %ks ildspyd kugle.,%o wurde von %ks Feuerkeule zerquetscht.,,%o premiĝis de la grandega klubsfero de %k.,A %o l@[ao_esp] ha aplastado una esfera gigante de la maza de %k.,A %o l@[ao_esp] aplastó una esfera gigante de la maza de %k.,%k liiskasi %o paran jättiläisnuijapallollaan.,%o s'est fait@[e_fr] écraser par la balle de Masse géante de %k.,%o össze lett nyomva %k hatalmas buzogány gömbje által.,%o è stato spiaccicato da una sfera gigante della Mazza del Fuoco di %k.,%o は %k の巨大なメイススフィアで潰された。,%o 은(는) %k 의 마법부가 투사철퇴가 뿜은 거대포탄에 의해 납작해졌다.,%o werd verpletterd door %k's reusachtige strijdknots.,%o ble knust av %ks gigantiske muskatblomstkule.,%o został@[ao_pl] zmiażdżon@[adj_pl] przez ogromną kulę z buzdygana %k,%o foi esmagad@[ao_ptb] pela esfera de clava gigante de %k.,,"%o a fost strivit de globul buzduganului +lui %k.",Игрок %o раздавлен огромной сферой из огненной булавы %k.,%o је смрвљен@[adj_1_sr] од стане огромном сферско буздована играча %k.,%o blev mosad av %ks gigantiska eldstötsfär.,"%o, %k tarafından ezildi." +,,Hexen,,,,,,,,,,,,,,,,,,,,,,,,, +,,Pickup,,,,,,,,,,,,,,,,,,,,,,,,, +Blue Mana,TXT_MANA_1,,,,Modrá mana,Blå Mana,Blaues Mana,,Blua Manao,Maná Azul,,Sininen mana,Mana Bleu,Kék Mana,Mana blu,青マナ,청색 마나,Blauwe Mana,Blå Mana,Niebieska Mana,Mana Azul,,Mană Albastră,Синяя мана,Плава мана,Blå Mana,Mavi Mana +Green Mana,TXT_MANA_2,,,,Zelená mana,Grøn Mana,Grünes Mana,,Verda Manao,Maná Verde,,Vihreä mana,Mana Vert,Zöld Mana,Mana verde,緑マナ,녹색 마나,Groene Mana,Grønn Mana,Zielona Mana,Mana Verde,,Mană Verde,Зелёная мана,Зелена мана,Grön Mana,Yeşil Mana +Combined Mana,TXT_MANA_BOTH,,,,Smíšená mana,Kombineret Mana,Kombiniertes Mana,,Kuna Manao,Maná Combinado,,Yhdistetty mana,Mana Combiné,Kombinált Mana,Mana misto,複合マナ,윰합된 마나,Gecombineerde Mana,Kombinert mana,Połączona Mana,Mana Combinado,,Mană Mixtă,Общая мана,Комбинована мана,Kombinerad Mana,Kombine Mana +Steel Key,TXT_KEY_STEEL,,,,Ocelový klíč,Stålnøgle,Stahlschlüssel,Ατσάλινο Κλειδί,Ŝtala Ŝlosilo,Llave de Acero,,Teräsavain,Clé d'Acier,Acél Kulcs,Chiave d'acciaio,鋼の鍵,강철 열쇠,Stalen Sleutel,Stålnøkkel,Stalowy Klucz,Chave de Aço,,Cheia din Oțel,Стальной ключ,Челични кључ,Stålnyckel,Çelik Anahtar +Cave Key,TXT_KEY_CAVE,,,,Klíč od jeskyně,Hule-nøgle,Höhlenschlüssel,,Kavern-Ŝlosilo,Llave de la Caverna,,Luola-avain,Clé de la Cave,Barlang Kulcs,Chiave della caverna,洞窟の鍵,동굴 열쇠,Grotsleutel,Hulenøkkel,Klucz do Jaskini,Chave da Caverna,,Cheia Peșterii,Пещерный ключ,Пећински кључ,Grottnyckel,Mağara Anahtarı +Axe Key,TXT_KEY_AXE,,,,Sekyrový klíč,Økse-nøgle,Axtschlüssel,,Hakil-Ŝlosilo,Llave de Hacha,,Kirvesavain,Clé de la Hache,Fejsze Kulcs,Chiave dell'ascia,斧の鍵,도끼 열쇠,Bijlsleutel,Økse-nøkkel,Klucz-topór,Chave do Machado,,Cheia Topor,Топор-ключ,Кључ секира,Yxnyckel,Balta Anahtarı +Fire Key,TXT_KEY_FIRE,,,,Ohnivý klíč,Ild-nøgle,Feuerschlüssel,,Fajro-Ŝlosilo,Llave de Fuego,,Tuliavain,Clé du Feu,Tűz Kulcs,Chiave del fuoco,炎の鍵,불 열쇠,Vuursleutel,Ildnøkkel,Ognisty Klucz,Chave do Fogo,,Cheia de Foc,Огненный ключ,Огњени кључ,Eldnyckel,Yangın Anahtarı +Emerald Key,TXT_KEY_EMERALD,,,,Smaragdový klíč,Smaragdnøgle,Smaragdschlüssel,,Smerelda Ŝlosilo,Llave Esmeralda,,Smaragdiavain,Clé d'Emeraude,Smaragd Kulcs,Chiave di smeraldo,翠玉の鍵,에메랄드 열쇠,Smaragden Sleutel,Smaragdnøkkel,Szmaragdowy Klucz,Chave de Esmeralda,,Cheia din Smarald,Изумрудный ключ,Смарагдни кључ,Smaragdnyckel,Zümrüt Anahtar +Dungeon Key,TXT_KEY_DUNGEON,,,,Klíč od žaláře,Dungeon-nøgle,Kerkerschlüssel,,Karcer-Ŝlosilo,Llave del Calabozo,,Tyrmän avain,Clé du Donjon,Várbörtön Kulcs,Chiave del sotterraneo,迷宮の鍵,지하감옥 열쇠,Kerkersleutel,Dungeon-nøkkel,Klucz do Lochu,Chave da Masmorra,,Cheia Temniței,Ключ от подземелья,Кључ од лагума,Kerker-nyckel,Zindan Anahtarı +Silver Key,TXT_KEY_SILVER,,,,Stříbrný klíč,Sølvnøgle,Silberschlüssel,Ασυμένιο Κλειδί,Arĝenta Ŝlosilo,Llave de Plata,,Hopea-avain,Clé d'Argent,Ezüst Kulcs,Chiave d'argento,銀の鍵,은 열쇠,Zilveren Sleutel,Sølvnøkkel,Srebrny Klucz,Chave de Prata,,Cheia din Argint,Серебряный ключ,Сребрни кључ,Silvernyckel,Gümüş Anahtar +Rusted Key,TXT_KEY_RUSTED,,,,Zrezivělý klíč,Rustet nøgle,Rostiger Schlüssel,Σκουριασμένο Κλειδί,Rusta Ŝlosilo,Llave Oxidada,,Ruosteinen avain,Clé Rouillée,Rozsdás Kulcs,Chiave arrugginita,錆びた鍵,녹슨 열쇠,Geroeste Sleutel,Rustet nøkkel,Zardzewiały Klucz,Chave Enferrujada,,Cheia Ruginită,Ржавый ключ,Зарђали кључ,Rostad nyckel,Paslı Anahtar +Horn Key,TXT_KEY_HORN,,,,Parožní klíč,Hornnøgle,Hornschlüssel,,Hup-Ŝlosilo,Llave de Cuerno,,Sarviavain,Clé Corne,Szarv Kulcs,Chiave del corno,角の鍵,뿔 열쇠,Hoornsleutel,Horn-nøkkel,Rogowy Klucz,Chave do Chifre,,Cheia Corn,Роговой ключ,Рогати кључ,Horn-nyckel,Korna Anahtarı +Swamp Key,TXT_KEY_SWAMP,,,,Klíč od bažiny,Sumpnøgle,Sumpfschlüssel,,Marĉo-Ŝlosilo,Llave del Pantano,,Suoavain,Clé des Marécages,Mocsár Kulcs,Chiave della palude,沼の鍵,늪지대 열쇠,Moerassleutel,Sumpnøkkel,Bagienny Klucz,Chave do Pântano,,Cheia Mlaștinii,Болотный ключ,Мочварни кључ,Träsknyckel,Bataklık Anahtarı +Castle Key,TXT_KEY_CASTLE,,,,Klíč od hradu,Slotsnøgle,Burgschlüssel,,Kastel-Ŝlosilo,Llave del Castillo,,Linnan avain,Clé du Château,Kastély Kulcs,Chiave del castello,城の鍵,성 열쇠,Kasteelsleutel,Slottsnøkkel,Klucz do Zamku,Chave do Castelo,,Cheia Castelului,Ключ от замка,Кључ од замка,Slottsnyckel,Kale Anahtarı +Icon of the Defender,TXT_ARTIINVULNERABILITY2,,,,Obráncova ikona,Ikon af forsvareren,Ikone des Verteidigers,,Ikono de la Defendanto,Icono del Defensor,Ícono del Defensor,Puolustajan ikoni,Icône du Défenseur,Védelmező Ikonja,Icona del difensore,守護者の像,수호의 성상,Symbool van de Verdediger,Forsvarerens ikon,Ikona Obrońcy,Ícone do Defensor,,Imaginea Apărătorului,Символ защитника,Симбол браниоца,Försvararens ikon,Savunucunun Simgesi +Dark Servant,TXT_ARTISUMMON,,,,Temný služebník,Mørk tjener,Dunkler Diener,,Malluma Servanto,Sirviente Oscuro,,Pimeä palvelija,Serviteur Noir,Árny Szolga,Servitore oscuro,闇の従者,어둠의 하인,Donkere Dienaar,Mørk tjener,Mroczny Sługa,Servo Negro,,Servitor Întunecat,Тёмный слуга,Мрачни слуга,Mörk tjänare,Karanlık Hizmetkar +Porkalator,TXT_ARTIEGG2,,,,Vepřovitel,,,,Porkigilo,Porcinador,,Sikaannuttaja,Porcificateur,Ártányátok,Porchificatore,ポークレイター,돈육기,,,Schabowator,Porquificador,,Porcolator,Свиновизатор,Свињатор,, +Flechette,TXT_ARTIPOISONBAG,,,,Střelka,,,,Flakono,,,,Fléchette,Flakon,Fiaschetta,フレチェット,플레셰트,,,Flaszka,,,Flacon,Флешетта,Бочица,, +Banishment Device,TXT_ARTITELEPORTOTHER,,,,Vyhošťovač,Forvisningsanordning,Verbannungsgerät,,Forpelilo,Dispositivo de Desvanecimiento,,Häivytyskoje,Outil de Banissement,Száműző,Artifatto dell'esilio,追放のデバイス,소멸 장치,Verbanningsapparaat,Forvisningsanordning,Urządzenie Wygnania ,Dispositivo do Banimento,,Dispozitiv al Alungării,Устройство изгнания,Амблем прогањања,Förvisningsenhet,Sürgün Cihazı +Boots of Speed,TXT_ARTISPEED,,,,Běhuté boty,Støvler af hastighed,Turbo-Stiefel,,Botoj de Rapideco,Botas de Velocidad,,Ripeyssaappaat,Bottes de Célérité,Sebesség Cipője,Stivali della velocità,素早さの靴,속도의 신발,Snelheidslaarzen,Støvler av fart,Buty Szybkości,Botas da Velocidade,,Bocancii Vitezei,Сапоги-скороходы,Брзинске чизме,Snabbhetens stövlar,Hız Çizmeleri +Krater of Might,TXT_ARTIBOOSTMANA,,,,Kalich síly,Krater of Might,Kelch der Macht,,Kratero de Potenco,Vasija de Fuerza,,Mahtikrateeri,Cratère de Pouvoir,Hatalom Krátere,Calice della forza,魔力の盃,힘의 향로,Beker van Macht,Krater av makt,Czara mocy,Cálice do Poder,,Pocal al Puterii,Чаша могущества,Чаша силе,Mäktighetens krater,Kudret Krateri +Dragonskin Bracers,TXT_ARTIBOOSTARMOR,,,,Dračí nátepníky,Drageskindsarmbøjler,Drachenhaut-Armschutz,,Brakbendo el Drakhaŭto,Brazaletes de piel de Dragón,,Lohikäärmeennahkarannesuojat,Bracelets en Peau de Dragon,Sárkánybőr Karkötők,Bracciali in pelle di drago,竜皮の小手,용가죽 팔찌,Drakenhuidbescherming,Dragehud-bindinger,Karwasze ze Smoczej Skóry,Braçadeiras de Pele de Dragão,,Brățări din Piele de Dragon,Наручи из драконьей кожи,Наруквице од змајеве коже,Drakskinnsarmbågar,Ejderha Derisi Bilezikler +Disc of Repulsion,TXT_ARTIBLASTRADIUS,,,,Kotouč odpuzení,Skive af frastødning,Rückstoßscheibe,,Disko de Repelado,Disco de Repulsión,,Karkotuskiekko,Disque de Répulsion,Visszaverés Lemeze,Disco della repulsione,反発の円盤,방탄의 원반,Schijf van Afstoting,Frastøtelsesskive,Dysk Odpychania,Disco da Repulsão,,Disc al Repulsiei,Диск отторжения,Диск одбијања,Skiva av avstötning,İtme Diski +Mystic Ambit Incant,TXT_ARTIHEALINGRADIUS,,,,Tajemný čár koljdoucí,Mystic Ambit Incant,Verbannungsgerät,,Sorĉo de Mistika Sfero,Encanto de Ámbito Místico,,Mystisen piirin loitsu,Incantation Mystique,Misztikus Mágialista,Confine mistico,魅知国の秘法,신비 영역의 주문,,Mystic Ambit-besvergelse,Inkantancja Mistycznego Kręgu,Encanto Místico,,Pergament Mistic,Чары магического единства,Чаролија магичног јединства,,Mistik Ambit Büyüsü +Yorick's Skull,TXT_ARTIPUZZSKULL,,,,Jorikova lebka,Yoricks kranium,Yoricks Schädel,,Kranio de Yorick,Calavera de Yorick,,Yorickin kallo,Crâne de Yorick,Yorick Koponyája,Teschio di Yorick,ヨリックの髑髏,요릭의 두개골,Yorick's Schedel,Yoricks hodeskalle,Czaszka Yoricka,Caveira de Yorick,,Craniul lui Yorick,Череп Йорика,Јорикова лобања,Yoricks skalle,Yorick'in Kafatası +Heart of D'sparil,TXT_ARTIPUZZGEMBIG,,,,Srdce D'Sparila,D'sparils hjerte,D'Sparils Herz,,Koro de D'sparil,Corazón de D'Sparil,,D'Sparilin sydän,Cœur de D'Sparil,D'Sparil szíve,Cuore di d'sparil,デ'スパリルの心,드'스파릴의 심장,Hart van D'sparil,D'Sparils hjerte,Serce D'Sparila,Coração de D'Sparil,,Inima lui D'Sparil,Сердце Д'Спарила,Д'Спарилино срце,D'sparils hjärta,D'sparil'in Kalbi +Ruby Planet,TXT_ARTIPUZZGEMRED,,,,Rubínová planeta,Rubinplanet,Rubinplanet,,Rubena Planedo,Planeta Rubí,,Rubiiniplaneetta,Planète de Rubis,Rubin Bolygó,Pianeta di rubino,ルビーの宝石,루비 행성석,Robijnrode Planeet,Rubinplaneten,Rubinowa Planeta,Planeta Rubi,,Planetă din Rubin,Рубиновая планета,Планета рубина,Rubinplanet,Yakut Gezegeni +Emerald Planet,TXT_ARTIPUZZGEMGREEN1,,,,Smaragdová planeta,Smaragdplanet,Smaragdplanet,,Smeralda Planedo,Planeta Esmeralda,,Smaragdiplaneetta,Planète d'Emeraude,Smaragd Bolygó,Pianeta di smeraldo,エメラルドの宝石,에메랄드 행성석 (1),Smaragdgroene Planeet,Smaragdplaneten,Szmaragdowa Planeta,Planeta Esmeralda,,Planetă din Smarald,Изумрудная планета,Смарагдна планета,Smaragdplanet,Zümrüt Gezegen +Emerald Planet,TXT_ARTIPUZZGEMGREEN2,,,,Smaragdová planeta,Smaragdplanet,Smaragdplanet,,Smeralda Planedo,Planeta Esmeralda,,Smaragdiplaneetta,Planète de Saphir,Smaragd Bolygó,Pianeta di smeraldo,エメラルドの宝石,에메랄드 행성석 (2),Smaragdgroene Planeet,Smaragdplaneten,Szmaragdowa Planeta,Planeta Esmeralda,,Planetă din Smarald,Изумрудная планета,Смарагдна планета,Smaragdplanet,Zümrüt Gezegen +Sapphire Planet,TXT_ARTIPUZZGEMBLUE1,,,,Safírová planeta,Safirplanet,Saphirplanet,,Safira Planedo,Planeta Zafiro,,Safiiriplaneetta,Planète de Saphir,Zafír Bolygó,Pianeta di zaffiro,サファイアの宝石,사파이어 행성석 (1),Saffierblauwe Planeet,Safirplaneten,Szafirowa Planeta,Planeta Safira,,Planetă din Safir,Сапфировая планета,Сафирна планета,Safirplanet,Safir Gezegen +Sapphire Planet,TXT_ARTIPUZZGEMBLUE2,,,,Safírová planeta,Safirplanet,Saphirplanet,,Safira Planedo,Planeta Zafiro,,Safiiriplaneetta,Planète de Saphir,Zafír Bolygó,Pianeta di zaffiro,サファイアの宝石,사파이어 행성석 (2),Saffierblauwe Planeet,Safirplaneten,Szafirowa Planeta,Planeta Safira,,Planetă din Safir,Сапфировая планета,Сафирна планета,Safirplanet,Safir Gezegen +Daemon Codex,TXT_ARTIPUZZBOOK1,,,,,,,,Kodekso de Demono,Códice del Demonio,,Daemon-koodeksi,Codex Démoniaque,Démon Kódex,Codice Demoniaco ,デーモンの写本,악마의 고문서,,,Demoniczny Kodeks,Códice Demoníaco,,Codexul Demonilor,Демонический кодекс,Демонски кодекс,, +Liber Oscura,TXT_ARTIPUZZBOOK2,,,,,,,,,,,,,,,オスキュラ公文書,어둠의 자유서,,,Liber Oscura,,,,Либер Оскура,Либер Оскура,, +Flame Mask,TXT_ARTIPUZZSKULL2,,,,Plamenná maska,Flammemaske,Flammenmaske,,Flamomasko,Máscara de llamas,,Liekkinaamio,Masque de Flammes,Láng Maszk,Maschera delle fiamme,炎の仮面,화염의 가면,Vuurmasker,Flammemaske,Maska Płomieni,Máscara das Chamas,,Mască de Foc,Маска пламени,Маска пламена,Flam-mask,Alev Maskesi +Glaive Seal,TXT_ARTIPUZZFWEAPON,,,,Glévská pečeť,Glasur-segl,Schwetsiegel,,Sigelo de Glavo,Sello de Espada,,Miekkasinetti,Sceau du Glaive,Pallos Pecsét,Sigillo della brando,グレイブシール,밀폐된 칼날,Lanszegel,Glaive segl,Pieczęć Glewii,Selo do Gládio,,Sigiliu Spadă,Печать воителя,Војников печат,Glasögonsegel,Glaive Mühür +Holy Relic,TXT_ARTIPUZZCWEAPON,,,,Svatá relikvie,Hellig relikvie,Heiliges Relikt,,Sankta Relikvo,Santa Reliquia,,Pyhä reliikki,Relique Sacrée,Szent Ereklye,Reliquia sacra,聖遺物,신성한 유물,Heilige Relikwie,Hellig relikvie,Święta Relikwia,Relíquia Sagrada,,Relicvă Sfântă,Святая реликвия,Света реликвија,Heliga reliker,Kutsal Emanet +Sigil of the Magus,TXT_ARTIPUZZMWEAPON,,,,Mágovo sigilium,Magus' segl,Symbol des Magiers,,Sigelo de la Mago,Emblema del Mago,,Taikurin sinetti,Sceau du Mage,Mágus Pecsétje,Suggello del magus,メイガスの印章,마거스의 인장,Sigaar van de Magus,Magusens segl,Emblemat Maga,Sigilo do Mago,,Sigiliul Magului,Печать Мага,Чаробњаков симбол,Magikerns sigill,Büyücünün Sigil'i +Clock Gear,TXT_ARTIPUZZGEAR,,,,Ozubené kolečko,Urværk,Zahnrad,,Dentrado de Horloĝo,Engranaje de reloj,,Kellonratas,Rouage d'Horloge,Óra Szerkezet,Ingranaggio d'orologio,時計の歯車,시계 톱니바퀴,Kloktandwiel,Klokkeutstyr,Mechanizm Zegara,Engrenagem de Relógio,,Mecanism Ceas,Часовая шестерня,Сатни зупчаник,Klockan växel,Saat Dişlisi +You Cannot Use This Here,TXT_USEPUZZLEFAILED,,,,Zde se tento předmět použít nedá,Du kan ikke bruge dette her,Das kannst du hier nicht benutzen,,Vi ne povas uzi ĉi tion ĉi tie.,No puedes usar esto aquí,,Et voi käyttää tätä tässä,Vous ne pouvez pas utiliser cela ici.,Ezt Itt Nem Használhatod,Non puoi usare questo oggetto qui,ここでは使用できない,이것은 여기에 사용할 수 없다,Dat kan je hier niet gebruiken,Du kan ikke bruke dette her,Nie możesz użyć tego tutaj,Você não pode usar isso aqui,Não podes usar isto aqui,Nu Poți Folosi Asta Aici,Здесь это невозможно использовать,Ово се не може користити овде,Du kan inte använda detta här,Bunu Burada Kullanamazsınız +Mesh Armor,TXT_ARMOR1,,,Mesh Armour,Kroužkové brnění,,Kettenrüstung,,Marŝkiraso,Armadura de Malla,,Rengashaarniska,Armure de Mailles,Háló Páncél,Maglia metallica,鎖帷子,사슬 갑옷,Maliënkolder,Nettrustning,Kolczuga,Armadura de Malha,,Armură din Zale,Кольчуга,Верижњача,Nätrustning,Örgü Zırh +Falcon Shield,TXT_ARMOR2,,,,Sokolí štít,Falke-skjold,Falkenschild,,Falko-Ŝildo,Escudo de Halcón,,Haukkakilpi,Bouclier du Faucon,Sólyom Pajzs,Scudo del falco,鷹の盾,팔콘 방패,Valkenschild,Falkeskjold,Sokola Tarcza,Escudo do Falcão,,Scut Șoim,Соколиный щит,Соколов штит,Falken-sköld,Falcon Kalkanı +Platinum Helmet,TXT_ARMOR3,,,,Platinová helma,Platin-hjelm,Platinhelm,,Platena Kasko,Casco de Platino,,Platinakypärä,Casque de Platine,Platina Sisak,Elmo di platino,白金の兜,백금 투구,Platina Helm,Platinahjelm,Platynowy Hełm,Capacete de Platina,,Coif de Platină,Платиновый шлем,Шлем од платине,Platinahjälm,Platin Kask +Amulet of Warding,TXT_ARMOR4,,,,Amulet uhýbání,Amulet af afværge,Wachamulett,,Amuleto de Gardado,Amuleto de Guarda,,Suojelusamuletti,Amulette de Protection,Oltalom Amulettje,Amuleto di protezione,回避の護符,수호의 부적,Amulet van Bescherming,Amulett av beskyttelse,Amulet Ochrony,Amuleto da Proteção,,Amuleta Protecției,Амулет стража,Амулет страже,Amulett för skydd,Korunma Tılsımı +Timon's Axe,TXT_WEAPON_F2,,,,Timonova sekera,Timons økse,Timons Axt,,Hakilo de Timon,Hacha de Timón,,Timonin kirves,Hache de Timon,Timon Baltája,Ascia di timon,タイモンの斧,티몬의 도끼,Timon's Bijl,Timons øks,Topór Timona,Machado de Timon,,Toporul lui Timon,Топор Тимона,Тимонова секира,Timons yxa,Timon'un Baltası +Hammer of Retribution,TXT_WEAPON_F3,,,,Kladivo odplaty,Gengældelsens hammer,Hammer der Rache,,Martelo de Repago,Martillo de Retribución,,Koston vasara,Marteau de la Rétribution,Kárhozat Kalapácsa,Martello del castigo,報復の金槌,징벌의 망치,Hamer der Vergelding,Gjengjeldelsens hammer,Młot Odkupienia,Martelo da Retribuição,,Ciocanul Salvării,Молот возмездия,Чекић одмазде,Hämndhammaren,İntikam Çekici +Quietus Assembled,TXT_WEAPON_F4,,,,Složený Tišitel,Forløser samlet,Erlöser komplettiert,,Kvietus' Muntita,Quietus Ensamblado,,Quietus koottuna,Quietus Assemblée,Némusz Összerakva,Quietus assemblato,組み立てた 死滅の剣,완성된 종언의 검,Quietus in elkaar gezet,Quietus samlet,Złożony Uciszacz,Quietus Montada,,Argument Final Asamblat,Последний довод собран воедино,Самрт је сабрана,Quietus monterad,Quietus Birleştirildi +Serpent Staff,TXT_WEAPON_C2,,,,Hadí hůl,Slange-stav,Schlangenstab,,Serpentbastono,Vara de Serpiente,,Käärmesauva,Sceptre du Serpent,Kígyó Bot,Bastone del serpente,蛇の杖,뱀 지팡이,Slangenstaf,Slangestav,Laska Węży,Cetro da Serpente,,Bastonul Șarpelui,Змеиный посох,Змијски штап,Ormens stav,Yılan Asa +Firestorm,TXT_WEAPON_C3,,,,Ohnivá bouře,Ildstorm,Feuersturm,,Fajroŝtormo,Tormenta de Fuego,,Tulimyrsky,Tempête de Feu,Tűzvihar,Tempesta di fuoco,ファイアストーム,화염폭풍,Vuurstorm,Ildstorm,Burza Ognia,Tempestade-de-Fogo,,Furtună de Foc,Огненный шторм,Огњена олуја,Eldstorm,Ateş Fırtınası +Wraithverge Assembled,TXT_WEAPON_C4,,,,Složený Zjevitel,Spirit Bringer samlet,Geisterbringer komplettiert,,Fantomkruc' Muntita,Báculo Fantasmal Ensamblado,Vara Fantasmal Ensamblada,Haamusauva koottuna,Verge Phantasmale Assemblée,Bosszúbot Összerakva,Verga Sconfinaspettri assemblata,組み立てた レイスバージ,완성된 사령의 십자가,Schimroede in elkaar gezet,Wraithverge samlet,Złożony Widmoskraj,Cajado Fantasma Montado,,Toiag Stafie Asamblat,Жезл духов собран воедино,Жезло утвара је сабрано,Wraithverge monterad,Wraithverge Birleştirildi +Frost Shards,TXT_WEAPON_M2,,,,Ledové střepy,Frostskår,Frostsplitter,,Frostfragmentoj,Fragmentos de Escarcha,,Pakkassirpaleet,Eclats de Givre,Fagyos Szilánkok,Frantumi gelati,フロスト シャード,얼음 파편,Vorstscherven,Frostskår,Lodowe Odłamki,Fragmentos de Geada,,Cioburi de Gheață,Ледяные осколки,Ледене крхотине,Frostskärvor,Buz Kırıkları +Arc of Death,TXT_WEAPON_M3,,,,Jiskry smrti,Dødens bue,Todesblitz,,Arko de Morto,Arcos de la Muerte,,Kuolonkaari,Foudre Mortelle,Halál Boltíve,Arco della morte,死の円弧,죽음의 번갯불,Doodsboog,Dødens bue,Łuk Śmierci,Arcos da Morte,,Izvorul Morții,Дуга смерти,Лук смрти,Dödsbåge,Ölüm Arkı +Bloodscourge Assembled,TXT_WEAPON_M4,,,,Složený Krvehrom,Blodgisel samlet,Blutgeißel komplettiert,,Sangskurĝ' Muntita,Plaga Sangrienta ensamblada,,Veripiiska koottuna,Fléau Sanglant Assemblé,Vérkorbács Összerakva,Flagello di Sangue assemblato,組み立てた 天罰,완성된 피의 재앙,Bloedgesel in elkaar gezet,Bloodscourge samlet,Złożona Krwioplaga,Flagelo de Sangue Montado,,Flagel Sângeros Asamblat,Кровавый бич собран воедино,Крвави бич је сабран,Bloodscourge monterad,Bloodscourge Birleştirildi +A weapon piece! This is your lucky day!,TXT_WEAPONPIECE,,,,Část zbraně! Dnes je tvůj šťastný den!,Et våbenstykke! Dette er din heldige dag!,Ein Waffensegment. Das ist dein Glückstag!,,Peco de armilo! Estas via bonŝanca tago!,¡Una pieza de un arma! ¡Es tu día de suerte!,,Aseen osa! Tämä on onnenpäiväsi!,Une pièce d'arme! C'est votre jour de chance!,Egy fegyver darab! Szerencés napod van!,Il frammento di un'arma! È il tuo giorno fortunato! ,武器の一片! 今日は吉日だ!,무기의 한 조각이다! 운수 좋은 날인 것 같다!,Een wapenstuk! Dit is je geluksdag!,En våpendel! Dette er lykkedagen din!,Część broni! To twój szczęśliwy dzień!,Um fragmento de arma! Esse é o seu dia de sorte!,Um fragmento de arma! Este é o teu dia de sorte!,O piesă din super armă! E ziua ta norocoasă!,Часть оружия! Сегодня ваш счастливый день!,Део оружја! Данас Вам је срећан дан!,En vapendel! Detta är din lyckodag!,Bir silah parçası! Bugün şanslı gününüz! +Segment of Quietus,TXT_QUIETUS_PIECE,,,,Část Tišitele,Segment af Forløseren,Segment des Erlösers,,Segmento de Kvietus',Segmento de Quietus,,Quietuksen osa,Segment de Quietus,Darab a Némuszból,Parte del Quietus,死滅の剣の切片,종언의 검 조각,Segment van Quietus,Segment av Quietus,Fragment Uciszacza,Segmento de Quietus,,Fragment din Argumentul Final,Часть последнего довода,Део Самрти,Segment av Quietus,Quietus'un bir bölümü +Segment of Wraithverge,TXT_WRAITHVERGE_PIECE,,,,Část Zjevitele,Segment af Spirit Bringer,Segment des Geisterbringers,,Segmento de Fantomkruc',Segmento del Báculo Fantasmal,,Haamusauvan osa,Segment de la Verge Phantasmale,Darab a Bosszúbotból,Parte della Verga Sconfinaspettri,レイスバージの切片,사령의 십자가 조각,Segment van Schimroede,Segment av Wraithverge,Fragment Widmoskraju,Segmento do Cajado Fantasma,,Fragment din Toiagul Stafie,Часть жезла духов,Део Жезла утвара,Segment av Wraithverge,Wraithverge'in Segmenti +Segment of Bloodscourge,TXT_BLOODSCOURGE_PIECE,,,,Část Krvehromu,Segment af Blodgiselen,Segment der Blutgeißel,,Segmento de Sangskurĝ',Segmento de la Plaga Sangrienta,,Veripiiskan osa,Segment du Fléau Sanglant,Darab a Vérkorbácsból,Parte del Flagello di Sangue,天罰の切片,피의 재앙 조각,Segment van Bloedgesel,Segment av Bloodscourge,Fragment Krwioplagi,Segmento do Flagelo de Sangue,,Fragment din Flagelul Sângeros,Часть кровавого бича,Део Крвавог бича,Segment av Bloodscourge,Bloodscourge'un Segmenti +,,Locks,,,,,,,,,,,,,,,,,,,,,,,,, +You need the Steel Key,TXT_NEED_KEY_STEEL,,,,Potřebuješ ocelový klíč,Du skal bruge stålnøglen,Du brauchst den Stahlschlüssel,Χρειάζεσε το Ατσάλινο κλειδί.,Vi bezonas la Ŝtalan Ŝlosilon,Necesitas la Llave de Acero,,Tarvitset teräsavaimen,Vous avez besoin de la Clé d'Acier,Az Acél Kulcsra van szükséged,Ti serve la Chiave d'Acciaio,鋼の鍵が必要だ,강철 열쇠가 필요하다,Je hebt de Stalen Sleutel nodig.,Du trenger stålnøkkelen,Potrzebujesz Stalowego Klucza,Você precisa da Chave de Aço,Precisas da Chave de Aço,Ai nevoie de Cheia din Oțel,Нужен стальной ключ,За отварање је потребан челични кључ,Du behöver stålnyckeln.,Çelik Anahtara ihtiyacın var +You need the Cave Key,TXT_NEED_KEY_CAVE,,,,Potřebuješ klíč od jeskyně,Du skal bruge hulenøglen,Du brauchst den Höhlenschlüssel,,Vi bezonas la Kavern-Ŝlosilon,Necesitas la Llave de la Caverna,,Tarvitset luola-avaimen,Vous avez besoin de la Clé de la Cave,A Barlang Kulcsra van szükséged,Ti serve la Chiave della Caverna ,洞窟の鍵が必要だ,동굴 열쇠가 필요하다,Je hebt de Grotsleutel nodig.,Du trenger hulenøkkelen,Potrzebujesz Klucza do Jaskini,Você precisa da Chave da Caverna,Precisas da Chave da Caverna,Ai nevoie de Cheia Peșterii,Нужен пещерный ключ,За отварање је потребан пећински кључ,Du behöver grottnyckeln,Mağara Anahtarına ihtiyacın var +You need the Axe Key,TXT_NEED_KEY_AXE,,,,Potřebuješ sekyrový klíč,Du skal bruge øksenøglen,Du brauchst den Axtschlüssel,,Vi bezonas la Hakil-Ŝlosilon,Necesitas la Llave de Hacha,,Tarvitset kirvesavaimen,Vous avez besoin de la Clé de la Hache,A Fejsze Kulcsra van szükséged,Ti serve la Chiave dell'Ascia,斧の鍵が必要だ,도끼 열쇠가 필요하다,Je hebt de Bijlsleutel nodig.,Du trenger øksenøkkelen,Potrzebujesz Klucza-Topora,Você precisa da Chave do Machado,Precisas da Chave do Machado,Ai nevoie de Cheia Topor,Нужен ключ-топор,За отварање је потребан кључ секира,Du behöver yxnyckeln,Balta Anahtarına ihtiyacın var +You need the Fire Key,TXT_NEED_KEY_FIRE,,,,Potřebuješ ohnivý klíč,Du skal bruge brandnøglen,Du brauchst den Feuerschlüssel,,Vi bezonas la Fajro-Ŝlosilon,Necesitas la Llave de Fuego,,Tarvitset tuliavaimen,Vous avez besoin de la Clé du Feu,A Tűz Kulcsra van szükséged,Ti serve la Chiave del Fuoco ,炎の鍵が必要だ,불 열쇠가 필요하다,Je hebt de Vuursleutel nodig.,Du trenger Ildnøkkelen,Potrzebujesz Ognistego Klucza,Você precisa da Chave do Fogo,Precisas da Chave do Fogo,Ai nevoie de Cheia de Foc,Нужен огненный ключ,За отварање је потребан огњени кључ,Du behöver eldnyckeln,Ateş Anahtarına ihtiyacın var +You need the Emerald Key,TXT_NEED_KEY_EMERALD,,,,Potřebuješ smaragdový klíč,Du skal bruge smaragdnøglen,Du brauchst den Smaragdschlüssel,,Vi bezonas la Smeraldan Ŝlosilon,Necesitas la Llave Esmeralda,,Tarvitset smaragdiavaimen,Vous avez besoin de la Clé d'Emeraude,A Smaragd Kulcsra van szükséged,Ti serve la Chiave di Smeraldo ,翠玉の鍵が必要だ,에메랄드 열쇠가 필요하다,Je hebt de Smaragden Sleutel nodig.,Du trenger smaragdnøkkelen,Potrzebujesz Szmaragdowego Klucza,Você precisa da Chave Esmeralda,Precisas da Chave Esmeralda,Ai nevoie de Cheia din Smarald,Нужен изумрудный ключ,За отварање је потребан смарагдни кључ,Du behöver smaragdnyckeln,Zümrüt Anahtarı'na ihtiyacın var. +You need the Dungeon Key,TXT_NEED_KEY_DUNGEON,,,,Potřebuješ klíč od žaláře,Du skal bruge fangehulsnøglen,Du brauchst den Kerkerschlüssel,,Vi bezonas la Karcer-Ŝlosilon,Necesitas la Llave del Calabozo,,Tarvitset tyrmän avaimen,Vous avez besoin de la Clé du Donjon,A Várbörtön Kulcsra van szükséged,Ti serve la Chiave del Sotterraneo ,迷宮の鍵が必要だ,지하감옥 열쇠가 필요하다,Je hebt de Kerkersleutel nodig.,Du trenger fangehullsnøkkelen,Potrzebujesz Klucza do Lochu,Você precisa da Chave da Masmorra,Precisas da Chave das Masmorras,Ai nevoie de Cheia Temniței,Нужен ключ от подземелья,За отварање је потребан кључ од лагума,Du behöver Kerker-nyckeln,Zindan Anahtarına ihtiyacın var +You need the Silver Key,TXT_NEED_KEY_SILVER,,,,Potřebuješ stříbrný klíč,Du skal bruge sølvnøglen,Du brauchst den Silberschlüssel,Χρειάζεσε το Ασυμένιο κλειδί.,Vi bezonas la Arĝentan Ŝlosilon,Necesitas la Llave de Plata,,Tarvitset hopea-avaimen,Vous avez besoin de la Clé d'Argent,Az Ezüst Kulcsra van szükséged,Ti serve la Chiave d'Argento ,銀の鍵が必要だ,은 열쇠가 필요하다,Je hebt de Zilveren Sleutel nodig.,Du trenger sølvnøkkelen,Potrzebujesz Srebrnego Klucza,Você precisa da Chave de Prata,Precisas da Chave Prata,Ai nevoie de Cheia din Argint,Нужен серебряный ключ,За отварање је потребан сребрни кључ,Du behöver silvernyckeln,Gümüş Anahtara ihtiyacın var +You need the Rusted Key,TXT_NEED_KEY_RUSTED,,,,Potřebuješ zrezivělý klíč,Du skal bruge den rustne nøgle,Du brauchst den rostigen Schlüssel,Χρειάζεσε το Σκουριασμένο κλειδί.,Vi bezonas la Rustan Ŝlosilon,Necesitas la Llave Oxidada,,Tarvitset ruosteisen avaimen,Vous avez besoin de la Clé Rouillée,A Rozsdás Kulcsra van szükséged,Ti serve la Chiave Arrugginita ,錆びた鍵が必要だ,녹슨 열쇠가 필요하다,Je hebt de Geroeste Sleutel nodig.,Du trenger den rustne nøkkelen,Potrzebujesz Zardzewiałego Klucza,Você precisa da Chave Enferrujada,Precisas da Chave Enferrujada,Ai nevoie de Cheia Ruginită,Нужен ржавый ключ,За отварање је потребан зарђали кључ,Du behöver den rostade nyckeln,Paslı Anahtar'a ihtiyacın var. +You need the Horn Key,TXT_NEED_KEY_HORN,,,,Potřebuješ parožní klíč,Du skal bruge hornnøglen,Du brauchst den Hornschlüssel,,Vi bezonas la Hup-Ŝlosilon,Necesitas la Llave de Cuerno,,Tarvitset sarviavaimen,Vous avez besoin de la Clé Corne,A Szarv Kulcsra van szükséged,Ti serve la Chiave del Corno ,角の鍵が必要だ,뿔 열쇠가 필요하다,Je hebt de Hoornsleutel nodig.,Du trenger Horn-nøkkelen,Potrzebujesz Rogowego Klucza,Você precisa da Chave do Chifre,Precisas da Chave do Chifre,Ai nevoie de Cheia Corn,Нужен роговой ключ,За отварање је потребан рогати кључ,Du behöver hornnyckeln,Korna Anahtarına ihtiyacınız var +You need the Swamp Key,TXT_NEED_KEY_SWAMP,,,,Potřebuješ klíč od bažiny,Du skal bruge sumpnøglen,Du brauchst den Sumpfschlüssel,,Vi bezonas la Marĉ-Ŝlosilon,Necesitas la Llave del Pantano,,Tarvitset suoavaimen,Vous avez besoin de la Clé des Marécages,A Mocsár Kulcsra van szükséged,Ti serve la Chiave della Palude ,沼の鍵が必要だ,늪지대 열쇠가 필요하다,Je hebt de Moerassleutel nodig.,Du trenger Sump-nøkkelen,Potrzebujesz Bagiennego Klucza,Você precisa da Chave do Pântano,Precisas da Chave do Pântano,Ai nevoie de Cheia Mlaștinii,Нужен болотный ключ,За отварање је потребан мочварни кључ,Du behöver träsknyckeln,Bataklık Anahtarına ihtiyacın var. +You need the Castle Key,TXT_NEED_KEY_CASTLE,,,,Potřebuješ klíč od hradu,Du skal bruge slotsnøglen,Du brauchst den Burgschlüssel,,Vi bezonas la Kastel-Ŝlosilon,Necesitas la Llave del Castillo,,Tarvitset linnan avaimen,Vous avez besoin de la Clé du Château,A Kastély Kulcsra van szükséged,Ti serve la Chiave del Castello ,城の鍵が必要だ,성 열쇠가 필요하다,Je hebt de Kasteelsleutel nodig.,Du trenger slottsnøkkelen,Potrzebujesz Klucza do Zamku,Você precisa da Chave do Castelo,Precisas da Chave do Castelo,Ai nevoie de Cheia Castelului,Нужен ключ от замка,За отварање је потребан кључ од замка,Du behöver slottsnyckeln,Kale Anahtarına ihtiyacın var +,,Actor tag names,,,,,,,,,,,,,,,,,,,,,,,,, +Afrit,FN_FIREDEMON,,,,,,,,Afrito,,,,,,,アフリート,아프리트,Afriet,,,,,Demon de Foc,Африт,Африт,, +Serpent,FN_DEMON1,,,,Zlohad,Slange,Chaos-Schlange,,Serpento,Serpiente,,Käärme,,Kígyó,Serpente del Caos,サーペント,서펜트,Slang,Slangen,Wąż,Serpente,,Șarpe,Змей,Серпент,Ormen,Yılan +Ettin,FN_ETTIN,,,,Skřet,,,,Gigantaĉo,,,,,,,エティン,에틴,,,,,,Etin,Эттин,Етин,Ettin, +Centaur,FN_CENTAUR,,,,Kentaur,Kentaur,Zentaur,,Centaŭro,Centauro,,Kentauri,Centaure,Kentaur,Centauro,ケンタウロス,켄타우로스,Centaurus,Kentaur,,Centauro,,,Кентавр,Кентаур,Kentaur,Kentaur +Slaughtaur,FN_SLAUGHTAUR,,,,Ničitaur,Slagtaur,Schlachtaur,,Buĉataŭro,Masacratauro,,Teurastauri,Sangtaure,Vágtaur,Sventrauro,スロアタウル,슬로터로스,Slachttaurus,Slakttaur,Rzeziotaur,Chacinotauro,,Centaur Violent,Убитавр,Кентаур старешина,Slaktaur,Katlaur +Bishop,FN_BISHOP,,,,Biskup,Biskop,Bischof,,Episkopo,Obispo,,Piispa,Evèque,Érsek,Vescovo,ビショップ,비숍,Bisschop,Biskop,Biskup,Bispo,,Episcop,Епископ,Епископ,Biskop,Piskopos +Wendigo,FN_ICEGUY,,,,,,,,Vendiko,,,,,,,ウェンディゴ,윈디고,,,,,,Vendigo,Вендиго,Вендиго,, +Stalker,FN_SERPENT,,,,Slídil,,Wasserjäger,,Gvatanto,Acechador,,Vaanija,Chasseur,Orvhalász,Cacciatore,ストーカー,스토커,,,Prześladowca,Caçador,,Vânător,Преследователь,Вребач,, +Reiver,FN_WRAITH,,,,Přízrak,,Phantom,,Fantomo,Saqueador,,Ryöväri,,Martalóc,Incursore,レイバー,리버,Rover,,Rozbójnik,Fantasma,,Pungaș,Грабитель,Грабљивац,Reiver,Hayalet +Death Wyvern,FN_DRAGON,,,,Smrtidrak,Døden Wyvern,Todesdrache,,Morta viverno,Guiverno de la muerte,,Kuolontraakki,Vouivre de la Mort,A Halál Sárkánya,Viverna Mortale,デス ワイバーン,데스 와이번,Doodsdraak,Døden Wyvern,Wiwerna Śmierci,Serpe da Morte,,Balaur al Morții,Виверна смерти,Змајак смрти,Döds Wyvern,Ölüm Wyvern +Korax,FN_KORAX,,,,,,,,,,,Kooraks,,,,唯一神コラックス,코락스,,,,,,,Коракс,Коракс,, +Zedek,FN_FBOSS,,,,,,,,Zedeko,,,Sedek,,,,ゼデク,제닥,,,,,,,Зедек,Зедек,, +Menelkir,FN_MBOSS,,,,,,,,Menelkiro,,,Menelkir,,,,メネルキル,메넬키어,,,,,,,Менелкир,Менелкир,, +Traductus,FN_CBOSS,,,,Traduktus,,,,Traduktuso,,,Traduktus,,Traduktusz,,トラダクタス,트라닥투스,,,,,,,Традуктус,Традуктус,, +Heresiarch,FN_HERESIARCH,,,,Arcikacíř,Heresiark,Erzketzer,,Ĉefherezulo,Heresiarca,,Kerettiarkki,L'Hérésiarche,Főeretnek,Eresiarca,ヘレシアーク,헤러시아크,,Heresiark,Herezjarcha,Heresiarca,,Ereziarh,Ересиарх,Јересијарх,Heresiark,Heresiark +Blue Mana,AMMO_MANA1,,,,Modrá mana,Blå Mana,Blaues Mana,,Blua Manao,Maná azul,,Sininen mana,Mana Bleu,Kék Mana,Mana blu,ブルーマナ,청색 마나,Blauwe Mana,Blå Mana,Niebieska Mana,Mana Azul,,Mană Albastră,Синяя мана,Плава мана,Blå Mana,Mavi Mana +Green Mana,AMMO_MANA2,,,,Zelená mana,Grøn Mana,Grünes Mana,,Verda Manao,Maná verde,,Vihreä mana,Mana Vert,Zöld Mana,Mana verde,グリーンマナ,녹색 마나,Groene Mana,Grønn Mana,Zielona Mana,Mana Verde,,Mană Verde,Зелёная мана,Зелена мана,Grön Mana,Yeşil Mana +Mace of Contrition,TAG_CWEAPMACE,,,,Palcát kajícnosti,Stridskølle af anger,Streitkolben,,Klabo de Penteco,Maza de Contrición,,Katumuksen nuija,Masse de Pénitence,Bűnbánat Buzogánya,Mazza del Pentimento,懺悔のメイス,참회의 철퇴,Knots van Wroeging,Mace of Contrition,Buzdygan Skruchy,Maça da Contrição,,Buzduganul Remușcării,Булава раскаяния,Буздован покајања,Tystnadens stridsspira,Pişmanlık Topuzu +Serpent Staff,TAG_CWEAPSTAFF,,,,Hadí hůl,Slange-stav,Schlangenstab,,Serpentbastono,Bastón de Serpiente,,Käärmesauva,Sceptre du Serpent,Kígyó Bot,Staffa del Serpente ,蛇の杖,뱀 지팡이,Slangenstaf,Slangestav,Laska Węży,Cetro da Serpente,,Bastonul Șarpelui,Змеиный посох,Змијски штап,Ormens stav,Yılan Asa +Firestorm,TAG_CWEAPFLAME,,,,Ohnivá bouře,Ildstorm,Feuersturm,,Fajrŝtormo,Tormenta de Fuego,,Tulimyrsky,Tempête de Feu,Tűzvihar,Tempesta di Fuoco ,ファイアストーム,화염폭풍,Vuurstorm,Ildstorm,Burza Ognia,Tempestade-de-fogo,,Furtună de Foc,Огненный шторм,Огњена олуја,Eldstorm,Ateş Fırtınası +Wraithverge,TAG_CWEAPWRAITHVERGE,,,,Zjevitel,Spirit Bringer,Geisterbringer,,Fantomkruc',Báculo Fantasmal,,Haamusauva,Verge Phantasmale,Lidércvég,Verga SconfinaSpettri,レイスバージ,사령의 십자가,Schimroede,Wraithverge,Widmoskraj,Cajado Fantasma,,Toiag Stafie,Жезл духов,Жезло утвара,,Wraithverge +Spiked Gauntlets,TAG_FWEAPFIST,,,,Ohrocené rukavice,Spidse handsker,Stachelhandschuhe,,Pintaj Fergantoj,Guanteletes Puntiagudos,,Piikkirautakintaat,Gantelets à Pointes,Tűskés Páncélkesztyűk,Guantoni Spinati,スパイク ガントレット,가시 장갑,Spijkerhandschoenen,Pigghansker,Kolczaste Rękawice,Manoplas Espinhadas,,Mănuși cu Țepi,Шипастые перчатки,Бодљикаве рукавице,Spikade handskar,Çivili Eldivenler +Timon's Axe,TAG_FWEAPAXE,,,,Timonova sekera,Timons økse,Timons Axt,,Hakilo de Timon,Hacha de Timón,,Timonin kirves,Hache de Timon,Timon Baltája,Ascia di Timon,タイモンの斧,티몬의 도끼,Timon's Bijl,Timons øks,Topór Timona,Machado de Timon,,Toporul lui Timon,Топор Тимона,Тимонова секира,Timons yxa,Timon'un Baltası +Hammer of Retribution,TAG_FWEAPHAMMER,,,,Kladivo odplaty,Hævnens hammer,Hammer der Rache,,Martelo de Repago,Martillo de Retribución,,Koston vasara,Marteau de la Rétribution,Kárhozat Kalapácsa,Martello del Castigo,報復の金槌,징벌의 망치,Hamer van Vergelding,Gjengjeldelsens hammer,Młot Odkupienia,Martelo da Retribuição,,Ciocanul Salvării,Молот возмездия,Чекић одмазде,Hämndhammaren,İntikam Çekici +Quietus,TAG_FWEAPQUIETUS,,,,Tišitel,Forløser,Erlöser,,Kvietus',,,,Quietus,Némusz,,死滅の剣,종언의 검,,,Uciszacz,,,Argument Final,Последний довод,Самрт,, +Sapphire Wand,TAG_MWEAPWAND,,,,Safírová hůl,Safir-stav,Saphirstab,,Safirsorĉbastono,Varita de Zafiro,,Safiirisauva,Baguette de Saphir,Zafír Pálca,Scettro di Zaffiro ,サファイア ワンド,사파이어 지팡이,Saffieren Toverstok,Safirstaven,Szafirowa Różdżka,Cetro de Safira,,Toiag cu Safir,Сапфировая волшебная палочка,Сафирни штап,Safirstav,Safir Değnek +Frost Shards,TAG_MWEAPFROST,,,,Ledové střepy,Frostskår,Frostsplitter,,Frostfragmentoj,Fragmentos de Escarcha,,Pakkassirpaleet,Eclats de Givre,Fagyos Szilánkok,Schegge di Ghiaccio ,フロスト シャード,얼음 파편,Vorstscherven,Frostskår,Lodowe Odłamki,Fragmentos de Geada,,Cioburi de Gheață,Замораживающие осколки,Ледене крхотине,Frostskärvor,Buz Kırıkları +Arcs of Death,TAG_MWEAPLIGHTNING,,,,Jiskry smrti,Dødens buer,Todesblitz,,Arkoj de Morto,Arcos de la Muerte,,Kuolonkaaret,Foudre Mortelle,Halál Boltíve,Archi della Morte ,死の円弧,죽음의 번갯불,Doodsboog,Dødens buer,Łuki Śmierci,Arcos da Morte,,Izvoarele Morții,Дуга смерти,Лук смрти,Dödsbågar,Ölüm Yayları +Bloodscourge,TAG_MWEAPBLOODSCOURGE,,,,Krvehrom,Blodgisel,Blutgeißel,,Sangskurĝ',Plaga Sangrienta,,Veripiiska,Fléau Sanglant,Vérkorbács,Flagello di Sangue,天罰,피의 재앙,Bloedgesel,,Krwioplaga,Flagelo de Sangue,,Flagel Sângeros,Кровавый бич,Крвави бич,, +Disc of Repulsion,TAG_ARTIBLASTRADIUS,,,,Kotouč odpuzení,Afstødningsskive,Rückstoßscheibe,,Disko de Repelado,Disco de Repulsión,,Karkotuskiekko,Disque de Répulsion,Visszaverő Pajzs,Disco della Repulsione ,反発の円盤,방탄의 원반,Schijf van Afstoting,Frastøtelsens skive,Dysk Odpychania,Disco da Repulsão,,Disc al Repulsiei,Диск отторжения,Диск одбијања,Skiva av avstötning,İtme Diski +Dragonskin Bracers,TAG_ARTIBOOSTARMOR,,,,Dračí nátepníky,Drageskindsarmbøjler,Drachenhaut-Armschutz,,Brakbendo el Drakhaŭto,Brazaletes de piel de Dragón,,Lohikäärmeennahkarannesuojat,Brassards en peau de Dragon,Sárkánybőr Karkötők,Bracciali in Pelle di Drago ,竜皮の小手,용가죽 팔찌,Drakenhuidbescherming,Dragehud-bindinger,Karwasze ze Smoczej Skóry,Braçadeiras de Pele de Dragão,,Brățări din Piele de Dragon,Наручи драконьей кожи,Наруквице од змајеве коже,Drakskinnsarmband,Ejderha Derisi Bilezikler +Krater of Might,TAG_ARTIBOOSTMANA,,,,Kalich síly,Kraftens bæger,Kelch der Macht,,Kratero de Potenco,Crátera de Poder,,Mahtikrateeri,Cratère de Pouvoir,Hatalom Kráterje,Calice della Forza,魔力の盃,힘의 향로,Beker van Macht,Krater av makt,Czara mocy,Cálice do Poder,,Pocal al Puterii,Кубок могущества,Чаша силе,Mäktighetens krater,Kudret Krateri +Flechette,TAG_ARTIPOISONBAG,,,,Střelka,,,,Flakono,,,,Fléchette,Nyílhegy,Fiaschetta ,フレシェット,플레셰트,,,Flaszka,,,Flacon,Флешетта,Бочица,, +Poison Cloud Flechette,TAG_ARTIPOISONBAG1,,,,Otrávená střelka,Flechette (giftig sky),Flechette (Giftwolke),,Venennub-Flakono,Flechette de Nube Venenosa,,Myrkkypilviflechette,Fléchette - Nuage Toxique,Méregfelhő hegy,Fiaschetta Velenosa,毒ガス フレシェット,독구름 플레셰트,Flechette (giftige wolk),Giftsky-flechette,Flaszka Trującej Chmury,Flechette de Nuvem Venenosa,,Flacon cu Otravă,Флешетта ядовитого облака,Бочица отровног облака,Flechette med giftmoln,Zehirli Bulut Flechette +Timebomb Flechette,TAG_ARTIPOISONBAG2,,,,Časovaná střelka,Flechette (tidsbombe),Flechette (Zeitbombe),,Horloĝbomb-Flakono ,Bomba de Tiempo Flechette,,Aikapommiflechette,Fléchette - Bombe a Retardement,Időbomba hegy,Fiaschetta a Tempo ,時限爆弾フレシェット,시한폭탄 플레셰트,Flechette (tijdbom),Tidsbombe Flechette,Flaszka-Bomba Zegarowa,Flechette Bomba-Relógio,,Bombă cu Ceas,Флешетта часовой бомбы,Бочица временске бомбе,Tidsbomb Flechette,Saatli bomba Flechette +Grenade Flechette,TAG_ARTIPOISONBAG3,,,,Granátová střelka,Flechette (granat),Flechettre (Granate),,Grenad-Flakono,Granada Flechette,,Kranaattiflechette,Fléchette - Grenade,Robbanó hegy,Fiaschetta da Lancio,グレネードフレシェット,폭발성 플레셰트,Flechette (granaat),Granat Flechette,Flaszka-Granat,Flechette Granada,,Flacon-Grenadă,Гранатная флешетта ,Бочица граната,Granat Flechette,El Bombası Flechette +Mystic Ambit Incant,TAG_ARTIHEALINGRADIUS,,,,Tajemný čár koljdoucí,,,,Sorĉo de Mistika Sfero,Encantamiento de Ámbito Místico,,Mystisen piirin loitsu,Incantation Mystique,Misztikus Mágialista,Incantamento Mistico ,魅知国の秘法,신비 영역의 주문,,,Inkantancja Mistycznego Kręgu,Encantamento Místico,,Pergament Mistic,Мистический зачарованный свиток,Чаролија магичног јединства,,Mistik Ambit Büyüsü +Icon of the Defender,TAG_ARTIDEFENDER,,,,Obráncova ikona,Ikon af forsvareren,Ikone des Verteidigers,,Ikono de la Defendanto,Icono del Defensor,Ícono del Defensor,Puolustajan ikoni,Icône du Défenseur,Védelmező Ikonja,Emblema del Difensore ,守護者の像,수호의 성상,,Forsvarerens ikon,Ikona Obrońcy,Ícone do Defensor,,Imaginea Apărătorului,Символ защитника,Симбол браниоца,Försvararens ikon,Savunucunun Simgesi +Porkalator,TAG_ARTIPORK,,,,Vepřovitel,,,,Porkigilo,Porcinador,,Sikaannuttaja,Porcificateur,Ártányátok,Porchificatore,ポークレイター,돈육기,,,Schabowator,Porquificador,,Porcolator,Свиновизатор,Свињатор,, +Boots of Speed,TAG_ARTISPEED,,,,Běhuté boty,Støvler af hastighed,Turbo-Stiefel,,Botoj de Rapideco,Botas de Velocidad,,Ripeyssaappaat,Bottes de Célérité,Sebesség Cipői,Stivali della Fretta,素早さの靴,속도의 부츠,Snelheidslaarzen,Støvler av fart,Buty Szybkości,Botas da Rapidez,,Bocancii Vitezei,Сапоги-скороходы,Брзинске чизме,Stövlar av snabbhet,Hız Çizmeleri +Dark Servant,TAG_ARTISUMMON,,,,Temný služebník,Mørk tjener,Dunkler Diener,,Malluma Servanto,Servidor Oscuro,,Pimeä palvelija,Serviteur Noir,Árny Szolga,Servo Oscuro,闇の従者,어둠의 하인,Donkere Dienaar,Mørk tjener,Mroczny Sługa,Servo Negro,,Servitor Întunecat,Тёмный слуга,Мрачни слуга,Mörk tjänare,Karanlık Hizmetkar +Banishment Device,TAG_ARTITELEPORTOTHER,,,,Vyhošťovač,Forvisningsanordning,Verbannungsgerät,,Forpelilo,Dispositivo de Destierro,,Häivytyskoje,Outil de Banissement,Számüzető Szerkentyű,Congegno dell'Esilio,追放のデバイス,소멸 장치,Verbanningsapparaat,Forvisningsinnretning,Urządzenie Wygnania ,Dispositivo do Banimento,,Dispozitiv al Alungării,Механизм изгнания,Амблем прогањања,Förvisningsenhet,Sürgün Cihazı +Yorick's Skull,TAG_ARTIPUZZSKULL,,,,Jorikova lebka,Yoricks kranium,Yoricks Schädel,,Kranio de Yorick,Calavera de Yorick,Cráneo de Yorick,Yorickin kallo,Crâne de Yorick,Yorick Koponyája,Teschio di Yorick,ヨリックの髑髏,요릭의 두개골,Yorick's Schedel,Yoricks hodeskalle,Czaszka Yoricka,Crânio de Yorick,,Craniul lui Yorick,Череп Йорика,Јорикова лобања,Yoricks skalle,Yorick'in Kafatası +Heart of D'Sparil,TAG_ARTIPUZZGEMBIG,,,,Srdce D'Sparila,D'Sparils hjerte,D'Sparils Herz,,Koro de D'Sparil,Corazón de D'Sparil,,D'Sparilin sydän,Cœur de D'Sparil,D'Sparil Szíve,Cuore di D'Sparil,デ'スパリルの心,드'스파릴의 심장,Hart van D'Sparil,D'Sparils hjerte,Serce D'Sparila,Coração de D'Sparil,,Inima lui D'Sparil,Сердце Д'Спарила,Д'Спарилово срце,D'Sparils hjärta,D'Sparil'in Kalbi +Ruby Planet,TAG_ARTIPUZZGEMRED,,,,Rubínová planeta,Rubinplanet,Rubinplanet,,Rubena Planedo,Planeta Rubí,,Rubiiniplaneetta,Planète en rubis,Rubin Bolygó,Pianeta di Rubino,ルビーの宝石,루비 행성석,Robijnrode Planeet,Rubinplaneten,Rubinowa Planeta,Planeta Rubi,,Planetă din Rubin,Рубиновая планета,Планета рубина,Rubinplanet,Yakut Gezegeni +Emerald Planet (1),TAG_ARTIPUZZGEMGREEN1,,,,Smaragdová planeta (1),Smaragdplanet (1),Smaragdplanet (1),,Smeralda Planedo (1),Planeta Esmeralda (1),,Smaragdiplaneetta (1),Planète en émeraude (1),Smaragd Bolygó (1),Pianeta di Smeraldo (1),エメラルドの宝石1,에메랄드 행성석 (1),Smaragdgroene Planeet (1),Smaragdplaneten (1),Szmaragdowa Planeta (1),Planeta Esmeralda (1),,Planetă din Smarald (1),Изумрудная планета (1),Смарагдна планета (1),Smaragdplanet (1),Zümrüt Gezegen (1) +Emerald Planet (2),TAG_ARTIPUZZGEMGREEN2,,,,Smaragdová planeta (2),Smaragdplanet (2),Smaragdplanet (2),,Smeralda Planedo (2),Planeta Esmeralda (2),,Smaragdiplaneetta (2),Planète en émeraude (2),Smaragd Bolygó (2),Pianeta di Smeraldo (2),エメラルドの宝石2,에메랄드 행성석 (2),Smaragdgroene Planeet (2),Smaragdplaneten (2),Szmaragdowa Planeta (2),Planeta Esmeralda (2),,Planetă din Smarald (2),Изумрудная планета (2),Смарагдна планета (2),Smaragdplanet (2),Zümrüt Gezegen (2) +Sapphire Planet (1),TAG_ARTIPUZZGEMBLUE1,,,,Safírová planeta (1),Safirplanet (1),Saphirplanet (1),,Safira Planedo (1),Planeta Zafiro (1),,Safiiriplaneetta (1),Planète en saphir (1),Zafír Bolygó (1),Pianeta di Zaffiro (1),サファイアの宝石1,사파이어 행성석 (1),Saffierblauwe Planeet (1),Safirplaneten (1),Szafirowa Planeta (1),Planeta Safira (1),,Planetă din Safir (1),Сапфировая планета (1),Сафирна планета (1),Safirplanet (1),Safir Gezegen (1) +Sapphire Planet (2),TAG_ARTIPUZZGEMBLUE2,,,,Safírová planeta (2),Safirplanet (2),Saphirplanet (2),,Safira Planedo (2),Planeta Zafiro (2),,Safiiriplaneetta (2),Planète en saphir (2),Zafír Bolygó (2),Pianeta di Zaffiro (2),サファイアの宝石2,사파이어 행성석 (2),Saffierblauwe Planeet (2),Safirplaneten (2),Szafirowa Planeta (2),Planeta Safira (2),,Planetă din Safir (2),Сапфировая планета (2),Сафирна планета (2),Safirplanet (2),Safir Gezegen (2) +Daemon Codex,TAG_ARTIPUZZBOOK1,,,,,,,,Kodekso de Demono,Códice del Demonio,,Daemon-koodeksi,Codex Démoniaque,Démon Kódex,Codice Demoniaco ,デーモンの写本,악마의 고문서,,,Demoniczny Kodeks,Códice Demoníaco,,Codexul Demonilor,Демонический кодекс,Демонски кодекс,, +Liber Oscura,TAG_ARTIPUZZBOOK2,,,,,,,,Liber Oscura,Liber Oscura,,,,,,オスキュラ公文書,어둠의 자유서,,,Liber Oscura,,,Liber Obscura,Либер Оскура,Либер Оскура,, +Flame Mask,TAG_ARTIPUZZSKULL2,,,,Plamenná maska,Flamme-maske,Flammenmaske,,Fajrmasko,Mascara de Llamas,Mascara de Flamas,Liekkinaamio,Masque de Flammes,Láng Maszk,Maschera delle Fiamme ,炎の仮面,화염의 가면,Vuurmasker,Flammemaske,Maska Płomieni,Máscara das Chamas,,Mască de Foc,Маска пламени,Маска пламена,Flam-Mask,Alev Maskesi +Glaive Seal,TAG_ARTIPUZZFWEAPON,,,,Glévská pečeť,Sværdsegl,Schwertsiegel,,Sigelo de Glavo,Sello de Espada,,Miekkasinetti,Sceau du Glaive,Pallos Pecsét,Sigillo del Brando,グレイブシール,밀폐된 칼날,Lanszegel,Glaive segl,Pieczęć Glewii,Selo do Gládio,,Sigiliu Spadă,Печать воителя,Војников печат,Glasögonsegel,Glaive Mühür +Holy Relic,TAG_ARTIPUZZCWEAPON,,,,Svatá relikvie,Hellig relikvie,Heiliges Relikt,,Sankta Relikvo,Santa Reliquia,,Pyhä reliikki,Relique Sacrée,Szent Ereklye,Reliquia Sacra,聖遺物,신성한 유물,Heilige Relikwie,Hellig relikvie,Święta Relikwia,Relíquia Sagrada,,Relicvă Sfântă,Святая реликвия,Света реликвија,Heliga reliker,Kutsal Emanet +Sigil of the Magus,TAG_ARTIPUZZMWEAPON,,,,Mágovo sigilium,Magus' segl,Symbol des Magiers,,Sigelo de la Mago,Emblema del Mago,,Taikurin sinetti,Sceau du Mage,Mágus Pecsétje,Suggello del Magus,メイガスの印章,마거스의 인장,Sigaar van de Magus,Magusens segl,Emblemat Maga,Sígilo do Mago,,Sigiliul Magului,Печать Мага,Чаробњаков симбол,Magikerns sigill,Büyücünün Sigil'i +Iron gear,TAG_ARTIPUZZGEAR1,,,,Železné kolečko,Tandhjul af jern,Eisenzahnrad,,Fera Dentrado,Engranaje de Hierro,,Rautaratas,Engrenage en Fer,Vas Felszerelés,Ingranaggio di Ferro,鉄の歯車,양철 톱니바퀴,IJzeren uitrusting,Jernutstyr,Żelazna Zębatka,Engrenagem de ferro,,Mecanism din fier,Железная шестерня,Гвожђени зупчаник,Kugghjul av järn,Demir dişli +Brass gear,TAG_ARTIPUZZGEAR2,,,,Mosazné kolečko,Tandhjul i messing,Messingzahnrad,,Latuna Dentrado,Engranaje de Bronce,,Messinkiratas,Engrenage en Bronze,Réz Felszerelés,Ingranaggio di Ottone ,真鍮のギア,황동 톱니바퀴,Messing uitrusting,Utstyr av messing,Mosiężna Zębatka,Engrenagem de latão,,Mecanism din alamă,Латунная шестерня,Месингани зупчаник,Kugghjul av mässing,Pirinç dişli +Brass and iron gear,TAG_ARTIPUZZGEAR3,,,,Mosazno-železné kolečko,Tandhjul af messing og jern,Messing-und-Eisen-Zahnrad,,Latuna Fera Dentrado,Engranaje de Bronce y Hierro,,Messinki- ja rautaratas,Engrenage en Fer et Bronze,Vas és Réz Felszerelés,Ingranaggio di Ferro e Ottone ,鉄と真鍮のギア,황동과 양철 톱니바퀴,Messing en ijzeren uitrusting,Utstyr av messing og jern,Zębatka z mosiądzu i żelaza,Engrenagem de ferro e latão,,Mecanism din alamă și fier,Латунно-железная шестерня,Месинганoгвожђени зупчаник,Kugghjul av mässing och järn,Pirinç ve demir dişli +Silver and brass gear,TAG_ARTIPUZZGEAR4,,,,Stříbro-mosazné kolečko,Tandhjul af sølv og messing,Silber-und-Messing-Zahnrad,,Arĝenta Latuna Dentrado,Engranaje de Plata y Bronce,,Hopea- ja messinkiratas,Engrenage en Argent et Bronze,Ezüst és Réz Felszerelés,Ingranaggio di Ottone e Argento ,銀と真鍮のギア,은과 황동 톱니바퀴,Zilveren en messing uitrusting,Utstyr av sølv og messing,Zębatka ze srebra i mosiądzu,Engrenagem de prata e latão,,Mecanism din argint și alamă,Серебряно-латунная шестерня,Сребрномесигани зупчаник,Kugghjul av silver och mässing,Gümüş ve pirinç dişli +,,Obituaries,,,,,,,,,,,,,,,,,,,,,,,,, +%o tasted an Afrit's fire.,OB_FIREDEMON,,,,%o okusil@[ao_cs] afritův oheň.,%o smagte en afrits ild.,%o spürte das Feuer des Afrits.,,%o gustis la fajron de Afrito.,%o ha probado el fuego de un Afrit.,%o probó el fuego de un Afrit.,%o maistoi afritin tulta.,%o a goûté au feu d'un Afrit.,%o megkóstolta a Tűz Szellem parazsát.,%o ha assaggiato il fuoco di un Afrit. ,%o はアフリートの炎を味わった。,%o 은(는) 아프리트의 화염을 맛봤다.,%o proefde het vuur van een Afriet.,%o smakte en Afrits ild.,%o spróbował@[ao_pl] ognia Afrita.,%o provou o fogo de um Afrit.,,%o a gustat flacăra Demonului de Foc.,Игрок %o отведал огня африта.,%o је окуси@[ao_1_sr] Афритов огањ.,%o smakade en Afrits eld.,%o bir Afrit'in ateşini tattı. +%o was scalded by a Serpent.,OB_DEMON1,,,,%o byl@[ao_cs] upálen@[ao_cs] zlohadem.,%o blev skoldet af en slange.,%o wurde von der Chaos-Schlange gebissen.,,%o brogiĝis de Serpento.,A %o l@[ao_esp] ha calcinado una Serpiente.,A %o l@[ao_esp] calcinó una Serpiente.,%o joutui käärmeen kalttaamaksi.,%o a été brûlé@[e_fr] par un Serpent.,%o testét leforrázta egy Kígyó,%o è stato sciolto da un Serpente del Caos,%o はサーペントに火傷を負わされた。,%o 은(는) 서펜트에 데였다.,%o werd gebroeid door een Slang.,%o ble skåldet av en slange.,%o został@[ao_pl] poparzon@[adj_pl] przez Węża.,Uma Serpente escaldou %o.,,%o a fost opărit de un Șarpe.,Игрока %o спален змеем.,Играча %o је спалио Серпент.,%o blev skållad av en orm.,%o bir yılan tarafından haşlandı. +%o was poisoned by a Serpent.,OB_DEMON2,,,,%o byl@[ao_cs] otráven@[ao_cs] zlohadem.,%o blev forgiftet af en slange.,%o wurde von der Chaos-Schlange verbrannt.,,%o veneniĝis de Serpento.,A %o l@[ao_esp] ha envenenado una Serpiente.,A %o l@[ao_esp] envenenó una Serpiente.,%o joutui käärmeen myrkyttämäksi.,%o a été empoisonné@[e_fr] par un Serpent.,%o vérébe mérget juttatott egy Kígyó,%o è stato avvelenato da un Serpente del Caos. ,%o はサーペントの毒にやられた。,%o 은(는) 독 서펜트에게 중독 당했다.,%o werd vergiftigd door een Slang.,%o ble forgiftet av en slange.,%o został@[ao_pl] zatrut@[adj_pl] przez Węża.,%o foi envenenad@[ao_ptb] por uma Serpente.,,%o a fost otrăvit de un Șarpe.,Игрока %o отравлен змеем.,Играча %o је отровао Серпент.,%o blev förgiftad av en orm.,%o bir yılan tarafından zehirlendi. +%o was mashed by an Ettin.,OB_ETTIN,,,,%o byl@[ao_cs] umlácen@[ao_cs] skřetem.,%o blev moset af en Ettin.,%o wurde von dem Ettin zermatscht.,,%o frakasiĝis de Gigantaĉo.,%o ha quedado hech@[ao_esp] puré por un Ettin.,%o quedó hech@[ao_esp] puré por un Ettin.,%o joutui ettinin muhentamaksi.,%o a été réduit@[e_fr] en purée par un Ettin.,%o csillagokat lát az Ettin miatt.,%o è stato schiacciato da un Ettin. ,%o はエティンに潰された。,%o 은(는) 에틴에게 철퇴를 맞았다.,%o werd gepureerd door een Ettin.,%o ble knust av en Ettin.,%o został@[ao_pl] stłuczon@[adj_pl] przez Ettina.,%o foi feito purê por um Ettin.,,%o a fost făcut piure de un Etin.,Игрока %o раздробил эттин.,Играча %o је смрскао Еттин.,%o blev mosad av en Ettin.,%o bir Ettin tarafından ezildi. +%o was cut up by a Centaur.,OB_CENTAUR,,,,%o byl@[ao_cs] rozsekán@[ao_cs] kentaurem.,%o blev skåret op af en kentaur.,%o wurde von dem Zentaur aufgeschlitzt.,,%o distranĉiĝis de Centaŭro.,A %o l@[ao_esp] ha partido un Centauro.,A %o l@[ao_esp] partió un Centauro.,%o joutui kentaurin pilkkomaksi.,%o a été tranché@[e_fr] par un Centaure.,%o fel lett vágva a Kentaur jóvoltából.,%o è stato affettato da un Centauro. ,%o はケンタウロスに切り刻まれた。,%o 은(는) 켄타우로스에 의해 절단됐다.,%o werd versneden door een Centaurus.,%o ble kuttet opp av en Kentaur.,%o został@[ao_pl] pocięt@[adj_pl] przez Centaura.,%o foi fatiad@[ao_ptb] por um Centauro.,,%o a fost tăiat deschis de un Centaur.,Игрока %o разрезал кентавр.,Играча %o је расекао Кентаур.,%o blev styckad av en Kentaur.,%o bir Kentaur tarafından kesildi. +%o was cut up by a Slaughtaur.,OB_SLAUGHTAURHIT,,,,%o byl@[ao_cs] rozsekán@[ao_cs] ničitaurem.,%o blev skåret op af en slagtaur.,%o wurde von dem Schlachtaur aufgeschlitzt.,,%o distranĉiĝis de Buĉataŭro.,A %o l@[ao_esp] ha partido un Masacratauro.,A %o l@[ao_esp] partió un Masacratauro.,%o joutui teurastaurin pilkkomaksi.,%o a été tranché@[e_fr] par un Sangtaure.,%o nagyon felvágott és a Vágtaur is a játékost,%o è stato affettato da uno Sventrauro. ,%o はスロアタウルに切り刻まれた。,%o 은(는) 슬로터로스에 의해 심하게 절단됐다.,%o werd versneden door een Slachtaurus.,%o ble kuttet opp av en Slakttaur.,%o został@[ao_pl] pocięt@[adj_pl] Rzeziotaura.,%o foi fatiad@[ao_ptb] por um Chacinotauro.,,%o a fost tăiat deschis de un Centaur Violent.,Игрока %o разрезал убитавр.,Играча %o је расекао Кентаур старешина.,%o blev styckad av en Slaktaur.,%o bir Katlaur tarafından kesildi. +%o was struck down by a Slaughtaur's fireball.,OB_SLAUGHTAUR,,,,%o byl@[ao_cs] zabit@[ao_cs] ničitaurovou ohnivou koulí.,%o blev slået ned af en slagtauras ildkugle.,%o wurde von dem Feuerball des Schlachtaurs niedergestreckt.,,%o subite mortiĝis de fajropilko de Buĉataŭro.,A %o l@[ao_esp] ha abatido la bola de fuego de un Masacratauro.,A %o l@[ao_esp] derribó la bola de fuego de un Masacratauro.,%o joutui teurastaurin tulipallon kaatamaksi.,%o a été touché@[e_fr] par une boule de feu de Sangtaure.,%o másodfokú égési sérüléseket szenvedett el a Vágtaur tűzgolyójától.,%o è stato abbattuto dalla palla di fuoco di uno Sventrauro. ,%o はスロアタウルの火玉に倒された。,%o 은(는) 슬로터로스의 마법구에 의해 피격당했다.,%o werd neergeslagen door een Slachtaurus' vuurbal.,%o ble truffet av en Slakttaurs ildkule.,%o został@[ao_pl] trafion@[adj_pl] przez kulę ognia Rzeziotaura.,%o foi abatid@[ao_ptb] pela bola de fogo de um Chacinotauro.,,"%o a fost răpus de mingea de foc a unui Centaur +Violent.",Игрока %o сбил огненным шаром убитавр.,Играча %o је огњеном куглом оборио Кентаур старешина.,%o blev nedslagen av en Slauktaurs eldklot.,%o bir Katlaur'un ateş topuyla vuruldu. +%o succumbed to a Bishop's dark power.,OB_BISHOP,,,,%o podlehl@[ao_cs] biskupově temné moci.,%o bukkede under for en biskops mørke kraft.,%o fiel der dunklen Macht des Bischofs zum Opfer.,,%o subfaliĝis de malluma potenco de Episkopo.,%o ha sucumbido ante el poder oscuro de un Obispo.,%o sucumbió ante el poder oscuro de un Obispo.,%o lankesi piispan pimeään voimaan.,%o a succombé au pouvoir obscur d'un évèque.,%o megadta magát a Püspök sötét erejének,%o è stato sottomesso dalla magia oscura di un Vescovo. ,%o はビショップの闇の力に屈した。,%o 은(는) 비숍의 힘에 무릎을 꿇었다.,%o bezweek aan de donkere kracht van een Bisschop.,%o bukket under for en Biskops mørke kraft.,%o uległ@[ao_pl] mrocznej mocy Biskupa.,%o sucumbiu ao poder negro de um Bispo.,,%o a cedat puterii întunecate a Episcopului.,Игрок %o поддался чёрным силам Епископа.,%o је подлег@[ao_2_sr] Епископовим црним силама.,%o gav efter för en biskops mörka kraft.,%o bir Piskopos'un karanlık gücüne yenik düştü. +%o was frozen solid by a Wendigo.,OB_ICEGUY,,,,%o byl@[ao_cs] zamrznut@[ao_cs] wendigem.,%o blev frosset fast af en wendigo.,%o wurde von dem Wendigo tiefgefroren.,,%o tute frostiĝis de Vendiko.,A %o l@[ao_esp] ha congelado un Wendigo.,A %o l@[ao_esp] congeló un Wendigo.,%o joutui wendigon läpikotaisin jäädyttämäksi.,%o a été gelé@[e_fr] par un Wendigo.,%o testét keményre fagyasztotta egy Wendigo,%o è stato congelato da un Wendigo. ,%o はウェンディゴによって固められた。,%o 은(는) 윈디고에 의해 단단하게 얼려졌다.,%o werd bevroren door een Wendigo.,%o ble frosset fast av en Wendigo.,%o został@[ao_pl] zamrożon@[adj_pl] przez Wendigo.,%o foi congelad@[ao_ptb] por um Wendigo.,,%o a fost făcut statuie de un Vendigo.,Игрока %o полностью заморозил вендиго.,Играча %o је потпуно замрзнуо Вендиго.,%o blev frusen av en Wendigo.,%o bir Wendigo tarafından kaskatı donduruldu. +%o was mauled by a Stalker.,OB_SERPENTHIT,,,,%o byl@[ao_cs] umlácen@[ao_cs] slídilem.,%o blev mast af en stalker.,%o wurde von dem Wasserjäger zerfleischt.,,%o vundegiĝis de Gvatanto.,A %o l@[ao_esp] ha triturado un Acechador.,A %o l@[ao_esp] trituró un Acechador.,%o joutui vaanijan raatelemaksi.,%o a été mutilé@[e_fr] par un Chasseur.,%o szét lett marcangolva egy Orhalász által.,%o è stato malmenato da un Cacciatore. ,%o はストーカーに引っ掻かれた。,%o 은(는) 스토커에게 발렸다.,%o werd verminkt door een Stalker.,%o ble maltraktert av en Stalker.,%o został@[ao_pl] poturbowan@[adj_pl] przez Prześladowcę.,%o foi mutilad@[ao_ptb] por um Caçador.,,%o a fost sfâșiat de un Vânător.,Игрок %o покусан преследователем.,Играча %o је растргао Вребач.,%o blev söndersliten av en Stalker.,%o bir Stalker tarafından parçalandı. +%o was melted by a Stalker.,OB_SERPENT,,,,%o byl@[ao_cs] rozpuštěn@[ao_cs] slídilem.,%o blev smeltet af en stalker.,%o wurde von dem Wasserjäger geschmolzen.,,%o fandiĝis de Gvatanto.,A %o l@[ao_esp] ha derretido un Acechador.,A %o l@[ao_esp] derritió un Acechador.,%o joutui vaanijan sulattamaksi.,%o a été fondu@[e_fr] par un Chasseur.,%o csontjairól a húst leolvasztotta egy Orvhalász,%o è stato squagliato da un Cacciatore. ,%o はストーカーに溶かされた。,%o 은(는) 스토커에 의해 녹았다.,%o werd gesmolten door een Stalker.,%o ble smeltet av en Stalker.,%o został@[ao_pl] stopion@[adj_pl] przez Prześladowcę.,%o foi derretid@[ao_ptb] por um Caçador.,,%o a fost topit de un Vânător.,Игрока %o расплавил преследователь.,Играча %o је растопио Вребач.,%o blev smält av en Stalker.,%o bir Takipçi tarafından eritildi. +%o was charred by a Reiver.,OB_WRAITH,,,,%o byl@[ao_cs] zpopelněn@[ao_cs] přízrakem.,%o blev forkullet af en reiver.,%o wurde von dem Phantom verkohlt.,,%o brulegiĝis de Fantomo.,A %o l@[ao_esp] ha carbonizado un Saqueador.,A %o l@[ao_esp] carbonizó un Saqueador.,%o joutui ryövärin hiiltämäksi.,%o a été carbonisé@[e_fr] par un Reiver.,%o testét egy Martalóc elszenesítette.,%o è stato carbonizzato da un Incursore. ,%o はレイバーに黒焦げにされた。,%o 은(는) 리버에 의해 그슬렸다.,%o werd verbrand door een Rover.,%o ble forkullet av en Reiver.,%o został@[ao_pl] zwęglon@[adj_pl] przez Rozbójnika.,%o foi carbonizad@[ao_ptb] por um Fantasma.,,%o a fost ceruit de un Pungaș.,Игрока %o обуглил грабитель.,Играча %o је угљенисао Вребач.,%o blev förkolnad av en Reiver.,%o bir Hayalet tarafından yakıldı. +%o had %p life stolen by a Reiver.,OB_WRAITHHIT,,,,%o si nechal@[ao_cs] ukradnout život přízrakem.,%o fik sit liv stjålet af en reiver.,%o wurde das Leben von dem Phantom gestohlen.,,%o havis sian vivon ŝtelita de Fantomo.,A %o le ha robado la vida un Saqueador.,A %o le robó la vida un Saqueador.,Ryöväri riisti pelaajan %o hengen.,%o a perdu la vie face à un Reiver.,%o %p életét ellopta egy Martalóc,%o ha permesso che un Incursore prosciugasse la sua vita ,%o はレイバーに命を %p盗まれた。,%o 은(는) 리버에게 영혼을 도둑맞았다.,%o had @[zijn_haar_nl] leven gestolen door een Rover.,%o fikk %p liv stjålet av en Reiver.,"Życie %o zostało skradzione przez Rozbójnika. +",%o teve sua vida roubada por um Fantasma.,,Viața lui %o a fost furată de un Pungaș.,Жизнь игрока %o украл грабитель.,Играчу %o је живот украо Вребач.,%o fick sitt liv stulet av en Reiver.,%o bir Hayalet tarafından kurutuldu. +%o was incinerated by the Death Wyvern.,OB_DRAGON,,,,%o byl@[ao_cs] upálen@[ao_cs] smrtidrakem.,%o blev forbrændt af wyvern.,%o wurde von dem Todesdrachen verbrannt.,,%o cindriĝis de Mortviverno.,A %o l@[ao_esp] ha calcinado el Guiverno de la Muerte.,A %o l@[ao_esp] calcinó el Guiverno de la Muerte.,%o joutui kuolontraakin polttamaksi.,%o a été incinéré@[e_fr] par une vouivre de la mort.,%o testét porig égette egy Halálsárkány,%o è stato incenerito da una Viverna Mortale. ,%o はダークワイバーンに焼却された。,%o 은(는) 데스 와이번에 의해 분신 당했다.,%o werd verbrand door de Doodsdraak.,%o ble brent opp av en Døden Wyvern.,%o został@[ao_pl] spalon@[adj_pl] przez Wiwernę Śmierci.,%o foi incinerad@[ao_ptb] por uma Serpe da Morte,,%o a fost incinerat de Balaurul Morții.,Игрока %o кремировала виверна Смерти.,Играча %o је кремировао Змајак смрти.,%o blev bränd av Döds Wyvern.,"%o, Ölüm Wyvern tarafından yakıldı." +%o was swept from the board by Korax.,OB_KORAX,,,,%o byl@[ao_cs] odhozen@[ao_cs] ze šachovnice Koraxem.,%o blev fejet væk fra brættet af Korax.,%o wurde von Korax vom Feld gefegt.,,%o estis prenita el la tabulo de Korax.,%o ha sido barrid@[ao_esp] del tablero por Korax.,%o fue barrid@[ao_esp] del tablero por Korax.,%o pyyhkäistiin laudalta Kooraksen voimasta.,%o a été balayé@[e_fr] de l'échiquier par Korax.,%o el lett söpörve a tábláról Korax által.,%o è stato eliminato dalla scacchiera da Korax. ,%o は唯一神の怒りに触れた。,%o 은(는) 코락스의 체스판에서 사라졌다.,%o werd door Korax van het bord geveegd.,%o ble feid fra brettet av Korax.,%o został@[ao_pl] zmiecion@[adj_pl] z pokładu przez Koraxa.,%o foi eliminad@[ao_ptb] do tabuleiro por Korax.,,%o a fost măturat de pe drum de Korax.,Игрока %o скинул с доски Коракс.,Играча %o је с табле уклонио Коракс.,%o blev avförd från spelplanen av Korax.,"%o, Korax tarafından tahtadan süpürüldü." +%o was slain by Zedek.,OB_FBOSS,,,,%o byl@[ao_cs] zabit@[ao_cs] Zedekem.,%o blev dræbt af Zedek.,%o wurde von Zedek hingemetzelt.,,%o mortigis de Zedeko.,A %o l@[ao_esp] ha asesinado Zedek.,A %o l@[ao_esp] asesinó Zedek.,%o joutui Sedekin tappamaksi.,%o a été pourfendu@[e_fr] par Zedek.,%o meghalt Zedek által.,%o è stato ammazzato da Zedek. ,%o はゼデクに討ち取られた。,%o 은(는) 제닥의 이름으로 쓰러졌다.,%o werd gedood door Zedek.,%o ble drept av Zedek.,%o został@[ao_pl] zgładzon@[adj_pl] przez Zedeka.,%o foi mort@[ao_ptb] por Zedek.,,%o a fost omorât de Zedek.,Игрока %o сразил Зедек.,Играча %o је оборио Коракс.,%o blev dödad av Zedek.,"%o, Zedek tarafından öldürüldü." +%o couldn't absorb Menelkir's Mana.,OB_MBOSS,,,,%o nemohl@[ao_cs] pojmout Menelkirovu manu.,%o kunne ikke absorbere Menelkirs Mana.,%o konnte Menelkirs Mana nicht verkraften.,,%o ne povis absorbi la Manaon de Menelkiro.,%o no ha absorbido el maná de Menelkir.,%o no absorbió el maná de Menelkir.,%o ei kyennyt ottamaan vastaan Menelkirin manaa.,%o n'aurait pu absorber le mana de Menelkir.,%o nem tudta elnyelni Menelkir manáját.,%o non è riuscito ad assorbire il mana di Menelkir. ,%o はメネルキルのマナを吸収できなかった。,%o 은(는) 메넬키어의 마나를 흡수하지 못했다.,%o kon Menelkir's mana niet absorberen.,%o kunne ikke absorbere Menelkirs Mana.,%o nie m@[irreg_4_pl] wchłonąć Many Menelkira.,%o não conseguiu absorver o Mana de Menelkir.,,%o nu a reușit să absoarbă mana lui Menelkir.,Игрок %o не смог поглотить ману Менелкира.,%o се није узмог@[ao_2_sr] носити с Менелкировом маном.,%o kunde inte absorbera Menelkirs Mana.,"%o, Menelkir'in Mana'sını ememedi." +%o was baptized by Traductus.,OB_CBOSS,,,,%o byl@[ao_cs] posvěcen@[ao_cs] Traduktem.,%o blev døbt af Traductus.,%o wurde von Traductus getauft.,,%o baptiĝis de Traduktuso.,A %o l@[ao_esp] ha bautizado Traductus.,A %o l@[ao_esp] bautizó Traductus.,%o joutui Traduktuksen kastamaksi.,%o a été baptisé@[e_fr] par Traductus.,%o meg lett keresztelve Traductus által.,%o è stato battezzato da Traductus. ,%o はトラダクタスの洗礼を受けた。,%o 은(는) 트라닥투스에게 침례를 당했다.,%o werd gedoopt door Traductus.,%o ble døpt av Traductus.,%o został@[ao_pl] ochrzczon@[adj_pl] przez Traductusa.,%o foi batizad@[ao_ptb] por Traductus.,,%o a fost botezat de Traductus.,Игрока %o крестил Традуктус.,Играча %o је крстио Традуктус.,%o blev döpt av Traductus.,"%o, Traductus tarafından vaftiz edildi." +%o had %p bones rolled by the Heresiarch.,OB_HERESIARCH,,,,%o si nechal@[ao_cs] rozmetat kosti Arcikacířem.,%o fik sine knogler rullet af Heresiark.,%os Knochen wurden vom Erzketzer gerollt.,,%o havis siajn ostojn rulis de la Ĉefherezulo.,A %o le ha arrollado los huesos el Heresiarca.,A %o le arrolló los huesos el Heresiarca.,Kerettiarkki jyräsi pelaajan %o luut.,%o s'est fait@[e_fr] rouler les os par l'Hérésiarche.,%o csontváza ki lett forgatva az Eretnek Vezér által.,Le ossa di %o sono state accartocciate dall'Eresiarca. ,%o はヘレシアークに骨を %p本 撒き散らされた。,%o 은(는) 헤러시아크에 의해 뼈와 살이 분리되었다.,%o @[zijn_haar_nl] botten werden opgerold door de Heresiarch.,%o fikk %p bein rullet av Heresiark.,Kości %o zostały porozrzucane przez Herezjarchę.,%o teve seus ossos moídos pelo Heresiarca.,,Oasele lui %o au fost făcute praf de către Ereziarh.,Ересиарх сыграл в кости игрока %o.,На играча %o су пале Јересијархове коцке.,%o fick sina ben rullade av Heresiark.,"%o, Heresiark tarafından kutsandı." +%o was beaten to a pulp by %k's bare fists.,OB_MPFWEAPFIST,,,,%o byl@[ao_cs] umlácen@[ao_cs] k smrti holými pěstmi hráče %k.,%o blev slået til plukfisk af %ks bare næver.,%o wurde von %ks nackten Fäusten zu Hackfleisch verarbeitet.,,%o kaĉe draŝiĝis de la nudaj pugnoj de %k.,%o ha quedado molid@[ao_esp] por los puños limpios de %k.,%o quedó molid@[ao_esp] por los puños limpios de %k.,%k hakkasi %o paran muusiksi paljailla nyrkeillään.,%o à été tabassé@[e_fr] à mort par les poings de %k.,%o péppé lett verve %k ökleivel.,%k ha ridotto %o in poltiglia a mani nude.,%o は %k に素手でボコボコにされた。,%o 은(는) %k 의 맨손 타격으로 묵사발이 되었다.,%o werd tot pulp geslagen door %k's blote vuisten.,%o ble slått til mos av %ks bare never.,%o został@[ao_pl] zbit@[adj_pl] na miazgę przez gołe pięści %k.,%o foi espancad@[ao_ptb] até a morte pelos punhos nus de %k.,,%k l-a omorât în bătaie pe %o cu mâinile goale.,Игрок %o избит в мясо голыми руками игрока %k.,%o је пребијен@[adj_1_sr] на смрт голим рукама играч %k.,%o blev slagen till mos av %ks nakna knytnävar.,"%o, %k tarafından eşek sudan gelinceye kadar dövüldü." +%o got the axe from %k.,OB_MPFWEAPAXE,,,,%o dostal@[ao_cs] sekerou od hráče %k.,%o fik øksen af %k.,%o sah %ks Axt.,,%o ricevis la hakilon el %k.,%o ha recibido el hachazo de %k.,%o recibió el hachazo de %k.,%o sai pelaajan %k kirveestä.,%o s'est fait@[e_fr] hacher menu par %k.,%o megkapta %k baltáját.,%o ha preso un colpo d'ascia da %k.,%o は %k から斧を受けた。,%o 은(는) %k 의 티몬의 도끼를 어설프게 받아쳤다.,%o kreeg de bijl van %k.,%o fikk øksa av %k.,%o dostał@[ao_pl] z topora %k.,%o recebeu o machado de %k.,,%o a primit un topor de la %k.,Игрок %o словил топорик игрока %k.,%o је добио секиру од %k.,%o fick yxan av %k.,"%o, %k tarafından baltayla dövüldü." +%o had %p head caved in by %k's hammer.,OB_MPFWEAPHAMMERM,,,,%o dostal@[ao_cs] po hlavě kladivem hráče %k.,%o fik sit hoved udhulet af %ks hammer.,%o wurde der Kopf von %ks Hammer eingeschlagen.,,%p havis sian kapon enfalis de la martelo de %k.,A %o le ha abollado la cabeza el martillo de %k.,A %o le abolló la cabeza el martillo de %k.,%k painoi vasarallaan %o paran pään kasaan.,%o s'est fait@[e_fr] éclater le crâne par le marteau de %k.,%o kapott egy üreges fejet %k Kalapácsa által.,La testa di %o è stata aperta in due dal martello di %k.,%o は %k のハンマーで頭に空洞を開けられた。,%k 은(는) 징벌의 망치로 %o 의 머리 위에 우물을 만들었다.,%o had @[zijn_haar_nl] kop ingestort met %k's hamer.,%o fikk %p hode knust av %ks hammer.,Głowa %o została zmiażdżona przez młot %k.,%o teve seu crânio afundado pelo martelo de %k.,%o teve seu crânio amolgado pelo martelo de %k.,%k i-a băgat capul lui %o în interior cu ciocanul.,Голова игрока %o была вдолблена в тело молотом игрока %k.,Играч %k је расцепао играчу %o главу.,%o fick huvudet krossat av %ks hammare.,"%o, %k tarafından dövüldü." +%o's soul was forged anew by %k's hammer.,OB_MPFWEAPHAMMERR,,,,%o@[psf1_cs] duše byla obrozena kladivem hráče %k.,%os sjæl blev smedet på ny af %ks hammer.,%os Seele wurde durch %ks Hammer erneuert.,,La animo de %o nove forĝiĝis de la martelo de %k.,El alma de %o ha sido forjada de nuevo por el martillo de %k.,El alma de %o fue forjada de nuevo por el martillo de %k.,%k uudelleentakoi %o paran sielun vasarallaan.,%o a eu son âme reforgée par le marteau de %k.,%o lelke újra lett kovácsolva %k Kalapácsa által.,L'anima di %o è stata riforgiata dal martello di %k.,%o の魂は %k のハンマーで一から鍛え直された。,%o 의 영혼은 %k 의 징벌의 망치에 의해 철거되었다.,%o's ziel werd omgesmeed door %k's hamer.,%o's sjel ble smidd på nytt av %ks hammer.,Dusza %o została wykuta na nowo przez młot %k.,%o teve sua alma reforjada pelo martelo de %k.,,%k i-a făcut sufletul lui %o ca nou cu ciocanul.,Душа игрока %o была перекована молотом игрока %k.,Играч %k је прековао душу играча %o чекићем.,%os själ smiddes på nytt av %ks hammare.,"%o, %k tarafından dövüldü." +%o was silenced by %k's mighty Quietus.,OB_MPFWEAPQUIETUS,,,,%o byl@[ao_cs] umlčen@[ao_cs] mocným Tišitelem hráče %k.,%o blev bragt til tavshed af %ks mægtige Forløser.,%o wurde durch %ks Erlöser befreit.,,%o slientiĝis de La Pova Kvietus' de %k.,A %o l@[ao_esp] ha silenciado el poderoso Quietus de %k.,A %o l@[ao_esp] silenció el poderoso Quietus de %k.,%k vaiensi %o paran mahtavalla Quietuksellaan.,%o à été réduit@[e_fr] au silence par le pouvoir de %k et Quietus.,%o el lett némítva %k hatalmas Némusza által.,%o è stato zittito dal potente Quietus di %k.,%o は %k の強靭なクワイエタスで静かにされた。,%o 은(는) %k 의 종언의 검 덕에 침묵을 지킬 수 있었다.,%o werd tot zwijgen gebracht door %k's machtige Quietus.,%o ble brakt til taushet av %ks mektige Quietus.,%o został@[ao_pl] uciszon@[adj_pl] przez %k.,%o foi silenciad@[ao_ptb] pelo poderoso Quietus de %k.,,"%o a fost redus la tăcere de argumentul final al +lui %k.",Игрок %o утихомирен легендарным Последним доводом игрока %k.,%o је утишан@[adj_1_sr] од моћи Куиетуса играч %k.,%o tystades av %ks mäktiga Quietus.,"%o, %k tarafından susturuldu." +%o got a mace to the face from %k.,OB_MPCWEAPMACE,,,,%o dostal@[ao_cs] palcátem po hlavě od hráče %k.,%o fik en stridskølle i ansigtet af %k.,%o bekam %ks Streitkolben ins Gesicht.,,%o prenis klabon al la vizaĝon el %k.,%o ha recibido un mazazo en la cara por %k.,%o recibió un mazazo en la cara por %k.,%o sai pelaajan %k nuijasta naamaansa.,%o s'est fait@[e_fr] casser la figure par la masse de %k.,%o kapott egy buzogányt a fejébe %k által.,%o si è preso una mazzata in faccia da %k.,%o は自らの顔に %k のメイスを受けた。,%o 은(는) %k 의 철퇴를 맞은 뒤에야 철이 들었다.,%o kreeg een %k's gesel in @[zijn_haar_nl] gezicht.,%o ble slått i ansiktet av %k.,%o dostał@[ao_pl] buzdyganem %k w twarz.,%o levou com a maça de %k na cara.,,%o a primit un buzdugan în față de la %k.,Игрок %o получил по морде булавой игрока %k.,%o је доби@[ao_1_sr] буздован у фацу играч %k.,%o fick en stridsklubba i ansiktet av %k.,"%o, %k tarafından eşek sudan gelinceye kadar dövüldü." +%o was bitten by %k's serpent staff.,OB_MPCWEAPSTAFFM,,,,%o byl@[ao_cs] kousnut@[ao_cs] hadí holí hráče %k.,%o blev bidt af %ks slange-stav.,%o wurde von %ks Schlangenstab gebissen.,,%o mordiĝis de la serpentbastono de %k.,A %o l@[ao_esp] ha mordido el bastón de la serpiente de %k.,A %o l@[ao_esp] mordió el bastón de la serpiente de %k.,%k puri %o parkaa käärmesauvallaan.,%o s'est fait@[e_fr] mordre par le Bâton du Serpent %k.,%o meg lett harapva %k Kígyó Botja által.,%o è stato morso dalla Staffa del Serpente di %k.,%o は %k の蛇の杖に噛まれた。,%o 은(는) %k 의 뱀 지팡이에 의해 독살당했다.,%o werd gebeten door %k's slangenstaf.,%o ble bitt av %ks slangestav.,%o został@[ao_pl] ugryzion@[adj_pl] laską węży %k.,%o foi mordid@[ao_ptb] pelo Cetro da Serpente de %k.,,%o a fost mușcat de bastonul șarpe al lui %k.,Игрок %o искусан змеиным посохом игрока %k.,%o је угрижен@[adj_1_sr] змијским штапом играч %k.,%o blev biten av %ks ormstab.,"%o, %k tarafından zehirlendi." +%o choked on %k's serpent staff.,OB_MPCWEAPSTAFFR,,,,%o se zadusil@[ao_cs] hadí holí hráče %k.,%o blev kvalt af %ks slange stav.,%o verschluckte sich an %ks Schlangenstab.,,%o sufokis la serpentbastonon de %k.,%o se ha ahogado con el bastón de la serpiente de %k.,%o se ahogó con el bastón de la serpiente de %k.,%o tukehtui pelaajan %k käärmesauvaan.,%o s'est étranglé@[e_fr] sur le Bâton du Serpent de %k,%o megfulladt %k Kígyó Botja által.,%o è soffocato a causa della Staffa del Serpente di %k.,%o は %k の蛇の杖に息の根を止められた。,%o 은(는) %k 의 뱀 지팡이 때문에 숨을 쉬지 못했다.,%o stikte in %k's slangenstaf.,%o ble kvalt av %ks slangestav.,%o zakrztusił@[ao_pl] się laską węży %k.,%o se engasgou com o Cetro da Serpente de %k,,%o s-a sufocat pe bastonul șarpe al lui %k.,Игрок %o задушен змеиным посохом игрока %k.,%o је задављен@[adj_1_sr] змијским штапом играч %k.,%o kvävdes av %ks ormstab.,"%o, %k tarafından kurutuldu." +%o was lit up by %k's flames.,OB_MPCWEAPFLAME,,,,%o vzplanul@[ao_cs] plameny hráče %k.,%o blev tændt af %ks flammer.,%o wurde von %ks Flammen erleuchtet.,,%o ekbruliĝis de la fajroj de %k.,A %o l@[ao_esp] han calcinado las llamas de %k.,A %o l@[ao_esp] calcinaron las llamas de %k.,%o syttyi pelaajan %k liekeistä.,%o s'est fait@[e_fr] allumer par %k.,%o fel lett gyújtva %k tűze által.,%o è stato illuminato dalle fiamme di %k.,%o は %k によって炎を灯された。,%o 은(는) %k 의 화염폭풍에 휩쓸렸다.,%o werd opgelicht door %k's vlammen.,%o ble opplyst av %ks flammer.,%o został@[ao_pl] oświetlon@[adj_pl] płomieniami %k.,%o foi incendiad@[ao_ptb] pelas chamas de %k.,,%o s-a aprins de la flăcările lui %k.,Игрок %o сгорел в огне игрока %k.,%o је осветљен@[adj_1_sr] пламеном играч %k.,%o blev upplyst av %ks lågor.,"%o, %k tarafından aydınlatıldı." +%o was cleansed by %k's Wraithverge.,OB_MPCWEAPWRAITHVERGE,,,,%o byl@[ao_cs] očištěn@[ao_cs] Zjevitelem hráče %k.,%o blev renset af %ks Spirit Bringer.,%o wurde durch %ks Geisterbringer geläutert.,,%o puriĝis de la Fantomkruc' de %k.,A %o l@[ao_esp] ha limpiado la vara fantasmal de %k.,A %o l@[ao_esp] limpió la vara fantasmal de %k.,%k puhdisti pelaajan %o Haamusauvallaan.,%o a été purifié@[e_fr] par la Verge Phantasmale de %k.,%o meg lett tisztítva %k Bosszúbot által.,%o è stato purificato dalla Verga SconfinaSpettri di %k.,%o は %k のレイスバージによって浄化された。,%o 은(는) %k 의 사령의 지팡이에 의해 정화되었다.,%o werd gereinigd door %k's Schimroede.,%o ble renset av %ks Wraithverge.,%o został@[ao_pl] oczyszczon@[adj_pl] przez Widmoskraj %k.,%o foi purificad@[ao_ptb] pelo Cajado Fantasma de %k.,,%o a fost purificat de Toiagul Stafie al lui %k.,Игрок %o очищен жезлом духов игрока %k.,%o je прочишћен@[adj_1_sr] штапом утваре играч %k.,%o blev renad av %ks Wraithverge.,"%o, %k tarafından temizlendi." +%o took one too many sapphire beams from %k.,OB_MPMWEAPWAND,,,,%o koupil@[ao_cs] přespříliš safírových střel od hráče %k.,%o tog en safirstråle for meget fra %k.,%o bekam zu viele Saphierstrahlen von %k ab.,,%o recivis unu tro da safira radio de %k.,%o ha recibido demasiados rayos de zafiro de %k.,%o recibió demasiados rayos de zafiro de %k.,%o otti vastaan yhden liikaa pelaajan %k safiirisäteistä.,%o s'est pris@[e_fr] un rayon saphirique en trop de la part de %k.,%o túl sok zafír sugarat kapott %k-tól/től.,%o si è buscato un raggio di zaffiro di troppo da %k.,%o は %k から多量のサファイアビームを受け取った。,%o 은(는) %k 의 사파이어 빛을 너무 많이 째려봤다.,%o kreeg een saffierstraal teveel van %k.,%o fikk en safirstråle for mye fra %k.,%o wzi@[irreg_2_pl] o jeden szafirowy promień od %k za dużo.,%o levou muitos raios de safira de %k.,,%o a primit o rază în plus de la safirul lui %k.,Игрок %o схватил слишком много сапфировых зарядов от игрока %k.,%o је узе@[ao_1_sr] превише сафирских зракова играч %k.,%o tog emot en för många safirstrålar från %k.,"%o, %k tarafından dönüştürüldü." +%o was turned into a frosty fellow by %k.,OB_MPMWEAPFROST,,,,%o byl@[ao_cs] zchlazen@[ao_cs] hráčem %k.,%o blev forvandlet til en frostklar fyr af %k.,%o wurde von %k schockgefrostet.,,%o farigiĝis frostulon de %k.,%o ha sido convertid@[ao_esp] en un helado por %k.,%o fue convertid@[ao_esp] en un helado por %k.,%k muutti %o paran pakkasveikoksi.,%o s'est fait@[e_fr] transformer en glaçon par %k.,%o jégbaráttá alakult %k által.,%o è stato trasformato in un simpatico pupazzo di neve da %k.,%o は %k によって冷ややかな輩になった。,%o 은(는) %k 의 얼음 파편에 의해 눈사람이 되었다.,%o werd ijskoud veranderd door %k.,%o ble forvandlet til en iskald fyr av %k.,%o został@[ao_pl] zmienion@[adj_pl] w mroźnego koleżkę przez %k.,%o foi transformad@[ao_ptb] em picolé por %k.,,%o a fost transformat într-un amic de gheață de %k.,Игрок %o обращается в ледяную скульптуру игроком %k.,%o је претворен@[adj_1_sr] у лед играч %k.,%o förvandlades till en frostig kille av %k.,"%o, %k tarafından soğuk bir adama dönüştürüldü." +%o received a shocking revelation from %k.,OB_MPMWEAPLIGHTNING,,,,%o zjistil@[ao_cs] šokující odhalení hráče %k.,%o fik en chokerende åbenbaring af %k.,%o musste eine schockierende Enthüllung von %k verkraften.,,%o recivis teruran revelacion de %k.,%o ha recibido una revelación impactante de %k.,%o recibió una revelación impactante de %k.,%o sai sähköistävän ilmestyksen pelaajalta %k.,%o a reçu un sacré coup de jus de la part de %k.,%o kapott egy sokkoló relevációt %k-tól/től,"%o ha ricevuto una notizia ""elettrizzante"" da %k.",%o は %k から衝撃的な啓示を受けた。,%o 은(는) %k 의 번갯불 덕에 충격적인 계시를 받았다.,%o kreeg een schokkende openbaring van %k.,%o fikk en sjokkerende åpenbaring fra %k.,%o otrzymał@[ao_pl] szokujące objawienie od %k.,%o recebeu uma revelação chocante de %k.,,%o a avut parte de o revelație șocantă de la %k.,Игрок %o откровенно шокирован игроком %k.,%o је прими@[ao_1_sr] шокантно откриће играч %k.,%o fick ett chockerande avslöjande av %k.,"%o, %k tarafından şoka uğratıldı." +%o was wiped off the face of the universe by %k's Bloodscourge.,OB_MPMWEAPBLOODSCOURGE,,,,%o byl@[ao_cs] vymýcen@[ao_cs] ze jsoucna vesmíru Krvehromem hráče %k.,%o blev udslettet af universets overflade af %ks Blodgisel.,%o wurde von %ks Blutgeißel aus dem Universum verbannt.,,%o disdetruiĝis el la universo de la Sangskurĝ' de %k.,%o ha sido borrad@[ao_esp] de la faz del universo por la plaga sangrienta de %k.,%o fue borrad@[ao_esp] de la faz del universo por la plaga sangrienta de %k.,%k pyyhki %o paran maailmankaikkeudesta.,%o s'est fait@[e_fr] effacer de l'univers par le Fléau Sanglant de %k.,%o ki lett törölve az univerzumból %k Vérkorbácsának köszönhetően.,%o è stato cancellato dalla faccia dell'universo dal Flagello di Sangue di %k.,%o は %k の天罰によりこの世から一掃された。,%o 은(는) %k 이(가) 피의 재앙을 씀으로써 전혀 존재하지 않는 존재가 되어버렸다.,%o werd van het gezicht van het universum geveegd door %k's Bloedgesel.,%o ble utslettet fra universets overflate av %ks Bloodscourge.,Twarz %o została zmieciona z wszechświata przez Krwioplagę %k.,%o foi varrid@[ao_ptb] da face do universo pelo Flagelo de Sangue de %k.,,"%o a fost ras de pe fața universului de +Flagelul Sângeros al lui %k.",Игрок %o стёрт с лица вселенной Кровавым бичом игрока %k.,%o је обрисан@[adj_1_sr] са лица свемира од Крвавог зла играч %k.,%o blev utplånad från universums yta av %ks Bloodscourge.,"%o, %k tarafından evrenden silindi." +,,Strife,,,,,,,,,,,,,,,,,,,,,,,,, +,,Pickups,,,,,,,,,,,,,,,,,,,,,,,,, +You picked up the Metal Armor.,TXT_METALARMOR,,,You picked up the Metal Armour.,Sebral@[ao_cs] jsi kovové brnění.,Du samlede metalrustningen op.,Du hast die Metallrüstung genommen.,Πήρες τη Μεταληκή Πανοπλία.,Vi trovis metalan armaĵon.,Encuentras una armadura de metal.,Hallaste una armadura de metal.,Poimit metallihaarniskan.,Vous avez pris l'armure de métal.,Felvetted a Fémpáncélt.,Hai raccolto l'Armatura di Metallo.,メタルアーマー 入手。,강철 갑옷을 획득했다.,Je hebt het metalen harnas opgepakt.,Du plukket opp metallrustningen.,Podniosł@[irreg_3_pl] Metalowy Pancerz.,Você pegou a Armadura de Metal.,Apanhaste a Armadura de Metal.,Ai ridicat Armura din Metal.,Получена металлическая броня.,Покупио си метални оклоп.,Du plockade upp metallrustningen.,Metal Zırhı aldın. +You picked up the Leather Armor.,TXT_LEATHERARMOR,,,You picked up the Leather Armour.,Sebral@[ao_cs] jsi kožené brnění.,Du samlede læderrustningen op.,Du hast die Lederrüstung genommen.,Πήρες τη Δερμάτινη Πανοπλία.,Vi trovis ledan armaĵon.,Encuentras una armadura de cuero.,Hallaste una armadura de cuero.,Poimit nahkasuojuksen.,Vous avez pris l'armure de cuir.,Felvetted a Bőrpáncélt.,Hai raccolto l'Armatura di Cuoio.,レザーアーマー 入手。,가죽 갑옷을 획득했다.,Je hebt het leren harnas opgepakt.,Du plukket opp lærrustningen.,Podniosł@[irreg_3_pl] Skórzany Pancerz.,Você pegou a Armadura de Couro.,Apanhaste a Armadura de Couro.,Ai ridicat Armura din Piele.,Получена кожаная броня.,Покупио си кожни оклоп.,Du plockade upp läderrustningen.,Deri Zırhı aldın. +You picked up the Med patch.,TXT_MEDPATCH,,,,Sebral@[ao_cs] jsi obvaz.,Du samlede Med patch op.,Du hast den Verband genommen.,,Vi trovis kuracbendojn.,Encuentras unas tiritas.,Hallaste unas curitas.,Poimit sidekääreen.,Vous avez pris le pansement.,Felvetted a Ragtapaszt.,Hai raccolto le Bende.,医薬パッチ 入手。,의료 붕대를 획득했다.,Je hebt de med-patch opgepakt.,Du plukket opp en Med-patch.,Podniosł@[irreg_3_pl] Bandaż.,Você pegou a compressa médica.,Apanhaste a compressa médica.,Ai ridicat Trusa de Prim-Ajutor.,Получен медицинский бинт.,Покупио си прву помоћ.,Du plockade upp den medicinska plåstret.,Sağlık bandını aldın. +You picked up the Medical kit.,TXT_MEDICALKIT,,,,Sebral@[ao_cs] jsi lékárničku.,Du samlede Medicinsk kit op.,Du hast den Verbandskasten genommen.,,Vi trovis sukurkeston.,Encuentras un botiquín.,Hallaste un botiquín.,Poimit lääkintälaukun.,Vous avez pris le kit médical.,Felvetted az Elsősegélycsomagot.,Hai raccolto il Kit di Pronto Soccorso.,医療用キット 入手。,구급 키트를 획득했다.,Je hebt de medicijndoos opgepakt.,Du plukket opp det medisinske settet.,Podniosł@[irreg_3_pl] Apteczkę.,Você pegou o Kit Médico.,Apanhaste o Kit Médico.,Ai ridicat Kitul de Prim-Ajutor.,Получена аптечка.,Покупио си медицински комплет,Du plockade upp den medicinska utrustningen.,Tıbbi kiti aldın. +You picked up the Surgery Kit.,TXT_SURGERYKIT,,,,Sebral@[ao_cs] jsi chirurgickou soupravu.,Du samlede kirurgisættet op.,Du hast den Erste-Hilfe-Kasten genommen.,,Vi trovis kirurgian keston.,Encuentras un kit quirúrgico.,Hallaste un kit quirúrgico.,Poimit kirurgilaukun.,Vous avez pris le kit de chirurgie.,Felvetted az Orvosi Műtőfelszerelést.,Hai raccolto il Kit Chirurgico.,手術キット 入手。,수술 키트를 획득했다.,Je hebt het chirurgenpakket opgepakt.,Du plukket opp Kirurgi-settet.,Podniosł@[irreg_3_pl] Zestaw Chirurga.,Você pegou o Kit de Cirurgia.,Apanhaste o Kit de Cirugia.,Ai ridicat Kitul pentru Operații.,Получен медкомплект.,Покупио си хируршки комплет,Du plockade upp operationssatsen.,Ameliyat setini aldın. +You picked up the map.,TXT_STRIFEMAP,,,,Sebral@[ao_cs] jsi mapu.,Du samlede kortet op.,Du hast die Karte genommen.,Πήρες το χάρτη.,Vi trovis la mapon.,Encuentras el mapa.,Hallaste el mapa.,Poimit kartan.,Vous avez pris la carte,Felvetted a térképet.,Hai raccolto la Mappa.,マップ 取得。,지도를 획득했다.,Je hebt de kaart opgepakt.,Du plukket opp kartet.,Podniosł@[irreg_3_pl] mapę.,Você pegou o mapa.,Apanhaste o mapa.,Ai ridicat harta.,Получена карта.,Покупио си мапу.,Du plockade upp kartan.,Haritayı aldın. +You picked up the ring.,TXT_BELDINSRING,,,,Sebral@[ao_cs] jsi prsten.,Du samlede ringen op.,Du hast den Ring genommen.,Πήρες το Δακτύλιο.,Vi prenis la ringon.,Tienes el anillo.,,Poimit sormuksen.,Vous avez pris l'anneau.,Felvetted a Gyűrűt.,Hai raccolto l'Anello.,指輪 取得。,반지를 획득했다.,Je hebt de ring opgepakt.,Du plukket opp ringen.,Podniosł@[irreg_3_pl] pierścień.,Você pegou o anel.,Apanhaste o anel.,Ai ridicat inelul.,Получено кольцо.,Покупио си прстен.,Du plockade upp ringen.,Yüzüğü aldın. +You picked up the Offering Chalice.,TXT_OFFERINGCHALICE,,,,Sebral@[ao_cs] jsi obětní kalich.,Du samlede offerkalken op.,Du hast den Opferkelch genommen.,,Vi prenis la oferdonan kalikon.,Tienes el cáliz de ofrenda.,,Poimit uhrimaljan.,Vous avez pris le Calice d'obole.,Felvetted az Áldozati Kelyhet.,Hai raccolto il Calice delle Offerte.,寄贈された聖杯 取得。,번제 성배를 훔쳤다.,Je hebt de Offerbeker opgepakt.,Du plukket opp offerbegeret.,Podniosł@[irreg_3_pl] Kielich Ofiarny.,Você pegou o Cálice de Oferenda.,Apanhaste o Cálice de Oferenda.,Ai ridicat Potirul pentru Ofrande.,Получена чаша для подношений.,Покупио си Жртвени пехар.,Du plockade upp offerkalken.,Adak Kadehini aldın. +You picked up the ear.,TXT_EAR,,,,Sebral@[ao_cs] jsi ucho.,Du samlede øret op.,Du hast das Ohr gernommen.,Πήρες το αυτί.,Vi prenis la orelon.,Tienes la oreja.,,Poimit korvan.,Vous avez pris l'oreille.,Felvetted a Fület.,Hai raccolto l'Orecchio.,耳 取得。,잘린 귀를 주웠다.,Je hebt het oor opgepakt.,Du plukket opp øret.,Podniosł@[irreg_3_pl] ucho.,Você pegou a orelha.,Apanhaste a orelha.,Ai ridicat urechea.,Получено ухо.,Покупио си уво.,Du plockade upp örat.,Kulağı aldın. +You picked up the broken power coupling.,TXT_BROKENCOUPLING,,,,Sebral@[ao_cs] jsi rozbitou spojku.,Du samlede den ødelagte strømkobling op.,Du hast den defekten Stromabnehmer genommen.,,Vi havas la rompitan energian kuplilon.,Tienes el acoplador de energía roto.,,Poimit rikkinäisen virtaliittimen.,Vous avez pris le coupleur énergétique cassé.,Felvetted a hibás tápcsatlakozót.,Hai raccolto la Coppia Energetica Rotta.,壊れたパワーカップリング 取得。,망가진 동력선 장치를 획득했다.,Je hebt de kapotte stroomkoppeling opgepakt.,Du plukket opp den ødelagte kraftkoblingen.,Podniosł@[irreg_3_pl] zepsute obwody zasilające.,Você pegou o acoplador de energia quebrado.,Apanhaste o acoplador de energia partido.,Ai ridicat cuplajul defect de curent.,Получена повреждённая муфта.,Покупио си неисправну спојницу напајања.,Du plockade upp den trasiga kraftkopplingen.,Kırık güç bağlantısını aldın. +You picked up the Shadow armor.,TXT_SHADOWARMOR,,,You picked up the Shadow armour.,Sebral@[ao_cs] jsi krycí brnění.,Du samlede skyggerustningen op.,Du hast die Schattenrüstung genommen.,,Vi trovis ombran armaĵon.,Encuentras una armadura de sombra.,Hallaste una armadura de sombra.,Poimit varjohaarniskan.,Vous avez pris l'armure de l'ombre.,Felvetted az Árnyékpáncélt.,Hai raccolto l'Armatura Ombra.,シャドウアーマー 入手。,그림자 갑옷을 획득했다.,Je hebt het schaduwharnas opgepakt.,Du plukket opp Skygge-rustningen.,Podniosł@[irreg_3_pl] Cienisty Pancerz.,Você pegou a armadura das sombras.,Apanhaste a armadura das sombras.,Ai ridicat Armura Umbrei.,Получена теневая броня.,Покупио си оклоп сенки.,Du plockade upp skuggrustningen.,Gölge zırhını aldın. +You picked up the Environmental Suit.,TXT_ENVSUIT,,,,Sebral@[ao_cs] jsi ochranný oděv,Du samlede miljødragten op.,Du hast den Schutzanzug genommen.,,Vi trovis medi-ŝirman veston,Encuentras un traje de protección ambiental.,Hallaste un traje de protección ambiental.,Poimit ympäristösuojapuvun.,Vous avez pris la combinaison hazmat.,Felvetted a Védőruhát.,Hai raccolto la Tuta Ambientale.,耐環境スーツ 入手。,환경 방호복을 획득했다.,Je hebt het beschermende pak opgepakt.,Du plukket opp miljødrakten.,Podniosł@[irreg_3_pl] Skafander Ochronny.,Você pegou o Traje de Proteção.,Apanhaste o Fato Protetor.,Ai ridicat Costumul de Protecție.,Получен защитный костюм.,Покупио си заштитно одело.,Du plockade upp miljödräkten.,Çevresel Kıyafeti aldın. +You picked up the Guard Uniform.,TXT_GUARDUNIFORM,,,,Sebral@[ao_cs] jsi hlídačovu uniformu.,Du samlede vagtuniformen op.,Du hast die Wächteruniform genommen.,,Vi prenis la uniformon de gardisto.,Tienes el uniforme de un guardia.,,Poimit vartijan univormun.,Vous avez pris l'Uniforme du garde.,Felvetted az Őr Egyenruhát.,Hai raccolto l'Uniforme da Guardia.,守衛の制服 入手。,경비 전투복을 획득했다.,Je hebt het wachtersuniform opgepakt.,Du plukket opp vaktuniformen.,Podniosł@[irreg_3_pl] Mundur Strażnika.,Você pegou o Uniforme de Guarda.,Apanhaste o Uniforme de Guarda.,Ai ridicat Uniforma de Paznic.,Получена униформа стражника.,Покупио си стражарску униформу,Du plockade upp vaktuniformen.,Muhafız Üniformasını aldın. +You picked up the Officer's Uniform.,TXT_OFFICERSUNIFORM,,,,Sebral@[ao_cs] jsi důstojníkovu uniformu.,Du samlede officersuniformen op.,Du hast die Offiziersuniform genommen.,,Vi trovis oficiran uniformon.,Encuentras un uniforme de oficial.,Hallaste un uniforme de oficial.,Poimit upseerin univormun.,Vous avez pris l'Uniforme de l'officier.,Felvetted a Tiszti Egyenruhát.,Hai raccolto l'Uniforme da Ufficiale.,士官の制服 入手。,장교 전투복을 획득했다.,Je hebt het officiersuniform opgepakt.,Du plukket opp offisersuniformen.,Podniosł@[irreg_3_pl] Mundur Oficera.,Você pegou o Uniforme de Oficial.,Apanhaste o Uniforme de Oficial.,Ai ridicat Uniforma Ofițerului.,Получена униформа офицера.,Покупио си официрску униформу,Du plockade upp officersuniformen.,Subay üniformasını aldın. +You picked up the flame thrower parts.,TXT_FTHROWERPARTS,,,,Sebral@[ao_cs] jsi součásti plamenometu.,Du samlede flammekasterdele op.,Du hast die Flammenwerferteile genommen.,,Vi havas la partojn de flamĵetilo.,Tienes las partes de un lanzallamas.,,Poimit liekinheittimen osat.,Vous avez pris les pièces du lance-flames.,Felvetted a lángszóró részeit.,Hai raccolto delle parti di Lanciafiamme.,火炎放射器の部品 入手。,화염방사기 부품을 획득했다.,Je hebt de vlammenwerperonderdelen opgepakt.,Du plukket opp delene til flammekasteren.,Podniosł@[irreg_3_pl] części miotacza ognia.,Você pegou as partes do lança-chamas.,Apanhaste as peças do lança-chamas.,Ai ridicat bucățile aruncătorului de flăcări.,Получены детали для огнемёта.,Покупио си делове за бацач пламена.,Du plockade upp delarna till flamkastaren.,Alev silahının parçalarını aldın. +You picked up the report.,TXT_REPORT,,,,Sebral@[ao_cs] jsi hlášení.,Du samlede rapporten op.,Du hast den Report genommen.,,Vi prenis la raporton.,Recogiste el reporte.,,Poimit raportin.,Vous avez pris le compte-rendu.,Felvetted a jelentést.,Hai raccolto il rapporto.,報告書 取得。,보고서를 획득했다.,Je hebt het rapport opgepakt.,Du plukket opp rapporten.,Podniosł@[irreg_3_pl] raport.,Você pegou o relatório.,Apanhaste o relatório.,Ai ridicat raportul.,Получен отчёт.,Покупио си извештај.,Du plockade upp rapporten.,Raporu aldın. +You picked up the info.,TXT_INFO,,,,Sebral@[ao_cs] jsi informace.,Du samlede oplysningerne op.,Du hast die Info genommen.,Πήρες της πληροφορίες,Vi prenis la informon.,Recogiste la información.,,Poimit tiedot.,Vous avez pris l'info.,Felvetted az információt.,Hai raccolto delle Informazioni.,情報 取得。,정보를 획득했다.,Je hebt de informatie opgepakt.,Du plukket opp informasjonen.,Podniosł@[irreg_3_pl] informacje.,Você pegou a informação.,Apanhaste a informação.,Ai recepționat informația.,Получена сводка.,Покупио си инфо.,Du plockade upp informationen.,Bilgiyi aldın. +You picked up the Targeter.,TXT_TARGETER,,,,Sebral@[ao_cs] jsi zaměřovač.,Du samlede targeter op.,Du hast die Zielhilfe genommen.,Πήρες τον Στοχευτή.,Vi prenis la Celilon.,Recogiste el apuntador.,,Poimit tähtäinlaitteen.,Vous avez pris le cibleur.,Felvetted a Célzóberendezést.,Hai raccolto il Puntatore.,照準器 入手。,조준기를 획득했다.,Je hebt het Richter opgepakt.,Du plukket opp Targeteren.,Podniosł@[irreg_3_pl] Namierzacz.,Você pegou a Mira.,Apanhaste a Mira.,Ai ridicat Țintitorul.,Получен целеуказатель.,Покупио си нишанитеља.,Du plockade upp targeter.,Hedefleyiciyi aldın. +You picked up the Communicator.,TXT_COMMUNICATOR,,,,Sebral@[ao_cs] jsi komunikátor.,Du samlede kommunikatoren op.,Du hast den Kommunikator genommen.,,Vi prenis la Komunikilon.,Recogiste el comunicador.,,Poimit viestintälaitteen.,Vous avez pris le Communicateur,Felvetted a Kommunikátort,Hai raccolto il Comunicatore.,コミュニケーター 取得。,연락장치를 획득했다.,Je hebt de Communicator opgepakt.,Du plukket opp kommunikatoren.,Podniosł@[irreg_3_pl] Komunikator.,Você pegou o Comunicador.,Apanhaste o Comunicador.,Ai ridicat Comunicatorul.,Получен передатчик.,Покупио си комуникатор.,Du plockade upp kommunikatorn.,İletişim cihazını aldın. +You picked up the coin.,TXT_COIN,,,,Sebral@[ao_cs] jsi minci.,Du samlede mønten op.,Du hast die Münze genommen.,Πήρες το κέρμα.,Vi trovis moneron.,Encuentras una moneda.,,Poimit kolikon.,Vous avez pris la pièce.,Felvetted az érmét.,Hai raccolto la Moneta.,コイン 入手。,동전을 주웠다.,Je hebt de munt opgepakt.,Du plukket opp mynten.,Podniosł@[irreg_3_pl] monetę.,Você pegou a moeda.,Apanhaste a moeda.,Ai ridicat moneda.,Получена монета.,Покупио си новчић.,Du plockade upp myntet.,Parayı aldın. +You picked up %d gold.,TXT_XGOLD,,,,Sebral@[ao_cs] jsi %d zlatých.,Du samlede %d guld op.,Du hast %d Gold genommen.,,Vi trovis %d da oro.,Encuentras %d monedas de oro.,,Poimit kultaa %d arvosta.,Vous avez pris %d pièces.,Felvettél %d aranyat.,Hai raccolto %d pezzi d'oro.,%d ゴールド 入手。,골드 %d 개를 획득했다.,Je hebt %d goud opgepakt.,Du plukket opp %d gull.,Podniosł@[irreg_3_pl] %d monet.,Você pegou %d moedas de ouro.,Apanhaste %d moedas de ouro.,Ai ridicat %g bucăți de aur.,Получено %d золотых.,Покупио си %d златника.,Du plockade upp %d guld.,%d altın aldın. +You picked up the Teleporter Beacon.,TXT_BEACON,,,,Sebral@[ao_cs] jsi teleportační maják.,Du samlede Teleporter Beacon op.,Du hast das Teleportersignal genommen.,,Vi prenis la Formovilan Signalilon.,Recogiste un faro de teletransportación.,,Poimit kaukosiirrinmajakan.,Vous avez pris la balise de téléporteur.,Felvetted a Teleport jelzőt.,Hai raccolto il Radiofaro per Teletrasporto.,テレポータービーコン 取得。,텔레포터 비콘을 획득했다.,Je hebt de teleporterbaken opgepakt.,Du plukket opp Teleporter-signalet.,Podniosł@[irreg_3_pl] Nadajnik Teleportera.,Você pegou o Sinalizador de Teletransporte.,Apanhaste o Sinalizador de Teletransporte.,Ai ridicat Luminatorul pentru Teleportor.,Получен телепортационный маяк.,Покупио си одашиљач за телепортовање.,Du plockade upp teleporterfyren.,Işınlayıcı İşaretini aldın. +You picked up the Degnin Ore.,TXT_DEGNINORE,,,,Sebral@[ao_cs] jsi degninskou rudu.,Du samlede Degnin Ore op.,Du hast das Degnin-Erz genommen.,,Vi prenis la Degninan Ercon.,Recogiste el Mineral Degnin.,,Poimit Degnin-malmia.,Vous avez pris le minerai de Degnin.,Felvetted a Degnin Ércet.,Hai raccolto il Minerale Degnin.,デグニン鉱石 取得。,데그닌 광석을 획득했다.,Je hebt het Degnin-erts opgepakt.,Du plukket opp Degnin-malmen.,Podniosł@[irreg_3_pl] Rudę Degninu.,Você pegou o Minério Degnin.,Apanhaste o Minério Degnin.,Ai ridicat minereul de Degnin.,Получена дегнинская руда.,Покупио си Дегнинску руду.,Du plockade upp Degnin Malm.,Degnin Cevherini aldın. +You picked up the scanner.,TXT_SCANNER,,,,Sebral@[ao_cs] jsi skener.,Du samlede scanneren op.,Du hast den Scanner genommen.,Πήρες το σαρωτή.,Vi prenis la skanilon.,Recogiste el escáner.,,Poimit skannerin.,Vous avez pris l'analyseur.,Felvetted a szkennert.,Hai raccolto lo Scanner.,スキャナー 入手。,탐지기를 획득했다.,Je hebt de scanner opgepakt.,Du plukket opp skanneren.,Podniosł@[irreg_3_pl] skaner.,Você pegou o scanner.,Apanhaste o scanner.,Ai ridicat scannerul.,Получен сканер.,Покупио си скенер.,Du plockade upp skannern.,Tarayıcıyı aldın. "The scanner won't work without a map! ",TXT_NEEDMAP,,,,Skener bez mapy fungovat nebude!,"Scanneren virker ikke uden et kort! ",Der Scanner kann ohne Karte nicht funktionieren.,Ο σαρωτής δέν θα δουλέψει χωρίς ένα χάρτη!,La skanilo ne funkcios sen mapo!,¡El escáner no funcionará sin un mapa!,,Skanneri ei toimi ilman karttaa!,"L'analyseur ne marchera pas sans une carte! ",Térkép nélkül nem fog működni a szkenner!,Lo scanner non può funzionare senza una mappa!,マップが無ければ スキャナーは機能しない!,지도 없이는 탐지기를 사용할 수 없다!,De scanner werkt niet zonder een kaart!,"Skanneren virker ikke uten et kart! ",Skaner nie zadziała bez mapy!,"O scanner não funciona sem um mapa! ",,Scannerul nu poate funcționa fără o hartă!,"Сканер не будет работать без карты! -",Скенер неће радити без мапе!,"Tarayıcı harita olmadan çalışmaz! +",Скенер неће радити без мапе!,"Skannern fungerar inte utan en karta! +","Tarayıcı harita olmadan çalışmaz! " -You picked up the Prison pass.,TXT_PRISONPASS,,,,Sebral@[ao_cs] jsi propustku do vězení.,Du samlede fængselspasset op.,Du hast den Gefängnispass genommen.,,Vi havas la malliberejan paspermeson.,Tienes el pase a la prisión.,,Poimit vankilan pääsyluvan.,Vous avez pris le passe de la prison.,Felvetted a Börtön belépőkártyát.,Hai raccolto il lasciapassare per la Prigione.,刑務所の許可証 取得。,감옥 통행증을 획득했다.,Je hebt de gevangenispas opgepakt.,Du plukket opp fengselspasset.,Podniosł@[irreg_3_pl] przepustkę do Więzienia.,Você pegou o passe da Prisão.,Apanhaste o passe da Prisão.,Ai ridicat Legitimația pentru Închisoare.,Получен пропуск в тюрьму.,Покупио си затворску пропусницу.,Hapishane kartını aldın. -You picked up the crossbow.,TXT_STRIFECROSSBOW,,,,Sebral@[ao_cs] jsi kuši.,Du samlede armbrøst op.,Du hast die Armbrust genommen.,Πήρες το τόξο,Vi trovis arbaleston.,Encuentras una ballesta.,,Poimit jousipyssyn.,Vous avez pris l'arbalète.,Felvetted a számszeríjat.,Hai raccolto la Balestra.,クロスボウ 入手。,석궁을 획득했다.,Je hebt de kruisboog opgepakt.,Du plukket opp armbrøsten.,Podniosł@[irreg_3_pl] kuszę.,Você pegou a besta.,Apanhaste uma besta.,Ai ridicat arbaleta.,Получен арбалет.,Покупио си самострел.,Tatar yayını aldın. -You picked up the assault gun.,TXT_ASSAULTGUN,,,,Sebral@[ao_cs] jsi pušku.,Du samlede pistolen op.,Du hast das Sturmgewehr genommen.,Πήρες το πολυβόλο.,Vi trovis sturmofusilon.,Encuentras un fusil de asalto.,,Poimit rynnäkkökiväärin.,Vous avez pris le fusil d'assaut.,Felvetted a gépfegyvert.,Hai raccolto il fucile d'assalto.,アサルトガン 入手。,돌격소총을 획득했다.,Je hebt het aanvalswapen opgepakt.,Du plukket opp stormgeværet.,Podniosł@[irreg_3_pl] karabin szturmowy.,Você pegou o fuzil de assalto.,Apanhaste a arma de assalto.,Ai ridicat pușca de asalt.,Получена штурмовая винтовка.,Покупио си аутоматску пушку.,Saldırı silahını aldın. -You picked up the mini missile launcher.,TXT_MMLAUNCHER,,,,Sebral@[ao_cs] jsi miniraketomet.,Du samlede mini-missilkasteren op.,Du hast den Miniraketenwerfer genommen.,Πήρες το μίνι πυραυλοβόλο.,Vi trovis misilet-pafilon.,Encuentras un minilanzacohetes.,,Poimit miniohjuslaukaisimen.,Vous avez pris le lance mini-missile.,Felvetted a minirakétavetőt.,Hai raccolto il Mini-Lanciamissili.,ミニミサイル ランチャー入手。,미니 미사일 런쳐를 획득했다.,Je hebt de mini-raketwerper opgepakt.,Du plukket opp mini-missilkasteren.,Podniosł@[irreg_3_pl] wyrzutnię minipocisków.,Você pegou o mini lança-mísseis.,Apanhaste o mini lança-mísseis,Ai ridicat mini lansatorul de rachete.,Получена мини-ракетница.,Покупио си мини ручни бацач.,Mini füze fırlatıcısını aldın. -You picked up the flame thrower.,TXT_FLAMER,,,,Sebral@[ao_cs] jsi plamenomet.,Du samlede flammekasteren op.,Du hast den Flammenwerfer genommen.,Πήρες το φλογοβόλο.,Vi trovis flamĵetilon.,Encuentras un lanzallamas.,,Poimit liekinheittimen.,Vous avez pris le lance-flames.,Felvetted a lángszórót.,Hai raccolto il Lanciafiamme.,火炎放射器 入手。,완성된 화염방사기를 얻었다.,Je hebt de vlammenwerper opgepakt.,Du plukket opp flammekasteren.,Podniosł@[irreg_3_pl] miotacz ognia.,Você pegou o lança-chamas.,Apanhaste o lança-chamas.,Ai ridicat aruncătorul de flăcări.,Получен огнемёт.,Покупио си бацач пламена.,Alev silahını aldın. -You picked up the mauler.,TXT_MAULER,,,,Sebral@[ao_cs] jsi trhač.,Du tog mauleren op.,Du hast den Vernichter genommen.,,Vi trovis vundegilon.,Encuentras un triturador.,Hallaste un triturador.,Poimit moukarin.,Vous avez pris le Broyeur.,Felvetted a marcangolót.,Hai raccolto il Pestatore.,マウラー 入手。,마울러를 획득했다.,Je hebt de toetakelaar opgepakt.,Du plukket opp mauleren.,Podniosł@[irreg_3_pl] miażdżyciel.,Você pegou o desintegrador.,Apanhaste o desintegrador.,Ai ridicat sfâșietorul.,Получен истязатель.,Покупио си маулер.,Parçalayıcıyı aldın. -You picked up the Grenade launcher.,TXT_GLAUNCHER,,,,Sebral@[ao_cs] jsi granátomet.,Du samlede granatkasteren op.,Du hast den Granatwerfer genommen.,Πήρες το εκτοξευτη χειροβομβίδων.,Vi trovis grenadĵetilon.,Encuentras un lanzagranadas.,,Poimit kranaatinheittimen.,Vous avez pris le lance-grenades,Felvetted a gránátvetőt.,Hai raccolto il Lanciagranate.,グレネードランチャー 入手。,유탄발사기를 획득했다.,Je hebt de granaatwerper opgepakt.,Du plukket opp granatkasteren.,Podniosł@[irreg_3_pl] wyrzutnię granatów.,Você pegou o lança-granadas.,Apanhaste o lança-granadas.,Ai ridicat Lansatorul de rachete.,Получен гранатомёт.,Покупио си бацач граната.,El bombası fırlatıcısını aldın. -You picked up the SIGIL.,TXT_SIGIL,,,,Sebral@[ao_cs] jsi Pečeť.,Du samlede SIGIL op.,Du hast das SIGIL genommen.,,Vi prenis la SIGELON.,Recogiste el EMBLEMA.,,Poimit SINETIN.,Vous avez pris le SIGIL.,Felvetted a Pecsétet.,Hai raccolto il SIGILLO.,シジル 取得。,시질은 이제 당신의 것이다.,Je hebt de SIGIL opgepakt.,Du plukket opp SIGIL.,Podniosł@[irreg_3_pl] PIECZĘĆ.,Você pegou o SIGILO.,Apanhaste o SIGILO,Ai ridicat SIGILIUL.,Получена ПЕЧАТЬ.,Покупио си СИГИЛ.,SİGİL'i aldın. -You picked up the Base Key.,TXT_BASEKEY,,,,Sebral@[ao_cs] jsi klíč od základny.,Du samlede Base nøglen op.,Du hast den Basisschlüssel genommen.,,Vi havas la ŝlosilon de la bazo.,Tienes la llave de la base.,,Poimit tukikohdan avaimen.,Vous avez pris la clé de la Base.,Felvetted a Bázis kulcsát.,Hai raccolto la chiave della Base.,基地のキー 取得。,기지 키를 획득했다.,Je hebt de basissleutel opgepakt.,Du plukket opp basenøkkelen.,Podniosł@[irreg_3_pl] Klucz do Bazy.,Você pegou a Chave da Base.,Apanhaste a Chave da Base.,Ai ridicat Cheia Bazei.,Получен ключ от базы.,Покупио си кључ базе.,Üs Anahtarını aldın. -You picked up the Govs Key.,TXT_GOVSKEY,,,,Sebral@[ao_cs] jsi klíč ke guvernérovi.,Du samlede guvernørens nøglen op.,Du hast den Gouverneursschlüssel genommen.,,Vi havas la ŝlosilon de la registo.,Tienes la llave del Gobernador.,,Poimit kuvernöörin avaimen.,Vous avez pris la clé du Gouverneur.,Felvetted a Kormányzó parcellájának kulcsát.,Hai raccolto la chiave del Governatore.,政府のキー 取得。,총독의 키를 획득했다.,Je hebt de gouverneursleutel opgepakt.,Du plukket opp regjeringsnøkkelen.,Podniosł@[irreg_3_pl] Klucz Gubernatora.,Você pegou a Chave do Governador.,Apanhaste a Chave do Governador.,Ai ridicat Cheia Guvernatorului.,Получен ключ губернатора.,Покупио си клуч гувернанте.,Hükümet Anahtarını aldın. -You picked up the Passcard.,TXT_PASSCARD,,,,Sebral@[ao_cs] jsi průkazku.,Du samlede Adgangskort op.,Du hast die Zugangskarte genommen.,,Vi havas la ŝlosilon de la elektra centralo.,Tienes la llave de la central eléctrica.,,Poimit avainkortin.,Vous avez pris le passe.,Felvetted a Belépőkártyát.,Hai raccolto la Tessera Lasciapassare.,パスカード 取得。,통행 카드를 획득했다.,Je hebt de doorgangskaart opgepakt.,Du plukket opp adgangskortet.,Podniosł@[irreg_3_pl] Kartę Dostępu.,Você pegou o Cartão de Acesso.,Apanhaste o Cartão de Acesso.,Ai ridicat Legitimația.,Получен пропуск.,Покупио си пасош.,Erişim kartıni aldın. -You picked up the ID Badge.,TXT_IDBADGE,,,,Sebral@[ao_cs] jsi identifikační odznak.,Du samlede ID Badge op.,Du hast die Identitätskarte genommen.,,Vi havas la insignon de la malliberejo.,Tienes la insignia de la prisión.,,Poimit henkilötunnisteen.,Vous avez pris le Badge d'identification.,Felvetted az Azonosítójelvényt.,Hai raccolto il Distintivo.,IDバッジ 取得。,신분 휘장을 획득했다.,Je hebt de ID-badge opgepakt.,Du plukket opp ID-skiltet.,Podniosł@[irreg_3_pl] Odznakę Identyfikacyjną.,Você pegou o Crachá de Identificação.,Apanhaste o Crachá de Identificação,Ai ridicat Ecusonul de Identificare.,Получена личная карта.,Покупио си личну карту.,Kimlik Rozetini aldın. -You picked up the Prison Key.,TXT_PRISONKEY,,,,Sebral@[ao_cs] jsi klič k vězení.,Du samlede nøglen til fængslet op.,Du hast den Gefängnisschlüssel genommen.,,Vi havas la ŝlosilon de la malliberejo.,Tienes la llave de la prisión.,,Poimit vankilan avaimen.,Vous avez pris la clé de la Prison.,Felvetted a Börtönkulcsot.,Hai raccolto la chiave della Prigione.,刑務所のキー 取得。,감옥 키를 획득했다.,Je hebt de gevangenissleutel opgepakt.,Du plukket opp Fengselsnøkkelen.,Podniosł@[irreg_3_pl] Klucz do Więzienia.,Você pegou a Chave da Prisão.,Apanhaste a Chave da Prisão.,Ai ridicat Cheia Închisorii.,Получен ключ от тюрьмы.,Покупио си затворски кључ,Hapishane Anahtarını aldın. -You picked up the Severed Hand.,TXT_SEVEREDHAND,,,,Sebral@[ao_cs] jsi useknutou ruku.,Du samlede den afhuggede hånd op.,Du hast die abgetrennte Hand genommen.,,Vi havas amputitan manon.,Tienes una mano amputada.,,Poimit katkenneen käden.,Vous avez pris la main coupée.,Felvetted a Levágott kezet.,Hai raccolto la Mano Mozzata.,切り取った手 取得。,잘린 손목을 주웠다.,Je hebt de Gescheurde Hand opgepakt.,Du plukket opp den avkuttede hånden.,Podniosł@[irreg_3_pl] Odciętą Rękę.,Você pegou a Mão Decepada.,Apanhaste a Mão Desmenbrada.,Ai ridicat Mâna Retezată.,Получена отрезанная рука.,Покупио си шаку,Kesik El'i aldın. -You picked up the Power1 Key.,TXT_POWER1KEY,,,,Sebral@[ao_cs] jsi klíč k elektrárně 1.,Du samlede Power1-nøglen op.,Du hast den Kraftwerksschlüssel 1 genommen,,Vi havas la unuan centralan identigilon.,Tienes una identificación nivel uno de la central.,,Poimit voimalan 1-avaimen.,Vous avez pris la clé Power1.,Felvetted az 1-es Áram kulcsot.,Hai raccolto la chiave della Centrale n.1,パワー1キー 取得。,발전소 1호 키를 획득했다.,Je hebt de 1e Machtsleutel opgepakt.,Du plukket opp Power1-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Elektrowni 1.,Você pegou a Chave da Usina 1.,Apanhaste a Chave Energética 1,Ai ridicat Cheia Putere1.,Получен ключ электростанции №1.,Покупио си први кључ од електране.,Güç1 Anahtarını aldın. -You picked up the Power2 Key.,TXT_POWER2KEY,,,,Sebral@[ao_cs] jsi klíč k elektrárně 2.,Du samlede Power2-nøglen op.,Du hast den Kraftwerksschlüssel 2 genommen,,Vi havas la duan centralan identigilon.,Tienes una identificación nivel dos de la central.,,Poimit voimalan 2-avaimen.,Vous avez pris la clé Power2.,Felvetted az 2-es Áram kulcsot.,Hai raccolto la chiave della Centrale n.2,パワー2キー 取得。,발전소 2호 키를 획득했다.,Je hebt de 2e Machtsleutel opgepakt.,Du plukket opp Power2-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Elektrowni 2.,Você pegou a Chave da Usina 2.,Apanhaste a Chave Energética 2,Ai ridicat Cheia Putere2.,Получен ключ электростанции №2.,Покупио си други кључ од електране.,Güç2 Anahtarını aldın. -You picked up the Power3 Key.,TXT_POWER3KEY,,,,Sebral@[ao_cs] jsi klíč k elektrárně 3.,Du samlede Power3-nøglen op.,Du hast den Kraftwerksschlüssel 3 genommen,,Vi havas la trian centralan identigilon.,Tienes una identificación nivel tres de la central.,,Poimit voimalan 3-avaimen.,Vous avez pris la clé Power3.,Felvetted az 3-as Áram kulcsot.,Hai raccolto la chiave della Centrale n.3,パワー3キー 取得。,발전소 3호 키를 획득했다.,Je hebt de 3e Machtsleutel opgepakt.,Du plukket opp Power3-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Elektrowni 3.,Você pegou a Chave da Usina 3.,Apanhaste a Chave Energética 3,Ai ridicat Cheia Putere3.,Получен ключ электростанции №3.,Покупио си трећи кључ од електране.,Güç3 Anahtarını aldın. -You picked up the Gold Key.,TXT_GOLDKEY,,,,Sebral@[ao_cs] jsi zlatý klíč.,Du samlede den guldnøglen op.,Du hast den Goldschlüssel genommen.,,Vi havas oran ŝlosilon.,Tienes una llave dorada.,,Poimit kulta-avaimen.,Vous avez pris la clé d'or.,Felvetted az Aranykulcsot.,Hai raccolto la chiave dorata,ゴールドキー 取得。,황금 키를 획득했다.,Je hebt de gouden sleutel opgepakt.,Du plukket opp Gullnøkkelen.,Podniosł@[irreg_3_pl] Złoty Klucz.,Você pegou a Chave de Ouro.,Apanhaste a Chave de Ouro,Ai ridicat Cheia de Aur.,Получен золотой ключ.,Покупио си златни кључ.,Altın Anahtarı aldın. -You picked up the ID Card.,TXT_IDCARD,,,,Sebral@[ao_cs] jsi ID kartu.,Du samlede ID-kortet op.,Du hast den Ausweis genommen.,,Vi havas identigilon de la kloakoj.,Tienes una identificación de las alcantarillas.,,Poimit henkilökortin.,Vous avez pris la Carte d'identité.,Felvetted az Igazolványt.,Hai raccolto la Tessera di Identificazione.,IDカード 取得。,신분증을 획득했다.,Je hebt de ID-kaart opgepakt.,Du plukket opp ID-kortet.,Podniosł@[irreg_3_pl] Kartę Identyfikacyjną.,Você pegou o Cartão de Identifiçacão.,Apanhaste o Cartão de Identificação,Ai ridicat Cardul de Identitate.,Получено удостоверение.,Покупио си идентификациону картицу.,Kimlik Kartını aldın. -You picked up the Silver Key.,TXT_SILVERKEY,,,,Sebral@[ao_cs] jsi stříbrný klíč.,Du tog sølvnøglen op.,Du hast den Silberschlüssel genommen.,,Vi havas arĝentan ŝlosilon.,Tienes una llave plateada.,,Poimit hopea-avaimen.,Vous avez pris la clé d'argent.,Felvetted az Ezüstkulcsot.,Hai raccolto la chiave argentata,シルバーキー 取得。,은 키를 획득했다.,Je hebt de zilveren sleutel opgepakt.,Du plukket opp sølvnøkkelen.,Podniosł@[irreg_3_pl] Srebrny Klucz.,Você pegou a Chave de Prata.,Apanhaste a Chave de Prata,Ai ridicat Cheia de Argint.,Получен серебряный ключ.,Покупио си сребрни кључ.,Gümüş Anahtarı aldınız. -You picked up the Oracle Key.,TXT_ORACLEKEY,,,,Sebral@[ao_cs] jsi věštcův klíč.,Du tog Oracle-nøglen op.,Du hast den Orakelschlüssel genommen.,,Vi havas ŝlosilon de la Orakolo,Tienes una llave del Oráculo.,,Poimit Oraakkelin avaimen.,Vous avez pris la clé Oraclé.,Felvetted az Orákulum kulcsát.,Hai raccolto la chiave dell'Oracolo.,オラクルキー 取得。,오라클 키를 획득했다.,Je hebt de Orakelsleutel opgepakt.,Du plukket opp Oracle-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Wyroczni.,Você pegou a Chave do Oráculo.,Apanhaste a Chave do Oráculo.,Ai ridicat Cheia Oracol.,Получен ключ Оракула.,Покупио си кључ пророка,Kahin Anahtarını aldın. -You picked up the Military ID.,TXT_MILITARYID,,,,Sebral@[ao_cs] jsi vojenské ID.,Du samlede militær-ID op.,Du hast den Militärausweis genommen.,,Vi havas militan identigilon.,Tienes una identificación militar.,,Poimit sotilastunnuksen.,Vous avez pris l'ID Militaire.,Felvetted a Katonai igazolványt.,Hai raccolto l'Identificativo Militare.,ミリタリーID 取得。,군용 아이디를 획득했다.,Je hebt de militaire ID opgepakt.,Du plukket opp den militære ID-en.,Podniosł@[irreg_3_pl] Wojskowy Identyfikator.,Você pegou a Identificação Militar.,Apanhaste a Identificação Militar.,Ai ridicat Legitimația Militară.,Получено военное удостоверение.,Покупио си војну идентификацију,Askeri Kimliği aldın. -You picked up the Order Key.,TXT_ORDERKEY,,,,Sebral@[ao_cs] jsi klíč Řádu.,Du samlede Ordensnøglen op.,Du hast den Ordensschlüssel genommen.,,Vi prenis la Ŝlosilon de La Ordono.,Tienes la llave de La Orden.,,Poimit Veljeskunnan avaimen.,Vous avez pris la clé de l'Ordre.,Felvetted a Rend kulcsát.,Hai raccolto la chiave dell'Ordine.,オーダーキー 取得。,오더의 키를 획득했다.,Je hebt de Ordesleutel opgepakt.,Du plukket opp Bestillingsnøkkelen.,Podniosł@[irreg_3_pl] Klucz Zakonu.,Você pegou a Chave da Ordem.,Apanhaste a Chave da Ordem.,Ai ridicat Cheia Ordinului.,Получен ключ Ордена.,Покупио си кључ одреда,Emir Anahtarını aldın. -You picked up the Warehouse Key.,TXT_WAREHOUSEKEY,,,,Sebral@[ao_cs] jsi klíč ke skladu.,Du samlede lagernøglen op.,Du hast den Lagerhausschlüssel genommen,,Vi prenis la Ŝlosilon de la Magazeno.,Recogiste la Llave del Almacén.,,Poimit varaston avaimen.,Vous avez pris la clé de l'entrepôt.,Felvetted a Raktár kulcsát.,Hai raccolto la chiave del Magazzino.,倉庫のキー 取得。,창고 키를 획득했다.,Je hebt de pakhuissleutel opgepakt.,Du plukket opp Lagernøkkelen.,Podniosł@[irreg_3_pl] Klucz do Magazynu.,Você pegou a Chave do Armazém.,Apanhaste a Chave do Armazém,Ai ridicat Cheia Depozitului.,Получен ключ от склада.,Покупио си кључ складишта,Depo Anahtarını aldın. -You picked up the Brass Key.,TXT_BRASSKEY,,,,Sebral@[ao_cs] jsi mosazný klíč.,Du samlede messingnøglen op.,Du hast den Messingschlüssel genommen.,,Vi prenis la Latunan Ŝlosilon.,Recogiste la Llave de Latón.,,Poimit messinkiavaimen.,Vous avez pris la clé de bronze.,Felvetted a Rézkulcsot.,Hai raccolto la chiave d'Ottone.,ブラスキー 取得。,황동 키를 획득했다.,Je hebt de messing sleutel opgepakt.,Du plukket opp messingnøkkelen.,Podniosł@[irreg_3_pl] Mosiężny Klucz.,Você pegou a Chave de Latão.,Apanhaste a Chave de Latão,Ai ridicat Cheia din Alamă.,Получен латунный ключ.,Покупио си кључ месинга,Pirinç Anahtarı aldın. -You picked up the Red Crystal Key.,TXT_REDCRYSTAL,,,,Sebral@[ao_cs] jsi červený krystalový klíč.,Du samlede den røde krystalnøgle op.,Du hast den roten Kristallschlüssel genommen.,,Vi prenis la Ruĝan Kristalan Ŝlosilon.,Recogiste la Llave de Cristal Rojo.,,Poimit punaisen kristalliavaimen.,Vous avez pris la clé cristal rouge.,Felvetted a Vörös Kristály Kulcsot.,Hai raccolto la chiave del Cristallo Rosso.,赤水晶のキー 取得。,적색 크리스탈 키를 획득했다.,Je hebt de rode kristallen sleutel opgepakt.,Du plukket opp den røde krystallnøkkelen.,Podniosł@[irreg_3_pl] Czerwony Kryształowy Klucz.,Você pegou a Chave de Cristal Vermelho.,Apanhaste a Chave de Cristal Vermelho.,Ai ridicat Cheia din Cristal Roșu.,Получен красный ключ-кристалл.,Покупио си кључ од црвеног кристала,Kırmızı Kristal Anahtarı aldın. -You picked up the Blue Crystal Key.,TXT_BLUECRYSTAL,,,,Sebral@[ao_cs] jsi modrý krystalový klíč.,Du samlede den blå krystalnøgle op.,Du hast den blauen Kristallschlüssel genommen.,,Vi prenis la Bluan Kristalan Ŝlosilon,Recogiste la Llave de Cristal Azul.,,Poimit sinisen kristalliavaimen.,Vous avez pris la clé cristal bleu.,Felvetted a Kék Kristály Kulcsot.,Hai raccolto la chiave del Cristallo Blu.,青水晶のキー 取得。,청색 크리스탈 키를 획득했다.,Je hebt de blauwe kristallen sleutel opgepakt.,Du plukket opp den blå krystallnøkkelen.,Podniosł@[irreg_3_pl] Niebieski Kryształowy Klucz.,Você pegou a Chave de Cristal Azul.,Apanhaste a Chave de Cristal Azul.,Ai ridicat Cheia din Cristal Albastru.,Получен синий ключ-кристалл.,Покупио си кључ од плавог кристала,Mavi Kristal Anahtarı aldın. -You picked up the Chapel Key.,TXT_CHAPELKEY,,,,Sebral@[ao_cs] jsi klíč ke kapli.,Du samlede Kapel-nøglen op.,Du hast den Kapellenschlüssel genommen.,,Vi prenis la Ŝlosilon de la Preĝejeto.,Recogiste la Llave de la Capilla.,,Poimit kappelin avaimen.,Vous avez pris la clé de la chapelle.,Felvetted a Kápolna Kulcsát.,Hai raccolto la chiave della Cappella,チャペルキー 取得。,예배당 키를 획득했다.,Je hebt de kapelsleutel opgepakt.,Du plukket opp kapellnøkkelen.,Podniosł@[irreg_3_pl] Klucz do Kaplicy.,Você pegou a Chave da Capela.,Apanhaste a Chave da Capela.,Ai ridicat Cheia Capelei.,Получен ключ от часовни.,Покупио си кључ капеле,Şapel Anahtarını aldın. -You picked up the Catacomb Key.,TXT_CATACOMBKEY,,,,Sebral@[ao_cs] jsi klíč do katakomb.,Du samlede Katakombe-nøglen op.,Du hast den Katakombenschlüssel genommen.,,Vi prenis la Ŝlosilon de la Katakombo.,Recogiste la Llave de la Catacumba.,,Poimit katakombin avaimen.,Vous avez pris la clé des catacombes.,Felvetted a Katakombák kulcsát.,Hai raccolto la chiave delle Catacombe.,カタコンベキー 取得。,고대 묘지 키를 획득했다.,Je hebt de catacombesleutel opgepakt.,Du plukket opp Katakomb-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Katakumb.,Você pegou a Chave da Catacumba.,Apanhaste a Chave da Catacumba.,Ai ridicat Cheia Catacombei.,Получен ключ от катакомб.,Покупио си кључ катакомбе,Yeraltı Mezarı Anahtarını aldın. -You picked up the Security Key.,TXT_SECURITYKEY,,,,Sebral@[ao_cs] jsi klíč ochranky.,Du samlede sikkerhedsnøglen op.,Du hast den Sicherheitsschlüssel genommen.,,Vi prenis la Sekurecŝlosilon.,Recogiste la Llave de Seguridad.,,Poimit turvamiesavaimen.,Vous avez pris la clé de la sécurité.,Felvetted a Biztonsági Kulcsot.,Hai raccolto la chiave della Sicurezza.,警備のキー 取得。,보안 키를 획득했다.,Je hebt de beveiligingssleutel opgepakt.,Du plukket opp Sikkerhetsnøkkelen.,Podniosł@[irreg_3_pl] Klucz Ochrony.,Você pegou a Chave de Seguranca.,Apanhaste a Chave de Segurança,Ai ridicat Cheia Securității.,Получен ключ охраны.,Покупио си кључ обезбеђења,Güvenlik Anahtarını aldın. -You picked up the Core Key.,TXT_COREKEY,,,,Sebral@[ao_cs] jsi klíč k jádru.,Du samlede reaktornøglen op.,Du hast den Reaktorschlüssel genommen.,,Vi trovis la ŝlosilon de la kernejo.,Encuentras la llave del núcleo.,Hallaste la llave del núcleo.,Poimit ytimen avaimen.,Vous avez pris la clé du réacteur.,Felvetted a Mag kulcsát.,Hai raccolto la chiave del Nucleo.,コアキー 取得。,중심부 키를 획득했다.,Je hebt de kernsleutel opgepakt.,Du plukket opp Kjernenøkkelen.,Podniosł@[irreg_3_pl] Klucz do Rdzenia.,Você pegou a Chave do Núcleo.,Apanhaste a Chave do Núcleo.,Ai ridicat Cheia Nucleului.,Получен ключ от реактора.,Покупио си кључ језгра,Çekirdek Anahtarını aldın. -You picked up the Mauler Key.,TXT_MAULERKEY,,,,Sebral@[ao_cs] jsi klíč k trhačům.,Du samlede Mauler-nøglen op.,Du hast den Vernichterschlüssel genommen.,,Vi havas la ŝlosilon de la vundegiloj.,Tiene la llave de los trituradores.,,Poimit moukarin avaimen.,Vous avez pris la clé du Broyeur.,Felvetted a Marcangoló kulcsot.,Hai raccolto la chiave del Pestatore.,マウラーキー 取得。,마울러 키를 획득했다.,Je hebt de toetakelaarssleutel opgepakt.,Du plukket opp Mauler-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Magazynu Miażdżycieli.,Você pegou a Chave do Mauler.,Apanhaste a Chave do Mauler.,Ai ridicat Cheia Sfâșietorului.,Получен ключ истязателя.,Покупио си кључ Маулера.,Mauler Anahtarını aldın. -You picked up the Factory Key.,TXT_FACTORYKEY,,,,Sebral@[ao_cs] jsi klíč do továrny.,Du samlede fabriksnøglen op.,Du hast den Fabrikschlüssel genommen.,,Vi prenis la Ŝlosilon de la Fabriko.,Recogiste la Llave de la Fábrica.,,Poimit tehtaan avaimen.,Vous avez pris la clé de l'usine.,Felvetted a Gyár kulcsát.,Hai raccolto la chiave della Fabbrica.,工場のキー 取得。,공장 키를 획득했다.,Je hebt de fabriekssleutel opgepakt.,Du plukket opp fabrikknøkkelen.,Podniosł@[irreg_3_pl] Klucz do Fabryki.,Você pegou a Chave da Fábrica.,Apanhaste a Chave da Fábrica.,Ai ridicat Cheia Fabricii.,Получен ключ от фабрики.,Покупио си кључ фабрике,Fabrika Anahtarını aldın. -You picked up the Mine Key.,TXT_MINEKEY,,,,Sebral@[ao_cs] jsi klíč do dolů.,Du samlede minenøglen op.,Du hast den Minenschlüssel genommen.,,Vi prenis la Ŝlosilon de la Minejo.,Recogiste la Llave de la Mina.,,Poimit kaivoksen avaimen.,Vous avez pris la clé de la mine.,Felvetted a Bánya kulcsát.,Hai raccolto la chiave della Miniera.,鉱山のキー 取得。,탄광 키를 획득했다.,Je hebt de mijnsleutel opgepakt.,Du plukket opp Gruvenøkkelen.,Podniosł@[irreg_3_pl] Klucz do Kopalni.,Você pegou a Chave da Mina.,Apanhaste a Chave da Mina.,Ai ridicat Cheia Minei.,Получен ключ от шахт.,Покупио си кључ рудника,Maden Anahtarını aldın. -You picked up the New Key5.,TXT_NEWKEY5,,,,Sebral@[ao_cs] jsi nový klíč 5.,Du samlede den nye nøgle5 op.,Du hast den neuen Schlüssel 5 genommen.,,Vi prenis la Novan Ŝlosilon5.,Recogiste la Llave Nueva5.,,Poimit uuden 5-avaimen.,Vous avez pris la nouvelle clé 5.,Felvetted az 5. kulcsot.,Hai raccolto la Nuova Chiave n.5,ニューキー5 取得。,새로운 키5를 획득했다.,Je hebt de nieuwe sleutel 5 opgepakt.,Du plukket opp den nye nøkkelen5.,Podniosł@[irreg_3_pl] Nowy Klucz5,Você pegou a Chave Nova 5.,Apanhaste a Chave Nova 5.,Ai ridicat Cheia Nouă5.,Получен новый ключ №5.,Покупио си нови кључ5,Yeni Anahtar5'i aldın. -You picked up the Oracle Pass.,TXT_ORACLEPASS,,,,Sebral@[ao_cs] jsi věštcovu propustku.,Du samlede orakelpas op.,Du hast den Orakelpass genommen.,,Vi prenis la Pasaĵo de la Okralo.,Recogiste el Pase del Oráculo.,,Poimit Oraakkelin passin.,Vous avez pris le passe de l'Oracle.,Felvetted az Orákulum Belépőkártyáját.,Hai raccolto il Lasciapassare dell'Oracolo.,オラクルパス 取得。,오라클의 통행증을 획득했다.,Je hebt de Orakelkaart opgepakt.,Du plukket opp Orakelpasset.,Podniosł@[irreg_3_pl] Przepustkę Wyroczni.,Você pegou o Passe do Oráculo.,Apanhaste o Passe do Oráculo.,Ai ridicat Legitimația Oracol.,Получен пропуск Оракула.,Покупио си пророкову пропусницу,Kahin Geçiş Kartını aldın. -You picked up the HE-Grenade Rounds.,TXT_HEGRENADES,,,,Sebral@[ao_cs] jsi výbušné granáty.,Du samlede HE-granaterne op.,Du hast die HE-Granaten genommen.,,Vi prenis la PE-Gernadmuniciojn.,Recogiste las Granadas HE.,,Poimit räjähdekranaattiammuksia.,Vous avez pris les Grenades Explosives.,Felvetted a robbanó gránátot.,Hai raccolto delle granate ad Alto Potenziale,HEグレネード弾 入手。,고폭 유탄을 획득했다.,Je hebt de HE-granaten opgepakt.,Du plukket opp HE-granaten.,Podniosł@[irreg_3_pl] Wiązkę Granatów.,Você pegou as Granadas Explosivas.,Apanhaste as Granadas Explosivas.,Ai ridicat Grenadele Explozive.,Получена связка гранат.,Покупио си ХЕ-Граната чауре,HE-Bombası Mermilerini aldın. -You picked up the Phosphorus-Grenade Rounds.,TXT_PHGRENADES,,,,Sebral@[ao_cs] jsi fosforové granáty.,Du samlede fosforgranaterne op.,Du hasr die Phosphorgranaten genommen.,,Vi prenis la Fosforajn Gernadmuniciojn.,Recogiste las Granadas de Fósforo.,,Poimit fosforikranaattiammuksia.,Vous avez pris les Grenades Phosphoriques.,Felvetted a foszfor-gránátokat.,Hai raccolto delle Granate al Fosforo.,白リングレネード弾 入手。,소이 유탄을 획득했다.,Je hebt de fosforgranaten opgepakt.,Du plukket opp fosforgranaten.,Podniosł@[irreg_3_pl] Wiązkę Fosforowych Granatów.,Você pegou as Granadas de Fósforo.,Apanhaste as Granadas de Fósforo.,Ai ridicat Grenadele cu Fosfor.,Получена связка фосфорных гранат.,Покупио си шаржер фосфорних граната.,Fosforlu El Bombası Mermilerini aldın. -You picked up the clip of bullets.,TXT_CLIPOFBULLETS,,,,Sebral@[ao_cs] jsi zásobník s náboji.,Du samlede patroner op.,Du hast die Gewehrmunition genommen.,Πήρες το κουτάκι με σφαίρες.,Vi prenis la kuglujon.,Recogiste un cargador con balas.,,Poimit luotilippaan.,Vous avez pris le Chargeur.,Felvettél egy tár lőszert.,Hai raccolto un caricatore di proiettili.,銃弾倉 入手。,돌격소총 탄창을 획득했다.,Je hebt de patroon met kogels opgepakt.,Du plukket opp magasinet med kuler.,Podniosł@[irreg_3_pl] magazynek.,Você pegou o carregador.,Apanhaste o carregador.,Ai ridicat cartușul cu gloanțe.,Получена обойма.,,Mermi şarjörünü aldın. -You picked up the box of bullets.,TXT_BOXOFBULLETS,,,,Sebral@[ao_cs] jsi krabici nábojů.,Du samlede kassen med kugler op.,Du hast die Munitionskiste genommen.,Πήρες το κουτί με σφαίρες.,Vi prenis la kuglarujon.,Recogiste una caja de balas.,,Poimit luotilaatikon.,Vous avez pris la boîte de balles.,Felvettél egy doboz lőszert.,Hai raccolto una scatola di proiettili.,弾薬箱 入手。,돌격소총 탄약 박스를 획득했다.,Je hebt de doos met kogels opgepakt.,Du plukket opp esken med kuler.,Podniosł@[irreg_3_pl] pudło z amunicją.,Você pegou a caixa de balas.,Apanhaste a caixa de balas.,Ai ridicat cutia cu gloanțe.,Получена коробка патронов.,Покупио си кутију меткова,Mermi kutusunu aldın. -You picked up the mini missiles.,TXT_MINIMISSILES,,,,Sebral@[ao_cs] jsi minirakety.,Du samlede mini-missiler op.,Du hast die Miniraketen genommen.,Πήρες τους μινι-πυράυλους.,Vi prenis la misiletojn.,Recogiste mini misiles.,,Poimit miniohjuksia.,Vous avez pris les mini-missiles.,Felvetted a minirakétákat.,Hai raccolto dei mini-missili.,ミニミサイル 入手。,미니 미사일 꾸러미를 획득했다.,Je hebt de mini-raketten opgepakt.,Du plukket opp minirakettene.,Podniosł@[irreg_3_pl] mini pociski.,Você pegou os mini-mísseis.,Apanhaste os mini-mísseis.,Ai ridicat mini proiectilele.,Получены мини-ракеты.,Покупио си мини ракете,Mini füzeleri aldın. -You picked up the crate of missiles.,TXT_CRATEOFMISSILES,,,,Sebral@[ao_cs] jsi bednu miniraket.,Du samlede kassen med missiler op.,Du hast die Miniraketenkiste genommen.,Πήρες το κιβώτιο με πυράυλους.,Vi prenis la misilarujon.,Recogiste una caja de misiles.,,Poimit ohjuslaatikon.,Vous avez pris la caisse de missiles.,Felvettél egy ládányi minirakétát.,Hai raccolto una cassa di missili.,ミサイルの箱 入手。,미니 미사일 박스를 획득했다.,Je hebt de kist met raketten opgepakt.,Du plukket opp kassen med missiler.,Podniosł@[irreg_3_pl] skrzynię z pociskami.,Você pegou a caixa de mísseis.,Apanhaste a caixa de mísseis.,Ai ridicat lada cu proiectile.,Получен ящик мини-ракет.,Покупио си кутију ракета,Füze sandığını aldın. -You picked up the energy pod.,TXT_ENERGYPOD,,,,Sebral@[ao_cs] jsi energetický kokón.,Du samlede energipoden op.,Du hast die Energiezelle genommen.,,Vi prenis la umon de energio.,Recogiste una vaina de energía.,,Poimit energia-akun.,Vous avez pris la cellule d'énergie.,Felvettél egy energiahüvelyt.,Hai raccolto un nucleo energetico.,エネルギーポット 入手。,에너지 포드를 획득했다.,Je hebt de energiecel opgepakt.,Du plukket opp energikapselen.,Podniosł@[irreg_3_pl] kapsułę energii.,Você pegou a célula de energia (pequeno).,Apanhaste a célula de energia (pequeno).,Ai ridicat capsula cu energie.,Получена энергокапсула.,Покупио си енергетско постоље.,Enerji kapsülünü aldın. -You picked up the energy pack.,TXT_ENERGYPACK,,,,Sebral@[ao_cs] jsi energetický svazek.,Du samlede energipakken op.,Du hast das Energiepack genommen.,,Vi prenis la pako de energio.,Recogiste un pack de energía.,,Poimit energiapaketin.,Vous avez pris le pack énergétique.,Felvetted az energiacsomagot.,Hai raccolto una carica energetica grande.,エネルギーパック 入手。,에너지 팩을 획득했다.,Je hebt het energiepak opgepakt.,Du plukket opp energipakken.,Podniosł@[irreg_3_pl] zasobnik energii.,Você pegou a célula de energia (grande).,Apanhaste a célula de energia (grande).,Ai ridicat pachetul cu energie.,Получен энергокомплект.,Покупио си пакет енергије,Enerji paketini aldın. -You picked up the poison bolts.,TXT_POISONBOLTS,,,,Sebral@[ao_cs] jsi otrávené šípy.,Du samlede giftboltene op.,Du hase die Giftbolzen genommen.,,Vi prenis la venenajn sagetojn.,Recogiste las flechas venenosas.,,Poimit myrkkynuolia.,Vous avez pris les carreaux empoisonnés.,Felvetted a mérgezett nyilakat.,Hai raccolto dei dardi velenosi.,ポイズンボルト 入手。,맹독 볼트를 획득했다.,Je hebt de gifbouten opgepakt.,Du plukket opp giftboltene.,Podniosł@[irreg_3_pl] zatrute bełty.,Você pegou as setas envenenadas.,Apanhaste as setas envenedadas.,Ai ridicat bolțurile cu otravă.,Получены отравленные болты.,Покупио си отровне стреле,Zehirli cıvataları aldın. -You picked up the electric bolts.,TXT_ELECTRICBOLTS,,,,Sebral@[ao_cs] jsi elektrické šípy.,Du samlede de elektriske bolte op.,Du hast die elektrischen Bolzen genommen.,,Vi prenis la elektrajn sagetojn.,Recogiste las flechas eléctricas.,,Poimit sähkönuolia.,Vous avez pris les carreaux électriques.,Felvetted az elektromos nyilakat.,Hai raccolto dei dardi elettrici.,エレクトリックボルト 入手。,전격 볼트를 획득했다.,Je hebt de elektrische bouten opgepakt.,Du plukket opp de elektriske boltene.,Podniosł@[irreg_3_pl] elektryczne bełty.,Você pegou as setas eletricas.,Apanhaste as setas electricas.,Ai ridicat bolțurile cu electricitate.,Получены электрические болты.,Покупио си електричне стреле,Elektrikli cıvataları aldın. -You picked up the ammo satchel.,TXT_AMMOSATCHEL,,,,Sebral@[ao_cs] jsi brašnu na munici.,Du samlede ammunitionstasken op.,Du hast die Munitionstasche genommen.,,Vi prenis la municiingo.,Recogiste un estuche de munición.,,Poimit ammuslaukun.,Vous avez pris la sacoche de munitions,Felvetted a lőszeres táskát.,Hai raccolto una Borsa delle Munizioni.,弾薬鞄 入手。,탄약 배낭을 획득했다.,Je hebt de munitietas opgepakt.,Du plukket opp ammunisjonsvesken.,Podniosł@[irreg_3_pl] torbę z amunicją.,Você pegou a mochila de munição.,Apanhaste a mochila de munição.,Ai ridicat sacoșa cu muniție.,Получен ранец для боеприпасов.,Покупио си торбицу муниције,Cephane çantasını aldın. -You have a feeling that it wasn't to be touched...,MSG_TALISMANRED,,,,"Máš pocit, že jsi na to sahat neměl@[ao_cs]...","Du har en fornemmelse af, at den ikke måtte røres...","Du hast das Gefühl, dass man es nicht anfassen sollte...",,"Vi sentas, ke ĝi ne devas tuŝiĝi...",Tienes la sensación de que no debía ser tocado...,,"Sinusta tuntuu, ettei siihen olisi pitänyt koskea.",Vous avez un pressentiment qu'il ne fallait pas y toucher.....,Úgy érzed azt nem kéne megérinteni...,Hai la sensazione che non doveva essere toccato...,己の勘が 触れてはならない物だと訴えている...,"결코, 만지면 안 된다는 생각이 든다...",Je hebt het gevoel dat het niet aangeraakt dient te worden...,Du har en følelse av at den ikke skulle røres...,"Czujesz, że trzeba było tego nie dotykać...",Você tem um pressentimento de que isso não devia ser tocado...,Tens um pressentimento que não devias ter mexido nisso.,Ai sentimentul că nu trebuia atinsă...,"Кажется, эту вещь лучше не трогать...",Имаш осећај да није требало бити дирано...,İçinizde dokunulmaması gerektiğine dair bir his var. -"Whatever it is, it doesn't belong in this world...",MSG_TALISMANGREEN,,,,"Je jedno, co to je, do tohoto světa to nepatří...","Uanset hvad det er, hører det ikke hjemme i denne verden...","Was auch immer es ist, es gehört nicht in diese Welt...","Οτιδήποτε είναι, δέν είναι απο αυτό τον κόσμο...","Kio ajn ĝi estas, ĝi ne apartenas al ĉi tiu mundo...","Sea lo que sea, no pertenece a este mundo...",,"Mikä ikinä se onkaan, se ei kuulu tähän maailmaan...","Quel que soit cette chose, elle ne devrait pas être ici...","Bármi legyen ez, nem ebben a világban van a helye...","Qualunque cosa sia, non appartiene a questo mondo...",何であろうと、この世には属さない物だ...,뭔지는 몰라도 이 세상에 속한 것이 아닌 것 같다...,"Wat het ook is, het hoort niet thuis in deze wereld...","Uansett hva det er, hører det ikke hjemme i denne verden...","Cokolwiek to jest, nie należy to do tego świata...","Seja o que for, isso não pertence a este mundo...","O que quer que isso seja, não pertence a este mundo...","Orice ar fi, nu are ce căuta în lumea asta...","Что бы это ни было, оно не из этого мира...","Шта год да је, не припада овом свету...","O her neyse, bu dünyaya ait değil." -It must do something...,MSG_TALISMANBLUE,,,,Něco to dělat musí...,Det må gøre noget...,Es muss etwas tun...,Πρέπει να κάνι κάτι...,Ĝi devas fari ion...,Debe hacer algo...,,Sen on pakko tehdä jotakin...,Ca doit servir a quelque chose...,Valamit kell hogy csináljon...,Deve fare qualcosa...,何かを成し遂げなければならない...,분명히 뭔가를 할 것이다...,Het moet iets doen....,Det må gjøre noe...,To musi coś robić...,Deveria fazer alguma coisa...,Devia fazer alguma coisa.,Trebuie să facă ceva...,Оно ведь зачем-то нужно?..,Мора урадити нешто...,Bir şey yapmalı. -You have super strength!,MSG_TALISMANPOWER,,,,Získal@[ao_cs] jsi super sílu!,Du har superstyrke!,Du hast Superkräfte,,Vi havas superan forton!,¡Tienes superfuerza!,,Sinulla on supervoimat!,Vous avez une puissance inégalée!,Tied a Szuper Erő!,Hai la super forza!,豪剛なる力を得た!,엄청난 힘이 솟는다!,Je hebt superkracht!,Du har superkrefter!,Masz super siłę!,Você tem a super força!,Tu tens super força!,Ai super forță!,Вы получили сверхсилу!,Имаш супер снагу!,Süper gücün var! -,,Locks,,,,,,,,,,,,,,,,,,,,,,,, -You don't have the key,TXT_NEEDKEY,,,,Nemáš klíč.,Du har ikke nøglen,Du hast den Schlüssel nicht,Δέν έχεις το κλειδί,Vi ne havas la ŝlosilon,No tienes la llave,,Sinulla ei ole avainta,Vous n'avez pas la clé.,Ehhez nincs kulcsod.,Non hai la chiave necessaria,キーを持っていない,필요한 열쇠가 없다,Je hebt de sleutel niet.,Du har ikke nøkkelen,Nie masz klucza,Você não tem a chave,Tu não tens a chave,Nu ai cheia,Нужен ключ,Немаш кључ,Anahtar sende değil. -You need a passcard,TXT_NEED_PASSCARD,,,,Potřebuješ průkaz.,Du har brug for et adgangskort,Du brauchst eine Zugangskarte.,,Vi bezonas central-ŝlosilon,Necesitas la llave de la central,,Tarvitset avainkortin,Vous avez besoin du passe.,Belépőkártyára lesz szükséged.,Ti serve un lasciapassare,パスカード が必要だ,통행 카드가 필요하다,Je hebt een doorgangskaart nodig.,Du trenger et passerkort,Potrzebujesz karty dostępu,Você precisa de um cartão de acesso,Precisas de um cartão de acesso,Ai nevoie de un card de acces,Нужен пропуск,Треба ти пропусница,Bir erişim kartına ihtiyacınız var +You picked up the Prison pass.,TXT_PRISONPASS,,,,Sebral@[ao_cs] jsi propustku do vězení.,Du samlede fængselspasset op.,Du hast den Gefängnispass genommen.,,Vi havas la malliberejan paspermeson.,Tienes el pase a la prisión.,,Poimit vankilan pääsyluvan.,Vous avez pris le passe de la prison.,Felvetted a Börtön belépőkártyát.,Hai raccolto il lasciapassare per la Prigione.,刑務所の許可証 取得。,감옥 통행증을 획득했다.,Je hebt de gevangenispas opgepakt.,Du plukket opp fengselspasset.,Podniosł@[irreg_3_pl] przepustkę do Więzienia.,Você pegou o passe da Prisão.,Apanhaste o passe da Prisão.,Ai ridicat Legitimația pentru Închisoare.,Получен пропуск в тюрьму.,Покупио си затворску пропусницу.,Du plockade upp fängelsepasset.,Hapishane kartını aldın. +You picked up the crossbow.,TXT_STRIFECROSSBOW,,,,Sebral@[ao_cs] jsi kuši.,Du samlede armbrøst op.,Du hast die Armbrust genommen.,Πήρες το τόξο,Vi trovis arbaleston.,Encuentras una ballesta.,,Poimit jousipyssyn.,Vous avez pris l'arbalète.,Felvetted a számszeríjat.,Hai raccolto la Balestra.,クロスボウ 入手。,석궁을 획득했다.,Je hebt de kruisboog opgepakt.,Du plukket opp armbrøsten.,Podniosł@[irreg_3_pl] kuszę.,Você pegou a besta.,Apanhaste uma besta.,Ai ridicat arbaleta.,Получен арбалет.,Покупио си самострел.,Du plockade upp armborstet.,Tatar yayını aldın. +You picked up the assault gun.,TXT_ASSAULTGUN,,,,Sebral@[ao_cs] jsi pušku.,Du samlede pistolen op.,Du hast das Sturmgewehr genommen.,Πήρες το πολυβόλο.,Vi trovis sturmofusilon.,Encuentras un fusil de asalto.,,Poimit rynnäkkökiväärin.,Vous avez pris le fusil d'assaut.,Felvetted a gépfegyvert.,Hai raccolto il fucile d'assalto.,アサルトガン 入手。,돌격소총을 획득했다.,Je hebt het aanvalswapen opgepakt.,Du plukket opp stormgeværet.,Podniosł@[irreg_3_pl] karabin szturmowy.,Você pegou o fuzil de assalto.,Apanhaste a arma de assalto.,Ai ridicat pușca de asalt.,Получена штурмовая винтовка.,Покупио си аутоматску пушку.,Du plockade upp pistolen.,Saldırı silahını aldın. +You picked up the mini missile launcher.,TXT_MMLAUNCHER,,,,Sebral@[ao_cs] jsi miniraketomet.,Du samlede mini-missilkasteren op.,Du hast den Miniraketenwerfer genommen.,Πήρες το μίνι πυραυλοβόλο.,Vi trovis misilet-pafilon.,Encuentras un minilanzacohetes.,,Poimit miniohjuslaukaisimen.,Vous avez pris le lance mini-missile.,Felvetted a minirakétavetőt.,Hai raccolto il Mini-Lanciamissili.,ミニミサイル ランチャー入手。,미니 미사일 런쳐를 획득했다.,Je hebt de mini-raketwerper opgepakt.,Du plukket opp mini-missilkasteren.,Podniosł@[irreg_3_pl] wyrzutnię minipocisków.,Você pegou o mini lança-mísseis.,Apanhaste o mini lança-mísseis,Ai ridicat mini lansatorul de rachete.,Получена мини-ракетница.,Покупио си мини ручни бацач.,Du plockade upp mini-missilkastaren.,Mini füze fırlatıcısını aldın. +You picked up the flame thrower.,TXT_FLAMER,,,,Sebral@[ao_cs] jsi plamenomet.,Du samlede flammekasteren op.,Du hast den Flammenwerfer genommen.,Πήρες το φλογοβόλο.,Vi trovis flamĵetilon.,Encuentras un lanzallamas.,,Poimit liekinheittimen.,Vous avez pris le lance-flames.,Felvetted a lángszórót.,Hai raccolto il Lanciafiamme.,火炎放射器 入手。,완성된 화염방사기를 얻었다.,Je hebt de vlammenwerper opgepakt.,Du plukket opp flammekasteren.,Podniosł@[irreg_3_pl] miotacz ognia.,Você pegou o lança-chamas.,Apanhaste o lança-chamas.,Ai ridicat aruncătorul de flăcări.,Получен огнемёт.,Покупио си бацач пламена.,Du plockade upp flamkastaren.,Alev silahını aldın. +You picked up the mauler.,TXT_MAULER,,,,Sebral@[ao_cs] jsi trhač.,Du tog mauleren op.,Du hast den Vernichter genommen.,,Vi trovis vundegilon.,Encuentras un triturador.,Hallaste un triturador.,Poimit moukarin.,Vous avez pris le Broyeur.,Felvetted a marcangolót.,Hai raccolto il Pestatore.,マウラー 入手。,마울러를 획득했다.,Je hebt de toetakelaar opgepakt.,Du plukket opp mauleren.,Podniosł@[irreg_3_pl] miażdżyciel.,Você pegou o desintegrador.,Apanhaste o desintegrador.,Ai ridicat sfâșietorul.,Получен истязатель.,Покупио си маулер.,Du plockade upp mauler.,Parçalayıcıyı aldın. +You picked up the Grenade launcher.,TXT_GLAUNCHER,,,,Sebral@[ao_cs] jsi granátomet.,Du samlede granatkasteren op.,Du hast den Granatwerfer genommen.,Πήρες το εκτοξευτη χειροβομβίδων.,Vi trovis grenadĵetilon.,Encuentras un lanzagranadas.,,Poimit kranaatinheittimen.,Vous avez pris le lance-grenades,Felvetted a gránátvetőt.,Hai raccolto il Lanciagranate.,グレネードランチャー 入手。,유탄발사기를 획득했다.,Je hebt de granaatwerper opgepakt.,Du plukket opp granatkasteren.,Podniosł@[irreg_3_pl] wyrzutnię granatów.,Você pegou o lança-granadas.,Apanhaste o lança-granadas.,Ai ridicat Lansatorul de rachete.,Получен гранатомёт.,Покупио си бацач граната.,Du plockade upp granatkastaren.,El bombası fırlatıcısını aldın. +You picked up the SIGIL.,TXT_SIGIL,,,,Sebral@[ao_cs] jsi Pečeť.,Du samlede SIGIL op.,Du hast das SIGIL genommen.,,Vi prenis la SIGELON.,Recogiste el EMBLEMA.,,Poimit SINETIN.,Vous avez pris le SIGIL.,Felvetted a Pecsétet.,Hai raccolto il SIGILLO.,シジル 取得。,시질은 이제 당신의 것이다.,Je hebt de SIGIL opgepakt.,Du plukket opp SIGIL.,Podniosł@[irreg_3_pl] PIECZĘĆ.,Você pegou o SIGILO.,Apanhaste o SIGILO,Ai ridicat SIGILIUL.,Получена ПЕЧАТЬ.,Покупио си СИГИЛ.,Du plockade upp Sigillet.,SİGİL'i aldın. +You picked up the Base Key.,TXT_BASEKEY,,,,Sebral@[ao_cs] jsi klíč od základny.,Du samlede Base nøglen op.,Du hast den Basisschlüssel genommen.,,Vi havas la ŝlosilon de la bazo.,Tienes la llave de la base.,,Poimit tukikohdan avaimen.,Vous avez pris la clé de la Base.,Felvetted a Bázis kulcsát.,Hai raccolto la chiave della Base.,基地のキー 取得。,기지 키를 획득했다.,Je hebt de basissleutel opgepakt.,Du plukket opp basenøkkelen.,Podniosł@[irreg_3_pl] Klucz do Bazy.,Você pegou a Chave da Base.,Apanhaste a Chave da Base.,Ai ridicat Cheia Bazei.,Получен ключ от базы.,Покупио си кључ базе.,Du plockade upp basnyckeln.,Üs Anahtarını aldın. +You picked up the Govs Key.,TXT_GOVSKEY,,,,Sebral@[ao_cs] jsi klíč ke guvernérovi.,Du samlede guvernørens nøglen op.,Du hast den Gouverneursschlüssel genommen.,,Vi havas la ŝlosilon de la registo.,Tienes la llave del Gobernador.,,Poimit kuvernöörin avaimen.,Vous avez pris la clé du Gouverneur.,Felvetted a Kormányzó parcellájának kulcsát.,Hai raccolto la chiave del Governatore.,政府のキー 取得。,총독의 키를 획득했다.,Je hebt de gouverneursleutel opgepakt.,Du plukket opp regjeringsnøkkelen.,Podniosł@[irreg_3_pl] Klucz Gubernatora.,Você pegou a Chave do Governador.,Apanhaste a Chave do Governador.,Ai ridicat Cheia Guvernatorului.,Получен ключ губернатора.,Покупио си клуч гувернанте.,Du plockade upp Govs nyckeln.,Hükümet Anahtarını aldın. +You picked up the Passcard.,TXT_PASSCARD,,,,Sebral@[ao_cs] jsi průkazku.,Du samlede Adgangskort op.,Du hast die Zugangskarte genommen.,,Vi havas la ŝlosilon de la elektra centralo.,Tienes la llave de la central eléctrica.,,Poimit avainkortin.,Vous avez pris le passe.,Felvetted a Belépőkártyát.,Hai raccolto la Tessera Lasciapassare.,パスカード 取得。,통행 카드를 획득했다.,Je hebt de doorgangskaart opgepakt.,Du plukket opp adgangskortet.,Podniosł@[irreg_3_pl] Kartę Dostępu.,Você pegou o Cartão de Acesso.,Apanhaste o Cartão de Acesso.,Ai ridicat Legitimația.,Получен пропуск.,Покупио си пасош.,Du plockade upp passerkortet.,Erişim kartıni aldın. +You picked up the ID Badge.,TXT_IDBADGE,,,,Sebral@[ao_cs] jsi identifikační odznak.,Du samlede ID Badge op.,Du hast die Identitätskarte genommen.,,Vi havas la insignon de la malliberejo.,Tienes la insignia de la prisión.,,Poimit henkilötunnisteen.,Vous avez pris le Badge d'identification.,Felvetted az Azonosítójelvényt.,Hai raccolto il Distintivo.,IDバッジ 取得。,신분 휘장을 획득했다.,Je hebt de ID-badge opgepakt.,Du plukket opp ID-skiltet.,Podniosł@[irreg_3_pl] Odznakę Identyfikacyjną.,Você pegou o Crachá de Identificação.,Apanhaste o Crachá de Identificação,Ai ridicat Ecusonul de Identificare.,Получена личная карта.,Покупио си личну карту.,Du plockade upp ID-brickan.,Kimlik Rozetini aldın. +You picked up the Prison Key.,TXT_PRISONKEY,,,,Sebral@[ao_cs] jsi klič k vězení.,Du samlede nøglen til fængslet op.,Du hast den Gefängnisschlüssel genommen.,,Vi havas la ŝlosilon de la malliberejo.,Tienes la llave de la prisión.,,Poimit vankilan avaimen.,Vous avez pris la clé de la Prison.,Felvetted a Börtönkulcsot.,Hai raccolto la chiave della Prigione.,刑務所のキー 取得。,감옥 키를 획득했다.,Je hebt de gevangenissleutel opgepakt.,Du plukket opp Fengselsnøkkelen.,Podniosł@[irreg_3_pl] Klucz do Więzienia.,Você pegou a Chave da Prisão.,Apanhaste a Chave da Prisão.,Ai ridicat Cheia Închisorii.,Получен ключ от тюрьмы.,Покупио си затворски кључ,Du tog upp fängelsenyckeln.,Hapishane Anahtarını aldın. +You picked up the Severed Hand.,TXT_SEVEREDHAND,,,,Sebral@[ao_cs] jsi useknutou ruku.,Du samlede den afhuggede hånd op.,Du hast die abgetrennte Hand genommen.,,Vi havas amputitan manon.,Tienes una mano amputada.,,Poimit katkenneen käden.,Vous avez pris la main coupée.,Felvetted a Levágott kezet.,Hai raccolto la Mano Mozzata.,切り取った手 取得。,잘린 손목을 주웠다.,Je hebt de Gescheurde Hand opgepakt.,Du plukket opp den avkuttede hånden.,Podniosł@[irreg_3_pl] Odciętą Rękę.,Você pegou a Mão Decepada.,Apanhaste a Mão Desmenbrada.,Ai ridicat Mâna Retezată.,Получена отрезанная рука.,Покупио си шаку,Du plockade upp den avhuggna handen.,Kesik El'i aldın. +You picked up the Power1 Key.,TXT_POWER1KEY,,,,Sebral@[ao_cs] jsi klíč k elektrárně 1.,Du samlede Power1-nøglen op.,Du hast den Kraftwerksschlüssel 1 genommen,,Vi havas la unuan centralan identigilon.,Tienes una identificación nivel uno de la central.,,Poimit voimalan 1-avaimen.,Vous avez pris la clé Power1.,Felvetted az 1-es Áram kulcsot.,Hai raccolto la chiave della Centrale n.1,パワー1キー 取得。,발전소 1호 키를 획득했다.,Je hebt de 1e Machtsleutel opgepakt.,Du plukket opp Power1-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Elektrowni 1.,Você pegou a Chave da Usina 1.,Apanhaste a Chave Energética 1,Ai ridicat Cheia Putere1.,Получен ключ электростанции №1.,Покупио си први кључ од електране.,Du plockade upp kraftnyckeln 1.,Güç1 Anahtarını aldın. +You picked up the Power2 Key.,TXT_POWER2KEY,,,,Sebral@[ao_cs] jsi klíč k elektrárně 2.,Du samlede Power2-nøglen op.,Du hast den Kraftwerksschlüssel 2 genommen,,Vi havas la duan centralan identigilon.,Tienes una identificación nivel dos de la central.,,Poimit voimalan 2-avaimen.,Vous avez pris la clé Power2.,Felvetted az 2-es Áram kulcsot.,Hai raccolto la chiave della Centrale n.2,パワー2キー 取得。,발전소 2호 키를 획득했다.,Je hebt de 2e Machtsleutel opgepakt.,Du plukket opp Power2-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Elektrowni 2.,Você pegou a Chave da Usina 2.,Apanhaste a Chave Energética 2,Ai ridicat Cheia Putere2.,Получен ключ электростанции №2.,Покупио си други кључ од електране.,Du plockade upp kraftnyckeln 2.,Güç2 Anahtarını aldın. +You picked up the Power3 Key.,TXT_POWER3KEY,,,,Sebral@[ao_cs] jsi klíč k elektrárně 3.,Du samlede Power3-nøglen op.,Du hast den Kraftwerksschlüssel 3 genommen,,Vi havas la trian centralan identigilon.,Tienes una identificación nivel tres de la central.,,Poimit voimalan 3-avaimen.,Vous avez pris la clé Power3.,Felvetted az 3-as Áram kulcsot.,Hai raccolto la chiave della Centrale n.3,パワー3キー 取得。,발전소 3호 키를 획득했다.,Je hebt de 3e Machtsleutel opgepakt.,Du plukket opp Power3-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Elektrowni 3.,Você pegou a Chave da Usina 3.,Apanhaste a Chave Energética 3,Ai ridicat Cheia Putere3.,Получен ключ электростанции №3.,Покупио си трећи кључ од електране.,Du plockade upp kraftnyckeln 3.,Güç3 Anahtarını aldın. +You picked up the Gold Key.,TXT_GOLDKEY,,,,Sebral@[ao_cs] jsi zlatý klíč.,Du samlede den guldnøglen op.,Du hast den Goldschlüssel genommen.,,Vi havas oran ŝlosilon.,Tienes una llave dorada.,,Poimit kulta-avaimen.,Vous avez pris la clé d'or.,Felvetted az Aranykulcsot.,Hai raccolto la chiave dorata,ゴールドキー 取得。,황금 키를 획득했다.,Je hebt de gouden sleutel opgepakt.,Du plukket opp Gullnøkkelen.,Podniosł@[irreg_3_pl] Złoty Klucz.,Você pegou a Chave de Ouro.,Apanhaste a Chave de Ouro,Ai ridicat Cheia de Aur.,Получен золотой ключ.,Покупио си златни кључ.,Du plockade upp guldnyckeln.,Altın Anahtarı aldın. +You picked up the ID Card.,TXT_IDCARD,,,,Sebral@[ao_cs] jsi ID kartu.,Du samlede ID-kortet op.,Du hast den Ausweis genommen.,,Vi havas identigilon de la kloakoj.,Tienes una identificación de las alcantarillas.,,Poimit henkilökortin.,Vous avez pris la Carte d'identité.,Felvetted az Igazolványt.,Hai raccolto la Tessera di Identificazione.,IDカード 取得。,신분증을 획득했다.,Je hebt de ID-kaart opgepakt.,Du plukket opp ID-kortet.,Podniosł@[irreg_3_pl] Kartę Identyfikacyjną.,Você pegou o Cartão de Identifiçacão.,Apanhaste o Cartão de Identificação,Ai ridicat Cardul de Identitate.,Получено удостоверение.,Покупио си идентификациону картицу.,Du plockade upp ID-kortet.,Kimlik Kartını aldın. +You picked up the Silver Key.,TXT_SILVERKEY,,,,Sebral@[ao_cs] jsi stříbrný klíč.,Du tog sølvnøglen op.,Du hast den Silberschlüssel genommen.,,Vi havas arĝentan ŝlosilon.,Tienes una llave plateada.,,Poimit hopea-avaimen.,Vous avez pris la clé d'argent.,Felvetted az Ezüstkulcsot.,Hai raccolto la chiave argentata,シルバーキー 取得。,은 키를 획득했다.,Je hebt de zilveren sleutel opgepakt.,Du plukket opp sølvnøkkelen.,Podniosł@[irreg_3_pl] Srebrny Klucz.,Você pegou a Chave de Prata.,Apanhaste a Chave de Prata,Ai ridicat Cheia de Argint.,Получен серебряный ключ.,Покупио си сребрни кључ.,Du plockade upp silvernyckeln.,Gümüş Anahtarı aldınız. +You picked up the Oracle Key.,TXT_ORACLEKEY,,,,Sebral@[ao_cs] jsi věštcův klíč.,Du tog Oracle-nøglen op.,Du hast den Orakelschlüssel genommen.,,Vi havas ŝlosilon de la Orakolo,Tienes una llave del Oráculo.,,Poimit Oraakkelin avaimen.,Vous avez pris la clé Oraclé.,Felvetted az Orákulum kulcsát.,Hai raccolto la chiave dell'Oracolo.,オラクルキー 取得。,오라클 키를 획득했다.,Je hebt de Orakelsleutel opgepakt.,Du plukket opp Oracle-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Wyroczni.,Você pegou a Chave do Oráculo.,Apanhaste a Chave do Oráculo.,Ai ridicat Cheia Oracol.,Получен ключ Оракула.,Покупио си кључ пророка,Du plockade upp Orakel-nyckeln.,Kahin Anahtarını aldın. +You picked up the Military ID.,TXT_MILITARYID,,,,Sebral@[ao_cs] jsi vojenské ID.,Du samlede militær-ID op.,Du hast den Militärausweis genommen.,,Vi havas militan identigilon.,Tienes una identificación militar.,,Poimit sotilastunnuksen.,Vous avez pris l'ID Militaire.,Felvetted a Katonai igazolványt.,Hai raccolto l'Identificativo Militare.,ミリタリーID 取得。,군용 아이디를 획득했다.,Je hebt de militaire ID opgepakt.,Du plukket opp den militære ID-en.,Podniosł@[irreg_3_pl] Wojskowy Identyfikator.,Você pegou a Identificação Militar.,Apanhaste a Identificação Militar.,Ai ridicat Legitimația Militară.,Получено военное удостоверение.,Покупио си војну идентификацију,Du plockade upp det militära ID-kortet.,Askeri Kimliği aldın. +You picked up the Order Key.,TXT_ORDERKEY,,,,Sebral@[ao_cs] jsi klíč Řádu.,Du samlede Ordensnøglen op.,Du hast den Ordensschlüssel genommen.,,Vi prenis la Ŝlosilon de La Ordono.,Tienes la llave de La Orden.,,Poimit Veljeskunnan avaimen.,Vous avez pris la clé de l'Ordre.,Felvetted a Rend kulcsát.,Hai raccolto la chiave dell'Ordine.,オーダーキー 取得。,오더의 키를 획득했다.,Je hebt de Ordesleutel opgepakt.,Du plukket opp Bestillingsnøkkelen.,Podniosł@[irreg_3_pl] Klucz Zakonu.,Você pegou a Chave da Ordem.,Apanhaste a Chave da Ordem.,Ai ridicat Cheia Ordinului.,Получен ключ Ордена.,Покупио си кључ одреда,Du plockade ordernyckeln.,Emir Anahtarını aldın. +You picked up the Warehouse Key.,TXT_WAREHOUSEKEY,,,,Sebral@[ao_cs] jsi klíč ke skladu.,Du samlede lagernøglen op.,Du hast den Lagerhausschlüssel genommen,,Vi prenis la Ŝlosilon de la Magazeno.,Recogiste la Llave del Almacén.,,Poimit varaston avaimen.,Vous avez pris la clé de l'entrepôt.,Felvetted a Raktár kulcsát.,Hai raccolto la chiave del Magazzino.,倉庫のキー 取得。,창고 키를 획득했다.,Je hebt de pakhuissleutel opgepakt.,Du plukket opp Lagernøkkelen.,Podniosł@[irreg_3_pl] Klucz do Magazynu.,Você pegou a Chave do Armazém.,Apanhaste a Chave do Armazém,Ai ridicat Cheia Depozitului.,Получен ключ от склада.,Покупио си кључ складишта,Du plockade lagernyckeln.,Depo Anahtarını aldın. +You picked up the Brass Key.,TXT_BRASSKEY,,,,Sebral@[ao_cs] jsi mosazný klíč.,Du samlede messingnøglen op.,Du hast den Messingschlüssel genommen.,,Vi prenis la Latunan Ŝlosilon.,Recogiste la Llave de Latón.,,Poimit messinkiavaimen.,Vous avez pris la clé de bronze.,Felvetted a Rézkulcsot.,Hai raccolto la chiave d'Ottone.,ブラスキー 取得。,황동 키를 획득했다.,Je hebt de messing sleutel opgepakt.,Du plukket opp messingnøkkelen.,Podniosł@[irreg_3_pl] Mosiężny Klucz.,Você pegou a Chave de Latão.,Apanhaste a Chave de Latão,Ai ridicat Cheia din Alamă.,Получен латунный ключ.,Покупио си кључ месинга,Du plockade mässingsnyckeln.,Pirinç Anahtarı aldın. +You picked up the Red Crystal Key.,TXT_REDCRYSTAL,,,,Sebral@[ao_cs] jsi červený krystalový klíč.,Du samlede den røde krystalnøgle op.,Du hast den roten Kristallschlüssel genommen.,,Vi prenis la Ruĝan Kristalan Ŝlosilon.,Recogiste la Llave de Cristal Rojo.,,Poimit punaisen kristalliavaimen.,Vous avez pris la clé cristal rouge.,Felvetted a Vörös Kristály Kulcsot.,Hai raccolto la chiave del Cristallo Rosso.,赤水晶のキー 取得。,적색 크리스탈 키를 획득했다.,Je hebt de rode kristallen sleutel opgepakt.,Du plukket opp den røde krystallnøkkelen.,Podniosł@[irreg_3_pl] Czerwony Kryształowy Klucz.,Você pegou a Chave de Cristal Vermelho.,Apanhaste a Chave de Cristal Vermelho.,Ai ridicat Cheia din Cristal Roșu.,Получен красный ключ-кристалл.,Покупио си кључ од црвеног кристала,Du plockade upp den röda kristallnyckeln.,Kırmızı Kristal Anahtarı aldın. +You picked up the Blue Crystal Key.,TXT_BLUECRYSTAL,,,,Sebral@[ao_cs] jsi modrý krystalový klíč.,Du samlede den blå krystalnøgle op.,Du hast den blauen Kristallschlüssel genommen.,,Vi prenis la Bluan Kristalan Ŝlosilon,Recogiste la Llave de Cristal Azul.,,Poimit sinisen kristalliavaimen.,Vous avez pris la clé cristal bleu.,Felvetted a Kék Kristály Kulcsot.,Hai raccolto la chiave del Cristallo Blu.,青水晶のキー 取得。,청색 크리스탈 키를 획득했다.,Je hebt de blauwe kristallen sleutel opgepakt.,Du plukket opp den blå krystallnøkkelen.,Podniosł@[irreg_3_pl] Niebieski Kryształowy Klucz.,Você pegou a Chave de Cristal Azul.,Apanhaste a Chave de Cristal Azul.,Ai ridicat Cheia din Cristal Albastru.,Получен синий ключ-кристалл.,Покупио си кључ од плавог кристала,Du plockade upp den blå kristallnyckeln.,Mavi Kristal Anahtarı aldın. +You picked up the Chapel Key.,TXT_CHAPELKEY,,,,Sebral@[ao_cs] jsi klíč ke kapli.,Du samlede Kapel-nøglen op.,Du hast den Kapellenschlüssel genommen.,,Vi prenis la Ŝlosilon de la Preĝejeto.,Recogiste la Llave de la Capilla.,,Poimit kappelin avaimen.,Vous avez pris la clé de la chapelle.,Felvetted a Kápolna Kulcsát.,Hai raccolto la chiave della Cappella,チャペルキー 取得。,예배당 키를 획득했다.,Je hebt de kapelsleutel opgepakt.,Du plukket opp kapellnøkkelen.,Podniosł@[irreg_3_pl] Klucz do Kaplicy.,Você pegou a Chave da Capela.,Apanhaste a Chave da Capela.,Ai ridicat Cheia Capelei.,Получен ключ от часовни.,Покупио си кључ капеле,Du plockade upp kapellnyckeln.,Şapel Anahtarını aldın. +You picked up the Catacomb Key.,TXT_CATACOMBKEY,,,,Sebral@[ao_cs] jsi klíč do katakomb.,Du samlede Katakombe-nøglen op.,Du hast den Katakombenschlüssel genommen.,,Vi prenis la Ŝlosilon de la Katakombo.,Recogiste la Llave de la Catacumba.,,Poimit katakombin avaimen.,Vous avez pris la clé des catacombes.,Felvetted a Katakombák kulcsát.,Hai raccolto la chiave delle Catacombe.,カタコンベキー 取得。,고대 묘지 키를 획득했다.,Je hebt de catacombesleutel opgepakt.,Du plukket opp Katakomb-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Katakumb.,Você pegou a Chave da Catacumba.,Apanhaste a Chave da Catacumba.,Ai ridicat Cheia Catacombei.,Получен ключ от катакомб.,Покупио си кључ катакомбе,Du plockade upp katakomberna nyckeln.,Yeraltı Mezarı Anahtarını aldın. +You picked up the Security Key.,TXT_SECURITYKEY,,,,Sebral@[ao_cs] jsi klíč ochranky.,Du samlede sikkerhedsnøglen op.,Du hast den Sicherheitsschlüssel genommen.,,Vi prenis la Sekurecŝlosilon.,Recogiste la Llave de Seguridad.,,Poimit turvamiesavaimen.,Vous avez pris la clé de la sécurité.,Felvetted a Biztonsági Kulcsot.,Hai raccolto la chiave della Sicurezza.,警備のキー 取得。,보안 키를 획득했다.,Je hebt de beveiligingssleutel opgepakt.,Du plukket opp Sikkerhetsnøkkelen.,Podniosł@[irreg_3_pl] Klucz Ochrony.,Você pegou a Chave de Seguranca.,Apanhaste a Chave de Segurança,Ai ridicat Cheia Securității.,Получен ключ охраны.,Покупио си кључ обезбеђења,Du plockade upp säkerhetsnyckeln.,Güvenlik Anahtarını aldın. +You picked up the Core Key.,TXT_COREKEY,,,,Sebral@[ao_cs] jsi klíč k jádru.,Du samlede reaktornøglen op.,Du hast den Reaktorschlüssel genommen.,,Vi trovis la ŝlosilon de la kernejo.,Encuentras la llave del núcleo.,Hallaste la llave del núcleo.,Poimit ytimen avaimen.,Vous avez pris la clé du réacteur.,Felvetted a Mag kulcsát.,Hai raccolto la chiave del Nucleo.,コアキー 取得。,중심부 키를 획득했다.,Je hebt de kernsleutel opgepakt.,Du plukket opp Kjernenøkkelen.,Podniosł@[irreg_3_pl] Klucz do Rdzenia.,Você pegou a Chave do Núcleo.,Apanhaste a Chave do Núcleo.,Ai ridicat Cheia Nucleului.,Получен ключ от реактора.,Покупио си кључ језгра,Du plockade upp kärnnyckeln.,Çekirdek Anahtarını aldın. +You picked up the Mauler Key.,TXT_MAULERKEY,,,,Sebral@[ao_cs] jsi klíč k trhačům.,Du samlede Mauler-nøglen op.,Du hast den Vernichterschlüssel genommen.,,Vi havas la ŝlosilon de la vundegiloj.,Tiene la llave de los trituradores.,,Poimit moukarin avaimen.,Vous avez pris la clé du Broyeur.,Felvetted a Marcangoló kulcsot.,Hai raccolto la chiave del Pestatore.,マウラーキー 取得。,마울러 키를 획득했다.,Je hebt de toetakelaarssleutel opgepakt.,Du plukket opp Mauler-nøkkelen.,Podniosł@[irreg_3_pl] Klucz do Magazynu Miażdżycieli.,Você pegou a Chave do Mauler.,Apanhaste a Chave do Mauler.,Ai ridicat Cheia Sfâșietorului.,Получен ключ истязателя.,Покупио си кључ Маулера.,Du plockade upp Mauler-nyckeln.,Mauler Anahtarını aldın. +You picked up the Factory Key.,TXT_FACTORYKEY,,,,Sebral@[ao_cs] jsi klíč do továrny.,Du samlede fabriksnøglen op.,Du hast den Fabrikschlüssel genommen.,,Vi prenis la Ŝlosilon de la Fabriko.,Recogiste la Llave de la Fábrica.,,Poimit tehtaan avaimen.,Vous avez pris la clé de l'usine.,Felvetted a Gyár kulcsát.,Hai raccolto la chiave della Fabbrica.,工場のキー 取得。,공장 키를 획득했다.,Je hebt de fabriekssleutel opgepakt.,Du plukket opp fabrikknøkkelen.,Podniosł@[irreg_3_pl] Klucz do Fabryki.,Você pegou a Chave da Fábrica.,Apanhaste a Chave da Fábrica.,Ai ridicat Cheia Fabricii.,Получен ключ от фабрики.,Покупио си кључ фабрике,Du plockade upp fabriksnyckeln.,Fabrika Anahtarını aldın. +You picked up the Mine Key.,TXT_MINEKEY,,,,Sebral@[ao_cs] jsi klíč do dolů.,Du samlede minenøglen op.,Du hast den Minenschlüssel genommen.,,Vi prenis la Ŝlosilon de la Minejo.,Recogiste la Llave de la Mina.,,Poimit kaivoksen avaimen.,Vous avez pris la clé de la mine.,Felvetted a Bánya kulcsát.,Hai raccolto la chiave della Miniera.,鉱山のキー 取得。,탄광 키를 획득했다.,Je hebt de mijnsleutel opgepakt.,Du plukket opp Gruvenøkkelen.,Podniosł@[irreg_3_pl] Klucz do Kopalni.,Você pegou a Chave da Mina.,Apanhaste a Chave da Mina.,Ai ridicat Cheia Minei.,Получен ключ от шахт.,Покупио си кључ рудника,Du plockade upp gruvnyckeln.,Maden Anahtarını aldın. +You picked up the New Key5.,TXT_NEWKEY5,,,,Sebral@[ao_cs] jsi nový klíč 5.,Du samlede den nye nøgle5 op.,Du hast den neuen Schlüssel 5 genommen.,,Vi prenis la Novan Ŝlosilon5.,Recogiste la Llave Nueva5.,,Poimit uuden 5-avaimen.,Vous avez pris la nouvelle clé 5.,Felvetted az 5. kulcsot.,Hai raccolto la Nuova Chiave n.5,ニューキー5 取得。,새로운 키5를 획득했다.,Je hebt de nieuwe sleutel 5 opgepakt.,Du plukket opp den nye nøkkelen5.,Podniosł@[irreg_3_pl] Nowy Klucz5,Você pegou a Chave Nova 5.,Apanhaste a Chave Nova 5.,Ai ridicat Cheia Nouă5.,Получен новый ключ №5.,Покупио си нови кључ5,Du hämtade den nya nyckeln5.,Yeni Anahtar5'i aldın. +You picked up the Oracle Pass.,TXT_ORACLEPASS,,,,Sebral@[ao_cs] jsi věštcovu propustku.,Du samlede orakelpas op.,Du hast den Orakelpass genommen.,,Vi prenis la Pasaĵo de la Okralo.,Recogiste el Pase del Oráculo.,,Poimit Oraakkelin passin.,Vous avez pris le passe de l'Oracle.,Felvetted az Orákulum Belépőkártyáját.,Hai raccolto il Lasciapassare dell'Oracolo.,オラクルパス 取得。,오라클의 통행증을 획득했다.,Je hebt de Orakelkaart opgepakt.,Du plukket opp Orakelpasset.,Podniosł@[irreg_3_pl] Przepustkę Wyroczni.,Você pegou o Passe do Oráculo.,Apanhaste o Passe do Oráculo.,Ai ridicat Legitimația Oracol.,Получен пропуск Оракула.,Покупио си пророкову пропусницу,Du plockade upp orakelpasset.,Kahin Geçiş Kartını aldın. +You picked up the HE-Grenade Rounds.,TXT_HEGRENADES,,,,Sebral@[ao_cs] jsi výbušné granáty.,Du samlede HE-granaterne op.,Du hast die HE-Granaten genommen.,,Vi prenis la PE-Gernadmuniciojn.,Recogiste las Granadas HE.,,Poimit räjähdekranaattiammuksia.,Vous avez pris les Grenades Explosives.,Felvetted a robbanó gránátot.,Hai raccolto delle granate ad Alto Potenziale,HEグレネード弾 入手。,고폭 유탄을 획득했다.,Je hebt de HE-granaten opgepakt.,Du plukket opp HE-granaten.,Podniosł@[irreg_3_pl] Wiązkę Granatów.,Você pegou as Granadas Explosivas.,Apanhaste as Granadas Explosivas.,Ai ridicat Grenadele Explozive.,Получена связка гранат.,Покупио си ХЕ-Граната чауре,Du plockade upp HE-granaterna.,HE-Bombası Mermilerini aldın. +You picked up the Phosphorus-Grenade Rounds.,TXT_PHGRENADES,,,,Sebral@[ao_cs] jsi fosforové granáty.,Du samlede fosforgranaterne op.,Du hasr die Phosphorgranaten genommen.,,Vi prenis la Fosforajn Gernadmuniciojn.,Recogiste las Granadas de Fósforo.,,Poimit fosforikranaattiammuksia.,Vous avez pris les Grenades Phosphoriques.,Felvetted a foszfor-gránátokat.,Hai raccolto delle Granate al Fosforo.,白リングレネード弾 入手。,소이 유탄을 획득했다.,Je hebt de fosforgranaten opgepakt.,Du plukket opp fosforgranaten.,Podniosł@[irreg_3_pl] Wiązkę Fosforowych Granatów.,Você pegou as Granadas de Fósforo.,Apanhaste as Granadas de Fósforo.,Ai ridicat Grenadele cu Fosfor.,Получена связка фосфорных гранат.,Покупио си шаржер фосфорних граната.,Du plockade upp fosforgranater.,Fosforlu El Bombası Mermilerini aldın. +You picked up the clip of bullets.,TXT_CLIPOFBULLETS,,,,Sebral@[ao_cs] jsi zásobník s náboji.,Du samlede patroner op.,Du hast die Gewehrmunition genommen.,Πήρες το κουτάκι με σφαίρες.,Vi prenis la kuglujon.,Recogiste un cargador con balas.,,Poimit luotilippaan.,Vous avez pris le Chargeur.,Felvettél egy tár lőszert.,Hai raccolto un caricatore di proiettili.,銃弾倉 入手。,돌격소총 탄창을 획득했다.,Je hebt de patroon met kogels opgepakt.,Du plukket opp magasinet med kuler.,Podniosł@[irreg_3_pl] magazynek.,Você pegou o carregador.,Apanhaste o carregador.,Ai ridicat cartușul cu gloanțe.,Получена обойма.,,Du plockade upp ett magasin med kulor.,Mermi şarjörünü aldın. +You picked up the box of bullets.,TXT_BOXOFBULLETS,,,,Sebral@[ao_cs] jsi krabici nábojů.,Du samlede kassen med kugler op.,Du hast die Munitionskiste genommen.,Πήρες το κουτί με σφαίρες.,Vi prenis la kuglarujon.,Recogiste una caja de balas.,,Poimit luotilaatikon.,Vous avez pris la boîte de balles.,Felvettél egy doboz lőszert.,Hai raccolto una scatola di proiettili.,弾薬箱 入手。,돌격소총 탄약 박스를 획득했다.,Je hebt de doos met kogels opgepakt.,Du plukket opp esken med kuler.,Podniosł@[irreg_3_pl] pudło z amunicją.,Você pegou a caixa de balas.,Apanhaste a caixa de balas.,Ai ridicat cutia cu gloanțe.,Получена коробка пуль.,Покупио си кутију меткова,Du plockade upp lådan med kulor.,Mermi kutusunu aldın. +You picked up the mini missiles.,TXT_MINIMISSILES,,,,Sebral@[ao_cs] jsi minirakety.,Du samlede mini-missiler op.,Du hast die Miniraketen genommen.,Πήρες τους μινι-πυράυλους.,Vi prenis la misiletojn.,Recogiste mini misiles.,,Poimit miniohjuksia.,Vous avez pris les mini-missiles.,Felvetted a minirakétákat.,Hai raccolto dei mini-missili.,ミニミサイル 入手。,미니 미사일 꾸러미를 획득했다.,Je hebt de mini-raketten opgepakt.,Du plukket opp minirakettene.,Podniosł@[irreg_3_pl] mini pociski.,Você pegou os mini-mísseis.,Apanhaste os mini-mísseis.,Ai ridicat mini proiectilele.,Получены мини-ракеты.,Покупио си мини ракете,Du plockade upp miniraketerna.,Mini füzeleri aldın. +You picked up the crate of missiles.,TXT_CRATEOFMISSILES,,,,Sebral@[ao_cs] jsi bednu miniraket.,Du samlede kassen med missiler op.,Du hast die Miniraketenkiste genommen.,Πήρες το κιβώτιο με πυράυλους.,Vi prenis la misilarujon.,Recogiste una caja de misiles.,,Poimit ohjuslaatikon.,Vous avez pris la caisse de missiles.,Felvettél egy ládányi minirakétát.,Hai raccolto una cassa di missili.,ミサイルの箱 入手。,미니 미사일 박스를 획득했다.,Je hebt de kist met raketten opgepakt.,Du plukket opp kassen med missiler.,Podniosł@[irreg_3_pl] skrzynię z pociskami.,Você pegou a caixa de mísseis.,Apanhaste a caixa de mísseis.,Ai ridicat lada cu proiectile.,Получен ящик мини-ракет.,Покупио си кутију ракета,Du plockade upp lådan med missiler.,Füze sandığını aldın. +You picked up the energy pod.,TXT_ENERGYPOD,,,,Sebral@[ao_cs] jsi energetický kokón.,Du samlede energipoden op.,Du hast die Energiezelle genommen.,,Vi prenis la umon de energio.,Recogiste una vaina de energía.,,Poimit energia-akun.,Vous avez pris la cellule d'énergie.,Felvettél egy energiahüvelyt.,Hai raccolto un nucleo energetico.,エネルギーポット 入手。,에너지 포드를 획득했다.,Je hebt de energiecel opgepakt.,Du plukket opp energikapselen.,Podniosł@[irreg_3_pl] kapsułę energii.,Você pegou a célula de energia (pequeno).,Apanhaste a célula de energia (pequeno).,Ai ridicat capsula cu energie.,Получена энергокапсула.,Покупио си енергетско постоље.,Du plockade upp energipodden.,Enerji kapsülünü aldın. +You picked up the energy pack.,TXT_ENERGYPACK,,,,Sebral@[ao_cs] jsi energetický svazek.,Du samlede energipakken op.,Du hast das Energiepack genommen.,,Vi prenis la pako de energio.,Recogiste un pack de energía.,,Poimit energiapaketin.,Vous avez pris le pack énergétique.,Felvetted az energiacsomagot.,Hai raccolto una carica energetica grande.,エネルギーパック 入手。,에너지 팩을 획득했다.,Je hebt het energiepak opgepakt.,Du plukket opp energipakken.,Podniosł@[irreg_3_pl] zasobnik energii.,Você pegou a célula de energia (grande).,Apanhaste a célula de energia (grande).,Ai ridicat pachetul cu energie.,Получен энергокомплект.,Покупио си пакет енергије,Du plockade upp energipaketet.,Enerji paketini aldın. +You picked up the poison bolts.,TXT_POISONBOLTS,,,,Sebral@[ao_cs] jsi otrávené šípy.,Du samlede giftboltene op.,Du hase die Giftbolzen genommen.,,Vi prenis la venenajn sagetojn.,Recogiste las flechas venenosas.,,Poimit myrkkynuolia.,Vous avez pris les carreaux empoisonnés.,Felvetted a mérgezett nyilakat.,Hai raccolto dei dardi velenosi.,ポイズンボルト 入手。,맹독 볼트를 획득했다.,Je hebt de gifbouten opgepakt.,Du plukket opp giftboltene.,Podniosł@[irreg_3_pl] zatrute bełty.,Você pegou as setas envenenadas.,Apanhaste as setas envenedadas.,Ai ridicat bolțurile cu otravă.,Получены отравленные болты.,Покупио си отровне стреле,Du plockade upp giftbultarna.,Zehirli cıvataları aldın. +You picked up the electric bolts.,TXT_ELECTRICBOLTS,,,,Sebral@[ao_cs] jsi elektrické šípy.,Du samlede de elektriske bolte op.,Du hast die elektrischen Bolzen genommen.,,Vi prenis la elektrajn sagetojn.,Recogiste las flechas eléctricas.,,Poimit sähkönuolia.,Vous avez pris les carreaux électriques.,Felvetted az elektromos nyilakat.,Hai raccolto dei dardi elettrici.,エレクトリックボルト 入手。,전격 볼트를 획득했다.,Je hebt de elektrische bouten opgepakt.,Du plukket opp de elektriske boltene.,Podniosł@[irreg_3_pl] elektryczne bełty.,Você pegou as setas eletricas.,Apanhaste as setas electricas.,Ai ridicat bolțurile cu electricitate.,Получены электрические болты.,Покупио си електричне стреле,Du plockade upp de elektriska bultarna.,Elektrikli cıvataları aldın. +You picked up the ammo satchel.,TXT_AMMOSATCHEL,,,,Sebral@[ao_cs] jsi brašnu na munici.,Du samlede ammunitionstasken op.,Du hast die Munitionstasche genommen.,,Vi prenis la municiingo.,Recogiste un estuche de munición.,,Poimit ammuslaukun.,Vous avez pris la sacoche de munitions,Felvetted a lőszeres táskát.,Hai raccolto una Borsa delle Munizioni.,弾薬鞄 入手。,탄약 배낭을 획득했다.,Je hebt de munitietas opgepakt.,Du plukket opp ammunisjonsvesken.,Podniosł@[irreg_3_pl] torbę z amunicją.,Você pegou a mochila de munição.,Apanhaste a mochila de munição.,Ai ridicat sacoșa cu muniție.,Получен ранец боеприпасов.,Покупио си торбицу муниције,Du plockade upp ammunitionsväskan.,Cephane çantasını aldın. +You have a feeling that it wasn't to be touched...,MSG_TALISMANRED,,,,"Máš pocit, že jsi na to sahat neměl@[ao_cs]...","Du har en fornemmelse af, at den ikke måtte røres...","Du hast das Gefühl, dass man es nicht anfassen sollte...",,"Vi sentas, ke ĝi ne devas tuŝiĝi...",Tienes la sensación de que no debía ser tocado...,,"Sinusta tuntuu, ettei siihen olisi pitänyt koskea.",Vous avez un pressentiment qu'il ne fallait pas y toucher.....,Úgy érzed azt nem kéne megérinteni...,Hai la sensazione che non doveva essere toccato...,己の勘が 触れてはならない物だと訴えている...,"결코, 만지면 안 된다는 생각이 든다...",Je hebt het gevoel dat het niet aangeraakt dient te worden...,Du har en følelse av at den ikke skulle røres...,"Czujesz, że trzeba było tego nie dotykać...",Você tem um pressentimento de que isso não devia ser tocado...,Tens um pressentimento que não devias ter mexido nisso.,Ai sentimentul că nu trebuia atinsă...,"Кажется, эту вещь лучше не трогать...",Имаш осећај да није требало бити дирано...,Du har en känsla av att den inte fick röras...,İçinizde dokunulmaması gerektiğine dair bir his var. +"Whatever it is, it doesn't belong in this world...",MSG_TALISMANGREEN,,,,"Je jedno, co to je, do tohoto světa to nepatří...","Uanset hvad det er, hører det ikke hjemme i denne verden...","Was auch immer es ist, es gehört nicht in diese Welt...","Οτιδήποτε είναι, δέν είναι απο αυτό τον κόσμο...","Kio ajn ĝi estas, ĝi ne apartenas al ĉi tiu mundo...","Sea lo que sea, no pertenece a este mundo...",,"Mikä ikinä se onkaan, se ei kuulu tähän maailmaan...","Quel que soit cette chose, elle ne devrait pas être ici...","Bármi legyen ez, nem ebben a világban van a helye...","Qualunque cosa sia, non appartiene a questo mondo...",何であろうと、この世には属さない物だ...,뭔지는 몰라도 이 세상에 속한 것이 아닌 것 같다...,"Wat het ook is, het hoort niet thuis in deze wereld...","Uansett hva det er, hører det ikke hjemme i denne verden...","Cokolwiek to jest, nie należy to do tego świata...","Seja o que for, isso não pertence a este mundo...","O que quer que isso seja, não pertence a este mundo...","Orice ar fi, nu are ce căuta în lumea asta...","Что бы это ни было, оно не из этого мира...","Шта год да је, не припада овом свету...",Vad det än är så hör det inte hemma i den här världen...,"O her neyse, bu dünyaya ait değil." +It must do something...,MSG_TALISMANBLUE,,,,Něco to dělat musí...,Det må gøre noget...,Es muss etwas tun...,Πρέπει να κάνι κάτι...,Ĝi devas fari ion...,Debe hacer algo...,,Sen on pakko tehdä jotakin...,Ca doit servir a quelque chose...,Valamit kell hogy csináljon...,Deve fare qualcosa...,何かを成し遂げなければならない...,분명히 뭔가를 할 것이다...,Het moet iets doen....,Det må gjøre noe...,To musi coś robić...,Deveria fazer alguma coisa...,Devia fazer alguma coisa.,Trebuie să facă ceva...,Оно ведь зачем-то нужно?..,Мора урадити нешто...,Det måste göra något...,Bir şey yapmalı. +You have super strength!,MSG_TALISMANPOWER,,,,Získal@[ao_cs] jsi super sílu!,Du har superstyrke!,Du hast Superkräfte,,Vi havas superan forton!,¡Tienes superfuerza!,,Sinulla on supervoimat!,Vous avez une puissance inégalée!,Tied a Szuper Erő!,Hai la super forza!,豪剛なる力を得た!,엄청난 힘이 솟는다!,Je hebt superkracht!,Du har superkrefter!,Masz super siłę!,Você tem a super força!,Tu tens super força!,Ai super forță!,Вы получили сверхсилу!,Имаш супер снагу!,Du har superstyrka!,Süper gücün var! +,,Locks,,,,,,,,,,,,,,,,,,,,,,,,, +You don't have the key,TXT_NEEDKEY,,,,Nemáš klíč.,Du har ikke nøglen,Du hast den Schlüssel nicht,Δέν έχεις το κλειδί,Vi ne havas la ŝlosilon,No tienes la llave,,Sinulla ei ole avainta,Vous n'avez pas la clé.,Ehhez nincs kulcsod.,Non hai la chiave necessaria,キーを持っていない,필요한 열쇠가 없다,Je hebt de sleutel niet.,Du har ikke nøkkelen,Nie masz klucza,Você não tem a chave,Tu não tens a chave,Nu ai cheia,Нужен ключ,Немаш кључ,Du har inte nyckeln.,Anahtar sende değil. +You need a passcard,TXT_NEED_PASSCARD,,,,Potřebuješ průkaz.,Du har brug for et adgangskort,Du brauchst eine Zugangskarte.,,Vi bezonas central-ŝlosilon,Necesitas la llave de la central,,Tarvitset avainkortin,Vous avez besoin du passe.,Belépőkártyára lesz szükséged.,Ti serve un lasciapassare,パスカード が必要だ,통행 카드가 필요하다,Je hebt een doorgangskaart nodig.,Du trenger et passerkort,Potrzebujesz karty dostępu,Você precisa de um cartão de acesso,Precisas de um cartão de acesso,Ai nevoie de un card de acces,Нужен пропуск,Треба ти пропусница,Du behöver ett passerkort.,Bir erişim kartına ihtiyacınız var You need a pass card key to open this door,TXT_NEED_PASSCARD_DOOR,,,,Pro otevření dveří potřebuješ průkaz.,Du skal bruge en adgangskort for at åbne denne dør,"Du brauchst eine Zugangskarte, um diese Tür zu öffnen.",,"Vi bezonas central-ŝlosilon por malfermi tiun pordon.","Necesitas una llave de la central para abrir esta puerta",,Tarvitset avainkortin tämän oven avaamiseksi,Vous avez besoin du passe ouvrir cette porte.,Belépőkártya nélkül nem nyílik ez az ajtó.,Ti serve una tessera lasciapassare per aprire questa porta.,このドアには パスカード が必要だ,이 문을 열기 위해서는 통행 카드가 필요하다,Je hebt een doorgangskaart nodig om deze deur te openen.,Du trenger en passerkortnøkkel for å åpne denne døren.,Potrzebujesz karty dostępu aby otworzyć te drzwi,Você precisa de um cartão de acesso para abrir esta porta,Precisas de um cartão de acesso para abrir esta porta,"Ai nevoie de un card de acces ca să deschizi ușa -asta",Для открытия нужен пропуск,Треба ти пасош да отвориш ова врата,Bu kapıyı açmak için bir erişim kartı anahtarına ihtiyacınız var -You need an ID card,TXT_NEED_IDCARD,,,,Potřebuješ identifikační kartu.,Du skal bruge et ID-kort,Du brauchst einen Ausweis.,,Vi bezonas identigil-karton.,Necesitas una tarjeta de Identificación,,Tarvitset henkilökortin,Vous avez besoin d'une carte d'identité.,Igazolvány szükséges,Ti serve una tessera identificativa.,IDカード が必要だ,신분증이 필요하다,Je hebt een ID-kaart nodig.,Du trenger et ID-kort,Potrzebujesz karty identyfikacyjną,Você precisa do cartão de identificação,Precisas do cartão de identificação,Ai nevoie de un card de identitate,Нужна личная карта,Треба ти идентификациона картица,Bir kimlik kartına ihtiyacınız var -You don't have the key to the prison,TXT_NEED_PRISONKEY,,,,Nemáš klíč do vězení.,Du har ikke nøglen til fængslet,Du brauchst den Schlüssel zum Gefängnis,,Vi ne havas la ŝlosilon de la malliberejo.,No tienes la llave a la prisión,,Sinulla ei ole vankilan avainta,Vous n'avez pas la clé de la prison.,Nincs kulcsod a börtönhöz.,Ti manca la chiave per la prigione,刑務所のキーを持っていない,감옥에 입장하기 위한 열쇠가 없다,Je hebt de sleutel van de gevangenis niet.,Du har ikke nøkkelen til fengselet.,Nie masz klucza do więzienia,Você não tem a chave da prisão,Não tens a chave da prisão,Nu ai cheia închisorii,Нужен ключ от тюрьмы,Треба ти кључ затвора,Hapishanenin anahtarı sende değil. -Hand print not on file,TXT_NEED_HANDPRINT,,,,Otisk ruky není v databázi.,Håndaftryk er ikke registreret,Handabdruck nicht gespeichert!,,Manspuro ne registrita,Huella de la mano no registrada,,Kädenjälki puuttuu tiedostosta,Votre main n'est pas reconnue par le scanner.,Azonosítatlan kézlenyomat.,Impronta digitale non in archivio,手形認証が一致しません,알 수 없는 지문입니다,Handafdruk niet in het bestand.,Håndavtrykk finnes ikke i filen,Brak odcisku dłoni w bazie danych,Biometria não autorizada,Impressão digital não autorizada,Amprenta mâinii nerecunoscută,Отпечаток руки не распознан,Отисак длана није у записнику,El izi dosyada yok -You need the Gold Key,TXT_NEED_GOLDKEY,,,,Potřebuješ zlatý klíč.,Du har brug for guldnøglen,Du brauchst den goldenen Schlüssel,,Vi bezonas la oran ŝlosilon.,Necesitas la llave dorada,,Tarvitset kulta-avaimen,Vous avez besoin d'une clé d'or.,Aranykulcs szükséges.,Ti serve la chiave dorata,ゴールドキーが必要だ,황금 키가 필요하다,Je hebt de gouden sleutel nodig.,Du trenger gullnøkkelen,Potrzebujesz Złotego Klucza,Você precisa da Chave de Ouro,Precisas da Chave de Ouro,Ai nevoie de cheia din Aur,Нужен золотой ключ,Треба ти златни кључ,Altın Anahtara ihtiyacınız var -You need an ID Badge,TXT_NEED_IDBADGE,,,,Potřebuješ identifikační odznak.,Du har brug for et ID-badge,Du brauchst eine Identitätskarte.,,Vi bezonas malliberejan insignon.,Necesitas una insignia de la prisión,,Tarvitset henkilötunnisteen,Vous avez besoin d'un badge d'identification.,Azonosító jelvény szükséges.,Ti serve un distintivo di identificazione,IDバッジが必要だ,신분 휘장이 필요하다,Je hebt een ID-badge nodig.,Du trenger en ID-badge,Potrzebujesz Odznaki Identyfikacyjnej,Você precisa do Crachá de Identificação,Precisas do Crachá de Identificação,Ai nevoie de un ecuson de identificare,Нужна личная карта,Треба ти лична карта,Bir Kimlik Rozetine ihtiyacınız var +asta",Для открытия нужен пропуск,Треба ти пасош да отвориш ова врата,Du behöver ett passerkort för att öppna den här dörren.,Bu kapıyı açmak için bir erişim kartı anahtarına ihtiyacınız var +You need an ID card,TXT_NEED_IDCARD,,,,Potřebuješ identifikační kartu.,Du skal bruge et ID-kort,Du brauchst einen Ausweis.,,Vi bezonas identigil-karton.,Necesitas una tarjeta de Identificación,,Tarvitset henkilökortin,Vous avez besoin d'une carte d'identité.,Igazolvány szükséges,Ti serve una tessera identificativa.,IDカード が必要だ,신분증이 필요하다,Je hebt een ID-kaart nodig.,Du trenger et ID-kort,Potrzebujesz karty identyfikacyjną,Você precisa do cartão de identificação,Precisas do cartão de identificação,Ai nevoie de un card de identitate,Нужна личная карта,Треба ти идентификациона картица,Du behöver ett ID-kort,Bir kimlik kartına ihtiyacınız var +You don't have the key to the prison,TXT_NEED_PRISONKEY,,,,Nemáš klíč do vězení.,Du har ikke nøglen til fængslet,Du brauchst den Schlüssel zum Gefängnis,,Vi ne havas la ŝlosilon de la malliberejo.,No tienes la llave a la prisión,,Sinulla ei ole vankilan avainta,Vous n'avez pas la clé de la prison.,Nincs kulcsod a börtönhöz.,Ti manca la chiave per la prigione,刑務所のキーを持っていない,감옥에 입장하기 위한 열쇠가 없다,Je hebt de sleutel van de gevangenis niet.,Du har ikke nøkkelen til fengselet.,Nie masz klucza do więzienia,Você não tem a chave da prisão,Não tens a chave da prisão,Nu ai cheia închisorii,Нужен ключ от тюрьмы,Треба ти кључ затвора,Du har inte nyckeln till fängelset.,Hapishanenin anahtarı sende değil. +Hand print not on file,TXT_NEED_HANDPRINT,,,,Otisk ruky není v databázi.,Håndaftryk er ikke registreret,Handabdruck nicht gespeichert!,,Manspuro ne registrita,Huella de la mano no registrada,,Kädenjälki puuttuu tiedostosta,Votre main n'est pas reconnue par le scanner.,Azonosítatlan kézlenyomat.,Impronta digitale non in archivio,手形認証が一致しません,알 수 없는 지문입니다,Handafdruk niet in het bestand.,Håndavtrykk finnes ikke i filen,Brak odcisku dłoni w bazie danych,Biometria não autorizada,Impressão digital não autorizada,Amprenta mâinii nerecunoscută,Отпечаток руки не распознан,Отисак длана није у записнику,Handavtryck finns inte i registret,El izi dosyada yok +You need the Gold Key,TXT_NEED_GOLDKEY,,,,Potřebuješ zlatý klíč.,Du har brug for guldnøglen,Du brauchst den goldenen Schlüssel,,Vi bezonas la oran ŝlosilon.,Necesitas la llave dorada,,Tarvitset kulta-avaimen,Vous avez besoin d'une clé d'or.,Aranykulcs szükséges.,Ti serve la chiave dorata,ゴールドキーが必要だ,황금 키가 필요하다,Je hebt de gouden sleutel nodig.,Du trenger gullnøkkelen,Potrzebujesz Złotego Klucza,Você precisa da Chave de Ouro,Precisas da Chave de Ouro,Ai nevoie de cheia din Aur,Нужен золотой ключ,Треба ти златни кључ,Du behöver guldnyckeln,Altın Anahtara ihtiyacınız var +You need an ID Badge,TXT_NEED_IDBADGE,,,,Potřebuješ identifikační odznak.,Du har brug for et ID-badge,Du brauchst eine Identitätskarte.,,Vi bezonas malliberejan insignon.,Necesitas una insignia de la prisión,,Tarvitset henkilötunnisteen,Vous avez besoin d'un badge d'identification.,Azonosító jelvény szükséges.,Ti serve un distintivo di identificazione,IDバッジが必要だ,신분 휘장이 필요하다,Je hebt een ID-badge nodig.,Du trenger en ID-badge,Potrzebujesz Odznaki Identyfikacyjnej,Você precisa do Crachá de Identificação,Precisas do Crachá de Identificação,Ai nevoie de un ecuson de identificare,Нужна личная карта,Треба ти лична карта,Du behöver ett ID-bricka,Bir Kimlik Rozetine ihtiyacınız var You need an ID Badge to open this door,TXT_NEED_IDBADGE_DOOR,,,,Pro otevření dveří potřebuješ identifikační odznak.,Du har brug for et ID Badge for at åbne denne dør,"Du brauchst eine Identitätskarte, um diese Tür zu öffnen.",,"Vi bezonas malliberejan insignon por malfermi ĉi tiun pordon.","Necesitas una insignia de la prisión para abrir esta puerta",,Tarvitset henkilötunnisteen tämän oven avaamiseksi,Vous avez besoin d'un badge d'identification pour ouvrir cette porte.,Azonosító jelvény szükséges az ajtó kinyitásához.,Ti serve un distintivo di identificazione per superare questa porta,このドアには IDバッジ が必要だ,이 문을 열기 위해서는 신분 휘장이 필요하다,Je hebt een ID-badge nodig om deze deur te openen.,Du trenger en ID-badge for å åpne denne døren,Potrzebujesz Odznaki Identyfikacyjnej aby otworzyć te drzwi,Você precisa do Crachá de Identificação para abrir a porta,Precisas do Crachá de Identificação para abrir a porta,"Ai nevoie de un ecuson de identificare ca să -deschizi ușa",Для открытия нужна личная карта,Треба ти лична карта да отвориш ова врата,Bu kapıyı açmak için kimlik kartına ihtiyacınız var -You need the Silver Key,TXT_NEED_SILVERKEY,,,,Potřebuješ stříbrný klíč.,Du skal bruge sølvnøglen,Du brauchst den Silberschlüssel,,Vi bezonas la arĝentan ŝlosilon. ,Necesitas la llave plateada,,Tarvitset hopea-avaimen,Vous avez besoin de la clé en argent.,Az ezüstkulcs szükséges.,Ti serve la chiave argentata,シルバーキーが必要だ,은 키가 필요하다,Je hebt de zilveren sleutel nodig.,Du trenger sølvnøkkelen,Potrzebujesz Srebrnego Klucza,Você precisa da Chave de Prata,Precisas da Chavede Prata,Ai nevoie de cheia din Argint,Нужен серебряный ключ,Треба ти сребрни кључ,Gümüş Anahtara ihtiyacın var -You need the Brass Key,TXT_NEED_BRASSKEY,,,,Potřebuješ mosazný klíč.,Du skal bruge messingnøglen,Du brauchst den Messingschlüssel,,Vi bezonas la Latunan Ŝlosilon.,Necesitas la Llave de Bronce,,Tarvitset messinkiavaimen,Vous avez besoin de la clé en bronze.,A rézkulcs szükséges.,Ti serve la chiave d'ottone,ブラスキーが必要だ,황동 키가 필요하다,Je hebt de messing sleutel nodig.,Du trenger messingnøkkelen,Potrzebujesz Mosiężnego Klucza,Você precisa da Chave de Latão,Precisas da Chave de Latão,Ai nevoie de cheia din Alamă,Нужен латунный ключ,Треба ти кључ од месинга,Pirinç Anahtara ihtiyacın var -You need the Red Crystal,TXT_NEED_REDCRYSTAL,,,,Potřebuješ červený krystal.,Du skal bruge den røde krystal,Du brauchst den roten Kristall,,Vi bezonas la Ruĝan Kristalon.,Necesitas el Cristal Rojo,,Tarvitset punaisen kristallin,Vous avez besoin du cristal rouge.,A vörös kristályra lesz szükség itt.,Ti serve il Cristallo Rosso,赤水晶のキーが必要だ,적색 크리스탈이 필요하다,Je hebt de rode kristallen sleutel nodig.,Du trenger den røde krystallen,Potrzebujesz Czerwonego Kryształu,Você precisa do Cristal Vermelho,Precisas do Cristal Vermelho,Ai nevoie de Cristalul Roșu,Нужен красный кристалл,Треба ти црвени кристал,Kırmızı Kristal'e ihtiyacın var. -You need the Blue Crystal,TXT_NEED_BLUECRYSTAL,,,,Potřebuješ modrý krystal.,Du skal bruge den blå krystal,Du brauchst den blauen Kristall,,Vi bezonas la Bluan Kristalon.,Necesitas el Cristal Azul,,Tarvitset sinisen kristallin,Vous avez besoin du cristal bleu.,A kék kristályra lesz szükség itt.,Ti serve il Cristallo Blu,青水晶のキーが必要だ,청색 크리스탈이 필요하다,Je hebt de blauwe kristallen sleutel nodig.,Du trenger den blå krystallen,Potrzebujesz Niebieskiego Kryształu,Você precisa do Cristal Azul,Precisas do Cristal Azul,Ai nevoie de Cristalul Albastru,Нужен синий кристалл,Треба ти плави кристал,Mavi Kristal'e ihtiyacın var. +deschizi ușa",Для открытия нужна личная карта,Треба ти лична карта да отвориш ова врата,Du behöver en ID-bricka för att öppna den här dörren.,Bu kapıyı açmak için kimlik kartına ihtiyacınız var +You need the Silver Key,TXT_NEED_SILVERKEY,,,,Potřebuješ stříbrný klíč.,Du skal bruge sølvnøglen,Du brauchst den Silberschlüssel,,Vi bezonas la arĝentan ŝlosilon. ,Necesitas la llave plateada,,Tarvitset hopea-avaimen,Vous avez besoin de la clé en argent.,Az ezüstkulcs szükséges.,Ti serve la chiave argentata,シルバーキーが必要だ,은 키가 필요하다,Je hebt de zilveren sleutel nodig.,Du trenger sølvnøkkelen,Potrzebujesz Srebrnego Klucza,Você precisa da Chave de Prata,Precisas da Chavede Prata,Ai nevoie de cheia din Argint,Нужен серебряный ключ,Треба ти сребрни кључ,Du behöver silvernyckeln,Gümüş Anahtara ihtiyacın var +You need the Brass Key,TXT_NEED_BRASSKEY,,,,Potřebuješ mosazný klíč.,Du skal bruge messingnøglen,Du brauchst den Messingschlüssel,,Vi bezonas la Latunan Ŝlosilon.,Necesitas la Llave de Bronce,,Tarvitset messinkiavaimen,Vous avez besoin de la clé en bronze.,A rézkulcs szükséges.,Ti serve la chiave d'ottone,ブラスキーが必要だ,황동 키가 필요하다,Je hebt de messing sleutel nodig.,Du trenger messingnøkkelen,Potrzebujesz Mosiężnego Klucza,Você precisa da Chave de Latão,Precisas da Chave de Latão,Ai nevoie de cheia din Alamă,Нужен латунный ключ,Треба ти кључ од месинга,Du behöver mässingsnyckeln,Pirinç Anahtara ihtiyacın var +You need the Red Crystal,TXT_NEED_REDCRYSTAL,,,,Potřebuješ červený krystal.,Du skal bruge den røde krystal,Du brauchst den roten Kristall,,Vi bezonas la Ruĝan Kristalon.,Necesitas el Cristal Rojo,,Tarvitset punaisen kristallin,Vous avez besoin du cristal rouge.,A vörös kristályra lesz szükség itt.,Ti serve il Cristallo Rosso,赤水晶のキーが必要だ,적색 크리스탈이 필요하다,Je hebt de rode kristallen sleutel nodig.,Du trenger den røde krystallen,Potrzebujesz Czerwonego Kryształu,Você precisa do Cristal Vermelho,Precisas do Cristal Vermelho,Ai nevoie de Cristalul Roșu,Нужен красный кристалл,Треба ти црвени кристал,Du behöver den röda kristallen,Kırmızı Kristal'e ihtiyacın var. +You need the Blue Crystal,TXT_NEED_BLUECRYSTAL,,,,Potřebuješ modrý krystal.,Du skal bruge den blå krystal,Du brauchst den blauen Kristall,,Vi bezonas la Bluan Kristalon.,Necesitas el Cristal Azul,,Tarvitset sinisen kristallin,Vous avez besoin du cristal bleu.,A kék kristályra lesz szükség itt.,Ti serve il Cristallo Blu,青水晶のキーが必要だ,청색 크리스탈이 필요하다,Je hebt de blauwe kristallen sleutel nodig.,Du trenger den blå krystallen,Potrzebujesz Niebieskiego Kryształu,Você precisa do Cristal Azul,Precisas do Cristal Azul,Ai nevoie de Cristalul Albastru,Нужен синий кристалл,Треба ти плави кристал,Du behöver den blå kristallen,Mavi Kristal'e ihtiyacın var. This area is only available in the retail version of Strife,TXT_RETAIL_ONLY,,,,Tato oblast je dostupná pouze v registrované verzi.,Dette område er kun tilgængeligt i detailudgaven af Strife,Dieser Bereich ist nur in der kompletten Version von Strife erreichbar.,Αυτή η περιοχή είναι μονο διαθέσημη στήν εγραμμένη έκδοση του Strife,"Ĉi tiu loko estas enirebla nur en la komercaĵa versio de Strife","Esta área solo está disponible en la versión completa de Strife",,Tämä alue on saatavilla ainoastaan Strifen kokoversiossa,Cette zone n'est accessible que dans la version complète de Strife.,Ez a terület kizárólag a Strife teljes verziójában érhető el,Quest'area è disponibile solo nella versione completa di Strife.,このエリアは Strifeの製品版でのみ利用可能です,이 구역은 정품 버전에서만 입장이 가능합니다,Deze ruimte is alleen beschikbaar in de verkoopversie van Strife.,Dette området er bare tilgjengelig i salgsversjonen av Strife.,Ten obszar jest dostępny tylko w pełnej wersji Strife,Essa área está disponível apenas na versão registrada de Strife,,"Această zonă e disponibilă doar în versiunea -cumpărată a jocului Strife",Эта локация доступна только в полной версии Strife,Ова област је само доступна у пуној верзији Strife-а,Bu alan yalnızca Strife'ın perakende sürümünde mevcuttur -That doesn't seem to work,TXT_DOES_NOT_WORK,,,,Takhle to nepůjde.,Det ser ikke ud til at virke,Das scheint nicht zu funktionieren,,Tio ŝajne ne funkcias.,Parece que eso no funciona,,Se ei näytä toimivan,Cela ne semble pas fonctionner.,Ez nem akar működni.,Non sembra funzionare,それは作動していない,작동이 안 되는 것 같다,Dat lijkt niet te werken.,Det ser ikke ut til å virke,To zdaje się nie działać,Parece que isso não funciona,,Nu pare să funcționeze,"Похоже, что не работает",То изгледа да не ради,Bu işe yaramıyor gibi görünüyor. -You need the chalice!,TXT_NEED_CHALICE,,,,Potřebuješ kalich!,Du skal bruge bægeret!,Du brauchst den Kelch!,,Vi bezonas la kalikon!,¡Necesitas el Cáliz!,,Tarvitset maljan!,Vous avez besoin du calice!,A Kupára van szükséged!,Hai bisogno del calice.,聖杯が必要だ!,성배가 필요하다!,Je hebt de beker nodig!,Du trenger begeret!,Potrzebujesz kielicha!,Você precisa do cálice!,Precisas do cálice!,Ai nevoie de potir!,Нужна чаша!,Треба ти пехар!,Kadehe ihtiyacın var! +cumpărată a jocului Strife",Эта локация доступна только в полной версии Strife,Ова област је само доступна у пуној верзији Strife-а,Det här området finns bara i detaljhandelsversionen av Strife.,Bu alan yalnızca Strife'ın perakende sürümünde mevcuttur +That doesn't seem to work,TXT_DOES_NOT_WORK,,,,Takhle to nepůjde.,Det ser ikke ud til at virke,Das scheint nicht zu funktionieren,,Tio ŝajne ne funkcias.,Parece que eso no funciona,,Se ei näytä toimivan,Cela ne semble pas fonctionner.,Ez nem akar működni.,Non sembra funzionare,それは作動していない,작동이 안 되는 것 같다,Dat lijkt niet te werken.,Det ser ikke ut til å virke,To zdaje się nie działać,Parece que isso não funciona,,Nu pare să funcționeze,"Похоже, что не работает",То изгледа да не ради,Det verkar inte fungera.,Bu işe yaramıyor gibi görünüyor. +You need the chalice!,TXT_NEED_CHALICE,,,,Potřebuješ kalich!,Du skal bruge bægeret!,Du brauchst den Kelch!,,Vi bezonas la kalikon!,¡Necesitas el Cáliz!,,Tarvitset maljan!,Vous avez besoin du calice!,A Kupára van szükséged!,Hai bisogno del calice.,聖杯が必要だ!,성배가 필요하다!,Je hebt de beker nodig!,Du trenger begeret!,Potrzebujesz kielicha!,Você precisa do cálice!,Precisas do cálice!,Ai nevoie de potir!,Нужна чаша!,Треба ти пехар!,Du behöver kalken!,Kadehe ihtiyacın var! You need the Oracle Pass!,TXT_NEED_OPASS,,,,Potřebuješ propustku od věštce!,Du har brug for orakelpas!,Du brauchst den Orakelpass!,,"Vi bezonas la paspermeson -de la Orakolo!",¡Necesitas el Pase del Oráculo!,,Tarvitset Oraakkelin passin,Vous avez besoin du passe Oracle!,Az Orákulum Engedélyére van szükséged!,Hai bisogno del pass dell'Oracolo.,オラクルパスが必要だ!,오라클 통행증이 필요하다!,Je hebt de Orakelpas nodig!,Du trenger Orakelpasset!,Potrzebujesz Przepustki Wyroczni!,Você precisa do Passe do Oráculo!,Precisas do Passe do Oráculo!,Ai nevoie de legitimația Oracol!,Нужен пропуск Оракула!,Треба ти Пророкова пропусница!,Kahin Kartı'na ihtiyacın var! -,,Actor tags,,,,,,,,,,,,,,,,,,,,,,,, -Dagger,TAG_PUNCHDAGGER,,,,Dýka,Dolk,Dolch,Μαχάιρι,Ponardo,Daga,,Tikari,Dague de Poing,Tőr,Pugnale,ダガー,단검,Dolk,Dolk,Sztylet,Punhal,,Pumnal,Кинжал,Бодеж,Hançer -Crossbow,TAG_STRIFECROSSBOW1,Crossbow with electric bolts,,,Kuše,Armbrøst,Armbrust,Τόξο (Δηλητήριο),Arbalesto (Elektraj sagoj),Ballesta (eléctrica),,Jousipyssy,Arbalète Electrique,Nyílpuska,Balestra ,クロスボウ,석궁 (전격),Kruisboog,Armbrøst,Kusza,Besta,,Arbaletă,Арбалет,Самострел,Arbalet -Crossbow,TAG_STRIFECROSSBOW2,Crossbow with poison bolts,,,Kuše,Armbrøst,Armbrust,Τόξο (Ηλεκτρικό),Arbalesto (Venenaj sagoj),Ballesta (veneno),,Jousipyssy,Arbalète Empoisonée,Nyílpuska,Balestra ,クロスボウ,석궁 (맹독),Kruisboog,Armbrøst,Kusza,Besta,,Arbaletă,Арбалет,Самострел,Arbalet -Assault Gun,TAG_ASSAULTGUN,,,,Útočná puška,Angrebsvåben,Sturmgewehr,,Sturmofusilo,Fusil de asalto,,Rynnäkkökivääri,Fusil d'Assaut,Gépfegyver,Fucile d'Assalto ,アサルトガン,돌격소총,Aanvalswapen,Stormgevær,Karabin Szturmowy,Fuzil de Assalto,Arma de Assalto,Pușcă de Asalt,Штурмовая винтовка,Аутоматска пушка,Saldırı Silahı -Mini Missile Launcher,TAG_MMLAUNCHER,,,,Miniraketomet,Mini-missilkaster,Miniraketenwerfer,Μίνι-Πυραυλοβόλο,Misilet-ĵetilo,Minilanzamisiles,,Miniohjuslaukaisin,Lanceur de Mini-Missiles,Mini Rakétavető,Mini-Lanciamissili,ミニミサイルランチャー,미니 미사일 런쳐,Miniraketwerper,Mini rakettkaster,Wyrzutnia Minipocisków,Mini Lança-mísseis,,Mini Lansator de Proiectile,Мини-гранатомёт,Мини ракетни бацач,Mini Füze Fırlatıcı -Flame Thrower,TAG_FLAMER,,,,Plamenomet,Flammekaster,Flammenwerfer,,Flamĵetilo,Lanzallamas,,Liekinheitin,Lance-Flammes,Lángszóró,Lanciafiamme ,火炎放射器,화염방사기,Vlammenwerper,Flammekaster,Miotacz Ognia,Lança-chamas,,Aruncător de Flăcări,Огнемёт,Бацеч пламена,Alev Fırlatıcı -Mauler,TAG_MAULER1,,,,Trhač,Mauler,Vernichter,,Vundegilo,Triturador (dispersión),,Moukari,Broyeur,Marcangoló,Pestatore ,マウラー,마울러 (저출력),Toetakelaar,Mauler,Miażdżyciel,Desintegrador,,Sfâșietor,Истязатель,Маулер,Parçalayıcı -Mauler,TAG_MAULER2,,,,Trhač,Mauler,Vernichter,,Vundegilo,Triturador (torpedo),,Moukari,Broyeur,Marcangoló,Pestatore,マウラー,마울러 (고출력),Toetakelaar,Mauler,Miażdżyciel,Desintegrador,,Sfâșietor,Истязатель,Маулер,Parçalayıcı -Grenade Launcher,TAG_GLAUNCHER1,High-explosive grenade launcher,,,Granátomet,Granatkaster,Granatwerfer,,Granadĵetilo (PE),Lanzagranadas,,Kranaatinheitin,Lance-Grenades Explosif,Gránátvető,Lanciagranate,グレネードランチャー,유탄발사기 (고폭탄),Granaatwerper,Granatkaster,Wyrzutnia Granatów,Lança-granadas,,Lansator de Grenade,Гранатомёт,Бацач граната,El Bombası Fırlatıcı -Grenade Launcher,TAG_GLAUNCHER2,White phosphorous grenade launcher ,,,Granátomet,Granatkaster,Granatwerfer,,Granadĵetilo (Fosfora),Lanzagranadas (fósforo),,Kranaatinheitin,Lance-Grenades Incendiaire,Gránátvető,Lanciagranate,グレネードランチャー,유탄발사기 (소이탄),Granaatwerper,Granatkaster,Wyrzutnia Granatów,Lança-granadas,,Lansator de Grenade,Гранатомёт,Бацач граната,El Bombası Fırlatıcı -Sigil,TAG_SIGIL,,,,Pečeť,,,,Sigelo,Emblema,,Sinetti,,Pecsét,Sigillo,シジル,시질,Sigil,,Pieczęć,Sigilo,,Sigiliu,Печать,Сигил,Sigil -Coin,TAG_COIN,,,,Mince,Mønt,Münze,,Monero,Moneda,,Kolikko,Pièce,Érme,Moneta,コイン,동전,Munt,Mynt,Moneta,Moeda(s),,Monedă,Монета,Новчић,Madeni Para -Med patch,TAG_MEDPATCH,,,,Obvazy,Medicinsk bandage,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekääre,Pansement,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinsk lapp,Bandaż,Compressa médica,,Trusă de Prim-Ajutor,Бинт,Прва помоћ,Med yama -Medical kit,TAG_MEDICALKIT,,,,Lékárnička,Medicinsk kit,Verbandskasten,,Sukurkesto,Botiquín,,Lääkintälaukku,Kit Médical,Orvosi Készlet,Kit di Pronto Soccorso ,医療キット,구급 키트,Medicijndoos,Medisinsk sett,Apteczka,Kit médico,,Kit de Prim-Ajutor,Аптечка,Медицински прибор,Tıbbi kit -Surgery Kit,TAG_SURGERYKIT,,,,Chirurgická souprava,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kirurgilaukku,Kit de Chirurgie,Sebészeti Készlet,Kit Chirurgico ,手術キット,수술 키트,Chirurgiepakket,Kirurgisk sett,Zestaw Chirurga,Kit de Cirurgia,,Kit pentru Operații,Медкомплект,Хируршки прибор,Ameliyat Kiti -Ring,TAG_BELDINSRING,,,,Prsten,,,,Ringo,Anillo,,Sormus,Anneau,Gyűrű,Anello ,指輪,반지,Ring,,Pierścień,Anel,,Inel,Кольцо,Прстен,Yüzük -Offering Chalice,TAG_OFFERINGCHALICE,,,,Obětní kalich,Offerkalk,Opferkelch,,Oferdona kaliko,Cáliz de ofrenda,,Uhrimalja,Calice d'Obole,Áldozati kehely,Calice delle Offerte,寄贈された聖杯,번제 성배,Offerbeker,Offerbeger,Kielich Ofiarny,Calice de Oferenda,,Potir pentru Ofrande,Чаша для подношений,Жртвени пехар,Adak Kadehi -Ear,TAG_EAR,,,,Ucho,Øre,Ohr,,Orelo,Oreja,,Korva,Oreille,Fül,Orecchio,耳,귀,Oor,Øre,Ucho,Orelha,,Ureche,Ухо,Уво,Kulak -Broken Power Coupling,TAG_BROKENCOUPLING,,,,Rozbitá spojka,Brækket strømkobling,Defekter Stromabnehmer,,Rompita energia kuplilo,Acoplador de energía roto,,Rikkinäinen virtaliitin,Coupleur Energétique cassé,Elromlott Tápcsatlakozó,Coppia Energetica Rotta ,壊れたパワーカップリング,망가진 동력선,Gebroken stroomkoppeling,Ødelagt kraftkobling,Zepsute Obwody Zasilające,Acoplador de Energia Quebrado,Acoplador de Energia Partido,Cuplaj de Putere Defect,Повреждённая муфта,Неисправна спојница напајања,Kırık Güç Kaplini -Shadow Armor,TAG_SHADOWARMOR,,,Shadow Armour,Stínové brnění,Skygge rustning,Schattenrüstung,,Ombra armaĵo,Armadura de sombra,,Varjohaarniska,Armure de l'Ombre,Sötét Páncél,Armatura Ombra ,シャドウアーマー,그림자 갑옷,Schaduwharnas,Skygge rustning,Cienisty Pancerz,Armadura das Sombras,,Armura Umbrei,Теневая броня,Оклоп сенки,Gölge Zırhı -Environmental Suit,TAG_ENVSUIT,,,,Ochranný oblek,Miljømæssig dragt,Schutzanzug,,Medi-ŝirma vesto,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison Hazmat,Védőöltözet,Tuta Ambientale ,耐環境スーツ,환경 방호복,Beschermend pak,Miljødrakt,Skafander Ochronny,Traje de Proteção,Fato Protetor,Costum de Protecție,Защитный костюм,Заштитно одело,Çevresel Takım -Guard Uniform,TAG_GUARDUNIFORM,,,,Hlídačova uniforma,Gardeuniform,Wächteruniform,,Gardista uniformo,Uniforme de guardia,,Vartijan univormu,Uniforme de Garde,Őr Egyenruha,Uniforme da Guardia,ガードの制服,경비 전투복,Wachtersuniform,Vaktuniform,Mundur Strażnika,Uniforme de Guarda,,Uniformă de Paznic,Униформа стражника,Стражарска униформа,Bekçi Üniforması -Officer's Uniform,TAG_OFFICERSUNIFORM,,,,Důstojníkova uniforma,Officersuniform,Offiziersuniform,,Oficira uniformo,Uniforme de oficial,,Upseerin univormu,Uniforme d'Officier,Tiszti Egyenruha,Uniforme da Ufficiale ,士官の制服,장교 전투복,Officiersuniform,Offisersuniform,Mundur Oficera,Uniforme de Oficial,,Uniformă de Ofițer,Офицерская униформа,Официрска униформа,Memur Üniforması -Flame Thrower Parts,TAG_FTHROWERPARTS,,,,Díly plamenometu,Dele til flammekasteren,Flammenwerferteile,,Partoj de flamjetilo,Partes de lanzallamas,,Liekinheittimen osat,Pièces de Lance-Flamme,Lángszóró Alkatrészek,Parti di Lanciafiamme ,火炎放射器の部品,화염방사기 부품,Vlammenwerperonderdelen,Deler til flammekaster,Części Miotacza Ognia,Partes do lança-chamas,,Bucăți de Aruncător de Flăcări,Детали огнемёта,Делови бацача пламена,Alev Püskürtücü Parçaları -Report,TAG_REPORT,,,,Hlášení,Rapport,,,Raporto,Reporte,,Raportti,Compte-rendu,Jelentés,Rapporto ,報告書,보고서,Verslag,Rapport,Raport,Relatório,,Raport,Отчёт,Извештај,Rapor -Info,TAG_INFO,,,,Informace,,,,Informo,Información,,Tiedot,,Információ,Informazioni ,情報,정보,Info,Informasjon,Informacje,Informação,,Informație,Сводка,Инфо,Bilgi -Targeter,TAG_TARGETER,,,,Zaměřovač,,Zielhilfe,,Celilo,Apuntador,,Tähtäinlaite,Cibleur,Célzó eszköz,Puntatore,照準器,조준기,Richter,,Namierzacz,Mira,,Țintitor,Целеуказатель,Нишанџија,Hedefleme cihazı -Communicator,TAG_COMMUNICATOR,,,,Komunikátor,Kommunikator,Kommunikator,,Komunikilo,Comunicador,,Viestintälaite,Communicateur,Kommunikátor,Comunicatore ,コミュニケーター,연락장치,Communicator,Kommunikator,Komunikator,Comunicador,,Comunicator,Передатчик,Комуникатор,İletişimci -Degnin Ore,TAG_DEGNINORE,,,,Degninská ruda,Degnin malm,Degnin-Erz,,Degnina Erco,Mineral Degnin,,Degnin-malmi,Minerai de Degnin,Degnin Érc,Minerale Degnin,デグニン鉱石,데그닌 광석,Degnin-erts,Degnin malm,Ruda Degninu,Minério Degnin,,Minereu de Degnir,Денгинская руда,Дегнинска руда,Degnin Cevheri -Accuracy,TAG_GUNTRAINING,,,,Přesnost,Nøjagtighed,Präzision,,Akurateco,Precisión,,Tarkkuus,Précision,Pontosság,Precisione,精度,정확도,Nauwkeurigheid,Nøyaktighet,Precyzja,Precisão,,Acuratețe,Меткость,Прецизност,Doğruluk -Toughness,TAG_HEALTHTRAINING,,,,Tvrdost,Robusthed,Ausdauer,,Forteco,Dureza,,Sitkeys,Endurance,Kitartás,Robustezza ,タフネス,힘,Stevigheid,Seighet,Wytrzymałość,Força,,Rezistență,Живучесть,Издржљивост,Sertlik -Scanner,TAG_SCANNER,,,,Skener,,,,Skanilo,Escáner,,Skanneri,Analyseur,Szkenner,Scanner,スキャナー,탐지기,Scanner,Skanner,Skaner,Scanner,,Scanner,Сканер,Скенер,Tarayıcı -Prison Pass,TAG_PRISONPASS,,,,Propustka do vězení,Fængselspas,Gefängnispass,,Mallibereja pasilo,Pase a la prisión,,Vankilan pääsylupa,Passe de la Prison,Börtön Engedély,Lasciapassare Prigione ,刑務所の許可証,감옥 통행증,Gevangenispas,Fengselspass,Przepustka do Więzienia,Passe da Prisão,,Legitimația pentru Închisoare,Пропуск в тюрьму,Затворска пропусница,Hapishane Kartı -Alarm,TAG_ALARM,,,,,,,,Alarmo,Alarma,,Hälytys,Alarme,Riasztó,Allarme ,警報,알람,Alarm,,,Alarme,,Alarmă,Тревога,Аларм,Alarm -Ammo,TAG_AMMOFILLUP,,,,Munice,Munition,Munition,,Municio,Munición,,Ammukset,Munitions,Lőszer,Munizioni ,弾薬,탄약,Munitie,Ammunisjon,Amunicja,Munição,,Muniție,Боеприпасы,Муниција,Cephane -Health,TAG_HEALTHFILLUP,,,,Zdraví,Sundhed,Gesundheit,,Sano,Salud,,Terveys,Santé,Életerő,Salute ,体力,체력,Gezondheid,Helse,Zdrowie,Saúde,,Sănătate,Здоровье,Живот,Sağlık -Teleporter Beacon,TAG_TELEPORTERBEACON,,,,Teleportační maják,Teleportør-bakke,Teleportersignal,,Formovila Signalilo,Faro de Teletransportación,,Kaukosiirrinmajakka,Balise de téléportation,Teleport Vészfény,Radiofaro per Teletrasporto ,テレポータービーコン,텔레포터 비콘,Teleporterbaken,Teleporter Beacon,Nadajnik Teleportera,Sinalizador para Teletransporte,,Lumină pentru Teleportor,Телепортационный маяк,Одашиљач за телепортовање,Işınlayıcı İşaretçisi -Metal Armor,TAG_METALARMOR,,,Metal Armour,Kovové brnění,Metal rustning,Metallrüstung,,Metala armaĵo,Armadura de metal,,Metallihaarniska,Armure en Métal,Fém Páncél,Armatura di Metallo ,メタルアーマー,강철 갑옷,Metalen harnas,Metall rustning,Metalowy Pancerz,Armadura de Metal,,Armură din Metal,Металлическая броня,Метални оклоп,Metal Zırh -Leather Armor,TAG_LEATHER,,,Leather Armour,Kožené brnění,Læderpanser,Lederrüstung,,Leda armaĵo,Armadura de cuero,,Nahkasuojus,Armure en Cuir,Bőr Páncél,Armatura di Cuoio,レザーアーマー,가죽 갑옷,Leren harnas,Lær rustning,Skórzany Pancerz,Armadura de Couro,,Armură din Piele,Кожаная броня,Кожни оклоп,Deri Zırh -HE-Grenade Rounds,TAG_HEGRENADES,,,,Výbušné granáty,HE-granater,HE-Granaten,,HE-grenadoj,Granadas HE,,Räjähdekranaatit,Grenades Explosives,Gránát Lőszer,Granata HE,HEグレネード弾,고폭 유탄,HE-granaten,HE-Granater,Wiązka Granatów,Munição - Granadas Explosivas,,Grenade Explozive,Осколочные гранаты,Хе-Граната чауре,HE-Bomba Mermileri -Phosphorus-Grenade Rounds,TAG_PHGRENADES,,,,Fosforové granáty,Fosforgranater,Phosphorgranaten,,Fosforaj grenadoj,Granadas de fósforo,,Fosforikranaatit,Grenades Incendiaires,Foszfor-Gránát Lőszer,Granata al Fosforo ,白リングレネード弾,소이 유탄,Fosforgranaten,Fosforgranater,Wiązka Fosforowych Granatów,Municão - Granadas de Fósforo,,Grenade cu Fosfor,Фосфорные гранаты,Фосфорне гранате,Fosforlu El Bombası Mermileri -Clip of Bullets,TAG_CLIPOFBULLETS,,,,Zásobník s náboji,Kugleklip,Gewehrmunition,,Magazeno,Cargador de balas,,Luotilipas,Chargeur d'Assaut,Golyó töltények,Caricatore di Proiettili ,弾丸のクリップ,소총 탄창,Patroon kogels,Klipp av kuler,Magazynek,Carregador de Balas,,Cartuș cu Gloanțe,Обойма,Клип метака,Kurşun Klipsi -Ammo,TAG_BOXOFBULLETS,,,,Krabice nábojů,Munition,Munitionskiste,,Municikesto,Caja de municiones,,Luotilaatikko,Bôite de Munitions,Lőszer,Munizioni ,弾薬箱,탄약,Munitie,Ammunisjon,Amunicja,Caixa de Balas,,Muniție,Боеприпасы,Муниција,Cephane -Mini Missiles,TAG_MINIMISSILES,,,,Minirakety,Mini missiler,Miniraketen,,Misiletoj,Minimisiles,,Miniohjukset,Mini-Missiles,Mini Rakéták,Mini-Missili,ミニミサイル,미니 미사일,Mini-raketten,Mini missiler,Mini Pociski,Mísseis,,Mini Proiectile,Мини-ракеты,Мини Ракете,Mini Füzeler -Crate of Missiles,TAG_CRATEOFMISSILES,,,,Bedna raket,kasse med missiler,Raketenkiste,,Misilet-kesto,Caja de misiles,,Ohjuslaatikko,Caisse de Mini-Missiles,Ládányi Rakéta,Cassa di Missili,ミサイルの箱,미사일 박스,Krat raketten,Kasse med missiler,Skrzynia z Pociskami,Caixa de Mísseis,,Ladă cu Proiectile,Коробка ракет,Кутија ракета,Füze Sandığı -Energy Pod,TAG_ENERGYPOD,,,,Energetický kokón,Energipod,Energiezelle,,Umo de Energio,Vaina de Energía,,Energia-akku,Cellule Energétique,Energia Lőszer,Nucleo Enegetico ,エネルギーポット,에너지 포드,Energiecel,Energikapsel,Kapsuła Energii,Energia (pequeno),,Capsulă cu Energie,Энергоячейка,Енергетска шипка,Enerji Bölmesi -Energy Pack,TAG_ENERGYPACK,,,,Energetický svazek,Energipakke,Energiepack,,Pako de Energio,Pack de Energía,,Energiapaketti,Pack Energétique,Energia Csomag,Carica Energetica ,エネルギーパック,에너지 팩,Energiepak,Energipakke,Zasobnik Energii,Energia (grande),,Pachet cu Energie,Энергобатарея,Паковање енергије,Enerji Paketi -Poison Bolts,TAG_POISONBOLTS,,,,Otrávené šípy,Giftige bolte,Giftbolzen,,Venenaj sagoj,Flechas venenosas,,Myrkkynuolet,Carreaux Empoisonnés,Mérgező hegyek,Dardi Velenosi ,ポイズンボルト,맹독 볼트,Giftige bouten,Giftbolter,Zatrute Bełty,Setas Envenenadas,,Bolțuri cu Otravă,Отравленные болты,Отровне стреле,Zehirli Cıvatalar -Electric Bolts,TAG_ELECTRICBOLTS,,,,Elektrické šípy,Elektriske bolte,Elektrische Bolzen,,Elektraj sagoj,Flechas eléctricas,,Sähkönuolet,Carreaux Electriques,Elektromos hegyek,Dardi Elettrici ,エレクトリックボルト,전격 볼트,Elektrische bouten,Elektriske bolter,Elektryczne Bełty,Setas Elétricas,,Bolțuri cu Electricitate,Электрические болты,Електричне стреле,Elektrikli Cıvatalar -Ammo Satchel,TAG_AMMOSATCHEL,,,,Brašna na munici,Ammo Satchel,Munitionstasche,,Sako da municioj,Bolso de municiones,,Ammuslaukku,Sacoche à munitions,Lőszeres táska,Borsa di Munizioni ,弾薬鞄,탄약 배낭,Munitietassen,Ammunisjonsveske,Torba z Amunicją,Bolsa de Munição,,Sacoșă cu Muniție,Ранец для боеприпасов,Торбица муниције,Cephane Çantası -Base Key,TAG_BASEKEY,,,,Klíč od základny,Basisnøgle,Basisschlüssel,,Bazŝlosilo,Llave de la base,,Tukikohdan avain,Clé de la base,Bázis Kulcs,Chiave della Base,,기지 키,Basissleutel,Basenøkkel,Klucz do Bazy,Chave da Base,,Cheia Bazei,Ключ от базы,Кључ базе,Temel Anahtar -Govs Key,TAG_GOVSKEY,,,,Klíč ke guvernérovi,Govs nøgle,Gouverneursschlüssel,,Ŝlosilo de registo,Llave Gobernador,,Kuvernöörin avain,Clé du Gouverneur,Kormányzó Kulcs,Chiave del Governatore ,,총독의 키,Gouverneursleutel,Regjeringsnøkkel,Klucz Gubernatora,Chave do Governador,,Cheia Guvernatorului,Ключ губернатора,Гувернеров кључ,Govs Anahtar -Passcard,TAG_PASSCARD,,,,Vstupní karta,Adgangskort,Zugangskarte,,Central-ŝlosilo,Llave de la central,,Avainkortti,Passe,Belépőkártya,Tessera Lasciapassare ,,통행 카드,Paspoortkaart,Adgangskort,Karta Dostępu,Cartão de Acesso,,Legitimație,Пропуск,Пропусница,Geçiş kartı -ID Badge,TAG_IDBADGE,,,,Identifikační odznak,ID-badge,Identitätskarte,,Mallibereja insigno,Insignia de prisión,,Henkilötunniste,Badge d'Identification,Azonosító Jelvény,Distintivo ,,신분 휘장,ID-Badge,ID-badge,Odznaka Identyfikacyjna,Crachá de Identificação,,Ecuson de Identificare,Личная карта,Идентификациона значка,Kimlik Rozeti -Prison Key,TAG_PRISONKEY,,,,Klíč od věznice,Fængselsnøgle,Gefängnisschlüssel,,Mallibereja ŝlosilo,Llave de la prisión,,Vankilan avain,Clé de la Prison,Börtön Kulcs,Chiave della Prigione ,,감옥 키,Gevangenissleutel,Fengselsnøkkel,Klucz do Więzienia,Chave da Prisão,,Cheia Închisorii,Ключ от тюрьмы,Кључ од 3атвора,Hapishane Anahtarı -Severed Hand,TAG_SEVEREDHAND,,,,Useknutá ruka,Afskåret hånd,Abgetrennte Hand,,Amputita mano,Mano amputada,,Katkennut käsi,Main coupée,Levágott Kéz,Mano Mozzata,,잘린 손목,Gescheurde Hand,Avkuttet hånd,Odcięta Ręka,Mão Decepada,Mão Desmenbrada,Mână Retezată,Отрезанная рука,Одвојена шака,Kesik El -Power1 Key,TAG_POWER1KEY,,,,Klíč od elektrárny 1,Power1 nøgle,Kraftwerksschlüssel 1,,Central-identigo 1,Ident. central nv. 1,,Voimalan 1-avain,Clé Power1,1. erő kulcs,Chiave della Centrale 1,,발전소 1호 키,1e Machtsleutel,Power1-nøkkel,Klucz do Elektrowni 1,Chave da Usina 1,Chave Energética 1,Cheia Putere1,Ключ ЭС №1,Кључ од ел. 1,Güç1 Anahtarı -Power2 Key,TAG_POWER2KEY,,,,Klíč od elektrárny 2,Power2-nøgle,Kraftwerksschlüssel 2,,Central-identigo 2,Ident. central nv. 2,,Voimalan 2-avain,Clé Power2,2. erő kulcs,Chiave della Centrale 2,,발전소 2호 키,2e Machtsleutel,Power2-nøkkel,Klucz do Elektrowni 2,Chave da Usina 2,Chave Energética 2,Cheia Putere2,Ключ ЭС №2,Кључ од ел. 2,Güç2 Anahtarı -Power3 Key,TAG_POWER3KEY,,,,Klíč od elektrárny 3,Power3-nøgle,Kraftwerksschlüssel 3,,Central-identigo 3,Ident. central nv. 3,,Voimalan 3-avain,Clé Power3,3. erő kulcs,Chiave della Centrale 3,,발전소 3호 키,3e Machtsleutel,Power3-nøkkel,Klucz do Elektrowni 3,Chave da Usina 3,Chave Energética 3,Cheia Putere3,Ключ ЭС №3,Кључ од ел. 3,Güç3 Anahtarı -Gold Key,TAG_GOLDKEY,,,,Zlatý klíč,Guldnøgle,Goldschlüssel,,Ora ŝlosilo,Llave dorada,,Kulta-avain,Clé en Or,Aranykulcs,Chiave Dorata,,황금 키,Gouden sleutel,Gullnøkkel,Złoty Klucz,Chave de Ouro,,Cheia din Aur,Золотой ключ,Златни кључ,Altın Anahtar -ID Card,TAG_IDCARD,,,,Identifikační karta,ID-kort,Ausweis,,Kloaka identigilo,Ident. alcantarillas,,Henkilökortti,Carte d'Identité,Azonosító Kártya,Tessera Identificativa,,신분증,ID-Kaart,ID-kort,Karta Identyfikacyjna,Cartão de Identificação,,Card de Identitate,Удостоверение,Лична карта,Kimlik Kartı -Silver Key,TAG_SILVERKEY,,,,Stříbrný klíč,Sølvnøgle,Silberschlüssel,,Arĝenta ŝlosilo,Llave plateada,,Hopea-avain,Clé en Argent,Ezüst Kulcs,Chiave Argentata,,은 키,Zilveren sleutel,Sølv-nøkkel,Srebrny Klucz,Chave de Prata,,Cheia din Argint,Серебряный ключ,Сребрни кључ,Gümüş Anahtar -Oracle Key,TAG_ORACLEKEY,,,,Věštcův klíč,Orakel-nøgle,Orakelschlüssel,,Orakolo-ŝlosilo,Llave del Oráculo,,Oraakkelin avain,Clé de l'Oracle,Orákulum kulcs,Chiave dell'Oracolo ,,오라클 키,Orakelsleutel,Oracle-nøkkel,Klucz do Wyroczni,Chave do Oráculo,,Cheia Oracol,Ключ Оракула,Пророков кључ,Kahin Anahtarı -Military ID,TAG_MILITARYID,,,,Vojenské ID,Militær ID,Militärausweis,,Milita identigilo,Identif. militar,,Sotilastunnus,Identification Militaire,Katonai Azonosító Kártya,Identificativo Militare,,군용 아이디,Militaire ID,Militær ID,Wojskowy Identyfikator,ID Militar,,Legitimație Militară,Удостовер. военного,Војна идентификација,Askeri Kimlik -Order Key,TAG_ORDERKEY,,,,Klíč Řádu,Bestillingsnøgle,Ordensschlüssel,,Ordona ŝlosilo,Llave de La Orden,,Veljeskunnan avain,Clé de l'Ordre,Rend Kulcs,Chiave dell'Ordine,,오더의 키,Ordesleutel,Bestillingsnøkkel,Klucz Zakonu,Chave da Ordem,,Cheia Ordinului,Ключ Ордена,Кључ одреда,Sipariş Anahtarı -Warehouse Key,TAG_WAREHOUSEKEY,,,,Klíč ke skladu,Lagernøgle,Lagerhausschlüssel,,Magazena ŝlosilo,Llave del almacén,,Varaston avain,Clé de l'Entrepôt,Raktár Kulcs,Chiave del Magazzino ,,창고 키,Magazijnsleutel,Lagernøkkel,Klucz do Magazynu,Chave do Armazém,,Cheia Depozitului,Ключ от склада,Кључ складишта,Depo Anahtarı -Brass Key,TAG_BRASSKEY,,,,Mosazný klíč,Messingnøgle,Messingschlüssel,,Latuna Ŝlosilo,Llave de Latón,,Messinkiavain,Clé en Bronze,Réz Kulcs,Chiave d'Ottone ,,황동 키,Messing sleutel,Messingnøkkel,Mosiężny Klucz,Chave de Latão,,Cheia din Alamă,Латунный ключ,Кључ од месинга,Pirinç Anahtar -Red Crystal Key,TAG_REDCRYSTALKEY,,,,Červený krystalový klíč,Rød krystalnøgle,Roter Kristallschlüssel,,Ruĝa Kristala Ŝlosilo,Llave de Cristal Rojo,,Punainen kristalliavain,Clé de Cristal Rouge,Piros Kristály Kulcs,Chiave di Cristallo Rosso ,,적색 크리스탈 키,Rode kristallen sleutel,Rød krystallnøkkel,Czerwony Kryształowy Klucz,Chave de Cristal Vermelho,,Cheia din Cristal Roșu,Крас. ключ-кристалл,Кључ од црвеног кристала,Kırmızı Kristal Anahtar -Blue Crystal Key,TAG_BLUECRYSTALKEY,,,,Modrý krystalový klíč,Blå krystalnøgle,Blauer Kristallschlüssel,,Blua Kristala Ŝlosilo,Llave de Cristal Azul,,Sininen kristalliavain,Clé de Crisal Bleu,Kék Kristály Kulcs,Chiave di Cristallo Blu,,청색 크리스탈 키,Blauwe kristallen sleutel,Blå krystallnøkkel,Niebieski Kryształowy Klucz,Chave de Cristal Azul,,Cheia din Cristal Albastru,Син. ключ-кристалл,Кључ од плавог кристала,Mavi Kristal Anahtar -Chapel Key,TAG_CHAPELKEY,,,,Klíč od kaple,Kapel nøgle,Kapellenschlüssel,,Kapelŝlosilo,Llave de la Capilla,,Kappelin avain,Clé de la Chapelle,Kápolna Kulcs,Chiave della Cappella ,,예배당 키,Kappelsleutel,Kapell-nøkkel,Klucz do Kaplicy,Chave da Capela,,Cheia Capelei,Ключ от часовни,Кључ капеле,Şapel Anahtarı -Catacomb Key,TAG_CATACOMBKEY,,,,Klíč do katakomb,Katakomb Nøgle,Katakombenschlüssel,,Katakombŝlosilo,Llave de la Catacumba,,Katakombin avain,Clé des Catacombes,Katakomba Kulcs,Chiave delle Catacombe ,,고대 묘지 키,Catacombesleutel,Katakomb-nøkkel,Klucz do Katakumb,Chave da Catacumba,,Cheia Catacombei,Ключ от катакомб,Кључ од катакомби,Katakomb Anahtarı -Security Key,TAG_SECURITYKEY,,,,Klíč ochranky,Sikkerhedsnøgle,Sicherheitsschlüssel,,Gardŝlosilo,Llave de Seguridad,,Turvamiesavain,Clé de la Sécurité,Biztonsági Kulcs,Chiave della Sicurezza ,,보안 키,Beveiligingssleutel,Sikkerhetsnøkkel,Klucz Ochrony,Chave de Segurança,,Cheia Securității,Ключ охраны,Сигурносни кључ,Güvenlik Anahtarı -Core Key,TAG_COREKEY,,,,Klíč k jádru,Reaktor Nøgle,Reaktorschlüssel,,Kernŝlosilo,Llave del Núcleo,,Ytimen avain,Clé du Réacteur,Mag Kulcs,Chiave del Nucleo,,중심부 키,Kernsleutel,Kjernenøkkel,Klucz do Rdzenia,Chave do Núcleo,,Cheia Nucleului,Ключ от реактора,Кључ језгра,Çekirdek Anahtar -Mauler Key,TAG_MAULERKEY,,,,Klíč k trhačům,Mauler-nøgle,Vernichterschlüssel,,Vundegilo-ŝlosilo,Llave Triturador,,Moukarin avain,Clé du Broyeur,Marcangoló Kulcs,Chiave del Pestatore ,,마울러 키,Toetakelaarssleutel,Mauler-nøkkel,Klucz do Magazynu Miażdżycieli,Chave - Mauler,,Cheia Sfâșietorului,Ключ истязателя,Маулер кључ,Mauler Anahtar -Factory Key,TAG_FACTORYKEY,,,,Klíč do továrny,Fabriksnøgle,Fabrikschlüssel,,Fabriko-ŝlosilo,Llave de la Fábrica,,Tehtaan avain,Clé de l'Usine,Gyár Kulcs,Chiave della Fabbrica ,,공장 키,Fabriekssleutel,Fabrikknøkkel,Klucz do Fabryki,Chave da Fábrica,,Cheia Fabricii,Ключ от фабрики,Кључ фабрике,Fabrika Anahtarı -Mine Key,TAG_MINEKEY,,,,Klíč od dolů,Mine-nøgle,Minenschlüssel,,Minejŝlosilo,Llave de la Mina,,Kaivoksen avain,Clé de la Mine,Bánya Kulcs,Chiave della Miniera ,,탄광 키,Mijnsleutel,Gruve-nøkkel,Klucz do Kopalni,Chave da Mina,,Cheia Minei,Ключ от шахт,Кључ рудника,Maden Anahtarı -New Key5,TAG_NEWKEY5,,,,Nový klíč 5,Ny nøgle5,Neuer Schlüssel 5,,Nova Ŝlosilo5,Llave Nueva5,,Uusi 5-avain,Clé nouveau 5,5. kulcs,Nuova Chiave 5,,새로운 키5,Nieuwe sleutel 5,Ny nøkkel5,Nowy Klucz5,Chave Nova 5,,Noua Cheie5,Новый ключ №5,Нови кључ5,Yeni Anahtar5 -Oracle Pass,TAG_ORACLEPASS,,,,Věštcova propustka,Orakelpas,Orakelpass,,Orakolo-pasilo,Pase del Oráculo,,Oraakkelin kulkulupa,Passe de l'Oracle,Orákulum útlevél,Lasciapassare dell'Oracolo ,,오라클의 통행증,Orakelpas,Oracle Pass,Przepustka Wyroczni,Passe do Oráculo,,Legitimația Oracol,Пропуск Оракула,Пророкова пропусница,Kahin Kartı -10 gold,TAG_10GOLD,,,,10 zlatých,10 guld,,,10 da oro,10 de oro,,10 kolikkoa,10 Pièces,10 arany,10 pezzi d'oro ,10ゴールド,10 골드,10 goud,10 gull,10 monet,10 moedas,10 moedas de ouro,10 monezi de aur,10 золотых,10 златника,10 altın -25 gold,TAG_25GOLD,,,,25 zlatých,25 guld,,,25 da oro,25 de oro,,25 kolikkoa,25 Pièces,25 arany,25 pezzi d'oro ,25ゴールド,25 골드,25 goud,25 gull,25 monet,25 moedas,25 moedas de ouro,25 de monezi de aur,25 золотых,25 златника,25 altın -50 gold,TAG_50GOLD,,,,50 zlatých,50 guld,,,50 da oro,50 de oro,,50 kolikkoa,50 Pièces,50 arany,50 pezzi d'oro ,50ゴールド,50 골드,50 goud,50 gull,50 monet,50 moedas,50 moedas de ouro,50 de monezi de aur,50 золотых,50 златника,50 altın -300 gold,TAG_300GOLD,,,,300 zlatých,300 guld,,,300 da oro,300 de oro,,300 kolikkoa,300 Pièces,300 arany,300 pezzi d'oro ,300ゴールド,300 골드,300 goud,300 gull,300 monet,300 moedas,300 moedas de ouro,300 de monezi de aur,300 золотых,300 златника,300 altın -Person,TXT_PERSON,,,,Osoba,,,,Persono,Persona,,Henkilö,Personne,Személy,Persona,一員,민간인,Persoon,,Osoba,Pessoa,,Persoană,Горожанин,Особа,Kişi -Acolyte,TAG_ACOLYTE,,,,Akolyta,Akolyt,Ministrant,,Akolito,Acólito,,Akoluutti,,Ministráns,Accolito ,アコライト,아콜라이트,Acoliet,Akolytt,Akolita,Acólito,,Acolit,Служитель,Следбеник,Yardımcı -Armorer,TAG_ARMORER,,,Armourer,Kovář,Våbendør,Rüster,,Armilisto,Armero,,Asemestari,Armurier,Páncélkovács,Armaiolo ,装甲,병기공,Harnassmid,Våpensmed,Płatnerz,Armeiro,,Armurier,Продавец брони,Ковач,Zırhçı -Bar Keep,TAG_BARKEEP,,,,Výčepní,Bar-værn,Wirt,,Trinkejisto,Cantinero,,Baarimikko,Barman,Csapos,Barista,酒屋,바텐더,Barman,Bartender,Barman,Dono do Bar,,Barman,Хозяин таверны,Конобар,Barmen -Beggar,TAG_BEGGAR,,,,Žebrák,Tigger,Bettler,,Almozulo,Mendigo,,Kerjäläinen,Mendiant,Koldus,Mendicante ,乞食,거지,Bedelaar,Tigger,Żebrak,Mendigo,,Sărman,Нищий,Просјак,Dilenci -Macil,TAG_MACIL1,,,,Macil,,,,,,,,,,Macil,マシル,마실,Macil,,Macil,Macil,,Macil,Мэйсил,Мејсил,Macil -Macil,TAG_MACIL2,,,,Macil,,,,,,,,,,Macil ,マシル,마실,Macil,,Macil,Macil,,Macil,Мэйсил,Мејсил,Macil -Medic,TAG_MEDIC,,,,Medik,Læge,Sanitäter,,Kuracisto,Médico,,Lääkintämies,Médecin,Szanitéc,Medico,メディック,의무관,Paramedicus,,Medyk,Médico,,Medic,Врач,Болничар,Medic -Oracle,TAG_ORACLE,,,,Věštec,Orakel,Orakel,,Orakolo,Oráculo,,Oraakkeli,,Orákulum,Oracolo,オラクル,오라클,Orakel,Orakel,Wyrocznia,Oráculo,,Oracol,Оракул,Пророк,Kahin -Priest,TAG_PRIEST,,,,Kněz,Præst,Priester,,Pastro,Sacerdote,,Pappi,Prêtre,Pap,Sacerdote,プリースト,성직자,Priester,Prest,Kapłan,Sacerdote,,Preot,Жрец,Свештеник,Rahip -Rat Buddy,TAG_RATBUDDY,,,,Krysík,Rottekammerat,Ratte,,Rato,Rata,,Rottakamu,Copain Rat,Patkánypajtás,Ratto,ラット バディ,생쥐 친구,Rattenvriendje,Rottekompis,Koleżka Szczurów,Rato,,Amicul Șobolanilor,Крыса-друг,Друг пацов,Sıçan Dostu -Rebel,TAG_REBEL,,,,,Rebel,Rebell,,Ribelanto,Rebelde,,Kapinallinen,Rebelle,Lázadó,Ribelle ,反乱軍,저항군,Rebel,Rebell,Rebeliant,Rebelde,,Rebel,Повстанец,Побуњеник,Asi -Templar,TAG_TEMPLAR,,,,Templář,Tempelridder,Templer,,Templano,Templario,,Temppeliherra,Templier,Templomos,Templare ,騎士団員,템플러,Tempelier,Tempelridder,Templariusz,Templário,,Templier,Храмовник,Темплар,Tapınakçı -Weapon Smith,TAG_WEAPONSMITH,,,,Zbraňmistr,Våbensmed,Waffenschmied,,Armilforĝisto,Forjador de Armas,,Aseseppä,Forgeron,Fegyverkovács,Fabbro ,武器工,무기 제조상,Wapensmid,Våpensmed,Wytwórca Broni,Ferreiro,,Făurar,Оружейник,Ковач оружја,Silah Ustası -Red Talisman,TAG_TALISMANRED,,,,Červený talisman,Rød Talisman,Roter Talisman,,Ruĝa Talismano,Talismán rojo,,Punainen talismaani,Talisman Rouge,Vörös Talizmán,Talismano rosso,赤の魔除け,붉은 부적,Rode Talisman,Rød talisman,Czerwony Talizman,Talismã Vermelho,,Talisman Roșu,Красный талисман,Црвени талисман,Kızıl Tılsım -Green Talisman,TAG_TALISMANGREEN,,,,Zelený talisman,Grøn Talisman,Grüner Talisman,,Verda Talismano,Talismán verde,,Vihreä talismaani,Talisman Vert,Zöld Talizmán,Talismano verde,緑の魔除け,녹색 부적,Groene Talisman,Grønn talisman,Zielony Talizman,Talismã Verde,,Talisman Verde,Зелёный талисман,Зелени талисман,Yeşil Tılsım -Blue Talisman,TAG_TALISMANBLUE,,,,Modrý talisman,Blå Talisman,Blauer Talisman,,Blua Talismano,Talismán azul,,Sininen talismaani,Talisman Bleu,Kék Talizmán,Talismano blu,青の魔除け,푸른 부적,Blauwe Talisman,Blå talisman,Niebieski Talizman,Talismã Azul,,Talisman Albastru,Синий талисман,Плави талисман,Mavi Tılsım -,,Obituaries,,,,,,,,,,,,,,,,,,,,,,,, -%o was zealously shot down by an Acolyte.,OB_ACOLYTE,,,,%o byl@[ao_cs] horlivě zastřelen@[ao_cs] akolytou.,%o blev skudt ned af en akolyt.,%o wurde eifrig von dem Ministranten erschossen.,,%o fervore pafiĝis de Akolito.,%o ha sido derribad@[ao_esp] con fervor por un Acólito.,%o fue derribad@[ao_esp] con entusiasmo por un Acólito.,%o joutui kiivailevan akoluutin ampumaksi.,%o a souffert d'une bavure policière.,%o-t buzgó módon le lett lőve egy Oltárszolga által.,%o è stato zelantemente abbattuto da un accolito. ,%o は熱心なアコライトに堕とされた。,%o 은(는) 아콜라이트에게 맹신적으로 사격 당했다.,%o werd gretig neergeschoten door een Acoliet.,%o ble nidkjært skutt ned av en akolytt.,%o został@[ao_pl] żarliwie zastrzelon@[adj_pl] przez Akolitę.,%o foi zelosamente abatid@[ao_ptb] por um Acólito.,,%o a fost împușcat zelos de un Acolit.,Игрок %o фанатично убит служителем.,%o је ревносно упуцан@[adj_1_sr] од стране секташа.,"%o, bir yardımcısı tarafından gayretle vuruldu." +de la Orakolo!",¡Necesitas el Pase del Oráculo!,,Tarvitset Oraakkelin passin,Vous avez besoin du passe Oracle!,Az Orákulum Engedélyére van szükséged!,Hai bisogno del pass dell'Oracolo.,オラクルパスが必要だ!,오라클 통행증이 필요하다!,Je hebt de Orakelpas nodig!,Du trenger Orakelpasset!,Potrzebujesz Przepustki Wyroczni!,Você precisa do Passe do Oráculo!,Precisas do Passe do Oráculo!,Ai nevoie de legitimația Oracol!,Нужен пропуск Оракула!,Треба ти Пророкова пропусница!,Du behöver Orakelpasset!,Kahin Kartı'na ihtiyacın var! +,,Actor tags,,,,,,,,,,,,,,,,,,,,,,,,, +Dagger,TAG_PUNCHDAGGER,,,,Dýka,Dolk,Dolch,Μαχάιρι,Ponardo,Daga,,Tikari,Dague de Poing,Tőr,Pugnale,ダガー,단검,Dolk,Dolk,Sztylet,Punhal,,Pumnal,Кинжал,Бодеж,Dolk,Hançer +Crossbow,TAG_STRIFECROSSBOW1,Crossbow with electric bolts,,,Kuše,Armbrøst,Armbrust,Τόξο (Δηλητήριο),Arbalesto (Elektraj sagoj),Ballesta (eléctrica),,Jousipyssy,Arbalète Electrique,Nyílpuska,Balestra ,クロスボウ,석궁 (전격),Kruisboog,Armbrøst,Kusza,Besta,,Arbaletă,Арбалет,Самострел,Armborst,Arbalet +Crossbow,TAG_STRIFECROSSBOW2,Crossbow with poison bolts,,,Kuše,Armbrøst,Armbrust,Τόξο (Ηλεκτρικό),Arbalesto (Venenaj sagoj),Ballesta (veneno),,Jousipyssy,Arbalète Empoisonée,Nyílpuska,Balestra ,クロスボウ,석궁 (맹독),Kruisboog,Armbrøst,Kusza,Besta,,Arbaletă,Арбалет,Самострел,Armborst,Arbalet +Assault Gun,TAG_ASSAULTGUN,,,,Útočná puška,Angrebsvåben,Sturmgewehr,,Sturmofusilo,Fusil de asalto,,Rynnäkkökivääri,Fusil d'Assaut,Gépfegyver,Fucile d'Assalto ,アサルトガン,돌격소총,Aanvalswapen,Stormgevær,Karabin Szturmowy,Fuzil de Assalto,Arma de Assalto,Pușcă de Asalt,Штурмовая винтовка,Аутоматска пушка,Anfallspistol,Saldırı Silahı +Mini Missile Launcher,TAG_MMLAUNCHER,,,,Miniraketomet,Mini-missilkaster,Miniraketenwerfer,Μίνι-Πυραυλοβόλο,Misilet-ĵetilo,Minilanzamisiles,,Miniohjuslaukaisin,Lanceur de Mini-Missiles,Mini Rakétavető,Mini-Lanciamissili,ミニミサイルランチャー,미니 미사일 런쳐,Miniraketwerper,Mini rakettkaster,Wyrzutnia Minipocisków,Mini Lança-mísseis,,Mini Lansator de Proiectile,Мини-гранатомёт,Мини ракетни бацач,Mini missilkastare,Mini Füze Fırlatıcı +Flame Thrower,TAG_FLAMER,,,,Plamenomet,Flammekaster,Flammenwerfer,,Flamĵetilo,Lanzallamas,,Liekinheitin,Lance-Flammes,Lángszóró,Lanciafiamme ,火炎放射器,화염방사기,Vlammenwerper,Flammekaster,Miotacz Ognia,Lança-chamas,,Aruncător de Flăcări,Огнемёт,Бацеч пламена,Flamkastare,Alev Fırlatıcı +Mauler,TAG_MAULER1,,,,Trhač,,Vernichter,,Vundegilo,Triturador (dispersión),,Moukari,Broyeur,Marcangoló,Pestatore ,マウラー,마울러 (저출력),Toetakelaar,,Miażdżyciel,Desintegrador,,Sfâșietor,Истязатель,Маулер,,Parçalayıcı +Mauler,TAG_MAULER2,,,,Trhač,,Vernichter,,Vundegilo,Triturador (torpedo),,Moukari,Broyeur,Marcangoló,Pestatore,マウラー,마울러 (고출력),Toetakelaar,,Miażdżyciel,Desintegrador,,Sfâșietor,Истязатель,Маулер,,Parçalayıcı +Grenade Launcher,TAG_GLAUNCHER1,High-explosive grenade launcher,,,Granátomet,Granatkaster,Granatwerfer,,Granadĵetilo (PE),Lanzagranadas,,Kranaatinheitin,Lance-Grenades Explosif,Gránátvető,Lanciagranate,グレネードランチャー,유탄발사기 (고폭탄),Granaatwerper,Granatkaster,Wyrzutnia Granatów,Lança-granadas,,Lansator de Grenade,Гранатомёт,Бацач граната,Granatkastare,El Bombası Fırlatıcı +Grenade Launcher,TAG_GLAUNCHER2,White phosphorous grenade launcher ,,,Granátomet,Granatkaster,Granatwerfer,,Granadĵetilo (Fosfora),Lanzagranadas (fósforo),,Kranaatinheitin,Lance-Grenades Incendiaire,Gránátvető,Lanciagranate,グレネードランチャー,유탄발사기 (소이탄),Granaatwerper,Granatkaster,Wyrzutnia Granatów,Lança-granadas,,Lansator de Grenade,Гранатомёт,Бацач граната,Granatkastare,El Bombası Fırlatıcı +Sigil,TAG_SIGIL,,,,Pečeť,,,,Sigelo,Emblema,,Sinetti,,Pecsét,Sigillo,シジル,시질,,,Pieczęć,Sigilo,,Sigiliu,Печать,Сигил,, +Coin,TAG_COIN,,,,Mince,Mønt,Münze,,Monero,Moneda,,Kolikko,Pièce,Érme,Moneta,コイン,동전,Munt,Mynt,Moneta,Moeda(s),,Monedă,Монета,Новчић,Mynt,Madeni Para +Med patch,TAG_MEDPATCH,,,,Obvazy,Medicinsk bandage,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekääre,Pansement,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinsk lapp,Bandaż,Compressa médica,,Trusă de Prim-Ajutor,Бинт,Прва помоћ,Medicinska plåster,Med yama +Medical kit,TAG_MEDICALKIT,,,,Lékárnička,Medicinsk kit,Verbandskasten,,Sukurkesto,Botiquín,,Lääkintälaukku,Kit Médical,Orvosi Készlet,Kit di Pronto Soccorso ,医療キット,구급 키트,Medicijndoos,Medisinsk sett,Apteczka,Kit médico,,Kit de Prim-Ajutor,Аптечка,Медицински прибор,Medicinsk utrustning,Tıbbi kit +Surgery Kit,TAG_SURGERYKIT,,,,Chirurgická souprava,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kirurgilaukku,Kit de Chirurgie,Sebészeti Készlet,Kit Chirurgico ,手術キット,수술 키트,Chirurgiepakket,Kirurgisk sett,Zestaw Chirurga,Kit de Cirurgia,,Kit pentru Operații,Медкомплект,Хируршки прибор,Kirurgiskt kit,Ameliyat Kiti +Ring,TAG_BELDINSRING,,,,Prsten,,,,Ringo,Anillo,,Sormus,Anneau,Gyűrű,Anello ,指輪,반지,,,Pierścień,Anel,,Inel,Кольцо,Прстен,,Yüzük +Offering Chalice,TAG_OFFERINGCHALICE,,,,Obětní kalich,Offerkalk,Opferkelch,,Oferdona kaliko,Cáliz de ofrenda,,Uhrimalja,Calice d'Obole,Áldozati kehely,Calice delle Offerte,寄贈された聖杯,번제 성배,Offerbeker,Offerbeger,Kielich Ofiarny,Calice de Oferenda,,Potir pentru Ofrande,Чаша для подношений,Жртвени пехар,Offertkalke,Adak Kadehi +Ear,TAG_EAR,,,,Ucho,Øre,Ohr,,Orelo,Oreja,,Korva,Oreille,Fül,Orecchio,耳,귀,Oor,Øre,Ucho,Orelha,,Ureche,Ухо,Уво,Öra,Kulak +Broken Power Coupling,TAG_BROKENCOUPLING,,,,Rozbitá spojka,Brækket strømkobling,Defekter Stromabnehmer,,Rompita energia kuplilo,Acoplador de energía roto,,Rikkinäinen virtaliitin,Coupleur Energétique cassé,Elromlott Tápcsatlakozó,Coppia Energetica Rotta ,壊れたパワーカップリング,망가진 동력선,Gebroken stroomkoppeling,Ødelagt kraftkobling,Zepsute Obwody Zasilające,Acoplador de Energia Quebrado,Acoplador de Energia Partido,Cuplaj de Putere Defect,Повреждённая муфта,Неисправна спојница напајања,Trasig kraftkoppling,Kırık Güç Kaplini +Shadow Armor,TAG_SHADOWARMOR,,,Shadow Armour,Stínové brnění,Skygge rustning,Schattenrüstung,,Ombra armaĵo,Armadura de sombra,,Varjohaarniska,Armure de l'Ombre,Sötét Páncél,Armatura Ombra ,シャドウアーマー,그림자 갑옷,Schaduwharnas,Skygge rustning,Cienisty Pancerz,Armadura das Sombras,,Armura Umbrei,Теневая броня,Оклоп сенки,Skuggarmering,Gölge Zırhı +Environmental Suit,TAG_ENVSUIT,,,,Ochranný oblek,Miljømæssig dragt,Schutzanzug,,Medi-ŝirma vesto,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison Hazmat,Védőöltözet,Tuta Ambientale ,耐環境スーツ,환경 방호복,Beschermend pak,Miljødrakt,Skafander Ochronny,Traje de Proteção,Fato Protetor,Costum de Protecție,Защитный костюм,Заштитно одело,Miljödräkt,Çevresel Takım +Guard Uniform,TAG_GUARDUNIFORM,,,,Hlídačova uniforma,Gardeuniform,Wächteruniform,,Gardista uniformo,Uniforme de guardia,,Vartijan univormu,Uniforme de Garde,Őr Egyenruha,Uniforme da Guardia,ガードの制服,경비 전투복,Wachtersuniform,Vaktuniform,Mundur Strażnika,Uniforme de Guarda,,Uniformă de Paznic,Униформа стражника,Стражарска униформа,Skyddsuniform,Bekçi Üniforması +Officer's Uniform,TAG_OFFICERSUNIFORM,,,,Důstojníkova uniforma,Officersuniform,Offiziersuniform,,Oficira uniformo,Uniforme de oficial,,Upseerin univormu,Uniforme d'Officier,Tiszti Egyenruha,Uniforme da Ufficiale ,士官の制服,장교 전투복,Officiersuniform,Offisersuniform,Mundur Oficera,Uniforme de Oficial,,Uniformă de Ofițer,Офицерская униформа,Официрска униформа,Officersuniform,Memur Üniforması +Flame Thrower Parts,TAG_FTHROWERPARTS,,,,Díly plamenometu,Dele til flammekasteren,Flammenwerferteile,,Partoj de flamjetilo,Partes de lanzallamas,,Liekinheittimen osat,Pièces de Lance-Flamme,Lángszóró Alkatrészek,Parti di Lanciafiamme ,火炎放射器の部品,화염방사기 부품,Vlammenwerperonderdelen,Deler til flammekaster,Części Miotacza Ognia,Partes do lança-chamas,,Bucăți de Aruncător de Flăcări,Детали огнемёта,Делови бацача пламена,Delar till flamkastaren,Alev Püskürtücü Parçaları +Report,TAG_REPORT,,,,Hlášení,Rapport,,,Raporto,Reporte,,Raportti,Compte-rendu,Jelentés,Rapporto ,報告書,보고서,Verslag,Rapport,Raport,Relatório,,Raport,Отчёт,Извештај,Rapportera,Rapor +Info,TAG_INFO,,,,Informace,,,,Informo,Información,,Tiedot,,Információ,Informazioni ,情報,정보,,Informasjon,Informacje,Informação,,Informație,Сводка,Инфо,,Bilgi +Targeter,TAG_TARGETER,,,,Zaměřovač,,Zielhilfe,,Celilo,Apuntador,,Tähtäinlaite,Cibleur,Célzó eszköz,Puntatore,照準器,조준기,Richter,,Namierzacz,Mira,,Țintitor,Целеуказатель,Нишанџија,,Hedefleme cihazı +Communicator,TAG_COMMUNICATOR,,,,Komunikátor,Kommunikator,Kommunikator,,Komunikilo,Comunicador,,Viestintälaite,Communicateur,Kommunikátor,Comunicatore ,コミュニケーター,연락장치,,Kommunikator,Komunikator,Comunicador,,Comunicator,Передатчик,Комуникатор,Kommunikator,İletişimci +Degnin Ore,TAG_DEGNINORE,,,,Degninská ruda,Degnin malm,Degnin-Erz,,Degnina Erco,Mineral Degnin,,Degnin-malmi,Minerai de Degnin,Degnin Érc,Minerale Degnin,デグニン鉱石,데그닌 광석,Degnin-erts,Degnin malm,Ruda Degninu,Minério Degnin,,Minereu de Degnir,Денгинская руда,Дегнинска руда,Degnin Malm,Degnin Cevheri +Accuracy,TAG_GUNTRAINING,,,,Přesnost,Nøjagtighed,Präzision,,Akurateco,Precisión,,Tarkkuus,Précision,Pontosság,Precisione,精度,정확도,Nauwkeurigheid,Nøyaktighet,Precyzja,Precisão,,Acuratețe,Меткость,Прецизност,Noggrannhet,Doğruluk +Toughness,TAG_HEALTHTRAINING,,,,Tvrdost,Robusthed,Ausdauer,,Forteco,Dureza,,Sitkeys,Endurance,Kitartás,Robustezza ,タフネス,힘,Stevigheid,Seighet,Wytrzymałość,Força,,Rezistență,Живучесть,Издржљивост,Seghet,Sertlik +Scanner,TAG_SCANNER,,,,Skener,,,,Skanilo,Escáner,,Skanneri,Analyseur,Szkenner,Scanner,スキャナー,탐지기,Scanner,Skanner,Skaner,Scanner,,Scanner,Сканер,Скенер,Scanner,Tarayıcı +Prison Pass,TAG_PRISONPASS,,,,Propustka do vězení,Fængselspas,Gefängnispass,,Mallibereja pasilo,Pase a la prisión,,Vankilan pääsylupa,Passe de la Prison,Börtön Engedély,Lasciapassare Prigione ,刑務所の許可証,감옥 통행증,Gevangenispas,Fengselspass,Przepustka do Więzienia,Passe da Prisão,,Legitimația pentru Închisoare,Пропуск в тюрьму,Затворска пропусница,Fängelsepass,Hapishane Kartı +Alarm,TAG_ALARM,,,,,,,,Alarmo,Alarma,,Hälytys,Alarme,Riasztó,Allarme ,警報,알람,,,,Alarme,,Alarmă,Тревога,Аларм,Larm, +Ammo,TAG_AMMOFILLUP,,,,Munice,Munition,Munition,,Municio,Munición,,Ammukset,Munitions,Lőszer,Munizioni ,弾薬,탄약,Munitie,Ammunisjon,Amunicja,Munição,,Muniție,Боеприпасы,Муниција,Ammunition,Cephane +Health,TAG_HEALTHFILLUP,,,,Zdraví,Sundhed,Gesundheit,,Sano,Salud,,Terveys,Santé,Életerő,Salute ,体力,체력,Gezondheid,Helse,Zdrowie,Saúde,,Sănătate,Здоровье,Живот,Hälsa,Sağlık +Teleporter Beacon,TAG_TELEPORTERBEACON,,,,Teleportační maják,Teleportør-bakke,Teleportersignal,,Formovila Signalilo,Faro de Teletransportación,,Kaukosiirrinmajakka,Balise de téléportation,Teleport Vészfény,Radiofaro per Teletrasporto ,テレポータービーコン,텔레포터 비콘,Teleporterbaken,Teleporter Beacon,Nadajnik Teleportera,Sinalizador para Teletransporte,,Lumină pentru Teleportor,Телепортационный маяк,Одашиљач за телепортовање,Teleporterfyr,Işınlayıcı İşaretçisi +Metal Armor,TAG_METALARMOR,,,Metal Armour,Kovové brnění,Metal rustning,Metallrüstung,,Metala armaĵo,Armadura de metal,,Metallihaarniska,Armure en Métal,Fém Páncél,Armatura di Metallo ,メタルアーマー,강철 갑옷,Metalen harnas,Metall rustning,Metalowy Pancerz,Armadura de Metal,,Armură din Metal,Металлическая броня,Метални оклоп,Metall rustning,Metal Zırh +Leather Armor,TAG_LEATHER,,,Leather Armour,Kožené brnění,Læderpanser,Lederrüstung,,Leda armaĵo,Armadura de cuero,,Nahkasuojus,Armure en Cuir,Bőr Páncél,Armatura di Cuoio,レザーアーマー,가죽 갑옷,Leren harnas,Lær rustning,Skórzany Pancerz,Armadura de Couro,,Armură din Piele,Кожаная броня,Кожни оклоп,Läderrustning,Deri Zırh +HE-Grenade Rounds,TAG_HEGRENADES,,,,Výbušné granáty,HE-granater,HE-Granaten,,HE-grenadoj,Granadas HE,,Räjähdekranaatit,Grenades Explosives,Gránát Lőszer,Granata HE,HEグレネード弾,고폭 유탄,HE-granaten,HE-Granater,Wiązka Granatów,Munição - Granadas Explosivas,,Grenade Explozive,Осколочные гранаты,Хе-Граната чауре,HE-granater,HE-Bomba Mermileri +Phosphorus-Grenade Rounds,TAG_PHGRENADES,,,,Fosforové granáty,Fosforgranater,Phosphorgranaten,,Fosforaj grenadoj,Granadas de fósforo,,Fosforikranaatit,Grenades Incendiaires,Foszfor-Gránát Lőszer,Granata al Fosforo ,白リングレネード弾,소이 유탄,Fosforgranaten,Fosforgranater,Wiązka Fosforowych Granatów,Municão - Granadas de Fósforo,,Grenade cu Fosfor,Фосфорные гранаты,Фосфорне гранате,Fosforgranater,Fosforlu El Bombası Mermileri +Clip of Bullets,TAG_CLIPOFBULLETS,,,,Zásobník s náboji,Kugleklip,Gewehrmunition,,Magazeno,Cargador de balas,,Luotilipas,Chargeur d'Assaut,Golyó töltények,Caricatore di Proiettili ,弾丸のクリップ,소총 탄창,Patroon kogels,Klipp av kuler,Magazynek,Carregador de Balas,,Cartuș cu Gloanțe,Обойма,Клип метака,Kulor i klipp,Kurşun Klipsi +Ammo,TAG_BOXOFBULLETS,,,,Krabice nábojů,Munition,Munitionskiste,,Municikesto,Caja de municiones,,Luotilaatikko,Bôite de Munitions,Lőszer,Munizioni ,弾薬箱,탄약,Munitie,Ammunisjon,Amunicja,Caixa de Balas,,Muniție,Боеприпасы,Муниција,Ammunition,Cephane +Mini Missiles,TAG_MINIMISSILES,,,,Minirakety,Mini missiler,Miniraketen,,Misiletoj,Minimisiles,,Miniohjukset,Mini-Missiles,Mini Rakéták,Mini-Missili,ミニミサイル,미니 미사일,Mini-raketten,Mini missiler,Mini Pociski,Mísseis,,Mini Proiectile,Мини-ракеты,Мини Ракете,Miniraketer,Mini Füzeler +Crate of Missiles,TAG_CRATEOFMISSILES,,,,Bedna raket,kasse med missiler,Raketenkiste,,Misilet-kesto,Caja de misiles,,Ohjuslaatikko,Caisse de Mini-Missiles,Ládányi Rakéta,Cassa di Missili,ミサイルの箱,미사일 박스,Krat raketten,Kasse med missiler,Skrzynia z Pociskami,Caixa de Mísseis,,Ladă cu Proiectile,Коробка ракет,Кутија ракета,Låda med missiler,Füze Sandığı +Energy Pod,TAG_ENERGYPOD,,,,Energetický kokón,Energipod,Energiezelle,,Umo de Energio,Vaina de Energía,,Energia-akku,Cellule Energétique,Energia Lőszer,Nucleo Enegetico ,エネルギーポット,에너지 포드,Energiecel,Energikapsel,Kapsuła Energii,Energia (pequeno),,Capsulă cu Energie,Энергоячейка,Енергетска шипка,Energipod,Enerji Bölmesi +Energy Pack,TAG_ENERGYPACK,,,,Energetický svazek,Energipakke,Energiepack,,Pako de Energio,Pack de Energía,,Energiapaketti,Pack Energétique,Energia Csomag,Carica Energetica ,エネルギーパック,에너지 팩,Energiepak,Energipakke,Zasobnik Energii,Energia (grande),,Pachet cu Energie,Энергобатарея,Паковање енергије,Energipaket,Enerji Paketi +Poison Bolts,TAG_POISONBOLTS,,,,Otrávené šípy,Giftige bolte,Giftbolzen,,Venenaj sagoj,Flechas venenosas,,Myrkkynuolet,Carreaux Empoisonnés,Mérgező hegyek,Dardi Velenosi ,ポイズンボルト,맹독 볼트,Giftige bouten,Giftbolter,Zatrute Bełty,Setas Envenenadas,,Bolțuri cu Otravă,Отравленные болты,Отровне стреле,Giftiga bultar,Zehirli Cıvatalar +Electric Bolts,TAG_ELECTRICBOLTS,,,,Elektrické šípy,Elektriske bolte,Elektrische Bolzen,,Elektraj sagoj,Flechas eléctricas,,Sähkönuolet,Carreaux Electriques,Elektromos hegyek,Dardi Elettrici ,エレクトリックボルト,전격 볼트,Elektrische bouten,Elektriske bolter,Elektryczne Bełty,Setas Elétricas,,Bolțuri cu Electricitate,Электрические болты,Електричне стреле,Elektriska bultar,Elektrikli Cıvatalar +Ammo Satchel,TAG_AMMOSATCHEL,,,,Brašna na munici,Ammo Satchel,Munitionstasche,,Sako da municioj,Bolso de municiones,,Ammuslaukku,Sacoche à munitions,Lőszeres táska,Borsa di Munizioni ,弾薬鞄,탄약 배낭,Munitietassen,Ammunisjonsveske,Torba z Amunicją,Bolsa de Munição,,Sacoșă cu Muniție,Ранец боеприпасов,Торбица муниције,Ammo Satchel,Cephane Çantası +Base Key,TAG_BASEKEY,,,,Klíč od základny,Basisnøgle,Basisschlüssel,,Bazŝlosilo,Llave de la base,,Tukikohdan avain,Clé de la base,Bázis Kulcs,Chiave della Base,,기지 키,Basissleutel,Basenøkkel,Klucz do Bazy,Chave da Base,,Cheia Bazei,Ключ от базы,Кључ базе,Basnyckel,Temel Anahtar +Govs Key,TAG_GOVSKEY,,,,Klíč ke guvernérovi,Govs nøgle,Gouverneursschlüssel,,Ŝlosilo de registo,Llave Gobernador,,Kuvernöörin avain,Clé du Gouverneur,Kormányzó Kulcs,Chiave del Governatore ,,총독의 키,Gouverneursleutel,Regjeringsnøkkel,Klucz Gubernatora,Chave do Governador,,Cheia Guvernatorului,Ключ губернатора,Гувернеров кључ,Govs-nyckel,Govs Anahtar +Passcard,TAG_PASSCARD,,,,Vstupní karta,Adgangskort,Zugangskarte,,Central-ŝlosilo,Llave de la central,,Avainkortti,Passe,Belépőkártya,Tessera Lasciapassare ,,통행 카드,Paspoortkaart,Adgangskort,Karta Dostępu,Cartão de Acesso,,Legitimație,Пропуск,Пропусница,Passerkort,Geçiş kartı +ID Badge,TAG_IDBADGE,,,,Identifikační odznak,ID-badge,Identitätskarte,,Mallibereja insigno,Insignia de prisión,,Henkilötunniste,Badge d'Identification,Azonosító Jelvény,Distintivo ,,신분 휘장,ID-Badge,ID-badge,Odznaka Identyfikacyjna,Crachá de Identificação,,Ecuson de Identificare,Личная карта,Идентификациона значка,ID-bricka,Kimlik Rozeti +Prison Key,TAG_PRISONKEY,,,,Klíč od věznice,Fængselsnøgle,Gefängnisschlüssel,,Mallibereja ŝlosilo,Llave de la prisión,,Vankilan avain,Clé de la Prison,Börtön Kulcs,Chiave della Prigione ,,감옥 키,Gevangenissleutel,Fengselsnøkkel,Klucz do Więzienia,Chave da Prisão,,Cheia Închisorii,Ключ от тюрьмы,Кључ од 3атвора,Fängelsenyckel,Hapishane Anahtarı +Severed Hand,TAG_SEVEREDHAND,,,,Useknutá ruka,Afskåret hånd,Abgetrennte Hand,,Amputita mano,Mano amputada,,Katkennut käsi,Main coupée,Levágott Kéz,Mano Mozzata,,잘린 손목,Gescheurde Hand,Avkuttet hånd,Odcięta Ręka,Mão Decepada,Mão Desmenbrada,Mână Retezată,Отрезанная рука,Одвојена шака,Avskuren hand,Kesik El +Power1 Key,TAG_POWER1KEY,,,,Klíč od elektrárny 1,Power1 nøgle,Kraftwerksschlüssel 1,,Central-identigo 1,Ident. central nv. 1,,Voimalan 1-avain,Clé Power1,1. erő kulcs,Chiave della Centrale 1,,발전소 1호 키,1e Machtsleutel,Power1-nøkkel,Klucz do Elektrowni 1,Chave da Usina 1,Chave Energética 1,Cheia Putere1,Ключ ЭС №1,Кључ од ел. 1,Kraftnyckel 1,Güç1 Anahtarı +Power2 Key,TAG_POWER2KEY,,,,Klíč od elektrárny 2,Power2-nøgle,Kraftwerksschlüssel 2,,Central-identigo 2,Ident. central nv. 2,,Voimalan 2-avain,Clé Power2,2. erő kulcs,Chiave della Centrale 2,,발전소 2호 키,2e Machtsleutel,Power2-nøkkel,Klucz do Elektrowni 2,Chave da Usina 2,Chave Energética 2,Cheia Putere2,Ключ ЭС №2,Кључ од ел. 2,Kraftnyckel 2,Güç2 Anahtarı +Power3 Key,TAG_POWER3KEY,,,,Klíč od elektrárny 3,Power3-nøgle,Kraftwerksschlüssel 3,,Central-identigo 3,Ident. central nv. 3,,Voimalan 3-avain,Clé Power3,3. erő kulcs,Chiave della Centrale 3,,발전소 3호 키,3e Machtsleutel,Power3-nøkkel,Klucz do Elektrowni 3,Chave da Usina 3,Chave Energética 3,Cheia Putere3,Ключ ЭС №3,Кључ од ел. 3,Kraftnyckel 3,Güç3 Anahtarı +Gold Key,TAG_GOLDKEY,,,,Zlatý klíč,Guldnøgle,Goldschlüssel,,Ora ŝlosilo,Llave dorada,,Kulta-avain,Clé en Or,Aranykulcs,Chiave Dorata,,황금 키,Gouden sleutel,Gullnøkkel,Złoty Klucz,Chave de Ouro,,Cheia din Aur,Золотой ключ,Златни кључ,Guldnyckel,Altın Anahtar +ID Card,TAG_IDCARD,,,,Identifikační karta,ID-kort,Ausweis,,Kloaka identigilo,Ident. alcantarillas,,Henkilökortti,Carte d'Identité,Azonosító Kártya,Tessera Identificativa,,신분증,ID-Kaart,ID-kort,Karta Identyfikacyjna,Cartão de Identificação,,Card de Identitate,Удостоверение,Лична карта,ID-kort,Kimlik Kartı +Silver Key,TAG_SILVERKEY,,,,Stříbrný klíč,Sølvnøgle,Silberschlüssel,,Arĝenta ŝlosilo,Llave plateada,,Hopea-avain,Clé en Argent,Ezüst Kulcs,Chiave Argentata,,은 키,Zilveren sleutel,Sølv-nøkkel,Srebrny Klucz,Chave de Prata,,Cheia din Argint,Серебряный ключ,Сребрни кључ,Silvernyckel,Gümüş Anahtar +Oracle Key,TAG_ORACLEKEY,,,,Věštcův klíč,Orakel-nøgle,Orakelschlüssel,,Orakolo-ŝlosilo,Llave del Oráculo,,Oraakkelin avain,Clé de l'Oracle,Orákulum kulcs,Chiave dell'Oracolo ,,오라클 키,Orakelsleutel,Oracle-nøkkel,Klucz do Wyroczni,Chave do Oráculo,,Cheia Oracol,Ключ Оракула,Пророков кључ,Oracle-nyckel,Kahin Anahtarı +Military ID,TAG_MILITARYID,,,,Vojenské ID,Militær ID,Militärausweis,,Milita identigilo,Identif. militar,,Sotilastunnus,Identification Militaire,Katonai Azonosító Kártya,Identificativo Militare,,군용 아이디,Militaire ID,Militær ID,Wojskowy Identyfikator,ID Militar,,Legitimație Militară,Удостовер. военного,Војна идентификација,Militärt ID,Askeri Kimlik +Order Key,TAG_ORDERKEY,,,,Klíč Řádu,Bestillingsnøgle,Ordensschlüssel,,Ordona ŝlosilo,Llave de La Orden,,Veljeskunnan avain,Clé de l'Ordre,Rend Kulcs,Chiave dell'Ordine,,오더의 키,Ordesleutel,Bestillingsnøkkel,Klucz Zakonu,Chave da Ordem,,Cheia Ordinului,Ключ Ордена,Кључ одреда,Beställningsnyckel,Sipariş Anahtarı +Warehouse Key,TAG_WAREHOUSEKEY,,,,Klíč ke skladu,Lagernøgle,Lagerhausschlüssel,,Magazena ŝlosilo,Llave del almacén,,Varaston avain,Clé de l'Entrepôt,Raktár Kulcs,Chiave del Magazzino ,,창고 키,Magazijnsleutel,Lagernøkkel,Klucz do Magazynu,Chave do Armazém,,Cheia Depozitului,Ключ от склада,Кључ складишта,Lagernyckel,Depo Anahtarı +Brass Key,TAG_BRASSKEY,,,,Mosazný klíč,Messingnøgle,Messingschlüssel,,Latuna Ŝlosilo,Llave de Latón,,Messinkiavain,Clé en Bronze,Réz Kulcs,Chiave d'Ottone ,,황동 키,Messing sleutel,Messingnøkkel,Mosiężny Klucz,Chave de Latão,,Cheia din Alamă,Латунный ключ,Кључ од месинга,Mässingsnyckel,Pirinç Anahtar +Red Crystal Key,TAG_REDCRYSTALKEY,,,,Červený krystalový klíč,Rød krystalnøgle,Roter Kristallschlüssel,,Ruĝa Kristala Ŝlosilo,Llave de Cristal Rojo,,Punainen kristalliavain,Clé de Cristal Rouge,Piros Kristály Kulcs,Chiave di Cristallo Rosso ,,적색 크리스탈 키,Rode kristallen sleutel,Rød krystallnøkkel,Czerwony Kryształowy Klucz,Chave de Cristal Vermelho,,Cheia din Cristal Roșu,Крас. ключ-кристалл,Кључ од црвеног кристала,Nyckel i röd kristall,Kırmızı Kristal Anahtar +Blue Crystal Key,TAG_BLUECRYSTALKEY,,,,Modrý krystalový klíč,Blå krystalnøgle,Blauer Kristallschlüssel,,Blua Kristala Ŝlosilo,Llave de Cristal Azul,,Sininen kristalliavain,Clé de Crisal Bleu,Kék Kristály Kulcs,Chiave di Cristallo Blu,,청색 크리스탈 키,Blauwe kristallen sleutel,Blå krystallnøkkel,Niebieski Kryształowy Klucz,Chave de Cristal Azul,,Cheia din Cristal Albastru,Син. ключ-кристалл,Кључ од плавог кристала,Blå kristallnyckel,Mavi Kristal Anahtar +Chapel Key,TAG_CHAPELKEY,,,,Klíč od kaple,Kapel nøgle,Kapellenschlüssel,,Kapelŝlosilo,Llave de la Capilla,,Kappelin avain,Clé de la Chapelle,Kápolna Kulcs,Chiave della Cappella ,,예배당 키,Kappelsleutel,Kapell-nøkkel,Klucz do Kaplicy,Chave da Capela,,Cheia Capelei,Ключ от часовни,Кључ капеле,Kapellnyckel,Şapel Anahtarı +Catacomb Key,TAG_CATACOMBKEY,,,,Klíč do katakomb,Katakomb Nøgle,Katakombenschlüssel,,Katakombŝlosilo,Llave de la Catacumba,,Katakombin avain,Clé des Catacombes,Katakomba Kulcs,Chiave delle Catacombe ,,고대 묘지 키,Catacombesleutel,Katakomb-nøkkel,Klucz do Katakumb,Chave da Catacumba,,Cheia Catacombei,Ключ от катакомб,Кључ од катакомби,Katakomb-nyckel,Katakomb Anahtarı +Security Key,TAG_SECURITYKEY,,,,Klíč ochranky,Sikkerhedsnøgle,Sicherheitsschlüssel,,Gardŝlosilo,Llave de Seguridad,,Turvamiesavain,Clé de la Sécurité,Biztonsági Kulcs,Chiave della Sicurezza ,,보안 키,Beveiligingssleutel,Sikkerhetsnøkkel,Klucz Ochrony,Chave de Segurança,,Cheia Securității,Ключ охраны,Сигурносни кључ,Säkerhetsnyckel,Güvenlik Anahtarı +Core Key,TAG_COREKEY,,,,Klíč k jádru,Reaktor Nøgle,Reaktorschlüssel,,Kernŝlosilo,Llave del Núcleo,,Ytimen avain,Clé du Réacteur,Mag Kulcs,Chiave del Nucleo,,중심부 키,Kernsleutel,Kjernenøkkel,Klucz do Rdzenia,Chave do Núcleo,,Cheia Nucleului,Ключ от реактора,Кључ језгра,Kärnnyckel,Çekirdek Anahtar +Mauler Key,TAG_MAULERKEY,,,,Klíč k trhačům,Mauler-nøgle,Vernichterschlüssel,,Vundegilo-ŝlosilo,Llave Triturador,,Moukarin avain,Clé du Broyeur,Marcangoló Kulcs,Chiave del Pestatore ,,마울러 키,Toetakelaarssleutel,Mauler-nøkkel,Klucz do Magazynu Miażdżycieli,Chave - Mauler,,Cheia Sfâșietorului,Ключ истязателя,Маулер кључ,Mauler-nyckel,Mauler Anahtar +Factory Key,TAG_FACTORYKEY,,,,Klíč do továrny,Fabriksnøgle,Fabrikschlüssel,,Fabriko-ŝlosilo,Llave de la Fábrica,,Tehtaan avain,Clé de l'Usine,Gyár Kulcs,Chiave della Fabbrica ,,공장 키,Fabriekssleutel,Fabrikknøkkel,Klucz do Fabryki,Chave da Fábrica,,Cheia Fabricii,Ключ от фабрики,Кључ фабрике,Fabriksnyckel,Fabrika Anahtarı +Mine Key,TAG_MINEKEY,,,,Klíč od dolů,Mine-nøgle,Minenschlüssel,,Minejŝlosilo,Llave de la Mina,,Kaivoksen avain,Clé de la Mine,Bánya Kulcs,Chiave della Miniera ,,탄광 키,Mijnsleutel,Gruve-nøkkel,Klucz do Kopalni,Chave da Mina,,Cheia Minei,Ключ от шахт,Кључ рудника,Gruvnyckel,Maden Anahtarı +New Key5,TAG_NEWKEY5,,,,Nový klíč 5,Ny nøgle5,Neuer Schlüssel 5,,Nova Ŝlosilo5,Llave Nueva5,,Uusi 5-avain,Clé nouveau 5,5. kulcs,Nuova Chiave 5,,새로운 키5,Nieuwe sleutel 5,Ny nøkkel5,Nowy Klucz5,Chave Nova 5,,Noua Cheie5,Новый ключ №5,Нови кључ5,Ny nyckel5,Yeni Anahtar5 +Oracle Pass,TAG_ORACLEPASS,,,,Věštcova propustka,Orakelpas,Orakelpass,,Orakolo-pasilo,Pase del Oráculo,,Oraakkelin kulkulupa,Passe de l'Oracle,Orákulum útlevél,Lasciapassare dell'Oracolo ,,오라클의 통행증,Orakelpas,Oracle Pass,Przepustka Wyroczni,Passe do Oráculo,,Legitimația Oracol,Пропуск Оракула,Пророкова пропусница,Orakelpass,Kahin Kartı +10 gold,TAG_10GOLD,,,,10 zlatých,10 guld,,,10 da oro,10 de oro,,10 kolikkoa,10 Pièces,10 arany,10 pezzi d'oro ,10ゴールド,10 골드,10 goud,10 gull,10 monet,10 moedas,10 moedas de ouro,10 monezi de aur,10 золотых,10 златника,10 guld,10 altın +25 gold,TAG_25GOLD,,,,25 zlatých,25 guld,,,25 da oro,25 de oro,,25 kolikkoa,25 Pièces,25 arany,25 pezzi d'oro ,25ゴールド,25 골드,25 goud,25 gull,25 monet,25 moedas,25 moedas de ouro,25 de monezi de aur,25 золотых,25 златника,25 guld,25 altın +50 gold,TAG_50GOLD,,,,50 zlatých,50 guld,,,50 da oro,50 de oro,,50 kolikkoa,50 Pièces,50 arany,50 pezzi d'oro ,50ゴールド,50 골드,50 goud,50 gull,50 monet,50 moedas,50 moedas de ouro,50 de monezi de aur,50 золотых,50 златника,50 guld,50 altın +300 gold,TAG_300GOLD,,,,300 zlatých,300 guld,,,300 da oro,300 de oro,,300 kolikkoa,300 Pièces,300 arany,300 pezzi d'oro ,300ゴールド,300 골드,300 goud,300 gull,300 monet,300 moedas,300 moedas de ouro,300 de monezi de aur,300 золотых,300 златника,300 guld,300 altın +Person,TXT_PERSON,,,,Osoba,,,,Persono,Persona,,Henkilö,Personne,Személy,Persona,一員,민간인,Persoon,,Osoba,Pessoa,,Persoană,Горожанин,Особа,Person,Kişi +Acolyte,TAG_ACOLYTE,,,,Akolyta,Akolyt,Ministrant,,Akolito,Acólito,,Akoluutti,,Ministráns,Accolito ,アコライト,아콜라이트,Acoliet,Akolytt,Akolita,Acólito,,Acolit,Служитель,Следбеник,Akolyt,Yardımcı +Armorer,TAG_ARMORER,,,Armourer,Kovář,Våbendør,Rüster,,Armilisto,Armero,,Asemestari,Armurier,Páncélkovács,Armaiolo ,装甲,병기공,Harnassmid,Våpensmed,Płatnerz,Armeiro,,Armurier,Продавец брони,Ковач,Rusthållare,Zırhçı +Bar Keep,TAG_BARKEEP,,,,Výčepní,Bar-værn,Wirt,,Trinkejisto,Cantinero,,Baarimikko,Barman,Csapos,Barista,酒屋,바텐더,Barman,Bartender,Barman,Dono do Bar,,Barman,Хозяин таверны,Конобар,Bartender,Barmen +Beggar,TAG_BEGGAR,,,,Žebrák,Tigger,Bettler,,Almozulo,Mendigo,,Kerjäläinen,Mendiant,Koldus,Mendicante ,乞食,거지,Bedelaar,Tigger,Żebrak,Mendigo,,Sărman,Нищий,Просјак,Tiggare,Dilenci +Macil,TAG_MACIL1,,,,,,,,,,,,,,,マシル,마실,,,,,,,Мэйсил,Мејсил,,Macil +Macil,TAG_MACIL2,,,,,,,,,,,,,,,マシル,마실,,,,,,,Мэйсил,Мејсил,,Macil +Medic,TAG_MEDIC,,,,Medik,Læge,Sanitäter,,Kuracisto,Médico,,Lääkintämies,Médecin,Szanitéc,Medico,メディック,의무관,Paramedicus,,Medyk,Médico,,,Врач,Болничар,Sjukvårdare, +Oracle,TAG_ORACLE,,,,Věštec,Orakel,Orakel,,Orakolo,Oráculo,,Oraakkeli,,Orákulum,Oracolo,オラクル,오라클,Orakel,Orakel,Wyrocznia,Oráculo,,Oracol,Оракул,Пророк,Orakel,Kahin +Priest,TAG_PRIEST,,,,Kněz,Præst,Priester,,Pastro,Sacerdote,,Pappi,Prêtre,Pap,Sacerdote,プリースト,성직자,Priester,Prest,Kapłan,Sacerdote,,Preot,Жрец,Свештеник,Präst,Rahip +Rat Buddy,TAG_RATBUDDY,,,,Krysík,Rottekammerat,Ratte,,Rato,Rata,,Rottakamu,Copain Rat,Patkánypajtás,Ratto,ラット バディ,생쥐 친구,Rattenvriendje,Rottekompis,Koleżka Szczurów,Rato,,Amicul Șobolanilor,Крыса-друг,Друг пацов,Råttkompis,Sıçan Dostu +Rebel,TAG_REBEL,,,,,,Rebell,,Ribelanto,Rebelde,,Kapinallinen,Rebelle,Lázadó,Ribelle ,反乱軍,저항군,,Rebell,Rebeliant,Rebelde,,,Повстанец,Побуњеник,Rebell,Asi +Templar,TAG_TEMPLAR,,,,Templář,Tempelridder,Templer,,Templano,Templario,,Temppeliherra,Templier,Templomos,Templare ,騎士団員,템플러,Tempelier,Tempelridder,Templariusz,Templário,,Templier,Храмовник,Темплар,Tempelriddare,Tapınakçı +Weapon Smith,TAG_WEAPONSMITH,,,,Zbraňmistr,Våbensmed,Waffenschmied,,Armilforĝisto,Forjador de Armas,,Aseseppä,Forgeron,Fegyverkovács,Fabbro ,武器工,무기 제조상,Wapensmid,Våpensmed,Wytwórca Broni,Ferreiro,,Făurar,Оружейник,Ковач оружја,Vapensmed,Silah Ustası +Red Talisman,TAG_TALISMANRED,,,,Červený talisman,Rød Talisman,Roter Talisman,,Ruĝa Talismano,Talismán rojo,,Punainen talismaani,Talisman Rouge,Vörös Talizmán,Talismano rosso,赤の魔除け,붉은 부적,Rode Talisman,Rød talisman,Czerwony Talizman,Talismã Vermelho,,Talisman Roșu,Красный талисман,Црвени талисман,Röd talisman,Kızıl Tılsım +Green Talisman,TAG_TALISMANGREEN,,,,Zelený talisman,Grøn Talisman,Grüner Talisman,,Verda Talismano,Talismán verde,,Vihreä talismaani,Talisman Vert,Zöld Talizmán,Talismano verde,緑の魔除け,녹색 부적,Groene Talisman,Grønn talisman,Zielony Talizman,Talismã Verde,,Talisman Verde,Зелёный талисман,Зелени талисман,Grön Talisman,Yeşil Tılsım +Blue Talisman,TAG_TALISMANBLUE,,,,Modrý talisman,Blå Talisman,Blauer Talisman,,Blua Talismano,Talismán azul,,Sininen talismaani,Talisman Bleu,Kék Talizmán,Talismano blu,青の魔除け,푸른 부적,Blauwe Talisman,Blå talisman,Niebieski Talizman,Talismã Azul,,Talisman Albastru,Синий талисман,Плави талисман,Blå Talisman,Mavi Tılsım +,,Obituaries,,,,,,,,,,,,,,,,,,,,,,,,, +%o was zealously shot down by an Acolyte.,OB_ACOLYTE,,,,%o byl@[ao_cs] horlivě zastřelen@[ao_cs] akolytou.,%o blev skudt ned af en akolyt.,%o wurde eifrig von dem Ministranten erschossen.,,%o fervore pafiĝis de Akolito.,A %o l@[ao_esp] ha derribado con fervor un Acólito.,A %o l@[ao_esp] derribó con entusiasmo un Acólito.,%o joutui kiivailevan akoluutin ampumaksi.,%o a souffert d'une bavure policière.,%o-t buzgó módon le lett lőve egy Oltárszolga által.,%o è stato zelantemente abbattuto da un accolito. ,%o は熱心なアコライトに堕とされた。,%o 은(는) 아콜라이트에게 맹신적으로 사격 당했다.,%o werd gretig neergeschoten door een Acoliet.,%o ble nidkjært skutt ned av en akolytt.,%o został@[ao_pl] żarliwie zastrzelon@[adj_pl] przez Akolitę.,%o foi zelosamente abatid@[ao_ptb] por um Acólito.,,%o a fost împușcat zelos de un Acolit.,Игрок %o фанатично убит служителем.,%o је ревносно упуцан@[adj_1_sr] од стране секташа.,%o blev nitiskt nedskjuten av en akolyt.,"%o, bir yardımcısı tarafından gayretle vuruldu." %o should have never rebelled against Macil.,OB_MACIL,,,,%o se nikdy neměl@[ao_cs] vzbouřit vůči Macilovi.,%o skulle aldrig have gjort oprør mod Macil.,%o hätte nicht gegen Macil rebellieren sollen.,,%o ne estus devinta ribeli kontraŭ Macil.,%o no debería haberse rebelado contra Macil.,%o hizo mal en rebelarse contra Macil.,%o paran ei olisi ikinä pitänyt kapinoida Macilia vastaan.,%o n'aurait jamais du se rebeller contre Macil.,%o Macil ellen próbált fellázadni.,%o non avrebbe mai dovuto opporsi a Macil. ,%o はマシルに歯向かうべきではなかった。,%o 은(는) 마실의 적이 되지 말았어야 했다.,%o had nooit in opstand mogen komen tegen Macil.,%o skulle aldri ha gjort opprør mot Macil.,%o nie powin@[irreg_5_pl] buntować się przeciwko Macilowi.,%o nunca deveria ter se rebelado contra Macil.,%o nunca deveria ter se rebeliado contra Macil.,"%o nu ar fi trebuit să se răscoale împotriva lui -Macil.",Игроку %o не следовало восставать против Мэйсила.,%o никад није треба@[ao_1_sr] да се супротстави Мејсилу.,"%o, Macil'e karşı asla isyan etmemeliydi." -%o was gunned down by a Rebel.,OB_REBEL,,,,%o byl@[ao_cs] odstřelen@[ao_cs] rebelem.,%o blev skudt ned af en oprører.,%o wurde von einem Rebellen erschossen.,,%o pafegiĝis de ribelanto.,%o ha sido fusilad@[ao_esp] por un Rebelde.,%o fue fusilad@[ao_esp] por un Rebelde.,%o joutui kapinallisen alas ampumaksi.,%o a été abattu@[e_fr] par un rebelle.,%o le lett lőve egy Lázadó által.,%o è stato colpito a morte da un Ribelle. ,%o は反乱軍に撃ち殺された。,%o 은(는) 저항군에 의해 제압당했다.,%o werd neergeschoten door een Rebel.,%o ble skutt ned av en opprører.,%o został@[ao_pl] rozstrzelan@[adj_pl] przez Rebelianta.,%o foi abatid@[ao_ptb] por um Rebelde.,,%o a fost pus la pământ de un Rebel.,Игрока %o расстрелял повстанец.,%o је упуцан@[adj_1_sr] од стране побуњеника.,%o bir asi tarafından vuruldu. -%o was beaten to death by the poor.,OB_BEGGAR,,,,%o byl@[ao_cs] umlácen@[ao_cs] chudinou.,%o blev slået ihjel af de fattige.,%o fiel der Armut zum Opfer.,,%o morte bategiĝis de la malriĉuloj.,%o ha sido abatid@[ao_esp] hasta morir por los pobres.,%o recibió una paliza letal de los pobres.,%o joutui köyhälistön kuoliaaksi hakkaamaksi.,%o a été battu@[e_fr] a mort par un pauvre.,%o halálra lett verve a szegénység által.,%o è stato calpestato dalla povertà. ,%o は貧民に殴り殺された。,%o 은(는) 자업자득으로 거지에게 맞아 죽었다.,%o werd door de armen doodgeslagen.,%o ble slått i hjel av de fattige.,%o został@[ao_pl] zatłuczon@[adj_pl] na śmierć przez żebraka.,%o foi espancad@[ao_ptb] até a morte pelos pobres.,,%o a fost omorât în bătaie de sărmani.,Игрока %o забили до смерти нищие.,%o је претучен@[adj_1_sr] од стране просјака.,%o fakirler tarafından ölene kadar dövüldü. -%o should have never picked a fight with a civilian.,OB_PEASANT,,,,%o si neměl@[ao_cs] začínat s civilistou.,%o skulle aldrig have taget et slagsmål med en civilist.,%o hätte sich nicht mit einem Zivilisten anlegen sollen.,,%o ne estus devinta komenci batalon al civilulo.,%o no debería haber empezado una pelea con un civil.,%o hizo mal en iniciar una pelea con un civil.,%o hölmön ei olisi ikinä pitänyt haastaa riitaa siviilin kanssa.,%o n'aurait jamais du chercher des noises a un civil.,%o ujjat húzott egy civillel.,%o non avrebbe mai dovuto prendersela con un civile. ,%o は庶民に戦いを挑むべきではなかった。,%o 은(는) 민간인과 싸울 힘도 전혀 없었다.,%o had nooit een gevecht met een burger moeten aangaan.,%o skulle aldri ha kranglet med en sivilist.,%o nigdy nie powin@[irreg_5_pl] wdawać się w bójkę z cywilem.,%o nunca deveria ter arrumado briga com um civil.,%o nunca deveria ter pegado à briga com um civil.,%o n-ar fi trebuit să se încaiere cu un civil.,Игроку %o не следовало начинать драку с горожанином.,%o никад није треба@[ao_1_sr] да се потуче са цивилом.,%o asla bir sivil ile kavga etmemeliydi. -%o was struck down by the Spectre.,OB_ALIENSPECTRE,,,,%o byl@[ao_cs] zničen@[ao_cs] přízrakem.,%o blev slået ned af spøgelset.,%o wurde von dem Schemen niedergestreckt.,,%o subite mortiĝis de la Fantomo.,%o ha sido fulminad@[ao_esp] por el Espectro.,%o fue fulminad@[ao_esp] por el Espectro.,%o joutui haamun kaatamaksi.,%o a été terrassé@[e_fr] par le Spectre.,%o ki lett ütve a lidérc által.,%o è stato abbattuto dallo Spettro. ,%o はスペクトルに討ち滅ぼされた。,%o 은(는) 스펙터에 의해 무너져 내렸다.,%o werd door de Specter neergeslagen.,%o ble slått ned av Spekter.,%o został@[ao_pl] powalon@[adj_pl] przez Widmo.,%o foi abatid@[ao_ptb] por um Espectro.,,%o a fost răpus de Spectru.,Игрока %o уничтожил призрак.,%o је обори@[ao_1_sr] са ногу утвара.,%o Hortlak tarafından vuruldu. -%o felt the wrath of The One God.,OB_ENTITY,,,,%o pocítil@[ao_cs] vztek Jediného Boha,%o følte den ene Guds vrede.,%o spürte den Zorn des Einen Gottes.,,%o sentis la koleregon de La Ununura Dio.,%o acaba de sentir la ira del Dios Único.,%o sintió la ira del Dios Único.,%o sai tuta Yhden Ainoan Jumalan vihan.,%o a senti le courroux du Seul Dieu.,%o megérezte az Egyetlen Isten haragját.,%o ha assistito all'ira dell'Unico Dio. ,%o は唯一神の怒りに触れた。,%o 은(는) 유일신의 이름으로 천벌을 받았다.,%o voelde de toorn van de Ene God.,%o følte vreden til Den ene Gud.,%o poczuł@[ao_pl] gniew Jedynego Boga.,%o sentiu a ira do Deus Único.,,%o a simțit furia Zeului.,Игрок %o столкнулся с гневом Единого Бога.,Играча %o је осетио бес Јединог бога.,%o Tek Tanrı'nın gazabını hissetti. -%o couldn't escape from the Lore Master's grasp.,OB_LOREMASTER,,,,%o nemohl@[ao_cs] utéct Dějepiscově sevření.,%o kunne ikke undslippe Loremesterens greb.,%o konnte dem Griff des Wissensmeisters nicht entkommen.,,%o ne povis eskapi el la kapto de la Ĉef-folklorulo.,%o no ha conseguido huir de las garras del Maestro del Conocimiento.,%o no pudo huir de las garras del Maestro del Conocimiento.,%o ei kyennyt pakenemaan Oppi-Isän otteesta.,%o n'a pu échapper a l'emprise du Maître des Traditions.,%o nem tudott elmenekülni a Tan Mester elől.,%o non è riuscito a sfuggire alla stretta del Sapiente.,%o はロアマスターの手から逃れられなかった。,%o 은(는) 로어마스터의 촉수를 벗어나지 못했다.,%o kon niet ontsnappen aan de greep van de kennismeester.,%o kunne ikke unnslippe Loremesterens grep.,%o nie m@[irreg_4_pl] uniknąć chwytu Mędrca.,%o não conseguiu escapar do alcance do Mestre do Conhecimento.,,"%o n-a putut scăpa din mâinile Maestrului -Cunoștințelor.",Игрок %o не смог избежать длани Хранителя мудрости.,%o није успе@[ao_1_sr] побећи из Чувареве мудрости домашаја.,"%o, İrfan Ustası'nın elinden kaçamadı." +Macil.",Игроку %o не следовало восставать против Мэйсила.,%o никад није треба@[ao_1_sr] да се супротстави Мејсилу.,%o borde aldrig ha gjort uppror mot Macil.,"%o, Macil'e karşı asla isyan etmemeliydi." +%o was gunned down by a Rebel.,OB_REBEL,,,,%o byl@[ao_cs] odstřelen@[ao_cs] rebelem.,%o blev skudt ned af en oprører.,%o wurde von einem Rebellen erschossen.,,%o pafegiĝis de ribelanto.,A %o l@[ao_esp] ha fusilado un Rebelde.,A %o l@[ao_esp] fusiló un Rebelde.,%o joutui kapinallisen alas ampumaksi.,%o a été abattu@[e_fr] par un rebelle.,%o le lett lőve egy Lázadó által.,%o è stato colpito a morte da un Ribelle. ,%o は反乱軍に撃ち殺された。,%o 은(는) 저항군에 의해 제압당했다.,%o werd neergeschoten door een Rebel.,%o ble skutt ned av en opprører.,%o został@[ao_pl] rozstrzelan@[adj_pl] przez Rebelianta.,%o foi abatid@[ao_ptb] por um Rebelde.,,%o a fost pus la pământ de un Rebel.,Игрока %o расстрелял повстанец.,%o је упуцан@[adj_1_sr] од стране побуњеника.,%o blev skjuten av en rebell.,%o bir asi tarafından vuruldu. +%o was beaten to death by the poor.,OB_BEGGAR,,,,%o byl@[ao_cs] umlácen@[ao_cs] chudinou.,%o blev slået ihjel af de fattige.,%o fiel der Armut zum Opfer.,,%o morte bategiĝis de la malriĉuloj.,%o ha sido abatid@[ao_esp] a muerte por los pobres.,%o recibió una paliza letal de los pobres.,%o joutui köyhälistön kuoliaaksi hakkaamaksi.,%o a été battu@[e_fr] a mort par un pauvre.,%o halálra lett verve a szegénység által.,%o è stato calpestato dalla povertà. ,%o は貧民に殴り殺された。,%o 은(는) 자업자득으로 거지에게 맞아 죽었다.,%o werd door de armen doodgeslagen.,%o ble slått i hjel av de fattige.,%o został@[ao_pl] zatłuczon@[adj_pl] na śmierć przez żebraka.,%o foi espancad@[ao_ptb] até a morte pelos pobres.,,%o a fost omorât în bătaie de sărmani.,Игрока %o забили до смерти нищие.,%o је претучен@[adj_1_sr] од стране просјака.,%o blev ihjälslagen av de fattiga.,%o fakirler tarafından ölene kadar dövüldü. +%o should have never picked a fight with a civilian.,OB_PEASANT,,,,%o si neměl@[ao_cs] začínat s civilistou.,%o skulle aldrig have taget et slagsmål med en civilist.,%o hätte sich nicht mit einem Zivilisten anlegen sollen.,,%o ne estus devinta komenci batalon al civilulo.,%o no debería haber empezado una pelea con un civil.,%o hizo mal en iniciar una pelea con un civil.,%o hölmön ei olisi ikinä pitänyt haastaa riitaa siviilin kanssa.,%o n'aurait jamais du chercher des noises a un civil.,%o ujjat húzott egy civillel.,%o non avrebbe mai dovuto prendersela con un civile. ,%o は庶民に戦いを挑むべきではなかった。,%o 은(는) 민간인과 싸울 힘도 전혀 없었다.,%o had nooit een gevecht met een burger moeten aangaan.,%o skulle aldri ha kranglet med en sivilist.,%o nigdy nie powin@[irreg_5_pl] wdawać się w bójkę z cywilem.,%o nunca deveria ter arrumado briga com um civil.,%o nunca deveria ter pegado à briga com um civil.,%o n-ar fi trebuit să se încaiere cu un civil.,Игроку %o не следовало начинать драку с горожанином.,%o никад није треба@[ao_1_sr] да се потуче са цивилом.,%o skulle aldrig ha börjat slåss med en civilperson.,%o asla bir sivil ile kavga etmemeliydi. +%o was struck down by the Spectre.,OB_ALIENSPECTRE,,,,%o byl@[ao_cs] zničen@[ao_cs] přízrakem.,%o blev slået ned af spøgelset.,%o wurde von dem Schemen niedergestreckt.,,%o subite mortiĝis de la Fantomo.,A %o l@[ao_esp] ha fulminado el Espectro.,A %o l@[ao_esp] fulminó el Espectro.,%o joutui haamun kaatamaksi.,%o a été terrassé@[e_fr] par le Spectre.,%o ki lett ütve a lidérc által.,%o è stato abbattuto dallo Spettro. ,%o はスペクトルに討ち滅ぼされた。,%o 은(는) 스펙터에 의해 무너져 내렸다.,%o werd door de Specter neergeslagen.,%o ble slått ned av Spekter.,%o został@[ao_pl] powalon@[adj_pl] przez Widmo.,%o foi abatid@[ao_ptb] por um Espectro.,,%o a fost răpus de Spectru.,Игрока %o уничтожил фантом.,%o је обори@[ao_1_sr] са ногу утвара.,%o blev nedsliten av spektret.,%o Hortlak tarafından vuruldu. +%o felt the wrath of The One God.,OB_ENTITY,,,,%o pocítil@[ao_cs] vztek Jediného Boha,%o følte den ene Guds vrede.,%o spürte den Zorn des Einen Gottes.,,%o sentis la koleregon de La Ununura Dio.,%o ha sentido la ira del Dios Único.,%o sintió la ira del Dios Único.,%o sai tuta Yhden Ainoan Jumalan vihan.,%o a senti le courroux du Seul Dieu.,%o megérezte az Egyetlen Isten haragját.,%o ha assistito all'ira dell'Unico Dio. ,%o は唯一神の怒りに触れた。,%o 은(는) 유일신의 이름으로 천벌을 받았다.,%o voelde de toorn van de Ene God.,%o følte vreden til Den ene Gud.,%o poczuł@[ao_pl] gniew Jedynego Boga.,%o sentiu a ira do Deus Único.,,%o a simțit furia Zeului.,Игрок %o столкнулся с гневом Единого Бога.,Играча %o је осетио бес Јединог бога.,%o fick känna på den ende gudens vrede.,%o Tek Tanrı'nın gazabını hissetti. +%o couldn't escape from the Lore Master's grasp.,OB_LOREMASTER,,,,%o nemohl@[ao_cs] utéct Dějepiscově sevření.,%o kunne ikke undslippe Loremesterens greb.,%o konnte dem Griff des Wissensmeisters nicht entkommen.,,%o ne povis eskapi el la kapto de la Ĉef-folklorulo.,%o no ha conseguido huir de las garras del Maestro del Conocimiento.,%o no logró huir de las garras del Maestro del Conocimiento.,%o ei kyennyt pakenemaan Oppi-Isän otteesta.,%o n'a pu échapper a l'emprise du Maître des Traditions.,%o nem tudott elmenekülni a Tan Mester elől.,%o non è riuscito a sfuggire alla stretta del Sapiente.,%o はロアマスターの手から逃れられなかった。,%o 은(는) 로어마스터의 촉수를 벗어나지 못했다.,%o kon niet ontsnappen aan de greep van de kennismeester.,%o kunne ikke unnslippe Loremesterens grep.,%o nie m@[irreg_4_pl] uniknąć chwytu Mędrca.,%o não conseguiu escapar do alcance do Mestre do Conhecimento.,,"%o n-a putut scăpa din mâinile Maestrului +Cunoștințelor.",Игрок %o не смог избежать длани Хранителя мудрости.,%o није успе@[ao_1_sr] побећи из Чувареве мудрости домашаја.,%o kunde inte fly från läromästarens grepp.,"%o, İrfan Ustası'nın elinden kaçamadı." %o was deleted by the Programmer.,OB_PROGRAMMER,,,,%o byl@[ao_cs] vymazán@[ao_cs] Programátorem.,%o blev slettet af Programmøren.,%o wurde vom Programmierer gelöscht.,,%o eksiĝis de La Programisto.,%o ha sido suprimid@[ao_esp] por El Programador.,%o fue suprimid@[ao_esp] por El Programador.,%o joutui Ohjelmoijan poistamaksi.,%o a été effacé@[e_fr] par le Programmeur.,%o ki lett törölve a Programozó által.,%o è stato cancellato dal Programmatore. ,%o はプログラマーに消去された。,%o 은(는) 프로그래머에 의해 삭제됐다.,%o werd door de programmeur verwijderd.,%o ble slettet av Programmereren.,"%o został@[ao_pl] usunięt@[adj_pl] przez Programistę. -",%o foi deletad@[ao_ptb] pelo Programador.,%o foi apagad@[ao_ptb] pelo Programador.,%o a fost șters de Programator.,Игрока %o удалил Программист.,Играча %о је обрисао Програмер.,%o Programcı tarafından silindi. -%o was blown away by the Bishop.,OB_STFBISHOP,,,,%o byl@[ao_cs] odpálen@[ao_cs] Biskupem.,%o blev sprængt væk af Biskoppen.,%o wurde vom Bischof weggeblasen.,,%o forbloviĝis de la Episkopo.,%o ha sido volad@[ao_esp] en pedazos por el Obispo.,%o fue volad@[ao_esp] en pedazos por el Obispo.,%o joutui Piispan tyrmäämäksi.,%o a été pulvérisé@[e_fr] par l'Evèque.,%o el lett fújva a Püspök által.,%o è stato spazzato via dal Vescovo. ,%o はビショップに吹き飛ばされた。,%o 은(는) 비숍에 의해 초토화되었다.,%o werd door de bisschop weggeblazen.,%o ble blåst bort av biskopen.,%o został@[ao_pl] wysadzon@[adj_pl] przez Biskupa.,%o foi detonad@[ao_ptb] pelo Bispo.,,%o a fost aruncat cât colo de Episcop.,Игрока %o поразил Епископ.,Играча %o је екслопдирао Епископ.,"%o, Piskopos tarafından havaya uçuruldu." -%o was shot down by a Sentinel.,OB_SENTINEL,,,,%o byl@[ao_cs] odstřelen@[ao_cs] strážným robotem.,%o blev skudt ned af en Sentinel.,%o wurde von dem Wächter niedergeschossen.,,%o pafegiĝis de Sentinelo.,%o ha sido derribad@[ao_esp] por un Centinela.,%o fue derribad@[ao_esp] por un Centinela.,%o joutui vartijan ampumaksi.,%o a été abattu@[e_fr] par une Sentinelle.,%o meg lett lőve egy Őrszem által.,%o è stato impallinato dalla Sentinella. ,%o はセンティネルに堕とされた。,%o 은(는) 센티넬의 레이져를 맞았다.,%o werd neergeschoten door een Sentinel.,%o ble skutt ned av en Sentinel.,%o został@[ao_pl] zastrzelon@[adj_pl] przez Wartownika.,%o foi abatid@[ao_ptb] por uma Sentinela.,,%o a fost pus la pământ de o Santinelă.,Игрока %o застрелил страж.,Играча %o је упуцао стражар.,%o bir Nöbetçi tarafından vuruldu. -%o was swept away by a Crusader.,OB_CRUSADER,,,,%o byl@[ao_cs] odhozen@[ao_cs] křižákem.,%o blev fejet væk af en korsfarer.,%o wurde vom Ordensritter weggeblasen.,,%o tute detruiĝis de Krucisto.,%o ha sido aniquilad@[ao_esp] por un Cruzado.,%o fue aniquilad@[ao_esp] por un Cruzado.,%o joutui ristiretkeläisen pois pyyhkäisemäksi.,%o a été balayé@[e_fr] par un Croisé.,%o el lett söpörve egy Keresztes Lovag által.,%o è stato tolto di mezzo da un Crociato. ,"%o はクルセーダーに一掃された。 -",%o 은(는) 크루세이더의 공격에 날라갔다.,%o werd weggevaagd door een kruisvaarder.,%o ble feid bort av en korsfarer.,%o został@[ao_pl] zmiecion@[adj_pl] przez Krzyżowca.,%o foi varrid@[ao_ptb] por um Cruzado.,,%o a fost măturat de un Cruciat.,Игрока %o смёл крестоносец.,%o је обори@[ao_1_sr] с ногу крсташ.,%o bir Haçlı tarafından süpürüldü. -%o was sentenced by an Inquisitor.,OB_INQUISITOR,,,,%o byl@[ao_cs] odsouzen@[ao_cs] inkvizitorem.,%o blev dømt af en inkvisitor.,%o wurde vom Inquisitor verurteilt.,,%o kondamniĝis de Inkvizitoro.,%o ha sido sentenciad@[ao_esp] por un Inquisidor.,%o fue sentenciad@[ao_esp] por un Inquisidor.,%o joutui inkvisiittorin tuomitsemaksi.,%o a été condamné@[e_fr] par un Inquisiteur.,%o el lett ítélve egy Vizsgálóbíró által.,%o è stato condannato da un Inquisitore. ,"%o は審問官によって宣告された。 -",%o 은(는) 인퀴지터에 의해 처벌받았다.,%o werd veroordeeld door een inquisiteur.,%o ble dømt av en inkvisitor.,%o został@[ao_pl] skazan@[adj_pl] przez Inkwizytora.,%o foi condenad@[ao_ptb] por um Inquisidor.,,%o a fost condamnat de un Inchizitor.,Игрока %o приговорил инквизитор.,Играчу %o је пресудио инквизитор.,%o bir Engizisyoncu tarafından mahkum edildi. -%o was bugged by a Stalker.,OB_STALKER,,,,%o se nechal@[ao_cs] otravovat slídilem.,%o blev aflyttet af en Stalker.,%o wurde von dem Jäger genervt.,,%o ĝeniĝis de Persekutanto.,%o ha sido fastidiad@[ao_esp] por un Acechador.,%o fue fastidiad@[ao_esp] por un Acechador.,%o joutui vaanijan häiritsemäksi.,%o a été asticoté@[e_fr] par un chasseur.,%o bogaras lett egy Settenkedő által.,%o è stato violentato da un Cacciatore. ,"%o はストーカーに精神を蝕まれた。 -",%o 은(는) 스토커에게 벌레 물림을 당했다.,%o werd afgeluisterd door een Stalker.,%o ble avlyttet av en Stalker.,%o został@[ao_pl] zaczepion@[adj_pl] przez Prześladowcę.,%o foi atacad@[ao_ptb] por um Caçador.,,%o a fost cicălit de un Hărțuitor.,Игрока %o ужалил преследователь.,Играча %o је убио прогонитељ.,%o bir Takipçi tarafından dinlendi. -%o triggered the automatic defenses.,OB_TURRET,,,%o triggered the automatic defences.,%o spustil@[ao_cs] automatickou obranu.,%o udløste det automatiske forsvar.,%o hat die automatische Verteidigung ausgelöst.,,%o ekagigis la aŭtomatajn defendojn.,%o ha activado las defensas automáticas.,%o activó las defensas automáticas.,%o laukaisi automaattipuolustukset.,%o a déclenché les défenses automatiques.,%o bekapcsolta az automata védelmi rendszert.,%o ha attivato le difese automatiche. ,%o は警備システムを起動してしまった。,%o 은(는) 경비 시스템에 발각되었다.,%o activeerde de automatische verdediging.,%o utløste det automatiske forsvaret.,%o aktywował@[ao_pl] automatyczne zabezpieczenia.,%o ativou as defesas automáticas.,,%o a alertat sistemul de protecție automat.,Из-за игрока %o активировалась автоматическая защита.,%o је активира@[ao_1_sr] дефанзивне системе.,%o otomatik savunmayı tetikledi. -%o was clawed by a Templar.,OB_TEMPLARHIT,,,,%o byl@[ao_cs] rozsápán@[ao_cs] templářem.,%o blev kløet af en Tempelridder.,%o wurde von dem Templer aufgeschlitzt.,,%o ungegiĝis de Templano.,%o ha sido desgarrad@[ao_esp] por un Templario.,%o fue desgarrad@[ao_esp] por un Templario.,%o joutui temppeliherran raatelemaksi.,%o a été griffé@[e_fr] par un Templier.,%o meg lett karmolva egy Templomos által.,%o è stato artigliato da un Templare. ,%o は騎士団員に連行された。,%o 은(는) 템플러에게 할큄을 당했다.,%o werd geklauwd door een Tempelier.,%o ble klort av en tempelridder.,%o został@[ao_pl] rozszarpan@[adj_pl] przez Templariusza.,%o foi rasgad@[ao_ptb] por um Templário.,,%o a fost zgâriat de un Templier.,Игрока %o разорвал храмовник.,%o је пресечен@[adj_1_sr] од стране темплара.,%o bir Tapınakçı tarafından pençelendi. -%o was vaporized by a Templar.,OB_TEMPLAR,,,,%o byl@[ao_cs] rozpuštěn@[ao_cs] templářem.,%o blev fordampet af en Tempelridder.,%o wurde von dem Templer vaporisiert.,,%o vaporiĝis de Templano.,%o ha sido vaporizad@[ao_esp] por un Templario.,%o fue vaporizad@[ao_esp] por un Templario.,%o joutui temppeliherran höyryttämäksi.,%o a été vaporisé@[e_fr] par un Templier.,%o elpárolgott egy Templomos által.,%o è stato vaporizzato da un Templare. ,%o は騎士団員に浄化された。,%o 은(는) 템플러에 의해 존재가 소멸됐다.,%o werd verdampt door een Tempelier.,%o ble fordampet av en tempelridder.,%o rozpłyn@[irreg_2_pl] się przez Templariusza.,%o foi vaporizad@[ao_ptb] por um Templário.,,%o a fost vaporizat de un Templier.,Игрока %o испепелил храмовник.,Играча %o је испарио темплар.,%o bir Tapınakçı tarafından buharlaştırıldı. -%o was sliced open by a Reaver.,OB_REAVERHIT,,,,%o byl@[ao_cs] rozřezán@[ao_cs] pleničem.,%o blev skåret op af en Reaver.,%o wude von dem Plünderer aufgeschlitzt.,,%o distranĉiĝis de Lerta roboto.,%o ha sido rebanad@[ao_esp] por un Saqueador.,%o fue rebanad@[ao_esp] por un Saqueador.,%o joutui raastajan auki viiltämäksi.,%o a été fendu@[e_fr] par un Reaver.,%o szét lett vágva egy Fosztogató által.,%o è stato aperto a metà da un Saccheggiatore. ,%o はリーバーに切り裂かれた。,%o 은(는) 리버에게 해부되었다.,%o werd opengesneden door een Reaver.,%o ble skåret opp av en Reaver.,%o został@[ao_pl] rozcięt@[adj_pl] przez Rozbójnika.,%o foi fatiad@[ao_ptb] por um Saqueador.,,%o a fost feliat de un Pungaș.,Игрока %o разрезал на куски похититель.,%o је исечен@[adj_1_sr] на отворено од стране сакупљача.,%o bir Yağmacı tarafından kesildi. -%o was shot down by a Reaver.,OB_REAVER,,,,%o byl@[ao_cs] zastřelen@[ao_cs] pleničem.,%o blev skudt ned af en Reaver.,%o wurde von dem Plünderer niedergeschossen.,,%o pafegiĝis de Lerta roboto.,%o ha sido derribad@[ao_esp] por un Saqueador.,%o fue derribad@[ao_esp] por un Saqueador.,%o joutui raastajan alas ampumaksi.,%o a été descendu@[e_fr] par un Reaver.,%o le lett lőve egy Fosztogató által.,%o è stato colpito da un Saccheggiatore. ,%o はリーバーに撃ち殺された。,%o 은(는) 리버에게 격파되었다.,%o werd neergeschoten door een Reaver.,%o ble skutt ned av en Reaver.,%o został@[ao_pl] zastrzelon@[adj_pl] przez Rozbójnika.,%o foi abatid@[ao_ptb] por um Saqueador.,,%o a fost împușcat de un Pungaș.,Игрока %o застрелил похититель.,Играча %o је упуцао сакупљач.,%o bir Yağmacı tarafından vuruldu. -%o was unwittingly backstabbed by %k.,OB_MPPUNCHDAGGER,,,,%o dostal@[ao_cs] kudlou do zad od hráče %k.,%o blev ufrivilligt stukket i ryggen af %k.,%o wurde von %k hinterrücks erdolcht.,,%o akcidente dorspikiĝis de %k.,%o ha sido apuñalad@[ao_esp] sin querer por %k.,%o fue apuñalad@[ao_esp] sin querer por %k.,%o joutui tahattomasti pelaajan %k selkäänpuukottamaksi.,%o s'est fait@[e_fr] planter un lame dans le dos de la part de %k.,%o véletlenül hátbalett szúrva %k által.,%o è stato colto alle spalle da %k senza che se ne accorgesse.,%o は電気ショックを %k からもらった。,%o 은(는) 모르는 사이에 %k 에 의해 비수를 찔렸다.,%o werd achtergestoken door %k.,%o ble uforvarende dolket i ryggen av %k.,%o został@[ao_pl] bezwiednie dźgnięt@[adj_pl] przez %k.,%o foi apunhalad@[ao_ptb] de surpresa por %k.,,%o a fost înjunghiat pe la spate de %k.,Игрок %o был непреднамеренно заколот кинжалом игрока %k.,%o је убоден@[adj_1_sr] у леђа од стране играча %k.,"%o, %k tarafından farkında olmadan arkadan bıçaklandı." -%o got bolted to the wall by %k.,OB_MPELECTRICBOLT,,,,%o byl@[ao_cs] přišpendlen@[ao_cs] ke zdi hráčem %k.,%o blev boltet fast til væggen af %k.,%o wurde von %k an die Wand genagelt.,,%o pafiĝis de sageto sur la muro de %k.,%o ha quedado atornillad@[ao_esp] a la pared por %k.,%o quedó atornillad@[ao_esp] a la pared por %k.,%o naulitsi %o paran seinään.,%o s'est fait@[e_fr] clouer au mur par %k.,%o falra lett szegezve %k által.,%o è stato inchiodato al muro da %k.,%o は %k に壁へ打ち付けられた。,%o 은(는) %k 의 전류가 흐르는 볼트촉을 만졌다.,%o werd door %k aan de muur geschroefd.,%o ble boltet fast til veggen av %k.,%o został@[ao_pl] przybit@[adj_pl] do ściany przez %k.,%o foi pregad@[ao_ptb] na parede por %k.,,%o a fost agățat de perete de %k.,Игрок %o был прибит к стене игроком %k.,%o је причвршћен@[adj_1_sr] за зид од стране играча %k.,"%o, %k tarafından duvara yapıştırıldı." -%o received a lethal dose of %k's wrath.,OB_MPPOISONBOLT,,,,%o přijal@[ao_cs] smrtelnou dávku hněvu hráče %k.,%o fik en dødelig dosis af %ks vrede.,%o erhielt eine tödliche Dosis von %ks Zorn.,,%o recivis mortigan dozon de la kolerego de %k.,%o ha recibido una dosis letal de la ira de %k.,%o recibió una dosis letal de la ira de %k.,%o sai tappavan annoksen pelaajan %k vihaa.,%o a recu une dose létale de la colère de %k.,%o kapott egy halálos adagot %k-tól/től.,%o ha ricevuto una dose letale dell'ira di %k.,%o は 致死量の %k の怒りを盛られた。,%o 은(는) %k 로부터 암살 같지 않은 암살을 당했다.,%o kreeg een dodelijke dosis van %k's toorn.,%o fikk en dødelig dose av %ks vrede.,%o dostał@[ao_pl] śmiertelną dawkę gniewu %k.,%o recebeu uma dose letal da ira de %k.,,%o a primit o doză letală din furia lui %k.,Игрок %o получил смертельную дозу гнева игрока %k.,%o је доби@[ao_1_sr] смртну дозу гнева играча %k.,"%o, %k tarafından zehirlendi." +",%o foi deletad@[ao_ptb] pelo Programador.,%o foi apagad@[ao_ptb] pelo Programador.,%o a fost șters de Programator.,Игрока %o удалил Программист.,Играча %о је обрисао Програмер.,%o blev raderad av programmeraren.,%o Programcı tarafından silindi. +%o was blown away by the Bishop.,OB_STFBISHOP,,,,%o byl@[ao_cs] odpálen@[ao_cs] Biskupem.,%o blev sprængt væk af Biskoppen.,%o wurde vom Bischof weggeblasen.,,%o forbloviĝis de la Episkopo.,%o ha sido volad@[ao_esp] en pedazos por el Obispo.,%o fue volad@[ao_esp] en pedazos por el Obispo.,%o joutui Piispan tyrmäämäksi.,%o a été pulvérisé@[e_fr] par l'Evèque.,%o el lett fújva a Püspök által.,%o è stato spazzato via dal Vescovo. ,%o はビショップに吹き飛ばされた。,%o 은(는) 비숍에 의해 초토화되었다.,%o werd door de bisschop weggeblazen.,%o ble blåst bort av biskopen.,%o został@[ao_pl] wysadzon@[adj_pl] przez Biskupa.,%o foi detonad@[ao_ptb] pelo Bispo.,,%o a fost aruncat cât colo de Episcop.,Игрока %o поразил Епископ.,Играча %o је екслопдирао Епископ.,%o blev bortblåst av biskopen.,"%o, Piskopos tarafından havaya uçuruldu." +%o was shot down by a Sentinel.,OB_SENTINEL,,,,%o byl@[ao_cs] odstřelen@[ao_cs] strážným robotem.,%o blev skudt ned af en Sentinel.,%o wurde von dem Wächter niedergeschossen.,,%o pafegiĝis de Sentinelo.,A %o l@[ao_esp] ha derribado un Centinela.,A %o l@[ao_esp] derribó un Centinela.,%o joutui vartijan ampumaksi.,%o a été abattu@[e_fr] par une Sentinelle.,%o meg lett lőve egy Őrszem által.,%o è stato impallinato dalla Sentinella. ,%o はセンティネルに堕とされた。,%o 은(는) 센티넬의 레이져를 맞았다.,%o werd neergeschoten door een Sentinel.,%o ble skutt ned av en Sentinel.,%o został@[ao_pl] zastrzelon@[adj_pl] przez Wartownika.,%o foi abatid@[ao_ptb] por uma Sentinela.,,%o a fost pus la pământ de o Santinelă.,Игрока %o застрелил страж.,Играча %o је упуцао стражар.,%o blev nedskjuten av en Sentinel.,%o bir Nöbetçi tarafından vuruldu. +%o was swept away by a Crusader.,OB_CRUSADER,,,,%o byl@[ao_cs] odhozen@[ao_cs] křižákem.,%o blev fejet væk af en korsfarer.,%o wurde vom Ordensritter weggeblasen.,,%o tute detruiĝis de Krucisto.,A %o l@[ao_esp] ha aniquilado un Cruzado.,A %o l@[ao_esp] aniquiló un Cruzado.,%o joutui ristiretkeläisen pois pyyhkäisemäksi.,%o a été balayé@[e_fr] par un Croisé.,%o el lett söpörve egy Keresztes Lovag által.,%o è stato tolto di mezzo da un Crociato. ,"%o はクルセーダーに一掃された。 +",%o 은(는) 크루세이더의 공격에 날라갔다.,%o werd weggevaagd door een kruisvaarder.,%o ble feid bort av en korsfarer.,%o został@[ao_pl] zmiecion@[adj_pl] przez Krzyżowca.,%o foi varrid@[ao_ptb] por um Cruzado.,,%o a fost măturat de un Cruciat.,Игрока %o смёл крестоносец.,%o је обори@[ao_1_sr] с ногу крсташ.,%o sveptes bort av en korsriddare.,%o bir Haçlı tarafından süpürüldü. +%o was sentenced by an Inquisitor.,OB_INQUISITOR,,,,%o byl@[ao_cs] odsouzen@[ao_cs] inkvizitorem.,%o blev dømt af en inkvisitor.,%o wurde vom Inquisitor verurteilt.,,%o kondamniĝis de Inkvizitoro.,A %o l@[ao_esp] ha sentenciado un Inquisidor.,A %o l@[ao_esp] sentenció un Inquisidor.,%o joutui inkvisiittorin tuomitsemaksi.,%o a été condamné@[e_fr] par un Inquisiteur.,%o el lett ítélve egy Vizsgálóbíró által.,%o è stato condannato da un Inquisitore. ,"%o は審問官によって宣告された。 +",%o 은(는) 인퀴지터에 의해 처벌받았다.,%o werd veroordeeld door een inquisiteur.,%o ble dømt av en inkvisitor.,%o został@[ao_pl] skazan@[adj_pl] przez Inkwizytora.,%o foi condenad@[ao_ptb] por um Inquisidor.,,%o a fost condamnat de un Inchizitor.,Игрока %o приговорил инквизитор.,Играчу %o је пресудио инквизитор.,%o blev dömd av en inkvisitor.,%o bir Engizisyoncu tarafından mahkum edildi. +%o was bugged by a Stalker.,OB_STALKER,,,,%o se nechal@[ao_cs] otravovat slídilem.,%o blev aflyttet af en Stalker.,%o wurde von dem Jäger genervt.,,%o ĝeniĝis de Persekutanto.,A %o l@[ao_esp] ha fastidiado un Acechador.,A %o l@[ao_esp] fastidió un Acechador.,%o joutui vaanijan häiritsemäksi.,%o a été asticoté@[e_fr] par un chasseur.,%o bogaras lett egy Settenkedő által.,%o è stato violentato da un Cacciatore. ,"%o はストーカーに精神を蝕まれた。 +",%o 은(는) 스토커에게 벌레 물림을 당했다.,%o werd afgeluisterd door een Stalker.,%o ble avlyttet av en Stalker.,%o został@[ao_pl] zaczepion@[adj_pl] przez Prześladowcę.,%o foi atacad@[ao_ptb] por um Caçador.,,%o a fost cicălit de un Hărțuitor.,Игрока %o ужалил преследователь.,Играча %o је убио прогонитељ.,%o blev avlyssnad av en Stalker.,%o bir Takipçi tarafından dinlendi. +%o triggered the automatic defenses.,OB_TURRET,,,%o triggered the automatic defences.,%o spustil@[ao_cs] automatickou obranu.,%o udløste det automatiske forsvar.,%o hat die automatische Verteidigung ausgelöst.,,%o ekagigis la aŭtomatajn defendojn.,%o ha activado las defensas automáticas.,%o activó las defensas automáticas.,%o laukaisi automaattipuolustukset.,%o a déclenché les défenses automatiques.,%o bekapcsolta az automata védelmi rendszert.,%o ha attivato le difese automatiche. ,%o は警備システムを起動してしまった。,%o 은(는) 경비 시스템에 발각되었다.,%o activeerde de automatische verdediging.,%o utløste det automatiske forsvaret.,%o aktywował@[ao_pl] automatyczne zabezpieczenia.,%o ativou as defesas automáticas.,,%o a alertat sistemul de protecție automat.,Из-за игрока %o активировалась автоматическая защита.,%o је активира@[ao_1_sr] дефанзивне системе.,%o utlöste det automatiska försvaret.,%o otomatik savunmayı tetikledi. +%o was clawed by a Templar.,OB_TEMPLARHIT,,,,%o byl@[ao_cs] rozsápán@[ao_cs] templářem.,%o blev kløet af en Tempelridder.,%o wurde von dem Templer aufgeschlitzt.,,%o ungegiĝis de Templano.,A %o l@[ao_esp] ha desgarrado un Templario.,A %o l@[ao_esp] desgarró un Templario.,%o joutui temppeliherran raatelemaksi.,%o a été griffé@[e_fr] par un Templier.,%o meg lett karmolva egy Templomos által.,%o è stato artigliato da un Templare. ,%o は騎士団員に連行された。,%o 은(는) 템플러에게 할큄을 당했다.,%o werd geklauwd door een Tempelier.,%o ble klort av en tempelridder.,%o został@[ao_pl] rozszarpan@[adj_pl] przez Templariusza.,%o foi rasgad@[ao_ptb] por um Templário.,,%o a fost zgâriat de un Templier.,Игрока %o разорвал храмовник.,%o је пресечен@[adj_1_sr] од стране темплара.,%o blev klömsugen av en tempelriddare.,%o bir Tapınakçı tarafından pençelendi. +%o was vaporized by a Templar.,OB_TEMPLAR,,,,%o byl@[ao_cs] rozpuštěn@[ao_cs] templářem.,%o blev fordampet af en Tempelridder.,%o wurde von dem Templer vaporisiert.,,%o vaporiĝis de Templano.,A %o l@[ao_esp] ha vaporizado un Templario.,A %o l@[ao_esp] vaporizó un Templario.,%o joutui temppeliherran höyryttämäksi.,%o a été vaporisé@[e_fr] par un Templier.,%o elpárolgott egy Templomos által.,%o è stato vaporizzato da un Templare. ,%o は騎士団員に浄化された。,%o 은(는) 템플러에 의해 존재가 소멸됐다.,%o werd verdampt door een Tempelier.,%o ble fordampet av en tempelridder.,%o rozpłyn@[irreg_2_pl] się przez Templariusza.,%o foi vaporizad@[ao_ptb] por um Templário.,,%o a fost vaporizat de un Templier.,Игрока %o испепелил храмовник.,Играча %o је испарио темплар.,%o blev förångad av en tempelriddare.,%o bir Tapınakçı tarafından buharlaştırıldı. +%o was sliced open by a Reaver.,OB_REAVERHIT,,,,%o byl@[ao_cs] rozřezán@[ao_cs] pleničem.,%o blev skåret op af en Reaver.,%o wude von dem Plünderer aufgeschlitzt.,,%o distranĉiĝis de Lerta roboto.,A %o l@[ao_esp] ha rebanado un Saqueador.,A %o l@[ao_esp] rebanó un Saqueador.,%o joutui raastajan auki viiltämäksi.,%o a été fendu@[e_fr] par un Reaver.,%o szét lett vágva egy Fosztogató által.,%o è stato aperto a metà da un Saccheggiatore. ,%o はリーバーに切り裂かれた。,%o 은(는) 리버에게 해부되었다.,%o werd opengesneden door een Reaver.,%o ble skåret opp av en Reaver.,%o został@[ao_pl] rozcięt@[adj_pl] przez Rozbójnika.,%o foi fatiad@[ao_ptb] por um Saqueador.,,%o a fost feliat de un Pungaș.,Игрока %o разрезал на куски похититель.,%o је исечен@[adj_1_sr] на отворено од стране сакупљача.,%o blev uppskuren av en Reaver.,%o bir Yağmacı tarafından kesildi. +%o was shot down by a Reaver.,OB_REAVER,,,,%o byl@[ao_cs] zastřelen@[ao_cs] pleničem.,%o blev skudt ned af en Reaver.,%o wurde von dem Plünderer niedergeschossen.,,%o pafegiĝis de Lerta roboto.,A %o l@[ao_esp] ha derribado un Saqueador.,A %o l@[ao_esp] derribó un Saqueador.,%o joutui raastajan alas ampumaksi.,%o a été descendu@[e_fr] par un Reaver.,%o le lett lőve egy Fosztogató által.,%o è stato colpito da un Saccheggiatore. ,%o はリーバーに撃ち殺された。,%o 은(는) 리버에게 격파되었다.,%o werd neergeschoten door een Reaver.,%o ble skutt ned av en Reaver.,%o został@[ao_pl] zastrzelon@[adj_pl] przez Rozbójnika.,%o foi abatid@[ao_ptb] por um Saqueador.,,%o a fost împușcat de un Pungaș.,Игрока %o застрелил похититель.,Играча %o је упуцао сакупљач.,%o blev nedskjuten av en Reaver.,%o bir Yağmacı tarafından vuruldu. +%o was unwittingly backstabbed by %k.,OB_MPPUNCHDAGGER,,,,%o dostal@[ao_cs] kudlou do zad od hráče %k.,%o blev ufrivilligt stukket i ryggen af %k.,%o wurde von %k hinterrücks erdolcht.,,%o akcidente dorspikiĝis de %k.,%o ha sido apuñalad@[ao_esp] sin querer por %k.,%o fue apuñalad@[ao_esp] sin querer por %k.,%o joutui tahattomasti pelaajan %k selkäänpuukottamaksi.,%o s'est fait@[e_fr] planter un lame dans le dos de la part de %k.,%o véletlenül hátbalett szúrva %k által.,%o è stato colto alle spalle da %k senza che se ne accorgesse.,%o は電気ショックを %k からもらった。,%o 은(는) 모르는 사이에 %k 에 의해 비수를 찔렸다.,%o werd achtergestoken door %k.,%o ble uforvarende dolket i ryggen av %k.,%o został@[ao_pl] bezwiednie dźgnięt@[adj_pl] przez %k.,%o foi apunhalad@[ao_ptb] de surpresa por %k.,,%o a fost înjunghiat pe la spate de %k.,Игрок %o был непреднамеренно заколот кинжалом игрока %k.,%o је убоден@[adj_1_sr] у леђа од стране играча %k.,%o blev omedvetet knivhuggen i ryggen av %k.,"%o, %k tarafından farkında olmadan arkadan bıçaklandı." +%o got bolted to the wall by %k.,OB_MPELECTRICBOLT,,,,%o byl@[ao_cs] přišpendlen@[ao_cs] ke zdi hráčem %k.,%o blev boltet fast til væggen af %k.,%o wurde von %k an die Wand genagelt.,,%o pafiĝis de sageto sur la muro de %k.,%o ha quedado atornillad@[ao_esp] a la pared por %k.,%o quedó atornillad@[ao_esp] a la pared por %k.,%o naulitsi %o paran seinään.,%o s'est fait@[e_fr] clouer au mur par %k.,%o falra lett szegezve %k által.,%o è stato inchiodato al muro da %k.,%o は %k に壁へ打ち付けられた。,%o 은(는) %k 의 전류가 흐르는 볼트촉을 만졌다.,%o werd door %k aan de muur geschroefd.,%o ble boltet fast til veggen av %k.,%o został@[ao_pl] przybit@[adj_pl] do ściany przez %k.,%o foi pregad@[ao_ptb] na parede por %k.,,%o a fost agățat de perete de %k.,Игрок %o был прибит к стене игроком %k.,%o је причвршћен@[adj_1_sr] за зид од стране играча %k.,%o blev bultad mot väggen av %k.,"%o, %k tarafından duvara yapıştırıldı." +%o received a lethal dose of %k's wrath.,OB_MPPOISONBOLT,,,,%o přijal@[ao_cs] smrtelnou dávku hněvu hráče %k.,%o fik en dødelig dosis af %ks vrede.,%o erhielt eine tödliche Dosis von %ks Zorn.,,%o recivis mortigan dozon de la kolerego de %k.,%o ha recibido una dosis letal de la ira de %k.,%o recibió una dosis letal de la ira de %k.,%o sai tappavan annoksen pelaajan %k vihaa.,%o a recu une dose létale de la colère de %k.,%o kapott egy halálos adagot %k-tól/től.,%o ha ricevuto una dose letale dell'ira di %k.,%o は 致死量の %k の怒りを盛られた。,%o 은(는) %k 로부터 암살 같지 않은 암살을 당했다.,%o kreeg een dodelijke dosis van %k's toorn.,%o fikk en dødelig dose av %ks vrede.,%o dostał@[ao_pl] śmiertelną dawkę gniewu %k.,%o recebeu uma dose letal da ira de %k.,,%o a primit o doză letală din furia lui %k.,Игрок %o получил смертельную дозу гнева игрока %k.,%o је доби@[ao_1_sr] смртну дозу гнева играча %k.,%o fick en dödlig dos av %ks vrede.,"%o, %k tarafından zehirlendi." %o was drilled full of holes by %k's assault gun.,OB_MPASSAULTGUN,,,,%o byl@[ao_cs] proděravěn@[ao_cs] skrz na skrz puškou hráče %k.,%o blev boret fuld af huller af %ks angrebspistol.,%o wurde von %ks Sturmgewehr perforiert.,,%o boriĝis kun multaj truoj de la sturmofusilo de %k.,%o ha sido taladrad@[ao_esp] por el fusil de asalto de %k.,%o fue taladrad@[ao_esp] por el fusil de asalto de %k.,%k porasi %o paran täyteen reikiä rynnäkkökiväärillään.,%o s'est fait@[e_fr] couvrir de trous par le fusil d'assaut de %k.,%o ki lett lyukasztva %k Gépfegyvere által.,%o è stato crivellato dall'arma d'assalto di %k.,%o は %k のアサルトガンで穴だらけにされた。,%o 은(는) %k 의 돌격소총 덕분에 멋진 구멍을 선물 받았다.,%o werd geperforeerd door %k.,%o ble boret full av hull av %ks stormgevær.,%o został@[ao_pl] przedziurkowan@[adj_pl] przez karabin szturmowy %k.,%o foi perfurad@[ao_ptb] pelo fuzil de assalto de %k.,,"%o a fost umplut de găuri de pușca lui -%k.",Игрок %o изрешечён штурмовой винтовкой игрока %k.,%o је изрешетан@[adj_1_sr] од стране јуришне пушке играча %k.,"%o, %k tarafından delik deşik edildi." -%o gulped down %k's missile.,OB_MPMINIMISSILELAUNCHER,,,,%o spolknul@[ao_cs] raketu hráče %k.,%o slugte %ks missil.,%o schluckte %ks Rakete herunter.,,%o glutis la misilon de %k.,%o se ha tragado el misil de %k.,%o se tragó el misil de %k.,%o nieli alas pelaajan %k ohjuksen.,%o a avalé le missile de %k.,%o lenyelte %k rakétáját.,%o ha inghiottito il missile di %k.,%o は %k のミサイルを味わった。,%o 은(는) %k 의 미니 미사일을 고맙게 삼켰다.,%o heeft %k's raket naar beneden geslingerd.,%o slukte %k's missil.,%o połkn@[irreg_2_pl] rakietę %k.,%o engoliu o míssil de %k.,,%o a înghițit proiectilul lui %k.,Игрок %o проглотил ракету игрока %k.,%o је прогута@[ao_1_sr] ракету играча %k.,"%o, %k tarafından patlatıldı." -%o was inverted by %k's H-E grenade.,OB_MPSTRIFEGRENADE,,,,%o byl@[ao_cs] otočen@[ao_cs] naruby výbušným granátem hráče %k.,%o blev omvendt af %ks H-E granat.,%o wurde von %ks HE-Granate invertiert.,,%o estis inversigita de la HE-grenado de %k.,%o ha sido invertid@[ao_esp] por la granada HE de %k.,%o fue invertid@[ao_esp] por la granada HE de %k.,%k käänsi %o paran nurinpäin räjähdekranaatillaan.,%o a été mis@[e_fr] sens dessus dessous par la grenade explosive de %k.,%o ki lett fordítva %k gránátája által.,%o è stato invertito dalla granata H-E di %k.,%o は %k のHE手榴弾によって反逆された。,%o 은(는) %k 의 고폭탄에 의해 역전당했다.,%o werd omgekeerd door %k's HE-granaat.,%o ble invertert av %ks H-E-granat.,%o został@[ao_pl] wywrócon@[adj_pl] przez granat %k.,%o foi peg@[ao_ptb] pelas granadas de %k.,,%o a fost întors pe dos de grenada lui %k.,Игрок %o вывернут наизнанку разрывной гранатой игрока %k.,%o се преокрену@[ao_1_sr] од стране Х-Е гранате играча %k.,"%o, %k tarafından ters çevrildi." -%o took a flame bath in %k's phosphorous pyre.,OB_MPPHOSPHOROUSGRENADE,,,,%o si dal@[ao_cs] ohnivou koupel ve fosforovém žáru hráče %k.,%o tog et flambad i %ks fosforbål.,%o nahm ein Flammenbad in %ks Scheiterhaufen.,,%o prenis flaman banon en la fosfora ŝtiparo de %k.,%o se ha bañado en las llamas de fósforo de %k.,%o se bañó en las llamas de fósforo de %k.,%o otti liekkikylvyn pelaajan %k fosforiroviolla.,%o s'est permis@[e_fr] une pyroclave dans les flammes phosphoriques de %k.,%o kapott egy tűzfürdőt %k máglyájától.,%o ha fatto un bagno nelle fiamme nella pira di fosforo di %k.,%o は %k の白リン弾で炎に包まれた。,%o 은(는) %k 의 소이탄이 뿜는 화염에 몸을 담갔다.,%o nam een vlammenbad in %k's fosforbrandstapel.,%o tok et flammebad i %ks fosforbål.,%o wzi@[irreg_2_pl] ognistą kąpiel w fosforowym stosie %k.,%o se banhou nas chamas de fósforo de %k.,,%o a făcut o baie fierbinte in fosforul lui %k.,Игрок %o принял горячую ванну из чистого фосфора игрока %k.,%o се окупа@[ao_1_sr] у пламену од стране фосфорне гранате играча %k.,"%o, %k tarafından fosforlu ateşte alev banyosu yaptırıldı." -%o was barbecued by %k.,OB_MPFLAMETHROWER,,,,%o byl@[ao_cs] usmažen@[ao_cs] hráčem %k.,%o blev grillet af %k.,%o wurde von %k gegrillt,,%o kradrostiĝis de %k.,%o ha sido asad@[ao_esp] por %k.,%o fue asad@[ao_esp] por %k.,%k grillasi %o paran.,%o est passé@[e_fr] au barbecue de %k.,%o meg lett sütve %k által.,%o è stato fatto alla griglia da %k.,%o は %k に丸焼きにされてしまった。,%o 은(는) %k 의 바비큐 파티에 참여했다. 혼자서.,%o werd gebarbecued door %k.,%o ble grillet av %k.,%o został@[ao_pl] ugrillowan@[adj_pl] przez %k.,%o virou churrasco por causa de %k.,,%o a fost făcut grătar de %k.,Игрок %k поджарил игрока %o.,%o је реш печен@[adj_1_sr] од стране играча %k.,"%o, %k tarafından mangalda pişirildi." -%o was zapped by %k.,OB_MPMAULER1,,,,%o byl@[ao_cs] zničen@[ao_cs] hráčem %k.,%o blev zappet af %k.,%o wurde von %k geschockt.,,%o elektrokutiĝis de %k.,%o ha sido electrocutad@[ao_esp] por %k.,%o fue electrocutad@[ao_esp] por %k.,%o joutui pelaajan %k sähköistämäksi.,%o s'est fait@[e_fr] électrocuter par %k.,%o kapott egy áramot %k által.,%o è stato fulminato da %k.,%o は %k から電気ショックを浴びた。,%o 은(는) %k 이(가) 가한 전기 충격을 당했다.,%o werd door %k gezapt.,%o fikk støt av %k.,%o został@[ao_pl] porażon@[adj_pl] przez %k.,%o foi eletrocutad@[ao_ptb] por %k.,,%o a fost electrocutat de %k.,Игрок %k ударил током игрока %o.,%o је елетрошокиран@[adj_1_sr] од стране играча %k.,"%o, %k tarafından zaplandı." -%o was viciously vaporized by %k.,OB_MPMAULER,,,,%o byl@[ao_cs] rozpuštěn@[ao_cs] hráčem %k.,%o blev brutalt fordampet af %k.,%o wurde von %k vaporisiert.,,%o estis brutale vaporigita de %k.,%o ha sido ferozmente vaporizad@[ao_esp] por %k.,%o fue ferozmente vaporizad@[ao_esp] por %k.,%o joutui pelaajan %k höyrystämäksi.,%o à été vicieusement vaporisé@[e_fr] par %k.,%o elpárolgott %k által.,%o è stato crudelmente vaporizzato da %k.,%o は %k の悪辣さにより気化した。,%o 은(는) %k 에 의해 소극적으로 소멸되었다.,%o was door %k verdampt.,%o ble ondskapsfullt fordampet av %k.,%o rozpłyn@[irreg_2_pl] się przez %k.,%o foi vaporizad@[ao_ptb] por %k.,,%o a fost evaporat în mod violent de %k.,Игрок %k безжалостно распылил игрока %o.,%o је брутално испари@[ao_1_sr] од стране играча %k.,"%o, %k tarafından acımasızca buharlaştırıldı." +%k.",Игрок %o изрешечён штурмовой винтовкой игрока %k.,%o је изрешетан@[adj_1_sr] од стране јуришне пушке играча %k.,%o blev fullborrad med hål av %ks attackpistol.,"%o, %k tarafından delik deşik edildi." +%o gulped down %k's missile.,OB_MPMINIMISSILELAUNCHER,,,,%o spolknul@[ao_cs] raketu hráče %k.,%o slugte %ks missil.,%o schluckte %ks Rakete herunter.,,%o glutis la misilon de %k.,%o se ha tragado el misil de %k.,%o se tragó el misil de %k.,%o nieli alas pelaajan %k ohjuksen.,%o a avalé le missile de %k.,%o lenyelte %k rakétáját.,%o ha inghiottito il missile di %k.,%o は %k のミサイルを味わった。,%o 은(는) %k 의 미니 미사일을 고맙게 삼켰다.,%o heeft %k's raket naar beneden geslingerd.,%o slukte %k's missil.,%o połkn@[irreg_2_pl] rakietę %k.,%o engoliu o míssil de %k.,,%o a înghițit proiectilul lui %k.,Игрок %o проглотил ракету игрока %k.,%o је прогута@[ao_1_sr] ракету играча %k.,%o slukade %ks missil.,"%o, %k tarafından patlatıldı." +%o was inverted by %k's H-E grenade.,OB_MPSTRIFEGRENADE,,,,%o byl@[ao_cs] otočen@[ao_cs] naruby výbušným granátem hráče %k.,%o blev omvendt af %ks H-E granat.,%o wurde von %ks HE-Granate invertiert.,,%o estis inversigita de la HE-grenado de %k.,%o ha sido invertid@[ao_esp] por la granada HE de %k.,%o fue invertid@[ao_esp] por la granada HE de %k.,%k käänsi %o paran nurinpäin räjähdekranaatillaan.,%o a été mis@[e_fr] sens dessus dessous par la grenade explosive de %k.,%o ki lett fordítva %k gránátája által.,%o è stato invertito dalla granata H-E di %k.,%o は %k のHE手榴弾によって反逆された。,%o 은(는) %k 의 고폭탄에 의해 역전당했다.,%o werd omgekeerd door %k's HE-granaat.,%o ble invertert av %ks H-E-granat.,%o został@[ao_pl] wywrócon@[adj_pl] przez granat %k.,%o foi peg@[ao_ptb] pelas granadas de %k.,,%o a fost întors pe dos de grenada lui %k.,Игрок %o вывернут наизнанку разрывной гранатой игрока %k.,%o се преокрену@[ao_1_sr] од стране Х-Е гранате играча %k.,%o blev omvänd av %ks H-E-granat.,"%o, %k tarafından ters çevrildi." +%o took a flame bath in %k's phosphorous pyre.,OB_MPPHOSPHOROUSGRENADE,,,,%o si dal@[ao_cs] ohnivou koupel ve fosforovém žáru hráče %k.,%o tog et flambad i %ks fosforbål.,%o nahm ein Flammenbad in %ks Scheiterhaufen.,,%o prenis flaman banon en la fosfora ŝtiparo de %k.,%o se ha bañado en las llamas de fósforo de %k.,%o se bañó en las llamas de fósforo de %k.,%o otti liekkikylvyn pelaajan %k fosforiroviolla.,%o s'est permis@[e_fr] une pyroclave dans les flammes phosphoriques de %k.,%o kapott egy tűzfürdőt %k máglyájától.,%o ha fatto un bagno nelle fiamme nella pira di fosforo di %k.,%o は %k の白リン弾で炎に包まれた。,%o 은(는) %k 의 소이탄이 뿜는 화염에 몸을 담갔다.,%o nam een vlammenbad in %k's fosforbrandstapel.,%o tok et flammebad i %ks fosforbål.,%o wzi@[irreg_2_pl] ognistą kąpiel w fosforowym stosie %k.,%o se banhou nas chamas de fósforo de %k.,,%o a făcut o baie fierbinte in fosforul lui %k.,Игрок %o принял горячую ванну из чистого фосфора игрока %k.,%o се окупа@[ao_1_sr] у пламену од стране фосфорне гранате играча %k.,%o tog ett flambad i %ks fosforbål.,"%o, %k tarafından fosforlu ateşte alev banyosu yaptırıldı." +%o was barbecued by %k.,OB_MPFLAMETHROWER,,,,%o byl@[ao_cs] usmažen@[ao_cs] hráčem %k.,%o blev grillet af %k.,%o wurde von %k gegrillt,,%o kradrostiĝis de %k.,%o ha sido asad@[ao_esp] por %k.,%o fue asad@[ao_esp] por %k.,%k grillasi %o paran.,%o est passé@[e_fr] au barbecue de %k.,%o meg lett sütve %k által.,%o è stato fatto alla griglia da %k.,%o は %k に丸焼きにされてしまった。,%o 은(는) %k 의 바비큐 파티에 참여했다. 혼자서.,%o werd gebarbecued door %k.,%o ble grillet av %k.,%o został@[ao_pl] ugrillowan@[adj_pl] przez %k.,%o virou churrasco por causa de %k.,,%o a fost făcut grătar de %k.,Игрок %k поджарил игрока %o.,%o је реш печен@[adj_1_sr] од стране играча %k.,%o blev grillad av %k.,"%o, %k tarafından mangalda pişirildi." +%o was zapped by %k.,OB_MPMAULER1,,,,%o byl@[ao_cs] zničen@[ao_cs] hráčem %k.,%o blev zappet af %k.,%o wurde von %k geschockt.,,%o elektrokutiĝis de %k.,A %o l@[ao_esp] ha electrocutado %k.,A %o l@[ao_esp] electrocutó %k.,%o joutui pelaajan %k sähköistämäksi.,%o s'est fait@[e_fr] électrocuter par %k.,%o kapott egy áramot %k által.,%o è stato fulminato da %k.,%o は %k から電気ショックを浴びた。,%o 은(는) %k 이(가) 가한 전기 충격을 당했다.,%o werd door %k gezapt.,%o fikk støt av %k.,%o został@[ao_pl] porażon@[adj_pl] przez %k.,%o foi eletrocutad@[ao_ptb] por %k.,,%o a fost electrocutat de %k.,Игрок %k ударил током игрока %o.,%o је елетрошокиран@[adj_1_sr] од стране играча %k.,%o blev zappad av %k.,"%o, %k tarafından zaplandı." +%o was viciously vaporized by %k.,OB_MPMAULER,,,,%o byl@[ao_cs] rozpuštěn@[ao_cs] hráčem %k.,%o blev brutalt fordampet af %k.,%o wurde von %k vaporisiert.,,%o estis brutale vaporigita de %k.,%o ha sido ferozmente vaporizad@[ao_esp] por %k.,%o fue ferozmente vaporizad@[ao_esp] por %k.,%o joutui pelaajan %k höyrystämäksi.,%o à été vicieusement vaporisé@[e_fr] par %k.,%o elpárolgott %k által.,%o è stato crudelmente vaporizzato da %k.,%o は %k の悪辣さにより気化した。,%o 은(는) %k 에 의해 소극적으로 소멸되었다.,%o was door %k verdampt.,%o ble ondskapsfullt fordampet av %k.,%o rozpłyn@[irreg_2_pl] się przez %k.,%o foi vaporizad@[ao_ptb] por %k.,,%o a fost evaporat în mod violent de %k.,Игрок %k безжалостно распылил игрока %o.,%o је брутално испари@[ao_1_sr] од стране играча %k.,%o blev brutalt förångad av %k.,"%o, %k tarafından acımasızca buharlaştırıldı." %o bowed down to the sheer power of %k's Sigil.,OB_MPSIGIL,,,,%o poklekl@[ao_cs] před čirou sílou Pečeti hráče %k.,%o bøjede sig for %ks sigil.,%o kapitulierte vor der Macht von %ks Sigil.,,%o kliniĝis antaŭ la plena potenco de la Sigelo de %k.,%o se ha inclinado ante el poder puro del emblema de %k.,%o se inclinó ante el poder puro del emblema de %k.,%o kumartui pelaajan %k Sinetin silkasta voimasta.,%o s'est prosterné@[e_fr] face à la toute puissance du Sigil de %k.,%o fejet hajtott %k Pecsétje ereje előtt.,%o si è prostrato davanti alla pura potenza del Sigillo di %k.,%o は %k のシジルによる威圧に屈した。,%o 은(는) %k 를 죽이기 전에 시질의 이름으로 절을 해야만 했다.,%o boog voor de kracht van %k's Sigil.,%o bøyde seg for kraften til %ks Sigil.,%o pokłonił@[ao_pl] się czystej mocy Pieczęci %k.,%o sentiu o poder do Sigilo de %k.,,"%o s-a plecat în fața puterii imense a Sigiliului -lui %k.",Игрок %o склонился перед силой Печати игрока %k.,%o је одклекну@[ao_1_sr] сировој моћи %k Сигила.,"%o, %k'in Sigil'inin katıksız gücüne boyun eğdi." -,,Miscellaneous,,,,,,,,,,,,,,,,,,,,,,,, -Quest for the Sigil,TXT_STRIFE_EPI,,,,Pátrání za Pečetí,Jagten på Sigilet,Suche nach dem Sigil,,Serĉado por la Sigelo,La búsqueda del Emblema,,Päämääränä Sinetti,La Quête du Sigil,A Pecsét felkutatása,Alla ricerca del Sigillo,シジルの探求,시질을 위한 임무,Zoektocht naar de Sigil,Jakten på sigilet,Poszukiwanie Pieczęci,Em Busca do Sigilo,Demanda pelo Sigilo,În căutarea Sigiliului,В поисках Печати,Потрага за Сигил,Sigilin Peşinde +lui %k.",Игрок %o склонился перед силой Печати игрока %k.,%o је одклекну@[ao_1_sr] сировој моћи %k Сигила.,%o böjde sig för den rena kraften i %ks Sigill.,"%o, %k'in Sigil'inin katıksız gücüne boyun eğdi." +,,Miscellaneous,,,,,,,,,,,,,,,,,,,,,,,,, +Quest for the Sigil,TXT_STRIFE_EPI,,,,Pátrání za Pečetí,Jagten på Sigilet,Suche nach dem Sigil,,Serĉado por la Sigelo,La búsqueda del Emblema,,Päämääränä Sinetti,La Quête du Sigil,A Pecsét felkutatása,Alla ricerca del Sigillo,シジルの探求,시질을 위한 임무,Zoektocht naar de Sigil,Jakten på sigilet,Poszukiwanie Pieczęci,Em Busca do Sigilo,Demanda pelo Sigilo,În căutarea Sigiliului,В поисках Печати,Потрага за Сигил,Jakten på Sigillet,Sigilin Peşinde You've freed the prisoners!,TXT_FREED_PRISONERS,,,,Vysvobodil@[ao_cs] jsi vězně!,Du har befriet fangerne!,Du hast die Gefangenen befreit!,,Vi liberigis la kaptitojn!,¡Has liberado a los prisioneros!,¡Liberaste a los prisioneros!,Olet vapauttanut vangit!,Vous avez libéré les prisonniers!,Kiszabadítottad a foglyokat!,"Hai liberato i prigionieri! -",囚人を解放した!,죄수들을 탈옥시켰다!,Je hebt de gevangenen bevrijd!,Du har befridd fangene!,Uwolnił@[irreg_3_pl] więźniów,Você liberou os prisioneiros!,Libertaste os prisioneiros!,Ai eliberat prizonierii!,Пленники освобождены!,Затвореници су ослобођени!,Mahkumları serbest bıraktınız! -You've destroyed the Converter!,TXT_DESTROYED_CONVERTER,,,,Zničil@[ao_cs] jsi konvertér!,Du har ødelagt konverteren!,Du hast den Konverter zerstört!,,Vi detruis la konvertilon!,¡Has destruido el convertidor!,¡Destruiste el convertidor!,Olet tuhonnut muuntajan!,Vous avez détruit le convertisseur!,Elpusztítottad a konvertálót!,Hai distrutto i Convertitori!,コンバーターを破壊した!,개조 장치를 파괴했다!,Je hebt de Converter vernietigd!,Du har tilintetgjort Omformeren!,Zniszczył@[irreg_3_pl] Transformator!,Você destruiu o Conversor!,Destruiste o Transformador!,Ai distrus Convertorul!,Преобразователь уничтожен!,Претварач је уништен!,Dönüştürücüyü yok ettiniz! +",囚人を解放した!,죄수들을 탈옥시켰다!,Je hebt de gevangenen bevrijd!,Du har befridd fangene!,Uwolnił@[irreg_3_pl] więźniów,Você liberou os prisioneiros!,Libertaste os prisioneiros!,Ai eliberat prizonierii!,Пленники освобождены!,Затвореници су ослобођени!,Du har befriat fångarna!,Mahkumları serbest bıraktınız! +You've destroyed the Converter!,TXT_DESTROYED_CONVERTER,,,,Zničil@[ao_cs] jsi konvertér!,Du har ødelagt konverteren!,Du hast den Konverter zerstört!,,Vi detruis la konvertilon!,¡Has destruido el convertidor!,¡Destruiste el convertidor!,Olet tuhonnut muuntajan!,Vous avez détruit le convertisseur!,Elpusztítottad a konvertálót!,Hai distrutto i Convertitori!,コンバーターを破壊した!,개조 장치를 파괴했다!,Je hebt de Converter vernietigd!,Du har tilintetgjort Omformeren!,Zniszczył@[irreg_3_pl] Transformator!,Você destruiu o Conversor!,Destruiste o Transformador!,Ai distrus Convertorul!,Преобразователь уничтожен!,Претварач је уништен!,Du har förstört omvandlaren!,Dönüştürücüyü yok ettiniz! Congratulations! You have completed the training area,TXT_COMPLETED_TRAINING,,,,Gratulujeme! Dokončil@[ao_cs] jsi tréninkový areál,Tillykke med det! Du har gennemført træningsområdet,Gratuliere! Du hast das Trainingsprogramm bestanden.,,Gratulon! Vi kompletigis la trejnejon,"¡Enhorabuena! Has completado la zona de entrenamiento","¡Muy bien! Completaste -la zona de entrenamiento",Onnittelut! Olet suorittanut koulutusalueen,Félicitations! Vous êtes arrivé à la fin de l'entraînement.,Gratulálok! Elvégezted a gyakorló területet.,Congratulazioni! Hai completato l'area di addestramento,おめでとう!トレーニングエリアを完了した,훈련 코스를 마쳤다. 능력치 업!,Gefeliciteerd! Je hebt de training voltooid.,Gratulerer! Du har fullført treningsområdet,Gratulacje! Ukończył@[irreg_3_pl] trening,Parabéns! Você completou a área de treinamento,Parabéns! Completaste a área de treino,Felicitări! Ai încheiat cu zona de antrenament,Браво! Ты прошёл тренировку,Честитке! Завршио си тренинг подручје,Tebrikler! Eğitim alanını tamamladınız -You've blown up the Crystal,TXT_QUEST_14,,,,Odpálil@[ao_cs] jsi krystal,Du ødelagde krystallen.,Du hast den Kristall zerstört.,,Vi eksplodigis la kristalon,Has volado el cristal,Volaste el cristal,Olet räjäyttänyt kristallin,Vous avez explosé le cristal!,Szétrobbantottad a kristályt,Hai fatto esplodere il Cristallo,クリスタルを爆破した,수정체를 파괴했다,Je hebt de Crystal opgeblazen.,Du har sprengt krystallen,Wysadził@[irreg_3_pl] Kryształ,Você explodiu o cristal,Explodiste o cristal,Ai aruncat în aer Cristalul,Кристалл взорван,Дигао си у ваздух кристал,Kristali havaya uçurdun. -You've blown up the Gates,TXT_QUEST_16,,,,Odpálil@[ao_cs] jsi brány,Du åbnede portene.,Du hast die Tore geöffnet.,,Vi detruis la pordegojn,Has destruido las puertas,Destruiste las puertas,Olet räjäyttänyt portit,Vous avez explosé les portes!,A levegőbe repítetted a kapukat,Hai fatto esplodere i Cancelli,ゲートを爆破した,성문을 파괴해서 열었다,Je hebt de Gates opgeblazen.,Du har sprengt portene,Wysadził@[irreg_3_pl] Bramy,Você explodiu as portões,Explodiste os portões,Ai aruncat în aer Porțile,Ворота взорваны,Дигао си у ваздух капију,Kapıları havaya uçurdun. -You've blown up the Computer,TXT_QUEST_27,,,,Odpálil@[ao_cs] jsi počítač,Du har ødelagt computeren.,Du hast den Computer zerstört.,,Vi detruis la komputilon,Has destruido el Ordenador,Destruiste la computadora,Olet räjäyttänyt tietokoneen,Vous avez explosé l'ordinateur!,Felrobbantottad a számítógépet,Hai fatto esplodere il Computer,コンピューターを爆破した,컴퓨터를 파괴했다,Je hebt de computer opgeblazen.,Du har sprengt Datamaskinen,Wysadził@[irreg_3_pl] Komputer,Você explodiu o computador,Explodiste o computador,Ai aruncat în aer Calculatorul,Компьютер взорван,Дигао си у ваздух компјутер,Bilgisayarı havaya uçurdun. -You killed the Bishop!,TXT_KILLED_BISHOP,,,,Zabil@[ao_cs] jsi Biskupa!,Du har dræbt biskoppen!,Du hast den Bischof getötet.,,Vi mortigis la Episkopon!,¡Has matado al Arzobispo!,¡Mataste al Arzobispo!,Olet tappanut Piispan!,Vous avez tué l'évèque!,Megölted a Püspököt!,Hai ucciso il Vescovo!,ビショップを殺した!,비숍을 사살했다!,Je hebt de bisschop vermoord!,Du har drept Biskopen!,Zabił@[irreg_3_pl] Biskupa!,Você matou o Bispo!,Mataste o Bispo!,Ai omorât Episcopul!,Епископ убит!,Епископ је мртав!,Piskoposu öldürdün! -You've killed the Oracle!,TXT_KILLED_ORACLE,,,,Zabil@[ao_cs] jsi Věštce!,Du har dræbt Oraklet!,Du hast das Orakel getötet,,Vi mortigis la Orakolon!,¡Has matado al Oráculo!,¡Mataste al Oráculo!,Olet tappanut Oraakkelin!,Vous avez tué l'oracle!,Megölted az Orákulumot!,Hai ucciso l'Oracolo!,オラクルの予言を覆した!,오라클의 음모를 막았다!,Je hebt het Orakel vermoord!,Du har drept Oraklet!,Zabił@[irreg_3_pl] Wyrocznię!,Você matou o Oráculo!,Mataste o Oráculo,Ai omorât Oracolul!,Оракул убит!,Пророк је мртав!,Kahini öldürdün! -You killed Macil!,TXT_KILLED_MACIL,,,,Zabil@[ao_cs] jsi Macila!,Du har dræbt Macil!,Du hast Macil getötet.,,Vi mortigis Macil!,¡Has matado a Macil!,¡Mataste a Macil!,Tapoit Macilin!,Vous avez tué Macil!,Megölted Macilt!,Hai ucciso Macil!,マシルを討ち取った!,마실을 처단했다!,Je hebt Macil vermoord!,Du har drept Macil!,Zabił@[irreg_3_pl] Macila!,Você matou o Macil!,Mataste Macil!,L-ai omorât pe Macil!,Мэйсил убит!,Мејсил је мртав!,Macil'i öldürdün! -You've killed the Loremaster!,TXT_KILLED_LOREMASTER,,,,Zabil@[ao_cs] jsi Dějepisce!,Du har dræbt Loremesteren!,Du hast den Wissensmeister getötet!,,Vi mortigis la Scimajstro!,¡Has matado al Maestro del Conocimiento!,¡Mataste al Maestro del Conocimiento!,Olet tappanut Oppi-Isän!,Vous avez tué le Maitre des traditions!,Megölted a Tudóst!,Hai ucciso il Sapiente!,ロアマスターを吊り上げた!,로어마스터의 목숨에 종지부를 찍었다!,Je hebt de Kennismeester vermoord!,Du har drept Loremaster!,Zabił@[irreg_3_pl] Mędrca!,Você matou o Mestre do Conhecimento!,Mataste o Mestre do Conhecimento!,L-ai omorât pe Maestrul Cunoștințelor!,Хранитель мудрости убит!,Чувара мудрости је мртав!,Loremaster'ı öldürdün! +la zona de entrenamiento",Onnittelut! Olet suorittanut koulutusalueen,Félicitations! Vous êtes arrivé à la fin de l'entraînement.,Gratulálok! Elvégezted a gyakorló területet.,Congratulazioni! Hai completato l'area di addestramento,おめでとう!トレーニングエリアを完了した,훈련 코스를 마쳤다. 능력치 업!,Gefeliciteerd! Je hebt de training voltooid.,Gratulerer! Du har fullført treningsområdet,Gratulacje! Ukończył@[irreg_3_pl] trening,Parabéns! Você completou a área de treinamento,Parabéns! Completaste a área de treino,Felicitări! Ai încheiat cu zona de antrenament,Браво! Ты прошёл тренировку,Честитке! Завршио си тренинг подручје,Grattis! Du har avslutat träningsområdet,Tebrikler! Eğitim alanını tamamladınız +You've blown up the Crystal,TXT_QUEST_14,,,,Odpálil@[ao_cs] jsi krystal,Du ødelagde krystallen.,Du hast den Kristall zerstört.,,Vi eksplodigis la kristalon,Has volado el cristal,Volaste el cristal,Olet räjäyttänyt kristallin,Vous avez explosé le cristal!,Szétrobbantottad a kristályt,Hai fatto esplodere il Cristallo,クリスタルを爆破した,수정체를 파괴했다,Je hebt de Crystal opgeblazen.,Du har sprengt krystallen,Wysadził@[irreg_3_pl] Kryształ,Você explodiu o cristal,Explodiste o cristal,Ai aruncat în aer Cristalul,Кристалл взорван,Дигао си у ваздух кристал,Du har sprängt kristallen.,Kristali havaya uçurdun. +You've blown up the Gates,TXT_QUEST_16,,,,Odpálil@[ao_cs] jsi brány,Du åbnede portene.,Du hast die Tore geöffnet.,,Vi detruis la pordegojn,Has destruido las puertas,Destruiste las puertas,Olet räjäyttänyt portit,Vous avez explosé les portes!,A levegőbe repítetted a kapukat,Hai fatto esplodere i Cancelli,ゲートを爆破した,성문을 파괴해서 열었다,Je hebt de Gates opgeblazen.,Du har sprengt portene,Wysadził@[irreg_3_pl] Bramy,Você explodiu as portões,Explodiste os portões,Ai aruncat în aer Porțile,Ворота взорваны,Дигао си у ваздух капију,Du har sprängt portarna.,Kapıları havaya uçurdun. +You've blown up the Computer,TXT_QUEST_27,,,,Odpálil@[ao_cs] jsi počítač,Du har ødelagt computeren.,Du hast den Computer zerstört.,,Vi detruis la komputilon,Has destruido el Ordenador,Destruiste la computadora,Olet räjäyttänyt tietokoneen,Vous avez explosé l'ordinateur!,Felrobbantottad a számítógépet,Hai fatto esplodere il Computer,コンピューターを爆破した,컴퓨터를 파괴했다,Je hebt de computer opgeblazen.,Du har sprengt Datamaskinen,Wysadził@[irreg_3_pl] Komputer,Você explodiu o computador,Explodiste o computador,Ai aruncat în aer Calculatorul,Компьютер взорван,Дигао си у ваздух компјутер,Du har sprängt datorn.,Bilgisayarı havaya uçurdun. +You killed the Bishop!,TXT_KILLED_BISHOP,,,,Zabil@[ao_cs] jsi Biskupa!,Du har dræbt biskoppen!,Du hast den Bischof getötet.,,Vi mortigis la Episkopon!,¡Has matado al Arzobispo!,¡Mataste al Arzobispo!,Olet tappanut Piispan!,Vous avez tué l'évèque!,Megölted a Püspököt!,Hai ucciso il Vescovo!,ビショップを殺した!,비숍을 사살했다!,Je hebt de bisschop vermoord!,Du har drept Biskopen!,Zabił@[irreg_3_pl] Biskupa!,Você matou o Bispo!,Mataste o Bispo!,Ai omorât Episcopul!,Епископ убит!,Епископ је мртав!,Du har dödat biskopen!,Piskoposu öldürdün! +You've killed the Oracle!,TXT_KILLED_ORACLE,,,,Zabil@[ao_cs] jsi Věštce!,Du har dræbt Oraklet!,Du hast das Orakel getötet,,Vi mortigis la Orakolon!,¡Has matado al Oráculo!,¡Mataste al Oráculo!,Olet tappanut Oraakkelin!,Vous avez tué l'oracle!,Megölted az Orákulumot!,Hai ucciso l'Oracolo!,オラクルの予言を覆した!,오라클의 음모를 막았다!,Je hebt het Orakel vermoord!,Du har drept Oraklet!,Zabił@[irreg_3_pl] Wyrocznię!,Você matou o Oráculo!,Mataste o Oráculo,Ai omorât Oracolul!,Оракул убит!,Пророк је мртав!,Du har dödat oraklet!,Kahini öldürdün! +You killed Macil!,TXT_KILLED_MACIL,,,,Zabil@[ao_cs] jsi Macila!,Du har dræbt Macil!,Du hast Macil getötet.,,Vi mortigis Macil!,¡Has matado a Macil!,¡Mataste a Macil!,Tapoit Macilin!,Vous avez tué Macil!,Megölted Macilt!,Hai ucciso Macil!,マシルを討ち取った!,마실을 처단했다!,Je hebt Macil vermoord!,Du har drept Macil!,Zabił@[irreg_3_pl] Macila!,Você matou o Macil!,Mataste Macil!,L-ai omorât pe Macil!,Мэйсил убит!,Мејсил је мртав!,Du har dödat Macil!,Macil'i öldürdün! +You've killed the Loremaster!,TXT_KILLED_LOREMASTER,,,,Zabil@[ao_cs] jsi Dějepisce!,Du har dræbt Loremesteren!,Du hast den Wissensmeister getötet!,,Vi mortigis la Scimajstro!,¡Has matado al Maestro del Conocimiento!,¡Mataste al Maestro del Conocimiento!,Olet tappanut Oppi-Isän!,Vous avez tué le Maitre des traditions!,Megölted a Tudóst!,Hai ucciso il Sapiente!,ロアマスターを吊り上げた!,로어마스터의 목숨에 종지부를 찍었다!,Je hebt de Kennismeester vermoord!,Du har drept Loremaster!,Zabił@[irreg_3_pl] Mędrca!,Você matou o Mestre do Conhecimento!,Mataste o Mestre do Conhecimento!,L-ai omorât pe Maestrul Cunoștințelor!,Хранитель мудрости убит!,Чувара мудрости је мртав!,Du har dödat Läromästaren!,Loremaster'ı öldürdün! You fool! You've set off the alarm.,TXT_YOUFOOL,,,,Blázne! Spustil@[ao_cs] jsi alarm!,Dit fjols! Du har udløst alarmen.,Du Trottel! Du hast den Alarm ausgelöst.,,"Stultulo! Vi ekigis la alarmon.","¡Insensat@[ao_esp]! Has activado la alarma.","¡Tont@[ao_esp]! -Activaste la alarma.",Sinä mieletön! Olet laukaissut hälytyksen.,Vous êtes fou! Vous avez activé l'alarme!,Te barom! Beindítottad a riasztót.,Stolto! Hai fatto scattare l'allarme.,バカな真似を! 警報を鳴らしてしまった。,어리석은 것! 알람이 작동되었다고!,Jij dwaas! Je hebt het alarm laten afgaan.,Din idiot! Du har utløst alarmen.,Głupcze! Włączył@[irreg_3_pl] alarm!,Seu idiota! Você ativou o alarme.,Idiota! Ativaste o alarme.,Nesăbuitule! Ai declanșat alarma!,Глупец. Ты привёл в действие сигнализацию!,Будало! Активирао си аларм.,Seni aptal! Alarmı çalıştırdın. +Activaste la alarma.",Sinä mieletön! Olet laukaissut hälytyksen.,Vous êtes fou! Vous avez activé l'alarme!,Te barom! Beindítottad a riasztót.,Stolto! Hai fatto scattare l'allarme.,バカな真似を! 警報を鳴らしてしまった。,어리석은 것! 알람이 작동되었다고!,Jij dwaas! Je hebt het alarm laten afgaan.,Din idiot! Du har utløst alarmen.,Głupcze! Włączył@[irreg_3_pl] alarm!,Seu idiota! Você ativou o alarme.,Idiota! Ativaste o alarme.,Nesăbuitule! Ai declanșat alarma!,Глупец. Ты привёл в действие сигнализацию!,Будало! Активирао си аларм.,Din idiot! Du har utlöst larmet.,Seni aptal! Alarmı çalıştırdın. You're dead! You set off the alarm.,TXT_YOUREDEAD,,,,Jsi mrtv@[adj_cs]! Spustil@[ao_cs] jsi alarm!,Du er død! Du udløste alarmen.,Du bist tot. Du hast den Alarm ausgelöst.,,"Vi estas mortinta! Vi ekigis la alarmon.","¡Estás muert@[ao_esp]! Has activado la alarma.","¡Estás muert@[ao_esp]! -Activaste la alarma.",Sinä kuolet! Laukaisit hälytyksen.,Vous êtes mort! Vous avez activé l'alarme!,Beindult a riasztó. Halott vagy!,Sei morto! L'allarme è scattato.,絶望的だ! 警報を鳴らしてしまった。,알람이 작동되었다. 넌 죽었어!,Je bent dood! Je hebt het alarm laten afgaan.,Du er død! Du utløste alarmen.,Już nie żyjesz! Włączył@[irreg_3_pl] alarm!,Você está mort@[ao_ptb]! Você ativou o alarme.,Estás mort@[ao_ptb]! Ativaste o alarme.,Ești mort! AI declanșat alarma!,Ты поднял тревогу! Готовься к смерти!,Активирао си аларм. Спреми се да умреш!,Sen öldün! Alarmı çalıştırdın. -You seem to have enough!,TXT_HAVEENOUGH,,,,Ty už máš přece dost!,Du ser ud til at have nok!,Du scheinst genug zu haben.,,Vi ŝajnas havi sufiĉe!,¡Se ve que tienes suficiente!,,Sinulla näyttää olevan tarpeeksi!,Vous avez l'air d'en avoir assez!,Úgy néz ki eleged van már!,Sembri averne abbastanza!,十分に持ち合わせている!,충분히 가진 것 같은데?,Je lijkt genoeg te hebben!,Du har visst fått nok!,"Wydaje się, że już ci wystarczy!",Você parece ter o suficiente!,Pareces ter o suficiente!,Pare că ai destule!,"Кажется, тебе хватит!",Изгледа да ти је доста!,Yeterince var gibi görünüyor! -Go away!,TXT_GOAWAY,,,,Jdi pryč!,Gå væk!,Verschwinde!,,Foriru!,¡Lárgate!,,Häivy!,Allez-vous en!,Takarodj!,Vattene via!,逃げ出せ!,저리 가!,Ga weg!,Forsvinn!,Idź stąd!,Vá embora!,Vai-te embora!,Pleacă!,Уходи!,Одлази!,Git başımdan! -Incoming Message...,TXT_COMM0,,,,Příchozí zpráva...,Indkommende besked...,Nachricht erhalten...,,Alvenas mesaĝo...,Mensaje entrante...,,Vastaantuleva viesti...,Message reçu.,Bejövő Üzenet...,Messaggio in arrivo...,メッセージが届いた...,메시지가 옴...,Inkomend bericht....,Innkommende melding...,Nadchodzi wiadomość...,Recebendo Mensagem...,A Receber Mensagem...,Mesaj în intrare...,Входящее сообщение...,Наилази порука...,Gelen Mesaj... -Incoming Message from BlackBird...,TXT_COMM1,,,,Příchozí zpráva od Straky...,Indkommende besked fra BlackBird...,Nachricht von Blackbird erhalten...,,Alvenas mesaĝo de BlackBird...,Mensaje entrante de BlackBird...,,Vastaantuleva viesti Blackbirdiltä...,Message reçu de BlackBird,Bejövő Üzenet Feketerigótól...,Messaggio in arrivo da Blackbird...,ブラックバードからのメッセージが届いた...,블랙버드로부터 메시지가 옴...,Inkomend bericht van BlackBird....,Innkommende melding fra BlackBird...,Nadchodzi wiadomość od BlackBird...,Recebendo Mensagem de BlackBird...,A Receber Mensagem de BlackBird...,Mesaj în intrare de la BlackBird...,Входящее сообщение от «Чёрного дрозда»...,Наилази порука од Црне птице....,Gelen Mesaj... -Find help,TXT_FINDHELP,,,,Najdi pomoc.,Find hjælp,Finde Hilfe,,Trovu helpon,Busca ayuda,,Etsi apua,Trouvez de L'aide,Keress segítséget,Trova aiuto,助けを探せ,도움말,Zoek hulp,Finn hjelp,Znajdź pomoc,Procure ajuda,Procura ajuda,Găsește ajutor,Найди помощь,Нађи помоћ,Yardım bul -for %u,TXT_TRADE,As in for %u amount of money.,,,za %u zlatých,til %u,für %u,,kontraŭ %u da oro.,por %u de oro.,,hintaan %u,pour %u,%u számára,per %u,%u ゴールド,(가격: %u),voor %u,til %u,za %u,por %u,,pentru %u,за %u,за %u,için %u -,,Chex Quest,,,,,,,,,,,,,,,,,,,,,,,, -,,Pickups,,,,,,,,,,,,,,,,,,,,,,,, -Picked up the Chex(R) Armor.,GOTCHEXARMOR,,,Picked up the Chex(R) Armour.,Sebráno Chex(R) brnění.,Hentede Chex(R) Rustning.,Du hast die Chex(R) Rüstung genommen,,Prenis la Chex(R)-kirason.,Recogiste la Armadura Chex(R).,,Poimit Chex(R)-panssarin.,Vous avez pris l'armure Chex(R).,Felvettél egy Chex(R) páncélt.,Raccolta un'Armatura Chex(R).,チェックス(R)アーマー をてにいれた。,첵스(R) 갑옷 획득.,Je hebt het Chex(R) harnas opgepakt.,Plukket opp Chex(R) Armor.,Zebrano Pancerz Chex(R).,Pegou uma Armadura Chex(R).,Apanhaste uma Armadura Chex(R).,Ai ridicat Armura Chex(R).,Получена Chex(R)-броня.,Покупио си Чех оклоп.,Chex(R) Zırhı'nı aldım. -Picked up the Super Chex(R) Armor!,GOTSUPERCHEXARMOR,,,Picked up the Super Chex(R) Armour!,Sebráno Super Chex(R) brnění!,Hentede Super Chex(R) Rustning!,Du hast die Superchex(R)Rüstung genommen!,,Prenis la superan Chex(R)-kirason!,¡Recogiste la Súper-Armadura Chex(R)!,,Poimit Super-Chex(R)-panssarin!,Vous avez pris la super armure Chex(R)!,Felvettél egy szuper Chex(R) páncélt!,Raccolta la Super Armatura Chex(R)!,スーパーチェックス(R)アーマー をてにいれた。,슈퍼 첵스(R) 갑옷 획득!,Je hebt het Super-Chex(R) harnas opgehaald!,Plukket opp Super Chex(R) Armor!,Zebrano Super Pancerz Chex(R)!,Pegou uma Super Armadura Chex(R)!,Apanhaste uma Super Armadura Chex(R)!,Ai ridicat Super Armura Chex(R)!,Получена Chex(R)-сверхброня!,Покупио си Супер Чех оклоп.,Süper Chex(R) Zırhı'nı aldı! -Picked up a glass of water.,GOTWATER,,,,Sebrána sklenice vody.,Samlede et glas vand op.,Du hast ein Glas Wasser genommen.,,Prenis glason de akvo.,Recogiste un vaso de agua.,,Poimit vesilasin.,Vous avez pris un verre d'eau.,Felvettél egy pohár vizet.,Raccolto un bicchiere d'acqua.,コップいっぱいの みずをひろった。,물 한 컵 섭취.,Je hebt een glas water opgepakt.,Hentet et glass vann.,Zebrano szklankę wody.,Pegou um copo d'água.,Apanhaste um copo de água.,Ai ridicat un pahar cu apă.,Получен стакан воды.,Покупио си чашу воде,Bir bardak su aldım. -Picked up slime repellent.,GOTREPELLENT,,,,Sebrán repelent proti slizu.,Hentede slimafvisende middel.,Du hast das Schleimabwehrmittel genommen.,,Prenis mukforigilon.,Recogiste un repelente de baba.,,Poimit limakarkotteen.,Vous avez pris de la chaux répulsive.,Felvettél egy nyálkataszítót.,Raccolto del repellente allo slime.,スライム はんぱつざい をひろった。,오물 방수제 획득.,Je hebt de slijmafstotende stof opgepakt.,Plukket opp slime repellent.,Zebrano odstraszacz szlamu.,Pegou repelente de gosma.,Apanhaste repelente de gosma.,Ai ridicat respingătorul de mâzga.,Получен репеллент от слизи.,Покупио си одбијаш љигавца.,Balçık kovucu aldım. -Supercharge Breakfast!,GOTBREAKFAST,,,,Supervýživná snídaně!,Supercharge Morgenmad!,Überladenes Frühstück!,,Ŝargega Matenmanĝon!,¡Desayuno supercargado!,,Superaamiaislatinki!,Petit-déjeuner superchargé!,Szupertöltött Reggeli!,Colazione da supercarica!,ちょうしょく スーパーチャージ!,힘찬 아침식사 섭취!,Overbelast ontbijt!,Superladet frokost!,Supernaładowane Śniadanie!,Super Café da Manhã!,Super Pequeno-Almoço!,Superîncărcătură Mic Dejun!,Завтрак из сверхзаряда!,Супер-напуњен доручак.,Süper Şarjlı Kahvaltı! -Picked up a blue key.,GOTCBLUEKEY,,,,Sebrán modrý klíč.,Samlede en blå nøgle op.,Du hast einen blauen Schlüssel genommen.,,Prenis bluan ŝlosilon.,Recogiste una llave azul.,,Poimit sinisen avaimen.,Vous avez pris une clé bleue.,Felvettél egy kék kulcsot.,Raccolta una chiave blu.,あお のかぎ をひろった。,파란색 열쇠 획득.,Je hebt een blauwe sleutel opgepakt.,Plukket opp en blå nøkkel.,Zebrano niebieski klucz.,Pegou a chave azul.,Apanhaste a chave azul.,Ai ridicat o cheie albastră.,Получен синий ключ.,Покупио си плави кључ.,Mavi bir anahtar aldı. -Picked up a yellow key.,GOTCYELLOWKEY,,,,Sebrán žlutý klíč.,Samlede en gul nøgle op.,Du hast einen gelben Schlüssel genommen.,,Prenis ruĝan ŝlosilon.,Recogiste una llave amarilla.,,Poimit keltaisen avaimen.,Vous avez pris une clé jaune.,Felvettél egy sárga kulcsot.,Raccolta una chiave gialla.,きいろ のかぎ をひろった。,노란색 열쇠 획득.,Je hebt een gele sleutel opgepakt.,Plukket opp en gul nøkkel.,Zebrano żółty klucz.,Pegou a chave amarela.,Apanhaste a chave amarela.,Ai ridicat o cheie galbenă.,Получен жёлтый ключ.,Покупио си жути кључ.,Sarı bir anahtar aldı. -Picked up a red key.,GOTCREDKEY,,,,Sebrán červený klíč.,Samlede en rød nøgle op.,Du hast einen roten Schlüssel genommen.,,Prenis flavan ŝlosilon.,Recogiste una llave roja.,,Poimit punaisen avaimen.,Vous avez pris une clé rouge.,Felvettél egy piros kulcsot.,Raccolta una chiave rossa.,あか のかぎ をひろった。,빨간색 열쇠 획득.,Je hebt een rode sleutel opgepakt.,Plukket opp en rød nøkkel.,Zebrano czerwony klucz.,Pegou a chave vermelha.,Apanhaste a chave vermelha.,Ai ridicat o cheie roșie.,Получен красный ключ.,Покупио си црвени кључ.,Kırmızı bir anahtar aldı. -Picked up a bowl of fruit.,GOTFRUIT,,,,Sebrána mísa s ovocem.,Samlede en skål med frugt op.,Du hast eine Obstschale genommen.,,Prenis bovlon de fruktoj.,Recogiste un tazón de fruta.,,Poimit hedelmäkulhon.,Vous avez pris un bol de fruits.,Felvettél egy tál gyümölcsöt.,Raccolto un vassoio di frutta.,フルーツのボウル をひろった。,과일 한 그릇 섭취.,Je hebt een fruitschaal opgepakt.,Plukket opp en bolle med frukt.,Zebrano miskę owoców.,Pegou uma tigela de frutas.,Apanhaste uma taça com fruta.,Ai ridicat un bol de fructe.,Получена тарелка с фруктами.,Покупио си чинију воћа.,Bir kase meyve al. -Vegetables are REALLY good for you!,GOTVEGETABLESNEED,,,,Zelenina je VELMI zdravá!,Grøntsager er VIRKELIG gode for dig!,Gemüse ist RICHTIG gut für dich!,,Legomoj estas TRE bonaj por vi!,¡Las verduras son REALMENTE buenas para ti!,,Vihannekset ovat TOSI terveellisiä!,Les légumes sont VRAIMENT bons pour vous!,A zöldségek NAGYON jót tesznek neked!,La verdura ti fa DAVVERO bene!,いま とってもひつような やさいのボウルだ!,채소의 건강한 영양분이 독 기운을 없앴습니다!,Groenten zijn echt goed voor je!,Grønnsaker er VIRKELIG bra for deg!,Warzywa są BARDZO dobre dla ciebie!,Vegetais fazem MUITO bem para você!,Os Vegetais são MUITO bons para ti!,Legumele sunt FOARTE bune pentru tine!,Овощи ОЧЕНЬ полезны для здоровья!,Поврће је ЈАКО добро за тебе!,Sebzeler sizin için GERÇEKTEN iyidir! -Picked up a bowl of vegetables.,GOTVEGETABLES,,,,Sebrána mísa se zeleninou.,Samlede en skål med grøntsager op.,Du hast eine Gemüseschale genommen.,,Prenis bovlon de legomoj.,Recogiste un tazón de verduras.,,Poimit vihannesvadin.,Vous avez pris un bol de légumes.,Felvettél egy tál zöldséget.,Raccolto un vassoio di verdura.,やさいのボウル をひろった。,채소 한 그릇 섭취.,Je hebt een kom groenten opgepakt.,Plukket opp en bolle med grønnsaker.,Zebrano miskę warzyw.,Pegou uma tigela de vegetais.,Apanhaste uma tigela com vegetais.,Ai ridicat un bol de legume.,Получена тарелка с овощами.,Покупио си чинију поврћа.,Bir kase sebze aldı. -Found a Slime-Proof Suit,GOTSLIMESUIT,,,,Nalezen slizu odolný oblek.,Fandt et slim-sikret jakkesæt,Du hast einen Schleimbeständigen Anzug gefunden,,Trovis mukimunan kompleton.,Encontraste un traje a prueba de baba.,,Löysit limaapitävän puvun,Combinaison pare-gelée,Felvettél egy nyálkaálló védőruhát,Raccolto un vestito a prova di slime,たい スライム スーツ をてにいれた。,오물 보호복 사용.,Je hebt een slijtvast pak opgepakt.,Fant en slimsikker drakt,Znaleziono Szlamoodporny Kombinezon,Achou um Traje Anti-Gosma,Apanhaste um Fato Anti-Gosma.,Ai ridicat un Costum Rezistent la Mâzgă,Получен противослизневый костюм,Нашо си љигаво-отпорано одело.,Balçık Geçirmez Takım Elbise Buldum -Found a Computer Area Map,GOTCHEXMAP,,,,Nalezena počítačová mapa oblasti.,Fandt et kort over et computerområde,Du hast eine Computerkarte gefunden,,Trovis komputilan regionmapon.,Encontraste un mapa computarizado del área.,,Löysit alueen tietokonekartan,Vous avez trouve une carte informatique de la zone.,Felvettél egy Számítógépes Térképet,Trovata una mappa computerizzata,コンピューターエリアマップ をてにいれた。,컴퓨터 지도 사용.,Je hebt een computerkaart opgepakt.,Fant et datamaskinkart,Znaleziono Komputerową Mapę Obszaru,Achou um Mapa Computadorizado,Apanhaste um Mapa Digital.,Ai ridicat o Hartă Generată pe Calculator a Zonei.,Получена компьютерная карта местности,Нашао компјутерку мапу окружења,Bilgisayar Alanı Haritası Bulundu -Picked up a mini zorch recharge.,GOTZORCHRECHARGE,,,,Sebrán minibzukový náboj.,Samlede en mini zorch-opladning op.,Du hast eine Minizorcher-Ladung genommen.,,Prenis zorĉreŝargeton.,Recogiste una recarga de mini zorch.,,Poimit minizorchlatauksen.,Vous avez pris une mini recharge zorch.,Felvettél egy Mini Zorker Újratöltőt,Raccolta una ricarica di mini zorch.,ミニゾーチ リチャージ をひろった。,소형 저치 전지 획득.,Je hebt een minizorcherlading opgepakt.,Plukket opp en mini zorch-opplading.,Zebrano mini ładunek zorch.,Pegou recarga para mini zorch.,Apanhaste uma recarga para o mini zorch.,Ai ridicat o mini încărcătură pentru zorch.,Получена зарядка для мини-Зорчера.,Покупио си мини зорч пуњач.,Mini bir Zorch şarjı aldım. -Picked up a mini zorch pack.,GOTMINIZORCHPACK,,,,Sebrán minibzukový balík.,Afhentede en mini zorch-pakke.,Du hast ein Minizorcher-Ladepaket genommen.,,Prenis zorĉpaketon,Recogiste un paquete de mini zorch.,,Poimit minizorchpaketin.,Vous avez pris un pack de mini recharges zorch.,Felvettél egy Mini Zorker Csomagot,Raccolta una scatola di mini zorch.,ミニゾーチ パック をひろった。,저치 전지 박스 획득.,Je hebt een pakket met minizorcherladingen opgepakt.,Plukket opp en mini zorch-pakke.,Zebrano mini paczkę zorch.,Pegou um pacote de recargas de mini zorch.,Apanhaste um pagcote de recargas para o mini zorch.,Ai ridicat un mini patchet de încărcătură pentru zorch.,Получена батарея для мини-Зорчера.,Покупио си мини зорч пакет.,Mini bir Zorch paketi aldım. -Picked up a zorch propulsor recharge.,GOTPROPULSORRECHARGE,,,,Sebrán náboj pro bzukový propulzor.,Afhentede en zorch propulsor opladning.,Du hast eine Propeller-Ladung genommen.,,Prenis zorĉpropulsilo-reŝargon.,Recogiste una recarga de propulsor de zorch.,,Poimit zorchtyöntimen latauksen.,Vous avez pris une recharge propulseur zorch.,Felvettél egy Zork Elhárító Újratöltőt,Raccolta una ricarica di zorch a propulsione.,ゾーチプロパルサーリチャージ をひろった。,저치 추진료 획득.,Je hebt een propulsorlading opgepakt.,Plukket opp en zorch propulsor-opplading.,Zebrano ładunek do pędnika zorch.,Pegou recarga para propulsor de zorch.,Apanhaste recarga para o propulsor de zorch.,Ai ridicat o încărcătură pentru acceleratorul zorch.,Получена зарядка для ускорителя Зорча.,Покупио си зорч погонски пуњач.,Bir Zorch itici şarjı aldı. -Picked up a zorch propulsor pack.,GOTPROPULSORPACK,,,,Sebrán balík pro bzukový propulzor.,Afhentede en zorch propulsorpakke.,Du hast ein Propeller-Ladepaket genommen.,,Prenis zorĉpropulsilo-pakon.,Recogiste un paquete de propulsor de zorch.,,Poimit zorchtyöntimen paketin.,Vous avez pris un paquet propulseur zorch.,Felvettél egy Zork Elhárító Csomagot,Raccolta una scatola di zorch a propulsione.,ゾーチプロパルサーパック をひろった。,저치 추진 팩 획득.,Je hebt een pakket met propulsorladingen opgepakt.,Plukket opp en zorch fremdriftspakke.,Zebrano paczkę pędnika zorch.,Pegou um pacote de recargas para propulsor de zorch.,Apanhaste um pacote de recargas para o propulsor de zorch,Ai ridicat un pachet de baterii pentru acceleratorul zorch.,Получена батарея для ускорителя Зорча.,Покупио си зорч погонски пакет.,Bir Zorch itici paketi aldı. -Picked up a phasing zorcher recharge,GOTPHASINGZORCHERRECHARGE,,,,Sebrán náboj pro fázovací bzukr.,Afhentede en zorcher-opladning til faseopladning.,Du hast eine Phasenzorcher-Ladung genommen.,,Prenis fluktuantzorĉilo-reŝargon.,Recogiste una recarga de zorch de fase.,,Poimit vaiheiszorcherin latauksen.,Vous avez pris une recharge zorch phasée.,Felvettél egy Fázis Zorker Újratöltőt,Raccolta una ricarica per zorcher a phasing,フェイシング ゾーチャーリチャージ をひろった。,저치 전자 충전기 획득.,Je hebt een phasenzorcherlading opgepakt.,Plukket opp en fasing zorcher oppladning.,Zebrano ładunek do fazowego zorchera.,Pegou recarga para zorcher fásico.,Apanhaste recarga para o zorcher fásico,Ai ridicat o încărcătură fazată pentru zorcher,Получена зарядка для фазерного Зорчера.,Покупио си фазни зорчер пуњач.,Bir faz zorcher şarjı aldı +Activaste la alarma.",Sinä kuolet! Laukaisit hälytyksen.,Vous êtes mort! Vous avez activé l'alarme!,Beindult a riasztó. Halott vagy!,Sei morto! L'allarme è scattato.,絶望的だ! 警報を鳴らしてしまった。,알람이 작동되었다. 넌 죽었어!,Je bent dood! Je hebt het alarm laten afgaan.,Du er død! Du utløste alarmen.,Już nie żyjesz! Włączył@[irreg_3_pl] alarm!,Você está mort@[ao_ptb]! Você ativou o alarme.,Estás mort@[ao_ptb]! Ativaste o alarme.,Ești mort! AI declanșat alarma!,Ты поднял тревогу! Готовься к смерти!,Активирао си аларм. Спреми се да умреш!,Du är död! Du utlöste larmet.,Sen öldün! Alarmı çalıştırdın. +You seem to have enough!,TXT_HAVEENOUGH,,,,Ty už máš přece dost!,Du ser ud til at have nok!,Du scheinst genug zu haben.,,Vi ŝajnas havi sufiĉe!,¡Se ve que tienes suficiente!,,Sinulla näyttää olevan tarpeeksi!,Vous avez l'air d'en avoir assez!,Úgy néz ki eleged van már!,Sembri averne abbastanza!,十分に持ち合わせている!,충분히 가진 것 같은데?,Je lijkt genoeg te hebben!,Du har visst fått nok!,"Wydaje się, że już ci wystarczy!",Você parece ter o suficiente!,Pareces ter o suficiente!,Pare că ai destule!,"Кажется, тебе хватит!",Изгледа да ти је доста!,Du verkar ha fått nog!,Yeterince var gibi görünüyor! +Go away!,TXT_GOAWAY,,,,Jdi pryč!,Gå væk!,Verschwinde!,,Foriru!,¡Lárgate!,,Häivy!,Allez-vous en!,Takarodj!,Vattene via!,逃げ出せ!,저리 가!,Ga weg!,Forsvinn!,Idź stąd!,Vá embora!,Vai-te embora!,Pleacă!,Уходи!,Одлази!,Gå härifrån!,Git başımdan! +Incoming Message...,TXT_COMM0,,,,Příchozí zpráva...,Indkommende besked...,Nachricht erhalten...,,Alvenas mesaĝo...,Mensaje entrante...,,Vastaantuleva viesti...,Message reçu.,Bejövő Üzenet...,Messaggio in arrivo...,メッセージが届いた...,메시지가 옴...,Inkomend bericht....,Innkommende melding...,Nadchodzi wiadomość...,Recebendo Mensagem...,A Receber Mensagem...,Mesaj în intrare...,Входящее сообщение...,Наилази порука...,Inkommande meddelande...,Gelen Mesaj... +Incoming Message from BlackBird...,TXT_COMM1,,,,Příchozí zpráva od Straky...,Indkommende besked fra BlackBird...,Nachricht von Blackbird erhalten...,,Alvenas mesaĝo de BlackBird...,Mensaje entrante de BlackBird...,,Vastaantuleva viesti Blackbirdiltä...,Message reçu de BlackBird,Bejövő Üzenet Feketerigótól...,Messaggio in arrivo da Blackbird...,ブラックバードからのメッセージが届いた...,블랙버드로부터 메시지가 옴...,Inkomend bericht van BlackBird....,Innkommende melding fra BlackBird...,Nadchodzi wiadomość od BlackBird...,Recebendo Mensagem de BlackBird...,A Receber Mensagem de BlackBird...,Mesaj în intrare de la BlackBird...,Входящее сообщение от «Чёрного дрозда»...,Наилази порука од Црне птице....,Inkommande meddelande från BlackBird...,Gelen Mesaj... +Find help,TXT_FINDHELP,,,,Najdi pomoc.,Find hjælp,Finde Hilfe,,Trovu helpon,Busca ayuda,,Etsi apua,Trouvez de L'aide,Keress segítséget,Trova aiuto,助けを探せ,도움말,Zoek hulp,Finn hjelp,Znajdź pomoc,Procure ajuda,Procura ajuda,Găsește ajutor,Найди помощь,Нађи помоћ,Hitta hjälp,Yardım bul +for %u,TXT_TRADE,As in for %u amount of money.,,,za %u zlatých,til %u,für %u,,kontraŭ %u da oro.,por %u de oro.,,hintaan %u,pour %u,%u számára,per %u,%u ゴールド,(가격: %u),voor %u,til %u,za %u,por %u,,pentru %u,за %u,за %u,för %u,için %u +,,Chex Quest,,,,,,,,,,,,,,,,,,,,,,,,, +,,Pickups,,,,,,,,,,,,,,,,,,,,,,,,, +Picked up the Chex(R) Armor.,GOTCHEXARMOR,,,Picked up the Chex(R) Armour.,Sebráno Chex(R) brnění.,Hentede Chex(R) Rustning.,Du hast die Chex(R) Rüstung genommen,,Prenis la Chex(R)-kirason.,Recogiste la Armadura Chex(R).,,Poimit Chex(R)-panssarin.,Vous avez pris l'armure Chex(R).,Felvettél egy Chex(R) páncélt.,Raccolta un'Armatura Chex(R).,チェックス(R)アーマー をてにいれた。,첵스(R) 갑옷 획득.,Je hebt het Chex(R) harnas opgepakt.,Plukket opp Chex(R) Armor.,Zebrano Pancerz Chex(R).,Pegou uma Armadura Chex(R).,Apanhaste uma Armadura Chex(R).,Ai ridicat Armura Chex(R).,Получена Chex(R)-броня.,Покупио си Чех оклоп.,Plockade upp Chex(R) rustningen.,Chex(R) Zırhı'nı aldım. +Picked up the Super Chex(R) Armor!,GOTSUPERCHEXARMOR,,,Picked up the Super Chex(R) Armour!,Sebráno Super Chex(R) brnění!,Hentede Super Chex(R) Rustning!,Du hast die Superchex(R)Rüstung genommen!,,Prenis la superan Chex(R)-kirason!,¡Recogiste la Súper-Armadura Chex(R)!,,Poimit Super-Chex(R)-panssarin!,Vous avez pris la super armure Chex(R)!,Felvettél egy szuper Chex(R) páncélt!,Raccolta la Super Armatura Chex(R)!,スーパーチェックス(R)アーマー をてにいれた。,슈퍼 첵스(R) 갑옷 획득!,Je hebt het Super-Chex(R) harnas opgehaald!,Plukket opp Super Chex(R) Armor!,Zebrano Super Pancerz Chex(R)!,Pegou uma Super Armadura Chex(R)!,Apanhaste uma Super Armadura Chex(R)!,Ai ridicat Super Armura Chex(R)!,Получена Chex(R)-сверхброня!,Покупио си Супер Чех оклоп.,Plockade upp Super Chex(R) rustningen!,Süper Chex(R) Zırhı'nı aldı! +Picked up a glass of water.,GOTWATER,,,,Sebrána sklenice vody.,Samlede et glas vand op.,Du hast ein Glas Wasser genommen.,,Prenis glason de akvo.,Recogiste un vaso de agua.,,Poimit vesilasin.,Vous avez pris un verre d'eau.,Felvettél egy pohár vizet.,Raccolto un bicchiere d'acqua.,コップいっぱいの みずをひろった。,물 한 컵 섭취.,Je hebt een glas water opgepakt.,Hentet et glass vann.,Zebrano szklankę wody.,Pegou um copo d'água.,Apanhaste um copo de água.,Ai ridicat un pahar cu apă.,Получен стакан воды.,Покупио си чашу воде,Plockade upp ett glas vatten.,Bir bardak su aldım. +Picked up slime repellent.,GOTREPELLENT,,,,Sebrán repelent proti slizu.,Hentede slimafvisende middel.,Du hast das Schleimabwehrmittel genommen.,,Prenis mukforigilon.,Recogiste un repelente de baba.,,Poimit limakarkotteen.,Vous avez pris de la chaux répulsive.,Felvettél egy nyálkataszítót.,Raccolto del repellente allo slime.,スライム はんぱつざい をひろった。,오물 방수제 획득.,Je hebt de slijmafstotende stof opgepakt.,Plukket opp slime repellent.,Zebrano odstraszacz szlamu.,Pegou repelente de gosma.,Apanhaste repelente de gosma.,Ai ridicat respingătorul de mâzga.,Получен репеллент от слизи.,Покупио си одбијаш љигавца.,Plockade upp ett slemavvisande medel.,Balçık kovucu aldım. +Supercharge Breakfast!,GOTBREAKFAST,,,,Supervýživná snídaně!,Supercharge Morgenmad!,Überladenes Frühstück!,,Ŝargega Matenmanĝon!,¡Desayuno supercargado!,,Superaamiaislatinki!,Petit-déjeuner superchargé!,Szupertöltött Reggeli!,Colazione da supercarica!,ちょうしょく スーパーチャージ!,힘찬 아침식사 섭취!,Overbelast ontbijt!,Superladet frokost!,Supernaładowane Śniadanie!,Super Café da Manhã!,Super Pequeno-Almoço!,Superîncărcătură Mic Dejun!,Завтрак из сверхзаряда!,Супер-напуњен доручак.,Supercharge frukost!,Süper Şarjlı Kahvaltı! +Picked up a blue key.,GOTCBLUEKEY,,,,Sebrán modrý klíč.,Samlede en blå nøgle op.,Du hast einen blauen Schlüssel genommen.,,Prenis bluan ŝlosilon.,Recogiste una llave azul.,,Poimit sinisen avaimen.,Vous avez pris une clé bleue.,Felvettél egy kék kulcsot.,Raccolta una chiave blu.,あお のかぎ をひろった。,파란색 열쇠 획득.,Je hebt een blauwe sleutel opgepakt.,Plukket opp en blå nøkkel.,Zebrano niebieski klucz.,Pegou a chave azul.,Apanhaste a chave azul.,Ai ridicat o cheie albastră.,Получен синий ключ.,Покупио си плави кључ.,Plockade upp en blå nyckel.,Mavi bir anahtar aldı. +Picked up a yellow key.,GOTCYELLOWKEY,,,,Sebrán žlutý klíč.,Samlede en gul nøgle op.,Du hast einen gelben Schlüssel genommen.,,Prenis ruĝan ŝlosilon.,Recogiste una llave amarilla.,,Poimit keltaisen avaimen.,Vous avez pris une clé jaune.,Felvettél egy sárga kulcsot.,Raccolta una chiave gialla.,きいろ のかぎ をひろった。,노란색 열쇠 획득.,Je hebt een gele sleutel opgepakt.,Plukket opp en gul nøkkel.,Zebrano żółty klucz.,Pegou a chave amarela.,Apanhaste a chave amarela.,Ai ridicat o cheie galbenă.,Получен жёлтый ключ.,Покупио си жути кључ.,Plockade upp en gul nyckel.,Sarı bir anahtar aldı. +Picked up a red key.,GOTCREDKEY,,,,Sebrán červený klíč.,Samlede en rød nøgle op.,Du hast einen roten Schlüssel genommen.,,Prenis flavan ŝlosilon.,Recogiste una llave roja.,,Poimit punaisen avaimen.,Vous avez pris une clé rouge.,Felvettél egy piros kulcsot.,Raccolta una chiave rossa.,あか のかぎ をひろった。,빨간색 열쇠 획득.,Je hebt een rode sleutel opgepakt.,Plukket opp en rød nøkkel.,Zebrano czerwony klucz.,Pegou a chave vermelha.,Apanhaste a chave vermelha.,Ai ridicat o cheie roșie.,Получен красный ключ.,Покупио си црвени кључ.,Plockade upp en röd nyckel.,Kırmızı bir anahtar aldı. +Picked up a bowl of fruit.,GOTFRUIT,,,,Sebrána mísa s ovocem.,Samlede en skål med frugt op.,Du hast eine Obstschale genommen.,,Prenis bovlon de fruktoj.,Recogiste un tazón de fruta.,,Poimit hedelmäkulhon.,Vous avez pris un bol de fruits.,Felvettél egy tál gyümölcsöt.,Raccolto un vassoio di frutta.,フルーツのボウル をひろった。,과일 한 그릇 섭취.,Je hebt een fruitschaal opgepakt.,Plukket opp en bolle med frukt.,Zebrano miskę owoców.,Pegou uma tigela de frutas.,Apanhaste uma taça com fruta.,Ai ridicat un bol de fructe.,Получена тарелка с фруктами.,Покупио си чинију воћа.,Plockade upp en skål med frukt.,Bir kase meyve al. +Vegetables are REALLY good for you!,GOTVEGETABLESNEED,,,,Zelenina je VELMI zdravá!,Grøntsager er VIRKELIG gode for dig!,Gemüse ist RICHTIG gut für dich!,,Legomoj estas TRE bonaj por vi!,¡Las verduras son REALMENTE buenas para ti!,,Vihannekset ovat TOSI terveellisiä!,Les légumes sont VRAIMENT bons pour vous!,A zöldségek NAGYON jót tesznek neked!,La verdura ti fa DAVVERO bene!,いま とってもひつような やさいのボウルだ!,채소의 건강한 영양분이 독 기운을 없앴습니다!,Groenten zijn echt goed voor je!,Grønnsaker er VIRKELIG bra for deg!,Warzywa są BARDZO dobre dla ciebie!,Vegetais fazem MUITO bem para você!,Os Vegetais são MUITO bons para ti!,Legumele sunt FOARTE bune pentru tine!,Овощи ОЧЕНЬ полезны для здоровья!,Поврће је ЈАКО добро за тебе!,Grönsaker är VÄLDIGT bra för dig!,Sebzeler sizin için GERÇEKTEN iyidir! +Picked up a bowl of vegetables.,GOTVEGETABLES,,,,Sebrána mísa se zeleninou.,Samlede en skål med grøntsager op.,Du hast eine Gemüseschale genommen.,,Prenis bovlon de legomoj.,Recogiste un tazón de verduras.,,Poimit vihannesvadin.,Vous avez pris un bol de légumes.,Felvettél egy tál zöldséget.,Raccolto un vassoio di verdura.,やさいのボウル をひろった。,채소 한 그릇 섭취.,Je hebt een kom groenten opgepakt.,Plukket opp en bolle med grønnsaker.,Zebrano miskę warzyw.,Pegou uma tigela de vegetais.,Apanhaste uma tigela com vegetais.,Ai ridicat un bol de legume.,Получена тарелка с овощами.,Покупио си чинију поврћа.,Plockade upp en skål med grönsaker.,Bir kase sebze aldı. +Found a Slime-Proof Suit,GOTSLIMESUIT,,,,Nalezen slizu odolný oblek.,Fandt et slim-sikret jakkesæt,Du hast einen Schleimbeständigen Anzug gefunden,,Trovis mukimunan kompleton.,Encontraste un traje a prueba de baba.,,Löysit limaapitävän puvun,Combinaison pare-gelée,Felvettél egy nyálkaálló védőruhát,Raccolto un vestito a prova di slime,たい スライム スーツ をてにいれた。,오물 보호복 사용.,Je hebt een slijtvast pak opgepakt.,Fant en slimsikker drakt,Znaleziono Szlamoodporny Kombinezon,Achou um Traje Anti-Gosma,Apanhaste um Fato Anti-Gosma.,Ai ridicat un Costum Rezistent la Mâzgă,Получен противослизневый костюм,Нашо си љигаво-отпорано одело.,Hittade en slimsäker kostym,Balçık Geçirmez Takım Elbise Buldum +Found a Computer Area Map,GOTCHEXMAP,,,,Nalezena počítačová mapa oblasti.,Fandt et kort over et computerområde,Du hast eine Computerkarte gefunden,,Trovis komputilan regionmapon.,Encontraste un mapa computarizado del área.,,Löysit alueen tietokonekartan,Vous avez trouve une carte informatique de la zone.,Felvettél egy Számítógépes Térképet,Trovata una mappa computerizzata,コンピューターエリアマップ をてにいれた。,컴퓨터 지도 사용.,Je hebt een computerkaart opgepakt.,Fant et datamaskinkart,Znaleziono Komputerową Mapę Obszaru,Achou um Mapa Computadorizado,Apanhaste um Mapa Digital.,Ai ridicat o Hartă Generată pe Calculator a Zonei.,Получена компьютерная карта местности,Нашао компјутерку мапу окружења,Hittade en karta över datorområdet,Bilgisayar Alanı Haritası Bulundu +Picked up a mini zorch recharge.,GOTZORCHRECHARGE,,,,Sebrán minibzukový náboj.,Samlede en mini zorch-opladning op.,Du hast eine Minizorcher-Ladung genommen.,,Prenis zorĉreŝargeton.,Recogiste una recarga de mini zorch.,,Poimit minizorchlatauksen.,Vous avez pris une mini recharge zorch.,Felvettél egy Mini Zorker Újratöltőt,Raccolta una ricarica di mini zorch.,ミニゾーチ リチャージ をひろった。,소형 저치 전지 획득.,Je hebt een minizorcherlading opgepakt.,Plukket opp en mini zorch-opplading.,Zebrano mini ładunek zorch.,Pegou recarga para mini zorch.,Apanhaste uma recarga para o mini zorch.,Ai ridicat o mini încărcătură pentru zorch.,Получена зарядка мини-зорчера.,Покупио си мини зорч пуњач.,Plockade upp en mini zorch-uppladdning.,Mini bir Zorch şarjı aldım. +Picked up a mini zorch pack.,GOTMINIZORCHPACK,,,,Sebrán minibzukový balík.,Afhentede en mini zorch-pakke.,Du hast ein Minizorcher-Ladepaket genommen.,,Prenis zorĉpaketon,Recogiste un paquete de mini zorch.,,Poimit minizorchpaketin.,Vous avez pris un pack de mini recharges zorch.,Felvettél egy Mini Zorker Csomagot,Raccolta una scatola di mini zorch.,ミニゾーチ パック をひろった。,저치 전지 박스 획득.,Je hebt een pakket met minizorcherladingen opgepakt.,Plukket opp en mini zorch-pakke.,Zebrano mini paczkę zorch.,Pegou um pacote de recargas de mini zorch.,Apanhaste um pagcote de recargas para o mini zorch.,Ai ridicat un mini patchet de încărcătură pentru zorch.,Получена батарея мини-зорчера.,Покупио си мини зорч пакет.,Plockade upp en mini zorch pack.,Mini bir Zorch paketi aldım. +Picked up a zorch propulsor recharge.,GOTPROPULSORRECHARGE,,,,Sebrán náboj pro bzukový propulzor.,Afhentede en zorch propulsor opladning.,Du hast eine Propeller-Ladung genommen.,,Prenis zorĉpropulsilo-reŝargon.,Recogiste una recarga de propulsor de zorch.,,Poimit zorchtyöntimen latauksen.,Vous avez pris une recharge propulseur zorch.,Felvettél egy Zork Elhárító Újratöltőt,Raccolta una ricarica di zorch a propulsione.,ゾーチプロパルサーリチャージ をひろった。,저치 추진료 획득.,Je hebt een propulsorlading opgepakt.,Plukket opp en zorch propulsor-opplading.,Zebrano ładunek do pędnika zorch.,Pegou recarga para propulsor de zorch.,Apanhaste recarga para o propulsor de zorch.,Ai ridicat o încărcătură pentru acceleratorul zorch.,Получена зарядка ускорителя зорча.,Покупио си зорч погонски пуњач.,Plockade upp en zorch propulsoruppladdning.,Bir Zorch itici şarjı aldı. +Picked up a zorch propulsor pack.,GOTPROPULSORPACK,,,,Sebrán balík pro bzukový propulzor.,Afhentede en zorch propulsorpakke.,Du hast ein Propeller-Ladepaket genommen.,,Prenis zorĉpropulsilo-pakon.,Recogiste un paquete de propulsor de zorch.,,Poimit zorchtyöntimen paketin.,Vous avez pris un paquet propulseur zorch.,Felvettél egy Zork Elhárító Csomagot,Raccolta una scatola di zorch a propulsione.,ゾーチプロパルサーパック をひろった。,저치 추진 팩 획득.,Je hebt een pakket met propulsorladingen opgepakt.,Plukket opp en zorch fremdriftspakke.,Zebrano paczkę pędnika zorch.,Pegou um pacote de recargas para propulsor de zorch.,Apanhaste um pacote de recargas para o propulsor de zorch,Ai ridicat un pachet de baterii pentru acceleratorul zorch.,Получена батарея ускорителя зорча.,Покупио си зорч погонски пакет.,Plockade upp en zorch propulsor pack.,Bir Zorch itici paketi aldı. +Picked up a phasing zorcher recharge,GOTPHASINGZORCHERRECHARGE,,,,Sebrán náboj pro fázovací bzukr.,Afhentede en zorcher-opladning til faseopladning.,Du hast eine Phasenzorcher-Ladung genommen.,,Prenis fluktuantzorĉilo-reŝargon.,Recogiste una recarga de zorch de fase.,,Poimit vaiheiszorcherin latauksen.,Vous avez pris une recharge zorch phasée.,Felvettél egy Fázis Zorker Újratöltőt,Raccolta una ricarica per zorcher a phasing,フェイシング ゾーチャーリチャージ をひろった。,저치 전자 충전기 획득.,Je hebt een phasenzorcherlading opgepakt.,Plukket opp en fasing zorcher oppladning.,Zebrano ładunek do fazowego zorchera.,Pegou recarga para zorcher fásico.,Apanhaste recarga para o zorcher fásico,Ai ridicat o încărcătură fazată pentru zorcher,Получена зарядка фазерного зорчера.,Покупио си фазни зорчер пуњач.,Plockade upp en phasing zorcher-uppladdning.,Bir faz zorcher şarjı aldı Picked up a phasing zorcher pack.,GOTPHASINGZORCHERPACK,,,,Sebrán balík pro fázovací bzukr.,Afhentede en phasing zorcher-pakke.,Du hast ein Phasenzorcher-Ladepaket genommen.,,Prenis fluktuantzorĉilo-pakon.,Recogiste un paquete de zorch de fase.,,Poimit vaiheiszorcherin paketin.,Vous avez pris un pack de recharges zorch phasée.,Felvettél egy Fázis Zorker Csomagot,Raccolta una scatola per zorcher a phasing.,フェイシング ゾーチャーパック をひろった。,특대 저치 충전기 획득.,Je hebt een pakket met phasenzorcherladingen opgepakt.,Plukket opp en fasing zorcher-pakke.,Zebrano paczkę fazowego zorchera.,Pegou um pacote de recargas para zorcher fásico.,Apanhaste um pacote de recargas para o zorcher fásico,"Ai ridicat un pachet de încărcături fazate pentru -zorcher.",Получена батарея для фазерного Зорчера.,Покупио си фазни зорчер пакет.,Bir faz zorcher paketi aldım. -Picked up a large zorcher recharge.,GOTLARGEZORCHERRECHARGE,,,,Sebrán náboj pro velký bzukr.,Afhentede en stor zorcher-opladning.,Du hast eine Zorcher-Ladung genommen.,,Prenis grandzorĉilo-reŝargon.,Recogiste una gran recarga de zorch.,,Poimit ison zorcherin latauksen,Vous avez pris une recharge pour zorcheur large.,Felvettél egy Nagy Zorker Újratöltőt,Raccolta una ricarica per zorcher grande.,ラージ ゾーチャーリチャージ をひろった。,대형 저치 카트리지 획득.,Je hebt een zorcherlading opgepakt.,Plukket opp en stor zorcher-opplading.,Zebrano ładunek do dużego zorchera.,Pegou recarga para zorcher grande.,Apanhaste recarga para o zorcher grande.,Ai ridicat o încărcătură mare pentru zorcher.,Получена зарядка для большого Зорчера.,Покупио си велики зорчер пуњач.,Büyük bir zorcher şarjı aldım. -Picked up a large zorcher pack.,GOTLARGEZORCHERPACK,,,,Sebrán balík pro velký bzukr.,Afhentede en stor zorcher-pakke.,Du hast ein Zorcher-Ladepaket genommen.,,Prenis grandegzorĉilo-reŝargon.,Recogiste un gran paquete de zorch.,,Poimit ison zorcherin paketin.,Vous avez pris un pack de recharges pour zorcheur large.,Felvettél egy Nagy Zorker Csomagot,Raccolta una scatola per zorcher grande.,ラージ ゾーチャーパック をひろった。,저치 카트리지 묶음 획득.,Je hebt een pakket met zorcherladingen opgepakt.,Plukket opp en stor zorcherpakke.,Zebrano paczkę dużego zorchera.,Pegou um pacote de recargas para zorcher grande.,Apanhaste um pacote de recargas para o zocher grande.,Ai ridicat un pachet mare de încărcături pentru zorcher.,Получена батарея для большого Зорчера.,Покупио си велики зорчер пакет.,Büyük bir zorcher paketi aldı. -Picked up a Zorchpak!,GOTZORCHPACK,,,,Sebrán Bzukrbatoh!,Afhentede en Zorchpak!,Du hast ein Zorchpaket genommen.,,Prenis Zorĉpakon!,¡Recogiste un Zorchpak!,,Poimit zorchpakin!,Vous avez pris un zorchpak!,Felvettél egy Zorkpakkot!,Raccolto uno ZorchZaino!,ゾーチパックをてにいれた!,저치 팩 획득!,Je hebt en zorchpak opgepakt.,Plukket opp en Zorchpak!,Zebrano Paczkę Zorch.,Pegou um Zorchpak!,Apanhaste um Zorchpak!,Ai ridicat un Ghiozdan Zorch!,Получен Зорч-рюкзак!,Покупио си зорчпак.,Bir Zorchpak aldım! -You got the LAZ Device! Woot!,GOTLAZDEVICE,,,,Získal@[ao_cs] jsi velkodosahový bzukr! Cooo?,Du fik LAZ-enheden! Woot!,Du hast den Flächenzorcher!,,Vi prenis la LAZ-aparaton! Hura!,¡Tienes el dispositivo LAZ! ¡Yuju!,,Sait SAZ-laitteen! Juhuu!,Vous avez pris l'Outil ZZL! Wahou!,Felvetted a LAZ Készüléket! Wáó!,Hai trovato il dispositivo LAZ! Cavolo!,LAZ デバイスをてにいれた! ワァオ!,LAZ 장치 습득! 완전 짱인걸!,Je hebt het LAZ-apparaat! Woot!,Du har LAZ-enheten! Woot!,Zdobył@[irreg_3_pl] urządzenie LAZ! Juhu!,Você achou o Dispositivo LAZ! Oba!,Apanhaste um Dispositivo LAZ! Fixe!,Ai ridicat un Dispozitiv LAZ! Uraa!,Получено устройство Зорчирования большого радиуса! Ура!,Добио си ЛАЗ уређај. ВУТ!,LAZ cihazını aldın! Woot! -You got the Rapid Zorcher!,GOTRAPIDZORCHER,,,,Získal@[ao_cs] jsi rychlobzukr!,Du fik en Rapid Zorcher!,Du hast den schnellen Zorcher genommen!,,Vi prenis la Rapidzorĉilon!,¡Tienes el Zorcher Rápido!,,Sait pikazorcherin!,Vous avez pris le Zorcheur Rapide!,Felvetted a Gyors Zorkert!,Hai trovato il zorcher rapido!,ラピッドゾーチャー をてにいれた!,속사 자쳐 습득!,Je hebt de snelle Zorcher!,Du har Rapid Zorcher!,Zdobył@[irreg_3_pl] Szybkostrzelny Zorcher!,Você pegou o Zorcher Automático!,Apanhaste o Zorcher Automático!,Ai ridicat un Zorcher cu Foc Rapid!,Получен скорострельный Зорчер!,Добио си рапидан зорчер!,Hızlı Zorcher'ı aldın! -You got the Super Bootspork!,GOTSUPERBOOTSPORK,,,,Získal@[ao_cs] jsi super botovidličku!,Du fik Super Bootspork!,Du hast den Super-Gabelquirl genommen!,,Vi prenis la Superan Ŝargmanĝilaron!,¡Tienes el Súper Cuchador!,,Sait superluhan!,Vous avez pris la Super Fourchette!,Felvetted a Szuper Rotációs Villát!,Hai trovato il super bootspork!,スーパーさきわれスプーン をてにいれた!,부트스포크 습득!,Je hebt de Super Bootspork!,Du har Super Bootspork!,Zdobył@[irreg_3_pl] Super Łyżkowidelec!,Você pegou o Super Garfo!,Apanhaste o Super Garfo-Colher!,Ai ridicat o Super Lingură!,Получена суперложковилка!,Добио си супер чизмо-порк!,Süper Bootspork'u aldın! -You got the Zorch Propulsor!,GOTZORCHPROPULSOR,,,,Získal@[ao_cs] jsi bzukový propulsor!,Du fik Zorch-propulsoren!,Du hast den Propellerzorcher genommen!,,Vi prenis la Zorĉpropulsilon!,¡Tienes el Propulsor de Zorch!,,Sait zorchtyöntimen!,Vous avez pris le Propulseur Zorch!,Felvetted a Zork Elhárítót!,Hai trovato il propulsore zorch!,ロケット ゾーチャー をてにいれた!,저치 추진기 습득!,Je hebt de Zorch Propulsor!,Du fikk Zorch Propulsor!,Zdobył@[irreg_3_pl] Pędnik Zorch!,Você pegou o Propulsor de Zorch!,Apanhaste o Propulsor de Zorch!,Ai ridicat un Accelerator Zorch!,Получен ускоритель Зорча!,Добио си зорч погон!,Zorch Propulsor'u aldın! -You got the Phasing Zorcher!,GOTPHASINGZORCHER,,,,Získal@[ao_cs] jsi fázovací bzukr!,Du fik Phasing Zorcher!,Du hast den Phasenzorcher genommen!,,Vi prenis la Fluktuantzorĉilon!,¡Tienes el Zorcher de Fase!,,Sait vaiheiszorcherin!,Vous avez pris le Zorcheur phasé!,Felvetted a Fázis Zorkert!,Hai trovato il zorcher a phasing!,フェイシング ゾーチャー をてにいれた!,전자 자쳐 습득!,Je hebt de Fasezorcher!,Du har Phasing Zorcher!,Zdobył@[irreg_3_pl] Fazowy Zorcher!,Você pegou o Zorcher Fásico!,Apanhaste o Zorcher Fásico!,Ai ridicat un Zorcher Fazat!,Получен фазерный Зорчер!,Добио си фазни зорчер!,Fazlama Zorcher'ı aldın! -You got the Large Zorcher!,GOTLARGEZORCHER,,,,Získal@[ao_cs] jsi velký bzukr!,Du fik den store Zorcher!,Du hast den großen Zorcher genommen!,,Vi prenis la Grandzorĉilon,¡Tienes el Zorcher Grande!,,Sait ison zorcherin!,Vous avez pris le Zorcheur Large!,Felvetted a Nagy Zorkert!,Hai trovato il zorcher grande!,おおがたゾーチャー をてにいれた!,대형 자쳐 습득!,Je hebt de grote Zorcher!,Du har den store Zorcher!,Zdobył@[irreg_3_pl] Duży Zorcher!,Você pegou o Zorcher Grande!,Apanhaste o Zorcher Grande!,Ai ridicat un Zorcher Mare!,Получен большой Зорчер!,Добио си велики зорчер!,Büyük Zorcher'ı aldınız! -You got the Mega Zorcher!,GOTSUPERLARGEZORCHER,,,,Získal@[ao_cs] jsi megabzukr!,Du fik Mega Zorcher!,Du hast den Megazorcher genommen!,,Vi prenis la Grandegzorĉilon!,¡Tienes el Mega Zorcher!,,Sait megazorcherin!,Vous avez pris le méga Zorcheur!,Felvetted a Mega Zorkert!,Hai trovato il mega zorcher!,ちょうおおがたゾーチャー をてにいれた!,초대형 자쳐 습득!,Je hebt de Megazorcher!,Du har Mega Zorcher!,Zdobył@[irreg_3_pl] Mega Zorcher!,Você pegou o Mega Zorcher!,Apanhaste o Mega Zorcher!,Ai ridicat un Mega Zorcher!,Получен Мегазорчер!,Добио си мега зорчер!,Mega Zorcher'ı aldın! -Picked up a Mini Zorcher.,GOTMINIZORCHER,,,,Sebrán minibzukr.,Du har fået en Mini Zorcher.,Du hast einen Minizorcher genommen.,,Prenis Zorĉileton.,Recogiste un Mini Zorcher,,Poimit minizorcherin.,Vous avez pris le Mini Zorcheur.,Felvettél egy Mini Zorkert.,Raccolto un mini zorcher.,こがたゾーチャー をてにいれた。,소형 자쳐 습득.,Je hebt een minizorcher opgepakt.,Plukket opp en Mini Zorcher.,Zebrano Mini Zorcher.,Você pegou um Mini Zorcher.,Apanhaste um Mini Zorcher.,Ai ridicat un Mini Zorcher.,Получен мини-Зорчер.,Покупио си мини зорчер!,Bir Mini Zorcher aldın. -,,Actor tags,,,,,,,,,,,,,,,,,,,,,,,, -Spoon,TAG_SPOON,,,,Lžíce,Ske,Löffel,,Kulero,Cuchara,,Lusikka,Cuillère à Botte,Kanál,Cucchiaio ,スプーン,숟가락,Lepel,Skje,Łyżka,Colher,,Lingură,Ложка,Кашика,Kaşık -Super Bootspork,TAG_SPORK,,,,Super botodlička,,Supergabel,,Ega Ŝargmanĝilaro,Súper Cuchador,,Superluha,Super Fourchette,Szuper Rotációs Villa,Super Forcucchiaio,スーパーさきわれスプーン,부트스포크,,,Super Łyżkowidelec,Super Garfo,Super Garfo-Colher,Super Lingură,Суперложковилка,Супер виљушка,Süper Bootspork -Mini Zorcher,TAG_MINIZORCHER,,,,Minibzukr,,Minizorcher,,Zorĉileto,Mini Zorcher,,Minizorcheri,Mini Zorcheur,Mini Zorker,Mini Zorcher,こがたゾーチャー,소형 자쳐,Minizorcher,,Mini Zorcher,Mini Zorcher,,Mini Zorcher,Мини-Зорчер,Мини зорчер,Mini Zorcher -Large Zorcher,TAG_LARGEZORCHER,,,,Velký bzukr,Stor Zorcher,Großer Zorcher,,Granda Zorĉilo,Zorcher Grande,,Iso zorcheri,Zorcheur Large,Nagy Zorker,Grosso Zorcher ,おおがたゾーチャー,대형 자쳐,Grote Zorcher,Stor Zorcher,Duży Zorcher,Zorcher Grande,,Zorcher Mare,Большой Зорчер,Велики зорчер,Büyük Zorcher -Super-Large Zorcher,TAG_SUPERLARGEZORCHER,,,,Supervelký bzukr,Super-stor Zorcher,Riesenzorcher,,Grandega Zorĉilo,Zorcher Súper Grande,,Superiso zorcheri,Zorcheur Extra-large,Hatalmas Zorker,Zorcher Enorme ,ちょうおおがたゾーチャー,초대형 자쳐,Super grote Zorcher,Super-stor Zorcher,Większy Zorcher,Super Zorcher Grande,,Zorcher Super-Mare,Мега-Зорчер,Супер-велики зорчер,Süper Büyük Zorcher -Rapid Zorcher,TAG_RAPIDZORCHER,,,,Rychlobzukr,,Schnellzorcher,,Rapida Zorĉilo,Zorcher Rápido,,Pikazorcheri,Zorcheur Rapide,Gyors Zorker,Zorcher Rapido,れんしゃ ゾーチャー,속사 자쳐,Snelle Zorcher,,Szybkostrzelny Zorcher,Zorcher Automático,,Zorcher cu Foc Rapid,Быстрый Зорчер,Рапидни зорчер,Hızlı Zorcher -Zorch Propulsor,TAG_ZORCHPROPULSOR,,,,Bzukový propulzor,,Zorch-Propeller,,Zorĉpropulsilo,Propulsor de Zorch,,Zorchtyönnin,Propulseur de Zorch,Zork Elhárító,Propulsore Zorch,ロケット ゾーチ,저치 추진기,,,Pędnik Zorch,Propulsor de Zorch,,Accelerator Zorch,Ускоритель Зорча,Погонски зорчер,Zorch Propulsor -Phasing Zorcher,TAG_PHASINGZORCHER,,,,Fázovací bzukr,,Phasenzorcher,,Fluktuantzorĉilo,Zorcher de Fase,,Vaiheiszorcheri,Zorcheur à Phase,Fokozatos Zorker,Zorcher di Fase,フェイシング ゾーチャー,전자 자쳐,Fasezorcher,,Fazowy Zorcher,Zorcher Fásico,,Zorcher Fazat,Фазерный Зорчер,Фазни зорчер,Fazlama Zorcher -LAZ Device,TAG_LAZDEVICE,,,,Velkodosahový bzukr,LAZ-enhed,Flächenzorcher,,LAZ-Aparato,Dispositivo LAZ,,SAZ-laite,Zorcheur Zone Large,LAZ Készülék,Dispositivo LAZ,ラージエリアゾーキング デバイス,LAZ 장치,LAZ-aparaat,LAZ-enhet,Urządzenie LAZ,Dispositivo LAZ,,Dispozitiv LAZ,Устройство «ЗБР»,ЛАЗ уређај,LAZ Cihazı +zorcher.",Получена батарея фазерного зорчера.,Покупио си фазни зорчер пакет.,Plockade upp en phasing zorcher pack.,Bir faz zorcher paketi aldım. +Picked up a large zorcher recharge.,GOTLARGEZORCHERRECHARGE,,,,Sebrán náboj pro velký bzukr.,Afhentede en stor zorcher-opladning.,Du hast eine Zorcher-Ladung genommen.,,Prenis grandzorĉilo-reŝargon.,Recogiste una gran recarga de zorch.,,Poimit ison zorcherin latauksen,Vous avez pris une recharge pour zorcheur large.,Felvettél egy Nagy Zorker Újratöltőt,Raccolta una ricarica per zorcher grande.,ラージ ゾーチャーリチャージ をひろった。,대형 저치 카트리지 획득.,Je hebt een zorcherlading opgepakt.,Plukket opp en stor zorcher-opplading.,Zebrano ładunek do dużego zorchera.,Pegou recarga para zorcher grande.,Apanhaste recarga para o zorcher grande.,Ai ridicat o încărcătură mare pentru zorcher.,Получена зарядка большого зорчера.,Покупио си велики зорчер пуњач.,Plockade upp en stor zorcher-uppladdning.,Büyük bir zorcher şarjı aldım. +Picked up a large zorcher pack.,GOTLARGEZORCHERPACK,,,,Sebrán balík pro velký bzukr.,Afhentede en stor zorcher-pakke.,Du hast ein Zorcher-Ladepaket genommen.,,Prenis grandegzorĉilo-reŝargon.,Recogiste un gran paquete de zorch.,,Poimit ison zorcherin paketin.,Vous avez pris un pack de recharges pour zorcheur large.,Felvettél egy Nagy Zorker Csomagot,Raccolta una scatola per zorcher grande.,ラージ ゾーチャーパック をひろった。,저치 카트리지 묶음 획득.,Je hebt een pakket met zorcherladingen opgepakt.,Plukket opp en stor zorcherpakke.,Zebrano paczkę dużego zorchera.,Pegou um pacote de recargas para zorcher grande.,Apanhaste um pacote de recargas para o zocher grande.,Ai ridicat un pachet mare de încărcături pentru zorcher.,Получена батарея большого зорчера.,Покупио си велики зорчер пакет.,Plockade upp ett stort zorcherpaket.,Büyük bir zorcher paketi aldı. +Picked up a Zorchpak!,GOTZORCHPACK,,,,Sebrán Bzukrbatoh!,Afhentede en Zorchpak!,Du hast ein Zorchpaket genommen.,,Prenis Zorĉpakon!,¡Recogiste un Zorchpak!,,Poimit zorchpakin!,Vous avez pris un zorchpak!,Felvettél egy Zorkpakkot!,Raccolto uno ZorchZaino!,ゾーチパックをてにいれた!,저치 팩 획득!,Je hebt en zorchpak opgepakt.,Plukket opp en Zorchpak!,Zebrano Paczkę Zorch.,Pegou um Zorchpak!,Apanhaste um Zorchpak!,Ai ridicat un Ghiozdan Zorch!,Получен зорч-рюкзак!,Покупио си зорчпак.,Jag hämtade en Zorchpak!,Bir Zorchpak aldım! +You got the LAZ Device! Woot!,GOTLAZDEVICE,,,,Získal@[ao_cs] jsi velkodosahový bzukr! Cooo?,Du fik LAZ-enheden! Woot!,Du hast den Flächenzorcher!,,Vi prenis la LAZ-aparaton! Hura!,¡Tienes el dispositivo LAZ! ¡Yuju!,,Sait SAZ-laitteen! Juhuu!,Vous avez pris l'Outil ZZL! Wahou!,Felvetted a LAZ Készüléket! Wáó!,Hai trovato il dispositivo LAZ! Cavolo!,LAZ デバイスをてにいれた! ワァオ!,LAZ 장치 습득! 완전 짱인걸!,Je hebt het LAZ-apparaat! Woot!,Du har LAZ-enheten! Woot!,Zdobył@[irreg_3_pl] urządzenie LAZ! Juhu!,Você achou o Dispositivo LAZ! Oba!,Apanhaste um Dispositivo LAZ! Fixe!,Ai ridicat un Dispozitiv LAZ! Uraa!,Получено устройство зорчирования большого радиуса! Ура!,Добио си ЛАЗ уређај. ВУТ!,Du fick LAZ-enheten! Woot!,LAZ cihazını aldın! Woot! +You got the Rapid Zorcher!,GOTRAPIDZORCHER,,,,Získal@[ao_cs] jsi rychlobzukr!,Du fik en Rapid Zorcher!,Du hast den schnellen Zorcher genommen!,,Vi prenis la Rapidzorĉilon!,¡Tienes el Zorcher Rápido!,,Sait pikazorcherin!,Vous avez pris le Zorcheur Rapide!,Felvetted a Gyors Zorkert!,Hai trovato il zorcher rapido!,ラピッドゾーチャー をてにいれた!,속사 자쳐 습득!,Je hebt de snelle Zorcher!,Du har Rapid Zorcher!,Zdobył@[irreg_3_pl] Szybkostrzelny Zorcher!,Você pegou o Zorcher Automático!,Apanhaste o Zorcher Automático!,Ai ridicat un Zorcher cu Foc Rapid!,Получен скорострельный зорчер!,Добио си рапидан зорчер!,Du fick den snabba Zorcher!,Hızlı Zorcher'ı aldın! +You got the Super Bootspork!,GOTSUPERBOOTSPORK,,,,Získal@[ao_cs] jsi super botovidličku!,Du fik Super Bootspork!,Du hast den Super-Gabelquirl genommen!,,Vi prenis la Superan Ŝargmanĝilaron!,¡Tienes el Súper Cuchador!,,Sait superluhan!,Vous avez pris la Super Fourchette!,Felvetted a Szuper Rotációs Villát!,Hai trovato il super bootspork!,スーパーさきわれスプーン をてにいれた!,부트스포크 습득!,Je hebt de Super Bootspork!,Du har Super Bootspork!,Zdobył@[irreg_3_pl] Super Łyżkowidelec!,Você pegou o Super Garfo!,Apanhaste o Super Garfo-Colher!,Ai ridicat o Super Lingură!,Получена суперложковилка!,Добио си супер чизмо-порк!,Du fick Super Bootspork!,Süper Bootspork'u aldın! +You got the Zorch Propulsor!,GOTZORCHPROPULSOR,,,,Získal@[ao_cs] jsi bzukový propulsor!,Du fik Zorch-propulsoren!,Du hast den Propellerzorcher genommen!,,Vi prenis la Zorĉpropulsilon!,¡Tienes el Propulsor de Zorch!,,Sait zorchtyöntimen!,Vous avez pris le Propulseur Zorch!,Felvetted a Zork Elhárítót!,Hai trovato il propulsore zorch!,ロケット ゾーチャー をてにいれた!,저치 추진기 습득!,Je hebt de Zorch Propulsor!,Du fikk Zorch Propulsor!,Zdobył@[irreg_3_pl] Pędnik Zorch!,Você pegou o Propulsor de Zorch!,Apanhaste o Propulsor de Zorch!,Ai ridicat un Accelerator Zorch!,Получен ускоритель хорча!,Добио си зорч погон!,Du fick Zorch Propulsor!,Zorch Propulsor'u aldın! +You got the Phasing Zorcher!,GOTPHASINGZORCHER,,,,Získal@[ao_cs] jsi fázovací bzukr!,Du fik Phasing Zorcher!,Du hast den Phasenzorcher genommen!,,Vi prenis la Fluktuantzorĉilon!,¡Tienes el Zorcher de Fase!,,Sait vaiheiszorcherin!,Vous avez pris le Zorcheur phasé!,Felvetted a Fázis Zorkert!,Hai trovato il zorcher a phasing!,フェイシング ゾーチャー をてにいれた!,전자 자쳐 습득!,Je hebt de Fasezorcher!,Du har Phasing Zorcher!,Zdobył@[irreg_3_pl] Fazowy Zorcher!,Você pegou o Zorcher Fásico!,Apanhaste o Zorcher Fásico!,Ai ridicat un Zorcher Fazat!,Получен фазерный зорчер!,Добио си фазни зорчер!,Du fick Fasande Zorcher!,Fazlama Zorcher'ı aldın! +You got the Large Zorcher!,GOTLARGEZORCHER,,,,Získal@[ao_cs] jsi velký bzukr!,Du fik den store Zorcher!,Du hast den großen Zorcher genommen!,,Vi prenis la Grandzorĉilon,¡Tienes el Zorcher Grande!,,Sait ison zorcherin!,Vous avez pris le Zorcheur Large!,Felvetted a Nagy Zorkert!,Hai trovato il zorcher grande!,おおがたゾーチャー をてにいれた!,대형 자쳐 습득!,Je hebt de grote Zorcher!,Du har den store Zorcher!,Zdobył@[irreg_3_pl] Duży Zorcher!,Você pegou o Zorcher Grande!,Apanhaste o Zorcher Grande!,Ai ridicat un Zorcher Mare!,Получен большой зорчер!,Добио си велики зорчер!,Du har den stora Zorcher!,Büyük Zorcher'ı aldınız! +You got the Mega Zorcher!,GOTSUPERLARGEZORCHER,,,,Získal@[ao_cs] jsi megabzukr!,Du fik Mega Zorcher!,Du hast den Megazorcher genommen!,,Vi prenis la Grandegzorĉilon!,¡Tienes el Mega Zorcher!,,Sait megazorcherin!,Vous avez pris le méga Zorcheur!,Felvetted a Mega Zorkert!,Hai trovato il mega zorcher!,ちょうおおがたゾーチャー をてにいれた!,초대형 자쳐 습득!,Je hebt de Megazorcher!,Du har Mega Zorcher!,Zdobył@[irreg_3_pl] Mega Zorcher!,Você pegou o Mega Zorcher!,Apanhaste o Mega Zorcher!,Ai ridicat un Mega Zorcher!,Получен мегазорчер!,Добио си мега зорчер!,Du har Mega Zorcher!,Mega Zorcher'ı aldın! +Picked up a Mini Zorcher.,GOTMINIZORCHER,,,,Sebrán minibzukr.,Du har fået en Mini Zorcher.,Du hast einen Minizorcher genommen.,,Prenis Zorĉileton.,Recogiste un Mini Zorcher,,Poimit minizorcherin.,Vous avez pris le Mini Zorcheur.,Felvettél egy Mini Zorkert.,Raccolto un mini zorcher.,こがたゾーチャー をてにいれた。,소형 자쳐 습득.,Je hebt een minizorcher opgepakt.,Plukket opp en Mini Zorcher.,Zebrano Mini Zorcher.,Você pegou um Mini Zorcher.,Apanhaste um Mini Zorcher.,Ai ridicat un Mini Zorcher.,Получен мини-зорчер.,Покупио си мини зорчер!,Du fick en Mini Zorcher.,Bir Mini Zorcher aldın. +,,Actor tags,,,,,,,,,,,,,,,,,,,,,,,,, +Spoon,TAG_SPOON,,,,Lžíce,Ske,Löffel,,Kulero,Cuchara,,Lusikka,Cuillère à Botte,Kanál,Cucchiaio ,スプーン,숟가락,Lepel,Skje,Łyżka,Colher,,Lingură,Ложка,Кашика,Sked,Kaşık +Super Bootspork,TAG_SPORK,,,,Super botodlička,,Supergabel,,Ega Ŝargmanĝilaro,Súper Cuchador,,Superluha,Super Fourchette,Szuper Rotációs Villa,Super Forcucchiaio,スーパーさきわれスプーン,부트스포크,,,Super Łyżkowidelec,Super Garfo,Super Garfo-Colher,Super Lingură,Суперложковилка,Супер виљушка,Super Bootspork,Süper Bootspork +Mini Zorcher,TAG_MINIZORCHER,,,,Minibzukr,,Minizorcher,,Zorĉileto,,,Minizorcheri,Mini Zorcheur,Mini Zorker,,こがたゾーチャー,소형 자쳐,Minizorcher,,,Mini Zorcher,,,Мини-зорчер,Мини зорчер,, +Large Zorcher,TAG_LARGEZORCHER,,,,Velký bzukr,Stor Zorcher,Großer Zorcher,,Granda Zorĉilo,Zorcher Grande,,Iso zorcheri,Zorcheur Large,Nagy Zorker,Grosso Zorcher ,おおがたゾーチャー,대형 자쳐,Grote Zorcher,Stor Zorcher,Duży Zorcher,Zorcher Grande,,Zorcher Mare,Большой зорчер,Велики зорчер,Stor Zorcher,Büyük Zorcher +Super-Large Zorcher,TAG_SUPERLARGEZORCHER,,,,Supervelký bzukr,Super-stor Zorcher,Riesenzorcher,,Grandega Zorĉilo,Zorcher Súper Grande,,Superiso zorcheri,Zorcheur Extra-large,Hatalmas Zorker,Zorcher Enorme ,ちょうおおがたゾーチャー,초대형 자쳐,Super grote Zorcher,Super-stor Zorcher,Większy Zorcher,Super Zorcher Grande,,Zorcher Super-Mare,Мегазорчер,Супер-велики зорчер,Superstor Zorcher,Süper Büyük Zorcher +Rapid Zorcher,TAG_RAPIDZORCHER,,,,Rychlobzukr,,Schnellzorcher,,Rapida Zorĉilo,Zorcher Rápido,,Pikazorcheri,Zorcheur Rapide,Gyors Zorker,Zorcher Rapido,れんしゃ ゾーチャー,속사 자쳐,Snelle Zorcher,,Szybkostrzelny Zorcher,Zorcher Automático,,Zorcher cu Foc Rapid,Быстрый зорчер,Рапидни зорчер,Snabbt Zorcher,Hızlı Zorcher +Zorch Propulsor,TAG_ZORCHPROPULSOR,,,,Bzukový propulzor,,Zorch-Propeller,,Zorĉpropulsilo,Propulsor de Zorch,,Zorchtyönnin,Propulseur de Zorch,Zork Elhárító,Propulsore Zorch,ロケット ゾーチ,저치 추진기,,,Pędnik Zorch,Propulsor de Zorch,,Accelerator Zorch,Ускоритель зорча,Погонски зорчер,, +Phasing Zorcher,TAG_PHASINGZORCHER,,,,Fázovací bzukr,,Phasenzorcher,,Fluktuantzorĉilo,Zorcher de Fase,,Vaiheiszorcheri,Zorcheur à Phase,Fokozatos Zorker,Zorcher di Fase,フェイシング ゾーチャー,전자 자쳐,Fasezorcher,,Fazowy Zorcher,Zorcher Fásico,,Zorcher Fazat,Фазерный зорчер,Фазни зорчер,Fasande Zorcher,Fazlama Zorcher +LAZ Device,TAG_LAZDEVICE,,,,Velkodosahový bzukr,LAZ-enhed,Flächenzorcher,,LAZ-Aparato,Dispositivo LAZ,,SAZ-laite,Zorcheur Zone Large,LAZ Készülék,Dispositivo LAZ,ラージエリアゾーキング デバイス,LAZ 장치,LAZ-aparaat,LAZ-enhet,Urządzenie LAZ,Dispositivo LAZ,,Dispozitiv LAZ,Устройство «ЗБР»,ЛАЗ уређај,LAZ-enhet,LAZ Cihazı %o was slimed by a flemoid.,OB_COMMONUS,,,,%o byl@[ao_cs] osliznut@[ao_cs] slizounem.,%o blev slimet af en flemoid.,%o wurde von einem Flemoiden vollgeschleimt.,,%o estas ŝlimiga de mukulo.,%o fue pegotead@[ao_esp] por un flemoide.,,%o joutui limatuksen limaamaksi.,%o à été gélifié par un flemoid.,%o el lett trutyizva egy Flemoid által.,%o è stato coperto di slime da un flemoid.,%o はフレモイドにベトベトにされた。,%o 은(는) 플레모이드에 의해 더러워졌습니다.,%o werd afgeslankt door een flemoid.,%o ble slimet av en flemoid.,"%o został@[ao_pl] oszlamion@[adj_pl] przez flemoida. -",%o foi melecad@[ao_ptb] por um flemóide.,%o foi suj@[ao_ptb] por um flemóide.,%o a fost transformat în mâzgă de un flemoid.,Игрока %o обслюнявил флемоид.,%o је унаказио љигавац.,%o bir flemoid tarafından sümüklendi. -%o was slimed by a bipedicus.,OB_BIPEDICUS,,,,%o byl@[ao_cs] osliznut@[ao_cs] dvojnožkem.,%o blev slimet af en bipedicus.,%o wurde von einem Bipedicus vollgeschleimt.,,%o estas ŝlimiga de dupiedmukulo.,%o fue pegotead@[ao_esp] por un bipedicus.,,%o joutui bipedicuksen limaamaksi.,%o à été gélifié@[e_fr] par un bipedicus.,%o el lett trutyizva egy kétlábusz által.,%o è stato coperto di slime da un bipedicus.,%o はバイペディクスにベトベトにされた。,%o 은(는) 바이피디쿠스의 끈쩍한 시야에 걸렸습니다.,%o werd afgeslankt door een bipedicus.,%o ble slimet av en bipedicus.,%o został@[ao_pl] oszlamion@[adj_pl] przez bipedicusa.,%o foi melecad@[ao_ptb] por um bipedicus.,%o foi suj@[ao_ptb] por um bipedicus.,% a fost transformat în mâzgă de un biped.,Игрока %o обслюнявила двуножка.,%o је унаказио двоножни-љигавац.,%o bir bipedicus tarafından sümüklendi. +",%o foi melecad@[ao_ptb] por um flemóide.,%o foi suj@[ao_ptb] por um flemóide.,%o a fost transformat în mâzgă de un flemoid.,Игрока %o обслюнявил флемоид.,%o је унаказио љигавац.,%o blev slemmad av en flemoid.,%o bir flemoid tarafından sümüklendi. +%o was slimed by a bipedicus.,OB_BIPEDICUS,,,,%o byl@[ao_cs] osliznut@[ao_cs] dvojnožkem.,%o blev slimet af en bipedicus.,%o wurde von einem Bipedicus vollgeschleimt.,,%o estas ŝlimiga de dupiedmukulo.,%o fue pegotead@[ao_esp] por un bipedicus.,,%o joutui bipedicuksen limaamaksi.,%o à été gélifié@[e_fr] par un bipedicus.,%o el lett trutyizva egy kétlábusz által.,%o è stato coperto di slime da un bipedicus.,%o はバイペディクスにベトベトにされた。,%o 은(는) 바이피디쿠스의 끈쩍한 시야에 걸렸습니다.,%o werd afgeslankt door een bipedicus.,%o ble slimet av en bipedicus.,%o został@[ao_pl] oszlamion@[adj_pl] przez bipedicusa.,%o foi melecad@[ao_ptb] por um bipedicus.,%o foi suj@[ao_ptb] por um bipedicus.,% a fost transformat în mâzgă de un biped.,Игрока %o обслюнявила двуножка.,%o је унаказио двоножни-љигавац.,%o blev slemmad av en bipedicus.,%o bir bipedicus tarafından sümüklendi. %o was slimed by an armored bipedicus.,OB_BIPEDICUS2,,,%o was slimed by an armoured bipedicus.,%o byl@[ao_cs] osliznut@[ao_cs] obrněným dvojnožkem.,%o blev slimet af en pansret bipedicus.,%o wurde von einem gepanzerten Bipedicus vollgeschleimt.,,%o estas ŝlimiga de kirasa dupiedmukulo.,%o fue pegotead@[ao_esp] por un bipedicus blindado.,,%o joutui panssaroidun bipedicuksen limaamaksi.,%o à été gélifié@[e_fr] par un bipedicus en armure.,%o el lett trutyizva egy páncélozott kétlábusz által.,%o è stato coperto di slime da un bipedicus corazzato.,%o はアーマードペディクスにベトベトにされた。,%o 은(는) 정예 바이피디쿠스의 찐득한 공격을 받았습니다.,%o werd afgeslankt door een gepantserde bipedicus.,%o ble slimet av en pansret bipedicus.,%o został@[ao_pl] oszlamion@[adj_pl] przez opancerzonego bipedicusa.,%o foi melecad@[ao_ptb] por um bipedicus de armadura.,%o foi suj@[ao_ptb] por um bipedicus de armadura.,"%o a fost transformat în mâzgă de un biped cu -armură.",Игрока %o обслюнявила бронированная двуножка.,%o је унаказио оклопни-љигавац.,%o zırhlı bir bipedicus tarafından sümüklendi. -%o was slimed by a cycloptis.,OB_CYCLOPTIS,,,,%o byl@[ao_cs] osliznut@[ao_cs] jednoočkem.,%o blev slimet af en cycloptis.,%o wurde von einem Cycloptis vollgeschleimt.,,%o estas ŝlimiga de ciklopmukulo,%o fue pegotead@[ao_esp] por un cicloptis.,,%o joutui cycloptiksen limaamaksi.,%o à été gélifié@[e_fr] par un cycloptis.,%o el lett trutyizva egy kükloptisz által.,%o è stato coperto di slime da un cycloptis.,%o はサイクロプティスにベトベトにされた。,%o 은(는) 사이클롭티스 곁에 미끄러졌습니다.,%o werd afgeslankt door een cycloptis.,%o ble slimet av en cycloptis.,%o został@[ao_pl] oszlamion@[adj_pl] przez cykloptisa.,%o foi melecad@[ao_ptb] por um cycloptis.,%o foi suj@[ao_ptb] por um cycloptis.,%o a fost transformat în mâzgă de un ciclioptic.,Игрока %o обслюнявил циклоптис.,%o је унаказио циклогавац.,%o bir cycloptis tarafından sümüklendi. -%o was defeated by the Flembrane.,OB_FLEMBRANE,,,,%o byl@[ao_cs] poražen@[ao_cs] Slizobránou.,%o blev besejret af Flembrane.,%o wurde von der Flembrane geschlagen,,%o estas venkita de La Mukmembrano.,%o fue vencid@[ao_esp] por la Flembrana.,,%o joutui Limakalvon päihittämäksi.,%o à été battu@[e_fr] par la Flembrane.,%o vereséget szenvedett a Slejmbrántól.,%o è stato sconfitto dalla Flembrana.,%o はフレムブランにはいぼくした。,%o 은(는) 역겨운 플렘브레인을 돌파하지 못했습니다.,%o werd verslagen door de Flembrane.,%o ble beseiret av Flembrane.,%o został@[ao_pl] pokonan@[adj_pl] przez Flembranę.,%o foi derrotad@[ao_ptb] pela Flembrane.,,%o a fost învins de Flembrană.,Игрока %o победила Флембрана.,%o је поразио љигомозак.,"%o, Flembrane tarafından yenildi." -%o was spoon fed by %k.,OB_MPSPOON,,,,%o byl@[ao_cs] nakrmen@[ao_cs] lžičkou hráče %k.,%o blev spoon-fodret af %k.,%o wurde von %k mit dem Löffel gefüttert.,,%o estas kulernutrita de %k.,%o fue cucharead@[ao_esp] por %k.,,%k syötti pelaajaa %o lusikalla.,%o à été nourri@[e_fr] a la petite cuillière par %k.,%o kanállal lett etetve %k által.,%o è stato imboccato da %k.,%o は %k にスプーンでたべさせられた。,%k 이(가) %o 을(를) 숟가락으로 맛있게 먹였습니다.,%o werd met een lepel gevoed door %k.,%o ble matet med skje av %k.,%o został@[ao_pl] nakarmion@[adj_pl] łyżką przez %k.,%o foi comid@[ao_ptb] de colher por %k.,,%o a fost hrănit cu lingura de %k.,Игрок %o поел с ложечки у игрока %k.,%o је накашикан од %k,"%o, %k tarafından kaşıkla beslendi." -%o was thoroughly mixed with %k's bootspork.,OB_MPBOOTSPORK,,,,%o byl@[ao_cs] pořádně namíchán@[ao_cs] botovidličkou hráče %k.,%o blev grundigt blandet med %ks støvlespork.,%o wurde von %k gründlich durchgerührt.,,%o estas plene miksita de la ŝargmanĝilaro de %k.,%o fue profundamente revuelt@[ao_esp] por el cubierto de %k.,,%k läpikotaisin sekoitti %o paran luhallaan.,%o à été mélangé@[e_fr] minutieusement par la Super Fourchette de %k.,%o össze lett keverve %k Rotációsvillája által.,%o è stato mischiato ben bene dal bootspork di %k.,%o は %k にスーパーさきわれスプーンでかきまぜられた。,%k 이(가) %o 을(를) 부트스포크로 빙빙 돌렸습니다.,%o werd grondig gemengd met %k's bootspork.,%o ble grundig blandet med %k's bootspork.,%o został@[ao_pl] dokładnie wymieszan@[adj_pl] łyżkowidelcem %k.,%o foi mexid@[ao_ptb] pelo garfo de %k.,%o foi mexid@[ao_ptb] pelo garfo-colher de %k.,%o a fost amestecat bine de lingura lui %k.,Игрок %o тщательно перемешан ложковилкой игрока %k.,%o је темељно измешан од стране %k супер виљушке.,%o iyice karıştırıldı. -%o was zorched by %k.,OB_MPZORCH,,,,%o byl@[ao_cs] bzukrnut@[ao_cs] hráčem %k.,%o blev zorched af %k.,%o wurde von %k gezorcht,,%o estas zorĉita de %k.,%o fue electrizad@[ao_esp] por %k.,,%k zorchasi %o paran.,%o à été zorché@[e_fr] par %k.,%o zorkolva lett %k által.,%o è stato zorchato da %k.,%o は %k にビリビリさせられた。,%o 은(는) %k 의 소형 자쳐 광선에 맞았습니다.,%o werd gezorched door %k.,%o ble svidd av %k.,%o został@[ao_pl] został zazorchowan@[adj_pl] przez %k.,%o foi zorchead@[ao_ptb] por %k.,,%o a fost înlăturat de zorcherul lui %k.,Игрок %o получил заряд из Зорчера %k.,%o је зорчован %k.,"%o, %k tarafından yenildi." -%o was hit by %k's mega-zorcher.,OB_MPMEGAZORCH,,,,%o byl@[ao_cs] trefen@[ao_cs] megabzukrem hráče %k.,%o blev ramt af %k's mega-zorcher.,%o wurde von%ks Mega-Zorcher getroffen,,%o estas trafita de la zorĉilego de %k.,%o fue impactad@[ao_esp] por el mega-zorcher de %k.,,%k osui %o parkaan megazorcherillaan.,%o à été frappé@[e_fr] par le méga zorcheur de %k.,%o elérte %k mega zorkerét.,%o è stato colpito dal mega-zorcher di %k.,%o に %k のメガゾーチャーがヒットした。,%o 은(는) %k 의 초대형 자쳐 광선에 날라갔습니다.,%o werd geraakt door %k's megazorcher.,%o ble truffet av %k's mega-zorcher.,%o został@[ao_pl] trafion@[adj_pl] mega-zorcherem %k.,%o foi atingid@[ao_ptb] pelo mega-zorcher de %k.,,%o a fost lovit de mega-zorcherul lui %k.,Игрок %o подстрелен из Мегазорчера %k.,%o је ударен од стране %k мега-зорчера.,"%o, %k tarafından yenildi." -%o was rapid zorched by %k.,OB_MPRAPIDZORCH,,,,%o dostal@[ao_cs] rychlobzukrem hráče %k.,%o blev hurtigt zorched af %k.,%o wurde von %k schnellgezorcht.,,%o estas rapidzorĉita de %k.,%o fue electrizad@[ao_esp] rápidamente por %k.,,%k pikazorchasi %o paran.,%o à été zorché@[e_fr] rapidement par %k.,%o gyors zorkolva lett %k által.,%o è stato rapid-zorchato da %k.,%o は %k に めをまわされた。,%o 은(는) %k 의 속사 자쳐 때문에 춤을 췄습니다.,%o werd snel zorched door %k.,%o ble raskt svidd av %k.,%o został@[ao_pl] szybko zazorchowan@[adj_pl] przez %k.,%o foi zorchead@[ao_ptb] automaticamente por %k.,,%o a fost învins de zorcherul rapid al lui %k.,Игрок %o получил заряд из быстрого Зорчера %k.,%o је рапидно зорчован %k,"%o, %k tarafından yenildi." -%o was zorched by %k's propulsor.,OB_MPPROPULSOR,,,,%o byl@[ao_cs] bzukrnut@[ao_cs] propulzorem hráče %k.,%o blev zorched af %ks propulsor.,%o wurde von %ks Propeller gezorcht,,%o estas zorĉita de la propulsilo de %k.,%o fue electrizad@[ao_esp] por el propulsor de %k.,,%k zorchasi %o paran työntimellään.,%o à été zorché@[e_fr] par le propulseur de %k.,%o zorkolva lett %k elhárítója által.,%o è stato zorchato dal propulsore di %k.,%o は %k のロケットゾーチャーにあたった。,%o 은(는) %k 의 저치 추진기 쓴 맛을 봤습니다.,%o werd zorched door %k's propulsor.,%o ble zorched av %k's propulsor.,%o został@[ao_pl] zazorchowan@[adj_pl] przez pędnik %k.,%o foi zorchead@[ao_ptb] pelo propulsor de %k.,,%o a fost învins de acceleratorul zorch al lui %k.,Игрок %o получил заряд из ускорителя Зорча %k.,%o је зорчован %k погоном.,"%o, %k tarafından yenildi." -%o was hit by %k's propulsor.,OB_MPP_SPLASH,,,,%o byl@[ao_cs] zasažen@[ao_cs] propulzorem hráčem %k.,%o blev ramt af %k's propulsor.,%o wurde von %ks Propeller getroffen,,%o estas trafita de la propulsilo de %k.,%o fue impactad@[ao_esp] por el propulsor de %k.,,%k osui %o parkaan työntimellään.,%o à été frappé@[e_fr] par le propulseur de %k.,%o elérte %k elhárítóját.,%o è stato colpito dal propulsore di %k.,%o に %k のロケットゾーチャーがとどいた。,%o 은(는) %k 의 저치 추진기의 방사 능력을 우습게 봤습니다.,%o werd geraakt door %k's propulsor.,%o ble truffet av %k's propulsor.,%o został@[ao_pl] trafion@[adj_pl] pędnikiem %k.,%o foi atingid@[ao_ptb] pelo propulsor de %k.,,%o a fost învins de acceleratorul lui %k.,Игрок %o подстрелен из ускорителя Зорча %k.,%o је ударен %k погоном.,"%o, %k tarafından yenildi." -%o was phase zorched by %k.,OB_MPPHASEZORCH,,,,%o byl@[ao_cs] bzukr-vyfázován@[ao_cs] hráčem %k.,%o blev fasezorched af %k.,%o wurde von %k wegsynchronisiert,,%o estas fluktuantzorĉita de %k.,%o fue electrizad@[ao_esp] en fase por %k.,,%k vaiheiszorchasi %o paran.,%o à été phasé@[e_fr] par %k.,%o fázis zorker áldozata lett %k által.,%o è stato phase-zorchato da %k.,%o は %k によってスベスベにされた。,%o 은(는) %k 의 전자 자쳐에 의해 쓰러졌습니다.,%o was fase zorched door %k.,%o ble fasebrent av %k.,%o został@[ao_pl] został sfazowan@[adj_pl] przez %k.,%o foi atingid@[ao_ptb] pelo zorcher fásico por %k.,,%o a fost înfrânt de zorcherul fazat al lui %k.,Игрок %o получил заряд из фазерного Зорчера %k.,%o је фазно торчован %k.,"%o, %k tarafından yenildi." -%o fell prey to %k's LAZ device.,OB_MPLAZ_BOOM,,,,%o padl@[ao_cs] velkodosahovému bzukru hráče %k.,%o blev offer for %k's LAZ-enhed.,%o fiel %ks Flächenzorcher zum Opfer,,%o iĝis predo de la LAZ-aparato de %k.,%o cayó pres@[ao_esp] ante el dispositivo LAZ de %k.,,%o lankesi pelaajan %k SAZ-laitteen uhriksi.,%o est devenu@[e_fr] la proie du ZZL de %k.,%o prédául lett ejtve %k LAZ készülékével.,%o è stato preda del dispositivo LAZ di %k.,%o は %k のLAZデバイスのえじきになった。,%k 이(가) LAZ 장치를 들기 전에 %o 은(는) 도망쳐야 했습니다.,%o viel ten prooi aan %k's LAZ apparaat.,%o ble offer for %k's LAZ-enhet.,%o stał@[ao_pl] się ofiarą urządzenia LAZ %k.,%o foi vítima do dispositivo LAZ de %k.,,%o a căzut pradă dispozitivului LAZ al lui %k.,Игрок %o склонился перед «ЗБР» игрока %k.,%o је постао жртва %k ЛАЗ уређаја.,"%o, %k tarafından lazzlandı." -%o was lazzed by %k.,OB_MPLAZ_SPLASH,,,,%o byl@[ao_cs] odbzukrován hráčem %k.,%o blev lazzed af %k.,%o wurde von %k weggebeamt.,,%o estas LAZ-ita de %k.,%o fue LAZeado por %k.,,%k sazzasi pelaajaan %o.,%o à été pris@[e_fr] par le ZZL de %k.,%o el lett lazzázva %k által.,%o è stato lazzato da %k.,%o は %k にとかされた。,%o 은(는) %k 의 LAZ 장치 범위를 벗어날 수 없었습니다.,%o werd gelazed door %k.,%o ble lazzed av %k.,%o został@[ao_pl] zLAZowan@[adj_pl] przez %k.,%o foi LAZead@[ao_ptb] por %k.,,%o a fost stropit de dispozitivul LAZ al lui %k.,Игрок %o получил заряд из «ЗБР» игрока %k.,%o је ЛАЗ-овао %k.,"%o, %k tarafından lazzlandı." -,,Miscellaneous,,,,,,,,,,,,,,,,,,,,,,,, -E1M1: Landing Zone,CHUSTR_E1M1,,,,E1M1: Přistávací zóna,E1M1: Landingszone,E1M1: Landezone,,E1M1: Surterejo,E1M1: Zona de Aterrizaje,,E1M1: Laskeutumisalue,E1M1: La piste d'atterissage,E1M1: Leszállópálya,E1M1: Zona di Atterraggio,E1M1: ちゃくりく ちてん,E1M1: 착륙 지점,E1M1: Landingszone,E1M1: Landingssone,E1M1: Strefa Lądowania,E1M1: Zona de Pouso,E1M1: Zona de Aterragem,E1M1: Pista de Aterizare,E1M1: Зона приземления,Е1М1: Зона слетања,E1M1: İniş Bölgesi -E1M2: Storage Facility,CHUSTR_E1M2,,,,E1M2: Skladiště,E1M2: Opbevaringsanlæg,E1M2: Lagerhalle,,E1M2: Stokejo,E1M2: Instalación de Almacenamiento,,E1M2: Varastolaitos,E1M2: Le centre de stockage,E1M2: Raktárépület,E1M2: Struttura di Immagazzinamento,E1M2: ほかん しせつ,E1M2: 저장 시설,E1M2: Opslagfaciliteit,E1M2: Lagringsanlegg,E1M2: Magazyn,E1M2: Depósito,E1M2: Armazém,E1M2: Depozitul,E1M2: Хранилище,Е1М2: Складиште,E1M2: Depolama Tesisi -E1M3: Experimental Lab,CHUSTR_E1M3,,,,E1M3: Testovací laboratoř,E1M3: Forsøgslaboratorium,E1M3: Experimentelles Labor,,E1M3: Eksperimenta Laboratorio,E1M3: Laboratorio Experimental,,E1M3: Koelaboratorio,E1M3: Les labos expérimentaux,E1M3: Laboratórium,E1M3: Laboratorio Sperimentale,E1M3: じっけんしつ,E1M3: 연구소,E1M3: Experimenteel laboratorium,E1M3: Eksperimentelt laboratorium,E1M3: Laboratorium Eksperymentalne,E1M3: Laboratório de Experimentos,E1M3: Laboratório Experimental,E1M2: Laboratorul,E1M3: Лаборатория,Е1М3: Експериментална лабораторија,E1M3: Deneysel Laboratuvar -E1M4: Arboretum,CHUSTR_E1M4,,,,,,,,E1M4: Arbejo,E1M4: Arboreto,,,E1M4: L'Arboretum,E1M4: Arborétum,E1M4: Arboreto,E1M4: じゅもくえん,E1M4: 수목원,E1M4: Arboretum,E1M4: Arboretet,E1M4: Arboretum,E1M4: Arvoredo,,E1M4: Arboretum,E1M4: Дендрарий,Е1М4: Ботаничка башта,E1M4: Arboretum -E1M5: Caverns of Bazoik,CHUSTR_E1M5,,,,E1M5: Bazoikské jeskyně,E1M5: Bazoiks grotter,E1M5: Die Höhlen von Bazoik,,E1M5: Kavernoj de Bazojko,E1M5: Cavernas de Bazoik,,E1M5: Bazoikin luolastot,E1M5: Les cavernes de Bazoik,E1M5: Bazoik barlangjai,E1M5: Caverne di Bazoik,E1M5: バゾイクの どうくつ,E1M5: 바조이크의 대동굴,E1M5: Grotten van Bazoik,E1M5: Grottene til Bazoik,E1M5: Jaskinie Bazoik,E1M5: Cavernas de Bazoik,,E1M5: Cavernele lui Bazoik,E1M5: Пещеры Базоика,Е1М5: Пећине Базоика,E1M5: Bazoik Mağaraları +armură.",Игрока %o обслюнявила бронированная двуножка.,%o је унаказио оклопни-љигавац.,%o blev slemmad av en bepansrad bipedicus.,%o zırhlı bir bipedicus tarafından sümüklendi. +%o was slimed by a cycloptis.,OB_CYCLOPTIS,,,,%o byl@[ao_cs] osliznut@[ao_cs] jednoočkem.,%o blev slimet af en cycloptis.,%o wurde von einem Cycloptis vollgeschleimt.,,%o estas ŝlimiga de ciklopmukulo,%o fue pegotead@[ao_esp] por un cicloptis.,,%o joutui cycloptiksen limaamaksi.,%o à été gélifié@[e_fr] par un cycloptis.,%o el lett trutyizva egy kükloptisz által.,%o è stato coperto di slime da un cycloptis.,%o はサイクロプティスにベトベトにされた。,%o 은(는) 사이클롭티스 곁에 미끄러졌습니다.,%o werd afgeslankt door een cycloptis.,%o ble slimet av en cycloptis.,%o został@[ao_pl] oszlamion@[adj_pl] przez cykloptisa.,%o foi melecad@[ao_ptb] por um cycloptis.,%o foi suj@[ao_ptb] por um cycloptis.,%o a fost transformat în mâzgă de un ciclioptic.,Игрока %o обслюнявил циклоптис.,%o је унаказио циклогавац.,%o blev slemmad av en cycloptis.,%o bir cycloptis tarafından sümüklendi. +%o was defeated by the Flembrane.,OB_FLEMBRANE,,,,%o byl@[ao_cs] poražen@[ao_cs] Slizobránou.,%o blev besejret af Flembrane.,%o wurde von der Flembrane geschlagen,,%o estas venkita de La Mukmembrano.,%o fue vencid@[ao_esp] por la Flembrana.,,%o joutui Limakalvon päihittämäksi.,%o à été battu@[e_fr] par la Flembrane.,%o vereséget szenvedett a Slejmbrántól.,%o è stato sconfitto dalla Flembrana.,%o はフレムブランにはいぼくした。,%o 은(는) 역겨운 플렘브레인을 돌파하지 못했습니다.,%o werd verslagen door de Flembrane.,%o ble beseiret av Flembrane.,%o został@[ao_pl] pokonan@[adj_pl] przez Flembranę.,%o foi derrotad@[ao_ptb] pela Flembrane.,,%o a fost învins de Flembrană.,Игрока %o победила Флембрана.,%o је поразио љигомозак.,%o blev besegrad av Flembrane.,"%o, Flembrane tarafından yenildi." +%o was spoon fed by %k.,OB_MPSPOON,,,,%o byl@[ao_cs] nakrmen@[ao_cs] lžičkou hráče %k.,%o blev spoon-fodret af %k.,%o wurde von %k mit dem Löffel gefüttert.,,%o estas kulernutrita de %k.,%o fue cucharead@[ao_esp] por %k.,,%k syötti pelaajaa %o lusikalla.,%o à été nourri@[e_fr] a la petite cuillière par %k.,%o kanállal lett etetve %k által.,%o è stato imboccato da %k.,%o は %k にスプーンでたべさせられた。,%k 이(가) %o 을(를) 숟가락으로 맛있게 먹였습니다.,%o werd met een lepel gevoed door %k.,%o ble matet med skje av %k.,%o został@[ao_pl] nakarmion@[adj_pl] łyżką przez %k.,%o foi comid@[ao_ptb] de colher por %k.,,%o a fost hrănit cu lingura de %k.,Игрок %o поел с ложечки у игрока %k.,%o је накашикан од %k,%o blev matad med sked av %k.,"%o, %k tarafından kaşıkla beslendi." +%o was thoroughly mixed with %k's bootspork.,OB_MPBOOTSPORK,,,,%o byl@[ao_cs] pořádně namíchán@[ao_cs] botovidličkou hráče %k.,%o blev grundigt blandet med %ks støvlespork.,%o wurde von %k gründlich durchgerührt.,,%o estas plene miksita de la ŝargmanĝilaro de %k.,%o fue profundamente revuelt@[ao_esp] por el cubierto de %k.,,%k läpikotaisin sekoitti %o paran luhallaan.,%o à été mélangé@[e_fr] minutieusement par la Super Fourchette de %k.,%o össze lett keverve %k Rotációsvillája által.,%o è stato mischiato ben bene dal bootspork di %k.,%o は %k にスーパーさきわれスプーンでかきまぜられた。,%k 이(가) %o 을(를) 부트스포크로 빙빙 돌렸습니다.,%o werd grondig gemengd met %k's bootspork.,%o ble grundig blandet med %k's bootspork.,%o został@[ao_pl] dokładnie wymieszan@[adj_pl] łyżkowidelcem %k.,%o foi mexid@[ao_ptb] pelo garfo de %k.,%o foi mexid@[ao_ptb] pelo garfo-colher de %k.,%o a fost amestecat bine de lingura lui %k.,Игрок %o тщательно перемешан ложковилкой игрока %k.,%o је темељно измешан од стране %k супер виљушке.,%o blev ordentligt uppblandad med %ks bootspork.,%o iyice karıştırıldı. +%o was zorched by %k.,OB_MPZORCH,,,,%o byl@[ao_cs] bzukrnut@[ao_cs] hráčem %k.,%o blev zorched af %k.,%o wurde von %k gezorcht,,%o estas zorĉita de %k.,%o fue electrizad@[ao_esp] por %k.,,%k zorchasi %o paran.,%o à été zorché@[e_fr] par %k.,%o zorkolva lett %k által.,%o è stato zorchato da %k.,%o は %k にビリビリさせられた。,%o 은(는) %k 의 소형 자쳐 광선에 맞았습니다.,%o werd gezorched door %k.,%o ble svidd av %k.,%o został@[ao_pl] został zazorchowan@[adj_pl] przez %k.,%o foi zorchead@[ao_ptb] por %k.,,%o a fost înlăturat de zorcherul lui %k.,Игрок %o получил заряд из зорчера %k.,%o је зорчован %k.,%o blev zorchad av %k.,"%o, %k tarafından yenildi." +%o was hit by %k's mega-zorcher.,OB_MPMEGAZORCH,,,,%o byl@[ao_cs] trefen@[ao_cs] megabzukrem hráče %k.,%o blev ramt af %k's mega-zorcher.,%o wurde von%ks Mega-Zorcher getroffen,,%o estas trafita de la zorĉilego de %k.,%o fue impactad@[ao_esp] por el mega-zorcher de %k.,,%k osui %o parkaan megazorcherillaan.,%o à été frappé@[e_fr] par le méga zorcheur de %k.,%o elérte %k mega zorkerét.,%o è stato colpito dal mega-zorcher di %k.,%o に %k のメガゾーチャーがヒットした。,%o 은(는) %k 의 초대형 자쳐 광선에 날라갔습니다.,%o werd geraakt door %k's megazorcher.,%o ble truffet av %k's mega-zorcher.,%o został@[ao_pl] trafion@[adj_pl] mega-zorcherem %k.,%o foi atingid@[ao_ptb] pelo mega-zorcher de %k.,,%o a fost lovit de mega-zorcherul lui %k.,Игрок %o подстрелен из мегазорчера %k.,%o је ударен од стране %k мега-зорчера.,%o blev träffad av %ks mega-zorcher.,"%o, %k tarafından yenildi." +%o was rapid zorched by %k.,OB_MPRAPIDZORCH,,,,%o dostal@[ao_cs] rychlobzukrem hráče %k.,%o blev hurtigt zorched af %k.,%o wurde von %k schnellgezorcht.,,%o estas rapidzorĉita de %k.,%o fue electrizad@[ao_esp] rápidamente por %k.,,%k pikazorchasi %o paran.,%o à été zorché@[e_fr] rapidement par %k.,%o gyors zorkolva lett %k által.,%o è stato rapid-zorchato da %k.,%o は %k に めをまわされた。,%o 은(는) %k 의 속사 자쳐 때문에 춤을 췄습니다.,%o werd snel zorched door %k.,%o ble raskt svidd av %k.,%o został@[ao_pl] szybko zazorchowan@[adj_pl] przez %k.,%o foi zorchead@[ao_ptb] automaticamente por %k.,,%o a fost învins de zorcherul rapid al lui %k.,Игрок %o получил заряд из быстрого зорчера %k.,%o је рапидно зорчован %k,%o blev snabbt zorchad av %k.,"%o, %k tarafından yenildi." +%o was zorched by %k's propulsor.,OB_MPPROPULSOR,,,,%o byl@[ao_cs] bzukrnut@[ao_cs] propulzorem hráče %k.,%o blev zorched af %ks propulsor.,%o wurde von %ks Propeller gezorcht,,%o estas zorĉita de la propulsilo de %k.,%o fue electrizad@[ao_esp] por el propulsor de %k.,,%k zorchasi %o paran työntimellään.,%o à été zorché@[e_fr] par le propulseur de %k.,%o zorkolva lett %k elhárítója által.,%o è stato zorchato dal propulsore di %k.,%o は %k のロケットゾーチャーにあたった。,%o 은(는) %k 의 저치 추진기 쓴 맛을 봤습니다.,%o werd zorched door %k's propulsor.,%o ble zorched av %k's propulsor.,%o został@[ao_pl] zazorchowan@[adj_pl] przez pędnik %k.,%o foi zorchead@[ao_ptb] pelo propulsor de %k.,,%o a fost învins de acceleratorul zorch al lui %k.,Игрок %o получил заряд из ускорителя зорча %k.,%o је зорчован %k погоном.,%o blev zorchad av %ks propulsor.,"%o, %k tarafından yenildi." +%o was hit by %k's propulsor.,OB_MPP_SPLASH,,,,%o byl@[ao_cs] zasažen@[ao_cs] propulzorem hráčem %k.,%o blev ramt af %k's propulsor.,%o wurde von %ks Propeller getroffen,,%o estas trafita de la propulsilo de %k.,%o fue impactad@[ao_esp] por el propulsor de %k.,,%k osui %o parkaan työntimellään.,%o à été frappé@[e_fr] par le propulseur de %k.,%o elérte %k elhárítóját.,%o è stato colpito dal propulsore di %k.,%o に %k のロケットゾーチャーがとどいた。,%o 은(는) %k 의 저치 추진기의 방사 능력을 우습게 봤습니다.,%o werd geraakt door %k's propulsor.,%o ble truffet av %k's propulsor.,%o został@[ao_pl] trafion@[adj_pl] pędnikiem %k.,%o foi atingid@[ao_ptb] pelo propulsor de %k.,,%o a fost învins de acceleratorul lui %k.,Игрок %o подстрелен из ускорителя зорча %k.,%o је ударен %k погоном.,%o blev träffad av %ks propulsor.,"%o, %k tarafından yenildi." +%o was phase zorched by %k.,OB_MPPHASEZORCH,,,,%o byl@[ao_cs] bzukr-vyfázován@[ao_cs] hráčem %k.,%o blev fasezorched af %k.,%o wurde von %k wegsynchronisiert,,%o estas fluktuantzorĉita de %k.,%o fue electrizad@[ao_esp] en fase por %k.,,%k vaiheiszorchasi %o paran.,%o à été phasé@[e_fr] par %k.,%o fázis zorker áldozata lett %k által.,%o è stato phase-zorchato da %k.,%o は %k によってスベスベにされた。,%o 은(는) %k 의 전자 자쳐에 의해 쓰러졌습니다.,%o was fase zorched door %k.,%o ble fasebrent av %k.,%o został@[ao_pl] został sfazowan@[adj_pl] przez %k.,%o foi atingid@[ao_ptb] pelo zorcher fásico por %k.,,%o a fost înfrânt de zorcherul fazat al lui %k.,Игрок %o получил заряд из фазерного зорчера %k.,%o је фазно торчован %k.,%o blev faszorchad av %k.,"%o, %k tarafından yenildi." +%o fell prey to %k's LAZ device.,OB_MPLAZ_BOOM,,,,%o padl@[ao_cs] velkodosahovému bzukru hráče %k.,%o blev offer for %k's LAZ-enhed.,%o fiel %ks Flächenzorcher zum Opfer,,%o iĝis predo de la LAZ-aparato de %k.,%o cayó pres@[ao_esp] ante el dispositivo LAZ de %k.,,%o lankesi pelaajan %k SAZ-laitteen uhriksi.,%o est devenu@[e_fr] la proie du ZZL de %k.,%o prédául lett ejtve %k LAZ készülékével.,%o è stato preda del dispositivo LAZ di %k.,%o は %k のLAZデバイスのえじきになった。,%k 이(가) LAZ 장치를 들기 전에 %o 은(는) 도망쳐야 했습니다.,%o viel ten prooi aan %k's LAZ apparaat.,%o ble offer for %k's LAZ-enhet.,%o stał@[ao_pl] się ofiarą urządzenia LAZ %k.,%o foi vítima do dispositivo LAZ de %k.,,%o a căzut pradă dispozitivului LAZ al lui %k.,Игрок %o склонился перед «ЗБР» игрока %k.,%o је постао жртва %k ЛАЗ уређаја.,%o föll offer för %ks LAZ-enhet.,"%o, %k tarafından lazzlandı." +%o was lazzed by %k.,OB_MPLAZ_SPLASH,,,,%o byl@[ao_cs] odbzukrován hráčem %k.,%o blev lazzed af %k.,%o wurde von %k weggebeamt.,,%o estas LAZ-ita de %k.,%o fue LAZeado por %k.,,%k sazzasi pelaajaan %o.,%o à été pris@[e_fr] par le ZZL de %k.,%o el lett lazzázva %k által.,%o è stato lazzato da %k.,%o は %k にとかされた。,%o 은(는) %k 의 LAZ 장치 범위를 벗어날 수 없었습니다.,%o werd gelazed door %k.,%o ble lazzed av %k.,%o został@[ao_pl] zLAZowan@[adj_pl] przez %k.,%o foi LAZead@[ao_ptb] por %k.,,%o a fost stropit de dispozitivul LAZ al lui %k.,Игрок %o получил заряд из «ЗБР» игрока %k.,%o је ЛАЗ-овао %k.,%o blev lazzad av %k.,"%o, %k tarafından lazzlandı." +,,Miscellaneous,,,,,,,,,,,,,,,,,,,,,,,,, +E1M1: Landing Zone,CHUSTR_E1M1,,,,E1M1: Přistávací zóna,E1M1: Landingszone,E1M1: Landezone,,E1M1: Surterejo,E1M1: Zona de Aterrizaje,,E1M1: Laskeutumisalue,E1M1: La piste d'atterissage,E1M1: Leszállópálya,E1M1: Zona di Atterraggio,E1M1: ちゃくりく ちてん,E1M1: 착륙 지점,E1M1: Landingszone,E1M1: Landingssone,E1M1: Strefa Lądowania,E1M1: Zona de Pouso,E1M1: Zona de Aterragem,E1M1: Pista de Aterizare,E1M1: Зона приземления,Е1М1: Зона слетања,E1M1: Landningszon,E1M1: İniş Bölgesi +E1M2: Storage Facility,CHUSTR_E1M2,,,,E1M2: Skladiště,E1M2: Opbevaringsanlæg,E1M2: Lagerhalle,,E1M2: Stokejo,E1M2: Instalación de Almacenamiento,,E1M2: Varastolaitos,E1M2: Le centre de stockage,E1M2: Raktárépület,E1M2: Struttura di Immagazzinamento,E1M2: ほかん しせつ,E1M2: 저장 시설,E1M2: Opslagfaciliteit,E1M2: Lagringsanlegg,E1M2: Magazyn,E1M2: Depósito,E1M2: Armazém,E1M2: Depozitul,E1M2: Хранилище,Е1М2: Складиште,E1M2: Förvaringsanläggning,E1M2: Depolama Tesisi +E1M3: Experimental Lab,CHUSTR_E1M3,,,,E1M3: Testovací laboratoř,E1M3: Forsøgslaboratorium,E1M3: Experimentelles Labor,,E1M3: Eksperimenta Laboratorio,E1M3: Laboratorio Experimental,,E1M3: Koelaboratorio,E1M3: Les labos expérimentaux,E1M3: Laboratórium,E1M3: Laboratorio Sperimentale,E1M3: じっけんしつ,E1M3: 연구소,E1M3: Experimenteel laboratorium,E1M3: Eksperimentelt laboratorium,E1M3: Laboratorium Eksperymentalne,E1M3: Laboratório de Experimentos,E1M3: Laboratório Experimental,E1M2: Laboratorul,E1M3: Лаборатория,Е1М3: Експериментална лабораторија,E1M3: Experimentellt labb,E1M3: Deneysel Laboratuvar +E1M4: Arboretum,CHUSTR_E1M4,,,,,,,,E1M4: Arbejo,E1M4: Arboreto,,,E1M4: L'Arboretum,E1M4: Arborétum,E1M4: Arboreto,E1M4: じゅもくえん,E1M4: 수목원,,E1M4: Arboretet,,E1M4: Arvoredo,,,E1M4: Дендрарий,Е1М4: Ботаничка башта,, +E1M5: Caverns of Bazoik,CHUSTR_E1M5,,,,E1M5: Bazoikské jeskyně,E1M5: Bazoiks grotter,E1M5: Die Höhlen von Bazoik,,E1M5: Kavernoj de Bazojko,E1M5: Cavernas de Bazoik,,E1M5: Bazoikin luolastot,E1M5: Les cavernes de Bazoik,E1M5: Bazoik barlangjai,E1M5: Caverne di Bazoik,E1M5: バゾイクの どうくつ,E1M5: 바조이크의 대동굴,E1M5: Grotten van Bazoik,E1M5: Grottene til Bazoik,E1M5: Jaskinie Bazoik,E1M5: Cavernas de Bazoik,,E1M5: Cavernele lui Bazoik,E1M5: Пещеры Базоика,Е1М5: Пећине Базоика,E1M5: Bazoiks grottor,E1M5: Bazoik Mağaraları "Mission accomplished. Are you prepared for the next mission? @@ -2061,7 +2035,16 @@ Apasă tasta Esc pentru a continua...","Миссия выполнена. -Притисни ESC да наставиш...","Görev tamamlandı. +Притисни ESC да наставиш...","Uppdraget slutfört. + +Är du redo för nästa uppdrag? + + + + + + +Tryck på escape-tangenten för att fortsätta...","Görev tamamlandı. Bir sonraki görev için hazır mısınız? @@ -2071,9 +2054,9 @@ Bir sonraki görev için hazır mısınız? Devam etmek için kaçış tuşuna basın..." -You've done it!,CE2TEXT,,,,Dokázal@[ao_cs] jsi to!,Du har gjort det!,Du hast es geschafft!,,Vi sukcesis!,¡Lo hiciste!,,Teit sen!,Vous l'avez fait!,Megcsináltad!,Ce l'hai fatta!,よくやった!,해내셨습니다!,Het is je gelukt!,Du klarte det!,Udało ci się!,Você conseguiu!,Conseguiste!,Ai reușit!,Вы справились!,Урадио си то!,Başardınız! -Wonderful Job!,CE3TEXT,,,,Skvělá práce!,Vidunderligt arbejde!,Großartige Arbeit!,,Mirindan Laboron!,¡Maravilloso!,,Hienoa työtä!,Merveilleux travail!,Tökéletes munka!,Meraviglioso!,ワンダフル!,멋지게 잘하셨습니다!,Geweldig werk!,Fantastisk jobb!,Dobra Robota!,Ótimo trabalho!,,O treabă minunată!,Превосходная работа!,Изванредан посао!,Harika bir iş! -Fantastic,CE4TEXT,,,,Fantastické,Fantastisk,Fantastisch,,Mirinda,¡Fantástico!,,Fantastista,Fantastique!,Fantasztikus!,Fantastico,すばらしい!,환상적,Fantastisch,Fantastisk!,Fantastycznie,Fantástico,,Fantastic,Великолепно.,Фантастично,Fantastik +You've done it!,CE2TEXT,,,,Dokázal@[ao_cs] jsi to!,Du har gjort det!,Du hast es geschafft!,,Vi sukcesis!,¡Lo hiciste!,,Teit sen!,Vous l'avez fait!,Megcsináltad!,Ce l'hai fatta!,よくやった!,해내셨습니다!,Het is je gelukt!,Du klarte det!,Udało ci się!,Você conseguiu!,Conseguiste!,Ai reușit!,Вы справились!,Урадио си то!,Du har gjort det!,Başardınız! +Wonderful Job!,CE3TEXT,,,,Skvělá práce!,Vidunderligt arbejde!,Großartige Arbeit!,,Mirindan Laboron!,¡Maravilloso!,,Hienoa työtä!,Merveilleux travail!,Tökéletes munka!,Meraviglioso!,ワンダフル!,멋지게 잘하셨습니다!,Geweldig werk!,Fantastisk jobb!,Dobra Robota!,Ótimo trabalho!,,O treabă minunată!,Превосходная работа!,Изванредан посао!,Underbart jobb!,Harika bir iş! +Fantastic,CE4TEXT,,,,Fantastické,Fantastisk,Fantastisch,,Mirinda,¡Fantástico!,,Fantastista,Fantastique!,Fantasztikus!,Fantastico,すばらしい!,환상적,Fantastisch,Fantastisk!,Fantastycznie,Fantástico,,,Великолепно.,Фантастично,Fantastiskt,Fantastik "You can't do load while in a net quest! Press a key.",CLOADNET,,,,"Nemůžeš použít načtení, když hraješ síťové pátrání! @@ -2117,7 +2100,8 @@ Apasă orice tastă.","Невозможно загрузить сохранен Нажмите любую клавишу.","Не можете учитати док сте у мрежној потрази! -Притисните тастер.","Bir ağ görevindeyken yükleme yapamazsınız! +Притисните тастер.","Du kan inte göra lastning när du är i ett nätspel! +Tryck på en tangent.","Bir ağ görevindeyken yükleme yapamazsınız! Bir tuşa basın." "Quicksave over your quest named @@ -2188,7 +2172,8 @@ Apasă Y sau N.","Выполнить быстрое сохранение зад «%s»? -Нажмите Y или N.",Брзо-сачувајте преко ваше потраге назване '%s'? Притисните Y или N.,"%s' +Нажмите Y или N.",Брзо-сачувајте преко ваше потраге назване '%s'? Притисните Y или N.,"Snabbt spara över ditt spel som heter %s? +Tryck på Y eller N.","%s' adlı oyununuzun üzerine hızlı kaydetme? @@ -2238,7 +2223,9 @@ Apasă orice tastă.","Невозможно загрузить быстрое с Нажмите любую клавишу.","Не можете брзо-учитати док сте у мрежној потрази! -Притисните тастер.","Bir ağ oyunu sırasında hızlı yükleme yapamazsınız! +Притисните тастер.","Du kan inte snabbladda under ett nätspel! + +Tryck på en tangent.","Bir ağ oyunu sırasında hızlı yükleme yapamazsınız! Bir tuşa basın." "Do you want to quickload the quest named @@ -2312,7 +2299,8 @@ Apasă Y sau N.","Загрузить быстрое сохранение зад Нажмите Y или N.","Да ли желиш да брзо-учиташ потрагу названу '%s'? -Притисните Y или N.","%s' +Притисните Y или N.","Vill du snabbladda spelet som heter ""%s""? +Tryck på Y eller N.","%s' adlı oyunu hızlı yüklemek istiyor musunuz? @@ -2366,7 +2354,9 @@ Apasă orice tastă.","Невозможно начать новое задани Нажмите любую клавишу.","Не можете почети нову потрагу док сте у мрежној потрази. -Притисните тастер.","Yeni bir görev başlatamazsınız +Притисните тастер.","Du kan inte starta ett nytt spel när du är i ett nätspel. + +Tryck på en tangent.","Yeni bir görev başlatamazsınız bir ağ görevindeyken. Bir tuşa basın." @@ -2429,7 +2419,10 @@ Apasă Y sau N.","Осторожно — будет сложно. Нажмите Y или N.","Пажљиво, ово је ће бити тешко. Да ли желиш да наставиш? -Притисните Y или N.","Dikkatli ol, bu zor olacak. +Притисните Y или N.","Försiktigt, det här kommer att bli svårt. +Vill du fortsätta? + +Tryck på Y eller N.","Dikkatli ol, bu zor olacak. Devam etmek istiyor musunuz? Y veya N tuşuna basın." @@ -2511,7 +2504,11 @@ Apasă orice tastă.","Вы играете в Chex(R) Quest. Остальные нивое на www.chexquest.com. -Притисните Y или N.","Bu Chex(R) Görevi. +Притисните Y или N.","Det här är Chex(R) Quest. + +framtida nivåer på www.chexquest.com. + +Tryck på en tangent.","Bu Chex(R) Görevi. www.chexquest.com adresinde gelecekteki seviyeler. @@ -2558,7 +2555,8 @@ Apasă orice tastă.","Невозможно прервать сетевое за Нажмите любую клавишу.","Не можете завршити мрежну потрагу! -Притисните тастер.","Bir netquest'i sonlandıramazsınız! +Притисните тастер.","Du kan inte avsluta ett nätspel! +Tryck på en tangent.","Bir netquest'i sonlandıramazsınız! Bir tuşa basın." "Are you sure you want to end the quest? @@ -2602,710 +2600,712 @@ Apasă Y sau N.","Вы точно хотите завершить задание Нажмите Y или N.","Да ли си сигуран да желиш да завршиш трагање? -Притисни Y или N.","Görevi sonlandırmak istediğinizden emin misiniz? +Притисни Y или N.","Är du säker på att du vill avsluta spelet? +Tryck på Y eller N.","Görevi sonlandırmak istediğinizden emin misiniz? Y veya N tuşuna basın." -Invincible Mode ON,STSTR_DQDON,,chex,,Režim nezranitelnosti ZAP,Uovervindelig tilstand TIL,Unbesiegbarer Modus EIN,,Nevenkebla-reĝimo ŜALTITA,Modo invencible ACTIVADO,,Kuolemattomuustila PÄÄLLÄ,Mode invincible ON,Sérthetetlen mód BE,Modalità invincibile attivata,むてきモード オン,무적 모드 켬,Onoverwinnelijke modus AAN,Uovervinnelig modus PÅ,Tryb Niewrażliwości WŁĄCZONY,Modo invencível ATIVADO,,Modul Invincibil ACTIVAT,Режим неуязвимости ВКЛЮЧЁН,Неуништив УКЉУЧЕН,Yenilmez Mod AÇIK -Invincible Mode OFF,STSTR_DQDOFF,,chex,,Režim nezranitelnosti VYP,Uovervindelig tilstand FRA,Unbesiegbarer Modus AUS,,Nevenkebla-reĝimo MALŜALTITA,Modo invencible DESACTIVADO,,Kuolemattomuustila POIS PÄÄLLÄ,Mode invincible OFF,Sérthetetlen mód KI,Modalità invincibile disattivata,むてきモード オフ,무적 모드 끔,Onoverwinnelijke modus UIT,Uovervinnelig modus AV,Tryb Niewrażliwości WYŁĄCZONY,Modo invencível DESATIVADO,,Modul Invincibil DEZACTIVAT,Режим неуязвимости ОТКЛЮЧЁН,Неуништив ИСКЉУЧЕН,Yenilmez Modu KAPALI -Zorch Added,STSTR_FAADDED,,chex,,Bzukry přidány,Zorch tilføjet,Zorch hinzugefügt,,Zorĉo Aldonita,Zorch añadido,,Zorch lisätty,Zorch Ajouté,Szörcs felvéve,Zorch aggiunto,ゾーチ ついか,모든 저치 에너지 추가,Zorch toegevoegd,Zorch lagt til,Zorch dodany,Zorch adicionado,,Zorcher Adăugat,Добавлен Зорч,Зорч додат,Zorch Eklendi -Super Zorch Added,STSTR_KFAADDED,,chex,,Superbzukry přidány,Super Zorch Tilføjet,Super Zorch hinzugefügt,,Supera Zorĉo Aldonita,Súper Zorch añadido,,Superzorch lisätty,Super Zorch Ajouté,Szuper Szörcs feléve,Super Zorch aggiunto,スーパーゾーチ ついか,모든 아이템 습득!,Super Zorch toegevoegd,Super Zorch lagt til,Super Zorch dodany,Super Zorch adicionado,,Super Lingură Adăugată,Добавлен Суперзорч,Супер зорч додат,Süper Zorch Eklendi -... Eat Chex(R)!,STSTR_CHOPPERS,,chex,,... Jez Chex(R)!,... Spis Chex(R)!,...Iss Chex(R)!,,... Manĝu Chex(R)-on!,... Come Chex(R),,... Syö Chex(R):ä!,... Mangez du Chex(R)!,...egyél Chex(R)-et!,... Mangia I Chex(R)!,...Chex(R)をたべよう!,... 첵스(R) 를 많이 먹자!,... Eet Chex(R)!,... Spis Chex(R)!,... jedz płatki Chex(R)!,... coma Chex(R)!,,... Mănâncă Chex(R)!,...ешь Chex(R)!,... Једи Chex(R)!,... Chex(R) yiyin! -Mini Zorch Charge,AMMO_CLIP,,chex,,Minibzukrové náboje,Mini Zorch ladning,Minizorcher-Ladung,,Zorĉileto-Ŝarĝo,Carga de Mini Zorch,,Minizorchvaraus,Charge Zorch,Mini szörcs töltet,Ricarica Mini Zorch,ミニゾーチ ほきゅう,소형 저치 전지,Mini Zorchlading,Mini Zorch ladning,Mini Ładunek Zorch,Recarga de Mini Zorch,,Mini Încărcătură pentru Zorcher,Заряд мини-Зорчера,Мини зорч пуњач,Mini Zorch Şarjı -Large Zorcher Charge,AMMO_SHELLS,,chex,,Velkobzukrové náboje,Stor Zorch ladning,Zorcher-Ladung,,Ŝarĝo por Granda Zorĉilo,Carga de Zorcher Grande,,Ison zorcherin varaus,Charge de Zorcheur Large,Nagy szörcs töltet,Ricarica Grande Zorch,ラージゾーチャー ほきゅう,대형 저치 카트리지,Grote Zorchlading,Stor Zorch ladning,Ładunek do Dużego Zorchera,Recarga de Zorch Grande,,Încărcătură Mare pentru Zorcher,Заряд большого Зорчера,Велики зорч пуњач,Büyük Zorcher Şarjı -Propulsor Charge,AMMO_ROCKETS,,chex,,Propulzorové náboje,Propulsor ladning,Propeller-Ladung,,Zorĉpropulsilo-ŝarĝo,Carga de Propulsor de Zorch ,,Työntimen varaus,Charge de Propulseur,Hajtómű töltet,Ricarica Propulsore,プロパルサー ほきゅう,저치 추진료,Propulsorlading,Propulsor ladning,Ładunek do Pędnika,Recarga de Propulsor de Zorch,,Încărcătură pentru Accelerator,Заряд ускорителя,Погонски зорч пуњач,İtici Şarjı -Phasing Zorcher Charge,AMMO_CELLS,,chex,,Fázovací náboje,Phasing-Zorcher ladning,Phasenzorcher-Ladung,,Fluktuantzorĉilo-ŝarĝo,Carga de Zorcher de Fase,,Vaiheiszorcherin varaus,Charge de Phaseur,Fázisszörcsölő töltet,Ricarica Zorcher di Fase,フェイシング ゾーチャー ほきゅう,저치 전자 충전기,Fasezorcherlading,Phasing-Zorcher ladning,Ładunek do Fazowego Zorchera,Recarga de Zorcher Fásico,,Încărcătură pentru Zorcherul Fazat,Заряд фазерного Зорчера,Фазни зорч пуњач,Zorcher Yükünün Aşamalandırılması -,,Menus,,,,,,,,,,,,,,,,,,,,,,,, -,,Main Menus,,,,,,,,,,,,,,,,,,,,,,,, -New Game,MNU_NEWGAME,,,,Nová hra,Nyt spil,Neues Spiel,Νέο Παιχνίδι,Nova ludado,Nueva partida,,Uusi peli,Nouvelle Partie,Új játék,Nuova partita,新規ゲーム,새로운 게임,Nieuw spel,Nytt spill,Nowa Gra,Novo jogo,,Joc Nou,Новая игра,Нова игра,Yeni Oyun -Options,MNU_OPTIONS,,,,Možnosti,Indstillinger,Optionen,Ρυθμίσεις,Agordoj,Opciones,,Asetukset,Options,Beállítások,Opzioni,オプション,설정,Opties,Alternativer,Opcje,Opções,,Opțiuni,Настройки,Подешавања,Seçenekler -Game Files,MNU_GAMEFILES,,,,Uložené hry,Spilfiler,Spieldateien,Αρχεία Παιχνιδιού,Ludo-dosieroj,Archivos del juego,,Pelitiedostot,Fichiers de jeu,Játékfájlok,File di gioco,ゲームファイル,게임 파일,Spelbestanden,Spillfiler,Pliki Gry,Jogos salvos,Jogos Gravados,Fișiere Joc,Файлы игры,Фајлови игре,Oyun Dosyaları -Info,MNU_INFO,,,,Informace,Info,Informationen,Πληροφορίες,Informoj,Información,,Tiedot,Info,Információ,Informazioni,情報,정보,Info,Info,Info,Informações,,Info,Информация,Подаци,Bilgi -Quit Game,MNU_QUITGAME,,,,Ukončit hru,Afslut spil,Spiel verlassen,Έξοδος,Forlasi ludon,Salir del juego,,Lopeta peli,Quitter le jeu,Kilépés,Esci dal gioco,終了,게임 종료,Verlaat spel,Avslutt spill,Wyjdź z Gry,Sair,,Ieșire din Joc,Выход из игры,Заврши игру,Oyundan Çık -Choose Skill Level:,MNU_CHOOSESKILL,This text is extremely space limited!,,,Vyber obtížnost:,Vælg færdighedsniveau:,Schwierigkeitsgrad:,Επίλεξε ΔυσκολΊα:,Elektu malfacilecon:,Elige nivel de dificultad:,,Valitse vaikeustaso:,Difficulté:,Nehézségi szint:,Livello di difficoltà:,実力を選べ:,난이도를 고르시오:,Vaardigheidsniveau:,Velg ferdighetsnivå:,Poziom Trudności:,Escolha o nível de dificuldade:,,Alege Dificultatea:,Уровень сложности:,Ниво тежине:,Beceri Seviyesini Seçin: -I'm too young to die.,SKILL_BABY,,,,Ještě nechci umřít.,Jeg er for ung til at dø.,Ich bin zu jung zum Sterben.,Είμαι πολύ νεαρός για να πεθάνω!,Mi tro junas por morti.,Soy muy joven para morir.,,Olen liian nuori kuolemaan.,Trop jeune pour mourir!,Kicsi vagyok még a halálhoz.,Troppo giovane per morire.,死ぬには若すぎる,난 죽기엔 너무 젊어.,Ik ben te jong om te sterven.,Jeg er for ung til å dø.,Jestem za młody by umierać.,Sou jovem demais para morrer.,Demasiado novo para morrer.,Sunt prea tânăr ca să mor.,Мне рано умирать.,Премлад сам да умрем.,Ölmek için çok gencim. -"Hey, not too rough.",SKILL_EASY,,,,"Hej, ne tak tvrdě.","Hey, ikke for hårdt.","He, nicht so ruppig.",Όχι πολύ δύσκολο,"He, ne tro malafable.","Oye, no seas tan duro.",,"Hei, ei liian kovaa.","Hé, pas trop fort!","Hé, ne túl erősen!","Ehi, non troppo duro!",あまり激しくするな,너무 세게 하지는 마.,"Hé, niet te ruw.","Hei, ikke for hardhendt.","Hej, nie tak mocno.","Opa, pega leve aí.","Ei, mais devagar.","Hei, nu foarte dur.","Эй, не слишком грубо.","Хеј, не претерано грубо.",Çok sert değil. -Hurt me plenty.,SKILL_NORMAL,,,,Pojď do mě.,Gør mig rigeligt ondt.,Tu mir weh.,Πόνεσε με,Vundu min multe.,Hazme mucho daño.,,Satuta minua kunnolla.,Fais-moi mal!,Adjál bőven!,Fammi molto male.,手加減無用,마음껏 때려봐.,Doe me veel pijn.,Skader meg mye.,Dowal mi.,Vem com tudo.,Dá-me com força.,Rănește-mă din plin.,Сделай мне больно.,Повреди ме кол'ко можеш.,Beni çok incittin. -Ultra-Violence.,SKILL_HARD,,,,Ultrařežba.,Ultra-vold.,Volle Gewalt.,Ύπερ-Βία,Ekstrema perforto.,Ultraviolencia.,,Ultraväkivalta.,Ultra-Violence!,Ultraerőszak!,Ultra-violenza.,ウルトラ バイオレンス,극단적인-폭력.,Ultra Geweld.,Ultra-vold.,Ultra-Przemoc.,Ultraviolência.,,Ultra-Violență.,Ультранасилие.,Ултра-насилно.,Ultra Şiddet. -Nightmare!,SKILL_NIGHTMARE,,,,Noční můra!,Mareridt!,Alptraum!,Εφιάλτης!,Inkubo!,¡Pesadilla!,,Painajainen!,Cauchemar!,Rémálom!,Incubo!,悪夢だ!,악몽!,Nachtmerrie!,Mareritt!,Koszmar!,Pesadelo!,,Coșmar!,Кошмар!,Ноћна мора!,Kabus! -Easy does it,CSKILL_BABY,,,,Hezky zlehka,Let gør det,Immer sachte,,Kvietiĝu,Así de fácil,,Hiljaa hyvä tulee,On y va Doucement,Csak gyengéden.,Facile no?,やさしくして,살살 하면 좋겠네,Gemakkelijk doet het,Rolig nå,Łatwizna,Vamos com calma,,Merge ușor,Потихоньку-полегоньку,Лагано сад,Sakin ol. +Invincible Mode ON,STSTR_DQDON,,chex,,Režim nezranitelnosti ZAP,Uovervindelig tilstand TIL,Unbesiegbarer Modus EIN,,Nevenkebla-reĝimo ŜALTITA,Modo invencible ACTIVADO,,Kuolemattomuustila PÄÄLLÄ,Mode invincible ON,Sérthetetlen mód BE,Modalità invincibile attivata,むてきモード オン,무적 모드 켬,Onoverwinnelijke modus AAN,Uovervinnelig modus PÅ,Tryb Niewrażliwości WŁĄCZONY,Modo invencível ATIVADO,,Modul Invincibil ACTIVAT,Режим неуязвимости ВКЛЮЧЁН,Неуништив УКЉУЧЕН,Oövervinnerligt läge på,Yenilmez Mod AÇIK +Invincible Mode OFF,STSTR_DQDOFF,,chex,,Režim nezranitelnosti VYP,Uovervindelig tilstand FRA,Unbesiegbarer Modus AUS,,Nevenkebla-reĝimo MALŜALTITA,Modo invencible DESACTIVADO,,Kuolemattomuustila POIS PÄÄLLÄ,Mode invincible OFF,Sérthetetlen mód KI,Modalità invincibile disattivata,むてきモード オフ,무적 모드 끔,Onoverwinnelijke modus UIT,Uovervinnelig modus AV,Tryb Niewrażliwości WYŁĄCZONY,Modo invencível DESATIVADO,,Modul Invincibil DEZACTIVAT,Режим неуязвимости ОТКЛЮЧЁН,Неуништив ИСКЉУЧЕН,Oövervinnerligt läge av,Yenilmez Modu KAPALI +Zorch Added,STSTR_FAADDED,,chex,,Bzukry přidány,Zorch tilføjet,Zorch hinzugefügt,,Zorĉo Aldonita,Zorch añadido,,Zorch lisätty,Zorch Ajouté,Szörcs felvéve,Zorch aggiunto,ゾーチ ついか,모든 저치 에너지 추가,Zorch toegevoegd,Zorch lagt til,Zorch dodany,Zorch adicionado,,Zorcher Adăugat,Получен зорч,Зорч додат,Zorch har lagts till,Zorch Eklendi +Super Zorch Added,STSTR_KFAADDED,,chex,,Superbzukry přidány,Super Zorch Tilføjet,Super Zorch hinzugefügt,,Supera Zorĉo Aldonita,Súper Zorch añadido,,Superzorch lisätty,Super Zorch Ajouté,Szuper Szörcs feléve,Super Zorch aggiunto,スーパーゾーチ ついか,모든 아이템 습득!,Super Zorch toegevoegd,Super Zorch lagt til,Super Zorch dodany,Super Zorch adicionado,,Super Lingură Adăugată,Получен суперзорч,Супер зорч додат,Super Zorch läggs till,Süper Zorch Eklendi +... Eat Chex(R)!,STSTR_CHOPPERS,,chex,,... Jez Chex(R)!,... Spis Chex(R)!,...Iss Chex(R)!,,... Manĝu Chex(R)-on!,... Come Chex(R),,... Syö Chex(R):ä!,... Mangez du Chex(R)!,...egyél Chex(R)-et!,... Mangia I Chex(R)!,...Chex(R)をたべよう!,... 첵스(R) 를 많이 먹자!,... Eet Chex(R)!,... Spis Chex(R)!,... jedz płatki Chex(R)!,... coma Chex(R)!,,... Mănâncă Chex(R)!,...ешь Chex(R)!,... Једи Chex(R)!,... Ät Chex(R)!,... Chex(R) yiyin! +Mini Zorch Charge,AMMO_CLIP,,chex,,Minibzukrové náboje,Mini Zorch ladning,Minizorcher-Ladung,,Zorĉileto-Ŝarĝo,Carga de Mini Zorch,,Minizorchvaraus,Charge Zorch,Mini szörcs töltet,Ricarica Mini Zorch,ミニゾーチ ほきゅう,소형 저치 전지,Mini Zorchlading,Mini Zorch ladning,Mini Ładunek Zorch,Recarga de Mini Zorch,,Mini Încărcătură pentru Zorcher,Заряд мини-зорчера,Мини зорч пуњач,,Mini Zorch Şarjı +Large Zorcher Charge,AMMO_SHELLS,,chex,,Velkobzukrové náboje,Stor Zorch ladning,Zorcher-Ladung,,Ŝarĝo por Granda Zorĉilo,Carga de Zorcher Grande,,Ison zorcherin varaus,Charge de Zorcheur Large,Nagy szörcs töltet,Ricarica Grande Zorch,ラージゾーチャー ほきゅう,대형 저치 카트리지,Grote Zorchlading,Stor Zorch ladning,Ładunek do Dużego Zorchera,Recarga de Zorch Grande,,Încărcătură Mare pentru Zorcher,Заряд большого зорчера,Велики зорч пуњач,Stor Zorch-laddning,Büyük Zorcher Şarjı +Propulsor Charge,AMMO_ROCKETS,,chex,,Propulzorové náboje,Propulsor ladning,Propeller-Ladung,,Zorĉpropulsilo-ŝarĝo,Carga de Propulsor de Zorch ,,Työntimen varaus,Charge de Propulseur,Hajtómű töltet,Ricarica Propulsore,プロパルサー ほきゅう,저치 추진료,Propulsorlading,Propulsor ladning,Ładunek do Pędnika,Recarga de Propulsor de Zorch,,Încărcătură pentru Accelerator,Заряд ускорителя,Погонски зорч пуњач,Propulsor-laddning,İtici Şarjı +Phasing Zorcher Charge,AMMO_CELLS,,chex,,Fázovací náboje,Phasing-Zorcher ladning,Phasenzorcher-Ladung,,Fluktuantzorĉilo-ŝarĝo,Carga de Zorcher de Fase,,Vaiheiszorcherin varaus,Charge de Phaseur,Fázisszörcsölő töltet,Ricarica Zorcher di Fase,フェイシング ゾーチャー ほきゅう,저치 전자 충전기,Fasezorcherlading,Phasing-Zorcher ladning,Ładunek do Fazowego Zorchera,Recarga de Zorcher Fásico,,Încărcătură pentru Zorcherul Fazat,Заряд фазерного зорчера,Фазни зорч пуњач,Zorcher-laddning för fasning,Zorcher Yükünün Aşamalandırılması +,,Menus,,,,,,,,,,,,,,,,,,,,,,,,, +,,Main Menus,,,,,,,,,,,,,,,,,,,,,,,,, +New Game,MNU_NEWGAME,,,,Nová hra,Nyt spil,Neues Spiel,Νέο Παιχνίδι,Nova ludado,Nueva partida,,Uusi peli,Nouvelle Partie,Új játék,Nuova partita,新規ゲーム,새로운 게임,Nieuw spel,Nytt spill,Nowa Gra,Novo jogo,,Joc Nou,Новая игра,Нова игра,Nytt spel,Yeni Oyun +Options,MNU_OPTIONS,,,,Možnosti,Indstillinger,Optionen,Ρυθμίσεις,Agordoj,Opciones,,Asetukset,Options,Beállítások,Opzioni,オプション,설정,Opties,Alternativer,Opcje,Opções,,Opțiuni,Настройки,Подешавања,Alternativ,Seçenekler +Game Files,MNU_GAMEFILES,,,,Uložené hry,Spilfiler,Spieldateien,Αρχεία Παιχνιδιού,Ludo-dosieroj,Archivos del juego,,Pelitiedostot,Fichiers de jeu,Játékfájlok,File di gioco,ゲームファイル,게임 파일,Spelbestanden,Spillfiler,Pliki Gry,Jogos salvos,Jogos Gravados,Fișiere Joc,Файлы игры,Фајлови игре,Spelfiler,Oyun Dosyaları +Info,MNU_INFO,,,,Informace,,Informationen,Πληροφορίες,Informoj,Información,,Tiedot,,Információ,Informazioni,情報,정보,,,,Informações,,,Информация,Подаци,,Bilgi +Quit Game,MNU_QUITGAME,,,,Ukončit hru,Afslut spil,Spiel verlassen,Έξοδος,Forlasi ludon,Salir del juego,,Lopeta peli,Quitter le jeu,Kilépés,Esci dal gioco,終了,게임 종료,Verlaat spel,Avslutt spill,Wyjdź z Gry,Sair,,Ieșire din Joc,Выход из игры,Заврши игру,Avsluta spelet,Oyundan Çık +Choose Skill Level:,MNU_CHOOSESKILL,This text is extremely space limited!,,,Vyber obtížnost:,Vælg færdighedsniveau:,Schwierigkeitsgrad:,Επίλεξε ΔυσκολΊα:,Elektu malfacilecon:,Elige nivel de dificultad:,,Valitse vaikeustaso:,Difficulté:,Nehézségi szint:,Livello di difficoltà:,実力を選べ:,난이도를 고르시오:,Vaardigheidsniveau:,Velg ferdighetsnivå:,Poziom Trudności:,Escolha o nível de dificuldade:,,Alege Dificultatea:,Уровень сложности:,Ниво тежине:,Välj färdighetsnivå:,Beceri Seviyesini Seçin: +I'm too young to die.,SKILL_BABY,,,,Ještě nechci umřít.,Jeg er for ung til at dø.,Ich bin zu jung zum Sterben.,Είμαι πολύ νεαρός για να πεθάνω!,Mi tro junas por morti.,Soy muy joven para morir.,,Olen liian nuori kuolemaan.,Trop jeune pour mourir!,Kicsi vagyok még a halálhoz.,Troppo giovane per morire.,死ぬには若すぎる,난 죽기엔 너무 젊어.,Ik ben te jong om te sterven.,Jeg er for ung til å dø.,Jestem za młody by umierać.,Sou jovem demais para morrer.,Demasiado novo para morrer.,Sunt prea tânăr ca să mor.,Мне рано умирать.,Премлад сам да умрем.,Jag är för ung för att dö.,Ölmek için çok gencim. +"Hey, not too rough.",SKILL_EASY,,,,"Hej, ne tak tvrdě.","Hey, ikke for hårdt.","He, nicht so ruppig.",Όχι πολύ δύσκολο,"He, ne tro malafable.","Oye, no seas tan duro.",,"Hei, ei liian kovaa.","Hé, pas trop fort!","Hé, ne túl erősen!","Ehi, non troppo duro!",あまり激しくするな,너무 세게 하지는 마.,"Hé, niet te ruw.","Hei, ikke for hardhendt.","Hej, nie tak mocno.","Opa, pega leve aí.","Ei, mais devagar.","Hei, nu foarte dur.","Эй, не слишком грубо.","Хеј, не претерано грубо.",Inte alltför grovt.,Çok sert değil. +Hurt me plenty.,SKILL_NORMAL,,,,Pojď do mě.,Gør mig rigeligt ondt.,Tu mir weh.,Πόνεσε με,Vundu min multe.,Hazme mucho daño.,,Satuta minua kunnolla.,Fais-moi mal!,Adjál bőven!,Fammi molto male.,手加減無用,마음껏 때려봐.,Doe me veel pijn.,Skader meg mye.,Dowal mi.,Vem com tudo.,Dá-me com força.,Rănește-mă din plin.,Сделай мне больно.,Повреди ме кол'ко можеш.,Gör mig mycket illa.,Beni çok incittin. +Ultra-Violence.,SKILL_HARD,,,,Ultrařežba.,Ultra-vold.,Volle Gewalt.,Ύπερ-Βία,Ekstrema perforto.,Ultraviolencia.,,Ultraväkivalta.,Ultra-Violence!,Ultraerőszak!,Ultra-violenza.,ウルトラ バイオレンス,극단적인-폭력.,Ultra Geweld.,Ultra-vold.,Ultra-Przemoc.,Ultraviolência.,,Ultra-Violență.,Ультранасилие.,Ултра-насилно.,Ultra-våld.,Ultra Şiddet. +Nightmare!,SKILL_NIGHTMARE,,,,Noční můra!,Mareridt!,Alptraum!,Εφιάλτης!,Inkubo!,¡Pesadilla!,,Painajainen!,Cauchemar!,Rémálom!,Incubo!,悪夢だ!,악몽!,Nachtmerrie!,Mareritt!,Koszmar!,Pesadelo!,,Coșmar!,Кошмар!,Ноћна мора!,Mardröm!,Kabus! +Easy does it,CSKILL_BABY,,,,Hezky zlehka,Let gør det,Immer sachte,,Kvietiĝu,Así de fácil,,Hiljaa hyvä tulee,On y va Doucement,Csak gyengéden.,Facile no?,やさしくして,살살 하면 좋겠네,Gemakkelijk doet het,Rolig nå,Łatwizna,Vamos com calma,,Merge ușor,Потихоньку-полегоньку,Лагано сад,Det är lätt att göra det.,Sakin ol. Not so sticky,CSKILL_EASY,,,,Ne tak ulepeně,Ikke så klistret,Nicht so schmierig,,Ne tiel glueca,No tan pegajoso,,Ei niin tahmaista,Pas trop Collant,Ne túl ragadósan!,"Non così appiccicoso -",ダラダラしない,질척하진 않게,Niet zo plakkerig.,Ikke så klissete,Nie tak lepko,Não tão gosmento,,Nu așa de lipicios,Не особо липко,Не тако лепљиво,Çok yapışkan değil +",ダラダラしない,질척하진 않게,Niet zo plakkerig.,Ikke så klissete,Nie tak lepko,Não tão gosmento,,Nu așa de lipicios,Не особо липко,Не тако лепљиво,Inte så klibbigt,Çok yapışkan değil Gobs of goo,CSKILL_NORMAL,,,,Hafo hlenu,Masser af klister,Schleimklumpen,,Buloj de muko,Montón de moco,,Limaklönttejä,Des Tonnes de Gelée,Egy csomó trutymó,Sputi di sostanza,"カッチカチスライム -",적지 않은 질퍽함,brokken slijm,Klumper av klister,Maziste Gęby,Um montão de meleca,Um montão de ranho,Multă mâzgă,Масса слизи,Лопте љиге,Çok fazla çamur +",적지 않은 질퍽함,brokken slijm,Klumper av klister,Maziste Gęby,Um montão de meleca,Um montão de ranho,Multă mâzgă,Масса слизи,Лопте љиге,Massor av kladd,Çok fazla çamur Extreme Ooze,CSKILL_HARD,,,,Extra bláto,Ekstrem slim,Extrem glitschig,,Ekstrema pusado,Goteo extremo,,Äärimmäisen mönjäistä,Extrêmement Gluant,Extrém nyúlós,Melma estrema,"かげきなウーズ -",엄청난 끈끈함,Uiterst glibberig,Ekstrem slim,Ekstremalny Muł,Gosma ao extremo,,Noroi Extrem,Экстремальная грязь,Екстремно љигаво,Aşırı Sızıntı -Super Slimey!,CSKILL_NIGHTMARE,,,,Superslizké!,Super slimet!,Super schleimig!,,Tre ŝlima!,¡Súper viscoso!,,Superlimaista!,Carrément Crade!,Szupernyálkás!,Super Viscido!,ちょうベトベト!,끈쩍함 천지!,Super slijmerig!,Super slimete!,Super Oślizgły!,Super Gosmento!,,Super Mâzgos!,Сверхсклизский!,СУПЕР ЉИГАВО,Süper yapışkan! -Training,SSKILL_BABY,,,,Trénink,Træning,,Eκπαίδευση,Trejnado,Práctica,,Koulutus,Entrâinement,Kiképzés,Allenamento,トレーニング,훈련병,Opleiding,Trening,Trening,Treinamento,Treino,În Pregătiri,Разминка,Тренинг,Eğitim -Rookie,SSKILL_EASY,,,,Zelenáč,Nybegynder,Anfänger,Αρχάριος,Komencanto,Novato,,Aloittelija,Recrue,Újonc,Matricola,ルーキー,신병,,Nybegynner,Rekrut,Novato,,Începător,Новичок,Новајлија,Çaylak -Veteran,SSKILL_NORMAL,,,,Veterán,,,,Veterano,Veterano,,Veteraani,Véteran,Veterán,Veterano,ベテラン,고참병,Veteraan,,Weteran,Veterano,,Veteran,Ветеран,Ветеран,Gazi -Elite,SSKILL_HARD,,,,Elita,,,,Elito,Élite,,Eliitti,,Elit,Elite,エリート,정예병,,,Elita,Elite,,Elită,Элита,Елитни,Elit -Bloodbath,SSKILL_NIGHTMARE,,,,Krveřežba,Blodbad,Blutbad,,Sangoverŝado,Baño de sangre,,Verilöyly,Massacre!,Vérfürdő,Bagno di sangue,ブラッドバス,피의 목욕,Bloedbad,Blodbad,Rozlew krwi,Banho de sangue,,Baie de sânge,Кровавая бойня,Купка крви,Kan banyosu -Thou needeth a Wet-Nurse,MNU_WETNURSE,,,,Potřěbuješ krmlici?,Du har brug for en våd sygeplejerske,Wo ist die Krankenschwester?,,Vi nutristinon bezonas,Necesitaréis una nodriza,,Tarvitseos imettäjää,Une Nourrice Vous Voulez,Süldőgyermek,Necessiti di un'infermiera per neonati,汝は乳母を欲する,그대에게는 유모가 필요하다,Waar is de verpleegster?,Du trenger en amme,Wciąż w pieluszkach,Tu precisas de uma Ama-de-Leite,Tu precisas de uma Ama-Seca,Doica are Nevoie de Mine,Нянечка надобна мне,Треба ти бабица,Islak bir hemşireye ihtiyacın var. -Yellowbellies-R-Us,MNU_YELLOWBELLIES,,,,"Nemehla, tož jsme my",,Vereinigte Waschlappen,,Malkuraĝuloj-as-ni,Somos pusilánimes,,Mameronapero,Un Trouillard-Tu-Est,Ne bántsék kend!,Codardo-tu-sei,我等こそが臆病者,장난감을 가지고 노는가,Verenigd washandje,Yellowbellies-R-Us,"Nie książę, lecz tchórz",Tu és um Amarelão,Tu és um Cobardolas,Nu Sunt Așa de Curajos,Не столь мужественен я,Ми-смо-жутица,Birleşik Korkak Kediler -Bringest Them Oneth,MNU_BRINGEST,,,,Chtějúci se práti?,Kom med dem,Her damit,,Al mi ilin kunvenigu,Traédnoslos,,Antaos tullaos,Amenez les moi!,Ide velük hinnye,Portali a me,招かれし者共,혈투를 벌일 준비하라,Geef me dat.,Kom med dem,Dawajże Ich,Podeis Virdes,Podeis Virdes,Aduceți-mi,Подайте мне их,Донеси изабраног,Onları Getir -Thou art a Smite-Meister,MNU_SMITE,,,,Ktož jsú boží bojovníci,Du er mesterdræberen,Du bist der Meistertöter,,Vi Venkobatanto estas,Sois un regicida,,Olet lyömäherra,Tu est Maître-Meurtrier,Csapjunk bele kend!,Sei un maestro assassino,汝は芸術的殺戮者,그대야말로 타격의 대가,Jij bent de meestermoordenaar.,Du er mesterdraperen,Mistrz w swoim fachu,Tu és Mestre-de-Massacres,,Lupta mă Ispitește,Искушён я сражениями,Ти си обузети-мајстор,Sen baş sihirbazsın -Black Plague Possesses Thee,MNU_BLACKPLAGUE,,,,Jsúci Smrtonošem morovým!,Den sorte pest besætter dig,Von der Pest besessen,,Nigra morto vin posedas,La peste negra os posee,,Musta surma on saanut sun,La Peste Noire me Possède!,Ehun gyün a pestis,La peste nera ti possiede,汝に憑した黒死病,흑사병이 그대를 저주 내리리,Geobsedeerd door de pest,Den svarte pesten besetter deg,Sługa Czarnej Plagi,A Peste Negra te Possui,A Peste Negra Possui-te,Ciuma Neagră mă Posedă,Чума овладела мной,Имаш црну кугу,Kara Veba Seni Ele Geçirdi -Squire,MNU_SQUIRE,,,,Panoš,Laird,Gutsherr,,Varleto,Escudero,,Aseenkantaja,Ecuyer,Apród,Scudiero,見習い騎士,향사,Squire,Væpner,Giermek,Escudeiro,,Scutier,Оруженосец,Штитоноша,Beyefendi -Knight,MNU_KNIGHT,,,,Rytíř,Ridder,Ritter,Ιππότης,Kavaliro,Caballero,,Ritari,Chevalier,Lovag,Cavaliere,騎士,기사,Ridder,Ridder,Rycerz,Cavaleiro,,Cavaler,Рыцарь,Витез,Şövalye -Warrior,MNU_WARRIOR,,,,Válečník,Kriger,Krieger,Πολεμιστής,Militisto,Guerrero,,Soturi,Guerrier,Katona,Guerriero,戦士,전사,Krijger,Kriger,Wojownik,Guerreiro,,Războinic,Воитель,Борац,Savaşçı -Berserker,MNU_BERSERKER,,,,Berserkr,,,,Frenezisto,Berserker,,Berserkkeri,,Harcos,Berserker,狂戦士,광전사,Berserker,,Szaleniec,,,Turbat,Берсерк,Делија,Berserker -Titan,MNU_TITAN,,,,Titán,,,Τιτάνας,Titano,Titán,,Titaani,,Titán,Titano,タイタン,철인,Titan,,Tytan,Titã,,Titan,Титан,Титан,Titan -Altar Boy,MNU_ALTARBOY,,,,Ministrant,Alterdreng,Novize,,Messervanto,Monaguillo,,Pyhäkköpoika,Enfant de Chœur,Ministráns,Chirichetto,堂役,복사,Altaarjongen,Altergutt,Ministrant,Menino de coral,Menino do coro,Paracliser,Алтарник,Министрант,Sunak Çocuğu -Acolyte,MNU_ACOLYTE,,,,Akolyta,Akolyt,Missionar,,Akolito,Acólito,,Akoluutti,,Oltárszolga,Accolito,侍祭,시종,Acoliet,Akolytt,Akolita,Coroinha,Acólito,Acolit,Служитель,Помоћник,Yardımcı -Priest,MNU_PRIEST,,,,Kněz,Præst,Priester,,Pastro,Sacerdote,,Pappi,Prêtre,Pap,Prete,司祭,사제,Priester,Prest,Kapłan,Padre,,Preot,Священник,Свештеник,Rahip -Cardinal,MNU_CARDINAL,,,,Kardinál,Kardinal,Kardinal,,Kardinalo,Cardenal,,Kardinaali,,Bíboros,Cardinale,枢機卿,추기경,Kardinaal,Kardinal,Kardynał,Cardeal,,Cardinal,Кардинал,Кардинал,Kardinal -Pope,MNU_POPE,,,,Papež,Pave,Papst,Πάπας,Papo,Papa,,Paavi,Pape,Pápa,Papa,教皇,교황,Paus,Pave,Papież,Papa,,Papă,Епископ,Папа,Papa -Apprentice,MNU_APPRENTICE,,,,Učeň,Lærling,Lehrling,,Lernanto,Aprendiz,,Kisälli,Apprenti,Tanonc,Apprendista,入門者,조수,Leerling,Lærling,Uczeń,Aprendiz,,Ucenic,Ученик,Шегрт,Çırak -Enchanter,MNU_ENCHANTER,,,,Kouzelník,Fortryller,Zauberer,,Ravisto,Encantador,,Lumooja,Enchanteur,Bűvölő,Incantatore,妖術士,주술사,Betoveraar,Trollmann,Zaklinacz,Encantador,,Fermecător,Чародей,Чаробњак,Sihirbaz -Sorcerer,MNU_SORCERER,,,,Čaroděj,Troldmand,Hexer,,Sorĉisto,Hechicero,,Taikuri,Sorcier,Varázsló,Mago,魔術士,마법사,Tovenaar,Magiker,Mag,Feiticeiro,,Mag,Колдун,Врачар,Büyücü -Warlock,MNU_WARLOCK,,,,Zaklínač,,Hexenmeister,,Magiisto,Brujo,,Noita,Mage de Guerre,Boszorkánymester,Stregone,黒魔術士,전투술사,Tovenaar,Veiviser,Wiedźmak,Mago,,Vrăjitor,Чернокнижник,Вештац,Efsuncu -Archmage,MNU_ARCHMAGE,,,,Arcimág,Ærkemagiker,Erzmagier,,Magiantestro,Archimago,,Arkkivelho,Archimage,Főmágus,Arcimago,大魔導師,대마법사,Aartsbisschop,Erkemagiker,Arcymag,Arquimago,,Prim-Vrăjitor,Архимаг,Врховни вештац,Başbüyücü -Choose Class:,MNU_CHOOSECLASS,,,,Vyber třídu:,Vælg klasse:,Figurengruppe wählen:,,Elektu klason:,Elige tu clase:,,Valitse luokka:,Choissisez une Classe:,Válassz kasztot:,Scegli la classe:,クラス選抜:,영웅 선택:,Kies klasse:,Velg klasse:,Wybierz klasę:,Escolha a classe:,,Alege Clasa:,Класс:,Класа:,Sınıf seç: -Fighter,MNU_FIGHTER,,,,Bojovník,Kriger,Krieger,,Batalanto,Luchador,,Taistelija,Guerrier,Harcos,Combattente,戦士,전사,Vechter,Kriger,Wojownik,Lutador,,Luptător,Воин,Борац,Dövüşçü -Cleric,MNU_CLERIC,,,,Klerik,Kleriker,Geistlicher,,Kleriko,Clérigo,,Pappi,Moine,Lelkész,Chierico,僧侶,성직자,Geestelijk,Kleriker,Kleryk,Clérigo,,,Клерик,Свештеник,Ruhban -Mage,MNU_MAGE,,,,Mág,Mage,Magier,,Magianto,Mago,,Velho,,Mágus,Mago,魔導士,마법사,Tovenaar,Magiker,Mag,Mago,,Magician,Маг,Чаробњак,Sihirbaz -Random,MNU_RANDOM,,,,Náhodný,Tilfældig,Zufällig,,Hazarda,Al azar,,Satunnainen,Au Hasard,Véletlenszerű,Casuale,ランダム,랜덤,Willekeurig,Tilfeldig,Losowa,Aleatório,,Aleatoriu,Наугад,Насумично,Rastgele -Which Episode?,MNU_EPISODE,,,,Jakou epizodu?,Hvilken episode?,Welche Episode?,,Kiu epizodo?,¿Qué episodio?,,Mikä episodi?,Quel épisode?,Melyik epizód?,Quale episodio?,どのエピソードだ?,에피소드 선택:,Welke aflevering?,Hvilken episode?,Który Epizod?,Qual Episódio?,,Care Episod?,Какой эпизод?,Која епизода?,Hangi Bölüm? -Choose Campaign,MNU_EPISODE,,strife,,Vyber kampaň,Vælg kampagne,Mission auswählen,,Elektu kampanjon,Selecciona una campaña,,Valitse kampanja,Choisissez la Campagne,Válassz hadjáratot,Scegli la campagna,キャンペーンを選べ,캠페인을 고르시오:,Kies campagne,Velg kampanje,Wybierz kampanię,Escolha a Campanha,,Alege Campania,Выбор кампании,Изабери кампању,Kampanyayı Seçin -City of the Damned,MNU_COTD,,,,Město zatracených,Byen af de forbandede,Stadt der Verdammten,,Urbo de la damnitaj,Ciudad de los condenados,,Kirottuin kaupunki,La Cité des Damnés,Az átkozottak városa,Città del dannato,呪われた都,멸망한 도시,Stad van de verdoemden,De fordømtes by,Miasto Przeklętych,Cidade dos Condenados,,Orașul Blestemaților,Город проклятых,Град проклетих,Lanetliler Şehri -Hell's Maw,MNU_HELLSMAW,,,,Chřtán pekel,Helvedes gab,Der Schlund zur Hölle,,Faŭko de Infero,Fauces del infierno,,Hornankita,La Geule des Enfers,A Pokol bugyrai,Lo Stomaco dell'Inferno,地獄の肚,지옥의 목구멍,De slokdarm naar de hel,Helvetes gap,Paszcza Piekieł,A Boca do Inferno,,Străfundurile Infernului,Адское жерло,Чељусти пакла,Cehennem Ağzı -The Dome of D'Sparil,MNU_DOME,,,,Báň D'Sparilova,D'Sparils kuppel,D'Sparils Dom,,La Kupolo de D'Sparil,La Cúpula de D'Sparil,El Domo de D'Sparil,D'Sparilin kupoli,Le Dôme de D'Sparil,D'Sparil kupolája,La Casa del D'Sparil,デ'スパリルの穹窿,드'스파릴의 돔,D'Sparils Kathedraal,D'Sparils kuppel,Gmach D'Sparila,A Cúpula de D'Sparil,,Domul lui D'Sparil,Купол Д'Спарила,Купола Д'Спарила,D'Sparil'in Kubbesi -The Ossuary,MNU_OSSUARY,,,,Kostnice,Benhuset,Das Beinhaus,,La Ostejo,El Osario,,Luuhuone,L'Ossuaire,Csontkamra,L'Ossario,納骨堂,납골당,Het Ossuarium,Beinhuset,Kostnica,O Ossuário,O Ossário,Osuarul,Склеп,Костурница,Mezar Odası -The Stagnant Demesne,MNU_DEMESNE,,,,Zatuchlé panství,Den stagnerede demesne,Das stagnierende Reich,,La Senmova Posedaĵo,La Heredad Estancada,,Seisahtunut maa,Le domaine Stagnant,A pangó birtok,La Proprietà terriera Stagnante,澱んだ荘園,침체된 영지,Het stagnerende rijk,Den stillestående herregården,Opuszczone Włości,O Reino Estagnado,,Tărâmul Stagnării,Застойная Демесна,Стагнирајући домени,Durgun Diyar -,,Gameplay menus,,,,,,,,,,,,,,,,,,,,,,,, -Teamplay,GMPLYMNU_TEAMPLAY,,,,Týmová hra,,Teamspiel,,Teamludado,Juego por equipos,,Joukkuepeli,Jeu en équipe,Csapatjáték,Gioco di squadra,チーム制,팀플레이,Teamplay,Lagspill,Gra Drużynowa,Jogo em equipe,Jogo em Equipa,Joc în Echipă,Командная игра,Тимска игра,Takım Oyunu -Team damage scalar,GMPLYMNU_TEAMDAMAGE,,,,Faktor týmového poškození,Skala for holdskader,Team-Schadenfaktor,,Teamdamaĝo-skalio,Escalar de daño del equipo,,Omien tulen vahinkokerroin,Facteur de Tir Fratricide,Csapatsebzés mértéke,Fattore danno da fuoco amico,チームメンバーへのダメージ倍率,팀 데미지 배율,Teamschade scalair,Skalar for lagskade,Skalar Obrażeń Drużyny,Escala de fogo amigo,,Multiplicator daune,Множитель урона по своим,Мултипликатор пријатељске ватре,Takım hasar skalası -Smart Autoaim,GMPLYMNU_SMARTAUTOAIM,,,,Chytré automatické zaměřování,Intelligent Autoaim,Intelligente Zielautomatik,,Inteligenta Celasisto,Autoapuntado inteligente,,Älykäs automaattitähtäys,Autovisée intelligente,Okos automata célzás,Mira automatica intelligente,スマートオートエイム,정확한 자동 조준,Slimme Autoaim,Smart Autoaim,Mądre Autocelowanie,Mira automática inteligente,,Asistare inteligentă la țintire,Умное автоприцеливание,Паметни нишан,Akıllı Autoaim -Falling damage,GMPLYMNU_FALLINGDAMAGE,,,,Zranění pádem,Faldskader,Fallschaden,,Faldamaĝo,Daño por caída,,Putoamisvahinko,Dommages de chute,Eséskor sebzés,Danno da caduta,落下ダメージ,낙하 데미지,Vallende schade,Fallende skade,Obrażenia przy upadku,Dano de queda,,Daune la căderi libere,Урон от падения,Штета од пада,Düşme hasarı +",엄청난 끈끈함,Uiterst glibberig,Ekstrem slim,Ekstremalny Muł,Gosma ao extremo,,Noroi Extrem,Экстремальная грязь,Екстремно љигаво,Extremt slemmigt,Aşırı Sızıntı +Super Slimey!,CSKILL_NIGHTMARE,,,,Superslizké!,Super slimet!,Super schleimig!,,Tre ŝlima!,¡Súper viscoso!,,Superlimaista!,Carrément Crade!,Szupernyálkás!,Super Viscido!,ちょうベトベト!,끈쩍함 천지!,Super slijmerig!,Super slimete!,Super Oślizgły!,Super Gosmento!,,Super Mâzgos!,Сверхсклизский!,СУПЕР ЉИГАВО,Super slemmig!,Süper yapışkan! +Training,SSKILL_BABY,,,,Trénink,Træning,,Eκπαίδευση,Trejnado,Práctica,,Koulutus,Entrâinement,Kiképzés,Allenamento,トレーニング,훈련병,Opleiding,Trening,Trening,Treinamento,Treino,În Pregătiri,Разминка,Тренинг,Träning,Eğitim +Rookie,SSKILL_EASY,,,,Zelenáč,Nybegynder,Anfänger,Αρχάριος,Komencanto,Novato,,Aloittelija,Recrue,Újonc,Matricola,ルーキー,신병,,Nybegynner,Rekrut,Novato,,Începător,Новичок,Новајлија,Nybörjare,Çaylak +Veteran,SSKILL_NORMAL,,,,Veterán,,,,Veterano,Veterano,,Veteraani,Véteran,Veterán,Veterano,ベテラン,고참병,Veteraan,,Weteran,Veterano,,,Ветеран,Ветеран,,Gazi +Elite,SSKILL_HARD,,,,Elita,,,,Elito,Élite,,Eliitti,,Elit,,エリート,정예병,,,Elita,,,Elită,Элита,Елитни,,Elit +Bloodbath,SSKILL_NIGHTMARE,,,,Krveřežba,Blodbad,Blutbad,,Sangoverŝado,Baño de sangre,,Verilöyly,Massacre!,Vérfürdő,Bagno di sangue,ブラッドバス,피의 목욕,Bloedbad,Blodbad,Rozlew krwi,Banho de sangue,,Baie de sânge,Кровавая бойня,Купка крви,Blodbad,Kan banyosu +Thou needeth a Wet-Nurse,MNU_WETNURSE,,,,Potřěbuješ krmlici?,Du har brug for en våd sygeplejerske,Wo ist die Krankenschwester?,,Vi nutristinon bezonas,Necesitaréis una nodriza,,Tarvitseos imettäjää,Une Nourrice Vous Voulez,Süldőgyermek,Necessiti di un'infermiera per neonati,汝は乳母を欲する,그대에게는 유모가 필요하다,Waar is de verpleegster?,Du trenger en amme,Wciąż w pieluszkach,Tu precisas de uma Ama-de-Leite,Tu precisas de uma Ama-Seca,Doica are Nevoie de Mine,Нянечка надобна мне,Треба ти бабица,Du behöver en våtsjuksköterska,Islak bir hemşireye ihtiyacın var. +Yellowbellies-R-Us,MNU_YELLOWBELLIES,,,,"Nemehla, tož jsme my",,Vereinigte Waschlappen,,Malkuraĝuloj-as-ni,Somos pusilánimes,,Mameronapero,Un Trouillard-Tu-Est,Ne bántsék kend!,Codardo-tu-sei,我等こそが臆病者,장난감을 가지고 노는가,Verenigd washandje,Yellowbellies-R-Us,"Nie książę, lecz tchórz",Tu és um Amarelão,Tu és um Cobardolas,Nu Sunt Așa de Curajos,Не столь мужественен я,Ми-смо-жутица,Förenade ynkryggar,Birleşik Korkak Kediler +Bringest Them Oneth,MNU_BRINGEST,,,,Chtějúci se práti?,Kom med dem,Her damit,,Al mi ilin kunvenigu,Traédnoslos,,Antaos tullaos,Amenez les moi!,Ide velük hinnye,Portali a me,招かれし者共,혈투를 벌일 준비하라,Geef me dat.,Kom med dem,Dawajże Ich,Podeis Virdes,Podeis Virdes,Aduceți-mi,Подайте мне их,Донеси изабраног,Ta med dem in,Onları Getir +Thou art a Smite-Meister,MNU_SMITE,,,,Ktož jsú boží bojovníci,Du er mesterdræberen,Du bist der Meistertöter,,Vi Venkobatanto estas,Sois un regicida,,Olet lyömäherra,Tu est Maître-Meurtrier,Csapjunk bele kend!,Sei un maestro assassino,汝は芸術的殺戮者,그대야말로 타격의 대가,Jij bent de meestermoordenaar.,Du er mesterdraperen,Mistrz w swoim fachu,Tu és Mestre-de-Massacres,,Lupta mă Ispitește,Искушён я сражениями,Ти си обузети-мајстор,Du är en Mästerdödare,Sen baş sihirbazsın +Black Plague Possesses Thee,MNU_BLACKPLAGUE,,,,Jsúci Smrtonošem morovým!,Den sorte pest besætter dig,Von der Pest besessen,,Nigra morto vin posedas,La peste negra os posee,,Musta surma on saanut sun,La Peste Noire me Possède!,Ehun gyün a pestis,La peste nera ti possiede,汝に憑した黒死病,흑사병이 그대를 저주 내리리,Geobsedeerd door de pest,Den svarte pesten besetter deg,Sługa Czarnej Plagi,A Peste Negra te Possui,A Peste Negra Possui-te,Ciuma Neagră mă Posedă,Чума овладела мной,Имаш црну кугу,Svarta pesten besitter dig,Kara Veba Seni Ele Geçirdi +Squire,MNU_SQUIRE,,,,Panoš,Laird,Gutsherr,,Varleto,Escudero,,Aseenkantaja,Ecuyer,Apród,Scudiero,見習い騎士,향사,,Væpner,Giermek,Escudeiro,,Scutier,Оруженосец,Штитоноша,,Beyefendi +Knight,MNU_KNIGHT,,,,Rytíř,Ridder,Ritter,Ιππότης,Kavaliro,Caballero,,Ritari,Chevalier,Lovag,Cavaliere,騎士,기사,Ridder,Ridder,Rycerz,Cavaleiro,,Cavaler,Рыцарь,Витез,Riddaren,Şövalye +Warrior,MNU_WARRIOR,,,,Válečník,Kriger,Krieger,Πολεμιστής,Militisto,Guerrero,,Soturi,Guerrier,Katona,Guerriero,戦士,전사,Krijger,Kriger,Wojownik,Guerreiro,,Războinic,Воитель,Борац,Krigare,Savaşçı +Berserker,MNU_BERSERKER,,,,Berserkr,,,,Frenezisto,,,Berserkkeri,,Harcos,,狂戦士,광전사,,,Szaleniec,,,Turbat,Берсерк,Делија,, +Titan,MNU_TITAN,,,,Titán,,,Τιτάνας,Titano,Titán,,Titaani,,Titán,Titano,タイタン,철인,,,Tytan,Titã,,,Титан,Титан,, +Altar Boy,MNU_ALTARBOY,,,,Ministrant,Alterdreng,Novize,,Messervanto,Monaguillo,,Pyhäkköpoika,Enfant de Chœur,Ministráns,Chirichetto,堂役,복사,Altaarjongen,Altergutt,Ministrant,Menino de coral,Menino do coro,Paracliser,Алтарник,Министрант,Altarpojke,Sunak Çocuğu +Acolyte,MNU_ACOLYTE,,,,Akolyta,Akolyt,Missionar,,Akolito,Acólito,,Akoluutti,,Oltárszolga,Accolito,侍祭,시종,Acoliet,Akolytt,Akolita,Coroinha,Acólito,Acolit,Служитель,Помоћник,Akolyt,Yardımcı +Priest,MNU_PRIEST,,,,Kněz,Præst,Priester,,Pastro,Sacerdote,,Pappi,Prêtre,Pap,Prete,司祭,사제,Priester,Prest,Kapłan,Padre,,Preot,Священник,Свештеник,Präst,Rahip +Cardinal,MNU_CARDINAL,,,,Kardinál,Kardinal,Kardinal,,Kardinalo,Cardenal,,Kardinaali,,Bíboros,Cardinale,枢機卿,추기경,Kardinaal,Kardinal,Kardynał,Cardeal,,Cardinal,Кардинал,Кардинал,Kardinal,Kardinal +Pope,MNU_POPE,,,,Papež,Pave,Papst,Πάπας,Papo,Papa,,Paavi,Pape,Pápa,Papa,教皇,교황,Paus,Pave,Papież,Papa,,Papă,Епископ,Папа,Påve,Papa +Apprentice,MNU_APPRENTICE,,,,Učeň,Lærling,Lehrling,,Lernanto,Aprendiz,,Kisälli,Apprenti,Tanonc,Apprendista,入門者,조수,Leerling,Lærling,Uczeń,Aprendiz,,Ucenic,Ученик,Шегрт,Lärling,Çırak +Enchanter,MNU_ENCHANTER,,,,Kouzelník,Fortryller,Zauberer,,Ravisto,Encantador,,Lumooja,Enchanteur,Bűvölő,Incantatore,妖術士,주술사,Betoveraar,Trollmann,Zaklinacz,Encantador,,Fermecător,Чародей,Чаробњак,Magiker,Sihirbaz +Sorcerer,MNU_SORCERER,,,,Čaroděj,Troldmand,Hexer,,Sorĉisto,Hechicero,,Taikuri,Sorcier,Varázsló,Mago,魔術士,마법사,Tovenaar,Magiker,Mag,Feiticeiro,,Mag,Колдун,Врачар,Trollkarl,Büyücü +Warlock,MNU_WARLOCK,,,,Zaklínač,,Hexenmeister,,Magiisto,Brujo,,Noita,Mage de Guerre,Boszorkánymester,Stregone,黒魔術士,전투술사,Tovenaar,Veiviser,Wiedźmak,Mago,,Vrăjitor,Чернокнижник,Вештац,Häxkarl,Efsuncu +Archmage,MNU_ARCHMAGE,,,,Arcimág,Ærkemagiker,Erzmagier,,Magiantestro,Archimago,,Arkkivelho,Archimage,Főmágus,Arcimago,大魔導師,대마법사,Aartsbisschop,Erkemagiker,Arcymag,Arquimago,,Prim-Vrăjitor,Архимаг,Врховни вештац,Ärkemagiker,Başbüyücü +Choose Class:,MNU_CHOOSECLASS,,,,Vyber třídu:,Vælg klasse:,Figurengruppe wählen:,,Elektu klason:,Elige tu clase:,,Valitse luokka:,Choissisez une Classe:,Válassz kasztot:,Scegli la classe:,クラス選抜:,영웅 선택:,Kies klasse:,Velg klasse:,Wybierz klasę:,Escolha a classe:,,Alege Clasa:,Класс:,Класа:,Välj klass:,Sınıf seç: +Fighter,MNU_FIGHTER,,,,Bojovník,Kriger,Krieger,,Batalanto,Luchador,,Taistelija,Guerrier,Harcos,Combattente,戦士,전사,Vechter,Kriger,Wojownik,Lutador,,Luptător,Воин,Борац,Kämpe,Dövüşçü +Cleric,MNU_CLERIC,,,,Klerik,Kleriker,Geistlicher,,Kleriko,Clérigo,,Pappi,Moine,Lelkész,Chierico,僧侶,성직자,Geestelijk,Kleriker,Kleryk,Clérigo,,,Клерик,Свештеник,Kleriker,Ruhban +Mage,MNU_MAGE,,,,Mág,,Magier,,Magianto,Mago,,Velho,,Mágus,Mago,魔導士,마법사,Tovenaar,Magiker,Mag,Mago,,Magician,Маг,Чаробњак,Magiker,Sihirbaz +Random,MNU_RANDOM,,,,Náhodný,Tilfældig,Zufällig,,Hazarda,Al azar,,Satunnainen,Au Hasard,Véletlenszerű,Casuale,ランダム,랜덤,Willekeurig,Tilfeldig,Losowa,Aleatório,,Aleatoriu,Наугад,Насумично,Slumpmässig,Rastgele +Which Episode?,MNU_EPISODE,,,,Jakou epizodu?,Hvilken episode?,Welche Episode?,,Kiu epizodo?,¿Qué episodio?,,Mikä episodi?,Quel épisode?,Melyik epizód?,Quale episodio?,どのエピソードだ?,에피소드 선택:,Welke aflevering?,Hvilken episode?,Który Epizod?,Qual Episódio?,,Care Episod?,Какой эпизод?,Која епизода?,Vilken episod?,Hangi Bölüm? +Choose Campaign,MNU_EPISODE,,strife,,Vyber kampaň,Vælg kampagne,Mission auswählen,,Elektu kampanjon,Selecciona una campaña,,Valitse kampanja,Choisissez la Campagne,Válassz hadjáratot,Scegli la campagna,キャンペーンを選べ,캠페인을 고르시오:,Kies campagne,Velg kampanje,Wybierz kampanię,Escolha a Campanha,,Alege Campania,Выбор кампании,Изабери кампању,Välj kampanj,Kampanyayı Seçin +City of the Damned,MNU_COTD,,,,Město zatracených,Byen af de forbandede,Stadt der Verdammten,,Urbo de la damnitaj,Ciudad de los condenados,,Kirottuin kaupunki,La Cité des Damnés,Az átkozottak városa,Città del dannato,呪われた都,멸망한 도시,Stad van de verdoemden,De fordømtes by,Miasto Przeklętych,Cidade dos Condenados,,Orașul Blestemaților,Город проклятых,Град проклетих,De fördömdas stad,Lanetliler Şehri +Hell's Maw,MNU_HELLSMAW,,,,Chřtán pekel,Helvedes gab,Der Schlund zur Hölle,,Faŭko de Infero,Fauces del infierno,,Hornankita,La Geule des Enfers,A Pokol bugyrai,Lo Stomaco dell'Inferno,地獄の肚,지옥의 목구멍,De slokdarm naar de hel,Helvetes gap,Paszcza Piekieł,A Boca do Inferno,,Străfundurile Infernului,Адское жерло,Чељусти пакла,Helvetets gap,Cehennem Ağzı +The Dome of D'Sparil,MNU_DOME,,,,Báň D'Sparilova,D'Sparils kuppel,D'Sparils Dom,,La Kupolo de D'Sparil,La Cúpula de D'Sparil,El Domo de D'Sparil,D'Sparilin kupoli,Le Dôme de D'Sparil,D'Sparil kupolája,La Casa del D'Sparil,デ'スパリルの穹窿,드'스파릴의 돔,D'Sparils Kathedraal,D'Sparils kuppel,Gmach D'Sparila,A Cúpula de D'Sparil,,Domul lui D'Sparil,Купол Д'Спарила,Купола Д'Спарила,D'Sparils kupol,D'Sparil'in Kubbesi +The Ossuary,MNU_OSSUARY,,,,Kostnice,Benhuset,Das Beinhaus,,La Ostejo,El Osario,,Luuhuone,L'Ossuaire,Csontkamra,L'Ossario,納骨堂,납골당,Het Ossuarium,Beinhuset,Kostnica,O Ossuário,O Ossário,Osuarul,Склеп,Костурница,Benhuset,Mezar Odası +The Stagnant Demesne,MNU_DEMESNE,,,,Zatuchlé panství,Den stagnerede demesne,Das stagnierende Reich,,La Senmova Posedaĵo,La Heredad Estancada,,Seisahtunut maa,Le domaine Stagnant,A pangó birtok,La Proprietà terriera Stagnante,澱んだ荘園,침체된 영지,Het stagnerende rijk,Den stillestående herregården,Opuszczone Włości,O Reino Estagnado,,Tărâmul Stagnării,Застойная Демесна,Стагнирајући домени,Den stillastående demesnen,Durgun Diyar +,,Gameplay menus,,,,,,,,,,,,,,,,,,,,,,,,, +Teamplay,GMPLYMNU_TEAMPLAY,,,,Týmová hra,,Teamspiel,,Teamludado,Juego por equipos,,Joukkuepeli,Jeu en équipe,Csapatjáték,Gioco di squadra,チーム制,팀플레이,,Lagspill,Gra Drużynowa,Jogo em equipe,Jogo em Equipa,Joc în Echipă,Командная игра,Тимска игра,,Takım Oyunu +Team damage scalar,GMPLYMNU_TEAMDAMAGE,,,,Faktor týmového poškození,Skala for holdskader,Team-Schadenfaktor,,Teamdamaĝo-skalio,Escalar de daño del equipo,,Omien tulen vahinkokerroin,Facteur de Tir Fratricide,Csapatsebzés mértéke,Fattore danno da fuoco amico,チームメンバーへのダメージ倍率,팀 데미지 배율,Teamschade scalair,Skalar for lagskade,Skalar Obrażeń Drużyny,Escala de fogo amigo,,Multiplicator daune,Множитель урона по своим,Мултипликатор пријатељске ватре,Skador i laget skalar,Takım hasar skalası +Smart Autoaim,GMPLYMNU_SMARTAUTOAIM,,,,Chytré automatické zaměřování,Intelligent Autoaim,Intelligente Zielautomatik,,Inteligenta Celasisto,Autoapuntado inteligente,,Älykäs automaattitähtäys,Autovisée intelligente,Okos automata célzás,Mira automatica intelligente,スマートオートエイム,정확한 자동 조준,Slimme Autoaim,Smart Autoaim,Mądre Autocelowanie,Mira automática inteligente,,Asistare inteligentă la țintire,Умное автоприцеливание,Паметни нишан,Smart Autoaim,Akıllı Autoaim +Falling damage,GMPLYMNU_FALLINGDAMAGE,,,,Zranění pádem,Faldskader,Fallschaden,,Faldamaĝo,Daño por caída,,Putoamisvahinko,Dommages de chute,Eséskor sebzés,Danno da caduta,落下ダメージ,낙하 데미지,Vallende schade,Fallende skade,Obrażenia przy upadku,Dano de queda,,Daune la căderi libere,Урон от падения,Штета од пада,Fallande skador,Düşme hasarı Drop weapon,GMPLYMNU_DROPWEAPON,,,,Odhazování zbraní,Taber våben,Waffen fallen lassen,,Faligi armilon,Arrojar arma,,Aseen pudottaminen,Arme lâchée à la mort,Fegyver eldobása,"Arma lasciata cadere -",死亡時に武器を落とす,무기 버리기,Laat het wapen vallen,Slipp våpen,Wyrzuć broń,Largar arma,,Aruncare armă,Терять оружие,Баци оружје,Silahı bırak -Double ammo,GMPLYMNU_DOUBLEAMMO,,,,Dvojnásobná munice,Dobbelt ammunition,Doppelte Munition,,Duobla municio,Doble munición,,Tupla-ammukset,Double munitions,Dupla muníció,Doppie munizioni,弾2倍,두 배의 탄약,Dubbele munitie,Dobbel ammunisjon,Podwojona amunicja,Munição em dobro,,Muniție dublă,Удвоенные патроны,Дупла муниција,Çift cephane -Infinite ammo,GMPLYMNU_INFINITEAMMO,,,,Nekonečná munice,Uendelig ammunition,Unendlich Munition,,Senlima municio,Munición infinita,,Loppumattomat ammukset,Munitions infinies,Végtelen muníció,Infinite munizioni,弾無限,무한 탄약,Oneindige munitie,Uendelig ammunisjon,Nieskończona amunicja,Munição infinita,,Muniție infinită,Бесконечные патроны,Бесконачна муниција,Sonsuz cephane -Infinite inventory,GMPLYMNU_INFINITEINVENTORY,,,,Nekonečný inventář,Uendelig lagerbeholdning,Unendliche Gegenstände,,Senlima inventaro,Inventario infinito,,Loppumattomat varusteet,Objets infinis,Végtelen felszerelés,Infinito inventario,所持品無限,무한 인벤토리,Oneindige voorraad,Uendelig lagerbeholdning,Nieskończony ekwipunek,Inventário infinito,,Inventar infinit,Бесконечный инвентарь,Бесконачно складиштење,Sonsuz envanter -No monsters,GMPLYMNU_NOMONSTERS,,,,Bez příšer,Ingen monstre,Keine Monster,,Neniu monstro,Sin monstruos,,Ei hirviöitä,Pas de monstres,Szörnyek nélkül,Nessun mostro,モンスターを出現させない,적 제거,Geen monsters,Ingen monstre,Brak potworów,Sem monstros,,Fără monștri,Без монстров,Без чудовишта,Canavar yok -No monsters to exit,GMPLYMNU_NOMONSTERSTOEXIT,,,,Ukončení levelu pouze bez příšer,Ingen monstre for at komme ud,Keine Monster um Level zu beenden,,Neniu monstro por eliri,Sin monstruos para salir,,Ei hirviöitä tason lopettamiseksi,Rien à tuer pour sortir,Megölendő szörnyek nélkül,Nessun mostro da uccidere per uscire,モンスター全滅までMAPから脱出不可,탈출을 위한 적 제거,Geen monsters om af te sluiten,Ingen monstre å avslutte,Brak potworów do wyjścia,Sem monstros para sair da fase,Sem monstros para sair do nível,Fără monștri pentru a ieși,Убить всех монстров для выхода,Без чудовишта до излаза,Çıkacak canavar yok -Monsters respawn,GMPLYMNU_MONSTERSRESPAWN,,,,Příšery se respawnují,Monstre genopstår igen,Monster kehren zurück,,Monstroj reekaperas,Reaparecer enemigos,,Hirviöt heräävät henkiin,Monstres réapparaissent,Szörnyek újraszületnek,Respawn mostri,モンスターの自力復活,적 부활,Monsters respawn,Monstre respawn,Ponowne pojawianie się potworów,Ressurgimento de monstros,,Monștrii reapar,Монстры воскрешаются,Чудовишта се оживљавају,Canavarlar yeniden doğar -Monsters do not respawn,GMPLYMNU_NORESPAWN,,,,Příšery se nerespawnují,Monstre respawner ikke igen,Kein Zurückkehren,,Monstroj ne reekaperas,Sin reaparición,,Ei henkiinheräämistä,Pas de réapparition,Szörnyek nem születnek újra,Nessun respawn,プレイヤーの復活禁止,부활 없음,Geen respawn,Monstre respawn ikke,Brak ponownego pojawienia się,Sem ressurgimento de monstros,,Monștrii nu reapar,Монстры не воскрешаются,Без оживљавања,Canavarlar yeniden doğmaz -Items respawn,GMPLYMNU_ITEMSRESPAWN,,,,Předměty se respawnují,Genstande respawnes,Gegenstände erscheinen wieder,,Objektoj reekaperas,Reaparecer objetos,,Esineet syntyvät takaisin,Objets réapparaissent,tárgyak újrateremnek,Respawn oggetti,アイテムを復活,아이템 재생성,Items respawn,Gjenstander respawn,Ponowne pojawianie się przedmiotów,Ressurgimento de itens,,Obiectele reapar,Восстановление предметов,Предмети се ресетују,Eşyalar yeniden doğar -Big powerups respawn,GMPLYMNU_SUPERRESPAWN,,,,Bonusy se respawnují,Store powerups respawnes,Große Boni erscheinen wieder,,Grandaj plifortigaĵoj reekaperas,Reaparecer poderes grandes,,Isot tehostimet syntyvät takaisin,Powerups réapparaissent,Nagy képességek újraszületnek,Respawn grandi potenziamenti,強力なパワーアップアイテムを復活,파워업 재생성,Grote power-ups respawn,Store powerups respawn,Ponowne pojawianie się dużych wzmocnień,Ressurgimento de potencializadores,,Super bonusurile reapar,Восстановление больших усилений,Велики предмети се ресетују,Büyük güçlendiriciler yeniden doğar -Fast monsters,GMPLYMNU_FASTMONSTERS,,,,Rychlé příšery,Hurtige monstre,Schnelle Monster,,Rapidaj monstroj,Monstruos rápidos,,Nopeat hirviöt,Monstres Rapides,Gyors szörnyek,Mostri veloci,モンスター高速化,빠른 적 개체 움직임,Snelle monsters,Raske monstre,Szybkie potwory,Monstros rápidos,,Monștri rapizi,Ускоренные монстры,Брза чудовишта,Hızlı canavarlar -Monsters Nightmare Reflexes,GMPLYMNU_INSTANTREACTION,,,,Okamžité reakce příšer (obtížnost Noční můra!),Monsterrefleksioner i 'Mareridt',Monsterreflexe in 'Alptraum!'.,,Refleksoj de monstroj en Inkubo-modo,Reflejos de los monsturos en Pesadilla,,Painajaisvaikeustason hirviöiden reaktioajat,,Rémálom szintű szörny reakciók,,敵が悪夢と同じ機敏さ,,,Monstre mareritt reflekser,Refleks Potworów z Trybu Koszmar,Reflexos dos Monstros em Pesadelo,,Monștri cu Reflexe de Coșmar,Кошмарные рефлексы монстров,,Canavarlar Kabus Refleksleri -Degeneration,GMPLYMNU_DEGENERATION,,,,Degenerace,,,,Degenero,Degeneración,,Rappeutuva terveys,Dégéneration,Degeneráció,Degrado della salute,プレイヤーの自動体力減少,약화,Degeneratie,Degenerasjon,Degeneracja,Degeneração,,Degenerare,Уменьшать дополнительное здоровье,Смањење додатног здравља,Dejenerasyon -Allow Autoaim,GMPLYMNU_NOAUTOAIM,,,,Povolit automatické míření,Tillad autoaim,Zielautomatik zulassen,,Permesi cel-asiston,Permitir autoapuntar,,Salli automaattitähtäys,Autoriser Auto-visée,Autocélzás engedélyezése,Mira automatica consentita,オートエイム有効化,자동 조준 허용,Autoaim toestaan,Tillat Autoaim,Pozwól na Autocelowanie,Permitir mira automática,,Permite asistența pentru țintire,Разрешить автоприцеливание,Дозволи аутоматско циљање,Autoaim'e İzin Ver -Allow Suicide,GMPLYMNU_ALLOWSUICIDE,,,,Povolit sebevraždu,Tillad selvmord,Selbstmord zulassen,,Permesi memmortigon,Permitir suicidio,,Salli itsemurha,Autoriser Suicide,Öngyilkosság engedélyezése,Suicidio consentito,自殺コマンド有効化,자살 허용,Zelfmoord toestaan,Tillat selvmord,Pozwól na Samobójstwo,Permitir suicídio,,Permite sinuciderile,Разрешить самоубийство,Дозволи самоубиство,İntihara İzin Ver -Allow jump,GMPLYMNU_ALLOWJUMP,,,,Povolit skákání,Tillader spring,Springen zulassen,,Permesi salton,Permitir salto,,Salli hyppiminen,Autoriser Sauts,Ugrás engedélyezése,Salto consentito,ジャンプ有効化,점프 허용,Springen toestaan,Tillat hopp,Pozwól na skakanie,Permitir pulo,Permitir salto,Permite săriturile,Разрешить прыжки,Дозволи скок,Atlamaya izin ver -Allow crouch,GMPLYMNU_ALLOWCROUCH,,,,Povolit klečení,Tillader krybeøvelser,Ducken zulassen,,Permesi kaŭron,Permitir agacharse,,Salli kyyristyminen,Autoriser Acroupissement,Guggolás engedélyezése,Abbassamento consentito,しゃがみ有効化,앉기 허용,Hurken toestaan,Tillat huk,Pozwól na kucanie,Permitir agachamento,,Permite ghemuirile,Разрешить приседание,Дозволи чучање,Çömelmeye izin ver -Allow freelook,GMPLYMNU_ALLOWFREELOOK,,,,Povolit koukání nahoru/dolů,Tillader freelook,Freien Blick zulassen,,Permesi liberrigardon,Permitir visión libre,,Salli vapaa katselu,Autoriser Vue Libre,Szabad egérmozgás engedélyezése,Sguardo libero consentito,フリールック有効化,프리룩 허용,Freelook toestaan,Tillat freelook,Pozwól na swobodne rozglądanie się,Permitir visão livre,,Permite privirea în jur cu mouse-ul,Обзор мышью,Дозволи слободан поглед,Freelook'a izin ver -Allow FOV,GMPLYMNU_ALLOWFOV,,,,Povolit změnu FOV,Tillad FOV,Blickwinkeländerung zulassen,,Permesi vidkampon,Permitir FOV,,Salli näkökentän muokkaaminen,Autoriser Angles de vue,Látószög állítás engedélyezése,Campo visivo consentito,FOVの調整を有効化,FOV 허용,Laat FOV,Tillat FOV,Pozwól na Pole Widzenia,Permitir campo de visão,,Permite ajustarea câmpului vizual,Разрешить изменение поля зрения,Дозволи FOV,FOV'a İzin Ver -Allow BFG aiming,GMPLYMNU_BFGFREEAIM,,,,Povolit míření s BFG,Tillad BFG-målsætning,Zielen mit BFG zulassen,,Permesi ekceladon de BFG,Permitir apuntado de BFG,,Salli BFG-tähtäys,Autoriser Visée au BFG,BFG célzás engedélyezése,Mira BFG consentita,BFG使用時のフリールックを有効化,BFG 조준 허용,Laat BFG toe om te streven naar,Tillat BFG-sikting,Pozwól na celowanie BFG,Permitir mira de BFG,,Permite țintirea cu BFG,Разрешить прицеливание с BFG,Дозволи BFG нишање,BFG hedeflemesine izin ver -Allow automap,GMPLYMNU_ALLOWAUTOMAP,,,,Povolit automapu,Tillader automap,Automap zulassen,,Permesi aŭtomapon,Permitir automapa,,Salli automaattikartta,Autoriser Carte,Autotérkép engedélyezése,Automap consentito,オートマップ有効化,오토맵 허용,Automap toestaan,Tillat automap,Pozwól na mapę,Permitir automapa,,Permite utilizarea hărții computerizate,Разрешить использование автокарты,Дозволи мапу,Otomatik eşlemeye izin ver -Automap allies,GMPLYMNU_AUTOMAPALLIES,,,,Zobrazit na automapě spojence,Automatisk indtegning af allierede,Verbündete zulassen,,Aliancanoj en aŭtomapo,Aliados en el automapa,,Omat automaattikartalla,Alliés sur la carte,Társak mutatása a térképen,Alleati nell'automap,オートマップに味方を表示,오토맵에 아군 표시,Automap bondgenoten,Automatisk kartlegging av allierte,Sojusznicy na mapie,Permitir aliados no automapa,,Aliați pe harta computerizată,Отображение союзников на автокарте,Савезници на аутомапи,Automap müttefikleri -Allow spying,GMPLYMNU_ALLOWSPYING,,,,Povolit špehování,Tillader spionage,Spionieren zulassen,,Permesi spionadon,Permitir espiar,,Salli vakoileminen,Autoriser espionnage,Kémkedés engedélyezése,Spionaggio consentita,死亡時の他プレイヤー観戦を許可,관전 허용,Laat spionage toe,Tillat spionering,Pozwól na śledzenie,Permitir visualização de outros jogadores,,Permite vederea prin ochii altor jucători,Разрешить вид от других игроков,Дозволи поглед од другог играча,Casusluğa izin ver -Chasecam cheat,GMPLYMNU_CHASECAM,,,,Povolit kameru z třetí osoby (cheat),Chasecam snyder,Verfolgerkamera Cheat,,Trompo por ĉaskamerao,Truco de vista 3era persona,,Seurantakamerahuijaus,Cheat caméra 3ième personne,Követésőkamera csalás,Cheat camera di inseguimento,チェイスカメラチート有効化,3인칭 카메라 치트,Chasecam cheat,Chasecam juks,Oszustwo kamery śledzenia,Trapaça de câmera em terceira pessoa,Batota de câmera em terceira pessoa,Trișare pentru vedere la persoana a 3-a,Разрешить вид от 3-го лица,Дозволи чејс-кем,Chasecam hilesi -Check ammo for weapon switch,GMPLYMNU_DONTCHECKAMMO,,,,Přepnout na zbraň pouze s municí,Kontroller ammunition for våbenskift,Munition beim Waffenwechsel prüfen,,Kontroli municion por armŝanĝi,Revisar munición para cambiar armas,,Tarkista ammustilanne aseenvaihdon yhteydessä,Vérifier muni. pour changer arme,Váltáskor üres fegyver átugrása,Controlla le munizioni per il cambio arma,武器切替時に弾の有無を確認,탄약 소진 시 무기 변경,Controleer munitie op wapenschakelaars.,Sjekk ammunisjon for våpenbryter,Sprawdź amunicję przy sprawdzaniu broni,Conferir munição para troca de arma,,Verifică muniția armei pentru schimbare,Проверять патроны при переключении оружия,Проверити муницију за прекидач за оружје,Silah anahtarı için cephaneyi kontrol edin -Icon's death kills its spawns,GMPLYMNU_KILLBOSSSPAWNS,,,,Smrt Ikony zabije i její potomky,Ikonets død dræber dets spawns,,,La morto de la piktogramo mortigas siajn idojn,La muerte del icono destruye sus lacayos,La muerte del ícono destruye sus lacayos,Ikonin kuolema tappaa myös siitä siinneet hirviöt,Tuer L'Icône tue ses monstres,Az ikon halála esetén a teremtményei is meghalnak,La morte dell'Icona uccide tutti i suoi figli,最終ボスを殺した際に召喚モンスターも殺す,보스 사망시 소환된 적들도 사망,Icon's dood doodt zijn spawns,Ikonets død dreper dets gyter,Śmierć Ikony zabija stworzone przez nią potwory,Morte do Ícone mata os seus monstros,Morte do Ícone mata os seus demónios,Decesul Idolului anihilează propriile creații,Убить порождения Иконы при её смерти,Смрт Икона греха убија његова потомства,İkon'un ölümü yumurtalarını öldürür +",死亡時に武器を落とす,무기 버리기,Laat het wapen vallen,Slipp våpen,Wyrzuć broń,Largar arma,,Aruncare armă,Терять оружие,Баци оружје,Släpp vapen,Silahı bırak +Double ammo,GMPLYMNU_DOUBLEAMMO,,,,Dvojnásobná munice,Dobbelt ammunition,Doppelte Munition,,Duobla municio,Doble munición,,Tupla-ammukset,Double munitions,Dupla muníció,Doppie munizioni,弾2倍,두 배의 탄약,Dubbele munitie,Dobbel ammunisjon,Podwojona amunicja,Munição em dobro,,Muniție dublă,Удвоенные патроны,Дупла муниција,Dubbel ammunition,Çift cephane +Infinite ammo,GMPLYMNU_INFINITEAMMO,,,,Nekonečná munice,Uendelig ammunition,Unendlich Munition,,Senlima municio,Munición infinita,,Loppumattomat ammukset,Munitions infinies,Végtelen muníció,Infinite munizioni,弾無限,무한 탄약,Oneindige munitie,Uendelig ammunisjon,Nieskończona amunicja,Munição infinita,,Muniție infinită,Бесконечные патроны,Бесконачна муниција,Oändlig ammunition,Sonsuz cephane +Infinite inventory,GMPLYMNU_INFINITEINVENTORY,,,,Nekonečný inventář,Uendelig lagerbeholdning,Unendliche Gegenstände,,Senlima inventaro,Inventario infinito,,Loppumattomat varusteet,Objets infinis,Végtelen felszerelés,Infinito inventario,所持品無限,무한 인벤토리,Oneindige voorraad,Uendelig lagerbeholdning,Nieskończony ekwipunek,Inventário infinito,,Inventar infinit,Бесконечный инвентарь,Бесконачно складиштење,Oändligt inventarium,Sonsuz envanter +No monsters,GMPLYMNU_NOMONSTERS,,,,Bez příšer,Ingen monstre,Keine Monster,,Neniu monstro,Sin monstruos,,Ei hirviöitä,Pas de monstres,Szörnyek nélkül,Nessun mostro,モンスターを出現させない,적 제거,Geen monsters,Ingen monstre,Brak potworów,Sem monstros,,Fără monștri,Без монстров,Без чудовишта,Inga monster,Canavar yok +No monsters to exit,GMPLYMNU_NOMONSTERSTOEXIT,,,,Ukončení levelu pouze bez příšer,Ingen monstre for at komme ud,Keine Monster um Level zu beenden,,Neniu monstro por eliri,Sin monstruos para salir,,Ei hirviöitä tason lopettamiseksi,Rien à tuer pour sortir,Megölendő szörnyek nélkül,Nessun mostro da uccidere per uscire,モンスター全滅までMAPから脱出不可,탈출을 위한 적 제거,Geen monsters om af te sluiten,Ingen monstre å avslutte,Brak potworów do wyjścia,Sem monstros para sair da fase,Sem monstros para sair do nível,Fără monștri pentru a ieși,Убить всех монстров для выхода,Без чудовишта до излаза,Inga monster för att ta sig ut,Çıkacak canavar yok +Monsters respawn,GMPLYMNU_MONSTERSRESPAWN,,,,Příšery se respawnují,Monstre genopstår igen,Monster kehren zurück,,Monstroj reekaperas,Reaparecer enemigos,,Hirviöt heräävät henkiin,Monstres réapparaissent,Szörnyek újraszületnek,Respawn mostri,モンスターの自力復活,적 부활,Monsters respawn,Monstre respawn,Ponowne pojawianie się potworów,Ressurgimento de monstros,,Monștrii reapar,Монстры воскрешаются,Чудовишта се оживљавају,Monster återuppstår,Canavarlar yeniden doğar +Monsters do not respawn,GMPLYMNU_NORESPAWN,,,,Příšery se nerespawnují,Monstre respawner ikke igen,Kein Zurückkehren,,Monstroj ne reekaperas,Sin reaparición,,Ei henkiinheräämistä,Pas de réapparition,Szörnyek nem születnek újra,Nessun respawn,プレイヤーの復活禁止,부활 없음,Geen respawn,Monstre respawn ikke,Brak ponownego pojawienia się,Sem ressurgimento de monstros,,Monștrii nu reapar,Монстры не воскрешаются,Без оживљавања,Monstren återuppstår inte,Canavarlar yeniden doğmaz +Items respawn,GMPLYMNU_ITEMSRESPAWN,,,,Předměty se respawnují,Genstande respawnes,Gegenstände erscheinen wieder,,Objektoj reekaperas,Reaparecer objetos,,Esineet syntyvät takaisin,Objets réapparaissent,tárgyak újrateremnek,Respawn oggetti,アイテムを復活,아이템 재생성,Items respawn,Gjenstander respawn,Ponowne pojawianie się przedmiotów,Ressurgimento de itens,,Obiectele reapar,Восстановление предметов,Предмети се ресетују,Föremål återuppstår.,Eşyalar yeniden doğar +Big powerups respawn,GMPLYMNU_SUPERRESPAWN,,,,Bonusy se respawnují,Store powerups respawnes,Große Boni erscheinen wieder,,Grandaj plifortigaĵoj reekaperas,Reaparecer poderes grandes,,Isot tehostimet syntyvät takaisin,Powerups réapparaissent,Nagy képességek újraszületnek,Respawn grandi potenziamenti,強力なパワーアップアイテムを復活,파워업 재생성,Grote power-ups respawn,Store powerups respawn,Ponowne pojawianie się dużych wzmocnień,Ressurgimento de potencializadores,,Super bonusurile reapar,Восстановление больших усилений,Велики предмети се ресетују,Stora powerups återuppstår.,Büyük güçlendiriciler yeniden doğar +Fast monsters,GMPLYMNU_FASTMONSTERS,,,,Rychlé příšery,Hurtige monstre,Schnelle Monster,,Rapidaj monstroj,Monstruos rápidos,,Nopeat hirviöt,Monstres Rapides,Gyors szörnyek,Mostri veloci,モンスター高速化,빠른 적 개체 움직임,Snelle monsters,Raske monstre,Szybkie potwory,Monstros rápidos,,Monștri rapizi,Ускоренные монстры,Брза чудовишта,Snabba monster,Hızlı canavarlar +Monsters Nightmare Reflexes,GMPLYMNU_INSTANTREACTION,,,,Okamžité reakce příšer (obtížnost Noční můra!),Monsterrefleksioner i 'Mareridt',Monsterreflexe in 'Alptraum!'.,,Refleksoj de monstroj en Inkubo-modo,Reflejos de los monsturos en Pesadilla,,Painajaisvaikeustason hirviöiden reaktioajat,,Rémálom szintű szörny reakciók,,敵が悪夢と同じ機敏さ,,,Monstre mareritt reflekser,Refleks Potworów z Trybu Koszmar,Reflexos dos Monstros em Pesadelo,,Monștri cu Reflexe de Coșmar,Кошмарные рефлексы монстров,,Monster mardrömsreflexer,Canavarlar Kabus Refleksleri +Degeneration,GMPLYMNU_DEGENERATION,,,,Degenerace,,,,Degenero,Degeneración,,Rappeutuva terveys,Dégéneration,Degeneráció,Degrado della salute,プレイヤーの自動体力減少,약화,Degeneratie,Degenerasjon,Degeneracja,Degeneração,,Degenerare,Уменьшать дополнительное здоровье,Смањење додатног здравља,,Dejenerasyon +Allow Autoaim,GMPLYMNU_NOAUTOAIM,,,,Povolit automatické míření,Tillad autoaim,Zielautomatik zulassen,,Permesi cel-asiston,Permitir autoapuntar,,Salli automaattitähtäys,Autoriser Auto-visée,Autocélzás engedélyezése,Mira automatica consentita,オートエイム有効化,자동 조준 허용,Autoaim toestaan,Tillat Autoaim,Pozwól na Autocelowanie,Permitir mira automática,,Permite asistența pentru țintire,Разрешить автоприцеливание,Дозволи аутоматско циљање,Tillåt autoaim,Autoaim'e İzin Ver +Allow Suicide,GMPLYMNU_ALLOWSUICIDE,,,,Povolit sebevraždu,Tillad selvmord,Selbstmord zulassen,,Permesi memmortigon,Permitir suicidio,,Salli itsemurha,Autoriser Suicide,Öngyilkosság engedélyezése,Suicidio consentito,自殺コマンド有効化,자살 허용,Zelfmoord toestaan,Tillat selvmord,Pozwól na Samobójstwo,Permitir suicídio,,Permite sinuciderile,Разрешить самоубийство,Дозволи самоубиство,Tillåt självmord,İntihara İzin Ver +Allow jump,GMPLYMNU_ALLOWJUMP,,,,Povolit skákání,Tillader spring,Springen zulassen,,Permesi salton,Permitir salto,,Salli hyppiminen,Autoriser Sauts,Ugrás engedélyezése,Salto consentito,ジャンプ有効化,점프 허용,Springen toestaan,Tillat hopp,Pozwól na skakanie,Permitir pulo,Permitir salto,Permite săriturile,Разрешить прыжки,Дозволи скок,Tillåt hopp,Atlamaya izin ver +Allow crouch,GMPLYMNU_ALLOWCROUCH,,,,Povolit klečení,Tillader krybeøvelser,Ducken zulassen,,Permesi kaŭron,Permitir agacharse,,Salli kyyristyminen,Autoriser Acroupissement,Guggolás engedélyezése,Abbassamento consentito,しゃがみ有効化,앉기 허용,Hurken toestaan,Tillat huk,Pozwól na kucanie,Permitir agachamento,,Permite ghemuirile,Разрешить приседание,Дозволи чучање,Tillåt huk,Çömelmeye izin ver +Allow freelook,GMPLYMNU_ALLOWFREELOOK,,,,Povolit koukání nahoru/dolů,Tillader freelook,Freien Blick zulassen,,Permesi liberrigardon,Permitir visión libre,,Salli vapaa katselu,Autoriser Vue Libre,Szabad egérmozgás engedélyezése,Sguardo libero consentito,フリールック有効化,프리룩 허용,Freelook toestaan,Tillat freelook,Pozwól na swobodne rozglądanie się,Permitir visão livre,,Permite privirea în jur cu mouse-ul,Обзор мышью,Дозволи слободан поглед,Tillåt freelook,Freelook'a izin ver +Allow FOV,GMPLYMNU_ALLOWFOV,,,,Povolit změnu FOV,Tillad FOV,Blickwinkeländerung zulassen,,Permesi vidkampon,Permitir FOV,,Salli näkökentän muokkaaminen,Autoriser Angles de vue,Látószög állítás engedélyezése,Campo visivo consentito,FOVの調整を有効化,FOV 허용,Laat FOV,Tillat FOV,Pozwól na Pole Widzenia,Permitir campo de visão,,Permite ajustarea câmpului vizual,Разрешить изменение поля зрения,Дозволи FOV,Tillåt FOV,FOV'a İzin Ver +Allow BFG aiming,GMPLYMNU_BFGFREEAIM,,,,Povolit míření s BFG,Tillad BFG-målsætning,Zielen mit BFG zulassen,,Permesi ekceladon de BFG,Permitir apuntado de BFG,,Salli BFG-tähtäys,Autoriser Visée au BFG,BFG célzás engedélyezése,Mira BFG consentita,BFG使用時のフリールックを有効化,BFG 조준 허용,Laat BFG toe om te streven naar,Tillat BFG-sikting,Pozwól na celowanie BFG,Permitir mira de BFG,,Permite țintirea cu BFG,Разрешить прицеливание с BFG,Дозволи BFG нишање,Tillåt BFG-målning,BFG hedeflemesine izin ver +Allow automap,GMPLYMNU_ALLOWAUTOMAP,,,,Povolit automapu,Tillader automap,Automap zulassen,,Permesi aŭtomatan mapon,Permitir automapa,,Salli automaattikartta,Autoriser Carte,Autotérkép engedélyezése,Automap consentito,オートマップ有効化,오토맵 허용,Automap toestaan,Tillat automap,Pozwól na mapę,Permitir automapa,,Permite utilizarea hărții computerizate,Разрешить использование автокарты,Дозволи мапу,Tillåt automap,Otomatik eşlemeye izin ver +Automap allies,GMPLYMNU_AUTOMAPALLIES,,,,Zobrazit na automapě spojence,Automatisk indtegning af allierede,Verbündete zulassen,,Aliancanoj en aŭtomata mapo,Aliados en el automapa,,Omat automaattikartalla,Alliés sur la carte,Társak mutatása a térképen,Alleati nell'automap,オートマップに味方を表示,오토맵에 아군 표시,Automap bondgenoten,Automatisk kartlegging av allierte,Sojusznicy na mapie,Permitir aliados no automapa,,Aliați pe harta computerizată,Отображение союзников на автокарте,Савезници на аутомапи,Automatiska allierade,Automap müttefikleri +Allow spying,GMPLYMNU_ALLOWSPYING,,,,Povolit špehování,Tillader spionage,Spionieren zulassen,,Permesi spionadon,Permitir espiar,,Salli vakoileminen,Autoriser espionnage,Kémkedés engedélyezése,Spionaggio consentita,死亡時の他プレイヤー観戦を許可,관전 허용,Laat spionage toe,Tillat spionering,Pozwól na śledzenie,Permitir visualização de outros jogadores,,Permite vederea prin ochii altor jucători,Разрешить вид от других игроков,Дозволи поглед од другог играча,Tillåter spionage,Casusluğa izin ver +Chasecam cheat,GMPLYMNU_CHASECAM,,,,Povolit kameru z třetí osoby (cheat),Chasecam snyder,Verfolgerkamera Cheat,,Trompo por ĉaskamerao,Truco de vista 3era persona,,Seurantakamerahuijaus,Cheat caméra 3ième personne,Követésőkamera csalás,Cheat camera di inseguimento,チェイスカメラチート有効化,3인칭 카메라 치트,Chasecam cheat,Chasecam juks,Oszustwo kamery śledzenia,Trapaça de câmera em terceira pessoa,Batota de câmera em terceira pessoa,Trișare pentru vedere la persoana a 3-a,Разрешить вид от 3-го лица,Дозволи чејс-кем,Fusk med Chasecam,Chasecam hilesi +Check ammo for weapon switch,GMPLYMNU_DONTCHECKAMMO,,,,Přepnout na zbraň pouze s municí,Kontroller ammunition for våbenskift,Munition beim Waffenwechsel prüfen,,Kontroli municion por armŝanĝi,Revisar munición para cambiar armas,,Tarkista ammustilanne aseenvaihdon yhteydessä,Vérifier muni. pour changer arme,Váltáskor üres fegyver átugrása,Controlla le munizioni per il cambio arma,武器切替時に弾の有無を確認,탄약 소진 시 무기 변경,Controleer munitie op wapenschakelaars.,Sjekk ammunisjon for våpenbryter,Sprawdź amunicję przy sprawdzaniu broni,Conferir munição para troca de arma,,Verifică muniția armei pentru schimbare,Проверять патроны при переключении оружия,Проверити муницију за прекидач за оружје,Kontrollera ammunition för vapenbyte,Silah anahtarı için cephaneyi kontrol edin +Icon's death kills its spawns,GMPLYMNU_KILLBOSSSPAWNS,,,,Smrt Ikony zabije i její potomky,Ikonets død dræber dets spawns,,,La morto de la piktogramo mortigas siajn idojn,La muerte del icono destruye sus lacayos,La muerte del ícono destruye sus lacayos,Ikonin kuolema tappaa myös siitä siinneet hirviöt,Tuer L'Icône tue ses monstres,Az ikon halála esetén a teremtményei is meghalnak,La morte dell'Icona uccide tutti i suoi figli,最終ボスを殺した際に召喚モンスターも殺す,보스 사망시 소환된 적들도 사망,Icon's dood doodt zijn spawns,Ikonets død dreper dets gyter,Śmierć Ikony zabija stworzone przez nią potwory,Morte do Ícone mata os seus monstros,Morte do Ícone mata os seus demónios,Decesul Idolului anihilează propriile creații,Убить порождения Иконы при её смерти,Смрт Икона греха убија његова потомства,Ikonens död dödar dess spawns,İkon'un ölümü yumurtalarını öldürür End sector counts for kill %,GMPLYMNU_NOCOUNTENDMONSTER,,,,Započítávat monstra v ukončujících sektorech,Slut sektor tæller for dræber %,Monster in Level-Beenden-Sektor zählen,,Finsektoro kalkulas al nombro da mortigoj,Sector de salida cuenta para % de muertes,,Loppusektori lasketaan mukaan tappoprosenttiin,Ennemis du secteur sortie comptés,Utolsó szektornál számít az ölés %,Conteggio dei nemici da uccidere nel settore in %,最終セクターの敵もキルに含む,레벨종료 섹터의 적들도 킬 수에 포함,Eindsector telt voor kill %,Slutt sektor teller for drap i prosent,"Zliczanie potworów w sektorze kończącym poziom -",Setor de saída conta para porcentagem de mortes,Setor de saída conta para percentagem de mortes,Numărare decese monștri în sectoare finale,Засчитывать убийства монстров в секторах конца игры,Урачунај убиство чудовишта у коначним секторима,Öldürme %'si için son sektör sayıları -Deathmatch Settings,GMPLYMNU_DEATHMATCH,,,,Nastavení deathmatche,Indstillinger for Deathmatch,Deathmatcheinstellungen,,Mortmatĉo-agordoj,Configuración modo a muerte,,Kuolonotteluasetukset,Options Deathmatch,Deathmatch beállítások,Impostazioni deathmatch,デスマッチの設定,데스매치 설정,Deathmatch instellingen,Deathmatch-innstillinger,Ustawienia Deathmatchu,Configurações de Deathmatch,,Setări Deathmatch,Настройки боя насмерть,Детмеч подешавања,Ölüm Maçı Ayarları -Weapons stay,GMPLYMNU_WEAPONSSTAY,,,,Zbraně zůstávají,Våben forbliver,Waffen bleiben,,Armiloj restiĝas,Las armas se quedan,,Aseet pysyvät,Armes restent au sol quand prises,Fegyverek mindig felvehetőek,Le armi rimangono in posizione,武器を取得時も残す,습득 후 무기가 남아있기,Wapenverblijven,Våpen forblir,Bronie zostają,Armas permanecem,,Părăsire arme după selectare,Оставлять оружие после подбора,Оружје се остаје након купљења,Silahlar kalıyor -Allow powerups,GMPLYMNU_ALLOWPOWERUPS,,,,Povolit bonusy,Tillad powerups,Boni erlauben,,Permesi plifortigaĵojn,Permitir poderes,,Salli tehostimet,Autoriser powerups,Powerupok engedélyezése,Potenziamenti consentiti,パワーアップアイテムを出現させる,파워 업 허용,Power-ups toestaan,Tillat powerups,Pozwól na wzmocnienia,Permitir powerups,,Permite bonusuri,Разрешить бонусы,Дозволи бонусе,Güçlendirmelere izin ver -Allow health,GMPLYMNU_ALLOWHEALTH,,,,Povolit zdraví,Tillad sundhed,Gesundheit erlauben,,Permesi sanon,Permitir salud,,Salli terveysesineet,Autoriser objets santé,Életerő engedélyezése,Oggetti per la salute consentiti,回復アイテムを出現させる,체력 회복 아이템 허용,Gezondheid toestaan,Tillat helse,Pozwól na przedmioty zdrowotne,Permitir itens de saúde,,Permite prim-ajutor,Разрешить здоровье,Дозволи бонусе за здравље,Sağlığa izin ver -Allow armor,GMPLYMNU_ALLOWARMOR,,,Allow armour,Povolit brnění,Tillad rustning,Panzer erlauben,,Permesi kirason,Permitir armadura,,Salli panssariesineet,Autoriser objets armure,Páncél engedélyezése,Armature consentite,アーマーを出現させる,아머 허용,Pantsertoeslag toestaan,Tillat rustning,Pozwól na pancerz,Permitir itens de armadura,,Permite bonusuri de armură,Разрешить броню,Дозволи оклоп,Zırha izin ver -Spawn farthest,GMPLYMNU_SPAWNFARTHEST,,,,Spawnovat hráče co nejdále od sebe,Spawn længst væk,Am weitesten entfernten Punkt erscheinen,,Ekaperi plej fore,Aparecer más lejos,,Herää henkiin kauimpaa,Apparaître au plus loin,Legmesszebb születés,Spawn il più lontano possibile,他のプレイヤーから最遠の場所に復活,먼 곳에서 소환,Kuitschieten het verst verwijderd,Spawn lengst,Pojaw się jak najdalej,Surgimento mais longe,,Apariție cât mai departată de ceilalți,Воскрешение подальше от остальных,Оживљавање даље од других,En uzakta yumurtla -Same map,GMPLYMNU_SAMEMAP,,,,Stejná mapa,Samme kort,Gleiches Level,,Sama mapo,Mismo mapa,,Sama taso,Même Carte,Ugyanazon pálya,Stessa mappa,同じMAPを繰り返す,같은 맵 플레이,Dezelfde kaart,Samme kart,Ta sama mapa,Mesmo mapa,,Reluare nivel,Зациклить уровень,Понављање нивоа,Aynı harita -Force respawn,GMPLYMNU_FORCERESPAWN,,,,Vynutit respawn,Tvinge respawn,Zurückkehren erzwingen,,Devigi reekaperon,Forzar reaparición,,Pakota henkiinherääminen,Forcer Réapparition,Újraszületés kényszerítése,Forza il respawn,死亡後に強制復活,강제 부활,Respawn is gedwongen,Force respawn,Wymuś ponowne pojawienie się,Forçar reaparecimento,,Reapariție instantă,Моментальное воскрешение,Форсирано оживљавање,Yeniden doğmaya zorla -Allow exit,GMPLYMNU_ALLOWEXIT,,,,Povolit ukončení levelu,Tillad at forlade,Verlassen erlauben,,Permesi eliron,Permitir salir,,Salli tasosta poistuminen,Autoriser Sortie,Kijárat engedélyezése,Uscita consentita,出口の使用を許可,탈출 허용,Uitgang toestaan,Tillat utgang,Pozwól na wyjście,Permitir saída,,Permite ieșirea,Разрешить выход,Дозволи излазак из нивоа,Çıkışa izin ver -Barrels respawn,GMPLYMNU_BARRELSRESPAWN,,,,Barely se respawnují,Tønder respawner,Fässer kehren zurück,,Bareloj reekaperas,Reaparecer barriles,,Tynnyrit syntyvät takaisin,Réapparition des Tonneaux,Hordók újraszületése,Respawn barili esplosivi,爆発バレルを復活させる,폭발통 재생성,Vaten respawn,Tønner respawn,Beczki pojawiają się ponownie,Barrís reaparecem,,Butoaiele reapar,Восстановление бочек,Бурад се ресетују,Variller yeniden doğar -Respawn protection,GMPLYMNU_RESPAWNPROTECTION,,,,Ochrana po respawnu,Respawn-beskyttelse,Schutz beim Zurückkehren,,Protekto de reekapero,Reaparecer protección,,Henkiinheräämissuoja,Protection à la réapparition,Újraszületési védelem,Protezione al respawn,復活したばかりのプレイヤーを保護,부활시 무적,Respawn bescherming,Respawn-beskyttelse,Ochrona przy ponownym pojawieniu się,Proteção de reaparecimento,,Protecție la apariția pe hartă,Кратковременная защита после воскрешения,Ресетује се заштита,Yeniden doğma koruması -Lose frag if fragged,GMPLYMNU_LOSEFRAG,,,,"Hráč ztratí frag, pokud je zabit",Mister frag hvis der er en fragged,Fragabzug bei Tod,,Perdi ludmurdon se ludmurdita,Perder baja al morir,,"Frägin menettäminen, jos joutuu frägätyksi",Perdre 1 frag quand tué,Halál esetén pont veszítése,Perdere i frag se fraggato,キルされた場合は得点を失う,적에게 사망시 점수를 잃음,Verlies frag bij dood,Miste frag hvis fragged,Strać fraga jeśli jesteś sfragowany,Perder frag ao ser fragado,,Pierdere din victime la deces,Терять фраг при смерти,Изгубити гранату ако опаљена,Parçalanırsa parça kaybeder -Keep frags gained,GMPLYMNU_KEEPFRAGS,,,,Ponechávat fragy mezi levely,Beholde vundne frags,Frags zwischen Leveln behalten,,Teni ludmurdojn gajnitajn,Mantener bajas ganadas,,Pidä ansaitut frägit,Garder les frags gagnés,Megszerzett pontok megmaradnak,Mantenere i frag vinti,MAP変更後も得点を保持する,맵 변경 시 점수 유지,Houd frags opgedaan,Behold frags vunnet,Zachowaj zdobyte fragi,Manter frags ganhos,,Păstrare număr victime,Сохранять фраги между уровнями,Задржати стечене гранате,Kırıntıları kazanmaya devam edin -No team switching,GMPLYMNU_NOTEAMSWITCH,,,,Uzamknout týmy,Ingen holdskifte,Kein Teamwechsel,,Neniu teamŝanĝado,No cambiar equipos,,Ei joukkueenvaihtoa,Pas de changement d'équipe,Nincs csapatváltás,Nessun cambio di squadra,チーム変更を禁止,팀 변경 없음,Geen teamwisseling,Ingen lagbytte,Zakaz zmieniania drużyn,Desativar troca de time,Desativar troca de equipa,Nu permite schimbarea echipelor,Запретить переход между командами,Нема мешања тимова,Takım değiştirme yok -Cooperative Settings,GMPLYMNU_COOPERATIVE,,,,Nastavení co-op módu,Kooperativ indstillinger,Kooperativ-Einstellungen,,Agordoj de koopera reĝimo,Configuración de cooperativo,,Yhteispeliasetukset,Options Coopératives,Együttműködő beállítások,Impostazioni cooperativa,協力モードの設定,협동 플레이 설정,Coöperatieve instellingen,Samarbeidsinnstillinger,Ustawienia Kooperacji,Configurações de jogo cooperativo,,Setări cooperative,Настройки совместной игры,Кооперативне поставке,Kooperatif Ayarları -Spawn multiplayer weapons,GMPLYMNU_MULTIPLAYERWEAPONS,,,,Spawnovat multiplayerově zbraně,Spawn multiplayer-våben,Deathmartch Waffen sind verfügbar,,Ekaperigi armilojn por plurludanta reĝimo,Aparecer armas multi.,,Kuolonotteluaseet saatavilla,Spawns d'armes deathmatch,Többjátékos fegyverek engedélyezése,Fai apparire le armi di multigiocatore,マルチプレイ用の武器を出現させる,멀티플레이어 무기 소환,Spawn multi. wapens,Spawn flerspillervåpen,Zezwól na bronie trybu dla wielu graczy,Surgimento de armas em multijogador,,Permite apariția armelor din modul online,Появление оружия из сетевой игры,Створити мулти оружја,Çok oyunculu silahları ortaya çıkarma -Lose entire inventory,GMPLYMNU_LOSEINVENTORY,,,,Ztrácet celý inventář,Mister hele inventaret,Verliere ganzes Inventar,,Perdi tutan inventorion,Perder todo el inventario,,Menetä kaikki varusteet,Perdre l'inventaire,Teljes készlet elvesztése,Perdere l'inventario,死亡時に全ての所持品を失う,인벤토리 비우기,Verlies van de volledige inventaris,Miste hele beholdningen,Utrać cały ekwipunek,Perder todo o inventário,,Pierdere inventar,Терять весь инвентарь при смерти,Изгубити цело складиште,Tüm envanteri kaybetmek -Keep keys,GMPLYMNU_KEEPKEYS,,,,Ponechat klíče,Beholde nøgler,Schlüssel behalten,,Teni ŝlosiojn,Mantener llaves,,Pidä avaimet,Garder clés,Kulcsok megtartása,Mantenere le chiavi,死亡後もキーを保持する,열쇠들을 소지하고 시작,Sleutels bewaren,Behold nøkler,Zachowaj klucze,Manter chaves,,Păstrare chei,Сохранять ключи,Задржати кључеве,Anahtarları sakla -Keep weapons,GMPLYMNU_KEEPWEAPONS,,,,Ponechat zbraně,Behold våben,Waffen behalten,,Teni armilojn,Mantener armas,,Pidä aseet,Garder armes,Fegyverek megtartása,Mantenere le armi,死亡後も武器を保持する,무기들을 소지하고 시작,Wapens bewaren,Behold våpen,Zachowaj bronie,Manter armas,,Păstrare arme,Сохранять оружие,Задржати оружје,Silahları saklayın -Keep armor,GMPLYMNU_KEEPARMOR,,,Keep armour,Ponechat brnění,Behold rustning,Rüstung behalten,,Teni kirason,Mantener armadura,,Pidä panssari,Garder armure,Páncél megtartása,Mantenere l'armatura,死亡後もアーマーを保持する,아머를 소지하고 시작,Pantser bewaren,Behold rustning,Zachowaj pancerz,Manter armadura,,Păstrare armură,Сохранять броню,Задржати панцир,Zırhı sakla -Keep powerups,GMPLYMNU_KEEPPOWERUPS,,,,Ponechat bonusy,Beholde powerups,Behalte Boni,,Teni plifortigaĵojn,Mantener poderes,,Pidä tehostimet,Garder powerups,Powerupok megtartása,Mantenere i potenziamenti,死亡後もパワーアップを保持する,파워업을 소지하고 시작,Power-ups bewaren,Behold powerups,Zachowaj wzmocnienia,Manter powerups,,Păstrare bonusuri,Сохранять супербонусы,Задржати повећану моћ,Güçlendirmeleri sakla -Keep ammo,GMPLYMNU_KEEPAMMO,,,,Ponechat munici,Beholde ammunition,Munition behalten,,Teni municion,Mantener munición,,Pidä ammukset,Garder munitions,Muníció megtartása,Mantenere le ammunizioni,死亡後も弾薬を保持する,탄약을 소지하고 시작,Munitie bewaren,Behold ammunisjon,Zachowaj amunicję,Manter munição,,Păstrare armură,Сохранять патроны,Задржати муницију,Cephaneyi sakla -Lose half ammo,GMPLYMNU_LOSEHALFAMMO,,,,Ztratit polovinu munice,Mister halvdelen af ammunitionen,Halbe Munition verlieren,,Perdi duonon de onia municio,Perder la mitad de la munición,,Menetä puolet ammuksista,Perdre la moité des munitions,Fele muníció elvesztése,Perdere metà ammunizioni,死亡時に弾を半分失う,탄약의 반을 잃음,Verlies halve munitie,Miste halv ammunisjon,Utrać pół amunicji,Perder metade da munição,,Pierdere jumătate din armură,Терять половину патронов,Изгубити пола муниције,Cephanenin yarısını kaybet -Spawn where died,GMPLYMNU_SPAWNWHEREDIED,,,,Respawn na místě smrti,Spawn hvor du døde,Neuerscheinen wo gestorben,,Ekaperigi kie oni mortigis,Aparecer donde moriste,,Herää henkiin kuolinpaikalla,Réapparaitre sur lieu de mort,Halál helyén újraszületés,Respawn nel luogo di morte,死亡したその場で復活,죽은 곳에서 소환,Kuit waar gestorven is,Gyte der du døde,Pojaw się znów tam gdzie zginąłeś,Surgir no local da morte,Reaparecer onde morreu,Apariție la locul decesului,Воскрешение на месте смерти,Оживљавање на месту смрти,Öldüğü yerde yumurtlama -Always spawn multiplayer objects,GMPLYMNU_ALWAYSSPAWNMULTI,,,,Vždy spawnovat multiplayerové objekty,Spawn altid multiplayer-objekter,Mehrspielerobjekte immer erzeugen,,Ĉiam ekaperi plurludantajn objektojn,Siempre hacer aparecer objetos en el modo multijugador,,Aina luo moninpelioliot,Toujours créer des objets multi-joueurs,Mindig megjelennek a többjátékos tárgyak,Fai sempre apparire gli oggetti di multigiocatore,常にマルチプレイ用の物を出現,,Altijd multiplayer objecten spawnen,Alltid gyte flerspillerobjekter,Pozwól na przedmioty dla trybu wielu graczy,Permitir surgimento de objetos multijogador,,Permite apariția obiectelor din multiplayer,Появление объектов из сетевой игры,Увек стварајте објекте за више играча,Her zaman çok oyunculu nesneler oluşturun -Allow Vertical Bullet Spread,GMPLYMNU_NOVERTSPREAD,,,,Povolit svislý rozptyl střelby,Tillad lodret kuglespredning,Vertikale Streuung erlauben,,Permesi vertikalan kuglan disvastiĝon,Desparramar balas de todas las armas en vertical,,Permesu Vertikalan Kuglon Disvastiĝon ,Permettre la propagation verticale des balles,Vertikális fegyverszórás engedélyezve,Permetti la diffusione dei proiettili in verticale,垂直方向への散弾を許可,,Verticale kogelspreiding toestaan,Tillat vertikal kulespredning,Pozwól na pionowy rozrzut pocisków,Permitir espalhamento vertical das balas,,Permiteți răspândirea verticală a gloanțelor,Разрешить вертикальный разброс пуль,Дозволи вертикално ширење метака,Dikey Mermi Yayılımına İzin Ver -Weapons give extra ammo (DM),GMPLYMNU_NOEXTRAAMMO,,,,Zbraně dávají munici navíc (DM),Våben giver ekstra munition (DM),Waffen geben Extramunition,,Armiloj donas ekstran municion (DM),Las armas dan munición extra (DM),,Armiloj donas ekstran municion (DM),Les armes donnent des munitions supplémentaires (DM),A fegyverek extra lőszert adnak (DM),Le armi danno munizioni extra (DM),武器に追加弾薬を付与 (DMのみ),,Wapens geven extra munitie (DM),Våpen gir ekstra ammunisjon (DM),Broń daje dodatkową amunicję (DM),Armas dão munição extra (DM),,Armele oferă muniție suplimentară (DM),Оружие дает дополнительные патроны (DM),Оружје даје додатну муницију (ДМ),Silahlar ekstra cephane verir (DM) -Compatibility Options,OPTMNU_COMPATIBILITY,,,,Kompatibilita,Kompatibilitetsindstillinger,Kompatibilitätsoptionen,Ρυθμίσεις Συμβατότητας,Kongruo-agordoj,Opciones de compatibilidad,,Yhteensopivuusasetukset,Options de Compatibilité,Kompatibilitási beállítások,Opzioni Compatibilità,互換性 オプション,호환 설정,Compatibiliteitsopties,Kompatibilitetsalternativer,Opcje Zgodności,Opções de compatibilidade,,Setări de Compatibilitate,Настройки совместимости,Компатибилност,Uyumluluk Seçenekleri -Compatibility Options,CMPTMNU_TITLE,,,,Nastavení kompatibility,Kompatibilitetsindstillinger,Kompatibilitätsoptionen,Ρυθμίσεις Συμβατότητας,Kongruo-agordoj,Opciones de compatibilidad,,Yhteensopivuusasetukset,Options Compatibilité,Kompatibilitási beállítások,Opzioni compatibilità,互換性 オプション,호환성 설정,Compatibiliteitsopties,Kompatibilitetsalternativer,Opcje Zgodności,Opções de compatibilidade,,Setări de Compatibilitate,Настройки совместимости,Компатибилна подешавања,Uyumluluk Seçenekleri -Compatibility mode,CMPTMNU_MODE,,,,Režim kompatibility,Kompatibilitetstilstand,Kompatibilitätsmodus,,Kongruo-reĝimo,Modo de Compatibilidad,,Yhteensopivuustila,Mode de compatibilité,Kompatibilitási mód,Modalità compatibilità,互換性モード,호환 모드,Compatibiliteitsmodus,Kompatibilitetsmodus,Tryb Zgodności,Modo de compatibilidade,,Mod Compatibilitate,Режим совместимости,Компатибилни мод,Uyumluluk modu -Actor Behavior,CMPTMNU_ACTORBEHAVIOR,,,Actor Behaviour,Objekty,Skuespilleradfærd,Verhalten der Akteure,,Aktorkonduto,Comportamiento del actor,,Olioiden käyttäytyminen,Comportement des Acteurs,Actor viselkedés,Comportamento degli attori,アクターの挙動,개체 관련 설정,Gedrag van de acteur,Skuespilleroppførsel,Zachowanie Aktorów,Comportamento de atores,,Comportament actori,Поведение объектов (акторов),Понашање актора,Aktör Davranışı -Friendly monsters aren't blocked,CMPTMNU_NOBLOCKFRIENDS,,,,Spojenecké příšery nejsou blokovány,Venlige monstre er ikke blokeret,Freundliche Monster werden nicht geblockt,,Amikaj monstroj ne estas baritaj,Monstruos amistosos no son bloqueados,,Myötämielisten hirviöiden esteetön liikkuminen,Monstres amicaux non bloqués,Barátságos szörnyek nem blokkolódnak,I mostri amichevoli non sono bloccati,仲間キャラは敵通行不可ラインの影響を受けない,아군 개체는 BLOCK 선분 무시,Vriendelijke monsters worden niet geblokkeerd.,Vennlige monstre er ikke blokkert,Przyjazne potwory nie mogą być blokowane,Monstros aliados não são bloqueados,,Monștrii aliați nu pot fi blocați,Не блокировать дружественных монстров,Пријатељска чудовишта се не блокирају,Dost canavarlar engellenmez -Limit Pain Elementals' Lost Souls,CMPTMNU_LIMITPAIN,,,,Omezit počet Ztrac. duší (Lost Souls) od Živlů (Pain Elementals),Grænse for tabte sjæle,Limit für Verlorene Seelen,,Limigi Perditajn Animojn de Doloro-Elementuloj,Limitar Almas Errantes de los Elementales del Dolor,,Rajoita kivun henkien kadonneitten sielujen määrää,Limiter âmes des élémentaires,Kiköpött Elveszett Lelkek limitálása,Limita le Anime Erranti degli Elementali del dolore,ペインエレメンタルのロストソウル制限,로스트 소울 소환 21개로 제한,Beperk de Verloren Zielen van Pijn Elementairs,Begrens smertelementalers tapte sjeler,Ogranicz Zagubione Dusze Elementala Bólu,Limitar Almas Perdidas criadas por Elementais da Dor,,Limitează numărul Sufletelor Pierdute create de Elementalii Durerii,Ограничить число потерянных душ от элементалей боли,Ограничи изгубљене душе од елементала патње,Acı Elementallerinin Kayıp Ruhlarını Sınırla -Monster movement is affected by effects,CMPTMNU_MBFMONSTERMOVE,,,,Pohyb příšer je ovlivněn efekty,Monsterbevægelse er påvirket af effekter,Monsterbewegung wird von Effekten beeinflusst,,Monstromovado estas afektita per efektoj,Los efectos afectan al movimiento de los monstruos,,Tehosteet vaikuttavat hirviöiden liikkumiseen,Mouvement monstre affecté par effets,Szörny sebesség függ az effektektől,Il movimento dei mostri è affetto dagli effetti,敵の移動が床の影響を受ける,구역의 이동 효과가 개체들에 영향,Monsterbeweging wordt beïnvloed door effecten,Monsterbevegelse påvirkes av effekter,Efekty wpływają na ruch potworów,Movimento dos monstros é afetado por efeitos,,Efectele afectează deplasarea monștrilor,Эффекты влияют на движение монстров,Ефекти утицају на покретљивост чудовишта,Canavar hareketi etkilerden etkilenir -Monsters cannot cross dropoffs,CMPTMNU_CROSSDROPOFF,,,,Příšery nemohou překročit výšiny,Monstre kan ikke krydse faldgruber,Monster können Abbruchkanten nicht überqueren,,Monstroj ne povas movi trans krutaĵojn,Los monstruos no pueden cruzar declives,,Hirviöt eivät voi ylittää pudotuksia,Monstres ne passent pas les corniches,Szörnyek le tudnak esni a lejtőről,I mostri non posso attraversare gli spigoli,敵はdropoffを横切れない,개체들이 난간에서 추락 불가,Monsters kunnen geen dropoffs kruisen,Monstre kan ikke krysse dropoffs,Potwory nie mogą przekraczać spadków,Monstros não podem atravessar penhascos,,Monștrii nu pot trece peste prăpăstii,Монстрам нельзя пересекать уступы,Чудовишта не могу прећи падове,Canavarlar inişleri geçemez -Monsters get stuck over dropoffs,CMPTMNU_DROPOFF,,,,Příšery se zasekávají na výšinách,Monstre bliver hængende over faldgruber,Monster bleiben auf Abbruchkanten hängen,,Monstroj ĉesiĝi super krutaĵoj,Los monstruos se atascan sobre declives,Los monstruos se atoran sobre declives,Hirviöt joutuvat jumiin pudotusten ylle,Monstres bloqués par les corniches,Szörnyek nem mennek tovább a lejtőnél,I mostri rimangono bloccati sugli spigoli,敵がdropoffにスタックする,개체들이 난간에 끼일 수 있음,Monsters komen vast te zitten boven dropoffs,Monstre blir sittende fast over dropoffs,Potwory mogą utknąć nad spadkami,Monstros ficam presos em penhascos,,Monștrii înțepenesc peste prăpăstii,Монстры застревают на уступах,Чудовишта се заглављују на падовима,Canavarlar inişlerde sıkışıp kalıyor -Monsters see invisible players,CMPTMNU_INVISIBILITY,,,,Příšery vidí neviditelné hráče,Monstre kan se usynlige spillere,Monster können unsichtbare Spieler sehen,,Monstroj povas vidi nevideblajn ludantojn,Los monstruos ven jugadores invisibles,,Hirviöt näkevät näkymättömät pelaajat,Monstres voient joueurs invisibles,Láthatatlanság alatt is látható a játékos,I mostri vedono i giocatori invisibili,敵が透明を見破る,개체들이 투명 플레이어 감지 가능,Monsters zien onzichtbare spelers,Monstre ser usynlige spillere,Potwory widzą niewidzialnych graczy,Monstros enxergam jogadores invisíveis,,Monștrii pot vedea jucătorii invizibili,Монстры видят невидимых игроков,Чудовишта могу да виде невидљиве играче,Canavarlar görünmez oyuncuları görür -No Minotaur floor flames in water,CMPTMNU_MINOTAUR,,,,Minotauři nemohou tvořit plameny ve vodě,Ingen Minotaur gulvflammer i vand,Keine Minotaurus-Flammen im Wasser,,Neniuj plankfajroj de Mintaŭroj en akvo,Sin llamas de minotauro en el agua,,Ei minotaurien lattialiekkejä vedessä,Pas de feu de Massetaur sur l'eau,Minotaurusz égő nyom nincs a vízben,Niente fiamme da terra del Minotauro sull'acqua,ミノタウロスの攻撃が水を通過しない,수면에서는 몰로타우어 지면화염 차단,Geen Minotaurus vloer vlammen in water,Ingen Minotaur-gulvflammer i vann,Brak płomieni Minotaura w wodzie,Desativar fogo do Marretauro na água,,Minotaurii nu pot folosi atacul de foc pe apă,Минотавры не создают огонь в воде,Минотаури не пале ватру у води,Suda Minotor zemin alevleri yok -Spawn item drops on the floor,CMPTMNU_NOTOSSDROPS,,,,Spadlé předměty se objeví na zemi,Spawn-genstande falder på gulvet,Gegenstände erscheinen auf dem Fußboden,,Ekaperigi faligitajn objektojn sur la plankon,Aparecer objetos dejados en el suelo,,Synnytä esinepudotukset lattialle,Objets lâchés direct au sol,Spawnolt tárgy a földön jelenik meg,Gli oggetti allo spawn cadono a terra,アイテムドロップが床に出る,아이템이 떨어질때 지면에 즉시 착지,Paaipunt druppels op de vloer,Spawn-element faller på gulvet,Obiekty pojawiają się na podłodze,Itens surgidos caem direto no chão,,Obiectele scăpate vor apărea la nivelul podelei,Выброшенные предметы создаются на земле,Одбачени предмети се појављују на поду,Eşya yere düşer -DehackEd Behavior,CMPTMNU_DEHACKEDBEHAVIOR,,,DehackEd Behaviour,DeHackEd,DehackEd Adfærd,DehackEd Verhalten,,Konduto de DehackEd,Comportamiento de DehackEd,,DehackEd-käyttäytyminen,Comportement DeHackEd,DeHackEd viselkedés,Comportamento DehackEd,Dehackedの挙動,DehackEd 관련 설정,DehackEd Gedrag,DehackEd oppførsel,Zachowanie DehackEd,Comportamento DehackEd,,Comportament DehackEd,Поведение DeHackEd,DehackEd понашање,DehackEd Davranışı -DEH health settings like Doom2.exe,CMPTMNU_DEHHEALTH,,,,Nastavení DEH jako v Doom2.exe,DEH sundhedsindstillinger som Doom2.exe,DEH Gesundheitseinstellungen wie in Doom2.exe,,DEH sanagordoj kiel Doom2.exe,Configuración de salud DEH como en Doom2.exe,,DEH-terveysasetukset kuin Doom2.exessä,Para. santé DEH comme Doom2.EXE,DEH életerő beállítások mint a Doom2.exe esetében,Impostazioni di salute DEH come in Doom2.exe,Doom2.exe式のDehヘルス設定,DEH 자체의 체력 최댓값 사용,DEH-gezondheidsinstellingen zoals Doom2.exe,DEH helseinnstillinger som Doom2.exe,Ustawienia zrowia DEH jak w Doom2.exe,Configurações de saúde de DEH como em Doom2.exe,,Setări sănătate în DEH precum în Doom2.exe,Настройки здоровья DEH как в Doom2.exe,DEH подешавања здравља као у Doom2.exe,Doom2.exe gibi DEH sağlık ayarları -Original A_Mushroom speed in DEH mods,CMPTMNU_MUSHROOM,,,,Původní rychlost pro A_Mushroom,Original A_Mushroom hastighed i DEH mods,Originale Berechnung für A_Mushroom,,Originala A_Mushroom rapideco en DEH-modifaĵoj,Velocidad original de A_Mushroom en mods con DEH,,Alkuperäinen A_Mushroom-nopeus DEH-modeissa,Vitesse A_Mushroom originale pour DEH,Eredeti A_Mushroom sebesség a DEH modoknál,Velocità originale di A_Mushroom nei mod DEH,Deh Modでの元のA_Mushroom速度,A_Mushroom효과가 MBF 원본의 속력 사용,Originele A_Mushroom in DEH-modellen,Original A_Mushroom hastighet i DEH mods,Oryginalna prędkość A_Mushroom w modach DEH,Velocidade original do A_Mushroom em mods DEH,,Folosește viteza originală pentru A_Mushroom în DEH în moduri,Изначальная скорость A_Mushroom в мод. DEH,Оригинална брзина A_Mushroom в DEH модовима,DEH modlarında orijinal A_Mushroom hızı -Map/Action Behavior,CMPTMNU_MAPACTIONBEHAVIOR,,,Map/Action Behaviour,Levely a akce,Map/Action Adfærd,Level/Aktionsverhalten,,Mapo/Ago-Konduto,Comportamiento Mapa/Acción,,Tason/Toimintojen käyttäytyminen,Comportement Niveau/Actions,Pálya/Akció viselkedés,Comportamento Mappa/Azioni,マップ/アクションの挙動,맵/동작 관련 설정,Kaart/Actiegedrag,Kart / handling oppførsel,Zachowanie Mapy/Akcji,Comportamento de Mapa/Ação,,Comportament hartă/actori,Поведение уровней/действий,Понашање нивоа/догађаја,Harita/Eylem Davranışı -All special lines can block ,CMPTMNU_USEBLOCKING,,,,Veškeré akční čáry blokují použití hráčem,Alle specielle linjer kan blokere ,Alle Speziallinien blockieren Benutzung,,Ĉiuj el specialaj linioj povas bari je ,Todas las líneas especiales pueden bloquear ,,Kaikki erikoisviivat voivat tukkia -toiminnon,Toute ligne d'action bloque ,Minden speciális sor blokkolhatja a parancsot,Tutte le linee speciali possono bloccare il comando ,全てのSpecial Linesがをブロック,특정 선상에 겹쳐있을 시 <사용> 무력화,Alle speciale lijnen kunnen blokkeren.,Alle spesielle linjer kan blokkere ,Wszystkie specjalne linie mogą blokować ,Todas as linhas especiais podem bloquear o comando ,,Toate liniile speciale pot bloca ,Все специальные линии могут блокировать использование,Све специјалне линије могу да блокирају ,Tüm özel hatlar engelleyebilir +",Setor de saída conta para porcentagem de mortes,Setor de saída conta para percentagem de mortes,Numărare decese monștri în sectoare finale,Засчитывать убийства монстров в секторах конца игры,Урачунај убиство чудовишта у коначним секторима,Slutsektorn räknas för dödande %,Öldürme %'si için son sektör sayıları +Deathmatch Settings,GMPLYMNU_DEATHMATCH,,,,Nastavení deathmatche,Indstillinger for Deathmatch,Deathmatcheinstellungen,,Mortmatĉo-agordoj,Configuración modo a muerte,,Kuolonotteluasetukset,Options Deathmatch,Deathmatch beállítások,Impostazioni deathmatch,デスマッチの設定,데스매치 설정,Deathmatch instellingen,Deathmatch-innstillinger,Ustawienia Deathmatchu,Configurações de Deathmatch,,Setări Deathmatch,Настройки боя насмерть,Детмеч подешавања,Inställningar för Deathmatch,Ölüm Maçı Ayarları +Weapons stay,GMPLYMNU_WEAPONSSTAY,,,,Zbraně zůstávají,Våben forbliver,Waffen bleiben,,Armiloj restiĝas,Las armas se quedan,,Aseet pysyvät,Armes restent au sol quand prises,Fegyverek mindig felvehetőek,Le armi rimangono in posizione,武器を取得時も残す,습득 후 무기가 남아있기,Wapenverblijven,Våpen forblir,Bronie zostają,Armas permanecem,,Părăsire arme după selectare,Оставлять оружие после подбора,Оружје се остаје након купљења,Vapen stannar kvar,Silahlar kalıyor +Allow powerups,GMPLYMNU_ALLOWPOWERUPS,,,,Povolit bonusy,Tillad powerups,Boni erlauben,,Permesi plifortigaĵojn,Permitir poderes,,Salli tehostimet,Autoriser powerups,Powerupok engedélyezése,Potenziamenti consentiti,パワーアップアイテムを出現させる,파워 업 허용,Power-ups toestaan,Tillat powerups,Pozwól na wzmocnienia,Permitir powerups,,Permite bonusuri,Разрешить бонусы,Дозволи бонусе,Tillåter powerups,Güçlendirmelere izin ver +Allow health,GMPLYMNU_ALLOWHEALTH,,,,Povolit zdraví,Tillad sundhed,Gesundheit erlauben,,Permesi sanon,Permitir salud,,Salli terveysesineet,Autoriser objets santé,Életerő engedélyezése,Oggetti per la salute consentiti,回復アイテムを出現させる,체력 회복 아이템 허용,Gezondheid toestaan,Tillat helse,Pozwól na przedmioty zdrowotne,Permitir itens de saúde,,Permite prim-ajutor,Разрешить здоровье,Дозволи бонусе за здравље,Tillåter hälsa,Sağlığa izin ver +Allow armor,GMPLYMNU_ALLOWARMOR,,,Allow armour,Povolit brnění,Tillad rustning,Panzer erlauben,,Permesi kirason,Permitir armadura,,Salli panssariesineet,Autoriser objets armure,Páncél engedélyezése,Armature consentite,アーマーを出現させる,아머 허용,Pantsertoeslag toestaan,Tillat rustning,Pozwól na pancerz,Permitir itens de armadura,,Permite bonusuri de armură,Разрешить броню,Дозволи оклоп,Tillåt rustning,Zırha izin ver +Spawn farthest,GMPLYMNU_SPAWNFARTHEST,,,,Spawnovat hráče co nejdále od sebe,Spawn længst væk,Am weitesten entfernten Punkt erscheinen,,Ekaperi plej fore,Aparecer más lejos,,Herää henkiin kauimpaa,Apparaître au plus loin,Legmesszebb születés,Spawn il più lontano possibile,他のプレイヤーから最遠の場所に復活,먼 곳에서 소환,Kuitschieten het verst verwijderd,Spawn lengst,Pojaw się jak najdalej,Surgimento mais longe,,Apariție cât mai departată de ceilalți,Воскрешение подальше от остальных,Оживљавање даље од других,Spawna längst bort,En uzakta yumurtla +Same map,GMPLYMNU_SAMEMAP,,,,Stejná mapa,Samme kort,Gleiches Level,,Sama mapo,Mismo mapa,,Sama taso,Même Carte,Ugyanazon pálya,Stessa mappa,同じMAPを繰り返す,같은 맵 플레이,Dezelfde kaart,Samme kart,Ta sama mapa,Mesmo mapa,,Reluare nivel,Зациклить уровень,Понављање нивоа,Samma karta,Aynı harita +Force respawn,GMPLYMNU_FORCERESPAWN,,,,Vynutit respawn,Tvinge respawn,Zurückkehren erzwingen,,Devigi reekaperon,Forzar reaparición,,Pakota henkiinherääminen,Forcer Réapparition,Újraszületés kényszerítése,Forza il respawn,死亡後に強制復活,강제 부활,Respawn is gedwongen,Force respawn,Wymuś ponowne pojawienie się,Forçar reaparecimento,,Reapariție instantă,Моментальное воскрешение,Форсирано оживљавање,Tvinga till återkomst,Yeniden doğmaya zorla +Allow exit,GMPLYMNU_ALLOWEXIT,,,,Povolit ukončení levelu,Tillad at forlade,Verlassen erlauben,,Permesi eliron,Permitir salir,,Salli tasosta poistuminen,Autoriser Sortie,Kijárat engedélyezése,Uscita consentita,出口の使用を許可,탈출 허용,Uitgang toestaan,Tillat utgang,Pozwól na wyjście,Permitir saída,,Permite ieșirea,Разрешить выход,Дозволи излазак из нивоа,Tillåter utgång,Çıkışa izin ver +Barrels respawn,GMPLYMNU_BARRELSRESPAWN,,,,Barely se respawnují,Tønder respawner,Fässer kehren zurück,,Bareloj reekaperas,Reaparecer barriles,,Tynnyrit syntyvät takaisin,Réapparition des Tonneaux,Hordók újraszületése,Respawn barili esplosivi,爆発バレルを復活させる,폭발통 재생성,Vaten respawn,Tønner respawn,Beczki pojawiają się ponownie,Barrís reaparecem,,Butoaiele reapar,Восстановление бочек,Бурад се ресетују,Tunnor återkommer,Variller yeniden doğar +Respawn protection,GMPLYMNU_RESPAWNPROTECTION,,,,Ochrana po respawnu,Respawn-beskyttelse,Schutz beim Zurückkehren,,Protekto de reekapero,Reaparecer protección,,Henkiinheräämissuoja,Protection à la réapparition,Újraszületési védelem,Protezione al respawn,復活したばかりのプレイヤーを保護,부활시 무적,Respawn bescherming,Respawn-beskyttelse,Ochrona przy ponownym pojawieniu się,Proteção de reaparecimento,,Protecție la apariția pe hartă,Кратковременная защита после воскрешения,Ресетује се заштита,Skydd för återstart,Yeniden doğma koruması +Lose frag if fragged,GMPLYMNU_LOSEFRAG,,,,"Hráč ztratí frag, pokud je zabit",Mister frag hvis der er en fragged,Fragabzug bei Tod,,Perdi ludmurdon se ludmurdita,Perder baja al morir,,"Frägin menettäminen, jos joutuu frägätyksi",Perdre 1 frag quand tué,Halál esetén pont veszítése,Perdere i frag se fraggato,キルされた場合は得点を失う,적에게 사망시 점수를 잃음,Verlies frag bij dood,Miste frag hvis fragged,Strać fraga jeśli jesteś sfragowany,Perder frag ao ser fragado,,Pierdere din victime la deces,Терять фраг при смерти,Изгубити гранату ако опаљена,Förlorar frag om du blir träffad,Parçalanırsa parça kaybeder +Keep frags gained,GMPLYMNU_KEEPFRAGS,,,,Ponechávat fragy mezi levely,Beholde vundne frags,Frags zwischen Leveln behalten,,Teni ludmurdojn gajnitajn,Mantener bajas ganadas,,Pidä ansaitut frägit,Garder les frags gagnés,Megszerzett pontok megmaradnak,Mantenere i frag vinti,MAP変更後も得点を保持する,맵 변경 시 점수 유지,Houd frags opgedaan,Behold frags vunnet,Zachowaj zdobyte fragi,Manter frags ganhos,,Păstrare număr victime,Сохранять фраги между уровнями,Задржати стечене гранате,Behåll de frags som vunnits,Kırıntıları kazanmaya devam edin +No team switching,GMPLYMNU_NOTEAMSWITCH,,,,Uzamknout týmy,Ingen holdskifte,Kein Teamwechsel,,Neniu teamŝanĝado,No cambiar equipos,,Ei joukkueenvaihtoa,Pas de changement d'équipe,Nincs csapatváltás,Nessun cambio di squadra,チーム変更を禁止,팀 변경 없음,Geen teamwisseling,Ingen lagbytte,Zakaz zmieniania drużyn,Desativar troca de time,Desativar troca de equipa,Nu permite schimbarea echipelor,Запретить переход между командами,Нема мешања тимова,Inget byte av lag,Takım değiştirme yok +Cooperative Settings,GMPLYMNU_COOPERATIVE,,,,Nastavení co-op módu,Kooperativ indstillinger,Kooperativ-Einstellungen,,Agordoj de koopera reĝimo,Configuración de cooperativo,,Yhteispeliasetukset,Options Coopératives,Együttműködő beállítások,Impostazioni cooperativa,協力モードの設定,협동 플레이 설정,Coöperatieve instellingen,Samarbeidsinnstillinger,Ustawienia Kooperacji,Configurações de jogo cooperativo,,Setări cooperative,Настройки совместной игры,Кооперативне поставке,Inställningar för samarbete,Kooperatif Ayarları +Spawn multiplayer weapons,GMPLYMNU_MULTIPLAYERWEAPONS,,,,Spawnovat multiplayerově zbraně,Spawn multiplayer-våben,Deathmartch Waffen sind verfügbar,,Ekaperigi armilojn por plurludanta reĝimo,Aparecer armas multi.,,Kuolonotteluaseet saatavilla,Spawns d'armes deathmatch,Többjátékos fegyverek engedélyezése,Fai apparire le armi di multigiocatore,マルチプレイ用の武器を出現させる,멀티플레이어 무기 소환,Spawn multi. wapens,Spawn flerspillervåpen,Zezwól na bronie trybu dla wielu graczy,Surgimento de armas em multijogador,,Permite apariția armelor din modul online,Появление оружия из сетевой игры,Створити мулти оружја,Spawna flerspelarvapen,Çok oyunculu silahları ortaya çıkarma +Lose entire inventory,GMPLYMNU_LOSEINVENTORY,,,,Ztrácet celý inventář,Mister hele inventaret,Verliere ganzes Inventar,,Perdi tutan inventorion,Perder todo el inventario,,Menetä kaikki varusteet,Perdre l'inventaire,Teljes készlet elvesztése,Perdere l'inventario,死亡時に全ての所持品を失う,인벤토리 비우기,Verlies van de volledige inventaris,Miste hele beholdningen,Utrać cały ekwipunek,Perder todo o inventário,,Pierdere inventar,Терять весь инвентарь при смерти,Изгубити цело складиште,Förlorar hela inventariet,Tüm envanteri kaybetmek +Keep keys,GMPLYMNU_KEEPKEYS,,,,Ponechat klíče,Beholde nøgler,Schlüssel behalten,,Teni ŝlosiojn,Mantener llaves,,Pidä avaimet,Garder clés,Kulcsok megtartása,Mantenere le chiavi,死亡後もキーを保持する,열쇠들을 소지하고 시작,Sleutels bewaren,Behold nøkler,Zachowaj klucze,Manter chaves,,Păstrare chei,Сохранять ключи,Задржати кључеве,Behåll nycklar,Anahtarları sakla +Keep weapons,GMPLYMNU_KEEPWEAPONS,,,,Ponechat zbraně,Behold våben,Waffen behalten,,Teni armilojn,Mantener armas,,Pidä aseet,Garder armes,Fegyverek megtartása,Mantenere le armi,死亡後も武器を保持する,무기들을 소지하고 시작,Wapens bewaren,Behold våpen,Zachowaj bronie,Manter armas,,Păstrare arme,Сохранять оружие,Задржати оружје,Behåll vapen,Silahları saklayın +Keep armor,GMPLYMNU_KEEPARMOR,,,Keep armour,Ponechat brnění,Behold rustning,Rüstung behalten,,Teni kirason,Mantener armadura,,Pidä panssari,Garder armure,Páncél megtartása,Mantenere l'armatura,死亡後もアーマーを保持する,아머를 소지하고 시작,Pantser bewaren,Behold rustning,Zachowaj pancerz,Manter armadura,,Păstrare armură,Сохранять броню,Задржати панцир,Behåll rustning,Zırhı sakla +Keep powerups,GMPLYMNU_KEEPPOWERUPS,,,,Ponechat bonusy,Beholde powerups,Behalte Boni,,Teni plifortigaĵojn,Mantener poderes,,Pidä tehostimet,Garder powerups,Powerupok megtartása,Mantenere i potenziamenti,死亡後もパワーアップを保持する,파워업을 소지하고 시작,Power-ups bewaren,Behold powerups,Zachowaj wzmocnienia,Manter powerups,,Păstrare bonusuri,Сохранять супербонусы,Задржати повећану моћ,Behåll powerups,Güçlendirmeleri sakla +Keep ammo,GMPLYMNU_KEEPAMMO,,,,Ponechat munici,Beholde ammunition,Munition behalten,,Teni municion,Mantener munición,,Pidä ammukset,Garder munitions,Muníció megtartása,Mantenere le ammunizioni,死亡後も弾薬を保持する,탄약을 소지하고 시작,Munitie bewaren,Behold ammunisjon,Zachowaj amunicję,Manter munição,,Păstrare armură,Сохранять патроны,Задржати муницију,Behålla ammunition,Cephaneyi sakla +Lose half ammo,GMPLYMNU_LOSEHALFAMMO,,,,Ztratit polovinu munice,Mister halvdelen af ammunitionen,Halbe Munition verlieren,,Perdi duonon de onia municio,Perder la mitad de la munición,,Menetä puolet ammuksista,Perdre la moité des munitions,Fele muníció elvesztése,Perdere metà ammunizioni,死亡時に弾を半分失う,탄약의 반을 잃음,Verlies halve munitie,Miste halv ammunisjon,Utrać pół amunicji,Perder metade da munição,,Pierdere jumătate din armură,Терять половину патронов,Изгубити пола муниције,Förlorar halva ammunitionen,Cephanenin yarısını kaybet +Spawn where died,GMPLYMNU_SPAWNWHEREDIED,,,,Respawn na místě smrti,Spawn hvor du døde,Neuerscheinen wo gestorben,,Ekaperigi kie oni mortigis,Aparecer donde moriste,,Herää henkiin kuolinpaikalla,Réapparaitre sur lieu de mort,Halál helyén újraszületés,Respawn nel luogo di morte,死亡したその場で復活,죽은 곳에서 소환,Kuit waar gestorven is,Gyte der du døde,Pojaw się znów tam gdzie zginąłeś,Surgir no local da morte,Reaparecer onde morreu,Apariție la locul decesului,Воскрешение на месте смерти,Оживљавање на месту смрти,Spawna där du dog,Öldüğü yerde yumurtlama +Always spawn multiplayer objects,GMPLYMNU_ALWAYSSPAWNMULTI,,,,Vždy spawnovat multiplayerové objekty,Spawn altid multiplayer-objekter,Mehrspielerobjekte immer erzeugen,,Ĉiam ekaperi plurludantajn objektojn,Siempre hacer aparecer objetos en el modo multijugador,,Aina luo moninpelioliot,Toujours créer des objets multi-joueurs,Mindig megjelennek a többjátékos tárgyak,Fai sempre apparire gli oggetti di multigiocatore,常にマルチプレイ用の物を出現,,Altijd multiplayer objecten spawnen,Alltid gyte flerspillerobjekter,Pozwól na przedmioty dla trybu wielu graczy,Permitir surgimento de objetos multijogador,,Permite apariția obiectelor din multiplayer,Появление объектов из сетевой игры,Увек стварајте објекте за више играча,Alltid spawna flerspelarobjekt,Her zaman çok oyunculu nesneler oluşturun +Allow Vertical Bullet Spread,GMPLYMNU_NOVERTSPREAD,,,,Povolit svislý rozptyl střelby,Tillad lodret kuglespredning,Vertikale Streuung erlauben,,Permesi vertikalan kuglan disvastiĝon,Desparramar balas de todas las armas en vertical,,Permesu Vertikalan Kuglon Disvastiĝon ,Permettre la propagation verticale des balles,Vertikális fegyverszórás engedélyezve,Permetti la diffusione dei proiettili in verticale,垂直方向への散弾を許可,,Verticale kogelspreiding toestaan,Tillat vertikal kulespredning,Pozwól na pionowy rozrzut pocisków,Permitir espalhamento vertical das balas,,Permiteți răspândirea verticală a gloanțelor,Разрешить вертикальный разброс пуль,Дозволи вертикално ширење метака,Tillåt vertikal kulspridning,Dikey Mermi Yayılımına İzin Ver +Weapons give extra ammo (DM),GMPLYMNU_NOEXTRAAMMO,,,,Zbraně dávají munici navíc (DM),Våben giver ekstra munition (DM),Waffen geben Extramunition,,Armiloj donas ekstran municion (DM),Las armas dan munición extra (DM),,Armiloj donas ekstran municion (DM),Les armes donnent des munitions supplémentaires (DM),A fegyverek extra lőszert adnak (DM),Le armi danno munizioni extra (DM),武器に追加弾薬を付与 (DMのみ),,Wapens geven extra munitie (DM),Våpen gir ekstra ammunisjon (DM),Broń daje dodatkową amunicję (DM),Armas dão munição extra (DM),,Armele oferă muniție suplimentară (DM),Оружие даёт дополнительные патроны (бой насмерть),Оружје даје додатну муницију (ДМ),Vapen ger extra ammunition (DM),Silahlar ekstra cephane verir (DM) +Compatibility Options,OPTMNU_COMPATIBILITY,,,,Kompatibilita,Kompatibilitetsindstillinger,Kompatibilitätsoptionen,Ρυθμίσεις Συμβατότητας,Kongruo-agordoj,Opciones de compatibilidad,,Yhteensopivuusasetukset,Options de Compatibilité,Kompatibilitási beállítások,Opzioni Compatibilità,互換性 オプション,호환 설정,Compatibiliteitsopties,Kompatibilitetsalternativer,Opcje Zgodności,Opções de compatibilidade,,Setări de Compatibilitate,Настройки совместимости,Компатибилност,Kompatibilitetsalternativ,Uyumluluk Seçenekleri +Compatibility Options,CMPTMNU_TITLE,,,,Nastavení kompatibility,Kompatibilitetsindstillinger,Kompatibilitätsoptionen,Ρυθμίσεις Συμβατότητας,Kongruo-agordoj,Opciones de compatibilidad,,Yhteensopivuusasetukset,Options Compatibilité,Kompatibilitási beállítások,Opzioni compatibilità,互換性 オプション,호환성 설정,Compatibiliteitsopties,Kompatibilitetsalternativer,Opcje Zgodności,Opções de compatibilidade,,Setări de Compatibilitate,Настройки совместимости,Компатибилна подешавања,Kompatibilitetsalternativ,Uyumluluk Seçenekleri +Compatibility mode,CMPTMNU_MODE,,,,Režim kompatibility,Kompatibilitetstilstand,Kompatibilitätsmodus,,Kongruo-reĝimo,Modo de Compatibilidad,,Yhteensopivuustila,Mode de compatibilité,Kompatibilitási mód,Modalità compatibilità,互換性モード,호환 모드,Compatibiliteitsmodus,Kompatibilitetsmodus,Tryb Zgodności,Modo de compatibilidade,,Mod Compatibilitate,Режим совместимости,Компатибилни мод,Kompatibilitetsläge,Uyumluluk modu +Actor Behavior,CMPTMNU_ACTORBEHAVIOR,,,Actor Behaviour,Objekty,Skuespilleradfærd,Verhalten der Akteure,,Aktorkonduto,Comportamiento del actor,,Olioiden käyttäytyminen,Comportement des Acteurs,Actor viselkedés,Comportamento degli attori,アクターの挙動,개체 관련 설정,Gedrag van de acteur,Skuespilleroppførsel,Zachowanie Aktorów,Comportamento de atores,,Comportament actori,Поведение объектов (акторов),Понашање актора,Beteende hos skådespelare,Aktör Davranışı +Friendly monsters aren't blocked,CMPTMNU_NOBLOCKFRIENDS,,,,Spojenecké příšery nejsou blokovány,Venlige monstre er ikke blokeret,Freundliche Monster werden nicht geblockt,,Amikaj monstroj ne estas baritaj,Monstruos amistosos no son bloqueados,,Myötämielisten hirviöiden esteetön liikkuminen,Monstres amicaux non bloqués,Barátságos szörnyek nem blokkolódnak,I mostri amichevoli non sono bloccati,仲間キャラは敵通行不可ラインの影響を受けない,아군 개체는 BLOCK 선분 무시,Vriendelijke monsters worden niet geblokkeerd.,Vennlige monstre er ikke blokkert,Przyjazne potwory nie mogą być blokowane,Monstros aliados não são bloqueados,,Monștrii aliați nu pot fi blocați,Не блокировать дружественных монстров,Пријатељска чудовишта се не блокирају,Vänliga monster blockeras inte,Dost canavarlar engellenmez +Limit Pain Elementals' Lost Souls,CMPTMNU_LIMITPAIN,,,,Omezit počet Ztrac. duší (Lost Souls) od Živlů (Pain Elementals),Grænse for tabte sjæle,Limit für Verlorene Seelen,,Limigi Perditajn Animojn de Doloro-Elementuloj,Limitar Almas Errantes de los Elementales del Dolor,,Rajoita kivun henkien kadonneitten sielujen määrää,Limiter âmes des élémentaires,Kiköpött Elveszett Lelkek limitálása,Limita le Anime Erranti degli Elementali del dolore,ペインエレメンタルのロストソウル制限,로스트 소울 소환 21개로 제한,Beperk de Verloren Zielen van Pijn Elementairs,Begrens smertelementalers tapte sjeler,Ogranicz Zagubione Dusze Elementala Bólu,Limitar Almas Perdidas criadas por Elementais da Dor,,Limitează numărul Sufletelor Pierdute create de Elementalii Durerii,Ограничить число потерянных душ от элементалей боли,Ограничи изгубљене душе од елементала патње,Begränsa Pain Elementals förlorade själar,Acı Elementallerinin Kayıp Ruhlarını Sınırla +Monster movement is affected by effects,CMPTMNU_MBFMONSTERMOVE,,,,Pohyb příšer je ovlivněn efekty,Monsterbevægelse er påvirket af effekter,Monsterbewegung wird von Effekten beeinflusst,,Monstromovado estas afektita per efektoj,Los efectos afectan al movimiento de los monstruos,,Tehosteet vaikuttavat hirviöiden liikkumiseen,Mouvement monstre affecté par effets,Szörny sebesség függ az effektektől,Il movimento dei mostri è affetto dagli effetti,敵の移動が床の影響を受ける,구역의 이동 효과가 개체들에 영향,Monsterbeweging wordt beïnvloed door effecten,Monsterbevegelse påvirkes av effekter,Efekty wpływają na ruch potworów,Movimento dos monstros é afetado por efeitos,,Efectele afectează deplasarea monștrilor,Эффекты влияют на движение монстров,Ефекти утицају на покретљивост чудовишта,Monsterrörelse påverkas av effekter,Canavar hareketi etkilerden etkilenir +Monsters cannot cross dropoffs,CMPTMNU_CROSSDROPOFF,,,,Příšery nemohou překročit výšiny,Monstre kan ikke krydse faldgruber,Monster können Abbruchkanten nicht überqueren,,Monstroj ne povas movi trans krutaĵojn,Los monstruos no pueden cruzar declives,,Hirviöt eivät voi ylittää pudotuksia,Monstres ne passent pas les corniches,Szörnyek le tudnak esni a lejtőről,I mostri non posso attraversare gli spigoli,敵はdropoffを横切れない,개체들이 난간에서 추락 불가,Monsters kunnen geen dropoffs kruisen,Monstre kan ikke krysse dropoffs,Potwory nie mogą przekraczać spadków,Monstros não podem atravessar penhascos,,Monștrii nu pot trece peste prăpăstii,Монстрам нельзя пересекать уступы,Чудовишта не могу прећи падове,Monster kan inte korsa stupstockar,Canavarlar inişleri geçemez +Monsters get stuck over dropoffs,CMPTMNU_DROPOFF,,,,Příšery se zasekávají na výšinách,Monstre bliver hængende over faldgruber,Monster bleiben auf Abbruchkanten hängen,,Monstroj ĉesiĝi super krutaĵoj,Los monstruos se atascan sobre declives,Los monstruos se atoran sobre declives,Hirviöt joutuvat jumiin pudotusten ylle,Monstres bloqués par les corniches,Szörnyek nem mennek tovább a lejtőnél,I mostri rimangono bloccati sugli spigoli,敵がdropoffにスタックする,개체들이 난간에 끼일 수 있음,Monsters komen vast te zitten boven dropoffs,Monstre blir sittende fast over dropoffs,Potwory mogą utknąć nad spadkami,Monstros ficam presos em penhascos,,Monștrii înțepenesc peste prăpăstii,Монстры застревают на уступах,Чудовишта се заглављују на падовима,Monster fastnar över stupstockar,Canavarlar inişlerde sıkışıp kalıyor +Monsters see invisible players,CMPTMNU_INVISIBILITY,,,,Příšery vidí neviditelné hráče,Monstre kan se usynlige spillere,Monster können unsichtbare Spieler sehen,,Monstroj povas vidi nevideblajn ludantojn,Los monstruos ven jugadores invisibles,,Hirviöt näkevät näkymättömät pelaajat,Monstres voient joueurs invisibles,Láthatatlanság alatt is látható a játékos,I mostri vedono i giocatori invisibili,敵が透明を見破る,개체들이 투명 플레이어 감지 가능,Monsters zien onzichtbare spelers,Monstre ser usynlige spillere,Potwory widzą niewidzialnych graczy,Monstros enxergam jogadores invisíveis,,Monștrii pot vedea jucătorii invizibili,Монстры видят невидимых игроков,Чудовишта могу да виде невидљиве играче,Monster ser osynliga spelare,Canavarlar görünmez oyuncuları görür +No Minotaur floor flames in water,CMPTMNU_MINOTAUR,,,,Minotauři nemohou tvořit plameny ve vodě,Ingen Minotaur gulvflammer i vand,Keine Minotaurus-Flammen im Wasser,,Neniuj plankfajroj de Mintaŭroj en akvo,Sin llamas de minotauro en el agua,,Ei minotaurien lattialiekkejä vedessä,Pas de feu de Massetaur sur l'eau,Minotaurusz égő nyom nincs a vízben,Niente fiamme da terra del Minotauro sull'acqua,ミノタウロスの攻撃が水を通過しない,수면에서는 몰로타우어 지면화염 차단,Geen Minotaurus vloer vlammen in water,Ingen Minotaur-gulvflammer i vann,Brak płomieni Minotaura w wodzie,Desativar fogo do Marretauro na água,,Minotaurii nu pot folosi atacul de foc pe apă,Минотавры не создают огонь в воде,Минотаури не пале ватру у води,Ingen Minotaur golvlåga flammar i vatten,Suda Minotor zemin alevleri yok +Spawn item drops on the floor,CMPTMNU_NOTOSSDROPS,,,,Spadlé předměty se objeví na zemi,Spawn-genstande falder på gulvet,Gegenstände erscheinen auf dem Fußboden,,Ekaperigi faligitajn objektojn sur la plankon,Aparecer objetos dejados en el suelo,,Synnytä esinepudotukset lattialle,Objets lâchés direct au sol,Spawnolt tárgy a földön jelenik meg,Gli oggetti allo spawn cadono a terra,アイテムドロップが床に出る,아이템이 떨어질때 지면에 즉시 착지,Paaipunt druppels op de vloer,Spawn-element faller på gulvet,Obiekty pojawiają się na podłodze,Itens surgidos caem direto no chão,,Obiectele scăpate vor apărea la nivelul podelei,Выброшенные предметы создаются на земле,Одбачени предмети се појављују на поду,Spawner föremål faller på golvet.,Eşya yere düşer +DehackEd Behavior,CMPTMNU_DEHACKEDBEHAVIOR,,,DehackEd Behaviour,DeHackEd,DehackEd Adfærd,DehackEd Verhalten,,Konduto de DehackEd,Comportamiento de DehackEd,,DehackEd-käyttäytyminen,Comportement DeHackEd,DeHackEd viselkedés,Comportamento DehackEd,DehackEdの挙動,DehackEd 관련 설정,DehackEd Gedrag,DehackEd oppførsel,Zachowanie DehackEd,Comportamento DehackEd,,Comportament DehackEd,Поведение DeHackEd,DehackEd понашање,DehackEd-beteende,DehackEd Davranışı +DEH health settings like Doom2.exe,CMPTMNU_DEHHEALTH,,,,Nastavení DEH jako v Doom2.exe,DEH sundhedsindstillinger som Doom2.exe,DEH Gesundheitseinstellungen wie in Doom2.exe,,DEH sanagordoj kiel Doom2.exe,Configuración de salud DEH como en Doom2.exe,,DEH-terveysasetukset kuin Doom2.exessä,Para. santé DEH comme Doom2.EXE,DEH életerő beállítások mint a Doom2.exe esetében,Impostazioni di salute DEH come in Doom2.exe,Doom2.exe式のDEHヘルス設定,DEH 자체의 체력 최댓값 사용,DEH-gezondheidsinstellingen zoals Doom2.exe,DEH helseinnstillinger som Doom2.exe,Ustawienia zrowia DEH jak w Doom2.exe,Configurações de saúde de DEH como em Doom2.exe,,Setări sănătate în DEH precum în Doom2.exe,Настройки здоровья DEH как в Doom2.exe,DEH подешавања здравља као у Doom2.exe,DEH-hälsoinställningar som Doom2.exe,Doom2.exe gibi DEH sağlık ayarları +Original A_Mushroom speed in DEH mods,CMPTMNU_MUSHROOM,,,,Původní rychlost pro A_Mushroom,Original A_Mushroom hastighed i DEH mods,Originale Berechnung für A_Mushroom,,Originala A_Mushroom rapideco en DEH-modifaĵoj,Velocidad original de A_Mushroom en mods con DEH,,Alkuperäinen A_Mushroom-nopeus DEH-modeissa,Vitesse A_Mushroom originale pour DEH,Eredeti A_Mushroom sebesség a DEH modoknál,Velocità originale di A_Mushroom nei mod DEH,DEH Modでの元のA_Mushroom速度,A_Mushroom효과가 MBF 원본의 속력 사용,Originele A_Mushroom in DEH-modellen,Original A_Mushroom hastighet i DEH mods,Oryginalna prędkość A_Mushroom w modach DEH,Velocidade original do A_Mushroom em mods DEH,,Folosește viteza originală pentru A_Mushroom în DEH în moduri,Изначальная скорость A_Mushroom в мод. DEH,Оригинална брзина A_Mushroom в DEH модовима,Ursprunglig A_Mushroom-hastighet i DEH-modifieringar,DEH modlarında orijinal A_Mushroom hızı +Map/Action Behavior,CMPTMNU_MAPACTIONBEHAVIOR,,,Map/Action Behaviour,Levely a akce,Map/Action Adfærd,Level/Aktionsverhalten,,Mapo/Ago-Konduto,Comportamiento Mapa/Acción,,Tason/Toimintojen käyttäytyminen,Comportement Niveau/Actions,Pálya/Akció viselkedés,Comportamento Mappa/Azioni,マップ/アクションの挙動,맵/동작 관련 설정,Kaart/Actiegedrag,Kart / handling oppførsel,Zachowanie Mapy/Akcji,Comportamento de Mapa/Ação,,Comportament hartă/actori,Поведение уровней/действий,Понашање нивоа/догађаја,Beteende för kartor/handlingar,Harita/Eylem Davranışı +All special lines can block ,CMPTMNU_USEBLOCKING,,,,Veškeré akční čáry blokují použití hráčem,Alle specielle linjer kan blokere ,Alle Speziallinien blockieren Benutzung,,Ĉiuj el specialaj linioj povas bari je ,Todas las líneas especiales pueden bloquear ,,Kaikki erikoisviivat voivat tukkia -toiminnon,Toute ligne d'action bloque ,Minden speciális sor blokkolhatja a parancsot,Tutte le linee speciali possono bloccare il comando ,全てのSpecial Linesがをブロック,특정 선상에 겹쳐있을 시 <사용> 무력화,Alle speciale lijnen kunnen blokkeren.,Alle spesielle linjer kan blokkere ,Wszystkie specjalne linie mogą blokować ,Todas as linhas especiais podem bloquear o comando ,,Toate liniile speciale pot bloca ,Все специальные линии могут блокировать использование,Све специјалне линије могу да блокирају ,Alla speciella linjer kan blockera ,Tüm özel hatlar engelleyebilir Allow any bossdeath for level special,CMPTMNU_ANYBOSSDEATH,,,,Smrt jakéhokoli bosse může aktivovat speciální akci levelu,Tillad enhver bossdeath for level special,Jeder Boss-Tod zählt für Spezialaktionen,,Permesi iun ajn estro-morton por nivelspecialo,Permitir cualquier muerte de jefe por especial de nivel,,Mikä tahansa pomokuolema lasketaan tason erikoistoiminnossa,N'importe quel boss active actions boss,Főgonosz halála megengedett a speciális pályákon,"Qualunque morte del boss per le azioni speciali consentita -",いずれのBossdeathでもlevel specialを許可,어느 레벨에서든 BOSSDEATH 이벤트 허용,Laat een eventuele bossdood voor een speciaal niveau toe....,Tillat enhver bossdeath for nivå spesiell,Każda śmierć bossa liczy się jako akcja specjalna,Permitir qualquer morte de chefão para ação especial,Permitir qualquer morte de chefe para ação especial,Orice utilizare de A_BossDeath activează evenimente speciale în nivel,Любой вызов A_BossDeath активирует special уровня,Било који случај A_BossDeath активира special на нивоу,Özel seviye için herhangi bir boss ölümüne izin ver -Disable BOOM door light effect,CMPTMNU_NODOORLIGHT,,,,Zakázat světelný efekt dveří z BOOMu,Deaktivere BOOM dør lys effekt,Boom-Türlichteffekt deaktiviert.,,Malvalidigi pordlumo-efekton de BOOM,Desactivar efecto de luz de puerta de BOOM,,BOOM-ovivalotehoste pois käytöstä,Pas d'effet de lumière BOOM sur portes,A BOOM ajtó fény effekt kikapcsolása ,Disabilitato l'effetto Boom della luce della porta,BOOMドアライト エフェクトを無効化,붐 문간 조명보정 효과 끄기,BOOM-deurlichteffect uitschakelen,Deaktiver BOOM dør lyseffekt,Wyłącz efekt oświetlenia drzwi BOOM,Desabilitar efeito de luz de porta do BOOM,,Dezactivează efectele de lumină BOOM pentru uși,Отключить световой эффект из BOOM на дверях,Онемогући светлосни ефекат из BOOM-а на вратима,BOOM kapı ışığı efektini devre dışı bırak -Find neighboring light like Doom,CMPTMNU_LIGHT,,,Find neighbouring light like Doom,Nacházet nejbližší světlo jako Doom,Find nabo lys som Doom,Finde benachbartes Licht wie in Doom,,Trovi najbaran lumon kiel Doom,Encontrar luces vecinas como en Doom,,Etsi vierustava valo niin kuin Doom,Trouver prochaine texture comme DOOM,Szomszédos fényforrás keresése mint Doom-ban,Trova le luci vicine come in DOOM,DOOM式の最寄りライト検知,고전적인 조명추적 사용,Vind naburig licht zoals Doom,Finn nærliggende lys som Doom,Znajdź sąsiadujące światło jak w Doomie,Encontrar luz vizinha como em Doom,,Caută o sursă de lumină apropriată ca în Doom,Искать соседний источник света как в Doom,Нађи суседно светло као у Doom-у,Doom gibi komşu ışık bulun -Find shortest textures like Doom,CMPTMNU_SHORTTEX,,,,Nacházet nejkratší textury jako Doom,Find korteste teksturer som Doom,Finde kurze Texturen wie in Doom,,Trovi la plej mallongajn tekstaĵojn kiel Doom,Encontrar texturas más cortas como en Doom,,Etsi lyhyimmät pintakuvioinnit niin kuin Doom,Trouver plus petite texture comme Doom,Legkisebb textúrák keresése mint Doom-ban,Trova le texture più piccole come in DOOM,DOOM式の最短テクスチャー検知,고전적인 텍스처분류 사용,Vind de kortste texturen zoals Doom,Finn korteste teksturer som Doom,Znajdź najkrótsze tekstury jak w Doomie,Encontrar menores texturas como em Doom,,Caută cele mai scurte texturi ca în Doom,Искать кратчайшие текстуры как в Doom,Нађи најкраће текстуре као у Doom-у,Doom gibi en kısa dokuları bulun -Use buggier stair building,CMPTMNU_STAIRS,,,,Použít méně stabilní stavění schodů,Brug buggier trappe bygning,Benutze fehlerhafte Treppenbaufunktion,,Uzi pli ciman ŝtupo-konstruadon,Usar construcción defectuosa de escaleras,,Käytä viallisempaa portaanrakennusfunktiota,Construction d'escalier plus buggée,Bugosabb lépcsőépítés használata,Usa la struttura a scalinate più buggata,バグった階段生成を使用,구형 계단상승 효과 사용,Gebruik buggier trapgebouw,Bruk buggier trappebygging,Użyj wadliwej funkcji budowania schodów,Usar construção defeituosa de escadas,,Utilizare mod de ridicare al scărilor incorect,Использовать неисправленное построение лестниц,Користи непоправљено грађење степеница,Daha az doğru merdiven binası kullanın -Use Doom's floor motion behavior,CMPTMNU_FLOORMOVE,,,Use Doom's floor motion behaviour,Použít původní chování Doomu pro pohyb podlah,Brug Dooms gulv bevægelsesadfærd,Benutze Dooms Verhalten für bewegende Böden,,Uzi konduton de Doom por plankmovo-konduto,Usar comportamiento de mov. del suelo de Doom,,Lattialiike käyttäytyy kuin Doomissa,Mouvement des sols à la DOOM,Doom jellegű padló mozgás,Adotta il comportamento di DOOM per il movimento sul pavimento,DOOMでの床の動作挙動を使用,표면이나 천장이 서로 통과가 가능함,Gebruik Doom's vloer beweging vloer,Bruk Dooms gulvbevegelsesatferd,Użyj zachowanie ruchu podłogi Dooma,Usar comportamento de mov. do chão de Doom,,Utilizare comportament de mișcare al podelelor din Doom,Поведение движения по полу из Doom,Користи Doom-ово подно моционо понашање,Doom'un zemin hareketi davranışını kullanın -Use Doom's point-on-line algorithm,CMPTMNU_POINTONLINE,,,,Použít původní algoritmus bod-na-čáře z Doomu,Brug Dooms point-on-line algoritme,Benutze Dooms Punkt-auf-Linie Algorithmus,,Uzi algoritmon de Doom por trovi punkton sur linio,Usar algoritmo de punto en línea de Doom,,Käytä Doomin piste viivalla -algoritmia,Algorithme point-sur-ligne de DOOM,Doom jellegű point-on-line algoritmus,Usa l'algoritmo del 'punto giacente sulla linea' di DOOM,DOOMでのポイントライン アルゴリズム を使用,구형 선상 지점 정의법 사용,Gebruik Doom's point-on-line-algoritme,Bruk Dooms punkt-på-nett-algoritme,Użyj algorytmu punktu na linii z Dooma,Usar algorítmo de ponto-em-linha de Doom,,Utilizare algoritm point-on-line din Doom,Использовать алгоритм «точка на линии» из Doom,Користи Doom-ов point-on-line алгоритам,Doom'un point-on-line algoritmasını kullanın -Level exit can be triggered more than once,CMPTMNU_MULTIEXIT,,,,Odchod z levelu může být spuštěn vícekrát,Level exit kan udløses mere end én gang,Ausgang kann mehr als einmal aktiviert werden,,Nivelelirejo povas esti ekagigita pli ol unufoje,La salida de nivel puede ser activada más de una vez,,Tasosta poistumisen voi laukaista useammin kuin kerran,Sortie niveau utilisable plusieures fois,Pálya kijárat többször is triggerelhető,L'uscita del livello può attivarsi più di una volta,Exitを複数回起動出来る,레벨 출구 트리거 한 번 이상 작동,Niveau-uitgang kan meer dan eens worden geactiveerd,Nivåutgang kan utløses mer enn én gang,Wyjście z poziomu może być uruchomione więcej niż raz,Saída de fase pode ser ativada mais de uma vez,Saída de nível pode ser ativada mais de uma vez,Ieșirea nivelului poate fi activată de mai multe ori,Выходы могут быть активированы более одного раза,Излаз нивоа може бити активиран више пута,Seviye çıkışı birden fazla kez tetiklenebilir -Physics Behavior,CMPTMNU_PHYSICSBEHAVIOR,,,Physics Behaviour,Fyzika,Fysik-adfærd,Physik-Verhalten,,Fizikokonduto,Comportamiento de la física,,Fysiikan käyttäytyminen,Comportement Physique,Fizika viselkedés,Comportamento della fisica,物理の挙動,물리 관련 설정,Fysica gedrag,Fysikkoppførsel,Zachowanie Fizyki,Comportamento de Física,Comportamento das Físicas,Comportament fizică,Поведение физики,Физичко понашање,Fiziksel Davranış -Actors are infinitely tall,CMPTMNU_NOPASSOVER,,,,Objekty jsou nekonečně vysoké,Aktører er uendeligt høje,Akteure sind unendlich hoch,,Aktoroj estas senfine altaj,Los actores son infinitamente altos,,Oliot ovat äärettömän korkeita,Hauteur des acteurs infinie,Személyek végtelen magasak,Gli attori sono infinitamente alti,アクターの上下には入れない,무한으로 키가 큰 개체,Acteurs zijn oneindig lang,Skuespillere er uendelig høye,Aktorzy są nieskończenie wysocy,Atores são infinitamente altos,,Actorii au înălțime infinită,Объекты бесконечно высокие,Глумци су бесконачно велики,Aktörler sonsuz uzunlukta -Boom scrollers are additive,CMPTMNU_BOOMSCROLL,,,,Boom posuvníky jsou aditivní,Boom scrollers er additive,Boom-Scroller sind additiv,,Skrolantaj Teksturaj de Boom estas adicia,Los scrollers de Boom son aditivos,,Boom-vierittimet ovat additiivisia,Glisseurs BOOM additifs,Boom scroller-ek összeadódnak,Le barre di scorrimento BOOM sono additivi,BOOM型 壁スクロールを適用,붐 스크롤러 누적법 사용,Boom scrollers zijn additief,Boom scrollere er additive,Przewijane tekstury Boom są addytywne,Scrollers de Boom são aditivos,,Elementele derulante BOOM sunt aditive,Конвейеры из BOOM складываются с собой,Boom скролери су додаци,Bom kaydırıcıları katkı maddelidir -Cannot travel straight NSEW,CMPTMNU_BADANGLES,,,,Nelze se pohybovat přímo na SJVZ,Kan ikke rejse lige NSØV,Bewegungsrichtungen direkt NSOW nicht möglich,,Ne eblas veturi rekte NSEW,Emular error de mal ángulo,,Liikkuminen puhtaasti pääilmansuuntiin mahdotonta,Direction pure NSEO impossible,Nem haladhat egyenes vonalban NSEW,Non si può viaggiare esattamente nelle direzioni cardinali,テレポート時は東西南北に直進出来ない,전방위 방향으로 이동 불가,Kan niet rechtdoor reizen NZOW,Kan ikke reise rett NSØV,Pozwól na błąd złego kąta,Impossível se deslocar reto em direções cardeais,Impossível se deslocar em frente em direções cardeais,Interzice deplasarea liniară NSEW,Запрещено двигаться прямо на С/Ю/З/В,Немогуће путовати право на NSEW,Düz seyahat edemez KGDB -Enable wall running,CMPTMNU_WALLRUN,,,,Povolit wall running (běhaní pomocí zdi),Aktiver vægløb,Ermögliche Wandrennen,,Ebligi kuradon sur muroj,Activar correr por muros,,Salli seinäjuoksu,Activer Wallrunning,Falon futás engedélyezése,Wall running abilitata,壁伝い走行を許可,벽면가속이동 허용,Wandloop mogelijk maken,Aktiver veggkjøring,Włącz szybkie bieganie wzdłuż ścian,Habilitar corrida por paredes,Permitir corrida pelas paredes,Permite fuga cu ajutorul pereților (Wallrun),Включить быстрый бег вдоль стен (wallrunning),Омогући пролажење кроз зида,Duvar çalışmasını etkinleştirin -Raven scrollers use original speed,CMPTMNU_RAVENSCROLL,,,,Raven posuvníky používají původní rychlost,Raven scrollers bruger original hastighed,Raven-Scroller benutzen originale Geschwindigkeit,,Skrolantaj teksturoj de Raven uzas originalan rapidecon,Los scrollers de Raven usan la velocidad original,,Ravenin vierittimet liikkuvat alkuperäisnopeudella,Glisseurs Raven à leur vitesse originale,Raven scroller-ek eredeti sebességűek,Le barre di scorrimento Raven usano la velocità originale,Raven型 壁スクロールは元の速度を使用,구형 헤러틱/헥센 스크롤러 사용,Raven scrollers gebruiken originele snelheid,Raven scrollers bruker original hastighet,Przwijane tekstury podłogi Raven używają oryginalną prędkość,Scrollers da Raven usam velocidade original,,Elementele derulante Raven folosesc viteza originală,Конвейеры из Raven используют неизменённую скорость,Raven скролери користе оригиналну брзину,Kuzgun kaydırıcılar orijinal hızı kullanır -Self ref. sectors don't block shots,CMPTMNU_TRACE,,,,Sebe-odkazující sektory neblokují střely,Selvreflekterende sektorer blokerer ikke for skud,Selbstreferenzierende Sektoren blockieren keine Schüsse,,Sinreferencantaj sektoroj ne baras pafojn,Sectores autoreferidos no bloquean los disparos,,Itseensä viittaavat sektorit eivät estä laukauksia,Secteur autoréférencé ne bloque pas les tirs,Saját ref.sektorok nem blokkkolják a lövéseket,Settori autoreferenziati non bloccano i colpi,Self ref.セクターは射撃を阻害しない,자기 참조 섹터가 총탄을 막지 않음,Zelfreferentie sectoren blokkeren geen schoten,Selvrefererende sektorer blokkerer ikke skudd.,Sektory odnoszoce się do siebie nie blokują strzałów,Setores autorreferidos não bloqueiam tiros,,Sectoarele cu referință proprie blochează focurile,Самоссылающиеся секторы не блокируют выстрелы,Самореф. сектори не блокирају пуцњеве,Kendi kendine hakemlik yapan sektörler atışları engellemez. -Use Doom code for hitscan checks,CMPTMNU_HITSCAN,,,,Použít původní Doom kód pro kontrolu hitscanů,Brug Doom-code til hitscan-kontrol,Benutze Original-Doom-Code für Hitscan-Checks,,Uzi kodon de Doom por batskanoj-kontrolado,Usar código de Doom para revisión de hitscan,,Käytä Doomin osumislaskentakoodia,Vérification Hitscan à la DOOM,Doom kód használata a hitscan ellenőrzéshez,Usa il codice DOOM per il controllo sugli hitscan,DOOM型ヒットスキャンチェックを使用,구형 총탄 판정법 사용,Gebruik Doom-code voor hitscancontroles,Bruk Doom-kode for treffkontroll,Użyj kod Dooma dla hitscanu,Usam código de Doom para verificação de hitscan,Usar código de Doom para verificação de hitscan,Utilizează cod din Doom pentru a verifica coliziunea focurilor,Использовать код из Doom для проверок зон мгновенного попадания (hitscan),Користи Doom код за хитскен проверу,Hitscan kontrolleri için Doom kodunu kullanın -Use Doom heights for missile clipping,CMPTMNU_MISSILECLIP,,,,Použít původní výšky z Doomu pro kolizi raket,Brug Doom-højder til missilklipper,Benutze Doom-Größen für Kollisionen mit Projektilen,,Uzi altojn de Doom por misilo-tonadoj,Usar altura de Doom para desplazamiento de misiles,,Käytä Doomin korkeuksia lentokappaleiden törmäyksissä,Clipping des missiles à la DOOM,Doom féle magasság használata a rakáta találathoz,Usa le altezze di DOOM per il clipping del razzo,DOOM型ミサイルクリッピングの高さを使用,구형 발사체 판정법 사용,Gebruik Doom hoogtes voor het knippen van raketten,Bruk Doom-høyder for missilklipping,Użyj wysokości Dooma dla przenikania pocisków,Usar alturas de Doom para colisão de projéteis,,Utilizează metoda de verificare a înălțimilor din Doom,Использовать высоту из Doom для столкновения ракет,Користи Doom висине за клиповање ракета,Füze kırpma için Doom yüksekliklerini kullanın -Rendering Behavior,CMPTMNU_RENDERINGBEHAVIOR,,,Rendering Behaviour,Vykreslování,Rendering Adfærd,Renderverhalten,,Bildigado-Konduto,Comportamiento de renderizado,,Hahmonnuksen käyttäytyminen,Comportement d'affichage,Renderelés viselkedése,Comportamento della grafica,レンダリングの挙動,렌더링 관련 설정,Rendering gedrag,Gjengivelse av oppførsel,Zachowanie Renderowania,Comportamento de Renderização,,Comportament Video,Поведение отрисовки,Понашање рендовања,Rendering Davranışı -Draw polyobjects like Hexen,CMPTMNU_POLYOBJ,,,,Vykreslovat polyobjekty jako Hexen,Tegn polyobjekter som Hexen,Zeichne Polyobjekte wie in Hexen,,Desegni plurangulo-objektojn kiel Hexen,Dibujar poliobjetos como en Hexen,,Piirrä polyobjektit niin kuin Hexen,Dessiner les Polyobjets comme Hexen,Hexen féle tárgy kirajzolás,Polioggetti disegnati come Hexen,Hexen式のポリオブジェクト描画,구형 폴리오브젝트 시스템 사용,Teken polyobjecten zoals Hexen,Tegn polyobjekter som Hexen,Rysuj poliobiekty jak w Hexenie,Desenhar poliobjetos como em Hexen,,Afișează poliobiectele precum în Hexen,Отрисовка полиобъектов как в Hexen,Цртај поли-објекте као Hexen,Hexen gibi çoklu nesneler çizin -Ignore Y offsets on masked midtextures,CMPTMNU_MASKEDMIDTEX,,,,Ignorovat Y posuny na průhledných mid-texturách,Ignorer Y offsets på maskerede midtextures,Ignoriere Y-Offsets bei transparenten Mitteltexturen,,Malatenti Y-deŝovaĵojn sur maskitaj midtekstaĵoj,Ignorar offsets de eje Y en texturas medias enmascaradas,,Älä huomioi Y-siirroksia peitetyissä keskipintakuvioinneissa,Offsets Y ignorés sur les textures centrales,Függőleges mozgatás ignorálása a maszkolt midtextúráknál,Ignora gli offset Y sulle midtexture mascherate,中間テクスチャーのマスクされたYオフセットを無効,이면선분의 중앙 텍스쳐의 Y축값 무시,Negeer Y compensaties op gemaskerde middentexturen,Ignorer Y-forskyvninger på maskerte mellomteksturer,Ignoruj przesunięcia osi Y na zamaskowanych teksturach po środku,Ignorar offsets de Y em texturas centrais,,Ignoră offsetul Y de pe texturile 3D mascate,Игнорировать смещение по вертикали на средних текстурах с маской,Игнориши Y нагиб на маскиране средње текстуре,Maskelenmiş orta dokularda Y ofsetlerini yoksay -Invert sprite sorting,CMPTMNU_SPRITESORT,,,,Obrátit řazení spritů,Inverter sprite-sortering,Umgekehrte Spritesortierung,,Inversigi ordigadon de spritoj,Invertir ordenado de sprites,,Käännä spritelajittelu,Ordres des sprites inversé,Sprite rendzés megfordítása,Ordinamento sprite invertito,反転スプライトの並び替え,구형 스프라이트 겹침 판정 사용,Sprite sorteren omkeren,Inverter sprite-sortering,Odwróć sortowanie sprite'ów,Inverter ordem de sprites,,Inversare sortare sprite-uri,Обратить порядок сортировки спрайтов,Обрнуто сортирање спрајтова,Sprite sıralamasını ters çevir -Sound Behavior,CMPTMNU_SOUNDBEHAVIOR,,,Sound Behaviour,Zvuk,Adfærd med lyd,Sound-Verhalten,,Sonkonduto,Comportamiento de sonido,,Äänen käyttäytyminen,Comportement Sonore,Hang viselkedés,Comportamento suono,音の挙動,효과음 관련 설정,Geluidsgedrag,Lydoppførsel,Zachowanie dźwięku,Comportamento de Áudio,,Comportament Sunet,Поведение звуков,Понашање звука,Ses Davranışı -Cripple sound for silent BFG trick,CMPTMNU_SOUNDSLOTS,,,,Zmrzačit zvukový systém pro trik tichého BFG,Lyd forkrøblet ved lydløst BFG-trick,Amputiere Soundsystem für geräuschloses BFG,,Kripligi sonon por lertaĵo de silenta BFG,Estropear sonido para truco de BFG silencioso,,Rampauta äänijärjestelmä hiljaista BFG-temppua varten,Massacrer le son pour BFG silencieux,Bénító hang a halk BFG trükknél,Blocca il suono per il trucco del BFG silenzioso,消音BFGトリックの為にサウンドを重複させない,소음 BFG 효과 허용,Kreupel geluid voor een stille BFG-truc,Krymp lyd for stille BFG-triks,Obetnij dźwięk dla triku cichego BFG,Bloquear som para o truque da BFG silenciosa,,Taie sunetul pentru trucul BFG silențios,Ограничить звуки ради трюка бесшумной BFG,Онемогући звук за тихи ВЈП трик,Sessiz BFG numarası için sesi kısın -Don't let others hear your pickups,CMPTMNU_SILENTPICKUP,,,,Ostatní tě neslyší sbírat předměty,Lad ikke andre høre dine pickupper,Andere können deine Gegenstandsaufnahmen nicht hören,,Ne lasi aliulojn aŭdas viajn prenadojn,No dejar a otros oír tus recogidas,,"Älä anna muiden kuulla, kun poimit esineitä",Autres joueurs n'entendent pas les ramassages,Mások ne hallhassák a tárgy felvételeidet,Non consentire agli altri giocatori di sentire le tue raccolte,他人にピックアップ音を聞かせない,상대방의 습득 효과음 청음 불가,Laat anderen uw pick-ups niet horen,Ikke la andre høre pickupene dine,"Nie pozwalaj by inni słyszeli, że podnosisz przedmioty",Não permitir que outros ouçam sua coleta de itens,Não permitir que outros ouçam sua aquisição de itens,Nu permite celorlalți să audă sunetul ridicării obiectelor,Запрещать другим слышать звук подбора предметов,Не допусти да други чују ваше скупљање,Başkalarının manyetiklerinizi duymasına izin vermeyin -Inst. moving floors are not silent,CMPTMNU_SILENTINSTANTFLOORS,,,,Okamžitě pohybující se podlahy nejsou tiché,Inst. bevægelige gulve er ikke lydløse,Böden mit sofortiger Bewegung machen Geräusche,,Tujaj movantaj plankoj ne estas silentaj,Suelos inst. movibles no son silenciosos,,Silmänräpäyksellisesti liikkuvat lattiat eivät ole hiljaisia,Sols à movement instanté font du bruit,Halk isntant mozgó padló,I pavimenti istantanei in movimento non sono silenziosi,即時稼働する床の音を鳴らさない,즉발식 이동표면 소음효과 제거,Direct bewegende vloeren zijn niet geruisloos,Øyeblikkelig bevegelige gulv er ikke stille,Nagle przesuwające się podłogi nie są ciche,Pisos que se deslocam instantâneamente emitem som,,Podelele care se mișcă instant nu sunt silențioase,Мгновенно двигающиеся полы не беззвучны,Инстантно покрећући нивои нису тихи,Inst. hareketli zeminler sessiz değildir -Sector sounds use center as source,CMPTMNU_SECTORSOUNDS,,,Sector sounds use centre as source,Sektorové zvuky používají jeho střed jako zdroj,Sektorlyde bruger centrum som kilde,Sektor-Sounds benutzen den Mittelpunkt des Sektors,,Sektorsonoj uzas centron kiel fonto,Sonidos de sector usan el centro como fuente,,Sektoriäänet käyttävät keskipistettä lähteenä,Sons secteur utilisent centre comme origine,Center forrás használata a szektor hangoknál,I suoni usano il centro dei settori come punto di sorgente,セクターサウンドをフロア中央で鳴らす,섹터 중심부를 효과음의 원천으로 판정,Sectorgeluiden gebruiken centrum als bron,Sektorlyder bruker senter som kilde,Dźwięki sektorów używają środka jako źródła,Sons de setor são emitidos a partir do centro,,Sunetele sectoarelor au ca sursă centrul,Звуки секторов используют центр как источник,Секторски звукови су центрисани,Sektör sesleri kaynak olarak merkezi kullanır -Sounds stop when actor vanishes,CMPTMNU_SOUNDCUTOFF,,,,"Utnout zvuky, když jejich objekt zmizí","Lydene stopper, når aktøren forsvinder","Sounds werden beendet, wenn der Akteur verschwindet",,"Sonoj ĉesas, kiam aktoro malaperas",El sonido se detiene cuando el actor desaparece,,"Äänet lakkaavat, kun olio katoaa",Sons s'arrêtent quand acteur disparait,Hangok megszűnnek az eltűnéskor,I suoni si fermano quando gli attori svaniscono,アクター消滅で音を止める,효과음 원천 소멸 시 효과음도 중단,Geluiden stoppen wanneer de acteur verdwijnt,Lyder stopper når skuespilleren forsvinner,Dźwięki zatrzymują się kiedy aktor znika,Som para quando o ator desaparece,,Sunetele se opresc când actorul sursă dispare,Останавливать звуки при исчезновении объекта,Звукови престају кад глумац нестане,Aktör ortadan kaybolduğunda sesler kesilir -Use original sound target handling,CMPTMNU_SOUNDTARGET,,,,Použít původní chování pro uchování zvukového cíle,Brug original lydmålhåndtering,Benutze originale Behandlung für das Sound-Ziel,,Uzi originalan manipuladon por soncelo,Usar manejo de destino de sonido original,,Käytä alkuperäistä äänen kohteen käsittelyä,Ciblage des sons selon algorithme original,Eredeti hang célpont kezelés,Targeting dei suoni in base all'algoritmo originale,元のサウンドターゲット処理を使用,구형 섹터 경고음 보존법 사용,Gebruik originele geluidsdoelwitverwerking,Bruk original lydmålhåndtering,Użyj oryginalną obsługę celu dźwięku,Usar método original de destino de som,,Procesare originală pentru sursele de sunet,Неизменённая обработка источников звука,Користи оригинални звук руковања метом,Orijinal ses hedefi kullanımını kullanın -Scripted teleports don't trigger sector actions,CMPTMNU_TELEPORT,,,,Skriptované teleportace neaktivují sektorové akce,Scriptede teleporteringer udløser ikke sektorhandlinger,Teleports in Skripten lösen keine Sektoraktionen aus,,Skriptitaj teleportoj ne ekagigas sektor-agojn,Telepuertos por script no activan acciones del sector,,Käsikirjoitetut kaukosiirtimet eivät laukaise sektoritoimintoja,Téléports par scripts n'activent pas le secteur,Szkriptelt teleportok nem triggerelnek szektor műveletet,I teletrasporti scriptati non attivano le azioni del settore,スクリプトテレポートではセクターアクションを起こさない,순간이동 스크립트는 섹터 이벤트 발동 불가능,De gescripte teleports leiden niet tot acties in de sector.,Skriptede teleporter utløser ikke sektorhandlinger,Oskryptowane teleporty nie włączają akcji sektora,Teletransportes scriptados não ativam ações de setor,,Teleportările scriptate nu declanșează acțiuni în sectoare,Скриптовые телепорты не запускают действия секторов,Скриптовани телепортери не активирају секторске радње,Komut dosyası ışınlanmaları sektör eylemlerini tetiklemiyor -Non-blocking lines can be pushed,CMPTMNU_PUSHWINDOW,,,,Neblokující čáry mohou být zmáčknuty,Ikke-blokerende linjer kan skubbes,Nicht-blockende Linien können angestoßen werden,,Nehaltantaj linioj povas esti premitaj,Líneas sin bloquear pueden ser presionadas,,Ei-tukkivia viivoja voi työntää,Lignes non-bloquantes sont non-poussables,Nem blokkoló vonalak megnyomhatóak,Le linee non bloccanti possono essere spinti,Non-bloking linesを押せる,비차단 선분 밀어내기 가능,Niet-blokkerende lijnen kunnen worden geduwd,Ikke-blokkerende linjer kan skyves,Nieblokujące ściany mogą być pchnięte,Linhas não-bloqueadoras podem ser pressionadas,,Liniile care nu blochează pot fi împinse înapoi,Неблокирующие линии можно задействовать перемещением сквозь,Неблокирабе линје могу бити гурнуте,Engelleyici olmayan hatlar itilebilir -Enable buggy CheckSwitchRange behavior,CMPTMNU_CHECKSWITCHRANGE,,,,Povolit nestabilní chování pro CheckSwitchRange,Aktiver den fejlbehæftede CheckSwitchRange-adfærd,Erlaube fehlerhaftes CheckSwitchRange Verhalten,,Ebligi cimajn kondutojn por CheckSwitchRange,Permitir comportamiento viejo de CheckSwitchRange,,Ota käyttöön viallinen CheckSwitchRange-käyttäytyminen,Fonction CheckSwitchRange buggée,Bugos CheckSwitchRange mechanika bekapcsolás,Abilita il comportamento buggato del CheckSwitchRange,バグのあるCheckSwitchRangeを許可,구형 CheckSwitchRange 판정법 사용,Buggy CheckSwitchSwitchRange gedrag inschakelen,Aktiver fejlbehæftet CheckSwitchRange-adfærd,Zezwól na zepsute zachowanie CheckSwitchRange,Permitir comportamento CheckSwitchRange defeituoso,,Comportament incorect pentru CheckSwitchRange,Включить ошибочное поведение CheckSwitchRange,Омогући баговано CheckSwitchRange понашање,Hatalı CheckSwitchRange davranışını etkinleştirin -Enable buggy Strife railing,CMPTMNU_RAILINGHACK,,,,Povolit nestabilní zábradlí ze Strifu,Aktiver buggy Strife railing,Fehlerhafte Strife-Geländer,Ενεργοποιηση σπασμένης συμπεριφοράς καγκέλον για το Strife,Ebligi ciman reladon de Strife,Activar barandillas bugueadas de Strife,,Ota käyttöön Strifen vialliset kaiteet,Barrières buggées pour Strife,Bugos Strife korlát bekapcsolása,Abilita il railing buggato di Strife,バグのあるStrife railingを許可,고전 스트라이프 철책 적용,Buggy mogelijk maken Strijk-reling,Aktiver fejlbehæftet Strife rekkverk,Włącz wadliwe bariery Strife'a,Permitir railing defeituoso do Strife,Permitir railing defeituoso do Strife,Utilizare comportament grilaj Strife incorect,Вернуть ошибочные перила в Strife,Омогући непоправљену ограду у Strife-у,Yanlış Strife korkuluğunu etkinleştirin -No vertical thrust from explosions,CMPTMNU_EXPLODE1,,,,Exploze neodhazují do výšky,Ingen vertikal fremdrift fra eksplosioner,Keine vertikale Bewegung durch Explosionen,Καθόλου κατακόρυφη ώθηση απο εκρήξεις,Neniuj vertikalaj puŝoj de eksplodoj,No causar empuje vertical en explosiones,,Ei pystysuuntaista työntövoimaa räjähdyksistä,Explosions sans propulsion verticale,A robbanásnak nincs függőleges lökése,Nessuna spinta verticale dalle esplosioni,爆風は垂直方向全域に影響しない,폭발시 수직방향 반동 억제,Geen verticale stuwkracht van explosies,Ingen vertikal skyvekraft fra eksplosjoner,Brak pionowego nacisku od eksplozji,Desativar propulsão vertical das explosões,,Fără împingere verticală de la explozii,Взрывы не отбрасывают вверх/вниз,Нема вертикалног гурања од експлозија,Patlamalardan kaynaklanan dikey itme yok -Use original Doom explosion behavior,CMPTMNU_EXPLODE2,,,Use original Doom explosion behaviour,Používat původní chování explozí Doomu,Brug original Doom eksplosionsadfærd,Benutze Original Doom Explosionsverhalten,Συμπεριφορά εκρήξεων απο το πρωτότυπο Doom,Uzi originalan konduton de Doom por eksplodoj ,Usar comportamiento de explosiones del DOOM original,,Käytä Doomin alkuperäisiä räjähdysten käyttäytymissääntöjä,Utiliser comportement Doom original,Eredeti Doom robbanás mechanika használata,Usa l'originale comportamento dell'esplosione di DOOM,Doom本来の爆発動作を使用する,고전 둠의 폭발 반발력 적용,Gebruik het originele Doom explosiegedrag,Bruk original Doom-eksplosjonsatferd,Użyj oryginalnego zachowania eksplozji z Dooma,Usar comportamento original de explosões do Doom,,Utilizare comportament original pentru explozii,Использовать модель взрывов из Doom,Користи оригнално Doom понашање за експлозије,Orijinal Doom patlama davranışını kullanın -,,player,,,,,,,,,,,,,,,,,,,,,,,, -Red,PLYRMNU_RED,,,,Červená,Rød,Rot,,Ruĝo,Rojo,,Punainen,Rouge,Piros,Rosso,赤の量,빨강,Rood,Rød,Czerwony,Vermelho,,Roșu,Красный,Црвева,Kırmızı -Green,PLYRMNU_GREEN,,,,Zelená,Grøn,Grün,,Verdo,Verde,,Vihreä,Vert,Zöld,Verde,緑の量,초록,Groen,Grønn,Zielony,Verde,,Verde,Зелёный,Зелена,Yeşil -Blue,PLYRMNU_BLUE,,,,Modrá,Blå,Blau,,Bluo,Azul,,Sininen,Bleu,Kék,Blu,青の量,파랑,Blauw,Blå,Niebieski,Azul,,Albastru,Синий,Плава,Mavi -Class,PLYRMNU_PLAYERCLASS,,,,Třída,Klasse,Klasse,,Klaso,Clase,,Luokka,Classe,Kaszt,Classe,役職,클래스,Klasse,Klasse,Klasa,Classe,,Clasă,Класс,Класа,Sınıf -Skin,PLYRMNU_PLAYERSKIN,,,,Skin,Skin,Skin,,Haŭto,Piel,,Ulkoasu,,Kinézet,Skin,外装,스킨,Uiterlijk,Hud,Wygląd,Skin,,Textură,Облик,Скин,Cilt -Switch on pickup,PLYRMNU_SWITCHONPICKUP,,,,Přepnout zbraň při sebrání,Tænd for pickup,Waffenwechsel bei Aufnahme,,Ŝanĝi armon ĉe preno,Cambiar arma al recoger,,Vaihda uuteen aseeseen,Dernière arme,Felvételkor váltás,Cambio d'arma quando si riceve,武器取得時に持ち替え,무기 획득 시 바꿈,Gebruik wapen meteen na oppakken,Slå på pickup,Przełącz po podniesieniu,Mudar de arma ao pegar,,Schimbare armă la ridicare,Смена оружия при подборе,Пребаци на покупљено оружје,Elinize aldığınızda silahı değiştirin -Press \cjSPACE,PLYRMNU_PRESSSPACE,,,,Zmáčkni \cjMEZERNÍK,Tryk på \cjSPACE,\cjLeertaste,,Premu \cjSPACON,Presiona \cjEspacio,,Paina \cjVÄLI \cfnähdäk-,\cjEspace,Nyomj \cjSPACE -t,Premi \cjSPAZIO,\cjスペースキー,회전: \cjSPACE바,Druk op \cjSPACE,Trykk \cjSPACE,\cjSPACJA,Aperte \cjESPAÇO,,Apasă \cjSPACE,Нажмите \cjПРОБЕЛ,Притисните \cjSPACE,\cjSPACE tuşuna basın -to see front,PLYRMNU_SEEFRONT,,,,pro pohled zepředu,for at se forsiden,für Frontansicht,,por vidi antaŭon,Para ver de Frente,,sesi etupuolen,Pour L'Avant,Előre nézni,per vedere avanti,で前面を表示,캐릭터 앞모습,om de voorkant te zien,for å se forsiden,by widzieć przód,para ver a frente,,pentru a vedea fața,для просмотра спереди,да видите спреда,ön tarafı görmek için -to see back,PLYRMNU_SEEBACK,,,,pro pohled zezadu,for at se bagsiden,für Rückansicht,,por vidi malantaŭon,Para ver por Detrás,,sesi takapuolen,Pour l'Arrière,Hátra Nézni,per vedere dietro,で背面を表示,캐릭터 뒷모습,om terug te kijken,for å se baksiden,by widzieć tył,para ver atrás,,pentru a vedea spatele,для просмотра сзади,да видите позади,geri görmek için -Vertical Bullet Spread,PLYRMNU_VERTSPREAD,,,,Svislý rozptyl střelby,Lodret kuglespredning,Vertikale Streuung,,Vertikala Kugla Disvastiĝo,Dispersión vertical de la bala,,Pystysuora luodin leviäminen,Écartement vertical des balles,Vertikális fegyver szórás,Diffusione dei proiettili in verticale,垂直方向の散弾,,Verticale kogelspreiding,Vertikal kulespredning,Pionowy rozrzut pocisków,Espalhamento Vertical das Balas,,Recul Vertical Gloanțe,Вертикальный разброс пуль,,Dikey Mermi Yayılımı -,,controls,,,,,,,,,,,,,,,,,,,,,,,, -Weapon Zoom,CNTRLMNU_ZOOM,,,,Přiblížení zbraně,Våbenzoom,Waffenzoom,Ζοομ,Armilzumo,Zoom del arma,,Aseen kiikaritähtäys,Zoom avec Arme,Ráközelítés fegyverrel,Zoom dell'arma,ズーム,무기 조준,Wapen Zoom,Våpen Zoom,Przybliżenie Broni,Zoom da Arma,,Zoom Armă,Приближение,Зум,Silah Yakınlaştırma -Weapon State 1,CNTRLMNU_USER1,,,,Akce zbraně 1,Våbenstatus 1,Waffen-Aktion 1,Κατάσταση Όπλου 1,Armilstato 1,Estado del arma 1,,Aseen tila 1,Etat d'Arme 1,Fegyver 1. állapot,Stato dell'arma 1,武器特殊動作 1,무기 상태 1,Wapenstaat 1,Våpenstat 1,Stan Broni 1,Estado da Arma 1,,Poziție Armă 1,Функция первого оружия,Стање оружја (1),Silah Durumu 1 -Weapon State 2,CNTRLMNU_USER2,,,,Akce zbraně 2,Våbenstatus 2,Waffen-Aktion 2,Κατάσταση Όπλου 2,Armilstato 2,Estado del arma 2,,Aseen tila 2,Etat d'Arme 2,Fegyver 2. állapot,Stato dell'arma 2,武器特殊動作 2,무기 상태 2,Wapenstaat 2,Våpenstat 2,Stan Broni 2,Estado da Arma 2,,Poziție Armă 2,Функция второго оружия,Стање оружја (2),Silah Durumu 2 -Weapon State 3,CNTRLMNU_USER3,,,,Akce zbraně 3,Våbenstatus 3,Waffen-Aktion 3,Κατάσταση Όπλου 3,Armilstato 3,Estado del arma 3,,Aseen tila 3,Etat d'Arme 3,Fegyver 3. állapot,Stato dell'arma 3,武器特殊動作 3,무기 상태 3,Wapenstaat 3,Våpenstat 3,Stan Broni 3,Estado da Arma 3,,Poziție Armă 3,Функция третьего оружия,Стање оружја (3),Silah Durumu 3 -Weapon State 4,CNTRLMNU_USER4,,,,Akce zbraně 4,Våbenstatus 4,Waffen-Aktion 4,Κατάσταση Όπλου 4,Armilstato 4,Estado del arma 4,,Aseen tila 4,Etat d'Arme 4,Fegyver 4. állapot,Stato dell'arma 4,武器特殊動作 4,무기 상태 4,Wapenstaat 4,Våpentilstand 4,Stan Broni 4,Estado da Arma 4,,Poziție Armă 4,Функция четвёртого оружия,Стање оружја (4),Silah Durumu 4 -Fly / Swim up,CNTRLMNU_MOVEUP,,,,Letět / plavat vzhůru,Flyv / svøm op,Fliegen / Hochschwimmen,Πέτα/Κολύμπα πάνω,Flugi / Naĝi supren,Volar / Nadar arriba,,Lennä / Ui ylös,Voler/Nager en haut,Repülés / Felfele úszás,Vola / Nuota in alto,飛行/水泳時 上昇,위로 날기 / 해엄치기,Omhoog vliegen/zwemmen omhoog,Fly / Svøm opp,Lot / Pływanie w górę,Voar / Nadar para cima,,Zbor / Înot în Sus,Лететь/плыть вверх,Лети/пливај нагоре,Uç / Yüz yukarı -Fly / Swim down,CNTRLMNU_MOVEDOWN,,,,Letět / plavat dolů,Flyv / svøm ned,Fliegen / Runterschwimmen,Πέτα/Κολύμπα κάτω,Flugi / Naĝi malsupren,Volar / Nadar abajo,,Lennä / Ui alas,Voler/Nager en bas,Repülés / Lefele úszás,Vola / Nuota in basso,飛行/水泳時 下降,아래로 날기 / 해엄치기,Naar beneden vliegen/zwemmen,Fly / Svøm ned,Lot / Pływanie w dół,Voar / Nadar para baixo,,Zbor / Înot în Jos,Лететь/плыть вниз,Лети/пливај надоле,Uç / Yüz aşağı -Stop flying,CNTRLMNU_LAND,,,,Přestat létat,Stop flyvning,Landen,Σταμάτα πέταμα,Ĉesi flugadon,Dejar de volar,,Lopeta lentäminen,Arrêter de voler,Repülés abbahagyása,Stop al volo,飛行停止,비행 정지,Stoppen met vliegen,Slutt å fly,Przestań latać,Parar de voar,,Încetare Zbor,Приземлиться,Престани летети,Uçmayı bırak -Keyboard look,CNTRLMNU_KEYBOARDLOOK,,,,Pohled klávesnicí,Tastatur-look,Tastatur-Blick,Κατακόρυφο κοίταχμα (Πλητρoλόγιο),Klavaroregardo,Vista con teclado,,Näppäinkatselu,Vue au clavier,Billentyűzettel való nézelődés,Modalità vista con la tastiera,キー視点上下化,키보드 룩,Toetsenbordaanzicht,Tastatur utseende,Rozglądanie się klawiaturą,Vista com o teclado,,Utilizare Tastatură pentru a Privi în Jur,Обзор клавиатурой,Гледај тастатуром,Klavye görünümü -Strife Popup Screens Controls,CNTRLMNU_POPUPS_TITLE,,,,Ovládání vyskakovacích oken ve Strife,Strife Popup-skærme Kontrolelementer,Strife Popup Steuerung einstellen,,Ŝprucfenestraj Regiloj de Strife,Popups de Strife,,Strifen ponnahdusruutujen ohjausasetukset,Contrôles Popups Strife,Strife Felugró Ablak Irányítás,Controlli Schermate popup di Strife,Strifeポップアップ表示設定,스트라이프 팝업 화면 조작,Strife Popup Schermen Bediening,Strife Popup-skjermer Kontroller,Ustaw Klawisze Okienek Strife'a,Comandos de Popups do Strife,Controlos de Popups do Strife,Control pentru Mesaje Strife,Управление всплывающими окнами Strife,Искакајући прикази контроле у Strife-у,Strife Açılır Ekran Kontrolleri -Team say,CNTRLMNU_TEAMSAY,,,,Říct týmu,Team sige,Teamkommunikation,Πές στην ομάδα,Teama diro,Hablar al equipo,,Sano omille,Parler (équipe),Üzenet csapattársaknak,Parla nella squadra,チーム内発言,팀 채팅하기,Zeggen in team,Lag si,Powiedz do Drużyny,Fala (equipe),Falar à equipa,Vorbește cu Echipa Proprie,Сообщение команде,Пиши тиму,Ekip diyor ki +",いずれのBossdeathでもlevel specialを許可,어느 레벨에서든 BOSSDEATH 이벤트 허용,Laat een eventuele bossdood voor een speciaal niveau toe....,Tillat enhver bossdeath for nivå spesiell,Każda śmierć bossa liczy się jako akcja specjalna,Permitir qualquer morte de chefão para ação especial,Permitir qualquer morte de chefe para ação especial,Orice utilizare de A_BossDeath activează evenimente speciale în nivel,Любой вызов A_BossDeath активирует special уровня,Било који случај A_BossDeath активира special на нивоу,Tillåt alla bossdödsfall för specialnivå,Özel seviye için herhangi bir boss ölümüne izin ver +Disable BOOM door light effect,CMPTMNU_NODOORLIGHT,,,,Zakázat světelný efekt dveří z BOOMu,Deaktivere BOOM dør lys effekt,Boom-Türlichteffekt deaktiviert.,,Malvalidigi pordlumo-efekton de BOOM,Desactivar efecto de luz de puerta de BOOM,,BOOM-ovivalotehoste pois käytöstä,Pas d'effet de lumière BOOM sur portes,A BOOM ajtó fény effekt kikapcsolása ,Disabilitato l'effetto Boom della luce della porta,BOOMドアライト エフェクトを無効化,붐 문간 조명보정 효과 끄기,BOOM-deurlichteffect uitschakelen,Deaktiver BOOM dør lyseffekt,Wyłącz efekt oświetlenia drzwi BOOM,Desabilitar efeito de luz de porta do BOOM,,Dezactivează efectele de lumină BOOM pentru uși,Отключить световой эффект из BOOM на дверях,Онемогући светлосни ефекат из BOOM-а на вратима,Inaktivera BOOM-dörrljuseffekten,BOOM kapı ışığı efektini devre dışı bırak +Find neighboring light like Doom,CMPTMNU_LIGHT,,,Find neighbouring light like Doom,Nacházet nejbližší světlo jako Doom,Find nabo lys som Doom,Finde benachbartes Licht wie in Doom,,Trovi najbaran lumon kiel Doom,Encontrar luces vecinas como en Doom,,Etsi vierustava valo niin kuin Doom,Trouver prochaine texture comme DOOM,Szomszédos fényforrás keresése mint Doom-ban,Trova le luci vicine come in DOOM,DOOM式の最寄りライト検知,고전적인 조명추적 사용,Vind naburig licht zoals Doom,Finn nærliggende lys som Doom,Znajdź sąsiadujące światło jak w Doomie,Encontrar luz vizinha como em Doom,,Caută o sursă de lumină apropriată ca în Doom,Искать соседний источник света как в Doom,Нађи суседно светло као у Doom-у,Hitta närliggande ljus som Doom,Doom gibi komşu ışık bulun +Find shortest textures like Doom,CMPTMNU_SHORTTEX,,,,Nacházet nejkratší textury jako Doom,Find korteste teksturer som Doom,Finde kurze Texturen wie in Doom,,Trovi la plej mallongajn tekstaĵojn kiel Doom,Encontrar texturas más cortas como en Doom,,Etsi lyhyimmät pintakuvioinnit niin kuin Doom,Trouver plus petite texture comme Doom,Legkisebb textúrák keresése mint Doom-ban,Trova le texture più piccole come in DOOM,DOOM式の最短テクスチャー検知,고전적인 텍스처분류 사용,Vind de kortste texturen zoals Doom,Finn korteste teksturer som Doom,Znajdź najkrótsze tekstury jak w Doomie,Encontrar menores texturas como em Doom,,Caută cele mai scurte texturi ca în Doom,Искать кратчайшие текстуры как в Doom,Нађи најкраће текстуре као у Doom-у,Hitta kortaste texturer som Doom,Doom gibi en kısa dokuları bulun +Use buggier stair building,CMPTMNU_STAIRS,,,,Použít méně stabilní stavění schodů,Brug buggier trappe bygning,Benutze fehlerhafte Treppenbaufunktion,,Uzi pli ciman ŝtupo-konstruadon,Usar construcción defectuosa de escaleras,,Käytä viallisempaa portaanrakennusfunktiota,Construction d'escalier plus buggée,Bugosabb lépcsőépítés használata,Usa la struttura a scalinate più buggata,バグだらけの階段生成を使用,구형 계단상승 효과 사용,Gebruik buggier trapgebouw,Bruk buggier trappebygging,Użyj wadliwej funkcji budowania schodów,Usar construção defeituosa de escadas,,Utilizare mod de ridicare al scărilor incorect,Использовать неисправленное построение лестниц,Користи непоправљено грађење степеница,Använda en mer buggig trappbyggnad,Daha az doğru merdiven binası kullanın +Use Doom's floor motion behavior,CMPTMNU_FLOORMOVE,,,Use Doom's floor motion behaviour,Použít původní chování Doomu pro pohyb podlah,Brug Dooms gulv bevægelsesadfærd,Benutze Dooms Verhalten für bewegende Böden,,Uzi konduton de Doom por plankmovo-konduto,Usar comportamiento de mov. del suelo de Doom,,Lattialiike käyttäytyy kuin Doomissa,Mouvement des sols à la DOOM,Doom jellegű padló mozgás,Adotta il comportamento di DOOM per il movimento sul pavimento,DOOMでの床の動作挙動を使用,표면이나 천장이 서로 통과가 가능함,Gebruik Doom's vloer beweging vloer,Bruk Dooms gulvbevegelsesatferd,Użyj zachowanie ruchu podłogi Dooma,Usar comportamento de mov. do chão de Doom,,Utilizare comportament de mișcare al podelelor din Doom,Поведение движения по полу из Doom,Користи Doom-ово подно моционо понашање,Använd Dooms golvrörelsebeteende,Doom'un zemin hareketi davranışını kullanın +Use Doom's point-on-line algorithm,CMPTMNU_POINTONLINE,,,,Použít původní algoritmus bod-na-čáře z Doomu,Brug Dooms point-on-line algoritme,Benutze Dooms Punkt-auf-Linie Algorithmus,,Uzi algoritmon de Doom por trovi punkton sur linio,Usar algoritmo de punto en línea de Doom,,Käytä Doomin piste viivalla -algoritmia,Algorithme point-sur-ligne de DOOM,Doom jellegű point-on-line algoritmus,Usa l'algoritmo del 'punto giacente sulla linea' di DOOM,DOOMでのポイントライン アルゴリズム を使用,구형 선상 지점 정의법 사용,Gebruik Doom's point-on-line-algoritme,Bruk Dooms punkt-på-nett-algoritme,Użyj algorytmu punktu na linii z Dooma,Usar algorítmo de ponto-em-linha de Doom,,Utilizare algoritm point-on-line din Doom,Использовать алгоритм «точка на линии» из Doom,Користи Doom-ов point-on-line алгоритам,Använda Dooms algoritm för punkt-till-linje-arbete,Doom'un point-on-line algoritmasını kullanın +Level exit can be triggered more than once,CMPTMNU_MULTIEXIT,,,,Odchod z levelu může být spuštěn vícekrát,Level exit kan udløses mere end én gang,Ausgang kann mehr als einmal aktiviert werden,,Nivelelirejo povas esti ekagigita pli ol unufoje,La salida de nivel puede ser activada más de una vez,,Tasosta poistumisen voi laukaista useammin kuin kerran,Sortie niveau utilisable plusieures fois,Pálya kijárat többször is triggerelhető,L'uscita del livello può attivarsi più di una volta,Exitを複数回起動出来る,레벨 출구 트리거 한 번 이상 작동,Niveau-uitgang kan meer dan eens worden geactiveerd,Nivåutgang kan utløses mer enn én gang,Wyjście z poziomu może być uruchomione więcej niż raz,Saída de fase pode ser ativada mais de uma vez,Saída de nível pode ser ativada mais de uma vez,Ieșirea nivelului poate fi activată de mai multe ori,Выходы могут быть активированы более одного раза,Излаз нивоа може бити активиран више пута,Nivåutgång kan utlösas mer än en gång,Seviye çıkışı birden fazla kez tetiklenebilir +Physics Behavior,CMPTMNU_PHYSICSBEHAVIOR,,,Physics Behaviour,Fyzika,Fysik-adfærd,Physik-Verhalten,,Fizikokonduto,Comportamiento de la física,,Fysiikan käyttäytyminen,Comportement Physique,Fizika viselkedés,Comportamento della fisica,物理の挙動,물리 관련 설정,Fysica gedrag,Fysikkoppførsel,Zachowanie Fizyki,Comportamento de Física,Comportamento das Físicas,Comportament fizică,Поведение физики,Физичко понашање,Fysikbeteende,Fiziksel Davranış +Actors are infinitely tall,CMPTMNU_NOPASSOVER,,,,Objekty jsou nekonečně vysoké,Aktører er uendeligt høje,Akteure sind unendlich hoch,,Aktoroj estas senfine altaj,Los actores son infinitamente altos,,Oliot ovat äärettömän korkeita,Hauteur des acteurs infinie,Személyek végtelen magasak,Gli attori sono infinitamente alti,アクターの上下には入れない,무한으로 키가 큰 개체,Acteurs zijn oneindig lang,Skuespillere er uendelig høye,Aktorzy są nieskończenie wysocy,Atores são infinitamente altos,,Actorii au înălțime infinită,Объекты бесконечно высокие,Глумци су бесконачно велики,Aktörerna är oändligt höga.,Aktörler sonsuz uzunlukta +Boom scrollers are additive,CMPTMNU_BOOMSCROLL,,,,Boom posuvníky jsou aditivní,Boom scrollers er additive,Boom-Scroller sind additiv,,Skrolantaj Teksturaj de Boom estas adicia,Los scrollers de Boom son aditivos,,Boom-vierittimet ovat additiivisia,Glisseurs BOOM additifs,Boom scroller-ek összeadódnak,Le barre di scorrimento BOOM sono additivi,BOOM型スクロール床を適用,붐 스크롤러 누적법 사용,Boom scrollers zijn additief,Boom scrollere er additive,Przewijane tekstury Boom są addytywne,Scrollers de Boom são aditivos,,Elementele derulante BOOM sunt aditive,Конвейеры из BOOM складываются с собой,Boom скролери су додаци,Boom scrollers är additiva,Bom kaydırıcıları katkı maddelidir +Cannot travel straight NSEW,CMPTMNU_BADANGLES,,,,Nelze se pohybovat přímo na SJVZ,Kan ikke rejse lige NSØV,Bewegungsrichtungen direkt NSOW nicht möglich,,Ne eblas veturi rekte NSEW,Emular error de mal ángulo,,Liikkuminen puhtaasti pääilmansuuntiin mahdotonta,Direction pure NSEO impossible,Nem haladhat egyenes vonalban NSEW,Non si può viaggiare esattamente nelle direzioni cardinali,NSEW直進走法の不許可,전방위 방향으로 이동 불가,Kan niet rechtdoor reizen NZOW,Kan ikke reise rett NSØV,Pozwól na błąd złego kąta,Impossível se deslocar reto em direções cardeais,Impossível se deslocar em frente em direções cardeais,Interzice deplasarea liniară NSEW,Запрещено двигаться прямо на С/Ю/З/В,Немогуће путовати право на NSEW,Kan inte resa rakt NSÖV,Düz seyahat edemez KGDB +Enable wall running,CMPTMNU_WALLRUN,,,,Povolit wall running (běhaní pomocí zdi),Aktiver vægløb,Ermögliche Wandrennen,,Ebligi kuradon sur muroj,Activar correr por muros,,Salli seinäjuoksu,Activer Wallrunning,Falon futás engedélyezése,Wall running abilitata,壁伝い走行を許可,벽면가속이동 허용,Wandloop mogelijk maken,Aktiver veggkjøring,Włącz szybkie bieganie wzdłuż ścian,Habilitar corrida por paredes,Permitir corrida pelas paredes,Permite fuga cu ajutorul pereților (Wallrun),Включить быстрый бег вдоль стен (wallrunning),Омогући пролажење кроз зида,Aktiverar väggkörning,Duvar çalışmasını etkinleştirin +Raven scrollers use original speed,CMPTMNU_RAVENSCROLL,,,,Raven posuvníky používají původní rychlost,Raven scrollers bruger original hastighed,Raven-Scroller benutzen originale Geschwindigkeit,,Skrolantaj teksturoj de Raven uzas originalan rapidecon,Los scrollers de Raven usan la velocidad original,,Ravenin vierittimet liikkuvat alkuperäisnopeudella,Glisseurs Raven à leur vitesse originale,Raven scroller-ek eredeti sebességűek,Le barre di scorrimento Raven usano la velocità originale,Raven式スクロール床を原作準拠にする,구형 헤러틱/헥센 스크롤러 사용,Raven scrollers gebruiken originele snelheid,Raven scrollers bruker original hastighet,Przwijane tekstury podłogi Raven używają oryginalną prędkość,Scrollers da Raven usam velocidade original,,Elementele derulante Raven folosesc viteza originală,Конвейеры из Raven используют неизменённую скорость,Raven скролери користе оригиналну брзину,Raven-skrollers använder ursprunglig hastighet,Kuzgun kaydırıcılar orijinal hızı kullanır +Self ref. sectors don't block shots,CMPTMNU_TRACE,,,,Sebe-odkazující sektory neblokují střely,Selvreflekterende sektorer blokerer ikke for skud,Selbstreferenzierende Sektoren blockieren keine Schüsse,,Sinreferencantaj sektoroj ne baras pafojn,Sectores autoreferidos no bloquean los disparos,,Itseensä viittaavat sektorit eivät estä laukauksia,Secteur autoréférencé ne bloque pas les tirs,Saját ref.sektorok nem blokkkolják a lövéseket,Settori autoreferenziati non bloccano i colpi,Self ref.Sectorsは射撃を阻害しない,자기 참조 섹터가 총탄을 막지 않음,Zelfreferentie sectoren blokkeren geen schoten,Selvrefererende sektorer blokkerer ikke skudd.,Sektory odnoszoce się do siebie nie blokują strzałów,Setores autorreferidos não bloqueiam tiros,,Sectoarele cu referință proprie blochează focurile,Самоссылающиеся секторы не блокируют выстрелы,Самореф. сектори не блокирају пуцњеве,Självbetjäningssektorer blockerar inte skott.,Kendi kendine hakemlik yapan sektörler atışları engellemez. +Use Doom code for hitscan checks,CMPTMNU_HITSCAN,,,,Použít původní Doom kód pro kontrolu hitscanů,Brug Doom-code til hitscan-kontrol,Benutze Original-Doom-Code für Hitscan-Checks,,Uzi kodon de Doom por batskanoj-kontrolado,Usar código de Doom para revisión de hitscan,,Käytä Doomin osumislaskentakoodia,Vérification Hitscan à la DOOM,Doom kód használata a hitscan ellenőrzéshez,Usa il codice DOOM per il controllo sugli hitscan,DOOM式の即着弾判定を使用,구형 총탄 판정법 사용,Gebruik Doom-code voor hitscancontroles,Bruk Doom-kode for treffkontroll,Użyj kod Dooma dla hitscanu,Usam código de Doom para verificação de hitscan,Usar código de Doom para verificação de hitscan,Utilizează cod din Doom pentru a verifica coliziunea focurilor,Использовать код из Doom для проверок зон мгновенного попадания (hitscan),Користи Doom код за хитскен проверу,Använd Doom-kod för hitscan-kontroller,Hitscan kontrolleri için Doom kodunu kullanın +Use Doom heights for missile clipping,CMPTMNU_MISSILECLIP,,,,Použít původní výšky z Doomu pro kolizi raket,Brug Doom-højder til missilklipper,Benutze Doom-Größen für Kollisionen mit Projektilen,,Uzi altojn de Doom por misilo-tonadoj,Usar altura de Doom para desplazamiento de misiles,,Käytä Doomin korkeuksia lentokappaleiden törmäyksissä,Clipping des missiles à la DOOM,Doom féle magasság használata a rakáta találathoz,Usa le altezze di DOOM per il clipping del razzo,ミサイル通過にDOOM heightsを使用,구형 발사체 판정법 사용,Gebruik Doom hoogtes voor het knippen van raketten,Bruk Doom-høyder for missilklipping,Użyj wysokości Dooma dla przenikania pocisków,Usar alturas de Doom para colisão de projéteis,,Utilizează metoda de verificare a înălțimilor din Doom,Использовать высоту из Doom для столкновения ракет,Користи Doom висине за клиповање ракета,Använd Doom-höjder för missilklippning.,Füze kırpma için Doom yüksekliklerini kullanın +Rendering Behavior,CMPTMNU_RENDERINGBEHAVIOR,,,Rendering Behaviour,Vykreslování,Rendering Adfærd,Renderverhalten,,Bildigado-Konduto,Comportamiento de renderizado,,Hahmonnuksen käyttäytyminen,Comportement d'affichage,Renderelés viselkedése,Comportamento della grafica,レンダリングの挙動,렌더링 관련 설정,Rendering gedrag,Gjengivelse av oppførsel,Zachowanie Renderowania,Comportamento de Renderização,,Comportament Video,Поведение обработки,Понашање рендовања,Beteende vid rendering,Rendering Davranışı +Draw polyobjects like Hexen,CMPTMNU_POLYOBJ,,,,Vykreslovat polyobjekty jako Hexen,Tegn polyobjekter som Hexen,Zeichne Polyobjekte wie in Hexen,,Desegni plurangulo-objektojn kiel Hexen,Dibujar poliobjetos como en Hexen,,Piirrä polyobjektit niin kuin Hexen,Dessiner les Polyobjets comme Hexen,Hexen féle tárgy kirajzolás,Polioggetti disegnati come Hexen,Hexen式のPolyObjects描画,구형 폴리오브젝트 시스템 사용,Teken polyobjecten zoals Hexen,Tegn polyobjekter som Hexen,Rysuj poliobiekty jak w Hexenie,Desenhar poliobjetos como em Hexen,,Afișează poliobiectele precum în Hexen,Отрисовка полиобъектов как в Hexen,Цртај поли-објекте као Hexen,Rita polyobjekt som Hexen,Hexen gibi çoklu nesneler çizin +Ignore Y offsets on masked midtextures,CMPTMNU_MASKEDMIDTEX,,,,Ignorovat Y posuny na průhledných mid-texturách,Ignorer Y offsets på maskerede midtextures,Ignoriere Y-Offsets bei transparenten Mitteltexturen,,Malatenti Y-deŝovaĵojn sur maskitaj midtekstaĵoj,Ignorar offsets de eje Y en texturas medias enmascaradas,,Älä huomioi Y-siirroksia peitetyissä keskipintakuvioinneissa,Offsets Y ignorés sur les textures centrales,Függőleges mozgatás ignorálása a maszkolt midtextúráknál,Ignora gli offset Y sulle midtexture mascherate,マスクされた中間テクスチャーのY軸ずれを無効,이면선분의 중앙 텍스쳐의 Y축값 무시,Negeer Y compensaties op gemaskerde middentexturen,Ignorer Y-forskyvninger på maskerte mellomteksturer,Ignoruj przesunięcia osi Y na zamaskowanych teksturach po środku,Ignorar offsets de Y em texturas centrais,,Ignoră offsetul Y de pe texturile 3D mascate,Игнорировать смещение по вертикали на средних текстурах с маской,Игнориши Y нагиб на маскиране средње текстуре,Ignorera Y-förskjutningar på maskerade midtexturer.,Maskelenmiş orta dokularda Y ofsetlerini yoksay +Invert sprite sorting,CMPTMNU_SPRITESORT,,,,Obrátit řazení spritů,Inverter sprite-sortering,Umgekehrte Spritesortierung,,Inversigi ordigadon de mov-rastrumoj,Invertir ordenado de sprites,,Käännä spritelajittelu,Ordres des sprites inversé,Sprite rendzés megfordítása,Ordinamento sprite invertito,反転スプライトの並び替え,구형 스프라이트 겹침 판정 사용,Sprite sorteren omkeren,Inverter sprite-sortering,Odwróć sortowanie sprite'ów,Inverter ordem de sprites,,Inversare sortare sprite-uri,Обратить порядок сортировки спрайтов,Обрнуто сортирање спрајтова,Invertera sprite-sortering,Sprite sıralamasını ters çevir +Sound Behavior,CMPTMNU_SOUNDBEHAVIOR,,,Sound Behaviour,Zvuk,Adfærd med lyd,Sound-Verhalten,,Sonkonduto,Comportamiento de sonido,,Äänen käyttäytyminen,Comportement Sonore,Hang viselkedés,Comportamento suono,音の挙動,효과음 관련 설정,Geluidsgedrag,Lydoppførsel,Zachowanie dźwięku,Comportamento de Áudio,,Comportament Sunet,Поведение звуков,Понашање звука,Ljudbeteende,Ses Davranışı +Cripple sound for silent BFG trick,CMPTMNU_SOUNDSLOTS,,,,Zmrzačit zvukový systém pro trik tichého BFG,Lyd forkrøblet ved lydløst BFG-trick,Amputiere Soundsystem für geräuschloses BFG,,Kripligi sonon por lertaĵo de silenta BFG,Estropear sonido para truco de BFG silencioso,,Rampauta äänijärjestelmä hiljaista BFG-temppua varten,Massacrer le son pour BFG silencieux,Bénító hang a halk BFG trükknél,Blocca il suono per il trucco del BFG silenzioso,消音BFG技の為にサウンドを重複させない,소음 BFG 효과 허용,Kreupel geluid voor een stille BFG-truc,Krymp lyd for stille BFG-triks,Obetnij dźwięk dla triku cichego BFG,Bloquear som para o truque da BFG silenciosa,,Taie sunetul pentru trucul BFG silențios,Ограничить звуки ради трюка бесшумной BFG,Онемогући звук за тихи ВЈП трик,Förlamning av ljudet vid tyst BFG-trick,Sessiz BFG numarası için sesi kısın +Don't let others hear your pickups,CMPTMNU_SILENTPICKUP,,,,Ostatní tě neslyší sbírat předměty,Lad ikke andre høre dine pickupper,Andere können deine Gegenstandsaufnahmen nicht hören,,Ne lasi aliulojn aŭdas viajn prenadojn,No dejar a otros oír tus recogidas,,"Älä anna muiden kuulla, kun poimit esineitä",Autres joueurs n'entendent pas les ramassages,Mások ne hallhassák a tárgy felvételeidet,Non consentire agli altri giocatori di sentire le tue raccolte,他人にピックアップ音を聞かせない,상대방의 습득 효과음 청음 불가,Laat anderen uw pick-ups niet horen,Ikke la andre høre pickupene dine,"Nie pozwalaj by inni słyszeli, że podnosisz przedmioty",Não permitir que outros ouçam sua coleta de itens,Não permitir que outros ouçam sua aquisição de itens,Nu permite celorlalți să audă sunetul ridicării obiectelor,Запрещать другим слышать звук подбора предметов,Не допусти да други чују ваше скупљање,Låt inte andra höra dina pickuper,Başkalarının manyetiklerinizi duymasına izin vermeyin +Inst. moving floors are not silent,CMPTMNU_SILENTINSTANTFLOORS,,,,Okamžitě pohybující se podlahy nejsou tiché,Inst. bevægelige gulve er ikke lydløse,Böden mit sofortiger Bewegung machen Geräusche,,Tujaj movantaj plankoj ne estas silentaj,Suelos inst. movibles no son silenciosos,,Silmänräpäyksellisesti liikkuvat lattiat eivät ole hiljaisia,Sols à movement instanté font du bruit,Halk isntant mozgó padló,I pavimenti istantanei in movimento non sono silenziosi,即時稼働するFloorsの音を鳴らさない,즉발식 이동표면 소음효과 제거,Direct bewegende vloeren zijn niet geruisloos,Øyeblikkelig bevegelige gulv er ikke stille,Nagle przesuwające się podłogi nie są ciche,Pisos que se deslocam instantâneamente emitem som,,Podelele care se mișcă instant nu sunt silențioase,Мгновенно двигающиеся полы не беззвучны,Инстантно покрећући нивои нису тихи,Inst. rörliga golv är inte tysta,Inst. hareketli zeminler sessiz değildir +Sector sounds use center as source,CMPTMNU_SECTORSOUNDS,,,Sector sounds use centre as source,Sektorové zvuky používají jeho střed jako zdroj,Sektorlyde bruger centrum som kilde,Sektor-Sounds benutzen den Mittelpunkt des Sektors,,Sektorsonoj uzas centron kiel fonto,Sonidos de sector usan el centro como fuente,,Sektoriäänet käyttävät keskipistettä lähteenä,Sons secteur utilisent centre comme origine,Center forrás használata a szektor hangoknál,I suoni usano il centro dei settori come punto di sorgente,Sectorサウンドをフロア中央で鳴らす,섹터 중심부를 효과음의 원천으로 판정,Sectorgeluiden gebruiken centrum als bron,Sektorlyder bruker senter som kilde,Dźwięki sektorów używają środka jako źródła,Sons de setor são emitidos a partir do centro,,Sunetele sectoarelor au ca sursă centrul,Звуки секторов используют центр как источник,Секторски звукови су центрисани,Sektorljud använder centrum som källa,Sektör sesleri kaynak olarak merkezi kullanır +Sounds stop when actor vanishes,CMPTMNU_SOUNDCUTOFF,,,,"Utnout zvuky, když jejich objekt zmizí","Lydene stopper, når aktøren forsvinder","Sounds werden beendet, wenn der Akteur verschwindet",,"Sonoj ĉesas, kiam aktoro malaperas",El sonido se detiene cuando el actor desaparece,,"Äänet lakkaavat, kun olio katoaa",Sons s'arrêtent quand acteur disparait,Hangok megszűnnek az eltűnéskor,I suoni si fermano quando gli attori svaniscono,アクター消滅で音を止める,효과음 원천 소멸 시 효과음도 중단,Geluiden stoppen wanneer de acteur verdwijnt,Lyder stopper når skuespilleren forsvinner,Dźwięki zatrzymują się kiedy aktor znika,Som para quando o ator desaparece,,Sunetele se opresc când actorul sursă dispare,Останавливать звуки при исчезновении объекта,Звукови престају кад глумац нестане,Ljudet upphör när aktören försvinner,Aktör ortadan kaybolduğunda sesler kesilir +Use original sound target handling,CMPTMNU_SOUNDTARGET,,,,Použít původní chování pro uchování zvukového cíle,Brug original lydmålhåndtering,Benutze originale Behandlung für das Sound-Ziel,,Uzi originalan manipuladon por soncelo,Usar manejo de destino de sonido original,,Käytä alkuperäistä äänen kohteen käsittelyä,Ciblage des sons selon algorithme original,Eredeti hang célpont kezelés,Targeting dei suoni in base all'algoritmo originale,元のサウンドターゲット処理を使用,구형 섹터 경고음 보존법 사용,Gebruik originele geluidsdoelwitverwerking,Bruk original lydmålhåndtering,Użyj oryginalną obsługę celu dźwięku,Usar método original de destino de som,,Procesare originală pentru sursele de sunet,Неизменённая обработка источников звука,Користи оригинални звук руковања метом,Använd original ljudmålshantering,Orijinal ses hedefi kullanımını kullanın +Scripted teleports don't trigger sector actions,CMPTMNU_TELEPORT,,,,Skriptované teleportace neaktivují sektorové akce,Scriptede teleporteringer udløser ikke sektorhandlinger,Teleports in Skripten lösen keine Sektoraktionen aus,,Skriptitaj teleportoj ne ekagigas sektor-agojn,Telepuertos por script no activan acciones del sector,,Käsikirjoitetut kaukosiirtimet eivät laukaise sektoritoimintoja,Téléports par scripts n'activent pas le secteur,Szkriptelt teleportok nem triggerelnek szektor műveletet,I teletrasporti scriptati non attivano le azioni del settore,スクリプトテレポートではSector actionsを起こさない,순간이동 스크립트는 섹터 이벤트 발동 불가능,De gescripte teleports leiden niet tot acties in de sector.,Skriptede teleporter utløser ikke sektorhandlinger,Oskryptowane teleporty nie włączają akcji sektora,Teletransportes scriptados não ativam ações de setor,,Teleportările scriptate nu declanșează acțiuni în sectoare,Скриптовые телепорты не запускают действия секторов,Скриптовани телепортери не активирају секторске радње,Skriptbaserade teleporter utlöser inte sektoråtgärder.,Komut dosyası ışınlanmaları sektör eylemlerini tetiklemiyor +Non-blocking lines can be pushed,CMPTMNU_PUSHWINDOW,,,,Neblokující čáry mohou být zmáčknuty,Ikke-blokerende linjer kan skubbes,Nicht-blockende Linien können angestoßen werden,,Nehaltantaj linioj povas esti premitaj,Líneas sin bloquear pueden ser presionadas,,Ei-tukkivia viivoja voi työntää,Lignes non-bloquantes sont non-poussables,Nem blokkoló vonalak megnyomhatóak,Le linee non bloccanti possono essere spinti,Non-bloking linesを押せる,비차단 선분 밀어내기 가능,Niet-blokkerende lijnen kunnen worden geduwd,Ikke-blokkerende linjer kan skyves,Nieblokujące ściany mogą być pchnięte,Linhas não-bloqueadoras podem ser pressionadas,,Liniile care nu blochează pot fi împinse înapoi,Неблокирующие линии можно задействовать перемещением сквозь,Неблокирабе линје могу бити гурнуте,Linjer som inte blockerar kan skjutas,Engelleyici olmayan hatlar itilebilir +Enable buggy CheckSwitchRange behavior,CMPTMNU_CHECKSWITCHRANGE,,,,Povolit nestabilní chování pro CheckSwitchRange,Aktiver den fejlbehæftede CheckSwitchRange-adfærd,Erlaube fehlerhaftes CheckSwitchRange Verhalten,,Ebligi cimajn kondutojn por CheckSwitchRange,Permitir comportamiento viejo de CheckSwitchRange,,Ota käyttöön viallinen CheckSwitchRange-käyttäytyminen,Fonction CheckSwitchRange buggée,Bugos CheckSwitchRange mechanika bekapcsolás,Abilita il comportamento buggato del CheckSwitchRange,バグのあるCheckSwitchRangeを許可,구형 CheckSwitchRange 판정법 사용,Buggy CheckSwitchSwitchRange gedrag inschakelen,Aktiver fejlbehæftet CheckSwitchRange-adfærd,Zezwól na zepsute zachowanie CheckSwitchRange,Permitir comportamento CheckSwitchRange defeituoso,,Comportament incorect pentru CheckSwitchRange,Включить ошибочное поведение CheckSwitchRange,Омогући баговано CheckSwitchRange понашање,Aktivera det felsägande CheckSwitchRange-beteendet,Hatalı CheckSwitchRange davranışını etkinleştirin +Enable buggy Strife railing,CMPTMNU_RAILINGHACK,,,,Povolit nestabilní zábradlí ze Strifu,Aktiver buggy Strife railing,Fehlerhafte Strife-Geländer,Ενεργοποιηση σπασμένης συμπεριφοράς καγκέλον για το Strife,Ebligi ciman reladon de Strife,Activar barandillas bugueadas de Strife,,Ota käyttöön Strifen vialliset kaiteet,Barrières buggées pour Strife,Bugos Strife korlát bekapcsolása,Abilita il railing buggato di Strife,バグのあるStrife railingを許可,고전 스트라이프 철책 적용,Buggy mogelijk maken Strijk-reling,Aktiver fejlbehæftet Strife rekkverk,Włącz wadliwe bariery Strife'a,Permitir railing defeituoso do Strife,Permitir railing defeituoso do Strife,Utilizare comportament grilaj Strife incorect,Вернуть ошибочные перила в Strife,Омогући непоправљену ограду у Strife-у,Aktivera felande Strife-Räcken,Yanlış Strife korkuluğunu etkinleştirin +No vertical thrust from explosions,CMPTMNU_EXPLODE1,,,,Exploze neodhazují do výšky,Ingen vertikal fremdrift fra eksplosioner,Keine vertikale Bewegung durch Explosionen,Καθόλου κατακόρυφη ώθηση απο εκρήξεις,Neniuj vertikalaj puŝoj de eksplodoj,No causar empuje vertical en explosiones,,Ei pystysuuntaista työntövoimaa räjähdyksistä,Explosions sans propulsion verticale,A robbanásnak nincs függőleges lökése,Nessuna spinta verticale dalle esplosioni,爆風は垂直方向全域に影響しない,폭발시 수직방향 반동 억제,Geen verticale stuwkracht van explosies,Ingen vertikal skyvekraft fra eksplosjoner,Brak pionowego nacisku od eksplozji,Desativar propulsão vertical das explosões,,Fără împingere verticală de la explozii,Взрывы не отбрасывают вверх/вниз,Нема вертикалног гурања од експлозија,Ingen vertikal dragkraft från explosioner,Patlamalardan kaynaklanan dikey itme yok +Use original Doom explosion behavior,CMPTMNU_EXPLODE2,,,Use original Doom explosion behaviour,Používat původní chování explozí Doomu,Brug original Doom eksplosionsadfærd,Benutze Original Doom Explosionsverhalten,Συμπεριφορά εκρήξεων απο το πρωτότυπο Doom,Uzi originalan konduton de Doom por eksplodoj ,Usar comportamiento de explosiones del DOOM original,,Käytä Doomin alkuperäisiä räjähdysten käyttäytymissääntöjä,Utiliser comportement Doom original,Eredeti Doom robbanás mechanika használata,Usa l'originale comportamento dell'esplosione di DOOM,Doom本来の爆発動作を使用する,고전 둠의 폭발 반발력 적용,Gebruik het originele Doom explosiegedrag,Bruk original Doom-eksplosjonsatferd,Użyj oryginalnego zachowania eksplozji z Dooma,Usar comportamento original de explosões do Doom,,Utilizare comportament original pentru explozii,Использовать модель взрывов из Doom,Користи оригнално Doom понашање за експлозије,Använd det ursprungliga Doom-explosionsbeteendet,Orijinal Doom patlama davranışını kullanın +,,player,,,,,,,,,,,,,,,,,,,,,,,,, +Red,PLYRMNU_RED,,,,Červená,Rød,Rot,,Ruĝo,Rojo,,Punainen,Rouge,Piros,Rosso,赤の量,빨강,Rood,Rød,Czerwony,Vermelho,,Roșu,Красный,Црвева,Röd,Kırmızı +Green,PLYRMNU_GREEN,,,,Zelená,Grøn,Grün,,Verdo,Verde,,Vihreä,Vert,Zöld,Verde,緑の量,초록,Groen,Grønn,Zielony,Verde,,Verde,Зелёный,Зелена,Grön,Yeşil +Blue,PLYRMNU_BLUE,,,,Modrá,Blå,Blau,,Bluo,Azul,,Sininen,Bleu,Kék,Blu,青の量,파랑,Blauw,Blå,Niebieski,Azul,,Albastru,Синий,Плава,Blå,Mavi +Class,PLYRMNU_PLAYERCLASS,,,,Třída,Klasse,Klasse,,Klaso,Clase,,Luokka,Classe,Kaszt,Classe,役職,클래스,Klasse,Klasse,Klasa,Classe,,Clasă,Класс,Класа,Klass,Sınıf +Skin,PLYRMNU_PLAYERSKIN,,,,,,,,Haŭto,Piel,,Ulkoasu,,Kinézet,,外装,스킨,Uiterlijk,Hud,Wygląd,,,Textură,Облик,Скин,Hud,Cilt +Switch on pickup,PLYRMNU_SWITCHONPICKUP,,,,Přepnout zbraň při sebrání,Tænd for pickup,Waffenwechsel bei Aufnahme,,Ŝanĝi armon ĉe preno,Cambiar arma al recoger,,Vaihda uuteen aseeseen,Dernière arme,Felvételkor váltás,Cambio d'arma quando si riceve,武器取得時に持ち替え,무기 획득 시 바꿈,Gebruik wapen meteen na oppakken,Slå på pickup,Przełącz po podniesieniu,Mudar de arma ao pegar,,Schimbare armă la ridicare,Смена оружия при подборе,Пребаци на покупљено оружје,Slå på pickupen,Elinize aldığınızda silahı değiştirin +Press \cjSPACE,PLYRMNU_PRESSSPACE,,,,Zmáčkni \cjMEZERNÍK,Tryk på \cjSPACE,\cjLeertaste,,Premu \cjSPACON,Presiona \cjEspacio,,Paina \cjVÄLI \cfnähdäk-,\cjEspace,Nyomj \cjSPACE -t,Premi \cjSPAZIO,\cjスペースキー,회전: \cjSPACE바,Druk op \cjSPACE,Trykk \cjSPACE,\cjSPACJA,Aperte \cjESPAÇO,,Apasă \cjSPACE,Нажмите \cjПРОБЕЛ,Притисните \cjSPACE,Tryck på \cjSPACE,\cjSPACE tuşuna basın +to see front,PLYRMNU_SEEFRONT,,,,pro pohled zepředu,for at se forsiden,für Frontansicht,,por vidi antaŭon,Para ver de Frente,,sesi etupuolen,Pour L'Avant,Előre nézni,per vedere avanti,で前面を表示,캐릭터 앞모습,om de voorkant te zien,for å se forsiden,by widzieć przód,para ver a frente,,pentru a vedea fața,для просмотра спереди,да видите спреда,för att se framsidan,ön tarafı görmek için +to see back,PLYRMNU_SEEBACK,,,,pro pohled zezadu,for at se bagsiden,für Rückansicht,,por vidi malantaŭon,Para ver por Detrás,,sesi takapuolen,Pour l'Arrière,Hátra Nézni,per vedere dietro,で背面を表示,캐릭터 뒷모습,om terug te kijken,for å se baksiden,by widzieć tył,para ver atrás,,pentru a vedea spatele,для просмотра сзади,да видите позади,för att se baksidan,geri görmek için +Vertical Bullet Spread,PLYRMNU_VERTSPREAD,,,,Svislý rozptyl střelby,Lodret kuglespredning,Vertikale Streuung,,Vertikala Kugla Disvastiĝo,Dispersión vertical de la bala,,Pystysuora luodin leviäminen,Écartement vertical des balles,Vertikális fegyver szórás,Diffusione dei proiettili in verticale,垂直方向の散弾,,Verticale kogelspreiding,Vertikal kulespredning,Pionowy rozrzut pocisków,Espalhamento Vertical das Balas,,Recul Vertical Gloanțe,Вертикальный разброс пуль,,Vertikal kulspridning,Dikey Mermi Yayılımı +,,controls,,,,,,,,,,,,,,,,,,,,,,,,, +Weapon Zoom,CNTRLMNU_ZOOM,,,,Přiblížení zbraně,Våbenzoom,Waffenzoom,Ζοομ,Armilzumo,Zoom del arma,,Aseen kiikaritähtäys,Zoom avec Arme,Ráközelítés fegyverrel,Zoom dell'arma,ズーム,무기 조준,Wapen Zoom,Våpen Zoom,Przybliżenie Broni,Zoom da Arma,,Zoom Armă,Приближение,Зум,Vapenzoom,Silah Yakınlaştırma +Weapon State 1,CNTRLMNU_USER1,,,,Akce zbraně 1,Våbenstatus 1,Waffen-Aktion 1,Κατάσταση Όπλου 1,Armilstato 1,Estado del arma 1,,Aseen tila 1,Etat d'Arme 1,Fegyver 1. állapot,Stato dell'arma 1,武器特殊動作 1,무기 상태 1,Wapenstaat 1,Våpenstat 1,Stan Broni 1,Estado da Arma 1,,Poziție Armă 1,Функция первого оружия,Стање оружја (1),Vapen Åtgärd 1,Silah Durumu 1 +Weapon State 2,CNTRLMNU_USER2,,,,Akce zbraně 2,Våbenstatus 2,Waffen-Aktion 2,Κατάσταση Όπλου 2,Armilstato 2,Estado del arma 2,,Aseen tila 2,Etat d'Arme 2,Fegyver 2. állapot,Stato dell'arma 2,武器特殊動作 2,무기 상태 2,Wapenstaat 2,Våpenstat 2,Stan Broni 2,Estado da Arma 2,,Poziție Armă 2,Функция второго оружия,Стање оружја (2),Vapen Åtgärd 2,Silah Durumu 2 +Weapon State 3,CNTRLMNU_USER3,,,,Akce zbraně 3,Våbenstatus 3,Waffen-Aktion 3,Κατάσταση Όπλου 3,Armilstato 3,Estado del arma 3,,Aseen tila 3,Etat d'Arme 3,Fegyver 3. állapot,Stato dell'arma 3,武器特殊動作 3,무기 상태 3,Wapenstaat 3,Våpenstat 3,Stan Broni 3,Estado da Arma 3,,Poziție Armă 3,Функция третьего оружия,Стање оружја (3),Vapen Åtgärd 3,Silah Durumu 3 +Weapon State 4,CNTRLMNU_USER4,,,,Akce zbraně 4,Våbenstatus 4,Waffen-Aktion 4,Κατάσταση Όπλου 4,Armilstato 4,Estado del arma 4,,Aseen tila 4,Etat d'Arme 4,Fegyver 4. állapot,Stato dell'arma 4,武器特殊動作 4,무기 상태 4,Wapenstaat 4,Våpentilstand 4,Stan Broni 4,Estado da Arma 4,,Poziție Armă 4,Функция четвёртого оружия,Стање оружја (4),Vapen Åtgärd 4,Silah Durumu 4 +Fly / Swim up,CNTRLMNU_MOVEUP,,,,Letět / plavat vzhůru,Flyv / svøm op,Fliegen / Hochschwimmen,Πέτα/Κολύμπα πάνω,Flugi / Naĝi supren,Volar / Nadar arriba,,Lennä / Ui ylös,Voler/Nager en haut,Repülés / Felfele úszás,Vola / Nuota in alto,飛行/水泳時 上昇,위로 날기 / 해엄치기,Omhoog vliegen/zwemmen omhoog,Fly / Svøm opp,Lot / Pływanie w górę,Voar / Nadar para cima,,Zbor / Înot în Sus,Лететь/плыть вверх,Лети/пливај нагоре,Flyga/simma upp,Uç / Yüz yukarı +Fly / Swim down,CNTRLMNU_MOVEDOWN,,,,Letět / plavat dolů,Flyv / svøm ned,Fliegen / Runterschwimmen,Πέτα/Κολύμπα κάτω,Flugi / Naĝi malsupren,Volar / Nadar abajo,,Lennä / Ui alas,Voler/Nager en bas,Repülés / Lefele úszás,Vola / Nuota in basso,飛行/水泳時 下降,아래로 날기 / 해엄치기,Naar beneden vliegen/zwemmen,Fly / Svøm ned,Lot / Pływanie w dół,Voar / Nadar para baixo,,Zbor / Înot în Jos,Лететь/плыть вниз,Лети/пливај надоле,Flyga/simma ner,Uç / Yüz aşağı +Stop flying,CNTRLMNU_LAND,,,,Přestat létat,Stop flyvning,Landen,Σταμάτα πέταμα,Ĉesi flugadon,Dejar de volar,,Lopeta lentäminen,Arrêter de voler,Repülés abbahagyása,Stop al volo,飛行停止,비행 정지,Stoppen met vliegen,Slutt å fly,Przestań latać,Parar de voar,,Încetare Zbor,Приземлиться,Престани летети,Sluta flyga,Uçmayı bırak +Keyboard look,CNTRLMNU_KEYBOARDLOOK,,,,Pohled klávesnicí,Tastatur-look,Tastatur-Blick,Κατακόρυφο κοίταχμα (Πλητρoλόγιο),Klavaroregardo,Vista con teclado,,Näppäinkatselu,Vue au clavier,Billentyűzettel való nézelődés,Modalità vista con la tastiera,キー視点上下化,키보드 룩,Toetsenbordaanzicht,Tastatur utseende,Rozglądanie się klawiaturą,Vista com o teclado,,Utilizare Tastatură pentru a Privi în Jur,Обзор клавиатурой,Гледај тастатуром,Tangentbordsutseende,Klavye görünümü +Strife Popup Screens Controls,CNTRLMNU_POPUPS_TITLE,,,,Ovládání vyskakovacích oken ve Strife,Strife Popup-skærme Kontrolelementer,Strife Popup Steuerung einstellen,,Ŝprucfenestraj Regiloj de Strife,Popups de Strife,,Strifen ponnahdusruutujen ohjausasetukset,Contrôles Popups Strife,Strife Felugró Ablak Irányítás,Controlli Schermate popup di Strife,Strifeポップアップ表示設定,스트라이프 팝업 화면 조작,Strife Popup Schermen Bediening,Strife Popup-skjermer Kontroller,Ustaw Klawisze Okienek Strife'a,Comandos de Popups do Strife,Controlos de Popups do Strife,Control pentru Mesaje Strife,Управление всплывающими окнами Strife,Искакајући прикази контроле у Strife-у,Strife Popup-skärmar Kontroller,Strife Açılır Ekran Kontrolleri +Team say,CNTRLMNU_TEAMSAY,,,,Říct týmu,Team sige,Teamkommunikation,Πές στην ομάδα,Teama diro,Hablar al equipo,,Sano omille,Parler (équipe),Üzenet csapattársaknak,Parla nella squadra,チーム内発言,팀 채팅하기,Zeggen in team,Lag si,Powiedz do Drużyny,Fala (equipe),Falar à equipa,Vorbește cu Echipa Proprie,Сообщение команде,Пиши тиму,Laget säger,Ekip diyor ki Drop item,CNTRLMNU_DROPITEM,,,,Odhodit předmět,Smid genstand,Gegenstand fallen lassen,Πέτα Aντικείμενο,Faligi objekton,Arrojar objeto,,Pudota varuste,Lâcher objet,Tárgy eldobása,Fai cadere l'oggetto,"アイテムを捨てる -",아이템 버리기,Item laten vallen,Slipp element,Upuść przedmiot,Largar item,,Aruncare Obiect,Бросить предмет,Баци предмет,Eşyayı bırak -Query item,CNTRLMNU_QUERYITEM,,,,Informace o předmětu,Forespørgsel element,Informationen über Gegenstand,,Informpeti objekton,Consultar objeto,,Hae varustetta,Vérifier objet,Rákérdez a tárgy eldobásnál,Indaga sull'oggetto,アイテム名を表示,아이템 정보 표시,Vraag item op,Spør om element,Zapytaj o przedmiot,Consultar item,,Cercetare Obiect,Проверить предмет,Прикажи предмет,Sorgu öğesi -Drop weapon,CNTRLMNU_DROPWEAPON,,,,Odhodit zbraň,Smid våben,Waffe fallen lassen,Πέτα Όπλο,Faligi armilon,Arrojar arma,,Pudota ase,Lâcher arme,Fegyver eldobása,Butta l'arma,武器を捨てる,무기 버리기,Wapen laten vallen,Slipp våpen,Upuść broń,Largar arma,,Aruncare Armă,Выбросить оружие,Баци оружје,Silahı bırak -Other,CNTRLMNU_OTHER,,,,Ostatní,Andre,Andere,Άλλα,Alia,Otros,,Muu,Autres,Más,Altro,その他,그 외 조작,Andere,Annet,Inne,Outro,,Altele,Прочее,Остало,Diğer -Coop spy,CNTRLMNU_COOPSPY,,,,Co-op špehování,Coop-spion,Coop Spion,,Kunlabora spiono,Espía cooperativo,,Vakoile joukkuetovereita,Espionner Coéquiper,Coop leskelődés,Spia cooperativa,他者視点,멀티플레이 카메라,Coöpspion,Coop-spion,Śledź (kooperacja),Visualização coop,,Vedere prin Ochii Altui Jucător,Вид от другого игрока,Поглед од другог играча,Coop casusu -Strife Popup Screens,CNTRLMNU_POPUPS,,,,Vyskakovací okna Strife,Strife popup-skærme,Strife Popups,,Ekmontraĵaj Ekranoj de Strife,Pop-ups de Strife,,Strifen ponnahdusruudut,Popups de Strife,Strife Felugró Ablakok,Schermate popup di Strife,Strife ポップアップ画面,스트라이프 팝업 화면,Strife Popup Schermen,Strife Popup-skjermer,Okienka Strife'a,Popup do Strife,,Mesaje Strife,Всплывающие окна Strife,Информација у Strife-у,Strife Açılır Ekranları -Mission objectives,CNTRLMNU_MISSION,,,,Úkoly mise,Mål for en mission,Missionsziele,Στόχοι Αποστολής,Misiobjektivoj,Objetivos de misión,,Tehtävätavoitteet,Objectifs de Mission,Küldetési célok,Obiettivi della missione,ミッションオブジェクト,임무 목록,Missiedoelen,Oppdragets mål,Cele misji,Objetivos da missão,,Obiectivele Misiunii,Текущее задание,Циљ мисије,Görev hedefleri -Keys list,CNTRLMNU_KEYS,,,,Seznam klíčů,Liste over nøgler,Schlüsselliste,Λίστα Κλειδιών,Ŝlosilolisto,Lista de llaves,,Avainlista,Liste des Clés,Kulcslista,Lista delle chiavi,キー類リスト,열쇠 목록,Lijst van toetsen,Liste over nøkler,Lista kluczy,Lista de teclas,,Listă Chei,Список ключей,Списка кључева,Anahtar listesi -Weapons/ammo/stats,CNTRLMNU_STATS,,,,Zbraně/munice/staty,Våben/ammo/stats,Waffen/Munition/Statistik,Οπλα/Πυρομαχικά/Στατιστικές,Armiloj/municio/stataĵoj,Armas/Munición/Estadísticas,,Aseet/ammukset/tila,"Statistiques, armes et munitions",Fegyver/lőszer/statisztika,Armi/ammunizioni/statistiche,武器 / 弾薬 / 状態,무기/탄약/통계 목록,Wapens/ammo/statistieken,Våpen/ammunisjon/statistikk,Bronie/amunicja/statystyki,Armas/munição/estatísticas,,Arme/muniție/statistici,"Оружие, патроны и показатели",Оружје/муниција/статистика,Silahlar/mühimmat/istatistikler -Toggle Scoreboard,CNTRLMNU_TOGGLESCOREBOARD,,,,Přepnout tabulku skóre,Skift Scoreboard,Punktetafel an/aus,Ενεργοποίηση Πίνακα Σκόρ,Baskuligi poentotabulon,Alternar Marcador,,Pistetaulun vaihtokytkin,Afficher Scores (alterner),Eredményjelző kapcsoló,Abilita/disabilita tabella punteggio,スコアボード切替,점수창 토글,Scorebord aan/uit,Veksle resultattavle,Włącz / Wyłącz tablicę wyników,Ativar/desativar placar,Ligar/desligar Pontuação no Ecrã,Comutator pentru Tabela de Marcaj,Таблица очков (перекл.),Табела (без држања),Skor Tablosunu Değiştir -Lookspring,MOUSEMNU_LOOKSPRING,,,,Automatické vystředění pohledu,,Automatisch zentrieren,,Rigardsalto,Mirar con ratón,,Katseenpalautin,Recentrer après Vue Souris,,,視点水平化,마우스룩 시점 초기화,Automatisch centraliseren,,Automatyczne Wyśrodkowanie,Centralizar automaticamente,Centrar automáticamente,Mișcare a jucătorului prin mouse,Передвижение мышью,Покрет мишем,Lookspring -Lookstrafe,MOUSEMNU_LOOKSTRAFE,,,,Použít myš k pohybu do stran,,Seitwärts bewegen mit der Maus,,Rigardturnmovo,Mirar con movimiento,,Sivuttaisastuntapalautin,Mouvement Latéral par Souris,,,視点横移動化,마우스룩 좌우 이동,Zijwaartse muisbeweging,,Unikanie przy użyciu myszki,Deslocamento lateral com o mouse,Deslocamento lateral com o rato,Mișcare în diagonală cu mouse,Движение боком мышью,Стрејф мишем,Lookstrafe -,,Map colors,,,,,,,,,,,,,,,,,,,,,,,, -Background,MAPCOLORMNU_BACKCOLOR,,,,Pozadí,Baggrund,Hintergrund,,Fono,Fondo,,Tausta,Fond,Háttér,Sfondo,背景,배경,Achtergrond,Bakgrunn,Tło,Fundo,,Fundal,Фон,Позадина,Arka plan -You,MAPCOLORMNU_YOURCOLOR,,,,Ty,Du,Du,,Vi,Tú,,Sinä,Votre couleur,Te,Tu,自分,당신,,Du,Ty,Você,Tu,Tu,Вы,Ти,Sen -1-sided walls,MAPCOLORMNU_WALLCOLOR,,,,Jednostranné zdi,1-sidede vægge,Einseitige Wände,,1-flankaj muroj,Paredes de 1 lado,,Yksipuoliset seinät,Murs à 1 côté,1 oldalú falak,Muri unilaterali,壁,단면 벽들,1-zijdige wanden,1-sidige vegger,Jednostronne ściany,Paredes de 1 lado,,Pereți cu o singură față,Односторонние стены,Једнострани зид,1 taraflı duvarlar -2-sided walls with different floors,MAPCOLORMNU_FDWALLCOLOR,,,,Oboustranné zdi s různými podlahami,2-sidede vægge med forskellige gulve,Zweiseitige Wände mit unterschiedlicher Bodenhöhe,,2-flankaj muroj kun malsamaj plankoj,Paredes de 2 lados con pisos distintos,,Kaksipuoliset seinät eroavilla lattiakorkeuksilla,Murs à 2 côtés avec différents sols,2 oldalú falak különböző padlókkal,Muri bilaterali con pavimenti diversi,高低差のある床,다른 층 추가된 양면 벽들,2-zijdige wanden met verschillende vloeren,2-sidige vegger med forskjellige gulv,Dwustronne ściany z innymi piętrami,Paredes de 2 lados com pisos diferentes,,Pereți cu două fețe si podele diferite,Двусторонние стены,Двострани зид са различитим нивоима,Farklı zeminlere sahip 2 taraflı duvarlar -2-sided walls with different ceilings,MAPCOLORMNU_CDWALLCOLOR,,,,Oboustranné zdi s různými stropy,2-sidede vægge med forskellige lofter,Zweiseitige Wände mit unterschiedlicher Deckenhöhe,,2-flankaj muroj kun malsamaj plafonoj,Paredes de 2 lados con techos distintos,,Kaksipuoliset seinät eroavilla kattokorkeuksilla,Murs à 2 côtés avec différents plafonds,2 oldalú falak különböző plafonnal,Muri bilaterali con soffitti diversi,高低差のある天井,다른 천장 추가된 양면 벽들,2-zijdige wanden met verschillende plafonds,2-sidige vegger med forskjellige tak,Dwustronne ściany z innymi sufitami,Paredes de 2 lados com tetos diferentes,,Pereți cu două fețe si tavane diferite,Двусторонние стены с разными потолками,Двострани зид са различитим плафонима,Farklı tavanlara sahip 2 taraflı duvarlar -2-sided walls with 3D floors,MAPCOLORMNU_EFWALLCOLOR,,,,Oboustranné zdi s 3D podlahami,2-sidede vægge med 3D-gulve,Zweiseitige Wände mit 3D-Ebenen,,2-flankaj muroj kun 3D-plankoj,Paredes de 2 lados con suelos 3D,,Kaksipuoliset seinät kolmiulotteisilla lattioilla,Murs à 2 côtés avec sols 3d,2 oldalú falak 3D-s padlókkal,Muri bilaterali con 3D floor,多重床,3D 층 추가된 양면 벽들,2-zijdige wanden met 3D-vloeren,2-sidige vegger med 3D-gulv,Dwustronne ściany z piętrami 3D,Paredes de 2 lados com pisos 3D,,Pereți cu două fețe si podele 3D,Двусторонние стены с разными полами,Двострани зид са 3D нивоима,3D zeminli 2 taraflı duvarlar -Map grid,MAPCOLORMNU_GRIDCOLOR,,,,Mřížka,Kortgitter,Kartengitter,,Mapkrado,Cuadrícula del mapa,,Kartan ruudukko,Quadrillage,Pálya szél,Griglia mappa,マップグリッド,맵 격자,Kaart raster,Kartrutenett,Siatka mapy,Grade do mapa,Grelha do mapa,Grilă hartă,Цвет сетки,Мапа координатне мреже,Harita ızgarası -Center point,MAPCOLORMNU_XHAIRCOLOR,,,Centre point,Středobod,Midterpunkt,Mittelpunkt,,Centra punkto,Punto central,,Keskipiste,Point Central,Pálya közepe,Punto centrale,中心点,중간 지점,Middenpunt,Midtpunkt,Środek,Ponto central,,Punct în centru,Курсор,Централна тачка,Merkez noktası -Not-yet-seen walls,MAPCOLORMNU_NOTSEENCOLOR,,,,Neobjevené zdi,"Vægge, der endnu ikke er synlige",Ungesehene Wände,,Vidotaj muroj,Paredes sin ver,,Tutkimattomat seinät,Murs non découvers,Még nem látott falak,Muri ancora da scoprire,未見の壁,안 본 벽들,Nog niet zichtbare wanden,Vegger som ennå ikke er sett,Jeszcze niewidziane ściany,Paredes não vistas até o momento,,Ziduri încă neobservate,Необнаруженные стены,Неоткривени зидови,Henüz görülmemiş duvarlar -Locked doors,MAPCOLORMNU_LOCKEDCOLOR,,,,Zamčené dveře,Låste døre,Verschlossene Türen,,Ŝlositaj pordoj,Puertas bloqueadas,,Lukitut ovet,Portes verouillées,Zárt ajtók,Porte bloccate,鍵の掛かったドア,잠긴 문들,Gesloten deuren,Låste dører,Zablokowane drzwi,Portas trancadas,,Uși închise,Запертые двери,Закључана врата,Kilitli kapılar -Teleporter to the same map,MAPCOLORMNU_INTRALEVELCOLOR,,,,Teleportér,Teleporter til samme kort,Teleporter,,Teleportilo al la sama mapo,Teletransporte al mismo mapa,,Kaukosiirrin samaan tasoon,Téléporteurs (même niveau),Ugyanarra a pályára teleportálás,Teletrasporto nella stessa mappa,テレポーター,같은 맵에 텔레포터 추가,Teleporter naar dezelfde niveau,Teleporter til samme kart,Teleporter do tej samej mapy,Teletransportador para o mesmo mapa,,Teleportor către aceeași hartă,Телепорт в пределах уровня,Телепортер до истог нивоа,Aynı haritaya ışınlayıcı -Teleporter to a different map,MAPCOLORMNU_INTERLEVELCOLOR,,,,Teleportér do jiného levelu,Teleporter til et andet kort,Teleporter in ein anderes Level,,Teleportilo al alia mapo,Teletransporte a un mapa diferente,,Kaukosiirrin eri tasoon,Téléporteurs (autre niveau),Másik pályára teleportálás,Teletrasporto in una mappa diversa,別マップへのテレポーター,다른 맵에 텔레포터 추가,Teleporter naar een andere niveau,Teleporter til et annet kart,Teleporter do innej mapy,Teletransportador para outro mapa,,Teleportor către altă hartă,Телепорт на другой уровень,Телепортер до различитог нивоа,Farklı bir haritaya ışınlayıcı -Secret sector,MAPCOLORMNU_SECRETSECTORCOLOR,,,,Skrýš,Hemmelig sektor,Geheimer Sektor,,Sekreta sektoro,Sector secreto,,Salasektori,Secteur Secret,Rejtekhely szektora,Settore segreto,シークレット,비밀 섹터,Geheime sector,Hemmelig sektor,Sekretny sektor,Setor secreto,,Sector secret,Тайный сектор,Тајни сектор,Gizli sektör -Unexplored secret,MAPCOLORMNU_UNEXPLOREDSECRETCOLOR,,,,Neobjevená skrýš,Uudforsket hemmelighed,nicht gefundener geheimer Sektor,,Neesplorita sekreto,Secreto sin explorar,,Tutkimaton sala,Secret non révélé,Még fel nem fedezett rejtekhely,Segreto non esplorato,未知のシークレット,발견하지 않은 비밀,Onontgonnen geheim,Uutforsket hemmelighet,Niezbadany sekret,Segredo não-explorado,,Secret neexplorat,Необнаруженный тайник,Ноткривена тајна,Keşfedilmemiş sır -Special trigger lines,MAPCOLORMNU_SPECIALWALLCOLOR,,,,Akční čáry,Særlige udløserlinjer,Spezielle Linien,,Specialaj ekagilo-linioj,Líneas especiales de activación,,Erikoislaukaisinviivat,Lignes d'actions spéciales,Speciális trigger vonalak,Linee di attivazione speciali,特殊トリガー,특수 트리거 선,Speciale trekkerlijnen,Spesielle utløserlinjer,Specjalne linie przełączników,Linhas de ativação especiais,,Linii declașatoare speciale,Специальные спусковые линии,Специјалне линије окидача,Özel tetik hatları -Cheat Mode,MAPCOLORMNU_CHEATMODE,,,,Cheatovací režim,Snyd-tilstand,Cheat-Modus,,Tromp-Reĝimo,Modo de truco,,Huijaustila,Mode Cheat,Csalás mód,Modalità cheat,チートモード時,치트 모드,Bedriegingsmodus,Juksemodus,Tryb oszustwa,Modo trapaça,Modo de Batota,Modul Trișor,Чит-режим,Чит мод,Hile Modu -Invisible 2-sided walls,MAPCOLORMNU_TSWALLCOLOR,,,,Neviditelné oboustranné zdi,Usynlige 2-sidede vægge,Unsichtbare zweiseitige Wände,,Nevideblaj 2-flankaj muroj,Paredes de 2 lados Invisibles,,Näkymättömät kaksipuoliset seinät,Murs à 2 côtés invisibles,Láthatatlan 2 oldalú falak,Muri invisibili bilaterali,表示されないline,투명한 양면 벽,Onzichtbare 2-zijdige wanden,Usynlige 2-sidige vegger,Niewidzialne dwustronne ściany,Paredes invisíveis de 2 lados,,Pereți cu două fețe invizibili,Невидимые двусторонние стены,Невидљиви двострани зидови,Görünmez 2 taraflı duvarlar -Secret walls,MAPCOLORMNU_SECRETWALLCOLOR,,,,Tajné zdi,Hemmelige vægge,Geheime Wände,,Sekretaj muroj,Paredes secretas,,Salaiset seinät,Murs Secrets,Titkos falak,Muri segreti,シークレットの壁,비밀 벽,Geheime muren,Hemmelige vegger,Sekretne ściany,Paredes secretas,,Pereți ascunși,Тайные стены,Тајни зидови,Gizli duvarlar -Actors,MAPCOLORMNU_THINGCOLOR,,,,Objekty,Skuespillere,Akteure,,Aktoroj,Actores,,Oliot,Acteurs,Játékos,Attori,アクター,개체,Acteurs,Skuespillere,Aktorzy,Atores,,Actori,Объекты,Актори,Aktörler -Monsters,MAPCOLORMNU_MONSTERCOLOR,,,,Příšery,Monstre,Monster,,Monstroj,Monstruos,,Hirviöt,Monstres,Szörnyek,Mostri,モンスター,적들,Monsters,Monstre,Potwory,Monstros,,Monștri,Монстры,Чудовишта,Canavarlar -Non-counting Monsters,MAPCOLORMNU_NONCOUNTINGMONSTERCOLOR,,,,Nepočítané příšery,Ikke-tællende monstre,nicht gezählte Monster,,Nenombradaj Monstroj,Monstruos no contados,Monstruos sin contar,Ei-laskettavat hirviöt,Monstres non comptés,Nem számolt szörnyek,Mostri non contati,非カウントモンスター,킬수에 포함 되지 않는 적들,Niet-tellende Monsters,Ikke-tellende monstre,Niezliczane Potwory,Monstros não contados,,Monștri neacoperiți de numărătoare,Неучитываемые монстры,Не рачунајући чудовишта,Sayılamayan Canavarlar -Friends,MAPCOLORMNU_FRIENDCOLOR,,,,Přátelé,Venner,Freunde,,Amikoj,Amigos,,Omat,Amis,Barátok,Amici,仲間,친구들,Vrienden,Venner,Przyjaciele,Amigos,,Prieteni,Дружественные,Пријатељи,Arkadaşlar -Items,MAPCOLORMNU_ITEMCOLOR,,,,Předměty,Genstande,Gegenstände,,Objektoj,Objetos,,Esineet,Objets,Tárgyak,Oggetti,アイテム,아이템들,Artikelen,Gjenstander,Przedmioty,Itens,,Obiecte,Предметы,Предмети,Eşyalar -Count Items,MAPCOLORMNU_COUNTITEMCOLOR,,,,Počítané předměty,Tælle genstande,gezählte Gegenstände,,Nombri Objektojn,Objetos contados,Conteo de objetos,Laske esineet,Objets comptés,Tárgyak számolása,Oggetti contati,カウント対象アイテム,아이템 계산,Tellen,Telle elementer,Zlicz przedmioty,Itens contados,,Numără obiectele,Учитываемые предметы,Рачунајући предмети,Sayım Öğeleri -Overlay Mode,MAPCOLORMNU_OVERLAY,,,,Překryvný režim,Overlay-tilstand,Überlagerungsmodus,,Surmeto-Reĝimo,Modo sobrepuesto,,Projisointitila,Mode surimpression,Overlay mód,Modalità sovrapposizione,オーバーレイモード,오버레이 모드,Overlaadmodus,Overleggsmodus,Tryb Nakładki,Modo de sobreposição,,Mod acoperit,Прозрачный режим,Провидна аутомапа,Kaplama Modu -Overlay Cheat Mode,MAPCOLORMNU_OVCHEATMODE,,,,Překryvný cheatovací režim,Overlay snydetilstand,Überlagerungsmodus Cheats,,Surmeto-Tromp-Reĝimo,Sobreposición modo de truco,,Projisointihuijaustila,Mode Cheat Surimpression,overlay csaló mód,Modalità cheat sovrapposizione,オーバーレイ チートモード,치트 모드 오버레이,Overlaadmodus Cheats,Overlegg-juksemodus,Tryb Nakładki Oszustwa,Modo trapaça de sobreposição,Modo Batota de Sobreposição,Mod acoperit trișor,Прозрачный чит-режим,Провидни читови,Kaplama Hile Modu -Portal Overlays,MAPCOLORMNU_PORTAL,,,,Portálové překryvy,Portal-overlejringer,Portalüberlagerung,,Portalo-Surmetoj,Sobreposición de portal,,Portaaliprojisoinnit,Portails superposés,Portál overlay-ek,Sovrapposizioni del portale,ポータル オーバーレイ,포탈 오버레이,Portaaloverlays,Portal-overlegg,Nakładanie się Portali,Sobreposição de portais,,Acoperiri portaluri,Порталы в прозрачном режиме,Провидни портали,Portal Kaplamaları -,,Messages,,,,,,,,,,,,,,,,,,,,,,,, -Messages,MSGMNU_TITLE,,,,Nastavení oznámení,Meddelelser,Nachrichten,,Mesaĝoj,Mensajes,,Viestit,,Üzenetek,Messaggi,メッセージ類,메시지들,Berichten,Meldinger,Wiadomości,Mensagens,,Mesaje,Сообщения,Поруке,Mesajlar -Show messages,MSGMNU_SHOWMESSAGES,,,,Zobrazit oznámení,Vis meddelelser,Zeige Nachrichten,,Montri mesaĝojn,Mostrar Mensajes,,Näytä viestit,Afficher messages,Üzenetek mutatása,Mostra messaggi,メッセージ表示,메시지 표시,Berichten tonen,Vis meldinger,Pokaż wiadomości,Exibir mensagens,,Afișare mesaje,Отображение сообщений,Прикажи поруке,Mesajları göster -Show obituaries,MSGMNU_SHOWOBITUARIES,,,,Zobrazit oznámení o smrtích,Vis dødsannoncer,Zeige Todesanzeigen,,Montri nekrologojn,Mostrar obituarios,,Näytä kuolinviestit,Afficher avis de décès,Halálok mutatása,Mostra i necrologi,訃報表示,사망 메시지 표시,Doodsbrieven tonen,Vis dødsannonser,Pokaż nekrologi,Exibir obituários,,Afișare necrologuri,Отображение некрологов,Прикажи читуље,Ölüm ilanlarını göster -Show secret notifications,MSGMNU_SHOWSECRETS,,,,Zobrazit zprávy o skrýších,Vis hemmelige meddelelser,Zeige Geheimnismeldung,,Montri sciigojn de sekretoj,Mostrar notificación de secretos,,Ilmoita salojen löytymisestä,Afficher secrets,Titkos üzenetek mutatása,Mostra le notifiche dei segreti,シークレット発見表示,비밀 알림 표시,Geheime meldingen tonen,Vis hemmelige meldinger,Pokaż wiadomości znalezienia sekretu,Exibir notificação de segredos,,Afișare notificări pentru secrete,Отображение сообщений о тайниках,Прикажи тајне нотификације,Gizli bildirimleri göster -Minimum message level,MSGMNU_MESSAGELEVEL,,,,Minimální úroveň oznámení,Mindste beskedniveau,Min. Nachrichtenanzeigestufe,,Minimuma nivelo de mesaĝoj,Nivel mínimo de mensaje,,Pienin viestintätaso,Niveau de message minimum,Milyen üzenet jelenjen meg,Numero di messaggi minimo,最小メッセージレベル,메시지 축소량,Minimaal berichtenniveau,Minste meldingsnivå,Poziom minimalnych wiadomości,Nível mínimo de mensagem,,Nivel minim de afișare mesaje,Минимальный уровень сообщений,Минимум левел порука,Minimum mesaj seviyesi -Message Colors,MSGMNU_MESSAGECOLORS,,,Message Colours,Barva oznámení,Farver på meddelelser,Nachrichtenfarben,,Mesaĝkoloroj,Colores de los Mensajes,,Viestien värit,Couleur des messages,Üzenet színek,Colore dei messaggi,メッセージ色,메시지 색상,Bericht Kleuren,Meldingsfarger,Kolory Wiadomości,Cores de mensagem,,Culori Mesaje,Цвета сообщений,Боје порука,Mesaj Renkleri -Item Pickup,MSGMNU_ITEMPICKUP,,,,Sebrání předmětu,Afhentning af varer,Genommene Gegenstände,,Objektoprenado,Toma de objetos,,Esineen poimiminen,Objets ramassés,Tárgy felvétele,Raccolta oggetti,アイテム取得,아이템 획득,Puntafhaling,Henting av element,Podniesienie Przedmiotu,Coleta de item,Aquisição de Itens,Ridicare obiecte,Подбор предмета,Покупити предмет,Bir eşyayı almak -Obituaries,MSGMNU_OBITUARIES,,,,Oznámení o úmrtí,Dødsannoncer,Todesanzeigen,,Nekrologoj,Obituarios,,Kuolinviestit,Avis de décès,Halálok,Necrologi,死亡時メッセージ,사망 메시지,Doodsbrieven,Nekrologer,Nekrologi,Obituários,,Necrologuri,Некрологи,Читуље,Ölüm İlanları -Critical Messages,MSGMNU_CRITICALMESSAGES,,,,Kritická oznámení,Kritiske meddelelser,Kritische Nachrichten,,Gravaj Mesaĝoj,Mensajes críticos,,Tärkeät viestit,Messages d'erreur,Fontos üzenetek,Messaggi critici,致命的なメッセージ,중요한 메시지,Kritische berichten,Kritiske meldinger,Wiadomości krytyczne,Mensagens críticas,,Mesaje Critice,Важные сообщения,Критичне поруке,Kritik Mesajlar -Chat Messages,MSGMNU_CHATMESSAGES,,,,Chatová oznámení,Chat-meddelelser,Chatnachrichten,,Babilmesaĝoj,Mensajes de chat,,Keskusteluviestit,Message de Chat,Chat üzenetek,Messaggi chat,チャットメッセージ,채팅 메시지,Chatberichten,Chat-meldinger,Wiadomości czatu,Mensagens de chat,,Mesaje Conversație,Сообщения в чате,Ћаскања,Sohbet Mesajları -Team Messages,MSGMNU_TEAMMESSAGES,,,,Týmová oznámení,Hold-meddelelser,Teamnachrichten,,Teammesaĝoj,Mensajes de equipo,,Joukkueen viestit,Messages d'équipe,Csapat chat üzenetek,Messaggi chat di squadra,チームメッセージ,팀 채팅 메시지,Team Berichten,Team-meldinger,Wiadomości czatu drużynowego,Mensagens de equipe,Mensagens de Equipa,Mesajele Echipei Proprii,Командные сообщения в чате,Тимске поруке,Ekip Mesajları -Centered Messages,MSGMNU_CENTEREDMESSAGES,,,Centred Messages,Oznámení na střed,Centrerede meddelelser,Zentrierte Nachrichten,,Centritaj Mesaĝoj,Mensajes centrados,,Keskitetyt viestit,Messages centrés,Üzenet középre igazítása,Messaggi centrati,スクリプトメッセージ,중간에 위치한 메시지,Gecentreerde berichten,Sentrerte meldinger,Wyśrodkowane wiadomości,Mensagens centralizadas,Mensagens Centradas,Mesaje Centrate,Центрированные сообщения,Централне поруке,Merkezli Mesajlar -Screenshot messages,MSGMNU_SCREENSHOTMESSAGES,,,,Oznámení o snímcích obrazovky,Beskeder med skærmbilleder,Screnshot-Meldungen,,Mesaĝoj de ekrankopio,Mensajes de captura de pantalla,,Kuvakaappausviestit,Messages de capture d'écran,Képernyőkép készítés visszajelzés,Messaggi di cattura schermo,スクショメッセージ,스크린샷 메시지,Screenshot berichten,Skjermbilde-meldinger,Wiadomości o zrobieniu zrzutu ekranu,Mensagens de captura de tela,Mensagen de captura de ecrã,Mesaje Capturi Ecran,Сообщения о снимках экрана,Скриншот поруке,Ekran görüntüsü mesajları -Detailed save messages,MSGMNU_LONGSAVEMESSAGES,,,,Detailní oznámení o uložené hře,Detaljerede beskeder om lagring,Detaillierte Speicher-Meldungen,,Detalaj konservmesaĝoj,Mensajes detallados de guardado,,Yksityiskohtaiset tallennusviestit,Messages de sauvegarde détailés,Részletes mentési információ,Messaggi sui dettagli di salvataggio,詳細なセーブメッセージ,자세한 저장 메시지,Gedetailleerde berichten voor op te slaan,Detaljerte lagringsmeldinger,Szczegółowe wiadomości o zapisie,Mensagens detalhadas de salvamento,Mensagens detalhadas de gravação,Mesaje detaliate pentru salvări,Подробные сообщения о сохранениях,Детаљно сачуване поруке,Ayrıntılı kaydetme mesajları -Developer message mode,MSGMNU_DEVELOPER,,,,Vývojářská oznámení,Meddelelsestilstand for udviklere,Entwickler-Modus,,Reĝimo de mesaĝoj por programistoj,Modo de mensajes de desarrollador,,Pelinkehittäjäviestitila,Mode de Développement,Fejlesztői üzenetek,Modalità messaggi per sviluppatore,開発者用モード,개발자 메시지 모드,Berichtenmodus voor ontwikkelaars,Meldingsmodus for utviklere,Tryb wiadomości deweloperskich,Modo de mensagens de desenvolvedor,,Mod mesaje pentru dezvoltator,Режим сообщений для разработчиков,Поруке девелопера,Geliştirici mesaj modu -,,Automap,,,,,,,,,,,,,,,,,,,,,,,, -Map color set,AUTOMAPMNU_COLORSET,,,Map colour set,Barevné schéma,Farvesæt til kort,Farbset,,Mapkoloro-agordaĵo,Definir colores,,Kartan värikokoelma,Set de couleurs de la carte,Pálya térkép szín séma,Colori della mappa,地図色セット,맵 색상 설정,Kaartkleurenset,Kartfargesett,Zestaw kolorów mapy,Definir cores de mapa,,Set culori hartă,Цвета автокарты,Боје за мапу,Harita renk seti -Allow map defined colors,AUTOMAPMNU_CUSTOMCOLORS,,,Allow map defined colours,Povolit barvy dle modů,Tillad kortdefinerede farver,Erlaube levelspezifische Farben,,Permesi mapdefinitajn kolorojn,Permitir colores definidos,,Salli tason määrittelemät värit,Couleurs définies par carte,Pálya orientált színséma használata,Consenti i colori definiti dalla mappa,定義したマップ色の許可,맵 정의 색상 허용,Niveau-specifieke kleuren toestaan,Tillat kartdefinerte farger,Pozwól na kolory zdefiniowne przez mapę,Permitir cores definidas por mapa,,Permite culorilor să fie definite de hartă,Разрешить определённые уровнем цвета автокарты,Дозволи дефинисане боје за мапу,Harita tanımlı renklere izin ver -Set custom colors,AUTOMAPMNU_SETCUSTOMCOLORS,,,Set custom colours,Vlastní barvy,Indstil brugerdefinerede farver,Benutzerdefinierte Farben,,Agordi laŭmendajn kolorojn,Fijar colores personalizados,,Mukauta värejä,Choisir couleurs personnalisées,Egyéni színek beállítása,Modifica i colori personalizzati,カスタム色を決める,사용자 지정 색상 설정,Aangepaste kleuren instellen,Angi egendefinerte farger,Spersonalizuj kolory,Definir cores personalizadas,,Setare culori personalizate,Задать свои цвета,Промени боје,Özel renkleri ayarlama -Customize map controls,AUTOMAPMNU_CONTROLS,,,,Ovládání mapy,Tilpas kontrolelementer til kortet,Automapsteuerung einstellen,,Adapti mapregilojn,Personalizar controles del mapa,,Kartanohjausasetukset,Choisir contrôles de la carte,Térkép irányítás testreszabása,Personalizza i controlli mappa,マップコントロール カスタマイズ,맵 조작 설정,Kaartcontroles aanpassen,Tilpass kartkontroller,Ustaw klawisze mapy,Configurar comandos de mapa,,Personalizare schemă de control a hărții,Управление автокартой,Промени контроле мапе,Harita kontrollerini özelleştirme -Overlay automap,AUTOMAPMNU_OVERLAY,,,,Překryvná mapa,Overlay automap,Überlagere Automap,,Surmeti aŭtomapon,Superponer automapa,,Projisoi automaattikartta,Carte en Surimpression,Képen felüli térkép,Copri l'automappa,オートマップを重ねる,오토맵을 오버레이,Overlay automap,Overlegg automatisk kart,Nałożenie mapy,Sobreposição de automapa,,Acoperire hartă computerizată,Прозрачная автокарта,Провидна аутомапа,Yerleşim otomatik haritası -Enable textured display,AUTOMAPMNU_TEXTURED,,,,Textury,Aktiver tekstureret visning,Texturanzeige,,Ŝalti teksturitan ekranon,Mostrar automapa texturizado,,Ota käyttöön pintakuvioinnit,Activer affichage texturé,Textúrázott térkép,Abilita la mostra texture,床テクスチャ表示を許可,텍스쳐 디스플레이 허용,Structuurweergave inschakelen,Aktiver teksturert visning,Włącz oteksturowanie mapy,Habilitar automapa texturizado,Permitir automapa texturizado,Activare mod texturat,Текстуры на автокарте,Омогући приказ текстура,Dokulu ekranı etkinleştir -Show item counts,AUTOMAPMNU_SHOWITEMS,,,,Počet předmětů,Vis tællinger af emner,Zeige Gegenstandsanzahl,,Montri nombron de objektoj,Mostrar conteo de objetos,,Näytä esineiden lukumäärä,Afficher compte d'objets,Tárgy számláló mutatása,Mostra il conteggio degli oggetti,アイテム数 表示,주운 아이템의 갯수를 표시,Toon artikeltellingen,Vis antall elementer,Pokaż liczbę przedmiotów,Exibir contagem de itens,,Afișare numărătoare obiecte,Количество предметов,Прикажи бројач за предмете,Öğe sayılarını göster -Show monster counts,AUTOMAPMNU_SHOWMONSTERS,,,,Počet příšer,Vis monstertællinger,Zeige Monsteranzahl,,Montri nombron de monstroj,Mostrar conteo de monstruos,,Näytä hirviöiden lukumäärä,Afficher compte de monstres,Szörny számláló mutatása,Mostra il conteggio dei mostri,モンスター数 表示,죽인 적의 횟수 표시,Toon monstertellingen,Vis antall monster,Pokaż liczbę potworów,Exibir contagem de monstros,,Afișare numărătoare monștri,Количество монстов,Прикажи бројач за чудовишта,Canavar sayılarını göster -Show secret counts,AUTOMAPMNU_SHOWSECRETS,,,,Počet skrýší,Vis hemmelige tællinger,Zeige Geheimnisanzahl,,Montri nombron de sekretoj,Mostrar conteo de secretos,,Näytä salojen lukumäärä,Afficher compte de secrets,Rejtekhely számláló mutatása,Mostra il conteggio dei segreti,シークレット数 表示,밝힌 비밀의 수 표시,Toon geheime tellingen,Vis hemmelige tellinger,Pokaż liczbę sekretów,Exibir contagem de segredos,,Afișare numărătoare secrete,Количество тайников,Прикажи бројач за тајне,Gizli sayıları göster -Show time elapsed,AUTOMAPMNU_SHOWTIME,,,,Uplynulý čas na mapě,Vis den forgangne tid,Zeige vergangene Zeit,,Montri pasintan tempon,Mostrar tiempo transcurrido,,Näytä kulunut aika,Afficher temps passé,Eltöltött idő mutatása,Mostra il tempo trascorso,経過時間 表示,경과한 시간 표시,Verstreken tijd tonen,Vis medgått tid,Pokaż ile czasu upłynęło,Exibir tempo decorrido,,Afișare timp petrecut pe hartă,Прошедшее время,Прикажи протекло време,Geçen süreyi göster -Show total time elapsed,AUTOMAPMNU_SHOWTOTALTIME,,,,Celkový uplynulý čas,"Vis den samlede tid, der er gået",Zeige Gesamtzeit,,Montri tutan pasintan tempon,Mostrar tiempo total transc.,,Näytä yhteensä kulunut aika,Afficher total de temps passé,Teljes eltelt idő mutatása,Mostra il tempo totale trascorso,統計時間 表示,누적 경과한 시간 표시,Toon de totale verstreken tijd,Vis total tid som har gått,"Pokaż całkowity czas, który upłynął",Exibir tempo total decorrido,,Afișare timp total petrecut în joc,Общее время,Прикажи укупно протекло време,Geçen toplam süreyi göster -Show secrets on map,AUTOMAPMNU_MAPSECRETS,,,,Zobrazit skrýše,Vis hemmeligheder på kortet,Zeige Geheimnisse auf der Karte,,Montri sekretojn sur mapo,Mostrar secretos en el mapa,,Näytä salat kartalla,Afficher secrets sur carte,Rejtekhelyek mutatása a pályán,Mostra i segreti nella mappa,シークレットを地図に表示,맵의 비밀을 표시,Toon geheimen op de kaart,Vis hemmeligheter på kartet,Pokaż sekrety na mapie,Exibir segredos no mapa,,Afișare secrete,Тайники на карте,Прикажи тајне на аутомапи,Haritada sırları göster -Show map label,AUTOMAPMNU_SHOWMAPLABEL,,,,Zobrazit název mapy,Vis kortmærke,Zeige Levelnamen,,Montri mapetikedon,Mostrar etiqueta del mapa,,Näytä tason tunniste,Afficher label de carte,Pályacím mutatása,Mostra le etichette della mappa,マップ名 表示,맵의 이름 표시,Toon kaartlabel,Vis kartetikett,Pokaż etykietę mapy,Exibir etiqueta do mapa,,Afișare etichetă hartă,Название карты,Прикажи ознаку мапе,Harita etiketini göster -Draw map background,AUTOMAPMNU_DRAWMAPBACK,,,,Pozadí mapy,Tegne kortbaggrund,Zeige Kartenhintergrund,,Desegni mapfondon,Dibujar fondo de mapa,,Piirrä tason tausta,Afficher fond d'écran carte,Térkép háttér kirajzolása,Mostra lo sfondo della mappa,マップの背景 描写,맵의 배경 출력,Teken de achtergrond van de kaart,Tegn kartbakgrunn,Rysuj tło mapy,Desenhar fundo do mapa,,Afișare fundal hartă,Отображение фона автокарты,Нацртај позадину мапе,Harita arka planı çizme -Show keys (cheat),AUTOMAPMNU_SHOWKEYS,,,,Zobrazení klíčů (podvod),Vis nøgler (snyd),Zeige Schlüssel (Cheat),,Montri klavojn (trompo),Mostrar llaves (truco),,Näytä avaimet (huijauskeino),Afficher les clés (cheat),Kulcsok mutatása,Mostra le chiavi (cheat),鍵 表示(チート時),키를 표시 (치트),Toon sleutels (valsspeler),Vis nøkler (juks),Pokaż klucze (oszustwo),Exibir chaves (trapaça),,Afișare chei (trișare),Отображение ключей (чит-коды),Прикажи кључеве (чит),Tuşları göster (hile) -Show trigger lines,AUTOMAPMNU_SHOWTRIGGERLINES,,,,Zobrazení aktivujících čar,Vis trigger-linjer,Zeige Auslöserlinien,,Montri baskulliniojn,Mostrar líneas de activación,,Näytä laukaisinviivat,Afficher lignes d'action,Trigger vonalak mutatása,Mostra le linee d'attivazione,トリガーライン 表示,트리거 선을 표시,Triggerlijnen tonen,Vis utløserlinjer,Pokaż linie przełączników,Exibir linhas de ativação,,Afișare linii declanșatoare,Отображение спусковых линий,Прикажи триггер линије,Tetik çizgilerini göster -Show things as sprites,AUTOMAPMNU_SHOWTHINGSPRITES,,,,Zobrazení objektů jako spritů,Vis ting som sprites,Zeige Dinge als Sprites,,Montri objektojn kiel spritoj,Mostrar cosas como sprites,,Näytä oliot spriteinä,Afficher objets comme sprites,Tárgyak sprite-ként megjelenítése,Mostra gli oggetti come sprite,thingsのスプライト表示,물체를 스프라이트로 표시,Toon dingen als sprites,Vis ting som sprites,Pokaż rzeczy jako sprite'y,Exibir objetos como sprites,,Afișare obiecte drept sprite,Отображение спрайтов объектов,Прикажи ствари као спрајтове,Nesneleri sprite olarak gösterme -Overlay portals,AUTOMAPMNU_PTOVERLAY,,,,Překrývat portály,Overlay portaler,Überlagere Portale,,Surmeti portalojn,Sobreponer portales,,Projisoi portaalit,Superposer les portails,Overlay portálok,Sovrapponi i portali,オーバーレイ ポータルズ,포탈을 오버레이,Overlappende portalen,Overlegg portaler,Nałóż portale,Sobreposição de portais,,Acoperire portaluri,Порталы в прозрачном режиме,Провидни портали,Yerleşim portalları -Empty space margin,AUTOMAPMNU_EMPTYSPACEMARGIN,,,,Práh prázdného prostoru,Tomrumsmargin,Breite des Randes,,Malplena spacia marĝeno,Margen de espacio vacío,,Tyhjän reunan leveys,Marge d'espace vide,Üres hely szegély,Margine dello spazio vuoto,空間の余白,빈공간 여백,Breedte van de rand,Tøm mellomromsmargen,Opróżnij margines przestrzeni,Margem de espaço vazio,,Margine spațiu gol,Край автокарты,Празна маргина,Boş alan marjı -Mark font,AUTOMAPMNU_MARKFONT,,,,Písmo značek,Marker skrifttype,Zeichensatz für Markierungen,,Marki tiparon,Fuente para marcas,,Karttamerkkien fontti,Police Marqueur,Jelzés betűtípus,Font del segnaposto,マークフォント,미니맵 마킹 폰트,Font voor markers,Merk skrifttype,Czcionka oznaczeń,Fonte das marcações,,Font marcaj,Шрифт отметок,Фонт ознака,Mark yazı tipi -Mark color,AUTOMAPMNU_MARKCOLOR,,,,Barva značek,Markere farve,Farbe für Markierungen,,Marki koloron,Color de las marcas,,Karttamerkkien väri,Couleur Marqueur,Jelzés szín,Colore del segnaposto,マーク色,미니맵 마킹 색상,Markeer kleur,Merk farge,Kolor oznaczeń,Cor das marcações,,Culoare marcaj,Цвет отметок,Боја ознака,Renk işaretle -Set mark,MAPCNTRLMNU_SETMARK,,,,Umístit značku,Indstille mærke,Setze Markierung,,Meti markon,Fijar marca,,Aseta merkki,Placer repère,Jelzés beállítása,Aggiungi segnaposto,マークを置く,마크 추가,Markering instellen,Sett merke,Ustaw znacznik,Posicionar marcação,,Marcare,Поставить отметку,Постави ознаку,İşareti ayarla -Clear mark,MAPCNTRLMNU_CLEARMARK,,,,Smazat značky,Slet markering,Lösche Markierung,,Forigi markon,Limpiar marca,,Pyyhi merkit,Enlever repères,Jelzések törlése,Pulisci il segnaposto,マーククリア,마크 삭제,Duidelijke markering,Fjern merke,Usuń znacznik,Limpar marcação,,Ștergere marcaj,Убрать отметку,Уклони ознаку,Açık işaret -,,Scoreboard,,,,,,,,,,,,,,,,,,,,,,,, -Scoreboard Options,DSPLYMNU_SCOREBOARD,,,,Tabulka skóre,Indstillinger for resultattavlen,Punktetabellenoptionen,,Poentotabulo-Agordoj,Opciones de marcador,,Pistetauluasetukset,Options Tableau des Scores,Eredményjelző beállítások,Opzioni tabella punteggio,スコアボード オプション,점수창 설정,Scorebord opties,Alternativer for resultattavlen,Opcje Tablicy Wyników,Opções de Tela de Pontuação,,Opțiuni Tabelă de Marcaj,Таблица очков,Табеларне подешавања,Skorbord Seçenekleri -Scoreboard Options,SCRBRDMNU_TITLE,,,,Nastavení tabulky skóre,Indstillinger for resultattavlen,Punktetabellenoptionen,,Poentotabulo-Agordoj,Opciones de marcador,,Pistetauluasetukset,Tableau des Scores,Eredményjelző beállítások,Opzioni per la tabella punteggio,スコアボード オプション,점수판 설정,Scorebord opties,Alternativer for resultattavlen,Opcje Tablicy Wyników,Opções de Tela de Pontuação,Opções do Ecrã de Pontuação,Setări Tabelă de Marcaj,Настройки таблицы очков,Подешавања бодовања,Skorbord Seçenekleri -Cooperative Options,SCRBRDMNU_COOPERATIVE,,,,Kooperativní mód,Samarbejdsmuligheder,Kooperativ-Optionen,,Kooperativo-Agordoj,Opciones de cooperativo,,Yhteispeliasetukset,Options Mode Coop,Együttműködő beállítása,Opzioni per il gioco cooperativo,協力モードの設定,코옵 설정,Coöperatieve Opties,Samarbeidsalternativer,Opcje Kooperacji,Opções de Jogo Cooperativo,,Setări Mod Cooperativ,Настройки для команд,Подешавања сарадње,Kooperatif Seçenekleri -Enable Scoreboard,SCRBRDMNU_ENABLE,,,,Povolit tabulku skóre,Aktiver resultattavle,Punktetabelle aktiv,,Ŝalti Poentotabulon,Activar marcador,,Ota käyttöön pistetaulu,Activer Tableau des Scores,Eredményjelző bekapcsolása,Abilita la tabella punteggio,スコアボード表示,점수판 허용,Scorebord inschakelen,Aktiver resultattavle,Zezwól na Tablicę Wyników,Habilitar Tela de Pontuação,Permitir Ecrã de Pontuação,Activare Tabelă de Marcaj,Включить таблицу очков,Омогући бодовање,Skor Tablosunu Etkinleştir -Header Color,SCRBRDMNU_HEADERCOLOR,,,Header Colour,Barva hlavičky,Overskriftsfarve,Kopfzeilenfarbe,,Kapokoloro,Color de cabecera,,Otsikon väri,Couleur du Titre,Fejléc szín,Colore della testata,ヘッダー色,헤더의 색깔,Kleur koptekst,Farge på topptekst,Kolor Nagłówka,Cor de Cabeçalho,,Culoare Antet,Цвет заголовка,Боја заглавља,Başlık Rengi -Your Player Color,SCRBRDMNU_YOURCOLOR,,,Your Player Colour,Barva tvého hráče,Din spillerfarve,Deine Spielerfarbe,,Via Ludantkoloro,Color de tu jugador,,Pelaajasi väri,Votre couleur,Játékos színe,Colore del giocatore 'Tu',自分の色,플레이어의 색깔,Uw Spelerskleur,Din spillerfarge,Twoje Kolory,Cor do Seu Jogador,Cor do teu Jogador,Culoarea Jucătorului Tău,Ваш цвет,Боја твога играча,Oyuncu Renginiz -Other Players' Color,SCRBRDMNU_OTHERPLAYERCOLOR,,,Other Players' Colour,Barva ostatních hráčů,Andre spilleres farve,Andere Spielerfarbe,,Koloro de Aliaj Ludantoj,Color de otros jugadores,,Muiden pelaajien väri,Couleur des autres joueurs,Más játékosok színe,Colore degli altri giocatori,他者の色,다른 플레이어들의 색깔,Andere spelerskleur,Andre spilleres farge,Kolory Innych Graczy,Cor de Outros Jogadores,Cor dos Outros Jogadores,Culorile Celorlalți Jucători,Цвет других игроков,Боја другог играча,Diğer Oyuncuların Rengi -Deathmatch Options,SCRBRDMNU_DEATHMATCH,,,,Deathmatch,Indstillinger for Deathmatch,Deathmatch-Optionen,,Mortmaĉo-Agordoj,Opciones modo a muerte,,Kuolonotteluasetukset,Options Deathmatch,Deathmatch Beállítások,Opzioni deathmatch,デスマッチの設定,데스매치 설정,Deathmatch opties,Deathmatch-alternativer,Opcje Deathmatchu,Opções de Deathmatch,,Setări Deathmatch,Настройки боя насмерть,Детмеч подешавања,Ölüm Maçı Seçenekleri -Team Deathmatch Options,SCRBRDMNU_TEAMDEATHMATCH,,,,Týmový deathmatch,Indstillinger for Team Deathmatch,Team-Deathmatch-Optionen,,Teamo-Mortmaĉo-Agordoj,Opciones modo a muerte por equipos,,Joukkuekuolonotteluasetukset,Options Deathmatch en équipe,Team Deathmatch Beállítások,Opzioni deathmatch a squadra,チームデスマッチの設定,팀 데스매치 설정,Team Deathmatch Opties,Lag Deathmatch-alternativer,Opcje Drużynowego Deathmatchu,Opções de Deathmatch de Equipe,Opções de Deathmatch de Equipa,Setări Deathmatch în Echipă,Настройки командного боя насмерть,Тимски детмеч подешавања,Takım Ölüm Maçı Seçenekleri -,,Alt HUD,,,,,,,,,,,,,,,,,,,,,,,, -Alternative HUD,ALTHUDMNU_TITLE,,,,Alternativní HUD,Alternativ HUD,Alternatives HUD,,Alternativa HUD,HUD alternativo,,Vaihtoehtoinen tilanäyttö,ATH Alternatif,Alternatív HUD,HUD alternativo,オルタナティブHUD,대체 HUD,Alternatieve HUD,Alternativ HUD,Alternatywny HUD,HUD alternativo,,Interfață pe Timp de Joc Alternativă,Альтернативное отображение информации,Алтернативни HUD,Alternatif HUD -Enable alternative HUD,ALTHUDMNU_ENABLE,,,,Povolit alternativní HUD,Aktiver alternativt HUD,Alternatives HUD eingeschaltet,,Ŝalti alternativan HUD,Activar HUD alternativo,,Ota käyttöön vaihtoehtoinen tilanäyttö,Activer l'ATH Alternatif,Alternatív HUD bekapcsolása,Abilita HUD alternativo,オルタナティブHUD有効,대체 HUD 사용,Alternatieve HUD inschakelen,Aktiver alternativ HUD,Włącz alternatywny HUD,Habilitar HUD alternativo,,Activează Interfața pe Timp de Joc Alternativă,Включить альтернативное отображение,Укључи алтернативни HUD,Alternatif HUD'yi etkinleştirin -Show secret count,ALTHUDMNU_SHOWSECRETS,,,,Zobrazit počet skrýší,Vis hemmelig optælling,Zeige Geheimniszähler,,Montri sekretonombron,Mostrar cont. de secretos,,Näytä salojen lukumäärä,Afficher compteur de secrets,Rejtekhely számláló mutatása,Mostra il conteggio dei segreti,シークレット数 表示,비밀 수 표시,Toon het aantal geheimen,Vis hemmelig antall,Pokaż liczbę sekretów,Exibir contagem de segredos,,Afișează numărul secretelor,Отображение обнаруженных тайников,Прикажи количину тајна,Gizli sayımı göster -Show monster count,ALTHUDMNU_SHOWMONSTERS,,,,Zobrazit počet příšer,Vis monstertælling,Zeige Monsterzähler,,Montri monstronombron,Mostrar cont. de monstruos,,Näytä hirviöiden lukumäärä,Afficher compteur de monstres,Szörny számláló mutatása,Mostra il conteggio dei mostri,モンスター数 表示,적 개체 수 표시,Toon het aantal monsters,Vis antall monstre,Pokaż liczbę zabójstw,Exibir contagem de monstros,,Afișează numărul de monștri,Отображение количества монстров,Прикажи количину чудовишта,Canavar sayısını göster -Show item count,ALTHUDMNU_SHOWITEMS,,,,Zobrazit počet předmětů,Vis optælling af genstande,Zeige Gegenstandszähler,,Montri objektonombron,Mostrar cont. de objetos,,Näytä esineiden lukumäärä,Afficher compteur d'objets,Tárgy számláló mutatása,Mostra il conteggio degli oggetti,アイテム数の表示,아이템 수 표시,Toon het aantal items,Vis antall gjenstander,Pokaż liczbę przedmiotów,Exibir contagem de itens,,Afișează numărul de obiecte,Отображение количества предметов,Прикажи количину предмета,Öğe sayısını göster -Show stamina and accuracy,ALTHUDMNU_SHOWSTATS,,,,Zobrazit výdrž a přesnost,Vis udholdenhed og nøjagtighed,Zeige Kondition und Genauigkeit,,Montri viglecon kaj akuratecon,Mostrar resistencia/precisión,,Näytä puhti ja tarkkuus,Afficher Endurance et Précision,Állóképesség és pontosság mutatása,Mostra stamina e accuratezza,スタミナと精度の表示,스테미나와 정확도를 표시,Toon uithoudingsvermogen en nauwkeurigheid,Vis utholdenhet og nøyaktighet,Pokaż wytrzymałość i precyzję,Exibir resistência e precisão,,Afișează rezistența fizică si acuratețea,Отображение выносливости и точности,Прикажи издржљивост и прецизност,Dayanıklılık ve doğruluk gösterin -Show berserk,ALTHUDMNU_SHOWBERSERK,,,,Zobrazit berserk,Vis berserk,Zeige Berserk,,Montri frenezecon,Mostrar berserker,,Näytä raivo,Afficher Berserk,Berserk mutatása,Mostra il berserk,バーサーク表示,버서크 아이템을 표시,Toon berserk,Vis berserk,Pokaż szał,Exibir berserk,,Afișează pachetul de forță mărită,Отображение берсерка,Прикажи берсерк,Berserk'i göster -Show weapons,ALTHUDMNU_SHOWWEAPONS,,,,Zobrazit zbraně,Vis våben,Zeige Waffen,,Montri armojn,Mostrar armas,,Näytä aseet,Afficher Armes,Fegyverek mutatása,Mostra le armi,武器表示,무기들을 표시,Toon wapens,Vis våpen,Pokaż bronie,Exibir armas,,Afișează armele,Отображение оружия,Прикажи оружја,Silahları göster -Show ammo for,ALTHUDMNU_SHOWAMMO,,,,Zobrazit munici pro,Vis ammunition for,Zeige Munition,,Montri municion por,Mostrar munición para,,Näytä ammukset aseelle,Afficher Munitions pour,Ammo mutatása a,Mostra le munizioni per,弾薬等の表示,탄약을 표시,Toon munitie voor,Vis ammunisjon for,Pokaż amunicję dla,Exibir munição para,,Afișează muniția pentru,Отображение патронов для,Прикажи муниције за,Cephane göster -Show time,ALTHUDMNU_SHOWTIME,,,,Zobrazit čas,Vis tid,Zeige Zeit,,Montri tempon,Mostrar tiempo,,Näytä aika,Afficher temps niveau,Idő mutatása,Mostra il tempo,時間の表示,시간 표시,Toon tijd,Vis tid,Pokaż czas,Exibir tempo,,Afișează timpul,Отображение времени,Прикажи време,Gösteri zamanı -Time color,ALTHUDMNU_TIMECOLOR,,,Time colour,Barva času,Tidens farve,Zeit-Farbe,,Tempkoloro,Color del tiempo,,Ajan väri,Couleur du timer,Idő színe,Colore del tempo,時間の字色,시간 색상,Tijdskleur,Tid farge,Kolor czasu,Cor do tempo,,Culoare timp,Цвет времени,Боја времена,Zaman rengi -Show network latency,ALTHUDMNU_SHOWLAG,,,,Zobrazit latenci sitě,Vis netværksforsinkelse,Zeige Netzwerk-Latenz,,Montri reto-respondotempon,Mostrar latencia de red,,Näytä verkon viive,Afficher latence réseau,Válaszidő mutatása,Mostra la latenza del network,ネットのラグ表示,내트워크 트래픽 표시,Toon netwerklatentie,Vis nettverksforsinkelse,Pokaż czas oczekiwania sieci,Exibir latência de rede,,Afișează perioada de întârziere a conexiunii,Отображение задержки сети,Прикажи кашњење мреже,Ağ gecikmesini göster -Ammo display order,ALTHUDMNU_AMMOORDER,,,,Pořadí zobrazení munice,Visningsrækkefølge for ammunition,Munitionsreihenfolge,,Vidiga aranĝo de municio,Orden vista de munición,,Ammusten esitysjärjestys,Ordre d'affichage des munitions,Muníció típus rendezése,Ordine mostra delle munizioni,弾薬表示順,탄약 표시 순서,Volgorde van de munitieweergave,Rekkefølge for ammunisjonsvisning,Kolejność pokazywania amunicji,Ordem de exibição de munição,,Ordine afișare muniție,Порядок отображения боеприпасов,Редослед муниција,Cephane teşhir düzeni -Red ammo display below %,ALTHUDMNU_AMMORED,,,,Červený indikátor munice pod %,Rød ammunitionsvisning under %,Rot für Munition unter %,,Ruĝa municividigo sub %,Porcent. de munición en rojo,,Punaiset ammukset ammusten alittaessa %,Compteur de munitions rouge sous,Piros muníció szín % alatt,Contatore delle munizioni di colore rosso sotto,弾薬の赤色表示%,적색 남은 탄약 밑에 표시,Rood munitieweergave onder %,Rød visning av ammunisjonsnivå under %,Wyświetl czerwoną amunicję pod ,Porcentagem de munição em vermelho até,Percentagem de munição em vermelho até,Muniția schimbă culoarea în roșu sub %,"Отображение боеприпасов красным ниже, %",Прикажи муниције црвеном испод %,Aşağıda kırmızı cephane göstergesi % -Yellow ammo display below %,ALTHUDMNU_AMMOYELLOW,,,,Žlutý indikátor munice pod %,Gul ammunitionsvisning under %,Gelb für Munition unter %,,Flava municividigo sub %,Porcent. de munición en amarillo,,Keltaiset ammukset ammusten alittaessa %,Compteur de munitions jaune sous,Sárga muníció szín % alatt,Contatore delle munizioni di colore giallo sotto,弾薬の黄色表示%,황색 남은 탄약 밑에 표시,Gele munitieweergave onder %,Gult ammunisjonsdisplay under %.,Wyświetl żółtą amunicję pod ,Porcentagem de munição em amarelo até,Percentagem de munição em amarelo até,Muniția schimbă culoarea în galben sub %,"Отображение боеприпасов жёлтым ниже, %",Прикажи муниције жутом испод %,Aşağıda sarı cephane göstergesi % -Red health display below,ALTHUDMNU_HEALTHRED,,,,Červený indikátor zdraví pod,Rødt sundhedsindikator under %,Rot für Gesundheit unter %,,Ruĝa sanvidigo sube,Porcent. de salud en rojo,,Punainen terveys terveyden alittaessa,Compteur de santé rouge sous,Piros életerő szín ezen szám alatt,Contatore della salute di colore rosso sotto,体力の赤色表示%,적색 체력 밑에 표시,Rood gezondheidsweergave beneden,Rød helsevisning under,Wyświetl czerwone zdrowie pod ,Porcentagem de saúde em vermelho até,Percentagem de saúde em vermelho até,Sănătatea schimbă culoarea în roșu sub %,"Отображение здоровья красным ниже, %",Прикажи здравље црвеном испод,Aşağıdaki kırmızı sağlık göstergesi -Yellow health display below,ALTHUDMNU_HEALTHYELLOW,,,,Žlutý indikátor zdraví pod,Gul sundhedsindikator under %,Gelb für Gesundheit unter %,,Flava sanvidigo sube,Porcent. de salud en amarillo,,Keltainen terveys terveyden alittaessa,Compteur de santé jaune sous,Sárga életerő szín ezen szám alatt,Contatore della salute di colore giallo sotto,体力の黄色表示%,황색 체력 밑에 표시,Geel gezondheidsweergave beneden,Gul helsevisning nedenfor,Wyświetl żółte zdrowie pod ,Porcentagem de saúde em amarelo até,Percentagem de saúde em amarelo até,Sănătatea schimbă culoarea în galben sub %,"Отображение здоровья жёлтым ниже, %",Прикажи здравље жутом испод,Aşağıdaki sarı sağlık göstergesi -Green health display below,ALTHUDMNU_HEALTHGREEN,,,,Zelený indikátor zdraví pod,Grønt sundhedsindikator under %,Grün für Gesundheit unter %,,Verda sanvidigo sube,Porcent. de salud en verde,,Vihreä terveys terveyden alittaessa,Compteur de santé vert sous,Zöld életerő szín ezen szám alatt,Contatore della salute di colore verde sotto,体力の緑色表示%,녹색 체력 밑에 표시,Groen gezondheidsweergave beneden,Grønn helsevisning under,Wyświetl zielone zdrowie pod ,Porcentagem de saúde em verde até,Percentagem de saúde em verde até,Sănătatea schimbă culoarea în verde sub %,"Отображение здоровья зелёным ниже, %",Прикажи здравље зеленом испод,Aşağıdaki yeşil sağlık göstergesi -Red armor display below,ALTHUDMNU_ARMORRED,,,Red armour display below,Červený indikátor brnění pod,Rødt panser display under %,Rot für Panzerung unter %,,Ruĝa kirasvidigo sube,Porcent. de blindaje en rojo,,Punainen panssari panssarin alittaessa,Compteur d' armure rouge sous,Piros páncél szín ezen szám alatt,Contatore dell'armatura di colore rosso sotto,防具の赤色表示%,적색 아머 밑에 표시,Rood pantserweergave beneden,Visning av rød rustning under,Wyświetl czerwony pancerz pod ,Porcentagem de armadura em vermelho até,Percentagem de armadura em vermelho até,Armura schimbă culoarea în galben sub %,"Отображение брони красным ниже, %",Прикажи оклоп црвеном испод,Kırmızı zırh ekranı aşağıda -Yellow armor display below,ALTHUDMNU_ARMORYELLOW,,,Yellow armour display below,Žlutý indikátor brnění pod,gul panser under displayet under %,Gelb für Panzerung unter %,,Flava kirasvidigo sube,Porcent. de blindaje en amarillo,,Keltainen panssari panssarin alittaessa,Compteur d' armure jaune sous,Sárga páncél szín ezen szám alatt,Contatore dell'armatura di colore giallo sotto,防具の黄色表示%,황색 아머 밑에 표시,Geel pantserweergave beneden,Visning av gul rustning under,Wyświetl żółty pancerz pod ,Porcentagem de armadura em amarelo até,Percentagem de armadura em amarelo até,Armura schimbă culoarea în galben sub %,"Отображение брони жёлтым ниже, %",Прикажи оклоп жутом испод,Aşağıdaki sarı zırh ekranı -Green armor display below,ALTHUDMNU_ARMORGREEN,,,Green armour display below,Zelený indikátor brnění pod,grønt panser display under %,Grün für Panzerung unter %,,Verda kirasvidigo sube,Porcent. de blindaje en verde,,Vihreä panssari panssarin alittaessa,Compteur d' armure bleu sous,Zöld páncél szín ezen szám alatt,Contatore dell'armatura di colore verde sotto,防具の緑色表示%,녹색 아머 밑에 표시,Groen pantserweergave beneden,Visning av grønn rustning under,Wyświetl zielony pancerz pod ,Porcentagem de armadura em verde até,Percentagem de armadura em verde até,Armura schimbă culoarea în verde sub %,"Отображение брони зелёным ниже, %",Прикажи оклоп зеленом испод,Aşağıdaki yeşil zırh ekranı -Alternative Automap HUD,ALTHUDMNU_AUTOMAPHUD,,,,Alternativní HUD automapy,Alternativ Automap HUD,Alternatives Automap HUD,,Alternativa HUD de Aŭtomapo,HUD alternativo del automapa,,Vaihtoehtoinen automaattikartan tilanäyttö,ATH Alternatif pour carte,Alternatív Automap HUD,HUD automappa alternativo,オルタナティブ オートマップHUD,대체 오토맵 HUD,Alternatieve Automap HUD,Alternativ Automap HUD,Alternatywny HUD mapy,HUD alternativo de automapa,,Hartă Computerizată Alternativă,Альтернативный интерфейс на автокарте,Алтернативни HUD за аутомапу,Alternatif Automap HUD -Map title color,ALTHUDMNU_TITLECOLOR,,,Map title colour,Barva názvu levelu,Farve på korttitel,Farbe für Levelnamen,,Maptitolo-koloro,Color del título del mapa,,Tason nimen väri,Couleur titre du niveau,Pálya cím szín,Colore titolo mappa,マップ名の色,맵 제목 색깔,Kleur kaarttitel,Farge på karttittel,Kolor nazwy mapy,Cor do título do fase,Cor do título do nível,Culoare titlu hartă,Цвет названия уровня,Боја назива нивоа,Harita başlık rengi -Map time color,ALTHUDMNU_MAPTIMECOLOR,,,Map time colour,Barva času levelu,Farve på kortets tid,Farbe für Level-Zeit,,Maptempo-koloro,Color del tiempo del mapa,,Tason ajan väri,Couleur temps du niveau,Pálya idő szín,Colore tempo mappa,経過時間の色,맵 시간 색깔,Kleur kaarttijd,Kartets tidsfarge,Kolor czasu na mapie,Cor do tempo da fase,Cor do tempo do nível,Culoare timp petrecut pe hartă,Цвет времени для уровней,Боја времена на нивоу,Harita zaman rengi -Hub time color,ALTHUDMNU_HUBTIMECOLOR,,,Hub time colour,Barva času hubu,Farve på hub-tid,Farbe für Hub-Zeit,,Nabtempo-koloro,Color del tiempo del nodo,,Tasokokoelman ajan väri,Couleur temps du hub,Csomópont idő szín,Colore tempo hub di mappe,区間経過時間の色,허브 시간 색깔,Kleur hubtijd,Farge for knutepunkttid,Kolor czasu w hubie,Cor do tempo no HUD,,Culoare timp petrecut în hub,Цвет времени для хабов,Боја времена на хабу,Hub zaman rengi -Total time color,ALTHUDMNU_TOTALTIMECOLOR,,,Total time colour,Barva celkového času,Farve for samlet tid,Farbe für Gesamtzeit,,Tuttempo-koloro,Color del tiempo total,,Kokonaisajan väri,Couleur temps total,Teljes idő szín,Colore tempo totale,合計経過時間の色,누적 경과한 시간 색깔,Kleur totale tijd,Farge for total tid,Kolor całkowitego czasu,Cor do tempo total,,Culoare timp total,Цвет общего времени,Боја укупног времена,Toplam zaman rengi -Coordinate color,ALTHUDMNU_COORDINATECOLOR,,,Coordinate colour,Barva souřadnic,Koordinat farve,Farbe für Koordinaten,,Kunordigi koloron,Color de coordenadas,,Koordinaattien väri,Couleur coordonnées,Koordináló szín,Colore coordinate,座標色,좌표 색깔,Kleur coördinaten,Koordinatfarge,Skoordynuj kolor,Cor das coordenadas,,Culoare coordonate,Цвет координат,Боја координата,Koordinat rengi -Coordinate mode,ALTHUDMNU_COORDINATEMODE,,,,Režim souřadnic,Koordinattilstand,Koordinatenmodus,,Kunordigi modon,Modo de coordenadas,,Koordinaattitila,Mode coordonnées,Koordináló mód,Modalità coordinate,座標モード,좌표 모드,Coördinatiemodus,Koordinat-modus,Skoordynuj tryb,Modo de coordenada,,Mod coordonate,Координаты игрока,Мод координата,Koordinat modu -Statistics name color,ALTHUDMNU_STATSNAMECOLOR,,,Statistics name colour,Barva názvu statistik,Farve på statistiknavn,Farbe für Statistik-Namen,,Statistiknomo-koloro,Color del nombre de estadísticas,,Tilastotiedon nimen väri,Couleur nom des statistiques,Statisztika név szín,Colore nome statistica,統計名の色,통계표 이름 색상,Kleur statistiekennaam,Farge på statistikknavn,Kolor nazw statystyk,Cor do nome das estatísticas,,Culoare nume statistici,Цвет имён в статистике,Боја назива статистика,İstatistik adı renk -Statistics color,ALTHUDMNU_STATSCOLOR,,,Statistics colour,Barva statistik,Statistik farve,Farbe für Statistik-Nummern,,Statistiko-koloro,Color de las estadísticas,,Tilastotiedon väri,Couleur statistiques,Statisztika szín,Colore contatore statistica,統計の色,통계표 색상,Kleur statistieken,Statistikk farge,Kolor statystyk,Cor das estatísticas,,Culoare statistici,Цвет статистики,Боја статистика,İstatistik renk -,,Display (game related),,,,,,,,,,,,,,,,,,,,,,,, -Rendering Interpolation,DSPLYMNU_CAPFPS,,,,Interpolace vykreslování,Interpolering af rendering,Renderinterpolation,,Bildigo-Interpolado,Interpolación de renderizado,,Hahmonnuksen interpolointi,Interpolation du rendu,Render animáció simítás,Interpolazione grafica,レンダリング補間,프레임 제한,Interpolatie renderen,Gjengivelse av interpolasjon,Interpolacja Renderowania,Interpolação de renderização,,Interpolare Imagine,Сглаживание рендеринга,Интерполација рендеринга,Rendering Enterpolasyonu -Transparency render mode,DSPLYMNU_BLENDMETHOD,,,,Režim vykreslování průhlednosti,Gennemsigtighedstilstand,Transparenzmodus,,Travidebleco-bildigo-reĝimo,Modo de renderizado de transparencia,,Läpinäkyvyyden hahmonnustila,Mode de Rendu transparence,Átlászóság render mód,Modalità della resa grafica della trasparenza,レンダリング透過モード,투명도 표시 모드,Transparantie render modus,Gjengivelsesmodus for gjennomsiktighet,Tryb renderowania przezroczystości,Modo de renderiz. de transparência,,Mod Transparență,Режим отрисовки прозрачности,Режим рендеринга транспарентности,Şeffaflık render modu -Screen wipe style,DSPLYMNU_WIPETYPE,,,,Styl přechodů,Skærmens aftørringsstil,Bildschirmwechseleffekt,,Stilo de ekranviŝo,Transición de pantalla,,Ruudun pyyhkiytymistyyli,Style de Fondu d'écran,Képernyőtörlődés módja,Stile della pulizia dello schermo,スクリーンワイプモード,화면 전환 방식,Schermveegstijl,Stil for skjermtørking,Styl przejścia ekranu,Tipo de transição de tela,Tipo de transição de ecrã,Stil ștergere imagine,Эффект плавной смены экранов,Ефект брисања екрана,Ekran silme stili -Show ENDOOM screen,DSPLYMNU_SHOWENDOOM,,,,Zobrazit ENDOOM obrazovku,Vis ENDOOM-skærm,Zeige ENDOOM,,Montri ENDOOM-ekranon,Mostrar pantalla ENDOOM,,Näytä ENDOOM-ruutu,Montrer la fenêtre ENDOOM,ENDOOM képernyő mutatása,Mostra la schermata ENDOOM,ENDOOM画面を表示,종료화면 표시,Toon ENDOOM scherm,Vis ENDOOM-skjerm,Pokaż ekran ENDOOM,Exibir tela ENDOOM,,Afișare fereastră ENDOOM,Показать экран ENDOOM,Прикажи ENDOOM екран,ENDOOM ekranını göster -Blood Flash Intensity,DSPLYMNU_BLOODFADE,,,,Intenzita bliknutí při zranění,Blodblinkintensitet,Intensität für Bluteffekt,,Egeco de sango-ekbrilo,Intensidad del destello al ser atacado,,Verivälähdyksen voimakkuus,Intensité du flash dommages,Sebzéskor villanás mértéke,Intensità Bagliore Sangue,血粉の濃度,피격 표시 강도,Intensiteit van de bloedflitser,Intensitet for blodblits,Intensywność Efektów Krwi,Intensidade de Flash de Sangue,,Intensitate strălucire sânge,Интенсивность вспышки при ранении,Интензивност треперења током повређивања,Kan Flaş Yoğunluğu -Pickup Flash Intensity,DSPLYMNU_PICKUPFADE,,,,Intenzita bliknutí při sebrání předmětu,Intensitet for optageeffekt,Intensität für Aufnehmen-Effekt,,Egeco de prenado-ekbrilo,Intensidad del destello al coger algo,Intensidad del destello al tomar un objeto,Poimintavälähdyksen voimakkuus,Intensité du flash objets,Fegyver felvételekor villanás mértéke,Intensità Bagliore Raccolta,取得の視界色濃度,습득 표시 강도,Intensiteit van de oppakflitser,Intensitet av opptaksblits,Intesnywność Efektów Podnoszenia Przedmiotów,Intensidade de Flash ao Pegar Itens,,Intensitate strălucire la ridicarea obiectelor,Интенсивность вспышки при подборе,Интензивност треперења током купљења,Pikap Flaş Yoğunluğu -Underwater Blend Intensity,DSPLYMNU_WATERFADE,,,,Intenzita zbarvení pod vodou,Undervandsblinkintensitet,Intensität für Unterwasser-Effekt,,Egeco de Subakva Mikso,Intensidad Color Sumergido,Intensidad Color Submarino,Vedenalaissumennuksen voimakkuus,Intensité du fondu sous l'eau,Vízalatti keverődés mértéke,Intensità Blend sott'acqua,水中反響音の濃度,수중 효과 강도,Intensiteit kleurvermenging onder water,Intensitet for undervannsblanding,Intensywność Efektów Pod Wodą,Intensidade de Efeito Debaixo d'Água,Intensidade de Efeito Debaixo de Água,Intensitate amestec culori subacvatice,Интенсивность эффекта под водой,Интензивност подводног треперења,Sualtı Karışım Yoğunluğu -Sky render mode,DSPLYMNU_SKYMODE,,,,Režim vykreslování oblohy,Himmel-renderingstilstand,Rendermodus für Himmel,,Ĉielo-bildigo-reĝimo,Modo de renderizado del cielo,,Taivaan hahmonnustila,Mode du rendu du Ciel,Égbolt render mód,Modalità resa grafica del cielo,空の表示方法,하늘 표시 모드,Luchtrendermodus,Modus for gjengivelse av himmel,Tryb renderowania nieba,Modo de renderização de céu,,Mod de vizualizare al cerului,Режим отрисовки неба,Режим рендеринга неба,Gökyüzü oluşturma modu -Linear skies,DSPLYMNU_LINEARSKY,,,,Lineární obloha,Lineære himmelstrøg,Lineare Himmel,,Linearaj ĉieloj,Cielo lineal,,Lineaariset taivaat,Ciel linéaire,Lineáris égboltok,Cieli lineari,空の歪み,선형 하늘,Lineaire lucht,Lineær himmel,Liniowe niebo,Céus lineares,,Cer rectiliniu,Линейное небо,Линеарна неба,Doğrusal gökyüzü -Fullbright overrides sector color,DSPLYMNU_GZDFULLBRIGHT,,,,Při plném jasu ignorovat barvu sektoru,Ignorer sektorfarve ved fuld lysstyrke,Ignoriere Sektorfarbe bei voller Helligkeit,,Plenbrileco tranpasas sektorkoloron,Brillo máximo anula color del sector,,Täyskirkkaat ohittavat sektorin värin,Fullbright ignore couleur secteur,Fullbright felülírja a szektor szinét,Luce piena sovrappone il colore del settore,明るさ最大時にsector color塗り替え,섹터 색상 최대밝기 우선화,Volledig helderheid overschrijft de sectorkleur,Fullbright overstyrer sektorfarge,Ignoruj kolor sektora przy pełnej jasności,Brilho máximo anula cor de setor,,Luminozitatea maximă suprascrie culoarea sectorului,Полная яркость замещает цвет сектора,Пуно осветљење премошћује боју сектора,Fullbright sektör rengini geçersiz kılar -Scale fuzz effect,DSPLYMNU_SCALEFUZZ,,,,Škálovat velikost fuzz efektu,Skala fuzz-effekt,Skaliere Fuzz-Effekt,,Skali barblano-efekton,Escala de efecto fuzz,,Skaalaa sumennustehostetta,Scaling de l'effet de bruit,Homályosodás effekt átméretezése,Scala l'effetto di fuzz,ファズエフェクトサイズ,반투명 효과 조정,Schaal fuzz effect,Skala fuzz-effekt,Skalowanie efektu szumu,Escala de efeito difuso,,Putere efect de strălucire,Масштабировать эффект шума,Повечавај шумни ефект,Ölçekli fuzz efekti -Use fuzz effect,DSPLYMNU_DRAWFUZZ,,,,Typ fuzz efektu,Brug fuzz-effekt,Benutze Fuzz-Effekt,,Uzi barblano-efekton,Usar efecto fuzz,,Käytä sumennustehostetta,Effet de bruit,Homályosodás effekt használata,Usa l'effetto di fuzz,ファズエフェクトを使用,반투명 효과 사용,Gebruik fuzz effect,Bruk fuzz-effekt,Użyj efektu szumu,Usar efeito difuso,,Mod efect de strălucire,Использовать эффект шума,Користи шумни ефект,Fuzz efekti kullanın -Classic Transparency,DSPLYMNU_OLDTRANS,,,,Klasická průhlednost,Klassisk gennemsigtighed,Klasssische Transparenz,,Klasika Travidebleco,Transp. Clásicas,,Perinteinen läpinäkyvyys,Transparence classique,Klasszikus átlátszóság,Trasparenza classica,旧式の透明度,구형 투명도,Klassieke transparantie,Klassisk gjennomsiktighet,Klasyczna Przezroczystość,Transparência Clássica,,Transparență Clasică,Классическая прозрачность,Класична транспарентност,Klasik Şeffaflık -Lost Soul translucency,DSPLYMNU_TRANSSOUL,,,,Průhlednost Ztracených duší,Fortabt sjæl-translucens,Transparenz für Verlorene Seelen,,Diafaneco de Perdita Animo,Transp. del alma perdida,,Kadonneiden sielujen läpikuultavuus,Transparence des âmes perdues,Lost soul átlátszóság,Trasparenza anima errante,ロストソウルの透明度,로스트 소울 반투명도,Verloren Ziel doorschijnendheid,Lost Soul gjennomskinnelighet,Przezroczystość Zagubionych Dusz,Translucência da Alma Perdida,Translucidez da Alma Penada,Transparență Suflete Pierdute,Прозрачность потерянных душ,Транспарентност изгубљених душа,Kayıp Ruh yarı saydamlığı -Use fake contrast,DSPLYMNU_FAKECONTRAST,,,,Použít falešný kontrast,Brug falsk kontrast,Benutze falschen Kontrast,,Uzi malveran kontraston,Usar falso contraste,,Käytä tekosävykkyyttä,Faux Contraste,Hamis kontraszt használata,Usa il falso contrasto,フェイクコントラストを使用,가명암 효과 사용,Gebruik vals contrast,Bruk falsk kontrast,Użyj sztuczny kontrast,Usar contraste falso,,Utilizare contrast fals,Имитация контрастного освещения стен,Користи фејк-контраст,Sahte kontrast kullanın -Rocket Trails,DSPLYMNU_ROCKETTRAILS,,,,Kouř raket,Raketspor,Raketenschweife,,Raketospuroj,Rastro de cohetes,,Rakettivanat,Trainées des Roquettes,Rakéta füstnyomok,Scia del razzo,ロケットの軌跡,로켓 추진 효과,Raketsporen,Rakettspor,Wiązki Rakiet,Rastro de Foguete,Rasto dos Mísseis,Dâră Rachete,Дымовой след у ракет,Траг дима код ракета,Roket Parkurları -Blood Type,DSPLYMNU_BLOODTYPE,,,,Druh krve,Blodtype,Blut-Typ,,Sangotipo,Tipo de sangre,,Verityyli,Type de particules Sang,Vér fajta,Tipo di sangue,血の種類,혈흔 효과,Bloedtype,Blodtype,Typ Krwi,Tipo de Sangue,,Tip efecte sângeroase,Тип крови,Тип крви,Kan Grubu -Bullet Puff Type,DSPLYMNU_PUFFTYPE,,,,Druh kouře nábojů,Kuglestød type,Pistolenrauch-Typ,,Tipo de Kuglopufo,Tipo de agujero de bala,,Luotien pöllähdystyyli,Type de particules Balles,Lövedék becsapódás fajtája,Tipo di sbuffo del proiettile,弾煙の種類,탄알 피격 효과,Kogelwolvertype,Bullet Puff Type,Typ Dymu,Tipo de Ricochete de Bala,,Tip efecte pentru gloanțe,Тип дыма от пуль,Тип рикошета,Mermi Puf Tipi -Number of particles,DSPLYMNU_MAXPARTICLES,,,,Množství částic,Antal partikler,Anzahl Partikel,,Nombro da partikloj,Número de partículas,,Hiukkasten lukumäärä,Nombre de particules,Részecskék száma,Numero di particelle,パーティクルの最大数,최대 입자 수,Aantal deeltjes,Antall partikler,Liczba cząsteczek,Número de partículas,,Număr particule,Количество частиц,Број честица,Parçacık sayısı -Number of decals,DSPLYMNU_MAXDECALS,,,,Množství decalů,Antal decals,Anzahl Trefferspuren,,Nombro da dekaloj,Número de calcomanías,,Siirtokuvien lukumäärä,Number de décalques,Lövésnyomok száma,Numero di decal,デカールの最大数,최대 데칼 수,Aantal stickers,Antall dekaler,Liczba kalk,Número de decalques,,Număr autocolante,Количество декалей,Број декала,Çıkartma sayısı -Show player sprites,DSPLYMNU_PLAYERSPRITES,,,,Zobrazit hráčovy sprity,Vis spiller sprites,Zeige Spieler-Sprites,,Montri ludantspritojn,Mostrar sprites del jugador,,Näytä pelaajaspritet,Montrer les sprites joueur,Játékos sprite-ok mutatása,Mostra gli sprite del giocatore,プレイヤーの武器の表示,1인칭 무기 표시,Toon speler sprites,Vis spillerens sprites,Pokaż sprite'y gracza,Exibir sprites do jogador,,Afișare arme,Отображение спрайтов игрока,Прикажи спрајтове играча,Oyuncu sprite'larını göster -Death camera,DSPLYMNU_DEATHCAM,,,,Posmrtná kamera,Dødskamera,Todeskamera,,Mortkamerao,Cámara de muerte,,Kuolonkamera,Caméra 3ème pers à la mort,Halál kamera,Telecamera all'atto della morte,死亡時の三人称視点,사망 화면 표시,Doodscamera,Dødskamera,Kamera śmierci,Câmera de morte,Câmara da morte,Cameră de Deces,Вид от 3-го лица при смерти,Смртна камера,Ölüm kamerası -Teleporter zoom,DSPLYMNU_TELEZOOM,,,,Zoom při teleportaci,Teleporter zoom,Teleporter Zoom,,Teleportila zomo,Zoom en teletransp.,,Kaukosiirrynnän kameran zoomaus ,Zoom sur téléportation,Teleporter ráközelítés,Zoom telecamera,テレポーター使用時のズーム,순간이동 효과,Teleporter zoom,Teleporter zoom,Przybliżenie teleportowania,Zoom de teletransporte,,Apropriere Cameră la Teleportare,Увеличение при телепортации,Зум током телепортације,Işınlayıcı yakınlaştırma -Earthquake shake intensity,DSPLYMNU_QUAKEINTENSITY,,,,Intenzita zemětřesení,Intensitet af jordskælv,Erdbeben Intensität,,Egeco de tertremo,Intensidad del terremoto,,Maanjäristystehosteen voimakkuus,Intensité des séismes,Földrengés erőssége,Intensità vibrazione terremoto,地震エフェクトの激しさ,지진 효과 강도,Aardbevingsschoksintensiteit,Intensitet av jordskjelvrystelser,Siła trzęsienia ziemi,Intensidade do tremor de terremoto,,Intensitate zguduire la cutremur,Интенсивность тряски землетрясений,Интенсивност земљотреса,Deprem sarsıntı şiddeti -Interpolate monster movement,DSPLYMNU_NOMONSTERINTERPOLATION,,,,Interpolovat pohyb příšer,Interpolere monsterbevægelse,Interpoliere Monsterbewegung,,Interpoli monstro-movadon,Interpolar mov. de los monstruos,,Interpoloi hirviöiden liike,Interpolation des monstres,Szörny mozgás simítása,Interpola il movimento dei mostri,モンスターの移動補間,개체 이동 보정,Interpoleer monsterbewegingen,Interpolere monsterbevegelse,Interpolacja ruchu potworów,Interpolar movimento de monstros,,Interpolare mișcare monștri (efect vizual),Сглаживание движения монстров,Интерполирај кретање чудовишта,Canavar hareketini enterpole et -Menu dim,DSPLYMNU_MENUDIM,,,,Síla barvy pozadí v menu,Menu dæmpes,Menüabdunklung,,Menuo-malheleco,Atenuación del menú,,Valikon himmennys,Assombrissement menu,Menü homályosítása,Offuscamento menu,メニュー背景,메뉴 배경색 강도,Donkere menuachtergrond,Demp meny,Mgła w menu,Atenuação do menu,,Întunecare meniu,Затемнение фона меню,Пригушивање менија,Menü loş -Dim color,DSPLYMNU_DIMCOLOR,,,Dim colour,Barva pozadí v menu,Dim farve,Abdunklungsfarbe,,Malheleca koloro,Color de la atenuación,,Himmennysväri,Couleur de l'assombrissement,Homályosítás színe,Colore offuscamento,背景色,배경색 설정,Donkere kleur,Demp farge,Kolor mgły,Cor da atenuação,,Culoare întunecare,Цвет затемнения,Боја пригушивања,Loş renk -View bob amount while moving,DSPLYMNU_MOVEBOB,,,,Pohupování pohledu při pohybu,Vis bob-beløb under bevægelse,Waffenpendeln beim Bewegen,,Vidi kvanton de kapo-balanciĝo dum movado,Cantidad de balanceo al moverse,,Aseen heilumisvoimakkuus liikkeessä,Chaloupage arme en movement,Fegyver mozgása lépés közben,Ammontare di bob di movimento,視点揺れする移動値,이동 시 화면 흔들림 강도,Bekijk bob bedrag terwijl je beweegt,Vis bob-beløp mens du beveger deg,Dygaj kiedy się ruszasz,Quantidade de balanço durante movimento,,Mișcare cameră în timpul deplasării,Покачивание камеры при движении,Тресење камере током кретања,Hareket halindeyken bob miktarını görüntüleme -View bob amount while not moving,DSPLYMNU_STILLBOB,,,,Pohupování pohledu v klidu,"Vis bob-beløbet, mens du ikke bevæger dig",Waffenpendeln bei Nichtbewegen,,Vidi kvanton de kapo-balanciĝo dum ne movado,Cantidad de balanceo al no moverse,,Aseen heilumisvoimakkuus levossa,Chaloupage arme statique,Fegyver mozgása egy helyben,Ammontare di bob di movimento da fermo,視点揺れしない移動値,정지 시 화면 움직임 강도,Bekijk bob bedrag terwijl je niet beweegt,Vis bobmengde mens du ikke beveger deg,Dygaj kiedy się nie ruszasz,Quantidade de balanço parado,,Mișcare cameră în timpul staționării,Покачивание камеры при бездействии,Тресење камере током неактивности,Hareket etmiyorken bob miktarını görüntüleme -Weapon bob speed,DSPLYMNU_BOBSPEED,,,,Rychlost pohupování zbraně,Våben bob hastighed,Waffenpendelgeschwindigkeit,,Rapido de armilo-balanciĝo,Velocidad de balanceo de Arma,,Aseen heilumisnopeus,Vitesse du chaloupage,Fegyver mozgás sebesség,Velocità di bob dell'arma,武器揺れ速度,무기 흔들림 속도,Snelheid wapenzwaaieffect,Våpen bob hastighet,Szybkość ruchu broni,Velocidade de balanço de arma,,Viteză mișcare arme,Скорость покачивания оружия,Брзина трсења оружја,Silah bob hızı -,,Scaling,,,,,,,,,,,,,,,,,,,,,,,, -Scaling Options,SCALEMNU_TITLE,,,,Nastavení škálování rozhraní,Indstillinger for skalering,Skalierungsoptionen,,Skalo-Agordoj,Opciones de escalado,,Skaalausasetukset,Option de mise à l'échelle,Méretezési Beállítások,Opzioni di scala,スケーリング オプション,배율 설정,Schaalopties,Alternativer for skalering,Opcje skalowania,Opções de Escala,,Setări Dimensiuni,Настройки масштабирования,Подешавања размере,Ölçeklendirme Seçenekleri -Overrides for above setting,SCALEMNU_OVERRIDE,,,,Potlačení nastavení výše,Overrides for ovenstående indstilling,Spezialisierungen,,Transpasoj por ĉi-supre agordo,Anular ajuste anterior,,Ohittaa asetuksen ylhäällä,Annule les paramètres au dessus,Beállítások felülírása,Sovrascritture per i settaggi sopra,設定の上書き,위 설정을 위해 무시,Overschrijdingen voor bovenstaande instelling,Overstyrer for innstillingen ovenfor,Nadpisuje dla powyższego ustawienia,Anular configurações acima,,Suprascriere pentru setările de mai sus,Задать специальные настройки,Специјална подешавања,Yukarıdaki ayar için geçersiz kılmalar -Messages,SCALEMNU_MESSAGES,,,,Oznámení,Meddelelser,Nachrichten,,Mesaĝoj,Mensajes,,Viestit,Messages,Üzenetek,Messaggi,メッセージ類,메시지,Berichten,Meldinger,Wiadomości,Mensagens,,Mesaje,Сообщения,Поруке,Mesajlar -Console,SCALEMNU_CONSOLE,,,,Konzole,Konsol,Konsole,,Konzolo,Consola,,Konsoli,Console,Konzol,Console,コンソール,콘솔,Console,Konsoll,Konsola,Console,Consola,Consolă,Консоль,Конзола,Konsol -Status bar,SCALEMNU_STATBAR,,,,Stavový panel,Statuslinje,Statusleiste,,Stata baro,Barra de estado,,Tilapalkki,Barre d'état,Státusz sáv,Barra di stato,ステータスバー,상태 바,Statusbalk,Statuslinje,Pasek statusu,Barra de status,Barra de estado,Bară de Stare,Строка состояния,Статусна трака,Durum çubuğu -Fullscreen HUD,SCALEMNU_HUD,,,,HUD přes celou obrazovku,HUD i fuld skærm,Vollbild-HUD,,Tutekrana HUD,HUD de pantalla completa,,Täyden ruudun tilanäyttö,ATH plein écran,Teljes képernyős HUD,HUD a pieno schermo,全画面HUD,전체화면 HUD,Volle scherm HUD,HUD i fullskjerm,HUD pełnoekranowy,HUD de tela cheia,HUD de ecrã cheio,Interfață pe Timp de Joc tip Fullscreen,Полноэкранный интерфейс,HUD преко целог екрана,Tam Ekran HUD -Alternative HUD,SCALEMNU_ALTHUD,,,,Alternativní HUD,Alternativ HUD,Alternatives HUD,,Alternativa HUD,HUD alternativo,,Vaihtoehtoinen tilanäyttö,ATH alternatif,Alternatív HUD,HUD alternativo,オルタナティブHUD,대체 HUD,Alternatieve HUD,Alternativ HUD,Alternatywny HUD,HUD alternativo,,Interfață pe Timp de Joc Alternativă,Альтернативный интерфейс,Алтернативни HUD,Alternatif HUD -HUD preserves aspect ratio,SCALEMNU_HUDASPECT,,,,HUD zachovává poměr stran,HUD bevarer formatforholdet,HUD bewahrt Seitenverhältnisse,,HUD konservas aspekto-proporcion,HUD conserva la rel. de aspecto,,Tilanäyttö säilyttää kuvasuhteen,ATH préserve le rapport d'aspect,A HUD képarány visszaállítása,HUD preserva le proporzioni,HUDのアスペクト比維持,HUD 화면 비율 보존,HUD behoudt de beeldverhouding,HUD bevarer størrelsesforholdet,HUD zachowuje współczynnik proporcji,HUD deve preservar proporções,,Interfața pe Timp de Joc își Păstrează Aspectul,Сохранение соотношения сторон интерфейса,Сачувај пропорције HUD-а,HUD en boy oranını korur -Use default scale,SCALEMNU_USEUI,,,,Použít výchozí velikost,Brug standardskala,Benutze Standardskalierung,,Uzi defaŭltskalon,Usar escalado por defecto,,Käytä oletusmittakaavaa,Défaut,Alap arányok használata,Usa la scala di default,通常サイズを使う,기본 배율 사용,Gebruik standaardweegschaal,Bruk standard skala,Użyj domyślnej skali,Usar escala padrão,,Folosește dimensiunea implicită,Размер по умолчанию,Уобичајена размера,Varsayılan ölçeği kullan -Scale to fullscreen,SCALEMNU_USEFS,,,,Škalovat přes celou obrazovku,Skaleres til fuld skærm,Skaliere auf Vollbild,,Skali al tutekrano,Escalar a pant. completa,,Skaalaa täyteen ruutuun,Plein écran,Teljes képernyőre arányítás,Scala a pieno schermo,全画面に拡大,전체화면에 맞게 축척,Schaalbaar tot volledig scherm,Skaler til fullskjerm,Przeskaluj do pełnego ekranu,Escala de tela cheia,Escalar para ecrã cheio,Dimensionare la modul Fullscreen,Масштабировать со всем экраном,Проширење преко целог екрана,Tam ekrana ölçeklendir -Adapt to screen size,SCALEMNU_ADAPT,,,,Přizpůsobit velikosti obrazovky,Tilpasning til skærmstørrelse,Passe an Bildschirmgröße an,,Adapti al ekranamplekso,Adaptar al tamaño de pantalla,,Sovita näytön kokoon,Ecran,Képernyő mérethez alkalmazkodik,Adatta alla dimensione della schermata,画面サイズに合わせる,화면 사이즈에 맞게 축척,Aanpassen aan de grootte van het scherm,Tilpass til skjermstørrelse,Dostosuj do pełnego ekranu,Adaptar ao tamanho de tela,,Adaptează la dimensiunea ecranului,Адаптироваться к размеру экрана,Прилагоди размери екрана,Ekran boyutuna uyum sağlayın -,,HUD,,,,,,,,,,,,,,,,,,,,,,,, -HUD Options,HUDMNU_TITLE,,,,Nastavení rozhraní a HUD,HUD-indstillinger,HUD Optionen,,HUD Agordoj,Opciones del HUD,,Tilanäytön asetukset,Options ATH,HUD beállításai,Opzioni HUD,HUDオプション,HUD 설정,HUD-opties,HUD-alternativer,Opcje HUD,Opções de HUD,,Setări Interfață pe Timp de Joc,Настройки отображения информации,HUD подешавања,HUD Seçenekleri -Alternative HUD,HUDMNU_ALTHUD,,,,Alternativní HUD,Alternativ HUD,Alternatives HUD,,Alternativa HUD,HUD alternativo,,Vaihtoehtoinen tilanäyttö,ATH Alternatif,Alternatív HUD,HUD alternativo,オルタナティブHUD,대체 HUD,Alternatieve HUD,Alternativ HUD,Alternatywny HUD,HUD Alternativo,,Interfață pe Timp de Joc Alternativă,Альтернативное отображение информации,Алтернативни HUD,Alternatif HUD -Message Options,HUDMNU_MESSAGE,,,,Oznámení,Indstillinger for meddelelser,Nachrichtenoptionen,,Mesaĝo-Agordoj,Opciones de mensajes,,Viestiasetukset,Options des Messages,Üzenet beállítások,Opzioni messaggi,メッセージの設定,메시지 설정,Berichtopties,Meldingsalternativer,Opcje wiadomości,Opções de Mensagem,,Setări Mesaje,Настройки сообщений,Подешавања порука,Mesaj Seçenekleri -User interface scale,HUDMNU_UISCALE,,,,Velikost rozhraní,Skala for brugergrænseflade,Benutzerinterfaceskalierung,,Interfaco-skalo de uzanto,Escala de la interfaz de usuario,,Käyttöliittymän skaalaus,Echelle de l'interface,Felhasználó Panel mérete,Scala l'interfaccia utente,インターフェースの大きさ,인터페이스 크기 조정,Schaal gebruikersinterface,Skalering av brukergrensesnitt,Skala interfejsu,Escala de interface de usuário,Escala de interface do utilizador,Dimensiune Interfață Utilizator,Размер интерфейса,Размера интерфејса,Kullanıcı arayüzü ölçeği -Force default crosshair,HUDMNU_FORCECROSSHAIR,,,,Vynutit výchozí zaměřovač,Tvinge standard-trådkorset,Erzwinge Standard-Fadenkreuz,,Devigi defaŭltan reteton,Forzar retícula por defecto,,Pakota oletustähtäin,Forcer Viseur par défaut,Alapcélkereszt erőltetése,Forza il mirino di default,デフォルトの照準を使う,기본 조준점 강제 설정,Forceer standaard dradenkruis,Tving frem standard trådkors,Wymuś domyślny celownik,Forçar mira padrão,,Forțare țintă implicită,Всегда стандартный прицел,Форсирај уобичајени нишан,Varsayılan artı işaretini zorla -Grow crosshair when picking up items,HUDMNU_GROWCROSSHAIR,,,,Zvětšit zaměřovač při sebrání předmětu,"Vokse trådkorset, når du samler genstande op",Größeres Fadenkreuz bei Gegenstandsaufnahme,,Grandigi reteton kiam oni prenas objektojn,Aumentar retícula al obtener obj.,Crecer retícula al obtener obj.,Suurenna tähtäintä esineitä poimiessa,Agrandir viseur en prenant un objet,A célkereszt nőjön tárgyfelvételkor,Accresci il mirino quando si raccolgono oggetti,アイテム取得時に照準を大きくする,아이템 획득 시 조준점 키우기 ,Vergroot het dradenkruis bij het oppakken van items,Utvid trådkorset når du plukker opp elementer,"Powiększ celownik, gdy podnosisz przedmioty",Aumentar mira ao pegar itens,Aumentar mira ao apanhar itens,Mărește ținta la ridicarea obiectelor,Увеличение прицела при подборе,Побољшај нишан током купљења предмета,Eşyaları alırken artı işaretini büyütün -Display nametags,HUDMNU_NAMETAGS,,,,Zobrazovat jmenovky,Viser navneskilte,Zeige Gegenstandsnamen,,Montri nometikedojn,Mostrar etiquetas,,Näytä nimitunnisteet,Afficher noms des objets,Névtábla mutatása,Mostra le targhette identificative,ディスプレイネームタグ,이름표 표시,Naamlabels weergeven,Vis navnelapper,Pokazuj nazwy przedmiotów,Exibir nomes,,Indică numele obiectelor,Указание названия предметов,Прикажи имена предмета,İsim etiketlerini gösterin -Nametag color,HUDMNU_NAMETAGCOLOR,,,Nametag colour,Barva jmenovek,Farve på navneskilte,Farbe für Gegenstandsnamen,,Nometikeda koloro,Color de las etiquetas,,Nimitunnisteen väri,Couleur des noms d'objet,Névtábla szín,Colore targhetta identificativa,ネームタグ色,이름표 색깔,Kleur naamlabel,Farge på navneskilt,Kolor nazw przedmiotów,Cor dos nomes,,Culoare nume obiecte,Цвет названия предметов,Боја имена предмета,İsim etiketi rengi -Use old ouch mug shot formula,HUDMNU_OLDOUCH,,,,Použít starý vzorec pro 'ouch' portrét,"Gammel formel for ""av"" ansigt",Alte Formel für „Autsch“-Gesicht,,Uzi maljunan formulon de aj-vizaĝo-foto,Usar formula antigua de foto de daño,,Käytä vanhaa auts-naamakuvan kaavaa,Ancien code pour l' « ouch face »,Régi sebződő fej formula használata,Mostra la formula originale del viso 'ouch',旧式ouch mug shotを使用,구형 피격 표정 스프라이트 방식 사용,"Oude formule voor ""Ouch""-gezicht",Bruk formelen for gamle forbryterbilder,Używaj starej formuły twarzy przy dostaniu obrażeń,Usar fórmula original do rosto de dor,,Utilizează modul portret vechi,Старая формула для портрета,Стара формула за приказ лика,Eski ouch oyuncu yüzü formülünü kullanın -Hexen weapon flashes,HUDMNU_HEXENFLASHES,,,,Druh bliknutí zbraní v Hexenu,Hexen-våben blinker,Hexen-Waffenblitze,,Ekbriloj de Hexen-armo,Destello armas Hexen,,Hexenin asevälähdykset,Flash d'arme dans Hexen,Hexen fegyver villanások,Bagliori armi Hexen,Hexen武器の視界色,헥센 무기 반짝임,Hexen-wapen flitsen,Hexen våpen blinker,Błysk przy podnoszeniu broni z Hexena,Flash de arma do Hexen,,Tip strălucire arme Hexen,Тип вспышки оружия в Hexen,Треперење оружја у Hexen-у,Hexen silah flaşları -Poison damage flashes,HUDMNU_POISONFLASHES,,,,Druh bliknutí při otrávení,Giftskabte skader blinker,Gift-Effekt,,Ekbriloj de venondamaĝo,Destello daño por veneno,,Myrkkyvahinkovälähdykset,Flash de poison dans Hexen,Méreg sebzés villanások,Bagliori danno da veleno,毒ダメージの視界色,독데미지 반짝임,Vergiftigingsschade knippert,Giftskade blinker,Efekt obrażeń przy zatruciu,Flash de dano por veneno,,Tip strălucire efect de otrăvire,Тип вспышки яда,Треперење током тровања,Zehir hasarı flaşları -Ice death flashes,HUDMNU_ICEFLASHES,,,,Druh bliknutí při smrti umrznutím,Isdødsblink,Eis-Tod-Effekt,,Ekbriloj de glacimorto,Destello muerte por hielo,,Jääkuolemavälähdykset,Flash de morts par glace,Jéghalál villanások,Bagliori morte da ghiaccio,氷結死の視界色,동사시 반짝임,IJsdood knippert,Isdød blinker,Błysk przy śmierci poprzez zamrożenie,Flash de morte por congelamento,,Tip strălucire deces prin înghețare,Тип вспышки при смерти от льда,Треперење током смрти од леда,Buz ölüm flaşları -Poison Buildup flashes,HUDMNU_HAZARDFLASHES,,,,Druh blikání při kumulaci jedu,Gift Buildup blinker,Kumulativer Gift-Effekt,,Ekbriloj de venonamasigo,Destello acumulación de veneno,,Myrkyn kertymisvälähdykset,Flash d'accumulation de poison,Fokozatos méreg sebzés villanások,Bagliori danno accumulato da veleno,蓄積毒の視界色,독데미지 반짝임 증강,Vergiftiging Opbouw knippert,Giftoppbygging blinker,Miganie przy nasilaniu się trucizny,Flash por acúmulo de dano por veneno,,Tip strălucire acumulare de otravă,Тип вспышки при скоплении яда,Треперење током гомилања отрова,Zehir Birikimi yanıp söner -Scaling Options,HUDMNU_SCALEOPT,,,,Škálování velikosti rozhraní,Skaleringsmuligheder,Skalierungsoptionen,,Skalo-Agordoj,Opciones de escalado,,Skaalausasetukset,Option de mise à l'échelle,Méretezés Beállítások,Opzioni di scala,スケーリング オプション,배율 설정,Schaalopties,Alternativer for skalering,Opcje skalowania,Opções de Escala,,Setări Dimensiuni,Настройки масштабирования,Подешавања размере,Ölçeklendirme Seçenekleri -Show IWAD selection dialog,MISCMNU_QUERYIWAD,,,,Zobrazit dialog pro výběr IWADu,Vis IWAD-valgdialogboks,Zeige IWAD-Auswahl,,Montri elektodialogon de IWAD,Mostrar diálogo de selección de IWAD,,Näytä IWAD-valintaikkuna,Afficher la séléction d'IWAD,IWAD kiválasztó ablak mutatása,Mostra la schermata della selezione IWAD,IWADの選択画面を表示,IWAD 게임 선택창 표시,IWAD-selectiedialoogvenster weergeven,Vis IWAD-valgdialogboks,Pokaż ekran wyboru gry (IWAD),Exibir janela de seleção de IWAD,,Afișează fereastra de selectare a jocurilor,Выбор IWAD-файла при запуске,Покажи IWAD дијалог за избор,IWAD seçim iletişim kutusunu göster -Enable cheats from all games,MISCMNU_ALLCHEATS,,,,Povolit cheaty ze všech her,Aktiver snyderier fra alle spil,Ermögliche Cheats aus allen Spielen,,Ebligi trompojn el tutaj ludoj,Activar trucos de todos los juegos,,Ota käyttöön huijauskoodit kaikista peleistä,Activer cheats de tous les jeux,Minden játék csaláskódja érvényes,Abilita tutti i cheat da tutti i giochi,全ゲームでチート使用可にする,모든 게임에 치트 허용,Laat bedriegers van alle spellen toe,Aktiver juks fra alle spill,Włącz oszustwa ze wszystkich gier,Habilitar trapaças de todos os jogos,Permitir batotas de todos os jogos,Permite codurile din toate jocurile,Читы из всех игр,Омогући читове од свих игара,Tüm oyunlardan hileleri etkinleştirin -,,Option Menus,,,,,,,,,,,,,,,,,,,,,,,, -Enable making screenshots by scripts,MISCMNU_ENABLESCRIPTSCREENSHOTS,,,,Povolit skriptům pořizovat snímky obrazovky,Aktivering af skærmbilleder ved hjælp af scripts,"Erlaube Skripts, Screenshots zu machen",,Ebligi faradon de ekrankopioj per skriptoj,Habilitar captura de pantalla por scripts,,Salli komentosarjoin otetut kuvakaappaukset,Autoriser les Scripts à prendre des captures,Szkriptek is készíthetnek képernyőképet,Abilita la cattura dello schermo tramite scripts,スクリプトからのスクショ作成を有効化,저장/불러오기 확인,Screenshots maken met behulp van scripts,Gjør det mulig å lage skjermbilder av skript,Pozwól na robienie zrzutów ekranu przez skrypty,Habilitar capturas de tela por scripts,Permitir capturas de ecrã por scripts,Posibilitate de a face poze prin scripturi,Возможность делать снимки экрана через скрипты,Омогући прављење скриншотова по скрипти,Komut dosyalarıyla ekran görüntüsü almayı etkinleştirme -Load *.deh/*.bex lumps,MISCMNU_DEHLOAD,,,,Načítat *.deh/*.bex soubory,Indlæsning af *.deh/*.bex-filer,Lade *.deh/*.bex Daten,,Ŝargi je *.deh/*.bex lumpoj,Cargar archivos *.deh/*.bex,,Lataa *.deh/*.bex-lump-tiedostot,Charger fichiers *.deh/*.bex,*.deh/*.bex lump-ok betöltése,Carica i lump *.deh/*.bex,.deh/.bexファイルを読み込む,*.deh/*.bex 럼프 파일 불러오기,*.deh/*.bex laden,Last inn *.deh/*.bex-arkiver,Załaduj dane *.deh/*.bex,Carregar lumps *.deh/*.bex,,Încarcă nodurile *.deh/*.bex,Загружать файлы *.deh/*.bex,Учитај *.deh/*.bex фајлове,.deh/*.bex topaklarını yükle -Cache nodes,MISCMNU_CACHENODES,,,,Cachovat nodes,,Nodes zwischenspeichern,,Kaŝmemoraj nodoj,Caché de nodos,,Tallenna solmut välimuistiin,Mise en cache des nodes,Node-ok cache-lése,Cache dei nodi,ノードキャッシュ,캐시 노드,Cache nodes,Bufre noder,Węzły pamięci podręcznej,Cachê de nodes,Cache de nodes,Depozitare noduri cache,Кэширование узлов,Кеширани чворови,Önbellek düğümleri -Time threshold for node caching,MISCMNU_CACHETIME,,,,Časový práh pro cachování nodes,Tidsgrænse for node-cache,Zeitschwelle für das Zwischenspeichern von Nodes,,Templimo pro kaŝmemornodi,Umbral de tiempo para caché de nodos,,Kynnysaika solmujen välimuistitallennukseen,Limite cache des nodes,Időhatár node cache-hez,Soglia di tempo per il caching dei nodi,ノードキャッシュ時間の閾値,노드 캐싱을 위한 시간 임계값 계산,Tijdsdrempel voor het cachen van nodes,Tidsterskel for nodebufring,Próg czasowy buforowania węzłów,Limite de tempo para cachê de nodes,Limite de tempo para cache de nodes,Limită de timp pentru depozitare cache,Временной порог для кэширования узлов,Временски праг за кеширање чвора,Düğüm önbelleğe alma için zaman eşiği +",아이템 버리기,Item laten vallen,Slipp element,Upuść przedmiot,Largar item,,Aruncare Obiect,Бросить предмет,Баци предмет,Släpp föremål,Eşyayı bırak +Query item,CNTRLMNU_QUERYITEM,,,,Informace o předmětu,Forespørgsel element,Informationen über Gegenstand,,Informpeti objekton,Consultar objeto,,Hae varustetta,Vérifier objet,Rákérdez a tárgy eldobásnál,Indaga sull'oggetto,アイテム名を表示,아이템 정보 표시,Vraag item op,Spør om element,Zapytaj o przedmiot,Consultar item,,Cercetare Obiect,Проверить предмет,Прикажи предмет,Fråga efter objekt,Sorgu öğesi +Drop weapon,CNTRLMNU_DROPWEAPON,,,,Odhodit zbraň,Smid våben,Waffe fallen lassen,Πέτα Όπλο,Faligi armilon,Arrojar arma,,Pudota ase,Lâcher arme,Fegyver eldobása,Butta l'arma,武器を捨てる,무기 버리기,Wapen laten vallen,Slipp våpen,Upuść broń,Largar arma,,Aruncare Armă,Выбросить оружие,Баци оружје,Släpp vapen,Silahı bırak +Other,CNTRLMNU_OTHER,,,,Ostatní,Andre,Andere,Άλλα,Alia,Otros,,Muu,Autres,Más,Altro,その他,그 외 조작,Andere,Annet,Inne,Outro,,Altele,Прочее,Остало,Annat,Diğer +Coop spy,CNTRLMNU_COOPSPY,,,,Co-op špehování,Coop-spion,Coop Spion,,Kunlabora spiono,Espía cooperativo,,Vakoile joukkuetovereita,Espionner Coéquiper,Coop leskelődés,Spia cooperativa,他者視点,멀티플레이 카메라,Coöpspion,Coop-spion,Śledź (kooperacja),Visualização coop,,Vedere prin Ochii Altui Jucător,Вид от другого игрока,Поглед од другог играча,Spion för samarbete,Coop casusu +Strife Popup Screens,CNTRLMNU_POPUPS,,,,Vyskakovací okna Strife,Strife popup-skærme,Strife Popups,,Ekmontraĵaj Ekranoj de Strife,Pop-ups de Strife,,Strifen ponnahdusruudut,Popups de Strife,Strife Felugró Ablakok,Schermate popup di Strife,Strife ポップアップ画面,스트라이프 팝업 화면,Strife Popup Schermen,Strife Popup-skjermer,Okienka Strife'a,Popup do Strife,,Mesaje Strife,Всплывающие окна Strife,Информација у Strife-у,Strife Popup-skärmar,Strife Açılır Ekranları +Mission objectives,CNTRLMNU_MISSION,,,,Úkoly mise,Mål for en mission,Missionsziele,Στόχοι Αποστολής,Misiobjektivoj,Objetivos de misión,,Tehtävätavoitteet,Objectifs de Mission,Küldetési célok,Obiettivi della missione,ミッションオブジェクト,임무 목록,Missiedoelen,Oppdragets mål,Cele misji,Objetivos da missão,,Obiectivele Misiunii,Текущее задание,Циљ мисије,Mål för uppdraget,Görev hedefleri +Keys list,CNTRLMNU_KEYS,,,,Seznam klíčů,Liste over nøgler,Schlüsselliste,Λίστα Κλειδιών,Ŝlosilolisto,Lista de llaves,,Avainlista,Liste des Clés,Kulcslista,Lista delle chiavi,キー類リスト,열쇠 목록,Lijst van toetsen,Liste over nøkler,Lista kluczy,Lista de teclas,,Listă Chei,Список ключей,Списка кључева,Lista över nycklar,Anahtar listesi +Weapons/ammo/stats,CNTRLMNU_STATS,,,,Zbraně/munice/staty,Våben/ammo/stats,Waffen/Munition/Statistik,Οπλα/Πυρομαχικά/Στατιστικές,Armiloj/municio/stataĵoj,Armas/Munición/Estadísticas,,Aseet/ammukset/tila,"Statistiques, armes et munitions",Fegyver/lőszer/statisztika,Armi/ammunizioni/statistiche,武器 / 弾薬 / 状態,무기/탄약/통계 목록,Wapens/ammo/statistieken,Våpen/ammunisjon/statistikk,Bronie/amunicja/statystyki,Armas/munição/estatísticas,,Arme/muniție/statistici,"Оружие, патроны и показатели",Оружје/муниција/статистика,Vapen/ammo/statistik,Silahlar/mühimmat/istatistikler +Toggle Scoreboard,CNTRLMNU_TOGGLESCOREBOARD,,,,Přepnout tabulku skóre,Skift Scoreboard,Punktetafel an/aus,Ενεργοποίηση Πίνακα Σκόρ,Baskuligi poentotabulon,Alternar Marcador,,Pistetaulun vaihtokytkin,Afficher Scores (alterner),Eredményjelző kapcsoló,Abilita/disabilita tabella punteggio,スコアボード切替,점수창 토글,Scorebord aan/uit,Veksle resultattavle,Włącz / Wyłącz tablicę wyników,Ativar/desativar placar,Ligar/desligar Pontuação no Ecrã,Comutator pentru Tabela de Marcaj,Таблица очков (перекл.),Табела (без држања),Växla resultattavla,Skor Tablosunu Değiştir +Lookspring,MOUSEMNU_LOOKSPRING,,,,Automatické vystředění pohledu,Centret automatisk,Automatisch zentrieren,,Rigardsalto,Mirar con ratón,,Katseenpalautin,Recentrer après Vue Souris,,,視点水平化,마우스룩 시점 초기화,Automatisch centraliseren,Sentrer automatisk,Automatyczne Wyśrodkowanie,Centralizar automaticamente,Centrar automáticamente,Mișcare a jucătorului prin mouse,Передвижение мышью,Покрет мишем,Centrum automatiskt,Merkez otomatik olarak +Lookstrafe,MOUSEMNU_LOOKSTRAFE,,,,Použít myš k pohybu do stran,Flyt sidelæns med musen,Seitwärts bewegen mit der Maus,,Rigardturnmovo,Mirar con movimiento,,Sivuttaisastuntapalautin,Mouvement Latéral par Souris,,,視点横移動化,마우스룩 좌우 이동,Zijwaartse muisbeweging,Flytt sidelengs med musen,Unikanie przy użyciu myszki,Deslocamento lateral com o mouse,Deslocamento lateral com o rato,Mișcare în diagonală cu mouse,Движение боком мышью,Стрејф мишем,Flytta i sidled med musen,Fare ile yana doğru hareket ettirin +,,Map colors,,,,,,,,,,,,,,,,,,,,,,,,, +Background,MAPCOLORMNU_BACKCOLOR,,,,Pozadí,Baggrund,Hintergrund,,Fono,Fondo,,Tausta,Fond,Háttér,Sfondo,背景,배경,Achtergrond,Bakgrunn,Tło,Fundo,,Fundal,Фон,Позадина,Bakgrund,Arka plan +You,MAPCOLORMNU_YOURCOLOR,,,,Ty,Du,Du,,Vi,Tú,,Sinä,Votre couleur,Te,Tu,自分,당신,,Du,Ty,Você,Tu,Tu,Вы,Ти,Du,Sen +1-sided walls,MAPCOLORMNU_WALLCOLOR,,,,Jednostranné zdi,1-sidede vægge,Einseitige Wände,,1-flankaj muroj,Paredes de 1 lado,,Yksipuoliset seinät,Murs à 1 côté,1 oldalú falak,Muri unilaterali,壁,단면 벽들,1-zijdige wanden,1-sidige vegger,Jednostronne ściany,Paredes de 1 lado,,Pereți cu o singură față,Односторонние стены,Једнострани зид,1-sidiga väggar,1 taraflı duvarlar +2-sided walls with different floors,MAPCOLORMNU_FDWALLCOLOR,,,,Oboustranné zdi s různými podlahami,2-sidede vægge med forskellige gulve,Zweiseitige Wände mit unterschiedlicher Bodenhöhe,,2-flankaj muroj kun malsamaj plankoj,Paredes de 2 lados con pisos distintos,,Kaksipuoliset seinät eroavilla lattiakorkeuksilla,Murs à 2 côtés avec différents sols,2 oldalú falak különböző padlókkal,Muri bilaterali con pavimenti diversi,高低差のある床,다른 층 추가된 양면 벽들,2-zijdige wanden met verschillende vloeren,2-sidige vegger med forskjellige gulv,Dwustronne ściany z innymi piętrami,Paredes de 2 lados com pisos diferentes,,Pereți cu două fețe si podele diferite,Двусторонние стены,Двострани зид са различитим нивоима,2-sidiga väggar med olika golv,Farklı zeminlere sahip 2 taraflı duvarlar +2-sided walls with different ceilings,MAPCOLORMNU_CDWALLCOLOR,,,,Oboustranné zdi s různými stropy,2-sidede vægge med forskellige lofter,Zweiseitige Wände mit unterschiedlicher Deckenhöhe,,2-flankaj muroj kun malsamaj plafonoj,Paredes de 2 lados con techos distintos,,Kaksipuoliset seinät eroavilla kattokorkeuksilla,Murs à 2 côtés avec différents plafonds,2 oldalú falak különböző plafonnal,Muri bilaterali con soffitti diversi,高低差のある天井,다른 천장 추가된 양면 벽들,2-zijdige wanden met verschillende plafonds,2-sidige vegger med forskjellige tak,Dwustronne ściany z innymi sufitami,Paredes de 2 lados com tetos diferentes,,Pereți cu două fețe si tavane diferite,Двусторонние стены с разными потолками,Двострани зид са различитим плафонима,2-sidiga väggar med olika tak,Farklı tavanlara sahip 2 taraflı duvarlar +2-sided walls with 3D floors,MAPCOLORMNU_EFWALLCOLOR,,,,Oboustranné zdi s 3D podlahami,2-sidede vægge med 3D-gulve,Zweiseitige Wände mit 3D-Ebenen,,2-flankaj muroj kun 3D-plankoj,Paredes de 2 lados con suelos 3D,,Kaksipuoliset seinät kolmiulotteisilla lattioilla,Murs à 2 côtés avec sols 3d,2 oldalú falak 3D-s padlókkal,Muri bilaterali con 3D floor,多重床,3D 층 추가된 양면 벽들,2-zijdige wanden met 3D-vloeren,2-sidige vegger med 3D-gulv,Dwustronne ściany z piętrami 3D,Paredes de 2 lados com pisos 3D,,Pereți cu două fețe si podele 3D,Двусторонние стены с разными полами,Двострани зид са 3D нивоима,2-sidiga väggar med 3D-golv,3D zeminli 2 taraflı duvarlar +Map grid,MAPCOLORMNU_GRIDCOLOR,,,,Mřížka,Kortgitter,Kartengitter,,Mapkrado,Cuadrícula del mapa,,Kartan ruudukko,Quadrillage,Pálya szél,Griglia mappa,マップグリッド,맵 격자,Kaart raster,Kartrutenett,Siatka mapy,Grade do mapa,Grelha do mapa,Grilă hartă,Цвет сетки,Мапа координатне мреже,Kartnät,Harita ızgarası +Center point,MAPCOLORMNU_XHAIRCOLOR,,,Centre point,Středobod,Midterpunkt,Mittelpunkt,,Centra punkto,Punto central,,Keskipiste,Point Central,Pálya közepe,Punto centrale,中心点,중간 지점,Middenpunt,Midtpunkt,Środek,Ponto central,,Punct în centru,Курсор,Централна тачка,Centrumpunkt,Merkez noktası +Not-yet-seen walls,MAPCOLORMNU_NOTSEENCOLOR,,,,Neobjevené zdi,"Vægge, der endnu ikke er synlige",Ungesehene Wände,,Vidotaj muroj,Paredes sin ver,,Tutkimattomat seinät,Murs non découvers,Még nem látott falak,Muri ancora da scoprire,未見の壁,안 본 벽들,Nog niet zichtbare wanden,Vegger som ennå ikke er sett,Jeszcze niewidziane ściany,Paredes não vistas até o momento,,Ziduri încă neobservate,Необнаруженные стены,Неоткривени зидови,Väggar som ännu inte har setts,Henüz görülmemiş duvarlar +Locked doors,MAPCOLORMNU_LOCKEDCOLOR,,,,Zamčené dveře,Låste døre,Verschlossene Türen,,Ŝlositaj pordoj,Puertas bloqueadas,,Lukitut ovet,Portes verouillées,Zárt ajtók,Porte bloccate,鍵の掛かったドア,잠긴 문들,Gesloten deuren,Låste dører,Zablokowane drzwi,Portas trancadas,,Uși închise,Запертые двери,Закључана врата,Låsta dörrar,Kilitli kapılar +Teleporter to the same map,MAPCOLORMNU_INTRALEVELCOLOR,,,,Teleportér,Teleporter til samme kort,Teleporter,,Teleportilo al la sama mapo,Teletransporte al mismo mapa,,Kaukosiirrin samaan tasoon,Téléporteurs (même niveau),Ugyanarra a pályára teleportálás,Teletrasporto nella stessa mappa,テレポーター,같은 맵에 텔레포터 추가,Teleporter naar dezelfde niveau,Teleporter til samme kart,Teleporter do tej samej mapy,Teletransportador para o mesmo mapa,,Teleportor către aceeași hartă,Телепорт в пределах уровня,Телепортер до истог нивоа,Teleporter till samma karta,Aynı haritaya ışınlayıcı +Teleporter to a different map,MAPCOLORMNU_INTERLEVELCOLOR,,,,Teleportér do jiného levelu,Teleporter til et andet kort,Teleporter in ein anderes Level,,Teleportilo al alia mapo,Teletransporte a un mapa diferente,,Kaukosiirrin eri tasoon,Téléporteurs (autre niveau),Másik pályára teleportálás,Teletrasporto in una mappa diversa,別マップへのテレポーター,다른 맵에 텔레포터 추가,Teleporter naar een andere niveau,Teleporter til et annet kart,Teleporter do innej mapy,Teletransportador para outro mapa,,Teleportor către altă hartă,Телепорт на другой уровень,Телепортер до различитог нивоа,Teleporter till en annan karta,Farklı bir haritaya ışınlayıcı +Secret sector,MAPCOLORMNU_SECRETSECTORCOLOR,,,,Skrýš,Hemmelig sektor,Geheimer Sektor,,Sekreta sektoro,Sector secreto,,Salasektori,Secteur Secret,Rejtekhely szektora,Settore segreto,シークレット,비밀 섹터,Geheime sector,Hemmelig sektor,Sekretny sektor,Setor secreto,,Sector secret,Тайный сектор,Тајни сектор,Hemlig sektor,Gizli sektör +Unexplored secret,MAPCOLORMNU_UNEXPLOREDSECRETCOLOR,,,,Neobjevená skrýš,Uudforsket hemmelighed,nicht gefundener geheimer Sektor,,Neesplorita sekreto,Secreto sin explorar,,Tutkimaton sala,Secret non révélé,Még fel nem fedezett rejtekhely,Segreto non esplorato,未知のシークレット,발견하지 않은 비밀,Onontgonnen geheim,Uutforsket hemmelighet,Niezbadany sekret,Segredo não-explorado,,Secret neexplorat,Необнаруженный тайник,Ноткривена тајна,Oexploaterad hemlighet,Keşfedilmemiş sır +Special trigger lines,MAPCOLORMNU_SPECIALWALLCOLOR,,,,Akční čáry,Særlige udløserlinjer,Spezielle Linien,,Specialaj ekagilo-linioj,Líneas especiales de activación,,Erikoislaukaisinviivat,Lignes d'actions spéciales,Speciális trigger vonalak,Linee di attivazione speciali,特殊トリガー,특수 트리거 선,Speciale trekkerlijnen,Spesielle utløserlinjer,Specjalne linie przełączników,Linhas de ativação especiais,,Linii declașatoare speciale,Специальные спусковые линии,Специјалне линије окидача,Särskilda utlösningslinjer,Özel tetik hatları +Cheat Mode,MAPCOLORMNU_CHEATMODE,,,,Cheatovací režim,Snyd-tilstand,Cheat-Modus,,Tromp-Reĝimo,Modo de truco,,Huijaustila,Mode Cheat,Csalás mód,Modalità cheat,チートモード時,치트 모드,Bedriegingsmodus,Juksemodus,Tryb oszustwa,Modo trapaça,Modo de Batota,Modul Trișor,Чит-режим,Чит мод,Fuskläge,Hile Modu +Invisible 2-sided walls,MAPCOLORMNU_TSWALLCOLOR,,,,Neviditelné oboustranné zdi,Usynlige 2-sidede vægge,Unsichtbare zweiseitige Wände,,Nevideblaj 2-flankaj muroj,Paredes de 2 lados Invisibles,,Näkymättömät kaksipuoliset seinät,Murs à 2 côtés invisibles,Láthatatlan 2 oldalú falak,Muri invisibili bilaterali,表示されないline,투명한 양면 벽,Onzichtbare 2-zijdige wanden,Usynlige 2-sidige vegger,Niewidzialne dwustronne ściany,Paredes invisíveis de 2 lados,,Pereți cu două fețe invizibili,Невидимые двусторонние стены,Невидљиви двострани зидови,Osynliga 2-sidiga väggar,Görünmez 2 taraflı duvarlar +Secret walls,MAPCOLORMNU_SECRETWALLCOLOR,,,,Tajné zdi,Hemmelige vægge,Geheime Wände,,Sekretaj muroj,Paredes secretas,,Salaiset seinät,Murs Secrets,Titkos falak,Muri segreti,シークレットの壁,비밀 벽,Geheime muren,Hemmelige vegger,Sekretne ściany,Paredes secretas,,Pereți ascunși,Тайные стены,Тајни зидови,Hemliga väggar,Gizli duvarlar +Actors,MAPCOLORMNU_THINGCOLOR,,,,Objekty,Skuespillere,Akteure,,Aktoroj,Actores,,Oliot,Acteurs,Játékos,Attori,アクター,개체,Acteurs,Skuespillere,Aktorzy,Atores,,Actori,Объекты,Актори,Skådespelare,Aktörler +Monsters,MAPCOLORMNU_MONSTERCOLOR,,,,Příšery,Monstre,Monster,,Monstroj,Monstruos,,Hirviöt,Monstres,Szörnyek,Mostri,モンスター,적들,,Monstre,Potwory,Monstros,,Monștri,Монстры,Чудовишта,Monster,Canavarlar +Non-counting Monsters,MAPCOLORMNU_NONCOUNTINGMONSTERCOLOR,,,,Nepočítané příšery,Ikke-tællende monstre,nicht gezählte Monster,,Nenombradaj Monstroj,Monstruos no contados,Monstruos sin contar,Ei-laskettavat hirviöt,Monstres non comptés,Nem számolt szörnyek,Mostri non contati,非カウントモンスター,킬수에 포함 되지 않는 적들,Niet-tellende Monsters,Ikke-tellende monstre,Niezliczane Potwory,Monstros não contados,,Monștri neacoperiți de numărătoare,Неучитываемые монстры,Не рачунајући чудовишта,Icke-räknande monster,Sayılamayan Canavarlar +Friends,MAPCOLORMNU_FRIENDCOLOR,,,,Přátelé,Venner,Freunde,,Amikoj,Amigos,,Omat,Amis,Barátok,Amici,仲間,친구들,Vrienden,Venner,Przyjaciele,Amigos,,Prieteni,Дружественные,Пријатељи,Vänner,Arkadaşlar +Items,MAPCOLORMNU_ITEMCOLOR,,,,Předměty,Genstande,Gegenstände,,Objektoj,Objetos,,Esineet,Objets,Tárgyak,Oggetti,アイテム,아이템들,Artikelen,Gjenstander,Przedmioty,Itens,,Obiecte,Предметы,Предмети,Föremål,Eşyalar +Count Items,MAPCOLORMNU_COUNTITEMCOLOR,,,,Počítané předměty,Tælle genstande,gezählte Gegenstände,,Nombri Objektojn,Objetos contados,Conteo de objetos,Laske esineet,Objets comptés,Tárgyak számolása,Oggetti contati,カウント対象アイテム,아이템 계산,Tellen,Telle elementer,Zlicz przedmioty,Itens contados,,Numără obiectele,Учитываемые предметы,Рачунајући предмети,Räkna objekt,Sayım Öğeleri +Overlay Mode,MAPCOLORMNU_OVERLAY,,,,Překryvný režim,Overlay-tilstand,Überlagerungsmodus,,Surmeto-Reĝimo,Modo sobrepuesto,,Projisointitila,Mode surimpression,Overlay mód,Modalità sovrapposizione,オーバーレイモード,오버레이 모드,Overlaadmodus,Overleggsmodus,Tryb Nakładki,Modo de sobreposição,,Mod acoperit,Прозрачный режим,Провидна аутомапа,Överlagringsläge,Kaplama Modu +Overlay Cheat Mode,MAPCOLORMNU_OVCHEATMODE,,,,Překryvný cheatovací režim,Overlay snydetilstand,Überlagerungsmodus Cheats,,Surmeto-Tromp-Reĝimo,Sobreposición modo de truco,,Projisointihuijaustila,Mode Cheat Surimpression,overlay csaló mód,Modalità cheat sovrapposizione,オーバーレイ チートモード,치트 모드 오버레이,Overlaadmodus Cheats,Overlegg-juksemodus,Tryb Nakładki Oszustwa,Modo trapaça de sobreposição,Modo Batota de Sobreposição,Mod acoperit trișor,Прозрачный чит-режим,Провидни читови,Överlagrat fuskläge,Kaplama Hile Modu +Portal Overlays,MAPCOLORMNU_PORTAL,,,,Portálové překryvy,Portal-overlejringer,Portalüberlagerung,,Portalo-Surmetoj,Sobreposición de portal,,Portaaliprojisoinnit,Portails superposés,Portál overlay-ek,Sovrapposizioni del portale,ポータル オーバーレイ,포탈 오버레이,Portaaloverlays,Portal-overlegg,Nakładanie się Portali,Sobreposição de portais,,Acoperiri portaluri,Порталы в прозрачном режиме,Провидни портали,Överlagringar i portalen,Portal Kaplamaları +,,Messages,,,,,,,,,,,,,,,,,,,,,,,,, +Messages,MSGMNU_TITLE,,,,Nastavení oznámení,Meddelelser,Nachrichten,,Mesaĝoj,Mensajes,,Viestit,,Üzenetek,Messaggi,メッセージ類,메시지들,Berichten,Meldinger,Wiadomości,Mensagens,,Mesaje,Сообщения,Поруке,Meddelanden,Mesajlar +Show messages,MSGMNU_SHOWMESSAGES,,,,Zobrazit oznámení,Vis meddelelser,Zeige Nachrichten,,Montri mesaĝojn,Mostrar Mensajes,,Näytä viestit,Afficher messages,Üzenetek mutatása,Mostra messaggi,メッセージ表示,메시지 표시,Berichten tonen,Vis meldinger,Pokaż wiadomości,Exibir mensagens,,Afișare mesaje,Отображение сообщений,Прикажи поруке,Visa meddelanden,Mesajları göster +Show obituaries,MSGMNU_SHOWOBITUARIES,,,,Zobrazit oznámení o smrtích,Vis dødsannoncer,Zeige Todesanzeigen,,Montri nekrologojn,Mostrar obituarios,,Näytä kuolinviestit,Afficher avis de décès,Halálok mutatása,Mostra i necrologi,訃報表示,사망 메시지 표시,Doodsbrieven tonen,Vis dødsannonser,Pokaż nekrologi,Exibir obituários,,Afișare necrologuri,Отображение некрологов,Прикажи читуље,Visa dödsannonser,Ölüm ilanlarını göster +Show secret notifications,MSGMNU_SHOWSECRETS,,,,Zobrazit zprávy o skrýších,Vis hemmelige meddelelser,Zeige Geheimnismeldung,,Montri sciigojn de sekretoj,Mostrar notificación de secretos,,Ilmoita salojen löytymisestä,Afficher secrets,Titkos üzenetek mutatása,Mostra le notifiche dei segreti,シークレット発見表示,비밀 알림 표시,Geheime meldingen tonen,Vis hemmelige meldinger,Pokaż wiadomości znalezienia sekretu,Exibir notificação de segredos,,Afișare notificări pentru secrete,Отображение сообщений о тайниках,Прикажи тајне нотификације,Visa hemliga meddelanden,Gizli bildirimleri göster +Minimum message level,MSGMNU_MESSAGELEVEL,,,,Minimální úroveň oznámení,Mindste beskedniveau,Min. Nachrichtenanzeigestufe,,Minimuma nivelo de mesaĝoj,Nivel mínimo de mensaje,,Pienin viestintätaso,Niveau de message minimum,Milyen üzenet jelenjen meg,Numero di messaggi minimo,最小メッセージレベル,메시지 축소량,Minimaal berichtenniveau,Minste meldingsnivå,Poziom minimalnych wiadomości,Nível mínimo de mensagem,,Nivel minim de afișare mesaje,Минимальный уровень сообщений,Минимум левел порука,Minsta nivå för meddelanden,Minimum mesaj seviyesi +Message Colors,MSGMNU_MESSAGECOLORS,,,Message Colours,Barva oznámení,Farver på meddelelser,Nachrichtenfarben,,Mesaĝkoloroj,Colores de los Mensajes,,Viestien värit,Couleur des messages,Üzenet színek,Colore dei messaggi,メッセージ色,메시지 색상,Bericht Kleuren,Meldingsfarger,Kolory Wiadomości,Cores de mensagem,,Culori Mesaje,Цвета сообщений,Боје порука,Färger för meddelanden,Mesaj Renkleri +Item Pickup,MSGMNU_ITEMPICKUP,,,,Sebrání předmětu,Afhentning af varer,Genommene Gegenstände,,Objektoprenado,Toma de objetos,,Esineen poimiminen,Objets ramassés,Tárgy felvétele,Raccolta oggetti,アイテム取得,아이템 획득,Puntafhaling,Henting av element,Podniesienie Przedmiotu,Coleta de item,Aquisição de Itens,Ridicare obiecte,Подбор предмета,Покупити предмет,Upphämtning av objekt,Bir eşyayı almak +Obituaries,MSGMNU_OBITUARIES,,,,Oznámení o úmrtí,Dødsannoncer,Todesanzeigen,,Nekrologoj,Obituarios,,Kuolinviestit,Avis de décès,Halálok,Necrologi,死亡時メッセージ,사망 메시지,Doodsbrieven,Nekrologer,Nekrologi,Obituários,,Necrologuri,Некрологи,Читуље,Dödsannonser,Ölüm İlanları +Critical Messages,MSGMNU_CRITICALMESSAGES,,,,Kritická oznámení,Kritiske meddelelser,Kritische Nachrichten,,Gravaj Mesaĝoj,Mensajes críticos,,Tärkeät viestit,Messages d'erreur,Fontos üzenetek,Messaggi critici,致命的なメッセージ,중요한 메시지,Kritische berichten,Kritiske meldinger,Wiadomości krytyczne,Mensagens críticas,,Mesaje Critice,Важные сообщения,Критичне поруке,Kritiska meddelanden,Kritik Mesajlar +Chat Messages,MSGMNU_CHATMESSAGES,,,,Chatová oznámení,Chat-meddelelser,Chatnachrichten,,Babilmesaĝoj,Mensajes de chat,,Keskusteluviestit,Message de Chat,Chat üzenetek,Messaggi chat,チャットメッセージ,채팅 메시지,Chatberichten,Chat-meldinger,Wiadomości czatu,Mensagens de chat,,Mesaje Conversație,Сообщения в чате,Ћаскања,Chatt-meddelanden,Sohbet Mesajları +Team Messages,MSGMNU_TEAMMESSAGES,,,,Týmová oznámení,Hold-meddelelser,Teamnachrichten,,Teammesaĝoj,Mensajes de equipo,,Joukkueen viestit,Messages d'équipe,Csapat chat üzenetek,Messaggi chat di squadra,チームメッセージ,팀 채팅 메시지,Team Berichten,Team-meldinger,Wiadomości czatu drużynowego,Mensagens de equipe,Mensagens de Equipa,Mesajele Echipei Proprii,Командные сообщения в чате,Тимске поруке,Meddelanden till laget,Ekip Mesajları +Centered Messages,MSGMNU_CENTEREDMESSAGES,,,Centred Messages,Oznámení na střed,Centrerede meddelelser,Zentrierte Nachrichten,,Centritaj Mesaĝoj,Mensajes centrados,,Keskitetyt viestit,Messages centrés,Üzenet középre igazítása,Messaggi centrati,スクリプトメッセージ,중간에 위치한 메시지,Gecentreerde berichten,Sentrerte meldinger,Wyśrodkowane wiadomości,Mensagens centralizadas,Mensagens Centradas,Mesaje Centrate,Центрированные сообщения,Централне поруке,Centrerade meddelanden,Merkezli Mesajlar +Screenshot messages,MSGMNU_SCREENSHOTMESSAGES,,,,Oznámení o snímcích obrazovky,Beskeder med skærmbilleder,Screnshot-Meldungen,,Mesaĝoj de ekrankopio,Mensajes de captura de pantalla,,Kuvakaappausviestit,Messages de capture d'écran,Képernyőkép készítés visszajelzés,Messaggi di cattura schermo,スクショメッセージ,스크린샷 메시지,Screenshot berichten,Skjermbilde-meldinger,Wiadomości o zrobieniu zrzutu ekranu,Mensagens de captura de tela,Mensagen de captura de ecrã,Mesaje Capturi Ecran,Сообщения о снимках экрана,Скриншот поруке,Meddelanden med skärmdump,Ekran görüntüsü mesajları +Detailed save messages,MSGMNU_LONGSAVEMESSAGES,,,,Detailní oznámení o uložené hře,Detaljerede beskeder om lagring,Detaillierte Speicher-Meldungen,,Detalaj konservmesaĝoj,Mensajes detallados de guardado,,Yksityiskohtaiset tallennusviestit,Messages de sauvegarde détailés,Részletes mentési információ,Messaggi sui dettagli di salvataggio,詳細なセーブメッセージ,자세한 저장 메시지,Gedetailleerde berichten voor op te slaan,Detaljerte lagringsmeldinger,Szczegółowe wiadomości o zapisie,Mensagens detalhadas de salvamento,Mensagens detalhadas de gravação,Mesaje detaliate pentru salvări,Подробные сообщения о сохранениях,Детаљно сачуване поруке,Detaljerade meddelanden om sparande,Ayrıntılı kaydetme mesajları +Developer message mode,MSGMNU_DEVELOPER,,,,Vývojářská oznámení,Meddelelsestilstand for udviklere,Entwickler-Modus,,Reĝimo de mesaĝoj por programistoj,Modo de mensajes de desarrollador,,Pelinkehittäjäviestitila,Mode de Développement,Fejlesztői üzenetek,Modalità messaggi per sviluppatore,開発者用モード,개발자 메시지 모드,Berichtenmodus voor ontwikkelaars,Meldingsmodus for utviklere,Tryb wiadomości deweloperskich,Modo de mensagens de desenvolvedor,,Mod mesaje pentru dezvoltator,Режим сообщений для разработчиков,Поруке девелопера,Meddelandeläge för utvecklare,Geliştirici mesaj modu +,,Automap,,,,,,,,,,,,,,,,,,,,,,,,, +Map color set,AUTOMAPMNU_COLORSET,,,Map colour set,Barevné schéma,Farvesæt til kort,Farbset,,Mapkoloro-agordaĵo,Definir colores,,Kartan värikokoelma,Set de couleurs de la carte,Pálya térkép szín séma,Colori della mappa,地図色セット,맵 색상 설정,Kaartkleurenset,Kartfargesett,Zestaw kolorów mapy,Definir cores de mapa,,Set culori hartă,Цвета автокарты,Боје за мапу,Färgsättning av kartan,Harita renk seti +Allow map defined colors,AUTOMAPMNU_CUSTOMCOLORS,,,Allow map defined colours,Povolit barvy dle modů,Tillad kortdefinerede farver,Erlaube levelspezifische Farben,,Permesi mapdefinitajn kolorojn,Permitir colores definidos,,Salli tason määrittelemät värit,Couleurs définies par carte,Pálya orientált színséma használata,Consenti i colori definiti dalla mappa,定義したマップ色の許可,맵 정의 색상 허용,Niveau-specifieke kleuren toestaan,Tillat kartdefinerte farger,Pozwól na kolory zdefiniowne przez mapę,Permitir cores definidas por mapa,,Permite culorilor să fie definite de hartă,Разрешить определённые уровнем цвета автокарты,Дозволи дефинисане боје за мапу,Tillåter kartdefinierade färger,Harita tanımlı renklere izin ver +Set custom colors,AUTOMAPMNU_SETCUSTOMCOLORS,,,Set custom colours,Vlastní barvy,Indstil brugerdefinerede farver,Benutzerdefinierte Farben,,Agordi laŭmendajn kolorojn,Fijar colores personalizados,,Mukauta värejä,Choisir couleurs personnalisées,Egyéni színek beállítása,Modifica i colori personalizzati,カスタム色を決める,사용자 지정 색상 설정,Aangepaste kleuren instellen,Angi egendefinerte farger,Spersonalizuj kolory,Definir cores personalizadas,,Setare culori personalizate,Задать свои цвета,Промени боје,Ställ in egna färger,Özel renkleri ayarlama +Customize map controls,AUTOMAPMNU_CONTROLS,,,,Ovládání mapy,Tilpas kontrolelementer til kortet,Automapsteuerung einstellen,,Adapti mapregilojn,Personalizar controles del mapa,,Kartanohjausasetukset,Choisir contrôles de la carte,Térkép irányítás testreszabása,Personalizza i controlli mappa,マップコントロール カスタマイズ,맵 조작 설정,Kaartcontroles aanpassen,Tilpass kartkontroller,Ustaw klawisze mapy,Configurar comandos de mapa,,Personalizare schemă de control a hărții,Управление автокартой,Промени контроле мапе,Anpassa kartkontroller,Harita kontrollerini özelleştirme +Overlay automap,AUTOMAPMNU_OVERLAY,,,,Překryvná mapa,Overlay automap,Überlagere Automap,,Surmeti aŭtomatan mapon,Superponer automapa,,Projisoi automaattikartta,Carte en Surimpression,Képen felüli térkép,Copri l'automappa,オートマップを重ねる,오토맵을 오버레이,Overlay automap,Overlegg automatisk kart,Nałożenie mapy,Sobreposição de automapa,,Acoperire hartă computerizată,Прозрачная автокарта,Провидна аутомапа,Överlagring av automap,Yerleşim otomatik haritası +Enable textured display,AUTOMAPMNU_TEXTURED,,,,Textury,Aktiver tekstureret visning,Texturanzeige,,Ŝalti teksturitan ekranon,Mostrar automapa texturizado,,Ota käyttöön pintakuvioinnit,Activer affichage texturé,Textúrázott térkép,Abilita la mostra texture,床テクスチャ表示を許可,텍스쳐 디스플레이 허용,Structuurweergave inschakelen,Aktiver teksturert visning,Włącz oteksturowanie mapy,Habilitar automapa texturizado,Permitir automapa texturizado,Activare mod texturat,Текстуры на автокарте,Омогући приказ текстура,Aktivera texturerad visning,Dokulu ekranı etkinleştir +Show item counts,AUTOMAPMNU_SHOWITEMS,,,,Počet předmětů,Vis tællinger af emner,Zeige Gegenstandsanzahl,,Montri nombron de objektoj,Mostrar conteo de objetos,,Näytä esineiden lukumäärä,Afficher compte d'objets,Tárgy számláló mutatása,Mostra il conteggio degli oggetti,アイテム数 表示,주운 아이템의 갯수를 표시,Toon artikeltellingen,Vis antall elementer,Pokaż liczbę przedmiotów,Exibir contagem de itens,,Afișare numărătoare obiecte,Количество предметов,Прикажи бројач за предмете,Visa antal objekt,Öğe sayılarını göster +Show monster counts,AUTOMAPMNU_SHOWMONSTERS,,,,Počet příšer,Vis monstertællinger,Zeige Monsteranzahl,,Montri nombron de monstroj,Mostrar conteo de monstruos,,Näytä hirviöiden lukumäärä,Afficher compte de monstres,Szörny számláló mutatása,Mostra il conteggio dei mostri,モンスター数 表示,죽인 적의 횟수 표시,Toon monstertellingen,Vis antall monster,Pokaż liczbę potworów,Exibir contagem de monstros,,Afișare numărătoare monștri,Количество монстов,Прикажи бројач за чудовишта,Visa antal monster,Canavar sayılarını göster +Show secret counts,AUTOMAPMNU_SHOWSECRETS,,,,Počet skrýší,Vis hemmelige tællinger,Zeige Geheimnisanzahl,,Montri nombron de sekretoj,Mostrar conteo de secretos,,Näytä salojen lukumäärä,Afficher compte de secrets,Rejtekhely számláló mutatása,Mostra il conteggio dei segreti,シークレット数 表示,밝힌 비밀의 수 표시,Toon geheime tellingen,Vis hemmelige tellinger,Pokaż liczbę sekretów,Exibir contagem de segredos,,Afișare numărătoare secrete,Количество тайников,Прикажи бројач за тајне,Visa antalet hemligheter,Gizli sayıları göster +Show time elapsed,AUTOMAPMNU_SHOWTIME,,,,Uplynulý čas na mapě,Vis den forgangne tid,Zeige vergangene Zeit,,Montri pasintan tempon,Mostrar tiempo transcurrido,,Näytä kulunut aika,Afficher temps passé,Eltöltött idő mutatása,Mostra il tempo trascorso,経過時間 表示,경과한 시간 표시,Verstreken tijd tonen,Vis medgått tid,Pokaż ile czasu upłynęło,Exibir tempo decorrido,,Afișare timp petrecut pe hartă,Прошедшее время,Прикажи протекло време,Visa förfluten tid,Geçen süreyi göster +Show total time elapsed,AUTOMAPMNU_SHOWTOTALTIME,,,,Celkový uplynulý čas,"Vis den samlede tid, der er gået",Zeige Gesamtzeit,,Montri tutan pasintan tempon,Mostrar tiempo total transc.,,Näytä yhteensä kulunut aika,Afficher total de temps passé,Teljes eltelt idő mutatása,Mostra il tempo totale trascorso,統計時間 表示,누적 경과한 시간 표시,Toon de totale verstreken tijd,Vis total tid som har gått,"Pokaż całkowity czas, który upłynął",Exibir tempo total decorrido,,Afișare timp total petrecut în joc,Общее время,Прикажи укупно протекло време,Visa total tid som förflutit,Geçen toplam süreyi göster +Show secrets on map,AUTOMAPMNU_MAPSECRETS,,,,Zobrazit skrýše,Vis hemmeligheder på kortet,Zeige Geheimnisse auf der Karte,,Montri sekretojn sur mapo,Mostrar secretos en el mapa,,Näytä salat kartalla,Afficher secrets sur carte,Rejtekhelyek mutatása a pályán,Mostra i segreti nella mappa,シークレットを地図に表示,맵의 비밀을 표시,Toon geheimen op de kaart,Vis hemmeligheter på kartet,Pokaż sekrety na mapie,Exibir segredos no mapa,,Afișare secrete,Тайники на карте,Прикажи тајне на аутомапи,Visa hemligheter på kartan,Haritada sırları göster +Show map label,AUTOMAPMNU_SHOWMAPLABEL,,,,Zobrazit název mapy,Vis kortmærke,Zeige Levelnamen,,Montri mapetikedon,Mostrar etiqueta del mapa,,Näytä tason tunniste,Afficher label de carte,Pályacím mutatása,Mostra le etichette della mappa,マップ名 表示,맵의 이름 표시,Toon kaartlabel,Vis kartetikett,Pokaż etykietę mapy,Exibir etiqueta do mapa,,Afișare etichetă hartă,Название карты,Прикажи ознаку мапе,Visa kartans etikett,Harita etiketini göster +Draw map background,AUTOMAPMNU_DRAWMAPBACK,,,,Pozadí mapy,Tegne kortbaggrund,Zeige Kartenhintergrund,,Desegni mapfondon,Dibujar fondo de mapa,,Piirrä tason tausta,Afficher fond d'écran carte,Térkép háttér kirajzolása,Mostra lo sfondo della mappa,マップの背景 描写,맵의 배경 출력,Teken de achtergrond van de kaart,Tegn kartbakgrunn,Rysuj tło mapy,Desenhar fundo do mapa,,Afișare fundal hartă,Отображение фона автокарты,Нацртај позадину мапе,Rita kartans bakgrund,Harita arka planı çizme +Show keys (cheat),AUTOMAPMNU_SHOWKEYS,,,,Zobrazení klíčů (podvod),Vis nøgler (snyd),Zeige Schlüssel (Cheat),,Montri klavojn (trompo),Mostrar llaves (truco),,Näytä avaimet (huijauskeino),Afficher les clés (cheat),Kulcsok mutatása,Mostra le chiavi (cheat),鍵 表示(チート時),키를 표시 (치트),Toon sleutels (valsspeler),Vis nøkler (juks),Pokaż klucze (oszustwo),Exibir chaves (trapaça),,Afișare chei (trișare),Отображение ключей (чит-коды),Прикажи кључеве (чит),Visa nycklar (fusk),Tuşları göster (hile) +Show trigger lines,AUTOMAPMNU_SHOWTRIGGERLINES,,,,Zobrazení aktivujících čar,Vis trigger-linjer,Zeige Auslöserlinien,,Montri baskulliniojn,Mostrar líneas de activación,,Näytä laukaisinviivat,Afficher lignes d'action,Trigger vonalak mutatása,Mostra le linee d'attivazione,トリガーライン 表示,트리거 선을 표시,Triggerlijnen tonen,Vis utløserlinjer,Pokaż linie przełączników,Exibir linhas de ativação,,Afișare linii declanșatoare,Отображение спусковых линий,Прикажи триггер линије,Visa utlösningslinjer,Tetik çizgilerini göster +Show things as sprites,AUTOMAPMNU_SHOWTHINGSPRITES,,,,Zobrazení objektů jako spritů,Vis ting som sprites,Zeige Dinge als Sprites,,Montri objektojn kiel mov-rastrumojn,Mostrar cosas como sprites,,Näytä oliot spriteinä,Afficher objets comme sprites,Tárgyak sprite-ként megjelenítése,Mostra gli oggetti come sprite,thingsのスプライト表示,물체를 스프라이트로 표시,Toon dingen als sprites,Vis ting som sprites,Pokaż rzeczy jako sprite'y,Exibir objetos como sprites,,Afișare obiecte drept sprite,Отображение спрайтов объектов,Прикажи ствари као спрајтове,Visa saker som sprites,Nesneleri sprite olarak gösterme +Overlay portals,AUTOMAPMNU_PTOVERLAY,,,,Překrývat portály,Overlay portaler,Überlagere Portale,,Surmeti portalojn,Sobreponer portales,,Projisoi portaalit,Superposer les portails,Overlay portálok,Sovrapponi i portali,オーバーレイ ポータルズ,포탈을 오버레이,Overlappende portalen,Overlegg portaler,Nałóż portale,Sobreposição de portais,,Acoperire portaluri,Порталы в прозрачном режиме,Провидни портали,Överlagra portaler,Yerleşim portalları +Empty space margin,AUTOMAPMNU_EMPTYSPACEMARGIN,,,,Práh prázdného prostoru,Tomrumsmargin,Breite des Randes,,Malplena spacia marĝeno,Margen de espacio vacío,,Tyhjän reunan leveys,Marge d'espace vide,Üres hely szegély,Margine dello spazio vuoto,空間の余白,빈공간 여백,Breedte van de rand,Tøm mellomromsmargen,Opróżnij margines przestrzeni,Margem de espaço vazio,,Margine spațiu gol,Край автокарты,Празна маргина,Marginal för tomt utrymme,Boş alan marjı +Mark font,AUTOMAPMNU_MARKFONT,,,,Písmo značek,Marker skrifttype,Zeichensatz für Markierungen,,Marki tiparon,Fuente para marcas,,Karttamerkkien fontti,Police Marqueur,Jelzés betűtípus,Font del segnaposto,マークフォント,미니맵 마킹 폰트,Font voor markers,Merk skrifttype,Czcionka oznaczeń,Fonte das marcações,,Font marcaj,Шрифт отметок,Фонт ознака,Markera typsnitt,Mark yazı tipi +Mark color,AUTOMAPMNU_MARKCOLOR,,,,Barva značek,Markere farve,Farbe für Markierungen,,Marki koloron,Color de las marcas,,Karttamerkkien väri,Couleur Marqueur,Jelzés szín,Colore del segnaposto,マーク色,미니맵 마킹 색상,Markeer kleur,Merk farge,Kolor oznaczeń,Cor das marcações,,Culoare marcaj,Цвет отметок,Боја ознака,Markera färg,Renk işaretle +Set mark,MAPCNTRLMNU_SETMARK,,,,Umístit značku,Indstille mærke,Setze Markierung,,Meti markon,Fijar marca,,Aseta merkki,Placer repère,Jelzés beállítása,Aggiungi segnaposto,マークを置く,마크 추가,Markering instellen,Sett merke,Ustaw znacznik,Posicionar marcação,,Marcare,Поставить отметку,Постави ознаку,Ställ in märket,İşareti ayarla +Clear mark,MAPCNTRLMNU_CLEARMARK,,,,Smazat značky,Slet markering,Lösche Markierung,,Forigi markon,Limpiar marca,,Pyyhi merkit,Enlever repères,Jelzések törlése,Pulisci il segnaposto,マーククリア,마크 삭제,Duidelijke markering,Fjern merke,Usuń znacznik,Limpar marcação,,Ștergere marcaj,Убрать отметку,Уклони ознаку,Rensa markeringen,Açık işaret +,,Scoreboard,,,,,,,,,,,,,,,,,,,,,,,,, +Scoreboard Options,DSPLYMNU_SCOREBOARD,,,,Tabulka skóre,Indstillinger for resultattavlen,Punktetabellenoptionen,,Poentotabulo-Agordoj,Opciones de marcador,,Pistetauluasetukset,Options Tableau des Scores,Eredményjelző beállítások,Opzioni tabella punteggio,スコアボード オプション,점수창 설정,Scorebord opties,Alternativer for resultattavlen,Opcje Tablicy Wyników,Opções de Tela de Pontuação,,Opțiuni Tabelă de Marcaj,Таблица очков,Табеларне подешавања,Alternativ för resultattavlan,Skorbord Seçenekleri +Scoreboard Options,SCRBRDMNU_TITLE,,,,Nastavení tabulky skóre,Indstillinger for resultattavlen,Punktetabellenoptionen,,Poentotabulo-Agordoj,Opciones de marcador,,Pistetauluasetukset,Tableau des Scores,Eredményjelző beállítások,Opzioni per la tabella punteggio,スコアボード オプション,점수판 설정,Scorebord opties,Alternativer for resultattavlen,Opcje Tablicy Wyników,Opções de Tela de Pontuação,Opções do Ecrã de Pontuação,Setări Tabelă de Marcaj,Настройки таблицы очков,Подешавања бодовања,Alternativ för resultattavlan,Skorbord Seçenekleri +Cooperative Options,SCRBRDMNU_COOPERATIVE,,,,Kooperativní mód,Samarbejdsmuligheder,Kooperativ-Optionen,,Kooperativo-Agordoj,Opciones de cooperativo,,Yhteispeliasetukset,Options Mode Coop,Együttműködő beállítása,Opzioni per il gioco cooperativo,協力モードの設定,코옵 설정,Coöperatieve Opties,Samarbeidsalternativer,Opcje Kooperacji,Opções de Jogo Cooperativo,,Setări Mod Cooperativ,Настройки для команд,Подешавања сарадње,Alternativ för samarbete,Kooperatif Seçenekleri +Enable Scoreboard,SCRBRDMNU_ENABLE,,,,Povolit tabulku skóre,Aktiver resultattavle,Punktetabelle aktiv,,Ŝalti Poentotabulon,Activar marcador,,Ota käyttöön pistetaulu,Activer Tableau des Scores,Eredményjelző bekapcsolása,Abilita la tabella punteggio,スコアボード表示,점수판 허용,Scorebord inschakelen,Aktiver resultattavle,Zezwól na Tablicę Wyników,Habilitar Tela de Pontuação,Permitir Ecrã de Pontuação,Activare Tabelă de Marcaj,Включить таблицу очков,Омогући бодовање,Aktivera resultattavlan,Skor Tablosunu Etkinleştir +Header Color,SCRBRDMNU_HEADERCOLOR,,,Header Colour,Barva hlavičky,Overskriftsfarve,Kopfzeilenfarbe,,Kapokoloro,Color de cabecera,,Otsikon väri,Couleur du Titre,Fejléc szín,Colore della testata,ヘッダー色,헤더의 색깔,Kleur koptekst,Farge på topptekst,Kolor Nagłówka,Cor de Cabeçalho,,Culoare Antet,Цвет заголовка,Боја заглавља,Färg på rubriken,Başlık Rengi +Your Player Color,SCRBRDMNU_YOURCOLOR,,,Your Player Colour,Barva tvého hráče,Din spillerfarve,Deine Spielerfarbe,,Via ludantkoloro,Color de tu jugador,,Pelaajasi väri,Votre couleur,Játékos színe,Colore del giocatore 'Tu',自分の色,플레이어의 색깔,Uw Spelerskleur,Din spillerfarge,Twoje Kolory,Cor do Seu Jogador,Cor do teu Jogador,Culoarea Jucătorului Tău,Ваш цвет,Боја твога играча,Din spelares färg,Oyuncu Renginiz +Other Players' Color,SCRBRDMNU_OTHERPLAYERCOLOR,,,Other Players' Colour,Barva ostatních hráčů,Andre spilleres farve,Andere Spielerfarbe,,Koloro de aliaj ludantoj,Color de otros jugadores,,Muiden pelaajien väri,Couleur des autres joueurs,Más játékosok színe,Colore degli altri giocatori,他者の色,다른 플레이어들의 색깔,Andere spelerskleur,Andre spilleres farge,Kolory Innych Graczy,Cor de Outros Jogadores,Cor dos Outros Jogadores,Culorile Celorlalți Jucători,Цвет других игроков,Боја другог играча,Andra spelares färg,Diğer Oyuncuların Rengi +Deathmatch Options,SCRBRDMNU_DEATHMATCH,,,,Deathmatch,Indstillinger for Deathmatch,Deathmatch-Optionen,,Mortmaĉo-Agordoj,Opciones modo a muerte,,Kuolonotteluasetukset,Options Deathmatch,Deathmatch Beállítások,Opzioni deathmatch,デスマッチの設定,데스매치 설정,Deathmatch opties,Deathmatch-alternativer,Opcje Deathmatchu,Opções de Deathmatch,,Setări Deathmatch,Настройки боя насмерть,Детмеч подешавања,Alternativ för Deathmatch,Ölüm Maçı Seçenekleri +Team Deathmatch Options,SCRBRDMNU_TEAMDEATHMATCH,,,,Týmový deathmatch,Indstillinger for Team Deathmatch,Team-Deathmatch-Optionen,,Teamo-Mortmaĉo-Agordoj,Opciones modo a muerte por equipos,,Joukkuekuolonotteluasetukset,Options Deathmatch en équipe,Team Deathmatch Beállítások,Opzioni deathmatch a squadra,チームデスマッチの設定,팀 데스매치 설정,Team Deathmatch Opties,Lag Deathmatch-alternativer,Opcje Drużynowego Deathmatchu,Opções de Deathmatch de Equipe,Opções de Deathmatch de Equipa,Setări Deathmatch în Echipă,Настройки командного боя насмерть,Тимски детмеч подешавања,Alternativ för Team Deathmatch,Takım Ölüm Maçı Seçenekleri +,,Alt HUD,,,,,,,,,,,,,,,,,,,,,,,,, +Alternative HUD,ALTHUDMNU_TITLE,,,,Alternativní HUD,Alternativ HUD,Alternatives HUD,,Alternativa HUD,HUD alternativo,,Vaihtoehtoinen tilanäyttö,ATH Alternatif,Alternatív HUD,HUD alternativo,オルタナティブHUD,대체 HUD,Alternatieve HUD,Alternativ HUD,Alternatywny HUD,HUD alternativo,,Interfață pe Timp de Joc Alternativă,Альтернативное отображение информации,Алтернативни HUD,Alternativ HUD,Alternatif HUD +Enable alternative HUD,ALTHUDMNU_ENABLE,,,,Povolit alternativní HUD,Aktiver alternativt HUD,Alternatives HUD eingeschaltet,,Ŝalti alternativan HUD,Activar HUD alternativo,,Ota käyttöön vaihtoehtoinen tilanäyttö,Activer l'ATH Alternatif,Alternatív HUD bekapcsolása,Abilita HUD alternativo,オルタナティブHUD有効,대체 HUD 사용,Alternatieve HUD inschakelen,Aktiver alternativ HUD,Włącz alternatywny HUD,Habilitar HUD alternativo,,Activează Interfața pe Timp de Joc Alternativă,Включить альтернативное отображение,Укључи алтернативни HUD,Aktivera alternativ HUD,Alternatif HUD'yi etkinleştirin +Show secret count,ALTHUDMNU_SHOWSECRETS,,,,Zobrazit počet skrýší,Vis hemmelig optælling,Zeige Geheimniszähler,,Montri sekretonombron,Mostrar cont. de secretos,,Näytä salojen lukumäärä,Afficher compteur de secrets,Rejtekhely számláló mutatása,Mostra il conteggio dei segreti,シークレット数 表示,비밀 수 표시,Toon het aantal geheimen,Vis hemmelig antall,Pokaż liczbę sekretów,Exibir contagem de segredos,,Afișează numărul secretelor,Отображение обнаруженных тайников,Прикажи количину тајна,Visa hemligt antal,Gizli sayımı göster +Show monster count,ALTHUDMNU_SHOWMONSTERS,,,,Zobrazit počet příšer,Vis monstertælling,Zeige Monsterzähler,,Montri monstronombron,Mostrar cont. de monstruos,,Näytä hirviöiden lukumäärä,Afficher compteur de monstres,Szörny számláló mutatása,Mostra il conteggio dei mostri,モンスター数 表示,적 개체 수 표시,Toon het aantal monsters,Vis antall monstre,Pokaż liczbę zabójstw,Exibir contagem de monstros,,Afișează numărul de monștri,Отображение количества монстров,Прикажи количину чудовишта,Visa antalet monster,Canavar sayısını göster +Show item count,ALTHUDMNU_SHOWITEMS,,,,Zobrazit počet předmětů,Vis optælling af genstande,Zeige Gegenstandszähler,,Montri objektonombron,Mostrar cont. de objetos,,Näytä esineiden lukumäärä,Afficher compteur d'objets,Tárgy számláló mutatása,Mostra il conteggio degli oggetti,アイテム数の表示,아이템 수 표시,Toon het aantal items,Vis antall gjenstander,Pokaż liczbę przedmiotów,Exibir contagem de itens,,Afișează numărul de obiecte,Отображение количества предметов,Прикажи количину предмета,Visa antalet föremål,Öğe sayısını göster +Show stamina and accuracy,ALTHUDMNU_SHOWSTATS,,,,Zobrazit výdrž a přesnost,Vis udholdenhed og nøjagtighed,Zeige Kondition und Genauigkeit,,Montri viglecon kaj akuratecon,Mostrar resistencia/precisión,,Näytä puhti ja tarkkuus,Afficher Endurance et Précision,Állóképesség és pontosság mutatása,Mostra stamina e accuratezza,スタミナと精度の表示,스테미나와 정확도를 표시,Toon uithoudingsvermogen en nauwkeurigheid,Vis utholdenhet og nøyaktighet,Pokaż wytrzymałość i precyzję,Exibir resistência e precisão,,Afișează rezistența fizică si acuratețea,Отображение выносливости и точности,Прикажи издржљивост и прецизност,Visa uthållighet och noggrannhet,Dayanıklılık ve doğruluk gösterin +Show berserk,ALTHUDMNU_SHOWBERSERK,,,,Zobrazit berserk,Vis berserk,Zeige Berserk,,Montri frenezecon,Mostrar berserker,,Näytä raivo,Afficher Berserk,Berserk mutatása,Mostra il berserk,バーサーク表示,버서크 아이템을 표시,Toon berserk,Vis berserk,Pokaż szał,Exibir berserk,,Afișează pachetul de forță mărită,Отображение берсерка,Прикажи берсерк,Visa berserk,Berserk'i göster +Show weapons,ALTHUDMNU_SHOWWEAPONS,,,,Zobrazit zbraně,Vis våben,Zeige Waffen,,Montri armojn,Mostrar armas,,Näytä aseet,Afficher Armes,Fegyverek mutatása,Mostra le armi,武器表示,무기들을 표시,Toon wapens,Vis våpen,Pokaż bronie,Exibir armas,,Afișează armele,Отображение оружия,Прикажи оружја,Visa vapen,Silahları göster +Show ammo for,ALTHUDMNU_SHOWAMMO,,,,Zobrazit munici pro,Vis ammunition for,Zeige Munition,,Montri municion por,Mostrar munición para,,Näytä ammukset aseelle,Afficher Munitions pour,Ammo mutatása a,Mostra le munizioni per,弾薬等の表示,탄약을 표시,Toon munitie voor,Vis ammunisjon for,Pokaż amunicję dla,Exibir munição para,,Afișează muniția pentru,Отображение патронов для,Прикажи муниције за,Visa ammunition för,Cephane göster +Show time,ALTHUDMNU_SHOWTIME,,,,Zobrazit čas,Vis tid,Zeige Zeit,,Montri tempon,Mostrar tiempo,,Näytä aika,Afficher temps niveau,Idő mutatása,Mostra il tempo,時間の表示,시간 표시,Toon tijd,Vis tid,Pokaż czas,Exibir tempo,,Afișează timpul,Отображение времени,Прикажи време,Visa tid,Gösteri zamanı +Time color,ALTHUDMNU_TIMECOLOR,,,Time colour,Barva času,Tidens farve,Zeit-Farbe,,Tempkoloro,Color del tiempo,,Ajan väri,Couleur du timer,Idő színe,Colore del tempo,時間の字色,시간 색상,Tijdskleur,Tid farge,Kolor czasu,Cor do tempo,,Culoare timp,Цвет времени,Боја времена,Tidens färg,Zaman rengi +Show network latency,ALTHUDMNU_SHOWLAG,,,,Zobrazit latenci sitě,Vis netværksforsinkelse,Zeige Netzwerk-Latenz,,Montri reto-respondotempon,Mostrar latencia de red,,Näytä verkon viive,Afficher latence réseau,Válaszidő mutatása,Mostra la latenza del network,ネットのラグ表示,내트워크 트래픽 표시,Toon netwerklatentie,Vis nettverksforsinkelse,Pokaż czas oczekiwania sieci,Exibir latência de rede,,Afișează perioada de întârziere a conexiunii,Отображение задержки сети,Прикажи кашњење мреже,Visa nätverksfördröjning,Ağ gecikmesini göster +Ammo display order,ALTHUDMNU_AMMOORDER,,,,Pořadí zobrazení munice,Visningsrækkefølge for ammunition,Munitionsreihenfolge,,Vidiga aranĝo de municio,Orden vista de munición,,Ammusten esitysjärjestys,Ordre d'affichage des munitions,Muníció típus rendezése,Ordine mostra delle munizioni,弾薬表示順,탄약 표시 순서,Volgorde van de munitieweergave,Rekkefølge for ammunisjonsvisning,Kolejność pokazywania amunicji,Ordem de exibição de munição,,Ordine afișare muniție,Порядок отображения боеприпасов,Редослед муниција,Ordning för visning av ammunition,Cephane teşhir düzeni +Red ammo display below %,ALTHUDMNU_AMMORED,,,,Červený indikátor munice pod %,Rød ammunitionsvisning under %,Rot für Munition unter %,,Ruĝa municividigo sub %,Porcent. de munición en rojo,,Punaiset ammukset ammusten alittaessa %,Compteur de munitions rouge sous,Piros muníció szín % alatt,Contatore delle munizioni di colore rosso sotto,弾薬の赤色表示%,적색 남은 탄약 밑에 표시,Rood munitieweergave onder %,Rød visning av ammunisjonsnivå under %,Wyświetl czerwoną amunicję pod ,Porcentagem de munição em vermelho até,Percentagem de munição em vermelho até,Muniția schimbă culoarea în roșu sub %,"Отображение боеприпасов красным ниже, %",Прикажи муниције црвеном испод %,Röd ammunition visas under %,Aşağıda kırmızı cephane göstergesi % +Yellow ammo display below %,ALTHUDMNU_AMMOYELLOW,,,,Žlutý indikátor munice pod %,Gul ammunitionsvisning under %,Gelb für Munition unter %,,Flava municividigo sub %,Porcent. de munición en amarillo,,Keltaiset ammukset ammusten alittaessa %,Compteur de munitions jaune sous,Sárga muníció szín % alatt,Contatore delle munizioni di colore giallo sotto,弾薬の黄色表示%,황색 남은 탄약 밑에 표시,Gele munitieweergave onder %,Gult ammunisjonsdisplay under %.,Wyświetl żółtą amunicję pod ,Porcentagem de munição em amarelo até,Percentagem de munição em amarelo até,Muniția schimbă culoarea în galben sub %,"Отображение боеприпасов жёлтым ниже, %",Прикажи муниције жутом испод %,Gul ammunition visas under %,Aşağıda sarı cephane göstergesi % +Red health display below,ALTHUDMNU_HEALTHRED,,,,Červený indikátor zdraví pod,Rødt sundhedsindikator under %,Rot für Gesundheit unter %,,Ruĝa sanvidigo sube,Porcent. de salud en rojo,,Punainen terveys terveyden alittaessa,Compteur de santé rouge sous,Piros életerő szín ezen szám alatt,Contatore della salute di colore rosso sotto,体力の赤色表示%,적색 체력 밑에 표시,Rood gezondheidsweergave beneden,Rød helsevisning under,Wyświetl czerwone zdrowie pod ,Porcentagem de saúde em vermelho até,Percentagem de saúde em vermelho até,Sănătatea schimbă culoarea în roșu sub %,"Отображение здоровья красным ниже, %",Прикажи здравље црвеном испод,Röd hälsoindikator nedanför,Aşağıdaki kırmızı sağlık göstergesi +Yellow health display below,ALTHUDMNU_HEALTHYELLOW,,,,Žlutý indikátor zdraví pod,Gul sundhedsindikator under %,Gelb für Gesundheit unter %,,Flava sanvidigo sube,Porcent. de salud en amarillo,,Keltainen terveys terveyden alittaessa,Compteur de santé jaune sous,Sárga életerő szín ezen szám alatt,Contatore della salute di colore giallo sotto,体力の黄色表示%,황색 체력 밑에 표시,Geel gezondheidsweergave beneden,Gul helsevisning nedenfor,Wyświetl żółte zdrowie pod ,Porcentagem de saúde em amarelo até,Percentagem de saúde em amarelo até,Sănătatea schimbă culoarea în galben sub %,"Отображение здоровья жёлтым ниже, %",Прикажи здравље жутом испод,Gul hälsoindikator nedanför,Aşağıdaki sarı sağlık göstergesi +Green health display below,ALTHUDMNU_HEALTHGREEN,,,,Zelený indikátor zdraví pod,Grønt sundhedsindikator under %,Grün für Gesundheit unter %,,Verda sanvidigo sube,Porcent. de salud en verde,,Vihreä terveys terveyden alittaessa,Compteur de santé vert sous,Zöld életerő szín ezen szám alatt,Contatore della salute di colore verde sotto,体力の緑色表示%,녹색 체력 밑에 표시,Groen gezondheidsweergave beneden,Grønn helsevisning under,Wyświetl zielone zdrowie pod ,Porcentagem de saúde em verde até,Percentagem de saúde em verde até,Sănătatea schimbă culoarea în verde sub %,"Отображение здоровья зелёным ниже, %",Прикажи здравље зеленом испод,Grön hälsoindikator nedan,Aşağıdaki yeşil sağlık göstergesi +Red armor display below,ALTHUDMNU_ARMORRED,,,Red armour display below,Červený indikátor brnění pod,Rødt panser display under %,Rot für Panzerung unter %,,Ruĝa kirasvidigo sube,Porcent. de blindaje en rojo,,Punainen panssari panssarin alittaessa,Compteur d' armure rouge sous,Piros páncél szín ezen szám alatt,Contatore dell'armatura di colore rosso sotto,防具の赤色表示%,적색 아머 밑에 표시,Rood pantserweergave beneden,Visning av rød rustning under,Wyświetl czerwony pancerz pod ,Porcentagem de armadura em vermelho até,Percentagem de armadura em vermelho até,Armura schimbă culoarea în galben sub %,"Отображение брони красным ниже, %",Прикажи оклоп црвеном испод,Röd rustning visas nedan,Kırmızı zırh ekranı aşağıda +Yellow armor display below,ALTHUDMNU_ARMORYELLOW,,,Yellow armour display below,Žlutý indikátor brnění pod,gul panser under displayet under %,Gelb für Panzerung unter %,,Flava kirasvidigo sube,Porcent. de blindaje en amarillo,,Keltainen panssari panssarin alittaessa,Compteur d' armure jaune sous,Sárga páncél szín ezen szám alatt,Contatore dell'armatura di colore giallo sotto,防具の黄色表示%,황색 아머 밑에 표시,Geel pantserweergave beneden,Visning av gul rustning under,Wyświetl żółty pancerz pod ,Porcentagem de armadura em amarelo até,Percentagem de armadura em amarelo até,Armura schimbă culoarea în galben sub %,"Отображение брони жёлтым ниже, %",Прикажи оклоп жутом испод,Gul rustning visas nedan,Aşağıdaki sarı zırh ekranı +Green armor display below,ALTHUDMNU_ARMORGREEN,,,Green armour display below,Zelený indikátor brnění pod,grønt panser display under %,Grün für Panzerung unter %,,Verda kirasvidigo sube,Porcent. de blindaje en verde,,Vihreä panssari panssarin alittaessa,Compteur d' armure bleu sous,Zöld páncél szín ezen szám alatt,Contatore dell'armatura di colore verde sotto,防具の緑色表示%,녹색 아머 밑에 표시,Groen pantserweergave beneden,Visning av grønn rustning under,Wyświetl zielony pancerz pod ,Porcentagem de armadura em verde até,Percentagem de armadura em verde até,Armura schimbă culoarea în verde sub %,"Отображение брони зелёным ниже, %",Прикажи оклоп зеленом испод,Grön rustning visas nedan,Aşağıdaki yeşil zırh ekranı +Alternative Automap HUD,ALTHUDMNU_AUTOMAPHUD,,,,Alternativní HUD automapy,Alternativ Automap HUD,Alternatives Automap HUD,,Alternativa HUD de aŭtomata mapo,HUD alternativo del automapa,,Vaihtoehtoinen automaattikartan tilanäyttö,ATH Alternatif pour carte,Alternatív Automap HUD,HUD automappa alternativo,オルタナティブ オートマップHUD,대체 오토맵 HUD,Alternatieve Automap HUD,Alternativ Automap HUD,Alternatywny HUD mapy,HUD alternativo de automapa,,Hartă Computerizată Alternativă,Альтернативный интерфейс на автокарте,Алтернативни HUD за аутомапу,Alternativ automap HUD,Alternatif Automap HUD +Map title color,ALTHUDMNU_TITLECOLOR,,,Map title colour,Barva názvu levelu,Farve på korttitel,Farbe für Levelnamen,,Maptitolo-koloro,Color del título del mapa,,Tason nimen väri,Couleur titre du niveau,Pálya cím szín,Colore titolo mappa,マップ名の色,맵 제목 색깔,Kleur kaarttitel,Farge på karttittel,Kolor nazwy mapy,Cor do título do fase,Cor do título do nível,Culoare titlu hartă,Цвет названия уровня,Боја назива нивоа,Färg på kartans titel,Harita başlık rengi +Map time color,ALTHUDMNU_MAPTIMECOLOR,,,Map time colour,Barva času levelu,Farve på kortets tid,Farbe für Level-Zeit,,Maptempo-koloro,Color del tiempo del mapa,,Tason ajan väri,Couleur temps du niveau,Pálya idő szín,Colore tempo mappa,経過時間の色,맵 시간 색깔,Kleur kaarttijd,Kartets tidsfarge,Kolor czasu na mapie,Cor do tempo da fase,Cor do tempo do nível,Culoare timp petrecut pe hartă,Цвет времени для уровней,Боја времена на нивоу,Färg för kartans tid,Harita zaman rengi +Hub time color,ALTHUDMNU_HUBTIMECOLOR,,,Hub time colour,Barva času hubu,Farve på hub-tid,Farbe für Hub-Zeit,,Nabtempo-koloro,Color del tiempo del nodo,,Tasokokoelman ajan väri,Couleur temps du hub,Csomópont idő szín,Colore tempo hub di mappe,区間経過時間の色,허브 시간 색깔,Kleur hubtijd,Farge for knutepunkttid,Kolor czasu w hubie,Cor do tempo no HUD,,Culoare timp petrecut în hub,Цвет времени для хабов,Боја времена на хабу,Färg för navets tid,Hub zaman rengi +Total time color,ALTHUDMNU_TOTALTIMECOLOR,,,Total time colour,Barva celkového času,Farve for samlet tid,Farbe für Gesamtzeit,,Tuttempo-koloro,Color del tiempo total,,Kokonaisajan väri,Couleur temps total,Teljes idő szín,Colore tempo totale,合計経過時間の色,누적 경과한 시간 색깔,Kleur totale tijd,Farge for total tid,Kolor całkowitego czasu,Cor do tempo total,,Culoare timp total,Цвет общего времени,Боја укупног времена,Färg för total tid,Toplam zaman rengi +Coordinate color,ALTHUDMNU_COORDINATECOLOR,,,Coordinate colour,Barva souřadnic,Koordinat farve,Farbe für Koordinaten,,Kunordigi koloron,Color de coordenadas,,Koordinaattien väri,Couleur coordonnées,Koordináló szín,Colore coordinate,座標色,좌표 색깔,Kleur coördinaten,Koordinatfarge,Skoordynuj kolor,Cor das coordenadas,,Culoare coordonate,Цвет координат,Боја координата,Färg för koordinater,Koordinat rengi +Coordinate mode,ALTHUDMNU_COORDINATEMODE,,,,Režim souřadnic,Koordinattilstand,Koordinatenmodus,,Kunordigi modon,Modo de coordenadas,,Koordinaattitila,Mode coordonnées,Koordináló mód,Modalità coordinate,座標モード,좌표 모드,Coördinatiemodus,Koordinat-modus,Skoordynuj tryb,Modo de coordenada,,Mod coordonate,Координаты игрока,Мод координата,Koordinatläge,Koordinat modu +Statistics name color,ALTHUDMNU_STATSNAMECOLOR,,,Statistics name colour,Barva názvu statistik,Farve på statistiknavn,Farbe für Statistik-Namen,,Statistiknomo-koloro,Color del nombre de estadísticas,,Tilastotiedon nimen väri,Couleur nom des statistiques,Statisztika név szín,Colore nome statistica,統計名の色,통계표 이름 색상,Kleur statistiekennaam,Farge på statistikknavn,Kolor nazw statystyk,Cor do nome das estatísticas,,Culoare nume statistici,Цвет имён в статистике,Боја назива статистика,Färg för statistiknamn,İstatistik adı renk +Statistics color,ALTHUDMNU_STATSCOLOR,,,Statistics colour,Barva statistik,Statistik farve,Farbe für Statistik-Nummern,,Statistiko-koloro,Color de las estadísticas,,Tilastotiedon väri,Couleur statistiques,Statisztika szín,Colore contatore statistica,統計の色,통계표 색상,Kleur statistieken,Statistikk farge,Kolor statystyk,Cor das estatísticas,,Culoare statistici,Цвет статистики,Боја статистика,Färg för statistik,İstatistik renk +,,Display (game related),,,,,,,,,,,,,,,,,,,,,,,,, +Rendering Interpolation,DSPLYMNU_CAPFPS,,,,Interpolace vykreslování,Interpolering af rendering,Renderinterpolation,,Bildigo-Interpolado,Interpolación de renderizado,,Hahmonnuksen interpolointi,Interpolation du rendu,Render animáció simítás,Interpolazione grafica,レンダリング補間,프레임 제한,Interpolatie renderen,Gjengivelse av interpolasjon,Interpolacja Renderowania,Interpolação de renderização,,Interpolare Imagine,Сглаживание обработки,Интерполација рендеринга,Rendering Interpolering,Rendering Enterpolasyonu +Transparency render mode,DSPLYMNU_BLENDMETHOD,,,,Režim vykreslování průhlednosti,Gennemsigtighedstilstand,Transparenzmodus,,Travidebleco-bildigo-reĝimo,Modo de renderizado de transparencia,,Läpinäkyvyyden hahmonnustila,Mode de Rendu transparence,Átlászóság render mód,Modalità della resa grafica della trasparenza,レンダリング透過モード,투명도 표시 모드,Transparantie render modus,Gjengivelsesmodus for gjennomsiktighet,Tryb renderowania przezroczystości,Modo de renderiz. de transparência,,Mod Transparență,Режим обработки прозрачности,Режим рендеринга транспарентности,Återgivning med transparens,Şeffaflık render modu +Screen wipe style,DSPLYMNU_WIPETYPE,,,,Styl přechodů,Skærmens aftørringsstil,Bildschirmwechseleffekt,,Stilo de ekranviŝo,Transición de pantalla,,Ruudun pyyhkiytymistyyli,Style de Fondu d'écran,Képernyőtörlődés módja,Stile della pulizia dello schermo,スクリーンワイプモード,화면 전환 방식,Schermveegstijl,Stil for skjermtørking,Styl przejścia ekranu,Tipo de transição de tela,Tipo de transição de ecrã,Stil ștergere imagine,Эффект плавной смены экранов,Ефект брисања екрана,Stil för skärmtorkning,Ekran silme stili +Show ENDOOM screen,DSPLYMNU_SHOWENDOOM,,,,Zobrazit ENDOOM obrazovku,Vis ENDOOM-skærm,Zeige ENDOOM,,Montri ENDOOM-ekranon,Mostrar pantalla ENDOOM,,Näytä ENDOOM-ruutu,Montrer la fenêtre ENDOOM,ENDOOM képernyő mutatása,Mostra la schermata ENDOOM,ENDOOM画面を表示,종료화면 표시,Toon ENDOOM scherm,Vis ENDOOM-skjerm,Pokaż ekran ENDOOM,Exibir tela ENDOOM,,Afișare fereastră ENDOOM,Показать экран ENDOOM,Прикажи ENDOOM екран,Visa ENDOOM-skärm,ENDOOM ekranını göster +Blood Flash Intensity,DSPLYMNU_BLOODFADE,,,,Intenzita bliknutí při zranění,Blodblinkintensitet,Intensität für Bluteffekt,,Egeco de sango-ekbrilo,Intensidad del destello al ser atacado,,Verivälähdyksen voimakkuus,Intensité du flash dommages,Sebzéskor villanás mértéke,Intensità Bagliore Sangue,血粉の濃度,피격 표시 강도,Intensiteit van de bloedflitser,Intensitet for blodblits,Intensywność Efektów Krwi,Intensidade de Flash de Sangue,,Intensitate strălucire sânge,Интенсивность вспышки при ранении,Интензивност треперења током повређивања,Intensitet av blodblixt,Kan Flaş Yoğunluğu +Pickup Flash Intensity,DSPLYMNU_PICKUPFADE,,,,Intenzita bliknutí při sebrání předmětu,Intensitet for optageeffekt,Intensität für Aufnehmen-Effekt,,Egeco de prenado-ekbrilo,Intensidad del destello al coger algo,Intensidad del destello al tomar un objeto,Poimintavälähdyksen voimakkuus,Intensité du flash objets,Fegyver felvételekor villanás mértéke,Intensità Bagliore Raccolta,取得の視界色濃度,습득 표시 강도,Intensiteit van de oppakflitser,Intensitet av opptaksblits,Intesnywność Efektów Podnoszenia Przedmiotów,Intensidade de Flash ao Pegar Itens,,Intensitate strălucire la ridicarea obiectelor,Интенсивность вспышки при подборе,Интензивност треперења током купљења,Intensitet av pickupblink,Pikap Flaş Yoğunluğu +Underwater Blend Intensity,DSPLYMNU_WATERFADE,,,,Intenzita zbarvení pod vodou,Undervandsblinkintensitet,Intensität für Unterwasser-Effekt,,Egeco de Subakva Mikso,Intensidad Color Sumergido,Intensidad Color Submarino,Vedenalaissumennuksen voimakkuus,Intensité du fondu sous l'eau,Vízalatti keverődés mértéke,Intensità Blend sott'acqua,水中反響音の濃度,수중 효과 강도,Intensiteit kleurvermenging onder water,Intensitet for undervannsblanding,Intensywność Efektów Pod Wodą,Intensidade de Efeito Debaixo d'Água,Intensidade de Efeito Debaixo de Água,Intensitate amestec culori subacvatice,Интенсивность эффекта под водой,Интензивност подводног треперења,Undervattensbländning Intensitet,Sualtı Karışım Yoğunluğu +Sky render mode,DSPLYMNU_SKYMODE,,,,Režim vykreslování oblohy,Himmel-renderingstilstand,Rendermodus für Himmel,,Ĉielo-bildigo-reĝimo,Modo de renderizado del cielo,,Taivaan hahmonnustila,Mode du rendu du Ciel,Égbolt render mód,Modalità resa grafica del cielo,空の表示方法,하늘 표시 모드,Luchtrendermodus,Modus for gjengivelse av himmel,Tryb renderowania nieba,Modo de renderização de céu,,Mod de vizualizare al cerului,Режим обработки неба,Режим рендеринга неба,Läge för rendering av himmel,Gökyüzü oluşturma modu +Linear skies,DSPLYMNU_LINEARSKY,,,,Lineární obloha,Lineære himmelstrøg,Lineare Himmel,,Linearaj ĉieloj,Cielo lineal,,Lineaariset taivaat,Ciel linéaire,Lineáris égboltok,Cieli lineari,空の歪み,선형 하늘,Lineaire lucht,Lineær himmel,Liniowe niebo,Céus lineares,,Cer rectiliniu,Линейное небо,Линеарна неба,Linjär himmel,Doğrusal gökyüzü +Fullbright overrides sector color,DSPLYMNU_GZDFULLBRIGHT,,,,Při plném jasu ignorovat barvu sektoru,Ignorer sektorfarve ved fuld lysstyrke,Ignoriere Sektorfarbe bei voller Helligkeit,,Plenbrileco tranpasas sektorkoloron,Brillo máximo anula color del sector,,Täyskirkkaat ohittavat sektorin värin,Fullbright ignore couleur secteur,Fullbright felülírja a szektor szinét,Luce piena sovrappone il colore del settore,明るさ最大時にsector color塗り替え,섹터 색상 최대밝기 우선화,Volledig helderheid overschrijft de sectorkleur,Fullbright overstyrer sektorfarge,Ignoruj kolor sektora przy pełnej jasności,Brilho máximo anula cor de setor,,Luminozitatea maximă suprascrie culoarea sectorului,Полная яркость замещает цвет сектора,Пуно осветљење премошћује боју сектора,Fullbright åsidosätter sektorfärg,Fullbright sektör rengini geçersiz kılar +Scale fuzz effect,DSPLYMNU_SCALEFUZZ,,,,Škálovat velikost fuzz efektu,Skala fuzz-effekt,Skaliere Fuzz-Effekt,,Skali barblano-efekton,Escala de efecto fuzz,,Skaalaa sumennustehostetta,Scaling de l'effet de bruit,Homályosodás effekt átméretezése,Scala l'effetto di fuzz,ファズエフェクトサイズ,반투명 효과 조정,Schaal fuzz effect,Skala fuzz-effekt,Skalowanie efektu szumu,Escala de efeito difuso,,Putere efect de strălucire,Масштабировать эффект шума,Повечавај шумни ефект,Skala fuzz-effekt,Ölçekli fuzz efekti +Use fuzz effect,DSPLYMNU_DRAWFUZZ,,,,Typ fuzz efektu,Brug fuzz-effekt,Benutze Fuzz-Effekt,,Uzi barblano-efekton,Usar efecto fuzz,,Käytä sumennustehostetta,Effet de bruit,Homályosodás effekt használata,Usa l'effetto di fuzz,ファズエフェクトを使用,반투명 효과 사용,Gebruik fuzz effect,Bruk fuzz-effekt,Użyj efektu szumu,Usar efeito difuso,,Mod efect de strălucire,Использовать эффект шума,Користи шумни ефект,Använd fuzz-effekt,Fuzz efekti kullanın +Classic Transparency,DSPLYMNU_OLDTRANS,,,,Klasická průhlednost,Klassisk gennemsigtighed,Klasssische Transparenz,,Klasika Travidebleco,Transparencia clásica,,Perinteinen läpinäkyvyys,Transparence classique,Klasszikus átlátszóság,Trasparenza classica,旧式の透明度,구형 투명도,Klassieke transparantie,Klassisk gjennomsiktighet,Klasyczna Przezroczystość,Transparência Clássica,,Transparență Clasică,Классическая прозрачность,Класична транспарентност,Klassisk genomskinlighet,Klasik Şeffaflık +Lost Soul translucency,DSPLYMNU_TRANSSOUL,,,,Průhlednost Ztracených duší,Fortabt sjæl-translucens,Transparenz für Verlorene Seelen,,Diafaneco de Perdita Animo,Traslucidez del Alma Errante,,Kadonneiden sielujen läpikuultavuus,Transparence des âmes perdues,Lost soul átlátszóság,Trasparenza anima errante,ロストソウルの透明度,로스트 소울 반투명도,Verloren Ziel doorschijnendheid,Lost Soul gjennomskinnelighet,Przezroczystość Zagubionych Dusz,Translucência da Alma Perdida,Translucidez da Alma Penada,Transparență Suflete Pierdute,Прозрачность потерянных душ,Транспарентност изгубљених душа,Lost Soul-translucens,Kayıp Ruh yarı saydamlığı +Use fake contrast,DSPLYMNU_FAKECONTRAST,,,,Použít falešný kontrast,Brug falsk kontrast,Benutze falschen Kontrast,,Uzi malveran kontraston,Usar falso contraste,,Käytä tekosävykkyyttä,Faux Contraste,Hamis kontraszt használata,Usa il falso contrasto,フェイクコントラストを使用,가명암 효과 사용,Gebruik vals contrast,Bruk falsk kontrast,Użyj sztuczny kontrast,Usar contraste falso,,Utilizare contrast fals,Имитация контрастного освещения стен,Користи фејк-контраст,Använd falsk kontrast,Sahte kontrast kullanın +Rocket Trails,DSPLYMNU_ROCKETTRAILS,,,,Kouř raket,Raketspor,Raketenschweife,,Raketospuroj,Rastro de cohetes,,Rakettivanat,Trainées des Roquettes,Rakéta füstnyomok,Scia del razzo,ロケットの軌跡,로켓 추진 효과,Raketsporen,Rakettspor,Wiązki Rakiet,Rastro de Foguete,Rasto dos Mísseis,Dâră Rachete,Дымовой след у ракет,Траг дима код ракета,Raketspår,Roket Parkurları +Blood Type,DSPLYMNU_BLOODTYPE,,,,Druh krve,Blodtype,Blut-Typ,,Sangotipo,Tipo de sangre,,Verityyli,Type de particules Sang,Vér fajta,Tipo di sangue,血の種類,혈흔 효과,Bloedtype,Blodtype,Typ Krwi,Tipo de Sangue,,Tip efecte sângeroase,Тип крови,Тип крви,Blodtyp,Kan Grubu +Bullet Puff Type,DSPLYMNU_PUFFTYPE,,,,Druh kouře nábojů,Kuglestød type,Pistolenrauch-Typ,,Tipo de Kuglopufo,Tipo de agujero de bala,,Luotien pöllähdystyyli,Type de particules Balles,Lövedék becsapódás fajtája,Tipo di sbuffo del proiettile,弾煙の種類,탄알 피격 효과,Kogelwolvertype,Bullet Puff Type,Typ Dymu,Tipo de Ricochete de Bala,,Tip efecte pentru gloanțe,Тип дыма от пуль,Тип рикошета,Kulavfallstyp,Mermi Puf Tipi +Number of particles,DSPLYMNU_MAXPARTICLES,,,,Množství částic,Antal partikler,Anzahl Partikel,,Nombro da partikloj,Número de partículas,,Hiukkasten lukumäärä,Nombre de particules,Részecskék száma,Numero di particelle,パーティクルの最大数,최대 입자 수,Aantal deeltjes,Antall partikler,Liczba cząsteczek,Número de partículas,,Număr particule,Количество частиц,Број честица,Antal partiklar,Parçacık sayısı +Number of decals,DSPLYMNU_MAXDECALS,,,,Množství decalů,Antal decals,Anzahl Trefferspuren,,Nombro da dekaloj,Número de calcomanías,,Siirtokuvien lukumäärä,Number de décalques,Lövésnyomok száma,Numero di decal,デカールの最大数,최대 데칼 수,Aantal stickers,Antall dekaler,Liczba kalk,Número de decalques,,Număr autocolante,Количество декалей,Број декала,Antal dekaler,Çıkartma sayısı +Show player sprites,DSPLYMNU_PLAYERSPRITES,,,,Zobrazit hráčovy sprity,Vis spiller sprites,Zeige Spieler-Sprites,,Montri ludanto-rastrumojn,Mostrar sprites del jugador,,Näytä pelaajaspritet,Montrer les sprites joueur,Játékos sprite-ok mutatása,Mostra gli sprite del giocatore,プレイヤーの武器の表示,1인칭 무기 표시,Toon speler sprites,Vis spillerens sprites,Pokaż sprite'y gracza,Exibir sprites do jogador,,Afișare arme,Отображение спрайтов игрока,Прикажи спрајтове играча,Visa spelarens sprites,Oyuncu sprite'larını göster +Death camera,DSPLYMNU_DEATHCAM,,,,Posmrtná kamera,Dødskamera,Todeskamera,,Mortkamerao,Cámara de muerte,,Kuolonkamera,Caméra 3ème pers à la mort,Halál kamera,Telecamera all'atto della morte,死亡時の三人称視点,사망 화면 표시,Doodscamera,Dødskamera,Kamera śmierci,Câmera de morte,Câmara da morte,Cameră de Deces,Вид от 3-го лица при смерти,Смртна камера,Dödskamera,Ölüm kamerası +Teleporter zoom,DSPLYMNU_TELEZOOM,,,,Zoom při teleportaci,Teleporter zoom,Teleporter Zoom,,Teleportila zomo,Zoom en teletransporte,,Kaukosiirrynnän kameran zoomaus ,Zoom sur téléportation,Teleporter ráközelítés,Zoom telecamera,テレポーター使用時のズーム,순간이동 효과,Teleporter zoom,Teleporter zoom,Przybliżenie teleportowania,Zoom de teletransporte,,Apropriere Cameră la Teleportare,Увеличение при телепортации,Зум током телепортације,Teleportörens zoom,Işınlayıcı yakınlaştırma +Earthquake shake intensity,DSPLYMNU_QUAKEINTENSITY,,,,Intenzita zemětřesení,Intensitet af jordskælv,Erdbeben Intensität,,Egeco de tertremo,Intensidad del terremoto,,Maanjäristystehosteen voimakkuus,Intensité des séismes,Földrengés erőssége,Intensità vibrazione terremoto,地震エフェクトの激しさ,지진 효과 강도,Aardbevingsschoksintensiteit,Intensitet av jordskjelvrystelser,Siła trzęsienia ziemi,Intensidade do tremor de terremoto,,Intensitate zguduire la cutremur,Интенсивность тряски землетрясений,Интенсивност земљотреса,Intensitet av jordbävningar,Deprem sarsıntı şiddeti +Interpolate monster movement,DSPLYMNU_NOMONSTERINTERPOLATION,,,,Interpolovat pohyb příšer,Interpolere monsterbevægelse,Interpoliere Monsterbewegung,,Interpoli monstro-movadon,Interpolar mov. de los monstruos,,Interpoloi hirviöiden liike,Interpolation des monstres,Szörny mozgás simítása,Interpola il movimento dei mostri,モンスターの移動補間,개체 이동 보정,Interpoleer monsterbewegingen,Interpolere monsterbevegelse,Interpolacja ruchu potworów,Interpolar movimento de monstros,,Interpolare mișcare monștri (efect vizual),Сглаживание движения монстров,Интерполирај кретање чудовишта,Interpolera monsterrörelse,Canavar hareketini enterpole et +Menu dim,DSPLYMNU_MENUDIM,,,,Síla barvy pozadí v menu,Menu dæmpes,Menüabdunklung,,Menuo-malheleco,Atenuación del menú,,Valikon himmennys,Assombrissement menu,Menü homályosítása,Offuscamento menu,メニュー背景,메뉴 배경색 강도,Donkere menuachtergrond,Demp meny,Mgła w menu,Atenuação do menu,,Întunecare meniu,Затемнение фона меню,Пригушивање менија,Dimma menyn,Menü loş +Dim color,DSPLYMNU_DIMCOLOR,,,Dim colour,Barva pozadí v menu,Dim farve,Abdunklungsfarbe,,Malheleca koloro,Color de la atenuación,,Himmennysväri,Couleur de l'assombrissement,Homályosítás színe,Colore offuscamento,背景色,배경색 설정,Donkere kleur,Demp farge,Kolor mgły,Cor da atenuação,,Culoare întunecare,Цвет затемнения,Боја пригушивања,Dimma färgen,Loş renk +View bob amount while moving,DSPLYMNU_MOVEBOB,,,,Pohupování pohledu při pohybu,Vis bob-beløb under bevægelse,Waffenpendeln beim Bewegen,,Vidi kvanton de kapo-balanciĝo dum movado,Cantidad de balanceo al moverse,,Aseen heilumisvoimakkuus liikkeessä,Chaloupage arme en movement,Fegyver mozgása lépés közben,Ammontare di bob di movimento,視点揺れする移動値,이동 시 화면 흔들림 강도,Bekijk bob bedrag terwijl je beweegt,Vis bob-beløp mens du beveger deg,Dygaj kiedy się ruszasz,Quantidade de balanço durante movimento,,Mișcare cameră în timpul deplasării,Покачивание камеры при движении,Тресење камере током кретања,Visa bob-mängden under förflyttning,Hareket halindeyken bob miktarını görüntüleme +View bob amount while not moving,DSPLYMNU_STILLBOB,,,,Pohupování pohledu v klidu,"Vis bob-beløbet, mens du ikke bevæger dig",Waffenpendeln bei Nichtbewegen,,Vidi kvanton de kapo-balanciĝo dum ne movado,Cantidad de balanceo al no moverse,,Aseen heilumisvoimakkuus levossa,Chaloupage arme statique,Fegyver mozgása egy helyben,Ammontare di bob di movimento da fermo,視点揺れしない移動値,정지 시 화면 움직임 강도,Bekijk bob bedrag terwijl je niet beweegt,Vis bobmengde mens du ikke beveger deg,Dygaj kiedy się nie ruszasz,Quantidade de balanço parado,,Mișcare cameră în timpul staționării,Покачивание камеры при бездействии,Тресење камере током неактивности,Visa bob-mängden när den inte rör sig,Hareket etmiyorken bob miktarını görüntüleme +Weapon bob speed,DSPLYMNU_BOBSPEED,,,,Rychlost pohupování zbraně,Våben bob hastighed,Waffenpendelgeschwindigkeit,,Rapido de armilo-balanciĝo,Velocidad de balanceo de Arma,,Aseen heilumisnopeus,Vitesse du chaloupage,Fegyver mozgás sebesség,Velocità di bob dell'arma,武器揺れ速度,무기 흔들림 속도,Snelheid wapenzwaaieffect,Våpen bob hastighet,Szybkość ruchu broni,Velocidade de balanço de arma,,Viteză mișcare arme,Скорость покачивания оружия,Брзина трсења оружја,Vapens hastighet,Silah bob hızı +,,Scaling,,,,,,,,,,,,,,,,,,,,,,,,, +Scaling Options,SCALEMNU_TITLE,,,,Nastavení škálování rozhraní,Indstillinger for skalering,Skalierungsoptionen,,Skalo-Agordoj,Opciones de escalado,,Skaalausasetukset,Option de mise à l'échelle,Méretezési Beállítások,Opzioni di scala,スケーリング オプション,배율 설정,Schaalopties,Alternativer for skalering,Opcje skalowania,Opções de Escala,,Setări Dimensiuni,Настройки масштабирования,Подешавања размере,Skalningsalternativ,Ölçeklendirme Seçenekleri +Overrides for above setting,SCALEMNU_OVERRIDE,,,,Potlačení nastavení výše,Overrides for ovenstående indstilling,Spezialisierungen,,Transpasoj por ĉi-supre agordo,Anular ajuste anterior,,Ohittaa asetuksen ylhäällä,Annule les paramètres au dessus,Beállítások felülírása,Sovrascritture per i settaggi sopra,設定の上書き,위 설정을 위해 무시,Overschrijdingen voor bovenstaande instelling,Overstyrer for innstillingen ovenfor,Nadpisuje dla powyższego ustawienia,Anular configurações acima,,Suprascriere pentru setările de mai sus,Задать специальные настройки,Специјална подешавања,Överordnar ovanstående inställningar,Yukarıdaki ayar için geçersiz kılmalar +Messages,SCALEMNU_MESSAGES,,,,Oznámení,Meddelelser,Nachrichten,,Mesaĝoj,Mensajes,,Viestit,,Üzenetek,Messaggi,メッセージ類,메시지,Berichten,Meldinger,Wiadomości,Mensagens,,Mesaje,Сообщения,Поруке,Meddelanden,Mesajlar +Console,SCALEMNU_CONSOLE,,,,Konzole,Konsol,Konsole,,Konzolo,Consola,,Konsoli,,Konzol,,コンソール,콘솔,,Konsoll,Konsola,,Consola,Consolă,Консоль,Конзола,Konsol,Konsol +Status bar,SCALEMNU_STATBAR,,,,Stavový panel,Statuslinje,Statusleiste,,Stata baro,Barra de estado,,Tilapalkki,Barre d'état,Státusz sáv,Barra di stato,ステータスバー,상태 바,Statusbalk,Statuslinje,Pasek statusu,Barra de status,Barra de estado,Bară de Stare,Строка состояния,Статусна трака,Statusfältet,Durum çubuğu +Fullscreen HUD,SCALEMNU_HUD,,,,HUD přes celou obrazovku,HUD i fuld skærm,Vollbild-HUD,,Tutekrana HUD,HUD de pantalla completa,,Täyden ruudun tilanäyttö,ATH plein écran,Teljes képernyős HUD,HUD a pieno schermo,全画面HUD,전체화면 HUD,Volle scherm HUD,HUD i fullskjerm,HUD pełnoekranowy,HUD de tela cheia,HUD de ecrã cheio,Interfață pe Timp de Joc tip Fullscreen,Полноэкранный интерфейс,HUD преко целог екрана,HUD i fullskärm,Tam Ekran HUD +Alternative HUD,SCALEMNU_ALTHUD,,,,Alternativní HUD,Alternativ HUD,Alternatives HUD,,Alternativa HUD,HUD alternativo,,Vaihtoehtoinen tilanäyttö,ATH alternatif,Alternatív HUD,HUD alternativo,オルタナティブHUD,대체 HUD,Alternatieve HUD,Alternativ HUD,Alternatywny HUD,HUD alternativo,,Interfață pe Timp de Joc Alternativă,Альтернативный интерфейс,Алтернативни HUD,Alternativ HUD,Alternatif HUD +HUD preserves aspect ratio,SCALEMNU_HUDASPECT,,,,HUD zachovává poměr stran,HUD bevarer formatforholdet,HUD bewahrt Seitenverhältnisse,,HUD konservas aspekto-proporcion,HUD conserva la rel. de aspecto,,Tilanäyttö säilyttää kuvasuhteen,ATH préserve le rapport d'aspect,A HUD képarány visszaállítása,HUD preserva le proporzioni,HUDのアスペクト比維持,HUD 화면 비율 보존,HUD behoudt de beeldverhouding,HUD bevarer størrelsesforholdet,HUD zachowuje współczynnik proporcji,HUD deve preservar proporções,,Interfața pe Timp de Joc își Păstrează Aspectul,Сохранение соотношения сторон интерфейса,Сачувај пропорције HUD-а,HUD behåller bildförhållandet,HUD en boy oranını korur +Use default scale,SCALEMNU_USEUI,,,,Použít výchozí velikost,Brug standardskala,Benutze Standardskalierung,,Uzi defaŭltskalon,Usar escalado por defecto,,Käytä oletusmittakaavaa,Défaut,Alap arányok használata,Usa la scala di default,通常サイズを使う,기본 배율 사용,Gebruik standaardweegschaal,Bruk standard skala,Użyj domyślnej skali,Usar escala padrão,,Folosește dimensiunea implicită,Размер по умолчанию,Уобичајена размера,Använder standardskalan,Varsayılan ölçeği kullan +Scale to fullscreen,SCALEMNU_USEFS,,,,Škalovat přes celou obrazovku,Skaleres til fuld skærm,Skaliere auf Vollbild,,Skali al tutekrano,Escalar a pant. completa,,Skaalaa täyteen ruutuun,Plein écran,Teljes képernyőre arányítás,Scala a pieno schermo,全画面に拡大,전체화면에 맞게 축척,Schaalbaar tot volledig scherm,Skaler til fullskjerm,Przeskaluj do pełnego ekranu,Escala de tela cheia,Escalar para ecrã cheio,Dimensionare la modul Fullscreen,Масштабировать со всем экраном,Проширење преко целог екрана,Skala till fullskärm,Tam ekrana ölçeklendir +Adapt to screen size,SCALEMNU_ADAPT,,,,Přizpůsobit velikosti obrazovky,Tilpasning til skærmstørrelse,Passe an Bildschirmgröße an,,Adapti al ekranamplekso,Adaptar al tamaño de pantalla,,Sovita näytön kokoon,Ecran,Képernyő mérethez alkalmazkodik,Adatta alla dimensione della schermata,画面サイズに合わせる,화면 사이즈에 맞게 축척,Aanpassen aan de grootte van het scherm,Tilpass til skjermstørrelse,Dostosuj do pełnego ekranu,Adaptar ao tamanho de tela,,Adaptează la dimensiunea ecranului,Адаптироваться к размеру экрана,Прилагоди размери екрана,Anpassas till skärmstorlek,Ekran boyutuna uyum sağlayın +,,HUD,,,,,,,,,,,,,,,,,,,,,,,,, +HUD Options,HUDMNU_TITLE,,,,Nastavení rozhraní a HUD,HUD-indstillinger,HUD Optionen,,HUD Agordoj,Opciones del HUD,,Tilanäytön asetukset,Options ATH,HUD beállításai,Opzioni HUD,HUDオプション,HUD 설정,HUD-opties,HUD-alternativer,Opcje HUD,Opções de HUD,,Setări Interfață pe Timp de Joc,Настройки отображения информации,HUD подешавања,Alternativ för HUD,HUD Seçenekleri +Alternative HUD,HUDMNU_ALTHUD,,,,Alternativní HUD,Alternativ HUD,Alternatives HUD,,Alternativa HUD,HUD alternativo,,Vaihtoehtoinen tilanäyttö,ATH Alternatif,Alternatív HUD,HUD alternativo,オルタナティブHUD,대체 HUD,Alternatieve HUD,Alternativ HUD,Alternatywny HUD,HUD Alternativo,,Interfață pe Timp de Joc Alternativă,Альтернативное отображение информации,Алтернативни HUD,Alternativ HUD,Alternatif HUD +Message Options,HUDMNU_MESSAGE,,,,Oznámení,Indstillinger for meddelelser,Nachrichtenoptionen,,Mesaĝo-Agordoj,Opciones de mensajes,,Viestiasetukset,Options des Messages,Üzenet beállítások,Opzioni messaggi,メッセージの設定,메시지 설정,Berichtopties,Meldingsalternativer,Opcje wiadomości,Opções de Mensagem,,Setări Mesaje,Настройки сообщений,Подешавања порука,Alternativ för meddelanden,Mesaj Seçenekleri +User interface scale,HUDMNU_UISCALE,,,,Velikost rozhraní,Skala for brugergrænseflade,Benutzerinterfaceskalierung,,Interfaco-skalo de uzanto,Escala de la interfaz de usuario,,Käyttöliittymän skaalaus,Echelle de l'interface,Felhasználó Panel mérete,Scala l'interfaccia utente,インターフェースの大きさ,인터페이스 크기 조정,Schaal gebruikersinterface,Skalering av brukergrensesnitt,Skala interfejsu,Escala de interface de usuário,Escala de interface do utilizador,Dimensiune Interfață Utilizator,Размер интерфейса,Размера интерфејса,Skala för användargränssnittet,Kullanıcı arayüzü ölçeği +Force default crosshair,HUDMNU_FORCECROSSHAIR,,,,Vynutit výchozí zaměřovač,Tvinge standard-trådkorset,Erzwinge Standard-Fadenkreuz,,Devigi defaŭltan reteton,Forzar retícula por defecto,,Pakota oletustähtäin,Forcer Viseur par défaut,Alapcélkereszt erőltetése,Forza il mirino di default,デフォルトの照準を使う,기본 조준점 강제 설정,Forceer standaard dradenkruis,Tving frem standard trådkors,Wymuś domyślny celownik,Forçar mira padrão,,Forțare țintă implicită,Всегда стандартный прицел,Форсирај уобичајени нишан,Forcera standardkorset,Varsayılan artı işaretini zorla +Grow crosshair when picking up items,HUDMNU_GROWCROSSHAIR,,,,Zvětšit zaměřovač při sebrání předmětu,"Vokse trådkorset, når du samler genstande op",Größeres Fadenkreuz bei Gegenstandsaufnahme,,Grandigi reteton kiam oni prenas objektojn,Aumentar retícula al obtener obj.,Crecer retícula al obtener obj.,Suurenna tähtäintä esineitä poimiessa,Agrandir viseur en prenant un objet,A célkereszt nőjön tárgyfelvételkor,Accresci il mirino quando si raccolgono oggetti,アイテム取得時に照準を大きくする,아이템 획득 시 조준점 키우기 ,Vergroot het dradenkruis bij het oppakken van items,Utvid trådkorset når du plukker opp elementer,"Powiększ celownik, gdy podnosisz przedmioty",Aumentar mira ao pegar itens,Aumentar mira ao apanhar itens,Mărește ținta la ridicarea obiectelor,Увеличение прицела при подборе,Побољшај нишан током купљења предмета,Växer hårkorset när du plockar upp föremål,Eşyaları alırken artı işaretini büyütün +Display nametags,HUDMNU_NAMETAGS,,,,Zobrazovat jmenovky,Viser navneskilte,Zeige Gegenstandsnamen,,Montri nometikedojn,Mostrar etiquetas,,Näytä nimitunnisteet,Afficher noms des objets,Névtábla mutatása,Mostra le targhette identificative,ディスプレイネームタグ,이름표 표시,Naamlabels weergeven,Vis navnelapper,Pokazuj nazwy przedmiotów,Exibir nomes,,Indică numele obiectelor,Указание названия предметов,Прикажи имена предмета,Visa namnbrickor,İsim etiketlerini gösterin +Nametag color,HUDMNU_NAMETAGCOLOR,,,Nametag colour,Barva jmenovek,Farve på navneskilte,Farbe für Gegenstandsnamen,,Nometikeda koloro,Color de las etiquetas,,Nimitunnisteen väri,Couleur des noms d'objet,Névtábla szín,Colore targhetta identificativa,ネームタグ色,이름표 색깔,Kleur naamlabel,Farge på navneskilt,Kolor nazw przedmiotów,Cor dos nomes,,Culoare nume obiecte,Цвет названия предметов,Боја имена предмета,Färg på namnbrickor,İsim etiketi rengi +Use old ouch mug shot formula,HUDMNU_OLDOUCH,,,,Použít starý vzorec pro 'ouch' portrét,"Gammel formel for ""av"" ansigt",Alte Formel für „Autsch“-Gesicht,,Uzi maljunan formulon de aj-vizaĝo-foto,Usar formula antigua de foto de daño,,Käytä vanhaa auts-naamakuvan kaavaa,Ancien code pour l' « ouch face »,Régi sebződő fej formula használata,Mostra la formula originale del viso 'ouch',旧式ouch mug shotを使用,구형 피격 표정 스프라이트 방식 사용,"Oude formule voor ""Ouch""-gezicht",Bruk formelen for gamle forbryterbilder,Używaj starej formuły twarzy przy dostaniu obrażeń,Usar fórmula original do rosto de dor,,Utilizează modul portret vechi,Старая формула для портрета,Стара формула за приказ лика,"Använd den gamla formeln med ""ouch"" foton",Eski ouch oyuncu yüzü formülünü kullanın +Hexen weapon flashes,HUDMNU_HEXENFLASHES,,,,Druh bliknutí zbraní v Hexenu,Hexen-våben blinker,Hexen-Waffenblitze,,Ekbriloj de Hexen-armo,Destello armas Hexen,,Hexenin asevälähdykset,Flash d'arme dans Hexen,Hexen fegyver villanások,Bagliori armi Hexen,Hexen武器の視界色,헥센 무기 반짝임,Hexen-wapen flitsen,Hexen våpen blinker,Błysk przy podnoszeniu broni z Hexena,Flash de arma do Hexen,,Tip strălucire arme Hexen,Тип вспышки оружия в Hexen,Треперење оружја у Hexen-у,Hexen-vapen blinkar,Hexen silah flaşları +Poison damage flashes,HUDMNU_POISONFLASHES,,,,Druh bliknutí při otrávení,Giftskabte skader blinker,Gift-Effekt,,Ekbriloj de venondamaĝo,Destello daño por veneno,,Myrkkyvahinkovälähdykset,Flash de poison dans Hexen,Méreg sebzés villanások,Bagliori danno da veleno,毒ダメージの視界色,독데미지 반짝임,Vergiftigingsschade knippert,Giftskade blinker,Efekt obrażeń przy zatruciu,Flash de dano por veneno,,Tip strălucire efect de otrăvire,Тип вспышки яда,Треперење током тровања,Blinkar för giftskador,Zehir hasarı flaşları +Ice death flashes,HUDMNU_ICEFLASHES,,,,Druh bliknutí při smrti umrznutím,Isdødsblink,Eis-Tod-Effekt,,Ekbriloj de glacimorto,Destello muerte por hielo,,Jääkuolemavälähdykset,Flash de morts par glace,Jéghalál villanások,Bagliori morte da ghiaccio,氷結死の視界色,동사시 반짝임,IJsdood knippert,Isdød blinker,Błysk przy śmierci poprzez zamrożenie,Flash de morte por congelamento,,Tip strălucire deces prin înghețare,Тип вспышки при смерти от льда,Треперење током смрти од леда,Blinkar för isdöd,Buz ölüm flaşları +Poison Buildup flashes,HUDMNU_HAZARDFLASHES,,,,Druh blikání při kumulaci jedu,Gift Buildup blinker,Kumulativer Gift-Effekt,,Ekbriloj de venonamasigo,Destello acumulación de veneno,,Myrkyn kertymisvälähdykset,Flash d'accumulation de poison,Fokozatos méreg sebzés villanások,Bagliori danno accumulato da veleno,蓄積毒の視界色,독데미지 반짝임 증강,Vergiftiging Opbouw knippert,Giftoppbygging blinker,Miganie przy nasilaniu się trucizny,Flash por acúmulo de dano por veneno,,Tip strălucire acumulare de otravă,Тип вспышки при скоплении яда,Треперење током гомилања отрова,Blinkningar för giftuppbyggnad,Zehir Birikimi yanıp söner +Scaling Options,HUDMNU_SCALEOPT,,,,Škálování velikosti rozhraní,Skaleringsmuligheder,Skalierungsoptionen,,Skalo-Agordoj,Opciones de escalado,,Skaalausasetukset,Option de mise à l'échelle,Méretezés Beállítások,Opzioni di scala,スケーリング オプション,배율 설정,Schaalopties,Alternativer for skalering,Opcje skalowania,Opções de Escala,,Setări Dimensiuni,Настройки масштабирования,Подешавања размере,Alternativ för skalning,Ölçeklendirme Seçenekleri +Show IWAD selection dialog,MISCMNU_QUERYIWAD,,,,Zobrazit dialog pro výběr IWADu,Vis IWAD-valgdialogboks,Zeige IWAD-Auswahl,,Montri elektodialogon de IWAD,Mostrar diálogo de selección de IWAD,,Näytä IWAD-valintaikkuna,Afficher la séléction d'IWAD,IWAD kiválasztó ablak mutatása,Mostra la schermata della selezione IWAD,IWADの選択画面を表示,IWAD 게임 선택창 표시,IWAD-selectiedialoogvenster weergeven,Vis IWAD-valgdialogboks,Pokaż ekran wyboru gry (IWAD),Exibir janela de seleção de IWAD,,Afișează fereastra de selectare a jocurilor,Выбор IWAD-файла при запуске,Покажи IWAD дијалог за избор,Visa dialogrutan för val av IWAD,IWAD seçim iletişim kutusunu göster +Enable cheats from all games,MISCMNU_ALLCHEATS,,,,Povolit cheaty ze všech her,Aktiver snyderier fra alle spil,Ermögliche Cheats aus allen Spielen,,Ebligi trompojn el tutaj ludoj,Activar trucos de todos los juegos,,Ota käyttöön huijauskoodit kaikista peleistä,Activer cheats de tous les jeux,Minden játék csaláskódja érvényes,Abilita tutti i cheat da tutti i giochi,全ゲームでチート使用可にする,모든 게임에 치트 허용,Laat bedriegers van alle spellen toe,Aktiver juks fra alle spill,Włącz oszustwa ze wszystkich gier,Habilitar trapaças de todos os jogos,Permitir batotas de todos os jogos,Permite codurile din toate jocurile,Читы из всех игр,Омогући читове од свих игара,Aktivera fusk från alla spel,Tüm oyunlardan hileleri etkinleştirin +,,Option Menus,,,,,,,,,,,,,,,,,,,,,,,,, +Enable making screenshots by scripts,MISCMNU_ENABLESCRIPTSCREENSHOTS,,,,Povolit skriptům pořizovat snímky obrazovky,Aktivering af skærmbilleder ved hjælp af scripts,"Erlaube Skripts, Screenshots zu machen",,Ebligi faradon de ekrankopioj per skriptoj,Habilitar captura de pantalla por scripts,,Salli komentosarjoin otetut kuvakaappaukset,Autoriser les Scripts à prendre des captures,Szkriptek is készíthetnek képernyőképet,Abilita la cattura dello schermo tramite scripts,スクリプトからのスクショ作成を有効化,저장/불러오기 확인,Screenshots maken met behulp van scripts,Gjør det mulig å lage skjermbilder av skript,Pozwól na robienie zrzutów ekranu przez skrypty,Habilitar capturas de tela por scripts,Permitir capturas de ecrã por scripts,Posibilitate de a face poze prin scripturi,Возможность делать снимки экрана через скрипты,Омогући прављење скриншотова по скрипти,Aktivera att göra skärmdumpar med hjälp av skript,Komut dosyalarıyla ekran görüntüsü almayı etkinleştirme +Load *.deh/*.bex lumps,MISCMNU_DEHLOAD,,,,Načítat *.deh/*.bex soubory,Indlæsning af *.deh/*.bex-filer,Lade *.deh/*.bex Daten,,Ŝargi je *.deh/*.bex lumpoj,Cargar archivos *.deh/*.bex,,Lataa *.deh/*.bex-lump-tiedostot,Charger fichiers *.deh/*.bex,*.deh/*.bex lump-ok betöltése,Carica i lump *.deh/*.bex,.deh/.bexファイルを読み込む,*.deh/*.bex 럼프 파일 불러오기,*.deh/*.bex laden,Last inn *.deh/*.bex-arkiver,Załaduj dane *.deh/*.bex,Carregar lumps *.deh/*.bex,,Încarcă nodurile *.deh/*.bex,Загружать файлы *.deh/*.bex,Учитај *.deh/*.bex фајлове,Ladda *.deh/*.bex-filer,.deh/*.bex topaklarını yükle +Cache nodes,MISCMNU_CACHENODES,,,,Cachovat nodes,,Nodes zwischenspeichern,,Kaŝmemoraj nodoj,Caché de nodos,,Tallenna solmut välimuistiin,Mise en cache des nodes,Node-ok cache-lése,Cache dei nodi,ノードキャッシュ,캐시 노드,Cache nodes,Bufre noder,Węzły pamięci podręcznej,Cachê de nodes,Cache de nodes,Depozitare noduri cache,Кэширование узлов,Кеширани чворови,Cache-noder,Önbellek düğümleri +Time threshold for node caching,MISCMNU_CACHETIME,,,,Časový práh pro cachování nodes,Tidsgrænse for node-cache,Zeitschwelle für das Zwischenspeichern von Nodes,,Templimo pro kaŝmemornodi,Umbral de tiempo para caché de nodos,,Kynnysaika solmujen välimuistitallennukseen,Limite cache des nodes,Időhatár node cache-hez,Soglia di tempo per il caching dei nodi,ノードキャッシュ時間の閾値,노드 캐싱을 위한 시간 임계값 계산,Tijdsdrempel voor het cachen van nodes,Tidsterskel for nodebufring,Próg czasowy buforowania węzłów,Limite de tempo para cachê de nodes,Limite de tempo para cache de nodes,Limită de timp pentru depozitare cache,Временной порог для кэширования узлов,Временски праг за кеширање чвора,Tidströskel för cachelagring av noder,Düğüm önbelleğe alma için zaman eşiği Clear node cache,MISCMNU_CLEARNODECACHE,,,,Vyčistit node cache,Ryd node-cache,Nodespeicher löschen,,Forigi kaŝmemorajn nodojn,Limpiar Caché de nodos,,Tyhjennä solmuvälimuisti,Vider le cache des nodes,Cache node ürítése,Pulisci la cache dei nodi,ノードのキャッシュをクリア,노드 캐시를 삭제,Node cache legen,Tøm nodebuffer,Wyczyść pamięć podręczną,Limpar cachê de nodes,Limpar cache de nodes,Ștergere noduri cache,Очистить кэш узлов,"Избриши кеширане чворове -",Düğüm önbelleğini temizle -Allow skipping of intermission scrollers,MISCMNU_INTERSCROLL,,,,Povolit přeskakování skrolujících obrázků,Tillad at springe over pausescrollere,Erlaube Überspringen von Intermission-Scrollern,,Permesi preterpason de intermitaj rulumoj,Permitir omisión de intermedios,,Salli vierivien väliruutujen ohittaminen,Sauter compteurs d'intermission,Pályaközi szünetek átugorhatóak,Consenti di saltare gli scorrimenti delle intermissioni,クリア結果集計のスキップを許可,인터미션 스크롤러 생략 허용,Overslaan van intermissiescrollers toestaan,Tillat å hoppe over pauserullere,Pozwól na pominięcie wstawek,Pular telas de intervalo entre fases,Saltar ecrãs de intervalo entre níveis,Permite saltul peste inserările de text,Разрешение пропуска текстовых вставок,Дозволи прескакање прелаза са текстовима,Ara kaydırıcıların atlanmasına izin ver -Network Options,NETMNU_TITLE,,,,Nastavení sítě,Netværksindstillinger,Netzwerkeinstellungen,,Reta Agordoj,Opciones de Red,,Verkkoasetukset,Options Réseau,Hálózati Beállítások,Opzioni network,ネットワーク オプション,네트워크 설정,Netwerkopties,Nettverksalternativer,Opcje Sieci,Opções de Rede,,Setări de Rețea,Настройки сети,Мрежна подешавања,Ağ Seçenekleri -Local options,NETMNU_LOCALOPTIONS,,,,Lokální nastavení,Lokale indstillinger,Lokale Einstellungen,,Lokaj agordoj,Opciones locales,,Paikallisasetukset,Options Locales,Helyi beállítások,Opzioni locali,ローカル オプション,로컬 설정,Lokale opties,Lokale alternativer,Opcje Lokalne,Opções locais,,Setări Locale,Локальные настройки,Локална подешавања,Yerel seçenekler -Movement prediction,NETMNU_MOVEPREDICTION,,,,Predikce pohybu,Forudsigelse af bevægelser,Bewegungsvorausberechnung,,Movprognozado,Predicción de Movimiento,,Liikkeen ennakoiminen,Prédiction de Mouvement,Mozgás előrejelzés,Predizione movimenti,移動予測,움직임 예측도,Voorspelling van bewegingen,Forutsigelse av bevegelse,Przewidywanie Ruchu,Previsão de movimento,,Anticipare mișcare,Предсказание движения,Предвиђање покрета,Hareket tahmini -Predict line actions,NETMNU_LINESPECIALPREDICTION,,,,Predikce čárových akcí,Forudsige linjehandlinger,Berechne Linienaktionen voraus,,Prognozi linio-agojn,Predecir acciones de línea,,Ennakoi viivasuorat toiminnat,Prédiction des actions de ligne,Előrejelzés vonal művelet,Predizione azioni di linea,line actionsを予測する,라인 움직임 감지,Voorspel lijnacties,Forutsi linjehandlinger,Przewidź akcje linii,Prever ações de linha,,Anticipează acționarea liniilor,Предсказание действий на уровне,Предвиђање линијске радње,Hat eylemlerini tahmin edin -Prediction Lerp Scale,NETMNU_PREDICTIONLERPSCALE,,,,Velikost interpolace predikce,Forudsigelse Lerp-skala,Vorberechnungs Lerp-Skalierung,,Skalo de Linia Lnterpolado,Escala de interp. lineal de predicción,,Lineaarisen interpolaatioennakoinnin skaalaus,Prédiction d'échelle LERP,Előrejelzés LERP Arány,Scala Lerp predizione,リープスケール予測,러프 예측 강도,Voorspelling Lerp Scale,Prediksjon Lerp-skala,Przewidywanie Skali Lerp,Escala de previsão de LERP,,Anticipare scară lerp,Предсказание увеличения доп. задержки,Предвиђање лерп скале,Tahmin Lerp Ölçeği -Lerp Threshold,NETMNU_LERPTHRESHOLD,,,,Práh interpolace,Lerp-tærskel,Lerp-Schwellwert,,Limito de Linia Interpolado,Umbral de interp. lineal,,Interpolaatiokynnys,Limite LERP,LERP küszöbérték,Soglia Lerp,リープしきい値,러프 계산,Lerp Threshold,Lerp-terskel,Próg Lerp,Limite de LERP,,Prag Lerp,Порог доп. задержки,Лерп праг,Lerp Eşiği -Host options,NETMNU_HOSTOPTIONS,,,,Nastavení hostitele,Værtsindstillinger,Gastoptionen,,Agordoj de Gastiganto,Opciones de Host,,Isäntäasetukset,Options Hôte,Host beállítások,Opzioni ospitante,ホスト オプション,호스트 설정,Verhuurders opties,Vertsalternativer,Opcje hosta,Opções de host,,Setări gazdă,Настройки сервера,Подешавања домаћина,Ev sahibi seçenekleri -Extra Tics,NETMNU_EXTRATICS,,,,Extra tiky,Ekstra tics,,,Ekstraj Tikoj,Tics Extra,,Lisäticit,Tics supplémentaires,Extra Tic-ek,Tics extra,予備秒数,추가 틱,,Ekstra tics,Dodatkowe tiki,Tics extras,,Ticăituri suplimentare,Дополнительные секунды,Додатни тикови,Ekstra Tikler -Latency balancing,NETMNU_TICBALANCE,,,,Vyrovnání latence,Balancering af latenstid,Latenzbalance,,Respondotempo-balancado,Balanceo de latencia,,Viiveen tasapainoitus,Equilibrage de latence,Válaszidő balanszolás,Bilanciamento latenza,レイテンシーバランス,지연 시간 조정,Latency balans,Balansering av ventetid,Balans czasu oczekiwania,Equilíbrio de latência,,Întârzierea echilibrării,Балансировка задержки,Балансирање кашњења,Gecikme dengeleme -Original,OPTVAL_ORIGINAL,,,,Původní,,,,Originala,,,Alkuperäinen,Original,Eredeti,Originale,オリジナル,원형,Origineel,,Oryginalny,Original,,,Изначальный,Оригинално,Orijinal -Optimized,OPTVAL_OPTIMIZED,,,,Optimalizovaný,Optimeret,Optimiert,,Optimumigita,Optimizado,,Optimoitu,Optimisé,Optimalizált,Ottimizzato,最適化,최적화 형,Geoptimaliseerd,Optimalisert,Zoptymalizowany,Otimizado,,Optimizat,Оптимизированный,Оптимизовано,Optimize Edilmiş -Classic (Faster),OPTVAL_CLASSIC,,,,Klasický (rychlejší),Classic (hurtigere),Klassisch (schneller),,Klasika (Pli rapide),Clásico (Más rápido),,Perinteinen (nopeampi),Classique (+ Rapide),Klasszikus (gyorsabb),Classico (più veloce),旧式(速度重視),구형 (빠르게),Klassiek (sneller),Klassisk (raskere),Klasyczny (szybszy),Clássico (Mais rápido),,Clasic (Mai rapid),Классический (быстрее),Класични (бржи),Klasik (Daha Hızlı) -Precise,OPTVAL_PRECISE,,,,Přesný,Præcist,Genau,,Preciza,Preciso,,Tarkka,Précis,Pontos,Preciso,精密,정확하게,Nauwkeurig,Presis,Dokładny,Preciso,,Precis,Точный,Прецизно,Kesin -Capped,OPTVAL_CAPPED,,,,Uzavřený,Begrænset,Limitiert,,Limitigita,Limitado,,Rajoitettu,Limité,Lekorlátozva,Limitato,上限,색상에 맞게,Afgeschermd,Begrenset,Ograniczony,Limitado,,Limitat,Ограниченный,Ограничено,Sınırlı -Particles,OPTVAL_PARTICLES,,,,Částice,Partikler,Partikel,,Partikloj,Partículas,,Hiukkasina,Particules,Részecskék,Particelle,パーティクル,입자만,Deeltjes,Partikler,Cząstki,Partículas,,Particule,Частицы,Честице,Parçacıklar -Sprites,OPTVAL_SPRITES,,,,Sprity,,Sprites,,Spritoj,,,Spriteinä,,Sprite-ok,Sprite,スプライト,스프라이트만,Sprites,Sprites,Sprite'y,Sprites,,Sprite-uri,Спрайты,Спрајтови,Sprite'lar -Sprites & Particles,OPTVAL_SPRITESPARTICLES,,,,Sprity a částice,Sprites og partikler,Sprites und Partikel,,Spritoj kaj Partikloj,Sprites y partículas,,Spriteinä ja hiukkasina,Sprites & Particules,Sprite-ok és részecskék,Sprite e particelle,スプライト & パーティクル,스프라이트+입자,Sprites & Deeltjes,Sprites og partikler,Sprite'y i cząstki,Sprites & Partículas,Sprites e Partículas,Sprite-uri & Particule,Спрайты и частицы,Спрајтови и честице,Sprite'lar ve Parçacıklar -Melt,OPTVAL_MELT,,,,Rozpuštění,Smelt,Verlauf,,Fandi,Derretir,,Sulaminen,Fondu,Olvadás,Scioglimento,メルト,녹는 효과,Smelten,Smelte,Stopienie,Derreter,,Topire,Таяние,Топљење,Eriyik -Burn,OPTVAL_BURN,,,,Oheň,Brænde,Einbrennen,,Bruli,Quemar,,Palaminen,Brûlure,Égés,Bruciamento,バーン,타는 효과,Verbranden,Brenne,Wypalenie,Queimar,,Ardere,Жжение,Спаљивање,Yanmak -Crossfade,OPTVAL_CROSSFADE,,,,Prolínačka,Crossfade,Überblenden,,Transvelki,Entrelazar,,Ristihäivytys,Fondu en croix,Átvezetés,Dissolvenza a croce,クロスフェード,화면 교차,Crossfade,Overblending,Przenikanie,Dissolver,,Ofilire,Увядание,Вењење,Crossfade -Smooth,OPTVAL_SMOOTH_1,"This setting is duplicated in order to allow for different grammatical gender endings in the Russian language (and any other language that depends on a grammatical gender system). In English, due to the lack of a grammatical gender system, both option values are the same.",,,Vyhlazený,Glat,Glatt,,Glata,Fluido,,Pehmeä,Lisse,Simítás,Liscio,スムーズ,부드럽게,Glad,Glatt,Gładki,Suavizado,,Fin,Плавная,Глатко,Pürüzsüz -Smooth,OPTVAL_SMOOTH_2,,,,Vyhlazené,Glat,Glatt,,Glata,Fluido,,Pehmeä,Lisse,Simítás,Liscio,スムーズ,부드럽게,Glad,Glatt,Gładka,Suavizado,,Fin,Плавные,Глатко,Pürüzsüz -Translucent,OPTVAL_TRANSLUCENT,,,,Průhledný,Gennemskinnelig,Transparent,,Diafana,Translúcido,,Läpikuultava,Transparent,Áttetsző,Traslucido,半透明,투명하게,Doorschijnend,Gjennomskinnelig,Przeświecający,Translúcido,,Transparent,Полупрозрачный,Прозрачно,Yarı Saydam -Fuzz,OPTVAL_FUZZ,,,,Šum,,Fuzz,,Lanugo,Borroso,,Sumeus,Bruit Blanc,Homályosítás,Annebbiato,ファズ,퍼즈 효과,Fuzz,,Szum,Difuso,,Sclipitor,Шумовой,Фаз,Fuzz -Shadow,OPTVAL_SHADOW,,,,Stín,Skygge,Schatten,,Ombro,Sombra,,Varjo,Ombre,Árnyék,Ombra,シャドウ,그림자 효과,Schaduw,Skygge,Cień,Sombra,,Umbră,Теневой,Сенка,Gölge -Items,OPTVAL_ITEMS,,,,Předměty,Varer,Gegenstände,,Objektoj,Objetos,,Esineet,Objets,Tárgyak,Oggetti,アイテム,아이템들,Artikelen,Gjenstander,Przedmioty,Itens,,Obiecte,Предметы,Предмет,Eşyalar -Weapons,OPTVAL_WEAPONS,,,,Zbraně,Våben,Waffen,,Armiloj,Armas,,Aseet,Armes,Fegyverek,Armi,武器,무기들,Wapens,Våpen,Bronie,Armas,,Arme,Оружие,Оружја,Silahlar -Both,OPTVAL_BOTH,,,,Obojí,Begge,Beide,,Ambaŭ,Ambos,,Molemmat,Les Deux,Mindkettő,Entrambi,両方,둘 다,Beide,Begge,Oba,Ambos,,Ambele,Оба,Оба,Her ikisi de -ZDoom,OPTVAL_ZDOOM,,,,,,,,,,,,,,,,Z둠,,,,,,,,, -Strife,OPTVAL_STRIFE,,,,,,,,,,,,,,,,스트라이프,,,,,,,,, -Player,OPTVAL_PLAYER,,,,Hráč,Spiller,Spieler,,Ludanto,Jugador,,Pelaaja,Joueur,Játékos,Giocatore,プレイヤー,플레이어,Speler,Spiller,Gracz,Jogador,,Jucător,Игрок,Играч,Oyuncu -Map,OPTVAL_MAP,,,,Level,Kort,Level,,Mapo,Mapa,,Kartta,Niveau,Pálya,Mappa,マップ,맵,Kaart,Kart,Mapa,Mapa,,Hartă,Карта,Мапа,Harita -Scale to 640x400,OPTVAL_SCALETO640X400,,,,Zvětšit na 640x400,Skaleres til 640x400,Skaliere auf 640x400,,Skali al 640x400,Escalar a 640x400,,Skaalaa resoluutioon 640x400,Echelle 640x400,640x480-hoz arányít,Scala a 640x400,640x400スケール,640x400까지 확대,Schaal tot 640x400,Skala til 640x400,Skaluj do 640x400,Escalar para 640x400,,Dimensionare la 640x480,Масштабировать до 640x400,Скалирај на 640x400,640x400'e ölçeklendirin -Pixel double,OPTVAL_PIXELDOUBLE,,,,Zdvojení pixelů,Pixel dobbelt,Pixelverdopplung,,Bilderon duobligi,Pixel doble,,Kuvapistekaksinkertaistus,,Pixel duplázás,Pixel doppi,ピクセル2倍,2배 픽셀,Pixel dubbel,Dobbel piksel,Dwukrotnie więcej pikseli,Pixel duplo,,Dublare pixeli,Двойные пиксели,Дупли пиксел,Piksel çift -Pixel quadruple,OPTVAL_PIXELQUADRUPLE,,,,Zčtyřnásobení pixelů,Pixel firedobbelt,Pixelvervierfachung,,Bilderon kvarobligi,Pixel cuádruple,,Kuvapistenelinkertaistus,,Pixel négyszerezés,Pixel quadrupli,ピクセル4倍,4배 픽셀,Pixel viervoudig,Piksel firedoblet,Czterokrotnie więcej pikseli,Pixel quádruplo,,Împătrire pixeli,Учетверённые пиксели,Четвороструки пиксел,Piksel dörtlü -Current weapon,OPTVAL_CURRENTWEAPON,,,,Současná zbraň,Nuværende våben,Aktuelle Waffe,,Nuntempa armilo,Arma actual,,Nykyinen ase,Arme actuelle,Jelenlegi fegyver,Arma corrente,使用中の武器,현 무기,Huidig wapen,Nåværende våpen,Aktualna broń,Arma atual,,Arma curentă,текущего оружия,Тренутно оружје,Mevcut silah -Available weapons,OPTVAL_AVAILABLEWEAPONS,,,,Dostupně zbraně,Tilgængelige våben,Verfügbare Waffen,,Haveblaj armiloj,Armas disponibles,,Käytettävissä olevat aseet,Armes Disponibles,Elérhető fegyverek,Armi disponibili,所持してる武器,사용 가능한 무기들,Beschikbare wapens,Tilgjengelige våpen,Dostępne bronie,Armas disponíveis,,Arme disponibile,доступного оружия,Доступно оружје,Mevcut silahlar -All weapons,OPTVAL_ALLWEAPONS,,,,Všechny zbraně,Alle våben,Alle Waffen,,Ĉiuj armiloj,Todas las armas,,Kaikki aseet,Toutes les armes,Minden fegyver,Tutte le armi,全ての武器,모든 무기들,Alle wapens,Alle våpen,Wszystkie bronie,Todas as armas,,Toate armele,всех видов оружия,Сва оружја,Tüm silahlar -"Level, milliseconds",OPTVAL_LEVELMILLISECONDS,,,,"Level, milisekundy","Level, millisekunder","Level, Millisekunden",,"Nivelo, milisekundoj","Nivel, milisegundos",,"Taso, millisekunnit","Niveau, milisecondes","Pálya, milliszekundum","Livello, millisecondi","現場, ミリ秒","레벨, 밀리초당","Niveau, milliseconden","Nivå, millisekunder","Poziom, milisekundy","Fase, milisegundos","Nível, milisegundos","Nivel, milisecunde","Уровень, миллисекунды","Ниво, милисекунде","Seviye, milisaniye" -"Level, seconds",OPTVAL_LEVELSECONDS,,,,"Level, vteřiny","Level, sekunder","Level, Sekunden",,"Nivelo, sekundoj","Nivel, segundos",,"Taso, sekunnit","Niveau, secondes","Pálya, másodpercek","Livello, secondi","現場, 秒","레벨, 초당","Niveau, seconden","Nivå, sekunder","Poziom, sekundy","Fase, segundos","Nível, segundos","Nivel, secunde","Уровень, секунды","Ниво, секунде","Seviye, saniye" -Level,OPTVAL_LEVEL,,,,Level,,Level,,Nivelo,Nivel,,Taso,Niveau,Pálya,Livello,現場,레벨,Niveau,Nivå,Poziom,Fase,Nível,Nivel,Уровень,Ниво,Seviye -"Hub, seconds",OPTVAL_HUBSECONDS,,,,"Hub, vteřiny","Hub, sekunder","Hub, Sekunden",,"Rekontejo, sekundoj","Hub, segundos",,"Tasokokoelma, sekunnit","Hub, secondes","Csomópont, másodpercek","Hub, secondi","区間, 秒","허브, 초당","Naaf, seconden","Hub, sekunder","Hub, sekundy","Hub, segundos",,"Hub, secunde",Хаб (секунды),"Хуб, секунде","Hub, saniye" -Hub,OPTVAL_HUB,,,,Hub,,Hub,,Rekontejo,Hub,,Tasokokoelma,Hub,Csomópont,Hub,区間,허브,Naaf,,,,,,Хаб,Хуб,Hub -"Total, seconds",OPTVAL_TOTALSECONDS,,,,"Celkový, vteřiny","I alt, sekunder","Gesamt, Sekunden",,"Tuto, sekundoj","Total, segundos",,"Yhteensä, sekunnit","Total, secondes","Teljes, másodpercek","Totale, secondi","合計, 秒","누적 경과, 초당","Totaal, seconden","Totalt, sekunder","Razem, sekundy","Total, segundos",,"Total, secunde",Общее (секунды),"Тотал, секунде","Toplam, saniye" -Total,OPTVAL_TOTAL,,,,Celkový,I alt,Gesamt,,Tuto,,,Yhteensä,Total,Teljes,Totale,合計,누적 경과,Totaal,Totalt,Razem,,,Total,Общее,Тотал,Toplam -"System, seconds",OPTVAL_SYSTEMSECONDS,,,,"Systémový, vteřiny","System, sekunder","System, Sekunden",,"Sistemo, sekundoj","Sistema, segundos",,"Järjestelmä, sekunnit","Système, secondes","Rendszer, másodpercek","Sistema, secondi","PC時刻, 秒","시스템, 초당","Systeem, seconden","System, sekunder","System, sekundy","Sistema, segundos",,"Sistem, secunde",Система (секунды),"Систем, секунде","Sistem, saniye" -System,OPTVAL_SYSTEM,,,,Systémový,System,System,,Sistemo,Sistema,,Järjestelmä,Système,Rendszer,Sistema,PC時刻,시스템,Systeem,System,System,Sistema,,Sistem,Система,Систем,Sistem -Netgames only,OPTVAL_NETGAMESONLY,,,,Pouze v síťové hře,Kun netspil,Nur Netzwerkspiele,,Retludoj sole,Solo para juegos en red,,Vain verkkopelit,Parties en Ligne seulement,Csak Netgames,Solo giochi net,オンラインのみ,멀티플레이에만,Alleen Netspellen,Kun nettspill,Tylko gry sieciowe,Jogos em rede apenas,,Doar în rețea,Только сетевые игры,Мрежне игре само,Sadece net oyunlar -Image and Text,OPTVAL_AMMOIMAGETEXT,,,,Obrázek a text,Billede og tekst,Bild und Text,,Bildo kaj Teksto,Imagen y texto,,Kuva ja teksti,Image et Texte,Kép és szöveg,Immagini e testo,画像と字,이미지와 텍스트,Beeld en tekst,Bilde og tekst,Obraz i Tekst,Imagem e texto,,Imagine și Text,Изображение и текст,Слика и текст,Resim ve Metin -Text and Image,OPTVAL_AMMOTEXTIMAGE,,,,Text a obrázek,Tekst og billede,Text und Bild,,Teksto kaj Bildo,Texto e imagen,,Teksti ja kuva,Texte et Image,Szöveg és kép,Testo e immagini,字と画像,텍스트와 이미지,Tekst en beeld,Tekst og bilde,Tekst i Obraz,Texto e imagem,,Text și Imagine,Текст и изобр.,Текст и слика,Metin ve Görüntü -Scripts Only,OPTVAL_SCRIPTSONLY,,,,Pouze skripty,Kun scripts,Nur Skripte,,Skriptoj Sole,Solo scripts,,Vain komentosarjat,Scripts seulement,Csak szkript,Solo script,スクリプトのみ,스크립트에만,Alleen scripts,Bare skript,Tylko skrypty,Scripts apenas,,Numai scripturi,Только скрипты,Само скрипте,Sadece Senaryolar -All,OPTVAL_ALL,,,,Všechny,Alle,Alle,,Ĉiuj,Todos,,Kaikki,Tout,Mind,Tutti,全て,모두 작동,Alle,Alle,Wszystko,Todos,,Tot,Все,Све,Tümü -Only last one,OPTVAL_ONLYLASTONE,,,,Pouze poslední,Kun den sidste,Nur das letzte,,Nur fina unu,Solo el último,,Vain viimeinen,Dernier seulement,Csak a legutolsó,Solo l'ultimo,最後のみ,오직 마지막 것만,Alleen de laatste,Bare den siste,Tylko ostatni,Somente o último,Apenas o último,Doar ultimul,Только последнее,Само последњи,Sadece sonuncusu -Traditional Doom,OPTVAL_TRADITIONALDOOM,,,,Tradiční Doom,Traditionel Doom,Doom traditionell,,Tradicia Doom,Doom tradicional,,Perinteinen Doom,Doom Traditionnel,Tradícionális Doom,DOOM tradizionale,正式DOOM,전형적인 둠 스타일,Traditioneel Doom,Tradisjonell undergang,Tradycyjny Doom,Doom Tradicional,,Tradițional Doom,Цвета из Doom,Традиционални Doom,Geleneksel Doom -Traditional Strife,OPTVAL_TRADITIONALSTRIFE,,,,Tradiční Strife,Traditionel Strife,Strife traditionell,,Tradicia Strife,Strife tradicional,,Perinteinen Strife,Strife Traditionnel,Tradícionális Strife,Strife tradizionale,正式Strife,전형적인 스트라이프 스타일,Traditionele Strife,Tradisjonell strid,Tradycyjny Strife,Strife Tradicional,,Tradițional Strife,Цвета из Strife,Традиционални Strife,Geleneksel Strife -Traditional Raven,OPTVAL_TRADITIONALRAVEN,,,,Tradiční Raven,Traditionel Raven,Raven traditionell,,Tradicia Raven,Raven tradicional,,Perinteinen Raven,Raven Traditionnel,Tradícionális Raven,Raven tradizionale,正式Raven,전형적인 레이븐 스타일,Traditionele Raven,Tradisjonell ravn,Tradycyjny Raven,Raven Tradicional,,Tradițional Raven,Цвета из Raven,Традиционални Raven,Geleneksel Raven -Only when found,OPTVAL_ONLYWHENFOUND,,,,Pouze po nalezení,Kun når de findes,Nur wenn gefunden,,Nur kiam trovita,Una vez encontrados,,"Vain, kun löydetty",Seulement découverts,Csak ha megleled,Solo quando trovato,発見時のみ,획득했을 때만,Alleen wanneer gevonden,Bare når funnet,Tylko gdy znaleziono,Somente quando encontrado,Apenas quando encontrado,Doar la descoperire,После обнаружения,Само кад је пронађен,Sadece bulunduğunda -On for overlay only,OPTVAL_ONFOROVERLAYONLY,,,,Pouze v překryvném režimu,Kun til overlay,Nur auf Overlay,,Ŝaltita nur por surmeto,Solo para superpuesto,,Päällä vain karttaprojisoinnin kanssa,On pour Surimpression,Csak az overlayen,Solo attivo per la sovrapposizione,オーバーレイ専用,오버레이에만 작동,Alleen op voor overlay alleen voor overlay,På kun for overlegg,Włączony tylko dla nakładek,Ativado somente para sobreposição,Apenas ativado para sobreposição,Doar pentru modul transparent,Только наложенная,Укључен само за навлаку,Yalnızca kaplama için etkin -Overlay+Normal,OPTVAL_OVERLAYNORMAL,,,,Překryv + normální,Overlay+Normal,Overlay+Normal,,Surmeto+Normala,Superpuesto+Normal,,Projisointi+tavallinen,Surimpression+Normal,Overlay+Normál,Sovrapposizione+Normale,オーバーレイ+通常,오버레이+기본,Overlay+Normaal,,Nakładka+Normalnie,Sobreposição+Normal,,Transparent + Normal,Наложенная + обычная,Навлака + нормално,Yer Kaplama+Normal -Overlay Only,OPTVAL_OVERLAYONLY,,,,Pouze překryv,Kun overlay,Nur Overlay,,Nur Surmeto,Solo superpuesto,,Vain projisointi,Surimpression seulement,Csak Overlay-nél,Solo Sovrapposizione,オーバーレイのみ,오버레이만,Alleen Overlay,Kun overlegg,Tylko Nakładka,Sobreposição apenas,,Doar modul transparent,Только прозрачный,Навлак само,Yalnızca Kaplama -Not for hubs,OPTVAL_NOTFORHUBS,,,,Ne pro huby,Ikke for knudepunkter,Nicht für Hubs,,Ne por naboj,No para hubs,,Ei tasokokoelmille,Pas pour les hubs,Csomópontokhoz nem,Non per gli hub,区間では出さない,허브는 제외,Niet voor hubs,Ikke for nav,Nie dla hubów,Exceto hubs,,Nu pentru hub-uri,Кроме групп,Није за хубове,Hub'lar için değil -Front,OPTVAL_FRONT,,,,Zepředu,Forside,Frontalansicht,,Fronto,Frontal,,Etu,Devant,Előnézet,Fronte,画像,정면,Voorkant,Forside,Przód,Frente,,Înainte,Перед,Испред,Ön -Animated,OPTVAL_ANIMATED,,,,Animované,Animeret,Animiert,,Animita,Animado,,Animoitu,Animés,Animált,Animato,動作,움직임,Geanimeerd,Animert,Animowany,Animado,,Animat,Анимированные,Анимирано,Animasyonlu -Rotated,OPTVAL_ROTATED,,,,Otáčivé,Drejet,Rotiert,,Turnita,Rotado,,Kääntyvä,Tournés,Elforgatott,Ruotato,回転,회전함,Geroteerd,Rotert,Obrócony,Rotacionado,Rodado,Rotit,Повёрнутые,Ротирано,Döndürülmüş -Map defined colors only,OPTVAL_MAPDEFINEDCOLORSONLY,,,Map defined colours only,Pouze barvy definované mapou,Kun kortdefinerede farver,Nur Leveldefinierte Farben,,Nur mapaj difinitaj koloroj,Colores definidos por el usuario,,Vain kartan määrittämät värit,Couleurs définies carte seul.,Csak map orientált színek,Solo i colori definiti dalla mappa,指定した色のみ,자체 미니맵 색상 사용,Alleen gedefinieerde kleuren op de kaart,Kun kartdefinerte farger,Tylko kolory zdefiniowane przez mapę,Cores definidas por mapa apenas,,Doar culori specifice hărții,Только определённые картой цвета,Само дефинисане мапом боје,Yalnızca harita tanımlı renkler -All except doors,OPTVAL_NODOORS,,,,Všechny krom dveří,Alle undtagen døre,Alle außer Türen,,Ĉiom krom pordoj,Todo excepto puertas,,Kaikki paitsi ovet,Tout sauf portes,"Minden, kivétel az ajtók",Tutti eccetto le porte,ドア以外全て,문을 제외한 모두,Allemaal behalve deuren,Alle unntatt dører,Wszystko oprócz drzwi,Tudo exceto portas,,Cu excepția ușilor,Кроме дверей,Све осим врата,Kapılar hariç hepsi -Double,OPTVAL_DOUBLE,,,,Dvojitý,Dobbelt,Doppel,,Duobligi,Doble,,Kaksinkertainen,,Dupla,Doppio,ダブル,2배,Dubbele,Dobbel,Podwójny,Dobro,,Dublu,Двойной,Дупло,Çift -Triple,OPTVAL_TRIPLE,,,,Trojitý,Tredobbelt,Dreifach,,Triobligi,,,Kolminkertainen,,Tripla,Triplo,トリプル,3배,Drievoudig,Trippel,Potrójny,Triplo,,Triplu,Тройной,Тродупло,Üçlü -Quadruple,OPTVAL_QUADRUPLE,,,,Čtveritý,Firedobbelt,Vierfach,,Kvarobligi,Cuádruple,,Nelinkertainen,,Négyszeres,Quadruplo,クァッド,4배,Viervoudig,Firedoblet,Poczwórny,Quádruplo,,Cvadruplu,Четырёхкратный ,Четвороструко,Dörtlü -Item Pickup,OPTVAL_ITEMPICKUP,,,,Sebrání předmětu,Afhentning af varer,Gegenstand genommen,,Objektoprenado,Recogida de objetos,,Esineen poiminta,Objets Ramassés,Tárgy felvétele,Raccolta oggetto,アイテム取得,아이템 획득시,Puntafhaling,Varehenting,Podniesienie Przedmiotu,Coleta de Item,Aquisição de Itens,Obiect Ridicat,Подбор предметов,Подигнут предмет,Bir eşyayı almak -Obituaries,OPTVAL_OBITUARIES,,,,Oznámení o smrti,Dødsannoncer,Todesanzeige,,Nekrologoj,Obituarios,,Kuolinviestit,Avis de décès,Halálok,Necrologio,死亡時,사망 메시지,Doodsbrieven,Dødsannonser,Nekrologi,Obituários,,Necrologuri,Некрологи,Читуље,Ölüm İlanları -Critical Messages,OPTVAL_CRITICALMESSAGES,,,,Kritická oznámení,Kritiske meddelelser,Kritische Meldungen,,Gravaj Mesaĝoj,Mensajes críticos,,Tärkeät viestit,Messages Critiques,Fontos üzenetek,Messaggi critici,重要メッセージ,중요한 메시지,Kritische berichten,Kritiske meldinger,Wiadomości krytyczne,Mensagens Críticas,,Mesaje Critice,Важные сообщения,Критичне поруке,Kritik Mesajlar -Never friends,OPTVAL_NEVERFRIENDS,,,,Nikdy spojence,Aldrig venner,Keine Freunde,,Neniam amikoj,Nunca amigos,,Ei koskaan ystäviä,Jamais les Amis,Barátokat sose,Mai amici,フレンド以外,아군 무시,Nooit vrienden,Aldri venner,Żadnych przyjaciół,Nunca amigos,,Nu aliați,Не по союзникам,Никад за пријатеље,Asla arkadaş değil -Only monsters,OPTVAL_ONLYMONSTERS,,,,Pouze příšery,Kun monstre,Nur Monster,,Nur monstroj,Solo monstruos,,Vain hirviöt,Monstres Seulement,Csak szörnyeket,Solo i mostri,モンスターのみ,적에게만,Alleen monsters,Bare monstre,Tylko potwory,Somente monstros,Monstros apenas,Doar monștri,Для монстров,Само чудовишста,Sadece canavarlar -Hexen,OPTVAL_HEXEN,,,,,,,,,,,,Hexen,,,,헥센,,,,,,,,, -Old,OPTVAL_OLD,,,,Starý,Gamle,Alt,,Maljuna,Viejo,,Vanha,Ancien,Régi,Vecchio,旧式,구형,Oud,Gamle,Stare,Antigo,,Vechi,Старый,Стар,Eski -Doom,OPTVAL_DOOM,,,,,,,,,,,,,,,,둠,,,,,,,,, -Doom (strict),OPTVAL_DOOMSTRICT,,,,Doom (striktní),Doom (streng),Doom (strikt),,Doom (severa),Doom (estricto),,Doom (tiukka),,Doom (szigorú),Doom (rigoroso),Doom(厳密),둠 (엄격하게),Doom (streng),Doom (streng),Doom (ścisły),Doom (estritamente),Doom (estrito),,Doom (строгий),Doom (строг),Doom (katı) -Boom,OPTVAL_BOOM,,,,,,,,,,,,,,,,붐,,,,,,,,, -Boom (strict),OPTVAL_BOOMSTRICT,,,,Boom (striktní),Boom (streng),Boom (strikt),,Boom (severa),Boom (estricto),,Boom (tiukka),,Boom (szigorú),Boom (rigoroso),Boom(厳密),붐 (엄격하게),Boom (streng),Boom (streng),Boom (ścisły),Boom (estritamente),Boom (estrito),,Boom (строгий),Boom (строг),Boom (katı) -MBF,OPTVAL_MBF,,,,,,,,,,,,,,,,마린의 절친한 친구,,,,,,,,, -MBF (strict),OPTVAL_MBFSTRICT,,,,MBF (striktní),MBF (streng),MBF (strikt),,MBF (severa),MBF (estricto),,MBF (tiukka),,MBF (szigorú),MBF (rigoroso),MBF(厳密),마린의 절친한 친구 (엄격하게),MBF (streng),MBF (streng),MBF (ścisły),MBF (estritamente),MBF (estrito),,MBF (строгий),MBF (строг),MBF (katı) -ZDoom 2.0.63,OPTVAL_ZDOOM2063,,,,,,,,,,,,,,,,Z둠 2.0.63,,,,,,,,, -All unacknowledged,OPTVAL_ALLUNACKNOWLEDGED,,,,Všechny nepotrvzené,Alle ubekræftede,Alle unbestätigten,,Ĉiuj neagnoskitaj,Todos no reconocidos,,Kaikki kuittaamattomat,Tout non-acknowledged,Minden visszaigazolatlan,Tutti non riconosciuti,未確認全て,모두 미확인함,Allemaal onbekend,Alle ubekreftet,Wszystkie niepotwierdzone,Todos não-reconhecidos,,Toate necunoscute,Всё неопознанное,Све неусвојено,Tüm onaylanmamış -Errors,OPTVAL_ERRORS,,,,Chyby,Fejl,Fehler,,Eraroj,Errores,,Virheet,Erreurs,Hibák,Errori,エラー,에러,Fouten,Feil,Błędy,Erros,,Erori,Ошибки,Грешка,Hatalar -Warnings,OPTVAL_WARNINGS,,,,Varování,Advarsler,Warnungen,,Avertoj,Advertencias,,Varoitukset,Avertissements,Figyelmeztetések,Avvisi,警告,경고,Waarschuwingen,Advarsler,Ostrzeżenia,Avisos,,Atenționări,Предупреждения,Упозорење,Uyarılar -Notifications,OPTVAL_NOTIFICATIONS,,,,Oznámení,Meddelelser,Benachrichtigungen,,Sciigoj,Notificaciones,,Ilmoitukset,,Üzenetek,Notifiche,通知,알림,Kennisgevingen,Varsler,Powiadomienia,Notificações,,Notificări,Уведомления,Обавештење,Bildirimler -Everything,OPTVAL_EVERYTHING,,,,Všechno,Alt,Alles,,Ĉio,Todo,,Kaikki,Tout,Minden,Tutti,全て,전체,Alles,Alt,Wszystko,Tudo,,Tot,Всё,Све,Her şey -Hardware accelerated,OPTVAL_HWPOLY,,,,Hardwarová akcelerace,Hardware accelereret,Hardwarebeschleunigt,,Aparatara Plirapidigo,Acelerado por Hardware,,Laitteistokiihdytetty,Accéléré par Hardware,Hardveres gyorsítás,Accelerazione Hardware,ハードウェア アクセラレート,오픈지엘 가속,Hardware versneld,Maskinvareakselerert,Napędzane sprzętowo,Acelerado por hardware,,Accelerat Hardware,Аппаратный,Харвер убрзан,Hızlandırılmış donanım -Doom Software Renderer,OPTVAL_SWDOOM,,,,Doom softwarový renderer,,,,Program-bildigilo de Doom,Renderizado por Software de Doom,,Doomin ohjelmistohahmonnin,Rendu Software Doom,Doom szoftveres renderer,Rendering DOOM software,Doom ソフトウェアレンダー,둠 소프트웨어 렌더러,,,Renderer Oprogramowania Dooma,Renderizador Software do Doom,,Software,Doom-программный,Doom софтверски рендерер,Doom Yazılım Oluşturucu -True Color SW Renderer,OPTVAL_SWDOOMTC,,,,True color softwarový renderer,,,,Program-bildigilo kun Plenkoloro,Renderizado SW Color Verdadero,Renderizado SW True Color,True Color -ohjelmistohahmonnin,Rendu Software Couleurs Réeles,,Rendering software a pieni colori,トゥルーカラー SWレンダー,트루 컬러 소프트웨어 렌더러,,,Renderer True Color,Renderizador Software True Color,,Software Color Complet,Полноцветный програмный,SW рендерер праве боје,Gerçek Renk SW Oluşturucu -High-Performance,OPTVAL_DEDICATED,,,,Vysoký výkon,Højtydende,Volle Leistung,,Alta Rendimento,Alto rendimiento,,Korkea suorituskyky,Hautes Performances,Nagy teljesítmény,Prestazioni massime,ハイパフォーマンス,고 성능,Hoogwaardige prestaties,Høy ytelse,Wysoka Wydajność,Alta-Performance,,De înaltă performanță,Высокая производительность,Високо-перформанси,Yüksek Performans -Power-Saving,OPTVAL_INTEGRATED,,,,Nízká spotřeba,Strømbesparende,energiesparend,,Energikonservo,Ahorro de energía,,Virransäästö,Economie d'Energie,Energia takarékos,Risparmio energetico,パワーセービング,저전력,Energiebesparing,Strømsparende,Oszczędzanie Energii,Economia de Energia,,Economie de energie,Энергосбережение,Енергетско-штедљиви,Güç Tasarrufu -Vanilla,OPTVAL_VANILLA,,,,Původní,,,,Originala,,,Alkuperäinen,,Hagyományos,Vanilla,バニラ,바닐라,,,Czysty,,,Original,Изначальный,Ванила,Vanilya -ZDoom (Forced),OPTVAL_VTFZDOOM,,,,ZDoom (vynucený),ZDoom (tvunget),ZDoom (erzwungen),,ZDoom (Devigita),ZDoom (forzado),,ZDoom (pakotettu),ZDoom (Forcé),ZDoom (erőltetett),ZDoom (forzato),ZDoom(強制),ZDoom (강제 설정),ZDoom (Gedwongen),ZDoom (Tvunget),ZDoom (Wymuszony),ZDoom (Forçar),,ZDoom (Forțat),ZDoom (принудительно),ZDoom (присиљен),ZDoom (Zorla) -Vanilla (Forced),OPTVAL_VTFVANILLA,,,,Původní (vynucený),Vanilla (tvungen),Vanilla (erzwungen),,Originala (Devigita),Vanilla (Forzado),,Perus (pakotettu),Vanilla (Forcé),Hagyományos (erőltettt),Vanilla (forzato),バニラ(強制),바닐라 (강제 설정),Vanilla (Gedwongen),Vanilla (Tvunget),Czysty (Wymuszony),Vanilla (Forçar),DOS Original (Forçar),Original (Forțat),Изначальный (принудительно),Ванила (присиљен),Vanilya (Zorlanmış) -Auto (ZDoom Preferred),OPTVAL_VTAZDOOM,,,,Auto (preferován ZDoom),Auto (ZDoom foretrukket),Auto (ZDoom bevorzugt),,Aŭtomata (ZDoom Preferita),Auto (ZDoom preferido),,Automaattinen (ZDoomia suosiva),Auto (ZDoom Préféré),Automata (ZDoom preferált),Automatico (ZDoom preferito),自動(ZDoom優先),자동 (ZDoom 기본 설정),Auto (bij voorkeur ZDoom),Auto (ZDoom foretrukket),Automatyczny (Preferowany ZDoom),Automático (De preferência ZDoom),,Auto (ZDoom preferat),Автоматически (предпочитать ZDoom),Аутоматски (ZDoom преферијални),Otomatik (ZDoom Tercih Edilir) -Auto (Vanilla Preferred),OPTVAL_VTAVANILLA,,,,Auto (preferován původní),Auto (Vanilla foretrukket),Auto (Vanilla bevorzugt),,Aŭtomata (Originala Preferita),Auto (Vanilla preferido),,Automaattinen (alkuperäistä suosiva),Auto (Vanilla Préféré),Automata (Hagyományos preferált),Automatico (Vanilla preferito),自動(バニラ優先),자동 (바닐라 기본 설정),Auto (bij voorkeur Vanilla),Auto (Vanilla foretrukket),Automatyczny (Preferowany czysty),Automático (De preferência Vanilla),Automático (De preferência DOS Original),Auto (Original preferat),Автоматически (предпочитать изначальный),Аутоматски (ванила преферијални),Otomatik (Vanilya Tercihli) -Small,OPTVAL_SMALL,,,,Malé,Lille,Klein,,Malgranda,Pequeño,,Pieni,Petit,Kicsi,Piccolo,小,작게,Klein,Liten,Mały,Pequeno,,Mic,Мелкий,Мало,Küçük -Large,OPTVAL_LARGE,,,,Velké,Stor,Groß,,Granda,Grande,,Suuri,Grand,Nagy,Grande,大,크게,Groot,Stor,Duży,Grande,,Mare,Крупный,Велико,Büyük -Console,OPTVAL_CONSOLE,,,,Konzole,Konsol,Konsole,,Konzolo,Consola,,Konsoli,Console,Konzol,,コンソール,콘솔,Console,Konsoll,Konsola,Console,Consola,Consolă,Консольный,Конзола,Konsol -\caBrick,C_BRICK,,,,\caCihlová,\caMursten,\caZiegelrot,,\caBrikkolora,\caLadrillo,,\catiili,\cabrique,\catéglavörös,\camattone,\ca丹,\ca주홍색,\casteenrood,\caMurstein,\cacegła,\catijolo,,\caCărămiziu,\caКирпичный,\caБоја цигле,\caTuğla -\cbTan,C_TAN,,,,\cbSvětle hnědá,,\cbHellbraun,,\cbTankolora,\cbBeis,\cbTostado,\cbkeltaruskea,\cbbeige,\cbbézs,\cbabbronzatura,\cb香,\cb상아색,\cblichtbruin,\cbBrun,\cbjasnobrązowy,\cbbege,,\caBronz,\cbБежевый,\cbБеж,\cbTan -\ccGray,C_GRAY,,,\ccgrey,\ccŠedá,\ccGrå,\ccGrau,,\ccGriza,\ccGris,,\ccharmaa,\ccgris,\ccszürke,\ccgrigio,\cc灰,\cc회색,\ccgrijs,\ccGrå,\ccszary,\cccinza,,\ccGri,\ccСерый,\ccСива,\ccGri -\cdGreen,C_GREEN,,,,\cdZelená,\cdGrøn,\cdGrün,,\cdVerda,\cdVerde,,\cdvihreä,\cdvert,\cdzöld,\cdverde,\cd緑,\cd녹색,\cdgroen,\cdGrønn,\cdzielony,\cdverde,,\cdVerde,\cdЗелёный,\cdЗелена,\cdYeşil -\ceBrown,C_BROWN,,,,\ceHnědá,\ceBrun,\ceBraun,,\ceBruna,\ceMarrón,\ceCafé,\ceruskea,\cebrun,\cebarna,\cemarrone,\ce茶,\ce갈색,\cebruin,\ceBrun,\cebrązowy,\cemarrom,,\ceMaro,\ceКоричневый,\ceСмеђа,\ceKahverengi -\cfGold,C_GOLD,,,,\cfZlatá,\cfGuld,,,\cfOrkolora,\cfDorado,,\cfkulta,\cfor,\cfarany,\cforo,\cf金,\cf금색,\cfgoud,\cfGull,\cfzłoty,\cfdourado,,\cfAuriu,\cfЗолотой,\cfЗлатна,\cfAltın -\cgRed,C_RED,,,,\cgČervená,\cgRød,\cGrot,,\cfRuĝa,\cgRojo,,\cgpunainen,\cgrouge,\cgvörös,\cgrosso,\cg赤,\cg적색,\cgrood,\cgRød,\cgczerwony,\cgvermelho,,\gRoșu,\cgКрасный,\cgЦрвена,\cgKırmızı -\chBlue,C_BLUE,,,,\chModrá,\chBlå,\chBlau,,\chBlua,\chAzul,,\chsininen,\chbleu,\chkék,\chblu,\ch青,\ch청색,\chblauw,\chBlå,\chniebieski,\chazul,,\chAlbastru,\chСиний,\chПлава,\chMavi -\ciOrange,C_ORANGE,,,,\ciOranžová,,,,\ciOranĝkolora,\ciNaranja,,\cioranssi,\ciorange,\cinarancs,\ciarancione,\ci橙,\ci주황색,\cioranje,\ciOransje,\cipomarańczowy,\cilaranja,,\ciPortocaliu,\ciОранжевый,\ciНаранџаста,\ciTuruncu -\cjWhite,C_WHITE,,,,\cjBílá,\cjHvid,\cjWeiß,,\cjBlanka,\cjBlanco,,\cjvalkoinen,\cjblanc,\cjfehér,\cjbianco,\cj白,\cj흰색,\cjwit,\cjHvit,\cjbiały,\cjbranco,,\cjAlb,\cjБелый,\cjБела,\cjBeyaz -\ckYellow,C_YELLOW,,,,\ckŽlutá,\ckGul,\ckGelb,,\ckFlava,\ckAmarillo,,\ckkeltainen,\ckjaune,\cksárga,\ckgiallo,\ck黄,\ck노란색,\ckgeel,\ckGul,\ckżółty,\ckamarelo,,\ckGalben,\ckЖёлтый,\ckЖута,\ckSarı -\clDefault,C_DEFAULT,,,,\clVýchozí,\clStandard,\clStandard,,\clDefaŭlta,\clPor defecto,,\cloletus,\cldéfaut,\clalap,\cldefault,\cl初期,\cl기본 색,\clstandaard,\clStandard,\cldomyślny,\clpadrão,,\clImplicită,\clПо умолчанию,\clУобичајена,\clVarsayılan -\cmBlack,C_BLACK,,,,\cmČerná,\cmSort,\cmSchwarz,,\cmNigra,\cmNegro,,\cmmusta,\cmnoir,\cmfekete,\cmnero,\cm黒,\cm검은색,\cmzwart,\cmSvart,\cmczarny,\cmpreto,,\cmNegru,\cmЧёрный,\cmЦрна,\cmSiyah -\cnLight blue,C_LIGHTBLUE,,,,\cnSvětle modrá,\cnLyseblå,\cnHellblau,,\cnHelblua,\cnAzul claro,,\cnvaaleansininen,\cnbleu clair,\cnvilágoskék,\cnblu chiaro,\cn空,\cn하늘색,\cnlicht blauw,\cnLyseblå,\cnjasnoniebieski,\cnazul claro,,\cnAlbastru deschis,\cnГолубой,\cnСветло плава,\cnAçık mavi -\coCream,C_CREAM,,,,\coKrémová,\coCreme,\coCremefarben,,\coKremkolora,\coCrema,,\cokerma,\cocrème,\cokrémszínű,\cocrema,\co肉,\co살구색,\cocrème,\coKremfarget,\cokremowy,\cocreme,,\coCrem,\coКремовый,\coКрем,\coKrem -\cpOlive,C_OLIVE,,,,\cpOlivová,\cpOliven,\cpOliv,,\cpOlivkolora,\cpOliva,,\cpoliivi,\cpolive,\cpolíva,\cpoliva,\cp泥,\cp녹갈색,\cpolijf,\cpOliven,\cpoliwkowy,\cpoliva,,\cpMăsliniu,\cpОливковый,\cpМаслинаста,\cpZeytin -\cqDark green,C_DARKGREEN,,,,\cqTmavě zelená,\cqMørkegrøn,\cqDunkelgrün,,\cqMalhelverda,\cqVerde oscuro,,\cqtummanvihreä,\cqvert sombre,\cqsötétzöld,\cqverde scuro,\cq深,\cq암녹색,\cqdonkergroen,\cqMørkegrøn,\cqciemnozielony,\cqverde escuro,,\cqVerde închis,\cqТёмно-зелёный,\cqТамно зелена,\cqKoyu yeşil -\crDark red,C_DARKRED,,,,\crTmavě červená,\crMørkerød,\crDunkelrot,,\crMalhelruĝa,\crRojo oscuro,,\crtummanpunainen,\crrouge sombre,\crsötétvörös,\crrosso scuro,\cr朱,\cr암적색,\crdonkerrood,\crMørkerød,\crciemnoczerwony,\crvermelho escuro,,\crRoșu închis,\crТёмно-красный,\crБордо,\crKoyu kırmızı -\csDark brown,C_DARKBROWN,,,,\csTmavě hnědá,\csMørkebrun,\csDunkelbraun,,\csMalhelbruna,\csMarrón oscuro,\csCafé oscuro,\cstummanruskea,\csbrun sombre,\cssötétbarna,\csmarrone scuro,\cs焦,\cs암갈색,\csdonkerbruin,\csMørkebrun,\csciemnobrązowy,\csmarrom escuro,,\csMaro închis,\csТёмно-коричневый,\csБраон,\csKoyu kahverengi -\ctPurple,C_PURPLE,,,,\ctFialová,\ctLilla,\ctLila,,\ctPurpura,\ctMorado,,\ctpurppura,\ctviolet,\ctlila,\ctviola,\ct紫,\ct보라색,\ctpaars,\ctLilla,\ctfioletowy,\ctroxo,,\ctMov,\ctФиолетовый,\ctЉубичаста,\ctMor -\cuDark gray,C_DARKGRAY,,,\cudark grey,\cuTmavě šedá,\cuMørkegrå,\cuDunkelgrau,,\cuMalhelgriza,\cuGris oscuro,,\cutummanharmaa,\cugris sombre,\cusötétszürke,\cugrigio scuro,\cu鉛,\cu치색,\cudonkergrijs,\cuMørkegrå,\cuciemnoszary,\cucinza escuro,,\cuGri închis,\cuТёмно-серый,\cuТамно сива,\cuKoyu gri -\cvCyan,C_CYAN,,,,\cvAzurová,,\cvTürkis,,\cvCejana,\cvCián,,\cvsinivihreä,\cvcyan,\cvcián,\cvciano,\cv天,\cv청록색,\cvcyan,,\cvbłękitny,\cvciano,,\cvTurcoaz,\cvСине-зелёный,\cvЦијан,\cvCyan -\cwIce,C_ICE,,,,\cwLed,\cwIs,\cwEis,,\cwGlacikolora,\cwHielo,,\cwjää,\cwglace,\cwjég,\cwghiaccio,\cw氷,\cw구색,\cwice,\cwIs,\cwlód,\cwgelo,,\cwGheață,\cwЛедяной,\cwЛед,\cwBuz -\cxFire,C_FIRE,,,,\cxOheň,\cxIld,\cxFeuer,,\cxFajrkolora,\cxFuego,,\cxtuli,\cxfeu,\cxtűz,\cxfuoco,\cx炎,\cx자황색,\cxvuur,\cxIld,\cxogień,\cxfogo,,\cxFoc,\cxОгненный,\cxВатрена,\cxYangın -\cySapphire,C_SAPPHIRE,,,,\cySafírová,\cySafir,\cySaphirblau,,\cySafirkolora,\cyZafiro,,\cysafiiri,\cysaphir,\cyzafír,\cyzaffiro,\cy藍,\cy벽청색,\cysaffier,\cySafir,\cyszafirowy,\cysafira,,\cySafir,\cyСапфировый,\cyТамно плава,\cySafir -\czTeal,C_TEAL,,,,\czModrozelená,\czKrikand,\czBlaugrün,,\czBluverda,\czTurquesa,,\cztummansinivihreä,\czturquoise,\cztürkiz,\czverde acqua,\cz碧,\cz암청록색,\czteal,\czBlågrønn,\czmorski,\czturquesa,,\czMare,\czМорской,\czТиркизна,\czDeniz mavisi -Heretic,OPTSTR_HERETIC,,,,,,,,,,,,,,,,헤러틱 커서,,,,,,,,, -Chex,OPTSTR_CHEX,,,,,,,,,,,,,,,,첵스 커서,,,,,,,,, -No Sound,OPTSTR_NOSOUND,,,,Bez zvuku,Ingen lyd,Kein Sound,,Neniu Sono,Sin sonido,,Ei ääntä,Pas de son,Hang nélkül,Nessun suono,サウンドなし,음향 없음,Geen geluid,Ingen lyd,Brak dźwięku,Sem som,,Fără Sunet,Без звука,Без-звучни,Ses Yok -No interpolation,OPTSTR_NOINTERPOLATION,,,,Bez interpolace,Ingen interpolation,Keine Interpolation,,Neniu interpolado,Sin interpolación,,Ei interpolaatiota,Pas d'interpolation,Nincs interoláció,No interpolazione,補間無し,보간 없음,Geen interpolatie,Ingen interpolasjon,Brak interpolacji,Sem interpolação,,Fără interpolare,Без сглаживания,Нема уметања,Enterpolasyon yok -Spline,OPTSTR_SPLINE,,,,Křivka,,,,Splajno,,,Splini,,,,スプライン,스플라인,,,,,,,Сплайн,Сплајн, -OpenAL,OPTSTR_OPENAL,,,,,,,,,,,,,,,,오픈에이엘,,,,,,,,, -Hardware Renderer,DSPLYMNU_GLOPT,,,,Hardwarový renderer,,,,Aparatara Bildigilo,Renderizado por Hardware,,Laitteistohahmonnin,Moteur de Rendu Hardware,Hardver Render,Rendering Hardware,ハードウェア レンダラー,오픈지엘 렌더러,,,Renderer Sprzętowy,Renderizador Hardware,,Setări Mod OpenGL,Отрисовка с OpenGL,Хардвер рендерер,Donanım Oluşturucu -Software Renderer,DSPLYMNU_SWOPT,,,,Softwarový renderer,,,,Programa Bildigilo,Renderizado por Software,,Ohjelmistohahmonnin,Moteur de Rendu Software,Szoftver Render,Rendering Software,ソフトウェア レンダラー,소프트웨어 렌더러,,,Renderer Oprogramowania,Renderizador Software,,Setări Mod Software,Программная отрисовка,Софтвер рендерер,Yazılım Oluşturucu -Hardware Rendering Options,GLMNU_TITLE,,,,Nastavení hardwarového rendereru,Indstillinger for hardware-rendering,Hardware-Renderer Optionen,,Agordoj de La Aparatara Bildigilo,Opciones de OpenGL,,Laitteistohahmonnusasetukset,Options OpenGL,Hardver Renderelő Beállítások,Opzioni OpenGL,ハードウェアレンダリング オプション,오픈지엘 설정,Hardware Rendering Opties,Alternativer for maskinvaregjengivelse,Opcje Renderowania Sprzętowego,Opções de Renderização por Hardware,,Setări Redare OpenGL,Настройки OpenGL,Опција хардвер рендера,Donanım Oluşturma Seçenekleri -Dynamic Light Options,GLMNU_DYNLIGHT,,,,Nastavení dynamických světel,Indstillinger for dynamisk lys,Dynamisches-Licht-Optionen,,Agordoj de Dinamikaj Lumoj,Opciones de luz dinámica,,Dynaamisen valon asetukset,Options Lumières Dynamiques,Dinamikus Fény Beállítások,Opzioni Luci Dinamiche,ダイナミックライト オプション,광원 설정,Dynamische Licht Opties,Alternativer for dynamisk lys,Opcje Dynamicznego Oświetlenia,Opções de Luz Dinâmica,,Setări Lumini Dinamice,Динамическое освещение,Подешавања динамичког осветљења,Dinamik Işık Seçenekleri -Preferences,GLMNU_PREFS,,,,Možnosti,Præferencer,Einstellungen,,Preferoj,Preferencias,,Asetukset,Préférences,Preferenciák,Preferenze,環境設定,성능,Voorkeuren,Innstillinger,Preferencje,Preferências,,Preferințe,Настройки,Преференција,Tercihler -Trim sprite edges,GLTEXMNU_TRIMSPREDGE,,,,Oříznout okraje spritů,Trimme sprite-kanter,Leerraum in Sprites wegschneiden,,Ĉirkaŭtranĉi randojn de spritoj,Recortar líneas de sprite,,Siisti spritejen reunat,Nettoyer le bord des sprites,Sprite szél igazítása,Taglia gli spigoli agli sprite,スプライトの角を取る,스프라이트 모서리 다듬기,,Trim sprite kanter,Przycinanie krawędzi sprite'ów,Cortar bordas de sprites,,Tundere margini sprite-uri,Обрезание краёв спрайтов,Подсећи ивице спрајтова,Sprite kenarlarını kırpma -Sort draw lists by texture,GLTEXMNU_SORTDRAWLIST,,,,Seřadit vykreslování podle textury,Sortere tegningslister efter tekstur,Renderlisten nach Textur sortieren,,Ordigi desegnado-listojn laŭ teksturo,Ordenar tablas por textura,,Lajittele piirtotaulut pintakuvioinneittain,Ordonner liste de rendu par texture,Textúra szerinti kirajzolási lista,Ordina la lista draw per texture,テクスチャーから描画リストを分類,텍스처별로 생성 목록 정렬,Tekeninglijsten sorteren op textuur,Sorter tegningslister etter tekstur,Sortowanie list renderowania wdług tekstur,Organizar listas de renderização por textura,,Sortează listele de texturi,Сортировать списки текстур,Сортирано цртај листе од текстуре,Çizim listelerini dokuya göre sıralama -Dynamic Lights,GLLIGHTMNU_TITLE,,,,Dynamická světla,Dynamisk lys,Dynamische Lichter,,Dinamikaj Lumoj,Luces dinámicas,,Dynaamiset valot,Lumières Dynamiques,Dinamikus Fények,Luci Dinamiche,ダイナミックライト,다이나믹 라이트,Dynamische verlichting,Dynamiske lys,Dynamiczne Oświetlenie,Luzes Dinâmicas,,Lumini Dinamice,Динамическое освещение,Динамичко осветљење,Dinamik Işıklar -Dynamic Lights (Hardware),GLLIGHTMNU_LIGHTSENABLED,,,,Dynamická světla (hardware),Dynamisk lys (hardware),Dynamische Lichter (Hardware),,Dinamikaj Lumoj (Aparataro),Luces dinámicas (Hardware),,Dynaamiset valot (laitteistokiihdytys),Lumières Dynamiques (Hardware),Dinamikus Fények (hardveres),Luci Dinamiche (Hardware),ダイナミックライト(OpenGL),다이나믹 라이트(오픈지엘),Dynamische verlichting (hardware),Dynamiske lys (maskinvare),Dynamiczne Oświetlenie (Sprzętowe),Luzes Dinâmicas (Hardware),,Lumini Dinamice (OpenGL),Динамическое освещение (аппаратное),Динамичко осветљење (хардвер),Dinamik Işıklar (Donanım) -Enable light definitions,GLLIGHTMNU_LIGHTDEFS,,,,Povolit definice světel,Aktiver lysdefinitioner,Lichtdefinitionen an,,Ŝalti lumdifinojn,Activar definiciones de luz,,Ota käyttöön valomääritykset,Activer les définitions de lumière,Fény részletesség,Abilita le definizioni GLDEFS,ライト定義 許可,조명 선명도 사용,Lichtdefinities mogelijk maken,Aktiver lysdefinisjoner,Włącz definicje światła,Habilitar definições de luz,Permitir definições de luz,Activează definiții lumini,Включить определения света,Омогући светлосне дефиниције,Işık tanımlarını etkinleştirin -Lights affect sprites,GLLIGHTMNU_LIGHTSPRITES,,,,Světla ovlivňují sprity,Lys påvirker sprites,Sprites werden beleuchtet,,Lumoj efiki spritojn,Las luces afectan a los sprites,,Valot vaikuttavat spriteihin,Lumières affectent les sprites,A fény hatással van a sprite-okra,Le luci influiscono sugli sprite,ライトがスプライトに影響,조명에 영향받는 스프라이트,Lichten beïnvloeden sprites,Lys påvirker sprites,Światło ma wpływ na sprite'y,Luzes afetam sprites,,Luminile afectează sprite-urile,Освещать спрайты,Светло утиче на спрајтове,Işıklar sprite'ları etkiler -Lights affect particles,GLLIGHTMNU_LIGHTPARTICLES,,,,Světla ovlivňují částice,Lys påvirker partikler,Partikel werden beleuchtet,,Lumoj efiki partiklojn,Las luces afectan a las partículas,,Valot vaikuttavat hiukkasiin,Lumières affectent les particules,A fény hatással van a részecskékre,Le luci influiscono sulle particelle,ライトがパーティクルに影響,조명에 영향받는 입자들,Lichten beïnvloeden deeltjes,Lys påvirker partikler,Światło ma wpływ na cząsteczki,Luzes afetam partículas,,Luminile afectează particulele,Освещать частицы,Светло утиче на честице,Işıklar parçacıkları etkiler -Light shadowmaps,GLLIGHTMNU_LIGHTSHADOWMAP,,,,Mapy stínů,Lys skyggemapper,Shadowmaps für Lichter,,Lum-ombro-mapoj,Mapeo de sombra de Luz,,Valojen varjokartat,Shadowmaps,,Ombre proiettate,ライトのシャドウマッピング,조명에 영향받는 섀도우맵,Lichte schaduwkaarten,Lys skyggekart,Oświetlenie map cieni,Shadowmaps,,Umbre lumini,Карты светотеней,Светло мапе сенки,Işık gölge haritaları -Shadowmap quality,GLLIGHTMNU_LIGHTSHADOWMAPQUALITY,,,,Kvalita map stínů,Shadowmap-kvalitet,Shadowmap Qualität,,Kvalito de ombro-mapo,Calidad de Mapeo de Sombras,,Varjokarttojen laatu,Qualité Shadowmap,Shadowmap minőség,Qualità ombre proiettate,シャドウマップ 品質,섀도우맵 퀄리티,Schaduwkaart kwaliteit,Shadowmap-kvalitet,Jakość map cieni,Qualidade de shadowmap,,Calitate umbre,Качество карт светотеней,Мапа сенки квалитет,Gölge haritası kalitesi -Shadowmap filter,GLLIGHTMNU_LIGHTSHADOWMAPFILTER,,,,Filtrování map stínů,Skyggemap-filter,Shadowmap Filter,,Filtro de ombro-mapo,Filtro de Mapeo de Sombras,,Varjokarttojen suodatus,Filtre de Shadowmaps,,Filtro ombre proiettate,シャドウマップ フィルター,섀도우맵 필터,Schaduwkaart filter,Shadowmap-filter,Filtr map cieni,Filtro de shadowmap,,Filtru umbre,Фильтр карт светотеней,Мапа сенки филтер,Gölge haritası filtresi -Fog mode,GLPREFMNU_FOGMODE,,,,Režim mlhy,Tågetilstand,Nebelmodus,,Reĝimo de nebulo,Modo de niebla,,Sumutila,Mode du broullard,Köd mód,Modalità nebbia,フォグモード,안개 모드,Mistmodus,Tåke-modus,Tryb mgły,Modo de neblina,,Mod ceață,Режим тумана,Магла мод,Sis modu -Fog forces fullbright,GLPREFMNU_FOGFORCEFULLBRIGHT,,,,Mlha vynucuje plný jas,Tåge tvinger fullbright,Nebel erzwingt volle Helligkeit,,Nebulo devigas plenbrilon,Forzar brillo completo en niebla,,Sumu pakottaa täyskirkkauden,Brouillard force fullbright,Köd Fullbright-ot erőltet ki,La nebbia forza piena luce,濃霧は明るさ最大,안개를 최대한 강제로 밝힘,Mistkrachten volle lichtsterkte,Tåke styrker fullbright,Mgła wymusza pełną jasność,Neblina força brilho máximo,,Ceața forțează luminozitate maximă,Туман включает режим максимальной яркости,Магла присиљава пуну светлост,Sis fullbright'ı zorlar -Weapon light strength,GLPREFMNU_WPNLIGHTSTR,,,,Intenzita světel zbraní,Våbenlysstyrke,Waffenlichtstärke,,Lumforteco de armilo,Intensidad de luz de las armas,,Aseiden valovoima,Intensité lumineuse des armes,Fegyver lövés fényerősség,Intensità luminosa dell'arma,武器ライトの強さ,무기 빛 강도,Sterkte van het wapenlicht,Våpen lysstyrke,Natężenie światła broni,Intensidade de luz da arma,,Intensitate lumină armă,Интенсивность вспышек оружия,Блага снага оружја,Silah ışık gücü -Environment map on mirrors,GLPREFMNU_ENVIRONMENTMAPMIRROR,,,,Mapa prostředí na zrcadlech,Miljøkort på spejle,Lichteffekt auf Spiegeln,,Medimapo sur speguloj,Mapa de entorno en espejos,,Ympäristökartta peileissä,Mappage environment sur les miroirs,Környezeti mappolás a tükrökön,Ambiente mappa sui riflessi,マップオンミラーの画像表示,거울 주변의지도 활성,Milieukaart op spiegels,Omgivelseskart på speil,Mapa środowiska w lustrach,Mapa de ambiente em espelhos,,Reflecții pe oglinzi,Карта окружения на зеркалах,Околинска мапа на прозорима,Aynalar üzerinde çevre haritası -Enhanced night vision mode,GLPREFMNU_ENV,,,,Vylepšený režim nočního vidění,Forbedret nattesynstilstand,Verbesserter Nachtsichtmodus,,Plibonigita reĝimo de noktvido,Modo de visión nocturna mejorado,,Paranneltu pimeänäkötila,Mode de vision nocture amélioré,Felerősített éjjellátó mód,Modalità visione notturna migliorata,バイザーを暗視装置調にする,야시경 효과 향상,Verbeterde nachtzicht modus,Forbedret nattsynsmodus,Ulepszony tryb widzenia w ciemności,Modo de visão noturna avançada,,Vedere infraroșie avansată,Улучшенный режим ночного видения,Побољшана ноћна визија мод,Geliştirilmiş gece görüş modu -ENV shows stealth monsters,GLPREFMNU_ENVSTEALTH,,,,Vylepšené noční vidění ukazuje skryté příšery,ENV viser stealth-monstre,Nachtsichtmodus zeigt Stealth-Monster,,ENV montras kaŝiĝitajn monstrojn,ENV muestra enemigos sigilosos,,PPN näyttää näkymättömät hirviöt,VNA affiche monstres invisibles,ENV felfedi a lopakodó szörnyeket,La VNM mostra i mostri stealth ,暗視バイザーが透明を見破る,스텔스 적 개체를 감지하는 ENV,ENV toont stealth monsters,ENV viser stealth monstre,Ulepszony noktowizor pokazuje ukrywających się przeciwników,Visão noturna mostra monstros invisíveis,,PNV afișează monștri ascunși,ПНВ показывает скрытых монстров,ПНВ показује скривена чудовишта,ENV gizli canavarları gösteriyor -Adjust sprite clipping,GLPREFMNU_SPRCLIP,,,,Vyladění clippingu spritů,Juster sprite clipping,Sprite Clipping,,Agordi trairadon de spritoj,Ajustar recortado de sprites,,Spritejen asettelu,Adjusted le clipping des sprites,Sprite átlógás igazítása,Aggiusta il clipping degli sprite,スプライトのずらしを調整する,스프라이트 클리핑 조정,Sprite clipping,Juster sprite klipping,Ustaw wcięcie sprite'ów,Ajustar clipping de sprite,,Ajustare poziții sprite-uri,Режим обрезки спрайтов,Подеси спрајт клипинг,Sprite kırpmayı ayarlama -Smooth sprite edges,GLPREFMNU_SPRBLEND,,,,Vyhladit okraje spritů,Udglatte sprite-kanter,Glätte Spritekanten,,Glatigi randojn de spritoj,Suavizar bordes de sprites,,Pehmeät spritejen reunat,Adoucir bords des sprites,Sprite szélek simítása,Smussa gli angoli degli sprite,スプライトの角を丸める,부드러운 스프라이트 모서리,Gladde sprite randen,Glatte sprite kanter,Gładkie krawędzie sprite'ów,Suavizar bordas de sprites,,Netezire margini sprite-uri,Размытие краёв спрайтов,Углачати ивице спрајта,Düzgün sprite kenarları -Fuzz Style,GLPREFMNU_FUZZSTYLE,,,,Styl šumu,Fuzz-stil,Fuzz Stil,,Stilo de Lenugo,Estilo de difuminación,,Sumennustyyli,Style de bruit blanc,Homályosítás stílusa,Stile fuzz,ファズスタイル,퍼즈 스타일,Fuzz stijl,Fuzz-stil,Styl Szumu,Estilo de difusão,,Stil sclipire,Тип шума,Фаз стајл,Fuzz Tarzı -Sprite billboard,GLPREFMNU_SPRBILLBOARD,,,,Orientace spritů,,Spriteausrichtung,,Liniigi Spritojn,Alineado de sprites,,Spritetaulu,Etalage des sprites,Sprite alapú reklámtábla,,スプライト ビルボード,스프라이트 샘플링,Sprite billboard,,Wyrównanie Sprite'ów,Alinhamento de sprite,,Rotire sprite-uri,Привязка по осям спрайтов,Спрајт билборд,Sprite reklam panosu -Sprites face camera,GLPREFMNU_SPRBILLFACECAMERA,,,,Sprity čelí kameře,Sprites vender mod kameraet,Sprites zur Kamera ausrichten,,Spritoj alfronti kameraon,Los sprites miran a la cámara,,Spritet suuntaavat kameraan,Sprites font face à la caméra,Sprite alapú kamera,Gli sprite sono rivolti alla telecamera.,スプライトのフェイスカメラ,카메라를 향한 스프라이트,Sprites gezicht camera,Sprites vender mot kameraet,Sprite'y skierowane w kamerę,Sprites de frente pra câmera,,Sprite-urile privesc înspre cameră,Спрайты направлены к камере,Спрајт камера фаце,Sprite'lar kamerayla yüzleşir -Particle style,GLPREFMNU_PARTICLESTYLE,,,,Styl částic,Partikelstil,Partikelstil,,Partikla stilo,Estilo de partículas,,Hiukkastyyli,Style de particules,Részecske stílusa,Stile particelle,パーティクル スタイル,입자 스타일,Deeltjes stijl,Partikkel-stil,Styl Cząsteczek,Tipo de partícula,,Stil particule,Тип частиц,Честице стајл,Parçacık stili -Rendering quality,GLPREFMNU_RENDERQUALITY,,,,Kvalita vykreslování,Renderingskvalitet,Renderqualität,,Kvalito de bildigado,Calidad de Renderizado,,Hahmonnuslaatu,Qualité du rendu,Renderelés minősége,Qualità resa grafica,レンダリング品質,렌더링 품질,Het teruggeven van kwaliteit,Renderingskvalitet,Jakość Renderowania,Qualidade de renderização,,Calitate video,Качество отрисовки,Квалитет рендовања,Render kalitesi -Stereo 3D VR,GLPREFMNU_VRMODE,,,,,,,,Duvida 3D VR,Modo Stereo 3D VR,,,3D VR Stéréo,,,ステレオ3DのVR,VR 입체 스테레오 사용,,,,3D Estéreo (VR),,Mod VR,Стерео 3D VR-режим,Стереотоно 3D VR,Stereo 3D VR -Enable Quad Stereo,GLPREFMNU_VRQUADSTEREO,,,,Povolit Quad Stereo,Aktiver Quad Stereo,Quad Stereo aktivieren,,Ŝalti Kvaroblo-Stereon,Activar Quad Stereo,,Ota käyttöön Quad Stereo,Activer Quad Stereo,Quad Sztereó bekapcsolása,Abilita il Quad Stereo,クァッドステレオを有効,쿼드 스테레오 사용,Quad Stereo inschakelen,Aktiver Quad Stereo,Włącz Poczwórne Stereo,Habilitar Quad Stereo,Permitir Quad Stereo,Activare Quad Stereo,Четырёхкратный стереорежим,Омогући четвороструки стерео,Dörtlü Stereoyu Etkinleştir -Banded SW Lightmode,GLPREFMNU_SWLMBANDED,,,,Režim pruhovaného SW osvětlení,Båndede SW-lystilstand,Gebänderter SW-Lichtmodus,,Reĝimo de Bendiga Lumo de Programbildigo,Modo de luz por bandas de SW,,Kaistoitettu ohjelmistoväritila,Lumière bandées en Software,,Lightmode software bandata,バンデドSWライトモード,단결된 SW 라이트 모드,SW-lichtmodus met banden,Båndet SW-lysmodus,Naznaczony Tryb Oświetlenia Oprogramowania,Modo de luz por bandas em software,,Mod limitat de iluminare Software,Программный режим освещения полосами,Повезани SW режим осветљења,Bantlı SW Işık Modu -Distance Between Your Eyes,GLPREFMNU_VRIPD,,,,Vzdálenost mezi očima,Afstand mellem øjnene,Abstand zwischen den Augen,,Distanco Inter Viaj Okuloj,Distancia entre tus ojos,,Silmiesi etäisyys toisistaan,Distance entre vos yeux,Szemek közötti távolság,Distranza tra i tuoi occhi,自分の目との距離,시야 간의 거리,Afstand tussen uw ogen,Avstand mellom øynene dine,Odległość Pomiędzy Twoimi Oczami,Distância entre os olhos,,Distanța dintre ochi,Расстояние между глазами,Даљина између твојих очију,Gözleriniz Arasındaki Mesafe -Distance From Your Screen,GLPREFMNU_VRSCREENDIST,,,,Vzdálenost od obrazovky,Afstand fra din skærm,Abstand vom Bildschirm,,Distanco De Via Ekrano,Distancia desde tu pantalla,,Etäisyys ruudullesi,Distance entre vous et l'écran,Képernyőtől mért távolság,Distanza dal tuo schermo,画面からの距離,화면과의 거리,Afstand van uw scherm,Avstand fra skjermen,Odległość Od Twojego Ekranu4,Distância a partir da tela,,Distanța față de ecranul tău,Расстояние от экрана,Даљина од окрена,Ekranınızdan Uzaklık -Smart,OPTVAL_SMART,,,,Chytré,,,,Inteligenta,Inteligente,,Älykäs,Intelligent,Okos,Intelligente,スマート,자동 조정,Slim,,Mądry,Inteligente,,Inteligent,Умный,Паметно,Akıllı -Smarter,OPTVAL_SMARTER,,,,Chytřejší,Smartere,,,Pli inteligenta,Más inteligente,,Älykkäämpi,+ Intelligent,Okosabb,Ancora più intelligente,よりスマート,고급 자동 조정,Slimmer,Smartere,Mądrzejszy,Mais inteligente,,Mai inteligent,Умнее,Паметније,Daha Akıllı -Infrared only,OPTVAL_INFRAREDONLY,,,,Pouze infračervené,Kun infrarødt,Nur Infrarot,,Nur transruĝa,Solo infrarrojo,,Vain infrapuna,Vis. Noct. Seulement,Csak az infravörösnél,Solo infrarossi,赤外線のみ,야시경만,Alleen infrarood,Kun infrarød,Tylko Podczerwień,Somente infravermelho,,Doar în infraroșu,Только инфракрасный,Само инфрацрвена,Sadece kızılötesi -Infrared and torch,OPTVAL_INFRAREDANDTORCH,,,,Infračervené a pochodeň,Infrarød og lommelygte,Infrarot und Fackel,,Transruĝa kaj torĉo,Infrarrojo y antorcha,,Vain infrapuna ja soihtu,Iis Noct. & Torche,Infravörös és fáklya,Infrarossi e torcia,赤外線と松明,야시경과 횃불만,Infrarood en fakkels,Infrarød og lommelykt,Tylko Podczerwień i Pochodnie,Infravermelho e tocha,,Infraroșu si torță,Инфракрасный и факел,Инфрацрвена/бакља,Kızılötesi ve fener -Any fixed colormap,OPTVAL_ANYFIXEDCOLORMAP,,,Any fixed colourmap,Jakákoli fixní mapa barev,Alle lyseffekter,Alle Lichteffekte,,Iu ajn fiksita kolormapo,Cualquier mapa de color fijo,,Mikä tahansa kiinteä värikartta,N'importe quelle colormap,Bármely fixált colormap,Ogni colormap fissata,任意の固定カラーマップ,고정된 컬러맵만,Elke vaste colormap,Alle faste fargekart,Którekolwiek naprawione mapy kolorów,Qualquer colormap fixo,,Orice colormap,Любая заданная цветовая карта,Било која поправљена табела боја,Herhangi bir sabit renk haritası +",Rensa nodcache,Düğüm önbelleğini temizle +Allow skipping of intermission scrollers,MISCMNU_INTERSCROLL,,,,Povolit přeskakování skrolujících obrázků,Tillad at springe over pausescrollere,Erlaube Überspringen von Intermission-Scrollern,,Permesi preterpason de intermitaj rulumoj,Permitir omisión de intermedios,,Salli vierivien väliruutujen ohittaminen,Sauter compteurs d'intermission,Pályaközi szünetek átugorhatóak,Consenti di saltare gli scorrimenti delle intermissioni,クリア結果集計のスキップを許可,인터미션 스크롤러 생략 허용,Overslaan van intermissiescrollers toestaan,Tillat å hoppe over pauserullere,Pozwól na pominięcie wstawek,Pular telas de intervalo entre fases,Saltar ecrãs de intervalo entre níveis,Permite saltul peste inserările de text,Разрешение пропуска текстовых вставок,Дозволи прескакање прелаза са текстовима,Tillåt att hoppa över rullgardiner för pauslägen.,Ara kaydırıcıların atlanmasına izin ver +Network Options,NETMNU_TITLE,,,,Nastavení sítě,Netværksindstillinger,Netzwerkeinstellungen,,Reta Agordoj,Opciones de Red,,Verkkoasetukset,Options Réseau,Hálózati Beállítások,Opzioni network,ネットワーク オプション,네트워크 설정,Netwerkopties,Nettverksalternativer,Opcje Sieci,Opções de Rede,,Setări de Rețea,Настройки сети,Мрежна подешавања,Nätverksalternativ,Ağ Seçenekleri +Local options,NETMNU_LOCALOPTIONS,,,,Lokální nastavení,Lokale indstillinger,Lokale Einstellungen,,Lokaj agordoj,Opciones locales,,Paikallisasetukset,Options Locales,Helyi beállítások,Opzioni locali,ローカル オプション,로컬 설정,Lokale opties,Lokale alternativer,Opcje Lokalne,Opções locais,,Setări Locale,Локальные настройки,Локална подешавања,Lokala alternativ,Yerel seçenekler +Movement prediction,NETMNU_MOVEPREDICTION,,,,Predikce pohybu,Forudsigelse af bevægelser,Bewegungsvorausberechnung,,Movprognozado,Predicción de Movimiento,,Liikkeen ennakoiminen,Prédiction de Mouvement,Mozgás előrejelzés,Predizione movimenti,移動予測,움직임 예측도,Voorspelling van bewegingen,Forutsigelse av bevegelse,Przewidywanie Ruchu,Previsão de movimento,,Anticipare mișcare,Предсказание движения,Предвиђање покрета,Förutsägelse av rörelser,Hareket tahmini +Predict line actions,NETMNU_LINESPECIALPREDICTION,,,,Predikce čárových akcí,Forudsige linjehandlinger,Berechne Linienaktionen voraus,,Prognozi linio-agojn,Predecir acciones de línea,,Ennakoi viivasuorat toiminnat,Prédiction des actions de ligne,Előrejelzés vonal művelet,Predizione azioni di linea,line actionsを予測する,라인 움직임 감지,Voorspel lijnacties,Forutsi linjehandlinger,Przewidź akcje linii,Prever ações de linha,,Anticipează acționarea liniilor,Предсказание действий на уровне,Предвиђање линијске радње,Förutsägelse av linjeåtgärder,Hat eylemlerini tahmin edin +Prediction Lerp Scale,NETMNU_PREDICTIONLERPSCALE,,,,Velikost interpolace predikce,Forudsigelse Lerp-skala,Vorberechnungs Lerp-Skalierung,,Skalo de Linia Lnterpolado,Escala de interp. lineal de predicción,,Lineaarisen interpolaatioennakoinnin skaalaus,Prédiction d'échelle LERP,Előrejelzés LERP Arány,Scala Lerp predizione,リープスケール予測,러프 예측 강도,Voorspelling Lerp Scale,Prediksjon Lerp-skala,Przewidywanie Skali Lerp,Escala de previsão de LERP,,Anticipare scară lerp,Предсказание увеличения доп. задержки,Предвиђање лерп скале,Förutsägelse Lerp Scale,Tahmin Lerp Ölçeği +Lerp Threshold,NETMNU_LERPTHRESHOLD,,,,Práh interpolace,Lerp-tærskel,Lerp-Schwellwert,,Limito de Linia Interpolado,Umbral de interp. lineal,,Interpolaatiokynnys,Limite LERP,LERP küszöbérték,Soglia Lerp,リープしきい値,러프 계산,Lerp Threshold,Lerp-terskel,Próg Lerp,Limite de LERP,,Prag Lerp,Порог доп. задержки,Лерп праг,Lerp Tröskelvärde,Lerp Eşiği +Host options,NETMNU_HOSTOPTIONS,,,,Nastavení hostitele,Værtsindstillinger,Gastoptionen,,Agordoj de Gastiganto,Opciones de Host,,Isäntäasetukset,Options Hôte,Host beállítások,Opzioni ospitante,ホスト オプション,호스트 설정,Verhuurders opties,Vertsalternativer,Opcje hosta,Opções de host,,Setări gazdă,Настройки сервера,Подешавања домаћина,Alternativ för värdar,Ev sahibi seçenekleri +Extra Tics,NETMNU_EXTRATICS,,,,Extra tiky,Ekstra tics,,,Ekstraj Tikoj,Tics Extra,,Lisäticit,Tics supplémentaires,Extra Tic-ek,Tics extra,予備秒数,추가 틱,,Ekstra tics,Dodatkowe tiki,Tics extras,,Ticăituri suplimentare,Дополнительные секунды,Додатни тикови,Extra tics,Ekstra Tikler +Latency balancing,NETMNU_TICBALANCE,,,,Vyrovnání latence,Balancering af latenstid,Latenzbalance,,Respondotempo-balancado,Balanceo de latencia,,Viiveen tasapainoitus,Equilibrage de latence,Válaszidő balanszolás,Bilanciamento latenza,レイテンシーバランス,지연 시간 조정,Latency balans,Balansering av ventetid,Balans czasu oczekiwania,Equilíbrio de latência,,Întârzierea echilibrării,Балансировка задержки,Балансирање кашњења,Balansering av latenstid,Gecikme dengeleme +Original,OPTVAL_ORIGINAL,,,,Původní,,,,Originala,,,Alkuperäinen,,Eredeti,Originale,オリジナル,원형,Origineel,,Oryginalny,,,,Изначальный,Оригинално,Ursprunglig,Orijinal +Optimized,OPTVAL_OPTIMIZED,,,,Optimalizovaný,Optimeret,Optimiert,,Optimumigita,Optimizado,,Optimoitu,Optimisé,Optimalizált,Ottimizzato,最適化,최적화 형,Geoptimaliseerd,Optimalisert,Zoptymalizowany,Otimizado,,Optimizat,Оптимизированный,Оптимизовано,Optimerad,Optimize Edilmiş +Classic (Faster),OPTVAL_CLASSIC,,,,Klasický (rychlejší),Classic (hurtigere),Klassisch (schneller),,Klasika (Pli rapide),Clásico (Más rápido),,Perinteinen (nopeampi),Classique (+ Rapide),Klasszikus (gyorsabb),Classico (più veloce),旧式(速度重視),구형 (빠르게),Klassiek (sneller),Klassisk (raskere),Klasyczny (szybszy),Clássico (Mais rápido),,Clasic (Mai rapid),Классический (быстрее),Класични (бржи),Classic (snabbare),Klasik (Daha Hızlı) +Precise,OPTVAL_PRECISE,,,,Přesný,Præcist,Genau,,Preciza,Preciso,,Tarkka,Précis,Pontos,Preciso,精密,정확하게,Nauwkeurig,Presis,Dokładny,Preciso,,Precis,Точный,Прецизно,Exakt,Kesin +Capped,OPTVAL_CAPPED,,,,Uzavřený,Begrænset,Limitiert,,Limitigita,Limitado,,Rajoitettu,Limité,Lekorlátozva,Limitato,上限,색상에 맞게,Afgeschermd,Begrenset,Ograniczony,Limitado,,Limitat,Ограниченный,Ограничено,Begränsad,Sınırlı +Particles,OPTVAL_PARTICLES,,,,Částice,Partikler,Partikel,,Partikloj,Partículas,,Hiukkasina,Particules,Részecskék,Particelle,パーティクル,입자만,Deeltjes,Partikler,Cząstki,Partículas,,Particule,Частицы,Честице,Partiklar,Parçacıklar +Sprites,OPTVAL_SPRITES,,,,Sprity,,,,Mov-rastrumoj,,,Spriteinä,,Sprite-ok,Sprite,スプライト,스프라이트만,,,Sprite'y,,,Sprite-uri,Спрайты,Спрајтови,,Sprite'lar +Sprites & Particles,OPTVAL_SPRITESPARTICLES,,,,Sprity a částice,Sprites og partikler,Sprites und Partikel,,Mov-rastrumoj kaj partikloj,Sprites y partículas,,Spriteinä ja hiukkasina,Sprites & Particules,Sprite-ok és részecskék,Sprite e particelle,スプライト & パーティクル,스프라이트+입자,Sprites & Deeltjes,Sprites og partikler,Sprite'y i cząstki,Sprites & Partículas,Sprites e Partículas,Sprite-uri & Particule,Спрайты и частицы,Спрајтови и честице,Sprites och partiklar,Sprite'lar ve Parçacıklar +Melt,OPTVAL_MELT,,,,Rozpuštění,Smelt,Verlauf,,Fandi,Derretir,,Sulaminen,Fondu,Olvadás,Scioglimento,メルト,녹는 효과,Smelten,Smelte,Stopienie,Derreter,,Topire,Таяние,Топљење,Smält,Eriyik +Burn,OPTVAL_BURN,,,,Oheň,Brænde,Einbrennen,,Bruli,Quemar,,Palaminen,Brûlure,Égés,Bruciamento,バーン,타는 효과,Verbranden,Brenne,Wypalenie,Queimar,,Ardere,Жжение,Спаљивање,Bränn,Yanmak +Crossfade,OPTVAL_CROSSFADE,,,,Prolínačka,Crossfade,Überblenden,,Transvelki,Entrelazar,,Ristihäivytys,Fondu en croix,Átvezetés,Dissolvenza a croce,クロスフェード,화면 교차,Crossfade,Overblending,Przenikanie,Dissolver,,Ofilire,Увядание,Вењење,Crossfade,Crossfade +Smooth,OPTVAL_SMOOTH_1,"This setting is duplicated in order to allow for different grammatical gender endings in the Russian language (and any other language that depends on a grammatical gender system). In English, due to the lack of a grammatical gender system, both option values are the same.",,,Vyhlazený,Glat,Glatt,,Glata,Fluido,,Pehmeä,Lisse,Simítás,Liscio,スムーズ,부드럽게,Glad,Glatt,Gładki,Suavizado,,Fin,Плавная,Глатко,Smidig,Pürüzsüz +Smooth,OPTVAL_SMOOTH_2,,,,Vyhlazené,Glat,Glatt,,Glata,Fluido,,Pehmeä,Lisse,Simítás,Liscio,スムーズ,부드럽게,Glad,Glatt,Gładka,Suavizado,,Fin,Плавные,Глатко,Smidig,Pürüzsüz +Translucent,OPTVAL_TRANSLUCENT,,,,Průhledný,Gennemskinnelig,Transparent,,Diafana,Translúcido,,Läpikuultava,Transparent,Áttetsző,Traslucido,半透明,투명하게,Doorschijnend,Gjennomskinnelig,Przeświecający,Translúcido,,Transparent,Полупрозрачный,Прозрачно,Genomskinlig,Yarı Saydam +Fuzz,OPTVAL_FUZZ,,,,Šum,,Fuzz,,Lanugo,Borroso,,Sumeus,Bruit Blanc,Homályosítás,Annebbiato,ファズ,퍼즈 효과,Fuzz,,Szum,Difuso,,Sclipitor,Шумовой,Фаз,Fuzz,Fuzz +Shadow,OPTVAL_SHADOW,,,,Stín,Skygge,Schatten,,Ombro,Sombra,,Varjo,Ombre,Árnyék,Ombra,シャドウ,그림자 효과,Schaduw,Skygge,Cień,Sombra,,Umbră,Теневой,Сенка,Skugga,Gölge +Items,OPTVAL_ITEMS,,,,Předměty,Varer,Gegenstände,,Objektoj,Objetos,,Esineet,Objets,Tárgyak,Oggetti,アイテム,아이템들,Artikelen,Gjenstander,Przedmioty,Itens,,Obiecte,Предметы,Предмет,Artiklar,Eşyalar +Weapons,OPTVAL_WEAPONS,,,,Zbraně,Våben,Waffen,,Armiloj,Armas,,Aseet,Armes,Fegyverek,Armi,武器,무기들,Wapens,Våpen,Bronie,Armas,,Arme,Оружие,Оружја,Vapen,Silahlar +Both,OPTVAL_BOTH,,,,Obojí,Begge,Beide,,Ambaŭ,Ambos,,Molemmat,Les Deux,Mindkettő,Entrambi,両方,둘 다,Beide,Begge,Oba,Ambos,,Ambele,Оба,Оба,Båda,Her ikisi de +ZDoom,OPTVAL_ZDOOM,,,,,,,,,,,,,,,,Z둠,,,,,,,,,, +Strife,OPTVAL_STRIFE,,,,,,,,,,,,,,,,스트라이프,,,,,,,,,, +Player,OPTVAL_PLAYER,,,,Hráč,Spiller,Spieler,,Ludanto,Jugador,,Pelaaja,Joueur,Játékos,Giocatore,プレイヤー,플레이어,Speler,Spiller,Gracz,Jogador,,Jucător,Игрок,Играч,Spelare,Oyuncu +Map,OPTVAL_MAP,,,,Level,Kort,Level,,Mapo,Mapa,,Kartta,Niveau,Pálya,Mappa,マップ,맵,Kaart,Kart,Mapa,Mapa,,Hartă,Карта,Мапа,Karta,Harita +Scale to 640x400,OPTVAL_SCALETO640X400,,,,Zvětšit na 640x400,Skaleres til 640x400,Skaliere auf 640x400,,Skali al 640x400,Escalar a 640x400,,Skaalaa resoluutioon 640x400,Echelle 640x400,640x480-hoz arányít,Scala a 640x400,640x400スケール,640x400까지 확대,Schaal tot 640x400,Skala til 640x400,Skaluj do 640x400,Escalar para 640x400,,Dimensionare la 640x480,Масштабировать до 640x400,Скалирај на 640x400,Skala till 640x400,640x400'e ölçeklendirin +Pixel double,OPTVAL_PIXELDOUBLE,,,,Zdvojení pixelů,Pixel dobbelt,Pixelverdopplung,,Bilderon duobligi,Pixel doble,,Kuvapistekaksinkertaistus,,Pixel duplázás,Pixel doppi,ピクセル2倍,2배 픽셀,Pixel dubbel,Dobbel piksel,Dwukrotnie więcej pikseli,Pixel duplo,,Dublare pixeli,Двойные пиксели,Дупли пиксел,Pixel dubbelt så mycket,Piksel çift +Pixel quadruple,OPTVAL_PIXELQUADRUPLE,,,,Zčtyřnásobení pixelů,Pixel firedobbelt,Pixelvervierfachung,,Bilderon kvarobligi,Pixel cuádruple,,Kuvapistenelinkertaistus,,Pixel négyszerezés,Pixel quadrupli,ピクセル4倍,4배 픽셀,Pixel viervoudig,Piksel firedoblet,Czterokrotnie więcej pikseli,Pixel quádruplo,,Împătrire pixeli,Учетверённые пиксели,Четвороструки пиксел,Pixel fyrdubbel,Piksel dörtlü +Current weapon,OPTVAL_CURRENTWEAPON,,,,Současná zbraň,Nuværende våben,Aktuelle Waffe,,Nuntempa armilo,Arma actual,,Nykyinen ase,Arme actuelle,Jelenlegi fegyver,Arma corrente,使用中の武器,현 무기,Huidig wapen,Nåværende våpen,Aktualna broń,Arma atual,,Arma curentă,текущего оружия,Тренутно оружје,Aktuellt vapen,Mevcut silah +Available weapons,OPTVAL_AVAILABLEWEAPONS,,,,Dostupně zbraně,Tilgængelige våben,Verfügbare Waffen,,Haveblaj armiloj,Armas disponibles,,Käytettävissä olevat aseet,Armes Disponibles,Elérhető fegyverek,Armi disponibili,所持してる武器,사용 가능한 무기들,Beschikbare wapens,Tilgjengelige våpen,Dostępne bronie,Armas disponíveis,,Arme disponibile,доступного оружия,Доступно оружје,Tillgängliga vapen,Mevcut silahlar +All weapons,OPTVAL_ALLWEAPONS,,,,Všechny zbraně,Alle våben,Alle Waffen,,Ĉiuj armiloj,Todas las armas,,Kaikki aseet,Toutes les armes,Minden fegyver,Tutte le armi,全ての武器,모든 무기들,Alle wapens,Alle våpen,Wszystkie bronie,Todas as armas,,Toate armele,всех видов оружия,Сва оружја,Alla vapen,Tüm silahlar +"Level, milliseconds",OPTVAL_LEVELMILLISECONDS,,,,"Level, milisekundy","Level, millisekunder","Level, Millisekunden",,"Nivelo, milisekundoj","Nivel, milisegundos",,"Taso, millisekunnit","Niveau, milisecondes","Pálya, milliszekundum","Livello, millisecondi","現場, ミリ秒","레벨, 밀리초당","Niveau, milliseconden","Nivå, millisekunder","Poziom, milisekundy","Fase, milisegundos","Nível, milisegundos","Nivel, milisecunde","Уровень, миллисекунды","Ниво, милисекунде","Nivå, millisekunder","Seviye, milisaniye" +"Level, seconds",OPTVAL_LEVELSECONDS,,,,"Level, vteřiny","Level, sekunder","Level, Sekunden",,"Nivelo, sekundoj","Nivel, segundos",,"Taso, sekunnit","Niveau, secondes","Pálya, másodpercek","Livello, secondi","現場, 秒","레벨, 초당","Niveau, seconden","Nivå, sekunder","Poziom, sekundy","Fase, segundos","Nível, segundos","Nivel, secunde","Уровень, секунды","Ниво, секунде","Nivå, sekunder","Seviye, saniye" +Level,OPTVAL_LEVEL,,,,,,,,Nivelo,Nivel,,Taso,Niveau,Pálya,Livello,現場,레벨,Niveau,Nivå,Poziom,Fase,Nível,Nivel,Уровень,Ниво,Nivå,Seviye +"Hub, seconds",OPTVAL_HUBSECONDS,,,,"Hub, vteřiny","Hub, sekunder","Hub, Sekunden",,"Rekontejo, sekundoj","Hub, segundos",,"Tasokokoelma, sekunnit","Hub, secondes","Csomópont, másodpercek","Hub, secondi","区間, 秒","허브, 초당","Naaf, seconden","Hub, sekunder","Hub, sekundy","Hub, segundos",,"Hub, secunde",Хаб (секунды),"Хуб, секунде","Hub, sekunder","Hub, saniye" +Hub,OPTVAL_HUB,,,,,,,,Rekontejo,,,Tasokokoelma,,Csomópont,,区間,허브,Naaf,,,,,,Хаб,Хуб,Nav, +"Total, seconds",OPTVAL_TOTALSECONDS,,,,"Celkový, vteřiny","I alt, sekunder","Gesamt, Sekunden",,"Tuto, sekundoj","Total, segundos",,"Yhteensä, sekunnit","Total, secondes","Teljes, másodpercek","Totale, secondi","合計, 秒","누적 경과, 초당","Totaal, seconden","Totalt, sekunder","Razem, sekundy","Total, segundos",,"Total, secunde",Общее (секунды),"Тотал, секунде","Totalt, sekunder","Toplam, saniye" +Total,OPTVAL_TOTAL,,,,Celkový,I alt,Gesamt,,Tuto,,,Yhteensä,,Teljes,Totale,合計,누적 경과,Totaal,Totalt,Razem,,,,Общее,Тотал,Totalt,Toplam +"System, seconds",OPTVAL_SYSTEMSECONDS,,,,"Systémový, vteřiny","System, sekunder","System, Sekunden",,"Sistemo, sekundoj","Sistema, segundos",,"Järjestelmä, sekunnit","Système, secondes","Rendszer, másodpercek","Sistema, secondi","PC時刻, 秒","시스템, 초당","Systeem, seconden","System, sekunder","System, sekundy","Sistema, segundos",,"Sistem, secunde",Система (секунды),"Систем, секунде","System, sekunder","Sistem, saniye" +System,OPTVAL_SYSTEM,,,,Systémový,,,,Sistemo,Sistema,,Järjestelmä,Système,Rendszer,Sistema,PC時刻,시스템,Systeem,,,Sistema,,Sistem,Система,Систем,,Sistem +Netgames only,OPTVAL_NETGAMESONLY,,,,Pouze v síťové hře,Kun netspil,Nur Netzwerkspiele,,Retludoj sole,Solo para juegos en red,,Vain verkkopelit,Parties en Ligne seulement,Csak Netgames,Solo giochi net,オンラインのみ,멀티플레이에만,Alleen Netspellen,Kun nettspill,Tylko gry sieciowe,Jogos em rede apenas,,Doar în rețea,Только сетевые игры,Мрежне игре само,Endast nätspel,Sadece net oyunlar +Image and Text,OPTVAL_AMMOIMAGETEXT,,,,Obrázek a text,Billede og tekst,Bild und Text,,Bildo kaj Teksto,Imagen y texto,,Kuva ja teksti,Image et Texte,Kép és szöveg,Immagini e testo,画像と字,이미지와 텍스트,Beeld en tekst,Bilde og tekst,Obraz i Tekst,Imagem e texto,,Imagine și Text,Изображение и текст,Слика и текст,Bild och text,Resim ve Metin +Text and Image,OPTVAL_AMMOTEXTIMAGE,,,,Text a obrázek,Tekst og billede,Text und Bild,,Teksto kaj Bildo,Texto e imagen,,Teksti ja kuva,Texte et Image,Szöveg és kép,Testo e immagini,字と画像,텍스트와 이미지,Tekst en beeld,Tekst og bilde,Tekst i Obraz,Texto e imagem,,Text și Imagine,Текст и изобр.,Текст и слика,Text och bild,Metin ve Görüntü +Scripts Only,OPTVAL_SCRIPTSONLY,,,,Pouze skripty,Kun scripts,Nur Skripte,,Skriptoj Sole,Solo scripts,,Vain komentosarjat,Scripts seulement,Csak szkript,Solo script,スクリプトのみ,스크립트에만,Alleen scripts,Bare skript,Tylko skrypty,Scripts apenas,,Numai scripturi,Только скрипты,Само скрипте,Endast skript,Sadece Senaryolar +All,OPTVAL_ALL,,,,Všechny,Alle,Alle,,Ĉiuj,Todos,,Kaikki,Tout,Mind,Tutti,全て,모두 작동,Alle,Alle,Wszystko,Todos,,Tot,Все,Све,Alla,Tümü +Only last one,OPTVAL_ONLYLASTONE,,,,Pouze poslední,Kun den sidste,Nur das letzte,,Nur fina unu,Solo el último,,Vain viimeinen,Dernier seulement,Csak a legutolsó,Solo l'ultimo,最後のみ,오직 마지막 것만,Alleen de laatste,Bare den siste,Tylko ostatni,Somente o último,Apenas o último,Doar ultimul,Только последнее,Само последњи,Endast den sista,Sadece sonuncusu +Traditional Doom,OPTVAL_TRADITIONALDOOM,,,,Tradiční Doom,Traditionel Doom,Doom traditionell,,Tradicia Doom,Doom tradicional,,Perinteinen Doom,Doom Traditionnel,Tradícionális Doom,DOOM tradizionale,正式DOOM,전형적인 둠 스타일,Traditioneel Doom,Tradisjonell undergang,Tradycyjny Doom,Doom Tradicional,,Tradițional Doom,Цвета из Doom,Традиционални Doom,Traditionell Doom,Geleneksel Doom +Traditional Strife,OPTVAL_TRADITIONALSTRIFE,,,,Tradiční Strife,Traditionel Strife,Strife traditionell,,Tradicia Strife,Strife tradicional,,Perinteinen Strife,Strife Traditionnel,Tradícionális Strife,Strife tradizionale,正式Strife,전형적인 스트라이프 스타일,Traditionele Strife,Tradisjonell strid,Tradycyjny Strife,Strife Tradicional,,Tradițional Strife,Цвета из Strife,Традиционални Strife,Traditionell Strife,Geleneksel Strife +Traditional Raven,OPTVAL_TRADITIONALRAVEN,,,,Tradiční Raven,Traditionel Raven,Raven traditionell,,Tradicia Raven,Raven tradicional,,Perinteinen Raven,Raven Traditionnel,Tradícionális Raven,Raven tradizionale,正式Raven,전형적인 레이븐 스타일,Traditionele Raven,Tradisjonell ravn,Tradycyjny Raven,Raven Tradicional,,Tradițional Raven,Цвета из Raven,Традиционални Raven,Traditionell Raven,Geleneksel Raven +Only when found,OPTVAL_ONLYWHENFOUND,,,,Pouze po nalezení,Kun når de findes,Nur wenn gefunden,,Nur kiam trovita,Una vez encontrados,,"Vain, kun löydetty",Seulement découverts,Csak ha megleled,Solo quando trovato,発見時のみ,획득했을 때만,Alleen wanneer gevonden,Bare når funnet,Tylko gdy znaleziono,Somente quando encontrado,Apenas quando encontrado,Doar la descoperire,После обнаружения,Само кад је пронађен,Endast när den hittas,Sadece bulunduğunda +On for overlay only,OPTVAL_ONFOROVERLAYONLY,,,,Pouze v překryvném režimu,Kun til overlay,Nur auf Overlay,,Ŝaltita nur por surmeto,Solo para superpuesto,,Päällä vain karttaprojisoinnin kanssa,On pour Surimpression,Csak az overlayen,Solo attivo per la sovrapposizione,オーバーレイ専用,오버레이에만 작동,Alleen op voor overlay alleen voor overlay,På kun for overlegg,Włączony tylko dla nakładek,Ativado somente para sobreposição,Apenas ativado para sobreposição,Doar pentru modul transparent,Только наложенная,Укључен само за навлаку,Endast på för överlagring,Yalnızca kaplama için etkin +Overlay+Normal,OPTVAL_OVERLAYNORMAL,,,,Překryv + normální,Overlay+Normal,Overlay+Normal,,Surmeto+Normala,Superpuesto+Normal,,Projisointi+tavallinen,Surimpression+Normal,Overlay+Normál,Sovrapposizione+Normale,オーバーレイ+通常,오버레이+기본,Overlay+Normaal,,Nakładka+Normalnie,Sobreposição+Normal,,Transparent + Normal,Наложенная + обычная,Навлака + нормално,Överlagring+Normal,Yer Kaplama+Normal +Overlay Only,OPTVAL_OVERLAYONLY,,,,Pouze překryv,Kun overlay,Nur Overlay,,Nur Surmeto,Solo superpuesto,,Vain projisointi,Surimpression seulement,Csak Overlay-nél,Solo Sovrapposizione,オーバーレイのみ,오버레이만,Alleen Overlay,Kun overlegg,Tylko Nakładka,Sobreposição apenas,,Doar modul transparent,Только прозрачный,Навлак само,Endast överlagring,Yalnızca Kaplama +Not for hubs,OPTVAL_NOTFORHUBS,,,,Ne pro huby,Ikke for knudepunkter,Nicht für Hubs,,Ne por naboj,No para hubs,,Ei tasokokoelmille,Pas pour les hubs,Csomópontokhoz nem,Non per gli hub,区間では出さない,허브는 제외,Niet voor hubs,Ikke for nav,Nie dla hubów,Exceto hubs,,Nu pentru hub-uri,Кроме групп,Није за хубове,Inte för nav,Hub'lar için değil +Front,OPTVAL_FRONT,,,,Zepředu,Forside,Frontalansicht,,Fronto,Frontal,,Etu,Devant,Előnézet,Fronte,画像,정면,Voorkant,Forside,Przód,Frente,,Înainte,Перед,Испред,Framsida,Ön +Animated,OPTVAL_ANIMATED,,,,Animované,Animeret,Animiert,,Animita,Animado,,Animoitu,Animés,Animált,Animato,動作,움직임,Geanimeerd,Animert,Animowany,Animado,,Animat,Анимированные,Анимирано,Animerad,Animasyonlu +Rotated,OPTVAL_ROTATED,,,,Otáčivé,Drejet,Rotiert,,Turnita,Rotado,,Kääntyvä,Tournés,Elforgatott,Ruotato,回転,회전함,Geroteerd,Rotert,Obrócony,Rotacionado,Rodado,Rotit,Повёрнутые,Ротирано,Roterad,Döndürülmüş +Map defined colors only,OPTVAL_MAPDEFINEDCOLORSONLY,,,Map defined colours only,Pouze barvy definované mapou,Kun kortdefinerede farver,Nur Leveldefinierte Farben,,Nur mapaj difinitaj koloroj,Colores definidos por el usuario,,Vain kartan määrittämät värit,Couleurs définies carte seul.,Csak map orientált színek,Solo i colori definiti dalla mappa,指定した色のみ,자체 미니맵 색상 사용,Alleen gedefinieerde kleuren op de kaart,Kun kartdefinerte farger,Tylko kolory zdefiniowane przez mapę,Cores definidas por mapa apenas,,Doar culori specifice hărții,Только определённые картой цвета,Само дефинисане мапом боје,Endast kartdefinierade färger,Yalnızca harita tanımlı renkler +All except doors,OPTVAL_NODOORS,,,,Všechny krom dveří,Alle undtagen døre,Alle außer Türen,,Ĉiom krom pordoj,Todo excepto puertas,,Kaikki paitsi ovet,Tout sauf portes,"Minden, kivétel az ajtók",Tutti eccetto le porte,ドア以外全て,문을 제외한 모두,Allemaal behalve deuren,Alle unntatt dører,Wszystko oprócz drzwi,Tudo exceto portas,,Cu excepția ușilor,Кроме дверей,Све осим врата,Alla utom dörrar,Kapılar hariç hepsi +Double,OPTVAL_DOUBLE,,,,Dvojitý,Dobbelt,Doppel,,Duobligi,Doble,,Kaksinkertainen,,Dupla,Doppio,ダブル,2배,Dubbele,Dobbel,Podwójny,Dobro,,Dublu,Двойной,Дупло,Dubbel,Çift +Triple,OPTVAL_TRIPLE,,,,Trojitý,Tredobbelt,Dreifach,,Triobligi,,,Kolminkertainen,,Tripla,Triplo,トリプル,3배,Drievoudig,Trippel,Potrójny,Triplo,,Triplu,Тройной,Тродупло,Tredubbel,Üçlü +Quadruple,OPTVAL_QUADRUPLE,,,,Čtveritý,Firedobbelt,Vierfach,,Kvarobligi,Cuádruple,,Nelinkertainen,,Négyszeres,Quadruplo,クァッド,4배,Viervoudig,Firedoblet,Poczwórny,Quádruplo,,Cvadruplu,Четырёхкратный ,Четвороструко,Fyrdubbel,Dörtlü +Item Pickup,OPTVAL_ITEMPICKUP,,,,Sebrání předmětu,Afhentning af varer,Gegenstand genommen,,Objektoprenado,Recogida de objetos,,Esineen poiminta,Objets Ramassés,Tárgy felvétele,Raccolta oggetto,アイテム取得,아이템 획득시,Puntafhaling,Varehenting,Podniesienie Przedmiotu,Coleta de Item,Aquisição de Itens,Obiect Ridicat,Подбор предметов,Подигнут предмет,Hämtning av föremål,Bir eşyayı almak +Obituaries,OPTVAL_OBITUARIES,,,,Oznámení o smrti,Dødsannoncer,Todesanzeige,,Nekrologoj,Obituarios,,Kuolinviestit,Avis de décès,Halálok,Necrologio,死亡時,사망 메시지,Doodsbrieven,Dødsannonser,Nekrologi,Obituários,,Necrologuri,Некрологи,Читуље,Dödsannonser,Ölüm İlanları +Critical Messages,OPTVAL_CRITICALMESSAGES,,,,Kritická oznámení,Kritiske meddelelser,Kritische Meldungen,,Gravaj Mesaĝoj,Mensajes críticos,,Tärkeät viestit,Messages Critiques,Fontos üzenetek,Messaggi critici,重要メッセージ,중요한 메시지,Kritische berichten,Kritiske meldinger,Wiadomości krytyczne,Mensagens Críticas,,Mesaje Critice,Важные сообщения,Критичне поруке,Kritiska meddelanden,Kritik Mesajlar +Never friends,OPTVAL_NEVERFRIENDS,,,,Nikdy spojence,Aldrig venner,Keine Freunde,,Neniam amikoj,Nunca amigos,,Ei koskaan ystäviä,Jamais les Amis,Barátokat sose,Mai amici,フレンド以外,아군 무시,Nooit vrienden,Aldri venner,Żadnych przyjaciół,Nunca amigos,,Nu aliați,Не по союзникам,Никад за пријатеље,Aldrig vänner,Asla arkadaş değil +Only monsters,OPTVAL_ONLYMONSTERS,,,,Pouze příšery,Kun monstre,Nur Monster,,Nur monstroj,Solo monstruos,,Vain hirviöt,Monstres Seulement,Csak szörnyeket,Solo i mostri,モンスターのみ,적에게만,Alleen monsters,Bare monstre,Tylko potwory,Somente monstros,Monstros apenas,Doar monștri,Для монстров,Само чудовишста,Endast monster,Sadece canavarlar +Hexen,OPTVAL_HEXEN,,,,,,,,,,,,Hexen,,,,헥센,,,,,,,,,, +Old,OPTVAL_OLD,,,,Starý,Gamle,Alt,,Maljuna,Viejo,,Vanha,Ancien,Régi,Vecchio,旧式,구형,Oud,Gamle,Stare,Antigo,,Vechi,Старый,Стар,Gamla,Eski +Doom,OPTVAL_DOOM,,,,,,,,,,,,,,,,둠,,,,,,,,,, +Doom (strict),OPTVAL_DOOMSTRICT,,,,Doom (striktní),Doom (streng),Doom (strikt),,Doom (severa),Doom (estricto),,Doom (tiukka),,Doom (szigorú),Doom (rigoroso),Doom(厳密),둠 (엄격하게),Doom (streng),Doom (streng),Doom (ścisły),Doom (estritamente),Doom (estrito),,Doom (строгий),Doom (строг),Doom (strikt),Doom (katı) +Boom,OPTVAL_BOOM,,,,,,,,,,,,,,,,붐,,,,,,,,,, +Boom (strict),OPTVAL_BOOMSTRICT,,,,Boom (striktní),Boom (streng),Boom (strikt),,Boom (severa),Boom (estricto),,Boom (tiukka),,Boom (szigorú),Boom (rigoroso),Boom(厳密),붐 (엄격하게),Boom (streng),Boom (streng),Boom (ścisły),Boom (estritamente),Boom (estrito),,Boom (строгий),Boom (строг),Boom (strikt),Boom (katı) +MBF,OPTVAL_MBF,,,,,,,,,,,,,,,,마린의 절친한 친구,,,,,,,,,, +MBF (strict),OPTVAL_MBFSTRICT,,,,MBF (striktní),MBF (streng),MBF (strikt),,MBF (severa),MBF (estricto),,MBF (tiukka),,MBF (szigorú),MBF (rigoroso),MBF(厳密),마린의 절친한 친구 (엄격하게),MBF (streng),MBF (streng),MBF (ścisły),MBF (estritamente),MBF (estrito),,MBF (строгий),MBF (строг),MBF (strikt),MBF (katı) +ZDoom 2.0.63,OPTVAL_ZDOOM2063,,,,,,,,,,,,,,,,Z둠 2.0.63,,,,,,,,,, +All unacknowledged,OPTVAL_ALLUNACKNOWLEDGED,,,,Všechny nepotrvzené,Alle ubekræftede,Alle unbestätigten,,Ĉiuj neagnoskitaj,Todos no reconocidos,,Kaikki kuittaamattomat,Tout non-acknowledged,Minden visszaigazolatlan,Tutti non riconosciuti,未確認全て,모두 미확인함,Allemaal onbekend,Alle ubekreftet,Wszystkie niepotwierdzone,Todos não-reconhecidos,,Toate necunoscute,Всё неопознанное,Све неусвојено,Alla obeaktade,Tüm onaylanmamış +Errors,OPTVAL_ERRORS,,,,Chyby,Fejl,Fehler,,Eraroj,Errores,,Virheet,Erreurs,Hibák,Errori,エラー,에러,Fouten,Feil,Błędy,Erros,,Erori,Ошибки,Грешка,Fel,Hatalar +Warnings,OPTVAL_WARNINGS,,,,Varování,Advarsler,Warnungen,,Avertoj,Advertencias,,Varoitukset,Avertissements,Figyelmeztetések,Avvisi,警告,경고,Waarschuwingen,Advarsler,Ostrzeżenia,Avisos,,Atenționări,Предупреждения,Упозорење,Varningar,Uyarılar +Notifications,OPTVAL_NOTIFICATIONS,,,,Oznámení,Meddelelser,Benachrichtigungen,,Sciigoj,Notificaciones,,Ilmoitukset,,Üzenetek,Notifiche,通知,알림,Kennisgevingen,Varsler,Powiadomienia,Notificações,,Notificări,Уведомления,Обавештење,Meddelanden,Bildirimler +Everything,OPTVAL_EVERYTHING,,,,Všechno,Alt,Alles,,Ĉio,Todo,,Kaikki,Tout,Minden,Tutti,全て,전체,Alles,Alt,Wszystko,Tudo,,Tot,Всё,Све,Allt,Her şey +Hardware accelerated,OPTVAL_HWPOLY,,,,Hardwarová akcelerace,Hardware accelereret,Hardwarebeschleunigt,,Aparatara Plirapidigo,Acelerado por Hardware,,Laitteistokiihdytetty,Accéléré par Hardware,Hardveres gyorsítás,Accelerazione Hardware,ハードウェア アクセラレート,오픈지엘 가속,Hardware versneld,Maskinvareakselerert,Napędzane sprzętowo,Acelerado por hardware,,Accelerat Hardware,Аппаратный,Харвер убрзан,Hårdvara påskyndad,Hızlandırılmış donanım +Doom Software Renderer,OPTVAL_SWDOOM,,,,Doom softwarový renderer,,,,Program-bildigilo de Doom,Renderizado por Software de Doom,,Doomin ohjelmistohahmonnin,Rendu Software Doom,Doom szoftveres renderer,Rendering DOOM software,Doom ソフトウェアレンダー,둠 소프트웨어 렌더러,,,Renderer Oprogramowania Dooma,Renderizador Software do Doom,,Software,Doom-программный,Doom софтверски рендерер,Doom Mjukvarurenderare,Doom Yazılım Oluşturucu +True Color SW Renderer,OPTVAL_SWDOOMTC,,,,True color softwarový renderer,,,,Program-bildigilo kun Plenkoloro,Renderizado SW Color Verdadero,Renderizado SW True Color,True Color -ohjelmistohahmonnin,Rendu Software Couleurs Réeles,,Rendering software a pieni colori,トゥルーカラー SWレンダー,트루 컬러 소프트웨어 렌더러,,,Renderer True Color,Renderizador Software True Color,,Software Color Complet,Полноцветный програмный,SW рендерер праве боје,True Color Mjukvarurenderare,Gerçek Renk SW Oluşturucu +High-Performance,OPTVAL_DEDICATED,,,,Vysoký výkon,Højtydende,Volle Leistung,,Alta Rendimento,Alto rendimiento,,Korkea suorituskyky,Hautes Performances,Nagy teljesítmény,Prestazioni massime,ハイパフォーマンス,고 성능,Hoogwaardige prestaties,Høy ytelse,Wysoka Wydajność,Alta-Performance,,De înaltă performanță,Высокая производительность,Високо-перформанси,Högpresterande,Yüksek Performans +Power-Saving,OPTVAL_INTEGRATED,,,,Nízká spotřeba,Strømbesparende,energiesparend,,Energikonservo,Ahorro de energía,,Virransäästö,Economie d'Energie,Energia takarékos,Risparmio energetico,パワーセービング,저전력,Energiebesparing,Strømsparende,Oszczędzanie Energii,Economia de Energia,,Economie de energie,Энергосбережение,Енергетско-штедљиви,Energibesparande,Güç Tasarrufu +Vanilla,OPTVAL_VANILLA,,,,Původní,,,,Originala,,,Alkuperäinen,,Hagyományos,,バニラ,바닐라,,,Czysty,,,Original,Изначальный,Ванила,,Vanilya +ZDoom (Forced),OPTVAL_VTFZDOOM,,,,ZDoom (vynucený),ZDoom (tvunget),ZDoom (erzwungen),,ZDoom (Devigita),ZDoom (forzado),,ZDoom (pakotettu),ZDoom (Forcé),ZDoom (erőltetett),ZDoom (forzato),ZDoom(強制),ZDoom (강제 설정),ZDoom (Gedwongen),ZDoom (Tvunget),ZDoom (Wymuszony),ZDoom (Forçar),,ZDoom (Forțat),ZDoom (принудительно),ZDoom (присиљен),ZDoom (tvingad),ZDoom (Zorla) +Vanilla (Forced),OPTVAL_VTFVANILLA,,,,Původní (vynucený),Vanilla (tvungen),Vanilla (erzwungen),,Originala (Devigita),Vanilla (Forzado),,Perus (pakotettu),Vanilla (Forcé),Hagyományos (erőltettt),Vanilla (forzato),バニラ(強制),바닐라 (강제 설정),Vanilla (Gedwongen),Vanilla (Tvunget),Czysty (Wymuszony),Vanilla (Forçar),DOS Original (Forçar),Original (Forțat),Изначальный (принудительно),Ванила (присиљен),Vanilla (tvingad),Vanilya (Zorlanmış) +Auto (ZDoom Preferred),OPTVAL_VTAZDOOM,,,,Auto (preferován ZDoom),Auto (ZDoom foretrukket),Auto (ZDoom bevorzugt),,Aŭtomata (ZDoom Preferita),Auto (ZDoom preferido),,Automaattinen (ZDoomia suosiva),Auto (ZDoom Préféré),Automata (ZDoom preferált),Automatico (ZDoom preferito),自動(ZDoom優先),자동 (ZDoom 기본 설정),Auto (bij voorkeur ZDoom),Auto (ZDoom foretrukket),Automatyczny (Preferowany ZDoom),Automático (De preferência ZDoom),,Auto (ZDoom preferat),Автоматически (предпочитать ZDoom),Аутоматски (ZDoom преферијални),Auto (ZDoom föredraget),Otomatik (ZDoom Tercih Edilir) +Auto (Vanilla Preferred),OPTVAL_VTAVANILLA,,,,Auto (preferován původní),Auto (Vanilla foretrukket),Auto (Vanilla bevorzugt),,Aŭtomata (Originala Preferita),Auto (Vanilla preferido),,Automaattinen (alkuperäistä suosiva),Auto (Vanilla Préféré),Automata (Hagyományos preferált),Automatico (Vanilla preferito),自動(バニラ優先),자동 (바닐라 기본 설정),Auto (bij voorkeur Vanilla),Auto (Vanilla foretrukket),Automatyczny (Preferowany czysty),Automático (De preferência Vanilla),Automático (De preferência DOS Original),Auto (Original preferat),Автоматически (предпочитать изначальный),Аутоматски (ванила преферијални),Auto (Vanilla föredraget),Otomatik (Vanilya Tercihli) +Small,OPTVAL_SMALL,,,,Malé,Lille,Klein,,Malgranda,Pequeño,,Pieni,Petit,Kicsi,Piccolo,小,작게,Klein,Liten,Mały,Pequeno,,Mic,Мелкий,Мало,Liten,Küçük +Large,OPTVAL_LARGE,,,,Velké,Stor,Groß,,Granda,Grande,,Suuri,Grand,Nagy,Grande,大,크게,Groot,Stor,Duży,Grande,,Mare,Крупный,Велико,Stor,Büyük +Console,OPTVAL_CONSOLE,,,,Konzole,Konsol,Konsole,,Konzolo,Consola,,Konsoli,,Konzol,,コンソール,콘솔,,Konsoll,Konsola,,Consola,Consolă,Консольный,Конзола,Konsol,Konsol +\caBrick,C_BRICK,,,,\caCihlová,\caMursten,\caZiegelrot,,\caBrikkolora,\caLadrillo,,\catiili,\cabrique,\catéglavörös,\camattone,\ca丹,\ca주홍색,\casteenrood,\caMurstein,\cacegła,\catijolo,,\caCărămiziu,\caКирпичный,\caБоја цигле,\caTegelsten,\caTuğla +\cbTan,C_TAN,,,,\cbSvětle hnědá,,\cbHellbraun,,\cbTankolora,\cbBeis,\cbTostado,\cbkeltaruskea,\cbbeige,\cbbézs,\cbabbronzatura,\cb香,\cb상아색,\cblichtbruin,\cbBrun,\cbjasnobrązowy,\cbbege,,\caBronz,\cbБежевый,\cbБеж,, +\ccGray,C_GRAY,,,\ccgrey,\ccŠedá,\ccGrå,\ccGrau,,\ccGriza,\ccGris,,\ccharmaa,\ccgris,\ccszürke,\ccgrigio,\cc灰,\cc회색,\ccgrijs,\ccGrå,\ccszary,\cccinza,,\ccGri,\ccСерый,\ccСива,\ccGrå,\ccGri +\cdGreen,C_GREEN,,,,\cdZelená,\cdGrøn,\cdGrün,,\cdVerda,\cdVerde,,\cdvihreä,\cdvert,\cdzöld,\cdverde,\cd緑,\cd녹색,\cdgroen,\cdGrønn,\cdzielony,\cdverde,,\cdVerde,\cdЗелёный,\cdЗелена,\cdGrön,\cdYeşil +\ceBrown,C_BROWN,,,,\ceHnědá,\ceBrun,\ceBraun,,\ceBruna,\ceMarrón,\ceCafé,\ceruskea,\cebrun,\cebarna,\cemarrone,\ce茶,\ce갈색,\cebruin,\ceBrun,\cebrązowy,\cemarrom,,\ceMaro,\ceКоричневый,\ceСмеђа,\ceBrun,\ceKahverengi +\cfGold,C_GOLD,,,,\cfZlatá,\cfGuld,,,\cfOrkolora,\cfDorado,,\cfkulta,\cfor,\cfarany,\cforo,\cf金,\cf금색,\cfgoud,\cfGull,\cfzłoty,\cfdourado,,\cfAuriu,\cfЗолотой,\cfЗлатна,\cfGuld,\cfAltın +\cgRed,C_RED,,,,\cgČervená,\cgRød,\cGrot,,\cfRuĝa,\cgRojo,,\cgpunainen,\cgrouge,\cgvörös,\cgrosso,\cg赤,\cg적색,\cgrood,\cgRød,\cgczerwony,\cgvermelho,,\gRoșu,\cgКрасный,\cgЦрвена,\cgRöd,\cgKırmızı +\chBlue,C_BLUE,,,,\chModrá,\chBlå,\chBlau,,\chBlua,\chAzul,,\chsininen,\chbleu,\chkék,\chblu,\ch青,\ch청색,\chblauw,\chBlå,\chniebieski,\chazul,,\chAlbastru,\chСиний,\chПлава,\chBlå,\chMavi +\ciOrange,C_ORANGE,,,,\ciOranžová,,,,\ciOranĝkolora,\ciNaranja,,\cioranssi,\ciorange,\cinarancs,\ciarancione,\ci橙,\ci주황색,\cioranje,\ciOransje,\cipomarańczowy,\cilaranja,,\ciPortocaliu,\ciОранжевый,\ciНаранџаста,,\ciTuruncu +\cjWhite,C_WHITE,,,,\cjBílá,\cjHvid,\cjWeiß,,\cjBlanka,\cjBlanco,,\cjvalkoinen,\cjblanc,\cjfehér,\cjbianco,\cj白,\cj흰색,\cjwit,\cjHvit,\cjbiały,\cjbranco,,\cjAlb,\cjБелый,\cjБела,\cjVit,\cjBeyaz +\ckYellow,C_YELLOW,,,,\ckŽlutá,\ckGul,\ckGelb,,\ckFlava,\ckAmarillo,,\ckkeltainen,\ckjaune,\cksárga,\ckgiallo,\ck黄,\ck노란색,\ckgeel,\ckGul,\ckżółty,\ckamarelo,,\ckGalben,\ckЖёлтый,\ckЖута,\ckGul,\ckSarı +\clDefault,C_DEFAULT,,,,\clVýchozí,\clStandard,\clStandard,,\clDefaŭlta,\clPor defecto,,\cloletus,\cldéfaut,\clalap,\cldefault,\cl初期,\cl기본 색,\clstandaard,\clStandard,\cldomyślny,\clpadrão,,\clImplicită,\clПо умолчанию,\clУобичајена,\clStandard,\clVarsayılan +\cmBlack,C_BLACK,,,,\cmČerná,\cmSort,\cmSchwarz,,\cmNigra,\cmNegro,,\cmmusta,\cmnoir,\cmfekete,\cmnero,\cm黒,\cm검은색,\cmzwart,\cmSvart,\cmczarny,\cmpreto,,\cmNegru,\cmЧёрный,\cmЦрна,\cmSvart,\cmSiyah +\cnLight blue,C_LIGHTBLUE,,,,\cnSvětle modrá,\cnLyseblå,\cnHellblau,,\cnHelblua,\cnAzul claro,,\cnvaaleansininen,\cnbleu clair,\cnvilágoskék,\cnblu chiaro,\cn空,\cn하늘색,\cnlicht blauw,\cnLyseblå,\cnjasnoniebieski,\cnazul claro,,\cnAlbastru deschis,\cnГолубой,\cnСветло плава,\cnLjusblått,\cnAçık mavi +\coCream,C_CREAM,,,,\coKrémová,\coCreme,\coCremefarben,,\coKremkolora,\coCrema,,\cokerma,\cocrème,\cokrémszínű,\cocrema,\co肉,\co살구색,\cocrème,\coKremfarget,\cokremowy,\cocreme,,\coCrem,\coКремовый,\coКрем,\coGrädde,\coKrem +\cpOlive,C_OLIVE,,,,\cpOlivová,\cpOliven,\cpOliv,,\cpOlivkolora,\cpOliva,,\cpoliivi,\cpolive,\cpolíva,\cpoliva,\cp泥,\cp녹갈색,\cpolijf,\cpOliven,\cpoliwkowy,\cpoliva,,\cpMăsliniu,\cpОливковый,\cpМаслинаста,\cpOliv,\cpZeytin +\cqDark green,C_DARKGREEN,,,,\cqTmavě zelená,\cqMørkegrøn,\cqDunkelgrün,,\cqMalhelverda,\cqVerde oscuro,,\cqtummanvihreä,\cqvert sombre,\cqsötétzöld,\cqverde scuro,\cq深,\cq암녹색,\cqdonkergroen,\cqMørkegrøn,\cqciemnozielony,\cqverde escuro,,\cqVerde închis,\cqТёмно-зелёный,\cqТамно зелена,\cqMörkgrön,\cqKoyu yeşil +\crDark red,C_DARKRED,,,,\crTmavě červená,\crMørkerød,\crDunkelrot,,\crMalhelruĝa,\crRojo oscuro,,\crtummanpunainen,\crrouge sombre,\crsötétvörös,\crrosso scuro,\cr朱,\cr암적색,\crdonkerrood,\crMørkerød,\crciemnoczerwony,\crvermelho escuro,,\crRoșu închis,\crТёмно-красный,\crБордо,\crMörkröd,\crKoyu kırmızı +\csDark brown,C_DARKBROWN,,,,\csTmavě hnědá,\csMørkebrun,\csDunkelbraun,,\csMalhelbruna,\csMarrón oscuro,\csCafé oscuro,\cstummanruskea,\csbrun sombre,\cssötétbarna,\csmarrone scuro,\cs焦,\cs암갈색,\csdonkerbruin,\csMørkebrun,\csciemnobrązowy,\csmarrom escuro,,\csMaro închis,\csТёмно-коричневый,\csБраон,\csMörkbrun,\csKoyu kahverengi +\ctPurple,C_PURPLE,,,,\ctFialová,\ctLilla,\ctLila,,\ctPurpura,\ctMorado,,\ctpurppura,\ctviolet,\ctlila,\ctviola,\ct紫,\ct보라색,\ctpaars,\ctLilla,\ctfioletowy,\ctroxo,,\ctMov,\ctФиолетовый,\ctЉубичаста,\ctLila,\ctMor +\cuDark gray,C_DARKGRAY,,,\cudark grey,\cuTmavě šedá,\cuMørkegrå,\cuDunkelgrau,,\cuMalhelgriza,\cuGris oscuro,,\cutummanharmaa,\cugris sombre,\cusötétszürke,\cugrigio scuro,\cu鉛,\cu치색,\cudonkergrijs,\cuMørkegrå,\cuciemnoszary,\cucinza escuro,,\cuGri închis,\cuТёмно-серый,\cuТамно сива,\cuMörkgrå,\cuKoyu gri +\cvCyan,C_CYAN,,,,\cvAzurová,,\cvTürkis,,\cvCejana,\cvCián,,\cvsinivihreä,\cvcyan,\cvcián,\cvciano,\cv天,\cv청록색,\cvcyan,,\cvbłękitny,\cvciano,,\cvTurcoaz,\cvСине-зелёный,\cvЦијан,, +\cwIce,C_ICE,,,,\cwLed,\cwIs,\cwEis,,\cwGlacikolora,\cwHielo,,\cwjää,\cwglace,\cwjég,\cwghiaccio,\cw氷,\cw구색,\cwice,\cwIs,\cwlód,\cwgelo,,\cwGheață,\cwЛедяной,\cwЛед,\cwIs,\cwBuz +\cxFire,C_FIRE,,,,\cxOheň,\cxIld,\cxFeuer,,\cxFajrkolora,\cxFuego,,\cxtuli,\cxfeu,\cxtűz,\cxfuoco,\cx炎,\cx자황색,\cxvuur,\cxIld,\cxogień,\cxfogo,,\cxFoc,\cxОгненный,\cxВатрена,\cxEld,\cxYangın +\cySapphire,C_SAPPHIRE,,,,\cySafírová,\cySafir,\cySaphirblau,,\cySafirkolora,\cyZafiro,,\cysafiiri,\cysaphir,\cyzafír,\cyzaffiro,\cy藍,\cy벽청색,\cysaffier,\cySafir,\cyszafirowy,\cysafira,,\cySafir,\cyСапфировый,\cyТамно плава,\cySafir,\cySafir +\czTeal,C_TEAL,,,,\czModrozelená,\czKrikand,\czBlaugrün,,\czBluverda,\czTurquesa,,\cztummansinivihreä,\czturquoise,\cztürkiz,\czverde acqua,\cz碧,\cz암청록색,\czteal,\czBlågrønn,\czmorski,\czturquesa,,\czMare,\czМорской,\czТиркизна,,\czDeniz mavisi +Heretic,OPTSTR_HERETIC,,,,,,,,,,,,,,,,헤러틱 커서,,,,,,,,,, +Chex,OPTSTR_CHEX,,,,,,,,,,,,,,,,첵스 커서,,,,,,,,,, +No Sound,OPTSTR_NOSOUND,,,,Bez zvuku,Ingen lyd,Kein Sound,,Neniu Sono,Sin sonido,,Ei ääntä,Pas de son,Hang nélkül,Nessun suono,サウンドなし,음향 없음,Geen geluid,Ingen lyd,Brak dźwięku,Sem som,,Fără Sunet,Без звука,Без-звучни,Inget ljud,Ses Yok +No interpolation,OPTSTR_NOINTERPOLATION,,,,Bez interpolace,Ingen interpolation,Keine Interpolation,,Neniu interpolado,Sin interpolación,,Ei interpolaatiota,Pas d'interpolation,Nincs interoláció,No interpolazione,補間無し,보간 없음,Geen interpolatie,Ingen interpolasjon,Brak interpolacji,Sem interpolação,,Fără interpolare,Без сглаживания,Нема уметања,Ingen interpolering,Enterpolasyon yok +Spline,OPTSTR_SPLINE,,,,Křivka,,,,Splajno,,,Splini,,,,スプライン,스플라인,,,,,,,Сплайн,Сплајн,, +OpenAL,OPTSTR_OPENAL,,,,,,,,,,,,,,,,오픈에이엘,,,,,,,,,, +Hardware Renderer,DSPLYMNU_GLOPT,,,,Hardwarový renderer,,,,Aparatara Bildigilo,Renderizado por Hardware,,Laitteistohahmonnin,Moteur de Rendu Hardware,Hardver Render,Rendering Hardware,ハードウェア レンダラー,오픈지엘 렌더러,,,Renderer Sprzętowy,Renderizador Hardware,,Setări Mod OpenGL,Обработка с OpenGL,Хардвер рендерер,Hårdvaru-renderare,Donanım Oluşturucu +Software Renderer,DSPLYMNU_SWOPT,,,,Softwarový renderer,,,,Programa Bildigilo,Renderizado por Software,,Ohjelmistohahmonnin,Moteur de Rendu Software,Szoftver Render,Rendering Software,ソフトウェア レンダラー,소프트웨어 렌더러,,,Renderer Oprogramowania,Renderizador Software,,Setări Mod Software,Программная обработка,Софтвер рендерер,Mjukvarurenderare,Yazılım Oluşturucu +Hardware Rendering Options,GLMNU_TITLE,,,,Nastavení hardwarového rendereru,Indstillinger for hardware-rendering,Hardware-Renderer Optionen,,Agordoj de La Aparatara Bildigilo,Opciones de OpenGL,,Laitteistohahmonnusasetukset,Options OpenGL,Hardver Renderelő Beállítások,Opzioni OpenGL,ハードウェアレンダリング オプション,오픈지엘 설정,Hardware Rendering Opties,Alternativer for maskinvaregjengivelse,Opcje Renderowania Sprzętowego,Opções de Renderização por Hardware,,Setări Redare OpenGL,Настройки OpenGL,Опција хардвер рендера,Alternativ för maskinvarurendering,Donanım Oluşturma Seçenekleri +Dynamic Light Options,GLMNU_DYNLIGHT,,,,Nastavení dynamických světel,Indstillinger for dynamisk lys,Dynamisches-Licht-Optionen,,Agordoj de Dinamikaj Lumoj,Opciones de luz dinámica,,Dynaamisen valon asetukset,Options Lumières Dynamiques,Dinamikus Fény Beállítások,Opzioni Luci Dinamiche,ダイナミックライト オプション,광원 설정,Dynamische Licht Opties,Alternativer for dynamisk lys,Opcje Dynamicznego Oświetlenia,Opções de Luz Dinâmica,,Setări Lumini Dinamice,Динамическое освещение,Подешавања динамичког осветљења,Alternativ för dynamiskt ljus,Dinamik Işık Seçenekleri +Preferences,GLMNU_PREFS,,,,Možnosti,Præferencer,Einstellungen,,Preferoj,Preferencias,,Asetukset,Préférences,Preferenciák,Preferenze,環境設定,성능,Voorkeuren,Innstillinger,Preferencje,Preferências,,Preferințe,Настройки,Преференција,Inställningar,Tercihler +Trim sprite edges,GLTEXMNU_TRIMSPREDGE,,,,Oříznout okraje spritů,Trimme sprite-kanter,Leerraum in Sprites wegschneiden,,Ĉirkaŭtranĉi randojn de mov-rastrumoj,Recortar líneas de sprite,,Siisti spritejen reunat,Nettoyer le bord des sprites,Sprite szél igazítása,Taglia gli spigoli agli sprite,スプライトの角を取る,스프라이트 모서리 다듬기,,Trim sprite kanter,Przycinanie krawędzi sprite'ów,Cortar bordas de sprites,,Tundere margini sprite-uri,Обрезание краёв спрайтов,Подсећи ивице спрајтова,Trimma sprite-kanter,Sprite kenarlarını kırpma +Sort draw lists by texture,GLTEXMNU_SORTDRAWLIST,,,,Seřadit vykreslování podle textury,Sortere tegningslister efter tekstur,Renderlisten nach Textur sortieren,,Ordigi desegnado-listojn laŭ teksturo,Ordenar tablas por textura,,Lajittele piirtotaulut pintakuvioinneittain,Ordonner liste de rendu par texture,Textúra szerinti kirajzolási lista,Ordina la lista draw per texture,テクスチャーから描画リストを分類,텍스처별로 생성 목록 정렬,Tekeninglijsten sorteren op textuur,Sorter tegningslister etter tekstur,Sortowanie list renderowania wdług tekstur,Organizar listas de renderização por textura,,Sortează listele de texturi,Сортировать списки текстур,Сортирано цртај листе од текстуре,Sortera ritningslistor efter textur,Çizim listelerini dokuya göre sıralama +Dynamic Lights,GLLIGHTMNU_TITLE,,,,Dynamická světla,Dynamisk lys,Dynamische Lichter,,Dinamikaj Lumoj,Luces dinámicas,,Dynaamiset valot,Lumières Dynamiques,Dinamikus Fények,Luci Dinamiche,ダイナミックライト,다이나믹 라이트,Dynamische verlichting,Dynamiske lys,Dynamiczne Oświetlenie,Luzes Dinâmicas,,Lumini Dinamice,Динамическое освещение,Динамичко осветљење,Dynamiska lampor,Dinamik Işıklar +Dynamic Lights (Hardware),GLLIGHTMNU_LIGHTSENABLED,,,,Dynamická světla (hardware),Dynamisk lys (hardware),Dynamische Lichter (Hardware),,Dinamikaj Lumoj (Aparataro),Luces dinámicas (Hardware),,Dynaamiset valot (laitteistokiihdytys),Lumières Dynamiques (Hardware),Dinamikus Fények (hardveres),Luci Dinamiche (Hardware),ダイナミックライト(OpenGL),다이나믹 라이트(오픈지엘),Dynamische verlichting (hardware),Dynamiske lys (maskinvare),Dynamiczne Oświetlenie (Sprzętowe),Luzes Dinâmicas (Hardware),,Lumini Dinamice (OpenGL),Динамическое освещение (аппаратное),Динамичко осветљење (хардвер),Dynamiska lampor (maskinvara),Dinamik Işıklar (Donanım) +Enable light definitions,GLLIGHTMNU_LIGHTDEFS,,,,Povolit definice světel,Aktiver lysdefinitioner,Lichtdefinitionen an,,Ŝalti lumdifinojn,Activar definiciones de luz,,Ota käyttöön valomääritykset,Activer les définitions de lumière,Fény részletesség,Abilita le definizioni GLDEFS,ライト定義 許可,조명 선명도 사용,Lichtdefinities mogelijk maken,Aktiver lysdefinisjoner,Włącz definicje światła,Habilitar definições de luz,Permitir definições de luz,Activează definiții lumini,Включить определения света,Омогући светлосне дефиниције,Aktivera ljusdefinitioner,Işık tanımlarını etkinleştirin +Lights affect sprites,GLLIGHTMNU_LIGHTSPRITES,,,,Světla ovlivňují sprity,Lys påvirker sprites,Sprites werden beleuchtet,,Lumoj efikas mov-rastrumojn,Las luces afectan a los sprites,,Valot vaikuttavat spriteihin,Lumières affectent les sprites,A fény hatással van a sprite-okra,Le luci influiscono sugli sprite,ライトがスプライトに影響,조명에 영향받는 스프라이트,Lichten beïnvloeden sprites,Lys påvirker sprites,Światło ma wpływ na sprite'y,Luzes afetam sprites,,Luminile afectează sprite-urile,Освещать спрайты,Светло утиче на спрајтове,Ljus påverkar sprites,Işıklar sprite'ları etkiler +Lights affect particles,GLLIGHTMNU_LIGHTPARTICLES,,,,Světla ovlivňují částice,Lys påvirker partikler,Partikel werden beleuchtet,,Lumoj efikas partiklojn,Las luces afectan a las partículas,,Valot vaikuttavat hiukkasiin,Lumières affectent les particules,A fény hatással van a részecskékre,Le luci influiscono sulle particelle,ライトがパーティクルに影響,조명에 영향받는 입자들,Lichten beïnvloeden deeltjes,Lys påvirker partikler,Światło ma wpływ na cząsteczki,Luzes afetam partículas,,Luminile afectează particulele,Освещать частицы,Светло утиче на честице,Ljus påverkar partiklar,Işıklar parçacıkları etkiler +Light shadowmaps,GLLIGHTMNU_LIGHTSHADOWMAP,,,,Mapy stínů,Lys skyggemapper,Shadowmaps für Lichter,,Lum-ombro-mapoj,Mapeo de sombra de Luz,,Valojen varjokartat,Shadowmaps,,Ombre proiettate,ライトのシャドウマッピング,조명에 영향받는 섀도우맵,Lichte schaduwkaarten,Lys skyggekart,Oświetlenie map cieni,Shadowmaps,,Umbre lumini,Карты светотеней,Светло мапе сенки,Ljusskuggor,Işık gölge haritaları +Shadowmap quality,GLLIGHTMNU_LIGHTSHADOWMAPQUALITY,,,,Kvalita map stínů,Shadowmap-kvalitet,Shadowmap Qualität,,Kvalito de ombro-mapo,Calidad de Mapeo de Sombras,,Varjokarttojen laatu,Qualité Shadowmap,Shadowmap minőség,Qualità ombre proiettate,シャドウマップ 品質,섀도우맵 퀄리티,Schaduwkaart kwaliteit,Shadowmap-kvalitet,Jakość map cieni,Qualidade de shadowmap,,Calitate umbre,Качество карт светотеней,Мапа сенки квалитет,Skuggmappens kvalitet,Gölge haritası kalitesi +Shadowmap filter,GLLIGHTMNU_LIGHTSHADOWMAPFILTER,,,,Filtrování map stínů,Skyggemap-filter,Shadowmap Filter,,Filtro de ombro-mapo,Filtro de Mapeo de Sombras,,Varjokarttojen suodatus,Filtre de Shadowmaps,,Filtro ombre proiettate,シャドウマップ フィルター,섀도우맵 필터,Schaduwkaart filter,Shadowmap-filter,Filtr map cieni,Filtro de shadowmap,,Filtru umbre,Фильтр карт светотеней,Мапа сенки филтер,Filter för skuggmappor,Gölge haritası filtresi +Fog mode,GLPREFMNU_FOGMODE,,,,Režim mlhy,Tågetilstand,Nebelmodus,,Reĝimo de nebulo,Modo de niebla,,Sumutila,Mode du broullard,Köd mód,Modalità nebbia,フォグモード,안개 모드,Mistmodus,Tåke-modus,Tryb mgły,Modo de neblina,,Mod ceață,Режим тумана,Магла мод,Dimläget,Sis modu +Fog forces fullbright,GLPREFMNU_FOGFORCEFULLBRIGHT,,,,Mlha vynucuje plný jas,Tåge tvinger fullbright,Nebel erzwingt volle Helligkeit,,Nebulo devigas plenbrilon,Forzar brillo completo en niebla,,Sumu pakottaa täyskirkkauden,Brouillard force fullbright,Köd Fullbright-ot erőltet ki,La nebbia forza piena luce,濃霧は明るさ最大,안개를 최대한 강제로 밝힘,Mistkrachten volle lichtsterkte,Tåke styrker fullbright,Mgła wymusza pełną jasność,Neblina força brilho máximo,,Ceața forțează luminozitate maximă,Туман включает режим максимальной яркости,Магла присиљава пуну светлост,Dimma tvingar fram full ljusstyrka,Sis fullbright'ı zorlar +Weapon light strength,GLPREFMNU_WPNLIGHTSTR,,,,Intenzita světel zbraní,Våbenlysstyrke,Waffenlichtstärke,,Lumforteco de armilo,Intensidad de luz de las armas,,Aseiden valovoima,Intensité lumineuse des armes,Fegyver lövés fényerősség,Intensità luminosa dell'arma,武器ライトの強さ,무기 빛 강도,Sterkte van het wapenlicht,Våpen lysstyrke,Natężenie światła broni,Intensidade de luz da arma,,Intensitate lumină armă,Интенсивность вспышек оружия,Блага снага оружја,Vapenljusets styrka,Silah ışık gücü +Environment map on mirrors,GLPREFMNU_ENVIRONMENTMAPMIRROR,,,,Mapa prostředí na zrcadlech,Miljøkort på spejle,Lichteffekt auf Spiegeln,,Medimapo sur speguloj,Mapa de entorno en espejos,,Ympäristökartta peileissä,Mappage environment sur les miroirs,Környezeti mappolás a tükrökön,Ambiente mappa sui riflessi,マップオンミラーの画像表示,거울 주변의지도 활성,Milieukaart op spiegels,Omgivelseskart på speil,Mapa środowiska w lustrach,Mapa de ambiente em espelhos,,Reflecții pe oglinzi,Карта окружения на зеркалах,Околинска мапа на прозорима,Miljökarta på speglar,Aynalar üzerinde çevre haritası +Enhanced night vision mode,GLPREFMNU_ENV,,,,Vylepšený režim nočního vidění,Forbedret nattesynstilstand,Verbesserter Nachtsichtmodus,,Plibonigita reĝimo de noktvido,Modo de visión nocturna mejorado,,Paranneltu pimeänäkötila,Mode de vision nocture amélioré,Felerősített éjjellátó mód,Modalità visione notturna migliorata,バイザーを暗視装置調にする,야시경 효과 향상,Verbeterde nachtzicht modus,Forbedret nattsynsmodus,Ulepszony tryb widzenia w ciemności,Modo de visão noturna avançada,,Vedere infraroșie avansată,Улучшенный режим ночного видения,Побољшана ноћна визија мод,Förbättrat läge för mörkerseende,Geliştirilmiş gece görüş modu +ENV shows stealth monsters,GLPREFMNU_ENVSTEALTH,,,,Vylepšené noční vidění ukazuje skryté příšery,ENV viser stealth-monstre,Nachtsichtmodus zeigt Stealth-Monster,,ENV montras kaŝiĝitajn monstrojn,ENV muestra enemigos sigilosos,,PPN näyttää näkymättömät hirviöt,VNA affiche monstres invisibles,ENV felfedi a lopakodó szörnyeket,La VNM mostra i mostri stealth ,暗視バイザーが透明を見破る,스텔스 적 개체를 감지하는 ENV,ENV toont stealth monsters,ENV viser stealth monstre,Ulepszony noktowizor pokazuje ukrywających się przeciwników,Visão noturna mostra monstros invisíveis,,PNV afișează monștri ascunși,ПНВ показывает скрытых монстров,ПНВ показује скривена чудовишта,ENV visar smygande monster,ENV gizli canavarları gösteriyor +Adjust sprite clipping,GLPREFMNU_SPRCLIP,,,,Vyladění clippingu spritů,Juster sprite clipping,Sprite Clipping,,Agordi trairadon de mov-rastrumoj,Ajustar recortado de sprites,,Spritejen asettelu,Adjusted le clipping des sprites,Sprite átlógás igazítása,Aggiusta il clipping degli sprite,スプライトのずらしを調整する,스프라이트 클리핑 조정,Sprite clipping,Juster sprite klipping,Ustaw wcięcie sprite'ów,Ajustar clipping de sprite,,Ajustare poziții sprite-uri,Режим обрезки спрайтов,Подеси спрајт клипинг,Justera sprite clipping,Sprite kırpmayı ayarlama +Smooth sprite edges,GLPREFMNU_SPRBLEND,,,,Vyhladit okraje spritů,Udglatte sprite-kanter,Glätte Spritekanten,,Glatigi randojn de mov-rastrumoj,Suavizar bordes de sprites,,Pehmeät spritejen reunat,Adoucir bords des sprites,Sprite szélek simítása,Smussa gli angoli degli sprite,スプライトの角を丸める,부드러운 스프라이트 모서리,Gladde sprite randen,Glatte sprite kanter,Gładkie krawędzie sprite'ów,Suavizar bordas de sprites,,Netezire margini sprite-uri,Размытие краёв спрайтов,Углачати ивице спрајта,Slätar ut sprite-kanter,Düzgün sprite kenarları +Fuzz Style,GLPREFMNU_FUZZSTYLE,,,,Styl šumu,Fuzz-stil,Fuzz Stil,,Stilo de Lenugo,Estilo de difuminación,,Sumennustyyli,Style de bruit blanc,Homályosítás stílusa,Stile fuzz,ファズスタイル,퍼즈 스타일,Fuzz stijl,Fuzz-stil,Styl Szumu,Estilo de difusão,,Stil sclipire,Тип шума,Фаз стајл,Fuzz stil,Fuzz Tarzı +Sprite billboard,GLPREFMNU_SPRBILLBOARD,,,,Orientace spritů,,Spriteausrichtung,,Liniigi mov-rastrumojn,Alineado de sprites,,Spritetaulu,Etalage des sprites,Sprite alapú reklámtábla,,スプライト ビルボード,스프라이트 샘플링,,,Wyrównanie Sprite'ów,Alinhamento de sprite,,Rotire sprite-uri,Привязка по осям спрайтов,Спрајт билборд,,Sprite reklam panosu +Sprites face camera,GLPREFMNU_SPRBILLFACECAMERA,,,,Sprity čelí kameře,Sprites vender mod kameraet,Sprites zur Kamera ausrichten,,Mov-rastrumoj ĉiam rigardas vian kameraon,Los sprites miran a la cámara,,Spritet suuntaavat kameraan,Sprites font face à la caméra,Sprite alapú kamera,Gli sprite sono rivolti alla telecamera.,スプライトのフェイスカメラ,카메라를 향한 스프라이트,Sprites gezicht camera,Sprites vender mot kameraet,Sprite'y skierowane w kamerę,Sprites de frente pra câmera,,Sprite-urile privesc înspre cameră,Спрайты направлены к камере,Спрајт камера фаце,Sprites vänder sig mot kameran,Sprite'lar kamerayla yüzleşir +Particle style,GLPREFMNU_PARTICLESTYLE,,,,Styl částic,Partikelstil,Partikelstil,,Partikla stilo,Estilo de partículas,,Hiukkastyyli,Style de particules,Részecske stílusa,Stile particelle,パーティクル スタイル,입자 스타일,Deeltjes stijl,Partikkel-stil,Styl Cząsteczek,Tipo de partícula,,Stil particule,Тип частиц,Честице стајл,Partikelstil,Parçacık stili +Rendering quality,GLPREFMNU_RENDERQUALITY,,,,Kvalita vykreslování,Renderingskvalitet,Renderqualität,,Kvalito de bildigado,Calidad de Renderizado,,Hahmonnuslaatu,Qualité du rendu,Renderelés minősége,Qualità resa grafica,レンダリング品質,렌더링 품질,Het teruggeven van kwaliteit,Renderingskvalitet,Jakość Renderowania,Qualidade de renderização,,Calitate video,Качество обработки,Квалитет рендовања,Renderingskvalitet,Render kalitesi +Stereo 3D VR,GLPREFMNU_VRMODE,,,,,,,,Duvida 3D VR,Modo Stereo 3D VR,,,3D VR Stéréo,,,ステレオ3DのVR,VR 입체 스테레오 사용,,,,3D Estéreo (VR),,Mod VR,Стерео 3D VR-режим,Стереотоно 3D VR,, +Enable Quad Stereo,GLPREFMNU_VRQUADSTEREO,,,,Povolit Quad Stereo,Aktiver Quad Stereo,Quad Stereo aktivieren,,Ŝalti Kvaroblo-Stereon,Activar Quad Stereo,,Ota käyttöön Quad Stereo,Activer Quad Stereo,Quad Sztereó bekapcsolása,Abilita il Quad Stereo,クァッドステレオを有効,쿼드 스테레오 사용,Quad Stereo inschakelen,Aktiver Quad Stereo,Włącz Poczwórne Stereo,Habilitar Quad Stereo,Permitir Quad Stereo,Activare Quad Stereo,Четырёхкратный стереорежим,Омогући четвороструки стерео,Aktivera Quad Stereo,Dörtlü Stereoyu Etkinleştir +Banded SW Lightmode,GLPREFMNU_SWLMBANDED,,,,Režim pruhovaného SW osvětlení,Båndede SW-lystilstand,Gebänderter SW-Lichtmodus,,Reĝimo de Bendiga Lumo de Programbildigo,Modo de luz por bandas de SW,,Kaistoitettu ohjelmistoväritila,Lumière bandées en Software,,Lightmode software bandata,バンデドSWライトモード,단결된 SW 라이트 모드,SW-lichtmodus met banden,Båndet SW-lysmodus,Naznaczony Tryb Oświetlenia Oprogramowania,Modo de luz por bandas em software,,Mod limitat de iluminare Software,Программный режим освещения полосами,Повезани SW режим осветљења,SW Ljusläge i bandform,Bantlı SW Işık Modu +Distance Between Your Eyes,GLPREFMNU_VRIPD,,,,Vzdálenost mezi očima,Afstand mellem øjnene,Abstand zwischen den Augen,,Distanco Inter Viaj Okuloj,Distancia entre tus ojos,,Silmiesi etäisyys toisistaan,Distance entre vos yeux,Szemek közötti távolság,Distranza tra i tuoi occhi,自分の目との距離,시야 간의 거리,Afstand tussen uw ogen,Avstand mellom øynene dine,Odległość Pomiędzy Twoimi Oczami,Distância entre os olhos,,Distanța dintre ochi,Расстояние между глазами,Даљина између твојих очију,Avstånd mellan ögonen,Gözleriniz Arasındaki Mesafe +Distance From Your Screen,GLPREFMNU_VRSCREENDIST,,,,Vzdálenost od obrazovky,Afstand fra din skærm,Abstand vom Bildschirm,,Distanco De Via Ekrano,Distancia desde tu pantalla,,Etäisyys ruudullesi,Distance entre vous et l'écran,Képernyőtől mért távolság,Distanza dal tuo schermo,画面からの距離,화면과의 거리,Afstand van uw scherm,Avstand fra skjermen,Odległość Od Twojego Ekranu4,Distância a partir da tela,,Distanța față de ecranul tău,Расстояние от экрана,Даљина од окрена,Avstånd från skärmen,Ekranınızdan Uzaklık +Smart,OPTVAL_SMART,,,,Chytré,,,,Inteligenta,Inteligente,,Älykäs,Intelligent,Okos,Intelligente,スマート,자동 조정,Slim,,Mądry,Inteligente,,Inteligent,Умный,Паметно,,Akıllı +Smarter,OPTVAL_SMARTER,,,,Chytřejší,Smartere,,,Pli inteligenta,Más inteligente,,Älykkäämpi,+ Intelligent,Okosabb,Ancora più intelligente,よりスマート,고급 자동 조정,Slimmer,Smartere,Mądrzejszy,Mais inteligente,,Mai inteligent,Умнее,Паметније,Smartare,Daha Akıllı +Infrared only,OPTVAL_INFRAREDONLY,,,,Pouze infračervené,Kun infrarødt,Nur Infrarot,,Nur transruĝa,Solo infrarrojo,,Vain infrapuna,Vis. Noct. Seulement,Csak az infravörösnél,Solo infrarossi,赤外線のみ,야시경만,Alleen infrarood,Kun infrarød,Tylko Podczerwień,Somente infravermelho,,Doar în infraroșu,Только инфракрасный,Само инфрацрвена,Endast infrarött ljus,Sadece kızılötesi +Infrared and torch,OPTVAL_INFRAREDANDTORCH,,,,Infračervené a pochodeň,Infrarød og lommelygte,Infrarot und Fackel,,Transruĝa kaj torĉo,Infrarrojo y antorcha,,Vain infrapuna ja soihtu,Iis Noct. & Torche,Infravörös és fáklya,Infrarossi e torcia,赤外線と松明,야시경과 횃불만,Infrarood en fakkels,Infrarød og lommelykt,Tylko Podczerwień i Pochodnie,Infravermelho e tocha,,Infraroșu si torță,Инфракрасный и факел,Инфрацрвена/бакља,Infraröd och ficklampa,Kızılötesi ve fener +Any fixed colormap,OPTVAL_ANYFIXEDCOLORMAP,,,Any fixed colourmap,Jakákoli fixní mapa barev,Alle lyseffekter,Alle Lichteffekte,,Iu ajn fiksita kolormapo,Cualquier mapa de color fijo,,Mikä tahansa kiinteä värikartta,N'importe quelle colormap,Bármely fixált colormap,Ogni colormap fissata,任意の固定カラーマップ,고정된 컬러맵만,Elke vaste colormap,Alle faste fargekart,Którekolwiek naprawione mapy kolorów,Qualquer colormap fixo,,Orice colormap,Любая заданная цветовая карта,Било која поправљена табела боја,Alla fasta färgkartor,Herhangi bir sabit renk haritası Use as palette,OPTVAL_USEASPALETTE,,,,Použít jako paletu,Brug som palet,Benutze als Palette,,Uzi kiel paletro,Usar como paleta,,Käytä palettina,Utiliser comme pallette,Palettaként használat,Utilizza come palette,パレットとして使用,팔레트로 적용,Gebruik als palet,Bruk som palett,"Użyj jako palety -",Usar como paleta,Usar como palete,Utilizare drept paletă,Использовать как палитру,Користи као палету,Palet olarak kullanın -Blend,OPTVAL_BLEND,,,,Míchat,Blend,Überblenden,,Miksi,Mezclar,,Sekoitus,Mélanger,Kever,Miscela,混合,혼합,Mengen,Blanding,Połącz,Mesclar,Misturar,Amestec,Смешать,Бленд,Karışım -Bright,OPTVAL_BRIGHT,,,,Světlý,Lys,Hell,,Hela,Brillante,,Kirkas,Clair,Világos,Chiara,明るい,밝은,Helder,Lys,Jasne,Claro,,Luminos,Яркий,Свијетло,Parlak -Dark,OPTVAL_DARK,,,,Tmavý,Mørk,Dunkel,,Malhela,Oscuro,,Tumma,Sombre,Sötét,Scura,暗い,어두운,Donker,Mørk,Ciemne,Escuro,,Întunecat,Тёмный,Тамно,Karanlık -Doom Legacy,OPTVAL_LEGACY,,,,,,Doom Legacy,,,,,Doom Legacy,,Hagyományos Doom,,DOOM調,둠 레거시,,,,,,,,, -Software,OPTVAL_SOFTWARE,,,,,,,,Programa bildigilo,,,Ohjelmisto,,Szoftver,,ソフトウェア,소프트웨어,,,Oprogramowanie,,,,Программный,Софтвер,Yazılım -Optimal,OPTVAL_OPTIMAL,,,,Optimální,,,,Optima,Óptimo,,Optimaalinen,Optimiser,Optimális,Ottimale,最適,최적함,Optimaal,,Optymalne,Otimizado,,Optim,Оптимальный,Оптимал,Optimal -Y Axis,OPTVAL_YAXIS,,,,Po ose Y,Y-akse,Y-Achse,,Y-Akso,Eje Y,,Y-akseli,Axe Y,Y tengely,Asse Y,縦軸,Y 축,Y-as,Y-akse,Oś Y,Eixo Y,,Axa Y,По горизонтали,Y оса,Y Ekseni -X/Y Axis,OPTVAL_XYAXIS,,,,Po osách X/Y,X/Y-akse,X/Y-Achse,,X/Y-Akso,Ejes X/Y,,X- ja Y-akselit,Axes X/Y,X/Y tengely,Asse X/Y,縦/横軸,X/Y 축,X/Y As,X/Y-akse,Oś X/Y,Eixo X/Y,,Axa Y/Z,По обеим осям,X/Y оса,X/Y Ekseni -Square,OPTVAL_SQUARE,,,,Čtvercové,Firkantet,Quadratisch,,Kvadrata,Cuadrado,,Kulmikas,Carrées,Négyzet,Quadrato,平方,정사각형,Vierkant,Firkantet,Kwadrat,Quadrado,,Pătrat,Квадратные,Квадрат,Kare -Round,OPTVAL_ROUND,,,,Kulaté,Rund,Rund,,Ronda,Redondo,,Pyöreä,Rondes,Kör,Arrotondato,円形,원형,Rond,Rund,Okrągłe,Redondo,,Rotund,Круглые,Круг,Yuvarlak -Radial,OPTVAL_RADIAL,,,,Radiální,,,Ακτινικό,Radiusa,,,Säteittäinen,,Sugaras,Radiale,放射状,방사형,Radiaal,,Promieniowe,,,Radială,Радиальный,Радијално,Radyal -Pixel fuzz,OPTVAL_PIXELFUZZ,,,,Pixelový fuzz,,Pixel,Pixel θολούρα,Bildera lanugo,Difuminado pixelado,,Kuvapistesumennus,Bruit Pixélisé,Pixeles homály,Fuzz pixelato,ピクセル ファズ,픽셀 퍼즈,Pixel fuzz,,Szum pikseli,Difuso pixelado,,Puf,Пиксельный шум,Пикселизовани фаз,Piksel fuzz -Smooth fuzz,OPTVAL_SMOOTHFUZZ,,,,Hladký fuzz,Glat fuzz,Glatt,Ομαλή θολούρα,Glata lanugo,Difuminado borroso,,Pehmeä sumennus,Bruit doux,Simított homály,Fuzz liscio,滑らかなファズ,부드러운 퍼즈,Gladde fuzz,Glatt fuzz,Wygładzony szum,Difuso suavizado,,Lin,Гладкий шум,Глатки фаз,Pürüzsüz fuzz -Swirly fuzz,OPTVAL_SWIRLYFUZZ,,,,Míchající fuzz,Svirklende fuzz,Gewirbelt,Περιστροφηκή θολούρα,Kirla lanugo,Difuminado en remolino, ,Pyörteinen sumennus,Bruit marbré,Örvénylő homály,Fuzz vorticoso,渦状ファズ,소용돌이 퍼즈,Zwerpend fuzz,Virvlende fuzz,Wirujący szum,Difuso encaracolado,,Vârtej,Кружащийся шум,Увртен фаз,Girdaplı fuzz -Translucent fuzz,OPTVAL_TRANSLUCENTFUZZ,,,,Průhledný fuzz,Gennemskinnelig fuzz,Transparent,Ημιδιαφανής θολούρα,Diafana lanugo,Difuminado Translúcido,,Läpikuultava sumennus,Bruit transparent,Áttetsző homály,Fuzz traslucido,半透明ファズ,반투명 퍼즈,Doorschijnende fuzz,Gjennomsiktig fuzz,Przezroczysty szum,Difuso translúcido,,Transparent,Прозрачный шум,Прозрачан фаз,Yarı saydam fuzz -Noise,OPTVAL_NOISE,,,,Šum,Støj,Rauschen,Ήχος,Bruo,Ruido,,Kohina,Neige,Zaj,Rumore,ノイズ,노이즈,Lawaaierige fuzz,Støy,Huk,Ruído,,Zgomot,Шум,Звук,Gürültü -Smooth Noise,OPTVAL_SMOOTHNOISE,,,,Hladký šum,Glat støj,Geglättetes Rauschen,Ομαλός ήχος,Glata Bruo,Ruido borroso,,Pehmeä kohina,Neige adoucie,Simított zaj,Rumore liscio,滑らかなノイズ,부드러운 노이즈,Gladde lawaaierige fuzz,Glatt støy,Wugładzony huk,Ruído suavizado,,Zgomot lin,Мягкий шум,Милозвучан звук,Yumuşak Gürültü -Jagged fuzz,OPTVAL_JAGGEDFUZZ,,,,Zubatý šum,Skarpt fuzz,Gezackt,Ζαρομένη θολούρα,Malglateca lanugo,Difuminado dentado,,Sahalaitainen sumennus,Neige rugeuse,Recés homály,Fuzz frastagliato,ギザギザ,들쭉날쭉한 퍼즈,Gekartelde fuzz,Takkete fuzz,Poszarpany szum,Difuso serrilhado,,Zimțat,Зазубренный шум,Назубљен фаз,Pürüzlü fuzz -Green/Magenta,OPTVAL_GREENMAGENTA,,,,Zelená/purpurová,Grøn/Magenta,Grün/Magenta,Πράσινο/Magenta,Verda/Magenta,Verde/Magenta,,Vihreä/Magenta,Vert/Magenta,Zöld/Magenta,Verde/Magenta,緑/紫,초록/심홍색,Groen/Magenta,Grønn/magenta,Zielony/Magenta,Verde/Magenta,,Verde/Purpuriu,Зелёный/пурпурный,Зелен/Магента,Yeşil/Macenta -Red/Cyan,OPTVAL_REDCYAN,,,,Červená/tyrkysová,Rød/Cyan,Rot/Cyan,Κόκινο/Κυανό,Ruĝa/Cejana,Rojo/Cian,,Punainen/Sinivihreä,Rouge/Bleu,Piros/Türkiz,Rosso/Ciano,赤/空,빨강/하늘색,Rood/Cyaan,Rød/cyan,Czerwony/Błękitny,Vermelho/Ciano,,Roșu/Turcoaz,Красный/голубой,Црвен/Цијан,Kırmızı/Mavi -Amber/Blue,OPTVAL_AMBERBLUE,,,,Oranžová/modrá,Rav/blå,Orange/Blau,Amber/Μπλέ,Sukcenokolora/Blua,Ámbar/Azul,,Ruskeankeltainen/Sininen,Ambre/Bleu,Sárga/Kék,Ambra/Blu,黄/青,황토/파랑색,Amber/Blauw,Rav/blå,Bursztynowy/Niebieski,Âmbar/Azul,,Chihlimbar/Albastru,Янтарный/синий,Ћилибарски/Плаво,Kehribar/Mavi -Left Eye,OPTVAL_LEFTEYE,,,,Levé oko,Venstre øje,Linkes Auge,Αριστερό μάτι,Maldekstra Okulo,Ojo izquierdo,,Vasen silmä,Oeil Gauche,Bal szem,Occhio sinistro,左目,왼쪽 눈,Linkeroog,Venstre øye,Lewe Oko,Olho Esquerdo,,Ochi Stâng,Левый глаз,Лево око,Sol Göz -Right Eye,OPTVAL_RIGHTEYE,,,,Pravé oko,Højre øje,Rechtes Auge,Δεξί μάτι,Dekstra Okulo,Ojo derecho,,Oikea silmä,Oeil Droit,Jobb szem,Occhio destro,右目,오른쪽 눈,Rechteroog,Høyre øye,Prawe Oko,Olho Direito,,Ochi drept,Правый глаз,Десно око,Sağ Göz -Side-by-side Full,OPTVAL_SBSFULL,,,,"Vedle sebe, plné",Side ved side i fuld bredde,Nebeneinander volle Breite,,Flank-ĉe-flanka Tuta,Lado a lado completo,,Täysi rinnakkaisasettelu,Côte-â-côte Complet,Egymás melletti Teljes,Fianco a fianco completo,両サイド フル,크게 좌우배치,Zij-aan-zij Volledig,Side-ved-side Full,Pełne Obok Siebie,Lado a lado completo,,Una lângă alta Pline,"Бок о бок, полно",Раме уз раме цело,Yan yana Tam -Side-by-side Narrow,OPTVAL_SBSNARROW,,,,"Vedle sebe, úzké",Side ved side i halv bredde,Nebeneinander halbe Breite,,Flank-ĉe-flanka Mallarĝa,Lado a lado estrecho,,Kapea rinnakkaisasettelu,Côte-â-côte étroit,Egymás melletti Szűk,Fianco a fianco stretto,両サイド ナロー,좁게 좌우배치,Zij-aan-zij smal,Side ved side Smal,Wąskie Obok Siebie,Lado a lado estreito,,Una lângă alta Înguste,"Бок о бок, узко",Раме уз раме уско,Yan yana Dar -Top/Bottom,OPTVAL_TOPBOTTOM,,,,Nad sebou,Øverst/underst,Übereinander,Πάνω/Κάτω,Supero/Subo,Superior/Inferior,,Ylä-/Alaosa,Dessus/Dessous,Fent/Lent,Sopra/Sotto,天/底,위/아래,Boven/onderkant,Topp/Bunn,Góra/Dół,Superior/Inferior,,Sus/Jos,Сверху/снизу,Врх/Дно,Üst/Alt -Row Interleaved,OPTVAL_ROWINTERLEAVED,,,,Po řádcích,Forskydning af rækker,Zeilenversetzt,,Vicoj interteksitaj,Fila intercalada,,Vaakalomitus,Entrelacement rangée,Sor beillesztés,Riga interfogliata,行インターリーブ,열 교차 배치,Rij interleaved,Rad sammenflettet,Przepleciony Szereg,Linha Intercalada,,Rând intercalat,Чередование строк,Редно прошарано,Satır Aralıklı -Column Interleaved,OPTVAL_COLUMNINTERLEAVED,,,,Po sloupcích,Forskydning af kolonner,Spaltenversetzt,,Kolonoj interteksitaj,Columna intercalada,,Pystylomitus,Entralcement colonne,Oszlop beillesztés,Colonna interfogliata,列インターリーブ,세로줄 교차 배치,Kolom Interleaved,Kolonne sammenflettet,Przepleciona Kolumna,Coluna Intercalada,,Coloană intercalată,Чередование столбцов,Колонско прошарано,Sütun Aralıklı -Checkerboard,OPTVAL_CHECKERBOARD,,,,Šachovnice,Ternet,Schachbrettmuster,,Ŝaktablo,Tablero de damas,,Shakkilautakuvio,Damier,Tábla,Scacchiere,市松模様,체크무늬,Dambord,Sjakkbrett,Szachownica,Xadrez,,Tablă de Șah,Шахматная доска,Шаховска табла,Dama Tahtası -Quad-buffered,OPTVAL_QUADBUFFERED,,,,Quad buffer,Quad-buffered,Vierfachgepuffert,,Kvarobla bufro,Cuádruple búfer,,Neloispuskurointi,Quadruple-tampon,Négyszeresen bufferelt,Quad buffer,クワッドバッファー,쿼드 버퍼,Viervoudig gebufferd,Firebufret,Poczwórnie zbuforowane,Buffer quádruplo,,Împătrit,Четырёхкратный,Квад-унапређено,Dört tamponlu -TrueColor Options,DSPLYMNU_TCOPT,,,,Nastavení True color,TrueColor-indstillinger,TrueColor Optionen,TrueColor Ρυθμίσεις,Plenkolora Agordoj,Opciones TrueColor,,TrueColor-asetukset,Options TrueColor,TrueColor Beállítások,Opzioni TrueColor,トゥルーカラー オプション,트루 컬러 설정,TrueColor Opties,TrueColor-alternativer,Opcje TrueColor,Opções de TrueColor,,Setări Mod Culori Complete,Полноцветный режим,Подешавања правих боја,TrueColor Seçenekleri -TrueColor Options,TCMNU_TITLE,,,,Nastavení True color,TrueColor-indstillinger,TrueColor Optionen,TrueColor Ρυθμίσεις,Plenkolora Agordoj,Opciones TrueColor,,TrueColor-asetukset,Options TrueColor,TrueColor Beállítások,Opzioni TrueColor,トゥルーカラー オプション,트루 컬러 설정,TrueColor Opties,TrueColor-alternativer,Opcje TrueColor,Opções de TrueColor,,Setări Mod Culori Complete,Настройки полноцветности,Подешавања правих боја,TrueColor Seçenekleri -True color output,TCMNU_TRUECOLOR,,,,Výstup True color,TrueColor-udgang,TrueColor Ausgabe,TrueColor παραγωγή,Plenkolora eligo,Salida de True color,,True color -ulostulo,Sortie Truecolor,Truecolor Kimenet,Output true color,トゥルーカラー出力,트루 컬러 출력,Ware kleurenoutput,Ekte fargeutgang,Wyjście TrueColor,Saída de true color,,Putere Mod Culori Complete,Полноцветный вывод,Излаз правих боја,Gerçek renk çıkışı -Linear filter when downscaling,TCMNU_MINFILTER,,,,Lineární filtrování při zmenšení,Lineært filter ved nedskalering,Linearer Filter beim Herunterskalieren,Γραμμικό φίλτρο για σμίκρυνση,Linia filtro kiam subskali,Filtro lineal por reducción,,Lineaarinen suodatin alas skaalatessa,Filtrage linéaire en réduction,Lineáris filterezés leméretezésnél,Filtro lineare per la riduzione,縮小時のリニアフィルター,축소시 선형 필터링함,Lineair filter voor downscaling,Lineært filter ved nedskalering,Liniowy filtr podczas zmniejszania rozmiaru,Filtro linear ao reduzir,,Filtru liniar la micșorare,Линейная фильтрация при уменьшении,Линеарни филтер током смањења,Küçültme sırasında doğrusal filtre -Linear filter when upscaling,TCMNU_MAGFILTER,,,,Lineární filtrování při zvětšení,Lineært filter ved opskalering,Linearer Filter beim Hochskalieren,Γραμμικό φίλτρο για πολυτέληση,Linia filtro kima superskali,Filtro lineal por escalado,,Lineaarinen suodatin ylös skaalatessa,Filtrage linéaire en agrandissement,Lineáris filterezés felméretezésnél,Filtro lineare per l'aumento,拡大時のリニアフィルター,확대시 선형 필터링함,Lineair filter voor upscaling,Lineært filter ved oppskalering,Liniowy filtr podczas zwiększania rozmiaru,Filtro linear ao aumentar,,Filtru liniar la mărire,Линейная фильтрация при увеличении,Линеарни филтер током повећања,Yükseltme sırasında doğrusal filtre -Use mipmapped textures,TCMNU_MIPMAP,,,,Použít mipmapy,Brug mipmapped teksturer,Benutze Textur-Mipmaps,Χρήση mipmapped υφών,Uzi mipmapajn teksturojn,Usar texturas con mipmap,,Käytä mipkartallisia pintakuviointeja,Utiliser textures mipmappées,Mipmap textúrák,Usa le texture mipmapped,ミップマップテクスチャを使用,밉맵 텍스쳐 사용,Gebruik mipmapped texturen,Bruk mipmapped teksturer,Użyj mipmapowane tekstury,Usar texturas com mipmapping,,Mip mapping pentru texturi,Применять MIP-текстурирование,Користи мипмаповане текстуре,Eşlenmiş dokular kullanın -Dynamic lights (Software),TCMNU_DYNLIGHTS,,,,Dynamická světla (software),Dynamisk lys (software),Dynamisches Licht (Software),Δυναμικά φώτα (Λογισμικό),Dinamikaj lumoj (Programbildigilo),Luces dinámicas (Software),,Dynaamiset valot (ohjelmisto),Lumières Dynamiques (Software),Dinamikus fények (szoftveres),Luci Dinamiche (Software),ダイナミックライト (ソフトウェア),다이나믹 라이트 (소프트웨어 버전),Dynamische verlichting (software),Dynamiske lys (programvare),Dynamiczne Światło (Oprogramowanie),Luzes Dinâmicas (Software),,Lumini Dinamice (Mod Software),Динамическое освещение (программное),Динамичко осветљење (софтвер),Dinamik ışıklar (Yazılım) -Option Search,OS_TITLE,,,,Vyhledávání možností,Mulighed Søg,Optionssuche,Αναζήτηση Ρυθμίσεων,Agorda Serĉo,Buscar Opciones,,Asetushaku,Recherche Option,Beállítás Keresés,Opzioni di ricerca,オプション検索,옵션 검색,Optie zoeken,Alternativt søk,Szukanie Opcji,Buscar opção,Procurar opção,Căutare Setări,Поиск настройки,Претрага,Seçenek Arama -Search for any term,OS_ANY,,,,Hledat jakékoli klíčové slovo,Søg efter et vilkårligt begreb,Suche nach beliebigem Begriff,Αναζήτηση για όποιαδηποτε λέξη,Serĉi por iu ajn termino,Buscar cualquier término,,Etsi mitä tahansa sanaa,N'importe quel mot,Bármilyen szótagra keresés,Cerca per ciascun termine,いずれかの用語を探す,용어 검색,Zoek naar eender welke term,Søk etter et vilkårlig begrep,Szukaj jakiegokolwiek wyrażenia,Buscar por qualquer termo,Procurar por um termo qualquer,Căutare după orice termen,Искать любое из слов,Тражи било коју од речи,Herhangi bir terim için arama yapın -Search for all terms,OS_ALL,,,,Hledat všechna klíčová slova,Søg efter alle udtryk,Suche nach allen Begriffen,Αναζήτηση για όλες της λέξεις,Serĉi por ĉiuj terminoj,Buscar todos los términos,,Etsi kaikki sanat,Tous les mots,Összes szótagra keresés,Cerca per tutti i termini,全ての用語を探す,모든 조건 검색,Zoek naar alle termen,Søk etter alle termer,Szukaj wszystkich wyrażeń,Buscar por todos os termos,Procurar por todos os termos,Căutare după toți termenii,Искать все слова,Тражи све речи,Tüm terimler için arama yapın -No results found.,OS_NO_RESULTS,,,,Nic nenalezeno.,Ingen resultater fundet.,Keine Resultate,Δέν βρέθηκαν αποτελέσματα,Neniuj rezultoj trovitaj.,Ningun resultado.,,Ei tuloksia.,Pas de résultat trouvé,Nincs keresési találat,Nessun risultato trovato.,見つかりませんでした。,검색 결과 없음.,Geen resultaten gevonden.,Ingen resultater funnet.,Brak wyników,Nenhum resultado encontrado.,,Niciun rezultat găsit.,Результаты не найдены.,Нема резултата.,Sonuç bulunamadı. -Search:,OS_LABEL,,,,Hledat:,Søg:,Suche:,Αναζήτηση:,Serĉi:,Buscar:,,Etsi:,Recherche:,Keresés:,Trova:,検索:,검색:,Zoeken:,Søk:,Szukaj:,Busca:,Procura:,Căutare:,Поиск:,Претрага:,Arama yapın: -Always show keys,AUTOMAPMNU_SHOWKEYS_ALWAYS,,,,Vždy zobrazit klíče,Vis altid nøgler,Zeige immer alle Schlüssel,Εμφάνιση πλήκτρων πάντα,Ĉiam montri ŝlosilojn,Mostrar llaves siempre,,Aina näytä avaimet,Toujour afficher clés,Kulcsokat mindig mutat,Mostra sempre le chiavi,常にキーを表示,항상 키들을 표시,Toon altijd de toetsen,Vis alltid nøkler,Zawsze pokazuj klucze,Sempre mostrar chaves,Exibir chaves sempre,Afișează cheile în permanență,Всегда отображать ключи,Увек приказуј кључеве,Her zaman anahtarları göster -,,Newly added content,,,,,,,,,,,,,,,,,,,,,,,, -Team changing has been disabled!,TXT_NO_TEAM_CHANGE,,,,Změna týmu je vypnuta!,Holdskift er blevet deaktiveret!,Teamwechsel ist deaktiviert!,Η αλαγγή ομάδον απαγορεύεται!,Teamŝanĝiĝo estas malvalidigita!,¡El cambio de equipo ha sido desactivado!,,Joukkueen vaihtaminen on kytketty pois päältä!,Les changements d'équipe sont désactivés!,Csapatváltás letiltva,È stato disabilitato il cambio di squadra!,チームの変更は受け付けない!,팀 변경이 불가능해짐!,Teamwisseling is uitgeschakeld!,Lagbytte har blitt deaktivert!,Zmiana drużyn została wyłączona!,Troca de equipe foi desativada!,Troca de equipa foi desativada!,Schimbarea echipelor a fost dezactivată!,Смена команды была отключена!,Мењање тима је искључено!,Takım değiştirme devre dışı bırakıldı! -%s joined the %t team,TXT_JOINED_TEAM,%s is the player and gender sensitive,,,%s se připojil@[ao_cs] k týmu %t.,%s er blevet medlem af %t-team,%s is dem %t Team beigetreten.,@[art_gr] %s έγινε μέλος τής %t ομάδας,%s aliĝis al la %t teamo,%s se unió al equipo %t,,%s liittyi joukkueeseen %t,%s a rejoint l'équipe %t.,%s belépett a %t csapatba,%s entra nel team %t,%s は %t のチームに入隊した,%s 이(가) %s 팀에 합류함,%s zijn bij het %t team gekomen.,%s ble med i %t-teamet,%s dołącza do drużyny %t,%s entrou na equipe %t,,%s s-a alăturat echipei %t,Игрок %s присоединяется к команде %t,%s је уш@[ao_2_sr] у %t тим,%s %t takımına katıldı -%s is now a loner.,TXT_LONER,,,,%s je teď @[self_cs].,%s er nu en enspænder.,%s ist jetzt ein@[e_de] Einzelgänger@[in_de].,@[art_gr] %s είναι τώρα μόνο/ς/η @[pro4_gr],%s nun estas solemulo.,%s es ahora solitari@[ao_esp].,,%s on nyt yksikseen.,%s joue maintenant tout seul.,%s immáron magányos útralépett,%s è da solo,%s は今 一匹狼だ。,%s 은(는) 혼자 남음.,%s is nu een eenling.,%s er nå en einstøing.,%s jest teraz sam@[ao_pl],%s está sozinh@[ao_ptb] agora.,,%s este singur acum,Игрок %s теперь одиночка.,%s је сада самотњак.,%s artık yalnız. +",Usar como paleta,Usar como palete,Utilizare drept paletă,Использовать как палитру,Користи као палету,Används som palett,Palet olarak kullanın +Blend,OPTVAL_BLEND,,,,Míchat,,Überblenden,,Miksi,Mezclar,,Sekoitus,Mélanger,Kever,Miscela,混合,혼합,Mengen,Blanding,Połącz,Mesclar,Misturar,Amestec,Смешать,Бленд,Blanda,Karışım +Bright,OPTVAL_BRIGHT,,,,Světlý,Lys,Hell,,Hela,Brillante,,Kirkas,Clair,Világos,Chiara,明るい,밝은,Helder,Lys,Jasne,Claro,,Luminos,Яркий,Свијетло,Ljusa,Parlak +Dark,OPTVAL_DARK,,,,Tmavý,Mørk,Dunkel,,Malhela,Oscuro,,Tumma,Sombre,Sötét,Scura,暗い,어두운,Donker,Mørk,Ciemne,Escuro,,Întunecat,Тёмный,Тамно,Mörk,Karanlık +Doom Legacy,OPTVAL_LEGACY,"This refers to the Doom Legacy port, not a legacy lighting style!",,,,,,,,,,,,,,,,,,,,,,,,, +Software,OPTVAL_SOFTWARE,,,,,,,,Programa bildigilo,,,Ohjelmisto,,Szoftver,,ソフトウェア,소프트웨어,,,Oprogramowanie,,,,Программный,Софтвер,Programvara,Yazılım +Optimal,OPTVAL_OPTIMAL,,,,Optimální,,,,Optima,Óptimo,,Optimaalinen,Optimiser,Optimális,Ottimale,最適,최적함,Optimaal,,Optymalne,Otimizado,,Optim,Оптимальный,Оптимал,Optimal,Optimal +Y Axis,OPTVAL_YAXIS,,,,Po ose Y,Y-akse,Y-Achse,,Y-Akso,Eje Y,,Y-akseli,Axe Y,Y tengely,Asse Y,縦軸,Y 축,Y-as,Y-akse,Oś Y,Eixo Y,,Axa Y,По горизонтали,Y оса,Y-axeln,Y Ekseni +X/Y Axis,OPTVAL_XYAXIS,,,,Po osách X/Y,X/Y-akse,X/Y-Achse,,X/Y-Akso,Ejes X/Y,,X- ja Y-akselit,Axes X/Y,X/Y tengely,Asse X/Y,縦/横軸,X/Y 축,X/Y As,X/Y-akse,Oś X/Y,Eixo X/Y,,Axa Y/Z,По обеим осям,X/Y оса,X/Y-axel,X/Y Ekseni +Square,OPTVAL_SQUARE,,,,Čtvercové,Firkantet,Quadratisch,,Kvadrata,Cuadrado,,Kulmikas,Carrées,Négyzet,Quadrato,平方,정사각형,Vierkant,Firkantet,Kwadrat,Quadrado,,Pătrat,Квадратные,Квадрат,Kvadratisk,Kare +Round,OPTVAL_ROUND,,,,Kulaté,Rund,Rund,,Ronda,Redondo,,Pyöreä,Rondes,Kör,Arrotondato,円形,원형,Rond,Rund,Okrągłe,Redondo,,Rotund,Круглые,Круг,Rund,Yuvarlak +Radial,OPTVAL_RADIAL,,,,Radiální,,,Ακτινικό,Radiusa,,,Säteittäinen,,Sugaras,Radiale,放射状,방사형,Radiaal,,Promieniowe,,,Radială,Радиальный,Радијално,Radial,Radyal +Pixel fuzz,OPTVAL_PIXELFUZZ,,,,Pixelový fuzz,,Pixel,Pixel θολούρα,Bildera lanugo,Difuminado pixelado,,Kuvapistesumennus,Bruit Pixélisé,Pixeles homály,Fuzz pixelato,ピクセル ファズ,픽셀 퍼즈,Pixel fuzz,,Szum pikseli,Difuso pixelado,,Puf,Пиксельный шум,Пикселизовани фаз,,Piksel fuzz +Smooth fuzz,OPTVAL_SMOOTHFUZZ,,,,Hladký fuzz,Glat fuzz,Glatt,Ομαλή θολούρα,Glata lanugo,Difuminado borroso,,Pehmeä sumennus,Bruit doux,Simított homály,Fuzz liscio,滑らかなファズ,부드러운 퍼즈,Gladde fuzz,Glatt fuzz,Wygładzony szum,Difuso suavizado,,Lin,Гладкий шум,Глатки фаз,Slät fuzz,Pürüzsüz fuzz +Swirly fuzz,OPTVAL_SWIRLYFUZZ,,,,Míchající fuzz,Svirklende fuzz,Gewirbelt,Περιστροφηκή θολούρα,Kirla lanugo,Difuminado en remolino, ,Pyörteinen sumennus,Bruit marbré,Örvénylő homály,Fuzz vorticoso,渦状ファズ,소용돌이 퍼즈,Zwerpend fuzz,Virvlende fuzz,Wirujący szum,Difuso encaracolado,,Vârtej,Кружащийся шум,Увртен фаз,Virvlande fuzz,Girdaplı fuzz +Translucent fuzz,OPTVAL_TRANSLUCENTFUZZ,,,,Průhledný fuzz,Gennemskinnelig fuzz,Transparent,Ημιδιαφανής θολούρα,Diafana lanugo,Difuminado Translúcido,,Läpikuultava sumennus,Bruit transparent,Áttetsző homály,Fuzz traslucido,半透明ファズ,반투명 퍼즈,Doorschijnende fuzz,Gjennomsiktig fuzz,Przezroczysty szum,Difuso translúcido,,Transparent,Прозрачный шум,Прозрачан фаз,Genomskinlig fuzz,Yarı saydam fuzz +Noise,OPTVAL_NOISE,,,,Šum,Støj,Rauschen,Ήχος,Bruo,Ruido,,Kohina,Neige,Zaj,Rumore,ノイズ,노이즈,Lawaaierige fuzz,Støy,Huk,Ruído,,Zgomot,Шум,Звук,Buller,Gürültü +Smooth Noise,OPTVAL_SMOOTHNOISE,,,,Hladký šum,Glat støj,Geglättetes Rauschen,Ομαλός ήχος,Glata Bruo,Ruido borroso,,Pehmeä kohina,Neige adoucie,Simított zaj,Rumore liscio,滑らかなノイズ,부드러운 노이즈,Gladde lawaaierige fuzz,Glatt støy,Wugładzony huk,Ruído suavizado,,Zgomot lin,Мягкий шум,Милозвучан звук,Slätt brus,Yumuşak Gürültü +Jagged fuzz,OPTVAL_JAGGEDFUZZ,,,,Zubatý šum,Skarpt fuzz,Gezackt,Ζαρομένη θολούρα,Malglateca lanugo,Difuminado dentado,,Sahalaitainen sumennus,Neige rugeuse,Recés homály,Fuzz frastagliato,ギザギザ,들쭉날쭉한 퍼즈,Gekartelde fuzz,Takkete fuzz,Poszarpany szum,Difuso serrilhado,,Zimțat,Зазубренный шум,Назубљен фаз,Skarvig fuzz,Pürüzlü fuzz +Green/Magenta,OPTVAL_GREENMAGENTA,,,,Zelená/purpurová,Grøn/Magenta,Grün/Magenta,Πράσινο/Magenta,Verda/Magenta,Verde/Magenta,,Vihreä/Magenta,Vert/Magenta,Zöld/Magenta,Verde/Magenta,緑/紫,초록/심홍색,Groen/Magenta,Grønn/magenta,Zielony/Magenta,Verde/Magenta,,Verde/Purpuriu,Зелёный/пурпурный,Зелен/Магента,Grön/Magenta,Yeşil/Macenta +Red/Cyan,OPTVAL_REDCYAN,,,,Červená/tyrkysová,Rød/Cyan,Rot/Cyan,Κόκινο/Κυανό,Ruĝa/Cejana,Rojo/Cian,,Punainen/Sinivihreä,Rouge/Bleu,Piros/Türkiz,Rosso/Ciano,赤/空,빨강/하늘색,Rood/Cyaan,Rød/cyan,Czerwony/Błękitny,Vermelho/Ciano,,Roșu/Turcoaz,Красный/голубой,Црвен/Цијан,Röd/Cyan,Kırmızı/Mavi +Amber/Blue,OPTVAL_AMBERBLUE,,,,Oranžová/modrá,Rav/blå,Orange/Blau,Amber/Μπλέ,Sukcenokolora/Blua,Ámbar/Azul,,Ruskeankeltainen/Sininen,Ambre/Bleu,Sárga/Kék,Ambra/Blu,黄/青,황토/파랑색,Amber/Blauw,Rav/blå,Bursztynowy/Niebieski,Âmbar/Azul,,Chihlimbar/Albastru,Янтарный/синий,Ћилибарски/Плаво,Bärnsten/blått,Kehribar/Mavi +Left Eye,OPTVAL_LEFTEYE,,,,Levé oko,Venstre øje,Linkes Auge,Αριστερό μάτι,Maldekstra Okulo,Ojo izquierdo,,Vasen silmä,Oeil Gauche,Bal szem,Occhio sinistro,左目,왼쪽 눈,Linkeroog,Venstre øye,Lewe Oko,Olho Esquerdo,,Ochi Stâng,Левый глаз,Лево око,Vänster öga,Sol Göz +Right Eye,OPTVAL_RIGHTEYE,,,,Pravé oko,Højre øje,Rechtes Auge,Δεξί μάτι,Dekstra Okulo,Ojo derecho,,Oikea silmä,Oeil Droit,Jobb szem,Occhio destro,右目,오른쪽 눈,Rechteroog,Høyre øye,Prawe Oko,Olho Direito,,Ochi drept,Правый глаз,Десно око,Höger öga,Sağ Göz +Side-by-side Full,OPTVAL_SBSFULL,,,,"Vedle sebe, plné",Side ved side i fuld bredde,Nebeneinander volle Breite,,Flank-ĉe-flanka Tuta,Lado a lado completo,,Täysi rinnakkaisasettelu,Côte-â-côte Complet,Egymás melletti Teljes,Fianco a fianco completo,両サイド フル,크게 좌우배치,Zij-aan-zij Volledig,Side-ved-side Full,Pełne Obok Siebie,Lado a lado completo,,Una lângă alta Pline,"Бок о бок, полно",Раме уз раме цело,Sidoordnat fullt ut,Yan yana Tam +Side-by-side Narrow,OPTVAL_SBSNARROW,,,,"Vedle sebe, úzké",Side ved side i halv bredde,Nebeneinander halbe Breite,,Flank-ĉe-flanka Mallarĝa,Lado a lado estrecho,,Kapea rinnakkaisasettelu,Côte-â-côte étroit,Egymás melletti Szűk,Fianco a fianco stretto,両サイド ナロー,좁게 좌우배치,Zij-aan-zij smal,Side ved side Smal,Wąskie Obok Siebie,Lado a lado estreito,,Una lângă alta Înguste,"Бок о бок, узко",Раме уз раме уско,Sidoväggar smal,Yan yana Dar +Top/Bottom,OPTVAL_TOPBOTTOM,,,,Nad sebou,Øverst/underst,Übereinander,Πάνω/Κάτω,Supero/Subo,Superior/Inferior,,Ylä-/Alaosa,Dessus/Dessous,Fent/Lent,Sopra/Sotto,天/底,위/아래,Boven/onderkant,Topp/Bunn,Góra/Dół,Superior/Inferior,,Sus/Jos,Сверху/снизу,Врх/Дно,Överst/underst,Üst/Alt +Row Interleaved,OPTVAL_ROWINTERLEAVED,,,,Po řádcích,Forskydning af rækker,Zeilenversetzt,,Vicoj interteksitaj,Fila intercalada,,Vaakalomitus,Entrelacement rangée,Sor beillesztés,Riga interfogliata,行インターリーブ,열 교차 배치,Rij interleaved,Rad sammenflettet,Przepleciony Szereg,Linha Intercalada,,Rând intercalat,Чередование строк,Редно прошарано,Rad med interfolierad rad,Satır Aralıklı +Column Interleaved,OPTVAL_COLUMNINTERLEAVED,,,,Po sloupcích,Forskydning af kolonner,Spaltenversetzt,,Kolonoj interteksitaj,Columna intercalada,,Pystylomitus,Entralcement colonne,Oszlop beillesztés,Colonna interfogliata,列インターリーブ,세로줄 교차 배치,Kolom Interleaved,Kolonne sammenflettet,Przepleciona Kolumna,Coluna Intercalada,,Coloană intercalată,Чередование столбцов,Колонско прошарано,Kolumn interfolierad,Sütun Aralıklı +Checkerboard,OPTVAL_CHECKERBOARD,,,,Šachovnice,Ternet,Schachbrettmuster,,Ŝaktablo,Tablero de damas,,Shakkilautakuvio,Damier,Tábla,Scacchiere,市松模様,체크무늬,Dambord,Sjakkbrett,Szachownica,Xadrez,,Tablă de Șah,Шахматная доска,Шаховска табла,Tärningsbräda,Dama Tahtası +Quad-buffered,OPTVAL_QUADBUFFERED,,,,Quad buffer,Quad-buffered,Vierfachgepuffert,,Kvarobla bufro,Cuádruple búfer,,Neloispuskurointi,Quadruple-tampon,Négyszeresen bufferelt,Quad buffer,クワッドバッファー,쿼드 버퍼,Viervoudig gebufferd,Firebufret,Poczwórnie zbuforowane,Buffer quádruplo,,Împătrit,Четырёхкратный,Квад-унапређено,Kvadratbuffrad,Dört tamponlu +TrueColor Options,DSPLYMNU_TCOPT,,,,Nastavení True color,TrueColor-indstillinger,TrueColor Optionen,TrueColor Ρυθμίσεις,Plenkolora Agordoj,Opciones TrueColor,,TrueColor-asetukset,Options TrueColor,TrueColor Beállítások,Opzioni TrueColor,トゥルーカラー オプション,트루 컬러 설정,TrueColor Opties,TrueColor-alternativer,Opcje TrueColor,Opções de TrueColor,,Setări Mod Culori Complete,Полноцветный режим,Подешавања правих боја,TrueColor-alternativ,TrueColor Seçenekleri +TrueColor Options,TCMNU_TITLE,,,,Nastavení True color,TrueColor-indstillinger,TrueColor Optionen,TrueColor Ρυθμίσεις,Plenkolora Agordoj,Opciones TrueColor,,TrueColor-asetukset,Options TrueColor,TrueColor Beállítások,Opzioni TrueColor,トゥルーカラー オプション,트루 컬러 설정,TrueColor Opties,TrueColor-alternativer,Opcje TrueColor,Opções de TrueColor,,Setări Mod Culori Complete,Настройки полноцветности,Подешавања правих боја,TrueColor-alternativ,TrueColor Seçenekleri +True color output,TCMNU_TRUECOLOR,,,,Výstup True color,TrueColor-udgang,TrueColor Ausgabe,TrueColor παραγωγή,Plenkolora eligo,Salida de True color,,True color -ulostulo,Sortie Truecolor,Truecolor Kimenet,Output true color,トゥルーカラー出力,트루 컬러 출력,Ware kleurenoutput,Ekte fargeutgang,Wyjście TrueColor,Saída de true color,,Putere Mod Culori Complete,Полноцветный вывод,Излаз правих боја,Utmatning i äkta färg,Gerçek renk çıkışı +Linear filter when downscaling,TCMNU_MINFILTER,,,,Lineární filtrování při zmenšení,Lineært filter ved nedskalering,Linearer Filter beim Herunterskalieren,Γραμμικό φίλτρο για σμίκρυνση,Linia filtro kiam subskali,Filtro lineal por reducción,,Lineaarinen suodatin alas skaalatessa,Filtrage linéaire en réduction,Lineáris filterezés leméretezésnél,Filtro lineare per la riduzione,縮小時のリニアフィルター,축소시 선형 필터링함,Lineair filter voor downscaling,Lineært filter ved nedskalering,Liniowy filtr podczas zmniejszania rozmiaru,Filtro linear ao reduzir,,Filtru liniar la micșorare,Линейная фильтрация при уменьшении,Линеарни филтер током смањења,Linjärt filter vid nedskalning,Küçültme sırasında doğrusal filtre +Linear filter when upscaling,TCMNU_MAGFILTER,,,,Lineární filtrování při zvětšení,Lineært filter ved opskalering,Linearer Filter beim Hochskalieren,Γραμμικό φίλτρο για πολυτέληση,Linia filtro kima superskali,Filtro lineal por escalado,,Lineaarinen suodatin ylös skaalatessa,Filtrage linéaire en agrandissement,Lineáris filterezés felméretezésnél,Filtro lineare per l'aumento,拡大時のリニアフィルター,확대시 선형 필터링함,Lineair filter voor upscaling,Lineært filter ved oppskalering,Liniowy filtr podczas zwiększania rozmiaru,Filtro linear ao aumentar,,Filtru liniar la mărire,Линейная фильтрация при увеличении,Линеарни филтер током повећања,Linjärt filter vid uppskalning,Yükseltme sırasında doğrusal filtre +Use mipmapped textures,TCMNU_MIPMAP,,,,Použít mipmapy,Brug mipmapped teksturer,Benutze Textur-Mipmaps,Χρήση mipmapped υφών,Uzi mipmapajn teksturojn,Usar texturas con mipmap,,Käytä mipkartallisia pintakuviointeja,Utiliser textures mipmappées,Mipmap textúrák,Usa le texture mipmapped,ミップマップテクスチャを使用,밉맵 텍스쳐 사용,Gebruik mipmapped texturen,Bruk mipmapped teksturer,Użyj mipmapowane tekstury,Usar texturas com mipmapping,,Mip mapping pentru texturi,Применять MIP-текстурирование,Користи мипмаповане текстуре,Använd mipmappade texturer,Eşlenmiş dokular kullanın +Dynamic lights (Software),TCMNU_DYNLIGHTS,,,,Dynamická světla (software),Dynamisk lys (software),Dynamisches Licht (Software),Δυναμικά φώτα (Λογισμικό),Dinamikaj lumoj (Programbildigilo),Luces dinámicas (Software),,Dynaamiset valot (ohjelmisto),Lumières Dynamiques (Software),Dinamikus fények (szoftveres),Luci Dinamiche (Software),ダイナミックライト (ソフトウェア),다이나믹 라이트 (소프트웨어 버전),Dynamische verlichting (software),Dynamiske lys (programvare),Dynamiczne Światło (Oprogramowanie),Luzes Dinâmicas (Software),,Lumini Dinamice (Mod Software),Динамическое освещение (программное),Динамичко осветљење (софтвер),Dynamiskt ljus (programvara),Dinamik ışıklar (Yazılım) +Option Search,OS_TITLE,,,,Vyhledávání možností,Mulighed Søg,Optionssuche,Αναζήτηση Ρυθμίσεων,Agorda Serĉo,Buscar Opciones,,Asetushaku,Recherche Option,Beállítás Keresés,Opzioni di ricerca,オプション検索,옵션 검색,Optie zoeken,Alternativt søk,Szukanie Opcji,Buscar opção,Procurar opção,Căutare Setări,Поиск настройки,Претрага,Alternativ Sök,Seçenek Arama +Search for any term,OS_ANY,,,,Hledat jakékoli klíčové slovo,Søg efter et vilkårligt begreb,Suche nach beliebigem Begriff,Αναζήτηση για όποιαδηποτε λέξη,Serĉi por iu ajn termino,Buscar cualquier término,,Etsi mitä tahansa sanaa,N'importe quel mot,Bármilyen szótagra keresés,Cerca per ciascun termine,いずれかの用語を探す,용어 검색,Zoek naar eender welke term,Søk etter et vilkårlig begrep,Szukaj jakiegokolwiek wyrażenia,Buscar por qualquer termo,Procurar por um termo qualquer,Căutare după orice termen,Искать любое из слов,Тражи било коју од речи,Sök efter valfri term,Herhangi bir terim için arama yapın +Search for all terms,OS_ALL,,,,Hledat všechna klíčová slova,Søg efter alle udtryk,Suche nach allen Begriffen,Αναζήτηση για όλες της λέξεις,Serĉi por ĉiuj terminoj,Buscar todos los términos,,Etsi kaikki sanat,Tous les mots,Összes szótagra keresés,Cerca per tutti i termini,全ての用語を探す,모든 조건 검색,Zoek naar alle termen,Søk etter alle termer,Szukaj wszystkich wyrażeń,Buscar por todos os termos,Procurar por todos os termos,Căutare după toți termenii,Искать все слова,Тражи све речи,Sök efter alla termer,Tüm terimler için arama yapın +No results found.,OS_NO_RESULTS,,,,Nic nenalezeno.,Ingen resultater fundet.,Keine Resultate,Δέν βρέθηκαν αποτελέσματα,Neniuj rezultoj trovitaj.,Ningun resultado.,,Ei tuloksia.,Pas de résultat trouvé,Nincs keresési találat,Nessun risultato trovato.,見つかりませんでした。,검색 결과 없음.,Geen resultaten gevonden.,Ingen resultater funnet.,Brak wyników,Nenhum resultado encontrado.,,Niciun rezultat găsit.,Результаты не найдены.,Нема резултата.,Inga resultat hittades.,Sonuç bulunamadı. +Search:,OS_LABEL,,,,Hledat:,Søg:,Suche:,Αναζήτηση:,Serĉi:,Buscar:,,Etsi:,Recherche:,Keresés:,Trova:,検索:,검색:,Zoeken:,Søk:,Szukaj:,Busca:,Procura:,Căutare:,Поиск:,Претрага:,Sök:,Arama yapın: +Always show keys,AUTOMAPMNU_SHOWKEYS_ALWAYS,,,,Vždy zobrazit klíče,Vis altid nøgler,Zeige immer alle Schlüssel,Εμφάνιση πλήκτρων πάντα,Ĉiam montri ŝlosilojn,Mostrar llaves siempre,,Aina näytä avaimet,Toujour afficher clés,Kulcsokat mindig mutat,Mostra sempre le chiavi,常にキーを表示,항상 키들을 표시,Toon altijd de toetsen,Vis alltid nøkler,Zawsze pokazuj klucze,Sempre mostrar chaves,Exibir chaves sempre,Afișează cheile în permanență,Всегда отображать ключи,Увек приказуј кључеве,Visa alltid nycklar,Her zaman anahtarları göster +,,Newly added content,,,,,,,,,,,,,,,,,,,,,,,,, +Team changing has been disabled!,TXT_NO_TEAM_CHANGE,,,,Změna týmu je vypnuta!,Holdskift er blevet deaktiveret!,Teamwechsel ist deaktiviert!,Η αλαγγή ομάδον απαγορεύεται!,Teamŝanĝiĝo estas malvalidigita!,¡El cambio de equipo ha sido desactivado!,,Joukkueen vaihtaminen on kytketty pois päältä!,Les changements d'équipe sont désactivés!,Csapatváltás letiltva,È stato disabilitato il cambio di squadra!,チームの変更は受け付けない!,팀 변경이 불가능해짐!,Teamwisseling is uitgeschakeld!,Lagbytte har blitt deaktivert!,Zmiana drużyn została wyłączona!,Troca de equipe foi desativada!,Troca de equipa foi desativada!,Schimbarea echipelor a fost dezactivată!,Смена команды была отключена!,Мењање тима је искључено!,Lagbyte har inaktiverats!,Takım değiştirme devre dışı bırakıldı! +%s joined the %t team,TXT_JOINED_TEAM,%s is the player and gender sensitive,,,%s se připojil@[ao_cs] k týmu %t.,%s er blevet medlem af %t-team,%s is dem %t Team beigetreten.,@[art_gr] %s έγινε μέλος τής %t ομάδας,%s aliĝis al la %t teamo,%s se unió al equipo %t,,%s liittyi joukkueeseen %t,%s a rejoint l'équipe %t.,%s belépett a %t csapatba,%s entra nel team %t,%s は %t のチームに入隊した,%s 이(가) %s 팀에 합류함,%s zijn bij het %t team gekomen.,%s ble med i %t-teamet,%s dołącza do drużyny %t,%s entrou na equipe %t,,%s s-a alăturat echipei %t,Игрок %s присоединяется к команде %t,%s је уш@[ao_2_sr] у %t тим,%s anslöt sig till %t teamet.,%s %t takımına katıldı +%s is now a loner.,TXT_LONER,,,,%s je teď @[self_cs].,%s er nu en enspænder.,%s ist jetzt ein@[e_de] Einzelgänger@[in_de].,@[art_gr] %s είναι τώρα μόνο/ς/η @[pro4_gr],%s nun estas solemulo.,%s es ahora solitari@[ao_esp].,,%s on nyt yksikseen.,%s joue maintenant tout seul.,%s immáron magányos útralépett,%s è da solo,%s は今 一匹狼だ。,%s 은(는) 혼자 남음.,%s is nu een eenling.,%s er nå en einstøing.,%s jest teraz sam@[ao_pl],%s está sozinh@[ao_ptb] agora.,,%s este singur acum,Игрок %s теперь одиночка.,%s је сада самотњак.,%s är nu en ensamvarg.,%s artık yalnız. %s left the game with %d frags,TXT_LEFTWITHFRAGS,,,,%s opustil@[ao_cs] hru s %d fragy,%s forlod spillet med %d frags,%s hat das Spiel mit %d Frags verlassen.,@[art_gr] %s έφυγε με %d κοματιασμόυς,%s eliris el la ludo kun %d ludmurdoj,%s salió de la partida con %d bajas,,%s poistui pelistä frägimäärällä %d,%s a quitté le jeu avec %d frags.,%s kilépett %d fraggel,%s ha lasciato il gioco con %d frag,"%s が逃げ出したので %d に点が入った -",%s 이(가) 게임에서 %d 의 점수를 기록하고 퇴장 함.,%s verliet het spel met %d frags,%s forlot spillet med %d frags,%s opuścił@[ao_pl] grę z %d fragami,%s saiu do jogo com %d frags,,%s a părăsit jocul cu %d victime,Игрок %s покидает игру с количеством фрагов: %d,%s је изаш@[ao_2_sr] из игре са %d фраговима.,%s oyunu %d frag ile terk etti -%s left the game,TXT_LEFTTHEGAME,,,,%s opustil@[ao_cs] hru,%s forlod spillet,%s hat das Spiel verlassen.,@[art_gr] %s έφυγε,%s eliris el la ludo,%s salió de la partida,,%s poistui pelistä,%s a quitté le jeu.,%s kilépett,%s ha lasciato il gioco,%s は退出した,%s 이(가) 게임을 떠남.,%s verliet het spel,%s forlot spillet,%s opuścił@[ao_pl] grę,%s saiu do jogo,,%s a părăsit jocul,Игрок %s покидает игру,%s је изаш@[ao_2_sr] из игре,%s oyundan ayrıldı -Could not read savegame '%s'.,TXT_COULDNOTREAD,,,,Nepodařilo se načíst uloženou hru '%s'.,Kunne ikke læse savegame '%s'.,Konnte Spielstand '%s' nicht lesen.,Το αρχείο αποθήκευσης %s δέν μπόρε να φορτωθεί,Ne povis legi la konservitan ludon '%s'.,No se pudo leer la partida guardada '%s'.,,Pelitallennetta '%s' ei voitu lukea.,Impossible de lire la sauvegarde '%s'.,A '%s' nem tölthető be.,Non si è potuto leggere il salvataggio '%s'.,%s' のセーブデータを読み込めなかった。,저장된 게임을 불러올 수 없습니다.'%s',Kon het savegame '%s' niet lezen.,Kunne ikke lese savegame '%s'.,Nie można odczytać zapisu „%s”.,"Não foi possível ler o jogo salvo ""%s"".","Não foi possível ler o jogo guardado ""%s"".",Salvarea '%s' nu a putut fi citită.,Невозможно прочитать сохранение: «%s».,Није могуће прочитати сачувану игру %s.,%s' kayıt oyunu okunamadı. +",%s 이(가) 게임에서 %d 의 점수를 기록하고 퇴장 함.,%s verliet het spel met %d frags,%s forlot spillet med %d frags,%s opuścił@[ao_pl] grę z %d fragami,%s saiu do jogo com %d frags,,%s a părăsit jocul cu %d victime,Игрок %s покидает игру с количеством фрагов: %d,%s је изаш@[ao_2_sr] из игре са %d фраговима.,%s lämnade spelet med %d frags,%s oyunu %d frag ile terk etti +%s left the game,TXT_LEFTTHEGAME,,,,%s opustil@[ao_cs] hru,%s forlod spillet,%s hat das Spiel verlassen.,@[art_gr] %s έφυγε,%s eliris el la ludo,%s salió de la partida,,%s poistui pelistä,%s a quitté le jeu.,%s kilépett,%s ha lasciato il gioco,%s は退出した,%s 이(가) 게임을 떠남.,%s verliet het spel,%s forlot spillet,%s opuścił@[ao_pl] grę,%s saiu do jogo,,%s a părăsit jocul,Игрок %s покидает игру,%s је изаш@[ao_2_sr] из игре,%s har lämnat spelet.,%s oyundan ayrıldı +Could not read savegame '%s'.,TXT_COULDNOTREAD,,,,Nepodařilo se načíst uloženou hru '%s'.,Kunne ikke læse savegame '%s'.,Konnte Spielstand '%s' nicht lesen.,Το αρχείο αποθήκευσης %s δέν μπόρε να φορτωθεί,Ne povis legi la konservitan ludon '%s'.,No se pudo leer la partida guardada '%s'.,,Pelitallennetta '%s' ei voitu lukea.,Impossible de lire la sauvegarde '%s'.,A '%s' nem tölthető be.,Non si è potuto leggere il salvataggio '%s'.,%s' のセーブデータを読み込めなかった。,저장된 게임을 불러올 수 없습니다.'%s',Kon het savegame '%s' niet lezen.,Kunne ikke lese savegame '%s'.,Nie można odczytać zapisu „%s”.,"Não foi possível ler o jogo salvo ""%s"".","Não foi possível ler o jogo guardado ""%s"".",Salvarea '%s' nu a putut fi citită.,Невозможно прочитать сохранение: «%s».,Није могуће прочитати сачувану игру %s.,"Kunde inte läsa sparspelet ""%s"".",%s' kayıt oyunu okunamadı. %s' is not a valid savegame: Missing 'info.json'.,TXT_NOINFOJSON,,,,%s' není funkční uloženou hrou: Chybí 'info.json'.,%s' er ikke et gyldigt savegame: Mangler 'info.json'.,%s' ist kein gültiger Spielstand. 'info.json' fehlt.,Το %s δεν είναι ένα έγκυρο αρχείο αποθήκευσης: Το info.json λείπει,%s' ne estas valida konservita ludo: Mankante 'info.json'.,%s' no es una partida guardada válida: Falta 'info.json'.,,%s' ei ole kelvollinen pelitallenne. Puuttuva 'info.json'.,%s n'est pas une sauvegarde valide. Fichier 'info.json' manquant.,%s' nem egy valós mentés: Hiányzó 'info.json'.,%s' non è un salvataggio valido: 'info.json' mancante.,%s' は有効なセーブデータ ではない: 'info.json'が不明。,%s' 는 유효하지 않습니다: 파일이 없습니다.'info.json',"%s"" is geen geldig savegame: Ontbreekt 'info.json'.",%s' er ikke et gyldig savegame: Mangler 'info.json'.,"„%s” nie jest prawidłowym zapisem gry: Brak „info.json” ","""%s"" não é um jogo salvo válido: Está faltando ""info.json"".","""%s"" não é um jogo gravado válido: Está faltando -""info.json"".",%s' nu este o salvare validă. Lipsește 'info.json',Сохранение «%s» некорректно: отсутствует «info.json».,%s није валидно сачувана игра: Недостаје „info.json“.,%s' geçerli bir kayıt oyunu değil: Eksik 'info.json'. -Failed to access savegame info in '%s'.,TXT_FAILEDTOREADSG,,,,Nepodařilo se načíst informace v uložené hře '%s'.,Det lykkedes ikke at få adgang til savegame info i '%s'.,Konnte Spielstandinfo in '%s' nicht lesen.,Η πρόσβαση πληροφοριών του αρχείου αποθήκευσης %s δέν ήταν επιτυχής,Malsukcesis aliri informon de la konservita ludo en '%s'.,Fallo al acceder a información de partida guardada en '%s'.,,Tiedoston '%s' pelitallennetietoihin ei päästy käsiksi.,Impossible d'accéder aux infos de sauvegarde dans le fichier '%s'.,A '%s' mentésben nem sikerült fellelni a mentésinfókat.,Accesso alle informazioni sul salvataggio in '%s' fallito.,%s' のセーブデータにアクセス出来なかった。,%s'의 저장된 게임 정보에 액세스 할 수 없습니다.,Geen toegang tot de opgeslagen informatie in '%s'.,Kunne ikke få tilgang til savegame-info i '%s'.,Nie udało się dostać informacji zapisu „%s”.,"Não foi possível acessar a informação do jogo salvo em ""%s"".","Não foi possível acessar a informação do jogo gravado em ""%s"".",Nu s-au putut accesa informațiile din salvarea '%s'.,Невозможно получить информацию из сохранения «%s».,Не успешно пристопљено инфу сачуване игре %s.,%s' içindeki kayıt oyunu bilgilerine erişilemedi. -Savegame '%s' is from an incompatible version.,TXT_INCOMPATIBLESG,,,,Uložená hra '%s' je z nekompatibilní verze.,Savegame '%s' er fra en inkompatibel version.,Spielstand '%s' ist von einer inkompatiblen Version.,Το αρχείο αποθήκευσης %s είναι απο μια ασύμβατη έκδοση,Konservita ludo '%s' estas el nekongrua versio.,La partida guardada '%s' es de una versión no compatible.,,Pelitallenne '%s' on yhteensopimattomasta versiosta.,La sauvegarde '%s' vient d'une version incompatible.,A '%s' mentés egy nem kompatibilis verzió mentése.,Il salvataggio '%s' proviene da una versione incompatibile.,%s' は互換性の無いバージョンのセーブデータだ。,저장된 게임'%s'은(는) 호환되지 않는 버전입니다.,Savegame '%s' komt uit een incompatibele versie.,Savegame '%s' er fra en inkompatibel versjon.,Zapis gry „%s” jest z niekompatybilnej wersji.,"O jogo salvo ""%s"" é de uma versão incompatível.","O jogo gravado ""%s"" é de uma versão incompatível.",Salvarea '%s' este dintr-o versiune incompatibilă.,Сохранение «%s» из несовместимой версии порта.,Сачувана игра %s је из инкомпетабилне верзије.,%s' kayıt oyunu uyumsuz bir sürüme ait. -Savegame '%s' is from another ZDoom-based engine:,TXT_OTHERENGINESG,,,,Uložená hra '%s' je z jiného enginu založeného na ZDoomu:,Savegame '%s' er fra en anden ZDoom-baseret engine:,Spielstand '%s' ist von einer anderen ZDoom-basierten Engine:,Το αρχείο αποθήκευσης %s είναι απο μια άλλη ZDoom βασισμένη μηχανή,Konservita ludo '%s' estas el alia ZDoom-bazita modulo:,La partida guardada '%s' es de otro motor basado en ZDoom:,,Pelitallenne '%s' on toisesta ZDoom-pohjaisesta moottorista.,La sauvegarde '%s' vient d'un autre moteur basé sur ZDoom:,A '%s' mentés egy másik ZDoom motorhoz való:,Il salvataggio '%s' proviene da un altro motore basato su ZDoom:,%s' は別のZDoom型のセーブデータだ。,저장된 게임 '%s'은(는) 다른 Z둠 기반 엔진입니다:,Savegame '%s' is van een andere ZDoom-gebaseerde engine:,Savegame '%s' er fra en annen ZDoom-basert engine:,Zapis gry „%s” jest z innego silnika bazowanego na ZDoomie:,"O jogo salvo ""%s"" é de outra engine baseada em ZDoom:","O jogo gravado ""%s"" é de outro motor baseado em ZDoom:",Salvarea '%s' este dintr-un alt motor care are ca bază ZDoom:,"Сохранение «%s» из другого, основанного на ZDoom, движка:",Сачувана игра %s је из други ZDoom-базиран енџин:,%s' kayıt oyunu başka bir ZDoom tabanlı motordan: -Savegame '%s' is from an older version: %d (%e is the oldest supported),TXT_TOOOLDSG,,,,Uložená hra '%s' je ze starší verze: %d (%e je nejstarší podporovaná verze),Savegame '%s' er fra en ældre version: %d (%e er den ældste understøttede version),Spielstand '%s' ist von einer älteren Version: %s (%e ist die älteste noch unterstützte Version,Το αρχείο αποθήκευσης %s είναι απο την %d έκδοση (H %e είναι η παλιότερη υποστηριζώμενη),Konservita ludo '%s' estas el pli malnova versio: %d (%e estas la plej malnova subtenata),La partida guardada '%s' es de una versión anterior: %d (%e es la más anterior soportada),,Pelitallenne '%s' on vanhemmasta versiosta: %d (%e on vanhin tuettu versio),La sauvegarde '%s' vient d'une version obsolète: %d (%e est la plus ancienne supportée.),A '%s' mentés egy túl régi verzióhoz való: %d (%e a legfrissebb támogatott verzió),Il salvataggio '%s' proviene da una versione precedente: %d (%e è la più vecchia supportata),%s' はバージョンが合わないセーブデータだ: %d(%e は旧式版の物),저장된 게임'%s'은(는) 구 버전입니다: %d (%e 이 지원되는 버전 중 가장 오래된 버전),Savegame '%s' is van een oudere versie: %d (%e is de oudste ondersteunde versie).,Savegame '%s' er fra en eldre versjon: %d (%e er den eldste som støttes).,Zapis gry „%s” jest ze starszej wersji: %d (%e jest najstarszą wspieraną),"O jogo salvo ""%s"" é de uma versão mais antiga: %d (%e sendo a mais antiga suportada)","O jogo gravado ""%s"" é de uma versão mais antiga: %d (%e sendo a mais antiga suportada)",Salvarea '%s' este dintr-o versiune mai veche: %d (%e e cea mai veche suportată),Сохранение «%s» из старой версии: %d (%e — последняя совместимая).,Сачувана игра „%s“ је из старије верзије: %d (%e је најстарија подржана),%s' kayıt oyunu daha eski bir sürümden: %d (%e desteklenen en eski sürümdür) -Savegame '%s' is from an newer version: %d (%e is the highest supported),TXT_TOONEWSG,"Shouldn’t this say “%e is the newest supported”? +""info.json"".",%s' nu este o salvare validă. Lipsește 'info.json',Сохранение «%s» некорректно: отсутствует «info.json».,%s није валидно сачувана игра: Недостаје „info.json“.,"%s' är inte ett giltigt sparspel: Saknar ""info.json"".",%s' geçerli bir kayıt oyunu değil: Eksik 'info.json'. +Failed to access savegame info in '%s'.,TXT_FAILEDTOREADSG,,,,Nepodařilo se načíst informace v uložené hře '%s'.,Det lykkedes ikke at få adgang til savegame info i '%s'.,Konnte Spielstandinfo in '%s' nicht lesen.,Η πρόσβαση πληροφοριών του αρχείου αποθήκευσης %s δέν ήταν επιτυχής,Malsukcesis aliri informon de la konservita ludo en '%s'.,Fallo al acceder a información de partida guardada en '%s'.,,Tiedoston '%s' pelitallennetietoihin ei päästy käsiksi.,Impossible d'accéder aux infos de sauvegarde dans le fichier '%s'.,A '%s' mentésben nem sikerült fellelni a mentésinfókat.,Accesso alle informazioni sul salvataggio in '%s' fallito.,%s' のセーブデータにアクセス出来なかった。,%s'의 저장된 게임 정보에 액세스 할 수 없습니다.,Geen toegang tot de opgeslagen informatie in '%s'.,Kunne ikke få tilgang til savegame-info i '%s'.,Nie udało się dostać informacji zapisu „%s”.,"Não foi possível acessar a informação do jogo salvo em ""%s"".","Não foi possível acessar a informação do jogo gravado em ""%s"".",Nu s-au putut accesa informațiile din salvarea '%s'.,Невозможно получить информацию из сохранения «%s».,Не успешно пристопљено инфу сачуване игре %s.,"Misslyckades med att få tillgång till information om sparspelet i ""%s"".",%s' içindeki kayıt oyunu bilgilerine erişilemedi. +Savegame '%s' is from an incompatible version.,TXT_INCOMPATIBLESG,,,,Uložená hra '%s' je z nekompatibilní verze.,Savegame '%s' er fra en inkompatibel version.,Spielstand '%s' ist von einer inkompatiblen Version.,Το αρχείο αποθήκευσης %s είναι απο μια ασύμβατη έκδοση,Konservita ludo '%s' estas el nekongrua versio.,La partida guardada '%s' es de una versión no compatible.,,Pelitallenne '%s' on yhteensopimattomasta versiosta.,La sauvegarde '%s' vient d'une version incompatible.,A '%s' mentés egy nem kompatibilis verzió mentése.,Il salvataggio '%s' proviene da una versione incompatibile.,%s' は互換性の無いバージョンのセーブデータだ。,저장된 게임'%s'은(는) 호환되지 않는 버전입니다.,Savegame '%s' komt uit een incompatibele versie.,Savegame '%s' er fra en inkompatibel versjon.,Zapis gry „%s” jest z niekompatybilnej wersji.,"O jogo salvo ""%s"" é de uma versão incompatível.","O jogo gravado ""%s"" é de uma versão incompatível.",Salvarea '%s' este dintr-o versiune incompatibilă.,Сохранение «%s» из несовместимой версии порта.,Сачувана игра %s је из инкомпетабилне верзије.,"Sparfil ""%s"" är från en inkompatibel version.",%s' kayıt oyunu uyumsuz bir sürüme ait. +Savegame '%s' is from another ZDoom-based engine:,TXT_OTHERENGINESG,,,,Uložená hra '%s' je z jiného enginu založeného na ZDoomu:,Savegame '%s' er fra en anden ZDoom-baseret engine:,Spielstand '%s' ist von einer anderen ZDoom-basierten Engine:,Το αρχείο αποθήκευσης %s είναι απο μια άλλη ZDoom βασισμένη μηχανή,Konservita ludo '%s' estas el alia ZDoom-bazita modulo:,La partida guardada '%s' es de otro motor basado en ZDoom:,,Pelitallenne '%s' on toisesta ZDoom-pohjaisesta moottorista.,La sauvegarde '%s' vient d'un autre moteur basé sur ZDoom:,A '%s' mentés egy másik ZDoom motorhoz való:,Il salvataggio '%s' proviene da un altro motore basato su ZDoom:,%s' は別のZDoom型のセーブデータだ。,저장된 게임 '%s'은(는) 다른 Z둠 기반 엔진입니다:,Savegame '%s' is van een andere ZDoom-gebaseerde engine:,Savegame '%s' er fra en annen ZDoom-basert engine:,Zapis gry „%s” jest z innego silnika bazowanego na ZDoomie:,"O jogo salvo ""%s"" é de outra engine baseada em ZDoom:","O jogo gravado ""%s"" é de outro motor baseado em ZDoom:",Salvarea '%s' este dintr-un alt motor care are ca bază ZDoom:,"Сохранение «%s» из другого, основанного на ZDoom, движка:",Сачувана игра %s је из други ZDoom-базиран енџин:,"Sparfil ""%s"" är från en annan ZDoom-baserad motor:",%s' kayıt oyunu başka bir ZDoom tabanlı motordan: +Savegame '%s' is from an older version: %d (%e is the oldest supported),TXT_TOOOLDSG,,,,Uložená hra '%s' je ze starší verze: %d (%e je nejstarší podporovaná verze),Savegame '%s' er fra en ældre version: %d (%e er den ældste understøttede version),Spielstand '%s' ist von einer älteren Version: %s (%e ist die älteste noch unterstützte Version,Το αρχείο αποθήκευσης %s είναι απο την %d έκδοση (H %e είναι η παλιότερη υποστηριζώμενη),Konservita ludo '%s' estas el pli malnova versio: %d (%e estas la plej malnova subtenata),La partida guardada '%s' es de una versión anterior: %d (%e es la más anterior soportada),,Pelitallenne '%s' on vanhemmasta versiosta: %d (%e on vanhin tuettu versio),La sauvegarde '%s' vient d'une version obsolète: %d (%e est la plus ancienne supportée.),A '%s' mentés egy túl régi verzióhoz való: %d (%e a legfrissebb támogatott verzió),Il salvataggio '%s' proviene da una versione precedente: %d (%e è la più vecchia supportata),%s' はバージョンが合わないセーブデータだ: %d(%e は旧式版の物),저장된 게임'%s'은(는) 구 버전입니다: %d (%e 이 지원되는 버전 중 가장 오래된 버전),Savegame '%s' is van een oudere versie: %d (%e is de oudste ondersteunde versie).,Savegame '%s' er fra en eldre versjon: %d (%e er den eldste som støttes).,Zapis gry „%s” jest ze starszej wersji: %d (%e jest najstarszą wspieraną),"O jogo salvo ""%s"" é de uma versão mais antiga: %d (%e sendo a mais antiga suportada)","O jogo gravado ""%s"" é de uma versão mais antiga: %d (%e sendo a mais antiga suportada)",Salvarea '%s' este dintr-o versiune mai veche: %d (%e e cea mai veche suportată),Сохранение «%s» из старой версии: %d (%e — последняя совместимая).,Сачувана игра „%s“ је из старије верзије: %d (%e је најстарија подржана),"Sparfil ""%s"" är från en äldre version: %d (%e är den äldsta versionen som stöds).",%s' kayıt oyunu daha eski bir sürümden: %d (%e desteklenen en eski sürümdür) +Savegame '%s' is from a newer version: %d (%e is the highest supported),TXT_TOONEWSG,"Shouldn’t this say “%e is the newest supported”? — Undead -Ask Randi: The text is old. I won't change it.",,,Uložená hra '%s' je z novější verze: %d (%e je nejvyšší podporovaná verze),Savegame '%s' er fra en nyere version: %d (%e er den højest understøttede),Spielstand '%s' ist von einer neueren Version: %s (%e ist die neueste noch unterstützte Version,Το αρχείο αποθήκευσης %s είναι απο μια πιο καινούρια έκδοση: %d (Η %e είναι η πιο καινούρια που υποστηρίζεται),Konservita ludo '%s' estas el pli nova versio: %d (%e estas la plej nova subtenata),La partida guardada '%s' es de una versión posterior: %d (%e es la más alta soportada),,Pelitallenne '%s' on uudemmasta versiosta: %d (%e on korkein tuettu versio),La sauvegarde '%s' vient d'une version plus récente: %d (%e est la plus récente supportée.),A '%s' mentés egy túl új verzióhoz való: %d (%e a legkorábbi támogatott verzió),Il salvataggio '%s' proviene da una versione recente: %d (%e è la più recente supportata),%s' はバージョンが合わないセーブデータだ: %d(%e は最新版の物),저장된 게임'%s'은(는) 새 버전입니다: %d (%e 이 지원되는 버전 중 가장 최근 버전),Savegame '%s' is van een nieuwere versie: %d (%e is de hoogst ondersteunde versie).,Savegame '%s' er fra en nyere versjon: %d (%e er den høyeste versjonen som støttes).,Zapis gry „%s” jest z nowszej wersji: %d (%e jest najwyższą wspieraną),"O jogo salvo ""%s"" é de uma versão mais nova: %d (%e sendo a mais recente suportada)","O jogo gravado ""%s"" é de uma versão mais nova: %d (%e sendo a mais recente suportada)",Salvarea '%s' e dintr-o versiune mai nouă: %d (%e este cea mai nouă suportată),Сохранение «%s» из новой версии: %d (%e — последняя совместимая).,Сачувана игра „%s“ је из новије верзије: %d (%e је најновија подржана),%s' kayıt oyunu daha yeni bir sürümden: %d (%e desteklenen en yüksek sürümdür) -Savegame '%s' is missing the current map.,TXT_NOMAPSG,,,,Uložená hra '%s' neobsahuje současný level.,Savegame '%s' mangler det aktuelle kort.,Spielstand '%s' hat keine Information über den alktuellen Level.,Το αρχείο αποθήκευσης %s δέν έχει την τωρινή πίστα,Al la konservita ludo '%s' mankas la nuna mapo.,La partida guardada '%s' carece del mapa actual.,,Pelitallenteesta '%s' puuttuu nykyinen taso.,La sauvegarde '%s' ne contient pas la carte actuelle.,A '%s' mentés hiányolja a jelenlegi pályát.,Il salvataggio '%s' non contiene la mappa corrente.,セーブデータ '%s'に現在のマップはない。,저장된 게임 '%s'에 현재 맵이 없습니다.,Savegame '%s' mist de huidige kaart.,Savegame '%s' mangler det gjeldende kartet.,W zapisie gry „%s” brakuje obecnej mapy.,"O jogo salvo ""%s"" não possui o mapa atual.","O jogo gravado ""%s"" não possui o mapa atual.",Salvării '%s' îi lipsește harta actuală.,В сохранении «%s» отсутствует текущая карта.,Сачувана игри „%s“ недостаје тренутна мапа.,%s' kayıt oyununda geçerli harita eksik. +Ask Randi: The text is old. I won't change it.",,,Uložená hra '%s' je z novější verze: %d (%e je nejvyšší podporovaná verze),Savegame '%s' er fra en nyere version: %d (%e er den højest understøttede),Spielstand '%s' ist von einer neueren Version: %s (%e ist die neueste noch unterstützte Version,Το αρχείο αποθήκευσης %s είναι απο μια πιο καινούρια έκδοση: %d (Η %e είναι η πιο καινούρια που υποστηρίζεται),Konservita ludo '%s' estas el pli nova versio: %d (%e estas la plej nova subtenata),La partida guardada '%s' es de una versión posterior: %d (%e es la más alta soportada),,Pelitallenne '%s' on uudemmasta versiosta: %d (%e on korkein tuettu versio),La sauvegarde '%s' vient d'une version plus récente: %d (%e est la plus récente supportée.),A '%s' mentés egy túl új verzióhoz való: %d (%e a legkorábbi támogatott verzió),Il salvataggio '%s' proviene da una versione recente: %d (%e è la più recente supportata),%s' はバージョンが合わないセーブデータだ: %d(%e は最新版の物),저장된 게임'%s'은(는) 새 버전입니다: %d (%e 이 지원되는 버전 중 가장 최근 버전),Savegame '%s' is van een nieuwere versie: %d (%e is de hoogst ondersteunde versie).,Savegame '%s' er fra en nyere versjon: %d (%e er den høyeste versjonen som støttes).,Zapis gry „%s” jest z nowszej wersji: %d (%e jest najwyższą wspieraną),"O jogo salvo ""%s"" é de uma versão mais nova: %d (%e sendo a mais recente suportada)","O jogo gravado ""%s"" é de uma versão mais nova: %d (%e sendo a mais recente suportada)",Salvarea '%s' e dintr-o versiune mai nouă: %d (%e este cea mai nouă suportată),Сохранение «%s» из новой версии: %d (%e — последняя совместимая).,Сачувана игра „%s“ је из новије верзије: %d (%e је најновија подржана),"Sparfil ""%s"" är från en nyare version: %d (%e är den högsta versionen som stöds).",%s' kayıt oyunu daha yeni bir sürümden: %d (%e desteklenen en yüksek sürümdür) +Savegame '%s' is missing the current map.,TXT_NOMAPSG,,,,Uložená hra '%s' neobsahuje současný level.,Savegame '%s' mangler det aktuelle kort.,Spielstand '%s' hat keine Information über den alktuellen Level.,Το αρχείο αποθήκευσης %s δέν έχει την τωρινή πίστα,Al la konservita ludo '%s' mankas la nuna mapo.,La partida guardada '%s' carece del mapa actual.,,Pelitallenteesta '%s' puuttuu nykyinen taso.,La sauvegarde '%s' ne contient pas la carte actuelle.,A '%s' mentés hiányolja a jelenlegi pályát.,Il salvataggio '%s' non contiene la mappa corrente.,セーブデータ '%s'に現在のマップはない。,저장된 게임 '%s'에 현재 맵이 없습니다.,Savegame '%s' mist de huidige kaart.,Savegame '%s' mangler det gjeldende kartet.,W zapisie gry „%s” brakuje obecnej mapy.,"O jogo salvo ""%s"" não possui o mapa atual.","O jogo gravado ""%s"" não possui o mapa atual.",Salvării '%s' îi lipsește harta actuală.,В сохранении «%s» отсутствует текущая карта.,Сачувана игри „%s“ недостаје тренутна мапа.,"Sparfil ""%s"" saknar den aktuella kartan.",%s' kayıt oyununda geçerli harita eksik. %s' is not a valid savegame: Missing 'globals.json'.,TXT_NOGLOBALSJSON,,,,%s' není funkční uloženou hrou: Chybí 'globals.json'.,%s' er ikke et gyldigt savegame: Mangler 'globals.json'.,%s' ist kein gültiger Spielstand. 'globals.json' fehlt.,Το %s δεν είναι ένα έγκυρο αρχείο αποθήκευσης: Το globals.json λείπει,%s' ne estas valida konservita ludo: Mankante 'globals.json'.,%s' no es una partida guardada válida: Falta 'globals.json'.,,%s' ei ole kelvollinen pelitallenne. Puuttuva 'globals.json'.,%s n'est pas une sauvegarde valide. Fichier 'global.json' manquant.,A '%s' nem valós mentés: Hiányzó 'globals.json'.,%s' non è un salvataggio valido: 'globals.json' mancante.,%s' は有効なセーブデータではない: 'globals.json'が不明。,%s' 는 유효하지 않습니다: 파일이 없습니다.'globals.json',%s' is geen geldig savegame: Ontbrekende 'globals.json'.,%s' er ikke et gyldig lagringsspill: Mangler 'globals.json'.,„%s” nie jest prawidłowym zapisem gry: Brak „globals.json”,"""%s"" não é um jogo salvo válido: Está faltando ""globals.json"".","""%s"" não é um jogo gravado válido: Está faltando -""globals.json"".",%s nu este o salvare validă. Lipsește 'globals.json'.,Сохранение «%s» некорректно: отсутствует «globals.json».,%s није валидно сачувана игра: Недостаје „globals.json“.,%s' geçerli bir kayıt oyunu değil: Eksik 'globals.json'. -Failed to access savegame info in '%s',TXT_SGINFOERR,,,,Nepodařilo se načíst informace v uložené hře '%s'.,Fejlslagen adgang til savegame info i '%s',Konnte Spielstandinformationen von '%s' nicht lesen.,Η πρόσβαση πληροφοριών του αρχείου αποθήκευσης %s δέν ήταν επιτυχής,Malsukcesis aliri informon de la konservita ludo en '%s',Fallo al acceder a información de partida guardada en '%s'.,,Tiedoston '%s' pelitallennetietoihin ei päästy käsiksi.,Impossible d'accéder aux infos de sauvegarde dans le fichier '%s'.,A '%s' -ban nem található mentési információ.,Accesso alle informazioni sul salvataggio in '%s' fallito,%s' のセーブデータにアクセス出来なかった,%s'의 저장된 게임 정보에 액세스 할 수 없습니다.,Geen toegang tot savegame info in '%s'.,Kunne ikke få tilgang til lagringsinformasjon i '%s'.,Nie udało się dostać informacji zapisu „%s”.,"Não foi possível acessar a informação do jogo salvo em ""%s"".","Não foi possível acessar a informação do jogo gravado em ""%s"".",Informațiile salvării '%s' nu au putut fi accesate,Невозможно получить информацию из сохранения «%s».,Не успешно приступљено саучуваној игри у %s,%s' içindeki savegame bilgisine erişilemedi -A game save is still pending.,TXT_SAVEPENDING,,,,Stále se čeká na uložení hry.,Et spilopbevaringsspil venter stadig på at blive gemt.,Das Speichern eines Spielstandes steht noch aus.,Μια αποθήκευση παιχνιδίου είναι ακόμα σε αναμονή,Konservita ludo ankoraŭ estas pritraktata.,Un guardado de partida aún está pendiente.,,Pelin tallennus on vielä kesken.,Une sauvegarde est déjà en cours.,A mentés folyamatban.,Un salvataggio di gioco è ancora in corso.,セーブ中だ,게임 저장이 아직 보류 중입니다.,Een spel opslaan is nog steeds in behandeling.,En spilloppdatering venter fortsatt.,Zapis gry jest wciąż w toku.,Jogo salvo ainda pendente.,Jogo gravado ainda pendente.,O salvare este încă în așteptare.,Сохранение в очереди.,Сачувана игра идаље чека,Bir oyun kaydı hala beklemede. -Not in a saveable game.,TXT_NOTSAVEABLE,,,,Nejsi v uložitelné hře.,"Ikke i et spil, der kan gemmes.",Kein speicherbares Spiel aktiv.,Δέν είσαι σε ένα παιχνίδει που μπορεί να αποθηκευτεί,Ne estas en konservebla ludo.,No en una partida guardable.,,Ei tallennettavassa pelissä.,Vous n'êtes pas dans une partie sauvegardable.,Nem menthető játék.,Non è in un gioco salvabile.,セーブ可能なゲームではない,저장 가능한 게임에선 불가능 합니다.,Geen opslagbaar spel actief.,Ikke i et spill som kan lagres.,Nie w grze do zapisywania.,Não está em uma partida salvável.,Não estás numa partida que possa ser gravada.,Nu ești într-un joc în care poți salva.,Не в сохранимой игре.,Није у сачувајућој игри,Kaydedilebilir bir oyunda değil. -Not in a level,TXT_NOTINLEVEL,,,,Nejsi v levelu.,Ikke i en kort,Nicht in einem Level.,Δέν ε'ισαι σε μια πίστα,Ne estas en nivelo,No en un nivel,,Ei tasossa,Vous n'êtes pas dans un niveau.,Nem menthető pályán van.,Non è in un livello,レベル内ではない,레벨 안에선 불가능 합니다.,Niet in een level,Ikke i et nivå,Nie w poziomie.,Não está em uma fase.,Não estás em nenhum nível.,Nu ești în niciun nivel,Не на уровне,Није у нивоу,Bir seviyede değil -Player is dead in a single-player game,TXT_SPPLAYERDEAD,,,,Hráč je mrtvý v singleplayer hře.,Spilleren er død i et single-player spil,Spieler ist tot in einem Einzelspieler-Spiel.,Ο παίχτης έιναι νεκρός σε ένα singleplayer παιχνίδι,Ludanto estas mortinta en sol-ludanta ludado,Jugador muerto en partida de un solo jugador,,Pelaaja on kuollut yksinpelissä,Le joueur est mort en mode solo.,Játékos meghalt egy egyjátékos módban.,Il giocatore è morto in un gioco single player,シングルプレイでプレイヤーが死んだ,플레이어가 싱글 플레이 게임에서 죽었습니다.,Speler is dood in een een-speler spel,Spilleren er død i et enspiller-spill,Gracz jest martwy w grze dla jednego gracza,Jogador está morto em partida single player.,Jogador está morto numa partida single player.,Jucătorul este mort într-un joc single-player,Игрок мёртв в одиночной игре,Играч је мртав у сингл-плејер игри,Oyuncu tek oyunculu bir oyunda öldü -Save failed,TXT_SAVEFAILED,,,,Uložení se nezdařilo.,Save mislykkedes,Speichern fehlgeschlagen.,Η αποθήκευση απέτυχε,Konservo malsukcesis,Guardado fallido,,Tallennus epäonnistui,La sauvegarde à échoué.,Mentés meghiusult,Salvataggio fallito,セーブに失敗した。,저장 실패,Opslaan mislukt,Lagring mislyktes,Nie udało się zapisać,Falha ao salvar,Falha ao gravar,Salvare eșuată,Ошибка сохранения игры,Сачување није успело,Kaydetme başarısız -Could not create screenshot.,TXT_SCREENSHOTERR,,,,Nepodařilo se pořídit snímek obrazovky.,Kunne ikke oprette et skærmbillede.,Konnte Screenshot nicht erzeugen.,Ένα screenshot δέν μπόρεσε να τραβυχτεί,Ne povis krei ekrankopion.,No se pudo crear captura de pantalla.,,Ei voitu ottaa kuvakaappausta.,La capture d'écran à échoué.,Képernyőmentés meghiusult,Non è stato possibile effettuare la cattura dello schermo.,スクリーンショットを作成できなかった。,스크린샷을 만들 수 없음.,Kon geen screenshot maken.,Kunne ikke opprette skjermbilde.,Nie można zrobić zrzutu ekranu.,Não foi possível capturar a tela.,Não foi possível capturar ecrã,Captura de ecran nu a putut fi creată.,Ошибка создания снимка экрана.,Није успело направити снимак екрана.,Ekran görüntüsü oluşturulamadı. +""globals.json"".",%s nu este o salvare validă. Lipsește 'globals.json'.,Сохранение «%s» некорректно: отсутствует «globals.json».,%s није валидно сачувана игра: Недостаје „globals.json“.,"%s"" är inte ett giltigt sparfil: Saknar ""globals.json"".",%s' geçerli bir kayıt oyunu değil: Eksik 'globals.json'. +Failed to access savegame info in '%s',TXT_SGINFOERR,,,,Nepodařilo se načíst informace v uložené hře '%s'.,Fejlslagen adgang til savegame info i '%s',Konnte Spielstandinformationen von '%s' nicht lesen.,Η πρόσβαση πληροφοριών του αρχείου αποθήκευσης %s δέν ήταν επιτυχής,Malsukcesis aliri informon de la konservita ludo en '%s',Fallo al acceder a información de partida guardada en '%s'.,,Tiedoston '%s' pelitallennetietoihin ei päästy käsiksi.,Impossible d'accéder aux infos de sauvegarde dans le fichier '%s'.,A '%s' -ban nem található mentési információ.,Accesso alle informazioni sul salvataggio in '%s' fallito,%s' のセーブデータにアクセス出来なかった,%s'의 저장된 게임 정보에 액세스 할 수 없습니다.,Geen toegang tot savegame info in '%s'.,Kunne ikke få tilgang til lagringsinformasjon i '%s'.,Nie udało się dostać informacji zapisu „%s”.,"Não foi possível acessar a informação do jogo salvo em ""%s"".","Não foi possível acessar a informação do jogo gravado em ""%s"".",Informațiile salvării '%s' nu au putut fi accesate,Невозможно получить информацию из сохранения «%s».,Не успешно приступљено саучуваној игри у %s,"Misslyckades med att få tillgång till information om sparfilet i ""%s"".",%s' içindeki savegame bilgisine erişilemedi +A game save is still pending.,TXT_SAVEPENDING,,,,Stále se čeká na uložení hry.,Et spilopbevaringsspil venter stadig på at blive gemt.,Das Speichern eines Spielstandes steht noch aus.,Μια αποθήκευση παιχνιδίου είναι ακόμα σε αναμονή,Konservita ludo ankoraŭ estas pritraktata.,Un guardado de partida aún está pendiente.,,Pelin tallennus on vielä kesken.,Une sauvegarde est déjà en cours.,A mentés folyamatban.,Un salvataggio di gioco è ancora in corso.,セーブ中だ,게임 저장이 아직 보류 중입니다.,Een spel opslaan is nog steeds in behandeling.,En spilloppdatering venter fortsatt.,Zapis gry jest wciąż w toku.,Jogo salvo ainda pendente.,Jogo gravado ainda pendente.,O salvare este încă în așteptare.,Сохранение в очереди.,Сачувана игра идаље чека,Ett sparande av spelet väntar fortfarande.,Bir oyun kaydı hala beklemede. +Not in a saveable game.,TXT_NOTSAVEABLE,,,,Nejsi v uložitelné hře.,"Ikke i et spil, der kan gemmes.",Kein speicherbares Spiel aktiv.,Δέν είσαι σε ένα παιχνίδει που μπορεί να αποθηκευτεί,Ne estas en konservebla ludo.,No en una partida guardable.,,Ei tallennettavassa pelissä.,Vous n'êtes pas dans une partie sauvegardable.,Nem menthető játék.,Non è in un gioco salvabile.,セーブ可能なゲームではない,저장 가능한 게임에선 불가능 합니다.,Geen opslagbaar spel actief.,Ikke i et spill som kan lagres.,Nie w grze do zapisywania.,Não está em uma partida salvável.,Não estás numa partida que possa ser gravada.,Nu ești într-un joc în care poți salva.,Не в сохранимой игре.,Није у сачувајућој игри,Inte i ett spel som kan sparas.,Kaydedilebilir bir oyunda değil. +Not in a level,TXT_NOTINLEVEL,,,,Nejsi v levelu.,Ikke i en kort,Nicht in einem Level.,Δέν ε'ισαι σε μια πίστα,Ne estas en nivelo,No en un nivel,,Ei tasossa,Vous n'êtes pas dans un niveau.,Nem menthető pályán van.,Non è in un livello,レベル内ではない,레벨 안에선 불가능 합니다.,Niet in een level,Ikke i et nivå,Nie w poziomie.,Não está em uma fase.,Não estás em nenhum nível.,Nu ești în niciun nivel,Не на уровне,Није у нивоу,Inte i en nivå.,Bir seviyede değil +Player is dead in a single-player game,TXT_SPPLAYERDEAD,,,,Hráč je mrtvý v singleplayer hře.,Spilleren er død i et single-player spil,Spieler ist tot in einem Einzelspieler-Spiel.,Ο παίχτης έιναι νεκρός σε ένα singleplayer παιχνίδι,Ludanto estas mortinta en sol-ludanta ludado,Jugador muerto en partida de un solo jugador,,Pelaaja on kuollut yksinpelissä,Le joueur est mort en mode solo.,Játékos meghalt egy egyjátékos módban.,Il giocatore è morto in un gioco single player,シングルプレイでプレイヤーが死んだ,플레이어가 싱글 플레이 게임에서 죽었습니다.,Speler is dood in een een-speler spel,Spilleren er død i et enspiller-spill,Gracz jest martwy w grze dla jednego gracza,Jogador está morto em partida single player.,Jogador está morto numa partida single player.,Jucătorul este mort într-un joc single-player,Игрок мёртв в одиночной игре,Играч је мртав у сингл-плејер игри,Spelaren är död i ett enspelarspel.,Oyuncu tek oyunculu bir oyunda öldü +Save failed,TXT_SAVEFAILED,,,,Uložení se nezdařilo.,Save mislykkedes,Speichern fehlgeschlagen.,Η αποθήκευση απέτυχε,Konservo malsukcesis,Guardado fallido,,Tallennus epäonnistui,La sauvegarde à échoué.,Mentés meghiusult,Salvataggio fallito,セーブに失敗した。,저장 실패,Opslaan mislukt,Lagring mislyktes,Nie udało się zapisać,Falha ao salvar,Falha ao gravar,Salvare eșuată,Ошибка сохранения игры,Сачување није успело,Spara misslyckades.,Kaydetme başarısız +Could not create screenshot.,TXT_SCREENSHOTERR,,,,Nepodařilo se pořídit snímek obrazovky.,Kunne ikke oprette et skærmbillede.,Konnte Screenshot nicht erzeugen.,Ένα screenshot δέν μπόρεσε να τραβυχτεί,Ne povis krei ekrankopion.,No se pudo crear captura de pantalla.,,Ei voitu ottaa kuvakaappausta.,La capture d'écran à échoué.,Képernyőmentés meghiusult,Non è stato possibile effettuare la cattura dello schermo.,スクリーンショットを作成できなかった。,스크린샷을 만들 수 없음.,Kon geen screenshot maken.,Kunne ikke opprette skjermbilde.,Nie można zrobić zrzutu ekranu.,Não foi possível capturar a tela.,Não foi possível capturar ecrã,Captura de ecran nu a putut fi creată.,Ошибка создания снимка экрана.,Није успело направити снимак екрана.,Kunde inte skapa en skärmdump.,Ekran görüntüsü oluşturulamadı. By %s,TXT_BY,As in paused by player %s.,,,hráčem %s,Af %s,Von %s,Απο @[pro_gr] %s,De %s,Por %s,,Pelaajan %s toimesta,Par %s,%s által,Da %s,"%s より -",%s 에 의해,Met %s,Etter %s,Przez %s,Por %s,,De către %s,игроком %s,играчем %s,Tarafından %s -Press any key or click anywhere in the window to quit.,TXT_QUITENDOOM,,,,"Pro ukončení stiskni libovolnou klávesu, nebo klikni kdekoliv v okně.",Tryk på en vilkårlig tast eller klik et vilkårligt sted i vinduet for at afslutte.,Drücke eine Taste oder klicke mit der Maus ins Fenster zum Beenden.,Πάτα οποιοδήποτε πλήκτρο ή πάτα οπουδήποτε για να κάνεις έξοδο,Premu ajnan klavon aŭ alklaku ie ajn en la fenestro por forlasi.,Presiona una tecla o haz click en cualquier lugar de la ventana para salir.,,Paina mitä tahansa näppäintä tai napsauta minne tahansa ikkunaa lopettaaksesi.,Appuyez sur une touche ou cliquez pour quitter.,Nyomjon egy billentyűt vagy kattintson bárhova a kilépéshez.,Premi un qualunque tasto o fai un click ovunque nella finestra per uscire.,何かのキーを押すか、ウィンドウのどこかをクリックすると終了する。,아무 키를 누르거나 아무 곳이나 클릭하면 종료됩니다.,Druk op een willekeurige toets of klik ergens in het venster om te stoppen.,Trykk på en hvilken som helst tast eller klikk hvor som helst i vinduet for å avslutte.,Wciśnij dowolny klawisz lub gdziekolwiek kliknij myszką aby wyjść.,Aperte qualquer tecla ou clique em qualquer lugar na janela para sair.,Carrega numa tecla ou clique em qualquer lugar na janela para sair.,Apasă orice tastă sau dă click oriunde în fereastră pentru a ieși.,"Нажмите любую клавишу или нажмите по окну, чтобы выйти.",Притисните било који тастер или кликните било где на екрану да одустанете.,Çıkmak için herhangi bir tuşa basın veya pencerede herhangi bir yere tıklayın. -Screen Blend Options,HUDMNU_FLASH,,,,Barvení obrazovky,Indstillinger for skærmblanding,Überblendoptionen,Ρυθμίσεις Ανάμειξης Οθόνης,Ekranmisko-Agordoj,Opciones de tintado de pantalla,,Näytön sekoitusasetukset,Options de blending écran,Képernyő Keverés Beállítások,Opzioni Blending dello Schermo,スクリーンブレンド オプション,화면 조합 설정,Opties voor schermmengsel,Alternativer for skjermblanding,Opcje scalania ekranu,Opções de mescla de tela,Opções de mistura de ecrã,Setări Amestec Imagine,Настройки смешивания экрана,Подешавања блед екрана,Ekran Karışım Seçenekleri -3D mode,GLMNU_3DMODE,,,,3D režim,3D-tilstand,3D Modus,3D λειτουργία,3D-reĝimo,Modo 3D,,3D-tila,Mode 3D,3D mód,Modalità 3D,3Dモード,3D 모드 적용,3D-modus,3D-modus,Tryb 3D,Modo 3D,,Mod 3D,Режим 3D,3D режим,3D modu -Crosshair,HUDMNU_CROSSHAIRON,,,,Zaměřovač,Trådkors,Fadenkreuz,Crosshair,Reteto,Retícula,,Tähtäin,Viseur,Célkereszt,Mirino,クロスヘア,조준점,Draadkruis,Trådkors,Celownik,Mira,,Țintă,Прицел,Нишан,Crosshair -Subtitles,MSGMNU_SUBTITLES,,,,Titulky,Undertekster,Untertitel,Υπότιτλοι,Subtekstoj,Subtítulos,,Tekstitys,Sous-titres,Feliratok,Sottotitoli,サブタイトル,자막,Ondertitels,Undertekster,Napisy,Legendas,,Subtitrări,Субтитры,Титлови,Altyazılar -Prevent gray shadows,GLPREFMNU_PALTONENOGREY,,,Prevent grey shadows,Předejít šedým stínům,Forebyg grå skygger,Vermeide graue Schatten,Απότρεξη γρί σκιών,Preventi grizajn ombrojn,Prevenir sombras grises,,Estä harmaat varjot,Eviter les ombres grises,Szürke árnyákok megakadályozása,Prevenire le ombre grigie,グレイシャドウを防ぐ,회색 그림자 없에기,Voorkom grijze schaduwen,Forhindre grå skygger,Zapobiegaj szarym cieniom,Prevenir sombras cinzentas,,Prevenire umbre gri,Убрать серые тени,Онемогући сиве сенке,Gri gölgeleri önleyin -Font Options,HUDMNU_FONTOPTIONS,,,,Písma,Indstillinger for skrifttyper,Zeichensatzoptionen,Ρυθμίσεις Γραμματοσειρών,Tiparo-Agordoj,Opciones de fuentes,,Fonttiasetukset,Options de police,Betű Beállítások,Opzioni per il tipo di carattere,フォント オプション,폰트 설정,Lettertype opties,Alternativer for skrifttype,Opcje czcionek,Opções de Fonte,,Setări Font,Настройки шрифта,Подешавања фонта,Yazı Tipi Seçenekleri -Use standard font for log display,FONTMNU_LOG,,,,Použít standardní font pro záznamy,Brug standardskrifttype til visning af logfiler,Benutze Standardzeichensatz für das Log,Χρησιμοποίηση πρότυπης γραμματοσειράς για προβολή ημερολόγιου,Uzi norman tiparon por protokola ekrano,Usar la fuente estándar para logs,,Käytä oletusfonttia lokinäytölle,Police standard pour affichage du log,Szabvány betűstílus használata a logokhoz,Usa il tipo di carattere di default per la visualizzazione dei messaggi di log,ログ表示に標準フォントを使用,로그 표시에서 기본 폰트 사용,Gebruik het standaardlettertype voor de weergave van logboekberichten,Bruk standard skrifttype for loggvisning,Użyj standardowej czcionki do wyświetlania dziennika,Usar fonte padrão para exibição de log,,Utilizează fontul standard pentru mesajele de tip log,Использовать стандартный шрифт для журнала,Користи стандардни фонт за приказ лога,Günlük ekranı için standart yazı tipi kullanın -Use standard font for dialogues,FONTMNU_DLG,,,,Použít standardní font pro dialogy,Brug standardskrifttype til dialoger,Benutze Standardzeichensatz für Dialoge,Χρησιμοποίηση πρότυπης γραμματοσειράς,Uzi norman tiparon por dialogoj,Usar la fuente estándar para diálogos,,Käytä oletusfonttia keskustelulle,Police standard pour dialogues,Szabvány betűstílus használata a dialógusokhoz,Usa il tipo di carattere di default per la visualizzazione dei dialoghi,ダイアログに標準フォントを使用,대화에서 기본 폰트 사용,Gebruik het standaardlettertype voor dialoogweergave,Bruk standard skrifttype for dialoger,Użyj standardowej czcionki do dialogów,Usar fonte padrão para diálogos,,Utiliează fontul standard pentru căsuțele de dialog,Использовать стандартный шрифт для диалогов,Користи стандардни фонт за дијалоге,Diyaloglar için standart yazı tipi kullanın +",%s 에 의해,Met %s,Etter %s,Przez %s,Por %s,,De către %s,игроком %s,играчем %s,Av %s,Tarafından %s +Press any key or click anywhere in the window to quit.,TXT_QUITENDOOM,,,,"Pro ukončení stiskni libovolnou klávesu, nebo klikni kdekoliv v okně.",Tryk på en vilkårlig tast eller klik et vilkårligt sted i vinduet for at afslutte.,Drücke eine Taste oder klicke mit der Maus ins Fenster zum Beenden.,Πάτα οποιοδήποτε πλήκτρο ή πάτα οπουδήποτε για να κάνεις έξοδο,Premu ajnan klavon aŭ alklaku ie ajn en la fenestro por forlasi.,Presiona una tecla o haz click en cualquier lugar de la ventana para salir.,,Paina mitä tahansa näppäintä tai napsauta minne tahansa ikkunaa lopettaaksesi.,Appuyez sur une touche ou cliquez pour quitter.,Nyomjon egy billentyűt vagy kattintson bárhova a kilépéshez.,Premi un qualunque tasto o fai un click ovunque nella finestra per uscire.,何かのキーを押すか、ウィンドウのどこかをクリックすると終了する。,아무 키를 누르거나 아무 곳이나 클릭하면 종료됩니다.,Druk op een willekeurige toets of klik ergens in het venster om te stoppen.,Trykk på en hvilken som helst tast eller klikk hvor som helst i vinduet for å avslutte.,Wciśnij dowolny klawisz lub gdziekolwiek kliknij myszką aby wyjść.,Aperte qualquer tecla ou clique em qualquer lugar na janela para sair.,Carrega numa tecla ou clique em qualquer lugar na janela para sair.,Apasă orice tastă sau dă click oriunde în fereastră pentru a ieși.,"Нажмите любую клавишу или нажмите по окну, чтобы выйти.",Притисните било који тастер или кликните било где на екрану да одустанете.,Tryck på någon tangent eller klicka någonstans i fönstret för att avsluta.,Çıkmak için herhangi bir tuşa basın veya pencerede herhangi bir yere tıklayın. +Screen Blend Options,HUDMNU_FLASH,,,,Barvení obrazovky,Indstillinger for skærmblanding,Überblendoptionen,Ρυθμίσεις Ανάμειξης Οθόνης,Ekranmisko-Agordoj,Opciones de tintado de pantalla,,Näytön sekoitusasetukset,Options de blending écran,Képernyő Keverés Beállítások,Opzioni Blending dello Schermo,スクリーンブレンド オプション,화면 조합 설정,Opties voor schermmengsel,Alternativer for skjermblanding,Opcje scalania ekranu,Opções de mescla de tela,Opções de mistura de ecrã,Setări Amestec Imagine,Настройки смешивания экрана,Подешавања блед екрана,Alternativ för skärmblandning,Ekran Karışım Seçenekleri +3D mode,GLMNU_3DMODE,,,,3D režim,3D-tilstand,3D Modus,3D λειτουργία,3D-reĝimo,Modo 3D,,3D-tila,Mode 3D,3D mód,Modalità 3D,3Dモード,3D 모드 적용,3D-modus,3D-modus,Tryb 3D,Modo 3D,,Mod 3D,Режим 3D,3D режим,3D-läge,3D modu +Crosshair,HUDMNU_CROSSHAIRON,,,,Zaměřovač,Trådkors,Fadenkreuz,,Reteto,Retícula,,Tähtäin,Viseur,Célkereszt,Mirino,クロスヘア,조준점,Draadkruis,Trådkors,Celownik,Mira,,Țintă,Прицел,Нишан,Hårkors, +Subtitles,MSGMNU_SUBTITLES,,,,Titulky,Undertekster,Untertitel,Υπότιτλοι,Subtekstoj,Subtítulos,,Tekstitys,Sous-titres,Feliratok,Sottotitoli,サブタイトル,자막,Ondertitels,Undertekster,Napisy,Legendas,,Subtitrări,Субтитры,Титлови,Undertexter,Altyazılar +Prevent gray shadows,GLPREFMNU_PALTONENOGREY,,,Prevent grey shadows,Předejít šedým stínům,Forebyg grå skygger,Vermeide graue Schatten,Απότρεξη γρί σκιών,Preventi grizajn ombrojn,Prevenir sombras grises,,Estä harmaat varjot,Eviter les ombres grises,Szürke árnyákok megakadályozása,Prevenire le ombre grigie,グレイシャドウを防ぐ,회색 그림자 없에기,Voorkom grijze schaduwen,Forhindre grå skygger,Zapobiegaj szarym cieniom,Prevenir sombras cinzentas,,Prevenire umbre gri,Убрать серые тени,Онемогући сиве сенке,Förhindra gråa skuggor,Gri gölgeleri önleyin +Font Options,HUDMNU_FONTOPTIONS,,,,Písma,Indstillinger for skrifttyper,Zeichensatzoptionen,Ρυθμίσεις Γραμματοσειρών,Tiparo-Agordoj,Opciones de fuentes,,Fonttiasetukset,Options de police,Betű Beállítások,Opzioni per il tipo di carattere,フォント オプション,폰트 설정,Lettertype opties,Alternativer for skrifttype,Opcje czcionek,Opções de Fonte,,Setări Font,Настройки шрифта,Подешавања фонта,Typsnittsalternativ,Yazı Tipi Seçenekleri +Use standard font for log display,FONTMNU_LOG,,,,Použít standardní font pro záznamy,Brug standardskrifttype til visning af logfiler,Benutze Standardzeichensatz für das Log,Χρησιμοποίηση πρότυπης γραμματοσειράς για προβολή ημερολόγιου,Uzi norman tiparon por protokola ekrano,Usar la fuente estándar para logs,,Käytä oletusfonttia lokinäytölle,Police standard pour affichage du log,Szabvány betűstílus használata a logokhoz,Usa il tipo di carattere di default per la visualizzazione dei messaggi di log,ログ表示に標準フォントを使用,로그 표시에서 기본 폰트 사용,Gebruik het standaardlettertype voor de weergave van logboekberichten,Bruk standard skrifttype for loggvisning,Użyj standardowej czcionki do wyświetlania dziennika,Usar fonte padrão para exibição de log,,Utilizează fontul standard pentru mesajele de tip log,Использовать стандартный шрифт для журнала,Користи стандардни фонт за приказ лога,Använd standardtypsnitt för loggvisningen,Günlük ekranı için standart yazı tipi kullanın +Use standard font for dialogues,FONTMNU_DLG,,,,Použít standardní font pro dialogy,Brug standardskrifttype til dialoger,Benutze Standardzeichensatz für Dialoge,Χρησιμοποίηση πρότυπης γραμματοσειράς,Uzi norman tiparon por dialogoj,Usar la fuente estándar para diálogos,,Käytä oletusfonttia keskustelulle,Police standard pour dialogues,Szabvány betűstílus használata a dialógusokhoz,Usa il tipo di carattere di default per la visualizzazione dei dialoghi,ダイアログに標準フォントを使用,대화에서 기본 폰트 사용,Gebruik het standaardlettertype voor dialoogweergave,Bruk standard skrifttype for dialoger,Użyj standardowej czcionki do dialogów,Usar fonte padrão para diálogos,,Utiliează fontul standard pentru căsuțele de dialog,Использовать стандартный шрифт для диалогов,Користи стандардни фонт за дијалоге,Använd standardtypsnitt för dialoger,Diyaloglar için standart yazı tipi kullanın Quick Exit,MISCMNU_QUICKEXIT,,,,Rychlé ukončení,Hurtig afslutning,"Schnelles Beenden -",Γρήγορη Έξοδος,Rapida Eliro,Salida Rápida,,Pikapoistuminen,Sortie rapide,Gyors kilépés,Uscita rapida,終了メッセージ無し,빠른 종료,Snel eindigen,Hurtigavslutning,Szybkie wyjście,Saída Rápida,,Ieșire Rapidă,Быстрый выход,Брзи излаз,Hızlı Çıkış -Custom Inverse Map,DSPLYMNU_CUSTOMINVERTMAP,,,,Vlastní inverzní barvení,Brugerdefinerede omvendte farver,Benutzerdefinierte invertierte Farben,Προσαρμοσμένος Ανάποδος Χάρτης,Propra Inversa Mapo,Personalizar Filtro Invertido,,Mukautettu käänteinen kartta,Couleurs inverses personnalisées,Egyéni inverz pálya,Mappa inversa personalizzata,マップ反転色カスタム,사용자 지정 반전 맵,Aangepaste inversiekleuren,Egendefinert omvendt kart,Niestandardowe odwrócone kolory,Personalizar Cores Invertidas,,Personalizare Inverse Map,Настроить цвета при неуязвимости,Прилагођена обрнута мапа,Özel Ters Harita +",Γρήγορη Έξοδος,Rapida Eliro,Salida Rápida,,Pikapoistuminen,Sortie rapide,Gyors kilépés,Uscita rapida,終了メッセージ無し,빠른 종료,Snel eindigen,Hurtigavslutning,Szybkie wyjście,Saída Rápida,,Ieșire Rapidă,Быстрый выход,Брзи излаз,Snabbavslutning,Hızlı Çıkış +Custom Inverse Map,DSPLYMNU_CUSTOMINVERTMAP,,,,Vlastní inverzní barvení,Brugerdefinerede omvendte farver,Benutzerdefinierte invertierte Farben,Προσαρμοσμένος Ανάποδος Χάρτης,Propra Inversa Mapo,Personalizar Filtro Invertido,,Mukautettu käänteinen kartta,Couleurs inverses personnalisées,Egyéni inverz pálya,Mappa inversa personalizzata,マップ反転色カスタム,사용자 지정 반전 맵,Aangepaste inversiekleuren,Egendefinert omvendt kart,Niestandardowe odwrócone kolory,Personalizar Cores Invertidas,,Personalizare Inverse Map,Настроить цвета при неуязвимости,Прилагођена обрнута мапа,Anpassad omvänd karta,Özel Ters Harita "Custom Inverse Color Dark ",DSPLYMNU_CUSTOMINVERTC1,,,Custom Inverse Colour Dark,Vlastní inverzní tmavá barva,Brugerdefineret omvendt farve mørk,Dunkle Farbe für Invertierung,Προσαρμοσμένος Ανάποδο Χρώμα Σκοτεινό,Propra Inversa Koloro Malhela,"Color Oscuro de Filtro Invertido ",,Mukautettu käänteinen tumma väri,Couleur foncée pour l'inversion,Egyéni inverz sötét szín,Colore inverso personalizzato scuro,反転色カスタム 暗,사용자 지정 어두운 반전 색상,Aangepaste donkere inversiekleur,"Egendefinert invers farge mørk -",Ciemny kolor do inwersji,Personalizar Cores Invertidas - Cor escura,,Personalizare Culoare Inverse Map Închisă,Тёмный цвет,Прилагођена инверзна боја тамна,"Özel Ters Renk Koyu +",Ciemny kolor do inwersji,Personalizar Cores Invertidas - Cor escura,,Personalizare Culoare Inverse Map Închisă,Тёмный цвет,Прилагођена инверзна боја тамна,"Anpassad omvänd färg Mörk +","Özel Ters Renk Koyu " Custom Inverse Color Light,DSPLYMNU_CUSTOMINVERTC2,,,Custom Inverse Colour Light,Vlastní inverzní světlá barva,Brugerdefineret omvendt farve lys,Helle Farbe für Invertierung,Προσαρμοσμένος Ανάποδο Χρώμα Φωτεινό,Propra Inversa Koloro Hela,Color Claro de Filtro Invertido,,"Mukautettu käänteinen vaalea väri -",Couleur claire pour l'inversion,Egyéni inverz világos szín,Colore inverso personalizzato chiaro,反転色カスタム 明,사용자 지정 밝은 반전 색상,Aangepaste lichte inversiekleur,Egendefinert invers farge lys,Jasny kolor do inwersji,Personalizar Cores Invertidas - Cor clara,,Personalizare Culoare Inverse Map Deschisă,Светлый цвет,Прилагођено инверзно светло у боји,Özel Ters Renkli Işık -View bob amount when firing,DSPLYMNU_BOBFIRE,,,,Pohupování pohybu při střelbě,Vis bob-beløb ved affyring,Waffenpendeln beim Schießen,,Vidi kvanton de kapo-balanciĝo dum pafado,Balanceo de pantalla al disparar,,Aseen heilumisvoimakkuus ammuttaessa,,Fegyvermozgás lövésnél,Movimento dell'arma quando si spara,攻撃時の視点揺れ値,발사 시 밥 양 보기,Op en neer tijdens schieten,Vis bob-beløp ved avfyring,Częstotliwość bujania się broni przy strzelaniu,Quantidade de balanço ao atirar,,Intensitate mișcare arme în timpul deplasării,Количество тряски экрана при стрельбе,,Ateşleme sırasında bob miktarını görüntüleme -Intermission and Screen Border Classic Scaling,SCALEMNU_SCALECLASSIC,HUD->Scaling Options,,,Klasické škálování text. obrazovek a okrajů obrazovky,Pause og skærmkant Klassisk skalering,Klassische Skalierung von Texthintergrund und Rahmen,,Klasika Skalado de Intermito kaj Ekranbordero,Escalado Clásico de Intermisión y Bordes de Pantalla,,Perinteinen väliruutujen ja ruudunreunusten skaalaus,Mise à l'échelle classique pour bordure écran et intermission,Megszakító és Képszél klasszikus arányosítása,Ridimensionamento classico dell'intermissione e del bordo dello schermo,旧式スケールのクリア結果と画面ボーダー,인터미션 및 화면 테두리 클래식 스케일링,Intermissie en schermrand schalen,Klassisk skalering av pause og skjermkant,Klasyczne skalowanie wstawek i ramek,Escala clássica para tela de intervalo e borda de tela,,Scară bordură antract și ecran,Классические размеры экрана между миссиями и границ экрана,Класично скалирање паузе и ивице екрана,Ara ve Ekran Kenarlığı Klasik Ölçeklendirme -Intermission background,SCALEMNU_INTER,,,,Pozadí textových obrazovek,Intermission baggrund,Texthintergrund,,Fono de intermito,Fondo de intermisión,,Väliruutujen tausta,Fond d'écran intermission,Megszakító háttér,Sottofondi delle intermissioni,クリア結果の背景,인터미션 배경,Intermissieachtergrond,Pause bakgrunn,Tło wstawek,Fundo da tela de intervalo,,Fundal antract,Фон экрана между миссиями,Интермиссион бацкгроунд,Devre arası arka planı -Screen border,SCALEMNU_BORDER,,,,Okraje obrazovky,Skærmbord,Rahmen,,Ekranbordero,Bordes de pantalla,,Ruudunreunus,Bordure d'écran,Kép széle,Bordo dello schermo,画面ボーダー,화면 테두리,Schermrand,Skjermkant,Ramka,Borda de tela,,Bordură ecran,Границы экрана,Граница екрана,Ekran kenarlığı -Scaling factor,SCALEMNU_FACTOR,,,,Měřítko,Skaleringsfaktor,Skalierungsfaktor,,Skalfaktoro,Factor de escalado,,Skaalauskerroin,Facteur de mise à l'échelle,Arányosító faktor,Fattore di scala,スケール倍率,스케일링 계수,Schaalfactor,Skaleringsfaktor,Współczynnik skalowania,Fator de escala,,Factor de scalare,Значение масштабирования,Фактор за скалирање,Ölçekleme faktörü -Aspect ratio,SCALEMNU_RATIO,,,,Poměr stran,Aspektforhold,Seitenverhältnis,,Proporcio,Ratio de aspecto,,Kuvasuhde,,Képarány,Proporzioni,アスペクト比,화면 비율,Beeldverhouding,Bildeforhold,Rozdzielczość,Proporção de tela,,Aspect imagine,Соотношение сторон,Однос ширине и висине,En boy oranı -Build,OPTVAL_BUILD,"as in ""Build engine"". This should not be translated unless there is a translated name for the engine",,,,,,,,,,,,,,,,,,,Build,,,,, -Show Tally Screen On Level Exit,MISCMNU_ALWAYSTALLY,sv_alwaystally,,,Zobrazit výsledky na konci mapy,"Vis resultater, når du forlader kortet",Zeige Ergebnisse beim Verlassen des Levels,,Montri Kalkulekranon Sur Niveleliro,Mostrar pantalla de conteo al salir de nivel,,Näytä pisteruutu tasosta poistuttaessa,Montrer les scores en fin de niveau,Elért pontok mutatása a megszakító képen,Mostra i punteggi alla fine del livello,Exit時にタリー画面を表示,레벨 종료 시 집계 화면 표시,Toon tellingen na eind van het level,Vis Tally-skjerm på nivåutgang,Pokazuj wyniki pod koniec poziomu,Exibir tela de pontuação no fim da fase,,Afișează Totalul la Ieșirea din Nivel,Отображение экрана статистики при выходе с уровня,Прикажи екран за израчунавање на излазу из нивоа,Seviye Çıkışında Çetele Ekranını Göster -Mod Defined,OPTVAL_MODDEFINED,this is '==0',,,Určeno mody,Mod Defineret,Mod-definiert,,Modifo Difinita,Definido por mod,,Modin määrittämä,Défini par Mod,Beállított Mod,Definito dalla mod,Mod定義,모드 정의,Volgens de mod,Mod Definert,Zdefiniowane przez modyfikację,Definir por mod,,Definit de către moduri,Определено модификацией,Мод Дефинед,Mod Tanımlı -"Always, except within hubs",OPTVAL_NOTHUBS,,,,Vždy kromě hubů,"Altid, undtagen i hubs","Immer, außer in Hubs",,"Ĉiam, krom en naboj","Siempre, excepto en hubs",,"Aina, keskustasoja lukuun ottamatta","Toujours, sauf dans les hubs","Mindig, kivétel a csomópontoknál","Sempre, tranne gli hub",区間を除き、常に,"항상, 허브 내 제외","Altijd, behalve binnen hubs","Alltid, unntatt innenfor knutepunkter","Zawsze, oprócz hubów","Sempre, exceto em hubs",,"Mereu, mai puțin în hub-uri",Всегда (кроме групп уровней),"Увек, осим унутар чворишта","Her zaman, hub'lar hariç" -"Always, even within hubs",OPTVAL_WITHHUBS,,,,Vždy včetně hubů,"Altid, også inden for hubs","Immer, auch in Hubs",,"Ĉiam, eĉ en naboj","Siempre, incluso en hubs",,"Aina, keskustasot mukaan lukien","Toujours, même dans les hubs","Mindig, még a csomópontoknál is","Sempre, inclusi gli hub",区間内でも、常に,"항상, 허브 내에서도","Altijd, zelfs binnen hubs","Alltid, også innenfor knutepunkter","Zawsze, nawet w hubach","Sempre, inclusive em hubs",,"Mereu, inclusiv în hub-uri",Всегда (включая группы уровни),"Увек, чак и унутар чворишта","Her zaman, merkezler içinde bile" -Preferred keyboard layout,CNTRLMNU_LAYOUT,,,,Preferované rozložení klávesnice,Foretrukket tastaturlayout,Bevorzugte Tastaturbelegung,,Preferita klavararanĝo,Disposición de teclado preferida,,Lempinäppäinasettelu,Organisation préférée du clavier,Preferált billentyűkiosztás,Layout della tastiera preferito,優先するキー配列,기본 키보드 레이아웃,Voorkeur toetsenbordindeling,Foretrukket tastaturoppsett,Preferowany układ klawiatury,Layout de teclado preferido,,Schemă de control preferată,Раскладка клавиатуры,Жељени распоред тастатуре,Tercih edilen klavye düzeni -Classic ZDoom,OPTVAL_CLASSICZ,,,,Klasický ZDoom,Klassisk ZDoom,ZDoom klassisch,,Klasika ZDoom,ZDoom clásico,,Perinteinen ZDoom,Zdoom Classique,Klasszikus ZDoom,ZDoom Classico,従来のZDOOM,클래식 ZDoom,Klassiek ZDoom,Klassisk ZDoom,Klasyczny ZDoom,ZDoom Clássico,,ZDoom Clasic,Классическая ZDoom,Цлассиц ЗДоом,Klasik ZDoom -Modern (WASD),OPTVAL_MODERN,,,,Moderní (WASD),Moderne (WASD),,,Moderna (WASD),Moderno (WASD),,Nykyaikainen (WASD),Moderne (ZQSD),,Moderno (WASD),現代的(WASD),모던(WASD),,Moderne (WASD),Współczesny (WSAD),Moderno (WASD),,Modernă (WASD),Современная (ЦФЫВ),модерно,Modern (WASD) -Modern (Keypad),OPTVAL_MODERNLEFT,,,,Moderní (číselník),Moderne (Keypad),,,Moderna (Cifera klavaro),Moderno (Teclado Numérico),,Nykyaikainen (numeronäppäimistö),Moderne (Pavé numérique),Modern (numpad),Moderno (tastierino numerico),現代的(Keypad),모던(키패드),Modern (nummeriek toetsenbord),Moderne (Keypad),Współczesny (klawiatura numeryczna),Moderno (Teclado numérico),,Modernă (Tastatură),Современная (цифровой блок),Модерна (тастатура),Modern (Tuş Takımı) -Strict KEYCONF Weapons/Players,MISCMNU_SETSLOTSTRICT,,,,Striktně zbraně/hráči z KEYCONF,Strenge KEYCONF Våben/spillere,Strikte KEYKONF Behandlung für Waffen und Spieler,,Strikta KEYCONF Armiloj/Ludantoj,KEYCONF de Armas/Jugadores estricto,,Pelaajien/Aseiden tiukka KEYCONF,Armes/Joueurs strictement selon KEYCONF,Szigorú KEYCONF a Fegyverek/Játékosok esetében,KEYCONF rigoroso per armi/giocatori,厳密にKEYCONFの武器/プレイヤー,엄격한 키콘프 무기/플레이어,Strikte KEYCONF Wapens/Spelers,Strenge KEYCONF-våpen/spillere,Surowe opcje KEYCONF dla broni/graczy,Armas/Jogadores estritamente de acordo com KEYCONF,,KEYCONF Strictă pentru Arme/Jucători,Строгий KEYCONF для оружия/игроков,Строго KEYKONF оружје/играчи,Sıkı KEYCONF Silahlar/Oyuncular +",Couleur claire pour l'inversion,Egyéni inverz világos szín,Colore inverso personalizzato chiaro,反転色カスタム 明,사용자 지정 밝은 반전 색상,Aangepaste lichte inversiekleur,Egendefinert invers farge lys,Jasny kolor do inwersji,Personalizar Cores Invertidas - Cor clara,,Personalizare Culoare Inverse Map Deschisă,Светлый цвет,Прилагођено инверзно светло у боји,Anpassad omvänd färg ljus,Özel Ters Renkli Işık +View bob amount when firing,DSPLYMNU_BOBFIRE,,,,Pohupování pohledu při střelbě,Vis bob-beløb ved affyring,Waffenpendeln beim Schießen,,Vidi kvanton de kapo-balanciĝo dum pafado,Balanceo de pantalla al disparar,,Aseen heilumisvoimakkuus ammuttaessa,Intensité du chaloupage lors des tirs,Fegyvermozgás lövésnél,Movimento dell'arma quando si spara,攻撃時の視点揺れ値,발사 시 밥 양 보기,Op en neer tijdens schieten,Vis bob-beløp ved avfyring,Częstotliwość bujania się broni przy strzelaniu,Quantidade de balanço ao atirar,,Intensitate mișcare arme în timpul deplasării,Количество тряски экрана при стрельбе,,Visa bob-värde vid skottlossning,Ateşleme sırasında bob miktarını görüntüleme +Intermission and Screen Border Classic Scaling,SCALEMNU_SCALECLASSIC,HUD->Scaling Options,,,Klasické škálování text. obrazovek a okrajů obrazovky,Pause og skærmkant Klassisk skalering,Klassische Skalierung von Texthintergrund und Rahmen,,Klasika Skalado de Intermito kaj Ekranbordero,Escalado Clásico de Intermisión y Bordes de Pantalla,,Perinteinen väliruutujen ja ruudunreunusten skaalaus,Mise à l'échelle classique pour bordure écran et intermission,Megszakító és Képszél klasszikus arányosítása,Ridimensionamento classico dell'intermissione e del bordo dello schermo,旧式スケールのクリア結果と画面ボーダー,인터미션 및 화면 테두리 클래식 스케일링,Intermissie en schermrand schalen,Klassisk skalering av pause og skjermkant,Klasyczne skalowanie wstawek i ramek,Escala clássica para tela de intervalo e borda de tela,,Scară bordură antract și ecran,Классические размеры экрана между миссиями и границ экрана,Класично скалирање паузе и ивице екрана,Klassisk skalning för paus och skärmkant,Ara ve Ekran Kenarlığı Klasik Ölçeklendirme +Intermission background,SCALEMNU_INTER,,,,Pozadí textových obrazovek,Intermission baggrund,Texthintergrund,,Fono de intermito,Fondo de intermisión,,Väliruutujen tausta,Fond d'écran intermission,Megszakító háttér,Sottofondi delle intermissioni,クリア結果の背景,인터미션 배경,Intermissieachtergrond,Pause bakgrunn,Tło wstawek,Fundo da tela de intervalo,,Fundal antract,Фон экрана между миссиями,Интермиссион бацкгроунд,Bakgrund för mellanslag,Devre arası arka planı +Screen border,SCALEMNU_BORDER,,,,Okraje obrazovky,Skærmbord,Rahmen,,Ekranbordero,Bordes de pantalla,,Ruudunreunus,Bordure d'écran,Kép széle,Bordo dello schermo,画面ボーダー,화면 테두리,Schermrand,Skjermkant,Ramka,Borda de tela,,Bordură ecran,Границы экрана,Граница екрана,Skärmgräns,Ekran kenarlığı +Scaling factor,SCALEMNU_FACTOR,,,,Měřítko,Skaleringsfaktor,Skalierungsfaktor,,Skalfaktoro,Factor de escalado,,Skaalauskerroin,Facteur de mise à l'échelle,Arányosító faktor,Fattore di scala,スケール倍率,스케일링 계수,Schaalfactor,Skaleringsfaktor,Współczynnik skalowania,Fator de escala,,Factor de scalare,Значение масштабирования,Фактор за скалирање,Skalningsfaktor,Ölçekleme faktörü +Aspect ratio,SCALEMNU_RATIO,,,,Poměr stran,Aspektforhold,Seitenverhältnis,,Proporcio,Ratio de aspecto,,Kuvasuhde,,Képarány,Proporzioni,アスペクト比,화면 비율,Beeldverhouding,Bildeforhold,Rozdzielczość,Proporção de tela,,Aspect imagine,Соотношение сторон,Однос ширине и висине,Bildförhållande,En boy oranı +Build,OPTVAL_BUILD,"as in ""Build engine"". This should not be translated unless there is a translated name for the engine",,,,,,,,,,,,,,,,,,,,,,,,, +Show Tally Screen On Level Exit,MISCMNU_ALWAYSTALLY,sv_alwaystally,,,Zobrazit výsledky na konci mapy,"Vis resultater, når du forlader kortet",Zeige Ergebnisse beim Verlassen des Levels,,Montri Kalkulekranon Sur Niveleliro,Mostrar pantalla de conteo al salir de nivel,,Näytä pisteruutu tasosta poistuttaessa,Montrer les scores en fin de niveau,Elért pontok mutatása a megszakító képen,Mostra i punteggi alla fine del livello,Exit時にタリー画面を表示,레벨 종료 시 집계 화면 표시,Toon tellingen na eind van het level,Vis Tally-skjerm på nivåutgang,Pokazuj wyniki pod koniec poziomu,Exibir tela de pontuação no fim da fase,,Afișează Totalul la Ieșirea din Nivel,Отображение экрана статистики при выходе с уровня,Прикажи екран за израчунавање на излазу из нивоа,Visa Tally-skärmen på nivå Avsluta,Seviye Çıkışında Çetele Ekranını Göster +Mod Defined,OPTVAL_MODDEFINED,this is '==0',,,Určeno mody,Mod Defineret,Mod-definiert,,Difinita per modif-dosiero,Definido por mod,,Modin määrittämä,Défini par Mod,Beállított Mod,Definito dalla mod,Mod定義,모드 정의,Volgens de mod,Mod Definert,Zdefiniowane przez modyfikację,Definir por mod,,Definit de către moduri,Определено модификацией,Мод Дефинед,Mod definierad,Mod Tanımlı +"Always, except within hubs",OPTVAL_NOTHUBS,,,,Vždy kromě hubů,"Altid, undtagen i hubs","Immer, außer in Hubs",,"Ĉiam, krom en naboj","Siempre, excepto en hubs",,"Aina, keskustasoja lukuun ottamatta","Toujours, sauf dans les hubs","Mindig, kivétel a csomópontoknál","Sempre, tranne gli hub",区間を除き、常に,"항상, 허브 내 제외","Altijd, behalve binnen hubs","Alltid, unntatt innenfor knutepunkter","Zawsze, oprócz hubów","Sempre, exceto em hubs",,"Mereu, mai puțin în hub-uri",Всегда (кроме групп уровней),"Увек, осим унутар чворишта","Alltid, utom i nav","Her zaman, hub'lar hariç" +"Always, even within hubs",OPTVAL_WITHHUBS,,,,Vždy včetně hubů,"Altid, også inden for hubs","Immer, auch in Hubs",,"Ĉiam, eĉ en naboj","Siempre, incluso en hubs",,"Aina, keskustasot mukaan lukien","Toujours, même dans les hubs","Mindig, még a csomópontoknál is","Sempre, inclusi gli hub",区間内でも、常に,"항상, 허브 내에서도","Altijd, zelfs binnen hubs","Alltid, også innenfor knutepunkter","Zawsze, nawet w hubach","Sempre, inclusive em hubs",,"Mereu, inclusiv în hub-uri",Всегда (включая группы уровни),"Увек, чак и унутар чворишта","Alltid, även inom nav","Her zaman, merkezler içinde bile" +Preferred keyboard layout,CNTRLMNU_LAYOUT,,,,Preferované rozložení klávesnice,Foretrukket tastaturlayout,Bevorzugte Tastaturbelegung,,Preferita klavararanĝo,Disposición de teclado preferida,,Lempinäppäinasettelu,Organisation préférée du clavier,Preferált billentyűkiosztás,Layout della tastiera preferito,優先するキー配列,기본 키보드 레이아웃,Voorkeur toetsenbordindeling,Foretrukket tastaturoppsett,Preferowany układ klawiatury,Layout de teclado preferido,,Schemă de control preferată,Раскладка клавиатуры,Жељени распоред тастатуре,Föredragen tangentbordslayout,Tercih edilen klavye düzeni +Classic ZDoom,OPTVAL_CLASSICZ,,,,Klasický ZDoom,Klassisk ZDoom,ZDoom klassisch,,Klasika ZDoom,ZDoom clásico,,Perinteinen ZDoom,Zdoom Classique,Klasszikus ZDoom,ZDoom Classico,従来のZDOOM,클래식 ZDoom,Klassiek ZDoom,Klassisk ZDoom,Klasyczny ZDoom,ZDoom Clássico,,ZDoom Clasic,Классическая ZDoom,Цлассиц ЗДоом,Klassiskt ZDoom,Klasik ZDoom +Modern (WASD),OPTVAL_MODERN,,,,Moderní (WASD),Moderne (WASD),,,Moderna (WASD),Moderno (WASD),,Nykyaikainen (WASD),Moderne (ZQSD),,Moderno (WASD),現代的(WASD),모던(WASD),,Moderne (WASD),Współczesny (WSAD),Moderno (WASD),,Modernă (WASD),Современная (ЦФЫВ),модерно,Modernt (WASD), +Modern (Keypad),OPTVAL_MODERNLEFT,,,,Moderní (číselník),Moderne (Keypad),,,Moderna (Cifera klavaro),Moderno (Teclado Numérico),,Nykyaikainen (numeronäppäimistö),Moderne (Pavé numérique),Modern (numpad),Moderno (tastierino numerico),現代的(Keypad),모던(키패드),Modern (nummeriek toetsenbord),Moderne (Keypad),Współczesny (klawiatura numeryczna),Moderno (Teclado numérico),,Modernă (Tastatură),Современная (цифр. клавиатура),Модерна (тастатура),Modernt (tangentbord),Modern (Tuş Takımı) +Strict KEYCONF Weapons/Players,MISCMNU_SETSLOTSTRICT,,,,Striktně zbraně/hráči z KEYCONF,Strenge KEYCONF Våben/spillere,Strikte KEYKONF Behandlung für Waffen und Spieler,,Strikta KEYCONF Armiloj/Ludantoj,KEYCONF de Armas/Jugadores estricto,,Pelaajien/Aseiden tiukka KEYCONF,Armes/Joueurs strictement selon KEYCONF,Szigorú KEYCONF a Fegyverek/Játékosok esetében,KEYCONF rigoroso per armi/giocatori,厳密にKEYCONFの武器/プレイヤー,엄격한 키콘프 무기/플레이어,Strikte KEYCONF Wapens/Spelers,Strenge KEYCONF-våpen/spillere,Surowe opcje KEYCONF dla broni/graczy,Armas/Jogadores estritamente de acordo com KEYCONF,,KEYCONF Strictă pentru Arme/Jucători,Строгий KEYCONF для оружия/игроков,Строго KEYKONF оружје/играчи,Strikt KEYCONF Vapen/spelare,Sıkı KEYCONF Silahlar/Oyuncular Classic ZDoom menu scaling,"MISCMNU_CLEANMENU -",,,,Škálování menu dle starého ZDoomu,Klassisk ZDoom-menu skalering,Alte ZDoom-Skalierung im Menü,,Klasika skalado de ZDoom-menuo,Escalado clásico de ZDoom en menús,,Perinteinen ZDoomin skaalaus valikossa,Mise à l'échelle du menu ZDoom Classique,Klasszikus ZDoom menü arányok,Fattore di scala ZDoom classico per i menu,従来のZDメニュースケール,클래식 ZDoom 메뉴 크기 조정,Klassieke ZDoom-menuschaal,Klassisk ZDoom-menyskalering,Klasyczne skalowanie menu z ZDooma,Escala clássica para menu do ZDoom,,Scară meniuri ZDoom clasică,Классический размер меню ZDoom,Класично скалирање ZDoom менија,Klasik ZDoom menü ölçeklendirme -Use percents on summary screen,MISCMNU_WIPERCENT,,,,Použít procenta ve výsledcích mapy,Brug procenter på oversigtsskærmen,Zeige Prozente auf Statistikseite,,Uzi procentojn sur resumekrano,Usar porcentajes en pantalla de sumario,,Käytä prosentteja pisteruuduilla,Utiliser pourcentages sur l'écran de fin de niveau,Százalékok használata az összefoglaló oldalon,Usa percentuali per le schermate di riepilogo,集計画面でパーセント表示,요약 화면에서 퍼센트 사용,Gebruik procenten op het overzichtsscherm,Bruk prosenter på sammendragsskjermen,Używaj procentów w ekranie wyników pod koniec poziomu,Usar porcentagem na tela de resumo,,Folosește procentaje la totaluri,Использовать проценты на экране итогов уровня,Користите проценте на екрану резимеа,Özet ekranında yüzdeleri kullanma -Classic ZDoom scaling on summary screen,MISCMNU_CLEANSTAT,,,,Škálovat obrazovky se shrnutím dle starého ZDoomu,Klassisk ZDoom-skala på oversigtsskærmen,Alte ZDoom-Skalierung auf Statistikseite,,Klasika ZDoom-skalado sur resumekrano,Escalado clásico de ZDoom en pantalla de sumario,,Perinteinen ZDoomin skaalaus pisteruudulla,Mise à l'échelle écran de fin de niveau ZDoom Classique,Klasszikus ZDoom arányok az összefoglaló oldalon,Fattore di scala ZDoom classico per le schermate di riepilogo,集計画面で従来のZDスケール,요약 화면에서 클래식 ZDoom 스케일링,Klassieke ZDoom-schaalverdeling op overzichtsscherm,Klassisk ZDoom-skalering på oppsummeringsskjermen,Klasyczne skalowanie ekranu z wynikami poziomu,Escala clássica do ZDoom na tela de resumo,,Scară ZDoom clasică a tabelei de marcaj,Классический размер ZDoom экрана итогов уровня,Класично ZDoom скалирање на екрану сажетка,Özet ekranında klasik ZDoom ölçeklendirme -Citizen,TAG_STRIFEZOMBIE,"Called ""citizens"" according to Doomwiki",,,Občan,Borger,Bürger,Πολίτης,Civilulo,Ciudadano,,Kansalainen,Citoyen,Polgár,Cittadino,住民,시민,Burger,Innbygger,Mieszkańcy,Cidadão,,Cetățean,Горожанин,грађанин,Vatandaş -Ceiling Turret,TAG_CEILINGTURRET,,,,Střílna,Tårn til loftet,Deckengeschütz,,Plafona tureto,Torreta de techo,,Kattotykkitorni,Tourelle de plafond,Plafon lövésztorony,Torretta da soffitto,警備システム,천장 터렛,Plafond torentje,Tak-tårn,Wieżyczka,Defesa Automática,,Turetă de Tavan,Потолочная турель,Цеилинг Туррет,Tavan Tareti -Crusader,TAG_CRUSADER,Names need to match the obituaries!,,,Křižák,Korsfarer,Ordensritter,,Krucisto,Cruzado,,Ristiretkeläinen,Croisé,Keresztes,Crociato,クルセーダー,성전사,Kruisvaarder,Korsfarer,Krzyżowiec,Cruzado,,Cruciat,Крестоносец,Црусадер,Haçlı -Inquisitor,TAG_INQUISITOR,,,,Inkvizitor,Inkvisitor,,,Inkvizitoro,Inquisidor,,Inkvisiittori,Inquisiteur,Inkvizítor,Inquisitore,審問官,인퀴지터,Inquisiteur,Inkvisitor,Inkwizytor,Inquisidor,,Inchizitor,Инквизитор,Инквизитор,Engizisyoncu -Peasant,TAG_PEASANT,,,,Rolník,Bonde,Bauer,Χωρικός,Kamparano,Campesino,,Maallikko,Paysan,Jobbágy,Civile,庶民,농민,Onderdaan,Bonde,Mieszczuch,Camponês,,Sărman,Рабочий,Сељак,Köylü -Reaver,TAG_REAVER,,,,Plenitel,Reaver,Plünderer,,Lerta roboto,Saqueador,,Raastaja,Reaver,Fosztogató,Saccheggiatore,リーバー,사수,,Reaver,Rozbójnik,Saqueador,,Hoț,Похититель,Реавер,Yağmacı -Sentinel,TAG_SENTINEL,,,,Strážbot,Sentinel,Wächter,,Sentinelo,Centinela,,Vartija,Sentinelle,Őrszem,Sentinella,センティネル,센티넬,,Vaktpost,Strażnik,Sentinela,,Santinelă,Страж,Сентинел,Nöbetçi -Stalker,TAG_STALKER,,,,Slídil,Stalker,Jäger,,Persekutanto,Acechador,,Vaanija,Chasseur,Lesipuskás,Cacciatore,ストーカー,스토커,,Forfølgeren,Prześladowca,Caçador,,Hărțuitor,Преследователь,Сталкер,Takipçi -The Bishop,TAG_BISHOP,,,,Biskup,Biskoppen,Bischof,,La Episkopo,El Obispo,,Piispa,Evèque,A Püspök,Vescovo,ビショップ,비숍,De Bisschop,Biskopen,Biskup,O Bispo,,Episcopul,Епископ,Бискуп,Piskopos -The One God,TAG_ENTITY,,,,Jeden Bůh,Den ene gud,Der Eine Gott,Ο ένας Θεός,La Ununura Dio,El Dios Único,,Yksi Ainoa Jumala,Le Seui Dieu,Az Egy Isten,Unico Dio,唯一神,유일신,De ene god,Den ene Gud,Jedyny Bóg,O Deus Único,,Adevăratul Zeu,Единый Бог,Једини Бог,Tek Tanrı -The Programmer,TAG_PROGRAMMER,,,,Programátor,Programmøren,Programmierer,,La Programisto,El Programador,,Ohjelmoija,Programmeur,A Programozó,Programmatore,プログラマー,프로그래머,Programmeur,Programmereren,Programista,O Programador,,Programatorul,Программист,Програмер,Programcı -The Spectre,TAG_ALIENSPECTRE,,,,Přízrak,Spøgelset,Schemen,,La Fantomo,El Espectro,,Haamu,Le spectre,A Lidérc,Spettro,スペクトル,스펙터,Het spook,Spøkelset,Widmo,O Espectro,,Spectrul,Призрак,Тхе Спецтре,Hortlak -Kneeling Guy,TAG_KNEELINGGUY,,,,Ctitel,Den knælende fyr,Kniender Typ,,Genuantulo,Tipo arrodillado,,Polvistunut mies,Homme agenouillé,Térdelő,Uomo inchinato,礼拝者,무릎 꿇은 남자,Knielende man,Den knelende fyren,Oddający pokłon,Crente,,Tip Îngenunchiat,Парень на коленях,Човек који клечи,Diz Çökmüş Adam -Spawn multiplayer things in coop,GMPLYMNU_MULTIPLAYERTHINGS,,,,Spawnovat multiplayerové předměty v co-opu,Spawn multiplayer-ting i coop,Multispielergegenstände in Coop,,Ekaperigi plurludantajn objekojn en koopera reĝimo,Hacer aparecer cosas del multijugador en cooperativo,,Luo moninpelioliot yhteispelissä,Créez des objets multijoueurs en co-op,Multiplayer tárgyak létrehozása Együttműködő módban,Fai apparire gli oggetti di multigiocatore in cooperativa,協力モードでマルチ用thingsを出す,협동 플레이에서 멀티플레이어 사물 생성,Spawnen van multiplayer dingen in coop,Spawn multiplayer ting i coop,Daj przedmioty trybu wieloosobowego w trybie kooperacji,Surgir objetos de multijogador no modo coperativo,,Afișează obiectele marcate pentru modul online,Появление вещей из сетевой игры в совместной игре,Поставите ствари за више играча у кооперацији,Coop'ta çok oyunculu şeyler ortaya çıkarma -Sprite shadows,DSPLYMNU_SPRITESHADOW,,,,Stíny spritů,Sprite skygger,Spriteschatten,,Ombroj de spritoj,Sombras de sprites,,Spritevarjot,Ombres de sprites,Sprite árnyékok,Ombre per sprite,スプライト シャドウ,스프라이트 그림자,Sprite schaduwen,Sprite skygger,Cienie sprite'ów,Sombras de sprites,,Umbre pentru sprite-uri,Тени спрайтов,Сприте схадовс,Sprite gölgeleri -Monsters and players,OPTVAL_SPRSHADALWAYS,Will enable sprite shadows for monster and player sprites,,,Monstra a hráči,Monstre og spillere,Monster und Spieler,Τέρατα και παίχτες,Monstroj kaj ludantoj,Monstruos y jugadores,,Hirviöt ja pelaajat,Monstres et joueurs,Szörnyek és játékosok,Mostri e giocatori,敵とプレイヤー,몬스터와 플레이어,Monsters en spelers,Monstre og spillere,Potwory i Gracze,Monstros e jogadores,,Monștrii și jucători,Монстров и игроков,Чудовишта и играчи,Canavarlar ve oyuncular -FOV,DSPLYMNU_FOV,the FOV slider,,,Zorné pole (FOV),,,,Vidkampo,Campo de visión,,Näkökenttä,Champ de vision,Látószög,Campo visivo,,,,,Pole Widzenia,Campo de visão,,Câmp vizual,Поле зрения,,FOV -Disable MBF21 features,CMPTMNU_NOMBF21,,,,Zakázat funkce MBF21,Deaktivere MBF21-funktioner,MBF21 Features deaktivieren,Απενεργοποίηση MBF21 λειτουργιών,Malvalidigi funkciojn de MBF21,Deshabilitar las funciones de MBF21,,Poista MBF21-ominaisuudet käytöstä,Désactiver les fonctionnalités MBF21,MBF21 vonások kikapcsolása,Disabilita le funzioni MBF21,MBF21機能を無効,MBF21 기능 비활성화,MBF21-functies uitschakelen,Deaktiver MBF21-funksjoner,Wyłącz funkcje portu MBF21,Desativar recursos do MBF21,,Dezactivare caracteristici MBF21,Отключить функции MBF21,Онемогућите функције MBF21,MBF21 özelliklerini devre dışı bırakma -Show time widget,ALTHUDMNU_SHOWTIMESTAT,,,,Zobrazit widget s časem,Vis tid widget,Zeige Zeit-Widget,,Montri tempo-fenestraĵon,Mostrar widget de tiempo,,Näytä aikatyökalu,Afficher le widget de l'heure,Óra mutatása,Mostra orario,ウィジットタイマーの表示,시간 표시 위젯,Tijdwidget tonen,Vis tid widget,Pokaż widżet czasu,Mostrar widget de tempo,,Afișare dispozitiv pt. timp,Показать виджет времени,Прикажи виџет времена,Zaman widget'ını göster -MBF21,OPTVAL_MBF21,,,,,,,,,,,,,,,,,,,,,,,,, -Crushed monsters get resurrected as ghosts,CMPTMNU_VILEGHOSTS,,,,Oživovat rozdrcené příšery jako duchy,Knuste monstre genopstår som spøgelser,Zermalmte Monster werden als Geister wiedererweckt,Συνθλιμένα τέρατα αναστήνοντε ως φαντάσματα,Dispremitaj monstroj reviviĝas kiel fantomoj,Los monstruos aplastados son resucitados como fantasmas,,Murskatut hirviöt heräävät henkiin aaveina...,Les monstres écrasés ressuscitent en fantômes,Összenyomott szörnyek szellemként születnek újra,Mostri schiacciati vengono resuscitati come fantasmi,圧死した敵が蘇生でゴースト化,분쇄된 몬스터는 유령으로 부활합니다.,Verpletterde monsters worden herrezen als geesten,Knuste monstre gjenoppstår som spøkelser,Zmiażdżone potwory wskrzeszone jako duchy,Monstros esmagados ressucitam como fantasmas,,Monștrii striviți sunt readuși la viață ca fantome.,Раздавленные монстры воскресают в виде призраков,Сломљена чудовишта васкрсавају као духови,Ezilmiş canavarlar hayalet olarak dirilir -View bobbing while flying,MISCMNU_FVIEWBOB,,,,Pohupování pohybu při létání,Vis bobbing mens du flyver,Waffenpendeln beim Fliegen,,Vidi kapo-balanciĝon dum flugado,,,,Chaloupage arme en vol,,,飛行中の視点揺れ,비행 중 흔들림 보기,Bekijk bob bedrag terwijl je vliegt,Se bobbing mens du flyr,Pokaż bujanie podczas lotu,Balanço na visão durante voo,,Mișcare cameră în timpul zborului,Покачивание камеры при полёте,Погледајте скакање током лета,Uçarken sallanmayı görüntüle \ No newline at end of file +",,,,Škálování menu dle starého ZDoomu,Klassisk ZDoom-menu skalering,Alte ZDoom-Skalierung im Menü,,Klasika skalado de ZDoom-menuo,Escalado clásico de ZDoom en menús,,Perinteinen ZDoomin skaalaus valikossa,Mise à l'échelle du menu ZDoom Classique,Klasszikus ZDoom menü arányok,Fattore di scala ZDoom classico per i menu,従来のZDメニュースケール,클래식 ZDoom 메뉴 크기 조정,Klassieke ZDoom-menuschaal,Klassisk ZDoom-menyskalering,Klasyczne skalowanie menu z ZDooma,Escala clássica para menu do ZDoom,,Scară meniuri ZDoom clasică,Классический размер меню ZDoom,Класично скалирање ZDoom менија,Skalning av Classic ZDoom-menyn,Klasik ZDoom menü ölçeklendirme +Use percents on summary screen,MISCMNU_WIPERCENT,,,,Použít procenta ve výsledcích mapy,Brug procenter på oversigtsskærmen,Zeige Prozente auf Statistikseite,,Uzi procentojn sur resumekrano,Usar porcentajes en pantalla de sumario,,Käytä prosentteja pisteruuduilla,Utiliser pourcentages sur l'écran de fin de niveau,Százalékok használata az összefoglaló oldalon,Usa percentuali per le schermate di riepilogo,集計画面でパーセント表示,요약 화면에서 퍼센트 사용,Gebruik procenten op het overzichtsscherm,Bruk prosenter på sammendragsskjermen,Używaj procentów w ekranie wyników pod koniec poziomu,Usar porcentagem na tela de resumo,,Folosește procentaje la totaluri,Использовать проценты на экране итогов уровня,Користите проценте на екрану резимеа,Använd procentsatser på sammanfattningsskärmen,Özet ekranında yüzdeleri kullanma +Classic ZDoom scaling on summary screen,MISCMNU_CLEANSTAT,,,,Škálovat obrazovky se shrnutím dle starého ZDoomu,Klassisk ZDoom-skala på oversigtsskærmen,Alte ZDoom-Skalierung auf Statistikseite,,Klasika ZDoom-skalado sur resumekrano,Escalado clásico de ZDoom en pantalla de sumario,,Perinteinen ZDoomin skaalaus pisteruudulla,Mise à l'échelle écran de fin de niveau ZDoom Classique,Klasszikus ZDoom arányok az összefoglaló oldalon,Fattore di scala ZDoom classico per le schermate di riepilogo,集計画面で従来のZDスケール,요약 화면에서 클래식 ZDoom 스케일링,Klassieke ZDoom-schaalverdeling op overzichtsscherm,Klassisk ZDoom-skalering på oppsummeringsskjermen,Klasyczne skalowanie ekranu z wynikami poziomu,Escala clássica do ZDoom na tela de resumo,,Scară ZDoom clasică a tabelei de marcaj,Классический размер ZDoom экрана итогов уровня,Класично ZDoom скалирање на екрану сажетка,Klassisk ZDoom-skalering på sammanfattningsskärmen,Özet ekranında klasik ZDoom ölçeklendirme +Citizen,TAG_STRIFEZOMBIE,"Called ""citizens"" according to Doomwiki",,,Občan,Borger,Bürger,Πολίτης,Civilulo,Ciudadano,,Kansalainen,Citoyen,Polgár,Cittadino,住民,시민,Burger,Innbygger,Mieszkańcy,Cidadão,,Cetățean,Горожанин,грађанин,Medborgare,Vatandaş +Ceiling Turret,TAG_CEILINGTURRET,,,,Střílna,Tårn til loftet,Deckengeschütz,,Plafona tureto,Torreta de techo,,Kattotykkitorni,Tourelle de plafond,Plafon lövésztorony,Torretta da soffitto,警備システム,천장 터렛,Plafond torentje,Tak-tårn,Wieżyczka,Defesa Automática,,Turetă de Tavan,Потолочная турель,Цеилинг Туррет,Tak turret,Tavan Tareti +Crusader,TAG_CRUSADER,Names need to match the obituaries!,,,Křižák,Korsfarer,Ordensritter,,Krucisto,Cruzado,,Ristiretkeläinen,Croisé,Keresztes,Crociato,クルセーダー,성전사,Kruisvaarder,Korsfarer,Krzyżowiec,Cruzado,,Cruciat,Крестоносец,Црусадер,Korsriddar,Haçlı +Inquisitor,TAG_INQUISITOR,,,,Inkvizitor,Inkvisitor,,,Inkvizitoro,Inquisidor,,Inkvisiittori,Inquisiteur,Inkvizítor,Inquisitore,審問官,인퀴지터,Inquisiteur,Inkvisitor,Inkwizytor,Inquisidor,,Inchizitor,Инквизитор,Инквизитор,Inkvisitor,Engizisyoncu +Peasant,TAG_PEASANT,,,,Rolník,Bonde,Bauer,Χωρικός,Kamparano,Campesino,,Maallikko,Paysan,Jobbágy,Civile,庶民,농민,Onderdaan,Bonde,Mieszczuch,Camponês,,Sărman,Рабочий,Сељак,Bonde,Köylü +Reaver,TAG_REAVER,,,,Plenitel,,Plünderer,,Lerta roboto,Saqueador,,Raastaja,,Fosztogató,Saccheggiatore,リーバー,사수,,,Rozbójnik,Saqueador,,Hoț,Похититель,Реавер,,Yağmacı +Sentinel,TAG_SENTINEL,,,,Strážbot,,Wächter,,Sentinelo,Centinela,,Vartija,Sentinelle,Őrszem,Sentinella,センティネル,센티넬,,Vaktpost,Strażnik,Sentinela,,Santinelă,Страж,Сентинел,,Nöbetçi +Stalker,TAG_STALKER,,,,Slídil,,Jäger,,Persekutanto,Acechador,,Vaanija,Chasseur,Lesipuskás,Cacciatore,ストーカー,스토커,,Forfølgeren,Prześladowca,Caçador,,Hărțuitor,Преследователь,Сталкер,,Takipçi +The Bishop,TAG_BISHOP,,,,Biskup,Biskoppen,Bischof,,La Episkopo,El Obispo,,Piispa,Evèque,A Püspök,Vescovo,ビショップ,비숍,De Bisschop,Biskopen,Biskup,O Bispo,,Episcopul,Епископ,Бискуп,Biskopen,Piskopos +The One God,TAG_ENTITY,,,,Jeden Bůh,Den ene gud,Der Eine Gott,Ο ένας Θεός,La Ununura Dio,El Dios Único,,Yksi Ainoa Jumala,Le Seul Dieu,Az Egy Isten,Unico Dio,唯一神,유일신,De ene god,Den ene Gud,Jedyny Bóg,O Deus Único,,Adevăratul Zeu,Единый Бог,Једини Бог,Den ende guden,Tek Tanrı +The Programmer,TAG_PROGRAMMER,,,,Programátor,Programmøren,Programmierer,,La Programisto,El Programador,,Ohjelmoija,Programmeur,A Programozó,Programmatore,プログラマー,프로그래머,Programmeur,Programmereren,Programista,O Programador,,Programatorul,Программист,Програмер,Programmeraren,Programcı +The Spectre,TAG_ALIENSPECTRE,,,,Přízrak,Spøgelset,Schemen,,La Fantomo,El Espectro,,Haamu,Le spectre,A Lidérc,Spettro,スペクトル,스펙터,Het spook,Spøkelset,Widmo,O Espectro,,Spectrul,Фантом,Тхе Спецтре,Spektret,Hortlak +Kneeling Guy,TAG_KNEELINGGUY,,,,Ctitel,Den knælende fyr,Kniender Typ,,Genuantulo,Tipo arrodillado,,Polvistunut mies,Homme agenouillé,Térdelő,Uomo inchinato,礼拝者,무릎 꿇은 남자,Knielende man,Den knelende fyren,Oddający pokłon,Crente,,Tip Îngenunchiat,Парень на коленях,Човек који клечи,Den knäböjande killen,Diz Çökmüş Adam +Spawn multiplayer things in coop,GMPLYMNU_MULTIPLAYERTHINGS,,,,Spawnovat multiplayerové předměty v co-opu,Spawn multiplayer-ting i coop,Multispielergegenstände in Coop,,Ekaperigi plurludantajn objekojn en koopera reĝimo,Hacer aparecer cosas del multijugador en cooperativo,,Luo moninpelioliot yhteispelissä,Objets multijoueurs en co-op,Multiplayer tárgyak létrehozása Együttműködő módban,Fai apparire gli oggetti di multigiocatore in cooperativa,協力モードでマルチ用thingsを出す,협동 플레이에서 멀티플레이어 사물 생성,Spawnen van multiplayer dingen in coop,Spawn multiplayer ting i coop,Daj przedmioty trybu wieloosobowego w trybie kooperacji,Surgir objetos de multijogador no modo coperativo,,Afișează obiectele marcate pentru modul online,Появление вещей из сетевой игры в совместной игре,Поставите ствари за више играча у кооперацији,Spawna multiplayer saker i coop,Coop'ta çok oyunculu şeyler ortaya çıkarma +Sprite shadows,DSPLYMNU_SPRITESHADOW,,,,Stíny spritů,Sprite skygger,Spriteschatten,,Ombroj de mov-rastrumoj,Sombras de «sprites»,,Spritevarjot,Ombres de sprites,Sprite árnyékok,Ombre per sprite,スプライト シャドウ,스프라이트 그림자,Sprite schaduwen,Sprite skygger,Cienie sprite'ów,Sombras de sprites,,Umbre pentru sprite-uri,Тени спрайтов,Сприте схадовс,Sprite-skuggor,Sprite gölgeleri +Monsters and players,OPTVAL_SPRSHADALWAYS,Will enable sprite shadows for monster and player sprites,,,Monstra a hráči,Monstre og spillere,Monster und Spieler,Τέρατα και παίχτες,Monstroj kaj ludantoj,Monstruos y jugadores,,Hirviöt ja pelaajat,Monstres et joueurs,Szörnyek és játékosok,Mostri e giocatori,敵とプレイヤー,몬스터와 플레이어,Monsters en spelers,Monstre og spillere,Potwory i Gracze,Monstros e jogadores,,Monștrii și jucători,Монстров и игроков,Чудовишта и играчи,Monster och spelare,Canavarlar ve oyuncular +FOV,DSPLYMNU_FOV,the FOV slider,,,Zorné pole (FOV),,,,Vidkampo,Campo de visión,,Näkökenttä,Champ de vision,Látószög,Campo visivo,,,,,Pole Widzenia,Campo de visão,,Câmp vizual,Поле зрения,,, +Disable MBF21 features,CMPTMNU_NOMBF21,,,,Zakázat funkce MBF21,Deaktivere MBF21-funktioner,MBF21 Features deaktivieren,Απενεργοποίηση MBF21 λειτουργιών,Malvalidigi funkciojn de MBF21,Deshabilitar las funciones de MBF21,,Poista MBF21-ominaisuudet käytöstä,Désactiver les fonctionnalités MBF21,MBF21 vonások kikapcsolása,Disabilita le funzioni MBF21,MBF21機能を無効,MBF21 기능 비활성화,MBF21-functies uitschakelen,Deaktiver MBF21-funksjoner,Wyłącz funkcje portu MBF21,Desativar recursos do MBF21,,Dezactivare caracteristici MBF21,Отключить функции MBF21,Онемогућите функције MBF21,Inaktivera MBF21-funktioner,MBF21 özelliklerini devre dışı bırakma +Show time widget,ALTHUDMNU_SHOWTIMESTAT,,,,Zobrazit widget s časem,Vis tid widget,Zeige Zeit-Widget,,Montri tempo-fenestraĵon,Mostrar widget de tiempo,,Näytä aikatyökalu,Afficher le widget horloge,Óra mutatása,Mostra orario,ウィジットタイマーの表示,시간 표시 위젯,Tijdwidget tonen,Vis tid widget,Pokaż widżet czasu,Mostrar widget de tempo,,Afișare dispozitiv pt. timp,Показать виджет времени,Прикажи виџет времена,Visa tidswidget,Zaman widget'ını göster +MBF21,OPTVAL_MBF21,,,,,,,,,,,,,,,,,,,,,,,,,, +Crushed monsters get resurrected as ghosts,CMPTMNU_VILEGHOSTS,,,,Oživovat rozdrcené příšery jako duchy,Knuste monstre genopstår som spøgelser,Zermalmte Monster werden als Geister wiedererweckt,Συνθλιμένα τέρατα αναστήνοντε ως φαντάσματα,Dispremitaj monstroj reviviĝas kiel fantomojn,Los monstruos aplastados son resucitados como fantasmas,,Murskatut hirviöt heräävät henkiin aaveina...,Les monstres écrasés ressuscitent en fantômes,Összenyomott szörnyek szellemként születnek újra,Mostri schiacciati vengono resuscitati come fantasmi,圧死した敵が蘇生でゴースト化,분쇄된 몬스터는 유령으로 부활합니다.,Verpletterde monsters worden herrezen als geesten,Knuste monstre gjenoppstår som spøkelser,Zmiażdżone potwory wskrzeszone jako duchy,Monstros esmagados ressucitam como fantasmas,,Monștrii striviți sunt readuși la viață ca fantome.,Раздавленные монстры воскресают в виде призраков,Сломљена чудовишта васкрсавају као духови,Krossade monster återuppstår som spöken.,Ezilmiş canavarlar hayalet olarak dirilir +View bobbing while flying,MISCMNU_FVIEWBOB,,,,Pohupování pohledu při létání,Vis bobbing mens du flyver,Waffenpendeln beim Fliegen,,Vidi kapo-balanciĝon dum flugado,La vista tambalea al volar,,,Chaloupage en vol,Nézet repüléskori billegése,,飛行中の視点揺れ,비행 중 흔들림 보기,Bekijk bob bedrag terwijl je vliegt,Se bobbing mens du flyr,Pokaż bujanie podczas lotu,Balanço na visão durante voo,,Mișcare cameră în timpul zborului,Покачивание камеры при полёте,Погледајте скакање током лета,Visa att det guppar när du flyger,Uçarken sallanmayı görüntüle \ No newline at end of file diff --git a/wadsrc/static/lmacros.csv b/wadsrc/static/lmacros.csv index af988a2c0..89ce640ce 100644 --- a/wadsrc/static/lmacros.csv +++ b/wadsrc/static/lmacros.csv @@ -32,7 +32,9 @@ adj_3_rus,ru,ён,на,но,но irreg_1_rus,ru,ёл,ла,ло,ло irreg_2_rus,ru,,ла,ло,ло irreg_3_rus,ru,ёг,егла,егло,егло -pron_rus,ru,него,неё,него,него +irreg_4_rus,ru,ёк,екла,екло,екло +pron_rus,ru,него,неё,, +cheatpron_rus,ru,щик,щица,, ao_1_sr,sr,о,ла,ло,ло ao_2_sr,sr,ао,ла,ло,ло ao_3_sr,sr,ог,у,ог,ог @@ -44,4 +46,11 @@ pro2_gr,el,Τον,Την,Τον,Το pro3_gr,el,στον,στην,στο,στο art_gr,el,Ο,Η,Το,Το pro4_gr,el,του,της,του,του -pro_dk,da,han,hun,han,det \ No newline at end of file +pro_dk,"da, no",han,hun,han,det +pro_sv,sv,han,hon,han,den +ref_sv,sv,honom,henne,honom,den +ao_ua,ua,ий,а,о,о +adj_1_ua,ua,в,ла,ло,ло +adj_2_ua,ua,вся,лась,лось,лось +adj_3_ua,ua,,ла,ло,ло +adj_4_ua,ua,ий,та,то,то \ No newline at end of file diff --git a/wadsrc_extra/static/filter/chex.chex3/language.csv b/wadsrc_extra/static/filter/chex.chex3/language.csv index 666a54380..f56a78df7 100644 --- a/wadsrc_extra/static/filter/chex.chex3/language.csv +++ b/wadsrc_extra/static/filter/chex.chex3/language.csv @@ -1,62 +1,62 @@ -default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,tr -Picked up a blue flemkey.,GOTBLUEFLEM,Flem = phlegm,,,Sebrán modrý slizoklíč.,Du samlede en blå flemkey op.,Blauen Flemschlüssel genommen,,Prenis bluan mukŝlosilon.,Recogiste una flemllave azul.,,Poimit sinisen lima-avaimen,Flemclé bleue récupérée.,Kék slejmkulcs felvéve.,Raccolta una chiave-flem blu.,ブルー フレムキー をみつけた,청색 플렘열쇠 획득.,Je hebt een blauwe flemsleutel opgehaald.,Plukket opp en blå flemkey.,Zebrano niebieski flemowy klucz,Pegou uma flemchave azul.,,Ai ridicat flemcheia albastră.,Получен синий флемключ.,,Mavi bir flemkey aldım. -Picked up a yellow flemkey.,GOTYELLOWFLEM,,,,Sebrán žlutý slizoklíč.,Du samlede en gul flemkey op.,Gelben Flemschlüssel genommen,,Prenis flavan mukŝlosilon.,Recogiste una flemllave amarilla.,,Poimit keltaisen lima-avaimen,Flemclé jaune récupérée.,Sárga slejmkulcs felvéve.,Raccolta una chiave-flem gialla.,イエローフレムキー をみつけた,황색 플렘열쇠 획득.,Je hebt een gele flemsleutel opgehaald.,Plukket opp en gul flemkey.,Zebrano żółty flemowy klucz,Pegou uma flemchave amarela.,,Ai ridicat flemcheia galbenă.,Получен жёлтый флемключ.,,Sarı bir flemkey aldı. -Picked up a red flemkey.,GOTREDFLEM,,,,Sebrán červený slizoklíč.,Du samlede en rød flemkey op.,Roten Flemschlüssel genommen.,,Prenis ruĝan mukŝlosilon.,Recogiste una flemllave roja.,,Poimit punaisen lima-avaimen,Flemclé rouge récupérée.,Piros slejmkulcs felvéve.,Raccolta una chiave-flem rossa.,レッド フレムキー をみつけた,적색 플렘열쇠 획득.,Je hebt een rode flemsleutel opgehaald.,Plukket opp en rød flemkey.,Zebrano czerwony flemowy klucz,Pegou uma flemchave vermelha.,,Ai ridicat flemcheia roșie.,Получен красный флемключ.,,Kırmızı bir flemkey aldı. -Found Ultra Goggles,GOTGOGGLES,,,,Nalezeny ultrabrýle.,Fandt Ultra Goggles,Ultrasichtbrille gefunden,,Trovis Plejajn Okulvitrojn.,Ultra Gafas encontradas,Ultralentes encontrados,Löysit ultralasit,Ultra-lunettes récupérées.,Ultraszemüveg felvéve.,,ウルトラゴーグル をみつけた,울트라 고글 사용.,Ultraroggles gevonden,Fant Ultra Goggles,Znaleziono Ultra Gogle,Achou um Ultra Óculos.,,Ai găsit Ultra Ochelarii,Получены ультра-очки,,Ultra Gözlük bulundu -You need a blue key to activate this object,PD_BLUECO,,,,Potřebuješ modrý klíč pro aktivaci tohoto objektu,Du skal bruge en blå nøgle for at aktivere dette objekt,"Du brauchst einen blauen Schlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas bluan ŝlosilon por aktivigi ĉi tiun objekton.,Necesitas una llave azul para activar este objeto,,Tarvitset sinisen avaimen aktivoidaksesi tämän kappaleen,Il vous faut une clé bleue pour activer cet objet.,Egy kék kulcs szükséges az objektum aktiválásához.,Ti serve una chiave blu per attivare questo oggetto,このそうちは ブルー キー がひつようだ,이걸 작동하려면 청색 열쇠가 필요합니다,Je hebt een blauwe sleutel nodig om dit object te activeren.,Du trenger en blå nøkkel for å aktivere dette objektet,"Potrzebujesz niebieskiego klucza, aby aktywować ten przedmiot",Você precisa de uma chave azul para ativar este objeto,,Ai nevoie de o cheie albastră pentru a activa acest obiect,Для активации нужен синий ключ,Треба вам плави кључ да бисте активирали овај предмет,Bu nesneyi etkinleştirmek için mavi bir anahtara ihtiyacınız var -You need a red key to activate this object,PD_REDCO,,,,Potřebuješ červený klíč pro aktivaci tohoto objektu,Du skal bruge en rød nøgle for at aktivere dette objekt,"Du brauchst einen roten Schlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas ruĝan ŝlosilon por aktivigi ĉi tiun objekton.,Necesitas una llave roja para activar este objeto,,Tarvitset punaisen avaimen aktivoidaksesi tämän kappaleen,Il vous faut une clé rouge pour activer cet objet.,Egy piros kulcs szükséges az objektum aktiválásához.,Ti serve una chiave rossa per attivare questo oggetto,このそうちは レッド キー がひつようだ,이걸 작동하려면 적색 열쇠가 필요합니다,Je hebt een rode sleutel nodig om dit object te activeren.,Du trenger en rød nøkkel for å aktivere denne gjenstanden,"Potrzebujesz czerwonego klucza, aby aktywować ten przedmiot",Você precisa de uma chave vermelha para ativar este objeto,,Ai nevoie de o cheie roșie pentru a activa acest obiect,Для активации нужен красный ключ,Треба вам црвени кључ да бисте активирали овај предмет,Bu nesneyi etkinleştirmek için kırmızı bir anahtara ihtiyacınız var -You need a yellow key to activate this object,PD_YELLOWCO,,,,Potřebuješ žlutý klíč pro aktivaci tohoto objektu,Du skal bruge en gul nøgle for at aktivere dette objekt,"Du brauchst einen gelben Schlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas flavan ŝlosilon por aktivigi ĉi tiun objekton.,Necesitas una llave amarilla para activar este objeto,,Tarvitset keltaisen avaimen aktivoidaksesi tämän kappaleen,Il vous faut une clé jaune pour activer cet objet.,Egy sárga kulcs szükséges az objektum aktiválásához.,Ti serve una chiave gialla per attivare questo oggetto,このそうちは イエローキー がひつようだ,이걸 작동하려면 황색 열쇠가 필요합니다,Je hebt een gele sleutel nodig om dit object te activeren.,Du trenger en gul nøkkel for å aktivere denne gjenstanden,"Potrzebujesz żółtego klucza, aby aktywować ten przedmiot",Você precisa de uma chave amarela para ativar este objeto,,Ai nevoie de o cheie galbenă pentru a activa acest obiect,Для активации нужен жёлтый ключ,Треба вам жути кључ да бисте активирали овај предмет,Bu nesneyi etkinleştirmek için sarı bir anahtara ihtiyacınız var -You need a blue flemkey to activate this object,PD_BLUEFO,,,,Potřebuješ modrý slizoklíč pro aktivaci tohoto objektu.,Du skal bruge en blå flemkey for at aktivere dette objekt,"Du brauchst einen blauen Flemschlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas bluan mukŝlosilon por aktivigi ĉi tiun objekton.,Necesitas una flemllave azul para activar este objeto,,Tarvitset sinisen lima-avaimen aktivoidaksesi tämän kappaleen,Il vous faut une flemclé bleue pour activer cet objet.,Egy kék slejmkulcs szükséges az objektum aktiválásához.,Ti serve una chiave-flem blu per attivare questo oggetto,このそうちは ブルー キーがひつようだ,이걸 작동하려면 청색 플렘열쇠가 필요합니다,Je hebt een blauwe flemsleutel nodig om dit object te activeren.,Du trenger en blå flemkey for å aktivere denne gjenstanden.,"Potrzebujesz niebieskiego flemowego klucza, aby aktywować ten przedmiot",Você precisa de uma flemchave azul para ativar este objeto,,Ai nevoie de o flemcheie albastră pentru a activa acest obiect,Для активации нужен синий флемключ,,Bu nesneyi etkinleştirmek için mavi bir flemkey'e ihtiyacınız var -You need a red flemkey to activate this object,PD_REDFO,,,,Potřebuješ červený slizoklíč pro aktivaci tohoto objektu.,Du skal bruge en rød flemkey for at aktivere dette objekt,"Du brauchst einen roten Flemschlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas ruĝan mukŝlosilon por aktivigi ĉi tiun objekton.,Necesitas una flemllave roja para activar este objeto,,Tarvitset punaisen lima-avaimen aktivoidaksesi tämän kappaleen,Il vous faut une flemclé rouge pour activer cet objet.,Egy piros slejmkulcs szükséges az objektum aktiválásához.,Ti serve una chiave-flem rossa per attivare questo oggetto,このそうちは レッド キーがひつようだ,이걸 작동하려면 적색 플렘열쇠가 필요합니다,Je hebt een rode flemsleutel nodig om dit object te activeren.,Du trenger en rød flemkey for å aktivere dette objektet.,"Potrzebujesz czerwonego flemowego klucza, aby aktywować ten przedmiot",Você precisa de uma flemchave vermelha para ativar este objeto,,Ai nevoie de o flemcheie roșie pentru a activa acest obiect,Для активации нужен красный флемключ,,Bu nesneyi etkinleştirmek için kırmızı bir flemkey'e ihtiyacınız var -You need a yellow flemkey to activate this object,PD_YELLOWFO,,,,Potřebuješ žlutý slizoklíč pro aktivaci tohoto objektu.,Du skal bruge en gul flemkey for at aktivere dette objekt,"Du brauchst einen gelben Flemschlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas flavan mukŝlosilon por aktivigi ĉi tiun objekton.,Necesitas unaflemllave amarilla para activar este objeto,,Tarvitset keltaisen lima-avaimen aktivoidaksesi tämän kappaleen,Il vous faut une flemclé jaune pour activer cet objet.,Egy sárga slejmkulcs szükséges az objektum aktiválásához.,Ti serve una chiave-flem gialla per attivare questo oggetto,このそうちは イエローキーがひつようだ,이걸 작동하려면 황색 플렘열쇠가 필요합니다,Je hebt een gele flemsleutel nodig om dit object te activeren.,Du trenger en gul flemkey for å aktivere dette objektet.,"Potrzebujesz żółtego flemowego klucza, aby aktywować ten przedmiot",Você precisa de uma flemchave amarela para ativar este objeto,,Ai nevoie de o flemcheie galbenă pentru a activa acest obiect,Для активации нужен жёлтый флемключ,,Bu nesneyi etkinleştirmek için sarı bir flemkey'e ihtiyacınız var -Picked up a zorcher.,PICKUP_PISTOL_DROPPED,,,,Sebrán bzukr.,Du samlede en zorcher op.,Zorcher genommen.,,Prenis zorĉilon.,Recogiste un zorcher.,,Poimit zorcherin,Zorcheur récupéré.,Szörcsölő felvéve.,Ho preso uno zorcher.,ゾーチャー をひろった,자쳐 습득.,Je hebt een zorcher opgehaald.,Plukket opp en zorcher.,Zebrano Zorcher,Pegou um zorcher.,,Ai ridicat un zorcher.,Получен Зорчер.,,Bir zorcher aldım. -Zorch and keys added,STSTR_KFAADDED,,,,Bzukr a klíče přidány,Zorch og nøgler tilføjet,Zorch und Schlüssel hinzugefügt.,,Zorĉaĵo kaj ŝlosiloj aldonitaj.,Zorch y llaves añadidas,,Zorch ja avaimet lisätty,Zorch et clés ajoutées.,Szörcs és kulcsok hozzáadva.,Zorch e chiavi aggiunte,ゾーチ と キーがとどいた,저치와 열쇠,Zorch en sleutels toegevoegd,Zorch og nøkler lagt til,Dodano amunicję Zorch i klucze,Zorch e chaves adicionadas,,Zorcher și chei adăugate,Зорч и ключи получены,,Zorch ve anahtarlar eklendi -E1M1: Landing Zone,HUSTR_E1M1,,,,E1M1: Přistávací zóna,E1M1: Landingszone,E1M1: Landezone,,E1M1: Surterejo,E1M1: Zona de Aterrizaje,,E1M1: Laskeutumisalue,E1M1: Zone D'Atterissage,E1M1: Leszállópálya,E1M1: Zona di Atterraggio,E1M1: ちゃくち ちてん,E1M1: 착륙 지점,E1M1: Landingzone,E1M1: Landingssone,E1M1: Strefa Lądowania,E1M1: Zona de Pouso,,E1M1: Zona de Aterizare,E1M1: Зона высадки,,E1M1: İniş Bölgesi -E1M2: Storage Facility,HUSTR_E1M2,,,,E1M2: Skladiště,E1M2: Opbevaringsanlæg,E1M2: Lagerhalle,,E1M2: Stokejo,E1M2: Instalación de Almacenamiento,,E1M2: Varastolaitos,E1M2: Centre de Stockage,E1M2: Raktárépület,E1M2: Struttura di Immagazzinamento,E1M2: ちょぞう しせつ,E1M2: 저장 시설,E1M2: Opslagfaciliteit,E1M2: Lagringsanlegg,E1M2: Magazyn,E1M2: Depósito,,E1M2: Depozitul,E1M2: Хранилище,,E1M2: Depolama Tesisi -E1M3: Laboratory,HUSTR_E1M3,,,,E1M3: Testovací laboratoř,E1M3: Laboratorium,E1M3: Labor,,E1M3: Laboratorio,E1M3: Laboratorio,,E1M3: Laboratorio,E1M3: Laboratoire,E1M3: Laboratórium,E1M3: Laboratorio,E1M3: ラボラトリー,E1M3: 연구소,E1M3: Laboratorium,E1M3: Laboratorium,E1M3: Laboratorium,E1M3: Laboratório de Experimentos,,E1M3: Laboratorul,E1M3: Лаборатория,,E1M3: Laboratuvar -E1M4: Arboretum,HUSTR_E1M4,,,,,,,,E1M4: Arbejo,E1M4: Arboreto,,,E1M4: Arboretum,E1M4: Arborétum,E1M4: Arboreto,E1M4: じゅもく園,E1M4: 수목원,,E1M4: Arboretet,E1M4: Arboretum,E1M4: Arvoredo,,E1M4: Arboretum,E1M4: Дендрарий,, -E1M5: Caverns of Bazoik,HUSTR_E1M5,,,,E1M5: Bazoikské jeskyně,E1M5: Bazoiks grotter,E1M5: Die Höhlen von Bazoik,,E1M5: Kavernoj de Bazojko,E1M5: Cavernas de Bazoik,,E1M5: Bazoikin luolastot,E1M5: Cavernes de Bazoik,E1M5: Bazoik barlangjai,E1M5: Caverne di Bazoik,E1M5: バゾイクのどうくつ,E1M5: 바조이크의 대동굴,E1M5: Grotten van Bazoik,E1M5: Grottene i Bazoik,E1M5: Jaskinie Bazoik,E1M5: Cavernas de Bazoik,,E1M5: Cavernele lui Bazoik,E1M5: Пещеры Базоика,,E1M5: Bazoik Mağaraları -E2M1: Spaceport,HUSTR_E2M1,,,,E2M1: Kosmodrom,E2M1: Rumhavn,E2M1: Raumhafen,,E2M1: Kosmo-haveno,E2M1: Puerto Espacial,,E2M1: Avaruussatama,E2M1: Spatioport,E2M1: Űrkikötő,E2M1: Spazioporto,E2M1: スペースポート,E2M1: 우주공항,E2M1: Ruimtehaven,E2M1: Romhavn,E2M1: Port Kosmiczny,E2M1: Espaçoporto,,E2M1: Portul Spațial,E2M1: Космодром,,E2M1: Uzay Limanı -E2M2: Cinema,HUSTR_E2M2,,,,E2M2: Kino,,E2M2: Kino,,E2M2: Kinejo,E2M2: Cine,,E2M2: Elokuvateatteri,E2M2: Cinéma,E2M2: Mozi,,E2M2: シネマ,E2M2: 극장,E2M2: Bioscoop,E2M2: Kino,E2M2: Kino,E2M2: Cinema,,E2M2: Cinema,E2M2: Кинотеатр,,E2M2: Sinema -E2M3: Chex Museum,HUSTR_E2M3,,,,E2M3: Muzem Chex,,,,E2M3: Chex-muzeo,E2M3: Museo de Chex,,E2M3: Chex-museo,E2M3: Musée Chex,E2M3: Chex-múzeum,E2M3: Museo di Chex,E2M3: チェックス ミュージアム,E2M3: 첵스 박물관,,,E2M3: Muzeum Chex,E2M3: Museu Chex,,E2M3: Muzeul Chex,E2M3: Музей Chex,,E2M3: Chex Müzesi -E2M4: City Streets,HUSTR_E2M4,,,,E2M4: Městské ulice,E2M4: Byens gader,E2M4: städtische Straßen,,E2M4: Urbstratoj,E2M4: Calles de la Ciudad,,E2M4: Kaupungin kadut,E2M4: Rues de la Ville,E2M4: Városi utcák,E2M4: Strade della città,E2M4: シティーストリート,E2M4: 도시 거리,E2M4: Stadsstraten,E2M4: Byens gater,E2M4: Ulice Miasta,E2M4: Ruas da Cidade,,E2M4: Străzile Orașului,E2M4: Городские улицы,,E2M4: Şehir Sokakları -E2M5: Sewer System,HUSTR_E2M5,,,,E2M5: Kanalizace,E2M5: Kloaksystem,E2M5: Kanalisation,,E2M5: Defluilego-sistemo,E2M5: Alcantarillado,,E2M5: Viemärijärjestelmä,E2M5: Système d'égouts,E2M5: Csatornarendszer,E2M5: Rete fognaria,E2M5: サワーシステム,E2M5: 하수도,E2M5: Rioleringssysteem,E2M5: Avløpssystem,E2M5: System Ścieków,E2M5: Rede de Esgoto,,E2M5: Sistemul de Canalizare,E2M5: Канализация,,E2M5: Kanalizasyon Sistemi -E3M1: Central Command,HUSTR_E3M1,,,,E3M1: Centrální velení,E3M1: Centralkommando,E3M1: Kommandozentrale,,E3M1: Centra Komandejo,E3M1: Comando central,,E3M1: Komentokeskus,E3M1: Commandement,E3M1: Központi parancsnokság,E3M1: Comando centrale,E3M1: 中央しれいとう,E3M1: 중앙 사령부,E3M1: Centraal Commando,E3M1: Sentral kommando,E3M1: Centrum Dowodzenia,E3M1: Comando Central,,E3M1: Centrul de Comanda,E3M1: Командный центр,,E3M1: Merkez Komutanlığı -E3M2: United Cereals,HUSTR_E3M2,,,,E3M2: Spojené cereálie,,E3M2: Vereinigte Zerealien,,E3M2: Uniaj Cerealoj,E3M2: Cereales unidos,,E3M2: Yhdistyneet murot,E3M2: Céréales Unies,E3M2: Egyesült Gabonapelyhek,E3M2: Cereali uniti,E3M2: ユナイテッド シリアル,E3M2: 시리얼 연합,E3M2: Verenigde granen,,E3M2: Zjednoczone Płatki,E3M2: Cereais Unidos,,E3M2: Cereale Unite,E3M2: Организация Объединённых Хлопьев,,E3M2: Birleşik Tahıllar -E3M3: Villa Chex,HUSTR_E3M3,,,,,,,,E3M3: Vilao Chex,,,,E3M3: Villa Chex,,,E3M3: チェックスのべっそう,E3M3: 책스 주택,,,E3M3: Willa Chex,E3M3: Villa Chex,,E3M3: Vila Chex,E3M3: Вилла Chex,,E3M3: Villa Chex -E3M4: Provincial Park,HUSTR_E3M4,,,,E3M4: Provinciální park,,E3M4: Provinzpark,,E3M4: Provinca Parko,E3M4: Parque provincial,,E3M4: Provinssipuisto,E3M4: Parc Naturel,E3M4: Tartományi park,E3M4: Parco provinciale,E3M4: 州立公園,E3M4: 주립공원,E3M4: Provinciaal Park,E3M4: Provincial Park,E3M4: Prowincjonalny Park,E3M4: Parque Natural,,E3M4: Parcul Provincial,E3M4: Провинциальный парк,,E3M4: İl Parkı -E3M5: Meteor Spaceship,HUSTR_E3M5,,,,E3M5: Meteorová vesmírná loď,E3M5: Meteor rumskib,E3M5: Meteor-Raumschiff,,E3M5: Meteor-kosmoŝipo,E3M5: Nave Meteoro,,E3M5: Meteoriavaruusalus,E3M5: Vaisseau Météore,E3M5: Meteor űrhajó,E2M5: Astronave meteorica,E3M5: メテオスペースシップ,E3M5: 거대 유성호,E3M5: Ruimteschip,E3M5: Meteor-romskipet,"E3M5: Statek Kosmiczny ""Meteor""",E3M5: Espaçonave Meteoro,,E3M5: Nava Spațială Meteor,E3M5: Космический корабль «Метеор»,,E3M5: Meteor Uzay Gemisi -Commonus,CC_ZOMBIE,,,,Obecnýs,,,,Oftmukulo,,,,,Általánusz,,コモンズ,커머누스,,,Pospolitus,,,Comun,Обыкновеннус,,Commonus -Bipedicus,CC_SHOTGUN,,,,Dvojnožus,,,,Dupiedmukulo,,,,,Kétlábusz,,バイピディクス,바이피디쿠스,,,,,,Biped,Двуножка,,Bipedicus -Bipedicus with Armor,CC_IMP,,,,Dvojnožus s brněním,Bipedicus med rustning,Bipedicus mit Panzerung,,Kirasa Dupiedmukulo,Bipedicus con Armadura,,Panssaroitu bipedicus,Bipedicus avec Armure,Páncélozott kétlábusz,Bipedicus corazzato,アーマードバイピディクス,정예 바이피디쿠스,Bipedicus met harnas,Bipedicus med rustning,Opancerzony Bipedicus,Bipedicus de Armadura,,Biped cu Armură,Бронированная двуножка,,Zırhlı Bipedicus -Stridicus,CC_DEMON,,,,Běhakus,,,,Paŝmukulo,,,,,Lépkedüsz,,ステュリクス,스트리디쿠스,,,,,,Picioare-Lungi,Длинноножка,,Stridicus -Flem Mine,CC_LOST,,,,Slizná mina,,,,Muksentinelo,Flem-Mina,,Limamiina,,Slejmakna,Bomba a Flem,フレムマイン,플렘 지뢰,Flemmijn,Flem Mine,Flemowa Mina,Mina Flem,,Flem Mină,Флем-мина,,Flem Madeni -Super Cycloptis,CC_CACO,,,,Superkykloptus,,,,Supera Ciklopmukulo,,,Supercycloptis,,Szuper Kükloptisz,,スーパーサイクロプティス,슈퍼 사이클롭티스,,Supersykloptis.,Super Cykloptis,,,Super Cicloptic,Супер-циклоптис,,Süper Cycloptis -Maximus,CC_BARON,,,,,,,,Mukulestro,,,,,Maximusz,,マクシムス,맥시무스,,,,Maximus,,Maxim,Максимус,,Maximus -The Flembomination,CC_SPIDER,,,,Slizavnost,Flembominationen,Die Flembomination,,Mukabomeno,La Flembominación,,Limaoikku,La Flembomination,Slejmdormány,La Flembominio,フレンボミネーション,플렘보미네이션,De Flembominatie,Flembominationen,Flembominacja,A Flembominação,,Flembominație,Флемомерзость,,Flembomination -Lord Snotfolus,CC_CYBER,,,,Lord Hlenfujus,,,,Lordo Mukplenulo,Lord Mocofolus,,Herra Räkänokka,Seigneur Morvator,Lord Takony,,ロード スノフォールス,스놋폴러스 마왕,,,Lord Smarkofolus,Lorde Snotfolus,,Lordul Snotfolus,Лорд Соплезелёнус,,Lord Snotfolus -Chex Warrior,CC_HERO,,,,Bojovník Chex,Chex Kriger,Chex Krieger,,Chex-batalisto,,,Chex-soturi,Guerrier Chex,Chex harcos,Guerriero Chex,チェックスのせんし,첵스 전사,Chex Krijger,Chex-krigeren,Wojownik Chex,Guerreiro Chex,,Războinic Chex,Воин Chex,,Chex Savaşçısı -You need a blue key to open this door,PD_BLUEC,,,,Potřebuješ modrý klíč pro otevření těchto dveří,Du skal bruge en blå nøgle for at åbne denne dør,"Du brauchst einen blauen Schlüssel, um diese Tür zu öffnen.",,Vi bezonas bluan ŝlosilon por malfermi ĉi tiun pordon.,Necesitas una llave azul para abrir esta puerta,,Tarvitset sinisen avaimen avataksesi tämän oven,Il vous faut une clé bleue pour ouvrir cette porte.,Kell egy kék kulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave blu per aprire questa porta,このとびらは ブルー キー がひつようだ,이 문을 열려면 청색 열쇠가 필요합니다,Je hebt een blauwe sleutel nodig om deze deur te openen.,Du trenger en blå nøkkel for å åpne denne døren,"Potrzebujesz niebieskiego klucza, aby otworzyć te drzwi",Você precisa de uma chave azul para abrir essa porta,,Ai nevoie de o cheie albastră pentru a deschide ușa aceasta,"Нужен синий ключ, чтобы открыть",Треба вам плави кључ да бисте отворили ова врата,Bu kapıyı açmak için mavi bir anahtara ihtiyacın var. -You need a red key to open this door,PD_REDC,,,,Potřebuješ červený klíč pro otevření těchto dveří,Du skal bruge en rød nøgle for at åbne denne dør,"Du brauchst einen roten Schlüssel, um diese Tür zu öffnen.",,Vi bezonas ruĝan ŝlosilon por malfermi ĉi tiun pordon.,Necesitas una llave roja para abrir esta puerta,,Tarvitset punaisen avaimen avataksesi tämän oven,Il vous faut une clé rouge pour ouvrir cette porte.,Kell egy piros kulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave rossa per aprire questa porta,このとびらは レッド キー がひつようだ,이 문을 열려면 적색 열쇠가 필요합니다,Je hebt een rode sleutel nodig om deze deur te openen.,Du trenger en rød nøkkel for å åpne denne døren,"Potrzebujesz czerwonego klucza, aby otworzyć te drzwi",Você precisa de uma chave vermelha para abrir essa porta,,Ai nevoie de o cheie roșie pentru a deschide ușa aceasta,"Нужен красный ключ, чтобы открыть",Треба вам црвени кључ да бисте отворили ова врата,Bu kapıyı açmak için kırmızı bir anahtara ihtiyacın var. -You need a yellow key to open this door,PD_YELLOWC,,,,Potřebuješ žlutý klíč pro otevření těchto dveří,Du skal bruge en gul nøgle for at åbne denne dør,"Du brauchst einen gelben Schlüssel, um diese Tür zu öffnen.",,Vi bezonas flavan ŝlosilon por malfermi ĉi tiun pordon.,Necesitas una llave amarilla para abrir esta puerta,,Tarvitset keltaisen avaimen avataksesi tämän oven,Il vous faut une clé jaune pour ouvrir cette porte.,Kell egy sárga kulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave gialla per aprire questa porta,このとびらは イエローキー がひつようだ,이 문을 열려면 황색 열쇠가 필요합니다,Je hebt een gele sleutel nodig om deze deur te openen.,Du trenger en gul nøkkel for å åpne denne døren,"Potrzebujesz żółtego klucza, aby otworzyć te drzwi",Você precisa de uma chave amarela para abrir essa porta,,Ai nevoie de o cheie galbenă pentru a deschide ușa aceasta,"Нужен жёлтый ключ, чтобы открыть",Треба вам жути кључ да бисте отворили ова врата,Bu kapıyı açmak için sarı bir anahtara ihtiyacınız var -You need a blue flemkey to open this door,PD_BLUEF,,,,Potřebuješ modrý slizoklíč pro otevření těchto dveří,Du skal bruge en blå flemkey for at åbne denne dør,"Du brauchst einen blauen Flemschlüssel, um diese Tür zu öffnen.",,Vi bezonas bluan mukŝlosilon por malfermi ĉi tiun pordon.,Necesitas una flemllave azul para abrir esta puerta,,Tarvitset sinisen lima-avaimen avataksesi tämän oven,Il vous faut une flemclé bleue pour ouvrir cette porte.,Kell egy kék slejmkulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave-flem blu per aprire questa porta,このとびらは ブルー キーがひつようだ,이 문을 열려면 청색 플렘열쇠가 필요합니다,Je hebt een blauwe flemsleutel nodig om deze deur te openen.,Du trenger en blå flemkey for å åpne denne døren,"Potrzebujesz niebieskiego flemowego klucza, aby otworzyć te drzwi",Você precisa de uma flemchave azul para ativar este objeto,,Ai nevoie de o flemcheie albastră pentru a deschide ușa aceasta,"Нужен синий флемключ, чтобы открыть",,Bu kapıyı açmak için mavi bir flemkey'e ihtiyacın var. -You need a red flemkey to open this door,PD_REDF,,,,Potřebuješ červený slizoklíč pro otevření těchto dveří,Du skal bruge en rød flemkey for at åbne denne dør,"Du brauchst einen roten Flemschlüssel, um diese Tür zu öffnen.",,Vi bezonas ruĝan mukŝlosilon por malfermi ĉi tiun pordon.,Necesitas una flemllave roja para abrir esta puerta,,Tarvitset punaisen lima-avaimen avataksesi tämän oven,Il vous faut une flemclé rouge pour ouvrir cette porte.,Kell egy piros slejmkulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave-flem rossa per aprire questa porta,このとびらは レッド キーがひつようだ,이 문을 열려면 적색 플렘열쇠가 필요합니다,Je hebt een rode flemsleutel nodig om deze deur te openen.,Du trenger en rød flemkey for å åpne denne døren,"Potrzebujesz czerwonego flemowego klucza, aby otworzyć te drzwi",Você precisa de uma flemchave vermelha para ativar este objeto,,Ai nevoie de o flemcheie roșie pentru a deschide ușa aceasta,"Нужен красный флемключ, чтобы открыть",,Bu kapıyı açmak için kırmızı bir flemkey'e ihtiyacın var. -You need a yellow flemkey to open this door,PD_YELLOWF,,,,Potřebuješ žlutý slizoklíč pro otevření těchto dveří,Du har brug for en gul flemkey for at åbne denne dør,"Du brauchst einen gelben Flemschlüssel, um diese Tür zu öffnen.",,Vi bezonas flavan mukŝlosilon por malfermi ĉi tiun pordon.,Necesitas una flemllave amarilla para abrir esta puerta,,Tarvitset keltaisen lima-avaimen avataksesi tämän oven,Il vous faut une flemclé jaune pour ouvrir cette porte.,Kell egy sárga slejmkulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave-flem gialla per aprire questa porta,このとびらは イエローキーがひつようだ,이 문을 열려면 황색 플렘열쇠가 필요합니다,Je hebt een gele flemsleutel nodig om deze deur te openen.,Du trenger en gul flemkey for å åpne denne døren,"Potrzebujesz żółtego flemowego klucza, aby otworzyć te drzwi",Você precisa de uma flemchave amarela para ativar este objeto,,Ai nevoie de o flemcheie galbenă pentru a deschide ușa aceasta,"Нужен жёлтый флемключ, чтобы открыть",,Bu kapıyı açmak için sarı bir flemkey'e ihtiyacın var. -%o sinks into some slime.,OB_SLIME,,,,%o se propadl@[ao_cs] do slizu.,%o synker ned i noget slim.,%o versank im Schleim,,%o malflosas subeniras en kelkan ŝlimon.,%o se hunde en babas.,,%o uppoaa limaan,%o se noie dans la morve.,%o elsüllyedt a trutyiban.,%o affonda in qualche melma.,%o はスライムにしずんだ。,%o 는(은) 점액 속으로 가라앉았습니다.,%o zinkt in wat slijm.,%o synker ned i noe slim.,%o topi się w szlamie.,%o afundou na gosma.,,%o se scufundă în mâzgă.,Игрок %o утонул в слизи.,,%o balçığın içine battı. -%o sinks into some slime.,OB_LAVA,,,,%o se propadl@[ao_cs] do slizu.,%o synker ned i noget slim.,%o versank im Schleim,,%o malflosas subeniras en kelkan ŝlimon.,%o se hunde en babas.,,%o uppoaa limaan,%o se noie dans la morve.,%o elsüllyedt a trutyiban.,%o affonda in qualche melma.,%o はスライムにしずんだ。,%o 는(은) 질척하게 가라앉았습니다.,%o zinkt in wat slijm.,%o synker ned i noe slim.,%o topi się w szlamie.,%o afundou na gosma.,,%o se scufundă în mâzgă.,Игрок %o утонул в слизи.,,%o balçığın içine battı. -%o was hit by inter-dimensional slime!,OB_POWERSTRAND,,,,%o byl@[ao_cs] zasažen@[ao_cs] mezidimenzionálním slizem!,%o blev ramt af interdimensionalt slim!,%o wurde von interdimensionalem Schleim getroffen,,%o estas trafita de interdimensia ŝlimo!,¡%o fue alcanzad@[ao_esp] por baba interdimensional!,,%o parkaan osui interdimensionaalista limaa!,%o s'est fait@[e_fr] toucher par de la morve interdimensionelle!,%o interdimenzionális trutyi áldozata lett!,%o è stato colpito da melma interdimensionale!,%o は いじげんスライムまみれになった!,%o 는(은) 차원균열 점액에 맞았습니다!,%o werd geraakt door interdimensionaal slijm!,%o ble truffet av interdimensjonalt slim!,%o został@[ao_pl] uderzon@[adj_pl] przez międzywymiarowy szlam!,%o foi atingid@[ao_ptb] por gosma interdimensional!,,%o a fost lovit de mâzgă interdimensională!,В игрока %o попала межпространственная слизь!,,%o boyutlar arası balçık tarafından vuruldu! -%o was hit by inter-dimensional slime!,OB_KILLEDSELF,,,,%o byl@[ao_cs] zasažen@[ao_cs] mezidimenzionálním slizem!,%o blev ramt af interdimensionalt slim!,%o wurde von interdimensionalem Schleim getroffen,,%o estas trafita de interdimensia ŝlimo!,¡%o fue alcanzad@[ao_esp] por baba interdimensional!,,%o parkaan osui interdimensionaalista limaa!,%o s'est fait@[e_fr] toucher par de la morve interdimensionelle!,%o interdimenzionális trutyi áldozata lett!,%o è stato colpito da melma interdimensionale!,%o は いじげんスライムまみれになった!,%o 는(은) 모르는 사이에 점액에 당했습니다!,%o werd geraakt door interdimensionaal slijm!,%o ble truffet av interdimensjonalt slim!,%o został@[ao_pl] uderzon@[adj_pl] przez międzywymiarowy szlam!,%o foi atingid@[ao_ptb] por gosma interdimensional!,,%o a fost lovit de mâzgă interdimensională!,В игрока %o попала межпространственная слизь!,,%o boyutlar arası balçık tarafından vuruldu! -%o was boogered by a stridicus.,OB_STRIDICUS,,,,%o dostal@[ao_cs] holuby od běhakem.,%o blev buogered af en stridicus.,%o wurde von einem Stridicus bepopelt.,,%o estas mukiga de paŝmukulo.,%o fue moquead@[ao_esp] por un stridicus.,,%o joutui stridicuksen räkäämäksi.,%o s'est fait@[e_fr] engluer par un stridicus.,%o taknyos lett egy lépkedüsztől.,%o è stato colpito da uno Stridicus.,%o は ステュリクスに おびやかされた。,%o 는(은) 스트리디쿠스의 코딱지에 당했습니다.,%o werd door een stridicus gezoomd.,%o ble bæsjet av en stridicus.,%o został@[ao_pl] zaglutowan@[adj_pl] przez stridicusa.,%o foi melecad@[ao_ptb] por um stridicus.,,%o a fost speriat de către un picioare-lungi.,Игрока %o облепила соплями длинноножка. ,,%o bir stridicus tarafından avlandı. -%o was gooed by a flem mine.,OB_FLEMMINE,,,,%o byl@[ao_cs] zablácen@[ao_cs] sliznou minou.,%o blev smittet af en flem mine.,%o wurde von einer Flem-Mine beschmiert.,,%o estas ŝlimiga de muksentinelo.,%o fue pegotead@[ao_esp] por una flem-mina.,,%o joutui limamiinan mönjäämäksi.,%o s'est fait@[e_fr] éclabousser par une flem mine.,%o-t összenyálkázta egy slejmakna.,%o è stato colpito da una bomba a flem.,%o はフレムマインに ヒドいめにあった。,%o 는(은) 플렘 지뢰에 의해 점액 범벅이 됐습니다.,%o werd door een Flemmijn getreiterd.,%o ble gooed av en flem mine.,"%o został@[ao_pl] zabrejowan@[adj_pl] przez flemową minę. -",%o foi engosmad@[ao_ptb] por uma mina flem.,,%o a fost lovit de mâzga unei flem mine.,Игрока %o забрызгала флем-мина.,,%o bir flem mayını tarafından yapışkan hale getirildi. -%o was slimed by a super cycloptis.,OB_SUPERCYCLOPTIS,,,,%o byl@[ao_cs] osliznut@[ao_cs] superkykloptem.,%o blev slimet af en super cycloptis.,%o wurde von einem Super Cycloptis vollgeschleimt.,,%o estas ŝlimiga de supera ciklopmukulo.,%o fue enlodad@[ao_esp] por un super cycloptis.,,%o joutui supercycloptiksen limaamaksi.,%o s'est fait@[e_fr] gélifier par un super cycloptis.,%o-t összenyálkázta egy Szuper Kükloptisz.,%o è stato snellito da una Super Ciyloptis.,%o はスーパーサイクロプティスに とかされた。,%o 는(은) 슈퍼 사이클롭티스의 점액에 당했습니다.,%o werd afgeslankt door een Super Cycloptis.,%o ble slimet av en supersykloptis.,%o został@[ao_pl] oszlamion@[adj_pl] przez super cykloptisa.,%o foi lambuzad@[ao_ptb] por um super cyclóptis.,,%o a fost transformat în mâzgă de către un super cicloptic.,Игрока %o обслюнявил супер-циклоптис.,,%o bir süper sikloptis tarafından sümüklendi. -%o was defeated by a Maximus.,OB_MAXIMUS,,,,%o byl@[ao_cs] poražen@[ao_cs] Maximem.,%o blev besejret af en Maximus.,%o wurde von einem Maximus besiegt.,,%o estas venkita de ĉefmukulo.,%o fue derrotad@[ao_esp] por un Maximus.,,%o joutui Maximuksen päihittämäksi.,%o s'est fait@[e_fr] battre par un Maximus.,%o-t legyőzte egy Maximusz.,%o è stato sconfitto da un Maximus.,%o はマクシムスに 敗北した。,%o 는(은) 맥시무스에게 패배했습니다.,%o werd verslagen door een Maximus.,%o ble beseiret av en Maximus.,%o został@[ao_pl] pokonan@[adj_pl] przez Maximusa.,%o foi derrotad@[ao_ptb] por um Maximus.,,%o a fost înfrânt de către un Maxim.,Игрок %o проиграл Максимусу.,,%o bir Maximus tarafından yenildi. -%o was gooed by a larva.,OB_LARVA,,,,%o byl@[ao_cs] zacáknut@[ao_cs] larvou.,%o blev smurt af en larve.,%o wurde von einer Larve beschmiert.,,%o estas ŝlimiga de larvo.,%o fue pegotead@[ao_esp] por una larva.,,%o joutui toukan mönjäämäksi.,%o s'est fait@[e_fr] tacher par une larve.,%o lárvatrutyit kapott a nyakába.,%o è stato colpito da una larva.,%o はラーバに ヒドいめにあわされた。,%o 는(은) 애벌레에 의해 점액 범벅이 됐습니다.,%o werd door een Larve weggegooid.,%o ble gooed av en larve.,%o został@[ao_pl] zabrejowan@[adj_pl] przez larwę.,%o foi engosmad@[ao_ptb] por uma larva.,,%o a fost lovit de mâzga unei larve.,Игрока %o обслюнявила личинка.,,%o bir larva tarafından öldürüldü. -%o was slimed by a Quadrumpus.,OB_QUADRUMPUS,,,,%o byl@[ao_cs] zahleněn@[ao_cs] Čtyřzadkem.,%o blev slimet af en Quadrumpus.,%o wurde von einem Quadrumpus vollgeschleimt.,,%o estas ŝlimiga de kvarbrakmukulo.,%o fue enlodad@[ao_esp] por un Quadrumpus.,,%o joutui Neliperän limaamaksi.,%o s'est fait@[e_fr] morver par un quadrumpus.,%o-t összenyálkázta egy Négylábusz.,%o è stato ridotto da un Quadrumpus.,%o はクワッドロンプスに スライムにされた。,%o 는(은) 쿼드럼푸스의 점액에 당했습니다.,%o werd afgeslankt door een Quadrumpus.,%o ble slimet av en Quadrumpus.,%o został@[ao_pl] oszlamion@[adj_pl] przez Quadrumpusa.,%o foi melecad@[ao_ptb] por um Quadrumpus.,,%o a fost transformat în mâzgă de către o creatură cu patru mâini,Игрока %o обслюнявила многоручка. ,,%o bir Quadrumpus tarafından zayıflatıldı. -%o was defeated by the Flembomination.,OB_FLEMBOMINATION,,,,%o byl@[ao_cs] poražen@[ao_cs] Slizavností.,%o blev besejret af Flembomination.,%o wurde von der Flembomination besiegt.,,%o estas venkita de la Mukabomeno.,%o fue derrotad@[ao_esp] por la Flembominación.,,%o joutui Limaoikun päihittämäksi.,%o s'est fait@[e_fr] éliminer par la Flembomination.,%o-t legyőzte a Slejmdormány.,%o è stato sconfitto dalla Flembomination.,%o はフレンボミネーションに敗北した。,%o 는(은) 플렘보미네이션으로부터 벗어날 수 없었습니다.,%o werd verslagen door de Flembominatie.,%o ble beseiret av Flembominationen.,%o został@[ao_pl] pokonan@[adj_pl] przez Flembominację.,%o foi derrotad@[ao_ptb] pela Flembominação.,,%o a fost învins de către Flembominație.,Игрока %o победила Флемомерзость.,,"%o, Flembomination tarafından yenildi." -%o was defeated by Lord Snotfolus.,OB_SNOTFOLUS,,,,%o byl@[ao_cs] poražen@[ao_cs] Lordem Hlenfujem.,%o blev besejret af Lord Snotfolus.,%o wurde von Lord Snotfolus besiegt.,,%o estas venkita de Lordo Mukplenulo.,%o fue derrotad@[ao_esp] por Lord Mocofolus.,,%o joutui herra Räkänokan päihittämäksi.,%o est tombé@[e_fr] face au Seigneur Morvator.,%o legyőzetett Lord Takony által.,%o è stato sconfitto da Lord Snotfolus.,%o はロード スノフォールスに敗北した。,%o 는(은) 스놋폴러스 마왕과 싸울 준비를 제대로 하지 못했습니다.,%o werd verslagen door Lord Snotfolus.,%o ble beseiret av Lord Snotfolus.,%o został@[ao_pl] pokonan@[adj_pl] przez Lorda Smarkofolusa.,%o foi derrotad@[ao_ptb] pelo Lorde Snotfolus.,,%o a fost pus la pământ de către Lordul Snotfolus.,Игрока %o победил лорд Соплезелёнус.,,"%o, Lord Snotfolus tarafından yenildi." -%o was hit by %k's propulsor.,OB_MPR_SPLASH,,,,%o byl@[ao_cs] zasažen@[ao_cs] propulzorem hráče %k.,%o blev ramt af %ks propulsor.,%o wurde von %ks Propeller getroffen,,%o estas trafita de la propulsilo de %k.,%o fue alcanzad@[ao_esp] por el propulsor de %k.,,%k osui %o parkaan työntimellään.,%o s'est fait@[e_fr] propulser par %k.,%o-t eltalálta %k hajtóműve.,%o è stato colpito dal propulsore di %k.,%o に %k のロケットゾーチがとどいた。,%o 는(은) %k 의 추진력에 휘말렸습니다.,%o werd geraakt door %k's propulsor.,%o ble truffet av %ks propulsor.,%o został@[ao_pl] uderzon@[adj_pl] przez pędnik %k.,%o foi atingid@[ao_ptb] pelo propulsor de %k.,,%o a fost lovit de către propulsorul lui %k.,Игрок %o подстрелен из ускорителя Зорча %k.,,"%o, %k tarafından vuruldu." -%o was lazzed by %k.,OB_MPBFG_SPLASH,,,,%o byl@[ao_cs] odlazován@[ao_cs] hráčem %k.,%o blev lazzed af %k.,%o wurde von %o weggezorcht.,,%o estas LAZ-ita de %k.,%o fue lazead@[ao_esp] por %k.,,%k sazzasi pelaajaan %o.,%o est entré@[e_fr] dans la zone de zorchage large de %k.,%o-t szörcsölődött %k által.,%o è stato lazzato da %k.,%o は %k にとかされた。,%o 는(은) %k 에게 레이져를 쐬였습니다.,%o werd gelazzed door %k.,%o ble lazzed av %k.,%o został@[ao_pl] zLAZowan@[adj_pl] przez %k.,%o foi LAZead@[ao_ptb] por %k.,,%k a folosit dispozitivul LAZ pe %o.,Игрок %o получил заряд из «ЗБР» игрока %k.,,"%o, %k tarafından lazzlandı." +default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,sv,tr +Picked up a blue flemkey.,GOTBLUEFLEM,Flem = phlegm,,,Sebrán modrý slizoklíč.,Du samlede en blå flemkey op.,Blauen Flemschlüssel genommen,,Prenis bluan mukŝlosilon.,Recogiste una flemllave azul.,,Poimit sinisen lima-avaimen,Flemclé bleue récupérée.,Kék slejmkulcs felvéve.,Raccolta una chiave-flem blu.,ブルー フレムキー をみつけた,청색 플렘열쇠 획득.,Je hebt een blauwe flemsleutel opgehaald.,Plukket opp en blå flemkey.,Zebrano niebieski flemowy klucz,Pegou uma flemchave azul.,,Ai ridicat flemcheia albastră.,Получен синий флемключ.,,Plockade upp en blå flemnyckel.,Mavi bir flemkey aldım. +Picked up a yellow flemkey.,GOTYELLOWFLEM,,,,Sebrán žlutý slizoklíč.,Du samlede en gul flemkey op.,Gelben Flemschlüssel genommen,,Prenis flavan mukŝlosilon.,Recogiste una flemllave amarilla.,,Poimit keltaisen lima-avaimen,Flemclé jaune récupérée.,Sárga slejmkulcs felvéve.,Raccolta una chiave-flem gialla.,イエローフレムキー をみつけた,황색 플렘열쇠 획득.,Je hebt een gele flemsleutel opgehaald.,Plukket opp en gul flemkey.,Zebrano żółty flemowy klucz,Pegou uma flemchave amarela.,,Ai ridicat flemcheia galbenă.,Получен жёлтый флемключ.,,Plockade upp en gul flemnyckel.,Sarı bir flemkey aldı. +Picked up a red flemkey.,GOTREDFLEM,,,,Sebrán červený slizoklíč.,Du samlede en rød flemkey op.,Roten Flemschlüssel genommen.,,Prenis ruĝan mukŝlosilon.,Recogiste una flemllave roja.,,Poimit punaisen lima-avaimen,Flemclé rouge récupérée.,Piros slejmkulcs felvéve.,Raccolta una chiave-flem rossa.,レッド フレムキー をみつけた,적색 플렘열쇠 획득.,Je hebt een rode flemsleutel opgehaald.,Plukket opp en rød flemkey.,Zebrano czerwony flemowy klucz,Pegou uma flemchave vermelha.,,Ai ridicat flemcheia roșie.,Получен красный флемключ.,,Plockade upp en röd flemnyckel.,Kırmızı bir flemkey aldı. +Found Ultra Goggles,GOTGOGGLES,,,,Nalezeny ultrabrýle.,Fandt Ultra Goggles,Ultrasichtbrille gefunden,,Trovis Plejajn Okulvitrojn.,Ultra Gafas encontradas,Ultralentes encontrados,Löysit ultralasit,Ultra-lunettes récupérées.,Ultraszemüveg felvéve.,,ウルトラゴーグル をみつけた,울트라 고글 사용.,Ultraroggles gevonden,Fant Ultra Goggles,Znaleziono Ultra Gogle,Achou um Ultra Óculos.,,Ai găsit Ultra Ochelarii,Получены ультра-очки,,Hittade Ultra Goggles,Ultra Gözlük bulundu +You need a blue key to activate this object,PD_BLUECO,,,,Potřebuješ modrý klíč pro aktivaci tohoto objektu,Du skal bruge en blå nøgle for at aktivere dette objekt,"Du brauchst einen blauen Schlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas bluan ŝlosilon por aktivigi ĉi tiun objekton.,Necesitas una llave azul para activar este objeto,,Tarvitset sinisen avaimen aktivoidaksesi tämän kappaleen,Il vous faut une clé bleue pour activer cet objet.,Egy kék kulcs szükséges az objektum aktiválásához.,Ti serve una chiave blu per attivare questo oggetto,このそうちは ブルー キー がひつようだ,이걸 작동하려면 청색 열쇠가 필요합니다,Je hebt een blauwe sleutel nodig om dit object te activeren.,Du trenger en blå nøkkel for å aktivere dette objektet,"Potrzebujesz niebieskiego klucza, aby aktywować ten przedmiot",Você precisa de uma chave azul para ativar este objeto,,Ai nevoie de o cheie albastră pentru a activa acest obiect,Для открытия требуется синий ключ,Треба вам плави кључ да бисте активирали овај предмет,Du behöver en blå nyckel för att aktivera det här objektet.,Bu nesneyi etkinleştirmek için mavi bir anahtara ihtiyacınız var +You need a red key to activate this object,PD_REDCO,,,,Potřebuješ červený klíč pro aktivaci tohoto objektu,Du skal bruge en rød nøgle for at aktivere dette objekt,"Du brauchst einen roten Schlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas ruĝan ŝlosilon por aktivigi ĉi tiun objekton.,Necesitas una llave roja para activar este objeto,,Tarvitset punaisen avaimen aktivoidaksesi tämän kappaleen,Il vous faut une clé rouge pour activer cet objet.,Egy piros kulcs szükséges az objektum aktiválásához.,Ti serve una chiave rossa per attivare questo oggetto,このそうちは レッド キー がひつようだ,이걸 작동하려면 적색 열쇠가 필요합니다,Je hebt een rode sleutel nodig om dit object te activeren.,Du trenger en rød nøkkel for å aktivere denne gjenstanden,"Potrzebujesz czerwonego klucza, aby aktywować ten przedmiot",Você precisa de uma chave vermelha para ativar este objeto,,Ai nevoie de o cheie roșie pentru a activa acest obiect,Для открытия требуется красный ключ,Треба вам црвени кључ да бисте активирали овај предмет,Du behöver en röd nyckel för att aktivera det här objektet.,Bu nesneyi etkinleştirmek için kırmızı bir anahtara ihtiyacınız var +You need a yellow key to activate this object,PD_YELLOWCO,,,,Potřebuješ žlutý klíč pro aktivaci tohoto objektu,Du skal bruge en gul nøgle for at aktivere dette objekt,"Du brauchst einen gelben Schlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas flavan ŝlosilon por aktivigi ĉi tiun objekton.,Necesitas una llave amarilla para activar este objeto,,Tarvitset keltaisen avaimen aktivoidaksesi tämän kappaleen,Il vous faut une clé jaune pour activer cet objet.,Egy sárga kulcs szükséges az objektum aktiválásához.,Ti serve una chiave gialla per attivare questo oggetto,このそうちは イエローキー がひつようだ,이걸 작동하려면 황색 열쇠가 필요합니다,Je hebt een gele sleutel nodig om dit object te activeren.,Du trenger en gul nøkkel for å aktivere denne gjenstanden,"Potrzebujesz żółtego klucza, aby aktywować ten przedmiot",Você precisa de uma chave amarela para ativar este objeto,,Ai nevoie de o cheie galbenă pentru a activa acest obiect,Для открытия требуется жёлтый ключ,Треба вам жути кључ да бисте активирали овај предмет,Du behöver en gul nyckel för att aktivera det här objektet.,Bu nesneyi etkinleştirmek için sarı bir anahtara ihtiyacınız var +You need a blue flemkey to activate this object,PD_BLUEFO,,,,Potřebuješ modrý slizoklíč pro aktivaci tohoto objektu.,Du skal bruge en blå flemkey for at aktivere dette objekt,"Du brauchst einen blauen Flemschlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas bluan mukŝlosilon por aktivigi ĉi tiun objekton.,Necesitas una flemllave azul para activar este objeto,,Tarvitset sinisen lima-avaimen aktivoidaksesi tämän kappaleen,Il vous faut une flemclé bleue pour activer cet objet.,Egy kék slejmkulcs szükséges az objektum aktiválásához.,Ti serve una chiave-flem blu per attivare questo oggetto,このそうちは ブルー キーがひつようだ,이걸 작동하려면 청색 플렘열쇠가 필요합니다,Je hebt een blauwe flemsleutel nodig om dit object te activeren.,Du trenger en blå flemkey for å aktivere denne gjenstanden.,"Potrzebujesz niebieskiego flemowego klucza, aby aktywować ten przedmiot",Você precisa de uma flemchave azul para ativar este objeto,,Ai nevoie de o flemcheie albastră pentru a activa acest obiect,Для открытия требуется синий флемключ,,Du behöver en blå flemnyckel för att aktivera det här objektet.,Bu nesneyi etkinleştirmek için mavi bir flemkey'e ihtiyacınız var +You need a red flemkey to activate this object,PD_REDFO,,,,Potřebuješ červený slizoklíč pro aktivaci tohoto objektu.,Du skal bruge en rød flemkey for at aktivere dette objekt,"Du brauchst einen roten Flemschlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas ruĝan mukŝlosilon por aktivigi ĉi tiun objekton.,Necesitas una flemllave roja para activar este objeto,,Tarvitset punaisen lima-avaimen aktivoidaksesi tämän kappaleen,Il vous faut une flemclé rouge pour activer cet objet.,Egy piros slejmkulcs szükséges az objektum aktiválásához.,Ti serve una chiave-flem rossa per attivare questo oggetto,このそうちは レッド キーがひつようだ,이걸 작동하려면 적색 플렘열쇠가 필요합니다,Je hebt een rode flemsleutel nodig om dit object te activeren.,Du trenger en rød flemkey for å aktivere dette objektet.,"Potrzebujesz czerwonego flemowego klucza, aby aktywować ten przedmiot",Você precisa de uma flemchave vermelha para ativar este objeto,,Ai nevoie de o flemcheie roșie pentru a activa acest obiect,Для открытия требуется красный флемключ,,Du behöver en röd flemnyckel för att aktivera det här objektet.,Bu nesneyi etkinleştirmek için kırmızı bir flemkey'e ihtiyacınız var +You need a yellow flemkey to activate this object,PD_YELLOWFO,,,,Potřebuješ žlutý slizoklíč pro aktivaci tohoto objektu.,Du skal bruge en gul flemkey for at aktivere dette objekt,"Du brauchst einen gelben Flemschlüssel, um dieses Objekt zu aktivieren.",,Vi bezonas flavan mukŝlosilon por aktivigi ĉi tiun objekton.,Necesitas unaflemllave amarilla para activar este objeto,,Tarvitset keltaisen lima-avaimen aktivoidaksesi tämän kappaleen,Il vous faut une flemclé jaune pour activer cet objet.,Egy sárga slejmkulcs szükséges az objektum aktiválásához.,Ti serve una chiave-flem gialla per attivare questo oggetto,このそうちは イエローキーがひつようだ,이걸 작동하려면 황색 플렘열쇠가 필요합니다,Je hebt een gele flemsleutel nodig om dit object te activeren.,Du trenger en gul flemkey for å aktivere dette objektet.,"Potrzebujesz żółtego flemowego klucza, aby aktywować ten przedmiot",Você precisa de uma flemchave amarela para ativar este objeto,,Ai nevoie de o flemcheie galbenă pentru a activa acest obiect,Для открытия требуется жёлтый флемключ,,Du behöver en gul flemnyckel för att aktivera det här objektet.,Bu nesneyi etkinleştirmek için sarı bir flemkey'e ihtiyacınız var +Picked up a zorcher.,PICKUP_PISTOL_DROPPED,,,,Sebrán bzukr.,Du samlede en zorcher op.,Zorcher genommen.,,Prenis zorĉilon.,Recogiste un zorcher.,,Poimit zorcherin,Zorcheur récupéré.,Szörcsölő felvéve.,Ho preso uno zorcher.,ゾーチャー をひろった,자쳐 습득.,Je hebt een zorcher opgehaald.,Plukket opp en zorcher.,Zebrano Zorcher,Pegou um zorcher.,,Ai ridicat un zorcher.,Получен зорчер.,,Plockade upp en zorcher.,Bir zorcher aldım. +Zorch and keys added,STSTR_KFAADDED,,,,Bzukr a klíče přidány,Zorch og nøgler tilføjet,Zorch und Schlüssel hinzugefügt.,,Zorĉaĵo kaj ŝlosiloj aldonitaj.,Zorch y llaves añadidas,,Zorch ja avaimet lisätty,Zorch et clés ajoutées.,Szörcs és kulcsok hozzáadva.,Zorch e chiavi aggiunte,ゾーチ と キーがとどいた,저치와 열쇠,Zorch en sleutels toegevoegd,Zorch og nøkler lagt til,Dodano amunicję Zorch i klucze,Zorch e chaves adicionadas,,Zorcher și chei adăugate,Зорч и ключи получены,,Zorch och nycklar har lagts till,Zorch ve anahtarlar eklendi +E1M1: Landing Zone,HUSTR_E1M1,,,,E1M1: Přistávací zóna,E1M1: Landingszone,E1M1: Landezone,,E1M1: Surteriĝejo,E1M1: Zona de aterrizaje,,E1M1: Laskeutumisalue,E1M1: Zone D'Atterissage,E1M1: Leszállópálya,E1M1: Zona di Atterraggio,E1M1: ちゃくち ちてん,E1M1: 착륙 지점,E1M1: Landingzone,E1M1: Landingssone,E1M1: Strefa Lądowania,E1M1: Zona de Pouso,,E1M1: Zona de Aterizare,E1M1: Зона высадки,,E1M1: Landningszon,E1M1: İniş Bölgesi +E1M2: Storage Facility,HUSTR_E1M2,,,,E1M2: Skladiště,E1M2: Opbevaringsanlæg,E1M2: Lagerhalle,,E1M2: Stokejo,E1M2: Instalación de almacenamiento,,E1M2: Varastolaitos,E1M2: Centre de Stockage,E1M2: Raktárépület,E1M2: Struttura di Immagazzinamento,E1M2: ちょぞう しせつ,E1M2: 저장 시설,E1M2: Opslagfaciliteit,E1M2: Lagringsanlegg,E1M2: Magazyn,E1M2: Depósito,,E1M2: Depozitul,E1M2: Хранилище,,E1M2: Förvaringsanläggning,E1M2: Depolama Tesisi +E1M3: Laboratory,HUSTR_E1M3,,,,E1M3: Testovací laboratoř,E1M3: Laboratorium,E1M3: Labor,,E1M3: Laboratorio,E1M3: Laboratorio,,E1M3: Laboratorio,E1M3: Laboratoire,E1M3: Laboratórium,E1M3: Laboratorio,E1M3: ラボラトリー,E1M3: 연구소,E1M3: Laboratorium,E1M3: Laboratorium,E1M3: Laboratorium,E1M3: Laboratório de Experimentos,,E1M3: Laboratorul,E1M3: Лаборатория,,E1M3: Laboratorium,E1M3: Laboratuvar +E1M4: Arboretum,HUSTR_E1M4,,,,,,,,E1M4: Arbejo,E1M4: Arboreto,,,,E1M4: Arborétum,E1M4: Arboreto,E1M4: じゅもく園,E1M4: 수목원,,E1M4: Arboretet,E1M4: Arboretum,E1M4: Arvoredo,,,E1M4: Дендрарий,,, +E1M5: Caverns of Bazoik,HUSTR_E1M5,,,,E1M5: Bazoikské jeskyně,E1M5: Bazoiks grotter,E1M5: Die Höhlen von Bazoik,,E1M5: Kavernoj de Bazojko,E1M5: Cavernas de Bazoik,,E1M5: Bazoikin luolastot,E1M5: Cavernes de Bazoik,E1M5: Bazoik barlangjai,E1M5: Caverne di Bazoik,E1M5: バゾイクのどうくつ,E1M5: 바조이크의 대동굴,E1M5: Grotten van Bazoik,E1M5: Grottene i Bazoik,E1M5: Jaskinie Bazoik,E1M5: Cavernas de Bazoik,,E1M5: Cavernele lui Bazoik,E1M5: Пещеры Базоика,,E1M5: Bazoiks grottor,E1M5: Bazoik Mağaraları +E2M1: Spaceport,HUSTR_E2M1,,,,E2M1: Kosmodrom,E2M1: Rumhavn,E2M1: Raumhafen,,E2M1: Kosmo-haveno,E2M1: Puerto espacial,,E2M1: Avaruussatama,E2M1: Spatioport,E2M1: Űrkikötő,E2M1: Spazioporto,E2M1: スペースポート,E2M1: 우주공항,E2M1: Ruimtehaven,E2M1: Romhavn,E2M1: Port Kosmiczny,E2M1: Espaçoporto,,E2M1: Portul Spațial,E2M1: Космодром,,E2M1: Rymdflygplats,E2M1: Uzay Limanı +E2M2: Cinema,HUSTR_E2M2,,,,E2M2: Kino,,E2M2: Kino,,E2M2: Kinejo,E2M2: Cine,,E2M2: Elokuvateatteri,E2M2: Cinéma,E2M2: Mozi,,E2M2: シネマ,E2M2: 극장,E2M2: Bioscoop,E2M2: Kino,E2M2: Kino,,,,E2M2: Кинотеатр,,,E2M2: Sinema +E2M3: Chex Museum,HUSTR_E2M3,,,,E2M3: Muzem Chex,,,,E2M3: Chex-muzeo,E2M3: Museo de Chex,,E2M3: Chex-museo,E2M3: Musée Chex,E2M3: Chex-múzeum,E2M3: Museo di Chex,E2M3: チェックス ミュージアム,E2M3: 첵스 박물관,,,E2M3: Muzeum Chex,E2M3: Museu Chex,,E2M3: Muzeul Chex,E2M3: Музей Chex,,,E2M3: Chex Müzesi +E2M4: City Streets,HUSTR_E2M4,,,,E2M4: Městské ulice,E2M4: Byens gader,E2M4: städtische Straßen,,E2M4: Urbstratoj,E2M4: Calles de la ciudad,,E2M4: Kaupungin kadut,E2M4: Rues de la Ville,E2M4: Városi utcák,E2M4: Strade della città,E2M4: シティーストリート,E2M4: 도시 거리,E2M4: Stadsstraten,E2M4: Byens gater,E2M4: Ulice Miasta,E2M4: Ruas da Cidade,,E2M4: Străzile Orașului,E2M4: Городские улицы,,E2M4: Stadens gator,E2M4: Şehir Sokakları +E2M5: Sewer System,HUSTR_E2M5,,,,E2M5: Kanalizace,E2M5: Kloaksystem,E2M5: Kanalisation,,E2M5: Defluilego-sistemo,E2M5: Alcantarillado,,E2M5: Viemärijärjestelmä,E2M5: Système d'égouts,E2M5: Csatornarendszer,E2M5: Rete fognaria,E2M5: サワーシステム,E2M5: 하수도,E2M5: Rioleringssysteem,E2M5: Avløpssystem,E2M5: System Ścieków,E2M5: Rede de Esgoto,,E2M5: Sistemul de Canalizare,E2M5: Канализация,,E2M5: Avloppssystem,E2M5: Kanalizasyon Sistemi +E3M1: Central Command,HUSTR_E3M1,,,,E3M1: Centrální velení,E3M1: Centralkommando,E3M1: Kommandozentrale,,E3M1: Centra komandejo,E3M1: Comando central,,E3M1: Komentokeskus,E3M1: Commandement,E3M1: Központi parancsnokság,E3M1: Comando centrale,E3M1: 中央しれいとう,E3M1: 중앙 사령부,E3M1: Centraal Commando,E3M1: Sentral kommando,E3M1: Centrum Dowodzenia,E3M1: Comando Central,,E3M1: Centrul de Comanda,E3M1: Командный центр,,E3M1: Centrala kommandot,E3M1: Merkez Komutanlığı +E3M2: United Cereals,HUSTR_E3M2,,,,E3M2: Spojené cereálie,,E3M2: Vereinigte Zerealien,,E3M2: Uniaj Cerealoj,E3M2: Cereales Unidos,,E3M2: Yhdistyneet murot,E3M2: Céréales Unies,E3M2: Egyesült Gabonapelyhek,E3M2: Cereali uniti,E3M2: ユナイテッド シリアル,E3M2: 시리얼 연합,E3M2: Verenigde granen,,E3M2: Zjednoczone Płatki,E3M2: Cereais Unidos,,E3M2: Cereale Unite,E3M2: Организация Объединённых Хлопьев,,E3M2: United Cereals,E3M2: Birleşik Tahıllar +E3M3: Villa Chex,HUSTR_E3M3,,,,,,,,E3M3: Vilao Chex,,,,E3M3: Villa Chex,,,E3M3: チェックスのべっそう,E3M3: 책스 주택,,,E3M3: Willa Chex,,,E3M3: Vila Chex,E3M3: Вилла Chex,,, +E3M4: Provincial Park,HUSTR_E3M4,,,,E3M4: Provinciální park,,E3M4: Provinzpark,,E3M4: Provinca Parko,E3M4: Parque provincial,,E3M4: Provinssipuisto,E3M4: Parc Naturel,E3M4: Tartományi park,E3M4: Parco provinciale,E3M4: 州立公園,E3M4: 주립공원,E3M4: Provinciaal Park,,E3M4: Prowincjonalny Park,E3M4: Parque Natural,,E3M4: Parcul Provincial,E3M4: Провинциальный парк,,,E3M4: İl Parkı +E3M5: Meteor Spaceship,HUSTR_E3M5,,,,E3M5: Meteorová vesmírná loď,E3M5: Meteor rumskib,E3M5: Meteor-Raumschiff,,E3M5: Meteor-kosmoŝipo,E3M5: Nave Meteoro,,E3M5: Meteoriavaruusalus,E3M5: Vaisseau Météore,E3M5: Meteor űrhajó,E2M5: Astronave meteorica,E3M5: メテオスペースシップ,E3M5: 거대 유성호,E3M5: Ruimteschip,E3M5: Meteor-romskipet,"E3M5: Statek Kosmiczny ""Meteor""",E3M5: Espaçonave Meteoro,,E3M5: Nava Spațială Meteor,E3M5: Космический корабль «Метеор»,,E3M5: Rymdskeppet Meteor,E3M5: Meteor Uzay Gemisi +Commonus,CC_ZOMBIE,,,,Obecnýs,,,,Oftmukulo,Comunis,,,,Általánusz,,コモンズ,커머누스,,,Pospolitus,,,Comun,Обыкновеннус,,, +Bipedicus,CC_SHOTGUN,,,,Dvojnožus,,,,Dupiedmukulo,Bipedico,,,,Kétlábusz,,バイピディクス,바이피디쿠스,,,,,,Biped,Двуножка,,, +Bipedicus with Armor,CC_IMP,,,,Dvojnožus s brněním,Bipedicus med rustning,Bipedicus mit Panzerung,,Kirasa Dupiedmukulo,Bipedico con armadura,,Panssaroitu bipedicus,Bipedicus avec Armure,Páncélozott kétlábusz,Bipedicus corazzato,アーマードバイピディクス,정예 바이피디쿠스,Bipedicus met harnas,Bipedicus med rustning,Opancerzony Bipedicus,Bipedicus de Armadura,,Biped cu Armură,Бронированная двуножка,,Bipedicus med rustning,Zırhlı Bipedicus +Stridicus,CC_DEMON,,,,Běhakus,,,,Paŝmukulo,Zancadico,,,,Lépkedüsz,,ステュリクス,스트리디쿠스,,,,,,Picioare-Lungi,Длинноножка,,, +Flem Mine,CC_LOST,,,,Slizná mina,,,,Muksentinelo,Flem-Mina,,Limamiina,,Slejmakna,Bomba a Flem,フレムマイン,플렘 지뢰,Flemmijn,,Flemowa Mina,Mina Flem,,Flem Mină,Флем-мина,,Flem-gruva,Flem Madeni +Super Cycloptis,CC_CACO,,,,Superkykloptus,,,,Supera Ciklopmukulo,Supercícloptis,,Supercycloptis,,Szuper Kükloptisz,,スーパーサイクロプティス,슈퍼 사이클롭티스,,Supersykloptis.,Super Cykloptis,,,Super Cicloptic,Супер-циклоптис,,,Süper Cycloptis +Maximus,CC_BARON,,,,,,,,Mukulestro,Máximus,,,,Maximusz,,マクシムス,맥시무스,,,,,,Maxim,Максимус,,, +The Flembomination,CC_SPIDER,,,,Slizavnost,Flembominationen,Die Flembomination,,Mukabomeno,La Flembominación,,Limaoikku,La Flembomination,Slejmdormány,La Flembominio,フレンボミネーション,플렘보미네이션,De Flembominatie,Flembominationen,Flembominacja,A Flembominação,,Flembominație,Флемомерзость,,Flammbomineringen,Flembomination +Lord Snotfolus,CC_CYBER,,,,Lord Hlenfujus,,,,Lordo Mukplenulo,Lord Mocofolus,,Herra Räkänokka,Seigneur Morvator,Lord Takony,,ロード スノフォールス,스놋폴러스 마왕,,,Lord Smarkofolus,Lorde Snotfolus,,Lordul Snotfolus,Правитель Соплезелёнус,,, +Chex Warrior,CC_HERO,,,,Bojovník Chex,Chex Kriger,Chex Krieger,,Chex-batalisto,,,Chex-soturi,Guerrier Chex,Chex harcos,Guerriero Chex,チェックスのせんし,첵스 전사,Chex Krijger,Chex-krigeren,Wojownik Chex,Guerreiro Chex,,Războinic Chex,Воин Chex,,Chex krigare,Chex Savaşçısı +You need a blue key to open this door,PD_BLUEC,,,,Potřebuješ modrý klíč pro otevření těchto dveří,Du skal bruge en blå nøgle for at åbne denne dør,"Du brauchst einen blauen Schlüssel, um diese Tür zu öffnen.",,Vi bezonas bluan ŝlosilon por malfermi ĉi tiun pordon.,Necesitas una llave azul para abrir esta puerta,,Tarvitset sinisen avaimen avataksesi tämän oven,Il vous faut une clé bleue pour ouvrir cette porte.,Kell egy kék kulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave blu per aprire questa porta,このとびらは ブルー キー がひつようだ,이 문을 열려면 청색 열쇠가 필요합니다,Je hebt een blauwe sleutel nodig om deze deur te openen.,Du trenger en blå nøkkel for å åpne denne døren,"Potrzebujesz niebieskiego klucza, aby otworzyć te drzwi",Você precisa de uma chave azul para abrir essa porta,,Ai nevoie de o cheie albastră pentru a deschide ușa aceasta,"Нужен синий ключ, чтобы открыть",Треба вам плави кључ да бисте отворили ова врата,Du behöver en blå nyckel för att öppna den här dörren.,Bu kapıyı açmak için mavi bir anahtara ihtiyacın var. +You need a red key to open this door,PD_REDC,,,,Potřebuješ červený klíč pro otevření těchto dveří,Du skal bruge en rød nøgle for at åbne denne dør,"Du brauchst einen roten Schlüssel, um diese Tür zu öffnen.",,Vi bezonas ruĝan ŝlosilon por malfermi ĉi tiun pordon.,Necesitas una llave roja para abrir esta puerta,,Tarvitset punaisen avaimen avataksesi tämän oven,Il vous faut une clé rouge pour ouvrir cette porte.,Kell egy piros kulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave rossa per aprire questa porta,このとびらは レッド キー がひつようだ,이 문을 열려면 적색 열쇠가 필요합니다,Je hebt een rode sleutel nodig om deze deur te openen.,Du trenger en rød nøkkel for å åpne denne døren,"Potrzebujesz czerwonego klucza, aby otworzyć te drzwi",Você precisa de uma chave vermelha para abrir essa porta,,Ai nevoie de o cheie roșie pentru a deschide ușa aceasta,"Нужен красный ключ, чтобы открыть",Треба вам црвени кључ да бисте отворили ова врата,Du behöver en röd nyckel för att öppna den här dörren,Bu kapıyı açmak için kırmızı bir anahtara ihtiyacın var. +You need a yellow key to open this door,PD_YELLOWC,,,,Potřebuješ žlutý klíč pro otevření těchto dveří,Du skal bruge en gul nøgle for at åbne denne dør,"Du brauchst einen gelben Schlüssel, um diese Tür zu öffnen.",,Vi bezonas flavan ŝlosilon por malfermi ĉi tiun pordon.,Necesitas una llave amarilla para abrir esta puerta,,Tarvitset keltaisen avaimen avataksesi tämän oven,Il vous faut une clé jaune pour ouvrir cette porte.,Kell egy sárga kulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave gialla per aprire questa porta,このとびらは イエローキー がひつようだ,이 문을 열려면 황색 열쇠가 필요합니다,Je hebt een gele sleutel nodig om deze deur te openen.,Du trenger en gul nøkkel for å åpne denne døren,"Potrzebujesz żółtego klucza, aby otworzyć te drzwi",Você precisa de uma chave amarela para abrir essa porta,,Ai nevoie de o cheie galbenă pentru a deschide ușa aceasta,"Нужен жёлтый ключ, чтобы открыть",Треба вам жути кључ да бисте отворили ова врата,Du behöver en gul nyckel för att öppna den här dörren,Bu kapıyı açmak için sarı bir anahtara ihtiyacınız var +You need a blue flemkey to open this door,PD_BLUEF,,,,Potřebuješ modrý slizoklíč pro otevření těchto dveří,Du skal bruge en blå flemkey for at åbne denne dør,"Du brauchst einen blauen Flemschlüssel, um diese Tür zu öffnen.",,Vi bezonas bluan mukŝlosilon por malfermi ĉi tiun pordon.,Necesitas una flemllave azul para abrir esta puerta,,Tarvitset sinisen lima-avaimen avataksesi tämän oven,Il vous faut une flemclé bleue pour ouvrir cette porte.,Kell egy kék slejmkulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave-flem blu per aprire questa porta,このとびらは ブルー キーがひつようだ,이 문을 열려면 청색 플렘열쇠가 필요합니다,Je hebt een blauwe flemsleutel nodig om deze deur te openen.,Du trenger en blå flemkey for å åpne denne døren,"Potrzebujesz niebieskiego flemowego klucza, aby otworzyć te drzwi",Você precisa de uma flemchave azul para ativar este objeto,,Ai nevoie de o flemcheie albastră pentru a deschide ușa aceasta,"Нужен синий флемключ, чтобы открыть",,Du behöver en blå flemnyckel för att öppna den här dörren.,Bu kapıyı açmak için mavi bir flemkey'e ihtiyacın var. +You need a red flemkey to open this door,PD_REDF,,,,Potřebuješ červený slizoklíč pro otevření těchto dveří,Du skal bruge en rød flemkey for at åbne denne dør,"Du brauchst einen roten Flemschlüssel, um diese Tür zu öffnen.",,Vi bezonas ruĝan mukŝlosilon por malfermi ĉi tiun pordon.,Necesitas una flemllave roja para abrir esta puerta,,Tarvitset punaisen lima-avaimen avataksesi tämän oven,Il vous faut une flemclé rouge pour ouvrir cette porte.,Kell egy piros slejmkulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave-flem rossa per aprire questa porta,このとびらは レッド キーがひつようだ,이 문을 열려면 적색 플렘열쇠가 필요합니다,Je hebt een rode flemsleutel nodig om deze deur te openen.,Du trenger en rød flemkey for å åpne denne døren,"Potrzebujesz czerwonego flemowego klucza, aby otworzyć te drzwi",Você precisa de uma flemchave vermelha para ativar este objeto,,Ai nevoie de o flemcheie roșie pentru a deschide ușa aceasta,"Нужен красный флемключ, чтобы открыть",,Du behöver en röd flemnyckel för att öppna den här dörren.,Bu kapıyı açmak için kırmızı bir flemkey'e ihtiyacın var. +You need a yellow flemkey to open this door,PD_YELLOWF,,,,Potřebuješ žlutý slizoklíč pro otevření těchto dveří,Du har brug for en gul flemkey for at åbne denne dør,"Du brauchst einen gelben Flemschlüssel, um diese Tür zu öffnen.",,Vi bezonas flavan mukŝlosilon por malfermi ĉi tiun pordon.,Necesitas una flemllave amarilla para abrir esta puerta,,Tarvitset keltaisen lima-avaimen avataksesi tämän oven,Il vous faut une flemclé jaune pour ouvrir cette porte.,Kell egy sárga slejmkulcs hogy kinyisd ezt az ajtót.,Ti serve una chiave-flem gialla per aprire questa porta,このとびらは イエローキーがひつようだ,이 문을 열려면 황색 플렘열쇠가 필요합니다,Je hebt een gele flemsleutel nodig om deze deur te openen.,Du trenger en gul flemkey for å åpne denne døren,"Potrzebujesz żółtego flemowego klucza, aby otworzyć te drzwi",Você precisa de uma flemchave amarela para ativar este objeto,,Ai nevoie de o flemcheie galbenă pentru a deschide ușa aceasta,"Нужен жёлтый флемключ, чтобы открыть",,Du behöver en gul flemnyckel för att öppna den här dörren.,Bu kapıyı açmak için sarı bir flemkey'e ihtiyacın var. +%o sinks into some slime.,OB_SLIME,,,,%o se propadl@[ao_cs] do slizu.,%o synker ned i noget slim.,%o versank im Schleim,,%o malflosas subeniras en kelkan ŝlimon.,%o se hunde en babas.,,%o uppoaa limaan,%o se noie dans la morve.,%o elsüllyedt a trutyiban.,%o affonda in qualche melma.,%o はスライムにしずんだ。,%o 는(은) 점액 속으로 가라앉았습니다.,%o zinkt in wat slijm.,%o synker ned i noe slim.,%o topi się w szlamie.,%o afundou na gosma.,,%o se scufundă în mâzgă.,Игрок %o утонул в слизи.,,%o sjunker ner i lite slem.,%o balçığın içine battı. +%o sinks into some slime.,OB_LAVA,,,,%o se propadl@[ao_cs] do slizu.,%o synker ned i noget slim.,%o versank im Schleim,,%o malflosas subeniras en kelkan ŝlimon.,%o se hunde en babas.,,%o uppoaa limaan,%o se noie dans la morve.,%o elsüllyedt a trutyiban.,%o affonda in qualche melma.,%o はスライムにしずんだ。,%o 는(은) 질척하게 가라앉았습니다.,%o zinkt in wat slijm.,%o synker ned i noe slim.,%o topi się w szlamie.,%o afundou na gosma.,,%o se scufundă în mâzgă.,Игрок %o утонул в слизи.,,%o sjunker ner i lite slem.,%o balçığın içine battı. +%o was hit by inter-dimensional slime!,OB_POWERSTRAND,,,,%o byl@[ao_cs] zasažen@[ao_cs] mezidimenzionálním slizem!,%o blev ramt af interdimensionalt slim!,%o wurde von interdimensionalem Schleim getroffen,,%o estas trafita de interdimensia ŝlimo!,¡A %o l@[ao_esp] ha alcanzado baba interdimensional!,¡A %o l@[ao_esp] alcanzó baba interdimensional!,%o parkaan osui interdimensionaalista limaa!,%o s'est fait@[e_fr] toucher par de la morve interdimensionelle!,%o interdimenzionális trutyi áldozata lett!,%o è stato colpito da melma interdimensionale!,%o は いじげんスライムまみれになった!,%o 는(은) 차원균열 점액에 맞았습니다!,%o werd geraakt door interdimensionaal slijm!,%o ble truffet av interdimensjonalt slim!,%o został@[ao_pl] uderzon@[adj_pl] przez międzywymiarowy szlam!,%o foi atingid@[ao_ptb] por gosma interdimensional!,,%o a fost lovit de mâzgă interdimensională!,В игрока %o попала межпространственная слизь!,,%o träffades av interdimensionellt slem!,%o boyutlar arası balçık tarafından vuruldu! +%o was hit by inter-dimensional slime!,OB_KILLEDSELF,,,,%o byl@[ao_cs] zasažen@[ao_cs] mezidimenzionálním slizem!,%o blev ramt af interdimensionalt slim!,%o wurde von interdimensionalem Schleim getroffen,,%o estas trafita de interdimensia ŝlimo!,¡A %o l@[ao_esp] ha alcanzado baba interdimensional!,¡A %o l@[ao_esp] alcanzó baba interdimensional!,%o parkaan osui interdimensionaalista limaa!,%o s'est fait@[e_fr] toucher par de la morve interdimensionelle!,%o interdimenzionális trutyi áldozata lett!,%o è stato colpito da melma interdimensionale!,%o は いじげんスライムまみれになった!,%o 는(은) 모르는 사이에 점액에 당했습니다!,%o werd geraakt door interdimensionaal slijm!,%o ble truffet av interdimensjonalt slim!,%o został@[ao_pl] uderzon@[adj_pl] przez międzywymiarowy szlam!,%o foi atingid@[ao_ptb] por gosma interdimensional!,,%o a fost lovit de mâzgă interdimensională!,В игрока %o попала межпространственная слизь!,,%o träffades av interdimensionellt slem!,%o boyutlar arası balçık tarafından vuruldu! +%o was boogered by a stridicus.,OB_STRIDICUS,,,,%o dostal@[ao_cs] holuby od běhakem.,%o blev buogered af en stridicus.,%o wurde von einem Stridicus bepopelt.,,%o estas mukiga de paŝmukulo.,A %o l@[ao_esp] ha moqueado un Zancadico.,A %o l@[ao_esp] moqueó un Zancadico.,%o joutui stridicuksen räkäämäksi.,%o s'est fait@[e_fr] engluer par un stridicus.,%o taknyos lett egy lépkedüsztől.,%o è stato colpito da uno Stridicus.,%o は ステュリクスに おびやかされた。,%o 는(은) 스트리디쿠스의 코딱지에 당했습니다.,%o werd door een stridicus gezoomd.,%o ble bæsjet av en stridicus.,%o został@[ao_pl] zaglutowan@[adj_pl] przez stridicusa.,%o foi melecad@[ao_ptb] por um stridicus.,,%o a fost speriat de către un picioare-lungi.,Игрока %o облепила соплями длинноножка. ,,%o blev utskälld av en stridicus.,%o bir stridicus tarafından avlandı. +%o was gooed by a flem mine.,OB_FLEMMINE,,,,%o byl@[ao_cs] zablácen@[ao_cs] sliznou minou.,%o blev smittet af en flem mine.,%o wurde von einer Flem-Mine beschmiert.,,%o estas ŝlimiga de muksentinelo.,A %o l@[ao_esp] ha pegoteado una Flem-Mina.,A %o l@[ao_esp] pegoteó una Flem-Mina.,%o joutui limamiinan mönjäämäksi.,%o s'est fait@[e_fr] éclabousser par une flem mine.,%o-t összenyálkázta egy slejmakna.,%o è stato colpito da una bomba a flem.,%o はフレムマインに ヒドいめにあった。,%o 는(은) 플렘 지뢰에 의해 점액 범벅이 됐습니다.,%o werd door een Flemmijn getreiterd.,%o ble gooed av en flem mine.,"%o został@[ao_pl] zabrejowan@[adj_pl] przez flemową minę. +",%o foi engosmad@[ao_ptb] por uma mina flem.,,%o a fost lovit de mâzga unei flem mine.,Игрока %o забрызгала флем-мина.,,%o blev gooad av en loppgruva.,%o bir flem mayını tarafından yapışkan hale getirildi. +%o was slimed by a super cycloptis.,OB_SUPERCYCLOPTIS,,,,%o byl@[ao_cs] osliznut@[ao_cs] superkykloptem.,%o blev slimet af en super cycloptis.,%o wurde von einem Super Cycloptis vollgeschleimt.,,%o estas ŝlimiga de supera ciklopmukulo.,A %o l@[ao_esp] ha enlodado un Supercícloptis.,A %o l@[ao_esp] enlodó un Supercícloptis.,%o joutui supercycloptiksen limaamaksi.,%o s'est fait@[e_fr] gélifier par un super cycloptis.,%o-t összenyálkázta egy Szuper Kükloptisz.,%o è stato snellito da una Super Ciyloptis.,%o はスーパーサイクロプティスに とかされた。,%o 는(은) 슈퍼 사이클롭티스의 점액에 당했습니다.,%o werd afgeslankt door een Super Cycloptis.,%o ble slimet av en supersykloptis.,%o został@[ao_pl] oszlamion@[adj_pl] przez super cykloptisa.,%o foi lambuzad@[ao_ptb] por um super cyclóptis.,,%o a fost transformat în mâzgă de către un super cicloptic.,Игрока %o обслюнявил супер-циклоптис.,,%o blev slemmig av en supercykloptis.,%o bir süper sikloptis tarafından sümüklendi. +%o was defeated by a Maximus.,OB_MAXIMUS,,,,%o byl@[ao_cs] poražen@[ao_cs] Maximem.,%o blev besejret af en Maximus.,%o wurde von einem Maximus besiegt.,,%o estas venkita de ĉefmukulo.,A %o l@[ao_esp] ha derrotado un Máximus.,A %o l@[ao_esp] derrotó un Máximus.,%o joutui Maximuksen päihittämäksi.,%o s'est fait@[e_fr] battre par un Maximus.,%o-t legyőzte egy Maximusz.,%o è stato sconfitto da un Maximus.,%o はマクシムスに 敗北した。,%o 는(은) 맥시무스에게 패배했습니다.,%o werd verslagen door een Maximus.,%o ble beseiret av en Maximus.,%o został@[ao_pl] pokonan@[adj_pl] przez Maximusa.,%o foi derrotad@[ao_ptb] por um Maximus.,,%o a fost înfrânt de către un Maxim.,Игрок %o проиграл Максимусу.,,%o besegrades av en Maximus.,%o bir Maximus tarafından yenildi. +%o was gooed by a larva.,OB_LARVA,,,,%o byl@[ao_cs] zacáknut@[ao_cs] larvou.,%o blev smurt af en larve.,%o wurde von einer Larve beschmiert.,,%o estas ŝlimiga de larvo.,A %o l@[ao_esp] ha pegoteado una larva.,A %o l@[ao_esp] pegoteó una larva.,%o joutui toukan mönjäämäksi.,%o s'est fait@[e_fr] tâcher par une larve.,%o lárvatrutyit kapott a nyakába.,%o è stato colpito da una larva.,%o はラーバに ヒドいめにあわされた。,%o 는(은) 애벌레에 의해 점액 범벅이 됐습니다.,%o werd door een Larve weggegooid.,%o ble gooed av en larve.,%o został@[ao_pl] zabrejowan@[adj_pl] przez larwę.,%o foi engosmad@[ao_ptb] por uma larva.,,%o a fost lovit de mâzga unei larve.,Игрока %o обслюнявила личинка.,,%o blev göad av en larv.,%o bir larva tarafından öldürüldü. +%o was slimed by a Quadrumpus.,OB_QUADRUMPUS,,,,%o byl@[ao_cs] zahleněn@[ao_cs] Čtyřzadkem.,%o blev slimet af en Quadrumpus.,%o wurde von einem Quadrumpus vollgeschleimt.,,%o estas ŝlimiga de kvarbrakmukulo.,A %o l@[ao_esp] ha enlodado un Quadrumpus.,A %o l@[ao_esp] enlodó un Quadrumpus.,%o joutui Neliperän limaamaksi.,%o s'est fait@[e_fr] morver par un quadrumpus.,%o-t összenyálkázta egy Négylábusz.,%o è stato ridotto da un Quadrumpus.,%o はクワッドロンプスに スライムにされた。,%o 는(은) 쿼드럼푸스의 점액에 당했습니다.,%o werd afgeslankt door een Quadrumpus.,%o ble slimet av en Quadrumpus.,%o został@[ao_pl] oszlamion@[adj_pl] przez Quadrumpusa.,%o foi melecad@[ao_ptb] por um Quadrumpus.,,%o a fost transformat în mâzgă de către o creatură cu patru mâini,Игрока %o обслюнявила многоручка. ,,%o blev slemmad av en Quadrumpus.,%o bir Quadrumpus tarafından zayıflatıldı. +%o was defeated by the Flembomination.,OB_FLEMBOMINATION,,,,%o byl@[ao_cs] poražen@[ao_cs] Slizavností.,%o blev besejret af Flembomination.,%o wurde von der Flembomination besiegt.,,%o estas venkita de la Mukabomeno.,A %o l@[ao_esp] ha derrotado la Flembominación.,A %o l@[ao_esp] derrotó la Flembominación.,%o joutui Limaoikun päihittämäksi.,%o s'est fait@[e_fr] éliminer par la Flembomination.,%o-t legyőzte a Slejmdormány.,%o è stato sconfitto dalla Flembomination.,%o はフレンボミネーションに敗北した。,%o 는(은) 플렘보미네이션으로부터 벗어날 수 없었습니다.,%o werd verslagen door de Flembominatie.,%o ble beseiret av Flembominationen.,%o został@[ao_pl] pokonan@[adj_pl] przez Flembominację.,%o foi derrotad@[ao_ptb] pela Flembominação.,,%o a fost învins de către Flembominație.,Игрока %o победила Флемомерзость.,,%o besegrades av Flembomination.,"%o, Flembomination tarafından yenildi." +%o was defeated by Lord Snotfolus.,OB_SNOTFOLUS,,,,%o byl@[ao_cs] poražen@[ao_cs] Lordem Hlenfujem.,%o blev besejret af Lord Snotfolus.,%o wurde von Lord Snotfolus besiegt.,,%o estas venkita de Lordo Mukplenulo.,A %o l@[ao_esp] ha derrotado Lord Mocofolus.,A %o l@[ao_esp] derrotó Lord Mocofolus.,%o joutui herra Räkänokan päihittämäksi.,%o est tombé@[e_fr] face au Seigneur Morvator.,%o legyőzetett Lord Takony által.,%o è stato sconfitto da Lord Snotfolus.,%o はロード スノフォールスに敗北した。,%o 는(은) 스놋폴러스 마왕과 싸울 준비를 제대로 하지 못했습니다.,%o werd verslagen door Lord Snotfolus.,%o ble beseiret av Lord Snotfolus.,%o został@[ao_pl] pokonan@[adj_pl] przez Lorda Smarkofolusa.,%o foi derrotad@[ao_ptb] pelo Lorde Snotfolus.,,%o a fost pus la pământ de către Lordul Snotfolus.,Игрока %o победил правитель Соплезелёнус.,,%o besegrades av Lord Snotfolus.,"%o, Lord Snotfolus tarafından yenildi." +%o was hit by %k's propulsor.,OB_MPR_SPLASH,,,,%o byl@[ao_cs] zasažen@[ao_cs] propulzorem hráče %k.,%o blev ramt af %ks propulsor.,%o wurde von %ks Propeller getroffen,,%o estas trafita de la propulsilo de %k.,A %o l@[ao_esp] ha alcanzado el propulsor de %k.,A %o l@[ao_esp] alcanzó el propulsor de %k.,%k osui %o parkaan työntimellään.,%o s'est fait@[e_fr] propulser par %k.,%o-t eltalálta %k hajtóműve.,%o è stato colpito dal propulsore di %k.,%o に %k のロケットゾーチがとどいた。,%o 는(은) %k 의 추진력에 휘말렸습니다.,%o werd geraakt door %k's propulsor.,%o ble truffet av %ks propulsor.,%o został@[ao_pl] uderzon@[adj_pl] przez pędnik %k.,%o foi atingid@[ao_ptb] pelo propulsor de %k.,,%o a fost lovit de către propulsorul lui %k.,Игрок %o подстрелен из ускорителя зорча %k.,,%o träffades av %ks propulsor.,"%o, %k tarafından vuruldu." +%o was lazzed by %k.,OB_MPBFG_SPLASH,,,,%o byl@[ao_cs] odlazován@[ao_cs] hráčem %k.,%o blev lazzed af %k.,%o wurde von %o weggezorcht.,,%o estas LAZ-ita de %k.,A %o l@[ao_esp] ha «lazeado» %k.,A %o l@[ao_esp] «lazeó» %k.,%k sazzasi pelaajaan %o.,%o est entré@[e_fr] dans la zone de zorchage large de %k.,%o-t szörcsölődött %k által.,%o è stato lazzato da %k.,%o は %k にとかされた。,%o 는(은) %k 에게 레이져를 쐬였습니다.,%o werd gelazzed door %k.,%o ble lazzed av %k.,%o został@[ao_pl] zLAZowan@[adj_pl] przez %k.,%o foi LAZead@[ao_ptb] por %k.,,%k a folosit dispozitivul LAZ pe %o.,Игрок %o получил заряд из «ЗБР» игрока %k.,,%o blev lurad av %k.,"%o, %k tarafından lazzlandı." "After sending the monstrous Flembrane back to his own dimension, you free the captives. Yet flemoids are everywhere! @@ -321,7 +321,27 @@ Orașul Chex!","Изгнав чудовищную Флембрану назад К сожалению, ты оказал@[refl_rus] прав@[ao_rus]. Вернувшись домой, ты обнаружил@[ao_rus], что Флемоиды добрались и сюда. -Тебя ждёт Chex Quest 2: Террор в Городе Chex!",,"Canavar Flembrane'i kendi boyutuna +Тебя ждёт Chex Quest 2: Террор в Городе Chex!",,"Efter att ha skickat tillbaka den +monstruösa Flembrane till sin +egen dimension befriar du +fångarna. Ändå finns flemoider +överallt! +Du och fångarna gör en +utbrytning till ditt rymdskepp. +Flemoiderna slevar ditt skepp, +men du lyckas med nöd och +näppe fly i omloppsbana. +Under återresan gratuleras du +till den djärva räddningen, men +du utfärdar en varning... +Vi har inte sett det sista av +flemoiderna. + +Tyvärr har du rätt. För när du +återvänder hem upptäcker du +att Flemoiderna på något sätt +har följt dig hit. Förbered dig på +Chex Quest 2: Terror i Chex City!","Canavar Flembrane'i kendi boyutuna geri gönderdikten sonra tutsakları serbest bırakıyorsunuz. Yine de flemoidler her yerde! @@ -601,7 +621,7 @@ interdimensională gigantă, iar acum o bilă enormă de mâzgă e îndreptată drept către planeta cerealelor! -Pregătește-te pentru Chex Quest 3: Invazia!","С помощью Зорчера, ты освободил@[ao_rus] +Pregătește-te pentru Chex Quest 3: Invazia!","С помощью зорчера, ты освободил@[ao_rus] канализацию от оставшихся флемоидов. Город Chex спасён. Казалось, что с угрозой флемоидов наконец-то покончено. @@ -615,7 +635,27 @@ Pregătește-te pentru Chex Quest 3: Invazia!","С помощью Зорчера разлом в космосе. Над планетой хлопьев навис огромный шар из слизи! -Приготовься к Chex Quest 3: Вторжение!",,"Kanalizasyonda toplanmış olan kalan +Приготовься к Chex Quest 3: Вторжение!",,"Du zorch de återstående +flemoiderna som hade samlats +i kloakerna. Chex City har +räddats. Det verkar som om +Flemoid-hotet äntligen har +upphört. + +Tio år går i fred och välstånd. +Men Flemoiderna besegrades +inte och deras önskan att +kontrollera den näringsrika +spannmålsdimensionen har inte +minskat. +De har samlat alla sina styrkor, +öppnat en gigantisk inter- +dimensionell spricka i rymden +och nu är en stor boll av slem på +väg rakt mot spannmålens planet! + +Gör dig redo för +Chex Quest 3: Invasion!","Kanalizasyonda toplanmış olan kalan flemoidleri zorluyorsun. Chex Şehri kurtarıldı. Görünüşe göre Flemoid tehdidi nihayet sona erdi. @@ -818,19 +858,31 @@ Speri cu adevărat că Flemoizii și-au învățat lecția cerealelor. -Dar dacă o vor face, vei fi pregătit pentru ei!","Последним метким выстрелом из Зорчера, -лорд Снотфолус был изгнан в назад своё измерение. +Dar dacă o vor face, vei fi pregătit pentru ei!","Последним метким выстрелом из зорчера, +правитель Снотфолус был изгнан в назад своё измерение. Всем бедам вопреки, ты собственноручно покончил@[ao_rus] со вторжением! Остаётся лишь надеяться, что теперь флемоиды усвоят урок, и больше никогда не проникнут -в измерение Хлопьев. +в измерение хлопьев. Но если всё-таки проникнут, -ты уже будешь к этому готов@[ao_rus]!",,"Son bir patlamayla Lord +ты уже будешь к этому готов@[ao_rus]!",,"Med en sista smäll zorchar +du Lord Snotfolus tillbaka till +sin egen dimension! +Mot alla odds har du på egen +hand förhindrat invasionen! + +Du hoppas verkligen att +Flemoiderna äntligen har lärt sig +sin läxa och aldrig mer kommer +att återvända till +spannmålsdimensionen. + +Men om de gör det vet du att dukommer att vara redo för dem!","Son bir patlamayla Lord Snotfolus'u kendi boyutuna geri döndürüyorsunuz! Tüm olasılıklara rağmen @@ -845,6 +897,6 @@ umuyorsun. Ama dönerlerse, onlar için hazır olacağınızı biliyorsunuz!" -Rescue on Bazoik,M_EPI1,,,,Záchrana na Bazoiku,Redning på Bazoik,Rettung auf Bazoik,,Savo sur Bazojko,Rescate en Bazoik,,Pelastustehtävä Bazoikissa,Sauvetage sur Bazoik,Mentőakció a Bazoik-on,Salvataggio su Bazoik,バゾイクからのきゅうしゅつ,바조이크의 대동굴,Redding op Bazoik,Redning på Bazoik,Ratunek na Bazoik,Resgate em Bazoik,,Misiune de Salvare pe Bazoik,Спасение на Базоике,,Bazoik'te Kurtarma -Terror in Chex City,M_EPI2,,,,Hrůza v Chex City,Terror i Chex City,,,Teruro en Chex-Urbo,Terror en Chex City,,Kauhua Chex-kaupungissa,Terreur à Chex City,Terror Chexvárosban,Terrore a Chex City,チェックスシティーのきょうふ,첵스 시티의 공포,Terreur in Chex City,Terror i Chex City,Terror w Mieście Chex,Terror em Chexópolis,,Teroare în Orașul Chex,Террор в городе Chex,,Chex Şehrinde Terör -Invasion!,M_EPI3,,,,Invaze!,,,,Invado!,¡Invasión!,,Invaasio!,,Invázió!,Invasione!,しんにゅう!,대침공!,,Invasjon!,Inwazja,A Invasão!,,Invazie!,Вторжение!,,İstila! \ No newline at end of file +Rescue on Bazoik,M_EPI1,,,,Záchrana na Bazoiku,Redning på Bazoik,Rettung auf Bazoik,,Savo sur Bazojko,Rescate en Bazoik,,Pelastustehtävä Bazoikissa,Sauvetage sur Bazoik,Mentőakció a Bazoik-on,Salvataggio su Bazoik,バゾイクからのきゅうしゅつ,바조이크의 대동굴,Redding op Bazoik,Redning på Bazoik,Ratunek na Bazoik,Resgate em Bazoik,,Misiune de Salvare pe Bazoik,Спасение на Базоике,,Räddning på Bazoik,Bazoik'te Kurtarma +Terror in Chex City,M_EPI2,,,,Hrůza v Chex City,Terror i Chex City,,,Teruro en Chex-Urbo,Terror en Chex City,,Kauhua Chex-kaupungissa,Terreur à Chex City,Terror Chexvárosban,Terrore a Chex City,チェックスシティーのきょうふ,첵스 시티의 공포,Terreur in Chex City,Terror i Chex City,Terror w Mieście Chex,Terror em Chexópolis,,Teroare în Orașul Chex,Террор в городе Chex,,Terror i Chex City,Chex Şehrinde Terör +Invasion!,M_EPI3,,,,Invaze!,,,,Invado!,¡Invasión!,,Invaasio!,,Invázió!,Invasione!,しんにゅう!,대침공!,,Invasjon!,Inwazja,A Invasão!,,Invazie!,Вторжение!,,,İstila! \ No newline at end of file diff --git a/wadsrc_extra/static/filter/hacx.hacx1/after_iwad/language.csv b/wadsrc_extra/static/filter/hacx.hacx1/after_iwad/language.csv index 235cee56c..d9c868569 100644 --- a/wadsrc_extra/static/filter/hacx.hacx1/after_iwad/language.csv +++ b/wadsrc_extra/static/filter/hacx.hacx1/after_iwad/language.csv @@ -1,122 +1,122 @@ -default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,tr -These bugs too tough for ya?,QUITMSG1,,,,Jsou ty bugy na tebe moc tvrdé?,Er disse bugs for hårde for dig?,Sind diese Bugs zu viel für dich?,,Ĉu ĉi tiuj cimoj estas tro forta por vi?,¿Son estos bichos demasiado duros para ti?,,Taitavat nämä ötökät olla liikaa sulle?,Ces bestioles sont trop fortes pour vous?,Túl erősek neked a bogarak is?,Questi errori sono troppo difficili per te?,テメェにはあんなバグ 厳しかないだろ?,고작 버그들 상대하는 것도 버거운 건가?,Zijn deze bugs te hard voor je?,Er disse insektene for tøffe for deg?,To robactwo jest za ciężkie dla ciebie?,"Tá achando difícil eliminar esses bugs, é?",,Sunt prea duri gândacii pentru tine?,Эти баги крутоваты для тебя?,,Bu böcekler senin için çok mu zor? +default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,sv,tr +These bugs too tough for ya?,QUITMSG1,,,,Jsou ty bugy na tebe moc tvrdé?,Er disse bugs for hårde for dig?,Sind diese Bugs zu viel für dich?,,Ĉu ĉi tiuj cimoj estas tro forta por vi?,¿Son estos bichos demasiado duros para ti?,,Taitavat nämä ötökät olla liikaa sulle?,Ces bestioles sont trop fortes pour vous?,Túl erősek neked a bogarak is?,Questi errori sono troppo difficili per te?,テメェにはあんなバグ 厳しかないだろ?,고작 버그들 상대하는 것도 버거운 건가?,Zijn deze bugs te hard voor je?,Er disse insektene for tøffe for deg?,To robactwo jest za ciężkie dla ciebie?,"Tá achando difícil eliminar esses bugs, é?",,Sunt prea duri gândacii pentru tine?,Эти баги крутоваты для тебя?,,Är dessa bugs för svåra för dig?,Bu böcekler senin için çok mu zor? Are you sure you want to\njack out of the action?,QUITMSG,,,,"Jsi si jistý, že se chceš zdáchnout z akce?","Er du sikker på, at du vil holdeop med at deltage?","Bist du sicher, dass du den\nStecker ziehen willst?",,"Ĉu vi certas, ke vi volas malkonektiĝi el la batalo?",¿Estás segur@[ao_esp] de que\nquieres desconectarte de la acción?,,Haluatko varmasti irrottaa\npiuhan toiminnasta?,Etes-vous sûr de vouloir\nvous déconnecter de l'action?,"Biztos vagy benne, hogy kihúzod a kábelt?",Sei sicuro di voler uscire?,もしかして逃げ出そうとしてないよな?,"지금 종료하겠다고? -진심이냐?",Weet je zeker dat je de actie wilt staken?,Er du sikker på at du vil trekke deg ut av handlingen?,Na pewo chcesz wyjść w środku akcji?,Tem certeza que quer se desconectar de toda a ação? ,,Ești sigur că vrei să\npărăsești acțiunea?,Ты правда хочешь улизнуть\nс поля боя?,,İşin dışında kalmak istediğine emin misin? -Trying to quit? And you call yourself a hacker?,QUITMSG2,,,,Snažíš se skončit? To si říkáš hacker?,Prøver du at holde op? Og du kalder dig selv en hacker?,Du willst gehen? Bist du wirklich ein Hacker?,,Vi provas rezigni? Kaj vi nomas vin kodrompisto?,¿Intentando salir? ¿Y te haces llamar hacker?,,Yritätkö lopettaa? Ja sinäkö muka hakkeri?,On essaye de quitter?\nvous prétendez être un hacker?,Próbálasz kilépni? És még te nevezed magad hekkernek?,Stai cercando di smettere?\nE ti definisci un hacker?,終了させる? それでハッカー自称してたのか?,그만두려고? 해커라는 이름이 아깝군그래.,Proberen te stoppen? En je noemt jezelf een hacker?,Prøver du å slutte? Og du kaller deg en hacker?,Próbujesz wyjść? I nazywasz siebie hakerem?,Tá querendo sair? E você ainda se acha um hacker?,,Încerci să ieși? Și te mai numești hacker?,Хочешь убежать? А ещё зовёшь себя хакером!,,Bırakmaya mı çalışıyorsun? Bir de kendine hacker mı diyorsun? +진심이냐?",Weet je zeker dat je de actie wilt staken?,Er du sikker på at du vil trekke deg ut av handlingen?,Na pewo chcesz wyjść w środku akcji?,Tem certeza que quer se desconectar de toda a ação? ,,Ești sigur că vrei să\npărăsești acțiunea?,Ты правда хочешь улизнуть\nс поля боя?,,Är du säker på att du inte vill vara med?,İşin dışında kalmak istediğine emin misin? +Trying to quit? And you call yourself a hacker?,QUITMSG2,,,,Snažíš se skončit? To si říkáš hacker?,Prøver du at holde op? Og du kalder dig selv en hacker?,Du willst gehen? Bist du wirklich ein Hacker?,,Vi provas rezigni? Kaj vi nomas vin kodrompisto?,¿Intentando salir? ¿Y te haces llamar hacker?,,Yritätkö lopettaa? Ja sinäkö muka hakkeri?,On essaye de quitter?\nvous prétendez être un hacker?,Próbálasz kilépni? És még te nevezed magad hekkernek?,Stai cercando di smettere?\nE ti definisci un hacker?,終了させる? それでハッカー自称してたのか?,그만두려고? 해커라는 이름이 아깝군그래.,Proberen te stoppen? En je noemt jezelf een hacker?,Prøver du å slutte? Og du kaller deg en hacker?,Próbujesz wyjść? I nazywasz siebie hakerem?,Tá querendo sair? E você ainda se acha um hacker?,,Încerci să ieși? Și te mai numești hacker?,Хочешь убежать? А ещё зовёшь себя хакером!,,Försöker du sluta? Och du kallar dig för hackare?,Bırakmaya mı çalışıyorsun? Bir de kendine hacker mı diyorsun? Get back here before I send a virus up your tailpipe!,QUITMSG3,,,,"Vrať se, než ti do zadku pošlu virus!","Kom tilbage, før jeg sender en virus op i dit udstødningsrør!","Komm zurück, oder ich schick dir 'nen Virus!",,"Revenu ĉi tien antaŭ ol mi sendos viruson en vian posttubon!","¡Vuelve aquí antes de que te meta un virus de través!","¡Vuelve antes de que te mande -un virus al tubo de escape!","Heti takaisin tänne, ennen kuin lähetän viruksen pitkin takaputkeasi!",Reviens ici avant que je t'envoie un virus là où ça fait mal!,"Gyere csak vissza, mielőtt feldugok neked egy vírust.",Torna indietro o ti\nmanderò un virus!,さっさと戻らねえと そのケツ穴にウィルスぶっこむぞ!,"돌아와, 네 전선에 바이러스 주입해버리기 전에!",Kom terug voordat ik een virus in je uitlaatpijp stuur!,Kom tilbake før jeg sender et virus opp eksosrøret ditt!,Wróć tu zanim wyślę ci wirusa!,Volta aqui antes que eu te mande um vírus!,,Treci înapoi aici până nu-ți trimit un virus!,"Вернись, пока я не посадил вирус тебе на хвост!",,Egzozuna bir virüs göndermeden önce buraya geri dön! +un virus al tubo de escape!","Heti takaisin tänne, ennen kuin lähetän viruksen pitkin takaputkeasi!",Reviens ici avant que je t'envoie un virus là où ça fait mal!,"Gyere csak vissza, mielőtt feldugok neked egy vírust.",Torna indietro o ti\nmanderò un virus!,さっさと戻らねえと そのケツ穴にウィルスぶっこむぞ!,"돌아와, 네 전선에 바이러스 주입해버리기 전에!",Kom terug voordat ik een virus in je uitlaatpijp stuur!,Kom tilbake før jeg sender et virus opp eksosrøret ditt!,Wróć tu zanim wyślę ci wirusa!,Volta aqui antes que eu te mande um vírus!,,Treci înapoi aici până nu-ți trimit un virus!,"Вернись, пока я не посадил вирус тебе на хвост!",,Kom tillbaka innan jag skickar ett virus upp i ditt avgasrör!,Egzozuna bir virüs göndermeden önce buraya geri dön! Real hackers never jack out of the action.,QUITMSG4,,,,Skuteční hackeři nikdy neprchají z akce.,Rigtige hackere går aldrig ud af spillet.,Echte Hacker geben nicht auf!,,"Veraj kodrompistoj neniam fuĝas el batalo.","Los verdaderos hackers no -se desconectan de la acción.",,Todelliset hakkerit eivät ikinä kytkeydy irti toiminnasta.,Un vrai hacker ne se déconnecte pas en pleine action.,Az igazi hekkerek sosem húzzák ki a kábelt.,I veri hacker non si arrendono!,本物のハッカーなら頭を銃で撃ち抜くことはしない。,진정한 해커는 이렇게 포기하지 않는다고!,Echte hackers komen nooit uit de actie.,Ekte hackere trekker seg aldri ut av kampen.,Prawdziwi hakerzy nigdy nie uciekają z akcji.,Hackers de verdade nunca vazam da ação!,,Adevărații hackeri nu fug de acțiune.,Настоящие хакеры не пытаются улизнуть с поля боя.,,Gerçek hackerlar asla aksiyondan kaçmazlar. +se desconectan de la acción.",,Todelliset hakkerit eivät ikinä kytkeydy irti toiminnasta.,Un vrai hacker ne se déconnecte pas en pleine action.,Az igazi hekkerek sosem húzzák ki a kábelt.,I veri hacker non si arrendono!,本物のハッカーなら頭を銃で撃ち抜くことはしない。,진정한 해커는 이렇게 포기하지 않는다고!,Echte hackers komen nooit uit de actie.,Ekte hackere trekker seg aldri ut av kampen.,Prawdziwi hakerzy nigdy nie uciekają z akcji.,Hackers de verdade nunca vazam da ação!,,Adevărații hackeri nu fug de acțiune.,Настоящие хакеры не пытаются улизнуть с поля боя.,,Riktiga hackare hoppar aldrig av.,Gerçek hackerlar asla aksiyondan kaçmazlar. C'mon! You haven't seen the best part yet!,QUITMSG5,,,,No tak! Ještě jsi neviděl to nejlepší!,Kom nu! Du har ikke set det bedste endnu!,Komm schon. Du hast das Beste noch gar nicht gesehen!,,"Nu! Vi ankoraŭ ne vidis la plej bonan parton!","¡Venga! ¡Aún no has visto la mejor parte!","¡Venga! ¡Aún no -viste la mejor parte!",Älä viitsi! Et ole edes vielä nähnyt parasta kohtaa!,"Allez, on arrive presque à la meilleure partie!",Nemár! Még nem is láttad a legjobb részt!,"Andiamo, forza! Non hai ancora\nvisto la parte migliore!",おいおい! お楽しみはこれからだぜ!,이봐! 아직 재밌는 부분은 시작도 안 했다고!,Kom op! Je hebt het beste deel nog niet gezien!,Kom igjen! Du har ikke sett det beste ennå!,No weź! Jeszcze nie widziałeś najlepszej części!,Qual é! Você nem viu a melhor parte ainda!,,Haide! Nu ai văzut partea cea mai bună încă!,"Да ладно, ты ещё не видел самое крутое!",,Hadi ama! Daha en iyi kısmını görmedin! +viste la mejor parte!",Älä viitsi! Et ole edes vielä nähnyt parasta kohtaa!,"Allez, on arrive presque à la meilleure partie!",Nemár! Még nem is láttad a legjobb részt!,"Andiamo, forza! Non hai ancora\nvisto la parte migliore!",おいおい! お楽しみはこれからだぜ!,이봐! 아직 재밌는 부분은 시작도 안 했다고!,Kom op! Je hebt het beste deel nog niet gezien!,Kom igjen! Du har ikke sett det beste ennå!,No weź! Jeszcze nie widziałeś najlepszej części!,Qual é! Você nem viu a melhor parte ainda!,,Haide! Nu ai văzut partea cea mai bună încă!,"Да ладно, ты ещё не видел самое крутое!",,Kom igen! Du har inte sett det bästa ännu!,Hadi ama! Daha en iyi kısmını görmedin! "Give up now, and cyberspace is toast!",QUITMSG6,,,,Vzdej se a s kyberprostorem je konec!,"Giv op nu, og cyberspace er ristet!",Wenn du jetzt aufgibst ist der Cyberspace am Ende.,,"Se vi rezignas nun, tiam Interret-spaco estos detruita!","¡Ríndete ahora y el ciberespacio -está frito!",,Luovuta nyt ja kyberavaruus kärtsää!,"Abandonne, et le cyberespace est foutu!","Ha most feladod, akkor a cyberspacenek lőttek.","Se ti arrendi ora,\nil cyberspazio è finito.",さっさと止めて、サイバースペースに乾杯だ!,포기하면 사이버 공간은 결국엔 사라질걸?,"Geef het nu op, en cyberspace is een toast!","Gi opp nå, og cyberspace er ferdig!","Poddaj się, a cyberprzestrzeń zmieni się w tosta!","Se você desistir agora, o ciberespaço já era!",,"Te dai bătut acum, și spațiul cibernetic e prăjit!","Если ты сейчас сдашься, киберпространству конец!",,"Şimdi pes edersen, siber uzay kızarır!" -"GENIE sends its best regards, scumbag!",QUITMSG7,,,,"GENIE posílá své pozdravy, hajzle!","GENIE sender dig sine bedste hilsner, skiderik!","GENIE sendet seine besten Grüße, Mistkerl!",,"ĜINIO sendas plej siajn konsiderojn, fiulo!","¡GENIE te envía saludos, desgraciado!",,"GENIE lähettää terveisensä, mäntti!","GENIE t'envoie ses salutations, salaud!","GENIE üdvözletét küldi, te mocsok!","GENIE ti manda i suoi\nmigliori saluti, bastardo!",GENIEがベストの挨拶を送るぜ、カス野郎!,어이 등신! 지니에서 안부를 전해 달라더군.,"GENIE doet je de groeten, klootzak!","GENIE sender sine beste hilsener, drittsekk!","GENIE przysyła pozdrowienia, łajzo!","GENIE manda lembranças, seu lixo!",,"GENIE își transmite condoleanțele, ticălosule!","Наилучшие пожелания от ДЖИННа, ублюдок!",,"GENIE selamlarını yolladı, pislik!" -"Hmm. So much for being a hero, Hacker.",QUITMSG8,,,,"Hmm. To by bylo pro hrdinství, Hackeře.","Hmm. Så meget for at være en helt, Hacker.","Hmm. So viel zum Thema ""Held"", Hacker.",,"Ĥaa. Kia domaĝo, ke vi estas hero, Kodrompisto.","Hmm. Poco tienes de héroe, hacker.",,"Höh, se siitä sankarina olemisesta sitten, hakkeri.","Eh bien, on est pas vraiment un héros, hacker.","Hmm. Ennyit a hős karrieredről, hekker barátom.","Hmm. E io che pensavo fossi un eroe, Hacker.",うーん。英雄とはこの程度だったのか、ハッカー。,영웅이 될 그릇은 아닌 거 같군. 안 그래? 해커 형씨.,"Hmm. Tot zover de held, Hacker.","Hmm. Så mye for å være en helt, Hacker.","Hmm. Tak wiele by być bohaterem, Hakerze.","Hmm. Não é tão herói assim, pelo visto.",,"Hmm. Asta a fost cu eroismele, Hacker.","Хм-м. Вот тебе и герой, хакер!",,"Hmm. Kahraman olmak için çok fazla, Hacker." -What? You'd rather go back to the pen?,QUITMSG9,,,,Co? Radši by ses vrátil do basy?,Hvad? Vil du hellere gå tilbage til fængslet?,Was? Du willst in den Knast zurück?,,"Kio? Ĉu vi preferas, ke vi revenu al la plumon?",¿Qué? ¿Prefieres volver al corral?,,Täh? Menisit mieluummin takaisin kynän ääreen?,Quoi? Tu préfère retourner dans ta cellule?,Hogy micsoda? inkább visszamennél a tolladhoz?,Cosa? Vuoi tornare in prigione?,何? 今更ペンで計算するのか?,펜이나 끄적거리는 인생으로 돌아가겠다. 이건가?,Wat? Ga je liever terug naar de pen?,Hva? Vil du heller tilbake til kasjotten?,Co? Wolisz wrócić do więzienia?,O quê? Prefere voltar pro xilindró?,,Ce? Vrei să te întorci la captivitate?,Что? Ты хочешь вернуться в неволю?,,Ne? Kalemine geri dönmeyi mi tercih ediyorsun? +está frito!",,Luovuta nyt ja kyberavaruus kärtsää!,"Abandonne, et le cyberespace est foutu!","Ha most feladod, akkor a cyberspacenek lőttek.","Se ti arrendi ora,\nil cyberspazio è finito.",さっさと止めて、サイバースペースに乾杯だ!,포기하면 사이버 공간은 결국엔 사라질걸?,"Geef het nu op, en cyberspace is een toast!","Gi opp nå, og cyberspace er ferdig!","Poddaj się, a cyberprzestrzeń zmieni się w tosta!","Se você desistir agora, o ciberespaço já era!",,"Te dai bătut acum, și spațiul cibernetic e prăjit!","Если ты сейчас сдашься, киберпространству конец!",,Om du ger upp nu är cyberrymden död!,"Şimdi pes edersen, siber uzay kızarır!" +"GENIE sends its best regards, scumbag!",QUITMSG7,,,,"GENIE posílá své pozdravy, hajzle!","GENIE sender dig sine bedste hilsner, skiderik!","GENIE sendet seine besten Grüße, Mistkerl!",,"ĜINIO sendas plej siajn konsiderojn, fiulo!","¡GENIE te envía saludos, desgraciado!",,"GENIE lähettää terveisensä, mäntti!","GENIE t'envoie ses salutations, salaud!","GENIE üdvözletét küldi, te mocsok!","GENIE ti manda i suoi\nmigliori saluti, bastardo!",GENIEがベストの挨拶を送るぜ、カス野郎!,어이 등신! 지니에서 안부를 전해 달라더군.,"GENIE doet je de groeten, klootzak!","GENIE sender sine beste hilsener, drittsekk!","GENIE przysyła pozdrowienia, łajzo!","GENIE manda lembranças, seu lixo!",,"GENIE își transmite condoleanțele, ticălosule!","Наилучшие пожелания от ДЖИННа, ублюдок!",,"GENIE skickar sina bästa hälsningar, skitstövel!","GENIE selamlarını yolladı, pislik!" +"Hmm. So much for being a hero, Hacker.",QUITMSG8,,,,"Hmm. To by bylo pro hrdinství, Hackeře.","Hmm. Så meget for at være en helt, Hacker.","Hmm. So viel zum Thema ""Held"", Hacker.",,"Ĥaa. Kia domaĝo, ke vi estas hero, Kodrompisto.","Hmm. Poco tienes de héroe, hacker.",,"Höh, se siitä sankarina olemisesta sitten, hakkeri.","Eh bien, on est pas vraiment un héros, hacker.","Hmm. Ennyit a hős karrieredről, hekker barátom.","Hmm. E io che pensavo fossi un eroe, Hacker.",うーん。英雄とはこの程度だったのか、ハッカー。,영웅이 될 그릇은 아닌 거 같군. 안 그래? 해커 형씨.,"Hmm. Tot zover de held, Hacker.","Hmm. Så mye for å være en helt, Hacker.","Hmm. Tak wiele by być bohaterem, Hakerze.","Hmm. Não é tão herói assim, pelo visto.",,"Hmm. Asta a fost cu eroismele, Hacker.","Хм-м. Вот тебе и герой, хакер!",,"Hmm. Så mycket för att vara en hjälte, Hacker.","Hmm. Kahraman olmak için çok fazla, Hacker." +What? You'd rather go back to the pen?,QUITMSG9,,,,Co? Radši by ses vrátil do basy?,Hvad? Vil du hellere gå tilbage til fængslet?,Was? Du willst in den Knast zurück?,,"Kio? Ĉu vi preferas, ke vi revenu al la plumon?",¿Qué? ¿Prefieres volver al corral?,,Täh? Menisit mieluummin takaisin kynän ääreen?,Quoi? Tu préfère retourner dans ta cellule?,Hogy micsoda? inkább visszamennél a tolladhoz?,Cosa? Vuoi tornare in prigione?,何? 今更ペンで計算するのか?,펜이나 끄적거리는 인생으로 돌아가겠다. 이건가?,Wat? Ga je liever terug naar de pen?,Hva? Vil du heller tilbake til kasjotten?,Co? Wolisz wrócić do więzienia?,O quê? Prefere voltar pro xilindró?,,Ce? Vrei să te întorci la captivitate?,Что? Ты хочешь вернуться в неволю?,,Vad? Vill du hellre gå tillbaka till pennan?,Ne? Kalemine geri dönmeyi mi tercih ediyorsun? Shoulda taken the blue pill.,QUITMSG10,,,,Měl sis vzít modrou pilulku.,Du skulle have taget den blå pille.,Du hättest die blaue Pille nehmen sollen...,,"Vi estus devinta preni -la bluan pilolon.",Deberías haber tomado la pastilla azul.,,Olis pitäny ottaa sininen pilleri.,T'aurais du prendre la pilule bleue.,Inkább a kék pirulát kellett volna választanod.,Avresti dovuto prendere la pillola blu ...,青いピルを採るべきではなかったな。,넌 파란 알약을 골랐어야 했어.,Je had de blauwe pil moeten nemen.,Skulle tatt den blå pillen.,Trzeba było wziąć niebieską pigułkę.,Devia ter tomado a pílula azul.,,Trebuia să iei pastila albastră.,Надо было принять синюю таблетку.,,Mavi hapı almalıydın. -The name of the game ain't Twitch n' Run!,QUITMSG11,,,,V názvu hry není napsané „uteč“!,"Spillets navn er ikke ""at flygte""!","Das Spiel heißt nicht ""wegrennen""!",,La nomo de la ludo ne estas Tiku kaj Kuru!,¡El nombre del juego no es Tirar a Correr!,,Pelin nimi ei oo Paniikkipako!,"Le jeu s'appelle pas ""Panique et cours!""",A játék neve nem Twitch n' Megfutamodás.,"Il gioco non significa ""scappare""!",ゲーム名は 萎え落ち小僧 じゃねえぞ!,"이봐, 이 게임은 때리고 도망가는 게임이 아니라고!",De naam van het spel is niet Twitch n' Run!,Navnet på spillet er ikke Twitch n' Run!,"Nazwą gry nie jest ""Drżyj i Uciekaj""!",O nome do jogo não é Trema nas Bases e Fuja!,,Numele jocului nu e Tremură și Ascunde-te!,Эта игра называется не «Дрожи и прячься»!,,Oyunun adı Twitch n' Run değil! -"No worries. Saving the world can wait, right?",QUITMSG12,,,,"Žádný problém. Záchrana světa může počkat, ne?","Det er ikke noget problem. At redde verden kan vente, ikke?","Also, die Welt zu retten kann warten, richtig?",,"Ne zorgu. Savi la mondon povas atendi, ĉu ne?","No te preocupes. Salvar el mundo puede esperar, ¿verdad?",,"Ei huolta; maailman pelastaminen voi odottaa, eikö niin?","Oh, pas de problème. Le monde peut attendre\nd'être sauvé, non?","Semmi pánik. A világmegmentés várhat, nemde?","Salvare il mondo può\naspettare, giusto?",気にはしない、世界を救うのは何時でも出来る、だろ?,걱정 말라고. 세상이 위험한데 급할 것 있나. 안 그래?,"Het redden van de wereld kan wachten, toch?","Slapp av. Å redde verden kan vente, ikke sant?","Bez obaw. Ratowanie świata może poczekać, prawda?","Sem problemas. O mundo pode esperar, não é mesmo?",,"Nicio problemă. Salvarea lumii poate aștepta, nu?","Не парься. Спасение мира подождёт, ведь так?",,"Endişelenme. Dünyayı kurtarmak bekleyebilir, değil mi?" -Guess it's time to make like the 'net and split!,QUITMSG13,,,,"Hádám, že je čas vypojit server!",Så er det vist på tide at gøre som nettet og smutte!,"Also ist es soweit, dass sich unsere Wege trennen.",,"Tempas, ke niaj vojoj agu kiel la reto kaj dividu.",¡Supongo que es hora de cortar con esta mala conexión!,,Kai sitten on aika katkaista palvelinyhteydet!,Ca doit être temps de partir comme une mauvaise connection!,Kettéváglak mint a netsplit a kapcsolatot.,Quindi è il momento per i\nnostri modi di separarsi.,ネット切断している暇は無いだろ!,벌써 서버를 다운시키는 '척' 할 시간인가?,Denk dat het tijd is om het te maken als het 'net en splitsen!,Det er vel på tide å gjøre som nettet og stikke!,"Wygląda na to, że trzeba się rozłączyć jak netsplit!","Acho que tá na hora de cair, que nem uma conexão ruim.",,Cred că e timpul de separare!,"Кажется, настало время устроить netsplit!",,Sanırım 'net gibi yapıp ayrılmanın zamanı geldi! -"Don't go off and forget about HacX, now!",QUITMSG14,,,,Ať tě nenapadne odejít a zapomenout na HacX!,Glem nu ikke HacX!,Bitte vergesse HacX nicht!,,Ne iru forgesi HacX nun!,¡Ahora no vayas y te olvides de Hacx!,,Älä nyt mene pois ja unohda HacX:ä!,Va pas oublier HacX maintenant!,"Ha elkalandozol, ne feletkezz meg a HacX-ről!","Non andartene e dimenticarti di HacX, ora!",HacXを忘れんじゃねえぞ、な!,부디 나가지 말고 HacX를 잊지 말아줘!,"Ga niet af en vergeet HacX niet, nu!","Ikke gå og glem HacX, nå!","Nie wyłączaj i nie zapominaj o HacX, teraz!","Não vai se esquecer do HacX, hein!",,Nu pleca și uita de HacX!,"Только посмей уйти и забыть про HacX, ты!",,"HacX'i unutup gitme, şimdi!" -%o deleted %hself from the universe.,OB_SUICIDE,,,,%o se smazal@[ao_cs] z vesmíru.,%o slettede sig selv fra universet.,%o entfernte sich aus dem Universum.,,%o forigis sin el la universo.,%o se borró a si mism@[ao_esp] del universo.,,%o poisti itsensä maailmankaikkeudesta.,%o s'est effacé@[e_fr] de l'univers.,%o kitörölte magát az univerzumból,%o si è cancellato dall'universo.,%o はこの宇宙から消滅した。,%o 은(는) 자기 자신의 존재를 소멸시켰다.,%o verwijderd zichzelf uit het universum.,%o slettet seg selv fra universet.,%o usun@[irreg_2_pl] się ze świata.,%o se deletou deste universo.,,%o s-a sters pe sine din univers.,Игрок %o стёр себя с лица вселенной.,,%o kendini evrenden sildi. -%o formed a crater the size of Kansas.,OB_FALLING,,,,%o utvořil@[ao_cs] kráter velikosti Kansasu.,%o dannede et krater på størrelse med Kansas.,%o wurde zu einem Krater in der Größe von Kansas.,,%o formis krateron grandan kiel Kansaso.,%o formó un cráter del tamaño de Kansas.,,%o muodosti Kansasin kokoisen kraaterin.,%o a formé un cratère de la taille du Kansas.,%o egy Kansas méretű krátert hagyott maga után.,%o ha formato un cratere delle dimensioni del Kansas.,%o はカンザス州程のクレーターを生成した。,%o 은(는) 땅바닥에 캔자스만큼 커다란 구멍을 뚫었다.,%o vormde een krater ter grootte van Kansas.,%o dannet et krater på størrelse med Kansas.,%o utworzył@[ao_pl] krater wielkości Kansas.,%o abriu uma cratera do tamanho do Kansas.,,%o a format un crater de dimensiunile statului Kansas.,На месте падения игрока %o образовался кратер размером с Канзас.,,%o Kansas büyüklüğünde bir krater oluşturdu. -%o became a human pancake.,OB_CRUSH,,,,%o se změnil@[ao_cs] v lidskou palačinku.,%o blev en menneskelig pandekage.,%o wurde zu einem menschlichen Pfannkuchen.,,%o Iĝis homa patkuko.,%o se convirtió en un crepe humano.,,%o tuli ihmispannukakun muotoiseksi.,%o est devenu@[e_fr] une crêpe.,%o palacsintává lapult,%o è diventato un pancake umano.,%o は人肉パンケーキになった。,%o 은(는) 인간 빈대떡이 되었다.,%o werd een menselijke pannenkoek.,%o ble en menneskelig pannekake.,%o stał@[ao_pl] się ludzkim plackiem.,%o virou uma panqueca humana.,,%o a devenit o clătită umană.,Игрока %o сплющило в лепешку.,,%o insan bir krep oldu. -%o tried to jack out.,OB_EXIT,,,,%o se pokusil@[ao_cs] prchnout.,%o forsøgte at stikke af.,%o hat sich ausgeloggt.,,%o provis malkonektiĝi.,%o intentó desconectarse.,,%o yritti irrottaa piuhan.,%o a tenté de se déconnecter.,%o ki akarta húzni a kábelét,%o è uscito.,%o は逃げ出そうとした。,%o 은(는) 로그아웃하려고 시도했다.,%o probeerde zich terug te trekken.,%o prøvde å jekke seg ut.,%o chciał@[ao_pl] się wydostać.,%o tentou se desconectar.,,%o a încercat să o taie.,Игрок %o хотел улизнуть.,,%o kaçmaya çalıştı. -%o swam like a brick.,OB_WATER,,,,%o uměl@[ao_cs] plavat jako cihla.,%o svømmede som en mursten.,%o schwamm wie ein Stein.,,%o naĝis kiel briko.,%o nadó como un ladrillo.,,%o ui kuin tiiliskivi.,%o nage comme une brique.,%o úgy úszik mint egy tégla.,%o nuotava come una pietra.,%o はカナヅチだった。,%o 은(는) 웹서핑을 못 하는 타입이었다.,%o zwom als een baksteen.,%o svømte som en murstein.,%o popłyn@[irreg_2_pl] jak cegła.,%o foi nadar como um tijolo.,,%o a înotat ca o cărămidă.,Игрок %o поплыл как топор.,,%o bir tuğla gibi yüzdü. -%o went nuclear.,OB_SLIME,,,,%o se rozpadl@[ao_cs] na atom.,%o blev nuklear.,%o wurde verstrahlt.,,%o iĝis nuklea,%o se volvió radioactiv@[ao_esp].,,%o kiinnostui ydinasioista.,%o s'est fait fissionner.,%o felrobbant mérgében.,%o è stato irradiato.,%o はニュークリアーと化した。,%o 은(는) 방사능 바람을 좀 쐬고 왔다.,%o werd nucleair.,%o ble nuklear.,%o został@[ao_pl] napromieniowan@[adj_pl].,%o ficou radioativ@[ao_ptb].,,%o a devenit radioactiv.,Игрок %o светится в темноте.,,%o nükleer oldu. -%o took a hot bath.,OB_LAVA,,,,%o si dal@[ao_cs] horkou koupel.,%o tog et varmt bad.,%o nahm ein heißes Bad.,,%o spertis varman banon.,%o tomó un baño caliente.,,%o otti kuuman kylvyn.,% o ha fatto un bagno caldo.,%o vett egy forró fürdőt.,%o ha fatto un bagno caldo.,%o は熱湯風呂に浸かった。,%o 은(는) 시원하게 용암 일광욕을 즐겼다.,%o nam een warm bad.,%o tok et varmt bad.,%o wzi@[irreg_2_pl] gorącą kąpiel.,%o tomou um banho bem quente.,,%o a făcut o baie fierbinte.,Игрок %o принял горячую ванну.,,%o sıcak bir banyo yaptı. -%o overdosed on nitro glycerine.,OB_BARREL,,,,%o se předávkoval@[ao_cs] nitroglycerinem.,%o fik en overdosis nitroglycerin.,%o nahm eine Überdosis Nitroglyzerin.,,%o trodozis nitroglicerinon.,%o tuvo una sobredosis de nitroglicerina.,,%o sai yliannostuksen nitroglyseriiniä.,%o a fait une overdose de nitroglycérine.,%o túladagolta a nitro-glicerint.,%o ha assunto un sovradosaggio di nitroglicerina.,%o はニトロを過剰摂取した。,%o 은(는) 니트로글리세린을 훅 가게 흡입했다.,%o overdosering op nitroglycerine.,%o tok en overdose nitroglyserin.,%o przedawkował@[ao_pl] nitroglicerynę.,%o overdosou em nitroglicerina.,,%o a luat o supradoză de nitroglicerină.,Игрок %o перебрал нитроглицерина.,,%o aşırı dozda nitro gliserin aldı. -%o is flayed into tiny little pieces.,OB_SPLASH,,,,%o byl@[ao_cs] sedřen@[ao_cs] na kousíčky.,%o er flået i småstykker.,%o wurde zerkleinert.,,%o estas senhaŭtiga en malgrandetaj pecoj.,%o es despellejad@[ao_esp] en trocitos pequeños.,,%o silpoutui riekaleiksi.,%o s'est fait éparpiller en petits morceaux.,%o ripityára szakadt szét.,%o è stato schiacciato.,%o は細かい粒をぶち撒けられた。,%o 은(는) 작은 입자로 분해되었다.,%o wordt gevild in kleine stukjes.,%o er flådd i bittesmå biter.,%o został@[ao_pl] roztrzaskan@[adj_pl] na małe kawałeczki.,%o foi detonad@[ao_ptb] em vários pedacinhos.,,%o s-a spart în mii de bucățele.,Игрока %o разодрали на мелкие клочки.,,%o küçük parçalara ayrıldı. -%o wanted to see what %g looked like inside-out.,OB_R_SPLASH,,,,"%o chtěl@[ao_cs] vědět, jak vypadá zevnitř.","%o ville se, hvordan han så ud indefra.",%o wollte @[pp_de] Innereien sehen.,,"%o volis vidi, kiel %g aspektus kun la interno ekstere.",%o quería ver que pinta tenía por dentro.,,%o halusi nähdä itsensä nurinperin.,%o voulait voir comment ses organes fonctionnent.,%o meg akarta tudni %g hogy néz ki belülről.,%o voleva vedere le sue interiora.,%o は %g が裏返しになるのを望んだ。,%o 은(는) 인체의 신비를 감상했다.,%o wilde zien hoe %g er binnenstebuiten uitzag.,%o ville se hvordan han så ut på innsiden.,%o chciał@[ao_pl] zobaczyć jak %g wygląda od środka.,%o queria ver como são os orgãos internos de %g.,,%o a vrut să vadă cum arăta %g întors pe dos.,"Игрок %o хотел посмотреть, что у него внутри.",,"%o, içinin dışının nasıl göründüğünü görmek istedi." -%o wanted to see what %g looked like inside-out.,OB_ROCKET,,,,"%o chtěl@[ao_cs] vědět, jak vypadá zevnitř.","%o ville se, hvordan han så ud indvfra.",%o wollte @[pp_de] Innereien sehen.,,"%o volis vidi, kiel %g aspektus kun la interno ekstere.",%o quería ver que pinta tenía por dentro.,,%o halusi nähdä itsensä nurinperin.,%o voulait voir comment ses organes fonctionnent.,%o meg akarta tudni %g hogy néz ki belülről.,%o voleva vedere le sue interiora.,%o は %g が裏返しになるのを望んだ。,%o 은(는) 퀀텀 여행을 즐겼다.,%o wilde zien hoe %g er binnenstebuiten uitzag.,%o ville se hvordan han så ut utenpå.,%o chciał@[ao_pl] zobaczyć jak %g wygląda od środka.,%o queria ver como são os orgãos internos de %g.,,%o a vrut să vadă cum arăta %g întors pe dos.,"Игрок %o хотел посмотреть, что у него внутри.",,%o içten dışa nasıl göründüğünü görmek istedi. -%o deleted %hself from the universe.,OB_KILLEDSELF,,,,%o se smazal@[ao_cs] z vesmíru.,%o slettede sig selv fra universet.,%o entfernte sich aus dem Universum.,,%o forigis sin el la universo.,%o se borró a si mism@[ao_esp] del universo.,,%o poisti itsensä maailmankaikkeudesta.,%o s'est effacé@[e_fr] de l'univers.,%o kitörölte magát az univerzumból,%o si è cancellato dall'universo.,%o はこの宇宙から消滅した。,%o 은(는) 자기 자신을 해킹했다.,%o schrapte zichzelf uit het universum.,%o slettet seg selv fra universet.,%o usun@[irreg_2_pl] się ze świata.,%o se deletou deste universo.,,%o s-a șters pe sine din univers.,Игрок %o стёр себя с лица вселенной.,,%o kendini evrenden sildi. -%o is no longer the dominant species.,OB_THUG,,,,%o už není vládnoucím živočichem.,%o er ikke længere den dominerende art.,%o ist nicht länger die dominante Spezies.,,%o ne estas la supera specio plu.,%o ya no es la especie dominante.,,%o ei ole enää vallitsevaa lajia.,%o n'est plus l'espèce dominante.,Már nem %o a csúcsragadozó.,%o non è più la specie dominante.,%o はもはや優性種ではなくなった。,%o 은(는) 그들의 시다바리가 아니였다.,%o is niet langer de dominante soort.,%o er ikke lenger den dominerende arten.,%o nie jest już dominującym gatunkiem.,%o não é mais a espécie dominante.,,%o nu mai e specia dominantă.,Игрок %o больше не доминантная форма жизни.,,%o artık baskın tür değil. -%o plugged in to the wrong machine.,OB_ANDROID,,,,%o se zapojil@[ao_cs] ke špatnému stroji.,%o har tilsluttet sig den forkerte maskine.,%o verband sich mit der falschen Maschine.,,%o konektiĝis en la eraran maŝinon.,%o se enchufó en la máquina equivocada.,,%o kytkeytyi väärään koneeseen.,%o s'est branché@[e_fr] à la mauvaise machine.,%o a rossz gépet dugta be.,%o connesso alla macchina sbagliata.,%o は違うマシンに接続してしまった。,%o 은(는) 잘못된 기계를 작동시켰다.,%o aangesloten op de verkeerde machine.,%o koblet seg til feil maskin.,%o podłączył@[ao_pl] się do złej maszyny.,%o se conectou na máquina errada.,,%o s-a conectat la mașina greșită.,Игрока %o подключили не к тому заряднику.,,%o yanlış makineye bağlandı. -%o got %hself a monster of a cyber-jockey-derriere-kicking.,OB_MONSTRUCT,,,,%o dostal@[ao_cs] šíleně kybernakopáno.,%o fik sig et monster af et cyber-jockey-derriere-spark.,%o bekam einen monströsen Cyber-Arschtritt verpasst.,,%o ricevis monstran cybernetik-raydist-postaĵ-piedbaton.,%o se ganó la madre de todas las patadas en el culo.,,%o sai hirviömäisen kyberlöylytyksen.,%o s'est fait@[e_fr] botter le cul de manière monumentale.,%o segge meg lett rugdosva.,% o ho avuto un mostruoso calcio cibernetico mancato.,%o は己に サイバー-ジョッキー-デリエレ-キッキング を取り入れた。,%o 은(는) 저 괴물의 슈퍼-울트라-캡쑝-파워를 맛봤다.,%o kreeg een monsterlijke cybertrap in @[zijn_haar_nl] kont.,%o fikk seg et monster av en cyber-jockey-derriere-sparking.,%o dostał@[ao_pl] cyber-kopa w dupę.,%o levou um cibercoice monstruoso nas fuças.,,%o s-a făcut praf în stil cibernetic.,Игрок %o получил поджопника от кибердиджея.,,%o kendine canavar gibi bir dayak attı. -%o got ICEd.,OB_ICE,,,,%o byl@[ao_cs] zmražen@[ao_cs] ICEm.,%o blev ICEd.,%o wurde verEISt.,,%o iĝis ICE-ita,%o fue ICEad@[ao_esp].,,%o raukkaa nyt varmaankin kICEmittää.,%o s'est fait@[e_fr] ICEr.,%o-t jégre tették.,% o è stato ghiacciato.,%o は冷えた。,%o 은(는) 지독하게 물어뜯겼다.,%o was IJS'd.,%o ble ICEd.,%o został@[ao_pl] zamrożon@[adj_pl].,%o foi peg@[ao_ptb] por um ICE. AI SE ferrou!,,%o a ÎNGHEȚat.,Игрок %o вляпался в ЛЁД.,,%o buzlandı. -%o feels a little buzzed.,OB_BUZZER,,,,%o dostal@[ao_cs] malou pecku.,%o føler sig lidt svimmel.,%o fühlt sich etwas gekitzelt.,,%o sentas sin iomete vibretita.,%o se siente algo zumbad@[ao_esp].,,%o raukan päässä hieman surisee.,%o sent le buzz.,%o-nak még mindig zúg a füle.,%o si sente solleticato un po '.,%o は少し賑やかになった。,%o 은(는) 짜릿하게 찔렸다.,%o voelt een beetje gezoemd.,%o føler seg litt beruset.,%o poczuł@[ao_pl] brzęczenie.,%o se sente meio chocad@[ao_ptb].,,%o se simte puțin șocat.,Игрок %o лёг спать в компании вертолётиков.,,%o biraz kafayı bulmuş gibi hissediyor. -%o uncovers a rather shocking development.,OB_STEALTH,,,,%o odhalil@[ao_cs] šokující informace.,%o opdager en temmelig chokerende udvikling.,%o machte eine schockierende Entdeckung.,,%o malkovras tre ŝokantan aferon.,%o descubre algo bastante chocante.,,%o raukalle paljastuu sangen sähköistävä uutinen.,%o a fait une découverte choquante.,"%o rájön, hogy az áram nem játék.",%o ha fatto una scoperta scioccante.,%o はかなり衝撃的な開発を発見した。,%o 은(는) 비밀리에 만들어진 병기를 발견했다.,%o ontdekt een nogal schokkende ontwikkeling.,%o avdekker en ganske sjokkerende utvikling.,%o odkrywa coś szokującego.,%o descobre uma revelação chocante.,,%o dezvăluie o schimbare șocantă.,Игрока %o встретил довольно серьёзный поворот событий.,,%o oldukça şok edici bir gelişmeyi ortaya çıkardı. -%o was erased from cyberspace.,OB_DMAN,,,,%o byl@[ao_cs] vymazán@[ao_cs] z kyberprostoru.,%o blev slettet fra cyberspace.,%o wurde aus dem Cyberspace gelöscht.,,%o estas viŝita el cyberspaco.,%o fue borrad@[ao_esp] del ciberespacio.,,%o poistettiin kyberavaruudesta.,%o s'est fait@[e_fr] effacer du cyberespace.,%o-t kitörölték a kibertérből.,%o è stato eliminato dal cyberspazio.,%o はサイバースペースに消去された。,%o 은(는) 영구차단을 당했다.,%o werd gewist uit cyberspace.,%o ble slettet fra cyberspace.,%o został@[ao_pl] usunięt@[adj_pl] z cyber przestrzeni.,%o foi deletad@[ao_ptb] do ciberespaço.,,%o a fost șters din spațiul cibernetic.,Игрока %o удалили из киберпространства.,,%o siber uzaydan silindi. -%o gave %hself a glass jaw.,OB_GLASS,,,,%o si přidělal@[ao_cs] skleněnou čelist.,%o gav sig selv en glaskæbe.,%o bekam ein Glaskinn.,,%o donis al si vitran makzelon.,%o se estampó contra un cristal.,,%o antoi itsellensä lasileuan.,%o s'est fait@[e_fr] vitrifier la figure.,%o állon vágta magát.,%o ha un mento di vetro.,%o は自身にグラスジョーを取り付けた。,%o 은(는) 유리창을 깨고 등장하는 액션 배우가 아니였다.,%o gaf zichzelf een glazen kaak.,%o ga seg selv en glasskjeve.,%o był@[ao_pl] zbyt delikatn@[adj_pl] ze szkłem.,%o tem um queixo de vidro.,,%o și-a făcut un maxilar de sticlă.,У игрока %o оказалась стеклянная челюсть.,,%o kendine cam çene taktı. -%o's life membership was terminated.,OB_MANIAC,,,,%o@[psn_cs] členství v klubu živých bylo přerušeno.,%os medlemskab på livstid blev opsagt.,%os Mitgliedschaft im Leben wurde beendet.,,La vivo-membrecon de %o estas finigita,%o tuvo su afiliación a la vida terminada.,,%o raukan elämänjäsenyys päätettiin.,L'abonnement à vie de %o est arrivé à sa fin.,%o elfelejtette befizetni az élők tagdíját.,L'appartenenza di %o alla vita è finita.,%o のメンバーシップ生活は終幕した。,%o 의 계정은 영원히 삭제되었다.,%o's levenslange lidmaatschap werd beëindigd.,%os livstidsmedlemskap ble avsluttet.,Członkowstwo %o w klubie żywych się skończyło.,%o não está mais afiliad@[ao_ptb] à vida.,,%o nu mai e membru al clubului celor vii.,Игрока %o исключили из клуба живых.,,%o hayata veda etti. -%o died in some random method I cannot fathom.,OB_MANIACHIT,,,,"%o umřel@[ao_cs] nějakým způsobem, který ani nemůžu pochopit.","%o døde på en eller anden tilfældig måde, som jeg ikke kan gennemskue.",%o starb auf eine unvorstellbare Art und Weise.,,"%o mortis per iu malcerta maniero, kiun mi ne povas kompreni.",%o murió de alguna manera que no llego a comprender.,,"%o kuoli jollakin sattumanvaraisella tavalla, jota en voi käsittää.",%o est mort@[e_fr] d'une manière que je n'arrive même pas à décrire.,Ötletem since hogy halt meg %o.,%o è morto in un modo inimmaginabile.,%o は計算外の乱数で死んだ。,%o 은(는) 의미불명의 이유로 잠수를 타게 되었다.,%o stierf op een of andere willekeurige manier die ik me niet kan voorstellen.,%o døde på en eller annen tilfeldig måte jeg ikke fatter.,"%o zgin@[irreg_2_pl] pod wpływem metody, której nie mogę pojąć.",%o morreu de alguma forma aleatória que nem consigo imaginar.,,%o a murit într-un mod aleatoriu pe care nu mi-l pot închipui.,Игрок %o внезапно умер по непостижимой для меня причине.,,%o anlayamadığım rastgele bir yöntemle öldü. -%o was fried by a femme fatale freak.,OB_TERMIN,,,,%o byl@[ao_cs] usmažen@[ao_cs] šílenou femme fatale.,%o blev stegt af en femme fatale freak.,%o wurde von einem Femme-Fatale Freak gebraten.,,%o estis fritita de femme-fatale-groteskulo.,%o fue tostad@[ao_esp] por una femme fatale.,,%o joutui kohtalokkaan kimman kärtsäämäksi.,%o s'est fait@[e_fr] frire par une femme fatale.,%o-t lebombázta egy bomba nő.,% o è stato fritto da una femme fatale.,%o はファム ファタル フリークに揚げられた。,%o 은(는) 미인계에 발을 들였다.,%o werd gebakken door een femme fatale freak.,%o ble stekt av en femme fatale-freak.,%o został@[ao_pl] usmażon@[adj_pl] przez szaloną femme fatale.,%o foi fritad@[ao_ptb] por uma femme fatale psicótica.,,%o a fost prăjit de către o femme fatale psihopată.,Игрока %o поджарила чокнутая роковая женщина.,,%o bir femme fatale ucubesi tarafından kızartıldı. -%o got a little close to the opposite sex.,OB_TERMINHIT,"This text is not gender neutral, obviously...",,,%o se moc přiblížil@[ao_cs] k opačnému pohlaví.,%o kom lidt tæt på det modsatte køn.,%o kam dem anderen Geschlecht zu nahe.,,%o iĝis iomete proksime al la mala sekso.,%o se acercó demasiado a la persona equivocada.,,%o meni hieman liian lähelle vastakkaista sukupuolta.,%o s'est trop rapproché@[e_fr] de la mauvaise personne.,%o túl közel került az ellenkező nemhez.,%o è arrivato troppo vicino all'altro sesso.,%o は少し異性に成り果てた。,%o 의 남자다운 자존심은 쪼그라들었다.,%o kwam een beetje in de buurt van het andere geslacht.,%o kom litt nær det motsatte kjønn.,%o pod@[irreg_1_pl] zbyt blisko do płci pięknej.,%o chegou perto demais do sexo oposto.,,%o s-a apropriat prea mult de sexul opus.,Игрок %o почти сблизился с противоположным полом.,,%o karşı cinsle biraz yakınlaştı. -%o said goodbye to an old friend.,OB_REPLI,,,,%o řekl@[ao_cs] sbohem starému příteli.,%o sagde farvel til en gammel ven.,%o verabschiedete sich von einem alten Freund.,,"%o diris ""Ĝis la revido"" al malnova amiko.",%o se despidió de un viejo amigo.,,%o sanoi hyvästit vanhalle ystävälle.,%o dit au revoir à un vieil ami.,%o búcsút intett egy régi barátjának.,%o ha detto addio a un vecchio amico.,%o は古い友人に別れを告げた。,%o 은(는) 오랜 친구와 작별인사를 했다.,%o nam afscheid van een oude vriendin.,%o tok farvel med en gammel venn.,%o pożegnał@[ao_pl] się ze starym znajomym.,%o disse adeus a um velho amigo.,,%o a spus adio unui vechi prieten.,Игрок %o распрощался со старым другом.,,%o eski bir arkadaşına veda etti. -%o was stabbed in the back by an old friend.,OB_REPLIHIT,,,,%o byl@[ao_cs] bodnuta do zad starým přítelem.,%o blev stukket i ryggen af en gammel ven.,%o wurde von einem alten Freund in den Rücken gestochen.,,%o estis pikita en la dorson de malnova amiko.,%o fue apuñalad@[ao_esp] en la espalda por un viejo amigo.,,%o joutui vanhan ystävän selkäänpuukottamaksi.,%o s'est fait@[e_fr] planter une lame dans le dos par un vieil ami.,%o-t hátba szúrta egy régi barát.,%o è stato pugnalato alla schiena da un vecchio amico.,%o は古い友人に背中を刺された。,%o 은(는) 오랜 친구에게 배신을 당했다.,%o werd in de rug gestoken door een oude vriend.,%o ble dolket i ryggen av en gammel venn.,%o został@[ao_pl] dźgnięt@[adj_pl] w plecy przez starego znajomego.,%o foi apunhalad@[ao_ptb] pelas costas por um velho amigo.,,%o a fost înjunghiat pe la spate de către un vechi prieten.,Игрок %o получил нож в спину от старого друга.,,%o eski bir arkadaşı tarafından sırtından bıçaklandı. -%o was weeded out by natural selection.,OB_PHAGE,,,,%o byl@[ao_cs] vyčištěna přirozeným výběrem.,%o blev sorteret fra ved naturlig udvælgelse.,%o fiel der natürlichen Auslese zum Opfer.,,%o estis foriga de natura elektado.,%o fue eliminad@[ao_esp] por selección natural.,,%o joutui luonnonvalinnan kitkemäksi.,%o a été éliminé@[e_fr] par la sélection naturelle.,A természetes kiválasztás áldozata lett %o.,%o cadde vittima della selezione naturale.,%o は自然淘汰によって除草された。,%o 은(는) 약육강식을 지금까진 모르고 있었다.,%o werd door natuurlijke selectie weggehaald.,%o ble luket ut av naturlig seleksjon.,%o został@[ao_pl] przesian@[adj_pl] przez naturalną selekcję.,%o foi eliminad@[ao_ptb] por seleção natural.,,%o a fost eliminat prin selecție naturală.,Игрок %o был отсеян естественным отбором.,,%o doğal seleksiyon tarafından ayıklandı. -%o couldn't escape a thorny death.,OB_THORN,,,,%o nemohl@[ao_cs] utéct bodlavé smrti.,%o kunne ikke undslippe en tornedød.,%o konnte einem dornigen Tod nicht entkommen.,,%o ne povis eskapi dornan morton.,%o no pudo escapar una muerte espinosa.,,%o ei kyennyt välttämään piikikästä kuolemaa.,%o n'a pu éviter une mort piquante.,Lyukasra szúrták %o-t a tövisek.,%o non poteva sfuggire a una morte spinosa.,%o は棘のある死から逃げられなかった。,%o 은(는) 따가운 죽음을 피할 수 없었다.,%o kon niet ontsnappen aan een netelige dood.,%o kunne ikke unnslippe en tornefull død.,%o nie m@[irreg_4_pl] uciec przed cierniową śmiercią.,%o não conseguiu escapar de uma morte espinhosa.,,%o nu a putut scăpa de o moarte spinoasă.,Игрока %o поджидала смерть на его тернистом пути.,,%o dikenli bir ölümden kaçamadı. -%o took a sumo punch to the groin.,OB_SUMATIC,,,,%o dostal@[ao_cs] sumo ránu pod pás.,%o fik et sumo-slag i lysken.,%o bekam einen Sumo-Schlag an @[pp_de] empfindlichste Stelle.,,%o prenis sumoan baton en la ingveno.,%o recibió un puñetazo de sumo en la entrepierna.,,%o otti vastaan sumoiskun nivusiin.,%o s'est pris le poing d'un sumo dans l'entrejambe.,%o szerszámjával tompította az jobb horgot.,%o ha ricevuto un soffio su un punto sensibile.,%o は股座にスモウ ハリテを食らった。,%o 은(는) 가랑이 사이에 정권을 찔렀다.,%o nam een sumo punch in de lies.,%o fikk et sumoslag i skrittet.,%o dostał@[ao_pl] cios sumo w pachwinę.,%o tomou um golpe de sumô na virilha.,,%o a primit un pumn sumo în vintre.,Игрок %o отхватил удар в пах от сумоиста.,,%o kasıklarına bir sumo yumruğu yedi. -%o didn't get %p three wishes.,OB_GENIE,,,,%o nedostal@[ao_cs] svá tři přání.,%o fik ikke sine tre ønsker.,%o bekam @[pp_de] drei Wünsche nicht erfüllt.,,%o ne ricevis siajn tri petojn.,%o no recibió sus tres deseos.,,%o ei saanut kolmea toivettaan.,%o n'a pas préparé ses trois vœux.,%o nem teljesítette %p 3 kívánságát.,%o non ha soddisfatto i suoi tre desideri.,%o は %p に三願を望まなかった。,%o 은(는) 세 가지 소원을 빌 수 없었다.,%o kreeg niet drie wensen.,%o fikk ikke oppfylt tre ønsker.,%o nie dostał@[ao_pl] swoich trzech życzeń.,%o não concedeu três desejos a %p.,,%o nu a putut să-și pună cele trei dorințe.,Игрок %o не загадает трёх желаний.,,%o üç dileğini yerine getiremedi. -%o tried to pet a mine.,OB_MINE,,,,%o se pokusil@[ao_cs] pohladit minu.,%o forsøgte at kæle for en mine.,"%o versuchte, eine Mine zu streicheln.",,%o provis glatumi minon.,%o intentó acariciar una mina.,,%o yritti silittää miinaa.,%o a essayé de caresser une mine.,%o meg akart simogatni egy aranyos aknát.,%o ha provato ad accarezzare una mina.,%o は地雷を愛撫しようとした。,%o 은(는) 기뢰와 친구가 되고 싶었다.,%o probeerde een mijn te aaien.,%o prøvde å klappe en mine.,%o próbował@[ao_pl] pogłaskać minę.,%o tentou fazer carinho numa mina.,,%o a încercat să mângâie o mină.,Игрок %o хотел погладить мину.,,%o bir mayını sevmeye çalıştı. -%o took %k's Bruce Lee fu-kick to the face.,OB_MPKICK,,,,%o dostal@[ao_cs] kopanec do obličeje od kung-fuistou %k.,%o fik %ks Bruce Lee fu-kick i ansigtet.,%o bekam einen Bruce-Lee-Fußtritt ins Gesicht.,,%o ricevis la Bruce Lee piedbaton de %k en sia vizaĝo.,%o se comió una patada de kung-fu a lo Bruce Lee de %k.,,%k potkaisi %o raukkaa päin naamaa Bruce Leen kung fu-tyyliin.,%o s'est mangé@[e_fr] un coup de pied à la Bruce Lee de la part de %k.,%o arccal vette le %k pörgőrugását.,%o ha un calcio in faccia.,%o の顔に %k のブルースリーキックを当てた。,%o 은(는) %k 의 거침없는 하이킥을 받았다.,%o nam %k's Bruce Lee fu-kick in het gezicht.,%o tok %ks Bruce Lee fu-kick i ansiktet.,%o dostał@[ao_pl] kopniakiem w stylu Bruce'a Lee od %k.,%o tomou uma voadora de %k na cara.,,%o a primit un șut în stil Bruce Lee.,"Игрок %o отхватил от игрока %k удар в лицо, достойный Брюса Ли.",,"%o, %k tarafından tekmelendi." -%o fell apart via %k's shocking revelation.,OB_MPREZNATOR,,,,%o se rozpadl@[ao_cs] šokujícím odhalením hráče %k.,%o faldt fra hinanden via %ks chokerende åbenbaring.,%o erhielt eine schockierende Enthüllung von %k.,,%o diseriĝis pro la ŝokantan revelaĉio de %k.,%o cayó ante la revelación chocante de %k.,,%o romahti käyttäjän %k sähköistävästä ilmestyksestä.,%o a été témoin de la révélation choquante de %k.,%k megrázó élmányben részesítette %o-t.,%o ricevette una scioccante rivelazione da %k.,%o は %k の衝撃的な啓示によりバラバラになった。,%o 은(는) %k 이(가) 선사한 전기 찜질을 맛봤다.,%o viel uit elkaar via %k's schokkende onthulling.,%o falt fra hverandre via %ks sjokkerende åpenbaring.,%o rozpadł@[ao_pl] się pod wpływem szokującego objawienia %k.,%o ficou arrasad@[ao_ptb] pela revelação chocante de %p.,,%o s-a făcut praf la revelația șocantă a lui %k.,Игрок %o шокирован откровениями %k.,,"%o, %k tarafından kızartıldı." -%o took a double-dose of %k's punishment.,OB_MPXPISTOL,,,,%o dostal@[ao_cs] dvojitou dávku potrestání hráče %k.,%o fik en dobbeltdosis af %ks straf.,%o bekam eine doppelte Dosis von %ks Bestrafung.,,%o duoble dozis la puno de %k.,%o recibió una doble dosis del castigo de %k.,,%o otti tupla-annoksen käyttäjän %k kuritusta.,%o a mangé une double dose de la furie de %k.,%o ólom túladagolást kapott %k-tól.,%o ha ottenuto una doppia dose della punizione di %k.,%o は %k の懲罰を二度受けた。,%o 은(는) %k 의 2총신 사격을 받았다.,%o nam een dubbele dosis van %k's straf.,%o tok en dobbel dose av %ks straff.,%o dostał@[ao_pl] podwójną dawkę kary %k.,%o tomou uma dose dupla da punição de %k.,,%o a luat o doză dublă din pedeapsa lui %k.,Игрок %o принял двойную дозу возмездия от %k.,,"%o, %k tarafından cezalandırıldı." -%o was shut down by %k's shock-stick.,OB_MPTAZER,,,,%o byl@[ao_cs] vypnut@[ao_cs] šokádou hráče %k.,%o blev lukket ned af %ks chok-stick.,%o wurde von %ks Schockstab ausgeschaltet.,,%o estis malŝaltita de la ŝokbateno de %k.,%o fue noquead@[ao_esp] por la vara eléctrica de %k.,,%o joutui käyttäjän %k sähkökepin sammuttamaksi.,%o s'est fait mettre K.O par le bâton électrique de %k.,"%o-t sokkolta a hír, hogy %k-t megölte.",%o è stato spento dalla bacchetta di %k.,%o は %k のショックスティックでシャットダウンした。,%o 은(는) %k 의 무력행사에 아예 포기했다.,%o werd uitgeschakeld door %k's schokstick.,%o ble stengt av %ks sjokkpinne.,%o został@[ao_pl] wyłączon@[adj_pl] przez szokującą pałkę %k.,%o foi desligado pelo espeto chocante de %k.,,%o a fost dezactivat de arma cu șocuri a lui %k.,Игрок %o выведен из строя электродубинкой %k.,,"%o, %k tarafından kapatıldı." -%o got a face-full of %k's ice-cold wrath.,OB_MPCRYOGUN,,,,%o se zabořil@[ao_cs] do mrazivého hněvu hráče %k.,%o fik et ansigt fuld af %ks iskolde vrede.,%o bekam eine Ladung von %ks eiskaltem Zorn ins Gesicht.,,%o ricevis la glacie malvarman koleregon de %k.,%o recibió la ira gélida de %k en toda la cara.,,%o sai saamansa täyteen käyttäjän %k jääkylmää vihaa.,%o s'est fait congeler la figure par la colère glaciale de %k.,%k jégre tette %o-t,%o ha un carico di freddo gelido di %k in faccia.,%o は %k の冷めた表情で凍った。,%o 은(는) %k 덕분에 맛있게 냉동 보존되었다.,%o kreeg een gezicht vol met %k's ijskoude toorn.,%o fikk ansiktet fullt av %ks iskalde vrede.,%o dostał@[ao_pl] wielką dawkę mroźnego gniewu %k.,%o tomou um gelo de %k. ,,%o a simțit din plin furia rece a lui %k.,Игрок %o столкнулся с ледяной ненавистью %k.,,"%o, %k tarafından donduruldu." -"%o was drilled full of holes by %k, gangsta-style.",OB_MPUZI,,,,%o byl@[ao_cs] prostřílen@[ao_cs] skrz na skrz gangsterem %k.,"%o blev boret fuld af huller af %k, på gangsta-stil.",%o wurde von %k im Gangsta-Stil perforiert.,,"%o estis borita truplena de %k, ganstere.","%o fue acribillad@[ao_esp] por %k, al estilo gangster.",,%k porasi %o raukan täyteen reikiä gangsta-tyyliin.,"%o s'est fait perforer dans tous les sens par %k, Gangsta style.",%o gengszter stílusban sajttá lyuggatta %k,%o è stato perforato da %k in stile gangsta.,%o はギャングの様な %k に蜂の巣にされた。,%o 은(는) %k 이(가) 선사한 갱스터 스타일 난사를 막지 못했다.,"%o werd vol gaten geboord met %k, in gangsta-stijl.","%o ble boret full av hull av %k, i gangsta-stil.",%o został@[ao_pl] podziurawion@[adj_pl] przez %k niczym gangster.,%o tomou pipoco de %k.,,%o a fost umplut de găuri în stil mafiot de către %k.,Игрок %o покрылся дырками после гангста-стрельбы игрока %k.,,"%o, %k tarafından gangsta tarzı delik deşik edildi." -%o ate %k's photon bomb.,OB_MPZOOKA,,,,%o sežral@[ao_cs] fotonovou bombu hráče %k.,%o spiste %ks fotobombe.,%o nahm %ks Photonenbombe.,,%o manĝis la fotonbombon de %k.,%o se comió la bomba de fotones de %k.,,%o söi käyttäjän %k fotonipommin.,%o a bouffé la bombe photonique de %k.,%o megette %k foton bombáját,%o ha preso la bomba fotonica di %k.,%o は %k のフォトンボムを食らった。,%o 은(는) %k 의 광자탄을 봤는데도 피하지 못했다.,%o at %o %k's fotonbom.,%o spiste %ks fotonbombe.,%o zjadł@[ao_pl] fotonową bombę %k.,%o engoliu a bomba de fótons de %k.,,%o a mâncat bomba fotonică a lui %k.,Игрок %o съел фотонную бомбу %k.,,"%o, %k tarafından atomize edildi." -%o was reduced to a neat pile of photons by %k.,OB_MPZ_SPLASH,,,,%o byl@[ao_cs] zredukován@[ao_cs] na hromádku fotonů hráčem %k.,%o blev reduceret til en ordentlig bunke fotoner af %k.,%o wurde von %k zu einem Haufen Photonen verarbeitet.,,%o estis reduktita en ordeman amason da fotonoj de %k.,%o fue reducid@[ao_esp] a una pila de fotones por %k.,,%k redusoi %o raukan sieväksi fotonipinoksi.,%o s'est fait@[e_fr] réduire en une jolie pile de photons par %k.,%o-ból csak egy marokni fotont hagyott hátra %k,%o è stato elaborato da %k in un mucchio di fotoni.,%o は %k によって蛍光灯にされた。,%o 은(는) %k 의 광자력을 탐냈다. 죽기 전까지는.,%o werd gereduceerd tot een nette stapel fotonen met %k.,%o ble redusert til en pen haug med fotoner av %k.,%o został@[ao_pl] zredukowan@[adj_pl] do maleńkiej kupki fotonów przez %k.,%o foi reduzido à uma bela pilha de fótons por %k.,,%o a fost transformat într-o grămadă simpatică de fotoni de către %k.,Игрок %o был разложен игроком %k в аккуратную кучку фотонов.,,"%o, %k tarafından düzgün bir foton yığınına indirgendi." -%o was reduced to antimatter by %k.,OB_MPANTIGUN,"Physically this is utter nonsense, of course.",,,%o byl@[ao_cs] zredukován@[ao_cs] na antihmotu hráčem %k.,%o blev reduceret til antimaterie af %k.,%o wurde von %k zu Antimaterie reduziert.,,%o estis reduktita en antimaterion de %k.,%o fue reducid@[ao_esp] a antimateria por %k.,,%k redusoi %o raukan antimateriaksi..,%o s'est fait inverser les atomes par %k.,%k antianyaggá lőttte %o-t,%o è stato ridotto all'antimateria da %k,%o は %k のにより反物質に変換された。,%o 은(는) %k 의 반물질의 힘에 의해 소멸되었다.,%o werd gereduceerd tot antimaterie met %k.,%o ble redusert til antimaterie av %k.,%o został@[ao_pl] zredukowan@[adj_pl] do antymaterii przez %k.,%o foi transformado em antimatéria por %k.,,%o a fost transformat în antimaterie de către %k.,Игрок %o был разложен игроком %k до антиматерии.,,"%o, %k tarafından atomlara indirgendi." -%o swallowed %k's nuke.,OB_MPNUKE,,,,%o spolkl@[ao_cs] atomovku hráče %k.,%o slugte %ks atombombe.,%o verschluckte sich an %ks Atomrakete.,,%o glutis la nuklean bombon de %k.,%o se tragó la bomba atómica de %k.,,%o nieli käyttäjän %k ydinpommin.,%o s'est pris@[e_fr] la bombe thermonucléaire de %k dans la figure.,%o megette %k atombomáját,%o soffocò sul missile nucleare di %k.,%o は %k の核を飲み干した。,%o 은(는) %k 덕분에 하늘을 뚫을 버섯구름이 되었다.,%o geslikt %o nuke %k's nuke.,%o svelget %ks atombombe.,%o połkn@[irreg_2_pl] atomówkę %k.,%o engoliu o míssil núclear de %k.,,%o a înghițit proiectilul lui %k.,Игрок %o проглотил ядерный заряд %k.,,"%o, %k tarafından bombalandı." -%o went nuclear from %k's mass destruction spree.,OB_MPNUKESPLASH,,,,%o si zkrátil@[ao_cs] svůj poločas rozpadu při zabijačce hráče %k.,%o blev atomvåben af %ks masseødelæggelser.,%o wurde von %ks Massenzerstörungsaktion verstrahlt.,,%o iĝis nuklea pro la amasdetruado de %k.,%o se volvió radioactiv@[ao_esp] por la racha de destrucción masiva de %k.,,%o muuttui radioaktiiviseksi käyttäjän %k massatuhoputken takia.,%o s'est fait@[e_fr] irradier par la folie destructrice de %k.,%o felrobbant az idegtől amikor meglátta %k bombáját,%o fu irradiato dall'azione di distruzione di massa di %k.,%o は %k の虐殺ごっこの犠牲者になった。,%o 은(는) %k 의 핵실험에 참여했다.,%o werd nucleair van de massavernietigingswoede van %k's massavernietigingswoede.,%o ble nuklear av %ks masseødeleggelse.,%o został@[ao_pl] napromieniowan@[adj_pl] przez masową destrukcję %k.,%o virou picadinho radioativo por causa da destruição em massa causada por %k.,,%o a devenit radioactiv în urma distrugerii în masă a lui %k.,Игрок %o светится в темноте от оружия массового поражения %k.,,"%o, %k tarafından bombalandı." -%o was turned inside-out by %k.,OB_MPTELEFRAG,,,,%o byl@[ao_cs] obrácen@[ao_cs] naruby hráčem %k.,%o blev vendt ud og ind af %k.,%o wurde von %k zerfetzt.,,La interno de %o estis eksteriga de %k.,%o fue puest@[ao_esp] del revés por %k.,,%k käänsi %o raukan nurinpäin.,%o s'est fait@[e_fr] inverser par %k.,%k kifordította %o-t,%o fu fatto a pezzi da %k,%o は %k に裏返しにされた。,%o 은(는) %k 에 의해 자신이 분해되는 꼴을 못 봤다.,%o werd binnenstebuiten gekeerd met %k.,%o ble snudd på hodet av %k.,%o został@[ao_pl] wywrócon@[adj_pl] na lewą stronę przez %k.,%o foi virad@[ao_ptb] ao avesso por %k.,,%o a fost întors pe dos de către %k.,Игрок %o вывернут наизнанку игроком %k.,,"%o, %k tarafından parçalandı." -%o's atomic structure was split apart.,OB_MONTELEFRAG,,,,Struktura atomů hráče %o se rozpadla.,%os atomstruktur blev splittet op.,%os Atomstruktur wurde vernichtet.,,La atoma strukturo de %o estis disfendita.,%o fue desintegrad@[ao_esp] al nivel atómico.,,%o raukan atomirakenne hajosi.,%o s'est fait@[e_fr] désassembler au niveau atomique.,%o atomjaira esett szét,La struttura atomica di %o fu distrutta.,%o の原子構造は分解された。,%o 의 원자 마디마디가 흩어졌다.,De atoomstructuur van %o werd gesplitst.,%o's atomstruktur ble splittet fra hverandre.,Atomy %o zostały od siebie oddzielone.,A estrutura atômica de %o foi separada.,,Structura atomică a lui %o a fost spulberată.,Атомная структура игрока %o разрушена.,,%o atomik düzeyde parçalara ayrıldı. -%o spontaneously expired.,OB_DEFAULT,,,,%o samovolně vypršel@[ao_cs].,%o udåndede spontant.,%o hörte spontan auf zu existieren.,,%o spontane finiĝis.,%o tuvo una muerte espontánea.,,%o spontaanisti kupsahti.,%o a spontanément expiré.,%o hirtelenjében elérte a lejárati időt,%o ha smesso spontaneamente di esistere.,%o の有効期限が自発的に切れた,%o 은(는) 파란만장하게 사라졌다.,%o is spontaan verlopen.,%o gikk spontant til grunne.,%o spontanicznie umarł@[ao_pl].,%o pereceu expontâneamente.,,%o a expirat în mod spontan.,Время игрока %o неожиданно вышло.,,%o kendiliğinden öldü. -You grab a NUKER! Suck on this!,GOTNUKER,,,,Sebral@[ao_cs] jsi ATOMOVKÁTOR! Pojď na to!,Du tager en NUKER! Sut på den!,Ein NUKER! Verschluck dich daran.,,Vi prenis NUKER! Jen havu!,¡Has pillado un NUKER! ¡Chupaos esa!,¡Has recogido un NUKER! ¡Chúpate esa!,%Kahmaiset YDÄRIN! Ime tätä!,Vous découvrez le NUKER! Ca va en chier!,Meglelted a NUKER-t! Ezt kapd ki!,Prendi un NUKER! Succhia su questo!,NUEKR を奪った! 覚悟しろ!,누커 획득! 한바탕 쓸어볼까!,Je pakt een NUKER! Zuig hier maar aan!,Ta en NUKER! Sug på denne!,Podniosłeś ATOMÓWKĘ! Ssijcie to!,Você pegou um NUKER! Chupa essa manga!,,Ai ridicat Lansatorul Nuclear! Ia de-aici!,Заполучен ЯДЕРНЫЙ ГРАНАТОМЁТ! Отсосите!,,Sen bir NÜKER kap! Bunu em! -You got an UZI!!,GOTUZI,,,,Získal@[ao_cs] jsi UZI!,Du har en UZI!!,UZI genommen!,,Vi prenis UZI!!,¡¡Has obtenido una UZI!!,,Sait UZIn!!,Vous chopez un UZI!,Meglelted az UZI-t!,Hai un UZI !!,UZI をゲットした!!,우지 기관단총 획득!,Je hebt een UZI!!,Du har en UZI!,Zdobyłeś UZI!!,Você pegou uma UZI!!,,Ai ridicat un UZI!!,Заполучен УЗИ!!,,Bir UZI'n var! -A HOIG Reznator - FRY some butt,GOTREZNATOR,,,,HOIG Reznátor - pár jich upeč,En HOIG Reznator - Fritér noget røv,Ein HOIG Reznator.,,HOIG-Reznilo - FRITU pugon!,Un Reznator HOIG. ¡Hora de freir traseros!,,HOIG-reznaattori - KÄRISTÄ takamuksia,"Un Reznator HOIG, allez frire du monde!",Egy HOIG Reznator - okozz pár megrázó élményt,Un Reignator HOIG - friggere un po 'di carne,HOIGレジネイター - ぶっ潰してやれ,HOIG 전자무력기 획득! 전기 통구이를 만들자고!,Een HOIG Reznator - FRY sommige kont,En HOIG Reznator - FRY litt rumpe!,Reznator HOIG - skop trochę tyłków,Um Reznador HOIG - Hora de fritar,,Un Rezonator HOIG - Arde-i!,ХОЙГ Резнатор,,Bir HOIG Reznator - Biraz kıç kızartın -You got a Photon 'Zooka!,GOTPHOTONZOOKA,,,,Sebral@[ao_cs] jsi Fotonovou bazuku!,Du har en Photon 'Zooka!,Photonen-'zooka genommen!,,Vi prenis Fotonbazukon!,¡Has obtenido un Bazooka de Fotones!,,Sait fotonisingon!,Vous récupérez un Bazooka Photonique!,Meglelted a Foton Ágyút!,Hai un cannone Photon!,フォトン'ゾーカ をゲットした!,광자 바주카 획득!,Je hebt een Photon 'Zooka!,Du har en Photon 'Zooka!,Zdobyłeś Fotonozukę!,Você pegou uma Bazuca de Fótons!,,Ai ridicat o Bazooka Fotonică!,Заполучена фотон-базука!,,Bir Foton 'Zooka'n var! -You carry a Big Stick!,GOTBIGSTICK,,,,Nosíš velkou bouchačku!,Du har en Big Stick!,Du trägst einen langen Stock.,,Vi portas grandan bastonon!,¡Llevas un Gran Palo!,,Kannat isoa keppiä!,Vous avez un gros bâton!,Nagy bottal jársz öcsém!,Porti un grosso bastone!,ビッグスティック を手に取った!,반물질 봉 획득!,Je draagt een Big Stick!,Du har en Big Stick!,Podnosisz Wielką Pałkę!,Você pegou um Grande Bastão!,,Ai ridicat un Băț Lung!,Заполучена длинная палка!,,Büyük bir sopa taşıyorsun! -You got a Tazer!!,GOTTAZER,,,,Získal@[ao_cs] jsi tazer!,Du har en Tazer!!,Tazer genommen!,,Vi prenis Elektropafilon!!,¡¡Has obtenido un Taser!!,,Sait etälamauttimen!!,Vous trouvez un Taser!,Meglelted a Sokkolót!,Hai un Taser !!,テイザー をゲットした!,테이져 획득!,Je hebt een Tazer!!,Du har en Tazer!,Zdobyłeś Tazer!!,Você pegou um Tazer!!,,Ai ridicat un Taser!!,Заполучен тазер!,,Bir Tazer'ın var!! -You grab a Cryogun! FREEZE!,GOTCRYOGUN,,,,Sebral@[ao_cs] jsi krypušku! ANI SE NEHNI!,Du har en Cryogun! Frys!,Cryowaffe genommen! GEFRIER!,,Vi prenis Kriogenikpafilon! FROSTIĜU!,¡Has pillado un Criogenizador!! ¡Todos quietos!,¡Has recogido un Criogenizador!! ¡Quietos todos!,Kahmaiset kryopyssyn! PYSÄHDY!,Vous prenez un Cryogun! On s'arrête!,Felkapod a Cryogun-t! Induljon a fagyasztás!,Prendi un Cryogun! CONGELARE!,クライォガン を奪った! フリーズ!,크라이로건 획득! 그대로 멈춰라!,Je pakt een Cryogun! FREEZE!,Du har en Cryogun! FREEZE!,Podniosłeś Zamrażarkę! STAĆ!,Você pegou uma Cryogun! FICA FRIO AÍ!,,Ai ridicat o Crio-armă! ÎNGHEAȚĂ!,Заполучена замораживающая пушка! НИ С МЕСТА!,,Bir Cryogun al! DONDUR! -You grab some rounds!,GOTROUNDS,,,,Sebral@[ao_cs] jsi nějaké náboje!,Du tager nogle patroner!,Munition genommen.,,Vi prenis kuglojn!,¡Has pillado unas balas!,¡Has recogido unas balas!,Kahmaiset patruunoita!,Vous prenez des balles!,Felkapsz pár lőszert!,Prendi delle munizioni!,幾つかのラウンド を奪った!,권총 탄약을 주웠다!,Je pakt wat rondes!,Du tar noen runder!,Podniosłeś trochę naboi!,Você pegou munição!,,Ai ridicat niște muniție!,Заполучена обойма патронов!,,Biraz mermi al! -You grab a case of rounds!,GOTROUNDSCASE,,,,Sebral@[ao_cs] jsi krabici nábojů!,Du tager en kasse med patroner!,Munitionskiste genommen.,,Vi prenis skatolon da kugloj!,¡Has pillado una caja de balas!,¡Has recogido una caja de balas!,Kahmaiset patruunalaatikon!,Vous prenez une bôite de balles!,Felkapsz egy doboz lőszert!,Prendi un caso di munizioni!,ケースのラウンド を奪った!,권총 탄약 상자를 주웠다!,Je pakt een kist met rondes!,Du tar en kasse med patroner!,Podniosłeś skrzynkę naboi!,Você pegou uma caixa de munição!,,Ai ridicat un cartuș de muniție!,Заполучена коробка патронов!,,Bir kutu mermi al! -You grab a Torpedo!,GOTTORPEDO,"Was ""grap"" for some reason.",,,Sebral@[ao_cs] jsi torpédo!,Du tager en Torpedo!,Torpedo genommen.,,Vi prenis Torpedon!,¡Has pillado un torpedo!,¡Has recogido un torpedo!,Kahmaiset torpedon!,Vous prenez une torpille!,Felkapsz egy Torpedót!,Prendi un siluro!,トルペード を奪った!,광자탄을 주웠다!,Je pakt een Torpedo!,Du tar en Torpedo!,Podniosłeś Torpedę!,Você pegou um Torpedo!,,Ai ridicat o Torpilă!,Заполучена торпеда!,,Bir Torpido al! -You grab a case of Torpedos!,GOTTORPEDOS,,,,Sebral@[ao_cs] jsi krabici torpéd!,Du tager en kasse med torpedoer!,Torpedokiste genommen.,,Vi prenis skatolon da Torpedoj!,¡Has pillado una caja de torpedos!,¡Has recogido una caja de torpedos!,Kahmaiset torpedolaatikon!,Vous prenez une bôite de torpilles!,Felkapsz egy doboz Torpedót!,Prendi un caso di siluri!,トルペードのケース を奪った!,광자탄 무더기를 주웠다!,Je pakt een kist Torpedo's!,Du tar en kasse med torpedoer!,Podniosłeś skrzynkę Torped!,Você pegou uma caixa de Torpedos!,,Ai ridicat o cutie de Torpile!,Заполучен ящик торпед!,,Bir kasa Torpido al! -You grab a molecule module!,GOTMOLECULES,,,,Sebral@[ao_cs] jsi molekulový modul!,Du tager et molekylmodul!,Molekülmodul genommen,,Vi prenis molekulmodulon!,¡Has pillado un módulo molecular!,¡Has recogido un módulo molecular!,Kahmaiset molekyylimoduulin!,Vous prenez un module moléculaire!,Felkapsz egy molekula modult!,Prendi un modulo molecolare!,モーレキュールモヂュール を奪った!,분자 모듈을 주웠다!,Je pakt een molecuulmodule!,Du tar en molekylmodul!,Podniosłeś molekularny moduł!,Você pegou um módulo molecular!,,Ai ridicat un modul molecular!,Заполучен молекулярный модуль!,,Bir molekül modülü kap! -You grab a tank full of molecules!,GOTMOLECULESTANK,,,,Sebral@[ao_cs] jsi sud plný molekul!,Du tager en tank fuld af molekyler!,Tank mit Molekülmodulen genommen.,,Vi prenis reservujon da molekulojn!,¡Has pillado un tanque lleno de moléculas!,¡Has recogido un tanque lleno de moléculas!,Kahmaiset tankin täynnä molekyylejä!,Vous prenez un réservoir de molécules!,Felkapsz egy teli tank molekulát!,Prendi un serbatoio pieno di molecole!,タンク満タンのモーレキュール を奪った!,분자 탱크를 주웠다!,Je pakt een tank vol met moleculen!,Du tar en tank full av molekyler!,Podniosłeś zbiornik pełen molekuł!,Você pegou um tanque cheio de moléculas!,,Ai ridicat un rezervor plin cu molecule!,Заполучен контейнер с молекулами!,,Moleküllerle dolu bir tank al! -You grab some Cartridges!,GOTCARTRIDGES,,,,Sebral@[ao_cs] jsi nějaké kazety!,Du tager nogle patroner!,Magazin genommen.,,Vi prenis iom da kartoĉoj!,¡Has pillado unos cartuchos!,¡Has recogido unos cartuchos!,Kahmaiset kasetteja!,Vous prenez des cartouches!,Felkapsz pár Töltényt!,Prendi alcune cartucce!,残弾のカートリッジ を奪った!,카트리지 한 줌을 주웠다!,Je pakt een paar patronen!,Du tar noen patroner!,Podniosłeś trochę pocisków!,Você pegou alguns Carregadores!,,Ai ridicat niște Cartușe!,Заполучены картриджи!,,Fişekleri al! -You grab a case of Cartridges!,GOTCARTRIDGESCASE,,,,Sebral@[ao_cs] jsi krabici kazet!,Du tager en kasse med patroner!,Magazinkiste genommen.,,Vi prenis skatolon da kartoĉoj!,¡Has pillado una caja de cartuchos!,¡Has recogido una caja de cartuchos!,Kahmaiset laatikollisen kasetteja!,Vous prenez une bôite de cartouches!,Felkapsz egy doboz Töltényt!,Prendi un caso di cartucce!,カートリッジケース を奪った!,카트리지 박스를 주웠다!,Je pakt een kist patronen!,Du tar en kasse med patroner!,Podniosłeś skrzynkę pocisków!,Você pegou uma caixa de Carregadores!,,Ai ridicat o cutie de Cartușe!,Заполучен ящик картриджей!,,Bir kutu fişek al! -You grab a Valise stuffed with goods!,GOTVALISE,,,,Sebral@[ao_cs] jsi kufr plný munice!,Du tager en kuffert fyldt med varer!,Munitionstasche genommen.,,Vi prenis valizon plenan de municiojn!,¡Has pillado una maleta llena de equipamiento!,¡Has recogido una maleta llena de equipamiento!,Kahmaiset laukullisen täynnä tavaraa!,Vous récupérez une valise pleine d'équipement!,Felkapsz egy Poggyásznyi Muníciót!,Prendi una Valigia piena di merci!,代物を詰めたバリス を奪った!,탄약이 든 서류 가방을 주웠다!,Je pakt een Valise gevuld met goederen!,Du tar en koffert fylt med varer!,Podniosłeś Walizkę z wieloma dobrami!,Você pegou uma Mala cheia de equipamento!,,Ai ridicat o Valiză plină cu bunătăți!,Заполучена полная сумка боеприпасов!,,İçi mal dolu bir valiz al! -Force Field!,GOTFORCEFIELD,,,,Silové pole!,Kraftfelt!,Kraftfeld!,,Fortkampo!,¡Campo de fuerza!,,Voimakenttä!,Champ de force!,Erőtér!,Campo di forza!,フォースフィールド!,방어막!,Krachtveld!,Kraftfelt!,Pole Siłowe!,Campo de Força!,,Câmp de Forță!,Силовое поле!,,Güç Alanı! -007Microtel,GOTMICROTEL,,,,,,,,007 Microtel!,Microtel 007,,,007 Microtel,,,007マイクロテル,007마이크로텔 근력 향상 칩!,,,,,,Microtel 007,Микрочип 007,,007Microtel -You are EnK Blind!,GOTENKBLIND,,,,Jsi EnK-slep@[adj_cs]!,Du er EnK Blind!,Du bist EnK-blind!,,Vi estas ENK-Blinda,¡Tienes Ceguera EnK!,,Olet EnK-sokea!,Vous êtes aveugle à l'EnK!,EnK védett lettél!,Sei EnK-cieco!,EnKブラインドみてえだ!,EnK 투명 위장 장치!,Jij bent EnK Blind!,Du er EnK Blind!,Jesteś oślepiony przez EnK!,Você está vendado por EnK!,,Acum ești nedetectabil pentru Enk!,У тебя EnK-видимость!,,Sen EnK Blind'sın! -Vulcan rubber Boots!,GOTRUBBERBOOTS,,,,Gumové boty!,Vulkaniske gummistøvler!,Gummistiefel!,,Vulkanaj Kauŭĉukaj Botoj!,¡Botas de goma vulcanizada!,,Vulkanoidut kumisaappaat!,Bottes en caoutchouc vulcanisé!,Vulkanizált gumi talp!,Stivali di gomma vulcanica!,バルカンラバーブーツ!,벌컨 방화 부츠!,Vulcan rubber Laarzen!,Vulcan gummistøvler!,Gumowe Buty Vulcan!,Botas Vulcanizadas!,,Bocanci din cauciuc Vulcan!,Резиновые сапоги!,,Vulcan lastik botları! -SI Array mapping!,GOTSIARRAY,,,,Mapa pole SI!,SI Array kortlægning!,SI-Feld Karte!,,SI-matric-mapado!,¡Mapeado de Tabla SI!,,SI-kenttäkartta!,Carte du tableau SI!,SI pálya Felderítő!,Mappatura di array SI!,SIアーレイ マッピング!,Si 어레이 지도!,,SI Array kartlegging!,Mapa Pola SI!,Mapeamento por Campo de SI!,,Hartă SI compilată!,Составлена карта SI-массива!,,SI Dizi eşlemesi! -Infrared Visor!,GOTINFRARED,,,,Infračervené brýle!,Infrarødt visir!,Infrarotbrille!,,Transruĝa Viziero!,¡Visor infrarrojo!,,Infrapunavisiiri!,Viseur infrarouge!,Infravörös Sisak!,Visore a infrarossi!,赤外線バイザー!,적외선 바이져!,Infrarood vizier!,Infrarødt visir!,Wizjer na Podczerwień!,Visor Infravermelho!,,Vedere Infraroșie!,Инфракрасный визор!,,Kızılötesi Vizör! -"Breathe deep, Inhaler!",GOTINHALER,,,,"Pořádně se nadechni, inhalátor!","Træk vejret dybt, Inhalator!","Atme tief, Inhalierer!",,"Spiru profunde, inhalo!","¡Un inhalador, inspira fuerte!",,"Hengitä syvään, inhalaattori!","Respire, inhaleur!","Mély lélegzet, Inhaláló!","Respirare profondamente, inalatore!",深呼吸だ、インヘイラー!,각성제를 주웠다. 잘 들이마셔!,"Adem diep in, inhalator!","Pust dypt, Inhalator!",Weź głęboki wdech! Inhalator!,Inalador! Respira fundo!,,"Inspiră adânc, Inhalatorule!",Ингалятор! Вдыхай глубже!,,"Derin nefes al, Inhaler!" -A dose of Hydergine from a Hypo saves you!,GOTHYPONEED,,,,Jsi zachráněn@[ao_cs] dávkou Hyderginu z Hypa!,En dosis Hydergine fra en Hypo redder dig!,Eine Dosis Hydergine rettet dich!,,,¡Una dosis de Hydergina te salva la vida!,,Hyderginepiikkiannos pelastaa sinut!,Une bonne dose d'hydergine vous sauve la vie!,Egy adag Hydergine megmenti az irhád!,Una dose di Hydergine di un Hypo ti salva!,ハイポで ヒデルギン をキメた!,하이포의 하이데르진이 당신을 살렸다!,Een dosis Hydergine van een Hypo redt je!,En dose Hydergine fra en Hypo redder deg!,Dawka Hyderginy z Hypo ratuje cię!,Uma dose de hidergina do Hypo para te salvar!,,O doză de Hidrogine dintr-o seringă te salvează!,Доза Редергина из шприца спасла тебя!,,Hypo'dan bir doz Hydergine seni kurtarır! -You grab a Hypo!,GOTHYPO,,,,Sebral@[ao_cs] jsi Hypo!,Du tager en Hypo!,Hypo!,,Vi prenis Injektilon!,¡Has pillado una jeringa hipodérmica!,,Kahmaiset piikin!,Vous prenez une seringue!,Felkapsz egy Hypo-t!,Prendi un Hypo!,ハイポ を奪った!,하이포를 주웠다!,Je pakt een Hypo!,Du tar en Hypo!,Podniosłeś Hypo!,Você pegou um Hypo!,,Ai ridicat o Seringă!,Заполучен шприц!,,Bir Hypo kaptın! -You found a KeyCard!,GOTKEYCARD,,,,Nalezl@[ao_cs] jsi přístupovou kartu!,Du har fundet et Nøglekort!,Schlüsselkarte gefunden!,,Vi trovis Ŝlosilkarton!,¡Has encontrado una Tarjeta Llave!,,Löysit avainkortin!,Vous trouvez une clé magnétique!,Leltél egy Kulcskártyát!,Hai trovato una chiave magnetica!,キーカードを見つけた!,키 카드를 찾았다!,U heeft een sleutelkaart gevonden!,Du har funnet et nøkkelkort!,Znalazłeś Kartę Dostępu!,Você achou um Cartão de Passe!,,Ai găsit un Card-Cheie!,Найдена ключ-карта!,,Bir Anahtar Kart buldun! -You found a C-Key!,GOTCKEY,,,,Nalezl@[ao_cs] jsi kyberklíč!,Du har fundet en C-nøgle!,C-Schlüssel gefunden!,,Vi trovis C-Ŝlosilon!,¡Has encontrado una Llave-C!,,Löysit C-avaimen!,Vous trouvez une C-Clé!,Leltél egy C-Kulcsot!,Hai trovato una chiave C!,C-keyを見つけた!,C-키를 찾았다!,Je hebt een C-sleutel gevonden!,Du har funnet en C-nøkkel!,Znalazłeś Klucz C!,Você achou uma Chave-C!,,Ai găsit o Cheie-C!,Найден C-образный ключ!,,Bir C-Anahtarı buldun! -You found a Password!,GOTPASSWORD,,,,Nalezl@[ao_cs] jsi heslo!,Du har fundet et kodeord!,Passwort gefunden!,,Vi trovis Pasvorton!,¡Has encontrado una Contraseña!,,Löysit salasanan!,Vous trouvez un mot de passe!,Leltél egy Jelszót!,Hai trovato una parola d'ordine!,パスワードを見つけた!,암호를 찾았다!,U heeft een wachtwoord gevonden!,Du har funnet et passord!,Znalazłeś Hasło!,Você achou uma Senha!,,Ai găsit o Parolă!,Найден пароль!,,Bir Şifre buldun! -You found a blue Z-Key!,GOTBLUEZKEY,,,,Nalezl@[ao_cs] jsi modrý Z-klíč!,Du fandt en blå Z-nøgle!,Blauen Z-Schlüssel gefunden!,,Vi trovis bluan Z-ŝlosilon!,¡Has encontrado una Llave-Z azul!,,Löysit sinisen Z-avaimen!,Vous trouvez une Z-Clé bleue!,Leltél egy kék Z-Kulcsot!,Hai trovato una chiave Z blu!,ブルー Z-Key を見つけた!,청색 Z-키를 찾았다!,Je hebt een blauwe Z-sleutel gevonden!,Du har funnet en blå Z-nøkkel!,Znalazłeś niebieski Klucz Z!,Você achou uma Chave-Z azul!,,Ai găsit o Z-Cheie albastră!,Найден синий Z-образный ключ!,,Mavi bir Z-Anahtarı buldun! -You found a yellow Z-Key!,GOTYELWZKEY,,,,Nalezl@[ao_cs] jsi žlutý Z-klíč!,Du fandt en gul Z-nøgle!,Gelben Z-Schlüssel gefunden!,,Vi trovis flavan Z-ŝlosilon!,¡Has encontrado una Llave-Z amarilla!,,Löysit keltaisen Z-avaimen!,Vous trouvez une Z-Clé jaune!,Leltél egy sárga Z-Kulcsot!,Hai trovato una chiave Z gialla!,イエローZ-Key を見つけた!,황색 Z-키를 찾았다!,Je hebt een gele Z-sleutel gevonden!,Du har funnet en gul Z-nøkkel!,Znalazłeś żółty Klucz Z!,Você achou uma Chave-Z amarela!,,Ai găsit o Z-Cheie galbenă!,Найден жёлтый Z-образный ключ!,,Sarı bir Z-Anahtarı buldun! -You found a red Z-Key!,GOTREDZKEY,,,,Nalezl@[ao_cs] jsi červený Z-klíč!,Du fandt en rød Z-nøgle!,Roten Z-Schlüssel gefunden!,,Vi trovis ruĝan Z-ŝlosilon!,¡Has encontrado una Llave-Z roja!,,Löysit punaisen Z-avaimen!,Vous trouvez une Z-Clé rouge!,Leltél egy piros Z-Kulcsot!,Hai trovato una chiave Z rossa!,レッド Z-Key を見つけた!,적색 Z-키를 찾았다!,Je hebt een rode Z-sleutel gevonden!,Du har funnet en rød Z-nøkkel!,Znalazłeś czerwony Klucz Z!,Você achou uma Chave-Z vermelha!,,Ai găsit o Z-Cheie roșie!,Найден красный Z-образный ключ!,,Kırmızı bir Z-Anahtarı buldun! -Body Armor!,GOTBODYARMOR,,,,Brnění!,Kropsrustning!,Körperpanzerung!,,Kiraso!,¡Armadura!,,Suojavarustus!,Armure!,Testpáncél!,Giubbotti antiproiettile!,ボディーアーマー!,강화복!,Kogelvrije vesten!,Skuddsikker vest!,Pancerz!,Colete a Prova de Balas!,,Armură de Corp!,Бронежилет!,,Vücut Zırhı! -Centrophenoxine,GOTCENTROPHENOXINE,,,,Centrofenoxin,Centrophenoxine,,,Centrofenoksino!,¡Centrofenoxina!,,Sentrofenoksiinia,Centrophenoxine!,,,セントロフェノキシン!,메클로페녹세이트!,,Centrophenoxine,Centrofenoxina,Centrofenoxina,,Centrofenoxine,Центрофеноксин,,Centrophenoxine -You grab a Kevlar vest!,GOTKEVLARVEST,,,,Sebral@[ao_cs] jsi kevlarovou vestu!,Du får fat i en kevlarvest!,Kevlarweste!,,Vi prenis kevlaran veŝton!,¡Has pillado un traje de Kevlar!,¡Has recogido un traje de Kevlar!,Kahmaiset Kevlar-liivit!,Veste en Kevlar!,Felkapsz egy Golyóálló Mellényt!,Prendi una maglia di kevlar!,ケブラーベスト を奪った!,방탄복을 주웠다!,Pak een Kevlar vest!,Du tar en Kevlar-vest!,Podniosłeś kamizelkę kuloodporną!,Você pegou um Colete de Kevlar!,,Ai ridicat o vestă din Kevlar!,Заполучен кевларовый жилет!,,Kevlar yeleği al! -You grab Super Kevlar vest!,GOTSKEVLARVEST,,,,Sebral@[ao_cs] jsi superkevlarovou vestu!,Du tager Super Kevlar vest!,Super-Kevlarweste!,,Vi prenis superan kevlaran veŝton!,¡Has pillado un supertraje de Kevlar!,¡Has recogido un supertraje de Kevlar!,Kahmaiset Superkevlar-liivit!,Super Veste en Kevlar!,Felkapsz egy Szuper Golyóálló Mellényt!,Prendi una maglia super kevlar!,スーパーケブラーベスト を奪った!,중 방탄복을 주웠다!,Je pakt een Super Kevlar vest!,Du tar en Super Kevlar vest!,Podniosłeś superkamizelkę kuloodporną!,Você pegou um Super Colete de Kevlar!,,Ai ridicat o Super Vestă din Kevlar!,Заполучен усиленный кевларовый жилет!,,Süper Kevlar yeleği al! -You grab a MicroKit!,GOTMICROKIT,,,,Sebral@[ao_cs] jsi mikrosadu!,Du får fat i et MicroKit!,MicroKit genommen!,,Vi prenis Kompleteton!,¡Has pillado un MicroKit!,¡Has recogido un MicroKit!,Kahmaiset Microkitin!,Microkit!,Felkapsz egy Mikorkit-et!,Prendi un MicroKit!,マイクロキット を奪った!,마이크로킷을 주웠다!,Je pakt een MicroKit!,Du tar en MicroKit!,Podniosłeś MikroZestaw!,Você pegou um MicroKit!,,Ai ridicat un MicroKit!,Заполучена мини-аптечка!,,Bir MicroKit al! -You grab a Dampener!,GOTDAMPENER,,,,Sebral@[ao_cs] jsi tlumič!,Du får fat i en Dampener!,Dämpfer genommen!,,Vi prenis Dampilon!,¡Has pillado un Amortiguador!,¡Has recogido un Amortiguador!,Kahmaiset vaimentimen!,Amortisseur!,Felkapsz egy Tompítót!,Prendi un antivento!,ダンプナー を奪った!,완충 장치를 주웠다!,Je pakt een Demper!,Du tar en Dampener!,Podniosłeś Tłumik!,Você pegou um Amortecedor!,,Ai ridicat un Amortizor!,Заполучен глушитель!,,Bir Sönümleyici al! -You need a C-Key to access this item!,PD_CKEY,,,,K přístupu potřebuješ kyberklíč!,Du skal bruge en C-nøgle for at få adgang til dette objekt!,Du brauchst einen C-Schlüssel um das hier zu bedienen.,,Vi bezonas C-ŝlosilon por aliri ĉi tiun objekton!,¡Necesitas una Llave-C para acceder a este objeto!,,Tarvitset C-avaimen saadaksesi pääsyn tähän kohteeseen!,Il vous faut une C-Clé pour accéder à cet objet!,Egy C-Kulcs szükséges a hozzáféréshez!,Hai bisogno di una chiave C per accedere a questo oggetto!,アクセスには C-key が必要だ!,C-키가 있어야 작동이 가능하다!,Je hebt een C-sleutel nodig om toegang te krijgen tot dit item!,Du trenger en C-nøkkel for å få tilgang til dette elementet!,Potrzebujesz Klucza C by uruchomić ten przedmiot.,Você precisa de uma Chave-C para acessar!,,Ai nevoie de o Cheie-C pentru a accesa acest obiect!,"Нет доступа, нужен C-образный ключ!",,Bu eşyaya erişmek için bir C-Anahtarına ihtiyacın var! -You need a KeyCard to access this item!,PD_KEYCARD,,,,K přístupu potřebuješ přístupovou kartu!,Du skal bruge et Nøglekort for at få adgang til dette objekt!,Du brauchst eine Schlüsselkarte um das hier zu bedienen.,,Vi bezonas Slosilkarton por aliri ĉi tiun objekton!,¡Necesitas una Tarjeta Llave para acceder a este objeto!,,Tarvitset avainkortin saadaksesi pääsyn tähän kohteeseen!,Il vous faut une carte magnétique pour accéder à cet objet!,Egy kulcskártya szükséges a hozzáféréshez!,Hai bisogno di una chiave magnetica per accedere a questo oggetto!,アクセスには キーカード が必要だ!,키 카드가 있어야 작동이 가능하다!,U heeft een sleutelkaart nodig om toegang te krijgen tot dit item!,Du trenger et nøkkelkort for å få tilgang til dette elementet!,Potrzebujesz Karty Dostępu by uruchomić ten przedmiot!,Você precisa de uma Chave de Passe para acessar!,,Ai nevoie de un Card-Cheie pentru a accesa acest obiect!,"Нет доступа, нужен ключ-карта!",,Bu öğeye erişmek için bir KeyCard'a ihtiyacınız var! -You need a Password to access this item!,PD_PASSWORD,,,,K přístupu potřebuješ heslo!,Du skal bruge et kodeord for at få adgang til dette objekt!,Du brauchst eine Passwort um das hier zu bedienen.,,Vi bezonas Pasvorton por aliri ĉi tiun objekton!,¡Necesitas una Contraseña para acceder a este objeto!,,Tarvitset salasanan saadaksesi pääsyn tähän kohteeseen!,Il vous faut un mot de passe pour accéder à cet objet!,Egy Jelszó szükséges a hozzáféréshez!,Hai bisogno di una parola d'ordine per accedere a questo oggetto!,アクセスには パスワード が必要だ!,암호를 입력해야 작동이 가능하다!,Je hebt een wachtwoord nodig om toegang te krijgen tot dit item!,Du trenger et passord for å få tilgang til dette elementet!,Potrzebujesz Hasła by uruchomić ten przedmiot!,Você precisa de uma Senha para acessar!,,Ai nevoie de Parolă pentru a accesa acest obiect!,"Нет доступа, нужен пароль!",,Bu öğeye erişmek için bir Şifreye ihtiyacınız var! -You need a Blue Z-Key to make this work,PD_BLUEZKEY,,,,Tohle bude fungovat jen s modrým Z-klíčem.,Du skal bruge en blå Z-nøgle for at få dette til at fungere!,Du brauchst einen blauen Z-Schlüssel um das hier zu bedienen.,,Vi bezonas Bluan Z-ŝlosilon por funkciigi ĉi tiun!,¡Necesitas una Llave-Z azul para hacer funcionar esto!,,Tarvitset sinisen Z-avaimen saadaksesi tämän toimimaan!,Il vous faut une Z-Clé bleue pour faire fonctionner cela.,Egy Kék Z-Kulcs szükséges a hozzáféréshez!,Hai bisogno di una chiave Z blu per accedere a questo oggetto!,アクセスには ブルーZ-key が必要だ!,청색 Z-키가 있어야 작동이 가능하다!,Je hebt een blauwe Z-sleutel nodig om dit te laten werken.,Du trenger en blå Z-nøkkel for å få dette til å fungere!,Potrzebujesz Niebieskiego Klucza Z by zadziałało!,Você precisa de uma Chave-Z azul para fazer isto funcionar!,,Ai nevoie de o Cheie-Z albastră pentru a face asta să funcționeze!,"Не работает, нужен синий Z-образный ключ!",,Bunu çalıştırmak için bir Mavi Z-Anahtarına ihtiyacınız var -You need a Red Z-Key to make this work!,PD_REDZKEY,,,,Tohle bude fungovat jen s červeným Z-klíčem.,Du skal bruge en rød Z-nøgle for at få dette til at fungere!,Du brauchst einen roten Z-Schlüssel um das hier zu bedienen.,,Vi bezonas Ruĝan Z-ŝlosilon por funkciigi ĉi tiun!,¡Necesitas una Llave-Z roja para hacer funcionar esto!,,Tarvitset punaisen Z-avaimen saadaksesi tämän toimimaan!,Il vous faut une Z-Clé rouge pour faire fonctionner cela.,Egy Piros Z-Kulcs szükséges a hozzáféréshez!,Hai bisogno di una chiave Z gialla per accedere a questo oggetto!,アクセスには レッドZ-key が必要だ!,적색 Z-키가 있어야 작동이 가능하다!,Je hebt een rode Z-sleutel nodig om dit te laten werken!,Du trenger en rød Z-nøkkel for å få dette til å fungere!,Potrzebujesz Czerwonego Klucza Z by zadziałało!,Você precisa de uma Chave-Z vermelha para fazer isto funcionar!,,Ai nevoie de o Cheie-Z roșie pentru a face asta să funcționeze!,"Не работает, нужен красный Z-образный ключ!",,Bunu çalıştırmak için Kırmızı Z-Anahtarına ihtiyacınız var! -You need a Yellow Z-Key to make this work!,PD_YELWZKEY,,,,Tohle bude fungovat jen se žlutým Z-klíčem.,Du skal bruge en gul Z-nøgle for at få dette til at fungere!,Du brauchst einen gelben Z-Schlüssel um das hier zu bedienen.,,Vi bezonas Flavan Z-ŝlosilon por funkciigi ĉi tiun!,¡Necesitas una Llave-Z amarilla para hacer funcionar esto!,,Tarvitset keltaisen Z-avaimen saadaksesi tämän toimimaan!,Il vous faut une Z-Clé jaune pour faire fonctionner cela.,Egy Sárga Z-Kulcs szükséges a hozzáféréshez!,Hai bisogno di una chiave Z rossa per accedere a questo oggetto!,アクセスには イエローZ-key が必要だ!,황색 Z-키가 있어야 작동이 가능하다!,Je hebt een gele Z-sleutel nodig om dit te laten werken!,Du trenger en gul Z-nøkkel for å få dette til å fungere!,Potrzebujesz Żółtego Klucza Z by zadziałało!,Você precisa de uma Chave-Z amarela para fazer isto funcionar!,,Ai nevoie de o Cheie-Z galbenă pentru a face asta să funcționeze!,"Не работает, нужен жёлтый Z-образный ключ!",,Bunu yapmak için Sarı Z-Anahtarına ihtiyacın var! +la bluan pilolon.",Deberías haber tomado la pastilla azul.,,Olis pitäny ottaa sininen pilleri.,T'aurais du prendre la pilule bleue.,Inkább a kék pirulát kellett volna választanod.,Avresti dovuto prendere la pillola blu ...,青いピルを採るべきではなかったな。,넌 파란 알약을 골랐어야 했어.,Je had de blauwe pil moeten nemen.,Skulle tatt den blå pillen.,Trzeba było wziąć niebieską pigułkę.,Devia ter tomado a pílula azul.,,Trebuia să iei pastila albastră.,Надо было принять синюю таблетку.,,Du borde ha tagit det blå pillret.,Mavi hapı almalıydın. +The name of the game ain't Twitch n' Run!,QUITMSG11,,,,V názvu hry není napsané „uteč“!,"Spillets navn er ikke ""at flygte""!","Das Spiel heißt nicht ""wegrennen""!",,La nomo de la ludo ne estas Tiku kaj Kuru!,¡El nombre del juego no es Tirar a Correr!,,Pelin nimi ei oo Paniikkipako!,"Le jeu s'appelle pas ""Panique et cours!""",A játék neve nem Twitch n' Megfutamodás.,"Il gioco non significa ""scappare""!",ゲーム名は 萎え落ち小僧 じゃねえぞ!,"이봐, 이 게임은 때리고 도망가는 게임이 아니라고!",De naam van het spel is niet Twitch n' Run!,Navnet på spillet er ikke Twitch n' Run!,"Nazwą gry nie jest ""Drżyj i Uciekaj""!",O nome do jogo não é Trema nas Bases e Fuja!,,Numele jocului nu e Tremură și Ascunde-te!,Эта игра называется не «Дрожи и прячься»!,,"Spelet heter inte ""Twitch n' Run""!",Oyunun adı Twitch n' Run değil! +"No worries. Saving the world can wait, right?",QUITMSG12,,,,"Žádný problém. Záchrana světa může počkat, ne?","Det er ikke noget problem. At redde verden kan vente, ikke?","Also, die Welt zu retten kann warten, richtig?",,"Ne zorgu. Savi la mondon povas atendi, ĉu ne?","No te preocupes. Salvar el mundo puede esperar, ¿verdad?",,"Ei huolta; maailman pelastaminen voi odottaa, eikö niin?","Oh, pas de problème. Le monde peut attendre\nd'être sauvé, non?","Semmi pánik. A világmegmentés várhat, nemde?","Salvare il mondo può\naspettare, giusto?",気にはしない、世界を救うのは何時でも出来る、だろ?,걱정 말라고. 세상이 위험한데 급할 것 있나. 안 그래?,"Het redden van de wereld kan wachten, toch?","Slapp av. Å redde verden kan vente, ikke sant?","Bez obaw. Ratowanie świata może poczekać, prawda?","Sem problemas. O mundo pode esperar, não é mesmo?",,"Nicio problemă. Salvarea lumii poate aștepta, nu?","Не парься. Спасение мира подождёт, ведь так?",,"Det är ingen fara. Att rädda världen kan vänta, eller hur?","Endişelenme. Dünyayı kurtarmak bekleyebilir, değil mi?" +Guess it's time to make like the 'net and split!,QUITMSG13,,,,"Hádám, že je čas vypojit server!",Så er det vist på tide at gøre som nettet og smutte!,"Also ist es soweit, dass sich unsere Wege trennen.",,"Tempas, ke niaj vojoj agu kiel la reto kaj dividu.",¡Supongo que es hora de cortar con esta mala conexión!,,Kai sitten on aika katkaista palvelinyhteydet!,Ca doit être temps de partir comme une mauvaise connection!,Kettéváglak mint a netsplit a kapcsolatot.,Quindi è il momento per i\nnostri modi di separarsi.,ネット切断している暇は無いだろ!,벌써 서버를 다운시키는 '척' 할 시간인가?,Denk dat het tijd is om het te maken als het 'net en splitsen!,Det er vel på tide å gjøre som nettet og stikke!,"Wygląda na to, że trzeba się rozłączyć jak netsplit!","Acho que tá na hora de cair, que nem uma conexão ruim.",,Cred că e timpul de separare!,"Кажется, настало время устроить netsplit!",,Det är nog dags att göra som nätet och dra sig ur!,Sanırım 'net gibi yapıp ayrılmanın zamanı geldi! +"Don't go off and forget about HacX, now!",QUITMSG14,,,,Ať tě nenapadne odejít a zapomenout na HacX!,Glem nu ikke HacX!,Bitte vergesse HacX nicht!,,Ne iru forgesi HacX nun!,¡Ahora no vayas y te olvides de Hacx!,,Älä nyt mene pois ja unohda HacX:ä!,Va pas oublier HacX maintenant!,"Ha elkalandozol, ne feletkezz meg a HacX-ről!","Non andartene e dimenticarti di HacX, ora!",HacXを忘れんじゃねえぞ、な!,부디 나가지 말고 HacX를 잊지 말아줘!,"Ga niet af en vergeet HacX niet, nu!","Ikke gå og glem HacX, nå!","Nie wyłączaj i nie zapominaj o HacX, teraz!","Não vai se esquecer do HacX, hein!",,Nu pleca și uita de HacX!,"Только посмей уйти и забыть про HacX, ты!",,Gå inte iväg och glömma HacX nu!,"HacX'i unutup gitme, şimdi!" +%o deleted %hself from the universe.,OB_SUICIDE,,,,%o se smazal@[ao_cs] z vesmíru.,%o slettede sig selv fra universet.,%o entfernte sich aus dem Universum.,,%o forigis sin el la universo.,%o se borró a si mism@[ao_esp] del universo.,,%o poisti itsensä maailmankaikkeudesta.,%o s'est effacé@[e_fr] de l'univers.,%o kitörölte magát az univerzumból,%o si è cancellato dall'universo.,%o はこの宇宙から消滅した。,%o 은(는) 자기 자신의 존재를 소멸시켰다.,%o verwijderd zichzelf uit het universum.,%o slettet seg selv fra universet.,%o usun@[irreg_2_pl] się ze świata.,%o se deletou deste universo.,,%o s-a sters pe sine din univers.,Игрок %o стёр себя с лица вселенной.,,%o raderade sig själv från universum.,%o kendini evrenden sildi. +%o formed a crater the size of Kansas.,OB_FALLING,,,,%o utvořil@[ao_cs] kráter velikosti Kansasu.,%o dannede et krater på størrelse med Kansas.,%o wurde zu einem Krater in der Größe von Kansas.,,%o formis krateron grandan kiel Kansaso.,%o formó un cráter del tamaño de Kansas.,,%o muodosti Kansasin kokoisen kraaterin.,%o a formé un cratère de la taille du Kansas.,%o egy Kansas méretű krátert hagyott maga után.,%o ha formato un cratere delle dimensioni del Kansas.,%o はカンザス州程のクレーターを生成した。,%o 은(는) 땅바닥에 캔자스만큼 커다란 구멍을 뚫었다.,%o vormde een krater ter grootte van Kansas.,%o dannet et krater på størrelse med Kansas.,%o utworzył@[ao_pl] krater wielkości Kansas.,%o abriu uma cratera do tamanho do Kansas.,,%o a format un crater de dimensiunile statului Kansas.,На месте падения игрока %o образовался кратер размером с Канзас.,,%o bildade en krater lika stor som Kansas.,%o Kansas büyüklüğünde bir krater oluşturdu. +%o became a human pancake.,OB_CRUSH,,,,%o se změnil@[ao_cs] v lidskou palačinku.,%o blev en menneskelig pandekage.,%o wurde zu einem menschlichen Pfannkuchen.,,%o Iĝis homa patkuko.,%o se convirtió en un crepe humano.,,%o tuli ihmispannukakun muotoiseksi.,%o est devenu@[e_fr] une crêpe.,%o palacsintává lapult,%o è diventato un pancake umano.,%o は人肉パンケーキになった。,%o 은(는) 인간 빈대떡이 되었다.,%o werd een menselijke pannenkoek.,%o ble en menneskelig pannekake.,%o stał@[ao_pl] się ludzkim plackiem.,%o virou uma panqueca humana.,,%o a devenit o clătită umană.,Игрока %o сплющило в лепешку.,,%o blev en mänsklig pannkaka.,%o insan bir krep oldu. +%o tried to jack out.,OB_EXIT,,,,%o se pokusil@[ao_cs] prchnout.,%o forsøgte at stikke af.,%o hat sich ausgeloggt.,,%o provis malkonektiĝi.,%o intentó desconectarse.,,%o yritti irrottaa piuhan.,%o a tenté de se déconnecter.,%o ki akarta húzni a kábelét,%o è uscito.,%o は逃げ出そうとした。,%o 은(는) 로그아웃하려고 시도했다.,%o probeerde zich terug te trekken.,%o prøvde å jekke seg ut.,%o chciał@[ao_pl] się wydostać.,%o tentou se desconectar.,,%o a încercat să o taie.,Игрок %o хотел улизнуть.,,%o försökte ta sig ut.,%o kaçmaya çalıştı. +%o swam like a brick.,OB_WATER,,,,%o uměl@[ao_cs] plavat jako cihla.,%o svømmede som en mursten.,%o schwamm wie ein Stein.,,%o naĝis kiel briko.,%o nadó como un ladrillo.,,%o ui kuin tiiliskivi.,%o nage comme une brique.,%o úgy úszik mint egy tégla.,%o nuotava come una pietra.,%o はカナヅチだった。,%o 은(는) 웹서핑을 못 하는 타입이었다.,%o zwom als een baksteen.,%o svømte som en murstein.,%o popłyn@[irreg_2_pl] jak cegła.,%o foi nadar como um tijolo.,,%o a înotat ca o cărămidă.,Игрок %o поплыл как топор.,,%o simmade som en tegelsten.,%o bir tuğla gibi yüzdü. +%o went nuclear.,OB_SLIME,,,,%o se rozpadl@[ao_cs] na atom.,%o blev nuklear.,%o wurde verstrahlt.,,%o iĝis nuklea,%o se volvió radioactiv@[ao_esp].,,%o kiinnostui ydinasioista.,%o s'est fait fissionner.,%o felrobbant mérgében.,%o è stato irradiato.,%o はニュークリアーと化した。,%o 은(는) 방사능 바람을 좀 쐬고 왔다.,%o werd nucleair.,%o ble nuklear.,%o został@[ao_pl] napromieniowan@[adj_pl].,%o ficou radioativ@[ao_ptb].,,%o a devenit radioactiv.,Игрок %o светится в темноте.,,%o blev kärnvapenfri.,%o nükleer oldu. +%o took a hot bath.,OB_LAVA,,,,%o si dal@[ao_cs] horkou koupel.,%o tog et varmt bad.,%o nahm ein heißes Bad.,,%o spertis varman banon.,%o tomó un baño caliente.,,%o otti kuuman kylvyn.,% prend un bain chaud.,%o vett egy forró fürdőt.,%o ha fatto un bagno caldo.,%o は熱湯風呂に浸かった。,%o 은(는) 시원하게 용암 일광욕을 즐겼다.,%o nam een warm bad.,%o tok et varmt bad.,%o wzi@[irreg_2_pl] gorącą kąpiel.,%o tomou um banho bem quente.,,%o a făcut o baie fierbinte.,Игрок %o принял горячую ванну.,,%o tog ett varmt bad.,%o sıcak bir banyo yaptı. +%o overdosed on nitro glycerine.,OB_BARREL,,,,%o se předávkoval@[ao_cs] nitroglycerinem.,%o fik en overdosis nitroglycerin.,%o nahm eine Überdosis Nitroglyzerin.,,%o trodozis nitroglicerinon.,%o tuvo una sobredosis de nitroglicerina.,,%o sai yliannostuksen nitroglyseriiniä.,%o a fait une overdose de nitroglycérine.,%o túladagolta a nitro-glicerint.,%o ha assunto un sovradosaggio di nitroglicerina.,%o はニトロを過剰摂取した。,%o 은(는) 니트로글리세린을 훅 가게 흡입했다.,%o overdosering op nitroglycerine.,%o tok en overdose nitroglyserin.,%o przedawkował@[ao_pl] nitroglicerynę.,%o overdosou em nitroglicerina.,,%o a luat o supradoză de nitroglicerină.,Игрок %o перебрал нитроглицерина.,,%o tog en överdos av nitroglycerin.,%o aşırı dozda nitro gliserin aldı. +%o is flayed into tiny little pieces.,OB_SPLASH,,,,%o byl@[ao_cs] sedřen@[ao_cs] na kousíčky.,%o er flået i småstykker.,%o wurde zerkleinert.,,%o estas senhaŭtiga en malgrandetaj pecoj.,%o es despellejad@[ao_esp] en trocitos pequeños.,,%o silpoutui riekaleiksi.,%o s'est fait éparpiller en petits morceaux.,%o ripityára szakadt szét.,%o è stato schiacciato.,%o は細かい粒をぶち撒けられた。,%o 은(는) 작은 입자로 분해되었다.,%o wordt gevild in kleine stukjes.,%o er flådd i bittesmå biter.,%o został@[ao_pl] roztrzaskan@[adj_pl] na małe kawałeczki.,%o foi detonad@[ao_ptb] em vários pedacinhos.,,%o s-a spart în mii de bucățele.,Игрока %o разодрали на мелкие клочки.,,%o är flådd i pyttesmå bitar.,%o küçük parçalara ayrıldı. +%o wanted to see what %g looked like inside-out.,OB_R_SPLASH,,,,"%o chtěl@[ao_cs] vědět, jak vypadá zevnitř.","%o ville se, hvordan han så ud indefra.",%o wollte @[pp_de] Innereien sehen.,,"%o volis vidi, kiel %g aspektus kun la interno ekstere.",%o quería ver que pinta tenía por dentro.,,%o halusi nähdä itsensä nurinperin.,%o voulait voir comment ses organes fonctionnent.,%o meg akarta tudni %g hogy néz ki belülről.,%o voleva vedere le sue interiora.,%o は %g が裏返しになるのを望んだ。,%o 은(는) 인체의 신비를 감상했다.,%o wilde zien hoe %g er binnenstebuiten uitzag.,%o ville se hvordan han så ut på innsiden.,%o chciał@[ao_pl] zobaczyć jak %g wygląda od środka.,%o queria ver como são os orgãos internos de %g.,,%o a vrut să vadă cum arăta %g întors pe dos.,"Игрок %o хотел посмотреть, что у него внутри.",,%o ville se hur @[pro_sv] såg ut på insidan.,"%o, içinin dışının nasıl göründüğünü görmek istedi." +%o wanted to see what %g looked like inside-out.,OB_ROCKET,,,,"%o chtěl@[ao_cs] vědět, jak vypadá zevnitř.","%o ville se, hvordan han så ud indvfra.",%o wollte @[pp_de] Innereien sehen.,,"%o volis vidi, kiel %g aspektus kun la interno ekstere.",%o quería ver que pinta tenía por dentro.,,%o halusi nähdä itsensä nurinperin.,%o voulait voir comment ses organes fonctionnent.,%o meg akarta tudni %g hogy néz ki belülről.,%o voleva vedere le sue interiora.,%o は %g が裏返しになるのを望んだ。,%o 은(는) 퀀텀 여행을 즐겼다.,%o wilde zien hoe %g er binnenstebuiten uitzag.,%o ville se hvordan han så ut utenpå.,%o chciał@[ao_pl] zobaczyć jak %g wygląda od środka.,%o queria ver como são os orgãos internos de %g.,,%o a vrut să vadă cum arăta %g întors pe dos.,"Игрок %o хотел посмотреть, что у него внутри.",,%o ville se hur @[pro_sv] såg ut på insidan.,%o içten dışa nasıl göründüğünü görmek istedi. +%o deleted %hself from the universe.,OB_KILLEDSELF,,,,%o se smazal@[ao_cs] z vesmíru.,%o slettede sig selv fra universet.,%o entfernte sich aus dem Universum.,,%o forigis sin el la universo.,%o se borró a si mism@[ao_esp] del universo.,,%o poisti itsensä maailmankaikkeudesta.,%o s'est effacé@[e_fr] de l'univers.,%o kitörölte magát az univerzumból,%o si è cancellato dall'universo.,%o はこの宇宙から消滅した。,%o 은(는) 자기 자신을 해킹했다.,%o schrapte zichzelf uit het universum.,%o slettet seg selv fra universet.,%o usun@[irreg_2_pl] się ze świata.,%o se deletou deste universo.,,%o s-a șters pe sine din univers.,Игрок %o стёр себя с лица вселенной.,,%o raderade sig själv från universum.,%o kendini evrenden sildi. +%o is no longer the dominant species.,OB_THUG,,,,%o už není vládnoucím živočichem.,%o er ikke længere den dominerende art.,%o ist nicht länger die dominante Spezies.,,%o ne estas la supera specio plu.,%o ya no es la especie dominante.,,%o ei ole enää vallitsevaa lajia.,%o n'est plus l'espèce dominante.,Már nem %o a csúcsragadozó.,%o non è più la specie dominante.,%o はもはや優性種ではなくなった。,%o 은(는) 그들의 시다바리가 아니였다.,%o is niet langer de dominante soort.,%o er ikke lenger den dominerende arten.,%o nie jest już dominującym gatunkiem.,%o não é mais a espécie dominante.,,%o nu mai e specia dominantă.,Игрок %o больше не доминантная форма жизни.,,%o är inte längre den dominerande arten.,%o artık baskın tür değil. +%o plugged in to the wrong machine.,OB_ANDROID,,,,%o se zapojil@[ao_cs] ke špatnému stroji.,%o har tilsluttet sig den forkerte maskine.,%o verband sich mit der falschen Maschine.,,%o konektiĝis en la eraran maŝinon.,%o se enchufó en la máquina equivocada.,,%o kytkeytyi väärään koneeseen.,%o s'est branché@[e_fr] à la mauvaise machine.,%o a rossz gépet dugta be.,%o connesso alla macchina sbagliata.,%o は違うマシンに接続してしまった。,%o 은(는) 잘못된 기계를 작동시켰다.,%o aangesloten op de verkeerde machine.,%o koblet seg til feil maskin.,%o podłączył@[ao_pl] się do złej maszyny.,%o se conectou na máquina errada.,,%o s-a conectat la mașina greșită.,Игрока %o подключили не к тому заряднику.,,%o anslöt sig till fel maskin.,%o yanlış makineye bağlandı. +%o got %hself a monster of a cyber-jockey-derriere-kicking.,OB_MONSTRUCT,,,,%o dostal@[ao_cs] šíleně kybernakopáno.,%o fik sig et monster af et cyber-jockey-derriere-spark.,%o bekam einen monströsen Cyber-Arschtritt verpasst.,,%o ricevis monstran cybernetik-raydist-postaĵ-piedbaton.,%o se ganó la madre de todas las patadas en el culo.,,%o sai hirviömäisen kyberlöylytyksen.,%o s'est fait@[e_fr] botter le cul de manière monumentale.,%o segge meg lett rugdosva.,% o ho avuto un mostruoso calcio cibernetico mancato.,%o は己に サイバー-ジョッキー-デリエレ-キッキング を取り入れた。,%o 은(는) 저 괴물의 슈퍼-울트라-캡쑝-파워를 맛봤다.,%o kreeg een monsterlijke cybertrap in @[zijn_haar_nl] kont.,%o fikk seg et monster av en cyber-jockey-derriere-sparking.,%o dostał@[ao_pl] cyber-kopa w dupę.,%o levou um cibercoice monstruoso nas fuças.,,%o s-a făcut praf în stil cibernetic.,Игрок %o получил поджопника от кибердиджея.,,%o fick sig ett monster av en cyber-jockey-derriärspark.,%o kendine canavar gibi bir dayak attı. +%o got ICEd.,OB_ICE,,,,%o byl@[ao_cs] zmražen@[ao_cs] ICEm.,%o blev ICEd.,%o wurde verEISt.,,%o iĝis ICE-ita,%o fue ICEad@[ao_esp].,,%o raukkaa nyt varmaankin kICEmittää.,%o s'est fait@[e_fr] ICEr.,%o-t jégre tették.,% o è stato ghiacciato.,%o は冷えた。,%o 은(는) 지독하게 물어뜯겼다.,%o was IJS'd.,%o ble ICEd.,%o został@[ao_pl] zamrożon@[adj_pl].,%o foi peg@[ao_ptb] por um ICE. AI SE ferrou!,,%o a ÎNGHEȚat.,Игрок %o вляпался в ЛЁД.,,%o blev ICEd.,%o buzlandı. +%o feels a little buzzed.,OB_BUZZER,,,,%o dostal@[ao_cs] malou pecku.,%o føler sig lidt svimmel.,%o fühlt sich etwas gekitzelt.,,%o sentas sin iomete vibretita.,%o se siente algo zumbad@[ao_esp].,,%o raukan päässä hieman surisee.,%o sent le buzz.,%o-nak még mindig zúg a füle.,%o si sente solleticato un po '.,%o は少し賑やかになった。,%o 은(는) 짜릿하게 찔렸다.,%o voelt een beetje gezoemd.,%o føler seg litt beruset.,%o poczuł@[ao_pl] brzęczenie.,%o se sente meio chocad@[ao_ptb].,,%o se simte puțin șocat.,Игрок %o лёг спать в компании вертолётиков.,,%o känner sig lite uppslukad.,%o biraz kafayı bulmuş gibi hissediyor. +%o uncovers a rather shocking development.,OB_STEALTH,,,,%o odhalil@[ao_cs] šokující informace.,%o opdager en temmelig chokerende udvikling.,%o machte eine schockierende Entdeckung.,,%o malkovras tre ŝokantan aferon.,%o descubre algo bastante chocante.,,%o raukalle paljastuu sangen sähköistävä uutinen.,%o a fait une découverte choquante.,"%o rájön, hogy az áram nem játék.",%o ha fatto una scoperta scioccante.,%o はかなり衝撃的な開発を発見した。,%o 은(는) 비밀리에 만들어진 병기를 발견했다.,%o ontdekt een nogal schokkende ontwikkeling.,%o avdekker en ganske sjokkerende utvikling.,%o odkrywa coś szokującego.,%o descobre uma revelação chocante.,,%o dezvăluie o schimbare șocantă.,Игрока %o встретил довольно серьёзный поворот событий.,,%o upptäcker en ganska chockerande utveckling.,%o oldukça şok edici bir gelişmeyi ortaya çıkardı. +%o was erased from cyberspace.,OB_DMAN,,,,%o byl@[ao_cs] vymazán@[ao_cs] z kyberprostoru.,%o blev slettet fra cyberspace.,%o wurde aus dem Cyberspace gelöscht.,,%o estas viŝita el cyberspaco.,%o fue borrad@[ao_esp] del ciberespacio.,,%o poistettiin kyberavaruudesta.,%o s'est fait@[e_fr] effacer du cyberespace.,%o-t kitörölték a kibertérből.,%o è stato eliminato dal cyberspazio.,%o はサイバースペースに消去された。,%o 은(는) 영구차단을 당했다.,%o werd gewist uit cyberspace.,%o ble slettet fra cyberspace.,%o został@[ao_pl] usunięt@[adj_pl] z cyber przestrzeni.,%o foi deletad@[ao_ptb] do ciberespaço.,,%o a fost șters din spațiul cibernetic.,Игрока %o удалили из киберпространства.,,%o raderades från cyberrymden.,%o siber uzaydan silindi. +%o gave %hself a glass jaw.,OB_GLASS,,,,%o si přidělal@[ao_cs] skleněnou čelist.,%o gav sig selv en glaskæbe.,%o bekam ein Glaskinn.,,%o donis al si vitran makzelon.,%o se estampó contra un cristal.,,%o antoi itsellensä lasileuan.,%o s'est fait@[e_fr] vitrifier la figure.,%o állon vágta magát.,%o ha un mento di vetro.,%o は自身にグラスジョーを取り付けた。,%o 은(는) 유리창을 깨고 등장하는 액션 배우가 아니였다.,%o gaf zichzelf een glazen kaak.,%o ga seg selv en glasskjeve.,%o był@[ao_pl] zbyt delikatn@[adj_pl] ze szkłem.,%o tem um queixo de vidro.,,%o și-a făcut un maxilar de sticlă.,У игрока %o оказалась стеклянная челюсть.,,%o gav sig själv en glaskäke.,%o kendine cam çene taktı. +%o's life membership was terminated.,OB_MANIAC,,,,%o@[psn_cs] členství v klubu živých bylo přerušeno.,%os medlemskab på livstid blev opsagt.,%os Mitgliedschaft im Leben wurde beendet.,,La vivo-membrecon de %o estas finigita,%o tuvo su afiliación a la vida terminada.,,%o raukan elämänjäsenyys päätettiin.,L'abonnement à vie de %o est arrivé à sa fin.,%o elfelejtette befizetni az élők tagdíját.,L'appartenenza di %o alla vita è finita.,%o のメンバーシップ生活は終幕した。,%o 의 계정은 영원히 삭제되었다.,%o's levenslange lidmaatschap werd beëindigd.,%os livstidsmedlemskap ble avsluttet.,Członkowstwo %o w klubie żywych się skończyło.,%o não está mais afiliad@[ao_ptb] à vida.,,%o nu mai e membru al clubului celor vii.,Игрока %o исключили из клуба живых.,,%os medlemskap på livstid avslutades.,%o hayata veda etti. +%o died in some random method I cannot fathom.,OB_MANIACHIT,,,,"%o umřel@[ao_cs] nějakým způsobem, který ani nemůžu pochopit.","%o døde på en eller anden tilfældig måde, som jeg ikke kan gennemskue.",%o starb auf eine unvorstellbare Art und Weise.,,"%o mortis per iu malcerta maniero, kiun mi ne povas kompreni.",%o murió de alguna manera que no llego a comprender.,,"%o kuoli jollakin sattumanvaraisella tavalla, jota en voi käsittää.",%o est mort@[e_fr] d'une manière que je n'arrive même pas à décrire.,Ötletem since hogy halt meg %o.,%o è morto in un modo inimmaginabile.,%o は計算外の乱数で死んだ。,%o 은(는) 의미불명의 이유로 잠수를 타게 되었다.,%o stierf op een of andere willekeurige manier die ik me niet kan voorstellen.,%o døde på en eller annen tilfeldig måte jeg ikke fatter.,"%o zgin@[irreg_2_pl] pod wpływem metody, której nie mogę pojąć.",%o morreu de alguma forma aleatória que nem consigo imaginar.,,%o a murit într-un mod aleatoriu pe care nu mi-l pot închipui.,Игрок %o внезапно умер по непостижимой для меня причине.,,%o dog på något slumpmässigt sätt som jag inte kan förstå.,%o anlayamadığım rastgele bir yöntemle öldü. +%o was fried by a femme fatale freak.,OB_TERMIN,,,,%o byl@[ao_cs] usmažen@[ao_cs] šílenou femme fatale.,%o blev stegt af en femme fatale freak.,%o wurde von einem Femme-Fatale Freak gebraten.,,%o estis fritita de femme-fatale-groteskulo.,%o fue tostad@[ao_esp] por una femme fatale.,,%o joutui kohtalokkaan kimman kärtsäämäksi.,%o s'est fait@[e_fr] frire par une femme fatale.,%o-t lebombázta egy bomba nő.,% o è stato fritto da una femme fatale.,%o はファム ファタル フリークに揚げられた。,%o 은(는) 미인계에 발을 들였다.,%o werd gebakken door een femme fatale freak.,%o ble stekt av en femme fatale-freak.,%o został@[ao_pl] usmażon@[adj_pl] przez szaloną femme fatale.,%o foi fritad@[ao_ptb] por uma femme fatale psicótica.,,%o a fost prăjit de către o femme fatale psihopată.,Игрока %o поджарила чокнутая роковая женщина.,,%o stektes av en femme fatale-freak.,%o bir femme fatale ucubesi tarafından kızartıldı. +%o got a little close to the opposite sex.,OB_TERMINHIT,"This text is not gender neutral, obviously...",,,%o se moc přiblížil@[ao_cs] k opačnému pohlaví.,%o kom lidt tæt på det modsatte køn.,%o kam dem anderen Geschlecht zu nahe.,,%o iĝis iomete proksime al la mala sekso.,%o se acercó demasiado a la persona equivocada.,,%o meni hieman liian lähelle vastakkaista sukupuolta.,%o s'est trop rapproché@[e_fr] de la mauvaise personne.,%o túl közel került az ellenkező nemhez.,%o è arrivato troppo vicino all'altro sesso.,%o は少し異性に成り果てた。,%o 의 남자다운 자존심은 쪼그라들었다.,%o kwam een beetje in de buurt van het andere geslacht.,%o kom litt nær det motsatte kjønn.,%o pod@[irreg_1_pl] zbyt blisko do płci pięknej.,%o chegou perto demais do sexo oposto.,,%o s-a apropriat prea mult de sexul opus.,Игрок %o почти сблизился с противоположным полом.,,%o kom lite väl nära det motsatta könet.,%o karşı cinsle biraz yakınlaştı. +%o said goodbye to an old friend.,OB_REPLI,,,,%o řekl@[ao_cs] sbohem starému příteli.,%o sagde farvel til en gammel ven.,%o verabschiedete sich von einem alten Freund.,,"%o diris ""Ĝis la revido"" al malnova amiko.",%o se despidió de un viejo amigo.,,%o sanoi hyvästit vanhalle ystävälle.,%o dit au revoir à un vieil ami.,%o búcsút intett egy régi barátjának.,%o ha detto addio a un vecchio amico.,%o は古い友人に別れを告げた。,%o 은(는) 오랜 친구와 작별인사를 했다.,%o nam afscheid van een oude vriendin.,%o tok farvel med en gammel venn.,%o pożegnał@[ao_pl] się ze starym znajomym.,%o disse adeus a um velho amigo.,,%o a spus adio unui vechi prieten.,Игрок %o распрощался со старым другом.,,%o tog farväl av en gammal vän.,%o eski bir arkadaşına veda etti. +%o was stabbed in the back by an old friend.,OB_REPLIHIT,,,,%o byl@[ao_cs] bodnuta do zad starým přítelem.,%o blev stukket i ryggen af en gammel ven.,%o wurde von einem alten Freund in den Rücken gestochen.,,%o estis pikita en la dorson de malnova amiko.,%o fue apuñalad@[ao_esp] en la espalda por un viejo amigo.,,%o joutui vanhan ystävän selkäänpuukottamaksi.,%o s'est fait@[e_fr] planter une lame dans le dos par un vieil ami.,%o-t hátba szúrta egy régi barát.,%o è stato pugnalato alla schiena da un vecchio amico.,%o は古い友人に背中を刺された。,%o 은(는) 오랜 친구에게 배신을 당했다.,%o werd in de rug gestoken door een oude vriend.,%o ble dolket i ryggen av en gammel venn.,%o został@[ao_pl] dźgnięt@[adj_pl] w plecy przez starego znajomego.,%o foi apunhalad@[ao_ptb] pelas costas por um velho amigo.,,%o a fost înjunghiat pe la spate de către un vechi prieten.,Игрок %o получил нож в спину от старого друга.,,%o blev knivhuggen i ryggen av en gammal vän.,%o eski bir arkadaşı tarafından sırtından bıçaklandı. +%o was weeded out by natural selection.,OB_PHAGE,,,,%o byl@[ao_cs] vyčištěna přirozeným výběrem.,%o blev sorteret fra ved naturlig udvælgelse.,%o fiel der natürlichen Auslese zum Opfer.,,%o estis foriga de natura elektado.,%o fue eliminad@[ao_esp] por selección natural.,,%o joutui luonnonvalinnan kitkemäksi.,%o a été éliminé@[e_fr] par la sélection naturelle.,A természetes kiválasztás áldozata lett %o.,%o cadde vittima della selezione naturale.,%o は自然淘汰によって除草された。,%o 은(는) 약육강식을 지금까진 모르고 있었다.,%o werd door natuurlijke selectie weggehaald.,%o ble luket ut av naturlig seleksjon.,%o został@[ao_pl] przesian@[adj_pl] przez naturalną selekcję.,%o foi eliminad@[ao_ptb] por seleção natural.,,%o a fost eliminat prin selecție naturală.,Игрок %o был отсеян естественным отбором.,,%o blev utsorterad av det naturliga urvalet.,%o doğal seleksiyon tarafından ayıklandı. +%o couldn't escape a thorny death.,OB_THORN,,,,%o nemohl@[ao_cs] utéct bodlavé smrti.,%o kunne ikke undslippe en tornedød.,%o konnte einem dornigen Tod nicht entkommen.,,%o ne povis eskapi dornan morton.,%o no pudo escapar una muerte espinosa.,,%o ei kyennyt välttämään piikikästä kuolemaa.,%o n'a pu éviter une mort piquante.,Lyukasra szúrták %o-t a tövisek.,%o non poteva sfuggire a una morte spinosa.,%o は棘のある死から逃げられなかった。,%o 은(는) 따가운 죽음을 피할 수 없었다.,%o kon niet ontsnappen aan een netelige dood.,%o kunne ikke unnslippe en tornefull død.,%o nie m@[irreg_4_pl] uciec przed cierniową śmiercią.,%o não conseguiu escapar de uma morte espinhosa.,,%o nu a putut scăpa de o moarte spinoasă.,Игрока %o поджидала смерть на его тернистом пути.,,%o kunde inte undgå en taggig död.,%o dikenli bir ölümden kaçamadı. +%o took a sumo punch to the groin.,OB_SUMATIC,,,,%o dostal@[ao_cs] sumo ránu pod pás.,%o fik et sumo-slag i lysken.,%o bekam einen Sumo-Schlag an @[pp_de] empfindlichste Stelle.,,%o prenis sumoan baton en la ingveno.,%o recibió un puñetazo de sumo en la entrepierna.,,%o otti vastaan sumoiskun nivusiin.,%o s'est pris le poing d'un sumo dans l'entrejambe.,%o szerszámjával tompította az jobb horgot.,%o ha ricevuto un soffio su un punto sensibile.,%o は股座にスモウ ハリテを食らった。,%o 은(는) 가랑이 사이에 정권을 찔렀다.,%o nam een sumo punch in de lies.,%o fikk et sumoslag i skrittet.,%o dostał@[ao_pl] cios sumo w pachwinę.,%o tomou um golpe de sumô na virilha.,,%o a primit un pumn sumo în vintre.,Игрок %o отхватил удар в пах от сумоиста.,,%o tog emot ett sumoslag i ljumsken.,%o kasıklarına bir sumo yumruğu yedi. +%o didn't get %p three wishes.,OB_GENIE,,,,%o nedostal@[ao_cs] svá tři přání.,%o fik ikke sine tre ønsker.,%o bekam @[pp_de] drei Wünsche nicht erfüllt.,,%o ne ricevis siajn tri petojn.,%o no recibió sus tres deseos.,,%o ei saanut kolmea toivettaan.,%o n'a pas préparé ses trois vœux.,%o nem teljesítette %p 3 kívánságát.,%o non ha soddisfatto i suoi tre desideri.,%o は %p に三願を望まなかった。,%o 은(는) 세 가지 소원을 빌 수 없었다.,%o kreeg niet drie wensen.,%o fikk ikke oppfylt tre ønsker.,%o nie dostał@[ao_pl] swoich trzech życzeń.,%o não concedeu três desejos a %p.,,%o nu a putut să-și pună cele trei dorințe.,Игрок %o не загадает трёх желаний.,,%o fick inte sina tre önskningar uppfyllda.,%o üç dileğini yerine getiremedi. +%o tried to pet a mine.,OB_MINE,,,,%o se pokusil@[ao_cs] pohladit minu.,%o forsøgte at kæle for en mine.,"%o versuchte, eine Mine zu streicheln.",,%o provis glatumi minon.,%o intentó acariciar una mina.,,%o yritti silittää miinaa.,%o a essayé de caresser une mine.,%o meg akart simogatni egy aranyos aknát.,%o ha provato ad accarezzare una mina.,%o は地雷を愛撫しようとした。,%o 은(는) 기뢰와 친구가 되고 싶었다.,%o probeerde een mijn te aaien.,%o prøvde å klappe en mine.,%o próbował@[ao_pl] pogłaskać minę.,%o tentou fazer carinho numa mina.,,%o a încercat să mângâie o mină.,Игрок %o хотел погладить мину.,,%o försökte klappa en mina.,%o bir mayını sevmeye çalıştı. +%o took %k's Bruce Lee fu-kick to the face.,OB_MPKICK,,,,%o dostal@[ao_cs] kopanec do obličeje od kung-fuistou %k.,%o fik %ks Bruce Lee fu-kick i ansigtet.,%o bekam einen Bruce-Lee-Fußtritt ins Gesicht.,,%o ricevis la Bruce Lee piedbaton de %k en sia vizaĝo.,%o se comió una patada de kung-fu a lo Bruce Lee de %k.,,%k potkaisi %o raukkaa päin naamaa Bruce Leen kung fu-tyyliin.,%o s'est mangé@[e_fr] un coup de pied à la Bruce Lee de la part de %k.,%o arccal vette le %k pörgőrugását.,%o ha un calcio in faccia.,%o の顔に %k のブルースリーキックを当てた。,%o 은(는) %k 의 거침없는 하이킥을 받았다.,%o nam %k's Bruce Lee fu-kick in het gezicht.,%o tok %ks Bruce Lee fu-kick i ansiktet.,%o dostał@[ao_pl] kopniakiem w stylu Bruce'a Lee od %k.,%o tomou uma voadora de %k na cara.,,%o a primit un șut în stil Bruce Lee.,"Игрок %o отхватил от игрока %k удар в лицо, достойный Брюса Ли.",,%o tog emot %ks Bruce Lee fu-kick i ansiktet.,"%o, %k tarafından tekmelendi." +%o fell apart via %k's shocking revelation.,OB_MPREZNATOR,,,,%o se rozpadl@[ao_cs] šokujícím odhalením hráče %k.,%o faldt fra hinanden via %ks chokerende åbenbaring.,%o erhielt eine schockierende Enthüllung von %k.,,%o diseriĝis pro la ŝokantan revelaĉio de %k.,%o cayó ante la revelación chocante de %k.,,%o romahti käyttäjän %k sähköistävästä ilmestyksestä.,%o a été témoin de la révélation choquante de %k.,%k megrázó élmányben részesítette %o-t.,%o ricevette una scioccante rivelazione da %k.,%o は %k の衝撃的な啓示によりバラバラになった。,%o 은(는) %k 이(가) 선사한 전기 찜질을 맛봤다.,%o viel uit elkaar via %k's schokkende onthulling.,%o falt fra hverandre via %ks sjokkerende åpenbaring.,%o rozpadł@[ao_pl] się pod wpływem szokującego objawienia %k.,%o ficou arrasad@[ao_ptb] pela revelação chocante de %p.,,%o s-a făcut praf la revelația șocantă a lui %k.,Игрок %o шокирован откровениями %k.,,%o föll sönder genom %ks chockerande avslöjande.,"%o, %k tarafından kızartıldı." +%o took a double-dose of %k's punishment.,OB_MPXPISTOL,,,,%o dostal@[ao_cs] dvojitou dávku potrestání hráče %k.,%o fik en dobbeltdosis af %ks straf.,%o bekam eine doppelte Dosis von %ks Bestrafung.,,%o duoble dozis la puno de %k.,%o recibió una doble dosis del castigo de %k.,,%o otti tupla-annoksen käyttäjän %k kuritusta.,%o a mangé une double dose de la furie de %k.,%o ólom túladagolást kapott %k-tól.,%o ha ottenuto una doppia dose della punizione di %k.,%o は %k の懲罰を二度受けた。,%o 은(는) %k 의 2총신 사격을 받았다.,%o nam een dubbele dosis van %k's straf.,%o tok en dobbel dose av %ks straff.,%o dostał@[ao_pl] podwójną dawkę kary %k.,%o tomou uma dose dupla da punição de %k.,,%o a luat o doză dublă din pedeapsa lui %k.,Игрок %o принял двойную дозу возмездия от %k.,,%o fick en dubbel dos av %ks straff.,"%o, %k tarafından cezalandırıldı." +%o was shut down by %k's shock-stick.,OB_MPTAZER,,,,%o byl@[ao_cs] vypnut@[ao_cs] šokádou hráče %k.,%o blev lukket ned af %ks chok-stick.,%o wurde von %ks Schockstab ausgeschaltet.,,%o estis malŝaltita de la ŝokbateno de %k.,%o fue noquead@[ao_esp] por la vara eléctrica de %k.,,%o joutui käyttäjän %k sähkökepin sammuttamaksi.,%o s'est fait mettre K.O par le bâton électrique de %k.,"%o-t sokkolta a hír, hogy %k-t megölte.",%o è stato spento dalla bacchetta di %k.,%o は %k のショックスティックでシャットダウンした。,%o 은(는) %k 의 무력행사에 아예 포기했다.,%o werd uitgeschakeld door %k's schokstick.,%o ble stengt av %ks sjokkpinne.,%o został@[ao_pl] wyłączon@[adj_pl] przez szokującą pałkę %k.,%o foi desligado pelo espeto chocante de %k.,,%o a fost dezactivat de arma cu șocuri a lui %k.,Игрок %o выведен из строя электродубинкой %k.,,%o blev nedsläckt av %ks chockpinne.,"%o, %k tarafından kapatıldı." +%o got a face-full of %k's ice-cold wrath.,OB_MPCRYOGUN,,,,%o se zabořil@[ao_cs] do mrazivého hněvu hráče %k.,%o fik et ansigt fuld af %ks iskolde vrede.,%o bekam eine Ladung von %ks eiskaltem Zorn ins Gesicht.,,%o ricevis la glacie malvarman koleregon de %k.,%o recibió la ira gélida de %k en toda la cara.,,%o sai saamansa täyteen käyttäjän %k jääkylmää vihaa.,%o s'est fait congeler la figure par la colère glaciale de %k.,%k jégre tette %o-t,%o ha un carico di freddo gelido di %k in faccia.,%o は %k の冷めた表情で凍った。,%o 은(는) %k 덕분에 맛있게 냉동 보존되었다.,%o kreeg een gezicht vol met %k's ijskoude toorn.,%o fikk ansiktet fullt av %ks iskalde vrede.,%o dostał@[ao_pl] wielką dawkę mroźnego gniewu %k.,%o tomou um gelo de %k. ,,%o a simțit din plin furia rece a lui %k.,Игрок %o столкнулся с ледяной ненавистью %k.,,%o fick en ansiktsfyllning av %ks iskalla vrede.,"%o, %k tarafından donduruldu." +"%o was drilled full of holes by %k, gangsta-style.",OB_MPUZI,,,,%o byl@[ao_cs] prostřílen@[ao_cs] skrz na skrz gangsterem %k.,"%o blev boret fuld af huller af %k, på gangsta-stil.",%o wurde von %k im Gangsta-Stil perforiert.,,"%o estis borita truplena de %k, ganstere.","%o fue acribillad@[ao_esp] por %k, al estilo gangster.",,%k porasi %o raukan täyteen reikiä gangsta-tyyliin.,"%o s'est fait perforer dans tous les sens par %k, Gangsta style.",%o gengszter stílusban sajttá lyuggatta %k,%o è stato perforato da %k in stile gangsta.,%o はギャングの様な %k に蜂の巣にされた。,%o 은(는) %k 이(가) 선사한 갱스터 스타일 난사를 막지 못했다.,"%o werd vol gaten geboord met %k, in gangsta-stijl.","%o ble boret full av hull av %k, i gangsta-stil.",%o został@[ao_pl] podziurawion@[adj_pl] przez %k niczym gangster.,%o tomou pipoco de %k.,,%o a fost umplut de găuri în stil mafiot de către %k.,Игрок %o покрылся дырками после гангста-стрельбы игрока %k.,,"%o borrades full av hål av %k, på gangstermanér.","%o, %k tarafından gangsta tarzı delik deşik edildi." +%o ate %k's photon bomb.,OB_MPZOOKA,,,,%o sežral@[ao_cs] fotonovou bombu hráče %k.,%o spiste %ks fotobombe.,%o nahm %ks Photonenbombe.,,%o manĝis la fotonbombon de %k.,%o se comió la bomba de fotones de %k.,,%o söi käyttäjän %k fotonipommin.,%o a bouffé la bombe photonique de %k.,%o megette %k foton bombáját,%o ha preso la bomba fotonica di %k.,%o は %k のフォトンボムを食らった。,%o 은(는) %k 의 광자탄을 봤는데도 피하지 못했다.,%o at %o %k's fotonbom.,%o spiste %ks fotonbombe.,%o zjadł@[ao_pl] fotonową bombę %k.,%o engoliu a bomba de fótons de %k.,,%o a mâncat bomba fotonică a lui %k.,Игрок %o съел фотонную бомбу %k.,,%o åt upp %ks fotobomb.,"%o, %k tarafından atomize edildi." +%o was reduced to a neat pile of photons by %k.,OB_MPZ_SPLASH,,,,%o byl@[ao_cs] zredukován@[ao_cs] na hromádku fotonů hráčem %k.,%o blev reduceret til en ordentlig bunke fotoner af %k.,%o wurde von %k zu einem Haufen Photonen verarbeitet.,,%o estis reduktita en ordeman amason da fotonoj de %k.,%o fue reducid@[ao_esp] a una pila de fotones por %k.,,%k redusoi %o raukan sieväksi fotonipinoksi.,%o s'est fait@[e_fr] réduire en une jolie pile de photons par %k.,%o-ból csak egy marokni fotont hagyott hátra %k,%o è stato elaborato da %k in un mucchio di fotoni.,%o は %k によって蛍光灯にされた。,%o 은(는) %k 의 광자력을 탐냈다. 죽기 전까지는.,%o werd gereduceerd tot een nette stapel fotonen met %k.,%o ble redusert til en pen haug med fotoner av %k.,%o został@[ao_pl] zredukowan@[adj_pl] do maleńkiej kupki fotonów przez %k.,%o foi reduzido à uma bela pilha de fótons por %k.,,%o a fost transformat într-o grămadă simpatică de fotoni de către %k.,Игрок %o был разложен игроком %k в аккуратную кучку фотонов.,,%o reducerades till en prydlig hög fotoner av %k.,"%o, %k tarafından düzgün bir foton yığınına indirgendi." +%o was reduced to antimatter by %k.,OB_MPANTIGUN,"Physically this is utter nonsense, of course.",,,%o byl@[ao_cs] zredukován@[ao_cs] na antihmotu hráčem %k.,%o blev reduceret til antimaterie af %k.,%o wurde von %k zu Antimaterie reduziert.,,%o estis reduktita en antimaterion de %k.,%o fue reducid@[ao_esp] a antimateria por %k.,,%k redusoi %o raukan antimateriaksi..,%o s'est fait inverser les atomes par %k.,%k antianyaggá lőttte %o-t,%o è stato ridotto all'antimateria da %k,%o は %k のにより反物質に変換された。,%o 은(는) %k 의 반물질의 힘에 의해 소멸되었다.,%o werd gereduceerd tot antimaterie met %k.,%o ble redusert til antimaterie av %k.,%o został@[ao_pl] zredukowan@[adj_pl] do antymaterii przez %k.,%o foi transformado em antimatéria por %k.,,%o a fost transformat în antimaterie de către %k.,Игрок %o был разложен игроком %k до антиматерии.,,%o reducerades till antimateria av %k.,"%o, %k tarafından atomlara indirgendi." +%o swallowed %k's nuke.,OB_MPNUKE,,,,%o spolkl@[ao_cs] atomovku hráče %k.,%o slugte %ks atombombe.,%o verschluckte sich an %ks Atomrakete.,,%o glutis la nuklean bombon de %k.,%o se tragó la bomba atómica de %k.,,%o nieli käyttäjän %k ydinpommin.,%o s'est pris@[e_fr] la bombe thermonucléaire de %k dans la figure.,%o megette %k atombomáját,%o soffocò sul missile nucleare di %k.,%o は %k の核を飲み干した。,%o 은(는) %k 덕분에 하늘을 뚫을 버섯구름이 되었다.,%o geslikt %o nuke %k's nuke.,%o svelget %ks atombombe.,%o połkn@[irreg_2_pl] atomówkę %k.,%o engoliu o míssil núclear de %k.,,%o a înghițit proiectilul lui %k.,Игрок %o проглотил ядерный заряд %k.,,%o svalde %ks atombomb.,"%o, %k tarafından bombalandı." +%o went nuclear from %k's mass destruction spree.,OB_MPNUKESPLASH,,,,%o si zkrátil@[ao_cs] svůj poločas rozpadu při zabijačce hráče %k.,%o blev atomvåben af %ks masseødelæggelser.,%o wurde von %ks Massenzerstörungsaktion verstrahlt.,,%o iĝis nuklea pro la amasdetruado de %k.,%o se volvió radioactiv@[ao_esp] por la racha de destrucción masiva de %k.,,%o muuttui radioaktiiviseksi käyttäjän %k massatuhoputken takia.,%o s'est fait@[e_fr] irradier par la folie destructrice de %k.,%o felrobbant az idegtől amikor meglátta %k bombáját,%o fu irradiato dall'azione di distruzione di massa di %k.,%o は %k の虐殺ごっこの犠牲者になった。,%o 은(는) %k 의 핵실험에 참여했다.,%o werd nucleair van de massavernietigingswoede van %k's massavernietigingswoede.,%o ble nuklear av %ks masseødeleggelse.,%o został@[ao_pl] napromieniowan@[adj_pl] przez masową destrukcję %k.,%o virou picadinho radioativo por causa da destruição em massa causada por %k.,,%o a devenit radioactiv în urma distrugerii în masă a lui %k.,Игрок %o светится в темноте от оружия массового поражения %k.,,%o blev kärnvapenfri av %ks massförstörelse.,"%o, %k tarafından bombalandı." +%o was turned inside-out by %k.,OB_MPTELEFRAG,,,,%o byl@[ao_cs] obrácen@[ao_cs] naruby hráčem %k.,%o blev vendt ud og ind af %k.,%o wurde von %k zerfetzt.,,La interno de %o estis eksteriga de %k.,%o fue puest@[ao_esp] del revés por %k.,,%k käänsi %o raukan nurinpäin.,%o s'est fait@[e_fr] inverser par %k.,%k kifordította %o-t,%o fu fatto a pezzi da %k,%o は %k に裏返しにされた。,%o 은(는) %k 에 의해 자신이 분해되는 꼴을 못 봤다.,%o werd binnenstebuiten gekeerd met %k.,%o ble snudd på hodet av %k.,%o został@[ao_pl] wywrócon@[adj_pl] na lewą stronę przez %k.,%o foi virad@[ao_ptb] ao avesso por %k.,,%o a fost întors pe dos de către %k.,Игрок %o вывернут наизнанку игроком %k.,,%o vändes ut och in av %k.,"%o, %k tarafından parçalandı." +%o's atomic structure was split apart.,OB_MONTELEFRAG,,,,Struktura atomů hráče %o se rozpadla.,%os atomstruktur blev splittet op.,%os Atomstruktur wurde vernichtet.,,La atoma strukturo de %o estis disfendita.,%o fue desintegrad@[ao_esp] al nivel atómico.,,%o raukan atomirakenne hajosi.,%o s'est fait@[e_fr] désassembler au niveau atomique.,%o atomjaira esett szét,La struttura atomica di %o fu distrutta.,%o の原子構造は分解された。,%o 의 원자 마디마디가 흩어졌다.,De atoomstructuur van %o werd gesplitst.,%o's atomstruktur ble splittet fra hverandre.,Atomy %o zostały od siebie oddzielone.,A estrutura atômica de %o foi separada.,,Structura atomică a lui %o a fost spulberată.,Атомная структура игрока %o разрушена.,,%os atomstruktur splittrades.,%o atomik düzeyde parçalara ayrıldı. +%o spontaneously expired.,OB_DEFAULT,,,,%o samovolně vypršel@[ao_cs].,%o udåndede spontant.,%o hörte spontan auf zu existieren.,,%o spontane finiĝis.,%o tuvo una muerte espontánea.,,%o spontaanisti kupsahti.,%o a spontanément expiré.,%o hirtelenjében elérte a lejárati időt,%o ha smesso spontaneamente di esistere.,%o の有効期限が自発的に切れた,%o 은(는) 파란만장하게 사라졌다.,%o is spontaan verlopen.,%o gikk spontant til grunne.,%o spontanicznie umarł@[ao_pl].,%o pereceu expontâneamente.,,%o a expirat în mod spontan.,Время игрока %o неожиданно вышло.,,%o dog spontant.,%o kendiliğinden öldü. +You grab a NUKER! Suck on this!,GOTNUKER,,,,Sebral@[ao_cs] jsi ATOMOVKÁTOR! Pojď na to!,Du tager en NUKER! Sut på den!,Ein NUKER! Verschluck dich daran.,,Vi prenis NUKER! Jen havu!,¡Has pillado un NUKER! ¡Chupaos esa!,¡Has recogido un NUKER! ¡Chúpate esa!,%Kahmaiset YDÄRIN! Ime tätä!,Vous découvrez le NUKER! Ca va en chier!,Meglelted a NUKER-t! Ezt kapd ki!,Prendi un NUKER! Succhia su questo!,NUEKR を奪った! 覚悟しろ!,누커 획득! 한바탕 쓸어볼까!,Je pakt een NUKER! Zuig hier maar aan!,Ta en NUKER! Sug på denne!,Podniosłeś ATOMÓWKĘ! Ssijcie to!,Você pegou um NUKER! Chupa essa manga!,,Ai ridicat Lansatorul Nuclear! Ia de-aici!,Заполучен ЯДЕРНЫЙ ГРАНАТОМЁТ! Отсосите!,,Du tar en NUKER! Sug på den här!,Sen bir NÜKER kap! Bunu em! +You got an UZI!!,GOTUZI,,,,Získal@[ao_cs] jsi UZI!,Du har en UZI!!,UZI genommen!,,Vi prenis UZI!!,¡¡Has obtenido una UZI!!,,Sait UZIn!!,Vous chopez un UZI!,Meglelted az UZI-t!,Hai un UZI !!,UZI をゲットした!!,우지 기관단총 획득!,Je hebt een UZI!!,Du har en UZI!,Zdobyłeś UZI!!,Você pegou uma UZI!!,,Ai ridicat un UZI!!,Заполучен УЗИ!!,,Du har en UZI!!,Bir UZI'n var! +A HOIG Reznator - FRY some butt,GOTREZNATOR,,,,HOIG Reznátor - pár jich upeč,En HOIG Reznator - Fritér noget røv,Ein HOIG Reznator.,,HOIG-Reznilo - FRITU pugon!,Un Reznator HOIG. ¡Hora de freir traseros!,,HOIG-reznaattori - KÄRISTÄ takamuksia,"Un Reznator HOIG, allez frire du monde!",Egy HOIG Reznator - okozz pár megrázó élményt,Un Reignator HOIG - friggere un po 'di carne,HOIGレジネイター - ぶっ潰してやれ,HOIG 전자무력기 획득! 전기 통구이를 만들자고!,Een HOIG Reznator - FRY sommige kont,En HOIG Reznator - FRY litt rumpe!,Reznator HOIG - skop trochę tyłków,Um Reznador HOIG - Hora de fritar,,Un Rezonator HOIG - Arde-i!,ХОЙГ Резнатор,,En HOIG Reznator - FRY några rumpor,Bir HOIG Reznator - Biraz kıç kızartın +You got a Photon 'Zooka!,GOTPHOTONZOOKA,,,,Sebral@[ao_cs] jsi Fotonovou bazuku!,Du har en Photon 'Zooka!,Photonen-'zooka genommen!,,Vi prenis Fotonbazukon!,¡Has obtenido un Bazooka de Fotones!,,Sait fotonisingon!,Vous récupérez un Bazooka Photonique!,Meglelted a Foton Ágyút!,Hai un cannone Photon!,フォトン'ゾーカ をゲットした!,광자 바주카 획득!,Je hebt een Photon 'Zooka!,Du har en Photon 'Zooka!,Zdobyłeś Fotonozukę!,Você pegou uma Bazuca de Fótons!,,Ai ridicat o Bazooka Fotonică!,Заполучена фотон-базука!,,Du har en Photon 'Zooka'!,Bir Foton 'Zooka'n var! +You carry a Big Stick!,GOTBIGSTICK,,,,Nosíš velkou bouchačku!,Du har en Big Stick!,Du trägst einen langen Stock.,,Vi portas grandan bastonon!,¡Llevas un Gran Palo!,,Kannat isoa keppiä!,Vous avez un gros bâton!,Nagy bottal jársz öcsém!,Porti un grosso bastone!,ビッグスティック を手に取った!,반물질 봉 획득!,Je draagt een Big Stick!,Du har en Big Stick!,Podnosisz Wielką Pałkę!,Você pegou um Grande Bastão!,,Ai ridicat un Băț Lung!,Заполучена длинная палка!,,Du har en stor käpp!,Büyük bir sopa taşıyorsun! +You got a Tazer!!,GOTTAZER,,,,Získal@[ao_cs] jsi tazer!,Du har en Tazer!!,Tazer genommen!,,Vi prenis Elektropafilon!!,¡¡Has obtenido un Taser!!,,Sait etälamauttimen!!,Vous trouvez un Taser!,Meglelted a Sokkolót!,Hai un Taser !!,テイザー をゲットした!,테이져 획득!,Je hebt een Tazer!!,Du har en Tazer!,Zdobyłeś Tazer!!,Você pegou um Tazer!!,,Ai ridicat un Taser!!,Заполучен тазер!,,Du har en Tazer!,Bir Tazer'ın var!! +You grab a Cryogun! FREEZE!,GOTCRYOGUN,,,,Sebral@[ao_cs] jsi krypušku! ANI SE NEHNI!,Du har en Cryogun! Frys!,Cryowaffe genommen! GEFRIER!,,Vi prenis Kriogenikpafilon! FROSTIĜU!,¡Has pillado un Criogenizador!! ¡Todos quietos!,¡Has recogido un Criogenizador!! ¡Quietos todos!,Kahmaiset kryopyssyn! PYSÄHDY!,Vous prenez un Cryogun! On s'arrête!,Felkapod a Cryogun-t! Induljon a fagyasztás!,Prendi un Cryogun! CONGELARE!,クライォガン を奪った! フリーズ!,크라이로건 획득! 그대로 멈춰라!,Je pakt een Cryogun! FREEZE!,Du har en Cryogun! FREEZE!,Podniosłeś Zamrażarkę! STAĆ!,Você pegou uma Cryogun! FICA FRIO AÍ!,,Ai ridicat o Crio-armă! ÎNGHEAȚĂ!,Заполучена замораживающая пушка! НИ С МЕСТА!,,Du har en Cryogun! FRIAS!,Bir Cryogun al! DONDUR! +You grab some rounds!,GOTROUNDS,,,,Sebral@[ao_cs] jsi nějaké náboje!,Du tager nogle patroner!,Munition genommen.,,Vi prenis kuglojn!,¡Has pillado unas balas!,¡Has recogido unas balas!,Kahmaiset patruunoita!,Vous prenez des balles!,Felkapsz pár lőszert!,Prendi delle munizioni!,幾つかのラウンド を奪った!,권총 탄약을 주웠다!,Je pakt wat rondes!,Du tar noen runder!,Podniosłeś trochę naboi!,Você pegou munição!,,Ai ridicat niște muniție!,Заполучена обойма патронов!,,Du tar några patroner!,Biraz mermi al! +You grab a case of rounds!,GOTROUNDSCASE,,,,Sebral@[ao_cs] jsi krabici nábojů!,Du tager en kasse med patroner!,Munitionskiste genommen.,,Vi prenis skatolon da kugloj!,¡Has pillado una caja de balas!,¡Has recogido una caja de balas!,Kahmaiset patruunalaatikon!,Vous prenez une bôite de balles!,Felkapsz egy doboz lőszert!,Prendi un caso di munizioni!,ケースのラウンド を奪った!,권총 탄약 상자를 주웠다!,Je pakt een kist met rondes!,Du tar en kasse med patroner!,Podniosłeś skrzynkę naboi!,Você pegou uma caixa de munição!,,Ai ridicat un cartuș de muniție!,Заполучена коробка патронов!,,Du tar en låda med patroner!,Bir kutu mermi al! +You grab a Torpedo!,GOTTORPEDO,"Was ""grap"" for some reason.",,,Sebral@[ao_cs] jsi torpédo!,Du tager en Torpedo!,Torpedo genommen.,,Vi prenis Torpedon!,¡Has pillado un torpedo!,¡Has recogido un torpedo!,Kahmaiset torpedon!,Vous prenez une torpille!,Felkapsz egy Torpedót!,Prendi un siluro!,トルペード を奪った!,광자탄을 주웠다!,Je pakt een Torpedo!,Du tar en Torpedo!,Podniosłeś Torpedę!,Você pegou um Torpedo!,,Ai ridicat o Torpilă!,Заполучена торпеда!,,Du tar en torped!,Bir Torpido al! +You grab a case of Torpedos!,GOTTORPEDOS,,,,Sebral@[ao_cs] jsi krabici torpéd!,Du tager en kasse med torpedoer!,Torpedokiste genommen.,,Vi prenis skatolon da Torpedoj!,¡Has pillado una caja de torpedos!,¡Has recogido una caja de torpedos!,Kahmaiset torpedolaatikon!,Vous prenez une bôite de torpilles!,Felkapsz egy doboz Torpedót!,Prendi un caso di siluri!,トルペードのケース を奪った!,광자탄 무더기를 주웠다!,Je pakt een kist Torpedo's!,Du tar en kasse med torpedoer!,Podniosłeś skrzynkę Torped!,Você pegou uma caixa de Torpedos!,,Ai ridicat o cutie de Torpile!,Заполучен ящик торпед!,,Du tar en låda med torpeder!,Bir kasa Torpido al! +You grab a molecule module!,GOTMOLECULES,,,,Sebral@[ao_cs] jsi molekulový modul!,Du tager et molekylmodul!,Molekülmodul genommen,,Vi prenis molekulmodulon!,¡Has pillado un módulo molecular!,¡Has recogido un módulo molecular!,Kahmaiset molekyylimoduulin!,Vous prenez un module moléculaire!,Felkapsz egy molekula modult!,Prendi un modulo molecolare!,モーレキュールモヂュール を奪った!,분자 모듈을 주웠다!,Je pakt een molecuulmodule!,Du tar en molekylmodul!,Podniosłeś molekularny moduł!,Você pegou um módulo molecular!,,Ai ridicat un modul molecular!,Заполучен молекулярный модуль!,,Du tar en molekylmodul!,Bir molekül modülü kap! +You grab a tank full of molecules!,GOTMOLECULESTANK,,,,Sebral@[ao_cs] jsi sud plný molekul!,Du tager en tank fuld af molekyler!,Tank mit Molekülmodulen genommen.,,Vi prenis reservujon da molekulojn!,¡Has pillado un tanque lleno de moléculas!,¡Has recogido un tanque lleno de moléculas!,Kahmaiset tankin täynnä molekyylejä!,Vous prenez un réservoir de molécules!,Felkapsz egy teli tank molekulát!,Prendi un serbatoio pieno di molecole!,タンク満タンのモーレキュール を奪った!,분자 탱크를 주웠다!,Je pakt een tank vol met moleculen!,Du tar en tank full av molekyler!,Podniosłeś zbiornik pełen molekuł!,Você pegou um tanque cheio de moléculas!,,Ai ridicat un rezervor plin cu molecule!,Заполучен контейнер с молекулами!,,Du tar en tank full av molekyler!,Moleküllerle dolu bir tank al! +You grab some Cartridges!,GOTCARTRIDGES,,,,Sebral@[ao_cs] jsi nějaké kazety!,Du tager nogle patroner!,Magazin genommen.,,Vi prenis iom da kartoĉoj!,¡Has pillado unos cartuchos!,¡Has recogido unos cartuchos!,Kahmaiset kasetteja!,Vous prenez des cartouches!,Felkapsz pár Töltényt!,Prendi alcune cartucce!,残弾のカートリッジ を奪った!,카트리지 한 줌을 주웠다!,Je pakt een paar patronen!,Du tar noen patroner!,Podniosłeś trochę pocisków!,Você pegou alguns Carregadores!,,Ai ridicat niște Cartușe!,Заполучены картриджи!,,Du tar några patroner!,Fişekleri al! +You grab a case of Cartridges!,GOTCARTRIDGESCASE,,,,Sebral@[ao_cs] jsi krabici kazet!,Du tager en kasse med patroner!,Magazinkiste genommen.,,Vi prenis skatolon da kartoĉoj!,¡Has pillado una caja de cartuchos!,¡Has recogido una caja de cartuchos!,Kahmaiset laatikollisen kasetteja!,Vous prenez une bôite de cartouches!,Felkapsz egy doboz Töltényt!,Prendi un caso di cartucce!,カートリッジケース を奪った!,카트리지 박스를 주웠다!,Je pakt een kist patronen!,Du tar en kasse med patroner!,Podniosłeś skrzynkę pocisków!,Você pegou uma caixa de Carregadores!,,Ai ridicat o cutie de Cartușe!,Заполучен ящик картриджей!,,Du tar en låda med patroner!,Bir kutu fişek al! +You grab a Valise stuffed with goods!,GOTVALISE,,,,Sebral@[ao_cs] jsi kufr plný munice!,Du tager en kuffert fyldt med varer!,Munitionstasche genommen.,,Vi prenis valizon plenan de municiojn!,¡Has pillado una maleta llena de equipamiento!,¡Has recogido una maleta llena de equipamiento!,Kahmaiset laukullisen täynnä tavaraa!,Vous récupérez une valise pleine d'équipement!,Felkapsz egy Poggyásznyi Muníciót!,Prendi una Valigia piena di merci!,代物を詰めたバリス を奪った!,탄약이 든 서류 가방을 주웠다!,Je pakt een Valise gevuld met goederen!,Du tar en koffert fylt med varer!,Podniosłeś Walizkę z wieloma dobrami!,Você pegou uma Mala cheia de equipamento!,,Ai ridicat o Valiză plină cu bunătăți!,Заполучена полная сумка боеприпасов!,,Du tar en valise fylld med varor!,İçi mal dolu bir valiz al! +Force Field!,GOTFORCEFIELD,,,,Silové pole!,Kraftfelt!,Kraftfeld!,,Fortkampo!,¡Campo de fuerza!,,Voimakenttä!,Champ de force!,Erőtér!,Campo di forza!,フォースフィールド!,방어막!,Krachtveld!,Kraftfelt!,Pole Siłowe!,Campo de Força!,,Câmp de Forță!,Силовое поле!,,Kraftfält!,Güç Alanı! +007Microtel,GOTMICROTEL,,,,,,,,007 Microtel!,Microtel 007,,,007 Microtel,,,007マイクロテル,007마이크로텔 근력 향상 칩!,,,,,,Microtel 007,Микрочип 007,,,007Microtel +You are EnK Blind!,GOTENKBLIND,,,,Jsi EnK-slep@[adj_cs]!,Du er EnK Blind!,Du bist EnK-blind!,,Vi estas ENK-Blinda,¡Tienes Ceguera EnK!,,Olet EnK-sokea!,Vous êtes aveugle à l'EnK!,EnK védett lettél!,Sei EnK-cieco!,EnKブラインドみてえだ!,EnK 투명 위장 장치!,Jij bent EnK Blind!,Du er EnK Blind!,Jesteś oślepiony przez EnK!,Você está vendado por EnK!,,Acum ești nedetectabil pentru Enk!,У тебя EnK-видимость!,,Du är EnK Blind!,Sen EnK Blind'sın! +Vulcan rubber Boots!,GOTRUBBERBOOTS,,,,Gumové boty!,Vulkaniske gummistøvler!,Gummistiefel!,,Vulkanaj Kauŭĉukaj Botoj!,¡Botas de goma vulcanizada!,,Vulkanoidut kumisaappaat!,Bottes en caoutchouc vulcanisé!,Vulkanizált gumi talp!,Stivali di gomma vulcanica!,バルカンラバーブーツ!,벌컨 방화 부츠!,Vulcan rubber Laarzen!,Vulcan gummistøvler!,Gumowe Buty Vulcan!,Botas Vulcanizadas!,,Bocanci din cauciuc Vulcan!,Резиновые сапоги!,,Vulkaniska gummistövlar!,Vulcan lastik botları! +SI Array mapping!,GOTSIARRAY,,,,Mapa pole SI!,SI Array kortlægning!,SI-Feld Karte!,,SI-matric-mapado!,¡Mapeado de Tabla SI!,,SI-kenttäkartta!,Carte du tableau SI!,SI pálya Felderítő!,Mappatura di array SI!,SIアーレイ マッピング!,Si 어레이 지도!,,SI Array kartlegging!,Mapa Pola SI!,Mapeamento por Campo de SI!,,Hartă SI compilată!,Составлена карта SI-массива!,,SI Array kartläggning!,SI Dizi eşlemesi! +Infrared Visor!,GOTINFRARED,,,,Infračervené brýle!,Infrarødt visir!,Infrarotbrille!,,Transruĝa Viziero!,¡Visor infrarrojo!,,Infrapunavisiiri!,Viseur infrarouge!,Infravörös Sisak!,Visore a infrarossi!,赤外線バイザー!,적외선 바이져!,Infrarood vizier!,Infrarødt visir!,Wizjer na Podczerwień!,Visor Infravermelho!,,Vedere Infraroșie!,Инфракрасный визор!,,Infrarött visir!,Kızılötesi Vizör! +"Breathe deep, Inhaler!",GOTINHALER,,,,"Pořádně se nadechni, inhalátor!","Træk vejret dybt, Inhalator!","Atme tief, Inhalierer!",,"Spiru profunde, inhalo!","¡Un inhalador, inspira fuerte!",,"Hengitä syvään, inhalaattori!","Respire, inhaleur!","Mély lélegzet, Inhaláló!","Respirare profondamente, inalatore!",深呼吸だ、インヘイラー!,각성제를 주웠다. 잘 들이마셔!,"Adem diep in, inhalator!","Pust dypt, Inhalator!",Weź głęboki wdech! Inhalator!,Inalador! Respira fundo!,,"Inspiră adânc, Inhalatorule!",Ингалятор! Вдыхай глубже!,,"Andas djupt, Inhalator!","Derin nefes al, Inhaler!" +A dose of Hydergine from a Hypo saves you!,GOTHYPONEED,,,,Jsi zachráněn@[ao_cs] dávkou Hyderginu z Hypa!,En dosis Hydergine fra en Hypo redder dig!,Eine Dosis Hydergine rettet dich!,,,¡Una dosis de Hydergina te salva la vida!,,Hyderginepiikkiannos pelastaa sinut!,Une bonne dose d'hydergine vous sauve la vie!,Egy adag Hydergine megmenti az irhád!,Una dose di Hydergine di un Hypo ti salva!,ハイポで ヒデルギン をキメた!,하이포의 하이데르진이 당신을 살렸다!,Een dosis Hydergine van een Hypo redt je!,En dose Hydergine fra en Hypo redder deg!,Dawka Hyderginy z Hypo ratuje cię!,Uma dose de hidergina do Hypo para te salvar!,,O doză de Hidrogine dintr-o seringă te salvează!,Доза Редергина из шприца спасла тебя!,,En dos Hydergine från en Hypo räddar dig!,Hypo'dan bir doz Hydergine seni kurtarır! +You grab a Hypo!,GOTHYPO,,,,Sebral@[ao_cs] jsi Hypo!,Du tager en Hypo!,Hypo!,,Vi prenis Injektilon!,¡Has pillado una jeringa hipodérmica!,,Kahmaiset piikin!,Vous prenez une seringue!,Felkapsz egy Hypo-t!,Prendi un Hypo!,ハイポ を奪った!,하이포를 주웠다!,Je pakt een Hypo!,Du tar en Hypo!,Podniosłeś Hypo!,Você pegou um Hypo!,,Ai ridicat o Seringă!,Заполучен шприц!,,Du tar en Hypo!,Bir Hypo kaptın! +You found a KeyCard!,GOTKEYCARD,,,,Nalezl@[ao_cs] jsi přístupovou kartu!,Du har fundet et Nøglekort!,Schlüsselkarte gefunden!,,Vi trovis Ŝlosilkarton!,¡Has encontrado una Tarjeta Llave!,,Löysit avainkortin!,Vous trouvez une clé magnétique!,Leltél egy Kulcskártyát!,Hai trovato una chiave magnetica!,キーカードを見つけた!,키 카드를 찾았다!,U heeft een sleutelkaart gevonden!,Du har funnet et nøkkelkort!,Znalazłeś Kartę Dostępu!,Você achou um Cartão de Passe!,,Ai găsit un Card-Cheie!,Найдена ключ-карта!,,Du hittade ett nyckelkort!,Bir Anahtar Kart buldun! +You found a C-Key!,GOTCKEY,,,,Nalezl@[ao_cs] jsi kyberklíč!,Du har fundet en C-nøgle!,C-Schlüssel gefunden!,,Vi trovis C-Ŝlosilon!,¡Has encontrado una Llave-C!,,Löysit C-avaimen!,Vous trouvez une C-Clé!,Leltél egy C-Kulcsot!,Hai trovato una chiave C!,C-keyを見つけた!,C-키를 찾았다!,Je hebt een C-sleutel gevonden!,Du har funnet en C-nøkkel!,Znalazłeś Klucz C!,Você achou uma Chave-C!,,Ai găsit o Cheie-C!,Найден C-образный ключ!,,Du hittade en C-nyckel!,Bir C-Anahtarı buldun! +You found a Password!,GOTPASSWORD,,,,Nalezl@[ao_cs] jsi heslo!,Du har fundet et kodeord!,Passwort gefunden!,,Vi trovis Pasvorton!,¡Has encontrado una Contraseña!,,Löysit salasanan!,Vous trouvez un mot de passe!,Leltél egy Jelszót!,Hai trovato una parola d'ordine!,パスワードを見つけた!,암호를 찾았다!,U heeft een wachtwoord gevonden!,Du har funnet et passord!,Znalazłeś Hasło!,Você achou uma Senha!,,Ai găsit o Parolă!,Найден пароль!,,Du hittade ett lösenord!,Bir Şifre buldun! +You found a blue Z-Key!,GOTBLUEZKEY,,,,Nalezl@[ao_cs] jsi modrý Z-klíč!,Du fandt en blå Z-nøgle!,Blauen Z-Schlüssel gefunden!,,Vi trovis bluan Z-ŝlosilon!,¡Has encontrado una Llave-Z azul!,,Löysit sinisen Z-avaimen!,Vous trouvez une Z-Clé bleue!,Leltél egy kék Z-Kulcsot!,Hai trovato una chiave Z blu!,ブルー Z-Key を見つけた!,청색 Z-키를 찾았다!,Je hebt een blauwe Z-sleutel gevonden!,Du har funnet en blå Z-nøkkel!,Znalazłeś niebieski Klucz Z!,Você achou uma Chave-Z azul!,,Ai găsit o Z-Cheie albastră!,Найден синий Z-образный ключ!,,Du hittade en blå Z-nyckel!,Mavi bir Z-Anahtarı buldun! +You found a yellow Z-Key!,GOTYELWZKEY,,,,Nalezl@[ao_cs] jsi žlutý Z-klíč!,Du fandt en gul Z-nøgle!,Gelben Z-Schlüssel gefunden!,,Vi trovis flavan Z-ŝlosilon!,¡Has encontrado una Llave-Z amarilla!,,Löysit keltaisen Z-avaimen!,Vous trouvez une Z-Clé jaune!,Leltél egy sárga Z-Kulcsot!,Hai trovato una chiave Z gialla!,イエローZ-Key を見つけた!,황색 Z-키를 찾았다!,Je hebt een gele Z-sleutel gevonden!,Du har funnet en gul Z-nøkkel!,Znalazłeś żółty Klucz Z!,Você achou uma Chave-Z amarela!,,Ai găsit o Z-Cheie galbenă!,Найден жёлтый Z-образный ключ!,,Du hittade en gul Z-nyckel!,Sarı bir Z-Anahtarı buldun! +You found a red Z-Key!,GOTREDZKEY,,,,Nalezl@[ao_cs] jsi červený Z-klíč!,Du fandt en rød Z-nøgle!,Roten Z-Schlüssel gefunden!,,Vi trovis ruĝan Z-ŝlosilon!,¡Has encontrado una Llave-Z roja!,,Löysit punaisen Z-avaimen!,Vous trouvez une Z-Clé rouge!,Leltél egy piros Z-Kulcsot!,Hai trovato una chiave Z rossa!,レッド Z-Key を見つけた!,적색 Z-키를 찾았다!,Je hebt een rode Z-sleutel gevonden!,Du har funnet en rød Z-nøkkel!,Znalazłeś czerwony Klucz Z!,Você achou uma Chave-Z vermelha!,,Ai găsit o Z-Cheie roșie!,Найден красный Z-образный ключ!,,Du hittade en röd Z-nyckel!,Kırmızı bir Z-Anahtarı buldun! +Body Armor!,GOTBODYARMOR,,,,Brnění!,Kropsrustning!,Körperpanzerung!,,Kiraso!,¡Armadura!,,Suojavarustus!,Armure!,Testpáncél!,Giubbotti antiproiettile!,ボディーアーマー!,강화복!,Kogelvrije vesten!,Skuddsikker vest!,Pancerz!,Colete a Prova de Balas!,,Armură de Corp!,Бронежилет!,,Kroppspansar!,Vücut Zırhı! +Centrophenoxine,GOTCENTROPHENOXINE,,,,Centrofenoxin,Centrophenoxine,,,Centrofenoksino!,¡Centrofenoxina!,,Sentrofenoksiinia,Centrophenoxine!,,,セントロフェノキシン!,메클로페녹세이트!,,Centrophenoxine,Centrofenoxina,Centrofenoxina,,Centrofenoxine,Центрофеноксин,,, +You grab a Kevlar vest!,GOTKEVLARVEST,,,,Sebral@[ao_cs] jsi kevlarovou vestu!,Du får fat i en kevlarvest!,Kevlarweste!,,Vi prenis kevlaran veŝton!,¡Has pillado un traje de Kevlar!,¡Has recogido un traje de Kevlar!,Kahmaiset Kevlar-liivit!,Veste en Kevlar!,Felkapsz egy Golyóálló Mellényt!,Prendi una maglia di kevlar!,ケブラーベスト を奪った!,방탄복을 주웠다!,Pak een Kevlar vest!,Du tar en Kevlar-vest!,Podniosłeś kamizelkę kuloodporną!,Você pegou um Colete de Kevlar!,,Ai ridicat o vestă din Kevlar!,Заполучен кевларовый жилет!,,Du tar en kevlarväst!,Kevlar yeleği al! +You grab Super Kevlar vest!,GOTSKEVLARVEST,,,,Sebral@[ao_cs] jsi superkevlarovou vestu!,Du tager Super Kevlar vest!,Super-Kevlarweste!,,Vi prenis superan kevlaran veŝton!,¡Has pillado un supertraje de Kevlar!,¡Has recogido un supertraje de Kevlar!,Kahmaiset Superkevlar-liivit!,Super Veste en Kevlar!,Felkapsz egy Szuper Golyóálló Mellényt!,Prendi una maglia super kevlar!,スーパーケブラーベスト を奪った!,중 방탄복을 주웠다!,Je pakt een Super Kevlar vest!,Du tar en Super Kevlar vest!,Podniosłeś superkamizelkę kuloodporną!,Você pegou um Super Colete de Kevlar!,,Ai ridicat o Super Vestă din Kevlar!,Заполучен усиленный кевларовый жилет!,,Du tar tag i Super Kevlar väst!,Süper Kevlar yeleği al! +You grab a MicroKit!,GOTMICROKIT,,,,Sebral@[ao_cs] jsi mikrosadu!,Du får fat i et MicroKit!,MicroKit genommen!,,Vi prenis Kompleteton!,¡Has pillado un MicroKit!,¡Has recogido un MicroKit!,Kahmaiset Microkitin!,Microkit!,Felkapsz egy Mikorkit-et!,Prendi un MicroKit!,マイクロキット を奪った!,마이크로킷을 주웠다!,Je pakt een MicroKit!,Du tar en MicroKit!,Podniosłeś MikroZestaw!,Você pegou um MicroKit!,,Ai ridicat un MicroKit!,Заполучена мини-аптечка!,,Du tar en MicroKit!,Bir MicroKit al! +You grab a Dampener!,GOTDAMPENER,,,,Sebral@[ao_cs] jsi tlumič!,Du får fat i en Dampener!,Dämpfer genommen!,,Vi prenis Dampilon!,¡Has pillado un Amortiguador!,¡Has recogido un Amortiguador!,Kahmaiset vaimentimen!,Amortisseur!,Felkapsz egy Tompítót!,Prendi un antivento!,ダンプナー を奪った!,완충 장치를 주웠다!,Je pakt een Demper!,Du tar en Dampener!,Podniosłeś Tłumik!,Você pegou um Amortecedor!,,Ai ridicat un Amortizor!,Заполучен глушитель!,,Du tar en Dämpare!,Bir Sönümleyici al! +You need a C-Key to access this item!,PD_CKEY,,,,K přístupu potřebuješ kyberklíč!,Du skal bruge en C-nøgle for at få adgang til dette objekt!,Du brauchst einen C-Schlüssel um das hier zu bedienen.,,Vi bezonas C-ŝlosilon por aliri ĉi tiun objekton!,¡Necesitas una Llave-C para acceder a este objeto!,,Tarvitset C-avaimen saadaksesi pääsyn tähän kohteeseen!,Il vous faut une C-Clé pour accéder à cet objet!,Egy C-Kulcs szükséges a hozzáféréshez!,Hai bisogno di una chiave C per accedere a questo oggetto!,アクセスには C-key が必要だ!,C-키가 있어야 작동이 가능하다!,Je hebt een C-sleutel nodig om toegang te krijgen tot dit item!,Du trenger en C-nøkkel for å få tilgang til dette elementet!,Potrzebujesz Klucza C by uruchomić ten przedmiot.,Você precisa de uma Chave-C para acessar!,,Ai nevoie de o Cheie-C pentru a accesa acest obiect!,"Нет доступа, нужен C-образный ключ!",,Du behöver en C-nyckel för att få tillgång till detta objekt!,Bu eşyaya erişmek için bir C-Anahtarına ihtiyacın var! +You need a KeyCard to access this item!,PD_KEYCARD,,,,K přístupu potřebuješ přístupovou kartu!,Du skal bruge et Nøglekort for at få adgang til dette objekt!,Du brauchst eine Schlüsselkarte um das hier zu bedienen.,,Vi bezonas Slosilkarton por aliri ĉi tiun objekton!,¡Necesitas una Tarjeta Llave para acceder a este objeto!,,Tarvitset avainkortin saadaksesi pääsyn tähän kohteeseen!,Il vous faut une carte magnétique pour accéder à cet objet!,Egy kulcskártya szükséges a hozzáféréshez!,Hai bisogno di una chiave magnetica per accedere a questo oggetto!,アクセスには キーカード が必要だ!,키 카드가 있어야 작동이 가능하다!,U heeft een sleutelkaart nodig om toegang te krijgen tot dit item!,Du trenger et nøkkelkort for å få tilgang til dette elementet!,Potrzebujesz Karty Dostępu by uruchomić ten przedmiot!,Você precisa de uma Chave de Passe para acessar!,,Ai nevoie de un Card-Cheie pentru a accesa acest obiect!,"Нет доступа, нужен ключ-карта!",,Du behöver ett KeyCard för att komma åt det här objektet!,Bu öğeye erişmek için bir KeyCard'a ihtiyacınız var! +You need a Password to access this item!,PD_PASSWORD,,,,K přístupu potřebuješ heslo!,Du skal bruge et kodeord for at få adgang til dette objekt!,Du brauchst eine Passwort um das hier zu bedienen.,,Vi bezonas Pasvorton por aliri ĉi tiun objekton!,¡Necesitas una Contraseña para acceder a este objeto!,,Tarvitset salasanan saadaksesi pääsyn tähän kohteeseen!,Il vous faut un mot de passe pour accéder à cet objet!,Egy Jelszó szükséges a hozzáféréshez!,Hai bisogno di una parola d'ordine per accedere a questo oggetto!,アクセスには パスワード が必要だ!,암호를 입력해야 작동이 가능하다!,Je hebt een wachtwoord nodig om toegang te krijgen tot dit item!,Du trenger et passord for å få tilgang til dette elementet!,Potrzebujesz Hasła by uruchomić ten przedmiot!,Você precisa de uma Senha para acessar!,,Ai nevoie de Parolă pentru a accesa acest obiect!,"Нет доступа, нужен пароль!",,Du behöver ett lösenord för att få tillgång till detta objekt!,Bu öğeye erişmek için bir Şifreye ihtiyacınız var! +You need a Blue Z-Key to make this work,PD_BLUEZKEY,,,,Tohle bude fungovat jen s modrým Z-klíčem.,Du skal bruge en blå Z-nøgle for at få dette til at fungere!,Du brauchst einen blauen Z-Schlüssel um das hier zu bedienen.,,Vi bezonas Bluan Z-ŝlosilon por funkciigi ĉi tiun!,¡Necesitas una Llave-Z azul para hacer funcionar esto!,,Tarvitset sinisen Z-avaimen saadaksesi tämän toimimaan!,Il vous faut une Z-Clé bleue pour faire fonctionner cela.,Egy Kék Z-Kulcs szükséges a hozzáféréshez!,Hai bisogno di una chiave Z blu per accedere a questo oggetto!,アクセスには ブルーZ-key が必要だ!,청색 Z-키가 있어야 작동이 가능하다!,Je hebt een blauwe Z-sleutel nodig om dit te laten werken.,Du trenger en blå Z-nøkkel for å få dette til å fungere!,Potrzebujesz Niebieskiego Klucza Z by zadziałało!,Você precisa de uma Chave-Z azul para fazer isto funcionar!,,Ai nevoie de o Cheie-Z albastră pentru a face asta să funcționeze!,"Не работает, нужен синий Z-образный ключ!",,Du behöver en blå Z-nyckel för att få detta att fungera.,Bunu çalıştırmak için bir Mavi Z-Anahtarına ihtiyacınız var +You need a Red Z-Key to make this work!,PD_REDZKEY,,,,Tohle bude fungovat jen s červeným Z-klíčem.,Du skal bruge en rød Z-nøgle for at få dette til at fungere!,Du brauchst einen roten Z-Schlüssel um das hier zu bedienen.,,Vi bezonas Ruĝan Z-ŝlosilon por funkciigi ĉi tiun!,¡Necesitas una Llave-Z roja para hacer funcionar esto!,,Tarvitset punaisen Z-avaimen saadaksesi tämän toimimaan!,Il vous faut une Z-Clé rouge pour faire fonctionner cela.,Egy Piros Z-Kulcs szükséges a hozzáféréshez!,Hai bisogno di una chiave Z gialla per accedere a questo oggetto!,アクセスには レッドZ-key が必要だ!,적색 Z-키가 있어야 작동이 가능하다!,Je hebt een rode Z-sleutel nodig om dit te laten werken!,Du trenger en rød Z-nøkkel for å få dette til å fungere!,Potrzebujesz Czerwonego Klucza Z by zadziałało!,Você precisa de uma Chave-Z vermelha para fazer isto funcionar!,,Ai nevoie de o Cheie-Z roșie pentru a face asta să funcționeze!,"Не работает, нужен красный Z-образный ключ!",,Du behöver en röd Z-nyckel för att detta ska fungera!,Bunu çalıştırmak için Kırmızı Z-Anahtarına ihtiyacınız var! +You need a Yellow Z-Key to make this work!,PD_YELWZKEY,,,,Tohle bude fungovat jen se žlutým Z-klíčem.,Du skal bruge en gul Z-nøgle for at få dette til at fungere!,Du brauchst einen gelben Z-Schlüssel um das hier zu bedienen.,,Vi bezonas Flavan Z-ŝlosilon por funkciigi ĉi tiun!,¡Necesitas una Llave-Z amarilla para hacer funcionar esto!,,Tarvitset keltaisen Z-avaimen saadaksesi tämän toimimaan!,Il vous faut une Z-Clé jaune pour faire fonctionner cela.,Egy Sárga Z-Kulcs szükséges a hozzáféréshez!,Hai bisogno di una chiave Z rossa per accedere a questo oggetto!,アクセスには イエローZ-key が必要だ!,황색 Z-키가 있어야 작동이 가능하다!,Je hebt een gele Z-sleutel nodig om dit te laten werken!,Du trenger en gul Z-nøkkel for å få dette til å fungere!,Potrzebujesz Żółtego Klucza Z by zadziałało!,Você precisa de uma Chave-Z amarela para fazer isto funcionar!,,Ai nevoie de o Cheie-Z galbenă pentru a face asta să funcționeze!,"Не работает, нужен жёлтый Z-образный ключ!",,Du behöver en gul Z-nyckel för att detta ska fungera!,Bunu yapmak için Sarı Z-Anahtarına ihtiyacın var! "Twenty mill in gold doesn't seem worth all this aggravation, does it, hacker? Makes the pen look like a freakin' picnic! @@ -367,7 +367,13 @@ mașină în spațiul cibernetic, feliezi niște mutanți, задницы и выберись из этой чёртовой передряги! -",,"Yirmi milyon altın bu kadar +",,"Tjugo miljoner i guld verkar inte vara värt allt detta besvär, eller hur, hackare? Det får pennan att se ut som en jäkla picknick! + +Röviga biomutationer och dina medmänniskor hängde från taket som matsäckar. + +Vad i helvete är det här för GENIE? Som ingen dator du någonsin hackat! + +Det är bäst att du hittar nästa terminal, tar en tur genom c-rymden, skär några mutantrumpor och sticker härifrån!","Yirmi milyon altın bu kadar zahmete değmez, değil mi hacker? Hapishane piknik yeri gibi görünüyor! @@ -677,7 +683,15 @@ spatele...","Где все люди?! вокруг не осталось никого живого. Передай эти сведения подкомитету. И будь осторожен... -",,"Bütün insanlar nerede?! +",,"Var är alla människor?! + +Paris är en spökstad, om man inte anser att mutantbaggar är enastående medborgare. + +Du har stött på blodigt motstånd. De här insekterna kan verkligen slåss! Tur för dig att de inte är de ljusaste verandalamporna i kvarteret. + +Men ni har fått fram en del av den information som underkommittén vill ha. Och det är otäckt! + +Mänskliga neurala vätskor matar dessa insekter! Inte undra på att grannskapet börjar bli glesare. Rapportera till underkommittén. Och se upp för din rygg...","Bütün insanlar nerede?! Paris hayalet bir şehir, tabii mutant böcekleri seçkin @@ -920,7 +934,19 @@ Iar aurul? La naiba cu el, asta e din partea casei. денег. .....(продолжение следует)..... -",,"Bildiğiniz medeniyet artık yok! +",,"Civilisationen som du kände till den är nada! + +Inga vänner, ingen familj. Inga fler människor. +Inte normala människor i alla fall. + +Bara en sak kvar... GENIE! +Och om du måste gå till slutet av +universum kommer du att hitta dess muterade rumpa! +För nu är du förbannad! + +Och guldet? Det här är gratis. + +.....(fortsättning).....","Bildiğiniz medeniyet artık yok! Arkadaş yok, aile yok. Artık insan yok. @@ -1085,7 +1111,15 @@ Ești... singur.","Ты выжил! Ты... остался один. -",,"Yaşıyorsun! +",,"Du lever! + +Vad är oddsen, hackare?! +Det är en dator som är full av buggar. + +Du kan inte nå underkommittén, vilket betyder att den har blivit komprometterad. + + +Du... är ensam.","Yaşıyorsun! Bu ihtimaller nedir, hacker?! Çünkü böceklerle dolu. @@ -1096,50 +1130,52 @@ anlamına geliyor. Sen... yalnızsın." -,,,,,,,,,,,,,,,,,,,,,,,,,, -GenEmp Corp.,TXT_HACXMAP01,,,,Sídlo GenEmp,,,,Korporacio GenEmp,,,GenEmp-yhtiö,,,,GenEmpコーポ,ZONE 1: 진엠프 주식회사 본부,,,,,,Corporația GenEmp,Корпорация ГенИмп,,GenEmp Corp. -Tunnel Town,TXT_HACXMAP02,,,,Tunelové město,tunnelbyen,Tunnelstadt,,Tunelo Urbeto,Pueblo Túnel,,Tunnelikaupunki,Ville Tunnel,Kanális Község,Città del tunnel,トンネル タウン,ZONE 2: 터널 도시,Tunnelstad,Tunnelbyen,Miasto Tuneli,Cidade Túnel,,Orașul Subteran,Подземный город,,Tünel Kasabası -Lava Annex,TXT_HACXMAP03,,,,Lávová přístavba,,Lavaanbau,,Lafa Anekso,Anexo de Lava,,Laavalaajennus,Annexe de Lave,Láva Szárny,Annesso di lava,ラバ アネックス,ZONE 3: 용암 속 건물,Lava Bijlage,Lava Vedlegg,Aneks Lawy,Anexo de Lava,,Anexa de Lavă,Лавовая электростанция,,Lava Annex -Alcatraz,TXT_HACXMAP04,,,,,,,,Alkatrazo,,,,,Alkatraz,,アルカトラズ,ZONE 4: 알카트라즈,,,,,,,Алькатрас,,Alcatraz -Cyber Circus,TXT_HACXMAP05,,,,Kybercirkus,Cybercirkus,Cyberzirkus,,Cibernetika Cirko,Circo Cibernético,,Kybersirkus,,Kiber Cirkusz,Circo Cyber,サイバーサークル,ZONE 5: 사이버 서커스,,Cyber sirkus,Cyber Cyrk,Circo Cibernético,,Circ Cibernetic,Киберцирк,,Siber Sirk -Digi-Ota,TXT_HACXMAP06,,,,,,,,,,,,,,,デジ - オータ,ZONE 6: 디지-오타,,,,,,,Диджитал-Ота,,Digi-Ota -The Great Wall,TXT_HACXMAP07,,,,Velká zeď,Den store mur,Die große Mauer,,La Grandega Muro,La Gran Muralla,,Suuri muuri,La grande Muraille,A Nagy Fal,Il grande muro,ザ - グレート ウォール,ZONE 7: 만리장성,De grote muur,Den kinesiske mur,Wielka Ściana,A Grande Muralha,,Marele Zid,Великая стена,,Büyük Duvar -Garden of Delights,TXT_HACXMAP08,,,,Zahrada rozkoše,Dejlighedernes have,Lustgarten,,Ĝardeno de Ĝuoj,Jardin de las Delicias,,Nautintojen puutarha,Jardin de Délices,A Gyönyör Kertje,Giardino delle delizie,ガーデン オブ デライト,ZONE 8: 쾌락의 정원,Tuin van lekkernijen,Gledenes hage,Ogród Zachwytu,Jardim dos Prazeres,,Grădina Plăcerilor,Сад наслаждений,,Lezzet Bahçesi -Hidden Fortress,TXT_HACXMAP09,,,,Skrytá pevnost,Skjulte fæstning,Versteckte Festung,,Kaŝita Fortreso,Fortaleza Oculta,,Salainen linnoitus,Forteresse Secrète,Eltitkolt Erőd,Fortezza nascosta,ヒドゥン フォートレス,ZONE 9: 숨겨진 요새,Verborgen Vesting,Skjult festning,Ukryta Forteca,Fortaleza Oculta,,Fortăreața Ascunsă,Скрытая крепость,,Gizli Kale -Anarchist Dream,TXT_HACXMAP10,,,,Anarchistův sen,Anarkistisk drøm,Anarchistentraum,,Anarkia Sonĝo,Sueño Anarquista,,Anarkistin unelma,Rève d'Anarchiste,Anarchista Álom,Sogno anarchico,アナーキスト ドリーム,ZONE 10: 아나키스트의 꿈,Anarchistische droom,Anarkistisk drøm,Sen Anarchisty,Sonho Anarquista,,Vis Anarhist,Анархистская утопия,,Anarşist Rüya -Notus Us!,TXT_HACXMAP11,,,,,,,,,¡Notus Us!,,Pane merkille mEIdät!,,,,ワレラノ ノータス,ZONE 11: 노터스 어스!,,,,,,Nu ne vor uita!,Нас не забудут!,,Notus Us! -Gothik Gauntlet,TXT_HACXMAP12,,,,Gotický trest,,,,Gotika Spaliro,Guantelete Gótiko,,Goottinen kujanjuoksu,Gantelet Gothik,Gótikus Vesszőfutás,,ゴシック ガントレット,ZONE 12: 고딕풍 결투장,,Gothik hanske,Gotycka Rękawica,Punição Gótika,,Mănușa Gotică,Готическая перчатка,,Gothik Gauntlet -The Sewers,TXT_HACXMAP13,,,,Kanály,Kloakkerne,Die Kanäle,,La Kanaloj,Las Alcantarillas,,Viemärit,Les Egouts,A Kanális,Le fogne,ザ・サワー,ZONE 13: 하수 처리장,De Riolen,Kloakken,Ścieki,Os Esgotos,,Canale,Канализация,,Kanalizasyonlar -Trode Wars,TXT_HACXMAP14,,,,Válka elektrod,,Elektrodenkrieg,,Milito de Elektrodoj,Guerra de Electrodos,,Trodisodat,Guerre des Trodes,Trode Háborúk,Guerra degli elettrodi,トレード ウォーズ,ZONE 14: 전격의 전쟁,Trode oorlogen,Trode-krigene,Wojna Elektrod,Guerra de Eletrodos,,Război cu Electrozi,Торговые войны,,Elektrot Savaşları -Twilight of Enk's,TXT_HACXMAP15,,,,Soumrak EnKu,Enk's tusmørke,Zwielicht von EnK,,Krespusko de EnK-oj,Crepúsculo de los Enk,,EnKin illankoitto,Crépuscule des Enk's,Enk Alkonya,Crepuscolo di Enk,Enkタチ ノ トワイライト,ZONE 15: 전자황혼,Schemering van Enk's,Skumring av Enk's,Zmierzch Enk,Crepúsculo de Enk's,,Amurgul lui Enk,Сумерки EnK,,Enk'in Alacakaranlığı -Protean Cybex,TXT_HACXMAP16,,,,Proměnlivý Cybex,,Proteanischer Cybex,,Protea Cybex,Cybex Protéico,,Muuntuvainen Kybex,,,,プロテアン サイベックス,ZONE 16: 변화무쌍한 사이벡스,Proteanische Cybex,,Zmienny Cybex,Cybex Proteano,,Cybex Caleidoscopic,Многоликий Сайбэкс,,Protean Cybex -River of Blood,TXT_HACXMAP17,,,,Řeka krve,Blodets flod,Blutfluss,,Rivero de Sango,Río de Sangre,,Verivirta,Rivière de Sang,Vérfolyó,Fiume di sangue,リバー オブ ブラッド,ZONE 17: 학살의 강,Rivier van bloed,Blodets elv,Rzeka Krwi,Rio de Sangue,,Râu de Sânge,Река крови,,Kan Nehri -Bizarro,TXT_HACXMAP18,,,,Bizár,,,,,,,,,,,ビザロ,ZONE 18: 요상한 곳,,,,,,,Бизарро,,Bizarro -The War Rooms,TXT_HACXMAP19,,,,Válečné kabinety,Krigsrummene,Kriegsräume,,La Militĉambroj,Las Salas de Guerra,,Sotahuoneet,La Salle des Commandes,Háborús Terem,Le stanze della guerra,ザ・ウォー ルーム,ZONE 19: 전략 회의실,De oorlogskamers,Krigsrommene,Pokoje Wojny,As Salas de Comando,,Camerele de Control,Генеральный штаб,,Savaş Odaları -Intruder Alert!,TXT_HACXMAP20,,,,"Pozor, vetřelec!",Advarsel om ubudne gæster!,Eindringlingsalarm!,,Alarmo pri Entrudanto!,¡Alerta de Intruso!,,Murtohälytys!,"Alerte, Intrus!",Betolakodó Riadó!,Allarme intruso!,シンニュウシャ アリ!,ZONE 20: 칩입자 경보!,Inbreker alarm!,Inntrengeralarm!,Alarm Intruz!,Alerta de Intruso!,,Alertă Intrus!,Тревога! Нарушитель!,,Hırsız Alarmı! -Desiccant Room,TXT_HACXMAP31,,,,Sušící místnost,Tørremiddel-rummet,Trocknungsraum,,Ĉambro de Elsekigo,Sala del Desecante,,Kuivatesali,Salle du Desiccant,Szárító Szoba,Stanza disseccante,ダスキン ルーム,ZONE 31: 건조한 곳,Drogende kamer,Tørkerommet,Śluza Osuszająca,Sala do Dessecante,,Camera Desicanților,Сушильная комната,,Kurutucu Oda +,,,,,,,,,,,,,,,,,,,,,,,,,,, +GenEmp Corp.,TXT_HACXMAP01,,,,Sídlo GenEmp,,,,Korporacio GenEmp,,,GenEmp-yhtiö,,,,GenEmpコーポ,ZONE 1: 진엠프 주식회사 본부,,,,,,Corporația GenEmp,Корпорация «ГенИмп»,,, +Tunnel Town,TXT_HACXMAP02,,,,Tunelové město,tunnelbyen,Tunnelstadt,,Tunelo Urbeto,Pueblo Túnel,,Tunnelikaupunki,Ville Tunnel,Kanális Község,Città del tunnel,トンネル タウン,ZONE 2: 터널 도시,Tunnelstad,Tunnelbyen,Miasto Tuneli,Cidade Túnel,,Orașul Subteran,Подземный город,,Tunnelstaden,Tünel Kasabası +Lava Annex,TXT_HACXMAP03,,,,Lávová přístavba,,Lavaanbau,,Lafa Anekso,Anexo de Lava,,Laavalaajennus,Annexe de Lave,Láva Szárny,Annesso di lava,ラバ アネックス,ZONE 3: 용암 속 건물,Lava Bijlage,Lava Vedlegg,Aneks Lawy,Anexo de Lava,,Anexa de Lavă,Лавовая электростанция,,, +Alcatraz,TXT_HACXMAP04,,,,,,,,Alkatrazo,,,,,Alkatraz,,アルカトラズ,ZONE 4: 알카트라즈,,,,,,,Алькатрас,,, +Cyber Circus,TXT_HACXMAP05,,,,Kybercirkus,Cybercirkus,Cyberzirkus,,Cibernetika Cirko,Circo Cibernético,,Kybersirkus,,Kiber Cirkusz,Circo Cyber,サイバーサークル,ZONE 5: 사이버 서커스,,Cyber sirkus,Cyber Cyrk,Circo Cibernético,,Circ Cibernetic,Киберцирк,,Cybercirkus,Siber Sirk +Digi-Ota,TXT_HACXMAP06,,,,,,,,,,,,,,,デジ - オータ,ZONE 6: 디지-오타,,,,,,,Диджитал-Ота,,, +The Great Wall,TXT_HACXMAP07,,,,Velká zeď,Den store mur,Die große Mauer,,La Grandega Muro,La Gran Muralla,,Suuri muuri,La grande Muraille,A Nagy Fal,Il grande muro,ザ - グレート ウォール,ZONE 7: 만리장성,De grote muur,Den kinesiske mur,Wielka Ściana,A Grande Muralha,,Marele Zid,Великая стена,,Den stora muren,Büyük Duvar +Garden of Delights,TXT_HACXMAP08,,,,Zahrada rozkoše,Dejlighedernes have,Lustgarten,,Ĝardeno de Ĝuoj,Jardin de las Delicias,,Nautintojen puutarha,Jardin de Délices,A Gyönyör Kertje,Giardino delle delizie,ガーデン オブ デライト,ZONE 8: 쾌락의 정원,Tuin van lekkernijen,Gledenes hage,Ogród Zachwytu,Jardim dos Prazeres,,Grădina Plăcerilor,Сад наслаждений,,Lustarnas trädgård,Lezzet Bahçesi +Hidden Fortress,TXT_HACXMAP09,,,,Skrytá pevnost,Skjulte fæstning,Versteckte Festung,,Kaŝita Fortreso,Fortaleza Oculta,,Salainen linnoitus,Forteresse Secrète,Eltitkolt Erőd,Fortezza nascosta,ヒドゥン フォートレス,ZONE 9: 숨겨진 요새,Verborgen Vesting,Skjult festning,Ukryta Forteca,Fortaleza Oculta,,Fortăreața Ascunsă,Скрытая крепость,,Dolda fästningen,Gizli Kale +Anarchist Dream,TXT_HACXMAP10,,,,Anarchistův sen,Anarkistisk drøm,Anarchistentraum,,Anarkia Sonĝo,Sueño Anarquista,,Anarkistin unelma,Rève d'Anarchiste,Anarchista Álom,Sogno anarchico,アナーキスト ドリーム,ZONE 10: 아나키스트의 꿈,Anarchistische droom,Anarkistisk drøm,Sen Anarchisty,Sonho Anarquista,,Vis Anarhist,Анархистская утопия,,Anarkistisk dröm,Anarşist Rüya +Notus Us!,TXT_HACXMAP11,,,,,,,,,¡Notus Us!,,Pane merkille mEIdät!,,,,ワレラノ ノータス,ZONE 11: 노터스 어스!,,,,,,Nu ne vor uita!,Нас не забудут!,,, +Gothik Gauntlet,TXT_HACXMAP12,,,,Gotický trest,,,,Gotika Spaliro,Guantelete Gótiko,,Goottinen kujanjuoksu,Gantelet Gothik,Gótikus Vesszőfutás,,ゴシック ガントレット,ZONE 12: 고딕풍 결투장,,Gothik hanske,Gotycka Rękawica,Punição Gótika,,Mănușa Gotică,Готическая перчатка,,Gotik Utmaning, +The Sewers,TXT_HACXMAP13,,,,Kanály,Kloakkerne,Die Kanäle,,La Kanaloj,Las Alcantarillas,,Viemärit,Les Egouts,A Kanális,Le fogne,ザ・サワー,ZONE 13: 하수 처리장,De Riolen,Kloakken,Ścieki,Os Esgotos,,Canale,Канализация,,Avloppen,Kanalizasyonlar +Trode Wars,TXT_HACXMAP14,,,,Válka elektrod,,Elektrodenkrieg,,Milito de Elektrodoj,Guerra de Electrodos,,Trodisodat,Guerre des Trodes,Trode Háborúk,Guerra degli elettrodi,トレード ウォーズ,ZONE 14: 전격의 전쟁,Trode oorlogen,Trode-krigene,Wojna Elektrod,Guerra de Eletrodos,,Război cu Electrozi,Торговые войны,,Elektrodekrig,Elektrot Savaşları +Twilight of Enk's,TXT_HACXMAP15,,,,Soumrak EnKu,Enk's tusmørke,Zwielicht von EnK,,Krespusko de EnK-oj,Crepúsculo de los Enk,,EnKin illankoitto,Crépuscule des Enk's,Enk Alkonya,Crepuscolo di Enk,Enkタチ ノ トワイライト,ZONE 15: 전자황혼,Schemering van Enk's,Skumring av Enk's,Zmierzch Enk,Crepúsculo de Enk's,,Amurgul lui Enk,Сумерки EnK,,Skymning av Enks,Enk'in Alacakaranlığı +Protean Cybex,TXT_HACXMAP16,,,,Proměnlivý Cybex,,Proteanischer Cybex,,Protea Cybex,Cybex Protéico,,Muuntuvainen Kybex,,,,プロテアン サイベックス,ZONE 16: 변화무쌍한 사이벡스,Proteanische Cybex,,Zmienny Cybex,Cybex Proteano,,Cybex Caleidoscopic,Многоликий Сайбэкс,,Proteanska Cybexen, +River of Blood,TXT_HACXMAP17,,,,Řeka krve,Blodets flod,Blutfluss,,Rivero de Sango,Río de Sangre,,Verivirta,Rivière de Sang,Vérfolyó,Fiume di sangue,リバー オブ ブラッド,ZONE 17: 학살의 강,Rivier van bloed,Blodets elv,Rzeka Krwi,Rio de Sangue,,Râu de Sânge,Река крови,,Blodets flod,Kan Nehri +Bizarro,TXT_HACXMAP18,,,,Bizár,,,,,,,,,,,ビザロ,ZONE 18: 요상한 곳,,,,,,,Бизарро,,, +The War Rooms,TXT_HACXMAP19,,,,Válečné kabinety,Krigsrummene,Kriegsräume,,La Militĉambroj,Las Salas de Guerra,,Sotahuoneet,La Salle des Commandes,Háborús Terem,Le stanze della guerra,ザ・ウォー ルーム,ZONE 19: 전략 회의실,De oorlogskamers,Krigsrommene,Pokoje Wojny,As Salas de Comando,,Camerele de Control,Генеральный штаб,,Krigsrummen,Savaş Odaları +Intruder Alert!,TXT_HACXMAP20,,,,"Pozor, vetřelec!",Advarsel om ubudne gæster!,Eindringlingsalarm!,,Alarmo pri Entrudanto!,¡Alerta de Intruso!,,Murtohälytys!,"Alerte, Intrus!",Betolakodó Riadó!,Allarme intruso!,シンニュウシャ アリ!,ZONE 20: 칩입자 경보!,Inbreker alarm!,Inntrengeralarm!,Alarm Intruz!,Alerta de Intruso!,,Alertă Intrus!,Тревога! Нарушитель!,,Inkräktare!,Hırsız Alarmı! +Desiccant Room,TXT_HACXMAP31,,,,Sušící místnost,Tørremiddel-rummet,Trocknungsraum,,Ĉambro de Elsekigo,Sala del Desecante,,Kuivatesali,Salle du Desiccant,Szárító Szoba,Stanza disseccante,ダスキン ルーム,ZONE 31: 건조한 곳,Drogende kamer,Tørkerommet,Śluza Osuszająca,Sala do Dessecante,,Camera Desicanților,Сушильная комната,,Sorptionsmedel rum,Kurutucu Oda "Now Arriving At... ",STSTR_CLEV,,,,Příjezd do...,"Nu ankommer vi til... ",Angekommen bei...,,Nun Ĝisirante...,Ahora llegando a...,,Seuraavana...,On arrive maintenant à:,Következő állomás...,Arrivando a...,今到着した...,이동하는 중...,Nu we aankomen bij....,"Nå ankommer... -",Wchodzisz do...,Agora chegando em ...,,Acum Sosiți La...,Переходим на...,,"Şimdi Geliyor... +",Wchodzisz do...,Agora chegando em ...,,Acum Sosiți La...,Переходим на...,,"Nu anländer vi till... +","Şimdi Geliyor... " -...gonna fry your ass!,STSTR_CHOPPERS,"Printed when entering the idchoppers cheat, which gives the player a chainsaw",,,...ti upeče prdel!,...vil stege din røv!,...ich brate deinen Arsch!,,...fritos vian pugon!,... ¡voy a freirte el trasero!,,...kärtsää takalistosi!,...C'est l'heure de botter du cul!,...indulhat a sütögetés!,....ti friggerà il culo!,...ケツまくれ!,... 지져버리겠어!,...gaat je kont bakken!,...kommer til å steke ræva di!,...skopię ci dupę!,...vou fritar teu rabo!,,...te voi prăji!,...поджарит твою задницу!,,...kıçınızı kızartacak! -"inVuln, Str, Inviso, Rad, Allmap, or Lite-amp?",STSTR_BEHOLD,"Hacx's content here was totally useless so it got removed. However, this string has to be defined and minimally altered so that the Dehacked replacement is not being triggered.",,,"nesmrt(V), Síla, nevId, Rad, mApa nebo světLo","inVuln, Str, Inviso, Rad, Allmap, eller Lite-amp?","inVuln, Str, Inviso, Rad, Allmap, oder Lite-amp",,"inVuln, Str, Inviso, Rad, Allmap, aŭ Lite-amp?","inVuln, Str, Inviso, Rad, Allmap, o Lite-amp.",,"haavoittumattomuus (V), voima (S), näkymättömyys (I), koko kartta (A) tai valonvahvistus (L)?","in V ulnérable, S urpuissance, I nvisible, p R otection, c A rte, où L umière?","Sérthet (V), Berz (S), Láthat(i), Sugár(R), Térkép(A), vagy Fény Sisak(L)","inVuln, berSerk, Invisib, tuta anti-Rad, mAppa tutta, o amplif-Luce","V,I,S,R,A,Lのどれだ?","무적, 광전사, 투명, 보호복, 지도, 아니면 바이저?",,"inVuln, Str, Inviso, Rad, Allmap eller Lite-amp?","niezniszczalność (V), siła (S), niewidzialność (I), kombinezon (R), mapa (A) lub gogle noktowizyjne (L)","inVuln., berSerk, Invisib., anti-Rad., mApa completo ou amplificação de Luz",,"inVul, Forță ampl, Invizib, Hartă compl, sau Vedere amplificată?","Бессм. (V), берс. (S), нев. (I), кос. (R), крт. (A), виз (L).","нерањ., снага, невидљ., радиј., мапа или ноћ. визор","inVuln, Str, Inviso, Rad, Allmap veya Lite-amp?" -Let's Get Serious!,STSTR_BEHOLDX,,,,Teď je to vážné!,Lad os blive seriøse!,Es wird ernst!,,Ni Serioziĝu!,¡Vamos en Serio!,,Otetaanpa tosissaan!,Passons aux choses sérieuses!,Ennek fele sem Tréfa!,Prendiamoci sul serio!,マジになったぜ!,철들 때다!,Laten we serieus worden!,La oss bli seriøse!,Bądźmy Poważni!,Agora a Coisa Fica Séria!,,Să Devenim Serioși!,А теперь серьёзно!,,Ciddileşelim! -Cyberslicer Mode ON,STSTR_NCON,,,,Režim kybersekače ZAP,Cyberslicer tilstand TIL,Cyberschnetzelmodus AN,,Cibernetika Tranĉila Reĝimo AKTIVA,Modo Cibercorte ACTIVADO,,Kyberviipaloijatila PÄÄLLÄ,,Kibervágó Mód BE,Modalità Cyberslicer ATTIVADA,サイバースライサーモード オン,전자마귀 모드 ON,Cyberslicer-modus AAN,Cyberslicer-modus PÅ,Tryb Cybercięcia WŁĄCZONY,Cibercortador ATIVADO,,Modul Cibertăietor ACTIVAT,Режим киберрезака ВКЛЮЧЁН,,Siber dilimleyici Modu AÇIK -Cyberslicer Mode OFF,STSTR_NCOFF,,,,Režim kybersekače VYP,Cyberslicer tilstand FRA,Cyberschnetzelmodus AUS,,Cibernetika Tranĉila Reĝimo NEAKTIVA,Modo Cibercorte DESACTIVADO,,Kyberviipaloijatila POIS PÄÄLTÄ,,Kibervágó Mód KI,Modalità Cyberslicer DISATTIVADA,サイバースライサーモード オフ,전자마귀 모드 OFF,Cyberslicer-modus UIT,Cyberslicer-modus AV,Tryb Cybercięcia WYŁĄCZONY,Cibercortador DESATIVADO,,Modul Cibertăietor DEZACTIVAT,Режим киберрезака ОТКЛЮЧЁН,,Siber dilimleyici Modu KAPALI -Selection: Impossible ,STSTR_NOMUS,,,,Nemožný výběr,Forkert valg,Falsche Auswahl,,Elekto: Malebla,Selección impossible,,Valinta ei mahdollinen,Séléction Impossible!,Lehetetlen Kiválasztás,Selezione impossibile,選択: 不可能,선택 불가능,Selectie: Onmogelijk,Valg: Umulig,Niemożliwy wybór,Seleção: Impossível,,Selectare: Imposibilă,Выбор: Невозможен,НЕМОГУЋИ ИЗБОР,Seçim: İmkansız +...gonna fry your ass!,STSTR_CHOPPERS,"Printed when entering the idchoppers cheat, which gives the player a chainsaw",,,...ti upeče prdel!,...vil stege din røv!,...ich brate deinen Arsch!,,...fritos vian pugon!,... ¡voy a freirte el trasero!,,...kärtsää takalistosi!,...C'est l'heure de botter du cul!,...indulhat a sütögetés!,....ti friggerà il culo!,...ケツまくれ!,... 지져버리겠어!,...gaat je kont bakken!,...kommer til å steke ræva di!,...skopię ci dupę!,...vou fritar teu rabo!,,...te voi prăji!,...поджарит твою задницу!,,...kommer att steka ditt arsle!,...kıçınızı kızartacak! +"inVuln, Str, Inviso, Rad, Allmap, or Lite-amp?",STSTR_BEHOLD,"Hacx's content here was totally useless so it got removed. However, this string has to be defined and minimally altered so that the Dehacked replacement is not being triggered.",,,"nesmrt(V), Síla, nevId, Rad, mApa nebo světLo","inVuln, Str, Inviso, Rad, Allmap, eller Lite-amp?","inVuln, Str, Inviso, Rad, Allmap, oder Lite-amp",,"inVuln, Str, Inviso, Rad, Allmap, aŭ Lite-amp?","inVuln, Str, Inviso, Rad, Allmap, o Lite-amp.",,"haavoittumattomuus (V), voima (S), näkymättömyys (I), koko kartta (A) tai valonvahvistus (L)?","in V ulnérable, S urpuissance, I nvisible, p R otection, c A rte, où L umière?","Sérthet (V), Berz (S), Láthat(i), Sugár(R), Térkép(A), vagy Fény Sisak(L)","inVuln, berSerk, Invisib, tuta anti-Rad, mAppa tutta, o amplif-Luce","V,I,S,R,A,Lのどれだ?","무적, 광전사, 투명, 보호복, 지도, 아니면 바이저?",,"inVuln, Str, Inviso, Rad, Allmap eller Lite-amp?","niezniszczalność (V), siła (S), niewidzialność (I), kombinezon (R), mapa (A) lub gogle noktowizyjne (L)","inVuln., berSerk, Invisib., anti-Rad., mApa completo ou amplificação de Luz",,"inVul, Forță ampl, Invizib, Hartă compl, sau Vedere amplificată?","Бессм. (V), берс. (S), нев. (I), кос. (R), крт. (A), виз (L).","нерањ., снага, невидљ., радиј., мапа или ноћ. визор","inVuln, Str, Inviso, Rad, Allmap eller Lite-amp?","inVuln, Str, Inviso, Rad, Allmap veya Lite-amp?" +Let's Get Serious!,STSTR_BEHOLDX,,,,Teď je to vážné!,Lad os blive seriøse!,Es wird ernst!,,Ni Serioziĝu!,¡Vamos en Serio!,,Otetaanpa tosissaan!,Passons aux choses sérieuses!,Ennek fele sem Tréfa!,Prendiamoci sul serio!,マジになったぜ!,철들 때다!,Laten we serieus worden!,La oss bli seriøse!,Bądźmy Poważni!,Agora a Coisa Fica Séria!,,Să Devenim Serioși!,А теперь серьёзно!,,Nu blir det allvar!,Ciddileşelim! +Cyberslicer Mode ON,STSTR_NCON,,,,Režim kybersekače ZAP,Cyberslicer tilstand TIL,Cyberschnetzelmodus AN,,Cibernetika Tranĉila Reĝimo AKTIVA,Modo Cibercorte ACTIVADO,,Kyberviipaloijatila PÄÄLLÄ,,Kibervágó Mód BE,Modalità Cyberslicer ATTIVADA,サイバースライサーモード オン,전자마귀 모드 ON,Cyberslicer-modus AAN,Cyberslicer-modus PÅ,Tryb Cybercięcia WŁĄCZONY,Cibercortador ATIVADO,,Modul Cibertăietor ACTIVAT,Режим киберрезака ВКЛЮЧЁН,,Cyberslicer-läge PÅ,Siber dilimleyici Modu AÇIK +Cyberslicer Mode OFF,STSTR_NCOFF,,,,Režim kybersekače VYP,Cyberslicer tilstand FRA,Cyberschnetzelmodus AUS,,Cibernetika Tranĉila Reĝimo NEAKTIVA,Modo Cibercorte DESACTIVADO,,Kyberviipaloijatila POIS PÄÄLTÄ,,Kibervágó Mód KI,Modalità Cyberslicer DISATTIVADA,サイバースライサーモード オフ,전자마귀 모드 OFF,Cyberslicer-modus UIT,Cyberslicer-modus AV,Tryb Cybercięcia WYŁĄCZONY,Cibercortador DESATIVADO,,Modul Cibertăietor DEZACTIVAT,Режим киберрезака ОТКЛЮЧЁН,,Cyberslicer-läge AV,Siber dilimleyici Modu KAPALI +Selection: Impossible ,STSTR_NOMUS,,,,Nemožný výběr,Forkert valg,Falsche Auswahl,,Elekto: Malebla,Selección impossible,,Valinta ei mahdollinen,Séléction Impossible!,Lehetetlen Kiválasztás,Selezione impossibile,選択: 不可能,선택 불가능,Selectie: Onmogelijk,Valg: Umulig,Niemożliwy wybór,Seleção: Impossível,,Selectare: Imposibilă,Выбор: Невозможен,НЕМОГУЋИ ИЗБОР,Urval: Impossible,Seçim: İmkansız "Pump Up The Volume ",STSTR_MUS,Should probably not be translated...,,,Zesil to!,,,,,,,Nuppi kaakkoon,,Csavard Fel a Szőnyeget,,音量を上げろよ,볼륨을 올려라!,,"Pump opp volumet -",Podkręć Audio,"Som na Caixa, DJ!",,Mărește Volumul,Подкрутите громкость,,"Sesi Yükseltin +",Podkręć Audio,"Som na Caixa, DJ!",,Mărește Volumul,Подкрутите громкость,,"Pumpa upp volymen +","Sesi Yükseltin " -INIT-Twitch n'Kill Mode,STSTR_KFAADDED,,,,Inicializuji režim Twitch and Kill,INIT-Twitch n'Kill Mode,Initiiere Twitch'n Kill-Modus,,INIC-Modo de Tiku kaj Buĉu,INIT-Modo Tirar a Matar,,INIT-Nykäise ja nylje -tila,,Twitch n'Kill Mód Betöltése,Iniziare Twitch n'Kill Mode,INIT-Twitch n'Killモード,때리고 죽이는 모드 ON,,INIT-Twitch n'Kill-modus,Inicjacja Trybu Drżenia I Zabijania,Inicializando Modo Chumbo Grosso,,INIT-Modul Click-și-Elimină,ИНИЦ: режим «Дрожи и убивай»,,INIT-Twitch n'Kill Modu -"So be it, Hacker.",STSTR_FAADDED,,,,"Budiž, Hackeře.","Sådan skal det være, Hacker.","So sei es, Hacker.",,"Tiel estu, Kodrompisto.","Que así sea, Hacker.",,"Olkoon niin, hakkeri.","Qu'il en soit ainsi, hacker.","Akkor hát legyen, hekker.","Cosi' sia, Hacker.",好きにしろ、ハッカー。,"마음대로 해, 해커 양반.","Het zij zo, Hacker.","Som du vil, Hacker.","Niech tak będzie, Hakerze.","Que assim seja, Hacker.",,"Așa să fie, Hacker.","Да будет так, хакер.",,"Öyle olsun, Hacker." -Cyberpotence Mode ON,STSTR_DQDON,,,,Režim kybermoci ZAP,Cyberpotens-tilstand TIL,Cyberpotenzmodus AN,,Cibernetikpova Reĝimo AKTIVA,Modo Ciberpotencia ACTIVADO,,Kyberpotenssitila PÄÄLLÄ,,Kibererő Mód BE,Modo Cyberpotenza ATTIVADA,サイバーポテンスモード オン,전지전능 모드 ON,Cyberpotentiemodus AAN,Cyberpotensmodus PÅ,Tryb Cyberpotencji WŁĄCZONY,Ciberpotência ATIVADA,,Ciberpotență ACTIVATĂ,Режим киберулучшения ВКЛЮЧЁН,,Siber güç Modu AÇIK -Cyberpotence Mode OFF,STSTR_DQDOFF,,,,Režim kybermoci VYP,Cyberpotens-tilstand FRA,Cyberpotenzmodus AUS,,Cibernetikpova Reĝimo NEAKTIVA,Modo Ciberpotencia DESACTIVADO,,Kyberpotenssitila POIS PÄÄLTÄ,,Kibererő Mód KI,Modo Cyberpotenza DISATTIVADA,サイバーポテンスモード オフ,전지전능 모드 OFF,Cyberpotentiemodus UIT,Cyberpotensmodus AV,Tryb Cyberpotencji WYŁĄCZONY,Ciberpotência DESATIVADA,,Ciberpotență DEZACTIVATĂ,Режим киберулучшения ОТКЛЮЧЁН,,Siber güç Modu KAPALI -Tracking ON,AMSTR_FOLLOWON,,,,Sledování ZAP,Sporing TIL,Verfolgung AN,,Spurdado AKTIVA,Seguimiento ACTIVADO,,Seuranta PÄÄLLÄ,,Követés BE,Mappa scorribile DISATTIVATA,トラッキング オン,추적 모드 ON,Tracking AAN,Sporing PÅ,Namierzanie WŁĄCZONE,Seguimento ATIVADO,,Urmărire ACTIVATĂ,Сопровождение ВКЛЮЧЕНО,,İzleme AÇIK -Tracking OFF,AMSTR_FOLLOWOFF,,,,Sledování VYP,Sporing FRA,Verfolgung AUS,,Spurdado NEAKTIVA,Seguimiento DESACTIVADO,,Seuranta POIS PÄÄLTÄ,,Követés KI,Mappa scorribile ATTIVATA,トラッキング オフ,추적 모드 OFF,Tracking UIT,Sporing AV,Namierzanie WYŁĄCZONE,Seguimento DESATIVADO,,Urmărire DEZACTIVATĂ,Сопровождение ОТКЛЮЧЕНО,,İzleme KAPALI -- press Y to run away! -,DOSY,,,,- stiskni Y pro útěk! -,- Tryk på Y for at løbe væk! -,- drücke Y um wegzurennen -,,- premu Y por forkuri! -,- ¡pulsa Y para escapar! - ,,- Paina Y paetaksesi! -,-Appuie sur Y pour t'échapper!-,- nyomj Y-t a nyúlcipő felhúzáshoz -,- premere Y per scappare! -,-Y でトンズラだ!-,- 달아날려먼 Y 키를 눌러! -,- druk op Y om weg te lopen! -,- trykk Y for å stikke av! -,- wciśnij Y by uciec! -,- Aperte Y para fugir! -,- Carrega Y para fugir! -,- apasă Y pentru a fugi! -,"- нажми «Y», чтобы сбежать! -",,- Kaçmak için Y'ye basın! - +INIT-Twitch n'Kill Mode,STSTR_KFAADDED,,,,Inicializuji režim Twitch and Kill,INIT-Twitch n'Kill Mode,Initiiere Twitch'n Kill-Modus,,INIC-Modo de Tiku kaj Buĉu,INIT-Modo Tirar a Matar,,INIT-Nykäise ja nylje -tila,,Twitch n'Kill Mód Betöltése,Iniziare Twitch n'Kill Mode,INIT-Twitch n'Killモード,때리고 죽이는 모드 ON,,INIT-Twitch n'Kill-modus,Inicjacja Trybu Drżenia I Zabijania,Inicializando Modo Chumbo Grosso,,INIT-Modul Click-și-Elimină,ИНИЦ: режим «Дрожи и убивай»,,INIT-Twitch n'Kill Mode,INIT-Twitch n'Kill Modu +"So be it, Hacker.",STSTR_FAADDED,,,,"Budiž, Hackeře.","Sådan skal det være, Hacker.","So sei es, Hacker.",,"Tiel estu, Kodrompisto.","Que así sea, Hacker.",,"Olkoon niin, hakkeri.","Qu'il en soit ainsi, hacker.","Akkor hát legyen, hekker.","Cosi' sia, Hacker.",好きにしろ、ハッカー。,"마음대로 해, 해커 양반.","Het zij zo, Hacker.","Som du vil, Hacker.","Niech tak będzie, Hakerze.","Que assim seja, Hacker.",,"Așa să fie, Hacker.","Да будет так, хакер.",,"Så får det bli, Hacker.","Öyle olsun, Hacker." +Cyberpotence Mode ON,STSTR_DQDON,,,,Režim kybermoci ZAP,Cyberpotens-tilstand TIL,Cyberpotenzmodus AN,,Cibernetikpova Reĝimo AKTIVA,Modo Ciberpotencia ACTIVADO,,Kyberpotenssitila PÄÄLLÄ,,Kibererő Mód BE,Modo Cyberpotenza ATTIVADA,サイバーポテンスモード オン,전지전능 모드 ON,Cyberpotentiemodus AAN,Cyberpotensmodus PÅ,Tryb Cyberpotencji WŁĄCZONY,Ciberpotência ATIVADA,,Ciberpotență ACTIVATĂ,Режим киберулучшения ВКЛЮЧЁН,,Cyberpotens-läge PÅ,Siber güç Modu AÇIK +Cyberpotence Mode OFF,STSTR_DQDOFF,,,,Režim kybermoci VYP,Cyberpotens-tilstand FRA,Cyberpotenzmodus AUS,,Cibernetikpova Reĝimo NEAKTIVA,Modo Ciberpotencia DESACTIVADO,,Kyberpotenssitila POIS PÄÄLTÄ,,Kibererő Mód KI,Modo Cyberpotenza DISATTIVADA,サイバーポテンスモード オフ,전지전능 모드 OFF,Cyberpotentiemodus UIT,Cyberpotensmodus AV,Tryb Cyberpotencji WYŁĄCZONY,Ciberpotência DESATIVADA,,Ciberpotență DEZACTIVATĂ,Режим киберулучшения ОТКЛЮЧЁН,,Cyberpotens-läge AV,Siber güç Modu KAPALI +Tracking ON,AMSTR_FOLLOWON,,,,Sledování ZAP,Sporing TIL,Verfolgung AN,,Spurdado AKTIVA,Seguimiento ACTIVADO,,Seuranta PÄÄLLÄ,,Követés BE,Mappa scorribile DISATTIVATA,トラッキング オン,추적 모드 ON,Tracking AAN,Sporing PÅ,Namierzanie WŁĄCZONE,Seguimento ATIVADO,,Urmărire ACTIVATĂ,Сопровождение ВКЛЮЧЕНО,,Spårning PÅ,İzleme AÇIK +Tracking OFF,AMSTR_FOLLOWOFF,,,,Sledování VYP,Sporing FRA,Verfolgung AUS,,Spurdado NEAKTIVA,Seguimiento DESACTIVADO,,Seuranta POIS PÄÄLTÄ,,Követés KI,Mappa scorribile ATTIVATA,トラッキング オフ,추적 모드 OFF,Tracking UIT,Sporing AV,Namierzanie WYŁĄCZONE,Seguimento DESATIVADO,,Urmărire DEZACTIVATĂ,Сопровождение ОТКЛЮЧЕНО,,Spårning AV,İzleme KAPALI +- press Y to run away! -,DOSY,,,,- stiskni Y pro útěk! -,- Tryk på Y for at løbe væk! -,- drücke Y um wegzurennen -,,- premu Y por forkuri! -,- ¡pulsa Y para escapar! - ,,- Paina Y paetaksesi! -,-Appuie sur Y pour t'échapper!-,- nyomj Y-t a nyúlcipő felhúzáshoz -,- premere Y per scappare! -,-Y でトンズラだ!-,- 달아날려먼 Y 키를 눌러! -,- druk op Y om weg te lopen! -,- trykk Y for å stikke av! -,- wciśnij Y by uciec! -,- Aperte Y para fugir! -,- Carrega Y para fugir! -,- apasă Y pentru a fugi! -,"- нажми «Y», чтобы сбежать! -",,- Tryck på Y för att springa iväg! -,- Kaçmak için Y'ye basın! - "Are you insane or maladjusted? Well? Yes or No!",ENDGAME,,,,"Jsi blb@[adj_cs] nebo jen naveden@[adj_cs]? Tak? Jo nebo ne?","Er du sindssyg eller utilpasset? @@ -1155,7 +1191,7 @@ Nou? Ja of Nee!",Er du sinnssyk eller mistilpasset? Nå? Ja eller Nei!,"Oszalał Więc? Tak czy Nie!","Você é doido ou desregulado? Hein? Sim ou Não!",,"Ești nebun sau doar prost calibrat? Deci? Da sau Nu?","Ты дурак или родом так? -Отвечай! Да (Y) или нет (N)?",,Deli misin yoksa uyumsuz mu? Evet mi? Evet ya da hayır! +Отвечай! Да (Y) или нет (N)?",,Är du galen eller missanpassad? Nå? Ja eller nej!,Deli misin yoksa uyumsuz mu? Evet mi? Evet ya da hayır! "Are you sure? You can't handle this skill, hacker! @@ -1204,7 +1240,7 @@ Carrega Y para morrer.","Ești sigur? Nu poți face față dificultății, hacke Apasă Y ca să mori.","Ты уверен? С этим уровнем сложности ты не справишься, хакер! -Нажми «Y», чтобы умереть.",,"Emin misin? Bu yetenekle başa çıkamazsın, hacker! Ölmek için Y'ye bas." +Нажми «Y», чтобы умереть.",,"Är du säker? Du klarar inte av den här färdigheten, hackare! Tryck på Y för att dö.","Emin misin? Bu yetenekle başa çıkamazsın, hacker! Ölmek için Y'ye bas." "Quicksave over your data named '%s'? @@ -1279,7 +1315,7 @@ Apasă Y sau N.","Перезаписать файл „%s“? -Притисните Y или N.", +Притисните Y или N.",, "Do you want to quickload the data named '%s'? @@ -1352,21 +1388,21 @@ Apasă Y sau N.","Загрузить файл „%s“? -Притисните Y или N.", -Thug,CC_THUG,,,,Pobuda,Bølle,Scherge,,Perfortuloj,Matón,,Roisto,Brute,Bandatag,Tazza,チンピラ,서그,Schurk,Kjeltring,Zbir,Bandido,,Bandit,Головорез,,Eşkıya -Android,CC_ANDROID,,,,,,,,Androido,Androide,,Androidi,Androïde,,,アンドロイド,안드로이드,Androïde,,Android,Andróide,,,Андроид,,Android -ICE,CC_ICE,,,,,,,,,,,,,,,アイス,아이스,,,,,,,ЛЁД,,BUZ -Buzzer,CC_BUZZER,,,,Bzučák,,Summer,,Zumilo,Zumbador,,Surisija,,Sokkoló,Cicalino,ブザー,버저,Zoemer,Summer,Brzęczyk,,,Dronă,Летун,,Şok Uçağı -D-Man,CC_DMAN,,,,,,,,D-Vir',,,D-mies,,,,D-Man,디-맨,,,,,,,Ди-Мэн,,D-Man -Phage,CC_PHAGE,,,,Fág,,,,Faĝo,Fago,,Fagi,,Fekély,Fago,ファージ,페이지,Faag,Phage,Fag,Fago,,Mâncător,Пожиратель,,Faj -Monstruct,CC_MONSTRUCT,,,,Monstrukce,,Monstrukt,,Monstrukto,,,Keinohirviö,,Monstrum,Mostrutto,モンストラクト,몬스트럭트,Monstructie,,Monstrukt,,,,Монструкт,,Monstruct -Mecha Maniac,CC_MECH,,,,Mechamaniak,,,,Mekanika Frenezulo,Meca-Maníaco,,Mechamaanikko,Mécha-maniaque,Mecha Megszállott,Mecha Maniaco,メカマニア,메카 메니악,Mecha Maniak,,Mechaniczny Maniak,Meca-Maníaco,,Meca-Maniac,Механоман,,Meka Manyağı -Terminatrix,CC_TERMI,,,,,,,,,,,,,,,ターミネイトリクス,터미네트릭스,,,,,,,Терминатриса,,Terminatrix -Thorn Thing,CC_THORN,,,,Bodlák,Torn ting,Dornending,,Dorna Aĵo,Cosa Espinosa,,Okaolio,Truc épineux,Tövis Úrnő,,ソーンツィン,쏜 씽,Doornding,Torneting,Cierniowe Coś,Coisa Espinhosa,,Spinos,Тернистая тварь,,Dikenli Şey -Majong 7,CC_MAJONG,,,,,,,,Maĝango 7,,,Mahjong 7,,,,マージャン 7,마작 7호,,,,,,,Маджонг 7,,Majong 7 -Dan Evanger,CC_HERO,,,,,,,,Dan Evanĝer,,,,,,,ダン エブァンガー,댄 에반저,,,,,,,Дэн Эвенджер,,Dan Evanger -Please don't shoot!,SKILL_BABY,,,,"Nestřílej, prosím!",Lad være med at skyde!,Bitte schieß nicht!,,Bonvolu ne pafi!,¡Por favor no dispares!,,"Pyydän, älä ammu!","Pitié, ne tirez pas!",Kérlek ne lőj!,"Ti prego, non sparare!",撃たないでくれ!,쏘지 마세요!,"Niet schieten, alsjeblieft!","Vær så snill, ikke skyt!",Proszę nie strzelaj!,"Por favor, não atire!",,Te rog nu trage!,"Не стреляй, пожалуйста!",,Lütfen ateş etmeyin! -"Aargh, I need health!",SKILL_EASY,,,,Potřebuju zdraví!,"Aargh, jeg har brug for sundhed!",Ich brauche Gesundheit!,,"Aargh, mi bezonas sanon!","¡Aargh, necesito salud!",,"Aargh, tarvitsen terveyttä!","Aargh, des soins!","Á, kell egy kis életerő!","Aargh, ho bisogno di salute!",キメてくれ!,체력이 필요해!,"Aargh, ik heb gezondheid nodig!","Aargh, jeg trenger helse!","Ałć, potrzebuję apteczki!","Aargh, preciso de saúde!",,"Aarș, am nevoie de un medic!","А-а-ргх, аптечку!",,"Aargh, sağlığa ihtiyacım var!" -Let's rip them apart!,SKILL_NORMAL,,,,Rozsekejme je na kusy!,Lad os flå dem i stykker!,Lass uns sie zerfetzen!,,Ni disŝiru ilin!,¡Rompámoslos en pedazos!,,Revitään ne kappaleiksi!,J'en fais de la bouillie!,Tépjük csak szét őket!,Facciamoli a pezzi!,ばらまいてやれ!,갈기갈기 찢어버려!,Laten we ze uit elkaar scheuren!,La oss rive dem i filler!,Czas ich rozerwać!,Vamos despedaçá-los!,,Să-i facem zob!,Разорвём их на куски!,,Hadi onları parçalayalım! -I am immortal!,SKILL_HARD,,,,Jsem nesmrtelný!,Jeg er udødelig!,Ich bin unsterblich!,,Mi estas senmorta!,¡Soy inmortal!,,Olen kuolemation!,Je suis immortel!,Halhatatlan vagyok!,Sono immortale!,とっととくたばれ!,난 무적이다!,Ik ben onsterfelijk!,Jeg er udødelig!,Jestem nieśmiertelny!,Eu sou imortal!,,Sunt nemuritor!,Я бессмертен!,,Ben ölümsüzüm! -Insanity!,SKILL_NIGHTMARE,,,,Šílenství!,Sindssyge!,Wahnsinn!,,Frenezo!,¡Locura!,,Mielettömyys!,Folie!,Téboly!,Follia!,イカれてやがる!,코드명: 광기!,Waanzin!,Galskap!,Szaleństwo!,Insanidade!,,Demență!,Безумие!,,Delilik! \ No newline at end of file +Притисните Y или N.",, +Thug,CC_THUG,,,,Pobuda,Bølle,Scherge,,Perfortuloj,Matón,,Roisto,Brute,Bandatag,Tazza,チンピラ,서그,Schurk,Kjeltring,Zbir,Bandido,,Bandit,Головорез,,Buse,Eşkıya +Android,CC_ANDROID,,,,,,,,Androido,Androide,,Androidi,Androïde,,,アンドロイド,안드로이드,Androïde,,,Andróide,,,Андроид,,, +ICE,CC_ICE,,,,,,,,,,,,,,,アイス,아이스,,,,,,,ЛЁД,,,BUZ +Buzzer,CC_BUZZER,,,,Bzučák,,Summer,,Zumilo,Zumbador,,Surisija,,Sokkoló,Cicalino,ブザー,버저,Zoemer,Summer,Brzęczyk,,,Dronă,Летун,,Summer,Şok Uçağı +D-Man,CC_DMAN,,,,,,,,D-Vir',,,D-mies,,,,,디-맨,,,,,,,Ди-Мэн,,, +Phage,CC_PHAGE,,,,Fág,,,,Faĝo,Fago,,Fagi,,Fekély,Fago,ファージ,페이지,Faag,Phage,Fag,Fago,,Mâncător,Пожиратель,,,Faj +Monstruct,CC_MONSTRUCT,,,,Monstrukce,,Monstrukt,,Monstrukto,,,Keinohirviö,,Monstrum,Mostrutto,モンストラクト,몬스트럭트,Monstructie,,Monstrukt,,,,Монструкт,,, +Mecha Maniac,CC_MECH,,,,Mechamaniak,,,,Mekanika Frenezulo,Meca-Maníaco,,Mechamaanikko,Mécha-maniaque,Mecha Megszállott,Mecha Maniaco,メカマニア,메카 메니악,Mecha Maniak,,Mechaniczny Maniak,Meca-Maníaco,,Meca-Maniac,Механоман,,,Meka Manyağı +Terminatrix,CC_TERMI,,,,,,,,,,,,,,,ターミネイトリクス,터미네트릭스,,,,,,,Терминатриса,,, +Thorn Thing,CC_THORN,,,,Bodlák,Torn ting,Dornending,,Dorna Aĵo,Cosa Espinosa,,Okaolio,Truc épineux,Tövis Úrnő,,ソーンツィン,쏜 씽,Doornding,Torneting,Cierniowe Coś,Coisa Espinhosa,,Spinos,Тернистая тварь,,Tornen ting,Dikenli Şey +Majong 7,CC_MAJONG,,,,,,,,Maĝango 7,,,Mahjong 7,,,,マージャン 7,마작 7호,,,,,,,Маджонг 7,,, +Dan Evanger,CC_HERO,,,,,,,,Dan Evanĝer,,,,,,,ダン エブァンガー,댄 에반저,,,,,,,Дэн Эвенджер,,, +Please don't shoot!,SKILL_BABY,,,,"Nestřílej, prosím!",Lad være med at skyde!,Bitte schieß nicht!,,Bonvolu ne pafi!,¡Por favor no dispares!,,"Pyydän, älä ammu!","Pitié, ne tirez pas!",Kérlek ne lőj!,"Ti prego, non sparare!",撃たないでくれ!,쏘지 마세요!,"Niet schieten, alsjeblieft!","Vær så snill, ikke skyt!",Proszę nie strzelaj!,"Por favor, não atire!",,Te rog nu trage!,"Не стреляй, пожалуйста!",,"Snälla, skjut inte!",Lütfen ateş etmeyin! +"Aargh, I need health!",SKILL_EASY,,,,Potřebuju zdraví!,"Aargh, jeg har brug for sundhed!",Ich brauche Gesundheit!,,"Aargh, mi bezonas sanon!","¡Aargh, necesito salud!",,"Aargh, tarvitsen terveyttä!","Aargh, des soins!","Á, kell egy kis életerő!","Aargh, ho bisogno di salute!",キメてくれ!,체력이 필요해!,"Aargh, ik heb gezondheid nodig!","Aargh, jeg trenger helse!","Ałć, potrzebuję apteczki!","Aargh, preciso de saúde!",,"Aarș, am nevoie de un medic!","А-а-ргх, аптечку!",,"Aargh, jag behöver hälsa!","Aargh, sağlığa ihtiyacım var!" +Let's rip them apart!,SKILL_NORMAL,,,,Rozsekejme je na kusy!,Lad os flå dem i stykker!,Lass uns sie zerfetzen!,,Ni disŝiru ilin!,¡Rompámoslos en pedazos!,,Revitään ne kappaleiksi!,J'en fais de la bouillie!,Tépjük csak szét őket!,Facciamoli a pezzi!,ばらまいてやれ!,갈기갈기 찢어버려!,Laten we ze uit elkaar scheuren!,La oss rive dem i filler!,Czas ich rozerwać!,Vamos despedaçá-los!,,Să-i facem zob!,Разорвём их на куски!,,Låt oss slita dem i bitar!,Hadi onları parçalayalım! +I am immortal!,SKILL_HARD,,,,Jsem nesmrtelný!,Jeg er udødelig!,Ich bin unsterblich!,,Mi estas senmorta!,¡Soy inmortal!,,Olen kuolemation!,Je suis immortel!,Halhatatlan vagyok!,Sono immortale!,とっととくたばれ!,난 무적이다!,Ik ben onsterfelijk!,Jeg er udødelig!,Jestem nieśmiertelny!,Eu sou imortal!,,Sunt nemuritor!,Я бессмертен!,,Jag är odödlig!,Ben ölümsüzüm! +Insanity!,SKILL_NIGHTMARE,,,,Šílenství!,Sindssyge!,Wahnsinn!,,Frenezo!,¡Locura!,,Mielettömyys!,Folie!,Téboly!,Follia!,イカれてやがる!,코드명: 광기!,Waanzin!,Galskap!,Szaleństwo!,Insanidade!,,Demență!,Безумие!,,Galenskap!,Delilik! \ No newline at end of file diff --git a/wadsrc_extra/static/filter/harmony/language.csv b/wadsrc_extra/static/filter/harmony/language.csv index 5dea99602..aaf4a4cb5 100644 --- a/wadsrc_extra/static/filter/harmony/language.csv +++ b/wadsrc_extra/static/filter/harmony/language.csv @@ -1,4 +1,4 @@ -default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,tr +default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,sv,tr Do you really think you can handle that?\n\npress 'Y' or 'N'...,NIGHTMARE,,,,"Opravdu si myslíš, že to zvládneš? Zmáčkni Y nebo N.","Tror du virkelig, at du kan klare det? @@ -20,52 +20,53 @@ Y키, 아니면 N키를 누르시오...","Denk je echt dat je dat aankunt? Druk op 'Y' of 'N'...",Tror du virkelig at du kan håndtere det? Trykk 'Y' eller 'N'...,"Czy ty naprawdę myślisz, że temu podołasz? -Wciśnij 'Y' lub 'N'...",Você acha que dá conta?\n\nAperte Y ou N...,,Chiar crezi că poți face față?\n\napasă 'Y' sau 'N'...,"Уверены, что справитесь?\n\nНажмите «Y» или «N»...",,Gerçekten bununla başa çıkabileceğini düşünüyor musun? 'Y' veya 'N' tuşuna basın... -Spot marked,AMSTR_MARKEDSPOT,,,,Bod označen,Pletmærket,Punkt markiert,,Punkto markita,Punto marcado,,Paikka merkitty,Repère marqué.,Hely megjelölve.,Posizione segnata,スポットヲ マーク シタ,마커 표시함,Vlek gemarkeerd,Punkt markert,Miejsce zaznaczone,Posição marcada,,Loc marcat,Отметка,Означено место,İşaretli nokta -Requires the GREEN keycard,PD_BLUEO,,,,Vyžaduje ZELENOU kartu,Kræver det GRØNNE nøglekort,Benötigt die GRÜNE Schlüsselkarte,,Vi bezonas la VERDAN ŝlosilkarton,Requiere la tarjeta llave VERDE,,Tarvitsee VIHREÄN avainkortin,Carte VERTE demandée.,ZÖLD kulcskártya szükséges,Richiede la card d'accesso VERDE,グリーン キーカード ガ ヒツヨウダ,필요함: 초록색 키카드,Vereist de GROENE sleutelkaart,Krever det GRØNNE nøkkelkortet,Wymaga ZIELONEJ karty,Você precisa do cartão de passe VERDE,,Necesită cardul VERDE,Требуется ЗЕЛЁНАЯ ключ-карта,,YEŞİL anahtar kartı gerektirir -Requires the PURPLE keycard,PD_REDO,,,,Vyžaduje FIALOVOU kartu,Kræver det LILLA nøglekort,Benötigt die VIOLETTE Schlüsselkarte,,Vi bezonas la PURPURAN ŝlosilkarton,Requiere la tarjeta llave VIOLETA,,Tarvitsee VIOLETIN avainkortin,Carte VIOLETTE demandée.,LILA kulcskártya szükséges,Richiede la card d'accesso VIOLA,イエロー キーカード ガ ヒツヨウダ,필요함: 보라색 키카드,Vereist de PAARSE sleutelkaart,Krever det LILLA nøkkelkortet,Wymaga FIOLETOWEJ karty,Você precisa do cartão de passe ROXO,,Necesită cardul MOV,Требуется ФИОЛЕТОВАЯ ключ-карта,,MOR anahtar kartı gerektirir -Requires the YELLOW keycard,PD_YELLOWO,,,,Vyžaduje ŽLUTOU kartu,Kræver det GULLE nøglekort,Benötigt die GELBE Schlüsselkarte,,Vi bezonas la FLAVAN ŝlosilkarton,Requiere la tarjeta llave AMARILLA,,Tarvitsee KELTAISEN avainkortin,Carte JAUNE demandée.,SÁRGA kulcskártya szükséges,Richiede la card d'accesso GIALLA,パープル キーカード ガ ヒツヨウダ,필요함: 노란색 키카드,Vereist de GELE sleutelkaart,Krever det GULT nøkkelkortet,Wymaga ŻÓŁTEJ karty,Você precisa do cartão de passe AMARELO,,Necesită cardul GALBEN,Требуется ЖЁЛТАЯ ключ-карта,,SARI anahtar kartı gerektirir -Requires the GREEN key,PD_BLUEK,,,,Vyžaduje ZELENÝ klíč,Kræver den GRØNNE nøgle,Benötigt den GRÜNEN Schlüssel,,Vi bezonas la VERDAN ŝlosilon,Requiere la llave VERDE,,Tarvitsee VIHREÄN avaimen,Clé VERTE demandée.,ZÖLD kulcs szükséges,Richiede la chiave VERDE,グリーン キー ガ ヒツヨウダ,필요함: 초록색 열쇠,Vereist de GROENE sleutel,Krever den GRØNNE nøkkelen,Wymaga ZIELONEGO klucza,Você precisa da chave VERDE,,Necesită cheia VERDE,Требуется ЗЕЛЁНЫЙ ключ,,YEŞİL tuş gerektirir -Requires the YELLOW key,PD_YELLOWK,,,,Vyžaduje ŽLUTÝ klíč,Kræver den GULLE nøgle,Benötigt den GELBEN Schlüssel,,Vi bezonas la PURPURAN ŝlosilon,Requiere la llave AMARILLA,,Tarvitsee KELTAISEN avaimen,Clé JAUNE demandée.,SÁRGA kulcs szükséges,Richiede la chiave GIALLO,イエロー キー ガ ヒツヨウダ,필요함: 노란색 열쇠,Vereist de GEELE sleutel,Krever den GUL nøkkelen,Wymaga ŻÓŁTEGO klucza,Você precisa da chave AMARELA,,Necesită cheia GALBENĂ,Требуется ЖЁЛТЫЙ ключ,,SARI tuş gerektirir -Requires the PURPLE key,PD_REDK,,,,Vyžaduje FIALOVÝ klíč,Kræver den LILLA nøgle,Benötigt den VIOLETTEN Schlüssel,,Vi bezonas la FLAVAN ŝlosilon,Requiere la llave VIOLETA,,Tarvitsee VIOLETIN avaimen,Clé VIOLETTE demandée.,LILA kulcs szükséges,Richiede la chiave VIOLA,パープル キー ガ ヒツヨウダ,필요함: 보라색 열쇠,Vereist de PAARSE sleutel,Krever den LILLA nøkkelen,Wymaga FIOLETOWEGO klucza,Você precisa da chave ROXA,,Necesită cheia MOV,Требуется ФИОЛЕТОВЫЙ ключ,,MOR tuş gerektirir -Picked up armor.,GOTARMOR,,,Picked up armour.,Sebráno brnění.,Hentede rustning.,Panzer genommen.,,Vi trovis armaĵon.,Encuentras una armadura.,Hallaste una armadura.,Panssari poimittu.,Armure récupérée.,Vért felvéve,Raccolto un'armatura.,アーマー ニュウシュ,획득: 전투복.,Je hebt een harnas opgehaald.,Plukket opp rustning.,Zebrano pancerz.,Pegou uma armadura.,,Ai ridicat Armura.,Получена броня.,Покупили сте панцир.,Zırhı aldım. -Picked up Combat Armor.,GOTMEGA,,,Picked up Combat Armour.,Sebráno bojové brnění.,Samlet Combat Armor op.,Super-Panzer genommen.,,Vi trovis batal-armaĵon.,Encuentras una armadura de combate.,Hallaste una armadura de combate.,Taistelupanssari poimittu.,Armure de combat récupérée.,Harci vért felvéve,Raccolto Armatura da combattimento.,コンバット アーマー ニュウシュ,획득: 강화된 전투복.,Je hebt een gevechtsharnas opgehaald.,Plukket opp kamprustning.,Zebrano pancerz bojowy.,Pegou uma Armadura de Combate.,,Ai ridicat Armura de Luptă.,Получена боевая броня.,,Savaş Zırhı aldı. -Superhealth,GOTMSPHERE,,,,Superzdraví,Superhealth,Super-Gesundheit,,Supersano,Supersalud,,Superterveys,Super-Santé,Szuperéleterő,Super salute,スーパー ヘルス,사용: 체력강화 버섯.,,Superhelse,Superzdrowie,Superssaúde,,Supersănătate,Суперздоровье,,Süper Sağlık -Obtained the GREEN keycard.,GOTBLUECARD,,,,Sebrána ZELENÁ karta.,Opnået det GRØNNE nøglekort.,GRÜNE Schlüsselkarte erhalten,,Vi trovis la VERDAN ŝlosilkarton.,Encuentras la tarjeta llave VERDE.,Hallaste la tarjeta llave VERDE.,VIHREÄ avainkortti poimittu.,Carte VERTE obtenue.,Megszerezted a ZÖLD kulcskártyát.,Ottenuta la card d'accesso VERDE.,グリーン キーカード ニュウシュ,획득: 초록색 키카드.,GROENE sleutelkaart ontvangen,Fått det GRØNNE nøkkelkortet.,Zdobyto ZIELONĄ kartę.,Pegou o cartão de passe VERDE.,,Ai achiziționat cardul VERDE.,Получена ЗЕЛЁНАЯ ключ-карта.,,YEŞİL anahtar kartı elde edildi. -Obtained the YELLOW keycard.,GOTYELWCARD,,,,Sebrána ŽLUTÁ karta.,Opnået det GULLE nøglekort.,GELBE Schlüsselkarte erhalten,,Vi trovis la FLAVAN ŝlosilkarton.,Encuentras la tarjeta llave AMARILLA.,Hallaste la tarjeta llave AMARILLA.,KELTAINEN avainkortti poimittu.,Carte JAUNE obtenue.,Megszerezted a SÁRGA kulcskártyát.,Ottenuta la card d'accesso GIALLA.,イエロー キーカード ニュウシュ,획득: 노란색 키카드.,GELE sleutelkaart ontvangen,Fått det GUL nøkkelkortet.,Zdobyto ŻÓŁTĄ kartę.,Pegou o cartão de passe AMARELO.,,Ai achiziționat cardul GALBEN.,Получена ЖЁЛТАЯ ключ-карта.,,SARI anahtar kartı elde edildi. -Obtained the PURPLE keycard.,GOTREDCARD,,,,Sebrána FIALOVÁ karta.,Opnået det LILLA nøglekort.,VIOLETTE Schlüsselkarte erhalten,,Vi trovis la PURPURAN ŝlosilkarton.,Encuentras la tarjeta llave VIOLETA.,Hallaste la tarjeta llave VIOLETA.,VIOLETTI avainkortti poimittu.,Carte VIOLETTE obtenue.,Megszerezted a LILA kulcskártyát.,Ottenuta la card d'accesso VIOLA.,パープル キーカード ニュウシュ,획득: 보라색 키카드.,PAARSE sleutelkaart ontvangen,Fikk det LILLA nøkkelkortet.,Zdobyto FIOLETOWĄ kartę.,Pegou o cartão de passe ROXO.,,Ai achiziționat cardul MOV.,Получена ФИОЛЕТОВАЯ ключ-карта.,,MOR anahtar kartı elde edildi. -Obtained the GREEN key.,GOTBLUESKUL,,,,Sebrán ZELENÝ klíč.,Opnået den GRØNNE nøgle.,GRÜNEN Schlüssel erhalten,,Vi trovis la VERDAN ŝlosilon.,Encuentras la llave VERDE.,Hallaste la llave VERDE.,VIHREÄ avain poimittu.,Clé VERTE obtenue.,Megszerezted a ZÖLD kulcsot.,Ottenuta la chiave VERDE.,グリーン キー ニュウシュ,획득: 초록색 열쇠.,GROENE sleutel ontvangen,Fikk den GRØNNE nøkkelen.,Zdobyto ZIELONY klucz.,Pegou a chave VERDE.,,Ai achiziționat cheia VERDE.,Получен ЗЕЛЁНЫЙ ключ.,,YEŞİL anahtar elde edildi. -Obtained the YELLOW key.,GOTYELWSKUL,,,,Sebrán ŽLUTÝ klíč.,Opnået den GULLE nøgle.,GELBEN Schlüssel erhalten,,Vi trovis la FLAVAN ŝlosilon.,Encuentras la llave AMARILLA.,Hallaste la llave AMARILLA.,KELTAINEN avain poimittu.,Clé JAUNE obtenue.,Megszerezted a SÁRGA kulcsot.,Ottenuta la chiave GIALLA.,イエロー キー ニュウシュ,획득: 노란색 열쇠.,GELE sleutel ontvangen,Fikk den GULA nøkkelen.,Zdobyto ŻÓŁTY klucz.,Pegou a chave AMARELA.,,Ai achiziționat cheia GALBENĂ.,Получен ЖЁЛТЫЙ ключ.,,SARI anahtar elde edildi. -Obtained the PURPLE key.,GOTREDSKUL,,,,Sebrán FIALOVÝ klíč.,Opnået den LILLA nøgle.,VIOLETTEN Schlüssel erhalten,,Vi trovis la PURPURAN ŝlosilon.,Encuentras la llave VIOLETA.,Hallaste la llave VIOLETA.,VIOLETTI avain poimittu.,Clé VIOLETTE obtenue.,Megszerezted a LILA kulcsot.,Ottenuta la chiave VIOLA.,パープル キー ニュウシュ,획득: 보라색 열쇠.,PAARSE sleutel ontvangen,Fikk den LILLA nøkkelen.,Zdobyto FIOLETOWY klucz.,Pegou a chave ROXA.,,Ai achiziționat cheia MOV.,Получен ФИОЛЕТОВЫЙ ключ.,,MOR anahtar elde edildi. -Healing mushroom,GOTSTIM,,,,Léčivka,Helbredende svamp,Heilpilz,,Saniga fungo,Seta medicinal,Hongo medicinal,Lääkesieni,Champignon médicinal,Gyógyító gomba,Funghi curativi,ヒーリング マッシュルーム,사용: 체력회복 버섯.,Genezende paddenstoel,Helbredende sopp,Leczący grzyb,Cogumelo medicinal,,Ciupercă vindecătoare,Целебный гриб,,İyileştirici mantar -Acquired: medical kit.,GOTMEDIKIT,,,,Získána lékárnička.,Erhvervet: medicinsk kit.,Erhalten: Medikit,,Vi trovis sukurkeston.,Encuentras un botiquín.,Hallaste un botiquín.,Saatu: lääkintälaukku.,Acquis: Kit médical.,Megszerezve: orvosi csomag,Acquisito: kit medico.,シュトク: メディカルキット,사용: 의료 키트.,Verworven: medische kit.,Ervervet: medisinsk sett.,Zdobyto: apteczkę.,Pegou um kit médico.,,Ridicat: Kit de Prim-Ajutor.,Получена: Аптечка.,,Elde edilen: tıbbi kit. -Acquired: medical kit that you REALLY need.,GOTMEDINEED,,,,"Získána lékárnička, kterou OPRAVDU potřebuješ.","Erhvervet: medicinsk kit, som du VIRKELIG har brug for.","Erhalten: Medikit, das du WIRKLICH brauchst",,"Vi trovis sukurkeston, kiun vi VERE bezonas.",Encuentras un botiquín que REALMENTE necesitabas.,Hallaste un botiquín que REALMENTE necesitabas.,"Saatu: lääkintälaukku, jota TODELLA tarvitsit.",Acquis: Kit médical. Besoin critique.,Megszerezve: már NAGYON hiányzott orvosi csomag,Acquisito: kit medico di cui VERAMENTE avete bisogno.,シュトク: キンキュウジタイヲ スクウ メディカルキット,사용: 당신을 살려줄 의료 키트.,Verworven: medische kit die je ECHT nodig heeft.,Ervervet: medisinsk sett som du virkelig trenger.,"Zdobyto: apteczkę, której NAPRAWDĘ potrzebujesz.",Pegou um kit médico que você REALMENTE precisa.,,Ridicat: Kit de Prim-Ajutor de care CHIAR AI nevoie.,Получена: Аптечка (КРАЙНЕ необходимая).,,Elde edilen: GERÇEKTEN ihtiyacınız olan tıbbi kit. -Map,GOTMAP,,,,Mapa,Kort,Karte,,Vi trovis la mapon,Mapa,,Kartta,Carte,Térkép,Mappa,コノ クイキノ マップダ ,획득: 지도.,Kaart,Kart,Mapa,Mapa,,Hartă,Карта,,Harita -Acquired: case of bullets.,GOTCLIPBOX,,,,Získána krabice nábojů.,Erhvervet: kasse med kugler.,Erhalten: Munitionskiste,,Vi trovis skatolon da kugloj.,Encuentras una caja de balas.,Hallaste una caja de balas.,Saatu: luotilaatikko.,Acquis: Boîte de balles.,Megszerezve: doboznyi lőszer.,Acquisito: caso di proiettili.,シュトク: バレット ケース,획득: 회전포 탄약.,Verworven: geval van kogels.,Ervervet: tilfelle av kuler.,Zdobyto: pudełko naboi.,Pegou uma caixa de balas,,Achiziționat: Cutie de gloanțe.,Получен: Ящик с пулями.,,Elde edilen: mermi kovanı. -Acquired: Grenade.,GOTROCKET,,,,Ziskán granát.,Erhvervet: Granat.,Erhalten: Granate,,Vi trovis grenadon.,Encuentras una granada.,Hallaste una granada.,Saatu: kranaatti.,Acquis: Grenade.,Megszerezve: Gránát.,Acquisito: Granata.,シュトク: グレネード,획득: 세열탄.,Verworven: Granaat.,Ervervet: Granat.,Zdobyto: Granat.,Pegou uma granada.,,Achiziționat: Grenadă.,Получена: Граната.,,Elde edildi: El bombası. -Acquired: Grenades.,GOTROCKBOX,,,,Ziskány granáty.,Erhvervet: Granater.,Erhalten: Granaten,,Vi trovis grenadojn.,Encuentras unas granadas.,Hallaste unas granadas.,Saatu: kranaatteja.,Acquis: Grenades.,Megszerezve: Gránátok.,Acquisito: Granate.,シュトク: グレネード セット,획득: 세열탄 여러 개.,Verworven: Granaten.,Ervervet: Granater.,Zdobyto: Granaty.,Pegou granadas.,,Achiziționat: Grenade.,Получены: Гранаты.,,Elde edildi: El bombaları. -Acquired: box of shotgun shells.,GOTSHELLBOX,,,,Získána krabice broků.,Erhvervet: kasse med haglpatroner.,Erhalten: Schrotpatronen,,Vi trovis skatolon da kartoĉoj.,Encuentras una caja de cartuchos de escopeta.,Hallaste una caja de cartuchos de escopeta.,Saatu: laatikollinen haulikon patruunoita.,Acquis: Boîte de cartouches.,Megszerezve: doboznyi puska sörét,Acquisito: scatola di cartucce per fucile.,シュトク: シェル ボックス,획득: 산탄총 탄약.,Verworven: doos met shotgun schelpen.,Ervervet: eske med haglepatroner.,Zdobyto: pudełko loftek do strzelby.,Pegou uma caixa de cartuchos de espingarda.,,Achiziționat: Cutie de muniție pentru pușcă.,Получена: Коробка патронов для дробовика.,,Edinildi: Bir kutu av tüfeği fişeği. -Acquired: ammo backpack.,GOTBACKPACK,,,,Ziskán batoh s municí.,Erhvervet: ammunitionsrygsæk.,Erhalten: Munitionsrucksack,,Vi trovis tornistron da municioj.,Encuentras una mochila de municiones.,Hallaste una mochila de municiones.,Saatu: ammusreppu.,Acquis: Sac de munitions.,Megszerezve: lőszeres hátizsák,Acquisito: zaino munizioni.,シュトク: バックパック,획득: 탄약 가방.,Verworven: munitie rugzak.,Ervervet: ryggsekk med ammunisjon.,Zdobyto: plecak z amunicją.,Pegou uma mochila de munição.,,Achiziționat: Raniță.,Получен: Ранец для боеприпасов.,,Edinildi: Cephane çantası. -Acquired: Grenade.,GOTBFG9000,,,,Získán granát.,Erhvervet: Granat.,Erhalten: Granate,,Vi trovis grenadon.,Encuentras una granada.,Hallaste una granada.,Saatu: kranaatti.,Acquis: Grenade.,Megszerezve: Gránát.,Acquisito: Granata.,シュトク: グレネード,획득: 세열탄.,Verworven: Granaat.,Ervervet: Granat.,Zdobyto: Granat.,Pegou uma granada.,,Achiziționat: Grenadă.,Получена: Граната.,,Elde edildi: El bombası. -Acquired: Minigun.,GOTCHAINGUN,,,,Získán kulomet.,Erhvervet: Minigun.,Erhalten: Minigun,,Vi trovis maŝinpafilon.,Encuentras una ametralladora.,Hallaste una ametralladora.,Saatu: minigun.,Acquis: Minigun.,Megszerezve: Gépfegyver.,Acquisito: Minigun.,シュトク: ミニガン,획득: 회전포.,Verworven: Minigun.,Ervervet: Minigun.,Zdobyto: Minigun.,Pegou uma metralhadora giratória.,,Achiziționat: Minimitralieră.,Получен: Пулемёт.,,Elde edildi: Minigun. -Acquired: Grenade launcher.,GOTLAUNCHER,,,,Získán granátomet.,Erhvervet: Granatkaster.,Erhalten: Granatwerfer,,Vi trovis grenadĵetilon.,Encuentras un lanzagranadas.,Hallaste un lanzagranadas.,Saatu: kranaatinheitin.,Acquis: Lance-Grenades,Megszerezve: Gránátvető,Acquisito: Lanciagranate.,シュトク: グレネードランチャー,획득: 세열탄 추진기.,Verworven: Granaatwerper.,Ervervet: Granatkaster.,Zdobyto: Wyrzutnię granatów.,Pegou um lança-granadas.,,Achiziționat: Lansator de grenade.,Получен: Гранатомёт.,,Elde edildi: El bombası fırlatıcı. -Entropy thrower!,GOTPLASMA,,,,Vrhač entropie!,Entropi-lancer!,Entropiewerfer,,Entropi-ĵetilon!,¡Lanzador de entropía!,,Entropianheitin!,Acquis: Lanceur d'Entropie!,Entrópiavető!,Lancia entropia!,エントロピースロワー!,획득: 엔트로피 방사기!,Entropiewerper!,Entropikaster!,Miotacz Entropii!,Lançador de entropia!,,Aruncător entropic!,Энтропиемёт!,,Entropi fırlatıcı! -Acquired: Shotgun.,GOTSHOTGUN,,,,Získána brokovnice.,Erhvervet: Shotgun.,Erhalten: Schrotflinte,,Vi trovis kartoĉan fusilon.,Encuentras una escopeta.,Hallaste una escopeta.,Saatu: haulikko.,Acquis: Fusil à pompe.,Megszerezve: Sörétes puska,Acquisito: Fucile.,シュトク: ショットガン,획득: 산탄총.,Verworven: Shotgun.,Ervervet: Haglgevær.,Zdobyto: Strzelbę.,Pegou uma espingarda.,,Achiziționat: Pușcă.,Получен: Дробовик.,,Edinildi: Av tüfeği. -God Mode ON,STSTR_DQDON,,,,Nesmrtelnost ZAP,Gud-tilstand PÅ,Gott-Modus AN,,Dio-Reĝimo AKTIVA,Modo Dios ACTIVADO,,Kuolemattomuustila PÄÄLLÄ,Mode invulnérable ON,Isten mód BE,Modalità Dio ATTIVATA,ゴッドモード オン,무적 치트: ON,God Modus AAN,Gudsmodus PÅ,Tryb Boga WŁĄCZONY,Modo Deus LIGADO,,Modul Invincibil PORNIT,Режим Бога ВКЛЮЧЁН,,Tanrı Modu AÇIK -God Mode OFF,STSTR_DQDOFF,,,,Nesmrtelnost VYP,Gud-tilstand FRA,Gott-Modus AUS,,Dio-Reĝimo NEAKTIVA,Modo Dios DESACTIVADO,,Kuolemattomuustila POIS PÄÄLTÄ,Mode invulnérable OFF,Isten mód KI,Modalità Dio DISATTIVATA,ゴッドモード オフ,무적 치트: OFF,God Modus UIT,Gudsmodus AV,Tryb Boga WYŁĄCZONY,Modo Deus DESLIGADO,,Modul Invincibil OPRIT,Режим Бога ОТКЛЮЧЁН,,Tanrı Modu KAPALI -All weapons/ ammo/ keys,STSTR_KFAADDED,,,,Všechny zbraně/munice/klíče,Alle våben/ ammunition/ nøgler,"Alle Waffen, Munition und Schlüssel",,Ĉiuj armiloj/municioj/ŝlosiloj,Todas las armas/municiones/llaves,,Kaikki aseet/ ammukset/ avaimet,Toutes les armes/munitions/clés,Minden fegyver / lőszer / kulcs,Tutte le armi / munizioni / chiavi,スベテノ ブキ/カギ/ダンヤク,추가: 모든 무기/탄약/열쇠 치트,Alle wapens / munitie / sleutels,Alle våpen / ammunisjon / nøkler,Wszystkie bronie/amunicja/klucze,Todas as armas/munição/chaves,,Toate armele/muniție/chei,Всё оружие/боеприпасы/ключи,,Tüm silahlar/ cephane/ anahtarlar -All weapons and ammo,STSTR_FAADDED,,,,Všechny zbraně a munice,Alle våben og ammunition,Alle Waffen und Munition,,Ĉiuj armiloj kaj municioj,Todas las armas y municiones,,Kaikki aseet ja ammukset,Toutes les armes et munitions,Minden fegyver és lőszer,Tutte le armi e le munizioni,スベテノ ブキ/ダンヤク,추가: 모든 무기/탄약 치트,Alle wapens en munitie,Alle våpen og ammunisjon,Wszystkie bronie i amunicja,Todas as armas e munição completa,,Toate armele și muniție,Всё оружие и боеприпасы,,Tüm silahlar ve cephane -Abduction,TXT_HARMMAP01,,,,Únos,Bortførelse,Entführung,,Forkapto,Abducción,,Sieppaus,Enlèvement,Elrablás,Il rapimento,アブダクション,유괴,Ontvoering,Bortføring,Porwanie,Sequestro,,Răpire,Похищение,,Kaçırılma -Harm's Way,TXT_HARMMAP02,,,,Nebezpečí,,In Gefahr,,Vojo de danĝero,En peligro,,Vaara,Mise en Danger,Baj,La via del danno,ハーム'ズ ウェイ,해함의 길,,,Niebezpieczeństwo,No Caminho do Perigo,,Calea pericolului,Опасный путь,,Zarar Görebilecek Durumda -Owt Mood,TXT_HARMMAP03,,,,Špatný pocit,,Missstimmung,,Sentaĉo,Buen humor,,Nollatunnelma,Scontento,Túlterhelve,Scontento,ヤバイムード,이상한 분위기,,,Paskudny Nastrój,Mau Humor,,Fricțiune,Нестроение,,Kötü Ruh Hali -Megalapolis,TXT_HARMMAP04,,,,Megalopole,,Megalopolis,,Megtropolo,Megalópolis,,Megalopoli,Mégalopole,Megalopolisz,Megalapoli,メガラポリス,거대 도시,Megalopolis,,Megalapolis,Megalópole,,Megalopolis,Мегалаполис,,Megalapolis -The Hospital,TXT_HARMMAP05,,,,Nemocnice,Hospitalet,Das Hospital,,La malsanulejo,El hospital,,Sairaala,L'Hôpital,Kórház,L'ospedale,ホスピタル,병동,Het ziekenhuis,Sykehuset,Szpital,O Hospital,,Spitalul,Больница,,Hastane -The Weapons Factory,TXT_HARMMAP06,,,,Továrna na zbraně,Våbenfabrikken,Die Waffenfabrik,,La armil-fabriko,La fábrica de armas,,Asetehdas,L'Usine d'Armes,Fegyvergyár,La fabbrica di armi,ウェポンファクトリー,무기 공장,De Wapenfabriek,Våpenfabrikken,Fabryka Broni,A Fábrica de Armamentos,,Fabrica de Arme,Оружейный завод,,Silah Fabrikası -The Underwater Lab,TXT_HARMMAP07,,,,Podvodní laboratoř,Undervandslaboratoriet,Das Unterwasserlabor,,La subakva labotorio,El laboratorio submarino,,Vedenalainen laboratorio,Le Laboratoire Sous-marin,Vízalatti labor,Il laboratorio subacqueo,アンダーウォーターラボ,해저 연구소,Het onderwaterlaboratorium,Undervannslaboratoriet,Podwodne Laboratorium,O Laboratório Submarino,,Laboratorul Subacvatic,Подводная лаборатория,,Sualtı Laboratuvarı -Airstrip One,TXT_HARMMAP08,,,,Přistávací dráha jedna,Landingsbane et,Flugplatz Eins,,Surteriĝejo numero unu,Pista de aterrizaje uno,,Kiitorata Yksi,Piste D'Atterrisage Un,1-es kifutó,Pista Uno,エアーシップ ワン,활주로 1호,Vliegveld Een,Flystripe én,Lądowisko Numer Jeden,Base Aérea Um,,Pista Unu,Взлётная полоса №1,,Birinci Pist -The Launch Base,TXT_HARMMAP09,,,,Vzletová základna,Affyringsbasen,Die Startbasis,,La lanĉbazo,La base de despegue,,Laukaisutukikohta,La Base de Lancement,Kilövő Állomás,La base di lancio,ランチャーベース,발진기지,De lanceerbasis,Utskytningsbasen,Baza Startowa,A Base de Lançamento,,Baza de Lansare,Пусковая площадка,,Fırlatma Üssü -The Radioactive Zone,TXT_HARMMAP10,,,,Radioaktivní zóna,Den radioaktive zone,Die radioaktive Zone,,La radioaktiva zono,La zona radioactiva,,Radioaktiivinen vyöhyke,La Zone Radioactive,Radioaktív Zóna,La zona radioattiva,ラディオアクティブ ゾーン,방사능 처리소,De Radioactieve Zone,Den radioaktive sonen,Radioaktywna Strefa,A Zona Radioativa,,Zona Radioactivă,Заражённая зона,,Radyoaktif Bölge -Echidna,TXT_HARMMAP11,,,,,,,,Ekidno,,,Nokkasiili,,Hangyászsün,,エキドナ,에키드나,,,,Equidna,,,Ехидна,,Echidna +Wciśnij 'Y' lub 'N'...",Você acha que dá conta?\n\nAperte Y ou N...,,Chiar crezi că poți face față?\n\napasă 'Y' sau 'N'...,"Уверены, что справитесь?\n\nНажмите «Y» или «N»...",,"Tror du verkligen att du klarar av det? +Tryck på ""Y"" eller ""N""...",Gerçekten bununla başa çıkabileceğini düşünüyor musun? 'Y' veya 'N' tuşuna basın... +Spot marked,AMSTR_MARKEDSPOT,,,,Bod označen,Pletmærket,Punkt markiert,,Punkto markita,Punto marcado,,Paikka merkitty,Repère marqué.,Hely megjelölve.,Posizione segnata,スポットヲ マーク シタ,마커 표시함,Vlek gemarkeerd,Punkt markert,Miejsce zaznaczone,Posição marcada,,Loc marcat,Отметка,Означено место,Markerad punkt,İşaretli nokta +Requires the GREEN keycard,PD_BLUEO,,,,Vyžaduje ZELENOU kartu,Kræver det GRØNNE nøglekort,Benötigt die GRÜNE Schlüsselkarte,,Vi bezonas la VERDAN ŝlosilkarton,Requiere la tarjeta llave VERDE,,Tarvitsee VIHREÄN avainkortin,Carte VERTE demandée.,ZÖLD kulcskártya szükséges,Richiede la card d'accesso VERDE,グリーン キーカード ガ ヒツヨウダ,필요함: 초록색 키카드,Vereist de GROENE sleutelkaart,Krever det GRØNNE nøkkelkortet,Wymaga ZIELONEJ karty,Você precisa do cartão de passe VERDE,,Necesită cardul VERDE,Требуется ЗЕЛЁНАЯ ключ-карта,,Kräver det GRÖNA nyckelkortet.,YEŞİL anahtar kartı gerektirir +Requires the PURPLE keycard,PD_REDO,,,,Vyžaduje FIALOVOU kartu,Kræver det LILLA nøglekort,Benötigt die VIOLETTE Schlüsselkarte,,Vi bezonas la PURPURAN ŝlosilkarton,Requiere la tarjeta llave VIOLETA,,Tarvitsee VIOLETIN avainkortin,Carte VIOLETTE demandée.,LILA kulcskártya szükséges,Richiede la card d'accesso VIOLA,イエロー キーカード ガ ヒツヨウダ,필요함: 보라색 키카드,Vereist de PAARSE sleutelkaart,Krever det LILLA nøkkelkortet,Wymaga FIOLETOWEJ karty,Você precisa do cartão de passe ROXO,,Necesită cardul MOV,Требуется ФИОЛЕТОВАЯ ключ-карта,,Kräver det LILA nyckelkortet,MOR anahtar kartı gerektirir +Requires the YELLOW keycard,PD_YELLOWO,,,,Vyžaduje ŽLUTOU kartu,Kræver det GULLE nøglekort,Benötigt die GELBE Schlüsselkarte,,Vi bezonas la FLAVAN ŝlosilkarton,Requiere la tarjeta llave AMARILLA,,Tarvitsee KELTAISEN avainkortin,Carte JAUNE demandée.,SÁRGA kulcskártya szükséges,Richiede la card d'accesso GIALLA,パープル キーカード ガ ヒツヨウダ,필요함: 노란색 키카드,Vereist de GELE sleutelkaart,Krever det GULT nøkkelkortet,Wymaga ŻÓŁTEJ karty,Você precisa do cartão de passe AMARELO,,Necesită cardul GALBEN,Требуется ЖЁЛТАЯ ключ-карта,,Kräver det GULLA nyckelkortet,SARI anahtar kartı gerektirir +Requires the GREEN key,PD_BLUEK,,,,Vyžaduje ZELENÝ klíč,Kræver den GRØNNE nøgle,Benötigt den GRÜNEN Schlüssel,,Vi bezonas la VERDAN ŝlosilon,Requiere la llave VERDE,,Tarvitsee VIHREÄN avaimen,Clé VERTE demandée.,ZÖLD kulcs szükséges,Richiede la chiave VERDE,グリーン キー ガ ヒツヨウダ,필요함: 초록색 열쇠,Vereist de GROENE sleutel,Krever den GRØNNE nøkkelen,Wymaga ZIELONEGO klucza,Você precisa da chave VERDE,,Necesită cheia VERDE,Требуется ЗЕЛЁНЫЙ ключ,,Kräver det GRÖNA nyckeln,YEŞİL tuş gerektirir +Requires the YELLOW key,PD_YELLOWK,,,,Vyžaduje ŽLUTÝ klíč,Kræver den GULLE nøgle,Benötigt den GELBEN Schlüssel,,Vi bezonas la PURPURAN ŝlosilon,Requiere la llave AMARILLA,,Tarvitsee KELTAISEN avaimen,Clé JAUNE demandée.,SÁRGA kulcs szükséges,Richiede la chiave GIALLO,イエロー キー ガ ヒツヨウダ,필요함: 노란색 열쇠,Vereist de GEELE sleutel,Krever den GUL nøkkelen,Wymaga ŻÓŁTEGO klucza,Você precisa da chave AMARELA,,Necesită cheia GALBENĂ,Требуется ЖЁЛТЫЙ ключ,,Kräver den GULLA nyckeln,SARI tuş gerektirir +Requires the PURPLE key,PD_REDK,,,,Vyžaduje FIALOVÝ klíč,Kræver den LILLA nøgle,Benötigt den VIOLETTEN Schlüssel,,Vi bezonas la FLAVAN ŝlosilon,Requiere la llave VIOLETA,,Tarvitsee VIOLETIN avaimen,Clé VIOLETTE demandée.,LILA kulcs szükséges,Richiede la chiave VIOLA,パープル キー ガ ヒツヨウダ,필요함: 보라색 열쇠,Vereist de PAARSE sleutel,Krever den LILLA nøkkelen,Wymaga FIOLETOWEGO klucza,Você precisa da chave ROXA,,Necesită cheia MOV,Требуется ФИОЛЕТОВЫЙ ключ,,Kräver den LILA nyckeln,MOR tuş gerektirir +Picked up armor.,GOTARMOR,,,Picked up armour.,Sebráno brnění.,Hentede rustning.,Panzer genommen.,,Vi trovis armaĵon.,Encuentras una armadura.,Hallaste una armadura.,Panssari poimittu.,Armure récupérée.,Vért felvéve,Raccolto un'armatura.,アーマー ニュウシュ,획득: 전투복.,Je hebt een harnas opgehaald.,Plukket opp rustning.,Zebrano pancerz.,Pegou uma armadura.,,Ai ridicat Armura.,Получена броня.,Покупили сте панцир.,Plockade upp en rustning.,Zırhı aldım. +Picked up Combat Armor.,GOTMEGA,,,Picked up Combat Armour.,Sebráno bojové brnění.,Samlet Combat Armor op.,Super-Panzer genommen.,,Vi trovis batal-armaĵon.,Encuentras una armadura de combate.,Hallaste una armadura de combate.,Taistelupanssari poimittu.,Armure de combat récupérée.,Harci vért felvéve,Raccolto Armatura da combattimento.,コンバット アーマー ニュウシュ,획득: 강화된 전투복.,Je hebt een gevechtsharnas opgehaald.,Plukket opp kamprustning.,Zebrano pancerz bojowy.,Pegou uma Armadura de Combate.,,Ai ridicat Armura de Luptă.,Получена боевая броня.,,Plockade upp kampen rustning.,Savaş Zırhı aldı. +Superhealth,GOTMSPHERE,,,,Superzdraví,,Super-Gesundheit,,Supersano,Supersalud,,Superterveys,Super-Santé,Szuperéleterő,Super salute,スーパー ヘルス,사용: 체력강화 버섯.,,Superhelse,Superzdrowie,Superssaúde,,Supersănătate,Суперздоровье,,Supersundhet,Süper Sağlık +Obtained the GREEN keycard.,GOTBLUECARD,,,,Sebrána ZELENÁ karta.,Opnået det GRØNNE nøglekort.,GRÜNE Schlüsselkarte erhalten,,Vi trovis la VERDAN ŝlosilkarton.,Encuentras la tarjeta llave VERDE.,Hallaste la tarjeta llave VERDE.,VIHREÄ avainkortti poimittu.,Carte VERTE obtenue.,Megszerezted a ZÖLD kulcskártyát.,Ottenuta la card d'accesso VERDE.,グリーン キーカード ニュウシュ,획득: 초록색 키카드.,GROENE sleutelkaart ontvangen,Fått det GRØNNE nøkkelkortet.,Zdobyto ZIELONĄ kartę.,Pegou o cartão de passe VERDE.,,Ai achiziționat cardul VERDE.,Получена ЗЕЛЁНАЯ ключ-карта.,,Skaffade det GRÖNA nyckelkortet.,YEŞİL anahtar kartı elde edildi. +Obtained the YELLOW keycard.,GOTYELWCARD,,,,Sebrána ŽLUTÁ karta.,Opnået det GULLE nøglekort.,GELBE Schlüsselkarte erhalten,,Vi trovis la FLAVAN ŝlosilkarton.,Encuentras la tarjeta llave AMARILLA.,Hallaste la tarjeta llave AMARILLA.,KELTAINEN avainkortti poimittu.,Carte JAUNE obtenue.,Megszerezted a SÁRGA kulcskártyát.,Ottenuta la card d'accesso GIALLA.,イエロー キーカード ニュウシュ,획득: 노란색 키카드.,GELE sleutelkaart ontvangen,Fått det GUL nøkkelkortet.,Zdobyto ŻÓŁTĄ kartę.,Pegou o cartão de passe AMARELO.,,Ai achiziționat cardul GALBEN.,Получена ЖЁЛТАЯ ключ-карта.,,Skaffade det GULLA nyckelkortet.,SARI anahtar kartı elde edildi. +Obtained the PURPLE keycard.,GOTREDCARD,,,,Sebrána FIALOVÁ karta.,Opnået det LILLA nøglekort.,VIOLETTE Schlüsselkarte erhalten,,Vi trovis la PURPURAN ŝlosilkarton.,Encuentras la tarjeta llave VIOLETA.,Hallaste la tarjeta llave VIOLETA.,VIOLETTI avainkortti poimittu.,Carte VIOLETTE obtenue.,Megszerezted a LILA kulcskártyát.,Ottenuta la card d'accesso VIOLA.,パープル キーカード ニュウシュ,획득: 보라색 키카드.,PAARSE sleutelkaart ontvangen,Fikk det LILLA nøkkelkortet.,Zdobyto FIOLETOWĄ kartę.,Pegou o cartão de passe ROXO.,,Ai achiziționat cardul MOV.,Получена ФИОЛЕТОВАЯ ключ-карта.,,Skaffade det LILA nyckelkortet.,MOR anahtar kartı elde edildi. +Obtained the GREEN key.,GOTBLUESKUL,,,,Sebrán ZELENÝ klíč.,Opnået den GRØNNE nøgle.,GRÜNEN Schlüssel erhalten,,Vi trovis la VERDAN ŝlosilon.,Encuentras la llave VERDE.,Hallaste la llave VERDE.,VIHREÄ avain poimittu.,Clé VERTE obtenue.,Megszerezted a ZÖLD kulcsot.,Ottenuta la chiave VERDE.,グリーン キー ニュウシュ,획득: 초록색 열쇠.,GROENE sleutel ontvangen,Fikk den GRØNNE nøkkelen.,Zdobyto ZIELONY klucz.,Pegou a chave VERDE.,,Ai achiziționat cheia VERDE.,Получен ЗЕЛЁНЫЙ ключ.,,Skaffade den GRÖNA nyckeln.,YEŞİL anahtar elde edildi. +Obtained the YELLOW key.,GOTYELWSKUL,,,,Sebrán ŽLUTÝ klíč.,Opnået den GULLE nøgle.,GELBEN Schlüssel erhalten,,Vi trovis la FLAVAN ŝlosilon.,Encuentras la llave AMARILLA.,Hallaste la llave AMARILLA.,KELTAINEN avain poimittu.,Clé JAUNE obtenue.,Megszerezted a SÁRGA kulcsot.,Ottenuta la chiave GIALLA.,イエロー キー ニュウシュ,획득: 노란색 열쇠.,GELE sleutel ontvangen,Fikk den GULA nøkkelen.,Zdobyto ŻÓŁTY klucz.,Pegou a chave AMARELA.,,Ai achiziționat cheia GALBENĂ.,Получен ЖЁЛТЫЙ ключ.,,Skaffade den GULLA nyckeln.,SARI anahtar elde edildi. +Obtained the PURPLE key.,GOTREDSKUL,,,,Sebrán FIALOVÝ klíč.,Opnået den LILLA nøgle.,VIOLETTEN Schlüssel erhalten,,Vi trovis la PURPURAN ŝlosilon.,Encuentras la llave VIOLETA.,Hallaste la llave VIOLETA.,VIOLETTI avain poimittu.,Clé VIOLETTE obtenue.,Megszerezted a LILA kulcsot.,Ottenuta la chiave VIOLA.,パープル キー ニュウシュ,획득: 보라색 열쇠.,PAARSE sleutel ontvangen,Fikk den LILLA nøkkelen.,Zdobyto FIOLETOWY klucz.,Pegou a chave ROXA.,,Ai achiziționat cheia MOV.,Получен ФИОЛЕТОВЫЙ ключ.,,Skaffade den LILA nyckeln.,MOR anahtar elde edildi. +Healing mushroom,GOTSTIM,,,,Léčivka,Helbredende svamp,Heilpilz,,Saniga fungo,Seta medicinal,Hongo medicinal,Lääkesieni,Champignon médicinal,Gyógyító gomba,Funghi curativi,ヒーリング マッシュルーム,사용: 체력회복 버섯.,Genezende paddenstoel,Helbredende sopp,Leczący grzyb,Cogumelo medicinal,,Ciupercă vindecătoare,Целебный гриб,,Helande svamp,İyileştirici mantar +Acquired: medical kit.,GOTMEDIKIT,,,,Získána lékárnička.,Erhvervet: medicinsk kit.,Erhalten: Medikit,,Vi trovis sukurkeston.,Encuentras un botiquín.,Hallaste un botiquín.,Saatu: lääkintälaukku.,Acquis: Kit médical.,Megszerezve: orvosi csomag,Acquisito: kit medico.,シュトク: メディカルキット,사용: 의료 키트.,Verworven: medische kit.,Ervervet: medisinsk sett.,Zdobyto: apteczkę.,Pegou um kit médico.,,Ridicat: Kit de Prim-Ajutor.,Получена: Аптечка.,,Förvärvad: medicinsk utrustning.,Elde edilen: tıbbi kit. +Acquired: medical kit that you REALLY need.,GOTMEDINEED,,,,"Získána lékárnička, kterou OPRAVDU potřebuješ.","Erhvervet: medicinsk kit, som du VIRKELIG har brug for.","Erhalten: Medikit, das du WIRKLICH brauchst",,"Vi trovis sukurkeston, kiun vi VERE bezonas.",Encuentras un botiquín que REALMENTE necesitabas.,Hallaste un botiquín que REALMENTE necesitabas.,"Saatu: lääkintälaukku, jota TODELLA tarvitsit.",Acquis: Kit médical. Besoin critique.,Megszerezve: már NAGYON hiányzott orvosi csomag,Acquisito: kit medico di cui VERAMENTE avete bisogno.,シュトク: キンキュウジタイヲ スクウ メディカルキット,사용: 당신을 살려줄 의료 키트.,Verworven: medische kit die je ECHT nodig heeft.,Ervervet: medisinsk sett som du virkelig trenger.,"Zdobyto: apteczkę, której NAPRAWDĘ potrzebujesz.",Pegou um kit médico que você REALMENTE precisa.,,Ridicat: Kit de Prim-Ajutor de care CHIAR AI nevoie.,Получена: Аптечка (КРАЙНЕ необходимая).,,Förvärvad: medicinsk utrustning som du verkligen behöver.,Elde edilen: GERÇEKTEN ihtiyacınız olan tıbbi kit. +Map,GOTMAP,,,,Mapa,Kort,Karte,,Vi trovis la mapon,Mapa,,Kartta,Carte,Térkép,Mappa,コノ クイキノ マップダ ,획득: 지도.,Kaart,Kart,Mapa,Mapa,,Hartă,Карта,,Karta,Harita +Acquired: case of bullets.,GOTCLIPBOX,,,,Získána krabice nábojů.,Erhvervet: kasse med kugler.,Erhalten: Munitionskiste,,Vi trovis skatolon da kugloj.,Encuentras una caja de balas.,Hallaste una caja de balas.,Saatu: luotilaatikko.,Acquis: Boîte de balles.,Megszerezve: doboznyi lőszer.,Acquisito: caso di proiettili.,シュトク: バレット ケース,획득: 회전포 탄약.,Verworven: geval van kogels.,Ervervet: tilfelle av kuler.,Zdobyto: pudełko naboi.,Pegou uma caixa de balas,,Achiziționat: Cutie de gloanțe.,Получен: Ящик с пулями.,,Förvärvad: väska med kulor.,Elde edilen: mermi kovanı. +Acquired: Grenade.,GOTROCKET,,,,Ziskán granát.,Erhvervet: Granat.,Erhalten: Granate,,Vi trovis grenadon.,Encuentras una granada.,Hallaste una granada.,Saatu: kranaatti.,Acquis: Grenade.,Megszerezve: Gránát.,Acquisito: Granata.,シュトク: グレネード,획득: 세열탄.,Verworven: Granaat.,Ervervet: Granat.,Zdobyto: Granat.,Pegou uma granada.,,Achiziționat: Grenadă.,Получена: Граната.,,Förvärvad: Granat.,Elde edildi: El bombası. +Acquired: Grenades.,GOTROCKBOX,,,,Ziskány granáty.,Erhvervet: Granater.,Erhalten: Granaten,,Vi trovis grenadojn.,Encuentras unas granadas.,Hallaste unas granadas.,Saatu: kranaatteja.,Acquis: Grenades.,Megszerezve: Gránátok.,Acquisito: Granate.,シュトク: グレネード セット,획득: 세열탄 여러 개.,Verworven: Granaten.,Ervervet: Granater.,Zdobyto: Granaty.,Pegou granadas.,,Achiziționat: Grenade.,Получены: Гранаты.,,Förvärvad: Granater.,Elde edildi: El bombaları. +Acquired: box of shotgun shells.,GOTSHELLBOX,,,,Získána krabice broků.,Erhvervet: kasse med haglpatroner.,Erhalten: Schrotpatronen,,Vi trovis skatolon da kartoĉoj.,Encuentras una caja de cartuchos de escopeta.,Hallaste una caja de cartuchos de escopeta.,Saatu: laatikollinen haulikon patruunoita.,Acquis: Boîte de cartouches.,Megszerezve: doboznyi puska sörét,Acquisito: scatola di cartucce per fucile.,シュトク: シェル ボックス,획득: 산탄총 탄약.,Verworven: doos met shotgun schelpen.,Ervervet: eske med haglepatroner.,Zdobyto: pudełko loftek do strzelby.,Pegou uma caixa de cartuchos de espingarda.,,Achiziționat: Cutie de muniție pentru pușcă.,Получена: Коробка патронов дробовика.,,Förvärvad: låda med hagelpatroner.,Edinildi: Bir kutu av tüfeği fişeği. +Acquired: ammo backpack.,GOTBACKPACK,,,,Ziskán batoh s municí.,Erhvervet: ammunitionsrygsæk.,Erhalten: Munitionsrucksack,,Vi trovis tornistron da municioj.,Encuentras una mochila de municiones.,Hallaste una mochila de municiones.,Saatu: ammusreppu.,Acquis: Sac de munitions.,Megszerezve: lőszeres hátizsák,Acquisito: zaino munizioni.,シュトク: バックパック,획득: 탄약 가방.,Verworven: munitie rugzak.,Ervervet: ryggsekk med ammunisjon.,Zdobyto: plecak z amunicją.,Pegou uma mochila de munição.,,Achiziționat: Raniță.,Получен: Ранец боеприпасов.,,Förvärvad: Ammunitionsryggsäck.,Edinildi: Cephane çantası. +Acquired: Grenade.,GOTBFG9000,,,,Získán granát.,Erhvervet: Granat.,Erhalten: Granate,,Vi trovis grenadon.,Encuentras una granada.,Hallaste una granada.,Saatu: kranaatti.,Acquis: Grenade.,Megszerezve: Gránát.,Acquisito: Granata.,シュトク: グレネード,획득: 세열탄.,Verworven: Granaat.,Ervervet: Granat.,Zdobyto: Granat.,Pegou uma granada.,,Achiziționat: Grenadă.,Получена: Граната.,,Förvärvad: Granat.,Elde edildi: El bombası. +Acquired: Minigun.,GOTCHAINGUN,,,,Získán kulomet.,Erhvervet: Minigun.,Erhalten: Minigun,,Vi trovis maŝinpafilon.,Encuentras una ametralladora.,Hallaste una ametralladora.,Saatu: minigun.,Acquis: Minigun.,Megszerezve: Gépfegyver.,Acquisito: Minigun.,シュトク: ミニガン,획득: 회전포.,Verworven: Minigun.,Ervervet: Minigun.,Zdobyto: Minigun.,Pegou uma metralhadora giratória.,,Achiziționat: Minimitralieră.,Получен: Пулемёт.,,Förvärvad: Minigun.,Elde edildi: Minigun. +Acquired: Grenade launcher.,GOTLAUNCHER,,,,Získán granátomet.,Erhvervet: Granatkaster.,Erhalten: Granatwerfer,,Vi trovis grenadĵetilon.,Encuentras un lanzagranadas.,Hallaste un lanzagranadas.,Saatu: kranaatinheitin.,Acquis: Lance-Grenades,Megszerezve: Gránátvető,Acquisito: Lanciagranate.,シュトク: グレネードランチャー,획득: 세열탄 추진기.,Verworven: Granaatwerper.,Ervervet: Granatkaster.,Zdobyto: Wyrzutnię granatów.,Pegou um lança-granadas.,,Achiziționat: Lansator de grenade.,Получен: Гранатомёт.,,Förvärvad: Granatkastare.,Elde edildi: El bombası fırlatıcı. +Entropy thrower!,GOTPLASMA,,,,Vrhač entropie!,Entropi-lancer!,Entropiewerfer,,Entropi-ĵetilon!,¡Lanzador de entropía!,,Entropianheitin!,Acquis: Lanceur d'Entropie!,Entrópiavető!,Lancia entropia!,エントロピースロワー!,획득: 엔트로피 방사기!,Entropiewerper!,Entropikaster!,Miotacz Entropii!,Lançador de entropia!,,Aruncător entropic!,Энтропиемёт!,,,Entropi fırlatıcı! +Acquired: Shotgun.,GOTSHOTGUN,,,,Získána brokovnice.,Erhvervet: Shotgun.,Erhalten: Schrotflinte,,Vi trovis kartoĉan fusilon.,Encuentras una escopeta.,Hallaste una escopeta.,Saatu: haulikko.,Acquis: Fusil à pompe.,Megszerezve: Sörétes puska,Acquisito: Fucile.,シュトク: ショットガン,획득: 산탄총.,Verworven: Shotgun.,Ervervet: Haglgevær.,Zdobyto: Strzelbę.,Pegou uma espingarda.,,Achiziționat: Pușcă.,Получен: Дробовик.,,Förvärvad: Hagelgevär,Edinildi: Av tüfeği. +God Mode ON,STSTR_DQDON,,,,Nesmrtelnost ZAP,Gud-tilstand PÅ,Gott-Modus AN,,Dio-Reĝimo AKTIVA,Modo Dios ACTIVADO,,Kuolemattomuustila PÄÄLLÄ,Mode invulnérable ON,Isten mód BE,Modalità Dio ATTIVATA,ゴッドモード オン,무적 치트: ON,God Modus AAN,Gudsmodus PÅ,Tryb Boga WŁĄCZONY,Modo Deus LIGADO,,Modul Invincibil PORNIT,Режим Бога ВКЛЮЧЁН,,Gud läge PÅ,Tanrı Modu AÇIK +God Mode OFF,STSTR_DQDOFF,,,,Nesmrtelnost VYP,Gud-tilstand FRA,Gott-Modus AUS,,Dio-Reĝimo NEAKTIVA,Modo Dios DESACTIVADO,,Kuolemattomuustila POIS PÄÄLTÄ,Mode invulnérable OFF,Isten mód KI,Modalità Dio DISATTIVATA,ゴッドモード オフ,무적 치트: OFF,God Modus UIT,Gudsmodus AV,Tryb Boga WYŁĄCZONY,Modo Deus DESLIGADO,,Modul Invincibil OPRIT,Режим Бога ОТКЛЮЧЁН,,Gud läge AV,Tanrı Modu KAPALI +All weapons/ ammo/ keys,STSTR_KFAADDED,,,,Všechny zbraně/munice/klíče,Alle våben/ ammunition/ nøgler,"Alle Waffen, Munition und Schlüssel",,Ĉiuj armiloj/municioj/ŝlosiloj,Todas las armas/municiones/llaves,,Kaikki aseet/ ammukset/ avaimet,Toutes les armes/munitions/clés,Minden fegyver / lőszer / kulcs,Tutte le armi / munizioni / chiavi,スベテノ ブキ/カギ/ダンヤク,추가: 모든 무기/탄약/열쇠 치트,Alle wapens / munitie / sleutels,Alle våpen / ammunisjon / nøkler,Wszystkie bronie/amunicja/klucze,Todas as armas/munição/chaves,,Toate armele/muniție/chei,Всё оружие/боеприпасы/ключи,,Alla vapen/ammunition/nycklar,Tüm silahlar/ cephane/ anahtarlar +All weapons and ammo,STSTR_FAADDED,,,,Všechny zbraně a munice,Alle våben og ammunition,Alle Waffen und Munition,,Ĉiuj armiloj kaj municioj,Todas las armas y municiones,,Kaikki aseet ja ammukset,Toutes les armes et munitions,Minden fegyver és lőszer,Tutte le armi e le munizioni,スベテノ ブキ/ダンヤク,추가: 모든 무기/탄약 치트,Alle wapens en munitie,Alle våpen og ammunisjon,Wszystkie bronie i amunicja,Todas as armas e munição completa,,Toate armele și muniție,Всё оружие и боеприпасы,,Alla vapen och all ammunition,Tüm silahlar ve cephane +Abduction,TXT_HARMMAP01,,,,Únos,Bortførelse,Entführung,,Forkapto,Abducción,,Sieppaus,Enlèvement,Elrablás,Il rapimento,アブダクション,유괴,Ontvoering,Bortføring,Porwanie,Sequestro,,Răpire,Похищение,,Bortförande,Kaçırılma +Harm's Way,TXT_HARMMAP02,,,,Nebezpečí,,In Gefahr,,Vojo de danĝero,En peligro,,Vaara,Mise en Danger,Baj,La via del danno,ハーム'ズ ウェイ,해함의 길,,,Niebezpieczeństwo,No Caminho do Perigo,,Calea pericolului,Опасный путь,,Harms väg,Zarar Görebilecek Durumda +Owt Mood,TXT_HARMMAP03,,,,Špatný pocit,,Missstimmung,,Sentaĉo,Buen humor,,Nollatunnelma,Scontento,Túlterhelve,Scontento,ヤバイムード,이상한 분위기,,,Paskudny Nastrój,Mau Humor,,Fricțiune,Нестроение,,Dåligt stämning,Kötü Ruh Hali +Megalapolis,TXT_HARMMAP04,,,,Megalopole,,Megalopolis,,Megtropolo,Megalópolis,,Megalopoli,Mégalopole,Megalopolisz,Megalapoli,メガラポリス,거대 도시,Megalopolis,,Megalapolis,Megalópole,,Megalopolis,Мегалаполис,,,Megalapolis +The Hospital,TXT_HARMMAP05,,,,Nemocnice,Hospitalet,Das Hospital,,La malsanulejo,El hospital,,Sairaala,L'Hôpital,Kórház,L'ospedale,ホスピタル,병동,Het ziekenhuis,Sykehuset,Szpital,O Hospital,,Spitalul,Больница,,Sjukhuset,Hastane +The Weapons Factory,TXT_HARMMAP06,,,,Továrna na zbraně,Våbenfabrikken,Die Waffenfabrik,,La armil-fabriko,La fábrica de armas,,Asetehdas,L'Usine d'Armes,Fegyvergyár,La fabbrica di armi,ウェポンファクトリー,무기 공장,De Wapenfabriek,Våpenfabrikken,Fabryka Broni,A Fábrica de Armamentos,,Fabrica de Arme,Оружейный завод,,Vapenfabriken,Silah Fabrikası +The Underwater Lab,TXT_HARMMAP07,,,,Podvodní laboratoř,Undervandslaboratoriet,Das Unterwasserlabor,,La subakva labotorio,El laboratorio submarino,,Vedenalainen laboratorio,Le Laboratoire Sous-marin,Vízalatti labor,Il laboratorio subacqueo,アンダーウォーターラボ,해저 연구소,Het onderwaterlaboratorium,Undervannslaboratoriet,Podwodne Laboratorium,O Laboratório Submarino,,Laboratorul Subacvatic,Подводная лаборатория,,Undervattenslaboratoriet,Sualtı Laboratuvarı +Airstrip One,TXT_HARMMAP08,,,,Přistávací dráha jedna,Landingsbane et,Flugplatz Eins,,Surteriĝejo numero unu,Pista de aterrizaje uno,,Kiitorata Yksi,Piste D'Atterrisage Un,1-es kifutó,Pista Uno,エアーシップ ワン,활주로 1호,Vliegveld Een,Flystripe én,Lądowisko Numer Jeden,Base Aérea Um,,Pista Unu,Взлётная полоса №1,,Landningsbana ett,Birinci Pist +The Launch Base,TXT_HARMMAP09,,,,Vzletová základna,Affyringsbasen,Die Startbasis,,La lanĉbazo,La base de despegue,,Laukaisutukikohta,La Base de Lancement,Kilövő Állomás,La base di lancio,ランチャーベース,발진기지,De lanceerbasis,Utskytningsbasen,Baza Startowa,A Base de Lançamento,,Baza de Lansare,Пусковая площадка,,Avfyrningsbasen,Fırlatma Üssü +The Radioactive Zone,TXT_HARMMAP10,,,,Radioaktivní zóna,Den radioaktive zone,Die radioaktive Zone,,La radioaktiva zono,La zona radioactiva,,Radioaktiivinen vyöhyke,La Zone Radioactive,Radioaktív Zóna,La zona radioattiva,ラディオアクティブ ゾーン,방사능 처리소,De Radioactieve Zone,Den radioaktive sonen,Radioaktywna Strefa,A Zona Radioativa,,Zona Radioactivă,Заражённая зона,,Den radioaktiva zonen,Radyoaktif Bölge +Echidna,TXT_HARMMAP11,,,,,,,,Ekidno,,,Nokkasiili,,Hangyászsün,,エキドナ,에키드나,,,,Equidna,,,Ехидна,,,Echidna "You feel sick to your stomach... Looking in the face of the mutant queen... That thing... That used to be... @@ -368,7 +369,27 @@ Te aduni... женщиной!» = К О Н Е Ц = -",,"Kendini mutsuz hissediyorsun... +",,"Du mår illa i magen... +När du ser mutantdrottningen i ansiktet... +Den där saken... Som brukade vara... +Din vän... Amira! + +De där monstren måste ha hittat ett +sätt att mutera henne och förvandla +henne till den här avskyvärda +varelsen för att föda sin avkomma. + +-suck- + +Ta dig samman... +De kommer att få betala för att de +tvingade dig att döda din vän... + +""Helvetet har ingen vrede som +en kvinna som är föraktad!"" + + + = S L U T E T =","Kendini mutsuz hissediyorsun... Mutant kraliçenin yüzüne bakarken. O şey. O eskiden... Arkadaşın. Amira'ydı! @@ -390,12 +411,12 @@ bir kadın gibi öfke yoktur!"" = SON =" -,WI_FINISHED,This text is deliberately empty,,,,,,,,,,,,,,,,,,,,,,,, -Loading,WI_ENTERING,Yellow needs retranslation,,,Načítá se,Indlæsning,Lade,,Ŝargante,Cargando,,Ladattavana,Chargement,Betöltés,Caricamento,ローディング,불러오는 중,Laden van,Laster,Ładowanie,Carregando,,Se încarcă,Загрузка уровня,,Yükleniyor -Very Easy,SKILL_BABY,,,,Velmi snadné,Meget let,Sehr einfach,,Tre facila,Muy fácil,,Erittäin helppo,Trés facile,Nagyon könnyű,Molto facile,ベリーイージー,아주 쉬움,Zeer gemakkelijk,Veldig lett,Bardzo Łatwy,Muito fácil,,Foarte Ușor,Очень легко,,Çok Kolay -Easy,SKILL_EASY,,,,Snadný,Let,Einfach,,Facila,Fácil,,Helppo,Facile,Könnyű,Facile,イージー,쉬움,Gemakkelijk,Lett,Łatwy,Fácil,,Ușor,Легко,,Kolay -Medium,SKILL_NORMAL,,,,Střední,Middel,Mittel,,Meza,Normal,,Keskivaikea,Moyen,Normál,Medio,ミディアム,중간,Middel,Middels,Średni,Médio,,Mediu,Средне,,Orta -Hard,SKILL_HARD,,,,Obtížný,Svær,Schwer,,Malfacila,Difícil,,Vaikea,Difficile,Nehéz,Difficile,ハード,어려움,Moeilijk,Vanskelig,Trudny,Difícil,,Greu,Тяжело,,Sert -Very Hard,SKILL_NIGHTMARE,,,,Velmi obtížné,Meget svær,Sehr schwer,,Tre malfacila,Muy difícil,,Erittäin vaikea,Très difficile,Nagyon nehéz,Molto difficile,ベリーハード,아주 어려윰,Zeer moeilijk,Svært vanskelig,Bardzo Trudny,Muito difícil,,Foarte Greu,Очень тяжело,,Çok Zor -Thanks for playing,HARMQUITMSG,,,,Díky za hraní,Tak for at spille,Danke fürs Spielen,,Dankon pro ludado,Gracias por jugar,,Kiitos pelaamisesta,Merci d'avoir joué,"Köszönjük, hogy játszottál!",Grazie per aver giocato,プレイ シテクレテ カンシャスル,플레이 해주셔서 감사드립니다,Bedankt voor het spelen,Takk for at du spilte,Dziękuję za grę,Obrigado por jogar,,Mulțumim că ai jucat,"Спасибо, что сыграли в Harmony",,Oynadığınız için teşekkürler -Harmony,TXT_D2E1,,,,,,,,Harmonio,,,Harmonia,,Harmónia,,,,,,Harmonia,Harmony,,,,, \ No newline at end of file +,WI_FINISHED,This text is deliberately empty,,,,,,,,,,,,,,,,,,,,,,,,, +Loading,WI_ENTERING,Yellow needs retranslation,,,Načítá se,Indlæsning,Lade,,Ŝargante,Cargando,,Ladattavana,Chargement,Betöltés,Caricamento,ローディング,불러오는 중,Laden van,Laster,Ładowanie,Carregando,,Se încarcă,Загрузка уровня,,Laddar,Yükleniyor +Very Easy,SKILL_BABY,,,,Velmi snadné,Meget let,Sehr einfach,,Tre facila,Muy fácil,,Erittäin helppo,Trés facile,Nagyon könnyű,Molto facile,ベリーイージー,아주 쉬움,Zeer gemakkelijk,Veldig lett,Bardzo Łatwy,Muito fácil,,Foarte Ușor,Очень легко,,Mycket lätt,Çok Kolay +Easy,SKILL_EASY,,,,Snadný,Let,Einfach,,Facila,Fácil,,Helppo,Facile,Könnyű,Facile,イージー,쉬움,Gemakkelijk,Lett,Łatwy,Fácil,,Ușor,Легко,,Lätt,Kolay +Medium,SKILL_NORMAL,,,,Střední,Middel,Mittel,,Meza,Normal,,Keskivaikea,Moyen,Normál,Medio,ミディアム,중간,Middel,Middels,Średni,Médio,,Mediu,Средне,,Medel,Orta +Hard,SKILL_HARD,,,,Obtížný,Svær,Schwer,,Malfacila,Difícil,,Vaikea,Difficile,Nehéz,Difficile,ハード,어려움,Moeilijk,Vanskelig,Trudny,Difícil,,Greu,Тяжело,,Svårt,Sert +Very Hard,SKILL_NIGHTMARE,,,,Velmi obtížné,Meget svær,Sehr schwer,,Tre malfacila,Muy difícil,,Erittäin vaikea,Très difficile,Nagyon nehéz,Molto difficile,ベリーハード,아주 어려윰,Zeer moeilijk,Svært vanskelig,Bardzo Trudny,Muito difícil,,Foarte Greu,Очень тяжело,,Mycket svårt,Çok Zor +Thanks for playing,HARMQUITMSG,,,,Díky za hraní,Tak for at spille,Danke fürs Spielen,,Dankon pro ludado,Gracias por jugar,,Kiitos pelaamisesta,Merci d'avoir joué,"Köszönjük, hogy játszottál!",Grazie per aver giocato,プレイ シテクレテ カンシャスル,플레이 해주셔서 감사드립니다,Bedankt voor het spelen,Takk for at du spilte,Dziękuję za grę,Obrigado por jogar,,Mulțumim că ai jucat,"Спасибо, что сыграли в Harmony",,Tack för att du spelar,Oynadığınız için teşekkürler +Harmony,TXT_D2E1,,,,,,,,Harmonio,,,Harmonia,,Harmónia,,,,,,Harmonia,,,,,,, \ No newline at end of file diff --git a/wadsrc_extra/static/language.csv b/wadsrc_extra/static/language.csv index 2def38e36..66ccf1086 100644 --- a/wadsrc_extra/static/language.csv +++ b/wadsrc_extra/static/language.csv @@ -1,316 +1,316 @@ -default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,tr -,,Doom Episode names,,,,,,,,,,,,,,,,,,,"As long as there is no other Portuguese variant, the language ID should be two letters only!",,,,, -Knee-Deep in the Dead,TXT_D1E1,,,,Po kolena v mrtvých,Knæet dybt i de døde,Knietief im Tod,Βουτηγμένος στους Νεκρούς μέχρι τα γόνατα,Ĝisgenue en la Mortintoj,Hasta las Rodillas entre Muertos,,Polvia myöten vainajissa,Plongé dans la Mort,Térdig halálban,Nella morte fino al collo,膝元迫る亡者,끝없이 밀려오는 죽음,Knie-diep in de Doden,Knedyp i de døde,Po kolana w trupach,Corpos até os Joelhos,,Îngropat printre Cadavre,По колено в трупах,До колена у лешевима,Ölüme Diz Boyu -The Shores of Hell,TXT_D1E2,,,,Břehy pekla,Helvedes kyster,Die Ufer der Hölle,Οι Ακτές της Κόλασης,La Bordoj de Infero,Las Orillas del Infierno,,Hornan rannat,Les Portes de l'Enfer,A pokol tornáca,Le rive dell'Inferno,地獄の瀬戸際,지옥의 해변,De Oevers van de Hel,Helvetes kyster,Przedsionek Piekieł,As Margens do Abismo,,Țărmurile Iadului,Прибрежье преисподней,Обале пакла,Cehennem Kıyıları -Inferno,TXT_D1E3,,,,,,,Πυρ το Εξώτερον,,,,,,Alvilág,,インフェルノ,연옥,,,Piekło,,,Infernul,Инферно,Инферно,İnferno +default,Identifier,Remarks,Filter,eng enc ena enz eni ens enj enb enl ent enw,cs,da,de,el,eo,es,esm esn esg esc esa esd esv eso esr ess esf esl esy esz esb ese esh esi esu,fi,fr,hu,it,jp,ko,nl,no nb,pl,pt,ptg,ro,ru,sr,sv,tr +,,Doom Episode names,,,,,,,,,,,,,,,,,,,"As long as there is no other Portuguese variant, the language ID should be two letters only!",,,,,, +Knee-Deep in the Dead,TXT_D1E1,,,,Po kolena v mrtvých,Knæet dybt i de døde,Knietief im Tod,Βουτηγμένος στους Νεκρούς μέχρι τα γόνατα,Ĝisgenue en la Mortintoj,Hasta las Rodillas entre Muertos,,Polvia myöten vainajissa,Plongé dans la Mort,Térdig halálban,Nella morte fino al collo,膝元迫る亡者,끝없이 밀려오는 죽음,Knie-diep in de Doden,Knedyp i de døde,Po kolana w trupach,Corpos até os Joelhos,,Îngropat printre Cadavre,По колено в трупах,До колена у лешевима,Knä-djupt i de döda,Ölüme Diz Boyu +The Shores of Hell,TXT_D1E2,,,,Břehy pekla,Helvedes kyster,Die Ufer der Hölle,Οι Ακτές της Κόλασης,La Bordoj de Infero,Las Orillas del Infierno,,Hornan rannat,Les Portes de l'Enfer,A pokol tornáca,Le rive dell'Inferno,地獄の瀬戸際,지옥의 해변,De Oevers van de Hel,Helvetes kyster,Przedsionek Piekieł,As Margens do Abismo,,Țărmurile Iadului,Прибрежье преисподней,Обале пакла,Helvetets stränder,Cehennem Kıyıları +Inferno,TXT_D1E3,,,,,,,Πυρ το Εξώτερον,,,,,,Alvilág,,インフェルノ,연옥,,,Piekło,,,Infernul,Инферно,Инферно,,İnferno Thy Flesh Consumed,TXT_D1E4,"The episode and levels' names in E4 are taken from the Bible. -Proverbs 5:11",,,Tvé tělo pozřeto,Dit kød er fortæret,Dein Leib verzehrt,Η Σάρκα σου θα Καταναλωθεί,Via Karno Konsumita,Tu Carne Consumida,,Lihasi kulutettu,Votre Chair Consumée,Megemésztetik a te húsod,La tua Carne Consumata,滅びし汝の身,쇠패해진 그대의 육신,Uw Vlees Geconsumeerd,Ditt kjøtt fortæres,Ciało Twe Zwiotczeje,No Consumir-se da Tua Carne,,Carnea ta Fără de Vlagă,Твоя плоть поглощена,Твоје месо строшено,Etin Tükendi -Hell On Earth,TXT_D2E1,,,,Peklo na zemi,Helvede på jorden,Hölle auf Erden,Αρμαγεδδών,Infero Sur La Tero,Infierno en la Tierra,,Helvetti maan päällä,Enfer sur Terre,Földi pokol,Inferno sulla Terra,第三惑星:地獄,지상에 강림한 지옥,Hel op Aarde,Helvete på jorden,Piekło na Ziemi,Inferno na Terra,,Iadul pe Pământ,Ад на Земле,Пакао на Земљи,Yeryüzündeki Cehennem -No Rest for the Living,TXT_D2E2,"References ""No rest for the wicked"" in Isaiah 48:22",,,Nemajíť živí pokoje,Ingen hvile for de levende,Keine Ruhe für die Lebenden,Καμία Ανάπαυση για τους Ζωντανούς,Nenia Ripozo por la Vivantoj,No hay Descanso para los Vivos,,Ei lepoa eläville,Pas de repos pour les vivants,Nincs nyugodalom az élőnek,Nessun Riposo per i Vivi,休息なき生計,산 자에게 휴식은 없다,Geen Rust voor de Levenden,Ingen hvile for de levende,Brak Wytchnienia Dla Żywych,Não Há Descanso Para os Vivos,,Cei vii Fără de Odihnă,Не будет покоя живым,Нема одмора живима,Yaşayanlara Huzur Yok -The Plutonia Experiment,TXT_PLUT_EP,,,,Experiment Plutonia,Plutonia-eksperimentet,Das Plutonia Experiment,Το Πείραμα Πλουτώνια,La Eksperimento de Plutonia,El Experimento Plutonia,,Plutoniakokemus,L'expérience Plutonia,A Plutonia-kísérlet,L'Esperimento di Plutonia,プルトニア記,플루토니아 익스페리먼트,Het Plutonia Experiment,Plutonia-eksperimentet,Eksperyment Plutonia,O Experimento Plutonia,A Experiência Plutonia,Experimentul Plutonia,Эксперимент «Плутония»,Експеримент Плутонија,Plutonia Deneyi -TNT: Evilution,TXT_TNT_EP,,,,TNT: Zlovoluce,,,ΤΝΤ: Κακοξέλιξη,TNT: Mavalucio,TNT: Diabolución,,TNT: Paholuutio,,,TNT: Malvoluzione,TNT:邪神化,TNT: 이블루션,Tnt: Evilutie,,TNT: Ewolucja Zła,TNT: Malvolução,,TNT: Diavoluția,TNT: Дьяволюция,TNT: Ђаволуција,TNT: Evilution -Chex Quest,TXT_CHEX_EP,,,,Mise Chex,,,Η Περιπέτεια του Chex,Aventuro de Chex,,,Chex-seikkailu,,,,チェックス クエスト,첵스 퀘스트,,,Misja Chex,,,,,Чекс Квест,Chex Quest -,,Level names,,,,,,,,,,,,,,,,,,,,,,,, -,,Doom 1,,,,,,,,,,,,,,,,,,,,,,,, -E1M1: Hangar,HUSTR_E1M1,,,,E1M1: Hangár,,,E1Χ1: Υπόστεγο,E1M1: Hangaro,,,E1M1: Lentoalushalli,,E1M1: Hangár,,E1M1: 格納庫,E1M1: 격납고,,,E1M1: Hangar,E1M1: Hangar,,E1M1: Hangar,E1M1: Ангар,E1M1: Хангар,E1M1: Hangar -E1M2: Nuclear Plant,HUSTR_E1M2,,,,E1M2: Jaderná elektrárna,E1M2: Atomkraftværk,E1M2: Kernkraftwerk,E1Χ2: Πυρηνικό Εργοστάσιο,E1M2: Nuklea Centralo,E1M2: Planta Nuclear,,E1M2: Ydinvoimala,E1M2: Centrale Nucléaire,E1M2: Atomerőmű,E1M2: Centrale Nucleare,E1M2: 原子力発電所,E1M2: 원자력 발전소,E1M2: Kerncentrale,E1M2: Kjernekraftverk,E1M2: Elektrownia Jądrowa,E1M2: Usina Nuclear,E1M2: Central Nuclear,E1M2: Uzina Nucleară,E1M2: Атомная электростанция,E1M2: Нуклеарна електрана,E1M2: Nükleer Santral -E1M3: Toxin Refinery,HUSTR_E1M3,,,,E1M3: Chemická rafinerie,E1M3: Giftraffinaderi,E1M3: Giftraffinerie,E1Χ3: Διυλιστήριο Τοξινών,E1M3: Toksin-Rafinejo,E1M3: Refinería de Toxinas,,E1M3: Myrkkyjalostamo,E1M3: Raffinerie de Toxines,E1M3: Méregfinomító,E1M3: Raffineria delle Tossine,E1M3: 毒素精錬所 ,E1M3: 폐기물 정제소,E1M3: Giftstofraffinaderij,E1M3: Giftraffineri,E1M3: Rafineria Toksyn,E1M3: Refinaria de Toxinas,,E1M3: Rafinăria de Toxine,E1M3: Очистной завод,E1M3: Рафинерија за токсине,E1M3: Toksin Rafinerisi -E1M4: Command Control,HUSTR_E1M4,,,,E1M4: Řídící velín,E1M4: Kommandokontrol,E1M4: Betriebssteuerung,E1Χ4: Κέντρο Ελέγχου,E1M4: Kontrolcentro,E1M4: Control de Mando,,E1M4: Komentohallinta,E1M4: Centre de Contrôle,E1M4: Parancsnoki vezérlő,E1M4: Centrale di Comando,E1M4: 指令管制塔,E1M4: 지휘 통제소,E1M4: Controlecentrum,E1M4: Kommandokontroll,E1M4: Kontrola Dowodzenia,E1M4: Controle de Comando,E1M4: Controlo de Comando,E1M4: Comandă și Control,E1M4: Пункт управления,E1M4: Заповедни центар,E1M4: Komuta Kontrol -E1M5: Phobos Lab,HUSTR_E1M5,,,,E1M5: Phobosská laboratoř,E1M5: Phobos-laboratorium,E1M5: Phobos-Labor,E1Χ5: Εργαστήριο Φόβου,E1M5: Fobo-Laboratorio,E1M5: Laboratorio de Fobos,,E1M5: Phoboksen laboratorio,E1M5: Laboratoires Phobos,E1M5: Phoboszi laboratórium,E1M5: Laboratorio di Phobos,E1M5: フォボス研究所,E1M5: 포보스 연구소,E1M5: Phobos Laboratorium,E1M5: Phobos-laboratorium,E1M5: Laboratoria Fobosa,E1M5: Laboratório de Fobos,,E1M5: Laboratorul Phobos,E1M5: Лаборатория Фобоса,E1M5: Лабораторија на Фобосу,E1M5: Phobos Laboratuvarı -E1M6: Central Processing,HUSTR_E1M6,,,,E1M6: Centrální zpracování,E1M6: Central behandling,E1M6: Zentralverarbeitung,E1Χ6: Κεντρική Επεξεργασία,E1M6: Centra Eskpedado,E1M6: Procesador Central,,E1M6: Käsittelykeskus,E1M6: Centre de Traitement,E1M6: Központi feldolgozó,E1M6: Zona Elaboratori,E1M6: 中央処理施設,E1M6: 중앙 처리 본부,E1M6: Centrale Verwerking,E1M6: Sentral prosessering,E1M6: Centralne Przetwarzanie,E1M6: Processamento Central,,E1M6: Prelucrare Centrală,E1M6: Центральный пункт обработки,E1M6: Централна обрада,E1M6: Merkezi İşlem -E1M7: Computer Station,HUSTR_E1M7,,,,E1M7: Počítačová stanice,E1M7: Computerstation,E1M7: Computerstation,E1Χ7: Σταθμός Υπολογιστών,E1M7: Komputila Stacio,E1M7: Estación de Cómputo,,E1M7: Tietokoneasema,E1M7: Station Informatique,E1M7: Számítógépes központ,E1M7: Stazione dei Computer,E1M7: コンピューターステーション,E1M7: 컴퓨터 기지,E1M7: Computerstation,E1M7: Datastasjon,E1M7: Stacja Komputerowa,E1M7: Estação de Computadores,,E1M7: Stația de Calculatoare,E1M7: Вычислительный центр,E1M7: Компјутерска станица,E1M7: Bilgisayar İstasyonu -E1M8: Phobos Anomaly,HUSTR_E1M8,,,,E1M8: Phobosská anomálie,E1M8: Phobos-anomali,E1M8: Phobos-Anomalie,E1Χ8: Ανωμαλία στον Φόβο,E1M8: Nenormalaĵo de Fobo,E1M8: Anomalía de Fobos,,E1M8: Phoboksen poikkeama,E1M8: Anomalie de Phobos,E1M8: Phoboszi anomália,E1M8: L'anomalia di Phobos,E1M8: フォボス アノマリー,E1M8: 포보스 이상거점,E1M8: Phobos Anomalie,E1M8: Phobos-anomali,E1M8: Anomalia Fobosa,E1M8: Anomalia de Fobos,,E1M8: Anomalia Phobos,E1M8: Аномалия Фобоса,E1M8: Аномалија на Фобосу,E1M8: Phobos Anomalisi -E1M9: Military Base,HUSTR_E1M9,,,,E1M9: Vojenská základna,E1M9: Militærbase,E1M9: Militärbasis,E1Χ9: Στρατιωτική Βάση,E1M9: Militbazo,E1M9: Base Militar,,E1M9: Sotilastukikohta,E1M9: Base Militaire ,E1M9: Katonai bázis,E1M9: Base militare,E1M9: 軍事基地,E1M9: 군사 기지,E1M9: Militaire Basis,E1M9: Militærbase,E1M9: Baza Wojskowa,E1M9: Base Militar,,E1M9: Baza Militară,E1M9: Военная база,E1M9: Војна база,E1M9: Askeri Üs -E1M10: Sewers,HUSTR_E1M10,,,,E1M10: Kanály,E1M10: Kloakkerne,E1M10: Kanalisation,,E1M10: Kloakoj,E1M10: Alcantarillas,,E1M10: Viemärit,E1M10: Egouts,E1M10: Kanálisok,E1M10: Le Fogne,E1M10: 下水道,E1M10: 하수구,E1M10: De Rioleringen,E1M10: Kloakk,E1M10: Ścieki,E1M10: Os Esgotos,,E1M10: Canalizarea,E1M10: Канализация,E1M10: Канализација,E1M10: Kanalizasyonlar -E2M1: Deimos Anomaly,HUSTR_E2M1,,,,E2M1: Deimosská anomálie,E2M1: Deimos Anomali,E2M1: Deimos-Anomalie,E2Χ1: Ανωμαλία στον Δείμο,E2M1: Nenormalaĵo de Dejmo,E2M1: Anomalía de Deimos,,E2M1: Deimoksen poikkeama,E2M1: Anomalie de Déimos,E2M1: Deimoszi anomália,E2M1: L'anomalia di Deimos,E2M1: 異常なるダイモス,E2M1: 데이모스 이상거점,E2M1: Deimos Anomalie,E2M1: Deimos-anomali,E2M1: Anomalia Deimosa,E2M1: Anomalia de Deimos,,E2M1: Anomalia Deimos,E2M1: Аномалия Деймоса,E2M1: Аномалија на Дејмосу,E2M1: Deimos Anomalisi -E2M2: Containment Area,HUSTR_E2M2,,,,E2M2: Skladiště,E2M2: Indespærringsområde,E2M2: Lagerhalle,E2Χ2: Ζώνη Περιορισμού,E2M2: Enhavarejo,E2M2: Área de Confinamiento,,E2M2: Säilöntäalue,E2M2: Zone de Stockage,E2M2: Raktár,E2M2: Area di contenimento,E2M2: 収容エリア,E2M2: 화물 보관구역,E2M2: Inperkingsgebied,E2M2: Innesperringsområde,E2M2: Obszar Zastrzeżony,E2M2: Area de Contenção,E2M2: Área de Confinamento,E2M2: Zona de Izolare,E2M2: Зона сдерживания,E2M2: Складишта,E2M2: Çevreleme Alanı -E2M3: Refinery,HUSTR_E2M3,,,,E2M3: Rafinerie,E2M3: Raffinaderi,E2M3: Raffinerie,E2Χ3: Διυλιστήριο,E2M3: Rafinejo,E2M3: Refinería,,E2M3: Jalostamo,E2M3: Raffinerie,E2M3: Finomító,E2M3: Raffineria,E2M3: 精製所,E2M3: 정제소,E2M3: Raffinaderij,E2M3: Raffineri,E2M3: Rafineria,E2M3: Refinaria,,E2M3: Rafinărie,E2M3: Перерабатывающий завод,E2M3: Рафинерија,E2M3: Rafineri -E2M4: Deimos Lab,HUSTR_E2M4,,,,E2M4: Deimosská laboratoř,E2M4: Deimos-laboratorium,E2M4: Deimos Labor,E2Χ4: Εργαστήριο Δείμου,E2M4: Dejmo-Laboratorio,E2M4: Laboratorio de Deimos,,E2M4: Deimoksen laboratorio,E2M4: Laboratoires Déimos,E2M4: Deimoszi laboratórium,E2M4: Laboratorio di Deimos,E2M4: ダイモス研究所,E2M4: 데이모스 연구소,E2M4: Deimos Laboratorium,E2M4: Deimos-laboratoriet,E2M4: Laboratoria Deimosa,E2M4: Laboratório de Deimos,,E2M4: Laboratorul Deimos,E2M4: Лаборатория Деймоса,E2M4: Лабораторија на Дејмосу,E2M4: Deimos Laboratuvarı -E2M5: Command Center,HUSTR_E2M5,,,,E2M5: Řídící středisko,E2M5: Kommandocentral,E2M5: Kommandozentrum,E2Χ5: Κέντρο Διοίκησης,E2M5: Komandcentro,E2M5: Centro de Mando,,E2M5: Komentokeskus,E2M5: Centre de Commandement,E2M5: Központi parancsnokság,E2M5: Centro di Comando,E2M5: 指令本部,E2M5: 사령부,E2M5: Commandocentrum,E2M5: Kommandosentralen,E2M5: Centrum Dowodzenia,E2M5: Centro de Comando,,E2M5: Centru de Comandă,E2M5: Командный центр,E2M5: Командни центар,E2M5: Komuta Merkezi -E2M6: Halls of the Damned,HUSTR_E2M6,,,,E2M6: Chodby zatracených,E2M6: De Forbandedes haller,E2M6: Säle der Verdammten,E2X6: Διάδρομοι των Κολασμένων,E2M6: Koridoroj de la Damnitaj,E2M6: Salones de los Malditos,,E2M6: Kirottujen salit,E2M6: Halls des Damnés,E2M6: Az átkozottak termei,E2M6: Sale dei Dannati,E2M6: ダムドの会堂,E2M6: 저주받은 회랑,E2M6: Zalen der Verdoemden,E2M6: De fordømtes haller,E2M6: Korytarze Przeklętych,E2M6: Salões dos Condenados,,E2M6: Camerele Blestemaților,E2M6: Залы проклятых,E2M6: Дворана проклетих,E2M6: Lanetliler Salonu -E2M7: Spawning Vats,HUSTR_E2M7,,,,E2M7: Plodné kádě,E2M7: Spirebassiner,E2M7: Materialisationskammern,E2X7: Δεξαμενές Γέννησης,E2M7: Nasko-Kuvegoj,E2M7: Silos de Materialización,,E2M7: Sikiämissammiot,E2M7: Cuves de Reproduction,E2M7: Szaporító tartályok,E2M7: Vasche di Riproduzione,E2M7: 産卵桶,E2M7: 산란독,E2M7: Materialisatietanks,E2M7: Gytekarene,E2M7: Kadzie Reprodukcyjne,E2M7: Tanques de Criação,,E2M7: Cuve de Reproducere,E2M7: Нерестилище,E2M7: Размножавалиште,E2M7: Yumurtlama Fıçıları -E2M8: Tower of Babel,HUSTR_E2M8,,,,E2M8: Babylonská věž,E2M8: Babelstårn,E2M8: Turmbau zu Babel,E2Χ8: Πύργος της Βαβέλ,E2M8: Turo de Babelo,E2M8: Torre de Babel,,E2M8: Baabelin torni,E2M8: Tour de Babel,E2M8: Bábel tornya,E2M8: Torre di Babele,E2M8: バベルの塔,E2M8: 바벨탑,E2M8: Toren van Babel,E2M8: Babels tårn,E2M8: Wieża Babel,E2M8: Torre de Babel,,E2M8: Turnul Babel,E2M8: Вавилонская башня,E2M8: Вавилонска кула,E2M8: Babil Kulesi -E2M9: Fortress of Mystery,HUSTR_E2M9,,,,E2M9: Pevnost záhad,E2M9: Mysteriets fæstning,E2M9: Geheimnisvolle Festung,E2Χ9: Φρούριο του Μυστηρίου,E2M9: Fortreso de Mistero,E2M9: Fortaleza del Misterio,,E2M9: Salaperäisyyden linnake,E2M9: Mystérieuse Forteresse,E2M9: A rejtélyek erődje,E2M9: Fortezza del Mistero,E2M9: 神秘の要塞,E2M9: 신비의 요새,E2M9: Vesting der Mysterie,E2M9: Mysteriets festning,E2M9: Forteca Tajemnic,E2M9: Fortaleza do Mistério,,E2M9: Fortăreața Misterelor,E2M9: Крепость тайн,E2M9: Тврђава тајни,E2M9: Gizem Kalesi -E3M1: Hell Keep,HUSTR_E3M1,,,,E3M1: Pekelná tvrz,E3M1: Helvedesborg,E3M1: Höllenbollwerk,E3Χ1: Ακροπύργιο της Κολάσεως,E3M1: Infera Loĝejturo,E3M1: Torreón del Infierno,E3M1: Torre del Infierno,E3M1: Hornantorni,E3M1: Donjon Infernal,E3M1: A pokol bástyái,E3M1: Bastioni dell'Inferno,E3M1: 牢獄,E3M1: 지옥 성채,E3M1: Helleslot,E3M1: Helvetes borg,E3M1: Twierdza Piekieł,E3M1: Torre do Inferno,,E3M1: Fortul Iadului,E3M1: Крепость Ада,E3M1: Тврђава пакла,E3M1: Cehennem Kalesi -E3M2: Slough of Despair,HUSTR_E3M2,,,,E3M2: Bažina zoufalství,E3M2: Fortvivlelsens sump,E3M2: Sumpf der Verzweiflung,E3Χ2: Έλος της Απελπισίας,E3M2: Ŝlimejo de Malespero,E3M2: Ciénaga de la Desesperación,,E3M2: Epätoivon räme,E3M2: Bourbier du Désespoir,E3M2: A kétségbeesés mocsara,E3M2: Palude della Disperazione,E3M2: 絶望の大地,E3M2: 절망의 심연,E3M2: Moeras der Wanhoop,E3M2: Fortvilelsens sump,E3M2: Bagno Rozpaczy,E3M2: Lamaçal do Desespero,,E3M2: Mlaștinile Disperării,E3M2: Трясина отчаяния,E3M2: Блато очајања,E3M2: Umutsuzluk Slough'u -E3M3: Pandemonium,HUSTR_E3M3,,,,,E3M3: Pandemonium,E3M3: Pandämonium,E3Χ3: Πανδαιμόνιο,E3M3: Pandemonio,E3M3: Pandemonio,,,E3M3: Pandémonium,E3M3: Zűrzavar,E3M3: Pandemonio,E3M3: 伏魔殿,E3M3: 복마전,,,E3M3: Piekło,E3M3: Pandemônio,,E3M3: Pandemoniu,E3M3: Пандемоний,E3M3: Пандемонијум,E3M3: Pandemonium -E3M4: House of Pain,HUSTR_E3M4,,,,E3M4: Dům bolesti,E3M4: Hus af smerte,E3M4: Haus des Schmerzes,E3Χ4: Σπίτι του Πόνου,E3M4: Domo de Doloro,E3M4: Casa del Dolor,,E3M4: Tuskanmaja,E3M4: Maison de la Douleur,E3M4: A kínok háza,E3M4: Casa del Dolore,E3M4: 苦痛の館,E3M4: 고통의 집,E3M4: Huis van Pijn,E3M4: Smertens hus,E3M4: Dom Bólu,E3M4: Casa da Dor,,E3M4: Casa Durerii,E3M4: Обитель боли,E3M4: Кућа патње,E3M4: Acı Evi -E3M5: Unholy Cathedral,HUSTR_E3M5,,,,E3M5: Bezbožná katedrála,E3M5: Uhellig katedral,E3M5: Unheilige Kathedrale,E3X5: Ανίερος Καθεδρικός,E3M5: Malsankta Katedralo,E3M5: Catedral Profana,,E3M5: Epäpyhä katedraali,E3M5: Cathédrale Profane,E3M5: Az istentelen katedrális ,E3M5: Cattedrale Blasfema,E3M5: 邪教の大聖堂,E3M5: 불경한 성당,E3M5: Onheilige Kathedraal,E3M5: Den vanhellige katedralen,E3M5: Bluźniercza Katedra,E3M5: Catedral Profana,,E3M5: Catedrala Necurată,E3M5: Нечестивый собор,E3M5: Несвета катедрала,E3M5: Kutsal Olmayan Katedral -E3M6: Mt. Erebus,HUSTR_E3M6,,,,E3M6: Hora Erebus,,,E3X6: Όρος Έρεβος,E3M6: Monto de Erebo,E3M6: Monte Erebus,,E3M6: Erebusvuori,E3M6: Mont Erèbe,E3M6: Erebus-hegy,E3M6: Monte Erebus,E3M6: エレボス山,E3M6: 에레버스 산,,E3M6: Erebus-fjellet,E3M6: Góra Erebus,E3M6: Monte Érebo,,E3M6: M. Erebus,E3M6: Гора Эребус,E3M6: Планина Еребус,E3M6: Erebus Dağı -E3M7: Limbo,HUSTR_E3M7,,,,E3M7: Předpeklí,,,E3Χ7: Είσοδος της Κολάσεως,,,,E3M7: Limbus,E3M7: Limbes,E3M7: Limbus,E3M7: Limbo,E3M7: 忘却の地,E3M7: 고성소,,,E3M7: Otchłań,E3M7: Limbo,,E3M7: Limb,E3M7: Чистилище,E3M7: Лимбо,E3M7: Araf -E3M8: Dis,HUSTR_E3M8,"Based on the City of Dis, located on the sixth circle of Hell, according to Dante Alighieri's The Divine Comedy",,,,,,E3Χ8: Δίτα,,,,,,,E3M8: Dite,E3M8: 死,E3M8: 디스,,,E3M8: Dis,E3M8: Dite,,E3M8: Dite,E3M8: Дит,E3M8: Дис,E3M8: Dis -E3M9: Warrens,HUSTR_E3M9,,,,E3M9: Brlohy,E3M9: Rotteboet,E3M9: Rattennest,E3X9: Λαγούμια,E3M9: Nestego,E3M9: Madrigueras,,E3M9: Sokkelot,E3M9: Clapiers,E3M9: Nyúlkert,E3M9: Le Garenne,E3M9: 兎小屋,E3M9: 토끼굴,E3M9: Doolhof,E3M9: Rottebo,E3M9: Królikarnia,E3M9: Tocas,,E3M9: Vizuini,E3M9: Изнорье,E3M9: Одгајалиште,E3M9: Sıçan yuvası -E4M1: Hell Beneath,HUSTR_E4M1,Proverbs 15:24,,,E4M1: Peklo v hlubinách,E4M1: Helvede nedenunder,E4M1: Die Hölle unterwärts,E4Χ1: Κάτω Κόσμος,E4M1: Ŝeolo Malsupre,E4M1: Bajo el Infierno,,E4M1: Tuonela alhaalla,E4M1: Le Séjour des Morts,E4M1: A holtak hazája odalent,E4M1: In Basso,E4M1: 地獄の下へ,E4M1: 지옥의 밑에서,E4M1: Hel beneden,E4M1: Helvete under,E4M1: Piekło Najgłębsze,E4M1: Inferno Abaixo,E4M1: Inferno Profundo,E4M1: Iadul de Jos,E4M1: Преисподняя под ногами,E4M1: Пакао одоздо,E4M1: Cehennem Altında -E4M2: Perfect Hatred,HUSTR_E4M2,Psalm 139:22,,,E4M2: Naprostá nenávist,E4M2: Perfekt had,E4M2: Perfekter Hass,E4Χ2: Τέλειο Μίσος,E4M2: Perfekta Malamo,E4M2: Odio Perfecto,,E4M2: Kaikella vihalla,E4M2: Une Parfaite Haine,E4M2: Teljes gyűlölettel,E4M2: Odio Perfetto,E4M2: 完全なる憎悪,E4M2: 완벽한 증오,E4M2: Perfecte Haat,E4M2: Perfekt hat,E4M2: Pełnia Nienawiści,E4M2: Ódio Perfeito,,E4M2: Ură Desăvârșită,E4M2: Полная ненависть,E4M2: Пуном мрзошћу,E4M2: Kusursuz Nefret -E4M3: Sever The Wicked,HUSTR_E4M3,Matthew 13:49,,,E4M3: Oddělit zkažené,E4M3: Afskære de onde,E4M3: Scheidet die Bösen,E4Χ3: Ξερίζωσε τους Πονηρούς,E4M3: Apartigi la Malbonulojn,E4M3: Cercena a los impíos,,E4M3: Erottavat pahat,E4M3: Séparer les Vicieux,E4M3: Felnégyelni a bűnösöket,E4M3: Separeranno I Cattivi,E4M3: 邪悪を絶つ,E4M3: 악령처단,E4M3: Scheid de goddelozen af,E4M3: Skille ut de onde,E4M3: Oddzielą Niegodziwych,E4M3: Separarão os Maus,E4M3: Separarão o Mal,E4M3: Să Desparți pe Cei Răi,E4M3: Отделить злых,E4M3: Одлучи зле,E4M3: Kötüleri Kesin -E4M4: Unruly Evil,HUSTR_E4M4,James 3:8,,,E4M4: Nezkrotitelné zlo,E4M4: Ustyrlig ondskab,E4M4: Schandbare Worte,E4X4: Ασυγκράτητο Κακό,E4M4: Neretenebla Malbono,E4M4: Maldad Incontrolable,,E4M4: Levotointa pahuutta,E4M4: Un Mal Irrépréssible,E4M4: Féktelen gonosz,E4M4: Male Senza Posa,E4M4: 手に負えない邪悪,E4M4: 광폭한 악마,E4M4: Het weerbarstige kwaad,E4M4: Uregjerlig ondskap,E4M4: Niepohamowane Zło,E4M4: Mal Irrefreável,E4M4: Mal que não Refreia,E4M4: Un Rău fără Astâmpăr,E4M4: Неудержимое зло,Е4М4: Немирно зло,E4M4: Asi Kötülük -E4M5: They Will Repent,HUSTR_E4M5,Luke 16:30,,,E4M5: Budou činit pokání,E4M5: De vil omvende sig,E4M5: Sie werden bereuen,E4X5: Θα Μετανοήσουν,E4M5: Ili Pentos,E4M5: Se Arrepentirán,,E4M5: He parannuksen tekisivät,E4M5: Ils se repentiront,E4M5: Megtérnek majd,E4M5: Si Ravvederanno,E4M5: 奴等に後悔を,E4M5: 그들은 회개할 지어다,E4M5: Ze zullen berouw hebben,E4M5: De vil omvende seg,E4M5: Nawrócą Się,E4M5: Arrepender-se,E4M5: Eles Arrepender-se-iam,E4M5: Se vor Pocăi,E4M5: Они покаются,E4M5: Покајаће се,E4M5: Tövbe Edecekler -E4M6: Against Thee Wickedly,HUSTR_E4M6,Psalm 139:20,,,E4M6: Při svých pletichách,E4M6: Mod dig ondskabsfuldt,E4M6: Feinde erheben sich,E4X6: Κακόβουλα Εναντίον Σου,E4M6: Kontraŭ Vi Malvirte,E4M6: Perversamente contra ti,,E4M6: Sinusta petollisesti,E4M6: D'une manière criminelle,E4M6: Hitványul ellened,E4M6: Contro di te Malvagiamente,E4M6: 汝への悪逆,E4M6: 그대와 짖궂게 맞서다,E4M6: Tegen de goddeloze,E4M6: Mot deg ondskapsfullt,E4M6: Podstępnie Przeciw Tobie,E4M6: Malvadamente Contra Ti,,E4M6: Te Grăiesc de Rău,E4M6: Против тебя нечестиво,E4M6: Ружно на тебе,E4M6: Sana Karşı Kötüce -E4M7: And Hell Followed,HUSTR_E4M7,Revelation 6:8,,,E4M7: A peklo šlo za ním,E4M7: Og Helvede fulgte efter,E4M7: Und die Hölle folgte,E4X7: Και η Κόλαση Ακολούθησε,E4M7: Kaj Hades Sekvis,E4M7: Y el Infierno Continuó,,E4M7: Ja Tuonela seurasi,E4M7: Et l'Enfer Suivit,E4M7: És a pokol követé azt,E4M7: E l'inferno seguitava,E4M7: そして地獄は従った,E4M7: 그리고 지옥이 뒤따른다,E4M7: En de hel volgde,E4M7: Og helvete fulgte,E4M7: A Piekło Szło Za Nim,E4M7: E o Inferno Seguia,E4M7: Inferno o Seguia,E4M7: Iadul se Ținea după El,E4M7: И последовал Ад,E4M7: И пакао иђаше,E4M7: Ve Cehennem Takip Etti -E4M8: Unto The Cruel,HUSTR_E4M8,Proverbs 5:9,,,E4M8: Ukrutníku odevzdáš,E4M8: Til de grusomme,E4M8: Deine Jahre dem Grausamen,E4X8: Προς Τους Ανελεήμονες,E4M8: Al La Kruelulo,E4M8: En lo Cruel,,E4M8: Armottomalle,E4M8: A un Homme cruel,E4M8: A kegyetlennek,E4M8: Al Crudele,E4M8: 容赦なき者へ,E4M8: 잔혹한 자에게로,E4M8: Naar de wrede,E4M8: Til de grusomme,E4M8: Kto Nie Zna Litości,E4M8: Aos Cruéis,E4M8: Entregue a Cruéis,E4M8: Unuia Fără de Milă,E4M8: К мучителю,E4M8: Немилостивоме,E4M8: Zalimlere Karşı -E4M9: Fear,HUSTR_E4M9,,,,E4M9: Strach,E4M9: Frygt,E4M9: Angst,E4Χ9: Τρόμος,E4M9: Timo,E4M9: Miedo,,E4M9: Pelko,E4M9: Terreur,E4M9: Félelem,E4M9: Paura,E4M9: 恐怖,E4M9: 공포,E4M9: Angst,E4M9: Frykt,E4M9: Strach,E4M9: Medo,,E4M9: Frica,E4M9: Страх,E4M9: Страх,E4M9: Korku -,,Doom 2,,,,,,,,,,,,,,,,,,,,,,,, -Level 1: Entryway,HUSTR_1,"Note that the ""LEVEL"" part of the string will be stripped so it shouldn't be translated",,,Level 1: Vchod,Level 1: Indgang,Level 1: Eingangshalle,Επίπεδο 1: Είσοδος,Nivelo 1: Enirejo,Nivel 1: Entrada,,Taso 1: Eteiskäytävä,NIVEAU 1: Hall D'Entrée,1. Pálya: Bejárat,Livello 1: Ingresso,Level 1: 入口,레벨 1: 초입,Level 1: Ingang,Nivå 1: Inngangen,Level 1: Wejście,Fase 1: Entrada,Nível 1: Entrada,Nivelul 1: Intrarea,Уровень №1: Вход,Level 1: Улаз,Seviye 1: Giriş Yolu -Level 2: Underhalls,HUSTR_2,,,,Level 2: Podzemí,Level 2: Underbukser,Level 2: Kellergewölbe,,Nivelo 2: Subtervojoj,Nivel 2: Salones subterráneos,,Taso 2: Maanalaiset käytävät,NIVEAU 2: Souterrains,2. Pálya: Alagutak,Livello 2: Sotterranei,Level 2: 地下堂,레벨 2: 지하수로,Level 2: Onderhallen,Nivå 2: Underhaller,Level 2: Podziemia,Fase 2: Subterrâneo,Nível 2: Subterrâneo,Nivelul 2: Pasaje subterane,Уровень №2: Подземные ходы,Level 2: Подземни ходници,Seviye 2: Tulumlar -Level 3: The Gantlet,HUSTR_3,“a form of punishment in which a person is forced to run between two lines of men facing each other and armed with clubs or whips to beat the victim”,,,Level 3: Trest,Level 3: Spidsrod,Level 3: Spießrutenlauf,,Nivelo 3: La Spaliro,Nivel 3: Las Baquetas,,Taso 3: Kujanjuoksu,NIVEAU 3: Parcours du Combatant,3. Pálya: Vesszőfutás,Livello 3: Le Forche,Level 3: ガントレット,레벨 3: 건틀릿,Level 3: De gantlet,Nivå 3: Hansken,Level 3: Praszczęta,Fase 3: A Punição,Nível 3: A Punição,Nivelul 3: Stroiul,Уровень №3: Сквозь строй,Level 3: Казна,Seviye 3: Zorluk -Level 4: The Focus,HUSTR_4,,,,Level 4: Ohnisko,Level 4: Fokus,Level 4: Der Fokus,,Nivelo 4: La Fokuso,Nivel 4: El Foco,,Taso 4: Polttopiste,NIVEAU 4: Le Focus,4. Pálya: A középpont,Livello 4: L'Epicentro,Level 4: フォーカス,레벨 4: 초점,Level 4: De focus,Nivå 4: Fokus,Level 4: Skupisko,Fase 4: O Foco,Nível 4: O Foco,Nivelul 4: Focarul,Уровень №4: Средоточие,Level 4: Средиште,Seviye 4: Odaklanma -Level 5: The Waste Tunnels,HUSTR_5,,,,Level 5: Odpadní tunely,Level 5: Affaldstunnellerne,Level 5: Die Abfall-Tunnel,Επίπεδο 5: Οι Σήραγγες Αποβλήτων,Nivelo 5: La Rubtuneloj,Nivel 5: Los Túneles de Desechos,,Taso 5: Jätetunnelit,NIVEAU 5: Les Egouts,5. Pálya: Szennyvízalagutak,Livello 5: I Tunnel dei Rifiuti,Level 5: 廃棄トンネル,레벨 5: 하수도,Level 5: De afvaltunnels,Nivå 5: Avfallstunnelene,Level 5: Kanały,Fase 5: Os Túneis de Dejetos,Nível 5: Os Túneis de Dejetos,Nivelul 5: Tuneluri de deșeuri,Уровень №5: Сточные туннели,Level 5: Отпадни тунели,Seviye 5: Atık Tünelleri -Level 6: The Crusher,HUSTR_6,,,,Level 6: Drtička,Level 6: Knuseren,Level 6: Die Presse,Επίπεδο 6: Ο Συνθλιπτής,Nivelo 6: La Dispistilo,Nivel 6: La Trituradora,,Taso 6: Murskaaja,NIVEAU 6: Le Broyeur,6. Pálya: A zúzda,Livello 6: La Pressa,Level 6: クラッシャー,레벨 6: 분쇄기,Level 6: De maalmachine,Nivå 6: Knuseren,Level 6: Zgniatarka,Fase 6: O Esmagador,Nível 6: O Esmagador,Nivelul 6: Zdrobitorul,Уровень №6: Давилка,Level 6: Разбијач,Seviye 6: Kırıcı -Level 7: Dead Simple,HUSTR_7,,,,Level 7: Smrtelně prosté,Level 7: Død simpel,Level 7: Tödlich einfach,Επίπεδο 7: Πανεύκολο,Nivelo 7: Morte Simpla,Nivel 7: Simplemente Muerto,,Taso 7: Kuolettavan yksinkertainen,NIVEAU 7: Mortellement Simple,7. Pálya: Halálegyszerű,Livello 7: Morte Pura,Level 7: 死ぬほど単純,레벨 7: 죽여주는 단순함,Level 7: Dodelijk eenvoudig,Nivå 7: Helt enkelt,Level 7: Śmiertelnie Proste,Fase 7: Mortalmente Simples,Nível 7: Simplesmente Mortal,Nivelul 7: Mortal de simplu,Уровень №7: Смертельно просто,Level 7: Смртно једноставно,Seviye 7: Ölü Basit -Level 8: Tricks and Traps,HUSTR_8,,,,Level 8: Lesti a léčky,Level 8: Tricks og fælder,Level 8: Tricks und Fallen,Επίπεδο 8: Κόλπα και Παγίδες,Nivelo 8: Trukoj kaj Kaptiloj,Nivel 8: Trucos y Trampas,,Taso 8: Metkuja ja pauloja,NIVEAU 8: Ruses et Pièges,8. Pálya: Cselek és csapdák,Livello 8: Trucchi e Trappole,Level 8: 悪戯と罠,레벨 8: 속임수와 함정들,Level 8: Trucs en vallen,Nivå 8: Triks og feller,Level 8: Sztuczki i Pułapki,Fase 8: Truques e Armadilhas,Nível 8: Truques e Armadilhas,Nivelul 9: Surprize și capcane,Уровень №8: Уловки и ловушки,Level 8: Замке и смицалице,Seviye 8: Hileler ve Tuzaklar -Level 9: The Pit,HUSTR_9,,,,Level 9: Jáma,Level 9: Gruben,Level 9: Die Grube,Επίπεδο 9: Λάκκος,Nivelo 9: La Fosaĵo,Nivel 9: El Pozo,,Taso 9: Monttu,NIVEAU 9: La Fosse,9. Pálya: A gödör,Livello 9: Il Pozzo,Level 9: 大穴,레벨 9: 구덩이,Level 9: De groeve,Nivå 9: Gropen,Level 9: Dół,Fase 9: O Fosso,Nível 9: O Fosso,Nivelul 9: Groapa,Уровень №9: Яма,Level 9: Јама,Seviye 9: Çukur -Level 10: Refueling Base,HUSTR_10,,,,Level 10: Tankovací základna,Level 10: Tankstation,Level 10: Treibstoffbunker,Επίπεδο 10: Βάση Ανεφοδιασμού,Nivelo 10: Refuelbazo,Nivel 10: Base de Reabastecimiento,,Taso 10: Tankkausasema,NIVEAU 10: Base de Ravitaillement,10. Pálya: Tankolóállomás,Livello 10: Base di Rifornimento,Level 10: 補給基地,레벨 10: 연료 충전소,Level 10: Tankstation,Nivå 10: Påfyllingsbasen,Level 10: Stacja Tankowania,Fase 10: Base de Reabastecimento,Nível 10: Base de Reabastecimento,Nivelul 10: Baza de alimentare,Уровень №10: Заправочная база,Level 10: Бензинска база,Seviye 10: Yakıt İkmal Üssü +Proverbs 5:11",,,Tvé tělo pozřeto,Dit kød er fortæret,Dein Leib verzehrt,Η Σάρκα σου θα Καταναλωθεί,Via Karno Konsumita,Tu Carne Consumida,,Lihasi kulutettu,Votre Chair Consumée,Megemésztetik a te húsod,La tua Carne Consumata,滅びし汝の身,쇠패해진 그대의 육신,Uw Vlees Geconsumeerd,Ditt kjøtt fortæres,Ciało Twe Zwiotczeje,No Consumir-se da Tua Carne,,Carnea ta Fără de Vlagă,Твоя плоть поглощена,Твоје месо строшено,Ditt kött är uppslukat,Etin Tükendi +Hell On Earth,TXT_D2E1,,,,Peklo na zemi,Helvede på jorden,Hölle auf Erden,Αρμαγεδδών,Infero Sur La Tero,Infierno en la Tierra,,Helvetti maan päällä,Enfer sur Terre,Földi pokol,Inferno sulla Terra,第三惑星:地獄,지상에 강림한 지옥,Hel op Aarde,Helvete på jorden,Piekło na Ziemi,Inferno na Terra,,Iadul pe Pământ,Ад на Земле,Пакао на Земљи,Helvetet på jorden,Yeryüzündeki Cehennem +No Rest for the Living,TXT_D2E2,"References ""No rest for the wicked"" in Isaiah 48:22",,,Nemajíť živí pokoje,Ingen hvile for de levende,Keine Ruhe für die Lebenden,Καμία Ανάπαυση για τους Ζωντανούς,Nenia Ripozo por la Vivantoj,No hay Descanso para los Vivos,,Ei lepoa eläville,Pas de repos pour les vivants,Nincs nyugodalom az élőnek,Nessun Riposo per i Vivi,休息なき生計,산 자에게 휴식은 없다,Geen Rust voor de Levenden,Ingen hvile for de levende,Brak Wytchnienia Dla Żywych,Não Há Descanso Para os Vivos,,Cei vii Fără de Odihnă,Не будет покоя живым,Нема одмора живима,Ingen vila för de levande,Yaşayanlara Huzur Yok +The Plutonia Experiment,TXT_PLUT_EP,,,,Experiment Plutonia,Plutonia-eksperimentet,Das Plutonia Experiment,Το Πείραμα Πλουτώνια,La Eksperimento de Plutonia,El Experimento Plutonia,,Plutoniakokemus,L'expérience Plutonia,A Plutonia-kísérlet,L'Esperimento di Plutonia,プルトニア記,플루토니아 익스페리먼트,Het Plutonia Experiment,Plutonia-eksperimentet,Eksperyment Plutonia,O Experimento Plutonia,A Experiência Plutonia,Experimentul Plutonia,Эксперимент «Плутония»,Експеримент Плутонија,Plutonia-experimentet,Plutonia Deneyi +TNT: Evilution,TXT_TNT_EP,,,,TNT: Zlovoluce,,,ΤΝΤ: Κακοξέλιξη,TNT: Mavalucio,TNT: Diabolución,,TNT: Paholuutio,,,TNT: Malvoluzione,TNT:邪神化,TNT: 이블루션,Tnt: Evilutie,,TNT: Ewolucja Zła,TNT: Malvolução,,TNT: Diavoluția,TNT: Дьяволюция,TNT: Ђаволуција,, +Chex Quest,TXT_CHEX_EP,,,,Mise Chex,,,Η Περιπέτεια του Chex,Aventuro de Chex,,,Chex-seikkailu,,,,チェックス クエスト,첵스 퀘스트,,,Misja Chex,,,,,Чекс Квест,, +,,Level names,,,,,,,,,,,,,,,,,,,,,,,,, +,,Doom 1,,,,,,,,,,,,,,,,,,,,,,,,, +E1M1: Hangar,HUSTR_E1M1,,,,E1M1: Hangár,,,E1Χ1: Υπόστεγο,E1M1: Hangaro,,,E1M1: Lentoalushalli,,E1M1: Hangár,,E1M1: 格納庫,E1M1: 격납고,,,,,,,E1M1: Ангар,E1M1: Хангар,, +E1M2: Nuclear Plant,HUSTR_E1M2,,,,E1M2: Jaderná elektrárna,E1M2: Atomkraftværk,E1M2: Kernkraftwerk,E1Χ2: Πυρηνικό Εργοστάσιο,E1M2: Nuklea Centralo,E1M2: Planta Nuclear,,E1M2: Ydinvoimala,E1M2: Centrale Nucléaire,E1M2: Atomerőmű,E1M2: Centrale Nucleare,E1M2: 原子力発電所,E1M2: 원자력 발전소,E1M2: Kerncentrale,E1M2: Kjernekraftverk,E1M2: Elektrownia Jądrowa,E1M2: Usina Nuclear,E1M2: Central Nuclear,E1M2: Uzina Nucleară,E1M2: Атомная электростанция,E1M2: Нуклеарна електрана,E1M2: Kärnkraftverk,E1M2: Nükleer Santral +E1M3: Toxin Refinery,HUSTR_E1M3,,,,E1M3: Chemická rafinerie,E1M3: Giftraffinaderi,E1M3: Giftraffinerie,E1Χ3: Διυλιστήριο Τοξινών,E1M3: Toksin-Rafinejo,E1M3: Refinería de Toxinas,,E1M3: Myrkkyjalostamo,E1M3: Raffinerie de Toxines,E1M3: Méregfinomító,E1M3: Raffineria delle Tossine,E1M3: 毒素精錬所 ,E1M3: 폐기물 정제소,E1M3: Giftstofraffinaderij,E1M3: Giftraffineri,E1M3: Rafineria Toksyn,E1M3: Refinaria de Toxinas,,E1M3: Rafinăria de Toxine,E1M3: Очистной завод,E1M3: Рафинерија за токсине,E1M3: Toxinraffinaderi,E1M3: Toksin Rafinerisi +E1M4: Command Control,HUSTR_E1M4,,,,E1M4: Řídící velín,E1M4: Kommandokontrol,E1M4: Betriebssteuerung,E1Χ4: Κέντρο Ελέγχου,E1M4: Kontrolcentro,E1M4: Control de Mando,,E1M4: Komentohallinta,E1M4: Centre de Contrôle,E1M4: Parancsnoki vezérlő,E1M4: Centrale di Comando,E1M4: 指令管制塔,E1M4: 지휘 통제소,E1M4: Controlecentrum,E1M4: Kommandokontroll,E1M4: Kontrola Dowodzenia,E1M4: Controle de Comando,E1M4: Controlo de Comando,E1M4: Comandă și Control,E1M4: Пункт управления,E1M4: Заповедни центар,E1M4: Kommandokontroll,E1M4: Komuta Kontrol +E1M5: Phobos Lab,HUSTR_E1M5,,,,E1M5: Phobosská laboratoř,E1M5: Phobos-laboratorium,E1M5: Phobos-Labor,E1Χ5: Εργαστήριο Φόβου,E1M5: Fobo-Laboratorio,E1M5: Laboratorio de Fobos,,E1M5: Phoboksen laboratorio,E1M5: Laboratoires Phobos,E1M5: Phoboszi laboratórium,E1M5: Laboratorio di Phobos,E1M5: フォボス研究所,E1M5: 포보스 연구소,E1M5: Phobos Laboratorium,E1M5: Phobos-laboratorium,E1M5: Laboratoria Fobosa,E1M5: Laboratório de Fobos,,E1M5: Laboratorul Phobos,E1M5: Лаборатория Фобоса,E1M5: Лабораторија на Фобосу,E1M5: Phobos-laboratorium,E1M5: Phobos Laboratuvarı +E1M6: Central Processing,HUSTR_E1M6,,,,E1M6: Centrální zpracování,E1M6: Central behandling,E1M6: Zentralverarbeitung,E1Χ6: Κεντρική Επεξεργασία,E1M6: Centra Eskpedado,E1M6: Procesador Central,,E1M6: Käsittelykeskus,E1M6: Centre de Traitement,E1M6: Központi feldolgozó,E1M6: Zona Elaboratori,E1M6: 中央処理施設,E1M6: 중앙 처리 본부,E1M6: Centrale Verwerking,E1M6: Sentral prosessering,E1M6: Centralne Przetwarzanie,E1M6: Processamento Central,,E1M6: Prelucrare Centrală,E1M6: Центральный пункт обработки,E1M6: Централна обрада,E1M6: Central bearbetning,E1M6: Merkezi İşlem +E1M7: Computer Station,HUSTR_E1M7,,,,E1M7: Počítačová stanice,E1M7: Computerstation,E1M7: Computerstation,E1Χ7: Σταθμός Υπολογιστών,E1M7: Komputila Stacio,E1M7: Estación de Cómputo,,E1M7: Tietokoneasema,E1M7: Station Informatique,E1M7: Számítógépes központ,E1M7: Stazione dei Computer,E1M7: コンピューターステーション,E1M7: 컴퓨터 기지,E1M7: Computerstation,E1M7: Datastasjon,E1M7: Stacja Komputerowa,E1M7: Estação de Computadores,,E1M7: Stația de Calculatoare,E1M7: Вычислительный центр,E1M7: Компјутерска станица,E1M7: Datorstation,E1M7: Bilgisayar İstasyonu +E1M8: Phobos Anomaly,HUSTR_E1M8,,,,E1M8: Phobosská anomálie,E1M8: Phobos-anomali,E1M8: Phobos-Anomalie,E1Χ8: Ανωμαλία στον Φόβο,E1M8: Nenormalaĵo de Fobo,E1M8: Anomalía de Fobos,,E1M8: Phoboksen poikkeama,E1M8: Anomalie de Phobos,E1M8: Phoboszi anomália,E1M8: L'anomalia di Phobos,E1M8: フォボス アノマリー,E1M8: 포보스 이상거점,E1M8: Phobos Anomalie,E1M8: Phobos-anomali,E1M8: Anomalia Fobosa,E1M8: Anomalia de Fobos,,E1M8: Anomalia Phobos,E1M8: Аномалия Фобоса,E1M8: Аномалија на Фобосу,E1M8: Phobos anomali,E1M8: Phobos Anomalisi +E1M9: Military Base,HUSTR_E1M9,,,,E1M9: Vojenská základna,E1M9: Militærbase,E1M9: Militärbasis,E1Χ9: Στρατιωτική Βάση,E1M9: Militbazo,E1M9: Base Militar,,E1M9: Sotilastukikohta,E1M9: Base Militaire ,E1M9: Katonai bázis,E1M9: Base militare,E1M9: 軍事基地,E1M9: 군사 기지,E1M9: Militaire Basis,E1M9: Militærbase,E1M9: Baza Wojskowa,E1M9: Base Militar,,E1M9: Baza Militară,E1M9: Военная база,E1M9: Војна база,E1M9: Militärbas,E1M9: Askeri Üs +E1M10: Sewers,HUSTR_E1M10,,,,E1M10: Kanály,E1M10: Kloakkerne,E1M10: Kanalisation,,E1M10: Kloakoj,E1M10: Alcantarillas,,E1M10: Viemärit,E1M10: Egouts,E1M10: Kanálisok,E1M10: Le Fogne,E1M10: 下水道,E1M10: 하수구,E1M10: De Rioleringen,E1M10: Kloakk,E1M10: Ścieki,E1M10: Os Esgotos,,E1M10: Canalizarea,E1M10: Канализация,E1M10: Канализација,E1M10: Avloppsledningar,E1M10: Kanalizasyonlar +E2M1: Deimos Anomaly,HUSTR_E2M1,,,,E2M1: Deimosská anomálie,E2M1: Deimos Anomali,E2M1: Deimos-Anomalie,E2Χ1: Ανωμαλία στον Δείμο,E2M1: Nenormalaĵo de Dejmo,E2M1: Anomalía de Deimos,,E2M1: Deimoksen poikkeama,E2M1: Anomalie de Déimos,E2M1: Deimoszi anomália,E2M1: L'anomalia di Deimos,E2M1: 異常なるダイモス,E2M1: 데이모스 이상거점,E2M1: Deimos Anomalie,E2M1: Deimos-anomali,E2M1: Anomalia Deimosa,E2M1: Anomalia de Deimos,,E2M1: Anomalia Deimos,E2M1: Аномалия Деймоса,E2M1: Аномалија на Дејмосу,E2M1: Deimos-anomali,E2M1: Deimos Anomalisi +E2M2: Containment Area,HUSTR_E2M2,,,,E2M2: Skladiště,E2M2: Indespærringsområde,E2M2: Lagerhalle,E2Χ2: Ζώνη Περιορισμού,E2M2: Enhavarejo,E2M2: Área de Confinamiento,,E2M2: Säilöntäalue,E2M2: Zone de Stockage,E2M2: Raktár,E2M2: Area di contenimento,E2M2: 収容エリア,E2M2: 화물 보관구역,E2M2: Inperkingsgebied,E2M2: Innesperringsområde,E2M2: Obszar Zastrzeżony,E2M2: Area de Contenção,E2M2: Área de Confinamento,E2M2: Zona de Izolare,E2M2: Зона сдерживания,E2M2: Складишта,E2M2: Lagringsområde,E2M2: Çevreleme Alanı +E2M3: Refinery,HUSTR_E2M3,,,,E2M3: Rafinerie,E2M3: Raffinaderi,E2M3: Raffinerie,E2Χ3: Διυλιστήριο,E2M3: Rafinejo,E2M3: Refinería,,E2M3: Jalostamo,E2M3: Raffinerie,E2M3: Finomító,E2M3: Raffineria,E2M3: 精製所,E2M3: 정제소,E2M3: Raffinaderij,E2M3: Raffineri,E2M3: Rafineria,E2M3: Refinaria,,E2M3: Rafinărie,E2M3: Перерабатывающий завод,E2M3: Рафинерија,E2M3: Raffinaderi,E2M3: Rafineri +E2M4: Deimos Lab,HUSTR_E2M4,,,,E2M4: Deimosská laboratoř,E2M4: Deimos-laboratorium,E2M4: Deimos Labor,E2Χ4: Εργαστήριο Δείμου,E2M4: Dejmo-Laboratorio,E2M4: Laboratorio de Deimos,,E2M4: Deimoksen laboratorio,E2M4: Laboratoires Déimos,E2M4: Deimoszi laboratórium,E2M4: Laboratorio di Deimos,E2M4: ダイモス研究所,E2M4: 데이모스 연구소,E2M4: Deimos Laboratorium,E2M4: Deimos-laboratoriet,E2M4: Laboratoria Deimosa,E2M4: Laboratório de Deimos,,E2M4: Laboratorul Deimos,E2M4: Лаборатория Деймоса,E2M4: Лабораторија на Дејмосу,E2M4: Deimos Lab,E2M4: Deimos Laboratuvarı +E2M5: Command Center,HUSTR_E2M5,,,,E2M5: Řídící středisko,E2M5: Kommandocentral,E2M5: Kommandozentrum,E2Χ5: Κέντρο Διοίκησης,E2M5: Komandcentro,E2M5: Centro de Mando,,E2M5: Komentokeskus,E2M5: Centre de Commandement,E2M5: Központi parancsnokság,E2M5: Centro di Comando,E2M5: 指令本部,E2M5: 사령부,E2M5: Commandocentrum,E2M5: Kommandosentralen,E2M5: Centrum Dowodzenia,E2M5: Centro de Comando,,E2M5: Centru de Comandă,E2M5: Командный центр,E2M5: Командни центар,E2M5: Kommandocentrum,E2M5: Komuta Merkezi +E2M6: Halls of the Damned,HUSTR_E2M6,,,,E2M6: Chodby zatracených,E2M6: De Forbandedes haller,E2M6: Säle der Verdammten,E2X6: Διάδρομοι των Κολασμένων,E2M6: Koridoroj de la Damnitaj,E2M6: Salones de los Malditos,,E2M6: Kirottujen salit,E2M6: Halls des Damnés,E2M6: Az átkozottak termei,E2M6: Sale dei Dannati,E2M6: ダムドの会堂,E2M6: 저주받은 회랑,E2M6: Zalen der Verdoemden,E2M6: De fordømtes haller,E2M6: Korytarze Przeklętych,E2M6: Salões dos Condenados,,E2M6: Camerele Blestemaților,E2M6: Залы проклятых,E2M6: Дворана проклетих,E2M6: De fördömdas salar,E2M6: Lanetliler Salonu +E2M7: Spawning Vats,HUSTR_E2M7,,,,E2M7: Plodné kádě,E2M7: Spirebassiner,E2M7: Materialisationskammern,E2X7: Δεξαμενές Γέννησης,E2M7: Nasko-Kuvegoj,E2M7: Silos de Materialización,,E2M7: Sikiämissammiot,E2M7: Cuves de Reproduction,E2M7: Szaporító tartályok,E2M7: Vasche di Riproduzione,E2M7: 産卵桶,E2M7: 산란독,E2M7: Materialisatietanks,E2M7: Gytekarene,E2M7: Kadzie Reprodukcyjne,E2M7: Tanques de Criação,,E2M7: Cuve de Reproducere,E2M7: Нерестилище,E2M7: Размножавалиште,E2M7: Växthus för spädning,E2M7: Yumurtlama Fıçıları +E2M8: Tower of Babel,HUSTR_E2M8,,,,E2M8: Babylonská věž,E2M8: Babelstårn,E2M8: Turmbau zu Babel,E2Χ8: Πύργος της Βαβέλ,E2M8: Turo de Babelo,E2M8: Torre de Babel,,E2M8: Baabelin torni,E2M8: Tour de Babel,E2M8: Bábel tornya,E2M8: Torre di Babele,E2M8: バベルの塔,E2M8: 바벨탑,E2M8: Toren van Babel,E2M8: Babels tårn,E2M8: Wieża Babel,E2M8: Torre de Babel,,E2M8: Turnul Babel,E2M8: Вавилонская башня,E2M8: Вавилонска кула,E2M8: Babels torn,E2M8: Babil Kulesi +E2M9: Fortress of Mystery,HUSTR_E2M9,,,,E2M9: Pevnost záhad,E2M9: Mysteriets fæstning,E2M9: Geheimnisvolle Festung,E2Χ9: Φρούριο του Μυστηρίου,E2M9: Fortreso de Mistero,E2M9: Fortaleza del Misterio,,E2M9: Salaperäisyyden linnake,E2M9: Mystérieuse Forteresse,E2M9: A rejtélyek erődje,E2M9: Fortezza del Mistero,E2M9: 神秘の要塞,E2M9: 신비의 요새,E2M9: Vesting der Mysterie,E2M9: Mysteriets festning,E2M9: Forteca Tajemnic,E2M9: Fortaleza do Mistério,,E2M9: Fortăreața Misterelor,E2M9: Крепость тайн,E2M9: Тврђава тајни,E2M9: Mysteriets fästning,E2M9: Gizem Kalesi +E3M1: Hell Keep,HUSTR_E3M1,,,,E3M1: Pekelná tvrz,E3M1: Helvedesborg,E3M1: Höllenbollwerk,E3Χ1: Ακροπύργιο της Κολάσεως,E3M1: Infera Loĝejturo,E3M1: Torreón del Infierno,E3M1: Torre del Infierno,E3M1: Hornantorni,E3M1: Donjon Infernal,E3M1: A pokol bástyái,E3M1: Bastioni dell'Inferno,E3M1: 牢獄,E3M1: 지옥 성채,E3M1: Helleslot,E3M1: Helvetes borg,E3M1: Twierdza Piekieł,E3M1: Torre do Inferno,,E3M1: Fortul Iadului,E3M1: Крепость Ада,E3M1: Тврђава пакла,E3M1: Helvetesborg,E3M1: Cehennem Kalesi +E3M2: Slough of Despair,HUSTR_E3M2,,,,E3M2: Bažina zoufalství,E3M2: Fortvivlelsens sump,E3M2: Sumpf der Verzweiflung,E3Χ2: Έλος της Απελπισίας,E3M2: Ŝlimejo de Malespero,E3M2: Ciénaga de la Desesperación,,E3M2: Epätoivon räme,E3M2: Bourbier du Désespoir,E3M2: A kétségbeesés mocsara,E3M2: Palude della Disperazione,E3M2: 絶望の大地,E3M2: 절망의 심연,E3M2: Moeras der Wanhoop,E3M2: Fortvilelsens sump,E3M2: Bagno Rozpaczy,E3M2: Lamaçal do Desespero,,E3M2: Mlaștinile Disperării,E3M2: Трясина отчаяния,E3M2: Блато очајања,E3M2: Förtvivlans svackor,E3M2: Umutsuzluk Slough'u +E3M3: Pandemonium,HUSTR_E3M3,,,,,E3M3: Pandemonium,E3M3: Pandämonium,E3Χ3: Πανδαιμόνιο,E3M3: Pandemonio,E3M3: Pandemonio,,,E3M3: Pandémonium,E3M3: Zűrzavar,E3M3: Pandemonio,E3M3: 伏魔殿,E3M3: 복마전,,,E3M3: Piekło,E3M3: Pandemônio,,E3M3: Pandemoniu,E3M3: Пандемоний,E3M3: Пандемонијум,E3M3: Pandemonium,E3M3: Pandemonium +E3M4: House of Pain,HUSTR_E3M4,,,,E3M4: Dům bolesti,E3M4: Hus af smerte,E3M4: Haus des Schmerzes,E3Χ4: Σπίτι του Πόνου,E3M4: Domo de Doloro,E3M4: Casa del Dolor,,E3M4: Tuskanmaja,E3M4: Maison de la Douleur,E3M4: A kínok háza,E3M4: Casa del Dolore,E3M4: 苦痛の館,E3M4: 고통의 집,E3M4: Huis van Pijn,E3M4: Smertens hus,E3M4: Dom Bólu,E3M4: Casa da Dor,,E3M4: Casa Durerii,E3M4: Обитель боли,E3M4: Кућа патње,E3M4: Smärtans hus,E3M4: Acı Evi +E3M5: Unholy Cathedral,HUSTR_E3M5,,,,E3M5: Bezbožná katedrála,E3M5: Uhellig katedral,E3M5: Unheilige Kathedrale,E3X5: Ανίερος Καθεδρικός,E3M5: Malsankta Katedralo,E3M5: Catedral Profana,,E3M5: Epäpyhä katedraali,E3M5: Cathédrale Profane,E3M5: Az istentelen katedrális ,E3M5: Cattedrale Blasfema,E3M5: 邪教の大聖堂,E3M5: 불경한 성당,E3M5: Onheilige Kathedraal,E3M5: Den vanhellige katedralen,E3M5: Bluźniercza Katedra,E3M5: Catedral Profana,,E3M5: Catedrala Necurată,E3M5: Нечестивый собор,E3M5: Несвета катедрала,E3M5: Den oheliga katedralen,E3M5: Kutsal Olmayan Katedral +E3M6: Mt. Erebus,HUSTR_E3M6,,,,E3M6: Hora Erebus,,,E3X6: Όρος Έρεβος,E3M6: Monto de Erebo,E3M6: Monte Erebus,,E3M6: Erebusvuori,E3M6: Mont Erèbe,E3M6: Erebus-hegy,E3M6: Monte Erebus,E3M6: エレボス山,E3M6: 에레버스 산,,E3M6: Erebus-fjellet,E3M6: Góra Erebus,E3M6: Monte Érebo,,E3M6: M. Erebus,E3M6: Гора Эребус,E3M6: Планина Еребус,,E3M6: Erebus Dağı +E3M7: Limbo,HUSTR_E3M7,,,,E3M7: Předpeklí,,,E3Χ7: Είσοδος της Κολάσεως,,,,E3M7: Limbus,E3M7: Limbes,E3M7: Limbus,,E3M7: 忘却の地,E3M7: 고성소,,,E3M7: Otchłań,,,E3M7: Limb,E3M7: Чистилище,E3M7: Лимбо,,E3M7: Araf +E3M8: Dis,HUSTR_E3M8,"Based on the City of Dis, located on the sixth circle of Hell, according to Dante Alighieri's The Divine Comedy",,,,,,E3Χ8: Δίτα,,,,,,,E3M8: Dite,E3M8: 死,E3M8: 디스,,,,E3M8: Dite,,E3M8: Dite,E3M8: Дит,E3M8: Дис,, +E3M9: Warrens,HUSTR_E3M9,,,,E3M9: Brlohy,E3M9: Rotteboet,E3M9: Rattennest,E3X9: Λαγούμια,E3M9: Nestego,E3M9: Madrigueras,,E3M9: Sokkelot,E3M9: Clapiers,E3M9: Nyúlkert,E3M9: Le Garenne,E3M9: 兎小屋,E3M9: 토끼굴,E3M9: Doolhof,E3M9: Rottebo,E3M9: Królikarnia,E3M9: Tocas,,E3M9: Vizuini,E3M9: Изнорье,E3M9: Одгајалиште,E3M9: Vildmark,E3M9: Sıçan yuvası +E4M1: Hell Beneath,HUSTR_E4M1,Proverbs 15:24,,,E4M1: Peklo v hlubinách,E4M1: Helvede nedenunder,E4M1: Die Hölle unterwärts,E4Χ1: Κάτω Κόσμος,E4M1: Ŝeolo Malsupre,E4M1: Bajo el Infierno,,E4M1: Tuonela alhaalla,E4M1: Le Séjour des Morts,E4M1: A holtak hazája odalent,E4M1: In Basso,E4M1: 地獄の下へ,E4M1: 지옥의 밑에서,E4M1: Hel beneden,E4M1: Helvete under,E4M1: Piekło Najgłębsze,E4M1: Inferno Abaixo,E4M1: Inferno Profundo,E4M1: Iadul de Jos,E4M1: Преисподняя под ногами,E4M1: Пакао одоздо,E4M1: Helvetet under,E4M1: Cehennem Altında +E4M2: Perfect Hatred,HUSTR_E4M2,Psalm 139:22,,,E4M2: Naprostá nenávist,E4M2: Perfekt had,E4M2: Perfekter Hass,E4Χ2: Τέλειο Μίσος,E4M2: Perfekta Malamo,E4M2: Odio Perfecto,,E4M2: Kaikella vihalla,E4M2: Une Parfaite Haine,E4M2: Teljes gyűlölettel,E4M2: Odio Perfetto,E4M2: 完全なる憎悪,E4M2: 완벽한 증오,E4M2: Perfecte Haat,E4M2: Perfekt hat,E4M2: Pełnia Nienawiści,E4M2: Ódio Perfeito,,E4M2: Ură Desăvârșită,E4M2: Полная ненависть,E4M2: Пуном мрзошћу,E4M2: Perfekt Hass,E4M2: Kusursuz Nefret +E4M3: Sever The Wicked,HUSTR_E4M3,Matthew 13:49,,,E4M3: Oddělit zkažené,E4M3: Afskære de onde,E4M3: Scheidet die Bösen,E4Χ3: Ξερίζωσε τους Πονηρούς,E4M3: Apartigi la Malbonulojn,E4M3: Cercena a los impíos,,E4M3: Erottavat pahat,E4M3: Séparer les Vicieux,E4M3: Felnégyelni a bűnösöket,E4M3: Separeranno I Cattivi,E4M3: 邪悪を絶つ,E4M3: 악령처단,E4M3: Scheid de goddelozen af,E4M3: Skille ut de onde,E4M3: Oddzielą Niegodziwych,E4M3: Separarão os Maus,E4M3: Separarão o Mal,E4M3: Să Desparți pe Cei Răi,E4M3: Отделить злых,E4M3: Одлучи зле,E4M3: Separera de onda,E4M3: Kötüleri Kesin +E4M4: Unruly Evil,HUSTR_E4M4,James 3:8,,,E4M4: Nezkrotitelné zlo,E4M4: Ustyrlig ondskab,E4M4: Schandbare Worte,E4X4: Ασυγκράτητο Κακό,E4M4: Neretenebla Malbono,E4M4: Maldad Incontrolable,,E4M4: Levotointa pahuutta,E4M4: Un Mal Irrépréssible,E4M4: Féktelen gonosz,E4M4: Male Senza Posa,E4M4: 手に負えない邪悪,E4M4: 광폭한 악마,E4M4: Het weerbarstige kwaad,E4M4: Uregjerlig ondskap,E4M4: Niepohamowane Zło,E4M4: Mal Irrefreável,E4M4: Mal que não Refreia,E4M4: Un Rău fără Astâmpăr,E4M4: Неудержимое зло,Е4М4: Немирно зло,E4M4: Den oregerliga ondskan,E4M4: Asi Kötülük +E4M5: They Will Repent,HUSTR_E4M5,Luke 16:30,,,E4M5: Budou činit pokání,E4M5: De vil omvende sig,E4M5: Sie werden bereuen,E4X5: Θα Μετανοήσουν,E4M5: Ili Pentos,E4M5: Se Arrepentirán,,E4M5: He parannuksen tekisivät,E4M5: Ils se repentiront,E4M5: Megtérnek majd,E4M5: Si Ravvederanno,E4M5: 奴等に後悔を,E4M5: 그들은 회개할 지어다,E4M5: Ze zullen berouw hebben,E4M5: De vil omvende seg,E4M5: Nawrócą Się,E4M5: Arrepender-se,E4M5: Eles Arrepender-se-iam,E4M5: Se vor Pocăi,E4M5: Они покаются,E4M5: Покајаће се,E4M5: De kommer att ångra sig,E4M5: Tövbe Edecekler +E4M6: Against Thee Wickedly,HUSTR_E4M6,Psalm 139:20,,,E4M6: Při svých pletichách,E4M6: Mod dig ondskabsfuldt,E4M6: Feinde erheben sich,E4X6: Κακόβουλα Εναντίον Σου,E4M6: Kontraŭ Vi Malvirte,E4M6: Perversamente contra ti,,E4M6: Sinusta petollisesti,E4M6: D'une manière criminelle,E4M6: Hitványul ellened,E4M6: Contro di te Malvagiamente,E4M6: 汝への悪逆,E4M6: 그대와 짖궂게 맞서다,E4M6: Tegen de goddeloze,E4M6: Mot deg ondskapsfullt,E4M6: Podstępnie Przeciw Tobie,E4M6: Malvadamente Contra Ti,,E4M6: Te Grăiesc de Rău,E4M6: Против тебя нечестиво,E4M6: Ружно на тебе,E4M6: Mot dig ondskan,E4M6: Sana Karşı Kötüce +E4M7: And Hell Followed,HUSTR_E4M7,Revelation 6:8,,,E4M7: A peklo šlo za ním,E4M7: Og Helvede fulgte efter,E4M7: Und die Hölle folgte,E4X7: Και η Κόλαση Ακολούθησε,E4M7: Kaj Hades Sekvis,E4M7: Y el Infierno Continuó,,E4M7: Ja Tuonela seurasi,E4M7: Et l'Enfer Suivit,E4M7: És a pokol követé azt,E4M7: E l'inferno seguitava,E4M7: そして地獄は従った,E4M7: 그리고 지옥이 뒤따른다,E4M7: En de hel volgde,E4M7: Og helvete fulgte,E4M7: A Piekło Szło Za Nim,E4M7: E o Inferno Seguia,E4M7: Inferno o Seguia,E4M7: Iadul se Ținea după El,E4M7: И последовал Ад,E4M7: И пакао иђаше,E4M7: Och helvetet följde,E4M7: Ve Cehennem Takip Etti +E4M8: Unto The Cruel,HUSTR_E4M8,Proverbs 5:9,,,E4M8: Ukrutníku odevzdáš,E4M8: Til de grusomme,E4M8: Deine Jahre dem Grausamen,E4X8: Προς Τους Ανελεήμονες,E4M8: Al La Kruelulo,E4M8: En lo Cruel,,E4M8: Armottomalle,E4M8: A un Homme cruel,E4M8: A kegyetlennek,E4M8: Al Crudele,E4M8: 容赦なき者へ,E4M8: 잔혹한 자에게로,E4M8: Naar de wrede,E4M8: Til de grusomme,E4M8: Kto Nie Zna Litości,E4M8: Aos Cruéis,E4M8: Entregue a Cruéis,E4M8: Unuia Fără de Milă,E4M8: К мучителю,E4M8: Немилостивоме,E4M8: Mot de grymma,E4M8: Zalimlere Karşı +E4M9: Fear,HUSTR_E4M9,,,,E4M9: Strach,E4M9: Frygt,E4M9: Angst,E4Χ9: Τρόμος,E4M9: Timo,E4M9: Miedo,,E4M9: Pelko,E4M9: Terreur,E4M9: Félelem,E4M9: Paura,E4M9: 恐怖,E4M9: 공포,E4M9: Angst,E4M9: Frykt,E4M9: Strach,E4M9: Medo,,E4M9: Frica,E4M9: Страх,E4M9: Страх,E4M9: Rädsla,E4M9: Korku +,,Doom 2,,,,,,,,,,,,,,,,,,,,,,,,, +Level 1: Entryway,HUSTR_1,"Note that the ""LEVEL"" part of the string will be stripped so it shouldn't be translated",,,Level 1: Vchod,Level 1: Indgang,Level 1: Eingangshalle,Επίπεδο 1: Είσοδος,Nivelo 1: Enirejo,Nivel 1: Entrada,,Taso 1: Eteiskäytävä,NIVEAU 1: Hall D'Entrée,1. Pálya: Bejárat,Livello 1: Ingresso,Level 1: 入口,레벨 1: 초입,Level 1: Ingang,Nivå 1: Inngangen,Level 1: Wejście,Fase 1: Entrada,Nível 1: Entrada,Nivelul 1: Intrarea,Уровень №1: Вход,Level 1: Улаз,Nivå 1: Ingång,Seviye 1: Giriş Yolu +Level 2: Underhalls,HUSTR_2,,,,Level 2: Podzemí,Level 2: Underbukser,Level 2: Kellergewölbe,,Nivelo 2: Subtervojoj,Nivel 2: Salones subterráneos,,Taso 2: Maanalaiset käytävät,NIVEAU 2: Souterrains,2. Pálya: Alagutak,Livello 2: Sotterranei,Level 2: 地下堂,레벨 2: 지하수로,Level 2: Onderhallen,Nivå 2: Underhaller,Level 2: Podziemia,Fase 2: Subterrâneo,Nível 2: Subterrâneo,Nivelul 2: Pasaje subterane,Уровень №2: Подземные ходы,Level 2: Подземни ходници,Nivå 2: Underhallar,Seviye 2: Tulumlar +Level 3: The Gantlet,HUSTR_3,“a form of punishment in which a person is forced to run between two lines of men facing each other and armed with clubs or whips to beat the victim”,,,Level 3: Trest,Level 3: Spidsrod,Level 3: Spießrutenlauf,,Nivelo 3: La Spaliro,Nivel 3: Carrera de baquetas,,Taso 3: Kujanjuoksu,NIVEAU 3: Parcours du Combatant,3. Pálya: Vesszőfutás,Livello 3: Le Forche,Level 3: ガントレット,레벨 3: 건틀릿,Level 3: De gantlet,Nivå 3: Hansken,Level 3: Praszczęta,Fase 3: A Punição,Nível 3: A Punição,Nivelul 3: Stroiul,Уровень №3: Сквозь строй,Level 3: Казна,Nivå 3: Utmaningen,Seviye 3: Zorluk +Level 4: The Focus,HUSTR_4,,,,Level 4: Ohnisko,Level 4: Fokus,Level 4: Der Fokus,,Nivelo 4: La Fokuso,Nivel 4: El Foco,,Taso 4: Polttopiste,NIVEAU 4: Le Focus,4. Pálya: A középpont,Livello 4: L'Epicentro,Level 4: フォーカス,레벨 4: 초점,Level 4: De focus,Nivå 4: Fokus,Level 4: Skupisko,Fase 4: O Foco,Nível 4: O Foco,Nivelul 4: Focarul,Уровень №4: Средоточие,Level 4: Средиште,Nivå 4: Fokus,Seviye 4: Odaklanma +Level 5: The Waste Tunnels,HUSTR_5,,,,Level 5: Odpadní tunely,Level 5: Affaldstunnellerne,Level 5: Die Abfall-Tunnel,Επίπεδο 5: Οι Σήραγγες Αποβλήτων,Nivelo 5: La Rubtuneloj,Nivel 5: Los Túneles de Desechos,,Taso 5: Jätetunnelit,NIVEAU 5: Les Egouts,5. Pálya: Szennyvízalagutak,Livello 5: I Tunnel dei Rifiuti,Level 5: 廃棄トンネル,레벨 5: 하수도,Level 5: De afvaltunnels,Nivå 5: Avfallstunnelene,Level 5: Kanały,Fase 5: Os Túneis de Dejetos,Nível 5: Os Túneis de Dejetos,Nivelul 5: Tuneluri de deșeuri,Уровень №5: Сточные туннели,Level 5: Отпадни тунели,Nivå 5: Avfallstunnlarna,Seviye 5: Atık Tünelleri +Level 6: The Crusher,HUSTR_6,,,,Level 6: Drtička,Level 6: Knuseren,Level 6: Die Presse,Επίπεδο 6: Ο Συνθλιπτής,Nivelo 6: La Dispistilo,Nivel 6: La Trituradora,,Taso 6: Murskaaja,NIVEAU 6: Le Broyeur,6. Pálya: A zúzda,Livello 6: La Pressa,Level 6: クラッシャー,레벨 6: 분쇄기,Level 6: De maalmachine,Nivå 6: Knuseren,Level 6: Zgniatarka,Fase 6: O Esmagador,Nível 6: O Esmagador,Nivelul 6: Zdrobitorul,Уровень №6: Давилка,Level 6: Разбијач,Nivå 6: krossen,Seviye 6: Kırıcı +Level 7: Dead Simple,HUSTR_7,,,,Level 7: Smrtelně prosté,Level 7: Død simpel,Level 7: Tödlich einfach,Επίπεδο 7: Πανεύκολο,Nivelo 7: Morte Simpla,Nivel 7: Simplemente Muerto,,Taso 7: Kuolettavan yksinkertainen,NIVEAU 7: Mortellement Simple,7. Pálya: Halálegyszerű,Livello 7: Morte Pura,Level 7: 死ぬほど単純,레벨 7: 죽여주는 단순함,Level 7: Dodelijk eenvoudig,Nivå 7: Helt enkelt,Level 7: Śmiertelnie Proste,Fase 7: Mortalmente Simples,Nível 7: Simplesmente Mortal,Nivelul 7: Mortal de simplu,Уровень №7: Смертельно просто,Level 7: Смртно једноставно,Nivå 7: Död enkel,Seviye 7: Ölü Basit +Level 8: Tricks and Traps,HUSTR_8,,,,Level 8: Lesti a léčky,Level 8: Tricks og fælder,Level 8: Tricks und Fallen,Επίπεδο 8: Κόλπα και Παγίδες,Nivelo 8: Trompoj kaj embuskoj,Nivel 8: Trucos y Trampas,,Taso 8: Metkuja ja pauloja,NIVEAU 8: Ruses et Pièges,8. Pálya: Cselek és csapdák,Livello 8: Trucchi e Trappole,Level 8: 悪戯と罠,레벨 8: 속임수와 함정들,Level 8: Trucs en vallen,Nivå 8: Triks og feller,Level 8: Sztuczki i Pułapki,Fase 8: Truques e Armadilhas,Nível 8: Truques e Armadilhas,Nivelul 9: Surprize și capcane,Уровень №8: Уловки и ловушки,Level 8: Замке и смицалице,Nivå 8: Tricks och fällor,Seviye 8: Hileler ve Tuzaklar +Level 9: The Pit,HUSTR_9,,,,Level 9: Jáma,Level 9: Gruben,Level 9: Die Grube,Επίπεδο 9: Λάκκος,Nivelo 9: La Fosaĵo,Nivel 9: El Pozo,,Taso 9: Monttu,NIVEAU 9: La Fosse,9. Pálya: A gödör,Livello 9: Il Pozzo,Level 9: 大穴,레벨 9: 구덩이,Level 9: De groeve,Nivå 9: Gropen,Level 9: Dół,Fase 9: O Fosso,Nível 9: O Fosso,Nivelul 9: Groapa,Уровень №9: Яма,Level 9: Јама,Nivå 9: Grottan,Seviye 9: Çukur +Level 10: Refueling Base,HUSTR_10,,,,Level 10: Tankovací základna,Level 10: Tankstation,Level 10: Treibstoffbunker,Επίπεδο 10: Βάση Ανεφοδιασμού,Nivelo 10: Refuelbazo,Nivel 10: Base de Reabastecimiento,,Taso 10: Tankkausasema,NIVEAU 10: Base de Ravitaillement,10. Pálya: Tankolóállomás,Livello 10: Base di Rifornimento,Level 10: 補給基地,레벨 10: 연료 충전소,Level 10: Tankstation,Nivå 10: Påfyllingsbasen,Level 10: Stacja Tankowania,Fase 10: Base de Reabastecimento,Nível 10: Base de Reabastecimento,Nivelul 10: Baza de alimentare,Уровень №10: Заправочная база,Level 10: Бензинска база,Nivå 10: Tankningsbasen,Seviye 10: Yakıt İkmal Üssü Level 11: 'O' of Destruction!,HUSTR_11,"Alternative title: -Circle of Death ",,,Level 11: Kruh smrti,Level 11: Ødelæggelsens cirkel!,Level 11: 'O' der Zerstörung!,Επίπεδο 11: Ο Κύκλος της Καταστροφής,Nivelo 11: Morta cirklo,Nivel 11: Círculo de la muerte,,Taso 11: Hävityksen 'O',NIVEAU 11: Le Cercle de la Mort!,11. Pálya: A pusztulás köre,Livello 11: Il Cerchio della Morte,Level 11: 破滅の'O'!,레벨 11: 파괴의 고리,Level 11: 'O' van vernietiging!,Nivå 11: Ødeleggelsens 'O'!,Level 11: Krąg Śmierci,Fase 11: Círculo da Morte,Nível 11: Círculo da Morte,Nivelul 11: Cercul distrugerii,Уровень №11: Круг разрушения!,Level 11: Круг уништења,Seviye 11: Yıkımın 'O'su! -Level 12: The Factory,HUSTR_12,,,,Level 12: Továrna,Level 12: Fabrikken,Level 12: Die Fabrik,Επίπεδο 12: To Εργοστάσιο,Nivelo 12: La Fabriko,Nivel 12: La Fábrica,,Taso 12: Tehdas,NIVEAU 12: L'Usine,12. Pálya: A gyár,Livello 12: La Fabbrica,Level 12: 工場,레벨 12: 공장,Level 12: De fabriek,Nivå 12: Fabrikken,Level 12: Fabryka,Fase 12: A Fábrica,Nível 12: A Fábrica,Nivelul 12: Fabrica,Уровень №12: Фабрика,Level 12: Фабрика,Seviye 12: Fabrika -Level 13: Downtown,HUSTR_13,,,,Level 13: Centrum,Level 13: Centrum,Level 13: Stadtzentrum,Επίπεδο 13: Κέντρο,Nivelo 13: Urbocentro,Nivel 13: Centro de la Ciudad,,Taso 13: Keskikaupunki,NIVEAU 13: Centre-Ville,13. Pálya: Belváros,Livello 13: Periferia,Level 13: 市内,레벨 13: 번화가,Level 13: De binnenstad,Nivå 13: Sentrum,Level 13: Śródmieście,Fase 13: Centro Urbano,Nível 13: Centro Urbano,Nivelul 13: Centru urban,Уровень №13: Центр города,Level 13: Центар града,Seviye 13: Şehir Merkezi -Level 14: The Inmost Dens,HUSTR_14,,,,Level 14: Nejhlubší doupata,Level 14: Den inderste hule,Level 14: Die innersten Bauten,Επίπεδο 14: Οι Ενδότερες Φωλιές,Nivelo 14: La Internaj Kavernoj,Nivel 14: Los Antros más Recónditos,,Taso 14: Sisimmät piilot,NIVEAU 14: Les Antres Profondes,14. Pálya: A legmélyebb rejtekek,Livello 14: Gli Antri Profondi,Level 14: 最深巣窟,레벨 14: 깊숙한 동굴들,Level 14: De binnenste gebouwen,Nivå 14: De innerste huler,Level 14: Najgłębsze Nory,Fase 14: Os Antros Profundos,Nível 14: Os Antros Profundos,Nivelul 14: Cele mai intime bârloguri,Уровень №14: Глубочайшие логовища,Level 14: Најдубље јазбине,Seviye 14: En İçteki İnler -Level 15: Industrial Zone,HUSTR_15,,,,Level 15: Průmyslová zóna,Level 15: Industriområde,Level 15: Industriegebiet,Επίπεδο 15: Βιομηχανική Ζώνη,Nivelo 15: Industria Zono,Nivel 15: Zona Industrial,,Taso 15: Teollisuusalue,NIVEAU 15: Zone Industrielle,15. Pálya: Ipari zóna,Livello 15: Zona Industriale,Level 15: 工業地帯,레벨 15: 공업 지대,Level 15: Industriegebied,Nivå 15: Industriområdet,Level 15: Strefa Przemysłowa,Fase 15: Zona Industrial,Nível 15: Zona Industrial,Nivelul 15: Zona industrială,Уровень №15: Промышленный район,Level 15: Индустријска зона,Seviye 15: Sanayi Bölgesi -Level 16: Suburbs,HUSTR_16,,,,Level 16: Předměstí,Level 16: Forstæderne,Level 16: Vororte,Επίπεδο 16: Προάστια,Nivelo 16: Antaŭurboj,Nivel 16: Suburbios,,Taso 16: Lähiö,NIVEAU 16: Banlieue,16. Pálya: Külváros,Livello 16: Sobborghi,Level 16: 郊外,레벨 16: 교외,Level 16: Buitenwijken,Nivå 16: Forstedene,Level 16: Przedmieścia,Fase 16: Subúrbios,Nível 16: Subúrbios,Nivelul 16: Suburbi,Уровень №16: Пригород,Level 16: Предграђе,Seviye 16: Banliyöler -Level 17: Tenements,HUSTR_17,,,,Level 17: Sídliště,Level 17: Lejligheder,Level 17: Wohnbezirk,Επίπεδο 17: Καταλύματα,Nivelo 17: Loĝejoj,Nivel 17: Viviendas,,Taso 17: Vuokratalot,NIVEAU 17: Immeubles,17. Pálya: Bérházak,Livello 17: Possedimenti,Level 17: 安アパート,레벨 17: 공동주택,Level 17: Huurwoningen,Nivå 17: Leiegårder,Level 17: Kamienice,Fase 17: Habitações,Nível 17: Habitações,Nivelul 17: Proprietăți,Уровень №17: Владения,Level 17: Станови,Seviye 17: Kiralık Evler -Level 18: The Courtyard,HUSTR_18,,,,Level 18: Nádvoří,Level 18: Gårdspladsen,Level 18: Der Innenhof,Επίπεδο 18: Η Αυλή,Nivelo 18: La Korto,Nivel 18: El Patio,,Taso 18: Esipiha,NIVEAU 18: La Cour,18. Pálya: Az udvar,Livello 18: Il Cortile,Level 18: 中庭,레벨 18: 중정,Level 18: De binnenplaats,Nivå 18: Gårdsplassen,Level 18: Dziedziniec,Fase 18: O Átrio,Nível 18: O Átrio,Nivelul 18: Curtea,Уровень №18: Внутренний двор,Level 18: Двориште,Seviye 18: Avlu -Level 19: The Citadel,HUSTR_19,,,,Level 19: Citadela,Level 19: Citadellet,Level 19: Die Zizadelle,Επίπεδο 19: Το Κάστρο,Nivelo 19: La Citadelo,Nivel 19: La Ciudadela,,Taso 19: Linnoitus,NIVEAU 19: La Citadelle,19. Pálya: Fellegvár,Livello 19: La Cittadella,Level 19: 要塞,레벨 19: 성채,Level 19: De citadel,Nivå 19: Citadellet,Level 19: Cytadela,Fase 19: A Cidadela,Nível 19: A Cidadela,Nivelul 19: Cetatea,Уровень №19: Цитадель,Level 19: Цитадела,Seviye 19: Hisar -Level 20: Gotcha!,HUSTR_20,,,,Level 20: Mám tě!,,Level 20: Erwischt!,Επίπεδο 20: Σ'έπιασα!,Nivelo 20: Kaptis Vin!,Nivel 20: ¡Te pillé!,Nivel 20: ¡Te tengo!,Taso 20: Sainpas sinut!,NIVEAU 20: Je t'ai eu!,20. Pálya: Megvagy!,Livello 20: Preso!,Level 20: 捉らえた!,레벨 20: 잡았다!,Level 20: Ik heb je!,Nivå 20: Fikk deg!,Level 20: Mam Cię!,Fase 20: Te Peguei!,Nível 20: Apanhei-te!,Nivelul 20: Te-am prins!,Уровень №20: Попался!,Level 20: Имају те!,Seviye 20: Yakaladım! -Level 21: Nirvana,HUSTR_21,,,,Level 21: Nirvána,,,Επίπεδο 21: Νιρβάνα,Nivelo 21: Nirvano,Nivel 21: Nirvana,,,NIVEAU 21: Nirvana,21. Pálya: Nirvána,Livello 21: Nirvana,Level 21: 涅槃,레벨 21: 열반,,,Level 21: Nirvana,Fase 21: Nirvana,Nível 21: Nirvana,Nivelul 21: Nirvana,Уровень №21: Нирвана,Level 21: Нирвана,Seviye 21: Nirvana -Level 22: The Catacombs,HUSTR_22,,,,Level 22: Katakomby,Level 22: Katakomberne,Level 22: Katakomben,Επίπεδο 22: Οι Κατακόμβες,Nivelo 22: La Katakomboj,Nivel 22: Las Catacumbas,,Taso 22: Katakombit,NIVEAU 22: Les Catacombes,22. Pálya: A katakombák,Livello 22: Le Catacombe,Level 22: 地下悪霊墓所,레벨 22: 지하 묘지,Level 22: De catacomben,Nivå 22: Katakombene,Level 22: Katakumby,Fase 22: As Catacumbas,Nível 22: Os Calabouços,Nivelul 22: Catacombe,Уровень №22: Катакомбы,Level 22: Катакомбе,Seviye 22: Yeraltı Mezarları -Level 23: Barrels O' Fun,HUSTR_23,,,,Level 23: Barely srandy,Level 23: Tønder af sjov,Level 23: Lustige Fässer,,Nivelo 23: Bareloj de Amuzo,Nivel 23: Barriles de Diversión,,Taso 23: Huvitynnyrit,NIVEAU 23: Une Tonne-eau de plaisir,23. Pálya: Mókás hordók,Livello 23: Barili da Sballo,Level 23: 戯れのバレル,레벨 23: 신나는 폭발통들,Level 23: Grappige vaten,Nivå 23: Tønner med moro,Level 23: Beczki Śmiechu,Fase 23: Barris de Diversão,Nível 23: Barris de Diversão,Nivelul 23: Butoaiele veseliei,Уровень №23: Бочки веселья,Level 23: Бачве забаве,Seviye 23: Eğlence Fıçıları -Level 24: The Chasm,HUSTR_24,,,,Level 24: Rokle,Level 24: Kløften,Level 24: Die Kluft,Επίπεδο 24: Το Χάσμα,Nivelo 24: La Fendego,Nivel 24: El Desfiladero,,Taso 24: Rotko,NIVEAU 24: Le Gouffre,24. Pálya: A szakadék,Livello 24: L'Abisso,Level 24: 裂け目,레벨 24: 협곡,Level 24: De afgrond,Nivå 24: Avgrunnen,Level 24: Przepaść,Fase 24: O Abismo,Nível 24: O Abismo,Nivelul 24: Hăul,Уровень №24: Пропасть,Level 24: Провалија,Seviye 24: Uçurum -Level 25: Bloodfalls,HUSTR_25,,,,Level 25: Krvopády,Level 25: Blodfald,Level 25: Blutfälle,Επίπεδο 25: Καταρράκτες Αίματος,Nivelo 25: Sangfaloj,Nivel 25: Cataratas de Sangre,,Taso 25: Veriputoukset,NIVEAU 25: Chutes de Sang,25. Pálya: Véresések,Livello 25: Cascate di Sangue,Level 25: 血の滝,레벨 25: 혈폭포,Level 25: Bloeddruppels,Nivå 25: Blodfall,Level 25: Wodospad Krwi,Fase 25: Cataratas de Sangue,Nível 25: Cascatas de Sangue,Nivelul 25: Cascade de sânge,Уровень №25: Кровопады,Level 25: Крвопади,Seviye 25: Kan Düşüşleri -Level 26: The Abandoned Mines,HUSTR_26,,,,Level 26: Opuštěné doly,Level 26: De forladte miner,Level 26: Die aufgegebene Mine,Επίπεδο 26: Τα Εγκαταλελειμμένα Ορυχεία,Nivelo 26: La Forlasitaj Minoj,Nivel 26: Las Minas Abandonadas,,Taso 26: Hylätyt kaivokset,NIVEAU 26: Les Mines Abandonnées,26. Pálya: Az elhagyatott bányák,Livello 26: Le Miniere Abbandonate,Level 26: 廃鉱山,레벨 26: 버려진 광산,Level 26: De verlaten mijnen,Nivå 26: De forlatte gruvene,Level 26: Opuszczone Kopalnie,Fase 26: As Minas Abandonadas,Nível 26: As Minas Abandonadas,Nivelul 26: Minele părăsite,Уровень №26: Заброшенные шахты,Level 26: Напуштени рудници,Seviye 26: Terk Edilmiş Madenler -Level 27: Monster Condo,HUSTR_27,,,,Level 27: Netvoří dům,,Level 27: Monsterbehausung,,Nivelo 27: Monstro-Domo,Nivel 27: Condominio de Monstruos,,Taso 27: Hirviöasuntola,NIVEAU 27: Monstrueuse Résidence,27. Pálya: A szörnyek háza,Livello 27: Casa dei Mostri,Level 27: モンスターマンション,레벨 27: 괴물 콘도,,Nivå 27: Monsterleiligheten,Level 27: Apartament Potworów,Fase 27: Mansão dos Monstros,Nível 27: Condomínio Monstruoso,Nivelul 27: Casa monștrilor,Уровень №27: Жилище монстров,Level 27: Боравишта монструма,Seviye 27: Canavar Dairesi -Level 28: The Spirit World,HUSTR_28,,,,Level 28: Onen svět,Level 28: Åndeverdenen,Level 28: Die Geisterwelt,Επίπεδο 28: Ο Κόσμος των Πνευμάτων,Nivelo 28: La Animo-Mondo,Nivel 28: El Mundo Espiritual,,Taso 28: Henkimaailma,NIVEAU 28: Le Monde Spirituel,28. Pálya: A lelkek világa,Livello 28: Il Mondo dello Spirito,Level 28: 悪霊の世界,레벨 28: 영령의 세계,Level 28: De geestenwereld,Nivå 28: Åndeverdenen,Level 28: Świat Dusz,Fase 28: O Mundo Espiritual,Nível 28: O Mundo Espiritual,Nivelul 28: Lumea duhurilor,Уровень №28: Мир духов,Level 28: Духовни свет,Seviye 28: Ruhlar Dünyası -Level 29: The Living End,HUSTR_29,,,,Level 29: Živoucí konec,Level 29: Den levende ende,Level 29: Das lebende Ende,Επίπεδο 29: Το Ζωντανό Τέλος,Nivelo 29: La Viva Fino,Nivel 29: El Final Viviente,,Taso 29: Elävä loppu,NIVEAU 29: La Limite,29. Pálya: Az élő Végzet,Livello 29: La Fine Imminente,Level 29: 極限の存在,레벨 29: 최종점,Level 29: Het levende einde,Nivå 29: Den levende enden,Level 29: Żywy Koniec,Fase 29: O Cúmulo da Existência,Nível 29: O Cúmulo da Existência,Nivelul 29: Sfârșitul întregii vieți,Уровень №29: Конец всего живого,Level 29: Крај живота,Seviye 29: Yaşamın Sonu -Level 30: Icon of Sin,HUSTR_30,,,,Level 30: Ikona hříchu,Level 30: Syndens ikon,Level 30: Symbol der Sünde,Επίπεδο 30: Σύμβολο της Αμαρτίας,Nivelo 30: Ikono de Peko,Nivel 30: Icono del pecado,Nivel 30: Ícono del pecado,Taso 30: Synnin ikoni,NIVEAU 30: L'Icône du Péché,30. Pálya: A megtestesült bűn,Livello 30: Icona del Peccato,Level 30: 罪の聖像,레벨 30: 죄악의 상징,Level 30: Pictogram van de zonde,Nivå 30: Syndens ikon,Level 30: Ikona Grzechu,Fase 30: Ícone do Pecado,Nível 30: Ícone do Pecado,Nivelul 30: Icoana păcatelor,Уровень №30: Икона греха,Level 30: Икона греха,Seviye 30: Günah Simgesi -Level 31: Wolfenstein,HUSTR_31,,,,,,,,Nivelo 31: Wolfenstein,Nivel 31: Wolfenstein,,,,31. Pálya: Wolfenstein,Livello 31: Wolfenstein,Level 31: ウルフェンシュタイン,레벨 31: 울펜슈타인,,,Level 31: Wolfenstein,Fase 31: Wolfenstein,Nível 31: Wolfenstein,Nivelul 31: Wolfenstein,Уровень №31: Вольфенштайн,Level 31: Волфенштајн,Seviye 31: Wolfenstein -Level 32: Grosse,HUSTR_32,,,,,,,,Nivelo 32: Grosse,Nivel 32: Grosse,,,,32. Pálya: Grosse,Livello 32: Grosse,Level 32: グローシュ,레벨 32: 그로세,,,Level 32: Grosse,Fase 32: Grosse,Nível 32: Grosse,Nivelul 32: Grosse,Уровень №32: Гросс,Level 32: Гроссе,Seviye 32: Grosse -Level 31: IDKFA,HUSTR_31B,,,,,,,,Nivelo 31: IDKFA,Nivel 31: IDKFA,,,NIVEAU 31: IDKFQ,31. Pálya: IDKFA,Livello 31: IDKFA,Level 31: IDKFA,레벨 31: IDKFA,,,Level 31: IDKFA,Fase 31: IDKFA,Nível 31: IDKFA,Nivelul 31: IDKFA,Уровень №31: IDKFA,,Seviye 31: IDKFA -Level 32: Keen,HUSTR_32B,,,,,,,,Nivelo 32: Keen,Nivel 32: Keen,,,,32. Pálya: Keen,Livello 32: Keen,Level 32: キーン,레벨 32: 킨,,,Level 32: Keen,Fase 32: Keen,Nível 32: Keen,Nivelul 32: Keen,Уровень №32: Кин,Level 32: Кин,Seviye 32: Keen -Level 33: Betray,HUSTR_33,,,,Level 33: Zraď,Level 33: Forræderi,Level 33: Verrat,,Nivelo 33: Perfido,Nivel 33: Traición,,Taso 33: Petä,NIVEAU 33: Trahison,33. Pálya: Árulás,Livello 33: Tradimento ,Level 33: 裏切り,레벨 33: 배반,Level 33: Verraad,Nivå 33: Forråde,Level 33: Zdrada,Fase 33: Traição,Nível 33: Traição,Nivelul 33: Trădare,Уровень №33: Предай,Level 33: Издаја,Seviye 33: İhanet -,,No Rest For The Living,,,,,,,,,,,,,,,,,,,,,,,, -Level 1: The Earth Base,NHUSTR_1,,,,Level 1: Pozemská základna,Level 1: Jordbasen,Level 1: Die Erd-Basis,,Nivelo 1: La Tera Bazo,Nivel 1: La Base Terrestre,,Taso 1: Maatukikohta,NIVEAU 1: La Base Terrienne,1. Pálya: A földi bázis,Livello 1: La Base Terrestre ,Level 1: 地球基地,레벨 1: 지구 기지,Level 1: De basis van de aarde,Nivå 1: Jordbasen,Level 1: Ziemska Baza,Fase 1: A Base Terrestre,Nível 1: A Base Terrestre,Nivelul 1: Baza terestră,Уровень №1: База на Земле,Level 1: Земаљска база,Seviye 1: Dünya Üssü -Level 2: The Pain Labs,NHUSTR_2,,,,Level 2: Laboratoře bolesti,Level 2: Smerte laboratorier,Level 2: Die Folterlabore,,Nivelo 2: La Doloro-Laboratorio,Nivel 2: Los Laboratorios del Dolor,,Taso 2: Tuskalaboratoriot,NIVEAU 2: Les Laboratoires de la Douleur,2. Pálya: A kínok laboratóriuma,Livello 2: I Laboratori del Dolore,Level 2: 生物工学実験室,레벨 2: 고통의 연구소,Level 2: De pijnlaboratoria,Nivå 2: Smertelaboratoriet,Level 2: Laboratoria Bólu,Fase 2: Os Laboratórios da Dor,Nível 2: Os Laboratórios da Dor,Nivelul 2: Laboratoarele durerii,Уровень №2: Лаборатории боли,Level 2: Лабораторије патње,Seviye 2: Ağrı Laboratuvarları -Level 3: Canyon of The Dead,NHUSTR_3,,,,Level 3: Kaňon mrtvých,Level 3: De dødes kløft,Level 3: Schlucht der Toten,,Nivelo 3: Kanjono de La Mortintoj,Nivel 3: Cañón de los Muertos,,Taso 3: Kalmankanjoni,NIVEAU 3: Canyon des Morts,3. Pálya: A holtak szurdoka,Livello 3: Il Canyon dei Morti,Level 3: 死の渓谷,레벨 3: 죽음의 계곡,Level 3: Canyon van de doden,Nivå 3: De dødes kløft,Level 3: Kanion Umarłych,Fase 3: Desfiladeiro dos Mortos,Nível 3: Desfiladeiro dos Mortos,Nivelul 3: Canionul morților,Уровень №3: Каньон мертвецов,Level 3: Кањон мртваца,Seviye 3: Ölüler Kanyonu -Level 4: Hell Mountain,NHUSTR_4,,,,Level 4: Pekelná hora,Level 4: Helvede bjerg,Level 4: Höllenberg,,Nivelo 4: Monto de Infero,Nivel 4: Montaña Infernal,,Taso 4: Hornanvuori,NIVEAU 4: Montagne Infernale,4. Pálya: Pokol-hegy,Livello 4: Montagna Infernale ,Level 4: 地獄山脈,레벨 4: 지옥의 산,Level 4: Helleberg,Nivå 4: Helvetesfjellet,Level 4: Piekielna Góra,Fase 4: Montanha Infernal,Nível 4: Montanha Infernal,Nivelul 4: Muntele infernal,Уровень №4: Адская гора,Level 4: Планина пакла,Seviye 4: Cehennem Dağı -Level 5: Vivisection,NHUSTR_5,,,,Level 5: Vivisekce,Level 5: Vivisektion,Level 5: Vivisektion,,Nivelo 5: Vivisekcio,Nivel 5: Vivisección,,Taso 5: Vivisektio,NIVEAU 5: Vivisection,5. Pálya: Élveboncolás,Livello 5: Vivisezione ,Level 5: 生体解剖,레벨 5: 생체 해부,Level 5: Vivisectie,Nivå 5: Viviseksjon,Level 5: Wiwisekcja,Fase 5: Vivissecção,Nível 5: Vivissecção,Nivelul 5: Vivisecție,Уровень №5: Вивисекция,Level 5: Вивисекција,Seviye 5: Canlı Kesim -Level 6: Inferno of Blood,NHUSTR_6,,,,Level 6: Krvavé inferno,Level 6: Blodets inferno,Level 6: Blutiges Inferno,,Nivelo 6: Brulego de Sango,Nivel 6: Hoguera de Sangre,,Taso 6: Veri-inferno,NIVEAU 6: Enfer Sanglant,6. Pálya: Véres alvilág,Livello 6: Inferno di Sangue ,Level 6: 血のインフェルノ,레벨 6: 연옥의 피,Level 6: Bloederige inferno,Nivå 6: Blodets inferno,Level 6: Piekło Krwi,Fase 6: Inferno de Sangue,Nível 6: Inferno de Sangue,Nivelul 6: Infern sângeriu,Уровень №6: Кровавая преисподняя,Level 6: Ватре крви,Seviye 6: Kan Cehennemi -Level 7: Baron's Banquet,NHUSTR_7,,,,Level 7: Baronova hostina,Level 7: Baron's Banquet,Level 7: Das Bankett des Barons,,Nivelo 7: Festeno de Barono,Nivel 7: Banquete del Barón,,Taso 7: Paronin pidot,NIVEAU 7: Banquet du Baron,7. Pálya: A báró bankettje,Livello 7: Il Banchetto del Barone ,Level 7: バロンの晩餐,레벨 7: 남작의 연회,Level 7: Baron's banket,Nivå 7: Baronens bankett,Level 7: Bankiet Barona,Fase 7: Banquete do Barão,Nível 7: Banquete do Barão,Nivelul 7: Banchetul baronilor,Уровень №7: Банкет у барона,Level 7: Баронова Гозба,Seviye 7: Baron'un Ziyafeti -Level 8: Tomb of Malevolence,NHUSTR_8,,,,Level 8: Hrobka zlovolnosti,Level 8: Ondskabens grav,Level 8: Feindselige Gruft,,Nivelo 8: Tombo de Malbonvolo,Nivel 8: Tumba de Malevolencia,,Taso 8: Pahantahdon hauta,NIVEAU 8: Tombe Maléfique,8. Pálya: A Gátlástalanság sírja,Livello 8: Tomba della Malevolenza,Level 8: 悪意の墓,레벨 8: 증오의 무덤,Level 8: Graf van kwaadwilligheid,Nivå 8: Ondskapens grav,Level 8: Grobowiec Zła,Fase 8: Tumba da Malevolência,Nível 8: Túmulo da Malevolência,Nivelul 8: Mormântul răutății,Уровень №8: Гробница злобы,Level 8: Гроб злобе,Seviye 8: Kötülük Mezarı -Level 9: March of The Demons,NHUSTR_9,,,,Level 9: Pochod démonů,Level 9: Dæmonernes march,Level 9: Marsch der Dämonen,,Nivelo 9: Marŝo de La Demonoj,Nivel 9: Marcha de los Demonios,,Taso 9: Demonien marssi,NIVEAU 9: Marche des Démons,9. Pálya: A démonok parádéja,Livello 9: La Marcia dei Demoni ,Level 9: デーモンの行進,레벨 9: 악마들의 행진,Level 9: Maart van de demonen,Nivå 9: Demonenes marsj,Level 9: Marsz Demonów,Fase 9: Marcha dos Demônios,Nível 9: Marcha dos Demônios,Nivelul 9: Marșul demonilor,Уровень №9: Шествие демонов,Level 9: Марш демона,Seviye 9: Şeytanların Yürüyüşü -,,Plutonia,,,,,,,,,,,,,,,,,,,,,,,, -Level 1: Congo,PHUSTR_1,,,,Level 1: Kongo,,Level 1: Kongo,,Nivelo 1: Kongo,Nivel 1: Congo,,Taso 1: Kongo,NIVEAU 1: Congo,1. Pálya: Kongó,Livello 1: Congo,Level 1: コンゴ川,레벨 1: 콩고,Level 1: Kongo,Nivå 1: Kongo,Level 1: Kongo,Fase 1: Congo,Nível 1: Congo,Nivelul 1: Congo,Уровень №1: Конго,Level 1: Конго,Seviye 1: Kongo -Level 2: Well of Souls,PHUSTR_2,,,,Level 2: Studna duší,Level 2: Sjælebrønden,Level 2: Seelenbrunnen,,Nivelo 2: Puto de Animoj,Nivel 2: Pozo de Almas,,Taso 2: Sielujen lähde,NIVEAU 2: Puits des Ames,2. Pálya: A lelkek kútja,Livello 2: Pozzo delle Anime,Level 2: 魂の井戸,레벨 2: 영혼의 우물,Level 2: Bron van zielen,Nivå 2: Sjelenes brønn,Level 2: Studnia Dusz,Fase 2: Poço das Almas,Nível 2: Poço de Almas,Nivelul 2: Fântâna sufletelor,Уровень №2: Колодец душ,Level 2: Бунар душа,Seviye 2: Ruhlar Kuyusu -Level 3: Aztec,PHUSTR_3,,,,Level 3: Azték,Level 3: Azteker,Level 3: Aztekisch,,Nivelo 3: Azteko,Nivel 3: Azteca,,Taso 3: Asteekki,NIVEAU 3: Aztèque,3. Pálya: Azték,Livello 3: Aztec,Level 3: アステカ,레벨 3: 아즈텍,Level 3: Azteken,Nivå 3: Aztekisk,Level 3: Aztek,Fase 3: Asteca,Nível 3: Asteca,Nivelul 3: Aztec,Уровень №3: Ацтек,Level 3: Астек,Seviye 3: Aztek -Level 4: Caged,PHUSTR_4,,,,Level 4: V kleci,Level 4: Låst op,Level 4: Eingesperrt,,Nivelo 4: Enkaĝigita,Nivel 4: Enjaulado,,Taso 4: Häkissä,NIVEAU 4: Enfermé,4. Pálya: Ketrecbe zárva,Livello 4: Ingabbiato,Level 4: 檻の中,레벨 4: 갇히다,Level 4: Gekooid,Nivå 4: Buret,Level 4: W Klatce,Fase 4: Na Jaula,Nível 4: Na Jaula,Nivelul 4: Încarcerat,Уровень №4: В клетке,Level 4: Заробљен,Seviye 4: Kafesli -Level 5: Ghost Town,PHUSTR_5,,,,Level 5: Město duchů,Level 5: Spøgelsesby,Level 5: Geisterstadt,,Nivelo 5: Fantomurbeto,Nivel 5: Pueblo Fantasma,,Taso 5: Aavekaupunki,NIVEAU 5: Ville Fantôme,5. Pálya: Szellemváros,Livello 5: Città Fantasma,Level 5: ゴーストタウン,레벨 5: 유령 도시,Level 5: Spookstad,Nivå 5: Spøkelsesbyen,Level 5: Miasto Duchów,Fase 5: Cidade Fantasma,Nível 5: Cidade Fantasma,Nivelul 5: Orașul fantomă,Уровень №5: Город-призрак,Level 5: Град духова,Seviye 5: Hayalet Kasaba -Level 6: Baron's Lair,PHUSTR_6,,,,Level 6: Baronovo doupě,Level 6: Baronens hule,Level 6: Lager des Barons,,Nivelo 6: Nestego de Barono,Nivel 6: Guarida del Barón,,Taso 6: Paronin luola,NIVEAU 6: Repaire du Baron,6. Pálya: A báró rejteke,Livello 6: Tana del Barone,Level 6: バロンの隠れ家,레벨 6: 남작의 은신처,Level 6: Baron's kamp,Nivå 6: Baronens hule,Level 6: Legowisko Barona,Fase 6: Covil do Barão,Nível 6: Covil do Barão,Nivelul 6: Claustrul Baronului,Уровень №6: Обитель барона,Level 6: Баронова јазбина,Seviye 6: Baron'un İni -Level 7: Caughtyard,PHUSTR_7,,,,Level 7: Karcer,,Level 7: Gehege,,Nivelo 7: Kaptkorto,Nivel 7: Campo de Concentración,,Taso 7: Posenpiha,NIVEAU 7: Pris de court,7. Pálya: A foglyok udvara,Livello 7: Cortile Prigione,Level 7: 囚われの庭,레벨 7: 포획마당,Level 7: Omheining,Nivå 7: Fangegården,Level 7: Dziedziniec Więzienny,Fase 7: Campo de Concentração,Nível 7: Campo de Concentração,Nivelul 7: Capcana curții,Уровень №7: Ловчий двор,Level 7: Замчиште,Seviye 7: Caughtyard -Level 8: Realm,PHUSTR_8,,,,Level 8: Říše,Level 8: Rige,Level 8: Bereich,,Nivelo 8: Regno,Nivel 8: Reino,,Taso 8: Valtapiiri,NIVEAU 8: Royaume,8. Pálya: Uradalom,Livello 8: Regno,Level 8: 領地,레벨 8: 왕국,Level 8: Rijk,Nivå 8: Riket,Level 8: Królestwo,Fase 8: Reino,Nível 8: Reino,Nivelul 8: Tărâm,Уровень №8: Царство,Level 8: Царство,Seviye 8: Diyar -Level 9: Abattoire,PHUSTR_9,,,,Level 9: Jatka,,Level 9: Schlachthaus,,Nivelo 9: Buĉejo,Nivel 9: Matadero,,Taso 9: Teurastamo,NIVEAU 9: Abattoir,9. Pálya: Vágóhíd,Livello 9: Mattatoio,Level 9: 屠殺場,레벨 9: 도축장,Level 9: Abattoir,Nivå 9: Slakteriet,Level 9: Rzeźnia,Fase 9: Matadouro,Nível 9: Matadouro,Nivelul 9: Abator,Уровень №9: Абатство,Level 9: Кланица,Seviye 9: Abattoire -Level 10: Onslaught,PHUSTR_10,,,,Level 10: Nájezd,Level 10: Stormløb,Level 10: Angriff,,Nivelo 10: Buĉado,Nivel 10: Arremetida,,Taso 10: Ryntäys,NIVEAU 10: Assaut,10. Pálya: Roham,Livello 10: Assalto,Level 10: 猛襲,레벨 10: 맹공격,Level 10: Aanval,Nivå 10: Angrep,Level 10: Szturm,Fase 10: Investida,Nível 10: Investida,Nivelul 10: Năvala,Уровень №10: Натиск,Level 10: Јуриш,Seviye 10: Saldırı -Level 11: Hunted,PHUSTR_11,,,,Level 11: Loven,Level 11: Jaget,Level 11: Gehetzt,,Nivelo 11: Ĉasata,Nivel 11: Cazado,,Taso 11: Metsästetty,NIVEAU 11: Traque,11. Pálya: Űzött vad,Livello 11: Braccato,Level 11: 逃走,레벨 11: 사냥당함,Level 11: Gejaagd,Nivå 11: Jaget,Level 11: Nawiedzony,Fase 11: Perseguição,Nível 11: Perseguição,Nivelul 11: Vânătoarea,Уровень №11: Преследуемый,Level 11: Уловљен,Seviye 11: Avlanmış -Level 12: Speed,PHUSTR_12,,,,Level 12: Rychlost,Level 12: Fart,Level 12: Tempo,,Nivelo 12: Rapido,Nivel 12: Velocidad,,Taso 12: Vauhti,NIVEAU 12: Vitesse,12. Pálya: Iram,Livello 12: Velocità,Level 12: スピード,레벨 12: 스피드,Level 12: Haast,Nivå 12: Hastighet,Level 12: Pęd,Fase 12: Velocidade,Nível 12: Velocidade,Nivelul 12: Viteză,Уровень №12: Скорость,Level 12: Брзина,Seviye 12: Hız -Level 13: The Crypt,PHUSTR_13,,,,Level 13: Krypta,Level 13: Krypten,Level 13: Die Gruft,,Nivelo 13: La Kripto,Nivel 13: La Cripta,,Taso 13: Krypta,NIVEAU 13: La Crypte,13. Pálya: A kripta,Livello 13: La Cripta,Level 13: 地下聖堂,레벨 13: 봉안당,Level 13: De crypte,Nivå 13: Krypten,Level 13: Krypta,Fase 13: A Cripta,Nível 13: A Cripta,Nivelul 13: Cripta,Уровень №13: Склеп,Level 13: Гробница,Seviye 13: Mahzen -Level 14: Genesis,PHUSTR_14,,,,,,,,Nivelo 14: Genezo,Nivel 14: Génesis,,Taso 14: Luominen,NIVEAU 14: Genèse,14. Pálya: Teremtés,Livello 14: Genesi,Level 14: 創世記,레벨 14: 창세기,,,Level 14: Geneza,Fase 14: Gênese,Nível 14: Gênese,Nivelul 14: Geneza,Уровень №14: Зарождение,Level 14: Постанак,Seviye 14: Yaratılış -Level 15: The Twilight,PHUSTR_15,,,,Level 15: Soumrak,Level 15: Tusmørket,Level 15: Zwielicht,,Nivelo 15: La Krepusko,Nivel 15: El Ocaso,,Taso 15: Hämärä,NIVEAU 15: Le Crépuscule,15. Pálya: Alkonyat,Livello 15: Il Crepuscolo,Level 15: 黄昏,레벨 15: 황혼,Level 15: De schemering,Nivå 15: Skumringen,Level 15: Zmierzch,Fase 15: O Crepúsculo,Nível 15: O Crepúsculo,Nivelul 15: Amurgul,Уровень №15: Сумерки,Level 15: Сумрак,Seviye 15: Alacakaranlık -Level 16: The Omen,PHUSTR_16,,,,Level 16: Znamení,Level 16: Omenet,Level 16: Das Omen,,Nivelo 16: La Aŭguro,Nivel 16: El Presagio,,Taso 16: Enne,NIVEAU 16: Le Présage,16. Pálya: Az Ómen,Livello 16: Il Presagio,Level 16: 予兆,레벨 16: 징조,Level 16: De omen,Nivå 16: Varselet,Level 16: Omen,Fase 16: O Presságio,Nível 16: O Presságio,Nivelul 16: Prevestirea,Уровень №16: Предзнаменование,Level 16: Знамење,Seviye 16: Omen -Level 17: Compound,PHUSTR_17,,,,Level 17: Ústav,Level 17: Forbindelsen,Level 17: Anlage,,Nivelo 17: Konstruaĵaro,Nivel 17: Complejo,,Taso 17: Laitos,NIVEAU 17: Installation,17. Pálya: Létesítmény,Livello 17: Recinto,Level 17: 調合,레벨 17: 복합체,Level 17: Faciliteit,Nivå 17: Forbindelsen,Level 17: Mieszanka,Fase 17: Complexo,Nível 17: Complexo,Nivelul 17: Complexul,Уровень №17: Комплекс,Level 17: Једињење,Seviye 17: Bileşik -Level 18: Neurosphere,PHUSTR_18,,,,Level 18: Neurosféra,Level 18: Neurosfæren,Level 18: Neurosphäre,,Nivelo 18: Neŭrosfero,Nivel 18: Neuroesfera,,Taso 18: Neurosfääri,NIVEAU 18: Neurosphère,18. Pálya: Neuroszféra,Livello 18: Neurosfera,Level 18: ニューロスフィア,레벨 18: 뉴로스피어,Level 18: Neurosferen,Nivå 18: Nevrosfæren,Level 18: Neurosfera,Fase 18: Neurosfera,Nível 18: Neurosfera,Nivelul 18: Neurosferă,Уровень №18: Нейросфера,Level 18: Неуросфера,Seviye 18: Nörosfer -Level 19: NME,PHUSTR_19,"“NME” read out loud means “enemy”, so translators should consider the translation of “enemy” into their language.",,,Level 19: Nepřítel,,,,Nivelo 19: Mal-BN,Nivel 19: N-MIGO,,Taso 19: VHLLNN,NIVEAU 19: NMI,19. Pálya: LNSG,Livello 19: NMIC,Level 19: 野郎,레벨 19: NOM,,,Level 19: WRG,Fase 19: N-MIGO,Nível 19: N-MIGO,Nivelul 19: INMIC,Уровень №19: В.Р.А.Г.,Level 19: Н.Е.П.Р.,Seviye 19: NME -Level 20: The Death Domain,PHUSTR_20,,,,Level 20: Panství smrti,Level 20: Dødsdomænet,Level 20: Die Todeszone,,Nivelo 20: La Regno de Morto,Nivel 20: El Dominio Mortal,,Taso 20: Kuoleman piiri,NIVEAU 20: Le Domaine de la Mort,20. Pálya: A holtak birtoka,Livello 20: Il Dominio della Morte,Level 20: 死の領域,레벨 20: 죽음의 영역,Level 20: Het domein van de dood,Nivå 20: Dødens domene,Level 20: Domena Śmierci,Fase 20: O Domínio da Morte,Nível 20: O Domínio da Morte,Nivelul 20: Domeniul morții,Уровень №20: Владения смерти,Level 20: Подручије смрти,Seviye 20: Ölüm Alanı -Level 21: Slayer,PHUSTR_21,,,,Level 21: Zabiják,Level 21: Slagter,Level 21: Töter,,Nivelo 21: Mortigisto,Nivel 21: Descuatizador,,Taso 21: Tappaja,NIVEAU 21: Pourfendeur,21. Pálya: Halálosztó,Livello 21: Assassino,Level 21: スレイヤー,레벨 21: 슬레이어,Level 21: Doder,Nivå 21: Slakteren,Level 21: Pogromca,Fase 21: Matador,Nível 21: Matador,Nivelul 21: Ucigător,Уровень №21: Истребитель,Level 21: Убица,Seviye 21: Avcı -Level 22: Impossible Mission,PHUSTR_22,,,,Level 22: Nemožná mise,Level 22: Umulig mission,Level 22: Unmögliche Mission,,Nivelo 22: Malebla Misio,Nivel 22: Misión Imposible,,Taso 22: Mahdoton tehtävä,NIVEAU 22: Mission Impossible,22. Pálya: Lehetetlen küldetés,Livello 22: Missione Impossibile,Level 22: 不可能な任務,레벨 22: 임파서블 미션,Level 22: Onmogelijke missie,Nivå 22: Umulig oppdrag,Level 22: Niemożliwa Misja,Fase 22: Missão Impossível,Nível 22: Missão Impossível,Nivelul 22: Misiune imposibilă,Уровень №22: Невыполнимое задание,Level 22: Немогућа мисија,Seviye 22: İmkansız Görev -Level 23: Tombstone,PHUSTR_23,,,,Level 23: Náhrobek,Level 23: Gravsten,Level 23: Grabstein,,Nivelo 23: Tombŝtono,Nivel 23: Lápida,,Taso 23: Hautakivi,NIVEAU 23: Pierre Tombale,23. Pálya: Sírkő,Livello 23: Pietra Tombale,Level 23: 墓石,레벨 23: 묘비,Level 23: Grafsteen,Nivå 23: Gravstein,Level 23: Nagrobek,Fase 23: Lápide,Nível 23: Lápide,Nivelul 23: Piatra de mormânt,Уровень №23: Надгробие,Level 23: Надгробни споменик,Seviye 23: Mezar Taşı -Level 24: The Final Frontier,PHUSTR_24,,,,Level 24: Poslední hranice,Level 24: Den endelige grænse,Level 24: Die letzte Grenze,,Nivelo 24: La Fina Limo,Nivel 24: La Frontera Final,Nivel 24: La Última Frontera,Taso 24: Viimeinen rajamaa,NIVEAU 24: La Frontière Finale,24. Pálya: A végső határ,Livello 24: La Frontiera Finale,Level 24: 最後のフロンティア,레벨 24: 최후의 개척지,Level 24: De eindgrens,Nivå 24: Den siste grensen,Level 24: Ostateczna Granica,Fase 24: A Fronteira Final,Nível 24: A Fronteira Final,Nivelul 24: Ultima frontieră,Уровень №24: Последний рубеж,Level 24: Коначна граница,Seviye 24: Son Sınır -Level 25: The Temple of Darkness,PHUSTR_25,,,,Level 25: Chrám temna,Level 25: Mørkets tempel,Level 25: Der Tempel der Dunkelheit,,Nivelo 25: La Idolejo de Mallumo,Nivel 25: El Templo de la Oscuridad,,Taso 25: Pimeyden temppeli,NIVEAU 25: Le Temple des Ténèbres,25. Pálya: A sötétség temploma,Livello 25: Il Tempio dell'Oscurità,Level 25: 暗黒の神殿,레벨 25: 어둠의 신전,Level 25: De tempel van de duisternis,Nivå 25: Mørkets tempel,Level 25: Świątynia Mroku,Fase 25: O Templo da Escuridão,Nível 25: O Templo da Escuridão,Nivelul 25: Templul tenebros,Уровень №25: Храм тьмы,Level 25: Храм таме,Seviye 25: Karanlığın Tapınağı -Level 26: Bunker,PHUSTR_26,,,,Level 26: Bunkr,,Level 26: Bunker,,Nivelo 26: Bunkro,Nivel 26: Búnker,,Taso 26: Bunkkeri,NIVEAU 26: Bunker,26. Pálya: Bunker,Livello 26: Bunker,Level 26: バンカー,레벨 26: 방공호,,,Level 26: Bunkier,Fase 26: Casamata,Nível 26: Bunker,Nivelul 26: Buncăr,Уровень №26: Бункер,Level 26: Бункер,Seviye 26: Sığınak -Level 27: Anti-christ,PHUSTR_27,,,,Level 27: Antikrist,,Level 27: Antichrist,,Nivelo 27: Antikristo,Nivel 27: Anti-cristo,,Taso 27: Antikristus,NIVEAU 27: Anti-Christ,27. Pálya: Antikrisztus,Livello 27: Anticristo,Level 27: アンチキリスト,레벨 27: 적그리스도,Level 27: Antichrist,Nivå 27: Antikrist,Level 27: Antychryst,Fase 27: Anticristo,Nível 27: Anticristo,Nivelul 27: Antihrist,Уровень №27: Антихрист,Level 27: Антихрист,Seviye 27: Mesih Karşıtı -Level 28: The Sewers,PHUSTR_28,,,,Level 28: Kanály,Level 28: Kloakkerne,Level 28: Kanäle,,Nivelo 28: La Kanalo,Nivel 28: Las Alcantarillas,,Taso 28: Viemärit,NIVEAU 28: Les Egouts,28. Pálya: A kanális,Livello 28: Le Fogne,Level 28: 下水道,레벨 28: 하수구,Level 28: De rioleringen,Nivå 28: Kloakken,Level 28: Ścieki,Fase 28: Os Esgotos,Nível 28: Os Esgotos,Nivelul 28: Canalizarea,Уровень №28: Канализация,Level 28: Канализација,Seviye 28: Kanalizasyonlar -Level 29: Odyssey of Noises,PHUSTR_29,,,,Level 29: Odysea křiku,Level 29: Lydenes odyssé,Level 29: Odyssee der Geräusche,,Nivelo 29: Vojaĝo de Sonoj,Nivel 29: Odisea de Ruidos,,Taso 29: Äänten harharetki,NIVEAU 29: Odysée de Bruits,29. Pálya: A moraj ösvénye,Livello 29: Odissea dei Rumori,Level 29: オデッセイのノイズ,레벨 29: 속삭임의 여정,Level 29: Odyssee van geluiden,Nivå 29: Lydenes odyssé,Level 29: Odyseja Wrzawy,Fase 29: Odisséia de Ruidos,Nível 29: Odisséia de Ruidos,Nivelul 29: Odiseea zgomotelor,Уровень №29: Одиссея шумов,Level 29: Одисеја шумова,Seviye 29: Seslerin Odyssey'i -Level 30: The Gateway of Hell,PHUSTR_30,,,,Level 30: Brána pekla,Level 30: Helvedes port,Level 30: Tor zur Hölle,,Nivelo 30: La Pordego de Inferno,Nivel 30: La Puerta del Infierno,,Taso 30: Helvetin porttikäytävä,NIVEAU 30: La Porte des Enfers,30. Pálya: Átjáró a pokolba,Livello 30: La Porta dell'Inferno,Level 30: 地獄の関門,레벨 30: 지옥의 차원문,Level 30: De poort van de hel,Nivå 30: Porten til helvete,Level 30: Brama Piekieł,Fase 30: O Portão do Inferno,Nível 30: O Portão do Inferno,Nivelul 30: Poarta spre infern,Уровень №30: Врата ада,Level 30: Пролаз пакла,Seviye 30: Cehennem Kapısı -Level 31: Cyberden,PHUSTR_31,,,,Level 31: Kyberdoupě,,Level 31: Cyberbau,,Nivelo 31: Cibernesto,Nivel 31: Ciber-guarida,,Taso 31: Kyberpesä,NIVEAU 31: Cyber-Antre,31. Pálya: Kiberodú,Livello 31: Cybergabbia,Level 31: サイバーの巣,레벨 31: 사이버소굴,,,Level 31: Cybernora,Fase 31: Ciberantro,Nível 31: Ciberantro,Nivelul 31: Cibervizuină,Уровень №31: Киберлогово,Level 31: Сајбер-јазбина,Seviye 31: Siber'in ini -Level 32: Go 2 It,PHUSTR_32,,,,Level 32: Jdi do toho,,,,Nivelo 32: Iru Al Ĝi!,Nivel 32: Ve a x ello,Nivel 32: Ve x eso,Taso 32: Iske kii,NIVEAU 32: Go 2 It,32. Pálya: Menj oda!,Livello 32: Dacci Dentro,Level 32: 逝ってこい,레벨 32: 함 해 봐,Level 32: Ga ervoor,,Level 32: Do Dzieła,Fase 32: Vai Fundo,Nível 32: Siga em Frente,Nivelul 32: Du-te la ei,Уровень №32: П0лный вп3рёд,Level 32: Иди ка њему,Seviye 32: Devam Et -,,TNT: Evilution,,,,,,,,,,,,,,,,,,,,,,,, -Level 1: System Control,THUSTR_1,,,,Level 1: Administrace,Level 1: Systemkontrol,Level 1: Systemkontrolle,,Nivelo 1: Sistema Kontrolo,Nivel 1: Control del Sistema,,Taso 1: Järjestelmäohjaamo,NIVEAU 1: Système de Contrôle,1. Pálya: Rendszervezérlő,Livello 1: Controllo del Sistema,Level 1: 制御システム,레벨 1: 시스템 제어시설,Level 1: Systeemcontrole,Nivå 1: Systemkontroll,Level 1: Kontrola Systemu,Fase 1: Controle do Sistema,Nível 1: Controlo de Sistema,Nivelul 1: Control sisteme,Уровень №1: Центр управления системой,Level 1: Контролна система,Seviye 1: Sistem Kontrolü -Level 2: Human BBQ,THUSTR_2,,,,Level 2: Člověčí grilovačka,Level 2: Menneskelig grill,Level 2: Menschliches Barbecue,,Nivelo 2: Homo-Kradrostado,Nivel 2: Barbacoa Humana,,Taso 2: Ihmisgrilli,NIVEAU 2: Barbecue Humain,2. Pálya: Emberi grill,Livello 2: Barbecue Umano,Level 2: 人肉晩餐会,레벨 2: 인간 바비큐,Level 2: Menselijke BBQ,Nivå 2: Menneskelig BBQ,Level 2: Ludzki Grill,Fase 2: Churrasco Humano,Nível 2: Churrasco Humano,Nivelul 2: Oameni la grătar,Уровень №2: Барбекю из человечины,Level 2: Људски роштиљ,Seviye 2: İnsan Barbekü -Level 3: Power Control,THUSTR_3,,,,Level 3: Napájecí vedení,Level 3: Kontrol med magten,Level 3: Energiekontrolle,,Nivelo 3: Energia Kontrolo,Nivel 3: Control de Energía,,Taso 3: Voimalan ohjaamo,NIVEAU 3: Contrôle Energétique,3. Pálya: Energiavezérlő,Livello 3: Centrale Energetica,Level 3: 制御室,레벨 3: 전력 통제소,Level 3: Machtscontrole,Nivå 3: Kraftkontroll,Level 3: Kontrola Zasilania,Fase 3: Controle de Energia,Nível 3: Controlo Energético,Nivelul 3: Uzina,Уровень №3: Центр управления питанием,Level 3: Контролна моћ,Seviye 3: Güç Kontrolü -Level 4: Wormhole,THUSTR_4,,,,Level 4: Červí díra,Level 4: Ormehul,Level 4: Wurmloch,,Nivelo 4: Vermtruo,Nivel 4: Agujero de Gusano,,Taso 4: Madonreikä,NIVEAU 4: Trou de Ver,4. Pálya: Féreglyuk,Livello 4: Wormhole,Level 4: 虫喰い穴,레벨 4: 웜홀,Level 4: Wormgat,Nivå 4: Ormehull,Level 4: Tunel,Fase 4: Buraco de Minhoca,Nível 4: Buraco de Minhoca,Nivelul 4: Gaura de vierme,Уровень №4: Червоточина,Level 4: Црвоточина,Seviye 4: Solucan Deliği -Level 5: Hanger,THUSTR_5,"Not ""Hangar""",,,Level 5: Hangár,,Level 5: Hangar,,Nivelo 5: Pendigejo,Nivel 5: Colgador,,Taso 5: Lentoalushalli,NIVEAU 5: Hangar,5. Pálya: Horog,Livello 5: Hanga,Level 5: 格納庫,레벨 5: 격납고,Level 5: Hangar,Nivå 5: Hanger,Level 5: Hangar,Fase 5: Hangar,Nível 5: Hangar,Nivelul 5: Hangar,Уровень №5: Ангар,Level 5: Вешалица,Seviye 5: Askı -Level 6: Open Season,THUSTR_6,,,,Level 6: Lovecká sezóna,Level 6: Åben sæson,Level 6: Jagdsaison,,Nivelo 6: Ĉasosezono,Nivel 6: Temporada Abierta,,Taso 6: Avoin sesonki,NIVEAU 6: La Chasse Est Ouverte,6. Pálya: Vadászszezon,Livello 6: Stagione Aperta,Level 6: 狩猟解禁,레벨 6: 사냥철,Level 6: Open seizoen,Nivå 6: Åpen sesong,Level 6: Otwarty Sezon,Fase 6: Temporada Aberta,Nível 6: Época Aberta,Nivelul 6: Sezon deschis,Уровень №6: Сезон охоты,Level 6: Отворена сезона,Seviye 6: Açık Sezon -Level 7: Prison,THUSTR_7,,,,Level 7: Vězení,Level 7: Fængsel,Level 7: Gefängnis,,Nivelo 7: Malliberejo,Nivel 7: Prisión,,Taso 7: Vankila,NIVEAU 7: Prison,7. Pálya: Börtön,Livello 7: Prigione,Level 7: 監獄,레벨 7: 감옥,Level 7: Gevangenis,Nivå 7: Fengsel,Level 7: Więzienie,Fase 7: Prisão,Nível 7: Prisão,Nivelul 7: Închisoare,Уровень №7: Тюрьма,Level 7: Затвор,Seviye 7: Hapishane -Level 8: Metal,THUSTR_8,,,,Level 8: Kov,,Level 8: Metall,,Nivelo 8: Metalo,Nivel 8: Metal,,Taso 8: Metalli,NIVEAU 8: Métal,8. Pálya: Fém,Livello 8: Metallo,Level 8: メタル,레벨 8: 강철,Level 8: Metaal,Nivå 8: Metall,Level 8: Metal,Fase 8: Metal,Nível 8: Metal,Nivelul 8: Metal,Уровень №8: Металл,Level 8: Метал,Seviye 8: Metal -Level 9: Stronghold,THUSTR_9,,,,Level 9: Pevnost,Level 9: Borgen,Level 9: Festung,,Nivelo 9: Fuorto,Nivel 9: Fortaleza,,Taso 9: Linnake,NIVEAU 9: Forteresse,9. Pálya: Erőd,Livello 9: Fortezza,Level 9: 牙城,레벨 9: 요새,Level 9: Vesting,Nivå 9: Festning,Level 9: Warownia,Fase 9: Fortaleza,Nível 9: Fortaleza,Nivelul 9: Bastion,Уровень №9: Твердыня,Level 9: Упориште,Seviye 9: Kale -Level 10: Redemption,THUSTR_10,,,,Level 10: Vykoupení,Level 10: Forløsning,Level 10: Erlösung,,Nivelo 10: Elaĉeto,Nivel 10: Redención,,Taso 10: Lunastus,NIVEAU 10: Rédemption,10. Pálya: Megváltás,Livello 10: Redenzione,Level 10: 償還,레벨 10: 구원,Level 10: Aflossing,Nivå 10: Innløsning,Level 10: Odkupienie,Fase 10: Redenção,Nível 10: Redenção,Nivelul 10: Răscumpărare,Уровень №10: Искупление,Level 10: Искупљење,Seviye 10: Kefaret -Level 11: Storage Facility,THUSTR_11,,,,Level 11: Skladiště,Level 11: Opbevaringsanlæg,Level 11: Lagerstätte,,Nivelo 11: Stokejo,Nivel 11: Complejo de Almacenes,Nivel 11: Almacenes,Taso 11: Varastolaitos,NIVEAU 11: Complexe de Stockage,11. Pálya: Raktárépület,Livello 11: Impianto di Stoccaggio,Level 11: 貯蔵施設,레벨 11: 저장소,Level 11: Opslagfaciliteit,Nivå 11: Lagringsanlegg,Level 11: Magazyn,Fase 11: Centro de Armazenamento,Nível 11: Centro de Armazenamento,Nivelul 11: Stația de depozitare,Уровень №11: Склад,Level 11: Складиште,Seviye 11: Depolama Tesisi -Level 12: Crater,THUSTR_12,,,,Level 12: Kráter,Level 12: Krater,Level 12: Krater,,Nivelo 12: Kratero,Nivel 12: Cráter,,Taso 12: Kraateri,NIVEAU 12: Cratère,12. Pálya: Kráter,Livello 12: Cratere,Level 12: 火口,레벨 12: 분화구,Level 12: Krater,Nivå 12: Krater,Level 12: Krater,Fase 12: Cratera,Nível 12: Cratera,Nivelul 12: Crater,Уровень №12: Кратер,Level 12: Кратер,Seviye 12: Krater -Level 13: Nukage Processing,THUSTR_13,,,,Level 13: Jaderné zpracování,Level 13: Nukageforarbejdning,Level 13: Nuklearverarbeitung,,Nivelo 13: Nukleaĵo-Traktejo,Nivel 13: Procesamiento de Residuos Nucleares,,Taso 13: Ydinjätekäsittely,NIVEAU 13: Traitement Nucléaire,13. Pálya: Atomhulladék-feldolgozó,Livello 13: Trattamento Nucleare,Level 13: 核廃棄物加工所,레벨 13: 폐기물 처리소,Level 13: Nucleaire verwerking,Nivå 13: Nukage-prosessering,Level 13: Przetwórstwo Jądrowe,Fase 13: Processamento Nuclear,Nível 13: Processamento Nuclear,Nivelul 13: Prelucrarea deșeurilor nucleare,Уровень №13: Переработка ядерных отходов,Level 13: Прерада нуклеарног отпада,Seviye 13: Nukage İşleme -Level 14: Steel Works,THUSTR_14,,,,Level 14: Ocelárna,Level 14: Stålværk,Level 14: Stahlwerk,,Nivelo 14: Ŝtalejo,Nivel 14: Siderúrgica,Nivel 14: Siderurgia,Taso 14: Terästehdas,NIVEAU 14: Aciérie,14. Pálya: Acélművek,Livello 14: Acciaieria,Level 14: 製鉄所,레벨 14: 제강소,Level 14: Staalfabrieken,Nivå 14: Stålverk,Level 14: Huta,Fase 14: Siderúrgica,Nível 14: Siderúrgica,Nivelul 14: Oțelărie,Уровень №14: Сталелитейный завод,Level 14: Челичана,Seviye 14: Çelik İşleri -Level 15: Dead Zone,THUSTR_15,,,,Level 15: Mrtvá zóna,Level 15: Død zone,Level 15: Tote Zone,,Nivelo 15: Senvivzono,Nivel 15: Zona Muerta,,Taso 15: Kuollut alue,NIVEAU 15: Zone Morte,15. Pálya: A holtak zónája,Livello 15: Zona Morta,Level 15: 危険地帯,레벨 15: 사각지대,Level 15: Dode zone,Nivå 15: Død sone,Level 15: Martwa Strefa,Fase 15: Zona Morta,Nível 15: Zona Morta,Nivelul 15: Zona moartă,Уровень №15: Мёртвая зона,Level 15: Зона смрти,Seviye 15: Ölü Bölge -Level 16: Deepest Reaches,THUSTR_16,,,,Level 16: Nejhlubší sluje,Level 16: De dybeste afkroge,Level 16: Tiefe,,Nivelo 16: Plejsubejo,Nivel 16: Recodos profundos,,Taso 16: Syvyydet,NIVEAU 16: Profondeurs,16. Pálya: A legmélyebb pont,Livello 16: Profondità,Level 16: 最深部,레벨 16: 깊숙한 강,Level 16: Diepste reiken,Nivå 16: De dypeste områdene,Level 16: Głębiny,Fase 16: Profundezas,Nível 16: Profundezas,Nivelul 16: În adâncuri,Уровень №16: Глубочайшие достижения,Level 16: Најдубља дубина,Seviye 16: En Derin Erişimler -Level 17: Processing Area,THUSTR_17,,,,Level 17: Kombinát,Level 17: Forarbejdningsområde,Level 17: Verarbeitungsbereich,,Nivelo 17: Traktadareo,Nivel 17: Área de Procesamiento,,Taso 17: Käsittelyalue,NIVEAU 17: Zone de Traitement,17. Pálya: Feldolgozó,Livello 17: Area di Elaborazione,Level 17: 処理地帯,레벨 17: 처리 구역,Level 17: Verwerkingsgebied,Nivå 17: Behandlingsområde,Level 17: Strefa Przerobowa,Fase 17: Área de Processamento,Nível 17: Área de Processamento,Nivelul 17: Aria de procesare,Уровень №17: Зона обработки,Level 17: Подручје обраде,Seviye 17: İşleme Alanı -Level 18: Mill,THUSTR_18,,,,Level 18: Mlýn,Level 18: Mølle,Level 18: Mühle,,Nivelo 18: Muelejo,Nivel 18: Molino,,Taso 18: Mylly,NIVEAU 18: Fonderie,18. Pálya: Malom,Livello 18: Fonderia,Level 18: 製粉所,레벨 18: 제분소,Level 18: Molen,Nivå 18: Mølle,Level 18: Młyn,Fase 18: Moinho,Nível 18: Moinho,Nivelul 18: Moara,Уровень №18: Завод,Level 18: Млин,Seviye 18: Değirmen -Level 19: Shipping/respawning,THUSTR_19,,,,Level 19: Přeprava,Level 19: Forsendelsescenter,Level 19: Versandlager,,Nivelo 19: Ekspedo/Revivado,Nivel 19: Enviando/Reapareciendo,,Taso 19: Huolinta/Ylösnostatus,NIVEAU 19: Envoi/Réapparition,19. Pálya: Szállítás/újraéledés,Livello 19: Consegna/Respawn,Level 19: 出荷と再生成,레벨 19: 운송/리스폰 장소,Level 19: Verzendingscentrum,Nivå 19: Frakt/omlasting,Level 19: Wysyłka/Reprodukcja,Fase 19: Expedição/reaparecimento,Nível 19: Expedição/reaparecimento,Nivelul 19: Livrare/reapariție,Уровень №19: Погрузка и отправка,Level 19: Отпремање/оживљавање,Seviye 19: Nakliye Merkezi -Level 20: Central Processing,THUSTR_20,,,,Level 20: Centrální zpracování,Level 20: Central forarbejdning,Level 20: Zentralverarbeitung,,Nivelo 20: Centra Eskpedado,Nivel 20: Procesamiento Central,,Taso 20: Käsittelykeskus,NIVEAU 20: Organisme Central,20. Pálya: Központi feldolgozó,Livello 20: Centrale di Elaborazione,Level 20: 中央処理所,레벨 20: 중앙 처리소,Level 20: Centrale verwerking,Nivå 20: Sentral behandling,Level 20: Centralny Proces,Fase 20: Processamento Central,Nível 20: Processamento Central,Nivelul 20: Prelucrare centrală,Уровень №20: Центральный пункт обработки,Level 20: Централна обрада,Seviye 20: Merkezi İşlem -Level 21: Administration Center,THUSTR_21,,,,Level 21: Administrativní centrum,Level 21: Administrationscenter,Level 21: Verwaltungszentrum,,Nivelo 21: Administracia Centro,Nivel 21: Centro de Administración,,Taso 21: Keskushallinto,NIVEAU 21: Centre Administratif,21. Pálya: Adminisztrációs központ,Livello 21: Centro Amministrativo,Level 21: 行政センター,레벨 21: 관리 센터,Level 21: Administratief centrum,Nivå 21: Administrasjonssenter,Level 21: Centrum Administracyjne,Fase 21: Centro de Administração,Nível 21: Centro de Administração,Nivelul 21: Centru administrativ,Уровень №21: Административный центр,Level 21: Административни центар,Seviye 21: Yönetim Merkezi -Level 22: Habitat,THUSTR_22,,,,,Level 22: Levested,,,Nivelo 22: Habitato,Nivel 22: Hábitat,,Taso 22: Asuinpaikka,NIVEAU 22: Habitat,22. Pálya: Élőhely,Livello 22: Habitat,Level 22: 生息地,레벨 22: 서식지,,Nivå 22: Habitat,Level 22: Siedlisko,Fase 22: Habitat,Nível 22: Habitat,Nivelul 22: Habitat,Уровень №22: Ареал,Level 22: Станиште,Seviye 22: Habitat -Level 23: Lunar Mining Project,THUSTR_23,,,,Level 23: Lunární těžební projekt,Level 23: Projekt for månens minedrift,Level 23: Mondbergbauprojekt,,Nivelo 23: Luna Mino-Projekto,Nivel 23: Proyecto de Minería Lunar,,Taso 23: Kuukaivosprojekti,NIVEAU 23: Projet Minier Lunaire,23. Pálya: Holdbánya-projekt,Livello 23: Progetto Minerario Lunare,Level 23: 月面探鉱計画,레벨 23: 월석 채광 계획,Level 23: Maanmijnbouw project,Nivå 23: Månegruveprosjekt,Level 23: Projekt Księżycowe Górnictwo,Fase 23: Projeto de Mineração Lunar,Nível 23: Projeto de Escavação Lunar,Nivelul 23: Proiect minier satelitar,Уровень №23: Лунный проект горной добычи,Level 23: Пројекат лунарног рударства,Seviye 23: Ay Madenciliği Projesi -Level 24: Quarry,THUSTR_24,,,,Level 24: Kamenolom,Level 24: Stenbrud,Level 24: Steinbruch,,Nivelo 24: Ŝtonejo,Nivel 24: Cantera,,Taso 24: Louhos,NIVEAU 24: Carrière,24. Pálya: Kőbánya,Livello 24: Caccia,Level 24: 採石場,레벨 24: 채석장,Level 24: Steengroeve,Nivå 24: Steinbrudd,Level 24: Kamieniołom,Fase 24: Pedreira,Nível 24: Pedreira,Nivelul 24: Carieră,Уровень №24: Карьер,Level 24: Каменолом,Seviye 24: Taş Ocağı -Level 25: Baron's Den,THUSTR_25,,,,Level 25: Baronovo doupě,Level 25: Baronens hule,Level 25: Der Bau des Barons,,Nivelo 25: Nestego de Barono,Nivel 25: Guarida del Barón,,Taso 25: Paronin pesä,NIVEAU 25: l'Antre des Barons,25. Pálya: A báró odúja,Livello 25: Antro del Barone,Level 25: バロンの巣窟,레벨 25: 남작의 소굴,Level 25: Het baron's gebouw,Nivå 25: Baronens hule,Level 25: Legowisko Barona,Fase 25: Covil do Barão,Nível 25: Covil do Barão,Nivelul 25: Cuibul Baronului,Уровень №25: Логово барона,Level 25: Баронова јазбина,Seviye 25: Baron'un İni -Level 26: Ballistyx,THUSTR_26,,,,Level 26: Balistika,,,,Nivelo 26: Balistikso,Nivel 26: Balístige,,Taso 26: Ballistyks,NIVEAU 26: Ballistyx,26. Pálya: Ballisztüx,Livello 26: Ballistige,Level 26: バリステュクス,레벨 26: 탄도스틱스,,,Level 26: Balistyka,Fase 26: Ballistige,Nível 26: Ballistige,Nivelul 26: Ballistyx,Уровень №26: Баллистикс,Level 26: Билистичкикс,Seviye 26: Balistyx -Level 27: Mount Pain,THUSTR_27,,,,Level 27: Hora bolesti,Level 27: Smertefjellet,Level 27: Berg des Schmerzes,,Nivelo 27: Monto de Doloro,Nivel 27: Monte Dolor,,Taso 27: Tuskavuori,NIVEAU 27: Mont Souffrance,27. Pálya: A Gyötrelem Hegye,Livello 27: Monte del Dolore,Level 27: 苦しみの山,레벨 27: 등신같은 등산,Level 27: Pijn in de bergen,Nivå 27: Smertefjellet,Level 27: Góra Bólu,Fase 27: Monte Dor,Nível 27: Monte Dor,Nivelul 27: Muntele Durerii,Уровень №27: Гора Боль,Level 27: Планина боли,Seviye 27: Acı Dağı -Level 28: Heck,THUSTR_28,,,,Level 28: Sakra,,Level 28: Zum Teufel,,Nivelo 28: Diable,Nivel 28: Diablos,,Taso 28: Hemmetti,NIVEAU 28: Que Diable?,28. Pálya: Rosseb,Livello 28: Al Diavolo,Level 28: 苛立ち,레벨 28: 젠장함,,Nivå 28: Helvete,Level 28: Do Diabła,Fase 28: Capeta,Nível 28: Inferno,Nivelul 28: Naiba,Уровень №28: Чертовщина,Level 28: Пакао,Seviye 28: Cehennem -Level 29: River Styx,THUSTR_29,,,,Level 29: Řeka Styx,Level 29: Floden Styx,Level 29: Fluss Styx,,Nivelo 29: Rivero de Stikso,Nivel 29: Río Estige,,Taso 29: Styksjoki,NIVEAU 29: Fleuve Styx,29. Pálya: A Sztüx folyó,Livello 29: Fiume Stige,Level 29: 三途の川,레벨 29: 스틱스 강,Level 29: Rivier Styx,Nivå 29: Elven Styx,Level 29: Styks,Fase 29: Rio Estige,Nível 29: Rio Estige,Nivelul 29: Râul Styx,Уровень №29: Река Стикс,Level 29: Река Стикс,Seviye 29: Styx Nehri -Level 30: Last Call,THUSTR_30,,,,Level 30: Poslední mise,Level 30: Sidste opkald,Level 30: Letzter Aufruf,,Nivelo 30: Fina Voko,Nivel 30: Última Llamada,,Taso 30: Viimeinen koollehuuto,NIVEAU 30: Dernier Appel,30. Pálya: Utolsó esély,Livello 30: Ultima Chiamata,Level 30: 最終指令,레벨 30: 최후의 호출,Level 30: Laatste oproep,Nivå 30: Siste innkalling,Level 30: Ostatni Zew,Fase 30: Última Chamada,Nível 30: Última Chamada,Nivelul 30: Ultimul apel,Уровень №30: Последний вызов,Level 30: Последњи позив,Seviye 30: Son Çağrı -Level 31: Pharaoh,THUSTR_31,,,,Level 31: Faraón,Level 31: Farao,Level 31: Pharao,,Nivelo 31: Faraono,Nivel 31: Faraón,,Taso 31: Faarao,NIVEAU 31: Pharaon,31. Pálya: Fáraó,Livello 31: Faraone,Level 31: ファラオ,레벨 31: 파라오,Level 31: Farao,Nivå 31: Farao,Level 31: Faraon,Fase 31: Faraó,Nível 31: Faraó,Nivelul 31: Faraon,Уровень №31: Фараон,Level 31: Фараон,Seviye 31: Firavun -Level 32: Caribbean,THUSTR_32,,,,Level 32: Karibik,Level 32: Caribien,Level 32: Karibik,,Nivelo 32: Karibio,Nivel 32: Caribeño,,Taso 32: Karibia,NIVEAU 32: Caraïbes,32. Pálya: Karib-térség,Livello 32: Caraibi,Level 32: カリビアン,레벨 32: 카리브해,Level 32: Caribisch,Nivå 32: Karibia,Level 32: Karaiby,Fase 32: Caribe,Nível 32: Caraíbas,Nivelul 32: Caraibe,Уровень №32: Карибы,Level 32: Кариби,Seviye 32: Karayipler -,,Heretic,,,,,,,,,,,,,,,,,,,,,,,, -The Docks,HHUSTR_E1M1,,,,Přístav,Havnene,Die Docks,,La Havenoj,Los Muelles,,Satamat,Les Docks,A Kikötő,Il Molo,埠頭,항구,De dokken,Havnen,Doki,As Docas,,Docul,Доки,Лука,Rıhtım -The Dungeons,HHUSTR_E1M2,,,,Žaláře,Fangehullerne,Die Kerker,,La Malliberejoj,Los Calabozos,,Tyrmät,Le Donjon,A Kazamaták,I Sotterranei,地下牢,지하감옥,De kerkers,Fangehullene,Lochy,As Masmorras,,Temnița,Темницы,Тамнице,Zindanlar -The Gatehouse,HHUSTR_E1M3,,,,Vrátnice,Portens hus,Das Pförtnerhaus,,La Pordegejo,El Cuerpo de Guardia,,Porttitalo,Le Corps de Garde,A Kapuház,L'ingresso,門塔,문루,Het poortgebouw,Porthuset,Stróżówka,O Portão de Entrada,,Casa portarului,Привратницкая,Стражарница,Kapı Evi -The Guard Tower,HHUSTR_E1M4,,,,Strážní věž,Vagttårnet,Der Wachturm,,La Gardturo,La Torre de Guardia,,Vartiotorni,La Tour de Garde,Az Őrtorony,La Torre di Guardia,監視塔,보초 누대,De wachttoren,Vakttårnet,Wieża Strażnicza,A Torre de Guarda,,Turnul de veghe,Сторожевая башня,Извидница,Muhafız Kulesi -The Citadel,HHUSTR_E1M5,,,,Citadela,Citadellet,Die Festung,,La Citadelo,La Ciudadela,,Linnake,La Citadelle,A Citadella,La Cittadella,要塞,거점,De citadel,Citadellet,Cytadela,A Cidadela,,Cetatea,Цитадель,Цитадела,Hisar -The Cathedral,HHUSTR_E1M6,,,,Katedrála,Katedralen,Die Kathedrale,,La Katedralo,La Catedral,,Katedraali,La Cathédrale,A Katedrális,La Cattedrale,大聖堂,대성당,De kathedraal,Katedralen,Katedra,A Catedral,,Catedrala,Кафедральный собор,Катедрала,Katedral -The Crypts,HHUSTR_E1M7,,,,Krypty,Krypterne,Die Krypten,,La Kriptoj,Las Criptas,,Kryptat,La Crypte,A Kripták,Le Cripte,地下聖堂,지하 묘실,De grafkelders,Kryptene,Krypty,As Criptas,,Criptele,Склепы,Крипта,Mahzenler -Hell's Maw,HHUSTR_E1M8,,,,Chřtán pekla,Helvedes gab,Der Höllenschlund,,Faŭko de Infero,Fauces del Infierno,,Helvetin kita,La Geule de l'Enfer,A Pokol Szája,La Bocca dell'Inferno,地獄の肚,지옥의 목구멍,De helmouth,Helvetes gap,Paszcza Piekieł,A Boca do Inferno,,Gura iadului,Адская утроба,Паклено ждрело,Cehennem Ağzı -The Graveyard,HHUSTR_E1M9,,,,Hřbitov,Kirkegården,Der Friedhof,,La Tombejo,El Cementerio,,Hautausmaa,Le Cimetière,A Temető,Il Cimitero,墓場,공동묘지,De begraafplaats,Kirkegården,Cmentarz,O Cemitério,,Cimitirul,Кладбище,Гробље,Mezarlık -The Crater,HHUSTR_E2M1,,,,Kráter,Krateret,Der Krater,,La Kratero,El Cráter,,Kraateri,Le Cratère,A Kráter,Il Cratere,噴火口,깊은 혈,De krater,Krateret,Krater,A Cratera,,Craterul,Кратер,Кратер,Krater -The Lava Pits,HHUSTR_E2M2,,,,Lávové jámy,Lavagruberne,Die Lavagruben,,La Lafo-Fosaĵo,Las Canteras de Lava,,Laavamontut,Les Puits de Lave,A Lávaárok,I Pozzi della Lava,溶岩の竪穴,용암 구덩이,De lavaputten,Lavagropene,Szyb Lawy,Os Fossos de Lava,,Gropile cu lavă,Лавовые очаги,Понор лаве,Lav Çukurları -The River of Fire,HHUSTR_E2M3,,,,Ohnivá řeka,Ildfloden,Der Feuerfluss,,La Rivero de Fajro,El Río de Fuego,,Tulijoki,La Rivière de Feu,A Tűzfolyó,Il Fiume di Fuoco,火の河,화염의 강,De rivier van vuur,Elven av ild,Rzeka Ognia,O Rio de Fogo,,Râul de foc,Река огня,Река од ватре,Ateş Nehri -The Ice Grotto,HHUSTR_E2M4,,,,Ledová grotta,Isgrotten,Die Eisgrotte,,La Glacigroto,La Gruta de Hielo,,Jääluola,La Grotte de Glace,A Jégbarlang,La Grotta del Ghiaccio,氷の洞窟,얼음 동굴,De ijsgrot,Isgrotten,Lodowa Grota,A Gruta de Gelo,,Grota de gheață,Ледяной грот,Ледена пећина,Buz Mağarası -The Catacombs,HHUSTR_E2M5,,,,Katakomby,Katakomberne,Die Katakomben,,La Katakomboj,Las Catacumbas,,Katakombit,Les Catacombes,A Katakombák,Le Catacombe,地下墓所,태고의 무덤,De catacomben,Katakombene,Katakumby,As Catacumbas,Os Túmulos,Catacombele,Катакомбы,Катакомбе,Yeraltı Mezarları -The Labyrinth,HHUSTR_E2M6,,,,Labyrint,Labyrinten,Das Labyrinth,,La Labirinto,El Laberinto,,Labyrintti,Le Labyrinthe,A Labirintus,Il Labirinto,迷宮,미궁,Het labyrint,Labyrinten,Labirynt,O Labirinto,,Labirintul,Лабиринт,Лавиринт,Labirent -The Great Hall,HHUSTR_E2M7,,,,Velký sál,Den store sal,Die große Halle,,La Granda Halo,El Gran Salón,,Suuri halli,Le Grand Hall,A Nagy Folyosó,La Grande Sala,大公会堂,대회관,De grote zaal,Den store salen,Wielki Hol,O Grande Salão,,Sala cea mare,Большой зал,Велика дворана,Büyük Salon -The Portals of Chaos,HHUSTR_E2M8,,,,Portály chaosu,Kaosets portaler,Das Portal des Chaos,,La Portaloj de Ĥaoso,Los Portales del Caos,,Kaaoksen portaalit,Le Portail du Chaos,A Káosz Portáljai,I Portali del Caos,混沌への門,혼돈의 차원문,De portalen van chaos,Kaosets portaler,Portale Chaosu,Os Portais do Caos,,Portalurile haosului,Порталы хаоса,Портали хаоса,Kaos Kapıları -The Glacier,HHUSTR_E2M9,,,,Ledovec,Gletsjeren,Der Gletscher,,La Glaciejo,El Glaciar,,Jäätikkö,Le Glacier,A Gleccser,Il Ghiacciaio,氷河,빙하 구역,De gletsjer,Isbreen,Lodowiec,A Geleira,O Glaciar,Ghețarul,Ледник,Глечер,Buzul -The Storehouse,HHUSTR_E3M1,,,,Skladiště,Magasinet,Die Lagerhalle,,La Stokejo,El Almacén,,Varasto,L'Entrepôt,A Raktár,Il Magazzino,倉庫,저장고,Het pakhuis,Forrådshuset,Magazyn,O Armazém,,Depozitul,Кладовая,Складиште,Depo -The Cesspool,HHUSTR_E3M2,,,,Žumpa,Kedelbassinet,Die Latrine,,La Kloako,El Pozo,,Likakaivo,Le Bourbier,A Pöcegödör,Il Pozzo Nero,汚水層,불결한 장소,De zinkput,Søledammen,Szambo,A Fossa,,Haznaua,Сточный колодец,Септичка јама,Lağım Çukuru -The Confluence,HHUSTR_E3M3,,,,Soutok,Sammenløbet,Die Vereinigung,,La Kunfluiĝo,La Confluencia,,Yhtymäkohta,La Confluence,A Kereszteződés,La Confluenza,合流点,합류점,De samenvloeiing,Sammenløpet,Spływ,A Confluência,,Confluența,Слияние,Ушће,Confluence -The Azure Fortress,HHUSTR_E3M4,,,,Azurová pevnost,Den azurblå fæstning,Die himmelblaue Festung,,La Lazurfortikaĵo,La Fortaleza de Azur,,Sininen linnoitus,La Fortresse d'Azur,Az Azúr Erőd,La Fortezza Azzurra,紺碧の要塞,청천의 요새,De azuurblauwe vesting,Den azurblå festningen,Lazurowa Forteca,A Fortaleza Azul,,Fortăreața de azur,Лазурная крепость,Азурна дврђава,Azure Kalesi -The Ophidian Lair,HHUSTR_E3M5,,,,Hadí doupě,Ophidian Hulen,Das Schlangennest,,La Nestego de Ofidia,La Guarida Ofídica,,Käärmeiden pesä,Le Repaire des Ophidiens,Az Opfidiánok Fészke,L'antro degli Ophidian,オフィディアンの塒,오피디안의 소굴,Het slangennest,Ophidian-hulen,Gniazdo Węży,A Cova dos Ofídios,,Cuibul ofidienilor,Логово офидианов,Змијска јазбина,Ophidian İni -The Halls of Fear,HHUSTR_E3M6,,,,Chodby strachu,Frygtens haller,Die Hallen der Angst,,La Koridoroj de Timo,Los Salones del Miedo,,Pelon salit,Les Couloirs de la Peur,A Félelem Folyosói,Le Sale della Paura,恐怖の館,공포의 회관,De zalen van angst,Fryktens haller,Korytarze Strachu,Os Salões do Medo,,Sălile groazei,Залы страха,Дворана страха,Korku Salonları -The Chasm,HHUSTR_E3M7,,,,Propast,Kløften,Der Abgrund,,La Fendego,El Abismo,,Rotko,Le Gouffre,A Szakadék,L'abisso,裂け目,깊은 골,De kloof,Kløften,Przepaść,O Abismo,,Prăpastia,Пропасть,Понор лаве,Uçurum -D'Sparil's Keep,HHUSTR_E3M8,,,,D'Sparilova pevnost,D'Sparils borg,D'Sparils Außenposten,,Ĉefturo de Desparilo,Guarida de D'Sparil,,D'Sparilin linna,Le Donjon de D'Sparil,D'Sparil Terme,La Dimora di D'Sparil,デ’スパリルの間,드'스파릴의 초소,D'Sparil's voorpost,D'Sparils borg,Baszta D'Sparila,Fortaleza de D'Sparil,,Palatul lui D'sparil,Крепость Д'Спарила,Д'Спарилова кула,D'Sparil'in Kalesi -The Aquifer,HHUSTR_E3M9,,,,Zvodeň,Akvifer,Der Wasserspeicher,,La Akvigilo,El Acuífero,,Akviferi,L'Aquifère,A Víztorony,L'acquedotto,帯水層,대수층,Het water reservoir,Akviferen,Wodociąg,O Aquífero,,Galerii acvifere,Водоносный слой,Водоносник,Akifer -Catafalque,HHUSTR_E4M1,,,,Katafalk,Katafalken,Katafalk,,Katafalko,Catafalco,,Katafalkki,Le Catafalque,Ravatal,Catafalco,棺台,관대,Catafalk,Katafalken,Katafalk,Catafalco,,Catafalc,Катафалк,Одар,Katafalk -Blockhouse,HHUSTR_E4M2,,,,Tvrzka,Blokhuset,Blockhaus,,Blokhaŭso,Fortín,,Linnoitus,Le Fortin,Gerendaház,Blocco di Case,丸太小屋,특화점,Blokhuis,Blokkhuset,Blokhauz,O Forte,,Fort,Блокгауз,Бункер,Blok ev -Ambulatory,HHUSTR_E4M3,,,,Ochoz,Ambulatory,Wandelgang,,Ĥorĉirkaŭirejo,Ambulatorio,,Kuorikäytävä,Le Déambulatoire,Kerengő,Ambulatorio,遊歩道,유보장,Kloostergang,Gangen,Krużganek,Ambulatório,,Clinică,Амбулатория,Амбуланта,Ambulatuvar -Sepulcher,HHUSTR_E4M4,,,,Hrobka,Graven,Grabstätte,,Tombo,Sepulcro,,Hautakammio,Le Sépulcre,Síremlék,Sepolcro,埋葬所,매장소,Grafsteen,Graven,Grób,Sepulcro,,Sepulcru,Гробница,Гробница,Mezar -Great Stair,HHUSTR_E4M5,,,,Velké schody,Den store trappe,Große Treppe,,Granda Ŝtuparo,Gran Escalera,,Suuret portaat,Le Grand Escalier,Nagy Lépcső,Grande Scala,大階段,특급 계단,Grote trap,Den store trappen,Wielka Gwiazda,Grande Escada,,Scara cea mare,Великая лестница,Велики степеник,Büyük Merdiven -Halls of the Apostate,HHUSTR_E4M6,,,,Chodby odpadlictví,Apostaternes haller,Halle des Abtrünnigen,,Haloj de la Apostato,Salas de los Apóstatas,,Luopioiden salit,Les Halls de l'Apôtre,A Hitehagyott Csarnoka,Sale dell'Apostata,背教者の館,배교자의 회관,Zalen van de afvallige,De frafalnes haller,Korytarze Odszczepieńca,Os Salões dos Apóstatas,,Sălile apostatului,Залы отступников,Дворана апостола,Mürted Salonları -Ramparts of Perdition,HHUSTR_E4M7,,,,Náspy zatracení,Fortabelsens ramper,Wälle der Verdammnis,,Muregoj de Pereo,Murallas de la Perdición,,Kadotuksen vallit,Les Remparts de la Perdition,A Kárhozat Támasza,Torrioni della Perdizione,破滅の塁壁,파멸의 성벽,Wallen van de verdoemenis,Fortapelsens voller,Wał Potępienia,Muralhas da Perdição,,Meterezele pierzaniei,Твердыни погибели,Бедем пропасти,Azap Surları -Shattered Bridge,HHUSTR_E4M8,,,,Rozbitý most,Den ødelagte bro,Zerstörte Brücke,,Frakasita Ponto,Puente Destrozado,,Särkynyt silta,Le Pont effondré,Az Összeomlott Híd,Ponte Distrutto,崩落の橋,붕괴된 다리,Verbrijzelde brug,Den knuste broen,Zniszczony Most,Ponte Despedaçada,,Podul dărâmat,Разрушенный мост,Поломљен мост,Parçalanmış Köprü -Mausoleum,HHUSTR_E4M9,,,,Mauzoleum,,,,Maŭzoleo,Mausoleo,,Mausoleumi,Le Mausolée,Mauzóleum,Mausoleo,霊廟,대영묘,,Mausoleet,Mauzoleum,Mausoléu,,Mausoleu,Мавзолей,Маузолеј,Anıt Mezar -Ochre Cliffs,HHUSTR_E5M1,,,,Okrové útesy,Okkerklipper,Ockerfarbene Klippen,,Klifoj de Okro,Acantilados Ocres,,Okrajyrkänteet,Les Falaises Ochre,Okker Szakadékok,Colline Ocra,黄土絶壁,황토 산맥,Okerkliffen,Oker-klippene,Ochrowe Klify,Penhascos Ocres,,Stâncile de ocru,Охровые утёсы,Окер брда,Ochre Kayalıkları -Rapids,HHUSTR_E5M2,,,,Peřeje,Rapider,Stromschnellen,,Rapidfluoj,Rápidos,,Koski,Les Rapides,Zuhatagok,Rapide,奔流,여울,Stroomversnellingen,Strykene,Katarakty,Corredeiras,,Ape repezi,Стремнина,Брзак,Akıntıları -Quay,HHUSTR_E5M3,,,,Nábřeží,Kaj,Kai,,Kajo,Muelle,,Satamalaituri,Le Quai,Rakpart,Banchina,岸壁,부두,Kade,Kai,Wir,Cais,,Chei,Причал,Пристаниште,Rıhtım -Courtyard,HHUSTR_E5M4,,,,Nádvoří,Slotsgården,Schlosshof,,Korto,Patio,,Linnanpiha,La Cour,Pitvar,Cortile,中庭,안마당,Binnenplaats,Gårdsplass,Dziedziniec,Pátio,,Curte,Внутренний двор,Двориште,Avlu -Hydratyr,HHUSTR_E5M5,,,,Hydratýr,,,,Akvotjr,Hydratyr,,,L'Hydratyr,Hidratáló,Hydratyr,ヒュドラテュール,식수공급처,,,Hydratyr,Reservatório,,Hidratir,Гидротир,Канализација,Hydratyr -Colonnade,HHUSTR_E5M6,,,,Kolonáda,Kolonnader,Kolonnaden,,Kolonaro,Columnata,,Pylväikkö,La Colonnade,Kolonnád,Colonnato,柱廊,열주의 길,Zuilengalerij,Kolonnade,Kolumnada,Colunata,,Colonadă,Колоннада,Колонада,Kolonat -Foetid Manse,HHUSTR_E5M7,,,,Smrdutá vila,Stinkende præstegård,Stinkendes Pfarrhaus,,Haladza Domego,Mansión Fétida,,Löyhkäävä kartano,Le Presbytère Fétide,Bűzös Parókia,Fetido Castello,悪臭の牧師館,역겨운 목사관,Stinkende pastorie,Stinkende prestegård,Cuchnąca Plebania,Mansão Fétida,,Conac Fetid,Зловонный особняк,Фетидна кућа,Foetid Manse -Field of Judgement,HHUSTR_E5M8,,,,Soudná pole,Dommervældet,Richtstätte,,Kampo de Juĝo,Campo de Juicio,,Tuomion kenttä,Les Champs du Jugement,Az Itélet Mezeje,Campo del Giudizio,審判之地,심판의 평야,Plaats van oordeelsvorming,Dømmekraftsområde,Pole Sądu,Campo de Julgamento,,Câmpul de Judecată,Поле высшего суда,Чистилиште,Yargı Alanı -Skein of D'sparil,HHUSTR_E5M9,,,,Hejno D'Sparilovo,D'sparils skein,DSparils Bau,,Fadenaro de D'Sparil,Madeja de D'Sparil,,D'Sparilin vyyhti,L'échevaux de D'Sparil,D'Sparil Káosza,Groviglio di D'Sparil,デ'スパリルの枷,드'스파릴의 타래,D'Sparil's gebouw,Garn av D'sparil,Motek D'Sparila,Meada de D'Sparil,,Jurubița lui D'Sparil,Путаница Д'Спарила,Реке Д'Спарила,D'sparil Çileği -,,Strife,,,,,,,,,,,,,,,,,,,,,,,, -AREA 1: Sanctuary,TXT_STRIFE_MAP01,,,,ZÓNA 1: Svatyně,AREA 1: Fristedet,ZONE 1: Heiligtum,,AREO 1: Sanktejo,ÁREA 1: Santuario,,ALUE 1: Pyhäkkö,ZONE 1: Sanctuaire,1. Terület: Szentély,AREA 1: Santuario,エリア 1: 聖域,구역 1: 성소,Zone 1: Heiligdom,OMRÅDE 1: Helligdom,Strefa 1: Sanktuarium,Área 1: Santuário,,ZONA 1: Sanctuar,МЕСТНОСТЬ 1: Святилище,,ALAN 1: Sığınak +Circle of Death ",,,Level 11: Kruh smrti,Level 11: Ødelæggelsens cirkel!,Level 11: 'O' der Zerstörung!,Επίπεδο 11: Ο Κύκλος της Καταστροφής,Nivelo 11: Morta cirklo,Nivel 11: Círculo de la muerte,,Taso 11: Hävityksen 'O',NIVEAU 11: Le Cercle de la Mort!,11. Pálya: A pusztulás köre,Livello 11: Il Cerchio della Morte,Level 11: 破滅の'O'!,레벨 11: 파괴의 고리,Level 11: 'O' van vernietiging!,Nivå 11: Ødeleggelsens 'O'!,Level 11: Krąg Śmierci,Fase 11: Círculo da Morte,Nível 11: Círculo da Morte,Nivelul 11: Cercul distrugerii,Уровень №11: Круг разрушения!,Level 11: Круг уништења,"Nivå 11: ""O"" av förstörelse!",Seviye 11: Yıkımın 'O'su! +Level 12: The Factory,HUSTR_12,,,,Level 12: Továrna,Level 12: Fabrikken,Level 12: Die Fabrik,Επίπεδο 12: To Εργοστάσιο,Nivelo 12: La Fabriko,Nivel 12: La Fábrica,,Taso 12: Tehdas,NIVEAU 12: L'Usine,12. Pálya: A gyár,Livello 12: La Fabbrica,Level 12: 工場,레벨 12: 공장,Level 12: De fabriek,Nivå 12: Fabrikken,Level 12: Fabryka,Fase 12: A Fábrica,Nível 12: A Fábrica,Nivelul 12: Fabrica,Уровень №12: Фабрика,Level 12: Фабрика,Nivå 12: Fabriken,Seviye 12: Fabrika +Level 13: Downtown,HUSTR_13,,,,Level 13: Centrum,Level 13: Centrum,Level 13: Stadtzentrum,Επίπεδο 13: Κέντρο,Nivelo 13: Urbocentro,Nivel 13: Centro de la Ciudad,,Taso 13: Keskikaupunki,NIVEAU 13: Centre-Ville,13. Pálya: Belváros,Livello 13: Periferia,Level 13: 市内,레벨 13: 번화가,Level 13: De binnenstad,Nivå 13: Sentrum,Level 13: Śródmieście,Fase 13: Centro Urbano,Nível 13: Centro Urbano,Nivelul 13: Centru urban,Уровень №13: Центр города,Level 13: Центар града,Nivå 13: Centrum,Seviye 13: Şehir Merkezi +Level 14: The Inmost Dens,HUSTR_14,,,,Level 14: Nejhlubší doupata,Level 14: Den inderste hule,Level 14: Die innersten Bauten,Επίπεδο 14: Οι Ενδότερες Φωλιές,Nivelo 14: La Internaj Kavernoj,Nivel 14: Los Antros más Recónditos,,Taso 14: Sisimmät piilot,NIVEAU 14: Les Antres Profondes,14. Pálya: A legmélyebb rejtekek,Livello 14: Gli Antri Profondi,Level 14: 最深巣窟,레벨 14: 깊숙한 동굴들,Level 14: De binnenste gebouwen,Nivå 14: De innerste huler,Level 14: Najgłębsze Nory,Fase 14: Os Antros Profundos,Nível 14: Os Antros Profundos,Nivelul 14: Cele mai intime bârloguri,Уровень №14: Глубочайшие логовища,Level 14: Најдубље јазбине,Nivå 14: Den innersta täkten,Seviye 14: En İçteki İnler +Level 15: Industrial Zone,HUSTR_15,,,,Level 15: Průmyslová zóna,Level 15: Industriområde,Level 15: Industriegebiet,Επίπεδο 15: Βιομηχανική Ζώνη,Nivelo 15: Industria Zono,Nivel 15: Zona Industrial,,Taso 15: Teollisuusalue,NIVEAU 15: Zone Industrielle,15. Pálya: Ipari zóna,Livello 15: Zona Industriale,Level 15: 工業地帯,레벨 15: 공업 지대,Level 15: Industriegebied,Nivå 15: Industriområdet,Level 15: Strefa Przemysłowa,Fase 15: Zona Industrial,Nível 15: Zona Industrial,Nivelul 15: Zona industrială,Уровень №15: Промышленный район,Level 15: Индустријска зона,Nivå 15: Industriområde,Seviye 15: Sanayi Bölgesi +Level 16: Suburbs,HUSTR_16,,,,Level 16: Předměstí,Level 16: Forstæderne,Level 16: Vororte,Επίπεδο 16: Προάστια,Nivelo 16: Antaŭurboj,Nivel 16: Suburbios,,Taso 16: Lähiö,NIVEAU 16: Banlieue,16. Pálya: Külváros,Livello 16: Sobborghi,Level 16: 郊外,레벨 16: 교외,Level 16: Buitenwijken,Nivå 16: Forstedene,Level 16: Przedmieścia,Fase 16: Subúrbios,Nível 16: Subúrbios,Nivelul 16: Suburbi,Уровень №16: Пригород,Level 16: Предграђе,Nivå 16: Förorter,Seviye 16: Banliyöler +Level 17: Tenements,HUSTR_17,,,,Level 17: Sídliště,Level 17: Lejligheder,Level 17: Wohnbezirk,Επίπεδο 17: Καταλύματα,Nivelo 17: Loĝejoj,Nivel 17: Viviendas,,Taso 17: Vuokratalot,NIVEAU 17: Immeubles,17. Pálya: Bérházak,Livello 17: Possedimenti,Level 17: 安アパート,레벨 17: 공동주택,Level 17: Huurwoningen,Nivå 17: Leiegårder,Level 17: Kamienice,Fase 17: Habitações,Nível 17: Habitações,Nivelul 17: Proprietăți,Уровень №17: Владения,Level 17: Станови,Nivå 17: Hyreshus,Seviye 17: Kiralık Evler +Level 18: The Courtyard,HUSTR_18,,,,Level 18: Nádvoří,Level 18: Gårdspladsen,Level 18: Der Innenhof,Επίπεδο 18: Η Αυλή,Nivelo 18: La Korto,Nivel 18: El Patio,,Taso 18: Esipiha,NIVEAU 18: La Cour,18. Pálya: Az udvar,Livello 18: Il Cortile,Level 18: 中庭,레벨 18: 중정,Level 18: De binnenplaats,Nivå 18: Gårdsplassen,Level 18: Dziedziniec,Fase 18: O Átrio,Nível 18: O Átrio,Nivelul 18: Curtea,Уровень №18: Внутренний двор,Level 18: Двориште,Nivå 18: Gården,Seviye 18: Avlu +Level 19: The Citadel,HUSTR_19,,,,Level 19: Citadela,Level 19: Citadellet,Level 19: Die Zizadelle,Επίπεδο 19: Το Κάστρο,Nivelo 19: La Citadelo,Nivel 19: La Ciudadela,,Taso 19: Linnoitus,NIVEAU 19: La Citadelle,19. Pálya: Fellegvár,Livello 19: La Cittadella,Level 19: 要塞,레벨 19: 성채,Level 19: De citadel,Nivå 19: Citadellet,Level 19: Cytadela,Fase 19: A Cidadela,Nível 19: A Cidadela,Nivelul 19: Cetatea,Уровень №19: Цитадель,Level 19: Цитадела,Nivå 19: Citadellet,Seviye 19: Hisar +Level 20: Gotcha!,HUSTR_20,,,,Level 20: Mám tě!,,Level 20: Erwischt!,Επίπεδο 20: Σ'έπιασα!,Nivelo 20: Kaptis Vin!,Nivel 20: ¡Te pillé!,Nivel 20: ¡Te tengo!,Taso 20: Sainpas sinut!,NIVEAU 20: Je t'ai eu!,20. Pálya: Megvagy!,Livello 20: Preso!,Level 20: 捉らえた!,레벨 20: 잡았다!,Level 20: Ik heb je!,Nivå 20: Fikk deg!,Level 20: Mam Cię!,Fase 20: Te Peguei!,Nível 20: Apanhei-te!,Nivelul 20: Te-am prins!,Уровень №20: Попался!,Level 20: Имају те!,Nivå 20: Gotcha!,Seviye 20: Yakaladım! +Level 21: Nirvana,HUSTR_21,,,,Level 21: Nirvána,,,Επίπεδο 21: Νιρβάνα,Nivelo 21: Nirvano,Nivel 21: Nirvana,,,NIVEAU 21: Nirvana,21. Pálya: Nirvána,Livello 21: Nirvana,Level 21: 涅槃,레벨 21: 열반,,,,Fase 21: Nirvana,Nível 21: Nirvana,Nivelul 21: Nirvana,Уровень №21: Нирвана,Level 21: Нирвана,Nivå 21: Nirvana,Seviye 21: Nirvana +Level 22: The Catacombs,HUSTR_22,,,,Level 22: Katakomby,Level 22: Katakomberne,Level 22: Katakomben,Επίπεδο 22: Οι Κατακόμβες,Nivelo 22: La Katakomboj,Nivel 22: Las Catacumbas,,Taso 22: Katakombit,NIVEAU 22: Les Catacombes,22. Pálya: A katakombák,Livello 22: Le Catacombe,Level 22: 地下悪霊墓所,레벨 22: 지하 묘지,Level 22: De catacomben,Nivå 22: Katakombene,Level 22: Katakumby,Fase 22: As Catacumbas,Nível 22: Os Calabouços,Nivelul 22: Catacombe,Уровень №22: Катакомбы,Level 22: Катакомбе,Nivå 22: Katakomberna,Seviye 22: Yeraltı Mezarları +Level 23: Barrels O' Fun,HUSTR_23,,,,Level 23: Barely srandy,Level 23: Tønder af sjov,Level 23: Lustige Fässer,,Nivelo 23: Bareloj de Amuzo,Nivel 23: Barriles de Diversión,,Taso 23: Huvitynnyrit,NIVEAU 23: Une Tonne-eau de plaisir,23. Pálya: Mókás hordók,Livello 23: Barili da Sballo,Level 23: 戯れのバレル,레벨 23: 신나는 폭발통들,Level 23: Grappige vaten,Nivå 23: Tønner med moro,Level 23: Beczki Śmiechu,Fase 23: Barris de Diversão,Nível 23: Barris de Diversão,Nivelul 23: Butoaiele veseliei,Уровень №23: Бочки веселья,Level 23: Бачве забаве,Nivå 23: Tunnor med kul,Seviye 23: Eğlence Fıçıları +Level 24: The Chasm,HUSTR_24,,,,Level 24: Rokle,Level 24: Kløften,Level 24: Die Kluft,Επίπεδο 24: Το Χάσμα,Nivelo 24: La Fendego,Nivel 24: El Desfiladero,,Taso 24: Rotko,NIVEAU 24: Le Gouffre,24. Pálya: A szakadék,Livello 24: L'Abisso,Level 24: 裂け目,레벨 24: 협곡,Level 24: De afgrond,Nivå 24: Avgrunnen,Level 24: Przepaść,Fase 24: O Abismo,Nível 24: O Abismo,Nivelul 24: Hăul,Уровень №24: Пропасть,Level 24: Провалија,Nivå 24: Klyftan,Seviye 24: Uçurum +Level 25: Bloodfalls,HUSTR_25,,,,Level 25: Krvopády,Level 25: Blodfald,Level 25: Blutfälle,Επίπεδο 25: Καταρράκτες Αίματος,Nivelo 25: Sangfaloj,Nivel 25: Cataratas de Sangre,,Taso 25: Veriputoukset,NIVEAU 25: Chutes de Sang,25. Pálya: Véresések,Livello 25: Cascate di Sangue,Level 25: 血の滝,레벨 25: 혈폭포,Level 25: Bloeddruppels,Nivå 25: Blodfall,Level 25: Wodospad Krwi,Fase 25: Cataratas de Sangue,Nível 25: Cascatas de Sangue,Nivelul 25: Cascade de sânge,Уровень №25: Кровопады,Level 25: Крвопади,Nivå 25: Blodfall,Seviye 25: Kan Düşüşleri +Level 26: The Abandoned Mines,HUSTR_26,,,,Level 26: Opuštěné doly,Level 26: De forladte miner,Level 26: Die aufgegebene Mine,Επίπεδο 26: Τα Εγκαταλελειμμένα Ορυχεία,Nivelo 26: La Forlasitaj Minoj,Nivel 26: Las Minas Abandonadas,,Taso 26: Hylätyt kaivokset,NIVEAU 26: Les Mines Abandonnées,26. Pálya: Az elhagyatott bányák,Livello 26: Le Miniere Abbandonate,Level 26: 廃鉱山,레벨 26: 버려진 광산,Level 26: De verlaten mijnen,Nivå 26: De forlatte gruvene,Level 26: Opuszczone Kopalnie,Fase 26: As Minas Abandonadas,Nível 26: As Minas Abandonadas,Nivelul 26: Minele părăsite,Уровень №26: Заброшенные шахты,Level 26: Напуштени рудници,Nivå 26: De övergivna gruvorna,Seviye 26: Terk Edilmiş Madenler +Level 27: Monster Condo,HUSTR_27,,,,Level 27: Netvoří dům,,Level 27: Monsterbehausung,,Nivelo 27: Monstro-Domo,Nivel 27: Condominio de Monstruos,,Taso 27: Hirviöasuntola,NIVEAU 27: Monstrueuse Résidence,27. Pálya: A szörnyek háza,Livello 27: Casa dei Mostri,Level 27: モンスターマンション,레벨 27: 괴물 콘도,,Nivå 27: Monsterleiligheten,Level 27: Apartament Potworów,Fase 27: Mansão dos Monstros,Nível 27: Condomínio Monstruoso,Nivelul 27: Casa monștrilor,Уровень №27: Жилище монстров,Level 27: Боравишта монструма,Nivå 27: Monster Condo,Seviye 27: Canavar Dairesi +Level 28: The Spirit World,HUSTR_28,,,,Level 28: Onen svět,Level 28: Åndeverdenen,Level 28: Die Geisterwelt,Επίπεδο 28: Ο Κόσμος των Πνευμάτων,Nivelo 28: La Animo-Mondo,Nivel 28: El Mundo Espiritual,,Taso 28: Henkimaailma,NIVEAU 28: Le Monde Spirituel,28. Pálya: A lelkek világa,Livello 28: Il Mondo dello Spirito,Level 28: 悪霊の世界,레벨 28: 영령의 세계,Level 28: De geestenwereld,Nivå 28: Åndeverdenen,Level 28: Świat Dusz,Fase 28: O Mundo Espiritual,Nível 28: O Mundo Espiritual,Nivelul 28: Lumea duhurilor,Уровень №28: Мир духов,Level 28: Духовни свет,Nivå 28: Den andliga världen,Seviye 28: Ruhlar Dünyası +Level 29: The Living End,HUSTR_29,,,,Level 29: Živoucí konec,Level 29: Den levende ende,Level 29: Das lebende Ende,Επίπεδο 29: Το Ζωντανό Τέλος,Nivelo 29: La Viva Fino,Nivel 29: El Final Viviente,,Taso 29: Elävä loppu,NIVEAU 29: La Limite,29. Pálya: Az élő Végzet,Livello 29: La Fine Imminente,Level 29: 極限の存在,레벨 29: 최종점,Level 29: Het levende einde,Nivå 29: Den levende enden,Level 29: Żywy Koniec,Fase 29: O Cúmulo da Existência,Nível 29: O Cúmulo da Existência,Nivelul 29: Sfârșitul întregii vieți,Уровень №29: Конец всего живого,Level 29: Крај живота,Nivå 29: Det levande slutet,Seviye 29: Yaşamın Sonu +Level 30: Icon of Sin,HUSTR_30,,,,Level 30: Ikona hříchu,Level 30: Syndens ikon,Level 30: Symbol der Sünde,Επίπεδο 30: Σύμβολο της Αμαρτίας,Nivelo 30: Ikono de Peko,Nivel 30: Icono del pecado,Nivel 30: Ícono del pecado,Taso 30: Synnin ikoni,NIVEAU 30: L'Icône du Péché,30. Pálya: A megtestesült bűn,Livello 30: Icona del Peccato,Level 30: 罪の聖像,레벨 30: 죄악의 상징,Level 30: Pictogram van de zonde,Nivå 30: Syndens ikon,Level 30: Ikona Grzechu,Fase 30: Ícone do Pecado,Nível 30: Ícone do Pecado,Nivelul 30: Icoana păcatelor,Уровень №30: Икона греха,Level 30: Икона греха,Nivå 30: Syndens ikon,Seviye 30: Günah Simgesi +Level 31: Wolfenstein,HUSTR_31,,,,,,,,Nivelo 31: Wolfenstein,Nivel 31: Wolfenstein,,,,31. Pálya: Wolfenstein,Livello 31: Wolfenstein,Level 31: ウルフェンシュタイン,레벨 31: 울펜슈타인,,,,Fase 31: Wolfenstein,Nível 31: Wolfenstein,Nivelul 31: Wolfenstein,Уровень №31: Вольфенштайн,Level 31: Волфенштајн,Nivå 31: Wolfenstein,Seviye 31: Wolfenstein +Level 32: Grosse,HUSTR_32,,,,,,,,Nivelo 32: Grosse,Nivel 32: Grosse,,,,32. Pálya: Grosse,Livello 32: Grosse,Level 32: グローシュ,레벨 32: 그로세,,,,Fase 32: Grosse,Nível 32: Grosse,Nivelul 32: Grosse,Уровень №32: Гросс,Level 32: Гроссе,Nivå 32: Grosse,Seviye 32: Grosse +Level 31: IDKFA,HUSTR_31B,,,,,,,,Nivelo 31: IDKFA,Nivel 31: IDKFA,,,NIVEAU 31: IDKFQ,31. Pálya: IDKFA,Livello 31: IDKFA,Level 31: IDKFA,레벨 31: IDKFA,,,,Fase 31: IDKFA,Nível 31: IDKFA,Nivelul 31: IDKFA,Уровень №31: IDKFA,,Nivå 31: IDKFA,Seviye 31: IDKFA +Level 32: Keen,HUSTR_32B,,,,,,,,Nivelo 32: Keen,Nivel 32: Keen,,,,32. Pálya: Keen,Livello 32: Keen,Level 32: キーン,레벨 32: 킨,,,,Fase 32: Keen,Nível 32: Keen,Nivelul 32: Keen,Уровень №32: Кин,Level 32: Кин,Nivå 32: Keen,Seviye 32: Keen +Level 33: Betray,HUSTR_33,,,,Level 33: Zraď,Level 33: Forræderi,Level 33: Verrat,,Nivelo 33: Perfido,Nivel 33: Traición,,Taso 33: Petä,NIVEAU 33: Trahison,33. Pálya: Árulás,Livello 33: Tradimento ,Level 33: 裏切り,레벨 33: 배반,Level 33: Verraad,Nivå 33: Forråde,Level 33: Zdrada,Fase 33: Traição,Nível 33: Traição,Nivelul 33: Trădare,Уровень №33: Предай,Level 33: Издаја,Nivå 33: Förråda,Seviye 33: İhanet +,,No Rest For The Living,,,,,,,,,,,,,,,,,,,,,,,,, +Level 1: The Earth Base,NHUSTR_1,,,,Level 1: Pozemská základna,Level 1: Jordbasen,Level 1: Die Erd-Basis,,Nivelo 1: La Tera Bazo,Nivel 1: La Base Terrestre,,Taso 1: Maatukikohta,NIVEAU 1: La Base Terrienne,1. Pálya: A földi bázis,Livello 1: La Base Terrestre ,Level 1: 地球基地,레벨 1: 지구 기지,Level 1: De basis van de aarde,Nivå 1: Jordbasen,Level 1: Ziemska Baza,Fase 1: A Base Terrestre,Nível 1: A Base Terrestre,Nivelul 1: Baza terestră,Уровень №1: База на Земле,Level 1: Земаљска база,Nivå 1: Jordbasen,Seviye 1: Dünya Üssü +Level 2: The Pain Labs,NHUSTR_2,,,,Level 2: Laboratoře bolesti,Level 2: Smerte laboratorier,Level 2: Die Folterlabore,,Nivelo 2: La Doloro-Laboratorio,Nivel 2: Los Laboratorios del Dolor,,Taso 2: Tuskalaboratoriot,NIVEAU 2: Les Laboratoires de la Douleur,2. Pálya: A kínok laboratóriuma,Livello 2: I Laboratori del Dolore,Level 2: 生物工学実験室,레벨 2: 고통의 연구소,Level 2: De pijnlaboratoria,Nivå 2: Smertelaboratoriet,Level 2: Laboratoria Bólu,Fase 2: Os Laboratórios da Dor,Nível 2: Os Laboratórios da Dor,Nivelul 2: Laboratoarele durerii,Уровень №2: Лаборатории боли,Level 2: Лабораторије патње,Nivå 2: Smärtlaboratorierna,Seviye 2: Ağrı Laboratuvarları +Level 3: Canyon of The Dead,NHUSTR_3,,,,Level 3: Kaňon mrtvých,Level 3: De dødes kløft,Level 3: Schlucht der Toten,,Nivelo 3: Kanjono de La Mortintoj,Nivel 3: Cañón de los Muertos,,Taso 3: Kalmankanjoni,NIVEAU 3: Canyon des Morts,3. Pálya: A holtak szurdoka,Livello 3: Il Canyon dei Morti,Level 3: 死の渓谷,레벨 3: 죽음의 계곡,Level 3: Canyon van de doden,Nivå 3: De dødes kløft,Level 3: Kanion Umarłych,Fase 3: Desfiladeiro dos Mortos,Nível 3: Desfiladeiro dos Mortos,Nivelul 3: Canionul morților,Уровень №3: Каньон мертвецов,Level 3: Кањон мртваца,Nivå 3: De dödas kanjon,Seviye 3: Ölüler Kanyonu +Level 4: Hell Mountain,NHUSTR_4,,,,Level 4: Pekelná hora,Level 4: Helvede bjerg,Level 4: Höllenberg,,Nivelo 4: Monto de Infero,Nivel 4: Montaña Infernal,,Taso 4: Hornanvuori,NIVEAU 4: Montagne Infernale,4. Pálya: Pokol-hegy,Livello 4: Montagna Infernale ,Level 4: 地獄山脈,레벨 4: 지옥의 산,Level 4: Helleberg,Nivå 4: Helvetesfjellet,Level 4: Piekielna Góra,Fase 4: Montanha Infernal,Nível 4: Montanha Infernal,Nivelul 4: Muntele infernal,Уровень №4: Адская гора,Level 4: Планина пакла,Nivå 4: Helvetesberget,Seviye 4: Cehennem Dağı +Level 5: Vivisection,NHUSTR_5,,,,Level 5: Vivisekce,Level 5: Vivisektion,Level 5: Vivisektion,,Nivelo 5: Vivisekcio,Nivel 5: Vivisección,,Taso 5: Vivisektio,NIVEAU 5: Vivisection,5. Pálya: Élveboncolás,Livello 5: Vivisezione ,Level 5: 生体解剖,레벨 5: 생체 해부,Level 5: Vivisectie,Nivå 5: Viviseksjon,Level 5: Wiwisekcja,Fase 5: Vivissecção,Nível 5: Vivissecção,Nivelul 5: Vivisecție,Уровень №5: Вивисекция,Level 5: Вивисекција,Nivå 5: Vivisektion,Seviye 5: Canlı Kesim +Level 6: Inferno of Blood,NHUSTR_6,,,,Level 6: Krvavé inferno,Level 6: Blodets inferno,Level 6: Blutiges Inferno,,Nivelo 6: Brulego de Sango,Nivel 6: Hoguera de Sangre,,Taso 6: Veri-inferno,NIVEAU 6: Enfer Sanglant,6. Pálya: Véres alvilág,Livello 6: Inferno di Sangue ,Level 6: 血のインフェルノ,레벨 6: 연옥의 피,Level 6: Bloederige inferno,Nivå 6: Blodets inferno,Level 6: Piekło Krwi,Fase 6: Inferno de Sangue,Nível 6: Inferno de Sangue,Nivelul 6: Infern sângeriu,Уровень №6: Кровавая преисподняя,Level 6: Ватре крви,Nivå 6: Blodets inferno,Seviye 6: Kan Cehennemi +Level 7: Baron's Banquet,NHUSTR_7,,,,Level 7: Baronova hostina,Level 7: Baron's Banquet,Level 7: Das Bankett des Barons,,Nivelo 7: Festeno de Barono,Nivel 7: Banquete del Barón,,Taso 7: Paronin pidot,NIVEAU 7: Banquet du Baron,7. Pálya: A báró bankettje,Livello 7: Il Banchetto del Barone ,Level 7: バロンの晩餐,레벨 7: 남작의 연회,Level 7: Baron's banket,Nivå 7: Baronens bankett,Level 7: Bankiet Barona,Fase 7: Banquete do Barão,Nível 7: Banquete do Barão,Nivelul 7: Banchetul baronilor,Уровень №7: Банкет у барона,Level 7: Баронова Гозба,Nivå 7: Baronens bankett,Seviye 7: Baron'un Ziyafeti +Level 8: Tomb of Malevolence,NHUSTR_8,,,,Level 8: Hrobka zlovolnosti,Level 8: Ondskabens grav,Level 8: Feindselige Gruft,,Nivelo 8: Tombo de Malbonvolo,Nivel 8: Tumba de Malevolencia,,Taso 8: Pahantahdon hauta,NIVEAU 8: Tombe Maléfique,8. Pálya: A Gátlástalanság sírja,Livello 8: Tomba della Malevolenza,Level 8: 悪意の墓,레벨 8: 증오의 무덤,Level 8: Graf van kwaadwilligheid,Nivå 8: Ondskapens grav,Level 8: Grobowiec Zła,Fase 8: Tumba da Malevolência,Nível 8: Túmulo da Malevolência,Nivelul 8: Mormântul răutății,Уровень №8: Гробница злобы,Level 8: Гроб злобе,Nivå 8: Ondskans grav,Seviye 8: Kötülük Mezarı +Level 9: March of The Demons,NHUSTR_9,,,,Level 9: Pochod démonů,Level 9: Dæmonernes march,Level 9: Marsch der Dämonen,,Nivelo 9: Marŝo de La Demonoj,Nivel 9: Marcha de los Demonios,,Taso 9: Demonien marssi,NIVEAU 9: Marche des Démons,9. Pálya: A démonok parádéja,Livello 9: La Marcia dei Demoni ,Level 9: デーモンの行進,레벨 9: 악마들의 행진,Level 9: Maart van de demonen,Nivå 9: Demonenes marsj,Level 9: Marsz Demonów,Fase 9: Marcha dos Demônios,Nível 9: Marcha dos Demônios,Nivelul 9: Marșul demonilor,Уровень №9: Шествие демонов,Level 9: Марш демона,Nivå 9: Demonernas marsch,Seviye 9: Şeytanların Yürüyüşü +,,Plutonia,,,,,,,,,,,,,,,,,,,,,,,,, +Level 1: Congo,PHUSTR_1,,,,Level 1: Kongo,,Level 1: Kongo,,Nivelo 1: Kongo,Nivel 1: Congo,,Taso 1: Kongo,NIVEAU 1: Congo,1. Pálya: Kongó,Livello 1: Congo,Level 1: コンゴ川,레벨 1: 콩고,Level 1: Kongo,Nivå 1: Kongo,Level 1: Kongo,Fase 1: Congo,Nível 1: Congo,Nivelul 1: Congo,Уровень №1: Конго,Level 1: Конго,Nivå 1: Kongo,Seviye 1: Kongo +Level 2: Well of Souls,PHUSTR_2,,,,Level 2: Studna duší,Level 2: Sjælebrønden,Level 2: Seelenbrunnen,,Nivelo 2: Puto de Animoj,Nivel 2: Pozo de Almas,,Taso 2: Sielujen lähde,NIVEAU 2: Puits des Ames,2. Pálya: A lelkek kútja,Livello 2: Pozzo delle Anime,Level 2: 魂の井戸,레벨 2: 영혼의 우물,Level 2: Bron van zielen,Nivå 2: Sjelenes brønn,Level 2: Studnia Dusz,Fase 2: Poço das Almas,Nível 2: Poço de Almas,Nivelul 2: Fântâna sufletelor,Уровень №2: Колодец душ,Level 2: Бунар душа,Nivå 2: Själarnas brunn,Seviye 2: Ruhlar Kuyusu +Level 3: Aztec,PHUSTR_3,,,,Level 3: Azték,Level 3: Azteker,Level 3: Aztekisch,,Nivelo 3: Azteko,Nivel 3: Azteca,,Taso 3: Asteekki,NIVEAU 3: Aztèque,3. Pálya: Azték,Livello 3: Aztec,Level 3: アステカ,레벨 3: 아즈텍,Level 3: Azteken,Nivå 3: Aztekisk,Level 3: Aztek,Fase 3: Asteca,Nível 3: Asteca,Nivelul 3: Aztec,Уровень №3: Ацтек,Level 3: Астек,Nivå 3: Azteker,Seviye 3: Aztek +Level 4: Caged,PHUSTR_4,,,,Level 4: V kleci,Level 4: Låst op,Level 4: Eingesperrt,,Nivelo 4: Enkaĝigita,Nivel 4: Enjaulado,,Taso 4: Häkissä,NIVEAU 4: Enfermé,4. Pálya: Ketrecbe zárva,Livello 4: Ingabbiato,Level 4: 檻の中,레벨 4: 갇히다,Level 4: Gekooid,Nivå 4: Buret,Level 4: W Klatce,Fase 4: Na Jaula,Nível 4: Na Jaula,Nivelul 4: Încarcerat,Уровень №4: В клетке,Level 4: Заробљен,Nivå 4: Burad,Seviye 4: Kafesli +Level 5: Ghost Town,PHUSTR_5,,,,Level 5: Město duchů,Level 5: Spøgelsesby,Level 5: Geisterstadt,,Nivelo 5: Fantomurbeto,Nivel 5: Pueblo Fantasma,,Taso 5: Aavekaupunki,NIVEAU 5: Ville Fantôme,5. Pálya: Szellemváros,Livello 5: Città Fantasma,Level 5: ゴーストタウン,레벨 5: 유령 도시,Level 5: Spookstad,Nivå 5: Spøkelsesbyen,Level 5: Miasto Duchów,Fase 5: Cidade Fantasma,Nível 5: Cidade Fantasma,Nivelul 5: Orașul fantomă,Уровень №5: Город-призрак,Level 5: Град духова,Nivå 5: Spökstad,Seviye 5: Hayalet Kasaba +Level 6: Baron's Lair,PHUSTR_6,,,,Level 6: Baronovo doupě,Level 6: Baronens hule,Level 6: Lager des Barons,,Nivelo 6: Nestego de Barono,Nivel 6: Guarida del Barón,,Taso 6: Paronin luola,NIVEAU 6: Repaire du Baron,6. Pálya: A báró rejteke,Livello 6: Tana del Barone,Level 6: バロンの隠れ家,레벨 6: 남작의 은신처,Level 6: Baron's kamp,Nivå 6: Baronens hule,Level 6: Legowisko Barona,Fase 6: Covil do Barão,Nível 6: Covil do Barão,Nivelul 6: Claustrul Baronului,Уровень №6: Обитель барона,Level 6: Баронова јазбина,Nivå 6: Baronens lya,Seviye 6: Baron'un İni +Level 7: Caughtyard,PHUSTR_7,,,,Level 7: Karcer,,Level 7: Gehege,,Nivelo 7: Kaptkorto,Nivel 7: Campo de Concentración,,Taso 7: Posenpiha,NIVEAU 7: Pris de court,7. Pálya: A foglyok udvara,Livello 7: Cortile Prigione,Level 7: 囚われの庭,레벨 7: 포획마당,Level 7: Omheining,Nivå 7: Fangegården,Level 7: Dziedziniec Więzienny,Fase 7: Campo de Concentração,Nível 7: Campo de Concentração,Nivelul 7: Capcana curții,Уровень №7: Ловчий двор,Level 7: Замчиште,Nivå 7: Fångården,Seviye 7: Caughtyard +Level 8: Realm,PHUSTR_8,,,,Level 8: Říše,Level 8: Rige,Level 8: Bereich,,Nivelo 8: Regno,Nivel 8: Reino,,Taso 8: Valtapiiri,NIVEAU 8: Royaume,8. Pálya: Uradalom,Livello 8: Regno,Level 8: 領地,레벨 8: 왕국,Level 8: Rijk,Nivå 8: Riket,Level 8: Królestwo,Fase 8: Reino,Nível 8: Reino,Nivelul 8: Tărâm,Уровень №8: Царство,Level 8: Царство,Nivå 8: Riket,Seviye 8: Diyar +Level 9: Abattoire,PHUSTR_9,,,,Level 9: Jatka,,Level 9: Schlachthaus,,Nivelo 9: Buĉejo,Nivel 9: Matadero,,Taso 9: Teurastamo,NIVEAU 9: Abattoir,9. Pálya: Vágóhíd,Livello 9: Mattatoio,Level 9: 屠殺場,레벨 9: 도축장,Level 9: Abattoir,Nivå 9: Slakteriet,Level 9: Rzeźnia,Fase 9: Matadouro,Nível 9: Matadouro,Nivelul 9: Abator,Уровень №9: Абатство,Level 9: Кланица,Nivå 9: Slakthus,Seviye 9: Abattoire +Level 10: Onslaught,PHUSTR_10,,,,Level 10: Nájezd,Level 10: Stormløb,Level 10: Angriff,,Nivelo 10: Buĉado,Nivel 10: Arremetida,,Taso 10: Ryntäys,NIVEAU 10: Assaut,10. Pálya: Roham,Livello 10: Assalto,Level 10: 猛襲,레벨 10: 맹공격,Level 10: Aanval,Nivå 10: Angrep,Level 10: Szturm,Fase 10: Investida,Nível 10: Investida,Nivelul 10: Năvala,Уровень №10: Натиск,Level 10: Јуриш,Nivå 10: Angrepp,Seviye 10: Saldırı +Level 11: Hunted,PHUSTR_11,,,,Level 11: Loven,Level 11: Jaget,Level 11: Gehetzt,,Nivelo 11: Ĉasata,Nivel 11: Cazado,,Taso 11: Metsästetty,NIVEAU 11: Traque,11. Pálya: Űzött vad,Livello 11: Braccato,Level 11: 逃走,레벨 11: 사냥당함,Level 11: Gejaagd,Nivå 11: Jaget,Level 11: Nawiedzony,Fase 11: Perseguição,Nível 11: Perseguição,Nivelul 11: Vânătoarea,Уровень №11: Преследуемый,Level 11: Уловљен,Nivå 11: Jaktad,Seviye 11: Avlanmış +Level 12: Speed,PHUSTR_12,,,,Level 12: Rychlost,Level 12: Fart,Level 12: Tempo,,Nivelo 12: Rapido,Nivel 12: Velocidad,,Taso 12: Vauhti,NIVEAU 12: Vitesse,12. Pálya: Iram,Livello 12: Velocità,Level 12: スピード,레벨 12: 스피드,Level 12: Haast,Nivå 12: Hastighet,Level 12: Pęd,Fase 12: Velocidade,Nível 12: Velocidade,Nivelul 12: Viteză,Уровень №12: Скорость,Level 12: Брзина,Nivå 12: Hastighet,Seviye 12: Hız +Level 13: The Crypt,PHUSTR_13,,,,Level 13: Krypta,Level 13: Krypten,Level 13: Die Gruft,,Nivelo 13: La Kripto,Nivel 13: La Cripta,,Taso 13: Krypta,NIVEAU 13: La Crypte,13. Pálya: A kripta,Livello 13: La Cripta,Level 13: 地下聖堂,레벨 13: 봉안당,Level 13: De crypte,Nivå 13: Krypten,Level 13: Krypta,Fase 13: A Cripta,Nível 13: A Cripta,Nivelul 13: Cripta,Уровень №13: Склеп,Level 13: Гробница,Nivå 13: Kryptan,Seviye 13: Mahzen +Level 14: Genesis,PHUSTR_14,,,,,,,,Nivelo 14: Genezo,Nivel 14: Génesis,,Taso 14: Luominen,NIVEAU 14: Genèse,14. Pálya: Teremtés,Livello 14: Genesi,Level 14: 創世記,레벨 14: 창세기,,,Level 14: Geneza,Fase 14: Gênese,Nível 14: Gênese,Nivelul 14: Geneza,Уровень №14: Зарождение,Level 14: Постанак,Nivå 14: Genesis,Seviye 14: Yaratılış +Level 15: The Twilight,PHUSTR_15,,,,Level 15: Soumrak,Level 15: Tusmørket,Level 15: Zwielicht,,Nivelo 15: La Krepusko,Nivel 15: El Ocaso,,Taso 15: Hämärä,NIVEAU 15: Le Crépuscule,15. Pálya: Alkonyat,Livello 15: Il Crepuscolo,Level 15: 黄昏,레벨 15: 황혼,Level 15: De schemering,Nivå 15: Skumringen,Level 15: Zmierzch,Fase 15: O Crepúsculo,Nível 15: O Crepúsculo,Nivelul 15: Amurgul,Уровень №15: Сумерки,Level 15: Сумрак,Nivå 15: Skymningen,Seviye 15: Alacakaranlık +Level 16: The Omen,PHUSTR_16,,,,Level 16: Znamení,Level 16: Omenet,Level 16: Das Omen,,Nivelo 16: La Aŭguro,Nivel 16: El Presagio,,Taso 16: Enne,NIVEAU 16: Le Présage,16. Pálya: Az Ómen,Livello 16: Il Presagio,Level 16: 予兆,레벨 16: 징조,Level 16: De omen,Nivå 16: Varselet,Level 16: Omen,Fase 16: O Presságio,Nível 16: O Presságio,Nivelul 16: Prevestirea,Уровень №16: Предзнаменование,Level 16: Знамење,Nivå 16: Omen,Seviye 16: Omen +Level 17: Compound,PHUSTR_17,,,,Level 17: Ústav,Level 17: Forbindelsen,Level 17: Anlage,,Nivelo 17: Konstruaĵaro,Nivel 17: Complejo,,Taso 17: Laitos,NIVEAU 17: Installation,17. Pálya: Létesítmény,Livello 17: Recinto,Level 17: 調合,레벨 17: 복합체,Level 17: Faciliteit,Nivå 17: Forbindelsen,Level 17: Mieszanka,Fase 17: Complexo,Nível 17: Complexo,Nivelul 17: Complexul,Уровень №17: Комплекс,Level 17: Једињење,Nivå 17: Förbandet,Seviye 17: Bileşik +Level 18: Neurosphere,PHUSTR_18,,,,Level 18: Neurosféra,Level 18: Neurosfæren,Level 18: Neurosphäre,,Nivelo 18: Neŭrosfero,Nivel 18: Neuroesfera,,Taso 18: Neurosfääri,NIVEAU 18: Neurosphère,18. Pálya: Neuroszféra,Livello 18: Neurosfera,Level 18: ニューロスフィア,레벨 18: 뉴로스피어,Level 18: Neurosferen,Nivå 18: Nevrosfæren,Level 18: Neurosfera,Fase 18: Neurosfera,Nível 18: Neurosfera,Nivelul 18: Neurosferă,Уровень №18: Нейросфера,Level 18: Неуросфера,Nivå 18: Neurosfären,Seviye 18: Nörosfer +Level 19: NME,PHUSTR_19,"“NME” read out loud means “enemy”, so translators should consider the translation of “enemy” into their language.",,,Level 19: Nepřítel,,,,Nivelo 19: Mal-BN,Nivel 19: N-MIGO,,Taso 19: VHLLNN,NIVEAU 19: NMI,19. Pálya: LNSG,Livello 19: NMIC,Level 19: 野郎,레벨 19: NOM,,,Level 19: WRG,Fase 19: N-MIGO,Nível 19: N-MIGO,Nivelul 19: INMIC,Уровень №19: В.Р.А.Г.,Level 19: Н.Е.П.Р.,Nivå 19: FiND,Seviye 19: NME +Level 20: The Death Domain,PHUSTR_20,,,,Level 20: Panství smrti,Level 20: Dødsdomænet,Level 20: Die Todeszone,,Nivelo 20: La Regno de Morto,Nivel 20: El Dominio Mortal,,Taso 20: Kuoleman piiri,NIVEAU 20: Le Domaine de la Mort,20. Pálya: A holtak birtoka,Livello 20: Il Dominio della Morte,Level 20: 死の領域,레벨 20: 죽음의 영역,Level 20: Het domein van de dood,Nivå 20: Dødens domene,Level 20: Domena Śmierci,Fase 20: O Domínio da Morte,Nível 20: O Domínio da Morte,Nivelul 20: Domeniul morții,Уровень №20: Владения смерти,Level 20: Подручије смрти,Nivå 20: Dödsdomänen,Seviye 20: Ölüm Alanı +Level 21: Slayer,PHUSTR_21,,,,Level 21: Zabiják,Level 21: Slagter,Level 21: Töter,,Nivelo 21: Mortigisto,Nivel 21: Descuatizador,,Taso 21: Tappaja,NIVEAU 21: Pourfendeur,21. Pálya: Halálosztó,Livello 21: Assassino,Level 21: スレイヤー,레벨 21: 슬레이어,Level 21: Doder,Nivå 21: Slakteren,Level 21: Pogromca,Fase 21: Matador,Nível 21: Matador,Nivelul 21: Ucigător,Уровень №21: Истребитель,Level 21: Убица,Nivå 21: Jägare,Seviye 21: Avcı +Level 22: Impossible Mission,PHUSTR_22,,,,Level 22: Nemožná mise,Level 22: Umulig mission,Level 22: Unmögliche Mission,,Nivelo 22: Malebla Misio,Nivel 22: Misión Imposible,,Taso 22: Mahdoton tehtävä,NIVEAU 22: Mission Impossible,22. Pálya: Lehetetlen küldetés,Livello 22: Missione Impossibile,Level 22: 不可能な任務,레벨 22: 임파서블 미션,Level 22: Onmogelijke missie,Nivå 22: Umulig oppdrag,Level 22: Niemożliwa Misja,Fase 22: Missão Impossível,Nível 22: Missão Impossível,Nivelul 22: Misiune imposibilă,Уровень №22: Невыполнимое задание,Level 22: Немогућа мисија,Nivå 22: Omöjligt uppdrag,Seviye 22: İmkansız Görev +Level 23: Tombstone,PHUSTR_23,,,,Level 23: Náhrobek,Level 23: Gravsten,Level 23: Grabstein,,Nivelo 23: Tombŝtono,Nivel 23: Lápida,,Taso 23: Hautakivi,NIVEAU 23: Pierre Tombale,23. Pálya: Sírkő,Livello 23: Pietra Tombale,Level 23: 墓石,레벨 23: 묘비,Level 23: Grafsteen,Nivå 23: Gravstein,Level 23: Nagrobek,Fase 23: Lápide,Nível 23: Lápide,Nivelul 23: Piatra de mormânt,Уровень №23: Надгробие,Level 23: Надгробни споменик,Nivå 23: Gravsten,Seviye 23: Mezar Taşı +Level 24: The Final Frontier,PHUSTR_24,,,,Level 24: Poslední hranice,Level 24: Den endelige grænse,Level 24: Die letzte Grenze,,Nivelo 24: La Fina Limo,Nivel 24: La Frontera Final,Nivel 24: La Última Frontera,Taso 24: Viimeinen rajamaa,NIVEAU 24: La Frontière Finale,24. Pálya: A végső határ,Livello 24: La Frontiera Finale,Level 24: 最後のフロンティア,레벨 24: 최후의 개척지,Level 24: De eindgrens,Nivå 24: Den siste grensen,Level 24: Ostateczna Granica,Fase 24: A Fronteira Final,Nível 24: A Fronteira Final,Nivelul 24: Ultima frontieră,Уровень №24: Последний рубеж,Level 24: Коначна граница,Nivå 24: Den sista gränsen,Seviye 24: Son Sınır +Level 25: The Temple of Darkness,PHUSTR_25,,,,Level 25: Chrám temna,Level 25: Mørkets tempel,Level 25: Der Tempel der Dunkelheit,,Nivelo 25: La Idolejo de Mallumo,Nivel 25: El Templo de la Oscuridad,,Taso 25: Pimeyden temppeli,NIVEAU 25: Le Temple des Ténèbres,25. Pálya: A sötétség temploma,Livello 25: Il Tempio dell'Oscurità,Level 25: 暗黒の神殿,레벨 25: 어둠의 신전,Level 25: De tempel van de duisternis,Nivå 25: Mørkets tempel,Level 25: Świątynia Mroku,Fase 25: O Templo da Escuridão,Nível 25: O Templo da Escuridão,Nivelul 25: Templul tenebros,Уровень №25: Храм тьмы,Level 25: Храм таме,Nivå 25: Mörkrets tempel,Seviye 25: Karanlığın Tapınağı +Level 26: Bunker,PHUSTR_26,,,,Level 26: Bunkr,,,,Nivelo 26: Bunkro,Nivel 26: Búnker,,Taso 26: Bunkkeri,NIVEAU 26: Bunker,26. Pálya: Bunker,Livello 26: Bunker,Level 26: バンカー,레벨 26: 방공호,,,Level 26: Bunkier,Fase 26: Casamata,Nível 26: Bunker,Nivelul 26: Buncăr,Уровень №26: Бункер,Level 26: Бункер,Nivå 26: Bunker,Seviye 26: Sığınak +Level 27: Anti-christ,PHUSTR_27,,,,Level 27: Antikrist,,Level 27: Antichrist,,Nivelo 27: Antikristo,Nivel 27: Anti-cristo,,Taso 27: Antikristus,NIVEAU 27: Anti-Christ,27. Pálya: Antikrisztus,Livello 27: Anticristo,Level 27: アンチキリスト,레벨 27: 적그리스도,Level 27: Antichrist,Nivå 27: Antikrist,Level 27: Antychryst,Fase 27: Anticristo,Nível 27: Anticristo,Nivelul 27: Antihrist,Уровень №27: Антихрист,Level 27: Антихрист,Nivå 27: Antikrist,Seviye 27: Mesih Karşıtı +Level 28: The Sewers,PHUSTR_28,,,,Level 28: Kanály,Level 28: Kloakkerne,Level 28: Kanäle,,Nivelo 28: La Kanalo,Nivel 28: Las Alcantarillas,,Taso 28: Viemärit,NIVEAU 28: Les Egouts,28. Pálya: A kanális,Livello 28: Le Fogne,Level 28: 下水道,레벨 28: 하수구,Level 28: De rioleringen,Nivå 28: Kloakken,Level 28: Ścieki,Fase 28: Os Esgotos,Nível 28: Os Esgotos,Nivelul 28: Canalizarea,Уровень №28: Канализация,Level 28: Канализација,Nivå 28: Sjukhusen,Seviye 28: Kanalizasyonlar +Level 29: Odyssey of Noises,PHUSTR_29,,,,Level 29: Odysea křiku,Level 29: Lydenes odyssé,Level 29: Odyssee der Geräusche,,Nivelo 29: Vojaĝo de Sonoj,Nivel 29: Odisea de Ruidos,,Taso 29: Äänten harharetki,NIVEAU 29: Odysée de Bruits,29. Pálya: A moraj ösvénye,Livello 29: Odissea dei Rumori,Level 29: オデッセイのノイズ,레벨 29: 속삭임의 여정,Level 29: Odyssee van geluiden,Nivå 29: Lydenes odyssé,Level 29: Odyseja Wrzawy,Fase 29: Odisséia de Ruidos,Nível 29: Odisséia de Ruidos,Nivelul 29: Odiseea zgomotelor,Уровень №29: Одиссея шумов,Level 29: Одисеја шумова,Nivå 29: Ljudets odyssé,Seviye 29: Seslerin Odyssey'i +Level 30: The Gateway of Hell,PHUSTR_30,,,,Level 30: Brána pekla,Level 30: Helvedes port,Level 30: Tor zur Hölle,,Nivelo 30: La Pordego de Inferno,Nivel 30: La Puerta del Infierno,,Taso 30: Helvetin porttikäytävä,NIVEAU 30: La Porte des Enfers,30. Pálya: Átjáró a pokolba,Livello 30: La Porta dell'Inferno,Level 30: 地獄の関門,레벨 30: 지옥의 차원문,Level 30: De poort van de hel,Nivå 30: Porten til helvete,Level 30: Brama Piekieł,Fase 30: O Portão do Inferno,Nível 30: O Portão do Inferno,Nivelul 30: Poarta spre infern,Уровень №30: Врата ада,Level 30: Пролаз пакла,Nivå 30: Helvetets port,Seviye 30: Cehennem Kapısı +Level 31: Cyberden,PHUSTR_31,,,,Level 31: Kyberdoupě,,Level 31: Cyberbau,,Nivelo 31: Cibernesto,Nivel 31: Ciber-guarida,,Taso 31: Kyberpesä,NIVEAU 31: Cyber-Antre,31. Pálya: Kiberodú,Livello 31: Cybergabbia,Level 31: サイバーの巣,레벨 31: 사이버소굴,,,Level 31: Cybernora,Fase 31: Ciberantro,Nível 31: Ciberantro,Nivelul 31: Cibervizuină,Уровень №31: Киберлогово,Level 31: Сајбер-јазбина,Nivå 31: Cyberden,Seviye 31: Siber'in ini +Level 32: Go 2 It,PHUSTR_32,,,,Level 32: Jdi do toho,,,,Nivelo 32: Iru Al Ĝi!,Nivel 32: Ve a x ello,Nivel 32: Ve x eso,Taso 32: Iske kii,NIVEAU 32: Go 2 It,32. Pálya: Menj oda!,Livello 32: Dacci Dentro,Level 32: 逝ってこい,레벨 32: 함 해 봐,Level 32: Ga ervoor,,Level 32: Do Dzieła,Fase 32: Vai Fundo,Nível 32: Siga em Frente,Nivelul 32: Du-te la ei,Уровень №32: П0лный вп3рёд,Level 32: Иди ка њему,Nivå 32: Gå till det,Seviye 32: Devam Et +,,TNT: Evilution,,,,,,,,,,,,,,,,,,,,,,,,, +Level 1: System Control,THUSTR_1,,,,Level 1: Administrace,Level 1: Systemkontrol,Level 1: Systemkontrolle,,Nivelo 1: Sistema Kontrolo,Nivel 1: Control del Sistema,,Taso 1: Järjestelmäohjaamo,NIVEAU 1: Système de Contrôle,1. Pálya: Rendszervezérlő,Livello 1: Controllo del Sistema,Level 1: 制御システム,레벨 1: 시스템 제어시설,Level 1: Systeemcontrole,Nivå 1: Systemkontroll,Level 1: Kontrola Systemu,Fase 1: Controle do Sistema,Nível 1: Controlo de Sistema,Nivelul 1: Control sisteme,Уровень №1: Центр управления системой,Level 1: Контролна система,Nivå 1: Systemkontroll,Seviye 1: Sistem Kontrolü +Level 2: Human BBQ,THUSTR_2,,,,Level 2: Člověčí grilovačka,Level 2: Menneskelig grill,Level 2: Menschliches Barbecue,,Nivelo 2: Homo-Kradrostado,Nivel 2: Barbacoa Humana,,Taso 2: Ihmisgrilli,NIVEAU 2: Barbecue Humain,2. Pálya: Emberi grill,Livello 2: Barbecue Umano,Level 2: 人肉晩餐会,레벨 2: 인간 바비큐,Level 2: Menselijke BBQ,Nivå 2: Menneskelig BBQ,Level 2: Ludzki Grill,Fase 2: Churrasco Humano,Nível 2: Churrasco Humano,Nivelul 2: Oameni la grătar,Уровень №2: Барбекю из человечины,Level 2: Људски роштиљ,Nivå 2: Människogrill,Seviye 2: İnsan Barbekü +Level 3: Power Control,THUSTR_3,,,,Level 3: Napájecí vedení,Level 3: Kontrol med magten,Level 3: Energiekontrolle,,Nivelo 3: Energia Kontrolo,Nivel 3: Control de Energía,,Taso 3: Voimalan ohjaamo,NIVEAU 3: Contrôle Energétique,3. Pálya: Energiavezérlő,Livello 3: Centrale Energetica,Level 3: 制御室,레벨 3: 전력 통제소,Level 3: Machtscontrole,Nivå 3: Kraftkontroll,Level 3: Kontrola Zasilania,Fase 3: Controle de Energia,Nível 3: Controlo Energético,Nivelul 3: Uzina,Уровень №3: Центр управления питанием,Level 3: Контролна моћ,Nivå 3: Maktkontroll,Seviye 3: Güç Kontrolü +Level 4: Wormhole,THUSTR_4,,,,Level 4: Červí díra,Level 4: Ormehul,Level 4: Wurmloch,,Nivelo 4: Vermtruo,Nivel 4: Agujero de Gusano,,Taso 4: Madonreikä,NIVEAU 4: Trou de Ver,4. Pálya: Féreglyuk,Livello 4: Wormhole,Level 4: 虫喰い穴,레벨 4: 웜홀,Level 4: Wormgat,Nivå 4: Ormehull,Level 4: Tunel,Fase 4: Buraco de Minhoca,Nível 4: Buraco de Minhoca,Nivelul 4: Gaura de vierme,Уровень №4: Червоточина,Level 4: Црвоточина,Nivå 4: Maskhål,Seviye 4: Solucan Deliği +Level 5: Hanger,THUSTR_5,"Not ""Hangar""",,,Level 5: Hangár,,Level 5: Hangar,,Nivelo 5: Pendigejo,Nivel 5: Colgador,,Taso 5: Lentoalushalli,NIVEAU 5: Hengar,5. Pálya: Horog,Livello 5: Hanga,Level 5: 格納庫,레벨 5: 격납고,Level 5: Hangar,Nivå 5: Hanger,Level 5: Hangar,Fase 5: Hangar,Nível 5: Hangar,Nivelul 5: Hangar,Уровень №5: Ангар,Level 5: Вешалица,Nivå 5: Hängare,Seviye 5: Askı +Level 6: Open Season,THUSTR_6,,,,Level 6: Lovecká sezóna,Level 6: Åben sæson,Level 6: Jagdsaison,,Nivelo 6: Ĉasosezono,Nivel 6: Temporada Abierta,,Taso 6: Avoin sesonki,NIVEAU 6: La Chasse Est Ouverte,6. Pálya: Vadászszezon,Livello 6: Stagione Aperta,Level 6: 狩猟解禁,레벨 6: 사냥철,Level 6: Open seizoen,Nivå 6: Åpen sesong,Level 6: Otwarty Sezon,Fase 6: Temporada Aberta,Nível 6: Época Aberta,Nivelul 6: Sezon deschis,Уровень №6: Сезон охоты,Level 6: Отворена сезона,Nivå 6: Öppen säsong,Seviye 6: Açık Sezon +Level 7: Prison,THUSTR_7,,,,Level 7: Vězení,Level 7: Fængsel,Level 7: Gefängnis,,Nivelo 7: Malliberejo,Nivel 7: Prisión,,Taso 7: Vankila,NIVEAU 7: Prison,7. Pálya: Börtön,Livello 7: Prigione,Level 7: 監獄,레벨 7: 감옥,Level 7: Gevangenis,Nivå 7: Fengsel,Level 7: Więzienie,Fase 7: Prisão,Nível 7: Prisão,Nivelul 7: Închisoare,Уровень №7: Тюрьма,Level 7: Затвор,Nivå 7: Fängelse,Seviye 7: Hapishane +Level 8: Metal,THUSTR_8,,,,Level 8: Kov,,Level 8: Metall,,Nivelo 8: Metalo,Nivel 8: Metal,,Taso 8: Metalli,NIVEAU 8: Métal,8. Pálya: Fém,Livello 8: Metallo,Level 8: メタル,레벨 8: 강철,Level 8: Metaal,Nivå 8: Metall,,Fase 8: Metal,Nível 8: Metal,Nivelul 8: Metal,Уровень №8: Металл,Level 8: Метал,Nivå 8: Metall,Seviye 8: Metal +Level 9: Stronghold,THUSTR_9,,,,Level 9: Pevnost,Level 9: Borgen,Level 9: Festung,,Nivelo 9: Fuorto,Nivel 9: Fortaleza,,Taso 9: Linnake,NIVEAU 9: Forteresse,9. Pálya: Erőd,Livello 9: Fortezza,Level 9: 牙城,레벨 9: 요새,Level 9: Vesting,Nivå 9: Festning,Level 9: Warownia,Fase 9: Fortaleza,Nível 9: Fortaleza,Nivelul 9: Bastion,Уровень №9: Твердыня,Level 9: Упориште,Nivå 9: Fästning,Seviye 9: Kale +Level 10: Redemption,THUSTR_10,,,,Level 10: Vykoupení,Level 10: Forløsning,Level 10: Erlösung,,Nivelo 10: Elaĉeto,Nivel 10: Redención,,Taso 10: Lunastus,NIVEAU 10: Rédemption,10. Pálya: Megváltás,Livello 10: Redenzione,Level 10: 償還,레벨 10: 구원,Level 10: Aflossing,Nivå 10: Innløsning,Level 10: Odkupienie,Fase 10: Redenção,Nível 10: Redenção,Nivelul 10: Răscumpărare,Уровень №10: Искупление,Level 10: Искупљење,Nivå 10: Inlösen,Seviye 10: Kefaret +Level 11: Storage Facility,THUSTR_11,,,,Level 11: Skladiště,Level 11: Opbevaringsanlæg,Level 11: Lagerstätte,,Nivelo 11: Stokejo,Nivel 11: Complejo de Almacenes,Nivel 11: Almacenes,Taso 11: Varastolaitos,NIVEAU 11: Complexe de Stockage,11. Pálya: Raktárépület,Livello 11: Impianto di Stoccaggio,Level 11: 貯蔵施設,레벨 11: 저장소,Level 11: Opslagfaciliteit,Nivå 11: Lagringsanlegg,Level 11: Magazyn,Fase 11: Centro de Armazenamento,Nível 11: Centro de Armazenamento,Nivelul 11: Stația de depozitare,Уровень №11: Склад,Level 11: Складиште,Nivå 11: Förvaringsanläggning,Seviye 11: Depolama Tesisi +Level 12: Crater,THUSTR_12,,,,Level 12: Kráter,Level 12: Krater,Level 12: Krater,,Nivelo 12: Kratero,Nivel 12: Cráter,,Taso 12: Kraateri,NIVEAU 12: Cratère,12. Pálya: Kráter,Livello 12: Cratere,Level 12: 火口,레벨 12: 분화구,Level 12: Krater,Nivå 12: Krater,Level 12: Krater,Fase 12: Cratera,Nível 12: Cratera,Nivelul 12: Crater,Уровень №12: Кратер,Level 12: Кратер,Nivå 12: Krater,Seviye 12: Krater +Level 13: Nukage Processing,THUSTR_13,,,,Level 13: Jaderné zpracování,Level 13: Nukageforarbejdning,Level 13: Nuklearverarbeitung,,Nivelo 13: Nukleaĵo-Traktejo,Nivel 13: Procesamiento de Residuos Nucleares,,Taso 13: Ydinjätekäsittely,NIVEAU 13: Traitement Nucléaire,13. Pálya: Atomhulladék-feldolgozó,Livello 13: Trattamento Nucleare,Level 13: 核廃棄物加工所,레벨 13: 폐기물 처리소,Level 13: Nucleaire verwerking,Nivå 13: Nukage-prosessering,Level 13: Przetwórstwo Jądrowe,Fase 13: Processamento Nuclear,Nível 13: Processamento Nuclear,Nivelul 13: Prelucrarea deșeurilor nucleare,Уровень №13: Переработка ядерных отходов,Level 13: Прерада нуклеарног отпада,Nivå 13: Kärnavfall Behandling,Seviye 13: Nukage İşleme +Level 14: Steel Works,THUSTR_14,,,,Level 14: Ocelárna,Level 14: Stålværk,Level 14: Stahlwerk,,Nivelo 14: Ŝtalejo,Nivel 14: Siderúrgica,Nivel 14: Siderurgia,Taso 14: Terästehdas,NIVEAU 14: Aciérie,14. Pálya: Acélművek,Livello 14: Acciaieria,Level 14: 製鉄所,레벨 14: 제강소,Level 14: Staalfabrieken,Nivå 14: Stålverk,Level 14: Huta,Fase 14: Siderúrgica,Nível 14: Siderúrgica,Nivelul 14: Oțelărie,Уровень №14: Сталелитейный завод,Level 14: Челичана,Nivå 14: Stålverk,Seviye 14: Çelik İşleri +Level 15: Dead Zone,THUSTR_15,,,,Level 15: Mrtvá zóna,Level 15: Død zone,Level 15: Tote Zone,,Nivelo 15: Senvivzono,Nivel 15: Zona Muerta,,Taso 15: Kuollut alue,NIVEAU 15: Zone Morte,15. Pálya: A holtak zónája,Livello 15: Zona Morta,Level 15: 危険地帯,레벨 15: 사각지대,Level 15: Dode zone,Nivå 15: Død sone,Level 15: Martwa Strefa,Fase 15: Zona Morta,Nível 15: Zona Morta,Nivelul 15: Zona moartă,Уровень №15: Мёртвая зона,Level 15: Зона смрти,Nivå 15: Dödszon,Seviye 15: Ölü Bölge +Level 16: Deepest Reaches,THUSTR_16,,,,Level 16: Nejhlubší sluje,Level 16: De dybeste afkroge,Level 16: Tiefe,,Nivelo 16: Plejsubejo,Nivel 16: Recodos profundos,,Taso 16: Syvyydet,NIVEAU 16: Profondeurs,16. Pálya: A legmélyebb pont,Livello 16: Profondità,Level 16: 最深部,레벨 16: 깊숙한 강,Level 16: Diepste reiken,Nivå 16: De dypeste områdene,Level 16: Głębiny,Fase 16: Profundezas,Nível 16: Profundezas,Nivelul 16: În adâncuri,Уровень №16: Глубочайшие достижения,Level 16: Најдубља дубина,Nivå 16: De djupaste hålen,Seviye 16: En Derin Erişimler +Level 17: Processing Area,THUSTR_17,,,,Level 17: Kombinát,Level 17: Forarbejdningsområde,Level 17: Verarbeitungsbereich,,Nivelo 17: Traktadareo,Nivel 17: Área de Procesamiento,,Taso 17: Käsittelyalue,NIVEAU 17: Zone de Traitement,17. Pálya: Feldolgozó,Livello 17: Area di Elaborazione,Level 17: 処理地帯,레벨 17: 처리 구역,Level 17: Verwerkingsgebied,Nivå 17: Behandlingsområde,Level 17: Strefa Przerobowa,Fase 17: Área de Processamento,Nível 17: Área de Processamento,Nivelul 17: Aria de procesare,Уровень №17: Зона обработки,Level 17: Подручје обраде,Nivå 17: Bearbetningsområde,Seviye 17: İşleme Alanı +Level 18: Mill,THUSTR_18,,,,Level 18: Mlýn,Level 18: Mølle,Level 18: Mühle,,Nivelo 18: Muelejo,Nivel 18: Molino,,Taso 18: Mylly,NIVEAU 18: Fonderie,18. Pálya: Malom,Livello 18: Fonderia,Level 18: 製粉所,레벨 18: 제분소,Level 18: Molen,Nivå 18: Mølle,Level 18: Młyn,Fase 18: Moinho,Nível 18: Moinho,Nivelul 18: Moara,Уровень №18: Завод,Level 18: Млин,Nivå 18: Kvarn,Seviye 18: Değirmen +Level 19: Shipping/respawning,THUSTR_19,,,,Level 19: Přeprava,Level 19: Forsendelsescenter,Level 19: Versandlager,,Nivelo 19: Ekspedo/Revivado,Nivel 19: Enviando/Reapareciendo,,Taso 19: Huolinta/Ylösnostatus,NIVEAU 19: Envoi/Réapparition,19. Pálya: Szállítás/újraéledés,Livello 19: Consegna/Respawn,Level 19: 出荷と再生成,레벨 19: 운송/리스폰 장소,Level 19: Verzendingscentrum,Nivå 19: Frakt/omlasting,Level 19: Wysyłka/Reprodukcja,Fase 19: Expedição/reaparecimento,Nível 19: Expedição/reaparecimento,Nivelul 19: Livrare/reapariție,Уровень №19: Погрузка и отправка,Level 19: Отпремање/оживљавање,Nivå 19: Skeppning,Seviye 19: Nakliye Merkezi +Level 20: Central Processing,THUSTR_20,,,,Level 20: Centrální zpracování,Level 20: Central forarbejdning,Level 20: Zentralverarbeitung,,Nivelo 20: Centra Eskpedado,Nivel 20: Procesamiento Central,,Taso 20: Käsittelykeskus,NIVEAU 20: Organisme Central,20. Pálya: Központi feldolgozó,Livello 20: Centrale di Elaborazione,Level 20: 中央処理所,레벨 20: 중앙 처리소,Level 20: Centrale verwerking,Nivå 20: Sentral behandling,Level 20: Centralny Proces,Fase 20: Processamento Central,Nível 20: Processamento Central,Nivelul 20: Prelucrare centrală,Уровень №20: Центральный пункт обработки,Level 20: Централна обрада,Nivå 20: Centralt bearbetningsområde,Seviye 20: Merkezi İşlem +Level 21: Administration Center,THUSTR_21,,,,Level 21: Administrativní centrum,Level 21: Administrationscenter,Level 21: Verwaltungszentrum,,Nivelo 21: Administracia Centro,Nivel 21: Centro de Administración,,Taso 21: Keskushallinto,NIVEAU 21: Centre Administratif,21. Pálya: Adminisztrációs központ,Livello 21: Centro Amministrativo,Level 21: 行政センター,레벨 21: 관리 센터,Level 21: Administratief centrum,Nivå 21: Administrasjonssenter,Level 21: Centrum Administracyjne,Fase 21: Centro de Administração,Nível 21: Centro de Administração,Nivelul 21: Centru administrativ,Уровень №21: Административный центр,Level 21: Административни центар,Nivå 21: Administrationscenter,Seviye 21: Yönetim Merkezi +Level 22: Habitat,THUSTR_22,,,,,Level 22: Levested,,,Nivelo 22: Habitato,Nivel 22: Hábitat,,Taso 22: Asuinpaikka,NIVEAU 22: Habitat,22. Pálya: Élőhely,Livello 22: Habitat,Level 22: 生息地,레벨 22: 서식지,,Nivå 22: Habitat,Level 22: Siedlisko,Fase 22: Habitat,Nível 22: Habitat,Nivelul 22: Habitat,Уровень №22: Ареал,Level 22: Станиште,Nivå 22: Livsområde,Seviye 22: Habitat +Level 23: Lunar Mining Project,THUSTR_23,,,,Level 23: Lunární těžební projekt,Level 23: Projekt for månens minedrift,Level 23: Mondbergbauprojekt,,Nivelo 23: Luna Mino-Projekto,Nivel 23: Proyecto de Minería Lunar,,Taso 23: Kuukaivosprojekti,NIVEAU 23: Projet Minier Lunaire,23. Pálya: Holdbánya-projekt,Livello 23: Progetto Minerario Lunare,Level 23: 月面探鉱計画,레벨 23: 월석 채광 계획,Level 23: Maanmijnbouw project,Nivå 23: Månegruveprosjekt,Level 23: Projekt Księżycowe Górnictwo,Fase 23: Projeto de Mineração Lunar,Nível 23: Projeto de Escavação Lunar,Nivelul 23: Proiect minier satelitar,Уровень №23: Лунный проект горной добычи,Level 23: Пројекат лунарног рударства,Nivå 23: Gruvprojekt på månen,Seviye 23: Ay Madenciliği Projesi +Level 24: Quarry,THUSTR_24,,,,Level 24: Kamenolom,Level 24: Stenbrud,Level 24: Steinbruch,,Nivelo 24: Ŝtonejo,Nivel 24: Cantera,,Taso 24: Louhos,NIVEAU 24: Carrière,24. Pálya: Kőbánya,Livello 24: Caccia,Level 24: 採石場,레벨 24: 채석장,Level 24: Steengroeve,Nivå 24: Steinbrudd,Level 24: Kamieniołom,Fase 24: Pedreira,Nível 24: Pedreira,Nivelul 24: Carieră,Уровень №24: Карьер,Level 24: Каменолом,Nivå 24: Stenbrott,Seviye 24: Taş Ocağı +Level 25: Baron's Den,THUSTR_25,,,,Level 25: Baronovo doupě,Level 25: Baronens hule,Level 25: Der Bau des Barons,,Nivelo 25: Nestego de Barono,Nivel 25: Guarida del Barón,,Taso 25: Paronin pesä,NIVEAU 25: l'Antre des Barons,25. Pálya: A báró odúja,Livello 25: Antro del Barone,Level 25: バロンの巣窟,레벨 25: 남작의 소굴,Level 25: Het baron's gebouw,Nivå 25: Baronens hule,Level 25: Legowisko Barona,Fase 25: Covil do Barão,Nível 25: Covil do Barão,Nivelul 25: Cuibul Baronului,Уровень №25: Логово барона,Level 25: Баронова јазбина,Nivå 25: Baronens lya,Seviye 25: Baron'un İni +Level 26: Ballistyx,THUSTR_26,,,,Level 26: Balistika,,,,Nivelo 26: Balistikso,Nivel 26: Balístige,,Taso 26: Ballistyks,NIVEAU 26: Ballistyx,26. Pálya: Ballisztüx,Livello 26: Ballistige,Level 26: バリステュクス,레벨 26: 탄도스틱스,,,Level 26: Balistyka,Fase 26: Ballistige,Nível 26: Ballistige,Nivelul 26: Ballistyx,Уровень №26: Баллистикс,Level 26: Билистичкикс,Nivå 26: Ballistyx,Seviye 26: Balistyx +Level 27: Mount Pain,THUSTR_27,,,,Level 27: Hora bolesti,Level 27: Smertefjellet,Level 27: Berg des Schmerzes,,Nivelo 27: Monto de Doloro,Nivel 27: Monte Dolor,,Taso 27: Tuskavuori,NIVEAU 27: Mont Souffrance,27. Pálya: A Gyötrelem Hegye,Livello 27: Monte del Dolore,Level 27: 苦しみの山,레벨 27: 등신같은 등산,Level 27: Pijn in de bergen,Nivå 27: Smertefjellet,Level 27: Góra Bólu,Fase 27: Monte Dor,Nível 27: Monte Dor,Nivelul 27: Muntele Durerii,Уровень №27: Гора Боль,Level 27: Планина боли,Nivå 27: Smärta på berget,Seviye 27: Acı Dağı +Level 28: Heck,THUSTR_28,,,,Level 28: Sakra,,Level 28: Zum Teufel,,Nivelo 28: Diable,Nivel 28: Diablos,,Taso 28: Hemmetti,NIVEAU 28: Que Diable?,28. Pálya: Rosseb,Livello 28: Al Diavolo,Level 28: 苛立ち,레벨 28: 젠장함,,Nivå 28: Helvete,Level 28: Do Diabła,Fase 28: Capeta,Nível 28: Inferno,Nivelul 28: Naiba,Уровень №28: Чертовщина,Level 28: Пакао,Nivå 28: Heck,Seviye 28: Cehennem +Level 29: River Styx,THUSTR_29,,,,Level 29: Řeka Styx,Level 29: Floden Styx,Level 29: Fluss Styx,,Nivelo 29: Rivero de Stikso,Nivel 29: Río Estige,,Taso 29: Styksjoki,NIVEAU 29: Fleuve Styx,29. Pálya: A Sztüx folyó,Livello 29: Fiume Stige,Level 29: 三途の川,레벨 29: 스틱스 강,Level 29: Rivier Styx,Nivå 29: Elven Styx,Level 29: Styks,Fase 29: Rio Estige,Nível 29: Rio Estige,Nivelul 29: Râul Styx,Уровень №29: Река Стикс,Level 29: Река Стикс,Nivå 29: Floden Styx,Seviye 29: Styx Nehri +Level 30: Last Call,THUSTR_30,,,,Level 30: Poslední mise,Level 30: Sidste opkald,Level 30: Letzter Aufruf,,Nivelo 30: Fina Voko,Nivel 30: Última Llamada,,Taso 30: Viimeinen koollehuuto,NIVEAU 30: Dernier Appel,30. Pálya: Utolsó esély,Livello 30: Ultima Chiamata,Level 30: 最終指令,레벨 30: 최후의 호출,Level 30: Laatste oproep,Nivå 30: Siste innkalling,Level 30: Ostatni Zew,Fase 30: Última Chamada,Nível 30: Última Chamada,Nivelul 30: Ultimul apel,Уровень №30: Последний вызов,Level 30: Последњи позив,Nivå 30: Sista kallelsen,Seviye 30: Son Çağrı +Level 31: Pharaoh,THUSTR_31,,,,Level 31: Faraón,Level 31: Farao,Level 31: Pharao,,Nivelo 31: Faraono,Nivel 31: Faraón,,Taso 31: Faarao,NIVEAU 31: Pharaon,31. Pálya: Fáraó,Livello 31: Faraone,Level 31: ファラオ,레벨 31: 파라오,Level 31: Farao,Nivå 31: Farao,Level 31: Faraon,Fase 31: Faraó,Nível 31: Faraó,Nivelul 31: Faraon,Уровень №31: Фараон,Level 31: Фараон,Nivå 31: Farao,Seviye 31: Firavun +Level 32: Caribbean,THUSTR_32,,,,Level 32: Karibik,Level 32: Caribien,Level 32: Karibik,,Nivelo 32: Karibio,Nivel 32: Caribeño,,Taso 32: Karibia,NIVEAU 32: Caraïbes,32. Pálya: Karib-térség,Livello 32: Caraibi,Level 32: カリビアン,레벨 32: 카리브해,Level 32: Caribisch,Nivå 32: Karibia,Level 32: Karaiby,Fase 32: Caribe,Nível 32: Caraíbas,Nivelul 32: Caraibe,Уровень №32: Карибы,Level 32: Кариби,Nivå 32: Karibien,Seviye 32: Karayipler +,,Heretic,,,,,,,,,,,,,,,,,,,,,,,,, +The Docks,HHUSTR_E1M1,,,,Přístav,Havnene,Die Docks,,La Havenoj,Los Muelles,,Satamat,Les Docks,A Kikötő,Il Molo,埠頭,항구,De dokken,Havnen,Doki,As Docas,,Docul,Доки,Лука,Hamnarna,Rıhtım +The Dungeons,HHUSTR_E1M2,,,,Žaláře,Fangehullerne,Die Kerker,,La Malliberejoj,Los Calabozos,,Tyrmät,Le Donjon,A Kazamaták,I Sotterranei,地下牢,지하감옥,De kerkers,Fangehullene,Lochy,As Masmorras,,Temnița,Темницы,Тамнице,Fästningarna,Zindanlar +The Gatehouse,HHUSTR_E1M3,,,,Vrátnice,Portens hus,Das Pförtnerhaus,,La Pordegejo,El Cuerpo de Guardia,,Porttitalo,Le Corps de Garde,A Kapuház,L'ingresso,門塔,문루,Het poortgebouw,Porthuset,Stróżówka,O Portão de Entrada,,Casa portarului,Привратницкая,Стражарница,Porthuset,Kapı Evi +The Guard Tower,HHUSTR_E1M4,,,,Strážní věž,Vagttårnet,Der Wachturm,,La Gardturo,La Torre de Guardia,,Vartiotorni,La Tour de Garde,Az Őrtorony,La Torre di Guardia,監視塔,보초 누대,De wachttoren,Vakttårnet,Wieża Strażnicza,A Torre de Guarda,,Turnul de veghe,Сторожевая башня,Извидница,Vakttornet,Muhafız Kulesi +The Citadel,HHUSTR_E1M5,,,,Citadela,Citadellet,Die Festung,,La Citadelo,La Ciudadela,,Linnake,La Citadelle,A Citadella,La Cittadella,要塞,거점,De citadel,Citadellet,Cytadela,A Cidadela,,Cetatea,Цитадель,Цитадела,Citadellet,Hisar +The Cathedral,HHUSTR_E1M6,,,,Katedrála,Katedralen,Die Kathedrale,,La Katedralo,La Catedral,,Katedraali,La Cathédrale,A Katedrális,La Cattedrale,大聖堂,대성당,De kathedraal,Katedralen,Katedra,A Catedral,,Catedrala,Кафедральный собор,Катедрала,Katedralen,Katedral +The Crypts,HHUSTR_E1M7,,,,Krypty,Krypterne,Die Krypten,,La Kriptoj,Las Criptas,,Kryptat,La Crypte,A Kripták,Le Cripte,地下聖堂,지하 묘실,De grafkelders,Kryptene,Krypty,As Criptas,,Criptele,Склепы,Крипта,Krypten,Mahzenler +Hell's Maw,HHUSTR_E1M8,,,,Chřtán pekla,Helvedes gab,Der Höllenschlund,,Faŭko de Infero,Fauces del Infierno,,Helvetin kita,La Geule de l'Enfer,A Pokol Szája,La Bocca dell'Inferno,地獄の肚,지옥의 목구멍,De helmouth,Helvetes gap,Paszcza Piekieł,A Boca do Inferno,,Gura iadului,Адская утроба,Паклено ждрело,Helvetets gap,Cehennem Ağzı +The Graveyard,HHUSTR_E1M9,,,,Hřbitov,Kirkegården,Der Friedhof,,La Tombejo,El Cementerio,,Hautausmaa,Le Cimetière,A Temető,Il Cimitero,墓場,공동묘지,De begraafplaats,Kirkegården,Cmentarz,O Cemitério,,Cimitirul,Кладбище,Гробље,Kyrkogården,Mezarlık +The Crater,HHUSTR_E2M1,,,,Kráter,Krateret,Der Krater,,La Kratero,El Cráter,,Kraateri,Le Cratère,A Kráter,Il Cratere,噴火口,깊은 혈,De krater,Krateret,Krater,A Cratera,,Craterul,Кратер,Кратер,Kratern,Krater +The Lava Pits,HHUSTR_E2M2,,,,Lávové jámy,Lavagruberne,Die Lavagruben,,La Lafo-Fosaĵo,Las Canteras de Lava,,Laavamontut,Les Puits de Lave,A Lávaárok,I Pozzi della Lava,溶岩の竪穴,용암 구덩이,De lavaputten,Lavagropene,Szyb Lawy,Os Fossos de Lava,,Gropile cu lavă,Лавовые очаги,Понор лаве,Lavagruvorna,Lav Çukurları +The River of Fire,HHUSTR_E2M3,,,,Ohnivá řeka,Ildfloden,Der Feuerfluss,,La Rivero de Fajro,El Río de Fuego,,Tulijoki,La Rivière de Feu,A Tűzfolyó,Il Fiume di Fuoco,火の河,화염의 강,De rivier van vuur,Elven av ild,Rzeka Ognia,O Rio de Fogo,,Râul de foc,Река огня,Река од ватре,Eldfloden,Ateş Nehri +The Ice Grotto,HHUSTR_E2M4,,,,Ledová grotta,Isgrotten,Die Eisgrotte,,La Glacigroto,La Gruta de Hielo,,Jääluola,La Grotte de Glace,A Jégbarlang,La Grotta del Ghiaccio,氷の洞窟,얼음 동굴,De ijsgrot,Isgrotten,Lodowa Grota,A Gruta de Gelo,,Grota de gheață,Ледяной грот,Ледена пећина,Isgrottan,Buz Mağarası +The Catacombs,HHUSTR_E2M5,,,,Katakomby,Katakomberne,Die Katakomben,,La Katakomboj,Las Catacumbas,,Katakombit,Les Catacombes,A Katakombák,Le Catacombe,地下墓所,태고의 무덤,De catacomben,Katakombene,Katakumby,As Catacumbas,Os Túmulos,Catacombele,Катакомбы,Катакомбе,Katakomberna,Yeraltı Mezarları +The Labyrinth,HHUSTR_E2M6,,,,Labyrint,Labyrinten,Das Labyrinth,,La Labirinto,El Laberinto,,Labyrintti,Le Labyrinthe,A Labirintus,Il Labirinto,迷宮,미궁,Het labyrint,Labyrinten,Labirynt,O Labirinto,,Labirintul,Лабиринт,Лавиринт,Labyrinten,Labirent +The Great Hall,HHUSTR_E2M7,,,,Velký sál,Den store sal,Die große Halle,,La Granda Halo,El Gran Salón,,Suuri halli,Le Grand Hall,A Nagy Folyosó,La Grande Sala,大公会堂,대회관,De grote zaal,Den store salen,Wielki Hol,O Grande Salão,,Sala cea mare,Большой зал,Велика дворана,Den stora hallen,Büyük Salon +The Portals of Chaos,HHUSTR_E2M8,,,,Portály chaosu,Kaosets portaler,Das Portal des Chaos,,La Portaloj de Ĥaoso,Los Portales del Caos,,Kaaoksen portaalit,Le Portail du Chaos,A Káosz Portáljai,I Portali del Caos,混沌への門,혼돈의 차원문,De portalen van chaos,Kaosets portaler,Portale Chaosu,Os Portais do Caos,,Portalurile haosului,Порталы хаоса,Портали хаоса,Kaosets portaler,Kaos Kapıları +The Glacier,HHUSTR_E2M9,,,,Ledovec,Gletsjeren,Der Gletscher,,La Glaciejo,El Glaciar,,Jäätikkö,Le Glacier,A Gleccser,Il Ghiacciaio,氷河,빙하 구역,De gletsjer,Isbreen,Lodowiec,A Geleira,O Glaciar,Ghețarul,Ледник,Глечер,Glaciären,Buzul +The Storehouse,HHUSTR_E3M1,,,,Skladiště,Magasinet,Die Lagerhalle,,La Stokejo,El Almacén,,Varasto,L'Entrepôt,A Raktár,Il Magazzino,倉庫,저장고,Het pakhuis,Forrådshuset,Magazyn,O Armazém,,Depozitul,Кладовая,Складиште,Magasinet,Depo +The Cesspool,HHUSTR_E3M2,,,,Žumpa,Kedelbassinet,Die Latrine,,La Kloako,El Pozo,,Likakaivo,Le Bourbier,A Pöcegödör,Il Pozzo Nero,汚水層,불결한 장소,De zinkput,Søledammen,Szambo,A Fossa,,Haznaua,Сточный колодец,Септичка јама,Rännstenen,Lağım Çukuru +The Confluence,HHUSTR_E3M3,,,,Soutok,Sammenløbet,Die Vereinigung,,La Kunfluiĝo,La Confluencia,,Yhtymäkohta,La Confluence,A Kereszteződés,La Confluenza,合流点,합류점,De samenvloeiing,Sammenløpet,Spływ,A Confluência,,Confluența,Слияние,Ушће,Sammanflödet,Confluence +The Azure Fortress,HHUSTR_E3M4,,,,Azurová pevnost,Den azurblå fæstning,Die himmelblaue Festung,,La Lazurfortikaĵo,La Fortaleza de Azur,,Sininen linnoitus,La Fortresse d'Azur,Az Azúr Erőd,La Fortezza Azzurra,紺碧の要塞,청천의 요새,De azuurblauwe vesting,Den azurblå festningen,Lazurowa Forteca,A Fortaleza Azul,,Fortăreața de azur,Лазурная крепость,Азурна дврђава,Den azurblå fästningen,Azure Kalesi +The Ophidian Lair,HHUSTR_E3M5,,,,Hadí doupě,Ophidian Hulen,Das Schlangennest,,La Nestego de Ofidia,La Guarida Ofídica,,Käärmeiden pesä,Le Repaire des Ophidiens,Az Opfidiánok Fészke,L'antro degli Ophidian,オフィディアンの塒,오피디안의 소굴,Het slangennest,Ophidian-hulen,Gniazdo Węży,A Cova dos Ofídios,,Cuibul ofidienilor,Логово офидианов,Змијска јазбина,Den Ophidiska hålan,Ophidian İni +The Halls of Fear,HHUSTR_E3M6,,,,Chodby strachu,Frygtens haller,Die Hallen der Angst,,La Koridoroj de Timo,Los Salones del Miedo,,Pelon salit,Les Couloirs de la Peur,A Félelem Folyosói,Le Sale della Paura,恐怖の館,공포의 회관,De zalen van angst,Fryktens haller,Korytarze Strachu,Os Salões do Medo,,Sălile groazei,Залы страха,Дворана страха,Skräckens hallar,Korku Salonları +The Chasm,HHUSTR_E3M7,,,,Propast,Kløften,Der Abgrund,,La Fendego,El Abismo,,Rotko,Le Gouffre,A Szakadék,L'abisso,裂け目,깊은 골,De kloof,Kløften,Przepaść,O Abismo,,Prăpastia,Пропасть,Понор лаве,Klyftan,Uçurum +D'Sparil's Keep,HHUSTR_E3M8,,,,D'Sparilova pevnost,D'Sparils borg,D'Sparils Außenposten,,Ĉefturo de Desparilo,Guarida de D'Sparil,,D'Sparilin linna,Le Donjon de D'Sparil,D'Sparil Terme,La Dimora di D'Sparil,デ’スパリルの間,드'스파릴의 초소,D'Sparil's voorpost,D'Sparils borg,Baszta D'Sparila,Fortaleza de D'Sparil,,Palatul lui D'sparil,Крепость Д'Спарила,Д'Спарилова кула,D'Sparils borg,D'Sparil'in Kalesi +The Aquifer,HHUSTR_E3M9,,,,Zvodeň,Akvifer,Der Wasserspeicher,,La Akvigilo,El Acuífero,,Akviferi,L'Aquifère,A Víztorony,L'acquedotto,帯水層,대수층,Het water reservoir,Akviferen,Wodociąg,O Aquífero,,Galerii acvifere,Водоносный слой,Водоносник,Akvifer,Akifer +Catafalque,HHUSTR_E4M1,,,,Katafalk,Katafalken,Katafalk,,Katafalko,Catafalco,,Katafalkki,Le Catafalque,Ravatal,Catafalco,棺台,관대,Catafalk,Katafalken,Katafalk,Catafalco,,Catafalc,Катафалк,Одар,Katafalken,Katafalk +Blockhouse,HHUSTR_E4M2,,,,Tvrzka,Blokhuset,Blockhaus,,Blokhaŭso,Fortín,,Linnoitus,Le Fortin,Gerendaház,Blocco di Case,丸太小屋,특화점,Blokhuis,Blokkhuset,Blokhauz,O Forte,,Fort,Блокгауз,Бункер,Blockhuset,Blok ev +Ambulatory,HHUSTR_E4M3,,,,Ochoz,Ambulatory,Wandelgang,,Ĥorĉirkaŭirejo,Ambulatorio,,Kuorikäytävä,Le Déambulatoire,Kerengő,Ambulatorio,遊歩道,유보장,Kloostergang,Gangen,Krużganek,Ambulatório,,Clinică,Амбулатория,Амбуланта,Ambulerande,Ambulatuvar +Sepulcher,HHUSTR_E4M4,,,,Hrobka,Graven,Grabstätte,,Tombo,Sepulcro,,Hautakammio,Le Sépulcre,Síremlék,Sepolcro,埋葬所,매장소,Grafsteen,Graven,Grób,Sepulcro,,Sepulcru,Гробница,Гробница,Gravskålen,Mezar +Great Stair,HHUSTR_E4M5,,,,Velké schody,Den store trappe,Große Treppe,,Granda Ŝtuparo,Gran Escalera,,Suuret portaat,Le Grand Escalier,Nagy Lépcső,Grande Scala,大階段,특급 계단,Grote trap,Den store trappen,Wielka Gwiazda,Grande Escada,,Scara cea mare,Великая лестница,Велики степеник,Stora trappan,Büyük Merdiven +Halls of the Apostate,HHUSTR_E4M6,,,,Chodby odpadlictví,Apostaternes haller,Halle des Abtrünnigen,,Haloj de la Apostato,Salas de los Apóstatas,,Luopioiden salit,Les Halls de l'Apôtre,A Hitehagyott Csarnoka,Sale dell'Apostata,背教者の館,배교자의 회관,Zalen van de afvallige,De frafalnes haller,Korytarze Odszczepieńca,Os Salões dos Apóstatas,,Sălile apostatului,Залы отступников,Дворана апостола,Apostaternas salar,Mürted Salonları +Ramparts of Perdition,HHUSTR_E4M7,,,,Náspy zatracení,Fortabelsens ramper,Wälle der Verdammnis,,Muregoj de Pereo,Murallas de la Perdición,,Kadotuksen vallit,Les Remparts de la Perdition,A Kárhozat Támasza,Torrioni della Perdizione,破滅の塁壁,파멸의 성벽,Wallen van de verdoemenis,Fortapelsens voller,Wał Potępienia,Muralhas da Perdição,,Meterezele pierzaniei,Твердыни погибели,Бедем пропасти,Fördärvets ramper,Azap Surları +Shattered Bridge,HHUSTR_E4M8,,,,Rozbitý most,Den ødelagte bro,Zerstörte Brücke,,Frakasita Ponto,Puente Destrozado,,Särkynyt silta,Le Pont effondré,Az Összeomlott Híd,Ponte Distrutto,崩落の橋,붕괴된 다리,Verbrijzelde brug,Den knuste broen,Zniszczony Most,Ponte Despedaçada,,Podul dărâmat,Разрушенный мост,Поломљен мост,Förstörd bro,Parçalanmış Köprü +Mausoleum,HHUSTR_E4M9,,,,Mauzoleum,,,,Maŭzoleo,Mausoleo,,Mausoleumi,Le Mausolée,Mauzóleum,Mausoleo,霊廟,대영묘,,Mausoleet,Mauzoleum,Mausoléu,,Mausoleu,Мавзолей,Маузолеј,,Anıt Mezar +Ochre Cliffs,HHUSTR_E5M1,,,,Okrové útesy,Okkerklipper,Ockerfarbene Klippen,,Klifoj de Okro,Acantilados Ocres,,Okrajyrkänteet,Les Falaises Ochre,Okker Szakadékok,Colline Ocra,黄土絶壁,황토 산맥,Okerkliffen,Oker-klippene,Ochrowe Klify,Penhascos Ocres,,Stâncile de ocru,Охровые утёсы,Окер брда,Ockerfärgade klippor,Ochre Kayalıkları +Rapids,HHUSTR_E5M2,,,,Peřeje,Rapider,Stromschnellen,,Rapidfluoj,Rápidos,,Koski,Les Rapides,Zuhatagok,Rapide,奔流,여울,Stroomversnellingen,Strykene,Katarakty,Corredeiras,,Ape repezi,Стремнина,Брзак,Forsar,Akıntıları +Quay,HHUSTR_E5M3,,,,Nábřeží,Kaj,Kai,,Kajo,Muelle,,Satamalaituri,Le Quai,Rakpart,Banchina,岸壁,부두,Kade,Kai,Wir,Cais,,Chei,Причал,Пристаниште,Kajen,Rıhtım +Courtyard,HHUSTR_E5M4,,,,Nádvoří,Slotsgården,Schlosshof,,Korto,Patio,,Linnanpiha,La Cour,Pitvar,Cortile,中庭,안마당,Binnenplaats,Gårdsplass,Dziedziniec,Pátio,,Curte,Внутренний двор,Двориште,Gården,Avlu +Hydratyr,HHUSTR_E5M5,,,,Hydratýr,,,,Akvotjr,Hydratyr,,,L'Hydratyr,Hidratáló,,ヒュドラテュール,식수공급처,,,Hydratyr,Reservatório,,Hidratir,Гидротир,Канализација,Hydratyr,Hydratyr +Colonnade,HHUSTR_E5M6,,,,Kolonáda,Kolonnader,Kolonnaden,,Kolonaro,Columnata,,Pylväikkö,La Colonnade,Kolonnád,Colonnato,柱廊,열주의 길,Zuilengalerij,Kolonnade,Kolumnada,Colunata,,Colonadă,Колоннада,Колонада,Colonnade,Kolonat +Foetid Manse,HHUSTR_E5M7,,,,Smrdutá vila,Stinkende præstegård,Stinkendes Pfarrhaus,,Haladza Domego,Mansión Fétida,,Löyhkäävä kartano,Le Presbytère Fétide,Bűzös Parókia,Fetido Castello,悪臭の牧師館,역겨운 목사관,Stinkende pastorie,Stinkende prestegård,Cuchnąca Plebania,Mansão Fétida,,Conac Fetid,Зловонный особняк,Фетидна кућа,Foetid Manse,Foetid Manse +Field of Judgement,HHUSTR_E5M8,,,,Soudná pole,Dommervældet,Richtstätte,,Kampo de Juĝo,Campo de Juicio,,Tuomion kenttä,Les Champs du Jugement,Az Itélet Mezeje,Campo del Giudizio,審判之地,심판의 평야,Plaats van oordeelsvorming,Dømmekraftsområde,Pole Sądu,Campo de Julgamento,,Câmpul de Judecată,Поле высшего суда,Чистилиште,Domarplatsen,Yargı Alanı +Skein of D'sparil,HHUSTR_E5M9,,,,Hejno D'Sparilovo,D'sparils skein,DSparils Bau,,Fadenaro de D'Sparil,Madeja de D'Sparil,,D'Sparilin vyyhti,L'échevaux de D'Sparil,D'Sparil Káosza,Groviglio di D'Sparil,デ'スパリルの枷,드'스파릴의 타래,D'Sparil's gebouw,Garn av D'sparil,Motek D'Sparila,Meada de D'Sparil,,Jurubița lui D'Sparil,Путаница Д'Спарила,Реке Д'Спарила,D'sparils skein,D'sparil Çileği +,,Strife,,,,,,,,,,,,,,,,,,,,,,,,, +AREA 1: Sanctuary,TXT_STRIFE_MAP01,,,,ZÓNA 1: Svatyně,AREA 1: Fristedet,ZONE 1: Heiligtum,,AREO 1: Sanktejo,ÁREA 1: Santuario,,ALUE 1: Pyhäkkö,ZONE 1: Sanctuaire,1. Terület: Szentély,AREA 1: Santuario,エリア 1: 聖域,구역 1: 성소,Zone 1: Heiligdom,OMRÅDE 1: Helligdom,Strefa 1: Sanktuarium,Área 1: Santuário,,ZONA 1: Sanctuar,МЕСТНОСТЬ 1: Святилище,,OMRÅDE 1: Fristad,ALAN 1: Sığınak AREA 2: Town,TXT_STRIFE_MAP02,,,,ZÓNA 2: Město,AREA 2: By,ZONE 2: Stadt,,AREO 2: Urbeto,ÁREA 2: Pueblo,,ALUE 2: Kylä,ZONE 2: Ville,2. Terület: Város,AREA 2: Città,"エリア 2: 町 -",구역 2: 마을,Zone 2: Stad,OMRÅDE 2: Byen,Strefa 2: Miasto,Área 2: Vila,,ZONA 2: Oraș,МЕСТНОСТЬ 2: Город,,ALAN 2: Şehir -AREA 3: Front Base,TXT_STRIFE_MAP03,,,,ZÓNA 3: Základna Fronty,AREA 3: Front Basis,ZONE 3: Basis der Front,,AREO 3: Front-Bazo,ÁREA 3: Base del Frente,,ALUE 3: Rintaman tukikohta,ZONE 3: Base du Front,3. Terület: Elülső bázis,AREA 3: Base del Fronte,エリア 3: フロント基地,구역 3: 프론트 기지,Zone 3: Front basis,OMRÅDE 3: Frontbase,Strefa 3: Baza Frontu,Área 3: Base da Frente,,ZONA 3: Baza Frontului,МЕСТНОСТЬ 3: База сопротивления,,ALAN 3: Ön Taban -AREA 4: Power Station,TXT_STRIFE_MAP04,,,,ZÓNA 4: Elektrárna,AREA 4: Kraftværk,ZONE 4: Kraftwerk,,AREO 4: Elektrocentralo,ÁREA 4: Central Eléctrica,,ALUE 4: Voimalaitos,ZONE 4: Centrale,4. Terület: Erőmű,AREA 4: Centrale Elettrica,エリア 4: 発電所,구역 4: 발전소,Zone 4: Energiecentrale,OMRÅDE 4: Kraftstasjon,Strefa 4: Elektrownia,Área 4: Usina de Energia,Área 4: Central Energética,ZONA 4: Centrala,МЕСТНОСТЬ 4: Электростанция,,ALAN 4: Elektrik Santrali -AREA 5: Prison,TXT_STRIFE_MAP05,,,,ZÓNA 5: Vězení,AREA 5: Fængsel,ZONE 5: Gefängnis,,AREO 5: Malliberejo,ÁREA 5: Prisión,,ALUE 5: Vankila,ZONE 5: Prison,5. Terület: Börtön,AREA 5: Carcere,エリア 5: 刑務所,구역 5: 감옥,Zone 5: Gevangenis,OMRÅDE 5: Fengsel,Strefa 5: Więzienie,Área 5: Prisão,,ZONA 5: Închisoare,МЕСТНОСТЬ 5: Тюрьма,,ALAN 5: Cezaevi -AREA 6: Sewers,TXT_STRIFE_MAP06,,,,ZÓNA 6: Stoky,AREA 6: Kloakkerne,ZONE 6: Kanalisation,,AREO 6: Kloako,ÁREA 6: Alcantarillas,,ALUE 6: Viemärit,ZONE 6: Egouts,6. Terület: Kanális,AREA 6: Fogne,エリア 6: 下水道,구역 6: 하수도,Zone 6: Riolering,OMRÅDE 6: Kloakk,Strefa 6: Kanały,Área 6: Esgoto,,ZONA 6: Canal,МЕСТНОСТЬ 6: Канализация,,ALAN 6: Kanalizasyonlar -AREA 7: Castle,TXT_STRIFE_MAP07,,,,ZÓNA 7: Hrad,AREA 7: Slot,ZONE 7: Burg,,AREO 7: Kastelo,ÁREA 7: Castillo,,ALUE 7: Linna,ZONE 7: Château,7. Terület: Vár,AREA 7: Castello,エリア 7: 城,구역 7: 성,Zone 7: Kasteel,OMRÅDE 7: Slottet,Strefa 7: Zamek,Área 7: Castelo,,ZONA 7: Castel,МЕСТНОСТЬ 7: Замок,,ALAN 7: Kale -AREA 8: Audience Chamber,TXT_STRIFE_MAP08,,,,ZÓNA 8: Audienční sál,AREA 8: Audience Chamber,ZONE 8: Audienzsaal,,AREO 8: Aŭdicencejo,ÁREA 8: Cámara de Audiencias,,ALUE 8: Yleisösali,ZONE 8: Chambre d'Audience,8. Terület: Nézőtér,AREA 8: Sala delle Udienze,エリア 8: 観客席,구역 8: 알현실,Zone 8: Auditorium,OMRÅDE 8: Audienssalen,Strefa 8: Izba Audiencji,Área 8: Câmara de Audiências,,ZONA 8: Camera de audiențe,МЕСТНОСТЬ 8: Приёмная,,ALAN 8: İzleyici Odası -AREA 9: Castle: Programmer's Keep,TXT_STRIFE_MAP09,,,,ZÓNA 9: Hrad: Programátorovo doupě,AREA 9: Slot: Programmørens værelse,ZONE 9: Burg: Unterkunft des Programmierers,,AREO 9: Kastelo: Fortikaĵo de Programisto,ÁREA 9: Castillo: Guarida del Programador,,ALUE 9: Linna: Ohjelmoitsijan linnake,ZONE 9: Château: Donjon du Programmeur,9. Terület: Vár: Programozó parcellája,AREA 9: Castello: Dimora del Programmatore,エリア 9: 城内:プログラマーの間,구역 9: 성: 프로그래머의 성채,Zone 9: Kasteel: Onderdak van de programmeur,OMRÅDE 9: Slottet: Programmørens tårn,Strefa 9: Zamek: Baszta Programisty,Área 9: Castelo: Torre do Programador,,ZONA 9: Castel: Cetatea programatorului,МЕСТНОСТЬ 9: Цитадель Программиста,,ALAN 9: Kale: Programcının Kalesi -AREA 10: New Front Base,TXT_STRIFE_MAP10,,,,ZÓNA 10: Nová základna Fronty,AREA 10: Ny frontbase,ZONE 10: Neue Basis der Front,,AREO 10: Nova Frontbazo,ÁREA 10: Nueva Base del Frente,,ALUE 10: Uusi Rintaman tukikohta,ZONE 10: Nouvelle Base du Front,10. Terület: Új első bázis,AREA 10: Nuova Base del Fronte,エリア 10: 新フロント基地,구역 10: 새 프론트 기지,Zone 10: Nieuwe Front basis,OMRÅDE 10: Den nye frontbasen,Strefa 10: Nowa Baza Frontu,Área 10: Nova Base da Frente,,ZONA 10: Noua bază a Frontului,МЕСТНОСТЬ 10: Новая база сопротивления,,ALAN 10: Yeni Ön Taban -AREA 11: Borderlands,TXT_STRIFE_MAP11,,,,ZÓNA 11: Pohraničí,AREA 11: Grænseland,ZONE 11: Grenzgebiete,,AREO 11: Limlando,ÁREA 11: Tierras Fronterizas,,ALUE 11: Rajamaat,ZONE 11: Terres Sauvages,11. Terület: Peremvidék,AREA 11: Lande di Confine,エリア 11: 国境地帯,구역 11: 접경지,Zone 11: Grensgebieden,OMRÅDE 11: Grenseland,Strefa 11: Pogranicze,Área 11: Fronteira,,ZONA 11: Frontiere,МЕСТНОСТЬ 11: Пограничье,,ALAN 11: Sınır Bölgeleri -AREA 12: The Temple of the Oracle,TXT_STRIFE_MAP12,,,,ZÓNA 12: Věštcův chrám,AREA 12: Oraklets tempel,ZONE 12: Der Tempel des Orakels,,AREO 12: La Templo de La Orakolo,ÁREA 12: El Templo del Oráculo,,ALUE 12: Oraakkelin temppeli,ZONE 12: Temple de l'Oracle,12. Terület: Az Orákulum Temploma,AREA 12: Il Tempio dell'Oracolo,エリア 12: オラクルの神殿,구역 12: 오라클의 신전,Zone 12: De tempel van het Orakel,OMRÅDE 12: Orakelets tempel,Strefa 12: Świątynia Wyroczni,Área 12: O Templo do Oráculo,,ZONA 12: Templul Oracolului,МЕСТНОСТЬ 12: Храм Оракула,,ALAN 12: Kahin Tapınağı -AREA 13: Catacombs,TXT_STRIFE_MAP13,,,,ZÓNA 13: Katakomby,AREA 13: Katakomberne,ZONE 13: Katakomben,,AREO 13: Katakombo,ÁREA 13: Catacumbas,,ALUE 13: Katakombit,ZONE 13: Catacombes,13. Terület: Katakombák,AREA 13: Catacombe,エリア 13: 地下墓所,구역 13: 고대 묘지,Zone 13: Catacomben,OMRÅDE 13: Katakombene,Strefa 13: Katakumby,Área 13: Catacumbas,Área 13: Túmulos,ZONA 13: Catacombe,МЕСТНОСТЬ 13: Катакомбы,,ALAN 13: Yeraltı Mezarları -AREA 14: Mines,TXT_STRIFE_MAP14,,,,ZÓNA 14: Doly,AREA 14: Miner,ZONE 14: Die Minen,,AREO 14: Minejo,ÁREA 14: Minas,,ALUE 14: Kaivokset,ZONE 14: Mines,14. Terület: Bánya,AREA 14: Miniere,エリア 14: 鉱山,구역 14: 광산,Zone 14: De mijnen,OMRÅDE 14: Minene,Strefa 14: Kopalnia,Área 14: Minas,,ZONA 14: Mine,МЕСТНОСТЬ 14: Шахты,,ALAN 14: Madenler -AREA 15: Fortress: Administration,TXT_STRIFE_MAP15,,,,ZÓNA 15: Pevnost: Administrace,AREA 15: Fæstning: Administration,ZONE 15: Festung: Administration,,AREO 15: Fortreso: Administrejo,ÁREA 15: Fortaleza: Administración,,ALUE 15: Linnoitus: hallinto,ZONE 15: Forteresse: Administration,15. Terület: Erőd: Elbírálás,AREA 15: Fortezza: Amministrazione,エリア 15: 要塞:管理室,구역 15: 요새: 중앙 관리소,Zone 15: Vesting: Administratieve organisatie,OMRÅDE 15: Festningen: Administrasjon,Strefa 15: Forteca: Administracja,Área 15: Fortaleza: Administração,,ZONA 15: Fortăreața: Administrația,МЕСТНОСТЬ 15: Крепость (администрация),,ALAN 15: Kale: Yönetim -AREA 16: Fortress: Bishop's Tower,TXT_STRIFE_MAP16,,,,ZÓNA 16: Pevnost: Biskupova věž,AREA 16: Fæstning: Biskoppens tårn,ZONE 16: Festung: Bischofsturm,,AREO 16: Fortreso: Turo de Episkopo,ÁREA 16: Fortaleza: Torre del Obispo,,ALUE 16: Linnoitus: Piispan torni,ZONE 16: Forteresse: Tour de l'évèque,16. Terület: Erőd: Püspök tornya,AREA 16: Fortezza: Torre del Vescovo,エリア 16: 要塞:ビショップの塔,구역 16: 요새: 비숍의 탑,Zone 16: Vesting: Bisschopstoren,OMRÅDE 16: Festningen: Biskopens tårn,Strefa 16: Forteca: Wieża Biskupa,Área 16: Fortaleza: Torre do Bispo,,ZONA 16: Fortăreața: Turnul Episcopului,МЕСТНОСТЬ 16: Крепость (башня Епископа),,ALAN 16: Kale: Piskopos Kulesi -AREA 17: Fortress: The Bailey,TXT_STRIFE_MAP17,,,,ZÓNA 17: Pevnost: Předhradí,AREA 17: Fæstning: Bailey,ZONE 17: Festung: Vorhof,,AREO 17: Fortreso: La Murego,ÁREA 17: Fortaleza: El Patio,,ALUE 17: Linnoitus: linnanpiha,ZONE 17: Forteresse: Mur d'enceinte,17. Terület: Erőd: Várfal,AREA 17: Fortezza: Bastione,エリア 17: 要塞:ベイリー,구역 17: 요새: 안뜰,Zone 17: Vesting: Voorplein,OMRÅDE 17: Festningen: Borggården,Strefa 17: Forteca: Mur Obronny,Área 17: Fortaleza: O Pátio,,ZONA 17: Fortăreața: Curte,МЕСТНОСТЬ 17: Крепость (двор),,ALAN 17: Kale: Dış avlu -AREA 18: Fortress: Stores,TXT_STRIFE_MAP18,,,,ZÓNA 18: Pevnost: Sklady,AREA 18: Fæstning: Magasiner,ZONE 18: Festung: Lager,,AREO 18: Fortreso: Stokejoj,ÁREA 18: Fortaleza: Almacenes,,ALUE 18: Linnoitus: varastot,ZONE 18: Forteresse: Réserves,18. Terület: Erőd: Üzletek,AREA 18: Fortezza: Negozi,エリア 18: 要塞:商店,구역 18: 요새: 격납고,Zone 18: Vesting: Lager,OMRÅDE 18: Festningen: Lagrene,Strefa 18: Forteca: Sklepy,Área 18: Fortaleza: Reservas,,ZONA 18: Fortăreața: Depozite,МЕСТНОСТЬ 18: Крепость (склады),,ALAN 18: Kale: Mağazalar -AREA 19: Fortress: Security Complex,TXT_STRIFE_MAP19,,,,ZÓNA 19: Pevnost: Bezpečnostní komplex,AREA 19: Fæstning: Sikkerhedskompleks,ZONE 19: Festung: Sicherheitsanlage,,AREO 19: Fortreso: Sekurkomplekso,ÁREA 19: Fortaleza: Complejo de Seguridad,,ALUE 19: Linnoitus: turvallisuuskeskus,ZONE 19: Forteresse: Complexe Sécurité,19. Terület: Erőd: Biztonsági Részleg,AREA 19: Fortezza: Complesso di Sicurezza,エリア 19: 要塞:複合警備所,구역 19: 요새: 보안 담당 기지,Zone 19: Vesting: Beveiligingssysteem,OMRÅDE 19: Festningen: Sikkerhetskomplekset,Strefa 19: Forteca: Kompleks Ochronny,Área 19: Fortaleza: Complexo de Segurança,,ZONA 19: Fortăreața: Complex de securitate,МЕСТНОСТЬ 19: Крепость (охранный комплекс),,ALAN 19: Kale: Güvenlik Kompleksi +",구역 2: 마을,Zone 2: Stad,OMRÅDE 2: Byen,Strefa 2: Miasto,Área 2: Vila,,ZONA 2: Oraș,МЕСТНОСТЬ 2: Город,,OMRÅDE 2: Staden,ALAN 2: Şehir +AREA 3: Front Base,TXT_STRIFE_MAP03,,,,ZÓNA 3: Základna Fronty,AREA 3: Front Basis,ZONE 3: Basis der Front,,AREO 3: Front-Bazo,ÁREA 3: Base del Frente,,ALUE 3: Rintaman tukikohta,ZONE 3: Base du Front,3. Terület: Elülső bázis,AREA 3: Base del Fronte,エリア 3: フロント基地,구역 3: 프론트 기지,Zone 3: Front basis,OMRÅDE 3: Frontbase,Strefa 3: Baza Frontu,Área 3: Base da Frente,,ZONA 3: Baza Frontului,МЕСТНОСТЬ 3: База сопротивления,,OMRÅDE 3: Frontbasen,ALAN 3: Ön Taban +AREA 4: Power Station,TXT_STRIFE_MAP04,,,,ZÓNA 4: Elektrárna,AREA 4: Kraftværk,ZONE 4: Kraftwerk,,AREO 4: Elektrocentralo,ÁREA 4: Central Eléctrica,,ALUE 4: Voimalaitos,ZONE 4: Centrale,4. Terület: Erőmű,AREA 4: Centrale Elettrica,エリア 4: 発電所,구역 4: 발전소,Zone 4: Energiecentrale,OMRÅDE 4: Kraftstasjon,Strefa 4: Elektrownia,Área 4: Usina de Energia,Área 4: Central Energética,ZONA 4: Centrala,МЕСТНОСТЬ 4: Электростанция,,OMRÅDE 4: Kraftverk,ALAN 4: Elektrik Santrali +AREA 5: Prison,TXT_STRIFE_MAP05,,,,ZÓNA 5: Vězení,AREA 5: Fængsel,ZONE 5: Gefängnis,,AREO 5: Malliberejo,ÁREA 5: Prisión,,ALUE 5: Vankila,ZONE 5: Prison,5. Terület: Börtön,AREA 5: Carcere,エリア 5: 刑務所,구역 5: 감옥,Zone 5: Gevangenis,OMRÅDE 5: Fengsel,Strefa 5: Więzienie,Área 5: Prisão,,ZONA 5: Închisoare,МЕСТНОСТЬ 5: Тюрьма,,OMRÅDE 5: Fängelse,ALAN 5: Cezaevi +AREA 6: Sewers,TXT_STRIFE_MAP06,,,,ZÓNA 6: Stoky,AREA 6: Kloakkerne,ZONE 6: Kanalisation,,AREO 6: Kloako,ÁREA 6: Alcantarillas,,ALUE 6: Viemärit,ZONE 6: Egouts,6. Terület: Kanális,AREA 6: Fogne,エリア 6: 下水道,구역 6: 하수도,Zone 6: Riolering,OMRÅDE 6: Kloakk,Strefa 6: Kanały,Área 6: Esgoto,,ZONA 6: Canal,МЕСТНОСТЬ 6: Канализация,,OMRÅDE 6: Avloppsledningar,ALAN 6: Kanalizasyonlar +AREA 7: Castle,TXT_STRIFE_MAP07,,,,ZÓNA 7: Hrad,AREA 7: Slot,ZONE 7: Burg,,AREO 7: Kastelo,ÁREA 7: Castillo,,ALUE 7: Linna,ZONE 7: Château,7. Terület: Vár,AREA 7: Castello,エリア 7: 城,구역 7: 성,Zone 7: Kasteel,OMRÅDE 7: Slottet,Strefa 7: Zamek,Área 7: Castelo,,ZONA 7: Castel,МЕСТНОСТЬ 7: Замок,,OMRÅDE 7: Slott,ALAN 7: Kale +AREA 8: Audience Chamber,TXT_STRIFE_MAP08,,,,ZÓNA 8: Audienční sál,AREA 8: Audience Chamber,ZONE 8: Audienzsaal,,AREO 8: Aŭdicencejo,ÁREA 8: Cámara de Audiencias,,ALUE 8: Yleisösali,ZONE 8: Chambre d'Audience,8. Terület: Nézőtér,AREA 8: Sala delle Udienze,エリア 8: 観客席,구역 8: 알현실,Zone 8: Auditorium,OMRÅDE 8: Audienssalen,Strefa 8: Izba Audiencji,Área 8: Câmara de Audiências,,ZONA 8: Camera de audiențe,МЕСТНОСТЬ 8: Приёмная,,OMRÅDE 8: Publikrum,ALAN 8: İzleyici Odası +AREA 9: Castle: Programmer's Keep,TXT_STRIFE_MAP09,,,,ZÓNA 9: Hrad: Programátorovo doupě,AREA 9: Slot: Programmørens værelse,ZONE 9: Burg: Unterkunft des Programmierers,,AREO 9: Kastelo: Fortikaĵo de Programisto,ÁREA 9: Castillo: Guarida del Programador,,ALUE 9: Linna: Ohjelmoitsijan linnake,ZONE 9: Château: Donjon du Programmeur,9. Terület: Vár: Programozó parcellája,AREA 9: Castello: Dimora del Programmatore,エリア 9: 城内:プログラマーの間,구역 9: 성: 프로그래머의 성채,Zone 9: Kasteel: Onderdak van de programmeur,OMRÅDE 9: Slottet: Programmørens tårn,Strefa 9: Zamek: Baszta Programisty,Área 9: Castelo: Torre do Programador,,ZONA 9: Castel: Cetatea programatorului,МЕСТНОСТЬ 9: Цитадель Программиста,,OMRÅDE 9: Programmerarens behållning,ALAN 9: Kale: Programcının Kalesi +AREA 10: New Front Base,TXT_STRIFE_MAP10,,,,ZÓNA 10: Nová základna Fronty,AREA 10: Ny frontbase,ZONE 10: Neue Basis der Front,,AREO 10: Nova Frontbazo,ÁREA 10: Nueva Base del Frente,,ALUE 10: Uusi Rintaman tukikohta,ZONE 10: Nouvelle Base du Front,10. Terület: Új első bázis,AREA 10: Nuova Base del Fronte,エリア 10: 新フロント基地,구역 10: 새 프론트 기지,Zone 10: Nieuwe Front basis,OMRÅDE 10: Den nye frontbasen,Strefa 10: Nowa Baza Frontu,Área 10: Nova Base da Frente,,ZONA 10: Noua bază a Frontului,МЕСТНОСТЬ 10: Новая база сопротивления,,OMRÅDE 10: Ny frontbas,ALAN 10: Yeni Ön Taban +AREA 11: Borderlands,TXT_STRIFE_MAP11,,,,ZÓNA 11: Pohraničí,AREA 11: Grænseland,ZONE 11: Grenzgebiete,,AREO 11: Limlando,ÁREA 11: Tierras Fronterizas,,ALUE 11: Rajamaat,ZONE 11: Terres Sauvages,11. Terület: Peremvidék,AREA 11: Lande di Confine,エリア 11: 国境地帯,구역 11: 접경지,Zone 11: Grensgebieden,OMRÅDE 11: Grenseland,Strefa 11: Pogranicze,Área 11: Fronteira,,ZONA 11: Frontiere,МЕСТНОСТЬ 11: Пограничье,,OMRÅDE 11: Gränsområde,ALAN 11: Sınır Bölgeleri +AREA 12: The Temple of the Oracle,TXT_STRIFE_MAP12,,,,ZÓNA 12: Věštcův chrám,AREA 12: Oraklets tempel,ZONE 12: Der Tempel des Orakels,,AREO 12: La Templo de La Orakolo,ÁREA 12: El Templo del Oráculo,,ALUE 12: Oraakkelin temppeli,ZONE 12: Temple de l'Oracle,12. Terület: Az Orákulum Temploma,AREA 12: Il Tempio dell'Oracolo,エリア 12: オラクルの神殿,구역 12: 오라클의 신전,Zone 12: De tempel van het Orakel,OMRÅDE 12: Orakelets tempel,Strefa 12: Świątynia Wyroczni,Área 12: O Templo do Oráculo,,ZONA 12: Templul Oracolului,МЕСТНОСТЬ 12: Храм Оракула,,OMRÅDE 12: Oraklets tempel,ALAN 12: Kahin Tapınağı +AREA 13: Catacombs,TXT_STRIFE_MAP13,,,,ZÓNA 13: Katakomby,AREA 13: Katakomberne,ZONE 13: Katakomben,,AREO 13: Katakombo,ÁREA 13: Catacumbas,,ALUE 13: Katakombit,ZONE 13: Catacombes,13. Terület: Katakombák,AREA 13: Catacombe,エリア 13: 地下墓所,구역 13: 고대 묘지,Zone 13: Catacomben,OMRÅDE 13: Katakombene,Strefa 13: Katakumby,Área 13: Catacumbas,Área 13: Túmulos,ZONA 13: Catacombe,МЕСТНОСТЬ 13: Катакомбы,,OMRÅDE 13: Katakomberna,ALAN 13: Yeraltı Mezarları +AREA 14: Mines,TXT_STRIFE_MAP14,,,,ZÓNA 14: Doly,AREA 14: Miner,ZONE 14: Die Minen,,AREO 14: Minejo,ÁREA 14: Minas,,ALUE 14: Kaivokset,ZONE 14: Mines,14. Terület: Bánya,AREA 14: Miniere,エリア 14: 鉱山,구역 14: 광산,Zone 14: De mijnen,OMRÅDE 14: Minene,Strefa 14: Kopalnia,Área 14: Minas,,ZONA 14: Mine,МЕСТНОСТЬ 14: Шахты,,OMRÅDE 14: Gruvor,ALAN 14: Madenler +AREA 15: Fortress: Administration,TXT_STRIFE_MAP15,,,,ZÓNA 15: Pevnost: Administrace,AREA 15: Fæstning: Administration,ZONE 15: Festung: Administration,,AREO 15: Fortreso: Administrejo,ÁREA 15: Fortaleza: Administración,,ALUE 15: Linnoitus: hallinto,ZONE 15: Forteresse: Administration,15. Terület: Erőd: Elbírálás,AREA 15: Fortezza: Amministrazione,エリア 15: 要塞:管理室,구역 15: 요새: 중앙 관리소,Zone 15: Vesting: Administratieve organisatie,OMRÅDE 15: Festningen: Administrasjon,Strefa 15: Forteca: Administracja,Área 15: Fortaleza: Administração,,ZONA 15: Fortăreața: Administrația,МЕСТНОСТЬ 15: Крепость (администрация),,OMRÅDE 15: Fästning: Administration,ALAN 15: Kale: Yönetim +AREA 16: Fortress: Bishop's Tower,TXT_STRIFE_MAP16,,,,ZÓNA 16: Pevnost: Biskupova věž,AREA 16: Fæstning: Biskoppens tårn,ZONE 16: Festung: Bischofsturm,,AREO 16: Fortreso: Turo de Episkopo,ÁREA 16: Fortaleza: Torre del Obispo,,ALUE 16: Linnoitus: Piispan torni,ZONE 16: Forteresse: Tour de l'évèque,16. Terület: Erőd: Püspök tornya,AREA 16: Fortezza: Torre del Vescovo,エリア 16: 要塞:ビショップの塔,구역 16: 요새: 비숍의 탑,Zone 16: Vesting: Bisschopstoren,OMRÅDE 16: Festningen: Biskopens tårn,Strefa 16: Forteca: Wieża Biskupa,Área 16: Fortaleza: Torre do Bispo,,ZONA 16: Fortăreața: Turnul Episcopului,МЕСТНОСТЬ 16: Крепость (башня Епископа),,OMRÅDE 16: Fästningen: Biskopens torn,ALAN 16: Kale: Piskopos Kulesi +AREA 17: Fortress: The Bailey,TXT_STRIFE_MAP17,,,,ZÓNA 17: Pevnost: Předhradí,AREA 17: Fæstning: Bailey,ZONE 17: Festung: Vorhof,,AREO 17: Fortreso: La Murego,ÁREA 17: Fortaleza: El Patio,,ALUE 17: Linnoitus: linnanpiha,ZONE 17: Forteresse: Mur d'enceinte,17. Terület: Erőd: Várfal,AREA 17: Fortezza: Bastione,エリア 17: 要塞:ベイリー,구역 17: 요새: 안뜰,Zone 17: Vesting: Voorplein,OMRÅDE 17: Festningen: Borggården,Strefa 17: Forteca: Mur Obronny,Área 17: Fortaleza: O Pátio,,ZONA 17: Fortăreața: Curte,МЕСТНОСТЬ 17: Крепость (двор),,OMRÅDE 17: Fästning: Bailey,ALAN 17: Kale: Dış avlu +AREA 18: Fortress: Stores,TXT_STRIFE_MAP18,,,,ZÓNA 18: Pevnost: Sklady,AREA 18: Fæstning: Magasiner,ZONE 18: Festung: Lager,,AREO 18: Fortreso: Stokejoj,ÁREA 18: Fortaleza: Almacenes,,ALUE 18: Linnoitus: varastot,ZONE 18: Forteresse: Réserves,18. Terület: Erőd: Üzletek,AREA 18: Fortezza: Negozi,エリア 18: 要塞:商店,구역 18: 요새: 격납고,Zone 18: Vesting: Lager,OMRÅDE 18: Festningen: Lagrene,Strefa 18: Forteca: Sklepy,Área 18: Fortaleza: Reservas,,ZONA 18: Fortăreața: Depozite,МЕСТНОСТЬ 18: Крепость (склады),,OMRÅDE 18: Fästning: Butiker,ALAN 18: Kale: Mağazalar +AREA 19: Fortress: Security Complex,TXT_STRIFE_MAP19,,,,ZÓNA 19: Pevnost: Bezpečnostní komplex,AREA 19: Fæstning: Sikkerhedskompleks,ZONE 19: Festung: Sicherheitsanlage,,AREO 19: Fortreso: Sekurkomplekso,ÁREA 19: Fortaleza: Complejo de Seguridad,,ALUE 19: Linnoitus: turvallisuuskeskus,ZONE 19: Forteresse: Complexe Sécurité,19. Terület: Erőd: Biztonsági Részleg,AREA 19: Fortezza: Complesso di Sicurezza,エリア 19: 要塞:複合警備所,구역 19: 요새: 보안 담당 기지,Zone 19: Vesting: Beveiligingssysteem,OMRÅDE 19: Festningen: Sikkerhetskomplekset,Strefa 19: Forteca: Kompleks Ochronny,Área 19: Fortaleza: Complexo de Segurança,,ZONA 19: Fortăreața: Complex de securitate,МЕСТНОСТЬ 19: Крепость (охранный комплекс),,OMRÅDE 19: Fästning: Säkerhetskomplex,ALAN 19: Kale: Güvenlik Kompleksi AREA 20: Factory: Receiving,TXT_STRIFE_MAP20,,,,ZÓNA 20: Továrna: Příjem,AREA 20: Fabrik: Modtagelse,ZONE 20: Fabrik: Empfang,,AREO 20: Fabrikejo: Ricevejo,ÁREA 20: Fábrica: Recepción,,ALUE 20: Tehdas: vastaanotto,ZONE 20: Usine: Réception,20. Terület: Gyár: Beérkeztető,AREA 20: Fabbrica: Ricevimento,"エリア 20: 工場:受取所 -",구역 20: 공장: 수납구역,Zone 20: Fabriek: Ontvangst,OMRÅDE 20: Fabrikken: Mottak,Strefa 20: Fabryka: Odbiór,Área 20: Fábrica: Recebimento,,ZONA 20: Fabrica: Recepție,МЕСТНОСТЬ 20: Фабрика (приём),,ALAN 20: Fabrika: Teslim Alma -AREA 21: Factory: Manufacturing,TXT_STRIFE_MAP21,,,,ZÓNA 21: Továrna: Výroba,AREA 21: Fabrik: Fremstilling,ZONE 21: Fabrik: Herstellung,,AREO 21: Fabrikejo,ÁREA 21: Fábrica: Manufactura,,ALUE 21: Tehdas: tuotanto,ZONE 21: Usine: Manufacture,21. Terület: Gyár: Gyártósor,AREA 21: Fabbrica: Manifattura,エリア 21: 工場:製造機関,구역 21: 공장: 조립시설,Zone 21: Fabriek: Productie,OMRÅDE 21: Fabrikk: Produksjon,Strefa 21: Fabryka: Przetwórstwo,Área 21: Fábrica: Manufatura,,ZONA 21: Fabrica: Procesare,МЕСТНОСТЬ 21: Фабрика (производство),,ALAN 21: Fabrika: İmalat -AREA 22: Factory: Forge,TXT_STRIFE_MAP22,,,,ZÓNA 22: Továrna: Slévárna,AREA 22: Fabrik: Smedje,ZONE 22: Fabrik: Schmiede,,AREO 22: Fabrikejo: Forĝejo,ÁREA 22: Fábrica: Forja,,ALUE 22 Tehdas: paja,ZONE 22: Usine: Forge,22. Terület: Gyár: Kohó,AREA 22: Fabbrica: Fucina,エリア 22: 工場:鉄工所,구역 22: 공장: 제련소,Zone 22: Fabriek: Smederij,OMRÅDE 22: Fabrikk: Smie,Strefa 22: Fabryka: Kuźnia,Área 22: Fábrica: Forja,,ZONA 22: Fabrica: Forja,МЕСТНОСТЬ 22: Фабрика (кузня),,ALAN 22: Fabrika: Demirhane -AREA 23: Order Commons,TXT_STRIFE_MAP23,,,,ZÓNA 23: Náves Řádu,AREA 23: Bestillingscentral,ZONE 23: Mensa des Ordens,,AREO 23: Komunejo de La Ordeno,ÁREA 23: Condominios de la Orden,,ALUE 23: Veljeskunnan messi,ZONE 23: Mess de l'Ordre,23. Terület: Rendi köztér,AREA 23: Camera dell'Ordine,エリア 23: オーダーコモンズ,구역 23: 오더 식당가,Zone 23: Mensa van de orde,OMRÅDE 23: Bestillingsallmenning,Strefa 23: Wikt Zakonu,Área 23: Câmara da Ordem,,ZONA 23: Decontare comenzi,МЕСТНОСТЬ 23: Поселение Ордена,,ALAN 23: Siparişin ortak alanı -AREA 24: Factory: Conversion Chapel,TXT_STRIFE_MAP24,,,,ZÓNA 24: Továrna: Kaple konverze,AREA 24: Fabrik: Omdannelseskapel,ZONE 24: Umwandlungskapelle,,AREO 24: Fabrikejo: Konvert-Kapelo,ÁREA 24: Fábrica: Capilla de Conversión,,ALUE 24: Tehdas: käännytyskappeli,ZONE 24: Usine: Chapelle de Conversion,24. Terület: A megtérés kápolnája,AREA 24: Fabbrica: Cappella di Conversione,エリア 24: 工場:改宗礼拝堂,구역 24: 공장: 전향실,Zone 24: Verbouwingskapel,OMRÅDE 24: Fabrikk: Konverteringskapell,Strefa 24: Fabryka: Kaplica Przemiany,Área 24: Fábrica: Capela de Conversão,,ZONA 24: Fabrica: Capela de conversie,МЕСТНОСТЬ 24: Фабрика (часовня обращения),,ALAN 24: Fabrika: Dönüşüm Şapeli -AREA 25: Catacombs: Ruined Temple,TXT_STRIFE_MAP25,,,,ZÓNA 25: Katakomby: Zničený chrám,AREA 25: Katakomberne: Ruineret tempel,ZONE 25: Katakomben: Zerstörter Tempel,,AREO: 25: Katakombo: Ruiniga Templo,ÁREA 25: Catacumbas: Templo Arruinado,,ALUE 25: Katakombit: temppeliraunio,ZONE 25: Catacombes: Temple Ruiné,25. Terület: Katakombák: Romtemplom,AREA 25: Catacombe: Tempio in Rovina,エリア 25: 地下墓所:没落した寺院,구역 25: 고대 묘지: 무너진 사원,Zone 25: Catacomben: Vernietigde tempel,OMRÅDE 25: Katakombene: Ruinert tempel,Strefa 25: Katakumby: Zrujnowana Świątynia,Área 25: Catacumbas: Templo Arruinado,Área 25: Túmulos: Templo Arruinado,ZONA 25: Catacombe: Templu în ruine,МЕСТНОСТЬ 25: Катакомбы (руины храма),,ALAN 25: Yeraltı Mezarları: Yıkık Tapınak -AREA 26: Proving Grounds,TXT_STRIFE_MAP26,,,,ZÓNA 26: Vojenský újezd,AREA 26: Prøvesteder,ZONE 26: Testgelände,,AREO 26: Provejo,ÁREA 26: Campo de Pruebas,,ALUE 26: Koetuspaikka,ZONE 26: Terrain d'entraînement,26. Terület: Próbatételek Földje,AREA 26: Banco di Prova,エリア 26: 試練場,구역 26: 증명의 전장,Zone 26: Testgebied,OMRÅDE 26: Prøveplassen,Strefa 26: Poligon Wojskowy,Área 26: Campo de Treinamento,Área 26: Campo de Treino,ZONA 26: Tabăra de instruire,МЕСТНОСТЬ 26: Испытательный полигон,,ALAN 26: Kanıtlama Alanları -AREA 27: The Lab,TXT_STRIFE_MAP27,,,,ZÓNA 27: Laboratoř,AREA 27: Laboratoriet,ZONE 27: Das Labor,,AREO 27: La Labotorio,ÁREA 27: El Laboratorio,,ALUE 27: Laboratorio,ZONE 27: Laboratoire,27. Terület: A labor,AREA 27: Il Laboratorio,エリア 27: 研究所,구역 27: 연구소,Zone 27: Het laboratorium,OMRÅDE 27: Laboratoriet,Strefa 27: Laboratorium,Área 27: O Laboratório,,ZONA 27: Laboratorul,МЕСТНОСТЬ 27: Лаборатория,,ALAN 27: Laboratuvar -AREA 28: Alien Ship,TXT_STRIFE_MAP28,,,,ZÓNA 28: Mimozemská loď,AREA 28: Fremmed skib,ZONE 28: Außerirdisches Schiff,,AREO 28: Alilanda Ŝipo,ÁREA 28: Nave Alienígena,,ALUE 28: Muukalaisalus,ZONE 28: Vaisseau Alien,28. Terület: Idegen űrhajó,AREA 28: Nave Aliena,エリア 28: エイリアンの船,구역 28: 외계 우주선,Zone 28: Buitenaards schip,OMRÅDE 28: Det fremmede skipet,Strefa 28: Statek Obcych,Área 28: Nave Alienígena,,ZONA 28: Nava extraterestră,МЕСТНОСТЬ 28: Корабль пришельцев,,ALAN 28: Uzaylı Gemisi -AREA 29: Entity's Lair,TXT_STRIFE_MAP29,,,,ZÓNA 29: Doupě Bytosti,AREA 29: Entitetsnesten,ZONE 29: Das Nest der Entität,,AREO 29: Nestego de Estulo,ÁREA 29: Escondite de la Entidad,,ALUE 29: Tosiolevan maja,ZONE 29: Demeure de L'Entité,29. Terület: A Teremtvény Búvóhelye,AREA 29: Tana dell'Entità,エリア 29: エンティティの隠れ家,구역 29: 엔티티의 소굴,Zone 29: Het nest van de entiteit,OMRÅDE 29: Enhetens hule,Strefa 29: Leże Bytu,Área 29: Covil da Entidade,,ZONA 29: Cuibul Entității,МЕСТНОСТЬ 29: Логово Сущности,,ALAN 29: Varlığın İni -AREA 30: Abandoned Front Base,TXT_STRIFE_MAP30,,,,ZÓNA 30: Opuštěná základna Fronty,AREA 30: Forladt frontbase,ZONE 30: Verlassene Basis der Front,,AREO 30: Forlasita Front-Bazo,ÁREA 30: Base Abandonada del Frente,,ALUE 30: Hylätty Rintaman tukikohta,ZONE 30: Base Abandonnée du Front,30. Terület: Elhagyatott Előbázis,AREA 30: Base del Fronte abbandonata,エリア 30: 放棄された基地,구역 30: 버려진 프론트 기지,Zone 30: Verlaten frontbasis,OMRÅDE 30: Forlatt frontbase,Strefa 30: Opuszczona Baza Frontu,Área 30: Base da Frente Abandonada,,ZONA 30: Baza abandonată a Frontului,МЕСТНОСТЬ 30: Заброшенная база сопротивления,,ALAN 30: Terk Edilmiş Ön Üs -AREA 31: Training Facility,TXT_STRIFE_MAP31,,,,ZÓNA 31: Výcvikové zařízení,AREA 31: Træningsanlæg,ZONE 31: Trainingseinrichtung,,AREO 31: Trejnejo,ÁREA 31: Zona de entrenamiento,,ALUE 31: Koulutuslaitos,ZONE 31: Complexe d'Entraînement,31. Terület: Kiképzőbázis,AREA 31: Struttura di Addestramento,エリア 31: 研修施設,구역 31: 훈련 시설,Zone 31: Trainingsfaciliteit,OMRÅDE 31: Treningsanlegg,Strefa 31: Centrum Szkoleniowe,Área 31: Instalação de Treinamento,,ZONA 31: Spațiul de antrenament,МЕСТНОСТЬ 31: Тренировочный корпус,,ALAN 31: Eğitim Tesisi -AREA 1: Sanctuary,TXT_STRIFE_MAP32,,,,ZÓNA 1: Svatyně,AREA 1: Fristedet,ZONE 1: Heiligtum,,AREO 1: Sanktejo,ÁREA 1: Santuario,,ALUE 1: Pyhäkkö,ZONE 1: Sanctuaire,1. Terület: Szentély,AREA 1: Santuario,エリア 1: 聖域 ,구역 1: 성소,Zone 1: Heiligdom,OMRÅDE 1: Fristedet,Strefa 1: Sanktuarium,Área 1: Santuário,,ZONA 1: Sanctuar,МЕСТНОСТЬ 1: Святилище,,ALAN 1: Sığınak -AREA 2: Town,TXT_STRIFE_MAP33,,,,ZÓNA 2: Město,AREA 2: By,ZONE 2: Stadt,,AREO 2: Urbeto,ÁREA 2: Pueblo,,ALUE 2: Kylä,ZONE 2: Ville,2. Terület: Város,AREA 2: Città,エリア 2: 町,구역 2: 마을,Zone 2: Stad,OMRÅDE 2: By,Strefa 2: Miasto,Área 2: Vila,,ZONA 2: Oraș,МЕСТНОСТЬ 2: Город,,ALAN 2: Şehir -AREA 3: Movement Base,TXT_STRIFE_MAP34,,,,ZÓNA 3: Rebelská základna,AREA 3: Front Basis,ZONE 3: Rebellenbasis,,AREO 3: Movad-Bazo,ÁREA 3: Base del Movimiento,,ALUE 3: Liikkeen tukikohta,ZONE 3: Base du Front,3. Terület: Mozgalmi Bázis,AREA 3: Base del Movimento,エリア 3: 移転基地,구역 3: 반군 기지,Zone 3: Front basis,OMRÅDE 3: Bevegelsesbase,Strefa 3: Baza Ruchu Oporu,Área 3: Base do Movimento,,ZONA 3: Baza rezistenței,МЕСТНОСТЬ 3: База сопротивления,,ALAN 3: Hareket Üssü -AREA 35: Factory: Production,TXT_STRIFE_MAP35,,,,ZÓNA 35: Továrna: Produkce,AREA 35: Fabrik: Produktion,ZONE 35: Fabrik: Produktion,,AREO 35: Fabrikejo: Produktejo,ÁREA 35: Fábrica: Producción,,ALUE 35: Tehdas: tuotanto,ZONE 35: Usine: Production,35. Terület: Gyár: Termelés,AREA 35: Fabbrica: Produzione,エリア 35: 工場 : 生産ライン,구역 35: 공장: 제작실,Zone 35: Fabriek: Productie,OMRÅDE 35: Fabrikk: Produksjon,Strefa 35: Fabryka: Produkcja,Área 35: Fábrica: Produção,,ZONA 35: Fabrica: Producție,МЕСТНОСТЬ 35: Фабрика (производство),,ALAN 35: Fabrika: Üretim -AREA 36: Castle Clash,TXT_STRIFE_MAP36,,,,ZÓNA 36: Střet na hradě,AREA 36: Slotskampe,ZONE 36: Burg-Konflikt,,AREO 36: Batalo ĉe Kastelo,ÁREA 36: Ataque al Castillo,,ALUE 36: Linnayhteenotto,ZONE 36: Bataille du Château,36: Terület: Vári ütközet,AREA 36: Collisione di Castello,エリア 36: キャッスルクラッシュ,구역 36: 성채간의 충돌,Zone 36: Kasteelconflict,OMRÅDE 36: Slottskampen,Strefa 36: Potyczka w Zamku,Área 36: Ataque ao Castelo,,ZONA 36: Bătălia castelului,МЕСТНОСТЬ 36: Битва в замке,,ALAN 36: Kale Çatışması -AREA 37: Killing Grounds,TXT_STRIFE_MAP37,,,,ZÓNA 37: Popravčí zahrady,AREA 37: Drabsområder,ZONE 37: Kampfgelände,,AREO 37: Tereno de Mortigado,ÁREA 37: Campo de Matanza,,ALUE 37: Tappotanner,ZONE 37: Zone de Chasse,37. Terület: Gyilkos Vidék,AREA 37: Campi di Uccisione,エリア 37: 殺害者の地,구역 37: 살육의 전장,Zone 37: Slagveld,OMRÅDE 37: Drapsplasser,Strefa 37: Śmiercionośny Grunt,Área 37: Campo de Matança,,ZONA 37: Teren de ucis,МЕСТНОСТЬ 37: Сектора обстрела,,ALAN 37: Öldürme Alanları -AREA 38: Ordered Chaos,TXT_STRIFE_MAP38,,,,ZÓNA 38: Nařízený chaos,AREA 38: Ordnet kaos,ZONE 38: Geordnetes Chaos,,AREO 38: Orda Kaoso,ÁREA 38: Caos Ordenado,,ALUE 38: Järjestynyt kaaos,ZONE 38: Chaos Ordonné,38. Terület: Rendezett Káosz,AREA 38: Caos Ordinato,エリア 38: カオスの秩序,구역 38: 정돈된 혼란,Zone 38: Ordelijke chaos,OMRÅDE 38: Ordnet kaos,Strefa 38: Uporządkowany Chaos,Área 38: Caos Ordenado,,ZONA 38: Haos controlat,МЕСТНОСТЬ 38: Управляемый хаос,,ALAN 38: Düzenli Kaos -,,Hexen,,,,,,,,,,,,,,,,,,,,,,,, -Winnowing Hall,TXT_HEXEN_MAP01,,,,Sál prosetí,Separationshal,Trennungshalle,,Solenejo de Separado,Sala de los Vientos,,Viskaussali,Chambre de la Séparation,Huzatos Folyosó,Camera di separazione,選抜の間,바람 회관,Scheidingszaal,Vinnersalen,Hala Przesiewu,Sala de Separação,,Sala de Separare,Зал отсеивания,Предсобље просејавања,Ayrılma Salonu -Seven Portals,TXT_HEXEN_MAP02,,,,Sedmero portálů,Syv portaler,Sieben Portale,,Sep Portaloj,Siete Portales,,Seitsemän portaalia,Les Sept Portails,Hét Portál,I Sette Portali,漆之門,일곱 차원문,Zeven portalen,Syv portaler,Siedem Portali,Sete Portais,,Șapte Portaluri,Семь порталов,Седам портала,Yedi Portal -Guardian of Ice,TXT_HEXEN_MAP03,,,,Strážce ledu,Vogter af is,Wächter des Eises,,Gardanto de Glacio,Guardián de Hielo,,Jään vartija,Gardien de Glace,A Jég Őre,Guardiano del Ghiaccio,氷の守護者,얼음의 수호자,Bewaker van ijs,Isens vokter,Strażnik Lodu,Guardião de Gelo,,Străjerul Gheții,Страж льда,Чувар леда,Buz Muhafızı -Guardian of Fire,TXT_HEXEN_MAP04,,,,Strážce ohně,Vogter af ild,Wächter des Feuers,,Gardanto de Fajro,Guardián de Fuego,,Tulen vartija,Gardien de Feu,A Tűz Őre,Guardiano del Fuoco,炎の守護者,화염의 수호자,Bewaker van vuur,Ildens vokter,Strażnik Ognia,Guardião de Fogo,,Străjerul Focului,Страж огня,Чувар огња,Ateşin Koruyucusu -Guardian of Steel,TXT_HEXEN_MAP05,,,,Strážce oceli,Vogter af stål,Wächter des Stahls,,Gardanto de Ŝtalo,Guardián de Acero,,Teräksen vartija,Gardien d'Acier,Az Acél Őre,Guardiano dell'Acciaio,鋼の守護者,강철의 수호자,Bewaker van staal,Stålets vokter,Strażnik Stali,Guardião de Aço,,Străjerul Oțelului,Страж стали,Чувар челика,Çelik Muhafız -Bright Crucible,TXT_HEXEN_MAP06,,,,Světlý očistec,Lys udfordring,Glänzende Feuerprobe,,Luma Krisolo,Crisol de Luz,,Kirkas tulikoe,Creuset Radiant,Fényes Ketrec,Crogiolo Luminoso,光の坩堝,빛나는 고난,Heldere beproeving,Lys utfordring,Tygiel Światła,Crisol de Luz,,Creuzet Luminos,Горнило света,Испит светла,Parlak Pota -Shadow Wood,TXT_HEXEN_MAP13,,,,Temný hvozd,Skyggetræ,Schattenwald,,Ombro-Arbareto,Bosque de la Sombra,,Varjosalo,Forêt des Ombres,Árnyék Erdő,Foresta Oscura,陰影樹,그림자 숲,Schaduwbos,Skyggeskogen,Las Cieni,Floresta das Sombras,,Pădurea Umbrelor,Лес теней,Шума сенки,Gölge Ahşap -Darkmere,TXT_HEXEN_MAP08,,,,Černý močál,,Düstersee,,Malluma Marĉo,Pantano,,Pikiräme,Marais Noir,Fekete Mocsár,Palude Nera,暗黒の地,흙빛호수,Sombermeer,,Mroczne Bagno,Pantâno Negro,,Mlaștinile Întunecate,Болотная топь,Мочварна земља,Koyu göl -Caves of Circe,TXT_HEXEN_MAP09,,,,Kirčiny jeskyně,Circes' grotter,Circes Höhle,,Kavernoj de Circe,Cuevas de Circe,,Circeluolat,Caves de Circé,Körök Barlangja,Grotte di Circe,キルケーの洞窟,키르케의 동굴,Grotten van Circe,Circes grotter,Jaskinie Kirke,Cavernas de Circe,,Peșterile lui Circe,Пещеры Цирцеи,Киркине пећине,Kirke Mağaraları -Wastelands,TXT_HEXEN_MAP10,,,,Pustiny,Ødemarker,Ödland,,Senvivejo,Yermo,,Erämaat,Terres Ruinées,Senkiföldje,Terre in rovina,荒野,황무지,Woestenij,Ødemarken,Pustkowia,Terras Desoladas,,Tărâmurile Pustii,Пустоши,Пустоши,Çorak Topraklar -Sacred Grove,TXT_HEXEN_MAP11,,,,Posvátný háj,Helliglund,Heiliger Hain,,Sankta Bosketo,Arboleda Sagrada,,Pyhä metsikkö,Bosquet Sacré,Szent Liget,Boschetto Sacro,神聖なる園,성스러운 수풀,Heilig bosje,Hellig lund,Święty Gaj,Bosque Sagrado,,Crângul Sacru,Священная роща,Свети шумарак,Kutsal Koru -Hypostyle,TXT_HEXEN_MAP12,,,,Hypostyl,,Säulenhalle,,Kolonejo,Hipóstila,,Hypostyyli,Hypostyle,Oszlopterem,Ipostilo,多柱の間,다주실,Zuilenhal,,Hypostyl,Hipostilo,,Hipostil,Гипостильный зал,Хипостил,Hipostil -Heresiarch's Seminary,TXT_HEXEN_MAP27,,,,Arcikacířův alumnát,Heresiarkens seminarium,Seminar des Erzketzers,,Seminario de Ĉefherezulo,Seminario del Heresiarca,,Kerettiarkin seminaari,Séminaire de l'Hérésiarche,A Főeretnek Neveldéje,Seminario dell'Heresiarch,ヘレシアークの神学舎,헤러시아크의 신학교,Seminarie van ketterij,Heresiarkens seminar,Seminarium Herezjarchy,Seminário do Heresiarca,,Seminarul Ereziarhului,Семинария Ересиарха,Јересијархов семинар,Heresiark'ın Ruhban Okulu -Dragon Chapel,TXT_HEXEN_MAP28,,,,Dračí kaple,Dragekapel,Drachenkapelle,,Drakkapelo,Capilla Dragón,,Lohikäärmekappeli,Chapelle du Dragon,Sárkány Szentély,Cappella del Drago,ドラゴンの庵寺,드래곤 예배실,Drakenkapel,Dragekapell,Kaplica Smoka,Capela do Dragão,,Capela dragonilor,Часовня дракона,Капела змајева,Ejderha Şapeli -Griffin Chapel,TXT_HEXEN_MAP30,,,,Gryfova kaple,Griffinkapel,Greifenkapelle,,Grifkapelo,Capilla Grifo,,Aarnikotkakappeli,Chapelle du Grifon,Griff Szentély,Cappella del Grifone,グリフィンの庵寺,그리핀 예배실,Griffioenenkapel,Griffon kapell,Kaplica Gryfa,Capela do Grifo,,Capela grifonilor,Часовня грифона,Капела грифонова,Griffin Şapeli -Deathwind Chapel,TXT_HEXEN_MAP31,,,,Kaple mrakosmrtě,Dødens vind kapel,Todeswindkapelle,,Mortvento-Kapelo,Capilla Viento de Muerte,,Kuolontuulikappeli,Chapelle du Vent Tueur,Halál Szentély,Cappella del Vento Assassino,デスウィンドの庵寺,죽음바람 예배실,Dodenwind kapel,Dødens vind kapell,Kaplica Wiatru Śmierci,Capela do Vento da Morte,,Capela suflului morții,Часовня ветра смерти,Капела ветра смрти,Ölüm Rüzgarı Şapeli -Orchard of Lamentations,TXT_HEXEN_MAP32,,,,Sad nářků,Klagesangens frugthave,Garten der Wehklagen,,Horto de Lamentoj,Huerto de los Lamentos,,Valitusvirtten tarha,Verger des Lamentations,Siránkozás Kertje,Frutteto delle Lamentazioni,哀悼茂る園,통탄의 과수원,Boomgaard van klaagliederen,Klagesangens hage,Płaczący Sad,Pomar das Lamentações,,Livada amărăciunii,Сады плача,Воћњак плача,Ağıtlar Bahçesi -Silent Refectory,TXT_HEXEN_MAP33,,,,Tichý refektář,Stilhedens refektorium,Stilles Refektorium,,Silenta Manĝejo,Refectorio Silencioso,,Hiljainen ruokasali,Réfectoire Silencieux,Néma Refektórium,Refettorio silenzioso,寡黙なる食堂,침묵의 식당,Stil refectory,Stille refektorium,Cichy Refektarz,Refeitório Silencioso,,Refectoriul tăcerii,Безмолвная трапезная,Безгласна трпезарија,Sessiz Yemekhane -Wolf Chapel,TXT_HEXEN_MAP34,,,,Vlčí kaple,Ulvekapel,Wolfskapelle,,Lupkapelo,Capilla Lobo,,Susikappeli,Chapelle du Loup,Farkas Szentély,Cappella del Lupo,狼の庵寺,늑대 예배실,Wolvenkapel,Ulvens kapell,Kaplica Wilka,Capela do Lobo,,Capela lupilor,Часовня волка,Капела вучја,Kurt Şapeli -Forsaken Outpost,TXT_HEXEN_MAP21,,,,Opuštěné stanoviště,Forladt forpost,Verlassener Vorposten,,Forlasita Posteno,Puesto de Avanzada Abandonado,,Hylätty etuvartio,Base Abandonnée,Elhagyott Őrség,Avamposto Abbandonato,荒れ果てた前哨地,버려진 초소,Verwaarloosde buitenpost,Forlatt utpost,Opuszczony Posterunek,Posto Abandonado,,Avanpostul părăsit,Покинутая застава,Напуштена постаја,Unutulmuş Karakol -Castle of Grief,TXT_HEXEN_MAP22,,,,Hrad smutku,Sorgens slot,Leidensburg,,Kastelo de Funebro,Castillo del Pesar,,Surulinna,Château de la Souffrance,A Gyász Kastélya,Castello della Sofferenza,嘆きの城,비탄의 성,Kasteel van verdriet,Sorgens slott,Zamek Smutku,Castelo da Aflição,,Castelul întristării,Замок скорби,Замак жалости,Keder Kalesi -Gibbet,TXT_HEXEN_MAP23,,,,Šibenice,,Richtstätte,,Pendigilo,Horca,,Hirsipuu,Gibet,Akasztófa,Forca,晒し台,교수대,,Galgen,Szubienica,Forca,,Eșafodul,Виселица,Вешала,İnfaz yeri -Effluvium,TXT_HEXEN_MAP24,,,,Výpary,,Effluvium,,Efluvo,Efluvio,,Katku,Effluvium,A Bűz Börtöne,Effluvio,腐臭漂う残骸,악취,,,Odór,Eflúvio,,Efluviu,Зловонный сток,Воњави одвод,Atık Su -Dungeons,TXT_HEXEN_MAP25,,,,Žalář,Fangehuller,Kerker,,Karceroj,Calabozos,,Tyrmät,Donjons,Kazamaták,I Dungeon,地下牢,지하감옥,Kerkers,Fangehull,Lochy,Masmorras,,Temnițe,Подземелья,Лагуми,Zindanlar -Desolate Garden,TXT_HEXEN_MAP26,,,,Zpustošená zahrada,Ødelagt have,Verwildeter Garten,,Dezerta Ĝardeno,Jardín Desolado,,Autio puutarha,Jardin de la Désolation,Sivár Kert,Giardino Desolato,荒涼とした庭,황폐한 정원,Woeste tuin,Øde hage,Spustoszały Ogród,Jardim Desolado,,Grădina dezolantă,Заброшенный сад,Напуштени врт,Issız Bahçe -Necropolis,TXT_HEXEN_MAP35,,,,Nekropole,Nekropolis,Nekropole,,Nekropolo,Necrópolis,,Nekropoli,Nécropole,Nekropolisz,Necropoli,ネクロポリス,망자의 도시,,Nekropolis,Nekropolia,Necrópole,,Necropola,Некрополь,Некропола,Nekropol -Zedek's Tomb,TXT_HEXEN_MAP36,,,,Zedekova hrobka,Zedeks grav,Zedeks Gruft,,Tombo de Zedek,Tumba de Zedek,,Sedekin hauta,Tombeau de Zedek,Zedek Sírja,Tomba di Zedek,ゼデクの墓,제닥의 무덤,Zedek's graf,Zedeks grav,Grobowiec Zedeka,Tumba de Zedek,Túmulo de Zedek,Mormântul lui Zedek,Гробница Зедека,Гробница Зедекова,Zedek'in Mezarı -Menelkir's Tomb,TXT_HEXEN_MAP37,,,,Menelkirova hrobka,Menelkirs grav,Menelkirs Gruft,,Tombo de Menelkir,Tumba de Menelkir,,Menelkirin hauta,Tombeau de Menelkir,Menelkir Sírja,Tomba di Menelkir,メネルキルの墓,메넬키어의 무덤,Menelkir's graf,Menelkirs grav,Grobowiec Menelkira,Tumba de Menelkir,Túmulo de Menelkir,Mormântul lui Menelkir,Гробница Менелкира,Гробница Менелкирова,Menelkir'in Mezarı -Traductus' Tomb,TXT_HEXEN_MAP38,,,,Traduktova hrobka,Traductus' grav,Traductus' Gruft,,Tombo de Traductus,Tumba de Traductus,,Traduktuksen hauta,Tombeau de Traductus,Traductus Sírja,Tomba di Traductus,トダクティスの墓,트라닥투스의 무덤,Traductus' graf,Traductus' grav,Grobowiec Traduktusa,Tumba de Traductus,Túmulo de Traductus,Mormântul lui Traductus,Гробница Традактуса,Гробница Традуктусова,Traductus'un Mezarı -Vivarium,TXT_HEXEN_MAP39,,,,Vivárium,,Vivarium,,Vivario,Vivario,,Vivaario,Vivarium,Vivárium,Vivario,ビバリウム,사육장,,,Wiwarium,Viveiro,,Vivariu,Виварий,Виваријум,Vivarium +",구역 20: 공장: 수납구역,Zone 20: Fabriek: Ontvangst,OMRÅDE 20: Fabrikken: Mottak,Strefa 20: Fabryka: Odbiór,Área 20: Fábrica: Recebimento,,ZONA 20: Fabrica: Recepție,МЕСТНОСТЬ 20: Фабрика (приём),,OMRÅDE 20: Fabrik: Mottagning,ALAN 20: Fabrika: Teslim Alma +AREA 21: Factory: Manufacturing,TXT_STRIFE_MAP21,,,,ZÓNA 21: Továrna: Výroba,AREA 21: Fabrik: Fremstilling,ZONE 21: Fabrik: Herstellung,,AREO 21: Fabrikejo,ÁREA 21: Fábrica: Manufactura,,ALUE 21: Tehdas: tuotanto,ZONE 21: Usine: Manufacture,21. Terület: Gyár: Gyártósor,AREA 21: Fabbrica: Manifattura,エリア 21: 工場:製造機関,구역 21: 공장: 조립시설,Zone 21: Fabriek: Productie,OMRÅDE 21: Fabrikk: Produksjon,Strefa 21: Fabryka: Przetwórstwo,Área 21: Fábrica: Manufatura,,ZONA 21: Fabrica: Procesare,МЕСТНОСТЬ 21: Фабрика (производство),,OMRÅDE 21: Fabrik: Tillverkning,ALAN 21: Fabrika: İmalat +AREA 22: Factory: Forge,TXT_STRIFE_MAP22,,,,ZÓNA 22: Továrna: Slévárna,AREA 22: Fabrik: Smedje,ZONE 22: Fabrik: Schmiede,,AREO 22: Fabrikejo: Forĝejo,ÁREA 22: Fábrica: Forja,,ALUE 22 Tehdas: paja,ZONE 22: Usine: Forge,22. Terület: Gyár: Kohó,AREA 22: Fabbrica: Fucina,エリア 22: 工場:鉄工所,구역 22: 공장: 제련소,Zone 22: Fabriek: Smederij,OMRÅDE 22: Fabrikk: Smie,Strefa 22: Fabryka: Kuźnia,Área 22: Fábrica: Forja,,ZONA 22: Fabrica: Forja,МЕСТНОСТЬ 22: Фабрика (кузня),,OMRÅDE 22: Fabrik: Smedja,ALAN 22: Fabrika: Demirhane +AREA 23: Order Commons,TXT_STRIFE_MAP23,,,,ZÓNA 23: Náves Řádu,AREA 23: Bestillingscentral,ZONE 23: Mensa des Ordens,,AREO 23: Komunejo de La Ordeno,ÁREA 23: Condominios de la Orden,,ALUE 23: Veljeskunnan messi,ZONE 23: Mess de l'Ordre,23. Terület: Rendi köztér,AREA 23: Camera dell'Ordine,エリア 23: オーダーコモンズ,구역 23: 오더 식당가,Zone 23: Mensa van de orde,OMRÅDE 23: Bestillingsallmenning,Strefa 23: Wikt Zakonu,Área 23: Câmara da Ordem,,ZONA 23: Decontare comenzi,МЕСТНОСТЬ 23: Поселение Ордена,,OMRÅDE 23: Beställningscentraler,ALAN 23: Siparişin ortak alanı +AREA 24: Factory: Conversion Chapel,TXT_STRIFE_MAP24,,,,ZÓNA 24: Továrna: Kaple konverze,AREA 24: Fabrik: Omdannelseskapel,ZONE 24: Umwandlungskapelle,,AREO 24: Fabrikejo: Konvert-Kapelo,ÁREA 24: Fábrica: Capilla de Conversión,,ALUE 24: Tehdas: käännytyskappeli,ZONE 24: Usine: Chapelle de Conversion,24. Terület: A megtérés kápolnája,AREA 24: Fabbrica: Cappella di Conversione,エリア 24: 工場:改宗礼拝堂,구역 24: 공장: 전향실,Zone 24: Verbouwingskapel,OMRÅDE 24: Fabrikk: Konverteringskapell,Strefa 24: Fabryka: Kaplica Przemiany,Área 24: Fábrica: Capela de Conversão,,ZONA 24: Fabrica: Capela de conversie,МЕСТНОСТЬ 24: Фабрика (часовня обращения),,OMRÅDE 24: Fabrik: Omvandlingskapell,ALAN 24: Fabrika: Dönüşüm Şapeli +AREA 25: Catacombs: Ruined Temple,TXT_STRIFE_MAP25,,,,ZÓNA 25: Katakomby: Zničený chrám,AREA 25: Katakomberne: Ruineret tempel,ZONE 25: Katakomben: Zerstörter Tempel,,AREO: 25: Katakombo: Ruiniga Templo,ÁREA 25: Catacumbas: Templo Arruinado,,ALUE 25: Katakombit: temppeliraunio,ZONE 25: Catacombes: Temple Ruiné,25. Terület: Katakombák: Romtemplom,AREA 25: Catacombe: Tempio in Rovina,エリア 25: 地下墓所:没落した寺院,구역 25: 고대 묘지: 무너진 사원,Zone 25: Catacomben: Vernietigde tempel,OMRÅDE 25: Katakombene: Ruinert tempel,Strefa 25: Katakumby: Zrujnowana Świątynia,Área 25: Catacumbas: Templo Arruinado,Área 25: Túmulos: Templo Arruinado,ZONA 25: Catacombe: Templu în ruine,МЕСТНОСТЬ 25: Катакомбы (руины храма),,OMRÅDE 25: Katakomber: Förfallet tempel,ALAN 25: Yeraltı Mezarları: Yıkık Tapınak +AREA 26: Proving Grounds,TXT_STRIFE_MAP26,,,,ZÓNA 26: Vojenský újezd,AREA 26: Prøvesteder,ZONE 26: Testgelände,,AREO 26: Provejo,ÁREA 26: Campo de Pruebas,,ALUE 26: Koetuspaikka,ZONE 26: Terrain d'entraînement,26. Terület: Próbatételek Földje,AREA 26: Banco di Prova,エリア 26: 試練場,구역 26: 증명의 전장,Zone 26: Testgebied,OMRÅDE 26: Prøveplassen,Strefa 26: Poligon Wojskowy,Área 26: Campo de Treinamento,Área 26: Campo de Treino,ZONA 26: Tabăra de instruire,МЕСТНОСТЬ 26: Испытательный полигон,,OMRÅDE 26: Provningsområden,ALAN 26: Kanıtlama Alanları +AREA 27: The Lab,TXT_STRIFE_MAP27,,,,ZÓNA 27: Laboratoř,AREA 27: Laboratoriet,ZONE 27: Das Labor,,AREO 27: La Labotorio,ÁREA 27: El Laboratorio,,ALUE 27: Laboratorio,ZONE 27: Laboratoire,27. Terület: A labor,AREA 27: Il Laboratorio,エリア 27: 研究所,구역 27: 연구소,Zone 27: Het laboratorium,OMRÅDE 27: Laboratoriet,Strefa 27: Laboratorium,Área 27: O Laboratório,,ZONA 27: Laboratorul,МЕСТНОСТЬ 27: Лаборатория,,OMRÅDE 27: Labbet,ALAN 27: Laboratuvar +AREA 28: Alien Ship,TXT_STRIFE_MAP28,,,,ZÓNA 28: Mimozemská loď,AREA 28: Fremmed skib,ZONE 28: Außerirdisches Schiff,,AREO 28: Alilanda Ŝipo,ÁREA 28: Nave Alienígena,,ALUE 28: Muukalaisalus,ZONE 28: Vaisseau Alien,28. Terület: Idegen űrhajó,AREA 28: Nave Aliena,エリア 28: エイリアンの船,구역 28: 외계 우주선,Zone 28: Buitenaards schip,OMRÅDE 28: Det fremmede skipet,Strefa 28: Statek Obcych,Área 28: Nave Alienígena,,ZONA 28: Nava extraterestră,МЕСТНОСТЬ 28: Корабль пришельцев,,OMRÅDE 28: Främmande skepp,ALAN 28: Uzaylı Gemisi +AREA 29: Entity's Lair,TXT_STRIFE_MAP29,,,,ZÓNA 29: Doupě Bytosti,AREA 29: Entitetsnesten,ZONE 29: Das Nest der Entität,,AREO 29: Nestego de Estulo,ÁREA 29: Escondite de la Entidad,,ALUE 29: Tosiolevan maja,ZONE 29: Demeure de L'Entité,29. Terület: A Teremtvény Búvóhelye,AREA 29: Tana dell'Entità,エリア 29: エンティティの隠れ家,구역 29: 엔티티의 소굴,Zone 29: Het nest van de entiteit,OMRÅDE 29: Enhetens hule,Strefa 29: Leże Bytu,Área 29: Covil da Entidade,,ZONA 29: Cuibul Entității,МЕСТНОСТЬ 29: Логово Сущности,,OMRÅDE 29: Väsendets lya,ALAN 29: Varlığın İni +AREA 30: Abandoned Front Base,TXT_STRIFE_MAP30,,,,ZÓNA 30: Opuštěná základna Fronty,AREA 30: Forladt frontbase,ZONE 30: Verlassene Basis der Front,,AREO 30: Forlasita Front-Bazo,ÁREA 30: Base Abandonada del Frente,,ALUE 30: Hylätty Rintaman tukikohta,ZONE 30: Base Abandonnée du Front,30. Terület: Elhagyatott Előbázis,AREA 30: Base del Fronte abbandonata,エリア 30: 放棄された基地,구역 30: 버려진 프론트 기지,Zone 30: Verlaten frontbasis,OMRÅDE 30: Forlatt frontbase,Strefa 30: Opuszczona Baza Frontu,Área 30: Base da Frente Abandonada,,ZONA 30: Baza abandonată a Frontului,МЕСТНОСТЬ 30: Заброшенная база сопротивления,,OMRÅDE 30: Övergiven frontbas,ALAN 30: Terk Edilmiş Ön Üs +AREA 31: Training Facility,TXT_STRIFE_MAP31,,,,ZÓNA 31: Výcvikové zařízení,AREA 31: Træningsanlæg,ZONE 31: Trainingseinrichtung,,AREO 31: Trejnejo,ÁREA 31: Zona de entrenamiento,,ALUE 31: Koulutuslaitos,ZONE 31: Complexe d'Entraînement,31. Terület: Kiképzőbázis,AREA 31: Struttura di Addestramento,エリア 31: 研修施設,구역 31: 훈련 시설,Zone 31: Trainingsfaciliteit,OMRÅDE 31: Treningsanlegg,Strefa 31: Centrum Szkoleniowe,Área 31: Instalação de Treinamento,,ZONA 31: Spațiul de antrenament,МЕСТНОСТЬ 31: Тренировочный корпус,,OMRÅDE 31: Utbildningsanläggning,ALAN 31: Eğitim Tesisi +AREA 1: Sanctuary,TXT_STRIFE_MAP32,,,,ZÓNA 1: Svatyně,AREA 1: Fristedet,ZONE 1: Heiligtum,,AREO 1: Sanktejo,ÁREA 1: Santuario,,ALUE 1: Pyhäkkö,ZONE 1: Sanctuaire,1. Terület: Szentély,AREA 1: Santuario,エリア 1: 聖域 ,구역 1: 성소,Zone 1: Heiligdom,OMRÅDE 1: Fristedet,Strefa 1: Sanktuarium,Área 1: Santuário,,ZONA 1: Sanctuar,МЕСТНОСТЬ 1: Святилище,,OMRÅDE 1: Fristad,ALAN 1: Sığınak +AREA 2: Town,TXT_STRIFE_MAP33,,,,ZÓNA 2: Město,AREA 2: By,ZONE 2: Stadt,,AREO 2: Urbeto,ÁREA 2: Pueblo,,ALUE 2: Kylä,ZONE 2: Ville,2. Terület: Város,AREA 2: Città,エリア 2: 町,구역 2: 마을,Zone 2: Stad,OMRÅDE 2: By,Strefa 2: Miasto,Área 2: Vila,,ZONA 2: Oraș,МЕСТНОСТЬ 2: Город,,OMRÅDE 2: Stad,ALAN 2: Şehir +AREA 3: Movement Base,TXT_STRIFE_MAP34,,,,ZÓNA 3: Rebelská základna,AREA 3: Front Basis,ZONE 3: Rebellenbasis,,AREO 3: Movad-Bazo,ÁREA 3: Base del Movimiento,,ALUE 3: Liikkeen tukikohta,ZONE 3: Base du Front,3. Terület: Mozgalmi Bázis,AREA 3: Base del Movimento,エリア 3: 移転基地,구역 3: 반군 기지,Zone 3: Front basis,OMRÅDE 3: Bevegelsesbase,Strefa 3: Baza Ruchu Oporu,Área 3: Base do Movimento,,ZONA 3: Baza rezistenței,МЕСТНОСТЬ 3: База сопротивления,,OMRÅDE 3: Förflyttningsbas,ALAN 3: Hareket Üssü +AREA 35: Factory: Production,TXT_STRIFE_MAP35,,,,ZÓNA 35: Továrna: Produkce,AREA 35: Fabrik: Produktion,ZONE 35: Fabrik: Produktion,,AREO 35: Fabrikejo: Produktejo,ÁREA 35: Fábrica: Producción,,ALUE 35: Tehdas: tuotanto,ZONE 35: Usine: Production,35. Terület: Gyár: Termelés,AREA 35: Fabbrica: Produzione,エリア 35: 工場 : 生産ライン,구역 35: 공장: 제작실,Zone 35: Fabriek: Productie,OMRÅDE 35: Fabrikk: Produksjon,Strefa 35: Fabryka: Produkcja,Área 35: Fábrica: Produção,,ZONA 35: Fabrica: Producție,МЕСТНОСТЬ 35: Фабрика (производство),,OMRÅDE 35: Fabrik: Produktion,ALAN 35: Fabrika: Üretim +AREA 36: Castle Clash,TXT_STRIFE_MAP36,,,,ZÓNA 36: Střet na hradě,AREA 36: Slotskampe,ZONE 36: Burg-Konflikt,,AREO 36: Batalo ĉe Kastelo,ÁREA 36: Ataque al Castillo,,ALUE 36: Linnayhteenotto,ZONE 36: Bataille du Château,36: Terület: Vári ütközet,AREA 36: Collisione di Castello,エリア 36: キャッスルクラッシュ,구역 36: 성채간의 충돌,Zone 36: Kasteelconflict,OMRÅDE 36: Slottskampen,Strefa 36: Potyczka w Zamku,Área 36: Ataque ao Castelo,,ZONA 36: Bătălia castelului,МЕСТНОСТЬ 36: Битва в замке,,OMRÅDE 36: Slottet Clash,ALAN 36: Kale Çatışması +AREA 37: Killing Grounds,TXT_STRIFE_MAP37,,,,ZÓNA 37: Popravčí zahrady,AREA 37: Drabsområder,ZONE 37: Kampfgelände,,AREO 37: Tereno de Mortigado,ÁREA 37: Campo de Matanza,,ALUE 37: Tappotanner,ZONE 37: Zone de Chasse,37. Terület: Gyilkos Vidék,AREA 37: Campi di Uccisione,エリア 37: 殺害者の地,구역 37: 살육의 전장,Zone 37: Slagveld,OMRÅDE 37: Drapsplasser,Strefa 37: Śmiercionośny Grunt,Área 37: Campo de Matança,,ZONA 37: Teren de ucis,МЕСТНОСТЬ 37: Сектора обстрела,,OMRÅDE 37: Dödsmark,ALAN 37: Öldürme Alanları +AREA 38: Ordered Chaos,TXT_STRIFE_MAP38,,,,ZÓNA 38: Nařízený chaos,AREA 38: Ordnet kaos,ZONE 38: Geordnetes Chaos,,AREO 38: Orda Kaoso,ÁREA 38: Caos Ordenado,,ALUE 38: Järjestynyt kaaos,ZONE 38: Chaos Ordonné,38. Terület: Rendezett Káosz,AREA 38: Caos Ordinato,エリア 38: カオスの秩序,구역 38: 정돈된 혼란,Zone 38: Ordelijke chaos,OMRÅDE 38: Ordnet kaos,Strefa 38: Uporządkowany Chaos,Área 38: Caos Ordenado,,ZONA 38: Haos controlat,МЕСТНОСТЬ 38: Управляемый хаос,,OMRÅDE 38: Ordnat kaos,ALAN 38: Düzenli Kaos +,,Hexen,,,,,,,,,,,,,,,,,,,,,,,,, +Winnowing Hall,TXT_HEXEN_MAP01,,,,Sál prosetí,Separationshal,Trennungshalle,,Solenejo de Separado,Sala de los Vientos,,Viskaussali,Chambre de la Séparation,Huzatos Folyosó,Camera di separazione,選抜の間,바람 회관,Scheidingszaal,Vinnersalen,Hala Przesiewu,Sala de Separação,,Sala de Separare,Зал отсеивания,Предсобље просејавања,Hallen för avräkning,Ayrılma Salonu +Seven Portals,TXT_HEXEN_MAP02,,,,Sedmero portálů,Syv portaler,Sieben Portale,,Sep Portaloj,Siete Portales,,Seitsemän portaalia,Les Sept Portails,Hét Portál,I Sette Portali,漆之門,일곱 차원문,Zeven portalen,Syv portaler,Siedem Portali,Sete Portais,,Șapte Portaluri,Семь порталов,Седам портала,Sju portaler,Yedi Portal +Guardian of Ice,TXT_HEXEN_MAP03,,,,Strážce ledu,Vogter af is,Wächter des Eises,,Gardanto de Glacio,Guardián de Hielo,,Jään vartija,Gardien de Glace,A Jég Őre,Guardiano del Ghiaccio,氷の守護者,얼음의 수호자,Bewaker van ijs,Isens vokter,Strażnik Lodu,Guardião de Gelo,,Străjerul Gheții,Страж льда,Чувар леда,Isens väktare,Buz Muhafızı +Guardian of Fire,TXT_HEXEN_MAP04,,,,Strážce ohně,Vogter af ild,Wächter des Feuers,,Gardanto de Fajro,Guardián de Fuego,,Tulen vartija,Gardien de Feu,A Tűz Őre,Guardiano del Fuoco,炎の守護者,화염의 수호자,Bewaker van vuur,Ildens vokter,Strażnik Ognia,Guardião de Fogo,,Străjerul Focului,Страж огня,Чувар огња,Elds väktare,Ateşin Koruyucusu +Guardian of Steel,TXT_HEXEN_MAP05,,,,Strážce oceli,Vogter af stål,Wächter des Stahls,,Gardanto de Ŝtalo,Guardián de Acero,,Teräksen vartija,Gardien d'Acier,Az Acél Őre,Guardiano dell'Acciaio,鋼の守護者,강철의 수호자,Bewaker van staal,Stålets vokter,Strażnik Stali,Guardião de Aço,,Străjerul Oțelului,Страж стали,Чувар челика,Stålets väktare,Çelik Muhafız +Bright Crucible,TXT_HEXEN_MAP06,,,,Světlý očistec,Lys udfordring,Glänzende Feuerprobe,,Luma Krisolo,Crisol de Luz,,Kirkas tulikoe,Creuset Radiant,Fényes Ketrec,Crogiolo Luminoso,光の坩堝,빛나는 고난,Heldere beproeving,Lys utfordring,Tygiel Światła,Crisol de Luz,,Creuzet Luminos,Горнило света,Испит светла,Ljus utmaning,Parlak Pota +Shadow Wood,TXT_HEXEN_MAP13,,,,Temný hvozd,Skyggetræ,Schattenwald,,Ombro-Arbareto,Bosque de la Sombra,,Varjosalo,Forêt des Ombres,Árnyék Erdő,Foresta Oscura,陰影樹,그림자 숲,Schaduwbos,Skyggeskogen,Las Cieni,Floresta das Sombras,,Pădurea Umbrelor,Лес теней,Шума сенки,Skuggskog,Gölge Ahşap +Darkmere,TXT_HEXEN_MAP08,,,,Černý močál,,Düstersee,,Malluma Marĉo,Pantano,,Pikiräme,Marais Noir,Fekete Mocsár,Palude Nera,暗黒の地,흙빛호수,Sombermeer,,Mroczne Bagno,Pantâno Negro,,Mlaștinile Întunecate,Болотная топь,Мочварна земља,Mörkträsk,Koyu göl +Caves of Circe,TXT_HEXEN_MAP09,,,,Kirčiny jeskyně,Circes' grotter,Circes Höhle,,Kavernoj de Circe,Cuevas de Circe,,Circeluolat,Caves de Circé,Körök Barlangja,Grotte di Circe,キルケーの洞窟,키르케의 동굴,Grotten van Circe,Circes grotter,Jaskinie Kirke,Cavernas de Circe,,Peșterile lui Circe,Пещеры Цирцеи,Киркине пећине,Circes grottor,Kirke Mağaraları +Wastelands,TXT_HEXEN_MAP10,,,,Pustiny,Ødemarker,Ödland,,Senvivejo,Yermo,,Erämaat,Terres Ruinées,Senkiföldje,Terre in rovina,荒野,황무지,Woestenij,Ødemarken,Pustkowia,Terras Desoladas,,Tărâmurile Pustii,Пустоши,Пустоши,Ödemarken,Çorak Topraklar +Sacred Grove,TXT_HEXEN_MAP11,,,,Posvátný háj,Helliglund,Heiliger Hain,,Sankta Bosketo,Arboleda Sagrada,,Pyhä metsikkö,Bosquet Sacré,Szent Liget,Boschetto Sacro,神聖なる園,성스러운 수풀,Heilig bosje,Hellig lund,Święty Gaj,Bosque Sagrado,,Crângul Sacru,Священная роща,Свети шумарак,Heliga lunden,Kutsal Koru +Hypostyle,TXT_HEXEN_MAP12,,,,Hypostyl,,Säulenhalle,,Kolonejo,Hipóstila,,Hypostyyli,,Oszlopterem,Ipostilo,多柱の間,다주실,Zuilenhal,,Hypostyl,Hipostilo,,Hipostil,Гипостильный зал,Хипостил,Hypostil,Hipostil +Heresiarch's Seminary,TXT_HEXEN_MAP27,,,,Arcikacířův alumnát,Heresiarkens seminarium,Seminar des Erzketzers,,Seminario de Ĉefherezulo,Seminario del Heresiarca,,Kerettiarkin seminaari,Séminaire de l'Hérésiarche,A Főeretnek Neveldéje,Seminario dell'Heresiarch,ヘレシアークの神学舎,헤러시아크의 신학교,Seminarie van ketterij,Heresiarkens seminar,Seminarium Herezjarchy,Seminário do Heresiarca,,Seminarul Ereziarhului,Семинария Ересиарха,Јересијархов семинар,Heresiarkens seminarium,Heresiark'ın Ruhban Okulu +Dragon Chapel,TXT_HEXEN_MAP28,,,,Dračí kaple,Dragekapel,Drachenkapelle,,Drakkapelo,Capilla Dragón,,Lohikäärmekappeli,Chapelle du Dragon,Sárkány Szentély,Cappella del Drago,ドラゴンの庵寺,드래곤 예배실,Drakenkapel,Dragekapell,Kaplica Smoka,Capela do Dragão,,Capela dragonilor,Часовня дракона,Капела змајева,Drakens kapell,Ejderha Şapeli +Griffin Chapel,TXT_HEXEN_MAP30,,,,Gryfova kaple,Griffinkapel,Greifenkapelle,,Grifkapelo,Capilla Grifo,,Aarnikotkakappeli,Chapelle du Grifon,Griff Szentély,Cappella del Grifone,グリフィンの庵寺,그리핀 예배실,Griffioenenkapel,Griffon kapell,Kaplica Gryfa,Capela do Grifo,,Capela grifonilor,Часовня грифона,Капела грифонова,Griffins kapell,Griffin Şapeli +Deathwind Chapel,TXT_HEXEN_MAP31,,,,Kaple mrakosmrtě,Dødens vind kapel,Todeswindkapelle,,Mortvento-Kapelo,Capilla Viento de Muerte,,Kuolontuulikappeli,Chapelle du Vent Tueur,Halál Szentély,Cappella del Vento Assassino,デスウィンドの庵寺,죽음바람 예배실,Dodenwind kapel,Dødens vind kapell,Kaplica Wiatru Śmierci,Capela do Vento da Morte,,Capela suflului morții,Часовня ветра смерти,Капела ветра смрти,Dödsblåsans kapell,Ölüm Rüzgarı Şapeli +Orchard of Lamentations,TXT_HEXEN_MAP32,,,,Sad nářků,Klagesangens frugthave,Garten der Wehklagen,,Horto de Lamentoj,Huerto de los Lamentos,,Valitusvirtten tarha,Verger des Lamentations,Siránkozás Kertje,Frutteto delle Lamentazioni,哀悼茂る園,통탄의 과수원,Boomgaard van klaagliederen,Klagesangens hage,Płaczący Sad,Pomar das Lamentações,,Livada amărăciunii,Сады плача,Воћњак плача,Klagovisornas trädgård,Ağıtlar Bahçesi +Silent Refectory,TXT_HEXEN_MAP33,,,,Tichý refektář,Stilhedens refektorium,Stilles Refektorium,,Silenta Manĝejo,Refectorio Silencioso,,Hiljainen ruokasali,Réfectoire Silencieux,Néma Refektórium,Refettorio silenzioso,寡黙なる食堂,침묵의 식당,Stil refectory,Stille refektorium,Cichy Refektarz,Refeitório Silencioso,,Refectoriul tăcerii,Безмолвная трапезная,Безгласна трпезарија,Tyst matsal,Sessiz Yemekhane +Wolf Chapel,TXT_HEXEN_MAP34,,,,Vlčí kaple,Ulvekapel,Wolfskapelle,,Lupkapelo,Capilla Lobo,,Susikappeli,Chapelle du Loup,Farkas Szentély,Cappella del Lupo,狼の庵寺,늑대 예배실,Wolvenkapel,Ulvens kapell,Kaplica Wilka,Capela do Lobo,,Capela lupilor,Часовня волка,Капела вучја,Vargkapellet,Kurt Şapeli +Forsaken Outpost,TXT_HEXEN_MAP21,,,,Opuštěné stanoviště,Forladt forpost,Verlassener Vorposten,,Forlasita Posteno,Puesto de Avanzada Abandonado,,Hylätty etuvartio,Base Abandonnée,Elhagyott Őrség,Avamposto Abbandonato,荒れ果てた前哨地,버려진 초소,Verwaarloosde buitenpost,Forlatt utpost,Opuszczony Posterunek,Posto Abandonado,,Avanpostul părăsit,Покинутая застава,Напуштена постаја,Försvunnen utpost,Unutulmuş Karakol +Castle of Grief,TXT_HEXEN_MAP22,,,,Hrad smutku,Sorgens slot,Leidensburg,,Kastelo de Funebro,Castillo del Pesar,,Surulinna,Château de la Souffrance,A Gyász Kastélya,Castello della Sofferenza,嘆きの城,비탄의 성,Kasteel van verdriet,Sorgens slott,Zamek Smutku,Castelo da Aflição,,Castelul întristării,Замок скорби,Замак жалости,Sorgens slott,Keder Kalesi +Gibbet,TXT_HEXEN_MAP23,,,,Šibenice,,Richtstätte,,Pendigilo,Horca,,Hirsipuu,Gibet,Akasztófa,Forca,晒し台,교수대,,Galgen,Szubienica,Forca,,Eșafodul,Виселица,Вешала,,İnfaz yeri +Effluvium,TXT_HEXEN_MAP24,,,,Výpary,,Effluvium,,Efluvo,Efluvio,,Katku,,A Bűz Börtöne,Effluvio,腐臭漂う残骸,악취,,,Odór,Eflúvio,,Efluviu,Зловонный сток,Воњави одвод,,Atık Su +Dungeons,TXT_HEXEN_MAP25,,,,Žalář,Fangehuller,Kerker,,Karceroj,Calabozos,,Tyrmät,Donjons,Kazamaták,I Dungeon,地下牢,지하감옥,Kerkers,Fangehull,Lochy,Masmorras,,Temnițe,Подземелья,Лагуми,Kerker,Zindanlar +Desolate Garden,TXT_HEXEN_MAP26,,,,Zpustošená zahrada,Ødelagt have,Verwildeter Garten,,Dezerta Ĝardeno,Jardín Desolado,,Autio puutarha,Jardin de la Désolation,Sivár Kert,Giardino Desolato,荒涼とした庭,황폐한 정원,Woeste tuin,Øde hage,Spustoszały Ogród,Jardim Desolado,,Grădina dezolantă,Заброшенный сад,Напуштени врт,Ödslig trädgård,Issız Bahçe +Necropolis,TXT_HEXEN_MAP35,,,,Nekropole,Nekropolis,Nekropole,,Nekropolo,Necrópolis,,Nekropoli,Nécropole,Nekropolisz,Necropoli,ネクロポリス,망자의 도시,,Nekropolis,Nekropolia,Necrópole,,Necropola,Некрополь,Некропола,Nekropolis,Nekropol +Zedek's Tomb,TXT_HEXEN_MAP36,,,,Zedekova hrobka,Zedeks grav,Zedeks Gruft,,Tombo de Zedek,Tumba de Zedek,,Sedekin hauta,Tombeau de Zedek,Zedek Sírja,Tomba di Zedek,ゼデクの墓,제닥의 무덤,Zedek's graf,Zedeks grav,Grobowiec Zedeka,Tumba de Zedek,Túmulo de Zedek,Mormântul lui Zedek,Гробница Зедека,Гробница Зедекова,Zedeks grav,Zedek'in Mezarı +Menelkir's Tomb,TXT_HEXEN_MAP37,,,,Menelkirova hrobka,Menelkirs grav,Menelkirs Gruft,,Tombo de Menelkir,Tumba de Menelkir,,Menelkirin hauta,Tombeau de Menelkir,Menelkir Sírja,Tomba di Menelkir,メネルキルの墓,메넬키어의 무덤,Menelkir's graf,Menelkirs grav,Grobowiec Menelkira,Tumba de Menelkir,Túmulo de Menelkir,Mormântul lui Menelkir,Гробница Менелкира,Гробница Менелкирова,Menelkirs grav,Menelkir'in Mezarı +Traductus' Tomb,TXT_HEXEN_MAP38,,,,Traduktova hrobka,Traductus' grav,Traductus' Gruft,,Tombo de Traductus,Tumba de Traductus,,Traduktuksen hauta,Tombeau de Traductus,Traductus Sírja,Tomba di Traductus,トダクティスの墓,트라닥투스의 무덤,Traductus' graf,Traductus' grav,Grobowiec Traduktusa,Tumba de Traductus,Túmulo de Traductus,Mormântul lui Traductus,Гробница Традактуса,Гробница Традуктусова,Traductus' grav,Traductus'un Mezarı +Vivarium,TXT_HEXEN_MAP39,,,,Vivárium,,,,Vivario,Vivario,,Vivaario,,Vivárium,Vivario,ビバリウム,사육장,,,Wiwarium,Viveiro,,Vivariu,Виварий,Виваријум,, Dark Crucible,TXT_HEXEN_MAP40,,,,Temný očistec,Mørk udfordring,Dunkle Feuerprobe,,Malluma Krisolo,Crisol de Oscuridad,,Pimeä tulikoe,Creuset Sombre,Sötét Ketrec,Crogiolo Buio,"暗黒の坩堝 -",어두운 고난,Donkere beproeving,Mørkets utfordring,Tygiel Mroku,Crisol das Trevas,,Creuzet Întunecat,Испытание тьмы,Испит таме,Karanlık Pota -,,Hexen Deathkings,,,,,,,,,,,,,,,,,,,,,,,, -Ruined Village,TXT_HEXDD_MAP41,,,,Zničená vesnice,Ødelagt landsby,Zerstörtes Dorf,,Ruiniga Vilaĝo,Pueblo en Ruinas,,Rauniokylä,Village en Ruines,Az Elpusztított Falu,Villagio in Rovine,廃村,파괴된 마을,Ruïneerd dorp,Den ødelagte landsbyen,Zrujnowana Wioska,Aldeia Destruída,Aldeia em Ruinas,Sat ruinat,Разрушенная деревня,Уништено село,Yıkık Köy -Blight,TXT_HEXDD_MAP42,,,,Pohroma,Skylle,Fäule,,Pesto,Decaimiento,,Turmelus,Peste,Penész,Peste,疫病,황폐화,Ziekte,Skade,Zaraza,Peste,,Cotropit,Упадок,Пошаст,Yanıklık -Sump,TXT_HEXDD_MAP43,,,,Žumpa,Sump,Sumpf,,Olekuvo,Pozo de Barro,,Likakaivo,Puisard,Tócsa,Pozzetto,汚水槽,웅덩이,Moeras,,Studzienka,Poço de Lama,,Joampă,Грязеотстойник,Сливник,Karter -Catacomb,TXT_HEXDD_MAP44,,,,Katakomby,Katakomb,Katakombe,,Katakombo,Catacumba,,Katakombi,Catacombe,Katakomba,Catacombe,カタコンベ,지하 묘실,Katacombe,Katakombe,Katakumba,Catacumba,,Catacombă,Катакомба,Катакомба,Katakomb -Badlands,TXT_HEXDD_MAP45,,,,Pustiny,Ødemarker,Ödland,,Badlandoj,Páramos,,Autiomaa,Terres Sauvages,Terméketlen Föld,Terre Selvagge,不毛地帯,불모지,Woestijn,Dårlige land,Pustkowia,Ermo,,Deșert,Бесплодные земли,Пустош,Çorak Topraklar -Brackenwood,TXT_HEXDD_MAP46,,,,Prales,,Moorwald,,Pteridejo,Brackenwood,,Saniaissalo,Forêt de Bracken,Páfrány Erdő,Foresta di Felce,ワラビの樹,고사리숲,Moorbos,,Las Paproci,Floresta de Samambaias,,Pădure de ferigi,Брекенвуд,Папрат,Bataklık orman -Pyre,TXT_HEXDD_MAP47,,,,Hranice,Bål,Scheiterhaufen,,Kremaciejo,Pira Funeraria,,Rovio,Brasier,Máglya,Pira,火葬薪,화장,Brandstapel,Bål,Ognisko,Pira,,Rug,Погребальный костёр,Ломача,Ateş Yakmak -Constable's Gate,TXT_HEXDD_MAP48,,,,Konstáblova brána,Vagtport,Wachtor,,Pordego de Ĝendarmo,Puerta del Alguacil,,Konstaapelin portti,Portail du Constable,Csendőr Kapu,Porta del Conestabile,城守達の門,무관장의 문,Constable's poort,Konstabelporten,Brama Posterunkowego,Portão do Condestável,,Poarta ofițerului,Комендантские врата,Чиновникова капија,Muhafız Kapısı -Treasury,TXT_HEXDD_MAP49,,,,Pokladnice,Skatkammer,Schatzkammer,,Trezorejo,Tesorería,,Rahasto,Trésorerie,Kincstár,Tesoreria,宝庫,국고,Schatkist,Skattkammeret,Skarbiec,Tesouraria,,Vistierie,Сокровищница,Трезор,Hazine Müsteşarlığı -Market Place,TXT_HEXDD_MAP50,,,,Tržnice,Markedspladsen,Marktplatz,,Foirejo,Plaza del Mercado,,Markkinat,Place du Marché,Piactér,Piazza del Mercato,市場,시장,Markt,Markedsplassen,Rynek,Feira,,Piață,Рыночная площадь,Пијаца,Pazar Yeri -Locus Requiescat,TXT_HEXDD_MAP51,,,,,,Locus Requiescat,,Locus Requiescat,Lugar de Descanso Eterno,,,Locus Requiescat,,,祈祷師の軌跡,명복의 장소,,,Locus Requiescat,,,,Место вечного упокоения,Место починка,Locus Requiescat -Ordeal,TXT_HEXDD_MAP52,,,,Utrpení,Forbandelse,Heimsuchung,,Provo Per Aflikto,Prueba,,Koettelemus,Supplice,Megpróbáltatás,Supplizio,試練,시죄의 시련,Orde,Prøvelsen,Męka,Suplício,,Supliciu,Испытание,Изазов,Çile -Armory,TXT_HEXDD_MAP53,,,Armoury,Zbrojnice,Våbenkammer,Waffenkammer,,Armilejo,Armería,,Asehuone,Amurerie,Fegyvertár,Armeria,武器庫,무기고,Wapenkamer,Våpenkammer,Zbrojownia,Arsenal,,Arsenal,Оружейная,Оружарница,Cephanelik -Nave,TXT_HEXDD_MAP54,,,,Chrámová loď,,Kirchenschiff,,Navo,La Nave,,Laiva,Nef,Templomhajó,Navata,身廊,본당,Naaf,Skipet,Nawa,,,Naos,Неф,Брод,Nef -Chantry,TXT_HEXDD_MAP55,,,,Modlitebna,Korskirke,Kantorei,,Kapelo,Capilla,,Kappeli,Chapelle,Gyászkápolna,Cappella,小礼拝堂,예배당,,Minnekapellet,Kaplica Wotywna,Capela,,Capelă,Часовня,Капела,Dua Odası -Abattoir,TXT_HEXDD_MAP56,,,,Jatka,Slagteriet,Schlachthaus,,Buĉejo,Matadero,,Teurastamo,Abbatoire,Vágóhíd,Mattatoio,屠殺場,도살장,Slachthuis,Slakteriet,Rzeźnia,Matadouro,,Abator,Бойня,Кланица,Mezbaha -Dark Watch,TXT_HEXDD_MAP57,,,,Tmavá hlídka,Mørk vagt,Dunkle Wache,,Ombra Gardisto,Guardia Oscura,,Pimeä vartio,Garde Noire,Éjjeli Őrség,Guardia Oscura,闇の刻計,어둠의 감시초소,Donkere horloge,Mørkets vakt,Ciemna Strażnica,Guarda Negra,,Gardian întunecat,Тёмный страж,Мрачни чувар,Karanlık Saat -Cloaca,TXT_HEXDD_MAP58,,,,Kloaka,,Kloake,,Kloako,Cloaca,,Kloaakki,Cloaque,Kloáka,,排泄腔,하수구,,,Kloaka,,,,Клоака,Клоака,Kloaka -Ice Hold,TXT_HEXDD_MAP59,,,,Ledová pevnost,Isrum,Eiskammer,,Fuorto el Glacio,Tierra de Hielo,,Jääsäilö,Fort de Glace,Jégtorony,Fortezza di Ghiaccio,氷結,빙고,Ijskamer,Ishall,Lodowa Twierdza,Fortaleza de Gelo,,Fort glaciar,Ледяная твердь,Ледена утврда,Buz Tutucu -Dark Citadel,TXT_HEXDD_MAP60,,,,Temná citadela,Mørkt citadel,Dunkle Festung,,Ombra Citadelo,Fortaleza Oscura,,Pimeä linnake,Citadelle Sombre,Sötét Torony,Cittadella Oscura,暗黒の城塞,어둠의 요새,Donkere citadel,Mørkets citadell,Mroczna Cytadela,Cidadela Negra,,Cetatea întunecată,Тёмная цитадель,Мрачна цитадела,Karanlık Kale -Transit,TXT_HEXDD_MAP33,,,,Převoz,,,,Vojo,Sala de Espera,,Läpikulku,Transit,Tranzit,Passaggio,変遷,통로,Doorvoer,Transitt,Tranzyt,Sala de Espera,,Tranzit,Переход,Прелаз,Transit -Over'n Under,TXT_HEXDD_MAP34,,,,Nad a Pod,,Drunter und Drüber,,Sub kaj Supre,Arriba y Abajo,,Yli ja ali,Sens Dessus Dessous,Fent és Lent,Sopra e Sotto,天と地,높낮이,Over'n under,Over og under,Nad I Pod,Sobre e Sob,,Mai sus și Mai jos,Выше и ниже,Изнад и испод,Üst ve Alt -Deathfog,TXT_HEXDD_MAP35,,,,Mha skonu,Dødens tåge,Todesnebel,,Mortnebulo,Niebla de Muerte,,Kuolonsumu,Brume Mortelle,Halálköd,Nebbia di Morte,死の霧,죽음의 안개,Dodenmist,Dødståke,Mgła Śmierci,Névoa da Morte,,Ceața morții,Туман смерти,Магла смрти,Ölüm Sisi -Castle of Pain,TXT_HEXDD_MAP36,,,,Hrad bolesti,Frygtens slot,Burg der Angst,,Kastelo de Doloro,Castillo del Dolor,,Tuskan linna,Château de la Douleur,Fájdalom Kastélya,Castello del Dolore,苦しみの城,고통의 성,Kasteel van pijn,Smertens slott,Zamek Bólu,Castelo da Dor,,Castelul durerii,Замок боли,Тврђава бола,Acı Kalesi -Sewer Pit,TXT_HEXDD_MAP37,,,,Odpadní jáma,Kloakgrube,Kanalgrube,,Fekaĵputo,Pozo de Residuos,,Viemärimonttu,Trou d'Egout,Kanális akna,Fossa della Fogna,地下溝穴,하수도,Rioolput,Kloakkgropen,Ściek,Fossa de Esgoto,,Groapa de scurgere,Сточная яма,Канализациона јама,Kanalizasyon Çukuru -The Rose,TXT_HEXDD_MAP38,,,,Růže,Rosen,Die Rose,,La Rozo,La Rosa,,Ruusu,La Rose,A Rózsa,La Rosa,薔薇,장밋빛,De roos,Rosen,Róża,A Rosa,,Roza,Роза,Ружа,Gül -,,Intermission texts,,,,,,,,,,,,,,,,,,,,,,,, +",어두운 고난,Donkere beproeving,Mørkets utfordring,Tygiel Mroku,Crisol das Trevas,,Creuzet Întunecat,Испытание тьмы,Испит таме,Mörk utmaning,Karanlık Pota +,,Hexen Deathkings,,,,,,,,,,,,,,,,,,,,,,,,, +Ruined Village,TXT_HEXDD_MAP41,,,,Zničená vesnice,Ødelagt landsby,Zerstörtes Dorf,,Ruiniga Vilaĝo,Pueblo en Ruinas,,Rauniokylä,Village en Ruines,Az Elpusztított Falu,Villagio in Rovine,廃村,파괴된 마을,Ruïneerd dorp,Den ødelagte landsbyen,Zrujnowana Wioska,Aldeia Destruída,Aldeia em Ruinas,Sat ruinat,Разрушенная деревня,Уништено село,Ruinerad by,Yıkık Köy +Blight,TXT_HEXDD_MAP42,,,,Pohroma,Skylle,Fäule,,Pesto,Decaimiento,,Turmelus,Peste,Penész,Peste,疫病,황폐화,Ziekte,Skade,Zaraza,Peste,,Cotropit,Упадок,Пошаст,Sköldpest,Yanıklık +Sump,TXT_HEXDD_MAP43,,,,Žumpa,Sump,Sumpf,,Olekuvo,Pozo de Barro,,Likakaivo,Puisard,Tócsa,Pozzetto,汚水槽,웅덩이,Moeras,,Studzienka,Poço de Lama,,Joampă,Грязеотстойник,Сливник,,Karter +Catacomb,TXT_HEXDD_MAP44,,,,Katakomby,Katakomb,Katakombe,,Katakombo,Catacumba,,Katakombi,Catacombe,Katakomba,Catacombe,カタコンベ,지하 묘실,Katacombe,Katakombe,Katakumba,Catacumba,,Catacombă,Катакомба,Катакомба,Katakomb,Katakomb +Badlands,TXT_HEXDD_MAP45,,,,Pustiny,Ødemarker,Ödland,,Badlandoj,Páramos,,Autiomaa,Terres Sauvages,Terméketlen Föld,Terre Selvagge,不毛地帯,불모지,Woestijn,Dårlige land,Pustkowia,Ermo,,Deșert,Бесплодные земли,Пустош,Dåliga marker,Çorak Topraklar +Brackenwood,TXT_HEXDD_MAP46,,,,Prales,,Moorwald,,Pteridejo,Brackenwood,,Saniaissalo,Forêt de Bracken,Páfrány Erdő,Foresta di Felce,ワラビの樹,고사리숲,Moorbos,,Las Paproci,Floresta de Samambaias,,Pădure de ferigi,Брекенвуд,Папрат,Brackenwood,Bataklık orman +Pyre,TXT_HEXDD_MAP47,,,,Hranice,Bål,Scheiterhaufen,,Kremaciejo,Pira Funeraria,,Rovio,Brasier,Máglya,Pira,火葬薪,화장,Brandstapel,Bål,Ognisko,Pira,,Rug,Погребальный костёр,Ломача,Bål,Ateş Yakmak +Constable's Gate,TXT_HEXDD_MAP48,,,,Konstáblova brána,Vagtport,Wachtor,,Pordego de Ĝendarmo,Puerta del Alguacil,,Konstaapelin portti,Portail du Constable,Csendőr Kapu,Porta del Conestabile,城守達の門,무관장의 문,Constable's poort,Konstabelporten,Brama Posterunkowego,Portão do Condestável,,Poarta ofițerului,Комендантские врата,Чиновникова капија,Konstapelns port,Muhafız Kapısı +Treasury,TXT_HEXDD_MAP49,,,,Pokladnice,Skatkammer,Schatzkammer,,Trezorejo,Tesorería,,Rahasto,Trésorerie,Kincstár,Tesoreria,宝庫,국고,Schatkist,Skattkammeret,Skarbiec,Tesouraria,,Vistierie,Сокровищница,Трезор,Skattkammaren,Hazine Müsteşarlığı +Market Place,TXT_HEXDD_MAP50,,,,Tržnice,Markedspladsen,Marktplatz,,Foirejo,Plaza del Mercado,,Markkinat,Place du Marché,Piactér,Piazza del Mercato,市場,시장,Markt,Markedsplassen,Rynek,Feira,,Piață,Рыночная площадь,Пијаца,Marknadsplats,Pazar Yeri +Locus Requiescat,TXT_HEXDD_MAP51,,,,,,Locus Requiescat,,Locus Requiescat,Lugar de Descanso Eterno,,,Locus Requiescat,,,祈祷師の軌跡,명복의 장소,,,Locus Requiescat,,,,Место вечного упокоения,Место починка,,Locus Requiescat +Ordeal,TXT_HEXDD_MAP52,,,,Utrpení,Forbandelse,Heimsuchung,,Provo Per Aflikto,Prueba,,Koettelemus,Supplice,Megpróbáltatás,Supplizio,試練,시죄의 시련,Orde,Prøvelsen,Męka,Suplício,,Supliciu,Испытание,Изазов,Rättegång,Çile +Armory,TXT_HEXDD_MAP53,,,Armoury,Zbrojnice,Våbenkammer,Waffenkammer,,Armilejo,Armería,,Asehuone,Amurerie,Fegyvertár,Armeria,武器庫,무기고,Wapenkamer,Våpenkammer,Zbrojownia,Arsenal,,Arsenal,Оружейная,Оружарница,Vapenförråd,Cephanelik +Nave,TXT_HEXDD_MAP54,,,,Chrámová loď,,Kirchenschiff,,Navo,La Nave,,Laiva,Nef,Templomhajó,Navata,身廊,본당,Naaf,Skipet,Nawa,,,Naos,Неф,Брод,,Nef +Chantry,TXT_HEXDD_MAP55,,,,Modlitebna,Korskirke,Kantorei,,Kapelo,Capilla,,Kappeli,Chapelle,Gyászkápolna,Cappella,小礼拝堂,예배당,,Minnekapellet,Kaplica Wotywna,Capela,,Capelă,Часовня,Капела,Kyrkogård,Dua Odası +Abattoir,TXT_HEXDD_MAP56,,,,Jatka,Slagteriet,Schlachthaus,,Buĉejo,Matadero,,Teurastamo,Abbatoire,Vágóhíd,Mattatoio,屠殺場,도살장,Slachthuis,Slakteriet,Rzeźnia,Matadouro,,Abator,Бойня,Кланица,Slakthus,Mezbaha +Dark Watch,TXT_HEXDD_MAP57,,,,Tmavá hlídka,Mørk vagt,Dunkle Wache,,Ombra Gardisto,Guardia Oscura,,Pimeä vartio,Garde Noire,Éjjeli Őrség,Guardia Oscura,闇の刻計,어둠의 감시초소,Donkere horloge,Mørkets vakt,Ciemna Strażnica,Guarda Negra,,Gardian întunecat,Тёмный страж,Мрачни чувар,Mörk vakt,Karanlık Saat +Cloaca,TXT_HEXDD_MAP58,,,,Kloaka,,Kloake,,Kloako,Cloaca,,Kloaakki,Cloaque,Kloáka,,排泄腔,하수구,,,Kloaka,,,,Клоака,Клоака,,Kloaka +Ice Hold,TXT_HEXDD_MAP59,,,,Ledová pevnost,Isrum,Eiskammer,,Fuorto el Glacio,Tierra de Hielo,,Jääsäilö,Fort de Glace,Jégtorony,Fortezza di Ghiaccio,氷結,빙고,Ijskamer,Ishall,Lodowa Twierdza,Fortaleza de Gelo,,Fort glaciar,Ледяная твердь,Ледена утврда,Ishållet,Buz Tutucu +Dark Citadel,TXT_HEXDD_MAP60,,,,Temná citadela,Mørkt citadel,Dunkle Festung,,Ombra Citadelo,Fortaleza Oscura,,Pimeä linnake,Citadelle Sombre,Sötét Torony,Cittadella Oscura,暗黒の城塞,어둠의 요새,Donkere citadel,Mørkets citadell,Mroczna Cytadela,Cidadela Negra,,Cetatea întunecată,Тёмная цитадель,Мрачна цитадела,Mörkt citadell,Karanlık Kale +Transit,TXT_HEXDD_MAP33,,,,Převoz,,,,Vojo,Sala de Espera,,Läpikulku,,Tranzit,Passaggio,変遷,통로,Doorvoer,Transitt,Tranzyt,Sala de Espera,,Tranzit,Переход,Прелаз,,Transit +Over'n Under,TXT_HEXDD_MAP34,,,,Nad a Pod,,Drunter und Drüber,,Sub kaj Supre,Arriba y Abajo,,Yli ja ali,Sens Dessus Dessous,Fent és Lent,Sopra e Sotto,天と地,높낮이,Over'n under,Over og under,Nad I Pod,Sobre e Sob,,Mai sus și Mai jos,Выше и ниже,Изнад и испод,Över'n Under,Üst ve Alt +Deathfog,TXT_HEXDD_MAP35,,,,Mha skonu,Dødens tåge,Todesnebel,,Mortnebulo,Niebla de Muerte,,Kuolonsumu,Brume Mortelle,Halálköd,Nebbia di Morte,死の霧,죽음의 안개,Dodenmist,Dødståke,Mgła Śmierci,Névoa da Morte,,Ceața morții,Туман смерти,Магла смрти,Dödsfog,Ölüm Sisi +Castle of Pain,TXT_HEXDD_MAP36,,,,Hrad bolesti,Frygtens slot,Burg der Angst,,Kastelo de Doloro,Castillo del Dolor,,Tuskan linna,Château de la Douleur,Fájdalom Kastélya,Castello del Dolore,苦しみの城,고통의 성,Kasteel van pijn,Smertens slott,Zamek Bólu,Castelo da Dor,,Castelul durerii,Замок боли,Тврђава бола,Slottet av smärta,Acı Kalesi +Sewer Pit,TXT_HEXDD_MAP37,,,,Odpadní jáma,Kloakgrube,Kanalgrube,,Fekaĵputo,Pozo de Residuos,,Viemärimonttu,Trou d'Egout,Kanális akna,Fossa della Fogna,地下溝穴,하수도,Rioolput,Kloakkgropen,Ściek,Fossa de Esgoto,,Groapa de scurgere,Сточная яма,Канализациона јама,Avloppsgrop,Kanalizasyon Çukuru +The Rose,TXT_HEXDD_MAP38,,,,Růže,Rosen,Die Rose,,La Rozo,La Rosa,,Ruusu,La Rose,A Rózsa,La Rosa,薔薇,장밋빛,De roos,Rosen,Róża,A Rosa,,Roza,Роза,Ружа,Rosen,Gül +,,Intermission texts,,,,,,,,,,,,,,,,,,,,,,,,, "Once you beat the big badasses and clean out the moon base you're supposed to win, aren't you? Aren't you? Where's @@ -590,7 +590,23 @@ Iadului” și continuarea sa nemaipomenită, Да бисте наставили искуство DOOM-а, играјте Обале пакла и његов невероватни наставак, Инферно! -","Büyük belalıları yendikten ve ay +","När du har besegrat de stora +skurkarna och rensat månbasen +är det meningen att du ska vinna, +eller hur? Eller hur? Var är din feta +belöning och din biljett hem? Vad +i helvete är det här? Det är inte +meningen att det ska sluta så här! + +Det stinker som ruttet kött, men ser +ut som den förlorade Deimosbasen. +Det ser ut som om du är fast på +helvetets stränder. +Den enda vägen ut är genom. + +För att fortsätta DOOM-upplevelsen +kan du spela Helvetets stränder och +dess fantastiska uppföljare Inferno!","Büyük belalıları yendikten ve ay üssünü temizledikten sonra Kazanmak için, değil mi? Değil misin? Nerede? büyük ödülün @@ -895,7 +911,23 @@ DOOM — «Инферно».","Успели сте! Грозни сајбер-д пакла. Сада, остатак је на последњем поглављу -DOOM! -- Инферно.","Başardınız! İğrenç siber Kayıp +DOOM! -- Инферно.","Du har gjort det! Den avskyvärda +cyberdemonherren som styrde den +förlorade Deimos månbasen har +dödats och du är triumferande! Men ... +var är du? Du klättrar till månens +kant och tittar ner för att se de + hemska sanningen. + +Deimos svävar över själva helvetet! +Du har aldrig hört talas om någon +som har lyckats fly från helvetet, men +du kommer att få de jävlarna att ångra +att de någonsin hört talas om dig! +Snabbt stiger du ner till helvetets yta. + +Nu är det dags för det sista +kapitlet i DOOM! -- Inferno.","Başardınız! İğrenç siber Kayıp Deimos'u yöneten iblis lordu ay üssü öldürüldü ve sen muzafferdir! Ama ... nerede Sen mi? Kenarına @@ -1229,7 +1261,23 @@ odată ce ai trecut prin acea ușă ...","Омерзительной демон док сте се борили против зла. Добро је што ниједно створење пакла не може проћи кроз та врата -с вама...","Ay üslerinin istilasını planlayan ve bu kadar çok ölüme neden olan iğrenç örümcek iblisin kıçı tüm zamanlar için tekmelendi. +с вама...","Den avskyvärda spindeldemon som +ledde invasionen av månbaserna och +orsakade så mycket död har fått +stryk för all framtid. + +En dold dörr öppnas och du går in. +Du har visat dig vara för tuff för att +helvetet skulle kunna hålla dig kvar, +och nu spelar helvetet äntligen rättvist - +för du kommer ut genom dörren och +ser jordens gröna fält! Äntligen hemma. + +Du undrar vad som har hänt på jorden +medan du har kämpat mot ondskan +som släppts lös. Det är bra att inga +demoner kunde ha kommit in genom +dörren med dig ...","Ay üslerinin istilasını planlayan ve bu kadar çok ölüme neden olan iğrenç örümcek iblisin kıçı tüm zamanlar için tekmelendi. Gizli bir kapı açılıyor ve içeri giriyorsunuz. Cehennem'in zapt edemeyeceği kadar güçlü olduğunu kanıtladın ve şimdi Cehennem nihayet adil davranıyor - çünkü kapıdan çıktığında Dünya'nın yeşil tarlalarını görüyorsun! @@ -1548,7 +1596,23 @@ Următoarea oprire, Iadul pe Pământ!","Скорее всего паучиха- док се хорда демона креће међу нашим градовима. -Следећа станица: пакао на земљи!","Örümcek beyni, siz cehennemden gelen o korkunç canavarla yüzleşmeden önce cehennem lejyonlarını göndermiş olmalı. Ama sen öne çıktın. ve ebedi laneti getirdi ve gerçek bir kahraman gibi sürünün üzerine bu kadar şeytani bir şeyle yüzleşmek. +Следећа станица: пакао на земљи!","""Spindelhjärnan måste ha skickat ut +sina legioner av helvetesgudar före din +slutliga konfrontation med det +fruktansvärda odjuret från helvetet, men +du klev fram och förde fram evig +fördömelse och lidande över horden, +som en sann hjälte skulle göra inför +något så ondskefullt. + +Dessutom skulle någon få betala för vad +som hände Daisy, din husdjurskanin. + +Men nu ser du framför dig mer potentiell +smärta och död när en nation av demoner +löper amok bland våra städer. + +Nästa stopp: Helvetet på jorden!","Örümcek beyni, siz cehennemden gelen o korkunç canavarla yüzleşmeden önce cehennem lejyonlarını göndermiş olmalı. Ama sen öne çıktın. ve ebedi laneti getirdi ve gerçek bir kahraman gibi sürünün üzerine bu kadar şeytani bir şeyle yüzleşmek. Ayrıca, birileri bunun bedelini ödeyecekti. evcil tavşanınız Daisy'nin başına geldi. @@ -1765,7 +1829,18 @@ de control care ține captivă populația Pământului.","Вы проникли кроз њега, моћи ћете да се пробијете до самог уклетог срца старбазе и да нађете контролишyће дугме које држи све -становништво земље таоце.","İstila edilmiş yıldız üssünün +становништво земље таоце.","""Du har gått djupt in i den infekterade +stjärnhamnen. Men något är fel. +Monstren har fört med sig sin egen +verklighet, och stjärnhamnens teknik +undergrävs av deras närvaro. + +Framför dig ser du en utpost av helvetet, +en befäst zon. Om du kan ta dig förbi +den kan du tränga in i stjärnbasens +hemsökta hjärta och hitta den +kontrollbrytare som håller jordens +befolkning som gisslan.","İstila edilmiş yıldız üssünün derinliklerine girdiniz. Ama yanlış giden bir şeyler var. Canavarlar kendi gerçekliklerini de @@ -2141,7 +2216,25 @@ la luptă.","Вы победили! Благодаря вашему триумф ванземаљска база се налази у вашем родном граду, недалеко од старпорта.“ Полако и безвољно устајете да би се вратили -у окршај.","Siz kazandınız! Zaferiniz sayesinde +у окршај.","Du har vunnit! Er seger har gjort det +möjligt för mänskligheten att eva- +kuera jorden och fly från mardrömmen. +Nu är du den enda människan som +finns kvar på planeten. Kannibalmutationer, +köttätande utomjordingar och onda andar +är dina enda grannar. Du sitter tillbaka och +väntar på döden, nöjd med att du har +räddat din art. + +Men så strålar Earth Control ner ett +meddelande från rymden: ""Sensorerna +har lokaliserat källan till den utomjordiska +invasionen."" Om du går dit kan du kanske +blockera deras inträde. Den utomjordiska +basen ligger i hjärtat av din egen +hemstad, inte långt från stjärnhamnen."" +Långsamt och smärtsamt reser du +dig upp och återvänder till striden.","Siz kazandınız! Zaferiniz sayesinde İnsanlık dünyayı boşaltıp kaçacak kabus. Şimdi tek sen varsın Gezegende insan kalmadı. @@ -2331,7 +2424,16 @@ să o descoperi?","Вы стоите в осквернённом сердце г Мора постојати начин да се пролаз уништи са друге стране. Шта вас брига ако -морате проћи пакао да би сте га нашли?","Şehrin yozlaşmış kalbindesiniz, +морате проћи пакао да би сте га нашли?","""Du befinner dig i stadens korrupta hjärta, +omgiven av dina fienders lik. Du ser inget +sätt att förstöra varelsernas ingång på +den här sidan, så du biter ihop tänderna +och kastar dig igenom den. + +Det måste finnas ett sätt att stänga den +på andra sidan. Vad bryr du dig om du +måste gå igenom helvetet för att +komma dit?","Şehrin yozlaşmış kalbindesiniz, etrafınız düşmanlarınızın cesetleriyle çevrili. Bu taraftaki geçidi yok etmenin bir yolunu @@ -2627,7 +2729,21 @@ siguranță mai distractivă decât a fost ruinarea lui.","Леденящий д зној са чела, почињете дугачак пут кyћи. Поновна изградња земље би требала бити забавнија од уништења исте. -","Gördüğünüz en büyük iblisin +","""Den största demonen som du någonsin +har sett faller ihop framför dig efter att +du har pumpat in dina raketer i hans +utsatta hjärna. Monstret skrumpnar +ihop och dör, dess slående lemmar +ödelägger otaliga mil av helvetets yta. + +Du har gjort det. Invasionen är över. +Jorden är räddad. Helvetet är ett vrak. +Du undrar vart de onda människorna +tar vägen när de dör, nu. Du torkar +svetten från pannan och börjar den +långa vandringen hemåt. Att +återuppbygga jorden borde vara mycket +roligare än vad det var att förstöra den.","Gördüğünüz en büyük iblisin korkunç görüntüsü, roketlerinizi açıktaki beynine pompaladıktan sonra önünüzde parçalanıyor. @@ -2723,7 +2839,11 @@ acestuit colț de infern.","Поздравляем, вы нашли секрет в этом уголке преисподней.","Честитамо, пронашли сте скривени ниво! Изгледа да је био изграђен од стране људи, а не монструма. Размишљате ко -ће бити становници овог дела пакла.","Tebrikler. Gizli seviyeyi buldunuz! +ће бити становници овог дела пакла.","Grattis, du har hittat den hemliga nivån! +Det ser ut som om den har byggts av +människor, snarare än demoner. Du +undrar vilka de intagna i detta hörn +av helvetet kommer att vara.","Tebrikler. Gizli seviyeyi buldunuz! Şeytanlar değil de İnsanlar tarafından inşa edilmiş gibi görünüyor. Cehennemin bu @@ -2769,7 +2889,9 @@ să termini rapid cu el!","Поздравляем, вы нашли сверхс уровень! И здесь вас вновь ждут кин-о и немцы.","Честитамо, пронашли сте супер скривени ниво! -Боље да пролетите кроз ово!","Tebrikler, süper gizli seviyeyi +Боље да пролетите кроз ово!","Grattis, du har hittat den superhemliga +nivån! Det är bäst att du tar dig igenom +den här!","Tebrikler, süper gizli seviyeyi buldunuz! Bunu geçsen iyi olur!" "You gloat over the steaming carcass of the Guardian. With its death, you've wrested @@ -3012,7 +3134,18 @@ trăiești, de asemenea.","Вы злорадствуете над дымящим муке протраћене. Наставите да се крећете, наставите да се борите, наставите да убијате. -И да, наставите и да живите.","Muhafız'ın dumanı tüten leşi +И да, наставите и да живите.","Ni gläds åt Väktarens rykande kadaver. +Med dess död har du vridit Acceleratorn +ur helvetets stinkande klor. Du slappnar +av och tittar runt i rummet. Fan! Det +skulle finnas åtminstone en fungerande +prototyp, men du kan inte se den. +Demonerna måste ha tagit den. + + Du måste hitta prototypen, annars har +all din kamp varit bortkastad. Fortsätt +röra på dig, fortsätt kämpa, fortsätt +döda. Åh ja, fortsätt att leva också.","Muhafız'ın dumanı tüten leşi üzerinde kına yakıyorsunuz. Onun ölümüyle Hızlandırıcı'yı Cehennem'in kokuşmuş @@ -3138,7 +3271,13 @@ Te pricepi la chestii de genul.","Даже смертоносный лабири прототип акцелератора који ће ускоро ефикасно бити деактивиран заувек. -Добри сте у таквим стварима.","Ölümcül Baş Aşağılık labirenti bile +Добри сте у таквим стварима.","Inte ens den dödliga Ärkevild-labyrinten +kunde stoppa dig, och du har nått fram +till prototypen av Acceleratorn som +snart är effektivt och permanent +avaktiverad. + +Du är bra på den typen av saker.","Ölümcül Baş Aşağılık labirenti bile seni durduramaz, ve sen prototip Hızlandırıcı yakında etkili ve kalıcı olarak devre dışı bırakıldı. @@ -3320,7 +3459,17 @@ pregătești să-i dai o mamă de bătaie ticălosului.","С боем и гро Са злобним изразом проверавате опрему, и припремате се да дате том кучкином сину мало пакла од -сопственог стварања!","İblis kovanının kalbine giden yolda +сопственог стварања!","Du har slagit och slagit dig in i +djävulskyrkans hjärta. Dags för ett +uppdrag att söka och förstöra, +riktat mot Portvakten, vars avkommor +som sprider sig till jorden. Ja, han är +ond. Men du vet vem som är värre! + +Med ett illvilligt flin kontrollerar du din +utrustning och gör dig redo att ge +jäveln ett litet helvete som du själv +har skapat!","İblis kovanının kalbine giden yolda savaştınız. İğrenç köleleri Dünya'yı istila eden Kapı Bekçisi'ni hedef alan bir Arama ve Yok Etme @@ -3537,7 +3686,19 @@ pentru ultima dată ...","От зловещего лика Привратник Не заборавите да кажете својим унучади да вам ставе ракетни бацач у ковчег. Ако одете у пакао када умрете, треба ће вам -за последње чишћење...","Kapı Bekçisi'nin şeytani yüzü her +за последње чишћење...","Portvaktens onda ansikte är utspridd +överallt. När dess söndertrasade lik +kollapsar bildas en inverterad port +som suger ner skärvorna av den sista +prototypen av acceleratorn, för att inte +nämna de få återstående demonerna. +Du är klar. Helvetet har återgått till att +slå på dåliga döda människor i stället +för goda levande. Kom ihåg att be dina +barnbarn att lägga en raketkastare i din +kista. Om du kommer till helvetet när +du dör kommer du att behöva den +för att göra en sista städning ...","Kapı Bekçisi'nin şeytani yüzü her yerde. Parçalanmış cesedi gibi çöker, ters bir geçit oluşur ve son parçalarını emer prototip @@ -3629,7 +3790,11 @@ soldați marini maeștri.","Вы нашли второй по сложности који имамо. Надамо се да сте сачували игру ниво или два назад. Ако нисте, припремите се да умрете пуно пута. -Само за маестро маринце.","Elimizdeki en zor ikinci seviyeyi buldun. +Само за маестро маринце.","Du har hittat den näst svåraste nivån +vi har. Hoppas att du har ett sparat +spel en nivå eller två tidigare. Om inte, +var beredd på att dö i mängder. +Endast för master marines.","Elimizdeki en zor ikinci seviyeyi buldun. Umarım bir ya da iki seviye öncesine ait kayıtlı bir oyununuz vardır. Eğer yoksa, bolca ölmeye hazır olun. @@ -3689,7 +3854,10 @@ Nimeni nu scapă viu.","Вы наверняка гадали, каков же с приготовили? Ну, теперь вы знаете. Никто не уйдёт живым.","Гладимо се да сте се питали који је НАЈТЕЖИ ниво који смо спремили за -вас? Сада знате. Нико не излази жив.","Eminim elimizdeki en zor seviyenin +вас? Сада знате. Нико не излази жив.","Du undrade säkert vad som var den +svåraste nivån vi hade redo för dig? +Nu vet du det. +Ingen kommer ut levande.","Eminim elimizdeki en zor seviyenin ne olduğunu merak etmişsinizdir. Artık biliyorsunuz. Kimse canlı çıkamayacak." @@ -3885,7 +4053,18 @@ niște artilerie de război pe undeva.","Вам удалось вырватьс најежден мртвим хорорима који једва чекају да уроне зубе у вама. Са срећом, комплекс идаље има неко оружје које -лежи унаоколо.","İstilaya uğradığın yerden savaşarak +лежи унаоколо.","Du har kämpat dig ut ur de infekterade +experimentlaboratorierna. Det verkar +som om UAC återigen har ställt till det. +Med sin höga omsättning måste det +vara svårt för stackars UAC att köpa +en företagsförsäkring nuförtiden... + +Framför oss ligger militärkomplexet, +som nu kryllar av sjuka skräckinjagare +som är heta på att sätta tänderna i dig. +Med lite tur har komplexet fortfarande +lite krigsmateriel som ligger kvar.","İstilaya uğradığın yerden savaşarak çıktın. deneysel laboratuarlar. Görünüşe göre UAC bir kez daha yuttu. Onların yüksek ciro, yoksullar @@ -4063,7 +4242,17 @@ N-ai de gând să cazi la pământ prea ușor.","Впереди вы слыши спакована две хиљада манијака у једног побеснолог убицу. -Не планирате да паднете тако лако.","İleride ağır makinelerin gıcırtılarını +Не планирате да паднете тако лако.","Du hör slipandet av tunga maskiner i +huvudet. Du hoppas verkligen att de +inte stampar fram nya helvetesdjur, +men du är redo att slå ut en hel +hjord om du måste. +De kanske planerar en blodfest, men +du känner dig ungefär lika elak som +två tusen galningar packade i en +enda galen mördare. + +Du planerar inte att gå ner lätt.","İleride ağır makinelerin gıcırtılarını duyuyorsunuz. Yeni iblisler üretmediklerini umuyorsunuz ama gerekirse bütün bir sürüyü ortadan @@ -4227,7 +4416,16 @@ Timpul să notezi niște nume.","Открывшийся вашему взору Што више зиљите у њега, то више сте љути. Подижући своју пишку, зао кез се оформио на вашем лицу. -Време је за убијање.","İleride açılan manzara gerçekten +Време је за убијање.","Utsikten som öppnar sig framför oss +ser jävligt bekant ut. Den luktar också +bekant - som stekt avföring. Du +gillade inte det här stället förut, och +du planerar inte att gilla det nu. Ju +mer du grubblar på det, desto +argare blir du. +Du lyfter din pistol och får ett +ondskefullt flin i ansiktet. +Dags att ta några namn.","İleride açılan manzara gerçekten çok tanıdık geliyor. Kokusu da tanıdık, kızarmış dışkı gibi. Bundan hoşlanmayacağın kesin. Düşündükçe @@ -4428,7 +4626,18 @@ de demoni.","Внезапно всё умолкает, с одного края Нешто тутњи у даљини. Плава светлост почиње да светли унутар -уништене лобање избацивача демона.","Birdenbire, bir ufuktan diğerine her şey +уништене лобање избацивача демона.","Plötsligt är allt tyst, från den ena +horisonten till den andra. Helvetets +plågsamma eko bleknar bort, +mardrömshimlen blir blå, högarna av +monsterkadaver börjar avdunsta +tillsammans med den onda stanken +som fyllde luften. Jösses, du kanske +har gjort det. Har du verkligen vunnit? + +Något mullrar i fjärran. +Ett blått ljus börjar glöda inuti +demonspridarens förstörda skalle.","Birdenbire, bir ufuktan diğerine her şey sessizleşir. Cehennemin acı veren yankısı kaybolur. Kabus gökyüzü maviye döner. Canavar ceset yığınları, @@ -4528,7 +4737,13 @@ fi cel mai bine să lași zeii adormiți să zacă...","Ну что теперь овде било не може бити горе од убичајеног. Или може? Или је можда најбоље да се допусти да успавани -богови леже...","Şimdi ne oldu? Tamamen farklı +богови леже...","Vad händer nu? +Det ser helt annorlunda ut. +Ungefär som King Tut's lägenhet. +Det som finns här kan inte vara +värre än vanligt. Eller hur? +Eller så är det kanske bäst att låta +sovande gudar ligga...","Şimdi ne oldu? Tamamen farklı görünüyor. Kral Tut'un evi gibi. Burada her ne varsa normalden daha kötü olamaz. Değil mi? @@ -4715,7 +4930,18 @@ grei ai pantofilor de fier ai ciberdemonului.","Пора устроить отп зградама, и вероватно нема демона. Корачате ван својег транспорта, и чујете -удар челичног копита сајбердемона.","Tatil zamanı. Cehennemin +удар челичног копита сајбердемона.","Dags för semester. Du har sprängt +helvetets inälvor och du är redo för +en paus. Du mumlar för dig själv, +Kanske någon annan kan spöa +helvetet nästa gång. Framför dig +ligger en lugn stad, med fridfullt +rinnande vatten, pittoreska byggnader +och förmodligen inga Hellspawn. + +När du kliver av transporten hör du +stampandet av en cyberdemons +järnsko.","Tatil zamanı. Cehennemin bağırsaklarını patlattınız ve bir mola için hazırsınız. Belki bir dahaki sefere başka biri Cehennem'in kıçını @@ -5076,7 +5302,26 @@ Călătoria s-a încheiat.","Очередная заварушка намети посмртни јаук грогори из збрке од лице са којем сте га вам оставили. -Ова атракција је затворена.","En sevdiğin tatil yerinde yine sorun +Ова атракција је затворена.","""Det var återigen oroligt på din +favoritsemesterplats... Helvetet. +Någon Cyberdemon-punk trodde att +han kunde förvandla helvetet till en +personlig nöjespark och göra +jorden till biljettkassan. + +Tja, den där halvrobot-freakshowen +visste inte vem som skulle komma till +tivoli. Det finns inget bättre än en +skjutbana full av helvetesgödsel +för att få blodet att pumpa... + +Nu ekar väggarna i demonens labyrint +med ljudet av hans metalliska lemmar +som slår i golvet. Hans dödsstön gurglar +ut genom den röra du lämnade av hans +ansikte. + +Den här föreställningen är stängt.","En sevdiğin tatil yerinde yine sorun çıkıyordu... Cehennem'de. Siber iblisin teki Cehennem'i kişisel bir eğlence parkına dönüştürebileceğini ve @@ -5346,7 +5591,7 @@ outro lado. Claro que isso significa que você pode ficar pres@[ao_ptb] num lugar nada amigável, mas ninguém jamais disse que ser herége era fácil.",,"Odată cu distrugerea Cadavrelor de Fier și ai -minionilor lor, ultimii nemorți dispar din acest +minionilor, ultimii nemorți dispar din acest plan al existenței. Aceste creaturi trebuie să fii venit de undeva, și ai @@ -5385,7 +5630,24 @@ fii un eretic!","С уничтожением железных личей друге стране. Наравно то значи да ћете можда заглавити у непријатељском свету, али нико није реко да је лако бити -јеретик.","Demir cesetlerin ve yardakçılarının +јеретик.","I och med förintelsen av järnlicherna +och deras hantlangare har de sista +odöda försvunnit från det här +existensplanet. + +Dessa varelser måste dock ha +kommit någonstans ifrån, och du har +en lömsk misstanke om att den eldiga +portalen i helvetets gap öppnar sig på +deras hemdimension. + +För att se till att inte fler odöda (eller +ännu värre saker) kommer igenom +måste du försegla Helvetets gap +från andra sidan. Naturligtvis innebär +detta att du kan fastna i en mycket +ovänlig värld, men ingen har någonsin +sagt att det är lätt att vara kättare!","Demir cesetlerin ve yardakçılarının yok edilmesiyle, son yaşayan ölüler de bu âlemden uzaklaştırılmış oldu. @@ -5676,7 +5938,7 @@ crudă că au fost distruși. Poarta care era păzită de ei e acum deschisă, dezvăluind ceea ce tu sperai să fie drumul spre casă. Dar o dată ce pășești prin ea, râset batjocoritor -îți sună în urechi. +îți răsună în urechi. Să fii fost o altă forță în spatele maulotaurilor? Să fie oare creaturi și mai oribile dincolo de acest portal? @@ -5710,7 +5972,25 @@ siguranță nu e un semn bun...","Могучие избитавры поверж минотауре? Да ли су још ужасавајуће ствари кроз ову капију? Замах кристалне куполе где би требало да буде небо -сигурно није добар знак.","Kudretli maulotorlar kanıtladı seninle +сигурно није добар знак.","De mäktiga maulotaurerna har visat +sig inte vara någon match för er, och +när deras ångande lik glider ner på +marken känner du en känsla av grym +tillfredsställelse över att de har +förintats. + +Portarna som de vaktade har öppnats +och avslöjat vad du hoppas är vägen +hem. Men när du kliver igenom ringer +ett hånfullt skratt i dina öron. + +Var det någon annan kraft som +kontrollerade maulotaurerna? Kan det +finnas ännu mer hemska varelser +bakom den här porten? En +kristallkupol över himlen där himlen +borde vara är verkligen inget bra +tecken...","Kudretli maulotorlar kanıtladı seninle boy ölçüşemez, ve dumanı tüten cesetleri acımasızlık hissi uyandırır oldukları için memnuniyet yok edildi. @@ -6099,7 +6379,26 @@ Dar din nou, cu ceilalți Călăreți cum rămâne?","С гибелью Д'Сп можда је само био врисак. Али ипак, шта је са осталим јахачима -змија?","D'Sparil'in ölümü, yaratıklarını bu +змија?","D'Sparils död har lossat de magiska +band som håller hans varelser på detta +plan, deras dödliga skrik överväldigade +hans egna skrik av plågor. + +Din hämndens ed uppfylld, går du in i +portalen till din egen värld, bara några +ögonblick innan kupolen splittras i +en miljon bitar. + +Men om D'Sparils makt är bruten för +alltid, varför känner du dig då inte +trygg? Var det det sista ropet strax +före hans död, det som lät som en +förbannelse? Eller en kallelse? Du kan +inte riktigt vara säker, men det kan +ha varit ett skrik. + +Men å andra sidan, +hur är det med de andra ormryttarna?","D'Sparil'in ölümü, yaratıklarını bu alemde tutan büyülü bağları kopardı, onların ölüm çığlıkları kendi acı çığlıklarını bastırdı. @@ -6465,7 +6764,26 @@ proprii lui gardieni îți așteaptă sosirea ...","С гибелью Д'Спа нађете излаз. И негде, у најмрачнијим ћошковима Д'Спариловог поседа, његови лишни телохранитељи -чекају ваш долазак.","Kendi evine döneceğini sanıyordun. +чекају ваш долазак.","Du trodde att du skulle återvända till +din egen värld efter D'Sparils död, men +hans sista handling förvisade dig till +hans eget plan. Här gick du in i +krossade resterna av de länder som +D'Sparil erövrade. Du besegrade de +sista väktarna av dessa länder, men +nu står du framför portarna till D'Sparils +fäste. Fram till det här ögonblicket hade +du inga tvivel om din förmåga att möta +allt som du skulle kunna möta, men +bortom den här portalen ligger själva +hjärtat av den ondska som invaderade +din värld. D'Sparil må vara död, men +gropen där han föddes finns kvar. Nu +måste du gå in i den gropen i hopp om +att hitta en väg ut. Och någonstans, i +det mörkaste hörnet av D'Sparils rike, +väntar hans personliga livvakter på +din ankomst ...","Kendi evine döneceğini sanıyordun. D'Sparil öldükten sonra kendi dünyasına döndü. son eylemi seni sürgüne gönderdi kendi uçağı. İşte @@ -6809,7 +7127,25 @@ destinul.","Наблюдая с мрачным отвращением у лице очајања? Да ли имате храброст? Налазите, да у себи није да се предате без борбе. Широких очију, идете да -упознате своју судбину.","Son maulotor kükrerken ölüm acısı, +упознате своју судбину.","När den sista maulotauren ropar sin +dödsagoni inser du att du aldrig har +varit så nära din egen förintelse. Inte +ens kampen mot D'Sparil och hans +lärjungar hade varit så desperat. Grimt +stirrar du på portarna som öppnar +sig framför dig och undrar om de leder +hem eller om de öppnar sig mot någon +oanade skräck. Du finner dig själv +undra om du har styrkan att fortsätta, +om inget annat än död och smärta +väntar dig. Men vad kan man göra om +viljan att kämpa är borta? Kan du +tvinga dig själv att fortsätta när du +står inför en sådan förtvivlan? Har du +modet? Till slut upptäcker du att det +inte finns inom dig att ge upp utan strid. +Med stora ögon går du ditt öde till +mötes.","Son maulotor kükrerken ölüm acısı, fark edersin ki hiç bu kadar yaklaş- mamıştın. Yıkım. Savaş bile değil D'Sparil ve müritleri bu kadar çaresiz. @@ -7168,7 +7504,24 @@ la fiecare efort pe care îl faci.","Вы прошли семь порталов А негде далеко, у дубинама бесконачног хипостила, оживели су и сами зидови како би -оптеретили сваки Ваш корак.","Bu diyarı mühürleyen yedi kapıyı +оптеретили сваки Ваш корак.","Efter att ha passerat de sju portaler +som förseglade den här världen, +sträcker sig ett stort område med hård +vildmark framför dig. Eld, is och stål har +testat dig, men större utmaningar +återstår. Det täta virrvarret av skog +döljer säkert fientliga ögon, men det som +ligger bortom kommer att vara värre. + +Karg öken, fuktiga träsk och mossiga +grottor spärrar din väg, men du kan inte +låta något hindra dig från ditt öde, även +om du kanske önskar att det skulle +göra det. + +Och bortom, flimrande i fjärran, tycks +hypostilens ständigt skiftande +väggar håna dina ansträngningar.","Bu diyarı mühürleyen yedi kapıyı geçtikten sonra, önünüzde uçsuz bucaksız bir vahşi doğa uzanıyor. Ateş, buz ve çelik sizi sınadı ama @@ -7511,7 +7864,24 @@ cum vei putea ieși de aici vreodată?","Едва переведя дух пос О богови смрти, какво је ово место? О богови бола, како се може изићи -из њега?","Zihniniz hâlâ hipostil içindeki karşı- +из њега?","Ditt sinne är fortfarande i upplösning +efter dina möten i hypostylen. Du +vacklar mot vad du hoppas är en väg +ut. Saker och ting verkar gå snabbare +och snabbare, din syn suddas ut och +börjar blekna... +Medan världen kollapsar runt omkring +dig, uppslukas du av ljuset från en +teleportal. En ljusblixt, och sedan +klättrar du trött på dina fötter. + +Du står på toppen av ett högt torn, och +underifrån kommer de fördömdas skrik. +Du kliver fram, och genast får ljudet av +demonisk sång ditt blod att rysa. +Vid alla dödsgudar, till vilken plats har +du kommit? Vid alla smärtans gudar, +hur ska du någonsin hitta ut?","Zihniniz hâlâ hipostil içindeki karşı- laşmalarınızdan dolayı sersemlemiş durumda. Bir çıkış yolu olduğunu umduğun şeye doğru sendeliyorsun. @@ -7854,7 +8224,26 @@ tine. Undeva în interior, dușmanii te așteaptă...","Сил могущест злобних очију из таме. Непријатељи, чекајући Ваш долазак, -вребају унутра...","Kadimlerin en güçlü silahları ve eserleri +вребају унутра...","De mäktigaste vapnen och arte- +fakterna från de forntida räckte knappt +till för att besegra heresiarken och +hans hantlangare, men nu ligger deras +vidriga kvarlevor utspridda vid dina +fötter. Genom att samla dina sista +krafter förbereder du dig för att gå in i +portalen som leder från heresiarkens +inre helgedom. + +Ovanför dig skymtar vallarna till ett +enormt slott. Tysta torn och kala +väggar omger en enda spira av svart +sten, som sitter i mitten av slottet +som en grubblande jätte. Eld och +skugga vrider sig bakom gapande +fönster, dussintals ondskefulla +ögon stirrar ner på dig. +Någonstans där inne väntar dina +fiender...","Kadimlerin en güçlü silahları ve eserleri kâfir hükümdarı ve yardakçılarını yenmeye ancak yetti, ama şimdi onların iğrenç kalıntıları ayaklarınızın dibine @@ -8054,7 +8443,17 @@ Firar să fie.","«...И сойдёт он в царство мёртвых, -Проклетство.","""... ve ölüler diyarına yolculuk edecek +Проклетство.",""".... och han skall resa in i de dödas +rike och tävla med krafterna där, +till själva porten till förtvivlan. +Men om han skall återvända +till ljusets värld vet ingen."" + + + + + + Fan.","""... ve ölüler diyarına yolculuk edecek ve oradaki güçlerle umutsuzluğun kapılarına kadar mücadele edecek. Ama tekrar ışık dünyasına dönüp @@ -8217,7 +8616,15 @@ sursă de lumină din această lume.","Внезапно вас окутал ог напуњеној сабласним одјецима и грозним, непознатим сенкама. С уздигнутог положаја, близу Вас, -тече усамљено светло.","Acı dolu bir çığlıkla bu dünyadan +тече усамљено светло.","Med ett skrik av smärta slits du från +den här världen till en annan, varenda +del av din kropp är omgiven av +mystisk eld. När din syn klarnar +finner du dig själv stå i en stor hall, +fylld av spöklika ekon och hotfulla +skuggor. I fjärran kan du se en +upphöjd dais, och på den den +enda ljuskällan i den här världen.","Acı dolu bir çığlıkla bu dünyadan başka bir dünyaya savruluyorsunuz, vücudunuzun her parçası mistik bir ateşle kaplanıyor. Görüşünüz @@ -8403,7 +8810,18 @@ tabla e în mâinile tale.","Это сфера хаоса, источник си васељенску шаховску таблу, попут ништавног пешака који служи своме краљу и, издавши га, заузме -улогу краљице.","Bu sadece Korax'ın gücünün kaynağı +улогу краљице.","Detta kan bara vara kaos-sfären, +källan till Korax kraft. Med denna +kan du skapa världar... eller förstöra +dem. Genom stridens och erö- +vringens rättigheter är den din, och +med darrande händer sträcker du dig +för att ta tag i den. Kanske kommer +nu en ny spelare att ansluta sig till +det kosmiska spelet om makt. Likt +en bonde som befordras till drottning +verkar plötsligt brädans yttersta +räckvidd vara inom räckhåll för dig.","Bu sadece Korax'ın gücünün kaynağı olan kaos küresi olabilir. Bununla dünyalar yaratabilirsin... ya da onları yok edebilirsin. Savaş ve fetih @@ -8450,7 +8868,9 @@ puternici decât tine, și cine le-ar putea anticipa următoarele mișcări?","\n...Но есть более опытные игроки, и кому ведомы их дальнейшие ходы?","\nАли постоје и искуснији играчи, а коме су познати њихови даљњи -потези?","\nAma senden daha güçlü başka +потези?","Men det finns andra spelare som +är mäktigare än du, och vem kan +känna till deras nästa drag?","\nAma senden daha güçlü başka oyuncular da var. Sonraki hamleler?" "Wiping a trembling hand across your @@ -8765,12 +9185,12 @@ continuare... ...și să uiți ce ai lăsat în urmă. În depărtare, meterezele unui falnic castel par -să spintece cerul de deasupra, iar mirosul +să spintece cerul, iar mirosul decadenței se răspândește de la mormintele profanate ale nenumăraților morți. Numărând atent ce mai rămâne din artefactele tale, -încerci să te reasiguri ca vor fi suficiente. Până la +încerci să te reasiguri că vor fi suficiente. Până la urmă, vor trebui să fie de ajuns, nu-i așa? @@ -8803,7 +9223,25 @@ Nu-i așa?","Отерев кровь с лица дрожащей рукой, Пажљиво бројите шта ти је остало од артефакта и пробате се поново уверити да ће бити довољно. На крају крајева, треба да буде довољно, је ли тако? -Је ли тако?","Titreyen elinizi kanayan yüzünüze silerek, +Је ли тако?","Du stryker en darrande hand över ditt +blödande ansikte och försöker rensa +ditt sinne för det som väntar dig... + +...och glömma det som ligger bakom. + +I fjärran tycks de karga vallarna till +ett stort slottsanläggning slita sönder +himlen ovanför, och stanken av +förruttnelse vajar från de våldtagna +gravarna av oräkneliga döda. + +När du noggrant räknar det som +återstår av dina artefakter försöker du +försäkra dig själv om att det kommer +att räcka. Det måste ju räcka, eller hur? + + + eller hur?","Titreyen elinizi kanayan yüzünüze silerek, önünüzdekiler için zihninizi temizlemeye çalışıyorsunuz... @@ -9104,7 +9542,7 @@ morte fria e prolongada... -...para os fortunados.",,"Cu siguranță că sufletele blestemaților habituează +...para os fortunados.",,"Cu siguranță că sufletele blestemaților populează această lume, considerând faptul că nimic drept și bun nu poate supraviețui aici pentru multă vreme. @@ -9154,7 +9592,26 @@ lentei, reci morți... -...за срећнике.","kesinlikle lanetlenmişlerin ruhları bu +...за срећнике.","Säkert bor de fördömdas själar i denna +värld, för inget rättvist eller gott skulle +kunna överleva här länge. + + Men det som har passerat tidigare +kan bara vara en blek skugga av det +som hindrar din passage nu: själva +det mörka citadellet. + +Katedralens dystra massa blockerar +alla utom fragmentariska glimtar av +själva citadellet, men det som kan ses +talar i svischande viskningar om kall, +kvardröjande död... + + + + + + ...för de lyckligt lottade.","kesinlikle lanetlenmişlerin ruhları bu dünya, hiçbir şey için adil ya da iyi burada uzun süre hayatta kalabilirdi. @@ -9368,7 +9825,18 @@ ești urmărit de ochi ascunși... било тихо шапутање, осећај да вас неко посматра скривеним очима... -...очи које штите злобну намеру.","Kendinizi bir kez daha kaos küresinin +...очи које штите злобну намеру.","Ännu en gång befinner du dig i den +stora salen i kaos-sfären, som om +ingen tid hade gått sedan du senast +rörde dig bland dessa skuggor. + +Men något är kusligt annorlunda, +en tystnad där det en gång hade +varit mjuka viskningar, en känsla +av att bli iakttagen av dolda ögon... + +...ögon som skyddar en ondskefull +avsikt.","Kendinizi bir kez daha kaos küresinin büyük salonu üzerinden hiç zaman geçmemiş olsaydı en son bu gölgeler arasında hareket etmiştin. @@ -9632,7 +10100,21 @@ dea înlături de la o provocare...","Когда-то вы уже владели Али још увек, нисте били од оних који се повлаче од изазова... -","Bir zamanlar kaos küresini kavradın, +","En gång i tiden greppade du kaos- +sfären, höll den i darrande händer. Nu +darrar dina händer av något mer än +girighet, och rädsla förenas med +hunger efter makt. + +Om inte ens sfärens kraft är tillräcklig +för att skydda dig från mörkrets krafter +är det kanske bättre att lämna den +orörd, att inte hålla dess löfte. + + + +Men du var aldrig den som +backade från en utmaning...","Bir zamanlar kaos küresini kavradın, titreyen ellerinde tuttun. şimdi ellerin açgözlülükten daha fazla bir şeyle titriyor ve dehşet güç açlığıyla birleşiyor. @@ -9657,315 +10139,315 @@ lépésedre vár.",\n...e altri giocatori aspettano.,"\n...更なる挑戦者を ",\n...a inni gracze czekają.,\n...e os outros jogadores aguardam.,,\n...și alți jucători așteaptă.,"\n...В то время как другие игроки будут ждать своего часа, чтобы совершить свой ход.","\n...и други играчи вас чекају. -","\n...ve diğer oyuncular bekliyor. +",\n... och andra spelare väntar.,"\n...ve diğer oyuncular bekliyor. " -,,Hexen script texts,,,,,,,,,,,,,,,,,,,,,,,, -The door is locked,TXT_ACS_MAP01_5_THEDO,,,,Dveře jsou zamčené.,Døren er låst,Die Tür ist verschlossen,,La pordo estas ŝlosita.,La puerta está cerrada,,Ovi on lukittu,Cette porte est verouillée.,Az ajtó zárva van.,La porta è bloccata,扉は施錠されている,문이 잠겨 있다,De deur is op slot,Døren er låst,Drzwi są zablokowane,A porta está trancada,,Ușa e încuiată,Дверь заперта,Врата су закључана,Kapı kilitli -"Greetings, mortal",TXT_ACS_MAP02_9_GREET,,,,"Vítej, smrtelníče,","Vær hilset, dødelige","Sei gegrüßt, Sterblicher",,"Salutojn, mortemul'.","Saludos, mortal",,"Tervehdys, kuolevainen","Salutations, humain.","Üdvözöllek, halandó!","Salve, mortale",御機嫌よう、小僧,"환영한다, 필멸자여.","Groeten, sterfelijk","Vær hilset, dødelige",Witaj śmiertelniku,"Saudações, mortal.",,"Salutări, muritorule","Приветствую, смертный","Поздрав, смртниче","Selamlar, ölümlü" -Are you ready to die?,TXT_ACS_MAP02_11_AREYO,,,,jsi připraven@[ao_cs] zemřít?,Er du klar til at dø?,Bist du bereit zu sterben?,,Ĉu vi pretas morti?,¿Estás listo para morir?,,Oletko valmis kuolemaan?,Êtes-vous prêt à mourir?,Készen állsz a halálra?,Sei pronto a morire?,死に急ぐ仕度は整ったか?,죽을 준비는 됐는가?,Ben je klaar om te sterven?,Er du klar til å dø?,Czy jesteś gotów na śmierć?,Você está pront@[ao_ptb] para morrer?,,Ești pregătit să mori?,Готов ли ты умереть?,Јеси ли спреман да умреш?,Ölmeye hazır mısın? -A door opened on the Guardian of Ice,TXT_ACS_MAP02_20_ADOOR,,,,Ve Strážci ledu se otevřely dveře.,En dør åbnede sig på isens vogter,Eine Tür öffnet sich zum Wächter des Eises,,Pordo malfermiĝis ĉe la Gardanto de Glacia.,Se abrió una puerta en el Guardián de Hielo,,Ovi avautui jään vartijan luona,Une porte s'est ouverte dans le Gardien de Glace.,Egy ajtó kinyillott a Jég Őrzőjénél,Una porta è stata aperta sul Guardiano di Ghiaccio,氷の守護者にある扉は開かれた,얼음의 수호자에서 문이 열렸다,Een deur opende op de bewaker van ijs,En dør åpnet seg på Isens vokter,Drzwi w Strażniku Lodu otworzyły się,Uma porta se abriu no Guardião de Gelo,,O ușă s-a deschis pe Gardianul de Foc,Дверь открыта у стража льда,Врата су отворена код Чувара леда,Buz Muhafızı'nda bir kapı açıldı -This path is barred,TXT_ACS_MAP03_12_THISP,,,,Cesta je zatarasená.,Denne vej er spærret,Dieser Pfad ist blockiert,,Ĉi tiu vojo estas barita.,Este camino está atrancado,,Tämä polku on teljetty,Ce chemin est barré.,Ez az út el van torlaszolva.,Questo percorso è sbarrato,この道は塞がれている,이 통로는 빗장이 걸려있다,Dit pad is geblokkeerd,Denne veien er sperret,Ścieżka jest zablokowana,Este caminho está bloqueado,,Această cale e blocată,Сейчас этот путь закрыт,Овај пут је тренутно забрањен,Bu yol yasaklandı -One half of the puzzle has been solved,TXT_ACS_MAP04_9_ONEHA,,,,U Sedmera portálů byla vyřešena,Den ene halvdel af puslespillet er blevet løst,Eine Hälfte des Rätsels wurde gelöst,,Unu duono de la puzlo estas solvita,Una mitad del acertijo se ha resuelto,,Puolet pulmasta on ratkaistu,La moitié du puzzle à été résolu,A rejtvény egyik fele meg lett fejtve,Metà del puzzle è stato risolto,パズルの一つが解かれた,수수께끼의 절반이 풀렸다,De helft van de puzzel is opgelost,Den ene halvdelen av gåten er løst,Połowa zagadki rozwiązana,Metade do quebra-cabeça foi resolvido,,O jumătate din puzzle e rezolvată,Половина головоломки разгадана,Половина загонетке је решена,Bulmacanın bir yarısı çözüldü -on the Seven Portals,TXT_ACS_MAP04_10_ONTHE,,,,jedna třetina rébusu.,på de syv portaler,bei den Sieben Portalen,,ĉe la Sep Portaloj.,en los Siete Portales,,seitsemän portaalin luona,pour les Sept Portails.,a Hét Portálon,nei Sette Portali,漆之門に影響を与えた,... 일곱 차원문에서,op de Zeven Portalen,på de syv portaler,przy Siedmiu Portalach,nos Sete Portais,,pe cele Șapte Portaluri,на Семи порталах,на Седам портала,Yedi Portalda -One third of the puzzle has been solved,TXT_ACS_MAP04_11_ONETH,,,,U Sedmera portálů byla vyřešena,En tredjedel af gåden er blevet løst,Ein Drittel des Rätsels wurde gelöst,,Unu triono de la puzlo estas solvita,Un tercio del acertijo se ha resuelto,,Kolmannes pulmasta on ratkaistu,Un tiers du puzzle à été résolu,A rejtvény egyharmada megfejtésre került,Un terzo del puzzle è stato risolto,三種のパズルの一つが解かれた,수수께끼의 3분의 1이 풀렸다,Een derde van de puzzel is opgelost,En tredjedel av puslespillet er løst,Jedna trzecia zagadki rozwiązana,Um terço do quebra-cabeça foi resolvido,,O treime din puzzle a fost rezolvată,Треть головоломки разгадана,Трећина загонетке је решена,Bulmacanın üçte biri çözüldü -Stairs have risen on the Seven Portals,TXT_ACS_MAP04_12_STAIR,,,,jedna třetina rébusu.,Der er kommet en trappe op på de syv portaler,Stufen bei den Sieben Portale wurden erbaut,,Ŝtupoj leviĝis ĉe la Sep Portaloj.,Unas escaleras se han erguido en los Siete Portales,,Portaat ovat kohonneet seitsemän portaalin luona,Des escaliers sont apparus dans les Sept Portails.,A Hét Portálon belül egy lépcsősor emlekedett,Sono sorte le scale nei Sette Portali,漆之門に階段が立ち昇った,일곱 차원문에서 계단이 솟아났다,Trappen zijn gestegen op de Zeven Portalen,Trapper har reist seg på De syv portaler,Schody przy Siedmiu Portalach podniosły się,As escadas se ergueram nos Sete Portais,,S-au ridicat scări pe cele Șapte Portaluri,Лестница воздвигнулась на Семи порталах,Степенице се подижу на Седам портала,Yedi Portalda merdivenler yükseldi -One third of the puzzle has been solved,TXT_ACS_MAP05_6_ONETH,,,,U Sedmera portálů byla vyřešena,En tredjedel af puslespillet er blevet løst,Ein Drittel des Rätsels wurde gelöst,,Unu triono de la puzlo estas solvita,Un tercio del acertijo se ha resuelto,,Kolmannes pulmasta on ratkaistu,Un tiers du puzzle à été résolu,A rejtvény egyharmada megfejtésre került,Un terzo del puzzle è stato risolto,三種のパズルの一つが解かれた,수수께끼의 3분의 1이 풀렸다,Een derde van de puzzel is opgelost,En tredjedel av puslespillet er løst,Jedna trzecia zagadki rozwiązana,Um terço do quebra-cabeça foi resolvido,,O treime din puzzle a fost rezolvată,Треть головоломки разгадана,Трећина загонетке је решена,Bulmacanın üçte biri çözüldü -on the Seven Portals,TXT_ACS_MAP05_7_ONTHE,,,,jedna třetina rébusu.,på de syv portaler,bei den Sieben Portalen,,ĉe la Sep Portaloj.,en los Siete Portales,,seitsemän portaalin luona,pour les Sept Portails.,a Hét Portálon,nei Sette Portali,漆之門 に影響を与えた,... 일곱 차원문에서,op de Zeven Portalen,på de syv portaler,przy Siedmiu Portalach,nos Sete Portais,,pe cele Șapte Portaluri,на Семи порталах,на Седам портала,Yedi Portalda -Stairs have risen on the Seven Portals,TXT_ACS_MAP05_8_STAIR,,,,Schody se zvedly u Sedmera portálů.,Trappen er steget op på de syv portaler,Stufen bei den Sieben Portale wurden erbaut,,Ŝtupoj leviĝis ĉe la Sep Portaloj.,Unas escaleras se han erguido en los Siete Portales,,Portaat ovat kohonneet seitsemän portaalin luona,Des escaliers sont apparus dans les Sept Portails.,A Hét Portálon belül egy lépcsősor emlekedett,Sono sorte le scale nei Sette Portali,漆之門 に階段が立ち昇った,일곱 차원문에서 계단이 솟아났다,Trappen zijn gestegen op de Zeven Portalen,Trappene har reist seg på De syv portaler,Schody przy Siedmiu Portalach podniosły się,Escadas se ergueram nos Sete Portais,,S-au ridicat scări pe cele Șapte Portaluri,Лестница воздвигнулась на Семи порталах,Степенице се подижу на Седам портала,Yedi Portalda merdivenler yükseldi -You have to find another switch...,TXT_ACS_MAP05_9_YOUHA,,,,Musíš najít další spínač.,Du skal finde en anden kontakt...,Du must einen weiteren Schalter finden...,,Vi bezonas trovi alian ŝaltilon...,Debes encontrar otro interruptor...,Debes encontrar otro switch...,Sinun on löydettävä toinen vipu...,Vous devez trouver un autre bouton..,Egy másik kapcsolót kell találnod...,Devi trovare un altro interruttore...,他のスイッチも探す必要がある...,다른 개폐기를 찾아야 한다,Je moet een andere schakelaar vinden...,Du må finne en annen bryter...,Musisz znaleźć inny przełącznik...,Você precisa encontrar outro interruptor...,,Trebuie să găsești alt buton...,Остался ещё один переключатель...,Остао је још један прекидач...,Başka bir anahtar bulmalısın... -Stones grind on the Seven Portals,TXT_ACS_MAP05_10_STONE,,,,Kameny dřou u Sedmera portálů.,Stenene knirker på de syv portaler,Steine schleifen bei den Sieben Portalen,,Ŝtonoj grincas ĉe la Sep Portaloj.,Las piedras giran en los Siete Portales,,Kiviä vierii seitsemän portaalin luona,Des pierres grincent dans les Sept Portails.,Kövek örlődnek a Hét Portálnál,Le pietre si sono frantumate nei Sette Portali,漆之門 の石壁が砕かれた,일곱 차원문에서 바위 부딪히는 소리가 들려왔다,Stenen slijpen op de Zeven Portalen,Steiner knuser på De syv portaler,Kamienie przy Siedmiu Portalach zgrzytają,As pedras giram nos Sete Portais,,Pietrele încep să macine pe cele Șapte Portaluri,Каменная преграда отступила на Семи порталах,Камена препрека се повлачи,Taşlar Yedi Portalda öğütülüyor -One sixth of the puzzle has been solved,TXT_ACS_MAP08_6_ONESI,,,,V Temném hvozdu byla vyřešena,En sjettedel af puslespillet er blevet løst,Ein Sechstel des Rätsels wurde gelöst,,Unu sesono de la puzlo estas solvita,Un sexto del acertijo se ha resuelto,,Kuudennes pulmasta on ratkaistu,Un sixième du puzzle à été résolu,A feladványok egyhatoda megfejtésre került,Un sesto del puzzle è stato risolto,六種のパズルの一つが解かれた,수수께끼의 6분의 1이 풀렸다,Een zesde van de puzzel is opgelost,En sjettedel av puslespillet er løst,Jedna szósta zagadki rozwiązana,Um sexto do quebra-cabeça foi resolvido,,O șesime din puzzle a fost rezolvată,Одна шестая головоломки разгадана,Шестина загонетке је решена,Bulmacanın altıda biri çözüldü -on the Shadow Wood,TXT_ACS_MAP08_7_ONTHE,,,,jedna šestina rébusu.,i Skyggetræet,Im Schattenwald,,en la Ombro-Arbareto.,En el Bosque de Sombras,,Varjosalossa,dans le Bois des Ombres.,a Sötét Erdőben,Nel Bosco d'Ombra,陰影樹 に少し影響を与えた,... 그림자 숲에서,op het Schaduwbos,på Skyggeskogen,w Lesie Cieni,na Floresta das Sombras,,în Pădurea Umbrelor,в лесу теней,у Шуми сенки,Gölge Ormanı'nda -The door is barred from the inside,TXT_ACS_MAP08_10_THEDO,,,,Dveře jsou zatarasené zevnitř.,Døren er spærret indefra,Die Tür ist von innen verriegelt,,La pordo estas barita interne.,La puerta está atrancada desde el interior,,Ovi on teljetty sisältä,Cette porte est bloquée de l'intérieur.,Az ajtó be van reteszelve belülről,La porta è sbarrata da dentro,この扉は内側から塞がれている,이 문은 안에 빗장이 걸려있다,De deur is van binnenuit geblokkeerd.,Døren er sperret fra innsiden,Drzwi są zabarykadowane od środka,A porta está barrada por dentro,,Ușa e blocată dinăuntru,Дверь заблокирована изнутри,Врата су забрављена изнутра,Kapı içeriden kilitli. -You hear a door open in the distance,TXT_ACS_MAP08_11_YOUHE,,,,Slyšíš v dálce otevírající se dveře.,Du hører en dør åbne i det fjerne,"Du hörst, wie sich in der Ferne eine Tür öffnet",,Vi aŭdas pordon malfermiĝantan malproksime.,Escuchas que una puerta se abre a la distancia,,Kuulet oven avautuvan etäällä,Vous entendez une porte s'ouvrir au loin.,Hallod ahogy egy ajtó kinyílik a távolban,Senti una porta aprirsi in lontananza,遠くから扉が開く音が聞こえる,멀리서 문이 열리는 소리가 들린다,In de verte hoor je een deur openstaan.,Du hører en dør åpnes i det fjerne,Słyszysz odgłos otwierających się w oddali drzwi,Você ouve de longe uma porta se abrindo,,Auzi o ușă deschizându-se în depărtare,Слышен звук открывающейся двери,Чује се звук отварања врата,Uzakta bir kapının açıldığını duyuyorsun. -One sixth of the puzzle has been solved,TXT_ACS_MAP09_6_ONESI,,,,V Temném hvozdu byla vyřešena,En sjettedel af puslespillet er blevet løst,Ein Sechstel des Rätsels wurde gelöst,,Unu sesono de la puzlo estas solvita,Un sexto del acertijo se ha resuelto,,Kuudennes pulmasta on ratkaistu,Un sixième du puzzle à été résolu,A feladványok egyhatoda megfejtésre került,Un sesto del puzzle è stato risolto,六種のパズルの一つが解かれた,수수께끼의 6분의 1이 풀렸다,Een zesde van de puzzel is opgelost,En sjettedel av gåten er løst,Jedna szósta zagadki rozwiązana,Um sexto do quebra-cabeça foi resolvido,,O șesime din puzzle a fost rezolvată,Одна шестая головоломки разгадана,Шестина загонетке је решена,Bulmacanın altıda biri çözüldü -on the Shadow Wood,TXT_ACS_MAP09_7_ONTHE,,,,jedna šestina rébusu.,i Skyggetræet,Im Schattenwald,,en la Ombro-Arbareto.,En el Bosque de Sombras,,Varjosalossa,dans le Bois des Ombres.,a Sötét Erdőben,Nel Bosco d'Ombra,陰影樹 に少し影響を与えた,... 그림자 숲에서,op het Schaduwbos,på Skyggeskogen,w Lesie Cieni,na Floresta das Sombras,,în Pădurea Umbrelor,в лесу теней,у Шуми сенки,Gölge Ormanı'nda -One sixth of the puzzle has been solved,TXT_ACS_MAP10_6_ONESI,,,,V Temném hvozdu byla vyřešena,En sjettedel af puslespillet er blevet løst,Ein Sechstel des Rätsels wurde gelöst,,Unu sesono de la puzlo estas solvita,Un sexto del acertijo se ha resuelto,,Kuudennes pulmasta on ratkaistu,Un sixième du puzzle à été résolu,A feladványok egyhatoda megfejtésre került,Un sesto del puzzle è stato risolto,六種のパズルの一つが解かれた,수수께끼의 6분의 1이 풀렸다,Een zesde van de puzzel is opgelost,En sjettedel av puslespillet har blitt løst,Jedna szósta zagadki rozwiązana,Um sexto do quebra-cabeça foi resolvido,,O șesime din puzzle a fost rezolvată,Одна шестая головоломки разгадана,Шестина загонетке је решена,Bulmacanın altıda biri çözüldü -on the Shadow Wood,TXT_ACS_MAP10_7_ONTHE,,,,jedna šestina rébusu.,i Skyggetræet,Im Schattenwald,,en la Ombro-Arbareto.,En el Bosque de Sombras,,Varjosalossa,dans le Bois des Ombres.,a Sötét Erdőben,Nel Bosco d'Ombra,陰影樹 に少し影響を与えた,... 그림자 숲에서,op het Schaduwbos,på Skyggeskogen,w Lesie Cieni,na Floresta das Sombras,,în Pădurea Umbrelor,в лесу теней,у Шуми сенки,Gölge Ormanı'nda -\ ettins left,TXT_ACS_MAP11_0_ETTIN,Yellow needs better translation,,,\ etinů zbývá.,\ ettins venstre,\ Ettins übrig,,\ gigantaĉoj ceteraj,\ Ettins restantes,,\ ettiniä jäljellä,\ ettins restants,\ ettin maradt,\ Ettins rimasti,\ 匹のエティンが残っている,\ 마리 에틴이 남았음,\ overgebleven Ettins,\ ettins igjen,\ pozostałych ettinów,\ ettins restantes,,\ etini rămași,\ оставшихся эттинов,Остало је \ еттина,\ ettins ayrıldı -"You waited too long, now you die!",TXT_ACS_MAP11_1_YOUWA,,,,"Čekal@[ao_cs] jsi moc dlouho, teď zemřeš!","Du ventede for længe, nu dør du!","Du hast zu lange gewartet, jetzt stirbst du!",,"Vi atendis tro longe, nun vi mortas!","Esperaste demasiado, ¡ahora morirás!",,"Odotit liian pitkään, nyt kuolet!","Vous avez attendu trop longtemps, maintenant, mourrez!","Túl sokáig vártál, most meghalsz!","Hai atteso troppo a lungo, ora muori!",長居をしたな、命を奪うには十分な程に!,시간을 너무 오래 끌었다. 이제 죽어라!,"Je hebt te lang gewacht, nu ga je dood!","Du ventet for lenge, nå dør du!",Czekałeś zbyt długo. Teraz giń!,Você esperou demais. Agora morrerá!,,"Ți-a luat prea mult, acum mori!",Слишком долго! Готовься к смерти!,Предуго! Припреми се за смрт!,"Çok bekledin, şimdi öleceksin!" -A door opened on the Forsaken Outpost,TXT_ACS_MAP11_7_ADOOR,,,,Dveře se otevřely na Opuštěném stanovišti.,En dør blev åbnet i forladt forpost,Eine Tür im verlassenen Vorposten hat sich geöffnet,,Pordo malfermiĝis ĉe la Forlasita Posteno.,Una puerta se abrió en el Puesto de Avanzada Abandonado,,Ovi avautui hylätyssä etuvartiossa,Une porte s'est ouverte dans la base abandonnée.,Egy ajtó kinyílik az Elátkozott Őrportyán,Una porta è stata aperta nell'Avamposto Abbandonato,荒れ果てた前哨地 への扉が開いた,버려진 초소에서 문이 열렸다,Een deur opende een deur op de Verwaarloosde buitenpost,En dør åpnet seg på den forlatte utposten,Drzwi przy Opuszczonym Posterunku otworzyły się,Uma porta se abriu no Posto Abandonado,,O ușă s-a deschis pe Avanpostul Părăsit,Дверь открылась на покинутой заставе,Врата су се отворила у Напуштеној постаји,Unutulmuş Karakol'da bir kapı açıldı -This door won't open yet,TXT_ACS_MAP12_9_THISD,,,,Tyto dveře se ještě neotevřou.,Denne dør vil ikke åbne sig endnu,Die Tür öffnet sich noch nicht,,Ĉi tiu pordo ne jam malfermiĝos.,Esta puerta no se abrirá todavía,,Tämä ovi ei aukea vielä,Cette porte ne s'ouvre pas pour l'instant.,Ez az ajtó még nem fog kitárulni.,Questa porta non è aperta ancora,扉はまだ開かない,이 문은 아직 열 수 없다,Deze deur gaat nog niet open.,Denne døren vil ikke åpne seg ennå,Te drzwi jeszcze się nie otwierają,Esta porta não se abrirá ainda,,Ușa n-o să se deschidă încă,Сейчас эта дверь закрыта,Ова врата су тренутно закључана,Bu kapı henüz açılmayacak. -"My servants can smell your blood, human",TXT_ACS_MAP13_11_MYSER,,,,"Mí služebníci cítí tvou krev, člověče.","Mine tjenere kan lugte dit blod, menneske","Meine Diener riechen dein Blut, Menschling",,"Miajn servantoj povas flari vian sangon, homo.","Mis sirvientes pueden oler tu sangre, humano",,"Palvelijani voivat haistaa veresi, ihminen","Mes servants peuvent sentir votre sang, humain.","Szolgáim érzik a véred szagát, emberfattya","I miei servi possono annusare il tuo sangue, umano",我が下僕が貴様の血を嗅ぎ付けた様だぞ、小童,"이 몸의 하인들은 네 피 냄새를 맏고 따라온다, 인간.","Mijn bedienden kunnen jouw bloed ruiken, mens","Mine tjenere kan lukte blodet ditt, menneske",Moje sługi czują twą krew śmiertelniku,"Meus servos sentem o cheiro do seu sangue, human@[ao_ptb]",,"Servitorii mei îți pot adulmeca sângele, muritorule","Мои прислужники чуют твою кровь, человек","Моје слуге миришу твоју крв, човече","Hizmetçilerim kanının kokusunu alabiliyor, insan." -A door opened in the Gibbet,TXT_ACS_MAP21_0_ADOOR,,,,Dveře se otevřely na Šibenici.,En dør blev åbnet i Gibbet,Eine Tür in der Richtstätte wurde geöffnet,,Pordo malfermiĝis ĉe la Pendigilo.,Una puerta se abrió en la horca,,Ovi avautui hirsipuulla,Une porte s'est ouverte dans le gibet.,Egy ajtó kinyílik az Akasztófánál,Una porta è stata aperta nella Forca,晒し台 への扉が開いた,교수대에서 문이 열렸다,Een deur geopend in de Gibbet,En dør åpnet seg i galgen,Drzwi przy Szubienicy otworzyły się,Uma porta se abriu na Forca,,O ușă s-a deschis pe Eșafod,Проход будет открыт возле виселицы,Пролаз је отворен код вешала,İnfaz yerinde bir kapı açıldı -The door is barred from the inside,TXT_ACS_MAP21_2_THEDO,,,,Dveře jsou zatarasené zevnitř.,Døren er spærret indefra,Die Tür ist von innen verriegelt,,La pordo estas barita interne.,La puerta está atrancada desde el interior,,Ovi on teljetty sisältä,Cette porte est bloquée de l'intérieur.,Az ajtó belülről van eltorlaszolva,La porta è sbarrata da dentro,この扉は内側から塞がれている,이 문은 안에 빗장이 걸려있다,De deur is van binnenuit geblokkeerd.,Døren er sperret fra innsiden,Drzwi są zabarykadowane od środka,A porta está barrada por dentro,,Ușa e blocată dinăuntru,Дверь заблокирована изнутри,Врата су забрављена изнутра,Kapı içeriden kilitli. -A platform has lowered in the tower,TXT_ACS_MAP22_3_APLAT,,,,Plošina ve věži sjela dolů.,En platform er sænket i tårnet,Im Turm hat sich eine Plattform gesenkt,,Plataĵo malleviĝis en la turo.,Una plataforma ha bajado en la torre,,Lava on laskeutunut tornissa,Une plateforme est descendue dans la tour.,Egy platform leereszkedett a toronyban,Una piattaforma si è abbassata nella torre,塔内の昇降機が下りた,성 안에서 보행판이 내려왔다,Een platform is in de toren neergelaten in de toren,En plattform har senket seg i tårnet,Platforma w wieży obniżyła się,Uma plataforma desceu na torre,,O platformă a coborât în turn,Площадка опустилась в центральной башне,Спустио се платформ у централном торњу,Kuleye bir platform indirildi -"You have played this game too long, mortal...",TXT_ACS_MAP22_27_YOUHA,,,,"Tuhle partii jsi už hrál@[ao_cs] moc dlouho, smrtelníče,","Du har spillet dette spil for længe, dødelige...","Du spielst schon zu lange, Sterblicher...",,"Ludis ĉi tiun ludon vi tro longe, mortemul'...","Has jugado este juego demasiado tiempo, mortal...",,"Olet pelannut tätä peliä liian pitkään, kuolevainen...","Vous avez joué à ce jeu trop longtemps, mortel..","Túl sokat játszadoztál, halandó...","Ha giocato a questo gioco troppo a lungo, mortale...",遊びはここまでだ、小僧,"네 놈은 오랫동안 놀았도다, 필멸자여...","Je hebt dit spel te lang gespeeld, sterfelijke...","Du har spilt dette spillet for lenge, dødelige...",Już za długo grasz w tą grę śmiertelniku...,"Você jogou este jogo por tempo demais, mortal...",,"Ai jucat acest joc prea multă vreme, muritorule...","Ты слишком заигрался, смертный...","Превише си се заиграо, смртниче...","Bu oyunu çok uzun oynadın, ölümlü." -I think I shall remove you from the board,TXT_ACS_MAP22_29_ITHIN,,,,"myslím, že bych tě měl odstranit ze šachovnice.","Jeg tror, jeg vil fjerne dig fra brættet.",Ich denke ich sollte dich vom Brett entfernen,,"Mi kredas, ke mi vin forigos el la tabul'.",Creo que te retiraré del tablero,,Ajattelenpa poistaa sinut pelilaudalta,Je pense qu'il est l'heure de vous retirer de l'échiquier.,"Azt hiszem le kell, hogy üsselek a tábláról",Penso che ti rimuoverò dalla scacchiera,盤上から貴様を排除する,이 몸이 너를 말 치우듯이 제거하겠다.,Ik denk dat ik u van het bord zal verwijderen,Jeg tror jeg skal fjerne deg fra brettet,"Myślę, że usunę cię z planszy",Acho que irei removê-l@[ao_ptb] do tabuleiro,,Cred că e timpul să te înlătur de pe tablă,Пришло время завершить твою партию,Дошло је време да се заврши твоја партија,Sanırım seni tahtadan kaldırmalıyım. -You hear a door open upstairs,TXT_ACS_MAP23_10_YOUHE,,,,Z patra slyšíš otevírající se dveře.,Du hører en dør blive åbnet ovenpå.,"Du hörst, wie sich oben eine Tür öffnet",,Vi aŭdas pordon malfermiĝantan superŝtupare.,Escuchas una puerta que se abre arriba,,Kuulet oven avautuvat yläkerrassa,Vous entendez une porte s'ouvrir à l'étage.,Hallod ahogy egy ajtó kinyílik az emeleten,Senti una porta aprirsi al piano di sopra,上層階の扉が開いた,윗층에서 문이 열리는 소리가 들린다,Je hoort een deur boven opengaan,Du hører en dør åpnes ovenpå,Słyszysz odgłos otwierających się na górze drzwi,Você ouve uma porta se abrir lá em cima,,Auzi o ușă deschizându-se sus,Слышен звук открывающейся двери наверху,Од северне дворане зачује се звук,Üst katta bir kapının açıldığını duyuyorsun. -"Worship me, and I may yet be merciful",TXT_ACS_MAP27_8_WORSH,,,,Uctívej mě a možná ještě budu milosrdný.,"Tilbeder du mig, så er jeg måske barmhjertig.",Verehre mich und ich könnte gnädig sein,,"Kultu min, tiam mi ankoraŭ eble kompatos.","Adórame, y aun puedo ser misericordioso",,"Palvo minua, ja saatan vielä olla armahtavainen","Prosternez vous devant moi, et je pourrai considérer de vous épargner.","Hódolj be, és talán kegyelmes leszek","Venerami, e potrei essere ancora misericordioso",我を崇めろ、慈悲を残している内に,"이 몸에게 경배하라, 그럼 자비를 베풀 것이다.","Aanbid me, en ik mag dan nog genadig zijn","Tilbe meg, og jeg kan ennå være barmhjertig.","Wielb mnie, a może będę miłosierny","Venere-me, e eu poderei ser piedoso",,"Venerează-mă, și s-ar putea să mai fiu milostiv încă","Преклонись предо мной, и, может быть, я буду милосерден","Преклони се преда мноме, и можда ћу бити милостив","Bana ibadet et, belki merhamet ederim" -"Then again, maybe not",TXT_ACS_MAP27_10_THENA,,,,"Na druhou stranu, možná ne.",Men måske heller ikke,"Andererseits, vielleicht aber auch nicht",,"Tamen, eble ne.","Aunque, tal vez no",,"Mutta toisaalta, ehken sittenkään",Quoi que cela soit peu probable.,"Jól átgondolva, inkább nem",O potrei anche non esserlo,まあ、有り得ないな,허나... 그러지는 않겠지.,"Maar nogmaals, misschien niet",Men kanskje ikke,"Z drugiej strony, może nie...","Pensando melhor, talvez não",,"Dar apoi, poate că nu","А может быть, и нет",А можда и нећу,"Sonra tekrar, belki de değil" -One ninth of the puzzle has been solved,TXT_ACS_MAP28_6_ONENI,,,,V Klášteru byla vyřešena,En niende del af puslespillet er blevet løst,Ein Neuntel des Rätsels wurde gelöst,,Unu naŭono de la puzlo estas solvita,Un noveno del acertijo se ha resuelto,,Yhdeksäsosa pulmasta on ratkaistu,Un neuvième du puzzle à été résolu,A rejtvény egy kilencede megfejtésre került,Un nono del puzzle è stato risolto,九種のパズルの一つが解かれた,수수께끼의 9분의 1이 풀렸다,Een negende van de puzzel is opgelost.,En niende del av puslespillet er løst.,Jedna dziewiąta zagadki rozwiązana,Um nono do quebra-cabeça foi resolvido,,O noime din puzzle a fost rezolvată,Одна девятая головоломки разгадана,Деветина загонетке је решена,Bulmacanın dokuzda biri çözüldü -On the Monastery,TXT_ACS_MAP28_7_ONTHE,,,,jedna devítina rébusu.,På klosteret,Im Kloster,,en la Monaĥejo.,En el Monasterio,,luostarissa,dans le monastère.,A Monostorban,Nel Monastero,修道院 にわずかに影響を与えた,... 헤러시아크의 신학교에서,Op het klooster,på klosteret,w Klasztorze,No Mosteiro,,pe Mănăstire,в семинарии Ересиарха,у Јересијарховој семинарији,Manastır Üzerine -One ninth of the puzzle has been solved,TXT_ACS_MAP30_6_ONENI,,,,V Klášteru byla vyřešena,En niende del af puslespillet er blevet løst,Ein Neuntel des Rätsels wurde gelöst,,Unu naŭono de la puzlo estas solvita,Un noveno del acertijo se ha resuelto,,Yhdeksäsosa pulmasta on ratkaistu,Un neuvième du puzzle à été résolu,A rejtvény egy kilencede megfejtésre került,Un nono del puzzle è stato risolto,九種のパズルの一つが解かれた,수수께끼의 9분의 1이 풀렸다,Een negende van de puzzel is opgelost.,En niende del av gåten er løst.,Jedna dziewiąta zagadki rozwiązana,Um nono do quebra-cabeça foi resolvido,,O noime din puzzle a fost rezolvată,Одна девятая головоломки разгадана,Деветина загонетке је решена,Bulmacanın dokuzda biri çözüldü -On the Monastery,TXT_ACS_MAP30_7_ONTHE,,,,jedna devítina rébusu.,På klosteret,Im Kloster,,en la Monaĥejo.,En el Monasterio,,luostarissa,dans le monastère.,A Monostorban,Nel Monastero,修道院 にわずかに影響を与えた,... 헤러시아크의 신학교에서,Op het klooster,på klosteret,w Klasztorze,No Mosteiro,,pe Mănăstire,в семинарии Ересиарха,у Јересијарховој семинарији,Manastır Üzerine -One ninth of the puzzle has been solved,TXT_ACS_MAP34_1_ONENI,,,,V Klášteru byla vyřešena,En niende del af puslespillet er blevet løst,Ein Neuntel des Rätsels wurde gelöst,,Unu naŭono de la puzlo estas solvita,Un noveno del acertijo se ha resuelto,,Yhdeksäsosa pulmasta on ratkaistu,Un neuvième du puzzle à été résolu,A rejtvény egy kilencede megfejtésre került,Un nono del puzzle è stato risolto,九種のパズルの一つが解かれた,수수께끼의 9분의 1이 풀렸다,Een negende van de puzzel is opgelost.,En niendedel av puslespillet er løst,Jedna dziewiąta zagadki rozwiązana,Um nono do quebra-cabeça foi resolvido,,O noime din puzzle a fost rezolvată,Одна девятая головоломки разгадана,Деветина загонетке је решена,Bulmacanın dokuzda biri çözüldü -On the Monastery,TXT_ACS_MAP34_2_ONTHE,,,,jedna devítina rébusu.,På klosteret,Im Kloster,,en la Monaĥejo.,En el Monasterio,,luostarissa,dans le monastère.,A Monostorban,Nel Monastero,修道院 にわずかに影響を与えた,... 헤러시아크의 신학교에서,Op het klooster,på klosteret,w Klasztorze,No Mosteiro,,pe Mănăstire,в семинарии Ересиарха,у Јересијарховој семинарији,Manastır Üzerine -The portal has been sealed,TXT_ACS_MAP35_0_THEPO,,,,Portál byl zapečeťen.,Portalen er blevet forseglet,Das Portal wurde versiegelt,,La portalo estas obturita.,El portal se ha sellado,,Portaali on sinetöity,Le portail est scellé.,Az átjáró bezárult.,Il portale è stato sigillato,ポータルは封印された,차원문은 봉인되었다,Het portaal is verzegeld,Portalen har blitt forseglet,Portal został zapieczętowany,O portal foi selado,,Portalul a fost închis,Портал закрылся,Врата су затворена,Geçit mühürlendi -Choose your fate,TXT_ACS_MAP35_1_CHOOS,,,,Vyber si svůj osud.,Vælg din skæbne,Wähle dein Schicksal,,Elektu vian fatalon.,Escoge tu destino,Escoge tú destino,Valitse kohtalosi,Choisissez votre sort.,Dönts sorsod felől,Scegli la tua sorte,運命を撰べ,그대의 운명을 정해라,Kies uw lot,Velg din skjebne,Wybierz swoje przeznaczenie,Escolha o seu destino,,Alegeți destinul,Сделай свой выбор,Донеси своју одлуку,Kaderinizi seçin -The door is barred from the inside,TXT_ACS_MAP35_3_THEDO,,,,Dveře jsou zatarasené zevnitř.,Døren er spærret indefra,Die Tür ist von innen verriegelt,,La pordo estas barita interne.,La puerta está atrancada desde el interior,,Ovi on teljetty sisältä,Cette porte est bloquée de l'intérieur.,Az ajtót belülről torlaszolták el.,La porta è sbarrata da dentro,この扉は内側から塞がれている,이 문은 안에 빗장이 걸려있다,De deur is van binnenuit geblokkeerd.,Døren er sperret fra innsiden,Drzwi są zabarykadowane od środka,A porta está barrada por dentro,,Ușa e blocată dinăuntru,Дверь заблокирована изнутри,Врата су забрављена изнутра,Kapı içeriden kilitli. -Are you strong enough,TXT_ACS_MAP35_12_AREYO,,,,"Jsi dost siln@[adj_cs],",Er du stærk nok?,Bist du stark genug,,Ĉu vi estas sufiĉe forta,Eres lo suficientemente fuerte,,Olet riittävän vahva,Etes vous suffisamment fort,"Elég erős vagy,",Sei abbastanza forte,お前がどれだけ強かろうと,네 놈은 주인들을 대면할 힘이...,Ben je sterk genoeg,Er du sterk nok,Czy jesteś wystarczająco silny,Você é forte o suficiente,,Ești întradevăr suficient de puternic,"Достаточно ли ты силён,",Јеси ли довољно снажан,Yeterince güçlü müsün? -To face your own masters?,TXT_ACS_MAP35_14_TOFAC,,,,čelit svým vlastním pánům?,Til at møde dine egne mestre?,Dich deinen eigenen Meistern zu stellen?,,por stari kontraŭ viaj propraj mastroj?,¿Para enfrentarte a tus maestros?,,kohtaamaan omat mestarisi?,pour faire face à vos maîtres?,Hogy saját mestereiddel nézz szembe?,Da affrontare i tuoi stessi maestri?,お前の師に立ち向かえるのか?,진심으로 있는 것인가?,Om je eigen meesters onder ogen te komen?,Til å møte dine egne mestere?,By stawić czoła swoim mistrzom?,Para enfrentar os seus próprios mestres?,,Să îți înfrunți proprii stăpâni?,чтобы сразиться со своими наставниками?,да се суочиш са својим господарима?,Kendi efendilerinizle yüzleşmek için mi? -,,Hexen: Deathkings script texts,,,,,,,,,,,,,,,,,,,,,,,, -You dare battle in the ready room?,TXT_ACS_MAP33_6_YOUDA,,,,Ty si dovoluješ rvát se v přípravné místnosti?,Tør du kæmpe i beredskabsrummet?,Du wagst es im Bereitschaftsraum zu kämpfen?,,Vi aŭdacas batali en la pretĉambro?,¿Te atreves a luchar en la sala de preparación?,,Kuinka kehtaat taistella valmistautumishuoneessa?,Vous osez faire escarmouche dans la salle de préparation?,Hogy merészelsz harcolni a váróteremben?,Hai il coraggio di combattere in questa sala?,挑戦する準備は整ったか?,감히 준비의 방에서 전투를 벌이다니...,Durf jij te vechten in de readyroom?,Våger du å kjempe i det klare rommet?,Śmiesz walczyć w pokoju przygotowań?,Como ousa batalhar na sala de espera?,,Îndrăznești să lupți în camera de așteptare?,Ты посмел сражаться в комнате ожидания?,Усуђујеш се борити у припремној соби?,Hazırlanma odasında savaşmaya mı cüret ediyorsun? -"For that, you shall die!",TXT_ACS_MAP33_7_FORTH,,,,Pro to zemřeš!,For det skal du dø!,Dafür sollst du sterben!,,"Pro tio, vi mortos!","Por eso, ¡deberás morir!",,Siitä hyvästä kuolet!,"Pour cette insulte, vous trépasserez!",Ezért meghalsz!,"Per questo, morirai!",ならば、死へ進め!,죽어서 값을 치러라!,Daarvoor zal je sterven!,For det skal du dø!,Umrzesz za to!,Você morrerá por isso!,,"Pentru asta, vei muri!",Так умри же!,За то ћеш умрети!,Bunun için öleceksin! -The waterfall is open,TXT_ACS_MAP41_6_THEWA,,,,Vodopád je otevřen.,Vandfaldet er åbent,Der Wasserfall ist geöffnet,,La akvofalo estas malferma.,La cascada se ha abierto,,Vesiputous on auki,La cascade s'est ouverte.,A vizesés nyitva,La cascata è aperta,滝 は開いた,폭포가 멈췄다,De waterval is open,Fossen er åpen,Wodospad jest otwarty,A cascata está aberta,,Cascada e deschisă,Поток воды остановлен,Водопад је отворен,Şelale açık -The waterfall is blocked,TXT_ACS_MAP41_7_THEWA,,,,Vodopád je zatarasen.,Vandfaldet er blokeret,Der Wasserfall ist blockiert,,La akvofalo estas barita.,La cascada está bloqueada,,Vesiputous on tukittu,La cascade est bloquée.,A vizesés zárva,La cascata è bloccata,滝 は塞がっている,폭포에 의해 막혔다,De waterval is geblokkeerd,Fossen er blokkert,Wodospad jest zablokowany,A cascata está bloqueada,,Cascada e închisă,Поток воды преграждает путь,Водопад је блокиран,Şelale tıkalı -A door has opened in the chapel,TXT_ACS_MAP41_8_ADOOR,,,,Dveře se otevřely v kapli.,Der er åbnet en dør i kapellet,Eine Tür in der Kapelle hat sich geöffnet,,Pordo malfermis en la kapelo.,Una puerta se abrió en la Capilla,,Ovi on avautunut kappelissa,Une porte s'est ouverte dans la chapelle.,Egy ajtó kitárult a kápolnában,Una porta si è aperta nella cappella,庵寺 への扉が開いた,교외 근처에서 문이 열렸다,Een deur is geopend in de kapel,En dør har åpnet seg i kapellet,Drzwi w kaplicy zostały otwarte,Uma porta se abriu na capela,,O ușă s-a deschis în capelă,Дверь открылась в часовне,Врата су се отворила у катедрали,Şapelde bir kapı açıldı. -Now that's odd...,TXT_ACS_MAP42_4_NOWTH,,,,Tak to je divné...,Det er mærkeligt...,Hm. Das ist merkwürdig...,,Nun tio estas stranga...,Eso es extraño...,,Onpa kummallista...,Ca c'est étrange....,Ez felettébb különös...,Questo sì che è strano...,何かがおかしい...,무언가가 이상하다...,Dat is vreemd....,Det var merkelig...,Dziwne...,Que estranho...,,Asta e ciudat...,Как странно...,То је чудно...,İşte bu garip. -Three more parts of the puzzle remain,TXT_ACS_MAP44_1_THREE,,,,Zbývají tři části rébusu.,Der er endnu tre dele af gåden tilbage,Drei weitere Teile des Rätsels verbleiben,,Nur tri partoj de la puzlo restas.,Quedan tres partes más del acertijo,,Kolme pulman palasta jäljellä,Trois parties du puzzle restent à résoudre.,Három rész maradt a rejtvényből,Rimangono altre tre parti del puzzle,パズルの部品は残り 3つ,3개의 수수께끼가 아직 풀리지 않았다,Er blijven nog drie onderdelen van de puzzel over,Tre deler av puslespillet gjenstår,Pozostały jeszcze trzy części zagadki,Faltam mais três partes do quebra-cabeça,,Trei părți din puzzle încă rămân,Остались три части головоломки,Остају још три дела загонетке ,Bulmacanın üç parçası daha kaldı. -Two more parts of the puzzle remain,TXT_ACS_MAP44_2_TWOMO,,,,Zbývají dvě části rébusu.,Der er endnu to dele af puslespillet tilbage,Zwei weitere Teile des Rätsels verbleiben,,Nur du partoj de la puzlo restas.,Quedan dos partes más del acertijo,,Kaksi pulman palasta jäljellä,Deux parties du puzzle restent à résoudre.,Kettő rész maradt a rejtvényből,Rimangono altre due parti del puzzle,パズルの部品は残り 2つ,2개의 수수께끼가 아직 풀리지 않았다,Twee andere delen van de puzzel blijven over,To deler av puslespillet gjenstår,Pozostały jeszcze dwie części zagadki,Faltam mais duas partes do quebra-cabeça,,Două părți din puzzle încă rămân,Остались две части головоломки,Остају још два дела загонетке,Bulmacanın iki parçası daha kaldı -One more part of the puzzle remains,TXT_ACS_MAP44_3_ONEMO,,,,Zbývá jedna část rébusu.,Der er endnu en del af puslespillet tilbage,Ein weiteres Teil des Rätsels ist übrig,,Nur unu parto de la puzlo restas.,Queda una parte más del acertijo,,Yksi pulman palanen jäljellä,Il reste une partie du puzzle à résoudre.,Egy rész maradt a rejtvényből,Rimane un'altra parte del puzzle,パズルの部品は残り 1つ,마지막 수수께끼가 아직 풀리지 않았다,Nog een deel van de puzzel blijft over,En del av puslespillet gjenstår,Pozostała jeszcze jedna część zagadki,Falta mais uma parte do quebra-cabeça,,O parte din puzzle încă rămâne,Осталась одна часть головоломки,Остаје још један део загонетке,Bulmacanın bir parçası daha kaldı -The puzzle is complete,TXT_ACS_MAP44_4_THEPU,,,,Rébus je kompletní.,Puslespillet er færdigt,Das Rätsel ist abgeschlossen,,La puzlo estas kompleta.,El acertijo está completo,,Pulma on ratkaistu,Le puzzle est résolu.,A rejtvény végleg megoldódott,Il puzzle è completo,パズルは完成した,모든 수수께끼가 풀렸다,De puzzel is compleet,Puslespillet er komplett,Zagadka ukończona,O quebra-cabeça está concluído,,Puzzle-ul e rezolvat,Головоломка разгадана,Загонетка је решена,Bulmaca tamamlandı -You have not completed the puzzle,TXT_ACS_MAP44_6_YOUHA,,,,Nesplnil jsi rébus.,Du har ikke fuldført puslespillet,Du hast das Rätsel noch nicht gelöst,,Vi ne kompletis la puzlon.,No has completado el acertijo,,Et ole ratkaissut pulmaa,Vous n'avez pas résolu le puzzle.,Nem fejtetted meg a rejtvényt,Non hai completato il puzzle,パズルはまだ完成していない,모든 수수께끼를 풀지 못했다,Je hebt de puzzel nog niet voltooid.,Du har ikke fullført puslespillet,Nie ukończyłeś zagadki,Você não concluiu o quebra-cabeça,,Nu ai rezolvat puzzle-ul,Головоломка не разгадана,Нисте решили загонетку,Bulmacayı tamamlamadınız -The floor is not safe!,TXT_ACS_MAP44_8_THEFL,,,,Podlaha není bezpečná!,Gulvet er ikke sikkert!,Der Boden hier ist nicht sicher!,,La planko ne estas sendanĝera!,¡El suelo no es seguro!,,Kerros ei ole turvallinen!,Le sol est dangereux!,A padló nem biztonságos!,Il pavimento è pericoloso!,この場は安全ではない!,이 층은 안전하지 않다!,De vloer is niet veilig!,Gulvet er ikke trygt!,Ta podłoga nie jest bezpieczna!,O chão não está seguro!,,Podeaua nu e sigură!,Пол совсем прогнил!,Под није безбедан!,Zemin güvenli değil! -One third of the puzzle is solved,TXT_ACS_MAP44_10_ONETH,,,,Jedna třetina rébusu je vyřešena.,En tredjedel af puslespillet er løst,Ein Drittel des Rätsels ist gelöst,,Unu triono de la puzlo estas solvita.,Un tercio del acertijo se ha resuelto,,Kolmannes pulmasta on ratkaistu,Un tiers du puzzle à été résolu,A rejtvény egyharmada megoldásra került,Un terzo del puzzle è stato risolto,パズルの 三分の一 が解かれた,수수께끼의 3분의 1이 풀렸다,Een derde van de puzzel is opgelost.,En tredjedel av puslespillet er løst,Jedna trzecia zagadki rozwiązana,Um terço do quebra-cabeça foi resolvido,,O treime din puzzle e rezolvată,Одна треть головоломки разгадана,Трећина загонетке је решена,Bulmacanın üçte biri çözüldü -Two thirds of the puzzle is solved,TXT_ACS_MAP44_11_TWOTH,,,,Dvě třetiny rébusu jsou vyřešeny.,To tredjedele af puslespillet er løst,Zwei Drittel des Rätsels sind gelöst,,Du trionoj de la puzlo estas solvita.,Dos tercios del acertijo se han resuelto,,Kaksi kolmannesta pulmasta on ratkaistu,Deux tiers du puzzle ont été résolus,A rejtvény kétharmada megoldásra került,Due terzi del puzzle sono stati risolto,パズルの 三分の二 が解かれた,수수께끼의 3분의 2가 풀렸다,Tweederde van de puzzel is opgelost,To tredjedeler av puslespillet er løst.,Dwie trzecie zagadki rozwiązane,Dois terços do quebra-cabeça foi resolvido,,Două treimi din puzzle sunt rezolvate,Две трети головоломки разгаданы,Две трећине загонетке су решене,Bulmacanın üçte ikisi çözüldü +,,Hexen script texts,,,,,,,,,,,,,,,,,,,,,,,,, +The door is locked,TXT_ACS_MAP01_5_THEDO,,,,Dveře jsou zamčené.,Døren er låst,Die Tür ist verschlossen,,La pordo estas ŝlosita.,La puerta está cerrada,,Ovi on lukittu,Cette porte est verouillée.,Az ajtó zárva van.,La porta è bloccata,扉は施錠されている,문이 잠겨 있다,De deur is op slot,Døren er låst,Drzwi są zablokowane,A porta está trancada,,Ușa e încuiată,Дверь заперта,Врата су закључана,Dörren är låst,Kapı kilitli +"Greetings, mortal",TXT_ACS_MAP02_9_GREET,,,,"Vítej, smrtelníče,","Vær hilset, dødelige","Sei gegrüßt, Sterblicher",,"Salutojn, mortemul'.","Saludos, mortal",,"Tervehdys, kuolevainen","Salutations, humain.","Üdvözöllek, halandó!","Salve, mortale",御機嫌よう、小僧,"환영한다, 필멸자여.","Groeten, sterfelijk","Vær hilset, dødelige",Witaj śmiertelniku,"Saudações, mortal.",,"Salutări, muritorule","Приветствую, смертный","Поздрав, смртниче","Hälsningar, dödliga","Selamlar, ölümlü" +Are you ready to die?,TXT_ACS_MAP02_11_AREYO,,,,jsi připraven@[ao_cs] zemřít?,Er du klar til at dø?,Bist du bereit zu sterben?,,Ĉu vi pretas morti?,¿Estás listo para morir?,,Oletko valmis kuolemaan?,Êtes-vous prêt à mourir?,Készen állsz a halálra?,Sei pronto a morire?,死に急ぐ仕度は整ったか?,죽을 준비는 됐는가?,Ben je klaar om te sterven?,Er du klar til å dø?,Czy jesteś gotów na śmierć?,Você está pront@[ao_ptb] para morrer?,,Ești pregătit să mori?,Готов ли ты умереть?,Јеси ли спреман да умреш?,Är du redo att dö?,Ölmeye hazır mısın? +A door opened on the Guardian of Ice,TXT_ACS_MAP02_20_ADOOR,,,,Ve Strážci ledu se otevřely dveře.,En dør åbnede sig på isens vogter,Eine Tür öffnet sich zum Wächter des Eises,,Pordo malfermiĝis ĉe la Gardanto de Glacia.,Se abrió una puerta en el Guardián de Hielo,,Ovi avautui jään vartijan luona,Une porte s'est ouverte dans le Gardien de Glace.,Egy ajtó kinyillott a Jég Őrzőjénél,Una porta è stata aperta sul Guardiano di Ghiaccio,氷の守護者にある扉は開かれた,얼음의 수호자에서 문이 열렸다,Een deur opende op de bewaker van ijs,En dør åpnet seg på Isens vokter,Drzwi w Strażniku Lodu otworzyły się,Uma porta se abriu no Guardião de Gelo,,O ușă s-a deschis pe Gardianul de Foc,Дверь открыта у стража льда,Врата су отворена код Чувара леда,En dörr öppnades på isens väktare,Buz Muhafızı'nda bir kapı açıldı +This path is barred,TXT_ACS_MAP03_12_THISP,,,,Cesta je zatarasená.,Denne vej er spærret,Dieser Pfad ist blockiert,,Ĉi tiu vojo estas barita.,Este camino está atrancado,,Tämä polku on teljetty,Ce chemin est barré.,Ez az út el van torlaszolva.,Questo percorso è sbarrato,この道は塞がれている,이 통로는 빗장이 걸려있다,Dit pad is geblokkeerd,Denne veien er sperret,Ścieżka jest zablokowana,Este caminho está bloqueado,,Această cale e blocată,Сейчас этот путь закрыт,Овај пут је тренутно забрањен,Denna väg är spärrad,Bu yol yasaklandı +One half of the puzzle has been solved,TXT_ACS_MAP04_9_ONEHA,,,,U Sedmera portálů byla vyřešena,Den ene halvdel af puslespillet er blevet løst,Eine Hälfte des Rätsels wurde gelöst,,Unu duono de la puzlo estas solvita,Una mitad del acertijo se ha resuelto,,Puolet pulmasta on ratkaistu,La moitié du puzzle à été résolu,A rejtvény egyik fele meg lett fejtve,Metà del puzzle è stato risolto,パズルの一つが解かれた,수수께끼의 절반이 풀렸다,De helft van de puzzel is opgelost,Den ene halvdelen av gåten er løst,Połowa zagadki rozwiązana,Metade do quebra-cabeça foi resolvido,,O jumătate din puzzle e rezolvată,Половина головоломки разгадана,Половина загонетке је решена,En halva av pusslet har lösts,Bulmacanın bir yarısı çözüldü +on the Seven Portals,TXT_ACS_MAP04_10_ONTHE,,,,jedna třetina rébusu.,på de syv portaler,bei den Sieben Portalen,,ĉe la Sep Portaloj.,en los Siete Portales,,seitsemän portaalin luona,pour les Sept Portails.,a Hét Portálon,nei Sette Portali,漆之門に影響を与えた,... 일곱 차원문에서,op de Zeven Portalen,på de syv portaler,przy Siedmiu Portalach,nos Sete Portais,,pe cele Șapte Portaluri,на Семи порталах,на Седам портала,på de sju portalerna,Yedi Portalda +One third of the puzzle has been solved,TXT_ACS_MAP04_11_ONETH,,,,U Sedmera portálů byla vyřešena,En tredjedel af gåden er blevet løst,Ein Drittel des Rätsels wurde gelöst,,Unu triono de la puzlo estas solvita,Un tercio del acertijo se ha resuelto,,Kolmannes pulmasta on ratkaistu,Un tiers du puzzle à été résolu,A rejtvény egyharmada megfejtésre került,Un terzo del puzzle è stato risolto,三種のパズルの一つが解かれた,수수께끼의 3분의 1이 풀렸다,Een derde van de puzzel is opgelost,En tredjedel av puslespillet er løst,Jedna trzecia zagadki rozwiązana,Um terço do quebra-cabeça foi resolvido,,O treime din puzzle a fost rezolvată,Треть головоломки разгадана,Трећина загонетке је решена,En tredjedel av pusslet har lösts,Bulmacanın üçte biri çözüldü +Stairs have risen on the Seven Portals,TXT_ACS_MAP04_12_STAIR,,,,jedna třetina rébusu.,Der er kommet en trappe op på de syv portaler,Stufen bei den Sieben Portale wurden erbaut,,Ŝtupoj leviĝis ĉe la Sep Portaloj.,Unas escaleras se han erguido en los Siete Portales,,Portaat ovat kohonneet seitsemän portaalin luona,Des escaliers sont apparus dans les Sept Portails.,A Hét Portálon belül egy lépcsősor emlekedett,Sono sorte le scale nei Sette Portali,漆之門に階段が立ち昇った,일곱 차원문에서 계단이 솟아났다,Trappen zijn gestegen op de Zeven Portalen,Trapper har reist seg på De syv portaler,Schody przy Siedmiu Portalach podniosły się,As escadas se ergueram nos Sete Portais,,S-au ridicat scări pe cele Șapte Portaluri,Лестница воздвигнулась на Семи порталах,Степенице се подижу на Седам портала,En trappa har stigit upp i de sju portalerna,Yedi Portalda merdivenler yükseldi +One third of the puzzle has been solved,TXT_ACS_MAP05_6_ONETH,,,,U Sedmera portálů byla vyřešena,En tredjedel af puslespillet er blevet løst,Ein Drittel des Rätsels wurde gelöst,,Unu triono de la puzlo estas solvita,Un tercio del acertijo se ha resuelto,,Kolmannes pulmasta on ratkaistu,Un tiers du puzzle à été résolu,A rejtvény egyharmada megfejtésre került,Un terzo del puzzle è stato risolto,三種のパズルの一つが解かれた,수수께끼의 3분의 1이 풀렸다,Een derde van de puzzel is opgelost,En tredjedel av puslespillet er løst,Jedna trzecia zagadki rozwiązana,Um terço do quebra-cabeça foi resolvido,,O treime din puzzle a fost rezolvată,Треть головоломки разгадана,Трећина загонетке је решена,En tredjedel av pusslet har lösts,Bulmacanın üçte biri çözüldü +on the Seven Portals,TXT_ACS_MAP05_7_ONTHE,,,,jedna třetina rébusu.,på de syv portaler,bei den Sieben Portalen,,ĉe la Sep Portaloj.,en los Siete Portales,,seitsemän portaalin luona,pour les Sept Portails.,a Hét Portálon,nei Sette Portali,漆之門 に影響を与えた,... 일곱 차원문에서,op de Zeven Portalen,på de syv portaler,przy Siedmiu Portalach,nos Sete Portais,,pe cele Șapte Portaluri,на Семи порталах,на Седам портала,på de sju portalerna,Yedi Portalda +Stairs have risen on the Seven Portals,TXT_ACS_MAP05_8_STAIR,,,,Schody se zvedly u Sedmera portálů.,Trappen er steget op på de syv portaler,Stufen bei den Sieben Portale wurden erbaut,,Ŝtupoj leviĝis ĉe la Sep Portaloj.,Unas escaleras se han erguido en los Siete Portales,,Portaat ovat kohonneet seitsemän portaalin luona,Des escaliers sont apparus dans les Sept Portails.,A Hét Portálon belül egy lépcsősor emlekedett,Sono sorte le scale nei Sette Portali,漆之門 に階段が立ち昇った,일곱 차원문에서 계단이 솟아났다,Trappen zijn gestegen op de Zeven Portalen,Trappene har reist seg på De syv portaler,Schody przy Siedmiu Portalach podniosły się,Escadas se ergueram nos Sete Portais,,S-au ridicat scări pe cele Șapte Portaluri,Лестница воздвигнулась на Семи порталах,Степенице се подижу на Седам портала,Trappor har stigit upp på de sju portalerna,Yedi Portalda merdivenler yükseldi +You have to find another switch...,TXT_ACS_MAP05_9_YOUHA,,,,Musíš najít další spínač.,Du skal finde en anden kontakt...,Du must einen weiteren Schalter finden...,,Vi bezonas trovi alian ŝaltilon...,Debes encontrar otro interruptor...,Debes encontrar otro switch...,Sinun on löydettävä toinen vipu...,Vous devez trouver un autre bouton..,Egy másik kapcsolót kell találnod...,Devi trovare un altro interruttore...,他のスイッチも探す必要がある...,다른 개폐기를 찾아야 한다,Je moet een andere schakelaar vinden...,Du må finne en annen bryter...,Musisz znaleźć inny przełącznik...,Você precisa encontrar outro interruptor...,,Trebuie să găsești alt buton...,Остался ещё один переключатель...,Остао је још један прекидач...,Du måste hitta en annan omkopplare...,Başka bir anahtar bulmalısın... +Stones grind on the Seven Portals,TXT_ACS_MAP05_10_STONE,,,,Kameny dřou u Sedmera portálů.,Stenene knirker på de syv portaler,Steine schleifen bei den Sieben Portalen,,Ŝtonoj grincas ĉe la Sep Portaloj.,Las piedras giran en los Siete Portales,,Kiviä vierii seitsemän portaalin luona,Des pierres grincent dans les Sept Portails.,Kövek örlődnek a Hét Portálnál,Le pietre si sono frantumate nei Sette Portali,漆之門 の石壁が砕かれた,일곱 차원문에서 바위 부딪히는 소리가 들려왔다,Stenen slijpen op de Zeven Portalen,Steiner knuser på De syv portaler,Kamienie przy Siedmiu Portalach zgrzytają,As pedras giram nos Sete Portais,,Pietrele încep să macine pe cele Șapte Portaluri,Каменная преграда отступила на Семи порталах,Камена препрека се повлачи,Stenar slipar på de sju portalerna,Taşlar Yedi Portalda öğütülüyor +One sixth of the puzzle has been solved,TXT_ACS_MAP08_6_ONESI,,,,V Temném hvozdu byla vyřešena,En sjettedel af puslespillet er blevet løst,Ein Sechstel des Rätsels wurde gelöst,,Unu sesono de la puzlo estas solvita,Un sexto del acertijo se ha resuelto,,Kuudennes pulmasta on ratkaistu,Un sixième du puzzle à été résolu,A feladványok egyhatoda megfejtésre került,Un sesto del puzzle è stato risolto,六種のパズルの一つが解かれた,수수께끼의 6분의 1이 풀렸다,Een zesde van de puzzel is opgelost,En sjettedel av puslespillet er løst,Jedna szósta zagadki rozwiązana,Um sexto do quebra-cabeça foi resolvido,,O șesime din puzzle a fost rezolvată,Одна шестая головоломки разгадана,Шестина загонетке је решена,En sjättedel av pusslet har lösts,Bulmacanın altıda biri çözüldü +on the Shadow Wood,TXT_ACS_MAP08_7_ONTHE,,,,jedna šestina rébusu.,i Skyggetræet,Im Schattenwald,,en la Ombro-Arbareto.,En el Bosque de Sombras,,Varjosalossa,dans le Bois des Ombres.,a Sötét Erdőben,Nel Bosco d'Ombra,陰影樹 に少し影響を与えた,... 그림자 숲에서,op het Schaduwbos,på Skyggeskogen,w Lesie Cieni,na Floresta das Sombras,,în Pădurea Umbrelor,в лесу теней,у Шуми сенки,i skuggskogen,Gölge Ormanı'nda +The door is barred from the inside,TXT_ACS_MAP08_10_THEDO,,,,Dveře jsou zatarasené zevnitř.,Døren er spærret indefra,Die Tür ist von innen verriegelt,,La pordo estas barita interne.,La puerta está atrancada desde el interior,,Ovi on teljetty sisältä,Cette porte est bloquée de l'intérieur.,Az ajtó be van reteszelve belülről,La porta è sbarrata da dentro,この扉は内側から塞がれている,이 문은 안에 빗장이 걸려있다,De deur is van binnenuit geblokkeerd.,Døren er sperret fra innsiden,Drzwi są zabarykadowane od środka,A porta está barrada por dentro,,Ușa e blocată dinăuntru,Дверь заблокирована изнутри,Врата су забрављена изнутра,Dörren är spärrad från insidan,Kapı içeriden kilitli. +You hear a door open in the distance,TXT_ACS_MAP08_11_YOUHE,,,,Slyšíš v dálce otevírající se dveře.,Du hører en dør åbne i det fjerne,"Du hörst, wie sich in der Ferne eine Tür öffnet",,Vi aŭdas pordon malfermiĝantan malproksime.,Escuchas que una puerta se abre a la distancia,,Kuulet oven avautuvan etäällä,Vous entendez une porte s'ouvrir au loin.,Hallod ahogy egy ajtó kinyílik a távolban,Senti una porta aprirsi in lontananza,遠くから扉が開く音が聞こえる,멀리서 문이 열리는 소리가 들린다,In de verte hoor je een deur openstaan.,Du hører en dør åpnes i det fjerne,Słyszysz odgłos otwierających się w oddali drzwi,Você ouve de longe uma porta se abrindo,,Auzi o ușă deschizându-se în depărtare,Слышен звук открывающейся двери,Чује се звук отварања врата,Du hör en dörr som öppnas i fjärran,Uzakta bir kapının açıldığını duyuyorsun. +One sixth of the puzzle has been solved,TXT_ACS_MAP09_6_ONESI,,,,V Temném hvozdu byla vyřešena,En sjettedel af puslespillet er blevet løst,Ein Sechstel des Rätsels wurde gelöst,,Unu sesono de la puzlo estas solvita,Un sexto del acertijo se ha resuelto,,Kuudennes pulmasta on ratkaistu,Un sixième du puzzle à été résolu,A feladványok egyhatoda megfejtésre került,Un sesto del puzzle è stato risolto,六種のパズルの一つが解かれた,수수께끼의 6분의 1이 풀렸다,Een zesde van de puzzel is opgelost,En sjettedel av gåten er løst,Jedna szósta zagadki rozwiązana,Um sexto do quebra-cabeça foi resolvido,,O șesime din puzzle a fost rezolvată,Одна шестая головоломки разгадана,Шестина загонетке је решена,En sjättedel av pusslet har lösts.,Bulmacanın altıda biri çözüldü +on the Shadow Wood,TXT_ACS_MAP09_7_ONTHE,,,,jedna šestina rébusu.,i Skyggetræet,Im Schattenwald,,en la Ombro-Arbareto.,En el Bosque de Sombras,,Varjosalossa,dans le Bois des Ombres.,a Sötét Erdőben,Nel Bosco d'Ombra,陰影樹 に少し影響を与えた,... 그림자 숲에서,op het Schaduwbos,på Skyggeskogen,w Lesie Cieni,na Floresta das Sombras,,în Pădurea Umbrelor,в лесу теней,у Шуми сенки,i skuggskogen,Gölge Ormanı'nda +One sixth of the puzzle has been solved,TXT_ACS_MAP10_6_ONESI,,,,V Temném hvozdu byla vyřešena,En sjettedel af puslespillet er blevet løst,Ein Sechstel des Rätsels wurde gelöst,,Unu sesono de la puzlo estas solvita,Un sexto del acertijo se ha resuelto,,Kuudennes pulmasta on ratkaistu,Un sixième du puzzle à été résolu,A feladványok egyhatoda megfejtésre került,Un sesto del puzzle è stato risolto,六種のパズルの一つが解かれた,수수께끼의 6분의 1이 풀렸다,Een zesde van de puzzel is opgelost,En sjettedel av puslespillet har blitt løst,Jedna szósta zagadki rozwiązana,Um sexto do quebra-cabeça foi resolvido,,O șesime din puzzle a fost rezolvată,Одна шестая головоломки разгадана,Шестина загонетке је решена,En sjättedel av pusslet har lösts.,Bulmacanın altıda biri çözüldü +on the Shadow Wood,TXT_ACS_MAP10_7_ONTHE,,,,jedna šestina rébusu.,i Skyggetræet,Im Schattenwald,,en la Ombro-Arbareto.,En el Bosque de Sombras,,Varjosalossa,dans le Bois des Ombres.,a Sötét Erdőben,Nel Bosco d'Ombra,陰影樹 に少し影響を与えた,... 그림자 숲에서,op het Schaduwbos,på Skyggeskogen,w Lesie Cieni,na Floresta das Sombras,,în Pădurea Umbrelor,в лесу теней,у Шуми сенки,i skuggskogen,Gölge Ormanı'nda +\ ettins left,TXT_ACS_MAP11_0_ETTIN,Yellow needs better translation,,,\ etinů zbývá.,\ ettins venstre,\ Ettins übrig,,\ gigantaĉoj ceteraj,\ Ettins restantes,,\ ettiniä jäljellä,\ ettins restants,\ ettin maradt,\ Ettins rimasti,\ 匹のエティンが残っている,\ 마리 에틴이 남았음,\ overgebleven Ettins,\ ettins igjen,\ pozostałych ettinów,\ ettins restantes,,\ etini rămași,\ оставшихся эттинов,Остало је \ еттина,\ ettins lämnade,\ ettins ayrıldı +"You waited too long, now you die!",TXT_ACS_MAP11_1_YOUWA,,,,"Čekal@[ao_cs] jsi moc dlouho, teď zemřeš!","Du ventede for længe, nu dør du!","Du hast zu lange gewartet, jetzt stirbst du!",,"Vi atendis tro longe, nun vi mortas!","Esperaste demasiado, ¡ahora morirás!",,"Odotit liian pitkään, nyt kuolet!","Vous avez attendu trop longtemps, maintenant, mourrez!","Túl sokáig vártál, most meghalsz!","Hai atteso troppo a lungo, ora muori!",長居をしたな、命を奪うには十分な程に!,시간을 너무 오래 끌었다. 이제 죽어라!,"Je hebt te lang gewacht, nu ga je dood!","Du ventet for lenge, nå dør du!",Czekałeś zbyt długo. Teraz giń!,Você esperou demais. Agora morrerá!,,"Ți-a luat prea mult, acum mori!",Слишком долго! Готовься к смерти!,Предуго! Припреми се за смрт!,"Du väntade för länge, nu dör du!","Çok bekledin, şimdi öleceksin!" +A door opened on the Forsaken Outpost,TXT_ACS_MAP11_7_ADOOR,,,,Dveře se otevřely na Opuštěném stanovišti.,En dør blev åbnet i forladt forpost,Eine Tür im verlassenen Vorposten hat sich geöffnet,,Pordo malfermiĝis ĉe la Forlasita Posteno.,Una puerta se abrió en el Puesto de Avanzada Abandonado,,Ovi avautui hylätyssä etuvartiossa,Une porte s'est ouverte dans la base abandonnée.,Egy ajtó kinyílik az Elátkozott Őrportyán,Una porta è stata aperta nell'Avamposto Abbandonato,荒れ果てた前哨地 への扉が開いた,버려진 초소에서 문이 열렸다,Een deur opende een deur op de Verwaarloosde buitenpost,En dør åpnet seg på den forlatte utposten,Drzwi przy Opuszczonym Posterunku otworzyły się,Uma porta se abriu no Posto Abandonado,,O ușă s-a deschis pe Avanpostul Părăsit,Дверь открылась на покинутой заставе,Врата су се отворила у Напуштеној постаји,En dörr har öppnats på försvunnen utposten,Unutulmuş Karakol'da bir kapı açıldı +This door won't open yet,TXT_ACS_MAP12_9_THISD,,,,Tyto dveře se ještě neotevřou.,Denne dør vil ikke åbne sig endnu,Die Tür öffnet sich noch nicht,,Ĉi tiu pordo ne jam malfermiĝos.,Esta puerta no se abrirá todavía,,Tämä ovi ei aukea vielä,Cette porte ne s'ouvre pas pour l'instant.,Ez az ajtó még nem fog kitárulni.,Questa porta non è aperta ancora,扉はまだ開かない,이 문은 아직 열 수 없다,Deze deur gaat nog niet open.,Denne døren vil ikke åpne seg ennå,Te drzwi jeszcze się nie otwierają,Esta porta não se abrirá ainda,,Ușa n-o să se deschidă încă,Сейчас эта дверь закрыта,Ова врата су тренутно закључана,Den här dörren kommer inte att öppnas än.,Bu kapı henüz açılmayacak. +"My servants can smell your blood, human",TXT_ACS_MAP13_11_MYSER,,,,"Mí služebníci cítí tvou krev, člověče.","Mine tjenere kan lugte dit blod, menneske","Meine Diener riechen dein Blut, Menschling",,"Miajn servantoj povas flari vian sangon, homo.","Mis sirvientes pueden oler tu sangre, humano",,"Palvelijani voivat haistaa veresi, ihminen","Mes servants peuvent sentir votre sang, humain.","Szolgáim érzik a véred szagát, emberfattya","I miei servi possono annusare il tuo sangue, umano",我が下僕が貴様の血を嗅ぎ付けた様だぞ、小童,"이 몸의 하인들은 네 피 냄새를 맏고 따라온다, 인간.","Mijn bedienden kunnen jouw bloed ruiken, mens","Mine tjenere kan lukte blodet ditt, menneske",Moje sługi czują twą krew śmiertelniku,"Meus servos sentem o cheiro do seu sangue, human@[ao_ptb]",,"Servitorii mei îți pot adulmeca sângele, muritorule","Мои прислужники чуют твою кровь, человек","Моје слуге миришу твоју крв, човече","Mina tjänare kan känna lukten av ditt blod, människa.","Hizmetçilerim kanının kokusunu alabiliyor, insan." +A door opened in the Gibbet,TXT_ACS_MAP21_0_ADOOR,,,,Dveře se otevřely na Šibenici.,En dør blev åbnet i Gibbet,Eine Tür in der Richtstätte wurde geöffnet,,Pordo malfermiĝis ĉe la Pendigilo.,Una puerta se abrió en la horca,,Ovi avautui hirsipuulla,Une porte s'est ouverte dans le gibet.,Egy ajtó kinyílik az Akasztófánál,Una porta è stata aperta nella Forca,晒し台 への扉が開いた,교수대에서 문이 열렸다,Een deur geopend in de Gibbet,En dør åpnet seg i galgen,Drzwi przy Szubienicy otworzyły się,Uma porta se abriu na Forca,,O ușă s-a deschis pe Eșafod,Проход будет открыт возле виселицы,Пролаз је отворен код вешала,En dörr öppnades i Gibbet,İnfaz yerinde bir kapı açıldı +The door is barred from the inside,TXT_ACS_MAP21_2_THEDO,,,,Dveře jsou zatarasené zevnitř.,Døren er spærret indefra,Die Tür ist von innen verriegelt,,La pordo estas barita interne.,La puerta está atrancada desde el interior,,Ovi on teljetty sisältä,Cette porte est bloquée de l'intérieur.,Az ajtó belülről van eltorlaszolva,La porta è sbarrata da dentro,この扉は内側から塞がれている,이 문은 안에 빗장이 걸려있다,De deur is van binnenuit geblokkeerd.,Døren er sperret fra innsiden,Drzwi są zabarykadowane od środka,A porta está barrada por dentro,,Ușa e blocată dinăuntru,Дверь заблокирована изнутри,Врата су забрављена изнутра,Dörren är spärrad från insidan,Kapı içeriden kilitli. +A platform has lowered in the tower,TXT_ACS_MAP22_3_APLAT,,,,Plošina ve věži sjela dolů.,En platform er sænket i tårnet,Im Turm hat sich eine Plattform gesenkt,,Plataĵo malleviĝis en la turo.,Una plataforma ha bajado en la torre,,Lava on laskeutunut tornissa,Une plateforme est descendue dans la tour.,Egy platform leereszkedett a toronyban,Una piattaforma si è abbassata nella torre,塔内の昇降機が下りた,성 안에서 보행판이 내려왔다,Een platform is in de toren neergelaten in de toren,En plattform har senket seg i tårnet,Platforma w wieży obniżyła się,Uma plataforma desceu na torre,,O platformă a coborât în turn,Площадка опустилась в центральной башне,Спустио се платформ у централном торњу,En plattform har sänkts i tornet,Kuleye bir platform indirildi +"You have played this game too long, mortal...",TXT_ACS_MAP22_27_YOUHA,,,,"Tuhle partii jsi už hrál@[ao_cs] moc dlouho, smrtelníče,","Du har spillet dette spil for længe, dødelige...","Du spielst schon zu lange, Sterblicher...",,"Ludis ĉi tiun ludon vi tro longe, mortemul'...","Has jugado este juego demasiado tiempo, mortal...",,"Olet pelannut tätä peliä liian pitkään, kuolevainen...","Vous avez joué à ce jeu trop longtemps, mortel..","Túl sokat játszadoztál, halandó...","Ha giocato a questo gioco troppo a lungo, mortale...",遊びはここまでだ、小僧,"네 놈은 오랫동안 놀았도다, 필멸자여...","Je hebt dit spel te lang gespeeld, sterfelijke...","Du har spilt dette spillet for lenge, dødelige...",Już za długo grasz w tą grę śmiertelniku...,"Você jogou este jogo por tempo demais, mortal...",,"Ai jucat acest joc prea multă vreme, muritorule...","Ты слишком заигрался, смертный...","Превише си се заиграо, смртниче...","Du har spelat det här spelet för länge, dödlig...","Bu oyunu çok uzun oynadın, ölümlü." +I think I shall remove you from the board,TXT_ACS_MAP22_29_ITHIN,,,,"myslím, že bych tě měl odstranit ze šachovnice.","Jeg tror, jeg vil fjerne dig fra brættet.",Ich denke ich sollte dich vom Brett entfernen,,"Mi kredas, ke mi vin forigos el la tabul'.",Creo que te retiraré del tablero,,Ajattelenpa poistaa sinut pelilaudalta,Je pense qu'il est l'heure de vous retirer de l'échiquier.,"Azt hiszem le kell, hogy üsselek a tábláról",Penso che ti rimuoverò dalla scacchiera,盤上から貴様を排除する,이 몸이 너를 말 치우듯이 제거하겠다.,Ik denk dat ik u van het bord zal verwijderen,Jeg tror jeg skal fjerne deg fra brettet,"Myślę, że usunę cię z planszy",Acho que irei removê-l@[ao_ptb] do tabuleiro,,Cred că e timpul să te înlătur de pe tablă,Пришло время завершить твою партию,Дошло је време да се заврши твоја партија,Jag tror att jag ska ta bort dig från spelplanen.,Sanırım seni tahtadan kaldırmalıyım. +You hear a door open upstairs,TXT_ACS_MAP23_10_YOUHE,,,,Z patra slyšíš otevírající se dveře.,Du hører en dør blive åbnet ovenpå.,"Du hörst, wie sich oben eine Tür öffnet",,Vi aŭdas pordon malfermiĝantan superŝtupare.,Escuchas una puerta que se abre arriba,,Kuulet oven avautuvat yläkerrassa,Vous entendez une porte s'ouvrir à l'étage.,Hallod ahogy egy ajtó kinyílik az emeleten,Senti una porta aprirsi al piano di sopra,上層階の扉が開いた,윗층에서 문이 열리는 소리가 들린다,Je hoort een deur boven opengaan,Du hører en dør åpnes ovenpå,Słyszysz odgłos otwierających się na górze drzwi,Você ouve uma porta se abrir lá em cima,,Auzi o ușă deschizându-se sus,Слышен звук открывающейся двери наверху,Од северне дворане зачује се звук,Du hör en dörr öppnas på övervåningen.,Üst katta bir kapının açıldığını duyuyorsun. +"Worship me, and I may yet be merciful",TXT_ACS_MAP27_8_WORSH,,,,Uctívej mě a možná ještě budu milosrdný.,"Tilbeder du mig, så er jeg måske barmhjertig.",Verehre mich und ich könnte gnädig sein,,"Kultu min, tiam mi ankoraŭ eble kompatos.","Adórame, y aun puedo ser misericordioso",,"Palvo minua, ja saatan vielä olla armahtavainen","Prosternez vous devant moi, et je pourrai considérer de vous épargner.","Hódolj be, és talán kegyelmes leszek","Venerami, e potrei essere ancora misericordioso",我を崇めろ、慈悲を残している内に,"이 몸에게 경배하라, 그럼 자비를 베풀 것이다.","Aanbid me, en ik mag dan nog genadig zijn","Tilbe meg, og jeg kan ennå være barmhjertig.","Wielb mnie, a może będę miłosierny","Venere-me, e eu poderei ser piedoso",,"Venerează-mă, și s-ar putea să mai fiu milostiv încă","Преклонись предо мной, и, может быть, я буду милосерден","Преклони се преда мноме, и можда ћу бити милостив","Dyrka mig, så kanske jag är barmhärtig.","Bana ibadet et, belki merhamet ederim" +"Then again, maybe not",TXT_ACS_MAP27_10_THENA,,,,"Na druhou stranu, možná ne.",Men måske heller ikke,"Andererseits, vielleicht aber auch nicht",,"Tamen, eble ne.","Aunque, tal vez no",,"Mutta toisaalta, ehken sittenkään",Quoi que cela soit peu probable.,"Jól átgondolva, inkább nem",O potrei anche non esserlo,まあ、有り得ないな,허나... 그러지는 않겠지.,"Maar nogmaals, misschien niet",Men kanskje ikke,"Z drugiej strony, może nie...","Pensando melhor, talvez não",,"Dar apoi, poate că nu","А может быть, и нет",А можда и нећу,"Men å andra sidan, kanske inte.","Sonra tekrar, belki de değil" +One ninth of the puzzle has been solved,TXT_ACS_MAP28_6_ONENI,,,,V Klášteru byla vyřešena,En niende del af puslespillet er blevet løst,Ein Neuntel des Rätsels wurde gelöst,,Unu naŭono de la puzlo estas solvita,Un noveno del acertijo se ha resuelto,,Yhdeksäsosa pulmasta on ratkaistu,Un neuvième du puzzle à été résolu,A rejtvény egy kilencede megfejtésre került,Un nono del puzzle è stato risolto,九種のパズルの一つが解かれた,수수께끼의 9분의 1이 풀렸다,Een negende van de puzzel is opgelost.,En niende del av puslespillet er løst.,Jedna dziewiąta zagadki rozwiązana,Um nono do quebra-cabeça foi resolvido,,O noime din puzzle a fost rezolvată,Одна девятая головоломки разгадана,Деветина загонетке је решена,En niondel av pusslet har lösts.,Bulmacanın dokuzda biri çözüldü +On the Monastery,TXT_ACS_MAP28_7_ONTHE,,,,jedna devítina rébusu.,På klosteret,Im Kloster,,en la Monaĥejo.,En el Monasterio,,luostarissa,dans le monastère.,A Monostorban,Nel Monastero,修道院 にわずかに影響を与えた,... 헤러시아크의 신학교에서,Op het klooster,på klosteret,w Klasztorze,No Mosteiro,,pe Mănăstire,в семинарии Ересиарха,у Јересијарховој семинарији,På klostret,Manastır Üzerine +One ninth of the puzzle has been solved,TXT_ACS_MAP30_6_ONENI,,,,V Klášteru byla vyřešena,En niende del af puslespillet er blevet løst,Ein Neuntel des Rätsels wurde gelöst,,Unu naŭono de la puzlo estas solvita,Un noveno del acertijo se ha resuelto,,Yhdeksäsosa pulmasta on ratkaistu,Un neuvième du puzzle à été résolu,A rejtvény egy kilencede megfejtésre került,Un nono del puzzle è stato risolto,九種のパズルの一つが解かれた,수수께끼의 9분의 1이 풀렸다,Een negende van de puzzel is opgelost.,En niende del av gåten er løst.,Jedna dziewiąta zagadki rozwiązana,Um nono do quebra-cabeça foi resolvido,,O noime din puzzle a fost rezolvată,Одна девятая головоломки разгадана,Деветина загонетке је решена,En niondel av pusslet har lösts.,Bulmacanın dokuzda biri çözüldü +On the Monastery,TXT_ACS_MAP30_7_ONTHE,,,,jedna devítina rébusu.,På klosteret,Im Kloster,,en la Monaĥejo.,En el Monasterio,,luostarissa,dans le monastère.,A Monostorban,Nel Monastero,修道院 にわずかに影響を与えた,... 헤러시아크의 신학교에서,Op het klooster,på klosteret,w Klasztorze,No Mosteiro,,pe Mănăstire,в семинарии Ересиарха,у Јересијарховој семинарији,På klostret,Manastır Üzerine +One ninth of the puzzle has been solved,TXT_ACS_MAP34_1_ONENI,,,,V Klášteru byla vyřešena,En niende del af puslespillet er blevet løst,Ein Neuntel des Rätsels wurde gelöst,,Unu naŭono de la puzlo estas solvita,Un noveno del acertijo se ha resuelto,,Yhdeksäsosa pulmasta on ratkaistu,Un neuvième du puzzle à été résolu,A rejtvény egy kilencede megfejtésre került,Un nono del puzzle è stato risolto,九種のパズルの一つが解かれた,수수께끼의 9분의 1이 풀렸다,Een negende van de puzzel is opgelost.,En niendedel av puslespillet er løst,Jedna dziewiąta zagadki rozwiązana,Um nono do quebra-cabeça foi resolvido,,O noime din puzzle a fost rezolvată,Одна девятая головоломки разгадана,Деветина загонетке је решена,En nionde del av pusslet har lösts.,Bulmacanın dokuzda biri çözüldü +On the Monastery,TXT_ACS_MAP34_2_ONTHE,,,,jedna devítina rébusu.,På klosteret,Im Kloster,,en la Monaĥejo.,En el Monasterio,,luostarissa,dans le monastère.,A Monostorban,Nel Monastero,修道院 にわずかに影響を与えた,... 헤러시아크의 신학교에서,Op het klooster,på klosteret,w Klasztorze,No Mosteiro,,pe Mănăstire,в семинарии Ересиарха,у Јересијарховој семинарији,På klostret,Manastır Üzerine +The portal has been sealed,TXT_ACS_MAP35_0_THEPO,,,,Portál byl zapečeťen.,Portalen er blevet forseglet,Das Portal wurde versiegelt,,La portalo estas obturita.,El portal se ha sellado,,Portaali on sinetöity,Le portail est scellé.,Az átjáró bezárult.,Il portale è stato sigillato,ポータルは封印された,차원문은 봉인되었다,Het portaal is verzegeld,Portalen har blitt forseglet,Portal został zapieczętowany,O portal foi selado,,Portalul a fost închis,Портал закрылся,Врата су затворена,Portalen har förseglats.,Geçit mühürlendi +Choose your fate,TXT_ACS_MAP35_1_CHOOS,,,,Vyber si svůj osud.,Vælg din skæbne,Wähle dein Schicksal,,Elektu vian fatalon.,Escoge tu destino,Escoge tú destino,Valitse kohtalosi,Choisissez votre sort.,Dönts sorsod felől,Scegli la tua sorte,運命を撰べ,그대의 운명을 정해라,Kies uw lot,Velg din skjebne,Wybierz swoje przeznaczenie,Escolha o seu destino,,Alegeți destinul,Сделай свой выбор,Донеси своју одлуку,Välj ditt öde,Kaderinizi seçin +The door is barred from the inside,TXT_ACS_MAP35_3_THEDO,,,,Dveře jsou zatarasené zevnitř.,Døren er spærret indefra,Die Tür ist von innen verriegelt,,La pordo estas barita interne.,La puerta está atrancada desde el interior,,Ovi on teljetty sisältä,Cette porte est bloquée de l'intérieur.,Az ajtót belülről torlaszolták el.,La porta è sbarrata da dentro,この扉は内側から塞がれている,이 문은 안에 빗장이 걸려있다,De deur is van binnenuit geblokkeerd.,Døren er sperret fra innsiden,Drzwi są zabarykadowane od środka,A porta está barrada por dentro,,Ușa e blocată dinăuntru,Дверь заблокирована изнутри,Врата су забрављена изнутра,Dörren är spärrad från insidan,Kapı içeriden kilitli. +Are you strong enough,TXT_ACS_MAP35_12_AREYO,,,,"Jsi dost siln@[adj_cs],",Er du stærk nok?,Bist du stark genug,,Ĉu vi estas sufiĉe forta,Eres lo suficientemente fuerte,,Olet riittävän vahva,Etes vous suffisamment fort,"Elég erős vagy,",Sei abbastanza forte,お前がどれだけ強かろうと,네 놈은 주인들을 대면할 힘이...,Ben je sterk genoeg,Er du sterk nok,Czy jesteś wystarczająco silny,Você é forte o suficiente,,Ești întradevăr suficient de puternic,"Достаточно ли ты силён,",Јеси ли довољно снажан,Är du stark nog?,Yeterince güçlü müsün? +To face your own masters?,TXT_ACS_MAP35_14_TOFAC,,,,čelit svým vlastním pánům?,Til at møde dine egne mestre?,Dich deinen eigenen Meistern zu stellen?,,por stari kontraŭ viaj propraj mastroj?,¿Para enfrentarte a tus maestros?,,kohtaamaan omat mestarisi?,pour faire face à vos maîtres?,Hogy saját mestereiddel nézz szembe?,Da affrontare i tuoi stessi maestri?,お前の師に立ち向かえるのか?,진심으로 있는 것인가?,Om je eigen meesters onder ogen te komen?,Til å møte dine egne mestere?,By stawić czoła swoim mistrzom?,Para enfrentar os seus próprios mestres?,,Să îți înfrunți proprii stăpâni?,чтобы сразиться со своими наставниками?,да се суочиш са својим господарима?,För att möta dina egna mästare?,Kendi efendilerinizle yüzleşmek için mi? +,,Hexen: Deathkings script texts,,,,,,,,,,,,,,,,,,,,,,,,, +You dare battle in the ready room?,TXT_ACS_MAP33_6_YOUDA,,,,Ty si dovoluješ rvát se v přípravné místnosti?,Tør du kæmpe i beredskabsrummet?,Du wagst es im Bereitschaftsraum zu kämpfen?,,Vi aŭdacas batali en la pretĉambro?,¿Te atreves a luchar en la sala de preparación?,,Kuinka kehtaat taistella valmistautumishuoneessa?,Vous osez faire escarmouche dans la salle de préparation?,Hogy merészelsz harcolni a váróteremben?,Hai il coraggio di combattere in questa sala?,挑戦する準備は整ったか?,감히 준비의 방에서 전투를 벌이다니...,Durf jij te vechten in de readyroom?,Våger du å kjempe i det klare rommet?,Śmiesz walczyć w pokoju przygotowań?,Como ousa batalhar na sala de espera?,,Îndrăznești să lupți în camera de așteptare?,Ты посмел сражаться в комнате ожидания?,Усуђујеш се борити у припремној соби?,Vågar du slåss i det färdiga rummet?,Hazırlanma odasında savaşmaya mı cüret ediyorsun? +"For that, you shall die!",TXT_ACS_MAP33_7_FORTH,,,,Pro to zemřeš!,For det skal du dø!,Dafür sollst du sterben!,,"Pro tio, vi mortos!","Por eso, ¡deberás morir!",,Siitä hyvästä kuolet!,"Pour cette insulte, vous trépasserez!",Ezért meghalsz!,"Per questo, morirai!",ならば、死へ進め!,죽어서 값을 치러라!,Daarvoor zal je sterven!,For det skal du dø!,Umrzesz za to!,Você morrerá por isso!,,"Pentru asta, vei muri!",Так умри же!,За то ћеш умрети!,För det ska du dö!,Bunun için öleceksin! +The waterfall is open,TXT_ACS_MAP41_6_THEWA,,,,Vodopád je otevřen.,Vandfaldet er åbent,Der Wasserfall ist geöffnet,,La akvofalo estas malferma.,La cascada se ha abierto,,Vesiputous on auki,La cascade s'est ouverte.,A vizesés nyitva,La cascata è aperta,滝 は開いた,폭포가 멈췄다,De waterval is open,Fossen er åpen,Wodospad jest otwarty,A cascata está aberta,,Cascada e deschisă,Поток воды остановлен,Водопад је отворен,Vattenfallet är öppet,Şelale açık +The waterfall is blocked,TXT_ACS_MAP41_7_THEWA,,,,Vodopád je zatarasen.,Vandfaldet er blokeret,Der Wasserfall ist blockiert,,La akvofalo estas barita.,La cascada está bloqueada,,Vesiputous on tukittu,La cascade est bloquée.,A vizesés zárva,La cascata è bloccata,滝 は塞がっている,폭포에 의해 막혔다,De waterval is geblokkeerd,Fossen er blokkert,Wodospad jest zablokowany,A cascata está bloqueada,,Cascada e închisă,Поток воды преграждает путь,Водопад је блокиран,Vattenfallet är blockerat,Şelale tıkalı +A door has opened in the chapel,TXT_ACS_MAP41_8_ADOOR,,,,Dveře se otevřely v kapli.,Der er åbnet en dør i kapellet,Eine Tür in der Kapelle hat sich geöffnet,,Pordo malfermis en la kapelo.,Una puerta se abrió en la Capilla,,Ovi on avautunut kappelissa,Une porte s'est ouverte dans la chapelle.,Egy ajtó kitárult a kápolnában,Una porta si è aperta nella cappella,庵寺 への扉が開いた,교외 근처에서 문이 열렸다,Een deur is geopend in de kapel,En dør har åpnet seg i kapellet,Drzwi w kaplicy zostały otwarte,Uma porta se abriu na capela,,O ușă s-a deschis în capelă,Дверь открылась в часовне,Врата су се отворила у катедрали,En dörr har öppnats i kapellet.,Şapelde bir kapı açıldı. +Now that's odd...,TXT_ACS_MAP42_4_NOWTH,,,,Tak to je divné...,Det er mærkeligt...,Hm. Das ist merkwürdig...,,Nun tio estas stranga...,Eso es extraño...,,Onpa kummallista...,Ca c'est étrange....,Ez felettébb különös...,Questo sì che è strano...,何かがおかしい...,무언가가 이상하다...,Dat is vreemd....,Det var merkelig...,Dziwne...,Que estranho...,,Asta e ciudat...,Как странно...,То је чудно...,Det där är konstigt...,İşte bu garip. +Three more parts of the puzzle remain,TXT_ACS_MAP44_1_THREE,,,,Zbývají tři části rébusu.,Der er endnu tre dele af gåden tilbage,Drei weitere Teile des Rätsels verbleiben,,Nur tri partoj de la puzlo restas.,Quedan tres partes más del acertijo,,Kolme pulman palasta jäljellä,Trois parties du puzzle restent à résoudre.,Három rész maradt a rejtvényből,Rimangono altre tre parti del puzzle,パズルの部品は残り 3つ,3개의 수수께끼가 아직 풀리지 않았다,Er blijven nog drie onderdelen van de puzzel over,Tre deler av puslespillet gjenstår,Pozostały jeszcze trzy części zagadki,Faltam mais três partes do quebra-cabeça,,Trei părți din puzzle încă rămân,Остались три части головоломки,Остају још три дела загонетке ,Det återstår tre delar av pusslet.,Bulmacanın üç parçası daha kaldı. +Two more parts of the puzzle remain,TXT_ACS_MAP44_2_TWOMO,,,,Zbývají dvě části rébusu.,Der er endnu to dele af puslespillet tilbage,Zwei weitere Teile des Rätsels verbleiben,,Nur du partoj de la puzlo restas.,Quedan dos partes más del acertijo,,Kaksi pulman palasta jäljellä,Deux parties du puzzle restent à résoudre.,Kettő rész maradt a rejtvényből,Rimangono altre due parti del puzzle,パズルの部品は残り 2つ,2개의 수수께끼가 아직 풀리지 않았다,Twee andere delen van de puzzel blijven over,To deler av puslespillet gjenstår,Pozostały jeszcze dwie części zagadki,Faltam mais duas partes do quebra-cabeça,,Două părți din puzzle încă rămân,Остались две части головоломки,Остају још два дела загонетке,Ytterligare två delar av pusslet återstår,Bulmacanın iki parçası daha kaldı +One more part of the puzzle remains,TXT_ACS_MAP44_3_ONEMO,,,,Zbývá jedna část rébusu.,Der er endnu en del af puslespillet tilbage,Ein weiteres Teil des Rätsels ist übrig,,Nur unu parto de la puzlo restas.,Queda una parte más del acertijo,,Yksi pulman palanen jäljellä,Il reste une partie du puzzle à résoudre.,Egy rész maradt a rejtvényből,Rimane un'altra parte del puzzle,パズルの部品は残り 1つ,마지막 수수께끼가 아직 풀리지 않았다,Nog een deel van de puzzel blijft over,En del av puslespillet gjenstår,Pozostała jeszcze jedna część zagadki,Falta mais uma parte do quebra-cabeça,,O parte din puzzle încă rămâne,Осталась одна часть головоломки,Остаје још један део загонетке,Ytterligare en del av pusslet återstår,Bulmacanın bir parçası daha kaldı +The puzzle is complete,TXT_ACS_MAP44_4_THEPU,,,,Rébus je kompletní.,Puslespillet er færdigt,Das Rätsel ist abgeschlossen,,La puzlo estas kompleta.,El acertijo está completo,,Pulma on ratkaistu,Le puzzle est résolu.,A rejtvény végleg megoldódott,Il puzzle è completo,パズルは完成した,모든 수수께끼가 풀렸다,De puzzel is compleet,Puslespillet er komplett,Zagadka ukończona,O quebra-cabeça está concluído,,Puzzle-ul e rezolvat,Головоломка разгадана,Загонетка је решена,Pusslet är komplett,Bulmaca tamamlandı +You have not completed the puzzle,TXT_ACS_MAP44_6_YOUHA,,,,Nesplnil jsi rébus.,Du har ikke fuldført puslespillet,Du hast das Rätsel noch nicht gelöst,,Vi ne kompletis la puzlon.,No has completado el acertijo,,Et ole ratkaissut pulmaa,Vous n'avez pas résolu le puzzle.,Nem fejtetted meg a rejtvényt,Non hai completato il puzzle,パズルはまだ完成していない,모든 수수께끼를 풀지 못했다,Je hebt de puzzel nog niet voltooid.,Du har ikke fullført puslespillet,Nie ukończyłeś zagadki,Você não concluiu o quebra-cabeça,,Nu ai rezolvat puzzle-ul,Головоломка не разгадана,Нисте решили загонетку,Du har inte fullbordat pusslet,Bulmacayı tamamlamadınız +The floor is not safe!,TXT_ACS_MAP44_8_THEFL,,,,Podlaha není bezpečná!,Gulvet er ikke sikkert!,Der Boden hier ist nicht sicher!,,La planko ne estas sendanĝera!,¡El suelo no es seguro!,,Kerros ei ole turvallinen!,Le sol est dangereux!,A padló nem biztonságos!,Il pavimento è pericoloso!,この場は安全ではない!,이 층은 안전하지 않다!,De vloer is niet veilig!,Gulvet er ikke trygt!,Ta podłoga nie jest bezpieczna!,O chão não está seguro!,,Podeaua nu e sigură!,Пол совсем прогнил!,Под није безбедан!,Golvet är inte säkert!,Zemin güvenli değil! +One third of the puzzle is solved,TXT_ACS_MAP44_10_ONETH,,,,Jedna třetina rébusu je vyřešena.,En tredjedel af puslespillet er løst,Ein Drittel des Rätsels ist gelöst,,Unu triono de la puzlo estas solvita.,Un tercio del acertijo se ha resuelto,,Kolmannes pulmasta on ratkaistu,Un tiers du puzzle à été résolu,A rejtvény egyharmada megoldásra került,Un terzo del puzzle è stato risolto,パズルの 三分の一 が解かれた,수수께끼의 3분의 1이 풀렸다,Een derde van de puzzel is opgelost.,En tredjedel av puslespillet er løst,Jedna trzecia zagadki rozwiązana,Um terço do quebra-cabeça foi resolvido,,O treime din puzzle e rezolvată,Одна треть головоломки разгадана,Трећина загонетке је решена,En tredjedel av pusslet är löst,Bulmacanın üçte biri çözüldü +Two thirds of the puzzle is solved,TXT_ACS_MAP44_11_TWOTH,,,,Dvě třetiny rébusu jsou vyřešeny.,To tredjedele af puslespillet er løst,Zwei Drittel des Rätsels sind gelöst,,Du trionoj de la puzlo estas solvita.,Dos tercios del acertijo se han resuelto,,Kaksi kolmannesta pulmasta on ratkaistu,Deux tiers du puzzle ont été résolus,A rejtvény kétharmada megoldásra került,Due terzi del puzzle sono stati risolto,パズルの 三分の二 が解かれた,수수께끼의 3분의 2가 풀렸다,Tweederde van de puzzel is opgelost,To tredjedeler av puslespillet er løst.,Dwie trzecie zagadki rozwiązane,Dois terços do quebra-cabeça foi resolvido,,Două treimi din puzzle sunt rezolvate,Две трети головоломки разгаданы,Две трећине загонетке су решене,Två tredjedelar av pusslet är löst.,Bulmacanın üçte ikisi çözüldü You hear a platform moving in the distance,TXT_ACS_MAP45_1_YOUHE,,,,Slyšíš v dálce pohybující se plošinu.,Du hører en platform bevæge sig i det fjerne,"Du hörst, wie sich in der Ferne eine Platform bewegt",,Vi aŭdas plataĵon movantan malproksime.,Escuchas una plataforma moverse a la distancia,,Kuulet lavan liikkuvan etäällä,Vous entendez une plateforme se déplacer au loin,Egy emelvény mozgását hallod a távolban,Senti una piattaforma muoversi in lontananza,昇降機の音が遠くで聞こえる,멀리서 보행판이 움직이는 소리가 들려왔다,Je hoort een platform bewegen in de verte,Du hører en plattform bevege seg i det fjerne,Słyszysz odgłos poruszającej się w oddali platformy,Você ouve de longe uma plataforma se movendo,,Auzi o platformă mișcându-se în depărtare,"Неподалёку раздаётся звук -движущейся деревянной площадки",Чујете како се платформа помера у даљини,Uzakta bir platformun hareket ettiğini duyuyorsunuz. +движущейся деревянной площадки",Чујете како се платформа помера у даљини,Du hör en plattform som rör sig på avstånd.,Uzakta bir platformun hareket ettiğini duyuyorsunuz. It is done...,TXT_ACS_MAP46_0_ITISD,,,,Je to dokonáno...,Det er gjort...,Es ist getan...,,Ĝi estas farita...,Está terminado...,,Se on tehty...,C'est terminé...,Készen van...,È fatto...,これで完了だ...,이제 끝났다...,Het is gebeurd,Det er gjort...,"Zrobione... -",Pronto...,,E gata...,Готово...,Готово је...,Bitti... -You have not completed the puzzle,TXT_ACS_MAP46_1_YOUHA,,,,Nesplnil@[ao_cs] jsi rébus.,Du har ikke løst puslespillet,Du hast das Rätsel noch nicht gelöst,,Vi ne kompletis la puzlon.,No has completado el acertijo,,Et ole ratkaissut pulmaa,Vous n'avez pas résolu le puzzle.,Nem fejtetted meg a rejtvényt.,Non hai completato il puzzle,パズルはまだ完成していない,모든 수수께끼를 풀지 못했다,Je hebt de puzzel nog niet voltooid...,Du har ikke fullført puslespillet,Nie ukończyłeś zagadki,Você não terminou o quebra-cabeça,,Nu ai rezolvat puzzle-ul,Головоломка не разгадана,Ниси решио загонетку,Bulmacayı tamamlamadınız -I'm warning you...,TXT_ACS_MAP46_2_IMWAR,,,,Varuju tě...,Jeg advarer dig...,Ich warne dich...,,Mi avertas vin...,Te lo advierto...,,Varoitan sinua...,Je vous avertis...,Figyelmeztetlek...,Ti avverto...,お前に警告しよう...,나는 경고했다...,Ik waarschuw je...,Jeg advarer deg...,Ostrzegam cię...,Estou te avisando...,,Te avertizez...,Я тебя предупреждаю...,Упозоравам те...,Seni uyarıyorum. -"Stubborn, aren't you?",TXT_ACS_MAP46_3_STUBB,,,,"Ty jsi ale tvrdohlav@[adj_cs], ne?","Du er stædig, ikke sandt?","Du bist aber stur, was?",,"Vi estas obstina, ĉu ne?","Eres obstinado, ¿verdad?",,Oletpa itsepäinen,"Obstiné, n'est-ce pas?","Makacs vagy, ugye?",Sei proprio così testardo?,頑固だと、自らも思わないか?,정말 끈질기군.,"Koppig, nietwaar?","Du er sta, ikke sant?","Jesteś uparty, prawda?","Você é teimos@[ao_ptb], não é mesmo?",,"Încăpățânat, nu-i așa?",Не слишком ли ты упрямый?,"Тврдоглав си, зар не?","İnatçısın, değil mi?" -"And stupid, too",TXT_ACS_MAP46_4_ANDST,,,,A taky hloup@[adj_cs].,Og også dum,Und auch noch dumm,,Kaj ankaŭ stulta.,"Y estúpido, también",,Ja vieläpä tyhmä,"Et stupide, aussi.",És oktondi is.,"E stupido, pure",そして、あまりにも愚か者だ,어리석기도 하고.,En ook dom,Og dum også.,Głupi też,E estúpid@[ao_ptb] também,,"Și prost, pe deasupra",И не слишком-то разумный!,А још си и глуп,Ve de aptal. -One fourth of this puzzle is complete,TXT_ACS_MAP46_8_ONEFO,,,,Jedna čtvrtina rébusu je vyřešena.,En fjerdedel af dette puslespil er fuldført,Ein Viertel des Rätsels ist gelöst,,Unu kvarono de la puzlo estas kompleta.,Un cuarto del acertijo se ha resuelto,,Neljännes pulmasta on ratkaistu,Un quart du puzzle à été résolu,Egy negyede e rejtvénynek megvan.,Un quarto del puzzle è completo,パズルの 四分の一 が解かれた,수수께끼의 4분의 1만 풀렸다,Een vierde van deze puzzel is compleet,En fjerdedel av dette puslespillet er ferdig,Jedna czwarta tej zagadki ukończona,Um quarto deste quebra-cabeça está completo,,O pătrime din puzzle e rezolvată,Одна четвёртая этой головоломки разгадана,Четвртина загонетке је решена,Bu bulmacanın dörtte biri tamamlandı -Bad choice...,TXT_ACS_MAP46_9_BADCH,,,,Špatná volba.,Dårligt valg...,Falsche Wahl...,,Malbona elekto...,Mala decisión...,,Huono valinta...,Mauvaise décision...,Rossz választás...,Scelta sbagliata...,拙い選択だ...,서투른 선택이다...,Slechte keuze....,Dårlig valg...,Zły wybór...,Péssima escolha...,,Proastă alegere...,Плохой выбор...,Лош избор...,Kötü seçim... -The symbols are not aligned,TXT_ACS_MAP47_2_THESY,,,,Symboly nejsou zarovnány.,Symbolerne er ikke på linje med hinanden.,Die Symbole sind nicht ausgerichtet,,La simboloj ne estas liniiga.,Los símbolos no están alineados,,Symbolit eivät ole järjestyksessä,Les symboles ne sont pas alignés.,A jelek nincsenek vonalban,I simboli non sono allineati,シンボルが揃っていない,상징이 정렬되지 않았다,De symbolen zijn niet uitgelijnd,Symbolene er ikke på linje.,Symbole nie są wyrównane,Os símbolos não estão alinhados,,Simbolurile nu sunt aliniate,Символы не совпадают,Симболи нису поравнати,Semboller aynı hizada değil -The door won't open from this side,TXT_ACS_MAP48_2_THEDO,,,,Dveře se z této strany neotevřou.,Døren kan ikke åbnes fra denne side.,Die Tür kann sich von dieser Seite nicht öffnen,,La pordo ne malfermiĝas.,La puerta no abrirá por este lado,,Ovi ei aukea tältä puolelta,La porte ne s'ouvre pas de ce côté.,Az ajtó nem fog kinyílni innen.,La porta non si apre da questo lato,扉はこちら側から開けられない,이 문은 이 방향으로는 열리지 않는다,De deur gaat niet open van deze kant,Døren kan ikke åpnes fra denne siden,Drzwi nie otworzą się z tej strony,A porta não se abrirá deste lado,,Ușile nu se vor deschide de pe partea asta,С этой стороны дверь не открыть,Врата неће да се отворе са стране,Kapı bu taraftan açılmıyor. -The door is barred from the outside,TXT_ACS_MAP50_1_THEDO,,,,Dveře jsou zatarasené zvenku.,Døren er spærret udefra,Die Tür ist von außen verriegelt,,La pordo estas barita ekstere.,La puerta está atrancada por fuera,,Ovi on teljetty ulkopuolelta,Cette porte est bloquée de l'extérieur.,Az ajtó kívülről van eltorlaszolva.,La porta è sbarrata da fuori,この扉は外側から塞がれている,이 문은 바깥에 빗장이 걸려있다,De deur is van buitenaf uitgesloten,Døren er sperret fra utsiden,Drzwi są zabarykadowane od zewnątrz,A porta está barrada por fora,,Ușa e încuiată pe dinafară,Дверь заблокирована снаружи,Врата су блокирана споља,Kapı dışarıdan parmaklıklı. -Sacrilege !,TXT_ACS_MAP51_5_SACRI,,,,Svatokrádež!,Helligbrøde!,Gotteslästerung!,,Sakrilegio !,¡Sacrilegio!,,Pyhäinhäväistys !,Sacrilège!,Szentségtörés!,Sacrilegio !,罰当たりが!,신성모독이다!,Heiligschennis!,Helligbrøde!,Świętokradztwo !,Sacrilégio!,,Sacrilegiu!,Святотатство!,Светогрђе !,Kutsala saygısızlık! -You have defiled Eric's tomb !!,TXT_ACS_MAP51_6_YOUHA,,,,Znesvětil@[ao_cs] jsi Erikovu hrobku!!,Du har besudlet Erics grav!!,Du hast Erics Gruft entehrt!!,,Vi malpurigis la tombon de Eric !!,¡Has profanado la tumba de Erick!,,Olet turmellut Ericin haudan !!,Vous avez vandalisé la tombe d'Eric!,Megszentségtelenítetted Eric sírját!,Hai profanato la tomba di Eric !!,貴様はエリックの墓を荒らしたな!!,네 놈은 성 에릭의 무덤을 더렵혔다!!,Je hebt Eric's graf bevlekt!!,Du har vanhelliget Erics grav !!!,Zhańbiłeś grób Erica !!,Você violou a tumba de Eric!,,Ai profanat mormântul lui Eric!!,Ты осквернил@[ao_rus] могилу Эрика!!,Оскрнавио си Ерикову гробницу !!,Eric'in mezarını kirlettin! -And now you die !!!,TXT_ACS_MAP51_7_ANDNO,,,,Teď zemřeš!!!,Og nu skal du dø!!!!,Und nun stirbst du!,,Kaj nun vi mortas !!!,¡Y ahora morirás!,,Ja nyt sinä kuolet !!!,"Pour cela, vous allez mourir!",És most meghalsz!,E ora muori !!!,万死に値する!!!,그 댓가로 목숨을 바쳐라!!!,En nu ga je dood!!!!!,Og nå dør du!!!,I teraz zginiesz !!!,E agora você morrerá!!!,,"Iar acum, mori!!",И умрёшь за это страшной смертью!!!,И због тога ћеш умрети !!!,Ve şimdi öleceksin!!! -One third of the puzzle is solved,TXT_ACS_MAP51_8_ONETH,,,,Jedna třetina rébusu je vyřešena.,En tredjedel af gåden er løst,Ein Drittel des Rätsels ist gelöst,,Unu triono de la puzlo estas solvita.,Un tercio del acertijo se ha resuelto,,Kolmannes pulmasta on ratkaistu,Un tiers du puzzle à été résolu,A rejtvény egyharmada megoldásra került.,Un terzo del puzzle è stato risolto,パズルの 三分の一 が解かれた,수수께끼의 3분의 1이 풀렸다,Een derde van de puzzel is opgelost.,En tredjedel av gåten er løst,Jedna trzecia zagadki rozwiązana,Um terço do quebra-cabeça foi resolvido,,O treime din puzzle e rezolvată,Одна треть головоломки разгадана,Трећина загонетке је решена,Bulmacanın üçte biri çözüldü. -Two thirds of the puzzle is solved,TXT_ACS_MAP51_9_TWOTH,,,,Dvě třetiny rébusu jsou vyřešeny.,To tredjedele af gåden er løst,Zwei Drittel des Rätsels sind gelöst,,Du trionoj de la puzlo estas solvita.,Dos tercios del acertijo se han resuelto,,Kaksi kolmannesta pulmasta on ratkaistu,deux tiers du puzzle ont été résolus,A rejtvény kétharmada megoldásra került.,Due terzi del puzzle è stato risolto,パズルの 三分の二 が解かれた,수수께끼의 3분의 2가 풀렸다,Tweederde van de puzzel is opgelost,To tredjedeler av puslespillet er løst.,Dwie trzecie zagadki rozwiązane,Dois terços do quebra-cabeça foi resolvido,,Două treimi din puzzle sunt rezolvate,Две трети головоломки разгаданы,Две трећине загонетке су решене,Bulmacanın üçte ikisi çözüldü -The crypt is open,TXT_ACS_MAP51_10_THECR,,,,Krypta je otevřena.,Krypten er åben,Die Gruft ist offen,,La kripto estas malfermita.,La cripta ahora está abierta,,Krypta on auki,La crypte est ouverte,A kripta kinyílt.,La cripta è aperta,地下聖堂 が開いた,지하 묘실의 입구가 열렸다.,De crypte is open,Krypten er åpen,Krypta jest otwarta,A cripta está aberta,,Cripta e deschisă,Склеп открыт,Гробница је отворена,Mahzen açık -Beware the spider's tomb,TXT_ACS_MAP51_11_BEWAR,,,,Vyvaruj se pavoučí hrobky.,Pas på edderkoppens grav,Hüte dich vor dem Grab der Spinne,,Singardu en la tombo de la araneo.,Cuidado con la tumba de la araña,,Varo hämähäkin hautaa,Attention à la tombe de l'araignée.,Óvakodj a pók sírjától!,Attento alla tomba del ragno,スパイダーの墓,거미의 무덤을 조심하라,Pas op voor het graf van de spin,Se opp for edderkoppens grav,Strzeż się grobowca pająków,Cuidado com a tumba da aranha,,Păzește-te de mormântul păianjenului,Опасайся гробницы паука,Чувај се паукове гробнице,Örümceğin mezarına dikkat edin +",Pronto...,,E gata...,Готово...,Готово је...,Det är gjort...,Bitti... +You have not completed the puzzle,TXT_ACS_MAP46_1_YOUHA,,,,Nesplnil@[ao_cs] jsi rébus.,Du har ikke løst puslespillet,Du hast das Rätsel noch nicht gelöst,,Vi ne kompletis la puzlon.,No has completado el acertijo,,Et ole ratkaissut pulmaa,Vous n'avez pas résolu le puzzle.,Nem fejtetted meg a rejtvényt.,Non hai completato il puzzle,パズルはまだ完成していない,모든 수수께끼를 풀지 못했다,Je hebt de puzzel nog niet voltooid...,Du har ikke fullført puslespillet,Nie ukończyłeś zagadki,Você não terminou o quebra-cabeça,,Nu ai rezolvat puzzle-ul,Головоломка не разгадана,Ниси решио загонетку,Du har inte fullbordat pusslet.,Bulmacayı tamamlamadınız +I'm warning you...,TXT_ACS_MAP46_2_IMWAR,,,,Varuju tě...,Jeg advarer dig...,Ich warne dich...,,Mi avertas vin...,Te lo advierto...,,Varoitan sinua...,Je vous avertis...,Figyelmeztetlek...,Ti avverto...,お前に警告しよう...,나는 경고했다...,Ik waarschuw je...,Jeg advarer deg...,Ostrzegam cię...,Estou te avisando...,,Te avertizez...,Я тебя предупреждаю...,Упозоравам те...,Jag varnar dig...,Seni uyarıyorum. +"Stubborn, aren't you?",TXT_ACS_MAP46_3_STUBB,,,,"Ty jsi ale tvrdohlav@[adj_cs], ne?","Du er stædig, ikke sandt?","Du bist aber stur, was?",,"Vi estas obstina, ĉu ne?","Eres obstinado, ¿verdad?",,Oletpa itsepäinen,"Obstiné, n'est-ce pas?","Makacs vagy, ugye?",Sei proprio così testardo?,頑固だと、自らも思わないか?,정말 끈질기군.,"Koppig, nietwaar?","Du er sta, ikke sant?","Jesteś uparty, prawda?","Você é teimos@[ao_ptb], não é mesmo?",,"Încăpățânat, nu-i așa?",Не слишком ли ты упрямый?,"Тврдоглав си, зар не?","Du är envis, eller hur?","İnatçısın, değil mi?" +"And stupid, too",TXT_ACS_MAP46_4_ANDST,,,,A taky hloup@[adj_cs].,Og også dum,Und auch noch dumm,,Kaj ankaŭ stulta.,"Y estúpido, también",,Ja vieläpä tyhmä,"Et stupide, aussi.",És oktondi is.,"E stupido, pure",そして、あまりにも愚か者だ,어리석기도 하고.,En ook dom,Og dum også.,Głupi też,E estúpid@[ao_ptb] também,,"Și prost, pe deasupra",И не слишком-то разумный!,А још си и глуп,Och dum också.,Ve de aptal. +One fourth of this puzzle is complete,TXT_ACS_MAP46_8_ONEFO,,,,Jedna čtvrtina rébusu je vyřešena.,En fjerdedel af dette puslespil er fuldført,Ein Viertel des Rätsels ist gelöst,,Unu kvarono de la puzlo estas kompleta.,Un cuarto del acertijo se ha resuelto,,Neljännes pulmasta on ratkaistu,Un quart du puzzle à été résolu,Egy negyede e rejtvénynek megvan.,Un quarto del puzzle è completo,パズルの 四分の一 が解かれた,수수께끼의 4분의 1만 풀렸다,Een vierde van deze puzzel is compleet,En fjerdedel av dette puslespillet er ferdig,Jedna czwarta tej zagadki ukończona,Um quarto deste quebra-cabeça está completo,,O pătrime din puzzle e rezolvată,Одна четвёртая этой головоломки разгадана,Четвртина загонетке је решена,En fjärdedel av pusslet är klart.,Bu bulmacanın dörtte biri tamamlandı +Bad choice...,TXT_ACS_MAP46_9_BADCH,,,,Špatná volba.,Dårligt valg...,Falsche Wahl...,,Malbona elekto...,Mala decisión...,,Huono valinta...,Mauvaise décision...,Rossz választás...,Scelta sbagliata...,拙い選択だ...,서투른 선택이다...,Slechte keuze....,Dårlig valg...,Zły wybór...,Péssima escolha...,,Proastă alegere...,Плохой выбор...,Лош избор...,Dåligt val...,Kötü seçim... +The symbols are not aligned,TXT_ACS_MAP47_2_THESY,,,,Symboly nejsou zarovnány.,Symbolerne er ikke på linje med hinanden.,Die Symbole sind nicht ausgerichtet,,La simboloj ne estas liniiga.,Los símbolos no están alineados,,Symbolit eivät ole järjestyksessä,Les symboles ne sont pas alignés.,A jelek nincsenek vonalban,I simboli non sono allineati,シンボルが揃っていない,상징이 정렬되지 않았다,De symbolen zijn niet uitgelijnd,Symbolene er ikke på linje.,Symbole nie są wyrównane,Os símbolos não estão alinhados,,Simbolurile nu sunt aliniate,Символы не совпадают,Симболи нису поравнати,Symbolerna är inte i linje med varandra.,Semboller aynı hizada değil +The door won't open from this side,TXT_ACS_MAP48_2_THEDO,,,,Dveře se z této strany neotevřou.,Døren kan ikke åbnes fra denne side.,Die Tür kann sich von dieser Seite nicht öffnen,,La pordo ne malfermiĝas.,La puerta no abrirá por este lado,,Ovi ei aukea tältä puolelta,La porte ne s'ouvre pas de ce côté.,Az ajtó nem fog kinyílni innen.,La porta non si apre da questo lato,扉はこちら側から開けられない,이 문은 이 방향으로는 열리지 않는다,De deur gaat niet open van deze kant,Døren kan ikke åpnes fra denne siden,Drzwi nie otworzą się z tej strony,A porta não se abrirá deste lado,,Ușile nu se vor deschide de pe partea asta,С этой стороны дверь не открыть,Врата неће да се отворе са стране,Dörren öppnas inte från den här sidan.,Kapı bu taraftan açılmıyor. +The door is barred from the outside,TXT_ACS_MAP50_1_THEDO,,,,Dveře jsou zatarasené zvenku.,Døren er spærret udefra,Die Tür ist von außen verriegelt,,La pordo estas barita ekstere.,La puerta está atrancada por fuera,,Ovi on teljetty ulkopuolelta,Cette porte est bloquée de l'extérieur.,Az ajtó kívülről van eltorlaszolva.,La porta è sbarrata da fuori,この扉は外側から塞がれている,이 문은 바깥에 빗장이 걸려있다,De deur is van buitenaf uitgesloten,Døren er sperret fra utsiden,Drzwi są zabarykadowane od zewnątrz,A porta está barrada por fora,,Ușa e încuiată pe dinafară,Дверь заблокирована снаружи,Врата су блокирана споља,Dörren är spärrad från utsidan,Kapı dışarıdan parmaklıklı. +Sacrilege !,TXT_ACS_MAP51_5_SACRI,,,,Svatokrádež!,Helligbrøde!,Gotteslästerung!,,Sakrilegio !,¡Sacrilegio!,,Pyhäinhäväistys !,Sacrilège!,Szentségtörés!,Sacrilegio !,罰当たりが!,신성모독이다!,Heiligschennis!,Helligbrøde!,Świętokradztwo !,Sacrilégio!,,Sacrilegiu!,Святотатство!,Светогрђе !,Helgerån!,Kutsala saygısızlık! +You have defiled Eric's tomb !!,TXT_ACS_MAP51_6_YOUHA,,,,Znesvětil@[ao_cs] jsi Erikovu hrobku!!,Du har besudlet Erics grav!!,Du hast Erics Gruft entehrt!!,,Vi malpurigis la tombon de Eric !!,¡Has profanado la tumba de Erick!,,Olet turmellut Ericin haudan !!,Vous avez vandalisé la tombe d'Eric!,Megszentségtelenítetted Eric sírját!,Hai profanato la tomba di Eric !!,貴様はエリックの墓を荒らしたな!!,네 놈은 성 에릭의 무덤을 더렵혔다!!,Je hebt Eric's graf bevlekt!!,Du har vanhelliget Erics grav !!!,Zhańbiłeś grób Erica !!,Você violou a tumba de Eric!,,Ai profanat mormântul lui Eric!!,Ты осквернил@[ao_rus] могилу Эрика!!,Оскрнавио си Ерикову гробницу !!,Du har besudlat Erics grav!!,Eric'in mezarını kirlettin! +And now you die !!!,TXT_ACS_MAP51_7_ANDNO,,,,Teď zemřeš!!!,Og nu skal du dø!!!!,Und nun stirbst du!,,Kaj nun vi mortas !!!,¡Y ahora morirás!,,Ja nyt sinä kuolet !!!,"Pour cela, vous allez mourir!",És most meghalsz!,E ora muori !!!,万死に値する!!!,그 댓가로 목숨을 바쳐라!!!,En nu ga je dood!!!!!,Og nå dør du!!!,I teraz zginiesz !!!,E agora você morrerá!!!,,"Iar acum, mori!!",И умрёшь за это страшной смертью!!!,И због тога ћеш умрети !!!,Och nu dör du !!!,Ve şimdi öleceksin!!! +One third of the puzzle is solved,TXT_ACS_MAP51_8_ONETH,,,,Jedna třetina rébusu je vyřešena.,En tredjedel af gåden er løst,Ein Drittel des Rätsels ist gelöst,,Unu triono de la puzlo estas solvita.,Un tercio del acertijo se ha resuelto,,Kolmannes pulmasta on ratkaistu,Un tiers du puzzle à été résolu,A rejtvény egyharmada megoldásra került.,Un terzo del puzzle è stato risolto,パズルの 三分の一 が解かれた,수수께끼의 3분의 1이 풀렸다,Een derde van de puzzel is opgelost.,En tredjedel av gåten er løst,Jedna trzecia zagadki rozwiązana,Um terço do quebra-cabeça foi resolvido,,O treime din puzzle e rezolvată,Одна треть головоломки разгадана,Трећина загонетке је решена,En tredjedel av pusslet är löst,Bulmacanın üçte biri çözüldü. +Two thirds of the puzzle is solved,TXT_ACS_MAP51_9_TWOTH,,,,Dvě třetiny rébusu jsou vyřešeny.,To tredjedele af gåden er løst,Zwei Drittel des Rätsels sind gelöst,,Du trionoj de la puzlo estas solvita.,Dos tercios del acertijo se han resuelto,,Kaksi kolmannesta pulmasta on ratkaistu,deux tiers du puzzle ont été résolus,A rejtvény kétharmada megoldásra került.,Due terzi del puzzle è stato risolto,パズルの 三分の二 が解かれた,수수께끼의 3분의 2가 풀렸다,Tweederde van de puzzel is opgelost,To tredjedeler av puslespillet er løst.,Dwie trzecie zagadki rozwiązane,Dois terços do quebra-cabeça foi resolvido,,Două treimi din puzzle sunt rezolvate,Две трети головоломки разгаданы,Две трећине загонетке су решене,Två tredjedelar av pusslet är löst.,Bulmacanın üçte ikisi çözüldü +The crypt is open,TXT_ACS_MAP51_10_THECR,,,,Krypta je otevřena.,Krypten er åben,Die Gruft ist offen,,La kripto estas malfermita.,La cripta ahora está abierta,,Krypta on auki,La crypte est ouverte,A kripta kinyílt.,La cripta è aperta,地下聖堂 が開いた,지하 묘실의 입구가 열렸다.,De crypte is open,Krypten er åpen,Krypta jest otwarta,A cripta está aberta,,Cripta e deschisă,Склеп открыт,Гробница је отворена,Kryptan är öppen.,Mahzen açık +Beware the spider's tomb,TXT_ACS_MAP51_11_BEWAR,,,,Vyvaruj se pavoučí hrobky.,Pas på edderkoppens grav,Hüte dich vor dem Grab der Spinne,,Singardu en la tombo de la araneo.,Cuidado con la tumba de la araña,,Varo hämähäkin hautaa,Attention à la tombe de l'araignée.,Óvakodj a pók sírjától!,Attento alla tomba del ragno,スパイダーの墓,거미의 무덤을 조심하라,Pas op voor het graf van de spin,Se opp for edderkoppens grav,Strzeż się grobowca pająków,Cuidado com a tumba da aranha,,Păzește-te de mormântul păianjenului,Опасайся гробницы паука,Чувај се паукове гробнице,Akta dig för spindelns grav,Örümceğin mezarına dikkat edin You hear a platform rise outside,TXT_ACS_MAP51_13_YOUHE,,,,Slyšíš zvenku zvedající se platformu.,Du hører en platform rejse sig udenfor,"Du hörst, wie sich draußen eine Plattform erhebt",,Vi aŭdas plataĵon leviĝantan ekstere.,Escuchas una plataforma erguirse afuera,,Kuulet lavan kohoavan ulkopuolella,Vous entendez une platforme s'élever dehors,Egy emelvényt hallasz emelkedni odakinn,Senti una piattaforma alzarsi in lontananza,外で昇降機の音が聞こえる,밖에서 보행판이 올라오는 소리가 들려왔다,Je hoort een platform buiten opstijgen,Du hører en plattform stige utenfor,Słyszysz odgłos unoszącej się na zewnątrz platformy,Você ouve uma plataforma subir lá fora,,Auzi o platformă ridicându-se afară,"Снаружи слышен звук -поднимающегося камня",Чујете како се платформа диже споља,Dışarıda bir platformun yükseldiğini duyarsınız -Do you feel lucky?,TXT_ACS_MAP51_14_DOYOU,,,,"Zdá se ti, že máš štěstí?",Føler du dig heldig?,Denkst du das heute dein Glückstag ist?,,Ĉu vi sentas vin bonŝanca?,¿Te sientes afortunado?,,Tunnetko olosi onnekkaaksi?,Vous pensez être chanceux?,Szerencsésnek érzed magad?,Ti senti fortunato?,運が良かったと思うか?,그대는 운수가 좋은가?,Heb je geluk?,Føler du deg heldig?,Masz szczęście?,Está se sentindo com sorte?,,Te simți norocos?,Чувствуешь ли ты себя везучим?,Да ли се осећаш срећним?,Kendinizi şanslı mı hissediyorsunuz? -You guessed wrong!,TXT_ACS_MAP51_15_YOUGU,,,,To máš smůlu!,Du gættede forkert!,Du hast falsch geraten!,,Vi divenis malĝuste!,¡Adivinaste incorrectamente!,,Arvasi väärin!,Et bien non!,Hát rosszul érzed!,Non hai indovinato!,それは違うな!,잘못된 판단이다!,Je hebt het verkeerd geraden!,Du gjettet feil!,Źle zgadłeś!,Adivinhou errado!,,N-ai ghicit!,Неправильное предположение!,Погрешно си погодио!,Yanlış tahmin ettin! -Good guess,TXT_ACS_MAP51_16_GOODG,,,,Dobré zdání.,Godt gættet.,Gut geraten,,Bona diveno.,Buena elección,,Hyvä arvaus,Vous avez deviné!,Jól sejtetted,Hai indovinato,良い推測だ,옳은 판단이다,Goede gok,Godt gjettet,Dobrze zgadłeś,Certa resposta,,Ai ghicit,Правильное предположение,Добар погодак,İyi tahmin -Can you do all the scripting for my level?,TXT_ACS_MAP51_17_CANYO,,,,Můžeš všechno skriptování udělat za mě?,Kan du lave alt scripting til mit niveau?,Kannst du die Skripte für all meine Level schreiben?,,Ĉu vi povas fari ĉiom da la skriptoj por mia nivelo?,¿Podrías hacer todo el script para mi nivel?,,Voitko tehdä kaikki tasoni skriptaukset?,Vous pouvez faire tout le script de mon niveau?,Meg tudnád csinálni az egészt scriptelést a pályámhoz?,Puoi fare tutto lo scripting per il mio livello?,この階層を全て書き換える事は可能かな?,어쩔 수 없이 살아간다. 태어났기 때문에...,Kun je al het scripten doen voor mijn niveau?,Kan du gjøre alt skriptet for mitt nivå?,Czy możesz zrobić cały skrypt do mojego poziomu?,Poderia fazer todo o scripting da minha fase?,,Te poți ocupa de scripting pentru nivelul meu?,"Может, напишешь за меня все скрипты для моего уровня?",Можеш ли да напишеш све скриптове за мој ниво?,Benim seviyem için tüm senaryoyu yazabilir misin? -Don't touch my gloppy,TXT_ACS_MAP51_18_DONTT,,,,Nesahej mi na slimáka!,Rør ikke ved min gloppy,Berühr mein Ding nicht!,,Ne tuŝas mian gloppy-on.,No toques mi gloppy,,Älä koske mönjääni,Ne touche pas mon gloppy,Ne nyúlj a bizémhez,Non toccare la mia caramella,汚らしい手で触れるな,"에틴을 쳐죽인 것까지 신경 쓰다간, 걸을 수도 없을걸.",Raak mijn gloppy niet aan,Ikke rør min gloppy,Nie ruszaj moich słodyczy,Não toca no meu docinho!,,Nu-mi atinge bomboana,Не трогай мою вкусняшку,Не дирај мој слаткиш,Benim cıvıklığıma dokunma. -Vorpal ?!?!?!,TXT_ACS_MAP51_19_VORPA,,,,Šaršoun?!?!?!,,Tödlich ?!?!?!,,Vorpal ?!?!?!,¡¿¡¿¡¿ Vorpal ?!?!?!,,Tappava ?!?!?!,,,,ボーパル ?!?!?!,드래곤 슬레이어 인가?!,,,Śmiercionośny ?!?!?!,Vorpal?!?!?!,,Vorpal?!?!?!,Остренько???!!!,Вајтолни мач ?!?!?!,Vorpal?!?!?! -"Gimme some sugar, baby",TXT_ACS_MAP51_20_GIMME,,,,"Dej mi trochu cukru, zlato.","Giv mig noget sukker, baby","Gib mir etwas Zucker, Baby",,"Donu al mi iom da sukeron, knanjo.","Dame un poco de azúcar, baby","Dame algo de azúcar, bebe","Anna vähän sokeria, beibi",,"Tégy magadévá, kislány!",,砂糖が欲しいかい、ベイビー,등짝을 보자!...,"Geef me wat suiker, schatje.","Gi meg litt sukker, baby",Daj mi całusa skarbie,"Me dá um pouco de açúcar, baby",,"Dă-mi niște zahăr, dulceață","Подай-ка мне сахар, детка","Дај ми мало шећера, душо","Bana biraz şeker ver, bebeğim." -Duh-uhhh...,TXT_ACS_MAP51_21_DUHUH,,,,A jéje.,,,,Da-aaaa...,,,Daa-aaa....,,Nyílván...,,えぇーとぉー...,낙원이란 있을 수 없는거야.,,,Oooooo...,Dãããã-ããã...,,,Ага-а-а-а...,Дух-уххх...,Duh-uhhh... -Film in an hour?,TXT_ACS_MAP51_22_FILMI,,,,Film za hodinu?,Film om en time?,Film in einer Stunde?,,Kino post horo?,¿Película en una hora?,¿Una película en una hora?,Filmi tunnissa?,Un film dans une heure?,Egy film egy óra múlva?,Un film in un'ora?,数時間のフィルム?,신은 운명을 주셨죠. 만남이라는 운명을.,Film in een uur?,Film på en time?,Za godzinę film?,Quer ver um filme daqui a pouco?,,Film într-o oră?,Фильм за час?,Снимамо за сат времена?,Bir saat içinde film mi? -I don't even get my own tombstone - cf,TXT_ACS_MAP51_23_IDONT,,,,Ani nemám svůj vlastní náhrobek. -CF,Jeg får ikke engang min egen gravsten - cf,Ich bekomme noch nicht einmal meinen eigenen Grabstein - cf,,Mi ne eĉ ekhavis mian propran tombŝtonon. - cf,Ni siquiera tengo mi propia lápida - cf,,En saa edes omaa hautakiveäni - cf,J'ai même pas le droit à ma propre tombe - cf,Még saját sírt sem kaptam - cf,Non ho potuto avere la mia pietra tombale - cf,私は自分の墓標すら得られない - cf,내 묘비를 세우지도 않았네 -cf,Ik krijg niet eens mijn eigen grafsteen - cf,Jeg får ikke engang min egen gravstein - cf...,Nawet nie dostałem swojego nagrobka - cf,Eu nem ganhei a minha própria lápide - cf,,Nici măcar nu primesc propria piatră de mormânt - cf,У меня даже нет своего надгробия (К. Ф.),Ја ни немам свој надгробни споменик - cf,Kendi mezar taşımı bile alamıyorum - cf -Let no blood be spilt,TXT_ACS_MAP51_24_LETNO,,,,Nechť není prolita žádná krev.,Lad intet blod blive spildt,Lass kein Blut vergossen sein,,Lasu neniom da sango elflui.,Que no se derrame sangre,,Älköön yhtään verta vuodatettako,Qu'aucune goutte de sang ne soit tirée,Ne ontsunk ki vért,Si cerchi di non spargere sangue,血を零さないように,피 한 방울도 흘리지 말라,Laat geen bloed worden vergoten,La ikke noe blod bli spilt,Nie pozwól by krew została przelana,Que sangue nenhum seja derramado,,Fie ca sângele să nu fie vărsat,Да не прольётся кровь,Нека се не пролије крв,Kan dökülmesin -Let no hand be raised in anger,TXT_ACS_MAP51_25_LETNO,,,,Nechť není žádná ruka hněvem zvednuta.,Lad ingen hånd blive løftet i vrede,Lass keine Hand in Wut erhoben sein,,Lasu nenion manon estas levita pro kolero.,Que ninguna mano se levante con ira,,Ei yhtäkään kättä kohotettako vihassa,Qu'aucune main de se lève avec colère,Ne emeljünk kezet haragból,Si cerchi di non alzare le mani per rabbia,怒りで拳を振るわないように,분노하여 주먹을 휘두르지 말라,Laat geen hand worden opgestoken in woede...,La ingen hånd bli løftet i sinne,Nie pozwól by ręka została uniesiona w gniewie,Que mão nenhuma seja erguida por raiva,,Fie ca nicio mână să nu fie ridicată în furie,И да не поднимется рука во гневе,Нека се ни рука из беса не подигне,Öfkeyle el kaldırmayın -Who dares disturb our slumber?,TXT_ACS_MAP52_9_WHODA,,,,Kdo se opovažuje narušit náš spánek?,Hvem vover at forstyrre vores slummer?,Wer wagt es unseren Schlummer zu stören?,,Kiu aŭdacas interrompi nian dormon? ,¿Quién se atreve a perturbar nuestro sueño?,,Kuka kehtaa häiritä untamme?,Qui ose troubler notre sommeil?,Ki meri megzavarni a szunyókálásunkat?,Chi osa disturbare il nostro riposo?,誰が、我々の眠りを妨げる勇気があるかな?,감히 우리의 숙면을 방해하는가?,Wie durft onze slaap te verstoren?,Hvem våger å forstyrre vår søvn?,Kto śmie przeszkadzać nam w drzemce?,Quem ousa perturbar o nosso descanso?,,Cine cutează să-mi perturbe odihna?,Кто осмелился потревожить наш покой?,Ко се усуђује узнемиравати наш спокој?,Uykumuzu bölmeye kim cüret eder? -The way is open,TXT_ACS_MAP52_10_THEWA,,,,Cesta je otevřena.,Vejen er åben,Der Weg ist offen,,La vojo estas malfermita.,El camino está abierto,,Tie on auki,Le chemin est ouvert.,Az út kinyílt,La via è aperta,道は開いた,길이 열렸다,De weg is open,Veien er åpen,Droga jest otwarta,O caminho está aberto,,Calea e deschisă,Путь открыт,Пролаз је отворен,Yol açık -You have ,TXT_ACS_MAP53_2_YOUHA,,,,Zbývají ti ,Du har,Du hast,,Vi havas,Tienes,,Sinulla on,Vous avez,Már csak,Hai,スイッチはまだ,지금 ,Je hebt,Du har,Masz,Restam ainda,,Mai ai,Осталось,Остало је , -\x20switches left,TXT_ACS_MAP53_3_SWITC,,,,\x20spínače.,\x20kontakter tilbage,\x20Schalter übrig,,\x20ŝaltilojn ceterajn.,\x20interruptores restantes,\x20switches restantes,\x20vipua jäljellä,\x20boutons à trouver,\x20kallantyú van hátra,\x20interuttori rimanenti,残っている,개의 개폐기들이 남았다,\x20schakelaars over,\x20brytere igjen,\x20pozostałych przełączników,\x20interruptores,,\x20butoane rămase,\x20переключателей,\x20прекидача,\x20anahtarınız kaldı -You have only ,TXT_ACS_MAP53_4_YOUHA,,,,Zbývá ti jen ,Du har kun,Du hast nur,,Vi nur havas,Tienes solo,,Sinulla on vain,Vous avez seulement,Már csak,Hai solamente,スイッチは,이제 오로지 ,Je hebt alleen,Du har bare,Masz tylko,Resta somente,,Mai ai doar,Остался всего,Остао је само , +поднимающегося камня",Чујете како се платформа диже споља,Du hör en plattform stiga upp utanför.,Dışarıda bir platformun yükseldiğini duyarsınız +Do you feel lucky?,TXT_ACS_MAP51_14_DOYOU,,,,"Zdá se ti, že máš štěstí?",Føler du dig heldig?,Denkst du das heute dein Glückstag ist?,,Ĉu vi sentas vin bonŝanca?,¿Te sientes afortunado?,,Tunnetko olosi onnekkaaksi?,Vous pensez être chanceux?,Szerencsésnek érzed magad?,Ti senti fortunato?,運が良かったと思うか?,그대는 운수가 좋은가?,Heb je geluk?,Føler du deg heldig?,Masz szczęście?,Está se sentindo com sorte?,,Te simți norocos?,Чувствуешь ли ты себя везучим?,Да ли се осећаш срећним?,Känner du dig lycklig?,Kendinizi şanslı mı hissediyorsunuz? +You guessed wrong!,TXT_ACS_MAP51_15_YOUGU,,,,To máš smůlu!,Du gættede forkert!,Du hast falsch geraten!,,Vi divenis malĝuste!,¡Adivinaste incorrectamente!,,Arvasi väärin!,Et bien non!,Hát rosszul érzed!,Non hai indovinato!,それは違うな!,잘못된 판단이다!,Je hebt het verkeerd geraden!,Du gjettet feil!,Źle zgadłeś!,Adivinhou errado!,,N-ai ghicit!,Неправильное предположение!,Погрешно си погодио!,Du gissade fel!,Yanlış tahmin ettin! +Good guess,TXT_ACS_MAP51_16_GOODG,,,,Dobré zdání.,Godt gættet.,Gut geraten,,Bona diveno.,Buena elección,,Hyvä arvaus,Vous avez deviné!,Jól sejtetted,Hai indovinato,良い推測だ,옳은 판단이다,Goede gok,Godt gjettet,Dobrze zgadłeś,Certa resposta,,Ai ghicit,Правильное предположение,Добар погодак,Bra gissning,İyi tahmin +Can you do all the scripting for my level?,TXT_ACS_MAP51_17_CANYO,,,,Můžeš všechno skriptování udělat za mě?,Kan du lave alt scripting til mit niveau?,Kannst du die Skripte für all meine Level schreiben?,,Ĉu vi povas fari ĉiom da la skriptoj por mia nivelo?,¿Podrías hacer todo el script para mi nivel?,,Voitko tehdä kaikki tasoni skriptaukset?,Vous pouvez faire tout le script de mon niveau?,Meg tudnád csinálni az egészt scriptelést a pályámhoz?,Puoi fare tutto lo scripting per il mio livello?,この階層を全て書き換える事は可能かな?,어쩔 수 없이 살아간다. 태어났기 때문에...,Kun je al het scripten doen voor mijn niveau?,Kan du gjøre alt skriptet for mitt nivå?,Czy możesz zrobić cały skrypt do mojego poziomu?,Poderia fazer todo o scripting da minha fase?,,Te poți ocupa de scripting pentru nivelul meu?,"Может, напишешь за меня все скрипты для моего уровня?",Можеш ли да напишеш све скриптове за мој ниво?,Kan du göra alla skript för min nivå?,Benim seviyem için tüm senaryoyu yazabilir misin? +Don't touch my gloppy,TXT_ACS_MAP51_18_DONTT,,,,Nesahej mi na slimáka!,Rør ikke ved min gloppy,Berühr mein Ding nicht!,,Ne tuŝas mian gloppy-on.,No toques mi gloppy,,Älä koske mönjääni,Ne touche pas mon gloppy,Ne nyúlj a bizémhez,Non toccare la mia caramella,汚らしい手で触れるな,"에틴을 쳐죽인 것까지 신경 쓰다간, 걸을 수도 없을걸.",Raak mijn gloppy niet aan,Ikke rør min gloppy,Nie ruszaj moich słodyczy,Não toca no meu docinho!,,Nu-mi atinge bomboana,Не трогай мою вкусняшку,Не дирај мој слаткиш,Rör inte min glittriga,Benim cıvıklığıma dokunma. +Vorpal ?!?!?!,TXT_ACS_MAP51_19_VORPA,,,,Šaršoun?!?!?!,,Tödlich ?!?!?!,,Vorpal ?!?!?!,¡¿¡¿¡¿ Vorpal ?!?!?!,,Tappava ?!?!?!,,,,ボーパル ?!?!?!,드래곤 슬레이어 인가?!,,,Śmiercionośny ?!?!?!,Vorpal?!?!?!,,Vorpal?!?!?!,Остренько???!!!,Вајтолни мач ?!?!?!,,Vorpal?!?!?! +"Gimme some sugar, baby",TXT_ACS_MAP51_20_GIMME,,,,"Dej mi trochu cukru, zlato.","Giv mig noget sukker, baby","Gib mir etwas Zucker, Baby",,"Donu al mi iom da sukeron, knanjo.","Dame un poco de azúcar, baby","Dame algo de azúcar, bebe","Anna vähän sokeria, beibi",,"Tégy magadévá, kislány!",,砂糖が欲しいかい、ベイビー,등짝을 보자!...,"Geef me wat suiker, schatje.","Gi meg litt sukker, baby",Daj mi całusa skarbie,"Me dá um pouco de açúcar, baby",,"Dă-mi niște zahăr, dulceață","Подай-ка мне сахар, детка","Дај ми мало шећера, душо","Ge mig lite socker, baby","Bana biraz şeker ver, bebeğim." +Duh-uhhh...,TXT_ACS_MAP51_21_DUHUH,,,,A jéje.,,,,Da-aaaa...,,,Daa-aaa....,,Nyílván...,,えぇーとぉー...,낙원이란 있을 수 없는거야.,,,Oooooo...,Dãããã-ããã...,,,Ага-а-а-а...,Дух-уххх...,,Duh-uhhh... +Film in an hour?,TXT_ACS_MAP51_22_FILMI,,,,Film za hodinu?,Film om en time?,Film in einer Stunde?,,Kino post horo?,¿Película en una hora?,¿Una película en una hora?,Filmi tunnissa?,Un film dans une heure?,Egy film egy óra múlva?,Un film in un'ora?,数時間のフィルム?,신은 운명을 주셨죠. 만남이라는 운명을.,Film in een uur?,Film på en time?,Za godzinę film?,Quer ver um filme daqui a pouco?,,Film într-o oră?,Фильм за час?,Снимамо за сат времена?,Filma om en timme?,Bir saat içinde film mi? +I don't even get my own tombstone - cf,TXT_ACS_MAP51_23_IDONT,,,,Ani nemám svůj vlastní náhrobek. -CF,Jeg får ikke engang min egen gravsten - cf,Ich bekomme noch nicht einmal meinen eigenen Grabstein - cf,,Mi ne eĉ ekhavis mian propran tombŝtonon. - cf,Ni siquiera tengo mi propia lápida - cf,,En saa edes omaa hautakiveäni - cf,J'ai même pas le droit à ma propre tombe - cf,Még saját sírt sem kaptam - cf,Non ho potuto avere la mia pietra tombale - cf,私は自分の墓標すら得られない - cf,내 묘비를 세우지도 않았네 -cf,Ik krijg niet eens mijn eigen grafsteen - cf,Jeg får ikke engang min egen gravstein - cf...,Nawet nie dostałem swojego nagrobka - cf,Eu nem ganhei a minha própria lápide - cf,,Nici măcar nu primesc propria piatră de mormânt - cf,У меня даже нет своего надгробия (К. Ф.),Ја ни немам свој надгробни споменик - cf,Jag får inte ens min egen gravsten - cf,Kendi mezar taşımı bile alamıyorum - cf +Let no blood be spilt,TXT_ACS_MAP51_24_LETNO,,,,Nechť není prolita žádná krev.,Lad intet blod blive spildt,Lass kein Blut vergossen sein,,Lasu neniom da sango elflui.,Que no se derrame sangre,,Älköön yhtään verta vuodatettako,Qu'aucune goutte de sang ne soit tirée,Ne ontsunk ki vért,Si cerchi di non spargere sangue,血を零さないように,피 한 방울도 흘리지 말라,Laat geen bloed worden vergoten,La ikke noe blod bli spilt,Nie pozwól by krew została przelana,Que sangue nenhum seja derramado,,Fie ca sângele să nu fie vărsat,Да не прольётся кровь,Нека се не пролије крв,Låt inget blod spillas,Kan dökülmesin +Let no hand be raised in anger,TXT_ACS_MAP51_25_LETNO,,,,Nechť není žádná ruka hněvem zvednuta.,Lad ingen hånd blive løftet i vrede,Lass keine Hand in Wut erhoben sein,,Lasu nenion manon estas levita pro kolero.,Que ninguna mano se levante con ira,,Ei yhtäkään kättä kohotettako vihassa,Qu'aucune main de se lève avec colère,Ne emeljünk kezet haragból,Si cerchi di non alzare le mani per rabbia,怒りで拳を振るわないように,분노하여 주먹을 휘두르지 말라,Laat geen hand worden opgestoken in woede...,La ingen hånd bli løftet i sinne,Nie pozwól by ręka została uniesiona w gniewie,Que mão nenhuma seja erguida por raiva,,Fie ca nicio mână să nu fie ridicată în furie,И да не поднимется рука во гневе,Нека се ни рука из беса не подигне,Låt ingen hand höjas i ilska,Öfkeyle el kaldırmayın +Who dares disturb our slumber?,TXT_ACS_MAP52_9_WHODA,,,,Kdo se opovažuje narušit náš spánek?,Hvem vover at forstyrre vores slummer?,Wer wagt es unseren Schlummer zu stören?,,Kiu aŭdacas interrompi nian dormon? ,¿Quién se atreve a perturbar nuestro sueño?,,Kuka kehtaa häiritä untamme?,Qui ose troubler notre sommeil?,Ki meri megzavarni a szunyókálásunkat?,Chi osa disturbare il nostro riposo?,誰が、我々の眠りを妨げる勇気があるかな?,감히 우리의 숙면을 방해하는가?,Wie durft onze slaap te verstoren?,Hvem våger å forstyrre vår søvn?,Kto śmie przeszkadzać nam w drzemce?,Quem ousa perturbar o nosso descanso?,,Cine cutează să-mi perturbe odihna?,Кто осмелился потревожить наш покой?,Ко се усуђује узнемиравати наш спокој?,Vem vågar störa vår slummer?,Uykumuzu bölmeye kim cüret eder? +The way is open,TXT_ACS_MAP52_10_THEWA,,,,Cesta je otevřena.,Vejen er åben,Der Weg ist offen,,La vojo estas malfermita.,El camino está abierto,,Tie on auki,Le chemin est ouvert.,Az út kinyílt,La via è aperta,道は開いた,길이 열렸다,De weg is open,Veien er åpen,Droga jest otwarta,O caminho está aberto,,Calea e deschisă,Путь открыт,Пролаз је отворен,Vägen är öppen,Yol açık +You have ,TXT_ACS_MAP53_2_YOUHA,,,,Zbývají ti ,Du har,Du hast,,Vi havas,Tienes,,Sinulla on,Vous avez,Már csak,Hai,スイッチはまだ,지금 ,Je hebt,Du har,Masz,Restam ainda,,Mai ai,Осталось,Остало је ,Du har, +\x20switches left,TXT_ACS_MAP53_3_SWITC,,,,\x20spínače.,\x20kontakter tilbage,\x20Schalter übrig,,\x20ŝaltilojn ceterajn.,\x20interruptores restantes,\x20switches restantes,\x20vipua jäljellä,\x20boutons à trouver,\x20kallantyú van hátra,\x20interuttori rimanenti,残っている,개의 개폐기들이 남았다,\x20schakelaars over,\x20brytere igjen,\x20pozostałych przełączników,\x20interruptores,,\x20butoane rămase,\x20переключателей,\x20прекидача,\x20växlar kvar,\x20anahtarınız kaldı +You have only ,TXT_ACS_MAP53_4_YOUHA,,,,Zbývá ti jen ,Du har kun,Du hast nur,,Vi nur havas,Tienes solo,,Sinulla on vain,Vous avez seulement,Már csak,Hai solamente,スイッチは,이제 오로지 ,Je hebt alleen,Du har bare,Masz tylko,Resta somente,,Mai ai doar,Остался всего,Остао је само ,Du har bara, \x20switch left,TXT_ACS_MAP53_5_SWITC,,,,\x20spínač.,\x20kontakter tilbage,\x20Schalter übrig,,\x20ŝaltilon ceteran.,\x20interruptor restante,\x20switch restante,\x20vipu jäljellä,\x20outon à trouver,\x20kallantyú van hátra,\x20interruttore rimanente,"だけ残っている -",개의 개폐기가 남았다,\x20schakelaar over,\x20bryter igjen,\x20przełącznik,\x20interruptor,,\x20buton rămas,\x20переключатель,\x20прекидач,\x20anahtarınız kaldı -The exit is open,TXT_ACS_MAP53_6_THEEX,,,,Východ je otevřen.,Udgangen er åben,Der Ausgang ist offen,,La elirejo estas malfermita,La salida está abierta,,Ulospääsy on auki,La sortie est ouverte,A kijárat kinyílt,L'uscita è aperta,出口が開いた,출구가 열렸다,De uitgang is open,Utgangen er åpen,Wyjście jest otwarte,A saída está aberta,,Ieșirea e deschisă,Выход открыт,Излаз је отворен,Çıkış açık -The doors won't open from this side,TXT_ACS_MAP54_1_THEDO,,,,Dveře se z této strany neotevřou.,Dørene kan ikke åbnes fra denne side,Die Türen werden sich nicht von dieser Seite öffnen,,La pordo ne malfermos de ĉi tio flanko.,Las puertas no se abren desde este lado,,Ovet eivät aukea tältä puolelta,Les portes ne s'ouvrent pas de ce côté,Az ajtó nem nyílik erről az oldalról,Le porte non si aprono da questo lato,扉はこちらから開けない,이 문들은 이 방향으로는 열리지 않는다,De deuren gaan niet open van deze kant....,Dørene kan ikke åpnes fra denne siden,Drzwi nie otworzą się z tej strony,As portas não se abrirão deste lado,,Ușile nu se vor deschide de pe partea asta,С этой стороны дверь не открыть,Врата неће да се отворе са стране,Kapılar bu taraftan açılmıyor. -The doors are open...,TXT_ACS_MAP54_4_THEDO,,,,Dveře jsou otevřené...,Dørene er åbne...,Die Türen sind offen,,La pordoj estas malfermitaj...,Las puertas están abiertas...,,Ovet ovat auki...,Les portes sont ouvertes...,Az ajtók kitárultak...,Le porte sono aperte...,ドアは開いている...,문이 열렸다...,De deuren zijn open....,Dørene er åpne...,Drzwi są otwarte...,As portas estão abertas...,,Ușile sunt deschise...,Двери открыты...,Врата су отворена...,Kapılar açık. -...if you are ready,TXT_ACS_MAP54_5_IFYOU,,,,...jestli jsi připraven@[ao_cs].,...hvis du er klar,...Wenn du bereit bist,,...se vi pretas.,...si estás listo,,...jos olet valmis,...si vous êtes prêt.,...csak rád várunk.,...Se sei pronto,...準備が良いなら,... 준비 되었다면,...als je er klaar voor bent...,...hvis du er klar,...jeśli jesteś gotów,...se você estiver preparad@[ao_ptb],,...dacă ești pregătit,...осмелишься ли ты войти?,...ако си спреман,...eğer hazırsanız -A door has opened,TXT_ACS_MAP54_9_ADOOR,,,,Dveře se otevřely,En dør er blevet åbnet,Eine Tür hat sich geöffnet,,Pordo malfermiĝis,Se ha abierto una puerta,Se abrió una puerta,Ovi on auennut,Une porte est ouverte,Egy ajtó kinyílt,Una porta è stata aperta,先へ進むドアは開いた,지금 문이 열렸다...,Een deur is geopend,En dør har åpnet seg,Drzwi otworzyły się,Uma porta se abriu,,O ușă s-a deschis,Дверь открылась,Врата су се отворила,Bir kapı açıldı -on the Chantry,TXT_ACS_MAP54_10_ONTHE,,,,v Modlitebně.,på Kirkerummet,In der Kantorei,,en la Kapelo.,En la capilla,,kappelissa,dans la chapelle.,a kápolnánál,Nella Cappella,小礼拝堂 へ向かえ,... 예배당에서,op de Chantry,på Minnekapellet,w Kaplicy Wotywnej,na Capela,,la Capelă,в часовне,у Капели,Chantry'de -A bridge has been built,TXT_ACS_MAP54_11_ABRID,,,,Most byl postaven,En bro er blevet bygget,Eine Brücke wurde errichtet,,Ponto estis konstruita,Se ha construido un puente,Se construyó un puente,Silta on rakennettu,Une pont a été construit,Egy hidat támasztottak fel,È stato costruito un ponte,先へ進む橋が架かった,다리가 건설되었다...,Er is een brug gebouwd,En bro har blitt bygget,Most został utworzony,Uma ponte foi construída,,Un pod a fost construit,Мост воздвигнут,Мост се саградио,Bir köprü inşa edildi -on the Abattoir,TXT_ACS_MAP54_12_ONTHE,,,,na Jatkách.,på Slagteriet,Im Schlachthaus,,en la Buĉejo.,En el matadero,,teurastamolla,dans l'abbatoir.,a vágóhídnál,Nella Macelleria, 屠殺場 へ向かえ,... 도살장에서,op het slachthuis,på slakteriet,w Rzeźni,no Matadouro,,pe Abator,у аббатства,на Кланици,Mezbahada -A stair has been built,TXT_ACS_MAP54_13_ASTAI,,,,Schody byly postaveny,Der er bygget en trappe,Eine Treppe wurde errichtet,,Ŝtuparo estis konstruita,Se ha construido una escalera,Se construyó una escalera,Portaat on rakennettu,Un escalier a été construit,Lépcső emelkedett ki,È stata costruita una scalinata,先へ進む階段が出来た,계단이 건설되었다...,Er is een trap gebouwd,En trapp har blitt bygget,Schody zostały utworzone,Uma escada foi construída,,O scară a fost construită,Лестница воздвигнута,Степенице су се саградиле,Bir merdiven inşa edildi -on the Dark Watch,TXT_ACS_MAP54_14_ONTHE,,,,na Temné hlídce.,på den mørke vagt,auf der Dunklen Wache,,en la Gardisto Ombra.,En la guardia oscura,,pimeällä vartiolla,dans la Garde Noire.,a Sötét Őrségnél,Nella Guardia Oscura, 闇の刻計 へ向かえ,... 어둠의 감시초소에서,op de donkere wacht,på den mørke vakten,w Ciemnej Strażnicy,na Guarda Negra,,pe Gardianul Întunecat,у тёмной стражи,на Црној стражи,Karanlık Nöbet'te -One gear has been placed,TXT_ACS_MAP54_15_ONEGE,,,,Jedno kolo bylo umístěno.,Der er blevet placeret et redskab,Ein Zahnrad wurde eingesetzt,,Dentrado estis metita.,Un engranaje en su lugar,,Ratas on asetettu,Un engrenage a été placé,Egy fogaskerék a helyére került,Un ingranaggio è stato piazzato,歯車を一つ配置した,톱니바퀴 1개가 배치되었다,Een tandwiel is geplaatst,Ett tannhjul har blitt plassert,Jedna zębatka została umieszczona,Uma engrenagem foi colocada,,Un mecanism a fost introdus,Шестерня установлена,Један зупчаник је постављен,Bir dişli yerleştirildi -\x20gears have been placed,TXT_ACS_MAP54_16_GEARS,,,,\x20kola byla umístěna.,\x20gear er blevet placeret,\x20Zahnräder wurden eingesetzt,,\x20dentradoj estis metitaj.,\x20engranajes en su lugar,,\x20ratasta on asetettu,\x20engrenages ont été placés,\x20fogaskerék a helyére került,\x20ingranaggi sono stati piazzati,歯車を配置した,톱니바퀴들이 배치되었다,\x20tandwielen zijn geplaatst,\x20 tannhjul har blitt plassert,\x20zębatki zostały umieszczone,\x20engrenagens foram colocadas,,\x20mecanisme au fost introduse,\x20шестерней установлено,\x20зупчаника су постављена,\x20dişliler yerleştirildi -A barricade has opened,TXT_ACS_MAP54_17_ABARR,,,,V Kloace se otevřela barikáda.,En barrikade er blevet åbnet,Eine Barrikade wurde geöffnet,,Barikado malfermiĝis,La barricada se ha abierto,Se abrió la barricada,Tiesulku on auennut,Une barricade s'est ouverte,Egy barikád megszűnt,Una barricata è stata aperta,バリケードは開かれた,방벽이 열렸다...,Er is een barricade geopend,En barrikade har åpnet seg,Barykada została otwarta,Uma barricada se abriu,,O baricadă s-a deschis,Преграда опустилась,Барикада је отворена,Bir barikat açıldı -On the Cloaca,TXT_ACS_MAP54_18_ONTHE,,,,V Kloace se otevřela barikáda.,På Cloaca,In der Kloake,,En la Kloako.,En la Cloaca,,kloaakilla,dans le cloaque,a Kloákánál,Nella Cloaca,排泄腔 へ向かえ,... 하수구에서,Op de Cloaca,på Cloaca,W Kloace,Na Cloaca,,pe Cloaca,в клоаке,у клоаци,Kloaka Üzerine -The way back is open,TXT_ACS_MAP54_20_THEWA,,,,Cesta zpět je otevřena.,Vejen tilbage er åben,Der Weg zurück ist offen,,La vojo reen estas malfermita.,El camino está abierto,,Tie takaisin on auki,Un chemin s'est ouvert,A visszavezető út kinyílt,La via del ritorno è aperta,裏口は開いた,돌아가는 길이 열렸다,De terugweg is open,Veien tilbake er åpen,Droga powrotna jest otwarta,O caminho de volta está aberto,,Calea e deschisă,Путь назад открыт,Пролаз назад је отворен,Dönüş yolu açık -The door is barred from the inside,TXT_ACS_MAP55_9_THEDO,,,,Dveře jsou zatarasené zevnitř.,Døren er spærret indefra,Die Tür ist von innen verriegelt,,La pordo estas barita interne.,La puerta está trabada desde el otro lado,,Ovi on teljetty sisältä,La porte est bloquée de ce côté,Az ajtó bentről van bereteszelve,La porta è stata aperta da dentro,この扉は内側から塞がれている,이 문은 안에 빗장이 걸려있다,De deur is van binnenuit geblokkeerd.,Døren er sperret fra innsiden,Drzwi są zabarykadowane od wewnątrz,A porta está barrada por dentro,,Ușa e încuiată din interior,Дверь заблокирована изнутри,Врата су забрављена изнутра,Kapı içeriden kilitli. -You dare plunder the tomb,TXT_ACS_MAP56_0_YOUDA,,,,Ty se opovažuješ rabovat,Du vover at plyndre graven,Wagst du es,,Ĉu vi aŭdacas rabi de la tombo,¿Te atreves a saquear la tumba,,Kuinka kehtaat ryöstää,Vous osez piller la tombe,A hóhér sírját,Osi saccheggiare la tomba,お前はあえて 執行人達の墓を,배짱이 두둑하구나...,Je durft de graftombe te plunderen,Våger du å plyndre graven,Śmiesz plądrować grobowiec,Como ousa saquear a tumba,,Cutezi să jefuiești mormântul,Ты посмел ограбить могилу,Усуђујеш се пљачкати,Mezarı yağmalamaya cüret ediyorsun -of the executioner?,TXT_ACS_MAP56_1_OFTHE,,,,hrobku popravčího?,af bødlen?,das Grab des Henkers zu plündern?,,de la ekzekutisto?,del ejecutor?,,teloittajan haudan?,du bourreau?,próbálod fosztogatni?,dell'esecutore?,荒らすつもりか?,사형 집행자의 무덤을 도굴하다니.,van de beul?,til bøddelen?,kata?,do executor?,,călăului?,верховного палача?,желатову гробницу?,Celladın mı? -Prepare to die,TXT_ACS_MAP56_2_PREPA,,,,Připrav se zemřít.,Forbered dig på at dø,Bereite dich vor zu sterben,,Pretiĝu por morti!,¡Prepárate para morir!,,Valmistaudu kuolemaan,Préparez vous à mourir!,Készülj a halálra,Preparati a morire,死ぬ準備をしろ,죽어서 회계하라.,Bereid je voor om te sterven,Forbered deg på å dø,Przygotuj się na śmierć,Prepare-se para morrer,,Pregătește-te să mori,Готовься к смерти,Припреми се да умреш,Ölmeye hazırlanın -You have ,TXT_ACS_MAP59_1_YOUHA,,,,Zbývají ti ,Du har,Du musst,,Vi ankoraŭ havas,Aún tienes,,Sinulla on,Vous avez,Még kell találnod,Hai ancora altri,スイッチはまだ,당신은,Je hebt,Du har,Masz,Faltam mais,,Mai ai,Осталось,Остало је ,Bulmanız gereken\x20 -\x20more switches to find,TXT_ACS_MAP59_2_MORES,,,,\x20spínače k nalezení.,\x20flere kontakter at finde,\x20weitere Schalter finden,,\x20trovindajn ŝaltilojn.,\x20interruptores más que encontrar,,\x20lisää vipua löydettävänä,\x20boutons à trouver,\x20darab kallantyút,\x20interruttori da trovare,残っている,개의 개폐기들을 더 찾아야 한다,\x20meer schakelaars te vinden,\x20 brytere til å finne,\x20przełączników do znalezienia,\x20interruptores para encontrar,,\x20butoane de găsit,\x20переключателей,\x20прекидача да се нађе,\x20anahtar daha var. -You have only ,TXT_ACS_MAP59_3_YOUHA,,,,Zbývá ti jen ,Du har kun,Du musst nur,,Vi nur havas,Tienes solo,,Sinulla on vain,Vous avez seulement,Már csak,Hai solamente,スイッチは,이제 당신은 ,Je hebt alleen,Du har bare,Masz tylko,Falta somente,,Mai ai doar,Остался всего,Oстао је само ,Bulmanız gereken\x20 +",개의 개폐기가 남았다,\x20schakelaar over,\x20bryter igjen,\x20przełącznik,\x20interruptor,,\x20buton rămas,\x20переключатель,\x20прекидач,\x20växel kvar,\x20anahtarınız kaldı +The exit is open,TXT_ACS_MAP53_6_THEEX,,,,Východ je otevřen.,Udgangen er åben,Der Ausgang ist offen,,La elirejo estas malfermita,La salida está abierta,,Ulospääsy on auki,La sortie est ouverte,A kijárat kinyílt,L'uscita è aperta,出口が開いた,출구가 열렸다,De uitgang is open,Utgangen er åpen,Wyjście jest otwarte,A saída está aberta,,Ieșirea e deschisă,Выход открыт,Излаз је отворен,Utgången är öppen,Çıkış açık +The doors won't open from this side,TXT_ACS_MAP54_1_THEDO,,,,Dveře se z této strany neotevřou.,Dørene kan ikke åbnes fra denne side,Die Türen werden sich nicht von dieser Seite öffnen,,La pordo ne malfermos de ĉi tio flanko.,Las puertas no se abren desde este lado,,Ovet eivät aukea tältä puolelta,Les portes ne s'ouvrent pas de ce côté,Az ajtó nem nyílik erről az oldalról,Le porte non si aprono da questo lato,扉はこちらから開けない,이 문들은 이 방향으로는 열리지 않는다,De deuren gaan niet open van deze kant....,Dørene kan ikke åpnes fra denne siden,Drzwi nie otworzą się z tej strony,As portas não se abrirão deste lado,,Ușile nu se vor deschide de pe partea asta,С этой стороны дверь не открыть,Врата неће да се отворе са стране,Dörrarna öppnas inte från den här sidan,Kapılar bu taraftan açılmıyor. +The doors are open...,TXT_ACS_MAP54_4_THEDO,,,,Dveře jsou otevřené...,Dørene er åbne...,Die Türen sind offen,,La pordoj estas malfermitaj...,Las puertas están abiertas...,,Ovet ovat auki...,Les portes sont ouvertes...,Az ajtók kitárultak...,Le porte sono aperte...,ドアは開いている...,문이 열렸다...,De deuren zijn open....,Dørene er åpne...,Drzwi są otwarte...,As portas estão abertas...,,Ușile sunt deschise...,Двери открыты...,Врата су отворена...,Dörrarna är öppna...,Kapılar açık. +...if you are ready,TXT_ACS_MAP54_5_IFYOU,,,,...jestli jsi připraven@[ao_cs].,...hvis du er klar,...Wenn du bereit bist,,...se vi pretas.,...si estás listo,,...jos olet valmis,...si vous êtes prêt.,...csak rád várunk.,...Se sei pronto,...準備が良いなら,... 준비 되었다면,...als je er klaar voor bent...,...hvis du er klar,...jeśli jesteś gotów,...se você estiver preparad@[ao_ptb],,...dacă ești pregătit,...осмелишься ли ты войти?,...ако си спреман,...om du är redo,...eğer hazırsanız +A door has opened,TXT_ACS_MAP54_9_ADOOR,,,,Dveře se otevřely,En dør er blevet åbnet,Eine Tür hat sich geöffnet,,Pordo malfermiĝis,Se ha abierto una puerta,Se abrió una puerta,Ovi on auennut,Une porte est ouverte,Egy ajtó kinyílt,Una porta è stata aperta,先へ進むドアは開いた,지금 문이 열렸다...,Een deur is geopend,En dør har åpnet seg,Drzwi otworzyły się,Uma porta se abriu,,O ușă s-a deschis,Дверь открылась,Врата су се отворила,En dörr har öppnats,Bir kapı açıldı +on the Chantry,TXT_ACS_MAP54_10_ONTHE,,,,v Modlitebně.,på Kirkerummet,In der Kantorei,,en la Kapelo.,En la capilla,,kappelissa,dans la chapelle.,a kápolnánál,Nella Cappella,小礼拝堂 へ向かえ,... 예배당에서,op de Chantry,på Minnekapellet,w Kaplicy Wotywnej,na Capela,,la Capelă,в часовне,у Капели,på Chantry,Chantry'de +A bridge has been built,TXT_ACS_MAP54_11_ABRID,,,,Most byl postaven,En bro er blevet bygget,Eine Brücke wurde errichtet,,Ponto estis konstruita,Se ha construido un puente,Se construyó un puente,Silta on rakennettu,Une pont a été construit,Egy hidat támasztottak fel,È stato costruito un ponte,先へ進む橋が架かった,다리가 건설되었다...,Er is een brug gebouwd,En bro har blitt bygget,Most został utworzony,Uma ponte foi construída,,Un pod a fost construit,Мост воздвигнут,Мост се саградио,En bro har byggts,Bir köprü inşa edildi +on the Abattoir,TXT_ACS_MAP54_12_ONTHE,,,,na Jatkách.,på Slagteriet,Im Schlachthaus,,en la Buĉejo.,En el matadero,,teurastamolla,dans l'abbatoir.,a vágóhídnál,Nella Macelleria, 屠殺場 へ向かえ,... 도살장에서,op het slachthuis,på slakteriet,w Rzeźni,no Matadouro,,pe Abator,у аббатства,на Кланици,på slakthuset,Mezbahada +A stair has been built,TXT_ACS_MAP54_13_ASTAI,,,,Schody byly postaveny,Der er bygget en trappe,Eine Treppe wurde errichtet,,Ŝtuparo estis konstruita,Se ha construido una escalera,Se construyó una escalera,Portaat on rakennettu,Un escalier a été construit,Lépcső emelkedett ki,È stata costruita una scalinata,先へ進む階段が出来た,계단이 건설되었다...,Er is een trap gebouwd,En trapp har blitt bygget,Schody zostały utworzone,Uma escada foi construída,,O scară a fost construită,Лестница воздвигнута,Степенице су се саградиле,En trappa har byggts,Bir merdiven inşa edildi +on the Dark Watch,TXT_ACS_MAP54_14_ONTHE,,,,na Temné hlídce.,på den mørke vagt,auf der Dunklen Wache,,en la Gardisto Ombra.,En la guardia oscura,,pimeällä vartiolla,dans la Garde Noire.,a Sötét Őrségnél,Nella Guardia Oscura, 闇の刻計 へ向かえ,... 어둠의 감시초소에서,op de donkere wacht,på den mørke vakten,w Ciemnej Strażnicy,na Guarda Negra,,pe Gardianul Întunecat,у тёмной стражи,на Црној стражи,på den mörka vakten,Karanlık Nöbet'te +One gear has been placed,TXT_ACS_MAP54_15_ONEGE,,,,Jedno kolo bylo umístěno.,Der er blevet placeret et redskab,Ein Zahnrad wurde eingesetzt,,Dentrado estis metita.,Un engranaje en su lugar,,Ratas on asetettu,Un engrenage a été placé,Egy fogaskerék a helyére került,Un ingranaggio è stato piazzato,歯車を一つ配置した,톱니바퀴 1개가 배치되었다,Een tandwiel is geplaatst,Ett tannhjul har blitt plassert,Jedna zębatka została umieszczona,Uma engrenagem foi colocada,,Un mecanism a fost introdus,Шестерня установлена,Један зупчаник је постављен,En kugghjul har placerats,Bir dişli yerleştirildi +\x20gears have been placed,TXT_ACS_MAP54_16_GEARS,,,,\x20kola byla umístěna.,\x20gear er blevet placeret,\x20Zahnräder wurden eingesetzt,,\x20dentradoj estis metitaj.,\x20engranajes en su lugar,,\x20ratasta on asetettu,\x20engrenages ont été placés,\x20fogaskerék a helyére került,\x20ingranaggi sono stati piazzati,歯車を配置した,톱니바퀴들이 배치되었다,\x20tandwielen zijn geplaatst,\x20 tannhjul har blitt plassert,\x20zębatki zostały umieszczone,\x20engrenagens foram colocadas,,\x20mecanisme au fost introduse,\x20шестерней установлено,\x20зупчаника су постављена,\x20 kugghjul har placerats,\x20dişliler yerleştirildi +A barricade has opened,TXT_ACS_MAP54_17_ABARR,,,,V Kloace se otevřela barikáda.,En barrikade er blevet åbnet,Eine Barrikade wurde geöffnet,,Barikado malfermiĝis,La barricada se ha abierto,Se abrió la barricada,Tiesulku on auennut,Une barricade s'est ouverte,Egy barikád megszűnt,Una barricata è stata aperta,バリケードは開かれた,방벽이 열렸다...,Er is een barricade geopend,En barrikade har åpnet seg,Barykada została otwarta,Uma barricada se abriu,,O baricadă s-a deschis,Преграда опустилась,Барикада је отворена,En barrikad har öppnats,Bir barikat açıldı +On the Cloaca,TXT_ACS_MAP54_18_ONTHE,,,,V Kloace se otevřela barikáda.,På Cloaca,In der Kloake,,En la Kloako.,En la Cloaca,,kloaakilla,dans le cloaque,a Kloákánál,Nella Cloaca,排泄腔 へ向かえ,... 하수구에서,Op de Cloaca,på Cloaca,W Kloace,Na Cloaca,,pe Cloaca,в клоаке,у клоаци,På Cloaca,Kloaka Üzerine +The way back is open,TXT_ACS_MAP54_20_THEWA,,,,Cesta zpět je otevřena.,Vejen tilbage er åben,Der Weg zurück ist offen,,La vojo reen estas malfermita.,El camino está abierto,,Tie takaisin on auki,Un chemin s'est ouvert,A visszavezető út kinyílt,La via del ritorno è aperta,裏口は開いた,돌아가는 길이 열렸다,De terugweg is open,Veien tilbake er åpen,Droga powrotna jest otwarta,O caminho de volta está aberto,,Calea e deschisă,Путь назад открыт,Пролаз назад је отворен,Vägen tillbaka är öppen,Dönüş yolu açık +The door is barred from the inside,TXT_ACS_MAP55_9_THEDO,,,,Dveře jsou zatarasené zevnitř.,Døren er spærret indefra,Die Tür ist von innen verriegelt,,La pordo estas barita interne.,La puerta está trabada desde el otro lado,,Ovi on teljetty sisältä,La porte est bloquée de ce côté,Az ajtó bentről van bereteszelve,La porta è stata aperta da dentro,この扉は内側から塞がれている,이 문은 안에 빗장이 걸려있다,De deur is van binnenuit geblokkeerd.,Døren er sperret fra innsiden,Drzwi są zabarykadowane od wewnątrz,A porta está barrada por dentro,,Ușa e încuiată din interior,Дверь заблокирована изнутри,Врата су забрављена изнутра,Dörren är spärrad från insidan,Kapı içeriden kilitli. +You dare plunder the tomb,TXT_ACS_MAP56_0_YOUDA,,,,Ty se opovažuješ rabovat,Du vover at plyndre graven,Wagst du es,,Ĉu vi aŭdacas rabi de la tombo,¿Te atreves a saquear la tumba,,Kuinka kehtaat ryöstää,Vous osez piller la tombe,A hóhér sírját,Osi saccheggiare la tomba,お前はあえて 執行人達の墓を,배짱이 두둑하구나...,Je durft de graftombe te plunderen,Våger du å plyndre graven,Śmiesz plądrować grobowiec,Como ousa saquear a tumba,,Cutezi să jefuiești mormântul,Ты посмел ограбить могилу,Усуђујеш се пљачкати,Du vågar plundra graven,Mezarı yağmalamaya cüret ediyorsun +of the executioner?,TXT_ACS_MAP56_1_OFTHE,,,,hrobku popravčího?,af bødlen?,das Grab des Henkers zu plündern?,,de la ekzekutisto?,del ejecutor?,,teloittajan haudan?,du bourreau?,próbálod fosztogatni?,dell'esecutore?,荒らすつもりか?,사형 집행자의 무덤을 도굴하다니.,van de beul?,til bøddelen?,kata?,do executor?,,călăului?,верховного палача?,желатову гробницу?,av bödeln?,Celladın mı? +Prepare to die,TXT_ACS_MAP56_2_PREPA,,,,Připrav se zemřít.,Forbered dig på at dø,Bereite dich vor zu sterben,,Pretiĝu por morti!,¡Prepárate para morir!,,Valmistaudu kuolemaan,Préparez vous à mourir!,Készülj a halálra,Preparati a morire,死ぬ準備をしろ,죽어서 회계하라.,Bereid je voor om te sterven,Forbered deg på å dø,Przygotuj się na śmierć,Prepare-se para morrer,,Pregătește-te să mori,Готовься к смерти,Припреми се да умреш,Förbered dig på att dö,Ölmeye hazırlanın +You have ,TXT_ACS_MAP59_1_YOUHA,,,,Zbývají ti ,Du har,Du musst,,Vi ankoraŭ havas,Aún tienes,,Sinulla on,Vous avez,Még kell találnod,Hai ancora altri,スイッチはまだ,당신은,Je hebt,Du har,Masz,Faltam mais,,Mai ai,Осталось,Остало је ,Du har,Bulmanız gereken\x20 +\x20more switches to find,TXT_ACS_MAP59_2_MORES,,,,\x20spínače k nalezení.,\x20flere kontakter at finde,\x20weitere Schalter finden,,\x20trovindajn ŝaltilojn.,\x20interruptores más que encontrar,,\x20lisää vipua löydettävänä,\x20boutons à trouver,\x20darab kallantyút,\x20interruttori da trovare,残っている,개의 개폐기들을 더 찾아야 한다,\x20meer schakelaars te vinden,\x20 brytere til å finne,\x20przełączników do znalezienia,\x20interruptores para encontrar,,\x20butoane de găsit,\x20переключателей,\x20прекидача да се нађе,\x20fler växlar att hitta.,\x20anahtar daha var. +You have only ,TXT_ACS_MAP59_3_YOUHA,,,,Zbývá ti jen ,Du har kun,Du musst nur,,Vi nur havas,Tienes solo,,Sinulla on vain,Vous avez seulement,Már csak,Hai solamente,スイッチは,이제 당신은 ,Je hebt alleen,Du har bare,Masz tylko,Falta somente,,Mai ai doar,Остался всего,Oстао је само ,Du har bara,Bulmanız gereken\x20 \x20switch left,TXT_ACS_MAP59_4_SWITC,,,,\x20spínač.,\x20kontakter tilbage,\x20Schalter finden,,\x20ŝaltilon ceteran.,\x20interruptor restante,,\x20vipu jäljellä,\x20bouton a trouver,\x20darab kallantyút kell találnod,\x20interruttore rimanente,"だけ残っている -",개의 개폐기만 찾으면 된다,\x20schakelaar over,1 bryter igjen,\x20przełącznik,\x20interruptor,,\x20buton rămas,\x20переключатель,\x20прекидач,\x20anahtar daha var. -The way to the tower is open,TXT_ACS_MAP59_5_THEWA,,,,Cesta do věže je otevřena.,Vejen til tårnet er åben,Der Weg zum Turm ist offen,,La vojo al la turo estas malfermita.,El camino a la torre está abierto,,Tie tornin luo on auki,Le chemin vers la tour est ouvert.,A toronyba vezető út kinyílt,La via alla torre è stata aperta,塔への道 が開いた,탑으로 가는 길이 열렸다,De weg naar de toren is open,Veien til tårnet er åpen,Droga do wieży jest otwarta,O caminho para a torre está aberto,,Calea către turn e deschisă,Путь к башне открыт,Пут до куле је отворен,Kuleye giden yol açık. -The way is open,TXT_ACS_MAP60_3_THEWA,,,,Cesta je otevřena.,Vejen er åben,Der Weg ist offen,,La vojo estas malfermita.,El camino está abierto,,Tie on auki,Le chemin est ouvert.,Az út kinyílt,La via è aperta,道は開いた,길이 열렸다,De weg is open,Veien er åpen,Droga jest otwarta,O caminho está aberto,,Calea e deschisă,Портал открыт,Портал је отворен,Yol açık -,,Strife dialogue,,,,,,,,,,,,,,,,,,,,,,,, +",개의 개폐기만 찾으면 된다,\x20schakelaar over,1 bryter igjen,\x20przełącznik,\x20interruptor,,\x20buton rămas,\x20переключатель,\x20прекидач,1 växel kvar,\x20anahtar daha var. +The way to the tower is open,TXT_ACS_MAP59_5_THEWA,,,,Cesta do věže je otevřena.,Vejen til tårnet er åben,Der Weg zum Turm ist offen,,La vojo al la turo estas malfermita.,El camino a la torre está abierto,,Tie tornin luo on auki,Le chemin vers la tour est ouvert.,A toronyba vezető út kinyílt,La via alla torre è stata aperta,塔への道 が開いた,탑으로 가는 길이 열렸다,De weg naar de toren is open,Veien til tårnet er åpen,Droga do wieży jest otwarta,O caminho para a torre está aberto,,Calea către turn e deschisă,Путь к башне открыт,Пут до куле је отворен,Vägen till tornet är öppen.,Kuleye giden yol açık. +The way is open,TXT_ACS_MAP60_3_THEWA,,,,Cesta je otevřena.,Vejen er åben,Der Weg ist offen,,La vojo estas malfermita.,El camino está abierto,,Tie on auki,Le chemin est ouvert.,Az út kinyílt,La via è aperta,道は開いた,길이 열렸다,De weg is open,Veien er åpen,Droga jest otwarta,O caminho está aberto,,Calea e deschisă,Портал открыт,Портал је отворен,Vägen är öppen.,Yol açık +,,Strife dialogue,,,,,,,,,,,,,,,,,,,,,,,,, "I don't want any trouble, stay away from me. I've had enough trouble with what that bastard Harris did to me. He promised me money, instead I get to look forward to being Questioned by the Programmer.",TXT_DLG_SCRIPT01_D0_IDONT,MAP01: Beldin.,,,"Nechci žádný trable, jdi ode mě. Už tak mám dost potíží s tím, co mi ten hajzl Harris provedl. Slíbil mi peníze a místo toho se můžu těšit na výslech od Programátora.","Jeg vil ikke have ballade, hold dig væk fra mig. Jeg har haft nok problemer med det, den skiderik Harris gjorde mod mig. Han lovede mig penge, men i stedet skal jeg se frem til at blive udspurgt af programmøren.","Ich möchte keinen Ärger, bleib weg von mir. Ich hatte genug Ärger mit dem was der Bastard Harris mir angetan hat. Er hat mir Geld versprochen, stattdessen musste ich mich darauf vorbereiten von dem Programmierer ausgefragt zu werden.",,"Malproksimiĝu de mi; mi ne volas pliajn problemojn. Mi jam havis sufiĉajn pro tio, kion Harris faris: li promesis monon al mi, kaj anstataŭ tio mi nun atendas, ke La Progamisto pridemandu min.","No te me acerques, que ya no quiero más problemas. He tenido suficientes con lo que me hizo Harris: me prometió dinero, y en lugar de eso, ahora me toca esperar a ser interrogado por El Programador.",,"En kaipaa ikävyyksiä; pysy pois luotani. Olen saanut kärsiä jo riittävästi vaivaa Harris-paskiaisen tekosista. Hän lupasi minulle rahaa, mutta sen sijaan pääsenkin Ohjelmoitsijan kuulusteltavaksi.","Je ne veux pas d'embrouilles. Laissez moi tranquille. J'ai déjà assez de problèmes avec ce que ce salaud d'Harris ma fait. Il m'a promis de l'argent, maintenant, je risque de me faire interroger par le Programmeur.","Én nem akarok semmi problémát, maradj távol tőlem. Elég baj nekem az amit az a barom Harris okozott. Pénzt ígért, ehelyett az vár rám, hogy a Programozó ki fog kérdezni.","Non voglio problemi, stai alla larga. Ho già avuto abbastanza problemi con quello che quel bastardo di mi ha fatto. Mi aveva promesso soldi, invece mi ritrovo ad avere l'opportunità di essere interrogato dal Programmatore.","もう面倒事には御免だ、私に近づくな。 あのハリスのクズのせいでもう十分面倒な目に 遭ったんだ。ヤツは私に金を渡すと約束したのに、 裏切られて私がプログラマーに尋問されることに なってしまったんだ。","난 문제를 더 일으키고 싶지 않아, 나에게서 떨어져! 해리스 그 자식이 나를 속였어. 녀석이 돈을 준다고 해서 도와줬더니 도망치고 없었고 결국엔 붙잡혀서 프로그래머에게 심문을 받을 처지에 놓였다고!","Ik wil geen problemen, blijf uit mijn buurt. Ik heb genoeg problemen gehad met wat die klootzak Harris me heeft aangedaan. Hij beloofde me geld, maar in plaats daarvan kan ik me verheugen op een Ondervraging door de programmeur.","Jeg vil ikke ha trøbbel. Hold deg unna meg. Jeg har hatt nok trøbbel med det den jævelen Harris gjorde mot meg. Han lovet meg penger, i stedet kan jeg se frem til å bli avhørt av programmereren.","Nie chcę żadnych kłopotów, zostaw mnie w spokoju. Miałem już wystarczająco dużo problemów z tym co ten drań Harris mi zrobił. Obiecał mi pieniądze, ale zamiast tego muszę czekać na to, by być Przesłuchanym przez Programistę.","Não quero me meter em problemas, fique longe de mim. Já tive problemas demais com o que aquele desgraçado do Harris fez comigo. Ele me prometeu dinheiro, mas ao invés disso vou ser Questionado pelo Programador.",,"Nu vreau să am probleme, stai departe de mine. Am avut suficiente probleme din cauza a ceea ce -mi-a făcut ticălosul de Harris. Mi-a promis niște bani, dar în schimb, acum aștept cu nerăbdare să fiu interogat de către Programator.","Не подходи ко мне — мне не нужны неприятности! У меня их и так достаточно из-за этого мерзавца Харриса. Он обещал мне деньги, а вместо этого меня ожидает «допрос» у Программиста.",,"Bela istemiyorum, benden uzak dur. O piç Harris'in bana yaptıkları yüzünden yeterince sorun yaşadım. Bana para sözü verdi, onun yerine Programcı tarafından sorgulanmayı dört gözle bekliyorum." +mi-a făcut ticălosul de Harris. Mi-a promis niște bani, dar în schimb, acum aștept cu nerăbdare să fiu interogat de către Programator.","Не подходи ко мне — мне не нужны неприятности! У меня их и так достаточно из-за этого мерзавца Харриса. Он обещал мне деньги, а вместо этого меня ожидает «допрос» у Программиста.",,"Jag vill inte ha några problem, håll dig borta från mig. Jag har haft tillräckligt med problem med vad den jäveln Harris gjorde mot mig. Han lovade mig pengar, istället får jag se fram emot att bli förhörd av Programmeraren.","Bela istemiyorum, benden uzak dur. O piç Harris'in bana yaptıkları yüzünden yeterince sorun yaşadım. Bana para sözü verdi, onun yerine Programcı tarafından sorgulanmayı dört gözle bekliyorum." I'll help you if you help me. Five pieces of gold and I'll tell all I know.,TXT_DLG_SCRIPT02_D0_ILLHE,MAP02: Guy next to Norwall Prison.,,,"Pomůžu ti, když pomůžeš ty mě. Pět zlaťáků a řeknu ti vše, co vím.","Jeg vil hjælpe dig, hvis du hjælper mig. Fem guldmønter, og jeg fortæller alt, hvad jeg ved.",Ich helfe dir wenn du mir hilfst. Fünf Goldstücke und ich erzähle alles was ich weiß.,,"Mi helpos vin se vi helpos min. Donu kvin da oro kaj mi rakontos ĉion, kion mi scias.",Te ayudo si me ayudas. Cinco piezas de oro y te cuento todo lo que sé.,,"Autan sinua, jos autat minua. Viidestä kultakolikosta kerron kaiken, minkä tiedän.","Tu m'aide, je t'aide. Cinq pièces et je te dis ce que je sais.","Segítek, ha segítesz. 5 arany és mindent elmondok, amit tudok.",Ti aiuterò se tu aiuti me. Cinque pezzi d'oro e ti dirò tutto quello che so.,"助けてくれるなら援助する。 5ゴールドで知っている情報を全て教えよう",저를 도와준다면 당신을 돕겠습니다. 5 골드를 줌으로써 말이죠.,Ik zal je helpen als je me helpt. Vijf goudstukken en ik vertel alles wat ik weet.,"Jeg hjelper deg hvis du hjelper meg. Fem gullstykker, så forteller jeg alt jeg vet.",Pomogę ci jeśli ty mi pomożesz. Pięć sztuk złota i powiem ci wszytsko co wiem.,Eu te ajudo se você me ajudar. Cinco moedas de ouro e te digo tudo que eu sei.,,"O să te ajut dacă și tu mă ajuți. Cinci bucăți de aur -și-ți voi spune tot ce știu.","Я помогу тебе, если ты поможешь мне. Пять золотых, и я расскажу всё, что знаю.",,Bana yardım edersen ben de sana yardım ederim. Beş altın ve tüm bildiklerimi anlatacağım. -Here's the gold.,TXT_RPLY0_SCRIPT02_D0_HERES,〃,,,Tady jsou.,Her er guldet.,Hier ist dein Gold.,,Jen la oro.,Aquí está el oro.,,Tässä on kulta.,Voilà l'argent.,Itt az arany.,Ecco l'oro.,金はこれだ。,여기 골드입니다.,Hier is het goud.,Her er gullet.,Oto złoto.,Aqui está o ouro.,,Poftiți aurul.,Вот золото.,,İşte altın. +și-ți voi spune tot ce știu.","Я помогу тебе, если ты поможешь мне. Пять золотых, и я расскажу всё, что знаю.",,Jag hjälper dig om du hjälper mig. Fem guldmynt och jag berättar allt jag vet.,Bana yardım edersen ben de sana yardım ederim. Beş altın ve tüm bildiklerimi anlatacağım. +Here's the gold.,TXT_RPLY0_SCRIPT02_D0_HERES,〃,,,Tady jsou.,Her er guldet.,Hier ist dein Gold.,,Jen la oro.,Aquí está el oro.,,Tässä on kulta.,Voilà l'argent.,Itt az arany.,Ecco l'oro.,金はこれだ。,여기 골드입니다.,Hier is het goud.,Her er gullet.,Oto złoto.,Aqui está o ouro.,,Poftiți aurul.,Вот золото.,,Här är guldet.,İşte altın. "Be stealthy when you kill, you won't set off alarms.",TXT_RYES0_SCRIPT02_D0_BESTE,〃,,,"Když zabíjíš, dělej to potichu - nespustíš tak poplach.","Vær snigende når du dræber, så du ikke udløser alarmer.","Sei leise, wenn du jemanden tötest, damit du keinen Alarm auslöst.",,"Mortigu silente por ne ekagigi alarmojn.","Sé sigiloso al matar para -no activar las alarmas.",,"Jos tapat vihollisesi salaa, vältyt hälytyksiltä.",Tuez discrètement et vous n'aurez pas de problème avec les alarmes.,"Lopakodva, halkan gyilkolj, kézzel, így nem indul be a riasztó.","Sii furtivo quando uccidi, non farai scattare l'allarme.",始末する際は隠密に、警報を鳴らさないように。,"조용히 은신해서 암살만 한다면, 경보를 울리지 않을 겁니다.","Wees sluipend als je doodt, je zult geen alarmbellen laten afgaan.","Vær snikende når du dreper, så du ikke utløser alarmer.","Bądź cicho kiedy zabijasz, nie włączysz wtedy alarmu.",Seja cauteloso quando for matar e não ativará os alarmes.,,"Fii discret când ucizi, nu vei declanșa alarma astfel.","Убивай бесшумно, чтобы не поднять тревогу.",,"Öldürürken gizli ol, alarmları çalıştırmazsın." -"Well, I won't be telling you anything for free!",TXT_RNO0_SCRIPT02_D0_WELLI,〃,,,Zadarmo ti nic říkat nebudu!,Jeg vil ikke fortælle dig noget gratis!,"Na ja, für umsonst werde ich dir nichts erzählen!",,"Nu, mi ne parolos senpage!","Bueno, ¡no te diré nada gratis!","Bueno, ¡no voy a decir nada gratis!","No, en aio kertoa mitään ilmaiseksi!",Je ne vous dirai rien si vous ne me donnez rien!,"Figyelj, ingyen semmit sem mondok el neked.","Beh, io non ti dirò un bel niente senza compenso!",いや、タダで情報は渡せない!,세상에 공짜가 어딨습니까? 먼저 돈을 주세요!,"Nou, ik zal je niets gratis vertellen!","Vel, jeg vil ikke fortelle deg noe gratis!","Cóż, nie będę ci mówił niczego za darmo!","Bom, não vou te dar informação de graça!",,"Păi, n-o să-ți zic nimic pe gratis!","Что ж, я ничего не скажу даром!",,Sana bedavaya hiçbir şey anlatmayacağım! -Have you by any chance got another 5 gold on you?,TXT_DLG_SCRIPT02_D1516_HAVEY,〃,,,Neměl bys u sebe náhodou dalších pět zlatek?,Har du tilfældigvis fem guldstykker mere på dig?,Hast du vielleicht 5 weitere Goldmünzen dabei?,,Ĉu eble vi havas aliajn 5 da oro?,"¿No tendrás otros 5 de oro, por casualidad?",,Sattuisiko sinulla olemaan toiset viisi kolikkoa?,T'aurais pas 5 pièces en plus sur toi?,Nincs véletlenül nálad még 5 arany?,Hai per caso altri 5 pezzi d'oro con te?,もしかして5ゴールド稼いだのか?,5 골드 더 있습니까? 그러면 아주 좋을 텐데.,Heb je toevallig nog 5 goud bij je?,Har du tilfeldigvis fem gull til på deg?,Czy przypadkiem masz może kolejne 5 monet przy sobie?,Por acaso teria mais 5 de ouro aí?,,"Ai cumva, din întâmplare, 5 monezi de aur?",У тебя случайно не найдётся ещё 5 монеток?,,Yanında 5 altın daha var mı acaba? -5 gold.,TXT_RPLY0_SCRIPT02_D1516_5GOLD,〃,,,Pět zlatých.,5 guld.,5 Gold.,,5 da oro.,5 de oro.,,5 kolikkoa.,5 pièces.,5 arany.,5 pezzi d'oro.,5ゴールドだ。,5 골드.,5 goud.,5 gull.,5 monet.,5 de ouro.,,5 monezi de aur.,5 золотых.,,5 altın. +no activar las alarmas.",,"Jos tapat vihollisesi salaa, vältyt hälytyksiltä.",Tuez discrètement et vous n'aurez pas de problème avec les alarmes.,"Lopakodva, halkan gyilkolj, kézzel, így nem indul be a riasztó.","Sii furtivo quando uccidi, non farai scattare l'allarme.",始末する際は隠密に、警報を鳴らさないように。,"조용히 은신해서 암살만 한다면, 경보를 울리지 않을 겁니다.","Wees sluipend als je doodt, je zult geen alarmbellen laten afgaan.","Vær snikende når du dreper, så du ikke utløser alarmer.","Bądź cicho kiedy zabijasz, nie włączysz wtedy alarmu.",Seja cauteloso quando for matar e não ativará os alarmes.,,"Fii discret când ucizi, nu vei declanșa alarma astfel.","Убивай бесшумно, чтобы не поднять тревогу.",,"Var smygande när du dödar, du kommer inte att utlösa larm.","Öldürürken gizli ol, alarmları çalıştırmazsın." +"Well, I won't be telling you anything for free!",TXT_RNO0_SCRIPT02_D0_WELLI,〃,,,Zadarmo ti nic říkat nebudu!,Jeg vil ikke fortælle dig noget gratis!,"Na ja, für umsonst werde ich dir nichts erzählen!",,"Nu, mi ne parolos senpage!","Bueno, ¡no te diré nada gratis!","Bueno, ¡no voy a decir nada gratis!","No, en aio kertoa mitään ilmaiseksi!",Je ne vous dirai rien si vous ne me donnez rien!,"Figyelj, ingyen semmit sem mondok el neked.","Beh, io non ti dirò un bel niente senza compenso!",いや、タダで情報は渡せない!,세상에 공짜가 어딨습니까? 먼저 돈을 주세요!,"Nou, ik zal je niets gratis vertellen!","Vel, jeg vil ikke fortelle deg noe gratis!","Cóż, nie będę ci mówił niczego za darmo!","Bom, não vou te dar informação de graça!",,"Păi, n-o să-ți zic nimic pe gratis!","Что ж, я ничего не скажу даром!",,Jag kommer inte att berätta något gratis!,Sana bedavaya hiçbir şey anlatmayacağım! +Have you by any chance got another 5 gold on you?,TXT_DLG_SCRIPT02_D1516_HAVEY,〃,,,Neměl bys u sebe náhodou dalších pět zlatek?,Har du tilfældigvis fem guldstykker mere på dig?,Hast du vielleicht 5 weitere Goldmünzen dabei?,,Ĉu eble vi havas aliajn 5 da oro?,"¿No tendrás otros 5 de oro, por casualidad?",,Sattuisiko sinulla olemaan toiset viisi kolikkoa?,T'aurais pas 5 pièces en plus sur toi?,Nincs véletlenül nálad még 5 arany?,Hai per caso altri 5 pezzi d'oro con te?,もしかして5ゴールド稼いだのか?,5 골드 더 있습니까? 그러면 아주 좋을 텐데.,Heb je toevallig nog 5 goud bij je?,Har du tilfeldigvis fem gull til på deg?,Czy przypadkiem masz może kolejne 5 monet przy sobie?,Por acaso teria mais 5 de ouro aí?,,"Ai cumva, din întâmplare, 5 monezi de aur?",У тебя случайно не найдётся ещё 5 монеток?,,Har du av en slump 5 guldpengar till på dig?,Yanında 5 altın daha var mı acaba? +5 gold.,TXT_RPLY0_SCRIPT02_D1516_5GOLD,〃,,,Pět zlatých.,5 guld.,5 Gold.,,5 da oro.,5 de oro.,,5 kolikkoa.,5 pièces.,5 arany.,5 pezzi d'oro.,5ゴールドだ。,5 골드.,5 goud.,5 gull.,5 monet.,5 de ouro.,,5 monezi de aur.,5 золотых.,,Fem guld.,5 altın. "Well, poison bolts can kill the guards instantly and won't set off the alarms.",TXT_RYES0_SCRIPT02_D1516_WELLP,〃,,,"No, otrávené šípy okamžitě zabijí stráže a nikdo nevyhlásí poplach.","Nå, giftpile kan dræbe vagterne med det samme og vil ikke udløse alarmen.",Also Giftpfeile können die Wachen sofort töten und lösen keinen Alarm aus.,,"Mortigi per venenaj sagoj estas tuje kaj silente.","Matar con flechas envenenadas es instantáneo y sin alarmas.",,No niin; myrkkynuolilla voi tappaa vartijat välittömästi hälytystä laukaisematta.,Les carreaux empoisonnés tuent les gardes instantanément et discrètement.,"Hát, a mérgező nyilak azonnal a túlvilágra küldik az őröket, és a riasztó sem kapcsol be.",Le frecce avvelenate possono uccidere le guardie istantaneamente e non faranno scattare l'allarme.,"そうだな、ポイズンボルトは警備員を簡単に殺せるし、 警報を作動させることもない。",아시나요? 맹독 볼트만 있으면 경보를 울리지 않고 경비병을 죽일 수 있다는거?,"Nou, gifbouten kunnen de bewakers onmiddellijk doden en zullen het alarm niet laten afgaan.","Vel, giftbolter kan drepe vaktene øyeblikkelig og vil ikke utløse alarmen.","Więc, zatrute bełty mogą od razu zabić strażników i nie włączą alarmu.","Bem, setas venenosas podem matar guardas na hora e não disparam alarmes.",,"Păi, bolțurile otrăvite pot omorâ gardienii instant -și nu vor declanșa alarma.","Что ж, отравленными болтами можно убивать охранников быстро и бесшумно.",,Zehirli oklar muhafızları anında öldürebilir ve alarmı çalıştırmaz. -"No sir, I won't be telling you anything for free!",TXT_RNO0_SCRIPT02_D1516_NOSIR,〃,,,"Ne, ne, zadarmo ti nic říkat nebudu!","Nej, sir, jeg vil ikke fortælle dig noget gratis!","Nein, ich werde dir nichts für umsonst erzählen!",,"Ne, mi diros nenion senpage!","¡No, no diré nada gratis!","¡No, no voy a decir nada gratis!","Ehei, en kerro mitään ilmaiseksi!","Non, monsieur, je ne vous dirai rien si je ne me fais pas payer!","Nem uram, nem árulok el semmit ingyen!","No signore, non ti dirò nulla senza avere qualcosa in cambio!",いやいや、タダでは話せないな!,"죄송합니다만, 전 아무것도 무료로 말해주지 않을 겁니다!","Nee meneer, ik zal u niets gratis vertellen!","Nei, sir, jeg vil ikke fortelle deg noe gratis!","Nie panie, nie będę ci mówił niczego za darmo!","Nada disso, senhor, não vou te dizer nada de graça!",,"Nu domnule, n-o să-ți zic nimic pe gratis!","Нет, товарищ! Даром — только за амбаром!",,"Hayır efendim, size bedava bir şey söylemeyeceğim!" -You've wrung the last bit of gossip out of me already!,TXT_DLG_SCRIPT02_D3032_YOUVE,〃,,,"Už jsi ze mě vyždímal všechny klepy, co jsem měl!",Du har allerede vredet den sidste smule sladder ud af mig!,Du hast bereits das letzte bisschen Klatsch aus mir herausgequetscht!,,Vi jam eltiris de mi eĉ la lastan klaĉon.,Ya me has sacado hasta el último cotilleo.,Ya me sacaste hasta el último chisme.,Olet jo puristanut minusta kaikki juorut!,Vous m'avez tiré tous les vers du nez!,Már a legutolsó pletykát is kiszedted belőlem.,Mi hai già spremuto fino all'ultimo pettegolezzo! ,既にイキのいい噂は聞かせたぞ!,가십거리를 이미 다 털어놓았습니다. 더 뭘 바랍니까?,Je hebt de laatste roddels al uit me uitgewrongen!,Du har allerede vrengt det siste sladderet ut av meg!,Wyciągnąłeś już ze mnie ostatnią plotkę!,Você já ouviu todos os boatos que posso te contar!,,Ai stors ultimele bârfe din mine deja!,"Ты уже вытянул из меня всё, что только можно!",,Benden son dedikodumu da aldınız zaten! -What can I get for you?,TXT_DLG_SCRIPT02_D4548_WHATC,MAP02: Irale.,,,Co si budeš přát?,Hvad kan jeg få for dig?,Was kann ich für dich tun?,,Kion mi donu al vi?,¿Qué puedo ofrecerte?,,Mitä saisi olla?,Qu'est ce que je peux pour vous?,Mit tehetnék érted?,Cosa posso offrirti?,何か必要か?,무엇을 구매하고 싶어?,Wat kan ik voor u halen?,Hva vil du ha?,Co mogę dla ciebie zrobić?,Como posso te ajudar?,,Ce pot să-ți aduc?,Что я могу тебе предложить?,,Sizin için ne alabilirim? -Assault gun,TXT_RPLY0_SCRIPT02_D4548_ASSAU,〃,,,Útočnou pušku,En pistol til angreb,Sturmgewehr,,Sturmofusilon,Fusil de asalto,,Rynnäkkökivääri,Fusil d'Assaut,Gépfegyver,Fucile d'assalto,アサルトガン,돌격소총,Aanvalswapen,En automatpistol.,Karabin Szturmowy,Fuzil de assalto,,Pușcă de asalt,Штурмовую винтовку,,Saldırı silahı. -Here you go.,TXT_RYES0_SCRIPT02_D4548_HEREY,〃,,,Tu máš.,Værsgo.,Bitte sehr!,,Jen.,Aquí tienes.,,"Tässä, ole hyvä.",Voilà pour vous.,Tessék,Ecco a te.,毎度あり。,여기 있어.,Alsjeblieft.,Vær så god.,Proszę bardzo.,Aqui está.,,Poftiți.,Держи.,,Al bakalım. +și nu vor declanșa alarma.","Что ж, отравленными болтами можно убивать охранников быстро и бесшумно.",,"Tja, giftbultar kan döda vakterna omedelbart och kommer inte att utlösa larmen.",Zehirli oklar muhafızları anında öldürebilir ve alarmı çalıştırmaz. +"No sir, I won't be telling you anything for free!",TXT_RNO0_SCRIPT02_D1516_NOSIR,〃,,,"Ne, ne, zadarmo ti nic říkat nebudu!","Nej, sir, jeg vil ikke fortælle dig noget gratis!","Nein, ich werde dir nichts für umsonst erzählen!",,"Ne, mi diros nenion senpage!","¡No, no diré nada gratis!","¡No, no voy a decir nada gratis!","Ehei, en kerro mitään ilmaiseksi!","Non, monsieur, je ne vous dirai rien si je ne me fais pas payer!","Nem uram, nem árulok el semmit ingyen!","No signore, non ti dirò nulla senza avere qualcosa in cambio!",いやいや、タダでは話せないな!,"죄송합니다만, 전 아무것도 무료로 말해주지 않을 겁니다!","Nee meneer, ik zal u niets gratis vertellen!","Nei, sir, jeg vil ikke fortelle deg noe gratis!","Nie panie, nie będę ci mówił niczego za darmo!","Nada disso, senhor, não vou te dizer nada de graça!",,"Nu domnule, n-o să-ți zic nimic pe gratis!","Нет, товарищ! Даром — только за амбаром!",,"Nej, sir, jag tänker inte berätta något gratis för dig!","Hayır efendim, size bedava bir şey söylemeyeceğim!" +You've wrung the last bit of gossip out of me already!,TXT_DLG_SCRIPT02_D3032_YOUVE,〃,,,"Už jsi ze mě vyždímal všechny klepy, co jsem měl!",Du har allerede vredet den sidste smule sladder ud af mig!,Du hast bereits das letzte bisschen Klatsch aus mir herausgequetscht!,,Vi jam eltiris de mi eĉ la lastan klaĉon.,Ya me has sacado hasta el último cotilleo.,Ya me sacaste hasta el último chisme.,Olet jo puristanut minusta kaikki juorut!,Vous m'avez tiré tous les vers du nez!,Már a legutolsó pletykát is kiszedted belőlem.,Mi hai già spremuto fino all'ultimo pettegolezzo! ,既にイキのいい噂は聞かせたぞ!,가십거리를 이미 다 털어놓았습니다. 더 뭘 바랍니까?,Je hebt de laatste roddels al uit me uitgewrongen!,Du har allerede vrengt det siste sladderet ut av meg!,Wyciągnąłeś już ze mnie ostatnią plotkę!,Você já ouviu todos os boatos que posso te contar!,,Ai stors ultimele bârfe din mine deja!,"Ты уже вытянул из меня всё, что только можно!",,Du har redan pressat ut det sista skvallret ur mig!,Benden son dedikodumu da aldınız zaten! +What can I get for you?,TXT_DLG_SCRIPT02_D4548_WHATC,MAP02: Irale.,,,Co si budeš přát?,Hvad kan jeg få for dig?,Was kann ich für dich tun?,,Kion mi donu al vi?,¿Qué puedo ofrecerte?,,Mitä saisi olla?,Qu'est ce que je peux pour vous?,Mit tehetnék érted?,Cosa posso offrirti?,何か必要か?,무엇을 구매하고 싶어?,Wat kan ik voor u halen?,Hva vil du ha?,Co mogę dla ciebie zrobić?,Como posso te ajudar?,,Ce pot să-ți aduc?,Что я могу тебе предложить?,,Vad kan jag få för dig?,Sizin için ne alabilirim? +Assault gun,TXT_RPLY0_SCRIPT02_D4548_ASSAU,〃,,,Útočnou pušku,En pistol til angreb,Sturmgewehr,,Sturmofusilon,Fusil de asalto,,Rynnäkkökivääri,Fusil d'Assaut,Gépfegyver,Fucile d'assalto,アサルトガン,돌격소총,Aanvalswapen,En automatpistol.,Karabin Szturmowy,Fuzil de assalto,,Pușcă de asalt,Штурмовую винтовку,,En attackpistol,Saldırı silahı. +Here you go.,TXT_RYES0_SCRIPT02_D4548_HEREY,〃,,,Tu máš.,Værsgo.,Bitte sehr!,,Jen.,Aquí tienes.,,"Tässä, ole hyvä.",Voilà pour vous.,Tessék,Ecco a te.,毎度あり。,여기 있어.,Alsjeblieft.,Vær så god.,Proszę bardzo.,Aqui está.,,Poftiți.,Держи.,,Här får du.,Al bakalım. You can't afford that right now.,TXT_RNO0_SCRIPT02_D4548_YOUCA,〃,,,Tu si teď nemůžeš dovolit.,Det har du ikke råd til lige nu.,Das kannst du dir momentan nicht leisten.,,"Vi nun ne havas -sufiĉe da oro.",No te alcanza por ahora.,,Sinulla ei ole siihen juuri nyt varaa.,Vous n'avez pas assez d'argent.,Erre most nincs pénzed.,Non hai abbastanza soldi.,今それを買える余裕は無い。,그걸 사기엔 여유가 없는 것 같네.,Dat kunt je zich nu niet veroorloven.,Det har du ikke råd til akkurat nå.,Nie możesz teraz tego kupić.,Você não pode comprar isso no momento.,,Nu-ți poți permite asta încă.,Ты пока не можешь себе это позволить.,,Şu anda bunu karşılayamazsın. -Clip of bullets,TXT_RPLY1_SCRIPT02_D4548_CLIPO,〃,,,Zásobník nábojů,Et magasin med kugler,Gewehrmunition.,,Magazenon,Un cargador,,Luotilipas,Chargeur de balles,Egy tár töltény,Un caricatore di proiettili,銃弾倉,돌격소총 탄창,Klem van kogels,Et magasin med kuler.,Magazynek,Carregador de balas,,Cartuș de gloanțe,Обойму патронов,,Mermi şarjörü -Thanks.,TXT_RYES1_SCRIPT02_D4548_THANK,〃,,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszi.,Grazie.,どうも。,고맙다!,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Благодарю.,,Teşekkürler. -"Come on, 10 gold.",TXT_RNO1_SCRIPT02_D4548_COMEO,〃,,,"No tak, jen deset zlatých.","Kom nu, 10 guld.","Na komm, 10 Gold.",,"Nu, ĝi kostas 10 da oro.","Vamos, que son 10 de oro.",,"Antaa tulla, 10 kolikkoa.","Allez, 10 pièces.","Gyerünk, 10 arany.","Avanti, 10 pezzi d'oro.",頼むぜ、10ゴールドだぞ。,10 골드만 있으면 되는데...,"Kom op, 10 goud.","Kom igjen, 10 gull.","No weź, 10 monet.","Vamos lá, 10 de ouro.",,"Haide, 10 monezi de aur.","Ну же, 10 золотых.",,"Hadi, 10 altın." -Ammo box,TXT_RPLY2_SCRIPT02_D4548_AMMOB,〃,,,Krabici nábojů,Ammo kasse,Munitionsschachtel,,Municikesto,Caja de municiones,,Ammuslaatikko,Bôite de balles,Egy doboz lőszer,Scatola di munizioni,銃弾倉箱,돌격소총 탄약 박스,Munitie doos,Ammunisjonsboks,Pudło z amunicją,Caixa de balas,,Cutie cu muniție,Коробку патронов,,Cephane kutusu -Here's your ammo.,TXT_RYES2_SCRIPT02_D4548_HERES,〃,,,Tady je tvá munice.,Her er din ammunition.,Hier ist deine Munition.,,Jen via municio.,Aquí está tu munición.,,Tässä ammuksesi.,Voilà vos munitions.,Itt a lőszered.,Ecco le tue munizioni.,これでアンタのブツだ。,탄약 여기 있어!,Hier is je munitie.,Her er ammunisjonen din.,Oto twoja amunicja.,Aqui está a sua munição.,,Poftiți muniția.,Вот твои патроны.,,İşte cephanen. +sufiĉe da oro.",No te alcanza por ahora.,,Sinulla ei ole siihen juuri nyt varaa.,Vous n'avez pas assez d'argent.,Erre most nincs pénzed.,Non hai abbastanza soldi.,今それを買える余裕は無い。,그걸 사기엔 여유가 없는 것 같네.,Dat kunt je zich nu niet veroorloven.,Det har du ikke råd til akkurat nå.,Nie możesz teraz tego kupić.,Você não pode comprar isso no momento.,,Nu-ți poți permite asta încă.,Ты пока не можешь себе это позволить.,,Du har inte råd med den just nu.,Şu anda bunu karşılayamazsın. +Clip of bullets,TXT_RPLY1_SCRIPT02_D4548_CLIPO,〃,,,Zásobník nábojů,Et magasin med kugler,Gewehrmunition.,,Magazenon,Un cargador,,Luotilipas,Chargeur de balles,Egy tár töltény,Un caricatore di proiettili,銃弾倉,돌격소총 탄창,Klem van kogels,Et magasin med kuler.,Magazynek,Carregador de balas,,Cartuș de gloanțe,Обойму патронов,,Kulor.,Mermi şarjörü +Thanks.,TXT_RYES1_SCRIPT02_D4548_THANK,〃,,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszi.,Grazie.,どうも。,고맙다!,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Благодарю.,,Tack.,Teşekkürler. +"Come on, 10 gold.",TXT_RNO1_SCRIPT02_D4548_COMEO,〃,,,"No tak, jen deset zlatých.","Kom nu, 10 guld.","Na komm, 10 Gold.",,"Nu, ĝi kostas 10 da oro.","Vamos, que son 10 de oro.",,"Antaa tulla, 10 kolikkoa.","Allez, 10 pièces.","Gyerünk, 10 arany.","Avanti, 10 pezzi d'oro.",頼むぜ、10ゴールドだぞ。,10 골드만 있으면 되는데...,"Kom op, 10 goud.","Kom igjen, 10 gull.","No weź, 10 monet.","Vamos lá, 10 de ouro.",,"Haide, 10 monezi de aur.","Ну же, 10 золотых.",,"Kom igen, 10 guld.","Hadi, 10 altın." +Ammo box,TXT_RPLY2_SCRIPT02_D4548_AMMOB,〃,,,Krabici nábojů,Ammo kasse,Munitionsschachtel,,Municikesto,Caja de municiones,,Ammuslaatikko,Bôite de balles,Egy doboz lőszer,Scatola di munizioni,銃弾倉箱,돌격소총 탄약 박스,Munitie doos,Ammunisjonsboks,Pudło z amunicją,Caixa de balas,,Cutie cu muniție,Коробку патронов,,Ammunitionslåda,Cephane kutusu +Here's your ammo.,TXT_RYES2_SCRIPT02_D4548_HERES,〃,,,Tady je tvá munice.,Her er din ammunition.,Hier ist deine Munition.,,Jen via municio.,Aquí está tu munición.,,Tässä ammuksesi.,Voilà vos munitions.,Itt a lőszered.,Ecco le tue munizioni.,これでアンタのブツだ。,탄약 여기 있어!,Hier is je munitie.,Her er ammunisjonen din.,Oto twoja amunicja.,Aqui está a sua munição.,,Poftiți muniția.,Вот твои патроны.,,Här är din ammunition.,İşte cephanen. Maybe some other time.,TXT_RNO2_SCRIPT02_D4548_MAYBE,〃,,,Možná někdy jindy.,Måske en anden gang.,Vielleicht ein anderes Mal.,,Eble alimomente.,"Puede que en -otro momento.",,Ehkä joku toinen kerta.,Peut être une autre fois.,Talán majd máskor.,Magari un'altra volta.,また後でな。,아마도 나중에...,Misschien een andere keer.,Kanskje en annen gang.,Może innym razem.,Talvez outra hora.,,Poate altădată.,"Может, в другой раз.",,Belki başka bir zaman. +otro momento.",,Ehkä joku toinen kerta.,Peut être une autre fois.,Talán majd máskor.,Magari un'altra volta.,また後でな。,아마도 나중에...,Misschien een andere keer.,Kanskje en annen gang.,Może innym razem.,Talvez outra hora.,,Poate altădată.,"Может, в другой раз.",,Kanske en annan gång.,Belki başka bir zaman. Good news from the Front for a change. Macil sent you for a reward and training. He's instructed me to give them to you.,TXT_DLG_SCRIPT02_D6064_GOODN,〃 (After destroying the crystal in the Power Station),,,"Pro jednou dobré zprávy od Fronty. Macil tě poslal pro odměnu a trénink. Řekl mi, že ti to mám předat.",Gode nyheder fra fronten til en forandring. Macil har sendt dig for at få en belønning og træning. Han har instrueret mig om at give dig dem.,"Gute Nachrichten von der Front zur Abwechslung. Macil lässt dir eine Belohnung und Training zukommen. Er hat mir aufgetragen, es dir zu geben.",,"Estas bonaj novaĵoj el la Fronto, laŭ la kutimo. Macil sendis oron kaj trejniĝon por vi. Li instrukciis, ke mi donu ilin al vi.","Buenas noticias desde el Frente, para variar. Macil te manda oro y entrenamiento. Me ha solicitado dártelos.","Buenas noticias desde el Frente, para variar. Macil te manda oro y entrenamiento. Me solicitó dártelos.",Hyviä uutisia Rintamalta vaihteeksi. Macil kutsui sinut saamaan minun kauttani palkkion ja koulutusta.,Des bonnes nouvelles du Front pour une fois. Macil t'a envoyé pour une récompense et de l'entraînement. Il m'a instruit de te les procurer.,"Jó hírekkel szolgálhatok a frontról a változatosság kedvéért. Macil érted küldött egy kis jutalommal a kiképzésért cserébe. Azt parancsolta, hogy adjam oda őket.",Buone notizie dal Fronte per una volta. Macil ti ha inviato una ricompensa e predisposto per l'addestramento. Mi ha raccomandato di procurarteli.,"フロントから朗報だ。 マシルは貴方に報酬と訓練の許可を送った。 -私はそれらを貴方に渡す為に持って来た。","프론트로부터 좋은 소식을 들었어. 마실 사령관님이 보상과 훈련받을 특권을 당신에게 전해주라는군. 이미 준비된 것 같으니, 시작할까?",Goed nieuws van het Front voor de verandering. Macil heeft je gestuurd voor een beloning en training. Hij heeft me geïnstrueerd om ze aan jou te geven.,Gode nyheter fra fronten til en forandring. Macil sendte deg for belønning og trening. Han ba meg gi dem til deg.,"Dobre wieści od Frontu dla odmiany. Macil wysłał cię po nagrodę i na trening. Poinstruował mnie, aby ci je dostarczyć.",Boas notícias da Frente pra variar. O Macil enviou uma recompensa e treinamento para você. Ele me deu ordens para passá-los a você.,,"În sfârșit, niște vești bune venite de pe Front. Ai venit de la Macil pentru o recompensă și niste instruire este? Mi-a ordonat ca eu să ți le ofer.","Наконец-то, хорошие новости от Сопротивления. Ты пришёл от Мэйсила за наградой и обучением. Он распорядился, чтобы я дал тебе их.",,Değişiklik olsun diye cepheden iyi haberler var. Macil seni ödül ve eğitim için gönderdi. Onları sana vermemi emretti. -Thanks.,TXT_RPLY0_SCRIPT02_D6064_THANK,〃 (〃),,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszi.,Grazie.,ありがとう。,고맙습니다.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Спасибо.,,Teşekkürler. -Glad to be of service.,TXT_RYES0_SCRIPT02_D6064_GLADT,〃 (〃),,,Rád jsem pomohl.,Glad for at være til tjeneste.,Es war mir eine Freude dir zu Diensten zu sein,,Estas plezuro esti serva.,Un placer atenderte.,,Onneksi voin olla avuksi.,Ravi de vous avoir servi.,Szíves örömest segítek.,Felice di essere utile.,感謝する。,도와줄 수 있어서 영광이야.,Blij om van dienst te zijn.,Glad for å stå til tjeneste.,"Cieszę się, że mogłem pomóc.",É um prazer serví-los.,,Mă bucur să fiu util.,Рад помочь.,,Hizmet edebildiğime sevindim. +私はそれらを貴方に渡す為に持って来た。","프론트로부터 좋은 소식을 들었어. 마실 사령관님이 보상과 훈련받을 특권을 당신에게 전해주라는군. 이미 준비된 것 같으니, 시작할까?",Goed nieuws van het Front voor de verandering. Macil heeft je gestuurd voor een beloning en training. Hij heeft me geïnstrueerd om ze aan jou te geven.,Gode nyheter fra fronten til en forandring. Macil sendte deg for belønning og trening. Han ba meg gi dem til deg.,"Dobre wieści od Frontu dla odmiany. Macil wysłał cię po nagrodę i na trening. Poinstruował mnie, aby ci je dostarczyć.",Boas notícias da Frente pra variar. O Macil enviou uma recompensa e treinamento para você. Ele me deu ordens para passá-los a você.,,"În sfârșit, niște vești bune venite de pe Front. Ai venit de la Macil pentru o recompensă și niste instruire este? Mi-a ordonat ca eu să ți le ofer.","Наконец-то, хорошие новости от Сопротивления. Ты пришёл от Мэйсила за наградой и обучением. Он распорядился, чтобы я дал тебе их.",,Goda nyheter från fronten för en gångs skull. Macil skickade dig för en belöning och utbildning. Han har instruerat mig att ge dig dem.,Değişiklik olsun diye cepheden iyi haberler var. Macil seni ödül ve eğitim için gönderdi. Onları sana vermemi emretti. +Thanks.,TXT_RPLY0_SCRIPT02_D6064_THANK,〃 (〃),,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszi.,Grazie.,ありがとう。,고맙습니다.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Спасибо.,,Tack.,Teşekkürler. +Glad to be of service.,TXT_RYES0_SCRIPT02_D6064_GLADT,〃 (〃),,,Rád jsem pomohl.,Glad for at være til tjeneste.,Es war mir eine Freude dir zu Diensten zu sein,,Estas plezuro esti serva.,Un placer atenderte.,,Onneksi voin olla avuksi.,Ravi de vous avoir servi.,Szíves örömest segítek.,Felice di essere utile.,感謝する。,도와줄 수 있어서 영광이야.,Blij om van dienst te zijn.,Glad for å stå til tjeneste.,"Cieszę się, że mogłem pomóc.",É um prazer serví-los.,,Mă bucur să fiu util.,Рад помочь.,,Glad att vara till tjänst.,Hizmet edebildiğime sevindim. "All right, here's a few pointers on what to do: don't get in the way of Crusaders: firing short bursts from your assault gun keeps it on target.",TXT_DLG_SCRIPT02_D7580_ALLRI,〃 (〃),,,"Jistě, tady je pár rad, co dělat: Nepleť se do cesty Křižákům. Střílení krátkých dávek z pušky ti zaručí přesnost.",,"Also, hier hast du ein paar Hinweise: Gerate nicht ins Visier der Ordensritter: Wenn du kurze Feuerstöße mit deinem Sturmgewehr abgibst, triffst du besser.",,"Bone, jen kelkaj konsiloj. Ne staru antaŭ Krucistoj; pafi mallongajn ŝprucojn per la sturmofusilo estas sufiĉe por teni vian celon.","Muy bien, aquí algunos consejos. No te pongas frente a los Cruzados: disparar ráfagas cortas con el fusil de asalto basta para mantenerte en el blanco.",,"No niin, ihan vain ohjeeksi: Pysy pois ristiretkeläisten tieltä; hallituilla rynnäkkökiväärin sarjoilla pidät kiväärin tähtäimissäsi.","Bon, voilà quelques conseils sur ce que tu devrais faire: Ne vas pas te mêler aux croisés. Tirer en courte rafales avec le fusil d'assaut te permet de rester sur ta cible.","Na jól van, itt egy kis útbaigazítás neked: Ne kerülj a keresztesek útjába: Gépfegyveredből rövid sorozatokat leadva pontosabban tudsz célozni.","Bene, ecco alcuni consigli sul da farsi: non metterti davanti ai Crociati: sparare singole raffiche con il tuo fucile d'assalto fa si che l'arma rimane sul bersaglio.","オーライ、 それで何をすべきかについて説明がある :クルセイダーの斜線に立つな -:アサルトガンを遠くから的に向かって撃て",좋아. 먼저 배워둬야 할 것은: 크루세이더를 제압하기 위해선 가능한 한 멀리서 상대해야 해. 그리고 돌격소총의 방아쇠를 한 번 누르면 정확한 3 점발사격이 가능하지. ,"Oké, hier zijn een paar tips over wat je moet doen: sta kruisvaarders niet in de weg: korte uitbarstingen van je aanvalsgeweer houden het doelwit.","Greit, her er noen tips om hva du skal gjøre: Ikke kom i veien for korsfarerne. Korte salver fra angrepsgeværet holder det på målet.","W porządku, oto kilka wskazówek co trzeba robić: nie wchodzić w drogę Krzyżowcom: strzelanie krótkimi seriami z karabinu szturmowego utrzymuje cel.","Muito bem, tenho alguns conselhos pra te dar: não se meta na frente dos Cruzados: atire rajadas curtas com o seu fuzil de assalto para ter mais precisão.",,"În regulă, uite niște puncte de reper: Nu te băga în calea Cruciaților: Focurile scurte ale armei tale de asalt sunt cele mai eficiente.","Отлично, вот несколько советов: не попадайся под ноги крестоносцам; из штурмовой винтовки лучше всего стрелять короткими очередями.",,"Pekala, işte size ne yapmanız gerektiğine dair birkaç ipucu: Haçlıların yoluna çıkmayın: saldırı silahınızla kısa aralıklarla ateş etmek onu hedefte tutar." -Is that it?,TXT_RPLY0_SCRIPT02_D7580_ISTHA,〃 (〃),,,To je všechno?,Er det det?,War es das?,,Ĉu nenio alia?,¿Eso es todo?,,Siinä kaikki?,C'est tout?,Ennyi?,Tutto qui?,そうなのか?,그게 답니까?,Is dat het?,Var det alt?,To wszystko?,Só isso?,,Asta e?,И всё?,,Bu kadar mı? +:アサルトガンを遠くから的に向かって撃て",좋아. 먼저 배워둬야 할 것은: 크루세이더를 제압하기 위해선 가능한 한 멀리서 상대해야 해. 그리고 돌격소총의 방아쇠를 한 번 누르면 정확한 3 점발사격이 가능하지. ,"Oké, hier zijn een paar tips over wat je moet doen: sta kruisvaarders niet in de weg: korte uitbarstingen van je aanvalsgeweer houden het doelwit.","Greit, her er noen tips om hva du skal gjøre: Ikke kom i veien for korsfarerne. Korte salver fra angrepsgeværet holder det på målet.","W porządku, oto kilka wskazówek co trzeba robić: nie wchodzić w drogę Krzyżowcom: strzelanie krótkimi seriami z karabinu szturmowego utrzymuje cel.","Muito bem, tenho alguns conselhos pra te dar: não se meta na frente dos Cruzados: atire rajadas curtas com o seu fuzil de assalto para ter mais precisão.",,"În regulă, uite niște puncte de reper: Nu te băga în calea Cruciaților: Focurile scurte ale armei tale de asalt sunt cele mai eficiente.","Отлично, вот несколько советов: не попадайся под ноги крестоносцам; из штурмовой винтовки лучше всего стрелять короткими очередями.",,"Okej, här är några tips om vad du ska göra: Ställ dig inte i vägen för korsfarare: Genom att avfyra korta salvor från ditt stormgevär håller du det i mål.","Pekala, işte size ne yapmanız gerektiğine dair birkaç ipucu: Haçlıların yoluna çıkmayın: saldırı silahınızla kısa aralıklarla ateş etmek onu hedefte tutar." +Is that it?,TXT_RPLY0_SCRIPT02_D7580_ISTHA,〃 (〃),,,To je všechno?,Er det det?,War es das?,,Ĉu nenio alia?,¿Eso es todo?,,Siinä kaikki?,C'est tout?,Ennyi?,Tutto qui?,そうなのか?,그게 답니까?,Is dat het?,Var det alt?,To wszystko?,Só isso?,,Asta e?,И всё?,,Är det så?,Bu kadar mı? "Look, you'll learn more later.",TXT_RYES0_SCRIPT02_D7580_LOOKY,〃 (〃),,,"Hele, víc se toho naučíš pak.","Hør, du vil få mere at vide senere.",Fürs Erste ja. Du wirst später noch mehr lernen.,,"Nu, vi lernos pli poste.","Ya aprenderás más después.","Ya vas a aprender -más después.",Saat oppia kyllä lisää myöhemmin.,Tu en apprendras davantage plus tard.,"Nézd, később majd többet fogsz megtudni.","Guarda, imparerai di più dopo.",良し、後でもっと学べるぞ。,나중에 알려줄게.,"Kijk, je komt er later meer over te weten.",Du får vite mer senere.,"Zobacz, później nauczysz się więcej.","Olha, você vai aprender mais depois.",,"Uite, o să afli mai multe mai târziu.","Позже узнаешь больше, хорошо?",,"Bak, daha sonra daha fazlasını öğreneceksin." +más después.",Saat oppia kyllä lisää myöhemmin.,Tu en apprendras davantage plus tard.,"Nézd, később majd többet fogsz megtudni.","Guarda, imparerai di più dopo.",良し、後でもっと学べるぞ。,나중에 알려줄게.,"Kijk, je komt er later meer over te weten.",Du får vite mer senere.,"Zobacz, później nauczysz się więcej.","Olha, você vai aprender mais depois.",,"Uite, o să afli mai multe mai târziu.","Позже узнаешь больше, хорошо?",,Du kommer att få veta mer senare.,"Bak, daha sonra daha fazlasını öğreneceksin." "I think I can convert a flamethrower from one of the Crusaders for use by a human. Oh, anything else I can get you?",TXT_DLG_SCRIPT02_D9096_ITHIN,〃 (〃),,,"Myslím, že bych mohl předělat plamenomet z jednoho z těch Křižáků pro použití člověkem. No, budeš si ještě něco přát?","Jeg tror, jeg kan omdanne en flammekaster fra en af korsfarerne til brug for et menneske. Er der andet, jeg kan skaffe dig?","Ich denke ich kann einen Flammenwerfer von einen der Ordensritter umbauen, damit ein Mensch ihn benutzen kann. Oh, kann ich dir sonst noch etwas besorgen?",,"Mi kredas, ke mi povas modifi la flamĵetilon de Krucisto, por ke homo povu uzi ĝin. Ha, ĉu io alia, kion mi povas doni al vi?","Creo que puedo modificar el lanzallamas de alguno de los Cruzados para que lo pueda usar un humano. Ah, ¿algo más para ofrecerte?",,Luulen pystyväni tekemään ristiretkeläisen liekinheittimestä ihmiskäyttöisen. Voinko olla vielä jotenkin muuten avuksi?,Je crois que je peux convertir un lance-flammes de croisé pour être utilisé par un humain. Je peux faire quelque chose d'autre pour vous?,"Azt hiszem, ha az egyik keresztesről leszednénk egy lángszórót, azt át tudnám alakítani emberi használatra. Ó, még valamit tehetek érted?","Penso di poter convertire un lanciafiamme da uno dei Crociati per essere usato da un umano. Oh, desideri qualcos'altro?","俺ならクルセイダー専用の火炎放射器を 誰でも使える様に作り変えられるだろう。 ああ、他に何か必要か?",크루세이더가 사용하는 화염방사기를 사람들이 다룰 수 있도록 개조할 수 있을 것 같아. 그래서... 뭘 원해?,"Ik denk dat ik een vlammenwerper van een van de kruisvaarders kan bekeren voor gebruik door een mens. Oh, kan ik nog iets anders voor je halen?",Jeg tror jeg kan konvertere en flammekaster fra en av korsfarerne til å brukes av et menneske. Noe annet jeg kan gi deg?,"Myślę, że mogę przerobić miotacz ognia jednego z Krzyżowców, by mógł z niego korzystać człowiek. Oh, czy mogę coś jeszcze dla ciebie zrobić?","Acho que eu consigo converter o lança-chamas de um dos Cruzados para ser usado por um humano. Ah, posso te ajudar com mais alguma coisa?",,"Cred că pot converti aruncătorul de flăcări de la un Cruciat pentru a putea fi folosit de oameni. Oh, mai pot să-ți aduc ceva?","Думаю, я смогу приспособить огнемёт для ручного использования. А, ты что-то ещё хотел? -",,Sanırım Haçlılardan birinin alev silahını bir insan tarafından kullanılmak üzere dönüştürebilirim. Sana verebileceğim başka bir şey var mı? -Flamethrower.,TXT_RPLY0_SCRIPT02_D9096_FLAME,〃 (〃),,,Plamenomet.,Flammekaster.,Flammenwerfer,,Flamĵetilon,Lanzallamas.,,Liekinheitin.,Lance-flammes.,Lángszóró.,Lanciafiamme.,火炎放射器,화염방사기?,Vlammenwerper.,Flammekaster.,Miotacz Ognia,Lança-chamas.,,Aruncător de flăcări.,Огнемёт.,,Alev makinesi. +",,"Jag tror att jag kan konvertera en eldkastare från en av korsfararna så att den kan användas av en människa. Åh, något annat jag kan ge dig?",Sanırım Haçlılardan birinin alev silahını bir insan tarafından kullanılmak üzere dönüştürebilirim. Sana verebileceğim başka bir şey var mı? +Flamethrower.,TXT_RPLY0_SCRIPT02_D9096_FLAME,〃 (〃),,,Plamenomet.,Flammekaster.,Flammenwerfer,,Flamĵetilon,Lanzallamas.,,Liekinheitin.,Lance-flammes.,Lángszóró.,Lanciafiamme.,火炎放射器,화염방사기?,Vlammenwerper.,Flammekaster.,Miotacz Ognia,Lança-chamas.,,Aruncător de flăcări.,Огнемёт.,,Flamkastare,Alev makinesi. "I knew that'd work! Here you go, take her for a spin!",TXT_RYES0_SCRIPT02_D9096_IKNEW,〃 (〃),,,"Věděl jsem, že to bude fungovat! Tady máš, pořádně ho rozpal!","Jeg vidste, at det ville virke! Værsgo, tag en tur med hende!","Ich wusste das würde funktionieren! Bitte sehr, probiere ihn mal aus!",,"Mi sciis, ke tio sukcesus! Jen ĝi. Provu ĝin!","¡Sabía que iba a resultar! -Aquí tienes. ¡Pruébalo!",,"Tiesin sen toimivan! Anna palaa, vie se kierrokselle!",Je savais que ça marcherait! Prends-le et va donc l'essayer!,"Tudtam, hogy ez működni fog! Nesze vidd el egy körre!",Lo sapevo che avrebbe funzionato! Prendilo e vai a provarlo!,よくやってくれた! どうよ、このアツアツな子を!,"역시 잘 작동할 줄 알았어! 여기, 화염방사기야. 한번 놈들에게 사용해봐!","Ik wist dat dat zou werken! Alsjeblieft, neem haar mee voor een ritje!","Jeg visste det ville fungere! Vær så god, ta en tur med den!","Wiedziałem, że zadziała! Masz, przetestuj ją!","Eu sabia que daria certo! Toma, leva pra testar!",,"Stiam că va funcționa! Uite, ia-o la o tură!","Я и не сомневался, что всё получится! Держи, испробуй его на ком-нибудь!",,"Bunun işe yarayacağını biliyordum! Al bakalım, bir tur at!" +Aquí tienes. ¡Pruébalo!",,"Tiesin sen toimivan! Anna palaa, vie se kierrokselle!",Je savais que ça marcherait! Prends-le et va donc l'essayer!,"Tudtam, hogy ez működni fog! Nesze vidd el egy körre!",Lo sapevo che avrebbe funzionato! Prendilo e vai a provarlo!,よくやってくれた! どうよ、このアツアツな子を!,"역시 잘 작동할 줄 알았어! 여기, 화염방사기야. 한번 놈들에게 사용해봐!","Ik wist dat dat zou werken! Alsjeblieft, neem haar mee voor een ritje!","Jeg visste det ville fungere! Vær så god, ta en tur med den!","Wiedziałem, że zadziała! Masz, przetestuj ją!","Eu sabia que daria certo! Toma, leva pra testar!",,"Stiam că va funcționa! Uite, ia-o la o tură!","Я и не сомневался, что всё получится! Держи, испробуй его на ком-нибудь!",,"Jag visste att det skulle fungera! Varsågod, ta en sväng med henne!","Bunun işe yarayacağını biliyordum! Al bakalım, bir tur at!" "Listen, I can't make anything without the right parts!",TXT_RNO0_SCRIPT02_D9096_LISTE,〃 (〃),,,"Poslyš, bez použitelných součástek ti nic nepostavím!","Hør, jeg kan ikke lave noget uden de rigtige dele!","Hör zu, ohne die richtigen Teile kann ich dir nichts machen!",,"Nu, mi povas fari nenion sen la ĝustaj partoj!","A ver, ¡no puedo hacer nada -sin las partes correctas!",,"Kuules, ilman oikeita osia en pysty tekemään mitään!","Ecoute, je ne peux pas faire quoi que ce soit si je n'ai pas les pièces dont j'ai besoin!","Figyu, a megfelelő alkatrészek nélkül semmit sem tudok tenni.","Senti, non posso creare nulla senza i pezzi che mi servono!",部品が無ければ何も出来ない!,"이봐, 제대로 된 부품 없이는 아무 것도 할 수 없다고!","Luister, ik kan niets maken zonder de juiste onderdelen!",Jeg kan ikke lage noe uten de rette delene!,"Słuchaj, nie mogę nic zrobić bez właściwych części!","Escuta, eu não consigo fazer qualquer coisa sem as peças certas!",,"Ascultă, nu pot face nimic fără părțile corespunzătoare!","Слушай, у меня нет нужных деталей!",,"Dinle, doğru parçalar olmadan hiçbir şey yapamam!" -Assault gun,TXT_RPLY1_SCRIPT02_D9096_ASSAU,〃 (〃),,,Útočnou pušku,Angrebsvåben,Sturmgewehr,,Sturmofusilon,Fusil de asalto,,Rynnäkkökivääri,Fusil d'Assaut,Gépfegyver,Fucile d'assalto,アサルトガン,돌격소총,Aanvalswapen,Flammekaster.,Karabin Szturmowy,Fuzil de assalto,,Armă de asalt,Штурмовую винтовку,,Saldırı silahı -"Well, here you go sir!",TXT_RYES1_SCRIPT02_D9096_WELLH,〃 (〃),,,"Tak tady máte, pane!","Værsgo, sir!","Alles klar, bitteschön!",,"Nu, jen, sinjoro!","¡Bueno, aquí tiene, caballero!",,"Kas tässä, hyvä herra!","Voilà pour vous, monsieur!","Nos, parancsoljon!","Bene, ecco qua signore!",ほら、毎度あり!,여기 대령이요!,"Nou, alsjeblieft, meneer!",Vær så god!,Oto jest proszę pana!,"Bem, aqui está, senhor!",,"Poftiți, domnule!",Забирай!,,Buyurun efendim! +sin las partes correctas!",,"Kuules, ilman oikeita osia en pysty tekemään mitään!","Ecoute, je ne peux pas faire quoi que ce soit si je n'ai pas les pièces dont j'ai besoin!","Figyu, a megfelelő alkatrészek nélkül semmit sem tudok tenni.","Senti, non posso creare nulla senza i pezzi che mi servono!",部品が無ければ何も出来ない!,"이봐, 제대로 된 부품 없이는 아무 것도 할 수 없다고!","Luister, ik kan niets maken zonder de juiste onderdelen!",Jeg kan ikke lage noe uten de rette delene!,"Słuchaj, nie mogę nic zrobić bez właściwych części!","Escuta, eu não consigo fazer qualquer coisa sem as peças certas!",,"Ascultă, nu pot face nimic fără părțile corespunzătoare!","Слушай, у меня нет нужных деталей!",,"Lyssna, jag kan inte göra något utan rätt delar!","Dinle, doğru parçalar olmadan hiçbir şey yapamam!" +Assault gun,TXT_RPLY1_SCRIPT02_D9096_ASSAU,〃 (〃),,,Útočnou pušku,Angrebsvåben,Sturmgewehr,,Sturmofusilon,Fusil de asalto,,Rynnäkkökivääri,Fusil d'Assaut,Gépfegyver,Fucile d'assalto,アサルトガン,돌격소총,Aanvalswapen,Flammekaster.,Karabin Szturmowy,Fuzil de assalto,,Armă de asalt,Штурмовую винтовку,,Anfallspistol,Saldırı silahı +"Well, here you go sir!",TXT_RYES1_SCRIPT02_D9096_WELLH,〃 (〃),,,"Tak tady máte, pane!","Værsgo, sir!","Alles klar, bitteschön!",,"Nu, jen, sinjoro!","¡Bueno, aquí tiene, caballero!",,"Kas tässä, hyvä herra!","Voilà pour vous, monsieur!","Nos, parancsoljon!","Bene, ecco qua signore!",ほら、毎度あり!,여기 대령이요!,"Nou, alsjeblieft, meneer!",Vær så god!,Oto jest proszę pana!,"Bem, aqui está, senhor!",,"Poftiți, domnule!",Забирай!,,"Här har du, sir!",Buyurun efendim! "Obviously, you can't afford that right now.",TXT_RNO1_SCRIPT02_D9096_OBVIO,〃 (〃),,,Tu si teď opravdu nemůžeš dovolit.,Du har tydeligvis ikke råd til den lige nu.,Offensichtlich kannst du dir das im Moment nicht leisten.,,"Evidente vi nun ne havas sufiĉe da mono.","Obviamente no te -alcanza por ahora.",,Sinulla ei selvästikään ole siihen nyt varaa.,"Manifestement, vous ne pouvez pas vous l'offrir.","Egyértelmű, hogy ezt nem tudod most kifizetni.","Ovviamente, ora non te lo puoi permettere.",明らかに、今買える余裕は無い。,"당연하겠지만, 아직 가질 수가 없겠네.",Dat kunt je zich natuurlijk nu niet veroorloven.,Det har du selvsagt ikke råd til akkurat nå!,"Oczywiście, nie możesz teraz tego kupić.",Obviamente você não pode comprar isso agora.,,"Evident, nu-ți poți permite asta chiar acum.","Похоже, тебе это не по карману.",,Belli ki şu anda bunu karşılayamazsınız. -Clip of bullets,TXT_RPLY2_SCRIPT02_D9096_CLIPO,〃 (〃),,,Zásobník nábojů,Et patron-klip,Gewehrmunition.,,Magazenon,Un cargador,,Luotilipas,Chargeur de balles,Egy tár töltény.,Un caricatore di proiettili,銃弾倉,돌격소총 탄창,Klem van kogels,Et magasin med kuler.,Magazynek,Carregador de balas,,Cartuș de gloanțe,Обойму патронов,,Mermi şarjörü -Thanks.,TXT_RYES2_SCRIPT02_D9096_THANK,〃 (〃),,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszi.,Grazie.,どうも。,고마워.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Благодарю.,,Teşekkürler. -"Come on, 10 gold.",TXT_RNO2_SCRIPT02_D9096_COMEO,〃 (〃),,,"No tak, jen deset zlatých.","Kom nu, 10 guld.","Na komm, 10 Gold.",,"Nu, ĝi kostas 10 da oro.","Vamos, que son 10 de oro.",,"Antaa tulla, 10 kolikkoa.","Allez, 10 pièces.","Rajta, 10 aranyat.","Avanti, 10 pezzi d'oro.",頼むぜ、10ゴールドだぞ。,"이봐, 그건 10 골드짜리라고.","Kom op, 10 goud.","Kom igjen, 10 gull.","No weź, 10 monet.","Vamos lá, 10 de ouro.",,"Haide, 10 monezi de aur.","Ну же, 10 золотых.",,"Hadi, 10 altın." -Ammo box,TXT_RPLY3_SCRIPT02_D9096_AMMOB,〃 (〃),,,Krabici nábojů,Ammo kasse,Munitionsschachtel,,Municikeston,Caja de municiones,,Ammuslaatikko,Bôite de balles,Lőszeres doboz.,Scatola di munizioni,弾薬箱,돌격소총 탄약 박스,Munitie doos,Ammunisjonsboks,Pudło z amunicją,Caixa de balas,,Cutie cu muniție,Коробку патронов,,Cephane kutusu -Here's your ammo.,TXT_RYES3_SCRIPT02_D9096_HERES,〃 (〃),,,Tady je tvá munice.,Her er din ammunition.,Hier ist deine Munition.,,Jen via municio.,Aquí está tu munición.,,Tässä ammuksesi.,Voilà vos munitions.,Itt a lőszered.,Ecco le tue munizioni.,これでアンタのブツだ。,여기 탄약.,Hier is je munitie.,Her er ammunisjonen din.,Oto twoja amunicja.,Aqui está a sua munição.,,Poftiți muniția.,Вот твои патроны.,,İşte cephanen. +alcanza por ahora.",,Sinulla ei selvästikään ole siihen nyt varaa.,"Manifestement, vous ne pouvez pas vous l'offrir.","Egyértelmű, hogy ezt nem tudod most kifizetni.","Ovviamente, ora non te lo puoi permettere.",明らかに、今買える余裕は無い。,"당연하겠지만, 아직 가질 수가 없겠네.",Dat kunt je zich natuurlijk nu niet veroorloven.,Det har du selvsagt ikke råd til akkurat nå!,"Oczywiście, nie możesz teraz tego kupić.",Obviamente você não pode comprar isso agora.,,"Evident, nu-ți poți permite asta chiar acum.","Похоже, тебе это не по карману.",,Uppenbarligen har du inte råd med den just nu.,Belli ki şu anda bunu karşılayamazsınız. +Clip of bullets,TXT_RPLY2_SCRIPT02_D9096_CLIPO,〃 (〃),,,Zásobník nábojů,Et patron-klip,Gewehrmunition.,,Magazenon,Un cargador,,Luotilipas,Chargeur de balles,Egy tár töltény.,Un caricatore di proiettili,銃弾倉,돌격소총 탄창,Klem van kogels,Et magasin med kuler.,Magazynek,Carregador de balas,,Cartuș de gloanțe,Обойму патронов,,Kulor i ett klipp,Mermi şarjörü +Thanks.,TXT_RYES2_SCRIPT02_D9096_THANK,〃 (〃),,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszi.,Grazie.,どうも。,고마워.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Благодарю.,,Tack.,Teşekkürler. +"Come on, 10 gold.",TXT_RNO2_SCRIPT02_D9096_COMEO,〃 (〃),,,"No tak, jen deset zlatých.","Kom nu, 10 guld.","Na komm, 10 Gold.",,"Nu, ĝi kostas 10 da oro.","Vamos, que son 10 de oro.",,"Antaa tulla, 10 kolikkoa.","Allez, 10 pièces.","Rajta, 10 aranyat.","Avanti, 10 pezzi d'oro.",頼むぜ、10ゴールドだぞ。,"이봐, 그건 10 골드짜리라고.","Kom op, 10 goud.","Kom igjen, 10 gull.","No weź, 10 monet.","Vamos lá, 10 de ouro.",,"Haide, 10 monezi de aur.","Ну же, 10 золотых.",,"Kom igen, 10 guld.","Hadi, 10 altın." +Ammo box,TXT_RPLY3_SCRIPT02_D9096_AMMOB,〃 (〃),,,Krabici nábojů,Ammo kasse,Munitionsschachtel,,Municikeston,Caja de municiones,,Ammuslaatikko,Bôite de balles,Lőszeres doboz.,Scatola di munizioni,弾薬箱,돌격소총 탄약 박스,Munitie doos,Ammunisjonsboks,Pudło z amunicją,Caixa de balas,,Cutie cu muniție,Коробку патронов,,Ammunitionslåda,Cephane kutusu +Here's your ammo.,TXT_RYES3_SCRIPT02_D9096_HERES,〃 (〃),,,Tady je tvá munice.,Her er din ammunition.,Hier ist deine Munition.,,Jen via municio.,Aquí está tu munición.,,Tässä ammuksesi.,Voilà vos munitions.,Itt a lőszered.,Ecco le tue munizioni.,これでアンタのブツだ。,여기 탄약.,Hier is je munitie.,Her er ammunisjonen din.,Oto twoja amunicja.,Aqui está a sua munição.,,Poftiți muniția.,Вот твои патроны.,,Här är din ammunition.,İşte cephanen. Maybe some other time. Goodbye!,TXT_RNO3_SCRIPT02_D9096_MAYBE,〃 (〃),,,Možná někdy jindy. Nashledanou!,Måske en anden gang. Farvel!,Vielleicht ein anderes mal. Auf Wiedersehen!,,Eble alimomente. Ĝis!,"Puede que en otro momento. ¡Adiós!","Puede que en otro -momento. ¡Nos vemos!",Ehkä jokin toinen aika. Näkemiin!,"Peut être une autre fois, au revoir!",Talán majd valamikor máskor. Viszlát!,Sarà per un'altra volta. Arrivederci!,またの機会に、じゃあな!,다음번에 돈을 챙기고 예기하자. 잘 가!,Misschien een andere keer. Tot ziens!,Kanskje en annen gang. Adjø!,Może innym razem. Do widzenia!,Talvez outra hora. Até mais!,,Poate altădată. La revedere!,"Может, в другой раз. Пока!",,Belki başka bir zaman. Güle güle! +momento. ¡Nos vemos!",Ehkä jokin toinen aika. Näkemiin!,"Peut être une autre fois, au revoir!",Talán majd valamikor máskor. Viszlát!,Sarà per un'altra volta. Arrivederci!,またの機会に、じゃあな!,다음번에 돈을 챙기고 예기하자. 잘 가!,Misschien een andere keer. Tot ziens!,Kanskje en annen gang. Adjø!,Może innym razem. Do widzenia!,Talvez outra hora. Até mais!,,Poate altădată. La revedere!,"Может, в другой раз. Пока!",,Kanske en annan gång. Adjö!,Belki başka bir zaman. Güle güle! "Now that you have the flamethrower, is there anything else I can get you?",TXT_DLG_SCRIPT02_D10612_NOWTH,〃 (With flamethrower),,,"Teď když máš ten plamenomet, můžu pro tebe udělat něco jiného?","Nu hvor du har flammekasteren, er der så noget andet, jeg kan skaffe dig?","Jetzt wo du den Flammenwerfer hast, gibt es etwas anderes was ich dir besorgen kann?",,"Nun kiam vi havas la flamĵetilon, ĉu estas io alia, kion mi povus doni al vi?","Ahora que tienes el lanzallamas, ¿hay algo más que pueda ofrecerte?",,"Voisinko vielä jotenkin auttaa, nyt kun sinulla on liekinheitin?","Maintenant que vous avez le lance-flammes, est-ce que je peux faire quelque chose pour vous?","Most, hogy megkaptad a lángszórót is, tehetek még valamit érted?","Ora che hai il lanciafiamme, c'è qualcos'altro che ti posso dare?","火炎放射器を手に入れたが、 -他に必要な物はあるか?","이제 화염방사기를 얻었으니, 더 원하는 물품이 있나?","Nu je de vlammenwerper hebt, is er nog iets anders dat ik je kan bezorgen?","Nå som du har flammekasteren, er det noe annet jeg kan skaffe deg?","Jak już masz miotacz ognia, mogę coś jeszcze dla ciebie zrobić?",Agora que você tem o lança-chamas. Deseja mais alguma coisa?,,"Acum că ai aruncătorul de flăcări, mai pot să-ți aduc ceva?","Ну, огнемёт у тебя теперь есть. Могу я ещё чем-нибудь помочь?",,"Artık alev makinen olduğuna göre, sana verebileceğim başka bir şey var mı?" -Assault gun,TXT_RPLY0_SCRIPT02_D10612_ASSAU,〃 (〃),,,Útočnou pušku,Angrebsvåben,Sturmgewehr,,Sturmofusilon,Fusil de asalto,,Rynnäkkökivääri,Fusil d'Assaut,Gépfegyver,Fucile d'assalto,アサルトガン,돌격소총,Aanvalswapen,Stormgevær.,Karabin Szturmowy,Fuzil de assalto,,Armă de asalt,Штурмовую винтовку,,Saldırı silahı -Here you go.,TXT_RYES0_SCRIPT02_D10612_HEREY,〃 (〃),,,Tu máš.,Værsgo.,Bitte sehr!,,Jen.,Aquí tienes.,,Ole hyvä.,Voilà pour vous.,Itt is van!,Ecco a te.,毎度あり。,여기 있어.,Alsjeblieft.,Vær så god.,Proszę bardzo.,Aqui está.,,Poftiți.,Забирай!,,Al bakalım. +他に必要な物はあるか?","이제 화염방사기를 얻었으니, 더 원하는 물품이 있나?","Nu je de vlammenwerper hebt, is er nog iets anders dat ik je kan bezorgen?","Nå som du har flammekasteren, er det noe annet jeg kan skaffe deg?","Jak już masz miotacz ognia, mogę coś jeszcze dla ciebie zrobić?",Agora que você tem o lança-chamas. Deseja mais alguma coisa?,,"Acum că ai aruncătorul de flăcări, mai pot să-ți aduc ceva?","Ну, огнемёт у тебя теперь есть. Могу я ещё чем-нибудь помочь?",,"Nu när du har flamkastaren, finns det något annat jag kan ge dig?","Artık alev makinen olduğuna göre, sana verebileceğim başka bir şey var mı?" +Assault gun,TXT_RPLY0_SCRIPT02_D10612_ASSAU,〃 (〃),,,Útočnou pušku,Angrebsvåben,Sturmgewehr,,Sturmofusilon,Fusil de asalto,,Rynnäkkökivääri,Fusil d'Assaut,Gépfegyver,Fucile d'assalto,アサルトガン,돌격소총,Aanvalswapen,Stormgevær.,Karabin Szturmowy,Fuzil de assalto,,Armă de asalt,Штурмовую винтовку,,Anfallspistol,Saldırı silahı +Here you go.,TXT_RYES0_SCRIPT02_D10612_HEREY,〃 (〃),,,Tu máš.,Værsgo.,Bitte sehr!,,Jen.,Aquí tienes.,,Ole hyvä.,Voilà pour vous.,Itt is van!,Ecco a te.,毎度あり。,여기 있어.,Alsjeblieft.,Vær så god.,Proszę bardzo.,Aqui está.,,Poftiți.,Забирай!,,Varsågod.,Al bakalım. You can't afford that right now.,TXT_RNO0_SCRIPT02_D10612_YOUCA,〃 (〃),,,Tu si teď nemůžeš dovolit.,Den har du ikke råd til lige nu.,Das kannst du dir im Moment nicht leisten.,,"Vi nun ne havas -sufiĉe da oro.",No te alcanza por ahora.,,Sinulla ei ole siihen juuri nyt varaa.,Vous n'avez pas assez d'argent.,Erre jelenleg nincs pénzed.,Non hai abbastanza soldi.,今それを買える余裕は無い。,그럴 여유가 전혀 없는 것 같은데 말이지.,Dat kunt u zich nu niet veroorloven.,Det har du ikke råd til akkurat nå.,Nie możesz teraz tego kupić.,Você não pode comprar isso no momento.,,Nu-ți poți permite asta încă.,"Похоже, тебе это не по карману.",,Şu anda bunu karşılayamazsın. -Clip of bullets,TXT_RPLY1_SCRIPT02_D10612_CLIPO,〃 (〃),,,Zásobník nábojů,Et patron-klip,Gewehrmunition.,,Magazenon,Un cargador,,Luotilipas,Chargeur de balles,Egy tárnyi töltény,Un caricatore di proiettili,銃弾倉,돌격소총 탄창,Klem van kogels,Et magasin med kuler.,Magazynek,Carregador de balas,,Cartuș de gloanțe,Обойму патронов,,Mermi şarjörü -Thanks.,TXT_RYES1_SCRIPT02_D10612_THANK,〃 (〃),,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszi.,Grazie.,どうも。,고마워.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Благодарю.,,Teşekkürler. -"Come on, 10 gold.",TXT_RNO1_SCRIPT02_D10612_COMEO,〃 (〃),,,"No tak, jen deset zlatých.","Kom nu, 10 guld.","Komm schon, 10 Gold.",,"Nu, ĝi kostas 10 da oro.","Vamos, que son 10 de oro.",,"Antaa tulla, 10 kolikkoa.","Allez, 10 pièces.","Gyerünk, 10 aranyat.","Avanti, 10 pezzi d'oro.",頼むぜ、10ゴールドだぞ。,"이봐, 10 골드를 먼저 달라고.","Kom op, 10 goud.","Kom igjen, 10 gull.","No weź, 10 monet.","Vamos lá, 10 de ouro.",,"Haide, 10 monezi de aur.","Ну же, 10 золотых.",,"Hadi, 10 altın." -Ammo box,TXT_RPLY2_SCRIPT02_D10612_AMMOB,〃 (〃),,,Krabici nábojů,Ammo kasse,Munitionsschachtel,,Municikeston,Caja de municiones,,Ammuslaatikko,Boîte de balles,Töltényes doboz,Scatola di munizioni,銃弾倉箱,돌격소총 탄약 박스,Munitie doos,Ammunisjonsboks,Pudło z amunicją,Caixa de balas,,Cutie cu muniție,Коробку патронов,,Cephane kutusu -Here's your ammo.,TXT_RYES2_SCRIPT02_D10612_HERES,〃 (〃),,,Tady je tvá munice.,Her er din ammunition.,Hier ist deine Munition.,,Jen via municio.,Aquí está tu munición.,,Tässä ammuksesi.,Voilà vos munitions.,Itt a töltényed.,Ecco le tue munizioni.,これでアンタのブツだ。,여기 네 탄약이야.,Hier is je munitie.,Her er ammunisjonen din.,Oto twoja amunicja.,Aqui está a sua munição.,,Poftiți muniția.,Вот твои патроны.,,İşte cephanen. +sufiĉe da oro.",No te alcanza por ahora.,,Sinulla ei ole siihen juuri nyt varaa.,Vous n'avez pas assez d'argent.,Erre jelenleg nincs pénzed.,Non hai abbastanza soldi.,今それを買える余裕は無い。,그럴 여유가 전혀 없는 것 같은데 말이지.,Dat kunt u zich nu niet veroorloven.,Det har du ikke råd til akkurat nå.,Nie możesz teraz tego kupić.,Você não pode comprar isso no momento.,,Nu-ți poți permite asta încă.,"Похоже, тебе это не по карману.",,Du har inte råd med den just nu.,Şu anda bunu karşılayamazsın. +Clip of bullets,TXT_RPLY1_SCRIPT02_D10612_CLIPO,〃 (〃),,,Zásobník nábojů,Et patron-klip,Gewehrmunition.,,Magazenon,Un cargador,,Luotilipas,Chargeur de balles,Egy tárnyi töltény,Un caricatore di proiettili,銃弾倉,돌격소총 탄창,Klem van kogels,Et magasin med kuler.,Magazynek,Carregador de balas,,Cartuș de gloanțe,Обойму патронов,,Kulor.,Mermi şarjörü +Thanks.,TXT_RYES1_SCRIPT02_D10612_THANK,〃 (〃),,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszi.,Grazie.,どうも。,고마워.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Благодарю.,,Tack.,Teşekkürler. +"Come on, 10 gold.",TXT_RNO1_SCRIPT02_D10612_COMEO,〃 (〃),,,"No tak, jen deset zlatých.","Kom nu, 10 guld.","Komm schon, 10 Gold.",,"Nu, ĝi kostas 10 da oro.","Vamos, que son 10 de oro.",,"Antaa tulla, 10 kolikkoa.","Allez, 10 pièces.","Gyerünk, 10 aranyat.","Avanti, 10 pezzi d'oro.",頼むぜ、10ゴールドだぞ。,"이봐, 10 골드를 먼저 달라고.","Kom op, 10 goud.","Kom igjen, 10 gull.","No weź, 10 monet.","Vamos lá, 10 de ouro.",,"Haide, 10 monezi de aur.","Ну же, 10 золотых.",,"Kom igen, 10 guld.","Hadi, 10 altın." +Ammo box,TXT_RPLY2_SCRIPT02_D10612_AMMOB,〃 (〃),,,Krabici nábojů,Ammo kasse,Munitionsschachtel,,Municikeston,Caja de municiones,,Ammuslaatikko,Boîte de balles,Töltényes doboz,Scatola di munizioni,銃弾倉箱,돌격소총 탄약 박스,Munitie doos,Ammunisjonsboks,Pudło z amunicją,Caixa de balas,,Cutie cu muniție,Коробку патронов,,Ammunitionslåda,Cephane kutusu +Here's your ammo.,TXT_RYES2_SCRIPT02_D10612_HERES,〃 (〃),,,Tady je tvá munice.,Her er din ammunition.,Hier ist deine Munition.,,Jen via municio.,Aquí está tu munición.,,Tässä ammuksesi.,Voilà vos munitions.,Itt a töltényed.,Ecco le tue munizioni.,これでアンタのブツだ。,여기 네 탄약이야.,Hier is je munitie.,Her er ammunisjonen din.,Oto twoja amunicja.,Aqui está a sua munição.,,Poftiți muniția.,Вот твои патроны.,,Här är din ammunition.,İşte cephanen. Maybe some other time.,TXT_RNO2_SCRIPT02_D10612_MAYBE,〃 (〃),,,Možná někdy jindy.,Måske en anden gang.,Vielleicht ein anderes mal.,,Eble alimomente.,"Puede que en -otro momento.",,Ehkä joku toinen kerta.,Peut être une autre fois.,Talán Máskor.,Magari un'altra volta.,また後でな。,지금 말고. 아마도 나중에?,Misschien een andere keer.,Kanskje en annen gang.,Może innym razem.,Talvez outra hora.,,Poate altădată.,"Может, в другой раз.",,Belki başka bir zaman. +otro momento.",,Ehkä joku toinen kerta.,Peut être une autre fois.,Talán Máskor.,Magari un'altra volta.,また後でな。,지금 말고. 아마도 나중에?,Misschien een andere keer.,Kanskje en annen gang.,Może innym razem.,Talvez outra hora.,,Poate altădată.,"Может, в другой раз.",,Kanske en annan gång.,Belki başka bir zaman. "Now that you have the flamethrower, is there anything else I can get you?",TXT_DLG_SCRIPT02_D12128_NOWTH,〃 (〃),,,"Teď, když máš ten plamenomet, můžu pro tebe udělat něco jiného?","Nu hvor du har flammekasteren, er der så noget andet, jeg kan give dig?","Jetzt wo du den Flammenwerfer hast, gibt es etwas anderes was ich dir besorgen kann?",,"Nun kiam vi havas la flamĵetilon, ĉu estas io alia, kion mi povus doni al vi?","Ahora que tienes el lanzallamas, ¿hay algo más que pueda ofrecerte?",,"Nyt kun sinulla on liekinheitin, saisiko sinulle vielä olla jotain muuta?","Maintenant que vous avez le lance-flammes, est-ce que je peux faire quelque chose pour vous?","Most, hogy van egy lángszóród, van bármi más, amivel szolgáhatok?","Ora che hai il lanciafiamme, c'è qualcos'altro che ti posso dare?","火炎放射器を手に入れたが、 -他に必要な物はあるか?","이제 화염방사기를 얻었으니, 더 원하는 물품이 있나?","Nu je de vlammenwerper hebt, is er nog iets anders dat ik je kan bezorgen?","Nå som du har flammekasteren, er det noe annet jeg kan gi deg?","Jak już masz miotacz ognia, mogę coś jeszcze dla ciebie zrobić?",Agora que você tem o lança-chamas. Deseja mais alguma coisa?,,"Acum că ai aruncătorul de flăcări, mai pot să-ți aduc ceva?","Ну, огнемёт у тебя теперь есть. Могу я ещё чем-нибудь помочь?",,"Artık alev silahın olduğuna göre, sana verebileceğim başka bir şey var mı?" -Clip of bullets,TXT_RPLY0_SCRIPT02_D12128_CLIPO,〃 (〃),,,Zásobník nábojů,Et patron-klip,Gewehrmunition.,,Magazenon,Un cargador,,Luotilipas,Chargeur de balles,Egy tárnyi töltény,Un caricatore di proiettili,銃弾倉,돌격소총 탄창,Klem van kogels,Et magasin med kuler.,Magazynek,Carregador de balas,,Cartuș de gloanțe,Обойму патронов,,Bir şarjör mermi -Thanks.,TXT_RYES0_SCRIPT02_D12128_THANK,〃 (〃),,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszönöm,Grazie.,どうも。,고맙네.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Благодарю.,,Teşekkürler. -"Come on, 10 gold.",TXT_RNO0_SCRIPT02_D12128_COMEO,〃 (〃),,,"No tak, jen deset zlatých.","Kom nu, 10 guld.","Na komm, 10 Gold.",,"Nu, ĝi kostas 10 da oro.","Vamos, que son 10 de oro.",,"Antaa tulla, 10 kolikkoa.","Allez, 10 pièces.","Gyerünk már, 10 aranyat.","Avanti, 10 pezzi d'oro.",頼むぜ、10ゴールドだぞ。,"이봐, 그건 10 골드라고.","Kom op, 10 goud.","Kom igjen, 10 gull.","No weź, 10 monet.","Vamos lá, 10 de ouro.",,"Haide, 10 monezi de aur.","Ну же, 10 золотых.",,"Hadi, 10 altın." -Ammo box,TXT_RPLY1_SCRIPT02_D12128_AMMOB,〃 (〃),,,Krabici nábojů,Ammo box,Munitionsschachtel,,Municikeston,Caja de municiones,,Ammuslaatikko,Bôite de balles,Lőszeres doboz.,Scatola di munizioni,銃弾倉箱,돌격소총 탄약 박스,Munitie doos,Ammunisjonsboks,Pudło z amunicją,Caixa de balas,,Cutie cu muniție,Коробку патронов,,Cephane kutusu -Here's your ammo.,TXT_RYES1_SCRIPT02_D12128_HERES,〃 (〃),,,Tady je tvá munice.,Her er din ammunition.,Hier ist deine Munition.,,Jen via municio.,Aquí está tu munición.,,Tässä ammuksesi.,Voilà vos munitions.,Itt a lőszered.,Ecco le tue munizioni.,これでアンタのブツだ。,여기 탄약이야.,Hier is je munitie.,Her er ammunisjonen din.,Oto twoja amunicja.,Aqui está a sua munição.,,Poftiți muniția.,Вот твои патроны.,,İşte cephanen. +他に必要な物はあるか?","이제 화염방사기를 얻었으니, 더 원하는 물품이 있나?","Nu je de vlammenwerper hebt, is er nog iets anders dat ik je kan bezorgen?","Nå som du har flammekasteren, er det noe annet jeg kan gi deg?","Jak już masz miotacz ognia, mogę coś jeszcze dla ciebie zrobić?",Agora que você tem o lança-chamas. Deseja mais alguma coisa?,,"Acum că ai aruncătorul de flăcări, mai pot să-ți aduc ceva?","Ну, огнемёт у тебя теперь есть. Могу я ещё чем-нибудь помочь?",,"Nu när du har flamkastaren, finns det något annat jag kan ge dig?","Artık alev silahın olduğuna göre, sana verebileceğim başka bir şey var mı?" +Clip of bullets,TXT_RPLY0_SCRIPT02_D12128_CLIPO,〃 (〃),,,Zásobník nábojů,Et patron-klip,Gewehrmunition.,,Magazenon,Un cargador,,Luotilipas,Chargeur de balles,Egy tárnyi töltény,Un caricatore di proiettili,銃弾倉,돌격소총 탄창,Klem van kogels,Et magasin med kuler.,Magazynek,Carregador de balas,,Cartuș de gloanțe,Обойму патронов,,Magasin med kulor,Bir şarjör mermi +Thanks.,TXT_RYES0_SCRIPT02_D12128_THANK,〃 (〃),,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszönöm,Grazie.,どうも。,고맙네.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Благодарю.,,Tack.,Teşekkürler. +"Come on, 10 gold.",TXT_RNO0_SCRIPT02_D12128_COMEO,〃 (〃),,,"No tak, jen deset zlatých.","Kom nu, 10 guld.","Na komm, 10 Gold.",,"Nu, ĝi kostas 10 da oro.","Vamos, que son 10 de oro.",,"Antaa tulla, 10 kolikkoa.","Allez, 10 pièces.","Gyerünk már, 10 aranyat.","Avanti, 10 pezzi d'oro.",頼むぜ、10ゴールドだぞ。,"이봐, 그건 10 골드라고.","Kom op, 10 goud.","Kom igjen, 10 gull.","No weź, 10 monet.","Vamos lá, 10 de ouro.",,"Haide, 10 monezi de aur.","Ну же, 10 золотых.",,"Kom igen, 10 guld.","Hadi, 10 altın." +Ammo box,TXT_RPLY1_SCRIPT02_D12128_AMMOB,〃 (〃),,,Krabici nábojů,Ammo kasse,Munitionsschachtel,,Municikeston,Caja de municiones,,Ammuslaatikko,Bôite de balles,Lőszeres doboz.,Scatola di munizioni,銃弾倉箱,돌격소총 탄약 박스,Munitie doos,Ammunisjonsboks,Pudło z amunicją,Caixa de balas,,Cutie cu muniție,Коробку патронов,,Ammunitionslåda,Cephane kutusu +Here's your ammo.,TXT_RYES1_SCRIPT02_D12128_HERES,〃 (〃),,,Tady je tvá munice.,Her er din ammunition.,Hier ist deine Munition.,,Jen via municio.,Aquí está tu munición.,,Tässä ammuksesi.,Voilà vos munitions.,Itt a lőszered.,Ecco le tue munizioni.,これでアンタのブツだ。,여기 탄약이야.,Hier is je munitie.,Her er ammunisjonen din.,Oto twoja amunicja.,Aqui está a sua munição.,,Poftiți muniția.,Вот твои патроны.,,Här är din ammunition.,İşte cephanen. Maybe some other time.,TXT_RNO1_SCRIPT02_D12128_MAYBE,〃 (〃),,,Možná někdy jindy.,Måske en anden gang.,Vielleicht ein anderes Mal.,,Eble alimomente.,"Puede que en -otro momento.",,Ehkä joku toinen kerta.,Peut être une autre fois.,Talán majd máskor.,Magari un'altra volta.,また後でな。,다음 번에 찾아와서 알려줘.,Misschien een andere keer.,Kanskje en annen gang.,Może innym razem.,Talvez outra hora.,,Poate altădată.,"Может, в другой раз.",,Belki başka bir zaman. -Phosphor grenades,TXT_RPLY2_SCRIPT02_D12128_PHOSP,,,,Fosforové granáty,Phosphor granater,Phosphorgranaten,,Fosforajn grenadojn,Granadas de fósforo,,Fosforikranaatteja,Grenades phosphoriques,Foszforgránátok,Granate al Fosforo.,白リングレネード弾,소이 유탄,Fosforgranaten,Fosforgranater,Fosforowe granaty,Granadas de fósforo,,Grenade cu fosfor,Фосфорные гранаты,,Fosfor bombaları -Thanks.,TXT_RYES2_SCRIPT02_D12128_THANK,,,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Kösz.,Grazie.,どうも。,고마워.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Благодарю.,,Teşekkürler. -You don't have enough,TXT_RNO2_SCRIPT02_D12128_YOUDO,,,,Nemáš u sebe dost.,Du har ikke nok,Du hast nicht genug,,Vi ne havas sufiĉe da mono.,No te alcanza.,,Sinulla ei ole riittävästi,Vous n'avez pas assez d'argent.,Nincs elég pénzed,Non hai abbastanza soldi.,十分な額じゃない,충분치 않아.,Je hebt niet genoeg...,Du har ikke nok,Nie wystarczy ci.,Você não tem o suficiente.,,Nu ai suficiente,Тебе не хватает на них.,,Sende yeterince -Poison bolts,TXT_RPLY3_SCRIPT02_D12128_POISO,,,,Otrávené šípy,Giftbolte,Giftbolzen,,Venenajn sagojn,Flechas envenenadas,,Myrkkynuolia,Carreaux Empoisonnés,Mérgezett nyilak,Frecce avvelenate.,ポイズンボルト,맹독 볼트,Giftige bouten,Giftbolter,Zatrute bełty,Setas venenosas,,Bolțuri cu otravă,Отравленные болты,,Zehirli cıvatalar -Worth every gold!,TXT_RYES3_SCRIPT02_D12128_WORTH,,,,Ty se vyplatí!,Hvert et guld værd!,Jedes Goldstück wert!,,Ili valoras ĉiu monero!,¡Valen cada moneda de oro!,,Joka kolikon väärti!,Ca vaut son prix!,Minden aranyat megér,Ne vale la pena!,値段に合う価値だぜ!,아주 가치가 있는 것이지!,Elk goud waard!,Verdt hvert gull!,Warte każdych pieniędzy!,Vale cada moeda de ouro!,,Merită fiecare bănuț!,Они того стоят!,,Her altına değer! -"Come on, 200 gold!",TXT_RNO3_SCRIPT02_D12128_COMEO,,,,"No tak, 200 zlatých!","Kom nu, 200 guld!","Na komm, 200 Gold!",,"Nu, ili kostas 200 da oro.","Vamos, que son 200 de oro.",,"Antaa tulla, 200 kolikkoa!","Allez, 200 pièces!","Rajta, 200 arany!","Avanti, 200 pezzi d'oro!",頼むぜ、200ゴールドだぞ!,"이봐, 이건 200 골드라고!","Kom op, 200 goud!","Kom igjen, 200 gull!","No weź, 200 monet!","Vamos lá, 200 de ouro!",,"Haide, 200 monezi de aur!","Ну же, 200 золотых!",,"Hadi, 200 altın!" +otro momento.",,Ehkä joku toinen kerta.,Peut être une autre fois.,Talán majd máskor.,Magari un'altra volta.,また後でな。,다음 번에 찾아와서 알려줘.,Misschien een andere keer.,Kanskje en annen gang.,Może innym razem.,Talvez outra hora.,,Poate altădată.,"Может, в другой раз.",,Kanske en annan gång.,Belki başka bir zaman. +Phosphor grenades,TXT_RPLY2_SCRIPT02_D12128_PHOSP,,,,Fosforové granáty,Phosphor granater,Phosphorgranaten,,Fosforajn grenadojn,Granadas de fósforo,,Fosforikranaatteja,Grenades phosphoriques,Foszforgránátok,Granate al Fosforo.,白リングレネード弾,소이 유탄,Fosforgranaten,Fosforgranater,Fosforowe granaty,Granadas de fósforo,,Grenade cu fosfor,Фосфорные гранаты,,Fosforgranater,Fosfor bombaları +Thanks.,TXT_RYES2_SCRIPT02_D12128_THANK,,,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Kösz.,Grazie.,どうも。,고마워.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Благодарю.,,Tack.,Teşekkürler. +You don't have enough,TXT_RNO2_SCRIPT02_D12128_YOUDO,,,,Nemáš u sebe dost.,Du har ikke nok,Du hast nicht genug,,Vi ne havas sufiĉe da mono.,No te alcanza.,,Sinulla ei ole riittävästi,Vous n'avez pas assez d'argent.,Nincs elég pénzed,Non hai abbastanza soldi.,十分な額じゃない,충분치 않아.,Je hebt niet genoeg...,Du har ikke nok,Nie wystarczy ci.,Você não tem o suficiente.,,Nu ai suficiente,Тебе не хватает на них.,,Du har inte tillräckligt med,Sende yeterince +Poison bolts,TXT_RPLY3_SCRIPT02_D12128_POISO,,,,Otrávené šípy,Giftbolte,Giftbolzen,,Venenajn sagojn,Flechas envenenadas,,Myrkkynuolia,Carreaux Empoisonnés,Mérgezett nyilak,Frecce avvelenate.,ポイズンボルト,맹독 볼트,Giftige bouten,Giftbolter,Zatrute bełty,Setas venenosas,,Bolțuri cu otravă,Отравленные болты,,Giftbultar.,Zehirli cıvatalar +Worth every gold!,TXT_RYES3_SCRIPT02_D12128_WORTH,,,,Ty se vyplatí!,Hvert et guld værd!,Jedes Goldstück wert!,,Ili valoras ĉiu monero!,¡Valen cada moneda de oro!,,Joka kolikon väärti!,Ca vaut son prix!,Minden aranyat megér,Ne vale la pena!,値段に合う価値だぜ!,아주 가치가 있는 것이지!,Elk goud waard!,Verdt hvert gull!,Warte każdych pieniędzy!,Vale cada moeda de ouro!,,Merită fiecare bănuț!,Они того стоят!,,Värda varje guld!,Her altına değer! +"Come on, 200 gold!",TXT_RNO3_SCRIPT02_D12128_COMEO,,,,"No tak, 200 zlatých!","Kom nu, 200 guld!","Na komm, 200 Gold!",,"Nu, ili kostas 200 da oro.","Vamos, que son 200 de oro.",,"Antaa tulla, 200 kolikkoa!","Allez, 200 pièces!","Rajta, 200 arany!","Avanti, 200 pezzi d'oro!",頼むぜ、200ゴールドだぞ!,"이봐, 이건 200 골드라고!","Kom op, 200 goud!","Kom igjen, 200 gull!","No weź, 200 monet!","Vamos lá, 200 de ouro!",,"Haide, 200 monezi de aur!","Ну же, 200 золотых!",,"Kom igen, 200 guld!","Hadi, 200 altın!" I can't believe that I got stuck with this duty. They say that something evil came up out of this sewer gate... Now I get to stand here until it comes up again!,TXT_DLG_SCRIPT02_D13644_ICANT,MAP02: Between governor's mansion and town hall.,,,"Nemůžu uvěřit, že jsem zkysnul s touhle prací. Řekli mi, že z téhle brány vylezlo něco zlého... A teď tady mám stát, dokud to znovu nevyleze!","Jeg kan ikke tro, at jeg blev sat til at have denne opgave. De siger, at noget ondt kom op af denne kloakport... Nu skal jeg stå her, indtil det kommer op igen!","Ich kann's nicht glauben dass ich diesen Dienst hier machen muss. Sie haben gesagt, dass etwas Böses aus dem Kanalisationstor gekommen ist... Nun muss ich hier stehen, bis es wieder kommt!",,"Mi ne povas kredi, ke mi estas blokita kun ĉi tiu tasko: Oni diras, ke malbonaĵo aperis el ĉi tiu pordo... kaj mi nun devas resti ĉi tie ĝis ĝi reaperu!",No puedo creer que haya quedado esclavizado con esta tarea: Dicen que algo maligno salió de esta compuerta... ¡y ahora tengo que quedarme aquí hasta que salga de nuevo!,,"Uskomatonta, että minulle tungettiin tämä tehtävä. Sanovat, että jokin paha nousi ylös tästä viemäriluukusta... Ja minä saan seistä tässä, kunnes se nousee jälleen!",J'arrive pas à croire que je me retrouve coincé ici. On me raconte qu'une chose maléfique est sortie de cette barrière des égouts.. Maintenant je me retrouve planté ici jusqu'a ce qu'elle revienne!,"Nem hiszem el, hogy én kaptam ezt a melót. Úgy hírlik, hogy valami gonosz bukkant fel itt a csatorna kapuja felől... Most addig fogok itt állni, amíg újra fel nem bukkan.",Non posso credere di aver accettato questo lavoro. Dicono che qualcosa di malvagio sia sbucato dalla chiusa delle fogne... E io devo stare qui finché non ritorna! ,"私がこの勤務で足止めとは信じられん。 皆が下水ゲートから悪しきものが来たと言う。 -再びドアが開くまで、ここで立ち往生だ!",내가 이 임무에 얽매였다는 게 믿기지 않아요. 사람들이 하수도 입구에서 뭔가 나타났다고 하던데... 이제 그게 다시 올 때까지 여기에서 서 있어야 한다니!,Ik kan niet geloven dat ik met deze plicht vast kwam te zitten. Ze zeggen dat er iets kwaadaardigs uit deze rioolpoort is gekomen.... Nu mag ik hier blijven staan tot het weer opduikt!,Jeg kan ikke tro at jeg ble sittende fast med denne plikten. De sier at noe ondt kom opp av denne kloakkporten... Nå må jeg stå her til det kommer opp igjen!,"Nie mogę uwierzyć, że zostałem z tym obowiązkiem. Mówią, że coś złego wyszło z tej bramy do kanałów... Teraz muszę tu stać aż się znów pojawi.",Não acredito que fiquei com essa tarefa. Dizem que algo horrível saiu dessa comporta de esgoto... Agora tenho que ficar aqui até que saia de novo!,,Nu-mi vine să cred că am rămas blocat cu meseria asta. Se zvonește că ceva malefic a ieșit la suprafată prin poarta canalului... Acum am ocazia să stau aici până se întoarce!,"Не могу поверить, что застрял на дежурстве. Они говорят, что какая-то пакость поднялась из этого люка... и теперь я должен стоять тут и ждать, пока она не появится снова!",,Bu görevin bana kaldığına inanamıyorum. Bu kanalizasyon kapısından kötü bir şeyin çıktığını söylüyorlar. Şimdi o şey tekrar ortaya çıkana kadar burada duracağım! -What gate?,TXT_RPLY0_SCRIPT02_D13644_WHATG,〃,,,Jaké brány?,Hvilken port?,Welches Tor?,,Kio estas post la pordo?,¿De qué es la compuerta?,,Mikä luukku?,Quelle barrière?,Milyen Kapu?,Quale chiusa? ,何のゲートだ?,무슨 입구?,Welk hek?,Hvilken port?,Jakiej bramy?,Que comporta?,,Care poartă?,Какого люка?,,Ne kapısı? +再びドアが開くまで、ここで立ち往生だ!",내가 이 임무에 얽매였다는 게 믿기지 않아요. 사람들이 하수도 입구에서 뭔가 나타났다고 하던데... 이제 그게 다시 올 때까지 여기에서 서 있어야 한다니!,Ik kan niet geloven dat ik met deze plicht vast kwam te zitten. Ze zeggen dat er iets kwaadaardigs uit deze rioolpoort is gekomen.... Nu mag ik hier blijven staan tot het weer opduikt!,Jeg kan ikke tro at jeg ble sittende fast med denne plikten. De sier at noe ondt kom opp av denne kloakkporten... Nå må jeg stå her til det kommer opp igjen!,"Nie mogę uwierzyć, że zostałem z tym obowiązkiem. Mówią, że coś złego wyszło z tej bramy do kanałów... Teraz muszę tu stać aż się znów pojawi.",Não acredito que fiquei com essa tarefa. Dizem que algo horrível saiu dessa comporta de esgoto... Agora tenho que ficar aqui até que saia de novo!,,Nu-mi vine să cred că am rămas blocat cu meseria asta. Se zvonește că ceva malefic a ieșit la suprafată prin poarta canalului... Acum am ocazia să stau aici până se întoarce!,"Не могу поверить, что застрял на дежурстве. Они говорят, что какая-то пакость поднялась из этого люка... и теперь я должен стоять тут и ждать, пока она не появится снова!",,Jag kan inte fatta att jag fick den här uppgiften. Det sägs att något ondskefullt kom upp ur den här kloakporten... Nu får jag stå här tills det kommer upp igen!,Bu görevin bana kaldığına inanamıyorum. Bu kanalizasyon kapısından kötü bir şeyin çıktığını söylüyorlar. Şimdi o şey tekrar ortaya çıkana kadar burada duracağım! +What gate?,TXT_RPLY0_SCRIPT02_D13644_WHATG,〃,,,Jaké brány?,Hvilken port?,Welches Tor?,,Kio estas post la pordo?,¿De qué es la compuerta?,,Mikä luukku?,Quelle barrière?,Milyen Kapu?,Quale chiusa? ,何のゲートだ?,무슨 입구?,Welk hek?,Hvilken port?,Jakiej bramy?,Que comporta?,,Care poartă?,Какого люка?,,Vilken port?,Ne kapısı? The sewer overflow gate.,TXT_RYES0_SCRIPT02_D13644_THESE,〃,,,Odpadní přepadové brány.,Kloakoverløbsporten.,Das Überlauftor der Kanalisation.,,"La elflua truo de la kloakoj.","Del pozo de desagüe -del alcantarillado.",,Viemärin ylivuotoluukku.,La barrière de débordement des égouts.,A csatorna kiárasztó kapuja.,La chiusa di contenimento delle fogne. ,下水道の溢水ゲートだ。,하수도 입구 말이에요.,Het riooloverloophek.,Kloakkoverløpsporten.,Bramy do kanałów.,A comporta de transborda de esgoto.,,Poarta de revărsare.,Канализационного люка перелива.,,Kanalizasyon taşma kapısı. -Hello friend. What can I get for you?,TXT_DLG_SCRIPT02_D15160_HELLO,MAP02: Weapons.,,,"Zdravím, příteli. Co pro vás můžu udělat?","Hej, min ven. Hvad kan jeg hjælpe dig med?","Hallo, Freund. Was darf es sein?",,"Saluton, amiko. Kion mi donu al vi?","Saludos, amigo. ¿Qué puedo ofrecerte?",,"Tervehdys, ystävä. Mitä saisi olla?","Bonjour mon ami, que puis-je faire pour vous?","Szervusz barátom, mit tehetnék érted?",Ehilà amico. Che posso darti? ,どうも同士よ。何か必要か?,안녕하십니까. 뭘 드릴까요?,Hallo vriend. Wat kan ik voor je halen?,"Hallo, min venn. Hva vil du ha?",Witaj kolego. Co mogę dla ciebie zrobić?,"Olá, amigo. Como posso ajudá-lo?",,Salut prietene. Ce pot să-ți aduc?,Здравствуй. Что-нибудь интересует?,,Merhaba dostum. Senin için ne yapabilirim? -Electric bolts,TXT_RPLY0_SCRIPT02_D15160_ELECT,〃,,,Elektrické šípy,Elektriske bolte,Elektrische Bolzen,,Elektrajn sagojn,Flechas eléctricas,,Sähkönuolia,Carreaux électriques,Elektromos nyilak.,Dardi elettrificati ,エレクトリックボルト,전격 볼트,Elektrische bouten,Elektriske bolter.,Elektryczne bełty,Setas elétricas,,Bolțuri electrice,Электрические болты,,Elektrikli cıvata. -You got the electric bolts.,TXT_RYES0_SCRIPT02_D15160_YOUGO,〃,,,Tady je máte.,Du fik de elektriske bolte.,Du hast die elektrischen Bolzen erhalten.,,Jen la sagoj.,Aquí están las flechas.,,Sait sähkönuolet.,Vous recevez les carreaux électriques.,Megkaptad az elektromos nyilakat.,Hai preso dei dardi elettrificati ,エレクトリックボルト 入手。,전격 볼트를 받았습니다.,Je hebt de elektrische bouten.,Du har de elektriske boltene.,Masz elektryczne bełty.,Você pegou as setas elétricas,,Ai ridicat bolțurile electrice.,Вот твои электрические болты.,,Elektrikli cıvatalar sende. -Ammo satchel,TXT_RPLY1_SCRIPT02_D15160_AMMOS,〃,,,Brašnu na munici,Ammotaske,Munitionstasche,,Sako da municioj,Bolso de municiones,,Ammusreppu,Sacoche de Munitions,Lőszeres táska.,Sacca di munizioni ,弾薬鞄,탄약 배낭,Munitie tasje,Ammunisjonsveske,Torba z amunicją,Mochila de munição,,Sacoșă cu muniție,Ранец для боеприпасов,,Cephane çantası +del alcantarillado.",,Viemärin ylivuotoluukku.,La barrière de débordement des égouts.,A csatorna kiárasztó kapuja.,La chiusa di contenimento delle fogne. ,下水道の溢水ゲートだ。,하수도 입구 말이에요.,Het riooloverloophek.,Kloakkoverløpsporten.,Bramy do kanałów.,A comporta de transborda de esgoto.,,Poarta de revărsare.,Канализационного люка перелива.,,Kloakens överflödsgrind.,Kanalizasyon taşma kapısı. +Hello friend. What can I get for you?,TXT_DLG_SCRIPT02_D15160_HELLO,MAP02: Weapons.,,,"Zdravím, příteli. Co pro vás můžu udělat?","Hej, min ven. Hvad kan jeg hjælpe dig med?","Hallo, Freund. Was darf es sein?",,"Saluton, amiko. Kion mi donu al vi?","Saludos, amigo. ¿Qué puedo ofrecerte?",,"Tervehdys, ystävä. Mitä saisi olla?","Bonjour mon ami, que puis-je faire pour vous?","Szervusz barátom, mit tehetnék érted?",Ehilà amico. Che posso darti? ,どうも同士よ。何か必要か?,안녕하십니까. 뭘 드릴까요?,Hallo vriend. Wat kan ik voor je halen?,"Hallo, min venn. Hva vil du ha?",Witaj kolego. Co mogę dla ciebie zrobić?,"Olá, amigo. Como posso ajudá-lo?",,Salut prietene. Ce pot să-ți aduc?,Здравствуй. Что-нибудь интересует?,,"Hej, min vän. Vad kan jag ge dig?",Merhaba dostum. Senin için ne yapabilirim? +Electric bolts,TXT_RPLY0_SCRIPT02_D15160_ELECT,〃,,,Elektrické šípy,Elektriske bolte,Elektrische Bolzen,,Elektrajn sagojn,Flechas eléctricas,,Sähkönuolia,Carreaux électriques,Elektromos nyilak.,Dardi elettrificati ,エレクトリックボルト,전격 볼트,Elektrische bouten,Elektriske bolter.,Elektryczne bełty,Setas elétricas,,Bolțuri electrice,Электрические болты,,Elektriska bultar,Elektrikli cıvata. +You got the electric bolts.,TXT_RYES0_SCRIPT02_D15160_YOUGO,〃,,,Tady je máte.,Du fik de elektriske bolte.,Du hast die elektrischen Bolzen erhalten.,,Jen la sagoj.,Aquí están las flechas.,,Sait sähkönuolet.,Vous recevez les carreaux électriques.,Megkaptad az elektromos nyilakat.,Hai preso dei dardi elettrificati ,エレクトリックボルト 入手。,전격 볼트를 받았습니다.,Je hebt de elektrische bouten.,Du har de elektriske boltene.,Masz elektryczne bełty.,Você pegou as setas elétricas,,Ai ridicat bolțurile electrice.,Вот твои электрические болты.,,Du fick elektriska bultar.,Elektrikli cıvatalar sende. +Ammo satchel,TXT_RPLY1_SCRIPT02_D15160_AMMOS,〃,,,Brašnu na munici,Ammotaske,Munitionstasche,,Sako da municioj,Bolso de municiones,,Ammusreppu,Sacoche de Munitions,Lőszeres táska.,Sacca di munizioni ,弾薬鞄,탄약 배낭,Munitie tasje,Ammunisjonsveske,Torba z amunicją,Mochila de munição,,Sacoșă cu muniție,Ранец боеприпасов,,Ammunitionsväska,Cephane çantası No. You don't have what I want for the electric bolts!,TXT_RNO0_SCRIPT02_D15160_NOYOU,〃,,,"Ne. Nemáte, co za ně chci!","Nej. Du har ikke det, jeg vil have for de elektriske bolte!","Nein. Du hast nicht das, was ich für die elektrischen Pfeile haben möchte!",,"Ne, vi ne havas tiom, -kiom mi petas.","No, no tienes lo que pido.",,"Ei. Sinulla ei ole, mitä haluan sähkönuolista!","Non, vous n'avez pas ce qu'il me faut pour les carreaux électriques!","Nem. Neked nincs olyanod, ami nekem kéne az elektromos nyilakért.",No. Non hai quello che mi serve per i dardi elettrificati! ,いや。エレクトリックボルトに必要な物が足りない!,전격 볼트의 가격에 해당하는 게 전혀 없구먼!,Nee. Je hebt niet wat ik wil voor de elektrische bouten!,Nei. Du har ikke det jeg vil ha for de elektriske boltene!,"Nie. Nie masz tego co ja chcę, by dać ci elektryczne bełty.",Não. Você não tem o que eu quero pelas setas elétricas!,,Nu. Nu ai ceea ce doresc pentru bolțurile electrice!,Нет. У тебя нет денег на электрические болты!,,Hayır. Elektrikli cıvatalar için istediğim şey sizde yok! +kiom mi petas.","No, no tienes lo que pido.",,"Ei. Sinulla ei ole, mitä haluan sähkönuolista!","Non, vous n'avez pas ce qu'il me faut pour les carreaux électriques!","Nem. Neked nincs olyanod, ami nekem kéne az elektromos nyilakért.",No. Non hai quello che mi serve per i dardi elettrificati! ,いや。エレクトリックボルトに必要な物が足りない!,전격 볼트의 가격에 해당하는 게 전혀 없구먼!,Nee. Je hebt niet wat ik wil voor de elektrische bouten!,Nei. Du har ikke det jeg vil ha for de elektriske boltene!,"Nie. Nie masz tego co ja chcę, by dać ci elektryczne bełty.",Não. Você não tem o que eu quero pelas setas elétricas!,,Nu. Nu ai ceea ce doresc pentru bolțurile electrice!,Нет. У тебя нет денег на электрические болты!,,"Nej, du har inte det jag vill ha för elbultarna!",Hayır. Elektrikli cıvatalar için istediğim şey sizde yok! No. You don't have what I want for the electric bolts!,TXT_RNO0_SCRIPT02_D16676_NOYOU,〃,,,"Ne. Nemáte, co za ně chci!","Nej. Du har ikke det, jeg vil have til de elektriske bolte!","Nein. Du hast nicht das, was ich für die elektrischen Pfeile haben möchte!",,"Ne, vi ne havas tiom, -kiom mi petas.","No, no tienes lo que pido.",,"Ei. Sinulla ei ole, mitä haluan sähkönuolista!","Non, vous n'avez pas ce qu'il me faut pour les carreaux électriques!","Nem. Neked nincs olyanod, ami nekem kéne az elektromos nyilakért.",No. Non hai quello che mi serve per i dardi elettrificati! ,いや。エレクトリックボルトに必要な物が足りない!,전격 볼트의 가격에 맞춰서 흥정하시길.,Nee. Je hebt niet wat ik wil voor de elektrische bouten!,Nei. Du har ikke det jeg vil ha for de elektriske boltene!,"Nie. Nie masz tego co ja chcę, by dać ci elektryczne bełty.",Não. Você não tem o que eu quero pelas setas elétricas!,,Nu. Nu ai ceea ce doresc pentru bolțurile electrice!,Нет. У тебя нет денег на электрические болты!,,Hayır. Elektrikli cıvatalar için istediğim şey sizde yok! -Thank you. Anything else?,TXT_RYES1_SCRIPT02_D15160_THANK,〃,,,Děkuji. Něco dalšího?,Tak. Er der andet?,Danke. Sonst noch etwas?,,Dankon. Ĉu ion alian?,Gracias. ¿Algo más?,,Kiitos. Jotain muuta?,"Merci, Autre chose?",Köszönöm. Még valamit?,Grazie. Qualcos'altro? ,ありがとう。 他に何か?,감사합니다. 다른 건 없나요?,"Bedankt, nog iets anders?",Takk skal du ha. Var det noe mer?,Dziękuję. Coś jeszcze?,Agradeço. Mais alguma coisa?,,Mulțumesc. Mai dorești ceva?,Благодарю. Что-нибудь ещё?,,Teşekkür ederim. Başka bir şey var mı? +kiom mi petas.","No, no tienes lo que pido.",,"Ei. Sinulla ei ole, mitä haluan sähkönuolista!","Non, vous n'avez pas ce qu'il me faut pour les carreaux électriques!","Nem. Neked nincs olyanod, ami nekem kéne az elektromos nyilakért.",No. Non hai quello che mi serve per i dardi elettrificati! ,いや。エレクトリックボルトに必要な物が足りない!,전격 볼트의 가격에 맞춰서 흥정하시길.,Nee. Je hebt niet wat ik wil voor de elektrische bouten!,Nei. Du har ikke det jeg vil ha for de elektriske boltene!,"Nie. Nie masz tego co ja chcę, by dać ci elektryczne bełty.",Não. Você não tem o que eu quero pelas setas elétricas!,,Nu. Nu ai ceea ce doresc pentru bolțurile electrice!,Нет. У тебя нет денег на электрические болты!,,"Nej, du har inte det jag vill ha för elbultarna!",Hayır. Elektrikli cıvatalar için istediğim şey sizde yok! +Thank you. Anything else?,TXT_RYES1_SCRIPT02_D15160_THANK,〃,,,Děkuji. Něco dalšího?,Tak. Er der andet?,Danke. Sonst noch etwas?,,Dankon. Ĉu ion alian?,Gracias. ¿Algo más?,,Kiitos. Jotain muuta?,"Merci, Autre chose?",Köszönöm. Még valamit?,Grazie. Qualcos'altro? ,ありがとう。 他に何か?,감사합니다. 다른 건 없나요?,"Bedankt, nog iets anders?",Takk skal du ha. Var det noe mer?,Dziękuję. Coś jeszcze?,Agradeço. Mais alguma coisa?,,Mulțumesc. Mai dorești ceva?,Благодарю. Что-нибудь ещё?,,Tack. Något annat?,Teşekkür ederim. Başka bir şey var mı? "You can't afford that, good day.",TXT_RNO1_SCRIPT02_D15160_YOUCA,〃,,,"To si nemůžete dovolit, přeji hezký den.","Det har du ikke råd til, god dag.",Das kannst du dir nicht leisten. Guten Tag.,,"Vi ne povas sen mono. Havu bonan tagon!","No te alcanza. -¡Ten un buen día!",,"Sinulla ei ole siihen varaa, hyvää päivänjatkoa.",Vous n'avez pas assez d'argent. Bonne journée.,Ezt most nem tudod kifizetni. Szép napot!,Non puoi permettertelo. Buona giornata. ,それを買える余裕は無い、また今度。,가질 수가 없는 것 같으니... 그럼 이만!,"Dat kun je je je niet veroorloven, goede dag.","Det har du ikke råd til, adjø.","Nie możesz tego kupić, miłego dnia.",Você não pode comprar isso. Tenha um bom dia.,,Nu îți permiți asta. O zi bună.,У тебя не хватает денег. Всего доброго.,,"Bunu karşılayamazsınız, iyi günler." -What can I get for you?,TXT_DLG_SCRIPT02_D16676_WHATC,〃,,,Co vám mohu nabídnout?,Hvad kan jeg skaffe til dig?,Was darf es sein?,,Kion mi donu al vi?,¿Qué puedo ofrecerte?,,Mitä saisi olla?,Que puis-je faire pour vous?,Mivel szolgáhatok?,Che cosa posso darti? ,何か必要か?,"무엇을 구매하고 싶으신가요, 좋은 친구여?",Wat kan ik voor je halen?,Hva vil du ha?,Co mogę dla ciebie zrobić?,Como posso te ajudar?,,Ce pot să-ți aduc?,Чем могу быть полезен?,,Sizin için ne alabilirim? -Electric bolts,TXT_RPLY0_SCRIPT02_D16676_ELECT,〃,,,Elektrické šípy,Elektriske bolte,Elektrische Bolzen,,Elektrajn sagojn,Flechas eléctricas,,Sähkönuolia,Carreaux électriques,Elektromos nyilak.,Dardi elettrificati ,エレクトリックボルト,전격 볼트,Elektrische bouten,Elektriske bolter.,Elektryczne bełty,Setas elétricas,,Bolțuri electrice,Электрические болты,,Elektrikli cıvatalar. -You got the electric bolts.,TXT_RYES0_SCRIPT02_D16676_YOUGO,〃,,,Tady je máte.,Du fik de elektriske bolte.,Du hast die elektrischen Bolzen erhalten.,,Jen la sagoj.,Aquí están las flechas.,,Sait sähkönuolet.,Vous recevez les carreaux électriques.,Elektromos nyilakra tettél szert.,Hai preso dei dardi elettrificati ,エレクトリックボルト 入手。,전격 볼트를 구매했습니다.,Je hebt de elektrische bouten.,Du har elektriske bolter.,Masz elektryczne bełty.,Você pegou as setas elétricas,,Ai ridicat bolțurile electrice.,Вот твои электрические болты.,,Elektrikli cıvatalar sende. -Ammo satchel,TXT_RPLY1_SCRIPT02_D16676_AMMOS,〃,,,Brašnu na munici,Ammotaske.,Munitionstasche,,Sako da municioj,Bolso de municiones,,Ammusreppu,Sacoche de Munitions,Lőszeres hátizsák,Sacca di munizioni ,弾薬鞄,탄약 배낭,Munitie tasje,Ammunisjonsveske.,Torba z amunicją,Mochila de munição,,Sacoșă cu muniție,Ранец для боеприпасов,,Cephane çantası -"Thank you, anything else?",TXT_RYES1_SCRIPT02_D16676_THANK,〃,,,Děkuji. Něco dalšího?,"Tak, andet?",Danke. Sonst noch etwas?,,Dankon. Ĉu ion alian?,Gracias. ¿Algo más?,,Kiitos. Jotain muuta?,"Merci, Autre chose?","Köszönöm, bármi mást?","Grazie, ti serve qualcos'altro?",ありがとう。 他に何か?,감사합니다. 다른 건 더 없나요?,"Bedankt, nog iets anders?","Takk, noe mer?","Dziękuję, coś jeszcze?",Agradeço. Mais alguma coisa?,,"Mulțumesc, mai dorești ceva?",Благодарю. Что-нибудь ещё?,,"Teşekkürler, başka bir şey var mı?" +¡Ten un buen día!",,"Sinulla ei ole siihen varaa, hyvää päivänjatkoa.",Vous n'avez pas assez d'argent. Bonne journée.,Ezt most nem tudod kifizetni. Szép napot!,Non puoi permettertelo. Buona giornata. ,それを買える余裕は無い、また今度。,가질 수가 없는 것 같으니... 그럼 이만!,"Dat kun je je je niet veroorloven, goede dag.","Det har du ikke råd til, adjø.","Nie możesz tego kupić, miłego dnia.",Você não pode comprar isso. Tenha um bom dia.,,Nu îți permiți asta. O zi bună.,У тебя не хватает денег. Всего доброго.,,"Du har inte råd med det, god dag.","Bunu karşılayamazsınız, iyi günler." +What can I get for you?,TXT_DLG_SCRIPT02_D16676_WHATC,〃,,,Co vám mohu nabídnout?,Hvad kan jeg skaffe til dig?,Was darf es sein?,,Kion mi donu al vi?,¿Qué puedo ofrecerte?,,Mitä saisi olla?,Que puis-je faire pour vous?,Mivel szolgáhatok?,Che cosa posso darti? ,何か必要か?,"무엇을 구매하고 싶으신가요, 좋은 친구여?",Wat kan ik voor je halen?,Hva vil du ha?,Co mogę dla ciebie zrobić?,Como posso te ajudar?,,Ce pot să-ți aduc?,Чем могу быть полезен?,,Vad kan jag ge dig?,Sizin için ne alabilirim? +Electric bolts,TXT_RPLY0_SCRIPT02_D16676_ELECT,〃,,,Elektrické šípy,Elektriske bolte,Elektrische Bolzen,,Elektrajn sagojn,Flechas eléctricas,,Sähkönuolia,Carreaux électriques,Elektromos nyilak.,Dardi elettrificati ,エレクトリックボルト,전격 볼트,Elektrische bouten,Elektriske bolter.,Elektryczne bełty,Setas elétricas,,Bolțuri electrice,Электрические болты,,Elektriska bultar,Elektrikli cıvatalar. +You got the electric bolts.,TXT_RYES0_SCRIPT02_D16676_YOUGO,〃,,,Tady je máte.,Du fik de elektriske bolte.,Du hast die elektrischen Bolzen erhalten.,,Jen la sagoj.,Aquí están las flechas.,,Sait sähkönuolet.,Vous recevez les carreaux électriques.,Elektromos nyilakra tettél szert.,Hai preso dei dardi elettrificati ,エレクトリックボルト 入手。,전격 볼트를 구매했습니다.,Je hebt de elektrische bouten.,Du har elektriske bolter.,Masz elektryczne bełty.,Você pegou as setas elétricas,,Ai ridicat bolțurile electrice.,Вот твои электрические болты.,,Du har elektriska bultar.,Elektrikli cıvatalar sende. +Ammo satchel,TXT_RPLY1_SCRIPT02_D16676_AMMOS,〃,,,Brašnu na munici,Ammotaske.,Munitionstasche,,Sako da municioj,Bolso de municiones,,Ammusreppu,Sacoche de Munitions,Lőszeres hátizsák,Sacca di munizioni ,弾薬鞄,탄약 배낭,Munitie tasje,Ammunisjonsveske.,Torba z amunicją,Mochila de munição,,Sacoșă cu muniție,Ранец боеприпасов,,Ammunitionsväska,Cephane çantası +"Thank you, anything else?",TXT_RYES1_SCRIPT02_D16676_THANK,〃,,,Děkuji. Něco dalšího?,"Tak, andet?",Danke. Sonst noch etwas?,,Dankon. Ĉu ion alian?,Gracias. ¿Algo más?,,Kiitos. Jotain muuta?,"Merci, Autre chose?","Köszönöm, bármi mást?","Grazie, ti serve qualcos'altro?",ありがとう。 他に何か?,감사합니다. 다른 건 더 없나요?,"Bedankt, nog iets anders?","Takk, noe mer?","Dziękuję, coś jeszcze?",Agradeço. Mais alguma coisa?,,"Mulțumesc, mai dorești ceva?",Благодарю. Что-нибудь ещё?,,"Tack, något annat?","Teşekkürler, başka bir şey var mı?" "You can't afford that, good day to you!",TXT_RNO1_SCRIPT02_D16676_YOUCA,〃,,,"To si nemůžete dovolit, přeji hezký den.","Det har du ikke råd til, god dag til dig!",Das kannst du dir nicht leisten. Guten Tag!,,"Vi ne povas sen mono. Havu bonan tagon!","No te alcanza. -¡Ten un buen día!",,"Sinulla ei ole siihen varaa, hyvää päivänjatkoa.",Vous n'avez pas assez d'argent. Bonne journée.,"Nincs elég pénzed arra, további jó napot neked!",Non puoi permettertelo. Buona giornata a te!,それを買える余裕は無い、また今度。,살 돈이 부족하신가요? 그럼 갈 길 가시길!,"Dat kunt u zich niet veroorloven, een goede dag voor je!","Det har du ikke råd til, ha en god dag!","Nie możesz tego kupić, życzę miłego dnia!",Você não pode comprar isso. Um bom dia pra você!,,Nu-ți poți permite asta. O zi bună îți doresc!,У тебя не хватает денег. Всего доброго!,,"Bunu karşılayamazsınız, size iyi günler!" +¡Ten un buen día!",,"Sinulla ei ole siihen varaa, hyvää päivänjatkoa.",Vous n'avez pas assez d'argent. Bonne journée.,"Nincs elég pénzed arra, további jó napot neked!",Non puoi permettertelo. Buona giornata a te!,それを買える余裕は無い、また今度。,살 돈이 부족하신가요? 그럼 갈 길 가시길!,"Dat kunt u zich niet veroorloven, een goede dag voor je!","Det har du ikke råd til, ha en god dag!","Nie możesz tego kupić, życzę miłego dnia!",Você não pode comprar isso. Um bom dia pra você!,,Nu-ți poți permite asta. O zi bună îți doresc!,У тебя не хватает денег. Всего доброго!,,"Du har inte råd med det, god dag till dig!","Bunu karşılayamazsınız, size iyi günler!" Welcome. What may I show you?,TXT_DLG_SCRIPT02_D18192_WELCO,MAP02: Armory.,,,Vítejte. Co vám mohu nabídnout?,Velkommen. Hvad må jeg vise dig?,Willkommen. Was kann ich dirZeigen.,,Bonvenon. Kion mi montru al vi?,Bienvenido. ¿Qué te muestro?,,Tervetuloa. Mitä haluaisitte vilkaista?,"Bienvenue, que souhaitez vous?",Üdvözletem! Miben segíthetek?,Benvenuto. Cosa posso mostrarti?,ようこそ、何を見ていきますか?,환영합니다! 보여드릴 게 아주 많아요.,Welkom. Wat kan ik je laten zien?,Velkommen. Hva kan jeg vise deg?,"Witaj. Co mogę ci pokazać? -",Saudações. O que posso te mostrar?,,Bun venit. Ce aș putea să-ți arăt?,Здравствуй. Что-нибудь интересует?,,Hoş geldiniz. Size ne gösterebilirim? -Environmental suit,TXT_RPLY0_SCRIPT02_D18192_ENVIR,〃,,,Ochranný oblek,Miljødragt,Schutzanzug.,,Medi-ŝirman veston,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison hazmat,Természetálló öltözet,Tuta ambientale,耐環境スーツ,환경 방호복,Milieupak,Miljødrakt,Skafander Ochronny,Traje de proteção,,Costum de protecție,Защитный костюм,,Çevre kıyafeti. -"Well, here you are.",TXT_RYES0_SCRIPT02_D18192_WELLH,〃,,,"Tak, tady to je.","Nå, værsgo.",Bitte sehr.,,"Nu, jen.","Bueno, aquí tienes.",,"Kas tässä, olkaa hyvä.",Voilà pour vous.,"Nos, tessék.","Bene, ecco a te.",はい、これをどうぞ。,"자, 여기있습니다.","Nou, hier ben je dan.",Vær så god.,"Proszę, masz.","Muito bem, aqui está.",,Poftiți.,"Хорошо, бери.",,İşte buradasın. +",Saudações. O que posso te mostrar?,,Bun venit. Ce aș putea să-ți arăt?,Здравствуй. Что-нибудь интересует?,,Välkommen. Vad får jag visa dig?,Hoş geldiniz. Size ne gösterebilirim? +Environmental suit,TXT_RPLY0_SCRIPT02_D18192_ENVIR,〃,,,Ochranný oblek,Miljødragt,Schutzanzug.,,Medi-ŝirman veston,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison hazmat,Természetálló öltözet,Tuta ambientale,耐環境スーツ,환경 방호복,Milieupak,Miljødrakt,Skafander Ochronny,Traje de proteção,,Costum de protecție,Защитный костюм,,Miljödräkt,Çevre kıyafeti. +"Well, here you are.",TXT_RYES0_SCRIPT02_D18192_WELLH,〃,,,"Tak, tady to je.","Nå, værsgo.",Bitte sehr.,,"Nu, jen.","Bueno, aquí tienes.",,"Kas tässä, olkaa hyvä.",Voilà pour vous.,"Nos, tessék.","Bene, ecco a te.",はい、これをどうぞ。,"자, 여기있습니다.","Nou, hier ben je dan.",Vær så god.,"Proszę, masz.","Muito bem, aqui está.",,Poftiți.,"Хорошо, бери.",,"Ja, här är du.",İşte buradasın. I'm sorry but you don't have enough money for that.,TXT_RNO0_SCRIPT02_D18192_IMSOR,〃,,,"Promiňte, ale na ten nemáte dost peněz.","Jeg beklager, men du har ikke penge nok til det.","Es tut mir Leid, aber du hast nicht genug Geld dabei.",,"Pardonon, sed vi ne -havas sufiĉe da mono.","Lo siento, pero no te alcanza.",,Valitettavasti teillä ei ole siihen riittävästi rahaa.,Je suis désolé mais vous n'avez pas assez d'argent.,"Sajnálom, de nincs elég pénzed erre.","Mi spiace, ma non hai abbastanza soldi per questo.",すみませんが、貴方は十分なお金を持っていません。,"죄송합니다만, 그걸 사기엔 돈이 부족해 보입니다.","Het spijt me, maar daar heb je niet genoeg geld voor.","Beklager, men du har ikke nok penger til det.","Przepraszam, ale nie masz wystarczająco dużo monet, aby to kupić.","Sinto muito, mas você não tem dinheiro suficiente para isso.",,"Îmi pare rău, dar nu ai suficienți bani pentru asta.","Извини, но у тебя не хватает денег.",,Üzgünüm ama bunun için yeterli paranız yok. -Leather armor,TXT_RPLY1_SCRIPT02_D18192_LEATH,〃,,Leather armour,Kožené brnění,Læderrustning,Lederrüstung,,Ledan armaĵon,Armadura de cuero,,Nahkasuojus,Armure en cuir,Bőr páncél,Armatura di cuoio,レザーアーマー,가죽 갑옷,Leren pantser,Skinnpanser,Skórzany Pancerz,Armadura de couro,,Armură din piele,Кожаная броня,,Deri zırh -Here you are.,TXT_RYES1_SCRIPT02_D18192_HEREY,〃,,,Tady máte.,Værsgo.,Bitte sehr.,,Jen.,Aquí tienes.,,"Tässä, olkaa hyvä.",Voilà pour vous.,Tessék.,Ecco qua.,これをどうぞ。,여기 있습니다.,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Poftiți.,Держи.,,Buyurun. -Perhaps some other time?,TXT_RNO1_SCRIPT02_D18192_PERHA,〃,,,Možná někdy jindy?,Måske en anden gang?,Vielleicht ein anderes Mal?,,Ĉu eble alian fojon?,¿Quizás en otra ocasión?,¿Tal vez en otra ocasión?,Ehkä joskus toiste?,Peut être une autre fois?,Esetleg talán máskor?,"Magari un'altra volta, va bene?",また別の機会に?,아마 나중에 사야 할 것 같은데?,Misschien een andere keer?,Kanskje en annen gang?,Może innym razem?,Talvez uma outra hora?,,Poate altădată?,"Может, в следующий раз?",,Belki başka bir zaman? -Metal armor,TXT_RPLY2_SCRIPT02_D18192_METAL,〃,,Metal armour,Kovové brnění,Metal rustning,Metallrüstung,,Metalan armaĵon,Armadura de metal,,Metallihaarniska,Armure en Métal,Fémpáncél,Armatura di metallo,メタルアーマー,강철 갑옷,Metalen harnas,Metall rustning,Metalowy Pancerz,Armadura de metal,,Armură din metal,Металлическая броня,,Metal zırh +havas sufiĉe da mono.","Lo siento, pero no te alcanza.",,Valitettavasti teillä ei ole siihen riittävästi rahaa.,Je suis désolé mais vous n'avez pas assez d'argent.,"Sajnálom, de nincs elég pénzed erre.","Mi spiace, ma non hai abbastanza soldi per questo.",すみませんが、貴方は十分なお金を持っていません。,"죄송합니다만, 그걸 사기엔 돈이 부족해 보입니다.","Het spijt me, maar daar heb je niet genoeg geld voor.","Beklager, men du har ikke nok penger til det.","Przepraszam, ale nie masz wystarczająco dużo monet, aby to kupić.","Sinto muito, mas você não tem dinheiro suficiente para isso.",,"Îmi pare rău, dar nu ai suficienți bani pentru asta.","Извини, но у тебя не хватает денег.",,Jag är ledsen men du har inte tillräckligt med pengar för det.,Üzgünüm ama bunun için yeterli paranız yok. +Leather armor,TXT_RPLY1_SCRIPT02_D18192_LEATH,〃,,Leather armour,Kožené brnění,Læderrustning,Lederrüstung,,Ledan armaĵon,Armadura de cuero,,Nahkasuojus,Armure en cuir,Bőr páncél,Armatura di cuoio,レザーアーマー,가죽 갑옷,Leren pantser,Skinnpanser,Skórzany Pancerz,Armadura de couro,,Armură din piele,Кожаная броня,,Läderrustning,Deri zırh +Here you are.,TXT_RYES1_SCRIPT02_D18192_HEREY,〃,,,Tady máte.,Værsgo.,Bitte sehr.,,Jen.,Aquí tienes.,,"Tässä, olkaa hyvä.",Voilà pour vous.,Tessék.,Ecco qua.,これをどうぞ。,여기 있습니다.,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Poftiți.,Держи.,,Här har du.,Buyurun. +Perhaps some other time?,TXT_RNO1_SCRIPT02_D18192_PERHA,〃,,,Možná někdy jindy?,Måske en anden gang?,Vielleicht ein anderes Mal?,,Ĉu eble alian fojon?,¿Quizás en otra ocasión?,¿Tal vez en otra ocasión?,Ehkä joskus toiste?,Peut être une autre fois?,Esetleg talán máskor?,"Magari un'altra volta, va bene?",また別の機会に?,아마 나중에 사야 할 것 같은데?,Misschien een andere keer?,Kanskje en annen gang?,Może innym razem?,Talvez uma outra hora?,,Poate altădată?,"Может, в следующий раз?",,Kanske en annan gång?,Belki başka bir zaman? +Metal armor,TXT_RPLY2_SCRIPT02_D18192_METAL,〃,,Metal armour,Kovové brnění,Metal rustning,Metallrüstung,,Metalan armaĵon,Armadura de metal,,Metallihaarniska,Armure en Métal,Fémpáncél,Armatura di metallo,メタルアーマー,강철 갑옷,Metalen harnas,Metall rustning,Metalowy Pancerz,Armadura de metal,,Armură din metal,Металлическая броня,,Metallrustning,Metal zırh Wear it in good health.,TXT_RYES2_SCRIPT02_D18192_WEARI,"〃 -(in good health = enjoy)",,,Noste jej ve zdraví.,Bær den ved godt helbred.,Trage sie mit Stolz.,,Ĝuu ĝin.,Disfrútala.,,Kaikin voimin pukeutukaa.,Portez la en bonne santé.,Viseld jó egészséggel!,Che possa esserti utile!,着ると安心しますよ。,건강하게 입으세요.,Draag het in goede gezondheid.,Bruk den med god helse.,Bądź zdrów nosząc go.,Vista ela com orgulho.,,Să o porți sănătos.,Носи на здоровье.,,Sağlıkla giy. +(in good health = enjoy)",,,Noste jej ve zdraví.,Bær den ved godt helbred.,Trage sie mit Stolz.,,Ĝuu ĝin.,Disfrútala.,,Kaikin voimin pukeutukaa.,Portez la bien.,Viseld jó egészséggel!,Che possa esserti utile!,着ると安心しますよ。,건강하게 입으세요.,Draag het in goede gezondheid.,Bruk den med god helse.,Bądź zdrów nosząc go.,Vista ela com orgulho.,,Să o porți sănătos.,Носи на здоровье.,,Bär den vid god hälsa.,Sağlıkla giy. Come back when you can afford to buy something you lout!,TXT_RNO2_SCRIPT02_D18192_COMEB,〃,,,"Vrať se, až si budeš moct něco dovolit, troubo!","Kom tilbage, når du har råd til at købe noget, din slyngel!","Komm zurück wenn du dir etwas leisten kannst, du Rüpel!",,"Revenu kiam vi povos aĉeti ion, stultulo!","¡Vuelve cuando puedas -comprar algo, zopenco! ",,"Palataan asiaan, kun teidän on mahdollista ostaa jotain himoitsemaanne.","Revenez quand vous avez de l'argent, rustre!","Majd akkor gyere vissza, ha lesz pénzed megvenni bármit is, te fajankó!","Ritorna quando potrai permetterti di comprare le cose, cafone!",余裕がある時にまたどうぞ!,뭔가를 살 여유가 있을 때 오세요!,Kom terug wanneer je het je kunt veroorloven om iets te kopen wat je louteren kunt!,"Kom tilbake når du har råd til å kjøpe noe, din lømmel!",Wróć kiedy będziesz mógł coś kupić prostaku!,"Volte quando você puder comprar algo, seu caloteiro!",,"Revin-o când o să ai bani să poți cumpăra ceva, secătură!","Возвращайся, когда сможешь позволить себе купить что-нибудь, придурок!",,Bir şeyler almaya gücün yettiğinde geri gel! +comprar algo, zopenco! ",,"Palataan asiaan, kun teidän on mahdollista ostaa jotain himoitsemaanne.","Revenez quand vous avez de l'argent, rustre!","Majd akkor gyere vissza, ha lesz pénzed megvenni bármit is, te fajankó!","Ritorna quando potrai permetterti di comprare le cose, cafone!",余裕がある時にまたどうぞ!,뭔가를 살 여유가 있을 때 오세요!,Kom terug wanneer je het je kunt veroorloven om iets te kopen wat je louteren kunt!,"Kom tilbake når du har råd til å kjøpe noe, din lømmel!",Wróć kiedy będziesz mógł coś kupić prostaku!,"Volte quando você puder comprar algo, seu caloteiro!",,"Revin-o când o să ai bani să poți cumpăra ceva, secătură!","Возвращайся, когда сможешь позволить себе купить что-нибудь, придурок!",,"Kom tillbaka när du har råd att köpa något, din tölp!",Bir şeyler almaya gücün yettiğinde geri gel! Welcome. What may I show you?,TXT_DLG_SCRIPT02_D19708_WELCO,,,,Vítejte. Co vám mohu nabídnout?,Velkommen. Hvad må jeg vise dig?,Willkommen. Was kann ich dir zeigen.,,Bonvenon. Kion mi montru al vi?,Bienvenido. ¿Qué te muestro?,,Tervetuloa. Mitä haluaisitte vilkaista?,"Bienvenue, que souhaitez vous?","Üdvözlet, mire volnál kíváncsi?",Benvenuto. Cosa posso mostrarti?,ようこそ、何をお探しで?,어서 오십시오. 어떤 걸 보여드릴까요?,Welkom. Wat kan ik je laten zien?,Velkommen. Hva kan jeg vise deg?,"Witaj. Co mogę ci pokazać? -",Saudações. O que posso te mostrar?,,Bun venit. Ce aș putea să-ți arăt?,Здравствуй. Что-нибудь интересует?,,Hoş geldiniz. Size ne gösterebilirim? -Environmental suit,TXT_RPLY0_SCRIPT02_D19708_ENVIR,,,,Ochranný oblek,Miljødragt,Schutzanzug.,,Medi-ŝirman veston,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison hazmat,Természetálló öltözet,Tuta ambientale,耐環境スーツ,환경 방호복,Beschermend Pak,Miljødrakt,Skafander Ochronny,Traje de proteção,,Costum de protecție,Защитный костюм,,Çevre kıyafeti -"Well, here you are.",TXT_RYES0_SCRIPT02_D19708_WELLH,,,,"Tak, tady to je.","Nå, værsgo.",Bitte sehr.,,"Nu, jen.","Bueno, aquí tienes.",,"Kas tässä, olkaa hyvä.",Voilà pour vous.,"Nos, íme.","Bene, ecco a te.",では、これをどうぞ。,"자, 여기 있습니다.","Nou, hier ben je dan.",Vær så god.,"Proszę, masz.","Muito bem, aqui está.",,Poftiți.,"Хорошо, бери.",,İşte buradasın. +",Saudações. O que posso te mostrar?,,Bun venit. Ce aș putea să-ți arăt?,Здравствуй. Что-нибудь интересует?,,Välkommen. Vad får jag visa dig?,Hoş geldiniz. Size ne gösterebilirim? +Environmental suit,TXT_RPLY0_SCRIPT02_D19708_ENVIR,,,,Ochranný oblek,Miljødragt,Schutzanzug.,,Medi-ŝirman veston,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison hazmat,Természetálló öltözet,Tuta ambientale,耐環境スーツ,환경 방호복,Beschermend Pak,Miljødrakt,Skafander Ochronny,Traje de proteção,,Costum de protecție,Защитный костюм,,Miljödräkt,Çevre kıyafeti +"Well, here you are.",TXT_RYES0_SCRIPT02_D19708_WELLH,,,,"Tak, tady to je.","Nå, værsgo.",Bitte sehr.,,"Nu, jen.","Bueno, aquí tienes.",,"Kas tässä, olkaa hyvä.",Voilà pour vous.,"Nos, íme.","Bene, ecco a te.",では、これをどうぞ。,"자, 여기 있습니다.","Nou, hier ben je dan.",Vær så god.,"Proszę, masz.","Muito bem, aqui está.",,Poftiți.,"Хорошо, бери.",,"Ja, här är du.",İşte buradasın. I'm sorry but you don't have enough money for that.,TXT_RNO0_SCRIPT02_D19708_IMSOR,,,,"Promiňte, ale na ten nemáte dost peněz.","Jeg beklager, men du har ikke penge nok til det.","Es tut mir Leid, aber du hast nicht genug Geld dabei.",,"Pardonon, sed vi ne -havas sufiĉe da mono.","Lo siento, pero no te alcanza.",,Valitettavasti teillä ei ole siihen riittävästi rahaa.,Je suis désolé mais vous n'avez pas assez d'argent.,"Sajnálom, de Önnek nem áll módjában kifizetni ezt.","Mi spiace, ma non hai abbastanza soldi per questo.",すみませんが、貴方は十分なお金を持っていません。,"미안하지만, 구매하기 위한 돈이 부족하신 것 같군요.","Het spijt me, maar daar heb je niet genoeg geld voor.","Beklager, men du har ikke nok penger til det.","Przepraszam, ale nie masz wystarczająco dużo monet, aby to kupić.","Sinto muito, mas você não tem dinheiro suficiente para isso.",,"Îmi pare rău, dar nu ai suficienți bani pentru asta.","Извини, но у тебя не хватает денег.",,Üzgünüm ama bunun için yeterli paranız yok. -Leather armor,TXT_RPLY1_SCRIPT02_D19708_LEATH,,,Leather armour,Kožené brnění,Læderrustning,Lederrüstung,,Ledan armaĵon,Armadura de cuero,,Nahkasuojus,Armure en cuir,Bőr páncél,Armatura di cuoio,レザーアーマー,가죽 갑옷,Leren harnas,Lær rustning,Skórzany Pancerz,Armadura de couro,,Armură din piele,Кожаная броня,,Deri zırh -Here you are.,TXT_RYES1_SCRIPT02_D19708_HEREY,,,,Tady máte.,Værsgo.,Bitte sehr.,,Jen.,Aquí tienes.,,"Tässä, olkaa hyvä.",Voilà pour vous.,Tessék,Ecco qua.,これをどうぞ。,여기 있습니다.,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Poftiți.,Держи.,,Buyurun. -Perhaps some other time?,TXT_RNO1_SCRIPT02_D19708_PERHA,,,,Možná někdy jindy?,Måske en anden gang?,Vielleicht ein anderes Mal?,,Ĉu eble alian fojon?,¿Quizás en otra ocasión?,¿Tal vez en otra ocasión?,Ehkä joskus toiste?,Peut être une autre fois?,Talán majd máskor?,"Magari un'altra volta, va bene?",また別の機会に?,나중에 돈을 모아서 구매하세요.,Misschien een andere keer?,Kanskje en annen gang?,Może innym razem?,Talvez uma outra hora?,,Poate altădată?,"Может, в следующий раз?",,Belki başka bir zaman? -Metal armor,TXT_RPLY2_SCRIPT02_D19708_METAL,,,Metal armour,Kovové brnění,Metal rustning,Metallrüstung,,Metalan armaĵon,Armadura de metal,,Metallihaarniska,Armure en Métal,Fém páncél,Armatura di metallo,メタルアーマー,강철 갑옷,Metalen harnas,Metall rustning,Metalowy Pancerz,Armadura de metal,,Armură din metal,Металлическая броня,,Metal zırh -Wear it in good health.,TXT_RYES2_SCRIPT02_D19708_WEARI,(in good health = enjoy),,,Noste jej ve zdraví.,Bær den ved godt helbred.,Trage sie mit Stolz.,,Ĝuu ĝin.,Disfrútala.,,Käyttäkää hyvällä omallatunnolla.,Portez la en bonne santé.,Viseld jó egészséggel!,Che possa esserti utile!,着ると安心しますよ。,믿고 입으셔도 됩니다.,Draag het in goede gezondheid.,Bruk den med god helse.,Bądź zdrów nosząc go.,Vista ela com orgulho.,,Să o porți sănătos.,Носи на здоровье.,,Sağlıkla giy. +havas sufiĉe da mono.","Lo siento, pero no te alcanza.",,Valitettavasti teillä ei ole siihen riittävästi rahaa.,Je suis désolé mais vous n'avez pas assez d'argent.,"Sajnálom, de Önnek nem áll módjában kifizetni ezt.","Mi spiace, ma non hai abbastanza soldi per questo.",すみませんが、貴方は十分なお金を持っていません。,"미안하지만, 구매하기 위한 돈이 부족하신 것 같군요.","Het spijt me, maar daar heb je niet genoeg geld voor.","Beklager, men du har ikke nok penger til det.","Przepraszam, ale nie masz wystarczająco dużo monet, aby to kupić.","Sinto muito, mas você não tem dinheiro suficiente para isso.",,"Îmi pare rău, dar nu ai suficienți bani pentru asta.","Извини, но у тебя не хватает денег.",,"Jag är ledsen, men du har inte tillräckligt med pengar för det.",Üzgünüm ama bunun için yeterli paranız yok. +Leather armor,TXT_RPLY1_SCRIPT02_D19708_LEATH,,,Leather armour,Kožené brnění,Læderrustning,Lederrüstung,,Ledan armaĵon,Armadura de cuero,,Nahkasuojus,Armure en cuir,Bőr páncél,Armatura di cuoio,レザーアーマー,가죽 갑옷,Leren harnas,Lær rustning,Skórzany Pancerz,Armadura de couro,,Armură din piele,Кожаная броня,,Läderrustning,Deri zırh +Here you are.,TXT_RYES1_SCRIPT02_D19708_HEREY,,,,Tady máte.,Værsgo.,Bitte sehr.,,Jen.,Aquí tienes.,,"Tässä, olkaa hyvä.",Voilà pour vous.,Tessék,Ecco qua.,これをどうぞ。,여기 있습니다.,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Poftiți.,Держи.,,Här har du.,Buyurun. +Perhaps some other time?,TXT_RNO1_SCRIPT02_D19708_PERHA,,,,Možná někdy jindy?,Måske en anden gang?,Vielleicht ein anderes Mal?,,Ĉu eble alian fojon?,¿Quizás en otra ocasión?,¿Tal vez en otra ocasión?,Ehkä joskus toiste?,Peut être une autre fois?,Talán majd máskor?,"Magari un'altra volta, va bene?",また別の機会に?,나중에 돈을 모아서 구매하세요.,Misschien een andere keer?,Kanskje en annen gang?,Może innym razem?,Talvez uma outra hora?,,Poate altădată?,"Может, в следующий раз?",,Kanske en annan gång?,Belki başka bir zaman? +Metal armor,TXT_RPLY2_SCRIPT02_D19708_METAL,,,Metal armour,Kovové brnění,Metal rustning,Metallrüstung,,Metalan armaĵon,Armadura de metal,,Metallihaarniska,Armure en Métal,Fém páncél,Armatura di metallo,メタルアーマー,강철 갑옷,Metalen harnas,Metall rustning,Metalowy Pancerz,Armadura de metal,,Armură din metal,Металлическая броня,,Metallrustning,Metal zırh +Wear it in good health.,TXT_RYES2_SCRIPT02_D19708_WEARI,(in good health = enjoy),,,Noste jej ve zdraví.,Bær den ved godt helbred.,Trage sie mit Stolz.,,Ĝuu ĝin.,Disfrútala.,,Käyttäkää hyvällä omallatunnolla.,Portez la bien.,Viseld jó egészséggel!,Che possa esserti utile!,着ると安心しますよ。,믿고 입으셔도 됩니다.,Draag het in goede gezondheid.,Bruk den med god helse.,Bądź zdrów nosząc go.,Vista ela com orgulho.,,Să o porți sănătos.,Носи на здоровье.,,Bär den vid god hälsa.,Sağlıkla giy. Come back when you can afford to buy something you lout!,TXT_RNO2_SCRIPT02_D19708_COMEB,,,,"Vrať se, až si budeš moct něco dovolit, troubo!","Kom tilbage, når du har råd til at købe noget, din slyngel!","Komm zurück wenn du dir etwas leisten kannst, du Rüpel!",,"Revenu kiam vi povos aĉeti ion, stultulo!","¡Vuelve cuando puedas -comprar algo, zopenco! ",,"Palataan asiaan, kun teidän on mahdollista ostaa jotain himoitsemaanne.","Revenez quand vous avez de l'argent, rustre!","Majd akkor gyere vissza, ha lesz pénzed megvenni bármit is, te fajankó!","Ritorna quando potrai permetterti di comprare le cose, cafone!",余裕がある時にまたどうぞ!,이런 거래는 못 하겠습니다. 돈을 모아서 다시 찾아오시길!,Kom terug wanneer je het je kunt veroorloven om iets te kopen wat je louteren kunt!,"Kom tilbake når du har råd til å kjøpe noe, din lømmel!",Wróć kiedy będziesz mógł coś kupić prostaku!,"Volte quando você puder comprar algo, seu caloteiro!",,"Revin-o când o să ai bani să poți cumpăra ceva, secătură!","Возвращайся, когда сможешь позволить себе купить что-нибудь, придурок!",,Bir şeyler satın almaya gücün yettiğinde geri gel! -How may I assist you?,TXT_DLG_SCRIPT02_D21224_HOWMA,MAP02: Hospital.,,,Jak vám mohu pomoci?,Hvordan kan jeg hjælpe dig?,Wie kann ich dir helfen?,,Kiel mi helpu vin?,¿Cómo puedo ayudarte?,,Kuinka voin olla avuksi?,Comment puis-je vous assister?,Miben segíthetek?,Come posso aiutarti?,何かお困りですか?,제가 어떻게 도와드릴까요?,Hoe kan ik u helpen?,Hva kan jeg hjelpe deg med?,Jak mogę ci pomóc?,Como posso ajudar?,,Cu ce vă pot ajuta?,Чем могу помочь?,,Size nasıl yardımcı olabilirim? -Med patch,TXT_RPLY0_SCRIPT02_D21224_MEDPA,〃,,,Obvaz,Medicinsk plaster,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekääre,Pansement,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinplaster,Bandaż,Compressa médica,,Trusă de Prim-Ajutor,Бинтами,,Tıbbi yama -Here's your patch.,TXT_RYES0_SCRIPT02_D21224_HERES,〃,,,Jeden obvaz.,Her er dit plaster.,Hier ist deine Bandage,,Jen viaj kuracbendoj,Aquí tienes tus tiritas.,Aquí tienes tus curitas.,Tässä kääreenne.,Voilà votre pansement.,Itt a tapaszod,Ecco le bende.,これをどうぞ。,의료 붕대 여깄습니다.,Hier is je patch.,Her er medisinplasteret ditt.,Oto twój bandaż.,Aqui está sua compressa.,,Poftiți trusa.,Вот они.,,İşte yamanız. -You need 10 gold for that.,TXT_RNO0_SCRIPT02_D21224_YOUNE,〃,,,Na ten potřebujete deset zlatých.,Du skal bruge 10 guld for det.,Dafür brauchst du 10 Gold.,,Vi bezonas 10 da oro.,Necesitas 10 de oro.,,Siihen tarvitset 10 kolikkoa.,Il vous faut 10 pièces pour cela.,10 Aranyra lesz szükséged ehhez.,Ti servono 10 pezzi d'oro per quello.,10 ゴールド必要です。,10 골드가 필요합니다.,Daar heb je 10 goud voor nodig.,Du trenger 10 gull for det.,Potrzebujesz 10 monet aby to kupić.,Você precisa de 10 de ouro para isso.,,Ai nevoie de 10 monezi de aur pentru asta.,Тебе не хватает 10 золотых.,,Bunun için 10 altına ihtiyacın var. -Medical kit,TXT_RPLY1_SCRIPT02_D21224_MEDIC,〃,,,Lékárničku,Medicinsk kit,Verbandskasten,,Sukurkesto,Botiquín,,Lääkintälaukku,Kit médical,Elsősegély készlet,Kit medico,医療用キット,구급 키트,Medische kit,Medisinsk utstyr,Apteczka,Kit médico,,Kit de Prim-Ajutor,Аптечкой,,Tıbbi kit -Thank you.,TXT_RYES1_SCRIPT02_D21224_THANK,〃,,,Děkuji.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszönöm,Grazie.,ありがとうございます。,이용 감사드려요.,Bedankt.,Takk skal du ha.,Dziękuję.,Agradeço.,,Mulțumesc.,Спасибо.,,Teşekkür ederim. +comprar algo, zopenco! ",,"Palataan asiaan, kun teidän on mahdollista ostaa jotain himoitsemaanne.","Revenez quand vous avez de l'argent, rustre!","Majd akkor gyere vissza, ha lesz pénzed megvenni bármit is, te fajankó!","Ritorna quando potrai permetterti di comprare le cose, cafone!",余裕がある時にまたどうぞ!,이런 거래는 못 하겠습니다. 돈을 모아서 다시 찾아오시길!,Kom terug wanneer je het je kunt veroorloven om iets te kopen wat je louteren kunt!,"Kom tilbake når du har råd til å kjøpe noe, din lømmel!",Wróć kiedy będziesz mógł coś kupić prostaku!,"Volte quando você puder comprar algo, seu caloteiro!",,"Revin-o când o să ai bani să poți cumpăra ceva, secătură!","Возвращайся, когда сможешь позволить себе купить что-нибудь, придурок!",,"Kom tillbaka när du har råd att köpa något, din tölp!",Bir şeyler satın almaya gücün yettiğinde geri gel! +How may I assist you?,TXT_DLG_SCRIPT02_D21224_HOWMA,MAP02: Hospital.,,,Jak vám mohu pomoci?,Hvordan kan jeg hjælpe dig?,Wie kann ich dir helfen?,,Kiel mi helpu vin?,¿Cómo puedo ayudarte?,,Kuinka voin olla avuksi?,Comment puis-je vous assister?,Miben segíthetek?,Come posso aiutarti?,何かお困りですか?,제가 어떻게 도와드릴까요?,Hoe kan ik u helpen?,Hva kan jeg hjelpe deg med?,Jak mogę ci pomóc?,Como posso ajudar?,,Cu ce vă pot ajuta?,Чем могу помочь?,,Hur kan jag hjälpa dig?,Size nasıl yardımcı olabilirim? +Med patch,TXT_RPLY0_SCRIPT02_D21224_MEDPA,〃,,,Obvaz,Medicinsk plaster,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekääre,Pansement,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinplaster,Bandaż,Compressa médica,,Trusă de Prim-Ajutor,Бинтами,,Medicinsk plåster,Tıbbi yama +Here's your patch.,TXT_RYES0_SCRIPT02_D21224_HERES,〃,,,Jeden obvaz.,Her er dit plaster.,Hier ist deine Bandage,,Jen viaj kuracbendoj,Aquí tienes tus tiritas.,Aquí tienes tus curitas.,Tässä kääreenne.,Voilà votre pansement.,Itt a tapaszod,Ecco le bende.,これをどうぞ。,의료 붕대 여깄습니다.,Hier is je patch.,Her er medisinplasteret ditt.,Oto twój bandaż.,Aqui está sua compressa.,,Poftiți trusa.,Вот они.,,Här är ditt plåster.,İşte yamanız. +You need 10 gold for that.,TXT_RNO0_SCRIPT02_D21224_YOUNE,〃,,,Na ten potřebujete deset zlatých.,Du skal bruge 10 guld for det.,Dafür brauchst du 10 Gold.,,Vi bezonas 10 da oro.,Necesitas 10 de oro.,,Siihen tarvitset 10 kolikkoa.,Il vous faut 10 pièces pour cela.,10 Aranyra lesz szükséged ehhez.,Ti servono 10 pezzi d'oro per quello.,10 ゴールド必要です。,10 골드가 필요합니다.,Daar heb je 10 goud voor nodig.,Du trenger 10 gull for det.,Potrzebujesz 10 monet aby to kupić.,Você precisa de 10 de ouro para isso.,,Ai nevoie de 10 monezi de aur pentru asta.,Тебе не хватает 10 золотых.,,Du behöver 10 guld för den.,Bunun için 10 altına ihtiyacın var. +Medical kit,TXT_RPLY1_SCRIPT02_D21224_MEDIC,〃,,,Lékárničku,Medicinsk kit,Verbandskasten,,Sukurkesto,Botiquín,,Lääkintälaukku,Kit médical,Elsősegély készlet,Kit medico,医療用キット,구급 키트,Medische kit,Medisinsk utstyr,Apteczka,Kit médico,,Kit de Prim-Ajutor,Аптечкой,,Medicinsk utrustning,Tıbbi kit +Thank you.,TXT_RYES1_SCRIPT02_D21224_THANK,〃,,,Děkuji.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszönöm,Grazie.,ありがとうございます。,이용 감사드려요.,Bedankt.,Takk skal du ha.,Dziękuję.,Agradeço.,,Mulțumesc.,Спасибо.,,Tack.,Teşekkür ederim. "I wish I could give them away, but they cost 25 gold.",TXT_RNO1_SCRIPT02_D21224_IWISH,〃,,,"Přál bych si je dávat zadarmo, ale stojí 25 zlatých.","Jeg ville ønske, jeg kunne give dem væk, men de koster 25 guld.","Ich wünschte ich könnte sie weggeben, aber sie kosten 25 Gold.",,"Mi donacus ĝin, sed ĝi kostas 25 da oro.","Ojalá pudiera regalarlo, -pero cuesta 25 de oro.",,"Mielelläni antaisin ilmaiseksi, mutta ne maksavat 25 kultakolikkoa.","J'aimerais vraiment les donner gratuitement, mais cela côute 25 pièces.","Bárcsak ingyen osztogathatnám, de 25 aranyba kerül.","Mi piacerebbe darli via, ma costano 25 pezzi d'oro.",譲渡したい所ですが、25 ゴールド必要です。,"주고 싶지만, 이것의 가격은 25 골드입니다.","Ik wou dat ik ze kon weggeven, maar ze kosten 25 goud.","Jeg skulle ønske jeg kunne gi dem bort, men de koster 25 gull.","Chciałbym móc je rozdać, ale one kosztują 25 monet.","Bem que eu queria poder dar de graça, mas custam 25 de ouro.",,"Mi-aș dori să le pot da pe gratis, dar costă 25 de monezi de aur.","С радостью бы отдал, но они по 25 золотых.",,Keşke onları verebilseydim ama 25 altına mal oluyorlar. -Field surgery kit,TXT_RPLY2_SCRIPT02_D21224_FIELD,〃,,,Chirurgickou soupravu,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kenttäkirurgilaukku,Kit de chirurgie,Harctéri műtéti felszerelés,Kit chirurgico,手術キット,수술 키트,Veld chirurgie kit,Kirurgisett,Polowy zestaw chirurga,Kit de cirurgia,,Trusă de chirurgie de teren,Медкомплектом,,Saha ameliyat kiti -There you go. Take care now.,TXT_RYES2_SCRIPT02_D21224_THERE,〃,,,Tady máte. Buďte opatrný.,Værsgo. Pas godt på dig selv nu.,Bitte schön. Mach's gut.,,Jen. Estu atenta.,Aquí tienes. Cuídate.,,Olkaa hyvä. Pitäkää itsestänne huoli.,Voilà pour vous. Faites attention à vous maintenant.,"Tessék, minden jót!",Ecco qua. Stammi bene.,こちらになります、お気をつけて。,여기 있습니다. 잘 쓰세요.,Daar ga je. Pas goed op jezelf.,Vær så god. Ta vare på deg selv.,Proszę bardzo. Trzymaj się.,Aqui está. Se cuida.,,Poftiți. Aveți grijă.,Пожалуйста. Береги себя!,,Al bakalım. Kendine iyi bak. +pero cuesta 25 de oro.",,"Mielelläni antaisin ilmaiseksi, mutta ne maksavat 25 kultakolikkoa.","J'aimerais vraiment les donner gratuitement, mais cela côute 25 pièces.","Bárcsak ingyen osztogathatnám, de 25 aranyba kerül.","Mi piacerebbe darli via, ma costano 25 pezzi d'oro.",譲渡したい所ですが、25 ゴールド必要です。,"주고 싶지만, 이것의 가격은 25 골드입니다.","Ik wou dat ik ze kon weggeven, maar ze kosten 25 goud.","Jeg skulle ønske jeg kunne gi dem bort, men de koster 25 gull.","Chciałbym móc je rozdać, ale one kosztują 25 monet.","Bem que eu queria poder dar de graça, mas custam 25 de ouro.",,"Mi-aș dori să le pot da pe gratis, dar costă 25 de monezi de aur.","С радостью бы отдал, но они по 25 золотых.",,"Jag önskar att jag kunde ge bort dem, men de kostar 25 guld.",Keşke onları verebilseydim ama 25 altına mal oluyorlar. +Field surgery kit,TXT_RPLY2_SCRIPT02_D21224_FIELD,〃,,,Chirurgickou soupravu,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kenttäkirurgilaukku,Kit de chirurgie,Harctéri műtéti felszerelés,Kit chirurgico,手術キット,수술 키트,Veld chirurgie kit,Kirurgisett,Polowy zestaw chirurga,Kit de cirurgia,,Trusă de chirurgie de teren,Медкомплектом,,Fältkirurgisk utrustning,Saha ameliyat kiti +There you go. Take care now.,TXT_RYES2_SCRIPT02_D21224_THERE,〃,,,Tady máte. Buďte opatrný.,Værsgo. Pas godt på dig selv nu.,Bitte schön. Mach's gut.,,Jen. Estu atenta.,Aquí tienes. Cuídate.,,Olkaa hyvä. Pitäkää itsestänne huoli.,Voilà pour vous. Faites attention à vous maintenant.,"Tessék, minden jót!",Ecco qua. Stammi bene.,こちらになります、お気をつけて。,여기 있습니다. 잘 쓰세요.,Daar ga je. Pas goed op jezelf.,Vær så god. Ta vare på deg selv.,Proszę bardzo. Trzymaj się.,Aqui está. Se cuida.,,Poftiți. Aveți grijă.,Пожалуйста. Береги себя!,,Här har du det. Ta hand om dig nu.,Al bakalım. Kendine iyi bak. "Well, maybe you can afford some med patches?",TXT_RNO2_SCRIPT02_D21224_WELLM,〃,,,"No, spíš byste si mohl dovolit nějaké obvazy?","Nå, måske har du råd til nogle medicinske plastre?","Nun, vielleicht kannst du dir ein paar medizinische Bandagen leisten?",,"Nu, ĉu vi eble povas aĉeti kuracbendojn?","Bueno, ¿quizás tengas para comprar tiritas?","Bueno, ¿tal vez tengas -para comprar curitas?",Olisiko teillä kuitenkin sidekääreisiin ehkä varaa?,"Eh bien, peut être que vous pouvez vous acheter quelques pansements?",Talán némi ragtapaszra tudnál költeni?,"Niente da fare, ma forse puoi permetterti delle bende?",ところで、医薬パッチを買う余裕はありますか?,"글쎄요, 아마 의료 붕대 정돈 살 수 있을걸요?","Nou ja, misschien kunt je zich wat med-patches veroorloven?",Kanskje du har råd til noen medisinplaster?,"Cóż, może stać cię na jakieś bandaże?","Bem, talvez você possa comprar algumas compressas?",,"Păi, poate îți permiți niște truse de prim-ajutor?","Тогда, может быть, купишь несколько бинтов?",,Belki ilaç yamalarını karşılayabilirsin? +para comprar curitas?",Olisiko teillä kuitenkin sidekääreisiin ehkä varaa?,"Eh bien, peut être que vous pouvez vous acheter quelques pansements?",Talán némi ragtapaszra tudnál költeni?,"Niente da fare, ma forse puoi permetterti delle bende?",ところで、医薬パッチを買う余裕はありますか?,"글쎄요, 아마 의료 붕대 정돈 살 수 있을걸요?","Nou ja, misschien kunt je zich wat med-patches veroorloven?",Kanskje du har råd til noen medisinplaster?,"Cóż, może stać cię na jakieś bandaże?","Bem, talvez você possa comprar algumas compressas?",,"Păi, poate îți permiți niște truse de prim-ajutor?","Тогда, может быть, купишь несколько бинтов?",,Du kanske har råd med några medicinska plåster?,Belki ilaç yamalarını karşılayabilirsin? "I hope Macil knows what he's doing. If the Order finds out I'm helping the Front I'm as good as dead... Not that this matters to you any. The Front's medic gave me an upgrade chip for you, are you ready? ",TXT_DLG_SCRIPT02_D22740_IHOPE,〃 (After destroying the crystal in the Power Station),,,"Doufám, že Macil ví, co dělá. Jestli Řád zjistí, že pomáhám Frontě, jsem mrtvý... Ne, že by vás to mělo trápit. Medik Fronty mi pro vás dal vylepšovací čip, připraven?","Jeg håber, at Macil ved, hvad han laver. Hvis Ordenen finder ud af, at jeg hjælper fronten, er jeg så godt som død... Ikke at det har nogen betydning for dig. Frontens læge gav mig en opgraderingschip til dig, er du klar?","Ich hoffe Macil weiß was er tut. Wenn der Orden herausfindet das ich der Front helfe, bin ich so gut wie tot... auch wenn es für dich keine Rolle spielt. Ein Sanitäter der Front hat mir einen Verbesserungschip für dich mitgegeben, bist du bereit?",,"Mi esperas, ke Macil scias tion, kion li faras. Se La Ordono malkovras, ke mi helpas la Fronton, mi estos sufiĉe mortinta... Ne kvazaŭ vi zorgus pri tio. La kuracisto de la Fronto donis al mi plibonigan icon por vi. Ĉu vi estas preta?","Espero que Macil sepa lo que está haciendo. Si La Orden se entera de que estoy ayudando al Frente, estoy bien muerto... No es como si te importara. El médico del Frente me dio un chip de mejora para ti. ¿Estás listo?",,"Toivottavasti Macil tietää, mitä tekee. Jos Veljeskunta saa kuulla minun auttavan Rintamaa, olen mennyttä... Ei siinä, että tieto sinua mitenkään kiinnostaisi. Sain Rintaman lääkintämieheltä sinulle päivityssirun; oletko valmis?","J'espère que Macil sait ce qu'il fait. Si l'Ordre se rend compte que j'aide le Front, c'est comme si j'étais mort.. bon, cela ne vous importe pas. Le médecin du Front m'a donné une puce d'augmentation pour vous. Etes vous prêt?","Remélem Macil tudja, mit csinál. Ha a Rend rájön, hogy a Frontot segítem, alulról szagolom majd az ibolyát...Nem mintha ez számítana számodra. A Front orvosa egy fejlesztési chipet küldött neked. Készen állsz?","Spero che Macil sappia quello che sta facendo. Se l'Ordine scopre che sto aiutando il Fronte sarò bello che morto... Non che questo importi ormai. Il medico del Fronte mi ha dato un upgrade chip per te, sei pronto?","マシルの行いが正しければ良いですが。 私がフロントを援助しているとオーダーが 知ったら、私は...これは貴方には関係無いか。 @@ -9973,252 +10455,252 @@ para comprar curitas?",Olisiko teillä kuitenkin sidekääreisiin ehkä varaa?," アップグレードチップを送ってくれました、 装着しますか? ",마실 사령관님이 하는 일이 무엇인지 알고 있기를... 만약 오더가 내가 프론트를 위해 일한다는 걸 눈치챈다면 절 죽일 거예요. 물론 당신이 알 바는 아니지만. 프론트 의무관님이 업그레이드 칩을 당신에게 이식하라고 여기까지 가져왔더군요. 준비되셨습니까?,"Ik hoop dat Macil weet wat hij doet. Als de Orde erachter komt dat ik het Front help, ben ik zo goed als dood.... Niet dat dit belangrijk voor je is. De dokter van het Front heeft me een upgradechip voor je gegeven, ben je er klaar voor?","Jeg håper Macil vet hva han gjør. Hvis Ordenen finner ut at jeg hjelper Fronten, er jeg så godt som død... Ikke at det betyr noe for deg. Frontens lege ga meg en oppgraderingsbrikke til deg. Er du klar?","Mam nadzieję, że Macil wie co robi. Jeśli Zakon odkryje, że pomagam Frontowi, będę martwy... Nie to, że kogokolwiek to obchodzi. Medyk frontu dał mi czip ulepszający dla ciebie, jesteś gotowy?","Espero que Macil saiba o que está fazendo. Se a Ordem descobrir que estou ajudando a Frente, estou morto... Não que isso importe para vocês. O médico da Frente me passou um chip de upgrade pra você, está preparado?",,"Sper că Macil știe ce face. Dacă Ordinul află că ajut Frontul sunt ca și mort. Nu-i ca și cum te-ar interesa asta. Medicul Frontului mi-a dat un cip pentru upgrade, ești pregătit?","Надеюсь, Мэйсил знает, что делает. Если Орден обнаружит, что я помогаю повстанцам, я не жилец... хотя тебе-то какое дело. Медик Сопротивления передал мне этот чип для тебя. Ты готов? -",,"Umarım Macil ne yaptığını biliyordur. Tarikat Cephe'ye yardım ettiğimi öğrenirse ölmüş sayılırım. Bu senin için önemli değil. Cephe'nin doktoru bana senin için bir yükseltme çipi verdi, hazır mısın?" -"Yes, I'm ready.",TXT_RPLY0_SCRIPT02_D22740_YESIM,〃,,,"Ano, jsem připravený.","Ja, jeg er klar.","Ja, ich bin bereit.",,"Jes, mi estas preta.","Sí, estoy listo.",,"Kyllä, olen valmis.","Oui, je suis prêt.","Igen, készen állok.","Sì, sono pronto.",ああ、準備良しだ。,"좋아요, 준비 됐습니다.","Ja, ik ben er klaar voor.","Ja, jeg er klar.","Tak, jestem gotowy.","Sim, estou preparado.",,"Da, sunt pregătit.","Да, готов.",,"Evet, hazırım." +",,"Jag hoppas att Macil vet vad han gör. Om Orden får reda på att jag hjälper fronten är jag så gott som död... Inte för att det spelar någon roll för dig. Frontens läkare gav mig ett uppgraderingschip till dig, är du redo?","Umarım Macil ne yaptığını biliyordur. Tarikat Cephe'ye yardım ettiğimi öğrenirse ölmüş sayılırım. Bu senin için önemli değil. Cephe'nin doktoru bana senin için bir yükseltme çipi verdi, hazır mısın?" +"Yes, I'm ready.",TXT_RPLY0_SCRIPT02_D22740_YESIM,〃,,,"Ano, jsem připravený.","Ja, jeg er klar.","Ja, ich bin bereit.",,"Jes, mi estas preta.","Sí, estoy listo.",,"Kyllä, olen valmis.","Oui, je suis prêt.","Igen, készen állok.","Sì, sono pronto.",ああ、準備良しだ。,"좋아요, 준비 됐습니다.","Ja, ik ben er klaar voor.","Ja, jeg er klar.","Tak, jestem gotowy.","Sim, estou preparado.",,"Da, sunt pregătit.","Да, готов.",,"Ja, jag är redo.","Evet, hazırım." "Well then, this won't take but a second. There, done already.",TXT_RYES0_SCRIPT02_D22740_WELLT,〃,,,"Tak dobře, měla by to být jen vteřinka. Tak, a je hotovo.","Nå, så tager det kun et øjeblik. Sådan, det er allerede gjort.","Nun dann, das wird nicht mal eine Sekunde dauern. So, bereits erledigt.",,"Bone, mi bezonos nur unu sekundon... kaj finite.","Muy bien, solo un -segundo... Y listo.",,"Siinä tapauksessa tähän ei mene paria sekuntia pidempään. Kas näin, valmista jo.","Bon, cela ne prendra qu'une seconde. Voilà, c'est fait.","Jól van hát, nem fog csak egy pár másodpercig tartani... És kész is.","Bene, non ci vorrà molto. Ecco fatto.",それでは、これに時間は掛かりません。はい、完了しました。,"그럼 잠깐이면 됩니다. 자, 다 됐어요.","Nou dan, dit duurt maar een seconde. Daar, al klaar.","Da tar det bare et øyeblikk. Sånn, ferdig.","Dobrze więc, to zajmie tylko sekundę. Już, gotowe.","Muito bem, isso vai levar um segundo. Pronto, já terminei.",,"Bine atunci, va dura doar o secundă. Așa, e gata deja.","Хорошо. Секундочку... Всё, готово.",,"O zaman bir saniye bile sürmez. İşte, bitti bile." -How may I assist you?,TXT_DLG_SCRIPT02_D24256_HOWMA,〃,,,Jak vám mohu pomoci?,Hvordan kan jeg hjælpe dig?,Wie kann ich dir helfen?,,Kiel mi helpu vin?,¿Cómo puedo ayudarte?,,Kuinka voin olla avuksi?,Comment puis-je vous assister?,Miben segíthetek?,Come posso aiutarti?,何かお困りですか?,어떻게 도와드릴까요?,Hoe kan ik je helpen?,Hva kan jeg hjelpe deg med?,Jak mogę ci pomóc?,Como posso ajudar?,,Cu ce vă pot ajuta?,Чем могу тебе помочь?,,Size nasıl yardımcı olabilirim? -Med patch,TXT_RPLY0_SCRIPT02_D24256_MEDPA,〃,,,Obvaz,Medicinsk plaster,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekääre,Pansement,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinplaster.,Bandaż,Compressa médica,,Trusă de Prim-Ajutor,Бинтами,,Tıbbi yama -Here's your patch.,TXT_RYES0_SCRIPT02_D24256_HERES,〃,,,Jeden obvaz.,Her er dit plaster.,Hier ist deine Bandage,,Jen viaj kuracbendoj,Aquí tienes tus tiritas.,Aquí tienes tus curitas.,Tässä kääreenne.,Voilà votre pansement.,Itt a tapaszod.,Ecco le bende.,これをどうぞ。,여기 의료 붕대입니다.,Hier is je patch.,Her er plasteret ditt.,Oto twój bandaż.,Aqui está sua compressa.,,Poftiți trusa.,Вот они.,,İşte yamanız. -You need 10 gold for that.,TXT_RNO0_SCRIPT02_D24256_YOUNE,〃,,,Na ten potřebujete deset zlatých.,Du skal bruge 10 guld for det.,Dafür brauchst du 10 Gold.,,Vi bezonas 10 da oro.,Necesitas 10 de oro.,,Tarvitset siihen 10 kolikkoa.,Il vous faut 10 pièces pour cela.,10 aranyra van szükséged ehhez.,Ti servono 10 pezzi d'oro per quello.,10 ゴールド必要です。,10 골드가 필요한데.,Daar heb je 10 goud voor nodig.,Du trenger 10 gull for det.,Potrzebujesz 10 monet aby to kupić.,Você precisa de 10 de ouro pra isso.,,Ai nevoie de 10 monezi de aur pentru asta.,Тебе не хватает 10 золотых.,,Bunun için 10 altına ihtiyacın var. -Medical kit,TXT_RPLY1_SCRIPT02_D24256_MEDIC,〃,,,Lékárničku,Medicinsk kit,Verbandskasten,,Sukurkesto,Botiquín,,Lääkintälaukku,Kit médical,Orvosi csomag.,Kit medico,医療用キット,구급 키트,Medische kit,Medisinsk utstyr,Apteczka,Kit médico,,Kit de Prim-Ajutor,Аптечкой,,Tıbbi kit -Thank you.,TXT_RYES1_SCRIPT02_D24256_THANK,〃,,,Děkuji.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszönöm.,Grazie.,ありがとうございます。,또 오세요.,Bedankt.,Takk skal du ha.,Dziękuję.,Agradeço.,,Mulțumesc.,Спасибо.,,Teşekkür ederim. +segundo... Y listo.",,"Siinä tapauksessa tähän ei mene paria sekuntia pidempään. Kas näin, valmista jo.","Bon, cela ne prendra qu'une seconde. Voilà, c'est fait.","Jól van hát, nem fog csak egy pár másodpercig tartani... És kész is.","Bene, non ci vorrà molto. Ecco fatto.",それでは、これに時間は掛かりません。はい、完了しました。,"그럼 잠깐이면 됩니다. 자, 다 됐어요.","Nou dan, dit duurt maar een seconde. Daar, al klaar.","Da tar det bare et øyeblikk. Sånn, ferdig.","Dobrze więc, to zajmie tylko sekundę. Już, gotowe.","Muito bem, isso vai levar um segundo. Pronto, já terminei.",,"Bine atunci, va dura doar o secundă. Așa, e gata deja.","Хорошо. Секундочку... Всё, готово.",,"Då tar det här bara en sekund. Där, redan gjort.","O zaman bir saniye bile sürmez. İşte, bitti bile." +How may I assist you?,TXT_DLG_SCRIPT02_D24256_HOWMA,〃,,,Jak vám mohu pomoci?,Hvordan kan jeg hjælpe dig?,Wie kann ich dir helfen?,,Kiel mi helpu vin?,¿Cómo puedo ayudarte?,,Kuinka voin olla avuksi?,Comment puis-je vous assister?,Miben segíthetek?,Come posso aiutarti?,何かお困りですか?,어떻게 도와드릴까요?,Hoe kan ik je helpen?,Hva kan jeg hjelpe deg med?,Jak mogę ci pomóc?,Como posso ajudar?,,Cu ce vă pot ajuta?,Чем могу тебе помочь?,,Hur kan jag hjälpa dig?,Size nasıl yardımcı olabilirim? +Med patch,TXT_RPLY0_SCRIPT02_D24256_MEDPA,〃,,,Obvaz,Medicinsk plaster,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekääre,Pansement,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinplaster.,Bandaż,Compressa médica,,Trusă de Prim-Ajutor,Бинтами,,Med patch,Tıbbi yama +Here's your patch.,TXT_RYES0_SCRIPT02_D24256_HERES,〃,,,Jeden obvaz.,Her er dit plaster.,Hier ist deine Bandage,,Jen viaj kuracbendoj,Aquí tienes tus tiritas.,Aquí tienes tus curitas.,Tässä kääreenne.,Voilà votre pansement.,Itt a tapaszod.,Ecco le bende.,これをどうぞ。,여기 의료 붕대입니다.,Hier is je patch.,Her er plasteret ditt.,Oto twój bandaż.,Aqui está sua compressa.,,Poftiți trusa.,Вот они.,,Här är ditt plåster.,İşte yamanız. +You need 10 gold for that.,TXT_RNO0_SCRIPT02_D24256_YOUNE,〃,,,Na ten potřebujete deset zlatých.,Du skal bruge 10 guld for det.,Dafür brauchst du 10 Gold.,,Vi bezonas 10 da oro.,Necesitas 10 de oro.,,Tarvitset siihen 10 kolikkoa.,Il vous faut 10 pièces pour cela.,10 aranyra van szükséged ehhez.,Ti servono 10 pezzi d'oro per quello.,10 ゴールド必要です。,10 골드가 필요한데.,Daar heb je 10 goud voor nodig.,Du trenger 10 gull for det.,Potrzebujesz 10 monet aby to kupić.,Você precisa de 10 de ouro pra isso.,,Ai nevoie de 10 monezi de aur pentru asta.,Тебе не хватает 10 золотых.,,Du behöver 10 guld för det.,Bunun için 10 altına ihtiyacın var. +Medical kit,TXT_RPLY1_SCRIPT02_D24256_MEDIC,〃,,,Lékárničku,Medicinsk kit,Verbandskasten,,Sukurkesto,Botiquín,,Lääkintälaukku,Kit médical,Orvosi csomag.,Kit medico,医療用キット,구급 키트,Medische kit,Medisinsk utstyr,Apteczka,Kit médico,,Kit de Prim-Ajutor,Аптечкой,,Medicinsk utrustning,Tıbbi kit +Thank you.,TXT_RYES1_SCRIPT02_D24256_THANK,〃,,,Děkuji.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Köszönöm.,Grazie.,ありがとうございます。,또 오세요.,Bedankt.,Takk skal du ha.,Dziękuję.,Agradeço.,,Mulțumesc.,Спасибо.,,Tack.,Teşekkür ederim. "I wish I could give them away, but they cost 25 gold.",TXT_RNO1_SCRIPT02_D24256_IWISH,〃,,,"Přál bych si je dávat zadarmo, ale stojí 25 zlatých.","Jeg ville ønske, jeg kunne give dem væk, men de koster 25 guld.","Ich wünschte ich könnte sie weggeben, aber sie kosten 25 Gold.",,"Mi donacus ĝin, sed ĝi kostas 25 da oro.","Ojalá pudiera regalarlo, -pero cuesta 25 de oro.",,"Kunpa voisinkin antaa niitä ilmaiseksi, mutta ne maksavat 25 kultakolikkoa.","J'aimerais vraiment les donner gratuitement, mais cela côute 25 pièces.","Bárcsak ingyen osztogathatnám, de 25 aranyba kerül.","Mi piacerebbe darli via, ma costano 25 pezzi d'oro.",譲渡したい所ですが、25 ゴールド必要です。,25 골드만 있다면 이건 당신 것인데 말이죠.,"Ik wou dat ik ze kon weggeven, maar ze kosten 25 goud.","Jeg skulle ønske jeg kunne gi dem bort, men de koster 25 gull.","Chciałbym móc je rozdać, ale one kosztują 25 monet.","Bem que eu queria poder dar de graça, mas custam 25 de ouro.",,"Mi-aș dori să le pot da pe gratis, dar costă 25 de monezi de aur.","С радостью бы отдал, но они по 25 золотых.",,Keşke onları verebilseydim ama 25 altına mal oluyorlar. -Field surgery kit,TXT_RPLY2_SCRIPT02_D24256_FIELD,〃,,,Chirurgickou soupravu,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kenttäkirurgilaukku,Kit de chirurgie,Harctéri műtéti felszerelés,Kit chirurgico,手術キット,수술 키트,Veld chirurgie kit,Kirurgisett,Polowy zestaw chirurga,Kit de cirurgia,,Trusă de chirurgie de teren,Медкомплект,,Saha ameliyat kiti -There you go. Take care now.,TXT_RYES2_SCRIPT02_D24256_THERE,〃,,,Tady máte. Buďte opatrný.,Værsgo. Pas godt på dig selv nu.,Bitte schön. Mach's gut.,,Jen. Estu atenta.,Aquí tienes. Cuídate.,,Olkaa hyvä. Pitäkää itsestänne huoli.,Voilà pour vous. Faites attention à vous maintenant.,Parancsolj! Aztán vigyázz magadra!,Ecco qua. Stammi bene.,こちらになります、お気をつけて。,여기 있습니다. 잘 쓰세요.,Daar ga je. Pas goed op jezelf.,Vær så god. Ta vare på deg selv.,Proszę bardzo. Trzymaj się.,Aqui está. Se cuida.,,Poftiți. Aveți grijă.,Пожалуйста. Береги себя!,,Al bakalım. Kendine iyi bak. +pero cuesta 25 de oro.",,"Kunpa voisinkin antaa niitä ilmaiseksi, mutta ne maksavat 25 kultakolikkoa.","J'aimerais vraiment les donner gratuitement, mais cela côute 25 pièces.","Bárcsak ingyen osztogathatnám, de 25 aranyba kerül.","Mi piacerebbe darli via, ma costano 25 pezzi d'oro.",譲渡したい所ですが、25 ゴールド必要です。,25 골드만 있다면 이건 당신 것인데 말이죠.,"Ik wou dat ik ze kon weggeven, maar ze kosten 25 goud.","Jeg skulle ønske jeg kunne gi dem bort, men de koster 25 gull.","Chciałbym móc je rozdać, ale one kosztują 25 monet.","Bem que eu queria poder dar de graça, mas custam 25 de ouro.",,"Mi-aș dori să le pot da pe gratis, dar costă 25 de monezi de aur.","С радостью бы отдал, но они по 25 золотых.",,"Jag önskar att jag kunde ge bort dem, men de kostar 25 guld.",Keşke onları verebilseydim ama 25 altına mal oluyorlar. +Field surgery kit,TXT_RPLY2_SCRIPT02_D24256_FIELD,〃,,,Chirurgickou soupravu,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kenttäkirurgilaukku,Kit de chirurgie,Harctéri műtéti felszerelés,Kit chirurgico,手術キット,수술 키트,Veld chirurgie kit,Kirurgisett,Polowy zestaw chirurga,Kit de cirurgia,,Trusă de chirurgie de teren,Медкомплект,,Fältkirurgisk utrustning,Saha ameliyat kiti +There you go. Take care now.,TXT_RYES2_SCRIPT02_D24256_THERE,〃,,,Tady máte. Buďte opatrný.,Værsgo. Pas godt på dig selv nu.,Bitte schön. Mach's gut.,,Jen. Estu atenta.,Aquí tienes. Cuídate.,,Olkaa hyvä. Pitäkää itsestänne huoli.,Voilà pour vous. Faites attention à vous maintenant.,Parancsolj! Aztán vigyázz magadra!,Ecco qua. Stammi bene.,こちらになります、お気をつけて。,여기 있습니다. 잘 쓰세요.,Daar ga je. Pas goed op jezelf.,Vær så god. Ta vare på deg selv.,Proszę bardzo. Trzymaj się.,Aqui está. Se cuida.,,Poftiți. Aveți grijă.,Пожалуйста. Береги себя!,,Här har du det. Ta hand om dig nu.,Al bakalım. Kendine iyi bak. "Well, maybe you can afford some med patches?",TXT_RNO2_SCRIPT02_D24256_WELLM,〃,,,"No, spíš byste si mohl dovolit nějaké obvazy?","Nå, måske har du råd til nogle medicinske plastre?","Nun, vielleicht kannst du dir ein paar medizinische Bandagen leisten?",,"Nu, ĉu vi eble povas aĉeti kuracbendojn?","Bueno, ¿quizás tengas para comprar tiritas?","Bueno, ¿tal vez tengas -para comprar curitas?",Olisiko teillä ehkä varaa sidekääreisiin?,"Eh bien, peut être que vous pouvez vous acheter quelques pansements?","Nos, talán telik pár ragtapaszra is?","Niente da fare, ma forse puoi permetterti delle bende?",ところで、医薬パッチを買う余裕はありますか?,글쎄요... 의료 붕대는 어떻습니까?,"Nou ja, misschien kunt je zich wat med-patches veroorloven?",Kanskje du har råd til noen medisinplaster?,"Cóż, może stać cię na jakieś bandaże?","Bem, talvez você possa comprar algumas compressas?",,"Păi, poate îți permiți niște truse de prim-ajutor?","Тогда, может быть, купишь несколько бинтов?",,Belki birkaç ilaç yamasını karşılayabilirsin? +para comprar curitas?",Olisiko teillä ehkä varaa sidekääreisiin?,"Eh bien, peut être que vous pouvez vous acheter quelques pansements?","Nos, talán telik pár ragtapaszra is?","Niente da fare, ma forse puoi permetterti delle bende?",ところで、医薬パッチを買う余裕はありますか?,글쎄요... 의료 붕대는 어떻습니까?,"Nou ja, misschien kunt je zich wat med-patches veroorloven?",Kanskje du har råd til noen medisinplaster?,"Cóż, może stać cię na jakieś bandaże?","Bem, talvez você possa comprar algumas compressas?",,"Păi, poate îți permiți niște truse de prim-ajutor?","Тогда, может быть, купишь несколько бинтов?",,Du kanske har råd med några medicinska plåster?,Belki birkaç ilaç yamasını karşılayabilirsin? "Hello stranger, I haven't seen you around here before. Let me give you a piece of free advice. I'd be careful if I were you. The Order does not tolerate free will, and their justice is swift.",TXT_DLG_SCRIPT02_D25772_HELLO,MAP02: Barkeep.,,,"Vítejte, cizinče, vás jsem tu ještě neviděl. Dám vám drobnou radu na začátek grátis: Být vámi, byl bych opatrný. Řád netoleruje svobodnou vůli a jejich spravedlnost je hbitá. ","Hej fremmede, jeg har ikke set dig her før. Lad mig give dig et gratis råd. Jeg ville være forsigtig, hvis jeg var dig. Ordenen tolererer ikke fri vilje, og deres retfærdighed er hurtig.","Hallo, Fremder. Ich habe dich hier vorher noch nie gesehen. Lass mich dir einen kostenlosen Rat geben. An deiner Stelle wäre ich vorsichtig. Der Orden duldet keinen freien Willen und sie greifen hart durch.",,"Saluton, fremdulo, mi ne vidis vin ĉi tie antaŭe. Jen senpaga konsilo: mi estus atenta se mi estus vi; La Ordono ne toleras liberan volon kaj havas rapidan «juston».","Hola, extranjero, no te he visto por aquí antes. Te daré un consejo gratis: tendría cuidado si fuera tú; La Orden no tolera el libre albedrío y su justicia es veloz.","Hola, extranjero, es la primera vez que te veo por aquí. Te voy a dar un consejo gratis: tendría cuidado si fuera tú; La Orden no tolera el libre albedrío y su justicia es veloz.","Päivää. En olekaan nähnyt teitä täällä ennen. Teinä neuvoisin olemaan varuillanne. Veljeskunta ei suvaitse vapaata tahtoa, ja heidän tuomionsa ovat pikaiset.","Bien le bonjour, étranger. On ne vous a pas encore vu dans ce coin. Laissez-moi vous donner un petit conseil. Je ferais attention si j'étais vous. L'Ordre ne tolère pas le libre arbitre et leur justice est fulgurante.","Üdvözöllek idegen, nem láttalak még itt a környéken. Hadd adjak egy ingyen tanácsot. Én óvatos lennék a helyedben. A Rend nem tolerálja a szabad akaratot, és elég fürge az igazságszolgáltatás.","Salve straniero, non ti ho mai visto da queste parti prima. Lascia che ti dia un consiglio. Io starei attento se fossi in te. L'Ordine non tollera il libero arbitrio, e la loro ""giustizia"" è repentina.","どうも余所者、この辺では見かけない顔だな。 では一杯アドバイスをおごろう。この付近が 自由な発言を許さないからって下手な真似は するなよ。オーダーという自警団がすぐに -駆けつけてくるぞ。","안녕하신가 이방인이여, 자네는 이곳에서 처음 보는 얼굴이군. 내가 자네에게 공짜 조언을 해주지. 내가 자네라면 조심할 거야. 오더는 자유의지를 용납하지 않아. 그리고 그들의 정의는 신속하지.","Hallo vreemdeling, ik heb je hier nog niet eerder gezien. Laat me je een stukje gratis advies geven. Ik zou voorzichtig zijn als ik jou was. De Orde tolereert geen vrije wil en hun gerechtigheid is snel.","Hei, fremmede, jeg har ikke sett deg her før. La meg gi deg et gratis råd. Jeg ville vært forsiktig hvis jeg var deg. Ordenen tolererer ikke fri vilje, og deres rettferdighet er rask.","Witaj nieznajomy, nigdy cie tu wcześniej nie widziałem. Dam ci darmową radę. Na twoim miejscu bym uważał. Zakon nie toleruje wolnej woli, a ich prawo działa prędko.","Olá, forasteiro. Nunca vi você por aqui antes. Deixa eu te dar um conselho de graça. Eu tomaria cuidado se eu fosse você. A Ordem não tolera livre arbítrio e a justiça deles é rápida.",,"Salutări străine, nu te-am mai văzut pe-aici. Permite-mi să-ți dau un sfat. Aș fi grijuliu în locul tău. Ordinul nu tolerează voința liberă, iar justiția lor e rapidă.","Привет, незнакомец. Что-то я не видел тебя тут раньше. Позволь дать тебе бесплатный совет: я на твоём месте был бы поосторожнее. Орден не терпит неповиновения, и они скоры на суд.",,"Merhaba yabancı, seni daha önce buralarda görmemiştim. Sana bedava bir tavsiye vereyim. Yerinde olsam dikkatli olurdum. Tarikat'ın özgür iradeye tahammülü yoktur ve adaletleri çok hızlıdır." -What's the word?,TXT_RPLY0_SCRIPT02_D25772_WHATS,〃,,,Nějaké zvěsti?,Hvad er ordet?,Was erzählt man sich so?,,Kion oni diras ĉi tie?,¿Qué se dice por aquí?,,Mikä on päivän sana?,C'est quoi la rumeur?,Mi a hír?,Che si dice in giro?,他には?,무슨 뜻이죠?,Wat is het woord?,Hva heter det?,Jakieś wieści?,Quais são as últimas?,,Ai vreo veste?,Есть новости?,,Neydi o kelime? +駆けつけてくるぞ。","안녕하신가 이방인이여, 자네는 이곳에서 처음 보는 얼굴이군. 내가 자네에게 공짜 조언을 해주지. 내가 자네라면 조심할 거야. 오더는 자유의지를 용납하지 않아. 그리고 그들의 정의는 신속하지.","Hallo vreemdeling, ik heb je hier nog niet eerder gezien. Laat me je een stukje gratis advies geven. Ik zou voorzichtig zijn als ik jou was. De Orde tolereert geen vrije wil en hun gerechtigheid is snel.","Hei, fremmede, jeg har ikke sett deg her før. La meg gi deg et gratis råd. Jeg ville vært forsiktig hvis jeg var deg. Ordenen tolererer ikke fri vilje, og deres rettferdighet er rask.","Witaj nieznajomy, nigdy cie tu wcześniej nie widziałem. Dam ci darmową radę. Na twoim miejscu bym uważał. Zakon nie toleruje wolnej woli, a ich prawo działa prędko.","Olá, forasteiro. Nunca vi você por aqui antes. Deixa eu te dar um conselho de graça. Eu tomaria cuidado se eu fosse você. A Ordem não tolera livre arbítrio e a justiça deles é rápida.",,"Salutări străine, nu te-am mai văzut pe-aici. Permite-mi să-ți dau un sfat. Aș fi grijuliu în locul tău. Ordinul nu tolerează voința liberă, iar justiția lor e rapidă.","Привет, незнакомец. Что-то я не видел тебя тут раньше. Позволь дать тебе бесплатный совет: я на твоём месте был бы поосторожнее. Орден не терпит неповиновения, и они скоры на суд.",,"Hej främling, jag har inte sett dig här förut. Låt mig ge dig ett gratis råd. Jag skulle vara försiktig om jag var du. Orden tolererar inte fri vilja och deras rättvisa är snabb.","Merhaba yabancı, seni daha önce buralarda görmemiştim. Sana bedava bir tavsiye vereyim. Yerinde olsam dikkatli olurdum. Tarikat'ın özgür iradeye tahammülü yoktur ve adaletleri çok hızlıdır." +What's the word?,TXT_RPLY0_SCRIPT02_D25772_WHATS,〃,,,Nějaké zvěsti?,Hvad er ordet?,Was erzählt man sich so?,,Kion oni diras ĉi tie?,¿Qué se dice por aquí?,,Mikä on päivän sana?,C'est quoi la rumeur?,Mi a hír?,Che si dice in giro?,他には?,무슨 뜻이죠?,Wat is het woord?,Hva heter det?,Jakieś wieści?,Quais são as últimas?,,Ai vreo veste?,Есть новости?,,Vad heter det?,Neydi o kelime? The word is... The sewers hold more than just rats and robots.,TXT_RYES0_SCRIPT02_D25772_THEWO,〃,,,Kolují zvěsti... že stoky ukrývají víc než jen krysy a roboty.,Ordet er... Kloakkerne rummer mere end bare rotter og robotter.,"Man erzählt sich, dass die Kanalisation mehr als Ratten und Roboter zu bieten hat.",,"Oni diras... ke en la kloakoj ne estas nur ratoj kaj robotoj.","Se dice... que en las alcantarillas -hay más que solo ratas y robots.",,Sana on... että viemärit pitävät sisällään muutakin kuin vain rottia ja robotteja.,La rumeur est.. Que les égouts cachent quelque chose de plus gros que des rats et des robots.,Az a hír...hogy a kanális nem csak patkányokat és robotokat rejteget.,In giro si dice che... Le fogne contengono molto di più che ratti e robot.,他は...下水道には鼠やロボが沢山だ。,"무슨 말이냐 하면, 하수도 안에는 시궁쥐만 있는 게 아니라 로봇들도 숨어 있다는 거지.",Het woord is.... De riolen bevatten meer dan alleen ratten en robots.,Ordet er... Kloakken rommer mer enn bare rotter og roboter.,"Wieści są takie, że... kanały skrywają coś więcej niż tylko szczury i roboty.",As últimas são... Que os esgotos abrigam mais do que apenas ratos e robôs.,,Vestea e că... Canalele ascund mai mult decât roboți și șoareci.,"Говорят, в канализации водятся не только крысы и роботы.",,Kelime şu. Lağımlarda fareler ve robotlardan daha fazlası var. -What can I do for you now?,TXT_DLG_SCRIPT02_D27288_WHATC,〃,,,Co pro vás můžu udělat teď?,Hvad kan jeg gøre for dig nu?,Was kann ich jetzt für dich tun?,,Kion mi faru por vi?,¿Qué puedo hacer por ti?,,"No niin, miten voin olla teille avuksi?",Que puis-je faire pour vous?,Mit tehetek ma Önért?,E ora cosa posso fare per te?,何か用か?,이제 자네에게 무엇을 해드릴까?,Wat kan ik nu voor je doen?,Hva kan jeg gjøre for deg nå?,Co mogę dla ciebie zrobić?,O que posso fazer por você agora?,,Cu ce te mai pot ajuta?,Тебе что-нибудь нужно?,,Şimdi senin için ne yapabilirim? -More info.,TXT_RPLY0_SCRIPT02_D27288_MOREI,〃,,,Další informace,Mere info.,Mehr Informationen.,,Pliaj informoj,Más información,,Muuta tietoa.,Plus d'infos.,Több információt.,Altre informazioni.,話のネタ。,더 많은 정보를 주세요.,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multe informații.,Расскажи больше,,Daha fazla bilgi. +hay más que solo ratas y robots.",,Sana on... että viemärit pitävät sisällään muutakin kuin vain rottia ja robotteja.,La rumeur est.. Que les égouts cachent quelque chose de plus gros que des rats et des robots.,Az a hír...hogy a kanális nem csak patkányokat és robotokat rejteget.,In giro si dice che... Le fogne contengono molto di più che ratti e robot.,他は...下水道には鼠やロボが沢山だ。,"무슨 말이냐 하면, 하수도 안에는 시궁쥐만 있는 게 아니라 로봇들도 숨어 있다는 거지.",Het woord is.... De riolen bevatten meer dan alleen ratten en robots.,Ordet er... Kloakken rommer mer enn bare rotter og roboter.,"Wieści są takie, że... kanały skrywają coś więcej niż tylko szczury i roboty.",As últimas são... Que os esgotos abrigam mais do que apenas ratos e robôs.,,Vestea e că... Canalele ascund mai mult decât roboți și șoareci.,"Говорят, в канализации водятся не только крысы и роботы.",,Ordet är... Kloakerna innehåller mer än bara råttor och robotar.,Kelime şu. Lağımlarda fareler ve robotlardan daha fazlası var. +What can I do for you now?,TXT_DLG_SCRIPT02_D27288_WHATC,〃,,,Co pro vás můžu udělat teď?,Hvad kan jeg gøre for dig nu?,Was kann ich jetzt für dich tun?,,Kion mi faru por vi?,¿Qué puedo hacer por ti?,,"No niin, miten voin olla teille avuksi?",Que puis-je faire pour vous?,Mit tehetek ma Önért?,E ora cosa posso fare per te?,何か用か?,이제 자네에게 무엇을 해드릴까?,Wat kan ik nu voor je doen?,Hva kan jeg gjøre for deg nå?,Co mogę dla ciebie zrobić?,O que posso fazer por você agora?,,Cu ce te mai pot ajuta?,Тебе что-нибудь нужно?,,Vad kan jag göra för dig nu?,Şimdi senin için ne yapabilirim? +More info.,TXT_RPLY0_SCRIPT02_D27288_MOREI,〃,,,Další informace,Mere info.,Mehr Informationen.,,Pliaj informoj,Más información,,Muuta tietoa.,Plus d'infos.,Több információt.,Altre informazioni.,話のネタ。,더 많은 정보를 주세요.,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multe informații.,Расскажи больше,,Mer information.,Daha fazla bilgi. The Governor is a simple reminder to us that we aren't free people anymore.,TXT_RYES0_SCRIPT02_D27288_THEGO,〃,,,"Náš guvernér je hezkou přípomínkou toho, že už nejsme svobodní.","Guvernøren er en simpel påmindelse til os om, at vi ikke længere er frie mennesker.","Der Gouverneur ist eine einfache Erinnerung daran, das wir keine freien Menschen mehr sind.",,"La registo estas simpla memorigaĵo pri tio, ke ne plu estas libero.","El gobernador es un simple recordatorio de -que ya no somos libres.",,"Kuvernööri toimii meille pienenä muistutuksena, ettemme ole enää vapaita ihmisiä.",Le gouverneur n'est qu'un exemple parmi d'autres pour nous montrer que ne nous somme plus un peuple libre.,"A Kormányzó egy egyszerű emlékeztető számunkra, hogy többé nem vagyunk szabad emberek.",Il governatore serve solo a farci ricordare che non siamo più delle persone libere.,知事は俺達に自由はないと思い出させる象徴さ。,모렐 총독은 우리들이 자유롭게 남들을 도울 수 없는 이유 중 하나이기도 하다네.,De gouverneur herinnert ons er eenvoudigweg aan dat we geen vrije mensen meer zijn.,Guvernøren er en enkel påminnelse om at vi ikke er frie mennesker lenger.,"Gubernator jest dla nas przypomnieniem, że już nie jesteśmy wolnymi ludźmi.",O Governador é um simples lembrete para nós de que não somos mais um povo livre.,,Guvernatorul e un simplu memento că nu mai suntem oameni liberi.,"Губернатор — живое напоминание, что мы больше не свободные люди.",,Vali bize artık özgür insanlar olmadığımızı hatırlatıyor. -Come back when you get some gold.,TXT_RNO0_SCRIPT02_D27288_COMEB,〃,,,"Vrať se, až budeš mít trochu zlata.","Kom tilbage, når du får noget guld.","Komm zurück, wenn du etwas Gold hast.",,Revenu kiam vi havos sufiĉe da oro.,Vuelve cuando tengas suficiente oro.,,"Palatkaa takaisin, kun teillä on kultaa.",Revenez quand vous avez de l'argent.,"Majd akkor térj vissza, ha szeretél egy kis aranyat.",Ritorna quando avrai più oro.,銭を一杯分持って戻ってきな。,골드가 더 있다면 더 알려주지.,Kom terug als je wat goud krijgt.,Kom tilbake når du har gull.,Wróć kiedy będziesz miał więcej monet.,Volte quando tiver ouro.,,Revin-o când ai niște aur.,"Возвращайся, когда у тебя будет золото.",,Biraz altın bulduğunda geri gel. +que ya no somos libres.",,"Kuvernööri toimii meille pienenä muistutuksena, ettemme ole enää vapaita ihmisiä.",Le gouverneur n'est qu'un exemple parmi d'autres pour nous montrer que ne nous somme plus un peuple libre.,"A Kormányzó egy egyszerű emlékeztető számunkra, hogy többé nem vagyunk szabad emberek.",Il governatore serve solo a farci ricordare che non siamo più delle persone libere.,知事は俺達に自由はないと思い出させる象徴さ。,모렐 총독은 우리들이 자유롭게 남들을 도울 수 없는 이유 중 하나이기도 하다네.,De gouverneur herinnert ons er eenvoudigweg aan dat we geen vrije mensen meer zijn.,Guvernøren er en enkel påminnelse om at vi ikke er frie mennesker lenger.,"Gubernator jest dla nas przypomnieniem, że już nie jesteśmy wolnymi ludźmi.",O Governador é um simples lembrete para nós de que não somos mais um povo livre.,,Guvernatorul e un simplu memento că nu mai suntem oameni liberi.,"Губернатор — живое напоминание, что мы больше не свободные люди.",,Guvernören är en enkel påminnelse om att vi inte längre är fria människor.,Vali bize artık özgür insanlar olmadığımızı hatırlatıyor. +Come back when you get some gold.,TXT_RNO0_SCRIPT02_D27288_COMEB,〃,,,"Vrať se, až budeš mít trochu zlata.","Kom tilbage, når du får noget guld.","Komm zurück, wenn du etwas Gold hast.",,Revenu kiam vi havos sufiĉe da oro.,Vuelve cuando tengas suficiente oro.,,"Palatkaa takaisin, kun teillä on kultaa.",Revenez quand vous avez de l'argent.,"Majd akkor térj vissza, ha szeretél egy kis aranyat.",Ritorna quando avrai più oro.,銭を一杯分持って戻ってきな。,골드가 더 있다면 더 알려주지.,Kom terug als je wat goud krijgt.,Kom tilbake når du har gull.,Wróć kiedy będziesz miał więcej monet.,Volte quando tiver ouro.,,Revin-o când ai niște aur.,"Возвращайся, когда у тебя будет золото.",,Kom tillbaka när du får lite guld.,Biraz altın bulduğunda geri gel. "Well, you're asking a lot of questions for someone who's not trying to die. Make sure you don't go and get yourself killed, or worse.",TXT_DLG_SCRIPT02_D28804_WELLY,〃,,,"Na někoho, kdo se nesnaží zemřít, se hodně ptáš. Dej si pozor a nenech se zabít, nebo něco horšího.","Du stiller mange spørgsmål af en, der ikke prøver at dø. Sørg for, at du ikke går hen og bliver dræbt, eller det der er værre.","Hmm, du stellst aber ziemlich viele Fragen für jemand der nicht versucht zu sterben. Lass dich nicht umbringen, oder schlimmeres.",,"Nu, vi faras multe da demandoj por esti iu, kiu ne intencas morti. Certiĝu, ke vi ne kaŭzos al vi mortigon... aŭ ion pli malbonan.","Bueno, estás haciendo muchas preguntas para ser alguien que no está tratando de morir. Asegúrate de que no vayas a hacer que te maten... o algo peor.",,"Kylläpäs te kysytte paljon ollaksenne joku, joka ei yritä tappaa itsensä. Pitäkää vain huoli, ettei niin edelleenkään käy, tai pahemmin.","Vous posez beaucoup de questions pour quelqu'un qui n'essaie pas de se faire tuer. Essayez donc de ne pas vous faire descendre, ou pire.","Figyelj, elég sok kérdést teszel fel, ahhoz képest, hogy elvileg nem akarsz meghalni. Igyekezz nem kinyiratni magad a továbbiakban, vagy rosszabb.","Lo sai, fai davvero tante domande per uno che cerca di sopravvivere. Fai attenzione a non farti uccidere, o peggio...","所で、アンタは死に行かない人達に 聞き回ってる様だが。悪いことは言わねえ、 -あんまし死に急ぐんじゃねえぞ。",죽지 않으려고 발버둥 치듯이 질문을 많이 하는구먼. 무장한 곳에 무모하게 가서 죽지나 말게.,"Nou, je stelt veel vragen voor iemand die niet probeert te sterven. Zorg ervoor dat je niet gaat en jezelf niet dood laat gaan, of erger nog.",Du stiller mange spørsmål til å være en som ikke prøver å dø. Pass på at du ikke blir drept eller det som verre er.,"Cóż, zadajesz dużo pytań jak na kogoś, kto próbuje nie zginąć. Upewnij się, że nie dasz się zabić jak pójdziesz. Lub gorzej.","Bom, você está fazendo um monte de perguntas pra alguém que não está tentando morrer. Procure não acabar sendo morto por aí, ou coisa pior.",,"Păi, pui multe întrebări pentru cineva care încearcă să nu moară. Ai grijă să nu ajungi un om mort, sau mai rău.","Ты задаёшь слишком много вопросов для того, кто не хочет сдохнуть. Убедись, что не идёшь на верную смерть или чего похуже.",,Ölmeye çalışmayan biri için çok fazla soru soruyorsun. Gidip kendini öldürtmediğinden ya da daha kötüsünü yapmadığından emin ol. -More info.,TXT_RPLY0_SCRIPT02_D28804_MOREI,〃,,,Další informace,Mere info.,Mehr Informationen.,,Pliaj informoj,Más información,,Muuta tietoa.,Plus d'infos.,Több infót.,Altre informazioni.,話のネタ。,정보를 좀 더 알려주시오.,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multe informații.,Говори дальше.,,Daha fazla bilgi. +あんまし死に急ぐんじゃねえぞ。",죽지 않으려고 발버둥 치듯이 질문을 많이 하는구먼. 무장한 곳에 무모하게 가서 죽지나 말게.,"Nou, je stelt veel vragen voor iemand die niet probeert te sterven. Zorg ervoor dat je niet gaat en jezelf niet dood laat gaan, of erger nog.",Du stiller mange spørsmål til å være en som ikke prøver å dø. Pass på at du ikke blir drept eller det som verre er.,"Cóż, zadajesz dużo pytań jak na kogoś, kto próbuje nie zginąć. Upewnij się, że nie dasz się zabić jak pójdziesz. Lub gorzej.","Bom, você está fazendo um monte de perguntas pra alguém que não está tentando morrer. Procure não acabar sendo morto por aí, ou coisa pior.",,"Păi, pui multe întrebări pentru cineva care încearcă să nu moară. Ai grijă să nu ajungi un om mort, sau mai rău.","Ты задаёшь слишком много вопросов для того, кто не хочет сдохнуть. Убедись, что не идёшь на верную смерть или чего похуже.",,"Du ställer många frågor för någon som inte försöker dö. Se till att du inte går och blir dödad, eller värre.",Ölmeye çalışmayan biri için çok fazla soru soruyorsun. Gidip kendini öldürtmediğinden ya da daha kötüsünü yapmadığından emin ol. +More info.,TXT_RPLY0_SCRIPT02_D28804_MOREI,〃,,,Další informace,Mere info.,Mehr Informationen.,,Pliaj informoj,Más información,,Muuta tietoa.,Plus d'infos.,Több infót.,Altre informazioni.,話のネタ。,정보를 좀 더 알려주시오.,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multe informații.,Говори дальше.,,Mer information.,Daha fazla bilgi. There's more to the Order than meets the eye.,TXT_RYES0_SCRIPT02_D28804_THERE,〃,,,"Za Řádem se toho skrývá víc, než se zdá.","Der er mere i Ordenen, end man umiddelbart tror.",An dem Orden ist mehr dran als man auf den ersten Blick denkt.,,"Estas pli pri La Ordono, ol kiom ili ŝajnigas.","Hay más de La Orden -de lo que aparenta.",,"Veljeskunta ei ole sitä, miltä päältä päin näyttää.",L'Ordre cache bien son jeu.,"Több van a Rend mögött, mint ami a külső sejtet.",C'è sotto molto di più sull'Ordine rispetto a come possa sembrare.,オーダーは見えてる以上に強大だ。,오더의 뒤에는 더 많은 것들이 숨겨져 있다네. 비밀 같은 것들 말일세.,De Orde heeft meer te bieden dan je op het eerste gezicht zou denken.,Det er mer ved Ordenen enn det som møter øyet.,"Zakonu jest więcej, niż się wydaje.",Há mais sobre a Ordem do que aparenta.,,Este ceva mai mult la Ordin decât ceea ce se poate vedea cu ochiul liber.,"Орден больше, чем кажется.",,Tarikat'ta göründüğünden daha fazlası var. +de lo que aparenta.",,"Veljeskunta ei ole sitä, miltä päältä päin näyttää.",L'Ordre cache bien son jeu.,"Több van a Rend mögött, mint ami a külső sejtet.",C'è sotto molto di più sull'Ordine rispetto a come possa sembrare.,オーダーは見えてる以上に強大だ。,오더의 뒤에는 더 많은 것들이 숨겨져 있다네. 비밀 같은 것들 말일세.,De Orde heeft meer te bieden dan je op het eerste gezicht zou denken.,Det er mer ved Ordenen enn det som møter øyet.,"Zakonu jest więcej, niż się wydaje.",Há mais sobre a Ordem do que aparenta.,,Este ceva mai mult la Ordin decât ceea ce se poate vedea cu ochiul liber.,"Орден больше, чем кажется.",,Det finns mer i Orden än vad man kan tro.,Tarikat'ta göründüğünden daha fazlası var. We'll talk when you get gold!,TXT_RNO0_SCRIPT02_D28804_WELLT,〃,,,"Popovídáme si, když budeš mít zlato!","Vi taler sammen, når du får guld!","Wir werden reden, wenn du Gold hast!",,"Ni parolos kiam -vi alportos oron!",¡Hablamos cuando traigas oro!,,"Puhutaan, kun sinulla on kultaa.",On parlera quand tu auras des sous!,"Majd beszélünk, ha lesz aranyad.",Ne parleremo quando avrai più soldi!,銭を持ってたら話すさ!,골드를 더 가져오면 의논을 시작해보지.,We praten wel als je goud krijgt!,Vi snakkes når du får gull!,Pomówimy jeśli masz złoto.,Conversaremos quando você tiver ouro!,,Vorbim când aduci aur!,"Поговорим, когда принесёшь золото!",,Altın aldığında konuşuruz! +vi alportos oron!",¡Hablamos cuando traigas oro!,,"Puhutaan, kun sinulla on kultaa.",On parlera quand tu auras des sous!,"Majd beszélünk, ha lesz aranyad.",Ne parleremo quando avrai più soldi!,銭を持ってたら話すさ!,골드를 더 가져오면 의논을 시작해보지.,We praten wel als je goud krijgt!,Vi snakkes når du får gull!,Pomówimy jeśli masz złoto.,Conversaremos quando você tiver ouro!,,Vorbim când aduci aur!,"Поговорим, когда принесёшь золото!",,Vi pratar när du får guld!,Altın aldığında konuşuruz! "That's it friend, the well of knowledge has run dry. I've told you more than I should have anyway. Good luck... And don't come back.",TXT_DLG_SCRIPT02_D30320_THATS,〃,,,"A to je vše, příteli, studnice mé moudrosti vyschla. Stejně jsem ti řekl víc, než jsem měl. Hodně štěstí... a už se nevracej.","Det var det, ven, vidensbrønden er tørlagt. Jeg har alligevel fortalt dig mere, end jeg burde have gjort. Held og lykke... Og kom ikke tilbage.","Das war's mein Freund, der Brunnen der Weisheit ist versiegt. Ich habe dir sowieso mehr erzählt als ich sollte. Viel Glück... und komm nicht zurück.",,"Jen ĉio, amiko; la fonto de scio sekiĝis. Malgraŭ tio, mi diris al vi pli ol tiom, kiom mi devus. Ŝancon... kaj ne revenu.","Ya está, amigo; el pozo del conocimiento ya se ha secado. De todas formas ya te he dicho más de lo que debería. Suerte... y no vuelvas.","Ya está, amigo; el pozo del conocimiento ya se secó. De todas formas ya te dije más de lo que debería. Suerte... y no vuelvas.","Siinä kaikki, ystävä; tiedon lähde on ehtynyt. Olen kertonut sinulle enemmän kuin olisin edes saanutkaan. Onnea matkaan... äläkä tule takaisin.","Eh bien voilà, mon ami, le puits de la connaîssance s'est enfin asséché.. Je t'en ai dit plus que je n'aurai du, de toutes manières! Bonne chance.. Et ne reviens pas!","Ez az, barátom. A tudás kútja kiszáradt. Többször mondtam neked kelleténél amúgyis. Sok szerencsét... És ne gyere vissza.","È tutto, amico, ho esaurito le cose che avevo da dirti. Ti ho già detto più di quanto avrei dovuto. Buona fortuna... e non tornare più.","これはこれは親友、心得の瓶は切らしてるぞ。 とにかく俺が知ってる話はこれで全部だ。 -頑張りな...それともう来なくていいぞ。","친구여... 안타깝게도 지식의 우물은 이제 고갈됐다네. 내가 알려줄 수 있는 걸 다 알려줬거든. 건투를 빌겠네, 그리고 다시 돌아오지는 말고.","Dat is het vriend, de bron van kennis is uitgeput. Ik heb je meer verteld dan ik zou moeten hebben. Veel succes.... En kom niet terug.","Det var det, min venn. Kunnskapens brønn har tørket ut. Jeg har fortalt deg mer enn jeg burde uansett. Lykke til... Og ikke kom tilbake.","To wszystko kolego, studnia wiedzy wyschła. Powiedziałem ci więcej niż powinienem. Powodzenia... I nie wracaj.","Isso é tudo, camarada. O poço de conhecimento está seco. Já te contei tudo o que eu deveria, de qualquer forma. Boa sorte... E não volte mais aqui.",,"Asta a fost prietene, fântâna cunoștiințelor a secat. Ți-am spus mai multe decât ar fi trebuit oricum. Baftă... Și nu te întoarce.","Это всё, дружище. Кладезь мудрости исчерпана. Я и так рассказал тебе больше, чем следовало. Удачи... и не возвращайся.",,"Bu kadar dostum, bilgi kuyusu kurudu. Zaten sana söylemem gerekenden fazlasını söyledim. İyi şanslar. Ve sakın geri gelme." +頑張りな...それともう来なくていいぞ。","친구여... 안타깝게도 지식의 우물은 이제 고갈됐다네. 내가 알려줄 수 있는 걸 다 알려줬거든. 건투를 빌겠네, 그리고 다시 돌아오지는 말고.","Dat is het vriend, de bron van kennis is uitgeput. Ik heb je meer verteld dan ik zou moeten hebben. Veel succes.... En kom niet terug.","Det var det, min venn. Kunnskapens brønn har tørket ut. Jeg har fortalt deg mer enn jeg burde uansett. Lykke til... Og ikke kom tilbake.","To wszystko kolego, studnia wiedzy wyschła. Powiedziałem ci więcej niż powinienem. Powodzenia... I nie wracaj.","Isso é tudo, camarada. O poço de conhecimento está seco. Já te contei tudo o que eu deveria, de qualquer forma. Boa sorte... E não volte mais aqui.",,"Asta a fost prietene, fântâna cunoștiințelor a secat. Ți-am spus mai multe decât ar fi trebuit oricum. Baftă... Și nu te întoarce.","Это всё, дружище. Кладезь мудрости исчерпана. Я и так рассказал тебе больше, чем следовало. Удачи... и не возвращайся.",,"Det var det vän, kunskapsbrunnen har tagit slut. Jag har berättat mer än jag borde ha gjort i alla fall. Lycka till... Och kom inte tillbaka.","Bu kadar dostum, bilgi kuyusu kurudu. Zaten sana söylemem gerekenden fazlasını söyledim. İyi şanslar. Ve sakın geri gelme." "Hey, I'm only here in case of an emergency. If the core breaches, then I make sure no one gets in... or out.",TXT_DLG_SCRIPT02_D31836_HEYIM,MAP02: Power Station guard.,,,"Hej, já jsem tu jen pro případ nouze. Jestli se něco stane s jádrem, jsem tu, abych zajistil, že se nikdo nedostane dovnitř... ani ven.","Hey, jeg er her kun i nødstilfælde. Hvis kernen bryder sammen, så sørger jeg for, at ingen kommer ind... eller ud.","Hey, ich bin nur für den Fall eines Notfalls hier. Im Falle eines Kernbruchs sorge ich dafür das niemand rein kommt... oder raus.",,"Mi estas nur krizokaza gardisto: se la kerno rompiĝus, mi certiĝus, ke neniu eniru... aŭ eliru.","Solo estoy aquí en caso de emergencia: si el núcleo se rompe, me aseguro de que nadie entre... o salga.",,"Hei, olen täällä vain hätätilanteen varalta. Jos ytimeen tulee murtuma, tehtäväni on varmistaa, ettei kukaan pääse sisään... tai ulos.","Hé, je ne suis là qu'en cas d'urgence. Si le coeur a une brèche, il faut que je fasse en sorte que rien ne rentre.. Ou ne sorte.","Hé, én csak vészhelyzet esetére vagyok itt. Ha a mag kitör, akkor elintézem, hogy senki ne jöjjön be... vagy ki.","Ehi, io sono qua solo in caso di emergenza. Se c'è una falla nel nucleo, allora mi assicuro che nessuno possa entrare... o uscire.","おう、俺は緊急時の為にここにいる。 コアが破壊されないか、誰が入っているかを -確認している...出ていくのもな。","이봐, 난 비상사태를 대비해서 여기에 있는 거라고. 만약 중심부가 파괴되면, 그 누구도 들어올 수 없게 막을 거야... 도망치는 사람도 포함해서.","Hé, ik ben hier alleen in geval van nood. Als de kern breekt, dan zorg ik ervoor dat er niemand binnenkomt... of buitenkomt.","Hei, jeg er bare her i nødstilfeller. Hvis kjernen brister, sørger jeg for at ingen kommer inn... eller ut.","Hej, jestem tu tylko w razie wypadku. Jeśli rdzeń zostanie naruszony, wtedy upewniam się, że nikt tam nie wejdzie... lub stamtąd nie wyjdzie.","Ei, só estou aqui em caso de uma emergência. Se o núcleo se romper, preciso garantir que ninguém entre... ou saia.",,"Hei, sunt aici doar în caz de urgență. Dacă apare o breșă în nucleu, mă asigur că nimeni nu intră... sau iese.","Слушай, меня сюда поставили на всякий случай. Если целостность ядра нарушится, я позабочусь, чтобы никто не вошёл... и не вышел.",,"Hey, ben sadece acil bir durumda buradayım. Çekirdek kırılırsa, kimsenin içeri girmediğinden emin olurum... ya da dışarı." +確認している...出ていくのもな。","이봐, 난 비상사태를 대비해서 여기에 있는 거라고. 만약 중심부가 파괴되면, 그 누구도 들어올 수 없게 막을 거야... 도망치는 사람도 포함해서.","Hé, ik ben hier alleen in geval van nood. Als de kern breekt, dan zorg ik ervoor dat er niemand binnenkomt... of buitenkomt.","Hei, jeg er bare her i nødstilfeller. Hvis kjernen brister, sørger jeg for at ingen kommer inn... eller ut.","Hej, jestem tu tylko w razie wypadku. Jeśli rdzeń zostanie naruszony, wtedy upewniam się, że nikt tam nie wejdzie... lub stamtąd nie wyjdzie.","Ei, só estou aqui em caso de uma emergência. Se o núcleo se romper, preciso garantir que ninguém entre... ou saia.",,"Hei, sunt aici doar în caz de urgență. Dacă apare o breșă în nucleu, mă asigur că nimeni nu intră... sau iese.","Слушай, меня сюда поставили на всякий случай. Если целостность ядра нарушится, я позабочусь, чтобы никто не вошёл... и не вышел.",,"Jag är bara här i nödfall. Om kärnan bryter igenom, ser jag till att ingen kommer in... eller ut.","Hey, ben sadece acil bir durumda buradayım. Çekirdek kırılırsa, kimsenin içeri girmediğinden emin olurum... ya da dışarı." "Watch your step, peasant!",TXT_DLG_SCRIPT02_D33352_WATCH,MAP02: Rust guards.,,,"Dávej si na sebe pozor, poddaný! -","Pas på hvor du træder, bonde!","Pass auf wo du hintrittst, Bauer!",,"Atentu tie, kie vi piediras, kampulo!","¡Cuida por donde caminas, campesino!","¡Cuidado por donde caminas, campesino!","Katso, mihin astut, maallikko!","Regarde où tu va, paysan!","Nézz a lábad elé, paraszt!",Guarda dove metti i piedi!,気を付けろ、田舎モン!,"똑바로 보고 다녀라, 시민!","Kijk uit waar je loopt, boer!","Se deg for, bonde!",Uważaj jak leziesz kmiocie!,"Cuida por onde anda, plebeu!",,"Ai grijă pe unde calci, plebeule!","Смотри, куда прёшь, холоп!",,"Adımına dikkat et, köylü!" +","Pas på hvor du træder, bonde!","Pass auf wo du hintrittst, Bauer!",,"Atentu tie, kie vi piediras, kampulo!","¡Cuida por donde caminas, campesino!","¡Cuidado por donde caminas, campesino!","Katso, mihin astut, maallikko!","Regarde où tu va, paysan!","Nézz a lábad elé, paraszt!",Guarda dove metti i piedi!,気を付けろ、田舎モン!,"똑바로 보고 다녀라, 시민!","Kijk uit waar je loopt, boer!","Se deg for, bonde!",Uważaj jak leziesz kmiocie!,"Cuida por onde anda, plebeu!",,"Ai grijă pe unde calci, plebeule!","Смотри, куда прёшь, холоп!",,"Se upp, bonde!","Adımına dikkat et, köylü!" We're going to kill you! ,TXT_DLG_SCRIPT02_D34868_WEREG,MAP02: Gray guards.,,,Zabijeme tě!,Vi slår dig ihjel!,Wir werden dich umbringen!,,Ni mortigos vin!,"¡Vamos a matarte! -",¡Te vamos a matar!,Tapamme sinut!,On va te descendre!,Megdöglesz!,Adesso ti ammazziamo!,お前を粛正する!,우린 널 죽일거야!,We gaan je vermoorden!,Vi skal drepe deg!,Zabijemy cię!,Vamos matar você!,,O să te omorâm!,Готовься к смерти!,,Seni öldüreceğiz! +",¡Te vamos a matar!,Tapamme sinut!,On va te descendre!,Megdöglesz!,Adesso ti ammazziamo!,お前を粛正する!,우린 널 죽일거야!,We gaan je vermoorden!,Vi skal drepe deg!,Zabijemy cię!,Vamos matar você!,,O să te omorâm!,Готовься к смерти!,,Vi kommer att döda dig!,Seni öldüreceğiz! Who in the blazes are you? No one's supposed to be loitering about in this area!,TXT_DLG_SCRIPT02_D36384_WHOIN,MAP02: Green guard.,,,Kdo k čertu jsi? Tady se nikdo nemá potloukat!,Hvem i helvede er du? Ingen skal slentre rundt i dette område!,Wer zum Teufel bist du? Hier soll doch eigentlich niemand rumschnüffeln!,,Kiu diable vi estas? Neniu supozeble devas vagi ĉi tie!,¿Quién diantres eres tú? ¡Se supone que nadie tiene que estar merodeando por esta área!,¿Quién demonios eres tú? ¡Se supone que nadie tiene que estar curioseando por esta zona!,Kuka ihme sinä olet? Kenelläkään ei ole lupaa kuljeksia tällä alueella!,Qu'est ce que c'est ça? Que faites vous ici? Personne n'est sensé se trouver dans cette zone!,Te meg ki az Isten nyila vagy? Senki sem csavaroghat ebben a körzetben.,E tu chi diavolo saresti? Nessuno dovrebbe aggirarsi in quest'area!,"誰だお前は?この区域を立ち入ることは 許されていないぞ! -",너는 누구지? 아무도 이 지역에서 어슬렁거릴 수 없다!,Wie ben jij in vredesnaam? Niemand wordt verondersteld op dit gebied rond te hangen!,Hvem i all verden er du? Ingen har lov til å drive rundt i dette området!,Kim u diaska jesteś? Nikt nie powinien się tu włóczyć!,Mas quem é você? Não pode ficar perambulando por aqui!,,Cine naiba mai ești tu? Nimeni nu ar trebui să zăbovească în zona asta!,"Кто ты, чёрт побери, такой? Никому не разрешено тут шляться!",,Sen de kimsin be? Kimsenin bu bölgede dolaşmaması gerekiyor! -"You there, nobody's allowed in here. Move along!",TXT_DLG_SCRIPT02_D37900_YOUTH,MAP02: Golden guards.,,,"Hej ty, sem nikdo nesmí. Jdi dál!","Du der, ingen må komme ind her. Af sted med jer!","Hey, du da. Hier darfst du nicht rein. Geh weiter!",,"He, neniu rajtas esti ĉi tie. Plue movu vin!","Oye, este lugar está restringido. ¡Sigue moviéndote!",,"Sinä siellä, tämä on kielletty alue. Tiehesi!","Vous, là, personne n'est autorisé à traîner ici, dégagez!","Te ott, ide senki sem jöhet be, kotródj!","Ehi, tu! A nessuno è permesso di stare qua. Vai via!",お前は許可していないぞ。立ち去れ!,"거기 너, 아무도 이곳에 지나갈 수 없다. 가던 길이나 가!","Jij daar, niemand mag hier naar binnen. Ga verder!","Du der, ingen har lov til å være her. Gå videre!","Ty tutaj, nikt nie ma prawa tu przebywać. Wynocha!","Ei, você, não pode ficar aqui. Vá embora!",,"Tu, nimeni nu are voie aici. Mișcă-te!","Эй, ты! Никому не позволено тут ошиваться. Проваливай!",,"Sen oradaki, kimsenin buraya girmesine izin yok. İlerleyin!" -Irale will set you right up!,TXT_DLG_SCRIPT02_D39416_IRALE,MAP02: Irale's shop.,,,Irale tě hned vyzbrojí!,Irale vil sætte dig på plads!,Irale wird sich darum kümmern!,,"Irale vendos al vi ĉion, kion vi bezonas!",¡Irale te venderá lo necesario!,¡Irale te va a vender lo necesario!,Irale järkkää sinulle varusteet!,Irale a ce qu'il te faut!,Irale majd ellát.,Irale ti darà quello che ti serve!,イラールが貴方を手助けします!,여기 이롤리가 중요한 물품을 판매할 거야.,Irale zal je er goed in luizen!,Irale skal ordne opp for deg!,Irale dobrze cię przygotuje!,O Irale vai te ajudar!,,Irale te va pregăti adecvat!,Ирэйл снабдит тебя всем необходимым!,,İrale seni hemen ayarlayacak! -I'm kinda a talent broker for the rebels. A guy who's as good as you could make a lot of gold... if you hooked up with the right people.,TXT_DLG_SCRIPT02_D40932_IMKIN,MAP02: Harris.,,,Jsem takový hledač talentů pro rebely. Někdo tak dobrý jako ty by si mohl vydělat hodně zlata... pokud by se spojil s těmi správnými lidmi.,"Jeg er en slags talentmægler for oprørerne. En fyr, der er lige så god som dig, kan tjene en masse guld ... hvis du kommer i kontakt med de rigtige folk.","Ich bin sowas wie ein Talentsucher für die Rebellen. Jemand, der so gut ist wie du kann hier eine Menge Gold verdienen... wenn du mit den richtigen Leuten in Verbindung stehst.",,"Mi estas speco de talentul-serĉanto por la ribelantoj. Iu tiel lerta, kiel vi povus gajni multe da oro… se vi ligas vin kun la ĝustaj homoj.",Soy algo así como un buscador de talento para los rebeldes. Alguien tan bueno como tú podría ganar mucho oro... Si te juntas con las personas adecuadas.,,Olen eräänlainen kykyjenvälittäjä kapinallisille. Kaltaisesi kaveri voisi tienata paljon kultaa... oikeiden kumppaneiden kanssa.,"Je suis une sorte de chasseur de têtes pour les rebelles. Un type comme toi pourrait se faire pas mal de fric... Avec les bons contacts, bien entendu.","Egyfajta toborzó vagyok a lázadóknál. Egy ürge aki ilyen jó mint te, elég sok aranyat kereshet...ha megfelelő emberekkel jösz össze.",Sono sempre alla ricerca di persone talentuose per i ribelli. Una persona come te potrebbe ricevere molto oro... se fosse in contatto con le persone giuste.,"俺は反乱者への斡旋屋さ。才能を生かして +",너는 누구지? 아무도 이 지역에서 어슬렁거릴 수 없다!,Wie ben jij in vredesnaam? Niemand wordt verondersteld op dit gebied rond te hangen!,Hvem i all verden er du? Ingen har lov til å drive rundt i dette området!,Kim u diaska jesteś? Nikt nie powinien się tu włóczyć!,Mas quem é você? Não pode ficar perambulando por aqui!,,Cine naiba mai ești tu? Nimeni nu ar trebui să zăbovească în zona asta!,"Кто ты, чёрт побери, такой? Никому не разрешено тут шляться!",,Vem i helvete är du? Det är inte meningen att någon ska gå omkring i det här området!,Sen de kimsin be? Kimsenin bu bölgede dolaşmaması gerekiyor! +"You there, nobody's allowed in here. Move along!",TXT_DLG_SCRIPT02_D37900_YOUTH,MAP02: Golden guards.,,,"Hej ty, sem nikdo nesmí. Jdi dál!","Du der, ingen må komme ind her. Af sted med jer!","Hey, du da. Hier darfst du nicht rein. Geh weiter!",,"He, neniu rajtas esti ĉi tie. Plue movu vin!","Oye, este lugar está restringido. ¡Sigue moviéndote!",,"Sinä siellä, tämä on kielletty alue. Tiehesi!","Vous, là, personne n'est autorisé à traîner ici, dégagez!","Te ott, ide senki sem jöhet be, kotródj!","Ehi, tu! A nessuno è permesso di stare qua. Vai via!",お前は許可していないぞ。立ち去れ!,"거기 너, 아무도 이곳에 지나갈 수 없다. 가던 길이나 가!","Jij daar, niemand mag hier naar binnen. Ga verder!","Du der, ingen har lov til å være her. Gå videre!","Ty tutaj, nikt nie ma prawa tu przebywać. Wynocha!","Ei, você, não pode ficar aqui. Vá embora!",,"Tu, nimeni nu are voie aici. Mișcă-te!","Эй, ты! Никому не позволено тут ошиваться. Проваливай!",,"Du där, ingen får komma in här. Flytta på er!","Sen oradaki, kimsenin buraya girmesine izin yok. İlerleyin!" +Irale will set you right up!,TXT_DLG_SCRIPT02_D39416_IRALE,MAP02: Irale's shop.,,,Irale tě hned vyzbrojí!,Irale vil sætte dig på plads!,Irale wird sich darum kümmern!,,"Irale vendos al vi ĉion, kion vi bezonas!",¡Irale te venderá lo necesario!,¡Irale te va a vender lo necesario!,Irale järkkää sinulle varusteet!,Irale a ce qu'il te faut!,Irale majd ellát.,Irale ti darà quello che ti serve!,イラールが貴方を手助けします!,여기 이롤리가 중요한 물품을 판매할 거야.,Irale zal je er goed in luizen!,Irale skal ordne opp for deg!,Irale dobrze cię przygotuje!,O Irale vai te ajudar!,,Irale te va pregăti adecvat!,Ирэйл снабдит тебя всем необходимым!,,Irale kommer att sätta dig på plats!,İrale seni hemen ayarlayacak! +I'm kinda a talent broker for the rebels. A guy who's as good as you could make a lot of gold... if you hooked up with the right people.,TXT_DLG_SCRIPT02_D40932_IMKIN,MAP02: Harris.,,,Jsem takový hledač talentů pro rebely. Někdo tak dobrý jako ty by si mohl vydělat hodně zlata... pokud by se spojil s těmi správnými lidmi.,"Jeg er en slags talentmægler for oprørerne. En fyr, der er lige så god som dig, kan tjene en masse guld ... hvis du kommer i kontakt med de rigtige folk.","Ich bin sowas wie ein Talentsucher für die Rebellen. Jemand, der so gut ist wie du kann hier eine Menge Gold verdienen... wenn du mit den richtigen Leuten in Verbindung stehst.",,"Mi estas speco de talentul-serĉanto por la ribelantoj. Iu tiel lerta, kiel vi povus gajni multe da oro… se vi ligas vin kun la ĝustaj homoj.",Soy algo así como un cazatalentos para los rebeldes. Alguien tan bueno como tú podría ganar mucho oro... Si te juntas con las personas adecuadas.,,Olen eräänlainen kykyjenvälittäjä kapinallisille. Kaltaisesi kaveri voisi tienata paljon kultaa... oikeiden kumppaneiden kanssa.,"Je suis une sorte de chasseur de têtes pour les rebelles. Un type comme toi pourrait se faire pas mal de fric... Avec les bons contacts, bien entendu.","Egyfajta toborzó vagyok a lázadóknál. Egy ürge aki ilyen jó mint te, elég sok aranyat kereshet...ha megfelelő emberekkel jösz össze.",Sono sempre alla ricerca di persone talentuose per i ribelli. Una persona come te potrebbe ricevere molto oro... se fosse in contatto con le persone giuste.,"俺は反乱者への斡旋屋さ。才能を生かして 誰よりも儲けたいと思ってるなら... 相応しい人と関係を持つことさ。 -",난 반란군을 위한 일종의 재능 중개인이야. 당신만큼 좋은 사람이라면 많은 돈을 벌 수 있겠지... 당신이 제대로 된 사람들과 연결되어 있다면.,Ik ben een soort van een talent makelaar voor de rebellen. Een man die zo goed is als je zou kunnen maken veel goud .... als je aangesloten met de juiste mensen.,Jeg er en slags talentmegler for opprørerne. En fyr som er så god som deg kan tjene mye gull... hvis du kommer i kontakt med de rette folkene.,Jestem tak jakby pośrednikiem rebeliantów. Człowiek tak dobry jak ty może zarobić dużo pieniędzy... jeśli trzymasz z właściwymi ludźmi.,Sou tipo um olheiro de talentos para rebeldes. Um cara tão bom quanto você poderia fazer bastante grana... se você se juntar às pessoas certas.,,Sunt un fel de broker de talent pentru rebeli. Un tip la fel de priceput precum ești tu ar putea face bani frumoși... dacă s-ar lega de cine trebuie.,"Я, скажем так, вербовщик повстанцев. Такой парень, как ты, может неплохо заработать... если состыкуется с нужными людьми.",,Ben asiler için yetenek simsarı sayılırım. Senin kadar iyi bir adam çok altın kazanabilir... eğer doğru insanlarla bağlantı kurarsan. -I'm interested.,TXT_RPLY0_SCRIPT02_D40932_IMINT,〃,,,Mám zájem.,Jeg er interesseret.,Ich bin interessiert.,,Tio interesas min.,Me interesa.,,Olen kiinnostunut.,Je suis intéressé.,Érdekel.,Sono interessato.,興味ある。,흥미롭군.,Ik ben geïnteresseerd.,Jeg er interessert.,Jestem zainteresowany.,Tenho interesse.,,Sunt interesat.,Я заинтригован.,,İlgileniyorum. -Screw the rebels!,TXT_RPLY1_SCRIPT02_D40932_SCREW,〃,,,Kašlu na rebely!,Skide være med rebellerne!,Scheiß auf die Rebellen!,,Fi al la ribelantoj!,¡Al demonio los rebeldes!,,Paskat kapinallisista!,Je m'en fous des rebelles!,Francba a lázadókkal!,Fanculo i ribelli!,何が反逆だ!,반란군은 집어치워!,De pot op met de rebellen!,Til helvete med opprørerne!,Pieprzyć rebeliantów!,Que se danem os rebeldes!,,La naiba cu rebelii!,К чёрту повстанцев!,,Asilerin canı cehenneme! +",난 반란군을 위한 일종의 재능 중개인이야. 당신만큼 좋은 사람이라면 많은 돈을 벌 수 있겠지... 당신이 제대로 된 사람들과 연결되어 있다면.,Ik ben een soort van een talent makelaar voor de rebellen. Een man die zo goed is als je zou kunnen maken veel goud .... als je aangesloten met de juiste mensen.,Jeg er en slags talentmegler for opprørerne. En fyr som er så god som deg kan tjene mye gull... hvis du kommer i kontakt med de rette folkene.,Jestem tak jakby pośrednikiem rebeliantów. Człowiek tak dobry jak ty może zarobić dużo pieniędzy... jeśli trzymasz z właściwymi ludźmi.,Sou tipo um olheiro de talentos para rebeldes. Um cara tão bom quanto você poderia fazer bastante grana... se você se juntar às pessoas certas.,,Sunt un fel de broker de talent pentru rebeli. Un tip la fel de priceput precum ești tu ar putea face bani frumoși... dacă s-ar lega de cine trebuie.,"Я, скажем так, вербовщик повстанцев. Такой парень, как ты, может неплохо заработать... если состыкуется с нужными людьми.",,Jag är en slags talangmäklare för rebellerna. En kille som är lika bra som du kan tjäna en massa guld... om du kopplar ihop dig med rätt personer.,Ben asiler için yetenek simsarı sayılırım. Senin kadar iyi bir adam çok altın kazanabilir... eğer doğru insanlarla bağlantı kurarsan. +I'm interested.,TXT_RPLY0_SCRIPT02_D40932_IMINT,〃,,,Mám zájem.,Jeg er interesseret.,Ich bin interessiert.,,Tio interesas min.,Me interesa.,,Olen kiinnostunut.,Je suis intéressé.,Érdekel.,Sono interessato.,興味ある。,흥미롭군.,Ik ben geïnteresseerd.,Jeg er interessert.,Jestem zainteresowany.,Tenho interesse.,,Sunt interesat.,Я заинтригован.,,Jag är intresserad.,İlgileniyorum. +Screw the rebels!,TXT_RPLY1_SCRIPT02_D40932_SCREW,〃,,,Kašlu na rebely!,Skide være med rebellerne!,Scheiß auf die Rebellen!,,Fi al la ribelantoj!,¡Al demonio los rebeldes!,,Paskat kapinallisista!,Je m'en fous des rebelles!,Francba a lázadókkal!,Fanculo i ribelli!,何が反逆だ!,반란군은 집어치워!,De pot op met de rebellen!,Til helvete med opprørerne!,Pieprzyć rebeliantów!,Que se danem os rebeldes!,,La naiba cu rebelii!,К чёрту повстанцев!,,Skit i rebellerna!,Asilerin canı cehenneme! "No, no second chance. Oh guards, kill him.",TXT_DLG_SCRIPT02_D42448_NONOS,〃,,,"Druhou šanci už nedostaneš. Á, stráže, zabte ho.","Nej, ingen ny chance. Åh vagter, dræb ham.","Nein, keine zweite Chance. Oh, Wachen, tötet ihn.",,"Ne, ne estas alia ŝanco. Gardistoj, mortigu lin!","No, no hay otra oportunidad. ¡Guardias, matadlo!","No, no hay otra oportunidad. ¡Guardias, mátenlo!","Ei, ei toista mahdollisuutta. Vartijat, tappakaa hänet.","Non, non, pas de deuxième chance. Gardes, tuez-le.","Nem, nincs második esély. Őrök, intézzétek el!","Nessuna seconda chance. Guardie, uccidetelo.","次はねえな。おぅガードの旦那、 -やっちゃってくだせえ。","안 돼, 두 번째 기회는 없어. 경비원, 저놈을 죽여.","Nee, geen tweede kans. Oh bewakers, dood hem.","Nei, ingen ny sjanse. Vakter, drep ham.","Nie, nie będzie drugiej szansy. Oh... strażnicy, zabijcie go.","Não, sem segundas chances. Ah, guardas, matem ele.",,"Nu, nici o altă șansă. Oh gardienilor, omorâți-l.","Нет, никакого второго шанса. Эй, стража, убейте его.",,"Hayır, ikinci bir şans yok. Muhafızlar, öldürün onu." +やっちゃってくだせえ。","안 돼, 두 번째 기회는 없어. 경비원, 저놈을 죽여.","Nee, geen tweede kans. Oh bewakers, dood hem.","Nei, ingen ny sjanse. Vakter, drep ham.","Nie, nie będzie drugiej szansy. Oh... strażnicy, zabijcie go.","Não, sem segundas chances. Ah, guardas, matem ele.",,"Nu, nici o altă șansă. Oh gardienilor, omorâți-l.","Нет, никакого второго шанса. Эй, стража, убейте его.",,"Nej, ingen andra chans. Åh vakter, döda honom.","Hayır, ikinci bir şans yok. Muhafızlar, öldürün onu." Good choice. The Order's sanctuary by the river is their unofficial torture chamber. Hidden inside there's a golden chalice. You swipe it and reap your reward.,TXT_DLG_SCRIPT02_D43964_GOODC,〃,,,Dobrá volba. Svatyně Řádu u řeky je jejich tajná mučírna. Uvnitř je skrytý zlatý kalich. Ukradni ho a převezmi si svou odměnu.,Godt valg. Ordenens fristed ved floden er deres uofficielle torturkammer. Der er en gylden bæger gemt derinde. Du tager den og høster din belønning.,Gute Wahl. Das Heiligtum des Ordens bei dem Fluss ist ihre inoffiziele Folterkammer. Darin versteckt ist ein goldener Kelch. Du klaust ihn und erntest deinen Lohn.,,Bona elekto. La sanktejo de La Ordono ĉe la rivero estas ĝia neoficiala torturejo. En ĝi estas kaŝita ora kaliko. Alportu ĝin al mi kaj vi havos rekompencon.,Buena elección. El santuario de La Orden junto al río es su cámara de tortura extraoficial. Dentro hay un cáliz dorado escondido. Tráemelo y tendrás tu recompensa.,"Buena elección. El santuario de La Orden junto al río es su cámara de tortura extraoficial. Adentro hay un cáliz dorado escondido. Si me lo traes, tu recompensa.","Viisas päätös. Veljeskunnan pyhäkkö joen varrella on heidän epävirallinen kidutuskammionsa, jonka kätköissä piilee kultakalkki. Kähvellä se ja saat vaivannäöstäsi palkan.",Bon choix. Le sanctuaire de l'ordre près de la rivière est leur chambre torture.. officieusement. A l'intérieur se trouve un calice en or. Récupérez le et venez prendre votre récompense.,"Jó választás. A Rend Szentélye a folyónál a nem hivatalos kínzókamrájuk. Odabent elrejtve található egy arany kehely. Elcsened, és learatod a dicsőséged.",Ottima scelta. Il santuario dell'Ordine vicino al fiume è la loro camera della tortura. Vi è un calice d'oro nascosto là dentro. Prendilo e avrai una lauta ricompensa.,"良い判断だ。川沿いにあるオーダーの聖域は あいつらの非公式の拷問室だ。中には黄金の 聖杯が隠してある。そいつを持ってくれば 報酬をやるぜ。 -",좋은 선택이야. 강가 근처에 있는 성소가 바로 오더의 비공식적인 고문실이야. 그리고 그 안에는 숨겨진 금색 성배가 있지. 넌 그것을 훔치고 보상을 받으면 돼.,Goede keuze. Het heiligdom van de Orde bij de rivier is hun onofficiële martelkamer. Verborgen in de kelk zit een gouden kelk. Je haalt hem weg en plukt je beloning.,Godt valg. Ordenens helligdom ved elven er deres uoffisielle torturkammer. Gjemt der inne er det et gyllent beger. Ta det og høste belønningen din.,Dobry wybór. Sanktuarium Zakonu nad rzeką to ich nieoficjalna sala tortur. Jest w niej ukryty złoty kielich. Zwijasz go i dostajesz swoją nagrodę.,Boa escolha. O santuário da Ordem perto do rio é a câmara de tortura não-oficial deles. Há um cálice dourado escondido dentro. Pegue-o e você recebe a sua recompensa.,,Bună alegere. Sanctuarul Ordinului de lângă râu e camera lor de tortură neoficială. Ascuns în interior e un potir auriu. Îl înhați și culegi recompensa.,Правильный выбор. В святилище Ордена у реки — там у них негласная камера пыток — спрятана золотая чаша. Ты крадёшь её и получаешь свою награду.,,İyi seçim. Tarikat'ın nehir kenarındaki sığınağı onların gayri resmi işkence odası. İçinde altın bir kadeh saklı. Onu araklarsın ve ödülünü alırsın. -How am I supposed to do that?,TXT_RPLY0_SCRIPT02_D43964_HOWAM,〃,,,Jak to mám udělat?,Hvordan skal jeg gøre det?,Wie soll ich das anstellen?,,Kiel mi faru tion?,¿Cómo se supone que debo hacer eso?,,Miten ihmeessä minä sen teen?,Comment est-ce que je suis sensé faire ça?,Mégis hogy kéne hozzálássak ehhez?,E come posso fare tutto ciò?,どうすればいい?,내가 그걸 어떻게 하지?,Hoe moet ik dat doen?,Hvordan skal jeg gjøre det?,Jak powinienem to zrobić?,E como eu vou fazer isso?,,Și cum ar trebui să fac asta?,И как я это сделаю?,,Bunu nasıl yapacağım? -"Here's a crossbow, just aim straight and --splat--. Remember, grab the fancy cup and get to the tavern.",TXT_DLG_SCRIPT02_D45480_HERES,〃,,,"Tady máš kuši, prostě zamiř rovně a --plesk--. Ještě jednou: popadni fešný hrnek a přijď do taverny.","Her er en armbrøst, bare sigt lige ud og -splat--. Husk, tag det fine bæger og gå til tavernaen.","Hier ist eine Armbust, einfach gerade zielen und --Platsch--. Denk dran, schnapp dir den schicken Kelch und dann ab zur Taverne.",,Jen arbalesto. Vi nur celu laŭ rekta linio kaj «gut». Ne forgesu preni la belan pokalon kaj tiam reveni al la taverno.,Aquí tengo una ballesta. Solo apunta en línea recta y «ploc». Recuerda: toma la bonita copa y luego vuelve aquí a la taberna.,,"Tässä sinulle jousipyssy; tähtää vain eteenpäin ja ""pläts""! Tärkeintä vain, että muistat kahmaista fiinin maljan ja sitten palata kapakkaan.",Voilà une arbalète. Vous avez juste à viser droit et paf! Souvenez-vous. Prenez le goblet et ramenez le à la taverne.,"Itt a számszeríj. Csak célozz előre és -placcs- . Vésd az eszedbe, fogd a pofás kis csészét és menj a fogadóba!","Ecco una balestra, basta mirare e --splat--. Ricorda, prendi il calice e ritorna alla taverna.","このクロスボウを使いな、狙いを定めて +",좋은 선택이야. 강가 근처에 있는 성소가 바로 오더의 비공식적인 고문실이야. 그리고 그 안에는 숨겨진 금색 성배가 있지. 넌 그것을 훔치고 보상을 받으면 돼.,Goede keuze. Het heiligdom van de Orde bij de rivier is hun onofficiële martelkamer. Verborgen in de kelk zit een gouden kelk. Je haalt hem weg en plukt je beloning.,Godt valg. Ordenens helligdom ved elven er deres uoffisielle torturkammer. Gjemt der inne er det et gyllent beger. Ta det og høste belønningen din.,Dobry wybór. Sanktuarium Zakonu nad rzeką to ich nieoficjalna sala tortur. Jest w niej ukryty złoty kielich. Zwijasz go i dostajesz swoją nagrodę.,Boa escolha. O santuário da Ordem perto do rio é a câmara de tortura não-oficial deles. Há um cálice dourado escondido dentro. Pegue-o e você recebe a sua recompensa.,,Bună alegere. Sanctuarul Ordinului de lângă râu e camera lor de tortură neoficială. Ascuns în interior e un potir auriu. Îl înhați și culegi recompensa.,Правильный выбор. В святилище Ордена у реки — там у них негласная камера пыток — спрятана золотая чаша. Ты крадёшь её и получаешь свою награду.,,Bra val. Ordens helgedom vid floden är deras inofficiella tortyrkammare. Gömd inuti finns en gyllene kalk. Du tar den och skördar din belöning.,İyi seçim. Tarikat'ın nehir kenarındaki sığınağı onların gayri resmi işkence odası. İçinde altın bir kadeh saklı. Onu araklarsın ve ödülünü alırsın. +How am I supposed to do that?,TXT_RPLY0_SCRIPT02_D43964_HOWAM,〃,,,Jak to mám udělat?,Hvordan skal jeg gøre det?,Wie soll ich das anstellen?,,Kiel mi faru tion?,¿Cómo se supone que debo hacer eso?,,Miten ihmeessä minä sen teen?,Comment est-ce que je suis sensé faire ça?,Mégis hogy kéne hozzálássak ehhez?,E come posso fare tutto ciò?,どうすればいい?,내가 그걸 어떻게 하지?,Hoe moet ik dat doen?,Hvordan skal jeg gjøre det?,Jak powinienem to zrobić?,E como eu vou fazer isso?,,Și cum ar trebui să fac asta?,И как я это сделаю?,,Hur ska jag göra det?,Bunu nasıl yapacağım? +"Here's a crossbow, just aim straight and --splat--. Remember, grab the fancy cup and get to the tavern.",TXT_DLG_SCRIPT02_D45480_HERES,〃,,,"Tady máš kuši, prostě zamiř rovně a --plesk--. Ještě jednou: popadni fešný hrnek a přijď do taverny.","Her er en armbrøst, bare sigt lige ud og -splat--. Husk, tag det fine bæger og gå til tavernaen.","Hier ist eine Armbust, einfach gerade zielen und --Platsch--. Denk dran, schnapp dir den schicken Kelch und dann ab zur Taverne.",,Jen arbalesto. Vi nur celu laŭ rekta linio kaj «gut». Ne forgesu preni la belan pokalon kaj tiam reveni al la taverno.,Aquí tengo una ballesta. Solo apunta en línea recta y «plaf». Recuerda: toma la bonita copa y luego vuelve aquí a la taberna.,,"Tässä sinulle jousipyssy; tähtää vain eteenpäin ja ""pläts""! Tärkeintä vain, että muistat kahmaista fiinin maljan ja sitten palata kapakkaan.",Voilà une arbalète. Vous avez juste à viser droit et paf! Souvenez-vous. Prenez le goblet et ramenez le à la taverne.,"Itt a számszeríj. Csak célozz előre és -placcs- . Vésd az eszedbe, fogd a pofás kis csészét és menj a fogadóba!","Ecco una balestra, basta mirare e --splat--. Ricorda, prendi il calice e ritorna alla taverna.","このクロスボウを使いな、狙いを定めて --シュッとな。覚えておけ、 -ファンシーなカップを持ってここに戻ってこい。","여기 석궁이야, 똑바로 겨냥해, 그리고... '철퍼덕'. 기억해, 멋진 컵을 들고 선술집에 와.","Hier is een kruisboog, mik gewoon recht en --splat--. Vergeet niet, pak de mooie beker en ga naar de herberg.","Her er en armbrøst, bare sikt rett og --splat--. Husk å ta det fine begeret og gå til vertshuset.","Oto kusza, tylko wyceluj i --plask--. Pamiętaj, weź ozdobny puchar i wróć do tawerny.","Aqui está uma besta. Só mirar reto e --splat--. Lembre-se, pegue o copo bonito e vá pra taverna.",,"Uite o arbaletă, doar țintești drept și --pleoșc--. Ține minte, ia cana scumpă și du-te la tavernă.",Вот арбалет — просто прицеливаешься и «шлёп!» Запомни — хватаешь чашку и возвращаешься в таверну.,,"İşte bir arbalet, sadece düz nişan al ve --splat--. Unutma, süslü kupayı al ve tavernaya git." +ファンシーなカップを持ってここに戻ってこい。","여기 석궁이야, 똑바로 겨냥해, 그리고... '철퍼덕'. 기억해, 멋진 컵을 들고 선술집에 와.","Hier is een kruisboog, mik gewoon recht en --splat--. Vergeet niet, pak de mooie beker en ga naar de herberg.","Her er en armbrøst, bare sikt rett og --splat--. Husk å ta det fine begeret og gå til vertshuset.","Oto kusza, tylko wyceluj i --plask--. Pamiętaj, weź ozdobny puchar i wróć do tawerny.","Aqui está uma besta. Só mirar reto e --splat--. Lembre-se, pegue o copo bonito e vá pra taverna.",,"Uite o arbaletă, doar țintești drept și --pleoșc--. Ține minte, ia cana scumpă și du-te la tavernă.",Вот арбалет — просто прицеливаешься и «шлёп!» Запомни — хватаешь чашку и возвращаешься в таверну.,,"Här är ett armborst, sikta bara rakt och --splat--. Kom ihåg att ta den fina bägaren och gå till tavernan.","İşte bir arbalet, sadece düz nişan al ve --splat--. Unutma, süslü kupayı al ve tavernaya git." Cool. I'll get it.,TXT_RPLY0_SCRIPT02_D45480_COOLI,〃,,,"Fajn, přinesu ho.",Det er fedt. Jeg henter den.,Cool. Ich werde ihn holen.,,Bonege. Mi trovos ĝin.,Genial. Ya lo traigo.,,Selvä. Saan sen.,Ok. Je m'en occupe.,Király. Meglesz majd.,Va bene. Vado a prenderlo.,良い物だ、貰っとく。,"멋지군, 이해 했어.",Cool. Ik zal het krijgen.,Kult. Jeg henter den.,Fajnie. Wchodzę w to.,Beleza. Vou lá pegar.,,Tare. O voi lua.,"Класс. Я достану её. -",,Güzel. Ben alırım. -What are you waiting for? Bring me that chalice.,TXT_DLG_SCRIPT02_D46996_WHATA,〃,,,Na co čekáš? Přines mi ten kalich.,Hvad venter du på? Giv mig det bæger.,Worauf wartest du noch? Bring mir den Kelch.,,Kion vi atendas? Alportu tiun kalikon.,¿A qué estás esperando? Tráeme ese cáliz.,¿Qué estás esperando? Tráeme ese cáliz.,Mitä oikein jahkailet? Tuo minulle se kalkki.,Qu'attendez vous? Récupérez-moi ce calice.,Mire vársz? Hozd ide azt a kelyhet.,Cosa stai aspettando? Portami il calice.,何ボーっとしてんだ?とっとと聖杯を持ってこい。,뭘 기다리는 거야? 가서 성배를 찾아.,Waar wacht je nog op? Breng me die kelk.,Hva venter du på? Gi meg det begeret.,Na co czekasz? Przynieś mi ten kielich.,Está esperando o quê? Me traga o cálice.,,Ce mai aștepți? Adu-mi potirul acela.,Чего ты ждёшь? Принеси мне эту чашу.,,Ne bekliyorsun? Bana o kadehi getir. +",,Coolt. Jag hämtar den.,Güzel. Ben alırım. +What are you waiting for? Bring me that chalice.,TXT_DLG_SCRIPT02_D46996_WHATA,〃,,,Na co čekáš? Přines mi ten kalich.,Hvad venter du på? Giv mig det bæger.,Worauf wartest du noch? Bring mir den Kelch.,,Kion vi atendas? Alportu tiun kalikon.,¿A qué estás esperando? Tráeme ese cáliz.,¿Qué estás esperando? Tráeme ese cáliz.,Mitä oikein jahkailet? Tuo minulle se kalkki.,Qu'attendez vous? Récupérez-moi ce calice.,Mire vársz? Hozd ide azt a kelyhet.,Cosa stai aspettando? Portami il calice.,何ボーっとしてんだ?とっとと聖杯を持ってこい。,뭘 기다리는 거야? 가서 성배를 찾아.,Waar wacht je nog op? Breng me die kelk.,Hva venter du på? Gi meg det begeret.,Na co czekasz? Przynieś mi ten kielich.,Está esperando o quê? Me traga o cálice.,,Ce mai aștepți? Adu-mi potirul acela.,Чего ты ждёшь? Принеси мне эту чашу.,,Vad väntar du på? Ge mig den där bägaren.,Ne bekliyorsun? Bana o kadehi getir. "Hey, I know, kinda looks like a set-up. I would never do that to such a great killing machine. Got the item? Great! Now get ready, gold and glory just like I promised. Take this key and the Governor will reward you.",TXT_DLG_SCRIPT02_D48512_HEYIK,〃,,,"Hej, já vím, že tohle vypadá jako bouda. Takovému zabijákovi jako ty bych nikdy nic takového neudělal! Máš ten kalich? Fajn! Tak teď se připrav, zlato a sláva, jak jsem slíbil. Vem si tenhle klíč a samotný guvernér tě odmění.","Jeg ved det godt, det ligner en fælde. Jeg ville aldrig gøre det mod sådan en stor dræbermaskine. Har du genstanden? Fedt! Gør dig nu klar, guld og ære, som jeg lovede. Tag denne nøgle, og guvernøren vil belønne dig.","Hey, ich weiß, es sieht anscheinend wie eine Falle aus, aber so etwas würde ich einer so großeartigen Tötungsmaschine nicht antun. Hast du ddas Ding? Großartig! Nun mach dich bereit, Geld und Ruhm, genau wie ich es dir versprochen habe. Nimm diesen Schlüssel und der Gouverneur wird dich belohnen.",,"Jes, mi scias, ĉi tio ŝajnas trompo, sed mi neniam farus tion al bonega mortig-maŝino. Ĉu vi havas la kalikon? Bonege! Pretiĝu: oro kaj gloro, tiel, kiel mi promesis. Prenu ĉi tiun ŝlosilon kaj la registo rekompencos vin.","Sí, ya lo sé, esto parece un timo, pero nunca le haría eso a una gran máquina de matar. ¿Tienes el cáliz? ¡Genial! Ahora prepárate: oro y gloria, tal y como he prometido. Toma esta llave y el gobernador te recompensará.","Sí, ya lo sé, esto parece una estafa, pero nunca le haría eso a una gran máquina de matar. ¿Tienes el cáliz? ¡Genial! Ahora prepárate: oro y gloria, tal y como prometí. Toma esta llave y el gobernador te va a recompensar.","Joo joo, tiedän, että on vähän väijytyksen makua. En kuitenkaan ikinä tekisi sellaista niin kovalle tappokoneelle. Saitko tavaran? Loistavaa! No niin, valmistaudu kultaan ja kunniaan, juuri niin kuin lupasinkin. Ota tämä avain ja kuvernööri palkitsee sinut.","Hé, je sais que ça à l'air d'être un coup monté, mais je ne ferais jamais ça à une aussi bonne machine à tuer. Vous avez le butin? Excellent! Préparez vous, l'or et la gloire vous attend, comme promis. Prenez cette clé et le gouverneur vous récompensera.","Tudom, hogy olyan szaga van mint egy csapdának. Sosem tennék ilyet egy ilyen kiváló gyilkológéppel. Megvan a cuccos? Zsír! Most készülj fel, arany és hírnév, mint ahogy ígértem. Vidd ezt a kulcsot és a kormányzó megjutalmaz.","Ehi, so che può sembrare una trappola. Ma io non tradirei mai a un killer abile come te. Hai il calice? Benissimo! Ora preparati, oro e gloria ti aspettano come promesso. Prendi questa chiave e il Governatore in persona ti ricompenserà.","おう、罠みたいだと思ったか。 俺に暴れん坊みたいな芸当出来るわきゃねえ。 ブツはあるか?そりゃいい!じゃあ準備しな。 金と栄光は約束された。この鍵で知事に合えば 報酬をありったけくれるさ。 -","이봐, 알겠어. 확실히 뭔가 꾸며 놓은 것 같다는 거. 난 훌륭한 학살 기계에게 그런 짓을 할 사람이 아니야. 그래서 그걸 가져왔나? 좋아! 그럼 약속한 대로 골드와 영광을 줄 테니 준비해. 이 열쇠를 총독에게 가져다주면 보상해 줄 거야.","Hé, ik weet het, het ziet er een beetje uit als een valstrik. Dat zou ik nooit met zo'n grote moordmachine doen. Heb je het item? Geweldig! Maak je nu klaar, goud en glorie, net zoals ik beloofd heb. Neem deze sleutel en de gouverneur zal je belonen.","Jeg vet at det ser ut som en felle. Jeg ville aldri gjort det mot en så flott drapsmaskin. Har du gjenstanden? Flott! Gjør deg klar. Gull og ære, som jeg lovte. Ta denne nøkkelen, så vil guvernøren belønne deg.","Hej, wiem, wygląda to jak zasadzka. Nigdy bym czegoś takiego nie zrobił wspaniałej maszynie do zabijania. Masz przedmiot? Wspaniale! Przygotuj się teraz, złoto i chwała tak jak obiecywałem. Weź ten klucz, a Gubernator cię nagrodzi.","Olha, eu sei, meio que parece uma cilada. Eu nunca faria aquilo a uma grande máquina mortífera. Conseguiu o item? Ótimo! Agora se prepare, ouro e glória conforme prometido. Pegue esta chave e o Governador irá te recompensar.",,"Hei, știu că pare o capcană. Nu aș face așa ceva niciodată unei mașini ucigașe atât de tare. Ai obiectul? Perfect! Acum pregătește-te, aur și glorie cum ți-am promis. Ia cheia asta și Guvernatorul te va răsplătii.","Слушай, я знаю, о чём ты думаешь. Ты думаешь, что это подстава. Но я бы никогда не сделал этого с такой машиной для убийств, как ты. Достал то, что я просил? Отлично! Тебя ждёт золото и слава, как я и обещал. Возьми этот ключ — губернатор лично наградит тебя.",,"Hey, biliyorum, biraz tuzağa benziyor. Böyle büyük bir ölüm makinesine bunu asla yapmazdım. Eşyayı aldın mı? Harika! Şimdi hazır ol, söz verdiğim gibi altın ve şan. Bu anahtarı al ve Vali seni ödüllendirecek." -He'd better. For your sake!,TXT_RPLY0_SCRIPT02_D48512_HEDBE,〃,,,"To by tedy měl, pro tvoje vlastní dobro!",Det har han bare at gøre. For din skyld!,Das macht er besser. Deinetwillen!,,Li devus. Por via bono!,Más le vale. ¡Por tu propio bien!,,Parasta palkitakin! Sinun kannaltasi!,"Il a intérêt, pour votre bien!",Jobban teszi. A Te érdekedben!,È meglio che lo faccia... per il tuo bene!,戻せ、お前の為だ!,"살고 싶으면, 이 말이 사실이야 할 거다!",Dat is hem maar beter gelukt. Voor uw eigen bestwil!,Det bør han. For din skyld!,Mam nadzieję. Dla twojego dobra!,Acho bom mesmo. Pro seu bem!,,Ar face bine. De dragul tău!,Надеюсь. Это в твоих интересах!,,Öyle olsa iyi olur. Senin hatırın için! -What! Where's my money?,TXT_RPLY1_SCRIPT02_D48512_WHATW,〃,,,Cože? Kde jsou moje peníze?,Hvad! Hvor er mine penge?,Was! Wo ist mein Geld?,,Kio!? Kie estas mia mono?,¿¡Qué!? ¿Y mi dinero?,,Mitä! Missä on rahani?,Quoi? Où est mon argent!,Mi a túró! Hol van a pénzem?,Aspetta! Dove sono i miei soldi?,何だと! 金はどこだ?,뭐라고! 내 돈은 어디있지?,Wat! Waar is mijn geld?,Hva! Hvor er pengene mine?,Co! Gdzie moje pieniądze?,Como é? Cadê o meu dinheiro?,,Ce! Unde sunt banii mei?,Что? Где мои деньги?,,Ne! Param nerede? -"Get lost kid, you bother me.",TXT_DLG_SCRIPT02_D50028_GETLO,〃,,,"Odprejskni, mladej, otravuješ mě.","Forsvind, knægt, du generer mig.","Verzieh dich Jungchen, du störst mich.",,"Foriru, junulo; vi ĝenas min.","Ya vete, chaval, que eres pesado.","Ya vete de una vez, que eres pesado.","Häivy nulikka, häiritset minua.","Dégage, gamin, tu m'agaces.","Kopj le kölyök, ne itt lábatlankodj.","Sparisci, ragazzo, mi stai infastidendo.",失せろ、うざってえ。,사라져. 신경 거슬리게 하지 말고.,"Rot op, jongen, je stoort me.","Forsvinn, gutt, du plager meg.","Spadaj mały, przeszkadzasz mi.","Some daqui, garoto. Você está me incomodando.",,"Cară-te puștiule, mă deranjezi.","Пропади, малой. Ты меня раздражаешь.",,"Kaybol evlat, beni rahatsız ediyorsun." +","이봐, 알겠어. 확실히 뭔가 꾸며 놓은 것 같다는 거. 난 훌륭한 학살 기계에게 그런 짓을 할 사람이 아니야. 그래서 그걸 가져왔나? 좋아! 그럼 약속한 대로 골드와 영광을 줄 테니 준비해. 이 열쇠를 총독에게 가져다주면 보상해 줄 거야.","Hé, ik weet het, het ziet er een beetje uit als een valstrik. Dat zou ik nooit met zo'n grote moordmachine doen. Heb je het item? Geweldig! Maak je nu klaar, goud en glorie, net zoals ik beloofd heb. Neem deze sleutel en de gouverneur zal je belonen.","Jeg vet at det ser ut som en felle. Jeg ville aldri gjort det mot en så flott drapsmaskin. Har du gjenstanden? Flott! Gjør deg klar. Gull og ære, som jeg lovte. Ta denne nøkkelen, så vil guvernøren belønne deg.","Hej, wiem, wygląda to jak zasadzka. Nigdy bym czegoś takiego nie zrobił wspaniałej maszynie do zabijania. Masz przedmiot? Wspaniale! Przygotuj się teraz, złoto i chwała tak jak obiecywałem. Weź ten klucz, a Gubernator cię nagrodzi.","Olha, eu sei, meio que parece uma cilada. Eu nunca faria aquilo a uma grande máquina mortífera. Conseguiu o item? Ótimo! Agora se prepare, ouro e glória conforme prometido. Pegue esta chave e o Governador irá te recompensar.",,"Hei, știu că pare o capcană. Nu aș face așa ceva niciodată unei mașini ucigașe atât de tare. Ai obiectul? Perfect! Acum pregătește-te, aur și glorie cum ți-am promis. Ia cheia asta și Guvernatorul te va răsplătii.","Слушай, я знаю, о чём ты думаешь. Ты думаешь, что это подстава. Но я бы никогда не сделал этого с такой машиной для убийств, как ты. Достал то, что я просил? Отлично! Тебя ждёт золото и слава, как я и обещал. Возьми этот ключ — губернатор лично наградит тебя.",,"Jag vet, det ser ut som en uppställning. Jag skulle aldrig göra det mot en så stor mördarmaskin. Har du föremålet? Bra! Gör dig nu redo, guld och ära precis som jag lovade. Ta den här nyckeln och guvernören kommer att belöna dig.","Hey, biliyorum, biraz tuzağa benziyor. Böyle büyük bir ölüm makinesine bunu asla yapmazdım. Eşyayı aldın mı? Harika! Şimdi hazır ol, söz verdiğim gibi altın ve şan. Bu anahtarı al ve Vali seni ödüllendirecek." +He'd better. For your sake!,TXT_RPLY0_SCRIPT02_D48512_HEDBE,〃,,,"To by tedy měl, pro tvoje vlastní dobro!",Det har han bare at gøre. For din skyld!,Das macht er besser. Deinetwillen!,,Li devus. Por via bono!,Más le vale. ¡Por tu propio bien!,,Parasta palkitakin! Sinun kannaltasi!,"Il a intérêt, pour votre bien!",Jobban teszi. A Te érdekedben!,È meglio che lo faccia... per il tuo bene!,戻せ、お前の為だ!,"살고 싶으면, 이 말이 사실이야 할 거다!",Dat is hem maar beter gelukt. Voor uw eigen bestwil!,Det bør han. For din skyld!,Mam nadzieję. Dla twojego dobra!,Acho bom mesmo. Pro seu bem!,,Ar face bine. De dragul tău!,Надеюсь. Это в твоих интересах!,,Det är bäst att han gör det. För din skull!,Öyle olsa iyi olur. Senin hatırın için! +What! Where's my money?,TXT_RPLY1_SCRIPT02_D48512_WHATW,〃,,,Cože? Kde jsou moje peníze?,Hvad! Hvor er mine penge?,Was! Wo ist mein Geld?,,Kio!? Kie estas mia mono?,¿¡Qué!? ¿Y mi dinero?,,Mitä! Missä on rahani?,Quoi? Où est mon argent!,Mi a túró! Hol van a pénzem?,Aspetta! Dove sono i miei soldi?,何だと! 金はどこだ?,뭐라고! 내 돈은 어디있지?,Wat! Waar is mijn geld?,Hva! Hvor er pengene mine?,Co! Gdzie moje pieniądze?,Como é? Cadê o meu dinheiro?,,Ce! Unde sunt banii mei?,Что? Где мои деньги?,,Vad! Var är mina pengar?,Ne! Param nerede? +"Get lost kid, you bother me.",TXT_DLG_SCRIPT02_D50028_GETLO,〃,,,"Odprejskni, mladej, otravuješ mě.","Forsvind, knægt, du generer mig.","Verzieh dich Jungchen, du störst mich.",,"Foriru, junulo; vi ĝenas min.","Ya vete, chaval, que eres pesado.","Ya vete de una vez, que eres pesado.","Häivy nulikka, häiritset minua.","Dégage, gamin, tu m'agaces.","Kopj le kölyök, ne itt lábatlankodj.","Sparisci, ragazzo, mi stai infastidendo.",失せろ、うざってえ。,사라져. 신경 거슬리게 하지 말고.,"Rot op, jongen, je stoort me.","Forsvinn, gutt, du plager meg.","Spadaj mały, przeszkadzasz mi.","Some daqui, garoto. Você está me incomodando.",,"Cară-te puștiule, mă deranjezi.","Пропади, малой. Ты меня раздражаешь.",,"Stick, grabben, du stör mig.","Kaybol evlat, beni rahatsız ediyorsun." "No second chance. Oh guards, kill him.",TXT_DLG_SCRIPT02_D51544_NOSEC,〃,,,"Žádná druhá šance. Á, stráže, zabte ho.","Ingen ny chance. Åh vagter, dræb ham.","Keine zweite Chance. Oh Wachen, tötet ihn.",,"Ne estas alia ŝanco. Gardistoj, mortigu lin!","No hay otra oportunidad. ¡Guardias, matadlo!","No hay otra oportunidad. ¡Guardias, mátenlo!","Ei uutta tilaisuutta. Vartijat, tappakaa hänet.","Pas de deuxième chance. Gardes, tuez-le.","Nincs második esély. Ó, őrök, öljétek meg.","Nessuna seconda chance. Guardie, uccidetelo.","次はねえな。おぅガードの旦那、 -やっちゃってくだせえ。","너에게는 기회 따윈 없었어. 경비원, 저놈을 죽여.","Geen tweede kans. Oh bewakers, dood hem.","Ingen ny sjanse. Vakter, drep ham.","Nie będzie drugiej szansy. Oh... strażnicy, zabijcie go.","Sem segunda chance. Ah, guardas, matem ele.",,"Nicio altă șansă. Oh gardienilor, omorâți-l.","Нет, никакого второго шанса. Эй, стража, убейте его.",,"İkinci bir şans yok. Muhafızlar, öldürün onu." +やっちゃってくだせえ。","너에게는 기회 따윈 없었어. 경비원, 저놈을 죽여.","Geen tweede kans. Oh bewakers, dood hem.","Ingen ny sjanse. Vakter, drep ham.","Nie będzie drugiej szansy. Oh... strażnicy, zabijcie go.","Sem segunda chance. Ah, guardas, matem ele.",,"Nicio altă șansă. Oh gardienilor, omorâți-l.","Нет, никакого второго шанса. Эй, стража, убейте его.",,"Ingen andra chans. Åh vakter, döda honom.","İkinci bir şans yok. Muhafızlar, öldürün onu." "First they slaughter thousands, now they want all able-bodied peasants for unspecified 'tests'. How does the Order expect me to keep the peace? What the hell do you want?",TXT_DLG_SCRIPT02_D53060_FIRST,MAP02: Mourel.,,,"Tak oni nejdříve povraždí tisíce a teď po mě chtějí všechny schopné poddané pro neupřesněné 'testování'. Jak Řád očekává, že mám zachovat mír? Co ty sakra chceš?","Først slagter de tusinder, nu vil de have alle raske bønder til uspecificerede ""tests"". Hvordan forventer ordenen, at jeg skal opretholde freden? Hvad fanden vil du?",Zuerst metzeln sie Tausende nieder und nun wollen sie alle gesunden Bauern für unspezifierte „Tests“. Wie kann es der Orden nur so von mir verlangen Frieden zu bewahren? Was zum Teufel willst du?,,"Ili unue buĉis milojn, kaj nun volas ĉiujn sanegajn kamparanojn por nespecifaj «provoj». Kiel La Ordono esperas, ke mi ankoraŭ povos teni la pacon?... Kion diable vi volas?",Primero matan a miles y ahora quieren a todos los campesinos sanos para «pruebas» no especificadas. ¿Cómo espera La Orden que yo pueda seguir manteniendo la paz?... ¿Y tú qué demonios quieres?,Primero matan a miles y ahora quieren a todos los campesinos sanos para «pruebas» no especificadas. ¿Cómo espera La Orden que yo pueda seguir manteniendo la paz?... ¿Y tú qué carajo quieres?,"Ensiksi ne lahtaavat tuhansia, nyt ne haluavat kaikki kynnelle kykenevät maallikot määrittelemättömiin ""kokeisiin""'. Miten veljeskunta odottaa minun pitävän järjestystä? Mitä helvettiä sinä haluat?","D'abord ils en massacrent des miliers, maintenant ils veulent tous les paysans en bonne santé pour leur « tests » dont personne ne sait rien. Comment est-ce que l'ordre veut que je garde la paix? Qu'est-ce que vous voulez?","Először ezreket kaszabolnak le, most meg minden ép testű jobbágyot ismeretlen ""kísérletekhez"" akarnak. Hogy várhatja el a Rend, hogy fenntartsam a békét? Mi a francot akarsz?","Prima massacrano migliaia di persone, poi vogliono cittadini in buona condizione fisica per ""test"" non meglio specificati. Come può l'Ordine aspettarsi che io riesca a mantenere la pace? E tu che diavolo vuoi?","あいつら散々大量虐殺しといて、今度は'実験' の為に健康な庶民を用意しろとか。オーダーは 本当に平和を維持してくれるのか? で、君は何用で来たのかね? -","먼저 오더가 수천 명을 죽여놓고, 이젠 힘 좋은 시민들을 불러서 생각지도 않은 시험을 하라고 시키는구먼. 그놈들이 나한테 바라는 게 뭔지 전혀 모르겠네. 넌 원하는 게 뭐야?","Eerst slachten ze duizenden mensen af, nu willen ze alle valide boeren voor ongespecificeerde 'tests'. Hoe verwacht de Orde dat ik de vrede bewaar? Wat wil je verdomme?","Først slakter de tusenvis, og nå vil de ha alle arbeidsføre bønder til uspesifiserte ""tester"". Hvordan forventer ordenen at jeg skal bevare freden? Hva i helvete vil du ha?","Najpierw mordują tysiące, a teraz chcą wszystkich krzepkich chłopów do nieokreślonych ""testów"". Jak Zakon oczekuje ode mnie abym utrzymywał pokój? Czego chcesz u diabła?","Primeiro eles massacram milhares, agora querem que todos os plebeus saudáveis façam ""provas"" não especificadas. Como que a Ordem quer que eu mantenha a paz? Que diabos você quer?",,"Mai întâi măcelăresc cu miile, apoi vor toți sărmanii capabili de muncă pentru 'teste' nespecificate. Cum se așteaptă Ordinul să mențin pacea? Ce naiba vrei?","Сначала они убивают людей тысячами, а теперь им нужны все пригодные рабочие для каких-то «экспериментов»! И Орден ещё хочет, чтобы я поддерживал мир? Какого чёрта тебе нужно?",,"Önce binlercesini katlettiler, şimdi de tüm sağlıklı köylüleri belirsiz 'testler' için istiyorlar. Tarikat benden barışı korumamı nasıl bekler? Ne halt istiyorsun?" -"A prison pass, let's deal.",TXT_RPLY0_SCRIPT02_D53060_APRIS,〃,,,"Propustku do vězení, udělejme dohodu.","Et fængselskort, lad os lave en aftale.",Ein Gefängnispass. Lassen Sie uns verhandeln.,,Malliberejan paspermeson. Ni intertraktu.,Un pase a la prisión. Negociemos.,,Vankilan pääsyluvan; hierotaan diili.,Un passe de la prison. Faisons affaires.,Egy börtön belépő. Üzleteljünk.,"Un pass per la prigione, trattiamo.",刑務所の許可証だ、取引をしよう。,감옥 통행증만 있으면 돼.,"Een gevangenispasje, laten we dealen.","Et fengselspass, la oss gjøre en avtale.","Przepustkę do więzienia, ponegocjujmy.","Um passe da prisão, vamos negociar.",,O legitimație pentru închisoare. Să facem un târg.,Пропуск в тюрьму. Заключим сделку.,,"Bir hapishane izni, anlaşalım." +","먼저 오더가 수천 명을 죽여놓고, 이젠 힘 좋은 시민들을 불러서 생각지도 않은 시험을 하라고 시키는구먼. 그놈들이 나한테 바라는 게 뭔지 전혀 모르겠네. 넌 원하는 게 뭐야?","Eerst slachten ze duizenden mensen af, nu willen ze alle valide boeren voor ongespecificeerde 'tests'. Hoe verwacht de Orde dat ik de vrede bewaar? Wat wil je verdomme?","Først slakter de tusenvis, og nå vil de ha alle arbeidsføre bønder til uspesifiserte ""tester"". Hvordan forventer ordenen at jeg skal bevare freden? Hva i helvete vil du ha?","Najpierw mordują tysiące, a teraz chcą wszystkich krzepkich chłopów do nieokreślonych ""testów"". Jak Zakon oczekuje ode mnie abym utrzymywał pokój? Czego chcesz u diabła?","Primeiro eles massacram milhares, agora querem que todos os plebeus saudáveis façam ""provas"" não especificadas. Como que a Ordem quer que eu mantenha a paz? Que diabos você quer?",,"Mai întâi măcelăresc cu miile, apoi vor toți sărmanii capabili de muncă pentru 'teste' nespecificate. Cum se așteaptă Ordinul să mențin pacea? Ce naiba vrei?","Сначала они убивают людей тысячами, а теперь им нужны все пригодные рабочие для каких-то «экспериментов»! И Орден ещё хочет, чтобы я поддерживал мир? Какого чёрта тебе нужно?",,"Först slaktar de tusentals, nu vill de ha alla dugliga bönder för ospecificerade ""tester"". Hur förväntar sig orden att jag ska kunna upprätthålla freden? Vad i helvete vill ni?","Önce binlercesini katlettiler, şimdi de tüm sağlıklı köylüleri belirsiz 'testler' için istiyorlar. Tarikat benden barışı korumamı nasıl bekler? Ne halt istiyorsun?" +"A prison pass, let's deal.",TXT_RPLY0_SCRIPT02_D53060_APRIS,〃,,,"Propustku do vězení, udělejme dohodu.","Et fængselskort, lad os lave en aftale.",Ein Gefängnispass. Lassen Sie uns verhandeln.,,Malliberejan paspermeson. Ni intertraktu.,Un pase a la prisión. Negociemos.,,Vankilan pääsyluvan; hierotaan diili.,Un passe de la prison. Faisons affaires.,Egy börtön belépő. Üzleteljünk.,"Un pass per la prigione, trattiamo.",刑務所の許可証だ、取引をしよう。,감옥 통행증만 있으면 돼.,"Een gevangenispasje, laten we dealen.","Et fengselspass, la oss gjøre en avtale.","Przepustkę do więzienia, ponegocjujmy.","Um passe da prisão, vamos negociar.",,O legitimație pentru închisoare. Să facem un târg.,Пропуск в тюрьму. Заключим сделку.,,"Ett fängelsepass, låt oss göra upp.","Bir hapishane izni, anlaşalım." "I like you already. I have two chores that I don't want to do myself. One is messy, the other bloody.",TXT_DLG_SCRIPT02_D54576_ILIKE,〃,,,"Už teď se mi líbíš. Mám dvě prácičky, které nechci dělat sám. Jedna je špinavá, druhá je krvavá.","Jeg kan allerede godt lide dig. Jeg har to pligter, som jeg ikke selv vil gøre. Den ene er rodet, den anden er blodig.","Du gefällst mir bereits. Ich habe zwei lästige Angelegenheiten, um die ich mich nicht selber kümmern möchte. Die eine davon ist dreckig, die andere blutig.",,"Mi jam ŝatas vin. Estas du farotaĵoj, kiujn mi mem ne volas fari: unu estas malpura kaj la alia estas sanga.",Ya me caes bien. Hay dos tareas que no quiero hacer por mi cuenta: una es sucia y la otra sangrienta.,,"Minähän pidän sinusta. Minulla olisi kyllä pari askaretta, joita en itse haluaisi tehdä. Yksi niistä on sotkuinen, toinen hurmeinen.","Vous me plaisez déjà. J'ai deux corvées que je n'ai pas envie de faire. Une est.. Sale, l'autre est sanglante.","Kedvellek már most. Van két feladatom, amit nem akarok magam végezni. Az egyik a koszos, a másik a véres.","Già mi piaci. Ho due faccende da sbrigare che non voglio fare di persona. Una è un pò complicata, e l'altra da risolvere col sangue.","いいだろう。仕事は二つあるのだが -一つは面倒で、もう一つは血を見ることになる。",이제야 말길이 가네. 지금 너에게 맡을 시험이 두 가지 있거든. 더러운 거랑... 잔인한 거.,"Ik vind je nu al leuk. Ik heb twee taken die ik zelf niet wil doen. De ene is rommelig, de andere bloedig.","Jeg liker deg allerede. Jeg har to plikter jeg ikke vil gjøre selv. Det ene er rotete, det andre blodig.","Już cię lubię. Mam dwa zadania, których sam nie chcę wykonać. Jedno jest brudne, a drugie krwawe.","Estou gostando de você. Tenho mais duas tarefas chatas que eu particularmente não estou a fim de fazer. Uma é suja, a outra sangrenta.",,"Deja îmi placi. Am două treburi nasoale pe care nu vreau să le fac eu însumi. Una e haotică, cealalta sângeroasă.","Мне нравится твой настрой! У меня есть два неприятных дела, которыми я не хочу заниматься сам. Одно грязное, а другое кровавое.",,"Seni şimdiden sevdim. Kendi başıma yapmak istemediğim iki işim var. Biri pis, diğeri kanlı." -Call me the cleaner,TXT_RPLY0_SCRIPT02_D54576_CALLM,〃,,,Říkej mi pan uklízeč.,Kald mig rengøringsmanden.,Nennen Sie mich den Säuberer,,Purigado estas mia specialo.,Limpiar es mi especialidad.,,Olen siivoojasi,Appelez-moi le nettoyeur.,Hívj csak takarítónak.,Risolvere problemi è la mia specialità,まだ手は汚したくない,청소부라 불러줘.,Noem me de schoonmaakster,Kall meg renholderen.,Nazywaj mnie czyścicielem.,Pode me chamar de faxineiro,,Spune-mi curățătorul,Я — лучший чистильщик!,,Bana temizlikçi de. -I'm not squeamish,TXT_RPLY1_SCRIPT02_D54576_IMNOT,〃,,,Mám silný žaludek.,Jeg er ikke squeamish,Ich bin nicht zimperlich.,,Sango estas nenio.,La sangre no es nada.,,En ole heikkohermoinen,J'ai pas peur de me tacher les mains.,Nem vagyok finnyás,Non mi impressiono facilmente,汚れ仕事でも構わない,나는 비위가 약하지 않아.,Ik ben niet katholiek.,Jeg er ikke pysete,Nie jestem wybredny.,Não sou muito escrupuloso,,Nu sunt mofturos,Я не боюсь крови.,,Ben alıngan değilim. +一つは面倒で、もう一つは血を見ることになる。",이제야 말길이 가네. 지금 너에게 맡을 시험이 두 가지 있거든. 더러운 거랑... 잔인한 거.,"Ik vind je nu al leuk. Ik heb twee taken die ik zelf niet wil doen. De ene is rommelig, de andere bloedig.","Jeg liker deg allerede. Jeg har to plikter jeg ikke vil gjøre selv. Det ene er rotete, det andre blodig.","Już cię lubię. Mam dwa zadania, których sam nie chcę wykonać. Jedno jest brudne, a drugie krwawe.","Estou gostando de você. Tenho mais duas tarefas chatas que eu particularmente não estou a fim de fazer. Uma é suja, a outra sangrenta.",,"Deja îmi placi. Am două treburi nasoale pe care nu vreau să le fac eu însumi. Una e haotică, cealalta sângeroasă.","Мне нравится твой настрой! У меня есть два неприятных дела, которыми я не хочу заниматься сам. Одно грязное, а другое кровавое.",,"Jag gillar dig redan. Jag har två sysslor som jag inte vill göra själv. Den ena är smutsig, den andra är blodig.","Seni şimdiden sevdim. Kendi başıma yapmak istemediğim iki işim var. Biri pis, diğeri kanlı." +Call me the cleaner,TXT_RPLY0_SCRIPT02_D54576_CALLM,〃,,,Říkej mi pan uklízeč.,Kald mig rengøringsmanden.,Nennen Sie mich den Säuberer,,Purigado estas mia specialo.,Limpiar es mi especialidad.,,Olen siivoojasi,Appelez-moi le nettoyeur.,Hívj csak takarítónak.,Risolvere problemi è la mia specialità,まだ手は汚したくない,청소부라 불러줘.,Noem me de schoonmaakster,Kall meg renholderen.,Nazywaj mnie czyścicielem.,Pode me chamar de faxineiro,,Spune-mi curățătorul,Я — лучший чистильщик!,,Kalla mig städaren.,Bana temizlikçi de. +I'm not squeamish,TXT_RPLY1_SCRIPT02_D54576_IMNOT,〃,,,Mám silný žaludek.,Jeg er ikke squeamish,Ich bin nicht zimperlich.,,Sango estas nenio.,La sangre no es nada.,,En ole heikkohermoinen,J'ai pas peur de me tacher les mains.,Nem vagyok finnyás,Non mi impressiono facilmente,汚れ仕事でも構わない,나는 비위가 약하지 않아.,Ik ben niet katholiek.,Jeg er ikke pysete,Nie jestem wybredny.,Não sou muito escrupuloso,,Nu sunt mofturos,Я не боюсь крови.,,Jag är inte känslig.,Ben alıngan değilim. One of my minions is stealing power with a tap on the mains somewhere. Find it and truncate his supply and I'll provide you with what you want. Bring me something as a token.,TXT_DLG_SCRIPT02_D56092_ONEOF,"〃 (""messy"" chore)",,,"Jeden z mých poddaných stáčedlem někde z hlavního vedení krade energii. Najdi jej a odřízni dotyčného od zásoby a já ti dám, co chceš. Přines mi něco jako důkaz.","En af mine håndlangere stjæler strøm med en vandhane et sted. Find den og afbryd hans forsyning, så skal jeg give dig, hvad du vil have. Bring mig noget som et symbol.","Einer meiner Untertanen zapft irgendwo Strom ab. Finde die Anzapfung und kappe sie. Falls du Erfolg hast, kriegst du was du brauchst. Aber bring mir einen Beweis mit!",,"Unu el miaj sbiroj metis konektilon ien por ŝteli energion de la elektriza sistemo. Ĝin trovu kaj detruu, kaj mi donos al vi tion, kion vi petis. Alportu pruvon kiam vi finos.","Uno de mis secuaces puso en algún lado una toma en la red eléctrica para robar energía. Encuéntralo, trunca su suministro y te daré lo que pides. Tráeme algo como prueba una vez que termines.","Uno de mis secuaces puso en algún lado una toma en la red eléctrica para robar energía. Encuéntralo, destruye su suministro y te voy a dar lo que pides. Tráeme algo como prueba una vez que termines.","Yksi alamaisistani varastaa verkkovirtaa jossakin sijaitsevalla salaisella kytkennällä. Löydä se ja katkaise hänen jakelunsa, niin annan sinulle haluamasi. Tuo minulle jotain todisteeksi.",Un de mes larbins pompe de l'électricité avec une connection pirate dans les transformateurs là haut. Trouvez là et coupez sa connection. Je vous donnerai ce que vous voulez. Ramenez moi une preuve.,"Az egyik alattvalóm áramot lop egy dugasszal a központi hálózatnál valahol. Találd meg, majd válaszd el az ellátását, és én adok neked amit akarsz. Hozz nekem valamit bizonyítékként","Uno dei miei tirapiedi sta rubando energia con un suo aggeggio attaccato alla rete elettrica da qualche parte. Trova questo aggeggio e staccalo dalla rete, e ti darò quello che desideri. Portami qualcosa come prova.","私の手下の一人が水力発電から電力を盗んで いるらしい。それを見つけ供給を切って くれれば君の望む物をやろう。 -その象徴となるのも持ってきてほしい。",내 부하 중 한 명이 어딘가에 있는 동력선에 추출기를 꽂아 동력을 훔치고 있다는군. 그것을 찾아내서 그의 공급을 자르면 네가 원하는 것을 제공하지. 증거가 될만한 그것을 가져와.,Een van mijn acolieten steelt stroom met een kraan op het lichtnet ergens. Zoek het en snoei zijn aansluiting in en ik zal je voorzien van wat je wilt. Breng me iets als teken.,"En av håndlangerne mine stjeler strøm med en kran på strømnettet et sted. Finn den og kutt forsyningen hans, så gir jeg deg det du vil ha. Gi meg noe som et symbol.","Jeden z moich sług kradnie gdzieś moc w przewodach za pomocą przełącznika. Znajdź go i odetnij jego dostawę mocy, a dam ci co chcesz. Przynieś mi coś jako dowód.",Um dos meus capangas está roubando energia por uma ligação clandestina em algum lugar. Encontre e corte essa ligação e conseguirei o que você quer. Traga algo como prova.,,"Unul dintre slujitorii mei fură electricitate cu robinetul pe undeva. Află cum face asta, distruge-i proviziile, și îți voi oferi ceea ce vrei. Adu-mi și ceva ca dovadă.","Кто-то из моих подчинённых отводит энергию откуда-то из питающей сети. Найди и отключи эту установку — тогда получишь то, за чем пришёл. И принеси мне что-нибудь в качестве доказательства.",,"Kölelerimden biri bir yerdeki şebekeden güç çalıyor. Onu bul ve kaynağını kes, ben de sana istediğini vereyim. Bana simge olarak bir şey getir." +その象徴となるのも持ってきてほしい。",내 부하 중 한 명이 어딘가에 있는 동력선에 추출기를 꽂아 동력을 훔치고 있다는군. 그것을 찾아내서 그의 공급을 자르면 네가 원하는 것을 제공하지. 증거가 될만한 그것을 가져와.,Een van mijn acolieten steelt stroom met een kraan op het lichtnet ergens. Zoek het en snoei zijn aansluiting in en ik zal je voorzien van wat je wilt. Breng me iets als teken.,"En av håndlangerne mine stjeler strøm med en kran på strømnettet et sted. Finn den og kutt forsyningen hans, så gir jeg deg det du vil ha. Gi meg noe som et symbol.","Jeden z moich sług kradnie gdzieś moc w przewodach za pomocą przełącznika. Znajdź go i odetnij jego dostawę mocy, a dam ci co chcesz. Przynieś mi coś jako dowód.",Um dos meus capangas está roubando energia por uma ligação clandestina em algum lugar. Encontre e corte essa ligação e conseguirei o que você quer. Traga algo como prova.,,"Unul dintre slujitorii mei fură electricitate cu robinetul pe undeva. Află cum face asta, distruge-i proviziile, și îți voi oferi ceea ce vrei. Adu-mi și ceva ca dovadă.","Кто-то из моих подчинённых отводит энергию откуда-то из питающей сети. Найди и отключи эту установку — тогда получишь то, за чем пришёл. И принеси мне что-нибудь в качестве доказательства.",,En av mina hantlangare stjäl ström med en kran på elnätet någonstans. Hitta den och avbryta hans leverans så ska jag förse dig med det du vill ha. Ta med dig något som ett tecken.,"Kölelerimden biri bir yerdeki şebekeden güç çalıyor. Onu bul ve kaynağını kes, ben de sana istediğini vereyim. Bana simge olarak bir şey getir." Where do I find this tap?,TXT_RPLY0_SCRIPT02_D56092_WHERE,"〃 -(〃)",,,Kde najdu to stáčedlo?,Hvor kan jeg finde denne vandhane?,Wo finde ich die Anzapfung?,,Kie estas la konektilo?,¿Dónde está la toma?,,Mistä tämä kytkentä löytyy?,Où est-ce que je trouve cette connection?,Hol találom ezt a dugaszt?,E dove lo trovo questo aggeggio?,どうやって突き止めたらいい?,그 추출기는 어디에 찾을 수 있지?,Waar vind ik deze kraan?,Hvor finner jeg denne kranen?,Gdzie znajdę ten przełącznik?,Onde encontro essa ligação clandestina?,,Unde-i găsesc robinetul?,Где может находиться эта установка?,,Bu musluğu nerede bulabilirim? +(〃)",,,Kde najdu to stáčedlo?,Hvor kan jeg finde denne vandhane?,Wo finde ich die Anzapfung?,,Kie estas la konektilo?,¿Dónde está la toma?,,Mistä tämä kytkentä löytyy?,Où est-ce que je trouve cette connection?,Hol találom ezt a dugaszt?,E dove lo trovo questo aggeggio?,どうやって突き止めたらいい?,그 추출기는 어디에 찾을 수 있지?,Waar vind ik deze kraan?,Hvor finner jeg denne kranen?,Gdzie znajdę ten przełącznik?,Onde encontro essa ligação clandestina?,,Unde-i găsesc robinetul?,Где может находиться эта установка?,,Var hittar jag den här kranen?,Bu musluğu nerede bulabilirim? "If I knew, it wouldn't be a chore now would it? Use your charm, but shut off his supply.",TXT_DLG_SCRIPT02_D57608_IFIKN,"〃 (〃)",,,"Kdybych věděl, nebyla by to práce, ne? Použij svůj šarm, ale vypni dotyčnému přívod.","Hvis jeg vidste det, ville det ikke være så besværligt, vel? Brug din charme, men luk for hans forsyning.","Wenn ich das wüsste, wäre das keine lästige Angelegenheit, nicht wahr? Benutze deinen Charme, aber schalte seine Versorgung aus.",,"Se mi scius tion, mi ne petus ĉi tion al vi, ĉu ne? Uzu vian ĉarmon, sed interrompu lian provizadon.","Si lo supiera no te lo estaría pidiendo, ¿no? Usa tu encanto, pero corta su suministro. ",,"Jos tietäisin sen, eihän se silloin enää olisi askare, eihän? Käytä sulokkuutasi, mutta katkaise hänen sähkönsä.","Si je le savais, ce ne serait pas une corvée, non? Utiliser votre charme si il le faut, mais coupez cette connection.","Ha tudnám, nem lenne ez a feladat már. Használd a bájodat, de állítsd le az ellátást.","E se lo sapessi, non sarebbe mica una faccenda scomoda! Usa il tuo fascino, ma metti fine al suo schema.","私が知っていたら、こんな雑用はさせない だろう?誰かをでっちあげるか、 聞き込みでもするんだ。","만약 내가 그 위치를 알았다면 지루한 심부름이 됐겠지, 그렇지 않아? 네 머리를 써! 그리고 그 추출기를 찾아. - \cy배부른 돼지 같은 녀석. 난 이 추출기에 대해서 아무것도 몰라. 너무 급하게 하지 말자.","Als ik het wist, zou het nu geen karwei zijn, toch? Gebruik je charme, maar schakel zijn voorraad uit.","Hvis jeg visste det, ville det ikke være et ork, ville det vel? Bruk sjarmen din, men steng av tilførselen hans.","Gdybym wiedział, to nie byłby problem, prawda? Wykorzystaj swój spryt, ale pamiętaj by odciąć mu dostawę.","Se eu soubesse, não seria uma tarefa chata, não é mesmo? Use seu charme, mas corte essa ligação.",,"Dacă știam, n-ar mai fi fost o corvoadă, este? Folosește-ți farmecul, dar distruge-i proviziile.","Если бы я знал, то справился бы с этим сам, как считаешь? Пусти в ход свои таланты, но прекрати утечку энергии.",,"Eğer bilseydim, bu bir angarya olmazdı, değil mi? Cazibeni kullan ama onun kaynağını kapat." + \cy배부른 돼지 같은 녀석. 난 이 추출기에 대해서 아무것도 몰라. 너무 급하게 하지 말자.","Als ik het wist, zou het nu geen karwei zijn, toch? Gebruik je charme, maar schakel zijn voorraad uit.","Hvis jeg visste det, ville det ikke være et ork, ville det vel? Bruk sjarmen din, men steng av tilførselen hans.","Gdybym wiedział, to nie byłby problem, prawda? Wykorzystaj swój spryt, ale pamiętaj by odciąć mu dostawę.","Se eu soubesse, não seria uma tarefa chata, não é mesmo? Use seu charme, mas corte essa ligação.",,"Dacă știam, n-ar mai fi fost o corvoadă, este? Folosește-ți farmecul, dar distruge-i proviziile.","Если бы я знал, то справился бы с этим сам, как считаешь? Пусти в ход свои таланты, но прекрати утечку энергии.",,"Om jag visste det skulle det inte vara så jobbigt, eller hur? Använd din charm, men stäng av hans förråd.","Eğer bilseydim, bu bir angarya olmazdı, değil mi? Cazibeni kullan ama onun kaynağını kapat." "Tell you what, there's a lying sack named Derwin who has been selling children to the Order. I won't tolerate that kind of depravity. Not without my cut. Derwin works in the warehouse. Kill him and bring me his, ear, and I'll see what I can do.",TXT_DLG_SCRIPT02_D59124_TELLY,"〃 (""bloody"" chore)",,,"Mám problém s pupkáčem jménem Derwin, který Řádu prodává děti. Takovou odpornost nemůžu tolerovat, ne bez mého podílu. Derwin pracuje ve skladišti. Zab ho a přines mi jeho ucho a já uvidím, co pro tebe budu moci udělat.","Ved du hvad, der er en løgnagtig sæk ved navn Derwin, der har solgt børn til Ordenen. Jeg vil ikke tolerere den slags fordærv. Ikke uden min andel. Derwin arbejder i lageret. Dræb ham og giv mig hans øre, så skal jeg se, hvad jeg kan gøre.","Ich sag dir was, da gibt es so einen lügenden Kerl namens Derwin, der Kinder an den Orden verkauft hat. Ich kann so eine Verdorbenheit nicht tolerieren. Nicht ohne meinen Anteil. Derwin arbeitet im Lagerhaus. Töte ihn und bring mir sein Ohr und ich werde sehen was ich tun kann.",,"Aŭskultu ĉi tion. Estas fimensogulo nomata Derwin, kiu kutimas vendi infanojn al La Ordono, kaj mi ne toleros tian perversecon: ne se li ne donos parton de la gajnoj. Derwin laboras en la magazeno. Mortigu lin, alportu lian orelon kaj mi vidos tion, kion mi povas fari.","A ver, te cuento. Hay un sucio mentiroso llamado Derwin que ha estado vendiendo niños a La Orden, y no toleraré ese tipo de perversión: no si no me da mi parte. Derwin trabaja en el almacén. Mátalo, tráeme su oreja y veré qué puedo hacer.","A ver, te cuento. Hay un sucio mentiroso llamado Derwin que ha estado vendiendo niños a La Orden, y no puedo tolerar ese tipo de perversión: no si no me da mi parte. Derwin trabaja en el almacén. Mátalo, tráeme su oreja y voy a ver qué puedo hacer.","Annapa, kun kerron valepukista nimeltä Derwin, joka myy lapsia Veljeskunnalle. En voi suvaita sellaista turmeltuneisuutta... jossa en pääse itse osingoille. Derwin työskentelee varastolla. Tapa hänet ja tuo minulle hänen... korvansa, ja katson sitten, jos voin olla avuksi.","Eh bien, il y a une raclure appelée Derwin qui vend des enfants à l'Ordre. Je ne tolère pas ce type d'atrocité, du moins pas sans ma part des frais. Derwin travaille dans l'entrepôt. Tuez-le et ramenez moi son oreille, je verrais ce que je peux faire pour vous.","Na figyusz, van egy Derwin nevű hazug genya, aki gyerekeket árul a Rend számára. Nem tolerálom az ilyen romlottságot. Legalábbis a részesedésem nélkül. Derwin a raktárban dolgozik. Intézd el, és hozdd el a fülét, meglátom mit tehetek érted.","Senti questa, ci sta questo sporco bugiardo chiamato Derwin che sta vendendo bambini all'Ordine. Non tollero queste azioni depravate. Non senza che io riceva una fetta dei soldi. Derwin lavora al magazzino. Fallo fuori e portami un suo, orecchio, e vedrò cosa posso fare.","教えよう、ダーウィンとかいう恥知らずが 子供をオーダーへ売りつけているようだ。 私に分け前無しに、そんな恥ずべき行為を 許すわけには行かん。ダーウィンは倉庫で 勤務している。殺った証拠として奴の、耳を、 -持ってきたまえ。","그렇담, 더윈이라는 뚱땡이가 지금 아이들을 붙잡아 오더에 팔아넘기는 짓을 일삼고 있어. 너무나도 괘씸해... 내게 이득이 전혀 없으니. 더윈은 발전소 주변 창고에서 일하고 있어. 그를 죽이고, 그의, 귀를 뜯어서 가져와. 그럼 거래를 진행하지.","Weet je wat, er is een leugenachtige zak genaamd Derwin die kinderen aan de Orde heeft verkocht. Dat soort verdorvenheid tolereer ik niet. Niet zonder mijn deel. Derwin werkt in het magazijn. Dood hem en breng me zijn oor, en ik zal zien wat ik kan doen.","Det er en løgnhals ved navn Derwin som har solgt barn til Ordenen. Jeg tolererer ikke den slags fordervelse. Ikke uten min andel. Derwin jobber på lageret. Drep ham og gi meg hans øre, så skal jeg se hva jeg kan gjøre.","Słuchaj, jest tu pewien worek kłamstw, który nazywa się Derwin. Sprzedaje on Zakonowi dzieci. Nie będę tolerował takiego zepsucia. Nie bez moich udziałów. Derwin pracuje w magazynie. Zabij go i przynieś mi jego... ucho, a zobaczę co da się zrobić.","É o seguinte, tem um mentiroso desgraçado chamado Derwin que anda vendendo crianças para a Ordem. Não vou tolerar esse tipo de depravação. Não sem a minha parte. Derwin trabalha no depósito. Mate-o e traga a...orelha dele e verei o que posso fazer.",,"Să-ți zic ceva, un gunoi mincinos pe nume Derwin vinde copii Ordinului. Nu tolerez ceva atât de depravat. Nu fără să primesc și eu ceva. Derwin lucrează în depozit. Omoară-l și adu-mi... urechea lui, și-o să văd ce pot face.","Лживый мешок дерьма по имени Дервин продаёт Ордену детей. Я не терплю такой безнравственности, особенно когда меня не берут в долю. Дервин работает в складе. Убей его и принеси мне его ухо, и я посмотрю, чем можно помочь.",,"Bak ne diyeceğim, Tarikat'a çocuk satan Derwin adında yalancı bir çuval var. Bu tür bir ahlaksızlığa müsamaha göstermeyeceğim. Benim payım olmadan olmaz. Derwin depoda çalışıyor. Onu öldürüp kulağını bana getir, ne yapabileceğime bakarım." +持ってきたまえ。","그렇담, 더윈이라는 뚱땡이가 지금 아이들을 붙잡아 오더에 팔아넘기는 짓을 일삼고 있어. 너무나도 괘씸해... 내게 이득이 전혀 없으니. 더윈은 발전소 주변 창고에서 일하고 있어. 그를 죽이고, 그의, 귀를 뜯어서 가져와. 그럼 거래를 진행하지.","Weet je wat, er is een leugenachtige zak genaamd Derwin die kinderen aan de Orde heeft verkocht. Dat soort verdorvenheid tolereer ik niet. Niet zonder mijn deel. Derwin werkt in het magazijn. Dood hem en breng me zijn oor, en ik zal zien wat ik kan doen.","Det er en løgnhals ved navn Derwin som har solgt barn til Ordenen. Jeg tolererer ikke den slags fordervelse. Ikke uten min andel. Derwin jobber på lageret. Drep ham og gi meg hans øre, så skal jeg se hva jeg kan gjøre.","Słuchaj, jest tu pewien worek kłamstw, który nazywa się Derwin. Sprzedaje on Zakonowi dzieci. Nie będę tolerował takiego zepsucia. Nie bez moich udziałów. Derwin pracuje w magazynie. Zabij go i przynieś mi jego... ucho, a zobaczę co da się zrobić.","É o seguinte, tem um mentiroso desgraçado chamado Derwin que anda vendendo crianças para a Ordem. Não vou tolerar esse tipo de depravação. Não sem a minha parte. Derwin trabalha no depósito. Mate-o e traga a...orelha dele e verei o que posso fazer.",,"Să-ți zic ceva, un gunoi mincinos pe nume Derwin vinde copii Ordinului. Nu tolerez ceva atât de depravat. Nu fără să primesc și eu ceva. Derwin lucrează în depozit. Omoară-l și adu-mi... urechea lui, și-o să văd ce pot face.","Лживый мешок дерьма по имени Дервин продаёт Ордену детей. Я не терплю такой безнравственности, особенно когда меня не берут в долю. Дервин работает в складе. Убей его и принеси мне его ухо, и я посмотрю, чем можно помочь.",,"Vet du vad, det finns en ljugande säck vid namn Derwin som har sålt barn till Orden. Jag tolererar inte den sortens fördärv. Inte utan min andel. Derwin arbetar i lagret. Döda honom och ge mig hans öra så ska jag se vad jag kan göra.","Bak ne diyeceğim, Tarikat'a çocuk satan Derwin adında yalancı bir çuval var. Bu tür bir ahlaksızlığa müsamaha göstermeyeceğim. Benim payım olmadan olmaz. Derwin depoda çalışıyor. Onu öldürüp kulağını bana getir, ne yapabileceğime bakarım." How do I get in?,TXT_RPLY0_SCRIPT02_D59124_HOWDO,"〃 -(〃)",,,Jak se dostanu dovnitř?,Hvordan kommer jeg ind?,Wie komme ich hinein?,,Kiel mi eniru tien?,¿Cómo entro?,,Miten pääsen sisään?,Comment j'y rentre?,Hogy jutok be?,Come ci arrivo?,どうすれば入れる?,어떻게 들어가지?,Hoe kom ik binnen?,Hvordan kommer jeg inn?,Jak się tam dostanę?,Como faço para entrar?,,Cum ajung înăuntru?,Как мне туда попасть?,,İçeri nasıl gireceğim? +(〃)",,,Jak se dostanu dovnitř?,Hvordan kommer jeg ind?,Wie komme ich hinein?,,Kiel mi eniru tien?,¿Cómo entro?,,Miten pääsen sisään?,Comment j'y rentre?,Hogy jutok be?,Come ci arrivo?,どうすれば入れる?,어떻게 들어가지?,Hoe kom ik binnen?,Hvordan kommer jeg inn?,Jak się tam dostanę?,Como faço para entrar?,,Cum ajung înăuntru?,Как мне туда попасть?,,Hur kommer jag in?,İçeri nasıl gireceğim? "This key will get you into the power station. On second thought, cut off the ear and then kill him. Much better.",TXT_DLG_SCRIPT02_D60640_THISK,"〃 (〃)",,,"Tímhle klíčem se dostaneš do elektrárny. Víš ty co, nejprve mu uřízni ucho, až pak ho zabij. Mnohem lepší.","Med denne nøgle kan du komme ind i kraftværket. Ved nærmere eftertanke, skær øret af og dræb ham så. Det er meget bedre.","Dieser Schlüssel wird dich ins Kraftwerk bringen. Andererseits, schneide ihm erst das Ohr ab und dann töte ihn. Viel besser.",,"Jen ŝlosilo de la elektra centralo. Repensante pri tio, fortranĉu lian orelon kaj tiam mortigu lin. Multe plibone.","Aquí tengo una llave de la central eléctrica. Pensándolo bien, córtale la oreja y luego mátalo. Mucho mejor.",,"Tällä avaimella pääset voimalaitokseen. Nyt, kun tarkemmin ajattelen, niin sivalla ensin hänen korvansa, ja sitten tapa hänet. Paljon parempi.","Cette clé vous laissera entrer dans la centrale électrique. Maintenant que j'y pense, coupez-lui l'oreille, puis tuez-le. Ca me plaît plus comme ça.","Ezzel a kulccsal bejuthatsz az erőműbe. Jobban átgondolva, vádg le a fülét és öld meg. Sokkal jobb. ","Questa chiave ti farà entrare nella centrale energetica. Ora che ci penso, prima tagliagli l'orecchio, e poi uccidilo. Molto meglio.","この鍵で発電所に入るんだ。出来れば、 先に耳を切り落としてから殺してくれ。 -その方が良い。","이 열쇠만 있으면 발전소에 들어갈 수 있을 거야. 그리고 다시 생각해보니, 그 자식을 죽이기 전에, 먼저 귀를 뜯어. 그럼 더 나을 거 같군.","Met deze sleutel kom je in de centrale. Bij nader inzien, snij je het oor eraf en vermoord je hem. Veel beter.","Denne nøkkelen får deg inn i kraftstasjonen. Ved nærmere ettertanke, skjær av øret og drep ham. Mye bedre.","Ten klucz pozwoli ci wejść do elektrowni. Z drugiej strony, najpierw odetnij mu ucho, a potem go zabij. Tak będzie lepiej.","Esta chave vai te ajudar a entrar na usina de energia. Pensando melhor, corte fora a orelha e depois mate ele. Muito melhor.",,"Cheia asta îți va oferi acces la stația electrică. Dacă mă gândesc mai bine, mai întâi taie-i urechea și abia apoi omoară-l. Mult mai bine.","С этим ключом ты пройдёшь на электростанцию. А, да, я тут подумал — сначала отрежь ему ухо, а затем убей. Так будет намного лучше.",,"Bu anahtar seni elektrik santraline sokacak. Bir daha düşündüm de, kulağını kes ve sonra onu öldür. Çok daha iyi olur." +その方が良い。","이 열쇠만 있으면 발전소에 들어갈 수 있을 거야. 그리고 다시 생각해보니, 그 자식을 죽이기 전에, 먼저 귀를 뜯어. 그럼 더 나을 거 같군.","Met deze sleutel kom je in de centrale. Bij nader inzien, snij je het oor eraf en vermoord je hem. Veel beter.","Denne nøkkelen får deg inn i kraftstasjonen. Ved nærmere ettertanke, skjær av øret og drep ham. Mye bedre.","Ten klucz pozwoli ci wejść do elektrowni. Z drugiej strony, najpierw odetnij mu ucho, a potem go zabij. Tak będzie lepiej.","Esta chave vai te ajudar a entrar na usina de energia. Pensando melhor, corte fora a orelha e depois mate ele. Muito melhor.",,"Cheia asta îți va oferi acces la stația electrică. Dacă mă gândesc mai bine, mai întâi taie-i urechea și abia apoi omoară-l. Mult mai bine.","С этим ключом ты пройдёшь на электростанцию. А, да, я тут подумал — сначала отрежь ему ухо, а затем убей. Так будет намного лучше.",,"Den här nyckeln tar dig in i kraftverket. Vid närmare eftertanke, skär av örat och döda honom sedan. Mycket bättre.","Bu anahtar seni elektrik santraline sokacak. Bir daha düşündüm de, kulağını kes ve sonra onu öldür. Çok daha iyi olur." "Oh, I just love souvenirs. Here, this will get you into the prison. Talk to Warden Montag. Whatever you do after that, I don't want to know.",TXT_DLG_SCRIPT02_D62156_OHIJU,"〃 (after completing ""messy"" chore)",,,"Ó, já prostě zbožňuju suvenýry. Tady, tohle tě dostane do vězení. Promluv si s dozorčím Montagem. Co máš v plánu dělat potom, to už vědět nechci.","Åh, jeg elsker souvenirs. Her, med den her kan du komme ind i fængslet. Tal med fængselsinspektør Montag. Hvad du end gør efter det, vil jeg ikke vide det.","Oh, ich liebe Souvenirs. Hier, damit kommst du in das Gefängnis. Sprich mit Direktor Montag. Was du danach machen musst, weiß ich nicht.",,"Ha, mi ŝategas memoraĵojn. Havu ĉi tion, kio ebligos al vi eniri la malliberejon. Parolu kun la provoso Montag. Tion ajn, kion vi faros poste, mi ne volas scii.","Ah, me encantan los recuerdos. Ten, con esto podrás entrar en la prisión. Habla con el carcelero Montag. Lo que hagas después de eso no quiero saberlo.","Ah, me encantan los recuerdos. Toma, con esto vas a poder entrar a la prisión. Habla con el carcelero Montag. Lo que hagas después de eso no quiero saberlo.","Minä siis niin rakastan matkamuistoja. Kas näin, pääset tällä vankilaan. Puhu vankilanjohtaja Montagin kanssa. Mitä teetkään sen jälkeen, en halua tietää.","Oh, j'adore les souvenirs. Voilà, ça vous laissera entrer dans la prison. Parlez au gardien Montag. Ce que vous faites après, je m'en fous complètement.","Oh, imádom az ajándékokat. Nesze, ezzel be fogsz tudni jutni a börtönbe. Beszélj Mondtag igazgatóval. Nem akarok tudni arról, mit teszel utána.","Ah, adoro i souvenir! Ecco qua, con questo potrai entrare nella prigione. Parla con Montag, il direttore del carcere. Quello che farai dopo, a me non interessa.","嬉しい手土産だ。では、これがあれば 刑務所に入れる。モンターグ所長と話すんだ。 -君がそこで何をしようが、私の管轄外だ。","오오, 난 기념품이 정말 좋아. 여기, 네가 원했던 감옥 통행증이야. 감옥으로 가서 몬탕 간수장에게 이야기해봐. 네가 어떤 짓을 저지르든, 그 후엔 절대로 알고 싶지 않아!","Oh, ik hou gewoon van souvenirs. Hier, dit zal je in de gevangenis brengen. Spreek met directeur Montag. Wat je daarna ook doet, ik wil het niet weten.","Jeg elsker suvenirer. Denne får deg inn i fengselet. Snakk med fengselsdirektør Montag. Uansett hva du gjør etter det, vil jeg ikke vite det.","Oh, po prostu kocham pamiątki. Masz, to pozwoli ci wejść do więzienia. Pogadaj z Naczelnikiem Montagiem. Nie chcę wiedzieć co potem zrobisz.","Ah, eu simplesmente adoro suvenires. Tome, isto vai te ajudar a entrar na prisão. Fale com o carcereiro, Montag. O que você for fazer depois não me interessa.",,"Oh, ce mai ador suvenirurile. Aici, asta îți va permite să ajungi în interiorul închisorii. Vorbește cu gardianul Montag. Ce faci după aceea, nu vreau să știu.","О, как я люблю сувениры! Вот твой пропуск в тюрьму. Обратись к тюремщику Монтагу, а что ты будешь делать потом, я и знать не желаю.",,"Hatıra eşyalarına bayılırım. İşte, bu seni hapishaneye sokacak. Müdür Montag ile konuş. Ondan sonra ne yaparsan yap, bilmek istemiyorum." +君がそこで何をしようが、私の管轄外だ。","오오, 난 기념품이 정말 좋아. 여기, 네가 원했던 감옥 통행증이야. 감옥으로 가서 몬탕 간수장에게 이야기해봐. 네가 어떤 짓을 저지르든, 그 후엔 절대로 알고 싶지 않아!","Oh, ik hou gewoon van souvenirs. Hier, dit zal je in de gevangenis brengen. Spreek met directeur Montag. Wat je daarna ook doet, ik wil het niet weten.","Jeg elsker suvenirer. Denne får deg inn i fengselet. Snakk med fengselsdirektør Montag. Uansett hva du gjør etter det, vil jeg ikke vite det.","Oh, po prostu kocham pamiątki. Masz, to pozwoli ci wejść do więzienia. Pogadaj z Naczelnikiem Montagiem. Nie chcę wiedzieć co potem zrobisz.","Ah, eu simplesmente adoro suvenires. Tome, isto vai te ajudar a entrar na prisão. Fale com o carcereiro, Montag. O que você for fazer depois não me interessa.",,"Oh, ce mai ador suvenirurile. Aici, asta îți va permite să ajungi în interiorul închisorii. Vorbește cu gardianul Montag. Ce faci după aceea, nu vreau să știu.","О, как я люблю сувениры! Вот твой пропуск в тюрьму. Обратись к тюремщику Монтагу, а что ты будешь делать потом, я и знать не желаю.",,"Jag älskar souvenirer. Här, den här tar dig in i fängelset. Prata med fängelsedirektör Montag. Vad du än gör efter det vill jag inte veta.","Hatıra eşyalarına bayılırım. İşte, bu seni hapishaneye sokacak. Müdür Montag ile konuş. Ondan sonra ne yaparsan yap, bilmek istemiyorum." Thanks.,TXT_RPLY0_SCRIPT02_D62156_THANK,"〃 -(〃)",,,Díky.,Jeg vil ikke vide det. Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Kösz.,Grazie.,ありがとう。,고마워.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Спасибо.,,Teşekkürler. -"Give you a hint. When I stop talking to you, you leave.",TXT_DLG_SCRIPT02_D63672_GIVEY,〃,,,"Dám ti radu: Když s tebou přestanu mluvit, znamená to odchod.","Jeg giver dig et hint. Når jeg holder op med at tale med dig, går du.","Hier mal ein Tipp. Wenn ich aufgehört habe mit dir zu reden, dann gehst du.",,"Jen konsilo: Kiam mi ĉesas paroli al vi, vi foriras.","Un consejo: Cuando dejo de hablarte, te vas.",,"Pienenä vinkkinä, että kun lakkaan puhumasta sinulle, sinä lähdet.","Petit conseil. Quand j'arrète de vous parler, vous sortez d'ici.","Csak egy tanács. Amikor már nem beszélek hozzád, húzz el.","Ti do un consiglio. Quando io smetto di parlare, tu vai via.",ヒントを出そう。話すのを止めたら去りたまえ。,"힌트를 하나 주지. 나랑 대화가 끝났으면, 넌 떠나는 거야.","Ik geef je een hint. Als ik niet meer met je praat, ga je weg.","Jeg skal gi deg et hint. Når jeg slutter å snakke med deg, drar du.",Dam ci wskazówkę. Jak przestanę mówić to wyjdź.,"Uma dica. Quando eu terminar de falar contigo, você vai embora.",,"Îți dau un sfat. Când termin de discutat cu tine, pleci.","Дам тебе подсказку: когда я закончу говорить, ты уходишь.",,"Sana bir ipucu vereyim. Seninle konuşmayı bıraktığımda, gideceksin." +(〃)",,,Díky.,Jeg vil ikke vide det. Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Kösz.,Grazie.,ありがとう。,고마워.,Bedankt.,Takk skal du ha.,Dzięki.,Agradeço.,,Mulțumesc.,Спасибо.,,Jag vill inte veta. Tack.,Teşekkürler. +"Give you a hint. When I stop talking to you, you leave.",TXT_DLG_SCRIPT02_D63672_GIVEY,〃,,,"Dám ti radu: Když s tebou přestanu mluvit, znamená to odchod.","Jeg giver dig et hint. Når jeg holder op med at tale med dig, går du.","Hier mal ein Tipp. Wenn ich aufgehört habe mit dir zu reden, dann gehst du.",,"Jen konsilo: Kiam mi ĉesas paroli al vi, vi foriras.","Un consejo: Cuando dejo de hablarte, te vas.",,"Pienenä vinkkinä, että kun lakkaan puhumasta sinulle, sinä lähdet.","Petit conseil. Quand j'arrète de vous parler, vous sortez d'ici.","Csak egy tanács. Amikor már nem beszélek hozzád, húzz el.","Ti do un consiglio. Quando io smetto di parlare, tu vai via.",ヒントを出そう。話すのを止めたら去りたまえ。,"힌트를 하나 주지. 나랑 대화가 끝났으면, 넌 떠나는 거야.","Ik geef je een hint. Als ik niet meer met je praat, ga je weg.","Jeg skal gi deg et hint. Når jeg slutter å snakke med deg, drar du.",Dam ci wskazówkę. Jak przestanę mówić to wyjdź.,"Uma dica. Quando eu terminar de falar contigo, você vai embora.",,"Îți dau un sfat. Când termin de discutat cu tine, pleci.","Дам тебе подсказку: когда я закончу говорить, ты уходишь.",,"Jag ger dig en ledtråd. När jag slutar prata med dig, går du.","Sana bir ipucu vereyim. Seninle konuşmayı bıraktığımda, gideceksin." Do you have good news for me? I'm all ears.,TXT_DLG_SCRIPT02_D65188_DOYOU,"〃 -(after completing ""bloody"" chore)",,,Máš pro mě dobré zprávy? Uši mám nastražené.,Har du gode nyheder til mig? Jeg er lutter ører.,Hast du gute Neuigkeiten für mich? Ich bin ganz Ohr.,,Ĉu vi alportas bonajn novaĵojn? Mi estas tute aŭskultema.,¿Tienes buenas noticias para mí? Soy todo oídos.,,Onko sinulla minulle hyviä uutisia? Olen pelkkänä korvana.,De bonnes nouvelles? Mes oreilles sont à vous.,Van valami jó híred számomra? Csupa fül vagyok.,Hai buone notizie per me? Sono tutto orecchi...,私の耳に吉報を伝えに来たかね?,날 위한 좋은 소식이 있나? 열심히 듣고 있다구.,Heb je goed nieuws voor mij? Ik ben een en al oor.,Har du gode nyheter til meg? Jeg er lutter øre.,Masz dobre wieści dla mnie? Zamieniam się w słuch.,Alguma notícia boa pra mim? Sou todo ouvidos.,,Ai vești bune pentru mine? Sunt numai urechi.,Есть для меня хорошие новости? Слушаю во все уши.,,Benim için iyi haberlerin var mı? Can kulağıyla dinliyorum. +(after completing ""bloody"" chore)",,,Máš pro mě dobré zprávy? Uši mám nastražené.,Har du gode nyheder til mig? Jeg er lutter ører.,Hast du gute Neuigkeiten für mich? Ich bin ganz Ohr.,,Ĉu vi alportas bonajn novaĵojn? Mi estas tute aŭskultema.,¿Tienes buenas noticias para mí? Soy todo oídos.,,Onko sinulla minulle hyviä uutisia? Olen pelkkänä korvana.,De bonnes nouvelles? Mes oreilles sont à vous.,Van valami jó híred számomra? Csupa fül vagyok.,Hai buone notizie per me? Sono tutto orecchi...,私の耳に吉報を伝えに来たかね?,날 위한 좋은 소식이 있나? 열심히 듣고 있다구.,Heb je goed nieuws voor mij? Ik ben een en al oor.,Har du gode nyheter til meg? Jeg er lutter øre.,Masz dobre wieści dla mnie? Zamieniam się w słuch.,Alguma notícia boa pra mim? Sou todo ouvidos.,,Ai vești bune pentru mine? Sunt numai urechi.,Есть для меня хорошие новости? Слушаю во все уши.,,Har du goda nyheter till mig? Jag är alldeles nyfiken.,Benim için iyi haberlerin var mı? Can kulağıyla dinliyorum. The deed is done!,TXT_RPLY0_SCRIPT02_D65188_THEDE,"〃 -(〃)",,,Skutek je dokonán!,Det er gjort!,Es ist geschehen!,,Interkonsento plenumita!,¡El trato está hecho!,,Se on tehty!,C'est bel est bien fait.,Véghezvittem a büntettet.,È fatta!,やることはヤった,임무 완료!,De daad is gedaan!,Gjerningen er utført!,Wszystko zrobione!,Está feito!,,Fapta e făcută.,Дело сделано!,,İş tamamdır! +(〃)",,,Skutek je dokonán!,Det er gjort!,Es ist geschehen!,,Interkonsento plenumita!,¡El trato está hecho!,,Se on tehty!,C'est bel est bien fait.,Véghezvittem a büntettet.,È fatta!,やることはヤった,임무 완료!,De daad is gedaan!,Gjerningen er utført!,Wszystko zrobione!,Está feito!,,Fapta e făcută.,Дело сделано!,,Det är gjort!,İş tamamdır! "Oh, I just love souvenirs. Here, this will get you into the prison. Talk to Warden Montag. Whatever you do after that, I don't want to know.",TXT_DLG_SCRIPT02_D66704_OHIJU,"〃 (〃)",,,"Ó, já prostě zbožňuju suvenýry. Tady, tohle tě dostane do vězení. Promluv si s dozorčím Montagem. Co máš v plánu dělat po tom, to už vědět nechci.","Åh, jeg elsker bare souvenirs. Her, det her vil få dig ind i fængslet. Tal med fængselsinspektør Montag. Hvad du end gør efter det, vil jeg ikke vide det.","Oh, ich liebe Souvenirs. Hier, damit kommst du in das Gefängnis. Sprich mit Direktor Montag. Was du danach machen musst, weiß ich nicht.",,"Ha, mi ŝategas memoraĵojn. Havu ĉi tion, kio ebligos al vi eniri la malliberejon. Parolu kun la provoso Montag. Tion ajn, kion vi faros poste, mi ne volas scii.","Ah, me encantan los recuerdos. Ten, con esto podrás entrar en la prisión. Habla con el carcelero Montag. Lo que hagas después de eso no quiero saberlo.","Ah, me encantan los recuerdos. Toma, con esto vas a poder entrar a la prisión. Habla con el carcelero Montag. Lo que hagas después de eso no quiero saberlo.","Voi, kun minä rakastan matkamuistoja. Kas näin, pääset tällä vankilaan. Puhu vankilanjohtaja Montagin kanssa. Mitä teetkään sen jälkeen, en halua tietää.","Oh, j'adore les souvenirs. Voilà, ça vous laissera entrer dans la prison. Parlez au gardien Montag. Ce que vous faites après, je m'en fous complètement.","Oh, imádom az ajándékokat. Nesze, ezzel be fogsz tudni jutni a börtönbe. Beszélj Mondtag igazgatóval. Nem akarok tudni arról, mit teszel utána.","Ah, adoro i souvenir! Ecco qua, con questo potrai entrare nella prigione. Parla con Montag, il direttore del carcere. Quello che farai dopo, a me non interessa.","嬉しい手土産だ。では、これがあれば 刑務所に入れる。モンターグ所長と話すんだ。 -君がそこで何をしようが、私の管轄外だ。","오오, 난 기념품이 정말 좋아. 여기, 네가 원했던 감옥 통행증이야. 감옥으로 가서 몬탕 간수장에게 이야기해봐. 네가 어떤 짓을 저지르든, 그 후엔 절대로 알고 싶지 않아!","Oh, ik hou gewoon van souvenirs. Hier, dit zal je in de gevangenis brengen. Praat met directeur Montag. Wat je daarna ook doet, ik wil het niet weten.","Jeg elsker suvenirer. Denne får deg inn i fengselet. Snakk med fengselsdirektør Montag. Uansett hva du gjør etter det, vil jeg ikke vite det.","Oh, po prostu kocham pamiątki. Masz, to pozwoli ci wejść do więzienia. Pogadaj z Naczelnikiem Montagiem. Nie chcę wiedzieć co potem zrobisz.","Ah, eu simplesmente adoro suvenires. Tome, isto vai te ajudar a entrar na prisão. Fale com o carcereiro, Montag. O que você for fazer depois não me interessa.",,"Oh, ce mai ador suvenirurile. Aici, asta îți va permite să ajungi în interiorul închisorii. Vorbește cu gardianul Montag. Ce faci după aceea, nu vreau să știu.","О, как я люблю сувениры! Вот твой пропуск в тюрьму. Обратись к тюремщику Монтагу, а что ты будешь делать потом, я и знать не желаю.",,"Hatıra eşyalarına bayılırım. İşte, bu seni hapishaneye sokacak. Müdür Montag ile konuş. Ondan sonra ne yaparsan yap, bilmek istemiyorum." +君がそこで何をしようが、私の管轄外だ。","오오, 난 기념품이 정말 좋아. 여기, 네가 원했던 감옥 통행증이야. 감옥으로 가서 몬탕 간수장에게 이야기해봐. 네가 어떤 짓을 저지르든, 그 후엔 절대로 알고 싶지 않아!","Oh, ik hou gewoon van souvenirs. Hier, dit zal je in de gevangenis brengen. Praat met directeur Montag. Wat je daarna ook doet, ik wil het niet weten.","Jeg elsker suvenirer. Denne får deg inn i fengselet. Snakk med fengselsdirektør Montag. Uansett hva du gjør etter det, vil jeg ikke vite det.","Oh, po prostu kocham pamiątki. Masz, to pozwoli ci wejść do więzienia. Pogadaj z Naczelnikiem Montagiem. Nie chcę wiedzieć co potem zrobisz.","Ah, eu simplesmente adoro suvenires. Tome, isto vai te ajudar a entrar na prisão. Fale com o carcereiro, Montag. O que você for fazer depois não me interessa.",,"Oh, ce mai ador suvenirurile. Aici, asta îți va permite să ajungi în interiorul închisorii. Vorbește cu gardianul Montag. Ce faci după aceea, nu vreau să știu.","О, как я люблю сувениры! Вот твой пропуск в тюрьму. Обратись к тюремщику Монтагу, а что ты будешь делать потом, я и знать не желаю.",,"Jag älskar souvenirer. Här, den här tar dig in i fängelset. Prata med Warden Montag. Vad du än gör efter det vill jag inte veta.","Hatıra eşyalarına bayılırım. İşte, bu seni hapishaneye sokacak. Müdür Montag ile konuş. Ondan sonra ne yaparsan yap, bilmek istemiyorum." Fine by me.,TXT_RPLY0_SCRIPT02_D66704_FINEB,"〃 -(〃)",,,To je dobře.,Det er fint med mig.,Ist mir recht.,,Mi ne malkonsentas.,Por mí está bien.,,Sopii minulle.,Ca me convient.,Felőlem rendben van.,Per me va bene.,良好だ。,난 괜찮아.,Ik vind het prima.,Greit for meg.,"Jak dla mnie, w porządku.","Por mim, sem problemas.",,Mie-mi convine.,По рукам!,,Bana uyar. +(〃)",,,To je dobře.,Det er fint med mig.,Ist mir recht.,,Mi ne malkonsentas.,Por mí está bien.,,Sopii minulle.,Ca me convient.,Felőlem rendben van.,Per me va bene.,良好だ。,난 괜찮아.,Ik vind het prima.,Greit for meg.,"Jak dla mnie, w porządku.","Por mim, sem problemas.",,Mie-mi convine.,По рукам!,,Det är okej för mig.,Bana uyar. "So you're the fool who stole the chalice? I'm going to have you arrested as a rebel thief... Thereby enhancing my position with the Order. How does it feel to be an unwitting pawn? I'll give you a hint, it's gonna hurt. ",TXT_DLG_SCRIPT02_D68220_SOYOU,〃,,,"Tak ty jsi ten blázen, který ukradl kalich? Teď tě nechám zatknout jako rebelského zloděje... a tím si upevním svou pozici s Řádem. Jaký je to pocit, být bezděčnou figurkou? Dám ti radu: Bude to bolet.","Så du er det fjols, der stjal bægeret? Jeg vil få dig arresteret som oprørstyv... og derved forbedre min position i ordenen. Hvordan føles det at være en uvidende brik? Jeg skal give dig et hint, det kommer til at gøre ondt.","So, du bist also der Narr der den Kelch gestohlen hat? Ich werde dich als Dieb der Rebellen verhaften lassen und dadurch meine Position im Orden verbessern. Wie fühlt es sich an als ahnungslose Schachfigur? Ich geb' dir einen Tipp: Es wird wehtun.",,"Vi do estas la stultulo, kiu ŝtelis la kalikon, ĉu? Mi kaptos vin kiel ribelan ŝteliston, tiel mi plibonigos mian statuson kun La Ordono. Kiel vi sentas, ke vi estas nevola marioneto? Jen aludeto: tio doloros vin.","¿Así que tú eres el necio que ha robado el cáliz? Te capturaré como ladrón rebelde, mejorando así mi posición con La Orden. ¿Qué se siente ser un peón involuntario? Una pista: te dolerá.","¿Así que tú eres el tonto que se robó el cáliz? Te voy a capturar como ladrón rebelde, mejorando así mi posición con La Orden. ¿Qué se siente ser un peón involuntario? Una pista: te va a doler.","Vai sinä olet se houkka, joka varasti kalkin? Pidätytän sinut kapinallisvarkaana, siten parantaen asemaani Veljeskunnassa. Miltäpä tuntuu olla tahaton pelinappula? Annanpa vihjeen, se tulee sattumaan.","Vous êtes l'abruti qui a volé le calice? Maintenant il faut que je vous arrète comme voleur rebelle.. Ca va aider ma position dans l'Ordre. Comment ça fait d'être un pion ignorant? Petite idée, ça va faire mal.",Szóval te vagy az isten barma aki ellopta a kelyhet? Jól letartóztatlak mint lázadó tolvaj...ezzel megerősítve a pozíciómat a Rendben. Milyen érzés egy tudatlan parasztnak lenni? Adok egy tippet: marhára fájni fog.,"Quindi sei tu il folle che ha rubato il calice? Ti farò arrestare come un ladro ribelle... E così facendo salirò nei ranghi dell'Ordine. Come ci si sente ad essere un'inconsapevole pedina? Ti do un consiglio, farà male.","それで、お前が聖杯を盗んだ愚か者か? 私は反賊としてお前を逮捕するつもりだ... そうすればオーダーの地位は上がる。 捨て駒に成るというのはどんな感じだ? ヒントを教えよう、お前はもう助からない。","그래서 네가 그 성배를 훔친 바보로군? 반군 절도범으로 체포해주지... 오더에서의 내 위치도 올리는 겸. 모르는 사이에 장물아비가 된 기분이 어떤가? 힌트를 주지, 정말 아플 거야.","Dus jij bent de dwaas die de kelk heeft gestolen? Ik ga je laten arresteren als een rebellendief.... Daardoor verbeter ik mijn positie bij de Orde. Hoe voelt het om een onwetende pion te zijn? Ik zal je een hint geven, het gaat pijn doen.","Så du er idioten som stjal begeret? Jeg skal få deg arrestert som en opprørsk tyv... Og dermed styrke min posisjon i Ordenen. Hvordan føles det å være en uvitende brikke? Jeg skal gi deg et hint, det kommer til å gjøre vondt.","Więc... to ty jesteś tym głupcem, który ukradł kielich? Aresztuję cię jako złodzieja-buntownika... A tym samym zwiększając swe uznanie u Zakonu. Jakie to uczucie jak się jest nieświadomym pionkiem? Podpowiedź, będzie bolało.",Então você é o imbecil que roubou o cálice? Eu vou mandar prender você como um ladrão rebelde... E assim a minha posição na Ordem vai melhorar. Como se sente sendo um plebeu ignorante? Só pra te dar uma ideia: vai doer.,,"Deci tu ești prostul care a furat potirul? Te voi aresta, hoț rebel... Prin urmare avansând în rangurile Ordinului. Cum e să fii un pion neștiutor? Îți dau un indiciu, o șă doară.","Так это ты тот недоумок, что украл чашу? Я передам тебя Ордену, как вора повстанцев... Это укрепит мои отношения с ним. Каково чувствовать себя безмозглой пешкой? Дам тебе подсказку: очень больно! -",,"Demek kadehi çalan aptal sensin? Seni asi bir hırsız olarak tutuklatacağım. Böylece Tarikat'taki konumumu güçlendireceğim. Farkında olmadan bir piyon olmak nasıl bir duygu? Sana bir ipucu vereyim, acıtacak." -It sucks!,TXT_RPLY0_SCRIPT02_D68220_ITSUC,〃,,,Je to na hovno!,Det stinker!,Scheiße!,,Tio estas aĉa!,¡Apesta!,,Ihan syvältä!,Quelle merde!,Szopás!,È uno schifo!,クソが!,이거 정말 난감한데?,Het is klote!,Det suger!,Cholera!,Que merda!,,E nașpa!,Это отстой!,,Berbat bir şey! -For you it does.,TXT_RYES0_SCRIPT02_D68220_FORYO,〃,,,Pro tebe určitě.,For dig gør det.,Du steckst ganz tief drin.,,Por vi ja.,Para ti sí.,,"Kyllä, sinun tilanteesi.","Pour vous, en effet.","Igen, neked.",A te lo farà.,私もそう思う。,너한테는 더욱 그럴걸.,Voor jou wel.,For deg gjør det det.,Dla ciebie tak.,"Pra você, sim.",,"Pentru tine, cu siguranță.",Для тебя — да.,,Senin için öyle. -Harris promised me money!,TXT_RPLY1_SCRIPT02_D68220_HARRI,〃,,,Harris mi slíbil peníze!,Harris lovede mig penge!,Harris hat mir Geld versprochen!,,Harris promesis monon al mi!,¡Harris me prometió dinero!,,Harris lupasi minulle rahaa!,Harris m'a promis de l'argent!,Harris pénzt igért!,Harris mi ha promesso dei soldi!,ハリスは俺に金を渡すと約束したのに!,해리스는 내게 돈을 약속했어!,Harris beloofde me geld!,Harris lovet meg penger!,Harris obiecał mi pieniądze!,O Harris prometeu me pagar!,,Harris mi-a promis bani!,Харрис обещал мне деньги!,,Harris bana para sözü verdi! +",,"Så du är idioten som stal kalken? Jag ska låta arrestera dig som en upprorisk tjuv... och på så sätt förbättra min ställning i orden. Hur känns det att vara en ovetande bricka? Jag ska ge dig en ledtråd, det kommer att göra ont.","Demek kadehi çalan aptal sensin? Seni asi bir hırsız olarak tutuklatacağım. Böylece Tarikat'taki konumumu güçlendireceğim. Farkında olmadan bir piyon olmak nasıl bir duygu? Sana bir ipucu vereyim, acıtacak." +It sucks!,TXT_RPLY0_SCRIPT02_D68220_ITSUC,〃,,,Je to na hovno!,Det stinker!,Scheiße!,,Tio estas aĉa!,¡Apesta!,,Ihan syvältä!,Quelle merde!,Szopás!,È uno schifo!,クソが!,이거 정말 난감한데?,Het is klote!,Det suger!,Cholera!,Que merda!,,E nașpa!,Это отстой!,,Det suger!,Berbat bir şey! +For you it does.,TXT_RYES0_SCRIPT02_D68220_FORYO,〃,,,Pro tebe určitě.,For dig gør det.,Du steckst ganz tief drin.,,Por vi ja.,Para ti sí.,,"Kyllä, sinun tilanteesi.","Pour vous, en effet.","Igen, neked.",A te lo farà.,私もそう思う。,너한테는 더욱 그럴걸.,Voor jou wel.,For deg gjør det det.,Dla ciebie tak.,"Pra você, sim.",,"Pentru tine, cu siguranță.",Для тебя — да.,,För dig gör det det.,Senin için öyle. +Harris promised me money!,TXT_RPLY1_SCRIPT02_D68220_HARRI,〃,,,Harris mi slíbil peníze!,Harris lovede mig penge!,Harris hat mir Geld versprochen!,,Harris promesis monon al mi!,¡Harris me prometió dinero!,,Harris lupasi minulle rahaa!,Harris m'a promis de l'argent!,Harris pénzt igért!,Harris mi ha promesso dei soldi!,ハリスは俺に金を渡すと約束したのに!,해리스는 내게 돈을 약속했어!,Harris beloofde me geld!,Harris lovet meg penger!,Harris obiecał mi pieniądze!,O Harris prometeu me pagar!,,Harris mi-a promis bani!,Харрис обещал мне деньги!,,Harris lovade mig pengar!,Harris bana para sözü verdi! Too bad. The only thing you're getting is dead!,TXT_RYES1_SCRIPT02_D68220_TOOBA,〃,,,"Smůla. Jediné, co dostaneš, je smrt.","Det var ærgerligt. Det eneste, du får, er død!",Jammerschade. Das Einzige was du bekommen wirst ist der Tod!,,"Kiel domaĝe. Ĉio, kion vi havos estas morto!","Qué mal. ¡Lo único que tendrás es la muerte!","Qué mal. ¡Lo único que -vas a tener es la muerte!","Voi voi. Sen kyllä voin sinulle luvata, että kuolet!","C'est dommage. Tout ce que vous gagnez, c'est une mort rapide!","Sajna, inkább ólmot kapsz helyette!",Peccato. L'unica cosa che otterrai è la morte!,残念だな、お前にやれるものは死のみだ!,그거 안됐네. 네가 얻는 거라곤 죽음뿐이니까!,Wat jammer. Het enige dat je zult krijgen is de dood!,"Synd for deg. Det eneste du får, er død!",Szkoda. Jedyne co dostaniesz to śmierć!,Que pena. A única coisa que você vai receber é a morte!,,Păcat. Tot ceea ce primești e moarte!,"Увы. Всё, что ты получишь — это смерть!",,Çok yazık. Elde edeceğin tek şey ölüm! -"In a small world, word travels fast. I hear you just removed some obstacles from your path. Nice work. Are you interested in some more lucrative projects?",TXT_DLG_SCRIPT02_D69736_INASM,MAP02: Rowan.,,,"V malém světě se zprávy šíří rychle. Slyšel jsem, že sis právě odstranil z cesty pár překážek. Pěkná práce. Měl bys zájem o nějaké lukrativnější zakázky?","I en lille verden spreder ordet sig hurtigt. Jeg hører, at du lige har fjernet nogle forhindringer fra din vej. Godt arbejde. Er du interesseret i nogle mere lukrative projekter?","Mir sind da Gerüchte zu Ohren gekommen, dass du gerade ein paar Hindernisse aus dem Weg geräumt hast. Gute Arbeit. Bist du an lukrativeren Angeboten interessiert?",,"En malgranda mondo novaĵoj vojaĝas rapide. Mi aŭdis, ke vi ĵus forigis kelkajn obstaklojn de via vojo. Bone farite. Ĉu interesas vin partopreni pli lukrajn projektojn?","En un mundo pequeño, las noticias vuelan. He oido que acabas de quitarte un par de obstáculos de encima. Bien hecho. ¿Te interesaría participar en proyectos más lucrativos?","En un mundo pequeño, las noticias vuelan. Oí que acabas de quitarte un par de obstáculos de encima. Bien hecho. ¿Te interesaría participar en proyectos más lucrativos?","Pienessä maailmassa sana kiirii nopeasti. Sana kuuluu, että olet juuri poistanut esteitä tieltäsi. Hyvin tehty. Olisitko kiinnostunut tuottoisammista projekteista?","Dans un petit monde, les rumeurs courent vite. J'entends que vous avez.. enlevé certains obstacles de votre chemin. Bon travail. Vous seriez intéressé par des projets plus lucratifs?",Ilyen kis helyen gyorsan terjednek a hírek. Úgy hírlik eltávolítottál pár akadályt az utadból. Szép munka. Nem érdekel valami jövedelmezőbb projekt?,"In un piccolo mondo, le voci si spargono in fretta... Ho sentito che hai appena rimosso alcuni ostacoli dal tuo percorso. Ottimo lavoro. Sei interessato a progetti un pò più lucrativi?","この小さな世界では噂が広まるのは早いもんだ。 +vas a tener es la muerte!","Voi voi. Sen kyllä voin sinulle luvata, että kuolet!","C'est dommage. Tout ce que vous gagnez, c'est une mort rapide!","Sajna, inkább ólmot kapsz helyette!",Peccato. L'unica cosa che otterrai è la morte!,残念だな、お前にやれるものは死のみだ!,그거 안됐네. 네가 얻는 거라곤 죽음뿐이니까!,Wat jammer. Het enige dat je zult krijgen is de dood!,"Synd for deg. Det eneste du får, er død!",Szkoda. Jedyne co dostaniesz to śmierć!,Que pena. A única coisa que você vai receber é a morte!,,Păcat. Tot ceea ce primești e moarte!,"Увы. Всё, что ты получишь — это смерть!",,Det var synd. Det enda du får är en död!,Çok yazık. Elde edeceğin tek şey ölüm! +"In a small world, word travels fast. I hear you just removed some obstacles from your path. Nice work. Are you interested in some more lucrative projects?",TXT_DLG_SCRIPT02_D69736_INASM,MAP02: Rowan.,,,"V malém světě se zprávy šíří rychle. Slyšel jsem, že sis právě odstranil z cesty pár překážek. Pěkná práce. Měl bys zájem o nějaké lukrativnější zakázky?","I en lille verden spreder ordet sig hurtigt. Jeg hører, at du lige har fjernet nogle forhindringer fra din vej. Godt arbejde. Er du interesseret i nogle mere lukrative projekter?","Mir sind da Gerüchte zu Ohren gekommen, dass du gerade ein paar Hindernisse aus dem Weg geräumt hast. Gute Arbeit. Bist du an lukrativeren Angeboten interessiert?",,"En malgranda mondo novaĵoj vojaĝas rapide. Mi aŭdis, ke vi ĵus forigis kelkajn obstaklojn de via vojo. Bone farite. Ĉu interesas vin partopreni pli lukrajn projektojn?",El mundo es un pañuelo y las noticias vuelan. He oido que acabas de quitarte un par de obstáculos de encima. Bien hecho. ¿Te interesaría participar en proyectos más lucrativos?,El mundo es un pañuelo y las noticias vuelan. Oí que acabas de quitarte un par de obstáculos de encima. Bien hecho. ¿Te interesaría participar en proyectos más lucrativos?,"Pienessä maailmassa sana kiirii nopeasti. Sana kuuluu, että olet juuri poistanut esteitä tieltäsi. Hyvin tehty. Olisitko kiinnostunut tuottoisammista projekteista?","Dans un petit monde, les rumeurs courent vite. J'entends que vous avez.. enlevé certains obstacles de votre chemin. Bon travail. Vous seriez intéressé par des projets plus lucratifs?",Ilyen kis helyen gyorsan terjednek a hírek. Úgy hírlik eltávolítottál pár akadályt az utadból. Szép munka. Nem érdekel valami jövedelmezőbb projekt?,"In un piccolo mondo, le voci si spargono in fretta... Ho sentito che hai appena rimosso alcuni ostacoli dal tuo percorso. Ottimo lavoro. Sei interessato a progetti un pò più lucrativi?","この小さな世界では噂が広まるのは早いもんだ。 あんたが素早く厄介事を片付けたと聞いたぞ。 もっと儲かる仕事をやってみる気はないかね?","이처럼 작은 세상엔, 소문이 빨리 전해지지. 방금 자네가 장애물들을 처리한 걸 들었다네. 수고했어. 수익이 아주 짭짤한 일자리에 관심이 있나? -",In een kleine wereld gaat het woord snel. Ik hoor dat je net wat obstakels van je pad hebt verwijderd. Goed werk. Ben je geïnteresseerd in wat lucratievere projecten?,I en liten verden sprer rykter seg fort. Jeg hører du har fjernet noen hindringer fra veien din. Bra jobbet. Er du interessert i flere lukrative prosjekter?,"W małym świecie wieści szybko się rozchodzą. Usłyszałem, że właśnie usunąłeś parę rzeczy ze swojej drogi. Dobra robota. Jesteś zainteresowany jakimiś bardziej korzystnymi projektami?","Neste mundo pequeno, as notícias viajam rápido. Fiquei sabendo que você tirou alguns obstáculos de seu caminho. Bom trabalho. Está interessado em alguns projetos mais lucrativos?",,"Într-o lume mică, vorba circulă repede. Aud că tocmai ai înlăturat niște obstacole din drum. Bună treabă. Mai ești interesat de alte proiecte profitabile?","Мир тесен, и новости разлетаются быстро. Я слышал, как ты только что убрал пару препятствий со своего пути. Хорошая работа. Заинтересован в более прибыльных занятиях?",,"Küçük bir dünyada, laf çabuk yayılır. Yolundaki bazı engelleri kaldırdığını duydum. İyi iş çıkardın. Daha kazançlı projelerle ilgileniyor musun?" -"Sure, why not.",TXT_RPLY0_SCRIPT02_D69736_SUREW,〃,,,"Klidně, proč ne.","Selvfølgelig, hvorfor ikke.","Sicher, warum nicht.",,"Jes, kial ne?","Por supuesto, ¿por qué no?","Claro, ¿por qué no?",Miksipä ei.,"Ouais, pourquoi pas.","Persze, miért is ne.","Certo, perché no.",ああ、もちろんだ。,그거 좋군요.,"Tuurlijk, waarom niet.","Ja, hvorfor ikke.","Jasne, czemu nie.","Claro, por que não?",,"Da, de ce nu.","Конечно, почему бы и нет.",,"Elbette, neden olmasın." -No thanks.,TXT_RPLY1_SCRIPT02_D69736_NOTHA,〃,,,"Ne, díky.",Nej tak.,Nein danke.,,"Ne, dankon.","No, gracias.",,Ei kiitos.,Non merci.,Nem kösz.,"No, grazie.",やめとくよ。,필요 없어요.,"Nee, dank je wel.",Nei takk.,"Nie, dziękuję.","Não, obrigado.",,Nu mulțumesc.,"Нет, спасибо.",,"Hayır, teşekkürler." -Then get lost!,TXT_RYES1_SCRIPT02_D69736_THENG,,,,Tak vypadni!,Så forsvind!,Dann verzieh dich!,,Tiuokaze malaperu!,¡Entonces piérdete!,,Sitten häivy!,Alors dégage!,Akkor húzz el innen!,E allora sparisci!,じゃあ失せるんだな!,그럼 꺼져!,Dan verdwalen!,Så stikk!,W takim razie spadaj!,Então suma daqui!,,Atunci valea!,Тогда проваливай!,,O zaman kaybol! +",In een kleine wereld gaat het woord snel. Ik hoor dat je net wat obstakels van je pad hebt verwijderd. Goed werk. Ben je geïnteresseerd in wat lucratievere projecten?,I en liten verden sprer rykter seg fort. Jeg hører du har fjernet noen hindringer fra veien din. Bra jobbet. Er du interessert i flere lukrative prosjekter?,"W małym świecie wieści szybko się rozchodzą. Usłyszałem, że właśnie usunąłeś parę rzeczy ze swojej drogi. Dobra robota. Jesteś zainteresowany jakimiś bardziej korzystnymi projektami?","Neste mundo pequeno, as notícias viajam rápido. Fiquei sabendo que você tirou alguns obstáculos de seu caminho. Bom trabalho. Está interessado em alguns projetos mais lucrativos?",,"Într-o lume mică, vorba circulă repede. Aud că tocmai ai înlăturat niște obstacole din drum. Bună treabă. Mai ești interesat de alte proiecte profitabile?","Мир тесен, и новости разлетаются быстро. Я слышал, как ты только что убрал пару препятствий со своего пути. Хорошая работа. Заинтересован в более прибыльных занятиях?",,I en liten värld går ryktet fort. Jag hörde att du just avlägsnade några hinder från din väg. Bra jobbat. Är du intresserad av några mer lukrativa projekt?,"Küçük bir dünyada, laf çabuk yayılır. Yolundaki bazı engelleri kaldırdığını duydum. İyi iş çıkardın. Daha kazançlı projelerle ilgileniyor musun?" +"Sure, why not.",TXT_RPLY0_SCRIPT02_D69736_SUREW,〃,,,"Klidně, proč ne.","Selvfølgelig, hvorfor ikke.","Sicher, warum nicht.",,"Jes, kial ne?","Por supuesto, ¿por qué no?","Claro, ¿por qué no?",Miksipä ei.,"Ouais, pourquoi pas.","Persze, miért is ne.","Certo, perché no.",ああ、もちろんだ。,그거 좋군요.,"Tuurlijk, waarom niet.","Ja, hvorfor ikke.","Jasne, czemu nie.","Claro, por que não?",,"Da, de ce nu.","Конечно, почему бы и нет.",,"Visst, varför inte.","Elbette, neden olmasın." +No thanks.,TXT_RPLY1_SCRIPT02_D69736_NOTHA,〃,,,"Ne, díky.",Nej tak.,Nein danke.,,"Ne, dankon.","No, gracias.",,Ei kiitos.,Non merci.,Nem kösz.,"No, grazie.",やめとくよ。,필요 없어요.,"Nee, dank je wel.",Nei takk.,"Nie, dziękuję.","Não, obrigado.",,Nu mulțumesc.,"Нет, спасибо.",,Nej tack.,"Hayır, teşekkürler." +Then get lost!,TXT_RYES1_SCRIPT02_D69736_THENG,,,,Tak vypadni!,Så forsvind!,Dann verzieh dich!,,Tiuokaze malaperu!,¡Entonces piérdete!,,Sitten häivy!,Alors dégage!,Akkor húzz el innen!,E allora sparisci!,じゃあ失せるんだな!,그럼 꺼져!,Dan verdwalen!,Så stikk!,W takim razie spadaj!,Então suma daqui!,,Atunci valea!,Тогда проваливай!,,Försvinn då!,O zaman kaybol! "Fool! Guards, rid me of this meddlesome peon.",TXT_DLG_SCRIPT02_D71252_FOOLG,Rowan.,,,"Blázne! Stráže, zbavte se tohohle zbytečného nuzáka.","Fjols! Vagter, befri mig for denne uopmærksomme bondeknold.","Du Narr! Wachen, entledigt mich dieses lästigen Tagelöhners.",,"Stultulo! Gardistoj, liberigu min de ĉi tiu entrudiĝema peono.","¡Insensato! Guardias, libérenme de este entrometido peón.","¡Tonto! Guardias, libérenme de este entrometido peón.","Sinä mieletön! Vartijat, hankkiutukaa eroon tästä tungettelevasta moukasta.","Idiot! Gardes, débarassez-moi de ce pion embêtant!","Barom! Őrök, takarítsátok el a színem elől ezt a kotnyeleskedő pondrót!","Sciocco! Guardie, liberatemi da questo ficcanaso.","なんと愚かな! -衛兵、この厄介な奴を始末してくれ。","멍청한 것! 경비병, 이 걸리적거리는 난동꾼을 치워라.","Dwaas! Bewakers, bevrijd me van deze bemoeizuchtige pioen.","Idiot! Vakter, kvitt meg med denne innpåslitne trellen.","Głupcze! Straż, uwolnijcie mnie od tego wścibskiego robola.","Idiota! Guardas, tirem esse peão intrometido daqui.",,"Prostule! Gardieni, scăpați-mă de acest pion băgăreț.","Глупец! Стража, избавьте меня от этого недоумка.",,"Aptal! Muhafızlar, beni bu işgüzar piyondan kurtarın." +衛兵、この厄介な奴を始末してくれ。","멍청한 것! 경비병, 이 걸리적거리는 난동꾼을 치워라.","Dwaas! Bewakers, bevrijd me van deze bemoeizuchtige pioen.","Idiot! Vakter, kvitt meg med denne innpåslitne trellen.","Głupcze! Straż, uwolnijcie mnie od tego wścibskiego robola.","Idiota! Guardas, tirem esse peão intrometido daqui.",,"Prostule! Gardieni, scăpați-mă de acest pion băgăreț.","Глупец! Стража, избавьте меня от этого недоумка.",,"Dumbom! Vakter, gör mig av med den här besvärliga pingsten.","Aptal! Muhafızlar, beni bu işgüzar piyondan kurtarın." "Good. Some uh, friends of mine need someone silenced. Beldin is being held by the Order in their sanctuary. There's a rarely used entrance by a small pier off the river which is unguarded. Get in, shut him up, and bring his ring back to me as proof.",TXT_DLG_SCRIPT02_D72768_GOODS,〃,,,"Dobře. Někteří mí... přátelé potřebují někoho umlčet. Beldin je držen Řádem v jejich svatyni. Na malém molu u řeky je málo používaný vchod, který nikdo nehlídá. Dostaň se dovnitř, umlč ho a přines mi jeho prsten jako důkaz.","Godt. Nogle af mine venner har brug for at få nogen til at tie stille. Beldin bliver tilbageholdt af Ordenen i deres fristed. Der er en sjældent brugt indgang ved en lille mole ud for floden, som er ubevogtet. Gå ind, luk munden på ham, og giv mig hans ring som bevis.","Gut. Einige, äh, Freunde von mir müssen zum Schweigen gebracht werden. Beldin wird vom Orden im Heiligtum gefangen gehalten. Es gibt dort einen selten benutzen Eingang bei einem kleinen Pier am Fluss, welcher unbewacht ist. Geh rein, mach ihn kalt und bringe mir seinen Ring als Beweis zurück.",,"Bone. Kelkaj... hm, amikoj bezonas silentemulon. Beldin estas retenita en la sanktejo de La Ordono. Estas malofte uzata enirejo ĉe malgranda kajo sen viglado apud la rivero. Eniru tien, silentigu lin kaj alportu lian ringon kiel pruvon.","Bien. Algunos... este, amigos míos necesitan a alguien sigiloso. Beldin es retenido por La Orden en su santuario. Hay una entrada rara vez utilizada por un pequeño muelle junto al río que está sin vigilancia. Entra, cállalo y tráeme su anillo como prueba.",,"Hyvä. Eräät, öh, ystäväni kaipaavat erään henkilön hiljentämistä. Veljeskunta pitää Beldiniä vankinaan pyhäkössään. Jokea vierustavalta vartioimattomalta pikkulaiturilta on harvoin käytetty sisäänkäynti. Mene sisään, vaienna hänet ja tuo hänen sormuksensa takaisin todisteena.","Bien. Certains... amis à moi demandent à ce que quelqu'un arrète de parler. Beldin est retenu par l'Ordre dans leur sanctuaire. Il y a une entrée rarement utilisée près d'un ponton près de la rivière qui n'est pas gardée. Entrez, coupez-lui le sifflet et ramenez moi son anneau comme preuve.","Kiváló. Néhány barátom el akar valakit némítani. Beldint a Rend szentélyében tartják fogva. Van egy ritkán használt bejárat egy kis mólónál, amit nem védenek katonák. Hatolj be, csitícsd el örökre, és hozdd el a gyűrűjét bizonyítékként.","Ottimo. Alcuni uh, amici miei hanno bisogno che qualcuno venga messo a tacere. Beldin è sotto custodia dell'Ordine nel loro santuario. C'è un ingresso poco utilizzato e non sorvegliato tramite un piccolo molo accanto al fiume. Entra, fallo tacere, e portami il suo anello come prova.","それでいい。ええと、私の友人がある人物を 黙らせて欲しいと望んでいるんだ。 ベルディンはオーダーの連中の聖域に 囚われている。建物への入り口は川に掛かった 桟橋の先にあり、そこは誰も警備してないし ほぼ使われていない。潜入してヤツを黙らせて、 -仕事をした証拠としてヤツの指輪を見せてくれ。","좋구만... 그래서, 내 지인이 말하기를 벨딘이라는 사람의 입을 다물게 만들라는군. 그는 지금 오더에 의해 성소에 감금됐네. 그 근처 강가에 있는 작은 부두 옆에 자주 쓰이지 않는 입구가 있다네. 거기로 향해서, 그의 입을 막게. 그리고 그의 반지를 증거로 가져오게.","Goed. Sommige uh, vrienden van mij hebben iemand nodig die het zwijgen oplegt. Beldin wordt vastgehouden door de Orde in hun heiligdom. Er is een zelden gebruikte ingang bij een kleine pier van de rivier die onbewaakt is. Stap in, sluit hem op en breng zijn ring terug als bewijs.","Fint. Noen venner av meg trenger å få noen til å tie. Beldin holdes av Ordenen i deres helligdom. Det er en sjelden brukt inngang ved en liten brygge ved elven som er ubevoktet. Gå inn, få ham til å holde kjeft, og gi meg ringen hans som bevis.","Dobrze. Paru moich... ehmm... przyjaciół potrzebuje kogoś uciszyć. Beldin jest trzymany przez Zakon w ich sanktuarium. Jest tu gdzieś rzadko używane wejście przy małej przystani przy rzece, które jest niestrzeżone. Wejdź tam, ucisz go i przynieś mi jego pierścień jako dowód.","Ótimo. Alguns hã... amigos meus precisam silenciar alguém. Beldin foi detido pela Ordem no santuário deles. Há uma entrada pouco usada perto de um pequeno pier pelo rio que está sem guardas. Entre lá, cale a boca dele e traga o seu anel de volta pra mim como prova.",,"Bun. Niște um... prieteni de-ai mei au nevoie de cineva redus la tăcere. Beldin e ținut de Ordin în sanctuarul lor. E o intrare rar folosită pe niște chei lângă râu care e nepăzită. Intră, fă-l să tacă pe veci, și adu-mi inelul lui ca dovadă.","Хорошо. Некоторые мои, э-э-э, приятели, хотят, чтобы кое-кто замолчал. Орден держит Белдина в своём святилище. У небольшого пира рядом с рекой есть редко используемый вход, что не охраняется. Проберись внутрь, заставь его замолчать навсегда и принеси мне его кольцо в качестве доказательства.",,"Güzel. Bazı arkadaşlarımın birinin susturulmasına ihtiyacı var. Beldin, Tarikat tarafından sığınaklarında tutuluyor. Nehir kıyısındaki küçük iskelede korumasız, nadiren kullanılan bir giriş var. İçeri gir, onu sustur ve yüzüğünü kanıt olarak bana geri getir." -Will it be worth the effort?,TXT_RPLY0_SCRIPT02_D72768_WILLI,〃,,,Bude mi to stát za to?,Vil det være indsatsen værd?,Wird es die Mühe denn wert sein?,,Ĉu la strebo estos valora?,¿Valdrá la pena el esfuerzo?,¿Va a valer la pena el esfuerzo?,Onko väärti vaivannäköni?,Est-ce que ça en vaudra l'effort?,Megéri az erőfeszítést?,Ne varrà la pena?,苦労に見合った報酬だろうな?,노력할만한 가치가 있나요?,Zal het de moeite waard zijn?,Er det verdt innsatsen?,Czy będzie to warte moich starań?,Será que vale a pena o esforço?,,O să merite efortul?,Оно того стоит?,,Bu çabaya değecek mi? +仕事をした証拠としてヤツの指輪を見せてくれ。","좋구만... 그래서, 내 지인이 말하기를 벨딘이라는 사람의 입을 다물게 만들라는군. 그는 지금 오더에 의해 성소에 감금됐네. 그 근처 강가에 있는 작은 부두 옆에 자주 쓰이지 않는 입구가 있다네. 거기로 향해서, 그의 입을 막게. 그리고 그의 반지를 증거로 가져오게.","Goed. Sommige uh, vrienden van mij hebben iemand nodig die het zwijgen oplegt. Beldin wordt vastgehouden door de Orde in hun heiligdom. Er is een zelden gebruikte ingang bij een kleine pier van de rivier die onbewaakt is. Stap in, sluit hem op en breng zijn ring terug als bewijs.","Fint. Noen venner av meg trenger å få noen til å tie. Beldin holdes av Ordenen i deres helligdom. Det er en sjelden brukt inngang ved en liten brygge ved elven som er ubevoktet. Gå inn, få ham til å holde kjeft, og gi meg ringen hans som bevis.","Dobrze. Paru moich... ehmm... przyjaciół potrzebuje kogoś uciszyć. Beldin jest trzymany przez Zakon w ich sanktuarium. Jest tu gdzieś rzadko używane wejście przy małej przystani przy rzece, które jest niestrzeżone. Wejdź tam, ucisz go i przynieś mi jego pierścień jako dowód.","Ótimo. Alguns hã... amigos meus precisam silenciar alguém. Beldin foi detido pela Ordem no santuário deles. Há uma entrada pouco usada perto de um pequeno pier pelo rio que está sem guardas. Entre lá, cale a boca dele e traga o seu anel de volta pra mim como prova.",,"Bun. Niște um... prieteni de-ai mei au nevoie de cineva redus la tăcere. Beldin e ținut de Ordin în sanctuarul lor. E o intrare rar folosită pe niște chei lângă râu care e nepăzită. Intră, fă-l să tacă pe veci, și adu-mi inelul lui ca dovadă.","Хорошо. Некоторые мои, э-э-э, приятели, хотят, чтобы кое-кто замолчал. Орден держит Белдина в своём святилище. У небольшого пира рядом с рекой есть редко используемый вход, что не охраняется. Проберись внутрь, заставь его замолчать навсегда и принеси мне его кольцо в качестве доказательства.",,"Jag är glad att du är här. Några av mina vänner behöver få någon tystad. Beldin hålls av orden i deras helgedom. Det finns en sällan använd ingång vid en liten brygga vid floden som är obevakad. Gå in, få tyst på honom och ge mig hans ring som bevis.","Güzel. Bazı arkadaşlarımın birinin susturulmasına ihtiyacı var. Beldin, Tarikat tarafından sığınaklarında tutuluyor. Nehir kıyısındaki küçük iskelede korumasız, nadiren kullanılan bir giriş var. İçeri gir, onu sustur ve yüzüğünü kanıt olarak bana geri getir." +Will it be worth the effort?,TXT_RPLY0_SCRIPT02_D72768_WILLI,〃,,,Bude mi to stát za to?,Vil det være indsatsen værd?,Wird es die Mühe denn wert sein?,,Ĉu la strebo estos valora?,¿Valdrá la pena el esfuerzo?,¿Va a valer la pena el esfuerzo?,Onko väärti vaivannäköni?,Est-ce que ça en vaudra l'effort?,Megéri az erőfeszítést?,Ne varrà la pena?,苦労に見合った報酬だろうな?,노력할만한 가치가 있나요?,Zal het de moeite waard zijn?,Er det verdt innsatsen?,Czy będzie to warte moich starań?,Será que vale a pena o esforço?,,O să merite efortul?,Оно того стоит?,,Kommer det att vara värt besväret?,Bu çabaya değecek mi? "I'll guarantee 50 gold and if you return without setting off every alarm in town, there's the chance to earn much, much more, and here's a little helper that should give you an edge.",TXT_DLG_SCRIPT02_D74284_ILLGU,〃,,,"Garantuji ti padesát zlatých a jestliže se vrátíš bez toho, abys spustil každý poplach ve městě, je tu šance vydělat si mnohem, mnohem víc. Tady je malý pomocník, který by ti měl pomoci.","Jeg garanterer dig 50 guld, og hvis du vender tilbage uden at udløse alle alarmer i byen, er der mulighed for at tjene meget, meget mere, og her er en lille hjælper, der burde give dig en fordel.","Ich garantiere dir 50 Gold und wenn du zurückkehrst ohne den Alarm in der Stadt ausgelöst zu haben, dann hast du noch die Chance, viel, viel mehr zu verdienen und hier ist noch ein kleiner Helfer der dir einen Vorteil verschaffen wird.",,"Mi garantias al vi 50 monerojn da oro, kaj se vi revenos sen ekagigi ĉiun alarmon en la urbo, estas eblo gajni multe, multe pliajn. Kaj jen malgranda «helpanto» por faciligi vian takson.","Te garantizo 50 de oro, y si vuelves sin activar todas las alarmas del pueblo, existe la posibilidad de ganar mucho, mucho más. Y aquí hay un pequeño ayudante que debería darte una ventaja.",,"Takaan sinulle 50 kultakolikkoa, ja jos palaat ilman, että soitatat jokaista kaupungin hälytyskelloa, voit mahdollisesti tienata paljon paljon enemmän. Tässä vielä pikkuapuri, jonka pitäisi antaa sinulle pienen kilpailuedun.","Je vous garantis 50 pièces et si vous revenez sans déclencher toutes les alarmes de la ville, vous avez la possibilité de gagner bien plus. Voilà une petite avance qui pourra vous aider.","50 arany garantáltan a markodat üti, és ha nem indítod be a riasztót a városban, akkor esélyed van többet is kapni, sokkal többet. Itt van egy kis segítség, hogy előnyhöz juss.","Ti garantisco 50 pezzi d'oro e se ritorni qua senza far scattare ogni allarme in città, ci sarà l'opportunità di guadagnare molto, molto di più, ed ecco qua anche un piccolo aggeggio che ti aiuterà.","50ゴールドは保証するし街の警報を鳴らさず 戻ってこれたら、もっと金を得られる機会が あるぞ。それと、お前の力となる物も渡そう。","만약 이 마을의 경보를 울리지 않고 조용히 완수하면 50 골드를 보상으로 주지. 이 외에도 더 많은 보상을 받을 수 있는 일들이 아주 많이 있다네. 그리고 여기, 모험에 도움이 될 만한 무기를 가져가게.","Ik garandeer 50 goud en als je terugkeert zonder elke alarmbel in de stad af te laten gaan, is er de kans om veel, veel meer te verdienen, en hier is een kleine helper die je een voordeel zou moeten geven.","Jeg garanterer 50 gull, og hvis du kommer tilbake uten å utløse alle alarmer i byen, kan du tjene mye, mye mer, og her er en liten hjelper som bør gi deg en fordel.","Gwarantuję 50 monet, a jeśli wrócisz bez włączania wszystkich alarmów w mieście, jest szansa, że mógłbyś dostać więcej. Znacznie więcej. Oto mały pomocnik, który da ci przewagę.","Garanto que você receberá 50 de ouro e se você retornar sem ativar todos os alarmes na cidade haverá uma chance de ganhar muito, muito mais. E aqui tem algo que pode te ajudar um pouco.",,"Garantez 50 de monezi de aur, și dacă nu declanșezi vreo alarmă în oraș, e o șansă de câștig mult, mult mai mare, iar aici e un mic ajutător care să-ți facă treaba mai ușoară.","Я обещаю тебе 50 золотых. И ты сможешь заработать куда больше, если выполнишь задание, не переполошив всю стражу в городе. А чтобы у тебя было некоторое преимущество, вот тебе небольшой помощник. -",,"50 altın garanti ediyorum ve eğer kasabadaki tüm alarmları çalıştırmadan geri dönerseniz, çok daha fazlasını kazanma şansınız var ve işte size avantaj sağlayacak küçük bir yardımcı." -"Thanks, I'll need it.",TXT_RPLY0_SCRIPT02_D74284_THANK,〃,,,"Díky, budu ho potřebovat.","Tak, jeg får brug for den.","Danke, das werde ich brauchen.",,Dankon. Mi bezonos ĝin.,Gracias. Lo necesitaré.,Gracais. Lo voy a necesitar.,"Kiitos, tarvitsen sitä.","Merci, j'en aurais besoin.","Köszönöm, kelleni is fog.","Grazie, ne avrò bisogno.",ありがとよ、これは後々必要になるな。,고마워요. 도움이 될 것 같습니다.,"Bedankt, ik zal het nodig hebben.","Takk, jeg trenger det.",Dzięki. Będę go potrzebował.,"Obrigado, vou precisar.",,"Merci, voi avea nevoie de el.",Спасибо. Он мне пригодится.,,"Teşekkürler, ihtiyacım olacak." -"Good. Remember, his silence is golden.",TXT_DLG_SCRIPT02_D75800_GOODR,〃,,,"Dobře. Pamatuj, že jeho mlčení má cenu zlata.","Godt. Husk, at hans tavshed er guld.",Gut. Denke dran. Sein Schweigen ist Gold wert.,,Bone. Memoru: lia silento estas el oro.,Bien. Recuerda: su silencio es de oro.,,"Hyvä. Muista, että hänen vaikenemisensa on kultaa.",Bien. Souvenez-vous. Le silence est d'or.,"Remek, a hallgatása arany.","Bene. Ricorda, il suo silenzio è d'oro.",いいぞ。覚えておけ、彼が沈黙したら金だ。,천만에. 그리고 기억하게. 그를 입막음하는 게 유일한 희망일세.,"Goed. Vergeet niet, zijn stilte is goud waard.",Bra. Husk at hans taushet er gull verdt.,"Dobrze. Pamiętaj, jego cisza jest cenna.","Ótimo. Lembre-se, o silêncio dele vale ouro.",,"Bun. Reține, tăcerea e de aur.","Превосходно. Запомни, его молчание — золото.",,"Güzel. Unutma, onun sessizliği altındır." -I'll get him.,TXT_RPLY0_SCRIPT02_D75800_ILLGE,〃,,,Dostanu ho.,Jeg henter ham.,Ich krieg ihn.,,Mi trovos lin.,Lo encontraré.,Lo voy a encontrar.,Saan hänet.,Je m'occupe de lui.,Elintézem.,Lo vado a prendere.,始末してみせる。,그를 잡겠어요.,Ik krijg hem wel.,Jeg skal ta ham.,Dorwę go.,Vou pegá-lo.,,O să-l aduc.,Я прикончу его.,,Onu yakalayacağım. -Mission accomplished? You have the ring of the traitor?,TXT_DLG_SCRIPT02_D77316_MISSI,〃,,,Mise splněna? Máš zrádcův prsten?,Mission fuldført? Har du forræderens ring?,Mission ausgeführt? Hast du den Ring des Verräters?,,Ĉu vi plenumis la mision? Ĉu vi havas la ringon de la perfidulo?,¿Misión cumplida? ¿Tienes el anillo del traidor?,,Tehtävä suoritettu? Sinulla on petturin sormus?,Mission accomplie? Vous avez l'anneau du traître?,Sikeres küldetés? Nálad van az áruló gyűrűje?,Missione compiuta? Hai l'anello del traditore?,"任務完了か? -あの裏切り者の指輪は持っているんだろうな?",임무를 완수 한 건가? 배신자의 반지를 가지고 있어?,Missie volbracht? Heb je de ring van de verrader?,Oppdrag utført? Har du forræderens ring?,Misja ukończona? Masz pierścień zdrajcy?,Missão cumprida? Está com o anel do traidor?,,Misiune îndeplinită? Ai inelul trădătorului?,Задание выполнено? Ты принёс кольцо предателя?,,Görev tamamlandı mı? Hainin yüzüğü sende mi? -"He's dead, where's my money?",TXT_RPLY0_SCRIPT02_D77316_HESDE,〃,,,"Je mrtvý, kde jsou moje peníze?","Han er død, hvor er mine penge?","Er ist tot, wo ist mein Geld?",,Mi mortigis lin. Kie estas mia mono?,Ya está muerto. ¿Y mi dinero?,,"Hän on kuollut, missä on rahani?","Il est mort, où est mon argent?","Meghalt, hol a pénzem?","Lui è morto, dove sono i miei soldi?",奴は死んだ、報酬はあるんだろうな?,"그는 죽었습니다, 제 보상은요?","Hij is dood, waar is mijn geld?","Han er død, hvor er pengene mine?",Jest martwy. Gdzie moje pieniądze?,"Ele está morto, cadê o meu dinheiro?",,"E mort, unde sunt banii?",Он мёртв. Где мои деньги?,,"O öldü, param nerede?" +",,"Jag garanterar 50 guld och om du återvänder utan att utlösa alla larm i staden finns chansen att tjäna mycket, mycket mer, och här är en liten hjälpreda som borde ge dig en fördel.","50 altın garanti ediyorum ve eğer kasabadaki tüm alarmları çalıştırmadan geri dönerseniz, çok daha fazlasını kazanma şansınız var ve işte size avantaj sağlayacak küçük bir yardımcı." +"Thanks, I'll need it.",TXT_RPLY0_SCRIPT02_D74284_THANK,〃,,,"Díky, budu ho potřebovat.","Tak, jeg får brug for den.","Danke, das werde ich brauchen.",,Dankon. Mi bezonos ĝin.,Gracias. Lo necesitaré.,Gracais. Lo voy a necesitar.,"Kiitos, tarvitsen sitä.","Merci, j'en aurais besoin.","Köszönöm, kelleni is fog.","Grazie, ne avrò bisogno.",ありがとよ、これは後々必要になるな。,고마워요. 도움이 될 것 같습니다.,"Bedankt, ik zal het nodig hebben.","Takk, jeg trenger det.",Dzięki. Będę go potrzebował.,"Obrigado, vou precisar.",,"Merci, voi avea nevoie de el.",Спасибо. Он мне пригодится.,,"Tack, jag kommer att behöva den.","Teşekkürler, ihtiyacım olacak." +"Good. Remember, his silence is golden.",TXT_DLG_SCRIPT02_D75800_GOODR,〃,,,"Dobře. Pamatuj, že jeho mlčení má cenu zlata.","Godt. Husk, at hans tavshed er guld.",Gut. Denke dran. Sein Schweigen ist Gold wert.,,Bone. Memoru: lia silento estas el oro.,Bien. Recuerda: su silencio es de oro.,,"Hyvä. Muista, että hänen vaikenemisensa on kultaa.",Bien. Souvenez-vous. Le silence est d'or.,"Remek, a hallgatása arany.","Bene. Ricorda, il suo silenzio è d'oro.",いいぞ。覚えておけ、彼が沈黙したら金だ。,천만에. 그리고 기억하게. 그를 입막음하는 게 유일한 희망일세.,"Goed. Vergeet niet, zijn stilte is goud waard.",Bra. Husk at hans taushet er gull verdt.,"Dobrze. Pamiętaj, jego cisza jest cenna.","Ótimo. Lembre-se, o silêncio dele vale ouro.",,"Bun. Reține, tăcerea e de aur.","Превосходно. Запомни, его молчание — золото.",,Bra. Kom ihåg att hans tystnad är av guld.,"Güzel. Unutma, onun sessizliği altındır." +I'll get him.,TXT_RPLY0_SCRIPT02_D75800_ILLGE,〃,,,Dostanu ho.,Jeg henter ham.,Ich krieg ihn.,,Mi trovos lin.,Lo encontraré.,Lo voy a encontrar.,Saan hänet.,Je m'occupe de lui.,Elintézem.,Lo vado a prendere.,始末してみせる。,그를 잡겠어요.,Ik krijg hem wel.,Jeg skal ta ham.,Dorwę go.,Vou pegá-lo.,,O să-l aduc.,Я прикончу его.,,Jag hämtar honom.,Onu yakalayacağım. +Mission accomplished? You have the ring of the traitor?,TXT_DLG_SCRIPT02_D77316_MISSI,〃,,,Mise splněna? Máš zrádcův prsten?,Mission fuldført? Har du forræderens ring?,Mission ausgeführt? Hast du den Ring des Verräters?,,Ĉu vi finis? Ĉu vi havas la ringon de la perfidulo?,¿Misión cumplida? ¿Tienes el anillo del traidor?,,Tehtävä suoritettu? Sinulla on petturin sormus?,Mission accomplie? Vous avez l'anneau du traître?,Sikeres küldetés? Nálad van az áruló gyűrűje?,Missione compiuta? Hai l'anello del traditore?,"任務完了か? +あの裏切り者の指輪は持っているんだろうな?",임무를 완수 한 건가? 배신자의 반지를 가지고 있어?,Missie volbracht? Heb je de ring van de verrader?,Oppdrag utført? Har du forræderens ring?,Misja ukończona? Masz pierścień zdrajcy?,Missão cumprida? Está com o anel do traidor?,,Misiune îndeplinită? Ai inelul trădătorului?,Задание выполнено? Ты принёс кольцо предателя?,,Uppdraget slutfört? Har du förrädarens ring?,Görev tamamlandı mı? Hainin yüzüğü sende mi? +"He's dead, where's my money?",TXT_RPLY0_SCRIPT02_D77316_HESDE,〃,,,"Je mrtvý, kde jsou moje peníze?","Han er død, hvor er mine penge?","Er ist tot, wo ist mein Geld?",,Mi mortigis lin. Kie estas mia mono?,Ya está muerto. ¿Y mi dinero?,,"Hän on kuollut, missä on rahani?","Il est mort, où est mon argent?","Meghalt, hol a pénzem?","Lui è morto, dove sono i miei soldi?",奴は死んだ、報酬はあるんだろうな?,"그는 죽었습니다, 제 보상은요?","Hij is dood, waar is mijn geld?","Han er død, hvor er pengene mine?",Jest martwy. Gdzie moje pieniądze?,"Ele está morto, cadê o meu dinheiro?",,"E mort, unde sunt banii?",Он мёртв. Где мои деньги?,,"Han är död, var är mina pengar?","O öldü, param nerede?" Liar! Go get the ring!,TXT_RNO0_SCRIPT02_D77316_LIARG,〃,,,Lháři! Jdi pro jeho prsten!,Løgner! Hent ringen!,Lügner! Hol' den Ring!,,"Ne mensongu! Forprenu lian ringon!","¡Mentiroso! ¡Ve a por el anillo!","¡Mentiroso! -¡Ve por el anillo!",Valehtelija! Mene hakemaan sormus!,Mensonges! Ramenez-moi l'anneau!,Hazug! Menj és szerezd meg a gyűrűt!,Bugiardo! Vai a prendere l'anello!,嘘をつくな、指輪を取ってこい!,거짓말쟁이! 가서 반지를 가져오게!,Leugenaar! Ga de ring halen!,Løgner! Hent ringen!,Kłamca! Idź po pierścień!,Mentiroso! Vá pegar o anel!,,Mincinos! Adu inelul!,Лжец! Принеси мне кольцо!,,Yalancı! Git yüzüğü al! +¡Ve por el anillo!",Valehtelija! Mene hakemaan sormus!,Mensonges! Ramenez-moi l'anneau!,Hazug! Menj és szerezd meg a gyűrűt!,Bugiardo! Vai a prendere l'anello!,嘘をつくな、指輪を取ってこい!,거짓말쟁이! 가서 반지를 가져오게!,Leugenaar! Ga de ring halen!,Løgner! Hent ringen!,Kłamca! Idź po pierścień!,Mentiroso! Vá pegar o anel!,,Mincinos! Adu inelul!,Лжец! Принеси мне кольцо!,,Lögnare! Hämta ringen!,Yalancı! Git yüzüğü al! "Here, you earned it. The traitor you killed was about to reveal the location of the Front. You saved lives. How would you like to earn more gold, and a future free from tyranny?",TXT_DLG_SCRIPT02_D78832_HEREY,〃,,,"Tady máš, zasloužil sis je. Zrádce, kterého jsi zabil, by vyzradil lokaci Fronty. Zachránil jsi životy. Jak by se ti líbilo vydělat si víc zlata spolu s budoucností bez tyranie?","Her, du har fortjent det. Den forræder, du dræbte, var ved at afsløre frontens placering. Du reddede liv. Hvad ville du sige til at tjene mere guld og en fremtid uden tyranni?","Hier, das hast du dir verdient. Der Verräter den du getötet hast war dabei über die Position der Front auszupacken. Du hast Leben gerettet. Wie würde es dir gefallen noch mehr Gold zu verdienen und eine tyrannenfreie Zukunft zu haben?",,"Jen ĝi, vi gajnis ĝin. La perfidulo, kiun vi mortigis, estis malkaŝonta la pozicion de la Fronto. Vi savis vivojn. Ĉu vi ŝatus gajni plian oron kaj estontecon liberan de tiranio?","Toma, te lo ganaste. El traidor que has matado estaba a punto de revelar la ubicación del Frente. Has salvado vidas. ¿Te gustaría ganar más oro y un futuro libre de tiranía?","Toma, te lo ganaste. El traidor que mataste estaba a punto de revelar la ubicación del Frente. Salvaste vidas. ¿Te gustaría ganar más oro y un futuro libre de tiranía?","Tässä, olet sen ansainnut. Tappamasi petturi oli lähellä paljastaa Rintaman sijainnin. Pelastit henkiä. Haluaisitko tienata lisää kultaa, ja tyranniasta vapaan tulevaisuuden?","Voilà, vous l'avez bien mérité. Ce traître que vous avez tué allait révéler la base du Front. Vous avez sauvé de nombreuses vies. Est-ce que ça vous intéresserait de vous faire plus d'argent et garantir un futur libre de la tyrannie?","Tessék, megérdemelted. Az áruló akit eltettél láb alól közel járt ahhoz, hogy felfedje a Front bázisát. Életeket mentettél. Mit szólnál ahhoz, ha még több arany is ütné a mancsod, és még egy zsarnok mentes jövőd is lenne?","Ecco qua, te li sei guadagnati. Il traditore che hai ucciso stava per rivelare il nascondiglio del Fronte. Hai salvato molte vite. Che ne diresti di guadagnare altro oro, e un futuro libero dalla tirannia?","よし、報酬はお前のものだ。お前が殺した あの裏切り者は、フロントの隠れ家をバラそうと していたんだ。おかげで大勢の命が救われた。 もっと多くの金と、奴等の支配から解放された -未来を得たいとは思わないか?",여기 보상일세. 그는 프론트의 비밀장소를 알리려던 참이었네. 자네가 우리들의 목숨을 구했어. 폭정을 타도해서 이처럼 더 많은 보상을 얻을 준비가 되어있나?,"Hier heb je het verdiend. De verrader die je vermoordde stond op het punt om de locatie van het Front te onthullen. Je hebt levens gered. Hoe zou je het vinden om meer goud te verdienen, en een toekomst vrij van tirannie?","Her, du har fortjent den. Forræderen du drepte var i ferd med å avsløre hvor Fronten er. Du reddet liv. Hva sier du til å tjene mer gull og en fremtid uten tyranni?","Masz, zasłużyłeś sobie. Zdrajca, którego zabiłeś zamierzał ujawnić gdzie znajduje się baza Frontu. Uratowałeś wiele żyć. Chcesz zarobić więcej pieniędzy i mieć przyszłość wolną od tyranii?","Tome, você merece. O traidor que você matou estava prestes a revelar a localização da Frente. Você salvou vidas. Que tal ganhar mais ouro e um futuro livre de tirania?",,"Aici, o meriți. Trădătorul pe care l-ai omorât urma să dezvăluie locația Frontului. Ai salvat vieți. Cum ai vrea să câștigi mai mult aur, și un viitor fără tiranie?","Вот, ты их заслужил. Убитый тобой предатель мог выдать Ордену местоположение базы Сопротивления. Ты спас много жизней. Тебе бы не хотелось ещё золота и будущего, свободного от тирании?",,"İşte, onu hak ettin. Öldürdüğün hain Cephe'nin yerini açıklamak üzereydi. Hayat kurtardın. Daha fazla altın ve zorbalıktan uzak bir gelecek kazanmaya ne dersin?" -Tell me more.,TXT_RPLY0_SCRIPT02_D78832_TELLM,〃,,,Řekni mi víc.,Fortæl mig mere.,Erzähl mir mehr.,,Mi aŭskultas vin.,Dime más.,,Kerro lisää.,Dites-moi en plus.,Mesélj még.,Dimmi di più.,もっと教えてくれ。,더 말해주시오.,Vertel me meer.,Fortell meg mer.,Mów dalej.,Me conte mais.,,Spune-mi mai multe.,Расскажи мне больше.,,Biraz daha anlat. -Not my style.,TXT_RPLY1_SCRIPT02_D78832_NOTMY,〃,,,To není můj styl.,Ikke min stil.,Nicht mein Stil.,,Tio ne estas mia stilo.,No es mi estilo.,,Ei kuulu tyyliini.,Pas mon genre.,Nem az Én stílusom.,Non fa per me.,俺の趣味じゃないな。,내 취향은 아닌데.,Niet mijn stijl.,Ikke min stil.,To nie w moim stylu.,Não faz o meu estilo.,,Nu-i genul meu.,Не в моём вкусе.,,Benim tarzım değil. +未来を得たいとは思わないか?",여기 보상일세. 그는 프론트의 비밀장소를 알리려던 참이었네. 자네가 우리들의 목숨을 구했어. 폭정을 타도해서 이처럼 더 많은 보상을 얻을 준비가 되어있나?,"Hier heb je het verdiend. De verrader die je vermoordde stond op het punt om de locatie van het Front te onthullen. Je hebt levens gered. Hoe zou je het vinden om meer goud te verdienen, en een toekomst vrij van tirannie?","Her, du har fortjent den. Forræderen du drepte var i ferd med å avsløre hvor Fronten er. Du reddet liv. Hva sier du til å tjene mer gull og en fremtid uten tyranni?","Masz, zasłużyłeś sobie. Zdrajca, którego zabiłeś zamierzał ujawnić gdzie znajduje się baza Frontu. Uratowałeś wiele żyć. Chcesz zarobić więcej pieniędzy i mieć przyszłość wolną od tyranii?","Tome, você merece. O traidor que você matou estava prestes a revelar a localização da Frente. Você salvou vidas. Que tal ganhar mais ouro e um futuro livre de tirania?",,"Aici, o meriți. Trădătorul pe care l-ai omorât urma să dezvăluie locația Frontului. Ai salvat vieți. Cum ai vrea să câștigi mai mult aur, și un viitor fără tiranie?","Вот, ты их заслужил. Убитый тобой предатель мог выдать Ордену местоположение базы Сопротивления. Ты спас много жизней. Тебе бы не хотелось ещё золота и будущего, свободного от тирании?",,"Här, du har förtjänat den. Förrädaren du dödade skulle avslöja var fronten finns. Du räddade liv. Hur skulle du vilja tjäna mer guld och en framtid fri från tyranni?","İşte, onu hak ettin. Öldürdüğün hain Cephe'nin yerini açıklamak üzereydi. Hayat kurtardın. Daha fazla altın ve zorbalıktan uzak bir gelecek kazanmaya ne dersin?" +Tell me more.,TXT_RPLY0_SCRIPT02_D78832_TELLM,〃,,,Řekni mi víc.,Fortæl mig mere.,Erzähl mir mehr.,,Mi aŭskultas vin.,Dime más.,,Kerro lisää.,Dites-moi en plus.,Mesélj még.,Dimmi di più.,もっと教えてくれ。,더 말해주시오.,Vertel me meer.,Fortell meg mer.,Mów dalej.,Me conte mais.,,Spune-mi mai multe.,Расскажи мне больше.,,Berätta mer.,Biraz daha anlat. +Not my style.,TXT_RPLY1_SCRIPT02_D78832_NOTMY,〃,,,To není můj styl.,Ikke min stil.,Nicht mein Stil.,,Tio ne estas mia stilo.,No es mi estilo.,,Ei kuulu tyyliini.,Pas mon genre.,Nem az Én stílusom.,Non fa per me.,俺の趣味じゃないな。,내 취향은 아닌데.,Niet mijn stijl.,Ikke min stil.,To nie w moim stylu.,Não faz o meu estilo.,,Nu-i genul meu.,Не в моём вкусе.,,Inte min stil.,Benim tarzım değil. "I have a business relationship with the Front's leader, Macil. I know he needs an incisive fellow like yourself, and he pays well. Take this recovered com unit and you'll be led to, shall we say, opportunities.",TXT_DLG_SCRIPT02_D80348_IHAVE,〃,,,"Mám obchodní vztah s vůdcem Fronty, Macilem. Vím, že potřebuje schopného člověka jako ty a dobře platí. Vem si tenhle spravený komunikátor; zavede tě k, řekněme, příležitostem.","Jeg har et forretningsmæssigt forhold til frontens leder, Macil. Jeg ved, han har brug for en skarp fyr som dig, og han betaler godt. Tag denne genvundne com-enhed, og du vil blive ført til, skal vi sige, muligheder.","Ich habe Geschäftsbeziehungen mit dem Anführer der Front, Macil. Er braucht einen pfiffigen Typen wie dich und er bezahlt gut. Nimm dieses erbeutete Kommunikationsgerät und es wird dich zu, sagen wir mal, Möglichkeiten führen.",,"Mi havas negoco-ligon kun Macil, la frontestro. Mi scias, ke li bezonas lertan kunulon kiel vi, aldone al tio, ke li pagas bone. Prenu ĉi tiun rekuperitan interfonon kaj vi havos la vojon al... ni diru, ŝancoj.","Tengo una relación de negocios con Macil, el líder del Frente. Sé que necesita un compañero hábil como tú, además de que paga bien. Toma este intercomunicador recuperado para que te guíe a... digamos, oportunidades.",,"Minulla on liikesuhteita Rintaman johtaja Maciliin. Tiedän hänen tarvitsevan kaltaistasi terävää kaveria, ja hän maksaa hyvin. Ota tämä talteenkerätty viestintälaite, ja tiesi johtaa, sanottaisiinko, mahdollisuuksien äärelle.","J'ai une relation d'affaires avec le leader du Front, Macil. Je sais qu'il a besoin de quelqu'un d'incisif comme vous, et il paye bien. Prenez ce communicateur avec vous, et vous serez mené à des.. on va dire des opportunités.","Van egy üzleti megállapodásom Macil-lal, a Front vezetőjével. pont egy ilyen belevaló embert keres mint te, és kiváló fizetést is adna. Használd ezt a kommunikációs egységet és - mondjuk úgy - odavezet a lehetőségekhez.","Ho dei rapporti d'affari col capo del Fronte, Macil. So che è alla ricerca di una persona diretta e precisa come te, e lui paga molto bene. Tieni questa unità di comunicazione che abbiamo recuperato, e sarai condotto verso, come dire, nuove opportunità.","私はフロントのリーダー、マシルと取引を しているんだ。彼は君のような切れる人物を 必要としていて、金払いも良い。 この修理された無線機を持っていけば、 -好機に出会えるだろう。","나는 프론트의 사령관, 마실과 깊은 관계를 가지고 있다네. 그리고 그는 자네를 비롯한 예리한 사람들을 원하고 말이지. 그리고 보상도 아주 잘 준다네. 이 수리된 통신기를 받고 이동하게나. 그럼 희망은 물론 기회가 아주 많아질 거야.","Ik heb een zakelijke relatie met de leider van het Front, Macil. Ik weet dat hij een scherpzinnige kerel als jij nodig heeft, en hij betaalt goed. Neem deze herstelde com-unit en u zult worden geleid tot, laten we zeggen, kansen.","Jeg har et forretningsforhold til Frontens leder, Macil. Jeg vet at han trenger en skarp fyr som deg, og han betaler godt. Ta denne gjenfunne kommunikasjonsenheten og du vil bli ledet til, skal vi si, muligheter.","Mam relacje biznesowe z dowódcą Frontu, Macilem. Wiem, że potrzebuje on kogoś z takim zapałem jak ty, i dobrze płaci. Weź ten komunikator, a poprowadzi cię do, powiedzmy, pewnych korzyści.","Tenho uma relação de negócios com o líder da Frente, Macil. Eu sei que ele anda precisando de um sujeito incisivo como você e ele paga bem. Leve este comunicador e você será conduzido para, digamos, oportunidades.",,"Fac afaceri cu liderul Frontului, Macil. Știu că are nevoie de băieți deștepți ca tine, și plătește bine. Ia acest emițător recuperat și vei fi dus, să zicem, spre oportunități.","Я веду дела c лидером повстанцев, Мэйсилом. Я знаю, что ему нужны толковые парни вроде тебя, и он неплохо платит. Возьми этот передатчик, и перед тобой откроются, скажем так, новые перспективы.",,"Cephe'nin lideri Macil ile bir iş ilişkim var. Senin gibi keskin zekalı bir adama ihtiyacı olduğunu biliyorum ve iyi para ödüyor. Bu kurtarılmış iletişim birimini alın ve size, diyelim ki, fırsatlar sunulacak." -Thanks.,TXT_RPLY0_SCRIPT02_D80348_THANK,〃,,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Kösz.,Grazie.,ありがとう。,알겠어요.,Bedankt.,Takk skal du ha.,Dzięki.,Obrigado.,,Mulțumesc.,Спасибо.,,Teşekkürler. +好機に出会えるだろう。","나는 프론트의 사령관, 마실과 깊은 관계를 가지고 있다네. 그리고 그는 자네를 비롯한 예리한 사람들을 원하고 말이지. 그리고 보상도 아주 잘 준다네. 이 수리된 통신기를 받고 이동하게나. 그럼 희망은 물론 기회가 아주 많아질 거야.","Ik heb een zakelijke relatie met de leider van het Front, Macil. Ik weet dat hij een scherpzinnige kerel als jij nodig heeft, en hij betaalt goed. Neem deze herstelde com-unit en u zult worden geleid tot, laten we zeggen, kansen.","Jeg har et forretningsforhold til Frontens leder, Macil. Jeg vet at han trenger en skarp fyr som deg, og han betaler godt. Ta denne gjenfunne kommunikasjonsenheten og du vil bli ledet til, skal vi si, muligheter.","Mam relacje biznesowe z dowódcą Frontu, Macilem. Wiem, że potrzebuje on kogoś z takim zapałem jak ty, i dobrze płaci. Weź ten komunikator, a poprowadzi cię do, powiedzmy, pewnych korzyści.","Tenho uma relação de negócios com o líder da Frente, Macil. Eu sei que ele anda precisando de um sujeito incisivo como você e ele paga bem. Leve este comunicador e você será conduzido para, digamos, oportunidades.",,"Fac afaceri cu liderul Frontului, Macil. Știu că are nevoie de băieți deștepți ca tine, și plătește bine. Ia acest emițător recuperat și vei fi dus, să zicem, spre oportunități.","Я веду дела c лидером повстанцев, Мэйсилом. Я знаю, что ему нужны толковые парни вроде тебя, и он неплохо платит. Возьми этот передатчик, и перед тобой откроются, скажем так, новые перспективы.",,"Jag har en affärsrelation med frontens ledare, Macil. Jag vet att han behöver en skarpsinnig kille som du, och han betalar bra. Ta den här återvunna kom-enheten och du kommer att ledas till, ska vi säga, möjligheter.","Cephe'nin lideri Macil ile bir iş ilişkim var. Senin gibi keskin zekalı bir adama ihtiyacı olduğunu biliyorum ve iyi para ödüyor. Bu kurtarılmış iletişim birimini alın ve size, diyelim ki, fırsatlar sunulacak." +Thanks.,TXT_RPLY0_SCRIPT02_D80348_THANK,〃,,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Kösz.,Grazie.,ありがとう。,알겠어요.,Bedankt.,Takk skal du ha.,Dzięki.,Obrigado.,,Mulțumesc.,Спасибо.,,Tack.,Teşekkürler. "Get going. If you hang around here, we're both dead.",TXT_DLG_SCRIPT02_D81864_GETGO,〃,,,"Měl bys jít. Jestli se tu budeš potloukat, jsme mrtví oba.","Kom i gang. Hvis du bliver hængende her, er vi begge døde.","Beweg dich. Wenn wir beide hier rumhängen, dann sind wir beide tot.",,"Ekmovu vin. Se vi restos ĉi tie, ni ambaŭ mortos.","Ponte en marcha. Si te quedas por aquí, los dos estamos muertos.",,"Jatka matkaasi. Jos viivyttelet täällä, kuolemme molemmat.","Partez maintenant, si vous traînez ici, nous serons morts tous les deux.","Mozgás! Ha sokáig lébucolsz itt, mindkettőnket megölnek.","Ti conviene andartene. Se bazzichi troppo qua, siamo entrambi morti.","うまくやれよ。こんな所でもたもたしていると -二人揃ってお陀仏だ。","어서 가게. 여기에 계속 있으면, 우리 둘 다 죽는다네.","Ga aan de slag. Als je hier rondhangt, zijn we allebei dood.","Sett i gang. Hvis du blir her, er vi begge døde.",Rusz się. Jak będziesz się tu kręcił to obaj będziemy martwi.,"Ande logo. Se você ficar por aqui, nós dois seremos mortos.",,"Timpul să pleci. Dacă mai stai pe-aici, o să fim amândoi morți.","Двигай. Если продолжишь тут ошиваться, нас обоих убьют.",,"Gidin hadi. Eğer burada takılırsan, ikimiz de ölürüz." +二人揃ってお陀仏だ。","어서 가게. 여기에 계속 있으면, 우리 둘 다 죽는다네.","Ga aan de slag. Als je hier rondhangt, zijn we allebei dood.","Sett i gang. Hvis du blir her, er vi begge døde.",Rusz się. Jak będziesz się tu kręcił to obaj będziemy martwi.,"Ande logo. Se você ficar por aqui, nós dois seremos mortos.",,"Timpul să pleci. Dacă mai stai pe-aici, o să fim amândoi morți.","Двигай. Если продолжишь тут ошиваться, нас обоих убьют.",,Sätt igång. Om du stannar här är vi båda döda.,"Gidin hadi. Eğer burada takılırsan, ikimiz de ölürüz." "A pity, but now that you know about my friends, I must kill you. Guards, take out this trash!",TXT_DLG_SCRIPT02_D83380_APITY,〃,,,"Škoda. Teď, když víš o mých známých, tě ale musím zabít. Stráže, zbavte mě tohohle smetí!","En skam, men nu hvor du kender til mine venner, må jeg slå dig ihjel. Vagter, tag det affald ud!","Ein Jammer, aber nun, da du über meine Freunde Bescheid weißt, muss ich dich umbringen. Wachen? Entsorgt ihn!",,"Nun kiam vi scias pri miaj amikoj, mi bedaŭrinde devas mortigi vin. Gardistoj, forprenu ĉi tiun rubon!","Una lástima, pero ahora que sabes de mis amigos, no me queda de otra que matarte. ¡Guardias, a sacar la basura!","Una pena, pero ahora que sabes de mis amigos, no me queda de otra que matarte. ¡Guardias, a sacar la basura!","Sääli, mutta nyt, kun tiedät ystävistäni, minun on tapettava sinut. Vartijat, heittäkää tämä roska ulos!","Dommage. Mais maintenant que vous savez qui sont mes amis, je dois me débarasser de vous. Garde, débarassez moi de mes ordures!","Kár érted, de sajnos miután kiderítetted a barátaim kilétét, meg kell hogy halj. Őrök, vigyétek ki ezt a szemetet!","Un vero peccato, ma ora che sai dei miei amici, non posso certo lasciarti vivo. Guardie, buttate via questa spazzatura!","残念だ、だがお前は私の友の事を知った以上 生きて帰す事はできない。 -衛兵、このゴミを片付けてくれ!","유감이군. 내 친구들을 이제 알고 있으니, 어쩔 수 없이 죽어줘야겠군. 경비병! 이 인간을 체포하라!","Jammer, maar nu je van mijn vrienden weet, moet ik je vermoorden. Bewakers, haal dit vuilnis eruit!","Synd, men nå som du vet om vennene mine, må jeg drepe deg. Vakter, ta ut dette søppelet!","Szkoda, ale skoro wiesz coś o moich przyjaciołach, muszę cię zabić. Straż, wyrzućcie tego śmiecia!","É uma pena, mas agora que você sabe sobre os meus amigos, preciso matar você. Guardas, levem esse lixo daqui!",,"Păcat, dar acum că-mi cunoști prietenii, voi fi nevoit să te omor. Gardieni, duceți gunoiul!","Жаль, но раз уж ты узнал о моих друзьях, мне придётся тебя убить. Стража, уберите его!",,"Yazık, ama artık arkadaşlarımı bildiğine göre, seni öldürmeliyim. Muhafızlar, şu çöpü dışarı çıkarın!" -Fool. Guards! Rid me of meddlesome peon.,TXT_DLG_SCRIPT02_D84896_FOOLG,〃,,,"Blázne! Stráže, zbavte se tohohle zbytečného nuzáka.",Fjols. Vagter! Fjern den besværlige bondeknold fra mig.,Du Narr! Wachen! Entledigt mich von diesem lästigen Tagelöhner.,,"Stultulo! Gardistoj, liberigu min de ĉi tiu entrudiĝema peono.","¡Insensato! Guardias, libérenme de este entrometido peón.","¡Tonto! Guardias, libérenme de este entrometido peón.",Järjetöntä. Vartijat! Hankkiutukaa eroon tästä tungettelevasta moukasta.,"Idiot! Gardes, débarassez-moi de ce pion embêtant!","Barom! Őrök, takarítsátok el a színem elől ezt a kotnyeleskedő pondrót!","Sciocco! Guardie, liberatemi da questo ficcanaso.","愚かな。 -衛兵!この厄介な奴を始末してくれ。","한심한 놈! 경비병, 이 소동피우는 불량배를 잡아라.",Dwaas. Bewakers! Verloste me van bemoeizuchtige pioen.,Idiot. Vakter! Kvitt meg med den innpåslitne bondetampen.,Głupcze! Straż! Uwolnijcie mnie od tego wścibskiego robola.,"Idiota! Guardas, tirem esse peão intrometido daqui.",,"Prostule! Gardieni, scăpați-mă de acest pion băgăreț.","Глупец! Стража, избавьте меня от этого недоумка.",,Aptal. Muhafızlar! Beni işgüzar piyondan kurtarın. -"Walk away, boy, just walk away.",TXT_DLG_SCRIPT02_D86412_WALKA,Geoff.,,,"Jdi pryč, chlapče, prostě odejdi.","Gå væk, dreng, bare gå væk.","Geh weg Jungchen, geh einfach weg.",,"Foriru, ulo. Vi nur foriru.","Vete, chaval. Solo vete.","Vete, muchacho. Solo vete.","Kävele pois vain, poju, kävele pois.","Pars, gamin, pars.","Csak sétálj el innen, sétálj el szépen.","Muoviti, ragazzo, muoviti...",どっか行け、若造、とっとと行け。,"지나가라고 친구, 그냥 지나가.","Loop weg, jongen, loop gewoon weg.","Gå vekk, gutt, bare gå vekk.","Odejdź stąd mały, po prostu odejdź.","Suma daqui, garoto. Apenas suma daqui.",,"Pleacă, băiete, pleacă.","Иди своей дорогой, парень, иди.",,"Yürü git evlat, yürü git." -What are you doing here?,TXT_DLG_SCRIPT02_D87928_WHATA,〃,,,Co ty tu děláš?,Hvad laver du her?,Was machst du hier?,,Kion vi volas ĉi tie?,¿Qué es lo que quieres?,,Mitäs sinä täällä teet?,Qu'est-ce que vous foutez ici?,Mit művelsz itt?,Che cosa fai qua?,ここで何をしている?,여기서 뭘 하는거야?,Wat doe jij hier?,Hva gjør du her?,Co ty tu robisz?,O que você está fazendo aqui?,,Ce cauți aici?,Что ты тут делаешь?,,Ne yapıyorsun burada? -"Hey, I need gold!",TXT_RPLY0_SCRIPT02_D87928_HEYIN,〃,,,"Hej, potřeboval bych zlato!","Hey, jeg har brug for guld!","Hey, ich brauche Gold!",,"Saluton, mi bezonas oron!","¡Buenas, necesito oro!",,"Hei, tarvitsen kultaa!","Hé, j'ai besoin de sous!","Héj, nekem arany kell!","Ehi, mi serve dell'oro!",よう、金が必要だ!,"이봐, 난 골드가 필요해!","Hé, ik heb goud nodig!",Jeg trenger gull!,"Hej, potrzebuję złota!","Ei, eu preciso de ouro!",,"Hei, am nevoie de aur!","Эй, мне нужно золото!",,"Hey, altına ihtiyacım var!" +衛兵、このゴミを片付けてくれ!","유감이군. 내 친구들을 이제 알고 있으니, 어쩔 수 없이 죽어줘야겠군. 경비병! 이 인간을 체포하라!","Jammer, maar nu je van mijn vrienden weet, moet ik je vermoorden. Bewakers, haal dit vuilnis eruit!","Synd, men nå som du vet om vennene mine, må jeg drepe deg. Vakter, ta ut dette søppelet!","Szkoda, ale skoro wiesz coś o moich przyjaciołach, muszę cię zabić. Straż, wyrzućcie tego śmiecia!","É uma pena, mas agora que você sabe sobre os meus amigos, preciso matar você. Guardas, levem esse lixo daqui!",,"Păcat, dar acum că-mi cunoști prietenii, voi fi nevoit să te omor. Gardieni, duceți gunoiul!","Жаль, но раз уж ты узнал о моих друзьях, мне придётся тебя убить. Стража, уберите его!",,"Synd, men nu när du vet om mina vänner måste jag döda dig. Vakter, ta ut det här skräpet!","Yazık, ama artık arkadaşlarımı bildiğine göre, seni öldürmeliyim. Muhafızlar, şu çöpü dışarı çıkarın!" +Fool. Guards! Rid me of meddlesome peon.,TXT_DLG_SCRIPT02_D84896_FOOLG,〃,,,"Blázne! Stráže, zbavte se tohohle zbytečného nuzáka.",Fjols. Vagter! Fjern den besværlige bondeknold fra mig.,Du Narr! Wachen! Entledigt mich von diesem lästigen Tagelöhner.,,"Stultulo! Gardistoj, liberigu min de ĉi tiu entrudiĝema peono.","¡Insensato! Guardias, libérenme de este entrometido peón.","¡Idiota! Guardias, libérenme de este entrometido peón.",Järjetöntä. Vartijat! Hankkiutukaa eroon tästä tungettelevasta moukasta.,"Idiot! Gardes, débarassez-moi de ce pion embêtant!","Barom! Őrök, takarítsátok el a színem elől ezt a kotnyeleskedő pondrót!","Sciocco! Guardie, liberatemi da questo ficcanaso.","愚かな。 +衛兵!この厄介な奴を始末してくれ。","한심한 놈! 경비병, 이 소동피우는 불량배를 잡아라.",Dwaas. Bewakers! Verloste me van bemoeizuchtige pioen.,Idiot. Vakter! Kvitt meg med den innpåslitne bondetampen.,Głupcze! Straż! Uwolnijcie mnie od tego wścibskiego robola.,"Idiota! Guardas, tirem esse peão intrometido daqui.",,"Prostule! Gardieni, scăpați-mă de acest pion băgăreț.","Глупец! Стража, избавьте меня от этого недоумка.",,Dumbom. Vakter! Befria mig från den besvärliga pingsten.,Aptal. Muhafızlar! Beni işgüzar piyondan kurtarın. +"Walk away, boy, just walk away.",TXT_DLG_SCRIPT02_D86412_WALKA,Geoff.,,,"Jdi pryč, chlapče, prostě odejdi.","Gå væk, dreng, bare gå væk.","Geh weg Jungchen, geh einfach weg.",,"Foriru, ulo. Vi nur foriru.","Vete, chaval. Solo vete.","Vete, muchacho. Solo vete.","Kävele pois vain, poju, kävele pois.","Pars, gamin, pars.","Csak sétálj el innen, sétálj el szépen.","Muoviti, ragazzo, muoviti...",どっか行け、若造、とっとと行け。,"지나가라고 친구, 그냥 지나가.","Loop weg, jongen, loop gewoon weg.","Gå vekk, gutt, bare gå vekk.","Odejdź stąd mały, po prostu odejdź.","Suma daqui, garoto. Apenas suma daqui.",,"Pleacă, băiete, pleacă.","Иди своей дорогой, парень, иди.",,"Gå iväg, pojke, bara gå iväg.","Yürü git evlat, yürü git." +What are you doing here?,TXT_DLG_SCRIPT02_D87928_WHATA,〃,,,Co ty tu děláš?,Hvad laver du her?,Was machst du hier?,,Kion vi volas ĉi tie?,¿Qué es lo que quieres?,,Mitäs sinä täällä teet?,Qu'est-ce que vous foutez ici?,Mit művelsz itt?,Che cosa fai qua?,ここで何をしている?,여기서 뭘 하는거야?,Wat doe jij hier?,Hva gjør du her?,Co ty tu robisz?,O que você está fazendo aqui?,,Ce cauți aici?,Что ты тут делаешь?,,Vad gör du här?,Ne yapıyorsun burada? +"Hey, I need gold!",TXT_RPLY0_SCRIPT02_D87928_HEYIN,〃,,,"Hej, potřeboval bych zlato!","Hey, jeg har brug for guld!","Hey, ich brauche Gold!",,"Saluton, mi bezonas oron!","¡Buenas, necesito oro!",,"Hei, tarvitsen kultaa!","Hé, j'ai besoin de sous!","Héj, nekem arany kell!","Ehi, mi serve dell'oro!",よう、金が必要だ!,"이봐, 난 골드가 필요해!","Hé, ik heb goud nodig!",Jeg trenger gull!,"Hej, potrzebuję złota!","Ei, eu preciso de ouro!",,"Hei, am nevoie de aur!","Эй, мне нужно золото!",,Jag behöver guld!,"Hey, altına ihtiyacım var!" "Blackbird told you the code, huh? Let me shut off the alarm. Macil is one flight down.",TXT_DLG_SCRIPT02_D89444_BLACK,〃,,,"Straka ti řekla heslo, co? Jen vypnu alarmy. Macil je o podlaží níž.","Blackbird fortalte dig koden, hva'? Lad mig slukke for alarmen. Macil er en etage længere nede.","Blackbird hat dir den Code gegeben, wie? Lass mich mal eben den Alarm abschalten. Macil ist eine Etage tiefer.",,"BlackBird diris la pasfrazon al vi, ĉu? Tiuokaze mi sensonorigos la alarmon. Macil estas malsupre.","Conque BlackBird te ha dado la clave, ¿eh? Ya apago la alarma, entonces. Macil está bajando las escaleras.","Así que BlackBird te dio la clave, ¿eh? Ya apago la alarma, entonces. Macil está bajando las escaleras.","Vai että Blackbird kertoi sinulle koodin? Anna, kun kytken hälyttimen pois päältä. Macil on yhdet rappuset alas.","Blackbird t'as donné le code, hein? Bon, laisse moi désactiver l'alarme. Macil est en bas des escaliers.","Feketerigó mondta el a kódot, mi? Hadd kapcosljam ki a riasztót. macil egy kőhajintásra van innen.","Blackbird ti ha detto qual'è il codice, eh? Fammi disattivare l'allarme. Macil è oltre le scale.","ブラックバードに教えてもらったんだな? -警報は切っておこう。マシルはこの先だ。","블랙버드가 암호를 알려줬나 보군? 흠, 그럼 경보를 꺼둬야겠군. 마실은 계단 저 밑에 있어.","Blackbird vertelde je de code, huh? Laat me de wekker uitzetten. Macil is een vlucht naar beneden.",Fortalte Blackbird deg koden? La meg slå av alarmen. Macil er en etasje ned.,"Blackbird podała ci hasło, co? Pozwól, że wyłączę alarm. Macil jest piętro niżej.","A Blackbird te passou o código, é? Deixa eu desligar o alarme. Macil está no andar debaixo.",,"Blackbird ți-a spus codul, huh? Permite-mi să opresc alarma, Macil e cu un etaj mai jos.","«Чёрный дрозд» сообщила тебе пароль, так? Давай я отключу сигнализацию. Мэйсил этажом ниже.",,"Karatavuk sana kodu söyledi, ha? Alarmı kapatayım. Macil bir kat aşağıda." -Thanks.,TXT_RPLY0_SCRIPT02_D89444_THANK,〃,,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Kösz.,Grazie.,ありがとう。,고맙다.,Bedankt.,Takk skal du ha.,Dzięki.,Obrigado.,,Mulțumesc.,Спасибо.,,Teşekkürler. -"Walk away, boy, just walk away.",TXT_DLG_SCRIPT02_D90960_WALKA,〃,,,"Jdi pryč, chlapče, prostě odejdi.","Gå væk, knægt, bare gå væk.","Geh weg Jungchen, geh einfach weg.",,"Foriru, ulo. Vi nur foriru.","Vete, chaval. Solo vete.","Vete, muchacho. Solo vete.","Kävele pois vain, poju, kävele pois.","Pars, gamin, pars.","Csak sétálj el innen, sétálj el szépen.","Muoviti, ragazzo, muoviti...",向こうへ行け、新入り、急ぐんだ。,"지나가라고 친구, 그냥 지나가.","Loop weg, jongen, loop gewoon weg.","Gå vekk, gutt. Bare gå vekk.","Odejdź stąd mały, po prostu odejdź.","Suma daqui, garoto. Apenas suma daqui.",,"Pleacă, băiete, pleacă.","Иди своей дорогой, парень, иди.",,"Yürü git evlat, yürü git." -Do you have an appointment with the Governor? ,TXT_DLG_SCRIPT02_D92476_DOYOU,Arion.,,,Máte domluvený termín schůzky s guvernérem?,Har du en aftale med guvernøren?,Hast du einen Termin bei dem Gouverneur?,,Ĉu vi supozeble havas rendevuon kun la registo?,¿Acaso tienes una cita con el gobernador?,,Onko teillä varattu tapaaminen kuvernöörin kanssa?,Avez-vous un rendez-vous avec le gouverneur?,Van időpontod a kormányzóval?,Hai un appuntamento con il governatore?,知事とアポイントメントは取ってますか?,총독과 약속이 있으십니까?,Heb je een afspraak met de gouverneur?,Har du en avtale med guvernøren?,Masz spotkanie z Gubernatorem?,Você tem hora marcada com o Governador?,,Ai o programare cu Guvernatorul?,У Вас назначена встреча с губернатором?,,Vali ile randevunuz var mı? -Of course!,TXT_RPLY0_SCRIPT02_D92476_OFCOU,〃,,,Samozřejmě!,"Ja, selvfølgelig!",Natürlich!,,Kompreneble!,¡Por supuesto!,,Totta kai!,Bien sûr!,Persze!,Certo!,問題ない!,당연하지!,Natuurlijk!,Selvsagt!,Oczywiście!,Claro que sim!,,Desigur!,Конечно!,,Tabii ki var! -"No, and I don't need one!",TXT_RPLY1_SCRIPT02_D92476_NOAND,〃,,,Ne a žádný nepotřebuju!,"Nej, og jeg har ikke brug for en!","Nein, und ich brauche auch keinen!",,"Ne, kaj mi ne bezonas ĝin!",¡No y no la necesito!,,"Ei, enkä sellaista tarvitsekaan!","Non, et j'en ai pas besoin!","Nincs, és nem is kell!","No, e non ne ho bisogno!",いや、必要ない!,아니. 없는데?,"Nee, en die heb ik niet nodig!","Nei, og jeg trenger ingen!","Nie mam, i nie chcę mieć!",Não e eu não preciso de hora marcada!,,"Nu, nici n-am nevoie de una!","Нет, и я в ней не нуждаюсь!",,"Hayır, ihtiyacım da yok!" +警報は切っておこう。マシルはこの先だ。","블랙버드가 암호를 알려줬나 보군? 흠, 그럼 경보를 꺼둬야겠군. 마실은 계단 저 밑에 있어.","Blackbird vertelde je de code, huh? Laat me de wekker uitzetten. Macil is een vlucht naar beneden.",Fortalte Blackbird deg koden? La meg slå av alarmen. Macil er en etasje ned.,"Blackbird podała ci hasło, co? Pozwól, że wyłączę alarm. Macil jest piętro niżej.","A Blackbird te passou o código, é? Deixa eu desligar o alarme. Macil está no andar debaixo.",,"Blackbird ți-a spus codul, huh? Permite-mi să opresc alarma, Macil e cu un etaj mai jos.","«Чёрный дрозд» сообщила тебе пароль, так? Давай я отключу сигнализацию. Мэйсил этажом ниже.",,"Blackbird berättade koden för dig, va? Låt mig stänga av larmet. Macil är en trappa ner.","Karatavuk sana kodu söyledi, ha? Alarmı kapatayım. Macil bir kat aşağıda." +Thanks.,TXT_RPLY0_SCRIPT02_D89444_THANK,〃,,,Díky.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitos.,Merci.,Kösz.,Grazie.,ありがとう。,고맙다.,Bedankt.,Takk skal du ha.,Dzięki.,Obrigado.,,Mulțumesc.,Спасибо.,,Tack.,Teşekkürler. +"Walk away, boy, just walk away.",TXT_DLG_SCRIPT02_D90960_WALKA,〃,,,"Jdi pryč, chlapče, prostě odejdi.","Gå væk, knægt, bare gå væk.","Geh weg Jungchen, geh einfach weg.",,"Foriru, ulo. Vi nur foriru.","Vete, chaval. Solo vete.","Vete, muchacho. Solo vete.","Kävele pois vain, poju, kävele pois.","Pars, gamin, pars.","Csak sétálj el innen, sétálj el szépen.","Muoviti, ragazzo, muoviti...",向こうへ行け、新入り、急ぐんだ。,"지나가라고 친구, 그냥 지나가.","Loop weg, jongen, loop gewoon weg.","Gå vekk, gutt. Bare gå vekk.","Odejdź stąd mały, po prostu odejdź.","Suma daqui, garoto. Apenas suma daqui.",,"Pleacă, băiete, pleacă.","Иди своей дорогой, парень, иди.",,"Gå iväg, pojke, bara gå iväg.","Yürü git evlat, yürü git." +Do you have an appointment with the Governor? ,TXT_DLG_SCRIPT02_D92476_DOYOU,Arion.,,,Máte domluvený termín schůzky s guvernérem?,Har du en aftale med guvernøren?,Hast du einen Termin bei dem Gouverneur?,,Ĉu vi supozeble havas rendevuon kun la registo?,¿Acaso tienes una cita con el gobernador?,,Onko teillä varattu tapaaminen kuvernöörin kanssa?,Avez-vous un rendez-vous avec le gouverneur?,Van időpontod a kormányzóval?,Hai un appuntamento con il governatore?,知事とアポイントメントは取ってますか?,총독과 약속이 있으십니까?,Heb je een afspraak met de gouverneur?,Har du en avtale med guvernøren?,Masz spotkanie z Gubernatorem?,Você tem hora marcada com o Governador?,,Ai o programare cu Guvernatorul?,У Вас назначена встреча с губернатором?,,Har du ett möte med guvernören?,Vali ile randevunuz var mı? +Of course!,TXT_RPLY0_SCRIPT02_D92476_OFCOU,〃,,,Samozřejmě!,"Ja, selvfølgelig!",Natürlich!,,Kompreneble!,¡Por supuesto!,,Totta kai!,Bien sûr!,Persze!,Certo!,問題ない!,당연하지!,Natuurlijk!,Selvsagt!,Oczywiście!,Claro que sim!,,Desigur!,Конечно!,,Självklart!,Tabii ki var! +"No, and I don't need one!",TXT_RPLY1_SCRIPT02_D92476_NOAND,〃,,,Ne a žádný nepotřebuju!,"Nej, og jeg har ikke brug for en!","Nein, und ich brauche auch keinen!",,"Ne, kaj mi ne bezonas ĝin!",¡No y no la necesito!,,"Ei, enkä sellaista tarvitsekaan!","Non, et j'en ai pas besoin!","Nincs, és nem is kell!","No, e non ne ho bisogno!",いや、必要ない!,아니. 없는데?,"Nee, en die heb ik niet nodig!","Nei, og jeg trenger ingen!","Nie mam, i nie chcę mieć!",Não e eu não preciso de hora marcada!,,"Nu, nici n-am nevoie de una!","Нет, и я в ней не нуждаюсь!",,"Nej, och jag behöver ingen!","Hayır, ihtiyacım da yok!" Sorry! I didn't mean... Please go right up.,TXT_DLG_SCRIPT02_D93992_SORRY,〃,,,"Pardon! Nechtěl jsem... jeďte tady nahoru, prosím.",Undskyld! Jeg mente ikke... Vær venlig at gå op.,Entschuldigung! Das war nicht so gemeint... Bitte geh durch.,,"Ha, pardonon; mi ne intencis... Uzu la lifton.","Ah, perdón; no quería... Ve al piso de arriba.",,"Pahoittelut! En tarkoittanut... Menkää suoraan ylös, olkaa hyvä.","Désolé, je.. Vous pouvez monter, bien sûr.",Elnézést! Nem akartam...kérem menjen fel az emeletre.,Scusa! Non intendevo... Vai al piano di sopra.,"すいません!知らずに... -そのまま上がって下さい。",이런! 기다리게 할 생각은 없었는데... 부디 위로 올라가시길 바랍니다.,Sorry! Ik bedoelde niet.... Ga alsjeblieft meteen naar boven.,Unnskyld! Unnskyld! Jeg mente ikke... Vær så snill å gå opp.,"Przepraszam! Nie chciałem... Proszę, idź na górę.",Desculpe! Eu não queria... Por favor pode subir.,,"Scuze! Te rog, poftește sus.","Простите! Я не думал... Пожалуйста, проходите наверх.",,Özür dilerim! Öyle demek istemedim. Lütfen yukarı çıkın. -I knew you'd say that.,TXT_RPLY0_SCRIPT02_D93992_IKNEW,〃,,,"Věděl jsem, že to řekneš.","Jeg vidste, at du ville sige det.","Ich dachte mir schon, das du das sagen würdest.",,"Mi sciis, ke vi dirus tion.",Sabía que dirías eso.,Sabía que ibas a decir eso.,"Arvasin, että sanoisit noin.",Je savais que vous diriez ceci.,"Tudtam, hogy ezt mondod.",Sapevo che l'avresti detto.,そう言うと思った。,그렇게 말할 줄 알았어.,Ik wist dat je dat zou zeggen.,Jeg visste du ville si det.,"Wiedziałem, że to powiesz.",Eu sabia que você diria isso.,,Știam că vei spune asta.,"Я знал, что ты это скажешь.",,Bunu söyleyeceğini biliyordum. +そのまま上がって下さい。",이런! 기다리게 할 생각은 없었는데... 부디 위로 올라가시길 바랍니다.,Sorry! Ik bedoelde niet.... Ga alsjeblieft meteen naar boven.,Unnskyld! Unnskyld! Jeg mente ikke... Vær så snill å gå opp.,"Przepraszam! Nie chciałem... Proszę, idź na górę.",Desculpe! Eu não queria... Por favor pode subir.,,"Scuze! Te rog, poftește sus.","Простите! Я не думал... Пожалуйста, проходите наверх.",,Jag är ledsen! Jag menade inte... Var snäll och gå upp.,Özür dilerim! Öyle demek istemedim. Lütfen yukarı çıkın. +I knew you'd say that.,TXT_RPLY0_SCRIPT02_D93992_IKNEW,〃,,,"Věděl jsem, že to řekneš.","Jeg vidste, at du ville sige det.","Ich dachte mir schon, das du das sagen würdest.",,"Mi sciis, ke vi dirus tion.",Sabía que dirías eso.,Sabía que ibas a decir eso.,"Arvasin, että sanoisit noin.",Je savais que vous diriez ceci.,"Tudtam, hogy ezt mondod.",Sapevo che l'avresti detto.,そう言うと思った。,그렇게 말할 줄 알았어.,Ik wist dat je dat zou zeggen.,Jeg visste du ville si det.,"Wiedziałem, że to powiesz.",Eu sabia que você diria isso.,,Știam că vei spune asta.,"Я знал, что ты это скажешь.",,Jag visste att du skulle säga det.,Bunu söyleyeceğini biliyordum. "If you're in such a hurry, don't waste your time with me.",TXT_DLG_SCRIPT02_D95508_IFYOU,〃,,,"Jestli tolik spěcháte, neztrácejte čas se mnou.","Hvis du har så travlt, skal du ikke spilde din tid med mig.","Wenn du so in Eile bist, dann verschwende deine Zeit nicht mit mir.",,"Se vi vere hastas renkonti lin, ne perdu vian tempo kun mi.","Si realmente tienes tanta prisa, no pierdas el tiempo conmigo.","Si realmente estás tan apurado, no pierdas el tiempo conmigo.","Jos kerta olet niin kovassa kiireessä, älä haaskaa aikaasi minun kanssani.","Si vous êtes tellement pressé, ne perdez pas votre temps avec moi.","Ha ennyire sietsz, ne pocsékold az idődet velem.","Se vai così di fretta, non sprecare il tuo tempo con me.","そんなに急いでいるなら、 -お互い時間を大切にしましょう。","아주 급하시다면, 저하고 예기하는 건 시간 낭비일 뿐이에요.","Als je zo'n haast hebt, verspil dan geen tijd met mij.","Hvis du har det så travelt, ikke kast bort tiden din på meg.","Jeśli się tak spieszysz, nie marnuj czasu tu ze mną.","Se você está com tanta pressa, não gaste seu tempo comigo.",,"Dacă te grăbești așa tare, nu-ți pierde vremea cu mine.","Если вы так торопитесь, не тратьте на меня время.",,"Madem bu kadar aceleniz var, benimle vakit kaybetmeyin." -"Release me, leave an old man alone.",TXT_DLG_SCRIPT02_D97024_RELEA,MAP02: MacGuffin,,,"Drž se dál, nech starce na pokoji.","Slip mig fri, lad en gammel mand være i fred.","Pack mich nicht an, lass einen alten Mann in Ruhe",,"Sufiĉe, ne ĝenu maljunulon.",Déjame en paz. No molestes a un anciano.,,"Päästä minut, jätä vanha mies rauhaan.","Laissez moi tranquille, un vieil homme a le droit d'être seul.","Engedj el, hagyd békén öreg csontjaimat.","Lasciami stare, non inquietare un vecchio.",ほっといてくれ、年寄り一人にしてくれ。,부탁일세. 이 노인을 내버려 두게.,"Laat me vrij, laat een oude man met rust.","Slipp meg, la en gammel mann være i fred.","Nie zbliżaj się, zostaw starca w spokoju.","Me solte, deixe um velho em paz.",,"Lasă-mă, lasă bătrânii în pace.",Оставь старика в покое!,,"Bırak beni, yaşlı bir adamı yalnız bırak." +お互い時間を大切にしましょう。","아주 급하시다면, 저하고 예기하는 건 시간 낭비일 뿐이에요.","Als je zo'n haast hebt, verspil dan geen tijd met mij.","Hvis du har det så travelt, ikke kast bort tiden din på meg.","Jeśli się tak spieszysz, nie marnuj czasu tu ze mną.","Se você está com tanta pressa, não gaste seu tempo comigo.",,"Dacă te grăbești așa tare, nu-ți pierde vremea cu mine.","Если вы так торопитесь, не тратьте на меня время.",,"Om du har så bråttom, slösa inte bort din tid med mig.","Madem bu kadar aceleniz var, benimle vakit kaybetmeyin." +"Release me, leave an old man alone.",TXT_DLG_SCRIPT02_D97024_RELEA,MAP02: MacGuffin,,,"Drž se dál, nech starce na pokoji.","Slip mig fri, lad en gammel mand være i fred.","Pack mich nicht an, lass einen alten Mann in Ruhe",,"Sufiĉe, ne ĝenu maljunulon.",Déjame en paz. No molestes a un anciano.,,"Päästä minut, jätä vanha mies rauhaan.","Laissez moi tranquille, un vieil homme a le droit d'être seul.","Engedj el, hagyd békén öreg csontjaimat.","Lasciami stare, non inquietare un vecchio.",ほっといてくれ、年寄り一人にしてくれ。,부탁일세. 이 노인을 내버려 두게.,"Laat me vrij, laat een oude man met rust.","Slipp meg, la en gammel mann være i fred.","Nie zbliżaj się, zostaw starca w spokoju.","Me solte, deixe um velho em paz.",,"Lasă-mă, lasă bătrânii în pace.",Оставь старика в покое!,,"Släpp mig, låt en gammal man vara ifred.","Bırak beni, yaşlı bir adamı yalnız bırak." "You seek wisdom, my son? The order has seen to it that we only ask one question, 'Why?'",TXT_DLG_SCRIPT02_D98540_YOUSE,"〃 (after accepting ""messy"" chore)",,,"Hledáš moudrost, chlapče? Řád dohlédl na to, abychom se ptali jen na jedno: „Proč?“","Søger du visdom, min søn? Ordenen har sørget for, at vi kun stiller ét spørgsmål: ""Hvorfor?","Du suchst Weisheit, mein Sohn? Der Orden hat zugesehen das wir nur noch eine Frage stellen, „Warum?“",,"Ĉu vi serĉas saĝon, filo? La Ordono certiĝis, ke ni nur faru unu demandon: «Kial?».","¿Buscas sabiduría, hijo mío? La Orden se ha asegurado de que hagamos solo una pregunta: «¿Por qué?».",,"Etsitkö viisautta, poikani? Veljeskunta on pitänyt huolen, että ainoa kysymys, jonka kysymme, on ""Miksi"".","Vous cherchez ma sagesse, jeune homme? L'Ordre ne pose qu'une seule question: « Pourquoi? »","Tudásra vágsz, fiam? A Rend gondoskodott róla, hogy az egyetlen kérdés amit felteszünk a 'Miért?'","Cerchi saggezza, figliolo? L'Ordine ha fatto si che noi possiamo chiedere una sola domanda. ""Perché?""","知恵が欲しそうだな、ボウズ? オーダーが勘付かないよう一つだけ質問しよう、 -'何故?'","지혜를 찾고 싶은가, 젊은이여? 오더도 이 사실을 알고 있어서 우리들을 '왜?' 하고 묻게 했다네. 자네도 '왜' 그러나?","Je zoekt wijsheid, mijn zoon? De orde heeft ervoor gezorgd dat we maar één vraag stellen: 'Waarom?","Søker du visdom, min sønn? Ordenen har sørget for at vi bare stiller ett spørsmål. Hvorfor?","Poszukujesz wiedzy mój synu? Zakon stara się dopilnować nas abyśmy zadawali sobie tylko jedno pytanie, ""Czemu?""","Está atrás de sabedoria, meu filho? A ordem se certificou de que a gente só fizesse uma única pergunta, ""por quê?""",,"Cauți înțelepciune, fiul meu? Ordinul a avut grijă ca noi să putem fi în stare să punem o singură întrebare: 'De ce?'","Ищешь совета, сын мой? Орден заботится о том, чтобы нас занимал только один вопрос: «За что?»",,"Bilgelik mi istiyorsun, oğlum? Düzen sadece tek bir soru sormamızı sağladı, ""Neden?" -Where's the power coupling?,TXT_RPLY0_SCRIPT02_D98540_WHERE,〃 (〃),,,Kde je elektrická spojka?,Hvor er kraftkoblingen?,Wo ist der Stromabnehmer?,,Kie estas la elektra kuplado?,¿Dónde está el acoplamiento eléctrico?,,Missä virtaliitin on?,Où est le coupleur énergétique?,Hol van az áram kapcsoló?,Dov'è il giunto dell'impianto energetico?,配電機 は何処だ?,동력선은 어디있나요?,Waar is de krachtkoppeling?,Hvor er kraftkoblingen?,Gdzie jest odbierak prądu?,Cadê a conexão de energia?,,Unde e cuplajul energiei?,Где соединительная муфта?,,Güç bağlantısı nerede? -Where's the Order's main?,TXT_RPLY1_SCRIPT02_D98540_WHERE,〃 (〃),,,Kde má Řád napájecí síť?,Hvor er ordenens vigtigste?,Wo ist die Stromleitung des Ordens?,,Kie estas la elektriza sistemo de La Ordono?,¿Dónde está la red eléctrica de La Orden?,,Missä on Veljeskunnan pääsähkölinja?,Où est le transformateur de l'Ordre?,Hol a Rend fővonala?,Dov'è il giunto dell'Ordine?,オーダーの本管 は何処だ?,오더의 동력 공급 시설은 어디있나요?,Waar is de hoofdopdracht van de Orde?,Hvor er Ordenens hovedledning?,Gdzie jest przewód Zakonu?,Cadê o transformador da Ordem?,,Unde e linia electrică a Ordinului?,Где линия электропередачи Ордена?,,Tarikat'ın ana hattı nerede? -Where's the illegal tap?,TXT_RPLY2_SCRIPT02_D98540_WHERE,〃 (〃),,,Kde je nelegální stáčedlo?,Hvor er den ulovlige aftapning?,Wo ist die illegale Anzapfung?,,Kie estas la kontraŭleĝa konektilo?,¿Dónde está la toma eléctrica ilegal?,,Missä laiton kytkentä on?,Où est la connection pirate?,Hol az illegális lék?,Dov'è l'aggeggio illegale che sta rubando l'energia?,違法供給源 は何処だ?,불법 추출기는 어디있나요?,Waar is de illegale kraan?,Hvor er den ulovlige kranen?,Gdzie jest nielegalny przełącznik prądu?,Cadê a ligação clandestina?,,Unde e conexiunea ilegală?,Где нелегальное подключение?,,Yasadışı musluk nerede? +'何故?'","지혜를 찾고 싶은가, 젊은이여? 오더도 이 사실을 알고 있어서 우리들을 '왜?' 하고 묻게 했다네. 자네도 '왜' 그러나?","Je zoekt wijsheid, mijn zoon? De orde heeft ervoor gezorgd dat we maar één vraag stellen: 'Waarom?","Søker du visdom, min sønn? Ordenen har sørget for at vi bare stiller ett spørsmål. Hvorfor?","Poszukujesz wiedzy mój synu? Zakon stara się dopilnować nas abyśmy zadawali sobie tylko jedno pytanie, ""Czemu?""","Está atrás de sabedoria, meu filho? A ordem se certificou de que a gente só fizesse uma única pergunta, ""por quê?""",,"Cauți înțelepciune, fiul meu? Ordinul a avut grijă ca noi să putem fi în stare să punem o singură întrebare: 'De ce?'","Ищешь совета, сын мой? Орден заботится о том, чтобы нас занимал только один вопрос: «За что?»",,"Du söker visdom, min son? Ordern har sett till att vi bara ställer en fråga: ""Varför?","Bilgelik mi istiyorsun, oğlum? Düzen sadece tek bir soru sormamızı sağladı, ""Neden?" +Where's the power coupling?,TXT_RPLY0_SCRIPT02_D98540_WHERE,〃 (〃),,,Kde je elektrická spojka?,Hvor er kraftkoblingen?,Wo ist der Stromabnehmer?,,Kie estas la elektra kuplado?,¿Dónde está el acoplamiento eléctrico?,,Missä virtaliitin on?,Où est le coupleur énergétique?,Hol van az áram kapcsoló?,Dov'è il giunto dell'impianto energetico?,配電機 は何処だ?,동력선은 어디있나요?,Waar is de krachtkoppeling?,Hvor er kraftkoblingen?,Gdzie jest odbierak prądu?,Cadê a conexão de energia?,,Unde e cuplajul energiei?,Где соединительная муфта?,,Var är kraftkopplingen?,Güç bağlantısı nerede? +Where's the Order's main?,TXT_RPLY1_SCRIPT02_D98540_WHERE,〃 (〃),,,Kde má Řád napájecí síť?,Hvor er ordenens vigtigste?,Wo ist die Stromleitung des Ordens?,,Kie estas la elektriza sistemo de La Ordono?,¿Dónde está la red eléctrica de La Orden?,,Missä on Veljeskunnan pääsähkölinja?,Où est le transformateur de l'Ordre?,Hol a Rend fővonala?,Dov'è il giunto dell'Ordine?,オーダーの本管 は何処だ?,오더의 동력 공급 시설은 어디있나요?,Waar is de hoofdopdracht van de Orde?,Hvor er Ordenens hovedledning?,Gdzie jest przewód Zakonu?,Cadê o transformador da Ordem?,,Unde e linia electrică a Ordinului?,Где линия электропередачи Ордена?,,Var är orderns huvudledning?,Tarikat'ın ana hattı nerede? +Where's the illegal tap?,TXT_RPLY2_SCRIPT02_D98540_WHERE,〃 (〃),,,Kde je nelegální stáčedlo?,Hvor er den ulovlige aftapning?,Wo ist die illegale Anzapfung?,,Kie estas la kontraŭleĝa konektilo?,¿Dónde está la toma eléctrica ilegal?,,Missä laiton kytkentä on?,Où est la connection pirate?,Hol az illegális lék?,Dov'è l'aggeggio illegale che sta rubando l'energia?,違法供給源 は何処だ?,불법 추출기는 어디있나요?,Waar is de illegale kraan?,Hvor er den ulovlige kranen?,Gdzie jest nielegalny przełącznik prądu?,Cadê a ligação clandestina?,,Unde e conexiunea ilegală?,Где нелегальное подключение?,,Var är den olagliga kranen?,Yasadışı musluk nerede? "I'll tell you where it is, but I don't know whose coupling you'll be tampering with. It's right here in the sewage plant.",TXT_DLG_SCRIPT02_D100056_ILLTE,〃 (〃),,,"Řeknu ti kde je, ale nevím s čí spojkou budeš manipulovat. Je přímo tady v čističce.","Jeg skal fortælle dig, hvor den er, men jeg ved ikke, hvis kobling du vil pille ved. Den er lige her i kloakanlægget.","Ich sage dir wo er ist, aber ich weiß nicht, an wessen Anzapfung du herummanipulieren willst. Er ist genau hier in der Kläranlage.",,"Mi respondos, sed mi ne scias, kies elektrizan sistemon vi intencas perturbi. Ĝi estas ĉi tie, en la kloakpurigejo.","Te diré donde, aunque no sé de quién será la red eléctrica que quieres manipular. Está justo aquí en la planta de aguas residuales.","Te voy a decir, aunque no sé de quién será la red eléctrica que quieres manipular. Está justo aquí en la planta de aguas residuales.","Kerron kyllä, missä se on, mutten tiedä, kenen kytkentään aiot sekaantua. Se on täällä jätelaitoksella.","Je peux vous dire où il est, mais je ne peux pas vous dire à qui il appartient. Il se trouve dans le traitement des égouts.","Elárom hol van, de pontosan nem tudom kinek a kapcsolójával fogsz babrálni. Itt van rögtön a szennyvíz tisztítóban.","Ti dirò dov'è, ma non so con quale giunto in particolare tu voglia maneggiare. Sta proprio qua nell'impianto fognario.","それが何処にあるかは話そう、だがオレには どれをイジるかまでは知らん。 -配電機はここの下水処理場にある。",그게 어딨는지 말해주지. 왜 그 동력선에 손을 대려고 하는지는 모르겠지마는. 저 앞 하수도 안에 있다네.,"Ik zal je vertellen waar hij is, maar ik weet niet met wie je met de koppeling zult knoeien. Het is hier in de rioolwaterzuiveringsinstallatie.","Jeg skal si deg hvor den er, men jeg vet ikke hvem sin kobling du skal tukle med. Den er her i kloakkanlegget.","Powiem ci gdzie jest, ale nie wiem czyj to odbierak, przy którym będziesz majstrować. Jest w oczyszczalni ścieków.","Vou te dizer onde está, mas não sei em qual ligação você vai acabar mexendo. Fica bem aqui na usina de tratamento de esgoto.",,"Îți voi spune unde este, dar nu știu de care cuplaj te vei lega. Este chiar aici, în sistemul de canalizare.","Я скажу тебе, где она, но не знаю, которая тебе нужна. Она прямо здесь, в очистной системе.",,"Nerede olduğunu söyleyeceğim, ama kimin bağlantılarını kurcalayacağınızı bilmiyorum. Tam burada, kanalizasyon tesisinde." -Thanks,TXT_RPLY0_SCRIPT02_D100056_THANK,〃 (〃),,,Díky.,Tak,Danke,,Dankon.,Gracias.,,Kiitos,Merci.,Kösz.,Grazie,ありがとう。,그렇군요.,Bedankt,Takk skal du ha.,Dzięki,Obrigado,,Mulțumesc,Спасибо.,,Teşekkürler. +配電機はここの下水処理場にある。",그게 어딨는지 말해주지. 왜 그 동력선에 손을 대려고 하는지는 모르겠지마는. 저 앞 하수도 안에 있다네.,"Ik zal je vertellen waar hij is, maar ik weet niet met wie je met de koppeling zult knoeien. Het is hier in de rioolwaterzuiveringsinstallatie.","Jeg skal si deg hvor den er, men jeg vet ikke hvem sin kobling du skal tukle med. Den er her i kloakkanlegget.","Powiem ci gdzie jest, ale nie wiem czyj to odbierak, przy którym będziesz majstrować. Jest w oczyszczalni ścieków.","Vou te dizer onde está, mas não sei em qual ligação você vai acabar mexendo. Fica bem aqui na usina de tratamento de esgoto.",,"Îți voi spune unde este, dar nu știu de care cuplaj te vei lega. Este chiar aici, în sistemul de canalizare.","Я скажу тебе, где она, но не знаю, которая тебе нужна. Она прямо здесь, в очистной системе.",,"Jag ska berätta var den är, men jag vet inte vems koppling du kommer att mixtra med. Den finns här i reningsverket.","Nerede olduğunu söyleyeceğim, ama kimin bağlantılarını kurcalayacağınızı bilmiyorum. Tam burada, kanalizasyon tesisinde." +Thanks,TXT_RPLY0_SCRIPT02_D100056_THANK,〃 (〃),,,Díky.,Tak,Danke,,Dankon.,Gracias.,,Kiitos,Merci.,Kösz.,Grazie,ありがとう。,그렇군요.,Bedankt,Takk skal du ha.,Dzięki,Obrigado,,Mulțumesc,Спасибо.,,Tack,Teşekkürler. That's right here in the sewage plant. But it's the Front's coupling. Whoever told you that it was the Order's was wrong.,TXT_DLG_SCRIPT02_D101572_THATS,〃 (〃),,,"Síť je přímo tady, v čističce. Ale je to spojka Fronty. Kdo ti řekl, že je Řádu, se mýlil.","Det er lige her i kloakanlægget. Men det er Fronts kobling. Den, der fortalte dig, at det var Ordenens, tog fejl.","Genau hier, in der Kläranlage. Aber sie gehört der Front. Wer auch immer dir gesagt hat, sie gehöre dem Orden, hat gelogen.",,"Ĝi estas ĉi tie, en la kloakpurigejo, sed ĝi estas la kuplado de la Fronto. Tiu ajn, kiu diris, ke ĝi estas de La Ordono, eraris.","Está justo aquí en la planta de aguas residuales, pero es el acoplamiento del Frente. Quien te haya dicho que era de La Orden se ha equivocado. ","Está justo aquí en la planta de aguas residuales, pero es el acoplamiento del Frente. Quien te haya dicho que era de La Orden te dijo mal. ","Se on täällä jätelaitoksella. Mutta se on Rintaman kytkentä. Kuka sinulle kertoikaan sen kuuluvan Veljeskunnalle, oli väärässä.","Il se trouve ici dans le traitement des égouts, mais c'est le coupleur du Front . Celui qui vous a dit qu'il appartient à l'Ordre se plante.","Igen, jól hallottad, a szennyvíz tisztítóban. Ez azonban a Front kapcsolója. Akárki mondta, hogy a Rendé, hazudott neked.",È proprio qui nell'impianto fognario. Ma è il giunto del Fronte. Chiunque ti abbia detto che fosse il giunto dell'Ordine si sbagliava.,"正にここの下水処理場にあるさ。 だがそれはフロントにも繋いでいる。 そいつがオーダーの所有物と言われてたが、 そりゃ間違いだ。",저 앞 하수도 안에 있다네. 프론트가 설치한 동력선일세. 저게 오더 소유라고 우기던 사람은 거짓말을 한 게야.,"Dat is hier in de rioolwaterzuiveringsinstallatie. Maar het is de koppeling van de voorkant. Degene die je vertelde dat het de Order's waren, had het mis.","Det er her i kloakkanlegget. Men det er Fronts kobling. Den som sa at det var Ordenens, tok feil.","Jest w oczyszczalni ścieków. Ale to jest odbierak Frontu. Ktokolwiek ci powiedział, że należy do Zakonu, był w błędzie.",Fica bem aqui na usina de tratamento de esgoto. Mas é a ligação da Frente. Quem te falou que era da Ordem estava enganado.,,Este chiar aici în sistemul de canalizare. Dar este cuplajul Frontului. Oricine ți-a spus că e al Ordinului a greșit.,"Она прямо здесь, в очистном сооружении. Но это линия Сопротивления. Тот, кто сказал тебе, что она принадлежит Ордену, ошибся. -",,"Tam burada, kanalizasyon tesisinde. Ama bu Cephe'nin bağlantısı. Size kim Tarikat'ın olduğunu söylediyse yanılmış." -Thanks,TXT_RPLY0_SCRIPT02_D101572_THANK,〃 (〃),,,Díky.,Tak,Danke.,,Dankon.,Gracias.,,Kiitos,Merci.,Kösz.,Grazie,ありがとう。,고맙습니다.,Bedankt,Takk.,Dzięki,Obrigado,,Mulțumesc,Спасибо.,,Teşekkürler. +",,Det är precis här i reningsverket. Men det är Fronts koppling. Den som sa till dig att det var ordens koppling hade fel.,"Tam burada, kanalizasyon tesisinde. Ama bu Cephe'nin bağlantısı. Size kim Tarikat'ın olduğunu söylediyse yanılmış." +Thanks,TXT_RPLY0_SCRIPT02_D101572_THANK,〃 (〃),,,Díky.,Tak,Danke.,,Dankon.,Gracias.,,Kiitos,Merci.,Kösz.,Grazie,ありがとう。,고맙습니다.,Bedankt,Takk.,Dzięki,Obrigado,,Mulțumesc,Спасибо.,,Tack,Teşekkürler. If you say it's illegal I want nothing to do with you. I have enough trouble as it is.,TXT_DLG_SCRIPT02_D103088_IFYOU,〃 (〃),,,"Jestli říkáš nelegální, nechci s tebou nic mít. Už tak mám svých problémů dost.","Hvis du siger, det er ulovligt, vil jeg ikke have noget med dig at gøre. Jeg har problemer nok i forvejen.","Wenn du sagst, es sei illegal, möchte ich nichts damit zu tun haben. Ich habe schon genug Probleme.",,"Se vi diras, ke ĝi estas kontraŭleĝa, mi volas nenian rilaton kun vi. Mi jam havas sufiĉe da problemoj.",Si dices que es ilegal no quiero tener nada que ver contigo. Ya tengo suficientes problemas.,,"Jos sanot sen olevan laiton, en halua olla kanssasi missään tekemisissä. On jo riitämiin pärjäämistä nykyhuolteni kanssa.","Si vous dites que c'est un truc illégal, alors je ne veux pas m'en mêler. J'ai déjà assez de problèmes.","Ha azt mondod, hogy illegális, nem akarok benne lenni. Van már így is elég bajom.","Se dici che è illegale, non voglio averci nulla a che fare. Ho già abbastanza problemi di mio.","それが違法だっつうんならオレには関係無い。 -トラブルは御免だ。",저게 불법이라고 말한다면 난 이제 더는 모른다네. 관련 문제도 원치 않고 말일세.,"Als je zegt dat het illegaal is, wil ik niets met je te maken hebben. Ik heb al genoeg problemen.","Hvis du sier det er ulovlig, vil jeg ikke ha noe med deg å gjøre. Jeg har nok problemer som det er.","Jeśli mówisz, że jest nielegalny, to nie chcę mieć z tobą nic wspólnego. Mam wystarczająco dużo kłopotów.",Se você diz que isso é ilegal então eu não quero envolvimento nenhum contigo. Já tenho problemas o suficiente.,,"Dacă zici că e ilegal, nu vreau să am nimic de-aface cu tine. Am destule probleme deja.","Раз ты говоришь, что оно нелегально, я не хочу иметь с тобой дел. Мне и так хватает проблем.",,"Eğer bunun yasadışı olduğunu söylüyorsanız, sizinle hiçbir şey yapmak istemiyorum. Başımda yeterince bela var zaten." -Thanks,TXT_RPLY0_SCRIPT02_D103088_THANK,〃 (〃),,,Díky.,Tak,Danke,,Dankon.,Gracias.,,Kiitos,Merci.,Kösz,Grazie,ありがとう。,감사합니다.,Bedankt,Takk.,Dzięki,Obrigado,,Mulțumesc,Спасибо.,,Teşekkürler. -"Release me, leave an old man alone.",TXT_DLG_SCRIPT02_D104604_RELEA,〃 (〃),,,"Drž se dál, nech starce na pokoji.","Slip mig fri, lad en gammel mand være i fred.",Bitte lass einen alten Mann in Ruhe,,"Sufiĉe, ne ĝenu maljunulon.",Déjame en paz. No molestes a un anciano.,,"Päästä minut, jätä vanha mies rauhaan.","Laissez moi tranquille, un vieil homme a le droit d'être seul.","Engedj el, hagyd békén öreg csontjaimat.","Lasciami stare, non inquietare un vecchio.",ほっといてくれ、年寄り一人にしてくれ。,보내주게. 이 노인은 이제 아무것도 몰라.,"Laat me vrij, laat een oude man met rust.","Slipp meg fri, la en gammel mann være i fred.","Nie zbliżaj się, zostaw starca w spokoju.","Me solte, deixe um velho em paz.",,"Lasă-mă, lasă bătrânii în pace.",Оставь старика в покое!,,"Bırakın beni, yaşlı bir adamı yalnız bırakın." +トラブルは御免だ。",저게 불법이라고 말한다면 난 이제 더는 모른다네. 관련 문제도 원치 않고 말일세.,"Als je zegt dat het illegaal is, wil ik niets met je te maken hebben. Ik heb al genoeg problemen.","Hvis du sier det er ulovlig, vil jeg ikke ha noe med deg å gjøre. Jeg har nok problemer som det er.","Jeśli mówisz, że jest nielegalny, to nie chcę mieć z tobą nic wspólnego. Mam wystarczająco dużo kłopotów.",Se você diz que isso é ilegal então eu não quero envolvimento nenhum contigo. Já tenho problemas o suficiente.,,"Dacă zici că e ilegal, nu vreau să am nimic de-aface cu tine. Am destule probleme deja.","Раз ты говоришь, что оно нелегально, я не хочу иметь с тобой дел. Мне и так хватает проблем.",,Om du säger att det är olagligt vill jag inte ha något med dig att göra. Jag har tillräckligt med problem som det är.,"Eğer bunun yasadışı olduğunu söylüyorsanız, sizinle hiçbir şey yapmak istemiyorum. Başımda yeterince bela var zaten." +Thanks,TXT_RPLY0_SCRIPT02_D103088_THANK,〃 (〃),,,Díky.,Tak,Danke,,Dankon.,Gracias.,,Kiitos,Merci.,Kösz,Grazie,ありがとう。,감사합니다.,Bedankt,Takk.,Dzięki,Obrigado,,Mulțumesc,Спасибо.,,Tack,Teşekkürler. +"Release me, leave an old man alone.",TXT_DLG_SCRIPT02_D104604_RELEA,〃 (〃),,,"Drž se dál, nech starce na pokoji.","Slip mig fri, lad en gammel mand være i fred.",Bitte lass einen alten Mann in Ruhe,,"Sufiĉe, ne ĝenu maljunulon.",Déjame en paz. No molestes a un anciano.,,"Päästä minut, jätä vanha mies rauhaan.","Laissez moi tranquille, un vieil homme a le droit d'être seul.","Engedj el, hagyd békén öreg csontjaimat.","Lasciami stare, non inquietare un vecchio.",ほっといてくれ、年寄り一人にしてくれ。,보내주게. 이 노인은 이제 아무것도 몰라.,"Laat me vrij, laat een oude man met rust.","Slipp meg fri, la en gammel mann være i fred.","Nie zbliżaj się, zostaw starca w spokoju.","Me solte, deixe um velho em paz.",,"Lasă-mă, lasă bătrânii în pace.",Оставь старика в покое!,,"Släpp mig, låt en gammal man vara ifred.","Bırakın beni, yaşlı bir adamı yalnız bırakın." "Welcome to the last flicker of hope. Only we have the free will to oppose the Order. We have the sharpest scientific minds, and many able bodies, but we lack that one real, uh... Problemsolver, who will give us the edge we need. Help us.",TXT_DLG_SCRIPT03_D0_WELCO,MAP03: Macil.,,,"Vítej u posledního plamínku naděje. Jen my máme svobodnou vůli vzdorovat Řádu. Máme sice nejčilejší vědecké génie a mnoho schopných vojáků, ale chybí nám ten jeden... pomocník, který by nás posunul vpřed. Pomoz nám.","Velkommen til det sidste lille håb. Kun vi har den frie vilje til at modsætte os Ordenen. Vi har de skarpeste videnskabelige hjerner og mange dygtige kroppe, men vi mangler den ene rigtige, øh... Problemløser, som vil give os den fordel, vi har brug for. Hjælp os.","Wilkommen beim letzten Hoffnungsschimmer. Nur wir haben noch den freien Willen, um gegen den Orden zu arbeiten. Wir haben die besten Wissenschaftler und viele fähige Kämpfer aber was uns fehlt ist ein spezieller... äh... Problemlöser, der uns den nötigen Vorteil verschafft. Bitte hilf uns.",,"Bonvenon en la lasta fajrero da espero. Nur ni havas liberan volon por kontraŭstari al La Ordono. Ni havas la plej inteligentajn mensojn kaj multe da kapablaj homoj, sed mankas tiu, kiu estus, hm... vera problem-solvanto, por ke li donu al ni la necesan avantaĝon. Helpu nin.","Bienvenido al último destello de esperanza. Solo nosotros tenemos el libre albedrío para oponernos a La Orden. Tenemos las mentes científicas más brillantes y muchas personas capaces, pero nos falta el que sería, este... todo un solucionador de problemas para que nos dé la ventaja que necesitamos. Ayúdanos.",,"Tervetuloa viimeisen toivonpilkahduksen äärelle. Ainoastaan meillä on vapaa tahto vastustaa Veljeskuntaa. Meillä on tieteen terävimmät mielet ja monia ruumiiltaan vahvoja, mutta meiltä puuttuu se yksi todellinen, sanottaisiinko, Ongelmanratkoja, joka antaisi meille kaipaamamme etulyöntiaseman. Auta meitä.","Bienvenue au dernier lieu d'espoir. Nous seuls avons la liberté d'esprit pour opposer l'Ordre. Nous avons les esprits scientifiques les plus aiguisés et de nombreux hommes habiles et sains.. Mais il nous manque quelqu'un qui pourrait.. résoudre nos problèmes. Nous donner un peu d'aide, nous permettre de prendre l'avantage.","Köszöntelek a remény utolsó pislákoló fényénél. Már csak mi merünk szembeszállni a Renddel. Itt vannak a legélesebb elmék, életerős emberek, de hiányzik egy igazi...probléma megoldó, aki előnyt szerez számunkra. Segíts nekünk!","Benvenuto nell'ultimo barlume di speranza. Noi siamo i soli ad avere la determinazione per combattere l'Ordine. Abbiamo brillanti scienziati e molti soldati capaci, ma ci manca quel vero e proprio... risolutore di problemi, che ci può dare quel vantaggio che cerchiamo. Aiutaci!","ようこそ、ここは我々の僅かな希望が集まる 最後の場所だ。オーダーへと立ち向かう意思を 持っているのは我々くらいだ。 @@ -10226,364 +10708,364 @@ Thanks,TXT_RPLY0_SCRIPT02_D103088_THANK,〃 (〃),,,Díky.,Tak,Danke,,Dankon.,Gr 丈夫な体を持った戦士たちがいる。 だがしかし、我々には問題解決に優れた者、 つまり私達の力となる者が足りていないんだ。 -我々に手を貸してくれ。","최후의 희망 한 가닥을 잡은 것을 환영합니다. 우리만이 오더를 거부할 수 있는 의지를 갖추고 있죠. 뛰어난 과학력과 전투력은 다 갖추고 있습니다만, 정작 '해결사' 몫을 해주는 인물이 없어서 말입니다... 부디 우리를 도와주시길 바랍니다.","Welkom bij het laatste sprankje hoop. Alleen wij hebben de vrije wil om ons te verzetten tegen de Orde. We hebben de scherpste wetenschappelijke geesten en veel bekwame lichamen, maar we missen die ene echte, uh.... probleemoplosser, die ons de voorsprong zal geven die we nodig hebben. Help ons.","Velkommen til det siste glimt av håp. Bare vi har den frie viljen til å motsette oss Ordenen. Vi har de skarpeste vitenskapelige hodene, og mange dyktige kropper, men vi mangler den ene virkelige... problemløseren, som vil gi oss det forspranget vi trenger. Hjelp oss.","Witaj w ostatniej iskierce nadziei. Tylko my mamy wolną wolę, aby sprzeciwić się Zakonowi. Mamy najmądrzejszych naukowców i wielu ludzi, ale brakuje nam kogoś porządnego by, ehmm... rozwiązać parę problemów, kogoś kto da nam przewagę, której potrzebujemy. Pomóż nam.","Seja bem-vindo à última ponta de esperança. Somente nós temos o livre arbítrio para combater a Ordem. Temos as mentes científicas mais afiadas e muitas pessoas capazes, mas nos falta aquele verdadeiro, hã... quebra-galho, que nos dará o impulso que precisamos. Ajude-nos.",,"Bun venit la ultima fărâmă de speranță. Numai noi avem voința liberă necesară pentru a ne opune Ordinului. Avem cele mai ascuțite minți științifice, și mulți oameni capabili de muncă, dar ne lipsește acel um... adevărat Salvator de la probleme, care să ne ofere avantajul de care avem nevoie. Ajută-ne.","Добро пожаловать в последний оплот надежды. Только мы обладаем свободной волей, чтобы противостоять Ордену. С нами лучшие учёные умы, и у нас есть много толковых людей, но нам не хватает одного-единственного, э... «решателя проблем», который поможет нам получить необходимое преимущество. Помоги нам.",,"Son umut ışığına hoş geldiniz. Tarikat'a karşı koyacak özgür irade sadece bizde var. En keskin bilimsel zihinlere ve birçok yetenekli bedene sahibiz, ancak bize ihtiyacımız olan avantajı sağlayacak gerçek bir Problem Çözücüden yoksunuz. Bize yardım edin." -"All right, I accept.",TXT_RPLY0_SCRIPT03_D0_ALLRI,〃,,,"Dobře, příjimám.","Okay, jeg accepterer.","Klar, ich bin dabei.",,"Bone, mi akceptas.","Muy bien, acepto.",,"Hyvä on, suostun auttamaan.",Très bien. J'accepte.,"Rendben, elfogadom.","Va bene, accetto.",いいぞ、引き受けよう。,좋아요. 받아들이죠.,"Oké, ik accepteer het.","Greit, jeg aksepterer.","Dobrze, zgadzam się.","Tá certo, eu aceito.",,"În regulă, accept.",Хорошо. Я согласен.,,"Pekala, kabul ediyorum." -No thanks!,TXT_RPLY1_SCRIPT03_D0_NOTHA,〃,,,"Ne, díky.",Nej tak!,"Nein, danke!",,"Ne, dankon!","¡No, gracias!",,Ei kiitos!,Non merci.,Nem kösz!,"No, grazie!",断る!,사양할게요!,"Nee, dank je wel!",Nei takk!,"Nie, dziękuję!","Não, obrigado!",,Nu merci!,"Нет уж, спасибо!",,"Hayır, teşekkürler!" +我々に手を貸してくれ。","최후의 희망 한 가닥을 잡은 것을 환영합니다. 우리만이 오더를 거부할 수 있는 의지를 갖추고 있죠. 뛰어난 과학력과 전투력은 다 갖추고 있습니다만, 정작 '해결사' 몫을 해주는 인물이 없어서 말입니다... 부디 우리를 도와주시길 바랍니다.","Welkom bij het laatste sprankje hoop. Alleen wij hebben de vrije wil om ons te verzetten tegen de Orde. We hebben de scherpste wetenschappelijke geesten en veel bekwame lichamen, maar we missen die ene echte, uh.... probleemoplosser, die ons de voorsprong zal geven die we nodig hebben. Help ons.","Velkommen til det siste glimt av håp. Bare vi har den frie viljen til å motsette oss Ordenen. Vi har de skarpeste vitenskapelige hodene, og mange dyktige kropper, men vi mangler den ene virkelige... problemløseren, som vil gi oss det forspranget vi trenger. Hjelp oss.","Witaj w ostatniej iskierce nadziei. Tylko my mamy wolną wolę, aby sprzeciwić się Zakonowi. Mamy najmądrzejszych naukowców i wielu ludzi, ale brakuje nam kogoś porządnego by, ehmm... rozwiązać parę problemów, kogoś kto da nam przewagę, której potrzebujemy. Pomóż nam.","Seja bem-vindo à última ponta de esperança. Somente nós temos o livre arbítrio para combater a Ordem. Temos as mentes científicas mais afiadas e muitas pessoas capazes, mas nos falta aquele verdadeiro, hã... quebra-galho, que nos dará o impulso que precisamos. Ajude-nos.",,"Bun venit la ultima fărâmă de speranță. Numai noi avem voința liberă necesară pentru a ne opune Ordinului. Avem cele mai ascuțite minți științifice, și mulți oameni capabili de muncă, dar ne lipsește acel um... adevărat Salvator de la probleme, care să ne ofere avantajul de care avem nevoie. Ajută-ne.","Добро пожаловать в последний оплот надежды. Только мы обладаем свободной волей, чтобы противостоять Ордену. С нами лучшие учёные умы, и у нас есть много толковых людей, но нам не хватает одного-единственного, э... «решателя проблем», который поможет нам получить необходимое преимущество. Помоги нам.",,"Välkommen till den sista flimret av hopp. Endast vi har den fria viljan att motsätta oss Orden. Vi har de skarpaste vetenskapliga hjärnorna och många dugliga kroppar, men vi saknar den där riktiga... Problemlösaren, som kan ge oss det övertag vi behöver. Hjälp oss.","Son umut ışığına hoş geldiniz. Tarikat'a karşı koyacak özgür irade sadece bizde var. En keskin bilimsel zihinlere ve birçok yetenekli bedene sahibiz, ancak bize ihtiyacımız olan avantajı sağlayacak gerçek bir Problem Çözücüden yoksunuz. Bize yardım edin." +"All right, I accept.",TXT_RPLY0_SCRIPT03_D0_ALLRI,〃,,,"Dobře, příjimám.","Okay, jeg accepterer.","Klar, ich bin dabei.",,"Bone, mi akceptas.","Muy bien, acepto.",,"Hyvä on, suostun auttamaan.",Très bien. J'accepte.,"Rendben, elfogadom.","Va bene, accetto.",いいぞ、引き受けよう。,좋아요. 받아들이죠.,"Oké, ik accepteer het.","Greit, jeg aksepterer.","Dobrze, zgadzam się.","Tá certo, eu aceito.",,"În regulă, accept.",Хорошо. Я согласен.,,"Okej, jag accepterar.","Pekala, kabul ediyorum." +No thanks!,TXT_RPLY1_SCRIPT03_D0_NOTHA,〃,,,"Ne, díky.",Nej tak!,"Nein, danke!",,"Ne, dankon!","¡No, gracias!",,Ei kiitos!,Non merci.,Nem kösz!,"No, grazie!",断る!,사양할게요!,"Nee, dank je wel!",Nei takk!,"Nie, dziękuję!","Não, obrigado!",,Nu merci!,"Нет уж, спасибо!",,"Nej, tack!","Hayır, teşekkürler!" "You might want to reconsider, seeing that you're surrounded by heavily armed angry rebels.",TXT_DLG_SCRIPT03_D1516_YOUMI,〃,,,"Možná bys o tom měl popřemýšlet, soudě podle toho, že jsi obklopen po zuby ozbrojenými, naštvanými rebely.","Du bør måske genoverveje det, når du er omgivet af tungt bevæbnede vrede oprørere.","Bitte überdenke das nochmal, angesichts der Tatsache, dass du von befaffneten und zornigen Rebellen umgeben bist.",,"Vi eble volos rekonsideri tion, se ni konsideras, ke vi estas ĉirkaŭita de ege armitaj kaj koleraj ribelantoj.","Puede que quieras reconsiderarlo, ya que estás rodeado de rebeldes ya hartos y bien armados.",,"Haluannet ehkä harkita uudelleen, ottaen huomioon, että ympärilläsi on vihainen joukko raskaasti aseistettuja kapinallisia.","J'espère que vous pouvez y réfléchir. Après tout, vous êtes entouré de rebelles lourdement armés et prêts à se défendre.","Azt ajánlanám, hogy gondold újra, lévén hogy mérges fegyveres lázadók vesznek körbe.","Forse faresti meglio a ripensarci, considerato che sei circondato da ribelli arrabbiati e armati.","少し考え直したほうが良さそうだぞ、 君が重装備の怒れる兵士たちに -囲まれているのはわかるだろう?",다시... 생각을 해보는 게 좋을 것 같군요. 우리 병사들을 당황하게 만든 것 같은데 말이죠.,"Misschien wil je er nog eens over nadenken, aangezien je omringd wordt door zwaar bewapende, boze rebellen.","Du bør kanskje revurdere det, siden du er omringet av tungt bevæpnede, sinte opprørere.","Może zmienisz zdanie, kiedy zauważysz, że jesteś otoczony przez ciężko uzbrojonych, wściekłych rebeliantów.","Talvez você queira reconsiderar, já que está cercado de rebeldes furiosos armados até os dentes.",,"S-ar putea să vrei să reconsideri, având în vedere că ești înconjurat de rebeli nervoși înarmați până în dinți.","Возможно, при виде нервных и вооружённых до зубов повстанцев ты передумаешь.",,Etrafınız ağır silahlı kızgın asilerle çevrili olduğuna göre tekrar düşünmek isteyebilirsiniz. -"All right, I'm in!",TXT_RPLY0_SCRIPT03_D1516_ALLRI,〃,,,"Dobře, jdu do toho!","Okay, jeg er med!","Na gut, ich bin dabei.",,"Bone, mi aliĝos!","De acuerdo, ¡quiero entrar!",,"Hyvä on, olen messissä!","Ok, d'accord, j'accepte!","Rendben, benne vagyok!","Va bene, vi aiuterò!",わかった、乗ろう!,그럼 도와주도록 하죠.,"Oké, ik doe mee!","Greit, jeg er med!","Dobra, wchodzę w to!","Tá certo, estou dentro!",,"Bine, mă bag!","Хорошо, я с вами!",,"Pekala, ben varım!" -No thanks.,TXT_RPLY1_SCRIPT03_D1516_NOTHA,〃,,,"Ne, díky.",Nej tak.,"Nein, danke!",,"Ne, dankon.","No, gracias.",,Ei kiitos.,Non merci.,Nem kösz.,No grazie.,断る。,싫어요! 당신은 낯선 사람이잖아요!,"Nee, bedankt.",Nei takk.,"Nie, dziękuję.","Não, obrigado.",,Nu merci.,"Нет, спасибо.",,"Hayır, teşekkürler." -Then die in shame and dishonor.,TXT_DLG_SCRIPT03_D3032_THEND,〃,,Then die in shame and dishonour.,Pak zemři v hanbě a potupě!,Så dø i skam og vanære.,Dann wirst du in Schande und Unehre sterben.,,Tiuokaze mortu honte kaj senhonore.,Entonces muere en vergüenza y deshonra.,,Sitten kuole häpeässä vailla kunniaa.,Périssez dans la honte et le déshonneur.,Akkor szégyenteljes halál vár rád.,"E allora muori, con vergogna e disonore!",では、恥と不名誉と共に死ぬがいい。,그럼 불명예스럽고 초라하게 죽어버리시길!,Sterf dan in schaamte en oneer.,Så dø i skam og vanære.,Więc giń we wstydzie i hańbie.,Então morra com desonra e vergonha!,,Atunci mori în rușine și dezonoare.,Тогда умри в бесчестии и позоре.,,O zaman utanç ve onursuzluk içinde öl. +囲まれているのはわかるだろう?",다시... 생각을 해보는 게 좋을 것 같군요. 우리 병사들을 당황하게 만든 것 같은데 말이죠.,"Misschien wil je er nog eens over nadenken, aangezien je omringd wordt door zwaar bewapende, boze rebellen.","Du bør kanskje revurdere det, siden du er omringet av tungt bevæpnede, sinte opprørere.","Może zmienisz zdanie, kiedy zauważysz, że jesteś otoczony przez ciężko uzbrojonych, wściekłych rebeliantów.","Talvez você queira reconsiderar, já que está cercado de rebeldes furiosos armados até os dentes.",,"S-ar putea să vrei să reconsideri, având în vedere că ești înconjurat de rebeli nervoși înarmați până în dinți.","Возможно, при виде нервных и вооружённых до зубов повстанцев ты передумаешь.",,"Du kanske vill tänka om, eftersom du är omgiven av tungt beväpnade arga rebeller.",Etrafınız ağır silahlı kızgın asilerle çevrili olduğuna göre tekrar düşünmek isteyebilirsiniz. +"All right, I'm in!",TXT_RPLY0_SCRIPT03_D1516_ALLRI,〃,,,"Dobře, jdu do toho!","Okay, jeg er med!","Na gut, ich bin dabei.",,"Bone, mi aliĝos!","De acuerdo, ¡quiero entrar!",,"Hyvä on, olen messissä!","Ok, d'accord, j'accepte!","Rendben, benne vagyok!","Va bene, vi aiuterò!",わかった、乗ろう!,그럼 도와주도록 하죠.,"Oké, ik doe mee!","Greit, jeg er med!","Dobra, wchodzę w to!","Tá certo, estou dentro!",,"Bine, mă bag!","Хорошо, я с вами!",,"Okej, jag är med!","Pekala, ben varım!" +No thanks.,TXT_RPLY1_SCRIPT03_D1516_NOTHA,〃,,,"Ne, díky.",Nej tak.,"Nein, danke!",,"Ne, dankon.","No, gracias.",,Ei kiitos.,Non merci.,Nem kösz.,No grazie.,断る。,싫어요! 당신은 낯선 사람이잖아요!,"Nee, bedankt.",Nei takk.,"Nie, dziękuję.","Não, obrigado.",,Nu merci.,"Нет, спасибо.",,"Nej, tack.","Hayır, teşekkürler." +Then die in shame and dishonor.,TXT_DLG_SCRIPT03_D3032_THEND,〃,,Then die in shame and dishonour.,Pak zemři v hanbě a potupě!,Så dø i skam og vanære.,Dann wirst du in Schande und Unehre sterben.,,Tiuokaze mortu honte kaj senhonore.,Entonces muere en vergüenza y deshonra.,,Sitten kuole häpeässä vailla kunniaa.,Périssez dans la honte et le déshonneur.,Akkor szégyenteljes halál vár rád.,"E allora muori, con vergogna e disonore!",では、恥と不名誉と共に死ぬがいい。,그럼 불명예스럽고 초라하게 죽어버리시길!,Sterf dan in schaamte en oneer.,Så dø i skam og vanære.,Więc giń we wstydzie i hańbie.,Então morra com desonra e vergonha!,,Atunci mori în rușine și dezonoare.,Тогда умри в бесчестии и позоре.,,Dö då i skam och vanära.,O zaman utanç ve onursuzluk içinde öl. "Good, Blackbird will continue to be your guide. She's taken quite a shine to you. Together you've got to unlock the secrets of the Order and their inhuman servants. Get inside and take them down.",TXT_DLG_SCRIPT03_D4548_GOODB,〃,,,"Dobře, Straka ti bude dále dávat pokyny. Docela ses jí zalíbil. Společně budete muset odkrýt tajemství Řádu a jeho nelidských služebníků. Pronikněte dovnitř a sejměte je.","Godt, Blackbird vil fortsat være din guide. Hun er blevet ret glad for dig. Sammen skal I løse hemmelighederne om Ordenen og deres umenneskelige tjenere. Kom ind og nedlæg dem.","Gut so! Blackbird wird weiter deine Leiterin sein, sie scheint dich zu mögen. Zusammen müsst ihr die Geheimnisse des Ordens und ihrer unmenschlichen Diener ergründen. Dann haben wir eine Chance, sie niederzuringen.",,"Bone. BlackBird plue estos via gvidanto; ŝajnas, ke ŝi jam simpatias vin. Vi kune devas malkaŝi la sekretojn de La Ordono kaj de ĝiaj nehomaj servantoj. Enŝoviĝu en la kastelon kaj detruu ilin.",Bien. BlackBird seguirá siendo tu guía; parece que ya le caes bien. Juntos debéis descubrir los secretos de La Orden y de sus sirvientes inhumanos. Infiltraos en el castillo y acabad con ellos.,Bien. BlackBird va a seguir siendo tu guía; parece que ya le caes bien. Juntos deben descubrir los secretos de La Orden y de sus sirvientes inhumanos. Infíltrense al castillo y destrúyanlos.,Hyvä; Blackbird jatkaa opastajanasi. Hän vaikuttaa pitävän sinusta. Teidän on yhdessä paljastettava Veljeskunnan ja heidän epäinhimillisten palvelijoinsa salat. Murtaudu sisään ja aja heidät alas.,"Parfait. Blackbird continuera à être votre guide. Elle semble vous apprécier. Ensemble, vous allez découvrir les secrets de l'Ordre et leurs servants inhumains. Infiltrez-les et détruisez-les.","Helyes, Feketerigó továbbra is az irányítód lesz. Eléggé megtetszettél neki. Együtt meg fogjátok fejteni a Rend és kegyetlen szolgáinak titkait. Hatoljatok be és intézzétek el őket.",Bene. Blackbird continuerà ad essere la tua guida. Sembra ti abbia preso in simpatia. Insieme dovrete scoprire i segreti dell'Ordine e dei loro servi inumani. Bisognerà infiltrarlo e distruggerlo.,"よし、君のガイドをブラックバードが今後務める 彼女は君に感心しているようだぞ。 君達の二人で、オーダーとその人間離れした 手下たちが持っている秘密を暴いてもらいたい。 奴等の基地に潜り込んで、倒すんだ。","좋군요. 블랙버드가 당신에게 지시를 계속 내려줄 겁니다. 당신을 꽤 신뢰하는 듯하더군요. 우리는 오더와 그들의 잔혹한 심복들의 실체를 파헤치고 폭로할 겁니다. 비밀을 헤집고 그들을 몰락시켜 버리세요. - \cy듣기만 해도 꿈에 그리던 일만 같네, 그렇지?","Goed, Blackbird zal je gids blijven. Ze heeft een behoorlijke glans aan je genomen. Samen moeten jullie de geheimen van de Orde en hun onmenselijke dienaren ontrafelen. Ga naar binnen en haal ze naar beneden.","Bra, Blackbird vil fortsette å være din guide. Hun har blitt ganske betatt av deg. Sammen må dere avsløre hemmelighetene til Ordenen og deres umenneskelige tjenere. Gå inn og ta dem.","Dobrze, Blackbird dalej będzie twoją przewodniczką. Chyba przepada za tobą. Wspólnie musicie odkryć sekrety zakonu i ich nieludzkich sług. Idź tam i załatw ich.",Ótimo. Blackbird continuará sendo a sua guia. Parece que ela vai com a sua cara. Juntos vocês desvendarão os segredos da Ordem e de seus discípulos desumanos. Entre lá e elimine eles.,,"Bun, Blackbird va fi ghidul tău în continuare. A luat ceva înteres în tine. Împreună trebuie să descoperiți secretele Ordinului și slujitorii lor inumani. Dați buzna ți puneții la pământ.",Хорошо. Чёрный дрозд останется твоим проводником. Она тебе несколько симпатизирует. Вместе вы раскроете секреты Ордена и его нечеловеческих слуг. Проникни туда и покончи с ними! ,,"Güzel, Karatavuk rehberiniz olmaya devam edecek. Senden oldukça hoşlandı. Birlikte Tarikat'ın ve insanlık dışı hizmetkârlarının sırlarını çözmelisiniz. İçeri gir ve onları alaşağı et." -Where do I start?,TXT_RPLY0_SCRIPT03_D4548_WHERE,〃,,,Kde mám začít?,Hvor skal jeg begynde?,Wo fange ich an?,,Kie mi komencu?,¿Por dónde empiezo?,,Mistä aloitan?,Où est-ce que je commence?,Hol kezdjem?,Da dove comincio?,どこから始めればいいんだ?,어디서부터 시작하면 되죠?,Waar moet ik beginnen?,Hvor skal jeg begynne?,Gdzie zaczynam?,Por onde eu começo?,,Unde încep?,С чего мне начать?,,Nereden başlayacağım? + \cy듣기만 해도 꿈에 그리던 일만 같네, 그렇지?","Goed, Blackbird zal je gids blijven. Ze heeft een behoorlijke glans aan je genomen. Samen moeten jullie de geheimen van de Orde en hun onmenselijke dienaren ontrafelen. Ga naar binnen en haal ze naar beneden.","Bra, Blackbird vil fortsette å være din guide. Hun har blitt ganske betatt av deg. Sammen må dere avsløre hemmelighetene til Ordenen og deres umenneskelige tjenere. Gå inn og ta dem.","Dobrze, Blackbird dalej będzie twoją przewodniczką. Chyba przepada za tobą. Wspólnie musicie odkryć sekrety zakonu i ich nieludzkich sług. Idź tam i załatw ich.",Ótimo. Blackbird continuará sendo a sua guia. Parece que ela vai com a sua cara. Juntos vocês desvendarão os segredos da Ordem e de seus discípulos desumanos. Entre lá e elimine eles.,,"Bun, Blackbird va fi ghidul tău în continuare. A luat ceva înteres în tine. Împreună trebuie să descoperiți secretele Ordinului și slujitorii lor inumani. Dați buzna ți puneții la pământ.",Хорошо. Чёрный дрозд останется твоим проводником. Она тебе несколько симпатизирует. Вместе вы раскроете секреты Ордена и его нечеловеческих слуг. Проникни туда и покончи с ними! ,,"Bra, Blackbird kommer att fortsätta att vara din guide. Hon har blivit ganska förtjust i dig. Tillsammans måste ni avslöja hemligheterna om Orden och deras omänskliga tjänare. Gå in och ta ner dem.","Güzel, Karatavuk rehberiniz olmaya devam edecek. Senden oldukça hoşlandı. Birlikte Tarikat'ın ve insanlık dışı hizmetkârlarının sırlarını çözmelisiniz. İçeri gir ve onları alaşağı et." +Where do I start?,TXT_RPLY0_SCRIPT03_D4548_WHERE,〃,,,Kde mám začít?,Hvor skal jeg begynde?,Wo fange ich an?,,Kie mi komencu?,¿Por dónde empiezo?,,Mistä aloitan?,Où est-ce que je commence?,Hol kezdjem?,Da dove comincio?,どこから始めればいいんだ?,어디서부터 시작하면 되죠?,Waar moet ik beginnen?,Hvor skal jeg begynne?,Gdzie zaczynam?,Por onde eu começo?,,Unde încep?,С чего мне начать?,,Var börjar jag?,Nereden başlayacağım? Frankly the situation is a mess. You must accomplish several missions to prepare the way for more attacks on the Order. Our last raid was a disaster and most of our troops were captured. I need you to free these prisoners.,TXT_DLG_SCRIPT03_D6064_FRANK,〃 (Prison mission),,,"Upřímně, současná situace je úděsná. Musíš splnit několik misí před dalšími útoky na Řád. Náš poslední nájezd byla katastrofa a většina našich vojáků byla zajata. Potřebuju, abys tyto vězně vysvobodil.","Helt ærligt, situationen er et rod. Du skal udføre flere missioner for at bane vejen for flere angreb på Ordenen. Vores sidste angreb var en katastrofe, og de fleste af vores tropper blev taget til fange. Jeg har brug for, at du befrier disse fanger.","Ehrlich gesagt, die Situation ist eine Sauerei. Du musst mehrere Aufgaben erfüllen um den Weg für weitere Angriffe vorzubereiten. Der letzte Überfall war ein Desaster und die meisten unserer Leute wurden gefangengenommen. Du musst sie wieder befreien.",,"Sincere la situacio estas malordo. Vi devas plenumi diversajn misiojn, por ke ni povu prepari pliajn atakojn kontraŭ La Ordono. Ni malvenkis la lastan kaj tial La Ordono kaptis la plimulton de niaj trupoj; mi bezonas, ke vi liberigu ilin.","La situación es un lío, a decir verdad. Debes completar varias misiones para poder preparar más ataques contra La Orden. Nuestra última incursión fue un desastre y la mayoría de nuestras tropas fueron capturadas; necesito que las liberes.",,"Rehellisesti sanoen tilanne on sekasortoinen. Sinun on suoritettava lukuisia tehtäviä valmistaaksesi tien lisähyökkäyksille Veljeskuntaa vastaan. Viimeisin hyökkäyksemme oli katastrofi, ja suurin osa joukoistamme vangittiin. Tarvitsen sinua vapauttamaan nämä vangit.","Franchement, nous sommes dans un bazar sans précédent. Vous devez accomplir de nombreuses missions pour préparer nos futures attaques contre l'Ordre. Notre dernier raid à été un désastre et la majorité de nos troupes ont été capturées. Il faut que vous les libérez.","Őszintén szólva a szituáció elég zűrzavaros. Több küldetést is véghez kell vinned, hogy előkészítsd a támadás következő hullámát a Rend ellen. A legutolsó portyánk egy óriási kudarc volt, és a legtöbb egységünket elfogták. Ki kell, hogy engedd őket!","Francamente, la situazione è critica. Dovrai completare diverse missioni per far si da poter preparare nuovi attacchi contro l'Ordine. La nostra ultima incursione è stata in disastro, e la maggiorparte delle nostre truppe sono state catturate. Ho bisogno che tu liberi questi prigionieri.","はっきり言えば、今の状況は全く良くない。 君は複数の任務をこなし、オーダーへの 攻撃態勢を整える必要がある。 我々が行ったこの前の襲撃は大失敗で、 ほとんどの兵たちは捕らえられてしまった。 君にはその捕らえられた者たちを -救助してもらいたい。","애석하게도, 현재 상황은 엉망입니다. 우리가 오더를 공습하기 전에 당신이 수행해야 할 일이 몇 가지 있습니다. 몇 주 전 공습은 비참한 결과로 끝났고, 대부분의 병사가 감금당했습니다. 그들을 풀어주어야만 합니다.",Eerlijk gezegd is de situatie een puinhoop. Je moet verschillende missies volbrengen om de weg te bereiden voor meer aanvallen op de Orde. Onze laatste inval was een ramp en de meeste van onze troepen werden gevangen genomen. Ik heb je nodig om deze gevangenen te bevrijden.,"Ærlig talt er situasjonen et rot. Du må utføre flere oppdrag for å bane vei for flere angrep på Ordenen. Vårt siste angrep var en katastrofe, og de fleste av våre tropper ble tatt til fange. Du må befri disse fangene.","Szczerze to mamy tu bałagan. Musisz ukończyć kilka misji, by przygotować drogę na więcej ataków na Zakon. Nasz ostatni nalot był porażką i większość naszych żołnierzy została złapana. Potrzebuję cię, byś uwolnił tych więźniów.",Sinceramente a situação é uma bagunça. Você precisa cumprir algumas missões para preparar o caminho para mais ataques contra a Ordem. Nossa última invasão foi um desastre e muitas das nossas tropas foram capturadas. Preciso que você liberte esses prisioneiros.,,Sincer situația e nasoală. Trebuie să îndepliniți câteva misiune pentru a pregătii calea pentru mai multe atacuri asupra Ordinului. Ultimul nostru raid a fost un dezastru și majoritatea trupelor noastre au fost capturate. Am nevoie ca voi să eliberați prizonierii.,"Честно говоря, наши дела идут не лучшим образом. Тебе предстоит выполнить несколько заданий, чтобы подготовить почву для дальнейших атак на Орден. Наша последняя вылазка обернулась катастрофой, и большинство наших бойцов были схвачены. Мне нужно, чтобы ты освободил их.",,Açıkçası durum tam bir karmaşa. Tarikat'a daha fazla saldırının yolunu hazırlamak için birkaç görevi tamamlamalısınız. Son baskınımız bir felaketti ve askerlerimizin çoğu esir alındı. Bu esirleri serbest bırakmanı istiyorum. -I think I can handle it.,TXT_RPLY0_SCRIPT03_D6064_ITHIN,〃 (〃),,,"Myslím, že to zvládnu.","Jeg tror, jeg kan klare det.","Ich denke, das kann ich schaffen.",,"Mi pensas, ke mi povos fari tion.",Creo poder hacerlo.,,Eiköhän se onnistu.,Je pense pouvoir m'en occuper.,Azt hiszem el tudom intézni.,Penso di potercela fare.,俺ならできるはずだ。,아마도 제가 할 수 있을 것 같군요.,Ik denk dat ik het aankan.,Jeg tror jeg kan klare det.,"Myślę, że dam sobie z tym radę.",Acho que eu posso dar conta disso.,,Cred că mă pot descurca.,"Думаю, справлюсь.",,Sanırım ben halledebilirim. +救助してもらいたい。","애석하게도, 현재 상황은 엉망입니다. 우리가 오더를 공습하기 전에 당신이 수행해야 할 일이 몇 가지 있습니다. 몇 주 전 공습은 비참한 결과로 끝났고, 대부분의 병사가 감금당했습니다. 그들을 풀어주어야만 합니다.",Eerlijk gezegd is de situatie een puinhoop. Je moet verschillende missies volbrengen om de weg te bereiden voor meer aanvallen op de Orde. Onze laatste inval was een ramp en de meeste van onze troepen werden gevangen genomen. Ik heb je nodig om deze gevangenen te bevrijden.,"Ærlig talt er situasjonen et rot. Du må utføre flere oppdrag for å bane vei for flere angrep på Ordenen. Vårt siste angrep var en katastrofe, og de fleste av våre tropper ble tatt til fange. Du må befri disse fangene.","Szczerze to mamy tu bałagan. Musisz ukończyć kilka misji, by przygotować drogę na więcej ataków na Zakon. Nasz ostatni nalot był porażką i większość naszych żołnierzy została złapana. Potrzebuję cię, byś uwolnił tych więźniów.",Sinceramente a situação é uma bagunça. Você precisa cumprir algumas missões para preparar o caminho para mais ataques contra a Ordem. Nossa última invasão foi um desastre e muitas das nossas tropas foram capturadas. Preciso que você liberte esses prisioneiros.,,Sincer situația e nasoală. Trebuie să îndepliniți câteva misiune pentru a pregătii calea pentru mai multe atacuri asupra Ordinului. Ultimul nostru raid a fost un dezastru și majoritatea trupelor noastre au fost capturate. Am nevoie ca voi să eliberați prizonierii.,"Честно говоря, наши дела идут не лучшим образом. Тебе предстоит выполнить несколько заданий, чтобы подготовить почву для дальнейших атак на Орден. Наша последняя вылазка обернулась катастрофой, и большинство наших бойцов были схвачены. Мне нужно, чтобы ты освободил их.",,Ärligt talat är situationen en enda röra. Du måste utföra flera uppdrag för att bereda vägen för fler attacker mot Orden. Vår senaste räd var en katastrof och de flesta av våra trupper blev tillfångatagna. Jag behöver dig för att befria dessa fångar.,Açıkçası durum tam bir karmaşa. Tarikat'a daha fazla saldırının yolunu hazırlamak için birkaç görevi tamamlamalısınız. Son baskınımız bir felaketti ve askerlerimizin çoğu esir alındı. Bu esirleri serbest bırakmanı istiyorum. +I think I can handle it.,TXT_RPLY0_SCRIPT03_D6064_ITHIN,〃 (〃),,,"Myslím, že to zvládnu.","Jeg tror, jeg kan klare det.","Ich denke, das kann ich schaffen.",,"Mi pensas, ke mi povos fari tion.",Creo poder hacerlo.,,Eiköhän se onnistu.,Je pense pouvoir m'en occuper.,Azt hiszem el tudom intézni.,Penso di potercela fare.,俺ならできるはずだ。,아마도 제가 할 수 있을 것 같군요.,Ik denk dat ik het aankan.,Jeg tror jeg kan klare det.,"Myślę, że dam sobie z tym radę.",Acho que eu posso dar conta disso.,,Cred că mă pot descurca.,"Думаю, справлюсь.",,Jag tror att jag klarar av det.,Sanırım ben halledebilirim. "Take this money and visit Irale who supplies our weapons. Then, this key will get you in to see the Governor. He's a corrupt puppet of the Order, but he loves to make deals. Do whatever you need to free our brothers in arms.",TXT_DLG_SCRIPT03_D7580_TAKET,〃 (〃),,,"Vem si tohle zlato a navštiv Iraleho, který nás zásobuje zbraněmi. Tento klíč tě pak dostane ke guvernérovi. Je to jen zkorumpovaná loutka Řádu, ale zbožňuje nabídky. Udělej cokoliv je třeba, abys osvobodil naše bratry ve zbrani.","Tag disse penge og besøg Irale, som leverer vores våben. Så vil denne nøgle give dig adgang til guvernøren. Han er en korrupt marionet af Ordenen, men han elsker at lave aftaler. Gør hvad du skal gøre for at befri vores våbenbrødre.","Nimm das Geld hier und geh zu Irale, der und mit Waffen versorgt. Und dieser Schlüssel erlaubt die Zutritt zum Haus des Gouverneurs. Er ist eine korrupte Marionette des Ordens aber er liebt es, Deals zu machen. Mach was nötig ist um unsere Waffenbrüder zu befreien.",,"Prenu ĉi tiun monon kaj renkontu Irale, la provizanto de niaj armiloj. Poste ĉi tiu ŝlosilo ebligos al vi renkonti la registon. Li estas koruptita marioneto de La Ordono, sed li ŝategas intertraktadojn. Faru tion ajn, kion vi bezonas por liberigi niajn soldatojn.","Ten este dinero y ve a ver a Irale, que suministra nuestras armas. Después, esta llave te servirá para ver al gobernador. Es una marioneta corrupta de La Orden, pero le encantan los tratos. Haz lo que creas necesario para liberar a nuestros conmilitones.","Toma este dinero y ve a ver a Irale, que suministra nuestras armas. Después, esta llave te va a servir para ver al gobernador. Es una marioneta corrupta de La Orden, pero le encantan los tratos. Haz lo que creas necesario para liberar a nuestros conmilitones.","Ota tästä rahaa ja käväise Iralen luona, joka toimittaa meidän aseemme. Sitten tällä avaimella pääset tapaamaan kuvernööriä. Hän on Veljeskunnan läpimätä sätkynukke, mutta hän rakastaa tehdä kauppoja. Tee kaikkesi vapauttaaksesi aseveljemme.",Prenez cet argent et allez voir Irale qui nous approvisionne en armes. Utilisez ensuite cette clé pour aller voir le gouverneur. Il est un pantin de l'Ordre mais il adore faire affaires. Faites ce qu'il faut pour libérer nos compatriotes.,"Fogd ezt a pénzt, és látogasd meg Irale-t a fegyverellátónkat. Azután, ezzel a kulccsal be tudsz jutni a kormányzóhoz. Ő a Rend egy korrupt bábja, de imád üzletet kötni. Tegyél meg mindent, hogy kiszabadítsd a bajtársainkat.","Prendi questo denaro e vai da Irale, uno dei nostri fornitori d'armi. Dopodiché, con questa chiave potrai entrare nella dimora del governatore. È un pupazzo corrotto dell'Ordine, ma adora trattare sottobanco. Fai tutto il necessario per liberare i nostri compagni d'arme.","この金で、我らの武器を調達してくれている イラールの元を訪ねて行け。 その次に、この鍵を使って知事に会え。 知事はオーダーの腐敗した傀儡だが取引には 興味を持ってくれる。我々の仲間を助けるために どんな手でも使ってくれ。","이 돈을 가지고 마을의 무기상인 이롤리를 찾아가시길 바랍니다. 그리고 이 열쇠만 있으면 모렐 총독을 쉽게 만날 수 있을 겁니다. 그는 부패한 오더의 앞잡이지만, 거래에 미쳐있죠. 우리 요원들을 풀어줄 무슨 수단이든 강구해 보시길. - \cy그리고 내가 너와 함께 있어 줄께.","Neem dit geld en bezoek Irale die onze wapens levert. Dan zal deze sleutel je naar binnen brengen om de Gouverneur te zien. Hij is een corrupte marionet van de Orde, maar hij houdt ervan om deals te sluiten. Doe alles wat je nodig hebt om onze broeders te bevrijden.","Ta disse pengene og besøk Irale som leverer våpnene våre. Med denne nøkkelen kommer du inn til guvernøren. Han er en korrupt nikkedukke for Ordenen, men han elsker å inngå avtaler. Gjør det du må for å befri våre våpenbrødre.","Weź te pieniądze i idź do Irale, który dostarcza nam bronie. Potem, ten klucz pozwoli ci spotkać się z Gubernatorem. Jest on skorumpowaną marionetką Zakonu, ale lubi robić interesy. Rób co musisz by uwolnić naszych towarzyszy broni.","Pegue este dinheiro e visite o Irale, nosso fornecedor de armas. Depois use esta chave para entrar e falar com o Governador. Ele é um fantoche corrupto da Ordem mas ele adora negociar. Faça o que for necessário para libertar os nossos irmãos de armas.",,"Ia acești bani și vizitează pe Irale, cel care ne aprovizionează cu arme. Apoi, cheia asta îți va permite să intri să îl vezi pe Guvernator. El este o marionetă coruptă a Ordinului, dar adoră să facă târguri. Fă orice e necesar pentru a ne putea elibera frații.","Возьми эти деньги и посети Ирэйла, нашего поставщика оружия. Затем, с этим ключом, ты пройдёшь к губернатору. Он продажная марионетка Ордена, но обожает торговаться. Делай всё, что сочтёшь нужным, но освободи наших братьев по оружию.",,"Bu parayı al ve silahlarımızı tedarik eden İrale'yi ziyaret et. Sonra, bu anahtar seni valiyi görmeye götürecek. Tarikat'ın yozlaşmış bir kuklasıdır ama anlaşma yapmayı sever. Silah arkadaşlarımızı serbest bırakmak için ne gerekiyorsa yap." -I'll see to it.,TXT_RPLY0_SCRIPT03_D7580_ILLSE,〃 (〃),,,Dohlédnu na to.,Jeg skal nok sørge for det.,"Ich seh, was ich machen kann.",,"Mi vidos tion, kion mi faru.",Veré qué hacer.,Voy a ver qué hacer.,Hoidan asian.,Je m'y attelle.,Megteszem.,Mi darò da fare.,了解した。,한 번 확인하러 가보겠습니다.,Ik zal ervoor zorgen.,Jeg skal sørge for det.,Zajmę się tym.,Vou dar um jeito nisso.,,O să mă ocup.,Я позабочусь об этом.,,Ben halledeceğim. -Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT03_D9096_FIGHT,〃 (〃),,,Bojuj za Frontu a svobodu! Odchod.,Kæmp for fronten og friheden. Af sted.,Kämpfe für die Front und die Freiheit. Nun geh.,,Batalu pro la Fronto kaj liberigota lando. Ekagu.,Lucha por el Frente y la libertad. En marcha.,,Taistele Rintaman ja vapauden puolesta. Liikkeelle mars.,Battez vous pour le Front et pour la liberté. Repos.,Együtt a Frontért és a szabadságért! Indulás!,"Lotta, per il Fronte e per la libertà! E ora, al lavoro.",フロントと自由の為の闘争を。さあ向かえ。,"프론트와 자유를 향하여, 전진하세요!",Vecht voor het Front en vrijheid. Verhuizen.,Kjemp for Fronten og friheten. Av sted.,Walcz dla Frontu i wolności. Wykonać.,Lute pela Frente e pela liberdade. Agora vá.,,Luptă pentru Front și libertate. Acum pleacă.,Сражайся за свободу и справедливость. Выдвигайся.,,Cephe ve özgürlük için savaşın. Dışarı çıkın. + \cy그리고 내가 너와 함께 있어 줄께.","Neem dit geld en bezoek Irale die onze wapens levert. Dan zal deze sleutel je naar binnen brengen om de Gouverneur te zien. Hij is een corrupte marionet van de Orde, maar hij houdt ervan om deals te sluiten. Doe alles wat je nodig hebt om onze broeders te bevrijden.","Ta disse pengene og besøk Irale som leverer våpnene våre. Med denne nøkkelen kommer du inn til guvernøren. Han er en korrupt nikkedukke for Ordenen, men han elsker å inngå avtaler. Gjør det du må for å befri våre våpenbrødre.","Weź te pieniądze i idź do Irale, który dostarcza nam bronie. Potem, ten klucz pozwoli ci spotkać się z Gubernatorem. Jest on skorumpowaną marionetką Zakonu, ale lubi robić interesy. Rób co musisz by uwolnić naszych towarzyszy broni.","Pegue este dinheiro e visite o Irale, nosso fornecedor de armas. Depois use esta chave para entrar e falar com o Governador. Ele é um fantoche corrupto da Ordem mas ele adora negociar. Faça o que for necessário para libertar os nossos irmãos de armas.",,"Ia acești bani și vizitează pe Irale, cel care ne aprovizionează cu arme. Apoi, cheia asta îți va permite să intri să îl vezi pe Guvernator. El este o marionetă coruptă a Ordinului, dar adoră să facă târguri. Fă orice e necesar pentru a ne putea elibera frații.","Возьми эти деньги и посети Ирэйла, нашего поставщика оружия. Затем, с этим ключом, ты пройдёшь к губернатору. Он продажная марионетка Ордена, но обожает торговаться. Делай всё, что сочтёшь нужным, но освободи наших братьев по оружию.",,"Ta de här pengarna och besök Irale som levererar våra vapen. Sedan kommer den här nyckeln att ge dig tillträde till guvernören. Han är en korrupt marionett för Orden, men han älskar att göra affärer. Gör vad du behöver för att befria våra vapenbröder.","Bu parayı al ve silahlarımızı tedarik eden İrale'yi ziyaret et. Sonra, bu anahtar seni valiyi görmeye götürecek. Tarikat'ın yozlaşmış bir kuklasıdır ama anlaşma yapmayı sever. Silah arkadaşlarımızı serbest bırakmak için ne gerekiyorsa yap." +I'll see to it.,TXT_RPLY0_SCRIPT03_D7580_ILLSE,〃 (〃),,,Dohlédnu na to.,Jeg skal nok sørge for det.,"Ich seh, was ich machen kann.",,"Mi vidos tion, kion mi faru.",Veré qué hacer.,Voy a ver qué hacer.,Hoidan asian.,Je m'y attelle.,Megteszem.,Mi darò da fare.,了解した。,한 번 확인하러 가보겠습니다.,Ik zal ervoor zorgen.,Jeg skal sørge for det.,Zajmę się tym.,Vou dar um jeito nisso.,,O să mă ocup.,Я позабочусь об этом.,,Jag ska se till det.,Ben halledeceğim. +Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT03_D9096_FIGHT,〃 (〃),,,Bojuj za Frontu a svobodu! Odchod.,Kæmp for fronten og friheden. Af sted.,Kämpfe für die Front und die Freiheit. Nun geh.,,Batalu pro la Fronto kaj liberigota lando. Ekagu.,Lucha por el Frente y la libertad. En marcha.,,Taistele Rintaman ja vapauden puolesta. Liikkeelle mars.,Battez vous pour le Front et pour la liberté. Repos.,Együtt a Frontért és a szabadságért! Indulás!,"Lotta, per il Fronte e per la libertà! E ora, al lavoro.",フロントと自由の為の闘争を。さあ向かえ。,"프론트와 자유를 향하여, 전진하세요!",Vecht voor het Front en vrijheid. Verhuizen.,Kjemp for Fronten og friheten. Av sted.,Walcz dla Frontu i wolności. Wykonać.,Lute pela Frente e pela liberdade. Agora vá.,,Luptă pentru Front și libertate. Acum pleacă.,Сражайся за свободу и справедливость. Выдвигайся.,,Kämpa för fronten och friheten. Gå ut.,Cephe ve özgürlük için savaşın. Dışarı çıkın. "The prisoners have been welcomed back, thanks to you. Here's some gold, go visit the medic and the weapons trainer and then, I have higher goals for you.",TXT_DLG_SCRIPT03_D10612_THEPR,〃 (Crystal mission),,,"Vězně jsme, díky tobě, přivítali zpět. Tady je nějaké zlato, jdi navštívit zdravotníka a zbraňmistra. Pak mám pro tebe vyšší cíle.","Fangerne er blevet budt velkommen tilbage, takket være dig. Her er lidt guld, besøg lægen og våbentræneren, og så har jeg højere mål for dig.","Die Gefangenen sind zu uns zrückgekehrt, dank dir. Hier hast du etwas Gold, schau mal beim Sanitäter und beim Waffentrainer rein, danach sind höhere Ziele in Aussicht.",,"Ni povis ribonveni la ekskaptitojn danke al vi. Jen iom da oro; iru renkonti la kuraciston kaj la armilan trejniston, kaj tiam mi havas pli altajn celojn por vi.","Los prisioneros ya han sido bienvenidos de vuelta gracias a ti. Aquí tienes algo de oro; ve a ver al médico y al entrenador de armas, y después... tengo mayores metas para ti.","Los prisioneros ya fueron bienvenidos de vuelta gracias a ti. Aquí tienes algo de oro; ve a ver al médico y al entrenador de armas, y después... tengo mayores metas para ti.","Vangit on otettu takaisin vastaan, kiitos sinun. Tässä kultaa; mene tapaamaan lääkintämiestä ja asekouluttajaa, minkä jälkeen minulla on sinulle korkeampia tavoitteita.","Les prisonniers sont revenus à bon port, grâce à vous. Voici de l'argent, allez voir le médecin et le maître d'armes, puis j'aurais d'autres missions pour vous.","A foglyok visszatértek hála neked. Itt van valamennyi arany, látogasd meg a szanitécot és a fegyverkereskedőt, aztán térj vissza mert nagy céljaim vannak veled.","I prigionieri sono stati riportati sani e salvi, grazie a te. Ecco dell'oro. Visita il dottore e l'istruttore d'armi, e poi, ho altri obiettivi per te.","逃げ出した囚人たちを迎え入れた。 君の活躍に感謝する。幾つか報酬を与えよう。 それとメディックと訓練師も訪ねるといい、 -その後に頼みたいことがある。",감금된 병사들이 당신 덕에 다시 돌아왔습니다. 정말 감사드립니다! 이 보상을 받으시고 의무관이랑 무기 담당관을 찾아뵈시길 바랍니다. 또 다른 임무가 기다리고 있으니까요.,"De gevangenen zijn dankzij u weer welkom teruggekomen. Hier is wat goud, ga naar de dokter en de wapentrainer en dan heb ik hogere doelen voor je.","Fangene har blitt ønsket velkommen tilbake, takket være deg. Her er litt gull, gå og besøk saniteten og våpentreneren, og så har jeg høyere mål for deg.","Więźniowie zostali ponownie powitani, wszystko dzięki tobie. Masz tu trochę złota, idź do medyka i instruktora broni, a potem powiem ci jakie większe zadania mam dla ciebie.","Recebemos os prisioneiros de volta, graças a você. Pegue este dinheiro, visite o médico, o treinador de armas e depois eu vou te dar uns objetivos mais importantes.",,"Prizonierii au fost primiți înapoi, mulțumită ție. Uite niște aur, vizitează medicul și antrenorul de arme, după aceea, am planuri mai mărețe pentru tine.","Благодаря тебе, пленники вернулись к нам. Вот немного золота. Посети медика и инструктора по стрельбе, а потом тебя ждут ещё более ответственные задания.",,"Sayende mahkumlar geri döndü. İşte biraz altın, sıhhiyeciyi ve silah eğitmenini ziyaret et ve sonra, senin için daha yüksek hedeflerim var." -I will. What's next?,TXT_RPLY0_SCRIPT03_D10612_IWILL,〃 (〃),,,Půjdu. Co dál?,Det vil jeg gøre. Hvad er det næste?,"Alles klar, was gibt's als Nächstes?",,Mi faros tion. Kio sekvas?,Lo haré. ¿Qué sigue?,Claro. ¿Qué sigue?,Menen. Mitä seuraavaksi on luvassa?,"Très bien, quoi maintenant?",Így teszek. Mi a következő lépés?,Lo farò. Qual'è la prossima mossa?,次は何だ?,그렇군요. 그 다음은 뭐죠?,Dat zal ik doen. Wat is het volgende?,Det skal jeg gjøre. Hva er det neste?,Dobrze. Co dalej?,Farei isso. Qual a próxima missão?,,Mă voi conforma. Ce facem mai departe?,Хорошо. Что дальше?,,Yapacağım. Sırada ne var? +その後に頼みたいことがある。",감금된 병사들이 당신 덕에 다시 돌아왔습니다. 정말 감사드립니다! 이 보상을 받으시고 의무관이랑 무기 담당관을 찾아뵈시길 바랍니다. 또 다른 임무가 기다리고 있으니까요.,"De gevangenen zijn dankzij u weer welkom teruggekomen. Hier is wat goud, ga naar de dokter en de wapentrainer en dan heb ik hogere doelen voor je.","Fangene har blitt ønsket velkommen tilbake, takket være deg. Her er litt gull, gå og besøk saniteten og våpentreneren, og så har jeg høyere mål for deg.","Więźniowie zostali ponownie powitani, wszystko dzięki tobie. Masz tu trochę złota, idź do medyka i instruktora broni, a potem powiem ci jakie większe zadania mam dla ciebie.","Recebemos os prisioneiros de volta, graças a você. Pegue este dinheiro, visite o médico, o treinador de armas e depois eu vou te dar uns objetivos mais importantes.",,"Prizonierii au fost primiți înapoi, mulțumită ție. Uite niște aur, vizitează medicul și antrenorul de arme, după aceea, am planuri mai mărețe pentru tine.","Благодаря тебе, пленники вернулись к нам. Вот немного золота. Посети медика и инструктора по стрельбе, а потом тебя ждут ещё более ответственные задания.",,"Fångarna har välkomnats tillbaka, tack vare dig. Här är lite guld, besök läkaren och vapentränaren och sedan har jag högre mål för dig.","Sayende mahkumlar geri döndü. İşte biraz altın, sıhhiyeciyi ve silah eğitmenini ziyaret et ve sonra, senin için daha yüksek hedeflerim var." +I will. What's next?,TXT_RPLY0_SCRIPT03_D10612_IWILL,〃 (〃),,,Půjdu. Co dál?,Det vil jeg gøre. Hvad er det næste?,"Alles klar, was gibt's als Nächstes?",,Mi faros tion. Kio sekvas?,Lo haré. ¿Qué sigue?,Claro. ¿Qué sigue?,Menen. Mitä seuraavaksi on luvassa?,"Très bien, quoi maintenant?",Így teszek. Mi a következő lépés?,Lo farò. Qual'è la prossima mossa?,次は何だ?,그렇군요. 그 다음은 뭐죠?,Dat zal ik doen. Wat is het volgende?,Det skal jeg gjøre. Hva er det neste?,Dobrze. Co dalej?,Farei isso. Qual a próxima missão?,,Mă voi conforma. Ce facem mai departe?,Хорошо. Что дальше?,,Det kommer jag att göra. Vad kommer härnäst?,Yapacağım. Sırada ne var? "A single crystal runs the power grid which drives the Order's shields. Destroy that crystal and you will punch huge holes in the Order's defenses. Blackbird will lead you to a spy who has a way in, good luck.",TXT_DLG_SCRIPT03_D12128_ASING,〃 (〃),,,"Elektrická síť, kterou jsou poháněné štíty Řádu, je napájena z jednoho krystalu. Znič ten krystal a zasaď tak obří ránu obranám Řádu. Straka tě navede ke špiónovi, který zná cestu dovnitř. Hodně štěstí.","En enkelt krystal driver det kraftnet, der driver ordenens skjolde. Ødelæg det krystal, og du vil slå store huller i Ordenens forsvar. Blackbird vil føre dig til en spion, der har en vej ind, held og lykke.","Ein einziger Kristall kontrolliert das gesamte Energiesystem für die Kraftschilde des Ordens. Zerstöre diesen Kristall und du wirst riesige Löcher in die Verteidigungsanlagen des Ordens schlagen. Blackbird führt dich zu einem Spion, der dir Einlass verschaffen kann. Viel Glück.",,"Ununura kristalo nutras la elektrizan sistemon, kiu tenas la ŝildojn de la kastelo. Detruu ĝin por fari grandegan «breĉon» en la defendojn de La Ordono. BlackBird gvidos vin al spiono, kiu havas manieron eniri. Ŝancon.",Un único cristal alimenta la red eléctrica que mantiene los escudos del castillo. Destruye ese cristal y abrirás grandes brechas en las defensas de La Orden. BlackBird te guiará hacia un espía que tiene una forma de entrar. Buena suerte.,Un único cristal alimenta la red eléctrica que mantiene los escudos del castillo. Destruye ese cristal para abrir grandes brechas en las defensas de La Orden. BlackBird te va a guiar hacia un espía que tiene una forma de entrar. Buena suerte.,"Kaupungin sähköverkon voimanlähteenä toimii yksittäinen kristalli, jonka voimaa Veljeskunnan kilvet käyttävät. Tuhoamalla kristallin puhkot valtavia reikiä Veljeskunnan puolustuksiin. Blackbird opastaa sinut vakoojan luo, jolla on sisäänpääsykeino. Lykkyä tykö.",Un seul cristal fait fonctionner la grille énergétique qui alimente les boucliers de l'Ordre. Détruisez ce cristal et vous créez des énormes failles dans les défenses de l'Ordre. Blackbird va vous mener à un espion qui a un moyen de vous faire rentrer. Bonne chance.,"Egyetlen krisztály hajtja az energia hálózatot, erre van rákötve a Rend pajzsa. Semmisítsd meg ezt a kristályt, és hatalmas lyukakat fogsz vágni a Rend védelmébe. Feketerigó elvezet egy spionhoz, aki tudja hogyan kell bejutni, sok sikert.","Un singolo cristallo alimenta l'impianto energetico che controlla gli scudi dell'Ordine. Distruggendo quel cristallo causerai enormi danni alle difese dell'Ordine. Blackbird ti porterà da una spia che ha indicazioni su come accedere al cristallo, buona fortuna.","とあるパワークリスタルがオーダー基地の シールドを維持している。それを破壊して 奴等の防壁に巨大な穴を開けるのだ。 潜入する為の情報を持ったスパイを ブラックバードが導いてくれる。","오더의 방어막을 생성하는 수정체가 그들의 발전소 안에 있습니다. 그것을 파괴할 수만 있다면, 오더의 방어 체계를 약화할 수 있을 겁니다. 블랙버드가 길을 알려줄 첩자의 위치를 알려줄 것입니다. 건투를 빌어요. - \cy워너는 우리가 모집한 첩자야. 그는 발전소 창고에 있어.","Een enkel kristal loopt over het elektriciteitsnet dat de schilden van de Orde aandrijft. Vernietig dat kristal en je zult grote gaten slaan in de verdediging van de Orde. Blackbird leidt je naar een spion die een weg naar binnen heeft, veel geluk.","En enkelt krystall driver kraftnettet som driver Ordenens skjold. Ødelegg den krystallen, og du vil slå store hull i Ordenens forsvar. Blackbird vil føre dere til en spion som har en vei inn. Lykke til.","Pojedynczy kryształ napędza sieć energetyczną, która zasila osłony Zakonu. Zniszcz kryształ, a Zakon będzie miał ogromne luki w ochronie. Blackbird zaprowadzi cię do szpiega, który ma sposób, aby się tam dostać, powodzenia.",Há um cristal que fornece energia à rede elétrica que mantém os escudos da Ordem em funcionamento. Destrua esse cristal e você abrirá brechas grandes nas defesas da Ordem. Blackbird guiará você a um espião que sabe como entrar lá. Boa sorte.,,"Un cristal unic alimentează grila de putere care acționează scuturile Ordiului. Distruge cristalul și veți provoca daune imense sistemului de apărare al Ordinului. Blackbird vă va introduce unui spion care să vă ofere o cale în interior, multă baftă.","Энергосеть, которая питает щиты Ордена, работает от одного кристалла. Уничтожь этот кристалл, и ты пробьёшь огромную брешь в их обороне. «Чёрный дрозд» приведёт тебя к шпиону, который знает, как проникнуть на станцию. Удачи!",,"Tarikat'ın kalkanlarını çalıştıran güç şebekesini tek bir kristal çalıştırıyor. O kristali yok edersen Tarikat'ın savunmasında büyük delikler açacaksın. Karatavuk seni içeri girmenin bir yolunu bulan bir casusa götürecek, iyi şanslar." -We'll get it.,TXT_RPLY0_SCRIPT03_D12128_WELLG,〃 (〃),,,Zničíme jej.,Vi skal nok få fat i den.,Das werden wir hinkriegen.,,Ni sukcesos.,Lo conseguiremos.,Lo vamos a lograr.,Saamme sen.,Je m'en occupe.,Megszerezzük.,Ce la faremo.,すぐ始めよう。,그 수정체를 파괴하겠습니다.,We krijgen het wel.,Vi får tak i den.,Poradzimy sobie.,Vamos conseguir.,,Vom ajunge în interior.,Мы справимся.,,Onu yakalayacağız. -Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT03_D13644_FIGHT,〃 (〃),,,Bojuj za Frontu a svobodu! Odchod.,Kæmp for fronten og friheden. Af sted.,Kämpfe für die Front und die Freiheit. Nun geh.,,Batalu pro la Fronto kaj liberigota lando. Ekagu.,Lucha por el Frente y la libertad. En marcha.,,Taistele Rintaman ja vapauden puolesta. Liikkeelle mars.,Battez vous pour le Front et pour la liberté. Repos.,Együtt a Frontért és a szabadságért! Indulás!,"Lotta, per il Fronte e per la libertà! E ora, al lavoro.",フロントと自由の為の闘争を。さあ向かえ。,"프론트와 자유를 향하여, 전진하세요!",Vecht voor het front en vrijheid. Verhuizen.,Kjemp for Fronten og friheten. Av sted.,Walcz dla Frontu i wolności. Wykonać.,Lute pela Frente e pela liberdade. Agora vá.,,Luptați pentru Front și libertate. Acum plecați.,Сражайся за свободу и справедливость. Выдвигайся.,,Cephe ve özgürlük için savaşın. Çıkın. + \cy워너는 우리가 모집한 첩자야. 그는 발전소 창고에 있어.","Een enkel kristal loopt over het elektriciteitsnet dat de schilden van de Orde aandrijft. Vernietig dat kristal en je zult grote gaten slaan in de verdediging van de Orde. Blackbird leidt je naar een spion die een weg naar binnen heeft, veel geluk.","En enkelt krystall driver kraftnettet som driver Ordenens skjold. Ødelegg den krystallen, og du vil slå store hull i Ordenens forsvar. Blackbird vil føre dere til en spion som har en vei inn. Lykke til.","Pojedynczy kryształ napędza sieć energetyczną, która zasila osłony Zakonu. Zniszcz kryształ, a Zakon będzie miał ogromne luki w ochronie. Blackbird zaprowadzi cię do szpiega, który ma sposób, aby się tam dostać, powodzenia.",Há um cristal que fornece energia à rede elétrica que mantém os escudos da Ordem em funcionamento. Destrua esse cristal e você abrirá brechas grandes nas defesas da Ordem. Blackbird guiará você a um espião que sabe como entrar lá. Boa sorte.,,"Un cristal unic alimentează grila de putere care acționează scuturile Ordiului. Distruge cristalul și veți provoca daune imense sistemului de apărare al Ordinului. Blackbird vă va introduce unui spion care să vă ofere o cale în interior, multă baftă.","Энергосеть, которая питает щиты Ордена, работает от одного кристалла. Уничтожь этот кристалл, и ты пробьёшь огромную брешь в их обороне. «Чёрный дрозд» приведёт тебя к шпиону, который знает, как проникнуть на станцию. Удачи!",,"En enda kristall driver kraftnätet som driver ordens sköldar. Förstör den kristallen och du kommer att slå enorma hål i ordens försvar. Blackbird kommer att leda dig till en spion som har en väg in, lycka till.","Tarikat'ın kalkanlarını çalıştıran güç şebekesini tek bir kristal çalıştırıyor. O kristali yok edersen Tarikat'ın savunmasında büyük delikler açacaksın. Karatavuk seni içeri girmenin bir yolunu bulan bir casusa götürecek, iyi şanslar." +We'll get it.,TXT_RPLY0_SCRIPT03_D12128_WELLG,〃 (〃),,,Zničíme jej.,Vi skal nok få fat i den.,Das werden wir hinkriegen.,,Ni sukcesos.,Lo conseguiremos.,Lo vamos a lograr.,Saamme sen.,Je m'en occupe.,Megszerezzük.,Ce la faremo.,すぐ始めよう。,그 수정체를 파괴하겠습니다.,We krijgen het wel.,Vi får tak i den.,Poradzimy sobie.,Vamos conseguir.,,Vom ajunge în interior.,Мы справимся.,,Vi kommer att hitta den.,Onu yakalayacağız. +Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT03_D13644_FIGHT,〃 (〃),,,Bojuj za Frontu a svobodu! Odchod.,Kæmp for fronten og friheden. Af sted.,Kämpfe für die Front und die Freiheit. Nun geh.,,Batalu pro la Fronto kaj liberigota lando. Ekagu.,Lucha por el Frente y la libertad. En marcha.,,Taistele Rintaman ja vapauden puolesta. Liikkeelle mars.,Battez vous pour le Front et pour la liberté. Repos.,Együtt a Frontért és a szabadságért! Indulás!,"Lotta, per il Fronte e per la libertà! E ora, al lavoro.",フロントと自由の為の闘争を。さあ向かえ。,"프론트와 자유를 향하여, 전진하세요!",Vecht voor het front en vrijheid. Verhuizen.,Kjemp for Fronten og friheten. Av sted.,Walcz dla Frontu i wolności. Wykonać.,Lute pela Frente e pela liberdade. Agora vá.,,Luptați pentru Front și libertate. Acum plecați.,Сражайся за свободу и справедливость. Выдвигайся.,,Kämpa för fronten och friheten. Gå ut.,Cephe ve özgürlük için savaşın. Çıkın. "You've exceeded all of our expectations. Because of your daring our troops are on the move. I want you two to join the assault, with a specific target. Take out the Programmer. It's time to reveal what we've found out about this layer of the Order.",TXT_DLG_SCRIPT03_D15160_YOUVE,〃 (Progammer mission),,,"Překonal jsi všechny naše představy. Díky tvé odvaze se naše vojska vydala na pochod. Chci, abyste se vy dva připojili k útoku se zvláštním cílem: zabít Programátora. Je čas odhalit, co jsme se dozvěděli o Řádu.","Du har overgået alle vores forventninger. På grund af jeres mod er vores tropper på vej. Jeg vil have jer to til at deltage i angrebet, med et specifikt mål. Udrydd programmereren. Det er tid til at afsløre, hvad vi har fundet ud af om dette lag af Ordenen.","Du hast alle unsere Erwartungen übertroffen. Dank dir sind unsere Truppen auf dem Vormarsch. Ich möchte, dass du auch an dem Angriff teilnimmst, aber mit einer Spezialmission. Eliminiere den Programmierer. Es ist Zeit zu enthüllen, was wir über dien Teil des Ordens herausgefunden haben.",,"Vi superis ĉiujn el niaj atendoj. Pro viaj heroaĵoj, niaj trupoj jam ekagis. Mi volas, ke vi ambaŭ aliĝu al la sturmo kun specifa celo: mortigi La Programiston. Estas tempo malkaŝi tion, kion ni malkovris pri tiu aspekto de La Ordono.",Has superado todas nuestras expectativas. Por tu hazaña nuestras tropas ya están en movimiento. Quiero que los dos os unáis al asalto con un objetivo específico: acabar con el Programador. Ya es hora de revelar lo que hemos descubierto sobre ese lado de La Orden.,Superaste todas nuestras expectativas. Por tu hazaña nuestras tropas ya están en movimiento. Quiero que los dos se unan al asalto con un objetivo específico: matar al Programador. Ya es hora de revelar lo que descubrimos sobre ese lado de La Orden.,"Olet ylittänyt kaikki odotuksemme. Rohkeutesi ansiosta joukkomme ovat liikkeellä. Haluan teidän molempien osallistuvan hyökkäykseen erityistehtävällä: Tuhotkaa Ohjelmoitsija. On aika paljastaa, mitä olemme saaneet selville Veljeskunnan tästä kerroksesta.","Vous avez dépassé toutes nos attentes. Grâce à votre audace, nos troupes sont sur le pied de guerre. Je que vous rejoignez l'assaut tous les deux, avec une cible précise. Eliminez le Programmeur. Il est l'heure de révéler ce que nous avons découvert sur cette facette de l'Ordre.",Túltettetek az elvárásaimon. Merész tetteitek inspirálóan hatottak katonáinkra. Mindkettőtöket szánok egy speciális feladatot a roham során. Iktassátok ki a Programozót. Ideje világosságra hozni amit találtunk a Rend ezen ágáról.,"Hai superato tutte le nostre aspettative. Grazie al vostro coraggio, le nostre truppe sono in movimento. Voglio che voi due vi uniate all'assalto, con un obiettivo specifico. Elimina il Programmatore. È giunto il momento di rivelare quello che abbiamo scoperto di questo strato dell'Ordine.","君達は我々の期待を超える活躍を行ってくれた。 君の勇猛さに私の部隊が動き出した。 今度は君達二人にある目的の為、強襲部隊に 加わって欲しい。プログラマーを討ち取るのだ。 オーダーに纏わる様々な事情について -明らかにする時が来た。",당신의 성과는 우리가 예상했던 것보다 훨씬 굉장하더군요. 당신의 노고 덕에 이제 우리가 활동을 본격적으로 개시할 수 있게 되었습니다. 자네와 블랙버드가 이번 공격에 참여했으면 합니다. 그리고 프로그래머를 없애버리세요. 지금이야말로 오더의 실체가 어떠한지를 폭로할 절호의 기회입니다.,"Je hebt al onze verwachtingen overtroffen. Door jouw durf zijn onze troepen in beweging. Ik wil dat jullie twee zich bij de aanval aansluiten, met een specifiek doelwit. Schakel de programmeur uit. Het is tijd om te onthullen wat we hebben ontdekt over deze laag van de Orde.","Du har overgått alle våre forventninger. På grunn av deres dristighet er troppene våre i bevegelse. Jeg vil at dere to skal bli med på angrepet, med et spesifikt mål. Drep programmereren. Det er på tide å avsløre hva vi har funnet ut om dette laget av Ordenen.","Przekroczyłeś nasze wszelkie oczekiwania. Dzięki twej odwadze nasi żołnierze są w drodze. Chciałbym, abyście razem dołączyli do szturmu, mając konkretny cel. Zabijcie Programistę. Czas pokazać co odkryliśmy na temat tego pionka Zakonu.","Você superou todas as nossas expectativas. Graças à sua audácia as nossas tropas estão em movimento. Quero que vocês dois participem do ataque, com um alvo específico. Elimine o Programador. Já está na hora de revelar o que descobrimos a respeito dessa parte da Ordem. ",,"Ne-ați depășit toate așteptările. Datorită îndrăznelii voastre trupele noastre s-au putut pune în mișcare. Vreau să vă alăturați asaltului, cu o țintă specifică. Eliminați-l pe Programator. E timpul să dezvăluim ce am descoperit despre acest nivel al Ordinului.","Ты превзошёл все наши ожидания. Благодаря твоей отваге наши войска уже в пути. Я хочу, чтобы вы двое присоединились к атаке, с особой целью — уничтожить Программиста. Настало время рассказать всё, что мы смогли узнать об этом уровне власти в Ордене.",,"Tüm beklentilerimizi aştınız. Cesaretiniz sayesinde birliklerimiz harekete geçti. İkinizin saldırıya katılmanızı istiyorum, belirli bir hedefle. Programcıyı ortadan kaldırın. Tarikat'ın bu katmanı hakkında ne bulduğumuzu açıklamanın zamanı geldi." -Tell me what we know.,TXT_RPLY0_SCRIPT03_D15160_TELLM,〃 (〃),,,"Řekni mi, co víme.","Fortæl mig, hvad vi ved.",Sag mir was du weißt.,,"Diru tion, kion ni scias.",Dime lo que sabemos.,,"Kerro, mitä tiedämme.",Donnez-moi ce que vous savez.,Mondd el mit tudtunk meg.,Dimmi cosa sappiamo.,こちらに知っている事を教えてくれ。,그 비밀에 대해서 알려주세요.,Vertel me wat we weten.,Fortell meg hva vi vet.,Powiedz co wiadomo.,Conte-me o que sabemos.,,Spune-mi ce știi.,Расскажи мне всё.,,Bana ne bildiğimizi söyle. +明らかにする時が来た。",당신의 성과는 우리가 예상했던 것보다 훨씬 굉장하더군요. 당신의 노고 덕에 이제 우리가 활동을 본격적으로 개시할 수 있게 되었습니다. 자네와 블랙버드가 이번 공격에 참여했으면 합니다. 그리고 프로그래머를 없애버리세요. 지금이야말로 오더의 실체가 어떠한지를 폭로할 절호의 기회입니다.,"Je hebt al onze verwachtingen overtroffen. Door jouw durf zijn onze troepen in beweging. Ik wil dat jullie twee zich bij de aanval aansluiten, met een specifiek doelwit. Schakel de programmeur uit. Het is tijd om te onthullen wat we hebben ontdekt over deze laag van de Orde.","Du har overgått alle våre forventninger. På grunn av deres dristighet er troppene våre i bevegelse. Jeg vil at dere to skal bli med på angrepet, med et spesifikt mål. Drep programmereren. Det er på tide å avsløre hva vi har funnet ut om dette laget av Ordenen.","Przekroczyłeś nasze wszelkie oczekiwania. Dzięki twej odwadze nasi żołnierze są w drodze. Chciałbym, abyście razem dołączyli do szturmu, mając konkretny cel. Zabijcie Programistę. Czas pokazać co odkryliśmy na temat tego pionka Zakonu.","Você superou todas as nossas expectativas. Graças à sua audácia as nossas tropas estão em movimento. Quero que vocês dois participem do ataque, com um alvo específico. Elimine o Programador. Já está na hora de revelar o que descobrimos a respeito dessa parte da Ordem. ",,"Ne-ați depășit toate așteptările. Datorită îndrăznelii voastre trupele noastre s-au putut pune în mișcare. Vreau să vă alăturați asaltului, cu o țintă specifică. Eliminați-l pe Programator. E timpul să dezvăluim ce am descoperit despre acest nivel al Ordinului.","Ты превзошёл все наши ожидания. Благодаря твоей отваге наши войска уже в пути. Я хочу, чтобы вы двое присоединились к атаке, с особой целью — уничтожить Программиста. Настало время рассказать всё, что мы смогли узнать об этом уровне власти в Ордене.",,"Du har överträffat alla våra förväntningar. På grund av er djärvhet är våra trupper på väg. Jag vill att ni två ansluter er till anfallet, med ett specifikt mål. Ta ut programmeraren. Det är dags att avslöja vad vi har kommit fram till om det här skiktet av Orden.","Tüm beklentilerimizi aştınız. Cesaretiniz sayesinde birliklerimiz harekete geçti. İkinizin saldırıya katılmanızı istiyorum, belirli bir hedefle. Programcıyı ortadan kaldırın. Tarikat'ın bu katmanı hakkında ne bulduğumuzu açıklamanın zamanı geldi." +Tell me what we know.,TXT_RPLY0_SCRIPT03_D15160_TELLM,〃 (〃),,,"Řekni mi, co víme.","Fortæl mig, hvad vi ved.",Sag mir was du weißt.,,"Diru tion, kion ni scias.",Dime lo que sabemos.,,"Kerro, mitä tiedämme.",Donnez-moi ce que vous savez.,Mondd el mit tudtunk meg.,Dimmi cosa sappiamo.,こちらに知っている事を教えてくれ。,그 비밀에 대해서 알려주세요.,Vertel me wat we weten.,Fortell meg hva vi vet.,Powiedz co wiadomo.,Conte-me o que sabemos.,,Spune-mi ce știi.,Расскажи мне всё.,,Berätta vad vi vet.,Bana ne bildiğimizi söyle. "The Programmer's lair is in the castle. Now, see the medic, grab some ammo and go get him.",TXT_DLG_SCRIPT03_D16676_THEPR,〃 (〃),,,"Programátorovo doupě je v hradu. Jdi navštívit zdravotníka, vem si munici a jdi ho dostat.","Programmørens hule er i slottet. Gå hen til lægen, tag noget ammunition og hent ham.",Der Programmierer hät sich irgendwo in der Burg auf. Und nun gehe bitter zum Sanitäter und beschaff dir neue Munition - und dann mach ihn fertig.,,"La kaŝejo de la Programisto estas en la kastelo. Vi nun renkontu la kuraciston, prenu municiojn kaj iru mortigi lin.","La guarida del Programador está en el castillo. Ahora ve a ver al médico, coge munición y ve a por él.","La guarida del Programador está en el castillo. Ahora ve a ver al médico, toma munición y ve por él.","Ohjelmoitsijan piilopaikka on linnassa. Käy nyt tapaamassa lääkintämiestä, ota panoksia matkaan ja napatkaa hänet.","Le repaire du Programmeur est dans le château. Allez voir le médecin, rechargez vos armes, et allez vous occuper de lui.","A Programozó búvóhelye a kastélyban található. Látogasd meg a szanitécot, vegyél magadhoz egy kis ammot, és irány a kastély.","La tana del Programmatore è nel castello. Ora, fai una visita al medico, prendi un pò di munizione, e vallo a predendere.","プログラマーの居場所は城内だ。それと、 メディックと訓練士に会い弾薬を補給したら 奴を倒せ。","프로그래머가 거주하는 곳은 성채 안에 있습니다. 의무관과 무기 담당관을 찾아뵈서 준비를 당당히 하시길 바랍니다. - \cy일생일대의 격전에 대비해. 돈 아끼지 말고 있는 대로 다 써.","Het hol van de programmeur is in het kasteel. Ga nu naar de dokter, pak wat munitie en ga hem halen.","Programmererens skjulested er i slottet. Gå til legen, hent ammunisjon og hent ham.","Kryjówka Programisty jest w zamku. Teraz idź do medyka, weź trochę amunicji i załatw go.","O covil do Programador fica no castelo. Agora vá ver o médico, pegue munição e vá atrás dele.",,"Bârlogul Programatorului e în castel. Acum, dute la medic, ia niște muniție, și prindeți-l.","Программист устроил себе логово в замке. Теперь наведайся к врачу, пополни боезапас, и расправься с ним.",,"Programcı'nın sığınağı kalenin içinde. Şimdi, doktoru gör, biraz cephane al ve gidip onu getir." -Let me at 'em!,TXT_RPLY0_SCRIPT03_D16676_LETME,〃 (〃),,,Pusť mě na ně!,Lad mig tage dem!,Lass mich das nur machen.,,Mi faros tion!,¡Voy a por ellos!,¡Voy por ellos!,Päästä minut niiden kimppuun!,Je vais me le faire!,Elkapom mindet!,Lasciali a me!,任せろ!,한 번 저질러 봅시다!,Laat me er naartoe gaan!,La meg ta dem!,Niech ja go dorwę!,Pode deixar!,,Le voi arăta eu lor!,Я им покажу!,,Bana bırakın! -Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT03_D18192_FIGHT,〃 (〃),,,Bojuj za Frontu a svobodu! Odchod.,Kæmp for fronten og friheden. Af sted.,Kämpfe für die Front und die Freiheit. Nun geh.,,Batalu pro la Fronto kaj liberigota lando. Ekagu.,Lucha por el Frente y la libertad. En marcha.,,Taistele Rintaman ja vapauden puolesta. Liikkeelle mars.,Battez vous pour le Front et pour la liberté. Repos.,Együtt a Frontért és a szabadságért! Indulás!,"Lotta, per il Fronte e per la libertà! E ora, al lavoro.",フロントと自由の為の闘争を。さあ向かえ。,"프론트와 자유를 향하여, 전진하세요!",Vecht voor het front en vrijheid. Verhuizen.,Kjemp for Fronten og friheten. Kom igjen.,Walcz dla Frontu i wolności. Wykonać.,Lute pela Frente e pela liberdade. Agora vá.,,Luptă pentru Front și libertate. Acum pleacă.,Сражайся за свободу и справедливость. Выдвигайся.,,Cephe ve özgürlük için savaşın. Dışarı çıkın. + \cy일생일대의 격전에 대비해. 돈 아끼지 말고 있는 대로 다 써.","Het hol van de programmeur is in het kasteel. Ga nu naar de dokter, pak wat munitie en ga hem halen.","Programmererens skjulested er i slottet. Gå til legen, hent ammunisjon og hent ham.","Kryjówka Programisty jest w zamku. Teraz idź do medyka, weź trochę amunicji i załatw go.","O covil do Programador fica no castelo. Agora vá ver o médico, pegue munição e vá atrás dele.",,"Bârlogul Programatorului e în castel. Acum, dute la medic, ia niște muniție, și prindeți-l.","Программист устроил себе логово в замке. Теперь наведайся к врачу, пополни боезапас, и расправься с ним.",,"Programmerarens gömställe finns i slottet. Gå till läkaren, ta lite ammunition och hämta honom.","Programcı'nın sığınağı kalenin içinde. Şimdi, doktoru gör, biraz cephane al ve gidip onu getir." +Let me at 'em!,TXT_RPLY0_SCRIPT03_D16676_LETME,〃 (〃),,,Pusť mě na ně!,Lad mig tage dem!,Lass mich das nur machen.,,Mi faros tion!,¡Voy a por ellos!,¡Voy por ellos!,Päästä minut niiden kimppuun!,Je vais me le faire!,Elkapom mindet!,Lasciali a me!,任せろ!,한 번 저질러 봅시다!,Laat me er naartoe gaan!,La meg ta dem!,Niech ja go dorwę!,Pode deixar!,,Le voi arăta eu lor!,Я им покажу!,,Låt mig ta dem!,Bana bırakın! +Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT03_D18192_FIGHT,〃 (〃),,,Bojuj za Frontu a svobodu! Odchod.,Kæmp for fronten og friheden. Af sted.,Kämpfe für die Front und die Freiheit. Nun geh.,,Batalu pro la Fronto kaj liberigota lando. Ekagu.,Lucha por el Frente y la libertad. En marcha.,,Taistele Rintaman ja vapauden puolesta. Liikkeelle mars.,Battez vous pour le Front et pour la liberté. Repos.,Együtt a Frontért és a szabadságért! Indulás!,"Lotta, per il Fronte e per la libertà! E ora, al lavoro.",フロントと自由の為の闘争を。さあ向かえ。,"프론트와 자유를 향하여, 전진하세요!",Vecht voor het front en vrijheid. Verhuizen.,Kjemp for Fronten og friheten. Kom igjen.,Walcz dla Frontu i wolności. Wykonać.,Lute pela Frente e pela liberdade. Agora vá.,,Luptă pentru Front și libertate. Acum pleacă.,Сражайся за свободу и справедливость. Выдвигайся.,,Kämpa för fronten och friheten. Gå ut.,Cephe ve özgürlük için savaşın. Dışarı çıkın. Remember what the town hall looked like? That's a gentle reminder of what they're willing to do to get at us. Be careful.,TXT_DLG_SCRIPT03_D19708_REMEM,MAP03: Barracks.,,,"Pamatuješ si, jak dřív vypadala radnice? To je jemná přípomínka toho, co jsou schopni nám udělat. Buď opatrný.","Kan du huske, hvordan rådhuset så ud? Det er en blid påmindelse om, hvad de er villige til at gøre for at få fat i os. Vær forsigtig.","Denk daran, wie unser Rathaus aussieht. Das ist nur ein Dankzettel dafür, wie weit sie gehen würden um uns zu finden. Sei vorsichtig.",,"Ĉu vi memoras, kiel la urbodomo aspektis antaŭe? Ĝi nun estas afabla ekzemplo de tio, kion ili estas pretaj fari por forigi nin. Estu atenta.",¿Recuerdas como era antes el ayuntamiento? Ahora es una muestra amable de lo que son capaces de hacer contra nosotros. Ten cuidado.,,"Muistatko, miltä kaupungintalo näytti? Se on hienovarainen muistutus siitä, mitä he ovat valmiita tekemään saadakseen meidät. Ole varuillasi.",Souvenez-vous de l'hôtel de ville avant tout cela? C'est une manière gentille de nous montrer ce qu'ils sont capables de faire pour se débarasser de nous. Faites attention.,"Emlékszel, hogy nézett ki a vársoháza? Jó példa arra, hogy mire képesek, hogy elintézzenek minket. Légy óvatos.",Ti ricordi com'era il municipio una volta? Adesso è un piccolo ricordo di cosa sono disposti a fare per attaccarci. Fai attenzione.,"市庁舎の外観を見たか?あれが我々に対する -奴等の所業を思い出させる。気をつけろ。",시청이 박살난 걸 보았지? 저건 오더의 심기를 무모하게 건드린 결과같은 거야. 그러니 조심해.,Weet je nog hoe het stadhuis eruit zag? Dat is een vriendelijke herinnering aan wat ze bereid zijn te doen om ons te pakken te krijgen. Wees voorzichtig.,Husker du hvordan rådhuset så ut? Det er en påminnelse om hva de er villige til å gjøre for å ta oss. Vær forsiktig.,"Pamiętasz jak ratusz wyglądał? To delikatne przypomnienie co chcą zrobić, aby nas dorwać. Uważaj na siebie.",Lembra como era a prefeitura? Aquilo é um simples lembrete do que eles estão dispostos a fazer para nos pegar. Tome cuidado.,,Mai ții minte cum arăta primăria? Asta e o reamintire ușoară de ceea ce sunt dispuși să facă pentru a ajunge la noi. Ai grijă.,"Видел, что стало с городской ратушей? Это мягкий намёк на то, что они сделают, если доберутся до нас. Будь осторожен.",,Belediye binasının neye benzediğini hatırlıyor musun? Bu bize ulaşmak için neler yapabileceklerini hatırlatıyor. Dikkatli olun. -Talk to Macil. He'll be able to help you.,TXT_DLG_SCRIPT03_D21224_TALKT,"MAP03: Upstairs, corridor.",,,Promluv si s Macilem. On ti pomůže.,Tal med Macil. Han vil kunne hjælpe dig.,Rede mit Macil. Er kann dir helfen.,,Parolu kun Macil. Li povos helpi vin.,Habla con Macil. Él te podrá ayudar.,Habla con Macil. Él te va a poder ayudar.,Puhu Macilille. Hän pystyy auttamaan sinua.,Parlez à Macil. Il pourra vous aider.,Beszélj Macil-lal. Ő tud segíteni neked.,Parla con Macil. Sarà in grado di aiutarti.,マシルと話すんだ。彼から援助が得られるはず。,도움이 필요한가? 그럼 마실 사령관님을 찾아.,Praat met Macil. Hij zal je kunnen helpen.,Snakk med Macil. Han kan hjelpe deg.,Porozmawiaj z Macilem. Pomoże ci.,Fale com Macil. Ele vai poder te ajudar.,,Discută cu Macil. Te va ajuta el.,Поговори с Мэйсилом. Он сможет тебе помочь.,,Macil ile konuş. Sana yardım edebilir. +奴等の所業を思い出させる。気をつけろ。",시청이 박살난 걸 보았지? 저건 오더의 심기를 무모하게 건드린 결과같은 거야. 그러니 조심해.,Weet je nog hoe het stadhuis eruit zag? Dat is een vriendelijke herinnering aan wat ze bereid zijn te doen om ons te pakken te krijgen. Wees voorzichtig.,Husker du hvordan rådhuset så ut? Det er en påminnelse om hva de er villige til å gjøre for å ta oss. Vær forsiktig.,"Pamiętasz jak ratusz wyglądał? To delikatne przypomnienie co chcą zrobić, aby nas dorwać. Uważaj na siebie.",Lembra como era a prefeitura? Aquilo é um simples lembrete do que eles estão dispostos a fazer para nos pegar. Tome cuidado.,,Mai ții minte cum arăta primăria? Asta e o reamintire ușoară de ceea ce sunt dispuși să facă pentru a ajunge la noi. Ai grijă.,"Видел, что стало с городской ратушей? Это мягкий намёк на то, что они сделают, если доберутся до нас. Будь осторожен.",,Minns du hur stadshuset såg ut? Det är en mild påminnelse om vad de är villiga att göra för att komma åt oss. Var försiktig.,Belediye binasının neye benzediğini hatırlıyor musun? Bu bize ulaşmak için neler yapabileceklerini hatırlatıyor. Dikkatli olun. +Talk to Macil. He'll be able to help you.,TXT_DLG_SCRIPT03_D21224_TALKT,"MAP03: Upstairs, corridor.",,,Promluv si s Macilem. On ti pomůže.,Tal med Macil. Han vil kunne hjælpe dig.,Rede mit Macil. Er kann dir helfen.,,Parolu kun Macil. Li povos helpi vin.,Habla con Macil. Él te podrá ayudar.,Habla con Macil. Él te va a poder ayudar.,Puhu Macilille. Hän pystyy auttamaan sinua.,Parlez à Macil. Il pourra vous aider.,Beszélj Macil-lal. Ő tud segíteni neked.,Parla con Macil. Sarà in grado di aiutarti.,マシルと話すんだ。彼から援助が得られるはず。,도움이 필요한가? 그럼 마실 사령관님을 찾아.,Praat met Macil. Hij zal je kunnen helpen.,Snakk med Macil. Han kan hjelpe deg.,Porozmawiaj z Macilem. Pomoże ci.,Fale com Macil. Ele vai poder te ajudar.,,Discută cu Macil. Te va ajuta el.,Поговори с Мэйсилом. Он сможет тебе помочь.,,Prata med Macil. Han kan hjälpa dig.,Macil ile konuş. Sana yardım edebilir. I've heard that Macil's got a plan to subvert the Order. It had better be good. One more failure and we're all just dead meat.,TXT_DLG_SCRIPT03_D22740_IVEHE,"MAP03: Barracks. (dead meat = corpse)",,,"Slyšel jsem, že Macil má plán, jak porazit Řád. Doufejme, že dobrý. Ještě jeden nezdar a všichni jsme mrtví.","Jeg har hørt, at Macil har en plan om at undergrave Ordenen. Den har bare at være god. En fiasko mere, og vi er alle bare dødt kød.","Ich habe gehört, Macil hätte einen Plan um den Orden zu unterwandern. Ich hoffe mal, er taugt was. Noch ein Fehlschlag und wir können uns gleich begraben lassen.",,"Mi aŭdis, ke Macil havas planon por malstabiligi La Ordonon. Pli bone, ke ĝi estas bona. Unu plua eraro kaj ni estos kadavroj.",He oído que Macil tiene un plan para desestabilizar a La Orden. Más vale que sea bueno. Un fallo más y somos fiambres.,Oí que Macil tiene un plan para desestabilizar a La Orden. Más vale que sea bueno. Un fallo más y somos fiambres.,"Kuulin, että Macililla on suunnitelma kukistaa Veljeskunta. Parasta ollakin hyvä. Vielä yksikin epäonnistuminen, ja olemme kaikki mennyttä.",J'ai entendu que Macil a un plan pour repousser l'Ordre. Il a intérêt à être bon. Une erreur de plus et nous sommes tous morts.,"Úgy tudom Macilnak van valami terve a Rend felforgatására. Remélem valami ütős terv. Még egy kudarc, és nekünk lőttek.",Ho sentito che Macil ha un piano per sovvertire l'Ordine. E spero proprio che sia un buon piano. Un altro fallimento e saremo tutti carne morta.,"私はマシルがオーダーを転覆させる計画を 持っていると聞いた。そうだと良かったが。 -我々は一度大敗し全滅しかけた。",오더를 괴멸할 방법을 마실 사령관님이 찾아냈대. 잘 먹혀야 하는데 말이야... 안 그럼 우리들이 잡아먹힐 거라고.,Ik heb gehoord dat Macil een plan heeft om de Orde te ondermijnen. Het kan maar beter goed zijn. Nog een mislukking en we zijn allemaal gewoon dood vlees.,"Jeg har hørt at Macil har en plan for å undergrave Ordenen. Den bør være god. Én fiasko til, og vi er ferdige.","Słyszałem, że Macil ma plan obalenia Zakonu. Oby był dobry. Jeszcze jedna porażka, a będziemy martwi.",Fiquei sabendo que Macil tem um plano para desestabilizar a Ordem. Espero que seja bom. Mais um fracasso e estaremos todos mortos.,,Am auzit că Macil are un plan pentru a submina Ordinul. Ar face bine să fie grozav. Încă un eșec și vom fi toți carne ambalată.,"Я слышал, что Мэйсил разработал план свержения Ордена. Лучше бы он сработал. Ещё одна ошибка, и мы все покойники.",,Macil'in Tarikat'ı yıkmak için bir planı olduğunu duydum. İyi olsa iyi olur. Bir başarısızlık daha olursa hepimiz ölürüz. +我々は一度大敗し全滅しかけた。",오더를 괴멸할 방법을 마실 사령관님이 찾아냈대. 잘 먹혀야 하는데 말이야... 안 그럼 우리들이 잡아먹힐 거라고.,Ik heb gehoord dat Macil een plan heeft om de Orde te ondermijnen. Het kan maar beter goed zijn. Nog een mislukking en we zijn allemaal gewoon dood vlees.,"Jeg har hørt at Macil har en plan for å undergrave Ordenen. Den bør være god. Én fiasko til, og vi er ferdige.","Słyszałem, że Macil ma plan obalenia Zakonu. Oby był dobry. Jeszcze jedna porażka, a będziemy martwi.",Fiquei sabendo que Macil tem um plano para desestabilizar a Ordem. Espero que seja bom. Mais um fracasso e estaremos todos mortos.,,Am auzit că Macil are un plan pentru a submina Ordinul. Ar face bine să fie grozav. Încă un eșec și vom fi toți carne ambalată.,"Я слышал, что Мэйсил разработал план свержения Ордена. Лучше бы он сработал. Ещё одна ошибка, и мы все покойники.",,Jag har hört att Macil har en plan för att omstörta Orden. Det är bäst att den är bra. Ett misslyckande till och vi är alla bara döda kött.,Macil'in Tarikat'ı yıkmak için bir planı olduğunu duydum. İyi olsa iyi olur. Bir başarısızlık daha olursa hepimiz ölürüz. A few of these barrels dumped into their water supply should even the odds a little.,TXT_DLG_SCRIPT03_D24256_AFEWO,〃,,,Pár těhle sudů v jejich zásobách vody by nám mělo alespoň trochu pomoct.,Et par af disse tønder dumpet i deres vandforsyning burde udligne oddsene lidt.,"Wenn wir ein paar von diesen Fässern in die Wasserversorgung kippen, sollte das unsere Chancen etwas verbessern.",,Ĵeti kelkajn el ĉi tiuj bareloj en ilian akvo-provizadon devus egaligi iomete la eblojn.,Tirar unos cuantos de estos barriles a su suministro de agua debería igualar un poco las probabilidades.,,Muutaman tällaisen tynnyrin kaataminen heidän vedenjakeluunsa varmaankin hieman tasoittaisi tilannetta.,Quelques uns de ces tonneaux vidés dans leur réserve d'eau devrait équilibrer le terrain de jeu.,Ezzel a pár víztározóba borított hordóval kiegyenlítjük az erőviszonyokat.,Un paio di questi barili rovesciati dentro la loro fornitura d'acqua dovrebbero bilanciare un pò le cose.,"ここの樽は捨てられていた物で -彼らの給水を補っている。",그들의 배수관에서 버려진 이 통들 일부는 분명히 약간의 승산이 있을거야.,"Een paar van deze vaten die in hun waterleiding gedumpt zijn, zullen de kans dat ze een beetje gelijk zijn.",Et par av disse tønnene dumpet i vannforsyningen deres burde jevne ut oddsen litt.,Parę tych beczek wrzuconcyh do ich zapasu wody powinno narobić wiele kłopotów.,"Se despejarmos alguns destes barris no estoque de água deles, vamos igualar as chances um pouco. ",,Câteva butoaie vărsate în rezerva lor de apă ar trebui să echilibreze balanța.,"Несколько таких бочек, сброшенных в их водоснабжение, немного уровняют шансы.",,Bu varillerden birkaçı su kaynaklarına atılırsa ihtimaller biraz olsun eşitlenir. +彼らの給水を補っている。",그들의 배수관에서 버려진 이 통들 일부는 분명히 약간의 승산이 있을거야.,"Een paar van deze vaten die in hun waterleiding gedumpt zijn, zullen de kans dat ze een beetje gelijk zijn.",Et par av disse tønnene dumpet i vannforsyningen deres burde jevne ut oddsen litt.,Parę tych beczek wrzuconcyh do ich zapasu wody powinno narobić wiele kłopotów.,"Se despejarmos alguns destes barris no estoque de água deles, vamos igualar as chances um pouco. ",,Câteva butoaie vărsate în rezerva lor de apă ar trebui să echilibreze balanța.,"Несколько таких бочек, сброшенных в их водоснабжение, немного уровняют шансы.",,Några av de här tunnorna dumpade i deras vattenförsörjning borde jämna ut oddsen lite.,Bu varillerden birkaçı su kaynaklarına atılırsa ihtimaller biraz olsun eşitlenir. "So you're the new operative? Thanks, without you, we'd all be dead right now.",TXT_DLG_SCRIPT03_D25772_SOYOU,〃,,,"Takže ty jsi ten nový agent? Díky, bez tebe bychom všichni byli mrtví.","Så du er den nye agent? Tak, uden dig ville vi alle være døde lige nu.","So, du bist der neue Agent? Danke, ohne dich wären wir schon alle tot.",,"Do ĉu vi estas la nova ano? Dankon. Sen vi, ni ĉiuj jam estus mortintaj.",¿O sea que tú eres el nuevo miembro? Gracias. Sin ti ya estaríamos todos muertos.,,Sinä siis olet se uusi agentti? Kiitos; ilman sinua olisimme nyt kaikki kuolleita.,"Vous êtes le nouvel agent? Merci, sans vous, nous serions tous morts.","Szóval te vagy az új kolléga? Köszi, nélküled már mind alulról szagolnánk az ibolyát.","Quindi sei tu il nuovo agente? Grazie, se non fosse per te, saremo tutti morti ora.","貴方が新しい工作員かい? それはありがたい、 -貴方がいなければ皆死んでいた所だ。","그래서, 네가 그 요원이지? 고맙다. 네가 없었으면 우리들은 이미 죽고 없었을걸.","Dus jij bent de nieuwe agent? Bedankt, zonder jou waren we nu allemaal dood geweest.","Så du er den nye agenten? Takk, uten deg ville vi alle vært døde nå.","Więc jesteś tu nowy? Dzięki, bez ciebie bylibyśmy już martwi.","Então você é o novo agente? Obrigado. Sem você, estaríamos todos mortos neste momento.",,"Deci tu ești noul operator? Merci, dacă nu erai tu, am fi fost cu toții morți deja.","Так это ты наш новый оперативник? Спасибо. Если бы не ты, мы бы все уже были мертвы.",,"Demek yeni ajan sensin? Teşekkürler, sen olmasaydın şu anda hepimiz ölmüş olurduk." +貴方がいなければ皆死んでいた所だ。","그래서, 네가 그 요원이지? 고맙다. 네가 없었으면 우리들은 이미 죽고 없었을걸.","Dus jij bent de nieuwe agent? Bedankt, zonder jou waren we nu allemaal dood geweest.","Så du er den nye agenten? Takk, uten deg ville vi alle vært døde nå.","Więc jesteś tu nowy? Dzięki, bez ciebie bylibyśmy już martwi.","Então você é o novo agente? Obrigado. Sem você, estaríamos todos mortos neste momento.",,"Deci tu ești noul operator? Merci, dacă nu erai tu, am fi fost cu toții morți deja.","Так это ты наш новый оперативник? Спасибо. Если бы не ты, мы бы все уже были мертвы.",,"Så du är den nya agenten? Tack, utan dig hade vi alla varit döda nu.","Demek yeni ajan sensin? Teşekkürler, sen olmasaydın şu anda hepimiz ölmüş olurduk." I'm working on something that will give us an edge. It will increase your stamina and completely jack you up. I've almost got all the bugs worked out. Can I do something for you?,TXT_DLG_SCRIPT03_D27288_IMWOR,MAP03: Gerald (no implant),,,"Pracuju na něčem, co by nám mělo pomoci. Přidá ti to výdrž a naprosto tě to nakopne. Už jsem skoro vychytal všechny mouchy. Co pro tebe mohu udělat?","Jeg arbejder på noget, der vil give os en fordel. Det vil øge din udholdenhed og gøre dig helt oppe at køre. Jeg har næsten fået styr på alle fejlene. Må jeg gøre noget for dig?","Ich arbeite an etwas, das uns einen Vorteil verschaffen kann. Es würde deine Ausdauer erhöhen und dir Superkräfte verleihen. Kann ich was für dich tun?",,"Mi laboras super io, kio donos avantaĝon al ni: ĝi pliigos vian energion kaj korpan forton. Mi jam korektis la plimulton de la difektoj. Ĉu mi povas fari ion por vi?",Estoy trabajando en algo que nos dará una ventaja: aumentará tu aguante y fuerza física. Ya casi tengo todos los fallos corregidos. ¿Puedo hacer algo por ti?,Estoy trabajando en algo que nos va a dar una ventaja: va a aumentar tu aguante y fuerza física. Ya casi tengo todos los fallos corregidos. ¿Puedo hacer algo por ti?,"Olen paraikaa työstämässä jotain, joka antaa meille etulyöntiaseman. Se kasvattaa kuntoasi ja täydellisesti virittää lihaksesi. Olen melkein saanut hiottua kaikki viat. Voinko olla jotenkin avuksi?",Je travaille sur quelque chose qui nous donnera un peu d'avance. Ca devrait augmenter votre endurance et vous donner un sacré coup de jus. Je crois que j'ai corrigé presque tous les bugs. Je peux vous aider?,"Dolgozok valamin, ami egy jelentősebb előnyhöz juttat minket. Megerősíti az állóképességedet és teljesen felpumpálja a tested. Már majdnem kiküszöböltem a hibákat. Amúgy tudok valamiben segíteni?",Sto lavorando a qualcosa che ci darà un notevole vantaggio. Aumenterà la tua resistenza e ti farà sentire molto più forte. Ho quasi risolto tutti gli effetti collaterali. Posso fare qualcosa per te?,"私は研究にも取り組んでいる。貴方のスタミナを 増強し完璧な体にすることも可能だ。 そのインプラントのバグも殆ど取り除かれている -ところで何か必要かい?","지금 우리들에게 승산이 갈 만한 연구를 하고 있습니다. 지구력 향상 이식 칩인데, 이 것만 있으면 당신의 체력과 힘을 더 불어넣어줄 겁니다. 오류를 거의 잡기도 했구요. 이제, 뭘 도와드릴까요?",Ik werk aan iets dat ons een voorsprong geeft. Het zal je uithoudingsvermogen verhogen en je volledig opkrikken. Ik heb bijna alle bugs uitgewerkt. Kan ik iets voor je doen?,Jeg jobber med noe som vil gi oss en fordel. Det vil øke utholdenheten din og løfte deg helt opp. Jeg har nesten funnet ut av alle problemene. Kan jeg gjøre noe for deg?,"Pracuję nad czymś dla ciebie co da nam przewagę. Zwiększy ci to wytrzymałość i sprawi, że poczujesz się lepiej. Już prawie naprawiłem wszystkie błędy. Mogę coś dla ciebie zrobić?",Estou trabalhando em algo que vai nos dar um impulso. É algo que vai aumentar sua resistência e te deixar bem mais forte. Estou com quase todos os bugs resolvidos. Posso te ajudar com algo?,,Lucrez la ceva care ne va oferi un avantaj. Îți va mării rezistența fizică și întări. Aproape am rezolvat toate problemele. Pot face ceva pentru tine?,"Я работаю кое над чем, что может нам пригодиться. Оно увеличит твою выносливость и улучшит самочувствие. Я уже исправил почти все дефекты. Что тебе нужно?",,Bize avantaj sağlayacak bir şey üzerinde çalışıyorum. Dayanıklılığını arttıracak ve seni tamamen uçuracak. Neredeyse tüm hataları çözdüm. Senin için bir şey yapabilir miyim? -Patch me up.,TXT_RPLY0_SCRIPT03_D27288_PATCH,〃 (〃),,,Dej mě dohromady.,Giv mig et plaster på såret.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Hoida minut kuntoon.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lappe meg sammen.,Opatrz mnie.,Trate meus ferimentos.,,Bandajează-mă.,Подлатай меня.,,Beni yamala. +ところで何か必要かい?","지금 우리들에게 승산이 갈 만한 연구를 하고 있습니다. 지구력 향상 이식 칩인데, 이 것만 있으면 당신의 체력과 힘을 더 불어넣어줄 겁니다. 오류를 거의 잡기도 했구요. 이제, 뭘 도와드릴까요?",Ik werk aan iets dat ons een voorsprong geeft. Het zal je uithoudingsvermogen verhogen en je volledig opkrikken. Ik heb bijna alle bugs uitgewerkt. Kan ik iets voor je doen?,Jeg jobber med noe som vil gi oss en fordel. Det vil øke utholdenheten din og løfte deg helt opp. Jeg har nesten funnet ut av alle problemene. Kan jeg gjøre noe for deg?,"Pracuję nad czymś dla ciebie co da nam przewagę. Zwiększy ci to wytrzymałość i sprawi, że poczujesz się lepiej. Już prawie naprawiłem wszystkie błędy. Mogę coś dla ciebie zrobić?",Estou trabalhando em algo que vai nos dar um impulso. É algo que vai aumentar sua resistência e te deixar bem mais forte. Estou com quase todos os bugs resolvidos. Posso te ajudar com algo?,,Lucrez la ceva care ne va oferi un avantaj. Îți va mării rezistența fizică și întări. Aproape am rezolvat toate problemele. Pot face ceva pentru tine?,"Я работаю кое над чем, что может нам пригодиться. Оно увеличит твою выносливость и улучшит самочувствие. Я уже исправил почти все дефекты. Что тебе нужно?",,Jag jobbar på något som kommer att ge oss en fördel. Det kommer att öka din uthållighet och göra dig helt upprymd. Jag har nästan löst alla buggar. Kan jag göra något för dig?,Bize avantaj sağlayacak bir şey üzerinde çalışıyorum. Dayanıklılığını arttıracak ve seni tamamen uçuracak. Neredeyse tüm hataları çözdüm. Senin için bir şey yapabilir miyim? +Patch me up.,TXT_RPLY0_SCRIPT03_D27288_PATCH,〃 (〃),,,Dej mě dohromady.,Giv mig et plaster på såret.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Hoida minut kuntoon.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lappe meg sammen.,Opatrz mnie.,Trate meus ferimentos.,,Bandajează-mă.,Подлатай меня.,,Laga mig.,Beni yamala. "Boy, you're a real mess. I'll see what I can do.",TXT_RYES0_SCRIPT03_D27288_BOYYO,〃 (〃),,,"Tebe teda zřídili, kluku. Uvidím, co s tebou.","Du er et rigtigt rod. Jeg skal se, hvad jeg kan gøre.","Mann, du siehst aber gar nicht gut aus. Mal sehen, was ich machen kann.",,"Ulo, vi estas iomege en malordo. Mi vidos tion, kion mi faru.","Tío, estás hecho un desastre. A ver qué puedo hacer.","Chico, estás hecho un desastre. -A ver qué puedo hacer.","Voi pojat, oletpa hajalla. Katsotaan, mihin pystyn.","Mon petit, vous êtes dans un sale état. Je vais voir ce que je peux faire.","Öregem, elég rossz passzban vagy. Megnézem mit tudok tenni.","Ragazzo, sei messo proprio male. Vediamo cosa posso fare.",君、滅茶苦茶だな。なんとかしよう。,"당신, 정말 엉망이네요... 어떻게든 치료해줄게요.","Jongen, je bent een echte puinhoop. Ik zal zien wat ik kan doen.","Jøss, du ser forferdelig ut. Jeg skal se hva jeg kan gjøre.","Chłopie, ależ ty jesteś poszarpany. Zobaczę co da się zrobić.","Rapaz, você está arrebentado. Vou ver o que posso fazer.",,"Măi să fie, ești un dezastru. O să văd ce pot face.","Парень, да на тебя смотреть страшно. Приступим...",,"Evlat, gerçekten berbat durumdasın. Ne yapabileceğime bir bakayım." -Stamina implant?,TXT_RPLY1_SCRIPT03_D27288_STAMI,〃 (〃),,,Implantát pro výdrž?,Udholdenhedsimplantat?,Ausdauerimplantat?,,Ĉu energidona enplantaĵo?,¿Implante de aguante?,,Kuntoistute?,Implant d'endurance?,Állóképesség implantátum?,Impianto stamina?,スタミナインプラント?,지구력 향상 이식?,Stamina implantaat?,Utholdenhetsimplantat?,Implant zwiększający wytrzymałość?,Implante de resistência?,,Implant pentru rezistență?,Выносливостный имплант?,,Dayanıklılık implantı mı? +A ver qué puedo hacer.","Voi pojat, oletpa hajalla. Katsotaan, mihin pystyn.","Mon petit, vous êtes dans un sale état. Je vais voir ce que je peux faire.","Öregem, elég rossz passzban vagy. Megnézem mit tudok tenni.","Ragazzo, sei messo proprio male. Vediamo cosa posso fare.",君、滅茶苦茶だな。なんとかしよう。,"당신, 정말 엉망이네요... 어떻게든 치료해줄게요.","Jongen, je bent een echte puinhoop. Ik zal zien wat ik kan doen.","Jøss, du ser forferdelig ut. Jeg skal se hva jeg kan gjøre.","Chłopie, ależ ty jesteś poszarpany. Zobaczę co da się zrobić.","Rapaz, você está arrebentado. Vou ver o que posso fazer.",,"Măi să fie, ești un dezastru. O să văd ce pot face.","Парень, да на тебя смотреть страшно. Приступим...",,Du är en riktig röra. Jag ska se vad jag kan göra.,"Evlat, gerçekten berbat durumdasın. Ne yapabileceğime bir bakayım." +Stamina implant?,TXT_RPLY1_SCRIPT03_D27288_STAMI,〃 (〃),,,Implantát pro výdrž?,Udholdenhedsimplantat?,Ausdauerimplantat?,,Ĉu energidona enplantaĵo?,¿Implante de aguante?,,Kuntoistute?,Implant d'endurance?,Állóképesség implantátum?,Impianto stamina?,スタミナインプラント?,지구력 향상 이식?,Stamina implantaat?,Utholdenhetsimplantat?,Implant zwiększający wytrzymałość?,Implante de resistência?,,Implant pentru rezistență?,Выносливостный имплант?,,Ett uthållighetsimplantat?,Dayanıklılık implantı mı? "All right, this won't take but a moment.",TXT_RYES1_SCRIPT03_D27288_ALLRI,〃 (〃),,,"Dobře, tohle potrvá jen chvilku.","Okay, det tager kun et øjeblik.","Alles klar, das haben wir sofort.",,"Bonege, ĉi tio estos rapidega.","Muy bien, solo tomará un momento.","Muy bien, solo va a -tomar un momento.","Hyvä on, tähän ei mene hetkeä pidempään.","Pas de problème, ça ne prendra qu'un moment.","Rendben, egy pillanat és kész.","Va bene, ci vorrà solo un momento.",いいでしょう、これは時間を取りません。,좋습니다. 시간이 오래 걸리진 않을 거예요.,"Oké, dit duurt maar een momentje.",Dette tar bare et øyeblikk.,"Dobra, to zajmie tylko chwilę.","Ok, só um momento.",,"În regulă, va dura doar un moment.","Отлично, это займёт всего пару секунд.",,"Pekala, bu bir dakikadan fazla sürmez." +tomar un momento.","Hyvä on, tähän ei mene hetkeä pidempään.","Pas de problème, ça ne prendra qu'un moment.","Rendben, egy pillanat és kész.","Va bene, ci vorrà solo un momento.",いいでしょう、これは時間を取りません。,좋습니다. 시간이 오래 걸리진 않을 거예요.,"Oké, dit duurt maar een momentje.",Dette tar bare et øyeblikk.,"Dobra, to zajmie tylko chwilę.","Ok, só um momento.",,"În regulă, va dura doar un moment.","Отлично, это займёт всего пару секунд.",,"Okej, det här tar bara ett ögonblick.","Pekala, bu bir dakikadan fazla sürmez." It's not done yet.,TXT_RNO1_SCRIPT03_D27288_ITSNO,〃 (〃),,,Ještě není hotový.,Det er ikke færdigt endnu.,Es ist noch nicht soweit.,,"Mi ankoraŭ -prilaboras ĝin.",Aún no está listo.,,Se ei ole valmis vielä.,Ce n'est pas encore terminé.,Még nincs kész.,Non è ancora pronto.,まだ完成していません。,아직 완료되지는 않았어요.,Het is nog niet klaar.,Det er ikke ferdig ennå.,Jeszcze nie jest gotowy.,Ainda não terminei.,,Încă nu e gata.,Он ещё не готов.,,Henüz bitmedi. +prilaboras ĝin.",Aún no está listo.,,Se ei ole valmis vielä.,Ce n'est pas encore terminé.,Még nincs kész.,Non è ancora pronto.,まだ完成していません。,아직 완료되지는 않았어요.,Het is nog niet klaar.,Det er ikke ferdig ennå.,Jeszcze nie jest gotowy.,Ainda não terminei.,,Încă nu e gata.,Он ещё не готов.,,Det är inte klart än.,Henüz bitmedi. "Hey, I'm working on an updated version of your implant. Is there anything else I can do?",TXT_DLG_SCRIPT03_D28804_HEYIM,〃 (one upgrade),,,"Hej, pracuju na vylepšené verzi tvého implantátu. Můžu pro tebe udělat něco jiného?","Jeg arbejder på en opdateret version af dit implantat. Er der andet, jeg kan gøre?","He, ich arbeite an einer verbesserten Version deines Implantats. Gibt es sonst etwas, das ich für dich tun kann?",,"Mi laboras super plibonigita versio de via enplantaĵo. Ĉu estas io alia, kion mi povas fari por vi?",Estoy trabajando en una versión mejorada de tu implante. ¿Hay algo más que pueda hacer?,,"Hei, olen työstämässä päivitettyä versiota istutteestasi. Voinko olla muuten avuksi?","Hé, je travaille sur une version améliorée de l'implant. Qu'est-ce que je peux faire pour vous?",Az implantátum újabb verzióján dolgozok. Tudok még valamiben segíteni?,"Ehi, sto lavorando ad un aggiornamento per l'impianto stamina. Posso fare qualcos'altro per te?","どうも、私は今最新版のインプラントに -取り組んでいる。何か用かな?","당신의 이식 칩을 위한 향상 개조가 준비되었습니다. 그런 이유로 온게 아니면, 무엇을 도와드릴까요?","Hé, ik ben bezig met een bijgewerkte versie van je implantaat. Is er nog iets anders dat ik kan doen?",Jeg jobber med en oppdatert versjon av implantatet ditt. Er det noe annet jeg kan gjøre?,"Hej, pracuję nad ulepszoną wersją twojego implantu. Mogę coś jeszcze dla ciebie zrobić?",E aí. Estou trabalhando numa versão aprimorada do seu implante. Posso te ajudar com algo?,,"Hei, lucrez la o variantă îmbunătățită a implantului tău. Mai pot să te ajut cu ceva?","Я работаю над улучшенной версией твоего импланта. А пока, что-нибудь ещё?",,"Hey, implantının güncellenmiş bir versiyonu üzerinde çalışıyorum. Yapabileceğim başka bir şey var mı?" -Patch me up.,TXT_RPLY0_SCRIPT03_D28804_PATCH,〃 (〃),,,Dej mě dohromady.,Gør mig klar.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Pistä minut kuntoon.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lappe meg sammen.,Opatrz mnie.,Trate meus ferimentos.,,Bandajează-mă.,Подлатай меня.,,Yama yap. +取り組んでいる。何か用かな?","당신의 이식 칩을 위한 향상 개조가 준비되었습니다. 그런 이유로 온게 아니면, 무엇을 도와드릴까요?","Hé, ik ben bezig met een bijgewerkte versie van je implantaat. Is er nog iets anders dat ik kan doen?",Jeg jobber med en oppdatert versjon av implantatet ditt. Er det noe annet jeg kan gjøre?,"Hej, pracuję nad ulepszoną wersją twojego implantu. Mogę coś jeszcze dla ciebie zrobić?",E aí. Estou trabalhando numa versão aprimorada do seu implante. Posso te ajudar com algo?,,"Hei, lucrez la o variantă îmbunătățită a implantului tău. Mai pot să te ajut cu ceva?","Я работаю над улучшенной версией твоего импланта. А пока, что-нибудь ещё?",,Jag jobbar på en uppdaterad version av ditt implantat. Finns det något annat jag kan göra?,"Hey, implantının güncellenmiş bir versiyonu üzerinde çalışıyorum. Yapabileceğim başka bir şey var mı?" +Patch me up.,TXT_RPLY0_SCRIPT03_D28804_PATCH,〃 (〃),,,Dej mě dohromady.,Gør mig klar.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Pistä minut kuntoon.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lappe meg sammen.,Opatrz mnie.,Trate meus ferimentos.,,Bandajează-mă.,Подлатай меня.,,Laga mig.,Yama yap. Well at least your seeing action.,TXT_RYES0_SCRIPT03_D28804_WELLA,〃 (〃),,,"No, alespoň se nenudíš.",I det mindste kan du se noget.,"Mann, du siehst aber gar nicht gut aus. Mal sehen, was ich machen kann.",,"Nu, almenaŭ vi ne havas enuigajn misiojn.","Bueno, al menos estás -teniendo algo de acción.",,"No, ainakin näet toimintaa.","Eh bien, au moins vous en voyez, de l'action.",Legalább neked jut valami akció.,"Beh, almeno ti stai dando da fare.",貴方の働きは聞き届いてるよ。,이제 전장에 힘을 발휘해보세요!,"Nou ja, in ieder geval uw zien actie.",Du ser i det minste noe.,Przynajmniej będziesz mógł wrócić do akcji.,"Bem, pelo menos tá tendo um pouco de ação.",,"Eh, măcar tu ai parte de acțiune.","Что ж, зато ты участвуешь в операциях.",,En azından hareket görüyorsun. -Implant upgrade?,TXT_RPLY1_SCRIPT03_D28804_IMPLA,〃 (〃),,,Vylepšený implantát?,Opgradering af implantater?,Implantatsupgrade?,,Ĉu plibonigo de enplantaĵo?,¿Mejora de implante?,,Istutteen päivitys?,Mise à jour de l'implant?,Implantátum fejlesztés?,Aggiornamento dell'impianto?,インプラント アップグレード?,지구력 업그레이드?,Implantaat upgrade?,Implantatoppgradering?,Ulepszenie implantu?,Versão aprimorada do implante?,,Upgrade pentru implant?,Улучшение импланта?,,İmplant güncellemesi mi? +teniendo algo de acción.",,"No, ainakin näet toimintaa.","Eh bien, au moins vous en voyez, de l'action.",Legalább neked jut valami akció.,"Beh, almeno ti stai dando da fare.",貴方の働きは聞き届いてるよ。,이제 전장에 힘을 발휘해보세요!,"Nou ja, in ieder geval uw zien actie.",Du ser i det minste noe.,Przynajmniej będziesz mógł wrócić do akcji.,"Bem, pelo menos tá tendo um pouco de ação.",,"Eh, măcar tu ai parte de acțiune.","Что ж, зато ты участвуешь в операциях.",,Du får åtminstone se handling.,En azından hareket görüyorsun. +Implant upgrade?,TXT_RPLY1_SCRIPT03_D28804_IMPLA,〃 (〃),,,Vylepšený implantát?,Opgradering af implantater?,Implantatsupgrade?,,Ĉu plibonigo de enplantaĵo?,¿Mejora de implante?,,Istutteen päivitys?,Mise à jour de l'implant?,Implantátum fejlesztés?,Aggiornamento dell'impianto?,インプラント アップグレード?,지구력 업그레이드?,Implantaat upgrade?,Implantatoppgradering?,Ulepszenie implantu?,Versão aprimorada do implante?,,Upgrade pentru implant?,Улучшение импланта?,,Implantatuppgradering?,İmplant güncellemesi mi? "Good thing, never can be too safe.",TXT_RYES1_SCRIPT03_D28804_GOODT,〃 (〃),,,"Dobrá věcička, nikdy si nemůžeš být moc jistý.","Godt nok, man kan aldrig være for sikker.","Alles klar, das haben wir sofort.",,"Bone. Neniam estas sufiĉe da sekureco.","Bien. Nunca se puede -estar del todo seguro.",,"Hyvä, koskaan ei voi olla liian turvallista.",Bonne idée. On ne peut jamais être trop sûr.,"Helyes, sosem lehetünk elég elővigyázatosak.","Ottimo, non si può mai essere troppo al sicuro.",良いことだ、安全すぎることはない。,좋은 선택입니다. 이거 없이는 안전할 수가 없죠.,"Goede zaak, kan nooit te veilig zijn.","Bra, man kan aldri være for sikker.","Dobra rzecz, nigdy za mało bezpieczeństwa.",Boa idéia. Segurança nunca é demais.,,"Recomand cu mare drag, nu poți fi niciodată prea sigur.","Очень советую, ни в чём нельзя быть уверенным до конца.",,"İyi bir şey, asla çok güvenli olamaz." +estar del todo seguro.",,"Hyvä, koskaan ei voi olla liian turvallista.",Bonne idée. On ne peut jamais être trop sûr.,"Helyes, sosem lehetünk elég elővigyázatosak.","Ottimo, non si può mai essere troppo al sicuro.",良いことだ、安全すぎることはない。,좋은 선택입니다. 이거 없이는 안전할 수가 없죠.,"Goede zaak, kan nooit te veilig zijn.","Bra, man kan aldri være for sikker.","Dobra rzecz, nigdy za mało bezpieczeństwa.",Boa idéia. Segurança nunca é demais.,,"Recomand cu mare drag, nu poți fi niciodată prea sigur.","Очень советую, ни в чём нельзя быть уверенным до конца.",,"Bra, man kan aldrig vara för säker.","İyi bir şey, asla çok güvenli olamaz." "I'm almost finished, but not quite.",TXT_RNO1_SCRIPT03_D28804_IMALM,〃 (〃),,,"Už je skoro hotový, ale ne úplně.","Jeg er næsten færdig, men ikke helt.",Es ist noch nicht soweit.,,"Mi preskaŭ finis, sed ne tute.","Casi he terminado, -pero no del todo.",,"Olen melkein valmis, mutten ihan vielä.","Presque fini, mais pas encore.","Már majdnem végeztem, még egy kicsi híja van.","Ho quasi finito, ma non ancora.",もうすぐ出来上がる、それほど掛からない。,"거의 다 돼가지만, 아직 완성된 게 아니에요.","Ik ben bijna klaar, maar niet helemaal.","Jeg er nesten ferdig, men ikke helt.","Prawie skończyłem, ale nie do końca.",Estou quase terminando. Só mais um pouco.,,"Sunt aproape gata, dar nu tocmai.",Я почти закончил. Ещё немного.,,Neredeyse bitirdim ama tam olarak değil. +pero no del todo.",,"Olen melkein valmis, mutten ihan vielä.","Presque fini, mais pas encore.","Már majdnem végeztem, még egy kicsi híja van.","Ho quasi finito, ma non ancora.",もうすぐ出来上がる、それほど掛からない。,"거의 다 돼가지만, 아직 완성된 게 아니에요.","Ik ben bijna klaar, maar niet helemaal.","Jeg er nesten ferdig, men ikke helt.","Prawie skończyłem, ale nie do końca.",Estou quase terminando. Só mais um pouco.,,"Sunt aproape gata, dar nu tocmai.",Я почти закончил. Ещё немного.,,"Jag är nästan klar, men inte riktigt.",Neredeyse bitirdim ama tam olarak değil. "All right, I've almost got everything working perfectly. There were a few problems left to get rid of. Do you need anything else? ",TXT_DLG_SCRIPT03_D30320_ALLRI,〃 (two upgrades),,,"Tak dobře, už mi skoro všechno perfektně funguje. Ještě tam bylo pár problémů. Potřebuješ ještě něco?","Okay, jeg har næsten fået det hele til at fungere perfekt. Der var et par problemer tilbage at slippe af med. Har du brug for noget andet?","He, ich arbeite an einer verbesserten Version deines Implantats. Gibt es sonst etwas, das ich für dich tun kann?",,"Bone, preskaŭ ĉio funkcias perfekte. Restis nur kelkaj korektindaj problemoj. Ĉu vi bezonas ion alian?","Muy bien, tengo casi todo funcionando a la perfección. Solo quedaban algunos problemas que corregir. ¿Necesitas algo más?",,"No niin, olen melkein saanut kaiken toimimaan täydellisesti. Vain muutamia vikoja oli enää jäljellä. Tarvitsetko mitään muuta?","Très bien, je crois que j'ai réussi à tout faire marcher parfaitement. Il y avait quelques problèmes dont je devais me débarrasser. Vous voulez quelque chose?","Nos, már majdnem minden tökéletesen működik. Volt néhány kijavítandó hiba. Tudok még valamiben segíteni?","Allora, sono riuscito a far funzionare quasi tutto benissimo. C'erano giusto un paio di problemi rimasti da risolvere. Ti serve qualcos'altro?","大丈夫、全て順調だ。残っていた問題も -全て取り除かれた。他に何が必要かな?",연구가 거의 다 끝나갑니다. 연구 도중에 오류를 좀 잡았어요. 기다리는 동안 뭐 필요한 게 있나요?,"Oke, ik heb bijna alles wat perfect werkt. Er waren nog een paar problemen over om van af te komen. Heeft u nog iets anders nodig?",Jeg har nesten fått alt til å fungere perfekt. Det var et par problemer igjen å bli kvitt. Trenger du noe mer?,"Dobra, prawie wszystko działa dobrze. Zostało jeszcze parę rzeczy do zrobienia. Czy coś jeszcze potrzebujesz?","Ok, tenho quase tudo funcionando perfeitamente. Ainda faltam alguns probleminhas para tirar de você. Precisa de mais alguma coisa?",,"În regulă, totul funcționează aproape perfect. Au mai fost niște probleme care trebuiau rezolvate. Mai ai nevoie de altceva?","Итак, тут оставалась пара проблем, но теперь всё работает почти идеально. Что-нибудь ещё?",,"Pekala, neredeyse her şey mükemmel çalışıyor. Kurtulmam gereken birkaç sorun kaldı. Başka bir şeye ihtiyacın var mı?" -Patch me up.,TXT_RPLY0_SCRIPT03_D30320_PATCH,〃 (〃),,,Dej mě dohromady.,Lav mig om.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Paikkaa minut.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lapp meg sammen.,Opatrz mnie.,Trate meus ferimentos.,,Tratează-mă.,Подлатай меня.,,Beni yamala. +全て取り除かれた。他に何が必要かな?",연구가 거의 다 끝나갑니다. 연구 도중에 오류를 좀 잡았어요. 기다리는 동안 뭐 필요한 게 있나요?,"Oke, ik heb bijna alles wat perfect werkt. Er waren nog een paar problemen over om van af te komen. Heeft u nog iets anders nodig?",Jeg har nesten fått alt til å fungere perfekt. Det var et par problemer igjen å bli kvitt. Trenger du noe mer?,"Dobra, prawie wszystko działa dobrze. Zostało jeszcze parę rzeczy do zrobienia. Czy coś jeszcze potrzebujesz?","Ok, tenho quase tudo funcionando perfeitamente. Ainda faltam alguns probleminhas para tirar de você. Precisa de mais alguma coisa?",,"În regulă, totul funcționează aproape perfect. Au mai fost niște probleme care trebuiau rezolvate. Mai ai nevoie de altceva?","Итак, тут оставалась пара проблем, но теперь всё работает почти идеально. Что-нибудь ещё?",,"Okej, jag har nästan fått allt att fungera perfekt. Det fanns några problem kvar att bli av med. Behöver du något annat?","Pekala, neredeyse her şey mükemmel çalışıyor. Kurtulmam gereken birkaç sorun kaldı. Başka bir şeye ihtiyacın var mı?" +Patch me up.,TXT_RPLY0_SCRIPT03_D30320_PATCH,〃 (〃),,,Dej mě dohromady.,Lav mig om.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Paikkaa minut.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lapp meg sammen.,Opatrz mnie.,Trate meus ferimentos.,,Tratează-mă.,Подлатай меня.,,Laga mig.,Beni yamala. What have you been trying to do? Go head to head with a Crusader?,TXT_RYES0_SCRIPT03_D30320_WHATH,〃 (〃),,,Co jsi dělal? Šel zmlátit Křižáka?,Hvad har du forsøgt at gøre? At gå i kamp mod en korsfarer?,"Mann, du siehst aber gar nicht gut aus. Mal sehen, was ich machen kann.",,"Kion vi intencis fari? Ĉu piki Kruciston?","¿Qué has intentado hacer? ¿Ir cara a cara con un Cruzado?","¿Qué anduviste haciendo? ¿Ir cara a cara con un Cruzado?",Mitä olet oikein yrittänyt tehdä? Mennä nokittain ristiretkeläisen kanssa?,Qu'est-ce que vous avez fait? Vous avez essayé de faire ami avec un Croisé?,Mi a francot képzeltél? Egymagad nekimész egy keresztesnek?,Ma cosa hai cercato di fare? Lottare da solo contro un Crociato?,"今度は何を始めるんだ? -クルセイダーと向かい合うのか?",뭘 하다 왔나요? 크루세이더랑 한판 뜨기라도 했나요?,Wat heb je geprobeerd te doen? Hoofd aan hoofd gaan met een kruisvaarder?,Hva har du prøvd å gjøre? Kjempe mot en korsfarer?,Co ty próbowałeś zrobić? Walczyć oko w oko z Krzyżowcem?,O que você andou tentando fazer? Partiu pro soco contra um Cruzado?,,Ce ai încercat să faci? Să dai cap în cap cu un Cruciat?,Что было у тебя на уме? Биться один на один с крестоносцем?,,Ne yapmaya çalışıyordun? Bir Crusader ile kafa kafaya mı? -Implant upgrade?.,TXT_RPLY1_SCRIPT03_D30320_IMPLA,〃 (〃),,,Vylepšený implantát?,Implantat opgradering?,Implantatsupgrade?,,Ĉu plibonigo de enplantaĵo?,¿Mejora de implante?,,Istutteen päivitys?,Mise à jour de l'implant?,Implantátum fejlesztés?,Aggiornamento dell'impianto?,インプラント アップグレード?,지구력 업그레이드?,Implantaat upgrade?,Implantatoppgradering?,Ulepszenie implantu?,Melhoria de implante?,,Upgrade pentru implant?,Улучшение импланта?,,İmplant yükseltmesi mi? -That should do it for you.,TXT_RYES1_SCRIPT03_D30320_THATS,〃 (〃),,,Tohle by mělo fungovat.,Det burde gøre det for dig.,"Alles klar, das haben wir sofort.",,Ĉi tio devus esti sufiĉa.,Con esto debería estar.,,Eiköhän tällä ala tepsiä.,Ca devrait faire l'affaire.,Ez már így jó lesz.,Questo dovrebbe andare.,今取り掛かっている。,이것만 있음 될 겁니다.,Dat zou het voor u moeten doen.,Det burde gjøre det for deg.,To powinno ci wystarczyć.,Isso deve funcionar.,,Ar trebui să fie bine acum.,Вот оно.,,Bu senin işini görür. +クルセイダーと向かい合うのか?",뭘 하다 왔나요? 크루세이더랑 한판 뜨기라도 했나요?,Wat heb je geprobeerd te doen? Hoofd aan hoofd gaan met een kruisvaarder?,Hva har du prøvd å gjøre? Kjempe mot en korsfarer?,Co ty próbowałeś zrobić? Walczyć oko w oko z Krzyżowcem?,O que você andou tentando fazer? Partiu pro soco contra um Cruzado?,,Ce ai încercat să faci? Să dai cap în cap cu un Cruciat?,Что было у тебя на уме? Биться один на один с крестоносцем?,,Vad har du försökt göra? Gå mot en korsriddare?,Ne yapmaya çalışıyordun? Bir Haçlı ile kafa kafaya mı? +Implant upgrade?.,TXT_RPLY1_SCRIPT03_D30320_IMPLA,〃 (〃),,,Vylepšený implantát?,Implantat opgradering?,Implantatsupgrade?,,Ĉu plibonigo de enplantaĵo?,¿Mejora de implante?,,Istutteen päivitys?,Mise à jour de l'implant?,Implantátum fejlesztés?,Aggiornamento dell'impianto?,インプラント アップグレード?,지구력 업그레이드?,Implantaat upgrade?,Implantatoppgradering?,Ulepszenie implantu?,Melhoria de implante?,,Upgrade pentru implant?,Улучшение импланта?,,Implantatuppgradering?,İmplant yükseltmesi mi? +That should do it for you.,TXT_RYES1_SCRIPT03_D30320_THATS,〃 (〃),,,Tohle by mělo fungovat.,Det burde gøre det for dig.,"Alles klar, das haben wir sofort.",,Ĉi tio devus esti sufiĉa.,Con esto debería estar.,,Eiköhän tällä ala tepsiä.,Ca devrait faire l'affaire.,Ez már így jó lesz.,Questo dovrebbe andare.,今取り掛かっている。,이것만 있음 될 겁니다.,Dat zou het voor u moeten doen.,Det burde gjøre det for deg.,To powinno ci wystarczyć.,Isso deve funcionar.,,Ar trebui să fie bine acum.,Вот оно.,,Det borde göra det för dig.,Bu senin işini görür. Let me run some more tests first.,TXT_RNO1_SCRIPT03_D30320_LETME,〃 (〃),,,Ještě ho musím dál otestovat.,Lad mig køre nogle flere tests først.,Es ist noch nicht soweit.,,"Unue mi faru kelkajn provojn.","Déjame hacer algunas -pruebas primero.",,Anna minun ajaa muutamia kokeita ensin.,Laissez moi faire quelques tests d'abord.,Hadd futtassak pár tesztet előtte.,Devo fare ancora qualche test.,もう少しテストしてからにしよう。,"우선, 시험을 좀 거쳐야 해요.",Laat me eerst nog wat testen doen.,La meg kjøre noen flere tester først.,Pozwól mi zrobić jeszcze parę testów.,Deixe eu fazer alguns testes primeiro.,,Lasă-mă să mai fac niște teste mai întâi.,Дай мне ещё времени на тесты.,,Önce birkaç test daha yapayım. +pruebas primero.",,Anna minun ajaa muutamia kokeita ensin.,Laissez moi faire quelques tests d'abord.,Hadd futtassak pár tesztet előtte.,Devo fare ancora qualche test.,もう少しテストしてからにしよう。,"우선, 시험을 좀 거쳐야 해요.",Laat me eerst nog wat testen doen.,La meg kjøre noen flere tester først.,Pozwól mi zrobić jeszcze parę testów.,Deixe eu fazer alguns testes primeiro.,,Lasă-mă să mai fac niște teste mai întâi.,Дай мне ещё времени на тесты.,,Låt mig köra några fler tester först.,Önce birkaç test daha yapayım. That's all I can do on the implant right now. Maybe some healing?,TXT_DLG_SCRIPT03_D31836_THATS,〃 (?),,,"Tak, to je všechno co teď můžu s tím implantátem udělat. Potřebuješ léčení?","Det er alt, hvad jeg kan gøre på implantatet lige nu. Måske noget healing?","Das ist alles, was ich im Moment mit dem Implantat machen kann. Vielleicht etwas medizinische Versorgung?",,"Tio estas ĉio, kion mi momente povas fari super la enplantaĵo. Ĉu vi bezonas kuracon?",Eso es todo lo que puedo hacer con el implante por ahora. ¿Necesitas curarte?,,Tätä enempää en voi istutteelle enää juuri nyt tehdä. Mutta oletko hoidon tarpeessa?,C'est tout ce que je peux faire pour l'implant. Vous voulez que je vous soigne?,Csak ennyit tudok most kezdeni az implantátummal. Talán egy kis gyógyítás?,È tutto per quanto riguarda l'impianto. Però posso sempre curarti.,"インプラントはこれ以上ない程完成した。 -それとも治療か?",지구력 향상 관련은 이게 다입니다. 이제 치료가 좀 필요하신가요?,Dat is alles wat ik nu kan doen op het implantaat. Misschien wat genezing?,Det er alt jeg kan gjøre med implantatet akkurat nå. Kanskje litt helbredelse?,To wszystko co mogę zrobić w sprawie implantu. Może chcesz się podleczyć?,Isso é tudo que posso fazer com o implante no momento. Não quer um tratamento nesses ferimentos?,,Asta e tot ce îi pot face implantului pentru moment. Poate niște tratament?,Пока что я больше ничего не могу сделать с имплантом. Как насчёт лечения?,,Şu anda implant üzerinde yapabileceğim tek şey bu. Belki biraz iyileşme? -Yeah.,TXT_RPLY0_SCRIPT03_D31836_YEAH,〃 (〃),,,Jo.,Ja.,Ja.,,Jes.,Sí.,,Kyllä.,Ouais.,Igen.,Sì.,ああ。,네.,Ja.,Ja.,Pewnie.,Pode ser.,,Da.,Давай.,,"Evet, belki." +それとも治療か?",지구력 향상 관련은 이게 다입니다. 이제 치료가 좀 필요하신가요?,Dat is alles wat ik nu kan doen op het implantaat. Misschien wat genezing?,Det er alt jeg kan gjøre med implantatet akkurat nå. Kanskje litt helbredelse?,To wszystko co mogę zrobić w sprawie implantu. Może chcesz się podleczyć?,Isso é tudo que posso fazer com o implante no momento. Não quer um tratamento nesses ferimentos?,,Asta e tot ce îi pot face implantului pentru moment. Poate niște tratament?,Пока что я больше ничего не могу сделать с имплантом. Как насчёт лечения?,,Det är allt jag kan göra med implantatet just nu. Kanske lite läkning?,Şu anda implant üzerinde yapabileceğim tek şey bu. Belki biraz iyileşme? +Yeah.,TXT_RPLY0_SCRIPT03_D31836_YEAH,〃 (〃),,,Jo.,Ja.,Ja.,,Jes.,Sí.,,Kyllä.,Ouais.,Igen.,Sì.,ああ。,네.,Ja.,Ja.,Pewnie.,Pode ser.,,Da.,Давай.,,"Ja, det är det.","Evet, belki." "Boy, you're a real mess. I'll see what I can do.",TXT_RYES0_SCRIPT03_D31836_BOYYO,〃 (〃),,,"Tebe teda zřídili, kluku. Uvidím, co s tebou.","Mand, du er et rigtigt rod. Jeg skal se, hvad jeg kan gøre.","Mann, du siehst aber gar nicht gut aus. Mal sehen, was ich machen kann.",,"Ulo, vi estas iomege en malordo. Mi vidos tion, kion mi faru.","Tío, estás hecho un desastre. A ver qué puedo hacer.","Chico, estás hecho un desastre. -A ver qué puedo hacer.","Kylläpä olet huonossa jamassa. Katsotaan, mitä voin tehdä.","Mon petit, vous êtes dans un sale état. Je vais voir ce que je peux faire.","Öregem, elég rossz passzban vagy. Megnézem mit tudok tenni.","Ragazzo, sei messo proprio male. Vediamo cosa posso fare.",君、滅茶苦茶だな。なんとかしよう。,심각한 부상을 입은 것 같군요. 치료하겠습니다.,"Jongen, je bent een echte puinhoop. Ik zal zien wat ik kan doen.","Jøss, du er et skikkelig rot. Jeg skal se hva jeg kan gjøre.","Chłopie, ależ ty jesteś poszarpany. Zobaczę co da się zrobić.","Rapaz, você está arrebentado. Vou ver o que posso fazer.",,"Mamă, ești un dezastru. O să văd ce pot face.","Парень, да на тебя смотреть страшно. Приступим...",,Çok dağınıksın. Ne yapabileceğime bir bakayım. -What can I do for you?,TXT_DLG_SCRIPT03_D33352_WHATC,MAP03: Feris (no training).,,,Co pro tebe můžu udělat?,Hvad kan jeg gøre for dig?,Was kann ich für dich tun?,,Kion mi faru por vi?,¿Qué puedo hacer por ti?,,Mitä voin tehdä sinulle?,Que puis-je faire pour vous?,Miben segíthetek?,Cosa posso fare per te?,どういったご用件で?,필요한 게 있으면 말씀하세요.,Wat kan ik voor je doen?,Hva kan jeg gjøre for deg?,Co mogę dla ciebie zrobić?,Como posso te ajudar?,,Ce pot face pentru tine?,Чем я могу тебе помочь?,,Senin için ne yapabilirim? -I'm out of bullets.,TXT_RPLY0_SCRIPT03_D33352_IMOUT,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Minulta on luodit loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Nie mam nabojów.,Estou sem balas.,,Nu mai am gloanțe.,У меня кончились патроны.,,Mermim bitti. +A ver qué puedo hacer.","Kylläpä olet huonossa jamassa. Katsotaan, mitä voin tehdä.","Mon petit, vous êtes dans un sale état. Je vais voir ce que je peux faire.","Öregem, elég rossz passzban vagy. Megnézem mit tudok tenni.","Ragazzo, sei messo proprio male. Vediamo cosa posso fare.",君、滅茶苦茶だな。なんとかしよう。,심각한 부상을 입은 것 같군요. 치료하겠습니다.,"Jongen, je bent een echte puinhoop. Ik zal zien wat ik kan doen.","Jøss, du er et skikkelig rot. Jeg skal se hva jeg kan gjøre.","Chłopie, ależ ty jesteś poszarpany. Zobaczę co da się zrobić.","Rapaz, você está arrebentado. Vou ver o que posso fazer.",,"Mamă, ești un dezastru. O să văd ce pot face.","Парень, да на тебя смотреть страшно. Приступим...",,Du är en riktig röra. Jag ska se vad jag kan göra.,Çok dağınıksın. Ne yapabileceğime bir bakayım. +What can I do for you?,TXT_DLG_SCRIPT03_D33352_WHATC,MAP03: Feris (no training).,,,Co pro tebe můžu udělat?,Hvad kan jeg gøre for dig?,Was kann ich für dich tun?,,Kion mi faru por vi?,¿Qué puedo hacer por ti?,,Mitä voin tehdä sinulle?,Que puis-je faire pour vous?,Miben segíthetek?,Cosa posso fare per te?,どういったご用件で?,필요한 게 있으면 말씀하세요.,Wat kan ik voor je doen?,Hva kan jeg gjøre for deg?,Co mogę dla ciebie zrobić?,Como posso te ajudar?,,Ce pot face pentru tine?,Чем я могу тебе помочь?,,Vad kan jag göra för dig?,Senin için ne yapabilirim? +I'm out of bullets.,TXT_RPLY0_SCRIPT03_D33352_IMOUT,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Minulta on luodit loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Nie mam nabojów.,Estou sem balas.,,Nu mai am gloanțe.,У меня кончились патроны.,,Jag har slut på kulor.,Mermim bitti. Here's some ammo for you. Don't waste it.,TXT_RYES0_SCRIPT03_D33352_HERES,〃 (〃),,,"Tady máš nějakou munici, neplýtvej s ní.",Her er noget ammunition til dig. Spild det ikke.,Hier hast du welche. Verschwende sie nicht.,,"Jen iom da municio. Ne malŝparu ĝin.","Aquí tienes algo de munición. -No la desperdicies.",,Tässä sinulle panoksia. Älä tuhlaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van egy kis muníció számodra. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,여기 조금의 탄약을 나눠줄게요. 낭비하지 마시길.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Masz tu trochę amunicji. Nie zmarnuj jej.,Tome um pouco de munição. Não desperdice.,,Uite niște muniție. N-o risipi.,Можешь взять немного. Не трать их понапрасну.,,Al sana biraz mermi. Boşa harcama. -Teach me.,TXT_RPLY1_SCRIPT03_D33352_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Ucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. +No la desperdicies.",,Tässä sinulle panoksia. Älä tuhlaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van egy kis muníció számodra. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,여기 조금의 탄약을 나눠줄게요. 낭비하지 마시길.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Masz tu trochę amunicji. Nie zmarnuj jej.,Tome um pouco de munição. Não desperdice.,,Uite niște muniție. N-o risipi.,Можешь взять немного. Не трать их понапрасну.,,Här är lite ammunition till dig. Slösa inte bort den.,Al sana biraz mermi. Boşa harcama. +Teach me.,TXT_RPLY1_SCRIPT03_D33352_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Ucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. "All right, I'll just show you a few little pointers.",TXT_RYES1_SCRIPT03_D33352_ALLRI,〃 (〃),,,"Dobře, ukážu ti pár triků.","Okay, jeg vil bare vise dig et par små tips.","Alles klar, ich zeige dir ein paar Kniffe.",,"Bone, jen kelkaj konsiletoj...","Muy bien, aquí van -un par de consejos...",,"Hyvä on, annan sinulle vain muutamia pikkuvinkkejä.",Pas de problème. Laissez moi vous montrer quelques trucs.,Akkor addok pár hasznos tanácsot.,"Va bene, ti darò un paio di dritte molto utili.",わかった、貴方にやり方を幾つか教えよう。,좋아요. 훈련에 도움이 될 만한 표적을 보여주겠습니다.,"Oké, ik zal je gewoon een paar kleine tips laten zien.","Greit, jeg skal bare vise deg noen små tips.","Dobrze, podam ci parę wskazówek.","Ok, vou te dar algumas dicas.",,"În regulă, o să îți arăt niște repere.",Хорошо. Покажу тебе пару приёмов.,,"Pekala, sana birkaç küçük ipucu göstereceğim." +un par de consejos...",,"Hyvä on, annan sinulle vain muutamia pikkuvinkkejä.",Pas de problème. Laissez moi vous montrer quelques trucs.,Akkor addok pár hasznos tanácsot.,"Va bene, ti darò un paio di dritte molto utili.",わかった、貴方にやり方を幾つか教えよう。,좋아요. 훈련에 도움이 될 만한 표적을 보여주겠습니다.,"Oké, ik zal je gewoon een paar kleine tips laten zien.","Greit, jeg skal bare vise deg noen små tips.","Dobrze, podam ci parę wskazówek.","Ok, vou te dar algumas dicas.",,"În regulă, o să îți arăt niște repere.",Хорошо. Покажу тебе пару приёмов.,,"Okej, jag ska bara visa dig några små tips.","Pekala, sana birkaç küçük ipucu göstereceğim." You're not ready yet.,TXT_RNO1_SCRIPT03_D33352_YOURE,〃 (〃),,,Ještě nejsi připravený.,Du er ikke klar endnu.,Du bist noch nicht so weit.,,"Vi ankoraŭ -ne estas preta.",Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Még nem állsz készen.,Non sei ancora pronto.,貴方の準備がまだ整ってないように思えます。,아직 준비가 안 됐어요.,Je bent nog niet klaar.,Du er ikke klar ennå.,Nie jesteś jeszcze gotowy.,Você ainda não está pronto.,,Nu ești pregătit încă.,Ты ещё не готов.,,Henüz hazır değilsin. -Back again? What do you need?,TXT_DLG_SCRIPT03_D34868_BACKA,〃 (one training),,,Zase zpátky? Co potřebuješ?,Tilbage igen? Hvad har du brug for?,Scxhon zurück? Was brauchst du?,,Do vi revenis. Kion vi bezonas?,¿Ya de vuelta? ¿Qué necesitas?,,Täällä taas? Mitä tarvitset?,Déjà de retour? De quoi avez-vous besoin?,Már vissza is tértél? Mire van szükséged?,Già di ritorno? Che cosa ti serve?,もう戻りましたか?何が必要ですか?,또 왔네? 뭐가 필요합니까?,Weer terug? Wat heb je nodig?,Tilbake igjen? Hva trenger du?,Wróciłeś? Czego chcesz?,Você novamente? Do que precisa?,,Te-ai întors iar? De ce ai nevoie?,Ты вернулся? Что тебе нужно?,,Yine mi? Neye ihtiyacın var? -I'm out of bullets.,TXT_RPLY0_SCRIPT03_D34868_IMOUT,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Minulta on ammukset loppu.,Je suis à cours de munitions.,Kifogytam a golyókból.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Nie mam nabojów.,Estou sem balas.,,Nu mai am gloanțe.,У меня кончились патроны.,,Mermim bitti. +ne estas preta.",Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Még nem állsz készen.,Non sei ancora pronto.,貴方の準備がまだ整ってないように思えます。,아직 준비가 안 됐어요.,Je bent nog niet klaar.,Du er ikke klar ennå.,Nie jesteś jeszcze gotowy.,Você ainda não está pronto.,,Nu ești pregătit încă.,Ты ещё не готов.,,Du är inte redo än.,Henüz hazır değilsin. +Back again? What do you need?,TXT_DLG_SCRIPT03_D34868_BACKA,〃 (one training),,,Zase zpátky? Co potřebuješ?,Tilbage igen? Hvad har du brug for?,Scxhon zurück? Was brauchst du?,,Do vi revenis. Kion vi bezonas?,¿Ya de vuelta? ¿Qué necesitas?,,Täällä taas? Mitä tarvitset?,Déjà de retour? De quoi avez-vous besoin?,Már vissza is tértél? Mire van szükséged?,Già di ritorno? Che cosa ti serve?,もう戻りましたか?何が必要ですか?,또 왔네? 뭐가 필요합니까?,Weer terug? Wat heb je nodig?,Tilbake igjen? Hva trenger du?,Wróciłeś? Czego chcesz?,Você novamente? Do que precisa?,,Te-ai întors iar? De ce ai nevoie?,Ты вернулся? Что тебе нужно?,,Tillbaka igen? Vad behöver du?,Yine mi? Neye ihtiyacın var? +I'm out of bullets.,TXT_RPLY0_SCRIPT03_D34868_IMOUT,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Minulta on ammukset loppu.,Je suis à cours de munitions.,Kifogytam a golyókból.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Nie mam nabojów.,Estou sem balas.,,Nu mai am gloanțe.,У меня кончились патроны.,,Jag har slut på kulor.,Mermim bitti. Here's some ammo for you. Don't waste it.,TXT_RYES0_SCRIPT03_D34868_HERES,〃 (〃),,,"Tady máš nějakou munici, neplýtvej s ní.",Her er lidt ammunition til dig. Spild det ikke.,Hier hast du welche. Verschwende sie nicht.,,"Jen iom da municio. Ne malŝparu ĝin.","Aquí tienes algo de munición. -No la desperdicies.",,Tässä vähän lisää. Älä haaskaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van egy kis muníció számodra. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,뭘 하다 탄약을 낭비한 겁니까? 여기 조금 줄게요.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Masz tu trochę amunicji. Nie zmarnuj jej.,Tome um pouco de munição. Não desperdice.,,Uite niște muniție. N-o risipi.,Можешь взять немного. Не трать их понапрасну.,,İşte sana biraz cephane. Boşa harcama. -You've got enough ammo.,TXT_RNO0_SCRIPT03_D34868_YOUVE,〃 (〃),,,Vždyť jich máš dost.,Du har ammunition nok.,Du hast genug.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ma veramente ne hai a sufficienza.,弾は十分に見えます。,당신은 충분한 탄약을 가졌어요.,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz już wystarczająco dużo amunicji.,Você já tem munição o suficiente.,,Au destulă muniție.,У тебя их достаточно.,,Yeterince mermin var. -Teach me.,TXT_RPLY1_SCRIPT03_D34868_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Ucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. +No la desperdicies.",,Tässä vähän lisää. Älä haaskaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van egy kis muníció számodra. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,뭘 하다 탄약을 낭비한 겁니까? 여기 조금 줄게요.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Masz tu trochę amunicji. Nie zmarnuj jej.,Tome um pouco de munição. Não desperdice.,,Uite niște muniție. N-o risipi.,Можешь взять немного. Не трать их понапрасну.,,Här är lite ammunition till dig. Slösa inte bort den.,İşte sana biraz cephane. Boşa harcama. +You've got enough ammo.,TXT_RNO0_SCRIPT03_D34868_YOUVE,〃 (〃),,,Vždyť jich máš dost.,Du har ammunition nok.,Du hast genug.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ma veramente ne hai a sufficienza.,弾は十分に見えます。,당신은 충분한 탄약을 가졌어요.,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz już wystarczająco dużo amunicji.,Você já tem munição o suficiente.,,Au destulă muniție.,У тебя их достаточно.,,Du har tillräckligt med ammunition.,Yeterince mermin var. +Teach me.,TXT_RPLY1_SCRIPT03_D34868_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Ucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. "All right, this should keep you going for a while.",TXT_RYES1_SCRIPT03_D34868_ALLRI,〃 (〃),,,"Dobře, tohle by ti mělo pomoct.","Okay, det her burde holde dig i gang et stykke tid.","Alles klar, das sollte fürs erste reichen.",,"Bone, ĉi tio devus esti sufiĉe utila nuntempe.","Muy bien, esto debería -servirte por el momento.",,"Selvä on, tällä sinun pitäisi pötkiä aika pitkälle.","Bien, ça devrait vous suffir pour un bon moment.","Rendben van, ezzel el leszel egy darabig.","Va bene, con questo dovresti andare sul sicuro per un pò.",わかりました、これで長くやり合えるでしょう。,그렇군요. 가능한 오래 싸울 수 있을겁니다.,"Oké, dit zou je een tijdje op de been moeten houden.","Greit, dette burde holde deg gående en stund.","Dobrze, to powinno ci pomóc na pewien czas.","Ok, isso deve te ajudar no momento.",,"În regulă, asta ar trebui să te ajute pentru moment.","Хорошо, это не раз спасёт тебе жизнь.",,"Pekala, bu seni bir süre idare eder." +servirte por el momento.",,"Selvä on, tällä sinun pitäisi pötkiä aika pitkälle.","Bien, ça devrait vous suffir pour un bon moment.","Rendben van, ezzel el leszel egy darabig.","Va bene, con questo dovresti andare sul sicuro per un pò.",わかりました、これで長くやり合えるでしょう。,그렇군요. 가능한 오래 싸울 수 있을겁니다.,"Oké, dit zou je een tijdje op de been moeten houden.","Greit, dette burde holde deg gående en stund.","Dobrze, to powinno ci pomóc na pewien czas.","Ok, isso deve te ajudar no momento.",,"În regulă, asta ar trebui să te ajute pentru moment.","Хорошо, это не раз спасёт тебе жизнь.",,"Okej, det här borde hålla dig igång ett tag.","Pekala, bu seni bir süre idare eder." "Sorry, can't. I'm just following Macil's orders.",TXT_RNO1_SCRIPT03_D34868_SORRY,〃 (〃),,,"Promiň, nemůžu. Řídím se rozkazy od Macila.","Beklager, jeg kan ikke. Jeg følger bare Macils ordrer.","Tut mir leid, aber ich kann nicht. Ich folge nur Macils Befehlen.",,"Pardonon, mi ne rajtas. Mi nur observas Macil-on.","Lo siento, no puedo. -Solo sigo órdenes de Macil.",,Valitettavasti en voi. Noudatan vain Macilin käskyjä.,"Désolé, pas possible. Je ne fais que suivre les ordres de Macil.","Sajnálom, de nem tehetem. Macil utasítása.","Mi spiace, ma non posso. Ordini dall'alto.",すまないが、できません。マシルの命令です。,미안합니다. 마실 사령관님의 명령을 따라야해요.,"Sorry, dat kan niet. Ik volg gewoon de orders van Macil op.","Beklager, jeg kan ikke. Jeg følger bare Macils ordre.","Przepraszam, ale nie mogę. Ja tylko wykonuję rozkazy Macila.",Desculpe mas não posso. Estou apenas seguindo as ordens de Macil.,,"Scuze, nu merge. Doar urmez ordinele lui Macil.","Увы, не могу. Я подчиняюсь Мэйсилу.",,"Üzgünüm, yapamam. Macil'in emirlerini uyguluyorum." +Solo sigo órdenes de Macil.",,Valitettavasti en voi. Noudatan vain Macilin käskyjä.,"Désolé, pas possible. Je ne fais que suivre les ordres de Macil.","Sajnálom, de nem tehetem. Macil utasítása.","Mi spiace, ma non posso. Ordini dall'alto.",すまないが、できません。マシルの命令です。,미안합니다. 마실 사령관님의 명령을 따라야해요.,"Sorry, dat kan niet. Ik volg gewoon de orders van Macil op.","Beklager, jeg kan ikke. Jeg følger bare Macils ordre.","Przepraszam, ale nie mogę. Ja tylko wykonuję rozkazy Macila.",Desculpe mas não posso. Estou apenas seguindo as ordens de Macil.,,"Scuze, nu merge. Doar urmez ordinele lui Macil.","Увы, не могу. Я подчиняюсь Мэйсилу.",,"Tyvärr, jag kan inte. Jag följer bara Macils order.","Üzgünüm, yapamam. Macil'in emirlerini uyguluyorum." "Well which is it, bullets or training? I can't wait to get my hands on those new weapons we captured. A little bit of training and then a lot of revenge.",TXT_DLG_SCRIPT03_D36384_WELLW,〃 (two trainings),,,"Tak co to bude, náboje nebo trénink? Nemůžu se dočkat, až se dostanu k těm novým zbraním, které jsme zabavili. Trocha cvičení a pak hodně odplaty.","Nå, hvad er det, kugler eller træning? Jeg kan ikke vente med at få fingrene i de nye våben, vi har taget til fange. En lille smule træning og så en masse hævn.","Also, was willst du? Munition oder Training? Ich kann kaum erwarten, diese neuen Waffen, die wir erbeutet haben, in die Finger zu kriegen. ein bisschen Training und dann jede Menge Vergeltung.",,"Nu, ĉu kugloj aŭ trejnado ĉi-foje? Mi sopire atendas provi tiujn novajn kaptitajn armilojn. Iom da trejnado kaj tiam multe da venĝo.","Bueno, ¿qué va a ser?, ¿balas o entrenamiento? No puedo esperar a poner mis manos en esas nuevas armas que hemos capturado. Un poco de entrenamiento y luego mucha venganza.","Bueno, ¿qué va a ser?, ¿balas o entrenamiento? No puedo esperar a poner mis manos en esas nuevas armas que capturamos. Un poco de entrenamiento y luego mucha venganza.","No niin, kumpaa saisi olla: luoteja vai koulutusta? En voi malttaa olla tarttumasta vasta kaappaamiimme aseisiin. Hieman perehdytystä, ja sitten paljon kostamista.","Qu'est-ce qu'il vous faut? Des munitions ou de l'entraînement? J'ai hâte d'essayer ces nouvelles armes que l'on a capturé, un peu d'entraînement et beaucoup de vengeance.","Akkor döntsd el, lőszer vagy kiképzés? Már alig várom hogy rátegyem a kezem a lefoglalt fegyverekre. Egy kis kiképzés, és jó sok bosszú.","Bene, che cosa ti serve, munizioni o addestramento? Non vedo l'ora di mettere le mani su quelle nuove armi che abbiamo preso. Un pò di addestramento e poi molta vendetta.","弾薬と訓練、どっちの用件ですか? 奪った新しい武器が届くのを待ち切れないです。 -少しの訓練でデカい復讐を。","무엇을 원하십니까? 보급? 아니면 훈련? 방금 전달된 새로운 무기들을 만지고 싶습니다! 아무튼, 훈련을 거치면 복수를 멋지게 해내실 거에요.","Wat is het dan wel, kogels of training? Ik kan niet wachten om die nieuwe wapens in handen te krijgen die we gevangen genomen hebben. Een beetje training en dan veel wraak.","Hva er det, kuler eller trening? Jeg gleder meg til å få tak i de nye våpnene vi tok. Litt trening, og så mye hevn.","Więc czego chcesz, naboje czy trening? Nie mogę się doczekać, aż dostanę jedną z tych nowych broni, które udało nam się przejąć. Trochę treningu, a potem zemsta.","Bem, o que vai ser? Munição ou treinamento? Mal posso esperar para pegar nessas novas armas que capturamos. Um pouquinho de treinamento e depois muita vingança.",,"Deci ce alegi, gloanțe sau antrenament? Abia aștept să pun mâna pe noile arme pe care le-am capturat. Puțin antrenament, iar apoi multă răzbunare.","Что скажешь, патроны или тренировка? Мне не терпится опробовать это новое трофейное оружие. Небольшая подготовка, и они за всё заплатят.",,"Hangisi, mermi mi eğitim mi? Yakaladığımız yeni silahları elime almak için sabırsızlanıyorum. Biraz eğitim ve sonra bolca intikam." -I'm out of ammo.,TXT_RPLY0_SCRIPT03_D36384_IMOUT,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for ammunition.,Ich habe keine Munition mehr.,,Mi estas sen municio.,No me queda munición.,,Minulta on panokset loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 떨어졌어요.,Ik heb geen munitie meer.,Jeg er tom for ammunisjon.,Nie mam amunicji.,Estou sem munição.,,Nu mai am muniție.,У меня кончились боеприпасы.,,Cephanem bitti. +少しの訓練でデカい復讐を。","무엇을 원하십니까? 보급? 아니면 훈련? 방금 전달된 새로운 무기들을 만지고 싶습니다! 아무튼, 훈련을 거치면 복수를 멋지게 해내실 거에요.","Wat is het dan wel, kogels of training? Ik kan niet wachten om die nieuwe wapens in handen te krijgen die we gevangen genomen hebben. Een beetje training en dan veel wraak.","Hva er det, kuler eller trening? Jeg gleder meg til å få tak i de nye våpnene vi tok. Litt trening, og så mye hevn.","Więc czego chcesz, naboje czy trening? Nie mogę się doczekać, aż dostanę jedną z tych nowych broni, które udało nam się przejąć. Trochę treningu, a potem zemsta.","Bem, o que vai ser? Munição ou treinamento? Mal posso esperar para pegar nessas novas armas que capturamos. Um pouquinho de treinamento e depois muita vingança.",,"Deci ce alegi, gloanțe sau antrenament? Abia aștept să pun mâna pe noile arme pe care le-am capturat. Puțin antrenament, iar apoi multă răzbunare.","Что скажешь, патроны или тренировка? Мне не терпится опробовать это новое трофейное оружие. Небольшая подготовка, и они за всё заплатят.",,"Vad är det, kulor eller träning? Jag kan inte vänta på att få ta del av de nya vapnen som vi tog till fånga. Lite träning och sedan en massa hämnd.","Hangisi, mermi mi eğitim mi? Yakaladığımız yeni silahları elime almak için sabırsızlanıyorum. Biraz eğitim ve sonra bolca intikam." +I'm out of ammo.,TXT_RPLY0_SCRIPT03_D36384_IMOUT,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for ammunition.,Ich habe keine Munition mehr.,,Mi estas sen municio.,No me queda munición.,,Minulta on panokset loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 떨어졌어요.,Ik heb geen munitie meer.,Jeg er tom for ammunisjon.,Nie mam amunicji.,Estou sem munição.,,Nu mai am muniție.,У меня кончились боеприпасы.,,Jag har slut på ammunition.,Cephanem bitti. Here's some ammo for you. Don't waste it.,TXT_RYES0_SCRIPT03_D36384_HERES,〃 (〃),,,"Tady máš nějakou munici, neplýtvej s ní.",Her er noget ammunition til dig. Spild det ikke.,Hier hast du welche. Verschwende sie nicht.,,"Jen iom da municio. Ne malŝparu ĝin.","Aquí tienes algo de munición. -No la desperdicies.",,Tässä ammuksia. Älä tuhlaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van egy kis muníció számodra. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,여기 탄약입니다. 부디 열심히 싸우고 정확하게 쏘시길.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Masz tu trochę amunicji. Nie zmarnuj jej.,Tome um pouco de munição. Não desperdice.,,Uite niște muniție. N-o risipi.,Можешь взять немного. Не трать их понапрасну.,,İşte sana biraz cephane. Boşa harcama. -You've got enough ammo.,TXT_RNO0_SCRIPT03_D36384_YOUVE,〃 (〃),,,Vždyť jich máš dost.,Du har ammunition nok.,Du hast genug.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ma veramente ne hai a sufficienza.,弾は十分に見えます。,거짓말. 탄약을 충분히 가졌잖아요.,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz już wystarczająco dużo amunicji.,Você já tem munição o suficiente.,,Ai destulă muniție.,У тебя хватает патронов.,,Yeterince cephanen var. -Teach me.,TXT_RPLY1_SCRIPT03_D36384_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Ucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. +No la desperdicies.",,Tässä ammuksia. Älä tuhlaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van egy kis muníció számodra. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,여기 탄약입니다. 부디 열심히 싸우고 정확하게 쏘시길.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Masz tu trochę amunicji. Nie zmarnuj jej.,Tome um pouco de munição. Não desperdice.,,Uite niște muniție. N-o risipi.,Можешь взять немного. Не трать их понапрасну.,,Här är lite ammunition till dig. Slösa inte bort den.,İşte sana biraz cephane. Boşa harcama. +You've got enough ammo.,TXT_RNO0_SCRIPT03_D36384_YOUVE,〃 (〃),,,Vždyť jich máš dost.,Du har ammunition nok.,Du hast genug.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ma veramente ne hai a sufficienza.,弾は十分に見えます。,거짓말. 탄약을 충분히 가졌잖아요.,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz już wystarczająco dużo amunicji.,Você já tem munição o suficiente.,,Ai destulă muniție.,У тебя хватает патронов.,,Du har tillräckligt med ammunition.,Yeterince cephanen var. +Teach me.,TXT_RPLY1_SCRIPT03_D36384_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Ucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. O.K. Take what you've learned here and show those Order clods the way to hell.,TXT_RYES1_SCRIPT03_D36384_OKTAK,〃 (〃),,,"Oukej. Pamatuj, co ses tady naučil, a ukaž těm hajzlům z Řádu kudy do pekla.","O.K. Tag det, du har lært her, og vis de ordensklodser vejen til helvede.","OK. Nutze, was du hier gelernt hast um diesen Tölpeln vom Orden den Weg in die Hölle zu zeigen.",,"Bone. Uzu ĉi tion por gvidi tiujn aĉulojn de La Ordono al la infero.","Bien. Usa lo aprendido para guiar a esos majaderos de La Orden al infierno.","Bien. Usa lo aprendido para guiar a esos desgraciados de La Orden al infierno.","OK. Hyödynnä täällä oppimaasi, ja näytä niille Veljeskunnan valopäille tie helvettiin.",OK. Utilisez ce que vous avez appris et envoyez ces abrutis de l'Ordre en enfer.,Akkor rendben is vagyunk. Mutasd meg a Rend barmainak hol lakik az isten.,O.K. Usa ciò che hai imparato qua per mostrare all'Ordine la via dell'Inferno.,"オーケー、ここで学んだ事を生かして -オーダー共を地獄に送って上げなさい。",좋아요! 훈련을 통해서 얻은 실력으로 저 오더 돌대가리들을 박살을 내버려요!,"Oké, neem wat je hier geleerd hebt en laat die Ordekluiten de weg naar de hel zien.","OK. Ta det du har lært her, og vis de ordenstullingene veien til helvete.",Ok. Bierz to czego się nauczyłeś i pokaż tym durniom z Zakonu drogę do piekła.,Ok. Use o que você aprendeu aqui para mostrar o caminho pro inferno a esses desgraçados da Ordem.,,În regulă. Folosește ce ai învățat aici si aratăle nătărăilor din Ordin calea spre infern.,"Запоминай внимательно, покажешь этим прихвостням Ордена быструю дорогу в ад.",,Tamam. Burada öğrendiklerini al ve o tarikatçılara cehenneme giden yolu göster. +オーダー共を地獄に送って上げなさい。",좋아요! 훈련을 통해서 얻은 실력으로 저 오더 돌대가리들을 박살을 내버려요!,"Oké, neem wat je hier geleerd hebt en laat die Ordekluiten de weg naar de hel zien.","OK. Ta det du har lært her, og vis de ordenstullingene veien til helvete.",Ok. Bierz to czego się nauczyłeś i pokaż tym durniom z Zakonu drogę do piekła.,Ok. Use o que você aprendeu aqui para mostrar o caminho pro inferno a esses desgraçados da Ordem.,,În regulă. Folosește ce ai învățat aici si aratăle nătărăilor din Ordin calea spre infern.,"Запоминай внимательно, покажешь этим прихвостням Ордена быструю дорогу в ад.",,O.K. Ta det du lärt dig här och visa de där ordenskloddarna vägen till helvetet.,Tamam. Burada öğrendiklerini al ve o tarikatçılara cehenneme giden yolu göster. "Come back later, when Macil says it's time.",TXT_RNO1_SCRIPT03_D36384_COMEB,〃 (〃),,,"Přijď někdy jindy, až řekne Macil.","Kom tilbage senere, når Macil siger, det er tid.","Komm wieder, wenn Macil dir Bescheid gibt.",,"Revenu post kiam Macil ordonis tion.","Vuelve más tarde cuando -Macil diga que ya es la hora.",,"Palaa asiaan myöhemmin, kun Macil näyttää vihreää valoa.",Revenez plus tard quand Macil décide qu'il est temps.,"Gyere vissza akkor, ha azt mondja Macil hogy ideje van.","Ritorna più tardi, quando Macil dirà che è il momento.",マシルの命令を受けてから、また来なさい。,사령관님은 인내심이 많은 분입니다. 나중에 확인해주시길.,"Kom later terug, als Macil zegt dat het tijd is.","Kom tilbake senere, når Macil sier det er på tide.","Przyjdź później, kiedy Macil powie, że już czas.","Volte mais tarde, quando Macil disser que está na hora.",,"Revin-o mai târziu, când Macil spune că e timpul.","Приходи позже, когда прикажет Мэйсил.",,Macil zamanı geldiğini söylediğinde geri gel. +Macil diga que ya es la hora.",,"Palaa asiaan myöhemmin, kun Macil näyttää vihreää valoa.",Revenez plus tard quand Macil décide qu'il est temps.,"Gyere vissza akkor, ha azt mondja Macil hogy ideje van.","Ritorna più tardi, quando Macil dirà che è il momento.",マシルの命令を受けてから、また来なさい。,사령관님은 인내심이 많은 분입니다. 나중에 확인해주시길.,"Kom later terug, als Macil zegt dat het tijd is.","Kom tilbake senere, når Macil sier det er på tide.","Przyjdź później, kiedy Macil powie, że już czas.","Volte mais tarde, quando Macil disser que está na hora.",,"Revin-o mai târziu, când Macil spune că e timpul.","Приходи позже, когда прикажет Мэйсил.",,"Kom tillbaka senare, när Macil säger att det är dags.",Macil zamanı geldiğini söylediğinde geri gel. I've taught you everything I can right now. Give me some time to put the new weapons through their paces. That is unless you're out of bullets.,TXT_DLG_SCRIPT03_D37900_IVETA,〃 (three trainings),,,"Naučil jsem tě vše, co teď můžu. Dej mi nějaký čas, abych vyzkoušel ty nové zbraně. Jedině, že bys potřeboval náboje.","Jeg har lært dig alt, hvad jeg kan lige nu. Giv mig lidt tid til at sætte de nye våben på prøve. Medmindre du er løbet tør for kugler.","Ich habe dir alles gezeigt, was ich momentan kann. Gib mir etwas Zeit um die neuen Waffen zu testen. Munition kriegst du natürlich auch so.",,"Mi instruis al vi ĉion, kion mi povas. Donu tempon al mi por elprovi la novajn armilojn... krom se vi nur bezonas pliajn kuglojn.","Te he enseñado todo lo que puedo por ahora. Dame tiempo para probar al 100% las nuevas armas... a menos que solo necesites más balas, claro.","Ya te enseñé todo lo que puedo por ahora. Dame tiempo para probar al 100% las nuevas armas... a menos que solo necesites más balas, claro.","Olen opettanut sinulle kaiken, mitä itse juuri nyt osaan. Anna minulle vähän aikaa käydä läpi uusien aseiden askelkuvioita. Ellei sinulla sitten ole luodit lopussa.","Je vous ai enseigné tout ce que je sais. Laissez moi un peu de temps pour tester ces nouvelles armes. Sauf si vous n'avez plus de munitions, bien sûr.","Megtanítottam mindent amit jelenleg tudtam. Adj egy kis időt, hogy leteszteljem a fegyvereket. Kivétel persze ha lőszer kell.",Ti ho insegnato tutto quello che potevo per ora. Dammi dell'altro tempo per mettere le nuove armi alla prova. A meno che non ti servano altre munizioni.,"私が教えられる事はもうありません。 今後新しい武器は時間が掛かるが自分のペースで -学びなさい。弾切れでなければの話ですが。",제가 제공할 수 있을 만큼의 훈련을 배우셨습니다. 부디 무기를 다룰 시간을 주세요. 보급 때문에 찾아오신 게 아니라면 말이죠.,Ik heb je alles geleerd wat ik nu kan. Geef me wat tijd om de nieuwe wapens op de proef te stellen. Tenzij je geen kogels meer hebt.,Jeg har lært deg alt jeg kan nå. Gi meg litt tid til å teste de nye våpnene. Med mindre du er tom for kuler.,"Nauczyłem cię wszystkiego co mogę na chwilę obecną. Daj mi trochę czasu, aby przetestować nowe bronie. No chyba, że brakuje ci nabojów.",Já te ensinei tudo o que pude. Me dê um tempo para eu testar as novas armas. A não ser que você esteja sem munição.,,Te-am învățat tot ce stiu. Dă-mi niște timp să pun noile arme la treabă. Asta dacă nu ai rămas fără gloanțe.,Пока что я не могу научить тебя ничему новому. Дай мне время разобраться в этом новом оружии. Или у тебя закончились патроны?,,Şu anda sana öğretebileceğim her şeyi öğrettim. Yeni silahları denemem için bana biraz zaman ver. Tabii mermin bitmediyse. -Yes I am.,TXT_RPLY0_SCRIPT03_D37900_YESIA,〃 (〃),,,"Ano, potřebuju.","Ja, det er jeg.","Ja, bin ich.",,Ĝuste.,Eso mismo.,,Kyllä on.,"En effet, je le suis.","Igen, az vagyok.",Sì che mi servono.,ああ、そうだ。,알겠습니다. 그럼 탄약이라도?,"Ja, dat ben ik wel.","Ja, det er jeg.",Zgadza się.,"Sim, estou.",,"Da, am rămas fără.","Да, закончились.",,"Evet, bitti." -Here you go.,TXT_RYES0_SCRIPT03_D37900_HEREY,〃 (〃),,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,"Tässä, ole hyvä.",Voilà pour vous.,Parancsolj.,Ecco qua.,どうぞ。,여기 있어요!,Alsjeblieft.,Vær så god.,Masz.,Aqui está.,,Iată.,Держи.,,Al bakalım. +学びなさい。弾切れでなければの話ですが。",제가 제공할 수 있을 만큼의 훈련을 배우셨습니다. 부디 무기를 다룰 시간을 주세요. 보급 때문에 찾아오신 게 아니라면 말이죠.,Ik heb je alles geleerd wat ik nu kan. Geef me wat tijd om de nieuwe wapens op de proef te stellen. Tenzij je geen kogels meer hebt.,Jeg har lært deg alt jeg kan nå. Gi meg litt tid til å teste de nye våpnene. Med mindre du er tom for kuler.,"Nauczyłem cię wszystkiego co mogę na chwilę obecną. Daj mi trochę czasu, aby przetestować nowe bronie. No chyba, że brakuje ci nabojów.",Já te ensinei tudo o que pude. Me dê um tempo para eu testar as novas armas. A não ser que você esteja sem munição.,,Te-am învățat tot ce stiu. Dă-mi niște timp să pun noile arme la treabă. Asta dacă nu ai rămas fără gloanțe.,Пока что я не могу научить тебя ничему новому. Дай мне время разобраться в этом новом оружии. Или у тебя закончились патроны?,,Jag har lärt dig allt jag kan just nu. Ge mig lite tid att sätta de nya vapnen på prov. Det vill säga om du inte har slut på kulor.,Şu anda sana öğretebileceğim her şeyi öğrettim. Yeni silahları denemem için bana biraz zaman ver. Tabii mermin bitmediyse. +Yes I am.,TXT_RPLY0_SCRIPT03_D37900_YESIA,〃 (〃),,,"Ano, potřebuju.","Ja, det er jeg.","Ja, bin ich.",,Ĝuste.,Eso mismo.,,Kyllä on.,"En effet, je le suis.","Igen, az vagyok.",Sì che mi servono.,ああ、そうだ。,알겠습니다. 그럼 탄약이라도?,"Ja, dat ben ik wel.","Ja, det er jeg.",Zgadza się.,"Sim, estou.",,"Da, am rămas fără.","Да, закончились.",,"Ja, det är jag.","Evet, bitti." +Here you go.,TXT_RYES0_SCRIPT03_D37900_HEREY,〃 (〃),,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,"Tässä, ole hyvä.",Voilà pour vous.,Parancsolj.,Ecco qua.,どうぞ。,여기 있어요!,Alsjeblieft.,Vær så god.,Masz.,Aqui está.,,Iată.,Держи.,,Här har du.,Al bakalım. Don't get trigger happy in the town. You'll set off the alarm and they'll start sending in guards from the castle. ,TXT_DLG_SCRIPT03_D39416_DONTG,MAP03: Upstairs.,,,Ať tě nenapadne střílet ve městě. Spustil bys poplach a přivolal stráže z hradu.,"Bliv ikke skydeglad i byen. Du vil udløse alarmen, og de vil sende vagter fra slottet.","Fang nicht an, hier in der Stadt herumzuballern. Wenn du hier den Alarm auslöst, senden sie gleich die Truppen aus der Burg.",,Ne uzu pafilon en la urbo; vi ekagigus la alarmon kaj ili eksendus gardistojn el la kastelo.,"No te líes a tiros en el pueblo, que activarás la alarma y empezarán a enviar guardias desde el castillo.","No andes a los tiros en el pueblo, que vas a activar la alarma y van a empezar a mandar guardias desde el castillo.","Älä ala turhan liipaisinherkäksi kaupungilla. Aiheutat vielä hälytyksen, ja ne alkavat lähettää linnasta vartijoita.",Ne tirez pas partout en ville. Vous risquez de déclencher l'alarme et ils enverront tous les gardes du château à vos trousses.,"Ne keresd a bajt a városban. Beindítod a riasztót, és kiküldik érted a kastély őröket.",Non ti consiglio di avere il grilletto facile in città. Finiresti per attivare l'allarme e inizierebbero a mandare guardie dal castello.,"街の中で銃をバンバン撃ったりするんじゃないぞ 警報を鳴らしてしまえば、奴等が衛兵共を -城から送り込んでくるぞ。","아무 마을에서나 총을 갈겨대지 마세요. 알람을 울릴 거고, 성안에 있는 병력을 다 끄집어내서라도 당신을 잡을 테니까요.",Laat de trekker niet gelukkig worden in de stad. Je laat het alarm afgaan en ze sturen bewakers van het kasteel naar binnen.,"Ikke bli skyteglad i byen. Du utløser alarmen, og de vil sende inn vakter fra slottet.",Nie bądź taki impulsywny na mieście. Włączysz alarm i zaczną po ciebie wysyłać straże z zamku.,Não fique atirando por toda parte na cidade. Você vai ativar o alarme e eles mandarão os guardas do castelo.,,Nu deveni încântat să apeși pe trăgaci în oraș. Vor declanșa alarma și vor trimite gardieni din castel.,"Когда будешь в городе, не стреляй направо и налево. Если ты поднимешь тревогу, они вызовут подкрепление из замка.",,Kasabada tetiğe basma. Alarmı çalıştırırsın ve kaleden muhafızlar göndermeye başlarlar. -"Welcome, we can always use more help.",TXT_DLG_SCRIPT03_D40932_WELCO,MAP03: Near Macil.,,,"Vítej, pomoc se nám vždycky hodí.","Velkommen, vi kan altid bruge mere hjælp.","Willkommen, wir können immer etwas Hilfe gebrauchen.",,Bonvenon. Plia helpo ĉiam estas utilega.,"Bienvenido, siempre nos viene bien algo más de ayuda.",,Tervetuloa; voisimme aina kaivata lisää apua.,Bienvenue. Nous apprécions toute l'aide que nous pouvons recevoir.,"Üdv nálunk, mindig jól jön a segítség.","Benvenuto, ci serve tutto l'aiuto che possiamo ottenere.",ようこそ、我々が貴方の助けに成ります。,환영합니다. 당신 같은 사람들이 더 있었더라면...,"Welkom, we kunnen altijd meer hulp gebruiken.","Velkommen, vi kan alltid trenge mer hjelp.","Witaj, każda pomoc się przyda.",Seja bem-vindo. Qualquer ajuda é sempre bem-vinda.,,"Bun venit, mereu putem primi o mână de ajutor.",Добро пожаловать. Нам всегда пригодится помощь.,,"Hoş geldiniz, her zaman daha fazla yardıma ihtiyacımız olabilir." +城から送り込んでくるぞ。","아무 마을에서나 총을 갈겨대지 마세요. 알람을 울릴 거고, 성안에 있는 병력을 다 끄집어내서라도 당신을 잡을 테니까요.",Laat de trekker niet gelukkig worden in de stad. Je laat het alarm afgaan en ze sturen bewakers van het kasteel naar binnen.,"Ikke bli skyteglad i byen. Du utløser alarmen, og de vil sende inn vakter fra slottet.",Nie bądź taki impulsywny na mieście. Włączysz alarm i zaczną po ciebie wysyłać straże z zamku.,Não fique atirando por toda parte na cidade. Você vai ativar o alarme e eles mandarão os guardas do castelo.,,Nu deveni încântat să apeși pe trăgaci în oraș. Vor declanșa alarma și vor trimite gardieni din castel.,"Когда будешь в городе, не стреляй направо и налево. Если ты поднимешь тревогу, они вызовут подкрепление из замка.",,Bli inte skjutglad i stan. Du kommer att utlösa larmet och de kommer att skicka in vakter från slottet.,Kasabada tetiğe basma. Alarmı çalıştırırsın ve kaleden muhafızlar göndermeye başlarlar. +"Welcome, we can always use more help.",TXT_DLG_SCRIPT03_D40932_WELCO,MAP03: Near Macil.,,,"Vítej, pomoc se nám vždycky hodí.","Velkommen, vi kan altid bruge mere hjælp.","Willkommen, wir können immer etwas Hilfe gebrauchen.",,Bonvenon. Plia helpo ĉiam estas utilega.,"Bienvenido, siempre nos viene bien algo más de ayuda.",,Tervetuloa; voisimme aina kaivata lisää apua.,Bienvenue. Nous apprécions toute l'aide que nous pouvons recevoir.,"Üdv nálunk, mindig jól jön a segítség.","Benvenuto, ci serve tutto l'aiuto che possiamo ottenere.",ようこそ、我々が貴方の助けに成ります。,환영합니다. 당신 같은 사람들이 더 있었더라면...,"Welkom, we kunnen altijd meer hulp gebruiken.","Velkommen, vi kan alltid trenge mer hjelp.","Witaj, każda pomoc się przyda.",Seja bem-vindo. Qualquer ajuda é sempre bem-vinda.,,"Bun venit, mereu putem primi o mână de ajutor.",Добро пожаловать. Нам всегда пригодится помощь.,,"Välkommen, vi kan alltid behöva mer hjälp.","Hoş geldiniz, her zaman daha fazla yardıma ihtiyacımız olabilir." "When I was still in action we had the chance to examine an acolyte before the reinforcements arrived. Listen, they're not human.",TXT_DLG_SCRIPT03_D42448_WHENI,〃,,,"Když jsem byl ještě v akci, měli jsme možnost prozkoumat mrtvého akolytu předtím, než přišly posily. Poslyš, nejsou to lidé.","Da jeg stadig var i aktion, havde vi mulighed for at undersøge en akolyt, inden forstærkningerne ankom. Hør, de er ikke menneskelige.","Als ich noch aktiv war, hatten wir mal die Möglichkeit, einen der Ministranten zu untersuchen, bevor Verstärkung eintraf. Hör zu, sie sind nicht menschlich!",,"Kiam mi ankoraŭ estis en misio, ni havis okazon ekzameni akoliton antaŭ ol pliaj malamikoj alvenis. Aŭskultu, ili ne estas homoj.","Cuando aún estaba en acción tuvimos la oportunidad de examinar a un acólito antes de que llegaran los refuerzos. Escucha, no son humanos.",,"Kun itse olin vielä mukana taistelemassa, saimme tilaisuuden tutkia akoluuttia ennen lisäjoukkojen saapumista. Ja kuule tarkkaan, ne eivät ole ihmisiä.","Quand j'étais encore en service, j'ai eu l'opportunité d'examiner un acolyte avant que les renforts n'arrivent. Vous savez, ils ne sont pas humains.","A harc után volt alkalmunk megvizsgálni egy oltárszolgát még mielőtt megjelent volna az erősítés. Esküszöm, hogy ezek nem emberek.","Quando ero ancora sul campo di battaglia, abbiamo avuto l'occasione di esaminare uno degli accoliti prima che arrivassero i rinforzi. Ascoltami, non sono umani.","私がまだ活動していた時、我々が増援に 囲まれる前にアコライトを調べる機会が あったんだ。聞いてくれ、奴等は人間では -なかったんだ。","제가 임무 수행 중이었을 때, 생포한 아콜라이트들을 조사한 적이 있었어요. 요점은, 그 들은 인간이 절대로 아닙니다.","Toen ik nog in actie was hadden we de kans om een acoliet te onderzoeken voordat de versterkingen kwamen. Luister, ze zijn niet menselijk.","Da jeg fortsatt var i tjeneste, fikk vi sjansen til å undersøke en akolytt før forsterkningene kom. Hør her, de er ikke mennesker.","Kiedy byłem jeszcze na chodzie, mieliśmy szansę się przyjrzeć akolitom zanim wezwano posiłki. Słuchaj, to nie są ludzie.","Quando eu estava na ativa, tivemos a oportunidade de examinar um acólito antes dos reforços chegarem. Ouça bem, eles não são humanos.",,"Când încă eram în acțiune am avut șansa de a examina un acolit până să apară întăririle. Ascultă, nu sunt oameni.","Пока я был в оперативной группе, нам удалось изучить одного из служителей, прежде чем прибыло подкрепление. Так вот, они не люди.",,"Ben hala görevdeyken, takviye birlikler gelmeden önce bir yardımcı inceleme şansımız oldu. Dinle, onlar insan değil." +なかったんだ。","제가 임무 수행 중이었을 때, 생포한 아콜라이트들을 조사한 적이 있었어요. 요점은, 그 들은 인간이 절대로 아닙니다.","Toen ik nog in actie was hadden we de kans om een acoliet te onderzoeken voordat de versterkingen kwamen. Luister, ze zijn niet menselijk.","Da jeg fortsatt var i tjeneste, fikk vi sjansen til å undersøke en akolytt før forsterkningene kom. Hør her, de er ikke mennesker.","Kiedy byłem jeszcze na chodzie, mieliśmy szansę się przyjrzeć akolitom zanim wezwano posiłki. Słuchaj, to nie są ludzie.","Quando eu estava na ativa, tivemos a oportunidade de examinar um acólito antes dos reforços chegarem. Ouça bem, eles não são humanos.",,"Când încă eram în acțiune am avut șansa de a examina un acolit până să apară întăririle. Ascultă, nu sunt oameni.","Пока я был в оперативной группе, нам удалось изучить одного из служителей, прежде чем прибыло подкрепление. Так вот, они не люди.",,"När jag fortfarande var i aktion hade vi chansen att undersöka en akolyt innan förstärkningarna kom. Lyssna, de är inte mänskliga.","Ben hala görevdeyken, takviye birlikler gelmeden önce bir yardımcı inceleme şansımız oldu. Dinle, onlar insan değil." "We're trying to find where the castle gate mechanisms are, but so far we've had no luck.",TXT_DLG_SCRIPT03_D43964_WERET,MAP03: Downstairs.,,,"Snažíme se zjistit, kde jsou mechanismy hradní brány, ale zatím jsme nic nenašli.","Vi prøver at finde ud af hvor slottets portmekanismer er, men indtil videre har vi ikke haft held.","Wir versuchen herauszufinden, von wo das Burgtor kontrolliert wird, aber bisher hatten wir kein Glück.",,"Ni provas malkovri, kie troviĝas la mekanismoj de la kastelpordo, sed ni ankoraŭ ne sukcesis.","Estamos intentando descubrir la ubicación de los mecanismos de la puerta del castillo, pero de momento no ha habido suerte.","Estamos tratando de descubrir la ubicación de los mecanismos de la puerta del castillo, pero por ahora no hubo suerte.","Yritämme löytää linnanportin koneistoa, mutta toistaiseksi laihoin tuloksin.","On essaie de trouver où se trouvent les contrôles de la porte du château, mais pour l'instant, on les a pas encore localisés.","Próbáljuk megtalálni a kastély kapu irányító mechanikáját, de eddig nem jártunk sikerrel.","Stiamo cercando di capire dove si trovano i meccanismi di apertura dell'entrata del castello, ma ancora niente.","我々は城門のメカニズムが何処にあるか -探し続けているが、あまり良い結果は出ていない","성의 정문이 어떻게 작동하는지, 어떻게 하면 열 수 있는지 연구를 했습니다만... 아직은 희망이 없어요.","We proberen te vinden waar de mechanismen van de kasteelpoort zich bevinden, maar tot nu toe hebben we geen geluk gehad.","Vi prøver å finne ut hvor slottets portmekanismer er, men så langt har vi ikke hatt noe hell.","Próbowaliśmy znaleźć mechanizm bramy zamku, ale nam się nie udało.","Estamos tentando localizar os mecanismos do portão do castelo, mas até agora não tivemos sorte.",,"Încercăm să găsim mecanismele castelului, dar până acum nu am avut noroc.","Мы ищем механизм управления воротами замка, но пока безуспешно.",,Kalenin kapı mekanizmalarının nerede olduğunu bulmaya çalışıyoruz ama şu ana kadar şansımız yaver gitmedi. +探し続けているが、あまり良い結果は出ていない","성의 정문이 어떻게 작동하는지, 어떻게 하면 열 수 있는지 연구를 했습니다만... 아직은 희망이 없어요.","We proberen te vinden waar de mechanismen van de kasteelpoort zich bevinden, maar tot nu toe hebben we geen geluk gehad.","Vi prøver å finne ut hvor slottets portmekanismer er, men så langt har vi ikke hatt noe hell.","Próbowaliśmy znaleźć mechanizm bramy zamku, ale nam się nie udało.","Estamos tentando localizar os mecanismos do portão do castelo, mas até agora não tivemos sorte.",,"Încercăm să găsim mecanismele castelului, dar până acum nu am avut noroc.","Мы ищем механизм управления воротами замка, но пока безуспешно.",,"Vi försöker ta reda på var slottets portmekanismer finns, men hittills har vi inte haft någon tur.",Kalenin kapı mekanizmalarının nerede olduğunu bulmaya çalışıyoruz ama şu ana kadar şansımız yaver gitmedi. Don't get caught. I've heard horror stories about what they do to our people after they're imprisoned. They just disappear... Without a trace.,TXT_DLG_SCRIPT03_D45480_DONTG,〃,,,"Nenech se chytit. Slyšel jsem děsivé příběhy o tom, co dělají našim lidem, když je uvězní. Prostě zmizí... beze stopy.","Bliv ikke fanget. Jeg har hørt skrækhistorier om, hvad de gør ved vores folk, når de er blevet fængslet. De forsvinder bare... Uden et spor.","Lass dich nicht erwischen. Ich habe Horrorgeschichten darüber gehört, was sie unseren Leuten antun, die sie gefangengenommen haben. Sie verschwinden einfach... ohne jede Spur.",,"Oni ne kaptu vin. Mi aŭdis terurajn historiojn pri tio, kio okazas al niaj homoj post ilia aresto: ili simple malaperas sen lasi nenian restaĵon.",Que no te atrapen. He oído historias terroríficas de lo que hacen con nuestros hombres una vez detenidos: simplemente desaparecen sin dejar rastro alguno.,,"Älä jää kiinni. Olen kuullut kauhukertomuksia siitä, mitä ne tekevät meidän omillemme, kun he jäävät vangiksi. He yksinkertaisesti katoavat, jälkeä jättämättä.",Ne vous faites pas avoir. J'ai entendu des choses horribles sur ce qu'ils font à ceux qu'ils emprisonnent. Ils disparaîssent... Sans laisser de trace.,Csak ne fogasd el magad. Hallottam horror történténeteket azokról akiket mégis elfognak. Csak úgy eltünnek...mindenféle nyom nélkül.,Non farti prendere. Ho sentito storie orribili su quello che fanno alle persone dopo che le catturano. Spariscono... senza traccia.,"決して捕まるな。投獄されると奴等が 何をしでかすか怪談として聞く程だ。 -跡形もなく...消される。",절대로 붙잡히지 마세요. 그 녀석들이 수감된 사람들에게 한 일에 대한 무서운 이야기를 들었어요. 흔적도 없이 그냥 사라져 버린 겁니다.,Laat je niet vangen. Ik heb horrorverhalen gehoord over wat ze onze mensen na hun gevangenschap aandoen. Ze verdwijnen gewoon.... Zonder een spoor.,Ikke bli tatt. Jeg har hørt skrekkhistorier om hva de gjør med folket vårt etter at de blir fengslet. De bare forsvinner... Sporløst.,"Nie daj się złapać. Słyszałem straszne historie co robią naszym ludziom, kiedy ich złapią. Oni po prostu znikają... Bez śladu.",Não deixe eles te pegarem. Ouvi histórias de terror sobre o que eles fazem com o nosso pessoal depois que são aprisionados. Eles desaparecem... sem deixar rastros.,,Să nu te prindă. Am auzit povești de groază despre ce le fac oamenilor în închisoare. Dispar pur și simplu... fără nicio urmă.,"Не дай себя схватить. Я слышал ужасные истории о том, что они делают с арестованными. Те просто исчезают... без следа.",,Sakın yakalanmayın. Hapsedildikten sonra insanlarımıza ne yaptıklarına dair korku hikayeleri duydum. Öylece ortadan kayboluyorlar. İz bırakmadan. +跡形もなく...消される。",절대로 붙잡히지 마세요. 그 녀석들이 수감된 사람들에게 한 일에 대한 무서운 이야기를 들었어요. 흔적도 없이 그냥 사라져 버린 겁니다.,Laat je niet vangen. Ik heb horrorverhalen gehoord over wat ze onze mensen na hun gevangenschap aandoen. Ze verdwijnen gewoon.... Zonder een spoor.,Ikke bli tatt. Jeg har hørt skrekkhistorier om hva de gjør med folket vårt etter at de blir fengslet. De bare forsvinner... Sporløst.,"Nie daj się złapać. Słyszałem straszne historie co robią naszym ludziom, kiedy ich złapią. Oni po prostu znikają... Bez śladu.",Não deixe eles te pegarem. Ouvi histórias de terror sobre o que eles fazem com o nosso pessoal depois que são aprisionados. Eles desaparecem... sem deixar rastros.,,Să nu te prindă. Am auzit povești de groază despre ce le fac oamenilor în închisoare. Dispar pur și simplu... fără nicio urmă.,"Не дай себя схватить. Я слышал ужасные истории о том, что они делают с арестованными. Те просто исчезают... без следа.",,Bli inte fångade. Jag har hört skräckhistorier om vad de gör med vårt folk efter att de blivit fängslade. De bara försvinner... Utan ett spår.,Sakın yakalanmayın. Hapsedildikten sonra insanlarımıza ne yaptıklarına dair korku hikayeleri duydum. Öylece ortadan kayboluyorlar. İz bırakmadan. "Here's some advice, if you ever see any of the Order's Tinsoldiers go in the other direction. They're fast and brutal.",TXT_DLG_SCRIPT03_D46996_HERES,〃,,,"Dám ti radu: Jestli někdy uvidíš jednoho z plecháčků Řádu, otoč se a utíkej. Jsou rychlí a suroví.",Her er et godt råd: Hvis du nogensinde ser nogen af Ordenens Tinsoldater gå i den anden retning. De er hurtige og brutale.,"Hier ist ein guter Rat, falls du jemals einen dieser Zinnsoldaten des Ordens vorbeigehen siehst. Sie sind schnell und brutal. ",,Jen konsilo: estu ĉiam fore de la artefaritaj soldatoj de La Ordono. Ili estas rapidaj kaj brutalaj.,Un consejo: mantente siempre alejado de los soldados artificiales de La Orden. Son rápidos y brutales.,,"Annan pienen vinkin: Jos koskaan näet Veljeskunnan tinasotilaita, mene toiseen suuntaan. Ne ovat nopeita ja raakoja.","Voilà un conseil. Si vous voyez un des soldats mécanisés de l'Ordre, retournez vous et courez. Ils sont rapides et brutaux.","Az a tanácsom számodra, hogy ha meglátod a Rend ólomkatonáit, vedd az utad az ellentétes irányba. Gyorsak és brutálisak.","Ecco un consiglio. Se vedi uno dei soldatini di latta dell'Ordine, vai nella direzione opposta. Sono veloci e brutali.","伝えておく、オーダーの錫兵は 他方から呼び出され押し寄せてくる。 -奴等は素早く残忍だ。","조언 하나 하겠습니다. 만약 오더 출신의 깡통로봇들이 당신에게 향하고 있다면, 얼른 피하세요. 그놈들은 훨씬 무섭고 잔혹합니다.","Hier is een advies, als je ooit een van de Tinsoldiers van de Orde de andere kant op ziet gaan. Ze zijn snel en wreed.","Her er noen råd, hvis du noen gang ser noen av Ordenens Tinsoldater gå i den andre retningen. De er raske og brutale.","Dam ci radę. Jeśli zobaczysz jakiegokolwiek Blaszanego Żołnierza Zakonu, idź w przeciwnym kierunku. Są szybcy i brutalni.","Tenho um conselho pra você. Se você ver algum soldadinho da Ordem, vá para outra direção. Eles são rápidos e brutais.",,Uite un sfat: Dacă vezi vreun soldat din staniu du-te în direcția opusă. Sunt rapizi și brutali.,"Небольшой совет: если увидишь «оловянных солдатиков» Ордена, сворачивай в другую сторону. Они быстры и жестоки.",,"İşte size bir tavsiye, eğer Tarikat'ın teneke askerlerinden birini görürseniz diğer yöne gidin. Hızlı ve acımasızdırlar." +奴等は素早く残忍だ。","조언 하나 하겠습니다. 만약 오더 출신의 깡통로봇들이 당신에게 향하고 있다면, 얼른 피하세요. 그놈들은 훨씬 무섭고 잔혹합니다.","Hier is een advies, als je ooit een van de Tinsoldiers van de Orde de andere kant op ziet gaan. Ze zijn snel en wreed.","Her er noen råd, hvis du noen gang ser noen av Ordenens Tinsoldater gå i den andre retningen. De er raske og brutale.","Dam ci radę. Jeśli zobaczysz jakiegokolwiek Blaszanego Żołnierza Zakonu, idź w przeciwnym kierunku. Są szybcy i brutalni.","Tenho um conselho pra você. Se você ver algum soldadinho da Ordem, vá para outra direção. Eles são rápidos e brutais.",,Uite un sfat: Dacă vezi vreun soldat din staniu du-te în direcția opusă. Sunt rapizi și brutali.,"Небольшой совет: если увидишь «оловянных солдатиков» Ордена, сворачивай в другую сторону. Они быстры и жестоки.",,"Här är ett råd, om du någonsin ser någon av Ordens Tinsoldater gå åt andra hållet. De är snabba och brutala.","İşte size bir tavsiye, eğer Tarikat'ın teneke askerlerinden birini görürseniz diğer yöne gidin. Hızlı ve acımasızdırlar." Leave me be. I'm doing something for Macil.,TXT_DLG_SCRIPT03_D48512_LEAVE,〃,,,"Teď mě nech, dělám něco pro Macila.",Lad mig være. Jeg gør noget for Macil.,Lass mich in Ruhe. Ich muss etwas für Macil erledigen.,,Lasu min. Mi faras ion por Macil.,"Déjame, que estoy haciendo algo para Macil.",,Anna minun olla. Palvelen parhaillani Macilia.,Laissez moi. Je suis en train de faire quelque chose pour Macil.,Hagyj békén. Épp macil számára csinálok valamit.,"Ora non ho tempo, sto sbrigando un incarico per Macil.","すまないが忙しい。 私はマシルの雑用を請け負っている。",방해하지 마세요. 사령관님을 위해 중요한 일을 하고 있으니.,Laat me met rust. Ik doe iets voor Macil.,La meg være i fred. Jeg gjør noe for Macil.,Zostaw mnie. Robię coś dla Macila.,Me deixe em paz. Estou fazendo algo pro Macil.,,Lasă-mă. Fac ceva pentru Macil.,"Не отвлекай меня. Я выполняю поручение Мэйсила. -",,Beni rahat bırak. Macil için bir şey yapıyorum. -"Sorry, no. You do not have clearance.",TXT_DLG_SCRIPT04_D0_SORRY,MAP04: Reactor Core red guard.,,,"Pardon, ne. Sem nemůžete.","Beklager, nej. Du har ikke tilladelse.","Tut mir leid, aber Sie haben keine Berechtigung.",,"Pardonon, sed ne, vi ne rajtas eniri.","Lo siento, pero no, no tienes permiso.",,"Anteeksi, ei. Sinulla ei ole kulkulupaa.","Non, désolé. Vous n'avez pas d'autorisation.",Sajnálom de nem. Nincs hozzá jogosultságod.,"Mi spiace, ma non hai l'autorizzazione.",すまないが、お前にクリアランスはない。,"유감이지만, 신분 휘장 없이는 보내줄 수 없어.","Sorry, nee. Je hebt geen toestemming.","Beklager, nei. Du har ikke klarering.","Wybacz, ale nie. Nie masz zezwolenia.",Desculpe mas não. Você não tem permissão.,,"Scuze, nu. Nu ai acces.","Увы, нет. У тебя нет пропуска.",,"Üzgünüm, olmaz. Yetkiniz yok." -Stop! Show me your ID badge.,TXT_DLG_SCRIPT04_D1516_STOPS,〃,,,Stát! Ukažte mi svůj identifikační průkaz.,Stop! Vis mig dit ID-skilt.,Halt. Zeigen Sie mir Ihre Identitätskarte.,,Haltu! Montru vian identigilon de la centralo.,¡Alto! Muéstrame tu identificación de la central.,,Seis! Näytä minulle henkilötunnisteesi.,Stop! Montrez moi votre carte d'identité.,Állj! Mutasd az igazolványod.,Fermo! Mostrami il tesserino d'identificazione.,待て! IDバッジを見せろ。,멈춰라! 너의 신분 휘장을 보여줘.,Stop! Laat me je ID-badge zien.,Stopp! Vis meg ID-kortet ditt.,Stój! Pokaż mi swoją odznakę identyfikacyjną.,Alto! Mostre a sua identificação.,,Stop! Arată-mi cardul de identitate.,Стой! Покажи мне своё удостоверение.,,Dur! Bana kimliğini göster. -Here's my I.D.,TXT_RPLY0_SCRIPT04_D1516_HERES,〃,,,Tady je moje průkazka.,Her er mit id-kort.,Hier ist sie.,,Jen la identigilo.,Aquí está mi identificación.,,Tässä.,La voilà.,Itt az igazolványom.,Eccolo qua.,これだ。,"여기, 휘장.",Hier is mijn ID.,Her er legitimasjonen min.,Oto ona.,Aqui está ela.,,Aici e cardul.,Вот оно.,,İşte kimliğim. -"Oh, ok. Sure go ahead. Have a nice day.",TXT_DLG_SCRIPT04_D3032_OHOKS,〃,,,"Aha, dobře. Jistě, jděte dál. Přeji hezký den.","Åh, okay. Selvfølgelig, værsgo. Hav en god dag.","Alles klar, ich wünsche einen schönen Tag.",,"Ha, bone. Kompreneble, eniru. Havu bonan tagon.","Ah, vale. Claro, adelante. Ten un buen día.","Ah, bueno. Claro, adelante. Ten un buen día.","Aa, hyvä. Selvä, voit mennä. Hyvää päivänjatkoa.","Bon, ok. Allez-y. Passez une bonne journée.","Oh, rendben. Mehetsz is tovább. További szép napot.","Ah, va bene. Vai pure avanti. Buona giornata.",あぁ、宜しい。通れ。良い一日を。,"오, 정말이네. 환영한다. 좋은 하루 보내고.","Oh, oké. Ga je gang. Nog een prettige dag.","Å, ok. Vær så god. Ha en fin dag.","Oh, ok. Proszę, wchodź. Miłego dnia.","Ah, ok. Pode passar. Tenha um bom dia.",,"Ah, în regulă. Mergi mai departe. O zi bună.","Ладно, проходи. Всего доброго.",,"Oh, tamam. Tabii, devam edin. İyi günler dilerim." +",,Låt mig vara. Jag gör något för Macil.,Beni rahat bırak. Macil için bir şey yapıyorum. +"Sorry, no. You do not have clearance.",TXT_DLG_SCRIPT04_D0_SORRY,MAP04: Reactor Core red guard.,,,"Pardon, ne. Sem nemůžete.","Beklager, nej. Du har ikke tilladelse.","Tut mir leid, aber Sie haben keine Berechtigung.",,"Pardonon, sed ne, vi ne rajtas eniri.","Lo siento, pero no, no tienes permiso.",,"Anteeksi, ei. Sinulla ei ole kulkulupaa.","Non, désolé. Vous n'avez pas d'autorisation.",Sajnálom de nem. Nincs hozzá jogosultságod.,"Mi spiace, ma non hai l'autorizzazione.",すまないが、お前にクリアランスはない。,"유감이지만, 신분 휘장 없이는 보내줄 수 없어.","Sorry, nee. Je hebt geen toestemming.","Beklager, nei. Du har ikke klarering.","Wybacz, ale nie. Nie masz zezwolenia.",Desculpe mas não. Você não tem permissão.,,"Scuze, nu. Nu ai acces.","Увы, нет. У тебя нет пропуска.",,"Tyvärr, nej. Du har inget tillstånd.","Üzgünüm, olmaz. Yetkiniz yok." +Stop! Show me your ID badge.,TXT_DLG_SCRIPT04_D1516_STOPS,〃,,,Stát! Ukažte mi svůj identifikační průkaz.,Stop! Vis mig dit ID-skilt.,Halt. Zeigen Sie mir Ihre Identitätskarte.,,Haltu! Montru vian identigilon de la centralo.,¡Alto! Muéstrame tu identificación de la central.,,Seis! Näytä minulle henkilötunnisteesi.,Stop! Montrez moi votre carte d'identité.,Állj! Mutasd az igazolványod.,Fermo! Mostrami il tesserino d'identificazione.,待て! IDバッジを見せろ。,멈춰라! 너의 신분 휘장을 보여줘.,Stop! Laat me je ID-badge zien.,Stopp! Vis meg ID-kortet ditt.,Stój! Pokaż mi swoją odznakę identyfikacyjną.,Alto! Mostre a sua identificação.,,Stop! Arată-mi cardul de identitate.,Стой! Покажи мне своё удостоверение.,,Stopp! Visa mig din ID-bricka.,Dur! Bana kimliğini göster. +Here's my I.D.,TXT_RPLY0_SCRIPT04_D1516_HERES,〃,,,Tady je moje průkazka.,Her er mit id-kort.,Hier ist sie.,,Jen la identigilo.,Aquí está mi identificación.,,Tässä.,La voilà.,Itt az igazolványom.,Eccolo qua.,これだ。,"여기, 휘장.",Hier is mijn ID.,Her er legitimasjonen min.,Oto ona.,Aqui está ela.,,Aici e cardul.,Вот оно.,,Här är mitt ID-kort.,İşte kimliğim. +"Oh, ok. Sure go ahead. Have a nice day.",TXT_DLG_SCRIPT04_D3032_OHOKS,〃,,,"Aha, dobře. Jistě, jděte dál. Přeji hezký den.","Åh, okay. Selvfølgelig, værsgo. Hav en god dag.","Alles klar, ich wünsche einen schönen Tag.",,"Ha, bone. Kompreneble, eniru. Havu bonan tagon.","Ah, vale. Claro, adelante. Ten un buen día.","Ah, bueno. Claro, adelante. Ten un buen día.","Aa, hyvä. Selvä, voit mennä. Hyvää päivänjatkoa.","Bon, ok. Allez-y. Passez une bonne journée.","Oh, rendben. Mehetsz is tovább. További szép napot.","Ah, va bene. Vai pure avanti. Buona giornata.",あぁ、宜しい。通れ。良い一日を。,"오, 정말이네. 환영한다. 좋은 하루 보내고.","Oh, oké. Ga je gang. Nog een prettige dag.","Å, ok. Vær så god. Ha en fin dag.","Oh, ok. Proszę, wchodź. Miłego dnia.","Ah, ok. Pode passar. Tenha um bom dia.",,"Ah, în regulă. Mergi mai departe. O zi bună.","Ладно, проходи. Всего доброго.",,"Åh, okej. Visst, fortsätt. Ha en trevlig dag.","Oh, tamam. Tabii, devam edin. İyi günler dilerim." "Derwin? Yeah, he's down in the warehouse, but you're not getting in unless you're cleared.",TXT_DLG_SCRIPT04_D4548_DERWI,MAP04: Warehouse red guard.,,,"Derwin? Jo, ten je dole ve skladu, ale ty nikam nejdeš jestliže nemáš povolení.","Derwin? Ja, han er nede i lageret, men du kommer ikke ind, medmindre du er godkendt.","Derwin? Ja, der ist unten im Lagerhaus, aber da kommst du nicht rein ohne Berechtigung.",,"Ĉu Derwin? Jes, li estas en la magazeno en la malsupra etaĝo, sed vi ne rajtas iri tien, krom se vi havas paspermeson.","¿Derwin? Sí, está abajo en el almacén, pero no puedes entrar a menos que tengas permiso.",,"Derwin? Joo, hän on varastolla, muttet pääse sisään ilman kulkulupaa.","Derwin? Ouais, il est dans l'entrepôt. Vous ne pouvez pas y entrer sans autorisation.","Derwin? Igen, Ő épp a raktárban van, de jogosultság nélkül nem jutsz be oda.","Derwin? Sì, è giù nel magazzino, ma non puoi entrare senza autorizzazione.","ダーウィン? ああ、奴はこの倉庫内にいるが、 -片付かない限りお前は入れん。",더윈? 녀석은 저 창고 밑에 있다. 그러나 허가 없이는 못 보내준다.,"Derwin? Ja, hij is in het magazijn, maar je komt er niet in tenzij je vrij bent.","Derwin? Ja, han er nede på lageret, men du kommer ikke inn med mindre du er klarert.","Derwin? Tak, jest w magazynie, ale tam nie wejdziesz bez zgody.","Derwin? Sim, ele está lá embaixo no depósito, mas você não pode entrar enquanto não tiver permissão.",,"Darwin? Da, e în depozit, dar nu intri înăuntru dacă nu ai acces.","Дервин? Да, он внизу, на складе, но тебя туда не пустят, если у тебя нет пропуска.",,"Derwin? Evet, depoda ama izin almadan içeri giremezsin." -I've got clearance.,TXT_RPLY0_SCRIPT04_D4548_IVEGO,〃,,,Mám povolení.,Jeg har fået tilladelse.,Ich habe eine Berechtigung.,,Mi havas ĝin.,Tengo permiso.,,Minulla on lupa.,J'ai une autorisation.,Van jogosultságom.,Ce l'ho l'autorizzazione.,クリアランスはある。,허가를 받았어.,Ik heb toestemming.,Jeg har klarering.,Mam zezwolenie.,Eu tenho permissão.,,Am acces.,У меня есть пропуск.,,İznim var. -Go on.,TXT_DLG_SCRIPT04_D6064_GOON,〃,,,Tak jdi.,Jeg har tilladelse.,Alles klar.,,Tiuokaze daŭrigu.,Entonces ve.,,Jatkakaa.,Allez-y.,Mesélj csak.,Va pure.,続けろ。,그럼 가도 좋다.,Ga door.,Jeg har klarering.,Wchodź.,Pode passar.,,Intră.,Проходи.,,Devam et. -Do you know where he is?,TXT_RPLY0_SCRIPT04_D6064_DOYOU,〃,,,"Nevíš, kde je?","Ved du, hvor han er?","Weißt du, wo er ist?",,"Ĉu vi scias, kie li estas?",¿Sabes dónde está?,,"Tiedätkö, missä hän on?",Vous savez où il est?,Tudod hol találom meg?,Sai dov'è?,ソイツが何処にいるか知っているか?,그가 어디 있는지 아는가?,Weet je waar hij is?,Vet du hvor han er?,Wiesz gdzie on jest?,Você sabe onde ele está?,,Știi unde e?,"Вы знаете, где Дервин?",,Nerede olduğunu biliyor musun? +片付かない限りお前は入れん。",더윈? 녀석은 저 창고 밑에 있다. 그러나 허가 없이는 못 보내준다.,"Derwin? Ja, hij is in het magazijn, maar je komt er niet in tenzij je vrij bent.","Derwin? Ja, han er nede på lageret, men du kommer ikke inn med mindre du er klarert.","Derwin? Tak, jest w magazynie, ale tam nie wejdziesz bez zgody.","Derwin? Sim, ele está lá embaixo no depósito, mas você não pode entrar enquanto não tiver permissão.",,"Darwin? Da, e în depozit, dar nu intri înăuntru dacă nu ai acces.","Дервин? Да, он внизу, на складе, но тебя туда не пустят, если у тебя нет пропуска.",,"Derwin? Ja, han är nere i lagret, men du kommer inte in om du inte har fått tillstånd.","Derwin? Evet, depoda ama izin almadan içeri giremezsin." +I've got clearance.,TXT_RPLY0_SCRIPT04_D4548_IVEGO,〃,,,Mám povolení.,Jeg har fået tilladelse.,Ich habe eine Berechtigung.,,Mi havas ĝin.,Tengo permiso.,,Minulla on lupa.,J'ai une autorisation.,Van jogosultságom.,Ce l'ho l'autorizzazione.,クリアランスはある。,허가를 받았어.,Ik heb toestemming.,Jeg har klarering.,Mam zezwolenie.,Eu tenho permissão.,,Am acces.,У меня есть пропуск.,,Jag har tillstånd.,İznim var. +Go on.,TXT_DLG_SCRIPT04_D6064_GOON,〃,,,Tak jdi.,Jeg har tilladelse.,Alles klar.,,Tiuokaze daŭrigu.,Entonces ve.,,Jatkakaa.,Allez-y.,Mesélj csak.,Va pure.,続けろ。,그럼 가도 좋다.,Ga door.,Jeg har klarering.,Wchodź.,Pode passar.,,Intră.,Проходи.,,Fortsätt.,Devam et. +Do you know where he is?,TXT_RPLY0_SCRIPT04_D6064_DOYOU,〃,,,"Nevíš, kde je?","Ved du, hvor han er?","Weißt du, wo er ist?",,"Ĉu vi scias, kie li estas?",¿Sabes dónde está?,,"Tiedätkö, missä hän on?",Vous savez où il est?,Tudod hol találom meg?,Sai dov'è?,ソイツが何処にいるか知っているか?,그가 어디 있는지 아는가?,Weet je waar hij is?,Vet du hvor han er?,Wiesz gdzie on jest?,Você sabe onde ele está?,,Știi unde e?,"Вы знаете, где Дервин?",,Vet du var han är?,Nerede olduğunu biliyor musun? I don't know where anybody is. I just keep the lid on the rat trap.,TXT_DLG_SCRIPT04_D7580_IDONT,〃,,,Já nevím kde kdo je. Já jen dohlížím na pastičku na myši.,"Jeg ved ikke, hvor nogen er. Jeg holder bare låget på rottefælden.","Ich weiß von niemandem, wo er ist. Ich kümmere mich nur um die Rattenfalle.",,"Mi ne scias, kie iu ajn estas. Mi nur estas komisiito de la ŝtopiloj de ĉi tiu ratkaptilo.",No me sé la ubicación de nadie. Solo estoy a cargo de las tapas de esta ratonera.,,"En tiedä, missä kukaan on. Huolehdin vain rotanloukun kannesta.",Je ne sais pas où se trouve qui que ce soit. Je ne fais que garder le couvercle de ce trou à rats.,Ötletem sincs merre vannak az emberek. Én csak a patkány csapda tetejéért vagyok felelős.,Non so dove sia nessuno di quelli che stanno nel magazzino. A me interessa solo che non scappino.,"俺には何処にいるかは分からない。 -俺はただネズミ捕りにフタを被せているだけだ。",그가 정확히 어디 있는지는 모른다. 난 도망자를 그냥 감시할 뿐이다.,Ik weet niet waar iemand is. Ik hou gewoon het deksel op de rattenval.,Jeg vet ikke hvor noen er. Jeg holder bare lokket på rottefella.,Nie wiem gdzie kto jest. Ja tylko plinuję tej pułapki na szczury.,Não sei onde ninguém está. Apenas mantenho a tampa neste bueiro.,,"Nu știu unde e nimeni, eu doar țin ochii pe capcana pentru șoareci.","Ничего я не знаю. Я просто слежу, чтобы никто из них не сбежал из западни.",,Kimsenin nerede olduğunu bilmiyorum. Ben sadece fare kapanının kapağını tutuyorum. -You are an unpleasant distraction.,TXT_DLG_SCRIPT04_D9096_YOUAR,〃,,,Jsi nepříjemná otrava.,Du er en ubehagelig distraktion.,Du bist eine unerwünschte Ablenkung,,Vi estas malagrabla distraĵo.,Eres una distracción incómoda.,,Oletpa epämiellyttävä häiriötekijä.,Vous êtes une distraction déplaisante.,Egy kellemetlen zavaró tényező vagy.,Sei una sgradevole distazione.,お前は不快で目障りだ。,당신은 지금 내 감시일을 방해하고 있다.,Je bent een onaangename afleiding.,Du er en ubehagelig distraksjon.,Bardzo mnie rozpraszasz.,Você é uma distração bem incômoda.,,Ești o distragere neplăcută.,Ты — досадная помеха.,,Hoş olmayan bir dikkat dağıtıcısın. -Move along or taste metal.,TXT_DLG_SCRIPT04_D10612_MOVEA,MAP04: Reactor Core gray guard.,,,"Jdi dál, nebo okus ocel.",Gå videre eller smag på metal.,Beweg dich oder du schmeckst Metall.,,Plue movu vin aŭ gustumu metalon.,Muévete o prueba metal.,,"Ala vetää, tai maista metallia.",Circulez ou préparez vous à manger de l'acier.,"Haladj tovább, vagy ízleld meg a kardom.",Sparisci o ti finisce male.,同行か鉄を味わうかだ。,어서 움직여. 총알 먹기 싫으면.,Ga verder of proef metaal.,Gå videre eller smak på metall.,Odejdź stąd albo posmakujesz mojej pukawki.,Vá embora ou vai tomar chumbo grosso.,,Mșcă-te sau înghiți metal.,"Прочь, или отведаешь металла.",,İlerle yoksa metalin tadına bakarsın. -Pass your ID through here for access.,TXT_DLG_SCRIPT04_D12128_PASSY,,,,Pro přístup tady nahrajte svou legitimaci.,Giv dit ID her igennem for at få adgang.,Reichen Sie Ihre Identitätskarte hier durch!,,Ŝovu vian identigilon sur la legilon por eniri.,Pasa tu identificación por aquí para acceder.,,Vedä tunnisteesi tästä päästäksesi läpi.,Faites passer votre carte d'identité ici pour continuer.,Add le az igazolványod itt a belépéshez.,Mostra il tesserino per accedere.,彼方のI.D.をここに提示してください。,신분증을 보여줘. 입장하고 싶으면.,Geef je ID hier door voor toegang.,Før legitimasjonen din gjennom her for å få adgang.,"Pokaż tu swój identyfikator, aby otrzymać dostęp.",Passe a sua identificação por aqui para acessar.,,Trece cardul de acces pe aici.,"Покажи своё удостоверение, чтобы получить допуск.",,Giriş için kimliğinizi buradan geçirin. -"Get back to work, now!",TXT_DLG_SCRIPT04_D13644_GETBA,MAP04: Green guard.,,,"Vrať se do práce, hned!","Tilbage til arbejdet, nu!",Gehen Sie sofort zurück an die Arbeit!,,"Reiru al via laborposteno, tuje!","Vuelve al trabajo, ¡ahora!",,"No niin, takaisin töihisi!","Retournez au boulot, maintenant!",Nyomás vissza dolgozni!,Ora torna a lavoro!,仕事へ戻れ、今すぐ!,당장 일해. 어서.,"Ga terug aan het werk, nu!","Tilbake til arbeidet, nå!","Do roboty, już!","Volte ao trabalho, agora!",,"Treci înapoi la muncă, acum!",Немедленно за работу!,,"İşinizin başına dönün, hemen!" -"Get back to work, now!",TXT_DLG_SCRIPT04_D15160_GETBA,〃,,,"Vrať se do práce, hned!","Tilbage til arbejdet, nu!",Gehen Sie sofort zurück an die Arbeit!,,"Reiru al via laborposteno, tuje!","Vuelve al trabajo, ¡ahora!",,"No niin, takaisin töihisi!","Retournez au boulot, maintenant!",Nyomás vissza dolgozni!,Ora torna a lavoro!,今すぐ仕事へ戻れ!,쉬면 알지? 어서 일해.,"Ga terug aan het werk, nu!","Tilbake til arbeidet, nå!","Do roboty, już!","Volte ao trabalho, agora!",,"Treci înapoi la muncă, acum!",Немедленно за работу!,,"İşinizin başına dönün, hemen!" +俺はただネズミ捕りにフタを被せているだけだ。",그가 정확히 어디 있는지는 모른다. 난 도망자를 그냥 감시할 뿐이다.,Ik weet niet waar iemand is. Ik hou gewoon het deksel op de rattenval.,Jeg vet ikke hvor noen er. Jeg holder bare lokket på rottefella.,Nie wiem gdzie kto jest. Ja tylko plinuję tej pułapki na szczury.,Não sei onde ninguém está. Apenas mantenho a tampa neste bueiro.,,"Nu știu unde e nimeni, eu doar țin ochii pe capcana pentru șoareci.","Ничего я не знаю. Я просто слежу, чтобы никто из них не сбежал из западни.",,Jag vet inte var någon är. Jag håller bara locket på råttfällan.,Kimsenin nerede olduğunu bilmiyorum. Ben sadece fare kapanının kapağını tutuyorum. +You are an unpleasant distraction.,TXT_DLG_SCRIPT04_D9096_YOUAR,〃,,,Jsi nepříjemná otrava.,Du er en ubehagelig distraktion.,Du bist eine unerwünschte Ablenkung,,Vi estas malagrabla distraĵo.,Eres una distracción incómoda.,,Oletpa epämiellyttävä häiriötekijä.,Vous êtes une distraction déplaisante.,Egy kellemetlen zavaró tényező vagy.,Sei una sgradevole distazione.,お前は不快で目障りだ。,당신은 지금 내 감시일을 방해하고 있다.,Je bent een onaangename afleiding.,Du er en ubehagelig distraksjon.,Bardzo mnie rozpraszasz.,Você é uma distração bem incômoda.,,Ești o distragere neplăcută.,Ты — досадная помеха.,,Du är en obehaglig distraktion.,Hoş olmayan bir dikkat dağıtıcısın. +Move along or taste metal.,TXT_DLG_SCRIPT04_D10612_MOVEA,MAP04: Reactor Core gray guard.,,,"Jdi dál, nebo okus ocel.",Gå videre eller smag på metal.,Beweg dich oder du schmeckst Metall.,,Plue movu vin aŭ gustumu metalon.,Muévete o prueba metal.,,"Ala vetää, tai maista metallia.",Circulez ou préparez vous à manger de l'acier.,"Haladj tovább, vagy ízleld meg a kardom.",Sparisci o ti finisce male.,同行か鉄を味わうかだ。,어서 움직여. 총알 먹기 싫으면.,Ga verder of proef metaal.,Gå videre eller smak på metall.,Odejdź stąd albo posmakujesz mojej pukawki.,Vá embora ou vai tomar chumbo grosso.,,Mșcă-te sau înghiți metal.,"Прочь, или отведаешь металла.",,Gå vidare eller smaka på metall.,İlerle yoksa metalin tadına bakarsın. +Pass your ID through here for access.,TXT_DLG_SCRIPT04_D12128_PASSY,,,,Pro přístup tady nahrajte svou legitimaci.,Giv dit ID her igennem for at få adgang.,Reichen Sie Ihre Identitätskarte hier durch!,,Ŝovu vian identigilon sur la legilon por eniri.,Pasa tu identificación por aquí para acceder.,,Vedä tunnisteesi tästä päästäksesi läpi.,Faites passer votre carte d'identité ici pour continuer.,Add le az igazolványod itt a belépéshez.,Mostra il tesserino per accedere.,彼方のI.D.をここに提示してください。,신분증을 보여줘. 입장하고 싶으면.,Geef je ID hier door voor toegang.,Før legitimasjonen din gjennom her for å få adgang.,"Pokaż tu swój identyfikator, aby otrzymać dostęp.",Passe a sua identificação por aqui para acessar.,,Trece cardul de acces pe aici.,"Покажи своё удостоверение, чтобы получить допуск.",,Ge ditt ID-kort här för att få tillträde.,Giriş için kimliğinizi buradan geçirin. +"Get back to work, now!",TXT_DLG_SCRIPT04_D13644_GETBA,MAP04: Green guard.,,,"Vrať se do práce, hned!","Tilbage til arbejdet, nu!",Gehen Sie sofort zurück an die Arbeit!,,"Reiru al via laborposteno, tuje!","Vuelve al trabajo, ¡ahora!",,"No niin, takaisin töihisi!","Retournez au boulot, maintenant!",Nyomás vissza dolgozni!,Ora torna a lavoro!,仕事へ戻れ、今すぐ!,당장 일해. 어서.,"Ga terug aan het werk, nu!","Tilbake til arbeidet, nå!","Do roboty, już!","Volte ao trabalho, agora!",,"Treci înapoi la muncă, acum!",Немедленно за работу!,,"Tillbaka till arbetet, nu!","İşinizin başına dönün, hemen!" +"Get back to work, now!",TXT_DLG_SCRIPT04_D15160_GETBA,〃,,,"Vrať se do práce, hned!","Tilbage til arbejdet, nu!",Gehen Sie sofort zurück an die Arbeit!,,"Reiru al via laborposteno, tuje!","Vuelve al trabajo, ¡ahora!",,"No niin, takaisin töihisi!","Retournez au boulot, maintenant!",Nyomás vissza dolgozni!,Ora torna a lavoro!,今すぐ仕事へ戻れ!,쉬면 알지? 어서 일해.,"Ga terug aan het werk, nu!","Tilbake til arbeidet, nå!","Do roboty, już!","Volte ao trabalho, agora!",,"Treci înapoi la muncă, acum!",Немедленно за работу!,,"Tillbaka till arbetet, nu!","İşinizin başına dönün, hemen!" We've been running around the clock for weeks with no down time. I'd say that the Order is planning a suppression raid on the Front.,TXT_DLG_SCRIPT04_D16676_WEVEB,MAP04: Warehouse → Northeast (worker in red),,,"Celé týdny makáme bez přestávek. Řekl bych, že Řád má v plánu nějaký útok na Frontu.","Vi har kørt døgnet rundt i ugevis uden at have nogen pause. Jeg vil sige, at Ordenen planlægger et undertrykkelsesangreb på fronten.","Die Station hier läuft seit Wochen ohne Stillstand. Ich vermute mal, der Orden bereitet einen großen Schlag gegen die Front vor.",,"Ni senhalte laboras 24 horojn ĉiutage de antaŭ semajnoj. Mi dirus, ke La Ordono planas atakon por subpremi la Fronton.",Llevamos semanas trabajando 24 horas al día sin parar. Diría que La Orden está planeando una incursión para suprimir al Frente.,,"Olemme työskennelleet viikkoja kellon ympäri ilman silmällistäkään. Sanoisin, että Veljeskunta on suunnittelemassa ehkäisevää iskua Rintamaa vastaan.",J'ai fait le tour de l'horloge depuis des semaines sans temps de repos. Je pense que l'Ordre prépare un raid de suppression sur le Front.,"A nap minden órájában dolgoztunk szünet nélkül. Az a gyanúm, hogy a Rend sorsdöntő támadást akar indítani a Front ellen.",Stiamo lavorando senza sosta per settimane oramai. Secondo me l'Ordine sta preparando un nuovo attacco contro il Fronte.,"もう数週間も休日返上で働いているんだ。 オーダーがまたフロントを攻撃する準備を -しているんだろうな。","일주일 동안 쉬지도 않고 일하느라 정신이 날아갈 것 같아요... 아무튼, 오더가 프론트 저항군을 제압할 작전을 준비한다는군요.","We rennen al weken rond de klok, zonder uitvaltijd. Ik zou zeggen dat de Orde een onderdrukkingsinval aan de voorkant plant.",Vi har kjørt døgnet rundt i ukevis uten pause. Jeg vil si at Ordenen planlegger et undertrykkelsesangrep på Fronten.,"Od kilku tygodni pracujemy przez całą dobę bez przerwy. Powiedziałbym, że Zakon planuje zniszczyć Front.",Estamos trabalhando noite e dia por semanas sem descanso. Eu diria que a Ordem está planjeando um ataque para suprimir a Frente.,,Muncim non-stop de săptămăni fără niciun fel de pauză. Aș zice că Ordinul plănuiește un atac de reprimare asupra Frontului.,"Мы работаем круглые сутки без перерыва уже несколько недель. Мне кажется, Орден готовит решительный рейд, чтобы окончательно покончить с Сопротивлением.",,Haftalardır hiç ara vermeden gece gündüz çalışıyoruz. Tarikat'ın Cephe'ye bir baskın planladığını söyleyebilirim. +しているんだろうな。","일주일 동안 쉬지도 않고 일하느라 정신이 날아갈 것 같아요... 아무튼, 오더가 프론트 저항군을 제압할 작전을 준비한다는군요.","We rennen al weken rond de klok, zonder uitvaltijd. Ik zou zeggen dat de Orde een onderdrukkingsinval aan de voorkant plant.",Vi har kjørt døgnet rundt i ukevis uten pause. Jeg vil si at Ordenen planlegger et undertrykkelsesangrep på Fronten.,"Od kilku tygodni pracujemy przez całą dobę bez przerwy. Powiedziałbym, że Zakon planuje zniszczyć Front.",Estamos trabalhando noite e dia por semanas sem descanso. Eu diria que a Ordem está planjeando um ataque para suprimir a Frente.,,Muncim non-stop de săptămăni fără niciun fel de pauză. Aș zice că Ordinul plănuiește un atac de reprimare asupra Frontului.,"Мы работаем круглые сутки без перерыва уже несколько недель. Мне кажется, Орден готовит решительный рейд, чтобы окончательно покончить с Сопротивлением.",,Vi har kört dygnet runt i flera veckor utan några avbrott. Jag skulle säga att Orden planerar en attack mot fronten.,Haftalardır hiç ara vermeden gece gündüz çalışıyoruz. Tarikat'ın Cephe'ye bir baskın planladığını söyleyebilirim. "Oh, damn. The governor sent you. I was going to give him his cut, really I was. OK, listen. I've got a bundle stashed. It's yours if you look the other way.",TXT_DLG_SCRIPT04_D18192_OHDAM,MAP04: Derwin.,,,"A sakra. Guvernér tě poslal. Měl jsem v plánu dát mu jeho podíl, opravdu. Dobře, poslouchej. Mám schované nějaké zlaťáky, můžou být tvoje, když přimhouříš oko.","Åh, for pokker. Guvernøren har sendt dig. Jeg ville give ham sin andel, det ville jeg virkelig. Okay, hør her. Jeg har en bunke gemt. Det er dit, hvis du ser den anden vej.","Verdammt, der Gouverneur hat dich geschickt. Ich wollte ihm seinen Anteil geben - wirklich ich wollte das. Hör zu, ich habe hier was zur Seite geschafft, es gehört die wenn du die Sache auf sich beruhen läßt.",,"Ha, fek, la registo sendis vin. Mi estis pagonta lin, serioze. Nu, aŭskultu, mi havas kelke da kaŝita mono; ĝi estas via se vi rigardos aliloken.","Ah, maldición, el gobernador te ha enviado; iba a darle su parte, en serio. Bueno, escucha, tengo un puñado escondido; es tuyo si miras para otro lado.","Ah, no puede ser, te manda el gobernador; iba a darle su parte, en serio. Bueno, escucha, tengo un puñado escondido; es tuyo si miras para otro lado.","Voi helvetti, kuvernööri on lähettänyt sinut. Meinasin antaa hänelle hänen siivunsa, ihan totta. Hei, kuuntele. Minulla on jemma kätkettynä. Se on sinun, jos katsot asiaa läpi sormiesi.","Oh, merde. Le gouverneur t'a envoyé? J'allais lui donner sa part, si, vraiment. Ok, écoute. J'en ai un paquet de mis de côté. Si tu veux, tu peux le prendre, si tu m'oublies.","Szóval a kormányzó küldött...francba. Oda akartam adni a megillető részét, hidd el tényleg. Figyelj, itt egy köteg eldugva. A tied ha képes vagy szemet hunyni felette.","Ah, dannazione... Ti ha mandato il governatore. Gli avrei dato la sua parte, giuro che l'avrei fatto. Ok, ascolta. Ho una parcella qua con me. È tua se chiudi un occhio.","クソッ、知事の回し者だな。 本当はあいつに分け前を渡そうとしてたんだがな。 よし、聞いてくれ。金はあるから、 -見逃してくれりゃお前にも分けてやる。","이런 제길... 총독 새끼가 널 보낸 거지? 하필 그 녀석의 몫을 보내기 전에. 좋아, 잘 들어. 날 살려주면 내가 숨긴 비상금을 줄게!","Oh, verdomme. De gouverneur heeft je gestuurd. Ik wilde hem zijn deel geven, echt waar. Oké, luister. Ik heb een bundel verstopt. Het is van jou als je de andere kant op kijkt.","Å, pokker. Guvernøren sendte deg. Jeg skulle gi ham hans andel, det skulle jeg virkelig. OK, hør her. Jeg har gjemt en bunke. Den er din hvis du ser den andre veien.","Kurde. Przysłał cię gubernator. Chciałem się z nim podzielić udziałami, naprawdę. Ok, słuchaj. Mam tu ukryty pewien pakunek. Będzie twój jeśli zawrócisz.","Ah, merda. O governador enviou você. Eu ja ia passar a parte dele, sério mesmo. Ok, ouça. Eu tenho um pacote escondido aqui. Ele é seu se você deixar passar.",,"Of, firar. Guvernatorul te-a trimis. Urma să îi dau partea lui din câștig, chiar urma, pe cuvânt. În regulă, ascultă. Am un pachet ascuns. E al tău dacă alegi să ignori ceea ce s-a întâmplat.","Ох, чёрт. Ты от губернатора. Я собирался отдать ему его долю — нет, правда. Слушай, я поднакопил изрядно денег — они твои, если найдёшь иной выход из ситуации.",,"Oh, kahretsin. Seni vali gönderdi. Ona payını verecektim, gerçekten. Tamam, dinle. Sakladığım bir paket var. Diğer tarafa bakarsan senindir." -"All right, I'll let you go.",TXT_RPLY0_SCRIPT04_D18192_ALLRI,〃,,,"Dobře, nechám tě jít.","Okay, jeg lader dig gå.","Ok, ich lass dich gehen.",,"Bone, vi rajtas foriri.","Muy bien, te dejaré ir.","Muy bien, te dejo ir.","Hyvä on, päästän sinut.","D'accord, tu peux y aller.","Rendben, elengedlek.","Va bene, ti lascerò andare.",分かった、見逃そう。,좋아. 그럼 널 살려주지.,"Oké, ik laat je gaan.","Greit, jeg skal la deg gå.","Dobra, zostawię cię w spokoju.","Ok, vou te deixar em paz.",,"În regulă, te las în pace.","Ладно, я дам тебе уйти.",,"Pekala, gitmene izin vereceğim." -"Sorry, nothing personal.",TXT_RPLY1_SCRIPT04_D18192_SORRY,〃,,,"Promiň, nic osobního.","Undskyld, det er ikke personligt.","Tut mir leid, nimm es nicht persönlich",,"Pardonon, mi nur laboras.","Lo siento, no es nada personal.",,"Pahoittelut, ei mitään henkilökohtaista.","Désolé, rien de personnel.","Sajnálom, nem személyes.","Mi spiace, nulla di personale.",悪いが、仕事なんでね。,"미안해, 사적인 건 아니야.","Sorry, niets persoonlijks.","Unnskyld, ikke ta det personlig.","Wybacz, nic osobistego.",Desculpe. Não é nada pessoal.,,"Scuze, nimic personal.","Прости, ничего личного.",,"Üzgünüm, kişisel bir şey değil." +見逃してくれりゃお前にも分けてやる。","이런 제길... 총독 새끼가 널 보낸 거지? 하필 그 녀석의 몫을 보내기 전에. 좋아, 잘 들어. 날 살려주면 내가 숨긴 비상금을 줄게!","Oh, verdomme. De gouverneur heeft je gestuurd. Ik wilde hem zijn deel geven, echt waar. Oké, luister. Ik heb een bundel verstopt. Het is van jou als je de andere kant op kijkt.","Å, pokker. Guvernøren sendte deg. Jeg skulle gi ham hans andel, det skulle jeg virkelig. OK, hør her. Jeg har gjemt en bunke. Den er din hvis du ser den andre veien.","Kurde. Przysłał cię gubernator. Chciałem się z nim podzielić udziałami, naprawdę. Ok, słuchaj. Mam tu ukryty pewien pakunek. Będzie twój jeśli zawrócisz.","Ah, merda. O governador enviou você. Eu ja ia passar a parte dele, sério mesmo. Ok, ouça. Eu tenho um pacote escondido aqui. Ele é seu se você deixar passar.",,"Of, firar. Guvernatorul te-a trimis. Urma să îi dau partea lui din câștig, chiar urma, pe cuvânt. În regulă, ascultă. Am un pachet ascuns. E al tău dacă alegi să ignori ceea ce s-a întâmplat.","Ох, чёрт. Ты от губернатора. Я собирался отдать ему его долю — нет, правда. Слушай, я поднакопил изрядно денег — они твои, если найдёшь иной выход из ситуации.",,"Fan också. Guvernören skickade dig. Jag tänkte ge honom hans andel, verkligen. Okej, lyssna. Jag har en bunt gömt. Det är ditt om du tittar åt andra hållet.","Oh, kahretsin. Seni vali gönderdi. Ona payını verecektim, gerçekten. Tamam, dinle. Sakladığım bir paket var. Diğer tarafa bakarsan senindir." +"All right, I'll let you go.",TXT_RPLY0_SCRIPT04_D18192_ALLRI,〃,,,"Dobře, nechám tě jít.","Okay, jeg lader dig gå.","Ok, ich lass dich gehen.",,"Bone, vi rajtas foriri.","Muy bien, te dejaré ir.","Muy bien, te dejo ir.","Hyvä on, päästän sinut.","D'accord, tu peux y aller.","Rendben, elengedlek.","Va bene, ti lascerò andare.",分かった、見逃そう。,좋아. 그럼 널 살려주지.,"Oké, ik laat je gaan.","Greit, jeg skal la deg gå.","Dobra, zostawię cię w spokoju.","Ok, vou te deixar em paz.",,"În regulă, te las în pace.","Ладно, я дам тебе уйти.",,"Okej, jag låter dig gå.","Pekala, gitmene izin vereceğim." +"Sorry, nothing personal.",TXT_RPLY1_SCRIPT04_D18192_SORRY,〃,,,"Promiň, nic osobního.","Undskyld, det er ikke personligt.","Tut mir leid, nimm es nicht persönlich",,"Pardonon, mi nur laboras.","Lo siento, no es nada personal.",,"Pahoittelut, ei mitään henkilökohtaista.","Désolé, rien de personnel.","Sajnálom, nem személyes.","Mi spiace, nulla di personale.",悪いが、仕事なんでね。,"미안해, 사적인 건 아니야.","Sorry, niets persoonlijks.","Unnskyld, ikke ta det personlig.","Wybacz, nic osobistego.",Desculpe. Não é nada pessoal.,,"Scuze, nimic personal.","Прости, ничего личного.",,"Ledsen, inget personligt.","Üzgünüm, kişisel bir şey değil." "Nuts, if I'm going down, then so are you. Guards!!",TXT_DLG_SCRIPT04_D19708_NUTSI,〃,,,"K čertu, jestli mám zemřít, tak ty taky. Stráže!","Fandens, hvis jeg ryger ned, så ryger du også ned. Vagter!!","Scheiße, aber wenn ich dran bin, bist du es auch. Wärter!",,"Al mil diabloj. Se mi falos, ankaŭ vi. Gardistoj!!","A tomar por saco. Si yo caigo, tú también. ¡¡Guardias!!","Al carajo. Si yo caigo, tú también. ¡¡Guardias!!","Vittu, jos kuolen nyt, niin sinäkin. Vartijat!!","Putain, si je crève ici, alors tu y passe aussi! Gardes!","Őrület! Ha Én lebukok, akkor rántalak magammal. Őrök!","Al diavolo, se devo andare al fondo, ti porterò con me. Guardie!!","社会の厳しさを分けてやるよ、お前もそうなれ。 -ガード!","썅! 아니야, 네가 가질 수 있는 건 전혀 없어! 경비병!!","Noten, als ik naar beneden ga, dan ben jij dat ook. Bewakers!!","Faen, hvis jeg går ned, så gjør du det også. Vakter!","Szlag, jeśli mam zginąć, to ty też. Straże!!","Porra, se eu vou morrer então você também vai. Guardas!!",,"Nebunie - dacă o iau la vale, atunci o să te iau cu mine. Gardieni!!","К чёрту — раз уж я сдохну, то и ты со мной. Стража!",,"Fındık, eğer ben batıyorsam, sen de batacaksın. Gardiyanlar!!" +ガード!","썅! 아니야, 네가 가질 수 있는 건 전혀 없어! 경비병!!","Noten, als ik naar beneden ga, dan ben jij dat ook. Bewakers!!","Faen, hvis jeg går ned, så gjør du det også. Vakter!","Szlag, jeśli mam zginąć, to ty też. Straże!!","Porra, se eu vou morrer então você também vai. Guardas!!",,"Nebunie - dacă o iau la vale, atunci o să te iau cu mine. Gardieni!!","К чёрту — раз уж я сдохну, то и ты со мной. Стража!",,"Nuts, om jag åker ner, så gör du det också. Vakter!","Fındık, eğer ben batıyorsam, sen de batacaksın. Gardiyanlar!!" "Business my ass. Help, guards, I've got a live one.",TXT_DLG_SCRIPT04_D21224_BUSIN,〃,,,"Do hajzlu s nabídkami. Pomoc, stráže, mám tu živého!","Skide være med forretningen! Hjælp, vagter, jeg har en indtrængende.","Scheiß' aufs Geschäft. Wärter, ich habe hier einen Eindringling.",,"«Intertraktadoj», kia feka ŝerco. Helpu min, gardistoj, estas viva ribelanto!","«Negocios» mis cojones. ¡Ayuda, guardias, tengo uno vivo!","«Negocios» las pelotas. ¡Ayuda, guardias, tengo uno vivo!","Ja paskat mitään kauppoja. Vartijat, apua. Tämä elää vielä.","Une affaire, mon cul! Gardes, à l'aide, j'en ai un de vivant ici!","Francokat üzlet. Segítség, őrök, itt van egy.","Alla faccia degli affari. Aiuto, guardie, c'è un intruso.","クソ野郎が、タダでは死なねえ。 助けてくれガード!イカれた奴がいる!","사적인 건 지랄하네. 경비병! 여기 노예가 도망친다! - \cy실례지만, 이거 좀 골때리겠는데?","Zaken mijn kont. Help, bewakers, ik heb een levende.","Drit i forretningene. Hjelp, vakter, jeg har en inntrenger!","Do dupy z takim biznesem. Pomocy, straże, mamy tu kogoś żywego.","Negócios coisa nenhuma. Guardas, me ajudem, tenho um vivo aqui.",,"Afaceri pe naiba. Ajutor, gardieni, am prins unul.","Дело дрянь. Стража, на помощь! Тут живой повстанец.",,"Kıçımın işi. Yardım edin gardiyanlar, canlı bir tane var." + \cy실례지만, 이거 좀 골때리겠는데?","Zaken mijn kont. Help, bewakers, ik heb een levende.","Drit i forretningene. Hjelp, vakter, jeg har en inntrenger!","Do dupy z takim biznesem. Pomocy, straże, mamy tu kogoś żywego.","Negócios coisa nenhuma. Guardas, me ajudem, tenho um vivo aqui.",,"Afaceri pe naiba. Ajutor, gardieni, am prins unul.","Дело дрянь. Стража, на помощь! Тут живой повстанец.",,"Affärer i min röv. Hjälp, vakter, jag har en levande.","Kıçımın işi. Yardım edin gardiyanlar, canlı bir tane var." "Ah, I got word from Macil that you'd be coming. I have a way to get you inside the power station, but it's on the risky side.",TXT_DLG_SCRIPT04_D22740_AHIGO,MAP04: Worner.,,,"Á, doneslo se mi od Macila, že přijdeš. Mám pro tebe cestu, jak se dostat do elektrárny, ale je trochu riskantní.","Jeg fik besked fra Macil om, at du ville komme. Jeg har en måde at få dig ind i kraftværket på, men det er lidt risikabelt.","Ah, Macil hat mir mitgeteilt, dass du kommst. Ich kenne einen Weg, um in das Werk reinzukommen, aber es ist etwas riskant.",,"Ha, Macil diris al mi, ke vi venus. Mi havas manieron meti vin en la centralon, sed ĝi estas riska.","Ah, Macil me ha dicho que ibas a venir. Tengo una forma de meterte en la central eléctrica, pero es algo arriesgada.","Ah, Macil me dijo que ibas a venir. Tengo una forma de meterte a la central eléctrica, pero es algo arriesgada.","Aah, sainkin Macililta viestin, että olisit tulossa. Minulla on keino saada sinut sisään voimalaitokseen, mutta se ei ole varmimmasta päästä.","Ah, Macil m'a prévenu que vous viendriez. J'ai une entrée dans la centrale pour vous mais elle est un peu risquée.","Ah, kaptam infót Maciltól hogy érkezni fogsz. Igazából van egy mód bejutni az erőműbe, de elég rizikós.","Ah, ho sentito da Macil che saresti arrivato. Ho un modo per farti entrare nella centrale energetica, ma è rischioso.","ああ、マシルから話は聞いたよ。 君を発電所に入れてやれるが -かなりリスキーな方法だぞ。","아! 마실 사령관님으로부터 당신이 여기로 온다는 소식을 들었습니다. 발전소로 깊숙이 향하는 지름길을 알고 있어요. 다만, 좀 위험하답니다.","Ah, ik heb van Macil gehoord dat je zou komen. Ik heb een manier om je in de centrale te krijgen, maar het is aan de riskante kant.","Jeg fikk beskjed fra Macil om at du ville komme. Jeg har en måte å få deg inn i kraftverket på, men det er risikabelt.","Ah, słyszałem od Macila, że przyjdziesz. Mam sposób, aby cię przedostać do środka elektrowni, ale jest to ryzykowne.","Ah, Macil me contou que você viria. Tenho um jeito de fazer você entrar na usina elétrica, mas é bem arriscado.",,"Ah, am primit știrea de la Macil că urma să vii. Am o cale de a te infiltra în uzină, dar e riscantă.","А-а, мне сообщили, что ты от Мэйсила. Я знаю способ проникнуть на станцию, но он довольно рискованный.",,Macil'den geleceğin haberini aldım. Seni güç istasyonuna sokmanın bir yolunu buldum ama biraz riskli. -I'll take my chances.,TXT_RPLY0_SCRIPT04_D22740_ILLTA,〃,,,Já to zkusím.,Jeg tager mine chancer.,Ich riskiere es.,,Mi povas preni sur min la riskon.,Puedo asumir el riesgo.,,Kokeilen onneani.,Je suis prêt à prendre ces risques.,Vállalom a kockázatot.,Correrò il rischio.,大丈夫だ。,그 정도야 각오하고 있습니다.,Ik neem mijn kansen.,Jeg tar sjansen.,Zaryzykuję.,Estou disposto a arriscar.,,Voi risca.,Я рискну.,,Şansımı deneyeceğim. +かなりリスキーな方法だぞ。","아! 마실 사령관님으로부터 당신이 여기로 온다는 소식을 들었습니다. 발전소로 깊숙이 향하는 지름길을 알고 있어요. 다만, 좀 위험하답니다.","Ah, ik heb van Macil gehoord dat je zou komen. Ik heb een manier om je in de centrale te krijgen, maar het is aan de riskante kant.","Jeg fikk beskjed fra Macil om at du ville komme. Jeg har en måte å få deg inn i kraftverket på, men det er risikabelt.","Ah, słyszałem od Macila, że przyjdziesz. Mam sposób, aby cię przedostać do środka elektrowni, ale jest to ryzykowne.","Ah, Macil me contou que você viria. Tenho um jeito de fazer você entrar na usina elétrica, mas é bem arriscado.",,"Ah, am primit știrea de la Macil că urma să vii. Am o cale de a te infiltra în uzină, dar e riscantă.","А-а, мне сообщили, что ты от Мэйсила. Я знаю способ проникнуть на станцию, но он довольно рискованный.",,"Macil berättade att du skulle komma. Jag har ett sätt att få in dig i kraftverket, men det är lite riskabelt.",Macil'den geleceğin haberini aldım. Seni güç istasyonuna sokmanın bir yolunu buldum ama biraz riskli. +I'll take my chances.,TXT_RPLY0_SCRIPT04_D22740_ILLTA,〃,,,Já to zkusím.,Jeg tager mine chancer.,Ich riskiere es.,,Mi povas preni sur min la riskon.,Puedo asumir el riesgo.,,Kokeilen onneani.,Je suis prêt à prendre ces risques.,Vállalom a kockázatot.,Correrò il rischio.,大丈夫だ。,그 정도야 각오하고 있습니다.,Ik neem mijn kansen.,Jeg tar sjansen.,Zaryzykuję.,Estou disposto a arriscar.,,Voi risca.,Я рискну.,,Jag tar mina chanser.,Şansımı deneyeceğim. "All right, I stole an I.D. from the corpse of some fool who fell into the reactor's coolant pit. --blat-- instant deep fry.",TXT_DLG_SCRIPT04_D24256_ALLRI,〃,,,"Tak dobře. Ukradl jsem identifikační kartu z mrtvoly nějakého chudáka, co spadl do reaktorové nádrže s chladivem. --Plesk--, okamžitě ho to upeklo.","Okay, jeg stjal et ID fra liget af et fjols, der faldt ned i reaktorens kølemiddelgrav. --blat-- øjeblikkelig friturestegning.","Alles klar. Ich habe hier die Identitätskarte von so 'nem Trottel, der in die Kühlanlage des Reaktors reingefallen ist. --platsch-- hat ihn schockgefrostet.",,"Bone. Mi ŝtelis la identigilon de la kadavro de stultulo, kiu falis en la malvarmigan truon de la reaktoro; «blat», tuje fritita.","Muy bien. He robado la identificación del cadáver de un inútil que cayó en el pozo refrigerante del reactor; «blat», frito al instante.","Muy bien. Me robé la identificación del cadáver de un inútil que se cayó al pozo refrigerante del reactor; «blat», frito al instante.","Hyvä on, varastin henkilötunnisteen joltain idiootilta, joka oli pudonnut reaktorin jäähdytyskuiluun. Pläts, pikauppopaisto.",Très vien. J'ai volé la carte d'identité d'un idiot qui est tombé dans le puits de refroidissement du réacteur. Plouf! Instantanément frit.,"Rendben van, elcsórtam egy szerencsétlen hullájáról az igazolványt aki beleesett a reaktor hűtőfolyadékába. --placcs-- rögtön ropogósra sült.","Molto bene allora, ho rubato una tessera d'identificazione da uno sciocco che è caduto nel pozzo refrigerante del reattore. --blat-- fritto instantaneamente.","わかった、このIDを受け取れ。 これはリアクターの冷却炉に落ちた間抜けが 持っていたものだ。 -バチッ!と一瞬で黒焦げになっちまったよ。",좋습니다. 이 신분증은 조심하지도 못하고 냉각 회로로 떨어진 한 불쌍한 녀석에게서 훔쳐온 겁니다. “뿌직”! 완전히 터졌죠.,"Oké, ik heb een I.D. gestolen van het lijk van een dwaas die in de koelvloeistofput van de reactor is gevallen. --Blat-- onmiddellijk frituren.",Jeg stjal et ID-kort fra liket til en idiot som falt ned i reaktorens kjølegrop. --...blat... øyeblikkelig frityrsteking.,"Dobra, ukradłem identyfikator ze zwłok pewnego durnia, który wpadł do chłodnicy reaktora. --puf-- i się usmażył.",Beleza. Eu roubei uma identificação do cadáver de algum otário que caiu no poço de refrigeração do reator. Pluft! Frito na hora. ,,Bine. Am furat un card de acces de pe cadavrul unui nătăfleț care a căzut în groapa sistemului de răcire al reactorului. --pleoșc--făcut scrum instant.,"Очень хорошо. Я украл удостоверение с трупа одного идиота, который упал прямо в охлаждающий бассейн реактора. «Шмяк!» — моментальное прожаривание до костей.",,"Pekala, reaktörün soğutucu çukuruna düşen bir aptalın cesedinden kimliğini çaldım. --Anında derin kızartma." -What should I do once I'm in?,TXT_RPLY0_SCRIPT04_D24256_WHATS,〃,,,Co mám udělat uvnitř?,"Hvad skal jeg gøre, når jeg er inde?","Was soll ich machen, wenn ich drin bin?",,Kion mi faru post mia eniro?,¿Qué debo hacer una vez dentro?,¿Qué hago una vez adentro?,Mitä teen päästyäni sisään?,Qu'est ce que je fais une fois que je suis rentré?,Mit tegyek amikor bejutottam?,E cosa devo fare una volta dentro?,中に入ったらどうすればいい?,그곳으로 들어간 후엔 뭘 해야 하죠?,Wat moet ik doen als ik eenmaal binnen ben?,Hva skal jeg gjøre når jeg er inne?,Co mam zrobić jak wejdę?,O que devo fazer depois de entrar?,,Ce trebuie să fac odată ce ajung în interior?,И что дальше?,,İçeri girdiğimde ne yapmalıyım? +バチッ!と一瞬で黒焦げになっちまったよ。",좋습니다. 이 신분증은 조심하지도 못하고 냉각 회로로 떨어진 한 불쌍한 녀석에게서 훔쳐온 겁니다. “뿌직”! 완전히 터졌죠.,"Oké, ik heb een I.D. gestolen van het lijk van een dwaas die in de koelvloeistofput van de reactor is gevallen. --Blat-- onmiddellijk frituren.",Jeg stjal et ID-kort fra liket til en idiot som falt ned i reaktorens kjølegrop. --...blat... øyeblikkelig frityrsteking.,"Dobra, ukradłem identyfikator ze zwłok pewnego durnia, który wpadł do chłodnicy reaktora. --puf-- i się usmażył.",Beleza. Eu roubei uma identificação do cadáver de algum otário que caiu no poço de refrigeração do reator. Pluft! Frito na hora. ,,Bine. Am furat un card de acces de pe cadavrul unui nătăfleț care a căzut în groapa sistemului de răcire al reactorului. --pleoșc--făcut scrum instant.,"Очень хорошо. Я украл удостоверение с трупа одного идиота, который упал прямо в охлаждающий бассейн реактора. «Шмяк!» — моментальное прожаривание до костей.",,Jag stal ett ID från en dåre som föll ner i reaktorns kylvattengrop. --blat-- omedelbar fritering.,"Pekala, reaktörün soğutucu çukuruna düşen bir aptalın cesedinden kimliğini çaldım. --Anında derin kızartma." +What should I do once I'm in?,TXT_RPLY0_SCRIPT04_D24256_WHATS,〃,,,Co mám udělat uvnitř?,"Hvad skal jeg gøre, når jeg er inde?","Was soll ich machen, wenn ich drin bin?",,Kion mi faru post mia eniro?,¿Qué debo hacer una vez dentro?,¿Qué hago una vez adentro?,Mitä teen päästyäni sisään?,Qu'est ce que je fais une fois que je suis rentré?,Mit tegyek amikor bejutottam?,E cosa devo fare una volta dentro?,中に入ったらどうすればいい?,그곳으로 들어간 후엔 뭘 해야 하죠?,Wat moet ik doen als ik eenmaal binnen ben?,Hva skal jeg gjøre når jeg er inne?,Co mam zrobić jak wejdę?,O que devo fazer depois de entrar?,,Ce trebuie să fac odată ce ajung în interior?,И что дальше?,,Vad ska jag göra när jag väl är inne?,İçeri girdiğimde ne yapmalıyım? "Tell whoever asks that you're the replacement worker for Mr. Crispy. It's just dumb enough to work. Oh, and you might want to check out the storeroom that's right above us.",TXT_DLG_SCRIPT04_D25772_TELLW,〃,,,"Řekni komukoliv, kdo se zeptá, že jsi náhrada za pana Pečínku. Je to dost pitomé na to, aby to fungovalo. Jo, a možná bys mohl mít zájem podívat se do skladu, který je přímo nad námi.","Fortæl dem, der spørger, at du er afløseren for Mr Crispy. Det er lige dumt nok til at virke. Åh, og du vil måske tjekke lagerrummet lige over os.","Sage jedem, der dich fragt, dass du der Ersatz für Mister Crispy bist. Es ist idiotisch genug, um zu funktionieren. Oh, du solltest auch mal einen Blick in den Lagerraum auf der oberen Etage werfen.",,"Diru al tiu, kiu demandos, ke vi estas la anstataŭanto de la S-ro Krakulo; li estas sufiĉe stulta por kredi tion. Ha, kaj vi eble volas trarigardi la stokejon super ni.","A quien pregunte, dile que eres el sustituto del Sr. Crujiente; es lo bastante estúpido como para que funcione. Ah, y puede que quieras revisar el cuarto de almacenamiento que está justo sobre nosotros.",,"Jos joku kysyy, kerro olevasi herra Crispyn korvaaja. Saattaa olla jo niin tyhmä idea, että jopa toimii. Ai niin, ja saattanet haluta vilkaista varastohuonetta, joka sijaitsee suoraan yläpuolellamme.","Expliquez à qui veut l'entrendre que vous remplacez Mr. Frite. C'et suffisamment stupide pour marcher. Oh, et pensez à fouiller la salle de stockage au dessus de nous.","Akárki is kérdezi, mondd azt, hogy Kétszersült úr helyettesítése vagy. Akkora böszmeség, hogy még müködhet is. Ja, és érdemes lenne körbenézned a fölöttünk levő tárolóban.","Basta che tu dica a chiunque lo chieda che tu sei il rimpiazzo per il Signor Fritto. È abbastanza stupido da funzionare. Ah, e potrebbe anche interessarti il deposito che si trova proprio sopra di noi.","誰かに聞かれたら、クリスピーの代わりに来た と言え。皆疑うことなく信じるだろうさ。 あと、上の階にある倉庫も行けるなら 見てみた方がいいぞ。","누군가가 물어보면 통구이 씨의 후임으로 들어왔다고 하시면 됩니다. 별로 어려운 일은 아닐 거에요. 아, 그리고 우리 바로 위에 있는 창고도 한번 확인해보세요. - \cy으음. 왠지 무기 같은데. 화력이야 더 많으면 좋지.","Vertel degene die vraagt of jij de vervanger bent van Mr. Crispy. Het is net dom genoeg om te werken. Oh, en misschien wilt je eens kijken naar het magazijn dat vlak boven ons is.",Si til alle som spør at du er vikar for Mr. Crispy. Det er dumt nok til å fungere. Og du vil kanskje sjekke lageret som er rett over oss.,"Jak ktoś się będzie pytał, powiedz, że przyszedłeś na zastępstwo za Pana Chrupka. Jest to tak głupie, ale zadziała. Oh, i na pewno chciałbyś sprawdzić co jest w magazynie nad nami.","Diga pra quem perguntar que você é o substituto do Sr. Fritinho. É idiota o suficiente pra funcionar. Ah, e talvez você queira dar uma olhada no depósito lá em cima.",,"Spune-i oricui te întreabă că ești înlocuitorul dl. Crispy. E suficient de stupid cât să funcționeze. Ah, și probabil vrei să verifici depozitul care se află chiar deasupra noastră.","Говори всем, что тебя прислали заменить г-на Поджаренного. Это так глупо, что должно сработать. И ещё, наверное, тебе захочется наведаться на склад, прямо над нами.",,"Soran kişiye Bay Çıtır'ın yerine gelen işçi olduğunu söyle. İşe yarayacak kadar aptalca. Oh, ve hemen üstümüzdeki depoya bakmak isteyebilirsin." -Boy I hope this I.D. Works.,TXT_RPLY0_SCRIPT04_D25772_BOYIH,〃,,,Snad tahle karta funguje.,"Jeg håber, at det her ID virker.","Mann, ich hoffe, dass diese Karte auch funktioniert.",,Espereble ĉi tiu identigilo funkcios.,"Vaya, espero que esta identificación funcione.",,"Toivon todellakin, että tämä tunniste toimii.","Eh bien, j'espère que cette carte fonctionnera.",Merem remélni hogy ez az igazolvány működni fog.,Spero proprio che questo tesserino funzioni.,このIDで上手くいけばいいが。,이 방법이 통했으면 좋겠네요.,"Jongen, ik hoop dat deze I.D. werkt.",Jeg håper denne legitimasjonen virker.,"Mam nadzieję, że ten identyfikator zadziała.","Olha, espero que esta identificação funcione.",,Mamă frate sper ca legitimația să funcționeze.,"Ох. Надеюсь, это сработает.",,Umarım bu kimlik işe yarar. + \cy으음. 왠지 무기 같은데. 화력이야 더 많으면 좋지.","Vertel degene die vraagt of jij de vervanger bent van Mr. Crispy. Het is net dom genoeg om te werken. Oh, en misschien wilt je eens kijken naar het magazijn dat vlak boven ons is.",Si til alle som spør at du er vikar for Mr. Crispy. Det er dumt nok til å fungere. Og du vil kanskje sjekke lageret som er rett over oss.,"Jak ktoś się będzie pytał, powiedz, że przyszedłeś na zastępstwo za Pana Chrupka. Jest to tak głupie, ale zadziała. Oh, i na pewno chciałbyś sprawdzić co jest w magazynie nad nami.","Diga pra quem perguntar que você é o substituto do Sr. Fritinho. É idiota o suficiente pra funcionar. Ah, e talvez você queira dar uma olhada no depósito lá em cima.",,"Spune-i oricui te întreabă că ești înlocuitorul dl. Crispy. E suficient de stupid cât să funcționeze. Ah, și probabil vrei să verifici depozitul care se află chiar deasupra noastră.","Говори всем, что тебя прислали заменить г-на Поджаренного. Это так глупо, что должно сработать. И ещё, наверное, тебе захочется наведаться на склад, прямо над нами.",,"Säg till den som frågar att du är ersättare för Mr Crispy. Det är tillräckligt dumt för att fungera. Åh, och du kanske vill kolla in förrådet som ligger precis ovanför oss.","Soran kişiye Bay Çıtır'ın yerine gelen işçi olduğunu söyle. İşe yarayacak kadar aptalca. Oh, ve hemen üstümüzdeki depoya bakmak isteyebilirsin." +Boy I hope this I.D. Works.,TXT_RPLY0_SCRIPT04_D25772_BOYIH,〃,,,Snad tahle karta funguje.,"Jeg håber, at det her ID virker.","Mann, ich hoffe, dass diese Karte auch funktioniert.",,Espereble ĉi tiu identigilo funkcios.,"Vaya, espero que esta identificación funcione.",,"Toivon todellakin, että tämä tunniste toimii.","Eh bien, j'espère que cette carte fonctionnera.",Merem remélni hogy ez az igazolvány működni fog.,Spero proprio che questo tesserino funzioni.,このIDで上手くいけばいいが。,이 방법이 통했으면 좋겠네요.,"Jongen, ik hoop dat deze I.D. werkt.",Jeg håper denne legitimasjonen virker.,"Mam nadzieję, że ten identyfikator zadziała.","Olha, espero que esta identificação funcione.",,Mamă frate sper ca legitimația să funcționeze.,"Ох. Надеюсь, это сработает.",,Jag hoppas att det här ID-kortet fungerar.,Umarım bu kimlik işe yarar. "Get out of here, unless you want to end up Mr. Dead.",TXT_DLG_SCRIPT04_D27288_GETOU,〃,,,"Vypadni odsud, leda že by z tebe chtěl být pan Mrtvý.","Forsvind herfra, medmindre du vil ende som Mr. Død.","Und nun verschwinde, wenn du nicht als Mister Tot enden willst.",,"Foriru, krom se vi volas iĝi S-ro Mortinto.","Ya vete, a menos que quieras ser el Sr. Muerto.",,"Ala liikkua, ellet sitten mieluummin halua ryhtyä herra Kalmon korvaajaksi.","Sortez de là, sauf si vous voulez être Mr. Mort.","Na húzz innen, ha nem akarod úgy végezni mint Halott úr.","Ora ti conviene andare, a meno che tu non voglia diventare Signor Morto.","ここを離れた方がいい、君がミスターポックリに -成らない為に。",어서 가세요. 여기 계속 있다간 고인이 될 겁니다.,"Maak dat je wegkomt, tenzij je wilt eindigen als meneer de Dood.","Kom deg ut herfra, med mindre du vil ende opp som Mr. Død.","Idź stąd, jeśli nie chcesz skończyć jako Pan Truposz.","Saia daqui, a não ser que você queria comer capim pela raiz.",,"Valea de aici, dacă nu vrei să devii dl. Mort.","Уходи сейчас же, если не хочешь стать «г-ном покойником».",,Sonunun Bay Ölü olmasını istemiyorsan git buradan. +成らない為に。",어서 가세요. 여기 계속 있다간 고인이 될 겁니다.,"Maak dat je wegkomt, tenzij je wilt eindigen als meneer de Dood.","Kom deg ut herfra, med mindre du vil ende opp som Mr. Død.","Idź stąd, jeśli nie chcesz skończyć jako Pan Truposz.","Saia daqui, a não ser que você queria comer capim pela raiz.",,"Valea de aici, dacă nu vrei să devii dl. Mort.","Уходи сейчас же, если не хочешь стать «г-ном покойником».",,"Försvinn härifrån, om du inte vill bli herr Död.",Sonunun Bay Ölü olmasını istemiyorsan git buradan. "Hey, leave me alone. If they catch us wasting time we get dead, or extra work.",TXT_DLG_SCRIPT04_D28804_HEYLE,MAP04: Warehouse → Dock Worker.,,,"Hej, nech mě bejt. Jestli nás chytěj ztrácet čas, dostanem kulku, nebo práci navíc.","Hey, lad mig være. Hvis de fanger os i at spilde tiden, bliver vi dræbt eller får ekstra arbejde.","Lass mich in Ruhe. Wenn sie uns beim Quatschen erwischen, sind wir entweder beide tot oder kriegen Extraarbeit aufgebrummt.",,"He, ne distru min. Se ili vidas, ke ni perdas tempon, ni estos mortigitaj... aŭ kun plia laboro.","Oye, déjame en paz. Si nos pillan perdiendo el tiempo nos matan... o nos dan más trabajo.","Oye, déjame en paz. Si nos ven perdiendo el tiempo nos matan... o nos dan más trabajo.","Hei, jätä minut rauhaan. Jos ne äkkäävät meidän tuhlaavan aikaa, saamme kuolla, tai lisää työtä.","Hé, foutez-moi la paix, si ils nous attrappent ici à nous tourner les pouces, on y passe où c'est le travail forcé.","Héj, hagyj engem békén. Ha meglátják, hogy itt lopjuk a napot, akkor vagy elintéznek vagy túlórát sóznak ránk.","Ehi, lasciami stare. Se ci beccano a perdere tempo ci ammazzano, o ci danno lavoro extra.","話しかけないでくれ、 -奴等にバレたら処分されるか、残業させられる。","이봐, 나 좀 내버려 둬. 우리가 이렇게 농땡이 치는 걸 들키면 둘 다 죽는다고... 아님 추가 근무를 받는다든지!","Hé, laat me met rust. Als ze ons betrappen op tijdverspilling worden we dood, of extra werk.","Hei, la meg være i fred. Hvis de tar oss i å kaste bort tid, blir vi drept, eller får ekstraarbeid.","Hej, zostaw mnie. Jeśli nas przyłapią na marnowaniu czasu to nas zabiją lub dadzą więcej pracy.","Ei, me deixe em paz. Se eles pegarem a gente fazendo corpo mole, a gente vai morrer ou receber trabalho extra.",,"Hei, lasă-mă în pace. Dacă ne prind pierzând vremea fie primim muncă în plus, fie moarte.","Эй, оставь меня в покое. Если они увидят, что мы болтаем, нас убьют, или добавят работы.",,"Hey, beni yalnız bırak. Bizi boşa zaman harcarken yakalarlarsa ya ölürüz ya da fazladan iş alırız." +奴等にバレたら処分されるか、残業させられる。","이봐, 나 좀 내버려 둬. 우리가 이렇게 농땡이 치는 걸 들키면 둘 다 죽는다고... 아님 추가 근무를 받는다든지!","Hé, laat me met rust. Als ze ons betrappen op tijdverspilling worden we dood, of extra werk.","Hei, la meg være i fred. Hvis de tar oss i å kaste bort tid, blir vi drept, eller får ekstraarbeid.","Hej, zostaw mnie. Jeśli nas przyłapią na marnowaniu czasu to nas zabiją lub dadzą więcej pracy.","Ei, me deixe em paz. Se eles pegarem a gente fazendo corpo mole, a gente vai morrer ou receber trabalho extra.",,"Hei, lasă-mă în pace. Dacă ne prind pierzând vremea fie primim muncă în plus, fie moarte.","Эй, оставь меня в покое. Если они увидят, что мы болтаем, нас убьют, или добавят работы.",,Lämna mig ifred. Om de kommer på oss med att slösa tid blir vi dödade eller får extra arbete.,"Hey, beni yalnız bırak. Bizi boşa zaman harcarken yakalarlarsa ya ölürüz ya da fazladan iş alırız." "Such pressure, at this rate we'll be back to normal shifts soon. We're pumping tons of power to the castle and I'm almost finished logging those new weapons.",TXT_DLG_SCRIPT04_D30320_SUCHP,MAP04: Reactor Core → Northern alarm green door → Level 2 door,,,"Takový tlak, tímhle tempem brzy budeme zase pracovat normální směny. Lijeme takové množství energie do hradu a já už jsem skoro hotov se zapisováním těch nových zbraní.","Sikke et pres, i dette tempo er vi snart tilbage på normale vagter. Vi pumper tonsvis af strøm til slottet, og jeg er næsten færdig med at logge de nye våben.","So viel Druck. Wenn es so weiter geht, gibt es bald wieder normale Schichten. Wir pumpen Tonnen von Energie in die Burg und ich habe die neuen Waffen fast alle verstaut.",,"Kia premo; laŭ ĉi tia kadenco, la normalaj deĵoroj baldaŭ revenos. Ni pumpas tunojn da energio al la kastelo kaj mi preskaŭ finis registri tiujn novajn armilojn.","Cuanta presión, a este ritmo volveremos pronto a turnos normales. Estamos dándole toneladas de energía al castillo y ya casi termino de registrar esas nuevas armas.","Cuanta presión, a este ritmo vamos a volver pronto a turnos normales. Estamos dándole toneladas de energía al castillo y ya casi termino de registrar esas nuevas armas.","Kovat paineet. Tällä tahdilla palaamme tuota pikaa normaaleihin työvuoroihin. Pumppaamme rutkasti voimaa linnaan, ja olen melkein saanut kirjattua uudet aseet.","Quelle pression. Si ça continue, on devrait revenir au rhytme de travail de base. On pompe des tonnes d'énergies pour le château et j'ai presque fini d'enregistrer toutes ces nouvelles armes.","Micsoda nyomás, ezzel az irammal vissza fogunk tudni térni a régi műszakba. Iszonyat áramot pumpálunk a kastélyba, és majdnem végeztem az új fegyverek nyílvántartásával. is.","Che pressione, a questo punto ritorneremo presto ai normali turni di lavoro. Stiamo indirizzando molta energia verso il castello, e ho quasi finito di catalogare quelle nuove armi.","この圧力、この速さならすぐ通常のシフトに 戻るだろう。私達は城へ大量の電気を供給して -いるし、新しい武器の切り出しも殆ど済んだ。","이런 압박감 속에 있다가는 다시 일반 교대 조로 복귀될 것 같아. 우린 지금 성 쪽으로 막대한 동력을 공급하고 있고, 난 저 신무기에 관한 일지를 거의 다 썼어.","Zulke druk, in dit tempo zullen we snel weer terug zijn bij normale diensten. We pompen tonnen energie naar het kasteel en ik ben bijna klaar met het kappen van die nieuwe wapens.","Med dette presset er vi snart tilbake til normale skift. Vi pumper masse strøm til slottet, og jeg er nesten ferdig med de nye våpnene.","Tyle nacisku, w ten sposób wkrótce będziemy mieli znów normalne zmiany. Pompujemy tony energii do zamku, a ja prawie skończyłem załadowywać te nowe bronie.",Quanta pressão. Desse jeito voltaremos a fazer turnos normais logo. Estamos mandando bastante energia para o castelo e estou quase terminando de registrar essas novas armas.,,"Ce presiuni, în ritmul ăsta o să revenim la turele obișnuite curând. Pompăm o tonă de energie către castel și aproape că am terminat să înregistrez aceste arme noi.","Такая нагрузка! С такими темпами мы вернёмся к нормальному графику совсем скоро. Мы направляем массу энергии в замок, и я почти закончил с погрузкой нового оружия.",,"Ne baskı ama, bu gidişle yakında normal vardiyaya döneceğiz. Kaleye tonlarca güç pompalıyoruz ve yeni silahları kaydetmeyi neredeyse bitirdim." -Weapons?,TXT_RPLY0_SCRIPT04_D30320_WEAPO,〃,,,Zbraní?,Våben?,Waffen?,,Ĉu armiloj?,¿Armas?,,Aseet?,Des armes?,Fegyverek?,Armi?,武器?,신무기?,Wapens?,Våpen?,Bronie?,Armas?,,Arme?,Оружия?,,Silahlar mı? +いるし、新しい武器の切り出しも殆ど済んだ。","이런 압박감 속에 있다가는 다시 일반 교대 조로 복귀될 것 같아. 우린 지금 성 쪽으로 막대한 동력을 공급하고 있고, 난 저 신무기에 관한 일지를 거의 다 썼어.","Zulke druk, in dit tempo zullen we snel weer terug zijn bij normale diensten. We pompen tonnen energie naar het kasteel en ik ben bijna klaar met het kappen van die nieuwe wapens.","Med dette presset er vi snart tilbake til normale skift. Vi pumper masse strøm til slottet, og jeg er nesten ferdig med de nye våpnene.","Tyle nacisku, w ten sposób wkrótce będziemy mieli znów normalne zmiany. Pompujemy tony energii do zamku, a ja prawie skończyłem załadowywać te nowe bronie.",Quanta pressão. Desse jeito voltaremos a fazer turnos normais logo. Estamos mandando bastante energia para o castelo e estou quase terminando de registrar essas novas armas.,,"Ce presiuni, în ritmul ăsta o să revenim la turele obișnuite curând. Pompăm o tonă de energie către castel și aproape că am terminat să înregistrez aceste arme noi.","Такая нагрузка! С такими темпами мы вернёмся к нормальному графику совсем скоро. Мы направляем массу энергии в замок, и я почти закончил с погрузкой нового оружия.",,"Vilken press, i den här takten är vi snart tillbaka på normala skift. Vi pumpar tonvis med ström till slottet och jag är nästan klar med att logga de nya vapnen.","Ne baskı ama, bu gidişle yakında normal vardiyaya döneceğiz. Kaleye tonlarca güç pompalıyoruz ve yeni silahları kaydetmeyi neredeyse bitirdim." +Weapons?,TXT_RPLY0_SCRIPT04_D30320_WEAPO,〃,,,Zbraní?,Våben?,Waffen?,,Ĉu armiloj?,¿Armas?,,Aseet?,Des armes?,Fegyverek?,Armi?,武器?,신무기?,Wapens?,Våpen?,Bronie?,Armas?,,Arme?,Оружия?,,Vapen?,Silahlar mı? "What do you think, we're backed up on socks?",TXT_DLG_SCRIPT04_D31836_WHATD,〃,,,"Co si myslíš, že ve zbrojnici máme ponožky?","Hvad tror du, vi er bagud med sokker?","Was dachtest du denn, glaubst du wir verteidigen uns mit Socken?",,Kion vi pensas? Ĉu ke ni agos per ŝtrumpetoj?,"¿Qué crees?, ¿que vamos con calcetines?","¿Qué crees?, ¿que vamos con medias o calcetines?","No mitä luulet meidän varastoineen, sukkia?",Vous croyez quoi? Qu'on a un surplus de chausettes?,"Mit gondolsz, zoknikkal vagyunk felfegyverkezve?","E che pensi, che ci difendiamo con dei calzini?",どう思う、ズボンがずり落ちないか?,"무슨 생각해? 양말 더 지급 받는 거? - \cy쉬운 일은 아니겠지만, 일단 한번 해보자고.","Wat denk je, dat we op sokken staan?","Hva tror du, at vi har sokker?","Co ty myślisz, że wysyłamy skarpetki?","Ora, você acha que usamos só as nossas meias?",,"Ce crezi, că suntem apărați pe șosete?","А ты думал, мы носки грузим?",,"Ne düşünüyorsun, çorapları yedekledik mi?" -What kind of weapons?,TXT_RPLY0_SCRIPT04_D31836_WHATK,〃,,,Jaké zbraně?,Hvilken slags våben?,Was für Waffen?,,Kiu speco de armiloj?,¿Qué clase de armas?,,Minkälaisia aseita?,Quel type d'armes?,Miféle fegyverek?,Che tipo di armi?,どんな武器だ?,어떤 신무기?,Wat voor wapens?,Hva slags våpen?,Jakie bronie?,Que tipo de armas?,,Ce fel de arme?,Какое оружие?,,Ne tür silahlar? -Are you deaf? I just told you how busy I am. Get back to work.,TXT_DLG_SCRIPT04_D33352_AREYO,〃,,,"Jsi hluchý? Už jsem ti řekl, jak jsem zaneprázdněný. Vrať se do práce.","Er du døv? Jeg har lige fortalt dig, hvor travlt jeg har. Kom tilbage til arbejdet.","Bist du taub? Ich hab dir dock gerade gesagt, wie beschäftigt ich bin. Geh zurück an die Arbeit.",,"Ĉu vi estas surda? Mi ĵus diris, kiel okupata mi estas. Reiru al via laboro.",¿Estás sordo? Ya te he dicho lo ocupado que estoy. Vuelve al trabajo.,¿Estás sordo? Ya te dije lo ocupado que estoy. Vuelve al trabajo.,"Kuuroko olet? Juurihan kerroin, kuinka kiire minulla on. Mene takaisin töihisi.","Vous êtes sourd? Je viens de vous dire que je suis occupé, retournez au travail!",Süket vagy? Most mondtam el mennyire elfoglalt vagyok. Húzz vissza dolgozni!,Ma sei sordo? Ti ho appena detto quanto sono occupato. Torna al lavoro.,難聴か? 私は、忙しい、から、仕事に、戻れ。,귀머거리야? 조금 전에 내가 얼마나 바쁜지 설명 했을 텐데? 일이나 해.,Ben je doof? Ik heb je net verteld hoe druk ik het heb. Ga terug aan het werk.,Er du døv? Jeg sa nettopp hvor opptatt jeg er. Tilbake til arbeidet.,"Głuchy jesteś? Mówiłem ci, że jestem zajęty. Wracaj do pracy.",Você é surdo? Já te disse que estou bem ocupado. Volte ao trabalho.,,Ești surd? Tocmai ți-am spus că sunt ocupat. Întoarce-te la muncă.,"Ты глухой, что ли? Я же сказал тебе, что я занят. Иди работать!",,Sağır mısın sen? Sana ne kadar meşgul olduğumu söyledim. İşinin başına dön. + \cy쉬운 일은 아니겠지만, 일단 한번 해보자고.","Wat denk je, dat we op sokken staan?","Hva tror du, at vi har sokker?","Co ty myślisz, że wysyłamy skarpetki?","Ora, você acha que usamos só as nossas meias?",,"Ce crezi, că suntem apărați pe șosete?","А ты думал, мы носки грузим?",,"Vad tror du, vi har inte tillräckligt med strumpor?","Ne düşünüyorsun, çorapları yedekledik mi?" +What kind of weapons?,TXT_RPLY0_SCRIPT04_D31836_WHATK,〃,,,Jaké zbraně?,Hvilken slags våben?,Was für Waffen?,,Kiu speco de armiloj?,¿Qué clase de armas?,,Minkälaisia aseita?,Quel type d'armes?,Miféle fegyverek?,Che tipo di armi?,どんな武器だ?,어떤 신무기?,Wat voor wapens?,Hva slags våpen?,Jakie bronie?,Que tipo de armas?,,Ce fel de arme?,Какое оружие?,,Vilken typ av vapen?,Ne tür silahlar? +Are you deaf? I just told you how busy I am. Get back to work.,TXT_DLG_SCRIPT04_D33352_AREYO,〃,,,"Jsi hluchý? Už jsem ti řekl, jak jsem zaneprázdněný. Vrať se do práce.","Er du døv? Jeg har lige fortalt dig, hvor travlt jeg har. Kom tilbage til arbejdet.","Bist du taub? Ich hab dir dock gerade gesagt, wie beschäftigt ich bin. Geh zurück an die Arbeit.",,"Ĉu vi estas surda? Mi ĵus diris, kiel okupata mi estas. Reiru al via laboro.",¿Estás sordo? Ya te he dicho lo ocupado que estoy. Vuelve al trabajo.,¿Estás sordo? Ya te dije lo ocupado que estoy. Vuelve al trabajo.,"Kuuroko olet? Juurihan kerroin, kuinka kiire minulla on. Mene takaisin töihisi.","Vous êtes sourd? Je viens de vous dire que je suis occupé, retournez au travail!",Süket vagy? Most mondtam el mennyire elfoglalt vagyok. Húzz vissza dolgozni!,Ma sei sordo? Ti ho appena detto quanto sono occupato. Torna al lavoro.,難聴か? 私は、忙しい、から、仕事に、戻れ。,귀머거리야? 조금 전에 내가 얼마나 바쁜지 설명 했을 텐데? 일이나 해.,Ben je doof? Ik heb je net verteld hoe druk ik het heb. Ga terug aan het werk.,Er du døv? Jeg sa nettopp hvor opptatt jeg er. Tilbake til arbeidet.,"Głuchy jesteś? Mówiłem ci, że jestem zajęty. Wracaj do pracy.",Você é surdo? Já te disse que estou bem ocupado. Volte ao trabalho.,,Ești surd? Tocmai ți-am spus că sunt ocupat. Întoarce-te la muncă.,"Ты глухой, что ли? Я же сказал тебе, что я занят. Иди работать!",,Är du döv? Jag berättade precis hur upptagen jag är. Fortsätt jobba.,Sağır mısın sen? Sana ne kadar meşgul olduğumu söyledim. İşinin başına dön. Who are you? Only clearance level two personnel are permitted in this area.,TXT_DLG_SCRIPT04_D34868_WHOAR,MAP04: Reactor Core → Southern alarm green door,,,Kdo jsi? Pouze pracovníci druhé úrovně sem mají povolen přístup.,Hvem er du? Kun personale på sikkerhedsniveau to har adgang til dette område.,Wer bist du? Nur Personal mit Zugangsstufe 2 hst hier Zutritt.,,Kiu vi estas? Nur dunivelaj laboristoj estas permesataj ĉi tie.,¿Quién eres? Solo el personal con permiso de nivel dos puede estar aquí.,,Kuka sinä olet? Vain kakkoskulkuluvan omaavalla henkilöstöllä on pääsy tälle alueelle.,Qui êtes vous? Seuls les personnes avec un niveau d'autorisation deux peuvent accéder à cette zone.,Te meg ki vagy? Csak kettes szintű engedéllyel rendekezők jöhetnek be ide.,Chi sei? Solo il personale con l'autorizzazione di livello due può stare in questa sezione.,"誰だ? レベル2のクリアランスを持たない者は -ここに来てはいけないが。",넌 누구지? 이곳은 2급 인원만이 출입할 수 있다.,Wie ben jij? Alleen ontruimingsniveau twee personeel is toegestaan in dit gebied.,Hvem er du? Bare personell med klareringsnivå to har adgang til dette området.,Kim jesteś? Tylko personel posiadający zezwolenie poziomu drugiego może tu przebywać.,Quem é você? Só funcionários com permissão nível 2 podem entrar nesta área.,,Cine ești? Doar personalul cu nivel 2 de acces are voie în zona aceasta.,Ты кто такой? Только персоналу второго уровня допуска разрешено находиться в этой зоне.,,Kimsin sen? Bu bölgeye sadece ikinci seviye personel girebilir. -I'm the replacement worker.,TXT_RPLY0_SCRIPT04_D34868_IMTHE,〃,,,Jsem náhradník.,Jeg er afløseren.,Ich bin der Ersatzarbeiter.,,Mi estas la anstataŭanto.,Soy el sustituto.,,Olen täydennystyöntekijä.,Je suis le remplaçant.,Én vagyok a helyettes.,Sono il lavoratore sostitutivo.,代替要員だ。,후임 근무자로 왔습니다.,Ik ben de vervanger.,Jeg er vikaren.,Jestem tu na zastępstwo.,Eu sou o operário substituto.,,Sunt înlocuitorul muncitorului.,Я замещаю рабочего.,,Ben yedek işçiyim. +ここに来てはいけないが。",넌 누구지? 이곳은 2급 인원만이 출입할 수 있다.,Wie ben jij? Alleen ontruimingsniveau twee personeel is toegestaan in dit gebied.,Hvem er du? Bare personell med klareringsnivå to har adgang til dette området.,Kim jesteś? Tylko personel posiadający zezwolenie poziomu drugiego może tu przebywać.,Quem é você? Só funcionários com permissão nível 2 podem entrar nesta área.,,Cine ești? Doar personalul cu nivel 2 de acces are voie în zona aceasta.,Ты кто такой? Только персоналу второго уровня допуска разрешено находиться в этой зоне.,,Vem är du? Endast personal på nivå två får vistas i det här området.,Kimsin sen? Bu bölgeye sadece ikinci seviye personel girebilir. +I'm the replacement worker.,TXT_RPLY0_SCRIPT04_D34868_IMTHE,〃,,,Jsem náhradník.,Jeg er afløseren.,Ich bin der Ersatzarbeiter.,,Mi estas la anstataŭanto.,Soy el sustituto.,,Olen täydennystyöntekijä.,Je suis le remplaçant.,Én vagyok a helyettes.,Sono il lavoratore sostitutivo.,代替要員だ。,후임 근무자로 왔습니다.,Ik ben de vervanger.,Jeg er vikaren.,Jestem tu na zastępstwo.,Eu sou o operário substituto.,,Sunt înlocuitorul muncitorului.,Я замещаю рабочего.,,Jag är ersättningsarbetaren.,Ben yedek işçiyim. "About time you showed up. Go talk with Ketrick in the core. Oh, and take this key card. Don't want you getting shot on your first day, huh?",TXT_DLG_SCRIPT04_D36384_ABOUT,〃,,,"Už bylo na čase, aby ses objevil. Jdi si promluvit s Ketrickem v jádře. A vezmi si tuhle kartu. Přece by ses nechtěl nechat zastřelit hned svůj první den, ne?","Det var på tide, du dukkede op. Gå hen og snak med Ketrick i kernen. Åh, og tag dette nøglekort. Du skal ikke blive skudt på din første dag, hva'?","Wird auch Zeit, dass du hier erscheinst. Rede mit Ketrick im Reaktorkern, Und nimm diesen Schlüssel. Du willst ja wohl nicht gleich am ersten Tag erschossen werden, oder?",,"Vi finfine aperis. Iru paroli kun Ketrick en la kerno. Ha, kaj prenu ĉi tiun ŝlosil-karton; vi ne volas ricevi pafon dum via unua tago, ĉu?","Ya era hora. Ve a hablar con Ketrick en el núcleo. Ah, y toma esta tarjeta llave; no querrás que te peguen un tiro en tu primer día, ¿eh?",,"Jo oli aikakin ilmaantua. Mene ytimeen puhumaan Ketrickin kanssa. Ai niin, ja ota tämä avainkortti. Ei parane joutua ammutuksi heti ensimmäisenä työpäivänä, eikö niin?","Ah. Enfin. Il vous en a fallu, du temps! Allez parler avec Ketrick dans la section du cœur. Oh, et prenez ce passe. Vous ne voulez pas vous faire tirer dessus lors de votre premier jour, non?","Már ideje volt. Menj és beszélj Kettickkel a magban. Ja, és vidd magaddal ezt a mágneskártyát. Gondolom nem akarod magadat agyonlövetni az első napodon.","Finalmente sei arrivato. Vai a parlare a Ketrick nel nucleo. Ah, e prendi questa tessera chiave. Non è il caso di farsi sparare il primo giorno di lavoro, eh?","そろそろ来ると思っていたよ。コアにいる ケトリックに話しかけてくれ。 あとこのキーカードを受け取ってくれ。 -初日で撃たれたくないならな。","마침 잘 와주었군. 중심부에 있는 케트릭에게 가서 얘기하라. 아, 그리고 여기 키카드를 받아라. 첫날부터 총에 맞고 싶지는 않겠지, 응?","Het werd tijd dat je kwam opdagen. Ga praten met Ketrick in de kern. Oh, en neem deze sleutelkaart. Wil je niet dat je op je eerste dag wordt neergeschoten, huh?",På tide du dukket opp. Gå og snakk med Ketrick i kjernen. Og ta dette nøkkelkortet. Du vil vel ikke bli skutt på din første dag?,"W końcu jesteś. Idź, porozmawiaj z Ketrickiem przy rdzeniu. Oh, weź tą kartę-klucz. Nie chcesz chyba być zastrzelony podczas pierwszego dnia w pracy, co?","Já era hora de você aparecer. Vá falar com o Ketrick lá no núcleo. Ah, e leve este cartão de acesso. Você não vai querer levar um tiro no primeiro dia, hein?",,"Era și timpul. Du-te și vorbește cu Ketrick în interiorul nucleului. Ah, și ia și cardul ăsta. Nu cred că vrei să fii împușcat în prima zi de lucru, eh?","Как раз вовремя. Иди поговори с Кетриком возле ядра реактора. О, и возьми эту карточку. Мы ведь не хотим, чтобы тебя подстрелили в первый же рабочий день?",,"Tam zamanında geldin. Git merkezdeki Ketrick ile konuş. Bu anahtar kartını da al. İlk gününde vurulmanı istemeyiz, değil mi?" -Where's the power crystal?,TXT_RPLY0_SCRIPT04_D36384_WHERE,〃,,,Kde je energetický krystal?,Hvor er kraftkrystallen?,Wo ist der Energiekristall?,,Kie estas la energia kristalo?,¿Dónde está el cristal de poder?,,Missä voimakristalli on?,Où se trouve le cristal du réacteur?,Hol van az erőkristály?,Dov'è il cristallo?,パワークリスタルは何処だ?,동력 수정체는 어디에 있죠?,Waar is het energiekristal?,Hvor er kraftkrystallen?,Gdzie jest kryształ mocy?,Onde fica o cristal de energia?,,Unde e cristalul de alimentare?,Где энергетический кристалл?,,Güç kristali nerede? +初日で撃たれたくないならな。","마침 잘 와주었군. 중심부에 있는 케트릭에게 가서 얘기하라. 아, 그리고 여기 키카드를 받아라. 첫날부터 총에 맞고 싶지는 않겠지, 응?","Het werd tijd dat je kwam opdagen. Ga praten met Ketrick in de kern. Oh, en neem deze sleutelkaart. Wil je niet dat je op je eerste dag wordt neergeschoten, huh?",På tide du dukket opp. Gå og snakk med Ketrick i kjernen. Og ta dette nøkkelkortet. Du vil vel ikke bli skutt på din første dag?,"W końcu jesteś. Idź, porozmawiaj z Ketrickiem przy rdzeniu. Oh, weź tą kartę-klucz. Nie chcesz chyba być zastrzelony podczas pierwszego dnia w pracy, co?","Já era hora de você aparecer. Vá falar com o Ketrick lá no núcleo. Ah, e leve este cartão de acesso. Você não vai querer levar um tiro no primeiro dia, hein?",,"Era și timpul. Du-te și vorbește cu Ketrick în interiorul nucleului. Ah, și ia și cardul ăsta. Nu cred că vrei să fii împușcat în prima zi de lucru, eh?","Как раз вовремя. Иди поговори с Кетриком возле ядра реактора. О, и возьми эту карточку. Мы ведь не хотим, чтобы тебя подстрелили в первый же рабочий день?",,"Det var på tiden att du dök upp. Gå och prata med Ketrick i kärnan. Och ta det här nyckelkortet. Jag vill inte att du blir skjuten på din första dag, va?","Tam zamanında geldin. Git merkezdeki Ketrick ile konuş. Bu anahtar kartını da al. İlk gününde vurulmanı istemeyiz, değil mi?" +Where's the power crystal?,TXT_RPLY0_SCRIPT04_D36384_WHERE,〃,,,Kde je energetický krystal?,Hvor er kraftkrystallen?,Wo ist der Energiekristall?,,Kie estas la energia kristalo?,¿Dónde está el cristal de poder?,,Missä voimakristalli on?,Où se trouve le cristal du réacteur?,Hol van az erőkristály?,Dov'è il cristallo?,パワークリスタルは何処だ?,동력 수정체는 어디에 있죠?,Waar is het energiekristal?,Hvor er kraftkrystallen?,Gdzie jest kryształ mocy?,Onde fica o cristal de energia?,,Unde e cristalul de alimentare?,Где энергетический кристалл?,,Var är kraftkristallen?,Güç kristali nerede? "If you don't get to work, you'll get shot anyway. Move your tunic.",TXT_DLG_SCRIPT04_D37900_IFYOU,〃,,,"Jestli se nepustíš do práce, zastřelí tě tak jako tak. Pohni tunikou!","Hvis du ikke går på arbejde, bliver du skudt alligevel. Flyt din kittel.","Wenn du nicht arbeitest, wirst du eh erschossen. Und nun beweg deinen Arsch!",,Vi ricevos pafon ankaŭ se vi ne eklaboras. Movu vian tunikon.,"Si no te pones a trabajar, te pegarán igual un tiro. Mueve tu túnica.","Si no te pones a trabajar, te van a pegar igual un tiro. Mueve tu túnica.","Jos et ryhdy töihin, sinut ammutaan kumminkin. Liikuta sitä ruhoasi.","Si vous ne partez pas travailler, vous allez vous faire tirer dessus de toutes manières. Bougez-vous les miches.","Ha nem dolgozol így is, úgy is agyonlőnek. Haladj már!","Se non ti metti subito a lavorare, ti spareranno ugualmente. Muovi la tua tuta.","今すぐ作業しないと奴等にバレて撃たれるぞ。 -さあ行け。",근무하러 안 가면 어차피 총살이야. 어서 일하러 가!,"Als je niet aan het werk gaat, wordt je toch al neergeschoten. Verplaats je tuniek.","Hvis du ikke kommer deg på jobb, blir du skutt uansett. Flytt tunikaen din.","Jeśli się nie weźmiesz do roboty, to tak czy siak cię zastrzelą. Rusz się.","Se você não trabalhar, você vai levar um tiro de qualquer jeito. Mexa-se.",,"Dacă nu te apuci de muncă, o să fii împuscat oricum. Miscă-ți tunica.","Если ты не приступишь к работе, тебя всё равно пристрелят. Шевелись!",,İşe gitmezsen zaten vurulacaksın. Tuniğini çek. +さあ行け。",근무하러 안 가면 어차피 총살이야. 어서 일하러 가!,"Als je niet aan het werk gaat, wordt je toch al neergeschoten. Verplaats je tuniek.","Hvis du ikke kommer deg på jobb, blir du skutt uansett. Flytt tunikaen din.","Jeśli się nie weźmiesz do roboty, to tak czy siak cię zastrzelą. Rusz się.","Se você não trabalhar, você vai levar um tiro de qualquer jeito. Mexa-se.",,"Dacă nu te apuci de muncă, o să fii împuscat oricum. Miscă-ți tunica.","Если ты не приступишь к работе, тебя всё равно пристрелят. Шевелись!",,Om du inte börjar jobba blir du skjuten ändå. Flytta din tunika.,İşe gitmezsen zaten vurulacaksın. Tuniğini çek. "I don't mean to sound alarmist, but if they keep pushing the power crystal this hard it's gonna flaw, and then shatter, and then *boom*! ...Just a thought.",TXT_DLG_SCRIPT04_D39416_IDONT,MAP04: Reactor Core → Northern alarm green door,,,"Nechci plašit, ale jestli budou krystal dál takhle protěžovat, tak se nalomí a pak roztříští a pak BUM! ...Jen tak přemýšlím.","Jeg vil ikke lyde alarmerende, men hvis de bliver ved med at presse energikrystallen så hårdt, så vil den flække, og så splintre, og så *bum*! ...Bare en tanke.","Ich will ja nicht herumunken, aber wenn sie den Kristall weiter so überstrapazieren, nimmt er Schaden, und dann *bumm*! ...nur so ein Gedanke.",,"Mi ne intencas soni alarme, sed se ili plue superŝargas la energian kristalon tiel multe, ĝi misfunkcios, poste ĝi rompiĝos kaj tiam «Bum!»... Por ke vi havu ian ideon.","No quiero sonar alarmante, pero si siguen forzando tanto el cristal de poder, primero fallará, luego se partirá y luego «¡Pum!»... Para que te hagas una idea.","No quiero sonar alarmante, pero si siguen forzando tanto el cristal de poder, primero va a fallar, luego se va a partir y luego «¡Pum!»... Para que te hagas una idea.","En halua kuulostaa pelon lietsojalta, mutta jos ne vaan jatkavat voimakristallin ajamista näin lujille, se säröytyy, sitten pirstoutuu, ja sitten pam! Ihan vain heittona.","Je n'ai pas envie d'être alarmiste, mais si ils continuent de mettre autant de tension sur le cristal du réacteur, il risque d'être endommagé, éclater, et puis boum! Enfin, c'est juste ce que je pense.","Nem akarok vészmadár lenni, de ha ennyire hajtják az erőkristályt, akkor megreped és eltörik, aztán meg *bumm*!...csak egy gondolat.","Non voglio sembrare un allarmista, ma se continuano a sovraccaricare il cristallo così tanto, ci sarà un errore, e il cristallo si spaccherà, e poi *boom*! ...Solo un pensiero.","オーダーがもしパワークリスタルに負荷を かけ続けていたら、いずれ限界でヒビが入って、 -砕けて、*ボーン*!...だと思うよ。","불안감을 조장하긴 싫지만, 동력 수정체를 지금처럼 심하게 다루면, 갑자기 균열이 나고, 조각나면서, 그리고 '쾅!' ... 그냥 그렇다고.","Ik wil geen paniekzaaier zijn, maar als ze zo hard op het energiekristal blijven duwen, gaat het scheuren, en dan versplinteren, en dan *boom*! ...Gewoon een gedachte.","Jeg mener ikke å høres alarmistisk ut, men hvis de fortsetter å presse kraftkrystallen så hardt, vil den sprekke, og så *boom*! ...Bare en tanke.","Nie chcę brzmieć jak panikarz, ale jeśli dalej tak bardzo będą zużywać kryształ mocy, to się zepsuje, pęknie, a potem *bum*! ...Tak myślę.","Não quero parecer alarmista, mas se eles continuarem pressionando tanto esse cristal de energia ele vai falhar, depois vai quebrar e então bum! ...Só minha opinião.",,"Nu vreau să par alarmist, dar... dacă o să continui să împingi cristalul atât de tare o să se crape, apoi sparge, iar apoi *bum*! ...Doar ziceam.","Не хочу показаться паникёром, но если продолжать так же сильно нагружать кристалл, он треснет, потом расколется, а потом «бум!».. Просто подумалось.",,"Endişeli görünmek istemem ama güç kristalini bu kadar zorlamaya devam ederlerse kusurlu olacak, sonra paramparça olacak ve sonra *boom*! ...Sadece bir düşünce." +砕けて、*ボーン*!...だと思うよ。","불안감을 조장하긴 싫지만, 동력 수정체를 지금처럼 심하게 다루면, 갑자기 균열이 나고, 조각나면서, 그리고 '쾅!' ... 그냥 그렇다고.","Ik wil geen paniekzaaier zijn, maar als ze zo hard op het energiekristal blijven duwen, gaat het scheuren, en dan versplinteren, en dan *boom*! ...Gewoon een gedachte.","Jeg mener ikke å høres alarmistisk ut, men hvis de fortsetter å presse kraftkrystallen så hardt, vil den sprekke, og så *boom*! ...Bare en tanke.","Nie chcę brzmieć jak panikarz, ale jeśli dalej tak bardzo będą zużywać kryształ mocy, to się zepsuje, pęknie, a potem *bum*! ...Tak myślę.","Não quero parecer alarmista, mas se eles continuarem pressionando tanto esse cristal de energia ele vai falhar, depois vai quebrar e então bum! ...Só minha opinião.",,"Nu vreau să par alarmist, dar... dacă o să continui să împingi cristalul atât de tare o să se crape, apoi sparge, iar apoi *bum*! ...Doar ziceam.","Не хочу показаться паникёром, но если продолжать так же сильно нагружать кристалл, он треснет, потом расколется, а потом «бум!».. Просто подумалось.",,"Jag vill inte låta alarmistisk, men om de fortsätter att trycka på kraftkristallen så här hårt kommer den att flaga, och sedan splittras, och sedan *boom*! ...Bara en tanke.","Endişeli görünmek istemem ama güç kristalini bu kadar zorlamaya devam ederlerse kusurlu olacak, sonra paramparça olacak ve sonra *boom*! ...Sadece bir düşünce." "Let me be quite clear. If this terminal locks up again, the coolant level will drop and we'll all have to answer to the Programmer. If we survive.",TXT_DLG_SCRIPT04_D40932_LETME,MAP04: Reactor Core → Southern alarm green door,,,"Vyjádřím se jasně: Jestli tenhle terminál znovu zamrzne, hladina chladiva poklesne a všichni se budeme muset zodpovídat Programátorovi. Pokud přežijeme.","Lad mig gøre det helt klart. Hvis denne terminal låser sig igen, vil kølevæskeniveauet falde, og vi vil alle skulle stå til ansvar over for programmøren. Hvis vi overlever.","Lass es mich klar und deutlich sagen. Wenn dieses Terminal nochmal abstürzt, sinkt der Kühlungsflüssigkeitspegel und wir dürfen uns vor dem Programmierer verantworten - wenn wir überleben.",,"Mi klagiru: se ĉi tiu terminalo paneas denove, la malvarmiga nivelo falos kaj ni ĉiuj devos respondeci pri tio al la Programisto... se ni supervivis.","Que quede claro: si esta terminal vuelve a colgarse, el nivel de refrigerante caerá y todos tendremos que dar la cara ante el Programador... si no morimos antes.","Que quede claro: si esta terminal vuelve a bloquearse, el nivel de refrigerante va a caer y todos vamos a tener que dar la cara ante el Programador... si no morimos antes.","Tehdäänpä asia selväksi. Jos tämä pääte vielä hyytyy, jäähdytysnestetaso laskee ja meillä on vähän selittelemistä Ohjelmoitsijalle. Sillä ehdolla, että selviämme.","Je vais être clair. Si ce terminal plante encore, les niveaux de liquide de refroidissement vont descendre et on aura tous à faire face au Programmeur. Si on survit, bien entendu.","Lényegretörő leszek. Ha a terminál még egyszer lezár, a hűtő folyadék szintje visszaesik, és felelülnek kell majd a Programozó színe előtt. Már ha túléljük.","Voglio essere chiaro su questo. Se questa console si blocca di nuovo, il livello di refrigerazione calerà bruscamente e dovremo risponderne di ciò al Programmtore. Se sopravviveremo.","万が一このターミナルがフリーズしたら、 冷却液の水位が下がってプログラマーと 対面しなければならないだろうな。 メルトダウンから生還すればの話だが。","이거 하나만 확실히 말하지. 이 시설이 또 고장 난다면, 냉각수 수치가 떨어질 거고 우리 둘 다 프로그래머에게 문책을 받을 거야. 만약 살아남는다면 말이지. - \cy어쩌라고. 아무도 프로그래머들 이야기는 안 듣는데.","Laat ik heel duidelijk zijn. Als deze terminal weer vastloopt, zal het koelmiddelniveau dalen en zullen we ons allemaal moeten verantwoorden tegenover de programmeur. Als we het overleven.","La meg gjøre det helt klart. Hvis denne terminalen låser seg igjen, vil kjølevæskenivået synke, og vi må alle stå til ansvar for programmereren. Hvis vi overlever.","Wyrażę się jasno. Jeśli terminal znów się zablokuje, to poziom płynu w chłodnicy spadnie i będziemy musieli za to odpowiadać przed Programistą. Jeśli wogóle przeżyjemy.","Só pra ficar bem claro. Se este terminal travar de novo, o nível de refrigeração vai cair e vamos nos ver com o Programador. Se nós sobrevivermos.",,"Ca să fiu înțeles. Dacă terminalul ăsta se blochează iar, nivelul răcirii va scădea și vom fi trași la răspundere de Programator. Dacă supraviețuim.","Давай говорить начистоту. Если этот терминал опять заклинит, то уровень охлаждения упадёт, и нам всем придётся отвечать перед Программистом — если выживем.",,"Açık konuşayım. Eğer bu terminal tekrar kilitlenirse, soğutma sıvısı seviyesi düşecek ve hepimiz Programcı'ya hesap vermek zorunda kalacağız. Eğer hayatta kalırsak." + \cy어쩌라고. 아무도 프로그래머들 이야기는 안 듣는데.","Laat ik heel duidelijk zijn. Als deze terminal weer vastloopt, zal het koelmiddelniveau dalen en zullen we ons allemaal moeten verantwoorden tegenover de programmeur. Als we het overleven.","La meg gjøre det helt klart. Hvis denne terminalen låser seg igjen, vil kjølevæskenivået synke, og vi må alle stå til ansvar for programmereren. Hvis vi overlever.","Wyrażę się jasno. Jeśli terminal znów się zablokuje, to poziom płynu w chłodnicy spadnie i będziemy musieli za to odpowiadać przed Programistą. Jeśli wogóle przeżyjemy.","Só pra ficar bem claro. Se este terminal travar de novo, o nível de refrigeração vai cair e vamos nos ver com o Programador. Se nós sobrevivermos.",,"Ca să fiu înțeles. Dacă terminalul ăsta se blochează iar, nivelul răcirii va scădea și vom fi trași la răspundere de Programator. Dacă supraviețuim.","Давай говорить начистоту. Если этот терминал опять заклинит, то уровень охлаждения упадёт, и нам всем придётся отвечать перед Программистом — если выживем.",,Låt mig vara helt tydlig. Om terminalen låser sig igen kommer kylvattennivån att sjunka och vi kommer alla att få stå till svars inför programmeraren. Om vi överlever.,"Açık konuşayım. Eğer bu terminal tekrar kilitlenirse, soğutma sıvısı seviyesi düşecek ve hepimiz Programcı'ya hesap vermek zorunda kalacağız. Eğer hayatta kalırsak." "You! Yeah, you. You aren't cleared for this area. Let me have your key card, fast. I'm in such a bad mood!",TXT_DLG_SCRIPT04_D42448_YOUYE,MAP04: Ketrick.,,,"Ty! Jo, ty. Pro tuhle oblast nemáš povolení. Ukaž mi svou kartu, hned. Mám hodně špatnou náladu!","Dig! Ja, dig. Du er ikke godkendt til dette område. Giv mig dit nøglekort, hurtigt. Jeg er i så dårligt humør!","Du da! Ja, du. Du hast keine Berechtigung für diesen Bereich. Gib mir deine Schlüsselkarte, und zwar schnell! Ich bin ja sowas von sauer!",,"Vi! Jes, vi! Vi ne laboras en ĉi tiu sektoro. Montru vian ŝlosil-karton, rapide! Mi estas en tre malbona humoro!","¡Tú! Sí, tú. No tienes permiso en esta área. A ver tu tarjeta llave, ¡y rápido, que estoy de muy mal humor!",,"Sinä! Niin, sinä. Sinulla ei ole lupaa tälle alueelle. Anna minulle avainkorttisi, joutuin. Olen niin huonolla päällä!","Vous! Oui, vous, vous, vous n'avez pas l'autorisation d'être dans cette zone! Donnez moi votre passe maintenant, et vite, je suis de sale humeur aujourd'hui!","Te! Igen, Te. Nincs jogod itt lenni. Add csak ide az igazolványodat. Nem jó kedvemben találtál meg.","Tu! Si, tu. Non hai l'autorizzazione per quest'area. Dammi la tua chiave tessera, presto! Ho un diavolo per capello!","お前!そうだお前だ。ここは立入禁止だ。 -IDカードを見せろ、早く。今機嫌が悪いんだ!","너! 그래, 너 말이야. 넌 여기에 들어올 수 있는 권한이 없어. 당장 네 키카드를 내놔. 나 지금 기분 더럽다고!","Jij! Ja, jij. Je bent niet vrij voor dit gebied. Geef me je sleutelkaart, snel. Ik ben in zo'n slecht humeur!","Du! Ja, du. Du er ikke klarert for dette området. Gi meg nøkkelkortet ditt, fort. Jeg er i så dårlig humør!","Ty! Tak, ty. Nie masz pozwolenia, aby tu przebywać. Pokaż mi swoją kartę-klucz, szybko. Nie jestem dziś w dobrym nastroju!","Você aí! É, você mesmo. Você não tem permissão para estar aqui. Me passa esse cartão logo de uma vez. Estou de péssimo humor.",,"Tu! Da, tu! Nu ai acces în zona asta. Dă-mi cardul tău, rapid. Sunt extrem de indispus!","Ты! Да, ты. У тебя нет сюда допуска. Давай свою карточку, быстро. Я сегодня в плохом настроении!",,"Sen! Evet, sen. Bu bölgeye giriş iznin yok. Anahtar kartını ver, çabuk. Çok kötü bir ruh halindeyim!" -"Here, here's my card.",TXT_RPLY0_SCRIPT04_D42448_HEREH,〃,,,"Tady, to je moje karta.","Her, her er mit kort.","Hier, hier ist meine Karte.",,Jen mia karto.,"Toma, aquí está mi tarjeta.",,Tässä on minun korttini.,Voilà mon passe.,"Parancsolj, itt a kártyám.",Ecco qua la mia tessera.,ほら、これがカードだ。,"자, 카드 여기 있어요.","Hier, hier is mijn kaart.","Her, her er kortet mitt.",Oto moja karta.,"Tome, aqui está o cartão.",,"Aici, aici e cardul.","Вот, вот моя карта.",,"İşte, işte kartım." +IDカードを見せろ、早く。今機嫌が悪いんだ!","너! 그래, 너 말이야. 넌 여기에 들어올 수 있는 권한이 없어. 당장 네 키카드를 내놔. 나 지금 기분 더럽다고!","Jij! Ja, jij. Je bent niet vrij voor dit gebied. Geef me je sleutelkaart, snel. Ik ben in zo'n slecht humeur!","Du! Ja, du. Du er ikke klarert for dette området. Gi meg nøkkelkortet ditt, fort. Jeg er i så dårlig humør!","Ty! Tak, ty. Nie masz pozwolenia, aby tu przebywać. Pokaż mi swoją kartę-klucz, szybko. Nie jestem dziś w dobrym nastroju!","Você aí! É, você mesmo. Você não tem permissão para estar aqui. Me passa esse cartão logo de uma vez. Estou de péssimo humor.",,"Tu! Da, tu! Nu ai acces în zona asta. Dă-mi cardul tău, rapid. Sunt extrem de indispus!","Ты! Да, ты. У тебя нет сюда допуска. Давай свою карточку, быстро. Я сегодня в плохом настроении!",,"Du! Ja, du. Du är inte godkänd för det här området. Ge mig ditt nyckelkort, snabbt. Jag är på så dåligt humör!","Sen! Evet, sen. Bu bölgeye giriş iznin yok. Anahtar kartını ver, çabuk. Çok kötü bir ruh halindeyim!" +"Here, here's my card.",TXT_RPLY0_SCRIPT04_D42448_HEREH,〃,,,"Tady, to je moje karta.","Her, her er mit kort.","Hier, hier ist meine Karte.",,Jen mia karto.,"Toma, aquí está mi tarjeta.",,Tässä on minun korttini.,Voilà mon passe.,"Parancsolj, itt a kártyám.",Ecco qua la mia tessera.,ほら、これがカードだ。,"자, 카드 여기 있어요.","Hier, hier is mijn kaart.","Her, her er kortet mitt.",Oto moja karta.,"Tome, aqui está o cartão.",,"Aici, aici e cardul.","Вот, вот моя карта.",,"Här, här är mitt kort.","İşte, işte kartım." This is garbage! Wait here. Oh screw it. Guards kill this intruder!,TXT_DLG_SCRIPT04_D43964_THISI,〃,,,"Blbost! Počkej tady. Á, kašlu na to. Stráže, zabte tohohle vetřelce!","Det her er affald! Vent her. Åh, pis. Vagter dræber denne ubudne gæst!","Das ist ja wohl die Höhe! Warte hier. Ach was. Wärter, tötet hn!",,"Ĉi tio estas rubaĵo! Atendu ĉi tie... Ba, al mil diabloj. Gardistoj, mortigu ĉi tiun entrudiĝanton!","¡Esto es basura! Espera aquí... Bah, ¿que más da? ¡Guardias, maten a este intruso!","¡Esto es basura! Espera aquí... Bah, al carajo. ¡Guardias, maten a este intruso!","Mitä pötyä tämä on? Odota tässä. Äh, ja paskat. Vartijat, tappakaa tämä tunkeilija!","C'est quoi cette blague? Attendez ici. Non, en fait, Gardes! Descendez cet intrus!","Ez egy szemét! Várj meg itt. Najó, nem kínlódok vele. Őrök nyírjátok ki a behatolót!","Questa è spazzatura! Aspetta qui. Ah, dannazione. Guardie, uccidete questo intruso!","なんだこのゴミは! いや待て。ああ、畜生。 -ガード、侵入者を殺せ!","이게 뭐야?! 잠깐... 이런 젠장. 경비, 여기 침입자를 쏴버려!","Dit is vuilnis! Wacht hier. Oh, laat maar. Bewakers doden deze indringer!","Dette er søppel! Vent her. Drit i det. Vakter, drep inntrengeren!","To nie karta, to śmieć! Czekaj. Pieprzyć to. Straże zabijcie tego intruza!","Que merda é essa? Fique aqui. Ah, que se dane. Guardas, matem este intruso!",,"Ăsta e gunoi! Așteaptă aici. Oh las-o baltă. Gardieni, ucideți intrusul!","Этой карточкой можно только подтереться! Жди здесь. А, к чёрту. Стража, здесь нарушитель! Убейте его!",,Bu çöp! Burada bekle. Siktir et. Gardiyanlar bu davetsiz misafiri öldürün! +ガード、侵入者を殺せ!","이게 뭐야?! 잠깐... 이런 젠장. 경비, 여기 침입자를 쏴버려!","Dit is vuilnis! Wacht hier. Oh, laat maar. Bewakers doden deze indringer!","Dette er søppel! Vent her. Drit i det. Vakter, drep inntrengeren!","To nie karta, to śmieć! Czekaj. Pieprzyć to. Straże zabijcie tego intruza!","Que merda é essa? Fique aqui. Ah, que se dane. Guardas, matem este intruso!",,"Ăsta e gunoi! Așteaptă aici. Oh las-o baltă. Gardieni, ucideți intrusul!","Этой карточкой можно только подтереться! Жди здесь. А, к чёрту. Стража, здесь нарушитель! Убейте его!",,"Det här är skräp! Vänta här. Åh, skit i det. Vakterna dödar den här inkräktaren!",Bu çöp! Burada bekle. Siktir et. Gardiyanlar bu davetsiz misafiri öldürün! "Work, sleep, get tortured, what a life. Say, you the replacement for the careless pit diver?",TXT_DLG_SCRIPT04_D45480_WORKS,MAP04: Reactor Core → Sammis,,,"Práce, spánek, poležení si na skřipci, dobrej život. Hele, ty jsi ta náhrada za toho neopatrného skokana?","Arbejde, sove, blive tortureret. Sikke et liv. Er du afløseren for den skødesløse pit dykker?","Arbeiten, schlafen, gefoltert werden, was für ein Leben. Sag mal, bist du der Ersatz für diesen sorglosen Grubentaucher?",,"Labori, dormi, esti torturata; kia vivo. Do ĉu vi venis anstataŭi la senatentan tru-plonĝinton?","Trabajar, dormir, ser torturado; qué vida. A ver, ¿eres el sustituto del distraído que hizo un clavado al pozo?",,"Raada, nuku, joudu kidutetuksi, mikä elämä. Sanopa, sinäkö olet sen huolimattoman kuilusukeltajan korvaaja?","Travail, sommeil, torture, quelle vie! Dites, vous êtes le remplaçant de l'unfortuné plongeur?","Munka, alvás, kínzás, milyen jó kis élet is ez. Figyelj csak, Te nem a figyelmetlen akna búvár helyettese vagy?","Lavoro, dormire e venire torturati, che vita. Dì un pò, sei tu il sostituto per l'incauto palombaro del pozzo?","働いて、寝て、処罰されて、なんて人生だ。 で、お前はあの冷却炉に落ちたアイツの -代替要員か?","일하고, 자고, 고문받고, 인생 참 멋지네. 자, 네가 그 부주의하게 추락사한 친구의 후임 맞지?","Werk, slaap, word gemarteld, wat een leven. Zeg, ben jij de vervanger van de onzorgvuldige pitduiker?","Jobbe, sove, bli torturert, for et liv! Er du avløseren for den uforsiktige dykkeren?","Spanie, praca, tortury, co za życie. Więc, jesteś tu na zastępstwo za tego co skoczył w przepaść?","Trabalhar, dormir, ser torturado. Que vida. Me diz uma coisa, você é o substituto daquele mergulhador de poço distraído?",,"Muncă, odihnă, tortură, ce mai viață. Și, zici că ești înlocuitorul înotătorului neatent?","Работа, сон и пытки, что за жизнь. Так ты заменяешь нашего беспечного ныряльщика?",,"Çalış, uyu, işkence gör, ne hayat ama. Söylesene, dikkatsiz çukur dalgıcının yerine sen mi geldin?" -"Yeah, can't wait to start.",TXT_RPLY0_SCRIPT04_D45480_YEAHC,〃,,,"Jo, už se nemůžu dočkat.","Ja, jeg kan ikke vente med at begynde.","Ja, ich kanns kaum erwarten, hier anzufangen.",,"Yes, kaj mi vere volas komenci.","Sí, y tengo ganas de empezar.",,"Kyllä, en malta odottaa.","Oui, j'ai hâte de commencer.","Igen, már alig várom, hogy kezdhessek.","Sì, non vedo l'ora di iniziare.",そうだ、もう待てない。,"네, 일이 정말 기대됩니다.","Ja, ik kan niet wachten om te beginnen.","Ja, jeg gleder meg til å begynne.","Tak, nie mogę się już doczekać.","É, mal posso esperar pra começar.",,"Deah, abia aștept să încep.","Да, поскорей бы уже за дело.",,"Evet, başlamak için sabırsızlanıyorum." -"Yeah, right. OK, get your ass to work.",TXT_DLG_SCRIPT04_D46996_YEAHR,〃,,,"Jo, jasně. Dobře, začni makat.","Ja, det er rigtigt. OK, få din røv på arbejde.","Na gut, schwing deinen Arsch zur Arbeit.",,"Jes, kompreneble. Nu, eklaboru.","Sí, claro. Bueno, ponte a trabajar.",,"Just joo. Selvä, raahaa ahterisi töiden ääreen.","Ouais, bien sûr. OK, allez bosser.","Ja persze már. Na, húzzál dolgozni inkább.","Già, certo. OK, muovi il culo e vai a lavorare.",わかった。さっさと働け。,"그래, 좋아. 일이나 하라고.","Ja, juist. Oké, ga aan het werk.","Ja, sikkert. OK, få ræva di på jobb.","Dobra. Ok, rusz swoją dupę do roboty.","Sim, sei. Tá, comece a trabalhar de uma vez.",,"Deah, sigur. Bine, hai, la muncă.","Да, конечно. Ладно, шуруй работать.",,"Evet, doğru. Tamam, kıçını kaldır da işe koyul." -Where's the crystal?,TXT_RPLY0_SCRIPT04_D46996_WHERE,〃,,,Kde je krystal?,Hvor er krystallen?,Wo ist der Kristall?,,Kie estas la kristalo?,¿Dónde está el cristal?,,Missä kristalli on?,Où est le cristal?,Hol van a kristály?,Dov'è il cristallo?,クリスタルは何処だ?,수정체는 어디에 있죠?,Waar is het kristal?,Hvor er krystallen?,Gdzie kryształ?,Onde fica o cristal?,,Unde e cristalul?,Где кристалл?,,Kristal nerede? +代替要員か?","일하고, 자고, 고문받고, 인생 참 멋지네. 자, 네가 그 부주의하게 추락사한 친구의 후임 맞지?","Werk, slaap, word gemarteld, wat een leven. Zeg, ben jij de vervanger van de onzorgvuldige pitduiker?","Jobbe, sove, bli torturert, for et liv! Er du avløseren for den uforsiktige dykkeren?","Spanie, praca, tortury, co za życie. Więc, jesteś tu na zastępstwo za tego co skoczył w przepaść?","Trabalhar, dormir, ser torturado. Que vida. Me diz uma coisa, você é o substituto daquele mergulhador de poço distraído?",,"Muncă, odihnă, tortură, ce mai viață. Și, zici că ești înlocuitorul înotătorului neatent?","Работа, сон и пытки, что за жизнь. Так ты заменяешь нашего беспечного ныряльщика?",,"Jobba, sova, bli torterad, vilket liv. Säg, är du ersättaren för den slarviga gropdykaren?","Çalış, uyu, işkence gör, ne hayat ama. Söylesene, dikkatsiz çukur dalgıcının yerine sen mi geldin?" +"Yeah, can't wait to start.",TXT_RPLY0_SCRIPT04_D45480_YEAHC,〃,,,"Jo, už se nemůžu dočkat.","Ja, jeg kan ikke vente med at begynde.","Ja, ich kanns kaum erwarten, hier anzufangen.",,"Yes, kaj mi vere volas komenci.","Sí, y tengo ganas de empezar.",,"Kyllä, en malta odottaa.","Oui, j'ai hâte de commencer.","Igen, már alig várom, hogy kezdhessek.","Sì, non vedo l'ora di iniziare.",そうだ、もう待てない。,"네, 일이 정말 기대됩니다.","Ja, ik kan niet wachten om te beginnen.","Ja, jeg gleder meg til å begynne.","Tak, nie mogę się już doczekać.","É, mal posso esperar pra começar.",,"Deah, abia aștept să încep.","Да, поскорей бы уже за дело.",,"Ja, jag längtar efter att få börja.","Evet, başlamak için sabırsızlanıyorum." +"Yeah, right. OK, get your ass to work.",TXT_DLG_SCRIPT04_D46996_YEAHR,〃,,,"Jo, jasně. Dobře, začni makat.","Ja, det er rigtigt. OK, få din røv på arbejde.","Na gut, schwing deinen Arsch zur Arbeit.",,"Jes, kompreneble. Nu, eklaboru.","Sí, claro. Bueno, ponte a trabajar.",,"Just joo. Selvä, raahaa ahterisi töiden ääreen.","Ouais, bien sûr. OK, allez bosser.","Ja persze már. Na, húzzál dolgozni inkább.","Già, certo. OK, muovi il culo e vai a lavorare.",わかった。さっさと働け。,"그래, 좋아. 일이나 하라고.","Ja, juist. Oké, ga aan het werk.","Ja, sikkert. OK, få ræva di på jobb.","Dobra. Ok, rusz swoją dupę do roboty.","Sim, sei. Tá, comece a trabalhar de uma vez.",,"Deah, sigur. Bine, hai, la muncă.","Да, конечно. Ладно, шуруй работать.",,"Ja, visst. Okej, sätt dig i arbete.","Evet, doğru. Tamam, kıçını kaldır da işe koyul." +Where's the crystal?,TXT_RPLY0_SCRIPT04_D46996_WHERE,〃,,,Kde je krystal?,Hvor er krystallen?,Wo ist der Kristall?,,Kie estas la kristalo?,¿Dónde está el cristal?,,Missä kristalli on?,Où est le cristal?,Hol van a kristály?,Dov'è il cristallo?,クリスタルは何処だ?,수정체는 어디에 있죠?,Waar is het kristal?,Hvor er krystallen?,Gdzie kryształ?,Onde fica o cristal?,,Unde e cristalul?,Где кристалл?,,Var är kristallen?,Kristal nerede? "Go talk to Ketrick. Bring the walkway up using the switches, then use this I.D. For the elevator.",TXT_DLG_SCRIPT04_D48512_GOTAL,〃,,,Promluv si s Ketrickem. Tlačítkem zvedni schodiště a ve výtahu pak použij tuhle kartu.,"Gå hen og snak med Ketrick. Få gangbroen op ved hjælp af kontakterne, og brug så dette ID til elevatoren.","Rede mit Ketrick. Hebe den Steg mit den Schaltern an, dann benutze dies ID für den Lift.",,Parolu al Ketrick. Levu la ponton per ĉi tiuj ŝaltiloj kaj tiam ekagigu la lifton per ĉi tiu identigilo.,Habla con Ketrick. Usa estos interruptores para alzar la pasarela y luego esta identificación con el ascensor.,,Mene puhumaan Ketrickin kanssa. Tuo kulkusilta vivuilla ylös ja sitten käytä hissiin tätä tunnistetta.,"Parlez à Ketrick. Vous pouvez étendre la coursive avec les boutons, puis utilisez ce passe pour l'ascenseur.","Menj és beszélj Ketrickkel. A kapcoslókkal emeld meg a szerelőhidat, majd használd ezt az igazolványt a lifthez.","Devi parlare con Ketrick. Usa i pulsanti per alzare la passarella, dopodiché usa questa tessera d'identificazione per l'ascensore. ","ケトリックと話をしろ。 隣のスイッチで道を上げこのカードで -エレベーターに乗るんだ。","케트릭에게 물어봐. 스위치를 눌러서 진입로를 올리고, 이 신분증을 써서 승강기를 타고 올라가.",Ga met Ketrick praten. Breng de loopbrug naar boven met behulp van de schakelaars en gebruik dan deze I.D. voor de lift.,"Snakk med Ketrick. Få gangbroen opp med bryterne, og bruk dette kortet til heisen.","Idź porozmawiać z Ketrickiem. Podnieś chodnik za pomocą przełączników, potem użyj tego identyfikatora do windy.",Fale com o Ketrick. Use os interruptores para fazer a passarela subir e depois use esta identificação para o elevador.,,"Discută cu Ketrick. Ridică pasarela cu ajutorul butoanelor, apoi folosește legitimația asta pentru lift.","Сходи поговори с Кетриком. Используй переключатели на стене, чтобы подняться наверх, потом запусти лифт этой карточкой.",,"Git Ketrick'le konuş. Anahtarları kullanarak geçidi yukarı getir, sonra asansör için bu kimliği kullan." -Where's the crystal again?,TXT_RPLY0_SCRIPT04_D48512_WHERE,〃,,,"Můžeš mi znovu říct, kde je krystal?",Hvor er krystallen igen?,"Wo ist der Kristall, nochmal?",,"Mi demandis, kie estas la kristalo.","De nuevo, ¿dónde está el cristal?",,Missä kristalli olikaan?,Mais où est le cristal?,Hol is van a kristály?,E il cristallo dov'è?,いいからクリスタルは何処だ?,수정체가 어디에 있다고요?,Waar is het kristal ook alweer?,Hvor er krystallen igjen?,"Jeszcze raz, gdzie kryształ?",Onde fica o cristal mesmo?,,Unde ziceai că e cristalul?,Ещё раз: где кристалл?,,Kristal yine nerede? -"None of your business, go talk to Ketrick.",TXT_DLG_SCRIPT04_D50028_NONEO,〃,,,"Do toho ti nic není, jdi si promluvit s Ketrickem.","Det rager ikke dig, gå hen og snak med Ketrick.","Geht dich nichts an, und jetzt rede mit Ketrick.",,Tio ne estas via afero. Iru paroli al Ketrick.,No es asunto tuyo. Ve a hablar con Ketrick.,,"Ei kuulu sinulle, puhu Ketrickille.",Ca ne vous concerne pas. Allez voir Ketrick.,"Semmi közöd hozzá, menj beszélj Ketrickkel.","Non sono affari tuoi, vai a parlare con Ketrick.",大きなお世話だ、ケトリックと話をしろ。,"상관 말고, 케트릭에게 물어봐.","Gaat je niets aan, ga met Ketrick praten.",Ikke din sak. Snakk med Ketrick.,"Nie twój interes, idź porozmawiać z Ketrickiem.",Não é da sua conta. Vá falar com o Ketrick.,,Nu-i treaba ta. Discută cu Ketrick.,Не твоё дело. Иди поговори с Кетриком.,,"Seni ilgilendirmez, git Ketrick'le konuş." -Ok.,TXT_RPLY0_SCRIPT04_D50028_OK,〃,,,Dobře.,Ok.,Ok.,,Bone.,Bueno.,,OK.,OK.,OK.,OK.,オーケー,알겠습니다.,OKÉ.,GREIT.,Ok.,Ok.,,Bine.,Понял.,,TAMAM. +エレベーターに乗るんだ。","케트릭에게 물어봐. 스위치를 눌러서 진입로를 올리고, 이 신분증을 써서 승강기를 타고 올라가.",Ga met Ketrick praten. Breng de loopbrug naar boven met behulp van de schakelaars en gebruik dan deze I.D. voor de lift.,"Snakk med Ketrick. Få gangbroen opp med bryterne, og bruk dette kortet til heisen.","Idź porozmawiać z Ketrickiem. Podnieś chodnik za pomocą przełączników, potem użyj tego identyfikatora do windy.",Fale com o Ketrick. Use os interruptores para fazer a passarela subir e depois use esta identificação para o elevador.,,"Discută cu Ketrick. Ridică pasarela cu ajutorul butoanelor, apoi folosește legitimația asta pentru lift.","Сходи поговори с Кетриком. Используй переключатели на стене, чтобы подняться наверх, потом запусти лифт этой карточкой.",,"Gå och prata med Ketrick. Ta upp gångvägen med hjälp av växlarna, använd sedan det här ID-kortet för hissen.","Git Ketrick'le konuş. Anahtarları kullanarak geçidi yukarı getir, sonra asansör için bu kimliği kullan." +Where's the crystal again?,TXT_RPLY0_SCRIPT04_D48512_WHERE,〃,,,"Můžeš mi znovu říct, kde je krystal?",Hvor er krystallen igen?,"Wo ist der Kristall, nochmal?",,"Mi demandis, kie estas la kristalo.","De nuevo, ¿dónde está el cristal?",,Missä kristalli olikaan?,Mais où est le cristal?,Hol is van a kristály?,E il cristallo dov'è?,いいからクリスタルは何処だ?,수정체가 어디에 있다고요?,Waar is het kristal ook alweer?,Hvor er krystallen igjen?,"Jeszcze raz, gdzie kryształ?",Onde fica o cristal mesmo?,,Unde ziceai că e cristalul?,Ещё раз: где кристалл?,,Var är kristallen igen?,Kristal yine nerede? +"None of your business, go talk to Ketrick.",TXT_DLG_SCRIPT04_D50028_NONEO,〃,,,"Do toho ti nic není, jdi si promluvit s Ketrickem.","Det rager ikke dig, gå hen og snak med Ketrick.","Geht dich nichts an, und jetzt rede mit Ketrick.",,Tio ne estas via afero. Iru paroli al Ketrick.,No es asunto tuyo. Ve a hablar con Ketrick.,,"Ei kuulu sinulle, puhu Ketrickille.",Ca ne vous concerne pas. Allez voir Ketrick.,"Semmi közöd hozzá, menj beszélj Ketrickkel.","Non sono affari tuoi, vai a parlare con Ketrick.",大きなお世話だ、ケトリックと話をしろ。,"상관 말고, 케트릭에게 물어봐.","Gaat je niets aan, ga met Ketrick praten.",Ikke din sak. Snakk med Ketrick.,"Nie twój interes, idź porozmawiać z Ketrickiem.",Não é da sua conta. Vá falar com o Ketrick.,,Nu-i treaba ta. Discută cu Ketrick.,Не твоё дело. Иди поговори с Кетриком.,,"Det angår inte dig, gå och prata med Ketrick.","Seni ilgilendirmez, git Ketrick'le konuş." +Ok.,TXT_RPLY0_SCRIPT04_D50028_OK,〃,,,Dobře.,,,,Bone.,Bueno.,,OK.,OK.,OK.,OK.,オーケー,알겠습니다.,OKÉ.,GREIT.,,,,Bine.,Понял.,,OKEJ.,TAMAM. "If it's busy work you want, go stare at that screen for a while, it'll bore you to tears.",TXT_DLG_SCRIPT04_D51544_IFITS,"〃 (bored to tears = extremely bored)",,,"Jestli chceš tvrdou práci, jdi na chvíli zírat na tamtu obrazovku. Unudí tě to k pláči.","Hvis det er travlt arbejde du vil have, så gå hen og stirr på den skærm i et stykke tid, den vil kede dig til tårer.","Wenn du richtige Arbeit willst, dann starre mal für längere Zeit auf den Bildschirm. Das langweilt zu Tränen.",,"Se penigan laboron vi serĉas, iru rigardi tiun ekranon dum momento: vi mortos de enuo.","Si es trabajo duro lo que buscas, ve a mirar esa pantalla un rato: te morirás de aburrimiento.",,"Jos puuhastelua kaipaat, niin mene tuijottamaan tuota ruutua joksikin aikaa. Eiköhän se ikävystytä sinut kuoliaaksi.","Si vous voulez un boulot éreintant, allez fixer cet écran pour quelques heures. Ca va vous ennuyer jusqu'a en pleurer.","Ha nagyon el akarod magad foglalni, akkor bámuld azt a monitort egy darabig. Halálra fog untatni.","Se vuoi un lavoro pesante, ti basta guardare quello schermo per un pò, e ti annoierai a morte.","忙しい仕事を望んでいるなら、 そのスクリーンをしばらく見ていなさい、 -飽きて涙が浮かぶでしょう。",만약 더 쉬운 일을 원한다면 저 차단기를 계속 쳐다봐봐. 눈물 나도록 지루해 죽을걸.,"Als het druk werk is dat je wilt, ga dan een tijdje naar dat scherm staren, het zal je tot tranen toe vervelen.","Hvis du vil ha mye å gjøre, kan du stirre på skjermen en stund. Den kjeder deg i hjel.","Jeśli szukasz ciężkiej pracy, to idź pogapić się przez chwilę w ten ekran, zanudzi cię to na śmierć.","Se você quer ficar bem ocupado, fique olhando para essa tela por um tempo. Você vai morrer de tédio.",,"Dacă vrei treabă pe bune, du-te holbează-te la ecranul ăla o vreme, te va plictisii până la lacrimi.","Если ты хочешь работы от ушей до пят, попялься какое-то время на тот экран... Наскучит до слёз.",,"Eğer meşgul olmak istiyorsan, git bir süre şu ekrana bak, seni gözyaşlarına boğacak." +飽きて涙が浮かぶでしょう。",만약 더 쉬운 일을 원한다면 저 차단기를 계속 쳐다봐봐. 눈물 나도록 지루해 죽을걸.,"Als het druk werk is dat je wilt, ga dan een tijdje naar dat scherm staren, het zal je tot tranen toe vervelen.","Hvis du vil ha mye å gjøre, kan du stirre på skjermen en stund. Den kjeder deg i hjel.","Jeśli szukasz ciężkiej pracy, to idź pogapić się przez chwilę w ten ekran, zanudzi cię to na śmierć.","Se você quer ficar bem ocupado, fique olhando para essa tela por um tempo. Você vai morrer de tédio.",,"Dacă vrei treabă pe bune, du-te holbează-te la ecranul ăla o vreme, te va plictisii până la lacrimi.","Если ты хочешь работы от ушей до пят, попялься какое-то время на тот экран... Наскучит до слёз.",,"Om du vill ha ett arbete, gå och stirra på den där skärmen ett tag, den kommer att tråka ut dig till tårar.","Eğer meşgul olmak istiyorsan, git bir süre şu ekrana bak, seni gözyaşlarına boğacak." The almighty Programmer is so paranoid of infiltration that he's locked up the computer core. How am I supposed to get my work done? The only way in is the suicide run.,TXT_DLG_SCRIPT04_D53060_THEAL,MAP04: Reactor Core → Southern alarm green door,,,"Náš všemocný Programátor je tak paranoidní, že uzamknul počítačové jádro. Jak mám takhle pracovat? Jediná cesta tam je skrz běh pro sebevrahy.","Den almægtige programmør er så paranoid over for infiltration, at han har låst computerkernen inde. Hvordan skal jeg få mit arbejde gjort? Den eneste vej ind er selvmordsruten.","Der allmächtige Programmierer ist so paranoid, dass er den Computer blockiert hat. Wie soll ich so meine Arbeit machen? Der einzige weg wäre über den Selbstmordpfad.",,"La ĉiopova Programisto estas tiel paranoja pri ebla enŝoviĝo, ke li ŝlosis la komputilan kernon. Kiel mi supozeble laboros? La ununura ŝlosilo estas la vivo-riska vojo.",El todopoderoso Programador tiene tanta paranoia de infiltración que hasta ha cerrado el núcleo del ordenador. ¿Cómo se supone que voy a hacer mi trabajo? La única forma es por la vía suicida.,El todopoderoso Programador tiene tanta paranoia de infiltración que hasta cerró el núcleo de la computadora. ¿Cómo se supone que voy a hacer mi trabajo? La única forma es por la vía suicida.,"Kaikkivoipa Ohjelmoitsija on niin vainoharhainen soluttautujista, että on lukinnut tietokoneen ytimen. Miten minä muka työni saan tehdyksi? Ainoa tie sisään on itsemurhareitti.","Ce tout-puissant Programmeur est tellement paranoïaque au sujet des infiltrations qu'il a mis le cœur informatique sous les verrous. Comment je peux faire mon travail maintenant? Si je veux essayer d'y entrer, faut que j'utilise le couloir du suicide!","A mindenható Programozó annyira tart a behatolóktól, hogy elzárta a számítógép magot. Hogy kéne így végeznem a munkámat. Az egyetlen lehetőség a halál inga.","L'onnipotente Programmatore è così paranoico per le infiltrazioni che ha bloccato l'ingresso al nucleo del computer. Come posso finire il mio lavoro? L'unico modo per entrare è tramite il ""percorso suicida"".","プログラマー様は潜入されるのを 非常に恐れているらしく、コンピューターコアの ロックを厳重にするよう命じたんだ。 -どうやってあんな危ない所で仕事するんだ?",위대하신 프로그래머님이 침입에 대해 너무나도 불안해하셔서 컴퓨터 중심부를 락다운 시켰어. 일이 점점 더 어려워지고 있는 것 같아. 내 생각엔 자살기행을 또 해봐야겠어.,De almachtige Programmeur is zo paranoïde van infiltratie dat hij de computerkern heeft afgesloten. Hoe moet ik mijn werk gedaan krijgen? De enige manier om binnen te komen is de zelfmoordactie.,Den allmektige programmereren er så paranoid for infiltrasjon at han har låst datakjernen. Hvordan skal jeg få arbeidet mitt gjort? Den eneste veien inn er selvmordsløpet.,"Wszechmocny Programista ma paranoję na punkcie infiltracji tak bardzo, że zamknął rdzeń komputera. Jakim cudem mam skończyć pracę? Jedyną drogą, by tam się dostać jest ścieżka samobójców.",O todo-poderoso Programador é tão paranóico com infiltração que ele travou o núcleo de computação. Como que eu vou fazer o meu trabalho? A único jeito é a maneira suicida.,,Atotputernicul Programator e atât de paranoic în privința infiltrărilor încât a încuiat nucleul calculatorului. Cum mi-aș putea face treaba? Singura cale de intrare e sinucidere.,"Всемогущий Программист настолько боится проникновения, что закрыл компьютерную комнату. И как мне теперь выполнять свою работу? Есть один способ пройти туда, но это чистое самоубийство.",,Yüce Programcı sızma konusunda o kadar paranoyak ki bilgisayar çekirdeğini kilitledi. İşimi nasıl yapacağım? İçeri girmenin tek yolu intihar koşusu. -Suicide run? What's that?,TXT_RPLY0_SCRIPT04_D53060_SUICI,〃,,,Běh pro sebevrahy? Co to je?,Selvmordsruten? Hvad er det?,"Selbstmordpfad, was ist das?",,Ĉu vivo-riska vojo? Kio estas tio?,¿Vía suicida? ¿Cómo es eso?,,Itsemurhareitti? Mikä se on?,Couloir du suicide? Comment ça?,Halál inga? Az meg mi a fene?,"""Percorso suicida""? Che roba è?",危ない?どういう事だ?,자살기행? 그건 뭡니까?,Zelfmoordactie? Wat is dat?,Selvmordsløp? Hva er det?,Ścieżka samobójców? Co to?,Maneira suicida? O que é isso?,,O cale sinucigașă? Cum așa?,Самоубийство? О чём ты?,,İntihar koşusu mu? O da ne? +どうやってあんな危ない所で仕事するんだ?",위대하신 프로그래머님이 침입에 대해 너무나도 불안해하셔서 컴퓨터 중심부를 락다운 시켰어. 일이 점점 더 어려워지고 있는 것 같아. 내 생각엔 자살기행을 또 해봐야겠어.,De almachtige Programmeur is zo paranoïde van infiltratie dat hij de computerkern heeft afgesloten. Hoe moet ik mijn werk gedaan krijgen? De enige manier om binnen te komen is de zelfmoordactie.,Den allmektige programmereren er så paranoid for infiltrasjon at han har låst datakjernen. Hvordan skal jeg få arbeidet mitt gjort? Den eneste veien inn er selvmordsløpet.,"Wszechmocny Programista ma paranoję na punkcie infiltracji tak bardzo, że zamknął rdzeń komputera. Jakim cudem mam skończyć pracę? Jedyną drogą, by tam się dostać jest ścieżka samobójców.",O todo-poderoso Programador é tão paranóico com infiltração que ele travou o núcleo de computação. Como que eu vou fazer o meu trabalho? A único jeito é a maneira suicida.,,Atotputernicul Programator e atât de paranoic în privința infiltrărilor încât a încuiat nucleul calculatorului. Cum mi-aș putea face treaba? Singura cale de intrare e sinucidere.,"Всемогущий Программист настолько боится проникновения, что закрыл компьютерную комнату. И как мне теперь выполнять свою работу? Есть один способ пройти туда, но это чистое самоубийство.",,Den allsmäktige programmeraren är så paranoid för infiltration att han har låst in datorkärnan. Hur ska jag kunna få mitt arbete gjort? Den enda vägen in är självmordsresan.,Yüce Programcı sızma konusunda o kadar paranoyak ki bilgisayar çekirdeğini kilitledi. İşimi nasıl yapacağım? İçeri girmenin tek yolu intihar koşusu. +Suicide run? What's that?,TXT_RPLY0_SCRIPT04_D53060_SUICI,〃,,,Běh pro sebevrahy? Co to je?,Selvmordsruten? Hvad er det?,"Selbstmordpfad, was ist das?",,Ĉu vivo-riska vojo? Kio estas tio?,¿Vía suicida? ¿Cómo es eso?,,Itsemurhareitti? Mikä se on?,Couloir du suicide? Comment ça?,Halál inga? Az meg mi a fene?,"""Percorso suicida""? Che roba è?",危ない?どういう事だ?,자살기행? 그건 뭡니까?,Zelfmoordactie? Wat is dat?,Selvmordsløp? Hva er det?,Ścieżka samobójców? Co to?,Maneira suicida? O que é isso?,,O cale sinucigașă? Cum așa?,Самоубийство? О чём ты?,,Självmordslopp? Vad är det för något?,İntihar koşusu mu? O da ne? "It's a sure-fire way to get killed, but that's not important right now. Go down the lift if you're so inclined.",TXT_DLG_SCRIPT04_D54576_ITSAS,〃,,,"Je to zaručený způsob, jak zemřít, ale to teď není důležité. Sjeď výtahem dolů, jestli tě to tak zajímá.","Det er en sikker måde at blive dræbt på, men det er ikke vigtigt lige nu. Gå ned i elevatoren, hvis du har lyst til det.","Es ist ein todsicherer Weg um das Zeitliche zu segnen, aber das ist jetzt nicht wichtig. Nimm den Lift da drüben, wenn du Lust hast,und sieh selbst unten nach.",,"Ĝi estas neeraripova maniero morti, sed tio nun ne estas grava. Iru malsupren per la lifto se vi estas inklina al tio.","Es una forma segura de matarte, pero eso no importa ahora. Baja por el ascensor si te apetece.",,"Se on taattu keino tapattaa itsensä, mutta sillä ei ole nyt väliä. Mene hissillä alas, jos niin haluat.",C'est un moyen garanti de se tuer. Mais ce n'est pas important pour l'instant. Descendez avec l'acsenseur si vous voulez absolument essayer.,"Egy holtbiztos módja, hogy kinyírasd magadat, de ez most nem lényeges. Menj le a lifttel, ha annyira érdekel.","È un ottimo metodo per rimanere uccisi, ma questo non è importante al momento. Scendi con l'ascensore, se sei così incline.","下手に立ち入ると射殺されるが、 今それどころではない。 そんなに行きたいならリフトを降りるんだな。","말 그대로 죽기 쉬운 방법인데, 더 알 필요는 없어. 궁금해 미치겠다면 밑으로 내려가 봐. - \cy오, 내가 숨어있어서 다행이야. 무슨 뜻인지 알겠지?","Het is een zekere manier om gedood te worden, maar dat is nu niet belangrijk. Ga de lift af als je zo geneigd bent.","Det er en sikker måte å bli drept på, men det er ikke viktig akkurat nå. Ta heisen hvis du vil.","To jest niezawodna droga, by dać się zabić, ale to nie jest teraz ważne. Zjedź windą, jeśli jesteś w stanie to zrobić.","É uma forma garantida de ser morto, mas isso não importa agora. Desça pelo elevador se você está tão curioso.",,"E un mod garantat de a muri, dar nu contează acum. Ia liftul jos dacă ești curios.","Сунуться туда — верная гибель, но на данный момент это не важно. Спускайся на лифте, если не боишься.",,Öldürülmek için kesin bir yol ama şu an bunun bir önemi yok. İstiyorsan asansörden aşağı in. + \cy오, 내가 숨어있어서 다행이야. 무슨 뜻인지 알겠지?","Het is een zekere manier om gedood te worden, maar dat is nu niet belangrijk. Ga de lift af als je zo geneigd bent.","Det er en sikker måte å bli drept på, men det er ikke viktig akkurat nå. Ta heisen hvis du vil.","To jest niezawodna droga, by dać się zabić, ale to nie jest teraz ważne. Zjedź windą, jeśli jesteś w stanie to zrobić.","É uma forma garantida de ser morto, mas isso não importa agora. Desça pelo elevador se você está tão curioso.",,"E un mod garantat de a muri, dar nu contează acum. Ia liftul jos dacă ești curios.","Сунуться туда — верная гибель, но на данный момент это не важно. Спускайся на лифте, если не боишься.",,"Det är ett säkert sätt att bli dödad, men det är inte viktigt just nu. Gå ner i hissen om du vill.",Öldürülmek için kesin bir yol ama şu an bunun bir önemi yok. İstiyorsan asansörden aşağı in. Halt. No one gets through here without authorization from the Warden or the Governor.,TXT_DLG_SCRIPT05_D0_HALTN,MAP05: Door Guard.,,,Stát. Nikdo tudy nesmí projít bez povolení dozorce nebo guvernéra.,Stop. Ingen kommer igennem her uden tilladelse fra direktøren eller guvernøren.,Halt. Niemand kommt hier ohne Autorisierung des Direktors durch.,,Haltu. Neniu eniras sen permeso el la provoso aŭ la registo.,Alto. Nadie entra aquí sin autorización del carcelero o del gobernador.,,Seis. Kukaan ei pääse tästä läpi ilman vankilanjohtajan tai kuvernöörin lupaa.,Halte! Personne ne passe sans autorisation du gardien ou du gouverneur.,Áljj! Nem haladhat át senki sem az Igazgató vagy Kormányzó engedélye nélkül.,Fermo lì. Nessuno passa qua senza l'autorizzazione del direttore o del governatore.,"止まれ。所長か知事の許可が無い限り -立ち入る事は許さん。",멈춰라. 총독이나 간수장의 허락을 받지 않은 이상 그 누구도 입장할 수 없다.,Stop. Niemand komt hier door zonder toestemming van de directeur of de gouverneur.,Stopp. Ingen kommer gjennom her uten tillatelse fra direktøren eller guvernøren.,Stop. Nikt tu nie wejdzie bez zgody Naczelnika lub Gubernatora.,Alto. Ninguém passa por aqui sem autorização do Carcereiro ou do Governador.,,Stop. Nimeni nu trece pe aici fără autorizație de la Director sau Guvernator.,Стой. Никто не может пройти сюда без разрешения от тюремщика или губернатора.,,Durun. Müdür ya da Vali'nin izni olmadan kimse buradan geçemez. -"Here's my pass, let me in.",TXT_RPLY0_SCRIPT05_D0_HERES,〃,,,"Tady je moje propustka, pusť mě dál.","Her er mit pas, luk mig ind.","Hier is mein Pass, lassen Sie mich rein.",,Jen mia paspermeso; lasu min eniri.,Aquí está mi pase; déjeme entrar.,,Tässä lupani; päästäkää minut sisään.,Voilà mon passe. Laissez-moi entrer.,"Itt az igazolásom, engedj be.","Ecco la mia autorizzazione, fammi entrare.",これが許可証だ、入れてくれ。,여기 통행증입니다. 들여보내 주세요.,"Hier is mijn pas, laat me binnen.","Her er passet mitt, slipp meg inn.",Oto moja przepustka. Wpuść mnie.,Aqui está o meu passe. Deixe-me entrar.,,"Aici e legitimația, lasă-mă să intru.",Вот мой пропуск. Дай войти.,,"İşte kartım, beni içeri alın." +立ち入る事は許さん。",멈춰라. 총독이나 간수장의 허락을 받지 않은 이상 그 누구도 입장할 수 없다.,Stop. Niemand komt hier door zonder toestemming van de directeur of de gouverneur.,Stopp. Ingen kommer gjennom her uten tillatelse fra direktøren eller guvernøren.,Stop. Nikt tu nie wejdzie bez zgody Naczelnika lub Gubernatora.,Alto. Ninguém passa por aqui sem autorização do Carcereiro ou do Governador.,,Stop. Nimeni nu trece pe aici fără autorizație de la Director sau Guvernator.,Стой. Никто не может пройти сюда без разрешения от тюремщика или губернатора.,,Halt. Ingen kommer igenom här utan tillstånd från föreståndaren eller guvernören.,Durun. Müdür ya da Vali'nin izni olmadan kimse buradan geçemez. +"Here's my pass, let me in.",TXT_RPLY0_SCRIPT05_D0_HERES,〃,,,"Tady je moje propustka, pusť mě dál.","Her er mit pas, luk mig ind.","Hier is mein Pass, lassen Sie mich rein.",,Jen mia paspermeso; lasu min eniri.,Aquí está mi pase; déjeme entrar.,,Tässä lupani; päästäkää minut sisään.,Voilà mon passe. Laissez-moi entrer.,"Itt az igazolásom, engedj be.","Ecco la mia autorizzazione, fammi entrare.",これが許可証だ、入れてくれ。,여기 통행증입니다. 들여보내 주세요.,"Hier is mijn pas, laat me binnen.","Her er passet mitt, slipp meg inn.",Oto moja przepustka. Wpuść mnie.,Aqui está o meu passe. Deixe-me entrar.,,"Aici e legitimația, lasă-mă să intru.",Вот мой пропуск. Дай войти.,,"Här är mitt passerkort, släpp in mig.","İşte kartım, beni içeri alın." "OK, but talk only to the Warden.",TXT_DLG_SCRIPT05_D1516_OKBUT,〃,,,"Dobře, ale mluvte pouze s dozorcem.","Okay, men tal kun med direktøren.","Ok, aber reden Sie nur mit dem Direktor.",,"Bone, sed limu vin paroli kun la provoso.","Entendido, pero limítate a hablar con el carcelero.",,"Selvä, mutta puhu ainoastaan vankilanjohtajan kanssa.","D'accord, mais vous ne vous pouvez parler qu'au gardien.","OK, de csak az igazgatóval beszélj.","OK, ma parla solo con il direttore.",良いだろう、ただし話すのは所長とだけだ。,"알겠다. 하지만 간수장에게만 대화해라. - \cy뭐가 이리 불만이야. 나중에 얘 좀 꼭 처리해줘.","OK, maar praat alleen met de directeur.","OK, men snakk bare med direktøren.","Ok, ale rozmawiaj tylko z Naczelnikiem.","Ok, mas você só pode falar com o Carcereiro.",,"Bine, dar vorbești doar cu Directorul.","Проходи, но говори только с тюремщиком.",,"Tamam, ama sadece müdürle konuş." + \cy뭐가 이리 불만이야. 나중에 얘 좀 꼭 처리해줘.","OK, maar praat alleen met de directeur.","OK, men snakk bare med direktøren.","Ok, ale rozmawiaj tylko z Naczelnikiem.","Ok, mas você só pode falar com o Carcereiro.",,"Bine, dar vorbești doar cu Directorul.","Проходи, но говори только с тюремщиком.",,"Okej, men prata bara med fängelsedirektören.","Tamam, ama sadece müdürle konuş." "Do I look like the Warden to you? Keep moving, this area's off limits.",TXT_DLG_SCRIPT05_D3032_DOILO,〃 (After killing Montag),,,"Vypadám snad jako dozorce? Pokračuj dál, do této oblasti je vstup zakázán.","Ligner jeg direktøren? Fortsæt, dette område er forbudt område.","Sehe ich wie ein Direktor aus? Beweg dich, du hast hier nichts zu suchen.",,"Ĉu mi aspektas kiel la provoso laŭ vi? Foriru, ĉi tiu zono estas ekster la limoj.","¿Te parezco el carcelero? Ya vete, que esta área está fuera de los límites.",,Näytänkö minä sinulle vankilanjohtajalta? Jatka matkaasi; tähän alueeseen on pääsy kielletty.,"Je ressemble au gardien, à ton avis? Bouge, cette zone est hors-limites!","Úgy nézek ki, mint egy igazgató? Haladj tovább, ez a terület nem látogatható.","Ti sembro forse il direttore? Non stare fermo qua, quest'area è riservata al personale autorizzato.","俺がワーデンに見えるか? どっか行け、 この区域は立入禁止だ。","내가 친히 나서서 간수장을 찾아야겠나? 어서 움직여. 이곳은 통행 금지야. - \cy“이곳은 통행 금지야!” 웃기고 앉아있네.","Zie ik eruit als de directeur? Blijf bewegen, dit gebied is verboden terrein.","Ser jeg ut som direktøren? Gå videre, dette området er forbudt område.","Czy według ciebie wyglądam na Naczelnika? Rusz się, nikt nie ma wstępu na ten obszar.",Está achando que eu sou o Carcereiro? Suma daqui. Você não pode andar por aqui.,,"Ți se pare că eu sunt Directorul? Continuă să mergi, asta e o zonă fără acces.","Я что, похож на тюремщика? Двигай отсюда. Здесь закрытая территория!",,"Sana Müdür gibi mi görünüyorum? Devam edin, bu bölge yasak bölge." + \cy“이곳은 통행 금지야!” 웃기고 앉아있네.","Zie ik eruit als de directeur? Blijf bewegen, dit gebied is verboden terrein.","Ser jeg ut som direktøren? Gå videre, dette området er forbudt område.","Czy według ciebie wyglądam na Naczelnika? Rusz się, nikt nie ma wstępu na ten obszar.",Está achando que eu sou o Carcereiro? Suma daqui. Você não pode andar por aqui.,,"Ți se pare că eu sunt Directorul? Continuă să mergi, asta e o zonă fără acces.","Я что, похож на тюремщика? Двигай отсюда. Здесь закрытая территория!",,"Ser jag ut som fängelsedirektören? Fortsätt gå, det här området är förbjudet område.","Sana Müdür gibi mi görünüyorum? Devam edin, bu bölge yasak bölge." The Order's wrath will rain down on these servants until they beg for death.,TXT_DLG_SCRIPT05_D4548_THEOR,MAP05: Prison Guard.,,,Hněv Řádu dopadne na ty služebníky dokud nebudou prosit o smrt.,"Ordenens vrede vil regne ned over disse tjenere, indtil de tigger om at dø.","Der Zorn des Ordens wird auf diese Untergebenen herabregnen, bis sie um den Tod betteln.",,La tondro de La Ordono pluvos sur tiujn servantojn ĝis ili petegos pri morto.,La ira de La Orden caerá sobre estos sirvientes hasta que supliquen por su muerte.,La ira de La Orden va a caer sobre estos sirvientes hasta que supliquen por su muerte.,"Veljeskunnan viha säilyy näiden palvelijoiden yllä siihen asti, kunnes rukoilevat kuolemaa.",La colère de l'Ordre s'abattrera sur ces serviles miséreux jusqu'a ce qu'ils pleurent pour leur propre mort.,"A Rend haragja fog lesújtani ezekre a szolgákra, egészen addig amíg nem könyörögnek a halálért.",La furia dell'Ordine si riverserà su questi servi finché non chiederanno pietà!,"オーダーの怒りは、奴等が死を望むまで 止む事はない。","이 죄인들이 죽음을 바라기 전까지는 오더의 심판과 응징을 받을 것이다. - \cy아주 들떠있는 녀석이네.",De toorn van de Orde zal op deze bedienden neerdalen tot ze om de dood smeken.,Ordenens vrede vil regne over disse tjenerne til de trygler om å dø.,Gniew Zakonu spadnie jak deszcz na te sługi dopóki nie będą błagać o śmierć.,A ira da Ordem descerá a esses servos até eles implorarem pela morte.,,Furia Ordinului se va năpusti asupra servitorilor aceștia până vor cerși după moarte.,"Гнев Ордена обрушится на этих рабов, и они будут молить о смерти.",,"Tarikat'ın gazabı, ölüm için yalvarana kadar bu hizmetkarların üzerine yağacak." + \cy아주 들떠있는 녀석이네.",De toorn van de Orde zal op deze bedienden neerdalen tot ze om de dood smeken.,Ordenens vrede vil regne over disse tjenerne til de trygler om å dø.,Gniew Zakonu spadnie jak deszcz na te sługi dopóki nie będą błagać o śmierć.,A ira da Ordem descerá a esses servos até eles implorarem pela morte.,,Furia Ordinului se va năpusti asupra servitorilor aceștia până vor cerși după moarte.,"Гнев Ордена обрушится на этих рабов, и они будут молить о смерти.",,Ordens vrede kommer att regna över dessa tjänare tills de ber om döden.,"Tarikat'ın gazabı, ölüm için yalvarana kadar bu hizmetkarların üzerine yağacak." "I don't care if Mourel gave you a pass. This is my prison. My key is the only way in or out, and I'm not taking any chances. The Order does not tolerate mistakes.",TXT_DLG_SCRIPT05_D6064_IDONT,MAP05: Montag.,,,"Mě je jedno, že ti Mourel dal propustku. Tohle je moje vězení. Můj klíč je jediná cesta dovnitř a ven a já nehodlám nic riskovat. Řád netoleruje chyby.","Jeg er ligeglad med, om Mourel gav dig et fripas. Dette er mit fængsel. Min nøgle er den eneste vej ind eller ud, og jeg tager ingen chancer. Ordenen tolererer ikke fejltagelser.","Es ist mir egal ob Mourel Ihnen einen Pass gegeben hat. Das ist mein Gefängnis. Mein Schlüssel ist die einzige Möglichkeit, herein- oder herauszukommen, und ich riskiere da gar nichts. Der Orden toleriert keine Fehler.",,"Mi ne zorgas, ke Mourel donis paspermeson al vi. Ĉi tiu estas mia malliberejo; mia ŝlosilo estas la ununura maniero eniri aŭ eliri, kaj mi ne riskos min. La Ordono toleras nenian eraron.","No me importa que Mourel te haya dado un pase. Esta es mi prisión; mi llave es la única forma de entrar o salir, y no me arriesgaré. La Orden no tolera los fallos.","No me importa que Mourel te haya dado un pase. Esta es mi prisión; mi llave es la única forma de entrar o salir, y no me voy a arriesgar. La Orden no tolera los fallos.","En välitä mistään Mourelin luvista. Tämä on minun vankilani. Vain minun avaimellani pääsee sisään tai ulos, enkä aio ottaa yhtäkään riskiä. Veljeskunta ei suvaitse virheitä.","Je m'en fous que Mourel t'ai donné un passe. C'est ma prison. Ma clé est la seule façon d'entrer ou de sortir, et je ne prends pas de risques. L'Ordre ne tolère pas les erreurs.","Az sem érdekel ha Mourel adta a belépőt. Ez az Én börtönöm. Az Én kulcsom az egyetlen ami ki és bejutást enged, nem kockáztatok. A Rend nem igazán tolerálja a hibákat.","Non mi interessa se Mourel ti ha fatto entrare qua. Questa è la mia prigione. La mia chiave è l'unico modo per entrare o per uscire, e non ho intenzione di lasciare nulla al caso. L'Ordine non tollera errori.","モーレルが許可しようが構わん。 ここは私の刑務所だ。この鍵でしか絶対出入りは 出来ないし、渡すつもりも無い。 オーダーは失敗を許さないからな。 -",모렐 녀석이 너에게 통행증을 줬다 해도 신경 안 써. 이곳은 이 몸이 통치하는 감옥이다! 내가 가지고 있는 열쇠만 있으면 죄인들의 자유를 맘껏 조종할 수 있지. 오더는 절대로 실수 같은걸 용납하지 않아!,Het kan me niet schelen of Mourel je een pasje heeft gegeven. Dit is mijn gevangenis. Mijn sleutel is de enige weg naar binnen of buiten en ik neem geen enkel risico. De Orde tolereert geen fouten.,"Jeg blåser i om Mourel ga deg et passerseddel. Dette er mitt fengsel. Min nøkkel er den eneste veien inn eller ut, og jeg tar ingen sjanser. Ordenen tolererer ikke feil.","Nie obchodzi mnie to, że Mourel dał ci przepustkę. To moje więzienie. Tylko mój klucz pozwala wejść lub wyjść, i nie mam zamiaru ryzykować. Zakon nie toleruje błędów.",Eu não estou nem aí se o Mourel te deu um passe. Esta é a minha prisão. A única forma de entrar ou sair é com a minha chave e eu não estou a fim de arriscar. A Ordem não tolera erros.,,"Nu-mi pasă că Mourel ți-a dat o legitimație. Asta e închisoarea mea. Cheia mea e singura cale de intrare sau ieșire, și nu risc nimic. Ordinul nu tolerează greșeli.","Мне плевать, дал ли тебе Морел пропуск или нет. Это моя тюрьма, и без моего ключа не войти и не выйти. И я не хочу рисковать — Орден не прощает ошибок!",,Mourel'in sana izin vermesi umurumda değil. Burası benim hapishanem. İçeri girip çıkmanın tek yolu benim anahtarım ve işimi şansa bırakmayacağım. Tarikatın hataya tahammülü yoktur. -Give me the damn key!,TXT_RPLY0_SCRIPT05_D6064_GIVEM,〃,,,Dej mi ten zatracený klíč!,Giv mig den forbandede nøgle!,Geben Sie mir den verdammten Schlüssel!,,Donu la fekan ŝlosilon!,¡Dame la maldita llave!,,Anna minulle se pahuksen avain!,Donne moi cette putain de clé!,Add ide az istenverte kulcsot!,Dammi quella dannata chiave!,いいからとっととキーを寄越せ!,그 망할 놈의 키를 건네!,Geef me die verdomde sleutel!,Gi meg den jævla nøkkelen!,Daj mi ten cholerny klucz!,Me dê a droga da chave!,,Dă-mi afurisita de cheie!,Дай мне чёртов ключ!,,Ver şu lanet anahtarı bana! +",모렐 녀석이 너에게 통행증을 줬다 해도 신경 안 써. 이곳은 이 몸이 통치하는 감옥이다! 내가 가지고 있는 열쇠만 있으면 죄인들의 자유를 맘껏 조종할 수 있지. 오더는 절대로 실수 같은걸 용납하지 않아!,Het kan me niet schelen of Mourel je een pasje heeft gegeven. Dit is mijn gevangenis. Mijn sleutel is de enige weg naar binnen of buiten en ik neem geen enkel risico. De Orde tolereert geen fouten.,"Jeg blåser i om Mourel ga deg et passerseddel. Dette er mitt fengsel. Min nøkkel er den eneste veien inn eller ut, og jeg tar ingen sjanser. Ordenen tolererer ikke feil.","Nie obchodzi mnie to, że Mourel dał ci przepustkę. To moje więzienie. Tylko mój klucz pozwala wejść lub wyjść, i nie mam zamiaru ryzykować. Zakon nie toleruje błędów.",Eu não estou nem aí se o Mourel te deu um passe. Esta é a minha prisão. A única forma de entrar ou sair é com a minha chave e eu não estou a fim de arriscar. A Ordem não tolera erros.,,"Nu-mi pasă că Mourel ți-a dat o legitimație. Asta e închisoarea mea. Cheia mea e singura cale de intrare sau ieșire, și nu risc nimic. Ordinul nu tolerează greșeli.","Мне плевать, дал ли тебе Морел пропуск или нет. Это моя тюрьма, и без моего ключа не войти и не выйти. И я не хочу рисковать — Орден не прощает ошибок!",,"Jag bryr mig inte om Mourel gav dig ett passerkort. Det här är mitt fängelse. Min nyckel är den enda vägen in eller ut, och jag tar inga risker. Orden tolererar inga misstag.",Mourel'in sana izin vermesi umurumda değil. Burası benim hapishanem. İçeri girip çıkmanın tek yolu benim anahtarım ve işimi şansa bırakmayacağım. Tarikatın hataya tahammülü yoktur. +Give me the damn key!,TXT_RPLY0_SCRIPT05_D6064_GIVEM,〃,,,Dej mi ten zatracený klíč!,Giv mig den forbandede nøgle!,Geben Sie mir den verdammten Schlüssel!,,Donu la fekan ŝlosilon!,¡Dame la maldita llave!,,Anna minulle se pahuksen avain!,Donne moi cette putain de clé!,Add ide az istenverte kulcsot!,Dammi quella dannata chiave!,いいからとっととキーを寄越せ!,그 망할 놈의 키를 건네!,Geef me die verdomde sleutel!,Gi meg den jævla nøkkelen!,Daj mi ten cholerny klucz!,Me dê a droga da chave!,,Dă-mi afurisita de cheie!,Дай мне чёртов ключ!,,Ge mig den förbannade nyckeln!,Ver şu lanet anahtarı bana! Over my dead body!,TXT_DLG_SCRIPT05_D7580_OVERM,〃,,,Jen přes mou mrtvolu!,Over mit lig!,Nur über meine Leiche!,,Nur post mia morto!,¡Primero muerto!,,Vain kuolleen ruumiini yli!,Il faudra me passer sur le corps!,Csak a holttestemen át!,Sul mio cadavere!,欲しけりゃ取りに来い。,"내 시체를 밟고 얻어라! - \cy아마 네가 “부탁”을 안 해서 이러나 봐.",Over mijn lijk!,Over mitt lik!,Po moim trupie!,Só sobre o meu cadáver!,,Doar peste cadavrul meu!,Только через мой труп!,,Cesedimi çiğneyin! -Great idea!,TXT_RPLY0_SCRIPT05_D7580_GREAT,〃,,,Skvělý nápad!,God idé!,Gute Idee!,,Bonega ideo!,¡Qué buena idea!,,Loistoidea!,Excellente idée!,Kiváló ötlet!,Ottima idea!,良い案だ!,좋은 생각이야!,Geweldig idee!,God idé!,Dobry pomysł!,Boa idéia!,,Grozavă idee!,Хорошая мысль!,,Harika bir fikir! -"Shackles or chains, I want you to hang around.",TXT_DLG_SCRIPT05_D9096_SHACK,〃,,,"Pouta či řetězy, chci tě tu vidět viset.","Lænker eller kæder, jeg vil have dig til at blive hængende.",Fesseln oder Ketten - ich will dich hier herumhängen sehen.,,"Ĉu vi volas katenojn aŭ ŝeklojn? Mi volas, ke vi ĝuu vian restadon.",¿Grilletes o cadenas? Quiero que disfrutes de tu estancia.,,"Olipa sitten kahleissa tai ketjuissa, haluan sinun jäävän pysyäksesi.",Chaînes ou menottes? J'ai vraiment envie de vous retenir!,"Mindegy hogy béklyó vagy lánc, csak lógj itt szépen.","Ferri o catene, potrai starci benissimo qua!",鎖や手錠で、繋いだ方が良いな。,"동아줄, 아님 쇠사슬... 네 목에 잘 어울리겠네. 으하하하!","Sluitingen of kettingen, ik wil dat je blijft hangen.","Lenker eller lenker, jeg vil at du skal bli her.",Kajdany czy łańcuchy? Chcę byś na chwilę tu został.,Algemas ou correntes? Quero que você fique aqui por um tempo.,,"Cătușe sau lanțuri, vreau să rămăi pe-aici.","Кандалы или цепи? Я хочу, чтобы ты подольше тут задержался.",,"Kelepçe ya da zincir, buralarda olmanı istiyorum." + \cy아마 네가 “부탁”을 안 해서 이러나 봐.",Over mijn lijk!,Over mitt lik!,Po moim trupie!,Só sobre o meu cadáver!,,Doar peste cadavrul meu!,Только через мой труп!,,Över min döda kropp!,Cesedimi çiğneyin! +Great idea!,TXT_RPLY0_SCRIPT05_D7580_GREAT,〃,,,Skvělý nápad!,God idé!,Gute Idee!,,Bonega ideo!,¡Qué buena idea!,,Loistoidea!,Excellente idée!,Kiváló ötlet!,Ottima idea!,良い案だ!,좋은 생각이야!,Geweldig idee!,God idé!,Dobry pomysł!,Boa idéia!,,Grozavă idee!,Хорошая мысль!,,Bra idé!,Harika bir fikir! +"Shackles or chains, I want you to hang around.",TXT_DLG_SCRIPT05_D9096_SHACK,〃,,,"Pouta či řetězy, chci tě tu vidět viset.","Lænker eller kæder, jeg vil have dig til at blive hængende.",Fesseln oder Ketten - ich will dich hier herumhängen sehen.,,"Ĉu vi volas katenojn aŭ ŝeklojn? Mi volas, ke vi ĝuu vian restadon.",¿Grilletes o cadenas? Quiero que disfrutes de tu estancia.,,"Olipa sitten kahleissa tai ketjuissa, haluan sinun jäävän pysyäksesi.",Chaînes ou menottes? J'ai vraiment envie de vous retenir!,"Mindegy hogy béklyó vagy lánc, csak lógj itt szépen.","Ferri o catene, potrai starci benissimo qua!",鎖や手錠で、繋いだ方が良いな。,"동아줄, 아님 쇠사슬... 네 목에 잘 어울리겠네. 으하하하!","Sluitingen of kettingen, ik wil dat je blijft hangen.","Lenker eller lenker, jeg vil at du skal bli her.",Kajdany czy łańcuchy? Chcę byś na chwilę tu został.,Algemas ou correntes? Quero que você fique aqui por um tempo.,,"Cătușe sau lanțuri, vreau să rămăi pe-aici.","Кандалы или цепи? Я хочу, чтобы ты подольше тут задержался.",,"Fängsel eller kedjor, jag vill att du stannar kvar.","Kelepçe ya da zincir, buralarda olmanı istiyorum." "I don't know how you managed to get past the guards and the Warden, but I hope you like the decor, because you just moved in.",TXT_DLG_SCRIPT05_D10612_IDONT,MAP05: Wolenick.,,,"Nemám tušení, jak se ti podařilo dostat se přes stráže a dozorce, ale doufám že se ti líbí naše výzdoba, protože jsi se právě nastěhoval.","Jeg ved ikke, hvordan det lykkedes dig at komme forbi vagterne og direktøren, men jeg håber, du kan lide indretningen, for du er lige flyttet ind.","Ich habe keine Ahnung, wie du an den Wachen und dem Direktor vorbeigekommen bist, aber ich hoffe du magst das Dekor, denn du bist gerade eingezogen.",,"Mi ne komprenas, kiel vi superis la gardistojn kaj la provoson, sed mi esperas, ke vi ŝatas la dekoracion, ĉar vi ĵus transloĝiĝis.","No sé cómo habrás pasado por los guardias y el carcelero, pero espero que te guste la decoración, porque te acabas de mudar aquí.",,"En tiedä, miten onnistuit pääsemään vartijoiden ja vankilanjohtajan läpi, mutta toivon, että pidät sisustuksesta; olethan sentään tänne juuri muuttanut.","Je ne sais pas comment vous êtes passé à travers les gardes et le gardien, mais j'espère que vous aimez le décor car ceci sera votre nouveau domicile.","Nem tudom, hogyan jutottál át az őrökön és az igazgatón, de remélem szimpatikus a hely, mert még sokáig leszel itt.","Non so come tu abbia fatto a superare il direttore o le guardie, ma spero che tu apprezzi l'ambiente, perché adesso questa sarà anche la tua prigione.","どうやってガードやセキュリティを 抜けてきたかは知らんが、私の部署に移れば、 -この素晴らしい装飾を堪能できるぞ。","그 많은 경비와 간수장을 어떻게 해서 격파한 건지는 모르겠다만, 빠른 재판을 추천하겠네. 왜냐하면 자네는 헛수고했으니까.","Ik weet niet hoe je langs de bewakers en de directeur bent gekomen, maar ik hoop dat je het decor leuk vindt, want je bent er net ingetrokken.","Jeg vet ikke hvordan du kom deg forbi vaktene og direktøren, men jeg håper du liker innredningen, for du har nettopp flyttet inn.","Nie wiem jak ominąłeś strażników i Naczelnika, ale mam nadzieję, że podoba ci się wystrój, bo właśnie tu zostaniesz.","Eu não sei como você conseguiu passar pelos guardas e pelo Carcereiro, mas espero que goste da decoração, porque você acabou de se mudar pra cá.",,"Nu știu cum ai reușit să treci de gardieni și de Director, dar sper că îți place noul decor, pentru că tocmai te-ai mutat aici.","Не знаю, как тебе удалось миновать стражу и Монтага, но, я надеюсь, тебе нравится интерьер? Потому что отсюда ты уже не выйдешь.",,Muhafızları ve Müdür'ü nasıl atlattın bilmiyorum ama umarım dekoru beğenmişsindir çünkü yeni taşındın. -Free my comrades or die!,TXT_RPLY0_SCRIPT05_D10612_FREEM,〃,,,"Osvoboď mé druhy, nebo zemři!",Befri mine kammerater eller dø!,Befreien Sie meine Kameraden oder sterben Sie!,,Liberigu miajn samideanojn aŭ mortu!,¡Libera a mis camaradas o muere!,¡Libera a mis compañeros o muere!,Vapauta toverini tai kuole!,Libère mes camarades ou meurs!,"Engedd el a társaimat, vagy meghalsz!",Libera i miei compagni o muori!,命が惜しければ仲間を解放しろ!,"내 전우를 풀어주든지, 죽든지!",Bevrijd mijn kameraden of sterf!,Befri kameratene mine eller dø!,Uwolnij moich towarzyszy lub giń!,Liberte meus companheiros ou morra!,,"Eliberează-mi camarazii, sau mori!","Освободи моих товарищей, или ты умрёшь!",,Yoldaşlarımı serbest bırak ya da öl! +この素晴らしい装飾を堪能できるぞ。","그 많은 경비와 간수장을 어떻게 해서 격파한 건지는 모르겠다만, 빠른 재판을 추천하겠네. 왜냐하면 자네는 헛수고했으니까.","Ik weet niet hoe je langs de bewakers en de directeur bent gekomen, maar ik hoop dat je het decor leuk vindt, want je bent er net ingetrokken.","Jeg vet ikke hvordan du kom deg forbi vaktene og direktøren, men jeg håper du liker innredningen, for du har nettopp flyttet inn.","Nie wiem jak ominąłeś strażników i Naczelnika, ale mam nadzieję, że podoba ci się wystrój, bo właśnie tu zostaniesz.","Eu não sei como você conseguiu passar pelos guardas e pelo Carcereiro, mas espero que goste da decoração, porque você acabou de se mudar pra cá.",,"Nu știu cum ai reușit să treci de gardieni și de Director, dar sper că îți place noul decor, pentru că tocmai te-ai mutat aici.","Не знаю, как тебе удалось миновать стражу и Монтага, но, я надеюсь, тебе нравится интерьер? Потому что отсюда ты уже не выйдешь.",,"Jag vet inte hur du lyckades ta dig förbi vakterna och fängelsedirektören, men jag hoppas att du gillar inredningen, för du har just flyttat in.",Muhafızları ve Müdür'ü nasıl atlattın bilmiyorum ama umarım dekoru beğenmişsindir çünkü yeni taşındın. +Free my comrades or die!,TXT_RPLY0_SCRIPT05_D10612_FREEM,〃,,,"Osvoboď mé druhy, nebo zemři!",Befri mine kammerater eller dø!,Befreien Sie meine Kameraden oder sterben Sie!,,Liberigu miajn samideanojn aŭ mortu!,¡Libera a mis camaradas o muere!,¡Libera a mis compañeros o muere!,Vapauta toverini tai kuole!,Libère mes camarades ou meurs!,"Engedd el a társaimat, vagy meghalsz!",Libera i miei compagni o muori!,命が惜しければ仲間を解放しろ!,"내 전우를 풀어주든지, 죽든지!",Bevrijd mijn kameraden of sterf!,Befri kameratene mine eller dø!,Uwolnij moich towarzyszy lub giń!,Liberte meus companheiros ou morra!,,"Eliberează-mi camarazii, sau mori!","Освободи моих товарищей, или ты умрёшь!",,Befria mina kamrater eller dö!,Yoldaşlarımı serbest bırak ya da öl! Kill me and you'll never set anyone free. I possess the only pattern key that will unlock the cells.,TXT_DLG_SCRIPT05_D12128_KILLM,〃,,,"Zab mě a neosvobodíš nikoho. Jenom já mám vzor, který otevře cely.","Dræb mig, og du vil aldrig sætte nogen fri. Jeg besidder den eneste mønsternøgle, der kan låse cellerne op.","Töte mich und du befreist niemanden. Ich bin der einzige, der autorisiert ist, die Gefangenen freizulassen.",,"Vi liberigos neniun se vi mortigos min: mi havas la ununuran manspuron, kiu ebligas malŝlosi la ĉelojn.",Mátame y no liberarás a nadie: poseo la única huella digital que abre las celdas.,Mátame y no vas a liberar a nadie: poseo la única huella digital que abre las celdas.,Tappamalla minut et vapauta ketään. Vain minun käsissäni ovat avaimet sellien avaamiseen.,Tuez moi et personne ne sera libéré. Je suis le seul qui possède la clé qui peut ouvrir les cellules.,"Ha megölsz, akkor senkit sem fogsz tudni kiszabadítani. Az egyetlen biztonsági kulcs az Én tulajdonomban van.",Uccidi e non libererai proprio nessuno. Posseggo l'unica chiave d'identificazione che può aprire le celle.,"私を殺せば誰も助かる事はない。 -私の指紋だけが檻を開けられるからな。",날 죽이면 일이 더 최악으로 변질될 것일세. 나에게 감옥 문을 열 수 있는 유일한 지문이 있으니 말이지.,Dood me en je zult nooit iemand vrijlaten. Ik bezit de enige patroonsleutel die de cellen zal ontsluiten.,"Dreper du meg, får du aldri satt noen fri. Jeg har den eneste mønsternøkkelen som låser opp cellene.","Zabij mnie, a już nigdy nikogo nie uwolnisz. Tylko ja mam klucz do ich cel.",Mate-me e você nunca libertará ninguém. Eu possuo a única chave que destranca as celas.,,Omoară-mă și nu vei elibera pe nimeni în veci. Eu posed singura cheie care poate deschide celulele.,"Убив меня, ты никого не освободишь. Только у меня есть ключ, которым можно открыть камеры.",,Beni öldürürsen kimseyi özgür bırakamazsın. Hücrelerin kilidini açacak tek desen anahtarı bende. -Can you lend me a hand then?,TXT_RPLY0_SCRIPT05_D12128_CANYO,〃,,,Mohl bys mi tedy půjčit ruku?,Kan du så give mig en hånd med?,Können Sie mir Ihre Hand leihen?,,Tiuokaze mi «enmanigos» ilin al vi.,"¿Me echas una mano, entonces?","¿Me das una mano, entonces?",Voisitko sitten ojentaa auttavaa kättäsi?,"Tu peux me prêter main forte, alors?",Tudsz nekem segíteni?,"Che ne dici di darmi una mano, allora?",じゃあ 手を貸して くれるか?,그럼 네 손길이 좀 필요할 것 같아...,Kun je me dan een handje helpen?,"Kan du hjelpe meg, da?",Więc może podasz mi pomocną dłoń?,Pode me dar uma mão então?,,Poți da o mână de ajutor atunci?,"Может быть, ты протянешь мне руку помощи?",,O zaman bana yardım edebilir misin? -Move along or join your friends.,TXT_DLG_SCRIPT05_D13644_MOVEA,〃,,,"Jdi, nebo se přidej ke svým kamarádům.",Gå videre eller slut dig til dine venner.,Hau ab oder zieh bei deinen Freunden ein.,,Foriru aŭ alliĝu al viaj amikoj.,Vete o únete a tus amigos.,,"Jatka eteenpäin, tai liity ystäviesi joukkoon.",Bougez ou rejoignez vos amis.,"Mozogj tovább, vagy csatlakozz a barátaidhoz.","Togliti dai piedi, o ti unirai ai tuoi amici.",共に行こう友よ。,"무죄, 아니면 사형 선고. 정하시게.",Ga mee of sluit je aan bij je vrienden.,Gå videre eller bli med vennene dine.,Idź stąd lub dołączysz do swoich przyjaciół.,Suma daqui ou junte-se aos seus amigos.,,Cară-te sau te vei alătura prietenilor tăi.,"Не подходи ко мне, или присоединишься к своим друзьям.",,İlerleyin ya da arkadaşlarınıza katılın. -"Don't just stand there, get us out of here!",TXT_DLG_SCRIPT05_D15160_DONTJ,MAP05: Prisoner.,,,"Nestůj tam tak, dostaň nás odsud!","Stå ikke bare der, få os ud herfra!","Steh da nicht so rum, hol uns raus!",,"Ne staru tie, liberigu nin!","No te quedes ahí, ¡sácanos de aquí!",,Älä vain siinä seisoskele; päästä meidät ulos täältä!,"Ne vous tenez pas là, sortez nous d'ici!","Ne csak bámészkodj, szabadíts ki minket!","Non stare lì fermo, facci uscire da qui!",もう待てない、早くここを出よう!,"거기 서 있지 말고, 어서 우릴 내보내 줘!","Blijf daar niet staan, haal ons hier weg!","Ikke bare stå der, få oss ut herfra!","Nie stój tak, uwolnij nas stąd!",Não fique parado aí. Nos tire daqui!,,"Nu sta acolo, scoate-ne de aici!",Не стой просто так. Вытащи нас отсюда!,,"Orada öylece durmayın, bizi buradan çıkarın!" -"The sky, I want to see the sky.",TXT_DLG_SCRIPT05_D16676_THESK,〃,,,"Nebe, chci vidět nebe.","Himlen, jeg vil se himlen.","Der Himmel, ich möchte den Himmel sehen.",,"La ĉielon, mi volas vidi la ĉielon.","El cielo, quiero ver el cielo.",,"Taivas, haluan nähdä taivaan.","Le ciel, je veux voir le ciel!","Az eget, szeretném újra látni az eget.","Il cielo, voglio vedere il cielo.",空を、空を見たい。,"하늘, 하늘을 보고 싶어.","De lucht, ik wil de lucht zien.","Himmelen, jeg vil se himmelen.",Niebo... tak bardzo chcę zobaczyć niebo.,O céu. Eu quero ver o céu.,,"Cerul, vreau să văd cerul!",Небо. Я хочу увидеть небо.,,"Gökyüzü, gökyüzünü görmek istiyorum." +私の指紋だけが檻を開けられるからな。",날 죽이면 일이 더 최악으로 변질될 것일세. 나에게 감옥 문을 열 수 있는 유일한 지문이 있으니 말이지.,Dood me en je zult nooit iemand vrijlaten. Ik bezit de enige patroonsleutel die de cellen zal ontsluiten.,"Dreper du meg, får du aldri satt noen fri. Jeg har den eneste mønsternøkkelen som låser opp cellene.","Zabij mnie, a już nigdy nikogo nie uwolnisz. Tylko ja mam klucz do ich cel.",Mate-me e você nunca libertará ninguém. Eu possuo a única chave que destranca as celas.,,Omoară-mă și nu vei elibera pe nimeni în veci. Eu posed singura cheie care poate deschide celulele.,"Убив меня, ты никого не освободишь. Только у меня есть ключ, которым можно открыть камеры.",,Om du dödar mig kommer du aldrig att befria någon. Jag besitter den enda mönsternyckeln som kan låsa upp cellerna.,Beni öldürürsen kimseyi özgür bırakamazsın. Hücrelerin kilidini açacak tek desen anahtarı bende. +Can you lend me a hand then?,TXT_RPLY0_SCRIPT05_D12128_CANYO,〃,,,Mohl bys mi tedy půjčit ruku?,Kan du så give mig en hånd med?,Können Sie mir Ihre Hand leihen?,,Tiuokaze mi «enmanigos» ilin al vi.,"¿Me echas una mano, entonces?","¿Me das una mano, entonces?",Voisitko sitten ojentaa auttavaa kättäsi?,"Tu peux me prêter main forte, alors?",Tudsz nekem segíteni?,"Che ne dici di darmi una mano, allora?",じゃあ 手を貸して くれるか?,그럼 네 손길이 좀 필요할 것 같아...,Kun je me dan een handje helpen?,"Kan du hjelpe meg, da?",Więc może podasz mi pomocną dłoń?,Pode me dar uma mão então?,,Poți da o mână de ajutor atunci?,"Может быть, ты протянешь мне руку помощи?",,Kan du ge mig en hand med det då?,O zaman bana yardım edebilir misin? +Move along or join your friends.,TXT_DLG_SCRIPT05_D13644_MOVEA,〃,,,"Jdi, nebo se přidej ke svým kamarádům.",Gå videre eller slut dig til dine venner.,Hau ab oder zieh bei deinen Freunden ein.,,Foriru aŭ alliĝu al viaj amikoj.,Vete o únete a tus amigos.,,"Jatka eteenpäin, tai liity ystäviesi joukkoon.",Bougez ou rejoignez vos amis.,"Mozogj tovább, vagy csatlakozz a barátaidhoz.","Togliti dai piedi, o ti unirai ai tuoi amici.",共に行こう友よ。,"무죄, 아니면 사형 선고. 정하시게.",Ga mee of sluit je aan bij je vrienden.,Gå videre eller bli med vennene dine.,Idź stąd lub dołączysz do swoich przyjaciół.,Suma daqui ou junte-se aos seus amigos.,,Cară-te sau te vei alătura prietenilor tăi.,"Не подходи ко мне, или присоединишься к своим друзьям.",,Gå vidare eller gå till dina vänner.,İlerleyin ya da arkadaşlarınıza katılın. +"Don't just stand there, get us out of here!",TXT_DLG_SCRIPT05_D15160_DONTJ,MAP05: Prisoner.,,,"Nestůj tam tak, dostaň nás odsud!","Stå ikke bare der, få os ud herfra!","Steh da nicht so rum, hol uns raus!",,"Ne staru tie, liberigu nin!","No te quedes ahí, ¡sácanos de aquí!",,Älä vain siinä seisoskele; päästä meidät ulos täältä!,"Ne vous tenez pas là, sortez nous d'ici!","Ne csak bámészkodj, szabadíts ki minket!","Non stare lì fermo, facci uscire da qui!",もう待てない、早くここを出よう!,"거기 서 있지 말고, 어서 우릴 내보내 줘!","Blijf daar niet staan, haal ons hier weg!","Ikke bare stå der, få oss ut herfra!","Nie stój tak, uwolnij nas stąd!",Não fique parado aí. Nos tire daqui!,,"Nu sta acolo, scoate-ne de aici!",Не стой просто так. Вытащи нас отсюда!,,"Stå inte bara där, ta oss härifrån!","Orada öylece durmayın, bizi buradan çıkarın!" +"The sky, I want to see the sky.",TXT_DLG_SCRIPT05_D16676_THESK,〃,,,"Nebe, chci vidět nebe.","Himlen, jeg vil se himlen.","Der Himmel, ich möchte den Himmel sehen.",,"La ĉielon, mi volas vidi la ĉielon.","El cielo, quiero ver el cielo.",,"Taivas, haluan nähdä taivaan.","Le ciel, je veux voir le ciel!","Az eget, szeretném újra látni az eget.","Il cielo, voglio vedere il cielo.",空を、空を見たい。,"하늘, 하늘을 보고 싶어.","De lucht, ik wil de lucht zien.","Himmelen, jeg vil se himmelen.",Niebo... tak bardzo chcę zobaczyć niebo.,O céu. Eu quero ver o céu.,,"Cerul, vreau să văd cerul!",Небо. Я хочу увидеть небо.,,"Himlen, jag vill se himlen.","Gökyüzü, gökyüzünü görmek istiyorum." "Five feet by four feet, five feet by four feet, five feet by four feet.",TXT_DLG_SCRIPT05_D18192_FIVEF,〃,,,"Pět kroků, čtyři kroky, pět kroků, čtyři kroky, pět kroků, čtyři kroky.","Fem fod gange fire fod, fem fod gange fire fod, fem fod gange fire fod...","Fünf Fuß mal vier Fuß, fünf Fuß mal vier Fuß, fünf Fuß mal vier Fuß...",,"1,2 oble 1,5 metroj. 1,2 oble 1,5 metroj. 1,2 oble 1,5 metroj...","Un metro y medio por un metro veinte. Un metro y medio por un metro veinte. Un metro y medio por un metro veinte...",,"Viisi kertaa neljä jalkaa, viisi kertaa neljä jalkaa, viisi kertaa neljä jalkaa.",Un mètre cinquante par un mètre trente. Un mètre cinquante par un mètre trente. Un mètre cinquante par un mètre trente.,"Öt lábszor négy láb, öt lábszor négy láb, öt lábszor négy láb.",Un metro e cinquanta per un metro e trenta. Un metro e cinquanta per un metro e trenta. Un metro e cinquanta per un metro e trenta.,"ファイブフィート バイ フォーフィート、 ファイブフィート バイ フォーフィート、 -ファイブフィート バイ フォーフィート。",나가려면 나갈 생각을 하고 나갈 준비를 해야 되는데 나갈 수가 없어 왜냐하면 나가는 걸 막는 놈들이...,"Vijf voet bij vier voet, vijf voet bij vier voet, vijf voet bij vier voet, vijf voet bij vier voet.","Fem fot ganger fire fot, fem fot ganger fire fot, fem fot ganger fire fot!","Pięć stóp na cztery, pięć stóp na cztery, pięć stóp na cztery.",Um metro e meio por um metro e vinte. Um metro e meio por um metro e vinte. Um metro e meio por um metro e vinte. ,,"Din 5 pași 4, din 5 pași 4, din 5 pași 4.","Пять футов на четыре, пять футов на четыре, пять футов на четыре.",,"Bir metreye bir metre, bir metreye bir metre, bir metreye bir metre." +ファイブフィート バイ フォーフィート。",나가려면 나갈 생각을 하고 나갈 준비를 해야 되는데 나갈 수가 없어 왜냐하면 나가는 걸 막는 놈들이...,"Vijf voet bij vier voet, vijf voet bij vier voet, vijf voet bij vier voet, vijf voet bij vier voet.","Fem fot ganger fire fot, fem fot ganger fire fot, fem fot ganger fire fot!","Pięć stóp na cztery, pięć stóp na cztery, pięć stóp na cztery.",Um metro e meio por um metro e vinte. Um metro e meio por um metro e vinte. Um metro e meio por um metro e vinte. ,,"Din 5 pași 4, din 5 pași 4, din 5 pași 4.","Пять футов на четыре, пять футов на четыре, пять футов на четыре.",,"Fem fot på fyra fot, fem fot på fyra fot, fem fot på fyra fot, fem fot på fyra fot.","Bir metreye bir metre, bir metreye bir metre, bir metreye bir metre." Don't release me if the Order's still in charge. I can't stand the terror.,TXT_DLG_SCRIPT05_D19708_DONTR,〃,,,"Nevysvobozuj mě, jestli ještě vládne Řád. Tu hrůzu nemůžu snést.","Slip mig ikke fri, hvis Ordenen stadig har kommandoen. Jeg kan ikke klare terroren.","Bitte befreie mich nicht, wenn der Orden hier noch herrscht, ich halte den Horror nicht aus.",,Ne liberigu min se La Ordono ankoraŭ regas: mi ne eltenas la teruron.,No me sueltes si La Orden sigue al mando: no soporto el terror.,,"Älä vapauta minua, jos Veljeskunta on vielä vallassa. En kestä enää sitä hirveyttä.",Laissez moi ici si l'Ordre est toujours au pouvoir. Je ne veux pas voir cette horreur.,Ne engedj ki míg a Rend hatalmon van. Nem bírom ezt az elnyomást.,Non liberarmi se l'Ordine è ancora al potere. Non voglio vedere questo orrore.,"まだオーダーがいる内は出たくない。 -恐怖に打ち拉がれそうだ。",오더 놈들이 아직도 설치고 있다면 절 내보내지 마세요. 죽을까 봐 두려워요...,Laat me niet los als de Orde nog steeds de leiding heeft. Ik kan niet tegen de terreur.,Ikke slipp meg ut hvis Ordenen fortsatt har kommandoen. Jeg holder ikke ut terroren.,Nie uwalniaj mnie jeśli Zakon jest wciąż u władzy. Nie mogę znieść tego terroru.,Não me solte se a Ordem ainda estiver no comando. Eu não suporto o horror.,,Nu mă elibera dacă Ordinul incă e tot la putere.,"Не освобождай меня, если Орден всё ещё у власти. Я не вынесу устрашения.",,Tarikat hâlâ yetkiliyse beni bırakmayın. Dehşete dayanamıyorum. +恐怖に打ち拉がれそうだ。",오더 놈들이 아직도 설치고 있다면 절 내보내지 마세요. 죽을까 봐 두려워요...,Laat me niet los als de Orde nog steeds de leiding heeft. Ik kan niet tegen de terreur.,Ikke slipp meg ut hvis Ordenen fortsatt har kommandoen. Jeg holder ikke ut terroren.,Nie uwalniaj mnie jeśli Zakon jest wciąż u władzy. Nie mogę znieść tego terroru.,Não me solte se a Ordem ainda estiver no comando. Eu não suporto o horror.,,Nu mă elibera dacă Ordinul incă e tot la putere.,"Не освобождай меня, если Орден всё ещё у власти. Я не вынесу устрашения.",,Släpp inte ut mig om Orden fortfarande har befälet. Jag står inte ut med skräcken.,Tarikat hâlâ yetkiliyse beni bırakmayın. Dehşete dayanamıyorum. "I don't want to bitch, but it's about time Macil sent someone to get us out.",TXT_DLG_SCRIPT05_D21224_IDONT,〃,,,"Nechci nadávat, ale už bylo na čase, aby Macil někoho poslal nás vysvobodit.","Jeg vil ikke brokke mig, men det er på tide, at Macil sender nogen ud for at få os ud.","Ich möchte ja nicht meckern, aber es wurde auch Zeit, dass Macil jemanden schickt, der uns hier rausholt",,"Mi ne intencas plendi, sed Macil finfine sendis iun por liberigi nin.","No quiero quejarme, pero ya era hora de que Macil enviara a alguien a sacarnos.",,"En halua ruikuttaa, mutta jo oli aikakin, että Macil lähetti jonkun päästämään meidät pois.","J'ai pas envie de me plaindre, mais Macil a vraiment pris son temps pour envoyer quelqu'un nous sortir d'ici!","Nem akarnék picsogni, de már ideje volt hogy Macil küldött értünk valakit.","Non è che voglio lamentarmi, però era ora che Macil mandasse qualcuno a liberarci.","意地が悪いな、だがマシルが解放の為に -誰か送ったのは大体わかる。","투정부리기는 싫지만, 드디어 사령관님이 구출작전을 실시한 것 같군요.","Ik wil niet zeuren, maar het wordt tijd dat Macil iemand stuurt om ons eruit te krijgen.","Jeg vil ikke klage, men det er på tide at Macil sender noen for å få oss ut.","Nie chcę psioczyć, ale najwyższa pora, aby Macil wysłał kogoś, by nas uwolnić.","Não quero encher o saco, mas já era hora do Macil enviar alguém para nos tirar daqui.",,"Nu vreau să mă smiorcăi, dar era și timpul ca Macil să trimită pe cineva să ne scoată afară.","Не хочу ныть, но Мэйсил мог бы и пораньше послать кого-нибудь освободить нас.",,Şikâyet etmek istemiyorum ama Macil'in bizi çıkarması için birini göndermesinin zamanı gelmişti. +誰か送ったのは大体わかる。","투정부리기는 싫지만, 드디어 사령관님이 구출작전을 실시한 것 같군요.","Ik wil niet zeuren, maar het wordt tijd dat Macil iemand stuurt om ons eruit te krijgen.","Jeg vil ikke klage, men det er på tide at Macil sender noen for å få oss ut.","Nie chcę psioczyć, ale najwyższa pora, aby Macil wysłał kogoś, by nas uwolnić.","Não quero encher o saco, mas já era hora do Macil enviar alguém para nos tirar daqui.",,"Nu vreau să mă smiorcăi, dar era și timpul ca Macil să trimită pe cineva să ne scoată afară.","Не хочу ныть, но Мэйсил мог бы и пораньше послать кого-нибудь освободить нас.",,"Jag vill inte vara taskig, men det är på tiden att Macil skickar någon för att få ut oss.",Şikâyet etmek istemiyorum ama Macil'in bizi çıkarması için birini göndermesinin zamanı gelmişti. I'd give anything for just a crust of bread. I'm so hungry.,TXT_DLG_SCRIPT05_D22740_IDGIV,〃,,,Dal bych cokoliv jen za kůrku chleba. Mám takový hlad.,Jeg ville give alt for bare en brødskorpe. Jeg er så sulten.,Ich gäbe alles für eine Brotkruste. Ich habe so einen Hunger.,,Mi interŝanĝus ion ajn kontraŭ panero. Mi malsategas.,Daría lo que fuera por una migaja de pan. Tengo tanta hambre.,Daría lo que fuera por una miga de pan. Tengo tanta hambre.,Antaisin mitä vain yhdestäkin leivän murenesta. Minulla on niin nälkä.,Je donnerai n'importe quoi pour une bouchée de pain. J'ai tellement faim!,"Bármit megadnék egy falat kenyérért, annyira nagyon éhes vagyok.",Darei qualsiasi cosa per una crosta di pane. Ho una grande fame.,"いつもパンの耳ばかりだったんだ。 -すごく腹減った。",빵 한 조각이라도 먹고 싶습니다... 너무 배고파요...,Ik zou alles geven voor een korstje brood. Ik heb zo'n honger.,Jeg ville gitt hva som helst for en brødskive. Jeg er så sulten.,Oddałbym wszystko za kromkę chleba. Jestem taki głodny.,Eu daria qualquer coisa por uma migalha de pão. Estou tão faminto.,,Aș da orice pentru o coajă de pâine. Sunt așa flămând.,Я бы всё отдал просто за ломоть хлеба. Я так голоден.,,Bir lokma ekmek için her şeyimi verirdim. Çok acıktım. -"Ah, a surfacer in need of a favor. Down here you do a favor to get a favor and I need the town entrance that is our path to food opened. The Order has it sealed and guarded.",TXT_DLG_SCRIPT06_D0_AHASU,MAP06: Weran.,,"Ah, a surfacer in need of a favour. Down here you do a favour to get a favour and I need the town entrance that is our path to food opened. The Order has it sealed and guarded.","Á, nadzemník, který potřebuje službu. Tady dole prokazuješ službu, abys dostal službu, a já potřebuju otevřít vchod do města, abychom měli cestu k jídlu. Řád ji nechal zapečetit a hlídat.","Ah, en overfladebeboer, der har brug for en tjeneste. Her nede gør man en tjeneste for at få en tjeneste, og jeg har brug for at få åbnet byens indgang, som er vores vej til mad. Ordenen har den forseglet og bevogtet.","Oh, ein Oberflächler, der Hilfe braucht. Hier unten musst du uns einen Gefallen erweisen, bevor wir dir helfen können. Der Ausgang zur Stadt, der unser Zugang zu Nahrung ist, muss wieder freigemacht werden. Der Orden hat ihn verschlossen und lässt ihn bewachen.",,"Ha, surfaco-loĝanto bezonas komplezon. Ĉi-malsupre oni faras servon por gajni reservon, kaj mi bezonas la enirejon al la urbo, kiu estas nia fonto de manĝaĵoj, malfermitan: La Ordono ĝin ŝlosis kaj gardas.","Ah, alguien de la superficie que necesita un favor. Aquí abajo se ofrece un favor a cambio de otro, y necesito abierta la entrada al pueblo que es nuestro camino a la comida: La Orden la tiene cerrada y con vigilancia.",,"Jaahas, maanpintalainen palveluksen tarpeessa. Täällä alhaalla on tapana tehdä palvelus palveluksesta, ja minä haluan, että kaupungin sisäänkäynti, tiemme ruuan pariin, avataan. Se on salvattu ja vartioitu Veljeskunnan toimesta.","Ah, quelqu'un de la surface qui a besoin d'une faveur. Ici, on en fait une pour en avoir une, et j'ai besoin que l'entrée de la ville qui est notre chemin pour les vivres ouverte. L'Ordre l'a scellée et mise sous garde.","Nahát, egy felszínlakó aki szívességet kér. Itt az a szokás, hogy egy szívességért cserébe szívesség dukál. Ahhoz, hogy elérhetővé válljon mindenki számára a élelem, kell egy biztonságos belépő a városba. A Rend nagy biztonságban őrzi.","Ah, un abitante della superficie che ha bisogno di un favore. Quaggiù tu fai un favore per ottenere un favore, e io ho bisogno che l'ingresso alla città venga aperto visto che è il nostro accesso al cibo. L'Ordine l'ha chiuso e lo sorveglia.","あー、何か用があって上から来たんだな。 +すごく腹減った。",빵 한 조각이라도 먹고 싶습니다... 너무 배고파요...,Ik zou alles geven voor een korstje brood. Ik heb zo'n honger.,Jeg ville gitt hva som helst for en brødskive. Jeg er så sulten.,Oddałbym wszystko za kromkę chleba. Jestem taki głodny.,Eu daria qualquer coisa por uma migalha de pão. Estou tão faminto.,,Aș da orice pentru o coajă de pâine. Sunt așa flămând.,Я бы всё отдал просто за ломоть хлеба. Я так голоден.,,Jag skulle ge vad som helst för bara en skorpa bröd. Jag är så hungrig.,Bir lokma ekmek için her şeyimi verirdim. Çok acıktım. +"Ah, a surfacer in need of a favor. Down here you do a favor to get a favor and I need the town entrance that is our path to food opened. The Order has it sealed and guarded.",TXT_DLG_SCRIPT06_D0_AHASU,MAP06: Weran.,,"Ah, a surfacer in need of a favour. Down here you do a favour to get a favour and I need the town entrance that is our path to food opened. The Order has it sealed and guarded.","Á, nadzemník, který potřebuje službu. Tady dole prokazuješ službu, abys dostal službu, a já potřebuju otevřít vchod do města, abychom měli cestu k jídlu. Řád ji nechal zapečetit a hlídat.","Ah, en overfladebeboer, der har brug for en tjeneste. Her nede gør man en tjeneste for at få en tjeneste, og jeg har brug for at få åbnet byens indgang, som er vores vej til mad. Ordenen har den forseglet og bevogtet.","Oh, ein Oberflächler, der Hilfe braucht. Hier unten musst du uns einen Gefallen erweisen, bevor wir dir helfen können. Der Ausgang zur Stadt, der unser Zugang zu Nahrung ist, muss wieder freigemacht werden. Der Orden hat ihn verschlossen und lässt ihn bewachen.",,"Ha, surfaco-loĝanto bezonas komplezon. Ĉi-malsupre oni faras servon por gajni reservon, kaj mi bezonas remalfermi la enirejon al la urbo, kiu estas nia fonto de manĝaĵoj: La Ordono ĝin ŝlosis kaj gardas.","Ah, alguien de la superficie que necesita un favor. Aquí abajo se ofrece un favor a cambio de otro, y necesito abierta la entrada al pueblo que es nuestro camino a la comida: La Orden la tiene cerrada y con vigilancia.",,"Jaahas, maanpintalainen palveluksen tarpeessa. Täällä alhaalla on tapana tehdä palvelus palveluksesta, ja minä haluan, että kaupungin sisäänkäynti, tiemme ruuan pariin, avataan. Se on salvattu ja vartioitu Veljeskunnan toimesta.","Ah, quelqu'un de la surface qui a besoin d'une faveur. Ici, on en fait une pour en avoir une, et j'ai besoin que l'entrée de la ville qui est notre chemin pour les vivres ouverte. L'Ordre l'a scellée et mise sous garde.","Nahát, egy felszínlakó aki szívességet kér. Itt az a szokás, hogy egy szívességért cserébe szívesség dukál. Ahhoz, hogy elérhetővé válljon mindenki számára a élelem, kell egy biztonságos belépő a városba. A Rend nagy biztonságban őrzi.","Ah, un abitante della superficie che ha bisogno di un favore. Quaggiù tu fai un favore per ottenere un favore, e io ho bisogno che l'ingresso alla città venga aperto visto che è il nostro accesso al cibo. L'Ordine l'ha chiuso e lo sorveglia.","あー、何か用があって上から来たんだな。 だがここでは物々交換が常識だ、 オーダーが町の出口を封鎖しやがったから -メシが手に入り辛くなったんだ。","아아... 도움이 필요한 지상인이구려. 도움을 받고 싶으면, 우리에게 도움이 되어야 할 것이야. 식량을 구할 수 있는 마을로 향하는 입구가 오더에 의해 막혔거단.","Ah, een verharder die een gunst nodig heeft. Hier beneden doe je een gunst om een gunst te krijgen en ik heb de stadstoegang nodig die onze weg naar eten is geopend. De Orde heeft het verzegeld en bewaakt.","Ah, en overflateboer som trenger en tjeneste. Her nede gjør man en tjeneste for å få en tjeneste, og jeg må få åpnet inngangen til byen som er vår vei til mat. Ordenen har den forseglet og bevoktet.","Ah, powierzchniowiec potrzebujący pomocy. Tutaj na dole robi się to tak: przysługa za przysługę, a ja potrzebuję otworzyć wyjście do miasta, które jest naszą jedyną drogą by zdobyć jedzenie. Zakon je zablokował i pilnie go strzeże.","Ah, um cara da superfície precisando de um favor. Aqui embaixo você faz um favor para conseguir um favor e eu preciso da entrada da cidade aberta para pegar a nossa comida. A Ordem mantém ela fechada e guardada.",,"Ah, un locuitor de la suprafață care are nevoie de o favoare. Aici jos faci o favoare, primești o favoare, iar eu am nevoie de o cale pentru a ajunge la intrarea din oraș, să putem avea acces la provizii. Ordinul a închis-o și acum e bine păzită.","А-а, гостю с поверхности нужно одолжение. Здесь, внизу, ты должен что-то сделать, прежде чем о чём-то попросить, и мне нужно, чтобы дверь в город, наш путь к пище, была открыта. Орден закрыл её и поставил охрану.",,İyiliğe ihtiyacı olan bir yüzey araştırmacısı. Burada bir iyilik için bir iyilik yaparsın ve ben de yiyecek yolumuz olan kasaba girişinin açılmasını istiyorum. Tarikat orayı mühürledi ve koruyor. -Where is the gate mechanism?,TXT_RPLY0_SCRIPT06_D0_WHERE,〃,,,Kde je mechanismus brány?,Hvor er portmekanismen?,Wo ist der Tormechanismus?,,Kie estas la mekanismo de la kastelpordo?,¿Dónde está el mecanismo de la puerta?,,Missä on portin koneisto?,Où se trouve le mécanisme d'ouverture de la porte?,Hol van a kapu szerkezet?,Dov'è il meccanismo per il cancello?,ゲートメカニズムは何処だ?,성문 관리 장치는 어딨지?,Waar is het poortmechanisme?,Hvor er portmekanismen?,Gdzie jest mechanizm sterujący bramą?,Onde fica o mecanismo do portão?,,Unde e mecanismul de acționare al porții?,Где механизм управления воротами?,,Kapı mekanizması nerede? +メシが手に入り辛くなったんだ。","아아... 도움이 필요한 지상인이구려. 도움을 받고 싶으면, 우리에게 도움이 되어야 할 것이야. 식량을 구할 수 있는 마을로 향하는 입구가 오더에 의해 막혔거단.","Ah, een verharder die een gunst nodig heeft. Hier beneden doe je een gunst om een gunst te krijgen en ik heb de stadstoegang nodig die onze weg naar eten is geopend. De Orde heeft het verzegeld en bewaakt.","Ah, en overflateboer som trenger en tjeneste. Her nede gjør man en tjeneste for å få en tjeneste, og jeg må få åpnet inngangen til byen som er vår vei til mat. Ordenen har den forseglet og bevoktet.","Ah, powierzchniowiec potrzebujący pomocy. Tutaj na dole robi się to tak: przysługa za przysługę, a ja potrzebuję otworzyć wyjście do miasta, które jest naszą jedyną drogą by zdobyć jedzenie. Zakon je zablokował i pilnie go strzeże.","Ah, um cara da superfície precisando de um favor. Aqui embaixo você faz um favor para conseguir um favor e eu preciso da entrada da cidade aberta para pegar a nossa comida. A Ordem mantém ela fechada e guardada.",,"Ah, un locuitor de la suprafață care are nevoie de o favoare. Aici jos faci o favoare, primești o favoare, iar eu am nevoie de o cale pentru a ajunge la intrarea din oraș, să putem avea acces la provizii. Ordinul a închis-o și acum e bine păzită.","А-а, гостю с поверхности нужно одолжение. Здесь, внизу, ты должен что-то сделать, прежде чем о чём-то попросить, и мне нужно, чтобы дверь в город, наш путь к пище, была открыта. Орден закрыл её и поставил охрану.",,"Ah, en ytmänniska i behov av en tjänst. Här nere gör man en tjänst för att få en tjänst och jag behöver öppna stadens ingång som är vår väg till mat. Orden har förseglat och bevakat den.",İyiliğe ihtiyacı olan bir yüzey araştırmacısı. Burada bir iyilik için bir iyilik yaparsın ve ben de yiyecek yolumuz olan kasaba girişinin açılmasını istiyorum. Tarikat orayı mühürledi ve koruyor. +Where is the gate mechanism?,TXT_RPLY0_SCRIPT06_D0_WHERE,〃,,,Kde je mechanismus brány?,Hvor er portmekanismen?,Wo ist der Tormechanismus?,,Kie estas la mekanismo de la kastelpordo?,¿Dónde está el mecanismo de la puerta?,,Missä on portin koneisto?,Où se trouve le mécanisme d'ouverture de la porte?,Hol van a kapu szerkezet?,Dov'è il meccanismo per il cancello?,ゲートメカニズムは何処だ?,성문 관리 장치는 어딨지?,Waar is het poortmechanisme?,Hvor er portmekanismen?,Gdzie jest mechanizm sterujący bramą?,Onde fica o mecanismo do portão?,,Unde e mecanismul de acționare al porții?,Где механизм управления воротами?,,Var är grindmekanismen?,Kapı mekanizması nerede? "Do my favor first, or you'll get squat from me.",TXT_DLG_SCRIPT06_D1516_DOMYF,〃,,"Do my favour first, or you'll get squat from me.","Prokaž mi službu, nebo ode mne nedostaneš nic.","Gør mig en tjeneste først, ellers får du ikke en skid af mig.",Tu erst mir einen Gefallen oder ich sage gar nichts.,,Vi unue faru mian komplezon se vi volas ricevi ion de mi.,Cumple mi favor primero o no tendrás nada de mí.,Cumple mi favor primero o no vas a tener nada de mí.,"Tee minun palveluspyyntöni ensin, tai et saa minulta mitään.",Faites moi une faveur ou vous n'aurez rien.,"Jobban jársz ha az én szívességemet teljesíted, mert különben lópikulát se kapsz.","Fai il mio favore prima, o da me non otterrai nulla.",俺の言った問題が先だ、でないと手助けできねえ。,"나를 도와주려, 아니면 너를 도륙할 거랴! - \cy다들 참 궁색하게 사네.","Doe me eerst een plezier, of je krijgt een hurkzitje van mij.","Gjør meg en tjeneste først, ellers får du ikke en dritt av meg.",Zrób najpierw to o co cię prosiłem lub figę dostaniesz.,"Faça o meu favor primeiro, ou você não recebe coisa nenhuma de mim.",,"Fă-mi favoarea mai întâi, sau nu-ți zic nimic.","Сначала выполни мою просьбу, или ты ничего не получишь.",,"Önce benim iyiliğimi yap, yoksa benden hiçbir şey alamazsın." -How will you know it's open?,TXT_RPLY0_SCRIPT06_D1516_HOWWI,〃,,,"Jak budeš vědět, že je otevřená?","Hvordan vil du vide, at den er åben?","Wodurch wirst du wissen, ob er offen ist?",,Kiel vi scios ĉu mi malfermis ĝin?,¿Cómo sabrás si está abierta?,¿Cómo vas a comprobar si la abrí?,"Mistä tiedät, että se on auki?",Comment est-ce que je saurais qu'elle est ouverte?,"Honnan tudod, hogy nyitva lesz?",Come farai a sapere che è aperto?,開放を知らせるには?,어떻게 도와주면 방법을 알 수 있지?,Hoe weet je dat het open is?,Hvordan vet du at den er åpen?,"Skąd będziesz wiedział, że jest już otwarta?",Como você vai saber que ela está aberta?,,Cum vei știi că e deschisă?,"Как ты узнаешь, что дверь открыта?",,Açık olduğunu nereden bileceksin? + \cy다들 참 궁색하게 사네.","Doe me eerst een plezier, of je krijgt een hurkzitje van mij.","Gjør meg en tjeneste først, ellers får du ikke en dritt av meg.",Zrób najpierw to o co cię prosiłem lub figę dostaniesz.,"Faça o meu favor primeiro, ou você não recebe coisa nenhuma de mim.",,"Fă-mi favoarea mai întâi, sau nu-ți zic nimic.","Сначала выполни мою просьбу, или ты ничего не получишь.",,"Gör mig en tjänst först, annars får du inget från mig.","Önce benim iyiliğimi yap, yoksa benden hiçbir şey alamazsın." +How will you know it's open?,TXT_RPLY0_SCRIPT06_D1516_HOWWI,〃,,,"Jak budeš vědět, že je otevřená?","Hvordan vil du vide, at den er åben?","Wodurch wirst du wissen, ob er offen ist?",,Kiel vi scios ĉu mi malfermis ĝin?,¿Cómo sabrás si está abierta?,¿Cómo vas a comprobar si la abrí?,"Mistä tiedät, että se on auki?",Comment est-ce que je saurais qu'elle est ouverte?,"Honnan tudod, hogy nyitva lesz?",Come farai a sapere che è aperto?,開放を知らせるには?,어떻게 도와주면 방법을 알 수 있지?,Hoe weet je dat het open is?,Hvordan vet du at den er åpen?,"Skąd będziesz wiedział, że jest już otwarta?",Como você vai saber que ela está aberta?,,Cum vei știi că e deschisă?,"Как ты узнаешь, что дверь открыта?",,Hur vet du att den är öppen?,Açık olduğunu nereden bileceksin? Bring me back the guard's uniform. That way one of my ratfellows can wear it and no one will try to shut the door again.,TXT_DLG_SCRIPT06_D3032_BRING,〃,,,"Přines mi uniformu stráže, pak ji jeden z mých krysaříků může nosit a nikdo se už nepokusí ty dveře zavřít.","Giv mig vagtens uniform tilbage. På den måde kan en af mine rottefæller bære den, og ingen vil forsøge at lukke døren igen.","Bring mir die Uniform des Wächters. So kann einer meiner Rattenkumpel sie tragen und niemand wird wieder versuchen, die Tür zu schließen.",,"Alportu la uniformon de la gardisto, tiel unu el miaj «kamaratoj» surhavos ĝin kaj tiam neniu provos reŝlosi la pordon.","Tráeme el uniforme del guardia, así uno de mis «camarratas» podrá ponérselo para que nadie intente cerrarla de nuevo.","Tráeme el uniforme del guardia, así uno de mis «camarratas» va a poder ponérselo para que nadie intente cerrarla de nuevo.","Tuo minulle vartijan univormu. Silloin yksi rottakumppaneistani voi pitää sitä yllään, eikä kukaan yritä sulkea ovea enää uudelleen.","Ramenez moi l'uniforme du garde. Comme ça, un de mes amis rats pourra le porter et personne n'essaiera de fermer cette porte.","Hozd nekem vissza az őr egyenruháját. Az egyik besúgom felveszi, és nem lesz többé zárt ajtó előtte.",Portami l'uniforme della guardia. In questo modo uno dei nostri può indossarla e nessuno proverà più a chiudere la porta.,"ガードの制服を持ってくればいい。 そうすりゃ成り代わったラットの仲間が もう封鎖されないよう監視するだろうさ。 ","오더 병사가 입고 있는 전투복을 가져오려. 내 걸인 동료가 그걸 입고 입구를 걱정 없이 영원히 열 수 있게. - \cy끝내준다. 이제 시궁쥐 왕의 심부름도 해야 한다니.",Breng me het uniform van de bewaker terug. Op die manier kan een van mijn rattenvrienden het dragen en niemand zal proberen de deur weer te sluiten.,"Gi meg vaktuniformen. På den måten kan en av mine rottekamerater ha den på seg, og ingen vil prøve å lukke døren igjen.",Przynieś mi mundur strażnika. Tym sposobem jeden z moich szczurokolegów będzie mógł go założyć i nikt nie spróbuje znowu zamknąć drzwi.,Me traga de volta o uniforme do guarda. Dessa forma um dos meus companheiros pode vestí-la e ninguém vai tentar fechar a porta novamente.,,"Adu-mi uniforma gardianului. Așa, unui dintre noi o va putea purta și nimeni nu va încerca să mai închidă poata vreodată.","Принеси мне униформу стражника. Тогда один из моих приятелей сможет носить её, и никто не попытается снова закрыть дверь.",,Bana muhafız üniformasını geri getir. Böylece hain dostlarımdan biri onu giyebilir ve kimse kapıyı tekrar kapatmaya çalışmaz. -You want his uniform?,TXT_RPLY0_SCRIPT06_D3032_YOUWA,〃,,,Ty chceš jeho uniformu?,Vil du have hans uniform?,Du möchtest seine Uniform haben?,,Ĉu vi volas lian uniformon?,¿Quieres su uniforme?,,Haluat siis tämän univormun?,Vous voulez son uniforme?,Kell az egyenruhája?,Vuoi la sua uniforme?,あんたに制服を渡せばいいか?,그 전투복이 정말로 필요한가?,Wil je zijn uniform?,Vil du ha uniformen hans?,Chcesz jego mundur?,Você quer o uniforme dele?,,Vrei uniforma lui?,Тебе нужна его форма?,,Üniformasını mı istiyorsun? + \cy끝내준다. 이제 시궁쥐 왕의 심부름도 해야 한다니.",Breng me het uniform van de bewaker terug. Op die manier kan een van mijn rattenvrienden het dragen en niemand zal proberen de deur weer te sluiten.,"Gi meg vaktuniformen. På den måten kan en av mine rottekamerater ha den på seg, og ingen vil prøve å lukke døren igjen.",Przynieś mi mundur strażnika. Tym sposobem jeden z moich szczurokolegów będzie mógł go założyć i nikt nie spróbuje znowu zamknąć drzwi.,Me traga de volta o uniforme do guarda. Dessa forma um dos meus companheiros pode vestí-la e ninguém vai tentar fechar a porta novamente.,,"Adu-mi uniforma gardianului. Așa, unui dintre noi o va putea purta și nimeni nu va încerca să mai închidă poata vreodată.","Принеси мне униформу стражника. Тогда один из моих приятелей сможет носить её, и никто не попытается снова закрыть дверь.",,Ge mig vaktens uniform. På så sätt kan en av mina råttföljeslagare bära den och ingen kommer att försöka stänga dörren igen.,Bana muhafız üniformasını geri getir. Böylece hain dostlarımdan biri onu giyebilir ve kimse kapıyı tekrar kapatmaya çalışmaz. +You want his uniform?,TXT_RPLY0_SCRIPT06_D3032_YOUWA,〃,,,Ty chceš jeho uniformu?,Vil du have hans uniform?,Du möchtest seine Uniform haben?,,Ĉu vi volas lian uniformon?,¿Quieres su uniforme?,,Haluat siis tämän univormun?,Vous voulez son uniforme?,Kell az egyenruhája?,Vuoi la sua uniforme?,あんたに制服を渡せばいいか?,그 전투복이 정말로 필요한가?,Wil je zijn uniform?,Vil du ha uniformen hans?,Chcesz jego mundur?,Você quer o uniforme dele?,,Vrei uniforma lui?,Тебе нужна его форма?,,Vill du ha hans uniform?,Üniformasını mı istiyorsun? "Open the door, bring me the uniform and we trade. Otherwise, piss off.",TXT_DLG_SCRIPT06_D4548_OPENT,〃,,,"Otevři dveře, přines mi uniformu a budeme obchodovat. Jinak se jdi vycpat.","Åbn døren, giv mig uniformen, og vi bytter. Ellers skal du gå ud.","Öffne die Tür, bring mir die Uniform und wir können handeln. Ansonsten verschwinde.",,"Malfermu la pordon, alportu la uniformon kaj tiam ni intertraktos. Alie, malaperu.","Abre la puerta, tráeme el uniforme y negociamos. Si no, pírate.","Abre la puerta, tráeme el uniforme y negociamos. Caso contrario, esfúmate.","Avaa ovi, tuo minulle univormu ja teemme vaihtokaupan. Muuten suksi suohon.","Ouvrez la porte, ramenez moi l'uniforme et nous ferons affaire. Sinon, barrez-vous.","Nyisd k iaz ajtót, add ide az egyenruhát és üzletelhetünk. Ha nem, akkor húzz a túróba.","Apri l'ingresso, portami l'uniforme e allora possiamo trattare. Altrimenti, non abbiamo nulla da dirci.","そうだ、ゲートを開いて制服を奪うんだ。 それまで戻ってくるんじゃねえぞ。","입구를 열고, 전투복을 구해서, 교환 하자구려! 아님... 꺼지시라. - \cy얘도 분명 냄새 하나는 죽여줄 거야.","Open de deur, breng me het uniform en we handelen. Anders, piss off.","Åpne døra, gi meg uniformen, så bytter vi. Ellers kan du dra til helvete.",Otwórz drzwi i przynieś mundur to się dogadamy. Jeśli nie to spadaj.,"Abra a porta, traga o uniforme e nós negociaremos. Caso contrário, vaza daqui.",,"Deschide poarta, adu-mi uniforma, și facem schimbul. Altfel, șterge-o de aici.","Открой эту дверь, принеси мне униформу и мы сторгуемся. Иначе, отвали.",,"Kapıyı aç, bana üniformayı getir ve takas edelim. Yoksa defol git." -Have you brought me what I want?,TXT_DLG_SCRIPT06_D6064_HAVEY,〃,,,"Přinesl jsi mi, co chci?","Har du bragt mig det, jeg vil have?",Hast du mir was mitgebracht?,,"Ĉu vi alportis tion, kion mi volas?",¿Me has traído lo que quiero?,¿Trajiste lo que quiero?,"Oletko tuonut minulle sen, mitä haluan?",Avez-vous ramené ce dont j'ai besoin?,"Elhoztad, amit kértem?",Mi hai portato ciò che volevo?,必要な物は持ってきたか?,내가 원하는 것을 가지고 왔나랴?,Heb je me gebracht wat ik wil?,Har du det jeg vil ha?,Przyniosłeś to o co cię prosiłem?,Você trouxe o que eu quero?,,Mi-ai adus ceea ce doresc?,"Ты принёс мне то, что я просил?",,İstediğim şeyi getirdin mi? -How about this uniform?,TXT_RPLY0_SCRIPT06_D6064_HOWAB,〃,,,Co tahle uniforma?,Hvad med denne uniform?,Wie findest du diese Uniform?,,Kion pri ĉi tiu uniformo?,¿Qué tal este uniforme?,¿Qué hay de este uniforme?,Miten olisi tämä univormu?,"Il vous convient, cet uniforme?",És mi az újság ezzel az egyenruhával?,Che ne dici di questa uniforme?,この制服はどうだ?,이 전투복은 어때?,Hoe zit het met dit uniform?,Hva med denne uniformen?,Może być ten mundur?,Que tal este uniforme?,,Ce zici de uniforma asta?,Эта униформа подойдёт?,,Bu üniformaya ne dersin? -Bring me the uniform.,TXT_RNO0_SCRIPT06_D6064_BRING,,,,Přines mi tu uniformu.,Giv mig hans uniform.,Bring mir seine Uniform.,,Alportu la uniformon.,Tráeme el uniforme.,,Tuo univormu minulle.,Amenez moi l'uniforme.,Hozdd ide az egyenruhát.,Portami l'uniforme.,制服を持ってこい。,전투복을 가져와랴...,Breng me het uniform.,Gi meg uniformen.,Przynieś mi mundur.,Me traga o uniforme.,,Adu-mi uniforma.,Принеси мне униформу.,,Bana üniformayı getir. + \cy얘도 분명 냄새 하나는 죽여줄 거야.","Open de deur, breng me het uniform en we handelen. Anders, piss off.","Åpne døra, gi meg uniformen, så bytter vi. Ellers kan du dra til helvete.",Otwórz drzwi i przynieś mundur to się dogadamy. Jeśli nie to spadaj.,"Abra a porta, traga o uniforme e nós negociaremos. Caso contrário, vaza daqui.",,"Deschide poarta, adu-mi uniforma, și facem schimbul. Altfel, șterge-o de aici.","Открой эту дверь, принеси мне униформу и мы сторгуемся. Иначе, отвали.",,"Öppna dörren, ge mig uniformen och vi byter. Annars kan du dra åt helvete.","Kapıyı aç, bana üniformayı getir ve takas edelim. Yoksa defol git." +Have you brought me what I want?,TXT_DLG_SCRIPT06_D6064_HAVEY,〃,,,"Přinesl jsi mi, co chci?","Har du bragt mig det, jeg vil have?",Hast du mir was mitgebracht?,,"Ĉu vi alportis tion, kion mi volas?",¿Me has traído lo que quiero?,¿Trajiste lo que quiero?,"Oletko tuonut minulle sen, mitä haluan?",Avez-vous ramené ce dont j'ai besoin?,"Elhoztad, amit kértem?",Mi hai portato ciò che volevo?,必要な物は持ってきたか?,내가 원하는 것을 가지고 왔나랴?,Heb je me gebracht wat ik wil?,Har du det jeg vil ha?,Przyniosłeś to o co cię prosiłem?,Você trouxe o que eu quero?,,Mi-ai adus ceea ce doresc?,"Ты принёс мне то, что я просил?",,Har du gett mig det jag vill ha?,İstediğim şeyi getirdin mi? +How about this uniform?,TXT_RPLY0_SCRIPT06_D6064_HOWAB,〃,,,Co tahle uniforma?,Hvad med denne uniform?,Wie findest du diese Uniform?,,Kion pri ĉi tiu uniformo?,¿Qué tal este uniforme?,¿Qué hay de este uniforme?,Miten olisi tämä univormu?,"Il vous convient, cet uniforme?",És mi az újság ezzel az egyenruhával?,Che ne dici di questa uniforme?,この制服はどうだ?,이 전투복은 어때?,Hoe zit het met dit uniform?,Hva med denne uniformen?,Może być ten mundur?,Que tal este uniforme?,,Ce zici de uniforma asta?,Эта униформа подойдёт?,,Vad sägs om den här uniformen?,Bu üniformaya ne dersin? +Bring me the uniform.,TXT_RNO0_SCRIPT06_D6064_BRING,,,,Přines mi tu uniformu.,Giv mig hans uniform.,Bring mir seine Uniform.,,Alportu la uniformon.,Tráeme el uniforme.,,Tuo univormu minulle.,Amenez moi l'uniforme.,Hozdd ide az egyenruhát.,Portami l'uniforme.,制服を持ってこい。,전투복을 가져와랴...,Breng me het uniform.,Gi meg uniformen.,Przynieś mi mundur.,Me traga o uniforme.,,Adu-mi uniforma.,Принеси мне униформу.,,Ge mig uniformen.,Bana üniformayı getir. "Good. Here's something extra. My fellows tore this off of a fallen Crusader, it's the parts that make up a flamethrower. Now Irale can make one for you. You can have such fun.",TXT_DLG_SCRIPT06_D7580_GOODH,MAP06: Weran.,,,"Dobře. Tady je něco navíc. Mí stoupenci tohle urvali ze zničeného Křižáka, jsou to části, ze kterých se skládá plamenomet. Teď ti jeden může Irale postavit. Můžeš mít takové legrace.","Godt. Her er noget ekstra. Mine kammerater rev den af en faldet korsfarer, det er de dele, der udgør en flammekaster. Nu kan Irale lave en til dig. Du kan have det så sjovt.",Gut so. Hier ist ein kleiner Bonus. Meine Kumpel haben das hier von einem gefallenen Ordensritter abgerissen. Es sind die Teile seines Flammenwerfers. Jetzt kann Irale dir auch einen machen. Du kannst so viel Spaß damit haben...,,Bone. Jen aldonaĵo; miaj kamaradoj deŝiris ĝin de venkita Krucisto: ili estas partoj de flamĵetilo; Irale nun povos krei unu por vi. Vi vere amuziĝos.,Genial. Aquí tienes algo extra; mis compañeros lo arrancaron de un Cruzado caído: son las partes de un lanzallamas; ahora Irale puede hacer uno para ti. Te vas a divertir cantidad.,,"Hyvä. Tässä vielä jotain vähän lisäksi. Toverini repivät tämän kaatuneesta ristiretkeläisestä. Ne ovat liekinheittimen osia. Nyt Irale voi väsätä sinulle seillaisen. Ajattele sitä, kuinka hauskaa sinulla tulee olemaan.",Bien. Voilà un petit bonus. Mes amis ont arraché ceci à un croisé. C'est les pièces nécessaires à monter un lance-flammes. Irale peut en assembler un pour vous. Vous allez vraiment vous amuser.,"Helyes. Itt van egy kis érdekesség. Egyik bajtársam letörte ezeket az egyik keresztesről, igazából egy lángszórót lehetne összerakni belőle. Irale össze tudna rakni egyet neked. Tuti örömteli pörkölő pillanatokat fog okozni.","Eccellente. Ecco, ho qualcosa per te. I miei compagni hanno staccato questo da un Crociato distrutto, sono le parti che costituiscono il lanciafiamme. Adesso Irale ne può creare uno per te. Ti potrai divertire un sacco.","良し。礼は果たそう。 それと仲間が倒れたクルセイダーからこれを 奪ってきた、火炎放射器の部品らしい。 イラールに渡せば作り上げるはずだ。 -楽しみだろう。","아주 좋은 겨! 여기, 추가 보답을 받으라. 내 걸인 동료가 크루세이더의 잔해 속에서 이걸 구해냈다네에. 아주 좋은 화염방사기를 만들어낼 수 있을 거야. 이걸 들고 이롤리를 찾아가 바. 그리고... 요리를 즐기는 거쟈.","Goed. Hier is iets extra's. Mijn vrienden scheurden dit af van een gevallen kruisvaarder, het zijn de onderdelen die een vlammenwerper vormen. Nu kan Irale er een voor je maken. Je kunt zoveel plezier hebben.",Bra. Her er noe ekstra. Mine karer rev dette av en falne korsfarer. Det er delene til en flammekaster. Nå kan Irale lage en til deg. Du kan ha det så gøy.,"Dobrze. Oto mały bonus dla ciebie. Moi koledzy wyciągnęli to ze zniszczonego Krzyżowca, są to części do miotacza ognia. Teraz Irale będzie mógł taki dla ciebie zrobić. Będziesz miał dużo frajdy.",Muito bom. Aqui tem um brinde. Meus companheiros arrancaram isso de um Cruzado destruído. São peças para lança-chamas. Agora o Irale vai poder montar um pra você. Vai se divertir bastante.,,"Bun. Uite aici ceva în plus. Tovarășii mei au smuls asta de pe un Cruciat răpus, sunt părți ale unui aruncător de flăcări. Acum Irale îți poate construi unul. Te poți distra de minune.","Хорошо. Я могу предложить тебе кое-что сверх уговора. Мои приятели сняли это с подбитого крестоносца. Это детали огнемёта. Ирэйл соберёт его для тебя, и ты сможешь повеселиться от души.",,Güzel. Burada ekstra bir şey var. Arkadaşlarım bunu düşmüş bir Haçlı'dan kopardılar. Alev silahını oluşturan parçalar. Şimdi İrale senin için bir tane yapabilir. Çok eğlenebilirsiniz. -Where's the gate mechanism?,TXT_RPLY0_SCRIPT06_D7580_WHERE,〃,,,Kde je mechanismus brány?,Hvor er portmekanismen?,Wo ist der Tormechanismus?,,Kie estas la mekanismo de la kastelpordo?,¿Dónde está el mecanismo de la puerta?,,Missä portin koneisto on?,Où se trouve le mécanisme d'ouverture de la porte?,Hol van a kapu szerkezet?,Dov'è il meccanismo per il cancello?,ゲートメカニズムは何処だ?,관리 장치는 이제 어디있지?,Waar is het poortmechanisme?,Hvor er portmekanismen?,Gdzie jest mechanizm sterujący bramą?,Onde fica o mecanismo do portão?,,Unde e mecanismul de acționare al porții?,Где механизм управления воротами?,,Kapı mekanizması nerede? +楽しみだろう。","아주 좋은 겨! 여기, 추가 보답을 받으라. 내 걸인 동료가 크루세이더의 잔해 속에서 이걸 구해냈다네에. 아주 좋은 화염방사기를 만들어낼 수 있을 거야. 이걸 들고 이롤리를 찾아가 바. 그리고... 요리를 즐기는 거쟈.","Goed. Hier is iets extra's. Mijn vrienden scheurden dit af van een gevallen kruisvaarder, het zijn de onderdelen die een vlammenwerper vormen. Nu kan Irale er een voor je maken. Je kunt zoveel plezier hebben.",Bra. Her er noe ekstra. Mine karer rev dette av en falne korsfarer. Det er delene til en flammekaster. Nå kan Irale lage en til deg. Du kan ha det så gøy.,"Dobrze. Oto mały bonus dla ciebie. Moi koledzy wyciągnęli to ze zniszczonego Krzyżowca, są to części do miotacza ognia. Teraz Irale będzie mógł taki dla ciebie zrobić. Będziesz miał dużo frajdy.",Muito bom. Aqui tem um brinde. Meus companheiros arrancaram isso de um Cruzado destruído. São peças para lança-chamas. Agora o Irale vai poder montar um pra você. Vai se divertir bastante.,,"Bun. Uite aici ceva în plus. Tovarășii mei au smuls asta de pe un Cruciat răpus, sunt părți ale unui aruncător de flăcări. Acum Irale îți poate construi unul. Te poți distra de minune.","Хорошо. Я могу предложить тебе кое-что сверх уговора. Мои приятели сняли это с подбитого крестоносца. Это детали огнемёта. Ирэйл соберёт его для тебя, и ты сможешь повеселиться от души.",,"Jag har den. Här är något extra. Mina kamrater slet av den här från en stupad korsriddare, det är delarna som utgör en flamkastare. Nu kan Irale göra en åt dig. Du kan ha så roligt.",Güzel. Burada ekstra bir şey var. Arkadaşlarım bunu düşmüş bir Haçlı'dan kopardılar. Alev silahını oluşturan parçalar. Şimdi İrale senin için bir tane yapabilir. Çok eğlenebilirsiniz. +Where's the gate mechanism?,TXT_RPLY0_SCRIPT06_D7580_WHERE,〃,,,Kde je mechanismus brány?,Hvor er portmekanismen?,Wo ist der Tormechanismus?,,Kie estas la mekanismo de la kastelpordo?,¿Dónde está el mecanismo de la puerta?,,Missä portin koneisto on?,Où se trouve le mécanisme d'ouverture de la porte?,Hol van a kapu szerkezet?,Dov'è il meccanismo per il cancello?,ゲートメカニズムは何処だ?,관리 장치는 이제 어디있지?,Waar is het poortmechanisme?,Hvor er portmekanismen?,Gdzie jest mechanizm sterujący bramą?,Onde fica o mecanismo do portão?,,Unde e mecanismul de acționare al porții?,Где механизм управления воротами?,,Var är grindmekanismen?,Kapı mekanizması nerede? "You have to enter another part of the sewers. To get there you must enter the castle from a sewer maintenance door and drain the fluid reclamation tank. At the bottom is the hidden entrance to sewers, and right beyond that is the manual gate control.",TXT_DLG_SCRIPT06_D9096_YOUHA,"〃 https://en.wikipedia.org/wiki/Reclaimed_water",,,Musíš vejít do jiné části stok. K tomu se potřebuješ údržbovými dveřmi dostat do hradu a vypustit záchytnou nádrž. Na dně je schovaný vchod do stok a hned za ním je manuální ovládání brány.,"Du skal ind i en anden del af kloakkerne. For at komme derhen skal du gå ind i slottet fra en dør til vedligeholdelse af kloakken og tømme væskegenvindingsbeholderen. Nederst er den skjulte indgang til kloakkerne, og lige bagved er den manuelle portkontrol.","Du musst in einen anderen Teil der Kanalisation. Um dort hinzukommen, musst du durch einen Wartungsgang in die Burg und den Wasserrückgewinnungstank entleeren. Am Boden des Tanks ist der versteckte Eingang zur Kanalisation und gleich dahinter die manuelle Torkontrolle.",,"Vi devas iri al alia parto de la kloakoj. Por atingi tien, vi devas eniri la kastelon tra pordo de ĉambro pri kloaka bontenado kaj dreni la rezervujon de akvoreuzo; en ĝia fundo estas kaŝita enirejo al la kloakoj, kaj ie tie estas la mana regilo de la pordo.",Tienes que adentrarte en otra parte de las cloacas. Para llegar ahí debes entrar en el castillo por la puerta de mantenimiento de las cloacas y drenar el tanque de recuperación de agua; al fondo está la entrada oculta a las cloacas y por ahí mismo el control manual de la puerta.,Tienes que ir a otra parte de las cloacas. Para llegar ahí debes entrar al castillo por la puerta de mantenimiento de las cloacas y drenar el tanque de recuperación de agua; al fondo está la entrada oculta a las cloacas y por ahí mismo el control manual de la puerta.,"Sinun on mentävä viemäreiden eri osioon. Päästäksesi sinne sinun on mentävä linnaan viemäreiden huolto-oven kautta ja tyhjennettävä nesteentalteenottoallas. Altaan pohjalla on viemärin salainen sisäänkäynti, ja suoraan sen jäljessä on portin käsiohjain.","Vous devez entrer dans une autre section des égouts. Quand vous y êtes, vous devez entrer dans le château à partir de la porte de maintenance des égouts, et drainer le réservoir de recyclage d'eau. Au fond se trouve l'entrée cachée des égouts, et juste après elle, les contrôles manuels de la porte.","A kanális egy másik részébe kell menned. Ehhez egy szervízajtón keresztül kell behatolnod a kastélyba, úgy hogy leereszted a szárító tartályból. Az alján található a titkos kanális bejárat, és rögtön utána a kézi kapu irányító.","Devi andare in un'altra sezione delle fogne. Per raggiungerla, devi entrare nel castello da una porta di manutenzione delle fogne e svuotare la vasca di recupero fluidi. Al fondo di questa vasca c'è l'uscita nascosta per le fogne, e subito dopo c'è il controllo manuale dei cancelli.","下水道の別の部分に入る必要がある。 @@ -10591,118 +11073,118 @@ https://en.wikipedia.org/wiki/Reclaimed_water",,,Musíš vejít do jiné části 城の浄水施設に入りタンクを排水する必要がある その下には隠された入り口があり、 その先に手動ゲートコントロールがあるはずだ。","하수도로 통하는 또 다른 입구로 가야 혀. 들어가려면 성안에 위치한 하수도 정비소에서 수조에 있는 오물을 배출해야 해. 그 수조 밑에는 하수도로 향하는 숨겨진 입구가 있고, 그곳으로 향하면, 정문의 장치를 찾을 수 있을 게야. - \cy또 하수도라... 끝내준다. 저 아래에 또 뭐가 살고 있을까?","Je moet een ander deel van de riolering betreden. Om daar te komen moet je het kasteel binnengaan via een deur voor het onderhoud van de riolering en de vloeistoftank aftappen. Onderaan is de verborgen toegang tot de riolering, en net daarachter is de handmatige poortbesturing.","Du må gå inn i en annen del av kloakken. For å komme dit må du gå inn i slottet fra en kloakkvedlikeholdsdør og tømme væskegjenvinningstanken. Nederst er den skjulte inngangen til kloakken, og rett bortenfor den er den manuelle portkontrollen.","Musisz wejść do innej części kanałów. Aby się tam dostać musisz wejść do zamku przez drzwi sekcji konserwacji ścieków i osuszyć zbiornik rekultywacyjny. Na dole znajduje się ukryte przejście do kanałów, a za nim jest mechanizm bramy.",Você precisa entrar em outra parte do esgoto. Para chegar até lá você deve entrar no castelo por uma porte de manutenção de esgoto e drenar o tanque de recuperação de fluído. Lá no fundo fica a entrada oculta do esgoto e logo adiante fica o controle manual do portão.,,"Va trebui să intrăm pe altă parte a canalelor. Ca să ajungi acolo trebuie să intri în castel printr-o ușa de mentenanță a canalului și să drenezi rezervorul. La bază e intrarea în canale, și imediat după aceea e controlul manual al porții.","Это в другой части канализации. Чтобы попасть туда, пройди в замок через дверь обслуживания канализации и слей жидкость из бака для переработки. На его дне есть скрытый вход в стоки, и прямо за ним — ручной механизм управления воротами.",,Kanalizasyonun başka bir bölümüne girmelisin. Oraya ulaşmak için kaleye bir kanalizasyon bakım kapısından girmeli ve sıvı geri kazanım tankını boşaltmalısınız. En altta kanalizasyonun gizli girişi ve onun hemen ötesinde de manuel kapı kontrolü var. -Anything else you can do?,TXT_RPLY0_SCRIPT06_D9096_ANYTH,〃,,,Mohl bys udělat ještě něco?,"Er der andet, du kan gøre?",Kannst du sonst noch was für mich tun?,,"Ĉu estas io alia, kion vi povas fari?",¿Algo más que puedas hacer?,,Voitko olla vielä jotenkin muuten avuksi?,Que pouvez vous faire d'autre?,Tudsz még valamit tenni?,C'è qualcos'altro che puoi fare?,他に出来ることは?,그 외에 당신이 할 수 있는 일은?,Kun je nog iets anders doen?,Noe annet du kan gjøre?,Czy coś jeszcze możesz zrobić?,Algo mais que você possa fazer?,,Mai poți face altceva?,Можешь помочь мне чем-нибудь ещё?,,Yapabileceğin başka bir şey var mı? + \cy또 하수도라... 끝내준다. 저 아래에 또 뭐가 살고 있을까?","Je moet een ander deel van de riolering betreden. Om daar te komen moet je het kasteel binnengaan via een deur voor het onderhoud van de riolering en de vloeistoftank aftappen. Onderaan is de verborgen toegang tot de riolering, en net daarachter is de handmatige poortbesturing.","Du må gå inn i en annen del av kloakken. For å komme dit må du gå inn i slottet fra en kloakkvedlikeholdsdør og tømme væskegjenvinningstanken. Nederst er den skjulte inngangen til kloakken, og rett bortenfor den er den manuelle portkontrollen.","Musisz wejść do innej części kanałów. Aby się tam dostać musisz wejść do zamku przez drzwi sekcji konserwacji ścieków i osuszyć zbiornik rekultywacyjny. Na dole znajduje się ukryte przejście do kanałów, a za nim jest mechanizm bramy.",Você precisa entrar em outra parte do esgoto. Para chegar até lá você deve entrar no castelo por uma porte de manutenção de esgoto e drenar o tanque de recuperação de fluído. Lá no fundo fica a entrada oculta do esgoto e logo adiante fica o controle manual do portão.,,"Va trebui să intrăm pe altă parte a canalelor. Ca să ajungi acolo trebuie să intri în castel printr-o ușa de mentenanță a canalului și să drenezi rezervorul. La bază e intrarea în canale, și imediat după aceea e controlul manual al porții.","Это в другой части канализации. Чтобы попасть туда, пройди в замок через дверь обслуживания канализации и слей жидкость из бака для переработки. На его дне есть скрытый вход в стоки, и прямо за ним — ручной механизм управления воротами.",,"Du måste gå in i en annan del av kloakerna. För att komma dit måste du gå in i slottet från en dörr för underhåll av kloakerna och tömma vätskereklamationstanken. Längst ner finns den dolda ingången till kloakerna, och precis bakom den finns den manuella grindmekanismen.",Kanalizasyonun başka bir bölümüne girmelisin. Oraya ulaşmak için kaleye bir kanalizasyon bakım kapısından girmeli ve sıvı geri kazanım tankını boşaltmalısınız. En altta kanalizasyonun gizli girişi ve onun hemen ötesinde de manuel kapı kontrolü var. +Anything else you can do?,TXT_RPLY0_SCRIPT06_D9096_ANYTH,〃,,,Mohl bys udělat ještě něco?,"Er der andet, du kan gøre?",Kannst du sonst noch was für mich tun?,,"Ĉu estas io alia, kion vi povas fari?",¿Algo más que puedas hacer?,,Voitko olla vielä jotenkin muuten avuksi?,Que pouvez vous faire d'autre?,Tudsz még valamit tenni?,C'è qualcos'altro che puoi fare?,他に出来ることは?,그 외에 당신이 할 수 있는 일은?,Kun je nog iets anders doen?,Noe annet du kan gjøre?,Czy coś jeszcze możesz zrobić?,Algo mais que você possa fazer?,,Mai poți face altceva?,Можешь помочь мне чем-нибудь ещё?,,Finns det något annat du kan göra?,Yapabileceğin başka bir şey var mı? "Good luck. I've opened several of our tunnels for you. It should make your task easier. Oh, size ten, perfect! ...But dreadful colors.",TXT_DLG_SCRIPT06_D10612_GOODL,〃,,,"Hodně štěstí. Otevřel jsem pro tebe několik našich tunelů. To by ti mělo tvůj úkol usnadnit. Ó, velikost deset, perfektní! ...Ale barva je hrozná.","Held og lykke. Jeg har åbnet flere af vores tunneler for dig. Det burde gøre din opgave lettere. Åh, størrelse ti, perfekt! ...Men forfærdelige farver.","Viel Glück. Ich habe mehrere von unseren Tunnels für dich geöffnet. Es sollte deine Aufgabe vereinfachen. Oh, Größe 10. Perfekt! Aber scheußliche Farben...",,"Ŝancon. Mi malfermis diversajn el niaj tuneloj. Tio devus faciligi la taskon por vi. Ha, la uniformo havas M-an talion. Perfekte!... Sed ĝiaj koloroj estas aĉaj.","Buena suerte. Te he abierto varios de nuestros túneles; eso debería facilitarte las cosas. Ah, es de talla 40. ¡Perfecto!... Aunque de colores espantosos.","Buena suerte. Te abrimos varios de nuestros túneles; eso debería facilitarte las cosas. Ah, es de talle M. ¡Perfecto!... Aunque de colores espantosos.","Lykkyä tykö. Olen aukaissut useita tunneleistamme sinulle, minkä pitäisi helpottaa tehtävääsi. Kas, kokoa kymmenen, prikulleen sopiva! ...Mutta aivan hirveän värinen.","Bonne chance. J'ai ouvert plusieurs de nos tunnels pour vous. Ca devrait rendre votre travail plus facile. Oh! Taille dix? Parfait! Les couleurs sont immondes, par contre.","Sok sikert. Kinyitottam számos alagutat neked. Meg kell, hogy könnyítse a dolgodat. Oh, tízes méret, tökéletes!...de milyen okádék színek.","Buona fortuna. Ho aperto diversi dei nostri tunnel per te. Così dovrebbe essere più facile per te. Ah, taglia dieci, perfetto! ...Ma pessimi colori.","頑張れよ。それとアンタの為に俺達は幾つか トンネルを開けといた。多少はやり易くなるだろ。 おぅ、サイズは10型か、ピッタリだ! -...だが、おっかねえ色してんな。","행운을 빈다. 지름길을 좀 열어놨어야. 덕분에 과제가 좀 쉬워질 거다. 오, 딱맞는 치수구먼! 완벽해... 그런데 색상이 별로다.","Veel succes. Ik heb een aantal van onze tunnels voor u geopend. Het moet uw taak gemakkelijker maken. Oh, maat tien, perfect! ...Maar vreselijke kleuren.","Lykke til. Jeg har åpnet flere av tunnelene våre for deg. Det burde gjøre oppgaven din lettere. Å, størrelse ti, perfekt! ...men forferdelige farger.","Powodzenia. Otworzyłem kilka naszych tuneli dla ciebie. To powinno ci ułatwić zadanie. Oh, rozmiar dziesięć, idealnie! ...Ale paskudne kolory.","Boa sorte. Eu abri alguns de nossos túneis pra você. Acho que vai facilitar o seu trabalho. Ah, tamanho M, perfeito! ...Mas as cores são um horror.",,"Noroc. Am deschis câteva canale pentru tine. Ar trebui să îți ușureze munca. Ah, mărimea zece, perfect! ...Dar cumplite culori.","Разве что пожелать удачи. Я открыл для тебя несколько наших туннелей, это может сделать твою задачу чуть проще. О, десятый размер! Как раз впору!.. Но остойные цвета.",,"İyi şanslar. Sizin için birkaç tünelimizi açtım. İşinizi kolaylaştıracaktır. Oh, 10 numara, mükemmel! ...Ama korkunç renkler." -Thanks for your help.,TXT_RPLY0_SCRIPT06_D10612_THANK,〃,,,Díky za pomoc.,Tak for din hjælp.,Danke für deine Hilfe.,,Dankon pro la helpo.,Gracias por la ayuda.,,Kiitos avustasi.,Merci pour votre aide.,Köszi a segítséget.,Grazie del tuo aiuto.,協力ありがとう。,도움 정말 고마워.,Bedankt voor je hulp.,Takk for hjelpen.,Dzięki za twoją pomoc.,Obrigado pela ajuda.,,Merci de ajutor.,Спасибо за помощь.,,Yardımınız için teşekkürler. -"You give me nothing, you get nothing.",TXT_DLG_SCRIPT06_D12128_YOUGI,〃,,,"Ty mi nic nedáš, já ti nic nedám.","Hvis du ikke giver mig noget, får du intet.","Du gibst mir nichts, ich gebe dir nichts.",,"Se vi donos nenion, vi ricevos nenion.","No me das nada, no recibes nada.",,"Jos et anna minulle mitään, et vastavuoroin mitään saakaan.","Vous ne me donnez rien, je ne vous donne rien.","Nem adsz semmit, nem kapsz semmit.","Se non mi dai niente, non ricevi niente!",何も無ければ、何も渡すモンは無い。,헤헤... 아무 일도 없는 거니 괜찮야!,"Je geeft me niets, je krijgt niets.","Du gir meg ingenting, du får ingenting.","Nic mi nie dajesz, nic nie dostajesz.","Você não me dá nada, não ganha nada.",,"Nu dai nimic, primești nimic.",Ничего не даёшь — ничего не получаешь.,,"Bana bir şey vermezsen, hiçbir şey alamazsın." +...だが、おっかねえ色してんな。","행운을 빈다. 지름길을 좀 열어놨어야. 덕분에 과제가 좀 쉬워질 거다. 오, 딱맞는 치수구먼! 완벽해... 그런데 색상이 별로다.","Veel succes. Ik heb een aantal van onze tunnels voor u geopend. Het moet uw taak gemakkelijker maken. Oh, maat tien, perfect! ...Maar vreselijke kleuren.","Lykke til. Jeg har åpnet flere av tunnelene våre for deg. Det burde gjøre oppgaven din lettere. Å, størrelse ti, perfekt! ...men forferdelige farger.","Powodzenia. Otworzyłem kilka naszych tuneli dla ciebie. To powinno ci ułatwić zadanie. Oh, rozmiar dziesięć, idealnie! ...Ale paskudne kolory.","Boa sorte. Eu abri alguns de nossos túneis pra você. Acho que vai facilitar o seu trabalho. Ah, tamanho M, perfeito! ...Mas as cores são um horror.",,"Noroc. Am deschis câteva canale pentru tine. Ar trebui să îți ușureze munca. Ah, mărimea zece, perfect! ...Dar cumplite culori.","Разве что пожелать удачи. Я открыл для тебя несколько наших туннелей, это может сделать твою задачу чуть проще. О, десятый размер! Как раз впору!.. Но остойные цвета.",,"Lycka till. Jag har öppnat flera av våra tunnlar åt dig. Det borde göra din uppgift lättare. Åh, storlek tio, perfekt! ...men hemska färger.","İyi şanslar. Sizin için birkaç tünelimizi açtım. İşinizi kolaylaştıracaktır. Oh, 10 numara, mükemmel! ...Ama korkunç renkler." +Thanks for your help.,TXT_RPLY0_SCRIPT06_D10612_THANK,〃,,,Díky za pomoc.,Tak for din hjælp.,Danke für deine Hilfe.,,Dankon pro la helpo.,Gracias por la ayuda.,,Kiitos avustasi.,Merci pour votre aide.,Köszi a segítséget.,Grazie del tuo aiuto.,協力ありがとう。,도움 정말 고마워.,Bedankt voor je hulp.,Takk for hjelpen.,Dzięki za twoją pomoc.,Obrigado pela ajuda.,,Merci de ajutor.,Спасибо за помощь.,,Tack för hjälpen.,Yardımınız için teşekkürler. +"You give me nothing, you get nothing.",TXT_DLG_SCRIPT06_D12128_YOUGI,〃,,,"Ty mi nic nedáš, já ti nic nedám.","Hvis du ikke giver mig noget, får du intet.","Du gibst mir nichts, ich gebe dir nichts.",,"Se vi donos nenion, vi ricevos nenion.","No me das nada, no recibes nada.",,"Jos et anna minulle mitään, et vastavuoroin mitään saakaan.","Vous ne me donnez rien, je ne vous donne rien.","Nem adsz semmit, nem kapsz semmit.","Se non mi dai niente, non ricevi niente!",何も無ければ、何も渡すモンは無い。,헤헤... 아무 일도 없는 거니 괜찮야!,"Je geeft me niets, je krijgt niets.","Du gir meg ingenting, du får ingenting.","Nic mi nie dajesz, nic nie dostajesz.","Você não me dá nada, não ganha nada.",,"Nu dai nimic, primești nimic.",Ничего не даёшь — ничего не получаешь.,,"Du ger mig inget, du får inget.","Bana bir şey vermezsen, hiçbir şey alamazsın." Weran will save us. He's never failed us yet.,TXT_DLG_SCRIPT06_D13644_WERAN,MAP06: Beggar.,,,Weran nás zachrání. Ještě nás nezklamal.,Weran vil redde os. Han har aldrig svigtet os endnu.,Weran wird uns retten. Er hat uns noch nie enttäuscht.,,Weran savos nin: li neniam desapontis nin.,Weran nos salvará: nunca nos ha fallado.,Weran nos va a salvar: nunca nos ha fallado.,Weran pelastaa meidät. Hän ei ole vielä kertaakaan pettänyt meitä.,Weran nous sauvera. Il ne nous a jamais failli.,Weran majd megment minket. Eddig sosem hagyott minket cserben.,Weran ci salverà. Non ci ha mai deluso fin'ora.,"ウェランは皆を保護してくれている。 -彼は誰も見捨てたことはない。",워렌이 우리들을 구원해 줄 겁니다. 그는 아직 믿어도 되니까요.,Weran zal ons redden. Hij heeft ons nog nooit teleurgesteld.,Weran vil redde oss. Han har aldri sviktet oss før.,Weran nas uratuje. Jeszcze nigdy nas nie zawiódł.,Weran vai nos salvar. Ele nunca nos deixou na mão.,,Weran ne va salva. Nu ne-a dezamăgit până acum.,Уэран поможет нам. Он ещё ни разу не подводил нас.,,Weran bizi kurtaracak. Şimdiye kadar bizi hiç hayal kırıklığına uğratmadı. +彼は誰も見捨てたことはない。",워렌이 우리들을 구원해 줄 겁니다. 그는 아직 믿어도 되니까요.,Weran zal ons redden. Hij heeft ons nog nooit teleurgesteld.,Weran vil redde oss. Han har aldri sviktet oss før.,Weran nas uratuje. Jeszcze nigdy nas nie zawiódł.,Weran vai nos salvar. Ele nunca nos deixou na mão.,,Weran ne va salva. Nu ne-a dezamăgit până acum.,Уэран поможет нам. Он ещё ни разу не подводил нас.,,Weran kommer att rädda oss. Han har aldrig svikit oss än.,Weran bizi kurtaracak. Şimdiye kadar bizi hiç hayal kırıklığına uğratmadı. "If you seek an answer to your problem, find Weran. ",TXT_DLG_SCRIPT06_D15160_IFYOU,〃,,,"Jestli hledáš odpověď na svou otázku, najdi Werana.","Hvis du søger et svar på dit problem, så find Weran.","Wenn du Lösungen für deine Probleme suchst, frag Weran.",,"Se vi serĉas respondon al via problemo, renkontu Weran-on.","Si buscas una respuesta a tu problema, ve con Weran.",,"Jos haet vastausta ongelmaasi, etsi Weran.","Si vous avez besoin d'une réponse à vos problèmes, allez voir Weran.","Ha választ keresel a problémádra, akkor keresd fel Werant.","Se cerchi una soluzione al tuo problema, torva Weran.","君の問題の答えが欲しいなら、 -ウェランに会うといい。","문제를 해결할 해답을 찾고 계신다면, 워렌을 찾아가세요.","Als je een antwoord zoekt op je probleem, vind Weran.","Hvis du søker et svar på problemet ditt, finn Weran.","Jeśli szukasz rozwiązania swojego problemu, poszukaj Werana.","Se você precisa de um resposta para o seu problema, procure Weran.",,"Dacă ești în căutarea unor răspunsuri, găsește-l pe Weran.",Тебе нужен ответ? Найди Уэрана.,,"Eğer sorununuza bir cevap arıyorsanız, Weran'ı bulun." +ウェランに会うといい。","문제를 해결할 해답을 찾고 계신다면, 워렌을 찾아가세요.","Als je een antwoord zoekt op je probleem, vind Weran.","Hvis du søker et svar på problemet ditt, finn Weran.","Jeśli szukasz rozwiązania swojego problemu, poszukaj Werana.","Se você precisa de um resposta para o seu problema, procure Weran.",,"Dacă ești în căutarea unor răspunsuri, găsește-l pe Weran.",Тебе нужен ответ? Найди Уэрана.,,"Om du söker ett svar på ditt problem, hitta Weran.","Eğer sorununuza bir cevap arıyorsanız, Weran'ı bulun." Long live the Front? That's all crap. We're all just waiting to die. ,TXT_DLG_SCRIPT06_D16676_LONGL,〃,,,Ať žije Fronta? To je blbost. Všichni jen čekáme na smrt.,Længe leve fronten? Det er alt sammen noget lort. Vi venter alle bare på at dø.,Lang lebe die Front? Was für ein Mist. Wir warten doch nur auf den Tod.,,Ĉu vivu la Fronto? Kia fekaĵo. Ni ĉiuj atendas morton.,¿Que viva el Frente? Menuda mierda. A todos nos espera la muerte.,¿Que viva el Frente? Pura mierda. A todos nos espera la muerte.,Kauan eläköön Rintama? Täyttä puppua. Me kaikki vain odotamme kuolemaa.,Longue vie au Front? Quelles conneries! On est tous en train d'attendre de mourir!,"Éljen a Front? Mekkora baromság. Csak arra várunk, hogy meghaljunk.",Lunga vita al Fronte? Sono tutte idiozie. Stiamo tutti in attesa di morire.,"フロントに入れ? 馬鹿げてる。 -死ねと言ってるようなもんだ。",프론트와 자유를 향하여... 는 개뿔. 때문에 우리들만 죽게 생겼어요.,Lang leve het Front? Dat is allemaal onzin. We wachten allemaal op de dood.,Lenge leve Fronten? Det er bare tull. Vi venter bare på å dø.,Niech żyje Front? To wszystko to gówno. My po prostu czekamy na śmierć.,Viva a Frente? Isso é besteira. Todos nós estamos esperando a morte.,,Să trăiască Frontul? Aiureli. Doar așteptăm să murim.,Да здравствует Сопротивление? Это всё чушь. Мы все просто ждём смерти.,,Cephe çok yaşa mı? Bunların hepsi saçmalık. Hepimiz ölmeyi bekliyoruz. +死ねと言ってるようなもんだ。",프론트와 자유를 향하여... 는 개뿔. 때문에 우리들만 죽게 생겼어요.,Lang leve het Front? Dat is allemaal onzin. We wachten allemaal op de dood.,Lenge leve Fronten? Det er bare tull. Vi venter bare på å dø.,Niech żyje Front? To wszystko to gówno. My po prostu czekamy na śmierć.,Viva a Frente? Isso é besteira. Todos nós estamos esperando a morte.,,Să trăiască Frontul? Aiureli. Doar așteptăm să murim.,Да здравствует Сопротивление? Это всё чушь. Мы все просто ждём смерти.,,Länge leve fronten? Det är bara skit. Vi väntar bara på att dö.,Cephe çok yaşa mı? Bunların hepsi saçmalık. Hepimiz ölmeyi bekliyoruz. "With our passage to the surface sealed, we can't even feed ourselves.",TXT_DLG_SCRIPT06_D18192_WITHO,〃,,,"Když je cesta na povrch uzavřená, nemůžeme se ani nakrmit.","Med vores passage til overfladen forseglet, kan vi ikke engang brødføde os selv.","Da unser Zugang zur Oberfläche verschlossen ist, haben wir nichts mehr zu essen.",,"Ĉar nia irado al la surfaco estas ŝlosita, ni eĉ ne povas nutri nin.","Con nuestro pasaje a la superficie cerrado, no podemos ni alimentarnos.",,Pääsymme maanpinnalle ollessa salvattuna emme voi edes ruokkia itseämme.,"Avec notre passage vers la surface scellé, on ne peut même plus se nourrir.","Mivel a felszínre vezető átjáró el van zárva, még ételhez sem jutunk.","Con il passaggio verso la superfice chiuso, non possiamo neanche mangiare.","外への出入口が封鎖されてるから、 飯が調達できないんだ。 -","오더가 지상으로 향하는 입구를 막은 이상, 우리는 굶어 죽어야 할 운명에 시달려야 해요.","Met onze doorgang naar de oppervlakte afgesloten, kunnen we onszelf niet eens voeden.","Nå som passasjen til overflaten er stengt, kan vi ikke engang få mat.",Z zamkniętą naszą drogą na powierzchnię nie możemy się nawet nakarmić.,"Com a nossa passagem para a superfície selada, não somos capazes nem de nos alimentar.",,"Cu calea spre suprafață sigilată, nici măcar nu ne putem hrănii.","Пока выход на поверхность закрыт, мы не можем даже прокормить себя.",,Yüzeye geçişimiz mühürlü olduğu için kendimizi bile besleyemiyoruz. -"Food, do you have any food? Please help us.",TXT_DLG_SCRIPT06_D19708_FOODD,〃,,,"Jídlo, nemáš nějaké jídlo? Pomoz nám, prosím.","Mad, har du noget mad? Vær sød at hjælpe os.","Essen, hast du was zu essen? Bitte hilf uns.",,Manĝaĵoj... Ĉu vi havas manĝaĵojn? Bonvolu helpi nin.,"Comida... ¿No tendrás algo de comida? Ayúdanos, por favor.",,"Ruokaa, onko sinulla yhtään ruokaa? Pyydän, auta meitä.","A manger, vous avez à manger? Aidez-nous, s'il vous plaît.","Étel, van nálad valami étel? Kérlek segíts nekünk.","Cibo, hai del cibo? Per favore aiutaci.",食い物、食い物を恵んでくれないか? 頼むよ。,굶어 죽을 것 같습니다... 부디 음식 찌꺼기라도 괜찮으니까 음식을...,"Eten, heb je eten? Help ons alstublieft.","Mat, har du noe mat? Vær så snill, hjelp oss.","Jedzenie, masz może jakieś jedzenie? Proszę pomóż nam.",Comida. Você tem alguma comida? Por favor nos ajude.,,"Mâncare, ai mâncare? Te rog ajută-ne.","Еда. У тебя есть еда? Пожалуйста, помоги нам.",,"Yiyecek, hiç yiyeceğiniz var mı? Lütfen bize yardım edin." +","오더가 지상으로 향하는 입구를 막은 이상, 우리는 굶어 죽어야 할 운명에 시달려야 해요.","Met onze doorgang naar de oppervlakte afgesloten, kunnen we onszelf niet eens voeden.","Nå som passasjen til overflaten er stengt, kan vi ikke engang få mat.",Z zamkniętą naszą drogą na powierzchnię nie możemy się nawet nakarmić.,"Com a nossa passagem para a superfície selada, não somos capazes nem de nos alimentar.",,"Cu calea spre suprafață sigilată, nici măcar nu ne putem hrănii.","Пока выход на поверхность закрыт, мы не можем даже прокормить себя.",,Med vår passage till ytan förseglad kan vi inte ens föda oss själva.,Yüzeye geçişimiz mühürlü olduğu için kendimizi bile besleyemiyoruz. +"Food, do you have any food? Please help us.",TXT_DLG_SCRIPT06_D19708_FOODD,〃,,,"Jídlo, nemáš nějaké jídlo? Pomoz nám, prosím.","Mad, har du noget mad? Vær sød at hjælpe os.","Essen, hast du was zu essen? Bitte hilf uns.",,Manĝaĵoj... Ĉu vi havas manĝaĵojn? Bonvolu helpi nin.,"Comida... ¿No tendrás algo de comida? Ayúdanos, por favor.",,"Ruokaa, onko sinulla yhtään ruokaa? Pyydän, auta meitä.","A manger, vous avez à manger? Aidez-nous, s'il vous plaît.","Étel, van nálad valami étel? Kérlek segíts nekünk.","Cibo, hai del cibo? Per favore aiutaci.",食い物、食い物を恵んでくれないか? 頼むよ。,굶어 죽을 것 같습니다... 부디 음식 찌꺼기라도 괜찮으니까 음식을...,"Eten, heb je eten? Help ons alstublieft.","Mat, har du noe mat? Vær så snill, hjelp oss.","Jedzenie, masz może jakieś jedzenie? Proszę pomóż nam.",Comida. Você tem alguma comida? Por favor nos ajude.,,"Mâncare, ai mâncare? Te rog ajută-ne.","Еда. У тебя есть еда? Пожалуйста, помоги нам.",,"Mat, har ni någon mat? Snälla, hjälp oss.","Yiyecek, hiç yiyeceğiniz var mı? Lütfen bize yardım edin." "This is my reward for letting prisoners escape, guarding the sewers. If I ever find the guy who broke them out, I'll slaughter him.",TXT_DLG_SCRIPT06_D21224_THISI,MAP06: Gray acolyte.,,,"Tohle je má odměna za to, že jsem nechal utéct vězně: hlídání stok. Jestli někdy najdu toho hajzla, který je pustil, zabiju ho.","Dette er min belønning for at lade fanger flygte og bevogte kloakkerne. Hvis jeg nogensinde finder den fyr, der brød dem ud, vil jeg slagte ham.","Das ist meine Belohnung dafür, dass ich die Gefangenen entkommen lassen habe. Jetzt darf ich die Kanalisation bewachen. Wenn ich jemals den Kerl finde, der das gemacht hat, mache ich Hackfleisch aus ihm!",,"Jen mia rekompenco pro tio, ke mi ne evitis la liberigon de la ekskaptitoj: gardi la kloakojn. Se mi iam trovas la liberiginton, mi mortigos lin.","Esta es mi recompensa por dejar escapar a los prisioneros: vigilar las cloacas. Si llego a encontrar al tipo que los ha liberado, me lo cargo.","Esta es mi recompensa por dejar escapar a los prisioneros: vigilar las cloacas. Si llego a encontrar al tipo que los liberó, lo asesino.","Tämä on minun palkkani siitä hyvästä, että päästin vangit pakenemaan: viemäreiden vartiointi. Jos ikinä saan käsiini sen tyypin, joka päästi ne pakoon, lahtaan sen.","Voici ma récompense pour avoir laissé les prisonniers s'évader: garder les égouts. Si je trouve celui qui les a libéré, je l'étripe.","Ez a jutalmam amiért hagytam elszökni a foglyokat. Ha meglelem az ürgét aki kiszabadította őket, biztosan kicsinálom.","Ecco la mia ricompensa per aver fatto scappare i prigionieri, fare la guardia alle fogne. Se mai trovo chi li ha liberati, lo faccio a pezzi.","この下水道から囚人を脱走させた奴を探す為、 下水道を監視している。首謀者を見つけたら、 -その命を持って報いを受けてもらう。","수감자들의 탈옥을 막지 못해서 하수도를 지키게 되었어. 만약 탈옥하게 만든 녀석을 만난다면, 녀석이 죽을 때 까지 내장을 천천히 끄집어낼 거다.","Dit is mijn beloning voor het laten ontsnappen van gevangenen, het bewaken van de riolering. Als ik ooit de man vind die ze heeft uitgebroken, zal ik hem afslachten.","Dette er belønningen min for å la fanger rømme og vokte kloakken. Hvis jeg finner fyren som slapp dem ut, skal jeg slakte ham.","To moja nagroda za pozwolenie więźniom uciec, pilnowanie ścieków. Jeśli kiedyklowiek dorwę tego, kto pomógł im uciec, to go zamorduję.","Essa é a minha recompensa por deixar os prisioneiros escaparem. Vigiar o esgoto. Se algum dia eu encontrar o cara que soltou eles, eu vou arrancar os seus pedaços.",,"Asta e răsplata mea pentru că am lăsat prizonieri să scape, apărarea canalelor. Dacă îl prind pe cel care i-a lăsat să scape, îl masacrez.","Я отбываю наказание за то, что не остановил побег из тюрьмы: охраняю канализацию. Если я когда-нибудь найду того парня, что освободил пленников, я его на куски порву.",,"Mahkumların kaçmasına izin verip kanalizasyonları koruduğum için ödülüm bu. Eğer onları kaçıran adamı bulursam, onu katledeceğim." +その命を持って報いを受けてもらう。","수감자들의 탈옥을 막지 못해서 하수도를 지키게 되었어. 만약 탈옥하게 만든 녀석을 만난다면, 녀석이 죽을 때 까지 내장을 천천히 끄집어낼 거다.","Dit is mijn beloning voor het laten ontsnappen van gevangenen, het bewaken van de riolering. Als ik ooit de man vind die ze heeft uitgebroken, zal ik hem afslachten.","Dette er belønningen min for å la fanger rømme og vokte kloakken. Hvis jeg finner fyren som slapp dem ut, skal jeg slakte ham.","To moja nagroda za pozwolenie więźniom uciec, pilnowanie ścieków. Jeśli kiedyklowiek dorwę tego, kto pomógł im uciec, to go zamorduję.","Essa é a minha recompensa por deixar os prisioneiros escaparem. Vigiar o esgoto. Se algum dia eu encontrar o cara que soltou eles, eu vou arrancar os seus pedaços.",,"Asta e răsplata mea pentru că am lăsat prizonieri să scape, apărarea canalelor. Dacă îl prind pe cel care i-a lăsat să scape, îl masacrez.","Я отбываю наказание за то, что не остановил побег из тюрьмы: охраняю канализацию. Если я когда-нибудь найду того парня, что освободил пленников, я его на куски порву.",,Det här är min belöning för att jag lät fångarna rymma och vaktade kloakerna. Om jag någonsin hittar killen som bröt ut dem ska jag slakta honom.,"Mahkumların kaçmasına izin verip kanalizasyonları koruduğum için ödülüm bu. Eğer onları kaçıran adamı bulursam, onu katledeceğim." "We've got those little beggars just where we want them. Few more days of this, and they'll have starved themselves into oblivion.",TXT_DLG_SCRIPT06_D22740_WEVEG,MAP06: Red acolyte.,,,"Máme ty žebráčky přesně tam, kde chceme. Ještě pár dní a vyhladoví se do zapomnění.","Vi har de små tiggere lige hvor vi vil have dem. Et par dage mere af dette, og de vil have sultet sig selv til ukendelighed.","Wir haben diese armseligen Bettler doch genau da, wo wir sie haben wollen. Noch ein paar Tage und sie wären verhungert.",,"Tiuj almozuloj estas precize tie, kie ni volas: ankoraŭ kelkajn tagojn en tia situo kaj ili ne plu eltenos la inanicion.",Tenemos a esos indigentes justo donde los queremos: unos cuantos días más así y se habrán consumido por el hambre.,Tenemos a esos mendigos justo donde los queremos: un par de días más así y ya no van a poder más del hambre.,"Olemme ajaneet ne pikku kerjäläiset juuri sinne, minne haluammekin. Vielä muutama päivä tätä, ja ovat varmaankin nääntyneet unholaan.",On a enfin ces sales clodos là où on veut qu'ils soient. Quelques jours de plus et il seront tous morts de faim.,"Pont ott vannak ezek a koldusok ahol akarjuk. Még néhány nap, és halálra fognak éhezni.","Abbiamo quei piccoli mendicanti proprio dove vogliamo. Un paio di altri giorni di questo trattamento, e saranno tutti morti di fame.","この辺の何処かに乞食共がいるはずだ。 -数日もすれば忘れ去られ飢え死するだろうな。",저 빌어먹을 거지들이 밖으로 나가지 못하게 우리들이 입구를 꼼꼼히 막아뒀지. 천천히 굶어 죽는 순간을 재밌게 즐기고 있을걸?,We hebben die kleine bedelaars precies waar we ze willen hebben. Nog maar een paar dagen en ze zullen zich in de vergetelheid hebben laten hongeren.,"Vi har de små tiggerne akkurat der vi vil ha dem. Et par dager til, så har de sultet seg selv i hjel.","Trzymamy tych małych żebraków tam gdzie chcemy, żeby byli. Jeszcze kilka dni i zagłodzą się na śmierć.",Esses mendigos estão bem onde a gente quer que estejam. Só mais alguns dias e eles vão morrer de fome.,,"Îi avem pe sărmanii ăștia exact acolo unde vrem. Încă câteva zile, și vor muri de foame.","Мы загнали этих жалких нищих туда, где им самое место. Ещё несколько дней, и все они подохнут с голоду.",,"O küçük dilencileri tam istediğimiz yere getirdik. Birkaç gün daha böyle devam ederlerse, kendilerini açlıktan öldürmüş olacaklar." +数日もすれば忘れ去られ飢え死するだろうな。",저 빌어먹을 거지들이 밖으로 나가지 못하게 우리들이 입구를 꼼꼼히 막아뒀지. 천천히 굶어 죽는 순간을 재밌게 즐기고 있을걸?,We hebben die kleine bedelaars precies waar we ze willen hebben. Nog maar een paar dagen en ze zullen zich in de vergetelheid hebben laten hongeren.,"Vi har de små tiggerne akkurat der vi vil ha dem. Et par dager til, så har de sultet seg selv i hjel.","Trzymamy tych małych żebraków tam gdzie chcemy, żeby byli. Jeszcze kilka dni i zagłodzą się na śmierć.",Esses mendigos estão bem onde a gente quer que estejam. Só mais alguns dias e eles vão morrer de fome.,,"Îi avem pe sărmanii ăștia exact acolo unde vrem. Încă câteva zile, și vor muri de foame.","Мы загнали этих жалких нищих туда, где им самое место. Ещё несколько дней, и все они подохнут с голоду.",,"Vi har de små tiggarna precis där vi vill ha dem. Några dagar till av detta, och de kommer att ha svultit sig själva till glömska.","O küçük dilencileri tam istediğimiz yere getirdik. Birkaç gün daha böyle devam ederlerse, kendilerini açlıktan öldürmüş olacaklar." What's your clearance? There's no unauthorized personnel allowed up here.,TXT_DLG_SCRIPT06_D24256_WHATS,MAP06: Near storage.,,,Máš oprávnění? Žádná nepovolená osoba tady nahoře nemá co dělat!,Hvad er din tilladelse? Der er ingen uautoriseret personale tilladt heroppe.,Wo ist deine Berechtigung? Unautorisiertes Personal darf hier nicht rein.,,Kiun paspermeson vi havas? Nerajtigita personaro ne estas permesata ĉi tie.,¿Qué permiso tienes? No se permite al personal no autorizado aquí.,,Mikä on kulkuoikeutesi? Henkilöstöllä ei ole tänne pääsyä ilman lupaa.,Où est votre autorisation? Aucun personnel non autorisé ne peut venir ici.,Milyen engedélyed van? Nem léphet be engedély nélkül ide egy alkalmazott sem.,Hai l'autorizzazione per essere qui? Non è assolutamente permesso al personale non autorizzato di stare qua sopra.,"お前のクリアランスは何だ? -ここは許可の無い者は立入を禁じている。",승인을 받지 않은 것 같은데. 여긴 출입금지 구역이다.,Wat is uw toelating? Er is hier geen onbevoegd personeel toegestaan.,Hva er din klarering? Uautorisert personell er ikke tillatt her oppe.,Gdzie twoje zezwolenie? Nieautoryzowany personel nie ma tu wstępu.,Onde está a sua permissão? Ninguém sem permissão pode ficar aqui.,,Care e nivelul tău de acces? Niciun personal neautorizat nu are voie aici.,Где твой пропуск? Здесь нечего делать неуполномоченным лицам.,,Yetkiniz nedir? Buraya yetkisiz personel giremez. +ここは許可の無い者は立入を禁じている。",승인을 받지 않은 것 같은데. 여긴 출입금지 구역이다.,Wat is uw toelating? Er is hier geen onbevoegd personeel toegestaan.,Hva er din klarering? Uautorisert personell er ikke tillatt her oppe.,Gdzie twoje zezwolenie? Nieautoryzowany personel nie ma tu wstępu.,Onde está a sua permissão? Ninguém sem permissão pode ficar aqui.,,Care e nivelul tău de acces? Niciun personal neautorizat nu are voie aici.,Где твой пропуск? Здесь нечего делать неуполномоченным лицам.,,Vad har du för tillstånd? Ingen obehörig personal tillåts här uppe.,Yetkiniz nedir? Buraya yetkisiz personel giremez. What the hell? Who opened the gates? Sound the alarm!!!,TXT_DLG_SCRIPT07_D0_WHATT,MAP07: Red acolyte at the main entrance.,,,Co to sakra? Kdo otevřel bránu? Volej na poplach!,Hvad fanden? Hvem åbnede portene? Slå alarm!!!!,Was zur Hölle? Wer hat die Tore geöffne? Alarm!,,Kio diable? Kiu malfermis la pordojn? Sonorigu la alarmon!!!,¿Qué demonios? ¿Quién ha abierto las puertas? ¡¡¡Activad la alarma!!!,¿Qué carajo? ¿Quién abrió las puertas? ¡¡¡Activen la alarma!!!,Mitä helvettiä? Kuka avasi portit? Laukaise hälytys!!!,Qu'est-ce que c'est que ce bordel? Qui a ouvert les portes? Faites sonner l'alarme!,Mi a franc? Ki nyitotta ki a kaput? Indítsátok be a riasztót!,Ma che diavolo? Chi ha aperto i cancelli? Suonate l'allarme!!!,"何をしやがった? -誰がゲートを開けた? 警報を鳴らせ!",누가 성문을 열어놨어? 경보! 알람을 울려라!,Wat de hel? Wie heeft de poorten geopend? Laat alarm slaan!!!,Hva i helvete? Hvem åpnet porten? Slå alarm!,Co u diabła? Kto otworzył bramy? Włączyć alarm!!!,Mas que diabos? Quem abriu os portões? Ativem o alarme!!!,,Ce naiba? Cine a deschis porțile? Sună alarma!!!,Что за чертовщина? Кто открыл ворота? Бейте тревогу!,,Ne oluyor be? Kapıları kim açtı? Alarmı çalın!!! +誰がゲートを開けた? 警報を鳴らせ!",누가 성문을 열어놨어? 경보! 알람을 울려라!,Wat de hel? Wie heeft de poorten geopend? Laat alarm slaan!!!,Hva i helvete? Hvem åpnet porten? Slå alarm!,Co u diabła? Kto otworzył bramy? Włączyć alarm!!!,Mas que diabos? Quem abriu os portões? Ativem o alarme!!!,,Ce naiba? Cine a deschis porțile? Sună alarma!!!,Что за чертовщина? Кто открыл ворота? Бейте тревогу!,,Vad i helvete? Vem öppnade grindarna? Slå larm!,Ne oluyor be? Kapıları kim açtı? Alarmı çalın!!! "There's another way into the sewers, throw that switch and then go up and purge the reclamation tank.",TXT_DLG_SCRIPT07_D1516_THERE,MAP07,,,"Do stok vede další cesta, zatáhni za tuhle páku a pak jdi nahoru a vypusť obnovnou nádrž.","Der er en anden vej ind i kloakkerne, smid kontakten og gå så op og tøm genvindingstanken.",Da ist ein anderer Weg in die Kanalisation. Drück den Schalter da und leere den Rückgewinnungstank.,,"Estas alia enirejo al la kloakoj: enŝaltu ĉi tiun ŝaltilon, tiam reiru supren laŭ la ŝtuparo kaj drenu la rezervujon de akvoreuzo.",Hay otra entrada a las cloacas: activa este interruptor y luego ve a drenar el tanque de recuperación de agua subiendo las escaleras.,,Viemäreihin on toinen reitti. Käännä tuota vipua ja mene sitten ylös tyhjentämään talteenottoallas.,Il y a une autre entrée pour les égouts. Utilisez ce bouton et montez purger le réservoir de recyclage.,"Van egy másik módja is bejutni a kanálisba. Kapcsold fel azt a kapcsolót, aztán menj fel és ereszd le a szárító tartályt.","C'è un altro ingresso per le fogne, attiva quella leva e poi sali per svuotare la vasca di recupero fluidi.","下水道に別の入り口がある、スイッチを入れ -次に昇って浄水タンクを空にするんだ。",하수도로 향하는 또 다른 길이 있어. 저 스위치를 켜고 위로 올라가서 수조의 오물을 비워봐.,"Er is nog een andere weg in de riolering, gooi die schakelaar naar boven en ga dan naar boven om de terugwinnings tank te zuiveren.","Det er en annen vei inn i kloakken, trykk på bryteren og gå opp og rens tanken.","Jest jeszcze inna droga do kanałów, wciśnij ten przełącznik, idź na górę i opróżnij zbiornik rekultywacyjny.","Há outra maneira de entrar no esgoto. Use esse interruptor, suba e esvazie o tanque de recuperação.",,"Mai e o cale de acces către canale, folosește butonul apoi du-te sus și scurge lichidul din rezervor.","Есть другой путь в канализацию. Переведи этот рычаг, затем иди наверх и слей жидность из бака для переработки.",,"Kanalizasyona giden başka bir yol var, o düğmeyi at ve sonra yukarı çıkıp ıslah tankını temizle." +次に昇って浄水タンクを空にするんだ。",하수도로 향하는 또 다른 길이 있어. 저 스위치를 켜고 위로 올라가서 수조의 오물을 비워봐.,"Er is nog een andere weg in de riolering, gooi die schakelaar naar boven en ga dan naar boven om de terugwinnings tank te zuiveren.","Det er en annen vei inn i kloakken, trykk på bryteren og gå opp og rens tanken.","Jest jeszcze inna droga do kanałów, wciśnij ten przełącznik, idź na górę i opróżnij zbiornik rekultywacyjny.","Há outra maneira de entrar no esgoto. Use esse interruptor, suba e esvazie o tanque de recuperação.",,"Mai e o cale de acces către canale, folosește butonul apoi du-te sus și scurge lichidul din rezervor.","Есть другой путь в канализацию. Переведи этот рычаг, затем иди наверх и слей жидность из бака для переработки.",,"Det finns en annan väg in i kloakerna, slå om den strömbrytaren och gå sedan upp och rensa återvinningstanken.","Kanalizasyona giden başka bir yol var, o düğmeyi at ve sonra yukarı çıkıp ıslah tankını temizle." "What the hell's your problem. If the Programmer comes up from his audience chamber, you're dead.",TXT_DLG_SCRIPT07_D3032_WHATT,MAP07: Hospital.,,,"Co máš sakra za problém? Jestli Programátor vyjde ze svého sálu, jsi mrtvý.","Hvad fanden er dit problem? Hvis programmøren kommer op fra sit publikumskammer, er du død.","Was, verdammt, ist dein Problem? Wenn der Programmierer seine Audienzkammer verläßt, bist du tot.",,"Kion diable vi faras!? Se la Programisto revenos de sia juĝejo, vi mortos.","¿¡Qué demonios te pasa!? Si el Programador vuelve de su sala de audiencias, estás muerto.","¿¡Qué carajo te pasa!? Si el Programador vuelve de su sala de audiencias, estás muerto.","Mikä helvetti sinussa on vialla. Jos ohjelmoitsija tulee valtaistuinsaliltaan, olet mennyttä.","C'est quoi votre problème? Si le Programmeur sort de sa chambre d'audience, vous êtes mort.","Mi az isten bajod van? Ha a Programozó feljön a kihallgató kamrájábó, akkor neked annyi.","Ma quale diavolo è il tuo problema. Se il Programmatore arriva dalla sua camera delle udienze, sei morto.","一体何をしに来た。プログラマーが オーディエンスチャンバーから来たら -死んでいた所だ。","너희들 제정신이야? 프로그래머님이 알현실에서 뛰쳐나오는 순간, 네 놈은 죽게 될 거라고!","Wat de hel is jouw probleem? Als de programmeur uit zijn publiekskamer komt, ben je dood.","Hva i helvete er problemet ditt? Hvis programmereren kommer opp fra audiensrommet, er du død.",Jaki masz problem do diaska? Jeśli Programista wyjdzie ze swojej sali audiencji będziesz martwy.,"Qual é o seu problema? Se o Programador vier até aqui de sua câmara de audiências, você estará morto.",,"Care mai e problema ta? Dacă Programatorul vine sus din camera sa de audiență, ești mort.","Проклятье, что с тобой не так? Если Программист поднимется из приёмного зала, ты покойник!",,"Senin sorunun ne? Eğer Programcı seyirci odasından çıkarsa, öldün demektir." +死んでいた所だ。","너희들 제정신이야? 프로그래머님이 알현실에서 뛰쳐나오는 순간, 네 놈은 죽게 될 거라고!","Wat de hel is jouw probleem? Als de programmeur uit zijn publiekskamer komt, ben je dood.","Hva i helvete er problemet ditt? Hvis programmereren kommer opp fra audiensrommet, er du død.",Jaki masz problem do diaska? Jeśli Programista wyjdzie ze swojej sali audiencji będziesz martwy.,"Qual é o seu problema? Se o Programador vier até aqui de sua câmara de audiências, você estará morto.",,"Care mai e problema ta? Dacă Programatorul vine sus din camera sa de audiență, ești mort.","Проклятье, что с тобой не так? Если Программист поднимется из приёмного зала, ты покойник!",,Vad i helvete är ditt problem. Om Programmeraren kommer upp från sin publikrum är du död.,"Senin sorunun ne? Eğer Programcı seyirci odasından çıkarsa, öldün demektir." "Hey, you're not cleared to go down there.",TXT_DLG_SCRIPT07_D4548_HEYYO,,,,"Hej, nemáš povolení jít tam dolů.",Du har ikke tilladelse til at gå derned.,"He, du darfst da nicht runtergehen.",,"He, vi ne rajtas iri malsupren.","Oye, no tienes permiso para bajar aquí.",,"Hei, sinulla ei ole lupaa mennä alas sinne.","Hé, vous n'avez pas le droit d'être ici.","Héj, nincs engedélyed oda lemenni.","Ehi, non hai l'autorizzazione per andare laggiù.","おい、あんたはここを降りる事は -許可されてないぞ。",잠깐. 너는 밑으로 내려갈 허가를 받지 않았다.,"Hé, je hebt geen toestemming om naar beneden te gaan.","Hei, du er ikke klarert til å gå ned dit.","Hej, nie masz zgody na zejście tam.","Ei, você não tem permissão para descer aí.",,"Hei, n-ai acces să mergi acolo jos.","Эй, у тебя нет разрешения спускаться туда.",,"Hey, oraya inme iznin yok." +許可されてないぞ。",잠깐. 너는 밑으로 내려갈 허가를 받지 않았다.,"Hé, je hebt geen toestemming om naar beneden te gaan.","Hei, du er ikke klarert til å gå ned dit.","Hej, nie masz zgody na zejście tam.","Ei, você não tem permissão para descer aí.",,"Hei, n-ai acces să mergi acolo jos.","Эй, у тебя нет разрешения спускаться туда.",,Du har inte tillstånd att gå ner dit.,"Hey, oraya inme iznin yok." Programmer? Who told you that? There is no Programmer. That story was spread ages ago. Don't tell me the Front actually believed that crap. Idiots.,TXT_DLG_SCRIPT07_D6064_PROGR,MAP07: Computer room (northwest building).,,,"Programátor? Kdo ti to řekl? Není žádný Programátor. To je stará pověra. Neříkej mi, že tomu Fronta doopravdy věřila. Idioti.","Programmør? Hvem har fortalt dig det? Der er ingen programmør. Den historie blev spredt for længe siden. Fortæl mig ikke, at fronten troede på det lort. Idioter.","Programmierer? Wer hat dir das erzählt? Es gibt keinen Programmierer. Das ist eine alte Legende. Sag mir nicht, dass die Front an diesen Blödsinn glaubt. Idioten.",,"Ĉu Programisto? Kie vi aŭdis tion? Ne estas Programisto; tiu storio ekdisvastiĝis antaŭ jaroj. Ne diru, ke la Fronto kredis tian fekaĵon. Kiel stultaj.",¿Programador? ¿De dónde sacas eso? No hay Programador; esa historia se ha extendido desde hace años. No me digas que el Frente realmente se ha creído el cuentito. Qué idiotas.,,"Ohjelmoitsija? Kuka sinulle on kertonut? Ei ole mitään Ohjelmoitsijaa. Tarina oli laitettu liikkeelle ajat sitten. Älä vain kerro, että Rintama oikeasti uskoi siihen höpöpuheeseen. Mitä idiootteja.",Programmeur? Qui vous a raconté ça? Il n'y a pas de Programmeur. Cette rumeur a commencé il y a des années. J'arrive pas à croire que ces abrutis du Front y croient. Idiots.,"Programozó? Ki mondta ezt neked? Nincs semmiféle programozó. Ez egy ezer éves történet. Azt ne mondd már, hogy a Front elhitte ezt a maszlagot. Idióták.",Programmatore? Ma chi te l'ha detto? Non c'è nessun Programmatore. Quella storia è stata diffusa un sacco di tempo fa. Non dirmi che il Fronte ha creduto a queste scempiaggini. Che idioti.,"プログラマー?誰ガそんなことヲ言った? ここにプログラマーハいない。 その噂ハ何年も前ニ広まったものダ。 そんな下らない事ヲ未だニ信じていたとは。 白痴モいいとこだ。","프로그래머? 누가 알려준 거야? 프로그래머 따위는 존재하지 않아. 이 소문이 몇 년 동안 계속 퍼졌다는 게 믿기지 않아. 프론트도 그 잡소문을 아직도 믿고 있던 모양이었고. 한심하네. - \cy여기가 아닌가 봐. 다른 곳을 찾아봐야겠어.",Programmeur? Wie heeft je dat verteld? Er is geen programmeur. Dat verhaal is eeuwen geleden verspreid. Vertel me niet dat het Front die onzin echt geloofde. Idioten.,Programmerer? Hvem har sagt det? Det finnes ingen programmerer. Den historien ble spredt for lenge siden. Ikke fortell meg at Fronten faktisk trodde på den dritten. Idioter.,"Programista? Kto ci to powiedział? Nie ma żadnego Programisty. Ta historia została wymyślona wiele lat temu. Tylko mi nie mów, że Front wierzy w te bzdury. Idioci.",Programador? Quem te disse isso? Não existe nenhum Programador. Essa história anda se espalhando desde muito tempo. Não me diga que a Frente acreditou mesmo nessa bobagem. Otários.,,Programator? Cine ți-a spus asta? Nu e niciun Programator. Povestea asta a fost răspândită acum multă vreme. Nu-mi spune că Frontul chiar a crezut prostia asta. Idioți.,"Программист? Кто тебе это сказал? Нет никакого программиста. Этой байке уже сто лет. Только не говори мне, что Сопротивление и правда поверило в эту чушь. Идиоты.",,Programcı mı? Bunu sana kim söyledi? Programcı diye biri yok. Bu hikaye yıllar önce yayıldı. Bana Cephe'nin bu saçmalığa gerçekten inandığını söyleme. Aptallar. -"Well, what's the truth then?",TXT_RPLY0_SCRIPT07_D6064_WELLW,〃,,,Kde je tedy pravda?,"Nå, hvad er sandheden så?","Nun, was ist denn die Wahrheit?",,"Tiuokaze, kiu estas la vero?",¿Entonces cuál es la verdad?,,"No, mikä totuus sitten on?","Quelle est la vérité, alors?","Nos, mi az igazság akkor?",E allora qual'è la verità?,それなら、本当の事は何だ?,"그럼, 진실이 뭐야?","Nou, wat is de waarheid dan?","Hva er sannheten, da?",Więc co jest prawdą?,"Bem, qual é a verdade?",,"Păi, care e adevărul atunci?","Ладно, и что же тогда правда?",,"Peki, gerçek ne o zaman?" + \cy여기가 아닌가 봐. 다른 곳을 찾아봐야겠어.",Programmeur? Wie heeft je dat verteld? Er is geen programmeur. Dat verhaal is eeuwen geleden verspreid. Vertel me niet dat het Front die onzin echt geloofde. Idioten.,Programmerer? Hvem har sagt det? Det finnes ingen programmerer. Den historien ble spredt for lenge siden. Ikke fortell meg at Fronten faktisk trodde på den dritten. Idioter.,"Programista? Kto ci to powiedział? Nie ma żadnego Programisty. Ta historia została wymyślona wiele lat temu. Tylko mi nie mów, że Front wierzy w te bzdury. Idioci.",Programador? Quem te disse isso? Não existe nenhum Programador. Essa história anda se espalhando desde muito tempo. Não me diga que a Frente acreditou mesmo nessa bobagem. Otários.,,Programator? Cine ți-a spus asta? Nu e niciun Programator. Povestea asta a fost răspândită acum multă vreme. Nu-mi spune că Frontul chiar a crezut prostia asta. Idioți.,"Программист? Кто тебе это сказал? Нет никакого программиста. Этой байке уже сто лет. Только не говори мне, что Сопротивление и правда поверило в эту чушь. Идиоты.",,Programmerare? Vem har sagt det? Det finns ingen programmerare. Den historien spreds för länge sedan. Säg inte att fronten verkligen trodde på den skiten. Idioter.,Programcı mı? Bunu sana kim söyledi? Programcı diye biri yok. Bu hikaye yıllar önce yayıldı. Bana Cephe'nin bu saçmalığa gerçekten inandığını söyleme. Aptallar. +"Well, what's the truth then?",TXT_RPLY0_SCRIPT07_D6064_WELLW,〃,,,Kde je tedy pravda?,"Nå, hvad er sandheden så?","Nun, was ist denn die Wahrheit?",,"Tiuokaze, kiu estas la vero?",¿Entonces cuál es la verdad?,,"No, mikä totuus sitten on?","Quelle est la vérité, alors?","Nos, mi az igazság akkor?",E allora qual'è la verità?,それなら、本当の事は何だ?,"그럼, 진실이 뭐야?","Nou, wat is de waarheid dan?","Hva er sannheten, da?",Więc co jest prawdą?,"Bem, qual é a verdade?",,"Păi, care e adevărul atunci?","Ладно, и что же тогда правда?",,Vad är sanningen då?,"Peki, gerçek ne o zaman?" I told you all I know. You are wasting your time.,TXT_DLG_SCRIPT07_D7580_ITOLD,〃,,,"Řekl jsem ti vše, co vím. Ztrácíš tu čas.","Jeg har fortalt dig alt, hvad jeg ved. Du spilder din tid.","Ich habe alles gesagt, was ich weiß. Du verschwendest deine Zeit.",,"Mi diris ĉion, kion mi scias. Vi perdas tempon.",Te he dicho todo lo que sé. Estás perdiendo el tiempo.,Ya te dije todo lo que sé. Estás perdiendo el tiempo.,"Minä kerroin jo kaiken, mitä tiedän. Tuhlaat aikaasi.",Je t'ai dit tous ce que je sais. Tu perds ton temps.,"Elmondtam mindent, amit tudtam. Csak az idődet vesztegeted.",Ti ho detto tutto quello che so. Stai sprecando il tuo tempo.,"私ハ知っていることヲ教えた。 -これ以上ハ互いニ時間ノ無駄ダ。",다 알려줬어. 시간 낭비하지 마.,Ik heb je alles verteld wat ik weet. Je verspilt je tijd.,Jeg har sagt alt jeg vet. Dere kaster bort tiden deres.,Powiedziałem ci wszystko co wiem. Marnujesz swój czas.,Eu já contei tudo o que eu sei. Você está perdendo tempo.,,"Ți-am spus tot ce știu, îți pierzi vremea.","Я рассказал всё, что знаю. Ты попусту тратишь время.",,Size tüm bildiklerimi anlattım. Zamanınızı boşa harcıyorsunuz. +これ以上ハ互いニ時間ノ無駄ダ。",다 알려줬어. 시간 낭비하지 마.,Ik heb je alles verteld wat ik weet. Je verspilt je tijd.,Jeg har sagt alt jeg vet. Dere kaster bort tiden deres.,Powiedziałem ci wszystko co wiem. Marnujesz swój czas.,Eu já contei tudo o que eu sei. Você está perdendo tempo.,,"Ți-am spus tot ce știu, îți pierzi vremea.","Я рассказал всё, что знаю. Ты попусту тратишь время.",,Jag har berättat allt jag vet. Du slösar bort din tid.,Size tüm bildiklerimi anlattım. Zamanınızı boşa harcıyorsunuz. "Fight on, we will triumph. This day will belong to us!",TXT_DLG_SCRIPT07_D9096_FIGHT,MAP07: Font soldier.,,,"Bojuj dál, však my zvítězíme! Dnešek bude patřit nám!","Kæmp videre, vi vil triumfere. Denne dag vil tilhøre os!","Lass uns kämpfen, wir werden gewinnen. Dieser Tag gehört uns!",,La batalo daŭru; ni venkos. Ĉi tiu tago estas nia!,"A seguir peleando, que hoy vamos a triunfar. ¡Este día es nuestro!",,"Jatkakaa taistoa, voitto on meidän. Tämä päivä kuuluu meille!","Continuez à vous battre, nous allons triompher! Ce jour nous appartient!",Előre a győzelembe! Mi leszünk a nap győztesei!,"Continuate a combattere, trionferemo. Questo è il nostro giorno!","我々は勝利を志し、戦う。 -この日は我々と共に在る!","같이 싸우자! 우리들이 이길 거고, 밝은 날이 찾아올 거야!","Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" +この日は我々と共に在る!","같이 싸우자! 우리들이 이길 거고, 밝은 날이 찾아올 거야!","Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Kämpa vidare, vi kommer att triumfera. Den här dagen kommer att tillhöra oss!","Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" "Fight on, we will triumph. This day will belong to us!",TXT_DLG_SCRIPT07_D10612_FIGHT,〃,,,"Bojuj dál, však my zvítězíme! Dnešek bude patřit nám!","Kæmp videre, vi vil triumfere. Denne dag vil tilhøre os!","Lass uns kämpfen, wir werden gewinnen. Dieser Tag gehört uns!",,La batalo daŭru; ni venkos. Ĉi tiu tago estas nia!,"A seguir peleando, que hoy vamos a triunfar. ¡Este día es nuestro!",,"Jatkakaa taistoa, voitto on meidän. Tämä päivä kuuluu meille!","Continuez à vous battre, nous allons triompher! Ce jour nous appartient!",Előre a győzelembe! Mi leszünk a nap győztesei!,"Continuate a combattere, trionferemo. Questo è il nostro giorno!","我々は勝利を志し、戦う。 -この日は我々と共に在る!",오늘이야말로 결전의 시간이야. 우리들이 바랬던 날을 위해!!,"Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" +この日は我々と共に在る!",오늘이야말로 결전의 시간이야. 우리들이 바랬던 날을 위해!!,"Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Kämpa vidare, vi kommer att triumfera. Den här dagen kommer att tillhöra oss!","Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" "Fight on, we will triumph. This day will belong to us!",TXT_DLG_SCRIPT07_D12128_FIGHT,〃,,,"Bojuj dál, však my zvítězíme! Dnešek bude patřit nám!","Kæmp videre, vi vil triumfere. Denne dag vil tilhøre os!","Lass uns kämpfen, wir werden gewinnen. Dieser Tag gehört uns!",,La batalo daŭru; ni venkos. Ĉi tiu tago estas nia!,"A seguir peleando, que hoy vamos a triunfar. ¡Este día es nuestro!",,"Jatkakaa taistoa, voitto on meidän. Tämä päivä kuuluu meille!","Continuez à vous battre, nous allons triompher! Ce jour nous appartient!",Előre a győzelembe! Mi leszünk a nap győztesei!,"Continuate a combattere, trionferemo. Questo è il nostro giorno!","我々は勝利を志し、戦う。 -この日は我々と共に在る!","우리들 중 한 명이 죽는다 해도, 승리는 확신해. 잃을 게 없어!","Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" +この日は我々と共に在る!","우리들 중 한 명이 죽는다 해도, 승리는 확신해. 잃을 게 없어!","Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Kämpa vidare, vi kommer att triumfera. Den här dagen kommer att tillhöra oss!","Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" "Fight on, we will triumph. This day will belong to us!",TXT_DLG_SCRIPT07_D13644_FIGHT,〃,,,"Bojuj dál, však my zvítězíme! Dnešek bude patřit nám!","Kæmp videre, vi vil triumfere. Denne dag vil tilhøre os!","Lass uns kämpfen, wir werden gewinnen. Dieser Tag gehört uns!",,La batalo daŭru; ni venkos. Ĉi tiu tago estas nia!,"A seguir peleando, que hoy vamos a triunfar. ¡Este día es nuestro!",,"Jatkakaa taistoa, voitto on meidän. Tämä päivä kuuluu meille!","Continuez à vous battre, nous allons triompher! Ce jour nous appartient!",Előre a győzelembe! Mi leszünk a nap győztesei!,"Continuate a combattere, trionferemo. Questo è il nostro giorno!","我々は勝利を志し、戦う。 -この日は我々と共に在る!","오더에 패배와 몰락을, 프론트에 인류와 영원한 자유를!","Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" +この日は我々と共に在る!","오더에 패배와 몰락을, 프론트에 인류와 영원한 자유를!","Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Kämpa vidare, vi kommer att triumfera. Den här dagen kommer att tillhöra oss!","Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" "Fight on, we will triumph. This day will belong to us!",TXT_DLG_SCRIPT07_D15160_FIGHT,〃,,,"Bojuj dál, však my zvítězíme! Dnešek bude patřit nám!","Kæmp videre, vi vil triumfere. Denne dag vil tilhøre os!","Lass uns kämpfen, wir werden gewinnen. Dieser Tag gehört uns!",,La batalo daŭru; ni venkos. Ĉi tiu tago estas nia!,"A seguir peleando, que hoy vamos a triunfar. ¡Este día es nuestro!",,"Jatkakaa taistoa, voitto on meidän. Tämä päivä kuuluu meille!","Continuez à vous battre, nous allons triompher! Ce jour nous appartient!",Előre a győzelembe! Mi leszünk a nap győztesei!,"Continuate a combattere, trionferemo. Questo è il nostro giorno!","我々は勝利を志し、戦う。 -この日は我々と共に在る!",희망 한가닥 작전을 위해! 오더여! 내가 돌아왔다!!,"Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" +この日は我々と共に在る!",희망 한가닥 작전을 위해! 오더여! 내가 돌아왔다!!,"Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Kämpa vidare, vi kommer att triumfera. Den här dagen kommer att tillhöra oss!","Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" "Fight on, we will triumph. This day will belong to us!",TXT_DLG_SCRIPT07_D16676_FIGHT,〃,,,"Bojuj dál, však my zvítězíme! Dnešek bude patřit nám!","Kæmp videre, vi vil triumfere. Denne dag vil tilhøre os!","Lass uns kämpfen, wir werden gewinnen. Dieser Tag gehört uns!",,La batalo daŭru; ni venkos. Ĉi tiu tago estas nia!,"A seguir peleando, que hoy vamos a triunfar. ¡Este día es nuestro!",,"Jatkakaa taistoa, voitto on meidän. Tämä päivä kuuluu meille!","Continuez à vous battre, nous allons triompher! Ce jour nous appartient!",Előre a győzelembe! Mi leszünk a nap győztesei!,"Continuate a combattere, trionferemo. Questo è il nostro giorno!","我々は勝利を志し、戦う。 -この日は我々と共に在る!","슬프지만, 이 것은 전쟁이잖아.","Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" +この日は我々と共に在る!","슬프지만, 이 것은 전쟁이잖아.","Vecht verder, we zullen zegevieren. Deze dag zal van ons zijn!","Kjemp videre, vi vil seire. Denne dagen vil tilhøre oss!","Walcz dalej, i tak zwyciężymy. Dzień należy do nas!","Continue lutando, nós iremos triunfar. Este dia pertence a nós!",,"Continuă lupta, vom triumfa. Ziua asta ne aparține!","Сражайся, и нас ждёт триумф. Сегодняшний день будет нашим!",,"Kämpa vidare, vi kommer att triumfera. Den här dagen kommer att tillhöra oss!","Savaşmaya devam edin, zafere ulaşacağız. Bu gün bize ait olacak!" "You killed all the guards. Don't hurt me. I told him this was a dumb idea. The real Programmer's in the keep. Here, take this key.",TXT_DLG_SCRIPT08_D0_YOUKI,MAP08: Northeast room.,,,"Tys zabil všechny stráže! Neubližuj mi. Já mu říkal, že to je hloupý nápad. Skutečný Programátor je v pevnosti. Tady, vem si tenhle klíč.","Du dræbte alle vagterne. Gør mig ikke noget. Jeg sagde til ham, at det var en dum idé. Den rigtige programmør er i tårnet. Her, tag denne nøgle.","Du hast alle Wächter getötet. Bitte tu mir nichts. Ich habe ihm gesagt, es wäre eine dumme Idee. Der Programmierer ist in seiner Unterkunft. Hier nimm diesen Schlüssel.",,"Vi mortigis ĉiujn gardistojn. Ne vundu min. Mi diris al li, ke ĉi tiu estas stulta ideo; la vera Programisto estas en la ĉefturo. Jen la ŝlosilo.","Has matado a todos los guardias. No me hagas nada. Le dije que era una idea estúpida; el verdadero Programador está en el torreón. Ten, toma esta llave.","Mataste a todos los guardias. No me hagas nada. Le dije que era una idea estúpida; el verdadero Programador está en el torreón. Ten, toma esta llave.","Tapoit kaikki vartijat. Älä satuta minua. Sanoin hänelle, että tämä oli tyhmä idea. Oikea Ohjelmoitsija on linnakkeessa. Tässä, ota tämä avain.",Vous avez tué tous les gardes. Ne me faites pas de mal. Je lui ai dit que c'était une idée stupide. Le vrai Programmeur se trouve dans le donjon. Prenez cette clé.,"Te ölted meg az összes őrt. Kérlek ne bánts. Én megmondtam, hogy ez egy rossz ötlet. Az igazi Programozó a vártoronyban van. Vidd ezt a kulcsot.","Hai ucciso tutte le guardie. Ho cercato di fargli capire che era un'idea stupida. Il vero Programmatore è nella fortezza. Ecco, prendi questa chiave.","君がガードを全員殺したノカ。 私ハ傷つけないでくれ。 私ハ望んでこんなふざけた事をしたワケではない。 本当のプログラマーはこのキーの場所ニいる。 -ほら、受け取れ。",경비들을 모조리 죽이시다니! 해치지 말아주세요. 제가 그분께 어리석은 짓이라고 제안을 했었는데... 진짜 프로그래머님은 성채에 있습니다. 이 열쇠를 쓰세요.,"Je hebt alle bewakers gedood. Doe me geen pijn. Ik zei hem dat dit een dom idee was. De echte programmeur is in de donjon. Hier, pak deze sleutel.","Du drepte alle vaktene. Ikke gjør meg noe. Jeg sa at dette var en dum idé. Den virkelige programmereren er i borgen. Her, ta denne nøkkelen.","Zabiłeś wszystkich strażników. Nie krzywdź mnie. Mówiłem mu, że to głupi pomysł. Prawdziwy Programista jest w twierdzy. Masz, weź ten klucz.","Você matou todos os guardas. Não me machuque. Eu disse a ele que isso era uma idéia besta. O verdadeiro Programador está na fortaleza. Aqui, pegue esta chave.",,Ai omorât toți gardienii. Nu mă rănii. I-am spus că e o idee proastă. Adevăratul Programator e înăuntru. Ia cheia asta.,"Ты убил всех стражников. Не трогай меня! Я говорил ему, что это глупая идея. Настоящий Программист в цитадели. Вот, возьми этот ключ.",,"Bütün muhafızları öldürdün. Bana zarar vermeyin. Ona bunun aptalca bir fikir olduğunu söyledim. Gerçek Programcı kalede. İşte, al şu anahtarı." -You're the Programmer!,TXT_RPLY0_SCRIPT08_D0_YOURE,〃,,,Ty jsi Programátor!,"Det er dig, der er programmøren!",Du bist der Programmierer!,,Vi estas la Programisto!,¡Tú eres el Programador!,,Sinä olet Ohjelmoitsija!,Vous êtes le Programmeur!,Te vagy a Programozó!,Sei tu il Programmatore!,アンタがプログラマーだろ!,넌 프로그래머잖아!,Jij bent de programmeur!,Du er programmereren!,To ty jesteś Programistą!,Você é o Programador!,,Tu ești Programatorul!,Ты Программист!,,Programcı sensin! +ほら、受け取れ。",경비들을 모조리 죽이시다니! 해치지 말아주세요. 제가 그분께 어리석은 짓이라고 제안을 했었는데... 진짜 프로그래머님은 성채에 있습니다. 이 열쇠를 쓰세요.,"Je hebt alle bewakers gedood. Doe me geen pijn. Ik zei hem dat dit een dom idee was. De echte programmeur is in de donjon. Hier, pak deze sleutel.","Du drepte alle vaktene. Ikke gjør meg noe. Jeg sa at dette var en dum idé. Den virkelige programmereren er i borgen. Her, ta denne nøkkelen.","Zabiłeś wszystkich strażników. Nie krzywdź mnie. Mówiłem mu, że to głupi pomysł. Prawdziwy Programista jest w twierdzy. Masz, weź ten klucz.","Você matou todos os guardas. Não me machuque. Eu disse a ele que isso era uma idéia besta. O verdadeiro Programador está na fortaleza. Aqui, pegue esta chave.",,Ai omorât toți gardienii. Nu mă rănii. I-am spus că e o idee proastă. Adevăratul Programator e înăuntru. Ia cheia asta.,"Ты убил всех стражников. Не трогай меня! Я говорил ему, что это глупая идея. Настоящий Программист в цитадели. Вот, возьми этот ключ.",,"Du dödade alla vakter. Gör mig inte illa. Jag sa till honom att detta var en dum idé. Den riktiga programmeraren är i fängelset. Här, ta den här nyckeln.","Bütün muhafızları öldürdün. Bana zarar vermeyin. Ona bunun aptalca bir fikir olduğunu söyledim. Gerçek Programcı kalede. İşte, al şu anahtarı." +You're the Programmer!,TXT_RPLY0_SCRIPT08_D0_YOURE,〃,,,Ty jsi Programátor!,"Det er dig, der er programmøren!",Du bist der Programmierer!,,Vi estas la Programisto!,¡Tú eres el Programador!,,Sinä olet Ohjelmoitsija!,Vous êtes le Programmeur!,Te vagy a Programozó!,Sei tu il Programmatore!,アンタがプログラマーだろ!,넌 프로그래머잖아!,Jij bent de programmeur!,Du er programmereren!,To ty jesteś Programistą!,Você é o Programador!,,Tu ești Programatorul!,Ты Программист!,,Du är programmeraren!,Programcı sensin! "Do I look like I wield ultimate power? The Order uses us all. Now go, I'm dead already.",TXT_DLG_SCRIPT08_D1516_DOILO,〃,,,"Vypadám snad jako bych se měl pyšnit nesmírnou mocí? Řád nás všechny využívá. Teď jdi, já jsem už teď mrtvý.","Ser jeg ud, som om jeg udøver den ultimative magt? Ordenen bruger os alle. Gå nu, jeg er allerede død.","Sehe ich so aus, als ob ich unendliche Macht hätte? Der Orden benutzt uns alle. Nun geh, ich bin ohnehin schon tot.",,"Ĉu mi aspektas kiel posedanto de absoluta povo? La Ordono uzas nin ĉiujn. Foriru, mi jam estas mortinta.","¿Te parezco poseer el poder absoluto? La Orden nos usa a todos. Ya vete, que yo ya estoy muerto.",,"Näytänkö muka sellaiselta, joka pitää hallussaan täyttä valtaa? Veljeskunta käyttää hyväkseen meitä kaikkia. Mene, olen jo yhtä kuin kuollut.","Est-ce que j'ai l'air d'avoir le pouvoir suprême? L'Ordre nous utilise tous. Partez, je suis déjà mort.","Úgy nézek ki, mint aki mindenki felett erőt gyakorol? A Rend kihasznál mindannyiunkat. Menj tovább, Én már amúgyis halott vagyok.","Davvero ti sembro uno che possiede poteri sovrumani? L'Ordine ci usa tutti. Adesso vai, tanto io sono spacciato ormai.","私ガそんな凄まじい力ヲ振舞っていると思うか? オーダーハ私達全員を利用している。 -私ハもう死人同然だ。さあ行け。","제가 신적인 힘을 갖고 있다고 생각하나요? 오더는 어차피 모두를 부려먹습니다. 떠나세요, 전 이미 죽은 목숨이에요.","Zie ik eruit alsof ik de ultieme macht heb? De Orde gebruikt ons allemaal. Ga nu, ik ben al dood.","Ser jeg ut som om jeg har den ultimate makten? Ordenen bruker oss alle. Gå nå, jeg er allerede død.","Czy wyglądam jakbym był we władaniu niesamowitej mocy? Zakon wykorzystuje nas wszystkich. Idź stąd, i tak już jestem martwy.",Você acha que eu pareço alguém que possui um poder tremendo? A Ordem manipula a todos nós. Agora vá. Eu já estou morto.,,"Ți se pare că controlez puterea supremă? Ordinul ne folosește pe toți. Acum pleacă, sunt mort deja.",Разве я похож на обладателя невероятной мощи? Орден использует нас всех. Теперь иди. Я уже всё равно мёртв.,,"Nihai güce sahipmişim gibi mi görünüyorum? Tarikat hepimizi kullanır. Şimdi git, ben zaten ölüyüm." -Power is the key!,TXT_DLG_SCRIPT08_D3032_POWER,,,,Moc je tím klíčem!,Magt er nøglen!,Macht ist der Schlüssel!,,Povo estas la ŝlosilo!,¡El poder es la clave!,,Valta on avain!,Le pouvoir est la clé!,Az erő a kulcs!,Il potere è la chiave!,キーが力だ!,힘이 곧 열쇠다!,Kracht is de sleutel!,Makt er nøkkelen!,Moc jest kluczem!,O poder é a chave!,,Puterea e cheia!,В силе — всё!,,Güç anahtardır! +私ハもう死人同然だ。さあ行け。","제가 신적인 힘을 갖고 있다고 생각하나요? 오더는 어차피 모두를 부려먹습니다. 떠나세요, 전 이미 죽은 목숨이에요.","Zie ik eruit alsof ik de ultieme macht heb? De Orde gebruikt ons allemaal. Ga nu, ik ben al dood.","Ser jeg ut som om jeg har den ultimate makten? Ordenen bruker oss alle. Gå nå, jeg er allerede død.","Czy wyglądam jakbym był we władaniu niesamowitej mocy? Zakon wykorzystuje nas wszystkich. Idź stąd, i tak już jestem martwy.",Você acha que eu pareço alguém que possui um poder tremendo? A Ordem manipula a todos nós. Agora vá. Eu já estou morto.,,"Ți se pare că controlez puterea supremă? Ordinul ne folosește pe toți. Acum pleacă, sunt mort deja.",Разве я похож на обладателя невероятной мощи? Орден использует нас всех. Теперь иди. Я уже всё равно мёртв.,,"Ser jag ut som om jag har den ultimata makten? Orden använder oss alla. Gå nu, jag är redan död.","Nihai güce sahipmişim gibi mi görünüyorum? Tarikat hepimizi kullanır. Şimdi git, ben zaten ölüyüm." +Power is the key!,TXT_DLG_SCRIPT08_D3032_POWER,,,,Moc je tím klíčem!,Magt er nøglen!,Macht ist der Schlüssel!,,Povo estas la ŝlosilo!,¡El poder es la clave!,,Valta on avain!,Le pouvoir est la clé!,Az erő a kulcs!,Il potere è la chiave!,キーが力だ!,힘이 곧 열쇠다!,Kracht is de sleutel!,Makt er nøkkelen!,Moc jest kluczem!,O poder é a chave!,,Puterea e cheia!,В силе — всё!,,Makt är nyckeln!,Güç anahtardır! "Good, you're conscious again. When you grabbed that item the Programmer dropped, you let loose some terrible secrets.",TXT_DLG_SCRIPT10_D0_GOODY,MAP10: Macil.,,,"Už jsi vzhůru, dobře. Když jsi sebral tu věc, kterou Programátor upustil, odhalil jsi děsivá tajemství.","Godt, du er ved bevidsthed igen. Da du greb den genstand, som programmøren tabte, slap du nogle frygtelige hemmeligheder løs.","Gut, du bist wieder wach. Als du das Ding, das der Programmierer fallengelassen hat, packtest, hast du einige schlimme Geheimnisse enthüllt.",,"Bone, vi jam rekonsciiĝis. Kelkaj teruraj sekretoj malkovriĝis kiam vi prenis tiun objekton, kiu elfalis el la Programisto.","Bien, ya has despertado. Se han revelado un par de secretos terribles en cuanto has cogido el objeto ese que se le ha caído al Programador.","Bien, ya despertaste. Se revelaron un par de secretos terribles en cuanto agarraste el objeto ese que se le cayó al Programador.","Hyvä, olet jälleen tajuissasi. Kaapattuasi esineen, jonka Ohjelmoitsija oli pudottanut, toit valoon kauhistuttavia salaisuuksia.","Bien. Vous êtes conscient. Quand vous avez pris ceci au Programmeur, vous avez libéré de terrible secrets.","Remek, magadhoz tértél. Amikor megmarkoltad a tárgyat amit a Programozó elejtett, elég sok titokra fény derült.","Meno male, sei di nuovo conscio. Quando hai preso quell'oggetto dal Programmatore, hai scoperchiato dei terribili segreti.","良し、意識が戻ったか。 君がプログラマーの遺品を拾った時に -恐ろしい秘密が解放されたのだ。","아, 드디어 깨어났군요. 프로그래머가 죽고 나서 얻은 저 물건을 쥐는 동안 우리는 그것에 대한 끔찍한 비밀을 밝혀냈습니다...","Goed, je bent weer bij bewustzijn. Toen je dat item pakte, liet de programmeur je een aantal vreselijke geheimen los.","Bra, du er ved bevissthet igjen. Da du tok den gjenstanden programmereren mistet, slapp du løs noen forferdelige hemmeligheter.","Dobrze, znów jesteś przytomny. Kiedy podniosłeś ten przedmiot, który upuścił Programista, uwolnniłeś wiele strasznych sekretów.","Ótimo, já está consciente de novo. Quando você pegou o item que o Programador largou você deixou escapar alguns segredos terríveis.",,"Bun, ești conștient din nou. Când ai pus mâna pe obiectul ăla Programatorul ți-a dat drumul ca să elibereze niște secrete oribile.","Хорошо, ты пришёл в себя. Взяв в руки артефакт, который выронил Программист, ты раскрыл страшные тайны.",,"Güzel, tekrar kendine geldin. Programcı'nın düşürdüğü o eşyayı aldığında, bazı korkunç sırları açığa çıkardın." -What kind of secrets. ,TXT_RPLY0_SCRIPT10_D0_WHATK,〃,,,Jaká tajemství?,Hvilken slags hemmeligheder?,Was für Geheimnisse?,,Kiaj sekretoj?,¿Qué clase de secretos?,,Minkälaisia salaisuuksia?,De quels secrets parlez-vous?,Miféle titkok?,Che tipo di segreti.,その秘密とは。,어떤 비밀인가요?,Wat voor geheimen.,Hva slags hemmeligheter?,Jakich sekretów?,Que tipos de segredos?,,Ce fel de secrete?,Какие тайны?,,Ne tür sırlar? -"We have no idea where this weapon came from, but we must find out. You have wrested one from the Order, but we must have all five. We have reached the limits of my knowledge. Seek out the Oracle and ask it for help.",TXT_DLG_SCRIPT10_D1516_WEHAV,〃,,,"Nemáme tušení, odkud se tato zbraň vzala, ale musíme to zjistit. Jednu část jsi z rukou Řádu už umanul, ale musíme najít všech pět. Dosáhli jsme hranic mých vědomostí. Vyhledej Věštce a požádej jej o pomoc.","Vi har ingen anelse om, hvor dette våben kommer fra, men vi må finde ud af det. Du har vristet en fra Ordenen, men vi skal have alle fem. Vi har nået grænserne for min viden. Opsøg Oraklet og bed det om hjælp.","Wir haben keine Ahnung, wo diese Waffe herkommt, aber wir müssen es herausfinden. Du hast ein Teil dem Orden entrungen aber wir brauchen alle fünf. Wir haben die Grenzen meines Wissens erreicht. Suche das Orakel und frage es um Hilfe.",,"Ĝi estas armilo; ni ne konas ĝian originon, sed ni devas malkovri ĝin. Vi jam prenis pecon el La Ordono, sed ni bezonas ĉiujn kvin. Ĝis ĉi tie ĉio, kion mi scias. Serĉu la Orakolon kaj petu lin pri helpo.","Se trata de un arma; no sabemos su origen, pero hay que averiguarlo. Ya le has quitado una pieza a La Orden, pero necesitamos las cinco. Hasta ahí todo lo que sé. Busca al Oráculo y pídele ayuda.","Se trata de un arma; no sabemos su origen, pero hay que averiguarlo. Ya le quitaste una pieza a La Orden, pero necesitamos las cinco. Hasta ahí todo lo que sé. Busca al Oráculo y pídele ayuda.","Meillä ei ole aavistustakaan tämän aseen alkuperästä, mutta se on selvitettävä. Olet nyt riistänyt Veljeskunnan käsistä yhden, mutta meidän on saatava kaikki viisi. Oma tietämykseni päättyy tähän. Etsi apua Oraakkelilta.","Je n'ai aucune idée d'où vient cette arme, mais il faut que nous le découvrions. Vous en avez arraché une à l'Ordre, mais il faut trouver toutes les cinq. C'est tout ce que je sais pour l'instant. Allez voir l'Oracle et demandez son aide.","Nem tudjuk mi ennek a fegyvernek az eredete, de ki kell derítenünk. Elcsentél egyet a Rendtől, de meg kell szereznünk mind az ötöt. Elértük a tudásom határát. Keresd fel az Orákulumot, és kérdd a segítségét.","Non abbiamo alcuna idea su dove quest'arma provenga, ma dobbiamo scoprirlo. Ne hai sottratto una all'Ordine, ma dobbiamo ottenerle tutte e cinque. E qui abbiamo raggiunto il limite della mia conoscienza. Devi raggiungere l'Oracolo e chiedergli aiuto.","この武器が何処で造られたかは分からないが、 +恐ろしい秘密が解放されたのだ。","아, 드디어 깨어났군요. 프로그래머가 죽고 나서 얻은 저 물건을 쥐는 동안 우리는 그것에 대한 끔찍한 비밀을 밝혀냈습니다...","Goed, je bent weer bij bewustzijn. Toen je dat item pakte, liet de programmeur je een aantal vreselijke geheimen los.","Bra, du er ved bevissthet igjen. Da du tok den gjenstanden programmereren mistet, slapp du løs noen forferdelige hemmeligheter.","Dobrze, znów jesteś przytomny. Kiedy podniosłeś ten przedmiot, który upuścił Programista, uwolnniłeś wiele strasznych sekretów.","Ótimo, já está consciente de novo. Quando você pegou o item que o Programador largou você deixou escapar alguns segredos terríveis.",,"Bun, ești conștient din nou. Când ai pus mâna pe obiectul ăla Programatorul ți-a dat drumul ca să elibereze niște secrete oribile.","Хорошо, ты пришёл в себя. Взяв в руки артефакт, который выронил Программист, ты раскрыл страшные тайны.",,"Bra, du är vid medvetande igen. När du tog tag i föremålet som programmeraren tappade släppte du lös några hemska hemligheter.","Güzel, tekrar kendine geldin. Programcı'nın düşürdüğü o eşyayı aldığında, bazı korkunç sırları açığa çıkardın." +What kind of secrets. ,TXT_RPLY0_SCRIPT10_D0_WHATK,〃,,,Jaká tajemství?,Hvilken slags hemmeligheder?,Was für Geheimnisse?,,Kiaj sekretoj?,¿Qué clase de secretos?,,Minkälaisia salaisuuksia?,De quels secrets parlez-vous?,Miféle titkok?,Che tipo di segreti.,その秘密とは。,어떤 비밀인가요?,Wat voor geheimen.,Hva slags hemmeligheter?,Jakich sekretów?,Que tipos de segredos?,,Ce fel de secrete?,Какие тайны?,,Vad för slags hemligheter.,Ne tür sırlar? +"We have no idea where this weapon came from, but we must find out. You have wrested one from the Order, but we must have all five. We have reached the limits of my knowledge. Seek out the Oracle and ask it for help.",TXT_DLG_SCRIPT10_D1516_WEHAV,〃,,,"Nemáme tušení, odkud se tato zbraň vzala, ale musíme to zjistit. Jednu část jsi z rukou Řádu už umanul, ale musíme najít všech pět. Dosáhli jsme hranic mých vědomostí. Vyhledej Věštce a požádej jej o pomoc.","Vi har ingen anelse om, hvor dette våben kommer fra, men vi må finde ud af det. Du har vristet en fra Ordenen, men vi skal have alle fem. Vi har nået grænserne for min viden. Opsøg Oraklet og bed det om hjælp.","Wir haben keine Ahnung, wo diese Waffe herkommt, aber wir müssen es herausfinden. Du hast ein Teil dem Orden entrungen aber wir brauchen alle fünf. Wir haben die Grenzen meines Wissens erreicht. Suche das Orakel und frage es um Hilfe.",,"Ĝi estas armilo; ni ne konas ĝian originon, sed ni devas malkovri ĝin. Vi jam prenis pecon el La Ordono kaj ili entute estas kvin. Ĝis ĉi tie ĉio, kion mi scias. Serĉu la Orakolon kaj petu lin pri helpo.","Se trata de un arma; no sabemos su origen, pero hay que averiguarlo. Ya le has quitado una pieza a La Orden y son cinco en total. Hasta ahí todo lo que sé. Busca al Oráculo y pídele ayuda.","Se trata de un arma; no sabemos su origen, pero hay que averiguarlo. Ya le quitaste una pieza a La Orden y son cinco en total. Hasta ahí todo lo que sé. Busca al Oráculo y pídele ayuda.","Meillä ei ole aavistustakaan tämän aseen alkuperästä, mutta se on selvitettävä. Olet nyt riistänyt Veljeskunnan käsistä yhden, mutta meidän on saatava kaikki viisi. Oma tietämykseni päättyy tähän. Etsi apua Oraakkelilta.","Je n'ai aucune idée d'où vient cette arme, mais il faut que nous le découvrions. Vous en avez arraché une à l'Ordre, mais il faut trouver toutes les cinq. C'est tout ce que je sais pour l'instant. Allez voir l'Oracle et demandez son aide.","Nem tudjuk mi ennek a fegyvernek az eredete, de ki kell derítenünk. Elcsentél egyet a Rendtől, de meg kell szereznünk mind az ötöt. Elértük a tudásom határát. Keresd fel az Orákulumot, és kérdd a segítségét.","Non abbiamo alcuna idea su dove quest'arma provenga, ma dobbiamo scoprirlo. Ne hai sottratto una all'Ordine, ma dobbiamo ottenerle tutte e cinque. E qui abbiamo raggiunto il limite della mia conoscienza. Devi raggiungere l'Oracolo e chiedergli aiuto.","この武器が何処で造られたかは分からないが、 我々はそれを突き止める必要がある様だ。 どうやら全部で5つあり、君はオーダーから 1つ手に入れている。我々の理解を超える存在だ -オラクルを探し何か情報を得なければ。","이 무기가 어디서 왔는지는 모르겠다만, 얼른 찾아내야만 합니다. 그 한 조각을 비롯한 나머지 '다섯' 조각도 필요합니다. 제가 알고 있는 건 이게 다입니다. 오라클이라는 자를 만나서 도움을 요청해보세요.","We hebben geen idee waar dit wapen vandaan komt, maar we moeten erachter komen. Je hebt er een uit de Orde weggehaald, maar we moeten ze alle vijf hebben. We hebben de grenzen van mijn kennis bereikt. Zoek het Orakel op en vraag het om hulp.","Vi aner ikke hvor våpenet kom fra, men vi må finne det ut. Du har vristet ett fra Ordenen, men vi må ha alle fem. Vi har nådd grensen for min kunnskap. Oppsøk oraklet og be det om hjelp.","Nie mamy pojęcia skąd ta broń pochodzi, ale musimy się dowiedzieć. Wyrwałeś jedną z łap Zakonu, ale musimy zdobyć wszystkie pięć. Osiągnęliśmy szczyt tego co wiem. Poszukaj Wyroczni i poproś ją o pomoc.","Não fazemos idéia de onde esta arma veio, mas precisamos descobrir. Você conseguiu roubar um deles da Ordem, mas precisamos de todos os cinco. Já atingimos os limites do meu conhecimento. Procure o Oráculo e peça a ajuda dele.",,"Nu avem nicio idee în legătură cu proveniența armei, dar trebuie să aflăm. Ai luat una de la Ordin, dar avem nevoie de toate 5. Am ajuns la capătul cunoștiințelor mele. Mergi în căutarea Oracolului, și cere-i ajutorul.","Мы понятия не имеем, откуда взялось это оружие, но обязаны выяснить. Ты отбил один фрагмент у Ордена, но нам нужны все пять. Я рассказал тебе всё, что знал. Найди Оракула и попроси его о помощи.",,Bu silahın nereden geldiğini bilmiyoruz ama öğrenmeliyiz. Tarikat'tan bir tane aldınız ama beşini de almalıyız. Bilgimin sınırlarına ulaştık. Kahin'i ara ve ondan yardım iste. -I'm gonna need more supplies.,TXT_RPLY0_SCRIPT10_D1516_IMGON,〃,,,Budu potřebovat zásoby.,Jeg får brug for flere forsyninger.,Ich brauche mehr Ausrüstung.,,Mi bezonos pliajn provizojn.,Voy a necesitar más suministros.,,Tarvitsen lisää varusteita.,Il me faut de l'équipment.,Szükségem lesz még felszerelésre.,Mi serviranno più provviste.,それには補給がもっと必要だ。,물자가 좀 필요할 것 같은데.,Ik zal meer voorraden nodig hebben.,Jeg trenger flere forsyninger.,Będę potrzebować więcej zaopatrzenia.,Vou precisar de mais equipmento.,,O să am nevoie de mai multe provizii.,Мне потребуются ещё припасы.,,Daha fazla malzemeye ihtiyacım olacak. +オラクルを探し何か情報を得なければ。","이 무기가 어디서 왔는지는 모르겠다만, 얼른 찾아내야만 합니다. 그 한 조각을 비롯한 나머지 '다섯' 조각도 필요합니다. 제가 알고 있는 건 이게 다입니다. 오라클이라는 자를 만나서 도움을 요청해보세요.","We hebben geen idee waar dit wapen vandaan komt, maar we moeten erachter komen. Je hebt er een uit de Orde weggehaald, maar we moeten ze alle vijf hebben. We hebben de grenzen van mijn kennis bereikt. Zoek het Orakel op en vraag het om hulp.","Vi aner ikke hvor våpenet kom fra, men vi må finne det ut. Du har vristet ett fra Ordenen, men vi må ha alle fem. Vi har nådd grensen for min kunnskap. Oppsøk oraklet og be det om hjelp.","Nie mamy pojęcia skąd ta broń pochodzi, ale musimy się dowiedzieć. Wyrwałeś jedną z łap Zakonu, ale musimy zdobyć wszystkie pięć. Osiągnęliśmy szczyt tego co wiem. Poszukaj Wyroczni i poproś ją o pomoc.","Não fazemos idéia de onde esta arma veio, mas precisamos descobrir. Você conseguiu roubar um deles da Ordem, mas precisamos de todos os cinco. Já atingimos os limites do meu conhecimento. Procure o Oráculo e peça a ajuda dele.",,"Nu avem nicio idee în legătură cu proveniența armei, dar trebuie să aflăm. Ai luat una de la Ordin, dar avem nevoie de toate 5. Am ajuns la capătul cunoștiințelor mele. Mergi în căutarea Oracolului, și cere-i ajutorul.","Мы понятия не имеем, откуда взялось это оружие, но обязаны выяснить. Ты отбил один фрагмент у Ордена, но нам нужны все пять. Я рассказал тебе всё, что знал. Найди Оракула и попроси его о помощи.",,"Vi har ingen aning om var det här vapnet kom ifrån, men vi måste ta reda på det. Du har vridit en från Orden, men vi måste få alla fem. Vi har nått gränsen för min kunskap. Sök upp Oraklet och be det om hjälp.",Bu silahın nereden geldiğini bilmiyoruz ama öğrenmeliyiz. Tarikat'tan bir tane aldınız ama beşini de almalıyız. Bilgimin sınırlarına ulaştık. Kahin'i ara ve ondan yardım iste. +I'm gonna need more supplies.,TXT_RPLY0_SCRIPT10_D1516_IMGON,〃,,,Budu potřebovat zásoby.,Jeg får brug for flere forsyninger.,Ich brauche mehr Ausrüstung.,,Mi bezonos pliajn provizojn.,Voy a necesitar más suministros.,,Tarvitsen lisää varusteita.,Il me faut de l'équipment.,Szükségem lesz még felszerelésre.,Mi serviranno più provviste.,それには補給がもっと必要だ。,물자가 좀 필요할 것 같은데.,Ik zal meer voorraden nodig hebben.,Jeg trenger flere forsyninger.,Będę potrzebować więcej zaopatrzenia.,Vou precisar de mais equipmento.,,O să am nevoie de mai multe provizii.,Мне потребуются ещё припасы.,,Jag kommer att behöva mer förnödenheter.,Daha fazla malzemeye ihtiyacım olacak. "Here's some gold. Go visit the medic and the weapons trainer and then, move out!",TXT_DLG_SCRIPT10_D3032_HERES,〃,,,"Tady je nějaké zlato. Jdi navštívit zdravotníka a zbraňmistra, a pak odchod!","Her er noget guld. Besøg lægen og våbentræneren, og så af sted!",Hier ist etwas Gold. Geh zum Sanitäter und zum Waffentrainer und dann los!,,"Jen iom da oro. Iru renkonti la kuraciston kaj la armilan trejniston, kaj tiam ekagu!","Aquí tienes algo de oro. Ve a ver al médico y al entrenador de armas y luego, ¡en marcha!",,"Tässä vähän kultaa. Tapaa lääkintämiestä ja asekouluttajaa, ja sen jälkeen lähde matkaan!","Voilà de l'argent. Allez voir le médecin et le maître d'armes, puis partez!","Itt van egy kis arany. Keresd fel a szanitécot és a fegyvermestert, aztán indulás!","Ecco dell'oro. Visita il dottore e l'istruttore d'armi, e poi, è tempo di muoversi!","資金を提供しよう。 そしてメディックと訓練士に会い装備を整えて、 -向かいたまえ!",골드를 좀 받으세요. 의무관이랑 무기 담당관을 찾아뵈시고 이동하시길!,Hier is wat goud. Ga naar de dokter en de wapentrainer en ga dan weg!,"Her er litt gull. Gå til legen og våpentreneren, og så drar vi!","Masz tu trochę złota. Odwiedź medyka i trenera od broni, a potem wykonać!",Pegue este dinheiro. Vá ver o médico e o treinador de armas e depois parta para a missão.,,"Uite niște aur. Vizitează medicul și antrenorul de arme iar apoi, dă-i drumul!","Вот немного золота. Посети медика и инструктора по стрельбе, и выдвигайся!",,İşte biraz altın. Sıhhiyeciyi ve silah eğitmenini ziyaret et ve sonra yola çık! -Right!,TXT_RPLY0_SCRIPT10_D3032_RIGHT,〃,,,Ano!,Så går vi.,Ja.,,Kompreneble!,¡A la orden!,,Selvä!,Bien!,Igenis!,Sarà fatto!,わかった!,네!,Juist!,Skal bli!,Dobrze!,Certo!,,Într-adevăr!,Есть!,,Tamamdır! -Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT10_D4548_FIGHT,〃,,,Bojuj za Frontu a svobodu! Odchod.,Kæmp for fronten og friheden. Af sted.,Kämpfe für die Front und die Freiheit. Nun geh.,,Batalu pro la Fronto kaj liberigota lando. Ekagu.,Lucha por el Frente y la libertad. En marcha.,,Taistele Rintaman ja vapauden puolesta. Liikkeelle mars.,Battez vous pour le Front et pour la liberté. Repos.,Együtt a Frontért és a szabadságért! Indulás!,"Lotta, per il Fronte e per la libertà! E ora, al lavoro.",フロントと自由の為の闘争を。さあ向かえ。,"프론트와 자유를 향하여, 전진하세요!",Vecht voor het front en vrijheid. Verhuizen.,Kjemp for fronten og friheten. Av sted med dere.,Walcz dla Frontu i wolności. Wykonać.,Lute pela Frente e pela liberdade. Agora vá.,,Luptă pentru Front și libertate. Acum pleacă.,Сражайся за свободу и справедливость. Выдвигайся.,,Cephe ve özgürlük için savaşın. Dışarı çıkın. +向かいたまえ!",골드를 좀 받으세요. 의무관이랑 무기 담당관을 찾아뵈시고 이동하시길!,Hier is wat goud. Ga naar de dokter en de wapentrainer en ga dan weg!,"Her er litt gull. Gå til legen og våpentreneren, og så drar vi!","Masz tu trochę złota. Odwiedź medyka i trenera od broni, a potem wykonać!",Pegue este dinheiro. Vá ver o médico e o treinador de armas e depois parta para a missão.,,"Uite niște aur. Vizitează medicul și antrenorul de arme iar apoi, dă-i drumul!","Вот немного золота. Посети медика и инструктора по стрельбе, и выдвигайся!",,"Här är lite guld. Gå och besök läkaren och vapentränaren och sedan, sätt fart!",İşte biraz altın. Sıhhiyeciyi ve silah eğitmenini ziyaret et ve sonra yola çık! +Right!,TXT_RPLY0_SCRIPT10_D3032_RIGHT,〃,,,Ano!,Så går vi.,Ja.,,Kompreneble!,¡A la orden!,,Selvä!,Bien!,Igenis!,Sarà fatto!,わかった!,네!,Juist!,Skal bli!,Dobrze!,Certo!,,Într-adevăr!,Есть!,,Okej!,Tamamdır! +Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT10_D4548_FIGHT,〃,,,Bojuj za Frontu a svobodu! Odchod.,Kæmp for fronten og friheden. Af sted.,Kämpfe für die Front und die Freiheit. Nun geh.,,Batalu pro la Fronto kaj liberigota lando. Ekagu.,Lucha por el Frente y la libertad. En marcha.,,Taistele Rintaman ja vapauden puolesta. Liikkeelle mars.,Battez vous pour le Front et pour la liberté. Repos.,Együtt a Frontért és a szabadságért! Indulás!,"Lotta, per il Fronte e per la libertà! E ora, al lavoro.",フロントと自由の為の闘争を。さあ向かえ。,"프론트와 자유를 향하여, 전진하세요!",Vecht voor het front en vrijheid. Verhuizen.,Kjemp for fronten og friheten. Av sted med dere.,Walcz dla Frontu i wolności. Wykonać.,Lute pela Frente e pela liberdade. Agora vá.,,Luptă pentru Front și libertate. Acum pleacă.,Сражайся за свободу и справедливость. Выдвигайся.,,Kämpa för fronten och friheten. Gå ut.,Cephe ve özgürlük için savaşın. Dışarı çıkın. "What prompts your return? Are you hurt? There's no time to lose, continue with your mission. Complete the Sigil.",TXT_DLG_SCRIPT10_D6064_WHATP,,,,"Co přimělo tvůj návrát? Jsi zraněný? Není času nazbyt, pokračuj ve své misi. Dokonči Pečeť.","Hvad får dig til at vende tilbage? Er du såret? Der er ingen tid at spilde, fortsæt med din mission. Færdiggør sigilet.","Warum kommst du zurück? Bist du verletzt? Wir haben keine Zeit zu verlieren, du musst deine Mission fortsetzen. Vervollständige das Sigil.",,,"¿A qué se debe tu retorno? ¿Estás herido? No hay tiempo que perder, continua con tu misión. Completa el Emblema.",,Miksi olet palannut? Oletko loukkaantunut? Aikaa ei ole menetettävänä; jatka tehtävääsi. Kokoa Sinetti.,"Qu'est ce qui vous amène? Vous avez mal? Il n'y a pas de temps à perdre. Continuez votre mission, complétez le Sigil.","Hogyhogy ilyen hamar visszatértél? Megsebesültél? Nem vesztegethetjük az időt, folytasd a küldetésed. Fejezd be a pecsétet.","Come mai già di ritorno? Sei ferito? Non c'è tempo da perdere, continua la tua missione. Completa il Sigillo.","何が帰還を促した?怪我をしたのか? 屈している場合ではない。 -シジルを完成させる使命を果たすんだ。",돌아왔습니까? 상처라도 입었나요? 시간이 없으니 임무를 속행하고 시질 조각을 마저 모으시길 바랍니다.,"Wat zet je ertoe aan om terug te keren? Ben je gewond? Er is geen tijd te verliezen, ga verder met je missie. Voltooi de Sigil.","Hvorfor kommer du tilbake? Er du såret? Det er ingen tid å miste, fortsett med oppdraget ditt. Fullfør sigillet.","Co skłoniło cię do powrotu? Jesteś ranny? Nie ma czasu do stracenia, kontynuuj swą misję. Uzupełnij Pieczęć.",O que fez você retornar? Você está ferido? Não há tempo a perder. Continue com a sua missão. Complete o Sigilo.,,"Ce te aduce înapoi? Nu avem timp de pierdut, continuă-ți misiunea. Asamblează Sigiliul.",С какой целью ты вернулся? Ты ранен? Нельзя терять ни минуты. Продолжай выполнение задания. Собери Печать!,,"Geri dönmene ne sebep oldu? Yaralandın mı? Kaybedecek zaman yok, görevinize devam edin. Sigil'i tamamla." -The Oracle says you must die!,TXT_RPLY0_SCRIPT10_D6064_THEOR,,,,"Věštec říká, že musíš zemřít!","Oraklet siger, at du skal dø!","Das Orakel sagt, du musst sterben.",,,¡El Oráculo dice que debes morir!,,"Oraakkeli sanoo, että sinun pitää kuoleman!",L'Oracle dit que vous devez mourir!,"Az Orákulum azt üzeni, hogy meg kell halnod!",L'Oracolo mi ha detto che devi morire!,オラクルは死ぬべきだと言った!,오라클의 이름으로 넌 죽어야 해!,Het Orakel zegt dat je moet sterven!,Oraklet sier at du må dø!,Wyrocznia mówi że musisz zginąć!,O Oráculo diz que você deve morrer!,,Oracolul spune că trebuie să mori!,"Оракул сказал, что я должен убить тебя!",,Kahin ölmen gerektiğini söylüyor! +シジルを完成させる使命を果たすんだ。",돌아왔습니까? 상처라도 입었나요? 시간이 없으니 임무를 속행하고 시질 조각을 마저 모으시길 바랍니다.,"Wat zet je ertoe aan om terug te keren? Ben je gewond? Er is geen tijd te verliezen, ga verder met je missie. Voltooi de Sigil.","Hvorfor kommer du tilbake? Er du såret? Det er ingen tid å miste, fortsett med oppdraget ditt. Fullfør sigillet.","Co skłoniło cię do powrotu? Jesteś ranny? Nie ma czasu do stracenia, kontynuuj swą misję. Uzupełnij Pieczęć.",O que fez você retornar? Você está ferido? Não há tempo a perder. Continue com a sua missão. Complete o Sigilo.,,"Ce te aduce înapoi? Nu avem timp de pierdut, continuă-ți misiunea. Asamblează Sigiliul.",С какой целью ты вернулся? Ты ранен? Нельзя терять ни минуты. Продолжай выполнение задания. Собери Печать!,,"Vad föranleder din återkomst? Är du skadad? Det finns ingen tid att förlora, fortsätt med ditt uppdrag. Slutför Sigillet.","Geri dönmene ne sebep oldu? Yaralandın mı? Kaybedecek zaman yok, görevinize devam edin. Sigil'i tamamla." +The Oracle says you must die!,TXT_RPLY0_SCRIPT10_D6064_THEOR,,,,"Věštec říká, že musíš zemřít!","Oraklet siger, at du skal dø!","Das Orakel sagt, du musst sterben.",,,¡El Oráculo dice que debes morir!,,"Oraakkeli sanoo, että sinun pitää kuoleman!",L'Oracle dit que vous devez mourir!,"Az Orákulum azt üzeni, hogy meg kell halnod!",L'Oracolo mi ha detto che devi morire!,オラクルは死ぬべきだと言った!,오라클의 이름으로 넌 죽어야 해!,Het Orakel zegt dat je moet sterven!,Oraklet sier at du må dø!,Wyrocznia mówi że musisz zginąć!,O Oráculo diz que você deve morrer!,,Oracolul spune că trebuie să mori!,"Оракул сказал, что я должен убить тебя!",,Oraklet säger att du måste dö!,Kahin ölmen gerektiğini söylüyor! I have sworn myself to freedom. It is the Oracle who holds the third piece. There's your traitor.,TXT_DLG_SCRIPT10_D7580_IHAVE,,,,"Já jsem zapřísáhnut svobodě! Věštec je ten, kdo má u sebe třetí díl. On je ten zrádce.","Jeg har svoret mig selv til frihed. Det er Oraklet, der har den tredje del. Der er din forræder.",Ich habe mich der Freiheit verpflichtet. Das Orakel besitzt das dritte Teilstück. Dort ist dein Verräter.,,,He hecho un juramento por la libertad. Es el Oráculo quien tiene la tercera pieza. Ahí tienes a tu traidor.,,Olen vannonut itseni vapauteen. Kolmas osanen on Oraakkelin hallussa. Siinä on petturisi.,J'ai juré donner ma vie à la liberté. C'est l'Oracle qui porte la troisième pièce. Voilà votre traître.,Felesküdtem a szabadságra. Az Orákulumnál van a harmadik darab. Ő lesz az árulód.,Io ho dedicato tutto me stesso alla libertà. È l'Oracolo che tiene il terzo pezzo. Ecco chi è il traditore.,"私は皆の自由を誓った。 三つ目の部品を持つのはオラクルだ。 -君は裏切るつもりか。",전 자유를 지키겠다고 맹세했습니다. 오라클이 세 번째 조각을 가지고 있단 말입니다. 그자가 바로 배신자입니다!,Ik heb mezelf gezworen tot vrijheid. Het is het Orakel dat het derde deel vasthoudt. Daar is je verrader.,Jeg har sverget meg til frihet. Det er oraklet som har den tredje biten. Der er forræderen din.,Przysiągłem sobie wolność. To Wyrocznia ma trzeci fragment. Masz tu swego zdrajcę.,Eu fiz um juramento à liberdade. É o Oráculo que possui a terceira peça. Ele é o seu traidor.,,Am jurat pentru libertate. Oracolul deține a treia piesă. Iată trădătorul.,Я присягнул борьбе за свободу. Третий фрагмент хранится у Оракула. Он и есть предатель.,,Özgürlük için yemin ettim. Üçüncü parça Kahin'de. İşte hainin. -The Oracle will die then!,TXT_RPLY0_SCRIPT10_D7580_THEOR,,,,Pak Věštec zemře!,Så dør Oraklet!,Dann wird das Orakel sterben.,,,¡El Oráculo morirá entonces!,,Siinä tapauksessa Oraakkeli kuolkoon!,L'Oracle va donc mourir!,Akkor meghal az Orákulum!,E allora l'Oracolo morirà!,オラクルは後で仕留める!,그럼 오라클을 죽여야겠군.,Het Orakel zal dan sterven!,Da skal oraklet dø!,A więc to Wyrocznia zginie!,O Oráculo morrerá então!,,Oracolul va pieri atunci!,Тогда умрёт Оракул!,,O zaman Kahin ölecek! -I think you're the traitor!,TXT_RPLY1_SCRIPT10_D7580_ITHIN,,,,"Myslím, že ty jsi ten zrádce!","Jeg tror, du er forræderen!","Ich denke, du bist der Verräter.",,,¡Creo que tú eres el traidor!,,"Luulen, että petturi olet sinä!","Je pense que c'est vous, le traître!",Azt hiszem inkább te vagy az áruló!,Io penso che sia tu il traditore!,裏切り者はお前の方だ!,배신자는 바로 당신이야!,Ik denk dat jij de verrader bent!,Jeg tror du er forræderen!,Według mnie to ty jesteś zdrajcą!,Eu acho que você que é o traidor!,,Eu cred că tu ești trădătorul!,"Я думаю, что предатель — это ты!",,Bence hain sensin! +君は裏切るつもりか。",전 자유를 지키겠다고 맹세했습니다. 오라클이 세 번째 조각을 가지고 있단 말입니다. 그자가 바로 배신자입니다!,Ik heb mezelf gezworen tot vrijheid. Het is het Orakel dat het derde deel vasthoudt. Daar is je verrader.,Jeg har sverget meg til frihet. Det er oraklet som har den tredje biten. Der er forræderen din.,Przysiągłem sobie wolność. To Wyrocznia ma trzeci fragment. Masz tu swego zdrajcę.,Eu fiz um juramento à liberdade. É o Oráculo que possui a terceira peça. Ele é o seu traidor.,,Am jurat pentru libertate. Oracolul deține a treia piesă. Iată trădătorul.,Я присягнул борьбе за свободу. Третий фрагмент хранится у Оракула. Он и есть предатель.,,Jag har svurit på frihet. Det är Oraklet som har den tredje delen. Där är din förrädare.,Özgürlük için yemin ettim. Üçüncü parça Kahin'de. İşte hainin. +The Oracle will die then!,TXT_RPLY0_SCRIPT10_D7580_THEOR,,,,Pak Věštec zemře!,Så dør Oraklet!,Dann wird das Orakel sterben.,,,¡El Oráculo morirá entonces!,,Siinä tapauksessa Oraakkeli kuolkoon!,L'Oracle va donc mourir!,Akkor meghal az Orákulum!,E allora l'Oracolo morirà!,オラクルは後で仕留める!,그럼 오라클을 죽여야겠군.,Het Orakel zal dan sterven!,Da skal oraklet dø!,A więc to Wyrocznia zginie!,O Oráculo morrerá então!,,Oracolul va pieri atunci!,Тогда умрёт Оракул!,,Oraklet kommer att dö då!,O zaman Kahin ölecek! +I think you're the traitor!,TXT_RPLY1_SCRIPT10_D7580_ITHIN,,,,"Myslím, že ty jsi ten zrádce!","Jeg tror, du er forræderen!","Ich denke, du bist der Verräter.",,,¡Creo que tú eres el traidor!,,"Luulen, että petturi olet sinä!","Je pense que c'est vous, le traître!",Azt hiszem inkább te vagy az áruló!,Io penso che sia tu il traditore!,裏切り者はお前の方だ!,배신자는 바로 당신이야!,Ik denk dat jij de verrader bent!,Jeg tror du er forræderen!,Według mnie to ty jesteś zdrajcą!,Eu acho que você que é o traidor!,,Eu cred că tu ești trădătorul!,"Я думаю, что предатель — это ты!",,Jag tror att du är förrädaren!,Bence hain sensin! Spirit of the One God avenge me and turn this world into dust.,TXT_DLG_SCRIPT10_D9096_SPIRI,,,,Duše Jednoho boha nechť mě pomstí a promění tento svět v prach!,Den ene Guds ånd hævner mig og gør denne verden til støv.,"Geist des einen Gottes, räche mich und verwandle diese Welt zu Staub.",,,Espíritu del Dios Único véngame y convierte este mundo en polvo.,,Yhden Ainoan Jumalan Henki kostakoon puolestani ja muuttakoon tämän maailman tuhaksi.,Que le Saint Esprit du Seul Dieu me venge et brûle ce monde jusqu'au cendres.,"Az egy igaz isten lelke bosszúljon meg, és zúzza porrá ezt a világot.","Spirito dell'Unico Dio, vendicami e trasforma questo mondo in cenere!","唯一神の魂が私を討てば -この世界を塵に変えるだろう。","유일신의 혼이여, 이 세계를 잿더미로 만듦으로써 저를 위해 복수하심이!!",De geest van de Ene God wreekt me en maakt deze wereld tot stof.,"Ånd av den ene Gud, hevn meg og gjør denne verden til støv.",Duchu Jedynego Boga pomścij mnie i zrównaj ten świat z ziemią.,"Ó, Espírito do Deus Único. Vingue-me e transforme este mundo em pó.",,Spiritul Adevăratului Zeu să mă răzbune și să facă lumea asta cenușă.,Дух Единого Бога отомстит за меня и обратит этот мир в прах.,,Tek Tanrı'nın Ruhu intikamımı al ve bu dünyayı toza çevir. +この世界を塵に変えるだろう。","유일신의 혼이여, 이 세계를 잿더미로 만듦으로써 저를 위해 복수하심이!!",De geest van de Ene God wreekt me en maakt deze wereld tot stof.,"Ånd av den ene Gud, hevn meg og gjør denne verden til støv.",Duchu Jedynego Boga pomścij mnie i zrównaj ten świat z ziemią.,"Ó, Espírito do Deus Único. Vingue-me e transforme este mundo em pó.",,Spiritul Adevăratului Zeu să mă răzbune și să facă lumea asta cenușă.,Дух Единого Бога отомстит за меня и обратит этот мир в прах.,,Den ende gudens ande hämnas mig och förvandlar den här världen till stoft.,Tek Tanrı'nın Ruhu intikamımı al ve bu dünyayı toza çevir. You have made the right decision. Its clear that the Oracle is controlled by whatever evil is driving the Order. Return to it and claim the third piece of the Sigil.,TXT_DLG_SCRIPT10_D10612_YOUHA,,,,"Učinil jsi správné rozhodnutí. Je zřejmé, že Věštec je ovládán tím zlem, které vede Řád. Vrať se k němu a přivlastni si třetí díl Pečetě.","Du har truffet den rigtige beslutning. Det er tydeligt, at Oraklet er kontrolleret af den ondskab, der driver ordenen. Vend tilbage til det og hæv den tredje del af sigilet.","Du hast die richtige Wahl getroffen. Es ist offensichtlich, dass das Orakel von demselben Übel kontrolliert wird, das den Orden antreibt. Kehre zu ihm zurück und hol dir das dritte Teilstück.",,,Has tomado la decisión correcta. Está claro que el Oráculo está siendo controlado por el mal que está detras de la Orden. Vuelve ante él y reclama la tercera pieza del Emblema.,,"Olet tehnyt oikean päätöksen. Mikä tahansa paha vallitseekaan Veljeskuntaa, selvästi myös hallitsee Oraakkelia. Palaa sen luokse ja lunasta Sinetti.",Vous avez fait le bon choix. Il est clair que l'Oracle est contrôlé par le mal qui est derrière l'Ordre. Retournez le voir et récupérez la troisième pièce du Sigil.,"A megfelelő döntést hoztad. Biztos, hogy az Orákulumot is az a gonosz hajtja, ami a Rendet. Térj vissza hozzá, és követeld tőle a Pecsét harmadik darabját.",Hai fatto la scelta giusta. È chiaro che l'Oracolo è controllato dallo stesso male che guida l'Ordine. Ritorna dall'Oracolo e reclama il terzo pezzo del Sigillo.,"君は正しい決断をした。 オラクルがオーダーに悪しき支配をしているのは 明白だ。戻って三番目のシジルを手に入れろ。","좋은 선택입니다. 아무래도 오더가 이끄는 악에서 오라클을 조종하는 것이 명백해졌으니, 녀석을 찾아가 시질의 세 번째 조각을 회수하세요. - \cy어서 가자, 나의 영웅. 그 못생긴 녀석에게 본때를 보여주자고.",Je hebt de juiste keuze gemaakt. Het is duidelijk dat het Orakel wordt beheerst door het kwaad dat de Orde drijft. Keer ernaar terug en claim het derde deel van de Sigil.,Du har tatt den rette avgjørelsen. Det er tydelig at oraklet styres av den ondskapen som driver ordenen. Vend tilbake til det og gjør krav på den tredje delen av sigillet.,"Postąpiłeś słusznie. To oczywiste, że Wyrocznia jest kontrolowana przez to zło które rządzi Zakonem. Wróć tam i odbierz jej trzeci fragment Pieczęci.",Você fez a decisão certa. Está claro que o Oráculo está sendo controlado por alguma força maligna por trás da Ordem. Volte para lá e pegue a terceira peça do Sigilo.,,Ai făcut alegerea corectă. E limpede că Oracolul e controlat de orice rău conduce și Ordinul. Întoarce-te la el și pune mâna pe cea de-a treia piesă a Sigiliului.,"Ты сделал правильный выбор. Ясно, что Оракулом управляет то же самое зло, что стоит за Орденом. Вернись к Оракулу и потребуй отдать тебе третий фрагмент Печати!",,"Doğru kararı verdin. Kahin'in, Düzen'i yönlendiren şeytan tarafından kontrol edildiği çok açık. Ona dön ve Sigil'in üçüncü parçasını al." + \cy어서 가자, 나의 영웅. 그 못생긴 녀석에게 본때를 보여주자고.",Je hebt de juiste keuze gemaakt. Het is duidelijk dat het Orakel wordt beheerst door het kwaad dat de Orde drijft. Keer ernaar terug en claim het derde deel van de Sigil.,Du har tatt den rette avgjørelsen. Det er tydelig at oraklet styres av den ondskapen som driver ordenen. Vend tilbake til det og gjør krav på den tredje delen av sigillet.,"Postąpiłeś słusznie. To oczywiste, że Wyrocznia jest kontrolowana przez to zło które rządzi Zakonem. Wróć tam i odbierz jej trzeci fragment Pieczęci.",Você fez a decisão certa. Está claro que o Oráculo está sendo controlado por alguma força maligna por trás da Ordem. Volte para lá e pegue a terceira peça do Sigilo.,,Ai făcut alegerea corectă. E limpede că Oracolul e controlat de orice rău conduce și Ordinul. Întoarce-te la el și pune mâna pe cea de-a treia piesă a Sigiliului.,"Ты сделал правильный выбор. Ясно, что Оракулом управляет то же самое зло, что стоит за Орденом. Вернись к Оракулу и потребуй отдать тебе третий фрагмент Печати!",,Du har fattat rätt beslut. Det är uppenbart att Oraklet kontrolleras av den ondska som driver Orden. Återvänd till det och kräv den tredje delen av Sigillet.,"Doğru kararı verdin. Kahin'in, Düzen'i yönlendiren şeytan tarafından kontrol edildiği çok açık. Ona dön ve Sigil'in üçüncü parçasını al." "There seems no end to the horror we face. We have found out that the Order is not killing our people. It is transforming them, into bio-mechanical soldiers. Find the facility where this is being done and close it, permanently.",TXT_DLG_SCRIPT10_D12128_THERE,,,,"Zdá se, že zlo, kterému čelíme, nemá konce. Zjistili jsme, že Řád nezabíjí naše lidi, ale přeměňuje je na biomechanické vojáky. Najdi továrnu, kde se tohle děje, a zavři ji, natrvalo.","Der synes ikke at være nogen ende på den rædsel, vi står over for. Vi har fundet ud af, at ordenen ikke dræber vores folk. Den forvandler dem til biomekaniske soldater. Find det anlæg, hvor dette sker, og luk det for altid.","Der Horror, dem wir ausgesetzt sind, scheint kein Ende zu nehmen. Wir haben herausgefunden, dass der Orden unsere Leute nicht tötet, sondern sie transformiert - int biomechanische Soldaten.Finde die Einrichtung, wo dies passiert und schließe sie - endgültig.",,,"Parece que no hay fin para el horror al que nos enfrentamos. Hemos descubierto que la Orden no solo mata a nuestra gente. La está transformando, en soldados bio-mecánicos. Encuentra la instalación donde esto se hace y clausúrala, permanentemente.",,"Meitä kohdanneelle kauhulle ei näytä olevan loppua. Olemme saaneet selville, että Veljeskunta ei tapa meidän omiamme, vaan muuntelee heitä biomekaanisiksi sotilaiksi. Etsi laitos, jossa tätä tehdään, ja lakkauta se, pysyvästi.","Il semble qu'il n'y ait pas de fin aux horreurs auxquelles nous devons faire face. Nous venons de découvrir que l'Ordre n'exécute pas notre peuple, il le transforme en soldats biomécaniques. Trouvez l'usine qui gère ce processus et fermez la pour toujours.","Úgy néz ki, már soha nem lesz vége ennek a horrornak. Mint kiderült, a Rend nem megöli az embereinket, hanem bio-mechanikus robotokká alakítják át. Keresd meg a létesítményt, ahol ez folyik, és azonnal zárdd be.","Sembra che non ci sia limite agli orrori che affrontiamo. Abbiamo scoperto che l'Ordine non solo uccide la nostra gente, ma li trasforma anche in soldati bio-meccanici. Devi trovare lo stabilimento dove questo sta avvenendo e chiuderlo, permanentemente.","どうやら我々の直面する恐怖は まだ終わらない様だ。オーダーが民を無意味に 殺害しているだけではなく、サイボーグ兵へ改造 していることが解かった。その施設を探し出し 機能を停止させるのだ。永久的に。 ","우리가 마주하는 공포의 끝이 없는 것 같군요... 최근 오더가 우리를 학살하는 게 아닌 일종의 강화 인간으로 개조시키고 있었던 것이라고 소식을 들었습니다. 개조가 시행되고 있는 시설을 찾아가서 그곳을 영구적으로 정지시키세요. - \cy인간개조? 음, 이거 때문에 녀석들이 끊임없이 나오는 거였어! 녀석들 성질 더러운 것도 그렇고.","Er lijkt geen einde te komen aan de verschrikking waar we voor staan. We hebben ontdekt dat de Orde onze mensen niet doodt. Het transformeert hen, in bio-mechanische soldaten. Zoek de faciliteit waar dit gebeurt en sluit deze permanent.","Det ser ikke ut til å være noen ende på skrekken vi står overfor. Vi har funnet ut at Ordenen ikke dreper folket vårt. Den forvandler dem til biomekaniske soldater. Finn anlegget der dette gjøres og steng det, permanent.","Wygląda na to, że naszym koszmarom nie ma końca. Dowiedzieliśmy się, że Zakon nie zabija naszych ludzi. Tylko zmienia ich w biomechanicznych żołnierzy. Znajdź ośrodek, w którym to robią i zamknij go na dobre.","Parece que os horrores que enfrentamos não têm fim. Descobrimos que a Ordem não está matando o nosso pessoal. Está os transformando em soldados biomecânicos. Ache a instalação onde isso é feito e feche-a, de uma vez por todas.",,"Pare să nu existe limite pentru răul pe care îl înfruntăm. Îi transformă, în soldați bio-mecanici. Găsește fabrica unde se întâmplă asta și închide-o, permanent.","Иногда кажется, что эти ужасы никогда не закончатся. Мы узнали, что Орден не убивает наших людей. Он перерабатывает их в биомеханических солдат. Найди фабрику, где происходит это, и закрой её раз и навсегда!",,Karşılaştığımız dehşetin sonu yok gibi görünüyor. Tarikat'ın insanlarımızı öldürmediğini öğrendik. Onları biyo-mekanik askerlere dönüştürüyor. Bunun yapıldığı tesisi bulun ve kalıcı olarak kapatın. -Where is this located?,TXT_RPLY0_SCRIPT10_D12128_WHERE,,,,Kde ji najdu?,Hvor er det placeret?,Wo finde ich sie?,,,¿Dónde se encuentra?,,Missä se sijaitsee?,Où se trouve-elle?,Hol van ez?,Dove si trova?,手掛かりは何処にある?,이 장소는 어디에 있죠?,Waar bevindt deze faciliteit zich?,Hvor ligger det?,Gdzie się znajduje?,Onde se encontra?,,Unde este localizată?,Где она находится?,,Burası nerede? + \cy인간개조? 음, 이거 때문에 녀석들이 끊임없이 나오는 거였어! 녀석들 성질 더러운 것도 그렇고.","Er lijkt geen einde te komen aan de verschrikking waar we voor staan. We hebben ontdekt dat de Orde onze mensen niet doodt. Het transformeert hen, in bio-mechanische soldaten. Zoek de faciliteit waar dit gebeurt en sluit deze permanent.","Det ser ikke ut til å være noen ende på skrekken vi står overfor. Vi har funnet ut at Ordenen ikke dreper folket vårt. Den forvandler dem til biomekaniske soldater. Finn anlegget der dette gjøres og steng det, permanent.","Wygląda na to, że naszym koszmarom nie ma końca. Dowiedzieliśmy się, że Zakon nie zabija naszych ludzi. Tylko zmienia ich w biomechanicznych żołnierzy. Znajdź ośrodek, w którym to robią i zamknij go na dobre.","Parece que os horrores que enfrentamos não têm fim. Descobrimos que a Ordem não está matando o nosso pessoal. Está os transformando em soldados biomecânicos. Ache a instalação onde isso é feito e feche-a, de uma vez por todas.",,"Pare să nu existe limite pentru răul pe care îl înfruntăm. Îi transformă, în soldați bio-mecanici. Găsește fabrica unde se întâmplă asta și închide-o, permanent.","Иногда кажется, что эти ужасы никогда не закончатся. Мы узнали, что Орден не убивает наших людей. Он перерабатывает их в биомеханических солдат. Найди фабрику, где происходит это, и закрой её раз и навсегда!",,Det verkar inte finnas något slut på den skräck vi står inför. Vi har fått reda på att Orden inte dödar vårt folk. Den förvandlar dem till biomekaniska soldater. Hitta anläggningen där detta sker och stäng den för gott.,Karşılaştığımız dehşetin sonu yok gibi görünüyor. Tarikat'ın insanlarımızı öldürmediğini öğrendik. Onları biyo-mekanik askerlere dönüştürüyor. Bunun yapıldığı tesisi bulun ve kalıcı olarak kapatın. +Where is this located?,TXT_RPLY0_SCRIPT10_D12128_WHERE,,,,Kde ji najdu?,Hvor er det placeret?,Wo finde ich sie?,,,¿Dónde se encuentra?,,Missä se sijaitsee?,Où se trouve-elle?,Hol van ez?,Dove si trova?,手掛かりは何処にある?,이 장소는 어디에 있죠?,Waar bevindt deze faciliteit zich?,Hvor ligger det?,Gdzie się znajduje?,Onde se encontra?,,Unde este localizată?,Где она находится?,,Var finns den?,Burası nerede? "One of our captains, Richter, is waiting for you by the waterfall in the commons. He has seen the facility and can guide you inside. Stop this atrocity, now.",TXT_DLG_SCRIPT10_D13644_ONEOF,,,,"Jeden z našich kapitánů, Richter, na tebe čeká u vodopádů na návsi. Továrnu už viděl a může ti poradit, jak dovnitř. Zastav tuhle ohavnost, ihned.","En af vores kaptajner, Richter, venter på dig ved vandfaldet i fællesrummet. Han har set anlægget og kan guide dig indenfor. Stop denne grusomhed, nu.","Einer unserer Anführer, Rickter warted auf dich, am Wasserfall bei der Mensa. Er hat es gesehen und kann dich dort hinführen. Stope dieses Gräuel - sofort.",,,"Uno de nuestros capitanes, Richter, está esperándote junto a la cascada en los comunes. Ha visto la instalación y puede guiarte dentro. Detén esta atrocidad, ahora.",,"Richter, yksi kapteeneistamme, odottaa sinua messissä vesiputouksen äärellä. Hän on nähnyt laitoksen ja voi opastaa sinut sisälle. Lopeta tämä kauhistus, heti paikalla.","Un de nos capitaines, Richter, vous attend près de la cascade dans le réfectoire. Il a vu l'usine et peut vous guider jusqu'a l'intérieur. Arrêtez cette atrocité maintenant.","Richter - az egyik kapitányunk - a vízesés melletti étkezdénél fog várni rád. Ő látta ezt a létesítményt, és be tud vinni. Állítsd meg ezt a borzalmat azonnal.","Uno dei nostri capitani, Richter, ti sta aspettando vicino alla cascata nei comuni. Lui ha visto la fabbrica e ti può guidare dentro. Devi fermare quest'atrocità al più presto.","キャプテンの一人、リヒターが コモンズの滝で待っている。 彼は施設を発見し生還した者だ。 -早急にそのふざけた行為を止めさせろ。","우리 군의 한 대대장인 릭터가 식당가에 위치한 폭포 근처에서 당신을 기다리고 있습니다. 그는 그 끔찍한 시설을 보았다고 했으며, 침투할 수 있게 도와주고 싶다는군요. 부디 이 잔혹 행위를 멈출 수 있기를 바랍니다.","Een van onze kapiteins, Richter, wacht u op bij de waterval in het Lagerhuis. Hij heeft het gebouw gezien en kan je naar binnen leiden. Stop deze gruweldaad, nu.","En av våre kapteiner, Richter, venter på deg ved fossen i allmenningen. Han har sett anlegget og kan lede dere inn. Stopp denne grusomheten, nå.","Jeden z naszych kapitanów, Richter, czeka na ciebie przy wodospadzie przy błoniach. Widział ten ośrodek i pomoże ci się tam dostać. Skończ z tym okrucieństwem.","Um dos nossos capitães, Richter, está te esperando perto da cascata próxima ao refeitório. Ele conhece a instalação e pode te ajudar a infiltrá-la. Detenha essa atrocidade o quanto antes.",,"Unul dintre căpitanii noștri, Richter, te așteaptă lângă cascadă. A văzut fabrica și te poate conduce în interiorul ei. Încheie atrocitatea asta, acum.","Один из наших капитанов, Рихтер, ожидает тебя возле водопада в поселении Ордена. Он уже проникал на фабрику, и он скажет тебе, как туда попасть. Положи конец этим зверствам, немедленно!",,"Kaptanlarımızdan biri, Richter, ortak kullanım alanındaki şelalenin yanında sizi bekliyor. Tesisi gördü ve size içeride rehberlik edebilir. Bu vahşeti durdurun, hemen." -They'll pay for this!,TXT_RPLY0_SCRIPT10_D13644_THEYL,,,,Za tohle budou pykat!,De vil betale for dette!,Dafür werden sie bezahlen.,,,¡Pagarán por esto!,,Ne saavat maksaa tästä!,Ils paieront pour cela!,Megfizetnek ezért!,La pagheranno per questo!,奴等に対価を払わせてやるさ!,그놈들은 죗값을 치를 것입니다!,Zij zullen hiervoor betalen!,De skal få svi for dette!,Zapłacą za to!,Eles pagarão por isso!,,Vor plătii pentru asta!,Они за всё заплатят!,,Bunun bedelini ödeyecekler! -Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT10_D15160_FIGHT,,,,Bojuj za Frontu a svobodu! Odchod.,Kæmp for fronten og friheden. Af sted.,Kämpfe für die Front und die Freiheit. Nun geh.,,Batalu pro la Fronto kaj liberigota lando. Ekagu.,Lucha por el Frente y la libertad. En marcha.,,Taistele Rintaman ja vapauden puolesta. Liikkeelle mars.,Battez vous pour le Front et pour la liberté. Repos.,Együtt a Frontért és a szabadságért! Indulás!,"Lotta, per il Fronte e per la libertà! E ora, al lavoro.",フロントと自由の為の闘争を。さあ向かえ。,"프론트와 자유를 향하여, 전진하세요!",Vecht voor het Front en vrijheid. Ga weg.,Kjemp for fronten og friheten. Av sted!,Walcz dla Frontu i wolności. Wykonać.,Lute pela Frente e pela liberdade. Agora vá.,,Luptă pentru Front și libertate. Acum pleacă.,Сражайся за свободу и справедливость. Выдвигайся.,,Cephe ve özgürlük için savaşın. Dışarı çıkın. +早急にそのふざけた行為を止めさせろ。","우리 군의 한 대대장인 릭터가 식당가에 위치한 폭포 근처에서 당신을 기다리고 있습니다. 그는 그 끔찍한 시설을 보았다고 했으며, 침투할 수 있게 도와주고 싶다는군요. 부디 이 잔혹 행위를 멈출 수 있기를 바랍니다.","Een van onze kapiteins, Richter, wacht u op bij de waterval in het Lagerhuis. Hij heeft het gebouw gezien en kan je naar binnen leiden. Stop deze gruweldaad, nu.","En av våre kapteiner, Richter, venter på deg ved fossen i allmenningen. Han har sett anlegget og kan lede dere inn. Stopp denne grusomheten, nå.","Jeden z naszych kapitanów, Richter, czeka na ciebie przy wodospadzie przy błoniach. Widział ten ośrodek i pomoże ci się tam dostać. Skończ z tym okrucieństwem.","Um dos nossos capitães, Richter, está te esperando perto da cascata próxima ao refeitório. Ele conhece a instalação e pode te ajudar a infiltrá-la. Detenha essa atrocidade o quanto antes.",,"Unul dintre căpitanii noștri, Richter, te așteaptă lângă cascadă. A văzut fabrica și te poate conduce în interiorul ei. Încheie atrocitatea asta, acum.","Один из наших капитанов, Рихтер, ожидает тебя возле водопада в поселении Ордена. Он уже проникал на фабрику, и он скажет тебе, как туда попасть. Положи конец этим зверствам, немедленно!",,"En av våra kaptener, Richter, väntar på dig vid vattenfallet i allmänningen. Han har sett anläggningen och kan guida dig in. Stoppa denna grymhet, nu.","Kaptanlarımızdan biri, Richter, ortak kullanım alanındaki şelalenin yanında sizi bekliyor. Tesisi gördü ve size içeride rehberlik edebilir. Bu vahşeti durdurun, hemen." +They'll pay for this!,TXT_RPLY0_SCRIPT10_D13644_THEYL,,,,Za tohle budou pykat!,De vil betale for dette!,Dafür werden sie bezahlen.,,,¡Pagarán por esto!,,Ne saavat maksaa tästä!,Ils paieront pour cela!,Megfizetnek ezért!,La pagheranno per questo!,奴等に対価を払わせてやるさ!,그놈들은 죗값을 치를 것입니다!,Zij zullen hiervoor betalen!,De skal få svi for dette!,Zapłacą za to!,Eles pagarão por isso!,,Vor plătii pentru asta!,Они за всё заплатят!,,De kommer att få betala för detta!,Bunun bedelini ödeyecekler! +Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT10_D15160_FIGHT,,,,Bojuj za Frontu a svobodu! Odchod.,Kæmp for fronten og friheden. Af sted.,Kämpfe für die Front und die Freiheit. Nun geh.,,Batalu pro la Fronto kaj liberigota lando. Ekagu.,Lucha por el Frente y la libertad. En marcha.,,Taistele Rintaman ja vapauden puolesta. Liikkeelle mars.,Battez vous pour le Front et pour la liberté. Repos.,Együtt a Frontért és a szabadságért! Indulás!,"Lotta, per il Fronte e per la libertà! E ora, al lavoro.",フロントと自由の為の闘争を。さあ向かえ。,"프론트와 자유를 향하여, 전진하세요!",Vecht voor het Front en vrijheid. Ga weg.,Kjemp for fronten og friheten. Av sted!,Walcz dla Frontu i wolności. Wykonać.,Lute pela Frente e pela liberdade. Agora vá.,,Luptă pentru Front și libertate. Acum pleacă.,Сражайся за свободу и справедливость. Выдвигайся.,,Kämpa för fronten och friheten. Gå ut.,Cephe ve özgürlük için savaşın. Dışarı çıkın. "I am the One God... I need his spirit to be free so that I can leave my body, and join him in flight. You have no idea what you possess... And what terror you face... The One God must be free... And he will reward me... I will be one...",TXT_DLG_SCRIPT10_D16676_IAMTH,,,,"Já jsem Jedním bohem... Potřebuju jeho duši abych se osvobodil a opustil své tělo a mohl se k němu připojit na nebesích. Nemáš ani tušení, co držíš v rukách... a jaké hrůze čelíš... Jeden bůh musí být svobodný... odmění mě... Budu jeden...","Jeg er den eneste Gud... Jeg har brug for, at hans ånd bliver fri, så jeg kan forlade min krop og slutte mig til ham i flugten. Du har ingen idé om, hvad du besidder... Og hvilken terror du står over for... Den ene Gud skal være fri... Og han vil belønne mig... Jeg vil være én...","Ich bin der Eine Gott... Sein Geist muss frei sein so dass ich seinen Körper verlassen und mit ihm fliegen kann. Du hast keine Ahnung, was du besitzt... And welcher Terror die bevorsteht... Der Eine Gott muss frei sein... Und er wird mich belohnen... Ich werde eins...",,,"Soy el Dios Único... Necesito que su espíritu sea libre para poder abandonar mi cuerpo, y unirme a él en vuelo. No tienes ni idea de lo que posees... Y de el terror al que te enfrentas... El Dios Único debe ser libre... Y me recompensará... Seré uno...",,"Minä olen Yksi Ainoa Jumala... Tarvitsen hänen henkeään ollakseni vapaa ja poistuakseni ruumiistani, jotta voisin paeta hänen kanssaan. Et käsitäkään, mitä omaat... ja mitä kauhua olet kohtaava... Yhden Ainoan Jumalan on päästävä vapaaksi... Ja hän palkitsee minut... Tulen olemaan yksi...","Je suis le Seul Dieu.. Il me faut libérer son esprit pour qu'il puisse sortir de mon corps, et le rejoindre dans sa fuite. Vous ne savez pas ce que vous possédez.. Et la terreur à laquelle vous devrez faire face... Le Seul Dieu doit être libre.. Et il me récompensera.. Je serais un avec lui..","Én vagyok az egy Igaz Isten...ki akarom szabadítani a lelkét, hogy elhagyhassam a testemet és társuljak mellé a harcban. Ötleted sincs miféle erővel rendelkezel...és miféle terroral nézel szemben...az egy Igaz Istennek szabadnak kell lennie...és majd megjutalmaz...eggyé válok majd...","Io sono l'Unico Dio... Ho bisogno che il suo spirito sia libero così che io possa lasciare il mio corpo, e unirmi a lui in volo. Non hai idea di cosa possiedi... E di quale terrore vai ad affrontare... L'Unico Dio deve essere libero... E mi ricompenserà... E sarò io...","我が唯一神だ...我は己の肉体を離れ 自由となり、神の魂と共に飛び立てる。 貴様には何も分かりもしないだろう... @@ -10710,15 +11192,15 @@ Fight for the Front and freedom. Move out.,TXT_DLG_SCRIPT10_D15160_FIGHT,,,,Boju 唯一神は解放されるのだ... そして神は我を表彰するだろう... 我は一つとなる...","유일신... 그분의 영혼의 힘으로... 나의 육신을 버리고... 그분과 자유롭게 날아가리라... 그대가 소유한 것, 그대가 직면할 운명... 모두 모를 것이다... 유일신이 자유가 되면... 나에게 보답하시매, 그와 하나가 되리라!! - \cy역겨운 자식... 죽여버려!","Ik ben de enige God.... Ik heb zijn geest nodig om vrij te zijn, zodat ik mijn lichaam kan verlaten en met hem mee kan vliegen. Je hebt geen idee wat je bezit.... En welke terreur je onder ogen ziet.... De Ene God moet vrij zijn.... En hij zal mij belonen.... Ik zal er een zijn....","Jeg er den ene Gud... Jeg trenger hans ånd for å være fri, så jeg kan forlate kroppen min og bli med ham på flukt. Du aner ikke hva du besitter... Og hvilken skrekk du står overfor... Den ene Gud må være fri... Og han vil belønne meg... Jeg vil bli en...",Jam jest Jedyny Bóg... potrzebuję uwolnić jego duszę abym opuścił swe ciało i dołączył do niego. Nie masz pojęcia co ty posiadłeś... I z jakim terrorem się spotykasz... Jedyny Bóg musi być wolny... I on mnie nagrodzi... To ja będę tym jednym...,"Eu sou o Deus Único... Eu preciso desse espírito para ser livre, poder abandonar este corpo e unir-me a ele na fuga. Você não tem idéia do que possui... E o horror que você enfrenta... O Deus Único deve ser livre... E ele me recompensará... Eu serei um...",,"Eu sunt adevăratul Zeu.... Am nevoie de sufletul lui ca să pot să-mi părăsesc corpul, și să mă alătur lui în zbor. Nu ai idee despre ceea ce posezi... Și ce teroare înfrunți... Adevăratul Zeu trebuie să fie liber... Și mă va răsplătii... Voi fi unul...","Я Единый Бог... Я должен высвободить его дух, тогда я смогу покинуть бренную оболочку моего тела и воссоединиться с ним в полёте. Ты и понятия не имеешь, чем обладаешь... и с какому кошмару смотришь в лицо... Единый Бог должен быть освобождён... И он вознаградит меня... Это сделаю я!",,"Ben Tek Tanrı'yım. Onun ruhunun özgür olmasına ihtiyacım var, böylece bedenimi terk edebilir ve uçuşta ona katılabilirim. Neye sahip olduğunuz hakkında hiçbir fikriniz yok. Ve nasıl bir dehşetle karşı karşıya olduğunuzu. Tek Tanrı özgür olmalı. Ve o beni ödüllendirecek. Ben bir olacağım." -I will destroy you!,TXT_RPLY0_SCRIPT10_D16676_IWILL,,,,Zničím tě!,Jeg vil ødelægge dig!,Ich werde dich zerstören!,,,¡Te destruiré!,,Tuhoan sinut!,L'heure est venue de vous détruire!,Megsemmisítelek!,Ti distruggerò!,お前を滅ぼす!,당신을 처단하겠어!,Ik zal je vernietigen!,Jeg skal tilintetgjøre deg!,Zniszczę cię!,Eu vou destruir você!,,Te voi distruge!,Я уничтожу тебя!,,Seni yok edeceğim! -Glad to see you made it. What do you need? ,TXT_DLG_SCRIPT10_D18192_GLADT,MAP10: Gerald (no upgrade).,,,"Jsem rád, žes to zvládnul. Co bys potřeboval?","Godt at se, at du klarede den. Hvad har du brug for?","Gut, dass du es geschafft hast. Was brauchst du?",,,Me alegro de verte de una pieza. ¿Qué necesitas?,,"Hienoa, että selvisit. Mitä tarvitset?",Ravi de voir que vous vous en êtes sorti. Que puis-je faire pour vous?,"Örömmel látom, hogy túlélted. Miben segíthetek?",Lieto di vederti qui. Di che hai bisogno?,お会いできて光栄です。何が必要ですか?,여기까지 오시다니 놀랍군요. 뭔가 필요한 게?,Blij te zien dat je het gehaald hebt. Wat heb je nodig?,Godt å se at du kom. Hva trenger du?,"Dobrze widzieć, że udało ci się. Czego ci potrzeba?",Que bom que você conseguiu. O que você precisa?,,Mă bucur să văd că ai reușit. De ce ai nevoie?,"Я рад, что ты справился. Чем могу помочь?",,Gelebilmene sevindim. Neye ihtiyacın var? -Heal me.,TXT_RPLY0_SCRIPT10_D18192_HEALM,〃,,,Potřebuju ošetřit.,Helbrede mig.,Mach mich gesund.,,,Cúrame.,,Hoida minua.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료해주세요.,Genees me.,Helbred meg.,Ulecz mnie.,Me cure.,,Bandajează-mă.,Подлечи меня.,,İyileştir beni. -"Well, lets get you fixed up.",TXT_RYES0_SCRIPT10_D18192_WELLL,〃,,,"Dobře, tak tě dáme dohromady.","Nå, lad os få dig ordnet.","Gut, das hier sollte helfen.",,,"Bien, vamos a hacerte unos arreglos.",,"Selvä, pistetään sinut kuntoon.","Allez, on va vous remettre sur pied.","Na, akkor pofozzunk helyre.","Molto bene, ti darò una sistemata.",では、すぐ治療しましょう。,그럼 긴급 치료하겠습니다.,"Nou, laten we je opknappen.","Vel, la oss få deg fikset opp.","Dobra, pozbieram cię do kupy.","Ok, vamos dar um jeito em você.",,"Păi, să te aranjăm.","Ну, давай приведём тебя в порядок.",,"Pekala, seni iyileştirelim." -You're fine.,TXT_RNO0_SCRIPT10_D18192_YOURE,〃,,,Jsi v pořádku.,Du har det fint.,Die geht es gut.,,,Estás bien.,,Olet kunnossa.,Vous allez bien.,Rendben is vagy.,Stai bene.,貴方は大丈夫です。,괜찮아 보이는데.,Je bent in orde.,Det går bra med deg.,Jesteś zdrowy.,Você está bem.,,Ești în regulă.,Ты здоров.,,İyisin. -Anything new?,TXT_RPLY1_SCRIPT10_D18192_ANYTH,〃,,,Něco nového?,Noget nyt?,Irgend etwas Neues?,,,¿Algo nuevo?,,Onko mitään uutta?,Quoi de neuf?,Valami újdonság?,Novità?,何か新しいのは?,특별한 거 없나요?,Iets nieuws?,Noe nytt?,Coś nowego?,Alguma novidade?,,Ceva nou?,Есть что-нибудь новое?,,Yeni bir şey var mı? -"Yes, I've got some new hardware for you.",TXT_RYES1_SCRIPT10_D18192_YESIV,〃,,,"Ano, mám pro tebe novou mašinku.","Ja, jeg har noget nyt hardware til dig.","Ja, ich habe neue Hardware für dich.",,,"Sí, tengo nuevo hardware para ti.",,"Kyllä, minulla on sinulle uutta rautaa.","Ah, j'ai du nouveau matériel pour vous.","Igen, van pár új fegyverem számodra.","Si, ho delle nuove attrezzature per te.",貴方の為に幾つか新しいハードウェアを見つけました。,네! 사용 가능한 하드웨어가 하나 있습니다.,"Ja, ik heb wat nieuwe hardware voor je.","Ja, jeg har noe nytt utstyr til deg.","Tak, mam dla ciebie nowe oprogramowanie.","Sim, tenho equipamento novo pra você.",,"Da, am ceva hardware nou pentru tine.",Да. Новая аппаратура для тебя.,,"Evet, senin için yeni bir donanımım var." -"Nope, I'm working on it though.",TXT_RNO1_SCRIPT10_D18192_NOPEI,〃,,,"Ne, ale pracuju na tom.","Nej, men jeg arbejder på det.","Nein, ich arbeite noch daran.",,,"No, pero estoy trabajando en ello.",,Ei; on kyllä työn alla.,"Rien, mais j'y travaille.","Nem, de már dolgozom rajta.","No, ma ci sto lavorando.",いえ、只今探しています。,아뇨. 아직 작업 진행 중입니다.,"Nee, maar ik ben er wel mee bezig.","Nei, men jeg jobber med det.","Nie, jeszcze nad tym pracuję.","Não, mas estou trabalhando nisso.",,"Nu, încă lucrez la asta.","Нет, но я работаю над ним.",,"Hayır, üzerinde çalışıyorum." + \cy역겨운 자식... 죽여버려!","Ik ben de enige God.... Ik heb zijn geest nodig om vrij te zijn, zodat ik mijn lichaam kan verlaten en met hem mee kan vliegen. Je hebt geen idee wat je bezit.... En welke terreur je onder ogen ziet.... De Ene God moet vrij zijn.... En hij zal mij belonen.... Ik zal er een zijn....","Jeg er den ene Gud... Jeg trenger hans ånd for å være fri, så jeg kan forlate kroppen min og bli med ham på flukt. Du aner ikke hva du besitter... Og hvilken skrekk du står overfor... Den ene Gud må være fri... Og han vil belønne meg... Jeg vil bli en...",Jam jest Jedyny Bóg... potrzebuję uwolnić jego duszę abym opuścił swe ciało i dołączył do niego. Nie masz pojęcia co ty posiadłeś... I z jakim terrorem się spotykasz... Jedyny Bóg musi być wolny... I on mnie nagrodzi... To ja będę tym jednym...,"Eu sou o Deus Único... Eu preciso desse espírito para ser livre, poder abandonar este corpo e unir-me a ele na fuga. Você não tem idéia do que possui... E o horror que você enfrenta... O Deus Único deve ser livre... E ele me recompensará... Eu serei um...",,"Eu sunt adevăratul Zeu.... Am nevoie de sufletul lui ca să pot să-mi părăsesc corpul, și să mă alătur lui în zbor. Nu ai idee despre ceea ce posezi... Și ce teroare înfrunți... Adevăratul Zeu trebuie să fie liber... Și mă va răsplătii... Voi fi unul...","Я Единый Бог... Я должен высвободить его дух, тогда я смогу покинуть бренную оболочку моего тела и воссоединиться с ним в полёте. Ты и понятия не имеешь, чем обладаешь... и с какому кошмару смотришь в лицо... Единый Бог должен быть освобождён... И он вознаградит меня... Это сделаю я!",,Jag är den ende guden... Jag behöver att hans ande är fri så att jag kan lämna min kropp och ansluta mig till honom i flykten. Du har ingen aning om vad du äger... Och vilken skräck ni står inför... Den ende guden måste vara fri... Och han kommer att belöna mig... Jag kommer att bli en...,"Ben Tek Tanrı'yım. Onun ruhunun özgür olmasına ihtiyacım var, böylece bedenimi terk edebilir ve uçuşta ona katılabilirim. Neye sahip olduğunuz hakkında hiçbir fikriniz yok. Ve nasıl bir dehşetle karşı karşıya olduğunuzu. Tek Tanrı özgür olmalı. Ve o beni ödüllendirecek. Ben bir olacağım." +I will destroy you!,TXT_RPLY0_SCRIPT10_D16676_IWILL,,,,Zničím tě!,Jeg vil ødelægge dig!,Ich werde dich zerstören!,,,¡Te destruiré!,,Tuhoan sinut!,L'heure est venue de vous détruire!,Megsemmisítelek!,Ti distruggerò!,お前を滅ぼす!,당신을 처단하겠어!,Ik zal je vernietigen!,Jeg skal tilintetgjøre deg!,Zniszczę cię!,Eu vou destruir você!,,Te voi distruge!,Я уничтожу тебя!,,Jag ska förgöra dig!,Seni yok edeceğim! +Glad to see you made it. What do you need? ,TXT_DLG_SCRIPT10_D18192_GLADT,MAP10: Gerald (no upgrade).,,,"Jsem rád, žes to zvládnul. Co bys potřeboval?","Godt at se, at du klarede den. Hvad har du brug for?","Gut, dass du es geschafft hast. Was brauchst du?",,,Me alegro de verte de una pieza. ¿Qué necesitas?,,"Hienoa, että selvisit. Mitä tarvitset?",Ravi de voir que vous vous en êtes sorti. Que puis-je faire pour vous?,"Örömmel látom, hogy túlélted. Miben segíthetek?",Lieto di vederti qui. Di che hai bisogno?,お会いできて光栄です。何が必要ですか?,여기까지 오시다니 놀랍군요. 뭔가 필요한 게?,Blij te zien dat je het gehaald hebt. Wat heb je nodig?,Godt å se at du kom. Hva trenger du?,"Dobrze widzieć, że udało ci się. Czego ci potrzeba?",Que bom que você conseguiu. O que você precisa?,,Mă bucur să văd că ai reușit. De ce ai nevoie?,"Я рад, что ты справился. Чем могу помочь?",,Det gläder mig att se att du klarade dig. Vad behöver du?,Gelebilmene sevindim. Neye ihtiyacın var? +Heal me.,TXT_RPLY0_SCRIPT10_D18192_HEALM,〃,,,Potřebuju ošetřit.,Helbrede mig.,Mach mich gesund.,,,Cúrame.,,Hoida minua.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료해주세요.,Genees me.,Helbred meg.,Ulecz mnie.,Me cure.,,Bandajează-mă.,Подлечи меня.,,Laga mig.,İyileştir beni. +"Well, lets get you fixed up.",TXT_RYES0_SCRIPT10_D18192_WELLL,〃,,,"Dobře, tak tě dáme dohromady.","Nå, lad os få dig ordnet.","Gut, das hier sollte helfen.",,,"Bien, vamos a hacerte unos arreglos.",,"Selvä, pistetään sinut kuntoon.","Allez, on va vous remettre sur pied.","Na, akkor pofozzunk helyre.","Molto bene, ti darò una sistemata.",では、すぐ治療しましょう。,그럼 긴급 치료하겠습니다.,"Nou, laten we je opknappen.","Vel, la oss få deg fikset opp.","Dobra, pozbieram cię do kupy.","Ok, vamos dar um jeito em você.",,"Păi, să te aranjăm.","Ну, давай приведём тебя в порядок.",,Vi får fixa till dig.,"Pekala, seni iyileştirelim." +You're fine.,TXT_RNO0_SCRIPT10_D18192_YOURE,〃,,,Jsi v pořádku.,Du har det fint.,Die geht es gut.,,,Estás bien.,,Olet kunnossa.,Vous allez bien.,Rendben is vagy.,Stai bene.,貴方は大丈夫です。,괜찮아 보이는데.,Je bent in orde.,Det går bra med deg.,Jesteś zdrowy.,Você está bem.,,Ești în regulă.,Ты здоров.,,Du är okej.,İyisin. +Anything new?,TXT_RPLY1_SCRIPT10_D18192_ANYTH,〃,,,Něco nového?,Noget nyt?,Irgend etwas Neues?,,,¿Algo nuevo?,,Onko mitään uutta?,Quoi de neuf?,Valami újdonság?,Novità?,何か新しいのは?,특별한 거 없나요?,Iets nieuws?,Noe nytt?,Coś nowego?,Alguma novidade?,,Ceva nou?,Есть что-нибудь новое?,,Något nytt?,Yeni bir şey var mı? +"Yes, I've got some new hardware for you.",TXT_RYES1_SCRIPT10_D18192_YESIV,〃,,,"Ano, mám pro tebe novou mašinku.","Ja, jeg har noget nyt hardware til dig.","Ja, ich habe neue Hardware für dich.",,,"Sí, tengo nuevo hardware para ti.",,"Kyllä, minulla on sinulle uutta rautaa.","Ah, j'ai du nouveau matériel pour vous.","Igen, van pár új fegyverem számodra.","Si, ho delle nuove attrezzature per te.",貴方の為に幾つか新しいハードウェアを見つけました。,네! 사용 가능한 하드웨어가 하나 있습니다.,"Ja, ik heb wat nieuwe hardware voor je.","Ja, jeg har noe nytt utstyr til deg.","Tak, mam dla ciebie nowe oprogramowanie.","Sim, tenho equipamento novo pra você.",,"Da, am ceva hardware nou pentru tine.",Да. Новая аппаратура для тебя.,,"Ja, jag har lite ny hårdvara till dig.","Evet, senin için yeni bir donanımım var." +"Nope, I'm working on it though.",TXT_RNO1_SCRIPT10_D18192_NOPEI,〃,,,"Ne, ale pracuju na tom.","Nej, men jeg arbejder på det.","Nein, ich arbeite noch daran.",,,"No, pero estoy trabajando en ello.",,Ei; on kyllä työn alla.,"Rien, mais j'y travaille.","Nem, de már dolgozom rajta.","No, ma ci sto lavorando.",いえ、只今探しています。,아뇨. 아직 작업 진행 중입니다.,"Nee, maar ik ben er wel mee bezig.","Nei, men jeg jobber med det.","Nie, jeszcze nad tym pracuję.","Não, mas estou trabalhando nisso.",,"Nu, încă lucrez la asta.","Нет, но я работаю над ним.",,"Nej, men jag jobbar på det.","Hayır, üzerinde çalışıyorum." "What can I do for you now? Feris is decrypting some really complex files, but it's all worth it. There's already some information that I'll be able to apply to the next version of the stamina implant.",TXT_DLG_SCRIPT10_D19708_WHATC,〃 (one upgrade),,,"Co pro tebe můžu udělat teď? Feris pracuje na dešifrování hodně složitých souborů, ale bude to stát za to. Už teď máme informace, které budu moct použít v nové verzi tvého implantátu.","Hvad kan jeg gøre for dig nu? Feris er ved at dekryptere nogle virkelig komplekse filer, men det er det hele værd. Der er allerede nogle oplysninger, som jeg vil kunne anvende til den næste version af udholdenhedsimplantatet.","Was kann ich für dich tun? Feris entschlüsselt gerade einige sehr komplexe Dateien, aber es ist den Aufwand wert. Einige dieser Informationen kann ich für die nächste Version deines Implantats anwenden.",,,"¿Qué puedo hacer por ti? Feris está desencriptando unos archivos bastante complejos, pero valdrá la pena. Ya hay algo de información que puedo aplicar a la próxima version del implante de aguante.",,"Miten voin olla avuksi? Feris on purkamassa joidenkin todella monimutkaisten tiedostojen salausta, mutta se on sen vaivan väärti.","Que puis-je faire pour vous? Feris est en train de décrypter des fichiers très complexes, mais ça à l'air d'en valoir la peine. Il y a déjà des informations très intéressantes que l'on va pouvoir utiliser pour la prochaine version de l'implant d'endurance.","Mit tehetek érted most? Feris elég komplex fájlokat próbál épp dekódolni, de ha sikerül meg fogja érni. Már van pár információm, amit fel tudok használni az állóképesség implantátum fejlesztésére.","Che cosa posso fare per te ora? Feris sta decriptando alcuni file molto complessi, ma ne varrà la pena. Abbiamo già delle informazioni che potrò applicare nella prossima versione dell'impianto stamina.","何か御用かい?幾つかの複雑に複合化された フェリスのファイルにはそれだけの価値はあった スタミナインプラントの次期バージョンに @@ -10728,12 +11210,12 @@ dokumenty, ale mówię ci... warto było. Już mamy trochę informacji, które będę mógł wykorzystać w nowszej wersji implantu zwiększającego -wytrzymałość.","Como posso te ajudar no momento? Feris está decriptando uns arquivos bem complexos, mas valerá a pena. Já temos informações que vou poder usar na próxima versão do implante de resistência.",,"Ce pot face pentru tine acum? Feris decriptează niște fișiere extrem de complexe, dar merită. Deja avem niște informații care le voi putea aplica urmatoarei versiuni ale implantului tău pentru rezistență.","Чем я могу тебе помочь? Ферис сейчас расшифровывает файлы Ордена. Это нелегко, но результат стоит того. Я уже получил кое-какие новые данные, которые помогут мне при разработке новой версии твоего импланта.",,Şimdi senin için ne yapabilirim? Feris bazı karmaşık dosyaların şifresini çözüyor ama buna değer. Dayanıklılık implantının bir sonraki versiyonuna uygulayabileceğim bazı bilgiler var. -Heal me.,TXT_RPLY0_SCRIPT10_D19708_HEALM,〃,,,Potřebuju ošetřit.,Helbred mig.,Mach mich gesund.,,Kuracu min.,Cúrame.,,Hoida minua.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료해주세요.,Genees mij.,Helbred meg.,Ulecz mnie.,Me cure.,,Bandajează-mă.,Подлечи меня.,,İyileştir beni. -You should learn to be a little more careful.,TXT_RYES0_SCRIPT10_D19708_YOUSH,〃,,,Měl bys být trochu opatrnější.,Du burde lære at være lidt mere forsigtig.,Du solltest wirklich etwas vorsichtiger sein.,,,Deberías aprender a tener un poco más de cuidado.,,Sinun pitäisi oppia olemaan hieman varovaisempi.,Vous devriez faire plus attention à vous.,Meg kéne tanulnod óvatosabbnak lenni.,Dovresti imparare ad essere un pò più attento.,もう少し慎重にやるべきでは。,몸 간수 잘하시고 싸우세요.,Je moet leren om wat voorzichtiger te zijn.,Du burde lære deg å være litt mer forsiktig.,Powinieneś być bardziej ostrożny.,Você precisa aprender a tomar mais cuidado.,,Ar trebui să fii mai grijuliu.,В следующий раз тебе стоит быть поосторожнее.,,Biraz daha dikkatli olmayı öğrenmelisin. -When will that be ready?,TXT_RPLY1_SCRIPT10_D19708_WHENW,〃,,,Kdy bude hotov?,Hvornår er den klar?,Wann ist es soweit?,,,¿Cuándo estará eso listo?,,Milloin se on valmis?,Quand-est-ce que t'il sera prêt?,Mikor lesz kész?,Quando sarà pronto?,出来ているか?,이식 준비는 다 됐습니까?,Wanneer is dat klaar?,Når er det klart?,Kiedy to będzie gotowe?,Quando isso vai estar pronto?,,Când va fi gata?,Когда он будет готов?,,Ne zaman hazır olacak? -It's ready now. This won't take but a moment.,TXT_RYES1_SCRIPT10_D19708_ITSRE,〃,,,Už je hotový. Nepotrvá to ani chvilku.,Det er klar nu. Det vil kun tage et øjeblik.,"Es ist fertig. Einen kurzen Moment, bitte.",,,Ya está listo. Ésto solo tomará un momento.,,Se on valmis nyt. Tähän ei mene kuin vain hetki.,"Il est déjà prêt, çe ne prendra qu'un moment.","Készen van, csak pár másodperc.",È pronto ora. Ci vorrà solo un momento.,用意出来ている。すぐ終わるさ。,다 됐습니다! 이제 이식을 시작하죠!,Het is nu klaar. Dit duurt niet langer dan een moment.,Det er klart nå. Dette tar bare et øyeblikk.,Już jest gotowe. To zajęło tylko chwilę.,Já está pronto. Isso não vai demorar.,,E gata. Va dura doar un moment.,Уже готово. Это не займёт много времени.,,Şimdi hazır. Bir dakika bile sürmez. -Soon.,TXT_RNO1_SCRIPT10_D19708_SOON,〃,,,Brzy.,Det er snart.,Bald.,,Baldaŭ.,Pronto.,,Pian.,Bientôt.,Hamarosan.,Presto.,間もなくだ。,곧 완성되요.,Binnenkort.,Snart.,Niedługo.,Logo logo.,,Curând.,Скоро.,,Çok yakında. +wytrzymałość.","Como posso te ajudar no momento? Feris está decriptando uns arquivos bem complexos, mas valerá a pena. Já temos informações que vou poder usar na próxima versão do implante de resistência.",,"Ce pot face pentru tine acum? Feris decriptează niște fișiere extrem de complexe, dar merită. Deja avem niște informații care le voi putea aplica urmatoarei versiuni ale implantului tău pentru rezistență.","Чем я могу тебе помочь? Ферис сейчас расшифровывает файлы Ордена. Это нелегко, но результат стоит того. Я уже получил кое-какие новые данные, которые помогут мне при разработке новой версии твоего импланта.",,"Vad kan jag göra för dig nu? Feris dekrypterar några riktigt komplicerade filer, men det är värt det. Det finns redan en del information som jag kommer att kunna tillämpa på nästa version av uthållighetsimplantatet.",Şimdi senin için ne yapabilirim? Feris bazı karmaşık dosyaların şifresini çözüyor ama buna değer. Dayanıklılık implantının bir sonraki versiyonuna uygulayabileceğim bazı bilgiler var. +Heal me.,TXT_RPLY0_SCRIPT10_D19708_HEALM,〃,,,Potřebuju ošetřit.,Helbred mig.,Mach mich gesund.,,Kuracu min.,Cúrame.,,Hoida minua.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료해주세요.,Genees mij.,Helbred meg.,Ulecz mnie.,Me cure.,,Bandajează-mă.,Подлечи меня.,,Laga mig.,İyileştir beni. +You should learn to be a little more careful.,TXT_RYES0_SCRIPT10_D19708_YOUSH,〃,,,Měl bys být trochu opatrnější.,Du burde lære at være lidt mere forsigtig.,Du solltest wirklich etwas vorsichtiger sein.,,,Deberías aprender a tener un poco más de cuidado.,,Sinun pitäisi oppia olemaan hieman varovaisempi.,Vous devriez faire plus attention à vous.,Meg kéne tanulnod óvatosabbnak lenni.,Dovresti imparare ad essere un pò più attento.,もう少し慎重にやるべきでは。,몸 간수 잘하시고 싸우세요.,Je moet leren om wat voorzichtiger te zijn.,Du burde lære deg å være litt mer forsiktig.,Powinieneś być bardziej ostrożny.,Você precisa aprender a tomar mais cuidado.,,Ar trebui să fii mai grijuliu.,В следующий раз тебе стоит быть поосторожнее.,,Du borde lära dig att vara lite mer försiktig.,Biraz daha dikkatli olmayı öğrenmelisin. +When will that be ready?,TXT_RPLY1_SCRIPT10_D19708_WHENW,〃,,,Kdy bude hotov?,Hvornår er den klar?,Wann ist es soweit?,,,¿Cuándo estará eso listo?,,Milloin se on valmis?,Quand-est-ce que t'il sera prêt?,Mikor lesz kész?,Quando sarà pronto?,出来ているか?,이식 준비는 다 됐습니까?,Wanneer is dat klaar?,Når er det klart?,Kiedy to będzie gotowe?,Quando isso vai estar pronto?,,Când va fi gata?,Когда он будет готов?,,När kommer den att vara klar?,Ne zaman hazır olacak? +It's ready now. This won't take but a moment.,TXT_RYES1_SCRIPT10_D19708_ITSRE,〃,,,Už je hotový. Nepotrvá to ani chvilku.,Det er klar nu. Det vil kun tage et øjeblik.,"Es ist fertig. Einen kurzen Moment, bitte.",,,Ya está listo. Ésto solo tomará un momento.,,Se on valmis nyt. Tähän ei mene kuin vain hetki.,"Il est déjà prêt, çe ne prendra qu'un moment.","Készen van, csak pár másodperc.",È pronto ora. Ci vorrà solo un momento.,用意出来ている。すぐ終わるさ。,다 됐습니다! 이제 이식을 시작하죠!,Het is nu klaar. Dit duurt niet langer dan een moment.,Det er klart nå. Dette tar bare et øyeblikk.,Już jest gotowe. To zajęło tylko chwilę.,Já está pronto. Isso não vai demorar.,,E gata. Va dura doar un moment.,Уже готово. Это не займёт много времени.,,Det är klart nu. Det här tar bara ett ögonblick.,Şimdi hazır. Bir dakika bile sürmez. +Soon.,TXT_RNO1_SCRIPT10_D19708_SOON,〃,,,Brzy.,Det er snart.,Bald.,,Baldaŭ.,Pronto.,,Pian.,Bientôt.,Hamarosan.,Presto.,間もなくだ。,곧 완성되요.,Binnenkort.,Snart.,Niedługo.,Logo logo.,,Curând.,Скоро.,,Snart.,Çok yakında. I think I found a glitch in your implant hardware. Feris is helping me design a retrofit that will take care of it and boost the speed of your hardware a little. Is there something I can do for you?,TXT_DLG_SCRIPT10_D21224_ITHIN,,,,"Myslím, že jsem našel vadu v tvém implantátu. Feris mi pomáhá navrhnout doplněk, který se o ni postará a zvýší jeho výkon. Můžu pro tebe něco udělat?","Jeg tror, jeg har fundet en fejl i dit implantathardware. Feris hjælper mig med at designe en eftermontering, der vil løse problemet og øge hastigheden på din hardware en smule. Er der noget, jeg kan gøre for dig?","Ich glaube ich habe eine Fehlfunktion in deinem Implantat gefunden. Feris hilft mir, einen Nachrüstsatz zu bauen und seine Funktion nochmal zu verbessern. Gibt es sonst etwas, das ich für dich tun kann?",,,Creo haber encontrado un defecto en el «hardware» de tu implante. Feris me está ayudando a diseñar una modernización para arreglarlo y aumentarle un poco la velocidad. ¿Hay algo que pueda hacer por ti?,,"Luulen löytäneeni vian istutteesi laitteistossa. Feris auttaa minua kehittämään jälkiasennuskappaleen, joka korjaa vian ja nopeuttaa laitteistoasi vähäsen. Miten voin olla muuten avuksi?",Je crois que j'ai découvert un bug dans votre implant. Feris m'aide à concevoir une mise à jour qui la corrigera et rendra le matériel encore plus rapide. Je peux faire quelque chose pour vous?,"Azt hiszem találtam egy hibát az implantátumban. Feris segít nekem áttervezni, hogy kiküszöböljük a hibát, és kicsit fel is gyorsítsuk a hardvert. Segíthetek valami másban?",Credo di aver trovato un problema nel tuo impianto. Feris mi sta aiutando a creare un ammodernamento che lo sistemerà e migliorerà un poco la velocità del tuo impianto. C'è qualcosa che posso fare per te?,"インプラントハードウェアに不具合が見つかった フェリスがそれを修正してハードウェアの性能を 上げる為の後付け機能を手伝ってくれた。 @@ -10743,13 +11225,13 @@ Feris próbuje mi pomóc stworzyć ulepszenie do niego, które naprawi ten błąd i ulepszy trochę twoją szybkość. Czy coś jeszcze mogę -dla ciebie zrobić?",Acho que encontrei um defeito no seu implante. Feris está me ajudando a desenvolver um aprimoramento que resolverá esse problema e também vai aumentar um pouco a velocidade. Precisa de alguma coisa?,,Cred că am găsit o problemă în implantul tău. Feris mă ajută la implementarea unor îmbunătățiri care vor avea grijă de el și vor crește viteza puțin. E ceva ce pot face pentru tine?,"Кажется, я обнаружил неполадку в устройстве твоего импланта. Ферис помогает мне в разработке модификации, которая исправит её и немного ускорит работу устройства. Чем я могу тебе помочь?",,Sanırım implant donanımında bir hata buldum. Feris bunu halledecek ve donanımınızın hızını biraz artıracak bir güçlendirme tasarlamama yardım ediyor. Senin için yapabileceğim bir şey var mı? -Patch me up.,TXT_RPLY0_SCRIPT10_D21224_PATCH,,,,Potřebuju ošetřit.,Giv mig en besked.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Kasaa minut takaisin kokoon.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Verbind me met elkaar.,Lappe meg sammen.,Opatrz mnie.,Trate meus ferimentos.,,Bandajează-mă.,Подлатай меня.,,Bana yama yap. -"There, as good as new I guess.",TXT_RYES0_SCRIPT10_D21224_THERE,,,,"Tak, a jsi jako nový.","Sådan, så god som ny, tror jeg.","So, fast wie neu, würde ich sagen.",,,"Ya está, como nuevo, supongo.",,"Kas niin, kuin uudenveroinen, luulisin.","Voilà, comme neuf, je crois.","Parancsolj, jobb mint új korában.","Ecco qua, come nuovo.",ほら、新鮮な気分だろう。,"자, 갓 태어난 것처럼 멀쩡할 겁니다!","Daar, zo goed als nieuw denk ik.","Sånn, så god som ny, antar jeg.",Proszę. Jak nowy. Chyba.,"Pronto. Novinho em folha, eu acho.",,"Gata, ca și nou bănuiesc.","Ну вот, прям как новенький.",,"İşte, yeni kadar iyi sanırım." -Retrofit?,TXT_RPLY1_SCRIPT10_D21224_RETRO,,,,Doplněk?,Eftermontering?,Nachrüstsatz?,,,¿Modernización?,,Jälkiasennuskappale?,Mise à jour de l'implant?,Áttervezni?,Ammodernamento?,後付け?,향상 칩 최근 버전?,Retrofit?,Oppgradering?,Ulepszenie?,Aprimoramento?,,Îmbunătățiri?,Модернизация?,,Güçlendirme mi? -"Ah, now we're cooking.",TXT_RYES1_SCRIPT10_D21224_AHNOW,,,,"Ahá, a už to jede.","Ah, nu er vi i gang.","Ah, jetzt bist du bei der Sache.",,,"Ah, ahora sí que sí.",,No nyt päästiin asiaan.,"Ah, on va s'amuser.",Ez a beszéd!,"Ah, ora ci siamo.",ああ、早速取り掛かろう。,이제야 좀 멋져 보이는군요.,"Ah, nu zijn we aan het koken.",Nå er vi i gang.,"Ah, no i to rozumiem.","Ah, agora sim.",,"Ah, acum discutăm.",Да. Мы славно поработали над ней.,,İşte şimdi pişiyoruz. +dla ciebie zrobić?",Acho que encontrei um defeito no seu implante. Feris está me ajudando a desenvolver um aprimoramento que resolverá esse problema e também vai aumentar um pouco a velocidade. Precisa de alguma coisa?,,Cred că am găsit o problemă în implantul tău. Feris mă ajută la implementarea unor îmbunătățiri care vor avea grijă de el și vor crește viteza puțin. E ceva ce pot face pentru tine?,"Кажется, я обнаружил неполадку в устройстве твоего импланта. Ферис помогает мне в разработке модификации, которая исправит её и немного ускорит работу устройства. Чем я могу тебе помочь?",,Jag tror att jag har hittat ett glapp i din implantathårdvara. Feris hjälper mig att utforma en eftermontering som kommer att ta hand om det och öka hastigheten på din hårdvara lite. Finns det något jag kan göra för dig?,Sanırım implant donanımında bir hata buldum. Feris bunu halledecek ve donanımınızın hızını biraz artıracak bir güçlendirme tasarlamama yardım ediyor. Senin için yapabileceğim bir şey var mı? +Patch me up.,TXT_RPLY0_SCRIPT10_D21224_PATCH,,,,Potřebuju ošetřit.,Giv mig en besked.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Kasaa minut takaisin kokoon.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Verbind me met elkaar.,Lappe meg sammen.,Opatrz mnie.,Trate meus ferimentos.,,Bandajează-mă.,Подлатай меня.,,Laga mig.,Bana yama yap. +"There, as good as new I guess.",TXT_RYES0_SCRIPT10_D21224_THERE,,,,"Tak, a jsi jako nový.","Sådan, så god som ny, tror jeg.","So, fast wie neu, würde ich sagen.",,,"Ya está, como nuevo, supongo.",,"Kas niin, kuin uudenveroinen, luulisin.","Voilà, comme neuf, je crois.","Parancsolj, jobb mint új korában.","Ecco qua, come nuovo.",ほら、新鮮な気分だろう。,"자, 갓 태어난 것처럼 멀쩡할 겁니다!","Daar, zo goed als nieuw denk ik.","Sånn, så god som ny, antar jeg.",Proszę. Jak nowy. Chyba.,"Pronto. Novinho em folha, eu acho.",,"Gata, ca și nou bănuiesc.","Ну вот, прям как новенький.",,"Så där, så gott som ny antar jag.","İşte, yeni kadar iyi sanırım." +Retrofit?,TXT_RPLY1_SCRIPT10_D21224_RETRO,,,,Doplněk?,Eftermontering?,Nachrüstsatz?,,,¿Modernización?,,Jälkiasennuskappale?,Mise à jour de l'implant?,Áttervezni?,Ammodernamento?,後付け?,향상 칩 최근 버전?,Retrofit?,Oppgradering?,Ulepszenie?,Aprimoramento?,,Îmbunătățiri?,Модернизация?,,Eftermontering?,Güçlendirme mi? +"Ah, now we're cooking.",TXT_RYES1_SCRIPT10_D21224_AHNOW,,,,"Ahá, a už to jede.","Ah, nu er vi i gang.","Ah, jetzt bist du bei der Sache.",,,"Ah, ahora sí que sí.",,No nyt päästiin asiaan.,"Ah, on va s'amuser.",Ez a beszéd!,"Ah, ora ci siamo.",ああ、早速取り掛かろう。,이제야 좀 멋져 보이는군요.,"Ah, nu zijn we aan het koken.",Nå er vi i gang.,"Ah, no i to rozumiem.","Ah, agora sim.",,"Ah, acum discutăm.",Да. Мы славно поработали над ней.,,"Ah, nu börjar det bli spännande.",İşte şimdi pişiyoruz. I'll have it as soon as Feris finishes it.,TXT_RNO1_SCRIPT10_D21224_ILLHA,,,,"Budu ho mít hned, co ho Feris dokončí.","Jeg får den, så snart Feris er færdig.","Ich gebe es dir, sobald Feris fertig ist.",,,"La tendré lista en cuanto -Feris la termine.",,"Asennan sen heti, kun Feris saa sen valmiiksi.",Je l'aurai dès que Feris l'a terminée.,"Meglesz egyből, amikor Feris végez vele.",Te lo farò avere non appena Feris lo finisce.,完了次第フェリスから私が送ろう。,페리스가 작업을 마치는 순간 보여드리겠습니다.,Ik heb het zodra Feris het klaar heeft.,Jeg får den så snart Feris er ferdig.,Będzie gotowe jak Feris je skończy.,Eu consigo ele assim que o Feris terminar.,,Îl voi avea imediat ce termină Feris cu el.,"Она будет у меня, как только Ферис закончит.",,Feris bitirir bitirmez getireceğim. +Feris la termine.",,"Asennan sen heti, kun Feris saa sen valmiiksi.",Je l'aurai dès que Feris l'a terminée.,"Meglesz egyből, amikor Feris végez vele.",Te lo farò avere non appena Feris lo finisce.,完了次第フェリスから私が送ろう。,페리스가 작업을 마치는 순간 보여드리겠습니다.,Ik heb het zodra Feris het klaar heeft.,Jeg får den så snart Feris er ferdig.,Będzie gotowe jak Feris je skończy.,Eu consigo ele assim que o Feris terminar.,,Îl voi avea imediat ce termină Feris cu el.,"Она будет у меня, как только Ферис закончит.",,Jag har den så snart Feris är klar.,Feris bitirir bitirmez getireceğim. "How's it going? Man, some of this new technology is simply amazing. This should also help with your implant. I've got a couple ideas that I'm sketching out and I'll have them ready soon. What can I do for you, maybe some healing?",TXT_DLG_SCRIPT10_D22740_HOWSI,,,,"Jak se vede? Sakra, některé tychle nové technologie jsou prostě úžasné. Mělo by ti to taky pomoct s tvým implantátem. Mám už pár nápadů, teď je dávám na papír a brzy by měly být hotové. Co pro tebe mohu udělat, nějaké ošetření?","Hvordan går det? Mand, noget af denne nye teknologi er simpelthen fantastisk. Det burde også hjælpe med dit implantat. Jeg har et par idéer, som jeg skitserer, og jeg har dem snart klar. Hvad kan jeg gøre for dig? Måske noget healing?","Wie läuft es? Mann, einiges von dieser Technologie ist einfach erstaunlich. Da sollte auch mit deinem Implantat helfen. Ich habe da schon einige Ideen, die ich noch ausarbeiten muss, aber sie werden bald fertig sein. Was kann ich sonst für dich tun?",,,"¿Cómo te va? Tío, algunas de estas nuevas tecnologías son realmente sorprendentes. Esto debería ayudar con tu implante. Tengo unas cuantas ideas que voy planeando y las tendré listas pronto. ¿Qué puedo hacer por ti?, ¿tal vez una cura?","¿Cómo te va? Hombre, algunas de estas nuevas tecnologías son realmente sorprendentes. Esto debería ayudar con tu implante. Tengo unas cuantas ideas que voy planeando y las tendré listas pronto. ¿Qué puedo hacer por ti?, ¿tal vez una curación?","Kuinka sujuu? Ei hitsi, osa tästä uudesta teknologiasta on yksinkertaisesti hämmästyttävää. Sen pitäisi auttaa myös istutteesi kanssa. Luonnostelen tässä paria ideaa, jotka saan toteutettua pian. Mutta, miten voisin olla avuksi; sairaanhoidon tarpeessa kenties?","Comment ça va? La vache, cete nouvelle technologie est simplement géniale. Elle devrait également aider pour le dévelopment de votre implant. J'ai quelques idées que je suis en train de tester et elles devraient être bientôt prêtes. Que puis-je faire pour vous? Des soins, peut être?","Hogy ityeg? Némely új technológia egyszerűen csodálatos. Ez kicsit feljavítja az implantátumodat is ha minden igaz. Van pár ötletem amit még most jegyzetelek ki, de hamarosan meglesz. Node mit tehetek érted, esetleg valami gyógyítás?","Come ti va? Te lo devo dire, alcune di queste nuove tecnologie sono semplicemente fantastiche. Questo dovrebbe anche aiutarti con il tuo impianto. Ho un paio di idee che sto elaborando e dovrei averle pronte presto. Cosa posso fare nel frattempo, hai bisogno di cure?","調子はどうだ?この新技術は素晴らしいものだ。 そちらのインプラントにも役立つ様な アイディアも幾つか思いついてあるぞ。 @@ -10759,12 +11241,12 @@ To powinno poprawić twój implant. Mam parę pomysłów w zanadrzu i niedługo postaram się je zrealizować. Co mogę dla ciebie zrobić? Może -trochę podleczyć?","Qual é a boa? Cara, essa tecnologia nova é simplesmente incrível. Isto também deve ajudar com o seu implante. Estou projetando umas idéias novas e logo mais devo ter elas prontas. Precisa de alguma coisa? Talvez cura?",,"Cum merge? Frate, noua tehnologie e pur și simplu uimitoare. Asta ar trebui să îți ajute și implantul. Am câteva idei pe hârtie și le voi pune în aplicare curând. Ce pot face pentru tine, poate să te bandajez?","Как дела? О, среди этих новых технологий есть просто изумительные! Их можно применить при усовершенствовании твоего импланта. Я сейчас воплощаю в жизнь парочку идей, и скоро всё будет готово. Чем я могу тебе помочь, лечением?",,"Nasıl gidiyor? Dostum, bu yeni teknolojinin bazıları tek kelimeyle inanılmaz. Bu implantına da yardımcı olacaktır. Taslağını çizdiğim birkaç fikir var, yakında hazır ederim. Senin için ne yapabilirim, belki biraz şifa?" -"Yes, heal me.",TXT_RPLY0_SCRIPT10_D22740_YESHE,,,,"Ano, ošetři mě.","Ja, helbrede mig.","Ja, mach mich gesund.",,,"Sí, cúrame.",,"Kyllä, paranna minut.","Oui, soignez-moi.","Igen, gyógyíts fel.","Sì, curami.",ああ、治してくれ。,네. 치료해주세요.,"Ja, genees me.","Ja, helbrede meg.","Tak, ulecz mnie.","Sim, me cure.",,"Da, bandajează-mă.","Да, полечи меня.",,"Evet, iyileştir beni." -"All right, here you go.",TXT_RYES0_SCRIPT10_D22740_ALLRI,,,,"Dobře, to by bylo.","Okay, værsgo.",Alles klar soweit.,,,"Muy bien, ya está.",,"Hyvä on, tästä se lähtee.","Très bien, bous pouvez y aller.","Rendben, parancsolj.","Va bene, ecco fatto.",了解、始めましょう。,더욱 더 건강하게 치료했습니다.,"Oké, alsjeblieft.","Greit, vær så god.",Proszę bardzo.,"Ok, pronto.",,Gata.,Хорошо. Уже готово.,,"Pekala, al bakalım." -How about that new tech?,TXT_RPLY1_SCRIPT10_D22740_HOWAB,,,,Co ta nová technologie?,Hvad med den nye teknologi?,Was ist mit der neuen Technologie?,,,¿Qué tal la nueva tecnología?,,Miten olisi se uusi teknologia?,Quoi de nouveau pour cette technologie?,Mi újság azzal az új technológiával?,E riguardo queste nuove technologie?,その新しい技術はどうだ?,세계 제일의 부품은 어떻습니까?,Hoe zit het met die nieuwe technologie?,Hva med den nye teknologien?,Co z tymi nowymi technologiami?,Me fale sobre essa nova tecnologia.,,Ce zici de tehnologia aceea nouă?,Как там с новыми технологиями?,,Şu yeni teknolojiye ne dersin? -Let me know how this works.,TXT_RYES1_SCRIPT10_D22740_LETME,,,,"Dej mi vědět, jak to funguje.","Lad mig vide, hvordan den virker.","Erklär mir, wie es funktioniert.",,,Cuéntame que tal funciona.,,"Kerro sitten, miten se toimii.",Dites-moi si ça fonctionne.,"Majd mondd meg, hogy hogyan szuperál.",Fammi sapere come funziona.,これでどんな調子か教えてくれ。,잘 작동되면 알려주시길!,Laat me weten hoe dit werkt.,Fortell meg hvordan den virker.,Daj znać czy działa.,Me conte como funciona.,,Să-mi spui cum funcționează asta.,"Дай мне знать, если будут неполадки.",,Nasıl çalıştığını bana anlat. -I'm not done designing it yet.,TXT_RNO1_SCRIPT10_D22740_IMNOT,,,,Ještě s ní nejsem hotový.,Jeg er ikke færdig med at designe den endnu.,Ich bin noch nicht fertig damit.,,,Aún no he terminado de diseñarla.,,Se on vielä kehitteillä.,Je n'ai pas fini mon concept pour l'instant.,Még nem végeztem a tervezéssel.,Non ho ancora finito il progetto.,まだ完成していない。,설계가 아직 끝나지 않았어요.,Ik ben nog niet klaar met het ontwerpen ervan.,Jeg er ikke ferdig med å designe den ennå.,Skończyłem już projektować.,Ainda não terminei de desenvolvê-la.,,Încă nu am terminat să o construiesc.,Я ещё не закончил с ними.,,Henüz tasarlamayı bitirmedim. +trochę podleczyć?","Qual é a boa? Cara, essa tecnologia nova é simplesmente incrível. Isto também deve ajudar com o seu implante. Estou projetando umas idéias novas e logo mais devo ter elas prontas. Precisa de alguma coisa? Talvez cura?",,"Cum merge? Frate, noua tehnologie e pur și simplu uimitoare. Asta ar trebui să îți ajute și implantul. Am câteva idei pe hârtie și le voi pune în aplicare curând. Ce pot face pentru tine, poate să te bandajez?","Как дела? О, среди этих новых технологий есть просто изумительные! Их можно применить при усовершенствовании твоего импланта. Я сейчас воплощаю в жизнь парочку идей, и скоро всё будет готово. Чем я могу тебе помочь, лечением?",,"Hur går det? En del av den här nya tekniken är helt enkelt fantastisk. Det här borde också hjälpa dig med ditt implantat. Jag har några idéer som jag skissar på och jag har dem klara snart. Vad kan jag göra för dig, kanske lite healing?","Nasıl gidiyor? Dostum, bu yeni teknolojinin bazıları tek kelimeyle inanılmaz. Bu implantına da yardımcı olacaktır. Taslağını çizdiğim birkaç fikir var, yakında hazır ederim. Senin için ne yapabilirim, belki biraz şifa?" +"Yes, heal me.",TXT_RPLY0_SCRIPT10_D22740_YESHE,,,,"Ano, ošetři mě.","Ja, helbrede mig.","Ja, mach mich gesund.",,,"Sí, cúrame.",,"Kyllä, paranna minut.","Oui, soignez-moi.","Igen, gyógyíts fel.","Sì, curami.",ああ、治してくれ。,네. 치료해주세요.,"Ja, genees me.","Ja, helbrede meg.","Tak, ulecz mnie.","Sim, me cure.",,"Da, bandajează-mă.","Да, полечи меня.",,"Ja, bota mig.","Evet, iyileştir beni." +"All right, here you go.",TXT_RYES0_SCRIPT10_D22740_ALLRI,,,,"Dobře, to by bylo.","Okay, værsgo.",Alles klar soweit.,,,"Muy bien, ya está.",,"Hyvä on, tästä se lähtee.","Très bien, bous pouvez y aller.","Rendben, parancsolj.","Va bene, ecco fatto.",了解、始めましょう。,더욱 더 건강하게 치료했습니다.,"Oké, alsjeblieft.","Greit, vær så god.",Proszę bardzo.,"Ok, pronto.",,Gata.,Хорошо. Уже готово.,,"Okej, varsågod.","Pekala, al bakalım." +How about that new tech?,TXT_RPLY1_SCRIPT10_D22740_HOWAB,,,,Co ta nová technologie?,Hvad med den nye teknologi?,Was ist mit der neuen Technologie?,,,¿Qué tal la nueva tecnología?,,Miten olisi se uusi teknologia?,Quoi de nouveau pour cette technologie?,Mi újság azzal az új technológiával?,E riguardo queste nuove technologie?,その新しい技術はどうだ?,세계 제일의 부품은 어떻습니까?,Hoe zit het met die nieuwe technologie?,Hva med den nye teknologien?,Co z tymi nowymi technologiami?,Me fale sobre essa nova tecnologia.,,Ce zici de tehnologia aceea nouă?,Как там с новыми технологиями?,,Vad sägs om den nya tekniken?,Şu yeni teknolojiye ne dersin? +Let me know how this works.,TXT_RYES1_SCRIPT10_D22740_LETME,,,,"Dej mi vědět, jak to funguje.","Lad mig vide, hvordan den virker.","Erklär mir, wie es funktioniert.",,,Cuéntame que tal funciona.,,"Kerro sitten, miten se toimii.",Dites-moi si ça fonctionne.,"Majd mondd meg, hogy hogyan szuperál.",Fammi sapere come funziona.,これでどんな調子か教えてくれ。,잘 작동되면 알려주시길!,Laat me weten hoe dit werkt.,Fortell meg hvordan den virker.,Daj znać czy działa.,Me conte como funciona.,,Să-mi spui cum funcționează asta.,"Дай мне знать, если будут неполадки.",,Låt mig veta hur den fungerar.,Nasıl çalıştığını bana anlat. +I'm not done designing it yet.,TXT_RNO1_SCRIPT10_D22740_IMNOT,,,,Ještě s ní nejsem hotový.,Jeg er ikke færdig med at designe den endnu.,Ich bin noch nicht fertig damit.,,,Aún no he terminado de diseñarla.,,Se on vielä kehitteillä.,Je n'ai pas fini mon concept pour l'instant.,Még nem végeztem a tervezéssel.,Non ho ancora finito il progetto.,まだ完成していない。,설계가 아직 끝나지 않았어요.,Ik ben nog niet klaar met het ontwerpen ervan.,Jeg er ikke ferdig med å designe den ennå.,Skończyłem już projektować.,Ainda não terminei de desenvolvê-la.,,Încă nu am terminat să o construiesc.,Я ещё не закончил с ними.,,Jag är inte klar med designen än.,Henüz tasarlamayı bitirmedim. "Back again, don't you ever tire of this? I've got some good news, Feris found a way to increase the output of your implant. He gave the specs to me and I'm trying to get it to blend with your physiology. I'm force growing some tissue, totally new stuff here, I hope it takes. Do you need healing?",TXT_DLG_SCRIPT10_D24256_BACKA,,,,"Zase zpátky, nezmáhá tě to? Mám pro tebe dobrou zprávu, Feris našel způsob, jak zvýšit výkon tvého implantátu. Dal mi specifikace a snažím se je teď seřídit s tvou fyziologií. Nechávám růst nějaké tkáně, je to úplně nová technologie, snad to zabere. Potřebuješ ošetřit?","Tilbage igen, bliver du aldrig træt af det her? Jeg har gode nyheder. Feris har fundet en måde at øge dit implantats effekt på. Han gav mig specifikationerne, og jeg forsøger at få det til at passe ind i din fysiologi. Jeg tvinger noget væv til at vokse, helt nye ting her, jeg håber, det virker. Har du brug for healing?","Schon wieder zurück, wird das nicht langweilig? Ivh habe gute Nachrichten. Feris hat eine Methode gefunden, um dein Implantat zu optimieren. Er hat mir die Spezifikationen gegeben und ich versuche, sie mit deiner Physiologie zu kombinieren. Ich lasse hier etwas Gewebe wachsen, völlig neues Zeug. Brauchst du medizinische Versorgung?",,,"¿De vuelta otra vez?, ¿nunca te cansas de esto? Tengo buenas noticias, Feris ha encontrado una forma de potenciar la salida de tu implante. Me ha dado las especificaciones y estoy intentando que se mezcle con tu fisiología. Estoy forzando el crecimiento de algunos tejidos, totalmente nuevos, espero que sirva. ¿Necesitas una cura?",,"Täällä taas? Eikö tämä ala jo kyllästyttää? No, minulla on hyviä uutisia: Feris keksi keinon parantaa istutteesi tehoa. Hän antoi minulle tekniset määritelmät, jotka yritän sovittaa sinun fysiologiaasi. Tehokasvatan tässä vähän kudosta; ihan huipputekniikasta siis kyse. Toivottavasti toimii. Tarvitsetko sairaanhoitoa?","Déjà de retour? Vous n'êtes jamais fatigué, hein? J'ai de bonnes nouvelles. Feris à trouvé un moyen d'augementer la capacité de votre implant. Il m'a donné les spécifications et j'essaie de les faire correspondre à votre physiologie. Je suis en train de forcer la croissance de tissus, quelque chose de totalement nouveau. J'espère que ça fonctionnera. Vous avez besoin de soins?","Máris visszajöttél...nem fáradtál még bele? Van amúgy jó hírem, Feris kitalálta, hogyan növeljük az implantátum hatékonyságát. Ide adta a specifikációkat, és most próbálom a testformádra szabni. Épp próbálok mesterségesen szövetet növeszteni, elég új ez nekem, remélem működni fog. Kell valami gyógyítás?","Di nuovo qua, non ti stanchi mai? Ho delle buone notizie, Feris ha trovato un modo per migliorare la performance del tuo impianto. Mi ha dato le schematiche, adesso devo adattarle alla tua fisiologia. Sto creando del nuovo tessuto qua nel laboratorio, spero vada bene. Comunque, hai bisogno di cure?","戻ったか、まだ疲れてないか?なら幾らか 良いニュースが届いた、フェリスが君の インプラント機能を増幅させる方法を見つけた。 @@ -10779,12 +11261,12 @@ staram się dostosować go do twojej fizjologii. Wymuszam tworzenie nowej tkanki. To zupełnie nowa technologia. Mam nadzieję, że -zadziała. Potrzebujesz leczenia?","De volta mais uma vez. Você não se cansa disso? Tenho boas novas, Feris acho um jeito de aumentar o rendimento do seu implante. Ele me passou as especificações e estou tentando fazer ele se mesclar com a sua fisiologia. Estou criando tecidos novos, novidade total. Espero que sirva bem. Precisa de cura?",,"Te-ai întors din nou, nu te plictisești niciodată? Am niște vești bune, Feris a descoperit o metodă de a îți îmbunătății implantul. Mi-a dat specificațiile și acum încerc să îl combin cu fizicul tău. Cresc forțat niște țesut, ceva complet nou. Ai nevoie de asistență?","Ты снова ранен? Тебе самому ещё не надоело? У меня для тебя хорошие новости: Ферис нашёл способ увеличить эффективность твоего импланта. Он дал мне схемы, и я пытаюсь подогнать имплант под твою физиологию. Я сейчас выращиваю кое-какие ткани. Раньше я никогда этого не делал, но надеюсь, что это сработает. Итак, тебе нужно лечение?",,"Yine başladık, bundan hiç bıkmadın mı? İyi haberlerim var. Feris implantının gücünü arttırmanın bir yolunu buldu. Özellikleri bana verdi ve ben de senin fizyolojinle uyumlu hale getirmeye çalışıyorum. Biraz doku büyütmeye zorluyorum, tamamen yeni şeyler, umarım tutar. İyileşmeye ihtiyacın var mı?" -"Yes, heal me.",TXT_RPLY0_SCRIPT10_D24256_YESHE,,,,"Ano, ošetři mě.","Ja, helbrede mig.","Ja, mach mich gesund.",,,"Sí, cúrame.",,"Kyllä, paranna minut.","Oui, soignez-moi.","Igen, gyógyíts fel.","Sì, curami.",ああ、治してくれ。,네. 치료해주세요.,"Ja, genees me.","Ja, helbred meg.","Tak, ulecz mnie.","Sim, me cure.",,"Da, bandajează-mă.","Да, полечи меня.",,"Evet, iyileştir beni." -"Done, now take care of yourself.",TXT_RYES0_SCRIPT10_D24256_DONEN,,,,"Hotovo, dávej na sebe pozor.",Færdig. Pas nu på dig selv.,"Alles klar, und nun pass auf dich auf.",,,"Hecho, ahora ve con cuidado.",,Noin. Pidä itsestäsi huoli.,"Fini, faites attention à vous.","Kész is, vigyázz magadra.","Fatto, abbi cura di te.",完了した、御気を付けて。,치료 끝. 이제 가까이서 불장난하지 마시길!,"Klaar, zorg nu voor jezelf.","Ferdig, ta vare på deg selv.",Gotowe. Uważaj na siebie.,Pronto. Agora vê se toma cuidado.,,"Gata, acum ai grijă de tine.",Сделано. Береги себя.,,"Bitti, şimdi kendine iyi bak." -When will you be done?,TXT_RPLY1_SCRIPT10_D24256_WHENW,,,,Kdy s tím budeš hotov?,Hvornår er du færdig?,Wann wird es fertig sein?,,,¿Cuándo habrás terminado?,,Milloin kudos on valmis?,Quand aurez-vous fini?,Mikor leszel kész?,Quando avrai finito?,いつ増幅できる?,칩 조정이 언제 끝나는지요?,Wanneer ben je klaar?,Når er du ferdig?,Kiedy skończysz?,Quando você vai terminar?,,Când vei fi gata?,Когда он будет готов?,,İşin ne zaman bitecek? -"Now. Hey great, it worked!",TXT_RYES1_SCRIPT10_D24256_NOWHE,,,,"Teď. No ne, funguje to skvěle!","Når du er færdig? Nu. Hej, godt, det virkede!","Oh, klasse. Es funktioniert.",,,"Ahora. Mira que bien, ¡Ha funcionado!",,"Nyt. Hei, sehän toimii; hienoa!","Maintenant. Hé, super, ça à fonctionné!","Épp most. Marha jó, működik!","Adesso. Ehi, fantastico, ha funzionato!",すぐにでも。素晴らしい、上手くいった!,"세상에나, 정말로 작동하는군요!","Nu. Hé, geweldig, het heeft gewerkt!","Nå. Flott, det virket!",Już. Hej! Udało się! Działa!,"Agora. Opa, beleza! Funcionou!",,"Acum. Hei grozav, a mers!","Секунду. Отлично, он работает!",,"Şimdi. Hey harika, işe yaradı!" -I'm waiting on the tissue to finish its growth cycle.,TXT_RNO1_SCRIPT10_D24256_IMWAI,,,,"Čekám, než dorostou ty tkáně.","Jeg venter på, at vævet afslutter sin vækstcyklus.","Ich muss warten, bis das Gewebe fertig gewachsen ist. ",,,Estoy esperando a que los tejidos terminen su ciclo de desarrollo.,,Odotan kudoksen kasvusyklin päättymistä.,J'attends que le tissu ait fini son cycle de croissance.,"Épp arra várok, hogy a szövet a növekedési ütemet elérje.",Sto aspettando che i tessuti finiscano la crescita per questo ciclo.,生体組織が成長しきるまで待つんだ。,조직이 다 자라날 때까지 기다리는 중입니다.,Ik wacht op het weefsel om de groeicyclus af te ronden.,Jeg venter på at vevet skal fullføre vekstsyklusen.,Czekam aż cykl odrastania tkanki się skończy.,Estou esperando que o tecido termine seu ciclo de desenvolvimento.,,Aștept ca țesutul să își continue ciclul de dezvoltare.,Подожди. Я жду коца цикла роста клеток ткани.,,Dokunun büyüme döngüsünü tamamlamasını bekliyorum. +zadziała. Potrzebujesz leczenia?","De volta mais uma vez. Você não se cansa disso? Tenho boas novas, Feris acho um jeito de aumentar o rendimento do seu implante. Ele me passou as especificações e estou tentando fazer ele se mesclar com a sua fisiologia. Estou criando tecidos novos, novidade total. Espero que sirva bem. Precisa de cura?",,"Te-ai întors din nou, nu te plictisești niciodată? Am niște vești bune, Feris a descoperit o metodă de a îți îmbunătății implantul. Mi-a dat specificațiile și acum încerc să îl combin cu fizicul tău. Cresc forțat niște țesut, ceva complet nou. Ai nevoie de asistență?","Ты снова ранен? Тебе самому ещё не надоело? У меня для тебя хорошие новости: Ферис нашёл способ увеличить эффективность твоего импланта. Он дал мне схемы, и я пытаюсь подогнать имплант под твою физиологию. Я сейчас выращиваю кое-какие ткани. Раньше я никогда этого не делал, но надеюсь, что это сработает. Итак, тебе нужно лечение?",,"Tillbaka igen, tröttnar du aldrig på det här? Jag har goda nyheter, Feris har hittat ett sätt att öka effekten av ditt implantat. Han gav specifikationerna till mig och jag försöker få det att smälta in i din fysiologi. Jag tvångsodlar lite vävnad, helt nya saker här, jag hoppas att det fungerar. Behöver du läkning?","Yine başladık, bundan hiç bıkmadın mı? İyi haberlerim var. Feris implantının gücünü arttırmanın bir yolunu buldu. Özellikleri bana verdi ve ben de senin fizyolojinle uyumlu hale getirmeye çalışıyorum. Biraz doku büyütmeye zorluyorum, tamamen yeni şeyler, umarım tutar. İyileşmeye ihtiyacın var mı?" +"Yes, heal me.",TXT_RPLY0_SCRIPT10_D24256_YESHE,,,,"Ano, ošetři mě.","Ja, helbrede mig.","Ja, mach mich gesund.",,,"Sí, cúrame.",,"Kyllä, paranna minut.","Oui, soignez-moi.","Igen, gyógyíts fel.","Sì, curami.",ああ、治してくれ。,네. 치료해주세요.,"Ja, genees me.","Ja, helbred meg.","Tak, ulecz mnie.","Sim, me cure.",,"Da, bandajează-mă.","Да, полечи меня.",,"Ja, bota mig.","Evet, iyileştir beni." +"Done, now take care of yourself.",TXT_RYES0_SCRIPT10_D24256_DONEN,,,,"Hotovo, dávej na sebe pozor.",Færdig. Pas nu på dig selv.,"Alles klar, und nun pass auf dich auf.",,,"Hecho, ahora ve con cuidado.",,Noin. Pidä itsestäsi huoli.,"Fini, faites attention à vous.","Kész is, vigyázz magadra.","Fatto, abbi cura di te.",完了した、御気を付けて。,치료 끝. 이제 가까이서 불장난하지 마시길!,"Klaar, zorg nu voor jezelf.","Ferdig, ta vare på deg selv.",Gotowe. Uważaj na siebie.,Pronto. Agora vê se toma cuidado.,,"Gata, acum ai grijă de tine.",Сделано. Береги себя.,,"Klart, ta hand om dig själv nu.","Bitti, şimdi kendine iyi bak." +When will you be done?,TXT_RPLY1_SCRIPT10_D24256_WHENW,,,,Kdy s tím budeš hotov?,Hvornår er du færdig?,Wann wird es fertig sein?,,,¿Cuándo habrás terminado?,,Milloin kudos on valmis?,Quand aurez-vous fini?,Mikor leszel kész?,Quando avrai finito?,いつ増幅できる?,칩 조정이 언제 끝나는지요?,Wanneer ben je klaar?,Når er du ferdig?,Kiedy skończysz?,Quando você vai terminar?,,Când vei fi gata?,Когда он будет готов?,,När är du klar?,İşin ne zaman bitecek? +"Now. Hey great, it worked!",TXT_RYES1_SCRIPT10_D24256_NOWHE,,,,"Teď. No ne, funguje to skvěle!","Når du er færdig? Nu. Hej, godt, det virkede!","Oh, klasse. Es funktioniert.",,,"Ahora. Mira que bien, ¡Ha funcionado!",,"Nyt. Hei, sehän toimii; hienoa!","Maintenant. Hé, super, ça à fonctionné!","Épp most. Marha jó, működik!","Adesso. Ehi, fantastico, ha funzionato!",すぐにでも。素晴らしい、上手くいった!,"세상에나, 정말로 작동하는군요!","Nu. Hé, geweldig, het heeft gewerkt!","Nå. Flott, det virket!",Już. Hej! Udało się! Działa!,"Agora. Opa, beleza! Funcionou!",,"Acum. Hei grozav, a mers!","Секунду. Отлично, он работает!",,"Nu. Bra, det fungerade!","Şimdi. Hey harika, işe yaradı!" +I'm waiting on the tissue to finish its growth cycle.,TXT_RNO1_SCRIPT10_D24256_IMWAI,,,,"Čekám, než dorostou ty tkáně.","Jeg venter på, at vævet afslutter sin vækstcyklus.","Ich muss warten, bis das Gewebe fertig gewachsen ist. ",,,Estoy esperando a que los tejidos terminen su ciclo de desarrollo.,,Odotan kudoksen kasvusyklin päättymistä.,J'attends que le tissu ait fini son cycle de croissance.,"Épp arra várok, hogy a szövet a növekedési ütemet elérje.",Sto aspettando che i tessuti finiscano la crescita per questo ciclo.,生体組織が成長しきるまで待つんだ。,조직이 다 자라날 때까지 기다리는 중입니다.,Ik wacht op het weefsel om de groeicyclus af te ronden.,Jeg venter på at vevet skal fullføre vekstsyklusen.,Czekam aż cykl odrastania tkanki się skończy.,Estou esperando que o tecido termine seu ciclo de desenvolvimento.,,Aștept ca țesutul să își continue ciclul de dezvoltare.,Подожди. Я жду коца цикла роста клеток ткани.,,Jag väntar på att vävnaden ska avsluta sin tillväxtcykel.,Dokunun büyüme döngüsünü tamamlamasını bekliyorum. "Well, I'm back up to my old tricks again, I'm still working on your implants. Did you know that Macil has now authorized them for everyone? No, huh? It's because you turned out so well. Anything I can do for you?",TXT_DLG_SCRIPT10_D25772_WELLI,,,,"Zase dělám to, co mi jde nejlépe, pracuju na tvých implantátech. Slyšel jsi, že Macil povolil jejich použití na všech vojácích? Ne? Je to protože u tebe fungují tak dobře. Můžu pro tebe něco udělat?","Nå, jeg er tilbage til mine gamle tricks igen, jeg arbejder stadig på dine implantater. Vidste du, at Macil nu har godkendt dem til alle? Nej, hva'? Det er fordi du blev så godt. Er der noget, jeg kan gøre for dig?","Ich arbeite immer noch an deinem Implantat. Wußtest du schon, dass Macil sie für alle autorisiert hat? Nein, was? Hat er getan, weil es bei dir so gut funktioniert hat. Kann ich sonst was für dich tun?",,,"Bueno, vuelvo a las andadas otra vez, sigo trabajando en tus implantes. ¿Sabías que Macil ahora los ha autorizado para todos? No, ¿eh? Es por lo bien que te ha salido. ¿Algo que pueda hacer por ti?",,"Olen taas palannut kyhäilyjeni pariin; työstän edelleenkin istutteitasi. Tiesitkö muuten, että Macil on valtuuttanut ne nyt kaikille? Ai et? No, ihan sen takia, kun sinä satuit onnistumaan niin hyvin. Mutta, mitä saisi olla?","Eh bien, je suis de retour à mes vieux violons, je suis toujours en train de travailler sur vos implants. Vous saviez que Macil les a autorisé pour tous les soldats? Non, hein? C'est parce que vous vous en êtes tellement bien sorti. Que puis-je faire pour vous?","Visszatértem a régi kerékvágásba, és újból fejlesztgetem az implantátumodat. Tudtad, hogy Macil mindenki számára engedélyezte őket? Nem, mi? Azért mert a Te esetedben nagyon jól bevállt. Segíthetek még neked valamiben?","Ebbene, sono di nuovo alle prese con questi impianti, inclusi i tuoi. Lo sapevi che Macil adesso li ha autorizzati per tutti? No, eh? È poiché sei venuto fuori così bene. Posso fare qualcosa per te?","さて、私は古い技術をバックアップして、 インプラントに更なる取り組みを試している。 マシルがそれを全員に着けるのを承認したのは @@ -10796,12 +11278,12 @@ Macil udostępnił je dla wszystkich? Nie wiesz? Wszystko dzięki temu, że sobie poradziłeś. Mogę coś jeszcze dla ciebie zrobić? -","Bem, estou de volta aos meus velhos truques novamente. Ainda estou trabalhando nos seus implantes. Você sabia que Macil os autorizou pra todo mundo? Ah não? É porque eles funcionaram muito bem em você. Precisa de alguma coisa?",,"Păi, m-am întors la treburile mele vechi, încă lucrez la implanturile tale. Știi că Macil a vrut să le autorizeze pentru toată lumea? Nu, așa-i? E din cauză că ai ieșit prea bine. Pot face ceva pentru tine?","Я снова вернулся к старым занятиям и по-прежнему работаю над твоим имплантом. Ты знаешь, что Мэйсил теперь всем разрешил использовать импланты? Нет? Это потому, что ты так хорошо показал себя. Могу я чем-нибудь тебе помочь?",,"Yine eski numaralarıma döndüm. Hâlâ implantların üzerinde çalışıyorum. Macil'in artık herkes için onay verdiğini biliyor muydun? Hayır, ha? Bu kadar iyi olduğun için. Senin için yapabileceğim bir şey var mı?" -Help me out here.,TXT_RPLY0_SCRIPT10_D25772_HELPM,,,,Pomoz mi.,Hjælp mig lige her.,Hilf mir mal.,,,Ayúdame.,,Autatko vähän.,Aidez moi.,Segíts nekem egy kicsit.,Aiutami.,ここで治してくれ。,나 좀 치료해줘요.,Help me hier.,Hjelp meg her.,Pomóż mi.,Preciso de uma ajuda aqui.,,Dă-mi o mână de ajutor.,Помоги мне вот с этим.,,Bana yardım et. -That's all I can do.,TXT_RYES0_SCRIPT10_D25772_THATS,,,,"To je vše, co mohu udělat.","Det er det eneste, jeg kan gøre.","Da ist alles, was ich tun kann.",,,Eso es todo lo que puedo hacer.,,"Tässä kaikki, mitä voin tehdä.",C'est tout ce que je peux faire.,Csak ennyit tudtam tenni.,È tutto quello che posso fare.,私が出来る事はここまでだ。,좀 치료해줬습니다. 이제 어떠신가요?,Dat is alles wat ik kan doen.,Det er alt jeg kan gjøre.,To wszystko co mogę zrobić.,Isso é tudo o que posso fazer.,,Asta e tot ceea ce pot face.,"Это всё, что я могу сделать.",,Tek yapabileceğim bu. -New implant?,TXT_RPLY1_SCRIPT10_D25772_NEWIM,,,,Nový implantát?,Nyt implantat?,Neues Implantat?,,,¿Nuevo implante?,,Uusi istute?,Un nouvel implant?,Új implantátum?,Nuovo impianto?,新しいインプラントは?,새로운 이식 칩?,Een nieuw implantaat?,Nytt implantat?,Nowy implant?,Implante novo?,,Implant nou?,Новый имплант?,,Yeni implant mı? -"Yep, my best one yet.",TXT_RYES1_SCRIPT10_D25772_YEPMY,,,,"Jo, můj zatím nejlepší.","Ja, mit bedste endnu.","Ja, mein bestes bisher.",,,"Si, el mejor que tengo.",,"Jep, tähänastisista istutteistani paras.","Oui, le meilleur que j'ai jamais conçu.","Igen, az egyik legjobb változat eddig.","Si, il migliore che ho creato fin'ora.",よし、これは傑作だ。,있죠. 제 생각엔 아주 좋은 품질인 것 같아요.,"Ja, mijn beste tot nu toe.","Ja, mitt beste hittil.",Tak. Najlepszy jaki dotychczas zrobiłem.,Isso mesmo. O melhor que já fiz até agora.,,"Da, cel mai bun, momentan.",Да. Моё лучшее творение.,,"Evet, şimdiye kadarki en iyisi." -"Sorry, but you just have to wait.",TXT_RNO1_SCRIPT10_D25772_SORRY,,,,"Promiň, ještě budeš muset počkat.","Beklager, men du må bare vente.","Tut mir leid, du musst noch warten.",,,"Lo siento, pero tendrás que esperar.",,"Pahoittelen, sinun täytyy vain vielä vähän odottaa.","Désolé, il faudra attendre encore.","Sajnálom, de várnod kell egy kicsit.","Mi spiace, ma devi attendere un poco.",すまない、だがもうすぐ出来そうだ。,시간을 좀 더 주신다면...,"Sorry, maar je moet gewoon wachten.","Beklager, men du må bare vente.","Wybacz, ale musisz poczekać.","Desculpe, mas você vai ter que esperar.",,"Scuze, dar trebuie să mai aștepți.","Прости, но тебе придётся подождать.",,Üzgünüm ama beklemek zorundasın. +","Bem, estou de volta aos meus velhos truques novamente. Ainda estou trabalhando nos seus implantes. Você sabia que Macil os autorizou pra todo mundo? Ah não? É porque eles funcionaram muito bem em você. Precisa de alguma coisa?",,"Păi, m-am întors la treburile mele vechi, încă lucrez la implanturile tale. Știi că Macil a vrut să le autorizeze pentru toată lumea? Nu, așa-i? E din cauză că ai ieșit prea bine. Pot face ceva pentru tine?","Я снова вернулся к старым занятиям и по-прежнему работаю над твоим имплантом. Ты знаешь, что Мэйсил теперь всем разрешил использовать импланты? Нет? Это потому, что ты так хорошо показал себя. Могу я чем-нибудь тебе помочь?",,"Jag är tillbaka till mina gamla tricks igen, jag jobbar fortfarande på dina implantat. Visste du att Macil nu har godkänt dem för alla? Nej, va? Det är för att du blev så bra. Är det något jag kan göra för dig?","Yine eski numaralarıma döndüm. Hâlâ implantların üzerinde çalışıyorum. Macil'in artık herkes için onay verdiğini biliyor muydun? Hayır, ha? Bu kadar iyi olduğun için. Senin için yapabileceğim bir şey var mı?" +Help me out here.,TXT_RPLY0_SCRIPT10_D25772_HELPM,,,,Pomoz mi.,Hjælp mig lige her.,Hilf mir mal.,,,Ayúdame.,,Autatko vähän.,Aidez moi.,Segíts nekem egy kicsit.,Aiutami.,ここで治してくれ。,나 좀 치료해줘요.,Help me hier.,Hjelp meg her.,Pomóż mi.,Preciso de uma ajuda aqui.,,Dă-mi o mână de ajutor.,Помоги мне вот с этим.,,Hjälp mig här.,Bana yardım et. +That's all I can do.,TXT_RYES0_SCRIPT10_D25772_THATS,,,,"To je vše, co mohu udělat.","Det er det eneste, jeg kan gøre.","Da ist alles, was ich tun kann.",,,Eso es todo lo que puedo hacer.,,"Tässä kaikki, mitä voin tehdä.",C'est tout ce que je peux faire.,Csak ennyit tudtam tenni.,È tutto quello che posso fare.,私が出来る事はここまでだ。,좀 치료해줬습니다. 이제 어떠신가요?,Dat is alles wat ik kan doen.,Det er alt jeg kan gjøre.,To wszystko co mogę zrobić.,Isso é tudo o que posso fazer.,,Asta e tot ceea ce pot face.,"Это всё, что я могу сделать.",,Det är allt jag kan göra.,Tek yapabileceğim bu. +New implant?,TXT_RPLY1_SCRIPT10_D25772_NEWIM,,,,Nový implantát?,Nyt implantat?,Neues Implantat?,,,¿Nuevo implante?,,Uusi istute?,Un nouvel implant?,Új implantátum?,Nuovo impianto?,新しいインプラントは?,새로운 이식 칩?,Een nieuw implantaat?,Nytt implantat?,Nowy implant?,Implante novo?,,Implant nou?,Новый имплант?,,Nytt implantat?,Yeni implant mı? +"Yep, my best one yet.",TXT_RYES1_SCRIPT10_D25772_YEPMY,,,,"Jo, můj zatím nejlepší.","Ja, mit bedste endnu.","Ja, mein bestes bisher.",,,"Si, el mejor que tengo.",,"Jep, tähänastisista istutteistani paras.","Oui, le meilleur que j'ai jamais conçu.","Igen, az egyik legjobb változat eddig.","Si, il migliore che ho creato fin'ora.",よし、これは傑作だ。,있죠. 제 생각엔 아주 좋은 품질인 것 같아요.,"Ja, mijn beste tot nu toe.","Ja, mitt beste hittil.",Tak. Najlepszy jaki dotychczas zrobiłem.,Isso mesmo. O melhor que já fiz até agora.,,"Da, cel mai bun, momentan.",Да. Моё лучшее творение.,,"Japp, mitt bästa hittills.","Evet, şimdiye kadarki en iyisi." +"Sorry, but you just have to wait.",TXT_RNO1_SCRIPT10_D25772_SORRY,,,,"Promiň, ještě budeš muset počkat.","Beklager, men du må bare vente.","Tut mir leid, du musst noch warten.",,,"Lo siento, pero tendrás que esperar.",,"Pahoittelen, sinun täytyy vain vielä vähän odottaa.","Désolé, il faudra attendre encore.","Sajnálom, de várnod kell egy kicsit.","Mi spiace, ma devi attendere un poco.",すまない、だがもうすぐ出来そうだ。,시간을 좀 더 주신다면...,"Sorry, maar je moet gewoon wachten.","Beklager, men du må bare vente.","Wybacz, ale musisz poczekać.","Desculpe, mas você vai ter que esperar.",,"Scuze, dar trebuie să mai aștepți.","Прости, но тебе придётся подождать.",,"Ledsen, men du måste vänta.",Üzgünüm ama beklemek zorundasın. "This is it, Feris has managed to drain everything he could out of all the data we have, this will be the best, and last implant upgrade. It will be sort of depressing, seeing my best creation reach its peak. Well, at least the rest of this crew will keep me occupied.",TXT_DLG_SCRIPT10_D27288_THISI,,,,"A je to, Feris vyždímal všechno, co mohl, z dat, která máme. Tohle bude poslední a nejlepší implantátový upgrade. Bude mi trochu smutno, vidět můj výtvor dosáhnout vrcholu. No, alespoň budu zaneprázdněný zbytkem armády.","Det er nu, Feris har formået at dræne alt hvad han kunne ud af alle de data vi har, dette bliver den bedste, og sidste implantatopgradering. Det bliver lidt deprimerende at se min bedste skabelse nå sit højdepunkt. I det mindste vil resten af besætningen holde mig beskæftiget.","Das ist es, Feris hat aus den Daten alles herausgeholt, was möglich war. Das wird das beste und letzte Upgrade sein. Irgendwie deprimierend zu sehen, dass meine beste Erfindung ihren Höhepunkt erreicht hat. Nun ja, wenigstens wird der Rest dieser Truppe mich lange genug beschäftigen.",,,"Ya está, Feris ha conseguido exprimir todo lo que ha podido de los datos que tenemos, este va a ser la mejor, y última mejora del implante. Es un poco triste ver mi mejor creación llegar a su cima. Bueno, al menos el resto del personal me mantendrá ocupado.",,"Tässä se nyt on; Feriksen on onnistunut puristaa kaiken ulos kaikesta käsissämme olevasta datasta. Tämä tulee olemaan istutteen paras ja viimeinen kehitysaskel. Vähän jotenkin masentavaa nähdä parhaan luomuksensa saavuttavan huippunsa. No, saanpahan sentään edes puuhaa lopuista tästä miehistöstä.","C'est fini, Feris a réussi à tirer tout ce qu'on pouvait des données que l'on a récupéré. Ce sera la dernière, et meilleure mise à jour. C'est un peu déprimant, de savoir que ma meilleure invention à déjà atteint son pinnacle.. Bon, au moins, le reste de l'équipe me gardera occupé.","Ez lesz a végkifejlett, Ferisnek sikerült kipréselni minden adatot, ez lesz a legjobb és egyben utolsó implantátum fejlesztés. Kicsit hervasztó érzés látni munkám gyümölcsének végkifejlettségét. Na de legalább a csapat többi része le fog foglalni.","Ecco qua, Feris è riuscito ad estrarre tutto quello che poteva dai dati che possediamo, e questo sarà il migliore, nonché l'ultimo, aggiornamento dell'impianto. In un certo senso sarà un pò deprimente, vedere la mia migliore creazione raggiungere l'apice. Se non altro, il resto di questa squadra mi terrà occupato.","いよいよだ、フェリスが我々の保管していた 全てのデータから全力を尽くして編み出した、 これが最高で最後のインプラント @@ -10813,9 +11295,9 @@ najlepsze i ostatnie ulepszenie implantu. To trochę smutne, że moje dzieło tak szybko osiągnęło szczyt możliwości. Cóż... przynajmniej będę -mógł zająć się resztą załogi.","É isso aí, Feris conseguiu tirar tudo que foi possível dos dados que temos. Este será a melhor e a última aprimoração do implante. Vai ser meio triste, vendo minha melhor criação chegar no seu ápice. Bom, pelo menos o resto do pessoal vai me manter ocupado.",,"Asta e, Feris a reușit să stoarcă tot din datele pe care le avem, acesta e ultimul, și cel mai bun upgrade pentru implant. Va fi oarecum deprimant, să-mi văd creația ajungând în vârf. Măcar restul echipajului mă va ține ocupat.","Вот и всё. Из тех данных, которыми мы располагаем, Ферису удалось вытянуть всё, что только можно. Это лучшая и последняя модификация импланта. Немного грустно видеть, что твоё творение достигло своего предела. Ну, по крайней мере, я всё ещё нужен остальной части команды.",,"İşte bu, Feris elimizdeki tüm verilerden çekebildiği her şeyi çekmeyi başardı, bu en iyi ve son implant güncellemesi olacak. En iyi eserimin zirveye ulaştığını görmek biraz iç karartıcı olacak. En azından bu mürettebatın geri kalanı beni meşgul edecek." -Could you heal me?,TXT_RPLY0_SCRIPT10_D27288_COULD,,,,Mohl bys mě ošetřit?,Kan du helbrede mig?,Kannst du mich gesund machen?,,,¿Podrías curarme?,,Voisitko hoitaa minua?,Vous pouvez me soigner?,Fel tudnál gyógyítani?,Puoi curarmi?,治してくれるか?,절 치료해줄 수 있나요?,Kunt je me genezen?,Kan du helbrede meg?,Możesz mnie uleczyć?,Poderia me curar?,,Mă poți bandaja?,Вылечишь меня?,,Beni iyileştirebilir misin? -"There, you're all set now.",TXT_RYES0_SCRIPT10_D27288_THERE,,,,"Tak, a jsi hotov.","Sådan, du er klar nu.","So, das wär's dann.",,,"Ya está, listo.",,"Siinä, kaikki kunnossa.","Voilà, vous pouvez y aller.","Parancsolj, harcra kész vagy.","Certo, ora sei apposto.",これで、準備完了だ。,"자, 이제 안전할 겁니다.",Daar ben je nu helemaal klaar.,"Sånn, nå er du klar.",Proszę. Wszystko gotowe.,Feito. Tudo certo agora.,,"Gata, ești pregătit.",Конечно. Теперь ты в норме.,,"İşte, şimdi hazırsın." +mógł zająć się resztą załogi.","É isso aí, Feris conseguiu tirar tudo que foi possível dos dados que temos. Este será a melhor e a última aprimoração do implante. Vai ser meio triste, vendo minha melhor criação chegar no seu ápice. Bom, pelo menos o resto do pessoal vai me manter ocupado.",,"Asta e, Feris a reușit să stoarcă tot din datele pe care le avem, acesta e ultimul, și cel mai bun upgrade pentru implant. Va fi oarecum deprimant, să-mi văd creația ajungând în vârf. Măcar restul echipajului mă va ține ocupat.","Вот и всё. Из тех данных, которыми мы располагаем, Ферису удалось вытянуть всё, что только можно. Это лучшая и последняя модификация импланта. Немного грустно видеть, что твоё творение достигло своего предела. Ну, по крайней мере, я всё ещё нужен остальной части команды.",,"Det här är det, Feris har lyckats dränera allt han kunde ur all data vi har, det här kommer att bli den bästa, och sista implantatuppgraderingen. Det kommer att bli lite deprimerande att se min bästa skapelse nå sin höjdpunkt. Tja, resten av besättningen kommer åtminstone att hålla mig sysselsatt.","İşte bu, Feris elimizdeki tüm verilerden çekebildiği her şeyi çekmeyi başardı, bu en iyi ve son implant güncellemesi olacak. En iyi eserimin zirveye ulaştığını görmek biraz iç karartıcı olacak. En azından bu mürettebatın geri kalanı beni meşgul edecek." +Could you heal me?,TXT_RPLY0_SCRIPT10_D27288_COULD,,,,Mohl bys mě ošetřit?,Kan du helbrede mig?,Kannst du mich gesund machen?,,,¿Podrías curarme?,,Voisitko hoitaa minua?,Vous pouvez me soigner?,Fel tudnál gyógyítani?,Puoi curarmi?,治してくれるか?,절 치료해줄 수 있나요?,Kunt je me genezen?,Kan du helbrede meg?,Możesz mnie uleczyć?,Poderia me curar?,,Mă poți bandaja?,Вылечишь меня?,,Kan du läka mig?,Beni iyileştirebilir misin? +"There, you're all set now.",TXT_RYES0_SCRIPT10_D27288_THERE,,,,"Tak, a jsi hotov.","Sådan, du er klar nu.","So, das wär's dann.",,,"Ya está, listo.",,"Siinä, kaikki kunnossa.","Voilà, vous pouvez y aller.","Parancsolj, harcra kész vagy.","Certo, ora sei apposto.",これで、準備完了だ。,"자, 이제 안전할 겁니다.",Daar ben je nu helemaal klaar.,"Sånn, nå er du klar.",Proszę. Wszystko gotowe.,Feito. Tudo certo agora.,,"Gata, ești pregătit.",Конечно. Теперь ты в норме.,,"Så där, du är redo nu.","İşte, şimdi hazırsın." It's the hero. Great job! What can I get for you? We've got a little larger selection now that we have all the ordinance from the castle. If you need to buy some ammo talk to Justin. He'll take care of you. ,TXT_DLG_SCRIPT10_D28804_ITSTH,MAP10: Feris (no training).,,,"Je to náš hrdina. Skvělá práce! Co ti můžu sehnat? Máme trochu větší výběr, když teď máme přístup ke všemu vybavení z hradu. Jestli potřebuješ munici, zeptej se Justina, on si s tebou poradí.","Det er helten. Godt gået! Hvad kan jeg skaffe til dig? Vi har et lidt større udvalg nu, hvor vi har alle ordinationerne fra slottet. Hvis du har brug for at købe noget ammunition, så tal med Justin. Han vil tage sig af dig.","Das ist der Held. Guter Job! Was kann ich für dich tun. Wir haben jetzt eine größere Auswahl nachdem wir die Burg geplündert haben. Wenn du noch Munition brauchst, wende dich an Justin. Er kümmert sich darum.",,,Es el héroe. ¡Buen trabajo! ¿Qué puedo ofrecerte? Tenemos una selección un poco más amplia ahora que tenemos todo el arsenal del castillo. Si necesitas comprar municiones habla con Justin. Él se ocupará de ti.,,"Sankarimmehan se siinä; hyvää työtä! Miten voin olla avuksi? Meillä on hieman suurempi valikoima nyt, kun olemme saaneet käsiimme linnan kaikki asetarvikkeet. Jos sinun tarvitsee ostaa ammuksia, puhu Justinille. Hän hoitaa tarpeesi.","Voilà notre héros! Fantastique travail! Que puis-je faire pour vous? Nous avons étendu notre séléction maintenant que nous avons l'arsenal du château à notre disposition. Si vous avez besoin de munitions, parlez à Justin. Il s'occupera de vous.","Itt a hősünk. Kiváló munka! Mit adhatok? Kicsivel nagyobb a választék, most hogy megvan az összes leírás a kastélyból. Ha akarsz lőszert venni, beszélj Justinnal. Majd Ő gondoskodik rólad.","È l'eroe, ottimo lavoro! Che posso procurarti? Abbiamo una selezione un pò più grande dopo aver saccheggiato i depositi del castello. Se ti servono altre munizioni parla con Justin. Ci penserà lui a te.","正に英雄、流石です! 何か必要ですか?城の全兵器が揃っております。 弾薬が必要ならジャスティンに頼めば大丈夫ですよ",그 프론트의 인기 많은 영웅 아닌가요? 잘하셨습니다! 무엇을 도와드릴까요? 성안에서 특이하고 질 좋은 보급물자들을 긁어모아 왔어요. 만약 탄약 보급을 위해서 오신 거라면 저스틴에게 물어보세요.,"Het is de held. Goed werk! Wat kan ik voor je halen? We hebben een iets grotere selectie nu we alle verordeningen van het kasteel hebben. Als je wat munitie moet kopen, praat dan met Justin. Hij zal voor je zorgen.","Det er helten. Bra jobbet! Hva vil du ha? Vi har et litt større utvalg nå som vi har alle ordrene fra slottet. Hvis du trenger å kjøpe ammunisjon, snakk med Justin. Han tar seg av deg.","Oto bohater. Dobra robota! Co mogę @@ -10823,40 +11305,40 @@ dla ciebie zrobić? Mamy teraz większy wybór towaru dzięki rozporządzeniu z zamku. Jeśli potrzebujesz amunicji to porozmawiaj z Justinem. Zajmie -się tobą.",Nosso herói. Bom trabalho! Como posso te ajudar? Temos uma seleção um pouco maior agora que conseguimos todo o equipamento do castelo. Se você precisar comprar munição é só falar com o Justin. Ele pode te ajudar.,,"E eroul. Bună treabă! Ce pot să-ți aduc? Avem o selecție mai largă acum, din moment ce am primit toate ordonanțele de la castel. Dacă ai nevoie de muniție vorbește cu Justin, se va ocupa de tine.","А вот и наш герой. Отлично сработано! Чем я могу тебе помочь? Теперь в нашем распоряжении всё оружие из замка, так что выбор стал побогаче. Если тебе нужны боеприпасы, обратись к Джастину: он тебе поможет.",,Bu kahraman. İyi iş çıkardın! Size ne getireyim? Kaledeki tüm teçhizat elimizde olduğu için biraz daha geniş bir seçkimiz var. Cephane almak istersen Justin'le konuş. O seninle ilgilenir. -I'm out of bullets.,TXT_RPLY0_SCRIPT10_D28804_IMOUT,〃,,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Luodit on loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Skończyły mi się naboje.,Estou sem munição.,,Nu mai am gloanțe.,У меня кончились патроны.,,Mermim bitti. +się tobą.",Nosso herói. Bom trabalho! Como posso te ajudar? Temos uma seleção um pouco maior agora que conseguimos todo o equipamento do castelo. Se você precisar comprar munição é só falar com o Justin. Ele pode te ajudar.,,"E eroul. Bună treabă! Ce pot să-ți aduc? Avem o selecție mai largă acum, din moment ce am primit toate ordonanțele de la castel. Dacă ai nevoie de muniție vorbește cu Justin, se va ocupa de tine.","А вот и наш герой. Отлично сработано! Чем я могу тебе помочь? Теперь в нашем распоряжении всё оружие из замка, так что выбор стал побогаче. Если тебе нужны боеприпасы, обратись к Джастину: он тебе поможет.",,Det är hjälten. Bra jobbat! Vad kan jag ge dig? Vi har ett lite större urval nu när vi har alla ordinationer från slottet. Om du behöver köpa lite ammunition så prata med Justin. Han tar hand om dig.,Bu kahraman. İyi iş çıkardın! Size ne getireyim? Kaledeki tüm teçhizat elimizde olduğu için biraz daha geniş bir seçkimiz var. Cephane almak istersen Justin'le konuş. O seninle ilgilenir. +I'm out of bullets.,TXT_RPLY0_SCRIPT10_D28804_IMOUT,〃,,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Luodit on loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Skończyły mi się naboje.,Estou sem munição.,,Nu mai am gloanțe.,У меня кончились патроны.,,Jag har slut på kulor.,Mermim bitti. Here's some ammo for you. Don't waste it.,TXT_RYES0_SCRIPT10_D28804_HERES,〃,,,"Tady máš nějakou munici, neplýtvej s ní.",Her er noget ammunition til dig. Spild det ikke.,Hier hast du welche. Verschwende sie nicht.,,"Jen iom da municio. Ne malŝparu ĝin.","Aquí tienes algo de munición. -No la desperdicies.",,Tässä sinulle vähän ammuksia. Älä tuhlaa niitä.,Voilà des munitions. Ne les gaspillez pas.,Itt van egy kis lőszer. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,그렇게 계속 쏘아대면 탄약이 낭비됩니다. 여기 탄약이에요.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Masz tu trochę amunicji. Tylko jej nie zmarnuj.,Leve um pouco desta munição. Não desperdice.,,Uite niște muniție. N-o risipi.,Можешь взять немного. Не трать их понапрасну.,,İşte sana biraz cephane. Ziyan etme. -Teach me.,TXT_RPLY1_SCRIPT10_D28804_TEACH,〃,,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. -"Now, a few tips on the big guns.",TXT_RYES1_SCRIPT10_D28804_NOWAF,〃,,,"Tak jo, pár tipů, jak na velké zbraně.",Nu et par tips om de store våben.,Nun einige Ratschläge für die großen Waffen,,,"Ahora, unos cuantos consejos sobre las armas pesadas.",,Voin antaa muutamia vinkkejä isojen aseiden käyttöön.,"Bon, voilà quelques conseils pour les armes plus grosses.","És most, pár tipp a nagyobb fegyverekhez.",Ecco qui un paio di consigli sulle armi pesanti.,では、大きい銃の扱い方を教えます。,중화기 다루는 훈련을 시작하겠습니다!,"Nu, een paar tips over de grote geweren.","Nå, noen tips om de store kanonene.",Proszę. Kilka wskazówek dotyczących używania większych broni.,"Ok, algumas dicas sobre as armas pesadas.",,"Acum, niște sfaturi pentru armele mari.",А теперь пара советов насчёт больших пушек.,,"Şimdi, büyük silahlar hakkında birkaç ipucu." -You're not ready yet.,TXT_RNO1_SCRIPT10_D28804_YOURE,〃,,,Ještě nejsi připraven.,Du er ikke klar endnu.,Du bist noch nicht soweit,,,Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Nem állsz még készen.,Non sei ancora pronto.,貴方の準備がまだ整ってないように思えます。,준비가 아직 안됐습니다.,Je bent nog niet klaar.,Du er ikke klar ennå.,Nie jesteś jeszcze na to gotowy.,Você ainda não está preparado.,,Nu ești pregătit încă.,Ты ещё не готов.,,Henüz hazır değilsin. +No la desperdicies.",,Tässä sinulle vähän ammuksia. Älä tuhlaa niitä.,Voilà des munitions. Ne les gaspillez pas.,Itt van egy kis lőszer. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,그렇게 계속 쏘아대면 탄약이 낭비됩니다. 여기 탄약이에요.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Masz tu trochę amunicji. Tylko jej nie zmarnuj.,Leve um pouco desta munição. Não desperdice.,,Uite niște muniție. N-o risipi.,Можешь взять немного. Не трать их понапрасну.,,Här är lite ammunition till dig. Slösa inte bort den.,İşte sana biraz cephane. Ziyan etme. +Teach me.,TXT_RPLY1_SCRIPT10_D28804_TEACH,〃,,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. +"Now, a few tips on the big guns.",TXT_RYES1_SCRIPT10_D28804_NOWAF,〃,,,"Tak jo, pár tipů, jak na velké zbraně.",Nu et par tips om de store våben.,Nun einige Ratschläge für die großen Waffen,,,"Ahora, unos cuantos consejos sobre las armas pesadas.",,Voin antaa muutamia vinkkejä isojen aseiden käyttöön.,"Bon, voilà quelques conseils pour les armes plus grosses.","És most, pár tipp a nagyobb fegyverekhez.",Ecco qui un paio di consigli sulle armi pesanti.,では、大きい銃の扱い方を教えます。,중화기 다루는 훈련을 시작하겠습니다!,"Nu, een paar tips over de grote geweren.","Nå, noen tips om de store kanonene.",Proszę. Kilka wskazówek dotyczących używania większych broni.,"Ok, algumas dicas sobre as armas pesadas.",,"Acum, niște sfaturi pentru armele mari.",А теперь пара советов насчёт больших пушек.,,"Nu, några tips om de stora vapnen.","Şimdi, büyük silahlar hakkında birkaç ipucu." +You're not ready yet.,TXT_RNO1_SCRIPT10_D28804_YOURE,〃,,,Ještě nejsi připraven.,Du er ikke klar endnu.,Du bist noch nicht soweit,,,Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Nem állsz még készen.,Non sei ancora pronto.,貴方の準備がまだ整ってないように思えます。,준비가 아직 안됐습니다.,Je bent nog niet klaar.,Du er ikke klar ennå.,Nie jesteś jeszcze na to gotowy.,Você ainda não está preparado.,,Nu ești pregătit încă.,Ты ещё не готов.,,Du är inte redo än.,Henüz hazır değilsin. "How's the war effort? Nevermind, if we're still here, it must be going fine. What can I do for you?",TXT_DLG_SCRIPT10_D30320_HOWST,〃 (one training),,,"Jak jde válečné úsilí? To je jedno, jestliže tu stále jsi, musí to jít dobře. Co pro tebe můžu udělat?","Hvordan går det med krigsindsatsen? Glem det, hvis vi stadig er her, må det gå fint. Hvad kan jeg gøre for dig?","Wie geht der Krieg voran? Egal, solange wir noch hier sind, kann es nicht schlecht laufen. Was kann ich für dich tun?",,,"¿Cómo va la guerra? No importa, si seguimos aquí, debe de ir bien. ¿Qué puedo hacer por ti?",,"Kuinkas sotaponnistelut sujuvat? Tai ei mitään, varmaankin hyvin sujuvat, jos kerran vielä olemme tässä. Miten voin palvella?","Comment va l'effort de guerre? Non, oubliez. Si vous êtes ici, ça veut dire que tout va bien. Que puis-je faire pour vous?","Hogy áll a harc? Mindegyis, ha még mindig itt vagyunk, akkor jól haladunk. Mit tehetek érted?","Come sta procedendo la guerra? Vabbè, lascia stare, siamo ancora qua, quindi deve procedere bene. Cosa posso fare per te?","奮闘してますか?気にしないで、 ここにいるなら上手くやってるのは分かります。 どういうご用件ですか?",전쟁 상황은 어떻게 되어가나요? 상관은 없지만. 우리들이 아직 살아있는 한 물어볼 필요도 없죠. 무엇을 원하시나요?,"Hoe gaat het met de oorlogsinspanning? Maakt niet uit, als we hier nog steeds zijn, moet het wel goed gaan. Wat kan ik voor je doen?","Hvordan går det med krigsinnsatsen? Glem det, hvis vi fortsatt er her, må det gå bra. Hva kan jeg gjøre for deg?","Jak tam wojna idzie? Nieważne. Jeśli cały czas żyjemy to chyba dobrze. -Co mogę dla ciebie zrobić?","Como está indo a guerra? Deixa pra lá, se nós ainda estamos aqui é porque deve estar indo bem. Como posso te ajudar?",,"Cum merge efortul de război? Nu mai contează, dacă suntem încă aici înseamnă că e bine. Ce pot face pentru tine?","Как дела на фронте? Впрочем, неважно. Наверняка всё хорошо, раз мы ещё живы. Что я могу для тебя сделать?",,"Savaş çabaları nasıl gidiyor? Boşver, hala burada olduğumuza göre, iyi gidiyor olmalı. Senin için ne yapabilirim?" -I ran out of bullets.,TXT_RPLY0_SCRIPT10_D30320_IRANO,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for kugler.,Mir ist die Munition ausgegangen.,,,Me he quedado sin balas.,,Minulta loppuivat luodit.,Je suis à court de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾を使い果たした。,탄약이 바닥났어요.,De kogels zijn op.,Jeg gikk tom for kuler.,Skończyły mi się naboje.,Fiquei sem munição.,,Am rămas fără gloanțe.,У меня кончились патроны.,,Mermim bitti. -That should help.,TXT_RYES0_SCRIPT10_D30320_THATS,〃 (〃),,,Tohle by mělo pomoci.,Det burde hjælpe.,Das hier sollte helfen.,,,Esto debería ayudar.,,Tämän pitäisi auttaa.,Cela devrait aider.,Ez majd segít.,Questo dovrebbe aiutarti.,これが助けになるでしょう。,좀 도움이 될 겁니다.,Dat zou moeten helpen.,Det burde hjelpe.,To powinno pomóc.,Isto deve ajudar.,,Asta ar trebui să ajute.,"Вот, пожалуйста.",,Bunun yardımı olur. -You've got enough ammo.,TXT_RNO0_SCRIPT10_D30320_YOUVE,〃 (〃),,,Máš jich dost.,Du har nok ammunition.,Du hast genug Munition.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ne hai a sufficienza.,弾は十分に見えます。,탄약을 충분히 소지한 것 같은데.,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz wystarczająco dużo amunicji.,Você já tem munição suficiente.,,Ai destulă.,Вполне достаточно.,,Yeterince cephanen var. -Teach me.,TXT_RPLY1_SCRIPT10_D30320_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. -"Here, I'll show you a few tricks of the trade.",TXT_RYES1_SCRIPT10_D30320_HEREI,〃 (〃),,,Ukážu ti pár triků mého řemesla.,"Her, jeg skal vise dig et par tricks.","Hier, ich zeige dir mal ein paar Geheimtricks.",,,"Bien, te mostraré algunos trucos de oficio.",,"No niin, valotan sinulle vähän alan saloja.",Voilà quelques conseils dont vous pouvez faire usage.,"Nézdd csak, mutatok neked pár trükköt.",Ora ti mostro un paio di trucchi del mestiere.,では、幾つかのコツを教えましょう。,저항군의 참된 기술들을 좀 가르쳐드리죠!,Hier zal ik je een paar trucjes van het vak laten zien.,Jeg skal vise deg noen triks.,Proszę. Oto kilka wskazówek o handlu.,"Certo, vou te mostrar alguns truques do ofício.",,"Iată, am să te învăț niște trucuri.","Давай, я покажу тебе пару секретных приёмчиков.",,Sana işin birkaç püf noktasını göstereceğim. -You're not ready yet.,TXT_RNO1_SCRIPT10_D30320_YOURE,〃 (〃),,,Ještě nejsi připraven.,Du er ikke klar endnu.,Du bist noch nicht soweit,,,Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Nem állsz még készen.,Non sei ancora pronto.,貴方の準備がまだ整ってないように思えます。,당신은 아직 준비가 안됐어요.,Je bent nog niet klaar.,Du er ikke klar ennå.,Nie jesteś jeszcze na to gotowy.,Você ainda não está preparado.,,Nu ești pregătit încă.,Ты ещё не готов.,,Henüz hazır değilsin. +Co mogę dla ciebie zrobić?","Como está indo a guerra? Deixa pra lá, se nós ainda estamos aqui é porque deve estar indo bem. Como posso te ajudar?",,"Cum merge efortul de război? Nu mai contează, dacă suntem încă aici înseamnă că e bine. Ce pot face pentru tine?","Как дела на фронте? Впрочем, неважно. Наверняка всё хорошо, раз мы ещё живы. Что я могу для тебя сделать?",,"Hur går det med krigsinsatsen? Strunt samma, om vi fortfarande är här måste det gå bra. Vad kan jag göra för dig?","Savaş çabaları nasıl gidiyor? Boşver, hala burada olduğumuza göre, iyi gidiyor olmalı. Senin için ne yapabilirim?" +I ran out of bullets.,TXT_RPLY0_SCRIPT10_D30320_IRANO,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for kugler.,Mir ist die Munition ausgegangen.,,,Me he quedado sin balas.,,Minulta loppuivat luodit.,Je suis à court de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾を使い果たした。,탄약이 바닥났어요.,De kogels zijn op.,Jeg gikk tom for kuler.,Skończyły mi się naboje.,Fiquei sem munição.,,Am rămas fără gloanțe.,У меня кончились патроны.,,Jag fick slut på kulor.,Mermim bitti. +That should help.,TXT_RYES0_SCRIPT10_D30320_THATS,〃 (〃),,,Tohle by mělo pomoci.,Det burde hjælpe.,Das hier sollte helfen.,,,Esto debería ayudar.,,Tämän pitäisi auttaa.,Cela devrait aider.,Ez majd segít.,Questo dovrebbe aiutarti.,これが助けになるでしょう。,좀 도움이 될 겁니다.,Dat zou moeten helpen.,Det burde hjelpe.,To powinno pomóc.,Isto deve ajudar.,,Asta ar trebui să ajute.,"Вот, пожалуйста.",,Det borde hjälpa.,Bunun yardımı olur. +You've got enough ammo.,TXT_RNO0_SCRIPT10_D30320_YOUVE,〃 (〃),,,Máš jich dost.,Du har nok ammunition.,Du hast genug Munition.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ne hai a sufficienza.,弾は十分に見えます。,탄약을 충분히 소지한 것 같은데.,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz wystarczająco dużo amunicji.,Você já tem munição suficiente.,,Ai destulă.,Вполне достаточно.,,Du har tillräckligt med ammunition.,Yeterince cephanen var. +Teach me.,TXT_RPLY1_SCRIPT10_D30320_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. +"Here, I'll show you a few tricks of the trade.",TXT_RYES1_SCRIPT10_D30320_HEREI,〃 (〃),,,Ukážu ti pár triků mého řemesla.,"Her, jeg skal vise dig et par tricks.","Hier, ich zeige dir mal ein paar Geheimtricks.",,,"Bien, te mostraré algunos trucos de oficio.",,"No niin, valotan sinulle vähän alan saloja.",Voilà quelques conseils dont vous pouvez faire usage.,"Nézdd csak, mutatok neked pár trükköt.",Ora ti mostro un paio di trucchi del mestiere.,では、幾つかのコツを教えましょう。,저항군의 참된 기술들을 좀 가르쳐드리죠!,Hier zal ik je een paar trucjes van het vak laten zien.,Jeg skal vise deg noen triks.,Proszę. Oto kilka wskazówek o handlu.,"Certo, vou te mostrar alguns truques do ofício.",,"Iată, am să te învăț niște trucuri.","Давай, я покажу тебе пару секретных приёмчиков.",,"Här, jag ska visa dig några knep.",Sana işin birkaç püf noktasını göstereceğim. +You're not ready yet.,TXT_RNO1_SCRIPT10_D30320_YOURE,〃 (〃),,,Ještě nejsi připraven.,Du er ikke klar endnu.,Du bist noch nicht soweit,,,Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Nem állsz még készen.,Non sei ancora pronto.,貴方の準備がまだ整ってないように思えます。,당신은 아직 준비가 안됐어요.,Je bent nog niet klaar.,Du er ikke klar ennå.,Nie jesteś jeszcze na to gotowy.,Você ainda não está preparado.,,Nu ești pregătit încă.,Ты ещё не готов.,,Du är inte redo än.,Henüz hazır değilsin. Well have you come for tutelage or is it some ammo you're looking for? Don't think that I'm done with you yet. I've still got a few tricks up my sleeve.,TXT_DLG_SCRIPT10_D31836_WELLH,〃 (two trainings),,,"Tak co, přišel jsi sem kvůli další lekci nebo potřebuješ náboje? Nemysli si, že jsme tu skončili. Ještě mám pár triků v rukávu.","Er du kommet for at få undervisning, eller er det ammunition du leder efter? Du skal ikke tro, at jeg er færdig med dig endnu. Jeg har stadig et par tricks i ærmet.","Also, bist du zum Lernen gekommen, oder weil du mal wieder Munition brauchst? Denk bloß nicht, dass ich mit dir fertig bin. Ich habe noch ein paar Tricks auf Lager.",,,"Bien, ¿has venido a por tutela o buscas municiones? No creas que he terminado contigo. Aun tengo algunos trucos bajo la manga.",,"Oletko koulutuksen tarpeessa vai ammuksiako kaipaat? Älä luulekaan, etteikö hihassani olisi sinulle vielä muutamaa ässää jaettavana.","Vous êtes venu pour des leçons ou avez-vous besoin de munitions? Je n'ai pas encore fini avec vous, ne vous inquiétez-pas. J'ai encore des tours dans mon sac.","Valami kiképzés érdekel, vagy csak lőszerért jöttél? nehogy azt hidd, hogy végeztem veled. Még mindig rejt a tarsolyom új trükköket.","Allora, sei venuto per imparare qualcosa di nuovo o stai solo cercando munizioni? Non pensare che io abbia finito con te. Ho ancora qualche trucco da impartirti.","指導の受講か、弾薬の受け取りですか? まだ全て終わったわけではありません。 私の袖口に若干技術を忍ばせております。","무엇을 원하시나요? 훈련? 아니면 탄약 보급? 그리고 훈련은 아직 끝난 게 아니니까 끝날 걱정도, 다칠 고민도 하지 마시길 바랍니다.",Ben je gekomen voor voogdij of ben je op zoek naar munitie? Denk niet dat ik nog niet klaar ben met jou. Ik heb nog een paar trucjes in mijn mouw.,"Har du kommet for å få veiledning, eller er det ammunisjon du er ute etter? Ikke tro at jeg er ferdig med deg ennå. Jeg har fortsatt noen triks i ermet.","Chcesz się czegoś nauczyć czy raczej przyszedłeś po trochę amunicji? Nie myśl, że z tobą skończyłem. Wciąż mam jeszcze parę sztuczek -w zanadrzu.","Muito bem, você veio para aprender algo ou está precisando de munição? Não pense que aquilo é tudo, ainda tenho alguns truques na manga.",,"Ai venit pentru a învăța ceva sau doar pentru muniție? Să nu crezi că am terminat cu tine, încă mai am niste ași în mânecă.","Итак, ты пришёл за напутствием? Или тебе нужны боеприпасы? Не думай, что твоё обучение окончено. У меня ещё есть кое-какие козыри в рукаве!",,Özel ders için mi geldin yoksa cephane mi arıyorsun? Seninle işimin bittiğini sanma. Hala birkaç numaram var. -It's ammo for now.,TXT_RPLY0_SCRIPT10_D31836_ITSAM,〃 (〃),,,Teď tu jsem jen pro náboje.,Det er ammunition for nu.,Im Moment ist es Munition.,,,Es munición por ahora.,,Ammuksia tähän hätään.,Munitions pour l'instant.,Csak lőszer lesz most.,"Per il momento, solo munizioni.",今のところ弾薬だ。,탄약이 필요하겠네요.,Het is voorlopig munitie.,Det er ammunisjon for nå.,Tym razem chodzi o amunicję.,No momento preciso de munição.,,Muniție pentru moment.,Мне нужны боеприпасы.,,Şimdilik cephane. +w zanadrzu.","Muito bem, você veio para aprender algo ou está precisando de munição? Não pense que aquilo é tudo, ainda tenho alguns truques na manga.",,"Ai venit pentru a învăța ceva sau doar pentru muniție? Să nu crezi că am terminat cu tine, încă mai am niste ași în mânecă.","Итак, ты пришёл за напутствием? Или тебе нужны боеприпасы? Не думай, что твоё обучение окончено. У меня ещё есть кое-какие козыри в рукаве!",,Har du kommit för att få undervisning eller är det ammunition du letar efter? Tro inte att jag är klar med dig än. Jag har fortfarande några knep i ärmen.,Özel ders için mi geldin yoksa cephane mi arıyorsun? Seninle işimin bittiğini sanma. Hala birkaç numaram var. +It's ammo for now.,TXT_RPLY0_SCRIPT10_D31836_ITSAM,〃 (〃),,,Teď tu jsem jen pro náboje.,Det er ammunition for nu.,Im Moment ist es Munition.,,,Es munición por ahora.,,Ammuksia tähän hätään.,Munitions pour l'instant.,Csak lőszer lesz most.,"Per il momento, solo munizioni.",今のところ弾薬だ。,탄약이 필요하겠네요.,Het is voorlopig munitie.,Det er ammunisjon for nå.,Tym razem chodzi o amunicję.,No momento preciso de munição.,,Muniție pentru moment.,Мне нужны боеприпасы.,,Det är ammunition för tillfället.,Şimdilik cephane. Here's some ammo for you. Don't waste it.,TXT_RYES0_SCRIPT10_D31836_HERES,〃 (〃),,,"Tady nějaké máš, neplýtvej s nimi.",Her er lidt ammunition til dig. Spild det ikke.,Hier hast du welche. Verschwende sie nicht.,,"Jen iom da municio. Ne malŝparu ĝin.","Aquí tienes algo de munición. -No la desperdicies.",,Tässä sinulle vähän kuteja. Älä haaskaa niitä.,Voilà des munitions. Ne les gaspillez pas.,Itt van egy kis lőszer. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,"좋은 병사에겐, 좋은 품질의 탄약을.",Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Masz tu trochę amunicji. Tylko jej nie zmarnuj.,Leve um pouco desta munição. Não desperdice.,,Uite niște muniție. N-o risipi.,Можешь взять немного. Не трать их понапрасну.,,İşte sana biraz cephane. Boşa harcama. -You've got enough ammo.,TXT_RNO0_SCRIPT10_D31836_YOUVE,〃 (〃),,,Máš jich dost.,Du har ammunition nok.,Du hast genug Munition.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ne hai a sufficienza.,弾は十分に見えます。,아직 당신에게 탄약이 남아있는 것 같습니다만...,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz wystarczająco dużo amunicji.,Você já tem munição suficiente.,,Ai destulă muniție.,У тебя хватает патронов.,,Yeterince cephanen var. -Teach me.,TXT_RPLY1_SCRIPT10_D31836_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. -Time for the advanced lessons.,TXT_RYES1_SCRIPT10_D31836_TIMEF,〃 (〃),,,Čas na pokročilé lekce.,Tid til de avancerede lektioner.,Zeit für fortgeschrittene Lektionen.,,,Es hora de las lecciones avanzadas.,,Aika aloittaa syventävät opinnot.,Il est temps de passer à des leçons plus avancées.,Jöjjön valami komolyabb lecke.,È arrivato il momento delle lezioni avanzate.,上級レッスンの時間です。,심화학습을 할 시간이군요!,Tijd voor de gevorderde lessen voor gevorderden.,På tide med de avanserte leksjonene.,Czas na lekcje dla zaawansowanych.,Hora das aulas avançadas.,,Timpul pentru lecțiile avansate.,Пришло время для углублённого изучения оружия!,,İleri seviye ders zamanı. -You're not ready yet.,TXT_RNO1_SCRIPT10_D31836_YOURE,〃 (〃),,,Ještě nejsi připraven.,Du er ikke klar endnu.,Du bist noch nicht soweit.,,,Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Nem állsz még készen.,Non sei ancora pronto.,貴方の準備がまだ整ってないように思えます。,넌 아직 준비가 안됐어.,Je bent nog niet klaar.,Du er ikke klar ennå.,Nie jesteś jeszcze na to gotowy.,Você ainda não está preparado.,,Nu ești pregătit încă.,Ты ещё не готов.,,Henüz hazır değilsin. +No la desperdicies.",,Tässä sinulle vähän kuteja. Älä haaskaa niitä.,Voilà des munitions. Ne les gaspillez pas.,Itt van egy kis lőszer. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,"좋은 병사에겐, 좋은 품질의 탄약을.",Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Masz tu trochę amunicji. Tylko jej nie zmarnuj.,Leve um pouco desta munição. Não desperdice.,,Uite niște muniție. N-o risipi.,Можешь взять немного. Не трать их понапрасну.,,Här är lite ammunition till dig. Slösa inte bort den.,İşte sana biraz cephane. Boşa harcama. +You've got enough ammo.,TXT_RNO0_SCRIPT10_D31836_YOUVE,〃 (〃),,,Máš jich dost.,Du har ammunition nok.,Du hast genug Munition.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ne hai a sufficienza.,弾は十分に見えます。,아직 당신에게 탄약이 남아있는 것 같습니다만...,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz wystarczająco dużo amunicji.,Você já tem munição suficiente.,,Ai destulă muniție.,У тебя хватает патронов.,,Du har tillräckligt med ammunition.,Yeterince cephanen var. +Teach me.,TXT_RPLY1_SCRIPT10_D31836_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. +Time for the advanced lessons.,TXT_RYES1_SCRIPT10_D31836_TIMEF,〃 (〃),,,Čas na pokročilé lekce.,Tid til de avancerede lektioner.,Zeit für fortgeschrittene Lektionen.,,,Es hora de las lecciones avanzadas.,,Aika aloittaa syventävät opinnot.,Il est temps de passer à des leçons plus avancées.,Jöjjön valami komolyabb lecke.,È arrivato il momento delle lezioni avanzate.,上級レッスンの時間です。,심화학습을 할 시간이군요!,Tijd voor de gevorderde lessen voor gevorderden.,På tide med de avanserte leksjonene.,Czas na lekcje dla zaawansowanych.,Hora das aulas avançadas.,,Timpul pentru lecțiile avansate.,Пришло время для углублённого изучения оружия!,,Dags för avancerade lektioner.,İleri seviye ders zamanı. +You're not ready yet.,TXT_RNO1_SCRIPT10_D31836_YOURE,〃 (〃),,,Ještě nejsi připraven.,Du er ikke klar endnu.,Du bist noch nicht soweit.,,,Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Nem állsz még készen.,Non sei ancora pronto.,貴方の準備がまだ整ってないように思えます。,넌 아직 준비가 안됐어.,Je bent nog niet klaar.,Du er ikke klar ennå.,Nie jesteś jeszcze na to gotowy.,Você ainda não está preparado.,,Nu ești pregătit încă.,Ты ещё не готов.,,Du är inte redo än.,Henüz hazır değilsin. "Well, what is it now? Don't you ever take a break? I'm glad that you're still breathing. I'd hate for my favorite student to come back looking out from the inside of a body bag.",TXT_DLG_SCRIPT10_D33352_WELLW,〃 (three trainings),,"Well, what is it now? Don't you ever take a break? I'm glad that you're still breathing. I'd hate for my favourite student to come back looking out from the inside of a body bag.","Tak, o co jde teď? Nechceš si někdy dát oraz? Jsem rád, že ještě dýcháš. Nechtěl bych, aby se mi můj oblíbený student vrátil v rakvi.","Hvad er det så nu? Tager du aldrig en pause? Jeg er glad for, at du stadig trækker vejret. Jeg ville hade, hvis min yndlingselev skulle komme tilbage og se ud fra en ligpose.","Also, was ist es dieses Mal? Machst du jemals eine Pause? Bin ich froh, dass du noch atmest.Gefiele mir nicht, meinen Lieblingschüler in einem Leichensack zurückkommen zu sehen.",,,"Bien, ¿Qué es ahora? ¿Es que nunca descansas? Me alegra que sigas respirando. Odiaría ver a mi estudiante favorito volver asomándose de dentro de una bolsa para cadáveres.",,Mikä nyt on? Etkö koskaan pidä taukoa? Onneksi henki vielä pihisee. En haluaisi lempioppilaani palaavan takaisin ruumissäkissä.,"Eh bien, comment allez vous? Vous prenez une pause de temps en temps? Je suis content de voir que vous êtes toujours vivant, çe me ferait mal de voir mon apprenti préféré dans un sac mortuaire.","Már megint mi van? Te sosem tartasz szünetet? Örülök, hogy még mindig lélegzel. Nem örülnék neki ha a kedvenc tanoncomat egy hullazsákban látnám viszont.","Ah, e adesso cosa c'è? Non ti prendi mai una pausa? Mi fa piacere vederti ancora respirare. Sarebbe tragico vedere il mio studente preferito ritornare in una sacca per cadaveri.","さて、調子はどうですか?休憩しませんか? 貴方がまだ息をしているのが喜ばしい事です。 お気に入りの生徒が死体袋から天を仰ぐ様に @@ -10864,233 +11346,233 @@ You're not ready yet.,TXT_RNO1_SCRIPT10_D31836_YOURE,〃 (〃),,,Ještě nejsi p robisz sobie jakieś przerwy? Cieszę się, że wciąż żyjesz. Przykro by mi się zrobiło gdyby mój ulubiony uczeń -wrócił w trumnie.","Bem, o que vai ser desta vez? Será que você não descansa nunca? Ainda bem que você ainda está respirando. Eu detestaria ver meu aluno favorito voltando num saco de cadáver.",,Ce mai este? Nu iei niciodată pauză? Mă bucur că încă mai respiri. Ar fi păcat dacă cel mai bun student al meu ar veni într-un sac.,"Итак, ты справился? У тебя было время передохнуть? Рад видеть, что ты всё ещё дышишь. Мне бы не хотелось, чтобы мой лучший ученик вернулся в мешке для трупов.",,"Peki, şimdi ne var? Hiç ara vermez misin? Hâlâ nefes alıyor olmana sevindim. En sevdiğim öğrencimin bir ceset torbasının içinden bakarak geri gelmesini istemem." -I need some more bullets.,TXT_RPLY0_SCRIPT10_D33352_INEED,〃 (〃),,,Potřebuju nějaké další náboje.,Jeg har brug for flere kugler.,Ich brauche mehr Munition.,,,Necesito más balas.,,Tarvitsen lisää luoteja.,J'ai besoin de munitions.,Még több lőszerre lesz szükségem.,Ho bisogno di altre munizioni.,もっと弾が必要だ。,총알이 좀 더 필요해.,Ik heb meer kogels nodig.,Jeg trenger flere kuler.,Potrzebuję trochę naboi.,Preciso de mais munição.,,Am nevoie de niște gloanțe.,Мне нужны патроны.,,Biraz daha mermiye ihtiyacım var. -"There, don't waste it.",TXT_RYES0_SCRIPT10_D33352_THERE,〃 (〃),,,"Tady máš, neplýtvej s nimi.","Sådan, lad være med at spilde den.","Hier, verschwende sie nicht.",,,"Toma, no las desperdicies.",,"Kas tässä, älä tuhlaa niitä.","Voilà, ne les gaspillez pas.","Parancsolj, ne pazarold el.","Ecco qua, non sprecarle.",大切にして下さいね。,여기 있습니다. 낭비하지 말고 아껴 쓰세요.,"Daar, verspil het niet.","Sånn, ikke sløs dem bort.",Proszę. Nie zmarnuj ich.,Pegue. Não desperdice.,,"Iată, n-o risipi.",Вот. Не трать их попусту.,,"İşte, boşa harcama." -You have enough.,TXT_RNO0_SCRIPT10_D33352_YOUHA,〃 (〃),,,Máš jich dost.,Du har nok.,Du hast genug.,,,Tienes suficientes.,,Sinulla on tarpeeksi.,Vous en avez assez.,Már van elég.,Ne hai a sufficienza.,十分そうです。,지금도 충분한 것 같은데요.,Je hebt genoeg.,Du har nok.,Masz już ich wystarczająco dużo.,Você já tem o suficiente.,,Ai destulă.,Тебе хватает.,,Sende yeterince var. -What can you teach me?,TXT_RPLY1_SCRIPT10_D33352_WHATC,〃 (〃),,,Co mě můžeš naučit?,Hvad kan du lære mig?,Was kannst du mir beibringen?,,,¿Qué puedes enseñarme?,,Mitä voit opettaa minulle?,Que pouvez-vous m'apprendre.,Mit tudsz tanítani?,Che cosa mi puoi insegnare?,何か教えてくれないか?,나에게 뭘 가르쳐 줄 수 있죠?,Wat kun je me leren?,Hva kan du lære meg?,Czego możesz mnie nauczyć?,O que você tem pra me ensinar?,,Ce mă poți învăța?,Чему ты можешь меня научить?,,Bana ne öğretebilirsin? -"Don't get snippy, you've still some room to grow.",TXT_RYES1_SCRIPT10_D33352_DONTG,〃 (〃),,,Nebuď moc domýšlivý; ještě se máš co učit.,"Du skal ikke blive snerpet, du har stadig plads til at vokse.","Werd nicht leichtsinnig, du kannst noch einiges dazulernen.",,,"No seas insolente, aún tienes mucho que aprender.",,"Äläs rupea nokkavaksi, sinulla on vielä kasvun varaa.","Ne faites pas l'orgeuilleux, vous avez encore de quoi apprendre.","Ne hordd úgy fennt az orrod, van még mit tanulnod.","Non essere brusco, ci sono ancora cose che puoi imparare.",ぶっきらぼうにならないで、まだ成長の余地はあります。,너무 자만하지 마세요. 아직 더 배울 게 많으니까.,"Wordt niet snipperig, je hebt nog wat ruimte om te groeien.","Ikke vær frekk, du har fortsatt litt å gå på.",Nie wychylaj się. Przed tobą jeszcze długa droga.,"Vai devagar, rapaz. Você ainda tem muito o que aprender.",,"Nu fi impetinent, încă mai ai ce învăța.",Не задирай нос. Тебе ещё есть куда расти.,,"Kibirlenme, hala büyümek için yerin var." -Nothing until you're ready.,TXT_RNO1_SCRIPT10_D33352_NOTHI,〃 (〃),,,"Nic, dokud nebudeš připraven.","Intet, før du er klar.","Nichts, bevor diu nicht bereit bist.",,,Nada hasta que estés listo.,,"Ei mitään, kunnes olet valmis.",Pas avant que vous ne soyez prêt.,"Semmi, míg nem állsz készen.","Nulla al momento, finché non sarai pronto",準備が整うまで何も出来ません。,준비가 안 된 것 같으니 나중에 배웁시다.,Niets totdat je er klaar voor bent.,Ingenting før du er klar.,Na razie nic póki nie jesteś gotowy.,Nada até que você esteja preparado.,,"Nimic, până nu ești pregătit.","Ничему, пока ты не готов.",,Hazır olana kadar hiçbir şey. +wrócił w trumnie.","Bem, o que vai ser desta vez? Será que você não descansa nunca? Ainda bem que você ainda está respirando. Eu detestaria ver meu aluno favorito voltando num saco de cadáver.",,Ce mai este? Nu iei niciodată pauză? Mă bucur că încă mai respiri. Ar fi păcat dacă cel mai bun student al meu ar veni într-un sac.,"Итак, ты справился? У тебя было время передохнуть? Рад видеть, что ты всё ещё дышишь. Мне бы не хотелось, чтобы мой лучший ученик вернулся в мешке для трупов.",,Vad är det nu då? Tar du aldrig en paus? Jag är glad att du fortfarande andas. Jag vill inte att min favoritelev ska komma tillbaka och titta ut från insidan av en liksäck.,"Peki, şimdi ne var? Hiç ara vermez misin? Hâlâ nefes alıyor olmana sevindim. En sevdiğim öğrencimin bir ceset torbasının içinden bakarak geri gelmesini istemem." +I need some more bullets.,TXT_RPLY0_SCRIPT10_D33352_INEED,〃 (〃),,,Potřebuju nějaké další náboje.,Jeg har brug for flere kugler.,Ich brauche mehr Munition.,,,Necesito más balas.,,Tarvitsen lisää luoteja.,J'ai besoin de munitions.,Még több lőszerre lesz szükségem.,Ho bisogno di altre munizioni.,もっと弾が必要だ。,총알이 좀 더 필요해.,Ik heb meer kogels nodig.,Jeg trenger flere kuler.,Potrzebuję trochę naboi.,Preciso de mais munição.,,Am nevoie de niște gloanțe.,Мне нужны патроны.,,Jag behöver fler kulor.,Biraz daha mermiye ihtiyacım var. +"There, don't waste it.",TXT_RYES0_SCRIPT10_D33352_THERE,〃 (〃),,,"Tady máš, neplýtvej s nimi.","Sådan, lad være med at spilde den.","Hier, verschwende sie nicht.",,,"Toma, no las desperdicies.",,"Kas tässä, älä tuhlaa niitä.","Voilà, ne les gaspillez pas.","Parancsolj, ne pazarold el.","Ecco qua, non sprecarle.",大切にして下さいね。,여기 있습니다. 낭비하지 말고 아껴 쓰세요.,"Daar, verspil het niet.","Sånn, ikke sløs dem bort.",Proszę. Nie zmarnuj ich.,Pegue. Não desperdice.,,"Iată, n-o risipi.",Вот. Не трать их попусту.,,Slösa inte bort den.,"İşte, boşa harcama." +You have enough.,TXT_RNO0_SCRIPT10_D33352_YOUHA,〃 (〃),,,Máš jich dost.,Du har nok.,Du hast genug.,,,Tienes suficientes.,,Sinulla on tarpeeksi.,Vous en avez assez.,Már van elég.,Ne hai a sufficienza.,十分そうです。,지금도 충분한 것 같은데요.,Je hebt genoeg.,Du har nok.,Masz już ich wystarczająco dużo.,Você já tem o suficiente.,,Ai destulă.,Тебе хватает.,,Du har tillräckligt.,Sende yeterince var. +What can you teach me?,TXT_RPLY1_SCRIPT10_D33352_WHATC,〃 (〃),,,Co mě můžeš naučit?,Hvad kan du lære mig?,Was kannst du mir beibringen?,,,¿Qué puedes enseñarme?,,Mitä voit opettaa minulle?,Que pouvez-vous m'apprendre.,Mit tudsz tanítani?,Che cosa mi puoi insegnare?,何か教えてくれないか?,나에게 뭘 가르쳐 줄 수 있죠?,Wat kun je me leren?,Hva kan du lære meg?,Czego możesz mnie nauczyć?,O que você tem pra me ensinar?,,Ce mă poți învăța?,Чему ты можешь меня научить?,,Vad kan du lära mig?,Bana ne öğretebilirsin? +"Don't get snippy, you've still some room to grow.",TXT_RYES1_SCRIPT10_D33352_DONTG,〃 (〃),,,Nebuď moc domýšlivý; ještě se máš co učit.,"Du skal ikke blive snerpet, du har stadig plads til at vokse.","Werd nicht leichtsinnig, du kannst noch einiges dazulernen.",,,"No seas insolente, aún tienes mucho que aprender.",,"Äläs rupea nokkavaksi, sinulla on vielä kasvun varaa.","Ne faites pas l'orgeuilleux, vous avez encore de quoi apprendre.","Ne hordd úgy fennt az orrod, van még mit tanulnod.","Non essere brusco, ci sono ancora cose che puoi imparare.",ぶっきらぼうにならないで、まだ成長の余地はあります。,너무 자만하지 마세요. 아직 더 배울 게 많으니까.,"Wordt niet snipperig, je hebt nog wat ruimte om te groeien.","Ikke vær frekk, du har fortsatt litt å gå på.",Nie wychylaj się. Przed tobą jeszcze długa droga.,"Vai devagar, rapaz. Você ainda tem muito o que aprender.",,"Nu fi impetinent, încă mai ai ce învăța.",Не задирай нос. Тебе ещё есть куда расти.,,"Bli inte snäsig, du har fortfarande utrymme att växa.","Kibirlenme, hala büyümek için yerin var." +Nothing until you're ready.,TXT_RNO1_SCRIPT10_D33352_NOTHI,〃 (〃),,,"Nic, dokud nebudeš připraven.","Intet, før du er klar.","Nichts, bevor diu nicht bereit bist.",,,Nada hasta que estés listo.,,"Ei mitään, kunnes olet valmis.",Pas avant que vous ne soyez prêt.,"Semmi, míg nem állsz készen.","Nulla al momento, finché non sarai pronto",準備が整うまで何も出来ません。,준비가 안 된 것 같으니 나중에 배웁시다.,Niets totdat je er klaar voor bent.,Ingenting før du er klar.,Na razie nic póki nie jesteś gotowy.,Nada até que você esteja preparado.,,"Nimic, până nu ești pregătit.","Ничему, пока ты не готов.",,Ingenting förrän du är redo.,Hazır olana kadar hiçbir şey. "Look who's back, what's on your mind? I know it's been hard, but all of us appreciate your efforts, believe me.",TXT_DLG_SCRIPT10_D34868_LOOKW,〃 (four trainings),,,"No ne, kdopak to je? Jak se vede? Vím, že je to těžké, ale všichni si tě vážíme, věř mi.","Se, hvem der er tilbage. Hvad har du på hjerte? Jeg ved, det har været svært, men vi sætter alle pris på din indsats, tro mig.","Sieh mal an, wer zurück ist. Was gibt es? Ich weiß, es ist schwierig, aber wir alle wissen deine Arbeit zu würdigen, glaub mir.",,,"Mira quien ha vuelto, ¿Qué tienes en mente? Se que es duro, pero todos apreciamos tus esfuerzos, créeme.",,"Kukas se siinä; mitä on mielessäsi? Tiedän, että sinulla on ollut rankkaa, mutta uskothan, että me kaikki arvostamme vaivannäköäsi.","Regardez qui revient! Comment ça va? Je sais que les temps sont durs mais nous apprécions vos efforts, vraiment.","Nézzenek oda kit látnak szemeim, mi újság van veled? Tudom, hogy nem könnyű, de hidd el mindannyian értékeljük a fáradozásaidat.","Guarda chi si vede, a cosa stai pensando? Lo so che son tempi duri, ma noi tutti apprezziamo i tuoi sforzi, credimi.","誰が戻って来たかについて、貴方の考えとは? 困難な事だとわかっています。しかし私達全員は -貴方の努力には感謝しています。","다시 돌아오다니. 어쩐 일이십니까? 견디기 힘든 고역이었겠지만, 지금 당신은 우리들을 위해 잘 싸우고 계십니다. 믿어주세요!","Kijk eens wie er terug is, waar denk je aan? Ik weet dat het moeilijk is geweest, maar we waarderen allemaal je inspanningen, geloof me.","Se hvem som er tilbake. Hva har du på hjertet? Jeg vet at det har vært vanskelig, men vi setter pris på innsatsen din, tro meg.","Patrzcie, kto wrócił, co wam chodzi po głowie? Wiem, że było ciężko, ale wszyscy doceniamy twoje wysiłki, uwierz mi.","Olha só quem voltou. Como vai? Eu sei que tem sido difícil, mas todos nós agradecemos pelos seus esforços, vai por mim.",,"Uite cine s-a întors? La ce te gândești? Știu că a fost greu, dar toți îți apreciem eforturile, crede-mă.","Посмотрите-ка, кто вернулся. Что у тебя стряслось? Я знаю, твои задания сложны, но, поверь, мы все ценим твои усилия.",,"Bak kim gelmiş, aklında ne var? Zor olduğunu biliyorum ama hepimiz çabalarını takdir ediyoruz, inan bana." -I've run out of bullets.,TXT_RPLY0_SCRIPT10_D34868_IVERU,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for kugler.,Mir ist die Munition ausgegangen.,,,Me he quedado sin balas.,,Minulta on luodit loppu.,Je suis à court de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾が無くなった。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Skończyły mi się naboje.,Fiquei sem munição.,,Am rămas fără gloanțe.,Мне нужны патроны.,,Mermim bitti. -"What else is new, here you go.",TXT_RYES0_SCRIPT10_D34868_WHATE,〃 (〃),,,Něco jiného nového? Tady máš.,"Hvad er der ellers nyt, værsgo.",Kennen wir das nicht? Hier hast du welche.,,,"Que más es nuevo, aquí tienes.",,Olipas uutinen; kas tässä.,"Rien de nouveau, voilà pour vous.","Már meg sem lepődök, parancsolj.","Nulla di nuovo sotto il sole, ecco qua.",新しい試みですか、どうぞ。,여기 탄약. 그리고 더 필요한게?,"Wat is er nog meer nieuw, alsjeblieft.",Vær så god.,"Co jeszcze jest nowe, proszę bardzo.",Que novidade. Aqui está.,,"Ce mai e nou, iată.","Знаю, знаю. Вот, держи!",,"Başka yeni ne var, al bakalım." -You have more than I can give you.,TXT_RNO0_SCRIPT10_D34868_YOUHA,〃 (〃),,,"Máš víc, než kolik ti můžu dát.","Du har mere, end jeg kan give dig.","Du hast mehr, als ich dir geben könnte.",,,Tienes más de las que podría darte.,,Sinulla on enemmän kuin voin antaa.,Vous avez plus que je ne suis autorisé à vous donner.,"Több van nálad, mint amennyit tudnék adni.",Ne hai più di quante te ne possa dare.,今渡せる以上に持ってますよ。,내가 줄 수 있는 탄약의 양보다 큰데?,Je hebt meer dan ik je kan geven.,Du har mer enn jeg kan gi deg.,Masz więcej niż mogę ci dać.,Você tem o suficiente.,,Ai mai multe decât ți-aș putea oferi.,"Да у тебя их больше, чем на нашем складе.",,Sana verebileceğimden daha fazlasına sahipsin. -Teach me what you can.,TXT_RPLY1_SCRIPT10_D34868_TEACH,〃 (〃),,,"Uč mě, co můžeš.","Lær mig, hvad du kan.",Zeig mir was du weißt.,,,Enseñame lo que puedas.,,"Opeta minulle, mitä voit.",Enseignez-moi ce que vous pouvez.,Tanítsd meg amit tudsz.,Potresti insegnarmi ciò che puoi.,可能な限り教えてくれ。,가르칠 수 있는 걸 가르쳐주세요.,Leer me wat je kunt.,Lær meg det du kan.,"Naucz mnie tego, co potrafisz.",O que você pode me ensinar?,,Învață-mă ce poți.,"Научи меня, чему можешь.",,Bana öğretebileceğin kadarını öğret. -"All right, here's some pointers.",TXT_RYES1_SCRIPT10_D34868_ALLRI,〃 (〃),,,"Dobře, tady je pár tipů.","Okay, her er nogle tips.","Ok, ich erklär dir ein paar Tricks.",,,"Muy bien, aquí tienes unos consejos.",,"Hyvä on, tässä muutama vinkki.",Voilà deux ou trois trucs.,"Rendben, itt van pár tanács.","Va bene, ecco qualche dritta.",わかりました、貴方に幾つかやり方を教ましょう。,알겠습니다. 여기 과녁을 보여주지.,"Oké, hier zijn wat aanwijzingen.","Greit, her har du noen tips.","W porządku, oto kilka wskazówek.","Tá legal, aqui vai algumas dicas.",,"În regulă, uite niște repere.",Ну хорошо. Вот пара советов.,,"Pekala, işte birkaç ipucu." -Not right now.,TXT_RNO1_SCRIPT10_D34868_NOTRI,〃 (〃),,,Zrovna teď ne.,Ikke lige nu.,Nicht jetzt.,,Ne nun.,Ahora no.,,Ei juuri nyt.,Pas maintenant.,Most nem érek rá.,Non adesso.,今はまだです。,지금은 안 돼요.,Niet op dit moment.,Ikke akkurat nå.,Nie teraz.,Agora não.,,Nu chiar acum.,Не сейчас.,,Şimdi olmaz. +貴方の努力には感謝しています。","다시 돌아오다니. 어쩐 일이십니까? 견디기 힘든 고역이었겠지만, 지금 당신은 우리들을 위해 잘 싸우고 계십니다. 믿어주세요!","Kijk eens wie er terug is, waar denk je aan? Ik weet dat het moeilijk is geweest, maar we waarderen allemaal je inspanningen, geloof me.","Se hvem som er tilbake. Hva har du på hjertet? Jeg vet at det har vært vanskelig, men vi setter pris på innsatsen din, tro meg.","Patrzcie, kto wrócił, co wam chodzi po głowie? Wiem, że było ciężko, ale wszyscy doceniamy twoje wysiłki, uwierz mi.","Olha só quem voltou. Como vai? Eu sei que tem sido difícil, mas todos nós agradecemos pelos seus esforços, vai por mim.",,"Uite cine s-a întors? La ce te gândești? Știu că a fost greu, dar toți îți apreciem eforturile, crede-mă.","Посмотрите-ка, кто вернулся. Что у тебя стряслось? Я знаю, твои задания сложны, но, поверь, мы все ценим твои усилия.",,"Titta vem som är tillbaka, vad tänker du på? Jag vet att det har varit svårt, men alla uppskattar dina ansträngningar, tro mig.","Bak kim gelmiş, aklında ne var? Zor olduğunu biliyorum ama hepimiz çabalarını takdir ediyoruz, inan bana." +I've run out of bullets.,TXT_RPLY0_SCRIPT10_D34868_IVERU,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for kugler.,Mir ist die Munition ausgegangen.,,,Me he quedado sin balas.,,Minulta on luodit loppu.,Je suis à court de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾が無くなった。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Skończyły mi się naboje.,Fiquei sem munição.,,Am rămas fără gloanțe.,Мне нужны патроны.,,Jag har slut på kulor.,Mermim bitti. +"What else is new, here you go.",TXT_RYES0_SCRIPT10_D34868_WHATE,〃 (〃),,,Něco jiného nového? Tady máš.,"Hvad er der ellers nyt, værsgo.",Kennen wir das nicht? Hier hast du welche.,,,"Que más es nuevo, aquí tienes.",,Olipas uutinen; kas tässä.,"Rien de nouveau, voilà pour vous.","Már meg sem lepődök, parancsolj.","Nulla di nuovo sotto il sole, ecco qua.",新しい試みですか、どうぞ。,여기 탄약. 그리고 더 필요한게?,"Wat is er nog meer nieuw, alsjeblieft.",Vær så god.,"Co jeszcze jest nowe, proszę bardzo.",Que novidade. Aqui está.,,"Ce mai e nou, iată.","Знаю, знаю. Вот, держи!",,"Vad mer är nytt, här har du.","Başka yeni ne var, al bakalım." +You have more than I can give you.,TXT_RNO0_SCRIPT10_D34868_YOUHA,〃 (〃),,,"Máš víc, než kolik ti můžu dát.","Du har mere, end jeg kan give dig.","Du hast mehr, als ich dir geben könnte.",,,Tienes más de las que podría darte.,,Sinulla on enemmän kuin voin antaa.,Vous avez plus que je ne suis autorisé à vous donner.,"Több van nálad, mint amennyit tudnék adni.",Ne hai più di quante te ne possa dare.,今渡せる以上に持ってますよ。,내가 줄 수 있는 탄약의 양보다 큰데?,Je hebt meer dan ik je kan geven.,Du har mer enn jeg kan gi deg.,Masz więcej niż mogę ci dać.,Você tem o suficiente.,,Ai mai multe decât ți-aș putea oferi.,"Да у тебя их больше, чем на нашем складе.",,Du har mer än vad jag kan ge dig.,Sana verebileceğimden daha fazlasına sahipsin. +Teach me what you can.,TXT_RPLY1_SCRIPT10_D34868_TEACH,〃 (〃),,,"Uč mě, co můžeš.","Lær mig, hvad du kan.",Zeig mir was du weißt.,,,Enseñame lo que puedas.,,"Opeta minulle, mitä voit.",Enseignez-moi ce que vous pouvez.,Tanítsd meg amit tudsz.,Potresti insegnarmi ciò che puoi.,可能な限り教えてくれ。,가르칠 수 있는 걸 가르쳐주세요.,Leer me wat je kunt.,Lær meg det du kan.,"Naucz mnie tego, co potrafisz.",O que você pode me ensinar?,,Învață-mă ce poți.,"Научи меня, чему можешь.",,Lär mig vad du kan.,Bana öğretebileceğin kadarını öğret. +"All right, here's some pointers.",TXT_RYES1_SCRIPT10_D34868_ALLRI,〃 (〃),,,"Dobře, tady je pár tipů.","Okay, her er nogle tips.","Ok, ich erklär dir ein paar Tricks.",,,"Muy bien, aquí tienes unos consejos.",,"Hyvä on, tässä muutama vinkki.",Voilà deux ou trois trucs.,"Rendben, itt van pár tanács.","Va bene, ecco qualche dritta.",わかりました、貴方に幾つかやり方を教ましょう。,알겠습니다. 여기 과녁을 보여주지.,"Oké, hier zijn wat aanwijzingen.","Greit, her har du noen tips.","W porządku, oto kilka wskazówek.","Tá legal, aqui vai algumas dicas.",,"În regulă, uite niște repere.",Ну хорошо. Вот пара советов.,,"Okej, här är några tips.","Pekala, işte birkaç ipucu." +Not right now.,TXT_RNO1_SCRIPT10_D34868_NOTRI,〃 (〃),,,Zrovna teď ne.,Ikke lige nu.,Nicht jetzt.,,Ne nun.,Ahora no.,,Ei juuri nyt.,Pas maintenant.,Most nem érek rá.,Non adesso.,今はまだです。,지금은 안 돼요.,Niet op dit moment.,Ikke akkurat nå.,Nie teraz.,Agora não.,,Nu chiar acum.,Не сейчас.,,Inte just nu.,Şimdi olmaz. What is it you need? I hope that you're giving the Order a taste of the kind of pain that we have been feeling for years.,TXT_DLG_SCRIPT10_D36384_WHATI,〃 (five trainings),,,"Copak potřebuješ? Doufám, že oplácíš Řádu to, co nám celé ty roky dělali.","Hvad er det, du har brug for? Jeg håber, at du giver Ordenen en smagsprøve på den slags smerte, som vi har følt i årevis.","Was brauchst du? Ich hoffe, du gibst dem Orden etwas von dem Schmerz zurück, den sie und allen haben zukommen lassen.",,,¿Qué necesitas? Espero que le estés dando a la Orden un poco del tipo de dolor que hemos estado sufriendo durante años.,,"Mitä tarvitset? Toivottavasti annat Veljeskunnan maistaa sitä tuskaa, jota me olemme tunteneet vuosia.",De quoi avez-vous besoin? J'espère que vous donnez à l'Ordre une idée de la douleur que nous avons ressenti pendant des années.,"Miben segíthetek? Remélem megízlettetted a Rendet ugyanazzal a fájdalommal, amit mi éreztünk eddig.",Di che cosa hai bisogno? Spero che tu stia dando all'Ordine un assaggio del tipo di dolore che noi abbiamo tollerato per anni.,"必要な物は何ですか?私達が何年も前から感じた 多くの苦痛の味をオーダーに与えることを -願っています。",필요한 게 있습니까? 수 년 동안 고통을 안겨 온 오더 놈들에게 복수를 해줬으면 하는 바입니다. 끝날 때까지!,Wat heb je nodig? Ik hoop dat je de Orde een voorproefje geeft van het soort pijn dat we al jaren voelen.,Hva er det du trenger? Jeg håper du gir Ordenen en forsmak på den smerten vi har følt i årevis.,"Czego potrzebujesz? Mam nadzieję, że dajesz Zakonowi przedsmak bólu, który odczuwamy od lat.",O que está precisando? Espero que você esteja fazendo a Ordem sentir um pouco do sofrimento que nós estivemos passando por anos.,,De ce ai nevoie? Sper că îi dai Ordinului aceeași durere pe care și el ne-a oferit-o în toți acești ani.,"Что тебе нужно? Надеюсь, ты даёшь Ордену почувствовать ту боль, что мы терпели годами.",,Neye ihtiyacın var? Umarım Tarikat'a yıllardır hissettiğimiz acıyı tattırıyorsundur. -Some ammo.,TXT_RPLY0_SCRIPT10_D36384_SOMEA,〃 (〃),,,Nějakou munici.,Lidt ammunition.,Etwas Munition.,,,Algo de munición.,,Vähän ammuksia.,Des munitions.,Valamennyi lőszer.,Un poco di munizioni.,弾を幾つか。,탄약 좀...,Wat munitie.,Litt ammunisjon.,Trochę amunicji.,Um pouco de munição.,,Niște muniție.,Боеприпасы.,,Biraz cephane. -"There you go, don't waste it.",TXT_RYES0_SCRIPT10_D36384_THERE,〃 (〃),,,"Tady máš, neplýtvej s ní.","Værsgo, lad være med at spilde den.",Hier hast du welche. Verschwende sie nicht.,,Jen. Ne malŝparu ĝin.,"Toma, no las desperdicies.",,"Ole hyvä, älä tuhlaa niitä.",Voilà pour vous. Ne les gaspillez pas.,"Parancsolj, ne pazarold el.","Ecco delle munizioni, non sprecarle.",はいどうぞ、無駄にしないように。,전장을 자주 누비나 보군요. 여기 탄약!,"Daar ga je, verspil het niet.","Vær så god, ikke sløs den bort.","Proszę bardzo, nie marnuj jej.",Aqui está. Não desperdice.,,"Iată, n-o risipi.",Вот. Не трать их попусту.,,"Al bakalım, boşa harcama." -You've got enough ammo.,TXT_RNO0_SCRIPT10_D36384_YOUVE,〃 (〃),,,Máš jí dost.,Du har nok ammunition.,Du hast genug Munition.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ne hai a sufficienza.,弾は十分に見えます。,당신의 남은 탄약이 눈에 보이는군요. 줄 수 없습니다!,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz wystarczająco dużo amunicji.,Você tem munição suficiente.,,Ai destulă muniție.,У тебя хватает патронов.,,Yeterince cephanen var. -Teach me.,TXT_RPLY1_SCRIPT10_D36384_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. -A few more lessons and you'll know all that I can teach.,TXT_RYES1_SCRIPT10_D36384_AFEWM,〃 (〃),,,"Pár dalších lekcí a budeš vědět všechno, co vím.","Et par lektioner mere, og du vil vide alt, hvad jeg kan lære dig.","Ein paar mehr Lektionen, und du weißt alles, was ich weiß.",,,Unas cuantas lecciones más y sabrás todo lo que puedo enseñar.,,"Enää vain muutama oppitunti ja tiedät kaiken, mitä voin opettaa.",Quelque leçons en plus et vous saurez tout ce que je peux vous enseigner.,"Még pár lecke, és mindent tudni fogsz amit Én.",Tra un paio di lezioni saprai tutto quello che conosco.,もう少しで私の教えられる事が全てわかるはずです。,제가 가르칠 만한 훈련을 배우면 좀 똑똑해질 겁니다.,Nog een paar lessen en je weet alles wat ik je kan leren.,"Et par leksjoner til, så vet du alt jeg kan lære deg.","Jeszcze kilka lekcji i będziesz wiedział wszystko, czego mogę nauczyć.",Mais algumas aulas e você já saberá tudo o que consigo ensinar.,,"Câteva lecții, și vei știi tot ce știu si eu.","Ещё немного, и ты будешь знать всё, что знаю я.",,Birkaç ders daha ve öğretebileceğim her şeyi öğreneceksin. -You're not ready yet.,TXT_RNO1_SCRIPT10_D36384_YOURE,〃 (〃),,,Ještě nejsi připraven.,Du er ikke klar endnu.,Du bist noch nicht soweit.,,,Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Nem állsz még készen.,Non sei ancora pronto.,貴方の準備がまだ整ってないように思えます。,훈련받기엔 가깝지만서도... 먼 것 같습니다.,Je bent er nog niet klaar voor.,Du er ikke klar ennå.,Nie jesteś jeszcze gotowy.,Você ainda não está preparado.,,Nu ești pregătit încă.,Ты ещё не готов.,,Henüz hazır değilsin. +願っています。",필요한 게 있습니까? 수 년 동안 고통을 안겨 온 오더 놈들에게 복수를 해줬으면 하는 바입니다. 끝날 때까지!,Wat heb je nodig? Ik hoop dat je de Orde een voorproefje geeft van het soort pijn dat we al jaren voelen.,Hva er det du trenger? Jeg håper du gir Ordenen en forsmak på den smerten vi har følt i årevis.,"Czego potrzebujesz? Mam nadzieję, że dajesz Zakonowi przedsmak bólu, który odczuwamy od lat.",O que está precisando? Espero que você esteja fazendo a Ordem sentir um pouco do sofrimento que nós estivemos passando por anos.,,De ce ai nevoie? Sper că îi dai Ordinului aceeași durere pe care și el ne-a oferit-o în toți acești ani.,"Что тебе нужно? Надеюсь, ты даёшь Ордену почувствовать ту боль, что мы терпели годами.",,Vad är det du behöver? Jag hoppas att du ger Orden en smak av den typ av smärta som vi har känt i åratal.,Neye ihtiyacın var? Umarım Tarikat'a yıllardır hissettiğimiz acıyı tattırıyorsundur. +Some ammo.,TXT_RPLY0_SCRIPT10_D36384_SOMEA,〃 (〃),,,Nějakou munici.,Lidt ammunition.,Etwas Munition.,,,Algo de munición.,,Vähän ammuksia.,Des munitions.,Valamennyi lőszer.,Un poco di munizioni.,弾を幾つか。,탄약 좀...,Wat munitie.,Litt ammunisjon.,Trochę amunicji.,Um pouco de munição.,,Niște muniție.,Боеприпасы.,,Lite ammunition.,Biraz cephane. +"There you go, don't waste it.",TXT_RYES0_SCRIPT10_D36384_THERE,〃 (〃),,,"Tady máš, neplýtvej s ní.","Værsgo, lad være med at spilde den.",Hier hast du welche. Verschwende sie nicht.,,Jen. Ne malŝparu ĝin.,"Toma, no las desperdicies.",,"Ole hyvä, älä tuhlaa niitä.",Voilà pour vous. Ne les gaspillez pas.,"Parancsolj, ne pazarold el.","Ecco delle munizioni, non sprecarle.",はいどうぞ、無駄にしないように。,전장을 자주 누비나 보군요. 여기 탄약!,"Daar ga je, verspil het niet.","Vær så god, ikke sløs den bort.","Proszę bardzo, nie marnuj jej.",Aqui está. Não desperdice.,,"Iată, n-o risipi.",Вот. Не трать их попусту.,,"Varsågod, slösa inte bort den.","Al bakalım, boşa harcama." +You've got enough ammo.,TXT_RNO0_SCRIPT10_D36384_YOUVE,〃 (〃),,,Máš jí dost.,Du har nok ammunition.,Du hast genug Munition.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ne hai a sufficienza.,弾は十分に見えます。,당신의 남은 탄약이 눈에 보이는군요. 줄 수 없습니다!,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz wystarczająco dużo amunicji.,Você tem munição suficiente.,,Ai destulă muniție.,У тебя хватает патронов.,,Du har tillräckligt med ammunition.,Yeterince cephanen var. +Teach me.,TXT_RPLY1_SCRIPT10_D36384_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. +A few more lessons and you'll know all that I can teach.,TXT_RYES1_SCRIPT10_D36384_AFEWM,〃 (〃),,,"Pár dalších lekcí a budeš vědět všechno, co vím.","Et par lektioner mere, og du vil vide alt, hvad jeg kan lære dig.","Ein paar mehr Lektionen, und du weißt alles, was ich weiß.",,,Unas cuantas lecciones más y sabrás todo lo que puedo enseñar.,,"Enää vain muutama oppitunti ja tiedät kaiken, mitä voin opettaa.",Quelque leçons en plus et vous saurez tout ce que je peux vous enseigner.,"Még pár lecke, és mindent tudni fogsz amit Én.",Tra un paio di lezioni saprai tutto quello che conosco.,もう少しで私の教えられる事が全てわかるはずです。,제가 가르칠 만한 훈련을 배우면 좀 똑똑해질 겁니다.,Nog een paar lessen en je weet alles wat ik je kan leren.,"Et par leksjoner til, så vet du alt jeg kan lære deg.","Jeszcze kilka lekcji i będziesz wiedział wszystko, czego mogę nauczyć.",Mais algumas aulas e você já saberá tudo o que consigo ensinar.,,"Câteva lecții, și vei știi tot ce știu si eu.","Ещё немного, и ты будешь знать всё, что знаю я.",,Några lektioner till och du kommer att veta allt jag kan lära dig.,Birkaç ders daha ve öğretebileceğim her şeyi öğreneceksin. +You're not ready yet.,TXT_RNO1_SCRIPT10_D36384_YOURE,〃 (〃),,,Ještě nejsi připraven.,Du er ikke klar endnu.,Du bist noch nicht soweit.,,,Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Nem állsz még készen.,Non sei ancora pronto.,貴方の準備がまだ整ってないように思えます。,훈련받기엔 가깝지만서도... 먼 것 같습니다.,Je bent er nog niet klaar voor.,Du er ikke klar ennå.,Nie jesteś jeszcze gotowy.,Você ainda não está preparado.,,Nu ești pregătit încă.,Ты ещё не готов.,,Du är inte redo än.,Henüz hazır değilsin. "I can't believe that we're still around, you and I. There's just too many of us that have passed since the beginning. What can I do for you friend?",TXT_DLG_SCRIPT10_D37900_ICANT,〃 (six trainings),,,"Nemůžu uvěřit, že tu my dva stále ještě jsme. Hrozně moc z nás za tu dobu zahynulo. Co pro tebe mohu udělat, příteli?","Jeg kan ikke tro, at vi stadig er her, du og jeg. Der er bare for mange af os, der er gået siden begyndelsen. Hvad kan jeg gøre for dig, min ven?","Ich kann kaum glauben, dass wir immer noch da sind, du und ich. Es sind so viele, die uns verlassen haben, seit alles anfing. Was kann ich für dich tun, Freund?",,,"No puedo creer que sigamos aquí tú y yo. Hemos perdidos a tantos desde que todo empezó... ¿Qué puedo hacer por ti, amigo?",,"En voi uskoa, että olemme vielä kuvioissa, sinä ja minä. Aivan liian moni on poistunut keskuudestamme sitten, kun kaikki tämä alkoi. Miten voin olla avuksi, ystäväni?","J'arrive pas a croire que vous êtes toujours avec nous. Tellement de nos camarades ont disparu depuis que tout a commencé. Que puis-je faire pour vous, mon ami?","Nem hiszem el, hogy eddig túléltük ezt. Sokan vesztették életüket a kezdetek óta. Mit tehetek érted barátom?","Non posso credere che siamo ancora vivi, tu e io. Ce ne sono così tanti che sono morti da quando è iniziata questa faccenda. Che cosa posso fare per te, amico?","私達はまだ貴方の護衛をし続けられるとは 思えません。昔からの仲間は殆ど去って しまいました。貴方の友人の為に -何がしてあげられますか?",아직도 살아 숨 쉬고 있다니 믿기지 않네요... 당신이 싸우고 생존하는 동안 살아 돌아온 병사들은 그렇게 많지 않아요. 원하는 게 있습니까?,"Ik kan niet geloven dat we er nog steeds zijn, jij en ik. Er zijn er gewoon te veel van ons die sinds het begin zijn overleden. Wat kan ik voor je doen, vriend?","Jeg kan ikke tro at vi fortsatt er her, du og jeg. Det er for mange av oss som har gått bort siden begynnelsen. Hva kan jeg gjøre for deg, min venn?","Nie mogę uwierzyć, że jeszcze żyjemy, ty i ja. Zbyt wielu z nas przeszło od początku. Co mogę dla ciebie zrobić, przyjacielu?","Mal consigo acreditar que ainda estamos vivos, você e eu. Perdemos muitos companheiros desde o início. O que posso fazer por você, meu amigo?",,"Nu-mi vine că cred că încă mai rezistăm, tu și eu. Sunt prea mulți cei care au murit de la început. Ce pot face pentru tine, prietene?","Не могу поверить, что мы всё ещё живы, ты и я. За всё это время уже стольких из нас не стало. Что я могу сделать для тебя, дружище?",,"Hala buralarda olduğumuza inanamıyorum, sen ve ben. Başlangıçtan bu yana çok fazla insan geçti. Senin için ne yapabilirim dostum?" -I'm out of bullets.,TXT_RPLY0_SCRIPT10_D37900_IMOUT,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Minulta on luodit loppu.,Je suis à court de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Skończyły mi się kule.,Estou sem munição.,,Nu mai am gloanțe.,У меня кончились патроны.,,Mermim bitti. +何がしてあげられますか?",아직도 살아 숨 쉬고 있다니 믿기지 않네요... 당신이 싸우고 생존하는 동안 살아 돌아온 병사들은 그렇게 많지 않아요. 원하는 게 있습니까?,"Ik kan niet geloven dat we er nog steeds zijn, jij en ik. Er zijn er gewoon te veel van ons die sinds het begin zijn overleden. Wat kan ik voor je doen, vriend?","Jeg kan ikke tro at vi fortsatt er her, du og jeg. Det er for mange av oss som har gått bort siden begynnelsen. Hva kan jeg gjøre for deg, min venn?","Nie mogę uwierzyć, że jeszcze żyjemy, ty i ja. Zbyt wielu z nas przeszło od początku. Co mogę dla ciebie zrobić, przyjacielu?","Mal consigo acreditar que ainda estamos vivos, você e eu. Perdemos muitos companheiros desde o início. O que posso fazer por você, meu amigo?",,"Nu-mi vine că cred că încă mai rezistăm, tu și eu. Sunt prea mulți cei care au murit de la început. Ce pot face pentru tine, prietene?","Не могу поверить, что мы всё ещё живы, ты и я. За всё это время уже стольких из нас не стало. Что я могу сделать для тебя, дружище?",,"Jag kan inte tro att vi fortfarande finns kvar, du och jag. Det är bara för många av oss som har passerat sedan början. Vad kan jag göra för dig, min vän?","Hala buralarda olduğumuza inanamıyorum, sen ve ben. Başlangıçtan bu yana çok fazla insan geçti. Senin için ne yapabilirim dostum?" +I'm out of bullets.,TXT_RPLY0_SCRIPT10_D37900_IMOUT,〃 (〃),,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Minulta on luodit loppu.,Je suis à court de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Skończyły mi się kule.,Estou sem munição.,,Nu mai am gloanțe.,У меня кончились патроны.,,Jag har slut på kulor.,Mermim bitti. "Here, use them to keep you in good health.",TXT_RYES0_SCRIPT10_D37900_HEREU,"〃 (〃) (in good health = enjoy)",,,"Tady, používej je, abys zůstal ve zdraví.","Her, brug dem til at holde dig sund og rask.","Hier, benutze sie um gesund zu bleiben,",,"Jen iom da municio. Ŝancon kaj ĝuu ĝin.","Aquí tienes algo de munición. -Suerte y disfrútala.",,"Tässä, pidä niillä itsesi terveenä.","Voilà, gardez vous en bonne santé.","Parancsolj, használd őket az egészséged érdekében.","Ecco qua, usale per tenerti in buona salute.",どうぞ、これで体の調子を保って下さい。,건강하고 집중됬을 때 소모하시길.,"Hier, gebruik ze om je in goede gezondheid te houden.","Her, bruk dem til å holde deg ved god helse.","Użyj ich, by utrzymać cię w dobrym zdrowiu.",Pode pegar. Use essa munição para se manter saudável.,,"Aici, folosește-le ca să te menții în formă.","Вот. Используй их, чтобы сохранить себя.",,"Al, onları sağlığını korumak için kullan." -You have enough.,TXT_RNO0_SCRIPT10_D37900_YOUHA,〃 (〃),,,Máš jich dost.,Du har nok.,Du hast genug.,,Vi havas sufiĉe.,Tienes suficientes.,,Sinulla on tarpeeksi.,Vous en avez assez.,Van elég.,Ne hai a sufficienza.,十分に持っています。,충분히 있으면 더 안 줘요.,Je hebt genoeg.,Du har nok.,Masz wystarczająco dużo.,Você tem o suficiente.,,Ai destule.,Тебе хватает.,,Sende yeterince var. -Teach me.,TXT_RPLY1_SCRIPT10_D37900_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. -"Well, that's it, you're done. I can teach no more.",TXT_RYES1_SCRIPT10_D37900_WELLT,〃 (〃),,,"Tak, a je to, jsme hotovi. Víc tě naučit nemůžu.","Nå, det var det, du er færdig. Jeg kan ikke undervise mere.","So, das war's. Ich kann dir nicht mehr beibringen.",,,"Bueno, eso es todo, estás listo. No tengo más que enseñar.",,"No, se oli siinä, olet valmis. Minulla ei ole sinulle enää opetettavaa.","Eh bien, voilà. Vous savez tout. Je n'ai rien de plus pour vous!","Elérkeztünk oda, hogy nem tudok többet tanítani neked.","Beh, ecco fatto, oramai hai concluso. Non c'è null'altro che ti possa insegnare.",これで全てです。これ以上は教える事がありません。,"흐음, 이게 다입니다. 훈련을 다 마쳤어요.","Nou, dat is het dan, je bent klaar. Ik kan geen les meer geven.","Vel, det var det, du er ferdig. Jeg kan ikke lære deg mer.","No cóż, to już koniec. Nie mogę więcej uczyć.","Bom, é isso. Você já sabe de tudo. Não consigo ensinar mais nada.",,"Asta e, gata, nu mai am ce să te învăț.","Что ж, это всё. Твоё обучение закончено. Больше я ничему не могу тебя научить.",,"Pekala, bu kadar, işin bitti. Daha fazla öğretemem." -Return after Macil tells you it's time.,TXT_RNO1_SCRIPT10_D37900_RETUR,〃 (〃),,,"Vrať se až ti Macil řekne, že je čas.","Vend tilbage, når Macil siger, at det er tid.","Komm wieder, wenn Macil sagt, dass es Zeit ist.",,,Vuelve cuando Macil diga que es la hora.,,"Palaa sitten, kun Macil kertoo sinulle ajan koittaneen.",Revenez quand Macil vous dit qu'il est temps.,"Ha Macil szól hogy idő van, akkor fordulj vissza.",Ritorna quando Macil dice che è arrivato il momento.,マシルに許可を貰わないとなりません。,사령관님의 말씀을 듣고 찾아와주시길.,Keer terug nadat Macil je vertelt dat het tijd is.,Kom tilbake når Macil sier det er på tide.,"Wróć, gdy Macil powie ci, że już czas.",Volte depois que Macil te disser que está na hora.,,Întoarce-te după ce Macil îți spune că e vremea.,"Возвращайся, когда скажет Мэйсил.",,Macil sana zamanın geldiğini söylediğinde geri dön. +Suerte y disfrútala.",,"Tässä, pidä niillä itsesi terveenä.","Voilà, gardez vous en bonne santé.","Parancsolj, használd őket az egészséged érdekében.","Ecco qua, usale per tenerti in buona salute.",どうぞ、これで体の調子を保って下さい。,건강하고 집중됬을 때 소모하시길.,"Hier, gebruik ze om je in goede gezondheid te houden.","Her, bruk dem til å holde deg ved god helse.","Użyj ich, by utrzymać cię w dobrym zdrowiu.",Pode pegar. Use essa munição para se manter saudável.,,"Aici, folosește-le ca să te menții în formă.","Вот. Используй их, чтобы сохранить себя.",,"Här, använd dem för att hålla dig vid god hälsa.","Al, onları sağlığını korumak için kullan." +You have enough.,TXT_RNO0_SCRIPT10_D37900_YOUHA,〃 (〃),,,Máš jich dost.,Du har nok.,Du hast genug.,,Vi havas sufiĉe.,Tienes suficientes.,,Sinulla on tarpeeksi.,Vous en avez assez.,Van elég.,Ne hai a sufficienza.,十分に持っています。,충분히 있으면 더 안 줘요.,Je hebt genoeg.,Du har nok.,Masz wystarczająco dużo.,Você tem o suficiente.,,Ai destule.,Тебе хватает.,,Du har tillräckligt.,Sende yeterince var. +Teach me.,TXT_RPLY1_SCRIPT10_D37900_TEACH,〃 (〃),,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Mutasd meg.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. +"Well, that's it, you're done. I can teach no more.",TXT_RYES1_SCRIPT10_D37900_WELLT,〃 (〃),,,"Tak, a je to, jsme hotovi. Víc tě naučit nemůžu.","Nå, det var det, du er færdig. Jeg kan ikke undervise mere.","So, das war's. Ich kann dir nicht mehr beibringen.",,,"Bueno, eso es todo, estás listo. No tengo más que enseñar.",,"No, se oli siinä, olet valmis. Minulla ei ole sinulle enää opetettavaa.","Eh bien, voilà. Vous savez tout. Je n'ai rien de plus pour vous!","Elérkeztünk oda, hogy nem tudok többet tanítani neked.","Beh, ecco fatto, oramai hai concluso. Non c'è null'altro che ti possa insegnare.",これで全てです。これ以上は教える事がありません。,"흐음, 이게 다입니다. 훈련을 다 마쳤어요.","Nou, dat is het dan, je bent klaar. Ik kan geen les meer geven.","Vel, det var det, du er ferdig. Jeg kan ikke lære deg mer.","No cóż, to już koniec. Nie mogę więcej uczyć.","Bom, é isso. Você já sabe de tudo. Não consigo ensinar mais nada.",,"Asta e, gata, nu mai am ce să te învăț.","Что ж, это всё. Твоё обучение закончено. Больше я ничему не могу тебя научить.",,"Det var det, du är klar. Jag kan inte undervisa mer.","Pekala, bu kadar, işin bitti. Daha fazla öğretemem." +Return after Macil tells you it's time.,TXT_RNO1_SCRIPT10_D37900_RETUR,〃 (〃),,,"Vrať se až ti Macil řekne, že je čas.","Vend tilbage, når Macil siger, at det er tid.","Komm wieder, wenn Macil sagt, dass es Zeit ist.",,,Vuelve cuando Macil diga que es la hora.,,"Palaa sitten, kun Macil kertoo sinulle ajan koittaneen.",Revenez quand Macil vous dit qu'il est temps.,"Ha Macil szól hogy idő van, akkor fordulj vissza.",Ritorna quando Macil dice che è arrivato il momento.,マシルに許可を貰わないとなりません。,사령관님의 말씀을 듣고 찾아와주시길.,Keer terug nadat Macil je vertelt dat het tijd is.,Kom tilbake når Macil sier det er på tide.,"Wróć, gdy Macil powie ci, że już czas.",Volte depois que Macil te disser que está na hora.,,Întoarce-te după ce Macil îți spune că e vremea.,"Возвращайся, когда скажет Мэйсил.",,Återvänd när Macil säger att det är dags.,Macil sana zamanın geldiğini söylediğinde geri dön. "I've taught you everything I can right now. I've given you all that you should ever need, unless you're out of bullets. Those I can still help you with.",TXT_DLG_SCRIPT10_D39416_IVETA,〃 (seven trainings),,,"Naučil jsem tě vše, co teď můžu. Dal jsem ti vše, co bys měl potřebovat, ledaže by ti došly náboje. S těmi ti stále můžu pomoci.","Jeg har lært dig alt, hvad jeg kan lige nu. Jeg har givet dig alt, hvad du nogensinde skulle få brug for, medmindre du er løbet tør for kugler. Dem kan jeg stadig hjælpe dig med.","Ich habe dir alles beigebracht, was ich weiß. Das sollte alles sein, was du brauchen wirst, es sei denn, du brauchst wieder mal Munition. Damit kann ich dir jederzeit helfen.",,,"Te he enseñado todo lo que puedo por ahora. Te he dado todo lo que puedas necesitar, a menos que te hayas quedado sin balas. Con eso si que te puedo ayudar todavía.",,"Olen opettanut sinulle kaiken osaamani. Olen antanut sinulle kaiken, mitä ikinä voisit tarvita, ellei sinulta sitten ole luodit loppu. Niiden suhteen voin vielä olla avuksi.","Je vous ai enseigné tout ce que je sais, et tout ce qu'il vous faudra, sauf si n'avez plus de munitions.. Et je peux vous aider pour ça, aussi.","Megtanítottam neked mindent amire most képes vagyok. Mindent megadtam neked amire valaha szükséged lehet, kivétel persze ha kifogysz a golyókból. Azt még mindig tudok adni.","Ti ho insegnato tutto quello che conosco. Ti ho dato tutto ciò di cui avrai mai bisogno, a meno che non hai finito le munizioni. Con quelle ti posso ancora essere d'aiuto.","私が教えられる事はもうありません。 今後新しい武器は時間が掛かるが自分のペースで -学びなさい。弾切れでなければの話ですが。",모든 훈련을 배우고 마치셨잖아요. 당신이 알아둬야 할 건 그게 전부입니다. 그 외에는 탄약이 필요하신가요?,"Ik heb je nu alles geleerd wat ik kan. Ik heb je alles gegeven wat je ooit nodig zou moeten hebben, tenzij je geen kogels meer hebt. Degenen waarmee ik je nog steeds kan helpen.","Jeg har lært deg alt jeg kan akkurat nå. Jeg har gitt deg alt du trenger, med mindre du er tom for kuler. De kan jeg fortsatt hjelpe deg med.","Nauczyłem cię wszystkiego, co mogę teraz. Dałem ci wszystko, co powinno ci być potrzebne, chyba że zabraknie ci naboi. Z tymi mogę ci jeszcze pomóc.","Eu te ensinei tudo o que eu consigo neste momento. Já te passei tudo o que você pode precisar, a não ser que esteja sem munição. Ainda posso te ajudar com isso.",,"Te-am învățat tot ce știu pentru moment. Ți-am dat tot ceea ce ai putea avea avea nevoie vreodată, decât dacă nu ai rămas cumva fără gloanțe. Cu astea te pot ajuta încă.","Я обучил тебя всему, что умею сам. Всему, что тебе может когда-нибудь пригодиться. Больше я ничем не могу тебе помочь... если, конечно, у тебя патроны не кончились.",,Şu anda sana öğretebileceğim her şeyi öğrettim. Mermin bitmediği sürece ihtiyacın olan her şeyi verdim. Onlar için sana hala yardım edebilirim. -Yes I am.,TXT_RPLY0_SCRIPT10_D39416_YESIA,〃 (〃),,,"Ano, došly.","Ja, det er jeg.","Ja, bin ich.",,Vi trafis.,Has acertado.,Acertaste.,Kyllä on.,"Oui, j'en ai besoin.",Igen.,"Sì, ho bisogno di munizioni.",ああ、そうだ。,알겠습니다. 그럼 탄약이라도?,"Ja, dat ben ik wel.","Ja, det er jeg.","Tak, jestem.",Estou mesmo.,,Da sunt.,"Да, кончились.",,"Evet, ediyorum." -Here you go. ,TXT_RYES0_SCRIPT10_D39416_HEREY,〃 (〃),,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,Ole hyvä.,Voilà pour vous.,Parancsolj.,Ecco a te.,どうぞ。,탄약 대령이요!,Alsjeblieft.,Vær så god.,Proszę bardzo.,Aqui está.,,Iată.,Держи.,,Al bakalım. +学びなさい。弾切れでなければの話ですが。",모든 훈련을 배우고 마치셨잖아요. 당신이 알아둬야 할 건 그게 전부입니다. 그 외에는 탄약이 필요하신가요?,"Ik heb je nu alles geleerd wat ik kan. Ik heb je alles gegeven wat je ooit nodig zou moeten hebben, tenzij je geen kogels meer hebt. Degenen waarmee ik je nog steeds kan helpen.","Jeg har lært deg alt jeg kan akkurat nå. Jeg har gitt deg alt du trenger, med mindre du er tom for kuler. De kan jeg fortsatt hjelpe deg med.","Nauczyłem cię wszystkiego, co mogę teraz. Dałem ci wszystko, co powinno ci być potrzebne, chyba że zabraknie ci naboi. Z tymi mogę ci jeszcze pomóc.","Eu te ensinei tudo o que eu consigo neste momento. Já te passei tudo o que você pode precisar, a não ser que esteja sem munição. Ainda posso te ajudar com isso.",,"Te-am învățat tot ce știu pentru moment. Ți-am dat tot ceea ce ai putea avea avea nevoie vreodată, decât dacă nu ai rămas cumva fără gloanțe. Cu astea te pot ajuta încă.","Я обучил тебя всему, что умею сам. Всему, что тебе может когда-нибудь пригодиться. Больше я ничем не могу тебе помочь... если, конечно, у тебя патроны не кончились.",,"Jag har lärt dig allt jag kan just nu. Jag har gett dig allt du någonsin skulle behöva, om du inte har slut på kulor. De kan jag fortfarande hjälpa dig med.",Şu anda sana öğretebileceğim her şeyi öğrettim. Mermin bitmediği sürece ihtiyacın olan her şeyi verdim. Onlar için sana hala yardım edebilirim. +Yes I am.,TXT_RPLY0_SCRIPT10_D39416_YESIA,〃 (〃),,,"Ano, došly.","Ja, det er jeg.","Ja, bin ich.",,Vi trafis.,Has acertado.,Acertaste.,Kyllä on.,"Oui, j'en ai besoin.",Igen.,"Sì, ho bisogno di munizioni.",ああ、そうだ。,알겠습니다. 그럼 탄약이라도?,"Ja, dat ben ik wel.","Ja, det er jeg.","Tak, jestem.",Estou mesmo.,,Da sunt.,"Да, кончились.",,"Ja, det gör jag.","Evet, ediyorum." +Here you go. ,TXT_RYES0_SCRIPT10_D39416_HEREY,〃 (〃),,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,Ole hyvä.,Voilà pour vous.,Parancsolj.,Ecco a te.,どうぞ。,탄약 대령이요!,Alsjeblieft.,Vær så god.,Proszę bardzo.,Aqui está.,,Iată.,Держи.,,Här har du.,Al bakalım. "Check out what's new, the teleporter beacon. When you use the beacon, we'll track the signal and send help. Is there something I can get you?",TXT_DLG_SCRIPT10_D40932_CHECK,MAP10: Justin.,,,"Podívej se na tohle, teleportační maják. Když ho použiješ, vystopujeme jeho signál a pošleme pomoc. Co ti můžu nabídnout?","Se det nye, teleporterfyret. Når du bruger fyret, sporer vi signalet og sender hjælp. Er der noget, jeg kan skaffe dig?","Sieh mal, was ich Neues habe, das Teleportersignal. Wenn du es benutzt können wir das Signal anpeilen und dir Hilfe schicken. Gibt es sonst was, was ich tun kann?",,,"Mira qué novedad, el faro de teletransporte. Cuando uses el faro, trazaremos la señal y enviaremos ayuda. ¿Hay algo que pueda ofrecerte?",,"Vilkaisepa tätä uutta kaukosiirrinmajakkaa. Kun käytät majakkaa, jäljitämme signaalin ja lähetämme apua. Saisiko sinulle olla jotain?","Regardez ce qu'on vient de sortir: L'antenne de téléporteur. Quand vous l'utilisez, on traque le signal et on envoie des renforts. Que puis-je faire pour vous?","Nézdd csak mit újítottunk be, egy teleport követőt. Amikor aktiválod, behatároljuk a jelet és kiküldjük a segítséget. Segítségedre lehetek még valamiben?","Guarda un pò questo nuovo aggeggio, il radiofaro per teletrasporto. Quando lo usi, identificheremo il tuo segnale e mandaremo rinforzi. C'è qualcosa che ti posso dare?","何を見つけたと思う、テレポータービーコンだ。 ビーコンを使用すると信号を追跡して増援を送る -ことができるぞ。必要な物はあるか?","이 녀석을 확인해보세요! 텔레포터 비컨이라는 건데, 사용해서 신호를 전송하면 병력을 보내겠습니다. 그 외에 원하는 게 있어요?","Kijk eens wat er nieuw is, het teleporterbaken. Als je het baken gebruikt, volgen we het signaal en sturen we hulp. Is er iets dat ik je kan krijgen?","Se hva som er nytt, teleportersignalet. Når du bruker den, sporer vi signalet og sender hjelp. Er det noe jeg kan hente til deg?","Zobaczcie, co nowego - teleporter. Kiedy użyjesz nadajnika, namierzymy sygnał i wyślemy pomoc. Czy jest coś, co mogę ci dać?","Veja só esta novidade, o sinalizador de teletransporte. Quando você usa o sinalizador, nós rastreamos o sinal e enviamos reforços. Posso te ajudar com alguma coisa?",,"Iată ce e nou, un far. Când folosești farul, ne ghidăm după el și trimitem întăriri. E ceva ce ți-aș putea aduce?","Посмотри на эту новинку: телепортационный маяк. Когда ты его включишь, мы проследим сигнал и вышлем подмогу. Итак, что я могу тебе предложить?",,"Yeni olan şeye bak, ışınlayıcı işaret. İşareti kullandığında, sinyali takip edip yardım göndereceğiz. Size getirebileceğim bir şey var mı?" -Box of rockets,TXT_RPLY0_SCRIPT10_D40932_BOXOF,〃,,,Bednu raket,En kasse med raketter,Kiste Raketen.,,,Caja de cohetes.,,Rakettilaatikko.,Boîte de roquettes.,Egy doboz rakéta kellene.,Cassa di razzi,ロケット箱,미니 미사일 한 박스,Doos met raketten,En eske med raketter.,Pudełko z rakietami,Caixa de foguetes,,Cutie de rachete.,Коробку ракет,,Roket kutusu -There you go.,TXT_RYES0_SCRIPT10_D40932_THERE,〃,,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Ahí tienes.,,Ole hyvä.,Voilà pour vous.,Parancsolj.,Ecco a te.,はい、どうぞ。,여기 있어!,Daar ga je.,Vær så god.,No i proszę.,Aqui está.,,Iată.,Бери.,,Al bakalım. -You can't afford that!,TXT_RNO0_SCRIPT10_D40932_YOUCA,〃,,,Tu si nemůžeš dovolit!,Det har du ikke råd til!,Das kannst du dir nicht leisten.,,,¡No puedes adquirir eso!,,Sinulla ei ole siihen varaa!,Vous n'avez pas assez d'argent.,Arra neked aztán nem tellik.,Non hai abbastanza soldi.,買うだけの余裕が無い!,돈이 부족한 것 같은데!,Dat kan je je niet betalen!,Det har du ikke råd til!,Nie stać cię na to!,Você não pode comprar isto!,,Nu-ți poți permite asta!,Ты не можешь себе этого позволить!,,Bunu karşılayamazsın! -H-E grenades.,TXT_RPLY1_SCRIPT10_D40932_HEGRE,〃,,,Výbušné granáty,H-E granater.,HE-Granaten.,,,Granadas HE.,,Räjähdekranaatteja.,Grenades explosives.,Robbanó gránátot.,Granate ad alto potenziale esplosivo,HEグレネード,고폭 유탄,H-E-granaten.,H-E-granater.,Granaty H-E.,Granadas explosivas.,,Grenade.,Осколочные гранаты,,H-E el bombaları. -Here you go.,TXT_RYES1_SCRIPT10_D40932_HEREY,〃,,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,Ole hyvä.,Voilà pour vous.,Parancsolj.,Eccole qua.,どうぞ。,거래 감사드립니다!,Alsjeblieft.,Vær så god.,Proszę bardzo.,Aqui está.,,Iată.,Держи.,,Al bakalım. -Come back when you have enough money.,TXT_RNO1_SCRIPT10_D40932_COMEB,〃,,,Vrať se až budeš mít dost peněz.,"Kom tilbage, når du har penge nok.","Komm wieder, wenn du genug Gold hast.",,,Vuelve cuando tengas suficiente dinero.,,"Palataan asiaan sitten, kun sinulla on riittävästi rahaa.",Revenez quand vous avez assez d'argent.,"Gyere vissza, ha már van elég pénzed.",Ritorna quando avrai i soldi.,十分持ってたらまた来い。,돈이 충분할 때 다시와요.,Kom terug als je genoeg geld hebt.,Kom tilbake når du har nok penger.,"Wróć, gdy będziesz miał wystarczająco dużo pieniędzy.",Volte quando tiver dinheiro suficiente.,,Întoarce-te când ai destui bani.,"Возвращайся, когда у тебя будут деньги.",,Yeterli paran olduğunda geri gel. -Energy pod,TXT_RPLY2_SCRIPT10_D40932_ENERG,〃,,,Energetický kokón,Energibælg,Energiezelle.,,,Vaina de energía,,Energia-akku.,Cellule énergétique.,Energia cella.,Nucleo energetico,エネルギーポッド,에너지 포드,Energiecapsule,Energikapsel,Statyw energetyczny.,Célula de energia.,,Capsulă energetică.,Энергоячейку,,Enerji kapsülü -Here's your energy pod,TXT_RYES2_SCRIPT10_D40932_HERES,〃,,,Tady ho máš.,Her er din energibælg.,Hier hast du deine Energiezele.,,,Aquí tienes tu vaina de energía,,Tässä energia-akkusi.,Voilà votre cellule.,Itt van az energia cellád.,Ecco il tuo nucleo energetico.,これがエネルギーポッドだ。,에너지 포드 한 개 대령이요!,Hier is je energiecapsule...,Her er energikapselen din.,Oto twój pojemnik na energię.,Aqui está a sua célula de energia.,,Iată capsula energetică.,Вот твоя энергоячейка.,,İşte enerji kapsülün. -You don't have enough for that.,TXT_RNO2_SCRIPT10_D40932_YOUDO,〃,,,Na ten nemáš dost.,Du har ikke nok til det.,"Nein, du hast nicht genug Gold dafür.",,,No tienes suficiente para eso.,,Sinulla ei ole tarpeeksi sitä varten.,Vous n'avez pas assez d'argent pour ça.,"Nincs elég nálad, hogy megvedd.",Non hai abbastanza soldi per quello.,それでは足りない。,이 물품은 비싸죠. 저도 압니다.,Daar heb je niet genoeg voor.,Du har ikke nok til det.,Nie masz na to wystarczająco dużo.,Você não tem o suficiente para isto.,,Nu ai suficiente fonduri pentru asta.,У тебя недостаточно денег.,,Bunun için yeterince paran yok. -Teleporter beacon,TXT_RPLY3_SCRIPT10_D40932_TELEP,〃,,,Teleportační maják,Teleportørfyr,Teleportersignal.,,,Faro de teletransporte,,Kaukosiirrinmajakka,Antenne de téléporteur.,Teleport követő,Radiofaro per teletrasporto.,テレポータービーコン,텔레포터 비콘,Teleporter baken,Teleporteringssignal,Teleporter beacon,Sinalizador de teletransporte,,Far pentru teleportare.,Телепортационный маяк,,Işınlayıcı işaretçisi -"Help, when and where you need it.",TXT_RYES3_SCRIPT10_D40932_HELPW,〃,,,Pomoc kdekoliv a kdykoliv je třeba.,"Hjælp, når og hvor du har brug for det.","Hilfe, wenn und wo sie gebraucht wird.",,,"Ayuda, cuando y donde la necesites.",,"Apua, missä ja milloin ikinä tarvitsetkaan.","De l'aide, quand il vous en faut.","Segítség, amikor és ahol akarod.",Con questo riceverai aiuto dove e quando ti servirà.,助けが必要になったら使うんだ。,위급한 상황에서만 사용하시길.,"Help, waar en wanneer je het nodig hebt.","Hjelp, når og hvor du trenger det.","Pomoc, kiedy i gdzie jej potrzebujesz.","Reforços, quando e onde você precisar.",,"Ajutor, acolo și când ai nevoie de el.",Теперь ты сможешь получить помощь всегда и везде.,,İhtiyacınız olduğu zaman ve yerde yardım. -"Sorry, no charity.",TXT_RNO3_SCRIPT10_D40932_SORRY,〃,,,"Promiň, nejsme charita.","Beklager, ingen velgørenhed.","Tut mir leid, wir sind keine Wohltätigkeitsveranstaltung.",,,"Lo siento, no es caridad.",,"Valitan, ei hyväntekeväisyyttä.","Désolé, on n'est pas une charité.","Sajnálom, ez nem jótékonyság.","Mi spiace, ma niente beneficienza.",すまない、チャリティーじゃないんだ。,"미안하지만, 여긴 자선단체가 아니에요.","Sorry, geen liefdadigheid.","Beklager, ingen veldedighet.","Przykro mi, ale nie ma mowy o dobroczynności.","Sinto muito, mas não fazemos caridade.",,"Scuze, nu e caritate.",Прости. Никакой благотворительности.,,"Üzgünüm, hayırseverlik yok." +ことができるぞ。必要な物はあるか?","이 녀석을 확인해보세요! 텔레포터 비컨이라는 건데, 사용해서 신호를 전송하면 병력을 보내겠습니다. 그 외에 원하는 게 있어요?","Kijk eens wat er nieuw is, het teleporterbaken. Als je het baken gebruikt, volgen we het signaal en sturen we hulp. Is er iets dat ik je kan krijgen?","Se hva som er nytt, teleportersignalet. Når du bruker den, sporer vi signalet og sender hjelp. Er det noe jeg kan hente til deg?","Zobaczcie, co nowego - teleporter. Kiedy użyjesz nadajnika, namierzymy sygnał i wyślemy pomoc. Czy jest coś, co mogę ci dać?","Veja só esta novidade, o sinalizador de teletransporte. Quando você usa o sinalizador, nós rastreamos o sinal e enviamos reforços. Posso te ajudar com alguma coisa?",,"Iată ce e nou, un far. Când folosești farul, ne ghidăm după el și trimitem întăriri. E ceva ce ți-aș putea aduce?","Посмотри на эту новинку: телепортационный маяк. Когда ты его включишь, мы проследим сигнал и вышлем подмогу. Итак, что я могу тебе предложить?",,"Kolla in vad som är nytt, teleporterfyren. När du använder fyren spårar vi signalen och skickar hjälp. Finns det något jag kan ge dig?","Yeni olan şeye bak, ışınlayıcı işaret. İşareti kullandığında, sinyali takip edip yardım göndereceğiz. Size getirebileceğim bir şey var mı?" +Box of rockets,TXT_RPLY0_SCRIPT10_D40932_BOXOF,〃,,,Bednu raket,En kasse med raketter,Kiste Raketen.,,,Caja de cohetes.,,Rakettilaatikko.,Boîte de roquettes.,Egy doboz rakéta kellene.,Cassa di razzi,ロケット箱,미니 미사일 한 박스,Doos met raketten,En eske med raketter.,Pudełko z rakietami,Caixa de foguetes,,Cutie de rachete.,Коробку ракет,,En låda med raketer.,Roket kutusu +There you go.,TXT_RYES0_SCRIPT10_D40932_THERE,〃,,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Ahí tienes.,,Ole hyvä.,Voilà pour vous.,Parancsolj.,Ecco a te.,はい、どうぞ。,여기 있어!,Daar ga je.,Vær så god.,No i proszę.,Aqui está.,,Iată.,Бери.,,Här har du.,Al bakalım. +You can't afford that!,TXT_RNO0_SCRIPT10_D40932_YOUCA,〃,,,Tu si nemůžeš dovolit!,Det har du ikke råd til!,Das kannst du dir nicht leisten.,,,¡No puedes adquirir eso!,,Sinulla ei ole siihen varaa!,Vous n'avez pas assez d'argent.,Arra neked aztán nem tellik.,Non hai abbastanza soldi.,買うだけの余裕が無い!,돈이 부족한 것 같은데!,Dat kan je je niet betalen!,Det har du ikke råd til!,Nie stać cię na to!,Você não pode comprar isto!,,Nu-ți poți permite asta!,Ты не можешь себе этого позволить!,,Du har inte råd med det!,Bunu karşılayamazsın! +H-E grenades.,TXT_RPLY1_SCRIPT10_D40932_HEGRE,〃,,,Výbušné granáty,H-E granater.,HE-Granaten.,,,Granadas HE.,,Räjähdekranaatteja.,Grenades explosives.,Robbanó gránátot.,Granate ad alto potenziale esplosivo,HEグレネード,고폭 유탄,H-E-granaten.,H-E-granater.,Granaty H-E.,Granadas explosivas.,,Grenade.,Осколочные гранаты,,H-E-granater.,H-E el bombaları. +Here you go.,TXT_RYES1_SCRIPT10_D40932_HEREY,〃,,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,Ole hyvä.,Voilà pour vous.,Parancsolj.,Eccole qua.,どうぞ。,거래 감사드립니다!,Alsjeblieft.,Vær så god.,Proszę bardzo.,Aqui está.,,Iată.,Держи.,,Varsågod.,Al bakalım. +Come back when you have enough money.,TXT_RNO1_SCRIPT10_D40932_COMEB,〃,,,Vrať se až budeš mít dost peněz.,"Kom tilbage, når du har penge nok.","Komm wieder, wenn du genug Gold hast.",,,Vuelve cuando tengas suficiente dinero.,,"Palataan asiaan sitten, kun sinulla on riittävästi rahaa.",Revenez quand vous avez assez d'argent.,"Gyere vissza, ha már van elég pénzed.",Ritorna quando avrai i soldi.,十分持ってたらまた来い。,돈이 충분할 때 다시와요.,Kom terug als je genoeg geld hebt.,Kom tilbake når du har nok penger.,"Wróć, gdy będziesz miał wystarczająco dużo pieniędzy.",Volte quando tiver dinheiro suficiente.,,Întoarce-te când ai destui bani.,"Возвращайся, когда у тебя будут деньги.",,Kom tillbaka när du har tillräckligt med pengar.,Yeterli paran olduğunda geri gel. +Energy pod,TXT_RPLY2_SCRIPT10_D40932_ENERG,〃,,,Energetický kokón,Energibælg,Energiezelle.,,,Vaina de energía,,Energia-akku.,Cellule énergétique.,Energia cella.,Nucleo energetico,エネルギーポッド,에너지 포드,Energiecapsule,Energikapsel,Statyw energetyczny.,Célula de energia.,,Capsulă energetică.,Энергоячейку,,Energipod.,Enerji kapsülü +Here's your energy pod,TXT_RYES2_SCRIPT10_D40932_HERES,〃,,,Tady ho máš.,Her er din energibælg.,Hier hast du deine Energiezele.,,,Aquí tienes tu vaina de energía,,Tässä energia-akkusi.,Voilà votre cellule.,Itt van az energia cellád.,Ecco il tuo nucleo energetico.,これがエネルギーポッドだ。,에너지 포드 한 개 대령이요!,Hier is je energiecapsule...,Her er energikapselen din.,Oto twój pojemnik na energię.,Aqui está a sua célula de energia.,,Iată capsula energetică.,Вот твоя энергоячейка.,,Här är din energipodd.,İşte enerji kapsülün. +You don't have enough for that.,TXT_RNO2_SCRIPT10_D40932_YOUDO,〃,,,Na ten nemáš dost.,Du har ikke nok til det.,"Nein, du hast nicht genug Gold dafür.",,,No tienes suficiente para eso.,,Sinulla ei ole tarpeeksi sitä varten.,Vous n'avez pas assez d'argent pour ça.,"Nincs elég nálad, hogy megvedd.",Non hai abbastanza soldi per quello.,それでは足りない。,이 물품은 비싸죠. 저도 압니다.,Daar heb je niet genoeg voor.,Du har ikke nok til det.,Nie masz na to wystarczająco dużo.,Você não tem o suficiente para isto.,,Nu ai suficiente fonduri pentru asta.,У тебя недостаточно денег.,,Du har inte tillräckligt för det.,Bunun için yeterince paran yok. +Teleporter beacon,TXT_RPLY3_SCRIPT10_D40932_TELEP,〃,,,Teleportační maják,Teleportørfyr,Teleportersignal.,,,Faro de teletransporte,,Kaukosiirrinmajakka,Antenne de téléporteur.,Teleport követő,Radiofaro per teletrasporto.,テレポータービーコン,텔레포터 비콘,Teleporter baken,Teleporteringssignal,Teleporter beacon,Sinalizador de teletransporte,,Far pentru teleportare.,Телепортационный маяк,,Teleporterfyren,Işınlayıcı işaretçisi +"Help, when and where you need it.",TXT_RYES3_SCRIPT10_D40932_HELPW,〃,,,Pomoc kdekoliv a kdykoliv je třeba.,"Hjælp, når og hvor du har brug for det.","Hilfe, wenn und wo sie gebraucht wird.",,,"Ayuda, cuando y donde la necesites.",,"Apua, missä ja milloin ikinä tarvitsetkaan.","De l'aide, quand il vous en faut.","Segítség, amikor és ahol akarod.",Con questo riceverai aiuto dove e quando ti servirà.,助けが必要になったら使うんだ。,위급한 상황에서만 사용하시길.,"Help, waar en wanneer je het nodig hebt.","Hjelp, når og hvor du trenger det.","Pomoc, kiedy i gdzie jej potrzebujesz.","Reforços, quando e onde você precisar.",,"Ajutor, acolo și când ai nevoie de el.",Теперь ты сможешь получить помощь всегда и везде.,,"Hjälp, när och var du behöver den.",İhtiyacınız olduğu zaman ve yerde yardım. +"Sorry, no charity.",TXT_RNO3_SCRIPT10_D40932_SORRY,〃,,,"Promiň, nejsme charita.","Beklager, ingen velgørenhed.","Tut mir leid, wir sind keine Wohltätigkeitsveranstaltung.",,,"Lo siento, no es caridad.",,"Valitan, ei hyväntekeväisyyttä.","Désolé, on n'est pas une charité.","Sajnálom, ez nem jótékonyság.","Mi spiace, ma niente beneficienza.",すまない、チャリティーじゃないんだ。,"미안하지만, 여긴 자선단체가 아니에요.","Sorry, geen liefdadigheid.","Beklager, ingen veldedighet.","Przykro mi, ale nie ma mowy o dobroczynności.","Sinto muito, mas não fazemos caridade.",,"Scuze, nu e caritate.",Прости. Никакой благотворительности.,,"Tyvärr, ingen välgörenhet.","Üzgünüm, hayırseverlik yok." "Now that we actually have the castle under control, we have to be extra vigilant to keep it. The Order's probably getting ready to strike back right now.",TXT_DLG_SCRIPT10_D42448_NOWTH,MAP10: Rebels in Macil's room.,,,"Teď když máme hrad pod kontrolou, musíme být ještě obezřetnější. Řád se pravděpodobně právě teď připravuje zaútočit.","Nu hvor vi faktisk har slottet under kontrol, skal vi være ekstra opmærksomme for at holde det. Ordenen er sikkert ved at gøre sig klar til at slå tilbage lige nu.","Jetzt, wo wir die Burg unter Kontrolle haben, müssen wir besonders wachsam sein, um sie nicht wieder zu verlieren. Der Orden bereitet womöglich gerade jetze einen Gegenschlag vor.",,,Ahora que realmente tenemos el castillo bajo control tenemos que estar bien alerta para guardarlo. La Orden probablemente se esté preparando para contraatacar ahora mismo.,,"Nyt, kun linna on todellakin meidän hallinnassamme, meidän on oltava erityisen valppaita pitääksemme sen. Veljeskunta on luultavasti parhaillaan valmistautumassa vastahyökkäykseen.","Maintenant que le château est sous notre contrôle, nous devons être très vigilants pour le conserver. L'Ordre se prépare sans doute à riposter maintenant.","Most, hogy már az egész kastély az irányításunk alatt van, még szemfülesebbnek kell lennünk, hogy megtarthassuk. A Rend valószínű, hogy a visszavételre készül.","Adesso che abbiamo il castello sotto controllo, dobbiamo essere ancora più vigili per tenerlo sotto controllo. L'Ordine sicuramente starà preparando un contrattacco.","城が管理下に入った今、維持させるためには 更なる警戒網が必要になるだろう。オーダーは -反撃の準備をしているはずだ。",성을 공격해 점령한 이후로 화력과 병력 등을 많이 증가시킬 수 있게 되었습니다. 오더 놈들은 분명히 이를 대비한 역습을 준비하고 있을 거예요.,"Nu we het kasteel daadwerkelijk onder controle hebben, moeten we extra waakzaam zijn om het onder controle te houden. De Orde maakt zich waarschijnlijk klaar om nu meteen terug te slaan.","Nå som vi faktisk har slottet under kontroll, må vi være ekstra årvåkne for å beholde det. Ordenen gjør seg nok klar til å slå tilbake nå.","Teraz, gdy mamy zamek pod kontrolą, musimy być bardzo czujni, by go utrzymać. Zakon pewnie szykuje się do ataku.","Agora que temos o castelo sob controle, precisamos estar mais alertas para mantê-lo assim. A Ordem provavelmente está se preparando para contra-atacar neste momento.",,"Acum că avem castelul sub control, va trebui să fim și mai vigilenți pentru a-l păstra. Ordinul probabil se pregătește pentru un atac de recuperare chiar acum.","Замок теперь наш, но если хотим его удержать, нужно не терять бдительности. Быть может, именно сейчас Орден готовит контратаку.",,"Artık kaleyi kontrol altına aldığımıza göre, onu korumak için daha dikkatli olmalıyız. Tarikat muhtemelen şu anda geri saldırmaya hazırlanıyor." -Be careful out there.,TXT_DLG_SCRIPT10_D43964_BECAR,MAP10: Castle's entrance.,,,Buď tam venku opatrný.,Vær forsigtig derude.,Sei vorsichtig da draußen.,,,Ten cuidado ahí fuera.,,Pidä varasi siellä.,Faites attention à vous.,Vigyázz magadra odakinnt.,Sii cauto la fuori.,外は気を付けろ。,부디 조심하시길.,Wees voorzichtig daarbuiten.,Vær forsiktig der ute.,Bądźcie ostrożni.,Tome cuidado.,,Ai grijă afară.,Будь настороже.,,Dışarıda dikkatli olun. +反撃の準備をしているはずだ。",성을 공격해 점령한 이후로 화력과 병력 등을 많이 증가시킬 수 있게 되었습니다. 오더 놈들은 분명히 이를 대비한 역습을 준비하고 있을 거예요.,"Nu we het kasteel daadwerkelijk onder controle hebben, moeten we extra waakzaam zijn om het onder controle te houden. De Orde maakt zich waarschijnlijk klaar om nu meteen terug te slaan.","Nå som vi faktisk har slottet under kontroll, må vi være ekstra årvåkne for å beholde det. Ordenen gjør seg nok klar til å slå tilbake nå.","Teraz, gdy mamy zamek pod kontrolą, musimy być bardzo czujni, by go utrzymać. Zakon pewnie szykuje się do ataku.","Agora que temos o castelo sob controle, precisamos estar mais alertas para mantê-lo assim. A Ordem provavelmente está se preparando para contra-atacar neste momento.",,"Acum că avem castelul sub control, va trebui să fim și mai vigilenți pentru a-l păstra. Ordinul probabil se pregătește pentru un atac de recuperare chiar acum.","Замок теперь наш, но если хотим его удержать, нужно не терять бдительности. Быть может, именно сейчас Орден готовит контратаку.",,Nu när vi faktiskt har slottet under kontroll måste vi vara extra vaksamma för att behålla det. Ordern gör sig förmodligen redo att slå tillbaka just nu.,"Artık kaleyi kontrol altına aldığımıza göre, onu korumak için daha dikkatli olmalıyız. Tarikat muhtemelen şu anda geri saldırmaya hazırlanıyor." +Be careful out there.,TXT_DLG_SCRIPT10_D43964_BECAR,MAP10: Castle's entrance.,,,Buď tam venku opatrný.,Vær forsigtig derude.,Sei vorsichtig da draußen.,,,Ten cuidado ahí fuera.,,Pidä varasi siellä.,Faites attention à vous.,Vigyázz magadra odakinnt.,Sii cauto la fuori.,外は気を付けろ。,부디 조심하시길.,Wees voorzichtig daarbuiten.,Vær forsiktig der ute.,Bądźcie ostrożni.,Tome cuidado.,,Ai grijă afară.,Будь настороже.,,Var försiktig där ute.,Dışarıda dikkatli olun. "Keep up the great work, we couldn't have done it without you.",TXT_DLG_SCRIPT10_D45480_KEEPU,MAP10: Rebel in Hospital.,,,"Jen tak dál, bez tebe bychom to nedokázali.","Fortsæt det gode arbejde, vi kunne ikke have gjort det uden jer.","Großartige Arbeit, mach weiter so. Ohne dich hätten wir es nicht schaffen können.",,,"Sigue así, no podríamos haberlo logrado sin ti.",,Jatka samaan malliin; emme olisi pärjänneet näin hyvin ilman sinua.,"Continuez votre magnifique travail, nous n'aurions jamais réussi sans vous.","Csak így tovább, nélküled sosem tudtuk volna véghezvinni.","Continua così, non ce l'avremmo fatta senza di te.","我々は貴方無くして成し遂げる事は出来なかった -素晴らしい働きをしてくれてます。",부디 건투를 빕니다. 당신 덕에 희망을 잃지 않는 거니까!,"Ga zo door, we hadden het zonder jou niet kunnen doen.","Fortsett med det flotte arbeidet, vi kunne ikke ha gjort det uten deg.","Kontynuujcie wspaniałą pracę, bez was nie dalibyśmy rady.",Continue assim. Nós não teríamos conseguido sem você.,,"Continuă să faci treabă bună, n-am fi reușit fără tine.",Продолжай в том же духе. Без тебя мы бы не справились.,,"Harika iş çıkarmaya devam edin, siz olmadan bunu başaramazdık." -I'm the keymaster.,TXT_DLG_SCRIPT11_D0_IMTHE,MAP11: Commons (no token).,,,Já jsem tu klíčníkem.,Jeg er nøglemesteren.,Ich bin der Schlüsselmeister.,,,Soy el amo de llaves.,,Olen avainmestari.,Je suis le maître des clés.,Én vagyok a kulcsmester.,Io sono il mastro delle chiavi.,僕がキーマスターだ。,전 열쇠지기에요.,Ik ben de sleutelbeheerder.,Jeg er nøkkelmesteren.,Jestem mistrzem kluczy.,Eu sou o mestre das chaves.,,Sunt stăpânul cheilor.,Я ключник.,,Ben anahtar yöneticisiyim. +素晴らしい働きをしてくれてます。",부디 건투를 빕니다. 당신 덕에 희망을 잃지 않는 거니까!,"Ga zo door, we hadden het zonder jou niet kunnen doen.","Fortsett med det flotte arbeidet, vi kunne ikke ha gjort det uten deg.","Kontynuujcie wspaniałą pracę, bez was nie dalibyśmy rady.",Continue assim. Nós não teríamos conseguido sem você.,,"Continuă să faci treabă bună, n-am fi reușit fără tine.",Продолжай в том же духе. Без тебя мы бы не справились.,,"Fortsätt med ert fantastiska arbete, vi hade inte kunnat göra det utan er.","Harika iş çıkarmaya devam edin, siz olmadan bunu başaramazdık." +I'm the keymaster.,TXT_DLG_SCRIPT11_D0_IMTHE,MAP11: Commons (no token).,,,Já jsem tu klíčníkem.,Jeg er nøglemesteren.,Ich bin der Schlüsselmeister.,,,Soy el amo de llaves.,,Olen avainmestari.,Je suis le maître des clés.,Én vagyok a kulcsmester.,Io sono il mastro delle chiavi.,僕がキーマスターだ。,전 열쇠지기에요.,Ik ben de sleutelbeheerder.,Jeg er nøkkelmesteren.,Jestem mistrzem kluczy.,Eu sou o mestre das chaves.,,Sunt stăpânul cheilor.,Я ключник.,,Jag är nyckelmästaren.,Ben anahtar yöneticisiyim. "A lot of people would say this is a thankless and insignificant job. But it's not, in fact...",TXT_DLG_SCRIPT11_D1516_ALOTO,〃 (Oracle's token),,,"Většina lidí by řekla, že tohle je nevděčná a nedůležitá práce, ale není, naopak...","Mange ville sige, at det er et utaknemmeligt og ubetydeligt job. Men det er det ikke, faktisk...","Eine Menge Leute würden sagen, dies sei eine undankbare Aufgabe, aber das ist es nicht, in Wirklichkeit...",,,"Mucha gente diría que este es un trabajo ingrato e insignificante, pero no, de hecho...",,Monet väittäisivät tehtäväni olevan epäkiitollinen ja vähäpätöinen. Mutta oikeasti se ei ole.,"Beaucoup de gens diraient que c'est un travail insignifiant et ingrat.. Mais en fait, ce n'est vraiment pas le cas.","Sokan azt mondják, hogy ez egy hálátlan és jelentéktelen munka. Ám nem is állhatnának messzebb az igazságtól...","Molte persone direbbero che questo è un lavoro ingrato e insignificante. Ma non lo è, infatti...","皆、この仕事が報われないと思っているが -実際はそうでもないんだ...","많은 사람이 이 직업을 감사해야 하고 놀라운 일이라 말하겠죠. 하지만 아닌데, 사실은...","Veel mensen zouden zeggen dat dit een ondankbare en onbeduidende klus is. Maar dat is het niet, in feite....",Mange vil si at dette er en utakknemlig og ubetydelig jobb. Men det er det faktisk ikke...,"Wielu ludzi powiedziałoby, że to niewdzięczna i mało znacząca praca. Ale tak nie jest, w rzeczywistości...",Muita gente diria que este é um trabalho ingrato e insignificante. Mas na verdade não é...,,"O grămadă de oameni ar spune că e o muncă fără mulțumiri și insignifiantă. În realitate, nu este...","Многие скажут, что это неблагодарная и незначительная работа, но это не так. На самом деле...",,"Birçok insan bunun nankör ve önemsiz bir iş olduğunu söyleyebilir. Ama değil, aslında..." -Give me the key!,TXT_RPLY0_SCRIPT11_D1516_GIVEM,〃,,,Dej mi klíč!,Giv mig nøglen!,Gib mir den Schlüssel.,,,¡Dame la llave!,,Anna minulle avain!,Donne moi la clé!,Add ide a kulcsot!,Dammi la chiave!,鍵をくれ!,그냥 망할 열쇠를 줘!,Geef me de sleutel!,Gi meg nøkkelen!,Daj mi klucz!,Me dê a chave!,,Dă-mi cheia!,Дай мне ключ!,,Anahtarı bana ver! -"OK, but remember, I'm the keymaster.",TXT_DLG_SCRIPT11_D3032_OKBUT,〃,,,"Dobře, ale nezapomeň, že klíčník jsem já.","OK, men husk, jeg er nøglemesteren.","Ok, aber vergiß nicht, dass ICH der Schlüsselmeister bin.",,,"Bueni, pero recuerda: soy el amo de llaves.",,"Selvä, mutta muista: minä olen avainmestari.","Ok, mais souviens-toi, je suis le maître des clés.","OK, de emlékezz arra, hogy Én vagyok a kulcsmester.","OK, ma ricorda, io sono il mastro delle chiavi.",オーケー、なんせ僕は、キーマスターだしな。,"좋아요, 하지만 기억해요. 전 열쇠지기랍니다!","Oké, maar onthoud, ik ben de sleutelbeheerder.","OK, men husk at jeg er nøkkelmesteren.","OK, ale pamiętaj, że to ja jestem klucznikiem.","Ok, mas lembre-se, eu sou o mestre das chaves.",,"Bine, dar ține minte, eu sunt stăpânul cheilor.","Держи, но помни: я ключник!",,"Tamam, ama unutma, anahtar ustası benim." -"OK pal, whatever.",TXT_RPLY0_SCRIPT11_D3032_OKPAL,〃,,,"Jasně, kámo, klidně.","Okay, kammerat.","Was auch immer, Kumpel.",,,"Sí, colega, lo que tú digas.","Sí, amigo, como tú digas.","Joo joo, ihan sama.","Comme tu veux, mon ami.","OK öreg, nem hat meg.","Sì, certo, come no.",わかった、何なりと。,"그래, 알 게 뭐야...","Oké, vriend, wat dan ook.","OK, kompis, samme det.","OK kolego, nieważne.","Ok, amigo. Que seja.",,"Bine amice, cum spui tu.",Ага. Без проблем.,,"Tamam dostum, her neyse." -I'm the keymaster.,TXT_DLG_SCRIPT11_D4548_IMTHE,〃,,,Já jsem tu klíčníkem.,Jeg er nøglemesteren.,Ich bin der Schlüsselmeister.,,,Soy el amo de llaves.,,Minä olen avainmestari.,Je suis le maître des clés.,Én vagyok a kulcsmester.,Io sono il mastro delle chiavi.,僕がキーマスターだ。,열쇠지기. 그게 바로 저죠!,Ik ben de sleutelbeheerder.,Jeg er nøkkelmesteren.,Ja jestem klucznikiem.,Eu sou o mestre das chaves.,,Sunt stăpânul cheilor.,Я ключник.,,Anahtar ustası benim. -Die traitor!,TXT_DLG_SCRIPT11_D6064_DIETR,MAP11: Red acolyte at temple's entrance.,,,"Zemři, zrádče!","Dø, forræder!","Stirb, Verräter.",,,"¡Muere, traidor!",,"Kuole, petturi!","Meurs, traître!",Halál rád áruló!,Muori traditore!,死ね、反逆者!,"죽어라, 배신자!","Sterf, verrader.",Dø forræder!,Giń zdrajco!,"Morra, traidor!",,Mori trădătorule!,"Умри, предатель!",,Geber hain! -Die traitor!,TXT_DLG_SCRIPT11_D7580_DIETR,〃,,,"Zemři, zrádče!","Dø, forræder!","Stirb, Verräter.",,,"¡Muere, traidor!",,"Kuole, petturi!","Meurs, traître!",Halál rád áruló!,Muori traditore!,死ね、反逆者!,"뒈져라, 배신자!","Sterf, verrader.",Dø forræder!,Giń zdrajco!,"Morra, traidor!",,Mori trădătorule!,"Умри, предатель!",,Geber hain! +実際はそうでもないんだ...","많은 사람이 이 직업을 감사해야 하고 놀라운 일이라 말하겠죠. 하지만 아닌데, 사실은...","Veel mensen zouden zeggen dat dit een ondankbare en onbeduidende klus is. Maar dat is het niet, in feite....",Mange vil si at dette er en utakknemlig og ubetydelig jobb. Men det er det faktisk ikke...,"Wielu ludzi powiedziałoby, że to niewdzięczna i mało znacząca praca. Ale tak nie jest, w rzeczywistości...",Muita gente diria que este é um trabalho ingrato e insignificante. Mas na verdade não é...,,"O grămadă de oameni ar spune că e o muncă fără mulțumiri și insignifiantă. În realitate, nu este...","Многие скажут, что это неблагодарная и незначительная работа, но это не так. На самом деле...",,"Många skulle säga att det är ett otacksamt och obetydligt jobb. Men det är det inte, i själva verket...","Birçok insan bunun nankör ve önemsiz bir iş olduğunu söyleyebilir. Ama değil, aslında..." +Give me the key!,TXT_RPLY0_SCRIPT11_D1516_GIVEM,〃,,,Dej mi klíč!,Giv mig nøglen!,Gib mir den Schlüssel.,,,¡Dame la llave!,,Anna minulle avain!,Donne moi la clé!,Add ide a kulcsot!,Dammi la chiave!,鍵をくれ!,그냥 망할 열쇠를 줘!,Geef me de sleutel!,Gi meg nøkkelen!,Daj mi klucz!,Me dê a chave!,,Dă-mi cheia!,Дай мне ключ!,,Ge mig nyckeln!,Anahtarı bana ver! +"OK, but remember, I'm the keymaster.",TXT_DLG_SCRIPT11_D3032_OKBUT,〃,,,"Dobře, ale nezapomeň, že klíčník jsem já.","OK, men husk, jeg er nøglemesteren.","Ok, aber vergiß nicht, dass ICH der Schlüsselmeister bin.",,,"Bueni, pero recuerda: soy el amo de llaves.",,"Selvä, mutta muista: minä olen avainmestari.","Ok, mais souviens-toi, je suis le maître des clés.","OK, de emlékezz arra, hogy Én vagyok a kulcsmester.","OK, ma ricorda, io sono il mastro delle chiavi.",オーケー、なんせ僕は、キーマスターだしな。,"좋아요, 하지만 기억해요. 전 열쇠지기랍니다!","Oké, maar onthoud, ik ben de sleutelbeheerder.","OK, men husk at jeg er nøkkelmesteren.","OK, ale pamiętaj, że to ja jestem klucznikiem.","Ok, mas lembre-se, eu sou o mestre das chaves.",,"Bine, dar ține minte, eu sunt stăpânul cheilor.","Держи, но помни: я ключник!",,"Okej, men kom ihåg att jag är nyckelmästaren.","Tamam, ama unutma, anahtar ustası benim." +"OK pal, whatever.",TXT_RPLY0_SCRIPT11_D3032_OKPAL,〃,,,"Jasně, kámo, klidně.","Okay, kammerat.","Was auch immer, Kumpel.",,,"Sí, colega, lo que tú digas.","Sí, amigo, como tú digas.","Joo joo, ihan sama.","Comme tu veux, mon ami.","OK öreg, nem hat meg.","Sì, certo, come no.",わかった、何なりと。,"그래, 알 게 뭐야...","Oké, vriend, wat dan ook.","OK, kompis, samme det.","OK kolego, nieważne.","Ok, amigo. Que seja.",,"Bine amice, cum spui tu.",Ага. Без проблем.,,"Okej kompis, vad som helst.","Tamam dostum, her neyse." +I'm the keymaster.,TXT_DLG_SCRIPT11_D4548_IMTHE,〃,,,Já jsem tu klíčníkem.,Jeg er nøglemesteren.,Ich bin der Schlüsselmeister.,,,Soy el amo de llaves.,,Minä olen avainmestari.,Je suis le maître des clés.,Én vagyok a kulcsmester.,Io sono il mastro delle chiavi.,僕がキーマスターだ。,열쇠지기. 그게 바로 저죠!,Ik ben de sleutelbeheerder.,Jeg er nøkkelmesteren.,Ja jestem klucznikiem.,Eu sou o mestre das chaves.,,Sunt stăpânul cheilor.,Я ключник.,,Jag är nyckelmästaren.,Anahtar ustası benim. +Die traitor!,TXT_DLG_SCRIPT11_D6064_DIETR,MAP11: Red acolyte at temple's entrance.,,,"Zemři, zrádče!","Dø, forræder!","Stirb, Verräter.",,,"¡Muere, traidor!",,"Kuole, petturi!","Meurs, traître!",Halál rád áruló!,Muori traditore!,死ね、反逆者!,"죽어라, 배신자!","Sterf, verrader.",Dø forræder!,Giń zdrajco!,"Morra, traidor!",,Mori trădătorule!,"Умри, предатель!",,"Dö, förrädare!",Geber hain! +Die traitor!,TXT_DLG_SCRIPT11_D7580_DIETR,〃,,,"Zemři, zrádče!","Dø, forræder!","Stirb, Verräter.",,,"¡Muere, traidor!",,"Kuole, petturi!","Meurs, traître!",Halál rád áruló!,Muori traditore!,死ね、反逆者!,"뒈져라, 배신자!","Sterf, verrader.",Dø forræder!,Giń zdrajco!,"Morra, traidor!",,Mori trădătorule!,"Умри, предатель!",,"Dö, förrädare!",Geber hain! "Have you come to gloat? Even though we're behind these bars, as long as we hold on, you still lose.",TXT_DLG_SCRIPT11_D9096_HAVEY,MAP11: Prisoner.,,,"Přišel ses nám vysmívat? I když jsme za mřížemi, dokud jsme na nohou, ty zůstáváš poražený.","Er du kommet for at fryde dig? Selvom vi er bag disse tremmer, så længe vi holder fast, taber du stadig.","Bist du zum Glotzen gekommen? Auch wenn wir hinter Gittern sind, solange wir nicht aufgeben wirst du immer noch verlieren.",,,"¿Has venido a regodearte? Aunque estemos entre rejas, mientras sigamos en pie, has perdido.",,"Oletko tullut meitä pilkkaamaan? Vaikka olemmekin näiden kaltereiden takansa, niin kunhan vain pidämme pintamme, sinä silti häviät.","Vous êtes venu vous moquer de nous? Même si on est derrière les barreaux, du moment que l'on reste en vie, vous allez perdre.","Dicsekedni jöttél ide? Habár itt rohadunk a rács mögött, amíg kitartunk miénk a győzelem.","Sei venuto a gongolare? Anche se siamo dietro queste sbarre, finché resisteremo, voi perderete.","何睨んでるんだ?この棒が俺達を囲んでる限り、 -お前は未だに負けている。","거들먹거리러 온 거냐? 비록 우리가 이 철창에 갇히긴 했지만, 계속 여기 있으면 넌 아직도 질 거라고.","Ben je gekomen om je te verkneukelen? Ook al zitten we achter deze tralies, zolang we ons vasthouden, verlies je nog steeds.","Har du kommet for å hovere? Selv om vi er bak gitteret, taper du så lenge vi holder fast.","Przyszliście się napawać? Nawet jeśli jesteśmy za tymi kratami, to dopóki się trzymamy, ty wciąż przegrywasz.","Você veio se gabar? Mesmo que a gente esteja atrás destas grades, enquanto resistirmos, você ainda perde.",,"Ai venit să te lauzi? Chiar dacă suntem în spatele gratilor, cât timp rezistăm, tu pierzi.","Пришёл поглумиться? Пусть мы и за этими решётками, но пока мы живы, вам не победить.",,"Kına yakmaya mı geldin? Bu parmaklıkların arkasında olsak bile, biz dayandığımız sürece siz kaybedersiniz." -Let us out of here!,TXT_DLG_SCRIPT11_D10612_LETUS,〃,,,Pusť nás odsud!,Lad os komme ud herfra!,Lass uns hier raus!,,,¡Sácanos de aquí!,,Päästä meidät pois täältä!,Sortez nous de là!,Engedj ki minket!,Facci uscire da qua!,ここから出してくれ!,우릴 여기서 내보내 줘!,Laat ons hier uit!,Slipp oss ut herfra!,Wypuść nas stąd!,Nos tire daqui!,,Scoate-ne de aici!,Выпусти нас отсюда!,,Çıkarın bizi buradan! -Leave me alone!,TXT_DLG_SCRIPT11_D12128_LEAVE,〃,,,Nech mě být!,Lad mig være i fred!,Lass mich in Ruhe!,,,¡Déjame en paz!,,Jätä minut rauhaan!,Foutez moi la paix!,Hagyj békén!,Lasciami in pace!,ほっといてくれ!,날 좀 내버려 둬!,Laat me met rust!,La meg være i fred!,Zostawcie mnie w spokoju!,Me deixe em paz!,,Lasă-mă în pace!,Оставь меня в покое!,,Beni yalnız bırakın! -"What is the wisdom you seek, simple one?",TXT_DLG_SCRIPT12_D0_WHATI,MAP12: Oracle.,,,"Jaké moudro hledáš, jednoduchý?","Hvad er det for en visdom du søger, simple en?","Welche Weisheit suchst du, Menschling?",,,"¿Cuál es la sabiduría que buscas, simple criatura?",,"Mitä viisautta etsit, sinä tietämätön?","Quelle est la sagesse que vous recherchez, simple humain?","Miféle bölcsességet kutatsz, egyszerű barátom?","Qual è la saggezza che cerchi, ottenebrato ?",迷える者よ、如何なる知識を求めに来た。,그대가 찾고 있는 지혜는 어떤 것인가? 평범한 자여?,"Wat is de wijsheid die je zoekt, eenvoudige wijsheid?","Hva er visdommen du søker, enfoldige?","Jakiej mądrości szukasz, prosty?","Qual é a sabedoria que você procura, simples criatura?",,"Ce întelepciune cauți, om simplu?","Какой мудрости ты ищешь, непосвящённый?",,"Aradığın bilgelik nedir, basit olan?" -The Sigil of the One God.,TXT_RPLY0_SCRIPT12_D0_THESI,〃,,,Pečeť Jednoho boha.,Sigilet af den ene Gud.,Das Sigil des Einen Gottes.,,,El Emblema del Dios Único.,,Yhden Ainoan Jumalan Sinettiä.,Le Sigil du Seul Dieu.,Az egy Igaz Isten pecsétjét.,Il Sigillo dell'Unico Dio.,唯一神のシジルだ。,"유일신의 인장, 시질이다.",De Sigil van de Ene God.,Den ene Guds sigill.,Sigil Jedynego Boga.,O Sigilo do Deus Único.,,Sigiliul Adevăratului Zeu.,Печать Единого Бога.,,Tek Tanrı'nın Mührü. +お前は未だに負けている。","거들먹거리러 온 거냐? 비록 우리가 이 철창에 갇히긴 했지만, 계속 여기 있으면 넌 아직도 질 거라고.","Ben je gekomen om je te verkneukelen? Ook al zitten we achter deze tralies, zolang we ons vasthouden, verlies je nog steeds.","Har du kommet for å hovere? Selv om vi er bak gitteret, taper du så lenge vi holder fast.","Przyszliście się napawać? Nawet jeśli jesteśmy za tymi kratami, to dopóki się trzymamy, ty wciąż przegrywasz.","Você veio se gabar? Mesmo que a gente esteja atrás destas grades, enquanto resistirmos, você ainda perde.",,"Ai venit să te lauzi? Chiar dacă suntem în spatele gratilor, cât timp rezistăm, tu pierzi.","Пришёл поглумиться? Пусть мы и за этими решётками, но пока мы живы, вам не победить.",,"Har du kommit för att skryta? Även om vi är bakom dessa galler, så länge vi håller ut, förlorar du ändå.","Kına yakmaya mı geldin? Bu parmaklıkların arkasında olsak bile, biz dayandığımız sürece siz kaybedersiniz." +Let us out of here!,TXT_DLG_SCRIPT11_D10612_LETUS,〃,,,Pusť nás odsud!,Lad os komme ud herfra!,Lass uns hier raus!,,,¡Sácanos de aquí!,,Päästä meidät pois täältä!,Sortez nous de là!,Engedj ki minket!,Facci uscire da qua!,ここから出してくれ!,우릴 여기서 내보내 줘!,Laat ons hier uit!,Slipp oss ut herfra!,Wypuść nas stąd!,Nos tire daqui!,,Scoate-ne de aici!,Выпусти нас отсюда!,,Släpp ut oss härifrån!,Çıkarın bizi buradan! +Leave me alone!,TXT_DLG_SCRIPT11_D12128_LEAVE,〃,,,Nech mě být!,Lad mig være i fred!,Lass mich in Ruhe!,,,¡Déjame en paz!,,Jätä minut rauhaan!,Foutez moi la paix!,Hagyj békén!,Lasciami in pace!,ほっといてくれ!,날 좀 내버려 둬!,Laat me met rust!,La meg være i fred!,Zostawcie mnie w spokoju!,Me deixe em paz!,,Lasă-mă în pace!,Оставь меня в покое!,,Lämna mig ifred!,Beni yalnız bırakın! +"What is the wisdom you seek, simple one?",TXT_DLG_SCRIPT12_D0_WHATI,MAP12: Oracle.,,,"Jaké moudro hledáš, jednoduchý?","Hvad er det for en visdom du søger, simple en?","Welche Weisheit suchst du, Menschling?",,,"¿Cuál es la sabiduría que buscas, simple criatura?",,"Mitä viisautta etsit, sinä tietämätön?","Quelle est la sagesse que vous recherchez, simple humain?","Miféle bölcsességet kutatsz, egyszerű barátom?","Qual è la saggezza che cerchi, ottenebrato ?",迷える者よ、如何なる知識を求めに来た。,그대가 찾고 있는 지혜는 어떤 것인가? 평범한 자여?,"Wat is de wijsheid die je zoekt, eenvoudige wijsheid?","Hva er visdommen du søker, enfoldige?","Jakiej mądrości szukasz, prosty?","Qual é a sabedoria que você procura, simples criatura?",,"Ce întelepciune cauți, om simplu?","Какой мудрости ты ищешь, непосвящённый?",,"Vad är det för visdom du söker, enkla man?","Aradığın bilgelik nedir, basit olan?" +The Sigil of the One God.,TXT_RPLY0_SCRIPT12_D0_THESI,〃,,,Pečeť Jednoho boha.,Sigilet af den ene Gud.,Das Sigil des Einen Gottes.,,,El Emblema del Dios Único.,,Yhden Ainoan Jumalan Sinettiä.,Le Sigil du Seul Dieu.,Az egy Igaz Isten pecsétjét.,Il Sigillo dell'Unico Dio.,唯一神のシジルだ。,"유일신의 인장, 시질이다.",De Sigil van de Ene God.,Den ene Guds sigill.,Sigil Jedynego Boga.,O Sigilo do Deus Único.,,Sigiliul Adevăratului Zeu.,Печать Единого Бога.,,Den ende gudens signum.,Tek Tanrı'nın Mührü. "I feel one fragment resonate within you. The second lies at the heart of the crimson and obsidian tower. There you must combat the Bishop, who is aware, and awaits you. You will find him by following his symbol of power. Take this token to the keymaster. Return to me after you have slain the beast.",TXT_DLG_SCRIPT12_D1516_IFEEL,〃,,,"Cítím z tebe rezonovat jeden díl. Druhý leží v srdci věže karmíno-obsidiánové. Tam musíš poraziti Biskupa, který si je tě vědom a očekává tě. Najdeš ho následováním symbolu jeho moci. Přijmi tuto známku pro klíčníka. Vrať se ke mě, až skolíš bestii.","Jeg føler et fragment resonere i dig. Det andet ligger i hjertet af det purpurfarvede og obsidian tårn. Der skal du bekæmpe biskoppen, som er klar over det og venter på dig. Du finder ham ved at følge hans symbol for magt. Tag dette symbol med til nøglemesteren. Vend tilbage til mig, når du har dræbt udyret.","Ich fühle, wie ein Fragment in dir pulsiert, Das zweite Teilstück des Sigils befindet sich im Herzen des Turms aus Purpur und Obsidian. Dort wartet der Bischof auf dich, den du bekämpfen musst. Er weiß von dir und wartet. Du findest ihn, wenn du seinem Symbol der Macht folgst. Nimm dieses Zeichen und gebe es dem Schlüsselmeister. Kehr zu mir zurück, nachdem du die Bestie vernichtet hast.",,,"Siento un fragmento resonar en ti. El segundo se encuentra en el corazón de la torre carmesí y obsidiana. Ahí debes combatir con el Obispo, quien sabe, y espera tu llegada. Lo encontrarás siguiendo su símbolo de poder. Lleva este vale al amo de llaves. Vuelve a mí tras haber matado a la bestia.",,"Minä tunnen yhden osasen väräjävän sisälläsi. Toinen piilee purppuranpunaisen laavalasisen tornin sydämessä. Siellä pitää sinun taisteleman Piispaa vastaan, joka on tietoinen ja sinua odottava. Löydät hänet seuraamalla hänen valtansa tunnuskuvaa. Toimita tämä merkki avainmestarille. Palaa tyköni surmattuasi pedon.","Je sens un fragment résonner en toi. Le deuxième repose au cœur de la tour d'obsidienne et d'écarlate. Ici, vous devrez défaire l'évêque, qui connaît déjà votre statut, et vous attend patiemment. Vous le trouverez en suivant son symbole de pouvoir. Prenez ce jeton et amenez le au maître des clés. Retournez à moi après que vous ayez vaincu la bête.","Érzem rajta az egyik darabot. A másodikat a karmazsin és obszidián toronyban találod meg. Ott viszont már várni fog rád a Püspök. Meg fogod lelni őt, ha követed a jelét. Vidd ezt a zálogot a kulcsmesterhez. Térj vissza hozzám, ha legyűrted a szörnyet.","Avverto che possiedi uno dei frammenti. Il secondo si trova nel cuore della torre cremisina e ossidiana. Lì dovrai combattere contro il Vescovo, che già ti attende. Lo troverai seguendo il suo simbolo del potere. Prendi questo gettone per il mastro delle chiavi. Ritorna da me dopo che avrai ucciso la bestia.","お主の持つ欠片が共鳴しているのを感受出来る。 二つ目の欠片は紅と黒曜の塔だ。 そこでお主を待ち構えているビショップと戦え。 その者が持つシンボルを辿れば見つかるだろう。 このトークンをキーマスターに渡せ。 魔物を討伐した後、此処へ戻るのだ。",그대에게서 시질의 조각 중 하나가 느껴지는군. 두 번째 조각은 진홍빛 흑요석 탑의 심장부에 있다. 거기서 기다리고 있는 비숍과 싸워야 한다. 그 자의 권력을 상징하는 문양을 따라가면 만날 수 있을 것이다. 열쇠지기에게 이 통행증을 전해주어라. 그리고 괴물을 처치하면 다시 나에게로 오라.,"Ik voel een fragment in je resoneren. Het tweede fragment ligt in het hart van de karmozijnrode en obsidiaan toren. Daar moet je de bisschop bestrijden, die zich bewust is van de situatie en op je wacht. Je zult hem vinden door zijn machtssymbool te volgen. Neem dit teken mee naar de sleutelbeheerder. Keer naar mij terug nadat je het beest hebt gedood.","Jeg føler et fragment resonere i deg. Det andre ligger i hjertet av det purpurfargede og obsidianske tårnet. Der må du bekjempe biskopen, som vet og venter på deg. Du finner ham ved å følge hans maktsymbol. Ta dette symbolet til nøkkelmesteren. Kom tilbake til meg etter at du har drept udyret.","Czuję, że jeden fragment rezonuje w tobie. Drugi leży w sercu karmazynowej i obsydianowej wieży. Tam musisz walczyć z Biskupem, który jest świadomy i czeka na ciebie. Znajdziesz go podążając za jego symbolem mocy. Zanieś ten żeton do klucznika. Wróć do mnie po zabiciu bestii.","Posso sentir um fragmento ressoar de dentro de você. O segundo está na torre carmesim e obsidiana. Lá você deverá combater o Bispo, que está acordado e te aguarda. Você o encontrará seguindo o seu símbolo de poder. Leve esta ensígnia ao mestre das chaves. Volte depois de eliminar a besta.",,"Simt un fragment care rezonează în tine. Al doilea e în inima turnului purpuriu, din obsidian. Acolo îl vei înfrunta pe Episcop, care e conștient, și în așteptare. Îl vei găsi urmându-i simbolul puterii. Du asta la stăpânul cheilor. Întoarce-te după ce ai înfrânt fiara.","Я чувствую один фрагмент, настроенный на тебя. Второй лежит в сердце багрово-обсидиановой башни. Там тебе предстоит сразиться с Епископом — он знает о тебе и ждёт твоего появления. Его символ власти приведёт тебя прямо к нему. Отнеси этот жетон ключнику. Срази чудовище и возвращайся ко мне. -",,"Bir parçanın içinde yankılandığını hissediyorum. İkincisi kızıl ve obsidyen kulenin kalbinde yatıyor. Orada, farkında olan ve seni bekleyen Piskopos'la savaşmalısın. Onu güç sembolünü takip ederek bulacaksın. Bu simgeyi anahtar ustasına götür. Canavarı öldürdükten sonra bana dön." -I'll be back.,TXT_RPLY0_SCRIPT12_D1516_ILLBE,〃,,,Vrátím se.,Jeg kommer tilbage.,Ich werde zurückkommen.,,Mi revenos.,Volveré.,,Tulen takaisin.,Je reviendrai.,Visszatérek még.,Ritornerò.,すぐ戻ってくる。,금방 돌아올게.,Ik kom terug.,Jeg kommer tilbake.,Wrócę.,Eu voltarei.,,Mă voi întoarce.,Я вернусь.,,Geri geleceğim. +",,"Jag känner ett fragment resonera inom dig. Det andra ligger i hjärtat av det karmosinröda och obsidianska tornet. Där måste du bekämpa biskopen, som är medveten och väntar på dig. Du hittar honom genom att följa hans maktsymbol. Ta den här symbolen till nyckelmästaren. Återvänd till mig när du har dödat odjuret.","Bir parçanın içinde yankılandığını hissediyorum. İkincisi kızıl ve obsidyen kulenin kalbinde yatıyor. Orada, farkında olan ve seni bekleyen Piskopos'la savaşmalısın. Onu güç sembolünü takip ederek bulacaksın. Bu simgeyi anahtar ustasına götür. Canavarı öldürdükten sonra bana dön." +I'll be back.,TXT_RPLY0_SCRIPT12_D1516_ILLBE,〃,,,Vrátím se.,Jeg kommer tilbage.,Ich werde zurückkommen.,,Mi revenos.,Volveré.,,Tulen takaisin.,Je reviendrai.,Visszatérek még.,Ritornerò.,すぐ戻ってくる。,금방 돌아올게.,Ik kom terug.,Jeg kommer tilbake.,Wrócę.,Eu voltarei.,,Mă voi întoarce.,Я вернусь.,,Jag kommer tillbaka.,Geri geleceğim. "Although the Bishop is formidable, this quest is slight. Return to me when you possess the next fragment.",TXT_DLG_SCRIPT12_D3032_ALTHO,〃,,,"I přes Biskupovu hrozivost je tento úkol drobný. Vrať se, až budeš vlastnit další díl.","Selv om biskoppen er formidabel, er denne søgen let. Vend tilbage til mig, når du er i besiddelse af det næste fragment.","Auch wenn der Bischof ein schwerer Gegner ist, diese Aufgabe ist geringfügig. Komm zu mir zurück, wenn du das nächste Fragment besitzt.",,,"Aunque el Obispo es formidable, esta misión es leve. Vuelve a mí cuando poseas el siguiente fragmento.",,"Vaikka suuri onkin Piispa, pieni kuitenkin on tämä tehtävä. Palaa tyköni, kun seuraava osanen on hallussasi.","Bien que l'évêque soit un puissant adversaire, cette quête n'est qu'une courte aventure. Revenez à moi quand vous possédez le deuxième fragment.","Habár a Püspök méltó ellenfél lesz, a küldetésed könnyű. Térj vissza, ha megvan a következő darabka.","Anche se il Vescovo è formidabile, questa sfida è leggera. Ritorna da me non appena possiedi il prossimo frammento.","ビショップは手強く、この使命は困難であろう。 次の欠片を手にしたら此処へ戻るのだ。 -","비숍은 만만치 않은 상대지만, 이보다 더한 일들이 기다리고 있다. 두 번째 조각을 찾고 다시 돌아오라.","Hoewel de bisschop formidabel is, is deze zoektocht gering. Keer terug naar mij als je het volgende fragment bezit.","Selv om biskopen er formidabel, er dette oppdraget lett. Kom tilbake til meg når du har det neste fragmentet.","Choć Biskup jest potężny, to zadanie jest niewielkie. Wróć do mnie, gdy posiądziesz kolejny fragment.","Embora o Bispo seja poderoso, esta missão é simples. Retorne para mim quando você possuir o próximo fragmento.",,"Deși Episocopul e formidabil, misiunea asta e ușoara. Întoarce-te când ai cel de-al doilea fragment.","Каким бы страшным Епископ ни был, это задание не доставит тебе хлопот. Достань следующий фрагмент и возвращайся ко мне.",,"Piskopos zorlu olsa da, bu görev hafif. Bir sonraki parçayı ele geçirdiğinde bana geri dön." +","비숍은 만만치 않은 상대지만, 이보다 더한 일들이 기다리고 있다. 두 번째 조각을 찾고 다시 돌아오라.","Hoewel de bisschop formidabel is, is deze zoektocht gering. Keer terug naar mij als je het volgende fragment bezit.","Selv om biskopen er formidabel, er dette oppdraget lett. Kom tilbake til meg når du har det neste fragmentet.","Choć Biskup jest potężny, to zadanie jest niewielkie. Wróć do mnie, gdy posiądziesz kolejny fragment.","Embora o Bispo seja poderoso, esta missão é simples. Retorne para mim quando você possuir o próximo fragmento.",,"Deși Episocopul e formidabil, misiunea asta e ușoara. Întoarce-te când ai cel de-al doilea fragment.","Каким бы страшным Епископ ни был, это задание не доставит тебе хлопот. Достань следующий фрагмент и возвращайся ко мне.",,Även om biskopen är formidabel är detta uppdrag lätt. Återvänd till mig när du besitter nästa fragment.,"Piskopos zorlu olsa da, bu görev hafif. Bir sonraki parçayı ele geçirdiğinde bana geri dön." Your next challenge will test your spirit. The third piece is held by your own leader. He is the same as that which he sends you to kill.,TXT_DLG_SCRIPT12_D4548_YOURN,,,,"Tvá další výzva pokusí tvou vůli. Třetí díl je držen tvým vlastním vůdcem. Je stejný, jako ti, které tě posílá zabít.","Din næste udfordring vil sætte din ånd på prøve. Det tredje stykke er i din egen leders besiddelse. Han er den samme som den, han sender dig ud for at dræbe.","Die nächste Herausforderung wird deinen Geist prüfen. Das dritte Teilstück wird von deinem eigenen Anführer, Macil, gehalten. Er ist das Gleiche, was er dich töten lässt.",,,Tu próximo desafío pondrá a prueba tu espíritu. El tercer fragmento está en manos de tu propio líder. Él es igual que aquello que te envía a matar.,,"Seuraava haasteesi koettelee sinua henkisesti. Kolmatta osasta pitää hallussaan oma päämiehesi. Hän on sama kuin se, jonka hän lähettää sinut surmaamaan.",Le prochain défi testera votre esprit. Le troisième fragment est possédé par votre leader. Il est le même que celui qu'il vous a envoyé tuer.,"A következő kihívás próbára fogja tenni a lelked. A harmadik darab a saját vezetődnél van. Ő maga ugyanaz, mint akiért elküldött.",La tua prossima sfida metterà alla prova il tuo spirito. Il terzo frammento è posseduto dal tuo stesso capo. Lui è uguale a quelli che ti manda ad uccidere.,"次の挑戦はお主の精神が試されるだろう。 三つ目の欠片はお主の指導者が所持している。 彼奴はお主の死を望むが為 -戦場へ送り込んでいるのだ。",다음 도전은 그대의 정신을 시험할 것이다. 세 번째 조각은 바로 그대의 지도자가 가지고 있다. 그는 그대를 시켜서 죽였던 괴물들과 마찬가지인 존재다.,Je volgende uitdaging zal je geest testen. Het derde stuk is in handen van je eigen leider. Hij is hetzelfde als wat hij je stuurt om te doden.,Din neste utfordring vil sette din ånd på prøve. Den tredje brikken holdes av din egen leder. Han er den samme som han sender deg for å drepe.,"Twoje kolejne wyzwanie będzie testem dla twojego ducha. Trzeci kawałek jest w posiadaniu waszego przywódcy. Jest taki sam jak ten, którego wysyła, byś zabił.",Seu próximo desafio testará o seu espírito. A terceira peça está com o seu próprio líder. Ele é a mesma pessoa que ele quer que você mate.,,Următoarea provocare îți va testa spiritul. A treia piesă e deținută de liderul tău. A celași care te trimite să omori.,"Следующее задание испытает силу твоего духа. Третий фрагмент у вашего лидера. Он сам — один из тех, кого вы убиваете по его приказу.",,Bir sonraki mücadeleniz ruhunuzu sınayacak. Üçüncü parça kendi lideriniz tarafından tutuluyor. Seni öldürmen için gönderdiğiyle aynı kişi. -Macil? A traitor?,TXT_RPLY0_SCRIPT12_D4548_MACIL,,,,Macil? Zrádce?,Macil? En forræder?,Macil? Ein Verräter?,,,¿Macil? ¿Un traidor?,,Macil? Petturiko?,Macil? Un traître?,Macil? Egy áruló volna?,Macil? Un traditore?,マシル?彼が裏切者?,마실이 배신자라고?,Macil? Een verrader?,Macil? En forræder?,Macil? Zdrajca?,Macil? Um traidor?,,Macil? Un trădător?,Мэйсил? Предатель?,,Macil mi? Bir hain mi? +戦場へ送り込んでいるのだ。",다음 도전은 그대의 정신을 시험할 것이다. 세 번째 조각은 바로 그대의 지도자가 가지고 있다. 그는 그대를 시켜서 죽였던 괴물들과 마찬가지인 존재다.,Je volgende uitdaging zal je geest testen. Het derde stuk is in handen van je eigen leider. Hij is hetzelfde als wat hij je stuurt om te doden.,Din neste utfordring vil sette din ånd på prøve. Den tredje brikken holdes av din egen leder. Han er den samme som han sender deg for å drepe.,"Twoje kolejne wyzwanie będzie testem dla twojego ducha. Trzeci kawałek jest w posiadaniu waszego przywódcy. Jest taki sam jak ten, którego wysyła, byś zabił.",Seu próximo desafio testará o seu espírito. A terceira peça está com o seu próprio líder. Ele é a mesma pessoa que ele quer que você mate.,,Următoarea provocare îți va testa spiritul. A treia piesă e deținută de liderul tău. A celași care te trimite să omori.,"Следующее задание испытает силу твоего духа. Третий фрагмент у вашего лидера. Он сам — один из тех, кого вы убиваете по его приказу.",,Din nästa utmaning kommer att sätta din själ på prov. Den tredje biten innehas av din egen ledare. Han är densamma som den som han skickar dig att döda.,Bir sonraki mücadeleniz ruhunuzu sınayacak. Üçüncü parça kendi lideriniz tarafından tutuluyor. Seni öldürmen için gönderdiğiyle aynı kişi. +Macil? A traitor?,TXT_RPLY0_SCRIPT12_D4548_MACIL,,,,Macil? Zrádce?,Macil? En forræder?,Macil? Ein Verräter?,,,¿Macil? ¿Un traidor?,,Macil? Petturiko?,Macil? Un traître?,Macil? Egy áruló volna?,Macil? Un traditore?,マシル?彼が裏切者?,마실이 배신자라고?,Macil? Een verrader?,Macil? En forræder?,Macil? Zdrajca?,Macil? Um traidor?,,Macil? Un trădător?,Мэйсил? Предатель?,,Macil? En förrädare?,Macil mi? Bir hain mi? Your blind faith has allowed him to advance to his goals with each piece you gain. Confront him and resolve your fate.,TXT_DLG_SCRIPT12_D6064_YOURB,,,,"Tvá slepá víra mu dovolila přiblížit se k jeho cíli s každým dalším dílem, jenž získáš. Postav se mu a rozhodni svůj osud.","Din blinde tro har gjort det muligt for ham at komme videre til sine mål med hver brik, du får. Konfronter ham, og afklar din skæbne.","Deine blinde Treue hat es ihm erlaubt, seine eigenen Ziele voranzutreiben - mit jedem Fragment, das du findest. Konfrontiere ihn und kläre dein Schicksal.",,,Tu fé ciega le ha permitido avanzar en sus objetivos con cada pieza que ganas. Confróntalo y resuelve tu destino.,,Sokea uskosi on sallinut hänen edistää omia tavoitteitaan jokaisen saavuttamasi osasen myötä. Kohtaa hänet ja päätä kohtalosi.,"Votre dévotion aveugle lui a permis d'avancer vers ses fins. Avec chaque fragment que vous récupérez, il s'en rapproche encore. Confrontez le et faites-face à votre destinée.","A vakon belé vetett hited segített számára, hogy minden darabkával közelebb jusson a céljához. Szembesítsd vele, és tisztázd le magadban a hited.",La tua fede cieca gli ha permesso di raggiungere i suoi obiettivi con ogni pezzo che ottieni. Affrontalo e risolvi il tuo destino.,"彼を妄信するお主の活躍によって、 彼奴の目的が果たされる間近だ。 -彼奴に立ち向かい、運命を切り開くのだ。",그대의 맹목적인 믿음이 조각들을 하나하나 찾으면서 그자의 목표를 이뤄주고 있다. 그를 상대하고 구속된 운명에서 벗어나라.,Jouw blinde geloof heeft hem in staat gesteld om met elk stuk dat je wint zijn doelen te bereiken. Confronteer hem en los je lot op.,Din blinde tro har gjort det mulig for ham å nå sine mål for hver brikke du vinner. Konfronter ham og avgjør din skjebne.,Twoja ślepa wiara pozwoliła mu na osiągnięcie celu z każdym zdobytym kawałkiem. Skonfrontuj się z nim i rozstrzygnij swój los.,Sua fé cega permitiu que ele avance em suas metas com cada peça que você adquire. Vá confrontá-lo e resolva o seu destino.,,"Credința ta oarbă i-a permis să-și avanseze planurile, cu fiecare piesă pe care o obții. Înfruntă-l și împlinește-ți destinul.","Твоя слепая вера приближала его к цели каждый раз, как ты находил фрагмент. Сразись с ним и исполни своё предназначение.",,"Kör inancınız, kazandığınız her parçayla hedeflerine ilerlemesine izin verdi. Onunla yüzleş ve kaderini çöz." -"All right, it is Macil.",TXT_RPLY0_SCRIPT12_D6064_ALLRI,,,,"Tak dobře, je to Macil.","Okay, det er Macil.","Na gut, es ist Macil.",,,"Muy bien, es Macil.",,"Niin se on, se on Macil.",Très bien. C'est le tour de Macil.,"Igazad volt, Macil az.","Va bene, è Macil.",わかった、それがマシルか。,역시... 마실이였군.,"Oké, het is Macil.","Greit, det er Macil.","W porządku, to Macil.",Certo. Então é o Macil.,,"Bine, Macil să fie.",Понятно. Я убью Мэйсила.,,"Pekala, bu Macil." -It's you I don't trust.,TXT_RPLY1_SCRIPT12_D6064_ITSYO,,,,Ale já nevěřím tobě.,"Det er dig, jeg ikke stoler på.","Du bist es, dem ich nicht vertraue.",,,Eres tú de quien no me fío.,,Sinuun en minä luota.,C'est vous à qui je ne fais pas confiance.,"Te vagy az, akiben nem bízok.",Sei tu quello di cui non mi fido.,信用できん。,내가 믿지 않는 건 네놈이다.,Ik vertrouw jou niet.,Det er deg jeg ikke stoler på.,To tobie nie ufam.,É você em quem eu não confio.,,Tu ești cel în care nu am încredere.,"Я думаю, что это ты лжешь!",,Güvenmediğim sensin. +彼奴に立ち向かい、運命を切り開くのだ。",그대의 맹목적인 믿음이 조각들을 하나하나 찾으면서 그자의 목표를 이뤄주고 있다. 그를 상대하고 구속된 운명에서 벗어나라.,Jouw blinde geloof heeft hem in staat gesteld om met elk stuk dat je wint zijn doelen te bereiken. Confronteer hem en los je lot op.,Din blinde tro har gjort det mulig for ham å nå sine mål for hver brikke du vinner. Konfronter ham og avgjør din skjebne.,Twoja ślepa wiara pozwoliła mu na osiągnięcie celu z każdym zdobytym kawałkiem. Skonfrontuj się z nim i rozstrzygnij swój los.,Sua fé cega permitiu que ele avance em suas metas com cada peça que você adquire. Vá confrontá-lo e resolva o seu destino.,,"Credința ta oarbă i-a permis să-și avanseze planurile, cu fiecare piesă pe care o obții. Înfruntă-l și împlinește-ți destinul.","Твоя слепая вера приближала его к цели каждый раз, как ты находил фрагмент. Сразись с ним и исполни своё предназначение.",,Din blinda tro har gjort det möjligt för honom att avancera mot sina mål med varje bit du vinner. Konfrontera honom och lös ditt öde.,"Kör inancınız, kazandığınız her parçayla hedeflerine ilerlemesine izin verdi. Onunla yüzleş ve kaderini çöz." +"All right, it is Macil.",TXT_RPLY0_SCRIPT12_D6064_ALLRI,,,,"Tak dobře, je to Macil.","Okay, det er Macil.","Na gut, es ist Macil.",,,"Muy bien, es Macil.",,"Niin se on, se on Macil.",Très bien. C'est le tour de Macil.,"Igazad volt, Macil az.","Va bene, è Macil.",わかった、それがマシルか。,역시... 마실이였군.,"Oké, het is Macil.","Greit, det er Macil.","W porządku, to Macil.",Certo. Então é o Macil.,,"Bine, Macil să fie.",Понятно. Я убью Мэйсила.,,"Okej, det är Macil.","Pekala, bu Macil." +It's you I don't trust.,TXT_RPLY1_SCRIPT12_D6064_ITSYO,,,,Ale já nevěřím tobě.,"Det er dig, jeg ikke stoler på.","Du bist es, dem ich nicht vertraue.",,,Eres tú de quien no me fío.,,Sinuun en minä luota.,C'est vous à qui je ne fais pas confiance.,"Te vagy az, akiben nem bízok.",Sei tu quello di cui non mi fido.,信用できん。,내가 믿지 않는 건 네놈이다.,Ik vertrouw jou niet.,Det er deg jeg ikke stoler på.,To tobie nie ufam.,É você em quem eu não confio.,,Tu ești cel în care nu am încredere.,"Я думаю, что это ты лжешь!",,Det är dig jag inte litar på.,Güvenmediğim sensin. Whatever choice you make your kind shall perish under the will of the One God.,TXT_DLG_SCRIPT12_D7580_WHATE,,,,"Nehledě na tvé rozhodnutí, tvůj druh skoná vůlí Jednoho boha.","Uanset hvilket valg du træffer, vil din slags gå under under den ene Guds vilje.","Welche Wahl du auch triffst, deine Spezies wird unter dem Willen des Einen Gottes zugrunde gehen.",,,Cualquiera que sea tu elección tu especie perecerá bajo la voluntad del Dios Único.,,"Teitpä minkä hyvänsä päätöksen, lajisi pitää hukkuman Yhden Ainoan Jumalan tahdon alle.","Quel que soit le choix que vous faites, votre espèce périra par la volonté du Seul Dieu.","Mindegy mire döntesz, az egy igaz isten szigora lesúlyt rád és fajtádra.","Qualunque scelta tu faccia, la tua specie perirà per il volere dell'Unico Dio.","如何なる選択でも、人類は大いなる神の元で -浄化されるだろう。","그대가 어떤 선택을 하더라도, 그대를 비롯한 종족은 유일신의 의지에 의해 멸망할 뿐이다.","Welke keuze je ook maakt, jouw soort zal vergaan onder de wil van de Ene God.","Uansett hvilket valg du tar, vil din art gå til grunne under den ene Guds vilje.","Jakiegokolwiek wyboru dokonasz, twój rodzaj zginie z woli Jedynego Boga.","Seja qual for a escolha que você fizer, sua espécie irá perecer sob a vontade do Deus Único.",,"Indiferent de alegerea ta, neamul tău va pieri sub voința Adevăratului Zeu.","Что бы ты ни выбрал, твой род исчезнет по воле Единого Бога.",,"Yaptığın seçim ne olursa olsun, türün Tek Tanrı'nın iradesi altında yok olacak." -I'll be back when Macil's dead.,TXT_RPLY0_SCRIPT12_D7580_ILLBE,,,,"Vrátím se, až bude Macil mrtev.","Jeg kommer tilbage, når Macil er død.","Ich komme wieder, wenn Macil tot ist.",,,Volveré cuando Macil esté muerto.,,"Tulen takaisin, kun Macil on kuollut.",Je reviendrai quand Macil sera mort.,"Visszajövök, ha Macil már halott.",Tornerò quando Macil sarà morto.,マシルの死と共に戻る。,마실을 죽이고 돌아오겠다.,Ik kom terug als Macil dood is.,Jeg kommer tilbake når Macil er død.,"Wrócę, gdy Macil będzie martwy.",Voltarei quando Macil estiver morto.,,Am să mă întorc odată ce Macil e mort.,Я вернусь после смерти Мэйсила.,,Macil öldüğünde geri döneceğim. -I can't let that happen.,TXT_RPLY1_SCRIPT12_D7580_ICANT,,,,To nemůžu dopustit.,Jeg kan ikke lade det ske.,Das darf nicht passieren.,,,No pienso permitirlo.,,En voi antaa sen tapahtua.,Je ne peux pas vous laisser faire ça.,Nem hagyhatom ezt.,Non posso permetterlo.,そうはさせん。,그렇게 할 순 없어.,Dat kan ik niet laten gebeuren.,Jeg kan ikke la det skje.,Nie mogę na to pozwolić.,Não posso deixar isso acontecer.,,Nu voi permite asta.,Я не могу этого допустить.,,Bunun olmasına izin veremem. -"The river of time moves forever onward, while you stand still.",TXT_DLG_SCRIPT12_D9096_THERI,,,,Řeka času plyne stále vpřed zatímco ty zůstáváš stát.,"Tidens flod bevæger sig for evigt fremad, mens du står stille.","Der Fluss der Zeit bewegt sich immer vorwärts, während du stillstehst.",,,"La corriente del tiempo sigue adelante, mientras tú sigues quieto.",,"Ajan virta liikkuu alati eteenpäin, samalla kun itse pysyt aloillasi.","La rivière du temps continue à couler, tandis que vous restez immobile.","Az idő folyója folyamat halad tovább, miközben te csak álldogállsz.","Il fiume del tempo scorre inesorabilmente, mentre tu rimani fermo.",事を措いても、時の河は永遠の先に進む。,"그대가 가만히 있어도, 시간의 강은 계속 흐를 뿐이다.","De rivier van de tijd beweegt voor altijd verder, terwijl je stilstaat.","Tidens elv beveger seg evig videre, mens du står stille.","Rzeka czasu płynie wiecznie do przodu, podczas gdy ty stoisz w miejscu.","O corrente do tempo se movimenta sempre adiante, enquanto você fica imóvel.",,"Râul timpului curge în permanență, în timp ce tu stai pe loc.","Река времени непрестанно течёт вперёд, в то время как ты стоишь без движения.",,"Sen dururken, zaman nehri sonsuza dek ilerliyor." +浄化されるだろう。","그대가 어떤 선택을 하더라도, 그대를 비롯한 종족은 유일신의 의지에 의해 멸망할 뿐이다.","Welke keuze je ook maakt, jouw soort zal vergaan onder de wil van de Ene God.","Uansett hvilket valg du tar, vil din art gå til grunne under den ene Guds vilje.","Jakiegokolwiek wyboru dokonasz, twój rodzaj zginie z woli Jedynego Boga.","Seja qual for a escolha que você fizer, sua espécie irá perecer sob a vontade do Deus Único.",,"Indiferent de alegerea ta, neamul tău va pieri sub voința Adevăratului Zeu.","Что бы ты ни выбрал, твой род исчезнет по воле Единого Бога.",,Vilket val du än gör kommer din sort att förgås under den ende Gudens vilja.,"Yaptığın seçim ne olursa olsun, türün Tek Tanrı'nın iradesi altında yok olacak." +I'll be back when Macil's dead.,TXT_RPLY0_SCRIPT12_D7580_ILLBE,,,,"Vrátím se, až bude Macil mrtev.","Jeg kommer tilbage, når Macil er død.","Ich komme wieder, wenn Macil tot ist.",,,Volveré cuando Macil esté muerto.,,"Tulen takaisin, kun Macil on kuollut.",Je reviendrai quand Macil sera mort.,"Visszajövök, ha Macil már halott.",Tornerò quando Macil sarà morto.,マシルの死と共に戻る。,마실을 죽이고 돌아오겠다.,Ik kom terug als Macil dood is.,Jeg kommer tilbake når Macil er død.,"Wrócę, gdy Macil będzie martwy.",Voltarei quando Macil estiver morto.,,Am să mă întorc odată ce Macil e mort.,Я вернусь после смерти Мэйсила.,,Jag kommer tillbaka när Macil är död.,Macil öldüğünde geri döneceğim. +I can't let that happen.,TXT_RPLY1_SCRIPT12_D7580_ICANT,,,,To nemůžu dopustit.,Jeg kan ikke lade det ske.,Das darf nicht passieren.,,,No pienso permitirlo.,,En voi antaa sen tapahtua.,Je ne peux pas vous laisser faire ça.,Nem hagyhatom ezt.,Non posso permetterlo.,そうはさせん。,그렇게 할 순 없어.,Dat kan ik niet laten gebeuren.,Jeg kan ikke la det skje.,Nie mogę na to pozwolić.,Não posso deixar isso acontecer.,,Nu voi permite asta.,Я не могу этого допустить.,,Jag kan inte låta det hända.,Bunun olmasına izin veremem. +"The river of time moves forever onward, while you stand still.",TXT_DLG_SCRIPT12_D9096_THERI,,,,Řeka času plyne stále vpřed zatímco ty zůstáváš stát.,"Tidens flod bevæger sig for evigt fremad, mens du står stille.","Der Fluss der Zeit bewegt sich immer vorwärts, während du stillstehst.",,,"La corriente del tiempo sigue adelante, mientras tú sigues quieto.",,"Ajan virta liikkuu alati eteenpäin, samalla kun itse pysyt aloillasi.","La rivière du temps continue à couler, tandis que vous restez immobile.","Az idő folyója folyamat halad tovább, miközben te csak álldogállsz.","Il fiume del tempo scorre inesorabilmente, mentre tu rimani fermo.",事を措いても、時の河は永遠の先に進む。,"그대가 가만히 있어도, 시간의 강은 계속 흐를 뿐이다.","De rivier van de tijd beweegt voor altijd verder, terwijl je stilstaat.","Tidens elv beveger seg evig videre, mens du står stille.","Rzeka czasu płynie wiecznie do przodu, podczas gdy ty stoisz w miejscu.","O corrente do tempo se movimenta sempre adiante, enquanto você fica imóvel.",,"Râul timpului curge în permanență, în timp ce tu stai pe loc.","Река времени непрестанно течёт вперёд, в то время как ты стоишь без движения.",,"Tidens flod rör sig för evigt framåt, medan du står stilla.","Sen dururken, zaman nehri sonsuza dek ilerliyor." "You have cut the cancer from your body, but your heart still beats. Next you must find the surgeon who butchers and controls your people, the Loremaster. Stop him, and the next piece will be yours.",TXT_DLG_SCRIPT12_D10612_YOUHA,,,,"Vyřízl jsi rakovinu ze svého těla, tvé srdce však stále bije. Dále musíš najít doktora, jenž vraždí a ovládá tvé druhy, Dějepisce. Učiň mu přítrž a další díl bude tvůj.","Du har skåret kræften ud af din krop, men dit hjerte slår stadig. Nu skal du finde den kirurg, der slagter og kontrollerer dit folk, Loremesteren. Stop ham, og det næste stykke vil være dit.","Du hast das Geschwür aus deinem Körper entferrnt, aber dein Herz schlägt noch. Als Nächstes musst du den Wissensmeister finden, der deine Leute kontrolliert und abschlachtet. Stoppe ihn und das nächste Teilstück ist Dein.",,,"Has cortado el cáncer de tu cuerpo, pero tu corazón aún late. Lo siguiente es encontrar al cirujano que destroza y controla a tu gente, el Maestro del Conocimiento. Deténlo, y la próxima pieza será tuya.",,"Olet erottanut syövän ruumiistasi, mutta sydämesi silti sykkii. Seuraavaksi pitää sinun löytämän kirugin, joka teurastaa ja hallitsee kansaasi: Oppi-Isän. Pysäytä hänet, ja seuraava osanen on oleva sinun.","Vous avez arraché le cancer de votre corps, mais le cœur bat encore. Vous devez maintenant trouver le chirurgien qui massacre votre peuple, le Maître des traditions. Arrètez-le, et le fragment suivant sera le vôtre.","Kioperáltad a rákos sejteket a testedből, de a szíved még mindig ver. Most meg kell találnod azt a sebészt, aki lemészárolja és kontrollálja a néped. Ő nem más, mint a Tanmester. Állítsd meg, és a következő darabka a tied.","Hai eliminato il cancro dal tuo corpo, ma il tuo cuore batte ancora. Adesso devi trovare il chirurgo che macella e controlla la tua gente, il Sapiente. Fermalo e il prossimo pezzo sarà tuo.","心に動揺が見られるな、だがお主は己の体から 癌を取り除いた。次の欠片は 人々を虐殺で支配するロアマスター外科医が -所持している。彼奴を止め、欠片を得るのだ。","그대 몸 안의 암 덩어리를 잘라냈건만, 심장은 여전히 뛰고 있구나. 다음은 네 종족의 도살과 지배를 책임졌던 로어마스터다. 그를 막아내면, 다음 조각은 너의 것이다.","Je hebt de kanker uit je lichaam gesneden, maar je hart klopt nog steeds. Vervolgens moet je de chirurg vinden die je volk afslacht en controleert, de Loremaster. Stop hem, en het volgende stuk zal van jou zijn.","Du har fjernet kreften fra kroppen din, men hjertet ditt slår fortsatt. Nå må du finne kirurgen som slakter og kontrollerer folket ditt, Loremesteren. Stopp ham, og det neste stykket blir ditt.","Wyciąłeś raka ze swojego ciała, ale twoje serce wciąż bije. Następnie musisz znaleźć chirurga, który rzeźbi i kontroluje twój lud, Loremastera. Powstrzymaj go, a następny kawałek będzie twój.","Você arrancou o câncer do seu corpo, mas seu coração ainda bate. Agora você deve encontrar o cirurgião que mutila e controla o seu povo, o Mestre do Conhecimento. Detenha-o e a próxima peça será sua.",,"Ai scăpat de cancerul din corp, dar inima ta încă bate. Mai departe, trebuie să îl găsești pe chirurgul care îți controlează și măcelărește oamenii, Stăpânul Învățăturilor. Oprește-l, și următoarea piesă va fi a ta.","Ты вырезал опухоль из своего тела, но твоё сердце всё ещё бьётся. Теперь тебе предстоит найти хирурга, который вскрывает твоих людей и управляет ими: Хранителя мудрости. Останови его, и следующий фрагмент твой.",,"Kanseri vücudunuzdan attınız ama kalbiniz hala atıyor. Şimdi halkını katleden ve kontrol eden cerrahı, Loremaster'ı bulmalısın. Onu durdurursan, bir sonraki parça senin olacak." -Where do I find him?,TXT_RPLY0_SCRIPT12_D10612_WHERE,,,,Kde ho najdu?,Hvor kan jeg finde ham?,Wo finde ich ihn?,,,¿Dónde lo encuentro?,,Mistä löydän hänet?,Où puis-je le trouver?,Hol találom meg?,Dove lo trovo.,そいつはどうやって見つける?,어디를 가야 그를 발견할 수 있지?,Waar vind ik hem?,Hvor finner jeg ham?,Gdzie go znajdę?,Onde encontro ele?,,Unde îl găsesc?,Где мне искать его?,,Onu nerede bulabilirim? +所持している。彼奴を止め、欠片を得るのだ。","그대 몸 안의 암 덩어리를 잘라냈건만, 심장은 여전히 뛰고 있구나. 다음은 네 종족의 도살과 지배를 책임졌던 로어마스터다. 그를 막아내면, 다음 조각은 너의 것이다.","Je hebt de kanker uit je lichaam gesneden, maar je hart klopt nog steeds. Vervolgens moet je de chirurg vinden die je volk afslacht en controleert, de Loremaster. Stop hem, en het volgende stuk zal van jou zijn.","Du har fjernet kreften fra kroppen din, men hjertet ditt slår fortsatt. Nå må du finne kirurgen som slakter og kontrollerer folket ditt, Loremesteren. Stopp ham, og det neste stykket blir ditt.","Wyciąłeś raka ze swojego ciała, ale twoje serce wciąż bije. Następnie musisz znaleźć chirurga, który rzeźbi i kontroluje twój lud, Loremastera. Powstrzymaj go, a następny kawałek będzie twój.","Você arrancou o câncer do seu corpo, mas seu coração ainda bate. Agora você deve encontrar o cirurgião que mutila e controla o seu povo, o Mestre do Conhecimento. Detenha-o e a próxima peça será sua.",,"Ai scăpat de cancerul din corp, dar inima ta încă bate. Mai departe, trebuie să îl găsești pe chirurgul care îți controlează și măcelărește oamenii, Stăpânul Învățăturilor. Oprește-l, și următoarea piesă va fi a ta.","Ты вырезал опухоль из своего тела, но твоё сердце всё ещё бьётся. Теперь тебе предстоит найти хирурга, который вскрывает твоих людей и управляет ими: Хранителя мудрости. Останови его, и следующий фрагмент твой.",,"Du har skurit bort cancern från din kropp, men ditt hjärta slår fortfarande. Nu måste du hitta kirurgen som slaktar och kontrollerar ditt folk, Läromästaren. Stoppa honom och nästa bit kommer att bli din.","Kanseri vücudunuzdan attınız ama kalbiniz hala atıyor. Şimdi halkını katleden ve kontrol eden cerrahı, Loremaster'ı bulmalısın. Onu durdurursan, bir sonraki parça senin olacak." +Where do I find him?,TXT_RPLY0_SCRIPT12_D10612_WHERE,,,,Kde ho najdu?,Hvor kan jeg finde ham?,Wo finde ich ihn?,,,¿Dónde lo encuentro?,,Mistä löydän hänet?,Où puis-je le trouver?,Hol találom meg?,Dove lo trovo.,そいつはどうやって見つける?,어디를 가야 그를 발견할 수 있지?,Waar vind ik hem?,Hvor finner jeg ham?,Gdzie go znajdę?,Onde encontro ele?,,Unde îl găsesc?,Где мне искать его?,,Var hittar jag honom?,Onu nerede bulabilirim? "Use the teleporter behind the door I just opened to reach the Loremaster. When he is dead, use the same device to return to me.",TXT_DLG_SCRIPT12_D12128_USETH,,,,"Dostaň se k Dějepisci pomocí teleportéru za dveřmi, které jsem právě otevřel. Když je mrtev, použij stejné zařízení k návratu ke mě.","Brug teleporteren bag den dør, jeg lige har åbnet, for at nå Loremesteren. Når han er død, skal du bruge den samme anordning til at vende tilbage til mig.","Benutze den Teleporter hinter der Tür, die ich gerade geöffnet habe. Wenn er tot ist, benutze dasselbe Gerät, um zu mir zurückzukehren.",,,"Usa el teleportador tras la puerta que he abierto para llegar hasta el Maestro del Conocimiento. Cuando esté muerto, usa el mismo dispositivo para volver a mí.",,"Käytä juuri avaamani oven takana olevaa kaukosiirrintä tavoittaaksesi Oppi-Isän. Kun hän on kuollut, käytä samaa laitetta palataksesi tyköni.","Utilisez le téléporteur derrière la porte que je viens d'ouvrir pour trouver le Maître des traditions. Quand il sera mort, utilisez ce même téléporteur pour revenir ici.","Használd a kinyílt ajtó mögötti portált a Tanmesterhez. Ha meghalt, használd a visszaútra is.","Usa il teletrasporto dietro la porta che ho appena sbloccato per raggiungere il Sapiente. Quando è morto, usa lo stesso teletrasporto per tornare da me.","我の傍にあるテレポーターの扉を開いた。 それがロアマスターの元に通ずる。 彼奴に死を伝えた後、再び扉を通るがよい。","내가 로어마스터로 향하는 순간이동 장치를 열어두었다. 그 자가 죽으면, 똑같은 장치를 써서 다시 나에게 오라. - \cy못생기긴 했어도, 이 양반 우리 편인 것 같네.","Gebruik de teleporter achter de deur die ik net heb geopend om de Loremaster te bereiken. Als hij dood is, gebruik je hetzelfde apparaat om terug te keren naar mij.","Bruk teleporteren bak døren jeg nettopp åpnet for å nå Loremaster. Når han er død, bruk samme apparat for å komme tilbake til meg.","Użyj teleportera za drzwiami, które właśnie otworzyłem, aby dotrzeć do Loremastera. Gdy będzie martwy, użyj tego samego urządzenia, by wrócić do mnie.","Use o teletransportador atrás da porta que eu acabei de abrir para chegar até o Mestre do Conhecimento. Quando ele morrer, use o mesmo dispositivo e retorne a mim.",,"Folosește teleportoul din spatele ușii pe care tocmai am deschis-o. După ce e mort, folosește același dispozitiv pentru a te întoarce la mine.","Используй телепорт за той дверью, что я только что открыл, чтобы добраться до Хранителя. Когда он умрёт, найди другой телепорт, чтобы вернуться ко мне.",,"Loremaster'a ulaşmak için az önce açtığım kapının arkasındaki ışınlayıcıyı kullan. O öldüğünde, bana dönmek için aynı cihazı kullan." -"I'll be back, with his piece!",TXT_RPLY0_SCRIPT12_D12128_ILLBE,,,,Vrátím se s jeho dílem!,Jeg kommer tilbage med hans brik!,"Ich komme wieder, mit dem Teilstück.",,,"Volveré, ¡con su pieza!",,Tulen takaisin hänen osasensa kanssa!,"Je reviendrai, avec son fragment!","Visszatérek, mégpedig a darabkájával!","Ritornerò, con il suo pezzo!",欠片を持ってすぐ戻る!,녀석의 조각을 가지고 다시 올게!,"Ik kom terug, met zijn stuk!","Jeg kommer tilbake, med hans del!",Wrócę z jego kawałkiem!,"Eu voltarei, com a peça dele!",,"Mă voi întoarce, cu piesa lui.",Я достану его фрагмент!,,Onun parçasıyla geri döneceğim! -"The river of time moves forever onward, while you stand still.",TXT_DLG_SCRIPT12_D13644_THERI,,,,Řeka času plyne stále vpřed zatímco ty zůstáváš stát.,"Tidens flod bevæger sig for evigt fremad, mens du står stille.","Der Fluss der Zeit bewegt sich immer vorwärts, während du stillstehst.",,,"La corriente del tiempo sigue adelante, mientras tú sigues quieto.",,"Ajan virta liikkuu alati eteenpäin, samalla kun itse pysyt aloillasi.","La rivière du temps continue à couler, tandis que vous restez immobile.","Az idő folyója folyamat halad tovább, miközben te csak álldogállsz.","Il fiume del tempo scorre inesorabilmente, mentre tu rimani fermo.",事を措いても、時の河は永遠の先に進む。,"발버둥을 친다해도, 시간의 강은 계속 흐를 뿐.","De rivier van de tijd beweegt voor altijd verder, terwijl je stilstaat.","Tidens elv beveger seg evig fremover, mens du står stille.","Rzeka czasu płynie wiecznie, podczas gdy ty stoisz w miejscu.","O corrente do tempo se movimenta sempre adiante, enquanto você fica imóvel.",,"Râul timpului curge în permanență, în timp ce tu stai pe loc.","Река времени непрестанно течёт вперёд, в то время как ты стоишь без движения.",,Zaman nehri sonsuza dek ilerlerken sen duruyorsun. + \cy못생기긴 했어도, 이 양반 우리 편인 것 같네.","Gebruik de teleporter achter de deur die ik net heb geopend om de Loremaster te bereiken. Als hij dood is, gebruik je hetzelfde apparaat om terug te keren naar mij.","Bruk teleporteren bak døren jeg nettopp åpnet for å nå Loremaster. Når han er død, bruk samme apparat for å komme tilbake til meg.","Użyj teleportera za drzwiami, które właśnie otworzyłem, aby dotrzeć do Loremastera. Gdy będzie martwy, użyj tego samego urządzenia, by wrócić do mnie.","Use o teletransportador atrás da porta que eu acabei de abrir para chegar até o Mestre do Conhecimento. Quando ele morrer, use o mesmo dispositivo e retorne a mim.",,"Folosește teleportoul din spatele ușii pe care tocmai am deschis-o. După ce e mort, folosește același dispozitiv pentru a te întoarce la mine.","Используй телепорт за той дверью, что я только что открыл, чтобы добраться до Хранителя. Когда он умрёт, найди другой телепорт, чтобы вернуться ко мне.",,Använd teleportern bakom dörren som jag just öppnade för att nå Läromästaren. När han är död använder du samma anordning för att återvända till mig.,"Loremaster'a ulaşmak için az önce açtığım kapının arkasındaki ışınlayıcıyı kullan. O öldüğünde, bana dönmek için aynı cihazı kullan." +"I'll be back, with his piece!",TXT_RPLY0_SCRIPT12_D12128_ILLBE,,,,Vrátím se s jeho dílem!,Jeg kommer tilbage med hans brik!,"Ich komme wieder, mit dem Teilstück.",,,"Volveré, ¡con su pieza!",,Tulen takaisin hänen osasensa kanssa!,"Je reviendrai, avec son fragment!","Visszatérek, mégpedig a darabkájával!","Ritornerò, con il suo pezzo!",欠片を持ってすぐ戻る!,녀석의 조각을 가지고 다시 올게!,"Ik kom terug, met zijn stuk!","Jeg kommer tilbake, med hans del!",Wrócę z jego kawałkiem!,"Eu voltarei, com a peça dele!",,"Mă voi întoarce, cu piesa lui.",Я достану его фрагмент!,,Jag kommer tillbaka med hans pjäs!,Onun parçasıyla geri döneceğim! +"The river of time moves forever onward, while you stand still.",TXT_DLG_SCRIPT12_D13644_THERI,,,,Řeka času plyne stále vpřed zatímco ty zůstáváš stát.,"Tidens flod bevæger sig for evigt fremad, mens du står stille.","Der Fluss der Zeit bewegt sich immer vorwärts, während du stillstehst.",,,"La corriente del tiempo sigue adelante, mientras tú sigues quieto.",,"Ajan virta liikkuu alati eteenpäin, samalla kun itse pysyt aloillasi.","La rivière du temps continue à couler, tandis que vous restez immobile.","Az idő folyója folyamat halad tovább, miközben te csak álldogállsz.","Il fiume del tempo scorre inesorabilmente, mentre tu rimani fermo.",事を措いても、時の河は永遠の先に進む。,"발버둥을 친다해도, 시간의 강은 계속 흐를 뿐.","De rivier van de tijd beweegt voor altijd verder, terwijl je stilstaat.","Tidens elv beveger seg evig fremover, mens du står stille.","Rzeka czasu płynie wiecznie, podczas gdy ty stoisz w miejscu.","O corrente do tempo se movimenta sempre adiante, enquanto você fica imóvel.",,"Râul timpului curge în permanență, în timp ce tu stai pe loc.","Река времени непрестанно течёт вперёд, в то время как ты стоишь без движения.",,"Tidens flod rör sig för evigt framåt, medan du står stilla.",Zaman nehri sonsuza dek ilerlerken sen duruyorsun. "Pitiful man, you have done what thousands have failed to do... You bring me the power of the Sigil, the voice of the One God.",TXT_DLG_SCRIPT12_D15160_PITIF,,,,"Ubohý člověče, dokázal jsi to, co tisíce před tebou ne... Přinášíš mi moc Pečetě, hlas Jednoho boha.","Ynkelige mand, du har gjort, hvad tusindvis af mennesker ikke har formået... Du bringer mig Sigilets kraft, den ene Guds stemme.","Armseliger Wurm, du hast getan woran Tausende gescheitert sind... Du brachtest mir die Macht des Sigils, die Stimme des Einen Gottes.",,,"Despreciable humano, has hecho lo que miles no han podido... Traes ante mí el poder del Emblema, la voz del Dios Único.",,"Kurja ihminen, olet tehnyt sen, missä tuhannet ovat epäonnistuneet: Olet tuonut minulle Sinetin voiman, Yhden Ainoan Jumalan äänen.","Pathétique mortel, vous avez réussi là où des milliers ont failli.. Vous m'amenez le pouvoir du Sigil, la voix du Seul Dieu.","Szánalmas kis pondró, megtetted amit emberek ezrei sem tudtak megtenni...elhoztad számomra a Pecsét erejét, az egy igaz isten hangját.","Patetico umano, sei riuscito a fare ciò che in migliaia hanno fallito nel compiere... Mi hai portato il potere del Sigillo, la voce dell'Unico Dio.","気の毒な者よ、お主は幾千の者達が 遂げられなかった行いを果たした... -お主は我にシジルの力を、唯一神の声を届けた。","애처로운 자여, 지금껏 수천 명이 이루지 못했던 일을 해내었다... 나에게 시질의 힘을, 유일신의 목소리를 전해주는구나.","Jammer man, je hebt gedaan wat duizenden mensen niet hebben gedaan.... Je brengt me de kracht van de Sigil, de stem van de Ene God.","Stakkars mann, du har gjort det tusener har mislyktes med... Du gir meg sigillets kraft, stemmen til den ene guden.","Żałosny człowieku, dokonałeś tego, czego nie udało się zrobić tysiącom... Przynosisz mi moc Sigil, głos Jedynego Boga.","Que homem patético. Você fez o que milhares não conseguiram... Você me trouxe o poder do Sigilo, a voz do Deus Único.",,"Om jalnic, ai reușit ceea ce nu a reușit nimeni să facă.... Îmi aduci puterea Sigiliului, vocea Adevăratului Zeu.","Ничтожный человечишка, тебе удалось сделать то, с чем не справились тысячи... Ты принёс мне мощь Печати, глас Единого Бога.",,"Zavallı adam, binlerce kişinin yapamadığını yaptın. Bana Sigil'in gücünü, Tek Tanrı'nın sesini getirdin." -I don't understand.,TXT_RPLY0_SCRIPT12_D15160_IDONT,,,,Nerozumím ti.,Jeg forstår ikke.,Ich verstehe nicht.,,Mi ne komprenas.,No entiendo.,,En ymmärrä.,Je ne comprends pas.,Nem értem.,Non capisco.,わからないな。,무슨 소리야?,Ik begrijp het niet.,Jeg forstår ikke.,Nie rozumiem.,Eu não entendo.,,Nu înțeleg.,Я не понимаю.,,Anlamıyorum. +お主は我にシジルの力を、唯一神の声を届けた。","애처로운 자여, 지금껏 수천 명이 이루지 못했던 일을 해내었다... 나에게 시질의 힘을, 유일신의 목소리를 전해주는구나.","Jammer man, je hebt gedaan wat duizenden mensen niet hebben gedaan.... Je brengt me de kracht van de Sigil, de stem van de Ene God.","Stakkars mann, du har gjort det tusener har mislyktes med... Du gir meg sigillets kraft, stemmen til den ene guden.","Żałosny człowieku, dokonałeś tego, czego nie udało się zrobić tysiącom... Przynosisz mi moc Sigil, głos Jedynego Boga.","Que homem patético. Você fez o que milhares não conseguiram... Você me trouxe o poder do Sigilo, a voz do Deus Único.",,"Om jalnic, ai reușit ceea ce nu a reușit nimeni să facă.... Îmi aduci puterea Sigiliului, vocea Adevăratului Zeu.","Ничтожный человечишка, тебе удалось сделать то, с чем не справились тысячи... Ты принёс мне мощь Печати, глас Единого Бога.",,"Du har gjort vad tusentals har misslyckats med att göra... Du ger mig Sigillets kraft, den ende Gudens röst.","Zavallı adam, binlerce kişinin yapamadığını yaptın. Bana Sigil'in gücünü, Tek Tanrı'nın sesini getirdin." +I don't understand.,TXT_RPLY0_SCRIPT12_D15160_IDONT,,,,Nerozumím ti.,Jeg forstår ikke.,Ich verstehe nicht.,,Mi ne komprenas.,No entiendo.,,En ymmärrä.,Je ne comprends pas.,Nem értem.,Non capisco.,わからないな。,무슨 소리야?,Ik begrijp het niet.,Jeg forstår ikke.,Nie rozumiem.,Eu não entendo.,,Nu înțeleg.,Я не понимаю.,,Jag förstår inte.,Anlamıyorum. The Sigil will open the door and free the spirit which will cleanse this planet and let me live forever. I will strip this world of its energies and find new worlds to conquer.,TXT_DLG_SCRIPT12_D16676_THESI,,,,"Pečeť otevře brány a uvolní duši, která očistí tuto planetu a dovolí mi žít navěky. Vysaju tento svět jeho sil a najdu další světy k podmanutí.","Sigilet vil åbne døren og frigøre ånden, som vil rense denne planet og lade mig leve for evigt. Jeg vil fratage denne verden dens energier og finde nye verdener at erobre.","Das Sigil wird die Tür öffnen und den Geist befreien, den Planeten läutern und mich für immer leben lassen. Ich werde dieser Welt alle Energie entziehen und neue Welten finden, um sie zu erobern.",,,El Emblema abrirá la puerta y liberará el espíritu que limpiará éste planeta y me dejará vivir eternamente. Despojaré a este mundo de su energía y buscaré otros que conquistar.,,"Sinetti aukaisee portin ja vapauttaa hengen, joka puhdistaa tämän planeetan ja antaa minun elää ikuisesti. Riisun tämän maailman sen energioista ja etsin uusia maailmoja vallattavaksi.",Le Sigil ouvrira la porte et libérera l'âme qui purifiera cette planète et me donnera la vie éternelle. J'arracherai toutes les énergies de ce monde et en trouverai d'autres à conquérir.,"A pecsét kinyitja az ajtót a lélek előtt, ami megtisztítja ezt a bolygót és örök életet biztosít számomra. Megfosztom ezt a világot az energiáitól, és továbblépek más világokba ha végeztem vele.",Il Sigillo aprirà la porta e libererà lo spirito che purificherà questo pianeta e mi lascerà vivere per sempre. Spoglierò questo mondo delle sue energie e troverò nuovi mondi da conquistare.,"シジルは門を開き、この惑星の魂を浄化し 我に永遠の命を授け給うのだ。我はこの世の 生命力を剥ぎ取り、新たなる星への征服に -駆り出すのだ。","시질은 잠겨저 있던 문을 열고, 이 세상을 정화할 혼령을 깨울 것이며, 나에게 영생을 선사할 것이다. 내가 이 세상의 기운을 모두 쓸어 담아 새로 정복할 세계를 찾아 나설 힘을 모을 것이다.",De Sigil zal de deur openen en de geest bevrijden die deze planeet zal reinigen en me voor altijd zal laten leven. Ik zal deze wereld van zijn energie ontdoen en nieuwe werelden vinden om te veroveren.,Sigllet vil åpne døren og frigjøre ånden som vil rense denne planeten og la meg leve evig. Jeg vil strippe denne verden for dens energier og finne nye verdener å erobre.,"Sigil otworzy drzwi i uwolni ducha, który oczyści tę planetę i pozwoli mi żyć wiecznie. Pozbawię ten świat jego energii i znajdę nowe światy do podbicia.",O Sigilo abrirá a porta e libertará o espirito que purificará este planeta e permitirá que eu viva para sempre. Arrancarei as energias deste mundo e encontrar novos mundos para conquistar.,,Sigiuliul va deschide ușa și elibera spiritul care va curăța planeta și mă va face nemuritor. Voi stoarce energia din planetă iar apoi voi găsi alte lumi de cucerit.,"Печать распахнёт дверь и высвободит сущность, что очистит эту планету и дарует мне вечную жизнь. Я выкраду всю энергию этого мира и отправлюсь на завоевание следующих.",,Sigil kapıyı açacak ve bu gezegeni temizleyecek ruhu serbest bırakacak ve sonsuza dek yaşamama izin verecek. Bu dünyayı enerjilerinden arındırıp fethedecek yeni dünyalar bulacağım. -I can't let you do that.,TXT_RPLY0_SCRIPT12_D16676_ICANT,,,,To ti nemůžu dovolit.,Det kan jeg ikke lade dig gøre.,Ich kann das nicht erlauben.,,,No puedo dejarte hacer eso.,,En voi antaa sinun tehdä sitä.,Je ne peux pas vous laisser faire ça.,Csak a holttestemen keresztül.,Non te lo posso permettere.,そんな真似はさせられないな。,네 놈의 음모를 막겠다!,Dat kan ik je niet laten doen.,Jeg kan ikke la deg gjøre det.,Nie mogę ci na to pozwolić.,Não vou deixar você fazer isso.,,Nu te pot lăsa să faci asta.,Я не могу этого допустить.,,Bunu yapmana izin veremem. -You can if you're dead.,TXT_DLG_SCRIPT12_D18192_YOUCA,,,,"Můžeš, když zemřeš.","Det kan du, hvis du er død.","Du kannst, wenn du tot bist.",,,"Puedes, si estás muerto.",,"Kyllä voit, jos olet kuollut.","Vous pouvez, une fois que vous êtes mort.",Ez megoldható.,Puoi... se sei morto!,お主の破滅は免れぬぞ。,네가 죽으면 될 것이다...,Dat kan je wel als je dood bent.,Du kan hvis du er død.,"Możesz, jeśli będziesz martwy.",Deixará se você estiver morto.,,"Poți, dacă ești mort.","Сможешь, когда умрёшь.",,Ölürsen izin verebilirsin. +駆り出すのだ。","시질은 잠겨저 있던 문을 열고, 이 세상을 정화할 혼령을 깨울 것이며, 나에게 영생을 선사할 것이다. 내가 이 세상의 기운을 모두 쓸어 담아 새로 정복할 세계를 찾아 나설 힘을 모을 것이다.",De Sigil zal de deur openen en de geest bevrijden die deze planeet zal reinigen en me voor altijd zal laten leven. Ik zal deze wereld van zijn energie ontdoen en nieuwe werelden vinden om te veroveren.,Sigllet vil åpne døren og frigjøre ånden som vil rense denne planeten og la meg leve evig. Jeg vil strippe denne verden for dens energier og finne nye verdener å erobre.,"Sigil otworzy drzwi i uwolni ducha, który oczyści tę planetę i pozwoli mi żyć wiecznie. Pozbawię ten świat jego energii i znajdę nowe światy do podbicia.",O Sigilo abrirá a porta e libertará o espirito que purificará este planeta e permitirá que eu viva para sempre. Arrancarei as energias deste mundo e encontrar novos mundos para conquistar.,,Sigiuliul va deschide ușa și elibera spiritul care va curăța planeta și mă va face nemuritor. Voi stoarce energia din planetă iar apoi voi găsi alte lumi de cucerit.,"Печать распахнёт дверь и высвободит сущность, что очистит эту планету и дарует мне вечную жизнь. Я выкраду всю энергию этого мира и отправлюсь на завоевание следующих.",,Sigillet kommer att öppna dörren och frigöra anden som kommer att rena den här planeten och låta mig leva för evigt. Jag kommer att beröva den här världen dess energier och hitta nya världar att erövra.,Sigil kapıyı açacak ve bu gezegeni temizleyecek ruhu serbest bırakacak ve sonsuza dek yaşamama izin verecek. Bu dünyayı enerjilerinden arındırıp fethedecek yeni dünyalar bulacağım. +I can't let you do that.,TXT_RPLY0_SCRIPT12_D16676_ICANT,,,,To ti nemůžu dovolit.,Det kan jeg ikke lade dig gøre.,Ich kann das nicht erlauben.,,,No puedo dejarte hacer eso.,,En voi antaa sinun tehdä sitä.,Je ne peux pas vous laisser faire ça.,Csak a holttestemen keresztül.,Non te lo posso permettere.,そんな真似はさせられないな。,네 놈의 음모를 막겠다!,Dat kan ik je niet laten doen.,Jeg kan ikke la deg gjøre det.,Nie mogę ci na to pozwolić.,Não vou deixar você fazer isso.,,Nu te pot lăsa să faci asta.,Я не могу этого допустить.,,Jag kan inte låta dig göra det.,Bunu yapmana izin veremem. +You can if you're dead.,TXT_DLG_SCRIPT12_D18192_YOUCA,,,,"Můžeš, když zemřeš.","Det kan du, hvis du er død.","Du kannst, wenn du tot bist.",,,"Puedes, si estás muerto.",,"Kyllä voit, jos olet kuollut.","Vous pouvez, une fois que vous êtes mort.",Ez megoldható.,Puoi... se sei morto!,お主の破滅は免れぬぞ。,네가 죽으면 될 것이다...,Dat kan je wel als je dood bent.,Du kan hvis du er død.,"Możesz, jeśli będziesz martwy.",Deixará se você estiver morto.,,"Poți, dacă ești mort.","Сможешь, когда умрёшь.",,Det kan du om du är död.,Ölürsen izin verebilirsin. "Are you here to free us? Because I've been good, they took my implant out. I still have to stay down here and wipe up the drool though.",TXT_DLG_SCRIPT14_D0_AREYO,,,,"Jsi tu, abys nás vysvobodil? Za dobré chování mi můj implantát vyndali. Stále tu ale musím zůstat a utírat sliny.","Er du her for at befri os? Fordi jeg har været god, tog de mit implantat ud. Jeg er dog stadig nødt til at blive hernede og tørre savlen op.","Bist du hier, um uns zu befreien? Ich war gut, sie haben mein Implasntat herasusgenommen. Ich muss aber hier bleiben und den Sabber aufwischen.",,,"¿Estás aquí para liberarnos? Porque he sido bueno, me han quitado el implante. Aunque aún tengo que quedarme aquí abajo y limpiar la saliva.",,"Oletko tullut vapauttamaan meidät? Koska olen käyttäytynyt kiltisti, he poistivat istutteeni. Minun kuitenkin on jäätävä tänne pyyhkimään kuolaa.","Vous êtes venus nous libérer? Je me suis bien comporté! Il m'on retiré mon implant, il faut que je reste ici et que j'essuie la bave, par contre.","Azért vagy itt, hogy felszabadíts minket? Jó voltam, és elvették az implantátumomat. Mégis itt kell rohadnom és takarítanom ezt a nyálkát.","Sei qui per liberarci? Dato che mi sono comportato bene, mi hanno tolto l'impianto. Però devo ancora restare quaggiù a pulire.","俺達を解放しに来たのか?あいつらに インプラントを外されたが、俺は大丈夫だ。 -まだ少し留まって涎を拭き取らないとならない。","저희를 구출하기 위해서 찾아오셨나요? 그들이 제가 성실하게 일을 한 사례로 세뇌 장치를 때어갔어요. 그런데... 아직도 위험한 것 같은데, 좀 흘린 침 자국을 좀 닦아야 할 것 같아요.","Ben je hier om ons te bevrijden? Omdat ik goed ben geweest, hebben ze mijn implantaat eruit gehaald. Ik moet nog steeds hier beneden blijven en de kwijl echter wegvegen.",Er du her for å befri oss? Fordi jeg har vært snill. De fjernet implantatet mitt. Men jeg må fortsatt bli her nede og tørke opp siklet.,"Jesteś tu, by nas uwolnić? Ponieważ byłem dobry, wyjęli mi implant. Ale nadal muszę tu zostać i wytrzeć ślinę.","Você está aqui para nos libertar? Por eu ter me comportado bem, eles tiraram o meu implante. Mas ainda tenho que ficar aqui para limpar a saliva.",,"Ai venit ca să ne eliberezi? Pentru că am fost cuminte, mi-au scos implantul. Dar tot trebuie să rămân aici și să fac curățenie însă.","Ты пришёл спасти нас? Я был послушным, так что они вынули мой имплант. И всё равно я вынужден оставаться тут, внизу, и подтирать слюни.",,Bizi özgür bırakmak için mi buradasın? İyi olduğum için implantımı çıkardılar. Yine de burada kalıp salyamı silmem gerekiyor. -"Yes, I'm here to free you.",TXT_RPLY0_SCRIPT14_D0_YESIM,,,,"Ano, jsem tu, abych vás osvobodil.","Ja, jeg er her for at befri jer.","Ja, ich werde eiuch befreien.",,,"Sí, estoy aquí para liberarte.",,"Kyllä, tulin vapauttamaan teidät.","Oui, je viens vous libérer.","Igen, azért jöttem hogy kiszabadítsalak.","Sì, sono qui per liberarvi.",そうだ、助けに来た。,"그래, 난 널 구하러 왔어.","Ja, ik ben hier om je te bevrijden.","Ja, jeg er her for å befri dere.","Tak, jestem tu, żeby was uwolnić.","Sim, estou aqui para libertar vocês.",,"Da, am venit să te eliberez.","Да, я здесь, чтобы спасти вас.",,"Evet, sizi kurtarmak için buradayım." -You mean it?,TXT_RYES0_SCRIPT14_D0_YOUME,,,,To myslíš doopravdy?,Mener du det?,Wirklich?,,,¿En serio?,,Todellako?,Vraiment?,Tényleg?,Veramente?,そういう意味か?,정말인가요?,Je meent het?,Mener du det?,Mówisz poważnie?,Sério mesmo?,,Pe bune?,Правда?,,Ciddi misin? +まだ少し留まって涎を拭き取らないとならない。","저희를 구출하기 위해서 찾아오셨나요? 그들이 제가 성실하게 일을 한 사례로 세뇌 장치를 때어갔어요. 그런데... 아직도 위험한 것 같은데, 좀 흘린 침 자국을 좀 닦아야 할 것 같아요.","Ben je hier om ons te bevrijden? Omdat ik goed ben geweest, hebben ze mijn implantaat eruit gehaald. Ik moet nog steeds hier beneden blijven en de kwijl echter wegvegen.",Er du her for å befri oss? Fordi jeg har vært snill. De fjernet implantatet mitt. Men jeg må fortsatt bli her nede og tørke opp siklet.,"Jesteś tu, by nas uwolnić? Ponieważ byłem dobry, wyjęli mi implant. Ale nadal muszę tu zostać i wytrzeć ślinę.","Você está aqui para nos libertar? Por eu ter me comportado bem, eles tiraram o meu implante. Mas ainda tenho que ficar aqui para limpar a saliva.",,"Ai venit ca să ne eliberezi? Pentru că am fost cuminte, mi-au scos implantul. Dar tot trebuie să rămân aici și să fac curățenie însă.","Ты пришёл спасти нас? Я был послушным, так что они вынули мой имплант. И всё равно я вынужден оставаться тут, внизу, и подтирать слюни.",,Är du här för att befria oss? För att jag har varit snäll tog de bort mitt implantat. Jag måste ändå stanna här nere och torka upp dreglet.,Bizi özgür bırakmak için mi buradasın? İyi olduğum için implantımı çıkardılar. Yine de burada kalıp salyamı silmem gerekiyor. +"Yes, I'm here to free you.",TXT_RPLY0_SCRIPT14_D0_YESIM,,,,"Ano, jsem tu, abych vás osvobodil.","Ja, jeg er her for at befri jer.","Ja, ich werde eiuch befreien.",,,"Sí, estoy aquí para liberarte.",,"Kyllä, tulin vapauttamaan teidät.","Oui, je viens vous libérer.","Igen, azért jöttem hogy kiszabadítsalak.","Sì, sono qui per liberarvi.",そうだ、助けに来た。,"그래, 난 널 구하러 왔어.","Ja, ik ben hier om je te bevrijden.","Ja, jeg er her for å befri dere.","Tak, jestem tu, żeby was uwolnić.","Sim, estou aqui para libertar vocês.",,"Da, am venit să te eliberez.","Да, я здесь, чтобы спасти вас.",,"Ja, jag är här för att befria er.","Evet, sizi kurtarmak için buradayım." +You mean it?,TXT_RYES0_SCRIPT14_D0_YOUME,,,,To myslíš doopravdy?,Mener du det?,Wirklich?,,,¿En serio?,,Todellako?,Vraiment?,Tényleg?,Veramente?,そういう意味か?,정말인가요?,Je meent het?,Mener du det?,Mówisz poważnie?,Sério mesmo?,,Pe bune?,Правда?,,Menar du det?,Ciddi misin? I can't help nobody else. Not until you blow up the transmitter. That's what's behind the forcefield upstairs. My job is to check on the conveyors to make sure they aren't jammed. Not anymore!,TXT_DLG_SCRIPT14_D1516_ICANT,,,,"Nemůžu nikomu jinému pomoct, ne dokud neodpálíš vysílačku, to je ta věc nahoře za silovým polem. Já mám za úkol kontrolovat pásy a dávat pozor, aby se nezasekly. Teď už ani náhodou!","Jeg kan ikke hjælpe nogen andre. Ikke før du sprænger senderen i luften. Det er det, der er bag kraftfeltet ovenpå. Mit job er at tjekke transportbåndene for at sikre mig, at de ikke er blokeret. Ikke længere!","Ich kann niemandem helfen. Nich bevor jemand den Transmitter hochjagt. Er ist hinter dem Kraftfeld da oben. Meine Aufgabe ist es, die Förderbänder zu prüfen um sicherzustellen, dass sie nicht blockieren. Jetzt nicht mehr!",,,No puedo ayudar a nadie más. No hasta que destruyas el transmisor. Eso es lo que está tras el campo de fuerza escaleras arriba. Mi trabajo es comprobar los transportadores para asegurarme de que no esten atascados. ¡Nunca más!,No puedo ayudar a nadie más. No hasta que destruyas el transmisor. Eso es lo que está detrás del campo de fuerza escaleras arriba. Mi trabajo es comprobar los transportadores para asegurarme de que no esten atascados. ¡Ya no más!,"En voi auttaa ketään muuta. En, ennen kuin räjäytät lähettimen. Se se on, joka sijaitsee yläkerran voimakentän takana. Työni on pitää silmällä ja varmistaa, etteivät liukuhihnat jumiudu, enää!","Je ne peux pas aider qui que ce soit d'autre, du moins pas avant que vous détruisez le transmetteur. C'est la chose derrière le champ de force à l'étage. Mon travail est de faire en sorte que les tapis roulants ne se coincent pas, mais plus maintenant!","Nem tudok már másnak segíteni. Legalábbis nem amíg nem robbantod fel az adóállomást. Ez áll az erőpajzs mögött. Az Én feladatom, hogy ellenőrizzem a futószalagot nem akadt e be. Többé aztán nem!",Non posso aiutare nessun'altro. Non finché non fai saltare in aria il trasmettitore. È questo che c'è dietro il campo di forza di sopra. Il mio compito è asicurarmi che i nastri trasportatori non si intoppino. Non più!,"まだ俺は手伝うことが出来ない。 トランスミッターを壊さなければバレてしまう。 そいつは上の階のフォースフィールドを越えた所 にいる。コンベアーの詰まりをチェックする -だけの仕事だったが、もう辞任だな!",전송기를 파괴하기 전까지는 세뇌된 사람들을 도와줄 수가 없어요. 저 위층에 방어막에 보호받고 있는 채로 있습니다. 제 원래 업무는 광석이 끼지 않게 운반 벨트를 확인하는 거였어요... 이젠 일할 필요도 없지만!,Ik kan niemand anders helpen. Niet voordat je de zender hebt opgeblazen. Dat is wat er achter het krachtveld boven is. Het is mijn taak om de transportbanden te controleren om er zeker van te zijn dat ze niet vastzitten. Nu niet meer!,Jeg kan ikke hjelpe noen andre. Ikke før du sprenger senderen. Det er det som er bak kraftfeltet der oppe. Jobben min er å sjekke at transportbåndene ikke er blokkert. Ikke nå lenger!,"Nie mogę pomóc nikomu innemu. Nie, dopóki nie wysadzisz nadajnika. To jest to, co jest za polem siłowym na górze. Moim zadaniem jest sprawdzanie, czy przenośniki nie są zablokowane. Już nie!",Não posso ajudar mais ninguém. Não até que você detone o transmissor. É isso que mantém o campo de força lá em cima. Meu trabalho é conferir as esteiras para que não fiquem emperradas. Nunca mais!,,"Nu pot ajuta pe nimeni. Nu până ce transmițătorul nu e aruncat în aer. Asta e la etaj, în spatele scuturilor. Treaba mea e să mă uit după conveioare, să mă asigur că nu sunt defecte. Numai!","Я не могу помочь другим, пока ты не взорвёшь передатчик. Он находится за силовым полем наверху. Моя работа — проверять, не заклинило ли конвейеры. Теперь уже нет!",,"Başka kimseye yardım edemem. Vericiyi patlatana kadar olmaz. Üst kattaki güç alanının arkasında bu var. Benim işim, sıkışmadıklarından emin olmak için konveyörleri kontrol etmek. Artık değil!" -"That's right, you're saved!",TXT_RPLY0_SCRIPT14_D1516_THATS,,,,"Ano, jsi zachráněn!","Det er rigtigt, du er reddet!","Das ist richtig, du bist in Sicherheit!",,,"Correcto, ¡estás salvado!",,"Näin on, olet pelastettu!","C'est ça, vous êtes sauvé!","Így van, meg van mentve.","Esatto, sei salvo!",そうだ、救われたぞ!,당연하지. 너는 자유야!,"Dat klopt, je bent gered!","Det stemmer, du er reddet!","Tak jest, jesteś uratowany!",Isso mesmo. Vocês estão salvos!,,"Așa e, ești salvat!","Да, это так! Вы спасены!",,"Bu doğru, kurtuldun!" -"Oh, thank you!",TXT_RYES0_SCRIPT14_D1516_OHTHA,,,,"Oh, děkuju!","Åh, tak!","Oh, danke sehr!",,"Ho, dankon.","Oh, ¡gracias!",,"Voi, kiitos!","Oh, merci!","Oh, köszönöm!","Oh, grazie!",おう、ありがとよ!,"오, 고마워요!","Oh, dank je wel!",Takk skal du ha!,"Och, dziękuję!","Ah, muito obrigado!",,"Oh, mulțumesc!",Ура! Спасибо тебе!,,"Oh, teşekkürler!" -We're free!! We're free!! We're free!!,TXT_DLG_SCRIPT14_D3032_WEREF,,,,Jsme volní! Jsme volní! Jsme volní!,Vi er fri!! Vi er fri!! Vi er fri!!!,Wir sind frei! Wir sind frei! Wir sind frei!,,,¡¡Somos libres!! ¡¡Somos libres!! ¡¡Somos libres!!,,Olemme vapaat!! Olemme vapaat!! Olemme vapaat!!,On est libres! Libres! Libres!,Szabadok vagyunk!! Szabadok vagyunk!! Szabadok vagyunk!!,Siamo liberi!! Siamo liberi!! Siamo liberi!!,自由だ!!俺達は自由だ!!俺達は自由だ!!,우린 자유야! 우린 자유라고!,We zijn vrij!! We zijn vrij!! We zijn vrij!!,Vi er fri! Vi er fri!! Vi er fri!!,Jesteśmy wolni!!! Jesteśmy wolni!!! Jesteśmy wolni!!!,Estamos livres!! Estamos livres!! Estamos livres!!,,Suntem liberi!! Suntem liberi!! Suntem liberi!!,Мы свободны! Мы свободны! Мы свободны!,,Özgürüz! Özgürüz! Özgürüz! -Must mine more ore!,TXT_DLG_SCRIPT14_D4548_MUSTM,,,,Muset těžit další rudu!,Vi må udvinde mere malm!,Muss Erz abbauen.,,,¡Debo picar más mineral!,,Täytyy louhia lisää malmia!,Faut que je trouve plus de minerai!,Még több ércet kell bányászni!,Devo estrarre più minerale!,もっと掘らねえといけねえんだ!,광석을... 캐내야 해...,Moet erts meer of meer ontginnen!,Må utvinne mer malm!,Musimy wydobyć więcej rudy!,Preciso minerar mais!,,Mai trebuie să minez încă o bucată de minereu.,Нужно добыть больше руды!,,Daha fazla maden çıkarmalıyız! -We're free!! We're free!! We're free!!,TXT_DLG_SCRIPT14_D6064_WEREF,,,,Jsme volní! Jsme volní! Jsme volní!,Vi er frie!! Vi er frie!!! Vi er frie!!,Wir sind frei! Wir sind frei! Wir sind frei!,,,¡¡Somos libres!! ¡¡Somos libres!! ¡¡Somos libres!!,,Olemme vapaat!! Olemme vapaat!! Olemme vapaat!!,On est libres! Libres! Libres!,Szabadok vagyunk!! Szabadok vagyunk!! Szabadok vagyunk!!,Siamo liberi!! Siamo liberi!! Siamo liberi!!,自由だ!!オレらは自由だ!!オレらは自由だ!!,프론트가 해냈다! 자유를 거의 되찾았어!,We zijn vrij!!! We zijn vrij!!! We zijn vrij!!!,Vi er fri!! Vi er frie!! Vi er fri!!,Jesteśmy wolni! Jesteśmy wolni!!! Jesteśmy wolni!!!,Estamos livres!! Estamos livres!! Estamos livres!!,,Suntem liberi!! Suntem liberi!! Suntem liberi!!,Мы свободны! Мы свободны! Мы свободны!,,Özgürüz! Özgürüz! Özgürüz! -Must mine more ore!,TXT_DLG_SCRIPT14_D7580_MUSTM,,,,Muset těžit další rudu!,Skal udvinde mere malm!,Muss Erz abbauen.,,,¡Debo picar más mineral!,,Täytyy louhia lisää malmia!,Faut que je trouve plus de minerai!,Még több ércet kell bányászni!,Devo estrarre più minerale!,鉱石がもっと必要なんだ!,광석... 데그닌... 캔다...,Moet meer erts ontginnen!,Må utvinne mer malm!,Musimy wydobyć więcej rudy!,Preciso minerar mais!,,Mai trebuie să minez încă o bucată de minereu.,Нужно добыть больше руды!,,Daha fazla maden çıkarmalıyız! -We're free!! We're free!! We're free!!,TXT_DLG_SCRIPT14_D9096_WEREF,,,,Jsme volní! Jsme volní! Jsme volní!,Vi er frie!!! Vi er frie!!! Vi er frie!!,Wir sind frei! Wir sind frei! Wir sind frei!,,,¡¡Somos libres!! ¡¡Somos libres!! ¡¡Somos libres!!,,Olemme vapaat!! Olemme vapaat!! Olemme vapaat!!,On est libres! Libres! Libres!,Szabadok vagyunk!! Szabadok vagyunk!! Szabadok vagyunk!!,Siamo liberi!! Siamo liberi!! Siamo liberi!!,自由だ!!私達は自由だ!!私達は自由だ!!,살았군요. 이제 저항군 기지로 향하는 일 밖엔 남지 않은 것 같아요.,We zijn vrij!!! We zijn vrij!!! We zijn vrij!!!,Vi er fri!! Vi er frie!! Vi er fri!!,Jesteśmy wolni!!! Jesteśmy wolni!!! Jesteśmy wolni!!!,Estamos livres!! Estamos livres!! Estamos livres!!,,Suntem liberi!! Suntem liberi!! Suntem liberi!!,Мы свободны! Мы свободны! Мы свободны!,,Özgürüz! Özgürüz! Özgürüz! -Must mine more ore!,TXT_DLG_SCRIPT14_D10612_MUSTM,,,,Muset těžit další rudu!,Skal udvinde mere malm!,Muss Erz abbauen.,,,¡Debo picar más mineral!,,Täytyy louhia lisää malmia!,Faut que je trouve plus de minerai!,Még több ércet kell bányászni!,Devo estrarre più minerale!,いつまで採掘しなければならない!,캐고... 캐고... 또 캔다...,Moet meer erts ontginnen!,Må utvinne mer malm!,Musimy wydobyć więcej rudy!,Preciso minerar mais!,,Mai trebuie să minez încă o bucată de minereu.,Нужно добыть больше руды!,,Daha fazla maden çıkarmalıyız! -We're free!! We're free!! We're free!!,TXT_DLG_SCRIPT14_D12128_WEREF,,,,Jsme volní! Jsme volní! Jsme volní!,Vi er frie!!! Vi er frie!!! Vi er frie!!,Wir sind frei! Wir sind frei! Wir sind frei!,,,¡¡Somos libres!! ¡¡Somos libres!! ¡¡Somos libres!!,,Olemme vapaat!! Olemme vapaat!! Olemme vapaat!!,On est libres! Libres! Libres!,Szabadok vagyunk!! Szabadok vagyunk!! Szabadok vagyunk!!,Siamo liberi!! Siamo liberi!! Siamo liberi!!,僕らは自由だ!!僕らは自由だ!!僕らは自由だ!!,살았다! 이제 그 놈들이 죽이기 전에 도망쳐야해요!,We zijn vrij!!! We zijn vrij!!! We zijn vrij!!!,Vi er fri!! Vi er frie!! Vi er frie!!,Jesteśmy wolni!!! Jesteśmy wolni!!! Jesteśmy wolni!!!,Estamos livres!! Estamos livres!! Estamos livres!!,,Suntem liberi!! Suntem liberi!! Suntem liberi!!,Мы свободны! Мы свободны! Мы свободны!,,Özgürüz! Özgürüz! Özgürüz! -What are you doing here?,TXT_DLG_SCRIPT15_D0_WHATA,MAP15: Red acolytes.,,,Co tady děláte?,Hvad laver du her?,Was machst du hier?,,,¿Qué haces aquí?,,Mitä teette täällä?,Qu'est ce que vous faites ici?,Mit csinálsz itt?,Che cosa fai qui?,ここで何をしている?,여기서 뭘 하는거지?,Wat doe je hier?,Hva gjør dere her?,Co ty tu robisz?,O que você está fazendo aqui?,,Ce cauți aici?,По какому делу ты здесь?,,Ne yapıyorsunuz burada? -Routine inspection.,TXT_RPLY0_SCRIPT15_D0_ROUTI,〃,,,Rutinní kontrola.,Rutinemæssig inspektion.,Eine Routineinspektion.,,,Inspección rutinaria.,,Rutiinitarkastus.,Inspection de routine.,Rutin ellenőrzés.,Ispezione ordinaria.,見回りだ。,정기적 검사요.,Routine-inspectie.,Rutinemessig inspeksjon.,Rutynowa inspekcja.,Inspeção de rotina.,,Inspecție de rutină.,Плановая проверка.,,Rutin teftiş. -"All right, carry on.",TXT_RYES0_SCRIPT15_D0_ALLRI,〃,,,"Dobře, pokračujte.","Okay, fortsæt.","In Ordnung, mach weiter.",,,"Muy bien, continúa.",,"Selvä on, jatkakaa.","D'accord, continuez.","Renben, folytasd csak.","Va bene, vai pure avanti.",わかった、続けろ。,"좋아, 계속해.","Oké, ga door.","Greit, fortsett.","W porządku, kontynuuj.","Muito bem, continue.",,"Bine, mergi mai departe.",Понятно. Продолжай.,,"Pekala, devam edin." +だけの仕事だったが、もう辞任だな!",전송기를 파괴하기 전까지는 세뇌된 사람들을 도와줄 수가 없어요. 저 위층에 방어막에 보호받고 있는 채로 있습니다. 제 원래 업무는 광석이 끼지 않게 운반 벨트를 확인하는 거였어요... 이젠 일할 필요도 없지만!,Ik kan niemand anders helpen. Niet voordat je de zender hebt opgeblazen. Dat is wat er achter het krachtveld boven is. Het is mijn taak om de transportbanden te controleren om er zeker van te zijn dat ze niet vastzitten. Nu niet meer!,Jeg kan ikke hjelpe noen andre. Ikke før du sprenger senderen. Det er det som er bak kraftfeltet der oppe. Jobben min er å sjekke at transportbåndene ikke er blokkert. Ikke nå lenger!,"Nie mogę pomóc nikomu innemu. Nie, dopóki nie wysadzisz nadajnika. To jest to, co jest za polem siłowym na górze. Moim zadaniem jest sprawdzanie, czy przenośniki nie są zablokowane. Już nie!",Não posso ajudar mais ninguém. Não até que você detone o transmissor. É isso que mantém o campo de força lá em cima. Meu trabalho é conferir as esteiras para que não fiquem emperradas. Nunca mais!,,"Nu pot ajuta pe nimeni. Nu până ce transmițătorul nu e aruncat în aer. Asta e la etaj, în spatele scuturilor. Treaba mea e să mă uit după conveioare, să mă asigur că nu sunt defecte. Numai!","Я не могу помочь другим, пока ты не взорвёшь передатчик. Он находится за силовым полем наверху. Моя работа — проверять, не заклинило ли конвейеры. Теперь уже нет!",,Jag kan inte hjälpa någon annan. Inte förrän du spränger sändaren. Det är det som finns bakom kraftfältet på övervåningen. Mitt jobb är att kontrollera transportörerna så att de inte fastnar. Inte längre!,"Başka kimseye yardım edemem. Vericiyi patlatana kadar olmaz. Üst kattaki güç alanının arkasında bu var. Benim işim, sıkışmadıklarından emin olmak için konveyörleri kontrol etmek. Artık değil!" +"That's right, you're saved!",TXT_RPLY0_SCRIPT14_D1516_THATS,,,,"Ano, jsi zachráněn!","Det er rigtigt, du er reddet!","Das ist richtig, du bist in Sicherheit!",,,"Correcto, ¡estás salvado!",,"Näin on, olet pelastettu!","C'est ça, vous êtes sauvé!","Így van, meg van mentve.","Esatto, sei salvo!",そうだ、救われたぞ!,당연하지. 너는 자유야!,"Dat klopt, je bent gered!","Det stemmer, du er reddet!","Tak jest, jesteś uratowany!",Isso mesmo. Vocês estão salvos!,,"Așa e, ești salvat!","Да, это так! Вы спасены!",,"Det stämmer, du är räddad!","Bu doğru, kurtuldun!" +"Oh, thank you!",TXT_RYES0_SCRIPT14_D1516_OHTHA,,,,"Oh, děkuju!","Åh, tak!","Oh, danke sehr!",,"Ho, dankon.","Oh, ¡gracias!",,"Voi, kiitos!","Oh, merci!","Oh, köszönöm!","Oh, grazie!",おう、ありがとよ!,"오, 고마워요!","Oh, dank je wel!",Takk skal du ha!,"Och, dziękuję!","Ah, muito obrigado!",,"Oh, mulțumesc!",Ура! Спасибо тебе!,,"Åh, tack!","Oh, teşekkürler!" +We're free!! We're free!! We're free!!,TXT_DLG_SCRIPT14_D3032_WEREF,,,,Jsme volní! Jsme volní! Jsme volní!,Vi er fri!! Vi er fri!! Vi er fri!!!,Wir sind frei! Wir sind frei! Wir sind frei!,,,¡¡Somos libres!! ¡¡Somos libres!! ¡¡Somos libres!!,,Olemme vapaat!! Olemme vapaat!! Olemme vapaat!!,On est libres! Libres! Libres!,Szabadok vagyunk!! Szabadok vagyunk!! Szabadok vagyunk!!,Siamo liberi!! Siamo liberi!! Siamo liberi!!,自由だ!!俺達は自由だ!!俺達は自由だ!!,우린 자유야! 우린 자유라고!,We zijn vrij!! We zijn vrij!! We zijn vrij!!,Vi er fri! Vi er fri!! Vi er fri!!,Jesteśmy wolni!!! Jesteśmy wolni!!! Jesteśmy wolni!!!,Estamos livres!! Estamos livres!! Estamos livres!!,,Suntem liberi!! Suntem liberi!! Suntem liberi!!,Мы свободны! Мы свободны! Мы свободны!,,Vi är fria!! Vi är fria! Vi är fria!!,Özgürüz! Özgürüz! Özgürüz! +Must mine more ore!,TXT_DLG_SCRIPT14_D4548_MUSTM,,,,Muset těžit další rudu!,Vi må udvinde mere malm!,Muss Erz abbauen.,,,¡Debo picar más mineral!,,Täytyy louhia lisää malmia!,Faut que je trouve plus de minerai!,Még több ércet kell bányászni!,Devo estrarre più minerale!,もっと掘らねえといけねえんだ!,광석을... 캐내야 해...,Moet erts meer of meer ontginnen!,Må utvinne mer malm!,Musimy wydobyć więcej rudy!,Preciso minerar mais!,,Mai trebuie să minez încă o bucată de minereu.,Нужно добыть больше руды!,,Måste bryta mer malm!,Daha fazla maden çıkarmalıyız! +We're free!! We're free!! We're free!!,TXT_DLG_SCRIPT14_D6064_WEREF,,,,Jsme volní! Jsme volní! Jsme volní!,Vi er frie!! Vi er frie!!! Vi er frie!!,Wir sind frei! Wir sind frei! Wir sind frei!,,,¡¡Somos libres!! ¡¡Somos libres!! ¡¡Somos libres!!,,Olemme vapaat!! Olemme vapaat!! Olemme vapaat!!,On est libres! Libres! Libres!,Szabadok vagyunk!! Szabadok vagyunk!! Szabadok vagyunk!!,Siamo liberi!! Siamo liberi!! Siamo liberi!!,自由だ!!オレらは自由だ!!オレらは自由だ!!,프론트가 해냈다! 자유를 거의 되찾았어!,We zijn vrij!!! We zijn vrij!!! We zijn vrij!!!,Vi er fri!! Vi er frie!! Vi er fri!!,Jesteśmy wolni! Jesteśmy wolni!!! Jesteśmy wolni!!!,Estamos livres!! Estamos livres!! Estamos livres!!,,Suntem liberi!! Suntem liberi!! Suntem liberi!!,Мы свободны! Мы свободны! Мы свободны!,,Vi är fria!! Vi är fria!! Vi är fria!!,Özgürüz! Özgürüz! Özgürüz! +Must mine more ore!,TXT_DLG_SCRIPT14_D7580_MUSTM,,,,Muset těžit další rudu!,Skal udvinde mere malm!,Muss Erz abbauen.,,,¡Debo picar más mineral!,,Täytyy louhia lisää malmia!,Faut que je trouve plus de minerai!,Még több ércet kell bányászni!,Devo estrarre più minerale!,鉱石がもっと必要なんだ!,광석... 데그닌... 캔다...,Moet meer erts ontginnen!,Må utvinne mer malm!,Musimy wydobyć więcej rudy!,Preciso minerar mais!,,Mai trebuie să minez încă o bucată de minereu.,Нужно добыть больше руды!,,Måste bryta mer malm!,Daha fazla maden çıkarmalıyız! +We're free!! We're free!! We're free!!,TXT_DLG_SCRIPT14_D9096_WEREF,,,,Jsme volní! Jsme volní! Jsme volní!,Vi er frie!!! Vi er frie!!! Vi er frie!!,Wir sind frei! Wir sind frei! Wir sind frei!,,,¡¡Somos libres!! ¡¡Somos libres!! ¡¡Somos libres!!,,Olemme vapaat!! Olemme vapaat!! Olemme vapaat!!,On est libres! Libres! Libres!,Szabadok vagyunk!! Szabadok vagyunk!! Szabadok vagyunk!!,Siamo liberi!! Siamo liberi!! Siamo liberi!!,自由だ!!私達は自由だ!!私達は自由だ!!,살았군요. 이제 저항군 기지로 향하는 일 밖엔 남지 않은 것 같아요.,We zijn vrij!!! We zijn vrij!!! We zijn vrij!!!,Vi er fri!! Vi er frie!! Vi er fri!!,Jesteśmy wolni!!! Jesteśmy wolni!!! Jesteśmy wolni!!!,Estamos livres!! Estamos livres!! Estamos livres!!,,Suntem liberi!! Suntem liberi!! Suntem liberi!!,Мы свободны! Мы свободны! Мы свободны!,,Vi är fria!! Vi är fria!! Vi är fria!!,Özgürüz! Özgürüz! Özgürüz! +Must mine more ore!,TXT_DLG_SCRIPT14_D10612_MUSTM,,,,Muset těžit další rudu!,Skal udvinde mere malm!,Muss Erz abbauen.,,,¡Debo picar más mineral!,,Täytyy louhia lisää malmia!,Faut que je trouve plus de minerai!,Még több ércet kell bányászni!,Devo estrarre più minerale!,いつまで採掘しなければならない!,캐고... 캐고... 또 캔다...,Moet meer erts ontginnen!,Må utvinne mer malm!,Musimy wydobyć więcej rudy!,Preciso minerar mais!,,Mai trebuie să minez încă o bucată de minereu.,Нужно добыть больше руды!,,Måste bryta mer malm!,Daha fazla maden çıkarmalıyız! +We're free!! We're free!! We're free!!,TXT_DLG_SCRIPT14_D12128_WEREF,,,,Jsme volní! Jsme volní! Jsme volní!,Vi er frie!!! Vi er frie!!! Vi er frie!!,Wir sind frei! Wir sind frei! Wir sind frei!,,,¡¡Somos libres!! ¡¡Somos libres!! ¡¡Somos libres!!,,Olemme vapaat!! Olemme vapaat!! Olemme vapaat!!,On est libres! Libres! Libres!,Szabadok vagyunk!! Szabadok vagyunk!! Szabadok vagyunk!!,Siamo liberi!! Siamo liberi!! Siamo liberi!!,僕らは自由だ!!僕らは自由だ!!僕らは自由だ!!,살았다! 이제 그 놈들이 죽이기 전에 도망쳐야해요!,We zijn vrij!!! We zijn vrij!!! We zijn vrij!!!,Vi er fri!! Vi er frie!! Vi er frie!!,Jesteśmy wolni!!! Jesteśmy wolni!!! Jesteśmy wolni!!!,Estamos livres!! Estamos livres!! Estamos livres!!,,Suntem liberi!! Suntem liberi!! Suntem liberi!!,Мы свободны! Мы свободны! Мы свободны!,,Vi är fria!! Vi är fria!! Vi är fria!!,Özgürüz! Özgürüz! Özgürüz! +What are you doing here?,TXT_DLG_SCRIPT15_D0_WHATA,MAP15: Red acolytes.,,,Co tady děláte?,Hvad laver du her?,Was machst du hier?,,,¿Qué haces aquí?,,Mitä teette täällä?,Qu'est ce que vous faites ici?,Mit csinálsz itt?,Che cosa fai qui?,ここで何をしている?,여기서 뭘 하는거지?,Wat doe je hier?,Hva gjør dere her?,Co ty tu robisz?,O que você está fazendo aqui?,,Ce cauți aici?,По какому делу ты здесь?,,Vad gör du här?,Ne yapıyorsunuz burada? +Routine inspection.,TXT_RPLY0_SCRIPT15_D0_ROUTI,〃,,,Rutinní kontrola.,Rutinemæssig inspektion.,Eine Routineinspektion.,,,Inspección rutinaria.,,Rutiinitarkastus.,Inspection de routine.,Rutin ellenőrzés.,Ispezione ordinaria.,見回りだ。,정기적 검사요.,Routine-inspectie.,Rutinemessig inspeksjon.,Rutynowa inspekcja.,Inspeção de rotina.,,Inspecție de rutină.,Плановая проверка.,,Rutininspektion.,Rutin teftiş. +"All right, carry on.",TXT_RYES0_SCRIPT15_D0_ALLRI,〃,,,"Dobře, pokračujte.","Okay, fortsæt.","In Ordnung, mach weiter.",,,"Muy bien, continúa.",,"Selvä on, jatkakaa.","D'accord, continuez.","Renben, folytasd csak.","Va bene, vai pure avanti.",わかった、続けろ。,"좋아, 계속해.","Oké, ga door.","Greit, fortsett.","W porządku, kontynuuj.","Muito bem, continue.",,"Bine, mergi mai departe.",Понятно. Продолжай.,,"Okej, fortsätt.","Pekala, devam edin." "Nothing to report here. Everything is working fine. If anything goes wrong, I'll be sure to report it.",TXT_DLG_SCRIPT15_D1516_NOTHI,MAP15: Red acolytes + Technician at the beginning.,,,"Tady nic k nahlášení není. Všechno funguje dobře. Pokud se něco pokazí, nahlásím to.","Der er intet at rapportere her. Alt fungerer fint. Hvis noget går galt, skal jeg nok rapportere det.","Keine besonderen Vorkommnisse. Alles funktioniert wie es soll. Wenn irgendetwas schief geht, werde ich es sofort melden.",,,"Nada que reportar aquí. Todo está funcionando bien. Si cualquier cosa sale mal, me aseguraré de reportarlo.",,"Ei mitään raportoitavaa. Kaikki toimii hyvin. Jo mikään menee vialle, raportoin siitä varmasti.","Rien à signaler ici. Tout fonctionne comme prévu. Si quelque chose tombe en panne, je ferai un rapport.","Nincs semmi bejelentenivaló. Minden prímán működik. Ha esetleg valami meghibásodik, rögtön jelezni fogom.","Nulla da riportare qua. Tutto funziona come dovrebbe. Se qualcosa non dovesse funzionare, lo riporterò subito.","報告することはない。全て順調だ。 -何か問題が起きたら報告する。","보고할 게 전혀 없어. 모든 장치, 시설, 인력 모두 이상 무. 만약 하나라도 문제가 생기면 나에게 알려줘.","Hier valt niets te melden. Alles werkt prima. Als er iets misgaat, zal ik het zeker melden.","Ingenting å rapportere her. Alt fungerer som det skal. Hvis noe går galt, skal jeg rapportere det.","Nie ma o czym mówić. Wszystko działa jak należy. Jeśli coś będzie nie tak, na pewno to zgłoszę.","Não há nada de errado aqui. Tudo está funcionando perfeitamente. Se algo parar de funcionar, pode ter certeza que eu vou avisar.",,"Nimic de raportat aici. Dacă e ceva, cu siguranță că voi da raportul.","Тут не о чём докладывать. Всё работает превосходно. Если что-нибудь пойдёт не так, я обязательно доложу об этом.",,"Burada rapor edilecek bir şey yok. Her şey yolunda gidiyor. Eğer bir sorun çıkarsa, rapor edeceğimden emin olabilirsiniz." +何か問題が起きたら報告する。","보고할 게 전혀 없어. 모든 장치, 시설, 인력 모두 이상 무. 만약 하나라도 문제가 생기면 나에게 알려줘.","Hier valt niets te melden. Alles werkt prima. Als er iets misgaat, zal ik het zeker melden.","Ingenting å rapportere her. Alt fungerer som det skal. Hvis noe går galt, skal jeg rapportere det.","Nie ma o czym mówić. Wszystko działa jak należy. Jeśli coś będzie nie tak, na pewno to zgłoszę.","Não há nada de errado aqui. Tudo está funcionando perfeitamente. Se algo parar de funcionar, pode ter certeza que eu vou avisar.",,"Nimic de raportat aici. Dacă e ceva, cu siguranță că voi da raportul.","Тут не о чём докладывать. Всё работает превосходно. Если что-нибудь пойдёт не так, я обязательно доложу об этом.",,Inget att rapportera här. Allt fungerar bra. Om något går fel ska jag rapportera det.,"Burada rapor edilecek bir şey yok. Her şey yolunda gidiyor. Eğer bir sorun çıkarsa, rapor edeceğimden emin olabilirsiniz." "Sir, there was a problem earlier, but it was taken care of.",TXT_DLG_SCRIPT15_D3032_SIRTH,MAP15: Technician at the beginning.,,,"Pane, předtím tu byl problém, ale vyřešili jsme jej.","Sir, der var et problem tidligere, men det blev ordnet.","Vor kurzem gab es ein Problem, aber das wurde bereits gelöst.",,,"Señor, hubo un problema antes, pero ha sido solucionado.",,"Tässä aiemmin oli ongelma, mutta se ratkaistiin.","Monsieur, il y a eu un problème récemment mais nous l'avons corrigé.","Uram, volt korábban egy probléma, de megoldásra került.","Signore, c'era un problema prima, ma è stato risolto.","上官殿、以前より問題があったが、 -もう心配はいらない。",안녕하십니까. 조금 전에 문제가 있었습니다만 경마한 문제였고 지금 해결됐습니다.,"Meneer, er was eerder een probleem, maar het is opgelost.","Sir, det var et problem tidligere, men det ble tatt hånd om.","Sir, wcześniej był problem, ale już się nim zajęto.","Senhor, havia um problema antes, mas já foi resolvido.",,"Domnule, a fost o problemă adineauri, dar s-a rezolvat.","Сэр, тут была одна неполадка, но её уже устранили.",,"Efendim, daha önce bir sorun vardı, ama halledildi." -Move along or taste metal.,TXT_DLG_SCRIPT17_D0_MOVEA,MAP17: Bailey (if you don't have Order's key),,,"Jdi dál, nebo okus ocel.",Fortsæt eller smag på metal.,Beweg dich oder spüre meinen Stahl.,,,Sigue caminando o prueba metal.,,"Jatka matkaasi, tai maista metallia.",Bougez ou préparez-vous à goûter de l'acier.,"Haladj tovább, vagy ízleld meg a kardom.",Sparisci o ti finisce male.,同行か鉄を味わうかだ。,탄창으로 맞고 싶지 않으면 움직여.,Ga verder of proef metaal.,Gå videre eller smak på metall.,Ruszaj się albo skosztuj metalu.,Vá embora ou vai tomar chumbo grosso.,,Mișcă-te sau mănânci metal.,"Прочь, или отведаешь металла.",,İlerleyin ya da metalin tadına bakın. -I.D. check.,TXT_DLG_SCRIPT17_D1516_IDCHE,〃 (if you have it),,,Doklady.,ID-tjek.,Ausweisüberprüfung.,,,Comprobación de identificación.,,Henkilöllisyystarkastus.,Vérification de carte d'identité.,Igazolvány ellenőrzés.,Verifica d'identità.,I.D.チェックだ。,신분증 확인.,I.D. check.,Legitimasjonskontroll.,Sprawdzenie tożsamości.,Verificação de identidade.,,Verificare card de identitate.,Ваши документы.,,Kimlik kontrolü. -"Here, I'm in a hurry.",TXT_RPLY0_SCRIPT17_D1516_HEREI,〃 (〃),,,"Tady, spěchám.","Her, jeg har travlt.","Hier, ich hab's eilig.",,,"Ten, tengo prisa.",,"Tässä, minulla on kiire.","Voilà, je suis pressé.","Nesze, nem érek rá.","Ecco qua, vado di fretta.",ほら、急いでるんだ。,여기요. 급하니 빨리 확인해주세요.,Hier heb ik haast.,"Her, jeg har dårlig tid.",Spieszę się.,"Pegue, estou com pressa.",,"Aici, mă grăbesc.",Вот. Я тороплюсь.,,"Al, acelem var." -Stop waving your ID in my face and go in.,TXT_DLG_SCRIPT17_D3032_STOPW,〃 (〃),,,Přestaň mi tu mávat tou kartou a jdi dovnitř.,Hold op med at vifte med dit ID i mit ansigt og gå ind.,Hör auf mit deinem Ausweis vor meinem Gesicht herumzufuchteln und geh hinein.,,,Deja de agitar tu identificación en mi cara y entra.,,Lakkaa heiluttelemasta tunnistettasi päin naamaa ja mene sisään.,Arrêtez de l'agiter dans ma figure et passez.,Ne lobogtasd az igazolványodat az arcomba és menj be.,Smettila di sventolarmela in faccia e vai avanti.,目前まで近づけるな、さっさと行け。,얼굴 앞에서 신분증 그만 흔들고 얼른 들어가.,Stop met je ID in mijn gezicht te zwaaien en ga naar binnen.,Slutt å vifte med legitimasjonen og gå inn.,Przestań machać mi przed nosem swoim dowodem i wejdź.,Pare de sacudir a sua identificação e entre logo.,,Nu mai flutura cardul în fața mea și intră.,Прекрати махать своей карточкой перед моим лицом и проходи.,,Kimliğini yüzüme karşı sallamayı bırak ve içeri gir. -Nothing to see here. Move along.,TXT_DLG_SCRIPT17_D4548_NOTHI,MAP17: Green guards.,,,Nic k vidění. Jdi dál.,Der er intet at se her. Gå videre.,Hier gibt es nichts zu sehen. Geh weiter.,,,Nada que ver aquí. Sigue caminando.,,Täällä ei ole mitään nähtävää. Jatkakaa matkaa.,Rien à voir ici. Bougez.,Nincs itt semmi látnivaló. Mozgás tovább.,Non c'è niente da vedere qui. Gira al largo.,何事も無い。進め。,아무 일도 안 일어났다. 어서 움직여.,Hier is niets te zien. Ga verder.,Ingenting å se her. Gå videre.,Nie ma tu nic do oglądania. Ruszaj się.,Nada pra ver aqui. Vá embora.,,Nimic aici. Mișcă.,Тут не на что смотреть. Проваливай.,,Burada görecek bir şey yok. İlerleyin. +もう心配はいらない。",안녕하십니까. 조금 전에 문제가 있었습니다만 경마한 문제였고 지금 해결됐습니다.,"Meneer, er was eerder een probleem, maar het is opgelost.","Sir, det var et problem tidligere, men det ble tatt hånd om.","Sir, wcześniej był problem, ale już się nim zajęto.","Senhor, havia um problema antes, mas já foi resolvido.",,"Domnule, a fost o problemă adineauri, dar s-a rezolvat.","Сэр, тут была одна неполадка, но её уже устранили.",,"Sir, det var ett problem tidigare, men det har tagits om hand.","Efendim, daha önce bir sorun vardı, ama halledildi." +Move along or taste metal.,TXT_DLG_SCRIPT17_D0_MOVEA,MAP17: Bailey (if you don't have Order's key),,,"Jdi dál, nebo okus ocel.",Fortsæt eller smag på metal.,Beweg dich oder spüre meinen Stahl.,,,Sigue caminando o prueba metal.,,"Jatka matkaasi, tai maista metallia.",Bougez ou préparez-vous à goûter de l'acier.,"Haladj tovább, vagy ízleld meg a kardom.",Sparisci o ti finisce male.,同行か鉄を味わうかだ。,탄창으로 맞고 싶지 않으면 움직여.,Ga verder of proef metaal.,Gå videre eller smak på metall.,Ruszaj się albo skosztuj metalu.,Vá embora ou vai tomar chumbo grosso.,,Mișcă-te sau mănânci metal.,"Прочь, или отведаешь металла.",,Gå vidare eller smaka på metall.,İlerleyin ya da metalin tadına bakın. +I.D. check.,TXT_DLG_SCRIPT17_D1516_IDCHE,〃 (if you have it),,,Doklady.,ID-tjek.,Ausweisüberprüfung.,,,Comprobación de identificación.,,Henkilöllisyystarkastus.,Vérification de carte d'identité.,Igazolvány ellenőrzés.,Verifica d'identità.,I.D.チェックだ。,신분증 확인.,I.D. check.,Legitimasjonskontroll.,Sprawdzenie tożsamości.,Verificação de identidade.,,Verificare card de identitate.,Ваши документы.,,ID-kontroll.,Kimlik kontrolü. +"Here, I'm in a hurry.",TXT_RPLY0_SCRIPT17_D1516_HEREI,〃 (〃),,,"Tady, spěchám.","Her, jeg har travlt.","Hier, ich hab's eilig.",,,"Ten, tengo prisa.",,"Tässä, minulla on kiire.","Voilà, je suis pressé.","Nesze, nem érek rá.","Ecco qua, vado di fretta.",ほら、急いでるんだ。,여기요. 급하니 빨리 확인해주세요.,Hier heb ik haast.,"Her, jeg har dårlig tid.",Spieszę się.,"Pegue, estou com pressa.",,"Aici, mă grăbesc.",Вот. Я тороплюсь.,,"Här, jag har bråttom.","Al, acelem var." +Stop waving your ID in my face and go in.,TXT_DLG_SCRIPT17_D3032_STOPW,〃 (〃),,,Přestaň mi tu mávat tou kartou a jdi dovnitř.,Hold op med at vifte med dit ID i mit ansigt og gå ind.,Hör auf mit deinem Ausweis vor meinem Gesicht herumzufuchteln und geh hinein.,,,Deja de agitar tu identificación en mi cara y entra.,,Lakkaa heiluttelemasta tunnistettasi päin naamaa ja mene sisään.,Arrêtez de l'agiter dans ma figure et passez.,Ne lobogtasd az igazolványodat az arcomba és menj be.,Smettila di sventolarmela in faccia e vai avanti.,目前まで近づけるな、さっさと行け。,얼굴 앞에서 신분증 그만 흔들고 얼른 들어가.,Stop met je ID in mijn gezicht te zwaaien en ga naar binnen.,Slutt å vifte med legitimasjonen og gå inn.,Przestań machać mi przed nosem swoim dowodem i wejdź.,Pare de sacudir a sua identificação e entre logo.,,Nu mai flutura cardul în fața mea și intră.,Прекрати махать своей карточкой перед моим лицом и проходи.,,Sluta vifta med ditt ID-kort i ansiktet på mig och gå in.,Kimliğini yüzüme karşı sallamayı bırak ve içeri gir. +Nothing to see here. Move along.,TXT_DLG_SCRIPT17_D4548_NOTHI,MAP17: Green guards.,,,Nic k vidění. Jdi dál.,Der er intet at se her. Gå videre.,Hier gibt es nichts zu sehen. Geh weiter.,,,Nada que ver aquí. Sigue caminando.,,Täällä ei ole mitään nähtävää. Jatkakaa matkaa.,Rien à voir ici. Bougez.,Nincs itt semmi látnivaló. Mozgás tovább.,Non c'è niente da vedere qui. Gira al largo.,何事も無い。進め。,아무 일도 안 일어났다. 어서 움직여.,Hier is niets te zien. Ga verder.,Ingenting å se her. Gå videre.,Nie ma tu nic do oglądania. Ruszaj się.,Nada pra ver aqui. Vá embora.,,Nimic aici. Mișcă.,Тут не на что смотреть. Проваливай.,,Det finns inget att se här. Gå vidare.,Burada görecek bir şey yok. İlerleyin. "What a healthy specimen. You don't need my help, do you?",TXT_DLG_SCRIPT17_D6064_WHATA,MAP17: Hospital → Quincy,,,"Takový zdravý exemplář! Moji pomoc nepotřebujete, že ne?","Sikke et sundt eksemplar. Du har ikke brug for min hjælp, vel?","Was für ein schönes Exemplar. Du brauchst meine Hilfe nicht, oder?",,,"Que espécimen más saludable. No necesitas mi ayuda, ¿verdad?",,No siinäpä vasta mallitapaus. Et sattumoisin ole avun tarpeessa?,"Quel magnifique spécimen! Vous n'avez pas besoin de mon aide, si?","Micsoda jó erőben levő példány. Neked nem kell segítség, ugye?","Che esemplare sano. Non hai bisogno del mio aiuto, vero?","なんて活きの良い標本だ。 -手当なんて必要なさそうだな、で何だ?","정말 건강한 표본이군. 아마 넌 내 도움이 필요하지 않을 거야, 그렇지?","Wat een gezond exemplaar. Je hebt mijn hulp niet nodig, of wel?",For et sunt eksemplar. Du trenger vel ikke min hjelp?,"Co za zdrowy okaz. Nie potrzebujesz mojej pomocy, prawda?","Mas que espécime mais saudável. Você não precisa da minha ajuda, precisa?",,"Ce specimen sănătos. Nu ai nevoie de ajutorul meu, nu?","Какой прекрасный образец. Тебе не нужна моя помощь, или нужна?",,"Ne kadar sağlıklı bir örnek. Yardımıma ihtiyacın yok, değil mi?" -"Well, yes. Macil sent me.",TXT_RPLY0_SCRIPT17_D6064_WELLY,〃,,,Potřebuju. Poslal mě Macil.,"Jo, jo. Macil har sendt mig.","Nun, doch. Macil hat mich geschickt.",,,"Bueno, sí. Macil me ha enviado.",,"Itse asiassa, kyllä. Macil lähetti minut.","Eh bien, si, Macil m'envoie.","Nos, igen. Macil küldött.","Ecco, si. Mi ha mandato Macil.",そうだ。マシルの使者だ。,"뭐, 그렇지. 마실이 날 보냈으니까.","Nou, ja. Macil heeft me gestuurd.",Jo. Macil sendte meg.,No tak. Macil mnie przysłał.,"Bem, sim. Macil me enviou.",,Ba da. Macil m-a trimis.,"Ну, нужна. Я от Мэйсила.",,"Evet, var. Beni Macil gönderdi." +手当なんて必要なさそうだな、で何だ?","정말 건강한 표본이군. 아마 넌 내 도움이 필요하지 않을 거야, 그렇지?","Wat een gezond exemplaar. Je hebt mijn hulp niet nodig, of wel?",For et sunt eksemplar. Du trenger vel ikke min hjelp?,"Co za zdrowy okaz. Nie potrzebujesz mojej pomocy, prawda?","Mas que espécime mais saudável. Você não precisa da minha ajuda, precisa?",,"Ce specimen sănătos. Nu ai nevoie de ajutorul meu, nu?","Какой прекрасный образец. Тебе не нужна моя помощь, или нужна?",,"Vilket friskt exemplar. Du behöver inte min hjälp, eller hur?","Ne kadar sağlıklı bir örnek. Yardımıma ihtiyacın yok, değil mi?" +"Well, yes. Macil sent me.",TXT_RPLY0_SCRIPT17_D6064_WELLY,〃,,,Potřebuju. Poslal mě Macil.,"Jo, jo. Macil har sendt mig.","Nun, doch. Macil hat mich geschickt.",,,"Bueno, sí. Macil me ha enviado.",,"Itse asiassa, kyllä. Macil lähetti minut.","Eh bien, si, Macil m'envoie.","Nos, igen. Macil küldött.","Ecco, si. Mi ha mandato Macil.",そうだ。マシルの使者だ。,"뭐, 그렇지. 마실이 날 보냈으니까.","Nou, ja. Macil heeft me gestuurd.",Jo. Macil sendte meg.,No tak. Macil mnie przysłał.,"Bem, sim. Macil me enviou.",,Ba da. Macil m-a trimis.,"Ну, нужна. Я от Мэйсила.",,"Jo, jo. Macil skickade mig.","Evet, var. Beni Macil gönderdi." "Shhhh... Keep it quiet, unless you want us both killed. Now, what can I do for you?",TXT_DLG_SCRIPT17_D7580_SHHHH,〃,,,"Pššš... Buď potichu, leda že bys nás oba chtěl nechat popravit. Tak, co pro tebe můžu udělat?","Shhhh... Hold det stille, medmindre du vil have os begge dræbt. Hvad kan jeg gøre for dig?","Psst... sei leise, oder willst du uns beide umbringen? Nun, was kann ich für dich tun?",,,"Shhhh... No tan alto, a menos que quieras que nos maten a ambos. Bueno, ¿Qué puedo hacer por ti?",,"Hyss, suuta soukemmalle, ellet halua tapattaa meitä molempia. No niin, miten voin auttaa?","Silence! Baissez de ton, sauf si vous voulez que l'on se fasse descendre tous le deux.. Que puis-je faire pour vous?","Shhhh...csak csendben, különben mindkettőnket megöletsz. Akkor, miben is segíthetek?","Shhhh... Fai piano, a meno che non vuoi farci ammazzare tutti e due. Ora, che posso fare per te?","シーッ...静かに、 -殺されるかもしれないんだぞ。それで何か用か?","쉿... 죽기 싫으면 조용히 해. 자, 내가 뭘 도와줄까?","Shhhhhh.... Hou het stil, tenzij je wilt dat we allebei gedood worden. Wat kan ik nu voor u doen?","Vær stille, hvis du ikke vil at vi begge skal bli drept. Hva kan jeg gjøre for deg?","Cicho, chyba że chcesz nas obu zabić. Co mogę dla ciebie zrobić?","Shhhh... Fale baixo, a não ser que queira que nos matem. Agora, como posso te ajudar?",,"Șhhhh... Mai încet, dacă nu vrei să murim amândoi. Acum, ce pot face pentru tine?","Тсс... Тише, если не хочешь, чтобы нас обоих убили. Итак, чем я могу тебе помочь?",,"İkimizin de ölmesini istemiyorsan sessiz ol. Şimdi, senin için ne yapabilirim?" -Tell me how to find the Bishop.,TXT_RPLY0_SCRIPT17_D7580_TELLM,〃,,,"Řekni mi, jak najít Biskupa.","Fortæl mig, hvordan jeg finder biskoppen.","Sage mir, wie ich den Bischof finde.",,,Dime como encontrar al Obispo.,,"Kerro, miten löydän Piispan.",Où puis-je trouver l'évêque?,"Áruld el, hol találom meg a Püspököt.",Dimmi dove trovare il Vescovo.,ビショップは何処か聞きたい。,비숍을 어떻게 찾아야 하는지 알려줘.,Vertel me hoe ik de bisschop kan vinden.,Fortell meg hvordan jeg finner biskopen.,Powiedz mi jak znaleźć biskupa.,Diga onde eu encontro o Bispo.,,Spune-mi cum găsesc Episcopul.,"Скажи, как мне найти Епископа.",,Bana Piskopos'u nasıl bulacağımı söyle. +殺されるかもしれないんだぞ。それで何か用か?","쉿... 죽기 싫으면 조용히 해. 자, 내가 뭘 도와줄까?","Shhhhhh.... Hou het stil, tenzij je wilt dat we allebei gedood worden. Wat kan ik nu voor u doen?","Vær stille, hvis du ikke vil at vi begge skal bli drept. Hva kan jeg gjøre for deg?","Cicho, chyba że chcesz nas obu zabić. Co mogę dla ciebie zrobić?","Shhhh... Fale baixo, a não ser que queira que nos matem. Agora, como posso te ajudar?",,"Șhhhh... Mai încet, dacă nu vrei să murim amândoi. Acum, ce pot face pentru tine?","Тсс... Тише, если не хочешь, чтобы нас обоих убили. Итак, чем я могу тебе помочь?",,"Shhhh... Håll tyst, om du inte vill att vi båda ska dödas. Vad kan jag göra för dig?","İkimizin de ölmesini istemiyorsan sessiz ol. Şimdi, senin için ne yapabilirim?" +Tell me how to find the Bishop.,TXT_RPLY0_SCRIPT17_D7580_TELLM,〃,,,"Řekni mi, jak najít Biskupa.","Fortæl mig, hvordan jeg finder biskoppen.","Sage mir, wie ich den Bischof finde.",,,Dime como encontrar al Obispo.,,"Kerro, miten löydän Piispan.",Où puis-je trouver l'évêque?,"Áruld el, hol találom meg a Püspököt.",Dimmi dove trovare il Vescovo.,ビショップは何処か聞きたい。,비숍을 어떻게 찾아야 하는지 알려줘.,Vertel me hoe ik de bisschop kan vinden.,Fortell meg hvordan jeg finner biskopen.,Powiedz mi jak znaleźć biskupa.,Diga onde eu encontro o Bispo.,,Spune-mi cum găsesc Episcopul.,"Скажи, как мне найти Епископа.",,Berätta hur jag hittar biskopen.,Bana Piskopos'u nasıl bulacağımı söyle. "Ohhh, I knew you would ask me for that. Look behind you. That's the entrance to the Bishop's citadel. It's guarded by a force field that is only shut off for official visitors, not you.",TXT_DLG_SCRIPT17_D9096_OHHHI,〃,,,"Ohó, já věděl, že se mě na tohle zeptáš. Podívej se za sebe. To je vchod do Biskupovy citadely. Je střežená silovým polem, které se vypíná pouze kvůli oficiálním návštěvám, ne tobě.","Jeg vidste, du ville spørge mig om det. Se bag dig. Det er indgangen til biskoppens citadel. Den er bevogtet af et kraftfelt, der kun er lukket for officielle besøgende, ikke dig.","Oh, hab ich's doch geahnt, dass du mich das fragen würdest. Schau mal hinter dich. Dort ist der Eingang zu der Festung des Bischofs. Er ist durch ein Kraftfeld geschützt, welches sich nur für offizielle Besucher abschaltet und nicht für dich.",,,"Ohhh, sabía que me preguntarías eso. Mira detrás de ti. Esa es la entrada a la ciudadela del Obispo. Está guardada por un campo de fuerza que solo se apaga para visitantes oficiales, no tú.",,"Oo, arvasin, että kysyisit sitä minulta. Katso taaksesi. Siellä on sisäänkäynti Piispan linnoitukseen. Sitä turvaa voimakenttä, joka kytketään pois päältä ainoastaan virallisille vieraille, ei sinulle.","Ohh, je savais que vous me demanderiez cela. Regardez derrière vous. C'est l'entrée de la citadelle de l'évêque. Elle est gardée par un champ de force qui ne s'ouvre que pour les visites officielles, pas vous.","Ohhh, tudtam, hogy ezt fogod kérdezni. Nézz csak magad mögé. Ez a püspök fellegvárához a bejárat. Egy erőpajzs védi, és csak hivatalos látogatóknak nyitják ki, aminek valljuk be Te nem igazán felelsz meg.","Ohhh, sapevo che me l'avresti chiesto. Guarda dietro di te. Quello è l'ingresso per la cittadella del Vescovo. È protetta da un campo di forza che viene disattivato solo per le visite ufficiali, quindi non per la tua.","おおぅ、そういう事だろうと思った。 後ろを見ろ。そこがビショップの大聖堂だ。 しかし要人以外は入れないよう フォースフィールドが張ってある、 -君には通れないな。","호오오, 난 네가 그걸 물어볼 줄 알았어. 뒤를 돌아봐. 저건 비숍의 성채로 향하는 입구야. 방어막으로 덮여있는데 저걸 끌 수 있는 건 허가된 방문자뿐이야. 네가 아니라.","Ohhhh, ik wist dat je me dat zou vragen. Kijk achter je. Dat is de ingang van de bisschopsburcht. Het wordt bewaakt door een krachtveld dat alleen afgesloten is voor officiële bezoekers, niet voor jou.","Jeg visste du ville spørre om det. Se bak deg. Det er inngangen til biskopens citadell. Den er bevoktet av et kraftfelt som bare er stengt for offisielle besøkende, ikke deg.","Ohhh, wiedziałem, że mnie o to poprosisz. Spójrz za siebie. To wejście do cytadeli biskupa. Jest strzeżone przez pole siłowe, które jest wyłączane tylko dla oficjalnych gości, nie dla ciebie.","Ahhh, eu sabia que você me perguntaria isso. Olhe atrás de você. Essa é a entrada para a cidadela do Bispo. Ela é protegida por um campo de força que é desligada somente para visitantes oficiais, para você não.",,"Ohhh, știam eu că asta urma să mă întrebi. Aia e intrarea către citadela Episcopului. E apărată de un scut care se oprește numai pentru vizitatorii autorizați, nu pentru tine.","А-а-а, я знал, что ты спросишь об этом. Оглянись: это вход в цитадель Епископа. Он защищён силовым полем, которое отключается только для официальных посетителей, не для тебя.",,"Benden bunu isteyeceğini biliyordum. Arkana bak. Bu Piskopos'un kalesinin girişi. Sadece resmi ziyaretçiler için kapatılan bir güç alanı tarafından korunuyor, sen değil." -I must kill the Bishop.,TXT_RPLY0_SCRIPT17_D9096_IMUST,〃,,,Musím zabít Biskupa.,Jeg må dræbe biskoppen.,Ich muss den Bischof töten.,,,Debo matar al Obispo.,,Minun on tapettava Piispa.,Je dois tuer l'évêque.,Meg kell ölnöm a Püspököt.,Devo uccidere il Vescovo.,ビショップを殺さなければならないんだ。,난 비숍을 죽여야만 해.,Ik moet de bisschop vermoorden.,Jeg må drepe biskopen.,Muszę zabić biskupa.,Preciso matar o Bispo.,,Trebuie să-l omor pe Episcop.,Я должен убить Епископа.,,Piskoposu öldürmeliyim. +君には通れないな。","호오오, 난 네가 그걸 물어볼 줄 알았어. 뒤를 돌아봐. 저건 비숍의 성채로 향하는 입구야. 방어막으로 덮여있는데 저걸 끌 수 있는 건 허가된 방문자뿐이야. 네가 아니라.","Ohhhh, ik wist dat je me dat zou vragen. Kijk achter je. Dat is de ingang van de bisschopsburcht. Het wordt bewaakt door een krachtveld dat alleen afgesloten is voor officiële bezoekers, niet voor jou.","Jeg visste du ville spørre om det. Se bak deg. Det er inngangen til biskopens citadell. Den er bevoktet av et kraftfelt som bare er stengt for offisielle besøkende, ikke deg.","Ohhh, wiedziałem, że mnie o to poprosisz. Spójrz za siebie. To wejście do cytadeli biskupa. Jest strzeżone przez pole siłowe, które jest wyłączane tylko dla oficjalnych gości, nie dla ciebie.","Ahhh, eu sabia que você me perguntaria isso. Olhe atrás de você. Essa é a entrada para a cidadela do Bispo. Ela é protegida por um campo de força que é desligada somente para visitantes oficiais, para você não.",,"Ohhh, știam eu că asta urma să mă întrebi. Aia e intrarea către citadela Episcopului. E apărată de un scut care se oprește numai pentru vizitatorii autorizați, nu pentru tine.","А-а-а, я знал, что ты спросишь об этом. Оглянись: это вход в цитадель Епископа. Он защищён силовым полем, которое отключается только для официальных посетителей, не для тебя.",,"Jag visste att du skulle be mig om det. Titta bakom dig. Det är ingången till biskopens citadell. Den är bevakad av ett kraftfält som bara stängs av för officiella besökare, inte för dig.","Benden bunu isteyeceğini biliyordum. Arkana bak. Bu Piskopos'un kalesinin girişi. Sadece resmi ziyaretçiler için kapatılan bir güç alanı tarafından korunuyor, sen değil." +I must kill the Bishop.,TXT_RPLY0_SCRIPT17_D9096_IMUST,〃,,,Musím zabít Biskupa.,Jeg må dræbe biskoppen.,Ich muss den Bischof töten.,,,Debo matar al Obispo.,,Minun on tapettava Piispa.,Je dois tuer l'évêque.,Meg kell ölnöm a Püspököt.,Devo uccidere il Vescovo.,ビショップを殺さなければならないんだ。,난 비숍을 죽여야만 해.,Ik moet de bisschop vermoorden.,Jeg må drepe biskopen.,Muszę zabić biskupa.,Preciso matar o Bispo.,,Trebuie să-l omor pe Episcop.,Я должен убить Епископа.,,Jag måste döda biskopen.,Piskoposu öldürmeliyim. "Oh, sure you do. First, fight your way into the security complex and use the teleporter. And this might be more to your liking, destroy the computer in central administration. No computer, no force field.",TXT_DLG_SCRIPT17_D10612_OHSUR,〃,,,"No jistě že! Nejprve se probojuj do bezpečnostního komplexu a použij teleportér. A tohle by se ti mohlo více zamlouvat: Znič počítač v ústřední administraci. Žádný počítač, žádné pole.","Selvfølgelig skal du det. Først skal du kæmpe dig ind i sikkerhedskomplekset og bruge teleporteren. Og dette er måske mere efter din smag, ødelæg computeren i centraladministrationen. Ingen computer, intet kraftfelt.","Oh, aber klar doch. Erst kämpf dich bis zum Sicherheitskomplex durch und benutze den Teleporter. Und er nächste Schritt dürfte dir gefallen: zerstöre den Computer in der Hauptverwaltung. Kein Computer, kein Kraftfeld.",,,"Oh, seguro que sí. Primero, lucha camino adentro del complejo de seguridad y usa el teletransporte. Y esto puede que sea de tu agrado, destruye la computadora en administración central. Sin computadora, no hay campo de fuerza.","Oh, seguro que sí. Primero, pelea para entrar al complejo de seguridad y usa el teletransporte. Y esto puede que sea de tu agrado, destruye la computadora en administración central. Sin computadora, no hay campo de fuerza.","Niinpä tietysti. Ensiksi taistele tiesi turvallisuuskeskukseen ja käytä kaukosiirrintä. Ja tämä saattaa olla ehkä enemmän sinun mieleesi: tuhoa tietokone keskushallinnossa. Ei tietokonetta, ei voimakenttää.","Oh, oui, bien sûr que vous devez. D'abord il faudra forcer le chemin vers le complexe de sécurité, puis utiliser le téléporteur. Ce qui vous plaira aussi, détruisez l'ordinateur dans le centre d'administration. Pas d'ordinateur, pas de champ de force.","Oh, persze persze. Előszöris, küzdd magad át a biztonsági komplexumig és használd a teleportert. Aztán - ami talán jobban fog tetszeni - tedd tönkre a számítógépet a központi adminisztráción. Ha nincs számítógép, nincs erőpajzs.","Oh, come no. Per cominciare, devi andare nel complesso di sicurezza e usare il teletrasporto là. E questo penso ti piacerà, devi distruggere il computer nell'amministrazione centrale. Niente computer, niente campo di forza.","ああ、だろうな。先にまず複合警備施設を 制圧してそこにあるテレポーターを使え。 君に合った方法だと思うが、テレポーター先の 中央管理部にあるコンピューターを潰せ。 コンピューターが無けれは、フォースも無しだ。 ","아, 그렇겠지. 먼저 보안단지에 들어가서 텔레포터를 이용해. 그리고 어쩌면 이건 네 취향일지도 모르겠군. 중앙 관리소에서 컴퓨터를 파괴해. 컴퓨터도 없애고, 방어막도 없애버리라고. - \cy최근 상황을 보건대, 잠입 작전은 힘들 것 같아.","Oh, zeker weten. Vecht je eerst een weg naar het veiligheidscomplex en gebruik de teleporter. En dit kan meer naar uw zin zijn, vernietig de computer in de centrale administratie. Geen computer, geen krachtveld.","Klart du må. Først må du kjempe deg inn i sikkerhetskomplekset og bruke teleporteren. Og dette er kanskje mer etter din smak. Ødelegg datamaskinen i sentraladministrasjonen. Ingen datamaskin, intet kraftfelt.","Oczywiście, że tak. Najpierw pokonaj drogę do kompleksu bezpieczeństwa i użyj teleportera. A to może bardziej ci się spodoba, zniszcz komputer w centralnej administracji. Nie ma komputera, nie ma pola siłowego.","Ah, mas é claro que precisa. Primeiro, lute até o complexo de segurança e use o teletransportador. E acho que você vai gostar disto: destrua o computador na administração central. Sem computador, sem campo de força.",,"Oh, normal. Mai întâi, trebuie să te zbați să ajungi în complexul de securitate și să folosești teleportorul. Și asta s-ar putea să îți placă mai mult, distruge calculatorul din camera de administrare centrală. Niciun calculator, niciun câmp de forță.","О, не сомневаюсь. Для начала проберись в охранный комплекс и используй телепорт. И, что тебе должно больше понравиться, уничтожь компьютер в центральной администрации. Нет компьютера — нет силового поля.",,"Tabii ki öldürmelisin. İlk olarak, güvenlik kompleksine girmek için savaş ve ışınlayıcıyı kullan. Ve bu daha çok hoşuna gidebilir, merkezi yönetimdeki bilgisayarı yok et. Bilgisayar yoksa, güç alanı da yok." -"Great, that sounds easy.",TXT_RPLY0_SCRIPT17_D10612_GREAT,〃,,,"Super, to zní snadně.","Fint, det lyder nemt.","Großartig, das klingt doch einfach.",,,"Genial, suena fácil.",,"Loistavaa, kuulostaa helpolta.","Bien, ça à l'air facile.","Remek, ez könnyűnek hangzik.","Ottimo, sembra facile.",そりゃいい、簡単そうだな。,"좋아, 쉬운 일인 것 같군.","Geweldig, dat klinkt gemakkelijk.","Flott, det høres enkelt ut.","Wspaniale, to brzmi łatwo.",Ótimo. Isso parece fácil.,,"Grozav, sună simplu.","Здорово, звучит легко.",,"Harika, kulağa kolay geliyor." + \cy최근 상황을 보건대, 잠입 작전은 힘들 것 같아.","Oh, zeker weten. Vecht je eerst een weg naar het veiligheidscomplex en gebruik de teleporter. En dit kan meer naar uw zin zijn, vernietig de computer in de centrale administratie. Geen computer, geen krachtveld.","Klart du må. Først må du kjempe deg inn i sikkerhetskomplekset og bruke teleporteren. Og dette er kanskje mer etter din smak. Ødelegg datamaskinen i sentraladministrasjonen. Ingen datamaskin, intet kraftfelt.","Oczywiście, że tak. Najpierw pokonaj drogę do kompleksu bezpieczeństwa i użyj teleportera. A to może bardziej ci się spodoba, zniszcz komputer w centralnej administracji. Nie ma komputera, nie ma pola siłowego.","Ah, mas é claro que precisa. Primeiro, lute até o complexo de segurança e use o teletransportador. E acho que você vai gostar disto: destrua o computador na administração central. Sem computador, sem campo de força.",,"Oh, normal. Mai întâi, trebuie să te zbați să ajungi în complexul de securitate și să folosești teleportorul. Și asta s-ar putea să îți placă mai mult, distruge calculatorul din camera de administrare centrală. Niciun calculator, niciun câmp de forță.","О, не сомневаюсь. Для начала проберись в охранный комплекс и используй телепорт. И, что тебе должно больше понравиться, уничтожь компьютер в центральной администрации. Нет компьютера — нет силового поля.",,"Javisst, det måste du. Kämpa dig först in i säkerhetskomplexet och använd teleportern. Och det här kanske är mer till din smak, förstör datorn i centralförvaltningen. Ingen dator, inget kraftfält.","Tabii ki öldürmelisin. İlk olarak, güvenlik kompleksine girmek için savaş ve ışınlayıcıyı kullan. Ve bu daha çok hoşuna gidebilir, merkezi yönetimdeki bilgisayarı yok et. Bilgisayar yoksa, güç alanı da yok." +"Great, that sounds easy.",TXT_RPLY0_SCRIPT17_D10612_GREAT,〃,,,"Super, to zní snadně.","Fint, det lyder nemt.","Großartig, das klingt doch einfach.",,,"Genial, suena fácil.",,"Loistavaa, kuulostaa helpolta.","Bien, ça à l'air facile.","Remek, ez könnyűnek hangzik.","Ottimo, sembra facile.",そりゃいい、簡単そうだな。,"좋아, 쉬운 일인 것 같군.","Geweldig, dat klinkt gemakkelijk.","Flott, det høres enkelt ut.","Wspaniale, to brzmi łatwo.",Ótimo. Isso parece fácil.,,"Grozav, sună simplu.","Здорово, звучит легко.",,"Bra, det låter enkelt.","Harika, kulağa kolay geliyor." "There's an advantage to destroying the computer, that's where the plans to the tower are kept. Can you say, five finger discount? Heh heh!",TXT_DLG_SCRIPT17_D12128_THERE,〃,,,Zničení toho počítače má výhodu: Na tom samém místě jsou uschovány plány věže. Co říkáš na takovou koupi za pět prstů? Haha!,"Der er en fordel ved at ødelægge computeren, det er der, hvor planerne til tårnet opbevares. Kan du sige, fem fingre rabat? Heh heh!","Es hätte sein Gutes, den Computer zu zerstören, denn dort sind auch die Pläne für den Turm. Kannst du sagen: Mitgehen lassen? Hehe!",,,"Hay una ventaja al destruir la computadora, ahí se guardan los planos de la torre. Puedes decir... ¿descuento a cinco dedos? ¡je je!",,"Tietokoneen tuhoamisessa on etunsa; siinä pidetään tornin piirustuksia. Sanottaisiinko, kaupanpäällisinä? Hehheh!",Ce serait avantageux de détruire l'ordinateur car c'est là qu'ils gardent les plans de la tour. C'est facile d'avoir ça gratuitement quand on peut juste les prendre comme ça!,"Van amúgy egy előnye a számítógép szobának, ott tartják ugyanis a torony terveit ott tárolják. Mi lenne mondjuk ha véletlen magaddal hoznád őket? heh heh!",Sarebbe vantaggioso distruggere il computer perché è lì che tengono i piani per la torre. È facile ottenerli gratuitamente quando puoi prenderli in questo modo! Heh heh!,"コンピューターを潰す利点はな、 奴等の塔へ送られる情報もそれに保管されている。 -それを万引き、とも言えるな?へヘッ!","컴퓨터를 파괴할 승산이 있을거야, 성채로 향하는 계획서가 있는 곳이니까. 물건 좀 빼돌려 본 적 있나? 헤헷!","Er is een voordeel aan het vernietigen van de computer, dat is waar de plannen om de toren te vernietigen worden bewaard. Kunt je zeggen, vijf vingers korting? Heh heh heh!","Det er en fordel med å ødelegge datamaskinen, det er der planene til tårnet er oppbevart. Kan du si, fem-finger-rabatt? Heh heh!","Jest jeszcze jedna zaleta zniszczenia komputera, to tam trzymane są plany wieży. Czy można powiedzieć, zniżka na pięć palców? Heh heh!","Há uma vantagem em destruir o computador. É nele onde ficam os planos da torre. É pegar e levar, hehehe!",,"Există un avantaj în distrugerea calculatorului, acolo sunt ținute schemele turnului. Poți spune, reducere la cinci degete? Ha ha!","В уничтожении компьютера есть ещё один плюс: планы башни хранятся там. Можно сказать, скидка на все сто? Хе-хе!",,"Bilgisayarı yok etmenin bir avantajı var, kulenin planları orada tutuluyor. Beş parmak indirimi diyebilir misin? Heh heh!" -Anything else?,TXT_RPLY0_SCRIPT17_D12128_ANYTH,〃,,,Ještě něco dalšího?,Er der andet?,Noch etwas?,,,¿Algo más?,,Onko jotain muuta?,Quoi d'autre?,Valami más még?,C'è dell'altro?,他にあるか?,뭐 다른건 없나?,Nog iets anders?,Noe annet?,Co jeszcze?,Mais alguma coisa?,,Altceva?,Что-нибудь ещё?,,Başka bir şey var mı? +それを万引き、とも言えるな?へヘッ!","컴퓨터를 파괴할 승산이 있을거야, 성채로 향하는 계획서가 있는 곳이니까. 물건 좀 빼돌려 본 적 있나? 헤헷!","Er is een voordeel aan het vernietigen van de computer, dat is waar de plannen om de toren te vernietigen worden bewaard. Kunt je zeggen, vijf vingers korting? Heh heh heh!","Det er en fordel med å ødelegge datamaskinen, det er der planene til tårnet er oppbevart. Kan du si, fem-finger-rabatt? Heh heh!","Jest jeszcze jedna zaleta zniszczenia komputera, to tam trzymane są plany wieży. Czy można powiedzieć, zniżka na pięć palców? Heh heh!","Há uma vantagem em destruir o computador. É nele onde ficam os planos da torre. É pegar e levar, hehehe!",,"Există un avantaj în distrugerea calculatorului, acolo sunt ținute schemele turnului. Poți spune, reducere la cinci degete? Ha ha!","В уничтожении компьютера есть ещё один плюс: планы башни хранятся там. Можно сказать, скидка на все сто? Хе-хе!",,"Det finns en fördel med att förstöra datorn, det är där ritningarna till tornet förvaras. Kan du säga femfingerrabatt? Heh heh!","Bilgisayarı yok etmenin bir avantajı var, kulenin planları orada tutuluyor. Beş parmak indirimi diyebilir misin? Heh heh!" +Anything else?,TXT_RPLY0_SCRIPT17_D12128_ANYTH,〃,,,Ještě něco dalšího?,Er der andet?,Noch etwas?,,,¿Algo más?,,Onko jotain muuta?,Quoi d'autre?,Valami más még?,C'è dell'altro?,他にあるか?,뭐 다른건 없나?,Nog iets anders?,Noe annet?,Co jeszcze?,Mais alguma coisa?,,Altceva?,Что-нибудь ещё?,,Något annat?,Başka bir şey var mı? "Oh well, word has it that the bailey's warehouse received a shipment of maulers, that's the weapon that vaporizes.",TXT_DLG_SCRIPT17_D13644_OHWEL,〃,,,"No, špitá se, že skladiště v opevnění obdrželo zásilku trhačů. To je ta zbraň, která vypařuje.","Nå ja, det siges, at Baileys lager har modtaget en sending maulers, det er det våben, der fordamper.","Nun, man sagt, dass im Lagerhaus eine Ladung Vernichter abgeliefert wurde, die Waffe die verdampft.",,,"Oh bueno, se dice que el almacén de la muralla ha recibido un envío de trituradores, es el arma que vaporiza.",,"No, tarina kertoo, että linnanpihan varastoon on saapunut erä moukareita; sitä asetta, joka haihduttaa.",Oh. La rumeur court que le dépôt du mur d'enceinte a reçu une cargaison de broyeurs. C'est l'arme qui vaporise les gens.,"Hát, az a hír járja, hogy érkezett pár közelharci fegyver a várfalnál levő raktárba. Ez az a fegyver ami rögtön elporlaszt.","Oh beh, ho sentito dire che il magazzino del bastione ha appena ricevuto un carico di Mauler, è l'arma che vaporizza.","そうだな、中庭の倉庫にマウラーが納品されたと 聞いた。その威力は相手を消滅させられる程だと。","음, 듣자 하니 성안 쪽 격납고에 마울러가 입고되었다더군. 뭐든지 날려버리는 무기 말이야. - \cy흠. 이유 없이 그런 소문이 났을 리는 없을 테고... 나도 그 무기 하나만 가져다줘.","Nou ja, er wordt gezegd dat het magazijn van de bailey een zending maulers heeft ontvangen, dat is het wapen dat verdampt.",Ryktene sier at Borggårdens lager har fått en sending maulere. Det er våpenet som fordamper.,"Podobno do magazynu Bailey'a dotarła dostawa maulerów, czyli broni, która paruje.","Bem, dizem que o depósito recebeu um envio de desintegradores. Aquela arma que...desintegra.",,"Păi, vorba spune că depozitul din curtea interioară a primit un pachet de schiloditoare, asta e arma care vapozirează.","Скажем так: есть слух, что склад крепости получил партию Истязателей: оружия, которое «испепеляет».",,"Bailey'nin deposuna parçalayıcı sevkiyatı yapıldığı söyleniyor, buharlaştıran bir silah." -"Is that it, now?",TXT_RPLY0_SCRIPT17_D13644_ISTHA,〃,,,Je to už všechno?,Er det det nu?,War es das jetzt?,,,"Con que eso es, ¿eh?",,Ja onko siinä nyt kaikki?,Vraiment?,Mi van már megint?,Tutto qui?,それはまだあるんだな?,이게 전부지?,"Is dat het, nu?",Er det alt?,"To wszystko, teraz?",Só isso?,,"Asta e, deci?",Теперь всё?,,Bu kadar mı yani? -"Don't you know the meaning of the words ""get lost""?",TXT_DLG_SCRIPT17_D15160_DONTY,〃,,,Neznáš význam slova „zmizni“?,"Kender du ikke betydningen af ordene ""forsvind""?",Sagen dir die Worte „Verzieh dich“ etwas?,,,¿No sabes lo que significa la palabra Piérdete?,,"Etkö tunne sanojen ""ala laputtaa"" merkitystä?",Vous ne connaîssez pas le sens du mot: « Dégage?»,"Melyik részét nem érted a ""húzz el""-nek?","Non conosci il significato delle parole, ""ora di andare""?",次の話はバレる前に'去れ'か?,"자네, “꺼져.”가 무슨 뜻인지는 알지?","Weet je niet wat de betekenis is van de woorden ""verdwalen""?","Vet du ikke hva som menes med ""stikk""?","Nie znasz znaczenia słowa ""zgubić się""?","Você não sabe o que significa a expressão ""se manda""?",,"Nu cunoști semnificația cuvântului ""dispari""?",Ты не знаешь значения слова «исчезни»?,,Kaybol kelimesinin anlamını bilmiyor musun? + \cy흠. 이유 없이 그런 소문이 났을 리는 없을 테고... 나도 그 무기 하나만 가져다줘.","Nou ja, er wordt gezegd dat het magazijn van de bailey een zending maulers heeft ontvangen, dat is het wapen dat verdampt.",Ryktene sier at Borggårdens lager har fått en sending maulere. Det er våpenet som fordamper.,"Podobno do magazynu Bailey'a dotarła dostawa maulerów, czyli broni, która paruje.","Bem, dizem que o depósito recebeu um envio de desintegradores. Aquela arma que...desintegra.",,"Păi, vorba spune că depozitul din curtea interioară a primit un pachet de schiloditoare, asta e arma care vapozirează.","Скажем так: есть слух, что склад крепости получил партию Истязателей: оружия, которое «испепеляет».",,"Nåja, ryktet säger att Baileys lager har fått en leverans av maulers, det är vapnet som förångar.","Bailey'nin deposuna parçalayıcı sevkiyatı yapıldığı söyleniyor, buharlaştıran bir silah." +"Is that it, now?",TXT_RPLY0_SCRIPT17_D13644_ISTHA,〃,,,Je to už všechno?,Er det det nu?,War es das jetzt?,,,"Con que eso es, ¿eh?",,Ja onko siinä nyt kaikki?,Vraiment?,Mi van már megint?,Tutto qui?,それはまだあるんだな?,이게 전부지?,"Is dat het, nu?",Er det alt?,"To wszystko, teraz?",Só isso?,,"Asta e, deci?",Теперь всё?,,Är det allt?,Bu kadar mı yani? +"Don't you know the meaning of the words ""get lost""?",TXT_DLG_SCRIPT17_D15160_DONTY,〃,,,Neznáš význam slova „zmizni“?,"Kender du ikke betydningen af ordene ""forsvind""?",Sagen dir die Worte „Verzieh dich“ etwas?,,,¿No sabes lo que significa la palabra Piérdete?,,"Etkö tunne sanojen ""ala laputtaa"" merkitystä?",Vous ne connaîssez pas le sens du mot: « Dégage?»,"Melyik részét nem érted a ""húzz el""-nek?","Non conosci il significato delle parole, ""ora di andare""?",次の話はバレる前に'去れ'か?,"자네, “꺼져.”가 무슨 뜻인지는 알지?","Weet je niet wat de betekenis is van de woorden ""verdwalen""?","Vet du ikke hva som menes med ""stikk""?","Nie znasz znaczenia słowa ""zgubić się""?","Você não sabe o que significa a expressão ""se manda""?",,"Nu cunoști semnificația cuvântului ""dispari""?",Ты не знаешь значения слова «исчезни»?,,"Vet du inte vad ordet ""försvinna"" betyder?",Kaybol kelimesinin anlamını bilmiyor musun? Talk to Quincy first. I'm not allowed to help anyone unless he says it's ok.,TXT_DLG_SCRIPT17_D16676_TALKT,MAP17: Hospital → Assistant,,,Promluvte si nejprve s Quincym. Já nemůžu nikomu pomáhat dokud to nepovolí.,"Tal med Quincy først. Jeg må ikke hjælpe nogen, medmindre han siger, at det er i orden.","Rede erst mit Quincy. Ich darf mit niemanden reden, solange er nicht sein OK gegeben hat.",,,Habla con Quincy primero. No se me permite ayudar a nadie a menos que él lo diga.,,"Puhu ensin Quincylle. En saa auttaa ketään, ellei hän anna siihen lupaa.",Parlez à Quincy d'abord. Je ne suis pas autorisé à aider qui que ce soit sans son autorisation.,"Beszélj Quincyvel először. Nem beszélhetek senkivel, amíg nem engedélyezi.",Parla con Quincy prima. Non sono autorizzato ad aiutare nessuno se prima lui non da il permesso.,"先にクインシーと話を。彼から許可を -得られない限りお助けすることは出来ません。",퀸시에게 먼저 물어보세요. 전 그가 괜찮다 하지 않는다면 아무것도 도울 수 없습니다.,"Praat eerst met Quincy. Ik mag niemand helpen, tenzij hij zegt dat het goed is.",Snakk med Quincy først. Jeg har ikke lov til å hjelpe noen med mindre han sier det er ok.,"Najpierw porozmawiaj z Quincy. Nie wolno mi nikomu pomagać, dopóki on nie powie, że to jest w porządku.",Fale com o Quincy primeiro. Não posso ajudar ninguém enquanto ele não autorizar.,,Vorbește cu Quincy mai întâi. Nu am permisiunea să ajut pe nimeni până nu spune că e în regulă.,"Сперва поговори с Куинси. Мне не позволено помогать кому-либо, пока он не разрешит.",,Önce Quincy ile konuş. O izin vermedikçe kimseye yardım edemem. -How how can I help you today?,TXT_DLG_SCRIPT17_D18192_HOWHO,〃,,,Jak vám mohu dnes pomoci?,Hvordan kan jeg hjælpe dig i dag?,Wie kann ich dir heute helfen?,,Kiel mi helpu vin hodiaŭ?,¿Cómo puedo ayudarte hoy?,,Miten voin olla avuksi tänään?,Comment puis-je vous aider aujourd'hui?,Ma miben segíthetek?,Come posso aiutarti oggi?,本日は何かお困りで?,오늘은 어떻게 도와드릴까요?,Hoe kan ik je vandaag helpen?,Hvordan kan jeg hjelpe deg i dag?,Jak mogę ci dzisiaj pomóc?,Como posso ajudá-lo hoje?,,Cu ce te pot ajuta azi?,Чем могу быть полезен?,,Bugün sana nasıl yardım edebilirim? -Med patch,TXT_RPLY0_SCRIPT17_D18192_MEDPA,〃,,,Obvazy,Medicinsk plaster,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekäärettä.,Pansement.,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinplaster,Bandaż,Compressa médica,,Trusă de prim-ajutor.,Бинтами,,Med yama -Here's your patch.,TXT_RYES0_SCRIPT17_D18192_HERES,〃,,,Tady jsou.,Her er dit plaster.,Hier ist deine Bandage.,,Jen viaj kuracbendoj,Aquí tienes tus tiritas.,Aquí tienes tus curitas.,Tässä kääreesi.,Voilà votre pansement.,Itt a tapaszod.,Ecco le tue bende.,これをどうぞ。,"의료 붕대 하나, 여기 있습니다.",Hier is je patch.,Her er lappen din.,Oto twój bandaż.,Aqui está sua compressa.,,Aici e trusa.,Вот твой набор бинтов.,,İşte yaman. -That is 15 gold my friend.,TXT_RNO0_SCRIPT17_D18192_THATI,〃,,,"To je patnáct zlatých, příteli.","Det er 15 guld, min ven.","Das macht 15 Gold, mein Freund.",,"Vi bezonas 15 pecojn, amiko.","Son 15 de oro, amigo.",,"Se saisi olla 15 kolikkoa, ystäväiseni.","15 pièces pour ça, mon ami.",Az bizony 15 arany lesz barátom.,Sono 15 pezzi d'oro amico mio.,15 ゴールド必要です。,"그건 15 골드입니다, 친구.","Dat is 15 goud, mijn vriend.","Det er 15 gull, min venn.","To jest 15 złota, mój przyjacielu.","Custa 15 moedas de ouro, meu amigo.",,Costă 15 monezi amice.,"Они стоят 15 золотых, друг.",,Bu 15 altın dostum. -Medical kit,TXT_RPLY1_SCRIPT17_D18192_MEDIC,〃,,,Lékárničku,Medicinsk kit,Verbandskasten,,Sukurkesto,Botiquín,,Lääkintälaukku.,Kit médical.,Elsősegély doboz.,Kit medico,医療用キット,구급 키트,Medische kit,Medisinsk utstyr,Zestaw medyczny,Kit médico,,Kit de prim-ajutor.,Аптечкой,,Tıbbi kit -Here's your medical kit.,TXT_RYES1_SCRIPT17_D18192_HERES,〃,,,Tady je.,Her er dit medicinske kit.,Hier ist dein Verbandskasten,,Jen via sukurkesto.,Aquí tienes tu botiquín.,,Tässä lääkintälaukkusi.,Voilà votre kit médical.,Itt az elsősegélydobozod.,Ecco il tuo kit medico.,こちらが 医療用キットです。,구급 키트입니다. 잘 쓰시길.,Hier is je medische uitrusting.,Her er førstehjelpsskrinet ditt.,Oto twój zestaw medyczny.,Aqui está o seu kit médico,,Aici e kitul.,Вот твоя аптечка.,,İşte tıbbi çantan. -You're a bit low on funds for that.,TXT_RNO1_SCRIPT17_D18192_YOURE,〃,,,Tu si nemůžete dovolit.,Du har lidt for få midler til det.,Du hast zu wenig Geld dafür.,,Mankas mono al vi.,Estás algo falto de dinero.,,Sinulla on varat hieman vähissä siihen.,Vous manquez d'argent pour ça.,Nincs elég pénzed ehhez.,Sei un pò a corto di fondi per quello.,その為の資金が少し足りません。,그거 사기엔 자금이 부족한 듯.,Je hebt daar een beetje weinig geld voor.,Du har litt lite penger til det.,Masz na to trochę mało funduszy.,Você está um pouco mal de dinheiro pra isso.,,Cam puțini bani pentru aia.,Тебе на это не хватает средств.,,Bunun için biraz az paran var. -Field surgery kit,TXT_RPLY2_SCRIPT17_D18192_FIELD,〃,,,Chirurgickou soupravu,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kenttäkirurgilaukku.,Kit de chirurgie.,Harctéri műtéti felszerelés,Kit chirurgico,手術キット,수술 키트.,Veld chirurgie kit,Kirurgisett,Zestaw do chirurgii polowej,Kit de cirurgia,,Kit chirurgical de teren.,Медкомплектом,,Saha ameliyat kiti -"One field surgery kit, done.",TXT_RYES2_SCRIPT17_D18192_ONEFI,〃,,,"Jedna souprava, zde.","Et kirurgisæt, færdig.","Ein Erste-Hilfe-Kasten, kommt sofort.",,Kirurgia kesto. Farite.,Un kit quirúrgico. Listo.,,"Yksi kirurgilaukku, noin.","Un kit de chirurgie, voilà.",Egy műtő felszerelés itt is van.,"Un kit chirurgico, eccolo qua.",野外用手術キット一丁。,수술 키트 하나 여기있습니다.,"Eén veldoperatiekit, klaar.","Ett kirurgisk sett, ferdig.","Jeden zestaw do chirurgii polowej, zrobione.",Um kit de cirurgia saindo,,"Un kit chirurgical de teren, gata.",Один медкомплект. Держи.,,"Bir saha ameliyat kiti, tamamdır." +得られない限りお助けすることは出来ません。",퀸시에게 먼저 물어보세요. 전 그가 괜찮다 하지 않는다면 아무것도 도울 수 없습니다.,"Praat eerst met Quincy. Ik mag niemand helpen, tenzij hij zegt dat het goed is.",Snakk med Quincy først. Jeg har ikke lov til å hjelpe noen med mindre han sier det er ok.,"Najpierw porozmawiaj z Quincy. Nie wolno mi nikomu pomagać, dopóki on nie powie, że to jest w porządku.",Fale com o Quincy primeiro. Não posso ajudar ninguém enquanto ele não autorizar.,,Vorbește cu Quincy mai întâi. Nu am permisiunea să ajut pe nimeni până nu spune că e în regulă.,"Сперва поговори с Куинси. Мне не позволено помогать кому-либо, пока он не разрешит.",,Prata med Quincy först. Jag får inte hjälpa någon om inte han säger att det är okej.,Önce Quincy ile konuş. O izin vermedikçe kimseye yardım edemem. +How how can I help you today?,TXT_DLG_SCRIPT17_D18192_HOWHO,〃,,,Jak vám mohu dnes pomoci?,Hvordan kan jeg hjælpe dig i dag?,Wie kann ich dir heute helfen?,,Kiel mi helpu vin hodiaŭ?,¿Cómo puedo ayudarte hoy?,,Miten voin olla avuksi tänään?,Comment puis-je vous aider aujourd'hui?,Ma miben segíthetek?,Come posso aiutarti oggi?,本日は何かお困りで?,오늘은 어떻게 도와드릴까요?,Hoe kan ik je vandaag helpen?,Hvordan kan jeg hjelpe deg i dag?,Jak mogę ci dzisiaj pomóc?,Como posso ajudá-lo hoje?,,Cu ce te pot ajuta azi?,Чем могу быть полезен?,,Hur kan jag hjälpa dig idag?,Bugün sana nasıl yardım edebilirim? +Med patch,TXT_RPLY0_SCRIPT17_D18192_MEDPA,〃,,,Obvazy,Medicinsk plaster,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekäärettä.,Pansement.,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinplaster,Bandaż,Compressa médica,,Trusă de prim-ajutor.,Бинтами,,Medicinsk plåster,Med yama +Here's your patch.,TXT_RYES0_SCRIPT17_D18192_HERES,〃,,,Tady jsou.,Her er dit plaster.,Hier ist deine Bandage.,,Jen viaj kuracbendoj,Aquí tienes tus tiritas.,Aquí tienes tus curitas.,Tässä kääreesi.,Voilà votre pansement.,Itt a tapaszod.,Ecco le tue bende.,これをどうぞ。,"의료 붕대 하나, 여기 있습니다.",Hier is je patch.,Her er lappen din.,Oto twój bandaż.,Aqui está sua compressa.,,Aici e trusa.,Вот твой набор бинтов.,,Här är ditt plåster.,İşte yaman. +That is 15 gold my friend.,TXT_RNO0_SCRIPT17_D18192_THATI,〃,,,"To je patnáct zlatých, příteli.","Det er 15 guld, min ven.","Das macht 15 Gold, mein Freund.",,"Vi bezonas 15 pecojn, amiko.","Son 15 de oro, amigo.",,"Se saisi olla 15 kolikkoa, ystäväiseni.","15 pièces pour ça, mon ami.",Az bizony 15 arany lesz barátom.,Sono 15 pezzi d'oro amico mio.,15 ゴールド必要です。,"그건 15 골드입니다, 친구.","Dat is 15 goud, mijn vriend.","Det er 15 gull, min venn.","To jest 15 złota, mój przyjacielu.","Custa 15 moedas de ouro, meu amigo.",,Costă 15 monezi amice.,"Они стоят 15 золотых, друг.",,"Det är 15 guld, min vän.",Bu 15 altın dostum. +Medical kit,TXT_RPLY1_SCRIPT17_D18192_MEDIC,〃,,,Lékárničku,Medicinsk kit,Verbandskasten,,Sukurkesto,Botiquín,,Lääkintälaukku.,Kit médical.,Elsősegély doboz.,Kit medico,医療用キット,구급 키트,Medische kit,Medisinsk utstyr,Zestaw medyczny,Kit médico,,Kit de prim-ajutor.,Аптечкой,,Medicinsk utrustning,Tıbbi kit +Here's your medical kit.,TXT_RYES1_SCRIPT17_D18192_HERES,〃,,,Tady je.,Her er dit medicinske kit.,Hier ist dein Verbandskasten,,Jen via sukurkesto.,Aquí tienes tu botiquín.,,Tässä lääkintälaukkusi.,Voilà votre kit médical.,Itt az elsősegélydobozod.,Ecco il tuo kit medico.,こちらが 医療用キットです。,구급 키트입니다. 잘 쓰시길.,Hier is je medische uitrusting.,Her er førstehjelpsskrinet ditt.,Oto twój zestaw medyczny.,Aqui está o seu kit médico,,Aici e kitul.,Вот твоя аптечка.,,Här är ditt medicinska utrustning.,İşte tıbbi çantan. +You're a bit low on funds for that.,TXT_RNO1_SCRIPT17_D18192_YOURE,〃,,,Tu si nemůžete dovolit.,Du har lidt for få midler til det.,Du hast zu wenig Geld dafür.,,Mankas mono al vi.,Estás algo falto de dinero.,,Sinulla on varat hieman vähissä siihen.,Vous manquez d'argent pour ça.,Nincs elég pénzed ehhez.,Sei un pò a corto di fondi per quello.,その為の資金が少し足りません。,그거 사기엔 자금이 부족한 듯.,Je hebt daar een beetje weinig geld voor.,Du har litt lite penger til det.,Masz na to trochę mało funduszy.,Você está um pouco mal de dinheiro pra isso.,,Cam puțini bani pentru aia.,Тебе на это не хватает средств.,,Du har lite ont om pengar för det.,Bunun için biraz az paran var. +Field surgery kit,TXT_RPLY2_SCRIPT17_D18192_FIELD,〃,,,Chirurgickou soupravu,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kenttäkirurgilaukku.,Kit de chirurgie.,Harctéri műtéti felszerelés,Kit chirurgico,手術キット,수술 키트.,Veld chirurgie kit,Kirurgisett,Zestaw do chirurgii polowej,Kit de cirurgia,,Kit chirurgical de teren.,Медкомплектом,,Fältkirurgisk utrustning,Saha ameliyat kiti +"One field surgery kit, done.",TXT_RYES2_SCRIPT17_D18192_ONEFI,〃,,,"Jedna souprava, zde.","Et kirurgisæt, færdig.","Ein Erste-Hilfe-Kasten, kommt sofort.",,Kirurgia kesto. Farite.,Un kit quirúrgico. Listo.,,"Yksi kirurgilaukku, noin.","Un kit de chirurgie, voilà.",Egy műtő felszerelés itt is van.,"Un kit chirurgico, eccolo qua.",野外用手術キット一丁。,수술 키트 하나 여기있습니다.,"Eén veldoperatiekit, klaar.","Ett kirurgisk sett, ferdig.","Jeden zestaw do chirurgii polowej, zrobione.",Um kit de cirurgia saindo,,"Un kit chirurgical de teren, gata.",Один медкомплект. Держи.,,"Ett fältkirurgiskt utrustning, klart.","Bir saha ameliyat kiti, tamamdır." Come back when you have money!,TXT_RNO2_SCRIPT17_D18192_COMEB,〃,,,"Vrať se, až budeš mít peníze!","Kom tilbage, når du har penge!","Komm wieder, wenn du etwas Geld hast.",,"Revenu kiam vi havos monon!","¡Vuelve cuando -tengas dinero!",,"Tule takaisin, kun sinulla on rahaa!",Revenez quand vous avez des sous!,"Gyere vissza, ha már van elég pénzed.",Torna quando avrai del denaro!,余裕がある時にまたどうぞ!,돈이 좀 있을 때 돌아와요!,Kom terug als je geld hebt!,Kom tilbake når du har penger!,"Wróć, gdy będziesz miał pieniądze!",Volte quando tiver dinheiro!,,Întoarce-te când ai destui bani!,Возвращайся с деньгами!,,Paran olduğunda geri gel! -What is it?,TXT_DLG_SCRIPT18_D0_WHATI,MAP18: Yellow guard,,,Co je?,Hvad er det?,Was gibt es?,,,¿Qué pasa?,,Mikä on?,Vous voulez quoi?,Az meg mi?,Che cos'è?,何事だ?,무슨 일이냐?,Wat is het?,Hva er det?,Co to jest?,O que foi?,,Ce e?,Что тебе нужно?,,Ne oldu? -Just looking around.,TXT_RPLY0_SCRIPT18_D0_JUSTL,〃,,,Jen se poohlížím.,Jeg kigger bare rundt.,Ich schaue mich bloß um.,,,Solo estoy mirando.,,Ihan vain katselen.,Je fais juste un tour.,Csak nézelődök.,Sto soltando guardando.,見周りしている。,그냥 둘러보는 중이었습니다.,Gewoon rondkijken.,Jeg ser meg bare rundt.,Rozglądam się.,Só dando uma olhada.,,Doar mă uit împrejur.,Просто осматриваюсь.,,Sadece etrafa bakıyorum. -Just keep out of the way.,TXT_RYES0_SCRIPT18_D0_JUSTK,〃,,,Prostě se drž z cesty.,Bare hold dig ude af vejen.,Sei einfach niemandem im Weg.,,,Mantente fuera de mi camino.,,Kunhan vain pysyt pois tieltä.,Restez hors du chemin.,Csak ne legyél láb alatt.,Basta che non ti metti in mezzo.,この先は立入禁止だ。,그럼 방해하지마.,Blijf gewoon uit de weg.,Bare hold deg unna.,Trzymaj się z dala od drogi.,Apenas fique fora do caminho.,,Doar nu sta în cale.,Просто не путайся под ногами.,,Yoldan uzak dur. +tengas dinero!",,"Tule takaisin, kun sinulla on rahaa!",Revenez quand vous avez des sous!,"Gyere vissza, ha már van elég pénzed.",Torna quando avrai del denaro!,余裕がある時にまたどうぞ!,돈이 좀 있을 때 돌아와요!,Kom terug als je geld hebt!,Kom tilbake når du har penger!,"Wróć, gdy będziesz miał pieniądze!",Volte quando tiver dinheiro!,,Întoarce-te când ai destui bani!,Возвращайся с деньгами!,,Kom tillbaka när du har pengar!,Paran olduğunda geri gel! +What is it?,TXT_DLG_SCRIPT18_D0_WHATI,MAP18: Yellow guard,,,Co je?,Hvad er det?,Was gibt es?,,,¿Qué pasa?,,Mikä on?,Vous voulez quoi?,Az meg mi?,Che cos'è?,何事だ?,무슨 일이냐?,Wat is het?,Hva er det?,Co to jest?,O que foi?,,Ce e?,Что тебе нужно?,,Vad är det för nåt?,Ne oldu? +Just looking around.,TXT_RPLY0_SCRIPT18_D0_JUSTL,〃,,,Jen se poohlížím.,Jeg kigger bare rundt.,Ich schaue mich bloß um.,,,Solo estoy mirando.,,Ihan vain katselen.,Je fais juste un tour.,Csak nézelődök.,Sto soltando guardando.,見周りしている。,그냥 둘러보는 중이었습니다.,Gewoon rondkijken.,Jeg ser meg bare rundt.,Rozglądam się.,Só dando uma olhada.,,Doar mă uit împrejur.,Просто осматриваюсь.,,Jag tittar bara runt.,Sadece etrafa bakıyorum. +Just keep out of the way.,TXT_RYES0_SCRIPT18_D0_JUSTK,〃,,,Prostě se drž z cesty.,Bare hold dig ude af vejen.,Sei einfach niemandem im Weg.,,,Mantente fuera de mi camino.,,Kunhan vain pysyt pois tieltä.,Restez hors du chemin.,Csak ne legyél láb alatt.,Basta che non ti metti in mezzo.,この先は立入禁止だ。,그럼 방해하지마.,Blijf gewoon uit de weg.,Bare hold deg unna.,Trzymaj się z dala od drogi.,Apenas fique fora do caminho.,,Doar nu sta în cale.,Просто не путайся под ногами.,,Håll dig bara ur vägen.,Yoldan uzak dur. The Templars will be here soon to pick up their new maulers. If you get in their way you're a dead man.,TXT_DLG_SCRIPT18_D1516_THETE,〃,,,"Templáři tu brzy budou vyzvednout si své nové trhače. Jestli se jim připleteš pod nohy, jsi mrtvý.","Tempelridderne kommer snart og henter deres nye maulere. Hvis du kommer i vejen for dem, er du en død mand.","Die Templer werden bald hier sein, um ihre neuen Vernichter abzuholen. Wenn du ihnen im Weg bist, dann bist du ein toter Mann.",,,Los templarios estarán aquí pronto para recoger sus nuevos trituradores. Si te interpones en su camino eres hombre muerto.,,"Temppeliherrat tulevat tänne pian noutamaan uudet moukarinsa. Jos menet heidän tielleen, olet mennyttä.","Les templiers vont venier chercher les nouveaux broyeurs. Si vous les gênez, vous êtes mort.","A Keresztesek rögtön itt lesznek a kézi fegyvereikért. Ha az utukba állsz, halál fia vagy.",I Templari arriveranno presto qui a prendere i loro nuovi Mauler. Se ti trovano qui sei un uomo morto.,"新しいマウラーズを得たテンプル騎士団が すぐにでもここに来る。長生きしたければ -邪魔をしようと思わない方がいい。",템플러가 곧 새 마울러를 가지러 올 거야. 그들을 방해하면 넌 죽은 목숨이야.,"De Tempeliers zullen hier binnenkort zijn om hun nieuwe maulers op te halen. Als je hen in de weg staat, ben je een dode man.","Tempelridderne kommer snart for å hente sine nye maulere. Kommer du i veien for dem, er du en død mann.","Templariusze będą tu niedługo po swoje nowe maulery. Jeśli wejdziesz im w drogę, będziesz martwy.","Os Templários estarão aqui logo para pegar seus novos desintegradores. Se você se meter no caminho deles, você é um homem morto.",,Templierii vor fi curând aici pentru a ridica schiloditoarele. Dacă le stai în cale ești mort.,"Храмовники скоро придут сюда забрать свои новые истязатели. Если попадёшься им на пути, станешь покойником.",,Tapınakçılar yeni parçalayıcılarını almak için yakında burada olacaklar. Eğer yollarına çıkarsan ölürsün. -Maulers?,TXT_RPLY0_SCRIPT18_D1516_MAULE,〃,,,Trhače?,Maulers?,Vernichter?,,,¿Trituradores?,,Moukarit?,Des broyeurs?,Kézi fegyver?,Mauler?,マウラーズ?,마울러?,Maulers?,Maulere?,Maulery?,Desintegradores?,,Schiloditoare?,Истязатели?,,Parçalayıcılar? -The Templar's favorite weapon.,TXT_RYES0_SCRIPT18_D1516_THETE,〃,,The templar's favourite weapon.,Oblíbená zbraň templářů.,Tempelriddernes yndlingsvåben.,Die Lieblingswaffe der Templer.,,,El arma favorita de los templarios.,,Temppeliherrojen lempiase.,L'arme favorite du templier.,A keresztesek kedvenc fegyvere.,È l'arma preferita dei Templari.,騎士団に人気の兵器だ。,템플러가 제일 좋아하는 무기야.,Het favoriete wapen van de Tempeliers.,Tempelriddernes favorittvåpen.,Ulubiona broń Templariuszy.,A arma favorita dos Templários.,,Arma preferată a Templierilor.,Их любимое оружие.,,Tapınakçıların en sevdiği silah. +邪魔をしようと思わない方がいい。",템플러가 곧 새 마울러를 가지러 올 거야. 그들을 방해하면 넌 죽은 목숨이야.,"De Tempeliers zullen hier binnenkort zijn om hun nieuwe maulers op te halen. Als je hen in de weg staat, ben je een dode man.","Tempelridderne kommer snart for å hente sine nye maulere. Kommer du i veien for dem, er du en død mann.","Templariusze będą tu niedługo po swoje nowe maulery. Jeśli wejdziesz im w drogę, będziesz martwy.","Os Templários estarão aqui logo para pegar seus novos desintegradores. Se você se meter no caminho deles, você é um homem morto.",,Templierii vor fi curând aici pentru a ridica schiloditoarele. Dacă le stai în cale ești mort.,"Храмовники скоро придут сюда забрать свои новые истязатели. Если попадёшься им на пути, станешь покойником.",,Templarna kommer snart att vara här för att hämta sina nya maulers. Om du kommer i deras väg är du en död man.,Tapınakçılar yeni parçalayıcılarını almak için yakında burada olacaklar. Eğer yollarına çıkarsan ölürsün. +Maulers?,TXT_RPLY0_SCRIPT18_D1516_MAULE,〃,,,Trhače?,Maulers?,Vernichter?,,,¿Trituradores?,,Moukarit?,Des broyeurs?,Kézi fegyver?,Mauler?,マウラーズ?,마울러?,Maulers?,Maulere?,Maulery?,Desintegradores?,,Schiloditoare?,Истязатели?,,Maulers?,Parçalayıcılar? +The Templar's favorite weapon.,TXT_RYES0_SCRIPT18_D1516_THETE,〃,,The templar's favourite weapon.,Oblíbená zbraň templářů.,Tempelriddernes yndlingsvåben.,Die Lieblingswaffe der Templer.,,,El arma favorita de los templarios.,,Temppeliherrojen lempiase.,L'arme favorite du templier.,A keresztesek kedvenc fegyvere.,È l'arma preferita dei Templari.,騎士団に人気の兵器だ。,템플러가 제일 좋아하는 무기야.,Het favoriete wapen van de Tempeliers.,Tempelriddernes favorittvåpen.,Ulubiona broń Templariuszy.,A arma favorita dos Templários.,,Arma preferată a Templierilor.,Их любимое оружие.,,Tempelriddarens favoritvapen.,Tapınakçıların en sevdiği silah. They came in earlier. That's what all the security's about. I got a chance to look at them when I locked up. Nobody's supposed to go in or out of there until the rest of the platoon comes to claim their weapons.,TXT_DLG_SCRIPT18_D3032_THEYC,〃,,,"Dorazily už dřív, proto ta ochranka. Měl jsem možnost se na ně podívat, když jsem zamykal. Nikdo nesmí vejít dovnitř ani ven dokud si zbytek čety nepřijde pro zbraně.","De kom ind tidligere. Det er derfor, der er så meget sikkerhed. Jeg fik en chance for at se dem, da jeg låste af. Ingen må gå ind eller ud derfra, før resten af delingen kommer for at hente deres våben.","Die sind heute früh hier eingetroffen. Daher all die Wachen. Ich konnte aber mal einen Blick darauf werfen. Niemand darf da rein, bevor die Waffen an die Truppen verteilt worden sind.",,,Vinieron antes. Para eso toda esta seguridad. Tuve una oportunidad de verlos cuando cerraba. Se supone que nadie puede entrar o salir hasta que el resto del pelotón venga a pedir sus armas.,,"He kävivät aiemmin. Siitä näissä kaikissa turvatoimissa on kyse. Sain mahdollisuuden vilkaista niitä, kun lukitsin paikkoja. Kukaan ei saa kulkea sisään eikä ulos, ennen kuin loput joukkueesta tulee noutamaan aseensa.",Ils sont passés plus tôt. C'est pour ça qu'il y a autant de personnel de sécurité. J'ai eu l'opportunité de les voire quand je suis parti verouiller les accès. Personne n'est sensé entrer ou sortir tant que la section n'a pas fini de récupérer leur armes.,"Most hamarabb jöttek. Emiatt van akkora biztonsági cécó. Jó megnéztem magamnak őket amikor bezártam. Senki nem mehet se ki se be, míg a szakasz be nem megy a fegyvereiért.",Sono arrivati da poco. Ecco perché c'è così tanta sicurezza. Ho avuto l'opportunità di vederli quando sono uscito per bloccare gli accessi. Nessuno dovrebbe entrare o uscire finché il plotone non ha finito di raccogliere le armi.,"以前所属したばかりだ。 彼等は全て警備に周るだろう。 門を閉める時に見る機会があったからな。 残りの小隊が兵器を請求するまで -誰も入れる事はできない。","최신 에너지 무기지. 이 무기를 보호하기 위해서 경비가 아주 삼엄하다고. 다만 시간 날 때 맨눈으로 보기는 했지만. 모든 템플러 분대가 이것들을 집어가기 전까지는 그 누구도 절대로 만질 수도, 볼 수도 없어.",Ze kwamen eerder binnen. Dat is waar de beveiliging over gaat. Ik kreeg de kans om naar ze te kijken toen ik ze opsloot. Niemand wordt verondersteld daar naar binnen of buiten te gaan totdat de rest van het peloton zijn wapens komt halen.,De kom inn tidligere. Det er det all sikkerheten handler om. Jeg fikk en sjanse til å se på dem da jeg låste meg inn. Ingen skal gå inn eller ut før resten av troppen kommer for å hente våpnene sine.,"Przyszły wcześniej. To o to chodzi w tej całej ochronie. Miałem okazję przyjrzeć się im przy zamykaniu. Nikt nie może tam wchodzić ani wychodzić, dopóki reszta plutonu nie przyjdzie po swoją broń.",Eles vieram aqui antes. Por isso toda essa segurança. Tive a oportunidade de dar uma olhada neles quando eu estava fechando. Ninguém pode entrar ou sair até que o resto do pelotão venha pegar suas armas.,,Au venit mai devreme. Asta e treaba cu toată securitatea. Am avut șansa să îi privesc când închideam. Nimeni nu intră sau iese până ce tot platonul vine să își ia armele.,"Его привезли раньше, поэтому здесь столько охраны. Я заглянул в хранилище, когда запирал его. Пока весь отряд храмовников не получит своё оружие, никому не позволено входить или выходить.",,Daha erken geldiler. Bütün güvenlik bunun için. Kapıyı kilitlediğimde onlara bakma şansım oldu. Müfrezenin geri kalanı silahlarını almaya gelene kadar kimsenin oraya girip çıkmaması gerekiyor. -This is where you get the plans for the central administration.,TXT_DLG_SCRIPT19_D0_THISI,"Appears in MAP19 and is supposed to be spoken by the Peasant1 actor (named “Security Comple”). However, no such actor is spawned in the map, rendering this line unused.",,,Tady se nachází plány pro ústřední administraci.,"Det er her, du får planerne for den centrale administration.",Dort bekommst du die Pläne für die Hauptverwaltung.,,,Aquí es donde obtienes los planos de la administración central.,,Täältä saat keskushallinnon piirustukset.,C'est ici que vous pouvez récuperer les plans du centre d'administration.,,Qui è dove prendi i piani per l'amministrazione centrale,,이곳은 중앙 관리소에 전술이나 계획을 보고하기 위한 곳이야.,Hier krijg je de plannen voor de centrale administratie.,Det er her du får planene for sentraladministrasjonen.,To tutaj dostajecie plany dla administracji centralnej.,É aqui onde você pega os planos da administração central.,,De aici vei lua schemele pentru camera de administrare centrală.,Здесь ты добудешь схему центральной администрации.,,Burası merkezi yönetimin planlarını aldığınız yer. +誰も入れる事はできない。","최신 에너지 무기지. 이 무기를 보호하기 위해서 경비가 아주 삼엄하다고. 다만 시간 날 때 맨눈으로 보기는 했지만. 모든 템플러 분대가 이것들을 집어가기 전까지는 그 누구도 절대로 만질 수도, 볼 수도 없어.",Ze kwamen eerder binnen. Dat is waar de beveiliging over gaat. Ik kreeg de kans om naar ze te kijken toen ik ze opsloot. Niemand wordt verondersteld daar naar binnen of buiten te gaan totdat de rest van het peloton zijn wapens komt halen.,De kom inn tidligere. Det er det all sikkerheten handler om. Jeg fikk en sjanse til å se på dem da jeg låste meg inn. Ingen skal gå inn eller ut før resten av troppen kommer for å hente våpnene sine.,"Przyszły wcześniej. To o to chodzi w tej całej ochronie. Miałem okazję przyjrzeć się im przy zamykaniu. Nikt nie może tam wchodzić ani wychodzić, dopóki reszta plutonu nie przyjdzie po swoją broń.",Eles vieram aqui antes. Por isso toda essa segurança. Tive a oportunidade de dar uma olhada neles quando eu estava fechando. Ninguém pode entrar ou sair até que o resto do pelotão venha pegar suas armas.,,Au venit mai devreme. Asta e treaba cu toată securitatea. Am avut șansa să îi privesc când închideam. Nimeni nu intră sau iese până ce tot platonul vine să își ia armele.,"Его привезли раньше, поэтому здесь столько охраны. Я заглянул в хранилище, когда запирал его. Пока весь отряд храмовников не получит своё оружие, никому не позволено входить или выходить.",,De kom in tidigare. Det är det som är orsaken till all säkerhet. Jag fick en chans att titta på dem när jag låste in dem. Ingen får gå in eller ut därifrån förrän resten av plutonen kommer för att hämta sina vapen.,Daha erken geldiler. Bütün güvenlik bunun için. Kapıyı kilitlediğimde onlara bakma şansım oldu. Müfrezenin geri kalanı silahlarını almaya gelene kadar kimsenin oraya girip çıkmaması gerekiyor. +This is where you get the plans for the central administration.,TXT_DLG_SCRIPT19_D0_THISI,"Appears in MAP19 and is supposed to be spoken by the Peasant1 actor (named “Security Comple”). However, no such actor is spawned in the map, rendering this line unused.",,,Tady se nachází plány pro ústřední administraci.,"Det er her, du får planerne for den centrale administration.",Dort bekommst du die Pläne für die Hauptverwaltung.,,,Aquí es donde obtienes los planos de la administración central.,,Täältä saat keskushallinnon piirustukset.,C'est ici que vous pouvez récuperer les plans du centre d'administration.,"Ez az a rész, ahol megszerezheted a terveket a központi irányításhoz.",Qui è dove prendi i piani per l'amministrazione centrale,,이곳은 중앙 관리소에 전술이나 계획을 보고하기 위한 곳이야.,Hier krijg je de plannen voor de centrale administratie.,Det er her du får planene for sentraladministrasjonen.,To tutaj dostajecie plany dla administracji centralnej.,É aqui onde você pega os planos da administração central.,,De aici vei lua schemele pentru camera de administrare centrală.,Здесь ты добудешь схему центральной администрации.,,Det är här du får planerna för den centrala administrationen.,Burası merkezi yönetimin planlarını aldığınız yer. "I run this place. My job is to build the raw parts needed for the Loremaster's robot designs. If you're not here on official business, then I'm afraid I don't have time to talk.",TXT_DLG_SCRIPT22_D0_IRUNT,,,,"Já jsem ten, kdo to tu řídí. Mým úkolem je konstruovat části pro Dějepiscovy návrhy robotů. Jestli tu nejsi kvůli oficiálním záležitostem, pak se obávám, že nemám čas s tebou mluvit.","Jeg styrer stedet her. Mit job er at bygge de rådele, der er nødvendige for Loremesterens robotdesigns. Hvis du ikke er her i officielt ærinde, så har jeg desværre ikke tid til at tale.","Ich leite dieses Unternehmen. Meine Aufgabe ist es, die Teile für die neuen Roboterdesigns des Wissensmeisters zu konstruieren. Wenn du hier nicht dienstlich hier bist, habe ich keine Zeit für dich.",,,"Yo manejo este sitio. Mi trabajo es contruir las partes necesarias para los diseños de robot del Maestro del Conocimiento. Si no estás aquí por asuntos oficiales, entonces me temo que no tengo tiempo para hablar.",,"Minä vedän tätä paikkaa. Työni on valmistaa osat, joita tarvitaan Oppi-Isän robottikehitelmiin. Jos et ole täällä virallisilla asioilla, sitten minulla valitettavasti ei ole aikaa puhua.","Je suis le chef de cet endroit. Mon travail est de faire fabriquer les pièces brutes utilisées pour les robots du Maître des traditions. Si vous n'êtes pas ici en visite officielle, je n'ai pas le temps de vous parler.","Én vezetem ezt a kócerájt. Az én feladatom, hogy a Tanmester robotjának alkatrészeit összerakjam. Ha nem hivatalos ügyben jöttél, akkor sajnos nincs időm rád.","Sono io a gestire questo posto. Il mio lavoro è costruire i materiali necessari per i progetti dei robot del Sapiente. A meno che tu non sia qua per discutere affari, mi spiace ma non ho tempo per parlare.","私がこの場所の主任者だ。 私の仕事は、ロアマスターのロボットの デザインに必要な原料パーツを生産することだ。 もしあなたが公用で来たのではないのなら、 -申し訳ないが話すための時間はないのだ。","난 이곳의 책임자야. 로어마스터님의 로봇 설계를 돕기 위해 일하고 있지. 만약 공식 업무 외에 온 거라면, 바쁘니까 돌아가 줘야 되겠는걸?","Ik run deze plek. Mijn taak is om de ruwe onderdelen te bouwen die nodig zijn voor de robotontwerpen van de Kennismeester. Als je hier niet bent voor officiële zaken, dan ben ik bang dat ik geen tijd heb om te praten.","Jeg driver dette stedet. Min jobb er å bygge rådelene som trengs til Loremesterens robotdesign. Hvis du ikke er her i offisielt ærend, har jeg ikke tid til å snakke.","Ja prowadzę to miejsce. Moim zadaniem jest budowanie części potrzebnych do projektów robotów Loremastera. Jeśli nie jesteś tu w oficjalnej sprawie, to obawiam się, że nie mam czasu na rozmowę.","Eu sou o chefe daqui deste lugar. Meu trabalho é construir as peças necessárias para os robôs do Mestre do Conhecimento. Se você não está aqui para assuntos oficiais, então receio que não temos tempo para conversa.",,"Eu conduc locul ăsta. Treaba mea e să produc materia primă pentru designul roboților Stăpânului Cunoștiințelor. Dacă nu ești aici cu treabă oficială, atunci nu am timp de vorbă.","Я здесь главный. Моя работа — изготавливать детали роботов для Хранителя мудрости. Если ты здесь не по служебным делам, то, боюсь, мне некогда с тобой болтать.",,"Burayı ben yönetiyorum. Benim işim Loremaster'ın robot tasarımları için gereken ham parçaları üretmek. Eğer resmi bir iş için burada değilseniz, korkarım ki konuşacak vaktim yok." -I am on official business.,TXT_RPLY0_SCRIPT22_D0_IAMON,,,,Jsem tu kvůli oficiálním záležitostem.,Jeg er i officielt ærinde.,Ich bin dienstlich hier.,,,Estoy por asuntos oficiales.,,Olen virallisilla asioilla.,Je suis en visite officielle.,Hivatalos ügyben jöttem.,Sono qua per discutere affari.,私は公用で来た。,공식 업무로 왔어.,Ik ben voor officiële zaken.,Jeg er her i offisielt ærend.,Jestem w oficjalnej sprawie.,Estou aqui para tratar de assuntos oficiais.,,Sunt cu treburi oficiale.,Я по служебным делам.,,Resmi bir iş için buradayım. +申し訳ないが話すための時間はないのだ。","난 이곳의 책임자야. 로어마스터님의 로봇 설계를 돕기 위해 일하고 있지. 만약 공식 업무 외에 온 거라면, 바쁘니까 돌아가 줘야 되겠는걸?","Ik run deze plek. Mijn taak is om de ruwe onderdelen te bouwen die nodig zijn voor de robotontwerpen van de Kennismeester. Als je hier niet bent voor officiële zaken, dan ben ik bang dat ik geen tijd heb om te praten.","Jeg driver dette stedet. Min jobb er å bygge rådelene som trengs til Loremesterens robotdesign. Hvis du ikke er her i offisielt ærend, har jeg ikke tid til å snakke.","Ja prowadzę to miejsce. Moim zadaniem jest budowanie części potrzebnych do projektów robotów Loremastera. Jeśli nie jesteś tu w oficjalnej sprawie, to obawiam się, że nie mam czasu na rozmowę.","Eu sou o chefe daqui deste lugar. Meu trabalho é construir as peças necessárias para os robôs do Mestre do Conhecimento. Se você não está aqui para assuntos oficiais, então receio que não temos tempo para conversa.",,"Eu conduc locul ăsta. Treaba mea e să produc materia primă pentru designul roboților Stăpânului Cunoștiințelor. Dacă nu ești aici cu treabă oficială, atunci nu am timp de vorbă.","Я здесь главный. Моя работа — изготавливать детали роботов для Хранителя мудрости. Если ты здесь не по служебным делам, то, боюсь, мне некогда с тобой болтать.",,Jag styr det här stället. Mitt jobb är att bygga de rådelar som behövs för Läromästarens robotkonstruktioner. Om du inte är här i officiellt ärende har jag tyvärr inte tid att prata.,"Burayı ben yönetiyorum. Benim işim Loremaster'ın robot tasarımları için gereken ham parçaları üretmek. Eğer resmi bir iş için burada değilseniz, korkarım ki konuşacak vaktim yok." +I am on official business.,TXT_RPLY0_SCRIPT22_D0_IAMON,,,,Jsem tu kvůli oficiálním záležitostem.,Jeg er i officielt ærinde.,Ich bin dienstlich hier.,,,Estoy por asuntos oficiales.,,Olen virallisilla asioilla.,Je suis en visite officielle.,Hivatalos ügyben jöttem.,Sono qua per discutere affari.,私は公用で来た。,공식 업무로 왔어.,Ik ben voor officiële zaken.,Jeg er her i offisielt ærend.,Jestem w oficjalnej sprawie.,Estou aqui para tratar de assuntos oficiais.,,Sunt cu treburi oficiale.,Я по служебным делам.,,Jag är i officiellt ärende.,Resmi bir iş için buradayım. "So you've spoken with Timothy, I see. He and I have worked together to try to unravel the mysteries of the Order, before it's too late for us all. Maybe you can help us. I've opened the door to the production sector.",TXT_DLG_SCRIPT22_D1516_SOYOU,,,,"Vidím, že sis promluvil s Timothym. Pracovali jsme spolu na odkrytí tajemství Řádu, dřív, než pro nás bude pozdě. Možná nám můžeš pomoct. Otevřel jsem dveře do výrobního sektoru.","Så du har talt med Timothy, kan jeg se. Han og jeg har arbejdet sammen for at forsøge at løse ordenens mysterier, før det er for sent for os alle. Måske kan du hjælpe os. Jeg har åbnet døren til produktionssektoren.","Du hast mit Timothy gesprochen, ich verstehe. Er und ich haben zusammengearbeitet und versucht die Mysterien des Ordens ergründen, bevor es für uns alle zu spät ist. Vielleicht kannst du uns helfen. Ich habe die Tür zum Produktionsektor geöffnet.",,,"Así que has ablado con Timothy, ya veo. Él y yo hemos trabajado juntos para intentar desenredar los misterios de la Orden, antes de que sea demasiado tarde para todos nosotros. Tal vez puedas ayudarnos. He abierto la puerta al sector de producción.",,"Olet siis näköjään puhunut Timothyn kanssa. Olemme yhteistyössä koettaneet ratkoa Veljeskunnan saloja, ennen kuin on liian myöhäistä meidän kaikkien kannalta. Ehkä voit auttaa meitä. Avasin oven tuotantolaitokselle.",Je vois que vous avez parlé à Timothy. Nous avons travaillé ensemble pour dénouer les mystères de l'Ordre avant qu'il soit trop tard. Peut être que vous pouvez nous aider. J'ai ouvert l'accès vers le secteur de production.,"Úgy látom már beszéltél Timothyval. Ő és Én már korábban is próbáltuk felderíteni a Rend rejtélyét, mielőtt még mindannyiunknak túl késő nem lesz. Talán tudsz segíteni. Kinyitottam az ajtót a gyártó részleghez.",Vedo che hai parlato con Timothy. Io e lui abbiamo lavorato insieme per cercare di svelare i misteri dell'Ordine prima che sia troppo tardi per tutti noi. Forse ci puoi aiutare. Ho aperto la porta che conduce al settore di produzione.,"ということは、ティモシーと話したのだな。 彼と私は、取り返しのつかない事態に陥る前に オーダーの秘密を解き明かすために 一緒に働いてきた。もしかすると、 君は私達に手を貸せるかもしれない。 -私は今、生産セクターへの扉を開いたぞ。","티모시와 이야기를 나눴구나, 그렇지? 티모시랑 같이 한발 늦기 전에 오더의 비밀을 파헤치려고 열심히 노력했지. 아마도 우리들을 도와줄 수 있을 것 같은데 말이야. 방금 제조 공간의 문을 열어놨어.","Dus je hebt met Timothy gesproken, zie ik. Hij en ik hebben samengewerkt om te proberen de mysteries van de Orde te ontrafelen, voordat het voor ons allemaal te laat is. Misschien kunt u ons helpen. Ik heb de deur geopend naar de productiesector.","Så du har snakket med Timothy, ser jeg. Han og jeg har jobbet sammen for å løse Ordenens mysterier før det er for sent for oss alle. Kanskje du kan hjelpe oss. Jeg har åpnet døren til produksjonssektoren.","Widzę, że rozmawiałaś z Timothym. Razem z nim próbujemy rozwikłać tajemnice Zakonu, zanim będzie za późno dla nas wszystkich. Może ty możesz nam pomóc. Otworzyłem drzwi do sektora produkcyjnego.","Então você andou falando com o Timothy, pelo visto. Eu e ele trabalhamos juntos para tentar desvendar os mistérios da Ordem antes que seja tarde para todos nós. Talvez você possa nos ajudar. Eu abri a porta para o setor de produção.",,"Ai vorbit cu Timotei, să înțeleg. Noi am lucrat împreună în încercarea de a descoperii misterele Ordinului, înainte să fie prea târziu pentru noi toți. Poate ne poți ajuta. Am deschis ușa la sectorul de producție.","Итак, ты уже поговорил с Тимоти. Мы с ним вместе пытаемся раскрыть тайны Ордена, пока не стало слишком поздно. Возможно, ты сможешь нам помочь. Я открыл дверь в производственный сектор.",,"Gördüğüm kadarıyla Timothy ile konuşmuşsunuz. O ve ben, hepimiz için çok geç olmadan Tarikat'ın gizemlerini çözmeye çalışmak için birlikte çalıştık. Belki bize yardım edebilirsin. Üretim sektörünün kapısını açtım." -Do you know what's inside?,TXT_RPLY0_SCRIPT22_D1516_DOYOU,,,,"Víš, co je uvnitř?","Ved du, hvad der er indenfor?",Weißt du was da drin ist?,,,¿Sabes que hay adentro?,,"Tiedätkö, mitä sisällä on?",Vous savez ce qu'il y à dedans?,Tudod mi van bent?,Che cosa c'è oltre la porta?,中に何があるのかを知っているのか?,그 안에 무엇이 있는지 아나?,Weet je wat er in zit?,Vet du hva som er der inne?,"Wiesz, co jest w środku?",Você sabe o que tem lá dentro?,,Știi cumva ce e înăuntru?,"Ты знаешь, что там?",,İçeride ne olduğunu biliyor musun? +私は今、生産セクターへの扉を開いたぞ。","티모시와 이야기를 나눴구나, 그렇지? 티모시랑 같이 한발 늦기 전에 오더의 비밀을 파헤치려고 열심히 노력했지. 아마도 우리들을 도와줄 수 있을 것 같은데 말이야. 방금 제조 공간의 문을 열어놨어.","Dus je hebt met Timothy gesproken, zie ik. Hij en ik hebben samengewerkt om te proberen de mysteries van de Orde te ontrafelen, voordat het voor ons allemaal te laat is. Misschien kunt u ons helpen. Ik heb de deur geopend naar de productiesector.","Så du har snakket med Timothy, ser jeg. Han og jeg har jobbet sammen for å løse Ordenens mysterier før det er for sent for oss alle. Kanskje du kan hjelpe oss. Jeg har åpnet døren til produksjonssektoren.","Widzę, że rozmawiałaś z Timothym. Razem z nim próbujemy rozwikłać tajemnice Zakonu, zanim będzie za późno dla nas wszystkich. Może ty możesz nam pomóc. Otworzyłem drzwi do sektora produkcyjnego.","Então você andou falando com o Timothy, pelo visto. Eu e ele trabalhamos juntos para tentar desvendar os mistérios da Ordem antes que seja tarde para todos nós. Talvez você possa nos ajudar. Eu abri a porta para o setor de produção.",,"Ai vorbit cu Timotei, să înțeleg. Noi am lucrat împreună în încercarea de a descoperii misterele Ordinului, înainte să fie prea târziu pentru noi toți. Poate ne poți ajuta. Am deschis ușa la sectorul de producție.","Итак, ты уже поговорил с Тимоти. Мы с ним вместе пытаемся раскрыть тайны Ордена, пока не стало слишком поздно. Возможно, ты сможешь нам помочь. Я открыл дверь в производственный сектор.",,"Så du har talat med Timothy, ser jag. Han och jag har arbetat tillsammans för att försöka lösa Ordens mysterier innan det är för sent för oss alla. Du kanske kan hjälpa oss. Jag har öppnat dörren till produktionssektorn.","Gördüğüm kadarıyla Timothy ile konuşmuşsunuz. O ve ben, hepimiz için çok geç olmadan Tarikat'ın gizemlerini çözmeye çalışmak için birlikte çalıştık. Belki bize yardım edebilirsin. Üretim sektörünün kapısını açtım." +Do you know what's inside?,TXT_RPLY0_SCRIPT22_D1516_DOYOU,,,,"Víš, co je uvnitř?","Ved du, hvad der er indenfor?",Weißt du was da drin ist?,,,¿Sabes que hay adentro?,,"Tiedätkö, mitä sisällä on?",Vous savez ce qu'il y à dedans?,Tudod mi van bent?,Che cosa c'è oltre la porta?,中に何があるのかを知っているのか?,그 안에 무엇이 있는지 아나?,Weet je wat er in zit?,Vet du hva som er der inne?,"Wiesz, co jest w środku?",Você sabe o que tem lá dentro?,,Știi cumva ce e înăuntru?,"Ты знаешь, что там?",,Vet du vad som finns där inne?,İçeride ne olduğunu biliyor musun? "It's a top secret area. Not only is the Order breeding some kind of... creature in there, I've seen with my own eyes a strange artifact called a Talisman. nobody's allowed near it. Rumor is that it holds great power if united with two others of its kind.",TXT_DLG_SCRIPT22_D3032_ITSAT,,,,"Je to přísně tajná oblast. Nejenže se tam Řád snaží zplodit nějakou... příšeru, ale na vlastní oči jsem tam viděl zvláštní artefakt jménem Talisman. Nikdo k němu nesmí. Říká se, že skrývá nesmírnou moc pokud se spojí s dalšími dvěma svého druhu.","Det er et tophemmeligt område. Ikke alene avler Ordenen en slags... væsen derinde, jeg har også set med mine egne øjne en mærkelig artefakt kaldet en Talisman. Ingen må komme i nærheden af den. Rygterne siger, at den har stor magt, hvis den forenes med to andre af sin slags.","Das ist alles streng geheim. Dort wird nicht nur irgendeine Art von... Kreatur vom Orden gezüchtet, sondern es gibt dort auch ein merkwürdiges Artefakt, ein Talisman. Keiner darf in auch nur in die Nähe davon. Gerüchten zufolge erhält man große Macht, wenn man es mit zwei anderen vereint.",,,"Es un área de alto secreto. No solo está la Orden criando una especie de... Criatura ahí, he visto con mis propios ojos un extraño artefacto llamado Talismán. No se permite a nadie acercarse a él. Se rumorea que posee un gran poder si se reune con otros dos de su tipo.",,"Se on huippusalainen alue. Vielä sen lisäksi, että Veljeskunta on luomassa siellä jonkinlaista... oliota, olen omin silmin nähnyt oudon esineen, jota kutsutaan Talismaaniksi. Ketään ei sallita sen lähelle. Huhutaan, että sen sisällä piilee suuri voima, jos sen yhdistää kahden toisen sen kaltaisen kanssa.",C'est une zone top secrète. L'Ordre essaie de.. faire une sorte de créature là dedans. J'ai vu avec mes yeux un artéfact étrange qu'ils appellent un Talisman. Personne n'a le droit de l'approcher. Les rumeurs disent qu'il contient un pouvoir phénoménal si il est réuni avec deux autres du même type.,"Egy totál titkos terület. Nem elég hogy valamiféle...lényeket tenyésztenek odabent, láttam valamiféle leletet is, amit Talizmán néven emlegettek. Senkit se engednek a közelébe. A legenda szerint hatalmas erő birtokosa lehet, aki egyesíti még két másik darabbal.","È un'area a cui quasi nessuno è permesso entrare. L'Ordine non solo sta crescendo una specie di... creatura là dentro, ma inoltre ho anche visto uno strano artefatto che chiamano Talismano. Nessuno ci si può avvicinare. Dicono che se unito a due altri talismani, sprigioni un enorme potere.","あの場所は極秘エリアだ。 オーダーはある種の生物のようなものを そこで繁殖させているし、それだけではなく @@ -11098,455 +11580,455 @@ Do you know what's inside?,TXT_RPLY0_SCRIPT22_D1516_DOYOU,,,,"Víš, co je uvnit アーティファクトをこの目で見た。 誰もそれには近づくことが許されていないのだ。 噂では、タリスマンはほかの2つのタリスマンと -つながることで強大なパワーを発揮できるらしい。",아주 중요한 기밀 공간이야. 난 오더가 거기에서 각종... 생물들을 만드는 거랑 부적이라는 희한한 유물을 보호하는 모습을 봤지. 그런 이유로 그 누구도 못 들어가. 그리고 이와 똑같은 다른 유물을 합치면 초월한 힘을 발휘한다는 소문도 들었어.,"Het is een topgeheim gebied. Niet alleen is de Orde daar een soort.... schepsel aan het kweken, ik heb met mijn eigen ogen een vreemd artefact gezien dat een Talisman wordt genoemd. niemand mag er in de buurt komen. Het gerucht gaat dat hij grote macht heeft als hij zich verenigt met twee anderen van zijn soort.","Det er et topphemmelig område. Ikke bare avler Ordenen en slags... skapning der inne, jeg har selv sett en merkelig gjenstand kalt en Talisman. Ingen får komme nær den. Ryktene sier at den har stor makt hvis den forenes med to andre av sitt slag.","To ściśle tajny obszar. Nie dość, że Zakon hoduje tam jakieś... stworzenia, to na własne oczy widziałem dziwny artefakt zwany Talizmanem. nikomu nie wolno się do niego zbliżać. Plotka głosi, że posiada on wielką moc, jeśli połączy się go z dwoma innymi tego rodzaju.","É uma área ultrassecreta. Não só a Ordem está criando um tipo de...criatura lá dentro, eu vi com meus próprios olhos um artefato estranho chamado de Talismã. Ninguém tem permissão para chegar perto. Dizem que ele tem um grande poder ao se unir com outros dois do mesmo tipo.",,"E o zonă secretă. Nu numai că Ordinul crește un fel de... creatură acolo, am văzut cu proprii mei ochi un fel de artefact numit Talisman, nimeni nu e lăsat să se apropie.. Zvonurile zic că e un artefact de o putere imensă dacă e unit cu celelalte două părți ale lui.","Это совершенно секретно. Во-первых, Орден разводит там каких-то... существ. Во-вторых, я своими глазами видел странный артефакт — «Талисман». К нему никого и близко не подпускают. Говорят, если объединить его с двумя другими, можно получить огромную силу.",,"Çok gizli bir bölge. Tarikat orada bir tür yaratık yetiştirmekle kalmıyor, Tılsım denen garip bir eseri kendi gözlerimle gördüm. Kimsenin ona yaklaşmasına izin verilmiyor. Söylentiye göre türünün diğer iki örneğiyle birleştiğinde büyük bir güce sahip oluyormuş." -I suppose you want this thing?,TXT_RPLY0_SCRIPT22_D3032_ISUPP,,,,"Předpokládám, že jej chceš?","Jeg formoder, at du vil have denne tingest?","Ich denke mal, du willst dieses Ding haben?",,,¿Supongo que quieres esto?,,Sinä varmaankin haluat tämän esineen?,Je suppose que vous le voulez?,Gondolom kell neked az a tárgy.,Immagino tu voglia questo?,それが欲しいということか?,내 생각엔 그걸 원하나 보지?,Ik neem aan dat je dit ding wilt?,Jeg antar at du vil ha den?,"Przypuszczam, że chcesz tego czegoś?",Imagino que você quer essa coisa?,,Presupun că vrei chestia asta?,"Похоже, ты и сам хочешь этот артефакт?",,Sanırım bu şeyi istiyorsun? +つながることで強大なパワーを発揮できるらしい。",아주 중요한 기밀 공간이야. 난 오더가 거기에서 각종... 생물들을 만드는 거랑 부적이라는 희한한 유물을 보호하는 모습을 봤지. 그런 이유로 그 누구도 못 들어가. 그리고 이와 똑같은 다른 유물을 합치면 초월한 힘을 발휘한다는 소문도 들었어.,"Het is een topgeheim gebied. Niet alleen is de Orde daar een soort.... schepsel aan het kweken, ik heb met mijn eigen ogen een vreemd artefact gezien dat een Talisman wordt genoemd. niemand mag er in de buurt komen. Het gerucht gaat dat hij grote macht heeft als hij zich verenigt met twee anderen van zijn soort.","Det er et topphemmelig område. Ikke bare avler Ordenen en slags... skapning der inne, jeg har selv sett en merkelig gjenstand kalt en Talisman. Ingen får komme nær den. Ryktene sier at den har stor makt hvis den forenes med to andre av sitt slag.","To ściśle tajny obszar. Nie dość, że Zakon hoduje tam jakieś... stworzenia, to na własne oczy widziałem dziwny artefakt zwany Talizmanem. nikomu nie wolno się do niego zbliżać. Plotka głosi, że posiada on wielką moc, jeśli połączy się go z dwoma innymi tego rodzaju.","É uma área ultrassecreta. Não só a Ordem está criando um tipo de...criatura lá dentro, eu vi com meus próprios olhos um artefato estranho chamado de Talismã. Ninguém tem permissão para chegar perto. Dizem que ele tem um grande poder ao se unir com outros dois do mesmo tipo.",,"E o zonă secretă. Nu numai că Ordinul crește un fel de... creatură acolo, am văzut cu proprii mei ochi un fel de artefact numit Talisman, nimeni nu e lăsat să se apropie.. Zvonurile zic că e un artefact de o putere imensă dacă e unit cu celelalte două părți ale lui.","Это совершенно секретно. Во-первых, Орден разводит там каких-то... существ. Во-вторых, я своими глазами видел странный артефакт — «Талисман». К нему никого и близко не подпускают. Говорят, если объединить его с двумя другими, можно получить огромную силу.",,"Det är ett topphemligt område. Inte nog med att Orden föder upp någon sorts... varelse där inne, jag har med egna ögon sett en märklig artefakt som kallas för en Talisman. Ingen får komma i närheten av den. Ryktet säger att den har stor kraft om den förenas med två andra av samma slag.","Çok gizli bir bölge. Tarikat orada bir tür yaratık yetiştirmekle kalmıyor, Tılsım denen garip bir eseri kendi gözlerimle gördüm. Kimsenin ona yaklaşmasına izin verilmiyor. Söylentiye göre türünün diğer iki örneğiyle birleştiğinde büyük bir güce sahip oluyormuş." +I suppose you want this thing?,TXT_RPLY0_SCRIPT22_D3032_ISUPP,,,,"Předpokládám, že jej chceš?","Jeg formoder, at du vil have denne tingest?","Ich denke mal, du willst dieses Ding haben?",,,¿Supongo que quieres esto?,,Sinä varmaankin haluat tämän esineen?,Je suppose que vous le voulez?,Gondolom kell neked az a tárgy.,Immagino tu voglia questo?,それが欲しいということか?,내 생각엔 그걸 원하나 보지?,Ik neem aan dat je dit ding wilt?,Jeg antar at du vil ha den?,"Przypuszczam, że chcesz tego czegoś?",Imagino que você quer essa coisa?,,Presupun că vrei chestia asta?,"Похоже, ты и сам хочешь этот артефакт?",,Jag antar att du vill ha den här?,Sanırım bu şeyi istiyorsun? "No! If you can find it, it's yours to keep. Maybe you can use it to help free us from our oppression. I'd wish you luck, but you're going to need a lot more than that if you go in there...",TXT_DLG_SCRIPT22_D4548_NOIFY,,,,"Ne! Jestli ho najdeš, je tvůj. Možná by ti mohl pomoct osvobodit nás od nadvlády. Přál bych ti štěstí, ale jestli tam půjdeš, budeš potřebovat mnohem víc než to...","Nej! Hvis du kan finde den, kan du beholde den. Måske kan du bruge den til at hjælpe os med at befri os fra vores undertrykkelse. Jeg ville ønske dig held og lykke, men du får brug for meget mere end det, hvis du går derind...","Nein! Wenn du es findest, darfst du es behalten. Vielleicht kannst du es benutzen, um uns von unserer Unterdrückung zu befreien. Ich würde dir Glück wünschen, aber du wirst viel mehr brauchen, wenn du dort hinein gehst.",,,"¡No! Si lo encuentras, quédatelo. Tal vez puedas usarlo para ayudar a librarnos de nuestra opresión. Te desearía suerte, pero vas a necesitar más que eso si vas ahí...",,"Ei! Jos löydät sen, saat pitää omanasi. Voit ehkä käyttää sitä auttaaksesi vapauttamaan meidät sorrostamme. Toivottaisin sinulle onnea, mutta tarvitset paljon enemmän kuin sitä, jos menet sinne.","Non! Si vous le trouvez, gardez le pour vous. Peut être qu'il vous aidera à nous débarasser de nos oppresseurs.. Je vous souhaiterais bonne chance, mais vous allez avoir besoin de beaucoup plus que ça si vous y entrez..","Dehogyis! Ha megleled, a tied lehet. Talán fel tudod használni annak érdekében, hogy felszabadíts minket az elnyomás alól. Szerencsét kívánnék, de annál sokkal többre lesz szükséged odabent...","No! Se lo trovi, te lo puoi tenere. Forse lo puoi utilizzare per liberarci dalla nostra oppressione. Ti augurerei buona fortuna, ma ti servirebbe molto più che fortuna se vai là dentro...","そうではない!もし見つけたら それは自分のものにしてくれ。もしかすれば、 それを私達をオーダーから解放するために 使えるかもしれない。幸運を祈ってはいるが、 もしあの場所に行こうとしているなら、 -もっと多くの力が必要となるぞ...","아니야! 만약 네가 가질 수만 있다면, 그건 네 거야. 아마도 우리들을 탄압으로부터 구해줄 수 있겠네. 부디 행운을 빌어. 왜냐하면 많은 걸 준비 한 뒤 각오하고 들어가야 하거든.","Nee, als je het kunt vinden, is het aan jou om het te houden. Misschien kunt je het gebruiken om ons te bevrijden van onze onderdrukking. Ik zou je veel geluk wensen, maar je zult veel meer nodig hebben als je daar naar binnen gaat....","Nei! Hvis du finner den, kan du beholde den. Kanskje du kan bruke den til å frigjøre oss fra undertrykkelsen. Jeg skulle ønske deg lykke til, men du trenger mer enn det hvis du går inn dit...","Nie! Jeśli go znajdziesz, zatrzymasz go dla siebie. Może użyjesz jej, by pomóc nam uwolnić się od ucisku. Życzyłbym ci szczęścia, ale będziesz potrzebował o wiele więcej, jeśli tam wejdziesz...","Não! Se você conseguir achá-lo, fique com ele. Talvez você possa usá-lo para nos libertar dessa opressão. Eu te desejaria sorte, mas você vai precisar de muito mais do que isso se você entrar lá dentro...",,"Nu! Dacă o găsești, e a ta. Poate o poți folosi ca să ne ajuți să scăpăm de oprimare. Ți-aș ura noroc, dar o să ai noroc de mult mai mult decât atât dacă mergi acolo...","Нет! Если ты его найдёшь, он твой. Может быть, он поможет тебе освободить нас от гнёта. Я бы пожелал тебе удачи, но, если ты пойдёшь туда, простой удачи будет недостаточно...",,"Hayır! Eğer onu bulabilirsen, sende kalabilir. Belki onu bizi zulmümüzden kurtarmak için kullanabilirsin. Sana şans dilerdim, ama oraya girersen bundan çok daha fazlasına ihtiyacın olacak..." -What's all this about the past?,TXT_RPLY0_SCRIPT22_D4548_WHATS,,,,Cos to říkal o minulosti?,Hvad er alt det her med fortiden?,Was ist dieses ganze Gerede über die Vergangenheit?,,,¿Qué es todo esto sobre el pasado?,,Mistä tässä kaikessa menneessä oikein on kyse?,Qu'est-ce que j'entends au sujet du passé?,És mi köze ennek a múlthoz?,E che mi dici riguardo a tutte ste storie del passato?,過去に何があったというんだ?,그 과거에 대해서 뭐가 어떻길레?,Wat is dit alles over het verleden?,Hva er alt dette om fortiden?,O co chodzi z tą przeszłością?,Que história é essa sobre o passado?,,Care e treaba cu trecutul ăsta?,Что такого творилось здесь в прошлом?,,Geçmişle ilgili tüm bu şeyler de ne? +もっと多くの力が必要となるぞ...","아니야! 만약 네가 가질 수만 있다면, 그건 네 거야. 아마도 우리들을 탄압으로부터 구해줄 수 있겠네. 부디 행운을 빌어. 왜냐하면 많은 걸 준비 한 뒤 각오하고 들어가야 하거든.","Nee, als je het kunt vinden, is het aan jou om het te houden. Misschien kunt je het gebruiken om ons te bevrijden van onze onderdrukking. Ik zou je veel geluk wensen, maar je zult veel meer nodig hebben als je daar naar binnen gaat....","Nei! Hvis du finner den, kan du beholde den. Kanskje du kan bruke den til å frigjøre oss fra undertrykkelsen. Jeg skulle ønske deg lykke til, men du trenger mer enn det hvis du går inn dit...","Nie! Jeśli go znajdziesz, zatrzymasz go dla siebie. Może użyjesz jej, by pomóc nam uwolnić się od ucisku. Życzyłbym ci szczęścia, ale będziesz potrzebował o wiele więcej, jeśli tam wejdziesz...","Não! Se você conseguir achá-lo, fique com ele. Talvez você possa usá-lo para nos libertar dessa opressão. Eu te desejaria sorte, mas você vai precisar de muito mais do que isso se você entrar lá dentro...",,"Nu! Dacă o găsești, e a ta. Poate o poți folosi ca să ne ajuți să scăpăm de oprimare. Ți-aș ura noroc, dar o să ai noroc de mult mai mult decât atât dacă mergi acolo...","Нет! Если ты его найдёшь, он твой. Может быть, он поможет тебе освободить нас от гнёта. Я бы пожелал тебе удачи, но, если ты пойдёшь туда, простой удачи будет недостаточно...",,"Nej! Om du kan hitta den, får du behålla den. Du kanske kan använda den för att befria oss från vårt förtryck. Jag skulle önska dig lycka till, men du kommer att behöva mycket mer än så om du går in där...","Hayır! Eğer onu bulabilirsen, sende kalabilir. Belki onu bizi zulmümüzden kurtarmak için kullanabilirsin. Sana şans dilerdim, ama oraya girersen bundan çok daha fazlasına ihtiyacın olacak..." +What's all this about the past?,TXT_RPLY0_SCRIPT22_D4548_WHATS,,,,Cos to říkal o minulosti?,Hvad er alt det her med fortiden?,Was ist dieses ganze Gerede über die Vergangenheit?,,,¿Qué es todo esto sobre el pasado?,,Mistä tässä kaikessa menneessä oikein on kyse?,Qu'est-ce que j'entends au sujet du passé?,És mi köze ennek a múlthoz?,E che mi dici riguardo a tutte ste storie del passato?,過去に何があったというんだ?,그 과거에 대해서 뭐가 어떻길레?,Wat is dit alles over het verleden?,Hva er alt dette om fortiden?,O co chodzi z tą przeszłością?,Que história é essa sobre o passado?,,Care e treaba cu trecutul ăsta?,Что такого творилось здесь в прошлом?,,Vad är allt det här om det förflutna?,Geçmişle ilgili tüm bu şeyler de ne? "You've surely seen the other ruins nearby. It seems that the Comet which crashed on our planet is actually a space ship, and believe it or not, it originated on this very world a long time ago.",TXT_DLG_SCRIPT22_D6064_YOUVE,,,,"Určitě jsi zahlédnul ty zříceniny tady v okolí. Zdá se, že ta kometa, která narazila do naší planety, je ve skutečnosti vesmírná loď, která, věř nebo ne, kdysi dávno pocházela z tohoto světa.","Du har sikkert set de andre ruiner i nærheden. Det ser ud til, at den komet, der styrtede ned på vores planet, faktisk er et rumskib, og tro det eller ej, men det stammer fra denne verden for længe siden.","Du hast doch sicherlich die Ruinen hier in der Nähe gesehen. Es scheint als wäre der Komet, der hier auf dem Planeten aufgeschlagen ist, eigentlich ein Raumschiff, und ob du es glaubst oder nicht, aber es kam vor langer Zeit sogar von dieser Welt.",,,"Seguramente has visto las otras ruinas cercanas. Al parecer el cometa que se estrelló sobre nuestro planeta es en realidad una nave espacial, y lo creas o no, es originaria de este mundo hace mucho tiempo.",,"Olet varmastikin nähnyt lähistön muut rauniot. Vaikuttaa siltä, että komeetta, joka törmäsi planeettaamme, on oikeasti avaruusalus; ja usko tai älä, se on alkuaan peräisin tästä samaisesta maailmasta kauan sitten.","Vous avez sans doute vu toutes ces ruines aux alentours. Il semble que la comète qui s'est écrasée sur notre planète était en fait un vaisseau spatial, et.. du moins si vous y croyez, venait aussi de notre planète, il y a très, très longtemps.","Bizonyára láttad a többi romot is. Úgy néz ki, a lehulló üstökös valójában egy űrhajó volt, és hiszed vagy sem, eredetileg erről a bolygóról indult sok évvel ezelőtt.","Sicuramente avrai visto le rovine qua vicino. Sembra che la cometa dell'impatto verso il nostro pianeta fosse in realtà una navicella spaziale, e so che può sembrare incredibile, ma nave è originaria di questo mondo, di molto tempo fa.","君はこの周りの廃墟群を見てきたはずだ。 この星に衝突した彗星は、実は宇宙船だったのだ 信じられないかもしれないが、 -それは遥か前のこの乱世の始まりとも言える。","주변을 돌아다니면서 각종 폐허를 봤을 거야. 믿기지는 않겠지만, 하늘에서 갑자기 추락한 혜성은 정말로 혜성이 아니라 외계인들이 타고 내려온 우주선이라는 거야. 그리고 더 놀라운 사실은, 이 녀석들은 다 이곳에서 태어났데.","Je hebt zeker de andere ruïnes in de buurt gezien. Het lijkt erop dat de komeet die op onze planeet is neergestort, eigenlijk een ruimteschip is, en geloof het of niet, het is al lang geleden op deze wereld ontstaan.","Du har sikkert sett de andre ruinene i nærheten. Det ser ut til at kometen som krasjet på planeten vår faktisk er et romskip, og tro det eller ei, det kom fra denne verdenen for lenge siden.","Na pewno widziałeś inne ruiny w pobliżu. Wygląda na to, że Kometa, która rozbiła się na naszej planecie jest tak naprawdę statkiem kosmicznym i wierzcie lub nie, pochodziła z tego właśnie świata dawno temu.","Você certamente viu as outras ruínas aqui perto. Parece que o Cometa que caiu neste planeta é na verdade uma espaçonave e, acredite se quiser, ela veio deste nosso mundo há muito tempo atrás.",,"Cu siguranță ai vazut ruinele din apropiere. Se pare că Cometa care a căzut e de fapt o navă spațială, și crezi sau nu, e originară din lumea asta, de acum mult timp.","Скорее всего, ты уже видел эти руины. Тот метеорит, который упал на нашу планету, — на самом деле это космический корабль. Веришь или нет, его построили на этой самой планете, давным-давно.",,"Yakındaki diğer kalıntıları görmüşsünüzdür. Görünüşe göre gezegenimize çarpan Kuyruklu Yıldız aslında bir uzay gemisi ve ister inanın ister inanmayın, uzun zaman önce tam da bu dünyada ortaya çıkmış." -"So the spectres, the One God...",TXT_RPLY0_SCRIPT22_D6064_SOTHE,,,,"Takže přízraky, Jeden bůh...","Så spøgelserne, den ene gud...","Also die Schemen, der Eine Gott...",,,"O sea que los espectros, el Dios Único...",,"Joten aaveet, Yksi Ainoa Jumala...","Donc, les Spectres, le Seul Dieu..","Szóval a kísértetek, az egy isten...","Quindi gli spettri, l'Unico Dio..",だから霊の、唯一神...,그래서 그 스펙터들과 유일신이...,"Dus de schrikbeelden, de Ene God....","Så spøkelsene, den ene Gud...","Więc widma, Jedyny Bóg...","Então os espectros, o Deus Único...",,"Deci spectrele, Adevăratul Zeu...",Так фантомы и Единый Бог...,,"Yani hayaletler, Tek Tanrı." +それは遥か前のこの乱世の始まりとも言える。","주변을 돌아다니면서 각종 폐허를 봤을 거야. 믿기지는 않겠지만, 하늘에서 갑자기 추락한 혜성은 정말로 혜성이 아니라 외계인들이 타고 내려온 우주선이라는 거야. 그리고 더 놀라운 사실은, 이 녀석들은 다 이곳에서 태어났데.","Je hebt zeker de andere ruïnes in de buurt gezien. Het lijkt erop dat de komeet die op onze planeet is neergestort, eigenlijk een ruimteschip is, en geloof het of niet, het is al lang geleden op deze wereld ontstaan.","Du har sikkert sett de andre ruinene i nærheten. Det ser ut til at kometen som krasjet på planeten vår faktisk er et romskip, og tro det eller ei, det kom fra denne verdenen for lenge siden.","Na pewno widziałeś inne ruiny w pobliżu. Wygląda na to, że Kometa, która rozbiła się na naszej planecie jest tak naprawdę statkiem kosmicznym i wierzcie lub nie, pochodziła z tego właśnie świata dawno temu.","Você certamente viu as outras ruínas aqui perto. Parece que o Cometa que caiu neste planeta é na verdade uma espaçonave e, acredite se quiser, ela veio deste nosso mundo há muito tempo atrás.",,"Cu siguranță ai vazut ruinele din apropiere. Se pare că Cometa care a căzut e de fapt o navă spațială, și crezi sau nu, e originară din lumea asta, de acum mult timp.","Скорее всего, ты уже видел эти руины. Тот метеорит, который упал на нашу планету, — на самом деле это космический корабль. Веришь или нет, его построили на этой самой планете, давным-давно.",,"Du har säkert sett de andra ruinerna i närheten. Det verkar som om kometen som kraschade på vår planet faktiskt är ett rymdskepp, och tro det eller ej, den härstammar från just den här världen för länge sedan.","Yakındaki diğer kalıntıları görmüşsünüzdür. Görünüşe göre gezegenimize çarpan Kuyruklu Yıldız aslında bir uzay gemisi ve ister inanın ister inanmayın, uzun zaman önce tam da bu dünyada ortaya çıkmış." +"So the spectres, the One God...",TXT_RPLY0_SCRIPT22_D6064_SOTHE,,,,"Takže přízraky, Jeden bůh...","Så spøgelserne, den ene gud...","Also die Schemen, der Eine Gott...",,,"O sea que los espectros, el Dios Único...",,"Joten aaveet, Yksi Ainoa Jumala...","Donc, les Spectres, le Seul Dieu..","Szóval a kísértetek, az egy isten...","Quindi gli spettri, l'Unico Dio..",だから霊の、唯一神...,그래서 그 스펙터들과 유일신이...,"Dus de schrikbeelden, de Ene God....","Så spøkelsene, den ene Gud...","Więc widma, Jedyny Bóg...","Então os espectros, o Deus Único...",,"Deci spectrele, Adevăratul Zeu...",Так фантомы и Единый Бог...,,"Så spökena, den enda guden...","Yani hayaletler, Tek Tanrı." "They are creatures who once ruled this world and are bent on consuming its life. The ancients managed to seal them away, but gave their lives in the process. I'm afraid that's all I know.",TXT_DLG_SCRIPT22_D7580_THEYA,,,,"Jsou stvoření, která dříve vládla tomuto světu a teď usilují o zničení všeho živého. Kdosi před námi byl schopen je zapečetit a přišel během toho o život. To je vše, co vím.","De er væsener, der engang herskede over denne verden og er opsat på at fortære dens liv. Det lykkedes de gamle at forsegle dem, men de gav deres liv i processen. Jeg er bange for, at det er alt, hvad jeg ved.","Das sind Wesen, die einst diese Welt regiert haben und sie ausbeuten wollen. Die Alten haben es geschafft, sie wegzusperren aber verloren ihr Leben dabei. Tut mir leid, das ist alles, was ich weiß",,,"Son criaturas que una vez dominaron este mundo e insisten en consumir su vida. Los antiguos consiguieron sellarlos, pero dieron sus vidas en el proceso. Me temo que eso es todo lo que sé.",,"Ne ovat olentoja, jotka kerran hallitsivat tätä maailmaa ja ovat nyt päättäneet hävittää sen elämästä. Muinaisten onnistui teljetä heidät ulos, mutta siinä samassa uhrasivat henkensä. Valitettavasti en tiedä tämän enempää.","Ce sont des créatures qui régnaient sur cette planète il y a longtemps, et étaient bornées à détruire toute vie sur sa surface, mais les anciens ont réussi à les sceller. Ils sont morts pour cela, j'ai peur que ce soit tout ce que je sais.","Ezek olyan lények, akik korábban a világot uralták, és mindenek felett meg akarják enni a világ életerejét. Az ősöknek sikerült őket elzárni, de bele is pusztultak a procedúrába. Attól félek, csak ennyit tudok mondani.","Sono tutte creature che una volta controllavano questo mondo e hanno come obiettivo consumarne la vita. Gli antichi riuscirono a isolarli, al costo della loro vita. Purtroppo è tutto quello che so.","奴等はかつてこの世界を支配していた生物で 生命力をひたすら吸収する存在だった。 古代人が辛うじて封印したが、 その過程で彼らの命は奪われた。 -私が知っているのはそれだけだ。","한때 이 생물들은 이 세상을 지배했던 존재였어. 초월한 힘을 계속 유지하기 위해 온갖 생명력을 빨아먹어 왔던 거지. 태초의 사람들이 어떻게든 이 들을 봉인하긴 했지만, 많은 희생이 뒤따라야만 했지... 이게 내가 알고 있는 전부야.","Het zijn wezens die ooit over deze wereld heersten en die er op uit zijn om haar leven te consumeren. De Ouden slaagden erin om ze af te sluiten, maar gaven hun leven in het proces. Ik ben bang dat dat alles is wat ik weet.","De er vesener som en gang styrte denne verden og er oppsatt på å fortære dens liv. De gamle klarte å stenge dem inne, men ga sine liv i prosessen. Jeg er redd det er alt jeg vet.","To istoty, które kiedyś rządziły tym światem i mają zamiar pochłonąć jego życie. Starożytni zdołali je zapieczętować, ale oddali za to życie. Obawiam się, że to wszystko, co wiem.","São criaturas que uma vez dominavam este mundo e querem consumir toda a vida daqui. Os antigos conseguiram selá-los, mas deram suas vidas no processo. Infelizmente isso é tudo o que eu sei.",,"Sunt creaturi care au condus cândva lumea asta și sunt determinați să-i consume toată viața. Cei antici au reușit să-i alunge, dar și-au dat viața pentru a reuși. Mă tem că asta e tot ce știu.","Эти существа когда-то правили этим миром и стремились выжать из него все соки. Древние смогли запечатать и изгнать их, пожертвовав своими жизнями. Больше, боюсь, я ничего не знаю.",,Onlar bir zamanlar bu dünyaya hükmetmiş ve yaşamı tüketmeye kararlı yaratıklar. Eskiler onları mühürlemeyi başardılar ama bu süreçte canlarını verdiler. Korkarım tüm bildiğim bu. -Thanks... I'll do what I can.,TXT_RPLY0_SCRIPT22_D7580_THANK,,,,"Díky... Uvidím, co budu moct.","Tak... Jeg vil gøre, hvad jeg kan.",Danke. Ich werde tun was ich kann.,,,Gracias... Haré lo que pueda.,,"Kiitos; teen, minkä pystyn.",Merci.. Je vais faire ce que je peux.,Kösz...megteszem amit tudok.,Grazie... farò il possibile.,ありがとう...精一杯の事をしよう。,고... 고마워. 내가 할 수 있는 것을 찾아보지.,Bedankt... Ik zal doen wat ik kan.,Takk skal du ha... Jeg skal gjøre hva jeg kan.,"Dzięki... Zrobię, co w mojej mocy.",Obrigado... Farei o possível.,,Merci... O să fac ce pot.,"Спасибо... Я сделаю всё, что смогу.",,Teşekkürler. Elimden geleni yapacağım. -"Godspeed, friend.",TXT_DLG_SCRIPT22_D9096_GODSP,,,,"Zlom vaz, příteli.","Held og lykke, min ven.","Viel Erfolg, Freund.",,,"Buena suerte, amigo.",,"Onnea matkaan, ystävä.","Bonne chance, mon ami.","Isten veled, barátom.","Ti auguro davvero di farcela, amico mio.",急ぎたまえ、同志よ。,"행운을 비네, 친구.","Goeie reis, vriend.","Lykke til, min venn.","Powodzenia, przyjacielu.","Boa sorte, amigo.",,"Noroc, prietene.","Удачи, друг.",,"Yolun açık olsun, dostum." +私が知っているのはそれだけだ。","한때 이 생물들은 이 세상을 지배했던 존재였어. 초월한 힘을 계속 유지하기 위해 온갖 생명력을 빨아먹어 왔던 거지. 태초의 사람들이 어떻게든 이 들을 봉인하긴 했지만, 많은 희생이 뒤따라야만 했지... 이게 내가 알고 있는 전부야.","Het zijn wezens die ooit over deze wereld heersten en die er op uit zijn om haar leven te consumeren. De Ouden slaagden erin om ze af te sluiten, maar gaven hun leven in het proces. Ik ben bang dat dat alles is wat ik weet.","De er vesener som en gang styrte denne verden og er oppsatt på å fortære dens liv. De gamle klarte å stenge dem inne, men ga sine liv i prosessen. Jeg er redd det er alt jeg vet.","To istoty, które kiedyś rządziły tym światem i mają zamiar pochłonąć jego życie. Starożytni zdołali je zapieczętować, ale oddali za to życie. Obawiam się, że to wszystko, co wiem.","São criaturas que uma vez dominavam este mundo e querem consumir toda a vida daqui. Os antigos conseguiram selá-los, mas deram suas vidas no processo. Infelizmente isso é tudo o que eu sei.",,"Sunt creaturi care au condus cândva lumea asta și sunt determinați să-i consume toată viața. Cei antici au reușit să-i alunge, dar și-au dat viața pentru a reuși. Mă tem că asta e tot ce știu.","Эти существа когда-то правили этим миром и стремились выжать из него все соки. Древние смогли запечатать и изгнать их, пожертвовав своими жизнями. Больше, боюсь, я ничего не знаю.",,"De är varelser som en gång styrde den här världen och är fast beslutna att förtära dess liv. De gamla lyckades försegla dem, men gav sina liv i processen. Jag är rädd att det är allt jag vet.",Onlar bir zamanlar bu dünyaya hükmetmiş ve yaşamı tüketmeye kararlı yaratıklar. Eskiler onları mühürlemeyi başardılar ama bu süreçte canlarını verdiler. Korkarım tüm bildiğim bu. +Thanks... I'll do what I can.,TXT_RPLY0_SCRIPT22_D7580_THANK,,,,"Díky... Uvidím, co budu moct.","Tak... Jeg vil gøre, hvad jeg kan.",Danke. Ich werde tun was ich kann.,,,Gracias... Haré lo que pueda.,,"Kiitos; teen, minkä pystyn.",Merci.. Je vais faire ce que je peux.,Kösz...megteszem amit tudok.,Grazie... farò il possibile.,ありがとう...精一杯の事をしよう。,고... 고마워. 내가 할 수 있는 것을 찾아보지.,Bedankt... Ik zal doen wat ik kan.,Takk skal du ha... Jeg skal gjøre hva jeg kan.,"Dzięki... Zrobię, co w mojej mocy.",Obrigado... Farei o possível.,,Merci... O să fac ce pot.,"Спасибо... Я сделаю всё, что смогу.",,Tack... Jag ska göra vad jag kan.,Teşekkürler. Elimden geleni yapacağım. +"Godspeed, friend.",TXT_DLG_SCRIPT22_D9096_GODSP,,,,"Zlom vaz, příteli.","Held og lykke, min ven.","Viel Erfolg, Freund.",,,"Buena suerte, amigo.",,"Onnea matkaan, ystävä.","Bonne chance, mon ami.","Isten veled, barátom.","Ti auguro davvero di farcela, amico mio.",急ぎたまえ、同志よ。,"행운을 비네, 친구.","Goeie reis, vriend.","Lykke til, min venn.","Powodzenia, przyjacielu.","Boa sorte, amigo.",,"Noroc, prietene.","Удачи, друг.",,"Lycka till, min vän.","Yolun açık olsun, dostum." Talk to the master Smithy if you have questions. All I do is put labels on the crates.,TXT_DLG_SCRIPT22_D10612_TALKT,,,,"Promluv si s mistrem Smithym, jestli se chceš na něco zeptat. Já jenom dávám štítky na krabice.","Tal med mester Smithy, hvis du har spørgsmål. Jeg sætter bare etiketter på kasserne.","Sprich mit dem Meister Smithy, wenn du Fragen hast. Ich versehe die Kisten nur mit Etiketten.",,,Habla con el maestro Smithy si tienes preguntas. Lo único que hago yo es etiquetar las cajas.,,"Puhu pajamestarin kanssa, jos sinulla on kysyttävää. Minä vain leimaan laatikoita.","Parlez au maître Smithy si vous avez des questions. Tout ce que je fais, c'est mettre des étiquettes sur des caisses.",Beszélj Smithy mesterrel ha van kérdésed. Én csak címkéket rakok a hordókra.,Parla con il mastro Smithy se hai delle domande. Il mio unico compito è catalogare gli scatoli.,"相談がある場合は鍛冶屋のマスターに仰って -下さい。私は箱にラベルを張っているだけです。",궁금한 게 있으면 스미시 제조장관님에게 물어봐. 내 업무는 상자에 표를 붙이는 것밖엔 없어.,Praat met meester Smithy als je vragen hebt. Het enige wat ik doe is etiketten op de kratten plakken.,"Snakk med smedmesteren hvis du har spørsmål. Alt jeg gjør, er å sette etiketter på kassene.","Porozmawiaj z mistrzem Smithy, jeśli masz pytania. Ja tylko naklejam etykiety na skrzyniach.",Fale com o mestre Smithy se tiver dúvidas. Tudo o que eu faço aqui é colocar etiquetas nas caixas.,,Vorbește cu maestrul Smithy dacă ai întrebări. Tot ce fac eu e să pun embleme pe cutii.,"Если у тебя есть какие-то вопросы, обратись к мастеру-кузнецу. Я просто клею ярлыки на ящики.",,Sorunuz olursa Demirci Usta ile konuşun. Tek yaptığım kasaların üzerine etiket yapıştırmak. -"What can I get you, citizen?",TXT_DLG_SCRIPT23_D0_WHATC,,,,"Co vám mohu nabídnout, občane?","Hvad kan jeg skaffe dig, borger?","Was darf es sein, Bürger?",,,"¿Qué puedo ofrecerte, ciudadano?",,"Mitä saisi olla, kansalainen?","Qu'est-ce que je peux faire pour vous, citoyen?","Miben segíthetek, polgártárs?","Che ti serve, cittadino?",何が入り用だ、お客さん?,"무엇을 줄까요, 형씨?","Wat kan ik voor je halen, burger?","Hva vil du ha, borger?","Co mogę ci dać, obywatelu?","Como posso ajudá-lo, cidadão?",,"Ce pot să-ți aduc, cetățeanule?","Что я могу тебе предложить, гражданин?",,"Sana ne verebilirim, vatandaş?" -Ammo box,TXT_RPLY0_SCRIPT23_D0_AMMOB,,,,Krabici nábojů,Ammo kasse,Munitionsschachtel,,Municikesto,Caja de municiones,,Ammuslaatikko,Boîte de munitions.,Lőszer doboz,Scatola di munizioni,銃弾倉,돌격소총 탄약 박스,Munitiedoos,En ammunisjonskasse.,Skrzynia z amunicją,Caixa de munição,,Cutie cu muniție,Коробку патронов,,Cephane kutusu -Here's your ammo.,TXT_RYES0_SCRIPT23_D0_HERES,,,,Tady je.,Her er din ammunition.,Hier ist deine Munition.,,Jen via municio.,Aquí está tu munición.,,Tässä ammuksesi.,Voilà vos munitions.,Itt a lőszered.,Ecco le tue munizioni.,これでソチラのブツだ。,탄약을 구매해줘서 고마워요.,Hier is je munitie.,Her er ammunisjonen din.,To twoja amunicja.,Aqui está a sua munição.,,Aici e muniția.,Вот твои патроны.,,İşte cephanen. -You don't have enough for that!,TXT_RNO0_SCRIPT23_D0_YOUDO,,,,Na tu nemáš dost peněz!,Du har ikke nok til det!,Du hast nich genug Gold!,,,¡No tienes suficiente para eso!,,Sinulla ei riitä rahat sitä varten!,Vous n'avez pas assez d'argent.,Nincs elég ehhez nálad!,Non hai abbastanza soldi per quello!,そんだけの金持ってないぞ!,가격에 맞게 돈을 가져오세요!,Daar heb je niet genoeg voor!,Du har ikke nok til det!,Nie masz na to dość!,Você não tem o suficiente para isto.,,Nu ai suficiente fonduri pentru asta.,У тебя недостаточно денег!,,Bunun için yeterince cephanen yok! -Crate of missiles,TXT_RPLY1_SCRIPT23_D0_CRATE,,,,Bednu raket,Kasse med missiler,Raketenkiste,,,Caja de misiles,,Ohjuslaatikko,Caisse de missiles.,Ládányi rakéta,Cassa di razzi,ミサイル箱,미니 미사일 박스,Krat van raketten,Kasse med raketter,Skrzynia z pociskami,Caixa de mísseis,,Cutie de rachete.,Коробку ракет,,Füze sandığı -"Here, citizen.",TXT_RYES1_SCRIPT23_D0_HEREC,,,,"Tady, občane.","Her, borger.","Hier, Bürger.",,,"Toma, ciudadano.",,"Tässä, kansalainen.","Voilà, citoyen.","Parancsolj, polgártárs.","Ecco qua, cittadino",どうぞ、お客さん。,여기 있습니다.,"Hier, burger.","Her, borger.","Proszę, obywatelu.","Aqui, cidadão.",,"Aici, orășene.","Вот, гражданин.",,"Buyur, vatandaş." -"It's 85 gold, citizen!",TXT_RNO1_SCRIPT23_D0_ITS85,,,,"Ta stojí 85 zlatých, občane!","Det koster 85 guld, borger!","Das macht 85 Gold, Bürger!",,,"¡Son 85 de oro, ciudadano!",,"Se maksaa 85 kolikkoa, kansalainen!","Cela coûte 85 pièces, citoyen!","85 arany lesz, polgártárs.","Sono 85 pezzi d'oro, cittadino!",85ゴールドだぜ、お客さん!,그건 85골드입니다.,"Het is 85 goud, burger!","Det er 85 gull, borger!","To 85 złotych, obywatelu!","Custa 85 moedas de ouro, cidadão!",,"E 85 de monezi, orășene!","Гражданин, это стоит 85 золотых!",,"85 altın, vatandaş!" -H-E grenades,TXT_RPLY2_SCRIPT23_D0_HEGRE,,,,Výbušné granáty,H-E granater,HE-Granaten,,,Granadas HE,,Räjähdekranaatteja,Grenades explosives.,Robbanó gránátok,Granate ad alto potenziale esplosivo,HEグレネード,고폭 유탄,H-E-granaten,H-E-granater,Granaty H-E,Granadas explosivas,,Grenade.,Осколочные гранаты,,H-E el bombaları -Here are your grenades.,TXT_RYES2_SCRIPT23_D0_HEREA,,,,Tady jsou.,Her er dine granater.,Hier sind deine Granaten.,,,Aquí tienes tus granadas.,,Tässä kranaattisi.,Voilà vos grenades.,Itt vannak a gránátaid.,Ecco le tue granate.,これでソチラのブツだ。,여기 유탄입니다.,Hier zijn je granaten.,Her er granatene dine.,Oto twoje granaty.,Aqui estão as suas granadas,,Aici sunt grenadele.,Забирай свои гранаты.,,İşte el bombaların. -"They are 100 gold, friend.",TXT_RNO2_SCRIPT23_D0_THEYA,,,,"Ty stojí sto zlatých, příteli.","De koster 100 guld, ven.","Sie kosten 100 Gold, mein Freund.",,,"Son 100 de oro, amigo.",,"Ne maksavat 100 kolikkoa, ystäväiseni.","Cela coûte 100 pièces, mon ami.",100 aranyba kerülnek polgártársam.,"Ti servono 100 pezzi d'oro, amico.",100ゴールドだぜ、旦那!,"그건 100 골드야, 친구.","Ze zijn 100 goud, vriend.","De koster 100 gull, min venn.","Kosztują 100 złota, przyjacielu.","Custam 100 moedas, amigo.",,"Costă 100 de monezi, prietene.","Они по 100 золотых, друг.",,"Onlar 100 altın, dostum." -Energy pod,TXT_RPLY3_SCRIPT23_D0_ENERG,,,,Energetický kokón,Energibælg,Energiezelle.,,,Vaina de energía,,Energia-akku,Cellule énergetique.,Energia cella,Nucleo energetico,エネルギーポッド,에너지 포드,Energiecapsule,Energikapsel,Strąk energii,Célula de energia.,,Capsulă energetică.,Энергоячейку,,Enerji kapsülü -Here you are.,TXT_RYES3_SCRIPT23_D0_HEREY,,,,Tady je.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,"Tässä, ole hyvä.",Voilà pour vous.,Parancsolj.,Eccolo qua.,どうぞ。,여기 있습니다.,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici este.,Получай.,,Buyurun. -"That's 135 gold, sorry.",TXT_RNO3_SCRIPT23_D0_THATS,,,,"Ten stojí 135 zlatých, je mi líto.","Den koster 135 guld, beklager.","Entschuldigung, aber das macht 135 Gold.",,,"Son 135 de oro, lo siento.",,"Se 135 kolikkoa, valitan.","Cela coûte 135 pièces, désolé.","Sajnálom, de az 135 arany.","Mi spiace, ma costa 135 pezzi d'oro.",135ゴールドなんだ、ワリィ!,"미안하지만, 그건 135 골드입니다.","Dat is 135 goud, sorry.","Det er 135 gull, beklager.","To 135 złota, przepraszam.",Custa 135 moedas. Sinto muito.,,"Costă 135 de monezi, scuze.",Она стоит 135 золотых. Извини.,,"Bu 135 altın, üzgünüm." -What can I assist you with?,TXT_DLG_SCRIPT23_D1516_WHATC,,,,S čím vám mohu pomoci?,Hvad kan jeg hjælpe dig med?,Wie kann ich dir behilflich sein?,,Kiel mi helpu vin?,¿Con qué puedo ayudarte?,,Miten voin auttaa?,Commen puis-je vous assister?,Miben segíthetek?,Come posso esserti utile?,何か手伝いましょうか?,어떤 걸 도와드릴까요?,Waarmee kan ik je helpen?,Hva kan jeg hjelpe deg med?,W czym mogę ci pomóc?,Como posso ajudá-lo?,,Cu ce te pot ajuta?,Чем я могу тебе помочь?,,Size nasıl yardımcı olabilirim? -Leather armor,TXT_RPLY0_SCRIPT23_D1516_LEATH,,,Leather armour,Kožené brnění,Læder rustning,Lederrüstung,,Leda armaĵo,Armadura de cuero,,Nahkasuojus,Armure de cuir.,Bőr vért,Armatura di cuoio,レザーアーマー,가죽 갑옷,Leren harnas,Skinnrustning.,Skórzana zbroja.,Armadura de couro,,Armură de piele,Кожаной бронёй,,Deri zırh -Here it is citizen.,TXT_RYES0_SCRIPT23_D1516_HEREI,,,,"Tady je, občane.","Her er den, borger.","Hier ist sie, Bürger.",,"Jen ĝi, civitano.","Aquí está, ciudadano.",,"Tässä on, kansalainen.","Voilà pour vous, citoyen.",Parancsolj.,"Ecco qua, cittadino.",どうぞ、お客さん。,"여기 있어요, 형씨.",Hier is het een burger.,"Her er den, borger.","Oto ona, obywatelu.","Aqui está, cidadão.",,Aici e orășene.,"Вот она, гражданин.",,İşte vatandaş. +下さい。私は箱にラベルを張っているだけです。",궁금한 게 있으면 스미시 제조장관님에게 물어봐. 내 업무는 상자에 표를 붙이는 것밖엔 없어.,Praat met meester Smithy als je vragen hebt. Het enige wat ik doe is etiketten op de kratten plakken.,"Snakk med smedmesteren hvis du har spørsmål. Alt jeg gjør, er å sette etiketter på kassene.","Porozmawiaj z mistrzem Smithy, jeśli masz pytania. Ja tylko naklejam etykiety na skrzyniach.",Fale com o mestre Smithy se tiver dúvidas. Tudo o que eu faço aqui é colocar etiquetas nas caixas.,,Vorbește cu maestrul Smithy dacă ai întrebări. Tot ce fac eu e să pun embleme pe cutii.,"Если у тебя есть какие-то вопросы, обратись к мастеру-кузнецу. Я просто клею ярлыки на ящики.",,Prata med mästersmeden om du har frågor. Allt jag gör är att sätta etiketter på lådorna.,Sorunuz olursa Demirci Usta ile konuşun. Tek yaptığım kasaların üzerine etiket yapıştırmak. +"What can I get you, citizen?",TXT_DLG_SCRIPT23_D0_WHATC,,,,"Co vám mohu nabídnout, občane?","Hvad kan jeg skaffe dig, borger?","Was darf es sein, Bürger?",,,"¿Qué puedo ofrecerte, ciudadano?",,"Mitä saisi olla, kansalainen?","Qu'est-ce que je peux faire pour vous, citoyen?","Miben segíthetek, polgártárs?","Che ti serve, cittadino?",何が入り用だ、お客さん?,"무엇을 줄까요, 형씨?","Wat kan ik voor je halen, burger?","Hva vil du ha, borger?","Co mogę ci dać, obywatelu?","Como posso ajudá-lo, cidadão?",,"Ce pot să-ți aduc, cetățeanule?","Что я могу тебе предложить, гражданин?",,"Vad vill du ha, medborgare?","Sana ne verebilirim, vatandaş?" +Ammo box,TXT_RPLY0_SCRIPT23_D0_AMMOB,,,,Krabici nábojů,Ammo kasse,Munitionsschachtel,,Municikesto,Caja de municiones,,Ammuslaatikko,Boîte de munitions.,Lőszer doboz,Scatola di munizioni,銃弾倉,돌격소총 탄약 박스,Munitiedoos,En ammunisjonskasse.,Skrzynia z amunicją,Caixa de munição,,Cutie cu muniție,Коробку патронов,,Ammunitionslåda,Cephane kutusu +Here's your ammo.,TXT_RYES0_SCRIPT23_D0_HERES,,,,Tady je.,Her er din ammunition.,Hier ist deine Munition.,,Jen via municio.,Aquí está tu munición.,,Tässä ammuksesi.,Voilà vos munitions.,Itt a lőszered.,Ecco le tue munizioni.,これでソチラのブツだ。,탄약을 구매해줘서 고마워요.,Hier is je munitie.,Her er ammunisjonen din.,To twoja amunicja.,Aqui está a sua munição.,,Aici e muniția.,Вот твои патроны.,,Här är din ammunition.,İşte cephanen. +You don't have enough for that!,TXT_RNO0_SCRIPT23_D0_YOUDO,,,,Na tu nemáš dost peněz!,Du har ikke nok til det!,Du hast nich genug Gold!,,,¡No tienes suficiente para eso!,,Sinulla ei riitä rahat sitä varten!,Vous n'avez pas assez d'argent.,Nincs elég ehhez nálad!,Non hai abbastanza soldi per quello!,そんだけの金持ってないぞ!,가격에 맞게 돈을 가져오세요!,Daar heb je niet genoeg voor!,Du har ikke nok til det!,Nie masz na to dość!,Você não tem o suficiente para isto.,,Nu ai suficiente fonduri pentru asta.,У тебя недостаточно денег!,,Du har inte tillräckligt med ammunition för det!,Bunun için yeterince cephanen yok! +Crate of missiles,TXT_RPLY1_SCRIPT23_D0_CRATE,,,,Bednu raket,Kasse med missiler,Raketenkiste,,,Caja de misiles,,Ohjuslaatikko,Caisse de missiles.,Ládányi rakéta,Cassa di razzi,ミサイル箱,미니 미사일 박스,Krat van raketten,Kasse med raketter,Skrzynia z pociskami,Caixa de mísseis,,Cutie de rachete.,Коробку ракет,,Låda med missiler,Füze sandığı +"Here, citizen.",TXT_RYES1_SCRIPT23_D0_HEREC,,,,"Tady, občane.","Her, borger.","Hier, Bürger.",,,"Toma, ciudadano.",,"Tässä, kansalainen.","Voilà, citoyen.","Parancsolj, polgártárs.","Ecco qua, cittadino",どうぞ、お客さん。,여기 있습니다.,"Hier, burger.","Her, borger.","Proszę, obywatelu.","Aqui, cidadão.",,"Aici, orășene.","Вот, гражданин.",,"Här, medborgare.","Buyur, vatandaş." +"It's 85 gold, citizen!",TXT_RNO1_SCRIPT23_D0_ITS85,,,,"Ta stojí 85 zlatých, občane!","Det koster 85 guld, borger!","Das macht 85 Gold, Bürger!",,,"¡Son 85 de oro, ciudadano!",,"Se maksaa 85 kolikkoa, kansalainen!","Cela coûte 85 pièces, citoyen!","85 arany lesz, polgártárs.","Sono 85 pezzi d'oro, cittadino!",85ゴールドだぜ、お客さん!,그건 85골드입니다.,"Het is 85 goud, burger!","Det er 85 gull, borger!","To 85 złotych, obywatelu!","Custa 85 moedas de ouro, cidadão!",,"E 85 de monezi, orășene!","Гражданин, это стоит 85 золотых!",,"Det är 85 guld, medborgare!","85 altın, vatandaş!" +H-E grenades,TXT_RPLY2_SCRIPT23_D0_HEGRE,,,,Výbušné granáty,H-E granater,HE-Granaten,,,Granadas HE,,Räjähdekranaatteja,Grenades explosives.,Robbanó gránátok,Granate ad alto potenziale esplosivo,HEグレネード,고폭 유탄,H-E-granaten,H-E-granater,Granaty H-E,Granadas explosivas,,Grenade.,Осколочные гранаты,,H-E-granater,H-E el bombaları +Here are your grenades.,TXT_RYES2_SCRIPT23_D0_HEREA,,,,Tady jsou.,Her er dine granater.,Hier sind deine Granaten.,,,Aquí tienes tus granadas.,,Tässä kranaattisi.,Voilà vos grenades.,Itt vannak a gránátaid.,Ecco le tue granate.,これでソチラのブツだ。,여기 유탄입니다.,Hier zijn je granaten.,Her er granatene dine.,Oto twoje granaty.,Aqui estão as suas granadas,,Aici sunt grenadele.,Забирай свои гранаты.,,Här är dina granater.,İşte el bombaların. +"They are 100 gold, friend.",TXT_RNO2_SCRIPT23_D0_THEYA,,,,"Ty stojí sto zlatých, příteli.","De koster 100 guld, ven.","Sie kosten 100 Gold, mein Freund.",,,"Son 100 de oro, amigo.",,"Ne maksavat 100 kolikkoa, ystäväiseni.","Cela coûte 100 pièces, mon ami.",100 aranyba kerülnek polgártársam.,"Ti servono 100 pezzi d'oro, amico.",100ゴールドだぜ、旦那!,"그건 100 골드야, 친구.","Ze zijn 100 goud, vriend.","De koster 100 gull, min venn.","Kosztują 100 złota, przyjacielu.","Custam 100 moedas, amigo.",,"Costă 100 de monezi, prietene.","Они по 100 золотых, друг.",,"De kostar 100 guld, vän.","Onlar 100 altın, dostum." +Energy pod,TXT_RPLY3_SCRIPT23_D0_ENERG,,,,Energetický kokón,Energibælg,Energiezelle.,,,Vaina de energía,,Energia-akku,Cellule énergetique.,Energia cella,Nucleo energetico,エネルギーポッド,에너지 포드,Energiecapsule,Energikapsel,Strąk energii,Célula de energia.,,Capsulă energetică.,Энергоячейку,,Energipod,Enerji kapsülü +Here you are.,TXT_RYES3_SCRIPT23_D0_HEREY,,,,Tady je.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,"Tässä, ole hyvä.",Voilà pour vous.,Parancsolj.,Eccolo qua.,どうぞ。,여기 있습니다.,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici este.,Получай.,,Här är den.,Buyurun. +"That's 135 gold, sorry.",TXT_RNO3_SCRIPT23_D0_THATS,,,,"Ten stojí 135 zlatých, je mi líto.","Den koster 135 guld, beklager.","Entschuldigung, aber das macht 135 Gold.",,,"Son 135 de oro, lo siento.",,"Se 135 kolikkoa, valitan.","Cela coûte 135 pièces, désolé.","Sajnálom, de az 135 arany.","Mi spiace, ma costa 135 pezzi d'oro.",135ゴールドなんだ、ワリィ!,"미안하지만, 그건 135 골드입니다.","Dat is 135 goud, sorry.","Det er 135 gull, beklager.","To 135 złota, przepraszam.",Custa 135 moedas. Sinto muito.,,"Costă 135 de monezi, scuze.",Она стоит 135 золотых. Извини.,,"Den kostar 135 guld, tyvärr.","Bu 135 altın, üzgünüm." +What can I assist you with?,TXT_DLG_SCRIPT23_D1516_WHATC,,,,S čím vám mohu pomoci?,Hvad kan jeg hjælpe dig med?,Wie kann ich dir behilflich sein?,,Kiel mi helpu vin?,¿Con qué puedo ayudarte?,,Miten voin auttaa?,Commen puis-je vous assister?,Miben segíthetek?,Come posso esserti utile?,何か手伝いましょうか?,어떤 걸 도와드릴까요?,Waarmee kan ik je helpen?,Hva kan jeg hjelpe deg med?,W czym mogę ci pomóc?,Como posso ajudá-lo?,,Cu ce te pot ajuta?,Чем я могу тебе помочь?,,Vad kan jag hjälpa dig med?,Size nasıl yardımcı olabilirim? +Leather armor,TXT_RPLY0_SCRIPT23_D1516_LEATH,,,Leather armour,Kožené brnění,Læder rustning,Lederrüstung,,Leda armaĵo,Armadura de cuero,,Nahkasuojus,Armure de cuir.,Bőr vért,Armatura di cuoio,レザーアーマー,가죽 갑옷,Leren harnas,Skinnrustning.,Skórzana zbroja.,Armadura de couro,,Armură de piele,Кожаной бронёй,,Läderrustning,Deri zırh +Here it is citizen.,TXT_RYES0_SCRIPT23_D1516_HEREI,,,,"Tady je, občane.","Her er den, borger.","Hier ist sie, Bürger.",,"Jen ĝi, civitano.","Aquí está, ciudadano.",,"Tässä on, kansalainen.","Voilà pour vous, citoyen.",Parancsolj.,"Ecco qua, cittadino.",どうぞ、お客さん。,"여기 있어요, 형씨.",Hier is het een burger.,"Her er den, borger.","Oto ona, obywatelu.","Aqui está, cidadão.",,Aici e orășene.,"Вот она, гражданин.",,"Här är den, medborgare.",İşte vatandaş. There's no charity given here!,TXT_RNO0_SCRIPT23_D1516_THERE,,,,Nejsme charita!,Der gives ingen velgørenhed her!,Hier gibt es nichts umsonst!,,"Ĉi tio ne estas -almozulejo!",¡Aquí no damos limosna!,,Täällä ei harrasteta hyväntekeväisyyttä!,On n'est pas une charité ici.,"Sajnálom, ez nem jótékonyság.",Non facciamo beneficienza!,これはチャリティーじゃない!,돈이 부족하면 다른 곳을 알아봐! 여긴 자선단체가 아니라고!,Er wordt hier geen liefdadigheid gegeven!,Det er ingen veldedighet her!,Nie ma tu żadnej dobroczynności!,Aqui não é local de caridade!,,Nu facem caritate aici!,Я благотворительностью не занимаюсь!,,Burada sadaka verilmez! -Metal armor,TXT_RPLY1_SCRIPT23_D1516_METAL,,,Metal armour,Kovové brnění,Metal rustning,Metallrüstung,,Metala armaĵo,Armadura de metal,,Metallihaarniska,Armure de métal.,Fém vért,Armatura di metallo,メタルアーマー,강철 갑옷,Metalen harnas,Metall rustning,Metalowa zbroja.,Armadura de metal,,Armură de metal,Металлической бронёй,,Metal zırh +almozulejo!",¡Aquí no damos limosna!,,Täällä ei harrasteta hyväntekeväisyyttä!,On n'est pas une charité ici.,"Sajnálom, ez nem jótékonyság.",Non facciamo beneficienza!,これはチャリティーじゃない!,돈이 부족하면 다른 곳을 알아봐! 여긴 자선단체가 아니라고!,Er wordt hier geen liefdadigheid gegeven!,Det er ingen veldedighet her!,Nie ma tu żadnej dobroczynności!,Aqui não é local de caridade!,,Nu facem caritate aici!,Я благотворительностью не занимаюсь!,,Det finns ingen välgörenhet här!,Burada sadaka verilmez! +Metal armor,TXT_RPLY1_SCRIPT23_D1516_METAL,,,Metal armour,Kovové brnění,Metal rustning,Metallrüstung,,Metala armaĵo,Armadura de metal,,Metallihaarniska,Armure de métal.,Fém vért,Armatura di metallo,メタルアーマー,강철 갑옷,Metalen harnas,Metall rustning,Metalowa zbroja.,Armadura de metal,,Armură de metal,Металлической бронёй,,Metall rustning,Metal zırh An excellent choice citizen.,TXT_RYES1_SCRIPT23_D1516_ANEXC,,,,"Výborná volba, občane.","Et glimrende valg, borger.","Eine exzellente Wahl, Bürger.",,"Bonega elekto, civitano.","Excelente elección, -ciudadano.",,"Erinomainen valinta, kansalainen.","Un excellent choix, citoyen.",Kiváló választás polgártárs.,"Ottima scelta, cittadino.",良い選択です。,"탁월한 선택이십니다, 형씨.","Een uitstekende keuze, burger.","Et utmerket valg, borger.","Doskonały wybór, obywatelu.","Excelente escolha, cidadão.",,Excelentă alegere orășene.,"Отличный выбор, гражданин.",,Mükemmel bir seçim vatandaş. +ciudadano.",,"Erinomainen valinta, kansalainen.","Un excellent choix, citoyen.",Kiváló választás polgártárs.,"Ottima scelta, cittadino.",良い選択です。,"탁월한 선택이십니다, 형씨.","Een uitstekende keuze, burger.","Et utmerket valg, borger.","Doskonały wybór, obywatelu.","Excelente escolha, cidadão.",,Excelentă alegere orășene.,"Отличный выбор, гражданин.",,"Ett utmärkt val, medborgare.",Mükemmel bir seçim vatandaş. You don't have enough for this!,TXT_RNO1_SCRIPT23_D1516_YOUDO,,,,Na to nemáte dost peněz!,Du har ikke nok til dette!,Du hast nich genug Gold dafür!,,"Vi ne havas -sufiĉe da mono!",¡No te alcanza!,,Rahasi ei riitä siihen!,Vous n'avez pas assez d'argent.,Nincs elég ehhez nálad!,Non hai abbastanza soldi per questo!,これでは足りない!,이것을 구입하기엔 돈이 부족합니다!,Je hebt hier niet genoeg voor!,Du har ikke nok til dette!,Nie masz na to dość!,Você não tem o suficiente para isto!,,Nu ai suficiente fonduri pentru asta!,У тебя недостаточно денег!,,Bunun için yeterli değilsin! -Environmental suit,TXT_RPLY2_SCRIPT23_D1516_ENVIR,,,,Ochranný oblek,Miljødragt,Schutzanzug.,,Medi-ŝirma vesto,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison Hazmat.,Védőruha,Tuta ambientale,耐環境スーツ,환경 방호복,Beschermend Pak,Miljødrakt,Kombinezon ekologiczny,Traje de proteção,,Costum de Protecție împotriva Mediului,Защитным костюмом,,Çevre kıyafeti -Here you are.,TXT_RYES2_SCRIPT23_D1516_HEREY,,,,Tady máte.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,Kas tässä.,Voilà pour vous.,"Itt van, parancsolj.",Eccola qua.,どうぞ。,여기 있습니다.,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici este.,Держи.,,İşte buradasın. +sufiĉe da mono!",¡No te alcanza!,,Rahasi ei riitä siihen!,Vous n'avez pas assez d'argent.,Nincs elég ehhez nálad!,Non hai abbastanza soldi per questo!,これでは足りない!,이것을 구입하기엔 돈이 부족합니다!,Je hebt hier niet genoeg voor!,Du har ikke nok til dette!,Nie masz na to dość!,Você não tem o suficiente para isto!,,Nu ai suficiente fonduri pentru asta!,У тебя недостаточно денег!,,Du har inte tillräckligt för detta!,Bunun için yeterli değilsin! +Environmental suit,TXT_RPLY2_SCRIPT23_D1516_ENVIR,,,,Ochranný oblek,Miljødragt,Schutzanzug.,,Medi-ŝirma vesto,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison Hazmat.,Védőruha,Tuta ambientale,耐環境スーツ,환경 방호복,Beschermend Pak,Miljødrakt,Kombinezon ekologiczny,Traje de proteção,,Costum de Protecție împotriva Mediului,Защитным костюмом,,Miljödräkt,Çevre kıyafeti +Here you are.,TXT_RYES2_SCRIPT23_D1516_HEREY,,,,Tady máte.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,Kas tässä.,Voilà pour vous.,"Itt van, parancsolj.",Eccola qua.,どうぞ。,여기 있습니다.,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici este.,Держи.,,Här är du.,İşte buradasın. "No money, no suit.",TXT_RNO2_SCRIPT23_D1516_NOMON,,,,Bez peněz pro oděvy nelez.,"Ingen penge, ingen dragt.","Kein Geld, kein Anzug.",,"Sen mono -ne estas vesto.",Sin dinero no hay traje.,,"Ei rahaa, ei pukua.","Pas d'argent, pas de combi.","Ha nincs pénz, nincs védőruha.","Niente denaro, niente completo.",金が無いならスーツは無しだ。,돈이 없다면 방호복을 줄 수 없습니다.,"Geen geld, geen pak.","Ingen penger, ingen drakt.","Nie ma pieniędzy, nie ma kombinezonu.","Sem dinheiro, sem traje.",,"Niciun ban, niciun costum.","Нет денег, нет костюма.",,"Para yok, takım elbise yok." -Something different?,TXT_RPLY3_SCRIPT23_D1516_SOMET,,,,Něco jiného?,Noget andet?,Irgendetwas anderes?,,,¿Algo distinto?,,Jotain erilaista?,Quelque chose d'autre?,Valami mást esetleg?,Qualcos'altro?,何か別のやつは?,뭔가 다른 거는?,Iets anders?,Noe annet?,Coś innego?,Algo diferente?,,Ceva diferit?,Что-нибудь ещё?,,Farklı bir şey mi var? -Go through the door down the hall.,TXT_RYES3_SCRIPT23_D1516_GOTHR,,,,Jděte dveřmi dole na chodbě.,Gå gennem døren nede ad gangen.,Geh durch die Tür zur Halle.,,,Ve por la puerta pasillo abajo.,,Mene ovesta käytävän päässä.,"Passez par la porte, vers le hall.",Menj át a csarnok végén levő ajtón.,Vai oltre la porta alla fine della stanza.,ホールのドアを通るんだ。,복도를 따라 문을 향해 가보세요.,Ga door de deur aan het einde van de gang.,Gå gjennom døren i gangen.,Przejdź przez drzwi na końcu korytarza.,Passe pela porta lá no salão.,,Intră pe ușa din josul holului.,"Дальше по коридору, за дверью.",,Koridorun sonundaki kapıdan geç. -You must pay if you want to play.,TXT_RNO3_SCRIPT23_D1516_YOUMU,,,,Chceš si hrát? Zaplať.,"Du skal betale, hvis du vil spille.","Du musst bezahlen, wenn du spielen willst.",,,Debes pagar si quieres jugar.,,"Ken leikkiin ryhtyy, se leikistä maksakoon.",Vous devez payer si vous voulez jouer.,Fizetned kell hogy játszhass.,Devi pagare se vuoi giocare.,プレイするなら支払うべきだ。,할려면 돈을 먼저 주세요.,Je moet betalen als je wilt spelen.,Du må betale hvis du vil spille.,"Musisz zapłacić, jeśli chcesz grać.",Você precisa pagar se quiser jogar.,,Trebuie să plătești dacă vrei să joci.,"Любишь играть, люби и платить!",,Oynamak istiyorsan ödeme yapmalısın. -What can I get you?,TXT_DLG_SCRIPT23_D3032_WHATC,,,,Co vám mohu nabídnout?,Hvad kan jeg give dig?,Was darf es sein?,,Kion mi donu al vi?,¿Qué puedo ofrecerte?,,Mitä teille saisi olla?,Que puis-je pour vous?,Mit adhatok?,Cosa ti porto?,何をお求めで?,무엇을 드릴까요?,Wat kan ik voor je halen?,Hva vil du ha?,Co mogę ci dać?,O que gostaria?,,Ce pot să-ți aduc?,Что я могу тебе предложить?,,Sana ne verebilirim? -Leather armor,TXT_RPLY0_SCRIPT23_D3032_LEATH,,,Leather armour,Kožené brnění,En læderrustning,Lederrüstung,,Ledan armaĵon,Armadura de cuero,,Nahkasuojus,Armure de cuir.,Bőr vért,Armatura di cuoio,レザーアーマー,가죽 갑옷,Leren harnas,En skinnrustning.,Skórzaną zbroję.,Armadura de couro,,Armură de piele,Кожаную броню,,Deri zırh. -"Here it is, citizen.",TXT_RYES0_SCRIPT23_D3032_HEREI,,,,"Tady je, občane.","Her er den, borger.","Hier ist sie, Bürger.",,"Jen ĝi, civitano.","Aquí está, ciudadano.",,"Tästä saat, kansalainen.","Voilà pour vous, citoyen.","Parancsolj, polgártárs.","Ecco qua, cittadino.",どうぞ、お客さん。,"적절히 입으세요, 시민.","Hier is het, burger.","Vær så god, borger.","Oto ona, obywatelu.","Aqui está, cidadão.",,"Aici este, orășene.","Вот она, гражданин.",,"İşte burada, vatandaş." +ne estas vesto.",Sin dinero no hay traje.,,"Ei rahaa, ei pukua.","Pas d'argent, pas de combi.","Ha nincs pénz, nincs védőruha.","Niente denaro, niente completo.",金が無いならスーツは無しだ。,돈이 없다면 방호복을 줄 수 없습니다.,"Geen geld, geen pak.","Ingen penger, ingen drakt.","Nie ma pieniędzy, nie ma kombinezonu.","Sem dinheiro, sem traje.",,"Niciun ban, niciun costum.","Нет денег, нет костюма.",,"Inga pengar, ingen dräkt.","Para yok, takım elbise yok." +Something different?,TXT_RPLY3_SCRIPT23_D1516_SOMET,,,,Něco jiného?,Noget andet?,Irgendetwas anderes?,,,¿Algo distinto?,,Jotain erilaista?,Quelque chose d'autre?,Valami mást esetleg?,Qualcos'altro?,何か別のやつは?,뭔가 다른 거는?,Iets anders?,Noe annet?,Coś innego?,Algo diferente?,,Ceva diferit?,Что-нибудь ещё?,,Något annat?,Farklı bir şey mi var? +Go through the door down the hall.,TXT_RYES3_SCRIPT23_D1516_GOTHR,,,,Jděte dveřmi dole na chodbě.,Gå gennem døren nede ad gangen.,Geh durch die Tür zur Halle.,,,Ve por la puerta pasillo abajo.,,Mene ovesta käytävän päässä.,"Passez par la porte, vers le hall.",Menj át a csarnok végén levő ajtón.,Vai oltre la porta alla fine della stanza.,ホールのドアを通るんだ。,복도를 따라 문을 향해 가보세요.,Ga door de deur aan het einde van de gang.,Gå gjennom døren i gangen.,Przejdź przez drzwi na końcu korytarza.,Passe pela porta lá no salão.,,Intră pe ușa din josul holului.,"Дальше по коридору, за дверью.",,Gå genom dörren i korridoren.,Koridorun sonundaki kapıdan geç. +You must pay if you want to play.,TXT_RNO3_SCRIPT23_D1516_YOUMU,,,,Chceš si hrát? Zaplať.,"Du skal betale, hvis du vil spille.","Du musst bezahlen, wenn du spielen willst.",,,Debes pagar si quieres jugar.,,"Ken leikkiin ryhtyy, se leikistä maksakoon.",Vous devez payer si vous voulez jouer.,Fizetned kell hogy játszhass.,Devi pagare se vuoi giocare.,プレイするなら支払うべきだ。,할려면 돈을 먼저 주세요.,Je moet betalen als je wilt spelen.,Du må betale hvis du vil spille.,"Musisz zapłacić, jeśli chcesz grać.",Você precisa pagar se quiser jogar.,,Trebuie să plătești dacă vrei să joci.,"Любишь играть, люби и платить!",,Du måste betala om du vill spela.,Oynamak istiyorsan ödeme yapmalısın. +What can I get you?,TXT_DLG_SCRIPT23_D3032_WHATC,,,,Co vám mohu nabídnout?,Hvad kan jeg give dig?,Was darf es sein?,,Kion mi donu al vi?,¿Qué puedo ofrecerte?,,Mitä teille saisi olla?,Que puis-je pour vous?,Mit adhatok?,Cosa ti porto?,何をお求めで?,무엇을 드릴까요?,Wat kan ik voor je halen?,Hva vil du ha?,Co mogę ci dać?,O que gostaria?,,Ce pot să-ți aduc?,Что я могу тебе предложить?,,Vad kan jag ge dig?,Sana ne verebilirim? +Leather armor,TXT_RPLY0_SCRIPT23_D3032_LEATH,,,Leather armour,Kožené brnění,En læderrustning,Lederrüstung,,Ledan armaĵon,Armadura de cuero,,Nahkasuojus,Armure de cuir.,Bőr vért,Armatura di cuoio,レザーアーマー,가죽 갑옷,Leren harnas,En skinnrustning.,Skórzaną zbroję.,Armadura de couro,,Armură de piele,Кожаную броню,,En läderrustning,Deri zırh. +"Here it is, citizen.",TXT_RYES0_SCRIPT23_D3032_HEREI,,,,"Tady je, občane.","Her er den, borger.","Hier ist sie, Bürger.",,"Jen ĝi, civitano.","Aquí está, ciudadano.",,"Tästä saat, kansalainen.","Voilà pour vous, citoyen.","Parancsolj, polgártárs.","Ecco qua, cittadino.",どうぞ、お客さん。,"적절히 입으세요, 시민.","Hier is het, burger.","Vær så god, borger.","Oto ona, obywatelu.","Aqui está, cidadão.",,"Aici este, orășene.","Вот она, гражданин.",,"Här är den, medborgare.","İşte burada, vatandaş." There's no charity given here!,TXT_RNO0_SCRIPT23_D3032_THERE,,,,Nejsme charita!,Der gives ingen velgørenhed her!,Hier gibt es nichts umsonst!,,"Ĉi tio ne estas -almozulejo!",¡Aquí no damos limosna!,,Tämä ei ole mikään hyväntekeväisyyspulju!,On n'est pas une charité ici.,"Sajnálom, ez nem jótékonyság.",Non facciamo beneficienza!,これはチャリティーじゃない!,딴 데 가서 구걸하세요!,Er wordt hier geen liefdadigheid gegeven!,Det er ingen veldedighet her!,Nie ma tu dobroczynności!,Aqui não é local de caridade!,,Nu facem caritate aici!,Я благотворительностью не занимаюсь!,,Burada sadaka verilmez! -Metal armor,TXT_RPLY1_SCRIPT23_D3032_METAL,,,Metal armour,Kovové brnění,Metal rustning,Metallrüstung,,Metalan armaĵon,Armadura de metal,,Metallihaarniska,Armure de métal.,Fém vért,Armatura di metallo,メタルアーマー,강철 갑옷,Metalen harnas,Metall rustning,Metalowa zbroja.,Armadura de metal,,Armură de metal,Металлическую броню,,Metal zırh +almozulejo!",¡Aquí no damos limosna!,,Tämä ei ole mikään hyväntekeväisyyspulju!,On n'est pas une charité ici.,"Sajnálom, ez nem jótékonyság.",Non facciamo beneficienza!,これはチャリティーじゃない!,딴 데 가서 구걸하세요!,Er wordt hier geen liefdadigheid gegeven!,Det er ingen veldedighet her!,Nie ma tu dobroczynności!,Aqui não é local de caridade!,,Nu facem caritate aici!,Я благотворительностью не занимаюсь!,,Det finns ingen välgörenhet här!,Burada sadaka verilmez! +Metal armor,TXT_RPLY1_SCRIPT23_D3032_METAL,,,Metal armour,Kovové brnění,Metal rustning,Metallrüstung,,Metalan armaĵon,Armadura de metal,,Metallihaarniska,Armure de métal.,Fém vért,Armatura di metallo,メタルアーマー,강철 갑옷,Metalen harnas,Metall rustning,Metalowa zbroja.,Armadura de metal,,Armură de metal,Металлическую броню,,Metallrustning,Metal zırh An excellent choice citizen.,TXT_RYES1_SCRIPT23_D3032_ANEXC,,,,"Výborná volba, občane.","Et fremragende valg, borger.","Eine exzellente Wahl, Bürger.",,"Bonega elekto, civitano.","Excelente elección, -ciudadano.",,"Erinomainen valinta, kansalainen.","Un excellent choix, citoyen.",Kiváló választás polgártárs.,"Ottima scelta, cittadino.",良い選択だ。,탄탄한 게 잘 보호해준답니다.,Een uitstekende keuze voor de burger.,"Et utmerket valg, borger.",Doskonały wybór obywatelu.,"Excelente escolha, cidadão.",,Excelentă alegere orășene.,"Отличный выбор, гражданин.",,Mükemmel bir seçim vatandaş. +ciudadano.",,"Erinomainen valinta, kansalainen.","Un excellent choix, citoyen.",Kiváló választás polgártárs.,"Ottima scelta, cittadino.",良い選択だ。,탄탄한 게 잘 보호해준답니다.,Een uitstekende keuze voor de burger.,"Et utmerket valg, borger.",Doskonały wybór obywatelu.,"Excelente escolha, cidadão.",,Excelentă alegere orășene.,"Отличный выбор, гражданин.",,"Ett utmärkt val, medborgare.",Mükemmel bir seçim vatandaş. You don't have enough for this!,TXT_RNO1_SCRIPT23_D3032_YOUDO,,,,Na to nemáte dost peněz!,Du har ikke nok til dette!,Du hast nich genug Gold dafür!,,"Vi ne havas -sufiĉe da mono!",¡No te alcanza!,,Sinulla ei rahat riitä siihen!,Vous n'avez pas assez d'argent.,Nincs elég ehhez nálad!,Non hai abbastanza soldi per questo!,これでは足りない!,돈이 부족합니다. 다른 건 어떠신가요?,Je hebt hier niet genoeg voor!,Du har ikke nok til dette!,Nie masz na to dość!,Você não tem o suficiente para isto!,,Nu ai suficiente fonduri pentru asta!,У тебя недостаточно денег!,,Bunun için yeterli değilsin! -Environmental suit,TXT_RPLY2_SCRIPT23_D3032_ENVIR,,,,Ochranný oblek,Miljødragt,Schutzanzug.,,Medi-ŝirman veston,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison Hazmat.,Védő ruha,Tuta ambientale,耐環境スーツ,환경 방호복,Beschermend Pak,Miljødrakt,Kombinezon ekologiczny,Traje de proteção,,Costum de Protecție împotriva Mediului,Защитный костюм,,Çevre kıyafeti -Here you are.,TXT_RYES2_SCRIPT23_D3032_HEREY,,,,Tady máte.,Her er du.,Bitteschön.,,Jen.,Aquí tienes.,,Olkaa hyvä.,Voilà pour vous.,Parancsolj.,Eccoti qui.,どうぞ。,여기 받으세요!,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici este.,Держи.,,İşte buradasın. +sufiĉe da mono!",¡No te alcanza!,,Sinulla ei rahat riitä siihen!,Vous n'avez pas assez d'argent.,Nincs elég ehhez nálad!,Non hai abbastanza soldi per questo!,これでは足りない!,돈이 부족합니다. 다른 건 어떠신가요?,Je hebt hier niet genoeg voor!,Du har ikke nok til dette!,Nie masz na to dość!,Você não tem o suficiente para isto!,,Nu ai suficiente fonduri pentru asta!,У тебя недостаточно денег!,,Du har inte tillräckligt för detta!,Bunun için yeterli değilsin! +Environmental suit,TXT_RPLY2_SCRIPT23_D3032_ENVIR,,,,Ochranný oblek,Miljødragt,Schutzanzug.,,Medi-ŝirman veston,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison Hazmat.,Védő ruha,Tuta ambientale,耐環境スーツ,환경 방호복,Beschermend Pak,Miljødrakt,Kombinezon ekologiczny,Traje de proteção,,Costum de Protecție împotriva Mediului,Защитный костюм,,Miljödräkt,Çevre kıyafeti +Here you are.,TXT_RYES2_SCRIPT23_D3032_HEREY,,,,Tady máte.,Her er du.,Bitteschön.,,Jen.,Aquí tienes.,,Olkaa hyvä.,Voilà pour vous.,Parancsolj.,Eccoti qui.,どうぞ。,여기 받으세요!,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici este.,Держи.,,Här är du.,İşte buradasın. "No money, no suit.",TXT_RNO2_SCRIPT23_D3032_NOMON,,,,Bez peněz pro oděvy nelez.,"Ingen penge, ingen dragt.","Kein Geld, kein Anzug.",,"Sen mono -ne estas vesto.",Sin dinero no hay traje.,,"Ei rahaa, ei pukua.","Pas d'argent, pas de combi.","Ha nincs pénz, nincs védőruha.","Niente denaro, niente completo.",金が無いならスーツは無しだ。,방호복을 사기엔 돈이 부족합니다.,"Geen geld, geen pak.","Ingen penger, ingen drakt.","Nie ma pieniędzy, nie ma kombinezonu.","Sem dinheiro, sem traje.",,"Niciun ban, niciun costum.","Нет денег, нет костюма.",,"Para yok, takım elbise yok." -How can I help you today?,TXT_DLG_SCRIPT23_D4548_HOWCA,,,,S čím vám mohu dnes pomoci?,Hvordan kan jeg hjælpe dig i dag?,Wie kann ich dir heute weiterhelfen?,,Kiel mi helpu vin hodiaŭ?,¿Cómo puedo ayudarte hoy?,,Miten voin tänään olla avuksi?,Comment puis-je vous aider aujourd'hui?,Miben segíthetek ezen a szép napon?,Come posso aiutarti oggi?,本日は何の用で?,환영합니다. 뭔가 필요하신지요?,Hoe kan ik u vandaag helpen?,Hvordan kan jeg hjelpe deg i dag?,Jak mogę ci dziś pomóc?,Como posso ajudá-lo hoje?,,Cu ce te pot ajuta azi?,Чем я могу тебе помочь сегодня?,,Bugün size nasıl yardımcı olabilirim? -Med patch,TXT_RPLY0_SCRIPT23_D4548_MEDPA,,,,Obvazy,Medicinsk plaster,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekäärettä,Pansement.,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinplaster,Bandaż,Compressa médica,,Bandaj medical,Бинтами,,İlaç yaması -Here's your patch.,TXT_RYES0_SCRIPT23_D4548_HERES,,,,Tady jsou.,Her er dit plaster.,Hier ist deine Bandage.,,Jen viaj kuracbendoj,Aquí tienes tus tiritas.,Aquí tienes tus curitas.,Tässä kääreesi.,Voilà votre pansement.,Itt a tapaszod.,Ecco le tue bende.,これが貴方のパッチです。,의료 붕대 하나. 경마한 부상에 쓰시길.,Hier is je patch.,Her er plasteret ditt.,Oto twój bandaż.,Aqui está sua compressa.,,Aici e bandajul.,Вот твой набор бинтов.,,İşte yaman. -That is 15 gold my friend.,TXT_RNO0_SCRIPT23_D4548_THATI,,,,"Ty stojí patnáct zlatých, příteli.","Det er 15 guld, min ven.","Das macht 15 Gold, mein Freund.",,"Ili kostas 15 da oro, amiko.","Son 15 de oro, amigo.",,"Se maksaa 15 kolikkoa, ystäväiseni.","15 pièces pour ça, mon ami.",15 arany lesz barátocskám.,Sono 15 pezzi d'oro amico mio.,これは15ゴールドですよ。,15 골드가 없습니까? 유감이군요.,"Dat is 15 goud, mijn vriend.","Det er 15 gull, min venn.","To jest 15 złota, mój przyjacielu.","Custa 15 moedas de ouro, meu amigo.",,E 15 monezi prietene.,"Они стоят 15 монет, друг.",,Bu 15 altın dostum. -Medical kit,TXT_RPLY1_SCRIPT23_D4548_MEDIC,,,,Lékárničku,Medicinsk kit,Verbandskasten,,Sukurkesto,Botiquín,,Lääkintälaukku,Kit médical.,Elsősegély doboz,Kit medico,医療用キット,구급 키트,Medische kit,Medisinsk utstyr,Zestaw medyczny,Kit médico,,Kit medical,Аптечкой,,Tıbbi kit -Here's your medical kit.,TXT_RYES1_SCRIPT23_D4548_HERES,,,,Tady je.,Her er dit medicinske kit.,Hier ist dein Verbandskasten,,Jen via sukurkesto.,Aquí tienes tu botiquín.,,Tässä lääkintälaukkusi.,Voilà votre kit médical.,Itt az elsősegély dobozod.,Ecco il tuo kid medico.,これが貴方のキットです。,구급 키트는 아주 유용하죠. 잘 쓰시길!,Hier is je medische uitrusting.,Her er medisinskrinet ditt.,Oto twój zestaw medyczny.,Aqui está o seu kit médico,,Aici e kitul medical.,Вот твоя аптечка.,,İşte tıbbi çantan. -Your a bit low on funds for that.,TXT_RNO1_SCRIPT23_D4548_YOURA,,,,Na tu nemáte dost.,Du har lidt for få midler til det.,Du hast zu wenig Geld dafür.,,Mankas mono al vi.,Estás algo falto de dinero.,,Rahasi eivät ihan riitä siihen.,Vous manquez d'argent pour ça.,Kevés lesz a pénzed ehhez most.,Sei un pò a corto di fondi per quello.,お金が少し足りませんよ。,돈이 부족하군요. 못 줍니다!,Je hebt daar een beetje weinig geld voor.,Du har litt lite penger til det.,Trochę brakuje ci na to funduszy.,Você está um pouco mal de dinheiro pra isso.,,Cam puțini bani pentru aia.,Тебе на это не хватает средств.,,Bunun için biraz az paran var. -Field surgery kit,TXT_RPLY2_SCRIPT23_D4548_FIELD,,,,Chirurgickou soupravu,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kenttäkirurgilaukku,Kit de chirurgie.,Harctéri műtéti felszerelés,Kit chirurgico,手術キット,수술 키트,Veld chirurgie kit,Kirurgisett,Zestaw do chirurgii polowej,Kit de cirurgia,,Kit chirurgical de teren.,Медкомплектом,,Saha ameliyat kiti -One field surgery kit.,TXT_RYES2_SCRIPT23_D4548_ONEFI,,,,Jedna souprava.,Et kirurgisæt.,"Eine Erste-Hilfe-Kasten, kommt sofort.",,Kirurgia kesto. Farite.,Un kit quirúrgico. Listo.,,"Yksi kirurgilaukku, tässä.","Un kit de chirurgie, voilà.","Parancsolj, egy műtéti felszerelés.","Un kit chirurgico, eccolo qua.",手術キット一丁。,아주 위박한 상황에 쓰시길. 여기 수술 키트입니다!,Een veldoperatiekit.,Ett kirurgisk sett.,Jeden zestaw do chirurgii polowej.,Um kit de cirurgia.,,"Un kit chirurgical de teren, gata.",Один медкомплект. Держи.,,Bir saha ameliyat kiti. +ne estas vesto.",Sin dinero no hay traje.,,"Ei rahaa, ei pukua.","Pas d'argent, pas de combi.","Ha nincs pénz, nincs védőruha.","Niente denaro, niente completo.",金が無いならスーツは無しだ。,방호복을 사기엔 돈이 부족합니다.,"Geen geld, geen pak.","Ingen penger, ingen drakt.","Nie ma pieniędzy, nie ma kombinezonu.","Sem dinheiro, sem traje.",,"Niciun ban, niciun costum.","Нет денег, нет костюма.",,"Inga pengar, ingen dräkt.","Para yok, takım elbise yok." +How can I help you today?,TXT_DLG_SCRIPT23_D4548_HOWCA,,,,S čím vám mohu dnes pomoci?,Hvordan kan jeg hjælpe dig i dag?,Wie kann ich dir heute weiterhelfen?,,Kiel mi helpu vin hodiaŭ?,¿Cómo puedo ayudarte hoy?,,Miten voin tänään olla avuksi?,Comment puis-je vous aider aujourd'hui?,Miben segíthetek ezen a szép napon?,Come posso aiutarti oggi?,本日は何の用で?,환영합니다. 뭔가 필요하신지요?,Hoe kan ik u vandaag helpen?,Hvordan kan jeg hjelpe deg i dag?,Jak mogę ci dziś pomóc?,Como posso ajudá-lo hoje?,,Cu ce te pot ajuta azi?,Чем я могу тебе помочь сегодня?,,Hur kan jag hjälpa dig i dag?,Bugün size nasıl yardımcı olabilirim? +Med patch,TXT_RPLY0_SCRIPT23_D4548_MEDPA,,,,Obvazy,Medicinsk plaster,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekäärettä,Pansement.,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinplaster,Bandaż,Compressa médica,,Bandaj medical,Бинтами,,Medicinsk plåster,İlaç yaması +Here's your patch.,TXT_RYES0_SCRIPT23_D4548_HERES,,,,Tady jsou.,Her er dit plaster.,Hier ist deine Bandage.,,Jen viaj kuracbendoj,Aquí tienes tus tiritas.,Aquí tienes tus curitas.,Tässä kääreesi.,Voilà votre pansement.,Itt a tapaszod.,Ecco le tue bende.,これが貴方のパッチです。,의료 붕대 하나. 경마한 부상에 쓰시길.,Hier is je patch.,Her er plasteret ditt.,Oto twój bandaż.,Aqui está sua compressa.,,Aici e bandajul.,Вот твой набор бинтов.,,Här är ditt plåster.,İşte yaman. +That is 15 gold my friend.,TXT_RNO0_SCRIPT23_D4548_THATI,,,,"Ty stojí patnáct zlatých, příteli.","Det er 15 guld, min ven.","Das macht 15 Gold, mein Freund.",,"Ili kostas 15 da oro, amiko.","Son 15 de oro, amigo.",,"Se maksaa 15 kolikkoa, ystäväiseni.","15 pièces pour ça, mon ami.",15 arany lesz barátocskám.,Sono 15 pezzi d'oro amico mio.,これは15ゴールドですよ。,15 골드가 없습니까? 유감이군요.,"Dat is 15 goud, mijn vriend.","Det er 15 gull, min venn.","To jest 15 złota, mój przyjacielu.","Custa 15 moedas de ouro, meu amigo.",,E 15 monezi prietene.,"Они стоят 15 монет, друг.",,"Det är 15 guld, min vän.",Bu 15 altın dostum. +Medical kit,TXT_RPLY1_SCRIPT23_D4548_MEDIC,,,,Lékárničku,Medicinsk kit,Verbandskasten,,Sukurkesto,Botiquín,,Lääkintälaukku,Kit médical.,Elsősegély doboz,Kit medico,医療用キット,구급 키트,Medische kit,Medisinsk utstyr,Zestaw medyczny,Kit médico,,Kit medical,Аптечкой,,Medicinsk utrustning,Tıbbi kit +Here's your medical kit.,TXT_RYES1_SCRIPT23_D4548_HERES,,,,Tady je.,Her er dit medicinske kit.,Hier ist dein Verbandskasten,,Jen via sukurkesto.,Aquí tienes tu botiquín.,,Tässä lääkintälaukkusi.,Voilà votre kit médical.,Itt az elsősegély dobozod.,Ecco il tuo kid medico.,これが貴方のキットです。,구급 키트는 아주 유용하죠. 잘 쓰시길!,Hier is je medische uitrusting.,Her er medisinskrinet ditt.,Oto twój zestaw medyczny.,Aqui está o seu kit médico,,Aici e kitul medical.,Вот твоя аптечка.,,Här är ditt medicinska utrustning.,İşte tıbbi çantan. +Your a bit low on funds for that.,TXT_RNO1_SCRIPT23_D4548_YOURA,,,,Na tu nemáte dost.,Du har lidt for få midler til det.,Du hast zu wenig Geld dafür.,,Mankas mono al vi.,Estás algo falto de dinero.,,Rahasi eivät ihan riitä siihen.,Vous manquez d'argent pour ça.,Kevés lesz a pénzed ehhez most.,Sei un pò a corto di fondi per quello.,お金が少し足りませんよ。,돈이 부족하군요. 못 줍니다!,Je hebt daar een beetje weinig geld voor.,Du har litt lite penger til det.,Trochę brakuje ci na to funduszy.,Você está um pouco mal de dinheiro pra isso.,,Cam puțini bani pentru aia.,Тебе на это не хватает средств.,,Du har inte så mycket pengar för det.,Bunun için biraz az paran var. +Field surgery kit,TXT_RPLY2_SCRIPT23_D4548_FIELD,,,,Chirurgickou soupravu,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kenttäkirurgilaukku,Kit de chirurgie.,Harctéri műtéti felszerelés,Kit chirurgico,手術キット,수술 키트,Veld chirurgie kit,Kirurgisett,Zestaw do chirurgii polowej,Kit de cirurgia,,Kit chirurgical de teren.,Медкомплектом,,Fältkirurgisk utrustning,Saha ameliyat kiti +One field surgery kit.,TXT_RYES2_SCRIPT23_D4548_ONEFI,,,,Jedna souprava.,Et kirurgisæt.,"Eine Erste-Hilfe-Kasten, kommt sofort.",,Kirurgia kesto. Farite.,Un kit quirúrgico. Listo.,,"Yksi kirurgilaukku, tässä.","Un kit de chirurgie, voilà.","Parancsolj, egy műtéti felszerelés.","Un kit chirurgico, eccolo qua.",手術キット一丁。,아주 위박한 상황에 쓰시길. 여기 수술 키트입니다!,Een veldoperatiekit.,Ett kirurgisk sett.,Jeden zestaw do chirurgii polowej.,Um kit de cirurgia.,,"Un kit chirurgical de teren, gata.",Один медкомплект. Держи.,,Ett fältkirurgiskt utrustning.,Bir saha ameliyat kiti. Come back when you have money!,TXT_RNO2_SCRIPT23_D4548_COMEB,,,,"Vrať se, až budeš mít peníze!","Kom tilbage, når du har penge!","Komm wieder, wenn du etwas Geld hast.",,"Revenu kiam vi havos monon!","¡Vuelve cuando -tengas dinero!",,"Tule takaisin, kun sinulla on rahaa!",Revenez quand vous avez des sous?,"Akkor gyere vissza, ha pénzed is lesz!",Torna quando avrai del denaro!,お金が有る時にまた!,"돈이 많이 있으면 모를까, 살 수 없을겁니다!",Kom terug als je geld hebt!,Kom tilbake når du har penger!,"Wróć, gdy będziesz miał pieniądze!",Volte quando tiver dinheiro!,,Revino când o să ai bani!,Возвращайся с деньгами!,,Paran olduğunda geri gel! -"Hello friend, what can I get you?",TXT_DLG_SCRIPT23_D6064_HELLO,,,,"Zdravím, příteli, co pro vás mohu udělat?","Hej ven, hvad kan jeg give dig?","Hallo Freund, was darf es sein?",,,"Hola amigo, ¿Qué puedo ofrecerte?",,"Tervehdys, ystävä; miten voin olla avuksi?","Bienvenu, l'ami, que puis-je pour vous?","Szevasz barátom, miben segíthetek?","Salve amico, cosa posso darti?",よう旦那、何が必要だ?,좋은 하루! 뭐 필요한거라도?,"Hallo vriend, wat kan ik voor je halen?","Hei venn, hva kan jeg gi deg?","Witaj przyjacielu, co mogę ci dać?","Olá amigo, como posso te ajudar?",,"Bună prietene, ce pot să-ți aduc?","Привет, друг. Могу я тебе что-нибудь предложить?",,"Merhaba arkadaşım, sana ne getirebilirim?" -Information,TXT_RPLY0_SCRIPT23_D6064_INFOR,,,,Informace,Information,Informationen,,,Información,,Tietoa.,Des infos.,Információ,Informazioni,情報,정보 있습니까?,Informatie,Informasjon.,Informacje,Informações,,Informație,Информацию,,Bilgi +tengas dinero!",,"Tule takaisin, kun sinulla on rahaa!",Revenez quand vous avez des sous?,"Akkor gyere vissza, ha pénzed is lesz!",Torna quando avrai del denaro!,お金が有る時にまた!,"돈이 많이 있으면 모를까, 살 수 없을겁니다!",Kom terug als je geld hebt!,Kom tilbake når du har penger!,"Wróć, gdy będziesz miał pieniądze!",Volte quando tiver dinheiro!,,Revino când o să ai bani!,Возвращайся с деньгами!,,Kom tillbaka när du har pengar!,Paran olduğunda geri gel! +"Hello friend, what can I get you?",TXT_DLG_SCRIPT23_D6064_HELLO,,,,"Zdravím, příteli, co pro vás mohu udělat?","Hej ven, hvad kan jeg give dig?","Hallo Freund, was darf es sein?",,,"Hola amigo, ¿Qué puedo ofrecerte?",,"Tervehdys, ystävä; miten voin olla avuksi?","Bienvenu, l'ami, que puis-je pour vous?","Szevasz barátom, miben segíthetek?","Salve amico, cosa posso darti?",よう旦那、何が必要だ?,좋은 하루! 뭐 필요한거라도?,"Hallo vriend, wat kan ik voor je halen?","Hei venn, hva kan jeg gi deg?","Witaj przyjacielu, co mogę ci dać?","Olá amigo, como posso te ajudar?",,"Bună prietene, ce pot să-ți aduc?","Привет, друг. Могу я тебе что-нибудь предложить?",,"Hej vän, vad vill du ha?","Merhaba arkadaşım, sana ne getirebilirim?" +Information,TXT_RPLY0_SCRIPT23_D6064_INFOR,,,,Informace,,Informationen,,,Información,,Tietoa.,Des infos.,Információ,Informazioni,情報,정보 있습니까?,Informatie,Informasjon.,Informacje,Informações,,Informație,Информацию,,,Bilgi "I've never seen anyone go in or out of the factory, the forcefield's always up.",TXT_RYES0_SCRIPT23_D6064_IVENE,,,,Nikdy jsem nikoho neviděl vcházet do ani vycházet z továrny. Silové pole je vždycky zapnuté.,"Jeg har aldrig set nogen gå ind eller ud af fabrikken, kraftfeltet er altid oppe.","Ich habe noch niemanden gesehen, der die Fabrik betreten oder verlassen hat. Das Kraftfeld ist immer aktiv.",,,"Nunca he visto a nadie entrar o salir de la fábrica, el campo de fuerza siempre está encendido.",,En ole nähnyt kenenkään koskaan menevän tai tulevan tehtaasta; voimakenttä on aina päällä.,Je n'ai jamais vu quelqu'un rentrer dans l'usine. Les champs de force sont toujours en ligne.,"Nem láttam még senkit ki- vagy be menni a gyárból, az erőpajzs mindig be van kapcsolva.","Non ho mai visto nessuno entrare o uscire dalla fabbrica, il campo di forza è sempre attivo.","誰も工場を出入りしている所を見ていない、 -フォースフィールドがずっと付いてる。",공장에서 나오는 사람들을 전혀 못 봤어. 방어막이 꺼지는 일이 없었으니까.,"Ik heb nog nooit iemand in of uit de fabriek zien gaan, het krachtveld is altijd in orde.","Jeg har aldri sett noen gå inn eller ut av fabrikken, kraftfeltet er alltid oppe.","Nigdy nie widziałem nikogo wchodzącego ani wychodzącego z fabryki, pole siłowe jest zawsze podniesione.",Nunca vi alguém entrar ou sair da fábrica. O campo de força está sempre ativado.,,"N-am văzut niciodată pe cineva intrând sau ieșind din fabrică, câmpul de forță e mereu activ.","Никогда не видел, чтобы кто-нибудь приходил или уходил с фабрики. Поле всегда включено.",,"Kimsenin fabrikaya girip çıktığını görmedim, güç alanı her zaman açık." -"No money, no info.",TXT_RNO0_SCRIPT23_D6064_NOMON,,,,"Žádné peníze, žádné informace.","Ingen penge, ingen info.","Kein Geld, keine Informationen.",,,Sin dinero no hay información.,,"Ei tuohta, ei tietoa.","Pas d'argent, pas d'infos.","Ha nincs pénz, nincs infó.","Niente denaro, niente informazioni.",金が無いなら情報は無しだ。,"돈 없으면, 정보도 없다네.","Geen geld, geen informatie.","Ingen penger, ingen informasjon.","Nie ma pieniędzy, nie ma informacji.","Sem grana, nada de informações.",,"Niciun ban, nicio informație.",Нет денег — нет сведений.,,"Para yok, bilgi yok." -"Yes, what would you like?",TXT_DLG_SCRIPT23_D7580_YESWH,,,,"Ano, co byste si přál?","Ja, hvad vil du gerne have?","Ja, was darf es sein?",,,"Sí, ¿Qué quieres?",,"Niin, mitä saisi olla?","Oui, que voulez-vous?","Igen, milyen érdekelne?","Sì, che posso darti?",はい、どうしたい?,"아, 무엇을 원하는가?","Ja, wat wil je graag?","Ja, hva vil du ha?","Tak, czego chcesz?","Sim, o que você gostaria?",,"Da, ce ai dori?",Да? Что ты хотел?,,"Evet, ne istiyorsunuz?" -More info.,TXT_RPLY0_SCRIPT23_D7580_MOREI,,,,Další informace.,Mere info.,Mehr Informationen.,,,Más información.,,Lisää tietoa.,Plus d'infos.,Több információ.,Più informazioni.,更なる情報,정보가 필요해요.,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multă informație.,Ещё сведений.,,Daha fazla bilgi. +フォースフィールドがずっと付いてる。",공장에서 나오는 사람들을 전혀 못 봤어. 방어막이 꺼지는 일이 없었으니까.,"Ik heb nog nooit iemand in of uit de fabriek zien gaan, het krachtveld is altijd in orde.","Jeg har aldri sett noen gå inn eller ut av fabrikken, kraftfeltet er alltid oppe.","Nigdy nie widziałem nikogo wchodzącego ani wychodzącego z fabryki, pole siłowe jest zawsze podniesione.",Nunca vi alguém entrar ou sair da fábrica. O campo de força está sempre ativado.,,"N-am văzut niciodată pe cineva intrând sau ieșind din fabrică, câmpul de forță e mereu activ.","Никогда не видел, чтобы кто-нибудь приходил или уходил с фабрики. Поле всегда включено.",,"Jag har aldrig sett någon gå in eller ut ur fabriken, kraftfältet är alltid uppe.","Kimsenin fabrikaya girip çıktığını görmedim, güç alanı her zaman açık." +"No money, no info.",TXT_RNO0_SCRIPT23_D6064_NOMON,,,,"Žádné peníze, žádné informace.","Ingen penge, ingen info.","Kein Geld, keine Informationen.",,,Sin dinero no hay información.,,"Ei tuohta, ei tietoa.","Pas d'argent, pas d'infos.","Ha nincs pénz, nincs infó.","Niente denaro, niente informazioni.",金が無いなら情報は無しだ。,"돈 없으면, 정보도 없다네.","Geen geld, geen informatie.","Ingen penger, ingen informasjon.","Nie ma pieniędzy, nie ma informacji.","Sem grana, nada de informações.",,"Niciun ban, nicio informație.",Нет денег — нет сведений.,,"Inga pengar, ingen information.","Para yok, bilgi yok." +"Yes, what would you like?",TXT_DLG_SCRIPT23_D7580_YESWH,,,,"Ano, co byste si přál?","Ja, hvad vil du gerne have?","Ja, was darf es sein?",,,"Sí, ¿Qué quieres?",,"Niin, mitä saisi olla?","Oui, que voulez-vous?","Igen, milyen érdekelne?","Sì, che posso darti?",はい、どうしたい?,"아, 무엇을 원하는가?","Ja, wat wil je graag?","Ja, hva vil du ha?","Tak, czego chcesz?","Sim, o que você gostaria?",,"Da, ce ai dori?",Да? Что ты хотел?,,"Ja, vad vill du ha?","Evet, ne istiyorsunuz?" +More info.,TXT_RPLY0_SCRIPT23_D7580_MOREI,,,,Další informace.,Mere info.,Mehr Informationen.,,,Más información.,,Lisää tietoa.,Plus d'infos.,Több információ.,Più informazioni.,更なる情報,정보가 필요해요.,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multă informație.,Ещё сведений.,,Mer information.,Daha fazla bilgi. The factory's built on the comet's impact site. I don't think it's by chance.,TXT_RYES0_SCRIPT23_D7580_THEFA,,,,"Továrnu postavili na místě dopadu komety. Nemyslím si, že to je náhoda.","Fabrikken er bygget på kometens nedslagssted. Jeg tror ikke, det er tilfældigt.","Die Fabrik wurde dort gebaut, wo der Komet eingeschlagen ist. Ich denke nicht, dass das Zufall ist.",,,La fábrica está construida sobre el lugar de impacto del cometa. No creo que sea casualidad.,,"Tehdas on rakennettu komeetan törmäyspaikalle; enkä usko, että sattumalta.",L'usine est construite sur le site d'impact de la comète. Je ne crois pas que c'est une coïncidence.,A gyár a becsapódott üstökösre épült. Biztosan nem lehet véletlen.,La fabbrica è stata costruita sopra il sito d'impatto della cometa. Non credo sia una coincidenza.,"工場は彗星の衝突地点に建っている。 -これは偶然だと思えない。",공장은 혜성이 충돌한 지점에서 건설되었다네. 우연으로 건설된 게 아니라고 생각해.,De fabriek is gebouwd op de impact van de komeet site. Ik denk niet dat het toeval is.,Fabrikken er bygget på kometens nedslagssted. Jeg tror ikke det er tilfeldig.,"Fabryka została zbudowana na miejscu uderzenia komety. Nie sądzę, żeby to był przypadek.",A fábrica foi construída no local de impacto do cometa. Não acho que tenha sido por acaso.,,Fabrica e construită pe locul de prăbușire al cometei. Nu cred că e o coincidență.,"Фабрика была построена в кратере от падения метеорита. Не думаю, что это случайность.",,Fabrika kuyruklu yıldızın çarpma alanına inşa edildi. Bunun tesadüf olduğunu sanmıyorum. -"Come on, it's a measly 5 gold.",TXT_RNO0_SCRIPT23_D7580_COMEO,,,,"No tak, chci pouhých pět zlatých.","Kom nu, det er sølle 5 guld.","Komm schon, es sind doch nur 5 mickrige Goldstücke.",,,"Venga, solo 5 míseras monedas de oro.",,"Hei, antaisit nyt vaivaiset viisi kolikkoa.","Allez, ça ne coûte que 5 pièces!","Nemár, francos 5 arany.","Andiamo, sono solo 5 pezzi d'oro.",頼むぜ、たった5ゴールドだぞ。,5 골드 정도 하는데 말이지.,"Kom op, het is een miezerige 5 goud.","Kom igjen, det er sølle fem gull.","Daj spokój, to marne 5 złotych.","Vamos lá, custa só 5 moedinhas.",,"Haide, sunt 5 bănuți amărâți.","Ну же, всего-то 5 золотых.",,"Hadi ama, sadece 5 altın." -"Hello again, what'll it be?",TXT_DLG_SCRIPT23_D9096_HELLO,,,,"Opět zdravím, co to bude?","Hej igen, hvad bliver det?",Willkommen zurück. Was darf es sein?,,,"Hola otra vez, ¿Qué va a ser?",,"Hei taas, mitä kaipaat?","Rebonjour, que puis-je pour vous?","Üdv újra itt, mit kérsz?","Chi si rivede, che cosa c'è?",また来たな、何か頼むか?,다시 만났군. 오늘은 어떤 걸?,"Hallo nogmaals, wat zal het zijn?","Hallo igjen, hva skal det være?","Witam ponownie, co to będzie?",Olá de novo. O que vai ser desta vez?,,"Bună din nou, ce dorești?",И снова привет. Что на этот раз?,,"Tekrar merhaba, ne alırdınız?" -More info.,TXT_RPLY0_SCRIPT23_D9096_MOREI,,,,Další informace.,Mere info.,Mehr Informationen.,,,Más información.,,Lisää tietoa.,Plus d'infos.,Több információ.,Altre informazioni,更なる情報,더 많은 정보를 원해요.,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multă informație.,Ещё информацию.,,Daha fazla bilgi. +これは偶然だと思えない。",공장은 혜성이 충돌한 지점에서 건설되었다네. 우연으로 건설된 게 아니라고 생각해.,De fabriek is gebouwd op de impact van de komeet site. Ik denk niet dat het toeval is.,Fabrikken er bygget på kometens nedslagssted. Jeg tror ikke det er tilfeldig.,"Fabryka została zbudowana na miejscu uderzenia komety. Nie sądzę, żeby to był przypadek.",A fábrica foi construída no local de impacto do cometa. Não acho que tenha sido por acaso.,,Fabrica e construită pe locul de prăbușire al cometei. Nu cred că e o coincidență.,"Фабрика была построена в кратере от падения метеорита. Не думаю, что это случайность.",,Fabriken är byggd på kometens nedslagsplats. Jag tror inte att det är en slump.,Fabrika kuyruklu yıldızın çarpma alanına inşa edildi. Bunun tesadüf olduğunu sanmıyorum. +"Come on, it's a measly 5 gold.",TXT_RNO0_SCRIPT23_D7580_COMEO,,,,"No tak, chci pouhých pět zlatých.","Kom nu, det er sølle 5 guld.","Komm schon, es sind doch nur 5 mickrige Goldstücke.",,,"Venga, solo 5 míseras monedas de oro.",,"Hei, antaisit nyt vaivaiset viisi kolikkoa.","Allez, ça ne coûte que 5 pièces!","Nemár, francos 5 arany.","Andiamo, sono solo 5 pezzi d'oro.",頼むぜ、たった5ゴールドだぞ。,5 골드 정도 하는데 말이지.,"Kom op, het is een miezerige 5 goud.","Kom igjen, det er sølle fem gull.","Daj spokój, to marne 5 złotych.","Vamos lá, custa só 5 moedinhas.",,"Haide, sunt 5 bănuți amărâți.","Ну же, всего-то 5 золотых.",,"Kom igen, det är bara 5 guld.","Hadi ama, sadece 5 altın." +"Hello again, what'll it be?",TXT_DLG_SCRIPT23_D9096_HELLO,,,,"Opět zdravím, co to bude?","Hej igen, hvad bliver det?",Willkommen zurück. Was darf es sein?,,,"Hola otra vez, ¿Qué va a ser?",,"Hei taas, mitä kaipaat?","Rebonjour, que puis-je pour vous?","Üdv újra itt, mit kérsz?","Chi si rivede, che cosa c'è?",また来たな、何か頼むか?,다시 만났군. 오늘은 어떤 걸?,"Hallo nogmaals, wat zal het zijn?","Hallo igjen, hva skal det være?","Witam ponownie, co to będzie?",Olá de novo. O que vai ser desta vez?,,"Bună din nou, ce dorești?",И снова привет. Что на этот раз?,,"Hej igen, vad vill du ha?","Tekrar merhaba, ne alırdınız?" +More info.,TXT_RPLY0_SCRIPT23_D9096_MOREI,,,,Další informace.,Mere info.,Mehr Informationen.,,,Más información.,,Lisää tietoa.,Plus d'infos.,Több információ.,Altre informazioni,更なる情報,더 많은 정보를 원해요.,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multă informație.,Ещё информацию.,,Mer information.,Daha fazla bilgi. The factory closed when the Order unveiled its new horror: the Inquisitor.,TXT_RYES0_SCRIPT23_D9096_THEFA,,,,Továrnu zavřeli když Řád odkryl svou novou hrůzu: Inkvizitora.,"Fabrikken lukkede, da Ordenen afslørede sin nye rædsel: Inquisitoren.","Die Fabrik wurde geschlossen, als der Orden seinen neuesten Horror enthült hat: Den Inquisitor.",,,La fábrica cerró cuando la Orden desveló su nuevo horror: el inquisidor.,,"Tehdas suljettiin, kun Veljeskunta paljasti sen uuden kauhistuksen: inkvisiittorin.","L'usine a été fermée quand l'Ordre a révélé sa nouvelle atrocité, L'inquisiteur.","A gyár bezárt, amikor a Rend leleplezte a nagyközönség előtt az új horrorát: az Inkvizítort.",La fabbrica è stata chiusa quando l'Ordine ha rivelato il suo nuovo orrore: l'Inquisitore,"工場はオーダーの「新審問官」が来てから -恐ろしい雰囲気を纏った。",오더가 획기적이고 무서운 병기들을 생산한 후 공장의 문을 닫았다네. 그것들의 이름은 '인퀴지터'지.,De fabriek werd gesloten toen de Orde haar nieuwe horror onthulde: de inquisiteur.,Fabrikken stengte da Ordenen avduket sin nye skrekk: Inkvisitoren.,"Fabryka została zamknięta, gdy Zakon zaprezentował swój nowy horror: Inkwizytora.",A fábrica fechou quando a Ordem revelou o seu novo horror: o Inquisidor.,,Fabrica s-a închis când Ordinul a dezvăluit noua sa oroare: Inchizitorul.,"Фабрика закрылась, когда Орден показал своё новое страшилище — инквизитора.",,"Fabrika, Tarikat yeni dehşeti Cezacı'yı tanıttığında kapandı." -5 gold please.,TXT_RNO0_SCRIPT23_D9096_5GOLD,,,,"Pět zlatých, prosim.","5 guld, tak.","5 Gold, bitte.",,,5 de oro por favor.,,"5 kolikkoa, kiitos.","5 pièces, s'il vous plaît.",5 arany lesz.,"Sono 5 pezzi d'oro, prego.",5ゴールドかかるぜ。,먼저 5 골드를 주게나.,5 goud alsjeblieft.,"5 gull, takk.",Proszę o 5 sztuk złota.,5 moedas por favor.,,5 bani te rog.,"5 золотых, пожалуйста.",,5 altın lütfen. +恐ろしい雰囲気を纏った。",오더가 획기적이고 무서운 병기들을 생산한 후 공장의 문을 닫았다네. 그것들의 이름은 '인퀴지터'지.,De fabriek werd gesloten toen de Orde haar nieuwe horror onthulde: de inquisiteur.,Fabrikken stengte da Ordenen avduket sin nye skrekk: Inkvisitoren.,"Fabryka została zamknięta, gdy Zakon zaprezentował swój nowy horror: Inkwizytora.",A fábrica fechou quando a Ordem revelou o seu novo horror: o Inquisidor.,,Fabrica s-a închis când Ordinul a dezvăluit noua sa oroare: Inchizitorul.,"Фабрика закрылась, когда Орден показал своё новое страшилище — инквизитора.",,Fabriken stängdes när Orden presenterade sin nya skräck: Inkvisitorn.,"Fabrika, Tarikat yeni dehşeti Cezacı'yı tanıttığında kapandı." +5 gold please.,TXT_RNO0_SCRIPT23_D9096_5GOLD,,,,"Pět zlatých, prosim.","5 guld, tak.","5 Gold, bitte.",,,5 de oro por favor.,,"5 kolikkoa, kiitos.","5 pièces, s'il vous plaît.",5 arany lesz.,"Sono 5 pezzi d'oro, prego.",5ゴールドかかるぜ。,먼저 5 골드를 주게나.,5 goud alsjeblieft.,"5 gull, takk.",Proszę o 5 sztuk złota.,5 moedas por favor.,,5 bani te rog.,"5 золотых, пожалуйста.",,"5 guld, tack.",5 altın lütfen. "That's all I know. Even bartenders run out of stuff to say, sorry.",TXT_DLG_SCRIPT23_D10612_THATS,,,,"To je vše, co vím. I barmani občas nemají, co dál říct, promiňte.","Det er alt, hvad jeg ved. Selv bartendere løber tør for ting at sige, undskyld.","Das ist alles was ich weiß. Selbst ein Barkeeper hat irgendwann keine Neugikeiten mehr, tut mir Leid.",,,"Eso es todo lo que sé. Incluso los taberneros se quedan sin cosas que decir, lo siento.",,"Siinä kaikki, mitä tiedän. Jopa baarimikoilta loppuvat jutun aiheet, pahoittelen.","C'est tout ce que je sais. Même les barmans peuvent arriver à court d'infos, désolé.","Ennyit tudok. Még a bárpultos tudása sem végtelen, sajnálom.","È tutto ciò che so. Anche i baristi hanno un limite alla loro conoscienza, mi spiace.","知ってることはこれで全部だ。 -バーテンダーの噂は売切れだ、すまない。",이 바텐더는 꺼낼 수 있는 모든 조언을 꺼냈다네. 미안.,"Dat is alles wat ik weet. Zelfs de barmannen hebben niet veel meer te zeggen, sorry.","Det er alt jeg vet. Selv bartendere går tom for ting å si, beklager.","To wszystko, co wiem. Nawet barmanom kończy się to, co można powiedzieć, przepraszam.","Isso é tudo o que eu sei. Até donos de bar acabam ficando sem algo pra dizer uma hora, sinto muito.",,"Asta e tot ce știu, până și barmanii rămân fără chestii de zis.","Это всё, что я знаю. Даже у хозяев таверн заканчиваются темы для болтовни, увы.",,"Tek bildiğim bu. Barmenlerin bile söyleyecek bir şeyleri kalmadı, üzgünüm." -Hello.,TXT_DLG_SCRIPT23_D12128_HELLO,,,,Ahoj.,Hej.,Hallo.,,Saluton.,Hola.,,Hei.,Bonjour.,Helló.,Ciao.,こんにちは。,안녕하세요.,Hallo.,Hallo.,Witam.,Olá.,,Salut.,Привет.,,Merhaba. -What are you doing?,TXT_RPLY0_SCRIPT23_D12128_WHATA,,,,Co tady děláš?,Hvad laver du?,Was machst du?,,Kion vi faras?,¿Qué estás haciendo?,,Mitä teet?,Qu'est-ce que vous faites?,Mit csinálsz?,Che cosa stai facendo?,何してるんだ?,뭐하는 거죠?,Wat ben je aan het doen?,Hva driver du med?,Co robisz?,O que você está fazendo?,,Ce faci?,Чем ты занимаешься?,,Ne yapıyorsun? -"I'm doing stuff, go away!",TXT_RYES0_SCRIPT23_D12128_IMDOI,,,,"Dělám věci, vypadni!","Jeg laver noget, gå væk!","Ich mach' halt was, geh weg!",,,"Estoy haciendo cosas, ¡Lárgate!",,"Teen juttuja, mene pois!","Je suis occupé, laissez-moi tranquille!","Épp elfoglalt vagyok, tünj innen!","Sto sbrigando delle cose, vattene!",今は立て込んでる、離れなさい!,별거 아닙니다. 방해하지 말고 저리 가세요!,"Ik doe dingen, ga weg!","Jeg gjør ting, gå vekk!","Robię różne rzeczy, odejdź!","Estou fazendo coisas, vá embora!",,"Am treabă, pleacă!",Ерундой всякой. Отвали!,,"Bir şeyler yapıyorum, git başımdan!" -"Now, what can I help you with?",TXT_DLG_SCRIPT23_D13644_NOWWH,,,,"Tak, s čím ti mohu pomoci?",Hvad kan jeg hjælpe dig med?,"Nun, wie kann ich dir weiterhelfen?",,,"Ahora, ¿En qué puedo ayudarte?",,"No niin, miten voin palvella?","Bon, que puis-je pour vous?","Na, miben segíthetek?","E ora, come posso aiutarti?",今手伝ってくれるか?,"자, 제가 뭘 도와드릴까요?","Nu, waar kan ik je mee helpen?",Hva kan jeg hjelpe deg med?,"A teraz, w czym mogę ci pomóc?","Então, como posso ajudá-lo?",,"Acum, cu ce te pot ajuta?","Итак, чем я могу быть тебе полезен?",,"Şimdi, sana nasıl yardımcı olabilirim?" -Shadow armor?,TXT_RPLY0_SCRIPT23_D13644_SHADO,,,Shadow armour?,Stínové brnění?,Skygge rustning?,Schattenrüstung?,,,¿Armadura de sombra?,,Varjohaarniska?,Armure des ombres?,Árnyék vért?,Armatura Ombra?,シャドウアーマー?,그림자 갑옷?,Schaduw harnas?,Skyggepanser?,Zbroja cieni?,Armadura das sombras?,,Armura umbrei?,Теневой бронёй?,,Gölge zırhı mı? -"Ahh, to be heard, but not seen!",TXT_RYES0_SCRIPT23_D13644_AHHTO,,,,"Áha, být slyšen, ne viděn!","Ahh, at blive hørt, men ikke set!","Ah, um gehört zu werden, aber ungesehen zu bleiben.",,,"Ah, ¡para ser oído, pero no visto!",,"Aah, tulla kuulluksi, muttei nähdyksi!","Ah, pour se faire entendre, sans se faire voir!","Csak hallani, de nem látni.","Ahh, per essere sentiti, ma non visti!",ああ、声はすれど姿は見えず。,하하하... 아주 조용하고 보이지 않는 도구죠!,"Ahhh, om gehoord, maar niet gezien te worden!","Å bli hørt, men ikke sett!","Ahh, być słyszanym, ale nie widzianym!","Ahh, ser ouvido mas não ser visto!",,"Ahh, să fii auzit, dar nu văzut!","Ах, чтобы быть услышанным, но не увиденным!",,"Ahh, duyulmak ama görülmemek!" -"Get out of here, come back when you have some cash.",TXT_RNO0_SCRIPT23_D13644_GETOU,,,,"Vypadni a vrať se, když budeš mít peníze.","Forsvind herfra, kom tilbage når du har nogle penge.","Verzieh dich, komm wieder, wenn du etwas Geld hast.",,,"Vete de aquí, vuelve cuando tengas algo de efectivo.",,"Antaa vetää; tule takaisin, kun sinulla on käteistä.","Sortez de là, revenez quand vous avez de l'argent!","Na kotródj innen, csak akkor lássalak ha van nálad pénz is.","Fuori di qui, ritorna quando avrai del denaro.",ここを出て、稼いでからまた来てくれ!,"저리 가, 돈이 있을 때나 여길 찾으라고요.","Ga hier weg, kom terug als je wat geld hebt.","Kom deg ut herfra, kom tilbake når du har penger.","Wynoś się stąd, wróć jak będziesz miał trochę kasy.",Vá embora daqui. Volte quando tiver dinheiro.,,"Cară-te, întoarce-te când ai bani.","Выметайся вон. Вернёшься, когда раздобудешь наличности.",,"Git buradan, biraz paran olduğunda geri gel." +バーテンダーの噂は売切れだ、すまない。",이 바텐더는 꺼낼 수 있는 모든 조언을 꺼냈다네. 미안.,"Dat is alles wat ik weet. Zelfs de barmannen hebben niet veel meer te zeggen, sorry.","Det er alt jeg vet. Selv bartendere går tom for ting å si, beklager.","To wszystko, co wiem. Nawet barmanom kończy się to, co można powiedzieć, przepraszam.","Isso é tudo o que eu sei. Até donos de bar acabam ficando sem algo pra dizer uma hora, sinto muito.",,"Asta e tot ce știu, până și barmanii rămân fără chestii de zis.","Это всё, что я знаю. Даже у хозяев таверн заканчиваются темы для болтовни, увы.",,"Det är allt jag vet. Till och med bartender får slut på saker att säga, tyvärr.","Tek bildiğim bu. Barmenlerin bile söyleyecek bir şeyleri kalmadı, üzgünüm." +Hello.,TXT_DLG_SCRIPT23_D12128_HELLO,,,,Ahoj.,Hej.,Hallo.,,Saluton.,Hola.,,Hei.,Bonjour.,Helló.,Ciao.,こんにちは。,안녕하세요.,Hallo.,Hallo.,Witam.,Olá.,,Salut.,Привет.,,Hej.,Merhaba. +What are you doing?,TXT_RPLY0_SCRIPT23_D12128_WHATA,,,,Co tady děláš?,Hvad laver du?,Was machst du?,,Kion vi faras?,¿Qué estás haciendo?,,Mitä teet?,Qu'est-ce que vous faites?,Mit csinálsz?,Che cosa stai facendo?,何してるんだ?,뭐하는 거죠?,Wat ben je aan het doen?,Hva driver du med?,Co robisz?,O que você está fazendo?,,Ce faci?,Чем ты занимаешься?,,Vad gör du?,Ne yapıyorsun? +"I'm doing stuff, go away!",TXT_RYES0_SCRIPT23_D12128_IMDOI,,,,"Dělám věci, vypadni!","Jeg laver noget, gå væk!","Ich mach' halt was, geh weg!",,,"Estoy haciendo cosas, ¡Lárgate!",,"Teen juttuja, mene pois!","Je suis occupé, laissez-moi tranquille!","Épp elfoglalt vagyok, tünj innen!","Sto sbrigando delle cose, vattene!",今は立て込んでる、離れなさい!,별거 아닙니다. 방해하지 말고 저리 가세요!,"Ik doe dingen, ga weg!","Jeg gjør ting, gå vekk!","Robię różne rzeczy, odejdź!","Estou fazendo coisas, vá embora!",,"Am treabă, pleacă!",Ерундой всякой. Отвали!,,"Jag gör saker, försvinn!","Bir şeyler yapıyorum, git başımdan!" +"Now, what can I help you with?",TXT_DLG_SCRIPT23_D13644_NOWWH,,,,"Tak, s čím ti mohu pomoci?",Hvad kan jeg hjælpe dig med?,"Nun, wie kann ich dir weiterhelfen?",,,"Ahora, ¿En qué puedo ayudarte?",,"No niin, miten voin palvella?","Bon, que puis-je pour vous?","Na, miben segíthetek?","E ora, come posso aiutarti?",今手伝ってくれるか?,"자, 제가 뭘 도와드릴까요?","Nu, waar kan ik je mee helpen?",Hva kan jeg hjelpe deg med?,"A teraz, w czym mogę ci pomóc?","Então, como posso ajudá-lo?",,"Acum, cu ce te pot ajuta?","Итак, чем я могу быть тебе полезен?",,Vad kan jag hjälpa dig med?,"Şimdi, sana nasıl yardımcı olabilirim?" +Shadow armor?,TXT_RPLY0_SCRIPT23_D13644_SHADO,,,Shadow armour?,Stínové brnění?,Skygge rustning?,Schattenrüstung?,,,¿Armadura de sombra?,,Varjohaarniska?,Armure des ombres?,Árnyék vért?,Armatura Ombra?,シャドウアーマー?,그림자 갑옷?,Schaduw harnas?,Skyggepanser?,Zbroja cieni?,Armadura das sombras?,,Armura umbrei?,Теневой бронёй?,,Skuggarmering?,Gölge zırhı mı? +"Ahh, to be heard, but not seen!",TXT_RYES0_SCRIPT23_D13644_AHHTO,,,,"Áha, být slyšen, ne viděn!","Ahh, at blive hørt, men ikke set!","Ah, um gehört zu werden, aber ungesehen zu bleiben.",,,"Ah, ¡para ser oído, pero no visto!",,"Aah, tulla kuulluksi, muttei nähdyksi!","Ah, pour se faire entendre, sans se faire voir!","Csak hallani, de nem látni.","Ahh, per essere sentiti, ma non visti!",ああ、声はすれど姿は見えず。,하하하... 아주 조용하고 보이지 않는 도구죠!,"Ahhh, om gehoord, maar niet gezien te worden!","Å bli hørt, men ikke sett!","Ahh, być słyszanym, ale nie widzianym!","Ahh, ser ouvido mas não ser visto!",,"Ahh, să fii auzit, dar nu văzut!","Ах, чтобы быть услышанным, но не увиденным!",,"Ahh, att höras men inte ses!","Ahh, duyulmak ama görülmemek!" +"Get out of here, come back when you have some cash.",TXT_RNO0_SCRIPT23_D13644_GETOU,,,,"Vypadni a vrať se, když budeš mít peníze.","Forsvind herfra, kom tilbage når du har nogle penge.","Verzieh dich, komm wieder, wenn du etwas Geld hast.",,,"Vete de aquí, vuelve cuando tengas algo de efectivo.",,"Antaa vetää; tule takaisin, kun sinulla on käteistä.","Sortez de là, revenez quand vous avez de l'argent!","Na kotródj innen, csak akkor lássalak ha van nálad pénz is.","Fuori di qui, ritorna quando avrai del denaro.",ここを出て、稼いでからまた来てくれ!,"저리 가, 돈이 있을 때나 여길 찾으라고요.","Ga hier weg, kom terug als je wat geld hebt.","Kom deg ut herfra, kom tilbake når du har penger.","Wynoś się stąd, wróć jak będziesz miał trochę kasy.",Vá embora daqui. Volte quando tiver dinheiro.,,"Cară-te, întoarce-te când ai bani.","Выметайся вон. Вернёшься, когда раздобудешь наличности.",,"Försvinn härifrån, kom tillbaka när du har lite pengar.","Git buradan, biraz paran olduğunda geri gel." "Thank Deus you got here. To enter the factory you need a key. We stole it but our agent is missing in the web of catacombs under the Order's stronghold. I have sent ten good men into those tunnels to find him, and none have returned. Something is down there!",TXT_DLG_SCRIPT23_D15160_THANK,,,,"Díky bohu, žes přišel. Aby ses dostal do továrny, potřebuješ klíč. Ten jsme ukradli, ale náš agent se ztratil v sítí katakomb pod pevností Řádu. Poslal jsem do těch tunelů deset dobrých mužů a žádný se nevrátil. Něco tam dole je!","Tak Deus for at du kom her. For at komme ind på fabrikken skal du bruge en nøgle. Vi stjal den, men vores agent er forsvundet i katakomberne under ordenens højborg. Jeg har sendt ti gode mænd ned i disse tunneller for at finde ham, men ingen er vendt tilbage. Der er noget dernede!","Deus sei dank bist du hier. Um die Fabrik zu betreten, brauchst du einen Schlüssel. Wir haben ihn gestohlen, aber unser Agent ist in den Irrwegen der Katakomben unter der Festung des Ordens verschollen. Ich habe zehn gute Männer da hinunter geschickt um ihn zu finden, aber niemand ist zurückgekehrt. Irgendetwas ist da unten!",,,"Gracias a deus que estás aquí. Para entrar en la fábrica necesitas una llave. La robamos, pero nuestro agente está perdido en la red de catacumbas debajo de la fortaleza de la Orden. He enviado diez buenos hombres a esos túneles para encontrarlo, y ninguno ha regresado. ¡Hay algo ahí abajo!",,"Luojan kiitos, että selvisit perille. Päästäksesi sisälle tehtaaseen tarvitset avaimen. Varastimme sen, mutta vakoojamme on eksynyt Veljeskunnan linnakkeen alapuolella sijaitsevaan katakombiverkostoon. Olen lähettänyt tunneleihin 10 kelpoa miestä etsimään häntä, eikä kukaan ole palannut. Jokin on siellä alla!","Merci Dieu, vous êtes là. Pour entrer dans l'usine, il vous faut une clé. On l'a volé, mais notre agent a disparu dans le dédale de catacombes sous la forteresse de l'Ordre. On a envoyé dix hommes dans ces tunnels pour le retrouver mais personne n'est revenu. Il doit y avoir quelque chose, là dedans!","Hála Deusnak, ideértél.Ahhoz, hogy bejuthass a gyárba kell majd egy kulcs. Habár sikerült ellopnunk a kulcsot, az ügynökünk elveszett a katakombák sűrűjében a Rend erődítménye alatt. Leküldtem tíz jó emberemet utána, de egyikük sem tért vissza. Valami borzasztó lehet ott lent!","Grazie a Dio sei arrivato. Per entrare nella fabbrica ti servirà una chiave. L'abbiamo rubata ma l'agente che l'ha presa è sparito nelle catacombe sotto la fortezza dell'Ordine. Ho mandato dieci uomini in quei tunnel a trovarlo, e nessuno è ritornato. C'è qualcosa là sotto!","ようやく来てくれたか。 工場に入るためには鍵が必要だ。 鍵は盗んだのだが、我々の密偵が砦地下にある 地下墓所で行方不明になった。 彼を探すため10名派遣したのだが、 誰一人帰ってこなかった。 -地下墓地で何か異変が起こっているに違いない。","데우스님 감사합니다, 지원군이 왔군! 공장에 들어가려면 열쇠가 필요합니다. 그 열쇠를 가진 한 요원이 오더의 요새가 있는 고대 무덤에서 길을 잃었습니다. 지원군 10 명을 보내긴 했으나 돌아오지 못했습니다. 그곳에 무언가가 있는 것 같아요!","Bedankt Deus dat je hier bent gekomen. Om de fabriek binnen te komen heb je een sleutel nodig. We hebben het gestolen maar onze agent ontbreekt in het web van de catacomben onder het bolwerk van de Orde. Ik heb tien goede mannen in die tunnels gestuurd om hem te vinden, en niemand is teruggekomen. Er is daar beneden iets!","Takk Gud for at du kom hit. For å komme inn i fabrikken trenger du en nøkkel. Vi stjal den, men agenten vår er forsvunnet i katakombene under Ordenens festning. Jeg har sendt ti gode menn ned i tunnelene for å finne ham, men ingen har kommet tilbake. Det er noe der nede!","Dziękuję Deusowi, że tu trafiłeś. Aby wejść do fabryki potrzebny jest klucz. Ukradliśmy go, ale nasz agent zaginął w sieci katakumb pod twierdzą Zakonu. Wysłałem dziesięciu dobrych ludzi do tych tuneli, by go znaleźli, ale żaden nie wrócił. Coś jest tam na dole!",Graças a Deus que você está aqui. Para entrar na fábrica você precisa de uma chave. Nós a roubamos mas nosso agente desapareceu na rede de catacumbas debaixo da fortaleza da Ordem. Mandei dez homens capazes pra dentro desses túneis para encontrá-lo e ninguém retornou. Tem alguma coisa lá embaixo!,,"Slavă Domnului că ești aici. Ca să intri în fabrică ai nevoie de o cheie. Am furat-o dar agentul nostru a dispărut în rețeaua catacombelor fortăreței Ordinului. Am trimis zece oameni pricepuți după el, dar niciunul nu s-a întors. Ceva se întâmplă acolo!","Хвала господу, ты добрался сюда. Тебе нужен ключ, чтобы проникнуть на фабрику. Мы выкрали его, но наш агент пропал в сети катакомб под крепостью Ордена. Чтобы разыскать его, я послал в эти туннели десять хороших бойцов, и ни один не вернулся. Там внизу что-то есть!",,Buraya geldiğin için Deus'a şükret. Fabrikaya girmek için bir anahtara ihtiyacınız var. Onu çaldık ama ajanımız Tarikat'ın kalesinin altındaki yeraltı mezarlarında kayıp. Onu bulmaları için o tünellere on iyi adam gönderdim ama hiçbiri geri dönmedi. Aşağıda bir şey var! -What is it? Human or... ?,TXT_RPLY0_SCRIPT23_D15160_WHATI,,,,"Co to je? Člověk, nebo...?",Hvad er det? Menneske eller... ?,Was ist es? Mensch oder...?,,,¿Qué es? ¿Humano o...?,,Mikä se on? Ihminen vai...,"Qu'est-ce que c'est? Un humain, où...",Mi lehet? Ember vagy...?,Che cosa è? Umano o... ?,それは一体?人間か...?,그게 뭐죠? 사람? 아니면... ?,Wat is het? Menselijk of.... ?,Hva er det? Menneskelig eller... ?,Co to jest? Człowiek czy... ?,O que é? É humano ou... ?,,Ce e? Uman sau... ?,Что это? Человек или...?,,Ne var orada? İnsan mı yoksa... ? +地下墓地で何か異変が起こっているに違いない。","데우스님 감사합니다, 지원군이 왔군! 공장에 들어가려면 열쇠가 필요합니다. 그 열쇠를 가진 한 요원이 오더의 요새가 있는 고대 무덤에서 길을 잃었습니다. 지원군 10 명을 보내긴 했으나 돌아오지 못했습니다. 그곳에 무언가가 있는 것 같아요!","Bedankt Deus dat je hier bent gekomen. Om de fabriek binnen te komen heb je een sleutel nodig. We hebben het gestolen maar onze agent ontbreekt in het web van de catacomben onder het bolwerk van de Orde. Ik heb tien goede mannen in die tunnels gestuurd om hem te vinden, en niemand is teruggekomen. Er is daar beneden iets!","Takk Gud for at du kom hit. For å komme inn i fabrikken trenger du en nøkkel. Vi stjal den, men agenten vår er forsvunnet i katakombene under Ordenens festning. Jeg har sendt ti gode menn ned i tunnelene for å finne ham, men ingen har kommet tilbake. Det er noe der nede!","Dziękuję Deusowi, że tu trafiłeś. Aby wejść do fabryki potrzebny jest klucz. Ukradliśmy go, ale nasz agent zaginął w sieci katakumb pod twierdzą Zakonu. Wysłałem dziesięciu dobrych ludzi do tych tuneli, by go znaleźli, ale żaden nie wrócił. Coś jest tam na dole!",Graças a Deus que você está aqui. Para entrar na fábrica você precisa de uma chave. Nós a roubamos mas nosso agente desapareceu na rede de catacumbas debaixo da fortaleza da Ordem. Mandei dez homens capazes pra dentro desses túneis para encontrá-lo e ninguém retornou. Tem alguma coisa lá embaixo!,,"Slavă Domnului că ești aici. Ca să intri în fabrică ai nevoie de o cheie. Am furat-o dar agentul nostru a dispărut în rețeaua catacombelor fortăreței Ordinului. Am trimis zece oameni pricepuți după el, dar niciunul nu s-a întors. Ceva se întâmplă acolo!","Хвала господу, ты добрался сюда. Тебе нужен ключ, чтобы проникнуть на фабрику. Мы выкрали его, но наш агент пропал в сети катакомб под крепостью Ордена. Чтобы разыскать его, я послал в эти туннели десять хороших бойцов, и ни один не вернулся. Там внизу что-то есть!",,"Tacka Deus för att du kom hit. För att komma in i fabriken behöver du en nyckel. Vi stal den, men vår agent saknas i katakomberna under Ordensfästet. Jag har skickat tio goda män in i tunnlarna för att hitta honom, men ingen har återvänt. Något finns där nere!",Buraya geldiğin için Deus'a şükret. Fabrikaya girmek için bir anahtara ihtiyacınız var. Onu çaldık ama ajanımız Tarikat'ın kalesinin altındaki yeraltı mezarlarında kayıp. Onu bulmaları için o tünellere on iyi adam gönderdim ama hiçbiri geri dönmedi. Aşağıda bir şey var! +What is it? Human or... ?,TXT_RPLY0_SCRIPT23_D15160_WHATI,,,,"Co to je? Člověk, nebo...?",Hvad er det? Menneske eller... ?,Was ist es? Mensch oder...?,,,¿Qué es? ¿Humano o...?,,Mikä se on? Ihminen vai...,"Qu'est-ce que c'est? Un humain, où...",Mi lehet? Ember vagy...?,Che cosa è? Umano o... ?,それは一体?人間か...?,그게 뭐죠? 사람? 아니면... ?,Wat is het? Menselijk of.... ?,Hva er det? Menneskelig eller... ?,Co to jest? Człowiek czy... ?,O que é? É humano ou... ?,,Ce e? Uman sau... ?,Что это? Человек или...?,,Vad är det? Mänskligt eller... ?,Ne var orada? İnsan mı yoksa... ? "Not. Definitely not. Whatever it is, you must fight it to retrieve the key. I'll open the catacombs' entrance. When you've got it, the factory is next to the mines. Hurry, each second counts.",TXT_DLG_SCRIPT23_D16676_NOTDE,,,,"Ne. Rozhodně ne. Ať je to cokoliv, musíš se s tím utkat, abys získal ten klíč zpět. Otevřu ti vchod do katakomb. Až ho budeš mít, továrna je vedle dolů. Pospěš si, každá vteřina se počítá.","Nej. Helt sikkert ikke. Uanset hvad det er, skal du kæmpe mod det for at få nøglen tilbage. Jeg åbner katakombernes indgang. Når du har fået den, er fabrikken ved siden af minerne. Skynd dig, hvert sekund tæller.","Nein. Definitiv nicht. Was auch immer es ist, du musst es bekämpfen, um an den Schlüssel zu kommen. Ich werde den Eingang zu den Katakomben öffnen. Wenn du ihn hast, die Fabrik ist direkt neben den Minen. Beeil dich, jede Sekunde zählt.",,,"No. Definitivamente no. Sea lo que sea, debes luchar contra eso para recuperar la llave. Abriré la entrada a las catacumbas. Cuando la tengas, la fábrica está junto a las minas. Date prisa, cada segundo cuenta.",,"Ei, ei varmana. Mikä ikinä se onkaan, sinun on kohdattava se noutaaksesi avaimen. Avaan katakombien sisäänkäynnin. Kun se on hallussasi, tehdas on kaivoksen vieressä. Pidä kiirettä, jokainen sekunti merkitsee.","Non, absolument pas. Je ne sais pas ce que c'est, mais il faudra s'en débarasser pour récupérer la clé. Je vais ouvrir l'entrée des catacombes. Quand vous êtes à l'intérieur, l'usine est près des ruines. Vite, chaque seconde compte.","Nem. Biztos, hogy nem. Akármi is az, meg kell majd küzdened vele a kulcsért. Kinyitom a katakomba bejáratát. Ha megszerezted, a gyár ott lesz a bánya mellett. Siess, minden másodperc számít.","No. Sicuramente no. Qualsiasi cosa sia, dovrai lottare per riavere la chiave. Adesso aprirò l'entrata per le catacombe. Quando avrai ripreso la chiave, potrai accedere alla fabbrica, che si trova accanto alle miniere. Sbrigati, ogni secondo può fare la differenza.","いや。人間の仕業だとはとても思えない。 それが何であれ君は鍵を取り戻せ。 地下墓所への入り口は開けておこう。 鍵を手に入れたら、工場は採掘所の隣にある。 -時間はあまり無いから急ぐのだ。","아냐. 사람 같은 건 절대로 아니라고. 그게 무엇이든, 당신은 어떻게든 싸워서 열쇠를 돌려받아야 합니다. 고대 무덤의 입구를 열어두겠습니다. 만약 열쇠를 얻으셨다면, 광산 옆에 있는 공장으로 향하시길 바랍니다. 시간이 얼마 남지 않았습니다!","Niet. Zeker niet. Wat het ook is, je moet ertegen vechten om de sleutel terug te krijgen. Ik zal de ingang van de catacomben openen. Als je hem hebt, staat de fabriek naast de mijnen. Schiet op, elke seconde telt.","Nei. Definitivt ikke. Uansett hva det er, må du kjempe mot det for å få tak i nøkkelen. Jeg åpner inngangen til katakombene. Når du har den, er fabrikken ved siden av gruvene. Skynd deg, hvert sekund teller.","Nie. Zdecydowanie nie. Cokolwiek to jest, musisz z tym walczyć, aby odzyskać klucz. Ja otworzę wejście do katakumb. Gdy go zdobędziesz, fabryka jest obok kopalni. Spiesz się, liczy się każda sekunda.","Não. Definitivamente não é. Seja lá o que for, você deve enfrentá-lo para recuperar a chave. Vou abrir a entrada das catacumbas. Quando você pegar a chave, vá para a fábrica próxima às minas. Depressa, cada segundo é importante.",,"Nu. Cu siguranță nu. Orice ar fi, va trebui să o înfrunți pentru a recupera cheia. Voi deschide intrarea catacombelor. Când o ai, fabrica e vizavi de mine. Grăbește-te, orice secundă contează.","Нет. Определённо нет. Что бы это ни было, ты должен сразиться с ним, чтобы заполучить ключ. Я открою вход в катакомбы. Когда добудешь его, направляйся на фабрику: она находится рядом со входом в шахты. Торопись! Дорога каждая секунда!",,"İnsan değil. Kesinlikle değil. O her neyse, anahtarı almak için onunla savaşmalısın. Yeraltı mezarlarının girişini açacağım. Anahtarı aldığında, fabrika madenlerin yanında. Acele et, her saniye önemli." -"Something inhuman, eh?, great.",TXT_RPLY0_SCRIPT23_D16676_SOMET,,,,"Něco nelidského, co? Skvělý.","Noget umenneskeligt, hva'?, fedt.",Irgendetwas unmenschliches? Na großartig.,,,"Algo inhumano, ¿eh?, genial.",,"Jotain epäinhimillistä, vai? Hienoa.","Quelque chose d'inhumain, hein? Parfait.","Valami nem emberi, mi? Csodás.","Qualcosa di inumano, eh? Fantastico.",非人道的な何か?流石だな。,비인간적인 녀석인가요? 좋군요.,"Iets onmenselijks, eh?, geweldig.","Noe umenneskelig, hva? Flott!","Coś nieludzkiego, ech, świetnie.","Algo não-humano, é? Que ótimo.",,"Ceva inuman, ei? Grozav.",Что-то иное? Просто отлично.,,"İnsanlık dışı bir şey, ha? Harika." +時間はあまり無いから急ぐのだ。","아냐. 사람 같은 건 절대로 아니라고. 그게 무엇이든, 당신은 어떻게든 싸워서 열쇠를 돌려받아야 합니다. 고대 무덤의 입구를 열어두겠습니다. 만약 열쇠를 얻으셨다면, 광산 옆에 있는 공장으로 향하시길 바랍니다. 시간이 얼마 남지 않았습니다!","Niet. Zeker niet. Wat het ook is, je moet ertegen vechten om de sleutel terug te krijgen. Ik zal de ingang van de catacomben openen. Als je hem hebt, staat de fabriek naast de mijnen. Schiet op, elke seconde telt.","Nei. Definitivt ikke. Uansett hva det er, må du kjempe mot det for å få tak i nøkkelen. Jeg åpner inngangen til katakombene. Når du har den, er fabrikken ved siden av gruvene. Skynd deg, hvert sekund teller.","Nie. Zdecydowanie nie. Cokolwiek to jest, musisz z tym walczyć, aby odzyskać klucz. Ja otworzę wejście do katakumb. Gdy go zdobędziesz, fabryka jest obok kopalni. Spiesz się, liczy się każda sekunda.","Não. Definitivamente não é. Seja lá o que for, você deve enfrentá-lo para recuperar a chave. Vou abrir a entrada das catacumbas. Quando você pegar a chave, vá para a fábrica próxima às minas. Depressa, cada segundo é importante.",,"Nu. Cu siguranță nu. Orice ar fi, va trebui să o înfrunți pentru a recupera cheia. Voi deschide intrarea catacombelor. Când o ai, fabrica e vizavi de mine. Grăbește-te, orice secundă contează.","Нет. Определённо нет. Что бы это ни было, ты должен сразиться с ним, чтобы заполучить ключ. Я открою вход в катакомбы. Когда добудешь его, направляйся на фабрику: она находится рядом со входом в шахты. Торопись! Дорога каждая секунда!",,"Inte. Definitivt inte. Vad det än är måste du slåss mot det för att få tag på nyckeln. Jag öppnar katakombernas ingång. När du har fått den är fabriken bredvid gruvorna. Skynda dig, varje sekund räknas.","İnsan değil. Kesinlikle değil. O her neyse, anahtarı almak için onunla savaşmalısın. Yeraltı mezarlarının girişini açacağım. Anahtarı aldığında, fabrika madenlerin yanında. Acele et, her saniye önemli." +"Something inhuman, eh?, great.",TXT_RPLY0_SCRIPT23_D16676_SOMET,,,,"Něco nelidského, co? Skvělý.","Noget umenneskeligt, hva'?, fedt.",Irgendetwas unmenschliches? Na großartig.,,,"Algo inhumano, ¿eh?, genial.",,"Jotain epäinhimillistä, vai? Hienoa.","Quelque chose d'inhumain, hein? Parfait.","Valami nem emberi, mi? Csodás.","Qualcosa di inumano, eh? Fantastico.",非人道的な何か?流石だな。,비인간적인 녀석인가요? 좋군요.,"Iets onmenselijks, eh?, geweldig.","Noe umenneskelig, hva? Flott!","Coś nieludzkiego, ech, świetnie.","Algo não-humano, é? Que ótimo.",,"Ceva inuman, ei? Grozav.",Что-то иное? Просто отлично.,,"Något omänskligt, va?, bra.","İnsanlık dışı bir şey, ha? Harika." You're wasting time and lives! Move!,TXT_DLG_SCRIPT23_D18192_YOURE,,,,Plýtváš časem i životy! Jdi!,Du spilder tid og liv! Af sted!,Du verschwendest Zeit und Leben! Beweg dich!,,,¡Estás perdiendo tiempo y vidas! ¡Muévete!,,Haaskaat aikaa ja henkiä! Liikkuu jo!,Vous perdez votre temps et des vies! Bougez!,Időt és életeket pazarolsz! Mozgás!,"Stai sprecando tempo, e vite. Sbrigati!","こうしてる間にも君は時間と人命を -無駄にしている。行け!",시간과 생명이 위협받고 있다고! 서두르세요!!,Je verspilt tijd en levens! Vooruit!,Du kaster bort tid og liv! Skynd dere!,Marnujesz czas i życie! Ruszać się!,Você está desperdiçando tempo e vidas! Ande logo!,,"Pierzi timp și vieți, mișcă-te!",Ты тратишь время и жизни! Шевелись!,,Zamanınızı ve hayatlarınızı boşa harcıyorsunuz! Çekilin! -Can I be of more help?,TXT_DLG_SCRIPT23_D10612_CANIB,,,,Můžu vám dál pomocI?,Kan jeg være til mere hjælp?,Kann ich dir sonst noch irgendwie helfen?,,,¿Puedo ser de más ayuda?,,Voinko vielä olla avuksi?,Je peux vous aider?,Lehetek még a segítségedre?,Posso aiutarti ancora?,何かお困りでも?,당신의 도움이 더 되어줄 수 있겠습니까?,Kan ik meer hulp bieden?,Kan jeg være til mer hjelp?,Czy mogę być bardziej pomocny?,Posso ajudar com mais alguma coisa?,,Pot fi mai de ajutor?,Могу ли я чем-нибудь помочь?,,Daha fazla yardımcı olabilir miyim? -More info.,TXT_RPLY0_SCRIPT23_D10612_MOREI,,,,Další informace.,Mere info.,Mehr Informationen.,,,Más información.,,Lisää tietoa.,Plus d'infos.,Több információ.,Più informazioni.,更なる情報。,정보 더 있습니까?,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multă informație.,Информацией.,,Daha fazla bilgi. +無駄にしている。行け!",시간과 생명이 위협받고 있다고! 서두르세요!!,Je verspilt tijd en levens! Vooruit!,Du kaster bort tid og liv! Skynd dere!,Marnujesz czas i życie! Ruszać się!,Você está desperdiçando tempo e vidas! Ande logo!,,"Pierzi timp și vieți, mișcă-te!",Ты тратишь время и жизни! Шевелись!,,Du slösar tid och liv! Flytta på dig!,Zamanınızı ve hayatlarınızı boşa harcıyorsunuz! Çekilin! +Can I be of more help?,TXT_DLG_SCRIPT23_D10612_CANIB,,,,Můžu vám dál pomocI?,Kan jeg være til mere hjælp?,Kann ich dir sonst noch irgendwie helfen?,,,¿Puedo ser de más ayuda?,,Voinko vielä olla avuksi?,Je peux vous aider?,Lehetek még a segítségedre?,Posso aiutarti ancora?,何かお困りでも?,당신의 도움이 더 되어줄 수 있겠습니까?,Kan ik meer hulp bieden?,Kan jeg være til mer hjelp?,Czy mogę być bardziej pomocny?,Posso ajudar com mais alguma coisa?,,Pot fi mai de ajutor?,Могу ли я чем-нибудь помочь?,,Kan jag vara till mer hjälp?,Daha fazla yardımcı olabilir miyim? +More info.,TXT_RPLY0_SCRIPT23_D10612_MOREI,,,,Další informace.,Mere info.,Mehr Informationen.,,,Más información.,,Lisää tietoa.,Plus d'infos.,Több információ.,Più informazioni.,更なる情報。,정보 더 있습니까?,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multă informație.,Информацией.,,Mer information.,Daha fazla bilgi. Look for Timothy. I've heard he knows some of the Order's secrets.,TXT_RYES0_SCRIPT23_D10612_LOOKF,,,,"Najděte Timothyho. Slyšel jsem, že ví nějaká tajemství Řádu.","Kig efter Timothy. Jeg har hørt, at han kender nogle af Ordenens hemmeligheder.","Suche Timothy. Ich habe gehört, das er etwas über die Geheimnisse des Ordens weiß.",,,Busca a Timothy. He oído que sabe algo sobre los secretos de la Orden.,,Etsi Timothy. Hän kuulemma tietää joitain Veljeskunnan salaisuuksia.,"Cherchez Timothy, j'entends qu'il sait des secrets de l'Ordre.","Keresd Timothyt. Azt hallotam, Ő tud pár Rend titkot.",Cerca Timothy. Ho sentito che conosce alcuni dei segreti dell'Ordine.,"ティモシーを探せ。彼がオーダーの秘密を -知っていると聞いた。",티모시를 찾아보세요. 제가 듣기론 그가 오더의 비밀들을 알고 있다던데.,Zoek Timothy. Ik heb gehoord dat hij enkele van de geheimen van de Orde kent.,Se etter Timothy. Jeg har hørt at han kjenner noen av Ordenens hemmeligheter.,"Poszukaj Timothy'ego. Słyszałem, że zna niektóre sekrety Zakonu.",Procure por Timothy. Fiquei sabendo que ele conhece alguns segredos da Ordem.,,Uită-te după Timotei. Am auzit că ar cunoaște mai multe secrete ale Ordinului.,"Найди Тимоти. Я слышал, он знает какие-то секреты Ордена.",,Timothy'i ara. Tarikat'ın bazı sırlarını bildiğini duydum. -Just another 5 gold.,TXT_RNO0_SCRIPT23_D10612_JUSTA,,,,Jen dalších pět zlatých.,Bare 5 guld mere.,Nur 5 weitere Goldstücke.,,,Solo otros 5 de oro.,,Vain 5 kolikkoa lisää.,Juste 5 pièces.,Még 5 arany kell.,Giusto altri 5 pezzi d'oro.,たった5ゴールドだぞ。,5 골드만 주세요.,Gewoon nog eens 5 goud.,Bare fem gull til.,Jeszcze tylko 5 złotych.,Só mais 5 moedas.,,Alte 5 monezi.,Всего лишь ещё 5 золотых!,,Sadece 5 altın daha. +知っていると聞いた。",티모시를 찾아보세요. 제가 듣기론 그가 오더의 비밀들을 알고 있다던데.,Zoek Timothy. Ik heb gehoord dat hij enkele van de geheimen van de Orde kent.,Se etter Timothy. Jeg har hørt at han kjenner noen av Ordenens hemmeligheter.,"Poszukaj Timothy'ego. Słyszałem, że zna niektóre sekrety Zakonu.",Procure por Timothy. Fiquei sabendo que ele conhece alguns segredos da Ordem.,,Uită-te după Timotei. Am auzit că ar cunoaște mai multe secrete ale Ordinului.,"Найди Тимоти. Я слышал, он знает какие-то секреты Ордена.",,Leta efter Timothy. Jag har hört att han känner till några av ordens hemligheter.,Timothy'i ara. Tarikat'ın bazı sırlarını bildiğini duydum. +Just another 5 gold.,TXT_RNO0_SCRIPT23_D10612_JUSTA,,,,Jen dalších pět zlatých.,Bare 5 guld mere.,Nur 5 weitere Goldstücke.,,,Solo otros 5 de oro.,,Vain 5 kolikkoa lisää.,Juste 5 pièces.,Még 5 arany kell.,Giusto altri 5 pezzi d'oro.,たった5ゴールドだぞ。,5 골드만 주세요.,Gewoon nog eens 5 goud.,Bare fem gull til.,Jeszcze tylko 5 złotych.,Só mais 5 moedas.,,Alte 5 monezi.,Всего лишь ещё 5 золотых!,,Bara ytterligare 5 guld.,Sadece 5 altın daha. "That's all I know. Even bartenders run out of stuff to say, sorry.",TXT_DLG_SCRIPT23_D12128_THATS,,,,"To je vše, co vím. I barmani občas nemají, co dál říct, promiňte.","Det er alt, hvad jeg ved. Selv bartendere løber tør for ting at sige, undskyld.","Das ist alles was ich weiß. Selbst ein Wirt hat irgendwann keine Neugikeiten mehr, tut mir Leid.",,,"Eso es todo lo que sé. Incluso los taberneros se quedan sin cosas que decir, lo siento.",,"Siinä kaikki tietämäni. Jopa baarimikkojen sanaiset arkut ehtyvät, valitan.","C'est tout ce que je sais. Même les barmans peuvent arriver à court d'infos, désolé.","Ennyit tudok. Még a bárpultos tudása sem végtelen, sajnálom.","È tutto ciò che so. Anche i baristi hanno un limite alla loro conoscienza, mi spiace.","知ってることはこれで全部だ。 -バーテンダーの噂は売切れだ、すまない。",내가 아는 건 그것뿐입니다. 바텐더라도 할 말이 떨어질 수 있다고. 미안해요.,"Dat is alles wat ik weet. Zelfs de barmannen hebben niet veel meer te zeggen, sorry.","Det er alt jeg vet. Selv bartendere går tom for ting å si, beklager.","To wszystko, co wiem. Nawet barmanom kończą się rzeczy do powiedzenia, przepraszam.","Isso é tudo o que eu sei. Até donos de bar acabam ficando sem algo pra dizer uma hora, sinto muito.",,"Asta e tot ce știu, până și barmanii rămân fără chestii de zis.","Это всё, что я знаю. Даже у хозяев таверн заканчиваются темы для болтовни, увы.",,"Tüm bildiğim bu. Barmenlerin bile söyleyecek şeyleri bitiyor, üzgünüm." -Hello.,TXT_DLG_SCRIPT23_D13644_HELLO,,,,Ahoj.,Hej.,Hallo.,,Saluton.,Hola.,,Hei.,Bonjour.,Helló.,Salve.,どうも。,안녕하세요.,Hallo.,Hallo.,Witam.,Olá.,,Salut.,Привет.,,Merhaba. -What are you doing?,TXT_RPLY0_SCRIPT23_D13644_WHATA,,,,Co tady děláš?,Hvad laver du?,Was machst du?,,Kion vi faras?,¿Qué estás haciendo?,,Mitä teet?,Qu'est-ce que vous faites?,Mit művelsz?,Cosa stai facendo?,何してるんだ?,무슨 일을 하고 있는거죠?,Wat ben je aan het doen?,Hva holder du på med?,Co robisz?,O que você está fazendo?,,Ce faci?,Чем ты занимаешься?,,Ne yapıyorsun? -"I'm doing stuff, go away!",TXT_RYES0_SCRIPT23_D13644_IMDOI,,,,"Dělám věci, vypadni!","Jeg laver noget, gå væk!","Ich mach' halt was, geh weg!",,,"Estoy haciendo cosas, ¡Lárgate!",,"Teen juttuja, mene pois!","Je suis occupé, laissez-moi tranquille!","Csinálom a dolgom, menj innen!","Sto sbrigando delle cose, vattene!",今は立て込んでる、離れろ!,그냥 뭘 하고 있습니다. 저리가세요!,"Ik doe dingen, ga weg!","Jeg gjør ting, gå vekk!","Robię różne rzeczy, odejdź!","Estou fazendo coisas, vá embora!",,"Am treabă, pleacă!",Ерундой всякой. Отвали!,,"Bir şeyler yapıyorum, git başımdan!" +バーテンダーの噂は売切れだ、すまない。",내가 아는 건 그것뿐입니다. 바텐더라도 할 말이 떨어질 수 있다고. 미안해요.,"Dat is alles wat ik weet. Zelfs de barmannen hebben niet veel meer te zeggen, sorry.","Det er alt jeg vet. Selv bartendere går tom for ting å si, beklager.","To wszystko, co wiem. Nawet barmanom kończą się rzeczy do powiedzenia, przepraszam.","Isso é tudo o que eu sei. Até donos de bar acabam ficando sem algo pra dizer uma hora, sinto muito.",,"Asta e tot ce știu, până și barmanii rămân fără chestii de zis.","Это всё, что я знаю. Даже у хозяев таверн заканчиваются темы для болтовни, увы.",,"Det är allt jag vet. Till och med bartender får slut på saker att säga, tyvärr.","Tüm bildiğim bu. Barmenlerin bile söyleyecek şeyleri bitiyor, üzgünüm." +Hello.,TXT_DLG_SCRIPT23_D13644_HELLO,,,,Ahoj.,Hej.,Hallo.,,Saluton.,Hola.,,Hei.,Bonjour.,Helló.,Salve.,どうも。,안녕하세요.,Hallo.,Hallo.,Witam.,Olá.,,Salut.,Привет.,,Hej.,Merhaba. +What are you doing?,TXT_RPLY0_SCRIPT23_D13644_WHATA,,,,Co tady děláš?,Hvad laver du?,Was machst du?,,Kion vi faras?,¿Qué estás haciendo?,,Mitä teet?,Qu'est-ce que vous faites?,Mit művelsz?,Cosa stai facendo?,何してるんだ?,무슨 일을 하고 있는거죠?,Wat ben je aan het doen?,Hva holder du på med?,Co robisz?,O que você está fazendo?,,Ce faci?,Чем ты занимаешься?,,Vad gör du?,Ne yapıyorsun? +"I'm doing stuff, go away!",TXT_RYES0_SCRIPT23_D13644_IMDOI,,,,"Dělám věci, vypadni!","Jeg laver noget, gå væk!","Ich mach' halt was, geh weg!",,,"Estoy haciendo cosas, ¡Lárgate!",,"Teen juttuja, mene pois!","Je suis occupé, laissez-moi tranquille!","Csinálom a dolgom, menj innen!","Sto sbrigando delle cose, vattene!",今は立て込んでる、離れろ!,그냥 뭘 하고 있습니다. 저리가세요!,"Ik doe dingen, ga weg!","Jeg gjør ting, gå vekk!","Robię różne rzeczy, odejdź!","Estou fazendo coisas, vá embora!",,"Am treabă, pleacă!",Ерундой всякой. Отвали!,,"Jag gör saker, försvinn!","Bir şeyler yapıyorum, git başımdan!" "If you have this much time to waste, see if you can find the blue chalice. My studies on the Order suggest they have hidden it somewhere in the manufacturing sector of the factory. This artifact would be of great value to me, so, bring it to me, and I'll help you out.",TXT_DLG_SCRIPT23_D15160_IFYOU,,,,"Jestli máš takového volného času, zkus najít modrý kalich. Má pátraní o Řádu naznačují, že je schovaný někde ve výrobním sektoru továrny. Tenhle artifakt by pro mě byl nesmírně cenný, takže jestli mi ho přineseš, pomůžu ti.","Hvis du har så meget tid at spilde, så se om du kan finde den blå bæger. Mine undersøgelser af Ordenen tyder på, at de har gemt den et sted i fabrikkens produktionssektor. Denne artefakt ville være af stor værdi for mig, så bring den til mig, og jeg vil hjælpe dig.","Wenn du so viel Zeit zu verschwenden hast, dann sieh zu, dass du den blauen Kelch finden kannst. Meine Studien über den Orden deuten an, dass er irgendwo im Produktionssektor der Fabrik versteckt sein muss. Dieses Artefakt würde mir viel bedeuten, also bring es mir, und ich werde dir weiterhelfen.",,,"Si tienes tanto tiempo que perder, ve si puedes encontrar el cáliz azul. Mis estudios sobre la Orden sugieren que lo tienen oculto en alguna parte del sector de producción de la fábrica. Este artefacto sería de gran valor para mi, así que, tráemelo, y te ayudaré.",,"Jos sinulla on näin paljon aikaa tuhlattavana, pidä silmäsi auki sinisen uhrimaljan varalta. Tutkimukseni Veljeskunnasta viittaavat siihen, että he ovat kätkeneet sen jonnekin tehtaan tuotanto-osastolla. Esine olisi minulle hyvin arvokas, joten tuo se minulle, ja autan sinua.","Si vous avez autant de temps à perdre, allez voir si vous pouvez récupérer le Calice Bleu. Mes études sur l'Ordre suggèrent qu'ils l'ont caché dans le secteur de manufacture de l'usine. Cet artéfact serait de grande valeur pour moi, amenez-le moi et je vous aiderai.","Ha ilyen őrülten sok időd van, akkor próbáld megkeresni a kék serleget. A kutatásaim azt mutatják, hogy a gyár gyártósoránál van elrejtve. Ez az ereklye nagyon fontos lenne számomra, ha elhozod nekem segítek rajtad.","Se proprio hai così tanto tempo da perdere, vedi se riesci a trovare il calice blu. I miei studi sull'Ordine indiano che lo hanno nascosto da qualche parte del settore manufatturiero della Fabbrica. Questo artifatto mi sarebbe molto utile, quindi se me lo porti, ti potrò aiutare.","アンタがもし時間を浪費するつもりじゃないなら 青の聖杯を見つけられるかどうかを確かめる。 その骨董品は俺にとって非常に価値がある。 -持ってきたら協力しよう。","만약 시간이 남아돈다면, 푸른 성배를 찾아보러 가시는 게 어떤가요? 오더에 대한 제 연구가 맞아떨어진다면, 그것은 분명히 공장의 조립시설에 숨겨져 있을 겁니다. 그 보물은 더 할 말 없이 아주 진귀할 거에요. 그걸 찾아주면, 딱 맞는 보답을 해주지요.","Als je zoveel tijd te verliezen hebt, kijk dan of je de blauwe kelk kunt vinden. Mijn studies over de Orde suggereren dat ze het ergens in de productiesector van de fabriek verborgen hebben. Dit artefact zou van grote waarde zijn voor mij, dus, breng het naar mij, en ik zal je helpen.","Hvis du har så mye tid å kaste bort, se om du kan finne det blå begeret. Mine studier om Ordenen tyder på at de har gjemt det et sted i fabrikkens produksjonssektor. Denne gjenstanden vil være av stor verdi for meg, så ta den med til meg, så skal jeg hjelpe deg.","Jeśli masz tyle czasu do stracenia, sprawdź, czy znajdziesz niebieski kielich. Moje badania nad Zakonem sugerują, że ukryli go gdzieś w sektorze produkcyjnym fabryki. Ten artefakt miałby dla mnie ogromną wartość, więc, przynieś go do mnie, a pomogę ci.","Se você tem tanto tempo livre assim, veja se você consegue achar o cálice azul. Pelo que pesquisei sobre a Ordem, eles o esconderam em algum lugar no setor de manufatura da fábrica. Esse artefato seria de grande valor pra mim, então traga ele para mim e eu te ajudarei.",,"Dacă ai atât de mult timp de pierdut, vezi dacă poți găsi pocalul albastru. Studiile mele indică faptul că Ordinul l-a ascuns undeva în sectorul de manufactură al fabricii. Artefactul mi-ar fi de mare folos, așa că, adu-mi-l, și o să te ajut.","Если тебе не жаль времени, найди синюю чашу. Я изучал Орден и узнал, что они спрятали её где-то в обрабатывающем секторе фабрики. Мне очень нужен этот артефакт. Принеси его мне, и я помогу тебе.",,"Kaybedecek bu kadar zamanın varsa, mavi kadehi bulmaya çalış. Tarikat üzerine yaptığım çalışmalar, onu fabrikanın üretim bölümünde bir yere sakladıklarını gösteriyor. Bu obje benim için çok değerli, bu yüzden onu bana getir, ben de sana yardım edeyim." +持ってきたら協力しよう。","만약 시간이 남아돈다면, 푸른 성배를 찾아보러 가시는 게 어떤가요? 오더에 대한 제 연구가 맞아떨어진다면, 그것은 분명히 공장의 조립시설에 숨겨져 있을 겁니다. 그 보물은 더 할 말 없이 아주 진귀할 거에요. 그걸 찾아주면, 딱 맞는 보답을 해주지요.","Als je zoveel tijd te verliezen hebt, kijk dan of je de blauwe kelk kunt vinden. Mijn studies over de Orde suggereren dat ze het ergens in de productiesector van de fabriek verborgen hebben. Dit artefact zou van grote waarde zijn voor mij, dus, breng het naar mij, en ik zal je helpen.","Hvis du har så mye tid å kaste bort, se om du kan finne det blå begeret. Mine studier om Ordenen tyder på at de har gjemt det et sted i fabrikkens produksjonssektor. Denne gjenstanden vil være av stor verdi for meg, så ta den med til meg, så skal jeg hjelpe deg.","Jeśli masz tyle czasu do stracenia, sprawdź, czy znajdziesz niebieski kielich. Moje badania nad Zakonem sugerują, że ukryli go gdzieś w sektorze produkcyjnym fabryki. Ten artefakt miałby dla mnie ogromną wartość, więc, przynieś go do mnie, a pomogę ci.","Se você tem tanto tempo livre assim, veja se você consegue achar o cálice azul. Pelo que pesquisei sobre a Ordem, eles o esconderam em algum lugar no setor de manufatura da fábrica. Esse artefato seria de grande valor pra mim, então traga ele para mim e eu te ajudarei.",,"Dacă ai atât de mult timp de pierdut, vezi dacă poți găsi pocalul albastru. Studiile mele indică faptul că Ordinul l-a ascuns undeva în sectorul de manufactură al fabricii. Artefactul mi-ar fi de mare folos, așa că, adu-mi-l, și o să te ajut.","Если тебе не жаль времени, найди синюю чашу. Я изучал Орден и узнал, что они спрятали её где-то в обрабатывающем секторе фабрики. Мне очень нужен этот артефакт. Принеси его мне, и я помогу тебе.",,"Om du har så mycket tid att slösa, se om du kan hitta den blå bägaren. Mina studier om orden tyder på att de har gömt den någonstans i fabrikens tillverkningssektor. Denna artefakt skulle vara av stort värde för mig, så, ta med den till mig så ska jag hjälpa dig.","Kaybedecek bu kadar zamanın varsa, mavi kadehi bulmaya çalış. Tarikat üzerine yaptığım çalışmalar, onu fabrikanın üretim bölümünde bir yere sakladıklarını gösteriyor. Bu obje benim için çok değerli, bu yüzden onu bana getir, ben de sana yardım edeyim." "You found the blue chalice! OK, give it to me first, and we'll trade.",TXT_DLG_SCRIPT23_D16676_YOUFO,,,,"Tys našel modrý kalich! Dobře, nejprv mi ho dej a vyrovnáme se.","Du har fundet den blå bæger! OK, giv mig den først, så kan vi bytte.","Du hast den blauen Kelch gefunden! Ok, erst gibst du ihn mir, dann handeln wir.",,,"¡Has encontrado el cáliz azul! Ok, dámelo primero, y negociamos.",,"Löysit sinisen maljan! No niin, anna se ensin minulle, niin tehdään vaihtokaupat.","Vous avez le Calice Bleu! Ok, donnez le moi et nous échangerons.","Megszerezted a kék serleget! OK, add ide gyorsan először, aztán üzletelhetünk.","Hai trovato il calice blu! OK, dammelo, e poi possiamo trattare.","青の聖杯を見つけたのか! -良し、それをくれたら取引に応じよう。",푸른 성배를 정말로 찾으셨군요! 저에게 주세요. 그럼 거래를 시작하죠!,"Je hebt de blauwe kelk gevonden! Oké, geef hem eerst aan mij, dan ruilen we hem.","Du fant det blå begeret! OK, gi det til meg først, så bytter vi.","Znalazłeś niebieski kielich! OK, daj mi go najpierw, a wymienimy się.","Você achou o cálice azul! Ok, me dê ele primeiro e aí a gente negocia.",,"Ai găsit pocalul albastru! OK, dă-mi-l, și o să facem schimb.","Ты нашёл синюю чашу! Отдай её мне, и я исполню свою часть договора.",,"Mavi kadehi bulmuşsun! Tamam, önce onu bana ver, sonra takas ederiz." -"Take it, it's bad luck anyway.",TXT_RPLY0_SCRIPT23_D16676_TAKEI,,,,"Vem si ho, stejně přináší jen smůlu.","Tag den, den bringer alligevel uheld.","Nimm ihn, er bringt sowieso Unglück.",,,"Toma, de todos modos da mala suerte.",,"Ota se, epäonnenkalu se kuitenkin on.","Gardez le, je parie qu'il file malchance.","Vidd nyugodtan, rossz szerencsét hoz amúgyis.","Prendilo, tanto porta sfortuna.",渡そう、兎に角運が悪かった。,여기 받아요. 재수 없어 보이니까.,"Neem het, het is toch al pech.","Ta det, det bringer ulykke uansett.","Weź go, to i tak przynosi pecha.",Pode pegar. Isso atrai azar de qualquer forma.,,"Ia-l, poartă ghinion oricum.",Держи. Она всё равно приносит несчастье.,,"Al, zaten kötü şans getirir." -"Screw you, I'm keeping it.",TXT_RPLY1_SCRIPT23_D16676_SCREW,,,,"Jdi se vycpat, nechám si ho.","Rend mig, jeg beholder den.","Ach, was soll's. Ich behalte ihn.",,,"Que te zurzan, me lo quedo.","Al diablo, me lo quedo.","Vedä käteen, pidän sen itselläni.","Allez vous faire voir, il est à moi maintenant.","Nagy francot, inkább megtartom.",E invece me lo tengo!,ふざけるな、俺の物だ。,"배 째시지, 이건 이제 제거에요.","Krijg de klere, ik hou het.","Faen ta deg, jeg beholder det.","Wal się, zatrzymuję go.","Vá se ferrar, ele é meu.",,"Du-te naibi, îl păstrez.",Пошёл ты! Я оставлю её себе.,,"Siktir git, bende kalacak." -Then I'm not giving you anything. Get lost!,TXT_RYES1_SCRIPT23_D16676_THENI,,,,Pak ti nic nedám. Zmizni!,Så giver jeg dig ikke noget. Forsvind!,Dann bekommst du auch nichts von mir. Verzieh dich!,,,Entonces no te voy a dar nada. ¡Piérdete!,,Sitten en anna sinulle mitään. Antaa vetää!,"Rien pour vous, alors, dégagez!",Akkor meg tudod mikor adok neked bármit is. Húzzál elfelé!,E allora non ti darò niente. Sparisci!,何もやるモンは無いぞ。失せな!,이런 식으로 나가시겠다? 그럼 거래를 취소하죠. 사라지세요!,Dan geef ik je niets. Donder op!,Da gir jeg deg ingenting. Forsvinn!,Więc nic ci nie dam. Spadaj!,Então não te darei nada. Se manda!,,Atunci nu îți dau nimic. Valea!,Тогда я тебе ничего не скажу. Убирайся!,,O zaman sana hiçbir şey vermiyorum. Kaybol! +良し、それをくれたら取引に応じよう。",푸른 성배를 정말로 찾으셨군요! 저에게 주세요. 그럼 거래를 시작하죠!,"Je hebt de blauwe kelk gevonden! Oké, geef hem eerst aan mij, dan ruilen we hem.","Du fant det blå begeret! OK, gi det til meg først, så bytter vi.","Znalazłeś niebieski kielich! OK, daj mi go najpierw, a wymienimy się.","Você achou o cálice azul! Ok, me dê ele primeiro e aí a gente negocia.",,"Ai găsit pocalul albastru! OK, dă-mi-l, și o să facem schimb.","Ты нашёл синюю чашу! Отдай её мне, и я исполню свою часть договора.",,"Du har hittat den blå bägaren! Okej, ge den till mig först så byter vi.","Mavi kadehi bulmuşsun! Tamam, önce onu bana ver, sonra takas ederiz." +"Take it, it's bad luck anyway.",TXT_RPLY0_SCRIPT23_D16676_TAKEI,,,,"Vem si ho, stejně přináší jen smůlu.","Tag den, den bringer alligevel uheld.","Nimm ihn, er bringt sowieso Unglück.",,,"Toma, de todos modos da mala suerte.",,"Ota se, epäonnenkalu se kuitenkin on.","Gardez le, je parie qu'il file malchance.","Vidd nyugodtan, rossz szerencsét hoz amúgyis.","Prendilo, tanto porta sfortuna.",渡そう、兎に角運が悪かった。,여기 받아요. 재수 없어 보이니까.,"Neem het, het is toch al pech.","Ta det, det bringer ulykke uansett.","Weź go, to i tak przynosi pecha.",Pode pegar. Isso atrai azar de qualquer forma.,,"Ia-l, poartă ghinion oricum.",Держи. Она всё равно приносит несчастье.,,"Ta den, den betyder ändå otur.","Al, zaten kötü şans getirir." +"Screw you, I'm keeping it.",TXT_RPLY1_SCRIPT23_D16676_SCREW,,,,"Jdi se vycpat, nechám si ho.","Rend mig, jeg beholder den.","Ach, was soll's. Ich behalte ihn.",,,"Que te zurzan, me lo quedo.","Al diablo, me lo quedo.","Vedä käteen, pidän sen itselläni.","Allez vous faire voir, il est à moi maintenant.","Nagy francot, inkább megtartom.",E invece me lo tengo!,ふざけるな、俺の物だ。,"배 째시지, 이건 이제 제거에요.","Krijg de klere, ik hou het.","Faen ta deg, jeg beholder det.","Wal się, zatrzymuję go.","Vá se ferrar, ele é meu.",,"Du-te naibi, îl păstrez.",Пошёл ты! Я оставлю её себе.,,"Dra åt helvete, jag behåller den.","Siktir git, bende kalacak." +Then I'm not giving you anything. Get lost!,TXT_RYES1_SCRIPT23_D16676_THENI,,,,Pak ti nic nedám. Zmizni!,Så giver jeg dig ikke noget. Forsvind!,Dann bekommst du auch nichts von mir. Verzieh dich!,,,Entonces no te voy a dar nada. ¡Piérdete!,,Sitten en anna sinulle mitään. Antaa vetää!,"Rien pour vous, alors, dégagez!",Akkor meg tudod mikor adok neked bármit is. Húzzál elfelé!,E allora non ti darò niente. Sparisci!,何もやるモンは無いぞ。失せな!,이런 식으로 나가시겠다? 그럼 거래를 취소하죠. 사라지세요!,Dan geef ik je niets. Donder op!,Da gir jeg deg ingenting. Forsvinn!,Więc nic ci nie dam. Spadaj!,Então não te darei nada. Se manda!,,Atunci nu îți dau nimic. Valea!,Тогда я тебе ничего не скажу. Убирайся!,,Då ger jag dig ingenting. Försvinn!,O zaman sana hiçbir şey vermiyorum. Kaybol! Locate the forge. The information I just gave you should help you enter a secretive sector of the factory. One of the forge workers can open the door.,TXT_DLG_SCRIPT23_D18192_LOCAT,,,,"Najdi slévárnu. Informace, které jsem ti právě dal, ti pomůžou vstoupit do tajného sektoru továrny. Jeden z pracovníků slévárny ti otevře dveře.","Find smedjen. De oplysninger, jeg lige har givet dig, skulle hjælpe dig med at komme ind i en hemmelig sektor af fabrikken. En af smediearbejderne kan åbne døren.","Finde die Schmiede. Die Informationen, die ich dir gegeben habe, sollten dir helfen einen geheimen Sektor der Fabrik zu betreten. Einer der Schmiedearbeiter kann dir helfen die Tür zu öffnen.",,,Localiza la forja. La información que te he dado debería ayudarte a entrar a un sector secreto de la fábrica. Uno de los trabajadores de la forja puede abrir la puerta.,,Suunnista pajalle. Juuri antamani tiedon pitäisi auttaa sinua pääsemään salamyhkäiseen osastoon tehtaalla. Yksi pajan työntekijöistä voi avata oven.,Localisez la forge. L'information que je vous ai donnée devrait vous aider à entrer dans une section secrète de l'usine. L'un des travailleurs de la forge peut ouvrir la porte pour vous.,"Keresd meg a kohót. Az információ amit adtam, segíteni fog abban, hogy megleld a gyár titkos részét. Az egyik kohóban dolgozó ki tudja nyitni az ajtót.",Trova la fucina. Le informazioni che ti ho appena dato ti dovrebbero aiutare a trovare una sezione segreta della Fabbrica. Uno dei lavoratori della fucina ti potrà aprire la porta.,"工場の鉄工所を探せ。俺が与えた情報は そこの隠された区域に入る為に必要だ。 -偽の作業員がドアを開けるだろう。",공장의 제련소로 찾아가세요. 제가 제공한 정보만 있으면 그곳으로 향하는 비밀구역을 쉽게 찾을 수 있을 겁니다. 제련소 직원 중 한 명이 그곳으로 향하는 문을 열 수 있어요.,Zoek de smederij. De informatie die ik je net heb gegeven zou je moeten helpen om een geheime sector van de fabriek te betreden. Een van de smidsewerkers kan de deur openen.,Finn smia. Informasjonen jeg nettopp ga deg bør hjelpe deg å komme inn i en hemmelig sektor av fabrikken. En av smiearbeiderne kan åpne døren.,"Zlokalizuj kuźnię. Informacje, które przed chwilą podałem, powinny pomóc ci wejść do tajnego sektora fabryki. Jeden z pracowników kuźni może otworzyć drzwi.",Localize a forja. A informação que acabei de te passar deve ajudar para entrar em um setor secreto da fábrica. Um dos operários da forja pode abrir a porta.,,Găsește forja. Informațiile pe care ți le-am oferit ar trebui să te ajute să intri într-un sector secret al fabricii. Unul dintre făurari poate deschide ușa.,"Найди кузню. Сведения, которые я передал тебе, помогут тебе пройти в секретный сектор фабрики. Один из работников в кузне откроет тебе дверь.",,Demirhaneyi bulun. Sana verdiğim bilgiler fabrikanın gizli bir bölümüne girmene yardımcı olacaktır. Demirci işçilerinden biri kapıyı açabilir. -What can I find there?,TXT_RPLY0_SCRIPT23_D18192_WHATC,,,,Co tam můžu najít?,Hvad kan jeg finde der?,Was kann ich dort finden?,,,¿Qué puedo encontrar allí?,,Mitä löydän sieltä?,Qu'est ce que je peux y trouver?,Mit fogok ott találni?,Che cosa troverò là?,そこには何がある?,그곳을 어떻게 찾을 수 있죠?,Wat kan ik daar vinden?,Hva kan jeg finne der?,Co mogę tam znaleźć?,O que vou encontrar lá?,,Ce pot găsi acolo?,Что там находится?,,Orada ne bulabilirim? +偽の作業員がドアを開けるだろう。",공장의 제련소로 찾아가세요. 제가 제공한 정보만 있으면 그곳으로 향하는 비밀구역을 쉽게 찾을 수 있을 겁니다. 제련소 직원 중 한 명이 그곳으로 향하는 문을 열 수 있어요.,Zoek de smederij. De informatie die ik je net heb gegeven zou je moeten helpen om een geheime sector van de fabriek te betreden. Een van de smidsewerkers kan de deur openen.,Finn smia. Informasjonen jeg nettopp ga deg bør hjelpe deg å komme inn i en hemmelig sektor av fabrikken. En av smiearbeiderne kan åpne døren.,"Zlokalizuj kuźnię. Informacje, które przed chwilą podałem, powinny pomóc ci wejść do tajnego sektora fabryki. Jeden z pracowników kuźni może otworzyć drzwi.",Localize a forja. A informação que acabei de te passar deve ajudar para entrar em um setor secreto da fábrica. Um dos operários da forja pode abrir a porta.,,Găsește forja. Informațiile pe care ți le-am oferit ar trebui să te ajute să intri într-un sector secret al fabricii. Unul dintre făurari poate deschide ușa.,"Найди кузню. Сведения, которые я передал тебе, помогут тебе пройти в секретный сектор фабрики. Один из работников в кузне откроет тебе дверь.",,Leta upp smedjan. Informationen jag just gav dig ska hjälpa dig att komma in i en hemlig sektor av fabriken. En av smidesarbetarna kan öppna dörren.,Demirhaneyi bulun. Sana verdiğim bilgiler fabrikanın gizli bir bölümüne girmene yardımcı olacaktır. Demirci işçilerinden biri kapıyı açabilir. +What can I find there?,TXT_RPLY0_SCRIPT23_D18192_WHATC,,,,Co tam můžu najít?,Hvad kan jeg finde der?,Was kann ich dort finden?,,,¿Qué puedo encontrar allí?,,Mitä löydän sieltä?,Qu'est ce que je peux y trouver?,Mit fogok ott találni?,Che cosa troverò là?,そこには何がある?,그곳을 어떻게 찾을 수 있죠?,Wat kan ik daar vinden?,Hva kan jeg finne der?,Co mogę tam znaleźć?,O que vou encontrar lá?,,Ce pot găsi acolo?,Что там находится?,,Vad kan jag hitta där?,Orada ne bulabilirim? My research suggests that some dark power from the ancient past is hidden there. Be careful!,TXT_DLG_SCRIPT23_D19708_MYRES,,,,"Můj výzkum naznačuje, že se tam schovává nějaká starověká temná síla. Buď opatrný!","Min forskning tyder på, at der er gemt en mørk magt fra den gamle fortid der. Vær forsigtig!","Meine Nachforschungen lassen vermuten, dass dort eine dunkle Macht aus längst vergangenen Zeiten versteckt ist. Sei vorsichtig!",,,Mi investigación sugiere que algún poder oscuro de la antigüedad se oculta allí. ¡Ten cuidado!,,"Tutkimukseni viittaa siihen, että jokin pimeä voima muinaismenneisyydestä on kätketty sinne. Ole varuillasi!",Mes recherches suggèrent qu'il y a un pouvoir sombre ancien qui s'y cache. Faites attention!,"A kutatásaim azt mutatják, hogy az ősidőkből maradt sötét erő bújik meg ott. Légy óvatos!","Dopo attente ricerche sul materiale che ho, ho stabilito che un oscuro e antico potere è nascosto lì. Fai attenzione!","俺の調査では、古代の災厄がそこに隠されている -という話だ。注意しろよ!","제가 연구를 좀 더 해봤는데, 그곳에서 사악한 고대의 기운이 솟아난다는군요. 조심하시길!",Mijn onderzoek suggereert dat daar een duistere kracht uit het oude verleden verborgen ligt. Wees voorzichtig!,Forskningen min tyder på at en mørk kraft fra fortiden er skjult der. Vær forsiktig!,"Moje badania sugerują, że ukryta jest tam jakaś mroczna moc z zamierzchłej przeszłości. Bądź ostrożny!",Minha pesquisa sugere que há algum poder sombrio do passado antigo escondido naquele lugar. Tome cuidado!,,Investigațiile mele indică faptul că ceva putere întunecată din trecutul antic e ascunsă acolo. Ai grijă!,"Судя по результатам исследования, какая-то тёмная сила из далёкого прошлого. Будь осторожен!",,"Araştırmalarım, kadim geçmişten gelen karanlık bir gücün orada saklı olduğunu gösteriyor. Dikkatli ol!" +という話だ。注意しろよ!","제가 연구를 좀 더 해봤는데, 그곳에서 사악한 고대의 기운이 솟아난다는군요. 조심하시길!",Mijn onderzoek suggereert dat daar een duistere kracht uit het oude verleden verborgen ligt. Wees voorzichtig!,Forskningen min tyder på at en mørk kraft fra fortiden er skjult der. Vær forsiktig!,"Moje badania sugerują, że ukryta jest tam jakaś mroczna moc z zamierzchłej przeszłości. Bądź ostrożny!",Minha pesquisa sugere que há algum poder sombrio do passado antigo escondido naquele lugar. Tome cuidado!,,Investigațiile mele indică faptul că ceva putere întunecată din trecutul antic e ascunsă acolo. Ai grijă!,"Судя по результатам исследования, какая-то тёмная сила из далёкого прошлого. Будь осторожен!",,Min forskning tyder på att någon mörk kraft från det forntida förflutna är gömd där. Var försiktig!,"Araştırmalarım, kadim geçmişten gelen karanlık bir gücün orada saklı olduğunu gösteriyor. Dikkatli ol!" "That blue chalice, how'd you come by it? I've been researching the Order and their links to the distant past, and that artifact would help me. Let's make a deal. Give me the chalice, and I'll give you some info.",TXT_DLG_SCRIPT23_D21224_THATB,,,,"Ten modrý kalich, jak jsi k němu přišel? Zkoumal jsem Řád a jeho pojítka k dávné minulosti a ten artefakt by mi pomohl. Udělejme dohodu: Ty mi dáš ten kalich a já ti dám nějaké informace.","Den blå bæger, hvordan er du kommet til den? Jeg har forsket i Ordenen og deres forbindelser til den fjerne fortid, og denne artefakt ville hjælpe mig. Lad os lave en aftale. Giv mig bægeret, og jeg giver dig nogle oplysninger.","Dieser blaue Kelch, wie bist du da ran gekommen? Ich habe bereits über den Orden und deren Verbindung zur fernen Vergangenheit recherchiert, und dieses Artefakt könnte mir weiterhelfen. Ich schlage dir etwas vor: Gib mir den Kelch und ich gebe dir Informationen.",,,"Ese cáliz azul, ¿Cómo lo has encontrado? He estado investigando a La Orden y sus conexiones con el pasado distante, y ese artefacto me ayudaría. Hagamos un trato. Dame el cáliz, y te daré algo de información.",,"Tuo sininen uhrimalja, miten onnistuit saamaan sen? Olen tutkinut Veljeskuntaa ja sen kytköksiä kaukaiseen menneisyyteen, ja tuo esine auttaisi minua. Tehdäänpä kauppa: Sinä annat minulle maljan, ja minä annan sinulle tietoa.","Ce calice bleu, comment l'avez vous trouvé? Je fais des recherches sur l'Ordre et leurs liens avec le passé. Cet artéfact m'aiderait beaucoup. Faisons affaires: donnez le moi et je vous aiderai.","Hogyan sikerült megszerened azt a kék serleget? Kutattam a Rendet és kapcsolatukat a messzi múlttal, és ez az ereklye nagy segítség lenne. Kössünk üzletet. Add ide a serleget, és cserébe kapsz információt.","Quel calice blu, come lo hai trovato? Ho passato molto tempo a ricercare l'Ordine e i suoi legami con il lontano passato, e quell'artifatto mi aiuterebbe. Facciamo una cosa. Se mi dai il calice, io ti darò delle informazioni.","その青い聖杯はどうした? 私はオーダーの遥か過去の関係について調査 していた、その骨董品が手掛かりになりそうだ。 -取引しよう、聖杯をくれれば幾つか情報を渡す。","저 푸른 성배... 어떻게 찾으신 거죠? 오더와 그들의 과거를 좀 조사하던 참이었습니다. 저 보물만 있으면 아주 커다란 도움이 될 것입니다. 그 성배를 주신다면, 좋은 정보를 알려주겠습니다.","Die blauwe kelk, hoe kom je eraan? Ik heb de Orde en hun verbanden met het verre verleden onderzocht, en dat artefact zou me helpen. Laten we een deal sluiten. Geef me de kelk en ik zal je wat informatie geven.","Det blå begeret, hvordan fikk du tak i det? Jeg har forsket på Ordenen og deres forbindelser til en fjern fortid, og den gjenstanden kan hjelpe meg. La oss gjøre en avtale. Gi meg begeret, så gir jeg deg informasjon.","Ten niebieski kielich, skąd go masz? Badałem Zakon i ich powiązania z odległą przeszłością, a ten artefakt mógłby mi pomóc. Zawrzyjmy układ. Daj mi kielich, a ja dam ci trochę informacji.","Esse cálice azul, como você o encontrou? Estive pesquisando sobre a Ordem e o seu vínculo com o passado distante e esse artefato me ajudaria. Vamos fazer um trato. Me dê o cálice e eu te dou informações.",,"Acel potir albastru, cum l-ai găsit? Am cercetat Ordinul și legăturile lor cu trecutul, iar acel artefact mă poate ajuta. Să facem un târg, Îmi dai potirul, iar eu îți dau informații.","Эта синяя чаша... откуда она у тебя? Мои исследования Ордена связаны с событиями далёкого прошлого, и мне очень нужен этот артефакт. Давай заключим сделку: ты мне чашу, а я тебе — информацию.",,"O mavi kadehi nereden buldun? Tarikat'ı ve uzak geçmişle bağlantılarını araştırıyordum ve bu eser bana yardımcı olabilir. Bir anlaşma yapalım. Kadehi bana ver, ben de sana biraz bilgi vereyim." -"Take it, it's bad luck anyway.",TXT_RPLY0_SCRIPT23_D21224_TAKEI,,,,"Vem si ho, stejně přináší jen smůlu.","Tag den, den bringer alligevel uheld.","Nimm ihn, er bringt sowieso Unglück.",,,"Toma, de todos modos da mala suerte.",,"Ota se, epäonnenkalu se kuitenkin on.","Gardez le, je parie qu'il file malchance.","Vidd nyugodtan, rossz szerencsét hoz amúgyis.","Prendilo, tanto porta sfortuna.",渡そう、兎に角運が悪かった。,"값어치도 없을 것 같은데, 그냥 가져가세요.","Neem het, het is toch al pech.","Ta det, det bringer ulykke uansett.","Weź go, to i tak przynosi pecha.",Pode pegar. Isso atrai azar de qualquer forma.,,"Ia-l, poartă ghinion oricum.",Держи. Она всё равно приносит несчастье.,,"Al, zaten kötü şans getirir." -"Screw you, I'm keeping it.",TXT_RPLY1_SCRIPT23_D21224_SCREW,,,,"Jdi se vycpat, nechám si ho.","Rend mig, jeg beholder den.","Ach, was soll's. Ich behalte ihn.",,,"Que te zurzan, me lo quedo.","Al diablo, me lo quedo.","Vedä käteen, pidän sen itselläni.","Allez vous faire voir, il est à moi maintenant.","Nagy francot, inkább megtartom.",E invece me lo tengo!,ふざけるな、俺の物だ。,뭔 개소리야? 이제 이건 내 것이라고!,"Krijg de klere, ik hou hem.","Faen ta deg, jeg beholder det.","Wal się, zatrzymam go.","Vá se ferrar, ele é meu.",,"Du-te naibi, îl păstrez.",Пошёл ты! Я оставлю её себе.,,"Siktir git, bende kalacak." -Then I'm not giving you anything. Get lost!,TXT_RYES1_SCRIPT23_D21224_THENI,,,,Pak ti nic nedám. Zmizni!,Så giver jeg dig ikke noget. Forsvind!,Dann bekommst du auch nichts von mir. Verzieh dich!,,,Entonces no te voy a dar nada. ¡Piérdete!,,Sitten en anna sinulle mitään. Antaa vetää!,"Rien pour vous, alors, dégagez!",Akkor meg tudod mikor adok neked bármit is. Húzzál elfelé!,E allora non ti darò niente. Sparisci!,何もやるモンは無いぞ。失せな!,아주 좋은 기회를 다 날려버리시는군. 꺼져요!,Dan geef ik je niets. Donder op!,Da gir jeg deg ingenting. Forsvinn!,Więc nic ci nie dam. Spadaj!,Então não te darei nada. Se manda!,,Atunci nu îți dau nimic. Valea!,Тогда я тебе ничего не скажу. Убирайся!,,O zaman sana hiçbir şey vermiyorum. Kaybol! -"Now, what can I help you with?",TXT_DLG_SCRIPT23_D22740_NOWWH,,,,"Tak, s čím ti mohu pomoci?",Hvad kan jeg hjælpe dig med?,"Nun, wie kann ich dir weiterhelfen?",,,"Ahora, ¿En qué puedo ayudarte?",,"No niin, miten voin palvella?","Bon, que puis-je pour vous?",Akkor miben segíthetek?,"E ora, come posso aiutarti?",今手伝ってくれるか?,"그럼, 뭘 더 도와드릴까요?","Nu, waar kan ik je mee helpen?",Hva kan jeg hjelpe deg med?,"A teraz, w czym mogę ci pomóc?","Então, como posso ajudá-lo?",,"Acum, cu ce te pot ajuta?","Итак, чем я могу быть тебе полезен?",,"Şimdi, sana nasıl yardım edebilirim?" -Shadow armor?,TXT_RPLY0_SCRIPT23_D22740_SHADO,,,Shadow armour?,Stínové brnění?,Skygge rustning?,Schattenrüstung?,,,¿Armadura de sombra?,,Varjohaarniska?,Armure des ombres?,Árnyék vért?,Armatura Ombra?,シャドウアーマー?,그림자 갑옷?,Schaduw pantser?,Skyggepanser?,Zbroja cieni?,Armadura das sombras?,,Armura umbrei?,Теневой бронёй?,,Gölge zırhı mı? -"Ahh, to be heard, but not seen!",TXT_RYES0_SCRIPT23_D22740_AHHTO,,,,"Áha, být slyšen, ne viděn!","Ahh, at blive hørt, men ikke set!","Ah, um gehört zu werden, aber ungesehen zu bleiben.",,,"Ahh, ¡Para ser oído, pero no visto!",,"Aah, tulla kuulluksi, muttei nähdyksi!","Ah, pour se faire entendre, sans se faire voir!","Csak hallani, de nem látni.","Ahh, per essere sentiti, ma non visti!",ああ、声はすれど姿は見えず。,들켜도 당신을 계속 맞추진 못할 거요!,"Ahhh, om gehoord, maar niet gezien te worden!","Å bli hørt, men ikke sett!","Ahh, być słyszanym, ale nie widzianym!","Ahh, ser ouvido mas não ser visto!",,"Ahh, să fii auzit, dar nu văzut!","Ах, чтобы быть услышанным, но не увиденным!",,"Ahh, duyulmak ama görülmemek!" -"Get out of here, come back when you have some cash.",TXT_RNO0_SCRIPT23_D22740_GETOU,,,,"Vypadni a vrať se, když budeš mít peníze.","Forsvind herfra, og kom tilbage, når du har nogle penge.","Verzieh dich, komm wieder, wenn du etwas Geld hast.",,,"Vete de aquí, vuelve cuando tengas algo de efectivo.",,"Antaa vetää; tule takaisin, kun sinulla on käteistä.","Sortez de là, revenez quand vous avez de l'argent!","Na kotródj innen, csak akkor lássalak ha van nálad pénz is.","Fuori di qui, ritorna quando avrai del denaro.",ここを出て、稼いでからまた来てくれ!,이 유용한 도구를 공짜로 주기엔 영 그렇군요.,"Ga hier weg, kom terug als je wat geld hebt.","Kom deg ut herfra, og kom tilbake når du har penger.","Wynoś się stąd, wróć jak będziesz miał trochę kasy.",Vá embora daqui. Volte quando tiver dinheiro.,,"Cară-te, întoarce-te când ai bani.","Выметайся вон. Вернёшься, когда раздобудешь наличности.",,"Git buradan, biraz paran olduğunda geri gel." +取引しよう、聖杯をくれれば幾つか情報を渡す。","저 푸른 성배... 어떻게 찾으신 거죠? 오더와 그들의 과거를 좀 조사하던 참이었습니다. 저 보물만 있으면 아주 커다란 도움이 될 것입니다. 그 성배를 주신다면, 좋은 정보를 알려주겠습니다.","Die blauwe kelk, hoe kom je eraan? Ik heb de Orde en hun verbanden met het verre verleden onderzocht, en dat artefact zou me helpen. Laten we een deal sluiten. Geef me de kelk en ik zal je wat informatie geven.","Det blå begeret, hvordan fikk du tak i det? Jeg har forsket på Ordenen og deres forbindelser til en fjern fortid, og den gjenstanden kan hjelpe meg. La oss gjøre en avtale. Gi meg begeret, så gir jeg deg informasjon.","Ten niebieski kielich, skąd go masz? Badałem Zakon i ich powiązania z odległą przeszłością, a ten artefakt mógłby mi pomóc. Zawrzyjmy układ. Daj mi kielich, a ja dam ci trochę informacji.","Esse cálice azul, como você o encontrou? Estive pesquisando sobre a Ordem e o seu vínculo com o passado distante e esse artefato me ajudaria. Vamos fazer um trato. Me dê o cálice e eu te dou informações.",,"Acel potir albastru, cum l-ai găsit? Am cercetat Ordinul și legăturile lor cu trecutul, iar acel artefact mă poate ajuta. Să facem un târg, Îmi dai potirul, iar eu îți dau informații.","Эта синяя чаша... откуда она у тебя? Мои исследования Ордена связаны с событиями далёкого прошлого, и мне очень нужен этот артефакт. Давай заключим сделку: ты мне чашу, а я тебе — информацию.",,"Den blå kalken, hur kom du över den? Jag har forskat om orden och deras kopplingar till det förflutna, och den artefakten skulle hjälpa mig. Låt oss göra en överenskommelse. Ge mig bägaren, så ger jag dig lite information.","O mavi kadehi nereden buldun? Tarikat'ı ve uzak geçmişle bağlantılarını araştırıyordum ve bu eser bana yardımcı olabilir. Bir anlaşma yapalım. Kadehi bana ver, ben de sana biraz bilgi vereyim." +"Take it, it's bad luck anyway.",TXT_RPLY0_SCRIPT23_D21224_TAKEI,,,,"Vem si ho, stejně přináší jen smůlu.","Tag den, den bringer alligevel uheld.","Nimm ihn, er bringt sowieso Unglück.",,,"Toma, de todos modos da mala suerte.",,"Ota se, epäonnenkalu se kuitenkin on.","Gardez le, je parie qu'il file malchance.","Vidd nyugodtan, rossz szerencsét hoz amúgyis.","Prendilo, tanto porta sfortuna.",渡そう、兎に角運が悪かった。,"값어치도 없을 것 같은데, 그냥 가져가세요.","Neem het, het is toch al pech.","Ta det, det bringer ulykke uansett.","Weź go, to i tak przynosi pecha.",Pode pegar. Isso atrai azar de qualquer forma.,,"Ia-l, poartă ghinion oricum.",Держи. Она всё равно приносит несчастье.,,"Ta den, den betyder ändå otur.","Al, zaten kötü şans getirir." +"Screw you, I'm keeping it.",TXT_RPLY1_SCRIPT23_D21224_SCREW,,,,"Jdi se vycpat, nechám si ho.","Rend mig, jeg beholder den.","Ach, was soll's. Ich behalte ihn.",,,"Que te zurzan, me lo quedo.","Al diablo, me lo quedo.","Vedä käteen, pidän sen itselläni.","Allez vous faire voir, il est à moi maintenant.","Nagy francot, inkább megtartom.",E invece me lo tengo!,ふざけるな、俺の物だ。,뭔 개소리야? 이제 이건 내 것이라고!,"Krijg de klere, ik hou hem.","Faen ta deg, jeg beholder det.","Wal się, zatrzymam go.","Vá se ferrar, ele é meu.",,"Du-te naibi, îl păstrez.",Пошёл ты! Я оставлю её себе.,,"Dra åt helvete, jag behåller den.","Siktir git, bende kalacak." +Then I'm not giving you anything. Get lost!,TXT_RYES1_SCRIPT23_D21224_THENI,,,,Pak ti nic nedám. Zmizni!,Så giver jeg dig ikke noget. Forsvind!,Dann bekommst du auch nichts von mir. Verzieh dich!,,,Entonces no te voy a dar nada. ¡Piérdete!,,Sitten en anna sinulle mitään. Antaa vetää!,"Rien pour vous, alors, dégagez!",Akkor meg tudod mikor adok neked bármit is. Húzzál elfelé!,E allora non ti darò niente. Sparisci!,何もやるモンは無いぞ。失せな!,아주 좋은 기회를 다 날려버리시는군. 꺼져요!,Dan geef ik je niets. Donder op!,Da gir jeg deg ingenting. Forsvinn!,Więc nic ci nie dam. Spadaj!,Então não te darei nada. Se manda!,,Atunci nu îți dau nimic. Valea!,Тогда я тебе ничего не скажу. Убирайся!,,Då ger jag dig ingenting. Försvinn!,O zaman sana hiçbir şey vermiyorum. Kaybol! +"Now, what can I help you with?",TXT_DLG_SCRIPT23_D22740_NOWWH,,,,"Tak, s čím ti mohu pomoci?",Hvad kan jeg hjælpe dig med?,"Nun, wie kann ich dir weiterhelfen?",,,"Ahora, ¿En qué puedo ayudarte?",,"No niin, miten voin palvella?","Bon, que puis-je pour vous?",Akkor miben segíthetek?,"E ora, come posso aiutarti?",今手伝ってくれるか?,"그럼, 뭘 더 도와드릴까요?","Nu, waar kan ik je mee helpen?",Hva kan jeg hjelpe deg med?,"A teraz, w czym mogę ci pomóc?","Então, como posso ajudá-lo?",,"Acum, cu ce te pot ajuta?","Итак, чем я могу быть тебе полезен?",,Vad kan jag hjälpa dig med?,"Şimdi, sana nasıl yardım edebilirim?" +Shadow armor?,TXT_RPLY0_SCRIPT23_D22740_SHADO,,,Shadow armour?,Stínové brnění?,Skygge rustning?,Schattenrüstung?,,,¿Armadura de sombra?,,Varjohaarniska?,Armure des ombres?,Árnyék vért?,Armatura Ombra?,シャドウアーマー?,그림자 갑옷?,Schaduw pantser?,Skyggepanser?,Zbroja cieni?,Armadura das sombras?,,Armura umbrei?,Теневой бронёй?,,Skuggarmering?,Gölge zırhı mı? +"Ahh, to be heard, but not seen!",TXT_RYES0_SCRIPT23_D22740_AHHTO,,,,"Áha, být slyšen, ne viděn!","Ahh, at blive hørt, men ikke set!","Ah, um gehört zu werden, aber ungesehen zu bleiben.",,,"Ahh, ¡Para ser oído, pero no visto!",,"Aah, tulla kuulluksi, muttei nähdyksi!","Ah, pour se faire entendre, sans se faire voir!","Csak hallani, de nem látni.","Ahh, per essere sentiti, ma non visti!",ああ、声はすれど姿は見えず。,들켜도 당신을 계속 맞추진 못할 거요!,"Ahhh, om gehoord, maar niet gezien te worden!","Å bli hørt, men ikke sett!","Ahh, być słyszanym, ale nie widzianym!","Ahh, ser ouvido mas não ser visto!",,"Ahh, să fii auzit, dar nu văzut!","Ах, чтобы быть услышанным, но не увиденным!",,"Ahh, att höras men inte ses!","Ahh, duyulmak ama görülmemek!" +"Get out of here, come back when you have some cash.",TXT_RNO0_SCRIPT23_D22740_GETOU,,,,"Vypadni a vrať se, když budeš mít peníze.","Forsvind herfra, og kom tilbage, når du har nogle penge.","Verzieh dich, komm wieder, wenn du etwas Geld hast.",,,"Vete de aquí, vuelve cuando tengas algo de efectivo.",,"Antaa vetää; tule takaisin, kun sinulla on käteistä.","Sortez de là, revenez quand vous avez de l'argent!","Na kotródj innen, csak akkor lássalak ha van nálad pénz is.","Fuori di qui, ritorna quando avrai del denaro.",ここを出て、稼いでからまた来てくれ!,이 유용한 도구를 공짜로 주기엔 영 그렇군요.,"Ga hier weg, kom terug als je wat geld hebt.","Kom deg ut herfra, og kom tilbake når du har penger.","Wynoś się stąd, wróć jak będziesz miał trochę kasy.",Vá embora daqui. Volte quando tiver dinheiro.,,"Cară-te, întoarce-te când ai bani.","Выметайся вон. Вернёшься, когда раздобудешь наличности.",,Stick härifrån och kom tillbaka när du har pengar.,"Git buradan, biraz paran olduğunda geri gel." "Thank Deus you got here. To enter the factory you need a key. We stole it but our agent is missing in the web of catacombs under the Order's stronghold. I have sent ten good men into those tunnels to find him, and none have returned. Something is down there!",TXT_DLG_SCRIPT23_D24256_THANK,,,,"Díky bohu, žes přišel. Aby ses dostal do továrny, potřebuješ klíč. Ten jsme ukradli, ale náš agent se ztratil v sítí katakomb pod pevností Řádu. Poslal jsem do těch tunelů deset dobrých mužů a žádný se nevrátil. Něco tam dole je!","Tak Deus for at du kom her. For at komme ind på fabrikken skal du bruge en nøgle. Vi stjal den, men vores agent er forsvundet i katakomberne under ordenens højborg. Jeg har sendt ti gode mænd ned i disse tunneller for at finde ham, men ingen er vendt tilbage. Der er noget dernede!","Deus sei dank bist du hier. Um die Fabrik zu betreten, brauchst du einen Schlüssel. Wir haben ihn gestohlen, aber unser Agent ist in den Irrwegen der Katakomben unter Festung des Ordens verschwunden. Ich habe zehn gute Männer da hinunter geschickt um ihn zu finden, aber niemand ist zurückgekehrt. Irgendetwas ist da unten!",,,"Gracias a deus que estás aquí. Para entrar en la fábrica necesitas una llave. La robamos, pero nuestro agente está perdido en la red de catacumbas debajo de la fortaleza de la Orden. He enviado diez buenos hombres a esos túneles para encontrarlo, y ninguno ha regresado. ¡Hay algo ahí abajo!",,"Luojan kiitos, että selvisit perille. Päästäksesi sisälle tehtaaseen tarvitset avaimen. Varastimme sen, mutta vakoojamme on eksynyt Veljeskunnan linnakkeen alapuolella sijaitsevaan katakombiverkostoon. Olen lähettänyt tunneleihin 10 kelpoa miestä etsimään häntä, eikä kukaan ole palannut. Jokin on siellä alla!","Merci Dieu, vous êtes là. Pour entrer dans l'usine, il vous faut une clé. On l'a volé, mais notre agent a disparu dans le dédale de catacombes sous la forteresse de l'Ordre. On a envoyé dix hommes dans ces tunnels pour le retrouver mais personne n'est revenu. Il doit y avoir quelque chose, là dedans!","Hála Deusnak, ideértél.Ahhoz, hogy bejuthass a gyárba kell majd egy kulcs. Habár sikerült ellopnunk a kulcsot, az ügynökünk elveszett a katakombák sűrűjében a Rend erődítménye alatt. Leküldtem tíz jó emberemet utána, de egyikük sem tért vissza. Valami borzasztó lehet ott lent!","Grazie a Dio sei arrivato. Per entrare nella fabbrica ti servirà una chiave. L'abbiamo rubata ma l'agente che l'ha presa è sparito nelle catacombe sotto la fortezza dell'Ordine. Ho mandato dieci uomini in quei tunnel a trovarlo, e nessuno è ritornato. C'è qualcosa là sotto!","ようやく来てくれたか。 工場に入るためには鍵が必要だ。 鍵は盗んだのだが、我々の密偵が砦地下にある 地下墓所で行方不明になった。 彼を探すため10名派遣したのだが、 誰一人帰ってこなかった。 -地下墓地で何か異変が起こっているに違いない。","데우스님 감사합니다, 지원군이 왔군! 공장에 들어가려면 열쇠가 필요합니다. 그 열쇠를 가진 한 요원이 오더의 요새가 있는 고대 무덤에서 길을 잃었습니다. 지원군 10 명을 보내긴 했으나 돌아오지 못했습니다. 그곳에 무언가가 있는 것 같아요!","Bedankt deus dat je hier bent gekomen. Om de fabriek binnen te komen heb je een sleutel nodig. We hebben het gestolen maar onze agent ontbreekt in het web van de catacomben onder het bolwerk van de Orde. Ik heb tien goede mannen in die tunnels gestuurd om hem te vinden, en niemand is teruggekomen. Er is daar beneden iets!","Takk Gud for at du kom hit. For å komme inn i fabrikken trenger du en nøkkel. Vi stjal den, men agenten vår er forsvunnet i katakombene under Ordenens festning. Jeg har sendt ti gode menn ned i tunnelene for å finne ham, men ingen har kommet tilbake. Det er noe der nede!","Dzięki Deusowi, że tu trafiłeś. Aby wejść do fabryki potrzebny jest klucz. Ukradliśmy go, ale nasz agent zaginął w sieci katakumb pod twierdzą Zakonu. Wysłałem dziesięciu dobrych ludzi do tych tuneli, by go znaleźli, ale żaden nie wrócił. Coś jest tam na dole!",Graças a Deus que você está aqui. Para entrar na fábrica você precisa de uma chave. Nós a roubamos mas nosso agente desapareceu na rede de catacumbas debaixo da fortaleza da Ordem. Mandei dez homens capazes pra dentro desses túneis para encontrá-lo e ninguém retornou. Tem alguma coisa lá embaixo!,,"Slavă Domnului că ești aici. Ca să intri în fabrică ai nevoie de o cheie. Am furat-o dar agentul nostru a dispărut în rețeaua catacombelor fortăreței Ordinului. Am trimis zece oameni pricepuți după el, dar niciunul nu s-a întors. Ceva se întâmplă acolo!","Хвала господу, ты добрался сюда. Тебе нужен ключ, чтобы проникнуть на фабрику. Мы выкрали его, но наш агент пропал в сети катакомб под крепостью Ордена. Чтобы разыскать его, я послал в эти туннели десять хороших бойцов, и ни один не вернулся. Там внизу что-то есть!",,Buraya geldiğin için Deus'a şükret. Fabrikaya girmek için bir anahtara ihtiyacınız var. Onu çaldık ama ajanımız Tarikat'ın kalesinin altındaki yeraltı mezarlarında kayıp. Onu bulmaları için o tünellere on iyi adam gönderdim ama hiçbiri geri dönmedi. Aşağıda bir şey var! -What is it? Human or... ?,TXT_RPLY0_SCRIPT23_D24256_WHATI,,,,"Co to je? Člověk, nebo...?",Hvad er det? Menneske eller... ?,Was ist es? Mensch oder...?,,,¿Qué es? ¿Humano ó...?,,Mikä se on? Ihminen vai...,"Qu'est-ce que c'est? Un humain, où...",Mi lehet? Ember vagy...?,Che cosa è? Umano o... ?,それは一体?人間か...?,이게 뭐지? 사람? 아니면... ?,Wat is het? Menselijk of.... ?,Hva er det? Menneskelig eller... ?,Co to jest? Człowiek czy... ?,O que é? É humano ou... ?,,Ce e? Uman sau... ?,Что это? Человек или...?,,Ne var orada? İnsan mı yoksa... ? +地下墓地で何か異変が起こっているに違いない。","데우스님 감사합니다, 지원군이 왔군! 공장에 들어가려면 열쇠가 필요합니다. 그 열쇠를 가진 한 요원이 오더의 요새가 있는 고대 무덤에서 길을 잃었습니다. 지원군 10 명을 보내긴 했으나 돌아오지 못했습니다. 그곳에 무언가가 있는 것 같아요!","Bedankt deus dat je hier bent gekomen. Om de fabriek binnen te komen heb je een sleutel nodig. We hebben het gestolen maar onze agent ontbreekt in het web van de catacomben onder het bolwerk van de Orde. Ik heb tien goede mannen in die tunnels gestuurd om hem te vinden, en niemand is teruggekomen. Er is daar beneden iets!","Takk Gud for at du kom hit. For å komme inn i fabrikken trenger du en nøkkel. Vi stjal den, men agenten vår er forsvunnet i katakombene under Ordenens festning. Jeg har sendt ti gode menn ned i tunnelene for å finne ham, men ingen har kommet tilbake. Det er noe der nede!","Dzięki Deusowi, że tu trafiłeś. Aby wejść do fabryki potrzebny jest klucz. Ukradliśmy go, ale nasz agent zaginął w sieci katakumb pod twierdzą Zakonu. Wysłałem dziesięciu dobrych ludzi do tych tuneli, by go znaleźli, ale żaden nie wrócił. Coś jest tam na dole!",Graças a Deus que você está aqui. Para entrar na fábrica você precisa de uma chave. Nós a roubamos mas nosso agente desapareceu na rede de catacumbas debaixo da fortaleza da Ordem. Mandei dez homens capazes pra dentro desses túneis para encontrá-lo e ninguém retornou. Tem alguma coisa lá embaixo!,,"Slavă Domnului că ești aici. Ca să intri în fabrică ai nevoie de o cheie. Am furat-o dar agentul nostru a dispărut în rețeaua catacombelor fortăreței Ordinului. Am trimis zece oameni pricepuți după el, dar niciunul nu s-a întors. Ceva se întâmplă acolo!","Хвала господу, ты добрался сюда. Тебе нужен ключ, чтобы проникнуть на фабрику. Мы выкрали его, но наш агент пропал в сети катакомб под крепостью Ордена. Чтобы разыскать его, я послал в эти туннели десять хороших бойцов, и ни один не вернулся. Там внизу что-то есть!",,"Tacka Deus för att du kom hit. För att komma in i fabriken behöver du en nyckel. Vi stal den, men vår agent saknas i katakomberna under Ordensfästet. Jag har skickat tio goda män in i tunnlarna för att hitta honom, men ingen har återvänt. Något finns där nere!",Buraya geldiğin için Deus'a şükret. Fabrikaya girmek için bir anahtara ihtiyacınız var. Onu çaldık ama ajanımız Tarikat'ın kalesinin altındaki yeraltı mezarlarında kayıp. Onu bulmaları için o tünellere on iyi adam gönderdim ama hiçbiri geri dönmedi. Aşağıda bir şey var! +What is it? Human or... ?,TXT_RPLY0_SCRIPT23_D24256_WHATI,,,,"Co to je? Člověk, nebo...?",Hvad er det? Menneske eller... ?,Was ist es? Mensch oder...?,,,¿Qué es? ¿Humano ó...?,,Mikä se on? Ihminen vai...,"Qu'est-ce que c'est? Un humain, où...",Mi lehet? Ember vagy...?,Che cosa è? Umano o... ?,それは一体?人間か...?,이게 뭐지? 사람? 아니면... ?,Wat is het? Menselijk of.... ?,Hva er det? Menneskelig eller... ?,Co to jest? Człowiek czy... ?,O que é? É humano ou... ?,,Ce e? Uman sau... ?,Что это? Человек или...?,,Vad är det? Människor eller... ?,Ne var orada? İnsan mı yoksa... ? "Not. Definitely not. Whatever it is, you must fight it to retrieve the key. I'll open the catacombs' entrance. When you've got it, the factory is next to the mines. Hurry, each second counts.",TXT_DLG_SCRIPT23_D25772_NOTDE,,,,"Ne. Rozhodně ne. Ať je to cokoliv, musíš se s tím utkat, abys získal ten klíč zpět. Otevřu ti vchod do katakomb. Až ho budeš mít, továrna je vedle dolů. Pospěš si, každá vteřina se počítá.","Nej. Helt sikkert ikke. Uanset hvad det er, skal du kæmpe mod det for at få nøglen tilbage. Jeg åbner katakombernes indgang. Når du har fået den, er fabrikken ved siden af minerne. Skynd dig, hvert sekund tæller.","Nein. Definitiv nicht. Was auch immer es ist, du musst es bekämpfen, um an den Schlüssel zu kommen. Ich werde den Eingang zu den Katakomben öffnen. Wenn du ihn hast, die Fabrik ist direkt neben den Minen. Beeil dich, jede Sekunde zählt.",,,"No. Definitivamente no. Sea lo que sea, debes luchar contra eso para recuperar la llave. Abriré la entrada a las catacumbas. Cuando la tengas, la fábrica está junto a las minas. Date prisa, cada segundo cuenta.",,"Ei, ei varmana. Mikä ikinä se onkaan, sinun on kohdattava se noutaaksesi avaimen. Avaan katakombien sisäänkäynnin. Kun se on hallussasi, tehdas on kaivoksen vieressä. Pidä kiirettä, jokainen sekunti merkitsee.","Non, absolument pas. Je ne sais pas ce que c'est, mais il faudra s'en débarasser pour récupérer la clé. Je vais ouvrir l'entrée des catacombes. Quand vous êtes à l'intérieur, l'usine est près des ruines. Vite, chaque seconde compte.","Nem. Biztos, hogy nem. Akármi is az, meg kell majd küzdened vele a kulcsért. Kinyitom a katakomba bejáratát. Ha megszerezted, a gyár ott lesz a bánya mellett. Siess, minden másodperc számít.","No. Sicuramente no. Qualsiasi cosa sia, dovrai lottare per riavere la chiave. Adesso aprirò l'entrata per le catacombe. Quando avrai ripreso la chiave, potrai accedere alla fabbrica, che si trova accanto alle miniere. Sbrigati, ogni secondo può fare la differenza.","いや。人間の仕業だとはとても思えない。 それが何であれ君は鍵を取り戻せ。 地下墓所への入り口は開けておこう。 鍵を手に入れたら、工場は採掘所の隣にある。 -時間はあまり無いから急ぐのだ。","아냐. 사람 같은 건 절대로 아니라고. 그게 무엇이든, 당신은 어떻게든 싸워서 열쇠를 돌려받아야 합니다. 고대 무덤의 입구를 열어두겠습니다. 만약 열쇠를 얻으셨다면, 광산 옆에 있는 공장으로 향하시길 바랍니다. 시간이 얼마 남지 않았습니다!","Niet. Zeker niet. Wat het ook is, je moet ertegen vechten om de sleutel terug te krijgen. Ik zal de ingang van de catacomben openen. Als je hem hebt, staat de fabriek naast de mijnen. Schiet op, elke seconde telt.","Nei. Definitivt ikke. Uansett hva det er, må du kjempe mot det for å få tak i nøkkelen. Jeg åpner inngangen til katakombene. Når du har den, er fabrikken ved siden av gruvene. Skynd deg, hvert sekund teller.","Nie. Zdecydowanie nie. Cokolwiek to jest, musisz z tym walczyć, aby odzyskać klucz. Ja otworzę wejście do katakumb. Gdy go zdobędziesz, fabryka jest obok kopalni. Spiesz się, liczy się każda sekunda.","Não. Definitivamente não é. Seja lá o que for, você deve enfrentá-lo para recuperar a chave. Vou abrir a entrada das catacumbas. Quando você pegar a chave, vá para a fábrica próxima às minas. Depressa, cada segundo é importante.",,"Nu. Cu siguranță nu. Orice ar fi, va trebui să o înfrunți pentru a recupera cheia. Voi deschide intrarea catacombelor. Când o ai, fabrica e vizavi de mine. Grăbește-te, orice secundă contează.","Нет. Определённо нет. Что бы это ни было, ты должен сразиться с ним, чтобы заполучить ключ. Я открою вход в катакомбы. Когда добудешь его, направляйся на фабрику: она находится рядом со входом в шахты. Торопись! Дорога каждая секунда!",,"İnsan değil. Kesinlikle değil. O her neyse, anahtarı almak için onunla savaşmalısın. Yeraltı mezarlarının girişini açacağım. Anahtarı aldığında, fabrika madenlerin yanında. Acele et, her saniye önemli." -"Something inhuman, eh?, great.",TXT_RPLY0_SCRIPT23_D25772_SOMET,,,,"Něco nelidského, co? Skvělý.","Noget umenneskeligt, hva'?, fantastisk.",Irgendetwas unmenschliches? Na großartig.,,,"Algo inhumano, ¿eh? Genial.",,"Jotain epäinhimillistä, vai? Hienoa.","Quelque chose d'inhumain, hein? Parfait.","Valami nem emberi, mi? Csodás.","Qualcosa di inumano, eh? Fantastico.",非人道的な何か?流石だな。,비인간적인 녀석인가요? 좋군요.,"Iets onmenselijks, eh?, geweldig.","Noe umenneskelig, hva? Flott!","Coś nieludzkiego, ech, świetnie.","Algo não-humano, é? Que ótimo.",,"Ceva inuman, ei? Grozav.",Что-то иное? Просто отлично.,,"İnsanlık dışı bir şey, ha? Harika." +時間はあまり無いから急ぐのだ。","아냐. 사람 같은 건 절대로 아니라고. 그게 무엇이든, 당신은 어떻게든 싸워서 열쇠를 돌려받아야 합니다. 고대 무덤의 입구를 열어두겠습니다. 만약 열쇠를 얻으셨다면, 광산 옆에 있는 공장으로 향하시길 바랍니다. 시간이 얼마 남지 않았습니다!","Niet. Zeker niet. Wat het ook is, je moet ertegen vechten om de sleutel terug te krijgen. Ik zal de ingang van de catacomben openen. Als je hem hebt, staat de fabriek naast de mijnen. Schiet op, elke seconde telt.","Nei. Definitivt ikke. Uansett hva det er, må du kjempe mot det for å få tak i nøkkelen. Jeg åpner inngangen til katakombene. Når du har den, er fabrikken ved siden av gruvene. Skynd deg, hvert sekund teller.","Nie. Zdecydowanie nie. Cokolwiek to jest, musisz z tym walczyć, aby odzyskać klucz. Ja otworzę wejście do katakumb. Gdy go zdobędziesz, fabryka jest obok kopalni. Spiesz się, liczy się każda sekunda.","Não. Definitivamente não é. Seja lá o que for, você deve enfrentá-lo para recuperar a chave. Vou abrir a entrada das catacumbas. Quando você pegar a chave, vá para a fábrica próxima às minas. Depressa, cada segundo é importante.",,"Nu. Cu siguranță nu. Orice ar fi, va trebui să o înfrunți pentru a recupera cheia. Voi deschide intrarea catacombelor. Când o ai, fabrica e vizavi de mine. Grăbește-te, orice secundă contează.","Нет. Определённо нет. Что бы это ни было, ты должен сразиться с ним, чтобы заполучить ключ. Я открою вход в катакомбы. Когда добудешь его, направляйся на фабрику: она находится рядом со входом в шахты. Торопись! Дорога каждая секунда!",,"Inte. Definitivt inte. Vad det än är måste du slåss mot det för att få tag på nyckeln. Jag öppnar katakombernas ingång. När du har fått den är fabriken bredvid gruvorna. Skynda dig, varje sekund räknas.","İnsan değil. Kesinlikle değil. O her neyse, anahtarı almak için onunla savaşmalısın. Yeraltı mezarlarının girişini açacağım. Anahtarı aldığında, fabrika madenlerin yanında. Acele et, her saniye önemli." +"Something inhuman, eh?, great.",TXT_RPLY0_SCRIPT23_D25772_SOMET,,,,"Něco nelidského, co? Skvělý.","Noget umenneskeligt, hva'?, fantastisk.",Irgendetwas unmenschliches? Na großartig.,,,"Algo inhumano, ¿eh? Genial.",,"Jotain epäinhimillistä, vai? Hienoa.","Quelque chose d'inhumain, hein? Parfait.","Valami nem emberi, mi? Csodás.","Qualcosa di inumano, eh? Fantastico.",非人道的な何か?流石だな。,비인간적인 녀석인가요? 좋군요.,"Iets onmenselijks, eh?, geweldig.","Noe umenneskelig, hva? Flott!","Coś nieludzkiego, ech, świetnie.","Algo não-humano, é? Que ótimo.",,"Ceva inuman, ei? Grozav.",Что-то иное? Просто отлично.,,"Något omänskligt, va?, bra.","İnsanlık dışı bir şey, ha? Harika." You're wasting time and lives! Move!,TXT_DLG_SCRIPT23_D27288_YOURE,,,,Plýtváš časem i životy! Jdi!,Du spilder tid og liv! Af sted!,Du verschwendest Zeit und Leben! Beweg dich!,,,¡Estás perdiendo tiempo y vidas! ¡Muévete!,,Haaskaat aikaa ja henkiä! Liikkuu jo!,Vous perdez votre temps et des vies! Bougez!,Időt és életeket pazarolsz! Mozgás!,"Stai sprecando tempo, e vite. Sbrigati!","こうしてる間にも君は時間と人命を -無駄にしている。行け!",시간과 생명이 위협받고 있다고! 서두르세요!!,Je verspilt tijd en levens! Vooruit!,Du kaster bort tid og liv! Skynd dere!,Marnujesz czas i życie! Ruszać się!,Você está desperdiçando tempo e vidas! Ande logo!,,"Pierzi timp și vieți, mișcă-te!",Ты тратишь время и жизни! Вперёд!,,Zamanınızı ve hayatlarınızı boşa harcıyorsunuz! Çekilin! +無駄にしている。行け!",시간과 생명이 위협받고 있다고! 서두르세요!!,Je verspilt tijd en levens! Vooruit!,Du kaster bort tid og liv! Skynd dere!,Marnujesz czas i życie! Ruszać się!,Você está desperdiçando tempo e vidas! Ande logo!,,"Pierzi timp și vieți, mișcă-te!",Ты тратишь время и жизни! Вперёд!,,Du slösar bort tid och liv! Flytta på dig!,Zamanınızı ve hayatlarınızı boşa harcıyorsunuz! Çekilin! "The master doesn't like visitors. He likes all of his work to remain undisturbed. I've got to go get fresh parts from the storage room. I think he said a leg and an arm. Oh, well no time to talk anymore. I'd leave before he finds you.",TXT_DLG_SCRIPT27_D0_THEMA,,,,"Pán nemá rád návštěvy. Má rád, když ho nic neruší od práce. Musím dojít pro čerstvé části ze skladu. Myslím, že chtěl nohu a ruku. Tak, na mluvení není čas. Být tebou, odešel bych dřív, než tě najde.","Mesteren kan ikke lide besøgende. Han kan lide, at alt hans arbejde forbliver uforstyrret. Jeg skal hente nye dele fra lagerrummet. Jeg tror, han sagde et ben og en arm. Nå, men vi har ikke tid til at snakke mere. Jeg ville gå, før han finder dig.","Der Meister mag keine Besucher. Er hat es gern, wenn er bei der Arbeit nicht gestört wird. Ich muss gehen und neue Teile aus dem Lagerraum holen. Ich glaube er sagte ein Bein und eine Arm. Naja, keine Zeit mehr zum Reden. Du solltest gehen, bevor er dich findet.",,,"Al maestro no le gustan las visitas. Le gusta que su trabajo permanezca ininterrumpido. Tengo que ir a recoger partes frescas del almacén. Creo que dijo una pierna y un brazo. Ah, bueno, no hay tiempo para hablar. Yo me iría antes de que te encuentre.",,"Mestari ei pidä vieraista. Hän haluaa kaikkien töittensä säilyä koskemattomina. Minun on mentävä noutamaan tuoreita osia varastosta. Hän taisi puhua jalasta ja käsivarresta. No, ei enempää aikaa puhua. Sinuna lähtisin, ennen kuin hän löytää sinut.","Le Maître n'aime pas les visiteurs. Il préfère que son travail se déroule dans le calme. Il faut que j'aille chercher des pièces dans la salle de stockage. Il m'a demandé une jambe et un bras, je crois. Bon, plus de temps pour parler. Je partirais si j'étais vous.","A gazda nem szereti a látogatókat. Úgy szereti, ha nem zavarja senki a munkájában. Mennem kell új darabokért a tárolóba. Azt hiszem egy lábat és egy kart említett. Hát, sajnos nincs időm beszélgetni már. A helyedben elmennék, mielőtt megtalál.","Al padrone non piacciono i visitatori. Vuole che tutto il suo lavoro rimanga indisturbato. Ho qua le parti nuove dal magazzino. Mi pare abbia detto una gamba e un braccio. Ah, non ho più tempo per parlare. Io me ne andrei prima che si accorga che tu sei qui.","マスターは訪問者ヲ嫌っている。 彼ハ自分ノ仕事ヲ邪魔されないノガ良いからダ。 私ハこれカラ倉庫に新品の部品を取りに行かねば 腕と足だったカナ。オット、モウ話ス時間ハ無イ -マスターが君を見つける前ニ出発しなけれバ。","주인님은 방문자들을 싫어해. 반대로 그는 남들의 방해 없이 혼자서 일을 하는 걸 아주 좋아하지. 저장고에서 재료를 꺼내서 가져다주는 나 같은 사람들을 제외하면. 한 쌍의 팔다리가 필요하다고 들었는데... 오, 이런. 이제 이야기할 시간도 없어졌네. 그가 널 찾기 전에 도망치는 게 좋을걸?","De meester houdt niet van bezoekers. Hij houdt ervan dat al zijn werk ongestoord blijft. Ik moet verse onderdelen uit de opslagruimte halen. Ik denk dat hij een been en een arm zei. Oh, nou geen tijd meer om te praten. Ik zou weggaan voordat hij je vindt.",Mesteren liker ikke besøkende. Han vil ha arbeidet sitt uforstyrret. Jeg må gå og hente nye deler fra lageret. Jeg tror han sa et bein og en arm. Jeg har ikke tid til å prate mer. Jeg ville dratt før han finner deg.,"Mistrz nie lubi gości. Lubi, gdy cała jego praca pozostaje niezakłócona. Muszę iść po świeże części z magazynu. Chyba powiedział noga i ręka. Nie ma czasu na gadanie. Wyszedłbym, zanim cię znajdzie.","O mestre não gosta de visitantes. Ele gosta que seu trabalho não seja perturbado. Tenho que ir buscar peças novas no depósito. Bom, não tenho mais tempo para conversa. Eu iria embora antes que ele te ache.",,"Stăpânului nu îi plac vizitatorii. Îi place ca toată muncă să fie nederanjată. Trebuie să aduc părți noi din depozit. Cred că a zis un braț și un picior. Of, nu mai e timp de vorbă. O să plec înainte să te găsească.","Хранитель не любит гостей — он предпочитает, чтобы его никто не отвлекал от работы. Он послал меня на склад за свежими частями. Рукой и ногой, кажется... Ох, нет времени на разговоры. Лучше бы тебе уйти, пока он не вернулся.",,Efendi ziyaretçileri sevmez. Tüm çalışmalarının rahatsız edilmeden kalmasını ister. Gidip depodan yeni parçalar almalıyım. Sanırım bir bacak ve bir kol dedi. Artık konuşacak vakit yok. Ben olsam o seni bulmadan giderdim. -Why's that.,TXT_RPLY0_SCRIPT27_D0_WHYST,,,,A proč?,Hvorfor det?,Wieo das?,,,¿Por qué?,,Miksi?,Pourquoi donc?,Miért tennék olyat?,E perché mai?,何故そんなことを。,그건 왜지?,Waarom is dat.,Hvorfor det?,Dlaczego tak jest?,Por quê?,,De ce.,Почему так?,,Nedenmiş o? -"Because, I told you he doesn't like visitors!",TXT_RYES0_SCRIPT27_D0_BECAU,,,,"Protože, jak už jsem řekl, nemá rád návštěvy!","Fordi jeg sagde jo, at han ikke kan lide besøgende!","Ich habe dir doch gesagt, dass er keine Besucher mag!",,,¡Porque te he dicho que no le gustan las visitas!,¡Te estoy diciendo que no le gustan las visitas!,"Koska minähän sanoin, ettei hän pidä vieraista!","Je vous ai dit, il n'aime pas les visiteurs!","Most mondtam, hogy nem szereti a látogatókat!","Perché, come ti ho appena detto, non gli piacciono i visitatori!",ナゼなら、マスターは訪問されたくナイからダ!,"왜냐하면, 그가 방문자들을 싫어한다고 내가 말했으니까!","Omdat hij niet van bezoekers houdt, zei ik toch!",Jeg sa jo at han ikke liker besøk!,"Bo mówiłem ci, że nie lubi gości!","Porque, como eu já te falei, ele não gosta de visitantes!",,"Pentru că, ți-am spus, nu-i plac vizitatorii!","Потому что, как я уже сказал тебе, он не любит посетителей!",,Çünkü sana ziyaretçileri sevmediğini söylemiştim! +マスターが君を見つける前ニ出発しなけれバ。","주인님은 방문자들을 싫어해. 반대로 그는 남들의 방해 없이 혼자서 일을 하는 걸 아주 좋아하지. 저장고에서 재료를 꺼내서 가져다주는 나 같은 사람들을 제외하면. 한 쌍의 팔다리가 필요하다고 들었는데... 오, 이런. 이제 이야기할 시간도 없어졌네. 그가 널 찾기 전에 도망치는 게 좋을걸?","De meester houdt niet van bezoekers. Hij houdt ervan dat al zijn werk ongestoord blijft. Ik moet verse onderdelen uit de opslagruimte halen. Ik denk dat hij een been en een arm zei. Oh, nou geen tijd meer om te praten. Ik zou weggaan voordat hij je vindt.",Mesteren liker ikke besøkende. Han vil ha arbeidet sitt uforstyrret. Jeg må gå og hente nye deler fra lageret. Jeg tror han sa et bein og en arm. Jeg har ikke tid til å prate mer. Jeg ville dratt før han finner deg.,"Mistrz nie lubi gości. Lubi, gdy cała jego praca pozostaje niezakłócona. Muszę iść po świeże części z magazynu. Chyba powiedział noga i ręka. Nie ma czasu na gadanie. Wyszedłbym, zanim cię znajdzie.","O mestre não gosta de visitantes. Ele gosta que seu trabalho não seja perturbado. Tenho que ir buscar peças novas no depósito. Bom, não tenho mais tempo para conversa. Eu iria embora antes que ele te ache.",,"Stăpânului nu îi plac vizitatorii. Îi place ca toată muncă să fie nederanjată. Trebuie să aduc părți noi din depozit. Cred că a zis un braț și un picior. Of, nu mai e timp de vorbă. O să plec înainte să te găsească.","Хранитель не любит гостей — он предпочитает, чтобы его никто не отвлекал от работы. Он послал меня на склад за свежими частями. Рукой и ногой, кажется... Ох, нет времени на разговоры. Лучше бы тебе уйти, пока он не вернулся.",,Mästaren gillar inte besökare. Han vill att allt arbete ska förbli ostört. Jag måste hämta nya delar från lagret. Jag tror att han sa ett ben och en arm. Vi har inte tid att prata längre. Jag skulle gå innan han hittar dig.,Efendi ziyaretçileri sevmez. Tüm çalışmalarının rahatsız edilmeden kalmasını ister. Gidip depodan yeni parçalar almalıyım. Sanırım bir bacak ve bir kol dedi. Artık konuşacak vakit yok. Ben olsam o seni bulmadan giderdim. +Why's that.,TXT_RPLY0_SCRIPT27_D0_WHYST,,,,A proč?,Hvorfor det?,Wieo das?,,,¿Por qué?,,Miksi?,Pourquoi donc?,Miért tennék olyat?,E perché mai?,何故そんなことを。,그건 왜지?,Waarom is dat.,Hvorfor det?,Dlaczego tak jest?,Por quê?,,De ce.,Почему так?,,Varför det?,Nedenmiş o? +"Because, I told you he doesn't like visitors!",TXT_RYES0_SCRIPT27_D0_BECAU,,,,"Protože, jak už jsem řekl, nemá rád návštěvy!","Fordi jeg sagde jo, at han ikke kan lide besøgende!","Ich habe dir doch gesagt, dass er keine Besucher mag!",,,¡Porque te he dicho que no le gustan las visitas!,¡Te estoy diciendo que no le gustan las visitas!,"Koska minähän sanoin, ettei hän pidä vieraista!","Je vous ai dit, il n'aime pas les visiteurs!","Most mondtam, hogy nem szereti a látogatókat!","Perché, come ti ho appena detto, non gli piacciono i visitatori!",ナゼなら、マスターは訪問されたくナイからダ!,"왜냐하면, 그가 방문자들을 싫어한다고 내가 말했으니까!","Omdat hij niet van bezoekers houdt, zei ik toch!",Jeg sa jo at han ikke liker besøk!,"Bo mówiłem ci, że nie lubi gości!","Porque, como eu já te falei, ele não gosta de visitantes!",,"Pentru că, ți-am spus, nu-i plac vizitatorii!","Потому что, как я уже сказал тебе, он не любит посетителей!",,För att jag sa ju att han inte gillar besökare!,Çünkü sana ziyaretçileri sevmediğini söylemiştim! "You know, you're about the right size for one of the acolyte's uniforms.",TXT_DLG_SCRIPT27_D1516_YOUKN,,,,"Hele, ty vypadáš, že by ti dobře sedla unforma akolytů.",Du har den rette størrelse til en af acolyternes uniformer.,"Weißt du, du hast genau die richtige Größe für die Uniform eines Missionars.",,,"Sabes, tienes la talla justa para uno de los uniformes de acólito.",,"Hei kuules, olet suurin piirtein sopivan kokoinen akoluutin univormuun.","Vous savez, vous avez juste la taille qu'il faut pour un uniforme d'acolyte.","Tudod-e, hogy ránézésre pont jó rád a ministráns egyenruha.","Sai che ti dico, sei proprio della taglia perfetta per una delle uniforme degli accoliti.","知ッテるハズだ、アンタに合う -アコライトの制服一着のサイズについてサ。","어디보자... 당신의 치수, 경비 전투복 크기에 적당히 딱 맞는 것 같군!","Weet je, je bent ongeveer de juiste maat voor een van de uniformen van de acoliet.","Vet du, du har omtrent riktig størrelse for en av akolyttenes uniformer.","Wiesz, masz odpowiedni rozmiar na jeden z mundurków akolitów.","Sabe, você tem a altura perfeita para um dos uniformes de acólito.",,"Știi, eși marimea potrivită pentru o uniformă de acolit.","Знаешь, тебе бы как раз впору пошла униформа служителя.",,"Biliyor musun, yardımcı üniformalarından biri için doğru bedensin." +アコライトの制服一着のサイズについてサ。","어디보자... 당신의 치수, 경비 전투복 크기에 적당히 딱 맞는 것 같군!","Weet je, je bent ongeveer de juiste maat voor een van de uniformen van de acoliet.","Vet du, du har omtrent riktig størrelse for en av akolyttenes uniformer.","Wiesz, masz odpowiedni rozmiar na jeden z mundurków akolitów.","Sabe, você tem a altura perfeita para um dos uniformes de acólito.",,"Știi, eși marimea potrivită pentru o uniformă de acolit.","Знаешь, тебе бы как раз впору пошла униформа служителя.",,"Du vet, du är ungefär rätt storlek för en av akolyternas uniformer.","Biliyor musun, yardımcı üniformalarından biri için doğru bedensin." "Oh no, I'm not the real Programmer, he's hiding. Continue past the guard training area, very tough. If you survive, you might be able to talk to him. Or kill him.",TXT_DLG_SCRIPT31_D0_OHNOI,MAP31,,,"Kdepak, já nejsem skutečný Programátor. Ten se schovává. Ale pokračuj skrz tréninkovou oblast, je velmi obtížná. Jestli přežiješ, mohl by sis s ním i promluvit. Nebo ho zabít.","Åh nej, jeg er ikke den rigtige programmør. Han gemmer sig. Fortsæt forbi vagttræningsområdet, meget hårdt. Hvis du overlever, kan du måske tale med ham. Eller slå ham ihjel.","O nein, ich bin nicht der echte Programmierer. Er versteckt sich. Ich glaube irgendwo jenseits des Trainingsbereichs für die Wächter. verdammt schwierig. Wenn du überlebst könntest du in finden. Oder töten.",,,"Eh no, no soy el verdadero Programador; está escondido. Continúa a traves del área de entrenamiento de guardias. Muy difícil. Si sobrevives, tal vez puedas hablar con él. O matarlo.",,"Ehei, en ole oikea Ohjelmoitsija; hän piilottelee. Jatka vartijoiden koulutusalueen läpi; tulee olemaan haastavaa. Jos selviydyt, saatat ehkä pystyä puhumaan hänen kanssaan; tai tappaa hänet.","Oh non, je ne suis pas le vrai Programmeur. Il se cache. Continuez après la zone d'entraînement des gardes. C'est dangereux, mais si vous y arrivez, vous devriez pouvoir lui parler.. Ou le tuer.","Oh dehogy, nem Én vagyok az igazi Programozó, Ő most elbújt. Ha túléled az őrképző részleget, akkor rögtön utána megtalálod őt. Vagy éppen meg is ölheted.","Oh no, io non sono il vero Programmatore, lui si sta nascondendo. Procedi oltre l'area di addestramento delle guardie, molto tosta. Se sopravvivi, potresti riuscire a parlargli. O magari ad ucciderlo.","イヤイヤ、私ハ真ノプログラマーではない、 彼ハ隠れている。非常ニタフなガードノ 訓練場にダ、もし生き残れたら会えるだろう 或いハ彼を殺せるだろう。","하하. 아, 난 프로그래머님이 아니야. 그는 지금 숨고 있어. 경비 훈련소를 한번 체험해봐. 어렵겠지만, 한번 통과하면 너에게 말을 걸어줄지도 몰라. 아니면 널 죽이던가! - \cy내가 사람들 죽이는 걸 지겨워할 것 같지만, 이 일이 모두 끝나면 아마 그리워할 거야.","Oh nee, ik ben niet de echte programmeur, hij verstopt zich. Ga verder langs de bewakingsopleiding, heel moeilijk. Als je het overleeft, kun je misschien met hem praten. Of dood hem.","Å nei, jeg er ikke den ekte programmereren. Han gjemmer seg. Fortsett forbi vaktenes treningsområde, veldig tøft. Hvis du overlever, kan du kanskje snakke med ham. Eller drepe ham.","O nie, nie jestem prawdziwym Programistą, on się ukrywa. Kontynuuj obok obszaru szkolenia strażników, bardzo trudnego. Jeśli przeżyjesz, może uda ci się z nim porozmawiać. Albo go zabić.","Ah não, eu não sou o verdadeiro Programador. Ele está escondido. Continue pela área de treinamento de guardas. É bem difícil. Se você sobreviver, talvez você possa falar com ele. Ou matar ele.",,"Oh nu, nu sunt adevăratul Programator. Continuă până dincolo de câmpul de antrenament. Dacă supraviețuiești, vei putea vorbi cu el. Sau să îl omori.","О, нет. Я не настоящий Программист. Он прячется. На твоём пути лежит зона тренировки стражи. Пройти её очень непросто. Если уцелеешь, то сможешь поговорить с ним... или убить его.",,"Oh hayır, ben gerçek Programcı değilim, o saklanıyor. Muhafız eğitim alanını geçmeye devam et, çok zorlu. Eğer hayatta kalırsan, onunla konuşabilirsin. Ya da onu öldürebilirsin." -Who are you?,TXT_RPLY0_SCRIPT31_D0_WHOAR,〃,,,Kdo jsi?,Hvem er du?,Wer bist du?,,Kiu vi estas?,¿Quién eres?,,Kuka sinä olet?,Qui êtes vous?,Ki vagy te?,E tu chi sei?,お前は誰だ?,당신은 누구죠?,Wie ben jij?,Hvem er du?,Kim jesteś?,Quem é você?,,Cine ești?,Кто ты?,,Kimsin sen? -You'll never find anything if you hang around here.,TXT_DLG_SCRIPT31_D1516_YOULL,〃,,,"Nic nenajdeš, když se tu budeš potloukat.","Du finder aldrig noget, hvis du bliver hængende her.","Du wirst niemals etwas finden, wenn du hier herumhängst.",,,Nunca encontrarás nada si permaneces aquí.,,"Et saa ikinä mitään selville, jos jäät tänne oleilemaan.",Vous ne découvrerez rien si vous traînez ici.,"Nem fogsz semmit se találni, ha csak itt bóklászol.",Non troverai nulla se rimani fermo qui.,アンタがここをふらついても何も無いよ。,여기에 계속 머무르고 있으면 다 알지도 못할걸.,Je zult nooit iets vinden als je hier rondhangt.,Du finner aldri noe hvis du blir her.,"Nic nie znajdziesz, jeśli będziesz się tu kręcił.",Você nunca vai descobrir nada se ficar por aqui.,,N-o să aflii nimic dacă pierzi timpul aici.,"Ты ничего не добьёшься, если будешь ошиваться тут.",,Buralarda takılırsan asla bir şey bulamazsın. -Piss off peasant!,TXT_DLG_SCRIPT32_D0_PISSO,〃,,,"Odprejskni, poddaný!",Pis af bonde!,"Verpiss dich, du Bauer!",,,"¡Esfúmate, campesino!",,"Suksi suohon, maallikko!","Dégage, paysan!",Takarodj a színem elől paraszt!,"Fuori dai piedi, cittadino!",イラつかせるな、田吾作が!,"저리 꺼져라, 시민!",Boer boer kwaad maken!,"Dra til helvete, bonde!",Odwal się chłopie!,"Suma daqui, plebeu!",,"Valea, sărmanule!","Вали отсюда, рабочий!",,Defol köylü! -Die little man!,TXT_DLG_SCRIPT32_D1516_DIELI,"Appears in MAP32 and is supposed to be spoken by the AcolyteRust actor (named “Interrogator”). However, no such actor is spawned in the map, rendering this line unused.",,,"Zemři, mužíčku!","Dø, lille mand!","Stirb, kleiner Mann!",,"Mortu, nano!","¡Muere, enano!",,"Kuole, pikku mies!","Meurs, petite frappe!",,"Muori, piccolo uomo!",,죽어라. 나약한 것!,Sterf kleine man!,"Dø, lille mann!",Giń mały człowieku!,"Morra, insignificante!",,"Mori, mititelule!","Сдохни, человечишка!",,Geber küçük adam! -Finally I can get out of this cell.,TXT_DLG_SCRIPT32_D3032_FINAL,MAP32: Cell.,,,Konečně se můžu z téhle cely dostat.,Endelig kan jeg komme ud af denne celle.,Endlich kann ich aus dieser Zelle raus.,,Mi finfine estas libera.,Por fin puedo salir de esta celda.,,"Vihdoinkin, voin päästä pois tästä sellistä.","Enfin, je peux sortir de cette cellule.",Végre kiszabadulhatok ebből a cellából.,Finalmente posso uscire da questa cella.,遂に、この独房から抜け出せる。,드디어 이 감옥에서 벗어나는구나...,Eindelijk kan ik uit deze cel komen.,Endelig kan jeg komme ut av denne cella.,Wreszcie mogę się wydostać z tej celi.,Finalmente eu posso sair desta cela.,,În sfârșit pot părăsi celula asta.,Наконец-то я могу сбежать из этой камеры!,,Sonunda bu hücreden çıkabilirim. -Why are you in here?,TXT_RPLY0_SCRIPT32_D3032_WHYAR,〃,,,Proč tu jsi?,Hvorfor er du herinde?,Warum bist du da drin?,,Kial vi estas ĉi tie?,¿Por que estás aquí?,,Miksi olet täällä?,Pourquoi êtes vous ici?,Miért vagy itt bent?,Perché ti trovi qui?,何でここにいる?,너가 왜 여기있지?,Waarom ben je hier binnen?,Hvorfor er du her?,Dlaczego tu jesteś?,Por que você está aqui?,,De ce ești închis?,Как ты здесь оказался?,,Sen neden buradasın? -I was framed.,TXT_RYES0_SCRIPT32_D3032_IWASF,〃,,,Podvedli mě.,Jeg er blevet snydt.,Ich wurde hereingelegt.,,Mi estis akuzita.,Fui incriminado.,,Minut lavastettiin.,J'ai été victime d'un coup monté.,Meggyanúsítottak.,Mi hanno incastrato.,私は無実だ。,저는 누명을 썼어요.,Ik werd erin geluisd.,Jeg ble lurt i en felle.,Zostałem wrobiony.,Eu caí numa cilada.,,Am fost înscenat.,Меня подставили.,,Bana komplo kuruldu. + \cy내가 사람들 죽이는 걸 지겨워할 것 같지만, 이 일이 모두 끝나면 아마 그리워할 거야.","Oh nee, ik ben niet de echte programmeur, hij verstopt zich. Ga verder langs de bewakingsopleiding, heel moeilijk. Als je het overleeft, kun je misschien met hem praten. Of dood hem.","Å nei, jeg er ikke den ekte programmereren. Han gjemmer seg. Fortsett forbi vaktenes treningsområde, veldig tøft. Hvis du overlever, kan du kanskje snakke med ham. Eller drepe ham.","O nie, nie jestem prawdziwym Programistą, on się ukrywa. Kontynuuj obok obszaru szkolenia strażników, bardzo trudnego. Jeśli przeżyjesz, może uda ci się z nim porozmawiać. Albo go zabić.","Ah não, eu não sou o verdadeiro Programador. Ele está escondido. Continue pela área de treinamento de guardas. É bem difícil. Se você sobreviver, talvez você possa falar com ele. Ou matar ele.",,"Oh nu, nu sunt adevăratul Programator. Continuă până dincolo de câmpul de antrenament. Dacă supraviețuiești, vei putea vorbi cu el. Sau să îl omori.","О, нет. Я не настоящий Программист. Он прячется. На твоём пути лежит зона тренировки стражи. Пройти её очень непросто. Если уцелеешь, то сможешь поговорить с ним... или убить его.",,"Åh nej, jag är inte den riktiga programmeraren, han gömmer sig. Fortsätt förbi vakternas träningsområde, mycket tufft. Om du överlever kanske du kan prata med honom. Eller döda honom.","Oh hayır, ben gerçek Programcı değilim, o saklanıyor. Muhafız eğitim alanını geçmeye devam et, çok zorlu. Eğer hayatta kalırsan, onunla konuşabilirsin. Ya da onu öldürebilirsin." +Who are you?,TXT_RPLY0_SCRIPT31_D0_WHOAR,〃,,,Kdo jsi?,Hvem er du?,Wer bist du?,,Kiu vi estas?,¿Quién eres?,,Kuka sinä olet?,Qui êtes vous?,Ki vagy te?,E tu chi sei?,お前は誰だ?,당신은 누구죠?,Wie ben jij?,Hvem er du?,Kim jesteś?,Quem é você?,,Cine ești?,Кто ты?,,Vem är du?,Kimsin sen? +You'll never find anything if you hang around here.,TXT_DLG_SCRIPT31_D1516_YOULL,〃,,,"Nic nenajdeš, když se tu budeš potloukat.","Du finder aldrig noget, hvis du bliver hængende her.","Du wirst niemals etwas finden, wenn du hier herumhängst.",,,Nunca encontrarás nada si permaneces aquí.,,"Et saa ikinä mitään selville, jos jäät tänne oleilemaan.",Vous ne découvrerez rien si vous traînez ici.,"Nem fogsz semmit se találni, ha csak itt bóklászol.",Non troverai nulla se rimani fermo qui.,アンタがここをふらついても何も無いよ。,여기에 계속 머무르고 있으면 다 알지도 못할걸.,Je zult nooit iets vinden als je hier rondhangt.,Du finner aldri noe hvis du blir her.,"Nic nie znajdziesz, jeśli będziesz się tu kręcił.",Você nunca vai descobrir nada se ficar por aqui.,,N-o să aflii nimic dacă pierzi timpul aici.,"Ты ничего не добьёшься, если будешь ошиваться тут.",,Du kommer aldrig att hitta något om du hänger kvar här.,Buralarda takılırsan asla bir şey bulamazsın. +Piss off peasant!,TXT_DLG_SCRIPT32_D0_PISSO,〃,,,"Odprejskni, poddaný!",Pis af bonde!,"Verpiss dich, du Bauer!",,,"¡Esfúmate, campesino!",,"Suksi suohon, maallikko!","Dégage, paysan!",Takarodj a színem elől paraszt!,"Fuori dai piedi, cittadino!",イラつかせるな、田吾作が!,"저리 꺼져라, 시민!",Boer boer kwaad maken!,"Dra til helvete, bonde!",Odwal się chłopie!,"Suma daqui, plebeu!",,"Valea, sărmanule!","Вали отсюда, рабочий!",,Dra åt helvete bonde!,Defol köylü! +Die little man!,TXT_DLG_SCRIPT32_D1516_DIELI,"Appears in MAP32 and is supposed to be spoken by the AcolyteRust actor (named “Interrogator”). However, no such actor is spawned in the map, rendering this line unused.",,,"Zemři, mužíčku!","Dø, lille mand!","Stirb, kleiner Mann!",,"Mortu, nano!","¡Muere, enano!",,"Kuole, pikku mies!","Meurs, petite frappe!","Halál rád, te jöttment!","Muori, piccolo uomo!",,죽어라. 나약한 것!,Sterf kleine man!,"Dø, lille mann!",Giń mały człowieku!,"Morra, insignificante!",,"Mori, mititelule!","Сдохни, человечишка!",,"Dö, lilla man!",Geber küçük adam! +Finally I can get out of this cell.,TXT_DLG_SCRIPT32_D3032_FINAL,MAP32: Cell.,,,Konečně se můžu z téhle cely dostat.,Endelig kan jeg komme ud af denne celle.,Endlich kann ich aus dieser Zelle raus.,,Mi finfine estas libera.,Por fin puedo salir de esta celda.,,"Vihdoinkin, voin päästä pois tästä sellistä.","Enfin, je peux sortir de cette cellule.",Végre kiszabadulhatok ebből a cellából.,Finalmente posso uscire da questa cella.,遂に、この独房から抜け出せる。,드디어 이 감옥에서 벗어나는구나...,Eindelijk kan ik uit deze cel komen.,Endelig kan jeg komme ut av denne cella.,Wreszcie mogę się wydostać z tej celi.,Finalmente eu posso sair desta cela.,,În sfârșit pot părăsi celula asta.,Наконец-то я могу сбежать из этой камеры!,,Äntligen kan jag komma ut ur den här cellen.,Sonunda bu hücreden çıkabilirim. +Why are you in here?,TXT_RPLY0_SCRIPT32_D3032_WHYAR,〃,,,Proč tu jsi?,Hvorfor er du herinde?,Warum bist du da drin?,,Kial vi estas ĉi tie?,¿Por que estás aquí?,,Miksi olet täällä?,Pourquoi êtes vous ici?,Miért vagy itt bent?,Perché ti trovi qui?,何でここにいる?,너가 왜 여기있지?,Waarom ben je hier binnen?,Hvorfor er du her?,Dlaczego tu jesteś?,Por que você está aqui?,,De ce ești închis?,Как ты здесь оказался?,,Varför är du här inne?,Sen neden buradasın? +I was framed.,TXT_RYES0_SCRIPT32_D3032_IWASF,〃,,,Podvedli mě.,Jeg er blevet snydt.,Ich wurde hereingelegt.,,Mi estis akuzita.,Fui incriminado.,,Minut lavastettiin.,J'ai été victime d'un coup monté.,Meggyanúsítottak.,Mi hanno incastrato.,私は無実だ。,저는 누명을 썼어요.,Ik werd erin geluisd.,Jeg ble lurt i en felle.,Zostałem wrobiony.,Eu caí numa cilada.,,Am fost înscenat.,Меня подставили.,,Jag blev lurad.,Bana komplo kuruldu. Harris said that I was plotting to kill the Governor. I would never harm a soul.,TXT_DLG_SCRIPT32_D4548_HARRI,〃,,,"Harris řekl, že jsem prý měl v plánu zavraždit guvernéra. Ani mouše bych neublížil.","Harris sagde, at jeg planlagde at dræbe guvernøren. Jeg ville aldrig skade nogen.","Harris hat erzählt, das ich plante den Gouverneur zu ermorden. Ich könnte keiner Menschenseele etwas antun.",,"Harris diris, ke mi planas mortigi la registon. Mi neniam vundus iun.",Harris dijo que yo estaba planeando matar al gobernador. Y yo no podría hacerle nada a nadie.,,Harris väitti minun juonineen kuvernöörin salamurhaa. En ikinä satuttaisi ketään.,Harris a dit que j'avais un plan pour tuer le gouverneur. Je ne ferais pas de mal à qui que ce soit.,"Harris azt nyilatkozta, hogy a kormányzó életére akarok törni. Egy légynek sem ártanék.",Harris ha detto che progettavo di uccidere il governatore. Ma io non farei mai del male a nessuno.,"ハリスに知事の暗殺を企てていると言われた。 -そんなこと心にも思ったことは無いのに。","해리스가 말하길, 제가 총독 암살을 꾀했데요. 난 파리 한마리도 못 죽이는데...",Harris zei dat ik van plan was om de gouverneur te vermoorden. Ik zou nooit een ziel kwaad doen.,Harris sa at jeg planla å drepe guvernøren. Jeg ville aldri skade noen.,"Harris powiedział, że spiskowałem, by zabić gubernatora. Nigdy nie skrzywdziłbym żadnej duszy.",O Harris disse que eu estava planejando matar o Governador. Eu nunca faria mal a qualquer pessoa.,,Harris a spus că plănuiam să-l omor pe Guvernator. N-aș răni un suflet niciodată.,"Харрис сказал, что я замышлял убийство губернатора. А я и мухи не обижу!",,"Harris, Vali'yi öldürmeyi planladığımı söyledi. Kimseye zarar vermem." -Be careful out there.,TXT_DLG_SCRIPT33_D0_BECAR,,,,Buď tam venku opatrný.,Vær forsigtig derude.,Sei vorsichtig dort draußen.,,,Ten cuidado ahí fuera.,,Pidä itsestäsi huoli.,Faites attention à vous.,Légy óvatos odakint.,Stai attento là fuori.,外は気をつけろ。,조심해.,Wees voorzichtig daarbuiten.,Vær forsiktig der ute.,Bądź ostrożny.,Tome cuidado por aí.,,Ai grijă pe-acolo.,Будь поосторожнее.,,Dışarıda dikkatli ol. +そんなこと心にも思ったことは無いのに。","해리스가 말하길, 제가 총독 암살을 꾀했데요. 난 파리 한마리도 못 죽이는데...",Harris zei dat ik van plan was om de gouverneur te vermoorden. Ik zou nooit een ziel kwaad doen.,Harris sa at jeg planla å drepe guvernøren. Jeg ville aldri skade noen.,"Harris powiedział, że spiskowałem, by zabić gubernatora. Nigdy nie skrzywdziłbym żadnej duszy.",O Harris disse que eu estava planejando matar o Governador. Eu nunca faria mal a qualquer pessoa.,,Harris a spus că plănuiam să-l omor pe Guvernator. N-aș răni un suflet niciodată.,"Харрис сказал, что я замышлял убийство губернатора. А я и мухи не обижу!",,Harris sa att jag planerade att döda guvernören. Jag skulle aldrig skada en själ.,"Harris, Vali'yi öldürmeyi planladığımı söyledi. Kimseye zarar vermem." +Be careful out there.,TXT_DLG_SCRIPT33_D0_BECAR,,,,Buď tam venku opatrný.,Vær forsigtig derude.,Sei vorsichtig dort draußen.,,,Ten cuidado ahí fuera.,,Pidä itsestäsi huoli.,Faites attention à vous.,Légy óvatos odakint.,Stai attento là fuori.,外は気をつけろ。,조심해.,Wees voorzichtig daarbuiten.,Vær forsiktig der ute.,Bądź ostrożny.,Tome cuidado por aí.,,Ai grijă pe-acolo.,Будь поосторожнее.,,Var försiktig där ute.,Dışarıda dikkatli ol. "Say friend, I'll help you, if you help me. Give me 5 gold and I'll tell you what I know.",TXT_DLG_SCRIPT33_D1516_SAYFR,MAP33: Guy next to Norwall Prison.,,,"Poslyš, příteli, pomůžu ti, když ti pomůžeš mě. Dej mi pět zlatých a já ti řeknu, co vím.","Sig ven, jeg vil hjælpe dig, hvis du hjælper mig. Giv mig 5 guld, så fortæller jeg dig, hvad jeg ved.","Sag, mein Freund. Ich helfe dir, wenn du mir hilst. Gib mir 5 Gold und ich sage dir was ich weiß.",,"Nu, amiko, mi helpos vin se vi helpas min. Donu 5 da oro kaj mi diros tion, kion mi scias.","A ver, amigo, te ayudo si tú me ayudas. Dame 5 de oro y te digo lo que sé.",,"Hei kuule; voin auttaa sinua, jos autat minua. Viidestä kultakolikosta kerron sinulle, mitä tiedän.","Dites, l'ami. Je vous aide si vous m'aidez. Donnez moi 5 pièces et je vous dirais ce que je sais.","Figyelj barátom, segítek rajtad ha te is segítesz. Adj szépen 5 aranyat és elárulom amit tudok.","Senti qua, amico, io aiuterò te se tu aiuterai me. Dammi 5 pezzi d'oro e ti dirò tutto quello che so.","助けてくれるなら援助する。 -5ゴールドで知っている情報を全て教えよう","친구, 나는 너를 도와주고 싶어. 그러기 전에 나에게 5 골드를 줘. 그럼 내가 아는 걸 알려줄게.","Zeg vriend, ik zal je helpen, als je me helpt. Geef me 5 goud en ik zal je vertellen wat ik weet.","Jeg skal hjelpe deg, hvis du hjelper meg. Gi meg fem gull, så forteller jeg hva jeg vet.","Powiedz przyjacielu, pomogę ci, jeśli ty pomożesz mi. Daj mi 5 złotych, a powiem ci, co wiem.","Que tal, eu te ajudo se você me ajudar. Me dê 5 moedas de ouro e eu te digo o que eu sei.",,"Să zicem prietene, că te ajut, dacă și tu m-ajuți. Dă-mi 5 monezi și îți voi spune ce știu.","Дружище, я помогу тебе, если ты поможешь мне. Пять золотых, и я расскажу тебе всё, что знаю!",,"Dostum, sen bana yardım edersen ben de sana yardım ederim. Bana 5 altın ver, ben de sana bildiklerimi anlatayım." -Here's the gold.,TXT_RPLY0_SCRIPT33_D1516_HERES,〃,,,Tady máš to zlato.,Her er guldet.,Hier ist das Gold.,,Jen la oro.,Aquí tienes el oro.,,Tässä kulta.,Voilà votre argent.,Itt az arany.,Ecco l'oro.,金はこれだ。,여기 골드입니다.,Hier is het goud.,Her er gullet.,Oto złoto.,Tome estas moedas.,,Aici e aurul.,Вот монеты.,,İşte altın. +5ゴールドで知っている情報を全て教えよう","친구, 나는 너를 도와주고 싶어. 그러기 전에 나에게 5 골드를 줘. 그럼 내가 아는 걸 알려줄게.","Zeg vriend, ik zal je helpen, als je me helpt. Geef me 5 goud en ik zal je vertellen wat ik weet.","Jeg skal hjelpe deg, hvis du hjelper meg. Gi meg fem gull, så forteller jeg hva jeg vet.","Powiedz przyjacielu, pomogę ci, jeśli ty pomożesz mi. Daj mi 5 złotych, a powiem ci, co wiem.","Que tal, eu te ajudo se você me ajudar. Me dê 5 moedas de ouro e eu te digo o que eu sei.",,"Să zicem prietene, că te ajut, dacă și tu m-ajuți. Dă-mi 5 monezi și îți voi spune ce știu.","Дружище, я помогу тебе, если ты поможешь мне. Пять золотых, и я расскажу тебе всё, что знаю!",,"Säg vän, jag hjälper dig om du hjälper mig. Ge mig fem guld så berättar jag vad jag vet.","Dostum, sen bana yardım edersen ben de sana yardım ederim. Bana 5 altın ver, ben de sana bildiklerimi anlatayım." +Here's the gold.,TXT_RPLY0_SCRIPT33_D1516_HERES,〃,,,Tady máš to zlato.,Her er guldet.,Hier ist das Gold.,,Jen la oro.,Aquí tienes el oro.,,Tässä kulta.,Voilà votre argent.,Itt az arany.,Ecco l'oro.,金はこれだ。,여기 골드입니다.,Hier is het goud.,Her er gullet.,Oto złoto.,Tome estas moedas.,,Aici e aurul.,Вот монеты.,,Här är guldet.,İşte altın. "If you punch someone, you won't set off the alarms.",TXT_RYES0_SCRIPT33_D1516_IFYOU,〃,,,"Když někoho praštíš, nespustíš alarmy.","Hvis du slår nogen, vil du ikke udløse alarmen.","Wenn du jemanden schlägst, wirst du keinen Alarm auslösen.",,Piki iun ne ekagigas alarmojn.,"Acuchillar a alguien -no activa las alarmas.",,"Jos lyöt jotakuta nyrkillä, et laukaise hälyttimiä.","Si vous plantez quelqu'un avec votre dague de poing, vous n'activez pas les alarmes.","Ha behúzol valakinek, még nem indul be a riasztó.","Se usi i pugni, non attiverai l'allarme.",パンチならアラームを鳴らせることはない。,"만약 네가 누군가를 주먹으로 때린다면, 알람은 울리지 않을 거야.","Als je iemand slaat, zal je het alarm niet afgaan.","Hvis du slår noen, utløser du ikke alarmen.","Jeśli kogoś uderzysz, nie uruchomisz alarmów.","Se você der um soco em alguém, você não ativará os alarmes.",,"Dacă îi tragi un pumn cuiva, nu vei declanșa alarma.","Убивай холодным оружием, тогда ты не поднимешь тревогу.",,"Eğer birine yumruk atarsan, alarmları çalıştırmazsın." -I won't tell you anything for free!,TXT_RNO0_SCRIPT33_D1516_IWONT,〃,,,Zadarmo ti nic říkat nebudu!,Jeg vil ikke fortælle dig noget gratis!,Umsonst werde ich dir nichts sagen.,,Mi diros nenion senpage!,¡No te diré nada gratis!,¡No te voy a decir nada gratis!,En kerro mitään ilmaiseksi!,Je ne vous dirai rien gratuitement!,Nem árulok el ingyen semmit se!,Non ti dirò nulla se prima non vedo l'oro!,タダでは教えられないな!,무료로는 말 못 해!,Ik zal je niets gratis vertellen!,Jeg forteller deg ikke noe gratis!,Nie powiem ci nic za darmo!,Não te direi nada de graça!,,Nu-ți voi spune nimic pe gratis.,Бесплатно я не скажу ничего!,,Sana bedavaya bir şey söylemeyeceğim! -I've already told you what I know.,TXT_DLG_SCRIPT33_D3032_IVEAL,〃,,,"Už jsem ti řekl, co vím.","Jeg har allerede fortalt dig, hvad jeg ved.","Ich habe dir alles gesagt, was ich weiß.",,"Mi jam diris tion, kion mi scias.",Ya te he dicho lo que sé.,Ya te dije lo que sé.,"Olen jo kertonut sinulle, mitä tiedän.",Je vous ai dit tout ce que je sais.,Már elmondtam amit tudtam.,Ti ho già detto ciò che so.,俺が知っていることはこれで全部だ。,난 이미 내가 아는 걸 말해 줬어!,Ik heb je al verteld wat ik weet.,Jeg har allerede fortalt deg det jeg vet.,"Już ci powiedziałem, co wiem.",Já te disse o que eu sei.,,Ți-am spus deja tot ce știu.,"Я уже сказал тебе всё, что знал.",,Sana bildiklerimi anlattım zaten. -Hello friend. What can I get for you?,TXT_DLG_SCRIPT33_D4548_HELLO,MAP33: Weapons.,,,"Zdravím, příteli, co ti mohu nabídnout?","Hej, min ven. Hvad kan jeg få for dig?","Hallo, Freund, was kann ich dir geben?",,"Saluton, amiko. Kion mi donu al vi?","Hola, amigo. ¿Qué puedo ofrecerte?",,"Terve, ystävä; miten voin olla avuksi?","Bonjour, l'ami, que puis-je pour vous?",Üdvözöllek barátom. Mit tehetek érted?,"Salve, amico. Cosa posso procurarti?",どうも同士よ。何か必要か?,"안녕하십니까, 친구여. 구매하고 싶은 게 있습니까?",Hallo vriend. Wat kan ik voor je halen?,"Hei, min venn. Hva vil du ha?",Witaj przyjacielu. Co mogę dla ciebie zdobyć?,"Olá amigo, como posso te ajudar?",,"Bună prietene, ce pot să-ți aduc?",Здравствуй. Что-нибудь интересует?,,Merhaba dostum. Senin için ne yapabilirim? -Electric bolts,TXT_RPLY0_SCRIPT33_D4548_ELECT,〃,,,Elektrické šípy,Elektriske bolte,Elektrische Pfeile,,,Flechas eléctricas,,Sähkönuolia,Carreaux électriques.,Elektromos nyilak,Dardi elettrificati ,エレクトリック ボルト,전격 볼트,Elektrische bouten,Elektriske bolter.,Elektryczne śruby.,Setas elétricas,,Bolțuri electrice,Электрические болты,,Elektrikli cıvata. -One quarrel it is.,TXT_RYES0_SCRIPT33_D4548_ONEQU,〃,,,Jeden toulec.,Et skænderi bliver det.,Hier hast du sie.,,,Marchando unas flechas.,,"Tässä, olkaa hyvä.",Un carquois pour vous.,Itt is van.,Eccoli qua.,クォーレル一本だ。,잔소리 없이 주겠습니다.,Eén ruzie is het.,En krangel blir det.,Jedna kłótnia to jest.,Está na mão.,,Aici sunt.,Один колчан.,,Tek bir tartışma. -You're broke!,TXT_RNO0_SCRIPT33_D4548_YOURE,〃,,,Jseš švorc!,Du er flad!,Du bist pleite!,,Vi ne havas monon!,¡Estás sin blanca!,¡Estás quebrado!,Olet peeaa!,Vous êtes à sec!,Nincs is nálad pénz!,Sei sul lastrico!,スッカラカンじゃないか!,돈이 한 푼도 없는 것 같은데.,Je bent blut!,Du er blakk!,Jesteście spłukani!,Você está sem grana!,,Ești falit!,"Друг, да ты на мели!",,Beş parasızsın! -Clip of bullets,TXT_RPLY1_SCRIPT33_D4548_10ROU,〃,,,Zásobník s náboji,Et patron-klip,10-Kugeln-Magazin,,Magazenon,Un cargador,,Luotilipas,Chargeur de 10 cartouches.,Egy tárnyi töltény,Un caricatore di proiettili,銃弾倉,돌격소총 탄창,Klem van kogels,Et magasin med kuler,Klips z kulami.,Carregador de balas,,Cartuș de gloanțe,Обойма патронов,,Mermi şarjörü -Here's your ammo,TXT_RYES1_SCRIPT33_D4548_HERES,〃,,,Tady je tvá munice.,Her er din ammunition,Hier ist deine Munition.,,,Aquí tienes tu munición.,,Tässä panoksesi.,Voilà vos balles.,Itt a töltényed.,Ecco le tue munizioni.,これでアンタのブツだ。,여기 탄약입니다.,Hier is je munitie....,Her er ammunisjonen din,Oto twoja amunicja.,Aqui está a sua munição.,,Aici e.,Вот твои патроны.,,İşte cephaneniz. -"Sorry, no money, no bullets.",TXT_RNO1_SCRIPT33_D4548_SORRY,〃,,,"Promiň. Žádné peníze, žádné náboje.","Beklager, ingen penge, ingen kugler.","Tut mir leid. Kein Geld, keine Munition.",,Pardonon. Sen mono ne estas kugloj.,"Lo siento, sin dinero, no hay balas.",,"Valitan, ei rahaa, ei luoteja.","Désolé, pas d'argent, pas de munitions.","Ha nincs pénz, nincs töltény.","Mi spiace, niente soldi, niente munizioni.",悪いが、金が無ければブツも無しだ。,돈 없으면 거래 못 합니다.,"Sorry, geen geld, geen kogels.","Beklager, ingen penger, ingen kuler.","Niestety, nie ma pieniędzy, nie ma naboi.","Desculpe. Sem grana, sem balas.",,"Scuze, niciun ban, niciun glonț.","Извини, нет денег — нет патронов!",,"Üzgünüm, para yoksa mermi de yok." -Ammo box,TXT_RPLY2_SCRIPT33_D4548_50ROU,〃,,,Krabici nábojů,Ammo kasse,50-Kugeln-Schachtel,,Municikesto,Caja de municiones,,Luotilaatikko,Boîte de 50 balles.,Töltény doboz,Scatola di munizioni,銃弾倉箱,돌격소총 탄약 박스,Munitiedoos,Ammunisjonsboks,Skrzynka z amunicją.,Caixa de munição,,Cutie cu muniție,Коробка патронов,,Cephane kutusu -Here you go,TXT_RYES2_SCRIPT33_D4548_HEREY,〃,,,Tu máš.,Værsgo.,Bitteschön.,,Jen,Aquí tienes,,Ole hyvä.,Voilà pour vous.,Parancsolj.,Ecco a te.,どうぞ。,거래 감사드립니다.,Alsjeblieft,Vær så god.,Proszę bardzo.,Aqui está,,Aici este,Держи.,,Al bakalım. -You don't have enough gold!,TXT_RNO2_SCRIPT33_D4548_YOUDO,〃,,,Nemáš dost zlaťáků!,Du har ikke nok guld!,Du hast nicht genug Gold.,,Vi ne havas sufiĉe da oro!,¡No tienes suficiente oro!,,Sinulla ei ole riittävästi kultaa!,Vous n'avez pas assez d'argent.,Nincs elég aranyad.,Non hai abbastanza oro!,十分な額じゃない,골드가 충분치 않군요!,Je hebt niet genoeg goud!,Du har ikke nok gull!,Nie masz wystarczająco dużo złota!,Você não tem ouro suficiente!,,Nu ai suficient aur!,У тебя недостаточно золота!,,Yeterince altının yok! -Ammo satchel,TXT_RPLY3_SCRIPT33_D4548_AMMOS,〃,,,Brašnu na munici,Ammotaske,Munitionstasche.,,,Mochila de municiones,,Ammuslaukku,Sacoche de munitions.,Lőszeres hátizsák,Sacca di munizioni,弾薬鞄,탄약 배낭,Munitie tasje,Ammunisjonsveske,Torba na amunicję,Mochila de munição,,Sac cu muniție,Ранец для боеприпасов,,Cephane çantası -"Thank you, anything else?",TXT_RYES3_SCRIPT33_D4548_THANK,〃,,,Děkuji. Něco dalšího?,"Tak, er der andet?","Danke, sonst noch was?",,,Gracias. ¿Algo más?,,Kiitos; vielä jotain muuta?,"Merci, quelque chose d'autre?","Köszönöm, még valami esetleg?","Grazie, serve qualcos'altro?",ありがとう。 他に何か?,좋습니다! 더 필요한 거라도?,"Bedankt, nog iets anders?","Takk, noe mer?","Dziękuję, coś jeszcze?",Obrigado. Mais alguma coisa?,,"Merci, altceva?",Благодарю. Что-нибудь ещё?,,"Teşekkürler, başka bir şey var mı?" +no activa las alarmas.",,"Jos lyöt jotakuta nyrkillä, et laukaise hälyttimiä.","Si vous plantez quelqu'un avec votre dague de poing, vous n'activez pas les alarmes.","Ha behúzol valakinek, még nem indul be a riasztó.","Se usi i pugni, non attiverai l'allarme.",パンチならアラームを鳴らせることはない。,"만약 네가 누군가를 주먹으로 때린다면, 알람은 울리지 않을 거야.","Als je iemand slaat, zal je het alarm niet afgaan.","Hvis du slår noen, utløser du ikke alarmen.","Jeśli kogoś uderzysz, nie uruchomisz alarmów.","Se você der um soco em alguém, você não ativará os alarmes.",,"Dacă îi tragi un pumn cuiva, nu vei declanșa alarma.","Убивай холодным оружием, тогда ты не поднимешь тревогу.",,Om du slår någon så kommer du inte att utlösa larmet.,"Eğer birine yumruk atarsan, alarmları çalıştırmazsın." +I won't tell you anything for free!,TXT_RNO0_SCRIPT33_D1516_IWONT,〃,,,Zadarmo ti nic říkat nebudu!,Jeg vil ikke fortælle dig noget gratis!,Umsonst werde ich dir nichts sagen.,,Mi diros nenion senpage!,¡No te diré nada gratis!,¡No te voy a decir nada gratis!,En kerro mitään ilmaiseksi!,Je ne vous dirai rien gratuitement!,Nem árulok el ingyen semmit se!,Non ti dirò nulla se prima non vedo l'oro!,タダでは教えられないな!,무료로는 말 못 해!,Ik zal je niets gratis vertellen!,Jeg forteller deg ikke noe gratis!,Nie powiem ci nic za darmo!,Não te direi nada de graça!,,Nu-ți voi spune nimic pe gratis.,Бесплатно я не скажу ничего!,,Jag kommer inte att berätta något gratis!,Sana bedavaya bir şey söylemeyeceğim! +I've already told you what I know.,TXT_DLG_SCRIPT33_D3032_IVEAL,〃,,,"Už jsem ti řekl, co vím.","Jeg har allerede fortalt dig, hvad jeg ved.","Ich habe dir alles gesagt, was ich weiß.",,"Mi jam diris tion, kion mi scias.",Ya te he dicho lo que sé.,Ya te dije lo que sé.,"Olen jo kertonut sinulle, mitä tiedän.",Je vous ai dit tout ce que je sais.,Már elmondtam amit tudtam.,Ti ho già detto ciò che so.,俺が知っていることはこれで全部だ。,난 이미 내가 아는 걸 말해 줬어!,Ik heb je al verteld wat ik weet.,Jeg har allerede fortalt deg det jeg vet.,"Już ci powiedziałem, co wiem.",Já te disse o que eu sei.,,Ți-am spus deja tot ce știu.,"Я уже сказал тебе всё, что знал.",,Jag har redan berättat vad jag vet.,Sana bildiklerimi anlattım zaten. +Hello friend. What can I get for you?,TXT_DLG_SCRIPT33_D4548_HELLO,MAP33: Weapons.,,,"Zdravím, příteli, co ti mohu nabídnout?","Hej, min ven. Hvad kan jeg få for dig?","Hallo, Freund, was kann ich dir geben?",,"Saluton, amiko. Kion mi donu al vi?","Hola, amigo. ¿Qué puedo ofrecerte?",,"Terve, ystävä; miten voin olla avuksi?","Bonjour, l'ami, que puis-je pour vous?",Üdvözöllek barátom. Mit tehetek érted?,"Salve, amico. Cosa posso procurarti?",どうも同士よ。何か必要か?,"안녕하십니까, 친구여. 구매하고 싶은 게 있습니까?",Hallo vriend. Wat kan ik voor je halen?,"Hei, min venn. Hva vil du ha?",Witaj przyjacielu. Co mogę dla ciebie zdobyć?,"Olá amigo, como posso te ajudar?",,"Bună prietene, ce pot să-ți aduc?",Здравствуй. Что-нибудь интересует?,,"Hej, min vän. Vad kan jag få för dig?",Merhaba dostum. Senin için ne yapabilirim? +Electric bolts,TXT_RPLY0_SCRIPT33_D4548_ELECT,〃,,,Elektrické šípy,Elektriske bolte,Elektrische Pfeile,,,Flechas eléctricas,,Sähkönuolia,Carreaux électriques.,Elektromos nyilak,Dardi elettrificati ,エレクトリック ボルト,전격 볼트,Elektrische bouten,Elektriske bolter.,Elektryczne śruby.,Setas elétricas,,Bolțuri electrice,Электрические болты,,Elektriska bultar,Elektrikli cıvata. +One quarrel it is.,TXT_RYES0_SCRIPT33_D4548_ONEQU,〃,,,Jeden toulec.,Et skænderi bliver det.,Hier hast du sie.,,,Marchando unas flechas.,,"Tässä, olkaa hyvä.",Un carquois pour vous.,Itt is van.,Eccoli qua.,クォーレル一本だ。,잔소리 없이 주겠습니다.,Eén ruzie is het.,En krangel blir det.,Jedna kłótnia to jest.,Está na mão.,,Aici sunt.,Один колчан.,,Ett gräl blir det.,Tek bir tartışma. +You're broke!,TXT_RNO0_SCRIPT33_D4548_YOURE,〃,,,Jseš švorc!,Du er flad!,Du bist pleite!,,Vi ne havas monon!,¡Estás sin blanca!,¡Estás quebrado!,Olet peeaa!,Vous êtes à sec!,Nincs is nálad pénz!,Sei sul lastrico!,スッカラカンじゃないか!,돈이 한 푼도 없는 것 같은데.,Je bent blut!,Du er blakk!,Jesteście spłukani!,Você está sem grana!,,Ești falit!,"Друг, да ты на мели!",,Du är pank!,Beş parasızsın! +Clip of bullets,TXT_RPLY1_SCRIPT33_D4548_10ROU,〃,,,Zásobník s náboji,Et patron-klip,10-Kugeln-Magazin,,Magazenon,Un cargador,,Luotilipas,Chargeur de 10 cartouches.,Egy tárnyi töltény,Un caricatore di proiettili,銃弾倉,돌격소총 탄창,Klem van kogels,Et magasin med kuler,Klips z kulami.,Carregador de balas,,Cartuș de gloanțe,Обойма патронов,,Klockan med kulor.,Mermi şarjörü +Here's your ammo,TXT_RYES1_SCRIPT33_D4548_HERES,〃,,,Tady je tvá munice.,Her er din ammunition,Hier ist deine Munition.,,,Aquí tienes tu munición.,,Tässä panoksesi.,Voilà vos balles.,Itt a töltényed.,Ecco le tue munizioni.,これでアンタのブツだ。,여기 탄약입니다.,Hier is je munitie....,Her er ammunisjonen din,Oto twoja amunicja.,Aqui está a sua munição.,,Aici e.,Вот твои патроны.,,Här är din ammunition.,İşte cephaneniz. +"Sorry, no money, no bullets.",TXT_RNO1_SCRIPT33_D4548_SORRY,〃,,,"Promiň. Žádné peníze, žádné náboje.","Beklager, ingen penge, ingen kugler.","Tut mir leid. Kein Geld, keine Munition.",,Pardonon. Sen mono ne estas kugloj.,"Lo siento, sin dinero, no hay balas.",,"Valitan, ei rahaa, ei luoteja.","Désolé, pas d'argent, pas de munitions.","Ha nincs pénz, nincs töltény.","Mi spiace, niente soldi, niente munizioni.",悪いが、金が無ければブツも無しだ。,돈 없으면 거래 못 합니다.,"Sorry, geen geld, geen kogels.","Beklager, ingen penger, ingen kuler.","Niestety, nie ma pieniędzy, nie ma naboi.","Desculpe. Sem grana, sem balas.",,"Scuze, niciun ban, niciun glonț.","Извини, нет денег — нет патронов!",,"Tyvärr, inga pengar, inga kulor.","Üzgünüm, para yoksa mermi de yok." +Ammo box,TXT_RPLY2_SCRIPT33_D4548_50ROU,〃,,,Krabici nábojů,Ammo kasse,50-Kugeln-Schachtel,,Municikesto,Caja de municiones,,Luotilaatikko,Boîte de 50 balles.,Töltény doboz,Scatola di munizioni,銃弾倉箱,돌격소총 탄약 박스,Munitiedoos,Ammunisjonsboks,Skrzynka z amunicją.,Caixa de munição,,Cutie cu muniție,Коробка патронов,,Ammunitionslåda,Cephane kutusu +Here you go,TXT_RYES2_SCRIPT33_D4548_HEREY,〃,,,Tu máš.,Værsgo.,Bitteschön.,,Jen,Aquí tienes,,Ole hyvä.,Voilà pour vous.,Parancsolj.,Ecco a te.,どうぞ。,거래 감사드립니다.,Alsjeblieft,Vær så god.,Proszę bardzo.,Aqui está,,Aici este,Держи.,,Varsågod.,Al bakalım. +You don't have enough gold!,TXT_RNO2_SCRIPT33_D4548_YOUDO,〃,,,Nemáš dost zlaťáků!,Du har ikke nok guld!,Du hast nicht genug Gold.,,Vi ne havas sufiĉe da oro!,¡No tienes suficiente oro!,,Sinulla ei ole riittävästi kultaa!,Vous n'avez pas assez d'argent.,Nincs elég aranyad.,Non hai abbastanza oro!,十分な額じゃない,골드가 충분치 않군요!,Je hebt niet genoeg goud!,Du har ikke nok gull!,Nie masz wystarczająco dużo złota!,Você não tem ouro suficiente!,,Nu ai suficient aur!,У тебя недостаточно золота!,,Du har inte tillräckligt med guld!,Yeterince altının yok! +Ammo satchel,TXT_RPLY3_SCRIPT33_D4548_AMMOS,〃,,,Brašnu na munici,Ammotaske,Munitionstasche.,,,Mochila de municiones,,Ammuslaukku,Sacoche de munitions.,Lőszeres hátizsák,Sacca di munizioni,弾薬鞄,탄약 배낭,Munitie tasje,Ammunisjonsveske,Torba na amunicję,Mochila de munição,,Sac cu muniție,Ранец боеприпасов,,Ammunitionsväska,Cephane çantası +"Thank you, anything else?",TXT_RYES3_SCRIPT33_D4548_THANK,〃,,,Děkuji. Něco dalšího?,"Tak, er der andet?","Danke, sonst noch was?",,,Gracias. ¿Algo más?,,Kiitos; vielä jotain muuta?,"Merci, quelque chose d'autre?","Köszönöm, még valami esetleg?","Grazie, serve qualcos'altro?",ありがとう。 他に何か?,좋습니다! 더 필요한 거라도?,"Bedankt, nog iets anders?","Takk, noe mer?","Dziękuję, coś jeszcze?",Obrigado. Mais alguma coisa?,,"Merci, altceva?",Благодарю. Что-нибудь ещё?,,"Tack, något annat?","Teşekkürler, başka bir şey var mı?" "You can't afford that, good day.",TXT_RNO3_SCRIPT33_D4548_YOUCA,〃,,,"To si nemůžeš dovolit, přeji hezký den.","Det har du ikke råd til, god dag.",Das kannst du dir nicht leisten. Guten Tag.,,,"No te alcanza. -¡Ten un buen día!",,Sinulla ei ole siihen varaa; hyvää päivänjatkoa.,Vous ne pouvez pas l'acheter. Au revoir.,"Erre neked nem tellik, szép napot.","Non te la puoi permettere, buona giornata.",それを買える余裕は無い、また今度。,제공할 수 없습니다. 유감이군요.,"Dat kan je je niet betalen, goede dag.",Det har du ikke råd til. Adjø.,"Nie stać cię na to, dzień dobry.",Você não pode comprar isto. Tenha um bom dia.,,"Nu ai bani, ziua bună.",У тебя не хватает денег. Всего доброго!,,"Bunu karşılayamazsın, iyi günler." -Welcome. What may I show you?,TXT_DLG_SCRIPT33_D6064_WELCO,MAP33: Armory,,,Vítej. Co bych ti mohl nabídnout?,Velkommen. Hvad må jeg vise dig?,Willkommen. Was darf ich dir zeigen?,,Bonvenon. Kion mi montru al vi?,Bienvenido. ¿Qué puedo mostrarte?,,Tervetuloa. Mitä voin teille esitellä?,"Bienvenue, comment puis-je vous servir?",Üdvözöllek barátom. Mit tehetek érted?,Benvenuto. Cosa posso farti vedere?,ようこそ、何を見ていきますか?,어서 오세요! 무엇이 필요한지?,Welkom. Wat kan ik je laten zien?,Velkommen. Hva kan jeg vise deg?,Witam. Co mogę ci pokazać?,Seja bem-vindo. O que posso lhe mostrar?,,Bună. Cu ce te pot ajuta?,Здравствуй. Что-нибудь интересует?,,Hoş geldiniz. Size ne gösterebilirim? -Environmental suit,TXT_RPLY0_SCRIPT33_D6064_ENVIR,〃,,,Ochranný oblek,Miljødragt,Schutzanzug.,,Medi-ŝirman veston,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison Hazmat.,Védő ruha,Tuta ambientale,耐環境スーツ,환경 방호복,Beschermend Pak,Miljødrakt,Kombinezon ekologiczny,Traje de proteção,,Costum de Protecție împotriva Mediului,Защитный костюм,,Çevre kıyafeti. -Here you are.,TXT_RYES0_SCRIPT33_D6064_HEREY,〃,,,"Tak, tady to je.",Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,"Tässä, olkaa hyvä.",Voilà pour vous.,Parancsolj.,Ecco a te.,はい、これをどうぞ。,받으세요!,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici e.,"Хорошо, бери.",,Al bakalım. -You don't have enough money for that.,TXT_RNO0_SCRIPT33_D6064_YOUDO,〃,,,Na to nemáš dost peněz.,Du har ikke penge nok til det.,Dafür hast du nicht genug Geld.,,Vi ne havas sufiĉe da mono.,No tienes suficiente dinero.,,Teillä ei ole tarpeeksi rahaa sitä varten.,Vous n'avez pas assez d'argent.,"Sajnálom, de Önnek nem áll módjában kifizetni ezt.",Non hai abbastanza soldi per questo.,すみませんが、貴方は十分なお金を持っていません。,돈이 충분치 않아요.,Daar heb je niet genoeg geld voor.,Du har ikke nok penger til det.,Nie masz na to pieniędzy.,Você não tem dinheiro o suficiente para isto.,,N-ai suficienți bani.,"Извини, но у тебя не хватает денег.",,Bunun için yeterli paran yok. -Leather armor.,TXT_RPLY1_SCRIPT33_D6064_LEATH,〃,,Leather armour,Kožené brnění,Læder rustning.,Lederrüstung,,Ledan armaĵon.,Armadura de cuero.,,Nahkasuojus,Armure de cuir.,Bőr vért.,Armatura di cuoio,レザーアーマー,가죽 갑옷,Leren harnas,Lær rustning,Skórzana zbroja.,Armadura de couro.,,Armură de piele.,Кожаная броня,,Deri zırh. -Here you are.,TXT_RYES1_SCRIPT33_D6064_HEREY,〃,,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,Olkaa hyvä.,Voilà pour vous.,Parancsolj.,Ecco a te.,これをどうぞ。,딱 맞는 치수의 갑옷이죠.,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici e.,Держи.,,Al bakalım. -Perhaps some other time?,TXT_RNO1_SCRIPT33_D6064_PERHA,〃,,,Možná někdy jindy?,Måske en anden gang?,Vielleicht ein anderes Mal?,,Ĉu eble alian fojon?,¿Quizás en otra ocasión?,¿Tal vez en otra ocasión?,Ehkä jokin toinen kerta?,Peut être une autre fois?,Talán később?,Magari un'altra volta?,また別の機会に?,아마 나중에 사야겠는데요?,Misschien een andere keer?,Kanskje en annen gang?,Może innym razem?,Talvez outra hora?,,Poate altădată?,"Может, в следующий раз?",,Belki başka bir zaman? -Metal armor,TXT_RPLY2_SCRIPT33_D6064_METAL,〃,,Metal armour,Kovové brnění,Metal rustning,Metallrüstung,,Metalan armaĵon,Armadura de metal,,Metallihaarniska,Armure de métal.,Fém vért,Armatura di metallo,メタルアーマー,강철 갑옷,Metalen harnas,Metallrustning.,Metalowa zbroja,Armadura de metal,,Armură de metal,Металлическая броня,,Metal zırh. -Wear it in good health.,TXT_RYES2_SCRIPT33_D6064_WEARI,〃,,,Nos ho ve zdraví.,Bær den ved godt helbred.,Trage sie und bleib gesund.,,Ĝuu ĝin.,Disfrútala.,,Pitäköön asu teidät terveenä.,Portez-la en bonne santé.,Használd egészséggel.,Che possa esserti utile!,着ると安心しますよ。,건강하게 착용하십시오.,Draag het in goede gezondheid.,Bruk den ved god helse.,Noś ją w dobrym zdrowiu.,Vista com orgulho.,,Să o porți sănătos.,Носи на здоровье.,,Sağlıkla giy. +¡Ten un buen día!",,Sinulla ei ole siihen varaa; hyvää päivänjatkoa.,Vous ne pouvez pas l'acheter. Au revoir.,"Erre neked nem tellik, szép napot.","Non te la puoi permettere, buona giornata.",それを買える余裕は無い、また今度。,제공할 수 없습니다. 유감이군요.,"Dat kan je je niet betalen, goede dag.",Det har du ikke råd til. Adjø.,"Nie stać cię na to, dzień dobry.",Você não pode comprar isto. Tenha um bom dia.,,"Nu ai bani, ziua bună.",У тебя не хватает денег. Всего доброго!,,"Du har inte råd med det, god dag.","Bunu karşılayamazsın, iyi günler." +Welcome. What may I show you?,TXT_DLG_SCRIPT33_D6064_WELCO,MAP33: Armory,,,Vítej. Co bych ti mohl nabídnout?,Velkommen. Hvad må jeg vise dig?,Willkommen. Was darf ich dir zeigen?,,Bonvenon. Kion mi montru al vi?,Bienvenido. ¿Qué puedo mostrarte?,,Tervetuloa. Mitä voin teille esitellä?,"Bienvenue, comment puis-je vous servir?",Üdvözöllek barátom. Mit tehetek érted?,Benvenuto. Cosa posso farti vedere?,ようこそ、何を見ていきますか?,어서 오세요! 무엇이 필요한지?,Welkom. Wat kan ik je laten zien?,Velkommen. Hva kan jeg vise deg?,Witam. Co mogę ci pokazać?,Seja bem-vindo. O que posso lhe mostrar?,,Bună. Cu ce te pot ajuta?,Здравствуй. Что-нибудь интересует?,,Välkommen. Vad får jag visa dig?,Hoş geldiniz. Size ne gösterebilirim? +Environmental suit,TXT_RPLY0_SCRIPT33_D6064_ENVIR,〃,,,Ochranný oblek,Miljødragt,Schutzanzug.,,Medi-ŝirman veston,Traje de protección ambiental,,Ympäristösuojapuku,Combinaison Hazmat.,Védő ruha,Tuta ambientale,耐環境スーツ,환경 방호복,Beschermend Pak,Miljødrakt,Kombinezon ekologiczny,Traje de proteção,,Costum de Protecție împotriva Mediului,Защитный костюм,,Miljödräkt,Çevre kıyafeti. +Here you are.,TXT_RYES0_SCRIPT33_D6064_HEREY,〃,,,"Tak, tady to je.",Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,"Tässä, olkaa hyvä.",Voilà pour vous.,Parancsolj.,Ecco a te.,はい、これをどうぞ。,받으세요!,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici e.,"Хорошо, бери.",,Varsågod.,Al bakalım. +You don't have enough money for that.,TXT_RNO0_SCRIPT33_D6064_YOUDO,〃,,,Na to nemáš dost peněz.,Du har ikke penge nok til det.,Dafür hast du nicht genug Geld.,,Vi ne havas sufiĉe da mono.,No tienes suficiente dinero.,,Teillä ei ole tarpeeksi rahaa sitä varten.,Vous n'avez pas assez d'argent.,"Sajnálom, de Önnek nem áll módjában kifizetni ezt.",Non hai abbastanza soldi per questo.,すみませんが、貴方は十分なお金を持っていません。,돈이 충분치 않아요.,Daar heb je niet genoeg geld voor.,Du har ikke nok penger til det.,Nie masz na to pieniędzy.,Você não tem dinheiro o suficiente para isto.,,N-ai suficienți bani.,"Извини, но у тебя не хватает денег.",,Du har inte tillräckligt med pengar för det.,Bunun için yeterli paran yok. +Leather armor.,TXT_RPLY1_SCRIPT33_D6064_LEATH,〃,,Leather armour,Kožené brnění,Læder rustning.,Lederrüstung,,Ledan armaĵon.,Armadura de cuero.,,Nahkasuojus,Armure de cuir.,Bőr vért.,Armatura di cuoio,レザーアーマー,가죽 갑옷,Leren harnas,Lær rustning,Skórzana zbroja.,Armadura de couro.,,Armură de piele.,Кожаная броня,,Läderrustning.,Deri zırh. +Here you are.,TXT_RYES1_SCRIPT33_D6064_HEREY,〃,,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,Olkaa hyvä.,Voilà pour vous.,Parancsolj.,Ecco a te.,これをどうぞ。,딱 맞는 치수의 갑옷이죠.,Hier ben je dan.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici e.,Держи.,,Här är den.,Al bakalım. +Perhaps some other time?,TXT_RNO1_SCRIPT33_D6064_PERHA,〃,,,Možná někdy jindy?,Måske en anden gang?,Vielleicht ein anderes Mal?,,Ĉu eble alian fojon?,¿Quizás en otra ocasión?,¿Tal vez en otra ocasión?,Ehkä jokin toinen kerta?,Peut être une autre fois?,Talán később?,Magari un'altra volta?,また別の機会に?,아마 나중에 사야겠는데요?,Misschien een andere keer?,Kanskje en annen gang?,Może innym razem?,Talvez outra hora?,,Poate altădată?,"Может, в следующий раз?",,Kanske en annan gång?,Belki başka bir zaman? +Metal armor,TXT_RPLY2_SCRIPT33_D6064_METAL,〃,,Metal armour,Kovové brnění,Metal rustning,Metallrüstung,,Metalan armaĵon,Armadura de metal,,Metallihaarniska,Armure de métal.,Fém vért,Armatura di metallo,メタルアーマー,강철 갑옷,Metalen harnas,Metallrustning.,Metalowa zbroja,Armadura de metal,,Armură de metal,Металлическая броня,,Metallrustning.,Metal zırh. +Wear it in good health.,TXT_RYES2_SCRIPT33_D6064_WEARI,〃,,,Nos ho ve zdraví.,Bær den ved godt helbred.,Trage sie und bleib gesund.,,Ĝuu ĝin.,Disfrútala.,,Pitäköön asu teidät terveenä.,Portez-la en bonne santé.,Használd egészséggel.,Che possa esserti utile!,着ると安心しますよ。,건강하게 착용하십시오.,Draag het in goede gezondheid.,Bruk den ved god helse.,Noś ją w dobrym zdrowiu.,Vista com orgulho.,,Să o porți sănătos.,Носи на здоровье.,,Bär den vid god hälsa.,Sağlıkla giy. Come back when you can afford it.,TXT_RNO2_SCRIPT33_D6064_COMEB,〃,,,"Vrať se, až si to budeš moct dovolit.","Kom tilbage, når du har råd til det.","Komme wieder, wenn du dir sie leisten kannst.",,"Revenu kiam vi povos aĉeti ĝin.","Vuelve cuando -puedas comprarla.",,"Palataan asiaa, kun teillä on siihen varaa.",Revenez quand vous pouvez l'acheter.,Gyere vissza ha tellik rá.,Ritorna quando potrai permettertela.,余裕がある時にまた。,돈이 좀 있을때 다시 찾아와주세요.,Kom terug wanneer je het je kunt veroorloven.,Kom tilbake når du har råd.,"Wróć, gdy będzie cię na to stać.",Volte quando puder comprar.,,Întoarce-te când ai destui bani!,"Вернёшься, когда поднакопишь на то, что хочешь!",,Paranız yettiğinde geri gelin. -How may I assist you?,TXT_DLG_SCRIPT33_D7580_HOWMA,MAP33: Hospital,,,Jak ti mohu pomoci?,Hvordan kan jeg hjælpe dig?,Womit kann ich dienen?,,Kiel mi helpu vin?,¿Cómo puedo ayudarte?,,Miten voin teitä avustaa?,Comment puis-je vous aider aujourd'hui?,Miben lehetek a segítségedre?,Come posso aiutarti?,何かお困りですか?,반갑습니다. 어떻게 도와드릴까요?,Hoe kan ik u helpen?,Hvordan kan jeg hjelpe deg?,Jak mogę ci pomóc?,Como posso ajudá-lo?,,Cu ce te pot ajuta?,Чем могу помочь?,,Size nasıl yardımcı olabilirim? -Med patch,TXT_RPLY0_SCRIPT33_D7580_MEDPA,〃,,,Obvazy,Medicinsk plaster,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekääre,Pansement.,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinplaster,Bandaż,Compressa médica,,Bandaj medical,Бинтами,,Tıbbi yama -Here's your patch kit.,TXT_RYES0_SCRIPT33_D7580_HERES,〃,,,Tady je tvůj obvaz.,Her er dit patch-kit.,Hier ist deine Bandage.,,Jen viaj kuracbendoj,Aquí tienes tus tiritas.,Aquí tienes tus curitas.,Tässä käärepakettisi.,Voilà votre pansement.,Itt a tapaszod.,Ecco le tue bende.,これをどうぞ。,저렴한 가격의 의료 붕대입니다.,Hier is je patch.,Her er lappesettet ditt.,Oto twój bandaż.,Aqui está a sua compressa,,Aici este.,Вот они.,,İşte yama setiniz. -You need 10 gold for that.,TXT_RNO0_SCRIPT33_D7580_YOUNE,〃,,,Na ty potřebuješ deset zlatých.,Du skal bruge 10 guld for det.,Dafür brauchst du 10 Gold.,,Vi bezonas 10 da oro.,Necesitas 10 de oro.,,Tarvitset sitä varten 10 kolikkoa.,Il vous faut 10 pièces pour ça.,10 aranyba kerül.,Ti servono 10 pezzi d'oro per quello.,10 ゴールド必要です。,10 골드입니다. 설마 이 만한 양의 돈이 없으신가요?,Daar heb je 10 goud voor nodig.,Du trenger 10 gull for det.,Potrzebujesz na to 10 złota.,Você precisa de 10 moedas para isto.,,Ai nevoie de 10 monezi pentru aia.,Тебе не хватает 10 золотых.,,Bunun için 10 altına ihtiyacın var. -Field surgery kit,TXT_RPLY1_SCRIPT33_D7580_FIELD,〃,,,Lékárničku,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kenttäkirurgilaukku,Kit de chirurgie.,Harctéri műtéti felszerelés,Kit chirurgico,手術キット,수술 키트,Veld chirurgie kit,Kirurgisett,Zestaw do chirurgii polowej,Kit de cirurgia,,Kit chirurgical de teren.,Аптечкой,,Saha ameliyat kiti -Thank you.,TXT_RYES1_SCRIPT33_D7580_THANK,〃,,,Děkuji.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitoksia,Merci.,Köszönöm.,Grazie.,ありがとうございます。,말 없이 주겠습니다. 거래 고마워요!,Bedankt.,Takk skal du ha.,Dziękuję.,Obrigado.,,Merci.,Спасибо.,,Teşekkür ederim. +puedas comprarla.",,"Palataan asiaa, kun teillä on siihen varaa.",Revenez quand vous pouvez l'acheter.,Gyere vissza ha tellik rá.,Ritorna quando potrai permettertela.,余裕がある時にまた。,돈이 좀 있을때 다시 찾아와주세요.,Kom terug wanneer je het je kunt veroorloven.,Kom tilbake når du har råd.,"Wróć, gdy będzie cię na to stać.",Volte quando puder comprar.,,Întoarce-te când ai destui bani!,"Вернёшься, когда поднакопишь на то, что хочешь!",,Kom tillbaka när du har råd.,Paranız yettiğinde geri gelin. +How may I assist you?,TXT_DLG_SCRIPT33_D7580_HOWMA,MAP33: Hospital,,,Jak ti mohu pomoci?,Hvordan kan jeg hjælpe dig?,Womit kann ich dienen?,,Kiel mi helpu vin?,¿Cómo puedo ayudarte?,,Miten voin teitä avustaa?,Comment puis-je vous aider aujourd'hui?,Miben lehetek a segítségedre?,Come posso aiutarti?,何かお困りですか?,반갑습니다. 어떻게 도와드릴까요?,Hoe kan ik u helpen?,Hvordan kan jeg hjelpe deg?,Jak mogę ci pomóc?,Como posso ajudá-lo?,,Cu ce te pot ajuta?,Чем могу помочь?,,Hur kan jag hjälpa dig?,Size nasıl yardımcı olabilirim? +Med patch,TXT_RPLY0_SCRIPT33_D7580_MEDPA,〃,,,Obvazy,Medicinsk plaster,Medizinische Bandage,,Kuracbendoj,Tiritas,Curitas,Sidekääre,Pansement.,Ragtapasz,Bende,医薬パッチ,의료 붕대,Med-patch,Medisinplaster,Bandaż,Compressa médica,,Bandaj medical,Бинтами,,Medicinsk plåster,Tıbbi yama +Here's your patch kit.,TXT_RYES0_SCRIPT33_D7580_HERES,〃,,,Tady je tvůj obvaz.,Her er dit patch-kit.,Hier ist deine Bandage.,,Jen viaj kuracbendoj,Aquí tienes tus tiritas.,Aquí tienes tus curitas.,Tässä käärepakettisi.,Voilà votre pansement.,Itt a tapaszod.,Ecco le tue bende.,これをどうぞ。,저렴한 가격의 의료 붕대입니다.,Hier is je patch.,Her er lappesettet ditt.,Oto twój bandaż.,Aqui está a sua compressa,,Aici este.,Вот они.,,Her er dit plaster.,İşte yama setiniz. +You need 10 gold for that.,TXT_RNO0_SCRIPT33_D7580_YOUNE,〃,,,Na ty potřebuješ deset zlatých.,Du skal bruge 10 guld for det.,Dafür brauchst du 10 Gold.,,Vi bezonas 10 da oro.,Necesitas 10 de oro.,,Tarvitset sitä varten 10 kolikkoa.,Il vous faut 10 pièces pour ça.,10 aranyba kerül.,Ti servono 10 pezzi d'oro per quello.,10 ゴールド必要です。,10 골드입니다. 설마 이 만한 양의 돈이 없으신가요?,Daar heb je 10 goud voor nodig.,Du trenger 10 gull for det.,Potrzebujesz na to 10 złota.,Você precisa de 10 moedas para isto.,,Ai nevoie de 10 monezi pentru aia.,Тебе не хватает 10 золотых.,,Du behöver 10 guld för den.,Bunun için 10 altına ihtiyacın var. +Field surgery kit,TXT_RPLY1_SCRIPT33_D7580_FIELD,〃,,,Lékárničku,Kirurgisæt,Erste-Hilfe-Kasten,,Kirurgia kesto,Kit quirúrgico,,Kenttäkirurgilaukku,Kit de chirurgie.,Harctéri műtéti felszerelés,Kit chirurgico,手術キット,수술 키트,Veld chirurgie kit,Kirurgisett,Zestaw do chirurgii polowej,Kit de cirurgia,,Kit chirurgical de teren.,Аптечкой,,Fältkirurgisk utrustning,Saha ameliyat kiti +Thank you.,TXT_RYES1_SCRIPT33_D7580_THANK,〃,,,Děkuji.,Tak.,Danke.,,Dankon.,Gracias.,,Kiitoksia,Merci.,Köszönöm.,Grazie.,ありがとうございます。,말 없이 주겠습니다. 거래 고마워요!,Bedankt.,Takk skal du ha.,Dziękuję.,Obrigado.,,Merci.,Спасибо.,,Tack.,Teşekkür ederim. "I wish I could give them away, but they cost 25 gold.",TXT_RNO1_SCRIPT33_D7580_IWISH,〃,,,"Přál bych si je dávat zadarmo, ale stojí 25 zlatých.","Jeg ville ønske, jeg kunne give dem væk, men de koster 25 guld.","Ich wünschte, ich könnte sie verschenken, aber sie kosten 25 Gold.",,"Mi donacus ĝin, sed ĝi kostas 25 da oro.","Ojalá pudiera regalarlo, -pero cuesta 25 de oro.",,"Kunpa voisinkin antaa niitä lahjaksi, mutta ne maksavat 25 kolikkoa.","J'adorerais les donner gratuitement, mais non, ça coûte 25 pièces.","Bárcsak ingyen osztogathatnám, de 25 aranyba kerül.","Mi piacerebbe darli via, ma costano 25 pezzi d'oro.",譲渡したい所ですが、25 ゴールド必要です。,25 골드만 있으면 잔소리 말고 주겠습니다.,"Ik wou dat ik ze kon weggeven, maar ze kosten 25 goud.","Jeg skulle ønske jeg kunne gi dem bort, men de koster 25 gull.","Chciałbym móc je rozdać, ale kosztują 25 złota.","Bem que eu queria doar de graça, mas custa 25 moedas de ouro.",,"Aș vrea să le pot da pe gratis, dar costă 25 de monezi.","С радостью бы отдал, но они по 25 золотых.",,Keşke onları verebilseydim ama 25 altına mal oluyorlar. -Healing,TXT_RPLY2_SCRIPT33_D7580_HEALI,〃,,,Ošetření,Healing,Heilung,,Kuracado,Curación,,Sairaanhoitoa,Des soins.,Gyógyítás,Ho bisogno di essere curato.,治療だ,치료 중.,Genezing,Helbredelse,Uzdrawianie,Cura,,Vindecă-mă.,Медкомплектом,,Şifa -There you go. Take care now.,TXT_RYES2_SCRIPT33_D7580_THERE,〃,,,A je to. Buď opatrný.,Værsgo. Pas godt på dig selv nu.,Bitteschön. Aber sei vorsichtiger.,,Jen. Estu atenta.,Aquí tienes. Cuídate.,,Olkaa hyvä. Pitäkäähän nyt huoli itsestänne.,"Voilà pour vous, portez-vous-bien.",Meg is oldottam. Vigyázz magadra.,"Ecco fatto, stammi bene.",こちらになります、お気をつけて。,치료가 끝났어. 몸 조심하라고.,Daar ga je. Pas goed op jezelf.,Vær så god. Ta vare på deg selv.,No i proszę. Dbaj o siebie.,Pronto. Se cuida.,,Gata. Ai grijă acum.,Пожалуйста. Береги себя!,,Al bakalım. Kendine iyi bak. +pero cuesta 25 de oro.",,"Kunpa voisinkin antaa niitä lahjaksi, mutta ne maksavat 25 kolikkoa.","J'adorerais les donner gratuitement, mais non, ça coûte 25 pièces.","Bárcsak ingyen osztogathatnám, de 25 aranyba kerül.","Mi piacerebbe darli via, ma costano 25 pezzi d'oro.",譲渡したい所ですが、25 ゴールド必要です。,25 골드만 있으면 잔소리 말고 주겠습니다.,"Ik wou dat ik ze kon weggeven, maar ze kosten 25 goud.","Jeg skulle ønske jeg kunne gi dem bort, men de koster 25 gull.","Chciałbym móc je rozdać, ale kosztują 25 złota.","Bem que eu queria doar de graça, mas custa 25 moedas de ouro.",,"Aș vrea să le pot da pe gratis, dar costă 25 de monezi.","С радостью бы отдал, но они по 25 золотых.",,"Jag önskar att jag kunde ge bort dem, men de kostar 25 guld.",Keşke onları verebilseydim ama 25 altına mal oluyorlar. +Healing,TXT_RPLY2_SCRIPT33_D7580_HEALI,〃,,,Ošetření,Healing,Heilung,,Kuracado,Curación,,Sairaanhoitoa,Des soins.,Gyógyítás,Ho bisogno di essere curato.,治療だ,치료 중.,Genezing,Helbredelse,Uzdrawianie,Cura,,Vindecă-mă.,Медкомплектом,,Helande,Şifa +There you go. Take care now.,TXT_RYES2_SCRIPT33_D7580_THERE,〃,,,A je to. Buď opatrný.,Værsgo. Pas godt på dig selv nu.,Bitteschön. Aber sei vorsichtiger.,,Jen. Estu atenta.,Aquí tienes. Cuídate.,,Olkaa hyvä. Pitäkäähän nyt huoli itsestänne.,"Voilà pour vous, portez-vous-bien.",Meg is oldottam. Vigyázz magadra.,"Ecco fatto, stammi bene.",こちらになります、お気をつけて。,치료가 끝났어. 몸 조심하라고.,Daar ga je. Pas goed op jezelf.,Vær så god. Ta vare på deg selv.,No i proszę. Dbaj o siebie.,Pronto. Se cuida.,,Gata. Ai grijă acum.,Пожалуйста. Береги себя!,,Här har du. Ta hand om dig nu.,Al bakalım. Kendine iyi bak. "Well, maybe you can afford some med patches?",TXT_RNO2_SCRIPT33_D7580_WELLM,〃,,,Možná si můžeš dovolit nějaké obvazy?,Måske har du råd til nogle medicinske plastre?,"Naja, vielleicht kannst du dir ein paar Bandagen leisten?",,"Nu, ĉu vi eble povas aĉeti kuracbendojn?","Bueno, ¿quizás tengas para comprar tiritas?","Bueno, ¿tal vez tengas -para comprar curitas?",Ehkä teillä olisi kuitenkin sidekääreisiin varaa?,"Eh bien, peut être pouvez-vous vous acheter quelques pansements?",Talán tellik pár tapaszra is?,"Beh, forse puoi permetterti delle bende?",ところで、医薬パッチを買う余裕はありますか?,의료 붕대는 어떠신가요? 이 건 저렴한데.,"Nou ja, misschien kunt u zich wat medische patches veroorloven?",Kanskje du har råd til noen medisinplaster?,Może stać cię na plastry?,"Bem, talvez você possa comprar algumas compressas?",,"Păi, poate îți permiți niște truse medicale?","Тогда, может быть, купишь несколько бинтов?",,Belki birkaç ilaç yamasını karşılayabilirsin? +para comprar curitas?",Ehkä teillä olisi kuitenkin sidekääreisiin varaa?,"Eh bien, peut être pouvez-vous vous acheter quelques pansements?",Talán tellik pár tapaszra is?,"Beh, forse puoi permetterti delle bende?",ところで、医薬パッチを買う余裕はありますか?,의료 붕대는 어떠신가요? 이 건 저렴한데.,"Nou ja, misschien kunt u zich wat medische patches veroorloven?",Kanskje du har råd til noen medisinplaster?,Może stać cię na plastry?,"Bem, talvez você possa comprar algumas compressas?",,"Păi, poate îți permiți niște truse medicale?","Тогда, может быть, купишь несколько бинтов?",,Du kanske har råd med några medicinska plåster?,Belki birkaç ilaç yamasını karşılayabilirsin? "Hello friend, I haven't seen you around here before. All I can say is that I'd be careful if I were you, there's a lot going on and it's better if you don't get in the way.",TXT_DLG_SCRIPT33_D9096_HELLO,MAP33: Barkeep.,,,"Ahoj, příteli, ještě jsem tě tady neviděl. Jediné, co můžu říct, je: Být tebou, byl bych opatrný. Děje se toho hodně a je lepší neplést se věcem do cesty.","Hej ven, jeg har ikke set dig her før. Alt jeg kan sige er, at jeg ville være forsigtig, hvis jeg var dig, der sker meget, og det er bedre, hvis du ikke kommer i vejen.","Hallo, Freund, ich habe dich hier noch nicht gesehen. Ich kann nur sagen, sei vorsichtig und wenn ich du wäre, würde ich es vorziehen, niemandem im Weg zu stehen.",,,"Hola amigo, no te he visto antes por aquí. Todo lo que puedo decir es que tendría cuidado si fuera tú, están pasando muchas cosas y es mejor que no te entrometas.",,"Tervehdys. En ole teitä täällä ennen nähnytkään. Teidän saappaissanne olisin varuillani. Paljon on meneillään, ja on parempi pysyä poissa tieltä.","Bienvenue, l'ami. Je ne vous ai pas vu ici avant. Tout ce que peux vous dire, c'est de faire attention à vous. Il se passe beaucoup de choses ici, et je pense que vous ne voulez pas vous en mêler.","Szervusz barátom, nem láttalak még itt eddig. Csak annyi jó tanácsot tudok adni, hogy légy óvatos. Felpörögtek az események az utóbbi időben, és a helydben nem keverednék bele.","Salve amico, non ti ho mai visto da queste parti prima. Posso solo dirti che farei molta attenzione se fossi in te. Stanno succedendo diverse cose, ed è meglio non immischiarsi.","どうも余所者、この辺では見かけない顔だな。 では一杯アドバイスをおごろう。 この付近が自由な発言を 許さないからって下手な真似をするなよ。 -オーダーという自警団がすぐに駆けつけてくるぞ。","반갑네, 친구. 낯선 사람인 것 같은데, 조심하고 걸어 다니게나. 지금 이곳에서 꽤 많은 일이 일어났거든. 내가 하는 말을 들으면 이해가 될 걸세.","Hallo vriend, ik heb je hier nog niet eerder gezien. Ik kan alleen maar zeggen dat ik voorzichtig zou zijn als ik jou was, er is veel aan de hand en het is beter als je niet in de weg staat.","Hei, min venn. Jeg har ikke sett deg her tidligere. Alt jeg kan si er at jeg ville vært forsiktig hvis jeg var deg, det er mye som skjer, og det er bedre om du ikke kommer i veien.","Witaj przyjacielu, nie widziałem cię tu wcześniej. Mogę tylko powiedzieć, że na twoim miejscu uważałbym, dużo się dzieje i lepiej, żebyś nie wchodził w drogę.",Olá amigo. Acho que não te vi por aqui antes. Tudo o que posso dizer é que eu tomaria cuidado se eu fosse você. Há muita coisa acontecendo e é melhor não se envolver.,,"Bună prietene, nu te-am mai văzut pe-aici. Tot ce spune e că aș avea grijă pe unde merg, se întâmplă multe prin jur și e mai bine să nu te amesteci.","Привет, дружище. Что-то я не видел тебя тут раньше. Дам тебе один совет: я бы на твоём месте был поосторожнее. Сейчас здесь такое творится, что лучше не высовываться.",,"Merhaba dostum, seni daha önce buralarda görmemiştim. Tek söyleyebileceğim, yerinde olsam dikkatli olurdum, çok şey oluyor ve yoluna çıkmazsan daha iyi olur." -Information,TXT_RPLY0_SCRIPT33_D9096_INFOR,〃,,,Informace,Information,Informationen,,Informoj,Información,,Tietoa.,Des infos.,Információ.,Informazioni,情報,정보를 줘.,Informatie,Informasjon,Informacje,Informações,,Informație,Есть новости?,,Bilgi +オーダーという自警団がすぐに駆けつけてくるぞ。","반갑네, 친구. 낯선 사람인 것 같은데, 조심하고 걸어 다니게나. 지금 이곳에서 꽤 많은 일이 일어났거든. 내가 하는 말을 들으면 이해가 될 걸세.","Hallo vriend, ik heb je hier nog niet eerder gezien. Ik kan alleen maar zeggen dat ik voorzichtig zou zijn als ik jou was, er is veel aan de hand en het is beter als je niet in de weg staat.","Hei, min venn. Jeg har ikke sett deg her tidligere. Alt jeg kan si er at jeg ville vært forsiktig hvis jeg var deg, det er mye som skjer, og det er bedre om du ikke kommer i veien.","Witaj przyjacielu, nie widziałem cię tu wcześniej. Mogę tylko powiedzieć, że na twoim miejscu uważałbym, dużo się dzieje i lepiej, żebyś nie wchodził w drogę.",Olá amigo. Acho que não te vi por aqui antes. Tudo o que posso dizer é que eu tomaria cuidado se eu fosse você. Há muita coisa acontecendo e é melhor não se envolver.,,"Bună prietene, nu te-am mai văzut pe-aici. Tot ce spune e că aș avea grijă pe unde merg, se întâmplă multe prin jur și e mai bine să nu te amesteci.","Привет, дружище. Что-то я не видел тебя тут раньше. Дам тебе один совет: я бы на твоём месте был поосторожнее. Сейчас здесь такое творится, что лучше не высовываться.",,"Hej vän, jag har inte sett dig här förut. Allt jag kan säga är att jag skulle vara försiktig om jag var du, det är mycket på gång och det är bättre om du inte kommer i vägen.","Merhaba dostum, seni daha önce buralarda görmemiştim. Tek söyleyebileceğim, yerinde olsam dikkatli olurdum, çok şey oluyor ve yoluna çıkmazsan daha iyi olur." +Information,TXT_RPLY0_SCRIPT33_D9096_INFOR,〃,,,Informace,,Informationen,,Informoj,Información,,Tietoa.,Des infos.,Információ.,Informazioni,情報,정보를 줘.,Informatie,Informasjon,Informacje,Informações,,Informație,Есть новости?,,,Bilgi The sewers hold more than just rats and robots.,TXT_RYES0_SCRIPT33_D9096_THESE,〃,,,Stoky ukrývají víc než jen krysy a roboty.,Kloakkerne rummer mere end bare rotter og robotter.,Die Kanalisation hat mehr zu bieten als Ratten und Roboter.,,"En la kloakoj ne estas nur ratoj kaj robotoj.","En las alcantarillas hay más -que solo ratas y robots.",,Viemärit pitävät sisällään muutakin kuin vain rottia ja robotteja.,Les égouts contiennent plus que des rats et des robots.,A kanális nem csak patkányokat és robotokat rejteget.,Le fogne contengono molto di più che ratti e robot.,他は...下水道には鼠やロボが沢山だ。,"하수도엔 쥐도 있고, 오물도 있고, 그 중 위험한 로봇들도 있다네.",In het riool zijn meer dan alleen ratten en robots te vinden.,Kloakken rommer mer enn bare rotter og roboter.,Kanały kryją w sobie coś więcej niż tylko szczury i roboty.,Os esgotos abrigam mais do que ratos e robôs.,,Canalele găzduiesc mai mult decât roboți și șobolani.,В канализации водятся не только крысы и роботы.,,Lağımlarda fareler ve robotlardan daha fazlası var. +que solo ratas y robots.",,Viemärit pitävät sisällään muutakin kuin vain rottia ja robotteja.,Les égouts contiennent plus que des rats et des robots.,A kanális nem csak patkányokat és robotokat rejteget.,Le fogne contengono molto di più che ratti e robot.,他は...下水道には鼠やロボが沢山だ。,"하수도엔 쥐도 있고, 오물도 있고, 그 중 위험한 로봇들도 있다네.",In het riool zijn meer dan alleen ratten en robots te vinden.,Kloakken rommer mer enn bare rotter og roboter.,Kanały kryją w sobie coś więcej niż tylko szczury i roboty.,Os esgotos abrigam mais do que ratos e robôs.,,Canalele găzduiesc mai mult decât roboți și șobolani.,В канализации водятся не только крысы и роботы.,,Kloakerna rymmer mer än bara råttor och robotar.,Lağımlarda fareler ve robotlardan daha fazlası var. Hey a guy's got to make some money. You think these jokers tip well?,TXT_RNO0_SCRIPT33_D9096_HEYAG,〃,,,"Hele, nějak si vydělávat musím. Myslíš, že tihle šašci dávají dobré spropitné?","Hey en fyr skal jo tjene nogle penge. Tror du, at de spassere giver gode drikkepenge?","Hey, mann muss auch sein Auskommen haben, glaubst du, diese Witzbolde geben einem Trinkgeld?",,,Hey un servidor tiene que ganar algo de dinero. ¿Crees que estos payasos dan buena propina?,,"Hei, jollakin tavalla sitä pitää leipänsä ansaita. Luuletko, että nämä pellet antavat hyvin juomarahaa?","Hé, j'ai besoin de me faire de l'argent, vous savez? Vous croyez que ces salauds me paient bien?","Figyelj, nekem is élni kell valamiből. Azt hiszed ezek a pacákok sok borravalót hagynak itt?","Ehi, devo pure riuscire a mettere qualcosa da parte. Pensi che i clienti qua diano laute mance?","ちょっと男はお金を稼ぐんだ。 あなたはこれらのジョーカーがうまく傾くと -思いますか?",먹고 살려면 돈이 필요하다네. 이 손님들은 팁도 안 준다니까!,"Hé, een man moet wat geld verdienen. Denk je dat deze grappenmakers een goede fooi geven?","Hei, en fyr må tjene litt penger. Tror du disse jokerne gir bra med tips?","Hej facet musi zarobić trochę pieniędzy. Myślisz, że ci żartownisie dobrze dają napiwki?","Ei, preciso ganhar uma grana. Você acha que esses palhaços dão bastante gorjeta?",,Hei un om are nevoie și de bani. Crezi că glumeții ăștia au sfaturi bune?,"Заработай немного денег, парень. Или ты думаешь, что все эти шутники щедро платят?",,"Hey, bir adam biraz para kazanmalı. Bu şakacıların iyi bahşiş verdiğini mi düşünüyorsun?" +思いますか?",먹고 살려면 돈이 필요하다네. 이 손님들은 팁도 안 준다니까!,"Hé, een man moet wat geld verdienen. Denk je dat deze grappenmakers een goede fooi geven?","Hei, en fyr må tjene litt penger. Tror du disse jokerne gir bra med tips?","Hej facet musi zarobić trochę pieniędzy. Myślisz, że ci żartownisie dobrze dają napiwki?","Ei, preciso ganhar uma grana. Você acha que esses palhaços dão bastante gorjeta?",,Hei un om are nevoie și de bani. Crezi că glumeții ăștia au sfaturi bune?,"Заработай немного денег, парень. Или ты думаешь, что все эти шутники щедро платят?",,Hej en kille måste ju tjäna lite pengar. Tror du att de här skojarna ger bra dricks?,"Hey, bir adam biraz para kazanmalı. Bu şakacıların iyi bahşiş verdiğini mi düşünüyorsun?" "Back again huh? Well, at least you know enough to keep your own skin intact. What can I do for you now?",TXT_DLG_SCRIPT33_D10612_BACKA,〃,,,"Zase zpátky, co? No, aspoň víš, jak si udržet kožich netknutý. Co pro tebe mohu udělat?","Tilbage igen, hva'? I det mindste ved du nok til at holde din egen hud intakt. Hvad kan jeg gøre for dig nu?","Schon wieder zurück, was? Na, wenigstens weißt du inzwischen, wie du das mit heiler Haut hinkriegst. Was kann ich jetzt für dich tun?",,,"¿De vuelta otra vez, eh? Bueno, al menos sabes suficiente para mantener tu pellejo intacto. ¿Qué puedo ofrecerte ahora?",,"Kas, tulit takaisin? Näköjään sen verran älliä päässä, että kykenet itsesi hengissä pitämään. Mutta mitä saisi nyt olla?","Déjà de retour, hein? Au moins vous savez sauver votre peau. Que puis-je faire pour vous?","Már visszatértél, mi? Legalább tudsz vigyázni az irhádra. Mit tehetek érted?","Già di ritorno, eh? Beh, almeno ciò che sai ti sta tornando utile per rimanere vivo. Cosa posso fare per te ora?","また戻ってね? まあ、少なくともあなたは自分の肌を 損なわないようにするのに十分知っています。 -私は今あなたのために何ができますか?","다시 돌아온 건가? 뭐, 자기 몸 간수 잘하고 살아 돌아왔기에 망정이지. 뭘 원하나?","Weer terug, hè? Nou ja, je weet tenminste genoeg om je eigen huid intact te houden. Wat kan ik nu voor je doen?","Tilbake igjen, hva? Du vet i det minste nok til å holde ditt eget skinn intakt. Hva kan jeg gjøre for deg nå?","Znowu to samo? Przynajmniej wiesz wystarczająco dużo, aby zachować własną skórę w nienaruszonym stanie. Co mogę dla ciebie zrobić?","Já voltou, é? Bom, pelo menos você sabe o suficiente para manter sua pele intacta. O que mais posso fazer por você?",,"Te-ai întors din nou, hă? Păi, măcar cunoști destule cât să rămâi întreg. Ce pot face pentru tine?","Снова ты? Ну что ж, ты хотя бы знаешь, как шкуру сберечь. Что я могу тебе предложить?",,Yine mi döndün? En azından kendi derini sağlam tutacak kadar biliyorsun. Şimdi senin için ne yapabilirim? -More info,TXT_RPLY0_SCRIPT33_D10612_MOREI,〃,,,Další informace,Mere info,Mehr Informationen.,,Pliaj informoj,Más información,,Lisää tietoa.,Plus d'infos.,Több információ.,Altre informazioni,話のネタ。,그 외의 정보를 줘.,Meer info,Mer info,Więcej informacji,Mais informações.,,Mai multă informație,Расскажи больше,,Daha fazla bilgi -The Governor is a simple reminder of the Order's influence.,TXT_RYES0_SCRIPT33_D10612_THEGO,〃,,,Guvernér je jednoduchou připomínkou vlivu Řádu.,Guvernøren er en simpel påmindelse om Ordenens indflydelse.,Der Gouverneur ist eine einfache Erinnering an die Macht des Ordens.,,,El gobernador es un simple recordatorio de la influencia de La Orden,,Kuvernööri on selvä muistutus Veljeskunnan vaikutusvallasta.,Le gouverneur d'est qu'un rappel de l'influence de l'ordre.,A Kormányzó csak a Rend hatalmának bábja.,Il governatore è solo un simbolo dell'influenza dell'Ordine.,知事は俺達に自由はないと思い出させる象徴さ。,모렐 총독은 부정하고 짜증 나는 오더의 정권의 예야.,De gouverneur is een eenvoudige herinnering aan de invloed van de Orde.,Guvernøren er en enkel påminnelse om ordenens innflytelse.,Gubernator to proste przypomnienie o wpływach Zakonu.,O governador é um simples lembrete da influência da Ordem.,,Guvernatorul e o simplă reamintire a influenței Ordinului.,Губернатор — живое напоминание о власти Ордена.,,"Vali, Tarikat'ın etkisinin basit bir hatırlatıcısıdır." -Come back if you change your mind.,TXT_RNO0_SCRIPT33_D10612_COMEB,〃,,,"Vrať se, pokud změníš názor.","Kom tilbage, hvis du skifter mening.","Komm zurück, wenn du deine Meinung geändert hast.",,,Vuelve si cambias de idea.,,"Puhutaan taas, jos tulet toisiin aatoksiin.",Revenez si vous changez d'avis.,Gyere vissza ha változik a véleményed.,Torna pure se cambi idea.,気が変わったら戻ってきな。,마음이 바뀌면 돌아와주게나.,Kom terug als u van gedachten verandert.,Kom tilbake hvis du ombestemmer deg.,"Wróć, jeśli zmienisz zdanie.",Volte quando mudar de idéia.,,Întoarce-te dacă te răzgândești.,Передумаешь — возвращайся.,,Fikrini değiştirirsen geri gel. +私は今あなたのために何ができますか?","다시 돌아온 건가? 뭐, 자기 몸 간수 잘하고 살아 돌아왔기에 망정이지. 뭘 원하나?","Weer terug, hè? Nou ja, je weet tenminste genoeg om je eigen huid intact te houden. Wat kan ik nu voor je doen?","Tilbake igjen, hva? Du vet i det minste nok til å holde ditt eget skinn intakt. Hva kan jeg gjøre for deg nå?","Znowu to samo? Przynajmniej wiesz wystarczająco dużo, aby zachować własną skórę w nienaruszonym stanie. Co mogę dla ciebie zrobić?","Já voltou, é? Bom, pelo menos você sabe o suficiente para manter sua pele intacta. O que mais posso fazer por você?",,"Te-ai întors din nou, hă? Păi, măcar cunoști destule cât să rămâi întreg. Ce pot face pentru tine?","Снова ты? Ну что ж, ты хотя бы знаешь, как шкуру сберечь. Что я могу тебе предложить?",,"Tillbaka igen, va? Du vet åtminstone tillräckligt för att hålla ditt eget skinn intakt. Vad kan jag göra för dig nu?",Yine mi döndün? En azından kendi derini sağlam tutacak kadar biliyorsun. Şimdi senin için ne yapabilirim? +More info,TXT_RPLY0_SCRIPT33_D10612_MOREI,〃,,,Další informace,Mere info,Mehr Informationen.,,Pliaj informoj,Más información,,Lisää tietoa.,Plus d'infos.,Több információ.,Altre informazioni,話のネタ。,그 외의 정보를 줘.,Meer info,Mer info,Więcej informacji,Mais informações.,,Mai multă informație,Расскажи больше,,Mer information,Daha fazla bilgi +The Governor is a simple reminder of the Order's influence.,TXT_RYES0_SCRIPT33_D10612_THEGO,〃,,,Guvernér je jednoduchou připomínkou vlivu Řádu.,Guvernøren er en simpel påmindelse om Ordenens indflydelse.,Der Gouverneur ist eine einfache Erinnering an die Macht des Ordens.,,,El gobernador es un simple recordatorio de la influencia de La Orden,,Kuvernööri on selvä muistutus Veljeskunnan vaikutusvallasta.,Le gouverneur d'est qu'un rappel de l'influence de l'ordre.,A Kormányzó csak a Rend hatalmának bábja.,Il governatore è solo un simbolo dell'influenza dell'Ordine.,知事は俺達に自由はないと思い出させる象徴さ。,모렐 총독은 부정하고 짜증 나는 오더의 정권의 예야.,De gouverneur is een eenvoudige herinnering aan de invloed van de Orde.,Guvernøren er en enkel påminnelse om ordenens innflytelse.,Gubernator to proste przypomnienie o wpływach Zakonu.,O governador é um simples lembrete da influência da Ordem.,,Guvernatorul e o simplă reamintire a influenței Ordinului.,Губернатор — живое напоминание о власти Ордена.,,Guvernören är en enkel påminnelse om ordens inflytande.,"Vali, Tarikat'ın etkisinin basit bir hatırlatıcısıdır." +Come back if you change your mind.,TXT_RNO0_SCRIPT33_D10612_COMEB,〃,,,"Vrať se, pokud změníš názor.","Kom tilbage, hvis du skifter mening.","Komm zurück, wenn du deine Meinung geändert hast.",,,Vuelve si cambias de idea.,,"Puhutaan taas, jos tulet toisiin aatoksiin.",Revenez si vous changez d'avis.,Gyere vissza ha változik a véleményed.,Torna pure se cambi idea.,気が変わったら戻ってきな。,마음이 바뀌면 돌아와주게나.,Kom terug als u van gedachten verandert.,Kom tilbake hvis du ombestemmer deg.,"Wróć, jeśli zmienisz zdanie.",Volte quando mudar de idéia.,,Întoarce-te dacă te răzgândești.,Передумаешь — возвращайся.,,Kom tillbaka om du ändrar dig.,Fikrini değiştirirsen geri gel. "Well, you're sure asking a lot of questions for someone who's lived this long. That's ok though, I'd rather talk to someone like you than most of this lot.",TXT_DLG_SCRIPT33_D12128_WELLY,〃,,,"Na někoho, kdo přežil takhle dlouho, se ptáš docela hodně. To je v pořádku, radši bych se bavil s tebou než s většinou těhle lidí.","Du stiller virkelig mange spørgsmål af en, der har levet så længe. Det er dog ok, jeg vil hellere tale med en som dig end med de fleste af dem her.","Du stellst eine Menge Fragen für jemanden, der schon so lange überlebt hat. Das ist ok, ich rede lieber mit jemandem wie dir als mit dem Rest der Typen da.",,,"Bueno, ciertamente estás haciendo muchas preguntas para alguien que ha vivido tanto. Aunque eso es bueno, preferiría hablar con alquien como tú que con la mayoría de esta gente.",,"No, kyllläpä paljon kyselet sellaiseksi, joka näin pitkään on hengissä säilynyt. Mutta ei se mitään; mieluummin puhun jonkun sinun kaltaisesi kuin suurimman osan kanssa tätä porukkaa.","Vous posez beacoup de questions pour quelqu'un qui a survécu aussi longtemps. Ca me convient, je préfère parler à quelqu'un comme vous qu'a la majorité de ces idiots.","Ahhoz képest, hogy eddig éltél, elég sok kédést teszel fel. Igazából nem probléma, szívesebben beszélek veled mint mással itt.","Beh, fai davvero tante domande, per uno che è ancora vivo. Ma a me sta bene, molto meglio parlare con te rispetto agli altri che stanno qui...","所で、アンタは死に行かない人達に 聞き回ってる様だが。悪いことは言わねえ、 -あんまし死に急ぐんじゃねえぞ。","아주 오래 살아서 배짱이 두둑한가, 다시 돌아와 줬구먼! 나야말로 괜찮다네. 이 주정부리들 보다 자네랑 대화하는 게 그나마 낫지.","Nou, je stelt zeker veel vragen aan iemand die zo lang heeft geleefd. Maar dat is niet erg, ik praat liever met iemand zoals jij dan met de meeste van deze mensen.","Du stiller mange spørsmål til å være en som har levd så lenge. Men det er greit, jeg vil heller snakke med en som deg enn de fleste av disse.","Zadajesz dużo pytań jak na kogoś, kto żyje tak długo. W porządku. Wolę rozmawiać z kimś takim jak ty niż z większością tych ludzi.","Bem, para alguém que conseguiu viver bastante você certamente faz muitas perguntas. Mas tudo bem, eu prefiro conversar com alguém como você do que com a maioria destes caras.",,"Păi, cu sigranță pui multe întrebări pentru cineva care a trăit atât. E în regulă însă, prefer să vorbesc cu cineva ca tine decât cu grămada asta.","Да, для человека, который прожил так долго, ты задаёшь многовато вопросов. Впрочем, это неплохо: я бы скорее предпочёл говорить с кем-то вроде тебя, чем с местными.",,"Bu kadar uzun yaşamış biri için çok fazla soru soruyorsun. Yine de sorun değil, buradakilerin çoğuyla konuşmaktansa senin gibi biriyle konuşmayı tercih ederim." -More info.,TXT_RPLY0_SCRIPT33_D12128_MOREI,〃,,,Další informace,Mere info.,Mehr Informationen.,,Pliaj informoj.,Más información.,,Lisää tietoa.,Plus d'infos.,Több információ.,Altre informazioni,話のネタ。,더 많은 정보를 줘.,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multă informație.,Говори дальше.,,Daha fazla bilgi. -There's more to the Order than what goes on around here.,TXT_RYES0_SCRIPT33_D12128_THERE,〃,,,"Za Řádem se toho skrývá víc, než tady vidíš.","Der er mere i Ordenen end det, der foregår her.","Hinter dem Orden steckt mehr, als es den Anschein hat.",,,Hay más de La Orden que lo que pasa por aquí.,,"Veljeskunnan toiminta ei rajoitu vain siihen, mitä täällä tapahtuu.",L'Ordre cache beaucoup plus que ce qui ne se passe ici.,"A Rend mögött több áll, mint amit az emberek pletykálnak.",C'è sotto molto di più sull'Ordine rispetto a quello che succede qua.,オーダーは見えてる以上に強大だ。,여기저기 퍼지는 소문보다 오더가 지키는 비밀이 더 깊숙하다네.,De Orde heeft meer te bieden dan wat er hier gebeurt.,Ordenen er mer enn bare det som foregår her.,"Zakon to coś więcej niż to, co dzieje się tutaj.",Há mais sobre a Ordem do que acontece por aqui.,,Sunt mai multe lucruri care țin de Ordin decât ceea ce se petrece în jur.,"Орден — нечто большее, чем кажется.",,Tarikat'ta burada olanlardan daha fazlası var. -Come back if you change your mind.,TXT_RNO0_SCRIPT33_D12128_COMEB,〃,,,"Vrať se, pokud změníš názor.","Kom tilbage, hvis du skifter mening.","Komm zurück, wenn du deine Meinung geändert hast.",,,Vuelve si cambias de idea.,,"Jos muutat mielesi, palataan asiaan.",Revenez si vous changez d'avis.,"Gyere vissza, ha meggondoltad magad.",Ritorna semmai cambi idea.,気が変わったら戻ってきな。,생각이 바뀌면 다시 돌아오게나.,Kom terug als je van gedachten verandert.,Kom tilbake hvis du ombestemmer deg.,"Wróć, jeśli zmienisz zdanie.",Volte quando mudar de idéia.,,Întoarce-te dacă te răzgândești.,Передумаешь — возвращайся.,,Fikrini değiştirirsen geri gel. +あんまし死に急ぐんじゃねえぞ。","아주 오래 살아서 배짱이 두둑한가, 다시 돌아와 줬구먼! 나야말로 괜찮다네. 이 주정부리들 보다 자네랑 대화하는 게 그나마 낫지.","Nou, je stelt zeker veel vragen aan iemand die zo lang heeft geleefd. Maar dat is niet erg, ik praat liever met iemand zoals jij dan met de meeste van deze mensen.","Du stiller mange spørsmål til å være en som har levd så lenge. Men det er greit, jeg vil heller snakke med en som deg enn de fleste av disse.","Zadajesz dużo pytań jak na kogoś, kto żyje tak długo. W porządku. Wolę rozmawiać z kimś takim jak ty niż z większością tych ludzi.","Bem, para alguém que conseguiu viver bastante você certamente faz muitas perguntas. Mas tudo bem, eu prefiro conversar com alguém como você do que com a maioria destes caras.",,"Păi, cu sigranță pui multe întrebări pentru cineva care a trăit atât. E în regulă însă, prefer să vorbesc cu cineva ca tine decât cu grămada asta.","Да, для человека, который прожил так долго, ты задаёшь многовато вопросов. Впрочем, это неплохо: я бы скорее предпочёл говорить с кем-то вроде тебя, чем с местными.",,"Du ställer verkligen många frågor för någon som har levt så här länge. Men det är okej, jag pratar hellre med någon som dig än med de flesta av de här.","Bu kadar uzun yaşamış biri için çok fazla soru soruyorsun. Yine de sorun değil, buradakilerin çoğuyla konuşmaktansa senin gibi biriyle konuşmayı tercih ederim." +More info.,TXT_RPLY0_SCRIPT33_D12128_MOREI,〃,,,Další informace,Mere info.,Mehr Informationen.,,Pliaj informoj.,Más información.,,Lisää tietoa.,Plus d'infos.,Több információ.,Altre informazioni,話のネタ。,더 많은 정보를 줘.,Meer info.,Mer informasjon.,Więcej informacji.,Mais informações.,,Mai multă informație.,Говори дальше.,,Mer information.,Daha fazla bilgi. +There's more to the Order than what goes on around here.,TXT_RYES0_SCRIPT33_D12128_THERE,〃,,,"Za Řádem se toho skrývá víc, než tady vidíš.","Der er mere i Ordenen end det, der foregår her.","Hinter dem Orden steckt mehr, als es den Anschein hat.",,,Hay más de La Orden que lo que pasa por aquí.,,"Veljeskunnan toiminta ei rajoitu vain siihen, mitä täällä tapahtuu.",L'Ordre cache beaucoup plus que ce qui ne se passe ici.,"A Rend mögött több áll, mint amit az emberek pletykálnak.",C'è sotto molto di più sull'Ordine rispetto a quello che succede qua.,オーダーは見えてる以上に強大だ。,여기저기 퍼지는 소문보다 오더가 지키는 비밀이 더 깊숙하다네.,De Orde heeft meer te bieden dan wat er hier gebeurt.,Ordenen er mer enn bare det som foregår her.,"Zakon to coś więcej niż to, co dzieje się tutaj.",Há mais sobre a Ordem do que acontece por aqui.,,Sunt mai multe lucruri care țin de Ordin decât ceea ce se petrece în jur.,"Орден — нечто большее, чем кажется.",,Det finns mer i Orden än vad som händer här.,Tarikat'ta burada olanlardan daha fazlası var. +Come back if you change your mind.,TXT_RNO0_SCRIPT33_D12128_COMEB,〃,,,"Vrať se, pokud změníš názor.","Kom tilbage, hvis du skifter mening.","Komm zurück, wenn du deine Meinung geändert hast.",,,Vuelve si cambias de idea.,,"Jos muutat mielesi, palataan asiaan.",Revenez si vous changez d'avis.,"Gyere vissza, ha meggondoltad magad.",Ritorna semmai cambi idea.,気が変わったら戻ってきな。,생각이 바뀌면 다시 돌아오게나.,Kom terug als je van gedachten verandert.,Kom tilbake hvis du ombestemmer deg.,"Wróć, jeśli zmienisz zdanie.",Volte quando mudar de idéia.,,Întoarce-te dacă te răzgândești.,Передумаешь — возвращайся.,,Kom tillbaka om du ändrar dig.,Fikrini değiştirirsen geri gel. "That's it friend, the well of knowledge has been tapped. I've told you more than I should have anyway.",TXT_DLG_SCRIPT33_D13644_THATS,〃,,,"A to je vše, příteli, studnice mé moudrosti vyschla. Stejně jsem ti řekl víc, než jsem měl.","Det var det, min ven, vidensbrønden er blevet tappet. Jeg har alligevel fortalt dig mere, end jeg burde have gjort.","Das ist es, Freund, der Brunnen des Wissens ist versiegt. Ich habe dir schon mehr gesagt, als ich eigentlich sollte.",,,"Ya está amigo, el pozo del conocimiento se ha secado. Te he dicho más de lo que debería, de todos modos.",,"Siinä kaikki, ystävä. Tiedon lähde on ehtynyt. Olen kertonut sinulle joka tapauksessa enemmän kuin olisi pitänytkään.","C'est tout, mon ami. Le puits de la sagesse s'est tari. Je vous en ai trop dit de toutes manières.","Ennyi volt barátom, a tudás forrása elapadt. Már így is többet mondtam a kelleténél.","È tutto, amico, ho esaurito le cose che avevo da dirti. Ti ho già detto più di quanto avrei dovuto.","これはこれは親友、心得の瓶は切らしてるぞ。 -とにかく俺が知ってる話はこれで全部だ。",이게 다일세. 내가 친히 줄 수 있는 조언이라는 이름의 술은 다 줬다네.,"Dat is het vriend, de bron van kennis is aangeboord. Ik heb je meer verteld dan ik toch al zou moeten hebben.","Det var det, min venn. Kunnskapens brønn er tappet. Jeg har fortalt deg mer enn jeg burde uansett.","To wszystko przyjacielu, studnia wiedzy została wyczerpana. I tak powiedziałem ci więcej niż powinienem.","É isso, amigo. O poço de conhecimento já secou. Já te contei mais do que eu deveria, de qualquer forma.",,"Gata prietene, fântâna a secat. Ți-am spus mai multe decât ar fi trebuit oricum.","Это всё, дружище. Кладезь мудрости исчерпан. Я и так рассказал тебе больше, чем следовало.",,"Bu kadar dostum, bilgi kuyusu doldu. Zaten sana söylemem gerekenden fazlasını söyledim." +とにかく俺が知ってる話はこれで全部だ。",이게 다일세. 내가 친히 줄 수 있는 조언이라는 이름의 술은 다 줬다네.,"Dat is het vriend, de bron van kennis is aangeboord. Ik heb je meer verteld dan ik toch al zou moeten hebben.","Det var det, min venn. Kunnskapens brønn er tappet. Jeg har fortalt deg mer enn jeg burde uansett.","To wszystko przyjacielu, studnia wiedzy została wyczerpana. I tak powiedziałem ci więcej niż powinienem.","É isso, amigo. O poço de conhecimento já secou. Já te contei mais do que eu deveria, de qualquer forma.",,"Gata prietene, fântâna a secat. Ți-am spus mai multe decât ar fi trebuit oricum.","Это всё, дружище. Кладезь мудрости исчерпан. Я и так рассказал тебе больше, чем следовало.",,"Det var allt, min vän, kunskapens källa har blivit tömd. Jag har berättat mer än jag borde ha gjort i alla fall.","Bu kadar dostum, bilgi kuyusu doldu. Zaten sana söylemem gerekenden fazlasını söyledim." Hard to shop for new toys... when you're broke. Run a little errand for me and you'll get more than you could ever spend. I'll make you a rich man.,TXT_DLG_SCRIPT33_D15160_HARDT,MAP33: Harris.,,,"Nové hračky se shánějí jen těžko... když jsi švorc. Udělej pro mě malou prácičku a dostaneš víc, než kolik bys mohl kdy utratit. Udělám z tebe boháče.","Det er svært at købe nyt legetøj, når man er flad. Gør et lille ærinde for mig, og du vil få mere, end du nogensinde vil kunne bruge. Jeg vil gøre dig til en rig mand.","Ist es nicht schwierig, an neue Sachen zu kommen, wenn du pleite bist? Tu mir einen Gefallen und du kannst mehr Gold kriegen, als du jemals ausgeben kannst. Ich mache dich reich.",,,Difícil comprarse nuevos juguetes... cuando estás sin blanca. Haz algunos recados para mí y conseguirás más de lo que puedas gastarte. Te haré un hombre rico.,Difícil comprarse nuevos juguetes... cuando estás quebrado. Haz algunos encargos para mí y conseguirás más de lo que puedas gastarte. Te voy a hacer un hombre rico.,"Vaikea ostaa uusia leluja, kun on peeaa. Käytkö hoitamassa minulle yhden asian, niin tienaat enemmän kuin pystyt ikinä kuluttamaan. Teen sinusta kroisoksen.",Difficile de s'acheter de nouveaux joujous quand on n'a plus de sous. Faites-moi une petite course et vous aurez plus que vous ne pourrez jamais dépenser. Je vous rendrai riche.,"Nehéz úgy új játékszereket beszerezni, ha ennyire nincs pénzed. Viszont ha megteszel nekem egy szívességet, annyi pénzed lesz amit el se tudsz költeni. Gazdaggá teszlek.","È difficile comprare nuovi giocattoli... quando non hai la grana. Se fai un piccolo favore per me, potrai avere così tanti soldi da non sapere come spenderli. Ti renderò un uomo molto ricco.","新しい玩具も買えないぐらい...貧しそうだな アンタ。良い儲け話があるぜ。 -俺のちょっとした仕事でガッポガポだぞ。",여기저기 장난감을 살려면 돈이 필요하지. 세상에 공짜가 어디 있나? 내 심부름을 좀 하다 보면 용돈도 생기고 부자가 될 걸세. 어떤가?,Moeilijk om nieuw speelgoed te kopen.... als je blut bent. Doe een kleine boodschap voor me en je krijgt meer dan je ooit zou kunnen uitgeven. Ik zal je een rijk man maken.,"Vanskelig å kjøpe nye leker... når man er blakk. Gjør et lite ærend for meg, så får du mer enn du kan bruke. Jeg skal gjøre deg rik.","Trudno jest kupować nowe zabawki... kiedy jest się spłukanym. Zrób dla mnie małe zlecenie, a dostaniesz więcej niż mógłbyś kiedykolwiek wydać. Zrobię z ciebie bogatego człowieka.","É difícil comprar brinquedos novos... quando você está duro. Se você fizer um favor pra mim, você vai ganhar mais do que jamais conseguiria gastar. Vou fazer de você um homem rico.",,Greu să cumperi jucarii noi... când ești falit. Dar faci o mică treabă pentru mine și o să fii putred de bogat.,"Трудновато покупать игрушки, когда нет и гроша за душой... Выполни одно заданьице для меня, и ты заработаешь столько, сколько в твоих карманах сроду не водилось. Ты будешь богатым!",,"Beş parasızken yeni oyuncaklar için alışveriş yapmak zor. Benim için ufak bir iş yaparsan, harcayabileceğinden fazlasını alırsın. Seni zengin bir adam yapacağım." -I got nothing better to do.,TXT_RPLY0_SCRIPT33_D15160_IGOTN,〃,,,Nemám nic lepšího na práci.,Jeg har intet bedre at lave.,Ich habe nichts besseres zu tun.,,Mi havas nenian farindaĵon.,No tengo nada mejor que hacer.,,Ei minulla parempaakaan tekemistä ole.,Je n'ai rien de mieux à faire.,Nincs jobb dolgom úgy sem.,Non ho di meglio da fare.,何もしないよりはいいか。,저는 할 것이 아무것도 없어요.,Ik heb niets beters te doen.,Jeg har ikke noe bedre å gjøre.,Nie mam nic lepszego do roboty.,Não tenho nada melhor pra fazer.,,N-am nimic mai bun de făcut.,Заманчивое предложение.,,Yapacak daha iyi bir işim yok. -No thanks.,TXT_RPLY1_SCRIPT33_D15160_NOTHA,〃,,,"Ne, díky.",Nej tak.,"Nein, danke.",,"Ne, dankon.","No, gracias.",,Ei kiitos.,Non merci.,Nem kösz.,No grazie.,いらない。,아뇨 괜찮습니다.,"Nee, bedankt.",Ellers takk.,"Nie, dziękuję.","Não, obrigado.",,Nu merci.,"Нет, спасибо.",,"Hayır, teşekkürler." -Nobody walks away from me!,TXT_RYES1_SCRIPT33_D15160_NOBOD,〃,,,Ode mě nikdo neodchází!,Ingen går væk fra mig!,Niemand sagt Nein zu mir.,,,¡Nadie pasa de mí!,,Kukaan ei käännä selkäänsä minulle!,Personne ne se barre après mon offre!,Senki sem sétál el előlem!,Nessuno fa l'impertinente con me!,俺から逃げられると思ってるのか!,그 누구도 나를 거절할 수 없어!,Niemand loopt weg van mij!,Ingen går fra meg!,Nikt ode mnie nie odchodzi!,Ninguém me ignora!,,Nimeni nu scapă de mine!,От меня ещё никто не уходил!,,Kimse benden kaçamaz! +俺のちょっとした仕事でガッポガポだぞ。",여기저기 장난감을 살려면 돈이 필요하지. 세상에 공짜가 어디 있나? 내 심부름을 좀 하다 보면 용돈도 생기고 부자가 될 걸세. 어떤가?,Moeilijk om nieuw speelgoed te kopen.... als je blut bent. Doe een kleine boodschap voor me en je krijgt meer dan je ooit zou kunnen uitgeven. Ik zal je een rijk man maken.,"Vanskelig å kjøpe nye leker... når man er blakk. Gjør et lite ærend for meg, så får du mer enn du kan bruke. Jeg skal gjøre deg rik.","Trudno jest kupować nowe zabawki... kiedy jest się spłukanym. Zrób dla mnie małe zlecenie, a dostaniesz więcej niż mógłbyś kiedykolwiek wydać. Zrobię z ciebie bogatego człowieka.","É difícil comprar brinquedos novos... quando você está duro. Se você fizer um favor pra mim, você vai ganhar mais do que jamais conseguiria gastar. Vou fazer de você um homem rico.",,Greu să cumperi jucarii noi... când ești falit. Dar faci o mică treabă pentru mine și o să fii putred de bogat.,"Трудновато покупать игрушки, когда нет и гроша за душой... Выполни одно заданьице для меня, и ты заработаешь столько, сколько в твоих карманах сроду не водилось. Ты будешь богатым!",,Svårt att handla nya leksaker när man är pank. Gör ett litet ärende åt mig och du får mer än du någonsin kan spendera. Jag gör dig till en rik man.,"Beş parasızken yeni oyuncaklar için alışveriş yapmak zor. Benim için ufak bir iş yaparsan, harcayabileceğinden fazlasını alırsın. Seni zengin bir adam yapacağım." +I got nothing better to do.,TXT_RPLY0_SCRIPT33_D15160_IGOTN,〃,,,Nemám nic lepšího na práci.,Jeg har intet bedre at lave.,Ich habe nichts besseres zu tun.,,Mi havas nenian farindaĵon.,No tengo nada mejor que hacer.,,Ei minulla parempaakaan tekemistä ole.,Je n'ai rien de mieux à faire.,Nincs jobb dolgom úgy sem.,Non ho di meglio da fare.,何もしないよりはいいか。,저는 할 것이 아무것도 없어요.,Ik heb niets beters te doen.,Jeg har ikke noe bedre å gjøre.,Nie mam nic lepszego do roboty.,Não tenho nada melhor pra fazer.,,N-am nimic mai bun de făcut.,Заманчивое предложение.,,Jag har inget bättre att göra.,Yapacak daha iyi bir işim yok. +No thanks.,TXT_RPLY1_SCRIPT33_D15160_NOTHA,〃,,,"Ne, díky.",Nej tak.,"Nein, danke.",,"Ne, dankon.","No, gracias.",,Ei kiitos.,Non merci.,Nem kösz.,No grazie.,いらない。,아뇨 괜찮습니다.,"Nee, bedankt.",Ellers takk.,"Nie, dziękuję.","Não, obrigado.",,Nu merci.,"Нет, спасибо.",,Jag har inget bättre för mig.,"Hayır, teşekkürler." +Nobody walks away from me!,TXT_RYES1_SCRIPT33_D15160_NOBOD,〃,,,Ode mě nikdo neodchází!,Ingen går væk fra mig!,Niemand sagt Nein zu mir.,,,¡Nadie pasa de mí!,,Kukaan ei käännä selkäänsä minulle!,Personne ne se barre après mon offre!,Senki sem sétál el előlem!,Nessuno fa l'impertinente con me!,俺から逃げられると思ってるのか!,그 누구도 나를 거절할 수 없어!,Niemand loopt weg van mij!,Ingen går fra meg!,Nikt ode mnie nie odchodzi!,Ninguém me ignora!,,Nimeni nu scapă de mine!,От меня ещё никто не уходил!,,Ingen går ifrån mig!,Kimse benden kaçamaz! "Good choice. The Order's sanctuary by the river is their unofficial torture chamber. Hidden inside there's a golden chalice. You swipe it, you meet me at the tavern, and reap your reward.",TXT_DLG_SCRIPT33_D16676_GOODC,〃,,,"Dobrá volba. Svatyně Řádu u řeky je jejich neoficiální mučírna. Uvnitř je skrytý zlatý kalich. Sebereš ho, sejdeš se se mnou v taverně a vyzvedneš si svou odměnu.","Godt valg. Ordenens fristed ved floden er deres uofficielle torturkammer. Der er en gylden bæger gemt derinde. Du tager den, du møder mig på kroen og høster din belønning.",Gute Wahl. Das Heiligtum des Ordens bei dem Fluss ist ihre inoffiziele Folterkammer. Darin versteckt ist ein goldener Kelch. Du klaust ihn und erntest deinen Lohn.,,,"Buena elección. El santuario de la Orden junto al río es su cámara de tortura no oficial. Oculto adentro hay un cáliz de oro. Lo robas, me vienes a ver a la taberna y consigues tu recompensa.",,"Viisas päätös. Veljeskunnan pyhäkkö joen varrella on heidän epävirallinen kidutuskammionsa, jonka kätköissä piilee kultakalkki. Kähvellä se ja saat vaivannäöstäsi palkan.",Bon choix. Le sanctuaire de l'ordre près de la rivière est leur chambre torture.. officieusement. A l'intérieur se trouve un calice en or. Récupérez le et venez prendre votre récompense.,"Jó választás. A Rend folyó melletti szentélye valójában a nem hivatalos kínzó kamrájuk. Elrejtve belül található egy arany serleg. Csend el szépen, és a kocsmánál találkozunk, lepasszolom a jutalmad.",Ottima scelta. Il santuario dell'Ordine vicino al fiume è la loro camera della tortura. Vi è un calice d'oro nascosto là dentro. Prendilo e avrai una lauta ricompensa.,"良い判断だ。川沿いにある オーダーの聖域 は あいつらの非公式の拷問室だ。 中には黄金の聖杯が隠してある。 そいつを持ってくれば報酬をやるぜ。 -",좋은 선택이야. 강가 근처에 있는 성소가 바로 오더의 비공식적인 고문실이야. 그리고 그 안에는 숨겨진 금색 성배가 있지. 넌 그것을 훔치고 여기 선술집으로 와서 보상을 받으면 돼.,"Goede keuze. Het heiligdom van de Orde bij de rivier is hun onofficiële martelkamer. Verborgen in de kelk zit een gouden kelk. Je haalt hem weg, je komt me tegen in de herberg, en plukt je beloning.","Godt valg. Ordenens helligdom ved elven er deres uoffisielle torturkammer. Gjemt der inne er det et gyllent beger. Du stjeler det, møter meg på vertshuset og høster belønningen din.","Dobry wybór. Sanktuarium Zakonu nad rzeką jest ich nieoficjalną salą tortur. W środku jest ukryty złoty kielich. Machniesz nim, spotkasz się ze mną w tawernie i odbierzesz swoją nagrodę.","Boa escolha. O santuário da Ordem próximo ao rio é a câmara de tortura não oficial deles. Dentro dele há um cálice dourado. Pegue-o, me encontre na taverna e pegue sua recompensa.",,"Bună alegere. Sanctuarul Ordinului de lângă râu e lagărul lor neoficial. Ascuns înăuntru e un potir. Îl înșfaci, mă găsești la tavernă, și îți iei răsplata.","Правильный выбор. В святилище Ордена у реки — там у них негласная камера пыток — спрятана золотая чаша. Ты крадёшь её, возвращаешься ко мне в таверну и получаешь свою награду.",,"İyi seçim. Tarikat'ın nehir kenarındaki sığınağı onların gayri resmi işkence odası. İçinde altın bir kadeh saklı. Onu çalacaksın, benimle tavernada buluşacaksın ve ödülünü alacaksın." -How am I supposed to do that?,TXT_RPLY0_SCRIPT33_D16676_HOWAM,〃,,,Jak to mám udělat?,Hvordan skal jeg gøre det?,Wie soll ich das anstellen?,,Kiel mi faru tion?,¿Cómo se supone que haga eso?,,Miten minä muka sen teen?,Comment est-ce que je suis sensé faire ça?,Hogyan kéne ezt véghezvinnem?,E come posso fare tutto ciò?,どうすればいいんだ?,어떻게 하면 되나요?,Hoe moet ik dat doen?,Hvordan skal jeg gjøre det?,Jak mam to zrobić?,Como vou conseguir fazer isso?,,Cum ar trebui să fac asta?,Как мне это сделать?,,Bunu nasıl yapacağım? -Let me think about it.,TXT_RPLY1_SCRIPT33_D16676_LETME,〃,,,Nech mě o tom popřemýšlet.,Lad mig tænke over det.,Lass mich darüber nachdenken.,,Mi pensu.,Déjame pensarlo.,,Anna minun pohtia asiaa.,Laissez-moi y réfléchir.,Hadd gondolkozzak.,Ci penso un pò su e poi ti farò sapere.,ちょっと考えとく。,좀 생각해 보겠습니다.,Laat me erover nadenken.,La meg tenke på det.,Pozwól mi się zastanowić.,Vou pensar sobre isso.,,Lasă-mă să mă gândesc.,Я подумаю над твоим предложением.,,Bir düşüneyim. +",좋은 선택이야. 강가 근처에 있는 성소가 바로 오더의 비공식적인 고문실이야. 그리고 그 안에는 숨겨진 금색 성배가 있지. 넌 그것을 훔치고 여기 선술집으로 와서 보상을 받으면 돼.,"Goede keuze. Het heiligdom van de Orde bij de rivier is hun onofficiële martelkamer. Verborgen in de kelk zit een gouden kelk. Je haalt hem weg, je komt me tegen in de herberg, en plukt je beloning.","Godt valg. Ordenens helligdom ved elven er deres uoffisielle torturkammer. Gjemt der inne er det et gyllent beger. Du stjeler det, møter meg på vertshuset og høster belønningen din.","Dobry wybór. Sanktuarium Zakonu nad rzeką jest ich nieoficjalną salą tortur. W środku jest ukryty złoty kielich. Machniesz nim, spotkasz się ze mną w tawernie i odbierzesz swoją nagrodę.","Boa escolha. O santuário da Ordem próximo ao rio é a câmara de tortura não oficial deles. Dentro dele há um cálice dourado. Pegue-o, me encontre na taverna e pegue sua recompensa.",,"Bună alegere. Sanctuarul Ordinului de lângă râu e lagărul lor neoficial. Ascuns înăuntru e un potir. Îl înșfaci, mă găsești la tavernă, și îți iei răsplata.","Правильный выбор. В святилище Ордена у реки — там у них негласная камера пыток — спрятана золотая чаша. Ты крадёшь её, возвращаешься ко мне в таверну и получаешь свою награду.",,"Bra val. Ordens helgedom vid floden är deras inofficiella tortyrkammare. Gömd inuti finns en gyllene bägare. Du tar den, möter mig på tavernan och skördar din belöning.","İyi seçim. Tarikat'ın nehir kenarındaki sığınağı onların gayri resmi işkence odası. İçinde altın bir kadeh saklı. Onu çalacaksın, benimle tavernada buluşacaksın ve ödülünü alacaksın." +How am I supposed to do that?,TXT_RPLY0_SCRIPT33_D16676_HOWAM,〃,,,Jak to mám udělat?,Hvordan skal jeg gøre det?,Wie soll ich das anstellen?,,Kiel mi faru tion?,¿Cómo se supone que haga eso?,,Miten minä muka sen teen?,Comment est-ce que je suis sensé faire ça?,Hogyan kéne ezt véghezvinnem?,E come posso fare tutto ciò?,どうすればいいんだ?,어떻게 하면 되나요?,Hoe moet ik dat doen?,Hvordan skal jeg gjøre det?,Jak mam to zrobić?,Como vou conseguir fazer isso?,,Cum ar trebui să fac asta?,Как мне это сделать?,,Hur ska jag göra det?,Bunu nasıl yapacağım? +Let me think about it.,TXT_RPLY1_SCRIPT33_D16676_LETME,〃,,,Nech mě o tom popřemýšlet.,Lad mig tænke over det.,Lass mich darüber nachdenken.,,Mi pensu.,Déjame pensarlo.,,Anna minun pohtia asiaa.,Laissez-moi y réfléchir.,Hadd gondolkozzak.,Ci penso un pò su e poi ti farò sapere.,ちょっと考えとく。,좀 생각해 보겠습니다.,Laat me erover nadenken.,La meg tenke på det.,Pozwól mi się zastanowić.,Vou pensar sobre isso.,,Lasă-mă să mă gândesc.,Я подумаю над твоим предложением.,,Låt mig tänka på det.,Bir düşüneyim. "Sorry, no second chances. Oh, guards, kill him!",TXT_RYES1_SCRIPT33_D16676_SORRY,〃,,,"Promiň, žádné druhé šance. A, stráže, zabte ho!","Beklager, ingen anden chance. Åh, vagter, dræb ham!","Keine zweite Chance. Oh Wachen, tötet ihn.",,,"Lo siento, no hay segundas oportunidades. ¡Guardias, matadlo!","Lo siento, no hay segundas oportunidades. ¡Guardias, mátenlo!","Pahoittelut, ei toista mahdollisuutta. Vartijat, tappakaa hänet.","Pas de deuxième chance. Gardes, tuez-le.","Bocs, de második esély már nincs. Őrök, végezzétek ki!","Nessuna seconda chance. Guardie, uccidetelo.","残念、次はねえよ。おぅガードの旦那、 -やっちゃってくだせえ。","유감. 두 번째 기회는 없어. 경비원, 저놈을 죽여.","Sorry, geen tweede kans. Oh, bewakers, dood hem!","Beklager, ingen nye sjanser. Vakter, drep ham!","Przykro mi, nie ma drugiej szansy. Och, strażnicy, zabijcie go!","Sinto muito, nada de segundas chances. Ah, guardas, matem-no!",,"Oh, nicio altă șansă. Gardienilor, omorâți-l.","Нет, никакого второго шанса. Эй, стража, убейте его.",,"Üzgünüm, ikinci bir şans yok. Muhafızlar, öldürün onu!" -"Here's a crossbow, just aim straight and -- splat!--. Remember, grab the fancy cup and meet me at the tavern.",TXT_DLG_SCRIPT33_D18192_HERES,〃,,,"Tady je kuše, prostě rovně zamiř a --plesk!--. Nezapomeň, vem fešný hrnek a najdi mě v taverně.","Her er en armbrøst, bare sigt lige ud og -- splat!--. Husk, tag den fine kop og mød mig på kroen.","Hier ist eine Armbust, einfach gerade zielen und --Platsch--. Denk dran, schnapp dir den schicken Kelch und dann ab zur Taverne.",,Jen arbalesto. Vi nur celu laŭ rekta linio kaj «gut». Ne forgesu preni la belan pokalon kaj tiam renkonti min en la taverno.,Aquí tengo una ballesta. Solo apunta en línea recta y «ploc». Recuerda: toma la bonita copa y luego ve a verme a la taberna.,,"Tässä sinulle jousipyssy; tähtää vain eteenpäin ja ""pläts""! Tärkeintä vain, että muistat kahmaista fiinin maljan ja sitten palata kapakkaan.",Voilà une arbalète. Vous avez juste à viser droit et paf! Souvenez-vous. Prenez le goblet et ramenez le à la taverne.,"Itt egy íj, csak célozz egyenesen és -- bumm!--. És emlékezz: hozdd el a díszes serleget nekem a kocsmába.","Ecco una balestra, basta mirare e --splat--. Ricorda, prendi il calice e ritorna alla taverna.","このクロスボウを使いな、狙いを定めて +やっちゃってくだせえ。","유감. 두 번째 기회는 없어. 경비원, 저놈을 죽여.","Sorry, geen tweede kans. Oh, bewakers, dood hem!","Beklager, ingen nye sjanser. Vakter, drep ham!","Przykro mi, nie ma drugiej szansy. Och, strażnicy, zabijcie go!","Sinto muito, nada de segundas chances. Ah, guardas, matem-no!",,"Oh, nicio altă șansă. Gardienilor, omorâți-l.","Нет, никакого второго шанса. Эй, стража, убейте его.",,"Tyvärr, inga andra chanser. Vakter, döda honom!","Üzgünüm, ikinci bir şans yok. Muhafızlar, öldürün onu!" +"Here's a crossbow, just aim straight and -- splat!--. Remember, grab the fancy cup and meet me at the tavern.",TXT_DLG_SCRIPT33_D18192_HERES,〃,,,"Tady je kuše, prostě rovně zamiř a --plesk!--. Nezapomeň, vem fešný hrnek a najdi mě v taverně.","Her er en armbrøst, bare sigt lige ud og -- splat!--. Husk, tag den fine kop og mød mig på kroen.","Hier ist eine Armbust, einfach gerade zielen und --Platsch--. Denk dran, schnapp dir den schicken Kelch und dann ab zur Taverne.",,Jen arbalesto. Vi nur celu laŭ rekta linio kaj «gut». Ne forgesu preni la belan pokalon kaj tiam renkonti min en la taverno.,Aquí tengo una ballesta. Solo apunta en línea recta y «plaf». Recuerda: toma la bonita copa y luego ve a verme a la taberna.,,"Tässä sinulle jousipyssy; tähtää vain eteenpäin ja ""pläts""! Tärkeintä vain, että muistat kahmaista fiinin maljan ja sitten palata kapakkaan.",Voilà une arbalète. Vous avez juste à viser droit et paf! Souvenez-vous. Prenez le goblet et ramenez le à la taverne.,"Itt egy íj, csak célozz egyenesen és -- bumm!--. És emlékezz: hozdd el a díszes serleget nekem a kocsmába.","Ecco una balestra, basta mirare e --splat--. Ricorda, prendi il calice e ritorna alla taverna.","このクロスボウを使いな、狙いを定めて --シュッとな。覚えておけ、 -ファンシーなカップを持ってここに戻ってくると。","여기 석궁이야, 똑바로 겨냥해, 그리고... '철퍼덕'. 기억해, 멋진 컵을 들고 이 곳으로 다시 와.","Hier is een kruisboog, richt gewoon recht en -- splat! --. Vergeet niet, pak de mooie beker en ontmoet me in de herberg.","Her er en armbrøst, bare sikt rett og... plask! Husk, ta den fine koppen og møt meg på tavernaen.","Tu jest kusza, wyceluj prosto i... splat! Pamiętajcie, weźcie elegancki puchar i spotkajmy się w tawernie.","Pegue esta besta. Só mirar direito e splat! Lembre-se, pegue o copo bonitinho e me encontre na taverna.",,"Aici e o arbaletă, doar țintești și -- pleoșc! --. Ține minte, pune mâna pe potir și găsește-mă la tavernă.",Вот арбалет — просто прицеливаешься и «шлеп!» Запомни — хватаешь чашку и возвращаешься в таверну.,,"İşte yaylı tüfek. Düz nişan al ve patlat! Unutma, süslü kupayı al ve benimle tavernada buluş." -I'll see you there.,TXT_RPLY0_SCRIPT33_D18192_ILLSE,〃,,,Uvidíme se tam.,Vi ses der.,Wir sehen uns dort.,,Mi estos tie.,Allí estaré.,Ahí voy a estar.,Tapaan sinut siellä.,Je vous y verrais.,Ott találkozunk.,Ci vediamo lì.,また会おう。,거기서 보자고.,Ik zie je daar.,Vi ses der.,Do zobaczenia.,Te vejo lá.,,Ne vedem acolo.,Я вернусь с чашей.,,Orada görüşürüz. +ファンシーなカップを持ってここに戻ってくると。","여기 석궁이야, 똑바로 겨냥해, 그리고... '철퍼덕'. 기억해, 멋진 컵을 들고 이 곳으로 다시 와.","Hier is een kruisboog, richt gewoon recht en -- splat! --. Vergeet niet, pak de mooie beker en ontmoet me in de herberg.","Her er en armbrøst, bare sikt rett og... plask! Husk, ta den fine koppen og møt meg på tavernaen.","Tu jest kusza, wyceluj prosto i... splat! Pamiętajcie, weźcie elegancki puchar i spotkajmy się w tawernie.","Pegue esta besta. Só mirar direito e splat! Lembre-se, pegue o copo bonitinho e me encontre na taverna.",,"Aici e o arbaletă, doar țintești și -- pleoșc! --. Ține minte, pune mâna pe potir și găsește-mă la tavernă.",Вот арбалет — просто прицеливаешься и «шлеп!» Запомни — хватаешь чашку и возвращаешься в таверну.,,"Här är ett armborst, sikta rakt och -- splat!--. Kom ihåg, ta den fina koppen och möt mig på tavernan.","İşte yaylı tüfek. Düz nişan al ve patlat! Unutma, süslü kupayı al ve benimle tavernada buluş." +I'll see you there.,TXT_RPLY0_SCRIPT33_D18192_ILLSE,〃,,,Uvidíme se tam.,Vi ses der.,Wir sehen uns dort.,,Mi estos tie.,Allí estaré.,Ahí voy a estar.,Tapaan sinut siellä.,Je vous y verrais.,Ott találkozunk.,Ci vediamo lì.,また会おう。,거기서 보자고.,Ik zie je daar.,Vi ses der.,Do zobaczenia.,Te vejo lá.,,Ne vedem acolo.,Я вернусь с чашей.,,Vi ses där.,Orada görüşürüz. "What are you waiting for? Don't worry, I'll clean up the bodies, just bring me that chalice!",TXT_DLG_SCRIPT33_D19708_WHATA,〃,,,"Na co čekáš? Neboj, mrtvol se zbavím já, prostě mi přines ten kalich!","Hvad venter du på? Bare rolig, jeg skal nok rydde op efter ligene, bare giv mig bægeret!","Worauf wartest du noch? Keine Sorge, ich kümmere mich um die Leichen. Bring mir den Kelch.",,,"¿A qué estás esperando? Yo me deshago de los cuerpos, así que tranquilo. ¡Tú solo tráeme ese cáliz!","¿Qué estás esperando? Yo me deshago de los cuerpos, así que tranquilo. ¡Tú solo tráeme ese cáliz!","Mitä oikein odottelet? Älä huoli, siivoan kyllä ruumiit. Tuo vaan minulle se kalkki.","Qu'attendez vous? Je m'occuperai des corps, ne vous inquiétez pas. Apportez-moi le calice!","Mire vársz? Ne aggódj, majd feltakarítom a hullákat, csak hozdd el a serleget.","Che cosa stai aspettando? Non ti preoccupare, ci penserò io a far sparire i corpi, tu pensa solo a portarmi quel calice!","何ボーっとしてんだ? 心配すんな、 -チャッチャと片付けて聖杯を持ってこい!","뭘 기다리는 거야? 걱정하지 마, 내가 시체들을 치워줄 테니. 그냥 성배를 가져와!","Waar wacht je nog op? Maak je geen zorgen, ik ruim de lichamen op, breng me gewoon die kelk!","Hva venter du på? Slapp av, jeg skal rydde opp i likene, bare gi meg begeret!","Na co czekasz? Nie martw się, posprzątam ciała, tylko przynieś mi ten kielich!","O que está esperando? Não se preocupe, eu limpo os corpos. Apenas me traga aquele cálice!",,"Ce mai aștepți? Nu te teme, voi curăța eu cadavrele, tu doar adu-mi potirul.",Чего ты ждёшь? Не беспокойся: я сам избавлюсь от трупов. Просто принеси мне чашу!,,"Neyi bekliyorsun? Merak etme, cesetleri temizleyeceğim, sadece kadehi bana getir!" -Guards! Kill the traitor!,TXT_DLG_SCRIPT33_D21224_GUARD,〃,,,Stráže! Zabte toho zrádce!,Vagter! Dræb forræderen!,Wächter! Tötet den Verräter!,,,¡Guardias! ¡Matad al traidor!,¡Guardias! ¡Maten al traidor!,Vartijat! Tappakaa petturi!,Gardes! Tuez ce traître!,Őrök! Öljétek meg az árulót!,Guardie! Uccidete il traditore!,ガード! 裏切者を殺せ!,경비! 반역자를 죽여라!,Bewakers! Dood de verrader!,Vakter! Drep forræderen!,Strażnicy! Zabić zdrajcę!,Guardas! Matem esse traidor!,,"Gardieni, omorâți trădătorul!",Стража! Убейте предателя!,,Muhafızlar! Haini öldürün! +チャッチャと片付けて聖杯を持ってこい!","뭘 기다리는 거야? 걱정하지 마, 내가 시체들을 치워줄 테니. 그냥 성배를 가져와!","Waar wacht je nog op? Maak je geen zorgen, ik ruim de lichamen op, breng me gewoon die kelk!","Hva venter du på? Slapp av, jeg skal rydde opp i likene, bare gi meg begeret!","Na co czekasz? Nie martw się, posprzątam ciała, tylko przynieś mi ten kielich!","O que está esperando? Não se preocupe, eu limpo os corpos. Apenas me traga aquele cálice!",,"Ce mai aștepți? Nu te teme, voi curăța eu cadavrele, tu doar adu-mi potirul.",Чего ты ждёшь? Не беспокойся: я сам избавлюсь от трупов. Просто принеси мне чашу!,,"Vad väntar du på? Oroa dig inte, jag städar upp kropparna, ge mig bara kalken!","Neyi bekliyorsun? Merak etme, cesetleri temizleyeceğim, sadece kadehi bana getir!" +Guards! Kill the traitor!,TXT_DLG_SCRIPT33_D21224_GUARD,〃,,,Stráže! Zabte toho zrádce!,Vagter! Dræb forræderen!,Wächter! Tötet den Verräter!,,,¡Guardias! ¡Matad al traidor!,¡Guardias! ¡Maten al traidor!,Vartijat! Tappakaa petturi!,Gardes! Tuez ce traître!,Őrök! Öljétek meg az árulót!,Guardie! Uccidete il traditore!,ガード! 裏切者を殺せ!,경비! 반역자를 죽여라!,Bewakers! Dood de verrader!,Vakter! Drep forræderen!,Strażnicy! Zabić zdrajcę!,Guardas! Matem esse traidor!,,"Gardieni, omorâți trădătorul!",Стража! Убейте предателя!,,Vakter! Döda förrädaren!,Muhafızlar! Haini öldürün! "Hey, I know what you're thinking, kinda looks like a setup, I would never do that to such a killing machine, I mean it. Whew, all this fuss over a cup, weird. Now get ready, gold and glory, like I promised. Take this key and the Governor himself will reward you.",TXT_DLG_SCRIPT33_D22740_HEYIK,〃,,,"Hej, vím co si myslíš, tohle vypadá jako bouda. Takovému stroji na zabíjení bych nic takového neudělal, vážně! Páni, takový povyk kvůli hrnečku, divný. Tak teď se připrav, zlato a sláva, jak jsem slíbil. Vem si tenhle klíč a sám guvernér tě odmění.","Hey, jeg ved hvad du tænker, det ligner en fælde, jeg ville aldrig gøre det mod sådan en dræbermaskine, jeg mener det. Alt dette postyr over en kop, underligt. Gør dig klar, guld og ære, som jeg lovede. Tag denne nøgle, og guvernøren selv vil belønne dig.","Hey, ich weiß, es sieht anscheinend wie eine Falle aus, aber so etwas würde ich einer so großeartigen Tötungsmaschine nicht antun. Hast du ddas Ding? Großartig! Nun mach dich bereit, Geld und Ruhm, genau wie ich es dir versprochen habe. Nimm diesen Schlüssel und der Gouverneur wird dich belohnen.",,,"Hey, sé lo que estás pensando, parece un timo, pero nunca haría algo así a tal máquina de matar, lo juro. Uf, todo este lío por una copa, que raro. Ahora prepárate, oro y gloria, tal y como prometí. Toma esta llave y el mismísimo gobernador te recompensará.",,"Joo joo, tiedän, mitä ajattelet: vähän tuntuu väijytykseltä. En kuitenkaan ikinä tekisi sellaista niin kovalle tappokoneelle. Tarkoitan sitä. Huhhuh, kaikki tämä vouhotus yhdestä kupista; kummallista. No niin, valmistaudu kultaan ja kunniaan, niin kuin lupasinkin. Ota tämä avain ja itse kuvernööri palkitsee sinut.","Hé, je sais que ça à l'air d'être un coup monté, mais je ne ferais jamais ça à une aussi bonne machine à tuer. Tellement de bruit pour une coupe, franchement.. Préparez vous, l'or et la gloire vous attend, comme promis. Prenez cette clé et le gouverneur vous récompensera.","Tudom mire gondolsz, olyan ez mintha egy csapda lenne, de esküszöm soha nemm tennék ilyet egy jó gyilkológéppel. Nahát, ennyi hűhó egy francos serleg miatt. Node, állj aztán készen, eljön az a bizonyos pénz és hírnév mint ahogy ígértem. Tedd el ezt a kulcsot, és maga a kormányzó fog megjutalmazni.","Ehi, so che può sembrare una trappola. Ma io non tradirei mai a un killer abile come te. Mah, tutto questo per una coppa, che strano. Adesso preparati, oro e gloria, come ti avevo promesso. Prendi questa chiave e il governatore in persona ti ricompenserà.","よう。アンタが何を考えてるかわかるぜ、 まるで罠だと。 俺には暴れん坊みたいな芸当出来ねえしな。 おう、カップを巡って大騒ぎだろうなこりゃ、 怖い怖い。 だったら準備しな、金と名誉は、約束通り。 -この鍵を取ったら知事が報酬を与えるだろうな。","이봐, 무슨 생각을 하는지 알겠어. 확실히 뭔가 꾸며 놓은 것 같다는 거. 난 훌륭한 학살 기계에게 그런 짓을 할 사람이 아니야. 휴... 그깟 컵 가지고. 이상해. 아무튼 준비해, 골드와 영광을. 이 열쇠를 총독에게 가져다주면 보상해 줄 거야.","Hé, ik weet wat je denkt, het lijkt een beetje op een valstrik, dat zou ik nooit met zo'n moordmachine doen, ik meen het. Whew, al deze ophef over een kopje, vreemd. Maak je nu klaar, goud en glorie, zoals ik heb beloofd. Neem deze sleutel en de Gouverneur zelf zal je belonen.","Jeg vet hva du tenker. Det ser ut som en felle. Jeg ville aldri gjort det mot en slik drapsmaskin. Alt dette oppstyret for en kopp. Merkelig. Gjør deg klar, gull og ære, som jeg lovet. Ta denne nøkkelen, så vil guvernøren selv belønne deg.","Hej, wiem co myślisz, wygląda to na ustawkę, nigdy nie zrobiłbym tego takiej maszynie do zabijania, mówię poważnie. Całe to zamieszanie z powodu kubka, dziwne. A teraz przygotuj się, złoto i chwała, jak obiecałem. Weź ten klucz, a sam gubernator cię nagrodzi.","Olha, eu sei o que você está pensando, que parece uma cilada. Eu nunca faria isso com uma máquina mortífera como você, sério mesmo. Nossa, todo esse escândalo por causa de um cálice, que esquisito. Agora se prepare, ouro e glória conforme prometido. Pegue esta chave e o governador vai te recompensar.",,"Hei, știu la ce te gândești, pare o capcană, dar nu aș face asta niciodată unei mașini ucigașe, serios. Atâta harababură pentru un potir, . Acum pregătește-te, aur și glorie, dupa cum ți-am promis. Ia cheia asta și însuși Guvernatorul te va răsplătii.","Слушай, я знаю, о чём ты думаешь. Ты думаешь, что это подстава. Но я бы никогда не сделал этого с такой машиной для убийств, как ты, правда-правда. Тем более, ради какой-то чаши. А теперь, тебя ждут золото и слава, как я и обещал. Возьми этот ключ, губернатор лично наградит тебя.",,"Hey, ne düşündüğünü biliyorum, biraz tuzak gibi görünüyor, böyle bir ölüm makinesine bunu asla yapmam, ciddiyim. Tüm bu yaygara bir fincan için, garip. Şimdi hazır ol, altın ve şan, söz verdiğim gibi. Bu anahtarı al ve Vali'nin kendisi seni ödüllendirecek." -"Great, I can't wait!",TXT_RPLY0_SCRIPT33_D22740_GREAT,〃,,,"Skvělý, nemůžu se dočkat!","Fedt, jeg kan ikke vente!","Toll, ich kann es kaum erwarten!",,,"Genial, ¡no puedo esperar!",,"Mahtavaa, en malta odottaa!","Parfait, je ne peux pas attendre!","Remek, már alig várom!","Ottimo, non vedo l'ora!",そりゃいいな、待ち遠しい!,좋았어! 기다릴 수 없는걸?,"Geweldig, ik kan niet wachten!","Flott, jeg gleder meg!","Świetnie, nie mogę się doczekać!","Ótimo, mal posso esperar!",,"Grozav, abia aștept.",Прекрасно. Мне уже не терпится!,,"Harika, sabırsızlanıyorum!" -"No chalice, no money!",TXT_RNO0_SCRIPT33_D22740_NOCHA,〃,,,"Žádný kalich, žádný prachy!","Ingen bæger, ingen penge!","Kein Kelch, kein Geld.",,,¡Sin cáliz no hay dinero!,,"Ei kalkkia, ei rahaa!","Pas de calice, pas d'argent!","Ha nincs serleg, nincs pénz!","Niente calice, niente soldi!",聖杯が無いなら、金も無しだ!,성배가 없다면 돈도 없어!,"Geen kelk, geen geld!","Ingen kalk, ingen penger!","Nie ma kielicha, nie ma pieniędzy!","Sem cálice, sem dinheiro!",,"Niciun potir, niciun ban!",Нет чаши — нет денег!,,Kadeh yoksa para da yok! -"I'll keep the chalice, thanks.",TXT_RPLY1_SCRIPT33_D22740_ILLKE,〃,,,"Nechám si ten kalich, díky.","Jeg beholder bægeret, tak.","Ich behalte den Kelch, danke.",,,Me quedaré el cáliz. Gracias.,,"Pidän kalkin, kiitos.","Je le garde, merci.","Inkább megtartom a serleget, kösz.","Il calice lo terrò io, grazie.",聖杯は頂く、じゃあな。,"내가 성배를 가지고 있을게, 고마워.","Ik bewaar de kelk, bedankt.","Jeg beholder begeret, takk.","Zatrzymam kielich, dzięki.","Vou ficar com o cálice, obrigado.",,"Păstrez potirul, merci.","Спасибо, но я оставлю чашу себе.",,"Kadeh bende kalsın, teşekkürler." -Keep it? I think not!,TXT_RYES1_SCRIPT33_D22740_KEEPI,〃,,,Necháš? Nemyslím si!,Beholde den? Det tror jeg ikke!,"Behalten? Ich glaube, nicht.",,,¿Quedártelo? ¡Me parece que no!,,Pidät sen? Enpä usko!,Le garder? Je ne pense pas!,Megtartod? Nem hinném öreg!,Davvero intendi tenerlo tu? Mi spiace ma non funziona così!,頂く? 有り得ねえな!,가지고 있겠다고? 내 생각은 아닌데?,Bewaren? Ik denk van niet!,Beholde det? Jeg tror ikke det!,Zatrzymać? Chyba nie!,Ficar com o cálice? Acho que não!,,Păstrezi? Ba nu cred!,Оставишь себе? Ещё чего!,,Saklamak mı? Hiç sanmıyorum! -What are you waiting for? The governor himself will reward you.,TXT_DLG_SCRIPT33_D24256_WHATA,〃,,,Na co čekáš? Sám guvernér tě odmění.,Hvad venter du på? Guvernøren selv vil belønne dig.,Worauf wartest du? Der Gouverneur wird dich belohnen.,,,¿Qué estás esperando? El mismísimo gobernador te recompensará.,,Mitä oikein odotat? Kuvernööri itse palkitsee sinut.,Qu'attendez-vous? Le gouverneur vous récompensera lui même.,Mire vársz? Maga a kormányzó fog megjutalmazni.,Che cosa stai aspettando? Il governatore in persona ti ricompenserà.,何突っ立ってんだ? 知事に報酬を受けて来いよ。,꾸물거리지 말고 총독을 만나. 그가 너를 보답해줄 거야.,Waar wacht je nog op? De gouverneur zelf zal je belonen.,Hva venter du på? Guvernøren selv vil belønne deg.,Na co czekasz? Sam gubernator cię nagrodzi.,O que você está esperando? O governador em pessoa vai te recompensar.,,Ce mai aștepți? Guvernatorul însuși te va răsplătii.,Чего ты ждёшь? Губернатор лично наградит тебя.,,Neyi bekliyorsun? Valinin kendisi seni ödüllendirecek. -Die traitor! ,TXT_DLG_SCRIPT33_D25772_DIETR,,,,"Zemři, zrádče!","Dø, forræder!","Stirb, Verräter!",,,"¡Muere, traidor!",,"Kuole, petturi!","Meurs, traître!",Halál rád áruló!,Muori traditore!,くたばれ裏切者が!,죽어라. 배신자!,Sterf de verrader!,"Dø, forræder!",Giń zdrajco!,"Morra, traidor!",,Mori trădătorule!,"Умри, предатель!",,Geber hain! +この鍵を取ったら知事が報酬を与えるだろうな。","이봐, 무슨 생각을 하는지 알겠어. 확실히 뭔가 꾸며 놓은 것 같다는 거. 난 훌륭한 학살 기계에게 그런 짓을 할 사람이 아니야. 휴... 그깟 컵 가지고. 이상해. 아무튼 준비해, 골드와 영광을. 이 열쇠를 총독에게 가져다주면 보상해 줄 거야.","Hé, ik weet wat je denkt, het lijkt een beetje op een valstrik, dat zou ik nooit met zo'n moordmachine doen, ik meen het. Whew, al deze ophef over een kopje, vreemd. Maak je nu klaar, goud en glorie, zoals ik heb beloofd. Neem deze sleutel en de Gouverneur zelf zal je belonen.","Jeg vet hva du tenker. Det ser ut som en felle. Jeg ville aldri gjort det mot en slik drapsmaskin. Alt dette oppstyret for en kopp. Merkelig. Gjør deg klar, gull og ære, som jeg lovet. Ta denne nøkkelen, så vil guvernøren selv belønne deg.","Hej, wiem co myślisz, wygląda to na ustawkę, nigdy nie zrobiłbym tego takiej maszynie do zabijania, mówię poważnie. Całe to zamieszanie z powodu kubka, dziwne. A teraz przygotuj się, złoto i chwała, jak obiecałem. Weź ten klucz, a sam gubernator cię nagrodzi.","Olha, eu sei o que você está pensando, que parece uma cilada. Eu nunca faria isso com uma máquina mortífera como você, sério mesmo. Nossa, todo esse escândalo por causa de um cálice, que esquisito. Agora se prepare, ouro e glória conforme prometido. Pegue esta chave e o governador vai te recompensar.",,"Hei, știu la ce te gândești, pare o capcană, dar nu aș face asta niciodată unei mașini ucigașe, serios. Atâta harababură pentru un potir, . Acum pregătește-te, aur și glorie, dupa cum ți-am promis. Ia cheia asta și însuși Guvernatorul te va răsplătii.","Слушай, я знаю, о чём ты думаешь. Ты думаешь, что это подстава. Но я бы никогда не сделал этого с такой машиной для убийств, как ты, правда-правда. Тем более, ради какой-то чаши. А теперь, тебя ждут золото и слава, как я и обещал. Возьми этот ключ, губернатор лично наградит тебя.",,"Jag vet vad du tänker, det ser ut som en fälla, jag skulle aldrig göra det mot en sådan dödsmaskin, jag menar det. Allt detta ståhej för en kopp, konstigt. Gör dig nu redo, guld och ära, som jag lovade. Ta den här nyckeln och guvernören själv kommer att belöna dig.","Hey, ne düşündüğünü biliyorum, biraz tuzak gibi görünüyor, böyle bir ölüm makinesine bunu asla yapmam, ciddiyim. Tüm bu yaygara bir fincan için, garip. Şimdi hazır ol, altın ve şan, söz verdiğim gibi. Bu anahtarı al ve Vali'nin kendisi seni ödüllendirecek." +"Great, I can't wait!",TXT_RPLY0_SCRIPT33_D22740_GREAT,〃,,,"Skvělý, nemůžu se dočkat!","Fedt, jeg kan ikke vente!","Toll, ich kann es kaum erwarten!",,,"Genial, ¡no puedo esperar!",,"Mahtavaa, en malta odottaa!","Parfait, je ne peux pas attendre!","Remek, már alig várom!","Ottimo, non vedo l'ora!",そりゃいいな、待ち遠しい!,좋았어! 기다릴 수 없는걸?,"Geweldig, ik kan niet wachten!","Flott, jeg gleder meg!","Świetnie, nie mogę się doczekać!","Ótimo, mal posso esperar!",,"Grozav, abia aștept.",Прекрасно. Мне уже не терпится!,,"Toppen, jag kan inte vänta!","Harika, sabırsızlanıyorum!" +"No chalice, no money!",TXT_RNO0_SCRIPT33_D22740_NOCHA,〃,,,"Žádný kalich, žádný prachy!","Ingen bæger, ingen penge!","Kein Kelch, kein Geld.",,,¡Sin cáliz no hay dinero!,,"Ei kalkkia, ei rahaa!","Pas de calice, pas d'argent!","Ha nincs serleg, nincs pénz!","Niente calice, niente soldi!",聖杯が無いなら、金も無しだ!,성배가 없다면 돈도 없어!,"Geen kelk, geen geld!","Ingen kalk, ingen penger!","Nie ma kielicha, nie ma pieniędzy!","Sem cálice, sem dinheiro!",,"Niciun potir, niciun ban!",Нет чаши — нет денег!,,"Ingen bägare, inga pengar!",Kadeh yoksa para da yok! +"I'll keep the chalice, thanks.",TXT_RPLY1_SCRIPT33_D22740_ILLKE,〃,,,"Nechám si ten kalich, díky.","Jeg beholder bægeret, tak.","Ich behalte den Kelch, danke.",,,Me quedaré el cáliz. Gracias.,,"Pidän kalkin, kiitos.","Je le garde, merci.","Inkább megtartom a serleget, kösz.","Il calice lo terrò io, grazie.",聖杯は頂く、じゃあな。,"내가 성배를 가지고 있을게, 고마워.","Ik bewaar de kelk, bedankt.","Jeg beholder begeret, takk.","Zatrzymam kielich, dzięki.","Vou ficar com o cálice, obrigado.",,"Păstrez potirul, merci.","Спасибо, но я оставлю чашу себе.",,"Jag behåller bägaren, tack.","Kadeh bende kalsın, teşekkürler." +Keep it? I think not!,TXT_RYES1_SCRIPT33_D22740_KEEPI,〃,,,Necháš? Nemyslím si!,Beholde den? Det tror jeg ikke!,"Behalten? Ich glaube, nicht.",,,¿Quedártelo? ¡Me parece que no!,,Pidät sen? Enpä usko!,Le garder? Je ne pense pas!,Megtartod? Nem hinném öreg!,Davvero intendi tenerlo tu? Mi spiace ma non funziona così!,頂く? 有り得ねえな!,가지고 있겠다고? 내 생각은 아닌데?,Bewaren? Ik denk van niet!,Beholde det? Jeg tror ikke det!,Zatrzymać? Chyba nie!,Ficar com o cálice? Acho que não!,,Păstrezi? Ba nu cred!,Оставишь себе? Ещё чего!,,Behålla den? Jag tror inte det!,Saklamak mı? Hiç sanmıyorum! +What are you waiting for? The governor himself will reward you.,TXT_DLG_SCRIPT33_D24256_WHATA,〃,,,Na co čekáš? Sám guvernér tě odmění.,Hvad venter du på? Guvernøren selv vil belønne dig.,Worauf wartest du? Der Gouverneur wird dich belohnen.,,,¿Qué estás esperando? El mismísimo gobernador te recompensará.,,Mitä oikein odotat? Kuvernööri itse palkitsee sinut.,Qu'attendez-vous? Le gouverneur vous récompensera lui même.,Mire vársz? Maga a kormányzó fog megjutalmazni.,Che cosa stai aspettando? Il governatore in persona ti ricompenserà.,何突っ立ってんだ? 知事に報酬を受けて来いよ。,꾸물거리지 말고 총독을 만나. 그가 너를 보답해줄 거야.,Waar wacht je nog op? De gouverneur zelf zal je belonen.,Hva venter du på? Guvernøren selv vil belønne deg.,Na co czekasz? Sam gubernator cię nagrodzi.,O que você está esperando? O governador em pessoa vai te recompensar.,,Ce mai aștepți? Guvernatorul însuși te va răsplătii.,Чего ты ждёшь? Губернатор лично наградит тебя.,,Vad väntar du på? Guvernören själv kommer att belöna dig.,Neyi bekliyorsun? Valinin kendisi seni ödüllendirecek. +Die traitor! ,TXT_DLG_SCRIPT33_D25772_DIETR,,,,"Zemři, zrádče!","Dø, forræder!","Stirb, Verräter!",,,"¡Muere, traidor!",,"Kuole, petturi!","Meurs, traître!",Halál rád áruló!,Muori traditore!,くたばれ裏切者が!,죽어라. 배신자!,Sterf de verrader!,"Dø, forræder!",Giń zdrajco!,"Morra, traidor!",,Mori trădătorule!,"Умри, предатель!",,Dö förrädare!,Geber hain! So you're the fool who stole the chalice? I'm going to have you arrested as a rebel thief... Thereby enhancing my position with the Order. How does it feel to be an unwitting pawn? ,TXT_DLG_SCRIPT33_D27288_SOYOU,,,,"Tak ty jsi ten blázen, který ukradl kalich? Teď tě nechám zatknout jako rebelského zloděj... a tím si upevním svou pozici s Řádem. Jaký je to pocit, být bezděčnou figurkou?","Så du er det fjols, der stjal bægeret? Jeg vil få dig arresteret som en oprørsk tyv... og derved forbedre min position i ordenen. Hvordan føles det at være en uvidende brik?","So, du bist also der Narr der den Kelch gestohlen hat? Ich werde dich als Dieb der Rebellen verhaften lassen und dadurch meine Position im Orden verbessern. Wie fühlt es sich an als ahnungslose Schachfigur?",,,¿Así que tú eres el necio que robó el cáliz? Voy a arrestarte como ladrón rebelde... Mejorando así mí posición con la Orden. ¿Cómo se siente ser un inconsciente peón?,,"Vai sinä olet se houkka, joka varasti kalkin? Pidätytän sinut kapinallisvarkaana, siten parantaen asemaani Veljeskunnassa. Miltäpä tuntuu olla tahaton pelinappula?","Vous êtes l'abruti qui a volé le calice? Maintenant il faut que je vous arrète comme voleur rebelle.. Ca va aider ma position dans l'Ordre. Comment ça fait d'être un pion ignorant? Petite idée, ça va faire mal.",Szóval te vagy az isten barma aki ellopta a kelyhet? Jól letartóztatlak mint lázadó tolvaj...ezzel megerősítve a pozíciómat a Rendben. Milyen érzés egy tudatlan parasztnak lenni?,Quindi sei tu il folle che ha rubato il calice? Ti farò arrestare come un ladro ribelle... E così facendo salirò nei ranghi dell'Ordine. Come ci si sente ad essere un'inconsapevole pedina?,"それで、お前が聖杯を盗んだ愚か者か? 私は反賊としてお前を逮捕するつもりだ... そうすればオーダーでの地位が上がる。 無意味な駒だと思うか? -",그래서 네가 그 성배를 훔친 바보로군? 반군 절도범으로 체포해주지... 오더에서의 내 위치도 올리는 겸. 모르는 사이에 장물아비가 된 기분이 어떤가?,Dus jij bent de dwaas die de kelk heeft gestolen? Ik ga je laten arresteren als rebelse dief.... Daardoor verbeter ik mijn positie bij de Orde. Hoe voelt het om een onwetende pion te zijn?,Så du er tosken som stjal begeret? Jeg skal få deg arrestert som en opprørsk tyv... Og dermed styrke min posisjon i Ordenen. Hvordan føles det å være en uvitende brikke?,"Więc to ty jesteś tym głupcem, który ukradł kielich? Każę cię aresztować jako buntowniczego złodzieja... Tym samym wzmocnię swoją pozycję w Zakonie. Jakie to uczucie być nieświadomym pionkiem?",Então você é o idiota que roubou o cálice? Eu vou prender você por ser um ladrão rebelde... E assim vou melhorar minha posição com a Ordem. Como se sente sendo um plebeu ignorante?,,Deci tu ești tolomacul care a furat potirul? Am să te arestez drept un hoț rebel... Prin urmare crescând in rangurile Ordinului. Cum e să fii un pion?,"Так это ты тот недоумок, что украл чашу? Я передам тебя Ордену, как вора повстанцев... Это укрепит мои отношения с ним. Каково чувствовать себя безмозглой пешкой?",,Demek kadehi çalan aptal sensin? Seni asi bir hırsız olarak tutuklatacağım. Böylece Tarikat'taki konumumu güçlendireceğim. Farkında olmadan bir piyon olmak nasıl bir duygu? -It sucks!,TXT_RPLY0_SCRIPT33_D27288_ITSUC,,,,Je to na hovno!,Det stinker!,Scheiße!,,Ĝi aĉas!,¡Apesta!,,Ihan perseestä!,Quelle merde!,Ez szopás!,È uno schifo!,クソが!,기분이 아주 좆같아.,Het is klote!,Det suger!,Do dupy!,É uma merda!,,Nașpa!,Чтоб ты сдох!,,Berbat! -For you it does.,TXT_RYES0_SCRIPT33_D27288_FORYO,,,,Pro tebe určitě.,For dig gør det.,Du steckst ganz tief drin.,,,"Para ti, sí.",,"Kyllä, sinun tilanteesi.","Pour vous, en effet.",...és a bráner rossz végén vagy.,Ti faccio vedere io!,私もそう思う。,더한 기분이 들게 해주지.,Voor jou wel.,For deg gjør det det.,Dla ciebie tak.,"Pra você, é mesmo.",,"Pentru tine, într-adevăr este.",Скоро сдохнешь ты.,,Senin için öyle. -Harris promised me money!,TXT_RPLY1_SCRIPT33_D27288_HARRI,,,,Harris mi slíbil peníze!,Harris lovede mig penge!,Harris hat mir Geld versprochen!,,,¡Harris me prometió dinero!,,Harris lupasi minulle rahaa!,Harris m'a promis de l'argent!,Harris pénzt ígért nekem.,Harris mi ha promesso dei soldi!,ハリスは俺に金を渡すと約束したのに!,해리스가 날 배신했어... 이 새끼!,Harris beloofde me geld!,Harris lovet meg penger!,Harris obiecał mi pieniądze!,O Harris prometeu me pagar!,,Harris mi-a promis bani!,Харрис обещал мне деньги!,,Harris bana para sözü verdi! -Too bad. The only thing you're getting is death!,TXT_RYES1_SCRIPT33_D27288_TOOBA,,,,"Smůla. Jediné, co dostaneš, je smrt!","Det var ærgerligt. Det eneste, du får, er døden!",Jammerschade. Das Einzige was du bekommen wirst ist der Tod!,,,Una pena. ¡Lo único que tendrás es la muerte!,,"Voi voi. Sen kyllä voin sinulle luvata, että kuolet!","Dommage. Tout ce que vous allez recevoir, c'est votre mort!","Így jártál. Az egyetlen dolog amit kapsz, az a halál.",Peccato. L'unica cosa che otterrai è la morte.,残念だな、お前にやれるものは死のみだ!,안됐네. 넌 여기서 죽게 될테니까!,Jammer. Het enige wat je krijgt is de dood!,"Synd for deg. Det eneste du får, er døden!",Szkoda. Jedyne co dostaniesz to śmierć!,Que pena. A única coisa que você vai receber é a morte!,,Păcat. Tot ce vei primi e moarte!,"Увы. Всё, что ты получишь, — это смерть!",,Çok yazık. Alacağın tek şey ölüm! -We're going to kill you!,TXT_DLG_SCRIPT33_D28804_WEREG,,,,Zabijeme tě!,Vi slår dig ihjel!,Wir werden euch töten!,,,¡Vamos a matarte!,,Tapamme sinut!,On va te buter!,Megölünk!,Adesso ti ammazziamo!,お前をぶっ殺す!,우린 널 죽일 거야!,We gaan je vermoorden!,Vi skal drepe deg!,Zabijemy cię!,Nós vamos te matar!,,Te vom omorâ!,Готовься к смерти!,,Seni öldüreceğiz! -Get out of here!,TXT_DLG_SCRIPT33_D30320_GETOU,,,,Vypadni odsud!,Forsvind herfra!,Verschwinde von hier!,,,¡Sal de aquí!,,Häivy täältä!,Sortez de là!,Pusztulj innen!,Fuori di qui!,ここから立ち去れ!,여길 나가!,Maak dat je hier wegkomt!,Forsvinn herfra!,Wynoś się stąd!,Saia daqui!,,Valea!,Убирайся отсюда!,,Defolun buradan! -We're going to kill you!,TXT_DLG_SCRIPT33_D31836_WEREG,,,,Zabijeme tě!,Vi slår dig ihjel!,Wir werden euch töten!,,,¡Vamos a matarte!,,Tapamme sinut!,On va te buter!,Megölünk!,Adesso ti ammazziamo!,お前をぶっ殺す!,널 죽이는걸 즐길테다.,We gaan je vermoorden!,Vi skal drepe deg!,Zabijemy cię!,Nós vamos te matar!,,Te vom omorâ!,Готовься к смерти!,,Seni öldüreceğiz! -Get out of here!,TXT_DLG_SCRIPT33_D33352_GETOU,,,,Vypadni odsud!,Kom ud herfra!,Verschwinde von hier!,,,¡Sal de aquí!,,Häivy täältä!,Sortez de là!,Pusztulj innen!,Fuori di qui!,ここから立ち去れ!,여기서 뭐하는 거야? 꺼져!,Maak dat je wegkomt!,Forsvinn herfra!,Wynoś się stąd!,Saia daqui!,,Valea!,Убирайся отсюда!,,Defolun buradan! +",그래서 네가 그 성배를 훔친 바보로군? 반군 절도범으로 체포해주지... 오더에서의 내 위치도 올리는 겸. 모르는 사이에 장물아비가 된 기분이 어떤가?,Dus jij bent de dwaas die de kelk heeft gestolen? Ik ga je laten arresteren als rebelse dief.... Daardoor verbeter ik mijn positie bij de Orde. Hoe voelt het om een onwetende pion te zijn?,Så du er tosken som stjal begeret? Jeg skal få deg arrestert som en opprørsk tyv... Og dermed styrke min posisjon i Ordenen. Hvordan føles det å være en uvitende brikke?,"Więc to ty jesteś tym głupcem, który ukradł kielich? Każę cię aresztować jako buntowniczego złodzieja... Tym samym wzmocnię swoją pozycję w Zakonie. Jakie to uczucie być nieświadomym pionkiem?",Então você é o idiota que roubou o cálice? Eu vou prender você por ser um ladrão rebelde... E assim vou melhorar minha posição com a Ordem. Como se sente sendo um plebeu ignorante?,,Deci tu ești tolomacul care a furat potirul? Am să te arestez drept un hoț rebel... Prin urmare crescând in rangurile Ordinului. Cum e să fii un pion?,"Так это ты тот недоумок, что украл чашу? Я передам тебя Ордену, как вора повстанцев... Это укрепит мои отношения с ним. Каково чувствовать себя безмозглой пешкой?",,Så du är dåren som stal kalken? Jag kommer att låta arrestera dig som en upprorisk tjuv... och därmed förbättra min ställning i orden. Hur känns det att vara en ovetande bricka?,Demek kadehi çalan aptal sensin? Seni asi bir hırsız olarak tutuklatacağım. Böylece Tarikat'taki konumumu güçlendireceğim. Farkında olmadan bir piyon olmak nasıl bir duygu? +It sucks!,TXT_RPLY0_SCRIPT33_D27288_ITSUC,,,,Je to na hovno!,Det stinker!,Scheiße!,,Ĝi aĉas!,¡Apesta!,,Ihan perseestä!,Quelle merde!,Ez szopás!,È uno schifo!,クソが!,기분이 아주 좆같아.,Het is klote!,Det suger!,Do dupy!,É uma merda!,,Nașpa!,Чтоб ты сдох!,,Det suger!,Berbat! +For you it does.,TXT_RYES0_SCRIPT33_D27288_FORYO,,,,Pro tebe určitě.,For dig gør det.,Du steckst ganz tief drin.,,,"Para ti, sí.",,"Kyllä, sinun tilanteesi.","Pour vous, en effet.",...és a bráner rossz végén vagy.,Ti faccio vedere io!,私もそう思う。,더한 기분이 들게 해주지.,Voor jou wel.,For deg gjør det det.,Dla ciebie tak.,"Pra você, é mesmo.",,"Pentru tine, într-adevăr este.",Скоро сдохнешь ты.,,För dig gör det det.,Senin için öyle. +Harris promised me money!,TXT_RPLY1_SCRIPT33_D27288_HARRI,,,,Harris mi slíbil peníze!,Harris lovede mig penge!,Harris hat mir Geld versprochen!,,,¡Harris me prometió dinero!,,Harris lupasi minulle rahaa!,Harris m'a promis de l'argent!,Harris pénzt ígért nekem.,Harris mi ha promesso dei soldi!,ハリスは俺に金を渡すと約束したのに!,해리스가 날 배신했어... 이 새끼!,Harris beloofde me geld!,Harris lovet meg penger!,Harris obiecał mi pieniądze!,O Harris prometeu me pagar!,,Harris mi-a promis bani!,Харрис обещал мне деньги!,,Harris lovade mig pengar!,Harris bana para sözü verdi! +Too bad. The only thing you're getting is death!,TXT_RYES1_SCRIPT33_D27288_TOOBA,,,,"Smůla. Jediné, co dostaneš, je smrt!","Det var ærgerligt. Det eneste, du får, er døden!",Jammerschade. Das Einzige was du bekommen wirst ist der Tod!,,,Una pena. ¡Lo único que tendrás es la muerte!,,"Voi voi. Sen kyllä voin sinulle luvata, että kuolet!","Dommage. Tout ce que vous allez recevoir, c'est votre mort!","Így jártál. Az egyetlen dolog amit kapsz, az a halál.",Peccato. L'unica cosa che otterrai è la morte.,残念だな、お前にやれるものは死のみだ!,안됐네. 넌 여기서 죽게 될테니까!,Jammer. Het enige wat je krijgt is de dood!,"Synd for deg. Det eneste du får, er døden!",Szkoda. Jedyne co dostaniesz to śmierć!,Que pena. A única coisa que você vai receber é a morte!,,Păcat. Tot ce vei primi e moarte!,"Увы. Всё, что ты получишь, — это смерть!",,Det var synd. Det enda du får är döden!,Çok yazık. Alacağın tek şey ölüm! +We're going to kill you!,TXT_DLG_SCRIPT33_D28804_WEREG,,,,Zabijeme tě!,Vi slår dig ihjel!,Wir werden euch töten!,,,¡Vamos a matarte!,,Tapamme sinut!,On va te buter!,Megölünk!,Adesso ti ammazziamo!,お前をぶっ殺す!,우린 널 죽일 거야!,We gaan je vermoorden!,Vi skal drepe deg!,Zabijemy cię!,Nós vamos te matar!,,Te vom omorâ!,Готовься к смерти!,,Vi ska döda dig!,Seni öldüreceğiz! +Get out of here!,TXT_DLG_SCRIPT33_D30320_GETOU,,,,Vypadni odsud!,Forsvind herfra!,Verschwinde von hier!,,,¡Sal de aquí!,,Häivy täältä!,Sortez de là!,Pusztulj innen!,Fuori di qui!,ここから立ち去れ!,여길 나가!,Maak dat je hier wegkomt!,Forsvinn herfra!,Wynoś się stąd!,Saia daqui!,,Valea!,Убирайся отсюда!,,Stick härifrån!,Defolun buradan! +We're going to kill you!,TXT_DLG_SCRIPT33_D31836_WEREG,,,,Zabijeme tě!,Vi slår dig ihjel!,Wir werden euch töten!,,,¡Vamos a matarte!,,Tapamme sinut!,On va te buter!,Megölünk!,Adesso ti ammazziamo!,お前をぶっ殺す!,널 죽이는걸 즐길테다.,We gaan je vermoorden!,Vi skal drepe deg!,Zabijemy cię!,Nós vamos te matar!,,Te vom omorâ!,Готовься к смерти!,,Vi ska döda dig!,Seni öldüreceğiz! +Get out of here!,TXT_DLG_SCRIPT33_D33352_GETOU,,,,Vypadni odsud!,Kom ud herfra!,Verschwinde von hier!,,,¡Sal de aquí!,,Häivy täältä!,Sortez de là!,Pusztulj innen!,Fuori di qui!,ここから立ち去れ!,여기서 뭐하는 거야? 꺼져!,Maak dat je wegkomt!,Forsvinn herfra!,Wynoś się stąd!,Saia daqui!,,Valea!,Убирайся отсюда!,,Stick härifrån!,Defolun buradan! "What a perfect place for us, under the old town hall. The Order thinks they've wiped us out, but all it was is a reminder to us of what can happen when you become careless. ",TXT_DLG_SCRIPT34_D0_WHATA,MAP34: Barracks,,,"Tady pod starou radnicí to je pro nás ideální místo. Řád si myslí, že nás vyhladil, ale pouze nám připomněl, co se může stát, když jsi neopatrný.","Sikke et perfekt sted for os, under det gamle rådhus. Ordenen tror, at de har udryddet os, men det var blot en påmindelse til os om, hvad der kan ske, når man bliver uforsigtig.","Was für ein Perfekter Ort für uns, unter dem alten Rathaus. Der Orden glaubt, er hätte uns vernichtet, aber es war nur ein Denkzettel für uns, was passieren kann wenn man unaufmerksam ist.",,,"Que lugar tan perfecto para nosotros, bajo el antiguo ayuntamiento. La Orden cree que nos ha aniquilado, pero todo lo que ha sido es un recordatorio para nosotros de lo que puede pasar cuando te descuidas.",,"Tämähän on täydellinen paikka meille, vanhan kaupungintalon alla. Veljeskunta luulee hävittäneensä meidät, mutta se toimi meille ainoastaan muistutuksena siitä, mitä voi tapahtua, kun tulee varomattomaksi.","Quel endroit parafait pour nous, sous la mairie. L'Ordre pense qu'ils nous ont tous tués, mais ça leur servira de leçon, ils verront se qu'il se passe quand on ne fait pas attention..","A városháza alatt, micsoda tökéletes hely. A Rend azt hiszi kiírtott mindőnket, de ez csak egy emlékeztető volt arra, hogy mi történik ha felelőtlenek vagyunk.","È davvero un posto perfetto per noi, sotto il vecchio municipio. L'Ordine pensa di averci spazzato via, ma è stato solo un avvertimento di cosa può succederci se siamo troppo incauti.","旧市庁舎の下で、 私たちにとって何という完璧な場所です。 秩序は彼らが私たちを消滅させたと考 えていますが、それがすべてだったのは あなたが不注意になったときに起こり得ることを -私たちに思い出させるものです。","정말 경치 좋지? 이 박살 난 시청 주변에서. 오더 놈들이 우리들을 전멸했다고 자랑하는데, 우리들이 힘을 모아서 복수하기 전까진 그렇게 놓아두는 게 좋을 것 같아.","Wat een perfecte plek voor ons, onder het oude stadhuis. De Orde denkt dat ze ons hebben weggevaagd, maar het enige wat ons eraan herinnert is wat er kan gebeuren als je onzorgvuldig wordt.","For et perfekt sted for oss, under det gamle rådhuset. Ordenen tror de har utslettet oss, men det var bare en påminnelse om hva som kan skje når man er uforsiktig.","Co za idealne miejsce dla nas, pod starym ratuszem. Zakon myśli, że nas wymazał, ale to było tylko przypomnienie nam, co może się stać, gdy staniesz się nieostrożny.","Que lugar perfeito para nós, abaixo da antiga prefeitura. A Ordem pensa que nos aniquilou, mas aquilo tudo foi para lembrarmos do que pode acontecer quando você não é cauteloso.",,"Ce loc perfect pentru noi, exact sub vechea hală a orașului. Oridnul crede că ne-a ras pe toți, dar a fost doar o amintire pentru ceea ce se poate întâmpla când devi neglijent.","Здесь, под городской ратушей, такое чудесное место для нашей базы! Орден думает, что мы разгромлены, но мы всего лишь усвоили урок о цене беспечности.",,"Bizim için ne mükemmel bir yer, eski belediye binasının altı. Tarikat bizi yok ettiklerini sanıyor ama bu bize dikkatsiz davrandığımızda neler olabileceğini hatırlattı." -"Talk to Macil, he'll be able to help you.",TXT_DLG_SCRIPT34_D1516_TALKT,MAP34,,,Promluv si s Macilem. On ti pomůže.,"Tal med Macil, han vil kunne hjælpe dig.",Rede mit Macil. Er kann dir helfen.,,,"Habla con Macil, él podrá ayudarte.",,Puhu Macilille. Hän pystyy auttamaan sinua.,Parlez à Macil. Il pourra vous aider.,"Beszélj Macillal, majd ő segít.","Parla con Macil, lui sarà in grado di aiutarti.",マシルと話すんだ。彼から援助が得られるはず。,"마실 사령관님에게 말해, 그가 널 도울 수 있을 거야.","Praat met Macil, hij zal je kunnen helpen.",Snakk med Macil. Han kan hjelpe deg.,"Porozmawiaj z Macil, on będzie w stanie ci pomóc.",Fale com o Macil. Ele vai poder te ajudar.,,"Vorbește cu Macil, el te poate ajuta.",Обратись к Мэйсилу. Он поможет тебе.,,"Macil'le konuş, sana yardım edebilir." +私たちに思い出させるものです。","정말 경치 좋지? 이 박살 난 시청 주변에서. 오더 놈들이 우리들을 전멸했다고 자랑하는데, 우리들이 힘을 모아서 복수하기 전까진 그렇게 놓아두는 게 좋을 것 같아.","Wat een perfecte plek voor ons, onder het oude stadhuis. De Orde denkt dat ze ons hebben weggevaagd, maar het enige wat ons eraan herinnert is wat er kan gebeuren als je onzorgvuldig wordt.","For et perfekt sted for oss, under det gamle rådhuset. Ordenen tror de har utslettet oss, men det var bare en påminnelse om hva som kan skje når man er uforsiktig.","Co za idealne miejsce dla nas, pod starym ratuszem. Zakon myśli, że nas wymazał, ale to było tylko przypomnienie nam, co może się stać, gdy staniesz się nieostrożny.","Que lugar perfeito para nós, abaixo da antiga prefeitura. A Ordem pensa que nos aniquilou, mas aquilo tudo foi para lembrarmos do que pode acontecer quando você não é cauteloso.",,"Ce loc perfect pentru noi, exact sub vechea hală a orașului. Oridnul crede că ne-a ras pe toți, dar a fost doar o amintire pentru ceea ce se poate întâmpla când devi neglijent.","Здесь, под городской ратушей, такое чудесное место для нашей базы! Орден думает, что мы разгромлены, но мы всего лишь усвоили урок о цене беспечности.",,"Vilken perfekt plats för oss, under det gamla stadshuset. Orden tror att de har utplånat oss, men det var bara en påminnelse för oss om vad som kan hända när man blir oförsiktig.","Bizim için ne mükemmel bir yer, eski belediye binasının altı. Tarikat bizi yok ettiklerini sanıyor ama bu bize dikkatsiz davrandığımızda neler olabileceğini hatırlattı." +"Talk to Macil, he'll be able to help you.",TXT_DLG_SCRIPT34_D1516_TALKT,MAP34,,,Promluv si s Macilem. On ti pomůže.,"Tal med Macil, han vil kunne hjælpe dig.",Rede mit Macil. Er kann dir helfen.,,,"Habla con Macil, él podrá ayudarte.",,Puhu Macilille. Hän pystyy auttamaan sinua.,Parlez à Macil. Il pourra vous aider.,"Beszélj Macillal, majd ő segít.","Parla con Macil, lui sarà in grado di aiutarti.",マシルと話すんだ。彼から援助が得られるはず。,"마실 사령관님에게 말해, 그가 널 도울 수 있을 거야.","Praat met Macil, hij zal je kunnen helpen.",Snakk med Macil. Han kan hjelpe deg.,"Porozmawiaj z Macil, on będzie w stanie ci pomóc.",Fale com o Macil. Ele vai poder te ajudar.,,"Vorbește cu Macil, el te poate ajuta.",Обратись к Мэйсилу. Он поможет тебе.,,"Prata med Macil, han kommer att kunna hjälpa dig.","Macil'le konuş, sana yardım edebilir." I've heard that Macil's going to start something again soon. We need a big hit after the last fiasco. One more like that and we'll be too weak to continue.,TXT_DLG_SCRIPT34_D3032_IVEHE,MAP34: Barracks,,,"Slyšel jsem, že Macil má v plánu brzy něco znovu podniknout. Potřebujeme něco velkého po posledním fiasku. Ještě jednou něco takového a budeme příliš slabí pokračovat.","Jeg har hørt, at Macil snart vil starte noget igen. Vi har brug for et stort hit efter den sidste fiasko. En mere af den slags, og vi vil være for svage til at fortsætte.","Ich habe gehört, Macil hätte einen Plan um den Orden zu unterwandern. Ich hoffe mal, er taugt was. Noch ein Fehlschlag und wir können uns gleich begraben lassen.",,,He oído que Macil va a empezar algo nuevo pronto. Necesitamos un buen golpe después del último fiasco. Uno más como ese y seremos demasiado débiles para continuar.,,"Kuulin, että Macil alkaa taas viritellä jotain. Tarvitsemme jättionnistumisen edellisen fiaskon jälkeen. Vielä yksikin samanlainen, ja olemme liian heikkoja jatkamaan.",J'entends que Macil va essayer de faire quelque chose bientôt. Il nous faut frapper un grand coup après le dernier fiasco. Encore un comme celui-ci et on sera trop affaibli pour continuer.,"Az a hír járja, hogy Macil újra készül valamire. Kell egy nagy fogás a múltkori fiaskó után. Még egy ilyen, és túl gyengék leszünk a folytatáshoz.",Ho sentito che Macil ha intenzione di partire all'attacco molto presto. Abbiamo bisogno di un grosso colpo dopo l'ultimo disastro. Se subiamo un'altra sconfitta del genere saremo troppo deboli per continuare.,"私はマシルがオーダーを転覆させる計画を 持っていると聞いた。そうだと良かったが。 -我々は一度大敗し全滅しかけた。",마실 사령관이 또 다른 작전을 준비한데. 그전에 일어났던 대참사보다 훨씬 나은 작전이었으면 좋겠는데. 운이 나쁘면 많은 병력을 잃어버릴 것 같아.,Ik heb gehoord dat Macil binnenkort weer met iets gaat beginnen. We hebben een grote hit nodig na het laatste fiasco. Nog zo'n hit en dan zijn we te zwak om verder te gaan.,"Jeg har hørt at Macil skal starte noe igjen snart. Vi trenger en stor hit etter den siste fiaskoen. En til, så er vi for svake til å fortsette.","Słyszałem, że Macil ma zamiar wkrótce znowu coś zacząć. Potrzebujemy dużego uderzenia po ostatnim fiasku. Jeszcze jedno takie i będziemy zbyt słabi, by kontynuować.",Fiquei sabendo que o Macil planeja começar algo logo. Precisamos acertar um grande golpe depois do último fiasco. Se aquilo se repetir nós não teremos força para continuar.,,Am auzit că Macil va începe ceva curând. Trebuie să dăm lovitura după ultimul fiasco. Încă unul și vom fi prea slabi să continuăm.,"Я слышал, что Мэйсил готовит новую операцию после провала предыдущей. Она должна быть крайне успешной. После второго такого провала мы уже не оправимся.",,Macil'in yakında yeniden bir şeyler başlatacağını duydum. Son fiyaskodan sonra büyük bir vuruşa ihtiyacımız var. Bir daha böyle bir şey olursa devam edemeyecek kadar zayıf düşeriz. +我々は一度大敗し全滅しかけた。",마실 사령관이 또 다른 작전을 준비한데. 그전에 일어났던 대참사보다 훨씬 나은 작전이었으면 좋겠는데. 운이 나쁘면 많은 병력을 잃어버릴 것 같아.,Ik heb gehoord dat Macil binnenkort weer met iets gaat beginnen. We hebben een grote hit nodig na het laatste fiasco. Nog zo'n hit en dan zijn we te zwak om verder te gaan.,"Jeg har hørt at Macil skal starte noe igjen snart. Vi trenger en stor hit etter den siste fiaskoen. En til, så er vi for svake til å fortsette.","Słyszałem, że Macil ma zamiar wkrótce znowu coś zacząć. Potrzebujemy dużego uderzenia po ostatnim fiasku. Jeszcze jedno takie i będziemy zbyt słabi, by kontynuować.",Fiquei sabendo que o Macil planeja começar algo logo. Precisamos acertar um grande golpe depois do último fiasco. Se aquilo se repetir nós não teremos força para continuar.,,Am auzit că Macil va începe ceva curând. Trebuie să dăm lovitura după ultimul fiasco. Încă unul și vom fi prea slabi să continuăm.,"Я слышал, что Мэйсил готовит новую операцию после провала предыдущей. Она должна быть крайне успешной. После второго такого провала мы уже не оправимся.",,Jag har hört att Macil snart ska starta något igen. Vi behöver en stor succé efter det senaste fiaskot. En sån där till och vi blir för svaga för att fortsätta.,Macil'in yakında yeniden bir şeyler başlatacağını duydum. Son fiyaskodan sonra büyük bir vuruşa ihtiyacımız var. Bir daha böyle bir şey olursa devam edemeyecek kadar zayıf düşeriz. A few of these barrels dumped into their water supply should even the odds a little. ,TXT_DLG_SCRIPT34_D4548_AFEWO,〃,,,Pár těhle sudů v jejich zásobách vody by nám mělo alespoň trochu pomoct.,Et par af disse tønder dumpet i deres vandforsyning burde udligne oddsene lidt.,"Wenn wir ein paar von diesen Fässern in die Wasserversorgung kippen, sollte das unsere Chancen etwas verbessern.",,,Unos cuantos de estos barriles arrojados a su suministro de agua debería igualar las probabilidades un poco.,,Muutaman tällaisen tynnyrin kaataminen heidän vedenjakeluunsa varmaankin hieman tasoittaisi tilannetta.,Quelques tonneaux vidés dans leur réserve d'eau devrait aplanir le terrain de jeu.,Kicsit kiegyenlíti az erőviszonyokat ha ezt a pár hordót beleöntjük a víztározójukba.,Un paio di questi barili rovesciati dentro la loro fornitura d'acqua dovrebbero bilanciare un pò le cose.,"ここの樽は捨てられていた物で -彼らの給水を補っている。","놈들의 상수도에서 내려온 이 통들, 이상하지 않아? 뭔가 승산이 있을 것 같아.","Een paar van deze vaten die in hun watertoevoer gedumpt worden, zullen de kans op een beetje gelijk zijn.",Et par av disse tønnene dumpet i vannforsyningen deres burde jevne ut oddsene litt.,Kilka tych beczek wrzuconych do ich wodociągów powinno trochę wyrównać szanse.,Alguns desses barris despejados no estoque de água deles deve melhorar um pouco as nossas chances.,,Câteva butoaie aruncate în rezerva lor de apă ar trebui să egaleze șansele.,"Несколько таких бочек, сброшенных в их водоснабжение, причинят немало неприятностей.",,Bu varillerden birkaçını su kaynaklarına boşaltmak olasılıkları biraz olsun eşitler. +彼らの給水を補っている。","놈들의 상수도에서 내려온 이 통들, 이상하지 않아? 뭔가 승산이 있을 것 같아.","Een paar van deze vaten die in hun watertoevoer gedumpt worden, zullen de kans op een beetje gelijk zijn.",Et par av disse tønnene dumpet i vannforsyningen deres burde jevne ut oddsene litt.,Kilka tych beczek wrzuconych do ich wodociągów powinno trochę wyrównać szanse.,Alguns desses barris despejados no estoque de água deles deve melhorar um pouco as nossas chances.,,Câteva butoaie aruncate în rezerva lor de apă ar trebui să egaleze șansele.,"Несколько таких бочек, сброшенных в их водоснабжение, причинят немало неприятностей.",,Några av de här tunnorna dumpade i deras vattenförsörjning borde jämna ut oddsen lite.,Bu varillerden birkaçını su kaynaklarına boşaltmak olasılıkları biraz olsun eşitler. I'm working on something that will give us an edge. It will increase your stamina and completely jack you up. I've almost got all the bugs worked out. Can I do something for you? ,TXT_DLG_SCRIPT34_D6064_IMWOR,"MAP34: Gerald. (Except for row 1335, everything in rows 1323-1343 is identical to 725-745)",,,"Pracuju na něčem, co by nám mělo pomoci. Přidá ti to výdrž a naprosto tě to napumpuje. Už jsem skoro vychytal všechny mouchy. Co pro tebe mohu udělat?","Jeg arbejder på noget, der vil give os en fordel. Det vil øge din udholdenhed og gøre dig helt oppe at køre. Jeg har næsten fået styr på alle fejlene. Må jeg gøre noget for dig?","Ich arbeite an etwas, das uns einen Vorteil verschaffen kann. Es würde deine Ausdauer erhöhen und dir Superkräfte verleihen. Kann ich was für dich tun?",,"Mi laboras super io, kio donos avantaĝon al ni: ĝi pliigos vian energion kaj korpan forton. Mi jam korektis la plimulton de la difektoj. Ĉu mi povas fari ion por vi?",Estoy trabajando en algo que nos dará una ventaja: aumentará tu aguante y fuerza física. Ya casi tengo todos los fallos corregidos. ¿Puedo hacer algo por ti?,Estoy trabajando en algo que nos va a dar una ventaja: va a aumentar tu aguante y fuerza física. Ya casi tengo todos los fallos corregidos. ¿Puedo hacer algo por ti?,"Olen paraikaa työstämässä jotain, joka antaa meille etulyöntiaseman. Se kasvattaa kuntoasi ja täydellisesti virittää lihaksesi. Olen melkein saanut hiottua kaikki viat. Voinko olla jotenkin avuksi?",Je travaille sur quelque chose qui nous donnera un peu d'avance. Ca devrait augmenter votre endurance et vous donner un sacré coup de jus. Je crois que j'ai corrigé presque tous les bugs. Je peux vous aider?,"Dolgozok valamin, ami egy jelentősebb előnyhöz juttat minket. Megerősíti az állóképességedet és teljesen felpumpálja a tested. Már majdnem kiküszöböltem a hibákat. Amúgy tudok valamiben segíteni?",Sto lavorando a qualcosa che ci darà un notevole vantaggio. Aumenterà la tua resistenza e ti farà sentire molto più forte. Ho quasi risolto tutti gli effetti collaterali. Posso fare qualcosa per te?,"私は研究にも取り組んでいる。貴方のスタミナを 増強し完璧な体にすることも可能だ。 そのインプラントのバグも殆ど取り除かれている -ところで何か必要かい?","아주 유용하고 승패를 가릴 수 있는 비장의 카드를 연구 중입니다. 바로 지구력 향상 이식 칩이죠. 이것만 있으면 체력과 힘을 증가시킵니다. 거의 완성되었어요. 이제, 뭘 도와드릴까요?",Ik werk aan iets dat ons een voorsprong geeft. Het zal je uithoudingsvermogen verhogen en je helemaal opkrikken. Ik heb bijna alle bugs uitgewerkt. Kan ik iets voor u doen?,Jeg jobber med noe som vil gi oss en fordel. Det vil øke utholdenheten din og løfte deg helt opp. Jeg har nesten løst alle problemene. Kan jeg gjøre noe for deg?,"Pracuję nad czymś, co da nam przewagę. Zwiększy to twoją wytrzymałość i całkowicie cię podnieci. Mam już prawie dopracowane wszystkie błędy. Mogę coś dla ciebie zrobić?",Estou trabalhando em algo que vai nos dar um impulso. É algo que vai aumentar sua resistência e te deixar bem mais forte. Estou com quase todos os bugs resolvidos. Posso te ajudar com algo?,,Lucrez la ceva ce ne va da un avantaj. Îți va crește rezistența și forța. Am rezolvat aproape toate problemele. Pot să te ajut cu ceva acum?,"Я работаю кое над чем, что может нам пригодиться. Оно увеличит твою выносливость и улучшит самочувствие. Я уже исправил почти все дефекты. Или тебе нужно что-то ещё?",,Bize avantaj sağlayacak bir şey üzerinde çalışıyorum. Dayanıklılığınızı arttıracak ve sizi tamamen güçlendirecek. Neredeyse tüm hataları çözdüm. Senin için bir şey yapabilir miyim? -Patch me up.,TXT_RPLY0_SCRIPT34_D6064_PATCH,〃,,,Dej mě do hromady.,Løs mig op.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Hoida minut kuntoon.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lappe meg sammen.,Załataj mnie.,Trate meus ferimentos.,,Bandajează-mă.,Перебинтуй меня.,,Beni yamala. +ところで何か必要かい?","아주 유용하고 승패를 가릴 수 있는 비장의 카드를 연구 중입니다. 바로 지구력 향상 이식 칩이죠. 이것만 있으면 체력과 힘을 증가시킵니다. 거의 완성되었어요. 이제, 뭘 도와드릴까요?",Ik werk aan iets dat ons een voorsprong geeft. Het zal je uithoudingsvermogen verhogen en je helemaal opkrikken. Ik heb bijna alle bugs uitgewerkt. Kan ik iets voor u doen?,Jeg jobber med noe som vil gi oss en fordel. Det vil øke utholdenheten din og løfte deg helt opp. Jeg har nesten løst alle problemene. Kan jeg gjøre noe for deg?,"Pracuję nad czymś, co da nam przewagę. Zwiększy to twoją wytrzymałość i całkowicie cię podnieci. Mam już prawie dopracowane wszystkie błędy. Mogę coś dla ciebie zrobić?",Estou trabalhando em algo que vai nos dar um impulso. É algo que vai aumentar sua resistência e te deixar bem mais forte. Estou com quase todos os bugs resolvidos. Posso te ajudar com algo?,,Lucrez la ceva ce ne va da un avantaj. Îți va crește rezistența și forța. Am rezolvat aproape toate problemele. Pot să te ajut cu ceva acum?,"Я работаю кое над чем, что может нам пригодиться. Оно увеличит твою выносливость и улучшит самочувствие. Я уже исправил почти все дефекты. Или тебе нужно что-то ещё?",,Jag arbetar på något som kommer att ge oss en fördel. Det kommer att öka din uthållighet och göra dig helt upprymd. Jag har nästan löst alla buggar. Kan jag göra något för dig?,Bize avantaj sağlayacak bir şey üzerinde çalışıyorum. Dayanıklılığınızı arttıracak ve sizi tamamen güçlendirecek. Neredeyse tüm hataları çözdüm. Senin için bir şey yapabilir miyim? +Patch me up.,TXT_RPLY0_SCRIPT34_D6064_PATCH,〃,,,Dej mě do hromady.,Løs mig op.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Hoida minut kuntoon.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lappe meg sammen.,Załataj mnie.,Trate meus ferimentos.,,Bandajează-mă.,Перебинтуй меня.,,Laga mig.,Beni yamala. "Boy, you're a real mess. I'll see what I can do.",TXT_RYES0_SCRIPT34_D6064_BOYYO,〃,,,"Tebe teda zřídili, kluku. Uvidím, co s tebou.","Mand, du er et rigtigt rod. Jeg skal se, hvad jeg kan gøre.","Mann, du siehst aber gar nicht gut aus. Mal sehen, was ich machen kann.",,"Ulo, vi estas iomege en malordo. Mi vidos tion, kion mi faru.","Tío, estás hecho un desastre. A ver qué puedo hacer.","Chico, estás hecho un desastre. -A ver qué puedo hacer.","Voi pojat, oletpa hajalla. Katsotaan, mihin pystyn.","Mon petit, vous êtes dans un sale état. Je vais voir ce que je peux faire.","Öregem, elég ramaty állapotban vagy. Megnézem mit tehetek.","Ragazzo, sei messo proprio male. Vediamo cosa posso fare.",君、滅茶苦茶だな。なんとかしよう。,가능한 한 아프지 않게 치료하겠습니다.,"Jongen, je bent een echte puinhoop. Ik zal zien wat ik kan doen.","Jøss, du ser forferdelig ut. Jeg skal se hva jeg kan gjøre.","Chłopcze, jesteś w niezłym stanie. Zobaczę, co da się zrobić.","Rapaz, você está arrebentado. Verei o que posso fazer.",,"Băiete, ești un dezastru. O să văd ce pot face.","Ты просто месиво. Посмотрим, что я смогу сделать.",,"Evlat, gerçekten berbat durumdasın. Ne yapabileceğime bir bakayım." -Stamina implant?,TXT_RPLY1_SCRIPT34_D6064_STAMI,〃,,,Implantát pro výdrž?,Udholdenhedsimplantat?,Ausdauerimplantat?,,Ĉu energidona enplantaĵo?,¿Implante de aguante?,,Kuntoistute?,Implant d'endurance?,Állóképesség implantátum?,Impianto stamina?,スタミナインプラント?,지구력 향상 이식?,Stamina implantaat?,Utholdenhetsimplantat?,Implant wytrzymałościowy?,Implante de resistência?,,Implant de rezistență?,Выносливостный имплант?,,Dayanıklılık implantı mı? +A ver qué puedo hacer.","Voi pojat, oletpa hajalla. Katsotaan, mihin pystyn.","Mon petit, vous êtes dans un sale état. Je vais voir ce que je peux faire.","Öregem, elég ramaty állapotban vagy. Megnézem mit tehetek.","Ragazzo, sei messo proprio male. Vediamo cosa posso fare.",君、滅茶苦茶だな。なんとかしよう。,가능한 한 아프지 않게 치료하겠습니다.,"Jongen, je bent een echte puinhoop. Ik zal zien wat ik kan doen.","Jøss, du ser forferdelig ut. Jeg skal se hva jeg kan gjøre.","Chłopcze, jesteś w niezłym stanie. Zobaczę, co da się zrobić.","Rapaz, você está arrebentado. Verei o que posso fazer.",,"Băiete, ești un dezastru. O să văd ce pot face.","Ты просто месиво. Посмотрим, что я смогу сделать.",,Du är en riktig röra. Jag ska se vad jag kan göra.,"Evlat, gerçekten berbat durumdasın. Ne yapabileceğime bir bakayım." +Stamina implant?,TXT_RPLY1_SCRIPT34_D6064_STAMI,〃,,,Implantát pro výdrž?,Udholdenhedsimplantat?,Ausdauerimplantat?,,Ĉu energidona enplantaĵo?,¿Implante de aguante?,,Kuntoistute?,Implant d'endurance?,Állóképesség implantátum?,Impianto stamina?,スタミナインプラント?,지구력 향상 이식?,Stamina implantaat?,Utholdenhetsimplantat?,Implant wytrzymałościowy?,Implante de resistência?,,Implant de rezistență?,Выносливостный имплант?,,Ett uthållighetsimplantat?,Dayanıklılık implantı mı? "All right, this won't take but a moment.",TXT_RYES1_SCRIPT34_D6064_ALLRI,〃,,,"Dobře, tohle potrvá jen chvilku.","Okay, det tager kun et øjeblik.","Alles klar, das haben wir sofort.",,"Bonege, ĉi tio estos rapidega.","Muy bien, solo tomará un momento.","Muy bien, solo va a -tomar un momento.","Hyvä on, tähän ei mene hetkeä pidempään.","Pas de problème, ça ne prendra qu'un moment.","Rendben, nem vesz igénybe többet pár másodpercnél.","Va bene, ci vorrà solo un momento.",大丈夫、すぐ終わります。,많이 걸리진 않을거에요...,"Oké, dit duurt maar een momentje.",Dette tar bare et øyeblikk.,"Dobra, to zajmie tylko chwilę.","Ok, isso não vai demorar.",,"În regulă, va dura doar un moment.","Отлично, это займёт всего пару секунд.",,"Pekala, bu bir dakikadan fazla sürmez." +tomar un momento.","Hyvä on, tähän ei mene hetkeä pidempään.","Pas de problème, ça ne prendra qu'un moment.","Rendben, nem vesz igénybe többet pár másodpercnél.","Va bene, ci vorrà solo un momento.",大丈夫、すぐ終わります。,많이 걸리진 않을거에요...,"Oké, dit duurt maar een momentje.",Dette tar bare et øyeblikk.,"Dobra, to zajmie tylko chwilę.","Ok, isso não vai demorar.",,"În regulă, va dura doar un moment.","Отлично, это займёт всего пару секунд.",,"Okej, det här tar bara ett ögonblick.","Pekala, bu bir dakikadan fazla sürmez." It's not done yet.,TXT_RNO1_SCRIPT34_D6064_ITSNO,〃,,,Ještě není hotový.,Det er ikke færdigt endnu.,Es ist noch nicht soweit.,,"Mi ankoraŭ -prilaboras ĝin.",Aún no está listo.,,Se ei ole valmis vielä.,Ce n'est pas encore terminé.,Még nincs kész.,Non è ancora pronto.,まだ完成していません。,연구가 진행중입니다. 나중에.,Het is nog niet klaar.,Det er ikke ferdig ennå.,Jeszcze nie skończyłem.,Ainda não terminei.,,Încă nu e gata.,Он ещё не готов.,,Henüz bitmedi. +prilaboras ĝin.",Aún no está listo.,,Se ei ole valmis vielä.,Ce n'est pas encore terminé.,Még nincs kész.,Non è ancora pronto.,まだ完成していません。,연구가 진행중입니다. 나중에.,Het is nog niet klaar.,Det er ikke ferdig ennå.,Jeszcze nie skończyłem.,Ainda não terminei.,,Încă nu e gata.,Он ещё не готов.,,Det är inte klart än.,Henüz bitmedi. "Hey, I'm working on an updated version of your implant. Is there anything else I can do?",TXT_DLG_SCRIPT34_D7580_HEYIM,〃,,,"Hej, pracuju na vylepšené verzi tvého implantátu. Můžu pro tebe udělat něco jiného?","Jeg arbejder på en opdateret version af dit implantat. Er der andet, jeg kan gøre?","He, ich arbeite an einer verbesserten Version deines Implantats. Gibt es sonst etwas, das ich für dich tun kann?",,"Mi laboras super plibonigita versio de via enplantaĵo. Ĉu estas io alia, kion mi povas fari por vi?",Estoy trabajando en una versión mejorada de tu implante. ¿Hay algo más que pueda hacer?,,"Hei, olen työstämässä päivitettyä versiota istutteestasi. Voinko olla muuten avuksi?","Hé, je travaille sur une version améliorée de l'implant. Qu'est-ce que je peux faire pour vous?",Az implantátum újabb verzióján dolgozok. Tudok még valamiben segíteni?,"Ehi, sto lavorando ad un aggiornamento per l'impianto stamina. Posso fare qualcos'altro per te?","どうも、私は今最新版のインプラントに -取り組んでいる。何か用かな?","여어! 이식 칩을 향상할 개조를 받고 싶으신가요? 아니라면, 뭐가 필요합니까?","Hé, ik ben bezig met een bijgewerkte versie van je implantaat. Is er nog iets anders dat ik kan doen?",Jeg jobber med en oppdatert versjon av implantatet ditt. Er det noe annet jeg kan gjøre?,"Hej, pracuję nad unowocześnioną wersją twojego implantu. Czy mogę zrobić coś jeszcze?",E aí. Estou trabalhando numa versão aprimorada do seu implante. Posso te ajudar com mais alguma coisa?,,"Hei, lucrez la o variantă îmbunătățită a implantului tău. E ceva cu care pot să te ajut?","Я работаю над улучшенной версией твоего импланта. А пока, что-нибудь ещё?",,"Hey, implantının güncellenmiş bir versiyonu üzerinde çalışıyorum. Yapabileceğim başka bir şey var mı?" -Patch me up.,TXT_RPLY0_SCRIPT34_D7580_PATCH,〃,,,Dej mě do hromady.,Gør mig klar.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Pistä minut kuntoon.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lappe meg sammen.,Załataj mnie.,Trate meus ferimentos.,,Bandajează-mă.,Перебинтуй меня.,,Bana yama yap. +取り組んでいる。何か用かな?","여어! 이식 칩을 향상할 개조를 받고 싶으신가요? 아니라면, 뭐가 필요합니까?","Hé, ik ben bezig met een bijgewerkte versie van je implantaat. Is er nog iets anders dat ik kan doen?",Jeg jobber med en oppdatert versjon av implantatet ditt. Er det noe annet jeg kan gjøre?,"Hej, pracuję nad unowocześnioną wersją twojego implantu. Czy mogę zrobić coś jeszcze?",E aí. Estou trabalhando numa versão aprimorada do seu implante. Posso te ajudar com mais alguma coisa?,,"Hei, lucrez la o variantă îmbunătățită a implantului tău. E ceva cu care pot să te ajut?","Я работаю над улучшенной версией твоего импланта. А пока, что-нибудь ещё?",,Jag jobbar på en uppdaterad version av ditt implantat. Finns det något annat jag kan göra?,"Hey, implantının güncellenmiş bir versiyonu üzerinde çalışıyorum. Yapabileceğim başka bir şey var mı?" +Patch me up.,TXT_RPLY0_SCRIPT34_D7580_PATCH,〃,,,Dej mě do hromady.,Gør mig klar.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Pistä minut kuntoon.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lappe meg sammen.,Załataj mnie.,Trate meus ferimentos.,,Bandajează-mă.,Перебинтуй меня.,,Laga mig.,Bana yama yap. Well at least you're seeing action.,TXT_RYES0_SCRIPT34_D7580_WELLA,〃,,,"No, alespoň jsi v akci.",I det mindste er du i gang.,"Mann, du siehst aber gar nicht gut aus. Mal sehen, was ich machen kann.",,"Nu, almenaŭ vi ne havas enuigajn misiojn.","Bueno, al menos estás -teniendo algo de acción.",,"No, ainakin näet toimintaa.","Eh bien, au moins vous en voyez, de l'action.",Legalább ér valami izgalom.,"Beh, almeno ti stai dando da fare.",少なくとも行動を起こしているのです。,이제 마음껏 움직여보세요.,"Nou ja, je ziet in ieder geval actie.",Det skjer i det minste noe.,"Przynajmniej widzisz, że coś się dzieje.","Bem, pelo menos está tendo um pouco de ação.",,"Pă, măcar tu ai parte de niște acțiune.","Что ж, зато ты участвуешь в операциях.",,En azından hareket görüyorsun. -Implant upgrade?,TXT_RPLY1_SCRIPT34_D7580_IMPLA,〃,,,Vylepšení implantátu?,Implantatopgradering?,Implantatsupgrade?,,Ĉu plibonigo de enplantaĵo?,¿Mejora de implante?,,Istutteen päivitys?,Mise à jour de l'implant?,Implantátum fejlesztés?,Aggiornamento dell'impianto?,インプラント アップグレード?,지구력 업그레이드?,Implantaat upgrade?,Implantatoppgradering?,Aktualizacja implantu?,Versão aprimorada do implante?,,Upgrade la implant?,Улучшение импланта?,,İmplant güncellemesi mi? +teniendo algo de acción.",,"No, ainakin näet toimintaa.","Eh bien, au moins vous en voyez, de l'action.",Legalább ér valami izgalom.,"Beh, almeno ti stai dando da fare.",少なくとも行動を起こしているのです。,이제 마음껏 움직여보세요.,"Nou ja, je ziet in ieder geval actie.",Det skjer i det minste noe.,"Przynajmniej widzisz, że coś się dzieje.","Bem, pelo menos está tendo um pouco de ação.",,"Pă, măcar tu ai parte de niște acțiune.","Что ж, зато ты участвуешь в операциях.",,Du ser åtminstone till att det händer något.,En azından hareket görüyorsun. +Implant upgrade?,TXT_RPLY1_SCRIPT34_D7580_IMPLA,〃,,,Vylepšení implantátu?,Implantatopgradering?,Implantatsupgrade?,,Ĉu plibonigo de enplantaĵo?,¿Mejora de implante?,,Istutteen päivitys?,Mise à jour de l'implant?,Implantátum fejlesztés?,Aggiornamento dell'impianto?,インプラント アップグレード?,지구력 업그레이드?,Implantaat upgrade?,Implantatoppgradering?,Aktualizacja implantu?,Versão aprimorada do implante?,,Upgrade la implant?,Улучшение импланта?,,Implantatuppgradering?,İmplant güncellemesi mi? "Good thing, never can be too safe.",TXT_RYES1_SCRIPT34_D7580_GOODT,〃,,,"Dobrá věcička, nikdy si nemůžeš být moc jistý.","Godt, man kan aldrig være for sikker.","Alles klar, das haben wir sofort.",,"Bone. Neniam estas sufiĉe da sekureco.","Bien. Nunca se puede -estar del todo seguro.",,"Hyvä, koskaan ei voi olla liian turvallista.",Bonne idée. On ne peut jamais être trop sûr.,"Még jó, soha nem lehetsz túl nagy biztonságban.","Ottimo, non si può mai essere troppo al sicuro.",良いことだ、安全すぎることはない。,위험 할 때도 있으니 지금 고치겠습니다.,"Goede zaak, kan nooit te veilig zijn.","Bra, man kan aldri være for sikker.","To dobrze, nigdy nie można być zbyt bezpiecznym.",Boa ideia. Segurança nunca é demais.,,"Bine zis, nu poți fi niciodată prea sigur.","Очень советую, ни в чём нельзя быть уверенным до конца.",,"İyi bir şey, asla çok güvenli olamaz." +estar del todo seguro.",,"Hyvä, koskaan ei voi olla liian turvallista.",Bonne idée. On ne peut jamais être trop sûr.,"Még jó, soha nem lehetsz túl nagy biztonságban.","Ottimo, non si può mai essere troppo al sicuro.",良いことだ、安全すぎることはない。,위험 할 때도 있으니 지금 고치겠습니다.,"Goede zaak, kan nooit te veilig zijn.","Bra, man kan aldri være for sikker.","To dobrze, nigdy nie można być zbyt bezpiecznym.",Boa ideia. Segurança nunca é demais.,,"Bine zis, nu poți fi niciodată prea sigur.","Очень советую, ни в чём нельзя быть уверенным до конца.",,"Bra, man kan aldrig vara för säker.","İyi bir şey, asla çok güvenli olamaz." "I'm almost finished, but not quite.",TXT_RNO1_SCRIPT34_D7580_IMALM,〃,,,"Už je skoro hotový, ale ne úplně.","Jeg er næsten færdig, men ikke helt.",Es ist noch nicht soweit.,,"Mi preskaŭ finis, sed ne tute.","Casi he terminado, -pero no del todo.",,"Olen melkein valmis, mutten ihan vielä.","Presque fini, mais pas encore.","Majdnem végeztem, de még nem teljesen","Ho quasi finito, ma non ancora.",もうすぐ出来上がる、それほど掛からない。,거의 완성했는데... 아마도 다음 시간에?,"Ik ben bijna klaar, maar niet helemaal.","Jeg er nesten ferdig, men ikke helt.","Prawie skończyłem, ale nie do końca.",Está quase pronto.,,"Sunt aproape gata, dar nu chiar.",Я почти закончил. Ещё немного.,,Neredeyse bitirdim ama tam değil. +pero no del todo.",,"Olen melkein valmis, mutten ihan vielä.","Presque fini, mais pas encore.","Majdnem végeztem, de még nem teljesen","Ho quasi finito, ma non ancora.",もうすぐ出来上がる、それほど掛からない。,거의 완성했는데... 아마도 다음 시간에?,"Ik ben bijna klaar, maar niet helemaal.","Jeg er nesten ferdig, men ikke helt.","Prawie skończyłem, ale nie do końca.",Está quase pronto.,,"Sunt aproape gata, dar nu chiar.",Я почти закончил. Ещё немного.,,"Jag är nästan klar, men inte riktigt.",Neredeyse bitirdim ama tam değil. "All right, this is it. I've almost got everything working perfectly. There were a few problems left to fix, do you need anything else? ",TXT_DLG_SCRIPT34_D9096_ALLRI,〃,,,"Tak dobře, už mi skoro všechno perfektně funguje. Ještě tam bylo pár problémů. Potřebuješ ještě něco?","Okay, det er det. Jeg har næsten fået det hele til at fungere perfekt. Der var et par problemer tilbage at løse, har du brug for andet?","He, ich arbeite an einer verbesserten Version deines Implantats. Gibt es sonst etwas, das ich für dich tun kann?",,"Bone, jen ĉio; preskaŭ ĉio funkcias perfekte. Restis nur kelkaj korektindaj problemoj. Ĉu vi bezonas ion alian?","Muy bien, ya está; tengo casi todo funcionando a la perfección. Solo quedaban algunos problemas que corregir. ¿Necesitas algo más?",,"No niin, olen melkein saanut kaiken toimimaan täydellisesti. Vain muutamia vikoja oli enää jäljellä. Tarvitsetko mitään muuta?","Très bien, je crois que j'ai réussi à tout faire marcher parfaitement. Il y avait quelques problèmes dont je devais me débarrasser. Vous voulez quelque chose?","Rendben, ez lesz az. Már majdnem mindent tökéletesre kidolgoztam. Már csak pár lehetőség van hátra, kell még valami esetleg?","Allora, sono riuscito a far funzionare quasi tutto benissimo. C'erano giusto un paio di problemi rimasti da risolvere. Ti serve qualcos'altro?","大丈夫、全て順調だ。残っていた問題も -全て取り除かれた。他に何が必要かな?","정말 힘든 시간이었어요. 이식 칩의 문제들의 거의 다 고쳐가고 있습니다. 기다리는 동안, 무엇을 도와드릴까요?","Goed, dit is het. Ik heb bijna alles perfect werkend. Er waren nog een paar problemen op te lossen, heb je nog iets anders nodig?","Greit, nå gjelder det. Jeg har nesten fått alt til å fungere perfekt. Det var noen problemer igjen å fikse, trenger du noe mer?","W porządku, to jest to. Prawie wszystko działa idealnie. Zostało kilka problemów do naprawienia, potrzebujesz czegoś jeszcze?","Ok, é isso aí. Está quase tudo funcionando perfeitamente. Faltavam alguns problemas pra consertar. Precisa de mais algo?",,"În regulă, asta e tot. Acum aproape totul merge perfect. Au mai fost câteva probleme de rezolvat, mai ai nevoie de ceva?","Итак, тут оставалась пара проблем, но теперь всё работает почти идеально. Что-нибудь ещё?",,"Pekala, işte bu. Neredeyse her şey mükemmel çalışıyor. Düzeltmem gereken birkaç sorun kaldı, başka bir şeye ihtiyacın var mı?" -Patch me up.,TXT_RPLY0_SCRIPT34_D9096_PATCH,〃,,,Dej mě do hromady.,Lav mig om.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Paikkaa minut.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lapp meg sammen.,Załataj mnie.,Trate meus ferimentos.,,Bandajează-mă.,Перебинтуй меня.,,Beni yamala. +全て取り除かれた。他に何が必要かな?","정말 힘든 시간이었어요. 이식 칩의 문제들의 거의 다 고쳐가고 있습니다. 기다리는 동안, 무엇을 도와드릴까요?","Goed, dit is het. Ik heb bijna alles perfect werkend. Er waren nog een paar problemen op te lossen, heb je nog iets anders nodig?","Greit, nå gjelder det. Jeg har nesten fått alt til å fungere perfekt. Det var noen problemer igjen å fikse, trenger du noe mer?","W porządku, to jest to. Prawie wszystko działa idealnie. Zostało kilka problemów do naprawienia, potrzebujesz czegoś jeszcze?","Ok, é isso aí. Está quase tudo funcionando perfeitamente. Faltavam alguns problemas pra consertar. Precisa de mais algo?",,"În regulă, asta e tot. Acum aproape totul merge perfect. Au mai fost câteva probleme de rezolvat, mai ai nevoie de ceva?","Итак, тут оставалась пара проблем, но теперь всё работает почти идеально. Что-нибудь ещё?",,"Okej, nu är det dags. Jag har nästan fått allt att fungera perfekt. Det fanns några problem kvar att fixa, behöver du något mer?","Pekala, işte bu. Neredeyse her şey mükemmel çalışıyor. Düzeltmem gereken birkaç sorun kaldı, başka bir şeye ihtiyacın var mı?" +Patch me up.,TXT_RPLY0_SCRIPT34_D9096_PATCH,〃,,,Dej mě do hromady.,Lav mig om.,Flick mich zusammen.,,Kuracu min.,Cúrame.,,Paikkaa minut.,Soignez moi.,Gyógyíts fel.,Curami.,治療してほしい。,치료가 필요합니다.,Patch me op.,Lapp meg sammen.,Załataj mnie.,Trate meus ferimentos.,,Bandajează-mă.,Перебинтуй меня.,,Laga mig.,Beni yamala. What have you been trying to do? Go head to head with a Crusader?,TXT_RYES0_SCRIPT34_D9096_WHATH,〃,,,Co jsi dělal? Šel zmlátit Křižáka?,Hvad har du forsøgt at gøre? Gå hoved mod hoved med en korsfarer?,"Mann, du siehst aber gar nicht gut aus. Mal sehen, was ich machen kann.",,"Kion vi intencis fari? Ĉu piki Kruciston?","¿Qué has intentado hacer? ¿Ir cara a cara con un Cruzado?","¿Qué anduviste haciendo? ¿Ir cara a cara con un Cruzado?",Mitä olet oikein yrittänyt tehdä? Mennä nokittain ristiretkeläisen kanssa?,Qu'est-ce que vous avez fait? Vous avez essayé de faire ami avec un Croisé?,Mit akartál tenni? Nekimenni egymagad egy keresztesnek?,Ma cosa hai cercato di fare? Lottare da solo contro un Crociato?,"今度は何を始めるんだ? -クルセイダーと向かい合うのか?",아콜라이트와 근접전을 펼친 것 같군요... 아마도.,Wat heb je geprobeerd te doen? Hoofd aan hoofd gaan met een kruisvaarder?,Hva har du prøvd å gjøre? Kjempe mot en korsfarer?,Co próbowałeś zrobić? Walczyć łeb w łeb z Crusaderem?,O que andou tentando fazer? Sair na porrada com um Cruzado?,,Ce ai încercat să faci? Dai cap în cap cu un Cruciat?,"Ты что, бился один на один с крестоносцем?",,Ne yapmaya çalışıyordun? Bir Crusader ile kafa kafaya mı? -Implant upgrade?,TXT_RPLY1_SCRIPT34_D9096_IMPLA,〃,,,Vylepšení implantátu?,Implantatopgradering?,Implantatsupgrade?,,Ĉu plibonigo de enplantaĵo?,¿Mejora de implante?,,Istutteen päivitys?,Mise à jour de l'implant?,Implantátum fejlesztés?,Aggiornamento dell'impianto?,インプラント アップグレード?,지구력 업그레이드?,Implantaat upgrade?.,Implantatoppgradering?,Ulepszenie implantu?,Aprimoramento de implante?,,Upgrade la implant?,Улучшение импланта?,,İmplant yükseltmesi mi? -That should do it for you.,TXT_RYES1_SCRIPT34_D9096_THATS,〃,,,Tohle by mělo fungovat.,Det burde gøre det for dig.,"Alles klar, das haben wir sofort.",,Ĉi tio devus esti sufiĉa.,Con esto debería estar.,,Eiköhän tällä ala tepsiä.,Ca devrait faire l'affaire.,Ez szerintem megteszi.,Questo dovrebbe andare.,今取り掛かっている。,도움이 좀 될 거에요.,Dat zou het voor je moeten doen.,Det burde gjøre det for deg.,To powinno ci wystarczyć.,Isso deve funcionar pra você.,,Asta ar trebui să fie suficient.,Вот оно.,,Bu senin işini görür. +クルセイダーと向かい合うのか?",아콜라이트와 근접전을 펼친 것 같군요... 아마도.,Wat heb je geprobeerd te doen? Hoofd aan hoofd gaan met een kruisvaarder?,Hva har du prøvd å gjøre? Kjempe mot en korsfarer?,Co ty próbowałeś zrobić? Walczyć oko w oko z Krzyżowcem?,O que andou tentando fazer? Sair na porrada com um Cruzado?,,Ce ai încercat să faci? Dai cap în cap cu un Cruciat?,"Ты что, бился один на один с крестоносцем?",,Vad har du försökt göra? Gå mot en korsriddare?,Ne yapmaya çalışıyordun? Bir Haçlı ile kafa kafaya mı? +Implant upgrade?,TXT_RPLY1_SCRIPT34_D9096_IMPLA,〃,,,Vylepšení implantátu?,Implantatopgradering?,Implantatsupgrade?,,Ĉu plibonigo de enplantaĵo?,¿Mejora de implante?,,Istutteen päivitys?,Mise à jour de l'implant?,Implantátum fejlesztés?,Aggiornamento dell'impianto?,インプラント アップグレード?,지구력 업그레이드?,Implantaat upgrade?.,Implantatoppgradering?,Ulepszenie implantu?,Aprimoramento de implante?,,Upgrade la implant?,Улучшение импланта?,,Implantatuppgradering?,İmplant yükseltmesi mi? +That should do it for you.,TXT_RYES1_SCRIPT34_D9096_THATS,〃,,,Tohle by mělo fungovat.,Det burde gøre det for dig.,"Alles klar, das haben wir sofort.",,Ĉi tio devus esti sufiĉa.,Con esto debería estar.,,Eiköhän tällä ala tepsiä.,Ca devrait faire l'affaire.,Ez szerintem megteszi.,Questo dovrebbe andare.,今取り掛かっている。,도움이 좀 될 거에요.,Dat zou het voor je moeten doen.,Det burde gjøre det for deg.,To powinno ci wystarczyć.,Isso deve funcionar pra você.,,Asta ar trebui să fie suficient.,Вот оно.,,Det borde göra det för dig.,Bu senin işini görür. Let me run some more tests first.,TXT_RNO1_SCRIPT34_D9096_LETME,〃,,,Ještě ho musím dál otestovat.,Lad mig køre nogle flere tests først.,Es ist noch nicht soweit.,,"Unue mi faru kelkajn provojn.","Déjame hacer algunas -pruebas primero.",,Anna minun ajaa muutamia kokeita ensin.,Laissez moi faire quelques tests d'abord.,Hadd futtassak pár tesztet.,Devo fare ancora qualche test.,もう少しテストしてからにしよう。,시험단계를 좀 거치고 예기할게요.,Laat me eerst nog wat testen doen.,La meg kjøre noen flere tester først.,Pozwól mi najpierw przeprowadzić kilka testów.,Só deixa eu fazer mais alguns testes.,,Lasă-mă să fac niște teste mai întâi.,Дай мне ещё времени на тесты.,,Önce birkaç test daha yapayım. +pruebas primero.",,Anna minun ajaa muutamia kokeita ensin.,Laissez moi faire quelques tests d'abord.,Hadd futtassak pár tesztet.,Devo fare ancora qualche test.,もう少しテストしてからにしよう。,시험단계를 좀 거치고 예기할게요.,Laat me eerst nog wat testen doen.,La meg kjøre noen flere tester først.,Pozwól mi najpierw przeprowadzić kilka testów.,Só deixa eu fazer mais alguns testes.,,Lasă-mă să fac niște teste mai întâi.,Дай мне ещё времени на тесты.,,Låt mig köra några fler tester först.,Önce birkaç test daha yapayım. That's all I can do on the implant right now. Maybe some healing?,TXT_DLG_SCRIPT34_D10612_THATS,〃,,,"Tak, to je všechno co teď můžu s tím implantátem udělat. Potřebuješ léčení?","Det er alt, hvad jeg kan gøre på implantatet lige nu. Måske noget healing?","Das ist alles, was ich im Moment mit dem Implantat machen kann. Vielleicht etwas medizinische Versorgung?",,"Tio estas ĉio, kion mi momente povas fari super la enplantaĵo. Ĉu vi bezonas kuracon?",Eso es todo lo que puedo hacer con el implante por ahora. ¿Necesitas curarte?,,Tätä enempää en voi istutteelle enää juuri nyt tehdä. Mutta oletko hoidon tarpeessa?,C'est tout ce que je peux faire pour l'implant. Vous voulez que je vous soigne?,Ennyit tudtam kezdeni most az implantátummal. Esetleg valami gyógyítás?,È tutto per quanto riguarda l'impianto. Però posso sempre curarti.,"インプラントはこれ以上ない程完成した。 -それとも治療か?",이식 칩에 관한 모든 걸 해줬습니다. 더 필요한 게 있나요?,Dat is alles wat ik nu kan doen op het implantaat. Misschien wat genezing?,Det er alt jeg kan gjøre med implantatet akkurat nå. Kanskje litt helbredelse?,"To wszystko, co mogę zrobić z implantem w tej chwili. Może trochę uzdrowienia?",Isso é tudo o que posso fazer com o implante no momento. Vai uma cura aí?,,Asta e tot ce pot face implantului acum. Poate niște bandaje?,Пока что я больше ничего не могу сделать с имплантом. Как насчёт лечения?,,Şu anda implant üzerinde yapabileceğim tek şey bu. Belki biraz iyileşme? -Yeah.,TXT_RPLY0_SCRIPT34_D10612_YEAH,〃,,,Jo.,Ja.,Ja.,,Jes.,Sí.,,Kyllä.,Ouais.,Igen.,Sì.,ああ。,그래.,Ja.,Ja.,Tak.,Sim.,,Da.,Давай.,,Evet. +それとも治療か?",이식 칩에 관한 모든 걸 해줬습니다. 더 필요한 게 있나요?,Dat is alles wat ik nu kan doen op het implantaat. Misschien wat genezing?,Det er alt jeg kan gjøre med implantatet akkurat nå. Kanskje litt helbredelse?,"To wszystko, co mogę zrobić z implantem w tej chwili. Może trochę uzdrowienia?",Isso é tudo o que posso fazer com o implante no momento. Vai uma cura aí?,,Asta e tot ce pot face implantului acum. Poate niște bandaje?,Пока что я больше ничего не могу сделать с имплантом. Как насчёт лечения?,,Det är allt jag kan göra med implantatet just nu. Kanske lite läkning?,Şu anda implant üzerinde yapabileceğim tek şey bu. Belki biraz iyileşme? +Yeah.,TXT_RPLY0_SCRIPT34_D10612_YEAH,〃,,,Jo.,Ja.,Ja.,,Jes.,Sí.,,Kyllä.,Ouais.,Igen.,Sì.,ああ。,그래.,Ja.,Ja.,Tak.,Sim.,,Da.,Давай.,,"Ja, det är det.",Evet. "Boy, you're a real mess. I'll see what I can do.",TXT_RYES0_SCRIPT34_D10612_BOYYO,〃,,,"Tebe teda zřídili, kluku. Uvidím, co s tebou.","Mand, du er et rigtigt rod. Jeg skal se, hvad jeg kan gøre.","Mann, du siehst aber gar nicht gut aus. Mal sehen, was ich machen kann.",,"Ulo, vi estas iomege en malordo. Mi vidos tion, kion mi faru.","Tío, estás hecho un desastre. A ver qué puedo hacer.","Chico, estás hecho un desastre. -A ver qué puedo hacer.","Kylläpä olet huonossa jamassa. Katsotaan, mitä voin tehdä.","Mon petit, vous êtes dans un sale état. Je vais voir ce que je peux faire.","Öregem, elég ramaty állapotban vagy. Megnézem mit tehetek.","Ragazzo, sei messo proprio male. Vediamo cosa posso fare.",君、滅茶苦茶だな。なんとかしよう。,치료가 다 끝났습니다. 다 의료기술 덕입니다.,"Jongen, je bent een echte puinhoop. Ik zal zien wat ik kan doen.","Jøss, du er et skikkelig rot. Jeg skal se hva jeg kan gjøre.","Chłopcze, masz niezły bałagan. Zobaczę, co da się zrobić.","Rapaz, você está arrebentado. Verei o que posso fazer.",,"Băiete, ești un dezastru. O să văd ce pot face.","Ты просто месиво. Посмотрим, что я смогу сделать.",,Gerçekten berbat durumdasın. Ne yapabileceğime bakacağım. -What can I do for you?,TXT_DLG_SCRIPT34_D12128_WHATC,"MAP34: Feris (identical to rows 746-768, except for row 1357).",,,Co pro tebe můžu udělat?,Hvad kan jeg gøre for dig?,Was kann ich für dich tun?,,Kion mi faru por vi?,¿Qué puedo hacer por ti?,,Mitä voin tehdä sinulle?,Que puis-je faire pour vous?,Mit tehetek érted?,Cosa posso fare per te?,それで何か用か?,무엇을 도와줄까.,Wat kan ik voor je doen?,Hva kan jeg gjøre for deg?,Co mogę zrobić dla ciebie?,Como posso te ajudar?,,Ce pot face pentru tine?,Чем я могу тебе помочь?,,Senin için ne yapabilirim? -I'm out of bullets.,TXT_RPLY0_SCRIPT34_D12128_IMOUT,〃,,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Minulta on luodit loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Skończyły mi się naboje.,Estou sem munição.,,Nu mai am gloanțe.,У меня кончились патроны.,,Mermim bitti. +A ver qué puedo hacer.","Kylläpä olet huonossa jamassa. Katsotaan, mitä voin tehdä.","Mon petit, vous êtes dans un sale état. Je vais voir ce que je peux faire.","Öregem, elég ramaty állapotban vagy. Megnézem mit tehetek.","Ragazzo, sei messo proprio male. Vediamo cosa posso fare.",君、滅茶苦茶だな。なんとかしよう。,치료가 다 끝났습니다. 다 의료기술 덕입니다.,"Jongen, je bent een echte puinhoop. Ik zal zien wat ik kan doen.","Jøss, du er et skikkelig rot. Jeg skal se hva jeg kan gjøre.","Chłopcze, masz niezły bałagan. Zobaczę, co da się zrobić.","Rapaz, você está arrebentado. Verei o que posso fazer.",,"Băiete, ești un dezastru. O să văd ce pot face.","Ты просто месиво. Посмотрим, что я смогу сделать.",,Du är en riktig röra. Jag ska se vad jag kan göra.,Gerçekten berbat durumdasın. Ne yapabileceğime bakacağım. +What can I do for you?,TXT_DLG_SCRIPT34_D12128_WHATC,"MAP34: Feris (identical to rows 746-768, except for row 1357).",,,Co pro tebe můžu udělat?,Hvad kan jeg gøre for dig?,Was kann ich für dich tun?,,Kion mi faru por vi?,¿Qué puedo hacer por ti?,,Mitä voin tehdä sinulle?,Que puis-je faire pour vous?,Mit tehetek érted?,Cosa posso fare per te?,それで何か用か?,무엇을 도와줄까.,Wat kan ik voor je doen?,Hva kan jeg gjøre for deg?,Co mogę zrobić dla ciebie?,Como posso te ajudar?,,Ce pot face pentru tine?,Чем я могу тебе помочь?,,Vad kan jag göra för dig?,Senin için ne yapabilirim? +I'm out of bullets.,TXT_RPLY0_SCRIPT34_D12128_IMOUT,〃,,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Minulta on luodit loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Skończyły mi się naboje.,Estou sem munição.,,Nu mai am gloanțe.,У меня кончились патроны.,,Jag har slut på kulor.,Mermim bitti. Here's some ammo for you. Don't waste it.,TXT_RYES0_SCRIPT34_D12128_HERES,〃,,,"Tady máš nějakou munici, neplýtvej s ní.",Her er lidt ammunition til dig. Spild det ikke.,Hier hast du welche. Verschwende sie nicht.,,"Jen iom da municio. Ne malŝparu ĝin.","Aquí tienes algo de munición. -No la desperdicies.",,Tässä sinulle panoksia. Älä tuhlaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van valamennyi lőszer. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,無駄遣いするなよ。,조금만 주겠습니다. 재고가 모자라거든요.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Tu jest trochę amunicji dla ciebie. Nie marnuj jej.,Leve esta munição. Não desperdice.,,Iată niște muniție. N-o irosi.,Можешь взять немного. Не трать их понапрасну.,,Al sana biraz mermi. Boşa harcama. -Teach me.,TXT_RPLY1_SCRIPT34_D12128_TEACH,〃,,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Taníts.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. +No la desperdicies.",,Tässä sinulle panoksia. Älä tuhlaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van valamennyi lőszer. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,無駄遣いするなよ。,조금만 주겠습니다. 재고가 모자라거든요.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Tu jest trochę amunicji dla ciebie. Nie marnuj jej.,Leve esta munição. Não desperdice.,,Iată niște muniție. N-o irosi.,Можешь взять немного. Не трать их понапрасну.,,Här är lite ammunition till dig. Slösa inte bort den.,Al sana biraz mermi. Boşa harcama. +Teach me.,TXT_RPLY1_SCRIPT34_D12128_TEACH,〃,,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Taníts.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. "All right, I'll just show you a few little pointers.",TXT_RYES1_SCRIPT34_D12128_ALLRI,〃,,,"Dobře, ukážu ti pár rad.","Okay, jeg vil bare vise dig et par små tips.","Alles klar, ich zeige dir ein paar Kniffe.",,"Bone, jen kelkaj konsiletoj...","Muy bien, aquí van -un par de consejos...",,"Hyvä on, annan sinulle vain muutamia pikkuvinkkejä.",Pas de problème. Laissez moi vous montrer quelques trucs.,Akkor addok pár hasznos tanácsot.,"Va bene, ti darò un paio di dritte molto utili.",わかった、幾つかやり方を教えよう。,좋습니다. 움직이는 과녁을 쏘세요!,"Oké, ik zal je gewoon een paar kleine tips laten zien.","Greit, jeg skal bare vise deg noen små tips.","W porządku, pokażę ci tylko kilka małych wskazówek.","Ok, vou te dar algumas dicas.",,"În regulă, am să-ți arăt niște repere.",Хорошо. Покажу тебе пару приёмов.,,"Pekala, sana birkaç küçük ipucu göstereceğim." +un par de consejos...",,"Hyvä on, annan sinulle vain muutamia pikkuvinkkejä.",Pas de problème. Laissez moi vous montrer quelques trucs.,Akkor addok pár hasznos tanácsot.,"Va bene, ti darò un paio di dritte molto utili.",わかった、幾つかやり方を教えよう。,좋습니다. 움직이는 과녁을 쏘세요!,"Oké, ik zal je gewoon een paar kleine tips laten zien.","Greit, jeg skal bare vise deg noen små tips.","W porządku, pokażę ci tylko kilka małych wskazówek.","Ok, vou te dar algumas dicas.",,"În regulă, am să-ți arăt niște repere.",Хорошо. Покажу тебе пару приёмов.,,"Okej, jag ska bara visa dig några små tips.","Pekala, sana birkaç küçük ipucu göstereceğim." You're not ready yet.,TXT_RNO1_SCRIPT34_D12128_YOURE,〃,,,Ještě nejsi připravený.,Du er ikke klar endnu.,Du bist noch nicht so weit.,,"Vi ankoraŭ -ne estas preta.",Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Nem állsz még készen.,Non sei ancora pronto.,そっちの準備がまだ整ってないようだな。,당신은 아직 준비가 안됐어요.,Je bent nog niet klaar.,Du er ikke klar ennå.,Nie jesteś jeszcze gotowy.,Você não está preparado ainda.,,Nu ești pregătit încă.,Ты ещё не готов.,,Henüz hazır değilsin. -Back again? What do you need?,TXT_DLG_SCRIPT34_D13644_BACKA,〃,,,Zase zpátky? Co potřebuješ?,Tilbage igen? Hvad har du brug for?,Scxhon zurück? Was brauchst du?,,Do vi revenis. Kion vi bezonas?,¿Ya de vuelta? ¿Qué necesitas?,,Täällä taas? Mitä tarvitset?,Déjà de retour? De quoi avez-vous besoin?,Már vissza is tértél? Mire van szükséged?,Già di ritorno? Che cosa ti serve?,もう戻ったか?何が必要だ?,다시 왔군요. 무엇이 필요하죠?,Weer terug? Wat heb je nodig?,Tilbake igjen? Hva trenger du?,Znowu? Czego potrzebujesz?,Já voltou? O que precisa?,,Te-ai întors? Ce mai dorești?,Ты вернулся? Что тебе нужно?,,Yine mi? Neye ihtiyacın var? -I'm out of bullets.,TXT_RPLY0_SCRIPT34_D13644_IMOUT,〃,,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Minulta on ammukset loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Skończyły mi się naboje.,Estou sem munição.,,Nu mai am gloanțe.,У меня кончились патроны.,,Mermim bitti. +ne estas preta.",Aún no estás listo.,,Et ole vielä valmis.,Vous n'êtes pas encore prêt.,Nem állsz még készen.,Non sei ancora pronto.,そっちの準備がまだ整ってないようだな。,당신은 아직 준비가 안됐어요.,Je bent nog niet klaar.,Du er ikke klar ennå.,Nie jesteś jeszcze gotowy.,Você não está preparado ainda.,,Nu ești pregătit încă.,Ты ещё не готов.,,Du är inte redo än.,Henüz hazır değilsin. +Back again? What do you need?,TXT_DLG_SCRIPT34_D13644_BACKA,〃,,,Zase zpátky? Co potřebuješ?,Tilbage igen? Hvad har du brug for?,Scxhon zurück? Was brauchst du?,,Do vi revenis. Kion vi bezonas?,¿Ya de vuelta? ¿Qué necesitas?,,Täällä taas? Mitä tarvitset?,Déjà de retour? De quoi avez-vous besoin?,Már vissza is tértél? Mire van szükséged?,Già di ritorno? Che cosa ti serve?,もう戻ったか?何が必要だ?,다시 왔군요. 무엇이 필요하죠?,Weer terug? Wat heb je nodig?,Tilbake igjen? Hva trenger du?,Znowu? Czego potrzebujesz?,Já voltou? O que precisa?,,Te-ai întors? Ce mai dorești?,Ты вернулся? Что тебе нужно?,,Tillbaka igen? Vad behöver du?,Yine mi? Neye ihtiyacın var? +I'm out of bullets.,TXT_RPLY0_SCRIPT34_D13644_IMOUT,〃,,,Došly mi náboje.,Jeg er løbet tør for kugler.,Ich habe keine Munition mehr.,,Mi estas sen kugloj.,No me quedan balas.,,Minulta on ammukset loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 바닥났어요.,Ik heb geen kogels meer.,Jeg er tom for kuler.,Skończyły mi się naboje.,Estou sem munição.,,Nu mai am gloanțe.,У меня кончились патроны.,,Jag har slut på kulor.,Mermim bitti. Here's some ammo for you. Don't waste it.,TXT_RYES0_SCRIPT34_D13644_HERES,〃,,,"Tady máš nějakou munici, neplýtvej s ní.",Her er lidt ammunition til dig. Spild det ikke.,Hier hast du welche. Verschwende sie nicht.,,"Jen iom da municio. Ne malŝparu ĝin.","Aquí tienes algo de munición. -No la desperdicies.",,Tässä vähän lisää. Älä haaskaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van valamennyi lőszer. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾を使え、無駄遣いするなよ。,"적을 사살하려면, 역시 탄약을 소진해야만 하죠. 여기 탄약입니다.",Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Tu jest trochę amunicji dla ciebie. Nie marnuj jej.,Leve esta munição. Não desperdice.,,Iată niște muniție. N-o irosi.,Можешь взять немного. Не трать их понапрасну.,,İşte sana biraz cephane. Boşa harcama. -You've got enough ammo.,TXT_RNO0_SCRIPT34_D13644_YOUVE,〃,,,Vždyť jich máš dost.,Du har ammunition nok.,Du hast genug.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ma veramente ne hai a sufficienza.,もう十分に弾を持ってるようだぞ。,충분한 탄약을 가졌어. 다 소진하고 찾아오세요.,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz wystarczająco dużo amunicji.,Você já tem munição suficiente.,,Ai suficientă muniție.,У тебя их достаточно.,,Yeterince mermin var. -Teach me.,TXT_RPLY1_SCRIPT34_D13644_TEACH,〃,,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Taníts.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. +No la desperdicies.",,Tässä vähän lisää. Älä haaskaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van valamennyi lőszer. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾を使え、無駄遣いするなよ。,"적을 사살하려면, 역시 탄약을 소진해야만 하죠. 여기 탄약입니다.",Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Tu jest trochę amunicji dla ciebie. Nie marnuj jej.,Leve esta munição. Não desperdice.,,Iată niște muniție. N-o irosi.,Можешь взять немного. Не трать их понапрасну.,,Här är lite ammunition till dig. Slösa inte bort den.,İşte sana biraz cephane. Boşa harcama. +You've got enough ammo.,TXT_RNO0_SCRIPT34_D13644_YOUVE,〃,,,Vždyť jich máš dost.,Du har ammunition nok.,Du hast genug.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ma veramente ne hai a sufficienza.,もう十分に弾を持ってるようだぞ。,충분한 탄약을 가졌어. 다 소진하고 찾아오세요.,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz wystarczająco dużo amunicji.,Você já tem munição suficiente.,,Ai suficientă muniție.,У тебя их достаточно.,,Du har tillräckligt med ammunition.,Yeterince mermin var. +Teach me.,TXT_RPLY1_SCRIPT34_D13644_TEACH,〃,,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Taníts.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. "All right, this should keep you going for a while.",TXT_RYES1_SCRIPT34_D13644_ALLRI,〃,,,"Dobře, tohle by ti mělo pomoct.","Okay, det her burde holde dig i gang et stykke tid.","Alles klar, das sollte fürs erste reichen.",,"Bone, ĉi tio devus esti sufiĉe utila nuntempe.","Muy bien, esto debería -servirte por el momento.",,"Selvä on, tällä sinun pitäisi pötkiä aika pitkälle.","Bien, ça devrait vous suffir pour un bon moment.","Rendben van, ezzel el leszel egy darabig.","Va bene, con questo dovresti andare sul sicuro per un pò.",わかった、これで長くやり合えるだろう。,"여기, 적병 일부를 충분히 죽일 수 있을 만큼의 탄약입니다.","Oké, dit zou je een tijdje op de been moeten houden.","Greit, dette burde holde deg gående en stund.","W porządku, to powinno ci wystarczyć na jakiś czas.","Ok, isso deve te ajudar por enquanto.",,"Bine, asta ar trebui să te ajute o vreme.","Хорошо, это не раз спасёт тебе жизнь.",,"Pekala, bu seni bir süre idare eder." +servirte por el momento.",,"Selvä on, tällä sinun pitäisi pötkiä aika pitkälle.","Bien, ça devrait vous suffir pour un bon moment.","Rendben van, ezzel el leszel egy darabig.","Va bene, con questo dovresti andare sul sicuro per un pò.",わかった、これで長くやり合えるだろう。,"여기, 적병 일부를 충분히 죽일 수 있을 만큼의 탄약입니다.","Oké, dit zou je een tijdje op de been moeten houden.","Greit, dette burde holde deg gående en stund.","W porządku, to powinno ci wystarczyć na jakiś czas.","Ok, isso deve te ajudar por enquanto.",,"Bine, asta ar trebui să te ajute o vreme.","Хорошо, это не раз спасёт тебе жизнь.",,"Okej, det här borde hålla dig igång ett tag.","Pekala, bu seni bir süre idare eder." "Sorry, can't. I'm just following Macil's orders.",TXT_RNO1_SCRIPT34_D13644_SORRY,〃,,,"Promiň, nemůžu. Řídím se rozkazy od Macila.","Beklager, jeg kan ikke. Jeg følger bare Macils ordrer.","Tut mir leid, aber ich kann nicht. Ich folge nur Macils Befehlen.",,"Pardonon, mi ne rajtas. Mi nur observas Macil-on.","Lo siento, no puedo. -Solo sigo órdenes de Macil.",,Valitettavasti en voi. Noudatan vain Macilin käskyjä.,"Désolé, pas possible. Je ne fais que suivre les ordres de Macil.","Sajnálom, de nem tehetem. Macil utasítása.","Mi spiace, ma non posso. Ordini dall'alto.",すまないが、できない。マシルの命令だ。,마실 사령관님의 명령입니다. 그럴 수는 없어요.,"Sorry, dat kan niet. Ik volg gewoon de orders van Macil op.","Beklager, jeg kan ikke. Jeg følger bare Macils ordre.","Przepraszam, nie mogę. Wykonuję tylko rozkazy Macila.",Desculpe mas não posso. Só estou seguindo as ordens do Macil.,,"Scuze, nu pot. Eu doar umez ordinele lui Macil.","Увы, не могу. Я подчиняюсь Мэйсилу.",,"Üzgünüm, yapamam. Macil'in emirlerini uyguluyorum." +Solo sigo órdenes de Macil.",,Valitettavasti en voi. Noudatan vain Macilin käskyjä.,"Désolé, pas possible. Je ne fais que suivre les ordres de Macil.","Sajnálom, de nem tehetem. Macil utasítása.","Mi spiace, ma non posso. Ordini dall'alto.",すまないが、できない。マシルの命令だ。,마실 사령관님의 명령입니다. 그럴 수는 없어요.,"Sorry, dat kan niet. Ik volg gewoon de orders van Macil op.","Beklager, jeg kan ikke. Jeg følger bare Macils ordre.","Przepraszam, nie mogę. Wykonuję tylko rozkazy Macila.",Desculpe mas não posso. Só estou seguindo as ordens do Macil.,,"Scuze, nu pot. Eu doar umez ordinele lui Macil.","Увы, не могу. Я подчиняюсь Мэйсилу.",,"Tyvärr, jag kan inte. Jag följer bara Macils order.","Üzgünüm, yapamam. Macil'in emirlerini uyguluyorum." "Well which is it, bullets or training? I can't wait to get my hands on those new weapons we captured. Once I get done with them, I'll be able to begin training everyone else.",TXT_DLG_SCRIPT34_D15160_WELLW,〃,,,"Tak co to bude, náboje nebo trénink? Nemůžu se dočkat, až se dostanu k těm novým zbraním, které jsme zabavili. Trocha cvičení a pak hodně odplaty.","Nå, hvad er det, kugler eller træning? Jeg kan ikke vente med at få fingrene i de nye våben, vi har taget til fange. Når jeg er færdig med dem, kan jeg begynde at træne alle de andre.","Also, was willst du? Munition oder Training? Ich kann kaum erwarten, diese neuen Waffen, die wir erbeutet haben, in die Finger zu kriegen. ein bisschen Training und dann jede Menge Vergeltung.",,"Nu, ĉu kugloj aŭ trejnado ĉi-foje? Mi sopire atendas provi tiujn novajn kaptitajn armilojn. Fininte tion, mi povos ektrejni la aliajn.","Bueno, ¿qué va a ser?, ¿balas o entrenamiento? No puedo esperar a poner mis manos en esas nuevas armas que hemos capturado. En cuanto termine, podré empezar a entrenar al resto.","Bueno, ¿qué va a ser?, ¿balas o entrenamiento? No puedo esperar a poner mis manos en esas nuevas armas que capturamos. En cuanto termine, voy a poder empezar a entrenar al resto.","No niin, kumpaa saisi olla: luoteja vai koulutusta? En voi malttaa olla tarttumasta vasta kaappaamiimme aseisiin. Hieman perehdytystä, ja sitten paljon kostamista.","Qu'est-ce qu'il vous faut? Des munitions ou de l'entraînement? J'ai hâte d'essayer ces nouvelles armes que l'on a capturé. Quand j'en aurai fini avec elles, je pourrai entraîner tout le monde.","Akkor mi lesz, ólom vagy tréning? Már alig várom, hogy kipróbáljam az újonnan zsákmányolt fegyvereket. Ha végeztem velük, mindenki mást is fel tudok készíteni.","Bene, che cosa ti serve, munizioni o addestramento? Non vedo l'ora di mettere le mani su quelle nuove armi che abbiamo preso. Un pò di addestramento e poi molta vendetta.","弾薬と訓練、どっちの用件だ? 奪った新しい武器が届くのを待ち切れないです。 -少しの訓練でデカい復讐を。",탄약보급? 훈련? 가능하면 모두 다 가능합니다! 그리고 방금 수송된 무기들을 만져보고 싶습니다. 조사가 끝난 뒤에는 모두가 특수 훈련을 받을 수 있을 거에요.,"Wat is het dan wel, kogels of training? Ik kan niet wachten om die nieuwe wapens in handen te krijgen die we gevangen genomen hebben. Als ik er klaar mee ben, kan ik beginnen met het trainen van alle anderen.","Hva er det, kuler eller trening? Jeg gleder meg til å få tak i de nye våpnene vi tok. Når jeg er ferdig med dem, kan jeg begynne å trene alle de andre.","Więc co to jest, kule czy trening? Nie mogę się doczekać, aż dostanę w swoje ręce tę nową broń, którą zdobyliśmy. Jak już się z nimi uporam, będę mógł zacząć szkolić wszystkich innych.","Bem, o que vai ser? Munição ou treinamento? Mal posso esperar pra pegar nessas novas armas que capturamos. Depois que eu terminar com eles, vou poder começar a treinar todo o pessoal.",,"Deci care e, gloanțe sau instruire? Abia aștept să pun mâna pe armele pe care le-am capturat. Odată ce termin cu ele îi voi putea instrui și pe ceilalți.","Что теперь, патроны или тренировка? Мне не терпится опробовать это новое трофейное оружие. Чуть-чуть тренировки, и они за всё заплатят.",,"Hangisi, mermi mi eğitim mi? Yakaladığımız şu yeni silahları elime almak için sabırsızlanıyorum. Onlarla işim bittiğinde, diğer herkesi eğitmeye başlayabileceğim." -I'm out of ammo.,TXT_RPLY0_SCRIPT34_D15160_IMOUT,〃,,,Došly mi náboje.,Jeg er løbet tør for ammunition.,Ich habe keine Munition mehr.,,Mi estas sen municio.,No me queda munición.,,Minulta on panokset loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 떨어졌어요.,Ik heb geen munitie meer.,Jeg er tom for ammunisjon.,Skończyła mi się amunicja.,Estou sem munição.,,Nu mai am gloanțe.,У меня кончились боеприпасы.,,Mermim bitti. +少しの訓練でデカい復讐を。",탄약보급? 훈련? 가능하면 모두 다 가능합니다! 그리고 방금 수송된 무기들을 만져보고 싶습니다. 조사가 끝난 뒤에는 모두가 특수 훈련을 받을 수 있을 거에요.,"Wat is het dan wel, kogels of training? Ik kan niet wachten om die nieuwe wapens in handen te krijgen die we gevangen genomen hebben. Als ik er klaar mee ben, kan ik beginnen met het trainen van alle anderen.","Hva er det, kuler eller trening? Jeg gleder meg til å få tak i de nye våpnene vi tok. Når jeg er ferdig med dem, kan jeg begynne å trene alle de andre.","Więc co to jest, kule czy trening? Nie mogę się doczekać, aż dostanę w swoje ręce tę nową broń, którą zdobyliśmy. Jak już się z nimi uporam, będę mógł zacząć szkolić wszystkich innych.","Bem, o que vai ser? Munição ou treinamento? Mal posso esperar pra pegar nessas novas armas que capturamos. Depois que eu terminar com eles, vou poder começar a treinar todo o pessoal.",,"Deci care e, gloanțe sau instruire? Abia aștept să pun mâna pe armele pe care le-am capturat. Odată ce termin cu ele îi voi putea instrui și pe ceilalți.","Что теперь, патроны или тренировка? Мне не терпится опробовать это новое трофейное оружие. Чуть-чуть тренировки, и они за всё заплатят.",,"Vad är det, kulor eller träning? Jag kan inte vänta på att få ta del av de nya vapnen som vi tog till fånga. När jag är klar med dem kan jag börja träna alla andra.","Hangisi, mermi mi eğitim mi? Yakaladığımız şu yeni silahları elime almak için sabırsızlanıyorum. Onlarla işim bittiğinde, diğer herkesi eğitmeye başlayabileceğim." +I'm out of ammo.,TXT_RPLY0_SCRIPT34_D15160_IMOUT,〃,,,Došly mi náboje.,Jeg er løbet tør for ammunition.,Ich habe keine Munition mehr.,,Mi estas sen municio.,No me queda munición.,,Minulta on panokset loppu.,Je suis à cours de munitions.,Kifogytam a lőszerből.,Ho finito le munizioni.,弾切れだ。,탄약이 떨어졌어요.,Ik heb geen munitie meer.,Jeg er tom for ammunisjon.,Skończyła mi się amunicja.,Estou sem munição.,,Nu mai am gloanțe.,У меня кончились боеприпасы.,,Jag har slut på ammunition.,Mermim bitti. Here's some ammo for you. Don't waste it.,TXT_RYES0_SCRIPT34_D15160_HERES,〃,,,"Tady máš nějakou munici, neplýtvej s ní.",Her er noget ammunition til dig. Spild det ikke.,Hier hast du welche. Verschwende sie nicht.,,"Jen iom da municio. Ne malŝparu ĝin.","Aquí tienes algo de munición. -No la desperdicies.",,Tässä ammuksia. Älä tuhlaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van valamennyi lőszer. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,조금 나눠주도록 하겠습니다. 부디 낭비하지 마시길.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Tu jest trochę amunicji dla ciebie. Nie marnuj jej.,Leve esta munição. Não desperdice.,,Iată niște muniție. N-o irosi.,Можешь взять немного. Не трать их понапрасну.,,Al sana biraz cephane. Boşa harcama. -You've got enough ammo.,TXT_RNO0_SCRIPT34_D15160_YOUVE,〃,,,Vždyť jich máš dost.,Du har ammunition nok.,Du hast genug.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ma veramente ne hai a sufficienza.,もう十分に弾を持ってるようだぞ。,충분한 탄약을 가졌군...,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz wystarczającą ilość amunicji.,Você já tem munição suficiente.,,Ai suficientă muniție.,У тебя хватает патронов.,,Yeterince cephanen var. -Teach me.,TXT_RPLY1_SCRIPT34_D15160_TEACH,〃,,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Taníts.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Öğret bana. +No la desperdicies.",,Tässä ammuksia. Älä tuhlaa niitä.,"En voilà pour vous, ne les gaspillez pas.",Itt van valamennyi lőszer. Ne pazarold el.,Ecco un pò di munizioni per te. Non sprecarle.,この弾をどうぞ、無駄遣いしないように。,조금 나눠주도록 하겠습니다. 부디 낭비하지 마시길.,Hier is wat munitie voor je. Verspil het niet.,Her er litt ammunisjon til deg. Ikke sløs den bort.,Tu jest trochę amunicji dla ciebie. Nie marnuj jej.,Leve esta munição. Não desperdice.,,Iată niște muniție. N-o irosi.,Можешь взять немного. Не трать их понапрасну.,,Här är lite ammunition till dig. Slösa inte bort den.,Al sana biraz cephane. Boşa harcama. +You've got enough ammo.,TXT_RNO0_SCRIPT34_D15160_YOUVE,〃,,,Vždyť jich máš dost.,Du har ammunition nok.,Du hast genug.,,Vi havas sufiĉe da municio.,Tienes suficiente munición.,,Sinulla on riittävästi ammuksia.,Vous avez assez de munitions.,Van elég lőszered.,Ma veramente ne hai a sufficienza.,もう十分に弾を持ってるようだぞ。,충분한 탄약을 가졌군...,Je hebt genoeg munitie.,Du har nok ammunisjon.,Masz wystarczającą ilość amunicji.,Você já tem munição suficiente.,,Ai suficientă muniție.,У тебя хватает патронов.,,Du har tillräckligt med ammunition.,Yeterince cephanen var. +Teach me.,TXT_RPLY1_SCRIPT34_D15160_TEACH,〃,,,Uč mě.,Lær mig det.,Unterrichte mich.,,Trejnu min.,Entréname.,,Kouluta minua.,Apprenez-moi.,Taníts.,Dammi dell'altro addestramento.,教えてくれ。,가르쳐 줘.,Leer het me.,Lær meg det.,Naucz mnie.,Me ensine.,,Învață-mă.,Обучи меня.,,Lär mig.,Öğret bana. O.K. Take what you've learned and show those Order bastards the way to hell.,TXT_RYES1_SCRIPT34_D15160_OKTAK,〃,,,"Oukej. Pamatuj, co ses tady naučil, a ukaž těm hajzlům z Řádu cestu do pekla.",O.K. Tag det du har lært og vis de ordens-svin vejen til helvede.,"OK. Nutze, was du hier gelernt hast um diesen Tölpeln vom Orden den Weg in die Hölle zu zeigen.",,"Bone. Uzu ĉi tion por gvidi tiujn aĉulojn de La Ordono al la infero.","Bien. Usa lo aprendido para guiar a esos majaderos de La Orden al infierno.","Bien. Usa lo aprendido para guiar a esos desgraciados de La Orden al infierno.","OK. Hyödynnä täällä oppimaasi, ja näytä niille Veljeskunnan valopäille tie helvettiin.",OK. Utilisez ce que vous avez appris et envoyez ces abrutis de l'Ordre en enfer.,"Rendben is vagyunk, mutasd meg a Rend kutyáknak a pokolba vezető utat!",O.K. Usa ciò che hai imparato qua per mostrare all'Ordine la via dell'Inferno.,"オーケー、ここで学んだ事を生かして -オーダー共を地獄に送って上げなさい。",이제 당신은 더 똑똑해졌습니다. 저 멍청한 오더 놈들에게 쓴맛을 보여주세요!,"Oké, neem wat je geleerd hebt en laat die ordeklootzakken de weg naar de hel zien.",OK. Ta det du har lært og vis de jævlene fra Ordenen veien til helvete.,"Weź to, czego się nauczyłeś i pokaż tym draniom z Zakonu drogę do piekła.",Ok. Use o que você aprendeu e mostre o caminho pro inferno para esses desgraçados da Ordem.,,"O.K. Cu ceea ce ai învățat, trimite-i pe nemernicii Ordinului către infern.","Запоминай внимательно, покажешь этим прихвостням Ордена быструю дорогу в ад.",,Tamam. Öğrendiklerini al ve o Tarikat piçlerine cehennemin yolunu göster. +オーダー共を地獄に送って上げなさい。",이제 당신은 더 똑똑해졌습니다. 저 멍청한 오더 놈들에게 쓴맛을 보여주세요!,"Oké, neem wat je geleerd hebt en laat die ordeklootzakken de weg naar de hel zien.",OK. Ta det du har lært og vis de jævlene fra Ordenen veien til helvete.,"Weź to, czego się nauczyłeś i pokaż tym draniom z Zakonu drogę do piekła.",Ok. Use o que você aprendeu e mostre o caminho pro inferno para esses desgraçados da Ordem.,,"O.K. Cu ceea ce ai învățat, trimite-i pe nemernicii Ordinului către infern.","Запоминай внимательно, покажешь этим прихвостням Ордена быструю дорогу в ад.",,Okej. Ta det du lärt dig och visa de där orderjävlarna vägen till helvetet.,Tamam. Öğrendiklerini al ve o Tarikat piçlerine cehennemin yolunu göster. "Come back later, when Macil says it's time.",TXT_RNO1_SCRIPT34_D15160_COMEB,〃,,,"Přijď někdy jindy, až řekne Macil.","Kom tilbage senere, når Macil siger, det er tid.","Komm wieder, wenn Macil dir Bescheid gibt.",,"Revenu post kiam Macil ordonis tion.","Vuelve más tarde cuando -Macil diga que ya es la hora.",,"Palaa asiaan myöhemmin, kun Macil näyttää vihreää valoa.",Revenez plus tard quand Macil décide qu'il est temps.,"Gyere vissza akkor, ha azt mondja Macil hogy ideje van.","Ritorna più tardi, quando Macil dirà che è il momento.",マシルの命令を受けてから、また来い。,마실 사령관님이 준비되었다고 말했을 때 와주세요.,"Kom later terug, als Macil zegt dat het tijd is.","Kom tilbake senere, når Macil sier det er på tide.","Wróć później, kiedy Macil powie, że już czas.","Volte mais tarde, quando o Macil disser que é hora.",,"Revin-o mai încolo, când Macil zice că e timpul.","Приходи позже, когда прикажет Мэйсил.",,Macil zamanı geldiğini söylediğinde geri gel. +Macil diga que ya es la hora.",,"Palaa asiaan myöhemmin, kun Macil näyttää vihreää valoa.",Revenez plus tard quand Macil décide qu'il est temps.,"Gyere vissza akkor, ha azt mondja Macil hogy ideje van.","Ritorna più tardi, quando Macil dirà che è il momento.",マシルの命令を受けてから、また来い。,마실 사령관님이 준비되었다고 말했을 때 와주세요.,"Kom later terug, als Macil zegt dat het tijd is.","Kom tilbake senere, når Macil sier det er på tide.","Wróć później, kiedy Macil powie, że już czas.","Volte mais tarde, quando o Macil disser que é hora.",,"Revin-o mai încolo, când Macil zice că e timpul.","Приходи позже, когда прикажет Мэйсил.",,"Kom tillbaka senare, när Macil säger att det är dags.",Macil zamanı geldiğini söylediğinde geri gel. I've taught you everything I can right now. Give me some time to put the new weapons through their paces. That is unless you're out of bullets.,TXT_DLG_SCRIPT34_D16676_IVETA,〃,,,"Naučil jsem tě vše, co teď můžu. Dej mi nějaký čas, abych vyzkoušel ty nové zbraně. Jedině, že bys potřeboval náboje.","Jeg har lært dig alt, hvad jeg kan lige nu. Giv mig lidt tid til at sætte de nye våben på prøve. Medmindre du er løbet tør for kugler.","Ich habe dir alles gezeigt, was ich momentan kann. Gib mir etwas Zeit um die neuen Waffen zu testen. Munition kriegst du natürlich auch so.",,"Mi instruis al vi ĉion, kion mi povas. Donu tempon al mi por elprovi la novajn armilojn... krom se vi nur bezonas pliajn kuglojn.","Te he enseñado todo lo que puedo por ahora. Dame tiempo para probar al 100% las nuevas armas... a menos que solo necesites más balas, claro.","Ya te enseñé todo lo que puedo por ahora. Dame tiempo para probar al 100% las nuevas armas... a menos que solo necesites más balas, claro.","Olen opettanut sinulle kaiken, mitä itse juuri nyt osaan. Anna minulle vähän aikaa käydä läpi uusien aseiden askelkuvioita. Ellei sinulla sitten ole luodit lopussa.","Je vous ai enseigné tout ce que je sais. Laissez moi un peu de temps pour tester ces nouvelles armes. Sauf si vous n'avez plus de munitions, bien sûr.","Megtanítottam mindent amit jelenleg tudtam. Adj egy kis időt, hogy leteszteljem a fegyvereket. Kivétel persze ha lőszer kell.",Ti ho insegnato tutto quello che potevo per ora. Dammi dell'altro tempo per mettere le nuove armi alla prova. A meno che non ti servano altre munizioni.,"私が教えられる事はもう無い。 今後新しい武器は時間が掛かるが 自分のペースで学んだ方がいい。 -弾切れでなければの話だが。","배울 수 있는 모든 것들을 배우셨습니다. 이제 보급할 시간을 좀 주세요. 말이 나와서 하는 말인데, 탄약이 필요하십니까?",Ik heb je alles geleerd wat ik nu kan. Geef me wat tijd om de nieuwe wapens op de proef te stellen. Tenzij je geen kogels meer hebt.,Jeg har lært deg alt jeg kan for øyeblikket. Gi meg litt tid til å teste de nye våpnene. Med mindre du er tom for kuler.,"Nauczyłem cię wszystkiego, co mogę teraz. Dajcie mi trochę czasu, żeby przetestować nową broń. Chyba, że skończyły ci się naboje.",Te ensinei tudo o que eu posso no momento. Me dê um tempo para testar as novas armas. A não ser que você esteja sem munição.,,Te-am învâțat tot ce știu. Dă-mi niște timp să învăț noile arme. Asta în cazul în care nu ai nevoie de gloanțe.,Пока что я не могу научить тебя ничему новому. Дай мне время разобраться в этом новом оружии. Или у тебя закончились патроны?,,Şu anda sana öğretebileceğim her şeyi öğrettim. Yeni silahları denemem için bana biraz zaman ver. Tabii mermin bitmediyse. -Yes I am.,TXT_RPLY0_SCRIPT34_D16676_YESIA,〃,,,"Ano, potřebuju.","Ja, det er jeg.","Ja, bin ich.",,Ĝuste.,Eso mismo.,,Kyllä on.,"En effet, je le suis.",Igen.,Sì che mi servono.,ああ、そうだ。,알겠습니다. 그럼 탄약이라도?,"Ja, dat ben ik wel.","Jo, det har jeg.",Tak.,"Sim, eu estou.",,Da sunt.,"Да, закончились.",,"Evet, bitti." -Here you go.,TXT_RYES0_SCRIPT34_D16676_HEREY,〃,,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,"Tässä, ole hyvä.",Voilà pour vous.,Parancsolj.,Ecco qua.,どうぞ。,여기요!,Alsjeblieft.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici sunt.,Держи.,,Al bakalım. +弾切れでなければの話だが。","배울 수 있는 모든 것들을 배우셨습니다. 이제 보급할 시간을 좀 주세요. 말이 나와서 하는 말인데, 탄약이 필요하십니까?",Ik heb je alles geleerd wat ik nu kan. Geef me wat tijd om de nieuwe wapens op de proef te stellen. Tenzij je geen kogels meer hebt.,Jeg har lært deg alt jeg kan for øyeblikket. Gi meg litt tid til å teste de nye våpnene. Med mindre du er tom for kuler.,"Nauczyłem cię wszystkiego, co mogę teraz. Dajcie mi trochę czasu, żeby przetestować nową broń. Chyba, że skończyły ci się naboje.",Te ensinei tudo o que eu posso no momento. Me dê um tempo para testar as novas armas. A não ser que você esteja sem munição.,,Te-am învâțat tot ce știu. Dă-mi niște timp să învăț noile arme. Asta în cazul în care nu ai nevoie de gloanțe.,Пока что я не могу научить тебя ничему новому. Дай мне время разобраться в этом новом оружии. Или у тебя закончились патроны?,,Jag har lärt dig allt jag kan just nu. Ge mig lite tid att sätta de nya vapnen på prov. Det vill säga om du inte har slut på kulor.,Şu anda sana öğretebileceğim her şeyi öğrettim. Yeni silahları denemem için bana biraz zaman ver. Tabii mermin bitmediyse. +Yes I am.,TXT_RPLY0_SCRIPT34_D16676_YESIA,〃,,,"Ano, potřebuju.","Ja, det er jeg.","Ja, bin ich.",,Ĝuste.,Eso mismo.,,Kyllä on.,"En effet, je le suis.",Igen.,Sì che mi servono.,ああ、そうだ。,알겠습니다. 그럼 탄약이라도?,"Ja, dat ben ik wel.","Jo, det har jeg.",Tak.,"Sim, eu estou.",,Da sunt.,"Да, закончились.",,"Ja, det är jag.","Evet, bitti." +Here you go.,TXT_RYES0_SCRIPT34_D16676_HEREY,〃,,,Tady máš.,Værsgo.,Bitteschön.,,Jen.,Aquí tienes.,,"Tässä, ole hyvä.",Voilà pour vous.,Parancsolj.,Ecco qua.,どうぞ。,여기요!,Alsjeblieft.,Vær så god.,Proszę bardzo.,Aqui está.,,Aici sunt.,Держи.,,Här har du.,Al bakalım. "Don't get trigger happy in the town, you'll set off the alarm and they will start sending in guards from the castle.",TXT_DLG_SCRIPT34_D18192_DONTG,"MAP34: Upstairs. (Identical to row 769)",,,Ať tě nenapadne střílet ve městě. Spustil bys poplach a přivolal stráže z hradu.,"Bliv ikke skydeglad i byen, du vil udløse alarmen, og de vil begynde at sende vagter ind fra slottet.","Fang nicht an, hier in der Stadt herumzuballern. Wenn du hier den Alarm auslöst, senden sie gleich die Truppen aus der Burg.",,Ne uzu pafilon en la urbo; vi ekagigus la alarmon kaj ili eksendus gardistojn el la kastelo.,"No te líes a tiros en el pueblo, que activarás la alarma y empezarán a enviar guardias desde el castillo.","No andes a los tiros en el pueblo, que vas a activar la alarma y van a empezar a mandar guardias desde el castillo.","Älä ala turhan liipaisinherkäksi kaupungilla. Aiheutat vielä hälytyksen, ja ne alkavat lähettää linnasta vartijoita.",Ne tirez pas partout en ville. Vous risquez de déclencher l'alarme et ils enverront tous les gardes du château à vos trousses.,"Ne keresd a bajt a városban. Beindítod a riasztót, és kiküldik érted a kastély őröket.",Non ti consiglio di avere il grilletto facile in città. Finiresti per attivare l'allarme e inizierebbero a mandare guardie dal castello.,"街の中で銃をバンバン撃ったりするんじゃないぞ 警報を鳴らしてしまえば、奴等が衛兵共を -城から送り込んでくるぞ。",무턱대고 마을에서 총질하지 마세요. 경보가 울림과 동시에 당신을 잡기 위해서 모든 병력을 보낼 겁니다.,"Laat de trekker niet gelukkig worden in de stad, je laat de wekker afgaan en ze sturen bewakers van het kasteel naar binnen.","Ikke bli skyteglad i byen, da går alarmen, og de sender inn vakter fra slottet.","Nie daj się sprowokować w mieście, bo podniesiesz alarm i zaczną wysyłać strażników z zamku.","Não saia atirando pela cidade, você vai ativar o alarme e vão mandar os guardas do castelo.",,"Nu deveni prea entuziasmat în oraș, vei declanșa alarma și vor trimite gardieni din castel.","Когда будешь в городе, не стреляй направо и налево. Если ты поднимешь тревогу, они вызовут подкрепление из замка.",,"Kasabada tetiğe basma, alarmı çalıştırırsın ve kaleden muhafızlar göndermeye başlarlar." +城から送り込んでくるぞ。",무턱대고 마을에서 총질하지 마세요. 경보가 울림과 동시에 당신을 잡기 위해서 모든 병력을 보낼 겁니다.,"Laat de trekker niet gelukkig worden in de stad, je laat de wekker afgaan en ze sturen bewakers van het kasteel naar binnen.","Ikke bli skyteglad i byen, da går alarmen, og de sender inn vakter fra slottet.","Nie daj się sprowokować w mieście, bo podniesiesz alarm i zaczną wysyłać strażników z zamku.","Não saia atirando pela cidade, você vai ativar o alarme e vão mandar os guardas do castelo.",,"Nu deveni prea entuziasmat în oraș, vei declanșa alarma și vor trimite gardieni din castel.","Когда будешь в городе, не стреляй направо и налево. Если ты поднимешь тревогу, они вызовут подкрепление из замка.",,"Bli inte skjutglad i staden, du sätter igång larmet och de börjar skicka in vakter från slottet.","Kasabada tetiğe basma, alarmı çalıştırırsın ve kaleden muhafızlar göndermeye başlarlar." "Welcome, we can always use more help.",TXT_DLG_SCRIPT34_D19708_WELCO,"〃 -(Identical to row 770)",,,"Vítej, pomoc se nám vždycky hodí.","Velkommen, vi kan altid bruge mere hjælp.","Willkommen, wir können immer etwas Hilfe gebrauchen.",,Bonvenon. Plia helpo ĉiam estas utilega.,"Bienvenido, siempre nos viene bien algo más de ayuda.",,Tervetuloa; voisimme aina kaivata lisää apua.,Bienvenue. Nous apprécions toute l'aide que nous pouvons recevoir.,"Üdv nálunk, mindig jól jön a segítség.","Benvenuto, ci serve tutto l'aiuto che possiamo ottenere.",ようこそ、我々が貴方の助けに成ります。,어서 오세요. 당신 같은 사람에게는 많은 도움이 필요합니다!,"Welkom, we kunnen altijd meer hulp gebruiken.","Velkommen, vi kan alltid trenge mer hjelp.","Witamy, zawsze przyda nam się więcej pomocy.",Seja bem-vindo. Qualquer ajuda também é sempre bem-vinda.,,"Bun-venit, ajutorul e bine-venit oricând.",Добро пожаловать. Нам всегда пригодится помощь.,,"Hoş geldiniz, her zaman daha fazla yardıma ihtiyacımız olabilir." +(Identical to row 770)",,,"Vítej, pomoc se nám vždycky hodí.","Velkommen, vi kan altid bruge mere hjælp.","Willkommen, wir können immer etwas Hilfe gebrauchen.",,Bonvenon. Plia helpo ĉiam estas utilega.,"Bienvenido, siempre nos viene bien algo más de ayuda.",,Tervetuloa; voisimme aina kaivata lisää apua.,Bienvenue. Nous apprécions toute l'aide que nous pouvons recevoir.,"Üdv nálunk, mindig jól jön a segítség.","Benvenuto, ci serve tutto l'aiuto che possiamo ottenere.",ようこそ、我々が貴方の助けに成ります。,어서 오세요. 당신 같은 사람에게는 많은 도움이 필요합니다!,"Welkom, we kunnen altijd meer hulp gebruiken.","Velkommen, vi kan alltid trenge mer hjelp.","Witamy, zawsze przyda nam się więcej pomocy.",Seja bem-vindo. Qualquer ajuda também é sempre bem-vinda.,,"Bun-venit, ajutorul e bine-venit oricând.",Добро пожаловать. Нам всегда пригодится помощь.,,"Välkommen, vi kan alltid behöva mer hjälp.","Hoş geldiniz, her zaman daha fazla yardıma ihtiyacımız olabilir." "When I was still in action we had the chance to examine an acolyte before the reinforcements arrived, they're not human I tell you.",TXT_DLG_SCRIPT34_D21224_WHENI,"〃 (Similar to row 771)",,,"Když jsem byl ještě v akci, měli jsme možnost prozkoumat mrtvého akolytu předtím, než přišly posily. Poslouchej, nejsou to lidé.","Da jeg stadig var i aktion havde vi mulighed for at undersøge en akolyt før forstærkningerne ankom, de er ikke menneskelige siger jeg jer.","Als ich noch aktiv war, hatten wir mal die Möglichkeit, einen der Ministranten zu untersuchen, bevor Verstärkung eintraf. Hör zu, sie sind nicht menschlich!",,"Kiam mi ankoraŭ estis en misio, ni havis okazon ekzameni akoliton antaŭ ol pliaj malamikoj alvenis, kaj ni malkovris, ke ili ne estas homoj.",Cuando aún estaba en acción tuvimos la oportunidad de examinar a un acólito antes de que llegaran los refuerzos y te digo que no son humanos.,,"Kun itse olin vielä mukana taistelemassa, saimme tilaisuuden tutkia akoluuttia ennen lisäjoukkojen saapumista. Ja kuule tarkkaan, ne eivät ole ihmisiä.","Quand j'étais encore en service, j'ai eu l'opportunité d'examiner un acolyte avant que les renforts n'arrivent. Vous savez, ils ne sont pas humains.","Amikor épp harcoltunk, alkalmunk adódott megvizsgálni egy ministránst amíg az erősítés meg nem érkezett volna. Bizony mondom neked, ezek nem emberek.","Quando ero ancora sul campo di battaglia, abbiamo avuto l'occasione di esaminare uno degli accoliti prima che arrivassero i rinforzi. Ascoltami, non sono umani.","私がまだ活動していた時、我々が増援に 囲まれる前にアコライトを調べる機会が あったんだ。聞いてくれ、奴等は人間では -なかったんだ。",제가 밖에서 근무했을 때 사살한 아콜라이트들을 자세히 들여다본 적이 있었어요. 그 들은 인간이 아니었습니다. 기억하세요.,"Toen ik nog in actie was hadden we de kans om een acoliet te onderzoeken voordat de versterkingen arriveerden, ze zijn niet menselijk, zeg ik je.","Da jeg fortsatt var i aksjon, fikk vi sjansen til å undersøke en akolytt før forsterkningene ankom. De er ikke menneskelige, sier jeg.","Kiedy byłem jeszcze w akcji, mieliśmy okazję zbadać akolitę przed przybyciem posiłków, nie są ludźmi, mówię wam.","Quando eu ainda estava na ativa nós tivemos a oportunidade de examinar um acólito antes dos reforços chegarem. Vai por mim, eles não são humanos.",,"Când încă luam parte la acțiune am avut ocazia să examinez un acolit. înaintă să ajungă întăririle, nu sunt umani.","Пока я был в оперативной группе, нам удалось вскрыть одного из служителей, прежде чем прибыло подкрепление. Так вот, они не люди.",,"Ben hala görevdeyken, takviye kuvvetler gelmeden önce bir yardımcı kişiyi inceleme şansımız oldu, size söylüyorum onlar insan değil." +なかったんだ。",제가 밖에서 근무했을 때 사살한 아콜라이트들을 자세히 들여다본 적이 있었어요. 그 들은 인간이 아니었습니다. 기억하세요.,"Toen ik nog in actie was hadden we de kans om een acoliet te onderzoeken voordat de versterkingen arriveerden, ze zijn niet menselijk, zeg ik je.","Da jeg fortsatt var i aksjon, fikk vi sjansen til å undersøke en akolytt før forsterkningene ankom. De er ikke menneskelige, sier jeg.","Kiedy byłem jeszcze w akcji, mieliśmy okazję zbadać akolitę przed przybyciem posiłków, nie są ludźmi, mówię wam.","Quando eu ainda estava na ativa nós tivemos a oportunidade de examinar um acólito antes dos reforços chegarem. Vai por mim, eles não são humanos.",,"Când încă luam parte la acțiune am avut ocazia să examinez un acolit. înaintă să ajungă întăririle, nu sunt umani.","Пока я был в оперативной группе, нам удалось вскрыть одного из служителей, прежде чем прибыло подкрепление. Так вот, они не люди.",,"När jag fortfarande var i aktion hade vi chansen att undersöka en akolyt innan förstärkningarna kom, de är inte mänskliga säger jag er.","Ben hala görevdeyken, takviye kuvvetler gelmeden önce bir yardımcı kişiyi inceleme şansımız oldu, size söylüyorum onlar insan değil." "We're trying to find where the castle gate mechanisms are, but so far we've had no luck.",TXT_DLG_SCRIPT34_D22740_WERET,"MAP34: Downstairs. (Identical to row 772)",,,"Snažíme se zjistit, kde jsou mechanismy hradní brány, ale zatím jsme nic nenašli.","Vi prøver at finde ud af hvor slottets portmekanismer er, men indtil videre har vi ikke haft held.","Wir versuchen herauszufinden, von wo das Burgtor kontrolliert wird, aber bisher hatten wir kein Glück.",,"Ni provas malkovri, kie troviĝas la mekanismoj de la kastelpordo, sed ni ankoraŭ ne sukcesis.","Estamos intentando descubrir la ubicación de los mecanismos de la puerta del castillo, pero de momento no ha habido suerte.","Estamos tratando de descubrir la ubicación de los mecanismos de la puerta del castillo, pero por ahora no hubo suerte.","Yritämme löytää linnanportin koneistoa, mutta toistaiseksi laihoin tuloksin.","On essaie de trouver où se trouvent les contrôles de la porte du château, mais pour l'instant, on les a pas encore localisés.","Próbáljuk megtalálni a kastély kapu irányító mechanikáját, de eddig nem jártunk sikerrel.","Stiamo cercando di capire dove si trovano i meccanismi di apertura dell'entrata del castello, ma ancora niente.","我々は城門のメカニズムが何処にあるか 探し続けているが、あまり良い結果は出ていない","성문을 열려고 열심히 분석을 해보았습니다만, 결국엔 해답을 찾지 못했습니다.","We proberen te vinden waar de mechanismen van de kasteelpoort zich bevinden, maar tot nu toe hebben we geen geluk gehad.","Vi prøver å finne ut hvor slottets portmekanismer er, men så langt har vi ikke hatt noe hell.","Próbujemy znaleźć gdzie są mechanizmy bramy zamkowej, ale jak na razie nie mamy szczęścia.","Estamos tentando localizar os mecanismos do portão do castelo, mas até agora não tivemos sorte.",,"Încercăm să găsim unde sunt mecanismele castelului, dar n-am avut noroc până acum.","Мы пытаемся найти механизм управления воротами замка, но пока безуспешно. -",,Kale kapısı mekanizmalarının nerede olduğunu bulmaya çalışıyoruz ama şu ana kadar şansımız yaver gitmedi. +",,"Vi försöker ta reda på var mekanismerna för slottets portar finns, men hittills har vi inte haft någon tur.",Kale kapısı mekanizmalarının nerede olduğunu bulmaya çalışıyoruz ama şu ana kadar şansımız yaver gitmedi. "Don't get caught. I've heard horror stories about what they do to our people after they're imprisoned. They just disappear, no traces, nothing. ",TXT_DLG_SCRIPT34_D24256_DONTG,"〃 (Similar to row 773)",,,"Nenech se chytit. Slyšel jsem děsivé příběhy o tom, co dělají našim lidem, když je uvězní. Prostě zmizí... beze stopy.","Bliv ikke fanget. Jeg har hørt skrækhistorier om, hvad de gør ved vores folk, efter de er blevet fængslet. De forsvinder bare, ingen spor, ingenting.","Lass dich nicht erwischen. Ich habe Horrorgeschichten darüber gehört, was sie unseren Leuten antun, die sie gefangengenommen haben. Sie verschwinden einfach... ohne jede Spur.",,"Oni ne kaptu vin. Mi aŭdis terurajn historiojn pri tio, kio okazas al niaj homoj post ilia aresto: ili simple malaperas, nek restaĵoj nek io ajn.",Que no te atrapen. He oído historias terroríficas de lo que hacen con nuestros hombres una vez detenidos: simplemente desaparecen sin rastros ni nada.,,"Älä jää kiinni. Olen kuullut kauhukertomuksia siitä, mitä ne tekevät meidän omillemme, kun he jäävät vangiksi. He yksinkertaisesti katoavat, jälkeä jättämättä.",Ne vous faites pas avoir. J'ai entendu des choses horribles sur ce qu'ils font à ceux qu'ils emprisonnent. Ils disparaîssent... Sans laisser de trace.,"Csak ne kapjanak el. Borzasztó történeteket hallottam azokról akiket bebörtönöztek. Csak úgy nyomuk vész, semmi nyom, konkrétan semmi.","Non farti prendere. Ho sentito storie orribili su quello che fanno alle persone dopo che le catturano. Spariscono completamente, senza tracce, niente di niente.","決して捕まるな。投獄されると奴等が 何をしでかすか怪談として聞く程だ。 -跡形もなく...消される。",오더에게 잡혀가면 절대로 안 됩니다. 수감자들에게 온갖 끔찍한 짓을 저지른다는 이야기를 들은 적이 있었으니까요. 흔적없이 조용히 끌고 간다네요...,"Laat je niet vangen. Ik heb horrorverhalen gehoord over wat ze onze mensen na hun gevangenschap aandoen. Ze verdwijnen gewoon, geen sporen, niets.","Ikke bli tatt. Jeg har hørt skrekkhistorier om hva de gjør med folket vårt etter at de blir fengslet. De bare forsvinner, ingen spor, ingenting.","Nie daj się złapać. Słyszałem przerażające historie o tym, co robią z naszymi ludźmi po uwięzieniu. Po prostu znikają, żadnych śladów, nic.","Não deixe eles te pegarem. Ouvi histórias de terror sobre o que eles fazem com o nosso pessoal depois que são aprisionados. Eles desaparecem, sem deixar rastros.",,Nu fii prins. Am auzit povești de groază legate de ce tratament primesc oamenii odată ce sunt închiși. Pur și simplu dispar fără niciun fel de urmă.,"Не дай себя схватить. Я слышал ужасные истории о том, что они делают с арестованными. Те просто исчезают... без следа.",,"Sakın yakalanmayın. Hapsedildikten sonra insanlarımıza ne yaptıklarına dair korku hikayeleri duydum. Öylece ortadan kayboluyorlar, ne bir iz ne de başka bir şey." +跡形もなく...消される。",오더에게 잡혀가면 절대로 안 됩니다. 수감자들에게 온갖 끔찍한 짓을 저지른다는 이야기를 들은 적이 있었으니까요. 흔적없이 조용히 끌고 간다네요...,"Laat je niet vangen. Ik heb horrorverhalen gehoord over wat ze onze mensen na hun gevangenschap aandoen. Ze verdwijnen gewoon, geen sporen, niets.","Ikke bli tatt. Jeg har hørt skrekkhistorier om hva de gjør med folket vårt etter at de blir fengslet. De bare forsvinner, ingen spor, ingenting.","Nie daj się złapać. Słyszałem przerażające historie o tym, co robią z naszymi ludźmi po uwięzieniu. Po prostu znikają, żadnych śladów, nic.","Não deixe eles te pegarem. Ouvi histórias de terror sobre o que eles fazem com o nosso pessoal depois que são aprisionados. Eles desaparecem, sem deixar rastros.",,Nu fii prins. Am auzit povești de groază legate de ce tratament primesc oamenii odată ce sunt închiși. Pur și simplu dispar fără niciun fel de urmă.,"Не дай себя схватить. Я слышал ужасные истории о том, что они делают с арестованными. Те просто исчезают... без следа.",,"Bli inte ertappad. Jag har hört skräckhistorier om vad de gör med vårt folk efter att de blivit fängslade. De bara försvinner, inga spår, ingenting.","Sakın yakalanmayın. Hapsedildikten sonra insanlarımıza ne yaptıklarına dair korku hikayeleri duydum. Öylece ortadan kayboluyorlar, ne bir iz ne de başka bir şey." "Here's some advice, if you ever see any of the Order's tin soldiers, run the other way. I especially don't like the Reavers, those things are just damned fast!",TXT_DLG_SCRIPT34_D25772_HERES,"〃 (Similar to row 774)",,,"Dám ti radu: Jestli někdy uvidíš jednoho z plecháčků Řádu, otoč se a jdi. Jsou rychlí a suroví.","Her er et godt råd: Hvis du nogensinde ser nogen af Ordenens tinsoldater, så løb den anden vej. Jeg kan især ikke lide Reavers, de er bare forbandet hurtige!","Hier ist ein guter Rat, falls du jemals einen dieser Zinnsoldaten des Ordens vorbeigehen siehst. Sie sind schnell und brutal. ",,"Jen konsilo: estu ĉiam fore de la artefaritaj soldatoj de La Ordono. Mi plej malŝatas Lertajn Robotojn, ili estas rapidegaj!",Un consejo: mantente siempre alejado de los soldados artificiales de La Orden. Los Saqueadores son los peores; ¡esas cosas son jodidamente rápidas!,Un consejo: mantente siempre alejado de los soldados artificiales de La Orden. Los Saqueadores son los peores; ¡esos desgraciados son rápidos!,"Annan pienen vinkin: Jos koskaan näet Veljeskunnan tinasotilaita, juokse toiseen suuntaan. Inhoan varsinkin raastajia; ne ovat vaan niin pirun nopeita!","Voilà un conseil. Si vous voyez un des soldats mécanisés de l'Ordre, retournez vous et courez. Ils sont rapides et brutaux. J'aime surtout pas les Reavers, ces satanés trucs vont trop vite!","Az a tanácsom számodra, hogy ha meglátod a Rend ólomkatonáit, vedd az utad az ellentétes irányba. Különösen igaz ez a fosztogatókra, piszkosul gyorsak.","Ecco un consiglio. Se vedi uno dei soldatini di latta dell'Ordine, vai nella direzione opposta. In particolare temo i Reaver, quei dannati robot sono davvero veloci!","伝えておく、オーダーの錫兵は 他方から呼び出され押し寄せてくる。 -奴等は素早く残忍だ。","충고 하나 해주죠. 오더의 로봇 병사들을 발견한다면, 조용히 피해가세요. 특히나 성가신 놈 중 하나가 리버인데, 그놈의 산탄총은 장난 아니에요!","Hier is een advies, als je ooit een van de tinnen soldaten van de Orde ziet, ren dan de andere kant op. Ik hou vooral niet van de Reavers, die dingen zijn gewoon verdomd snel!","Hvis du ser noen av Ordenens tinnsoldater, så løp den andre veien. Jeg liker spesielt ikke Reavers, de er så jævla raske!","Oto rada, jeśli kiedykolwiek zobaczysz któregoś z blaszanych żołnierzy Zakonu, uciekaj w drugą stronę. Szczególnie nie lubię Łupieżców, te rzeczy są cholernie szybkie!","Um conselho pra você: se você ver algum desses soldados de lata da Ordem, fuja para o lado oposto. Eu particularmente detesto os Saqueadores. Eles são rapidos pra caramba!",,"Iată un sfat, dacă vezi vreodată un soldat al Ordinului, fugi în direcția opusă. Îmi displac mai ales Războinicii, ăștia sunt pur și simplu rapizi!","Небольшой совет: если увидишь «оловянных солдатиков» Ордена, сворачивай в другую сторону. Я особенно не люблю похитителей — эти твари довольно быстрые!",,"Size bir tavsiye, Tarikat'ın teneke askerlerinden birini görürseniz, diğer tarafa kaçın. Özellikle Yağmacıları sevmiyorum, o şeyler çok hızlı!" +奴等は素早く残忍だ。","충고 하나 해주죠. 오더의 로봇 병사들을 발견한다면, 조용히 피해가세요. 특히나 성가신 놈 중 하나가 리버인데, 그놈의 산탄총은 장난 아니에요!","Hier is een advies, als je ooit een van de tinnen soldaten van de Orde ziet, ren dan de andere kant op. Ik hou vooral niet van de Reavers, die dingen zijn gewoon verdomd snel!","Hvis du ser noen av Ordenens tinnsoldater, så løp den andre veien. Jeg liker spesielt ikke Reavers, de er så jævla raske!","Oto rada, jeśli kiedykolwiek zobaczysz któregoś z blaszanych żołnierzy Zakonu, uciekaj w drugą stronę. Szczególnie nie lubię Łupieżców, te rzeczy są cholernie szybkie!","Um conselho pra você: se você ver algum desses soldados de lata da Ordem, fuja para o lado oposto. Eu particularmente detesto os Saqueadores. Eles são rapidos pra caramba!",,"Iată un sfat, dacă vezi vreodată un soldat al Ordinului, fugi în direcția opusă. Îmi displac mai ales Războinicii, ăștia sunt pur și simplu rapizi!","Небольшой совет: если увидишь «оловянных солдатиков» Ордена, сворачивай в другую сторону. Я особенно не люблю похитителей — эти твари довольно быстрые!",,"Här är ett råd, om du någonsin ser någon av ordens tennsoldater, spring åt andra hållet. Jag gillar särskilt inte Reavers, de där sakerna är förbannat snabba!","Size bir tavsiye, Tarikat'ın teneke askerlerinden birini görürseniz, diğer tarafa kaçın. Özellikle Yağmacıları sevmiyorum, o şeyler çok hızlı!" "Welcome to the last flicker of hope. Only we have the free will to oppose the Order. We have the sharpest scientific minds, and many able bodies. But we lack that one real problem solver, who will give us the edge we need.",TXT_DLG_SCRIPT34_D27288_WELCO,MAP34: Macil.,,,"Vítej u posledního plamínku naděje. Jen my máme svobodnou vůli vzdorovat Řádu. Máme sice nejčilejší vědecké génie a mnoho schopných vojáků, ale chybí nám ten jeden řešitel problémů, který by nás posunul vpřed.","Velkommen til det sidste lille håb. Kun vi har den frie vilje til at modsætte os Ordenen. Vi har de skarpeste videnskabelige hjerner og mange dygtige kroppe. Men vi mangler den ene rigtige problemløser, som vil give os den fordel, vi har brug for.","Wilkommen beim letzten Hoffnungsschimmer. Nur wir haben noch den freien Willen, um gegen den Orden zu arbeiten. Wir haben die besten Wissenschaftler und viele fähige Kämpfer aber was uns fehlt ist ein spezieller Problemlöser, der uns den nötigen Vorteil verschafft.",,,"Bienvenido al último destello de esperanza. Solo nosotros tenemos el libre albedrío para oponernos a la Orden. Tenemos las mentes científicas más brillantes, y muchos cuerpos capaces. Pero nos falta un verdadero solucionador de problemas, alguien que nos dé la ventaja que necesitamos.",,"Tervetuloa viimeisen toivonpilkahduksen äärelle. Ainoastaan meillä on vapaa tahto vastustaa Veljeskuntaa. Meillä on tieteen terävimmät mielet ja monia ruumiiltaan vahvoja, mutta meiltä puuttuu se yksi todellinen ongelmanratkoja, joka antaisi meille kaipaamamme etulyöntiaseman.","Bienvenue au dernier lieu d'espoir. Nous seuls avons la liberté d'esprit pour opposer l'Ordre. Nous avons les esprits scientifiques les plus aiguisés et de nombreux hommes habiles et sains.. Mais il nous manque quelqu'un qui pourrait.. résoudre nos problèmes. Nous donner un peu d'aide, nous permettre de prendre l'avantage.","Köszöntelek a remény utolsó pislákoló fényénél. Már csak mi merünk szembeszállni a Renddel. Itt vannak a legélesebb elmék, életerős emberek, de hiányzik egy igazi...probléma megoldó, aki előnyt szerez számunkra. Segíts nekünk!","Benenuto nell'ultimo barlume di speranza. Noi siamo i soli ad avere la determinazione per combattere l'Ordine. Abbiamo brillanti scienziati e molti soldati capaci, ma ci manca quel vero e proprio risolutore di problemi, che ci può dare quel vantaggio che cerchiamo.","ようこそ、ここは我々の僅かな希望が集まる 最後の場所だ。オーダーへと立ち向かう意思を 持っているのは我々くらいだ。 @@ -11554,575 +12036,575 @@ Here you go.,TXT_RYES0_SCRIPT34_D16676_HEREY,〃,,,Tady máš.,Værsgo.,Bittesch そして丈夫な体を持った戦士たちがいる。 だがしかし、我々には問題解決に優れた者、 つまり私達の力となる者が足りていないんだ。 -我々に手を貸してくれ。","희미한 희망에 빛에 온 것을 환영합니다. 우리만이 오더를 처치할 자유의지를 가지고 있지요. 우수한 과학력에, 뛰어난 실력을 소유한 부대도 있으니까 말입니다. 하지만, 우리들에게도 부족한 게 하나 있습니다. 바로 시련을 해결해 줄 해결사죠. 부디 도와주세요.","Welkom bij het laatste sprankje hoop. Alleen wij hebben de vrije wil om ons te verzetten tegen de Orde. We hebben de scherpste wetenschappelijke geesten en veel bekwame lichamen. Maar we missen die ene echte probleemoplosser, die ons de voorsprong zal geven die we nodig hebben.","Velkommen til det siste glimt av håp. Bare vi har den frie viljen til å motsette oss Ordenen. Vi har de skarpeste vitenskapelige hodene, og mange dyktige kropper. Men vi mangler den ene virkelige problemløseren, som vil gi oss det forspranget vi trenger.","Witamy w ostatniej iskierce nadziei. Tylko my mamy wolną wolę, by przeciwstawić się Zakonowi. Mamy najbystrzejsze umysły naukowe i wiele sprawnych ciał. Ale brakuje nam tego jednego prawdziwego rozwiązania problemu, które da nam przewagę, której potrzebujemy.","Seja bem-vindo à última ponta de esperança. Somos os únicos que têm o livre arbítrio para combater a Ordem. Temos as mentes científicas mais afiadas e muitas pessoas capazes. Mas ainda nos falta aquele verdadeiro quebra-galho, que nos dará o impulso que precisamos.",,"Bun-venit la ultima speranță. Numai noi avem voința de a ne opune Ordinului. Avem cele mai strălucite minți științifice și multe corpuri capabile. Dar ne lipsește acea persoană capabilă să rezolve probleme, care o să ne dea avantajul de care avem nevoie.","Добро пожаловать в последний оплот надежды. Только мы обладаем свободной волей, чтобы противостоять Ордену. С нами лучшие учёные умы, и у нас есть много толковых людей, но нам не хватает одного-единственного, э... «разрешителя проблем», который поможет нам получить необходимое преимущество.",,Son umut ışığına hoş geldiniz. Tarikat'a karşı çıkacak özgür irade sadece bizde var. En keskin bilimsel zihinlere ve birçok yetenekli bedene sahibiz. Ama bize ihtiyacımız olan avantajı sağlayacak gerçek bir sorun çözücüden yoksunuz. -What will I need to do? ,TXT_RPLY0_SCRIPT34_D27288_WHATW,〃,,,Co budu muset udělat?,Hvad skal jeg gøre?,Was muss ich tun?,,,¿Qué necesito hacer?,,Mitä minun tarvitsee tehdä?,Que dois-je faire?,Mit kell tennem?,Che cosa devo fare?,何をしたらいい?,무엇을 해야하죠?,Wat moet ik doen?,Hva må jeg gjøre?,Co będę musiał zrobić?,O que preciso fazer?,,Ce trebuie să fac?,Что я должен сделать?,,Ne yapmam gerekecek? +我々に手を貸してくれ。","희미한 희망에 빛에 온 것을 환영합니다. 우리만이 오더를 처치할 자유의지를 가지고 있지요. 우수한 과학력에, 뛰어난 실력을 소유한 부대도 있으니까 말입니다. 하지만, 우리들에게도 부족한 게 하나 있습니다. 바로 시련을 해결해 줄 해결사죠. 부디 도와주세요.","Welkom bij het laatste sprankje hoop. Alleen wij hebben de vrije wil om ons te verzetten tegen de Orde. We hebben de scherpste wetenschappelijke geesten en veel bekwame lichamen. Maar we missen die ene echte probleemoplosser, die ons de voorsprong zal geven die we nodig hebben.","Velkommen til det siste glimt av håp. Bare vi har den frie viljen til å motsette oss Ordenen. Vi har de skarpeste vitenskapelige hodene, og mange dyktige kropper. Men vi mangler den ene virkelige problemløseren, som vil gi oss det forspranget vi trenger.","Witamy w ostatniej iskierce nadziei. Tylko my mamy wolną wolę, by przeciwstawić się Zakonowi. Mamy najbystrzejsze umysły naukowe i wiele sprawnych ciał. Ale brakuje nam tego jednego prawdziwego rozwiązania problemu, które da nam przewagę, której potrzebujemy.","Seja bem-vindo à última ponta de esperança. Somos os únicos que têm o livre arbítrio para combater a Ordem. Temos as mentes científicas mais afiadas e muitas pessoas capazes. Mas ainda nos falta aquele verdadeiro quebra-galho, que nos dará o impulso que precisamos.",,"Bun-venit la ultima speranță. Numai noi avem voința de a ne opune Ordinului. Avem cele mai strălucite minți științifice și multe corpuri capabile. Dar ne lipsește acea persoană capabilă să rezolve probleme, care o să ne dea avantajul de care avem nevoie.","Добро пожаловать в последний оплот надежды. Только мы обладаем свободной волей, чтобы противостоять Ордену. С нами лучшие учёные умы, и у нас есть много толковых людей, но нам не хватает одного-единственного, э... «разрешителя проблем», который поможет нам получить необходимое преимущество.",,Välkommen till den sista gnistan av hopp. Endast vi har den fria viljan att motsätta oss Orden. Vi har de skarpaste vetenskapliga hjärnorna och många dugliga kroppar. Men vi saknar en riktig problemlösare som kan ge oss det övertag vi behöver.,Son umut ışığına hoş geldiniz. Tarikat'a karşı çıkacak özgür irade sadece bizde var. En keskin bilimsel zihinlere ve birçok yetenekli bedene sahibiz. Ama bize ihtiyacımız olan avantajı sağlayacak gerçek bir sorun çözücüden yoksunuz. +What will I need to do? ,TXT_RPLY0_SCRIPT34_D27288_WHATW,〃,,,Co budu muset udělat?,Hvad skal jeg gøre?,Was muss ich tun?,,,¿Qué necesito hacer?,,Mitä minun tarvitsee tehdä?,Que dois-je faire?,Mit kell tennem?,Che cosa devo fare?,何をしたらいい?,무엇을 해야하죠?,Wat moet ik doen?,Hva må jeg gjøre?,Co będę musiał zrobić?,O que preciso fazer?,,Ce trebuie să fac?,Что я должен сделать?,,Vad måste jag göra?,Ne yapmam gerekecek? Help us. Help us steal their technology. Free our comrades. Fight these twisted psychopaths to the death. I'm asking you to risk your life for the truth.,TXT_DLG_SCRIPT34_D28804_HELPU,〃,,,Pomoz nám. Pomoz nám ukrást jejich technologie. Osvobodit naše druhy. Bojovat s těmi šílenými psychopaty na smrt. Chci po tobě riskovat svůj život kvůli pravdě.,Hjælp os. Hjælp os med at stjæle deres teknologi. Befri vores kammerater. Bekæmp disse forvredne psykopater til døden. Jeg beder dig om at sætte dit liv på spil for sandheden.,"Hilf uns. Hilf uns ihre Technologie zu stehlen. Befreie unsere Kameraden. Bekämpfe diese verwirrten Psychopathen bis zum Tod. Ich bitte dich, dein Leben zu riskieren um die Wahrheit zu verteidigen.",,,Ayúdanos. Ayúdanos a robar su tecnología. Libera a nuestros camaradas. Lucha contra estos retorcidos psicópatas hasta la muerte. Te estoy pidiendo que arriesgues tu vida por la verdad.,,Auta meitä. Auta meitä kaappaamaan heidän teknologiaansa. Vapauta meidän toverimme. Taistele näitä kieroituneita psykopaatteja vastaan kuoloon asti. Pyydän sinua antamaan henkesi alttiiksi totuuden nimessä.,Aidez nous. Aidez nous à voler leur technologie. Libérer nos camarades. Combattre ces psychopathes jusqu'à la mort. Je vous demande de risquer votre vie pour la vérité.,"Segíts nekünk. Abban, hogy ellophassuk a technológiájukat. Kiszabadítani a társainkat. Halálunkig harcolni ezek a pszihopaták ellen. Azt kell kérjem tőled, hogy tedd kockára az életed az igazságérrt.",Aiutaci. Aiutaci a rubare la loro tecnologia. Libera i nostri compagni. Combatti questi maledetti psicopatici fino alla morte. Ti sto chiedendo di rischiare la tua vita per la verità.,"我々の援護だ。我々が奴等のテクノロジーを 盗むのを手伝って欲しい。同胞の解放の為だ。 イカレた奴等と戦闘する必要がある。 正義を取り戻すため君には危険の伴う任務を -受けてほしいのだ。","우릴 도와주세요. 놈들의 기술을 훔치고, 붙잡힌 동료들을 구출하고, 오더의 미치광이들을 타도하기 위해서 말이죠. 그리고 진실 어린 희망을 위해서 이렇게 묻는 겁니다.",Help ons. Help ons hun technologie te stelen. Bevrijd onze kameraden. Bestrijd deze verdraaide psychopaten tot de dood toe. Ik vraag je om je leven te riskeren voor de waarheid.,Hjelpe oss. Hjelp oss med å stjele teknologien deres. Befri kameratene våre. Kjemp mot disse forskrudde psykopatene til døden. Jeg ber deg om å risikere livet for sannheten.,"Pomóc nam. Pomóż nam wykraść ich technologię. Uwolnić naszych towarzyszy. Walczyć z tymi pokręconymi psychopatami na śmierć. Proszę cię, abyś zaryzykował swoje życie dla prawdy.",Nos ajudar. Ajude-nos a roubar a tecnologia deles. Liberte nossos companheiros. Lute contra esses psicopatas insanos até a morte. Estou te pedindo para arriscar a sua vida pela verdade.,,Ajută-ne. Ajută-ne să le furăm tehnologia. Să ne eliberăm compatrioții. Să luptăm cu acești psihopați suciți până la moarte. Îți cer să îți riști viața pentru adevăr.,Помочь нам. Помочь нам украсть их технологии. Освободить наших товарищей. Сразиться с этими извращёнными психопатами и убить их. Рискнуть своей жизнью ради правого дела.,,Bize yardım et. Teknolojilerini çalmamıza yardım et. Yoldaşlarımızı serbest bırak. Bu sapkın psikopatlarla ölümüne savaş. Senden gerçek için hayatını riske atmanı istiyorum. -I'm with you!,TXT_RPLY0_SCRIPT34_D28804_IMWIT,〃,,,Jsem s tebou!,Jeg er med dig!,Ich bin dabei.,,,¡Estoy contigo!,,Olen kanssanne!,Je suis avec vous!,Veletek vagyok!,Sono con te!,同意した!,함께 하겠습니다!,Ik sta achter je!,Jeg er med deg!,Jestem z tobą!,Estou com vocês!,,Sunt cu tine!,Хорошо! Я с вами!,,Seninleyim! +受けてほしいのだ。","우릴 도와주세요. 놈들의 기술을 훔치고, 붙잡힌 동료들을 구출하고, 오더의 미치광이들을 타도하기 위해서 말이죠. 그리고 진실 어린 희망을 위해서 이렇게 묻는 겁니다.",Help ons. Help ons hun technologie te stelen. Bevrijd onze kameraden. Bestrijd deze verdraaide psychopaten tot de dood toe. Ik vraag je om je leven te riskeren voor de waarheid.,Hjelpe oss. Hjelp oss med å stjele teknologien deres. Befri kameratene våre. Kjemp mot disse forskrudde psykopatene til døden. Jeg ber deg om å risikere livet for sannheten.,"Pomóc nam. Pomóż nam wykraść ich technologię. Uwolnić naszych towarzyszy. Walczyć z tymi pokręconymi psychopatami na śmierć. Proszę cię, abyś zaryzykował swoje życie dla prawdy.",Nos ajudar. Ajude-nos a roubar a tecnologia deles. Liberte nossos companheiros. Lute contra esses psicopatas insanos até a morte. Estou te pedindo para arriscar a sua vida pela verdade.,,Ajută-ne. Ajută-ne să le furăm tehnologia. Să ne eliberăm compatrioții. Să luptăm cu acești psihopați suciți până la moarte. Îți cer să îți riști viața pentru adevăr.,Помочь нам. Помочь нам украсть их технологии. Освободить наших товарищей. Сразиться с этими извращёнными психопатами и убить их. Рискнуть своей жизнью ради правого дела.,,Hjälp oss. Hjälp oss att stjäla deras teknologi. Befria våra kamrater. Kämpa mot de här förvridna psykopaterna in i döden. Jag ber dig riskera ditt liv för sanningen.,Bize yardım et. Teknolojilerini çalmamıza yardım et. Yoldaşlarımızı serbest bırak. Bu sapkın psikopatlarla ölümüne savaş. Senden gerçek için hayatını riske atmanı istiyorum. +I'm with you!,TXT_RPLY0_SCRIPT34_D28804_IMWIT,〃,,,Jsem s tebou!,Jeg er med dig!,Ich bin dabei.,,,¡Estoy contigo!,,Olen kanssanne!,Je suis avec vous!,Veletek vagyok!,Sono con te!,同意した!,함께 하겠습니다!,Ik sta achter je!,Jeg er med deg!,Jestem z tobą!,Estou com vocês!,,Sunt cu tine!,Хорошо! Я с вами!,,Jag är med dig!,Seninleyim! "Good. Blackbird will continue to be your guide. She's taken quite a shine to you. Together, you've got to unlock the secrets of the Order and their inhuman servants. There's a presence that lurks just outside our understanding which guides their terror. Get inside and take them down. ",TXT_DLG_SCRIPT34_D30320_GOODB,〃,,,"Dobře, Straka ti bude dále dávat pokyny. Docela ses jí zalíbil. Společně budete muset odkrýt tajemství Řádu a jeho nelidských služebníků. Někde mimo naše chápání je něco, co ovládá jejich řádění. Pronikněte dovnitř a sejměte je.","Jeg er med dig. Blackbird vil fortsat være din guide. Hun er blevet ret glad for dig. Sammen skal I løse hemmelighederne om Ordenen og deres umenneskelige tjenere. Der er en tilstedeværelse, der lurer lige uden for vores forståelse, som styrer deres terror. Kom ind og nedkæmp dem.","Gut so! Blackbird wird weiter deine Leiterin sein, sie scheint dich zu mögen. Zusammen müsst ihr die Geheimnisse des Ordens und ihrer unmenschlichen Diener ergründen. Dann haben wir eine Chance, sie niederzuringen. Da ist eine Präsenz außerhalb unseres Vorstellungsvermögens, das diesen Terror leitet. Wir müssen sie unterwandern und dann vernichten.",,,"Bien. Blackbird continuará siendo tu guía. Le caes bastante bien. Juntos, teneis que desvelar los secretos de la Orden y sus sirvientes inhumanos. Hay una presencia que acecha más allá de nuestro conocimiento que guía su terror. Adéntrate y derríbalos.","Bien. Blackbird continuará siendo tu guía. Le caes bastante bien. Juntos, deberán desvelar los secretos de la Orden y sus sirvientes inhumanos. Hay una presencia que acecha más allá de nuestro conocimiento que guía su terror. Adéntrate y derríbalos.","Hyvä; Blackbird jatkaa opastajanasi. Hän vaikuttaa pitävän sinusta. Teidän on yhdessä paljastettava Veljeskunnan ja heidän epäinhimillisten palvelijoinsa salat. Heidän hirmuvaltaansa ohjaa läsnäolo, joka ylittää ymmärryksemme. Murtaudu sisään ja aja heidät alas.","Parfait. Blackbird continuera à être votre guide. Elle semble vous apprécier. Ensemble, vous allez découvrir les secrets de l'Ordre et leurs servants inhumains. Il existe une présece qui rôde juste au dehors de notre compréhension qui guide cette terreur. Infiltrez-les et détruisez-les.","Helyes, Feketerigó továbbra is az irányítód lesz. Eléggé megtetszettél neki. Együtt meg fogjátok fejteni a Rend és kegyetlen szolgáinak titkait. Egyfajta emberi ésszel fel nem fogható jelenlét kényszeríti őket a terrorizálásra. Hatoljatok be és intézzétek el őket.","Bene. Blackbird continuerà ad essere la tua guida. Sembra ti abbia preso in simpatia. Insieme dovrete scoprire i segreti dell'Ordine e dei loro servi inumani. C'è qualcosa di malefico, oltre la nostra comprensione, che guida il loro terrore. Bisognerà infiltrarlo e distruggerlo.","いいぞ、今後もブラックバードが君のガイドを 務める。彼女は君に感心しているようだぞ。 君たちの二人で、オーダーと その人間離れした手下たちが持っている秘密を 暴いてもらいたい。 -奴等の基地に潜り込んで、倒すんだ。","감사드립니다! 블랙버드가 당신을 위해 계속 안내를 할 것입니다. 같이 행동한다면 오더의 흉측한 비밀들을 밝혀내고, 그들의 잔혹한 존재들을 응징할 수 있을 겁니다. 우리들의 이해심 밑에 공포를 인도하는 그들의 숨겨진 존재가 있죠. 그곳으로 들어가서, 물리치세요.",Goed. Blackbird zal je gids blijven. Ze heeft je een behoorlijke glans gegeven. Samen moeten jullie de geheimen van de Orde en hun onmenselijke dienaren ontrafelen. Er is een aanwezigheid die net buiten ons begrip schuilt en die hun angst leidt. Ga naar binnen en neem ze mee naar beneden.,Bra. Blackbird vil fortsette å være din guide. Hun har blitt ganske betatt av deg. Sammen må dere avsløre hemmelighetene til Ordenen og deres umenneskelige tjenere. Det er en tilstedeværelse som lurer like utenfor vår forståelse som styrer deres terror. Gå inn og ta dem.,"Dobrze. Blackbird nadal będzie twoim przewodnikiem. Polubiła cię. Razem musicie odkryć tajemnice Zakonu i ich nieludzkich sług. Istnieje obecność, która czai się poza naszym rozumieniem, która kieruje ich terrorem. Dostań się do środka i zdejmij ich.","Ótimo. Blackbird continuará sendo a sua guia. Ela parece que vai com a sua cara. Juntos, vocês desvendarão os segredos da Ordem e seus discípulos desumanos. Há uma presença que está além do nosso entendimento que guia todo esse terror. Vá infiltrar a Ordem e elimine-os.",,"Bun. Blackbird va continua să fie ghidul tău. A început să ia un interes asupra ta. Împreună, va trebui să aflați secretele Ordinului și servitorilor lor inumani. Există o prezență care se târăște la marginea capacității noastre de înțelegere care le ghidează teroarea. Infiltrează-te și pune-i la pământ.",Хорошо. «Чёрный дрозд» останется твоим проводником. Она тебе несколько симпатизирует. Вместе вы раскроете секреты Ордена и его бесчеловечных слуг. За этим ужасом стоит нечто лежащее далеко за пределами нашего понимания. Проникни на их территорию и ударь по ним как следует!,,Güzel. Karatavuk rehberin olmaya devam edecek. Senden oldukça hoşlandı. Birlikte Tarikat'ın ve insanlık dışı hizmetkârlarının sırlarını açığa çıkarmalısınız. Anlayışımızın hemen dışında gizlenen ve onların terörüne rehberlik eden bir varlık var. İçeri gir ve onları alaşağı et. -Let me at 'em!,TXT_RPLY0_SCRIPT34_D30320_LETME,〃,,,Pusť mě na ně!,Lad mig tage dem!,Lass mich das nur machen.,,,¡Voy a por ellos!,¡Voy por ellos!,Päästä minut heidän kimppuunsa!,Laissez moi m'en occuper!,Szétcincálom mind!,Lasciali a me!,任せろ!,저만 믿으세요!,Laat me naar ze toe!,La meg ta dem!,Pozwól mi na nich!,Pode deixar!,,Lasă-mă să pun mâna pe ei!,Я им покажу!,,Bırakın ben halledeyim! -That's the spirit.,TXT_RYES0_SCRIPT34_D30320_THATS,〃,,,Tak se mi to líbí.,Sådan er ånden.,Das ist die richtige Einstellung.,,,Ese es el espíritu.,,Niin sitä pitää.,J'aime entendre ça.,Ez a beszéd!,Questo è lo spirito giusto.,良い心掛けだ。,좋은 마음가짐입니다.,Dat is de geest.,Sånn skal det låte.,To jest duch.,Esse é o espírito.,,Ăsta e spiritul.,Правильный настрой.,,İşte ruh bu. -Welcome friend!,TXT_DLG_SCRIPT34_D31836_WELCO,〃,,,"Vítej, příteli!","Velkommen, min ven!","Wilkommen, Freund.",,"Bonvenon, amiko!","¡Bienvenido, amigo!",,"Tervetuloa, ystävä!","Bievenue, notre ami!",Üdvözöllek barátom.,Benvenuto amico!,よく来た、同志!,"어서오세요, 친구여!",Welkom vriend!,"Velkommen, min venn!",Witaj przyjacielu!,"Seja bem-vindo, amigo!",,Bun-venit prietene!,"Добро пожаловать, друг!",,Hoş geldin dostum! -,,Random dialogue,,,,,,,,,,,,,,,,,,,,,,,, -Please don't hurt me.,TXT_RANDOM_PEASANT_01,,,,"Neubližuj mi, prosím.",Du må ikke gøre mig noget.,Bitte tu mir nicht weh.,,Bonvolu ne vundi min.,"No me hagas nada, por favor.",,"Pyydän, älä vahingoita minua.","S'il vous plaît, laissez-moi tranquille.",Kérlek ne bánts!,"Ti prego, non farmi del male.",私を傷つけないでくれ。,목숨만은 살려줘.,Doe me alsjeblieft geen pijn.,"Vær så snill, ikke skad meg.","Proszę, nie rób mi krzywdy.","Por favor, não me machuque.",,Te rog nu mă răni.,"Пожалуйста, не трогай меня.",,Lütfen bana zarar verme. +奴等の基地に潜り込んで、倒すんだ。","감사드립니다! 블랙버드가 당신을 위해 계속 안내를 할 것입니다. 같이 행동한다면 오더의 흉측한 비밀들을 밝혀내고, 그들의 잔혹한 존재들을 응징할 수 있을 겁니다. 우리들의 이해심 밑에 공포를 인도하는 그들의 숨겨진 존재가 있죠. 그곳으로 들어가서, 물리치세요.",Goed. Blackbird zal je gids blijven. Ze heeft je een behoorlijke glans gegeven. Samen moeten jullie de geheimen van de Orde en hun onmenselijke dienaren ontrafelen. Er is een aanwezigheid die net buiten ons begrip schuilt en die hun angst leidt. Ga naar binnen en neem ze mee naar beneden.,Bra. Blackbird vil fortsette å være din guide. Hun har blitt ganske betatt av deg. Sammen må dere avsløre hemmelighetene til Ordenen og deres umenneskelige tjenere. Det er en tilstedeværelse som lurer like utenfor vår forståelse som styrer deres terror. Gå inn og ta dem.,"Dobrze. Blackbird nadal będzie twoim przewodnikiem. Polubiła cię. Razem musicie odkryć tajemnice Zakonu i ich nieludzkich sług. Istnieje obecność, która czai się poza naszym rozumieniem, która kieruje ich terrorem. Dostań się do środka i zdejmij ich.","Ótimo. Blackbird continuará sendo a sua guia. Ela parece que vai com a sua cara. Juntos, vocês desvendarão os segredos da Ordem e seus discípulos desumanos. Há uma presença que está além do nosso entendimento que guia todo esse terror. Vá infiltrar a Ordem e elimine-os.",,"Bun. Blackbird va continua să fie ghidul tău. A început să ia un interes asupra ta. Împreună, va trebui să aflați secretele Ordinului și servitorilor lor inumani. Există o prezență care se târăște la marginea capacității noastre de înțelegere care le ghidează teroarea. Infiltrează-te și pune-i la pământ.",Хорошо. «Чёрный дрозд» останется твоим проводником. Она тебе несколько симпатизирует. Вместе вы раскроете секреты Ордена и его бесчеловечных слуг. За этим ужасом стоит нечто лежащее далеко за пределами нашего понимания. Проникни на их территорию и ударь по ним как следует!,,Jag är med dig. Blackbird kommer att fortsätta att vara din guide. Hon har blivit ganska förtjust i dig. Tillsammans måste ni avslöja hemligheterna om Orden och deras omänskliga tjänare. Det finns en närvaro som lurar utanför vår förståelse och som styr deras terror. Ta dig in och ta ner dem.,Güzel. Karatavuk rehberin olmaya devam edecek. Senden oldukça hoşlandı. Birlikte Tarikat'ın ve insanlık dışı hizmetkârlarının sırlarını açığa çıkarmalısınız. Anlayışımızın hemen dışında gizlenen ve onların terörüne rehberlik eden bir varlık var. İçeri gir ve onları alaşağı et. +Let me at 'em!,TXT_RPLY0_SCRIPT34_D30320_LETME,〃,,,Pusť mě na ně!,Lad mig tage dem!,Lass mich das nur machen.,,,¡Voy a por ellos!,¡Voy por ellos!,Päästä minut heidän kimppuunsa!,Laissez moi m'en occuper!,Szétcincálom mind!,Lasciali a me!,任せろ!,저만 믿으세요!,Laat me naar ze toe!,La meg ta dem!,Pozwól mi na nich!,Pode deixar!,,Lasă-mă să pun mâna pe ei!,Я им покажу!,,Låt mig ta dem!,Bırakın ben halledeyim! +That's the spirit.,TXT_RYES0_SCRIPT34_D30320_THATS,〃,,,Tak se mi to líbí.,Sådan er ånden.,Das ist die richtige Einstellung.,,,Ese es el espíritu.,,Niin sitä pitää.,J'aime entendre ça.,Ez a beszéd!,Questo è lo spirito giusto.,良い心掛けだ。,좋은 마음가짐입니다.,Dat is de geest.,Sånn skal det låte.,To jest duch.,Esse é o espírito.,,Ăsta e spiritul.,Правильный настрой.,,Så ska det låta.,İşte ruh bu. +Welcome friend!,TXT_DLG_SCRIPT34_D31836_WELCO,〃,,,"Vítej, příteli!","Velkommen, min ven!","Wilkommen, Freund.",,"Bonvenon, amiko!","¡Bienvenido, amigo!",,"Tervetuloa, ystävä!","Bievenue, notre ami!",Üdvözöllek barátom.,Benvenuto amico!,よく来た、同志!,"어서오세요, 친구여!",Welkom vriend!,"Velkommen, min venn!",Witaj przyjacielu!,"Seja bem-vindo, amigo!",,Bun-venit prietene!,"Добро пожаловать, друг!",,"Välkommen, min vän!",Hoş geldin dostum! +,,Random dialogue,,,,,,,,,,,,,,,,,,,,,,,,, +Please don't hurt me.,TXT_RANDOM_PEASANT_01,,,,"Neubližuj mi, prosím.",Du må ikke gøre mig noget.,Bitte tu mir nicht weh.,,Bonvolu ne vundi min.,"No me hagas nada, por favor.",,"Pyydän, älä vahingoita minua.","S'il vous plaît, laissez-moi tranquille.",Kérlek ne bánts!,"Ti prego, non farmi del male.",私を傷つけないでくれ。,목숨만은 살려줘.,Doe me alsjeblieft geen pijn.,"Vær så snill, ikke skad meg.","Proszę, nie rób mi krzywdy.","Por favor, não me machuque.",,Te rog nu mă răni.,"Пожалуйста, не трогай меня.",,"Snälla, gör mig inte illa.",Lütfen bana zarar verme. "If you're looking to hurt me, I'm not really worth the effort.",TXT_RANDOM_PEASANT_02,,,,"Jestli mi chceš ublížit, fakt za to nestojím.","Hvis du er ude på at såre mig, er jeg ikke rigtig besværet værd.","Falls du mir was antun willst, ich bin den Aufwand nicht wert.",,"Se vi intencas vundi min, vi vere gajnos nenion.","Si estás tratando de hacerme algo, no vale la pena realmente.",,"Jos aikomuksenasi on vahingoittaa minua, en todellakaan ole sen vaivan väärti.","Si vous cherchez à me faire mal, Je n'en mérite pas l'effort.","Ha bántani akarsz, nem éri meg a fáradozást.","Se hai intenzione di farmi del male, ti assicuro che non ne valgo la pena.","もしお前が私に暴力を振るいたいなら間違いだ、 -私を殴る価値はないから。","날 괴롭히려고 여기까지 왔다면, 넌 헛수고를 한 거야.","Als je me pijn wilt doen, ben ik de moeite niet echt waard.","Hvis du er ute etter å skade meg, er jeg ikke verdt det.","Jeśli chcesz mnie skrzywdzić, nie jestem wart wysiłku.","Se pretende me machucar, te digo que não valerá a pena.",,"Dacă vrei să mă rănești, nu merit efortul.","Если ты хочешь ударить меня, то я не стою твоих усилий.",,"Eğer beni incitmek istiyorsan, bu çabaya değmem." -I don't know anything.,TXT_RANDOM_PEASANT_03,,,,O ničem nevím.,Jeg ved ikke noget.,Ich weiß nichts.,,Mi scias nenion.,No sé nada.,,En tiedä mitään.,Je ne sais rien.,Én semmit sem tudok.,Non so niente.,私は何も知らないんだ。,난 정말 아무것도 몰라.,Ik weet niets.,Jeg vet ingenting.,Nic nie wiem.,Eu não sei de nada.,,Nu știu nimic.,Я ничего не знаю.,,Ben bir şey bilmiyorum. -Go away or I'll call the guards!,TXT_RANDOM_PEASANT_04,,,,"Jdi pryč, nebo zavolám stráže!","Gå væk, eller jeg tilkalder vagterne!",Hau ab oder ich rufe die Wachen!,,Foriru aŭ mi vokos la gardistojn!,¡Vete o llamaré a los guardias!,¡Vete o llamo a los guardias!,"Mene pois, tai kutsun vartijat!",Allez vous en ou j'appelle les gardes!,"Tűnj innen, vagy hívom az őröket!",Vattene o chiamo le guardie!,離れろ、さもなくば衛兵を呼ぶぞ!,경비병 부르기 전에 얼른 사라져!,Ga weg of ik roep de bewakers!,"Gå vekk, ellers tilkaller jeg vaktene!",Odejdź albo zawołam strażników!,Vá embora antes que eu chame os guardas!,,Pleacă sau voi chema gardienii!,"Уходи, или я позову стражу!",,Git buradan yoksa muhafızları çağırırım! +私を殴る価値はないから。","날 괴롭히려고 여기까지 왔다면, 넌 헛수고를 한 거야.","Als je me pijn wilt doen, ben ik de moeite niet echt waard.","Hvis du er ute etter å skade meg, er jeg ikke verdt det.","Jeśli chcesz mnie skrzywdzić, nie jestem wart wysiłku.","Se pretende me machucar, te digo que não valerá a pena.",,"Dacă vrei să mă rănești, nu merit efortul.","Если ты хочешь ударить меня, то я не стою твоих усилий.",,Om du är ute efter att skada mig är jag inte värd besväret.,"Eğer beni incitmek istiyorsan, bu çabaya değmem." +I don't know anything.,TXT_RANDOM_PEASANT_03,,,,O ničem nevím.,Jeg ved ikke noget.,Ich weiß nichts.,,Mi scias nenion.,No sé nada.,,En tiedä mitään.,Je ne sais rien.,Én semmit sem tudok.,Non so niente.,私は何も知らないんだ。,난 정말 아무것도 몰라.,Ik weet niets.,Jeg vet ingenting.,Nic nie wiem.,Eu não sei de nada.,,Nu știu nimic.,Я ничего не знаю.,,Jag vet ingenting.,Ben bir şey bilmiyorum. +Go away or I'll call the guards!,TXT_RANDOM_PEASANT_04,,,,"Jdi pryč, nebo zavolám stráže!","Gå væk, eller jeg tilkalder vagterne!",Hau ab oder ich rufe die Wachen!,,Foriru aŭ mi vokos la gardistojn!,¡Vete o llamaré a los guardias!,¡Vete o llamo a los guardias!,"Mene pois, tai kutsun vartijat!",Allez vous en ou j'appelle les gardes!,"Tűnj innen, vagy hívom az őröket!",Vattene o chiamo le guardie!,離れろ、さもなくば衛兵を呼ぶぞ!,경비병 부르기 전에 얼른 사라져!,Ga weg of ik roep de bewakers!,"Gå vekk, ellers tilkaller jeg vaktene!",Odejdź albo zawołam strażników!,Vá embora antes que eu chame os guardas!,,Pleacă sau voi chema gardienii!,"Уходи, или я позову стражу!",,Gå härifrån eller så kallar jag på vakterna!,Git buradan yoksa muhafızları çağırırım! I wish sometimes that all these rebels would just learn their place and stop this nonsense.,TXT_RANDOM_PEASANT_05,,,,"Občas si přeju, aby si ti rebelové uvědomili, kde jsou, a skončili s těmi svými nesmysly.","Nogle gange ville jeg ønske, at alle disse oprørere bare ville lære deres plads og stoppe dette nonsens.","Manchmal wünsche ich mir, dass diese Rebellen ihren Unsinn stoppen würden.",,"Mi iufoje deziras, ke ĉiu ribelanto simple lernu vivi kaj haltigu tiun absurdon.",A veces deseo que todos los rebeldes simplemente aprendieran a vivir y se dejaran de tonterías.,A veces deseo que todos los rebeldes simplemente aprendan a vivir y que paren con esa idiotez.,Kunpa joskus kaikki nämä kapinalliset vain oppisivat paikkansa ja lopettaisivat tämän mielettömyyden.,"Je voudrais qu'a un moment, ces rebelles apprennent quelle est leur place et arrètent cette idiotie.","Néha azt kívánom, hogy ezek a lázadók bár megtanulnák, hol a helyük, és felhagynának ezzel az eszeveszett dologgal.",A volte vorrei solo che i ribelli imparassero a stare al loro posto e la smettessero con tutte queste follie.,"反乱軍がこんな出鱈目な状態をひっくり返すのを -切に願うよ。",저 저항군들이 가망이 없다는 걸 빨리 눈치챘으면 정말 좋겠군.,Ik wou soms dat al die rebellen gewoon hun plaats zouden leren kennen en deze onzin zouden stoppen.,Noen ganger skulle jeg ønske at alle disse opprørerne kunne lære seg sin plass og slutte med dette tullet.,"Chciałbym czasem, żeby ci wszyscy buntownicy nauczyli się, gdzie ich miejsce i skończyli z tymi bzdurami.",Às vezes eu queria que esses rebeldes cuidassem de suas próprias vidas e parassem com esse absurdo.,,Uneori îmi doresc ca rebelii ăștia să își vadă de treaba lor și să înceteze cu tâmpeniile.,"Иногда мне хочется, чтобы все эти повстанцы просто поняли своё место и прекратили эту пустую возню.",,Bazen tüm bu isyancıların hadlerini bilmelerini ve bu saçmalığa bir son vermelerini diliyorum. -"Just leave me alone, OK?",TXT_RANDOM_PEASANT_06,,,,"Prostě mě nech být, jasný?","Bare lad mig være i fred, okay?","Lass mich bitte in Ruhe, ok?",,"Ne proksimiĝu al mi, ĉu?","Déjame en paz, ¿vale?","Déjame en paz, ¿sí?","Jätä minut vain rauhaan, onko selvä?","Laissez moi seul, OK?","Csak hagyj magamra, jó?","Lasciami in pace e basta, OK?",私に構わないでくれよ、頼むぞ?,그냥 날 내버려 둬. 부탁이야.,"Laat me gewoon met rust, oké?","Bare la meg være i fred, OK?","Zostaw mnie w spokoju, dobrze?","Apenas me deixe em paz, ok?",,"Doar lasă-mă în pace, OK?","Просто оставь меня в покое, хорошо?",,"Beni yalnız bırak, tamam mı?" +切に願うよ。",저 저항군들이 가망이 없다는 걸 빨리 눈치챘으면 정말 좋겠군.,Ik wou soms dat al die rebellen gewoon hun plaats zouden leren kennen en deze onzin zouden stoppen.,Noen ganger skulle jeg ønske at alle disse opprørerne kunne lære seg sin plass og slutte med dette tullet.,"Chciałbym czasem, żeby ci wszyscy buntownicy nauczyli się, gdzie ich miejsce i skończyli z tymi bzdurami.",Às vezes eu queria que esses rebeldes cuidassem de suas próprias vidas e parassem com esse absurdo.,,Uneori îmi doresc ca rebelii ăștia să își vadă de treaba lor și să înceteze cu tâmpeniile.,"Иногда мне хочется, чтобы все эти повстанцы просто поняли своё место и прекратили эту пустую возню.",,Jag önskar ibland att alla dessa rebeller bara skulle lära sig sin plats och sluta med detta nonsens.,Bazen tüm bu isyancıların hadlerini bilmelerini ve bu saçmalığa bir son vermelerini diliyorum. +"Just leave me alone, OK?",TXT_RANDOM_PEASANT_06,,,,"Prostě mě nech být, jasný?","Bare lad mig være i fred, okay?","Lass mich bitte in Ruhe, ok?",,"Ne proksimiĝu al mi, ĉu?","Déjame en paz, ¿vale?","Déjame en paz, ¿sí?","Jätä minut vain rauhaan, onko selvä?","Laissez moi seul, OK?","Csak hagyj magamra, jó?","Lasciami in pace e basta, OK?",私に構わないでくれよ、頼むぞ?,그냥 날 내버려 둬. 부탁이야.,"Laat me gewoon met rust, oké?","Bare la meg være i fred, OK?","Zostaw mnie w spokoju, dobrze?","Apenas me deixe em paz, ok?",,"Doar lasă-mă în pace, OK?","Просто оставь меня в покое, хорошо?",,"Lämna mig bara ifred, okej?","Beni yalnız bırak, tamam mı?" "I'm not sure, but sometimes I think that I know some of the acolytes.",TXT_RANDOM_PEASANT_07,,,,"Nejsem si jistý, ale občas se mi zdá, že znám některé z akolytů.","Jeg er ikke sikker, men nogle gange tror jeg, at jeg kender nogle af akolytterne.","Ich bin nicht ganz sicher, aber manchmal kommt es mir vor, als kenne ich diese Ministranten.",,"Mi ne estas certa, sed mi iufoje kredas, ke mi konas iujn el la akolitoj.","No estoy seguro, pero a veces creo que reconozco a algunos de los acólitos.","No estoy seguro, pero a veces creo que ya conozco a algunos de los acólitos.","En ole varma, mutta toisinaan jotkut akoluutit vaikuttavat tutuilta.","Je ne suis pas sûr, mais quelque fois je pense reconnaître certains des acolytes.","Nem vagyok benne bizonyos, de néha mintha ismerném némelyik ministránst.","Non ne sono sicuro, ma volte mi sembra di conoscere alcuni degli accoliti.","何か、アコライトの中で見覚えのある顔したのが -いたんだが。","자세히는 모르지만, 내가 본 아콜라이트들 중에 아는 사람이 있는 것 같아.","Ik weet het niet zeker, maar soms denk ik dat ik sommige van de acolieten ken.","Jeg er ikke sikker, men noen ganger tror jeg at jeg kjenner noen av akolyttene.","Nie jestem pewien, ale czasem wydaje mi się, że znam niektórych akolitów.","Eu não tenho bem certeza, mas acho que conheco alguns dos acólitos.",,"Nu sunt sigur, dar uneori am impresia că cunosc pe unii acoliți.","Я не уверен, но порой мне кажется, что я узнаю некоторых служителей.",,Emin değilim ama bazen bazı yardımcıları tanıdığımı düşünüyorum. -The Order's got everything around here pretty well locked up tight.,TXT_RANDOM_PEASANT_08,,,,Řád to tu má všechno pod hodně přísným dohledem.,Ordenen har alting her omkring temmelig godt låst godt inde.,Der Orden hat hier alles ziemlich gut unter Kontrolle.,,La Ordono havas ĉion tie ĉi sufiĉe bone blokata.,La Orden tiene todo por aquí fuertemente bloqueado.,,Veljeskunnalla on täällä aika lailla kaikki tiukassa otteessaan.,L'ordre maintient la sûreté aux alentours.,A Rend mindent jól elzárt előlünk.,L'Ordine si è dato parecchio da fare per chiudere e sbarrare un po' tutto qui in giro.,オーダー達はここいらを厳しく取り締まってる。,오더가 치안유지도 그렇고 단속을 아주 실감 나게 잘하던데?,De Orde heeft alles hier in de buurt vrij goed afgesloten.,Ordenen har alt her ganske godt låst.,Zakon ma tu wszystko pod ścisłą kontrolą.,A Ordem mantém tudo trancado a sete chaves.,,Ordinul a încuiat cam tot ce se poate pe aici.,Орден держит тут всё под замком.,,Tarikat buradaki her şeyi oldukça iyi kilitlemiş. -There's no way that this is just a security force.,TXT_RANDOM_PEASANT_09,,,,"Není možné, aby tohle byly jen bezpečnostní složky.","Det er umuligt, at det bare er en sikkerhedsstyrke.",Das sind niemals nur Sicherheitskräfte.,,"Ne estas maniero, ke ĉi tio estas nur «sekureca forto».",No hay manera de que esto sea solo una fuerza de seguridad.,,Ei tämä mitenkään voi olla pelkkä turvallisuusjoukko.,Ca ne peut pas être juste une escouade de sécurité...,Na ez már tutira nem lehet csak a biztonsági szolgálat.,"E' impossibile che questa sia solo una ""forza di sicurezza"".",お前がただの警備兵なんてことはなさそうだな。,저 녀석들은 단순히 치안을 유지하기 위해 온 게 아니라고 생각해.,Er is geen sprake van dat dit gewoon een veiligheidsdienst is.,Det er ikke mulig at dette bare er en sikkerhetsstyrke.,"Nie ma mowy, żeby to była tylko ochrona.",Não tem como isso ser apenas um força de segurança.,,Sub nicio formă nu e asta doar o forță de securitate.,Без разрешения стражей порядка и шагу ступить нельзя.,,Bunun sadece bir güvenlik gücü olmasına imkan yok. +いたんだが。","자세히는 모르지만, 내가 본 아콜라이트들 중에 아는 사람이 있는 것 같아.","Ik weet het niet zeker, maar soms denk ik dat ik sommige van de acolieten ken.","Jeg er ikke sikker, men noen ganger tror jeg at jeg kjenner noen av akolyttene.","Nie jestem pewien, ale czasem wydaje mi się, że znam niektórych akolitów.","Eu não tenho bem certeza, mas acho que conheco alguns dos acólitos.",,"Nu sunt sigur, dar uneori am impresia că cunosc pe unii acoliți.","Я не уверен, но порой мне кажется, что я узнаю некоторых служителей.",,"Jag är inte säker, men ibland tror jag att jag känner några av akoliterna.",Emin değilim ama bazen bazı yardımcıları tanıdığımı düşünüyorum. +The Order's got everything around here pretty well locked up tight.,TXT_RANDOM_PEASANT_08,,,,Řád to tu má všechno pod hodně přísným dohledem.,Ordenen har alting her omkring temmelig godt låst godt inde.,Der Orden hat hier alles ziemlich gut unter Kontrolle.,,La Ordono havas ĉion tie ĉi sufiĉe bone blokata.,La Orden tiene todo por aquí fuertemente bloqueado.,,Veljeskunnalla on täällä aika lailla kaikki tiukassa otteessaan.,L'ordre maintient la sûreté aux alentours.,A Rend mindent jól elzárt előlünk.,L'Ordine si è dato parecchio da fare per chiudere e sbarrare un po' tutto qui in giro.,オーダー達はここいらを厳しく取り締まってる。,오더가 치안유지도 그렇고 단속을 아주 실감 나게 잘하던데?,De Orde heeft alles hier in de buurt vrij goed afgesloten.,Ordenen har alt her ganske godt låst.,Zakon ma tu wszystko pod ścisłą kontrolą.,A Ordem mantém tudo trancado a sete chaves.,,Ordinul a încuiat cam tot ce se poate pe aici.,Орден держит тут всё под замком.,,Ordern har allting här omkring ganska väl låst in ordentligt.,Tarikat buradaki her şeyi oldukça iyi kilitlemiş. +There's no way that this is just a security force.,TXT_RANDOM_PEASANT_09,,,,"Není možné, aby tohle byly jen bezpečnostní složky.","Det er umuligt, at det bare er en sikkerhedsstyrke.",Das sind niemals nur Sicherheitskräfte.,,"Ne estas maniero, ke ĉi tio estas nur «sekureca forto».",No hay manera de que esto sea solo una fuerza de seguridad.,,Ei tämä mitenkään voi olla pelkkä turvallisuusjoukko.,Ca ne peut pas être juste une escouade de sécurité...,Na ez már tutira nem lehet csak a biztonsági szolgálat.,"E' impossibile che questa sia solo una ""forza di sicurezza"".",お前がただの警備兵なんてことはなさそうだな。,저 녀석들은 단순히 치안을 유지하기 위해 온 게 아니라고 생각해.,Er is geen sprake van dat dit gewoon een veiligheidsdienst is.,Det er ikke mulig at dette bare er en sikkerhetsstyrke.,"Nie ma mowy, żeby to była tylko ochrona.",Não tem como isso ser apenas um força de segurança.,,Sub nicio formă nu e asta doar o forță de securitate.,Без разрешения стражей порядка и шагу ступить нельзя.,,Det är inte möjligt att det här bara är en säkerhetsstyrka.,Bunun sadece bir güvenlik gücü olmasına imkan yok. I've heard that the Order is really nervous about the Front's actions around here.,TXT_RANDOM_PEASANT_10,,,,"Slyšel jsem, že je Řád prý dost nervózní z toho, co tu Fronta dělá.","Jeg har hørt, at Ordenen er meget nervøs over Frontens handlinger her.","Ich habe gehört, dass der Orden sehr beunruhigt über die Aktionen der Front ist.",,"Mi aŭdis, ke La Ordono estas tre nervoza pro la agoj de la ĉirkaŭa Fronto.",He oído que La Orden está realmente nerviosa por las acciones del Frente en los alrededores.,,Veljeskunta on kuulemma tosi huolissaan Rintaman toimista täällä.,J'ai entendu dire que l'ordre était sur les nerfs à cause des actions du front.,Úgy hírlik A Rend nagyon ideges a Front munkálkodásai miatt mostanság.,Ho sentito che l'Ordine è parecchio nervoso riguardo le azioni del Fronte nei dintorni.,"私はオーダーがこの辺での反乱軍の行動を -本当に厄介がってると聞いたぞ。",오더가 프론트 저항군의 공작에 정말 불안해하고 있더라고.,Ik heb gehoord dat de Orde echt nerveus is over de acties van het Front hier in de buurt.,Jeg har hørt at Ordenen er veldig nervøs for Frontens handlinger her.,"Słyszałem, że Zakon jest bardzo zdenerwowany działaniami Frontu w tym miejscu.",Ouvi falar que a Ordem anda bem nervosa por causa das ações da Frente por aqui.,,Am auzit că Ordinul e destul de stresat dorită acțiunilor Frontului pe-aici.,"Я слыхал, что Орден серьёзно обеспокоен действиями повстанцев в этом районе.",,Tarikat'ın Cephe'nin buradaki eylemleri konusunda gerçekten gergin olduğunu duydum. -There's no way the Order will stand against us.,TXT_RANDOM_REBEL_01,,,,Řád se nám v žádném případě nemůže postavit.,Ordenen vil på ingen måde stå imod os.,Niemals wird sich der Orden gegen uns stellen!,,La Ordono neniel povos rezisti al ni.,No hay forma de que La Orden aguante contra nosotros.,,Veljeskunta ei voi millään kestää meitä vastaan.,L'ordre n'a aucune chance contre nous.,A Rend labdába sem rúghat ellenünk!,Non è possibile che l'Ordine possa mettersi contro di noi.,オーダーが私達に立ち向かえるはずはない。,오더 녀석들이 우리를 이길 가능성은 전혀 없어.,De Orde zal op geen enkele manier tegen ons ingaan.,Det er ingen sjanse for at Ordenen vil gå imot oss.,"Nie ma mowy, by Zakon stanął przeciwko nam.",Nao ha como a Ordem ficar contra a gente.,,Nicio șansă ca Ordinul să ni se opună.,Ордену никак не устоять против нас.,,Düzen'in bize karşı durmasına imkan yok. +本当に厄介がってると聞いたぞ。",오더가 프론트 저항군의 공작에 정말 불안해하고 있더라고.,Ik heb gehoord dat de Orde echt nerveus is over de acties van het Front hier in de buurt.,Jeg har hørt at Ordenen er veldig nervøs for Frontens handlinger her.,"Słyszałem, że Zakon jest bardzo zdenerwowany działaniami Frontu w tym miejscu.",Ouvi falar que a Ordem anda bem nervosa por causa das ações da Frente por aqui.,,Am auzit că Ordinul e destul de stresat dorită acțiunilor Frontului pe-aici.,"Я слыхал, что Орден серьёзно обеспокоен действиями повстанцев в этом районе.",,Jag har hört att Orden är riktigt nervös över Fronts agerande här.,Tarikat'ın Cephe'nin buradaki eylemleri konusunda gerçekten gergin olduğunu duydum. +There's no way the Order will stand against us.,TXT_RANDOM_REBEL_01,,,,Řád se nám v žádném případě nemůže postavit.,Ordenen vil på ingen måde stå imod os.,Niemals wird sich der Orden gegen uns stellen!,,La Ordono neniel povos rezisti al ni.,No hay forma de que La Orden aguante contra nosotros.,,Veljeskunta ei voi millään kestää meitä vastaan.,L'ordre n'a aucune chance contre nous.,A Rend labdába sem rúghat ellenünk!,Non è possibile che l'Ordine possa mettersi contro di noi.,オーダーが私達に立ち向かえるはずはない。,오더 녀석들이 우리를 이길 가능성은 전혀 없어.,De Orde zal op geen enkele manier tegen ons ingaan.,Det er ingen sjanse for at Ordenen vil gå imot oss.,"Nie ma mowy, by Zakon stanął przeciwko nam.",Nao ha como a Ordem ficar contra a gente.,,Nicio șansă ca Ordinul să ni se opună.,Ордену никак не устоять против нас.,,Det finns inte en chans att Orden kommer att stå emot oss.,Düzen'in bize karşı durmasına imkan yok. We're almost ready to strike. Macil's plans are falling in place.,TXT_RANDOM_REBEL_02,,,,Jsme téměř připraveni zaútočit. Macilovy plány do sebe začínají zapadat.,Vi er næsten klar til at slå til. Macils planer er ved at falde på plads.,Wir sind zum großen Schlag bereit. Macils Plane werden bald umgesetzt.,,Ni estas preskaŭ pretaj por ekataki. La planoj de Macil sukcesas perfekte.,Estamos casi listos para atacar. Los planes de Macil están saliendo a la perfección.,,Olemme melkein valmiit hyökkäämään. Macilin suunnitelmat loksahtavat paikalleen.,Nous sommes presque prêts à agir. Les plans de Macil se déroulent comme prévu.,"Már majdnem készen állunk, hogy lecsapjunk. Macil tervei kezdenek bejönni.",Siamo quasi pronti a colpire. I piani di Macil stanno andando lisci come l'olio.,"攻撃の準備は殆ど整った。 -マシルの計画は所定の位置に下す。",반격할 준비가 거의 다 돼가고 있어. 마실 사령관님의 계획이 잘 진행되고 있으니까.,We zijn bijna klaar om toe te slaan. Macil's plannen vallen op zijn plaats.,Vi er nesten klare til å slå til. Macils planer faller på plass.,Jesteśmy prawie gotowi do uderzenia. Plany Macila są coraz lepsze.,Estamos quase prontos para o ataque. Os planos de Macil estão fazendo efeito.,,Suntem aproape gata să dăm lovitura. Planurile lui Macil încep să se lege.,Мы почти готовы атаковать. Планы Мэйсила становятся ясны.,,Saldırmaya neredeyse hazırız. Macil'in planları yerine oturuyor. -"We're all behind you, don't worry.",TXT_RANDOM_REBEL_03,,,,"Všichni stojíme za tebou, neboj.","Vi står alle bag dig, bare rolig.","Wir stehen zu dir, keine Sorge.",,"Ni protektos vin dorse, vi do estu trankvila.","Nosotros te cubrimos la espalda, así que tranquilo.",,"Olemme kaikki tukenasi, älä huoli.","On couvre tes arrières, t'inquiète pas.","Mind itt vagyunk mögötted, ne aggódj!","Non preoccuparti, noi tutti ti copriamo le spalle.",後ろは見ているぞ、気にするな。,걱정 마. 무슨 일이 있어도 우리가 지켜줄게!,"We staan allemaal achter je, maak je geen zorgen.","Vi står bak deg, ikke vær redd.","Wszyscy jesteśmy za tobą, nie martw się.","Estamos todos te protegendo, não se preocupe.",,"Suntem toți în spatele tău, nu te teme.",Не беспокойся. Мы сразу за тобой.,,"Hepimiz arkandayız, merak etme." +マシルの計画は所定の位置に下す。",반격할 준비가 거의 다 돼가고 있어. 마실 사령관님의 계획이 잘 진행되고 있으니까.,We zijn bijna klaar om toe te slaan. Macil's plannen vallen op zijn plaats.,Vi er nesten klare til å slå til. Macils planer faller på plass.,Jesteśmy prawie gotowi do uderzenia. Plany Macila są coraz lepsze.,Estamos quase prontos para o ataque. Os planos de Macil estão fazendo efeito.,,Suntem aproape gata să dăm lovitura. Planurile lui Macil încep să se lege.,Мы почти готовы атаковать. Планы Мэйсила становятся ясны.,,Vi är nästan redo att slå till. Macils planer faller på plats.,Saldırmaya neredeyse hazırız. Macil'in planları yerine oturuyor. +"We're all behind you, don't worry.",TXT_RANDOM_REBEL_03,,,,"Všichni stojíme za tebou, neboj.","Vi står alle bag dig, bare rolig.","Wir stehen zu dir, keine Sorge.",,"Ni protektos vin dorse, vi do estu trankvila.","Nosotros te cubrimos la espalda, así que tranquilo.",,"Olemme kaikki tukenasi, älä huoli.","On couvre tes arrières, t'inquiète pas.","Mind itt vagyunk mögötted, ne aggódj!","Non preoccuparti, noi tutti ti copriamo le spalle.",後ろは見ているぞ、気にするな。,걱정 마. 무슨 일이 있어도 우리가 지켜줄게!,"We staan allemaal achter je, maak je geen zorgen.","Vi står bak deg, ikke vær redd.","Wszyscy jesteśmy za tobą, nie martw się.","Estamos todos te protegendo, não se preocupe.",,"Suntem toți în spatele tău, nu te teme.",Не беспокойся. Мы сразу за тобой.,,"Vi står alla bakom dig, oroa dig inte.","Hepimiz arkandayız, merak etme." Don't get too close to any of those big robots. They'll melt you down for scrap!,TXT_RANDOM_REBEL_04,,,,Nepřibližuj se k těm velkým robotům. Usmaží tě na kaši!,Kom ikke for tæt på nogen af de store robotter. De vil smelte dig ned til skrot!,Komm diesen großen Robotern nicht zu nahe. Die schmelzen dich zu Schrott ein.,,Ne proksimiĝu tiel multe al tiuj robotegoj. Ili povus disigi vin je rubo!,No te acerques tanto a uno de esos robots grandes. ¡Podrían convertirían en chatarra!,,Älä mene liian lähelle mitään noista isoista roboteista. Ne sulattavat sinut kuonaksi.,Ne vous approchez pas trop des gros robots. Ils vous brûleront jusqu'à l'os!,Azokhoz a nagy robotokhoz ne nagyon menj közel. Felaprítanak tüzifának!,Non avvicinarti troppo a uno di quei grossi robot. Ti ridurrebbero in rottami!,"デカブツには近づくなよ。スクラップみたいに -踏みつぶされるぞ!",저 커다란 로봇들에게 다가갈 생각은 하지 마. 너를 완전 발끝까지 녹여버릴 거라고.,Kom niet te dicht bij een van die grote robots. Ze zullen je laten smelten voor de schroothoop!,Ikke kom for nær noen av de store robotene. De smelter deg om til skrap!,Nie zbliżaj się zbytnio do tych wielkich robotów. Przetopią cię na złom!,Nem pense em ficar perto daqueles robôs. Vão te transformar em ferro velho num instante!,,Nu te apropia de roboți. Te vor topii!,Держись подальше от этих больших роботов. Они и мокрого места от тебя не оставят!,,O büyük robotlara fazla yaklaşma. Sizi hurda için eritirler! +踏みつぶされるぞ!",저 커다란 로봇들에게 다가갈 생각은 하지 마. 너를 완전 발끝까지 녹여버릴 거라고.,Kom niet te dicht bij een van die grote robots. Ze zullen je laten smelten voor de schroothoop!,Ikke kom for nær noen av de store robotene. De smelter deg om til skrap!,Nie zbliżaj się zbytnio do tych wielkich robotów. Przetopią cię na złom!,Nem pense em ficar perto daqueles robôs. Vão te transformar em ferro velho num instante!,,Nu te apropia de roboți. Te vor topii!,Держись подальше от этих больших роботов. Они и мокрого места от тебя не оставят!,,Kom inte för nära någon av de stora robotarna. De kommer att smälta ner dig till skrot!,O büyük robotlara fazla yaklaşma. Sizi hurda için eritirler! "The day of our glory will soon come, and those who oppose us will be crushed!",TXT_RANDOM_REBEL_05,,,,"Naše dny slávy brzy nadejdou a ti, kdo se nám postaví, budou rozdrceni!","Vores storhedsdag vil snart komme, og de, der modsætter sig os, vil blive knust!","Der Tag des Triumphes ist nahe, und die, die gegen uns sind, werden vernichtet.",,,¡El día de nuestra gloria llegará pronto y aquellos que se opusieron a nosotros serán destruidos!,¡El día de nuestra gloria va a llegar pronto y aquellos que se opusieron a nosotros van a ser destruidos!,"Kunnian päivämme häämöttää, ja kaikki meitä vastustavat vihittäkööt tuhon omiksi!","Le jour de gloire arrivera bientôt, et ceux qui s'opposeront a nous seront écrasés!","Dicsőségünk napja hamarosan eljön, és akik ellenünk szegülnek, elkárhoznak.","Il giorno della nostra gloria verrà presto, e quelli che si oppongono a noi verranno schiacciati!","栄光の日は我々に訪れる、 -そして反逆する者達は潰す!",영광스러운 새벽이 오고있어. 우리를 탄압한 녀석들에게 징벌을 내릴 새벽이!,"De dag van onze glorie zal snel komen, en degenen die zich tegen ons verzetten zullen worden verpletterd!","Dagen for vår herlighet vil snart komme, og de som motsetter seg oss vil bli knust!","Dzień naszej chwały wkrótce nadejdzie, a ci, którzy się nam sprzeciwią, zostaną zmiażdżeni!","O dia de nossa glória chegará, e aqueles que se opuserem contra nós serão destruídos!",,Ziua în care noi vom avea gloria va veni curând și toti vor fi striviți.,Близок день нашего триумфа. Скоро наши враги будут уничтожены!,,Zafer günümüz yakında gelecek ve bize karşı çıkanlar ezilecek! +そして反逆する者達は潰す!",영광스러운 새벽이 오고있어. 우리를 탄압한 녀석들에게 징벌을 내릴 새벽이!,"De dag van onze glorie zal snel komen, en degenen die zich tegen ons verzetten zullen worden verpletterd!","Dagen for vår herlighet vil snart komme, og de som motsetter seg oss vil bli knust!","Dzień naszej chwały wkrótce nadejdzie, a ci, którzy się nam sprzeciwią, zostaną zmiażdżeni!","O dia de nossa glória chegará, e aqueles que se opuserem contra nós serão destruídos!",,Ziua în care noi vom avea gloria va veni curând și toti vor fi striviți.,Близок день нашего триумфа. Скоро наши враги будут уничтожены!,,"Vår härlighets dag kommer snart, och de som motsätter sig oss kommer att krossas!",Zafer günümüz yakında gelecek ve bize karşı çıkanlar ezilecek! Don't get too comfortable. We've still got our work cut out for us.,TXT_RANDOM_REBEL_06,,,,"Neusínej na vavřínech, stále máme před sebou hodně práce.",Lad være med at sætte dig for godt til rette. Vi har stadig vores arbejde foran os.,"Werd nicht leichtsinnig, es gibt noch eine Menge zu tun.",,,No te pongas muy cómodo. Ya tenemos nuestro propio trabajo asignado a cada uno.,,Ei parane levätä laakereillaan; meillä on vielä paljon työsarkaa edessämme.,Ne vous reposez pas sur vos lauriers. Du travail nous attend encore.,Annyira azért ne érezd otthon magad. Nekünk még van némi munka kiosztva idelenn.,Non prendertela troppo comoda. Abbiamo ancora un sacco di lavoro da fare.,"あまり気楽でいるな。 -我々にはまだやるべき事があるんだ。",게으름 피울 생각하지는 마. 아직 일이 잘 안 풀렸으니까.,Maak het je niet al te comfortabel. We hebben nog steeds werk voor de boeg.,Ikke bli for komfortabel. Vi har fortsatt en jobb å gjøre.,Nie czuj się zbyt komfortowo. Wciąż mamy przed sobą zadanie do wykonania.,Não fique muito confortável. Ainda temos trabalho a fazer.,,Nu te fă prea comfortabil. Încă mai avem treabă de făcut.,Не расслабляйся. У нас по-прежнему хватает дел.,,Fazla rahatlamayın. İşimiz hala bizim için biçilmiş kaftan. +我々にはまだやるべき事があるんだ。",게으름 피울 생각하지는 마. 아직 일이 잘 안 풀렸으니까.,Maak het je niet al te comfortabel. We hebben nog steeds werk voor de boeg.,Ikke bli for komfortabel. Vi har fortsatt en jobb å gjøre.,Nie czuj się zbyt komfortowo. Wciąż mamy przed sobą zadanie do wykonania.,Não fique muito confortável. Ainda temos trabalho a fazer.,,Nu te fă prea comfortabil. Încă mai avem treabă de făcut.,Не расслабляйся. У нас по-прежнему хватает дел.,,Gör det inte för bekvämt. Vi har fortfarande vårt arbete framför oss.,Fazla rahatlamayın. İşimiz hala bizim için biçilmiş kaftan. Macil says that you're the new hope. Bear that in mind.,TXT_RANDOM_REBEL_07,,,,"Macil říká, že jsi naše nová naděje. Pamatuj na to.","Macil siger, at du er det nye håb. Husk det.",Macil nennt dich unsere neue Hoffnung. Vergiss das nicht.,,"Macil diras, ke vi estas la nova espero. Memoru tion.",Macil dice que eres la nueva esperanza. Ten eso en mente.,,Macil sanoo sinun olevan uusi toivomme. Pidä se mielessäsi.,Macil nous dit que tu es notre nouvel espoir. Garde ça à l'esprit.,Macil szerint te vagy az új reményünk. Ezt sose feledd!,Macil dice che tu sei la nuova speranza. Tienilo a mente.,"マシルは貴方が新しい希望だと言っている。 -心に留めておいてくれ。",마실 사령관님이 말하기를 네가 우리들의 유일한 희망이래. 명심해 둬.,Macil zegt dat jij de nieuwe hoop bent. Houd dat in gedachten.,Macil sier at du er det nye håpet. Husk det.,"Macil mówi, że jesteś nową nadzieją. Pamiętajcie o tym.",Macil disse que você é a nova esperança. Lembre-se disso.,,Macil spune că tu ești speranța. Ține minte asta.,"Мэйсил говорит, что на тебя сейчас вся надежда. Имей это в виду.",,Macil senin yeni umut olduğunu söylüyor. Bunu aklınızdan çıkarmayın. +心に留めておいてくれ。",마실 사령관님이 말하기를 네가 우리들의 유일한 희망이래. 명심해 둬.,Macil zegt dat jij de nieuwe hoop bent. Houd dat in gedachten.,Macil sier at du er det nye håpet. Husk det.,"Macil mówi, że jesteś nową nadzieją. Pamiętajcie o tym.",Macil disse que você é a nova esperança. Lembre-se disso.,,Macil spune că tu ești speranța. Ține minte asta.,"Мэйсил говорит, что на тебя сейчас вся надежда. Имей это в виду.",,Macil säger att du är det nya hoppet. Tänk på det.,Macil senin yeni umut olduğunu söylüyor. Bunu aklınızdan çıkarmayın. "Once we've taken these charlatans down, we'll be able to rebuild this world as it should be.",TXT_RANDOM_REBEL_08,,,,"Jakmile sesadíme ty šarlatány, budeme moci znovu vybudovat svět tak, jaký by měl být.","Når vi først har nedlagt disse charlataner, vil vi kunne genopbygge denne verden, som den skal være.","Wenn wir diese Scharlatane entmachtet haben, können wir unsere Welt endlich neu aufbauen.",,,"Una vez que hayamos eliminado a esos charlatanes, podremos reconstruir este mundo como debe ser.","Una vez eliminados esos charlatanes, vamos a poder reconstruir este mundo como debe ser.","Sen jälkeen, kun olemme nujertaneet nämä puoskarit, voimme jälleenrakentaa tämän maailman sellaiseksi kuin pitääkin.","Une fois que nous nous serons débarassés de ces charlatans, nous serons capable de rebâtir le monde tel qu'il devrait être.","Amint lenyomtuk ezeket a sarlatánokat, végre újjáépíthetjük ezt a világot olyanra, amilyennek lennie kéne.","Una volta eliminati questi ciarlatani, potremo ricostruire questo mondo per come dovrebbe essere.","我々が一度こんな酷いハッタリを負かせば、 -世界を本来の状態に建て直せるだろう。","저 허풍쟁이들을 다 물리칠 수만 있다면, 우리가 바랬던 평화로운 세상을 재건할 수 있을 거야.","Als we deze charlatans eenmaal hebben verwijderd, kunnen we deze wereld weer opbouwen zoals het hoort.","Når vi har tatt disse sjarlatanene, kan vi gjenoppbygge verden slik den burde være.","Kiedy obalimy tych szarlatanów, będziemy mogli odbudować ten świat tak, jak powinien być.","Assim que derrubarmos esses charlatões, poderemos reconstruir o mundo do jeito certo.",,"Dupa ce îi vom răpune pe șarlatanii ăștia, vom putea reconstrui lumea în ceea ce trebuie să fie.","Когда мы свергнем этих шарлатанов, то сможем воссоздать этот мир таким, каким он должен быть.",,"Bu şarlatanları alaşağı ettikten sonra, bu dünyayı olması gerektiği gibi yeniden inşa edebileceğiz." +世界を本来の状態に建て直せるだろう。","저 허풍쟁이들을 다 물리칠 수만 있다면, 우리가 바랬던 평화로운 세상을 재건할 수 있을 거야.","Als we deze charlatans eenmaal hebben verwijderd, kunnen we deze wereld weer opbouwen zoals het hoort.","Når vi har tatt disse sjarlatanene, kan vi gjenoppbygge verden slik den burde være.","Kiedy obalimy tych szarlatanów, będziemy mogli odbudować ten świat tak, jak powinien być.","Assim que derrubarmos esses charlatões, poderemos reconstruir o mundo do jeito certo.",,"Dupa ce îi vom răpune pe șarlatanii ăștia, vom putea reconstrui lumea în ceea ce trebuie să fie.","Когда мы свергнем этих шарлатанов, то сможем воссоздать этот мир таким, каким он должен быть.",,När vi väl har slagit ner dessa charlataner kommer vi att kunna återuppbygga den här världen som den borde vara.,"Bu şarlatanları alaşağı ettikten sonra, bu dünyayı olması gerektiği gibi yeniden inşa edebileceğiz." "Remember that you aren't fighting just for yourself, but for everyone here and outside.",TXT_RANDOM_REBEL_09,,,,"Nezapomeň, že nebojuješ jen kvůli sobě, ale kvůli všem tady a tam venku.","Husk, at du ikke kun kæmper for dig selv, men for alle her og udenfor.","Vergiß nicht, dass du nicht nur für dich selbst kämpfst, sondern für alle von uns da draußen.",,,"Recuerda que no estás peleando solo por ti, sino por todos aquí y fuera.","Recuerda que no estás peleando solo por ti, sino por todos aquí y afuera.","Muista, ettet taistele vain itsesi, vaan kaikkien täällä olevien sekä ulkopuolisten puolesta.","Souviens-toi, tu ne te bats pas seulement pour toi, mais pour tous le monde ici et ailleurs.","Ne feledd, nem csak magadért harcolsz, hanem mindnyájunkért idebent, és odakint.","Ricordati che non stai combattendo solo per te stesso, ma per tutti quelli che sono qui e fuori.","貴方は自分自身だけでなく、 -国中の人の為に戦っている事を忘れないでくれよ。",너 혼자 위해서 싸우는 게 아니라 인류를 위해서 싸우고 있다는 걸 잊지 마.,"Onthoud dat je niet alleen voor jezelf vecht, maar voor iedereen hier en daarbuiten.","Husk at du ikke bare kjemper for deg selv, men for alle her og utenfor.","Pamiętaj, że nie walczysz tylko dla siebie, ale dla wszystkich tu i na zewnątrz.","Lembre-se que você não está lutando só por si mesmo, mas por todos nós.",,"Ține minte că nu lupți doar pentru tine, ci pentru toți de aici și de afară.","Помни, ты сражаешься не только за себя, но и за каждого здесь и снаружи.",,"Sadece kendiniz için değil, buradaki ve dışarıdaki herkes için savaştığınızı unutmayın." -"As long as one of us still stands, we will win.",TXT_RANDOM_REBEL_10,,,,"Dokud je alespoň jeden z nás na nohou, vyhrajeme!","Så længe en af os stadig står tilbage, vil vi vinde.","Solange nur einer von uns steht, werden wir gewinnen.",,"Dum iu ajn el ni ankoraŭ povos stari, ni venkos.","Mientras uno de nosotros siga en pie, ganaremos.","Mientras uno de nosotros siga en pie, vamos a ganar.","Niin kauan kuin yksikin meistä vielä seisoo, voitto on meidän.","Aussi longtemps qu'un de nous est vivant, nous vaincrons.","Ha csak egy is marad meg közülünk, nyerni fogunk.","Finché uno di noi rimarrà in piedi, vinceremo.",我々が一人でも立っていれば、それが勝利。,"우리 중 한 명이 남아있는 한, 이길 수 있어.","Zolang één van ons nog staat, zullen we winnen.","Så lenge en av oss fortsatt står, vil vi vinne.","Tak długo jak jeden z nas nadal będzie stał, tak długo będziemy wygrywać.","Enquanto um de nós ainda estiver de pé, teremos chance de vencer.",,"Atâta timp cât unul din noi trăiește, vom triumfa.","Пока хотя бы один из нас ещё дышит, мы непобедимы.",,İçimizden biri ayakta kaldığı sürece kazanacağız. -"Move along, peasant.",TXT_RANDOM_AGUARD_01,,,,"Jdi dál, poddaný.","Gå videre, bonde.","Beweg dich, Bauer!",,"Ne haltu, kampulo.","No te detengas, campesino.",,"Jatka matkaa, maallikko.","Barre-toi, paysan!","Mozgás, paraszt. Egy kettő.","Muoviti, cittadino.",立ち去れ、百姓。,"어서 움직여, 이 자식아.","Ga verder, boer.","Gå videre, bonde.","Ruszaj w drogę, chłopie.","Continue andando, plebeu.",,"Mișcă, sărmanule.","Проходи, рабочий.",,İlerle köylü. -"Follow the true faith, only then will you begin to understand.",TXT_RANDOM_AGUARD_02,,,,"Následuj pravou víru, jen tak začneš chápat.","Følg den sande tro, først da vil du begynde at forstå.",Folge dem wahren Glauben und du wirst verstehen.,,"Sekvu la veran kredon, nur tiel vi ekkomprenos.","Sigue la fe verdadera, solo entonces empezarás a entender.","Sigue la fe verdadera, solo así vas a entender.",Seuraa totista uskoa; vasta silloin alat käsittää.,"Suis la vraie foi, tu commençeras a comprendre.","Csak ha az igaz hitet követed, csakis akkor kezded majd megérteni.","Segui la vera fede, solo allora comincerai a capire.",真の信仰を求めよ、それしか理解に至る道はない。,참된 신앙이야말로 자기 자신을 깨우칠 수 있지.,"Volg het ware geloof, pas dan zul je het begrijpen.","Følg den sanne troen, først da vil du begynne å forstå.","Podążaj za prawdziwą wiarą, tylko wtedy zaczniesz rozumieć.",Siga a verdadeira fé. Só então você começará a entender.,,"Urmează crezul adevărat, doar atunci vei începe să înțelegi.",Следуй истинной вере. Только тогда ты начнёшь понимать.,,"Gerçek inancı takip et, ancak o zaman anlamaya başlarsın." -Only through death can one be truly reborn.,TXT_RANDOM_AGUARD_03,,,,Pouze skrz smrt lze dosáhnout znovuzrození.,Kun gennem døden kan man virkelig blive genfødt.,Nur durch den Tod kann man wirklich wiedergeboren werden.,,Nur per morto oni povas vere renaskiĝi.,Solo a través de la muerte uno puede realmente renacer.,,Vain kuoleman kautta voi totisesti uudestisyntyä.,C'est seulement a travers la mort que quelqu'un peut renaître.,Csak a halál útján lehet igazán újjászületni.,Solo attraverso la morte uno può rinascere per davvero.,人が真の意味で生まれ変われる方法は、死のみだ,죽음을 통해서만이 진정하게 환생할 수 있는 거다.,Alleen door de dood kan men echt herboren worden.,Bare gjennom døden kan man virkelig bli gjenfødt.,Tylko przez śmierć można się naprawdę odrodzić.,Somente através da morte que alguem poderá renascer de verdade.,,Doar prin moarte poate cineva să fie renăscut cu adevărat.,Истинное перерождение возможно только через смерть.,,İnsan ancak ölümle gerçekten yeniden doğabilir. -I'm not interested in your useless drivel.,TXT_RANDOM_AGUARD_04,,,,Nezajímají mě tvoje žvásty.,Jeg er ikke interesseret i dit ubrugelige sludder.,Dein nutzloses Geschwafel interessiert mich nicht.,,Ne interesas min aŭdi viajn sensencaĵojn.,No me interesa tu charlatanería.,No me interesa oír tus estupideces.,Joutava hölynpölysi ei minua kiinnosta.,Je ne suis pas intéressé par tes idioties inutiles.,Nem érdekel az értelmetlen hablatyolásod.,Non sono interessato alle tue ciance inutili.,お前の無益な戯言なぞ興味は無い。,네 잡담 따위는 듣고 싶지 않아.,Ik ben niet geïnteresseerd in je nutteloze gewauwel.,Jeg er ikke interessert i det unyttige vrøvlet ditt.,Nie interesują mnie twoje bezużyteczne brednie.,Não estou interessado em ouvir as suas bobagens inúteis.,,Nu sunt interesat de lipsa ta de sens.,Мне неинтересна твоя пустая болтовня.,,İşe yaramaz saçmalıklarınla ilgilenmiyorum. -If I had wanted to talk to you I would have told you so.,TXT_RANDOM_AGUARD_05,,,,"Kdybych s tebou chtěl mluvit, nařídil bych ti to.","Hvis jeg havde ønsket at tale med dig, ville jeg have sagt det til dig.","Wenn ich mich mit dir unterhalten wollte, hätte ich dir das gesagt.",,"Se mi volus paroli kun vi, mi unue dirus tion al vi.",Si quisiera hablar contigo te lo hubiera dicho.,,"Jos olisin halunnut puhua kanssasi, olisin sen sinulle ilmaissut.",Si j'avais voulu te parler je te l'aurais dit.,"Ha beszélni akartam volna veled, azt mondtam volna.","Se avessi voluto parlarti, te lo avrei detto.",話があったらこちらからする。,대화하고 싶었으면 내가 먼저 말을 걸었겠지. 안 그래?,"Als ik met je had willen praten, had ik je dat gezegd.","Hadde jeg villet snakke med deg, hadde jeg sagt det.","Gdybym chciał z tobą rozmawiać, powiedziałbym ci to.","Se eu quisesse falar com você, eu teria te dito.",,Dacă voiam să vorbim ți-aș fi spus.,"Если бы я хотел поговорить с тобой, то сказал бы об этом.",,"Seninle konuşmak isteseydim, bunu sana söylerdim." -Go and annoy someone else!,TXT_RANDOM_AGUARD_06,,,,Jdi otravovat někoho jiného!,Gå ud og irriter en anden!,Bitte nerve jemand anderen.,,Ĝenu aliulon!,¡Ve a molestar a otro!,,Mene ärsyttämään jotakuta toista!,Va ennuyer quelqu'un d'autre!,Menj és idegesíts valaki mást!,Vai a scocciare qualcun altro!,あまりイライラさせるな!,귀찮게 하지 말고 가서 딴 녀석이랑 놀아!,Ga iemand anders irriteren!,Gå og plag noen andre!,Idź i denerwuj kogoś innego!,Vá incomodar outra pessoa!,,Du-te și enervează pe altul.,Иди и надоедай кому-нибудь другому!,,Git ve başkasını rahatsız et! -Keep moving!,TXT_RANDOM_AGUARD_07,,,,Nezastavuj se!,Fortsæt med at bevæge dig!,Beweg dich!,,Plue piediru!,¡Sigue caminando!,,Ala laputtaa!,Bouge!,Mozgás!,Continua a muoverti!,立ち去れ!,여어 움직여라!,Blijf in beweging!,Gå videre!,Ruszaj się!,Continue andando!,,Continuă să mergi!,Иди куда шёл!,,Yürümeye devam et! -"If the alarm goes off, just stay out of our way!",TXT_RANDOM_AGUARD_08,,,,"Jestli je vyhlášen poplach, jdi nám z cesty!","Hvis alarmen går i gang, så hold dig bare væk fra os!","Wenn der Alarm losgeht, steh uns nicht im Weg!",,,"¡Si la alarma se activa, solo quítate de nuestro camino!",,"Jos hälytys laukeaa, pysy vain pois meidät tieltämme!","Si l'alarme s'enclenche, reste en dehors de notre chemin!","Ha beindul a riasztó, csak ne állj az utunkba.","Se scatta l'allarme, stattene fuori dai piedi!",警報を鳴らされたくないなら、邪魔をするな!,"만약 알람이 작동된다면, 기도하고 도망치기나 해!","Als het alarm afgaat, blijf dan gewoon uit de weg!","Hvis alarmen går, bare hold deg unna oss!","Jeśli włączy się alarm, po prostu zejdź nam z drogi!","Se o alarme disparar, não fique no nosso caminho!",,"Dacă alarma e declanșată, pur și simplu nu ne sta în cale.","Если поднимется тревога, не попадайся нам под ноги!",,"Alarm çalarsa, yolumuzdan çekilin!" +国中の人の為に戦っている事を忘れないでくれよ。",너 혼자 위해서 싸우는 게 아니라 인류를 위해서 싸우고 있다는 걸 잊지 마.,"Onthoud dat je niet alleen voor jezelf vecht, maar voor iedereen hier en daarbuiten.","Husk at du ikke bare kjemper for deg selv, men for alle her og utenfor.","Pamiętaj, że nie walczysz tylko dla siebie, ale dla wszystkich tu i na zewnątrz.","Lembre-se que você não está lutando só por si mesmo, mas por todos nós.",,"Ține minte că nu lupți doar pentru tine, ci pentru toți de aici și de afară.","Помни, ты сражаешься не только за себя, но и за каждого здесь и снаружи.",,"Kom ihåg att du inte bara kämpar för dig själv, utan för alla här och utanför.","Sadece kendiniz için değil, buradaki ve dışarıdaki herkes için savaştığınızı unutmayın." +"As long as one of us still stands, we will win.",TXT_RANDOM_REBEL_10,,,,"Dokud je alespoň jeden z nás na nohou, vyhrajeme!","Så længe en af os stadig står tilbage, vil vi vinde.","Solange nur einer von uns steht, werden wir gewinnen.",,"Dum iu ajn el ni ankoraŭ povos stari, ni venkos.","Mientras uno de nosotros siga en pie, ganaremos.","Mientras uno de nosotros siga en pie, vamos a ganar.","Niin kauan kuin yksikin meistä vielä seisoo, voitto on meidän.","Aussi longtemps qu'un de nous est vivant, nous vaincrons.","Ha csak egy is marad meg közülünk, nyerni fogunk.","Finché uno di noi rimarrà in piedi, vinceremo.",我々が一人でも立っていれば、それが勝利。,"우리 중 한 명이 남아있는 한, 이길 수 있어.","Zolang één van ons nog staat, zullen we winnen.","Så lenge en av oss fortsatt står, vil vi vinne.","Tak długo jak jeden z nas nadal będzie stał, tak długo będziemy wygrywać.","Enquanto um de nós ainda estiver de pé, teremos chance de vencer.",,"Atâta timp cât unul din noi trăiește, vom triumfa.","Пока хотя бы один из нас ещё дышит, мы непобедимы.",,Så länge en av oss fortfarande står kvar kommer vi att vinna.,İçimizden biri ayakta kaldığı sürece kazanacağız. +"Move along, peasant.",TXT_RANDOM_AGUARD_01,,,,"Jdi dál, poddaný.","Gå videre, bonde.","Beweg dich, Bauer!",,"Ne haltu, kampulo.","No te detengas, campesino.",,"Jatka matkaa, maallikko.","Barre-toi, paysan!","Mozgás, paraszt. Egy kettő.","Muoviti, cittadino.",立ち去れ、百姓。,"어서 움직여, 이 자식아.","Ga verder, boer.","Gå videre, bonde.","Ruszaj w drogę, chłopie.","Continue andando, plebeu.",,"Mișcă, sărmanule.","Проходи, рабочий.",,"Gå vidare, bonde.",İlerle köylü. +"Follow the true faith, only then will you begin to understand.",TXT_RANDOM_AGUARD_02,,,,"Následuj pravou víru, jen tak začneš chápat.","Følg den sande tro, først da vil du begynde at forstå.",Folge dem wahren Glauben und du wirst verstehen.,,"Sekvu la veran kredon, nur tiel vi ekkomprenos.","Sigue la fe verdadera, solo entonces empezarás a entender.","Sigue la fe verdadera, solo así vas a entender.",Seuraa totista uskoa; vasta silloin alat käsittää.,"Suis la vraie foi, tu commençeras a comprendre.","Csak ha az igaz hitet követed, csakis akkor kezded majd megérteni.","Segui la vera fede, solo allora comincerai a capire.",真の信仰を求めよ、それしか理解に至る道はない。,참된 신앙이야말로 자기 자신을 깨우칠 수 있지.,"Volg het ware geloof, pas dan zul je het begrijpen.","Følg den sanne troen, først da vil du begynne å forstå.","Podążaj za prawdziwą wiarą, tylko wtedy zaczniesz rozumieć.",Siga a verdadeira fé. Só então você começará a entender.,,"Urmează crezul adevărat, doar atunci vei începe să înțelegi.",Следуй истинной вере. Только тогда ты начнёшь понимать.,,"Följ den sanna tron, först då kommer du att börja förstå.","Gerçek inancı takip et, ancak o zaman anlamaya başlarsın." +Only through death can one be truly reborn.,TXT_RANDOM_AGUARD_03,,,,Pouze skrz smrt lze dosáhnout znovuzrození.,Kun gennem døden kan man virkelig blive genfødt.,Nur durch den Tod kann man wirklich wiedergeboren werden.,,Nur per morto oni povas vere renaskiĝi.,Solo a través de la muerte uno puede realmente renacer.,,Vain kuoleman kautta voi totisesti uudestisyntyä.,C'est seulement a travers la mort que quelqu'un peut renaître.,Csak a halál útján lehet igazán újjászületni.,Solo attraverso la morte uno può rinascere per davvero.,人が真の意味で生まれ変われる方法は、死のみだ,죽음을 통해서만이 진정하게 환생할 수 있는 거다.,Alleen door de dood kan men echt herboren worden.,Bare gjennom døden kan man virkelig bli gjenfødt.,Tylko przez śmierć można się naprawdę odrodzić.,Somente através da morte que alguem poderá renascer de verdade.,,Doar prin moarte poate cineva să fie renăscut cu adevărat.,Истинное перерождение возможно только через смерть.,,Endast genom döden kan man verkligen återfödas.,İnsan ancak ölümle gerçekten yeniden doğabilir. +I'm not interested in your useless drivel.,TXT_RANDOM_AGUARD_04,,,,Nezajímají mě tvoje žvásty.,Jeg er ikke interesseret i dit ubrugelige sludder.,Dein nutzloses Geschwafel interessiert mich nicht.,,Ne interesas min aŭdi viajn sensencaĵojn.,No me interesa tu charlatanería.,No me interesa oír tus estupideces.,Joutava hölynpölysi ei minua kiinnosta.,Je ne suis pas intéressé par tes idioties inutiles.,Nem érdekel az értelmetlen hablatyolásod.,Non sono interessato alle tue ciance inutili.,お前の無益な戯言なぞ興味は無い。,네 잡담 따위는 듣고 싶지 않아.,Ik ben niet geïnteresseerd in je nutteloze gewauwel.,Jeg er ikke interessert i det unyttige vrøvlet ditt.,Nie interesują mnie twoje bezużyteczne brednie.,Não estou interessado em ouvir as suas bobagens inúteis.,,Nu sunt interesat de lipsa ta de sens.,Мне неинтересна твоя пустая болтовня.,,Jag är inte intresserad av ditt värdelösa dravel.,İşe yaramaz saçmalıklarınla ilgilenmiyorum. +If I had wanted to talk to you I would have told you so.,TXT_RANDOM_AGUARD_05,,,,"Kdybych s tebou chtěl mluvit, nařídil bych ti to.","Hvis jeg havde ønsket at tale med dig, ville jeg have sagt det til dig.","Wenn ich mich mit dir unterhalten wollte, hätte ich dir das gesagt.",,"Se mi volus paroli kun vi, mi unue dirus tion al vi.",Si quisiera hablar contigo te lo hubiera dicho.,,"Jos olisin halunnut puhua kanssasi, olisin sen sinulle ilmaissut.",Si j'avais voulu te parler je te l'aurais dit.,"Ha beszélni akartam volna veled, azt mondtam volna.","Se avessi voluto parlarti, te lo avrei detto.",話があったらこちらからする。,대화하고 싶었으면 내가 먼저 말을 걸었겠지. 안 그래?,"Als ik met je had willen praten, had ik je dat gezegd.","Hadde jeg villet snakke med deg, hadde jeg sagt det.","Gdybym chciał z tobą rozmawiać, powiedziałbym ci to.","Se eu quisesse falar com você, eu teria te dito.",,Dacă voiam să vorbim ți-aș fi spus.,"Если бы я хотел поговорить с тобой, то сказал бы об этом.",,Om jag hade velat prata med dig hade jag sagt det till dig.,"Seninle konuşmak isteseydim, bunu sana söylerdim." +Go and annoy someone else!,TXT_RANDOM_AGUARD_06,,,,Jdi otravovat někoho jiného!,Gå ud og irriter en anden!,Bitte nerve jemand anderen.,,Ĝenu aliulon!,¡Ve a molestar a otro!,,Mene ärsyttämään jotakuta toista!,Va ennuyer quelqu'un d'autre!,Menj és idegesíts valaki mást!,Vai a scocciare qualcun altro!,あまりイライラさせるな!,귀찮게 하지 말고 가서 딴 녀석이랑 놀아!,Ga iemand anders irriteren!,Gå og plag noen andre!,Idź i denerwuj kogoś innego!,Vá incomodar outra pessoa!,,Du-te și enervează pe altul.,Иди и надоедай кому-нибудь другому!,,Gå och irriter någon annan!,Git ve başkasını rahatsız et! +Keep moving!,TXT_RANDOM_AGUARD_07,,,,Nezastavuj se!,Fortsæt med at bevæge dig!,Beweg dich!,,Plue piediru!,¡Sigue caminando!,,Ala laputtaa!,Bouge!,Mozgás!,Continua a muoverti!,立ち去れ!,여어 움직여라!,Blijf in beweging!,Gå videre!,Ruszaj się!,Continue andando!,,Continuă să mergi!,Иди куда шёл!,,Fortsätt att röra på dig!,Yürümeye devam et! +"If the alarm goes off, just stay out of our way!",TXT_RANDOM_AGUARD_08,,,,"Jestli je vyhlášen poplach, jdi nám z cesty!","Hvis alarmen går i gang, så hold dig bare væk fra os!","Wenn der Alarm losgeht, steh uns nicht im Weg!",,,"¡Si la alarma se activa, solo quítate de nuestro camino!",,"Jos hälytys laukeaa, pysy vain pois meidät tieltämme!","Si l'alarme s'enclenche, reste en dehors de notre chemin!","Ha beindul a riasztó, csak ne állj az utunkba.","Se scatta l'allarme, stattene fuori dai piedi!",警報を鳴らされたくないなら、邪魔をするな!,"만약 알람이 작동된다면, 기도하고 도망치기나 해!","Als het alarm afgaat, blijf dan gewoon uit de weg!","Hvis alarmen går, bare hold deg unna oss!","Jeśli włączy się alarm, po prostu zejdź nam z drogi!","Se o alarme disparar, não fique no nosso caminho!",,"Dacă alarma e declanșată, pur și simplu nu ne sta în cale.","Если поднимется тревога, не попадайся нам под ноги!",,"Om larmet går, håll dig bara ur vägen!","Alarm çalarsa, yolumuzdan çekilin!" The Order will cleanse the world and usher it into the new era.,TXT_RANDOM_AGUARD_09,,,,Řád pročistí náš svět a navede ho do nového věku.,Ordenen vil rense verden og føre den ind i den nye æra.,Der Orden wird die Welt läutern und in eine neue Ära führen.,,,La Orden limpiará el mundo y marcará el inicio de la nueva era.,La Orden va a limpiar el mundo y marcar el inicio de la nueva era.,Veljeskunta puhdistaa tämän maailman ja johdattaa sen uudelle aikakaudelle.,L'ordre nettoira le monde et le conduira dans une nouvelle ère.,"A Rend megtisztítja a világot, és egy új korszakba vezeti.",L'ordine ripulirà questo mondo e lo porterà verso una nuova era.,"オーダーは世界を浄化し、 我々を新しい時代へ導いてくれる。",우리 오더는 언젠간 이 세상을 정화하고 새로운 시대를 만들 것이다.,De orde zal de wereld zuiveren en het nieuwe tijdperk inluiden.,Ordenen vil rense verden og føre den inn i en ny æra.,Zakon oczyści świat i wprowadzi go w nową erę.,A Ordem purificará o mundo e o conduzirá para a nova era.,,Ordinul va curăța lumea și ne va propulsa într-o nouă eră.,"Орден очистит этот мир и положит начало новой эре! -",,Tarikat dünyayı temizleyecek ve yeni bir çağ başlatacak. -"Problem? No, I thought not.",TXT_RANDOM_AGUARD_10,,,,"Nějaký problém? Ne, není.","Problemer? Nej, det troede jeg ikke.","Hast du Probleme? Nein, ich glaube nicht.",,"Ĉu ia problemo? Ne, tiel, kiel mi jam pensis.","¿Algún problema? No, como ya me imaginaba.",,"Jokin ongelma? Ei, niin arvelinkin.",Un problème? Je pense que non.,Baj van? Nem? Én is így gondoltam.,"Qualche problema? No, come pensavo.",問題か? そうは思わないが。,문제가 있다고? 자. 이제 없지?,"Probleem? Nee, ik dacht van niet.","Problemer? Nei, jeg trodde ikke det.","Problem? Nie, nie sądziłem.",Algum problema? Imaginei que não.,,"Probleme? Nu, așa credeam și eu.",Что-то не так? Нет? Я так и думал.,,"Sorun mu var? Hayır, ben de öyle düşünmüştüm." -Alms for the poor?,TXT_RANDOM_BEGGAR_01,,,,Almužnu pro chudáka?,Almisser til de fattige?,Almosen für die Armen.,,Ĉu vi havas almozon por malriĉuloj?,¿Limosnas para los pobres?,,Almuja köyhälle?,L'aumône pour les pauvres?,Alamizsna a szegényeknek?,Elemosina per i poveri?,貧民に何か恵んでくれるのか?,부디 빈민에게 구호를...,Aalmoezen voor de armen?,Almisser til de fattige?,Jałmużna dla biednych?,Uma ajuda para os pobres?,,Ceva pentru ce-i sărmani?,У тебя не найдётся мелочи для бедняка?,,Fakirler için sadaka mı? -"What are you looking at, surfacer?",TXT_RANDOM_BEGGAR_02,,,,"Na co koukáš, nadzemníku?","Hvad kigger du på, overfladeklipper?","Wonach suchst du, Oberflächler?",,,"¿Que estás mirando, prejuicioso?",,"Mitä tuijotat, maanpintalainen?","Tu regarde qui, habitant de la surface?","Mit nézel, felszínlakó?","Cosa stai guardando, abitante della superficie?",何ジロジロ見てる、地上人。,"어딜 보고 있는 겁니까, 지상인씨?","Waar kijk je naar, oppervlaktebewoner? ","Hva glor du på, overflatebehandler?","Na co się patrzysz, surferze?","Tá olhando o quê, habitante da superfície?",,La ce te uiți?,"Что уставился, незнакомец?",,"Neye bakıyorsun, sörfçü?" -"You wouldn't have any extra food, would you?",TXT_RANDOM_BEGGAR_03,,,,Neměl bys náhodou něco navíc k snědku?,"Du har vel ikke noget ekstra mad, vel?","Du hast nichts zu Essen übrig, oder?",,"Vi ne havas iom da restaj manĝaĵoj, ĉu?","No tendrás algo de comida que te sobre, ¿no?",,Ei sinulla sattuisi olemaan ylimääräistä ruokaa?,Aurais-tu de la nourriture en trop sur toi?,"Nincs egy kis felesleges ételed, ugye?",Tu non avresti del cibo avanzato da darci?,余ってる食べ物とかはないよな?,남은 식량 가지고 있습니까? 부디 있다고 말해주세요... 제발...,"Je zou toch geen extra eten hebben, of wel?",Du har vel ikke noe ekstra mat?,"Nie mielibyście żadnego dodatkowego jedzenia, prawda?","Por acaso você não tem comida sobrando, tem?",,"Nu ai mâncare în plus, nu-i așa?",У тебя случайно не найдётся немного лишней еды?,,"Fazladan yiyeceğin olmazdı, değil mi?" +",,Orden kommer att rena världen och föra in den i den nya eran.,Tarikat dünyayı temizleyecek ve yeni bir çağ başlatacak. +"Problem? No, I thought not.",TXT_RANDOM_AGUARD_10,,,,"Nějaký problém? Ne, není.","Problemer? Nej, det troede jeg ikke.","Hast du Probleme? Nein, ich glaube nicht.",,"Ĉu ia problemo? Ne, tiel, kiel mi jam pensis.","¿Algún problema? No, como ya me imaginaba.",,"Jokin ongelma? Ei, niin arvelinkin.",Un problème? Je pense que non.,Baj van? Nem? Én is így gondoltam.,"Qualche problema? No, come pensavo.",問題か? そうは思わないが。,문제가 있다고? 자. 이제 없지?,"Probleem? Nee, ik dacht van niet.","Problemer? Nei, jeg trodde ikke det.","Problem? Nie, nie sądziłem.",Algum problema? Imaginei que não.,,"Probleme? Nu, așa credeam și eu.",Что-то не так? Нет? Я так и думал.,,"Problem? Nej, det trodde jag inte.","Sorun mu var? Hayır, ben de öyle düşünmüştüm." +Alms for the poor?,TXT_RANDOM_BEGGAR_01,,,,Almužnu pro chudáka?,Almisser til de fattige?,Almosen für die Armen.,,Ĉu vi havas almozon por malriĉuloj?,¿Limosnas para los pobres?,,Almuja köyhälle?,L'aumône pour les pauvres?,Alamizsna a szegényeknek?,Elemosina per i poveri?,貧民に何か恵んでくれるのか?,부디 빈민에게 구호를...,Aalmoezen voor de armen?,Almisser til de fattige?,Jałmużna dla biednych?,Uma ajuda para os pobres?,,Ceva pentru ce-i sărmani?,У тебя не найдётся мелочи для бедняка?,,Almosor till de fattiga?,Fakirler için sadaka mı? +"What are you looking at, surfacer?",TXT_RANDOM_BEGGAR_02,,,,"Na co koukáš, nadzemníku?","Hvad kigger du på, overfladeklipper?","Wonach suchst du, Oberflächler?",,,"¿Que estás mirando, prejuicioso?",,"Mitä tuijotat, maanpintalainen?","Tu regarde qui, habitant de la surface?","Mit nézel, felszínlakó?","Cosa stai guardando, abitante della superficie?",何ジロジロ見てる、地上人。,"어딜 보고 있는 겁니까, 지상인씨?","Waar kijk je naar, oppervlaktebewoner? ","Hva glor du på, overflatebehandler?","Na co się patrzysz, surferze?","Tá olhando o quê, habitante da superfície?",,La ce te uiți?,"Что уставился, незнакомец?",,"Vad tittar du på, ytmänniska?","Neye bakıyorsun, sörfçü?" +"You wouldn't have any extra food, would you?",TXT_RANDOM_BEGGAR_03,,,,Neměl bys náhodou něco navíc k snědku?,"Du har vel ikke noget ekstra mad, vel?","Du hast nichts zu Essen übrig, oder?",,"Vi ne havas iom da restaj manĝaĵoj, ĉu?","No tendrás algo de comida que te sobre, ¿no?",,Ei sinulla sattuisi olemaan ylimääräistä ruokaa?,Aurais-tu de la nourriture en trop sur toi?,"Nincs egy kis felesleges ételed, ugye?",Tu non avresti del cibo avanzato da darci?,余ってる食べ物とかはないよな?,남은 식량 가지고 있습니까? 부디 있다고 말해주세요... 제발...,"Je zou toch geen extra eten hebben, of wel?",Du har vel ikke noe ekstra mat?,"Nie mielibyście żadnego dodatkowego jedzenia, prawda?","Por acaso você não tem comida sobrando, tem?",,"Nu ai mâncare în plus, nu-i așa?",У тебя случайно не найдётся немного лишней еды?,,"Du skulle inte ha någon extra mat, eller hur?","Fazladan yiyeceğin olmazdı, değil mi?" You surface people will never understand us.,TXT_RANDOM_BEGGAR_04,,,,Vy lidi z povrchu nás nikdy nepochopíte.,I overflademennesker vil aldrig forstå os.,Ihr Oberflächenleute werdet uns nie verstehen.,,"Vi, surfaco-loĝantoj, neniam komprenos nin.","Vosotros, gente de la superficie, nunca nos entenderéis.","Ustedes, gente de la superficie, jamás nos van a entender.",Te maanpinnan asukit ette meitä koskaan tule ymmärtämään.,"Vous, les gens de la surface, vous ne comprendrez jamais.",Ti felszíniek sosem fogtok megérteni minket.,Voi abitanti della superficie non ci comprenderete mai.,"お前みたいな地上の連中には俺らのことなんて -わかりゃしない。",당신 같은 지상인들은 우리를 아예 도와주지도 않죠. 그렇지 않나요?,Je zult mensen ons nooit begrijpen.,Dere overflatefolk vil aldri forstå oss.,"Wy, ludzie powierzchni, nigdy nas nie zrozumiecie.",Vocês da superfície nunca nos entenderão.,,Voi oamenii de la suprafață nu veți înțelege niciodată.,"Вы, люди с поверхности, никогда не поймёте нас.",,Siz yüzey insanları bizi asla anlamayacaksınız. +わかりゃしない。",당신 같은 지상인들은 우리를 아예 도와주지도 않죠. 그렇지 않나요?,Je zult mensen ons nooit begrijpen.,Dere overflatefolk vil aldri forstå oss.,"Wy, ludzie powierzchni, nigdy nas nie zrozumiecie.",Vocês da superfície nunca nos entenderão.,,Voi oamenii de la suprafață nu veți înțelege niciodată.,"Вы, люди с поверхности, никогда не поймёте нас.",,Ni ytliga människor kommer aldrig att förstå oss.,Siz yüzey insanları bizi asla anlamayacaksınız. "Ha, the guards can't find us. Those idiots don't even know we exist.",TXT_RANDOM_BEGGAR_05,,,,"Ha, stráže nás nenajdou. Ti idioti ani neví, že existujeme.","Ha, vagterne kan ikke finde os. De idioter ved ikke engang, at vi eksisterer.","Ha, die Wächter können uns nicht finden. Die Idioten ahnen nicht mal, dass wir existieren.",,,"Ja, los guardias no nos encontrarán. Esos idiotas ni siquiera saben que existimos.",,"Hah, vartijat eivät pysty löytämään meitä. Ne idiootit eivät edes tiedä olemassaolostamme.","Ha, les gardes ne nous trouveront jamais, ces idiots ne savent même pas qu'on existe!","Ha! Az őrök az életben nem találnak meg minket. Azok a barmok azt sem tudják, hogy létezünk.","Ha, le guardie non ci trovano. Quegli idioti non sanno neppure della nostra esistenza.","衛兵共は俺らを見つけられない。 あのバカどもは俺らがここに居ることすら -知らないんだぞ。","하, 저 멍청한 경비들은 우리가 이 밑에 숨어있다는 걸 모르죠!","Ha, de bewakers kunnen ons niet vinden. Die idioten weten niet eens dat we bestaan.",Vaktene kan ikke finne oss. De idiotene vet ikke engang at vi eksisterer.,"Strażnicy nie mogą nas znaleźć. Ci idioci nawet nie wiedzą, że istniejemy.","Hah, os guardas não conseguem nos achar. Esses idiotas nem sabem que a gente existe.",,"Ha, gardienii nu ne pot găsi. Idioții ăștia nici măcar nu știu de existența noastră.","Ха! Эта глупая стража никогда не найдёт нас. Они даже не знают, что мы существуем.",,"Ha, muhafızlar bizi bulamaz. O aptallar varlığımızdan bile haberdar değiller." +知らないんだぞ。","하, 저 멍청한 경비들은 우리가 이 밑에 숨어있다는 걸 모르죠!","Ha, de bewakers kunnen ons niet vinden. Die idioten weten niet eens dat we bestaan.",Vaktene kan ikke finne oss. De idiotene vet ikke engang at vi eksisterer.,"Strażnicy nie mogą nas znaleźć. Ci idioci nawet nie wiedzą, że istniejemy.","Hah, os guardas não conseguem nos achar. Esses idiotas nem sabem que a gente existe.",,"Ha, gardienii nu ne pot găsi. Idioții ăștia nici măcar nu știu de existența noastră.","Ха! Эта глупая стража никогда не найдёт нас. Они даже не знают, что мы существуем.",,"Ha, vakterna kan inte hitta oss. De idioterna vet inte ens att vi finns.","Ha, muhafızlar bizi bulamaz. O aptallar varlığımızdan bile haberdar değiller." One day everyone but those who serve the Order will be forced to join us.,TXT_RANDOM_BEGGAR_06,,,,"Jednoho dne se všichni, kdo neslouží Řádu, budou muset přidat k nám.","En dag vil alle undtagen dem, der tjener ordenen, blive tvunget til at slutte sig til os.","Eines Tages werden alle, die nicht dem Orden dienen, sich uns anschließen.",,"Iun tagon ĉiuj, krom la servantoj de La Ordono, estos devigataj aliĝi al ni.","Algún día todos, excepto aquellos que sirven a La Orden, serán forzados a unirse a nosotros.","Algún día todos, menos aquellos que le sirven a La Orden, se van a ver obligados a unirse a nosotros.",Jonain päivänä kaikkien paitsi Veljeskuntaa palvelevien on liityttävä meihin.,"Un jour, tous sauf les membres de l'ordre seront forcés de nous rejoindre.","Egy nap mindenki, kivéve a Rend szolgálói arra kényszerülnek majd, hogy hozzánk tartozzanak.","Un giorno tutti, salvo chi serve l'Ordine, sarà costretto ad unirsi a noi.","そのうち、オーダーに仕える者を除いて 全ての人間が私達のようになることを -強いられるだろう。",언젠가는 순종하는 사람들을 제외하고는 모두가 오더에 강제병합될지도 몰라요...,"Op een dag zal iedereen, behalve degenen die de Orde dienen, gedwongen worden om zich bij ons aan te sluiten.",En dag vil alle unntatt de som tjener Ordenen bli tvunget til å slutte seg til oss.,"Pewnego dnia wszyscy poza tymi, którzy służą Zakonowi, będą zmuszeni do przyłączenia się do nas.",Um dia todos exceto aqueles que servem à Ordem serão forçados a se juntarem a nós.,,Într-o bună zi toți în afară de cei care slujesc Ordinul vor fi nevoiți să ni se alăture.,"Однажды всем, кто не служит Ордену, придётся присоединиться к нам.",,Bir gün Tarikat'a hizmet edenler dışında herkes bize katılmak zorunda kalacak. +強いられるだろう。",언젠가는 순종하는 사람들을 제외하고는 모두가 오더에 강제병합될지도 몰라요...,"Op een dag zal iedereen, behalve degenen die de Orde dienen, gedwongen worden om zich bij ons aan te sluiten.",En dag vil alle unntatt de som tjener Ordenen bli tvunget til å slutte seg til oss.,"Pewnego dnia wszyscy poza tymi, którzy służą Zakonowi, będą zmuszeni do przyłączenia się do nas.",Um dia todos exceto aqueles que servem à Ordem serão forçados a se juntarem a nós.,,Într-o bună zi toți în afară de cei care slujesc Ordinul vor fi nevoiți să ni se alăture.,"Однажды всем, кто не служит Ордену, придётся присоединиться к нам.",,En dag kommer alla utom de som tjänar Orden att tvingas ansluta sig till oss.,Bir gün Tarikat'a hizmet edenler dışında herkes bize katılmak zorunda kalacak. "Stare now, but you know that this will be your own face one day.",TXT_RANDOM_BEGGAR_07,,,,"Teď zíráš, ale věz, že tohle bude jednou tvá tvář.","Stir nu, men du ved, at dette vil være dit eget ansigt en dag.","Glotz nur, aber irgendwann wirst du auch so aussehen.",,,"Observa ahora, pero ya sabes que esta será tu propia cara algún día.",,"Tuijotat nyt, mutta tiedä, että jonain päivänä nämä ovat sinun kasvosi.","Moque nous si tu veux, mais tu sais que ceci sera aussi ton sort un jour.","Bámulj csak, de tudd, hogy egy nap ez az arc a sajátod lesz.","Osservaci pure, ma tu sai bene che un giorno questa sarà la tua faccia.","今ジロジロ見てたみたいだが、 -お前もいつかこんな顔になるだろうな。",배꼽 잡고 웃으시구려. 결국엔 당신도 이 모양 이 꼴이 될 테니까.,"Staar nu, maar je weet dat dit op een dag je eigen gezicht zal zijn.","Stirr nå, men du vet at dette vil bli ditt eget ansikt en dag.","Gap się teraz, ale wiesz, że to będzie kiedyś twoja własna twarz.","Pode ficar olhando, mas você sabe que este será o seu próprio rosto um dia.",,"Te holbezi acum, dar asta va fi soarta ta într-o zi.","Смотри сколько влезет, но знай, что когда-нибудь так будет выглядеть и твоё лицо.",,"Şimdi bak, ama biliyorsun ki bu bir gün senin de yüzün olacak." -There's nothing more annoying than a surfacer with an attitude!,TXT_RANDOM_BEGGAR_08,,,,Není nic otravnějšího než nadzemník s dobrou náladou!,Der er intet mere irriterende end en surfacer med en attitude!,Es gibt nichts nervigeres als einen Oberflächler mit Gesinnung.,,,¡No hay nada más irritante que una persona de la superficie con mala actitud!,,Ei ole mitään ärsyttävämpää kuin töykeä maanpintalainen!,Il n'y rien de plus barbant qu'un type de la surface et son orgeuil!,Nincs bosszantóbb egy felszíninél ilyen hozzáállással.,Non c'è nulla di più seccante di un abitante della superficie saccente!,腹立たしい地上人の態度は悩みの種だ!,버릇없는 지상인 보다 더 짜증 나는 건 없을 거예요!,Er is niets vervelender dan een verharder met een houding!,Det er ikke noe mer irriterende enn en overflatebehandler med en holdning!,Nie ma nic bardziej irytującego niż surfer z nastawieniem!,Não há nada mais irritante do que alguém da superfície cheio de si!,,Nu e nimic mai enervant decât o persoană de la suprafață cu fițe!,"Ничто так не выводит из себя, как болтун с поверхности!",,Tavırlı bir sörfçüden daha sinir bozucu bir şey yoktur! +お前もいつかこんな顔になるだろうな。",배꼽 잡고 웃으시구려. 결국엔 당신도 이 모양 이 꼴이 될 테니까.,"Staar nu, maar je weet dat dit op een dag je eigen gezicht zal zijn.","Stirr nå, men du vet at dette vil bli ditt eget ansikt en dag.","Gap się teraz, ale wiesz, że to będzie kiedyś twoja własna twarz.","Pode ficar olhando, mas você sabe que este será o seu próprio rosto um dia.",,"Te holbezi acum, dar asta va fi soarta ta într-o zi.","Смотри сколько влезет, но знай, что когда-нибудь так будет выглядеть и твоё лицо.",,"Stirra nu, men du vet att detta kommer att vara ditt eget ansikte en dag.","Şimdi bak, ama biliyorsun ki bu bir gün senin de yüzün olacak." +There's nothing more annoying than a surfacer with an attitude!,TXT_RANDOM_BEGGAR_08,,,,Není nic otravnějšího než nadzemník s dobrou náladou!,Der er ikke noget mere irriterende end en overfladebeboer med en attitude!,Es gibt nichts nervigeres als einen Oberflächler mit Gesinnung.,,,¡No hay nada más irritante que una persona de la superficie con mala actitud!,,Ei ole mitään ärsyttävämpää kuin töykeä maanpintalainen!,Il n'y rien de plus barbant qu'un type de la surface et son orgeuil!,Nincs bosszantóbb egy felszíninél ilyen hozzáállással.,Non c'è nulla di più seccante di un abitante della superficie saccente!,腹立たしい地上人の態度は悩みの種だ!,버릇없는 지상인 보다 더 짜증 나는 건 없을 거예요!,Er is niets vervelender dan een verharder met een houding!,Det er ikke noe mer irriterende enn en overflatebehandler med en holdning!,Nie ma nic bardziej irytującego niż surfer z nastawieniem!,Não há nada mais irritante do que alguém da superfície cheio de si!,,Nu e nimic mai enervant decât o persoană de la suprafață cu fițe!,"Ничто так не выводит из себя, как болтун с поверхности!",,Det finns inget mer irriterande än en ytmänniska med attityd!,Tavırlı bir sörfçüden daha sinir bozucu bir şey yoktur! The Order will make short work of your pathetic Front.,TXT_RANDOM_BEGGAR_09,,,,Řád s tou vaší patetickou Frontou udělá krátký proces.,Ordenen vil gøre kort proces med din patetiske front.,Der Orden wird eure armselige Front auseinandernehmen.,,La Ordono detruos senprobleme vian ridindan Fronton.,La Orden acabará fácilmente con vuestro patético Frente.,La Orden va a destruir como si nada su patético Frente.,Veljeskunta tekee nopeasti selvän säälittävästä Rintamastanne.,L'ordre se débarrassera de vos soldats pathétiques.,A Rendnek gyerekjáték lesz a szánalmas kis Frontotok.,L'Ordine farà facilmente fuori il vostro patetico Fronte.,"オーダーはアンタの哀れなフロントに近付いてる -ってさ。",오더가 당신을 비롯한 한심한 프론트 저항군을 싹슬이할 겁니다.,De Orde zal kort werk maken van je zielige Front.,Ordenen vil gjøre kort prosess med din patetiske Front.,Zakon szybko rozprawi się z twoim żałosnym frontem.,A Ordem vai dar um jeito em vocês da Frente.,,Ordinul va face preș din Frontul tău.,Орден быстро расправится с твоим бессильным сопротивлением.,,Tarikat senin acınası cepheni kısa sürede halledecektir. -"Watch yourself, surfacer. We know our enemies!",TXT_RANDOM_BEGGAR_10,,,,"Dávej si pozor, nadzemníku. Známe své nepřátele!","Pas på dig selv, surfacer. Vi kender vores fjender!","Pass nur auf, Oberflächler. Wir kennen unsere Feinde.",,"Atentu, surfaco-loĝanto. Ni konas niajn malamikojn!","Cuidado, habitante de la superficie. ¡Nosotros conocemos a nuestros enemigos!",,"Pidä varasi, maanpintalainen. Tunnemme vihollisemme!","Prend guarde a toi, habitant de la surface. Nous connaîssons nos ennemis!","Óvakodj, felszíni! Ismerjük az ellenségeinket!","Stai attento, abitante della superficie. Conosciamo i nostri nemici!",気を付けろ、地上人。敵はアンタを知ってるぞ。,"조심하시오, 지상인. 우리는 적이 누군지 알고 있으니!","Let op jezelf, surfacer. Wij kennen onze vijanden!","Pass deg, overflatebehandler. Vi kjenner våre fiender!","Uważaj na siebie, surferze. Znamy naszych wrogów!","Cuidado, ô da superficie. Nós sabemos quem são os nossos inimigos!",,"Ai grijă, omule de la suprafață! Ne cunoaștem inamicii.","Поосторожнее, человек с поверхности. Мы знаем, кто наш враг!",,"Kendine dikkat et, sörfçü. Düşmanlarımızı tanıyoruz!" +ってさ。",오더가 당신을 비롯한 한심한 프론트 저항군을 싹슬이할 겁니다.,De Orde zal kort werk maken van je zielige Front.,Ordenen vil gjøre kort prosess med din patetiske Front.,Zakon szybko rozprawi się z twoim żałosnym frontem.,A Ordem vai dar um jeito em vocês da Frente.,,Ordinul va face preș din Frontul tău.,Орден быстро расправится с твоим бессильным сопротивлением.,,Orden kommer att göra processen kort med din patetiska front.,Tarikat senin acınası cepheni kısa sürede halledecektir. +"Watch yourself, surfacer. We know our enemies!",TXT_RANDOM_BEGGAR_10,,,,"Dávej si pozor, nadzemníku. Známe své nepřátele!","Pas på dig selv, overfladebeboer. Vi kender vores fjender!","Pass nur auf, Oberflächler. Wir kennen unsere Feinde.",,"Atentu, surfaco-loĝanto. Ni konas niajn malamikojn!","Cuidado, habitante de la superficie. ¡Nosotros conocemos a nuestros enemigos!",,"Pidä varasi, maanpintalainen. Tunnemme vihollisemme!","Prend guarde a toi, habitant de la surface. Nous connaîssons nos ennemis!","Óvakodj, felszíni! Ismerjük az ellenségeinket!","Stai attento, abitante della superficie. Conosciamo i nostri nemici!",気を付けろ、地上人。敵はアンタを知ってるぞ。,"조심하시오, 지상인. 우리는 적이 누군지 알고 있으니!","Pas op, oppervlaktebewoner. We kennen onze vijanden!","Pass deg, overflatebehandler. Vi kjenner våre fiender!","Uważaj na siebie, surferze. Znamy naszych wrogów!","Cuidado, ô da superficie. Nós sabemos quem são os nossos inimigos!",,"Ai grijă, omule de la suprafață! Ne cunoaștem inamicii.","Поосторожнее, человек с поверхности. Мы знаем, кто наш враг!",,"Se upp, ytmänniska. Vi känner våra fiender!","Kendine dikkat et, sörfçü. Düşmanlarımızı tanıyoruz!" We are the hands of fate. To earn our wrath is to find oblivion!,TXT_RANDOM_PGUARD_01,,,,Jsme rukama osudu. Získat si náš hněv je jako upadnout v zapomnění!,Vi er skæbnens hænder. At gøre sig fortjent til vores vrede er at finde glemsel!,Wir sind die Hände des Schicksals. Wer sich unseren Zorn verdient wird vernichtet!,,,Somos las manos del destino. ¡Encontrar nuestra ira es encontrar el olvido!,,"Olemme kohtalon käsi. Joka yllyttää meidät vihaan, etsii turmiotaan.",Nous sommes les mains du destin. Apprendre notre colère est l'égal de trouver l'oubli!,"Mi vagyunk a sors keze. Kárhozatra ítéltetett, ki haragunkat elnyeri.",Siamo le mani del destino. Farci infuriare significa trovare l'oblio!,"運命は我々の手の中だ。 -あまり歯向かわない方がいいぞ。","우리는 긍휼의 손길이며, 불신자들을 심판하는 검일지니!",Wij zijn de handen van het lot. Om onze toorn te verdienen is het vinden van de vergetelheid!,Vi er i skjebnens hender. Å fortjene vår vrede er å finne glemsel!,Jesteśmy rękami losu. Zasłużyć na nasz gniew to znaleźć zapomnienie!,Somos as mãos do destino. Quem despertar a nossa ira será destruído!,,Suntem mâinile destinului. Să ne câștigi furia e să găsești vidul!,Мы длани судьбы. Прогневить нас означает встретить забвение!,,"Bizler kaderin elleriyiz. Gazabımızı kazanmak, unutulmayı bulmaktır!" +あまり歯向かわない方がいいぞ。","우리는 긍휼의 손길이며, 불신자들을 심판하는 검일지니!",Wij zijn de handen van het lot. Om onze toorn te verdienen is het vinden van de vergetelheid!,Vi er i skjebnens hender. Å fortjene vår vrede er å finne glemsel!,Jesteśmy rękami losu. Zasłużyć na nasz gniew to znaleźć zapomnienie!,Somos as mãos do destino. Quem despertar a nossa ira será destruído!,,Suntem mâinile destinului. Să ne câștigi furia e să găsești vidul!,Мы длани судьбы. Прогневить нас означает встретить забвение!,,Vi är ödets händer. Att förtjäna vår vrede är att finna glömska!,"Bizler kaderin elleriyiz. Gazabımızı kazanmak, unutulmayı bulmaktır!" The Order will cleanse the world of the weak and corrupt!,TXT_RANDOM_PGUARD_02,,,,Řád vyčistí svět od slabých a zkažených!,Ordenen vil rense verden for de svage og korrupte!,Der Orden wird die Welt von allem Schwachen und Korrupten säubern.,,,¡La Orden limpiará el mundo de los débiles y los corruptos!,,Veljeskunta puhdistaa tämän maailman sen heikoista ja turmeltuneista!,L'ordre nettoira le monde des faibles et corrompus!,A Rend megtisztítja a világot a gyengéktől és a korruptaktól!,"L'Ordine ripulirà il mondo dai deboli e corrotti! ","オーダーは浅ましく腐敗した世界を -浄化するだろう!",유일신님은 반드시 이 나약하고 부패한 세상을 정화할 것이니라!,De Orde zal de wereld zuiveren van de zwakken en corrupten!,Ordenen vil rense verden for de svake og korrupte!,Zakon oczyści świat ze słabych i skorumpowanych!,A Ordem purificará o mundo dos fracos e corruptos!,,Ordinul va curăța lumea de slabi și corupți!,Орден очистит мир от слабых и порочных!,,"Düzen, dünyayı zayıf ve yozlaşmış olanlardan temizleyecek!" -Obey the will of the masters!,TXT_RANDOM_PGUARD_03,,,,Podrob se vůli svých pánů!,Adlyd mændenes vilje!,Gehorche dem Willen der Meister.,,,¡Obedece la voluntad de los maestros!,,Tottele mestareiden tahtoa!,Obéissez à la volonté de vos maîtres!,Engedelmeskedj mestereink akaratának!,Obbedisci al volere dei maestri!,主の意志に従うのだ。,스승님들께서 너희에게 명령하신 도를 행하라!,Gehoorzaam de wil van de meesters!,Adlyd mesternes vilje!,Bądźcie posłuszni woli mistrzów!,Obedeça a lei dos mestres!,,Supune-te voinței stăpânilor!,Подчинись воле хозяев!,,Efendilerin iradesine itaat edin! -Long life to the brothers of the Order!,TXT_RANDOM_PGUARD_04,,,,Nechť žijí naši bratři Řádu!,Langt liv til ordenens brødre!,Lang lebe die Brüder des Ordens.,,,¡Vivan los hermanos de La Orden!,,Pitkä ikä Veljeskunnan veljille!,Longue vie aux membres de l'Ordre!,Éljenek sokáig a Rend testvérei!,Lunga vita ai fratelli dell'Ordine.,オーダーの友に永久の命を!,"오더와 그의 동포들을 따르라, 그럼 영생을 얻을 지니!",Een lang leven voor de broeders van de Orde!,Lenge leve ordenens brødre!,Niech żyją bracia Zakonu!,Vida longa aos irmãos da Ordem!,,Viață lungă fraților Ordinului!,Да здравствуют братья Ордена!,,Tarikat'ın kardeşlerine uzun ömürler! -Free will is an illusion that binds the weak minded.,TXT_RANDOM_PGUARD_05,,,,"Svobodná vůle je jen iluze, která váže ruce slabomyslným.","Den frie vilje er en illusion, der binder de svage sind.",Freier Wille ist eine Illusion die die Schwachen fesselt.,,,El libre albedrio es una ilusión que une a los débiles de mente.,,"Vapaa tahto on harha, joka sitoo heikkomieliset.",La liberté de penser est l'illusion qui aveugle les faibles d'esprit.,"A Szabad akarat egy illúzió, ami csupán a gyengéknek mentsvára.",Il libero arbitrio è un'illusione che tiene legati i deboli di mente.,自由意志など、弱者を縛る幻想に過ぎぬ。,"자유의지는 나약함의 상징이요, 필멸의 꾐이라.",De vrije wil is een illusie die de zwakkeren bindt.,Fri vilje er en illusjon som binder de svake.,"Wolna wola to iluzja, która wiąże słabe umysły.",Livre arbítrio é uma ilusão para os fracos.,,Voința liberă e o iluzie care leagă mințile slabe.,"Свободная воля — лишь иллюзия, созданная для управления слабыми духом.",,"Özgür irade, zayıf zihinleri bağlayan bir yanılsamadır." +浄化するだろう!",유일신님은 반드시 이 나약하고 부패한 세상을 정화할 것이니라!,De Orde zal de wereld zuiveren van de zwakken en corrupten!,Ordenen vil rense verden for de svake og korrupte!,Zakon oczyści świat ze słabych i skorumpowanych!,A Ordem purificará o mundo dos fracos e corruptos!,,Ordinul va curăța lumea de slabi și corupți!,Орден очистит мир от слабых и порочных!,,Orden kommer att rensa världen från de svaga och korrupta!,"Düzen, dünyayı zayıf ve yozlaşmış olanlardan temizleyecek!" +Obey the will of the masters!,TXT_RANDOM_PGUARD_03,,,,Podrob se vůli svých pánů!,Adlyd mændenes vilje!,Gehorche dem Willen der Meister.,,,¡Obedece la voluntad de los maestros!,,Tottele mestareiden tahtoa!,Obéissez à la volonté de vos maîtres!,Engedelmeskedj mestereink akaratának!,Obbedisci al volere dei maestri!,主の意志に従うのだ。,스승님들께서 너희에게 명령하신 도를 행하라!,Gehoorzaam de wil van de meesters!,Adlyd mesternes vilje!,Bądźcie posłuszni woli mistrzów!,Obedeça a lei dos mestres!,,Supune-te voinței stăpânilor!,Подчинись воле хозяев!,,Lyd mästarnas vilja!,Efendilerin iradesine itaat edin! +Long life to the brothers of the Order!,TXT_RANDOM_PGUARD_04,,,,Nechť žijí naši bratři Řádu!,Langt liv til ordenens brødre!,Lang lebe die Brüder des Ordens.,,,¡Vivan los hermanos de La Orden!,,Pitkä ikä Veljeskunnan veljille!,Longue vie aux membres de l'Ordre!,Éljenek sokáig a Rend testvérei!,Lunga vita ai fratelli dell'Ordine.,オーダーの友に永久の命を!,"오더와 그의 동포들을 따르라, 그럼 영생을 얻을 지니!",Een lang leven voor de broeders van de Orde!,Lenge leve ordenens brødre!,Niech żyją bracia Zakonu!,Vida longa aos irmãos da Ordem!,,Viață lungă fraților Ordinului!,Да здравствуют братья Ордена!,,Länge liv till ordensbröderna!,Tarikat'ın kardeşlerine uzun ömürler! +Free will is an illusion that binds the weak minded.,TXT_RANDOM_PGUARD_05,,,,"Svobodná vůle je jen iluze, která váže ruce slabomyslným.","Den frie vilje er en illusion, der binder de svage sind.",Freier Wille ist eine Illusion die die Schwachen fesselt.,,,El libre albedrio es una ilusión que une a los débiles de mente.,,"Vapaa tahto on harha, joka sitoo heikkomieliset.",La liberté de penser est l'illusion qui aveugle les faibles d'esprit.,"A Szabad akarat egy illúzió, ami csupán a gyengéknek mentsvára.",Il libero arbitrio è un'illusione che tiene legati i deboli di mente.,自由意志など、弱者を縛る幻想に過ぎぬ。,"자유의지는 나약함의 상징이요, 필멸의 꾐이라.",De vrije wil is een illusie die de zwakkeren bindt.,Fri vilje er en illusjon som binder de svake.,"Wolna wola to iluzja, która wiąże słabe umysły.",Livre arbítrio é uma ilusão para os fracos.,,Voința liberă e o iluzie care leagă mințile slabe.,"Свободная воля — лишь иллюзия, созданная для управления слабыми духом.",,Fri vilja är en illusion som binder de svaga sinnena.,"Özgür irade, zayıf zihinleri bağlayan bir yanılsamadır." Power is the path to glory. To follow the Order is to walk that path!,TXT_RANDOM_PGUARD_06,,,,Moc je cesta ke slávě. Následovat Řád je chodit po té cestě!,Magt er vejen til ære. At følge Ordenen er at gå denne vej!,"Macht ist der Weg zum Ruhm. Dem Orden zu folgen bedeutet, diesen Weg zu gehen.",,,El poder es el camino a la gloria. ¡Seguir a La Orden es alcanzar ese camino!,,Valta on tie kunniaan. Veljeskunnan seuraaminen on vaeltaa sitä tietä!,le pouvoir est le chemin de la gloire. Suivre l'ordre c'est suivre ce chemin!,"A dicsőéghez vezető út az erő. Aki A Rendet követi, ezt az utat járja.",Il potere è il percorso verso la gloria. Seguire l'Ordine è come attraversare quel percorso!,"力は栄光への道だ。 -オーダーに従えばその道を歩めるだろう。","힘은 영광이자 희망이며, 이를 간구함으로써 축복받을지어다!",Macht is de weg naar glorie. De Orde volgen is dat pad bewandelen!,Makt er veien til ære. Å følge Ordenen er å gå den veien!,Władza jest drogą do chwały. Podążanie za Zakonem to podążanie tą ścieżką!,O poder é o caminho para a glória. Siga a Ordem e andará por esse caminho!,,Puterea e calea spre glorie. Să urmezi Ordinul e să urmezi acea cale!,Сила — путь к величию. Вступить в ряды Ордена означает пойти этим путём!,,"Güç, zafere giden yoldur. Tarikat'ı takip etmek o yolda yürümektir!" -"Take your place among the righteous, join us!",TXT_RANDOM_PGUARD_07,,,,"Najdi své místo mezi spravedlivými, přidej se k nám!","Tag din plads blandt de retfærdige, slut dig til os!",Nimm deinen Platz unter den Gerechten ein. ,,,Toma tu lugar entre los justos. ¡Únete a nosotros!,,Ota paikkasi hurskaitten joukossa; liity meihin!,"Prend ta place parmi les justes, rejoins nous!","Foglalj helyet az igazak között, csatlakozz hozzánk!","Prendi il tuo posto tra i giusti, unisciti a noi!",正義は我等と共に在る、参加せよ!,"우리는 참됐으며 구원을 받았느니라, 함께 기도하면 두려울 것이 없을지니!","Neem je plaats in tussen de rechtvaardigen, sluit je aan bij ons!","Ta din plass blant de rettferdige, bli med oss!","Zajmij swoje miejsce wśród sprawiedliwych, dołącz do nas!",Tenha o seu lugar entre os justos. Junte-se a nós!,,Alătură-te celor drepți!,Займи своё место среди праведных. Присоединись к нам!,,"Doğruların arasında yerinizi alın, bize katılın!" -The Order protects its own.,TXT_RANDOM_PGUARD_08,,,,Řád si své lidi chrání.,Ordenen beskytter sine egne.,Der Orden beschützt seine Jünger.,,,La Orden protege a los suyos.,,Veljeskunta puolustaa omiaan.,L'ordre protège les siens.,A Rend a magáét védi.,L'Ordine protegge i suoi.,オーダーは我々を守護している。,오더는 신들을 향한 기도로 거룩하여짐이니라.,De Orde beschermt zijn discipelen. ,Ordenen beskytter sine egne.,Zakon chroni swoich.,A Ordem protege os seus discípulos.,,Ordinul îi protejează pe cei loiali.,Орден защищает своих.,,Tarikat kendine ait olanları korur. +オーダーに従えばその道を歩めるだろう。","힘은 영광이자 희망이며, 이를 간구함으로써 축복받을지어다!",Macht is de weg naar glorie. De Orde volgen is dat pad bewandelen!,Makt er veien til ære. Å følge Ordenen er å gå den veien!,Władza jest drogą do chwały. Podążanie za Zakonem to podążanie tą ścieżką!,O poder é o caminho para a glória. Siga a Ordem e andará por esse caminho!,,Puterea e calea spre glorie. Să urmezi Ordinul e să urmezi acea cale!,Сила — путь к величию. Вступить в ряды Ордена означает пойти этим путём!,,Makt är vägen till ära. Att följa Orden är att gå den vägen!,"Güç, zafere giden yoldur. Tarikat'ı takip etmek o yolda yürümektir!" +"Take your place among the righteous, join us!",TXT_RANDOM_PGUARD_07,,,,"Najdi své místo mezi spravedlivými, přidej se k nám!","Tag din plads blandt de retfærdige, slut dig til os!",Nimm deinen Platz unter den Gerechten ein. ,,,Toma tu lugar entre los justos. ¡Únete a nosotros!,,Ota paikkasi hurskaitten joukossa; liity meihin!,"Prend ta place parmi les justes, rejoins nous!","Foglalj helyet az igazak között, csatlakozz hozzánk!","Prendi il tuo posto tra i giusti, unisciti a noi!",正義は我等と共に在る、参加せよ!,"우리는 참됐으며 구원을 받았느니라, 함께 기도하면 두려울 것이 없을지니!","Neem je plaats in tussen de rechtvaardigen, sluit je aan bij ons!","Ta din plass blant de rettferdige, bli med oss!","Zajmij swoje miejsce wśród sprawiedliwych, dołącz do nas!",Tenha o seu lugar entre os justos. Junte-se a nós!,,Alătură-te celor drepți!,Займи своё место среди праведных. Присоединись к нам!,,"Ta din plats bland de rättfärdiga, anslut dig till oss!","Doğruların arasında yerinizi alın, bize katılın!" +The Order protects its own.,TXT_RANDOM_PGUARD_08,,,,Řád si své lidi chrání.,Ordenen beskytter sine egne.,Der Orden beschützt seine Jünger.,,,La Orden protege a los suyos.,,Veljeskunta puolustaa omiaan.,L'ordre protège les siens.,A Rend a magáét védi.,L'Ordine protegge i suoi.,オーダーは我々を守護している。,오더는 신들을 향한 기도로 거룩하여짐이니라.,De Orde beschermt zijn discipelen. ,Ordenen beskytter sine egne.,Zakon chroni swoich.,A Ordem protege os seus discípulos.,,Ordinul îi protejează pe cei loiali.,Орден защищает своих.,,Orden skyddar sina egna.,Tarikat kendine ait olanları korur. Acolytes? They have yet to see the full glory of the Order.,TXT_RANDOM_PGUARD_09,,,,Akolyté? Ti ještě neviděli Řád v celé své kráse.,Acolytes? De har endnu ikke set Ordenens fulde herlighed.,Ministranten? Die müssen erst noch die volle Macht des Ordens erfahren.,,Ĉu akolitoj? Ili ankoraŭ ne vidis la tutan gloron de La Ordono.,¿Acólitos? Aún no han visto toda la gloria de La Orden.,¿Acólitos? Aún no vieron toda la gloria de La Orden.,Akoluutit? He eivät ole vielä nähneet Veljeskunnan täyttä kirkkautta.,Les Acolytes? Ils n'ont pas encore été témoins de la vraie gloire de l'ordre.,Ministránsok? Még nem látták A Rend igazi dicsőségét.,Gli accoliti? Devono ancora conoscere la vera gloria dell'Ordine.,"アコライト? -奴等はオーダーの爛漫なる未来を見ていない。",아콜라이트들이라... 애석하게도 이 들은 믿음이 아직 부족하다고 생각함이라.,Acolieten? Zij moeten de volle glorie van de Orde nog zien.,Akolytter? De har ennå ikke sett Ordenens fulle herlighet.,Akolitów? Oni jeszcze nie widzieli pełnej chwały Zakonu.,Acólitos? Eles ainda não viram toda a glória da Ordem.,,Acoliți? Încă nu au văzut gloria Ordinului.,Служители? Им ещё только предстоит узреть подлинное величие Ордена.,,Yardımcıları mı? Henüz Tarikat'ın tüm ihtişamını görmediler. +奴等はオーダーの爛漫なる未来を見ていない。",아콜라이트들이라... 애석하게도 이 들은 믿음이 아직 부족하다고 생각함이라.,Acolieten? Zij moeten de volle glorie van de Orde nog zien.,Akolytter? De har ennå ikke sett Ordenens fulle herlighet.,Akolitów? Oni jeszcze nie widzieli pełnej chwały Zakonu.,Acólitos? Eles ainda não viram toda a glória da Ordem.,,Acoliți? Încă nu au văzut gloria Ordinului.,Служители? Им ещё только предстоит узреть подлинное величие Ордена.,,Acolytes? De har ännu inte sett ordens fulla ära.,Yardımcıları mı? Henüz Tarikat'ın tüm ihtişamını görmediler. "If there is any honor inside that pathetic shell of a body, you'll enter into the arms of the Order.",TXT_RANDOM_PGUARD_10,,,"If there is any honour inside that pathetic shell of a body, you'll enter into the arms of the Order.","Jestli ta tvoje žalostná tělesná schránka má v sobě kousek cti, dáš se do rukou Řádu.","Hvis der er nogen ære inden i denne ynkelige skal af en krop, vil du gå ind i Ordenens arme.","Wenn du noch einen Hauch von Ehre hast, wirst du dem Orden beitreten.",,,"Si hay algo de honor dentro de ese patético cascarón llamado «cuerpo», La Orden te espera con los brazos abiertos.",,"Jos tuon säälittävän ruumiinhylyn sisällä on yhtään kunniakkuutta, otat itsesi Veljeskunnan huomaan.","Si il y a une once de gloire dans ce corps pathétique, ceux de l'ordre te prendront parmi les leurs.","Ha csak egy csipetnyi becsület is van testednek szánalmas páncéljában, A Rend katonáinak sorába fogsz beállni.","Se c'è un pò di onore rimasto dentro quel guscio patetico che chiami corpo, entrerai nelle braccia dell'Ordine.","その哀れな肉体の殻でも名誉の為ならば、 -オーダーの兵器を携える事が出来るだろう。",육체라는 나약한 껍질에 갇힌 운명을 참회하는 자들이야말로 오더와 함께할 수 있을지어다. ,"Als er enige eer in dat zielige omhulsel van een lichaam zit, zul je in de armen van de Orde binnengaan.","Hvis det er noe ære i det patetiske skallet av en kropp, vil du gå inn i Ordenens armer.","Jeśli w tej żałosnej skorupie ciała jest choć odrobina honoru, wejdziesz w ramiona Zakonu.","Se ainda existe honra dentro da sua carne patética, você entrará para os braços da Ordem.",,"Dacă e o fărâmă de onoare în acel corp jalnic, vei putea intra în brațele Ordinului.","Если внутри этой бренной телесной оболочки есть хоть капля чести, ты присоединишься к Ордену.",,"Eğer o zavallı bedenin içinde biraz onur varsa, Tarikat'ın kollarına gireceksin." -Bye!,TXT_RANDOMGOODBYE_1,,,,Tak ahoj!,Farvel!,Tschüss!,,Ĝis!,¡Adiós!,,Näkemiin!,Au revoir!,Szervusz!,Ciao!,じゃあな!,안녕!,Dag!,Adjø!,Pa!,Tchau!,,Pa!,Пока!,,Güle güle! -"Thanks, bye!",TXT_RANDOMGOODBYE_2,,,,"Díky, ahoj!","Tak, farvel!","Danke, tschüss!",,Dankon. Ĝis!,Gracias. ¡Adiós!,,"Kiitos, hei!","Merci, au revoir!","Köszi, szia!","Grazie, ciao!",どうも、じゃあ!,그렇군요. 그럼 안녕히!,"Bedankt, tot ziens!","Takk, ha det!","Dzięki, pa!",Obrigado. Até mais!,,"Merci, pa!","Спасибо, пока!",,"Teşekkürler, güle güle!" -See you later!,TXT_RANDOMGOODBYE_3,,,,Uvidíme se později!,Vi ses senere!,Bis später!,,Ĝis la revido!,¡Nos vemos!,,Nähdään!,A plus tard!,Később találkozunk!,Ci vediamo dopo!,また今度!,다음에 봐요!,Tot ziens!,Vi ses senere!,Do zobaczenia później!,Até logo!,,Ne vedem mai încolo!,До встречи!,,Sonra görüşürüz! -,,Strife logs,,,,,,,,,,,,,,,,,,,,,,,, +オーダーの兵器を携える事が出来るだろう。",육체라는 나약한 껍질에 갇힌 운명을 참회하는 자들이야말로 오더와 함께할 수 있을지어다. ,"Als er enige eer in dat zielige omhulsel van een lichaam zit, zul je in de armen van de Orde binnengaan.","Hvis det er noe ære i det patetiske skallet av en kropp, vil du gå inn i Ordenens armer.","Jeśli w tej żałosnej skorupie ciała jest choć odrobina honoru, wejdziesz w ramiona Zakonu.","Se ainda existe honra dentro da sua carne patética, você entrará para os braços da Ordem.",,"Dacă e o fărâmă de onoare în acel corp jalnic, vei putea intra în brațele Ordinului.","Если внутри этой бренной телесной оболочки есть хоть капля чести, ты присоединишься к Ордену.",,"Om det finns någon heder i det patetiska skalet av en kropp, kommer du att gå in i Ordens armar.","Eğer o zavallı bedenin içinde biraz onur varsa, Tarikat'ın kollarına gireceksin." +Bye!,TXT_RANDOMGOODBYE_1,,,,Tak ahoj!,Farvel!,Tschüss!,,Ĝis!,¡Adiós!,,Näkemiin!,Au revoir!,Szervusz!,Ciao!,じゃあな!,안녕!,Dag!,Adjø!,Pa!,Tchau!,,Pa!,Пока!,,Hej då!,Güle güle! +"Thanks, bye!",TXT_RANDOMGOODBYE_2,,,,"Díky, ahoj!","Tak, farvel!","Danke, tschüss!",,Dankon. Ĝis!,Gracias. ¡Adiós!,,"Kiitos, hei!","Merci, au revoir!","Köszi, szia!","Grazie, ciao!",どうも、じゃあ!,그렇군요. 그럼 안녕히!,"Bedankt, tot ziens!","Takk, ha det!","Dzięki, pa!",Obrigado. Até mais!,,"Merci, pa!","Спасибо, пока!",,"Tack, hej då!","Teşekkürler, güle güle!" +See you later!,TXT_RANDOMGOODBYE_3,,,,Uvidíme se později!,Vi ses senere!,Bis später!,,Ĝis la revido!,¡Nos vemos!,,Nähdään!,A plus tard!,Később találkozunk!,Ci vediamo dopo!,また今度!,다음에 봐요!,Tot ziens!,Vi ses senere!,Do zobaczenia później!,Até logo!,,Ne vedem mai încolo!,До встречи!,,Vi ses senare!,Sonra görüşürüz! +,,Strife logs,,,,,,,,,,,,,,,,,,,,,,,,, "Hello? Command, a com unit has just been activated... Am receiving visuals and sound from... somebody... Hey you, get out of there now... and drop the chalice!",TXT_ILOG1,,,,"Haló? Velení, právě byl aktivován komunikátor... příjimám obraz a zvuk od... někoho... Hej, ty, dostaň se odtaď... a zahoď ten kalich!","Hallo? Kommando, en kommunikationsenhed er lige blevet aktiveret... Jeg modtager billeder og lyd fra... en eller anden... Hey du, kom ud derfra nu... og smid bægeret!","Hallo, Kommandozentrale, eine Kommunikationseinheit wurde gerade aktiviert.... Ich empfange Bilder und Ton von... irgend jemandem... Hey, du, verschwinde da sofort... Und schmeiß den Kelch weg!",,,"¿Hola? Comando, una unidad de comunicación acaba de ser activada... Recibo visuales y sonido de... Alguien... Eh tú, sal de ahí ahora mismo... ¡Y tira el cáliz!",,"Haloo? Komentokeskus, äsken juuri kytkettiin päälle viestintälaite... Poimin... jonkun... videota ja ääntä... Hei sinä, häivy täältä heti paikalla... ja pudota kalkki!","Allô? Central, un communicateur à été activé.. Je recois visuel et son de.. quelqu'un.. Hé, vous, sortez de là! Et lâchez le calice!","Haló Központ! Egy jeladót aktiváltak...kép és hang jeleket veszek...valakitől...Hé Te ott, húzz ki onnan...és rakd le a serleget!","Pronto? Comando, un'unità di comunicazione è appena stata attivata... Sto ricevendo segnali audiovisivi da... qualcuno... Hey, tu, esci da là subito, e lascia stare quel calice!","もしもし? 司令部、comユニットが起動されました。 ...からビジュアルとサウンドを受け取っています ...誰かが...ちょっと、今そこから出て行ってください -...そして聖杯を捨ててください!","여보세요? 본부, 통신기가 막 작동되기 시작했다... 지금 어떤... 사람의 모습이 보이는데... 이봐, 거기서 당장 나와... 그리고 성배를 버려!","Hallo? Commando, een com-unit is zojuist geactiveerd.... Ontvang ik beelden en geluid van.... iemand... Hé jij, ga daar nu weg.... en laat de kelk vallen!","Hallo? Kommando, en kommunikasjonsenhet har nettopp blitt aktivert... Mottar bilder og lyd fra... noen... Hei du, kom deg ut derfra nå... og slipp begeret!","Halo? Dowództwo, jednostka komunikacyjna właśnie została aktywowana... Odbieram obraz i dźwięk od... kogoś... Hej ty, uciekaj stamtąd natychmiast... i rzuć kielich!","Alô? Comando, um comunicador acabou de ser ativado... Estou recebendo imagens e som de... alguém... Ei você, saia daí agora... e solte o cálice!",,"Alo? Centrul de comandă, o unitate tocmai a fost activată.... Primesc imagini și audio de la... cineva... Hei tu,pleacă de acolo și lasă potirul!","Алло? Штаб, передатчик только что включился... Я принимаю звук и картинку от... кого-то... Эй, ты, беги оттуда, сейчас же... и брось чашу!",,"Alo? Komuta, bir iletişim birimi az önce aktive edildi. Birinden görüntü ve ses alıyorum. Hey sen, hemen oradan çık... ve kadehi bırak!" +...そして聖杯を捨ててください!","여보세요? 본부, 통신기가 막 작동되기 시작했다... 지금 어떤... 사람의 모습이 보이는데... 이봐, 거기서 당장 나와... 그리고 성배를 버려!","Hallo? Commando, een com-unit is zojuist geactiveerd.... Ontvang ik beelden en geluid van.... iemand... Hé jij, ga daar nu weg.... en laat de kelk vallen!","Hallo? Kommando, en kommunikasjonsenhet har nettopp blitt aktivert... Mottar bilder og lyd fra... noen... Hei du, kom deg ut derfra nå... og slipp begeret!","Halo? Dowództwo, jednostka komunikacyjna właśnie została aktywowana... Odbieram obraz i dźwięk od... kogoś... Hej ty, uciekaj stamtąd natychmiast... i rzuć kielich!","Alô? Comando, um comunicador acabou de ser ativado... Estou recebendo imagens e som de... alguém... Ei você, saia daí agora... e solte o cálice!",,"Alo? Centrul de comandă, o unitate tocmai a fost activată.... Primesc imagini și audio de la... cineva... Hei tu,pleacă de acolo și lasă potirul!","Алло? Штаб, передатчик только что включился... Я принимаю звук и картинку от... кого-то... Эй, ты, беги оттуда, сейчас же... и брось чашу!",,"Hallå? Kommando, en kom-enhet har just aktiverats... Får bild och ljud från... någon... Hallå där, kom ut därifrån nu... och släpp kalken!","Alo? Komuta, bir iletişim birimi az önce aktive edildi. Birinden görüntü ve ses alıyorum. Hey sen, hemen oradan çık... ve kadehi bırak!" "Listen, this com unit tells me that you're 100% human. I've been ordered to bring you in, we're talking trust here. Betray me and pay. Oh, and by the way, you can call me Blackbird.",TXT_ILOG2,MAP02: After getting the com unit from Rowan and leaving his room.,,,"Poslyš, tento komunikátor mi říká, že jsi na sto procent člověkem. Dostala jsem rozkaz přivést tě k nám, jde o důvěryhodnou záležitost. Zraď mě a zaplatíš. Jo, a mimochodem, můžeš mi říkat Straka.","Hør, denne com-enhed fortæller mig, at du er 100% menneskelig. Jeg er blevet beordret til at bringe dig ind. Vi taler om tillid her. Forråd mig og betal. Åh, og forresten, du kan kalde mig Blackbird.","Hör zu, dieser Kommunikator sagt mit, dass du noch 100% menschlich bist. Mir wurde aufgetragen, dich zu unserer Zentrale zu führen. Wir reden über Vertrauen, wenn du mich verrätst, wirst du bezahlen. Übrigens, du kannst mich Blackbird nennen.",,,"Escucha, este intercomunicador me dice que eres 100% humano. Se me ha ordenado dejarte entrar, así que hablamos en confianza. Traicióname y pagarás. Ah, por cierto, puedes llamarme BlackBird.","Escucha, este intercomunicador me dice que eres 100% humano. Se ordenadó dejarte entrar, así que hablamos en confianza. Traicióname y te vas a arrepentir. Ah, por cierto, puedes llamarme BlackBird.","Kuule, tämä viestintälaite ilmaisee sinun olevan sataprosenttisesti ihminen. Minut on määrätty tuomaan sinut meidän joukkoomme; puhumme luottamuksellisesti. Petä minut ja saat luvan maksaa. Ja muuten, voit kutsua minua Blackbirdiksi.","Ecoute, ce communicateur me dit que tu est 100% humain. On m'a ordonnée de te ramener, c'est une question de confiance. Trahis-moi et tu paieras. Oh, et tu peux m'appeler Blackbird.","Figyelj, azt jelzi a jeladó, hogy 100%-ban ember vagy. Azt az utasítást kaptam ,hogy vigyelek be, de a bizalmammal játszol. Átversz és megfizetsz. Ja, és hívhatsz feketerigónak.","Ascolta, questa unità di comunicazione mi dice che sei 100% umano. Ho l'ordine di farti arrivare da noi, e quindi stiamo parlando di fiducia. Se mi tradisci la pagherai cara. Comunque, mi puoi chiamare Blackbird.","聞こえるか、この無線機がアナタは100%人間だと判断した。 私はアナタを信頼して良いとみて連れて来るよう命じられた、 -反乱への報酬は期待して良いわ。ああ、それと、私の名はブラックバードよ。","잘 들어, 이 통신기에 따르면 넌 100% 인간이야. 너를 믿어도 될 거 같으니 우리 편으로 끌어모으라는 지시를 받았어. 배신했다간 대가를 치를 거야. 아, 그리고, 날 블랙버드라고 불러줘.","Luister, deze com-unit vertelt me dat je 100% menselijk bent. Ik heb opdracht gekregen om je binnen te halen, we hebben het hier over vertrouwen. Verraad me en betaal. Oh, en trouwens, je mag me Blackbird noemen.","Hør her, denne kommunikasjonsenheten forteller meg at du er 100% menneskelig. Jeg har fått ordre om å hente deg inn, vi snakker om tillit her. Forråd meg og betal. Og forresten, du kan kalle meg Blackbird.","Słuchaj, to urządzenie mówi mi, że jesteś w 100% człowiekiem. Dostałem rozkaz, żeby cię sprowadzić, mówimy tu o zaufaniu. Zdradź mnie i zapłać. Aha, i przy okazji, możesz mi mówić Blackbird.","Ouça, este comunicador me diz que você é 100% humano. Recebi ordens para te trazer até aqui. É melhor você ser de confiança. Se você me trair, você me paga. Ah, a propósito, pode me chamar de Blackbird.",,"Ascultă, unitatea asta îmi spune că ești 100% uman. Am primit ordin să te arestez. Trădează-mă și plătești. Oh, apropo, îmi poți spune Blackbird.","Слушай — судя по этому передатчику, ты на сто процентов человек. Я получила приказ показать тебе дорогу к нам. Как видишь, тебе доверяют, но если предашь меня — пожалеешь. И да, обращайся ко мне «Чёрный дрозд». ",,"Dinle, bu iletişim ünitesi bana senin %100 insan olduğunu söylüyor. Seni buraya getirmem emredildi, burada güvenden bahsediyoruz. Bana ihanet edersen bedelini ödersin. Bu arada, bana Karatavuk diyebilirsin." +反乱への報酬は期待して良いわ。ああ、それと、私の名はブラックバードよ。","잘 들어, 이 통신기에 따르면 넌 100% 인간이야. 너를 믿어도 될 거 같으니 우리 편으로 끌어모으라는 지시를 받았어. 배신했다간 대가를 치를 거야. 아, 그리고, 날 블랙버드라고 불러줘.","Luister, deze com-unit vertelt me dat je 100% menselijk bent. Ik heb opdracht gekregen om je binnen te halen, we hebben het hier over vertrouwen. Verraad me en betaal. Oh, en trouwens, je mag me Blackbird noemen.","Hør her, denne kommunikasjonsenheten forteller meg at du er 100% menneskelig. Jeg har fått ordre om å hente deg inn, vi snakker om tillit her. Forråd meg og betal. Og forresten, du kan kalle meg Blackbird.","Słuchaj, to urządzenie mówi mi, że jesteś w 100% człowiekiem. Dostałem rozkaz, żeby cię sprowadzić, mówimy tu o zaufaniu. Zdradź mnie i zapłać. Aha, i przy okazji, możesz mi mówić Blackbird.","Ouça, este comunicador me diz que você é 100% humano. Recebi ordens para te trazer até aqui. É melhor você ser de confiança. Se você me trair, você me paga. Ah, a propósito, pode me chamar de Blackbird.",,"Ascultă, unitatea asta îmi spune că ești 100% uman. Am primit ordin să te arestez. Trădează-mă și plătești. Oh, apropo, îmi poți spune Blackbird.","Слушай — судя по этому передатчику, ты на сто процентов человек. Я получила приказ показать тебе дорогу к нам. Как видишь, тебе доверяют, но если предашь меня — пожалеешь. И да, обращайся ко мне «Чёрный дрозд». ",,"Lyssna, den här kommunikationsenheten säger mig att du är 100% mänsklig. Jag har blivit beordrad att ta in dig, vi pratar om förtroende här. Förråda mig och betala. Och förresten, du kan kalla mig Blackbird.","Dinle, bu iletişim ünitesi bana senin %100 insan olduğunu söylüyor. Seni buraya getirmem emredildi, burada güvenden bahsediyoruz. Bana ihanet edersen bedelini ödersin. Bu arada, bana Karatavuk diyebilirsin." "Listen, this com-unit tells me that you're 100% human. You might be one of us, and maybe we can try and trust each other. Consider this test, there's a flamethrower in the Governor's mansion. Get it, and I'll lead you to us.",TXT_ILOG2,,strifeteaser,,"Poslyš, tento komunikátor mi říká, že jsi na sto procent člověkem. Mohl bys být jedním z nás a možná se můžeme pokusit navzájem si věřit. Ber tohle jako test: V guvernérově sídle je plamenomet. Najdi ho a zavedu tě k nám.","Hør, denne com-enhed fortæller mig, at du er 100% menneskelig. Du er måske en af os, og måske kan vi prøve at stole på hinanden. Overvej denne test: Der er en flammekaster i guvernørens palæ. Hent den, så fører jeg dig til os.","Hör zu, dieser Kommunikator sagt mit, dass du noch 100% menschlich bist. Du magst einer von uns sein und vielleicht können wir einander vertrauen. Betrachte dies als einen Test, da ist ein Flammenwerfer in der Villa des Gouverneurs. Hole ihn und ich führe dich zu uns.",,,"Escucha, esta unidad de comunicación me dice que eres 100% humano. Podrías ser uno de nosotros, y tal vez podamos intentar confiar el uno en el otro. Considera esto una prueba, hay un lanzallamas en la mansión del gobernador. Tómalo, y te llevará a nosotros",,"Kuule, tämä viestintälaite ilmaisee sinun olevan sataprosenttisesti ihminen. Saatat olla yksi meistä, ja ehkä voimme yrittää luottaa toisiimme. Voit pitää tätä testinä: Kuvernöörin kartanossa on liekinheitin. Hanki se, ja johdatan sinut luoksemme.","Ecoute, ce communicateur me dit que tu est 100% humain. Il se peut que tu est l'un des nôtres, on pourrait se faire confiance. Considère cela comme un test. Il y a un lance-flammes dans le manoir du gouverneur. Récupère le et je te mènerai à nous.","Figyelj, azt jelzi a jeladó, hogy 100%-ban ember vagy. Talán tényleg egy vagy közülünk, és megpróbálhatunk bízni egymásban. Vedd a következőt tesztnek: kapj fel egy lángszórót a Kormányzó kúriájából. Ha megszerzed, elvezetlek hozzánk.","Ascolta, questa unità di comunicazione mi dice che sei 100% umano. Potresti essere uno di noi, e forse possiamo fidarci l'uno dell'altro. Ti metterò alla prova, c'è un lanciafiamme nel palazzo del governatore. Prendilo, e ti condurrò da noi.","聞いて、このcom-unitはあなたが100%人間だということを教えてくれます。 あなたは私たちのうちの一人であるかもしれません、 そしておそらく私たちは互いに試みて信頼することができます。 このテストを考えてください、知事の邸宅に火炎放射器があります。 -それを手に入れてください","잘 들어, 이 통신기에 따르면 넌 100% 인간이야. 우리들은 너를 적극적으로 믿으니까 너도 같이 이해하고 신뢰했으면 좋겠어. 그러기 위해선 시험을 치러야 하는데, 총독의 건물 안에 화염방사기가 있어. 얻으면 우리들이 있는 곳을 알려줄게. ","Luister, deze com-unit vertelt me dat je 100% menselijk bent. Misschien bent u een van ons, en misschien kunnen we elkaar proberen te vertrouwen. Overweeg deze test, er is een vlammenwerper in het landhuis van de gouverneur. Haal het, en ik zal je naar ons toe leiden....","Denne kommunikasjonsenheten forteller meg at du er 100 % menneskelig. Du kan være en av oss, og kanskje vi kan prøve å stole på hverandre. Tenk på denne testen, det er en flammekaster i guvernørens hus. Ta den, så fører jeg deg til oss.","Słuchaj, ta jednostka mówi mi, że jesteś w 100% człowiekiem. Może jesteś jednym z nas i możemy spróbować sobie zaufać. Rozważ ten test, w rezydencji gubernatora jest miotacz ognia. Weź go, a zaprowadzę cię do nas.","Ouça, este comunicador me diz que você é 100% humano. Pode ser que você seja um de nós e talvez possamos tentar confiar um no outro. Considere isto um teste, há um lança-chamas na mansão do Governador. Entre lá e eu te guiarei até nós.",,"Ascultă, unitatea asta îmi spune că ești 100% uman. Poate putem avea încredere unii în ceilalți. Consideră acest test, e un aruncător de flăcări în complexul Guvernatorului. Ia-l, te va duce la noi.","Слушай — судя по этому передатчику, ты на сто процентов человек. Ты можешь присоединиться к нам, и мы должны доверять друг другу. Небольшое тебе испытание: в особняке губернатора есть огнемёт. Достань его, и я покажу тебе дорогу к нам.",,"Dinle, bu iletişim birimi bana senin %100 insan olduğunu söylüyor. Bizden biri olabilirsin ve belki birbirimize güvenmeyi deneyebiliriz. Bu testi düşün, Vali'nin malikanesinde bir alev makinesi var. Onu al, ben de seni bize götüreyim." +それを手に入れてください","잘 들어, 이 통신기에 따르면 넌 100% 인간이야. 우리들은 너를 적극적으로 믿으니까 너도 같이 이해하고 신뢰했으면 좋겠어. 그러기 위해선 시험을 치러야 하는데, 총독의 건물 안에 화염방사기가 있어. 얻으면 우리들이 있는 곳을 알려줄게. ","Luister, deze com-unit vertelt me dat je 100% menselijk bent. Misschien bent u een van ons, en misschien kunnen we elkaar proberen te vertrouwen. Overweeg deze test, er is een vlammenwerper in het landhuis van de gouverneur. Haal het, en ik zal je naar ons toe leiden....","Denne kommunikasjonsenheten forteller meg at du er 100 % menneskelig. Du kan være en av oss, og kanskje vi kan prøve å stole på hverandre. Tenk på denne testen, det er en flammekaster i guvernørens hus. Ta den, så fører jeg deg til oss.","Słuchaj, ta jednostka mówi mi, że jesteś w 100% człowiekiem. Może jesteś jednym z nas i możemy spróbować sobie zaufać. Rozważ ten test, w rezydencji gubernatora jest miotacz ognia. Weź go, a zaprowadzę cię do nas.","Ouça, este comunicador me diz que você é 100% humano. Pode ser que você seja um de nós e talvez possamos tentar confiar um no outro. Considere isto um teste, há um lança-chamas na mansão do Governador. Entre lá e eu te guiarei até nós.",,"Ascultă, unitatea asta îmi spune că ești 100% uman. Poate putem avea încredere unii în ceilalți. Consideră acest test, e un aruncător de flăcări în complexul Guvernatorului. Ia-l, te va duce la noi.","Слушай — судя по этому передатчику, ты на сто процентов человек. Ты можешь присоединиться к нам, и мы должны доверять друг другу. Небольшое тебе испытание: в особняке губернатора есть огнемёт. Достань его, и я покажу тебе дорогу к нам.",,"Den här kommunikationsenheten säger mig att du är 100 procent mänsklig. Du kanske är en av oss och vi kanske kan försöka lita på varandra. Tänk på det här testet: Det finns en flamkastare i guvernörens herrgård. Hämta den, så leder jag dig till oss.","Dinle, bu iletişim birimi bana senin %100 insan olduğunu söylüyor. Bizden biri olabilirsin ve belki birbirimize güvenmeyi deneyebiliriz. Bu testi düşün, Vali'nin malikanesinde bir alev makinesi var. Onu al, ben de seni bize götüreyim." Head over to the old town hall. Macil had a tunnel built that lets us get in and out without the acolytes' knowledge.,TXT_ILOG3,MAP02: On the bridge with the com unit.,,,"Zamiř ke staré radnici. Macil nechal postavit tunel, který nám dovoluje se dostat dovnitř a ven bez vědomí akolytů.","Gå over til det gamle rådhus. Macil har fået bygget en tunnel, der lader os komme ind og ud uden acolytes' viden.","Geh zum alten Rathaus. Macil hat einen Tunnel bauen lassen, durch den wir dort reinkommen, ohne dass die Ministranten das mitbekommen.",,,Dirígete al antiguo ayuntamiento. Macil hizo construir un túnel que nos permite entrar y salir sin que los acólitos lo sepan.,,"Suuntaa kohti vanhaa kaupungintaloa. Macil oli rakennuttanut tunnelin, jonka avulla voimme päästä sisään ja ulos akoluuttien tietämättä.",Dirige-toi vers l'ancienne mairie. Macil a fait construire un tunnel qui nous permet d'y entrer sans que l'Ordre nous remarque.,"Vedd az utad a régi városfalhoz. Macil épített egy föld alatti alagutat, amin keresztül a ministránsok tudta nélkül tudunk ki és be járkálni.",Raggiungi il vecchio Municipio. Macil ha fatto costruire un tunnel che ci fa entrare ed uscire senza che gli accoliti lo sappiano.,"旧市庁舎に入る。そこにはマシルがアコライトに関わる者を欺く為の -抜け道を用意している。",구 시청으로 향해. 오더가 이곳을 폭격한 후에 마실이 그곳에 아콜라이트들이 모르는 통행로를 만들어놨어.,Ga naar het oude stadhuis. Macil heeft een tunnel laten bouwen die ons zonder medeweten van de acolieten in en uit kan stappen.,Gå til det gamle rådhuset. Macil fikk bygget en tunnel som lar oss komme inn og ut uten at akolyttene vet om det.,"Udaj się do starego ratusza. Macil kazał wybudować tunel, który pozwoli nam wejść i wyjść bez wiedzy akolitów.",Vá até a antiga prefeitura. Macil construiu um túnel que permite que a gente entre e saia sem os acólitos perceberem.,,Du-te în vechia hală a orașului. Macil a construit un tunel care ne permite să ne deplasăm fără ca acoliții să știe.,"Отправляйся к старой ратуше. Мэйсил построил там туннель, который позволяет нам входить и выходить без ведома служителей.",,"Eski belediye binasına gidin. Macil, yardımcıların haberi olmadan girip çıkmamızı sağlayan bir tünel inşa ettirdi." +抜け道を用意している。",구 시청으로 향해. 오더가 이곳을 폭격한 후에 마실이 그곳에 아콜라이트들이 모르는 통행로를 만들어놨어.,Ga naar het oude stadhuis. Macil heeft een tunnel laten bouwen die ons zonder medeweten van de acolieten in en uit kan stappen.,Gå til det gamle rådhuset. Macil fikk bygget en tunnel som lar oss komme inn og ut uten at akolyttene vet om det.,"Udaj się do starego ratusza. Macil kazał wybudować tunel, który pozwoli nam wejść i wyjść bez wiedzy akolitów.",Vá até a antiga prefeitura. Macil construiu um túnel que permite que a gente entre e saia sem os acólitos perceberem.,,Du-te în vechia hală a orașului. Macil a construit un tunel care ne permite să ne deplasăm fără ca acoliții să știe.,"Отправляйся к старой ратуше. Мэйсил построил там туннель, который позволяет нам входить и выходить без ведома служителей.",,Gå till det gamla stadshuset. Macil lät bygga en tunnel som gör att vi kan ta oss in och ut utan acolytternas vetskap.,"Eski belediye binasına gidin. Macil, yardımcıların haberi olmadan girip çıkmamızı sağlayan bir tünel inşa ettirdi." "Go through the door on your left, then the one on the right. The guard's name is Geoff. Tell him you need gold.",TXT_ILOG4,MAP02: In hall town with the com unit.,,,"Projdi dveřmi nalevo a pak napravo. Hlídač se jmenuje Geoff. Řekni mu, že potřebuješ zlato.","Gå gennem døren til venstre og derefter gennem den til højre. Vagtens navn er Geoff. Sig til ham, at du har brug for guld.","Geh durch die linke Tür, dann durch die rechte. Der Wächter heißt Geoff. Sag ihm du brauchst Gold.",,"Iru tra la maldekstra pordo kaj poste tra la dekstra. La nomo de la gardisto estas Geoff; diru al li, ke vi bezonas oron.",Ve por la puerta izquierda y luego por la derecha. El guardia se llama Geoff; dile que necesitas oro.,,"Kulje sinusta katsottuna vasemmalla puolella olevan oven läpi, sitten oikeanpuoleisesta ovesta. Vartijan nimi on Geoff. Kerro hänelle tarvitsevasi kultaa.",Passe par la porte à gauche puis celle à droite. Le garde s'appelle Geoff. Dis-lui que tu as besoin d'argent.,"Menj át a bal oldali ajtón, majd a jobb oldalin. Az őr neve Geoff. Mondd neki, hogy aranyra van szükséged.","Vai oltre la porta alla tua sinistra, e poi la porta alla tua destra. Il nome della guardia è Geoff. Digli che ti serve dell'oro.","すぐ左のドアを通り、右のドアから小部屋に入るんだ。 -見張りの名はジェフ。金が必要だ と言えば通じる。","네 왼쪽의 문으로 들어간 후, 다시 오른쪽의 문으로 가. 경비의 이름은 제프야. 그에게 골드가 필요하다고 얘기해.","Ga door de deur links van je, dan de deur rechts. De bewaker heet Geoff. Zeg hem dat je goud nodig hebt.","Gå gjennom døren til venstre, så den til høyre. Vakten heter Geoff. Si at du trenger gull.","Przejdź przez drzwi po lewej, a następnie te po prawej. Strażnik ma na imię Geoff. Powiedz mu, że potrzebujesz złota.",Vá pela porta à sua esquerda e depois a da direita. O nome do guarda é Geoff. Diga a ele que você precisa de ouro.,,"Intră pe ușa din stânga, apoi cea din dreapta. Numele paznicului e Geoff. Spune-i că-ți trebuie aur.","Пройди за левую дверь, затем иди направо. Стражника зовут Джефф. Скажи ему, что тебе нужно золото.",,"Solundaki kapıdan geç, sonra sağdakinden. Muhafızın adı Geoff. Ona altına ihtiyacın olduğunu söyle." -"Don't enter the town hall. It's not safe anymore, our cover's been blown. Kill all the big robots, the ""Crusaders"" and I'll guide you to us.",TXT_ILOG5,,strifeteaser,,"Nechoď do radnice, už není bezpečná. Byli jsme odhaleni. Zabij všechny ty velké roboty, Křižáky, a pak tě nasměruju k Macilovi.","Gå ikke ind på rådhuset. Det er ikke sikkert længere, vores dække er blevet afsløret. Dræb alle de store robotter, ""Crusaders"", og jeg vil guide dig til os.","Geh nicht ins Rathaus. Da ist es nicht mehr sicher, unsere Tarnung ist aufgeflogen. Erledige die großen Roboter, die „Ordensritter“ und ich führe dich zu uns.",,,"No entres en el ayuntamiento: nos han descubierto, o sea que ya no es seguro. Mata a todos los robots grandes, los «Cruzados» y te guiaré a nosotros.",,"Älä mene kaupungintaloon. Se ei ole enää turvallista; olemme paljastuneet. Tuhoa kaikki isot robotit, ""ristiretkeläiset"", ja opastan sinut luoksemme.","N'entre pas dans la mairie, ce n'est plus sûr. Notre couverture ne marche plus. Détruis tous les gros robots, les « Croisés » et je te mènerai à nous.","Ne menj be a városházába. Már nem biztonságos, lelepleződtünk. Öldd meg az összes nagy robotot, a Kereszteseket, és elvezetlek hozzánk.","Non entrare nel municipio. Non è più sicuro, la nostra copertura è saltata. Distruggi tutti i grossi robot, i ""Crociati"", e ti condurrò a noi.","町にいるフロントへの武器供給者であるイラールの元を訪ねる。 -彼は武器屋の隣のドアに居る。それで、知事と会う為にマシルから貰ったキーを使う。",아직 시청으로 가지 마. 우리가 발각된 상태라 위험하다고. 거대한 '크루세이더' 로봇들을 먼저 처리해. 그다음에 내가 안내해줄게.,"Ga het stadhuis niet binnen. Het is niet meer veilig, onze dekmantel is opgeblazen. Dood alle grote robots, de ""Kruisvaarders"" en ik zal je naar ons toe leiden.","Ikke gå inn i rådhuset. Det er ikke trygt lenger. Vi er avslørt. Drep alle de store robotene, ""korsfarerne"", så skal jeg lede dere til oss.","Nie wchodź do ratusza. To już nie jest bezpieczne, nasza przykrywka została zdmuchnięta. Zabij wszystkie duże roboty, ""Crusaders"", a ja zaprowadzę cię do nas.","Não entre na prefeitura. Não é mais seguro, fomos descobertos. Mate esses robozões, os ""Cruzados"" e eu te guiarei até nós.",,"Nu intra în hala orașului. Nu mai e sigură, s-a dus acoperirea noastră. Distruge toți roboții mari, Cruciații te vor conduce la noi.","Не ходи к ратуше. Наше убежище было разгромлено, теперь там небезопасно. Перебей этих больших роботов, «крестоносцев», и я покажу тебе дорогу к нам. ",,"Belediye binasına girme. Artık güvenli değil, kimliğimiz açığa çıktı. Bütün büyük robotları, ""Haçlıları"" öldürün, ben de sizi bize yönlendireyim." -"The door next to the weapons shop will open once all the Crusaders are dead. Inside the store room there's a teleporter, use it, and it'll bring you to us",TXT_ILOG6,,strifeteaser,,"Dveře vedle obchodu se zbraněmi se otevřou když budou všichni Křižáci zničeni. Uvnitř je teleportér, použij ho a dostaneš se k nám.","Døren ved siden af våbenbutikken vil åbne sig, når alle Crusaders er døde. Inde i lagerrummet er der en teleporter, brug den, og den vil føre dig til os","Die Tür neben dem Waffengeschäft wird sich öffnen, wenn alle Ordensritter tot sind. Dahinter ist ein Teleporter. Benutze ihn, er bringt dich zu uns.",,,"La puerta junto a la tienda de armas se abrirá en cuanto todos los cruzados estén muertos. Dentro del almacén hay un teletransporte, úsalo, y te traerá a nosotros.","La puerta junto a la tienda de armamento se abrirá una vez que todos los cruzados estén muertos. Adentro hay un teleporte, úsalo y te traerá a nosotros","Asekaupan viereinen ovi aukeaa, kun kaikki ristiretkeläiset on tuhottu. Varastohuoneessa on kaukosiirrin. Sitä käyttämällä pääset luoksemme.","La porte à côté du magasin d'armes s'ouvrira quand tous les croisés seront détruits. A l'intérieur de la salle de stockage se trouve un téléporteur, utilise-le pour nous rejoindre.","A fegyverbolt melletti ajtó ki fog nyílni, miután az összes Kresztes meghalt. Találsz a raktáron belül egy teleportot, ami ide fog hozni hozzánk.","La porta accanto al negozio delle armi si aprirà non appena tutti i Crociati sono distrutti. Oltre quella porta c'è un teletrasporto, usalo e ti porterà da noi.","私が知事について知っていることは、町の中央で双方を遊ばせてる様だ。 -ソイツがここいらを'マンション'と呼んでいる。",크루세이더들을 전부 처리하면 무기상 옆의 문이 열릴 거야. 그 안에 우리 기지로 통하는 텔레포터가 있으니 그걸 타.,"De deur naast de wapenwinkel gaat open als alle kruisvaarders dood zijn. In de opslagruimte staat een teleporter, gebruik die, en die brengt je naar ons toe.","Døren ved siden av våpenbutikken åpnes når alle korsfarerne er døde. Inne i lagerrommet er det en teleporter, bruk den, og den vil føre deg til oss...","Drzwi obok sklepu z bronią otworzą się, gdy wszyscy Crusaders będą martwi. Wewnątrz pomieszczenia ze sklepem jest teleporter, użyj go, a zaprowadzi cię do nas",A porta próxima à loja de armas abrirá assim que todos os Cruzados estiverem mortos. Dentro do depósito tem um teletransportador. Entre nele e ele o levará até nós.,,"Ușa de lângă magazinul de arme se va deschide odată ce toți Cruciații sunt morți. Înăuntru e un teleportor, ia-l, te va duce la noi.","Дверь возле оружейного магазина откроется, когда все крестоносцы будут уничтожены. На складе ты найдёшь телепорт. Используй его — он доставит тебя к нам.",,"Tüm Haçlılar öldüğünde silah dükkanının yanındaki kapı açılacak. Dükkanın içinde bir ışınlayıcı var, onu kullan ve seni bize getirecek" +見張りの名はジェフ。金が必要だ と言えば通じる。","네 왼쪽의 문으로 들어간 후, 다시 오른쪽의 문으로 가. 경비의 이름은 제프야. 그에게 골드가 필요하다고 얘기해.","Ga door de deur links van je, dan de deur rechts. De bewaker heet Geoff. Zeg hem dat je goud nodig hebt.","Gå gjennom døren til venstre, så den til høyre. Vakten heter Geoff. Si at du trenger gull.","Przejdź przez drzwi po lewej, a następnie te po prawej. Strażnik ma na imię Geoff. Powiedz mu, że potrzebujesz złota.",Vá pela porta à sua esquerda e depois a da direita. O nome do guarda é Geoff. Diga a ele que você precisa de ouro.,,"Intră pe ușa din stânga, apoi cea din dreapta. Numele paznicului e Geoff. Spune-i că-ți trebuie aur.","Пройди за левую дверь, затем иди направо. Стражника зовут Джефф. Скажи ему, что тебе нужно золото.",,Gå genom dörren till vänster och sedan genom dörren till höger. Vaktens namn är Geoff. Säg till honom att du behöver guld.,"Solundaki kapıdan geç, sonra sağdakinden. Muhafızın adı Geoff. Ona altına ihtiyacın olduğunu söyle." +"Don't enter the town hall. It's not safe anymore, our cover's been blown. Kill all the big robots, the ""Crusaders"" and I'll guide you to us.",TXT_ILOG5,,strifeteaser,,"Nechoď do radnice, už není bezpečná. Byli jsme odhaleni. Zabij všechny ty velké roboty, Křižáky, a pak tě nasměruju k Macilovi.","Gå ikke ind på rådhuset. Det er ikke sikkert længere, vores dække er blevet afsløret. Dræb alle de store robotter, ""korsfarerne"", så viser jeg dig vej til os.","Geh nicht ins Rathaus. Da ist es nicht mehr sicher, unsere Tarnung ist aufgeflogen. Erledige die großen Roboter, die „Ordensritter“ und ich führe dich zu uns.",,,"No entres en el ayuntamiento: nos han descubierto, o sea que ya no es seguro. Mata a todos los robots grandes, los «Cruzados» y te guiaré a nosotros.",,"Älä mene kaupungintaloon. Se ei ole enää turvallista; olemme paljastuneet. Tuhoa kaikki isot robotit, ""ristiretkeläiset"", ja opastan sinut luoksemme.","N'entre pas dans la mairie, ce n'est plus sûr. Notre couverture ne marche plus. Détruis tous les gros robots, les « Croisés » et je te mènerai à nous.","Ne menj be a városházába. Már nem biztonságos, lelepleződtünk. Öldd meg az összes nagy robotot, a Kereszteseket, és elvezetlek hozzánk.","Non entrare nel municipio. Non è più sicuro, la nostra copertura è saltata. Distruggi tutti i grossi robot, i ""Crociati"", e ti condurrò a noi.","町にいるフロントへの武器供給者であるイラールの元を訪ねる。 +彼は武器屋の隣のドアに居る。それで、知事と会う為にマシルから貰ったキーを使う。",아직 시청으로 가지 마. 우리가 발각된 상태라 위험하다고. 거대한 '크루세이더' 로봇들을 먼저 처리해. 그다음에 내가 안내해줄게.,"Ga het stadhuis niet binnen. Het is niet meer veilig, onze dekmantel is opgeblazen. Dood alle grote robots, de ""Kruisvaarders"" en ik zal je naar ons toe leiden.","Ikke gå inn i rådhuset. Det er ikke trygt lenger. Vi er avslørt. Drep alle de store robotene, ""korsfarerne"", så skal jeg lede dere til oss.","Nie wchodź do ratusza. To już nie jest bezpieczne, nasza przykrywka została zdmuchnięta. Zabij wszystkie duże roboty, ""krzyżowców"", a ja zaprowadzę cię do nas.","Não entre na prefeitura. Não é mais seguro, fomos descobertos. Mate esses robozões, os ""Cruzados"" e eu te guiarei até nós.",,"Nu intra în hala orașului. Nu mai e sigură, s-a dus acoperirea noastră. Distruge toți roboții mari, Cruciații te vor conduce la noi.","Не ходи к ратуше. Наше убежище было разгромлено, теперь там небезопасно. Перебей этих больших роботов, «крестоносцев», и я покажу тебе дорогу к нам. ",,"Gå inte in i stadshuset. Det är inte säkert längre, vår täckmantel har avslöjats. Döda alla stora robotar, ""Korsriddarna"", så ska jag guida dig till oss.","Belediye binasına girme. Artık güvenli değil, kimliğimiz açığa çıktı. Bütün büyük robotları, ""Haçlıları"" öldürün, ben de sizi bize yönlendireyim." +"The door next to the weapons shop will open once all the Crusaders are dead. Inside the store room there's a teleporter, use it, and it'll bring you to us",TXT_ILOG6,,strifeteaser,,"Dveře vedle obchodu se zbraněmi se otevřou když budou všichni Křižáci zničeni. Uvnitř je teleportér, použij ho a dostaneš se k nám.","Døren ved siden af våbenbutikken vil åbne sig, når alle korsfarerne er døde. Inde i lagerrummet er der en teleporter, brug den, og den vil føre dig til os.","Die Tür neben dem Waffengeschäft wird sich öffnen, wenn alle Ordensritter tot sind. Dahinter ist ein Teleporter. Benutze ihn, er bringt dich zu uns.",,,"La puerta junto a la tienda de armas se abrirá en cuanto todos los cruzados estén muertos. Dentro del almacén hay un teletransporte, úsalo, y te traerá a nosotros.","La puerta junto a la tienda de armamento se abrirá una vez que todos los cruzados estén muertos. Adentro hay un teleporte, úsalo y te traerá a nosotros","Asekaupan viereinen ovi aukeaa, kun kaikki ristiretkeläiset on tuhottu. Varastohuoneessa on kaukosiirrin. Sitä käyttämällä pääset luoksemme.","La porte à côté du magasin d'armes s'ouvrira quand tous les croisés seront détruits. A l'intérieur de la salle de stockage se trouve un téléporteur, utilise-le pour nous rejoindre.","A fegyverbolt melletti ajtó ki fog nyílni, miután az összes Kresztes meghalt. Találsz a raktáron belül egy teleportot, ami ide fog hozni hozzánk.","La porta accanto al negozio delle armi si aprirà non appena tutti i Crociati sono distrutti. Oltre quella porta c'è un teletrasporto, usalo e ti porterà da noi.","私が知事について知っていることは、町の中央で双方を遊ばせてる様だ。 +ソイツがここいらを'マンション'と呼んでいる。",크루세이더들을 전부 처리하면 무기상 옆의 문이 열릴 거야. 그 안에 우리 기지로 통하는 텔레포터가 있으니 그걸 타.,"De deur naast de wapenwinkel gaat open als alle kruisvaarders dood zijn. In de opslagruimte staat een teleporter, gebruik die, en die brengt je naar ons toe.","Døren ved siden av våpenbutikken åpnes når alle korsfarerne er døde. Inne i lagerrommet er det en teleporter, bruk den, og den vil føre deg til oss...","Drzwi obok sklepu z bronią otworzą się, gdy wszyscy krzyżowcy będą martwi. Wewnątrz pomieszczenia ze sklepem jest teleporter, użyj go, a zaprowadzi cię do nas",A porta próxima à loja de armas abrirá assim que todos os Cruzados estiverem mortos. Dentro do depósito tem um teletransportador. Entre nele e ele o levará até nós.,,"Ușa de lângă magazinul de arme se va deschide odată ce toți Cruciații sunt morți. Înăuntru e un teleportor, ia-l, te va duce la noi.","Дверь возле оружейного магазина откроется, когда все крестоносцы будут уничтожены. На складе ты найдёшь телепорт. Используй его — он доставит тебя к нам.",,"Dörren bredvid vapenbutiken öppnas när alla korsriddare är döda. Inne i butiksrummet finns det en teleporter, använd den och den för dig till oss.","Tüm Haçlılar öldüğünde silah dükkanının yanındaki kapı açılacak. Dükkanın içinde bir ışınlayıcı var, onu kullan ve seni bize getirecek" "The door next to the weapons shop will open once all the Crusaders are dead. Inside the store room there's a teleporter, use it, and it'll bring you to us.",TXT_ILOG7,,strifeteaser,,"Dveře vedle obchodu se zbraněmi se otevřou když budou všichni Křižáci zničeni. Uvnitř je teleportér, použij ho a dostaneš se k nám.","Døren ved siden af våbenbutikken åbnes, når alle korsfarerne er døde. Inde i lagerrummet er der en teleporter, brug den, og den vil bringe dig til os.","Die Tür neben dem Waffengeschäft wird sich öffnen, wenn alle Ordensritter tot sind. Dahinter ist ein Teleporter. Benutze ihn, er bringt dich zu uns.",,,"La puerta junto a la tienda de armas se abrirá en cuanto todos los cruzados estén muertos. Dentro del almacén hay un teletransporte, úsalo, y te traerá a nosotros.","La puerta junto a la tienda de armamento se abrirá una vez que todos los cruzados estén muertos. Adentro hay un teleporte, úsalo y te traerá a nosotros","Asekaupan viereinen ovi aukeaa, kun kaikki ristiretkeläiset on tuhottu. Varastohuoneessa on kaukosiirrin. Sitä käyttämällä pääset luoksemme.","La porte à côté du magasin d'armes s'ouvrira quand tous les croisés seront détruits. A l'intérieur de la salle de stockage se trouve un téléporteur, utilise-le pour nous rejoindre.","A fegyverbolt melletti ajtó ki fog nyílni, miután az összes Kresztes meghalt. Találsz a raktáron belül egy teleportot, ami ide fog hozni hozzánk.","La porta accanto al negozio delle armi si aprirà non appena tutti i Crociati sono distrutti. Oltre quella porta c'è un teletrasporto, usalo e ti porterà da noi.","私が知事について知っていることは、町の中央で双方を遊ばせてる様だ。 -ソイツがここいらを'マンション'と呼んでいる。",크루세이더들을 전부 처리하면 무기상 옆의 문이 열릴 거야. 그 안에 우리 기지로 통하는 텔레포터가 있으니 그걸 타.,"De deur naast de wapenwinkel gaat open als alle kruisvaarders dood zijn. In de opslagruimte staat een teleporter, gebruik die, en die brengt je naar ons toe.","Døren ved siden av våpenbutikken åpnes når alle korsfarerne er døde. Inne i lagerrommet er det en teleporter, bruk den, og den vil bringe deg til oss.","Drzwi obok sklepu z bronią otworzą się po śmierci wszystkich krzyżowców. Wewnątrz pomieszczenia sklepowego znajduje się teleporter, użyj go, a przeniesie cię do nas.",A porta próxima à loja de armas abrirá assim que todos os Cruzados estiverem mortos. Dentro do depósito tem um teletransportador. Entre nele e ele o levará até nós.,,"Ușa de lângă magazinul de arme se va deschide odată ce toți Cruciații sunt morți. Înăuntru e un teleportor, ia-l, te va duce la noi.","Дверь возле оружейного магазина откроется, когда все крестоносцы будут уничтожены. На складе ты найдёшь телепорт. Используй его — он доставит тебя к нам.",,"Tüm Haçlılar öldüğünde silah dükkanının yanındaki kapı açılacak. Dükkanın içinde bir ışınlayıcı var, onu kullanın ve sizi bize getirecek." -"Kill as many of the big robots, Crusaders, as you can. When you're done, I'll guide you to Macil",TXT_ILOG8,,strifeteaser,,"Znič tolik těch velkých robotů, Křižáků, kolik dokážeš. Až budeš hotov, dovedu tě k Macilovi.","Dræb så mange af de store robotter, Crusaders, som du kan. Når du er færdig, vil jeg guide dig til Macil","Erledige so viele von den großen Robotern - „Ordensrittern“, wie möglich. Wann das erledigt ist, führe ich dich zu Macil.",,,"Mata a tantos de los robots grandes, los cruzados, que puedas. Cuando termines, te guiaré hasta Macil.","Mata a tantos robots gigantes como puedas. Cuando termines, te guiaré a Macil","Tuhoa jättiroboteista, ristiretkeläisistä, niin monta kuin pystyt. Kun olet valmis, opastan sinut Macilin luokse.","Détruis autant des gros robots, les croisés, que tu peux, et je te mènerai à Macil.","Ölj meg annyi nagy robotot és keresztest amennyit csak tudsz. Ha kész vagy, elvezetlek Macilhoz.","Distruggi tutti i Crociati che vedi. Non appena hai finito, ti condurrò da Macil.",,"저 거대한 '크루세이더' 로봇들을 최대한 처리해. 상황이 정리되면, 내가 너를 마실에게 데려다줄게.","Dood zoveel mogelijk van de grote robots, kruisvaarders, als je kunt. Als je klaar bent, begeleid ik je naar Macil...","Drep så mange av de store robotene, korsfarerne, som du kan. Når du er ferdig, skal jeg vise deg veien til Macil.","Zabij jak najwięcej dużych robotów, Crusaders, jak tylko możesz. Gdy skończysz, zaprowadzę cię do Macila","Mate o máximo desses robos possível. Quando terminar, eu te guiarei ao Macil.",,"Distruge cât mai mulți roboți, Cruciați, pe cât poți. Când ești gata, te voi duce la Macil.","Убей столько больших роботов, — крестоносцев, — сколько сможешь. Когда закончишь, я приведу тебя к Мэйсилу.",,"Büyük robotlardan, Haçlılardan, öldürebildiğin kadarını öldür. İşiniz bittiğinde, sizi Macil'e götüreceğim." -"Go through the door, and talk to Macil.",TXT_ILOG9,,strifeteaser,,Projdi dveřmi a promluv si s Macilem.,"Gå gennem døren, og tal med Macil.",Geh durch die Tür und rede mit Macil.,,,Ve por la puerta y habla con Macil.,,Kulje ovesta ja puhu Macilille.,Traverse cette porte et va parler à Macil.,"Az ajtó mögött már vár Macil, beszélj vele.","Attraversa la porta, e vai a parlare con Macil.",ダーウィンを始末したら耳を知事に渡す。,저 문을 지나서 마실하고 대화를 해봐.,"Ga door de deur, en praat met Macil.",Gå gjennom døren og snakk med Macil.,Przejdź przez drzwi i porozmawiaj z Macil.,Passe pela porta e fale com o Macil.,,Intră pe ușă și du-te la Macil.,Обратись к Мэйсилу. Он за этой дверью.,,Kapıdan geçin ve Macil ile konuşun. +ソイツがここいらを'マンション'と呼んでいる。",크루세이더들을 전부 처리하면 무기상 옆의 문이 열릴 거야. 그 안에 우리 기지로 통하는 텔레포터가 있으니 그걸 타.,"De deur naast de wapenwinkel gaat open als alle kruisvaarders dood zijn. In de opslagruimte staat een teleporter, gebruik die, en die brengt je naar ons toe.","Døren ved siden av våpenbutikken åpnes når alle korsfarerne er døde. Inne i lagerrommet er det en teleporter, bruk den, og den vil bringe deg til oss.","Drzwi obok sklepu z bronią otworzą się po śmierci wszystkich krzyżowców. Wewnątrz pomieszczenia sklepowego znajduje się teleporter, użyj go, a przeniesie cię do nas.",A porta próxima à loja de armas abrirá assim que todos os Cruzados estiverem mortos. Dentro do depósito tem um teletransportador. Entre nele e ele o levará até nós.,,"Ușa de lângă magazinul de arme se va deschide odată ce toți Cruciații sunt morți. Înăuntru e un teleportor, ia-l, te va duce la noi.","Дверь возле оружейного магазина откроется, когда все крестоносцы будут уничтожены. На складе ты найдёшь телепорт. Используй его — он доставит тебя к нам.",,"Dörren bredvid vapenbutiken öppnas när alla korsfarare är döda. Inne i butiksrummet finns en teleporter, använd den och den tar dig till oss.","Tüm Haçlılar öldüğünde silah dükkanının yanındaki kapı açılacak. Dükkanın içinde bir ışınlayıcı var, onu kullanın ve sizi bize getirecek." +"Kill as many of the big robots, Crusaders, as you can. When you're done, I'll guide you to Macil",TXT_ILOG8,,strifeteaser,,"Znič tolik těch velkých robotů, Křižáků, kolik dokážeš. Až budeš hotov, dovedu tě k Macilovi.","Dræb så mange af de store robotter, korsfarerne, som du kan. Når du er færdig, vil jeg guide dig til Macil","Erledige so viele von den großen Robotern - „Ordensrittern“, wie möglich. Wann das erledigt ist, führe ich dich zu Macil.",,,"Mata a tantos de los robots grandes, los cruzados, que puedas. Cuando termines, te guiaré hasta Macil.","Mata a tantos robots gigantes como puedas. Cuando termines, te guiaré a Macil","Tuhoa jättiroboteista, ristiretkeläisistä, niin monta kuin pystyt. Kun olet valmis, opastan sinut Macilin luokse.","Détruis autant des gros robots, les croisés, que tu peux, et je te mènerai à Macil.","Ölj meg annyi nagy robotot és keresztest amennyit csak tudsz. Ha kész vagy, elvezetlek Macilhoz.","Distruggi tutti i Crociati che vedi. Non appena hai finito, ti condurrò da Macil.",,"저 거대한 '크루세이더' 로봇들을 최대한 처리해. 상황이 정리되면, 내가 너를 마실에게 데려다줄게.","Dood zoveel mogelijk van de grote robots, kruisvaarders, als je kunt. Als je klaar bent, begeleid ik je naar Macil...","Drep så mange av de store robotene, korsfarerne, som du kan. Når du er ferdig, skal jeg vise deg veien til Macil.","Zabij jak najwięcej dużych robotów, ""krzyżowców"", jak tylko możesz. Gdy skończysz, zaprowadzę cię do Macila","Mate o máximo desses robos possível. Quando terminar, eu te guiarei ao Macil.",,"Distruge cât mai mulți roboți, Cruciați, pe cât poți. Când ești gata, te voi duce la Macil.","Убей столько больших роботов, — крестоносцев, — сколько сможешь. Когда закончишь, я приведу тебя к Мэйсилу.",,"Döda så många av de stora robotarna, korsriddarna, som du kan. När du är klar kommer jag att guida dig till Macil.","Büyük robotlardan, Haçlılardan, öldürebildiğin kadarını öldür. İşiniz bittiğinde, sizi Macil'e götüreceğim." +"Go through the door, and talk to Macil.",TXT_ILOG9,,strifeteaser,,Projdi dveřmi a promluv si s Macilem.,"Gå gennem døren, og tal med Macil.",Geh durch die Tür und rede mit Macil.,,,Ve por la puerta y habla con Macil.,,Kulje ovesta ja puhu Macilille.,Traverse cette porte et va parler à Macil.,"Az ajtó mögött már vár Macil, beszélj vele.","Attraversa la porta, e vai a parlare con Macil.",ダーウィンを始末したら耳を知事に渡す。,저 문을 지나서 마실하고 대화를 해봐.,"Ga door de deur, en praat met Macil.",Gå gjennom døren og snakk med Macil.,Przejdź przez drzwi i porozmawiaj z Macil.,Passe pela porta e fale com o Macil.,,Intră pe ușă și du-te la Macil.,Обратись к Мэйсилу. Он за этой дверью.,,Gå in genom dörren och prata med Macil.,Kapıdan geçin ve Macil ile konuşun. "Find the power tap on the mains, and shut it off. Bring something back to the Governor as proof. Find MacGuffin, and talk to him.",TXT_ILOG10,"MAP02: After accepting ""messy"" chore and leaving Mourel's room.",,,Najdi stáčedlo energie na elektrické síti a vypni jej. Přines něco guvernérovi jako důkaz. Najdi MacGuffina a promluv s ním.,"Find strømhanen på hovedledningen, og luk den. Tag noget med tilbage til guvernøren som bevis. Find MacGuffin, og tal med ham.",Finde die Stromanzapfung und schalte sie ab. Bringe einen Beweis zum Gouverneur. Finde MacGuffin und rede mit ihm. ,,,Encuentra la intervención en la red eléctrica y destrúyela. Llévale algo al gobernador como prueba. Encuentra a MacGuffin y habla con él.,,Etsi verkkovirran piilokytkentä ja katkaise se. Tuo kuvernöörille jotain todisteeksi. Etsi MacGuffin ja puhu hänen kanssaan.,Trouve la connection pirate sur le transformateur et désactive la. Amène quelque chose au gouverneur comme preuve. Trouve MacGuffin et parle-lui.,"Keresd meg a fővonalon az áramkapcsolót, és kapcsold ki. Hozz vissza valamit a kormányzótól bizonyítékként. Keresd meg MacGuffint, és beszélj vele.","Trova l'aggeggio che sta venendo usato per rubare energia alla rete, e distruggilo. Porta dei resti al governatore come prova. Trova e parla con MacGuffin.","電力盗用の場所を見つけ、それを止める。 -知事に渡す証拠も必要だ。マクガフィンと話をつける。",주 동력선 어딘가에 있는 추출기를 처리해. 총독에게 전할 증거물도 챙기고. 맥거핀을 찾아서 대화해 봐.,Zoek het stopcontact op het lichtnet en zet het uit. Breng iets terug naar de gouverneur als bewijs. Zoek MacGuffin en praat met hem.,"Finn strømkranen på strømnettet, og slå den av. Ta med noe tilbake til guvernøren som bevis. Finn MacGuffin, og snakk med ham.",Znajdź kurek z prądem w sieci i wyłącz go. Przynieś coś gubernatorowi jako dowód. Znajdź MacGuffina i porozmawiaj z nim.,Encontre a ligação pirata no transformador e desligue ela. Traga algo de volta para o Governador como prova. Encontre o MacGuffin e fale com ele.,,"Găsește comutatorul de energie, și oprește-l. Du ceva înapoi la Guvernator drept dovadă. Găsește-l pe MacGuffin, și vorbește cu el.",Найди нелегальное подключение к линии электропередачи и выведи его из строя. Принеси что-нибудь губернатору в качестве доказательства. Найди Макгаффина и поговори с ним.,,Şebekedeki güç musluğunu bulun ve kapatın. Kanıt olarak Vali'ye bir şey getirin. MacGuffin'i bul ve onunla konuş. +知事に渡す証拠も必要だ。マクガフィンと話をつける。",주 동력선 어딘가에 있는 추출기를 처리해. 총독에게 전할 증거물도 챙기고. 맥거핀을 찾아서 대화해 봐.,Zoek het stopcontact op het lichtnet en zet het uit. Breng iets terug naar de gouverneur als bewijs. Zoek MacGuffin en praat met hem.,"Finn strømkranen på strømnettet, og slå den av. Ta med noe tilbake til guvernøren som bevis. Finn MacGuffin, og snakk med ham.",Znajdź kurek z prądem w sieci i wyłącz go. Przynieś coś gubernatorowi jako dowód. Znajdź MacGuffina i porozmawiaj z nim.,Encontre a ligação pirata no transformador e desligue ela. Traga algo de volta para o Governador como prova. Encontre o MacGuffin e fale com ele.,,"Găsește comutatorul de energie, și oprește-l. Du ceva înapoi la Guvernator drept dovadă. Găsește-l pe MacGuffin, și vorbește cu el.",Найди нелегальное подключение к линии электропередачи и выведи его из строя. Принеси что-нибудь губернатору в качестве доказательства. Найди Макгаффина и поговори с ним.,,Leta reda på strömkranen på elnätet och stäng av den. Ta med dig något tillbaka till guvernören som bevis. Hitta MacGuffin och prata med honom.,Şebekedeki güç musluğunu bulun ve kapatın. Kanıt olarak Vali'ye bir şey getirin. MacGuffin'i bul ve onunla konuş. "Find the power tap on the mains, and shut it off. Bring something back to the Governor as proof. Find MacGuffin, and talk to him. He's up by the sewage treatment plant, in the ""bum hole"", down the stairs.",TXT_ILOG11,"MAP02: After accepting ""messy"" chore and leaving Mourel's mansion.",,,"Najdi stáčedlo energie na elektrické síti a vypni jej. Přines něco guvernérovi jako důkaz. Najdi MacGuffina a promluv s ním. Je u čističky, v „zadnici“ pod schody.","Find strømhanen på hovedledningen, og luk den. Tag noget med tilbage til guvernøren som bevis. Find MacGuffin, og tal med ham. Han er oppe ved rensningsanlægget, i ""bum-hullet"", nede ad trappen.","Finde die Stromanzapfung und schalte sie ab. Bringe einen Beweis zum Gouverneur. Finde MacGuffin und rede mit ihm. Er ist in der Nähe der Kläranlage im „Pennerloch“, die Treppe runter.",,,"¡Idiota! Has apagado la energía de los circuitos de interferencia que usamos para ocultarle nuestra base a La Orden. Dirígete al ayuntamiento y elimina al equipo de escaneo, ¡ya! Luego vuelve con el gobernador y dale el acoplador roto.",,"Etsi verkkovirran piilokytkentä ja katkaise se. Tuo kuvernöörille jotain todisteeksi. Etsi MacGuffin ja puhu hänen kanssaan. Hän majailee jätelaitoksella ""pepunreiässä"" rappuset alas.","Trouve la connection pirate sur le transformateur et désactive la. Amène quelque chose au gouverneur comme preuve. Trouve MacGuffin et parle-lui. Il se trouve dans la centrale de traitement des eaux, dans le « trou à rats » en bas des escaliers.","Keresd meg a fővonalon az áramkapcsolót, és kapcsold ki. Hozz vissza valamit a kormányzótól bizonyítékként. Keresd fel MacGuffint és beszélj vele. Ott van a szennyvíz tisztítónál, ha lemész a lépcsőn, lent a ""kotorékban"".","Trova il marchingegno che sta venendo usato per rubare energia alla rete, e distruggilo. Porta dei resti al governatore come prova. Trova e parla con MacGuffin. Lui bazzica dalle parti dell'impianto fognario, oltre delle scale.","電力盗用の場所を見つけ、それを止める。 知事に渡す証拠も必要だ。マクガフィンと話をつける。 -彼は下水処理場の傍にある'物乞いの巣'と呼ばれる場所にいる。",주 동력선 어딘가에 있는 추출기를 처리해. 총독에게 전할 증거물도 챙기고. 맥거핀을 찾아서 대화해 봐. 그는 하수처리장 근처 계단 밑 개구멍에 있어.,"Zoek het stopcontact op het lichtnet en zet het uit. Breng iets terug naar de gouverneur als bewijs. Zoek MacGuffin en praat met hem. Hij is boven bij de rioolwaterzuiveringsinstallatie, in het ""zwerfgat"", de trap af.","Finn strømbryteren på strømnettet, og slå den av. Ta med noe tilbake til guvernøren som bevis. Finn MacGuffin og snakk med ham. Han er oppe ved kloakkrenseanlegget, i ""rumpehullet"", ned trappen.","Znajdź kurek z prądem w sieci i wyłącz go. Zanieś coś gubernatorowi jako dowód. Znajdź MacGuffina i porozmawiaj z nim. Jest przy oczyszczalni ścieków, w ""dziurze"", po schodach.","Encontre a ligação pirata no transformador e desligue ela. Traga algo de volta para o Governador como prova. Encontre o MacGuffin e fale com ele. Ele está na usina de tratamento, na ""toca de rato"" descendo as escadas.",,"Găsește comutatorul de energie, și oprește-l. Du ceva înapoi la Guvernator drept dovadă. Găsește-l pe MacGuffin, și vorbește cu el, e lângă fabrica de tratament, în josul scărilor.","Найди нелегальное подключение к линии электропередачи и выведи его из строя. Принеси что-нибудь губернатору в качестве доказательства. Найди Макгаффина и поговори с ним. Он возле очистного сооружения, в «бомжевой норе», вниз по лестнице.",,"Şebekedeki güç musluğunu bulun ve kapatın. Kanıt olarak Vali'ye bir şey getir. MacGuffin'i bul ve onunla konuş. Kanalizasyon arıtma tesisinin yanında, merdivenlerin aşağısındaki ""serseri deliğinde""." +彼は下水処理場の傍にある'物乞いの巣'と呼ばれる場所にいる。",주 동력선 어딘가에 있는 추출기를 처리해. 총독에게 전할 증거물도 챙기고. 맥거핀을 찾아서 대화해 봐. 그는 하수처리장 근처 계단 밑 개구멍에 있어.,"Zoek het stopcontact op het lichtnet en zet het uit. Breng iets terug naar de gouverneur als bewijs. Zoek MacGuffin en praat met hem. Hij is boven bij de rioolwaterzuiveringsinstallatie, in het ""zwerfgat"", de trap af.","Finn strømbryteren på strømnettet, og slå den av. Ta med noe tilbake til guvernøren som bevis. Finn MacGuffin og snakk med ham. Han er oppe ved kloakkrenseanlegget, i ""rumpehullet"", ned trappen.","Znajdź kurek z prądem w sieci i wyłącz go. Zanieś coś gubernatorowi jako dowód. Znajdź MacGuffina i porozmawiaj z nim. Jest przy oczyszczalni ścieków, w ""dziurze"", po schodach.","Encontre a ligação pirata no transformador e desligue ela. Traga algo de volta para o Governador como prova. Encontre o MacGuffin e fale com ele. Ele está na usina de tratamento, na ""toca de rato"" descendo as escadas.",,"Găsește comutatorul de energie, și oprește-l. Du ceva înapoi la Guvernator drept dovadă. Găsește-l pe MacGuffin, și vorbește cu el, e lângă fabrica de tratament, în josul scărilor.","Найди нелегальное подключение к линии электропередачи и выведи его из строя. Принеси что-нибудь губернатору в качестве доказательства. Найди Макгаффина и поговори с ним. Он возле очистного сооружения, в «бомжевой норе», вниз по лестнице.",,"Leta reda på eluttaget på elnätet och stäng av det. Ta med dig något tillbaka till guvernören som bevis. Hitta MacGuffin och prata med honom. Han är uppe vid reningsverket, i ""bum-hålet"", nerför trappan.","Şebekedeki güç musluğunu bulun ve kapatın. Kanıt olarak Vali'ye bir şey getir. MacGuffin'i bul ve onunla konuş. Kanalizasyon arıtma tesisinin yanında, merdivenlerin aşağısındaki ""serseri deliğinde""." "You idiot! You've shut off the power to the jamming circuits we use to conceal our base from the Order. Head to the town hall and take out the scanning crew, now! Then, go back to the Governor and give him the broken coupling.",TXT_ILOG13,MAP02: After destroying Front's power coupling.,,,"Ty debile! Odstřihnul jsi přívod proudu do rušiček, které používáme, abychom ukryli naší základnu před Řádem. Okamžitě si to zamiř k radnici a vybij průzkumnou četu! Pak se vrať ke guvernérovi a dej mu rozbitou spojku.","Din idiot! Du har slukket for strømmen til de støjkredsløb, som vi bruger til at skjule vores base for Ordenen. Gå hen til rådhuset og udryd scanningsholdet, nu! Gå derefter tilbage til guvernøren og giv ham den ødelagte kobling.","Du Idiot! Du hast die Energie für unsere Störsender unterbrochen, mit denen wir unsere Basis vor dem Orden verborgen haben. Geh schnell zum Rathaus und schalte den Suchtrupp aus. Geh danach zum Gouverneur und gib ihm den zerstörten Stromabnehmer.",,,"¡Idiota! Has apagado la energía de los circuitos de interferencia que usamos para ocultarle nuestra base a La Orden. Dirígete al ayuntamiento y elimina al equipo de escaneo, ¡ya! Luego vuelve con el gobernador y dale el acoplador roto.","¡Idiota! Apagaste la energía de los circuitos de interferencia que usamos para ocultarle nuestra base a La Orden. Dirígete al ayuntamiento y elimina al equipo de escaneo, ¡ya! Luego vuelve con el gobernador y dale el acoplador roto.","Sinä idiootti! Olet katkaissut virran häirintäpiireihin, joilla piilotamme sijaintimme Veljeskunnalta. Suuntaa kaupungintalolle ja hoitele tiedusteluryhmä, heti paikalla! Palaa sitten kuvernöörin luo ja anna rikkinäinen virtaliitin hänelle.",Idiot! Tu as désactivé les circuits brouilleurs qui cachaient notre base des senseurs de l'Ordre. Retourne vite à la mairie et tue l'équipe de scan maintenant! Retourne ensuite au gouverneur et donne lui le coupleur cassé.,"Te idióta! Leállítottad a zavaró áramellátását, amivel lerejtjük magunkat a Rend elől. Menj azonnal a városházára, és iktasd ki a felderítő brigádot! Aztán menj vissza a kormányzóhoz, és add át az elrontott kapcsolóművet.","Idiota! Hai interrotto il flusso di energia dei circuiti che usavamo per nascondere la nostra base dall'Ordine. Ritorna subito al municipio e fai fuori il gruppo venuto a perlustare la zona, ora! Poi, torna dal governatore e dagli questo pezzo di ferraglia.","馬鹿者! お前はオーダーから我々の基地を隠す妨害回路を 壊してしまった!市庁舎に調査隊が向かった、今すぐ片付けろ! -",이 멍청이야! 우리 기지를 오더로부터 은폐시켜주는 교란 장치의 동력을 끊어버렸잖아. 당장 시청으로 가서 탐색반들을 쓸어버려! 그다음에 총독에게 부서진 장치를 전해줘.,Idioot! Je hebt de stroom naar de stoorcircuits die we gebruiken om onze basis te verbergen voor de orde uitgeschakeld. Ga naar het stadhuis en haal de scanploeg er nu uit! Ga dan terug naar de Gouverneur en geef hem de kapotte koppeling.,"Din idiot! Du har slått av strømmen til blokkeringskretsene vi bruker for å skjule basen vår for Ordenen. Dra til rådhuset og drep skannermannskapet, nå! Gå tilbake til guvernøren og gi ham den ødelagte koblingen.","Ty idioto! Wyłączyłeś zasilanie obwodów zagłuszających, których używamy do ukrycia naszej bazy przed Zakonem. Idź do ratusza i zlikwiduj ekipę skanującą, natychmiast! Potem wróć do gubernatora i daj mu zepsute złącze.",Seu idiota! Você desligou a energia para os circuitos de interferência que usamos para esconder a nossa base dos sensores da Ordem. Vá até a prefeitura e tire a equipe de busca de lá imediatamente! Depois disso volte para o Governador e passe pra ele a conexão quebrada.,,"Idiotule! Ai oprit curentul circuitelor noastre care ne mascau prezența. Du-te în hala orașului și elimină echipajul! Apoi, du-te la Guvernator și dă-i cuplajul!","Идиот! Ты обесточил генератор радиопомех, с помощью которого мы скрывали местоположение нашей базы от Ордена. Возвращайся к ратуше и уничтожь разведывательную группу как можно скорее! Затем вернись к губернатору и отдай ему повреждённую муфту.",,"Seni aptal! Üssümüzü Tarikat'tan gizlemek için kullandığımız sinyal bozucu devrelerin gücünü kestin. Belediye binasına git ve tarama ekibini yok et, hemen! Sonra Vali'ye geri dön ve ona kırık bağlantıyı ver." +",이 멍청이야! 우리 기지를 오더로부터 은폐시켜주는 교란 장치의 동력을 끊어버렸잖아. 당장 시청으로 가서 탐색반들을 쓸어버려! 그다음에 총독에게 부서진 장치를 전해줘.,Idioot! Je hebt de stroom naar de stoorcircuits die we gebruiken om onze basis te verbergen voor de orde uitgeschakeld. Ga naar het stadhuis en haal de scanploeg er nu uit! Ga dan terug naar de Gouverneur en geef hem de kapotte koppeling.,"Din idiot! Du har slått av strømmen til blokkeringskretsene vi bruker for å skjule basen vår for Ordenen. Dra til rådhuset og drep skannermannskapet, nå! Gå tilbake til guvernøren og gi ham den ødelagte koblingen.","Ty idioto! Wyłączyłeś zasilanie obwodów zagłuszających, których używamy do ukrycia naszej bazy przed Zakonem. Idź do ratusza i zlikwiduj ekipę skanującą, natychmiast! Potem wróć do gubernatora i daj mu zepsute złącze.",Seu idiota! Você desligou a energia para os circuitos de interferência que usamos para esconder a nossa base dos sensores da Ordem. Vá até a prefeitura e tire a equipe de busca de lá imediatamente! Depois disso volte para o Governador e passe pra ele a conexão quebrada.,,"Idiotule! Ai oprit curentul circuitelor noastre care ne mascau prezența. Du-te în hala orașului și elimină echipajul! Apoi, du-te la Guvernator și dă-i cuplajul!","Идиот! Ты обесточил генератор радиопомех, с помощью которого мы скрывали местоположение нашей базы от Ордена. Возвращайся к ратуше и уничтожь разведывательную группу как можно скорее! Затем вернись к губернатору и отдай ему повреждённую муфту.",,"Din idiot! Du har stängt av strömmen till de störningskretsar som vi använder för att dölja vår bas för Orden. Gå till stadshuset och ta ut skanningspersonalen, nu! Gå sedan tillbaka till guvernören och ge honom den trasiga kopplingen.","Seni aptal! Üssümüzü Tarikat'tan gizlemek için kullandığımız sinyal bozucu devrelerin gücünü kestin. Belediye binasına git ve tarama ekibini yok et, hemen! Sonra Vali'ye geri dön ve ona kırık bağlantıyı ver." "OK, ""Trust no one"" is the name of the game! Let's get that prison pass from the Governor. Take the broken coupling to him.",TXT_ILOG14,MAP02: After destroying Front's power coupling and killing all blue acolytes in the town hall.,,,"Dobře, „Nevěř nikomu“ je motto hry! Pojďme od guvernéra dostat tu propustku a osvoboďme ty vězně. Přines mu rozbitou spojku.","Okay, ""Stol ikke på nogen"" er spillets navn! Lad os få det fængselskort fra guvernøren. Tag den ødelagte kobling med til ham.","Ok, „Trau keinem“ heißt dieses Spiel. Lass uns den Gefängnispass vom Gouverneur holen. Bring ihm den Stromabnehmer.",,,"Vale, ¡«No te fies de nadie» se llama el juego! Ya es hora de conseguir el pase a la prisión. Llévale el acoplador roto al Gobernador.","Bueno, ¡«No confíes en nadie» se llama el juego! Ya es hora de conseguir el pase a la prisión. Llévale el acoplador roto al Gobernador.","Selvä, ""Älä luota kehenkään"" on näköjään pelin nimi! Hankitaan vankilan pääsylupa kuvernööriltä. Vie rikkinäinen virtaliitin hänelle.","Ok, « ne fais confiance à personne » est notre nouveau slogan. On va récupérer le passe de la prison chez le gouverneur. Amène lui le coupleur cassé.","Készülj fel, hogy senkiben sem bízhatsz. Gyerünk, szerezzük meg a kormányzótól a börtön belépőt. Vidd el hozzá az elrontott kapcsolóművet.","OK, ""Non fidarti di nessuno"" è il gioco che stiamo giocando qua! Prendiamo quel pass per la prigione dal governatore. Portagli quel pezzo di ferraglia.","よし、'信用しない'のが最も重要なことだ! -壊れた配電機を渡して刑務所の許可証を知事から貰うんだ。","좋아, '아무도 믿지 말라'가 이 게임의 이름이겠군! 어서 총독에게 감옥 통행증이나 받자. 이 부서진 장치를 그에게 전해줘.","OK, ""Vertrouw niemand"" is de naam van het spel! Laten we die gevangenispas van de Gouverneur halen. Pak de kapotte koppeling naar hem toe.","OK, ""Stol ikke på noen"" er navnet på spillet! La oss få fengselspasset fra guvernøren. Gi ham den ødelagte koblingen.","OK, ""Nie ufaj nikomu"" to nazwa gry! Zdobądźmy tę przepustkę od Gubernatora. Zanieś mu zepsute złącze.","Ok, ""não confie em ninguém"" é o nome do jogo! Vamos pegar do Governador aquele passe da prisão. Leve a conexão quebrada a ele.",,"OK, 'Încrede-te în nimeni' e numele jocului. Să luam permisul închisorii de la Guvernator. Ia cuplajul defect și du-l lui.","Что ж, эта игра называется «не верь никому»! Давай получим у губернатора пропуск в тюрьму. Отнеси ему повреждённую муфту.",,"Tamam, ""Kimseye güvenme"" oyunun adı! Vali'den şu hapishane kartını alalım. Kırık bağlantıyı ona götür." +壊れた配電機を渡して刑務所の許可証を知事から貰うんだ。","좋아, '아무도 믿지 말라'가 이 게임의 이름이겠군! 어서 총독에게 감옥 통행증이나 받자. 이 부서진 장치를 그에게 전해줘.","OK, ""Vertrouw niemand"" is de naam van het spel! Laten we die gevangenispas van de Gouverneur halen. Pak de kapotte koppeling naar hem toe.","OK, ""Stol ikke på noen"" er navnet på spillet! La oss få fengselspasset fra guvernøren. Gi ham den ødelagte koblingen.","OK, ""Nie ufaj nikomu"" to nazwa gry! Zdobądźmy tę przepustkę od Gubernatora. Zanieś mu zepsute złącze.","Ok, ""não confie em ninguém"" é o nome do jogo! Vamos pegar do Governador aquele passe da prisão. Leve a conexão quebrada a ele.",,"OK, 'Încrede-te în nimeni' e numele jocului. Să luam permisul închisorii de la Guvernator. Ia cuplajul defect și du-l lui.","Что ж, эта игра называется «не верь никому»! Давай получим у губернатора пропуск в тюрьму. Отнеси ему повреждённую муфту.",,"Okej, ""Lita inte på någon"" är vad som gäller! Låt oss få fängelsepasset från guvernören. Ta den trasiga kopplingen till honom.","Tamam, ""Kimseye güvenme"" oyunun adı! Vali'den şu hapishane kartını alalım. Kırık bağlantıyı ona götür." Good move! The Governor is a liar. That's our power coupling. We're using it to hide the base from the Order. Take this broken coupling back to him and let's get that pass.,TXT_ILOG15,MAP02: After finding the broken power coupling.,,,"Dobrý tah! Guvernér je lhář, tohle je naše spojka. Používáme ji k ukrytí základny před Řádem. Přines mu tuhle rozbitou spojku a vezmi si od něj tu propustku.","Godt træk! Guvernøren er en løgner. Det er vores kraftkobling. Vi bruger den til at skjule basen for Ordenen. Tag den ødelagte kobling med tilbage til ham, og lad os få det pas.",Das war klasse! Der Gouverneur ist ein verdammter Lügner. Das war unsere Anzapfung. Wir benutzen sie um unsere Basis vor dem Orden zu verstecken. Und nun bring ihm den Stromabnehmer und hol den Gefängnispass.,,,¡Buen ojo! El gobernador es un mentiroso: ese era el acoplador de energía que el Frente está usando para ocultarle la base a La Orden. Llévale el acoplador roto para conseguir ese pase.,,"Hyvä veto! Kuvernööri on valehtelija. Se on meidän virtaliittimemme. Käytämme sitä piillottamaan tukikohtamme Veljeskunnalta. Toimita tämä rikkinäinen virtaliitin takaisin hänelle, ja hankitaan se pääsylupa.",Bonne idée! Le gouverneur est un menteur. Voilà notre coupleur. On l'utilise pour dissimuler notre présence à l'Ordre. Amène ce coupleur cassé à lui et récupère le passe.,"Ügyes lépés! A kormányzó egy hazug senkiházi. Ez a mi kapcsolóművünk. Arra használjuk, hogy elrejtsük a bázisunkat a Rend elől. Vidd vissza neki a tönkrevágott kapcsolóművet, és irány megszerezni a belépőt.","Ottima mossa! Il governatore è un bugiardo. Eravamo noi a utilizzare questo marchingegno collegato alla rete. Lo stiamo usando per nascondere la posizione della nostra base dall'Ordine. Prendi quest'altro rotto e vecchio e portalo da lui, e prendiamoci quel pass.","良い判断だ! 知事は嘘を付いている。 あれはオーダーから基地を隠す為に使用している我々の配電機だ。 -この壊れた配電機を渡して奴を騙し返せ。",참 잘했어! 총독이 거짓말을 했군. 이건 우리의 동력 장치야. 이걸 써서 우리 기지를 오더로부터 은폐시켜주지. 여기 있는 고장 난 장치를 전해주고 통행증이나 받자.,Goede zet! De Gouverneur is een leugenaar. Dat is onze stroomkoppeling. We gebruiken het om de basis te verbergen voor de Orde. Neem deze kapotte koppeling terug naar hem en laten we die pass pakken.,Godt trekk! Guvernøren er en løgner. Det er kraftkoblingen vår. Vi bruker den til å skjule basen for Ordenen. Ta denne ødelagte koblingen tilbake til ham og la oss få det passet.,"Dobry ruch! Gubernator to kłamca. To jest nasze sprzęgło mocy. Używamy go, by ukryć bazę przed Zakonem. Zabierz mu to zepsute sprzęgło i zdobądźmy tę przepustkę.",Boa! O Governador é um mentiroso . Essa é a nossa conexão. Vamos usá-la para esconder a base da Ordem. Leve esta conexão danificada de volta a ele e vamos pegar o passe.,,"Bună mutare! Guvernatorul e un mincins. Acela e cuplajul nostru. Îl folosim pentru a ne ascunde baza de Ordin. Ia cuplajul ăsta defect și du-l înapoi lui, să luăm permisul.","Отличный ход! Губернатор — лжец. Это наше подключение к силовой линии. Мы используем его, чтобы скрывать местоположение нашей базы от Ордена. Отнеси повреждённую муфту губернатору и получи пропуск.",,İyi hamle! Vali bir yalancı. Bu bizim güç bağlantımız. Üssü Tarikat'tan saklamak için kullanıyoruz. Bu kırık bağlantıyı ona geri götür ve şu geçiş iznini alalım. +この壊れた配電機を渡して奴を騙し返せ。",참 잘했어! 총독이 거짓말을 했군. 이건 우리의 동력 장치야. 이걸 써서 우리 기지를 오더로부터 은폐시켜주지. 여기 있는 고장 난 장치를 전해주고 통행증이나 받자.,Goede zet! De Gouverneur is een leugenaar. Dat is onze stroomkoppeling. We gebruiken het om de basis te verbergen voor de Orde. Neem deze kapotte koppeling terug naar hem en laten we die pass pakken.,Godt trekk! Guvernøren er en løgner. Det er kraftkoblingen vår. Vi bruker den til å skjule basen for Ordenen. Ta denne ødelagte koblingen tilbake til ham og la oss få det passet.,"Dobry ruch! Gubernator to kłamca. To jest nasze sprzęgło mocy. Używamy go, by ukryć bazę przed Zakonem. Zabierz mu to zepsute sprzęgło i zdobądźmy tę przepustkę.",Boa! O Governador é um mentiroso . Essa é a nossa conexão. Vamos usá-la para esconder a base da Ordem. Leve esta conexão danificada de volta a ele e vamos pegar o passe.,,"Bună mutare! Guvernatorul e un mincins. Acela e cuplajul nostru. Îl folosim pentru a ne ascunde baza de Ordin. Ia cuplajul ăsta defect și du-l înapoi lui, să luăm permisul.","Отличный ход! Губернатор — лжец. Это наше подключение к силовой линии. Мы используем его, чтобы скрывать местоположение нашей базы от Ордена. Отнеси повреждённую муфту губернатору и получи пропуск.",,Bra gjort! Guvernören är en lögnare. Det är vår kraftkoppling. Vi använder den för att dölja basen för orden. Ta tillbaka den trasiga kopplingen till honom och låt oss få det där passet.,İyi hamle! Vali bir yalancı. Bu bizim güç bağlantımız. Üssü Tarikat'tan saklamak için kullanıyoruz. Bu kırık bağlantıyı ona geri götür ve şu geçiş iznini alalım. Use the Warden's key to get into the prison cell blocks and find a way to free the prisoners.,TXT_ILOG18,MAP05: After crossing the alarm green door.,,,"Použij dozorcův klíč k dostání se do bloku s celami a najdi způsob, jak osvobodit vězně.",Brug fængselsdirektørens nøgle til at komme ind i fængselscelleblokkene og find en måde at befri fangerne på.,"Benutze den Schlüssel des Direktors um in die Zellenblöcke zu kommen und finde heraus, wie man die Gefangenen befreien kann.",,,Usa la llave del Carcelero para entrar en los bloques de celdas y encuentra una forma de liberar a los prisioneros.,Usa la llave del Carcelero para entrar a los bloques de celdas y encuentra una forma de liberar a los prisioneros.,Käytä vankilanjohtajan avainta päästäksesi vankilan selliosastoille ja keksi keino vapauttaa vangit.,Utilise la clé du gardien pour entrer dans le bloc de cellules et trouver une manière de libérer les prisonniers.,"Használd az igazgató kulcsát, hogy bejuss a börtön részlegbe, és kiszíbadíts mindenkit.",Usa la chiave del direttore per entrare nella sezione delle celle e trovare un modo per liberare i prigionieri.,"ワーデンの鍵で刑務所の独房区域に入って -囚人を解放する方法を見つける。","간수장의 열쇠를 써서 감옥 안으로 진입하고, 수감자들을 풀어줄 방법을 찾아봐.",Gebruik de sleutel van de bewaker om in de celblokken van de gevangenis te komen en een manier te vinden om de gevangenen te bevrijden.,Bruk direktørens nøkkel til å komme inn i fengselsblokkene og finn en måte å befri fangene på.,"Użyj klucza naczelnika, aby dostać się do bloków więziennych i znajdź sposób na uwolnienie więźniów.",Use a chave do Carcereiro para entrar nos blocos de celas e ache uma maneira de libertar os prisioneiros.,,Folosește cheia Directorului pentru a intra în blocurile celulelor și găsește o cale să eliberezi prizonierii.,"Используй ключ тюремщика, чтобы пройти к камерам. Найди способ освободить пленников.",,Hapishane hücre bloklarına girmek için Müdür'ün anahtarını kullan ve mahkumları serbest bırakmanın bir yolunu bul. +囚人を解放する方法を見つける。","간수장의 열쇠를 써서 감옥 안으로 진입하고, 수감자들을 풀어줄 방법을 찾아봐.",Gebruik de sleutel van de bewaker om in de celblokken van de gevangenis te komen en een manier te vinden om de gevangenen te bevrijden.,Bruk direktørens nøkkel til å komme inn i fengselsblokkene og finn en måte å befri fangene på.,"Użyj klucza naczelnika, aby dostać się do bloków więziennych i znajdź sposób na uwolnienie więźniów.",Use a chave do Carcereiro para entrar nos blocos de celas e ache uma maneira de libertar os prisioneiros.,,Folosește cheia Directorului pentru a intra în blocurile celulelor și găsește o cale să eliberezi prizonierii.,"Используй ключ тюремщика, чтобы пройти к камерам. Найди способ освободить пленников.",,Använd direktörens nyckel för att ta dig in i fängelsecellblocken och hitta ett sätt att befria fångarna.,Hapishane hücre bloklarına girmek için Müdür'ün anahtarını kullan ve mahkumları serbest bırakmanın bir yolunu bul. Find a way to free the prisoners. Find a way to open the hand scanner switch.,TXT_ILOG19,MAP05: After getting to Main Control.,,,"Najdi způsob, jak osvobodit vězně. Najdi způsob, jak aktivovat skener otisků ruky.",Find en måde at befri fangerne på. Find en måde at åbne håndscannerkontakten.,"Finde heraus, wie man die Gefangenen befreien kann und wie du den Handscanner umgehen kannst.",,,Encuentra una forma de liberar a los prisioneros. Encuentra una forma de operar los sensores de escáner de mano.,,Etsi keino vapauttaa vangit. Ratkaise tapa avata kädenjälkilukijan lukitus.,Trouve un moyen de libérer les prisonniers. Trouve une manière d'activer le scanner à empreinte digitale.,"Találd meg a módját, hogyan szabadíthatjuk ki a rabokat, és hogyan játszhatjuk ki a kézlenyomat olvasót.",Trova un modo per liberare i prigionieri. Trova un modo per attivare lo scanner della mano.,"囚人を解放する方法を見つける。 - ハンドスキャナーを開く方法を見つける。",수감자들을 풀어줄 방법을 찾자. 지문인식장치를 통과할 방법을 찾아봐.,Zoek een manier om de gevangenen te bevrijden. Zoek een manier om de handscanner schakelaar te openen.,Finn en måte å befri fangene på. Finn en måte å åpne håndskannerbryteren på.,Znajdź sposób na uwolnienie więźniów. Znajdź sposób na otwarcie przełącznika skanera ręcznego.,Encontre uma maneira de libertar os prisioneiros. Ache uma maneira de abrir o scanner de mão.,,Găsește o cale să eliberezi prizonierii. Găsește o cale să deschizi comutatorul scanner-ului de mâini.,Найди способ освободить пленников. Найди способ открыть замок со сканером отпечатка руки.,,Mahkûmları serbest bırakmanın bir yolunu bul. El tarayıcı anahtarını açmanın bir yolunu bulun. + ハンドスキャナーを開く方法を見つける。",수감자들을 풀어줄 방법을 찾자. 지문인식장치를 통과할 방법을 찾아봐.,Zoek een manier om de gevangenen te bevrijden. Zoek een manier om de handscanner schakelaar te openen.,Finn en måte å befri fangene på. Finn en måte å åpne håndskannerbryteren på.,Znajdź sposób na uwolnienie więźniów. Znajdź sposób na otwarcie przełącznika skanera ręcznego.,Encontre uma maneira de libertar os prisioneiros. Ache uma maneira de abrir o scanner de mão.,,Găsește o cale să eliberezi prizonierii. Găsește o cale să deschizi comutatorul scanner-ului de mâini.,Найди способ освободить пленников. Найди способ открыть замок со сканером отпечатка руки.,,Hitta ett sätt att befria fångarna. Hitta ett sätt att öppna handskanneromkopplaren.,Mahkûmları serbest bırakmanın bir yolunu bul. El tarayıcı anahtarını açmanın bir yolunu bulun. Find a way to free the prisoners. Use the judge's hand to operate the hand scanner switch.,TXT_ILOG20,MAP05: After cutting Wolenick's hand off.,,,"Najdi způsob, jak osvobodit vězně. Použij soudcovu ruku k aktivaci skeneru otisků ruky.",Find en måde at befri fangerne på. Brug dommerens hånd til at betjene håndscannerkontakten.,"Finde heraus, wie man die Gefangenen befreien kann. Benutze die Hand des Richters um den Handscannerschalter zu betätigen.",,,Encuentra una forma de liberar a los prisioneros. Usa la mano del juez para operar los sensores de escáner de mano.,,Etsi keino vapauttaa vangit. Käytä tuomarin kättä kädenjälkilukijaan.,Trouve un moyen de libérer les prisonniers. Utilise la main du juge pour activer le scanner à empreinte digitale.,"Találd meg a módját, hogyan szabadíthatjuk ki a rabokat, használd a bíró kezét a kézleolvasóhoz.",Trova un modo per liberare i prigionieri. Usa la mano del giudice per operare lo scanner.,"囚人を解放する方法を見つける。 -裁判官の手を使用してハンドスキャナースイッチを操作する。",수감자들을 풀어줄 방법을 찾자. 판사의 손을 써서 지문인식장치를 통과하는 거야.,Zoek een manier om de gevangenen te bevrijden. Gebruik de hand van de rechter om de handscanner schakelaar te bedienen.,Finn en måte å befri fangene på. Bruk dommerens hånd til å betjene håndskannerbryteren.,"Znajdź sposób na uwolnienie więźniów. Użyj ręki sędziego, aby uruchomić przełącznik skanera ręcznego.",Encontre uma maneira de libertar os prisioneiros. Use a mão do juiz para operar o scanner.,,Găsește o cale să eliberezi prizonierii. Folosește mâna judecătorului să operezi scanner-ul de mâini.,"Найди способ освободить пленников. Используй руку судьи, чтобы открыть замок со сканером отпечатка руки.",,Mahkûmları serbest bırakmanın bir yolunu bulun. El tarayıcı anahtarını çalıştırmak için yargıcın elini kullan. +裁判官の手を使用してハンドスキャナースイッチを操作する。",수감자들을 풀어줄 방법을 찾자. 판사의 손을 써서 지문인식장치를 통과하는 거야.,Zoek een manier om de gevangenen te bevrijden. Gebruik de hand van de rechter om de handscanner schakelaar te bedienen.,Finn en måte å befri fangene på. Bruk dommerens hånd til å betjene håndskannerbryteren.,"Znajdź sposób na uwolnienie więźniów. Użyj ręki sędziego, aby uruchomić przełącznik skanera ręcznego.",Encontre uma maneira de libertar os prisioneiros. Use a mão do juiz para operar o scanner.,,Găsește o cale să eliberezi prizonierii. Folosește mâna judecătorului să operezi scanner-ul de mâini.,"Найди способ освободить пленников. Используй руку судьи, чтобы открыть замок со сканером отпечатка руки.",,Hitta ett sätt att befria fångarna. Använd domarens hand för att använda handskannern.,Mahkûmları serbest bırakmanın bir yolunu bulun. El tarayıcı anahtarını çalıştırmak için yargıcın elini kullan. Way to go my friend. Good work freeing the prisoners. Jump on one of the teleporters and it will bring you back to base.,TXT_ILOG21,MAP05: After setting the prisoners free.,,,"Jen tak dál, příteli, dobrá práce. Skoč na teleportér, dostane tě to zpět na základnu.","Godt gået, min ven. Godt arbejde med at befri fangerne. Hop på en af teleportørerne, så kommer du tilbage til basen.","Das war gute Arbeit, wie du die Gefangenen befreit hast. Benutze einen der Teleporter um zur Basis zurückzugelangen.",,,"Así se hace, amigo. Buen trabajo liberando a los prisioneros. Ponte en uno de los teletransportes y te traerá de vuelta a la base.",,"Niin sitä pitää, ystäväni. Hyvin toimittu vankien vapauttamisessa. Hyppää johonkin kaukosiirtimistä, ja se tuo sinut takaisin tukikohtaan.",Bien joué mon ami! Bon travail avec ces prisonniers. Utilise l'un des téléporteurs pour revenir à la base.,"Remek volt. Szép munka volt a rabok kiszabadítása. Ugorj be valamelyik teleportba, és visszavisz a bázisba.","Ottimo lavoro, amico. Grazie a te i prigionieri sono stati liberati. Prendi uno dei teletrasporti e ti riporteremo alla base.","よくやった相棒。囚人を解放できたのは良い働きだ。 -いずれかのテレポーターに飛び込むと基地に戻る。","잘했어, 친구. 수감자들을 풀어주느라 고생했어. 저 텔레포터들 중 하나를 타면 우리 기지로 복귀할 수 있을 거야.","Goed gedaan, mijn vriend. Goed werk om de gevangenen te bevrijden. Spring op een van de teleporters en die brengt je terug naar de basis.","Sånn skal det gjøres, min venn. Godt jobbet med å befri fangene. Hopp på en av teleporterne, så kommer du tilbake til basen.","Brawo mój przyjacielu. Dobra robota z uwolnieniem więźniów. Wskocz na jeden z teleporterów, a przeniesie cię on z powrotem do bazy.","Boa, meu amigo. Bom trabalho ao libertar os prisioneiros. Entre num desses teletransportadores e você voltará pra base.",,Bună treabă prietene. Sari într-un teleportor și te va duce la baza noastră.,"Так держать, дружище. Ты отлично поработал и освободил пленников. Прыгай в любой телепорт, и он вернёт тебя на базу.",,Aferin dostum. Mahkûmları serbest bırakarak iyi iş çıkardın. Işınlayıcılardan birine atla ve seni üsse geri getirsin. +いずれかのテレポーターに飛び込むと基地に戻る。","잘했어, 친구. 수감자들을 풀어주느라 고생했어. 저 텔레포터들 중 하나를 타면 우리 기지로 복귀할 수 있을 거야.","Goed gedaan, mijn vriend. Goed werk om de gevangenen te bevrijden. Spring op een van de teleporters en die brengt je terug naar de basis.","Sånn skal det gjøres, min venn. Godt jobbet med å befri fangene. Hopp på en av teleporterne, så kommer du tilbake til basen.","Brawo mój przyjacielu. Dobra robota z uwolnieniem więźniów. Wskocz na jeden z teleporterów, a przeniesie cię on z powrotem do bazy.","Boa, meu amigo. Bom trabalho ao libertar os prisioneiros. Entre num desses teletransportadores e você voltará pra base.",,Bună treabă prietene. Sari într-un teleportor și te va duce la baza noastră.,"Так держать, дружище. Ты отлично поработал и освободил пленников. Прыгай в любой телепорт, и он вернёт тебя на базу.",,"Bra jobbat, min vän. Bra jobbat med att befria fångarna. Hoppa på en av teleporterna så tar den dig tillbaka till basen.",Aferin dostum. Mahkûmları serbest bırakarak iyi iş çıkardın. Işınlayıcılardan birine atla ve seni üsse geri getirsin. "Destroy the power crystal that runs the power grid which drives the Order's shields. Go visit Worner, a spy we recruited in the warehouse of the power station.",TXT_ILOG22,,,,"Znič energetický krystal, který napájí elektrickou síť, kterou jsou poháněné štíty Řádu. Jdi navštívit Wornera, špióna, kterého jsme najali ve skladu elektrárny.","Ødelæg energikrystallen, der driver det strømnet, som driver Ordenens skjolde. Besøg Worner, en spion, som vi rekrutterede i lageret på kraftværket.","Zerstöre den Energiekristall der die Energieversorgung für die Kraftschilde kontrolliert. Suche Worner auf, einen Spion, den wir im Lagerhaus des Kraftwerks rekrutiert haben. ",,,"Destruye el cristal de poder que impulsa la red eléctrica que alimenta los escudos de La Orden. Busca a Worner, un espía que reclutamos en el almacén de la central eléctrica.",,"Tuhoa kaupungin sähköverkon voimanlähteenä toimiva voimakristalli, jonka voimaa Veljeskunnan kilvet käyttävät. Mene tapaamaan Worneria, vakoojaa, jonka värväsimme voimalaitoksen varastolta.","Détruis le cristal qui contrôle la grille énergétique des boucliers de l'Ordre. Va voir Worner, un espion que l'on a recruté dans l'entrepôt de la centrale.","Semmisítsd meg az erő kristályt, ami a Rend külső védőpajzsát hajtja az elektromos hálózaton keresztül. Keresd fel az erőműtől betoborzott kémünket, Wornert.","Distruggi il cristallo che fornisce energia agli scudi dell'Ordine. Trova Worner, una spia che abbiamo reclutato nel magazzino della centrale energetica.","送電網を動かしているパワークリスタルを破壊してオーダーのシールドを止めろ。 -発電所の倉庫に潜らせたスパイ、ワーナーを訪ねよ。","오더의 방어막을 유지하는 동력 망의 전력원인 수정체를 파괴하자. 우선, 발전소 창고에 있는 우리 쪽 첩자인 워너에게 찾아가 보자.","Vernietig het energiekristal dat het stroomnet dat de schilden van de Orde aandrijft. Ga op bezoek bij Worner, een spion die we gerekruteerd hebben in het magazijn van de centrale.","Ødelegg kraftkrystallen som driver kraftnettet som driver Ordenens skjold. Besøk Worner, en spion vi rekrutterte i kraftstasjonens lager.","Zniszcz kryształ mocy, który zasila sieć energetyczną napędzającą tarcze Zakonu. Idź odwiedzić Wornera, szpiega, którego zwerbowaliśmy w magazynie elektrowni.","Destrua o cristal de energia que alimenta a rede elétrica por trás dos escudos da Ordem. Visite o Worner, um espião que recrutamos no depósito da usina de energia.",,"Distruge cristalul de energie care alimentează scuturile Ordinului. Vizitează-l pe Worner, un spion recrutat în depozitul stației de energie.","Уничтожь кристалл, питающий энергосеть Ордена, от которой работают их щиты. Встреться с Уорнэром, нашим шпионом, на складе электростанции.",,Tarikat'ın kalkanlarını çalıştıran güç şebekesini çalıştıran güç kristalini yok edin. Güç istasyonunun deposunda işe aldığımız casus Worner'ı ziyaret et. -Let's get lost. There's more fun to come.,TXT_ILOG24,MAP04: After leaving Reactor Core.,,,"Ztraťme se, za chvíli tu bude víc srandy.",Lad os fare vild. Der er mere sjov på vej.,Lass uns verschwinden. Hier wird's gleich ungemütlich.,,,Hay que irse. La central está alerta.,,Häivytään. Lisää hupia on luvassa.,"Partons d'ici, il y a encore de quoi s'amuser.",Húzzunk innen. Most jön még az izgi rész.,Leviamoci di torno. C'è ancora da divertirsi.,迷子になったら、もっと楽しめるぞ。,어서 여길 떠나자. 녀석들이 오기 전에 말이야.,Laten we verdwalen. Er komt nog meer plezier.,La oss stikke. Det er mer moro i vente.,Zgubmy się. Czeka nas jeszcze więcej zabawy.,Então se manda. Tem mais diversão por vir.,,Să ne pierdem. O să mai fie distracții.,Давай-ка исчезнем отсюда. Скоро начнётся веселье.,,Hadi kaybolalım. Daha çok eğlence var. +発電所の倉庫に潜らせたスパイ、ワーナーを訪ねよ。","오더의 방어막을 유지하는 동력 망의 전력원인 수정체를 파괴하자. 우선, 발전소 창고에 있는 우리 쪽 첩자인 워너에게 찾아가 보자.","Vernietig het energiekristal dat het stroomnet dat de schilden van de Orde aandrijft. Ga op bezoek bij Worner, een spion die we gerekruteerd hebben in het magazijn van de centrale.","Ødelegg kraftkrystallen som driver kraftnettet som driver Ordenens skjold. Besøk Worner, en spion vi rekrutterte i kraftstasjonens lager.","Zniszcz kryształ mocy, który zasila sieć energetyczną napędzającą tarcze Zakonu. Idź odwiedzić Wornera, szpiega, którego zwerbowaliśmy w magazynie elektrowni.","Destrua o cristal de energia que alimenta a rede elétrica por trás dos escudos da Ordem. Visite o Worner, um espião que recrutamos no depósito da usina de energia.",,"Distruge cristalul de energie care alimentează scuturile Ordinului. Vizitează-l pe Worner, un spion recrutat în depozitul stației de energie.","Уничтожь кристалл, питающий энергосеть Ордена, от которой работают их щиты. Встреться с Уорнэром, нашим шпионом, на складе электростанции.",,"Förstör kraftkristallen som driver kraftnätet som driver Ordens sköldar. Gå och besök Worner, en spion som vi rekryterade i kraftverkets lager.",Tarikat'ın kalkanlarını çalıştıran güç şebekesini çalıştıran güç kristalini yok edin. Güç istasyonunun deposunda işe aldığımız casus Worner'ı ziyaret et. +Let's get lost. There's more fun to come.,TXT_ILOG24,MAP04: After leaving Reactor Core.,,,"Ztraťme se, za chvíli tu bude víc srandy.",Lad os fare vild. Der er mere sjov på vej.,Lass uns verschwinden. Hier wird's gleich ungemütlich.,,,Hay que irse. La central está alerta.,,Häivytään. Lisää hupia on luvassa.,"Partons d'ici, il y a encore de quoi s'amuser.",Húzzunk innen. Most jön még az izgi rész.,Leviamoci di torno. C'è ancora da divertirsi.,迷子になったら、もっと楽しめるぞ。,어서 여길 떠나자. 녀석들이 오기 전에 말이야.,Laten we verdwalen. Er komt nog meer plezier.,La oss stikke. Det er mer moro i vente.,Zgubmy się. Czeka nas jeszcze więcej zabawy.,Então se manda. Tem mais diversão por vir.,,Să ne pierdem. O să mai fie distracții.,Давай-ка исчезнем отсюда. Скоро начнётся веселье.,,Låt oss gå vilse. Det finns mer kul att göra.,Hadi kaybolalım. Daha çok eğlence var. "One more adventure before command feels it's safe to attack the castle. Macil's arranged for Irale to give you gold and some training. After you visit him, see the medic in town for strength.",TXT_ILOG25,MAP02: After destroying the crystal in the Power Station.,,,"Ještě jedno dobrodružství, než se velení rozhodne zaútočit. Macil sjednal u Iraleho zlato a trénink. Pak navštiv městského lékaře pro sílu.","Et eventyr mere, før kommandoen føler, at det er sikkert at angribe slottet. Macil har sørget for, at Irale giver dig guld og noget træning. Når du har besøgt ham, skal du gå til lægen i byen for at få styrke.","Eine weitere Aufgabe noch, bevor Macil es für sicher hält, die Burg anzugreifen. Macil hat Irale gebeten, dir Gold zu geben und Training zu organisieren. Nachdem du bei ihm warst, lass dir vom Sanitäter in der Stadt deine Ausdauer erhöhen.",,,"Una aventura más antes de que el comando sienta que es seguro atacar el castillo. Macil ha acordado con Irale que te dé oro y algo de entrenamiento. Después de visitarlo, ve al médico en el pueblo para ganar fuerza.",,"Vielä yksi seikkailu, ennen kuin komentokeskus katsoo tilanteen hyväksi hyökätä linnaa vastaan. Macil on järjestänyt Iralen antamaan sinulle kultaa ja koulutusta. Kun olet tavannut häntä, tapaa kaupungilla lääkintämiestä vahvistusta varten.","Encore une aventure avant que le commandement ne pense qu'il soit bon temps d'attaquer le château. Macil s'est arrangé pour qu'Irale te donne de l'argent et qu'il t'entraîne. Une fois que tu en as fini avec lui, va visiter le médecin en ville pour qu'il te rende des forces.","Még egy kaland, mielőtt az irányítás hatékony támadást indíthat a kastély ellen. Macil elintézte, hogy Irale ellásson arannyal és kiképzéssel. Utána keresd fel a szanitécet, hogy kicsit kipofozzon.","Un'ultima avventura prima dell'assedio al castello. Macil ha parlato ad Irale per farti avere dell'oro e un pò di addestramento. Dopo che gli hai fatto visita, parla anche dal medico in città per una marcia in più.","もう一つの任務をこなす前に戦力の増強が必要と考えられる。 マシルがイラールを介して資金と訓練の手配をしてくれるので会いなさい。 -それと近所のメディックも支援してくれるわ。",본부가 공성전을 진행하기 전에 한 가지 해야 할 일이 있어. 마실이 이롤리에게 골드랑 훈련을 제공해달라고 부탁했대. 그리고 마을 병원에 가서 근력을 키워달라고 해.,"Nog een avontuur voor het commando het gevoel heeft dat het veilig is om het kasteel aan te vallen. Macil heeft geregeld dat Irale je goud en wat training geeft. Nadat je hem hebt bezocht, ga je naar de dokter in de stad voor kracht.","Ett eventyr til før kommandoen mener det er trygt å angripe slottet. Macil har sørget for at Irale gir deg gull og litt trening. Etter at du har besøkt ham, gå til legen i byen for å få styrke.","Jeszcze jedna przygoda, zanim dowództwo uzna, że można bezpiecznie zaatakować zamek. Macil umówił się z Irale, że da ci złoto i trochę treningu. Po wizycie u niego, udaj się do medyka w mieście po siłę.","Mais uma aventura antes que o comando ache que é seguro o bastante para atacar o castelo. Macil instruiu Irale a te passar ouro e treinamento. Após visitá-lo, vá ao médico para te dar uma força.",,"Încă o aventură până ce comanda e încrezătoare în atacarea castelului. Macil a aranjat ca Irale să îți ofere bani și antrenament. Dupa ce îț vizitezi, mergi la medicul din oraș pentru forță.","Ещё одно приключение, и штаб будет уверен в успешности атаки на замок. Мэйсил поручил Ирэйлу выплатить тебе награду и дать пару уроков. После встречи с ним, посети городского медика.",,"Komutanlık kaleye saldırmanın güvenli olduğunu düşünmeden önce bir macera daha. Macil, İrale'nin sana altın ve biraz eğitim vermesini ayarladı. Onu ziyaret ettikten sonra, güç için kasabadaki doktoru gör." +それと近所のメディックも支援してくれるわ。",본부가 공성전을 진행하기 전에 한 가지 해야 할 일이 있어. 마실이 이롤리에게 골드랑 훈련을 제공해달라고 부탁했대. 그리고 마을 병원에 가서 근력을 키워달라고 해.,"Nog een avontuur voor het commando het gevoel heeft dat het veilig is om het kasteel aan te vallen. Macil heeft geregeld dat Irale je goud en wat training geeft. Nadat je hem hebt bezocht, ga je naar de dokter in de stad voor kracht.","Ett eventyr til før kommandoen mener det er trygt å angripe slottet. Macil har sørget for at Irale gir deg gull og litt trening. Etter at du har besøkt ham, gå til legen i byen for å få styrke.","Jeszcze jedna przygoda, zanim dowództwo uzna, że można bezpiecznie zaatakować zamek. Macil umówił się z Irale, że da ci złoto i trochę treningu. Po wizycie u niego, udaj się do medyka w mieście po siłę.","Mais uma aventura antes que o comando ache que é seguro o bastante para atacar o castelo. Macil instruiu Irale a te passar ouro e treinamento. Após visitá-lo, vá ao médico para te dar uma força.",,"Încă o aventură până ce comanda e încrezătoare în atacarea castelului. Macil a aranjat ca Irale să îți ofere bani și antrenament. Dupa ce îț vizitezi, mergi la medicul din oraș pentru forță.","Ещё одно приключение, и штаб будет уверен в успешности атаки на замок. Мэйсил поручил Ирэйлу выплатить тебе награду и дать пару уроков. После встречи с ним, посети городского медика.",,Ett äventyr till innan kommandot känner att det är säkert att attackera slottet. Macil har ordnat så att Irale ger dig guld och lite träning. Efter att du besökt honom ska du gå till läkaren i staden för att få styrka.,"Komutanlık kaleye saldırmanın güvenli olduğunu düşünmeden önce bir macera daha. Macil, İrale'nin sana altın ve biraz eğitim vermesini ayarladı. Onu ziyaret ettikten sonra, güç için kasabadaki doktoru gör." "Visit Irale and the medic in town for gold and training, then find the sewers. Head along the river across from the Governor's mansion.",TXT_ILOG26,〃,,,"Navštiv Iraleho a doktora pro zlato a trénink, pak najdi stoky. Jdi podél řeky naproti guvernérově sídlu.","Besøg Irale og lægen i byen for at få guld og træning, og find derefter kloakkerne. Gå langs floden over for guvernørens palæ.","Geh zu Irale und dem Sanitäter in der Stadt, um etwas Gold und Training zu bekommen, dann finde die Kanalisation. Folge dem Fluss auf der gegenüberliegenden Seite der Villa des Gouverneurs.",,,"Visita a Irale y al médico en el pueblo para oro y entrenamiento, luego encuentra las alcantarillas. Dirígete a través del río junto a la mansión del gobernador.",,"Tapaa Iralea ja lääkintämiestä kaupungilla kultaa ja koulutusta varten, minkä jälkeen löydä viemärit. Kulje joen vartta kuvernöörin kartanoa vastapäätä.","Visite Irale et le médecin en ville pour de l'argent et de l'entraînement, puis trouve l'entrée des égouts. Descend le long de la rivière de l'autre côté du manoir du gouverneur.","Keresd fel Iralet és a szanitécet a városban egy kis aranyért és kiképzésért, aztán irány a kanáris. Menj a folyón ami átszeli a kormányzó kúriáját.","Visita Irale e il medico in città per oro e addestramento, dopodiché trova le fogne. Vi puoi accedere dal fiume vicino alla dimora del governatore.","イラールとメディックを尋ねて資金と訓練を受け、下水道に向かうんだ。 -入り口は知事のマンションの川を挟んだ向かい側だ。","이롤리와 마을 의무관에게 가서 골드와 훈련을 받고, 하수구를 찾아. 총독의 관저 건너편의 강을 따라서 가봐.","Bezoek Irale en de dokter in de stad voor goud en training, en zoek dan de riolen. Loop langs de rivier tegenover het landhuis van de gouverneur.","Besøk Irale og legen i byen for gull og trening, og finn deretter kloakken. Gå langs elven overfor guvernørens hus.","Odwiedź Irale i medyka w mieście po złoto i trening, a następnie znajdź kanały. Skieruj się wzdłuż rzeki naprzeciwko rezydencji gubernatora.",Visite o Irale e o médico na cidade para ouro e treinamento. Depois encontre o esgoto. Vá para o rio do outro lado da mansão do Governador.,,"Vizitează pe Irale și medicul din oraș pentru aur și antrenament, apoi găsește canalele. Urmează râul de lângă complexul Guvernatorului.","Зайди к Ирэйлу и городскому медику за золотом и обучением, потом спустись в канализацию. Иди вдоль берега реки, спуск прямо напротив особняка губернатора.",,"Altın ve eğitim için İrale'yi ve kasabadaki doktoru ziyaret edin, ardından kanalizasyonları bulun. Valinin konağının karşısındaki nehir boyunca ilerleyin." +入り口は知事のマンションの川を挟んだ向かい側だ。","이롤리와 마을 의무관에게 가서 골드와 훈련을 받고, 하수구를 찾아. 총독의 관저 건너편의 강을 따라서 가봐.","Bezoek Irale en de dokter in de stad voor goud en training, en zoek dan de riolen. Loop langs de rivier tegenover het landhuis van de gouverneur.","Besøk Irale og legen i byen for gull og trening, og finn deretter kloakken. Gå langs elven overfor guvernørens hus.","Odwiedź Irale i medyka w mieście po złoto i trening, a następnie znajdź kanały. Skieruj się wzdłuż rzeki naprzeciwko rezydencji gubernatora.",Visite o Irale e o médico na cidade para ouro e treinamento. Depois encontre o esgoto. Vá para o rio do outro lado da mansão do Governador.,,"Vizitează pe Irale și medicul din oraș pentru aur și antrenament, apoi găsește canalele. Urmează râul de lângă complexul Guvernatorului.","Зайди к Ирэйлу и городскому медику за золотом и обучением, потом спустись в канализацию. Иди вдоль берега реки, спуск прямо напротив особняка губернатора.",,Besök Irale och läkaren i staden för att få guld och träning och hitta sedan kloakerna. Gå längs floden mittemot guvernörens herrgård.,"Altın ve eğitim için İrale'yi ve kasabadaki doktoru ziyaret edin, ardından kanalizasyonları bulun. Valinin konağının karşısındaki nehir boyunca ilerleyin." "We're looking for Weran, who calls himself the Rat King. I'm sure it's descriptive as well as colorful.",TXT_ILOG28,MAP06: Entrance.,,,"Hledáma Werana, který si říká Krysí král. Jsem si jistá, že to je jak barvité, tak přesné.","Vi leder efter Weran, som kalder sig selv Rottekongen. Det er sikkert både beskrivende og farverigt.","Wir suchen Weran, den man auch den Rattenkönig nennt. Ich bin sicher, dass dies ihn sehr anschaulich beschreibt.",,,"Estamos buscando a Weran, quien se autoproclama el Rey de las Ratas. Estoy segura de que es tanto descriptivo como vistoso.",,"Etsimme Werania, joka kutsuu itseään Rottakuninkaaksi. Varmastikin kuvaava titteli, mutta myös väritetty.","Cherche Weran, il se fait appeler le Roi des Rats. Je suis sur que c'est aussi descriptif que flatteur.","Werant keressük, aki magát csak a Patkány Királyként emlegeti. Biztos vagyok, hogy nem csak színes név, de valszeg hasonlít is hozzá.","Stiamo cercando Weran, che si fa chiamare il Re dei Ratti. Sono sicura che lo descrive appieno.","誰が呼んだかラットキングのウェランを探すんだ。 -それが叙述的でもあり派手な呼び名なのも定かだ。",우리는 자신을 시궁쥐 왕이라고 부르는 워렌을 찾아야 해. 알록달록해서 눈에 잘 띌 것 같은데 말이야.,"We zijn op zoek naar Weran, die zichzelf de rattenkoning noemt. Ik weet zeker dat het zowel beschrijvend als kleurrijk is.","Vi leter etter Weran, som kaller seg Rottekongen. Det er sikkert både beskrivende og fargerikt.","Szukamy Werana, który nazywa siebie Królem Szczurów. Na pewno jest to opisowe, jak i barwne.","Estamos procurando pelo Weran, que se autodenomina o Rato Rei. Imagino que isso seja tão descritivo quanto gracioso.",,"Îl căutam pe Weran, care ăși spune Regele Șobolanilor. Sunt sigur că e descriptiv și colorat.","Нам нужен Уэран — он называет себя Крысиным королём. Уверена, прозвище так же емко, как и красочно.",,Kendisine Fare Kral diyen Weran'ı arıyoruz. Renkli olduğu kadar açıklayıcı da olduğuna eminim. +それが叙述的でもあり派手な呼び名なのも定かだ。",우리는 자신을 시궁쥐 왕이라고 부르는 워렌을 찾아야 해. 알록달록해서 눈에 잘 띌 것 같은데 말이야.,"We zijn op zoek naar Weran, die zichzelf de rattenkoning noemt. Ik weet zeker dat het zowel beschrijvend als kleurrijk is.","Vi leter etter Weran, som kaller seg Rottekongen. Det er sikkert både beskrivende og fargerikt.","Szukamy Werana, który nazywa siebie Królem Szczurów. Na pewno jest to opisowe, jak i barwne.","Estamos procurando pelo Weran, que se autodenomina o Rato Rei. Imagino que isso seja tão descritivo quanto gracioso.",,"Îl căutam pe Weran, care ăși spune Regele Șobolanilor. Sunt sigur că e descriptiv și colorat.","Нам нужен Уэран — он называет себя Крысиным королём. Уверена, прозвище так же емко, как и красочно.",,Vi letar efter Weran som kallar sig för råttkungen. Jag är säker på att det är både beskrivande och färgstarkt.,Kendisine Fare Kral diyen Weran'ı arıyoruz. Renkli olduğu kadar açıklayıcı da olduğuna eminim. "Take the flamethrower parts to Irale. Drain the reclamation tank. At the bottom is a hidden entrance to the sewers. The gate controls are down there, somewhere. Destroy them.",TXT_ILOG33,MAP06: After giving the guard's uniform to Weran.,,,Vezmi části plamenometu k Iralemu. Vypusť obnovovací nádrž. Na dně je skrytý vchod do stok. Někde tam je ovládání bran. Znič jej.,Tag flammekasterdelene med til Irale. Tøm genvindingstanken. I bunden er der en skjult indgang til kloakkerne. Kontrolelementerne til porten er dernede et sted. Ødelæg dem.,Bringe dir Flammenwerferteile zu Irale. Leere den Sammeltank. Am Boden ist ein versteckter Eingang zur Kanalisation. Dort ist die Steuerung für die Tore. Zerstöre sie.,,,"Llévale las partes de lanzallamas a Irale. Drena el tanque de recuperación del castillo: al fondo hay una entrada secreta a las alcantarillas. Los controles de la puerta están por ahí, en algún lugar. Destrúyelos.",,Toimita liekinheittimen osat Iralelle. Tyhjennä nesteentalteenottoallas. Sen pohjalla on viemärin salainen sisäänkäynti. Portin ohjaimet sijaitsevat jossakin siellä. Tuhoa ne.,Amène les pièces du lance-flamme à Irale. Fais vider le réservoir de recyclage. Au fond se trouve une entrée cachée vers les égouts. Les contrôles de la porte s'y trouvent. Détruis-les.,Vidd a lángszóró darabokat Iralehez. Ereszd le a szárító tartályt. Az alján megtalálod a titkos lejáratot a kanárisba. A kapu vezérlése ott van lent valahol. Semmisítsd meg őket.,"Porta i pezzi del lanciafiamme da Irale. Svuota la vasca di recupero fluidi. Nel fondo c'è un'entrata nascosta per le fogne. I controlli dei cancelli sono laggiù, da qualche parte. Distruggili.","火炎放射器の部品をイラールに持っていく。 浄化タンクを排水せよ。その下層に下水道への隠された入り口がある。 -ゲートコントロールを探し出し、破壊せよ。",이 화염방사기 부품을 가지고 이롤리에게 말 걸어봐. 수조에 있는 물을 비우면 밑에 하수도로 향하는 비밀 입구가 보일 거야. 성문의 관리 장치가 여기 어딘가에 있을 거야. 찾으면 파괴해.,"Neem de vlammenwerperonderdelen mee naar Irale. Laat de terugwinnings tank leeglopen. Onderaan is een verborgen ingang naar de riolering. De poortbediening is daar beneden, ergens. Vernietig ze.","Ta flammekasterdelene til Irale. Tøm utvinningstanken. Nederst er det en skjult inngang til kloakken. Portkontrollene er der nede, et sted. Ødelegg dem.",Zabierz części miotacza ognia do Irale. Opróżnij zbiornik rekultywacyjny. Na dole jest ukryte wejście do kanałów. Sterowniki bramy są gdzieś tam na dole. Zniszcz je.,Leve as peças do lança-chamas ao Irale. Drene o tanque de recuperação. No fundo há uma entrada oculta para o esgoto. Os controles do portão estão lá embaixo em algum lugar. Destrua-os.,,"Du bucățiile aruncătorului la Irale. Drenează rezervorul recuperării. La fund e o intrare secretă către canale. Controlul porții e jos, undeva. Distruge-l.","Отнеси детали огнемёта Ирэйлу. Слей жидкость из бака для переработки. На его дне скрытый вход в канализацию. Механизм управления воротами где-то там, внизу. Сломай его.",,Alev makinesi parçalarını İrale'ye götür. Islah tankını boşaltın. En altta kanalizasyona gizli bir giriş var. Kapı kontrolleri aşağıda bir yerde. Onları yok et. +ゲートコントロールを探し出し、破壊せよ。",이 화염방사기 부품을 가지고 이롤리에게 말 걸어봐. 수조에 있는 물을 비우면 밑에 하수도로 향하는 비밀 입구가 보일 거야. 성문의 관리 장치가 여기 어딘가에 있을 거야. 찾으면 파괴해.,"Neem de vlammenwerperonderdelen mee naar Irale. Laat de terugwinnings tank leeglopen. Onderaan is een verborgen ingang naar de riolering. De poortbediening is daar beneden, ergens. Vernietig ze.","Ta flammekasterdelene til Irale. Tøm utvinningstanken. Nederst er det en skjult inngang til kloakken. Portkontrollene er der nede, et sted. Ødelegg dem.",Zabierz części miotacza ognia do Irale. Opróżnij zbiornik rekultywacyjny. Na dole jest ukryte wejście do kanałów. Sterowniki bramy są gdzieś tam na dole. Zniszcz je.,Leve as peças do lança-chamas ao Irale. Drene o tanque de recuperação. No fundo há uma entrada oculta para o esgoto. Os controles do portão estão lá embaixo em algum lugar. Destrua-os.,,"Du bucățiile aruncătorului la Irale. Drenează rezervorul recuperării. La fund e o intrare secretă către canale. Controlul porții e jos, undeva. Distruge-l.","Отнеси детали огнемёта Ирэйлу. Слей жидкость из бака для переработки. На его дне скрытый вход в канализацию. Механизм управления воротами где-то там, внизу. Сломай его.",,Ta med dig flamethrowerdelarna till Irale. Töm återvinningstanken. I botten finns en dold ingång till kloakerna. Grindkontrollerna finns där nere någonstans. Förstör dem.,Alev makinesi parçalarını İrale'ye götür. Islah tankını boşaltın. En altta kanalizasyona gizli bir giriş var. Kapı kontrolleri aşağıda bir yerde. Onları yok et. "Command, he's done it! The gates are open. Send in the shock troops and tell Macil we're coming in! Let's get back to the Front base.",TXT_ILOG37,MAP06: After destroying the gate controls.,,,"Velení, dokázal to! Brány jsou otevřené. Pošlete tam úderníky a řekněte Macilovi, že přicházíme! Vrať se na základnu Fronty.","Kommando, han har gjort det! Portene er åbne. Send choktropperne ind og fortæl Macil, at vi kommer ind! Lad os komme tilbage til frontbasen.",Kommandozentrale: Er hat's geschafft! Die Tore sind offen. Schickt die Schocktruppen hinein und sagt Macil das wir auf dem Weg sind! Lass uns zur Frontbasis zurückkehren.,,,"¡Comando, lo ha conseguido! Las puertas ya están abiertas. ¡Enviad a las tropas de choque y decidle a Macil que ya es hora de entrar! Volvamos a la base del Frente.","Comando, ¡Lo ha hecho! Las puertas están abiertas. ¡Envíen las tropas de choque y díganel a Macil que estamos entrando! Regresemos a la base del Frente.","Komentokeskus, hän teki sen! Portit ovat auki; lähettäkää iskujoukot ja kertokaa Macilille, että vyörymme sisään! Palataan Rintaman tukikohtaan.","C'est bon, commandement, il a réussi! Les portes sont ouvertes, envoyez les soldats de choc et dites à Macil que l'on arrive! Retournons à la base du Front.","Irányítás, megcsinálta! A kpuk kinyíltak. Küldjétek be az elektromos egységeket, és értesítsd Macilt hogy jövünk! Irány vissza a homlokfronthoz.","Comando, ce l'ha fatta! I cancelli sono aperti. Mandate avanti le truppe e dite a Macil che stiamo arrivando! Torniamo alla base del Fronte.","司令官、彼はやったぞ! -ゲートが開いた。突撃部隊を送って我々も続くとマシルに伝えてくれ!",본부! 그가 해냈습니다! 성문이 열렸습니다. 공습부대를 성문으로 이동시키고 사령관님께 우리들도 따라올 거라고 전해주세요. 이제 프론트 기지로 돌아가!,"Commando, hij heeft het gedaan! De poorten zijn open. Stuur de stoottroepen naar binnen en zeg Macil dat we binnenkomen! Laten we teruggaan naar de voorste basis.","Kommando, han har klart det! Portene er åpne. Send inn sjokktroppene og si til Macil at vi kommer inn! La oss dra tilbake til frontbasen.","Dowództwo, udało mu się! Wrota są otwarte. Wyślij oddziały uderzeniowe i powiedz Macilowi, że wchodzimy! Wracajmy do bazy frontowej.","Comando, ele conseguiu! Os portões estão abertos. Mande as tropas de choque e diga ao Macil que estamos entrando! Vamos voltar pra base da Frente.",,"Comandă, a reușit! Porțile sunt deschise. Trimite trupele de șoc și spune-i lui Macil că intrăm! Să ne întoarcem la baza Frontului.","Штаб, он выполнил задание! Ворота открыты. Посылайте ударный отряд и доложите Мэйсилу, что мы пробились! Возвращайся на базу Сопротивления.",,"Komuta, başardı! Kapılar açıldı. Şok birliklerini gönderin ve Macil'e geldiğimizi söyleyin! Cephe üssüne geri dönelim." +ゲートが開いた。突撃部隊を送って我々も続くとマシルに伝えてくれ!",본부! 그가 해냈습니다! 성문이 열렸습니다. 공습부대를 성문으로 이동시키고 사령관님께 우리들도 따라올 거라고 전해주세요. 이제 프론트 기지로 돌아가!,"Commando, hij heeft het gedaan! De poorten zijn open. Stuur de stoottroepen naar binnen en zeg Macil dat we binnenkomen! Laten we teruggaan naar de voorste basis.","Kommando, han har klart det! Portene er åpne. Send inn sjokktroppene og si til Macil at vi kommer inn! La oss dra tilbake til frontbasen.","Dowództwo, udało mu się! Wrota są otwarte. Wyślij oddziały uderzeniowe i powiedz Macilowi, że wchodzimy! Wracajmy do bazy frontowej.","Comando, ele conseguiu! Os portões estão abertos. Mande as tropas de choque e diga ao Macil que estamos entrando! Vamos voltar pra base da Frente.",,"Comandă, a reușit! Porțile sunt deschise. Trimite trupele de șoc și spune-i lui Macil că intrăm! Să ne întoarcem la baza Frontului.","Штаб, он выполнил задание! Ворота открыты. Посылайте ударный отряд и доложите Мэйсилу, что мы пробились! Возвращайся на базу Сопротивления.",,"Kommando, han har gjort det! Portarna är öppna. Skicka in chocktrupperna och säg till Macil att vi kommer in! Låt oss återvända till Frontbasen.","Komuta, başardı! Kapılar açıldı. Şok birliklerini gönderin ve Macil'e geldiğimizi söyleyin! Cephe üssüne geri dönelim." "Join the assault on the castle. Find and take out the Programmer. We have conflicting reports about his location. One says he in a computer room, another hiding in a sub-level temple, and yet another at the end of a long hallway.",TXT_ILOG38,MAP03: After destroying the gate controls and talking to Macil.,,,"Připoj se k útoku na hrad. Najdi a zabij Programátora. Informace o jeho pozici se různí. Jedna mluví o místnosti s počítači, druhá o podzemním chrámu a třetí o konci dlouhé chodby.","Deltag i angrebet på slottet. Find og udslæt programmøren. Vi har modstridende rapporter om hans placering. En siger, at han er i et computerrum, en anden, at han gemmer sig i et tempel på et underliggende niveau, og endnu en anden for enden af en lang korridor.","Schließe dich dem Angriff auf die Burg an. Finde den Programmierer und schalte ihn aus. Wir haben widersprüchliche Angaben über seinen Aufenthaltsort. Eine sagt, in einem Computerraum, ein anderer, dass er sich in einem Tempelkeller versteckt und noch ein anderer sagt was vom Ende eines langen Flurs.",,,"Únete al asalto en el castillo. Encuentra y elimina al Programador. Tenemos informes contradictorios sobre su ubicación. Uno dice que está en una sala de computadoras, otro que se esconde en un templo en el subnivel, y también otro que al final de un largo pasillo.",,"Osallistu hyökkäykseen linnaa vastaan. Etsi ja kukista Ohjelmoitsija. Meillä on hänen sijainnistaan eriäviä tietoja: Yhden mukaan hän on tietokonehuoneessa, toisen mukaan maanalaisessa temppelissä ja vielä kolmannen mukaan pitkän käytävän päässä.","Rejoins l'assaut sur le château. Trouve et élimine le Programmeur. On a des rapports en conflit sur sa position. L'un d'entre eux nous dit qu'il se trouve dans la salle des ordinateurs, l'autre nous dit qu'il se cache dans un temple en sous sol, et un autre encore au bout d'un long couloir.","Csatlakozz a kastély ostromához. Keresd meg és iktasd ki a Programozót. Ellentmondó információink vannak a hollétéről. Az egyik szerint a számítógép szobában van, másik szerint egy föld alatti templomban, harmadik szerint egy hosszú folyosó végén.","Unisciti all'assalto sul castello. Trova e fai fuori il Programmatore. I rapporti che abbiamo sulla sua posizione si contraddicono. Uno lo piazza in una stanza di computer, un altro in un tempio di sottolivello, e un altro ancora alla fine di un lungo corridoio.","城に向かう突撃部隊に参加してプログラマーを探し出せ。 プログラマーの居場所について矛盾する報告もある。 ある人はコンピューター室にいる、別の人は保管室にいる、 -また別の人は長い廊下にいるとも言っていた。","성을 공략할 공성전에 참여해. 침투해서 프로그래머를 죽일 수 있게. 그의 장소와 관련된 보고들이 뭔가 혼란스러운데, 컴퓨터실에 있다고 하고, 낮은 층 신전에 숨어 있다고 하고, 다른 한 명은 긴 복도 맨 끝에 서 있대.","Doe mee aan de aanval op het kasteel. Zoek en schakel de Programmeur uit. We hebben tegenstrijdige berichten over zijn locatie. De ene zegt dat hij in een computerkamer zit, de andere verstopt zich in een tempel op subniveau, en nog een andere aan het einde van een lange gang.","Bli med på angrepet på slottet. Finn og drep programmereren. Vi har motstridende rapporter om hvor han befinner seg. En sier at han er i et datarom, en annen at han gjemmer seg i et underjordisk tempel, og en tredje at han er i enden av en lang gang.","Dołącz do szturmu na zamek. Znajdźcie i zlikwidujcie Programistę. Mamy sprzeczne raporty na temat jego lokalizacji. Jeden mówi, że w sali komputerowej, inny, że ukrywa się w podpoziomowej świątyni, a jeszcze inny, że na końcu długiego korytarza.","Junte-se ao ataque no castelo. Ache e elimine o Programador. Temos relatos conflitantes sobre onde ele se encontra. Um deles diz que ele está na sala de informática, outro que ele está escondido num templo no subsolo e mais outro diz que ele está no fim de um longo corredor.",,"Alăturăte asaltului asupra castelului. Găsește-l și elimină-l pe Programator. Avem rapoarte diferite în ceea ce privește locația lui. Unul spune că e într-o sală de calculatoare, iar altul că se ascunde într-un subnivel al templului, și încă unul care spune că e în capătul unui coridor lung.","Присоединись к атаке на замок. Найди и уничтожь Программиста. Наши сведения о его местонахождении противоречивы. Одни говорят, что он в компьютерной комнате, другие — что он укрывается в подземном храме, а третьи — что он в конце длинного коридора.",,"Kaleye yapılan saldırıya katılın. Programcıyı bulup çıkarın. Yeri hakkında çelişkili raporlarımız var. Biri bilgisayar odasında, diğeri alt kattaki bir tapınakta, bir başkası da uzun bir koridorun sonunda saklandığını söylüyor." -Find the Programmer and kill him.,TXT_ILOG45,MAP09: Entrance.,,,Najdi Programátora a zabij ho.,Find programmøren og dræb ham.,Finde den Programmierer und töte ihn.,,,Encuentra al Programador y mátalo.,,Etsi ja tapa Ohjelmoitsija.,Trouve le Programmeur et tue-le.,Keresd meg a Programozót és öld meg.,Trova il Programmatore e fallo fuori.,プログラマーを見つけて殺せ。,프로그래머를 찾아서 죽여.,Zoek de Programmeur en vermoord hem.,Finn programmereren og drep ham.,Znajdź Programistę i zabij go.,Encontre o Programador e mate-o.,,Găsește Programatorul și ucide-l.,Найди Программиста и убей его.,,Programcıyı bulun ve öldürün. +また別の人は長い廊下にいるとも言っていた。","성을 공략할 공성전에 참여해. 침투해서 프로그래머를 죽일 수 있게. 그의 장소와 관련된 보고들이 뭔가 혼란스러운데, 컴퓨터실에 있다고 하고, 낮은 층 신전에 숨어 있다고 하고, 다른 한 명은 긴 복도 맨 끝에 서 있대.","Doe mee aan de aanval op het kasteel. Zoek en schakel de Programmeur uit. We hebben tegenstrijdige berichten over zijn locatie. De ene zegt dat hij in een computerkamer zit, de andere verstopt zich in een tempel op subniveau, en nog een andere aan het einde van een lange gang.","Bli med på angrepet på slottet. Finn og drep programmereren. Vi har motstridende rapporter om hvor han befinner seg. En sier at han er i et datarom, en annen at han gjemmer seg i et underjordisk tempel, og en tredje at han er i enden av en lang gang.","Dołącz do szturmu na zamek. Znajdźcie i zlikwidujcie Programistę. Mamy sprzeczne raporty na temat jego lokalizacji. Jeden mówi, że w sali komputerowej, inny, że ukrywa się w podpoziomowej świątyni, a jeszcze inny, że na końcu długiego korytarza.","Junte-se ao ataque no castelo. Ache e elimine o Programador. Temos relatos conflitantes sobre onde ele se encontra. Um deles diz que ele está na sala de informática, outro que ele está escondido num templo no subsolo e mais outro diz que ele está no fim de um longo corredor.",,"Alăturăte asaltului asupra castelului. Găsește-l și elimină-l pe Programator. Avem rapoarte diferite în ceea ce privește locația lui. Unul spune că e într-o sală de calculatoare, iar altul că se ascunde într-un subnivel al templului, și încă unul care spune că e în capătul unui coridor lung.","Присоединись к атаке на замок. Найди и уничтожь Программиста. Наши сведения о его местонахождении противоречивы. Одни говорят, что он в компьютерной комнате, другие — что он укрывается в подземном храме, а третьи — что он в конце длинного коридора.",,"Gå med i anfallet mot slottet. Hitta och ta ut programmeraren. Vi har motstridiga rapporter om var han befinner sig. En säger att han befinner sig i ett datorrum, en annan gömmer sig i ett tempel på en underliggande nivå och ytterligare en annan i slutet av en lång korridor.","Kaleye yapılan saldırıya katılın. Programcıyı bulup çıkarın. Yeri hakkında çelişkili raporlarımız var. Biri bilgisayar odasında, diğeri alt kattaki bir tapınakta, bir başkası da uzun bir koridorun sonunda saklandığını söylüyor." +Find the Programmer and kill him.,TXT_ILOG45,MAP09: Entrance.,,,Najdi Programátora a zabij ho.,Find programmøren og dræb ham.,Finde den Programmierer und töte ihn.,,,Encuentra al Programador y mátalo.,,Etsi ja tapa Ohjelmoitsija.,Trouve le Programmeur et tue-le.,Keresd meg a Programozót és öld meg.,Trova il Programmatore e fallo fuori.,プログラマーを見つけて殺せ。,프로그래머를 찾아서 죽여.,Zoek de Programmeur en vermoord hem.,Finn programmereren og drep ham.,Znajdź Programistę i zabij go.,Encontre o Programador e mate-o.,,Găsește Programatorul și ucide-l.,Найди Программиста и убей его.,,Hitta programmeraren och döda honom.,Programcıyı bulun ve öldürün. "Seek out the Oracle and ask it about the other Sigil pieces. The Oracle resides in the borderlands, just outside of town. Cross the river, head towards the castle and go left through the archway.",TXT_ILOG46,,,,"Najdi Věštce a zeptej se ho na ostatní díly Pečetě. Věštec přebývá v pohraničí, hned za městem. Překroč řeku, zamiř k hradu a jdi vlevo pod obloukem.","Opsøg Oraklet og spørg det om de andre Sigil-stykker. Oraklet befinder sig i grænselandet, lige uden for byen. Kryds floden, gå mod slottet og gå til venstre gennem buegangen.","Suche das Orakel auf und befrage es bezüglich der anderen Teile des Sigils. Das Orakel ist in den Grenzgebieten zu finden, außerhalb der Stadt. Überquere den Fluss, gehe zur Burg und dann links durch das Tor.",,,"Busca al Oráculo y pregúntale sobre las otras piezas del Emblema. El Oráculo reside en las fronteras, justo fuera del pueblo. Cruza el río, dirígete hacia el castillo y gira a la izquierda a través del arco.","Busca al Oráculo y pregúntale acerca de las otras piezas del Emblema. El Oráculo reside en las fronteras, en las afueras de la ciudad. Cruza el río, dirígete hacia el castillo y gira a la izquierda a través del arco.","Etsi Oraakkeli ja kysy häneltä muista Sinetin osista. Oraakkeli asuu rajamailla aivan kaupungin liepeillä. Ylitä joki, kulje kohti linnaa ja mene vasemmalle kaarikäytävän läpi.","Trouve l'Oracle et demande lui où se trouvent les autres pièces du Sigil. L'Oracle se trouve dans les terrains vagues à l'extérieur de la ville. Traverse la rivière, va vers le château puis à gauche après l'arche.","Keresd fel az Orákulumot, és kérdezd ki a többi pecsét darabról. Az Orákulum a peremvidéken lakik, rögtön a város után. Elhagyva a folyót, vedd az utad a kastély felé, és balra a boltíves folyosónál.","Raggiungi l'Oracolo e chiedigli degli altri pezzi del Sigillo. L'Oracolo risiede nelle terre di confine, subito dopo la città. Attraversa il fiume, vai nella direzione del castello e poi a sinistra oltre l'arco.","オラクルに会いシジルの欠片の場所を尋ねろ。 オラクルは町外れの国境地帯にいる。 -川の向こうにある城を目指しアーチウェイを左に曲がるのだ。","오라클을 찾아서 다른 시질 조각이 어디에 있는지 물어봐. 오라클은 도시 외곽에 있는 접경지 근처에 있어. 강을 넘은 뒤, 성 쪽으로 향하고 아치 밑의 통로를 통해 왼쪽으로 이동해.","Zoek het Orakel op en vraag het over de andere Sigil stukken. Het Orakel woont in de grensgebieden, net buiten de stad. Steek de rivier over, loop naar het kasteel en ga linksaf door de poort.","Oppsøk Orakelet og spør det om de andre Sigil-brikkene. Oraklet holder til i grenselandet, like utenfor byen. Kryss elven, gå mot slottet og gå til venstre gjennom buegangen.","Poszukaj Wyroczni i zapytaj ją o pozostałe kawałki Sigila. Wyrocznia rezyduje na pograniczu, tuż za miastem. Przejdź przez rzekę, skieruj się w stronę zamku i przejdź w lewo przez łuki.","Procure pelo Oráculo e pergunte a ele sobre as outras peças do Sigilo. O Oráculo mora nas fronteiras, no lado de fora da cidade. Atravesse o rio, vá em direção ao castelo e vá pela esquerda através do arco.",,"Găsește Oracolul și întreabă-l de piesele Sigiliului. Oracolul are reședința în mărginime, chiar la ieșirea din oraș. Trece râul, du-te spre castel și ia-o la stânga prin arcadă.","Найди Оракула и спроси его про другие фрагменты Печати. Резиденция Оракула находится в пограничье, сразу за городской чертой. Пересеки реку, иди в сторону крепости и сверни налево, пройдя через арку.",,"Kahin'i bulun ve ona diğer Sigil parçalarını sorun. Kahin, şehrin hemen dışındaki sınır bölgelerinde bulunur. Nehri geçin, kaleye doğru gidin ve kemerden sola dönün." +川の向こうにある城を目指しアーチウェイを左に曲がるのだ。","오라클을 찾아서 다른 시질 조각이 어디에 있는지 물어봐. 오라클은 도시 외곽에 있는 접경지 근처에 있어. 강을 넘은 뒤, 성 쪽으로 향하고 아치 밑의 통로를 통해 왼쪽으로 이동해.","Zoek het Orakel op en vraag het over de andere Sigil stukken. Het Orakel woont in de grensgebieden, net buiten de stad. Steek de rivier over, loop naar het kasteel en ga linksaf door de poort.","Oppsøk Orakelet og spør det om de andre Sigil-brikkene. Oraklet holder til i grenselandet, like utenfor byen. Kryss elven, gå mot slottet og gå til venstre gjennom buegangen.","Poszukaj Wyroczni i zapytaj ją o pozostałe kawałki Sigila. Wyrocznia rezyduje na pograniczu, tuż za miastem. Przejdź przez rzekę, skieruj się w stronę zamku i przejdź w lewo przez łuki.","Procure pelo Oráculo e pergunte a ele sobre as outras peças do Sigilo. O Oráculo mora nas fronteiras, no lado de fora da cidade. Atravesse o rio, vá em direção ao castelo e vá pela esquerda através do arco.",,"Găsește Oracolul și întreabă-l de piesele Sigiliului. Oracolul are reședința în mărginime, chiar la ieșirea din oraș. Trece râul, du-te spre castel și ia-o la stânga prin arcadă.","Найди Оракула и спроси его про другие фрагменты Печати. Резиденция Оракула находится в пограничье, сразу за городской чертой. Пересеки реку, иди в сторону крепости и сверни налево, пройдя через арку.",,"Sök upp Oraklet och fråga det om de andra Sigilbitarna. Oraklet befinner sig i gränslandet, strax utanför staden. Korsa floden, gå mot slottet och gå till vänster genom valvet.","Kahin'i bulun ve ona diğer Sigil parçalarını sorun. Kahin, şehrin hemen dışındaki sınır bölgelerinde bulunur. Nehri geçin, kaleye doğru gidin ve kemerden sola dönün." "Seek out the Oracle and ask it about the other Sigil pieces. The Oracle's temple is in the borderlands, on the outskirts of town.",TXT_ILOG47,,,,"Najdi Věštce a zeptej se ho na ostatní díly Pečetě. Věštcův chrám je v pohraničí, na okraji města.","Opsøg Oraklet og spørg det om de andre Sigil stykker. Oraklets tempel ligger i grænselandet, i udkanten af byen.","Suche das Orakel auf und befrage es bezüglich der anderen Teile des Sigils. Der Tempel des Orakels ist in den Grenzgebieten zu finden, in den Außenbezirken der Stadt.",,,Busca al Oráculo y pregúntale sobre las otras piezas del Emblema. El templo del Oráculo está en las fronteras en las afueras del pueblo.,,Etsi Oraakkeli ja kysy häneltä muista Sinetin osista. Oraakkelin temppeli sijaitsee rajaseudulla kaupungin laitamilla.,Trouve l'Oracle et demande lui où se trouvent les autres pièces du Sigil. Le temple de l'Oracle se trouve dans les terrains vagues à l'extérieur de la ville. ,"Keresd fel az Orákulumot, és kérdezd ki a többi pecsét darabról. Az Orákulum a peremvidéken lakik, rögtön a város után.","Raggiungi l'Oracolo e chiedigli degli altri pezzi del Sigillo. Il tempio dell'Oracolo è nelle terre di confine, fuori città.","オラクルに会いシジルの欠片の場所を尋ねろ。 -オラクルは町外れの国境地帯にいる。",오라클을 찾고 다른 시질 조각에 관해 물어봐. 오라클의 신전은 도시 외곽의 접경지 근처에 있어.,"Zoek het Orakel op en vraag het over de andere Sigil stukken. De tempel van het Orakel ligt in het grensgebied, aan de rand van de stad.","Oppsøk oraklet og spør det om de andre Sigil-brikkene. Orakelets tempel ligger i grenselandet, i utkanten av byen.","Odszukaj Wyrocznię i zapytaj ją o inne kawałki Sigila. Świątynia Wyroczni znajduje się na pograniczu, na obrzeżach miasta.","Procure pelo Oráculo e pergunte a ele sobre as outras peças do Sigilo. Seu tempo está nas fronteiras, no lado de fora da cidade.",,"Găsește Oracolul și întreabă-l de piesele Sigiliului. Oracolul are reședința în mărginime, la ieșirea din oraș.","Найди Оракула и спроси его про другие фрагменты Печати. Храм Оракула расположен в пограничье, на окраине города.",,"Kahin'i bul ve ona diğer Sigil parçalarını sor. Kahin'in tapınağı sınır bölgelerinde, şehrin eteklerinde." +オラクルは町外れの国境地帯にいる。",오라클을 찾고 다른 시질 조각에 관해 물어봐. 오라클의 신전은 도시 외곽의 접경지 근처에 있어.,"Zoek het Orakel op en vraag het over de andere Sigil stukken. De tempel van het Orakel ligt in het grensgebied, aan de rand van de stad.","Oppsøk oraklet og spør det om de andre Sigil-brikkene. Orakelets tempel ligger i grenselandet, i utkanten av byen.","Odszukaj Wyrocznię i zapytaj ją o inne kawałki Sigila. Świątynia Wyroczni znajduje się na pograniczu, na obrzeżach miasta.","Procure pelo Oráculo e pergunte a ele sobre as outras peças do Sigilo. Seu tempo está nas fronteiras, no lado de fora da cidade.",,"Găsește Oracolul și întreabă-l de piesele Sigiliului. Oracolul are reședința în mărginime, la ieșirea din oraș.","Найди Оракула и спроси его про другие фрагменты Печати. Храм Оракула расположен в пограничье, на окраине города.",,"Sök upp Oraklet och fråga det om de andra Sigilbitarna. Oraklets tempel ligger i gränslandet, i utkanten av staden.","Kahin'i bul ve ona diğer Sigil parçalarını sor. Kahin'in tapınağı sınır bölgelerinde, şehrin eteklerinde." "Seek out the Oracle and ask it about the other Sigil pieces. Take your reward and go across to the medic and weapons trainer for health and training. The Oracle's temple is in the borderlands, on the outskirts of town.",TXT_ILOG48,MAP10: After talking to Macil and moving a bit.,,,"Najdi Věštce a zeptej se ho na ostatní díly Pečetě. Převezmi si svou odměnu a navštiv zdravotníka a učitele střelby pro zdraví a výcvik. Věštcův chrám je v pohraničí, na okraji města.","Opsøg Oraklet og spørg det om de andre Sigilstykker. Tag din belønning og gå over til lægen og våbentræneren for at få sundhed og træning. Oraklets tempel ligger i grænselandet, i udkanten af byen.","Suche das Orakel auf und befrage es bezüglich der anderen Teile des Sigils. Nimm deine Belohnung und suche den Sanitäter und den Waffentrainer auf. Der Tempel des Orakels ist in den Grenzgebieten zu finden, in den Außenbezirken der Stadt.",,,"Busca al Oráculo y pregúntale sobre las otras piezas del Emblema. Toma tu recompensa, ve al médico y al entrenador de armas para salud y entrenamiento. El templo del Oráculo está en las fronteras en las afueras del pueblo.",,Etsi Oraakkeli ja kysy häneltä muista Sinetin osista. Kerää palkkiosi ja hakeudu lääkintämiehen ja asekouluttajan luo terveydenhoitoa ja koulutusta varten. Oraakkelin temppeli sijaitsee rajaseudulla kaupungin laitamilla.,Trouve l'Oracle et demande lui où se trouvent les autres pièces du Sigil. Va chercher ta récompense chez le médecin et le maître d'armes pour de la santé et de l'entraînement. Le temple de l'Oracle se trouve dans les terrains vagues à l'extérieur de la ville. ,"Keresd fel az Orákulumot, és kérdezd ki a többi pecsét darabról. Vedd fel a jutalmad, majd ugorj át a szanitéchez és kiképzőhöz. Az Orákulum temploma a peremvidéken található, a város külvárosában.","Raggiungi l'Oracolo e chiedigli degli altri pezzi del Sigillo. Prendi la tua ricompensa e visita il dottore e l'addestratore di armi. Il tempio dell'Oracolo è nelle terre di confine, fuori città.","オラクルに会いシジルの欠片の場所を尋ねろ。 メディックと武器トレーナーに会い訓練と体力を強化せよ。 -オラクルは町外れの国境地帯にいる。",오라클을 찾아서 다른 시질 조각이 어디에 있는지 물어봐. 보상을 받고 치료와 훈련을 위해 의무관과 무기 담당관에게로 가. 오라클은 도시 외곽에 있는 접경지 근처에 있어.,"Zoek het Orakel op en vraag het over de andere Sigil stukken. Pak je beloning en ga naar de dokter en wapentrainer voor gezondheid en training. De tempel van het Orakel staat in de grensgebieden, aan de rand van de stad.","Oppsøk oraklet og spør det om de andre Sigil-brikkene. Ta belønningen din og gå over til medisineren og våpentreneren for helse og trening. Orakelets tempel ligger i grenselandet, i utkanten av byen.","Poszukaj Wyroczni i zapytaj ją o inne kawałki Sigila. Weź nagrodę i udaj się do medyka i trenera broni po zdrowie i trening. Świątynia Wyroczni znajduje się na pograniczu, na obrzeżach miasta.","Procure pelo Oráculo e pergunte a ele sobre as outras peças do Sigilo. Pegue a sua recompensa e visite o médico e o treinador de armas para saúde e treinamento. O templo do Oráculo se encontra nas fronteiras, do lado de fora da cidade.",,Găsește Oracolul și întreabă-l de piesele Sigiliului. Ia-ți recompensa ți du-te la medic și antrenorul de arme. Templul Oracolului e în mărginimea orașului.,"Найди Оракула и спроси его про другие фрагменты Печати. Возьми свою награду и зайди к медику и инструктору по стрельбе. Храм Оракула находится в пограничье, на окраине города.",,"Kahin'i bul ve ona diğer Sigil parçalarını sor. Ödülünüzü alın ve sağlık ve eğitim için sıhhiyeciye ve silah eğitmenine gidin. Kahin'in tapınağı sınır bölgelerinde, kasabanın eteklerinde." +オラクルは町外れの国境地帯にいる。",오라클을 찾아서 다른 시질 조각이 어디에 있는지 물어봐. 보상을 받고 치료와 훈련을 위해 의무관과 무기 담당관에게로 가. 오라클은 도시 외곽에 있는 접경지 근처에 있어.,"Zoek het Orakel op en vraag het over de andere Sigil stukken. Pak je beloning en ga naar de dokter en wapentrainer voor gezondheid en training. De tempel van het Orakel staat in de grensgebieden, aan de rand van de stad.","Oppsøk oraklet og spør det om de andre Sigil-brikkene. Ta belønningen din og gå over til medisineren og våpentreneren for helse og trening. Orakelets tempel ligger i grenselandet, i utkanten av byen.","Poszukaj Wyroczni i zapytaj ją o inne kawałki Sigila. Weź nagrodę i udaj się do medyka i trenera broni po zdrowie i trening. Świątynia Wyroczni znajduje się na pograniczu, na obrzeżach miasta.","Procure pelo Oráculo e pergunte a ele sobre as outras peças do Sigilo. Pegue a sua recompensa e visite o médico e o treinador de armas para saúde e treinamento. O templo do Oráculo se encontra nas fronteiras, do lado de fora da cidade.",,Găsește Oracolul și întreabă-l de piesele Sigiliului. Ia-ți recompensa ți du-te la medic și antrenorul de arme. Templul Oracolului e în mărginimea orașului.,"Найди Оракула и спроси его про другие фрагменты Печати. Возьми свою награду и зайди к медику и инструктору по стрельбе. Храм Оракула находится в пограничье, на окраине города.",,"Sök upp Oraklet och fråga det om de andra Sigilbitarna. Ta din belöning och gå över till läkaren och vapentränaren för hälsa och träning. Oraklets tempel ligger i gränslandet, i utkanten av staden.","Kahin'i bul ve ona diğer Sigil parçalarını sor. Ödülünüzü alın ve sağlık ve eğitim için sıhhiyeciye ve silah eğitmenine gidin. Kahin'in tapınağı sınır bölgelerinde, kasabanın eteklerinde." Seek out the Oracle's temple and ask it about the other Sigil pieces. Here it is. I'm recording everything. It's not that I don't have faith that you'll survive. It's just that we can't let the Order control the Sigil.,TXT_ILOG50,MAP11: Entrance to cave.,,,"Najdi Věštce a zeptej se ho na ostatní díly Pečetě. Tady to je. Nahrávám všechno, ne že bych neměla důvěru v tvé přežití, ale prostě nemůžeme dovolit Řádu ovládat Pečeť.","Søg ud til Oraklets tempel og spørg det om de andre Sigil stykker. Her er det. Jeg optager alt. Det er ikke fordi jeg ikke tror på, at du vil overleve. Vi kan bare ikke lade Ordenen kontrollere Sigil.","Suche das Orakel auf und befrage es bezüglich der anderen Teile des Sigils. Ich protokolliere alles. Ich glaube zwar schon daran, dass du überleben wirst, aber wir können es halt nicht zulassen, dass der Orden das Sigil kontrolliert.",,,Busca al Oráculo y pregúntale sobre las otras piezas del Emblema. Aquí está. Lo estoy grabando todo. No es que no tenga fe en tu supervivencia. Es solo que no podemos dejar que la Orden controle el Emblema.,,"Etsi Oraakkeli ja kysy häneltä muista Sinetin osista. Tässä se on. Tallennan kaiken. Tässä ei ole kyse siitä, etteikö minulla olisi täysi luotto, että selviäisit. Emme vain voi antaa Veljeskunnan hallita Sinettiä.","Trouve l'Oracle et demande lui où se trouvent les autres pièces du Sigil. Le voilà. J'enregistre tout, ce n'est pas que je n'ai pas confiance en ta capacité de survie, c'est juste que je ne peux pas laisser l'Ordre contrôler le Sigil.","Keresd fel az Orákulumot a templomában, és kérdezd meg a pecsét többi darabjáról. Itt is van. Felveszek mindent. Nem mintha nem bíznék meg benned, csak nem akarom, hogy a Rend kezébe kerüljön a pecsét.",Raggiungi l'Oracolo e chiedigli degli altri pezzi del Sigillo. Ecco qua. Sto registrando tutto. Non è che non penso che sopravviverai. È solo che non possiamo lasciare che l'Ordine controlli il Sigillo.,"オラクルに会いシジルの欠片の場所を尋ねろ。 オラクルはこの場所にいる。私は全部記録している。 私は貴方が生き残る確証がないというわけではなく、 オーダーはシジルを操る事が出来ないというだけだ。 -","오라클의 신전을 찾아서 시질 조각이 어디에 있는지 물어봐. 그리고 지금 난 모든 걸 녹음하고 있어. 네가 살아남을 거라는 믿음을 버린게 아니라, 오더가 시질을 손에 잡게 내버려 둘 수가 없어서 말이야.",Zoek de tempel van het Orakel op en vraag het over de andere Sigil stukken. Hier is het. Ik ben alles aan het opnemen. Niet dat ik er niet op vertrouw dat je het zult overleven. Het is gewoon dat we de Orde de Sigil niet kunnen laten controleren door de Orde.,Oppsøk Orakelets tempel og spør det om de andre seglbitene. Her er det. Jeg tar opp alt. Det er ikke det at jeg ikke har tro på at du overlever. Men vi kan ikke la Ordenen kontrollere seglet.,"Poszukaj świątyni Wyroczni i zapytaj ją o inne kawałki Sigila. Oto on. Nagrywam wszystko. Nie chodzi o to, że nie wierzę, że przeżyjesz. Po prostu nie możemy pozwolić Zakonowi kontrolować Sigilu.","Procure pelo Oráculo e pergunte a ele sobre as outras peças do Sigilo. Certo, estou gravando tudo. Não é que eu não tenha fé de que você vá sobreviver. É só que não podemos deixar a Ordem controlar o Sigilo.",,"Găsește Oracolul și întreabă de celelalte piese ale Sigiliului. Aici este. Înregistrez totul. Nu e vorba că nu am încredere că vei supraviețui, dar nu putem lăsa Ordinul ca ia Sigiliul.","Найди храм Оракула и спроси его про другие фрагменты Печати. Так. Я всё записываю на плёнку. Это не потому, что я не верю, что ты уцелеешь. Просто мы не можем позволить Ордену заполучить Печать.",,Kahin'in tapınağını bulun ve ona diğer Sigil parçalarını sorun. İşte burada. Her şeyi kaydediyorum. Hayatta kalacağınıza inanmadığımdan değil. Sadece Düzen'in Sigil'i kontrol etmesine izin veremeyiz. +","오라클의 신전을 찾아서 시질 조각이 어디에 있는지 물어봐. 그리고 지금 난 모든 걸 녹음하고 있어. 네가 살아남을 거라는 믿음을 버린게 아니라, 오더가 시질을 손에 잡게 내버려 둘 수가 없어서 말이야.",Zoek de tempel van het Orakel op en vraag het over de andere Sigil stukken. Hier is het. Ik ben alles aan het opnemen. Niet dat ik er niet op vertrouw dat je het zult overleven. Het is gewoon dat we de Orde de Sigil niet kunnen laten controleren door de Orde.,Oppsøk Orakelets tempel og spør det om de andre seglbitene. Her er det. Jeg tar opp alt. Det er ikke det at jeg ikke har tro på at du overlever. Men vi kan ikke la Ordenen kontrollere seglet.,"Poszukaj świątyni Wyroczni i zapytaj ją o inne kawałki Sigila. Oto on. Nagrywam wszystko. Nie chodzi o to, że nie wierzę, że przeżyjesz. Po prostu nie możemy pozwolić Zakonowi kontrolować Sigilu.","Procure pelo Oráculo e pergunte a ele sobre as outras peças do Sigilo. Certo, estou gravando tudo. Não é que eu não tenha fé de que você vá sobreviver. É só que não podemos deixar a Ordem controlar o Sigilo.",,"Găsește Oracolul și întreabă de celelalte piese ale Sigiliului. Aici este. Înregistrez totul. Nu e vorba că nu am încredere că vei supraviețui, dar nu putem lăsa Ordinul ca ia Sigiliul.","Найди храм Оракула и спроси его про другие фрагменты Печати. Так. Я всё записываю на плёнку. Это не потому, что я не верю, что ты уцелеешь. Просто мы не можем позволить Ордену заполучить Печать.",,Sök upp Orakelns tempel och fråga det om de andra Sigillbitarna. Här är den. Jag spelar in allting. Det är inte så att jag inte tror att du kommer att överleva. Det är bara det att vi inte kan låta Orden kontrollera Sigillet.,Kahin'in tapınağını bulun ve ona diğer Sigil parçalarını sorun. İşte burada. Her şeyi kaydediyorum. Hayatta kalacağınıza inanmadığımdan değil. Sadece Düzen'in Sigil'i kontrol etmesine izin veremeyiz. The second piece lies at the heart of the crimson and obsidian tower. There you will find the Bishop. The Bishop is the Order's military leader. We off him and we score twice. Take the Oracle's token to the key master in the borderlands.,TXT_ILOG56,MAP12: After talking to the Oracle.,,,"Druhý díl leží v srdci věže karmínoobsidiánové. Tam najdeš Biskupa. Biskup je armádní vůdce Řádu. Plánuje jejich taktiky, velí jejich špiónům a má za úkol ovládat nás. Odděláme ho a zaskórujeme dvakrát.","Den anden del ligger i hjertet af det purpurfarvede og obsidianske tårn. Der vil du finde biskoppen. Biskoppen er ordenens militære leder. Hvis vi dræber ham, scorer vi to gange. Tag Oraklets token til nøglemesteren i grænselandet.","Das zweite Stück liegt im Zentrum des Turms aus Purpur und Obsidian. Dort wirst du den Bischof, den militärischen Anführer des Ordens, finden. Wenn wir ihn kalt machen, können wir zwei Fliegen mit einer Klappe schlagen. Nimm das Zeichen des Orakels und bringe es zum Schlüsselmeister in den Grenzgebieten.",,,"La segunda pieza está en el corazón de la torre carmesí y obsidiana. Ahí encontrarás al Obispo, el líder militar de la Orden. Nos lo cargamos y marcamos dos puntos. Lleva el vale del Oráculo al amo de llaves en las fronteras.","La segunda pieza está en el corazón de la torre carmesí y obsidiana. Ahí se encuentra el Obispo, el líder militar de la Orden. Lo matamos y premios dobles. Llévale el vale del Oráculo al amo de llaves en las fronteras.","Toinen osanen piilee purppuranpunaisen laavalasisen tornin sydämessä. Löydät sieltä Piispan, Veljeskunnan sotapäällikön. Teemme hänestä lopun ja pokkaamme kaksi pistettä. Toimita Oraakkelin merkki avainmestarille rajaseudulla.","La deuxième pièce se trouve au cœur de la tour d'obsidienne et d'écarlate. Tu y trouvera l'évêque. L'évêque est le chef militaire de l'Ordre. Si on le tue, on marque deux points. Prends le jeton de l'Oracle et amène le au Mâitre des Clés dans les terrains vagues. ","A második darab a karmazsin és obszidián torony szívében található. Ott fogod megtalálni a Püspököt. A Püspök a Rend katonai vezetője. Ha kiiktatjuk, duplán nyerünk. Vidd az Orákulum zálogát a kulcsmesterhez, aki a peremvidéken van.",Il secondo pezzo si trova nel cuore della torre cremisina e ossidiana. Lì troverai il Vescovo. Il Vescovo è il capo militare dell'Ordine. Farlo fuori sarebbe un enorme vantaggio. Raggiungi il mastro delle chiavi nelle terre di confine con il pass che ti ha dato l'Oracolo.,"二つ目の欠片は深紅と黒曜石の塔にある。そこでビショップを見つけろ。 ビショップはオーダーの軍事指揮官だ。奴を討ち破り欠片を手に入れろ。 -国境地帯のキーマスターにオラクルのトークンを見せよ。",두 번째 시질 조각은 진홍빛 흑요석 탑에 숨어있는 비숍에게 있어. 비숍은 그들의 잔혹한 군사 지도자이지. 거기에 녀석이 있을 거야. 그를 죽이면 두 배로 이득이 갈 거야. 이 통행증을 들고 접경지 안의 열쇠지기에게로 가봐.,Het tweede stuk ligt in het hart van de karmozijnrode en obsidiaan toren. Daar vindt u de bisschop. De bisschop is de militaire leider van de Orde. We gaan van hem af en we scoren twee keer. Neem de orakels van de Orakel mee naar de sleutelmeester in de grensgebieden.,"Den andre biten ligger i hjertet av det purpurfargede og obsidianske tårnet. Der finner du biskopen. Biskopen er Ordenens militære leder. Dreper vi ham, scorer vi to ganger. Ta oraklets symbol til nøkkelmesteren i grenselandene.",Drugi kawałek leży w sercu karmazynowej i obsydianowej wieży. Znajdziesz tam Biskupa. Biskup jest przywódcą wojskowym Zakonu. Wyłączamy go i zdobywamy dwa razy punkty. Zabierz żeton Wyroczni do mistrza kluczy na pograniczu.,A segunda peça está no coração da torre carmesin e obsidiana. Lá você encontrará o Bispo. Ele é o líder militar da Ordem. Nós apagamos ele e serão dois coelhos numa tacada só. Leve o emblema do Oráculo para o mestre das chaves nas fronteiras.,,A doua piesă e în inima turnului stăveziu din obsidian. Episcopul e liderul miltar ar Ordinului. Îl omorâm și înscriem de două ori. Ia semnul Oracolului la stăpânul cheii în mărginime.,Второй фрагмент лежит в сердце багрово-обсидиановой башни. Там ты сразишься с Епископом. Епископ — военный лидер Ордена. От его убийства мы выигрываем вдвойне. Отнеси жетон Оракула ключнику в пограничье.,,İkinci parça kızıl ve obsidyen kulenin kalbinde yatıyor. Orada Piskopos'u bulacaksın. Piskopos Tarikat'ın askeri lideri. Onu yok edersek iki puan alırız. Kahin'in simgesini sınır bölgelerindeki anahtar ustasına götürün. +国境地帯のキーマスターにオラクルのトークンを見せよ。",두 번째 시질 조각은 진홍빛 흑요석 탑에 숨어있는 비숍에게 있어. 비숍은 그들의 잔혹한 군사 지도자이지. 거기에 녀석이 있을 거야. 그를 죽이면 두 배로 이득이 갈 거야. 이 통행증을 들고 접경지 안의 열쇠지기에게로 가봐.,Het tweede stuk ligt in het hart van de karmozijnrode en obsidiaan toren. Daar vindt u de bisschop. De bisschop is de militaire leider van de Orde. We gaan van hem af en we scoren twee keer. Neem de orakels van de Orakel mee naar de sleutelmeester in de grensgebieden.,"Den andre biten ligger i hjertet av det purpurfargede og obsidianske tårnet. Der finner du biskopen. Biskopen er Ordenens militære leder. Dreper vi ham, scorer vi to ganger. Ta oraklets symbol til nøkkelmesteren i grenselandene.",Drugi kawałek leży w sercu karmazynowej i obsydianowej wieży. Znajdziesz tam Biskupa. Biskup jest przywódcą wojskowym Zakonu. Wyłączamy go i zdobywamy dwa razy punkty. Zabierz żeton Wyroczni do mistrza kluczy na pograniczu.,A segunda peça está no coração da torre carmesin e obsidiana. Lá você encontrará o Bispo. Ele é o líder militar da Ordem. Nós apagamos ele e serão dois coelhos numa tacada só. Leve o emblema do Oráculo para o mestre das chaves nas fronteiras.,,A doua piesă e în inima turnului stăveziu din obsidian. Episcopul e liderul miltar ar Ordinului. Îl omorâm și înscriem de două ori. Ia semnul Oracolului la stăpânul cheii în mărginime.,Второй фрагмент лежит в сердце багрово-обсидиановой башни. Там ты сразишься с Епископом. Епископ — военный лидер Ордена. От его убийства мы выигрываем вдвойне. Отнеси жетон Оракула ключнику в пограничье.,,Den andra delen ligger i hjärtat av det karmosinröda och obsidianska tornet. Där hittar du biskopen. Biskopen är ordens militära ledare. Om vi dödar honom gör vi två poäng. Ta Orakelns token till nyckelmästaren i gränslandet.,İkinci parça kızıl ve obsidyen kulenin kalbinde yatıyor. Orada Piskopos'u bulacaksın. Piskopos Tarikat'ın askeri lideri. Onu yok edersek iki puan alırız. Kahin'in simgesini sınır bölgelerindeki anahtar ustasına götürün. "The Bishop is going to be heavily guarded, so why don't we swipe a uniform and blend in? Locate the Bishop. Once you have destroyed him, return to the Oracle.",TXT_ILOG57,MAP11: Officer's uniform room.,,,"Biskup bude silně strážen, co takhle sebrat uniformu a splynout s davem? Najdi Biskupa. Až ho zabiješ, vrať se k Věštci.","Biskoppen vil være stærkt bevogtet, så hvorfor stjæler vi ikke en uniform og blander os i mængden? Find biskoppen. Når du har udslettet ham, vender du tilbage til Oraklet.","Der Bischof wird schwer bewacht sein, also warum besorgen wir uns nicht eine Uniform und mischen uns unter seine Leute? Finde den Bischof. Wenn du ihn vernichtet hast, kehre zum Orakel zurück.",,,"El Obispo estará fuertemente protegido, así que ¿por qué no robamos un uniforme y nos mezclamos? Localiza al Obispo. Una vez lo hayas destruído, vuelve con el Oráculo.",,"Piispa on tarkoin vartioitu, joten kähvellettäisiinkö univormu ja sulauduttaisiin joukkoon? Paikallista Piispa. Tuhottuasi hänet palaa Oraakkelin luo.","L'évêque sera lourdement protégé. Pourquoi ne pas faire une entrée discrète avec un uniforme? Trouve l'évêque, une fois qu'il est mort, retourne à l'Oracle.","A Püspököt elég erősen védik, ezért ajánlott, hogy szerválj magadnak egy uniformist a beolvadás végett. Találd meg a Püspököt. Ha megölted, térj vissza az Orákulumhoz.","Il Vescovo sarà sicuramente ben protetto, quindi perché non camuffarsi con un'uniforme? Trova il Vescovo. Dopo averlo distrutto, ritorna dall'Oracolo.","ビショップのいる場所の警備は厳重なので、 奴等の制服を盗み紛れ込む方が良いのでは? -ビショップを探し、始末したらオラクルの元へ戻ろう。","비숍은 군사 지도자니까, 삼엄한 경비에 의해 지켜질 거야. 그러니 전투복을 입고 잠입하는 게 어때? 비숍을 찾아서, 그를 파괴하고 오라클에게 찾아가 봐.","De bisschop zal zwaar bewaakt worden, dus waarom vegen we er niet een uniform overheen en mengen we ons in de bisschop? Zoek de bisschop. Als je hem hebt vernietigd, keer je terug naar het Orakel.","Biskopen kommer til å være tungt bevoktet, så hvorfor tar vi ikke en uniform og smelter inn? Finn biskopen. Når du har tilintetgjort ham, gå tilbake til oraklet.","Biskup będzie pilnie strzeżony, więc może weźmiemy mundur i wtopimy się w tłum? Zlokalizuj Bishopa. Kiedy już go zniszczysz, wróć do Wyroczni.","O Bispo estará protegido por vários guardas, então que tal roubar um uniforme e se mesclar a eles? Localize o Bispo. Assim que você destruí-lo, volte ao Oráculo.",,"Episcopul o să fie extrem de bine înarmat, deci de ce nu strecurăm o uniformă ca să ne camuflăm? Găsește Episcopul. Odată ce l-ai distrus, întoarce-te la Oracol.","Похоже, что Епископа неплохо охраняют, так что почему бы нам не стянуть униформу и прокрасться внутрь? Найди Епископа. После того, как ты уничтожишь его, возвращайся к Оракулу.",,"Piskopos çok sıkı korunuyor olacak, o yüzden neden bir üniforma çalıp aralarına karışmıyoruz? Piskoposu bulun. Onu yok ettikten sonra Kahin'e dönün." +ビショップを探し、始末したらオラクルの元へ戻ろう。","비숍은 군사 지도자니까, 삼엄한 경비에 의해 지켜질 거야. 그러니 전투복을 입고 잠입하는 게 어때? 비숍을 찾아서, 그를 파괴하고 오라클에게 찾아가 봐.","De bisschop zal zwaar bewaakt worden, dus waarom vegen we er niet een uniform overheen en mengen we ons in de bisschop? Zoek de bisschop. Als je hem hebt vernietigd, keer je terug naar het Orakel.","Biskopen kommer til å være tungt bevoktet, så hvorfor tar vi ikke en uniform og smelter inn? Finn biskopen. Når du har tilintetgjort ham, gå tilbake til oraklet.","Biskup będzie pilnie strzeżony, więc może weźmiemy mundur i wtopimy się w tłum? Zlokalizuj Bishopa. Kiedy już go zniszczysz, wróć do Wyroczni.","O Bispo estará protegido por vários guardas, então que tal roubar um uniforme e se mesclar a eles? Localize o Bispo. Assim que você destruí-lo, volte ao Oráculo.",,"Episcopul o să fie extrem de bine înarmat, deci de ce nu strecurăm o uniformă ca să ne camuflăm? Găsește Episcopul. Odată ce l-ai distrus, întoarce-te la Oracol.","Похоже, что Епископа неплохо охраняют, так что почему бы нам не стянуть униформу и прокрасться внутрь? Найди Епископа. После того, как ты уничтожишь его, возвращайся к Оракулу.",,"Biskopen kommer att vara tungt bevakad, så varför inte sno en uniform och smälta in? Leta upp biskopen. När du har förintat honom återvänder du till oraklet.","Piskopos çok sıkı korunuyor olacak, o yüzden neden bir üniforma çalıp aralarına karışmıyoruz? Piskoposu bulun. Onu yok ettikten sonra Kahin'e dönün." "I just got word that we have an informer inside the fortress. Let's head for the hospital. He works there. After that, locate the Bishop and destroy him. Once he's dead return to the Oracle.",TXT_ILOG59,MAP17: Bailey → Upstairs.,,,"Právě jsem dostala zprávu, že máme v pevnosti informátora. Měli bychom zamířit k nemocnici, pracuje tam. Poté najdi Biskupa. Až ho zabiješ, vrať se k Věštci.","Jeg har lige fået at vide, at vi har en stikker inde i fæstningen. Lad os tage til hospitalet. Han arbejder der. Derefter skal du finde biskoppen og ødelægge ham. Når han er død, skal du vende tilbage til Oraklet.","Mir ist gerade zu Ohren gekommen, dass wir einen Informanten in der Festung haben. Lasst uns zum Krankenhaus gehen, er arbeitet dort. Danach finde den Bischof unz vernichte ihn. Sobald er tot ist kehre zum Orakel zurück.",,,"Acaban de decirme que tenemos un informante dentro de la fortaleza; vayamos al hospital, que es donde trabaja. Luego localiza al Obispo y destrúyelo. Una vez muerto, vuelve con el Oráculo.","Acaban de decirme que tenemos un informante adentro de la fortaleza; vayamos al hospital, que es donde trabaja. Luego localiza al Obispo y destrúyelo. Una vez muerto, vuelve con el Oráculo.","Sain juuri tiedon ilmiantajasta linnoituksessa. Matkataan sairaalaan; hän työskentelee siellä. Sen jälkeen löydä Piispa ja tuhoa hänet. Kun hän on kuollut, palaa Oraakkelin luo.","Je viens d'avoir vent que l'on a un informant dans la forteresse. Allons à l'hôpital, il y travaille. Après ça, trouve l'évêque et tue-le, puis retourne à l'Oracle.","Most kaptam a hírt, hogy van egy belső emberünk az erődítményben. Menjünk a kórházba. Ott dolgozik. Azután találd meg a Püspököt, és öld meg. Ha meghalt, menj az Orákulumhoz.","Ho appena scoperto che abbiamo un informatore dentro la fortezza. Rechiamoci all'ospedale. Lui lavora là. Dopodiché, trova il Vescovo e distruggilo. Non appena è morto, torna dall'Oracolo.","要塞の中に情報提供者がいるという話を聞いた。 -奴等が病院と呼んでいる場所に勤めているので向かいましょう。","요새 안에 우리들을 도울 정보원이 있다는 보고를 들었어. 그는 병원 안에 있는데, 그곳으로 찾아가 봐. 만난 뒤엔 비숍을 찾은 뒤 그를 파괴하고 오라클에게 찾아가 봐.","Ik heb net vernomen dat we een informant in het fort hebben. Laten we naar het ziekenhuis gaan. Hij werkt daar. Zoek daarna de bisschop en vernietig hem. Als hij dood is, ga dan terug naar het Orakel.","Jeg fikk nettopp beskjed om at vi har en informant inne i festningen. La oss dra til sykehuset. Han jobber der. Etter det, finn biskopen og drep ham. Når han er død, gå tilbake til Orakelet.","Właśnie dostałem wiadomość, że mamy informatora w twierdzy. Jedźmy do szpitala. On tam pracuje. Po tym zlokalizuj Bishopa i zniszcz go. Gdy będzie martwy, wróć do Wyroczni.","Acabei de saber que temos um informante dentro da fortaleza. Vamos ao hospital. Ele trabalha lá. Após isso, localize o Bispo e destrua-o. Assim que ele morrer retorne ao Oráculo.",,"Tocmai am primit informație că avem un informator în fortăreață. Să mergem către spital. Acolo lucrează. După aceea, să îl găsim pe Episcop și să-l eliminăm. Odată ce e mort întoarce-te la Oracol.","Мне только что сказали, что у нас есть информатор внутри крепости. Идём к госпиталю — он работает там. Затем найди Епископа и убей его. После его смерти вернись к Оракулу.",,"Az önce kalenin içinde bir muhbirimiz olduğu haberini aldım. Hastaneye gidelim. Orada çalışıyor. Ondan sonra, Piskoposu bulun ve onu yok edin. O öldükten sonra Kahin'e dönün." +奴等が病院と呼んでいる場所に勤めているので向かいましょう。","요새 안에 우리들을 도울 정보원이 있다는 보고를 들었어. 그는 병원 안에 있는데, 그곳으로 찾아가 봐. 만난 뒤엔 비숍을 찾은 뒤 그를 파괴하고 오라클에게 찾아가 봐.","Ik heb net vernomen dat we een informant in het fort hebben. Laten we naar het ziekenhuis gaan. Hij werkt daar. Zoek daarna de bisschop en vernietig hem. Als hij dood is, ga dan terug naar het Orakel.","Jeg fikk nettopp beskjed om at vi har en informant inne i festningen. La oss dra til sykehuset. Han jobber der. Etter det, finn biskopen og drep ham. Når han er død, gå tilbake til Orakelet.","Właśnie dostałem wiadomość, że mamy informatora w twierdzy. Jedźmy do szpitala. On tam pracuje. Po tym zlokalizuj Bishopa i zniszcz go. Gdy będzie martwy, wróć do Wyroczni.","Acabei de saber que temos um informante dentro da fortaleza. Vamos ao hospital. Ele trabalha lá. Após isso, localize o Bispo e destrua-o. Assim que ele morrer retorne ao Oráculo.",,"Tocmai am primit informație că avem un informator în fortăreață. Să mergem către spital. Acolo lucrează. După aceea, să îl găsim pe Episcop și să-l eliminăm. Odată ce e mort întoarce-te la Oracol.","Мне только что сказали, что у нас есть информатор внутри крепости. Идём к госпиталю — он работает там. Затем найди Епископа и убей его. После его смерти вернись к Оракулу.",,Jag fick just veta att vi har en informatör inne i fästningen. Vi går till sjukhuset. Han jobbar där. Efter det ska du lokalisera biskopen och förgöra honom. När han är död återvänder du till oraklet.,"Az önce kalenin içinde bir muhbirimiz olduğu haberini aldım. Hastaneye gidelim. Orada çalışıyor. Ondan sonra, Piskoposu bulun ve onu yok edin. O öldükten sonra Kahin'e dönün." "Don't give up. This is it. Straight ahead. Jump on the teleporter to central administration and destroy the computer core. This will kill the force field on the entrance to the Bishop's tower. Once he's dead, return to the Oracle.",TXT_ILOG64,MAP19: Last room (southwestern).,,,"Nevzdávej se, tohle je ono. Jdi rovně. Skoč na teleportér do centrálního velení a znič počítačové jádro. To zruší silové pole u vchodu do Biskupovy věže. Až ho zabiješ, vrať se k Věštci.","Du må ikke give op. Nu gælder det. Lige fremad. Hop på teleporteren til centraladministrationen og ødelæg computerkernen. Dette vil dræbe kraftfeltet ved indgangen til Bishop's tårn. Når han er død, skal du vende tilbage til Oraklet.",Nicht aufgeben. Da ist es. Direkt voraus. Springe auf den Teleporter zur Zentralverwaltung und zerstöre den Kern des Computers. Das wird das Kraftfeld zum Eingang des Turms des Bischofs lahmlegen. Sobald er tot ist kehre zum Orakel zurück.,,,"No te rindas. Aquí es. Justo de frente. Entra al teletransporte a la administración central y destruye el núcleo de la computadora. Esto apagará el campo de fuerza en la entrada a la torre del Obispo. Una vez muerto, vuelve con el Oráculo.","No re rindas. Aquí está. Justo enfrente. Entra al teleporte a la Administración Central y destruye el núcleo de la computadora. Esto quitará el campo de fuerza a la entrada de la torre del Obispo. Cuando esté muerto, regresa con el Oráculo.","Älä luovuta. Se on nyt tässä, suoraan edessä. Astu keskushallintoon johtavaan kaukosiirtimeen ja tuhoa keskustietokone. Se sammuttaa Piispan tornin voimakentän. Kun hän on kuollut, palaa Oraakkelin luo.","N'abandonne pas, on y est bientôt. Utilise le téléporteur vers le centre d'administration et détruis le cœur informatique. Cela désactivera le champ de force et l'entrée vers la tour de l'évêque. Une fois qu'il est mort, retourne voir l'Oracle.","Ne add fel. Már a célegyenesben vagyunk, rögtön előttünk van. A teleportot használva menj a központi irányításhoz és semmisítsd meg a számítógép magot. Ez majd kikapcsolja a Püspök tornyának bejárati erőpajzsát. Ha megölted, térj vissza az Orákulumhoz.","Non arrenderti. Siamo arrivati. Dritto in fronte a te. Entra in questo teletrasporto per l'amministrazione centrale e distruggi il nucleo del computer. Questo disattiverà il campo di forza per l'ingresso della torre del Vescovo. Non appena è morto, torna dall'Oracolo","諦めないで。これでいいんだ。真っ直ぐ行こう。 中央管理室のテレポーターに入りコンピューターコアを破壊せよ。 それはビショップのフォースフィールドを殺せる。 -ビショップも殺したらオラクルの元へ戻れ。",포기하지 마. 이제 거의 다 왔어. 저 텔레포터를 올라타서 관리소로 가서 컴퓨터 중심부를 파괴해. 방어막을 완전히 꺼버리고 비숍을 죽일 수 있을 거야. 그를 파괴하고 오라클에게 찾아가 봐.,"Geef niet op. Dit is het. Rechtdoor. Spring op de teleporter naar de centrale administratie en vernietig de computerkern. Dit zal het krachtveld op de ingang van de Bisschopstoren doden. Als hij dood is, keer je terug naar het Orakel.","Ikke gi opp. Her er det. Rett frem. Hopp på teleporteren til sentraladministrasjonen og ødelegg datakjernen. Dette vil drepe kraftfeltet ved inngangen til biskopens tårn. Når han er død, gå tilbake til Oraklet.","Nie poddawaj się. To jest to. Prosto przed siebie. Wskocz na teleporter do centralnej administracji i zniszcz rdzeń komputera. To zabije pole siłowe przy wejściu do wieży biskupa. Gdy będzie już martwy, wróć do Oracle.",Não desista. A hora é agora. Siga reto adiante. Entre no teletransportador para a administração central e destrua o núcleo de computação. Isso vai derrubar o campo de força na entrada da torre do Bispo. Assim que ele morrer retorne ao Oráculo.,,"Nu te da bătut. Drept în față. Sari pe teleportorul către administrația centrală și distruge nucleul calculatoarelor. Asta va distruge câmpul de forță la intrarea în turnul Episcopului. Odată ce e mort, întoarce-te la Oracol.","Не падай духом. Вот оно. Прямо впереди. Прыгай в телепорт к центральной администрации и уничтожь центральный компьютер. Это отключит силовое поле на входе в башню Епископа. После его смерти, возвращайся к Оракулу.",,"Sakın pes etmeyin. İşte burası. Dümdüz ilerleyin. Merkezi yönetime giden ışınlayıcıya atla ve bilgisayar çekirdeğini yok et. Bu, Piskopos'un kulesinin girişindeki güç alanını yok edecek. O öldükten sonra Kahin'e dönün." +ビショップも殺したらオラクルの元へ戻れ。",포기하지 마. 이제 거의 다 왔어. 저 텔레포터를 올라타서 관리소로 가서 컴퓨터 중심부를 파괴해. 방어막을 완전히 꺼버리고 비숍을 죽일 수 있을 거야. 그를 파괴하고 오라클에게 찾아가 봐.,"Geef niet op. Dit is het. Rechtdoor. Spring op de teleporter naar de centrale administratie en vernietig de computerkern. Dit zal het krachtveld op de ingang van de Bisschopstoren doden. Als hij dood is, keer je terug naar het Orakel.","Ikke gi opp. Her er det. Rett frem. Hopp på teleporteren til sentraladministrasjonen og ødelegg datakjernen. Dette vil drepe kraftfeltet ved inngangen til biskopens tårn. Når han er død, gå tilbake til Oraklet.","Nie poddawaj się. To jest to. Prosto przed siebie. Wskocz na teleporter do centralnej administracji i zniszcz rdzeń komputera. To zabije pole siłowe przy wejściu do wieży biskupa. Gdy będzie już martwy, wróć do Oracle.",Não desista. A hora é agora. Siga reto adiante. Entre no teletransportador para a administração central e destrua o núcleo de computação. Isso vai derrubar o campo de força na entrada da torre do Bispo. Assim que ele morrer retorne ao Oráculo.,,"Nu te da bătut. Drept în față. Sari pe teleportorul către administrația centrală și distruge nucleul calculatoarelor. Asta va distruge câmpul de forță la intrarea în turnul Episcopului. Odată ce e mort, întoarce-te la Oracol.","Не падай духом. Вот оно. Прямо впереди. Прыгай в телепорт к центральной администрации и уничтожь центральный компьютер. Это отключит силовое поле на входе в башню Епископа. После его смерти, возвращайся к Оракулу.",,Ge inte upp. Det här är det. Rakt fram. Hoppa på teleportern till centraladministrationen och förstör datorkärnan. Detta kommer att döda kraftfältet vid ingången till biskopens torn. När han är död återvänder du till oraklet.,"Sakın pes etmeyin. İşte burası. Dümdüz ilerleyin. Merkezi yönetime giden ışınlayıcıya atla ve bilgisayar çekirdeğini yok et. Bu, Piskopos'un kulesinin girişindeki güç alanını yok edecek. O öldükten sonra Kahin'e dönün." "Very impressive. Lets blow it up. That should take care of the force field. Let's get back to the bailey, then off to the tower and the Bishop.",TXT_ILOG70,MAP15: After pressing the switch to reveal the computer.,,,Velmi působivé. Co to nechat vybouchnout? To by se mělo postarat o silové pole. Vraťme se zpět do opevnění a tam do věže a k Biskupovi.,Meget imponerende. Lad os sprænge det i luften. Det burde tage sig af kraftfeltet. Lad os komme tilbage til borggården og derefter hen til tårnet og biskoppen.,"Sehr eindrucksvoll. Lass es uns in die Luft jagen. Damit sollte das Kraftfeld ausgeschaltet sein. Lass uns zum Vorhof zurückkehren, dann zum Turm und dem Bischof.",,,"Muy impresionante. Vamos a destruirlo; eso debería ocuparse del campo de fuerza. Volvamos al patio, luego derecho a la torre y al Obispo.","Muy impresionante. Vamos a destruirla; eso debería ocuparse del campo de fuerza. Volvamos al patio, luego derecho a la torre y al Obispo.","Aika vaikuttava. Posautetaan se. Sillä voimakentän pitäisi hoitua. Palataan linnanpihaan, josta sitten torniin Piispan luo.","Excellent, maintenant, faisons tout sauter. Cela devrait nous débarasser du cœur informatique. Retourne au mur d'enceinte puis rentre dans la tour de l'évêque.","Felettébb lenyűgöző. Robbantsuk is fel. Ez majd gondoskodik az erőpajzsról. Menjünk vissza a várfalhoz, majd a toronyhoz és magához a Püspökhöz.",Davvero impressionante. Facciamolo saltare in aria. Ora il campo di forza dovrebbe essere disattivato. Ora raggiungiamo la torre e facciamo fuori il Vescovo.,"あら、見事な物ね。是非とも火薬を献上しましょう。 -それでベイリーに戻ってフォースフィールドが守っていたビショップの塔へ向かおう。",아주 인상 깊은데? 어서 파괴하자고. 그러면 방어막을 끌 수 있을 거야. 그 후에 안뜰로 향해서 성으로 찾아가. 그리고 비숍을 죽여버려.,"Zeer indrukwekkend. Laten we het opblazen. Dat zou voor het krachtveld moeten zorgen. Laten we teruggaan naar de bailey, dan naar de toren en de bisschop.","Veldig imponerende. La oss sprenge det. Det burde ta seg av kraftfeltet. La oss gå tilbake til borggården, og så til tårnet og biskopen.","Bardzo efektowne. Wysadźmy ją w powietrze. To powinno załatwić sprawę pola siłowego. Wracajmy na podzamcze, a potem do wieży i biskupa.",Impressionante mesmo. Vamos detoná-lo. Isso deve dar um jeito no campo de força. Volte para a fortaleza e depois vá para a torre encontrar o Bispo.,,"Foarte impresionant. Să-l aruncăm în aer. Asta va rezolva problema câmpului de forță. Să ne întoarcem la alee, apoi către turn și Episcop.","Очень впечатляюще. Давай взорвём. Это должно избавить нас от проблем с силовым полем. Возвращаемся во внутренний двор, затем к башне и Епископу.",,"Çok etkileyici. Hadi onu havaya uçuralım. Bu güç alanının icabına bakacaktır. Dış avluya geri dönelim, sonra kuleye ve Piskopos'a gidelim." +それでベイリーに戻ってフォースフィールドが守っていたビショップの塔へ向かおう。",아주 인상 깊은데? 어서 파괴하자고. 그러면 방어막을 끌 수 있을 거야. 그 후에 안뜰로 향해서 성으로 찾아가. 그리고 비숍을 죽여버려.,"Zeer indrukwekkend. Laten we het opblazen. Dat zou voor het krachtveld moeten zorgen. Laten we teruggaan naar de bailey, dan naar de toren en de bisschop.","Veldig imponerende. La oss sprenge det. Det burde ta seg av kraftfeltet. La oss gå tilbake til borggården, og så til tårnet og biskopen.","Bardzo efektowne. Wysadźmy ją w powietrze. To powinno załatwić sprawę pola siłowego. Wracajmy na podzamcze, a potem do wieży i biskupa.",Impressionante mesmo. Vamos detoná-lo. Isso deve dar um jeito no campo de força. Volte para a fortaleza e depois vá para a torre encontrar o Bispo.,,"Foarte impresionant. Să-l aruncăm în aer. Asta va rezolva problema câmpului de forță. Să ne întoarcem la alee, apoi către turn și Episcop.","Очень впечатляюще. Давай взорвём. Это должно избавить нас от проблем с силовым полем. Возвращаемся во внутренний двор, затем к башне и Епископу.",,Mycket imponerande. Låt oss spränga det i luften. Det borde ta hand om kraftfältet. Vi går tillbaka till borggården och sedan vidare till tornet och biskopen.,"Çok etkileyici. Hadi onu havaya uçuralım. Bu güç alanının icabına bakacaktır. Dış avluya geri dönelim, sonra kuleye ve Piskopos'a gidelim." "Bravo, another piece of the Sigil! Did you see that weird spectre that came out of the Bishop's body? Where have I seen that before? Let's get back to the Oracle.",TXT_ILOG74,,,,"Bravo, další díl Pečetě! Viděl jsi ten divný přízrak, který vyšel z Biskupova těla? Kde jsem ho jen předtím viděla? Vraťme se k Věštci.","Bravo, endnu et stykke af Sigil! Så du det underlige spøgelse, der kom ud af biskoppens krop? Hvor har jeg set det før? Lad os gå tilbage til Oraklet.","Gratulation, ein weiteres Teil des Sigils! Hast du den merkwürdigen Schemen gesehen, der aus dem Körper des Bischofs herauskam? Wo habe ich ihn bloß schon einmal gesehen? Lass uns zum Orakel zurückkehren.",,,"¡Bravo, otra pieza del Emblema! ¿Viste ese extraño espectro que salió del cuerpo del Obispo? ¿Donde he visto eso antes? Volvamos con el Oráculo.","¡Bravo, otra pieza del Emblema! ¿Viste ese extraño espectro que salió del cuerpo del Obispo? ¿Dónde he visto eso antes? Regresemos con el Oráculo.","Bravo, toinen Sinetin osanen! Näitkö tuon oudon aaveen, joka nousi Piispan ruumiista? Missä olen nähnyt sen aiemmin? Palataan Oraakkelin luokse.","Bravo, encore une pièce du Sigil! Tu a vu ce spectre étrange qui est sorti du corps de l'évêque? Je crois l'avoir vu avant, retournons à l'Oracle.","Bravó, egy újabb pecsét darab! Láttad azt a fura kísértetet ami a Püspök teteméből eltávozott? Hol is láttam hasonlót? Menjünk vissza az Orákulumhoz.","Bravo, un altro pezzo del Sigillo! Hai visto quello strano spettro che è uscito dal corpo del Vescovo? Dove l'ho già visto prima? Torniamo dall'Oracolo.","ブラボー!新たなるシジルの欠片だ! ビショップの体から出てきたあの奇妙な幽体を見た? -以前に何処かで見た気がするけど?",브라보! 두 번째 시질 조각을 얻었어! 그나저나 비숍 몸에서 튀어나왔던 검은 물체 봤어? 전에 본 적이 있나? 오라클에게 돌아가자.,"Bravo, nog een stukje van de Sigil! Zag je dat rare spook dat uit het lichaam van de bisschop kwam? Waar heb ik dat eerder gezien? Laten we teruggaan naar het Orakel.","Bravo, enda en bit av sigillet! Så du det rare spøkelset som kom ut av biskopens kropp? Hvor har jeg sett det før? La oss gå tilbake til oraklet.","Brawo, kolejny kawałek Sigilu! Widziałeś to dziwne widmo, które wyszło z ciała biskupa? Gdzie ja to już widziałem? Wróćmy do Wyroczni.",Bravo! Outra peça do Sigilo! Você viu aquele espectro estranho que saiu do corpo do Bispo? Onde foi que eu já vi aquilo antes? Vamos voltar para o Oráculo.,,"Bravo, încă o bucată din Sigiliu! Ai văzut spectrul ciudat ce a ieșit din corpul Episcopului? Unde am mai văzut asta oare? Să ne întoarcem la Oracol.","Браво, ещё один фрагмент Печати! Видел тот странный фантом, вышедший из тела Епископа? Где я могла видеть такое раньше? Давай вернёмся к Оракулу.",,"Bravo, Sigil'in bir parçası daha! Piskopos'un bedeninden çıkan garip hayaleti gördün mü? Bunu daha önce nerede görmüştüm? Kahin'e geri dönelim." +以前に何処かで見た気がするけど?",브라보! 두 번째 시질 조각을 얻었어! 그나저나 비숍 몸에서 튀어나왔던 검은 물체 봤어? 전에 본 적이 있나? 오라클에게 돌아가자.,"Bravo, nog een stukje van de Sigil! Zag je dat rare spook dat uit het lichaam van de bisschop kwam? Waar heb ik dat eerder gezien? Laten we teruggaan naar het Orakel.","Bravo, enda en bit av sigillet! Så du det rare spøkelset som kom ut av biskopens kropp? Hvor har jeg sett det før? La oss gå tilbake til oraklet.","Brawo, kolejny kawałek Sigilu! Widziałeś to dziwne widmo, które wyszło z ciała biskupa? Gdzie ja to już widziałem? Wróćmy do Wyroczni.",Bravo! Outra peça do Sigilo! Você viu aquele espectro estranho que saiu do corpo do Bispo? Onde foi que eu já vi aquilo antes? Vamos voltar para o Oráculo.,,"Bravo, încă o bucată din Sigiliu! Ai văzut spectrul ciudat ce a ieșit din corpul Episcopului? Unde am mai văzut asta oare? Să ne întoarcem la Oracol.","Браво, ещё один фрагмент Печати! Видел тот странный фантом, вышедший из тела Епископа? Где я могла видеть такое раньше? Давай вернёмся к Оракулу.",,"Bravo, ännu en del av Sigillet! Såg du det konstiga spöket som kom ut ur biskopens kropp? Var har jag sett det förut? Låt oss gå tillbaka till oraklet.","Bravo, Sigil'in bir parçası daha! Piskopos'un bedeninden çıkan garip hayaleti gördün mü? Bunu daha önce nerede görmüştüm? Kahin'e geri dönelim." "I have a report that the spectral energy we found near the Bishop is also present by the Oracle, let's be careful.",TXT_ILOG76,,,,"Mám hlašení, že stejná přízračná energie, kterou jsme našli u Biskupa, se nachází také u Věštce, měli bychom být opatrní.","Jeg har en rapport om, at den spektrale energi, vi fandt nær biskoppen, også er til stede ved Oraklet, lad os være forsigtige.","Ich habe einen Report, dass die spektrale Energie, die wir beim Bischof vorfanden, auch in der Nähe des Orakels vorhanden ist. Wir sollten vorsichtig sein.",,,"Tengo un informe de que la energía espectral que encontramos cerca del Obispo también está presente junto al Oráculo, tengamos cuidado","Tengo reportes de que la energía espectral que encontramos cerca del Obispo también está presente en el Oráculo, tengamos cuidado","Sain tiedon, että aave-energiaa, jota löysimme Piispan läheltä, on läsnä myös Oraakkelin luona. Ollaan varovaisia.","Je recois un rapport que l'énergie spectrale qui possédait l'évêque se trouve aussi aux alentours de l'Oracle, fais attention.","Kaptam egy jelentést, hogy a Püspök körül érzékelt kísérteties energia észlelhető az Orákulum körül is. Vigyázzunk vele.","Ho qua un rapporto che ci informa che l'energia spettrale che abbiamo trovato vicino il Vescovo è anche presente vicino l'Oracolo, dobbiamo essere attenti.","ビショップにもあったスペクトラルエネルギーがオラクルにも宿っているという -報告があるわ、気を付けて。","지금 보고를 받았는데, 비숍을 죽인 뒤에 나온 혼령의 기운이 오라클에게도 있데. 조심하자.","Ik heb een bericht dat de spectrale energie die we in de buurt van de bisschop vonden ook aanwezig is bij het Orakel, laten we voorzichtig zijn.","Jeg har en rapport om at den spektrale energien vi fant nær biskopen også er til stede ved oraklet, la oss være forsiktige.","Mam raport, że energia widmowa, którą znaleźliśmy w pobliżu Bishopa, jest również obecna przy Wyroczni, bądźmy ostrożni.",Recebi um relatório de que a energia espectral que encontramos perto do Bispo também está presente pelo Oráculo. Precisamos tomar cuidado.,,"Am un raport care spune că energia spectrală a Episcopului a prezentă și în Oracol, s-avem grijă.","Мне доложили, что спектральная энергия, найденная нами возле Епископа, также исходит от Оракула. Будь начеку.",,"Piskoposun yanında bulduğumuz spektral enerjinin Kahin tarafından da mevcut olduğuna dair bir rapor aldım, dikkatli olalım." +報告があるわ、気を付けて。","지금 보고를 받았는데, 비숍을 죽인 뒤에 나온 혼령의 기운이 오라클에게도 있데. 조심하자.","Ik heb een bericht dat de spectrale energie die we in de buurt van de bisschop vonden ook aanwezig is bij het Orakel, laten we voorzichtig zijn.","Jeg har en rapport om at den spektrale energien vi fant nær biskopen også er til stede ved oraklet, la oss være forsiktige.","Mam raport, że energia widmowa, którą znaleźliśmy w pobliżu Bishopa, jest również obecna przy Wyroczni, bądźmy ostrożni.",Recebi um relatório de que a energia espectral que encontramos perto do Bispo também está presente pelo Oráculo. Precisamos tomar cuidado.,,"Am un raport care spune că energia spectrală a Episcopului a prezentă și în Oracol, s-avem grijă.","Мне доложили, что спектральная энергия, найденная нами возле Епископа, также исходит от Оракула. Будь начеку.",,"Jag har en rapport om att den spektrala energin som vi hittade nära biskopen också finns vid oraklet, låt oss vara försiktiga.","Piskoposun yanında bulduğumuz spektral enerjinin Kahin tarafından da mevcut olduğuna dair bir rapor aldım, dikkatli olalım." Richter has taken over command of our forces. It looks like Macil has been deceiving us all along. His true allegiance was to the Order. What a snake. Let's get back to the Oracle.,TXT_ILOG79,,,,"Richter převzal velení našich sil. Zdá se, že nás Macil celou dobu klamal. Ve skutečnosti byl věrný Řádu. Slizák jeden. Vraťme se k Věštci.","Richter har overtaget kommandoen over vores styrker. Det ser ud til, at Macil har bedraget os hele tiden. Hans sande loyalitet var over for ordenen. Sikke en slange. Lad os gå tilbage til Oraklet.",Richter hat das Kommando über unsere Streitkräfte übernommen. Es scheint als hätte Macil uns die ganze Zeit über getäuscht. Sein wahre Loyalität gehörte dem Orden. Was für eine Ratte. Lass uns zum Orakel zurückkehren.,,,Richter ha tomado el mando de nuestras fuerzas. Parece que Macil nos ha estado engañando todo este tiempo. Su verdadera lealtad era a la Orden. Qué serpiente. Volvamos con el Oráculo.,Richter ha tomado el mando de nuestras fuerzas. Parece que Macil nos ha estado engañando todo el tiempo. Su verdadera lealtad fue a la Orden. Que serpiente. Volvamos con el Oráculo.,"Richter on ottanut joukkomme komentoonsa. Näyttää siltä, että Macil on pettänyt meitä alusta alkaen. Hänen todellinen uskollisuutensa on ollut Veljeskunnalle; mikä käärme. Palataan Oraakkelin luokse.","Richter a pris le contrôle de nos forces. Il semble que Macil nous a menti tout du long. Sa vraie allégiance était avec l'Ordre, quel serpent! Retournous à l'Oracle.",Richter átvette az írányítást a csapataink fölött. Úgy tűnik Macil mindvégig megtévesztett minket. Valójában mindvégig a Rend oldalán volt. micsoda kígyó. Menjünk vissza az Orákulumhoz.,Richter ha assunto il comando delle nostre forze. Sembra che Macil ci avesse ingannato fin dall'inizio. In realtà è sempre stato alleato con l'Ordine. Che serpente. Ritorniamo dall'Oracolo.,"リヒターが指揮官の任を引き継いだ。マシルはずっと私達を騙していたなんて。 -あの人がオーダーに真の忠誠を誓っていたなんて、とんだ蛇神憑きだわ。",릭터가 저항군의 새로운 지도자가 될 거야. 내 생각엔 마실이 오랫동안 우리들을 속인 것 같아... 뱀 같은 자식. 오라클에게 돌아가자.,Richter heeft het bevel over onze troepen overgenomen. Het lijkt erop dat Macil ons al die tijd heeft bedrogen. Zijn ware trouw was aan de Orde. Wat een slang. Laten we teruggaan naar het Orakel.,Richter har overtatt kommandoen over styrkene våre. Det ser ut til at Macil har lurt oss hele tiden. Hans sanne lojalitet var til Ordenen. For en slange. La oss gå tilbake til orakelet.,"Richter przejął dowodzenie nad naszymi siłami. Wygląda na to, że Macil cały czas nas zwodził. Jego prawdziwa wierność była dla Zakonu. Co za wąż. Wracajmy do Wyroczni.",O Richter assumiu o comando de nossas forças. Parece que o Macil esteve nos enganando durante todo esse tempo. Sua verdadeira lealdade era à Ordem. Que traíra! Vamos voltar para o Oráculo.,,Richter a preluat controlul asupra forțelor noastre. Se pare că Macil ne-a mințit tot timpul. A fost loial cu adevărat doar Ordinului. Ce șarpe. Să ne întoarcem la Oracol.,"Рихтер принял на себя командование нашими силами. Похоже, что Мэйсил обманывал всех нас с самого начала. На самом деле он был предан Ордену. Подлец. Давай вернёмся к Оракулу.",,Richter kuvvetlerimizin komutasını devraldı. Görünüşe göre Macil başından beri bizi kandırıyormuş. Gerçek bağlılığı Tarikat'a imiş. Ne yılan ama. Kahin'e geri dönelim. +あの人がオーダーに真の忠誠を誓っていたなんて、とんだ蛇神憑きだわ。",릭터가 저항군의 새로운 지도자가 될 거야. 내 생각엔 마실이 오랫동안 우리들을 속인 것 같아... 뱀 같은 자식. 오라클에게 돌아가자.,Richter heeft het bevel over onze troepen overgenomen. Het lijkt erop dat Macil ons al die tijd heeft bedrogen. Zijn ware trouw was aan de Orde. Wat een slang. Laten we teruggaan naar het Orakel.,Richter har overtatt kommandoen over styrkene våre. Det ser ut til at Macil har lurt oss hele tiden. Hans sanne lojalitet var til Ordenen. For en slange. La oss gå tilbake til orakelet.,"Richter przejął dowodzenie nad naszymi siłami. Wygląda na to, że Macil cały czas nas zwodził. Jego prawdziwa wierność była dla Zakonu. Co za wąż. Wracajmy do Wyroczni.",O Richter assumiu o comando de nossas forças. Parece que o Macil esteve nos enganando durante todo esse tempo. Sua verdadeira lealdade era à Ordem. Que traíra! Vamos voltar para o Oráculo.,,Richter a preluat controlul asupra forțelor noastre. Se pare că Macil ne-a mințit tot timpul. A fost loial cu adevărat doar Ordinului. Ce șarpe. Să ne întoarcem la Oracol.,"Рихтер принял на себя командование нашими силами. Похоже, что Мэйсил обманывал всех нас с самого начала. На самом деле он был предан Ордену. Подлец. Давай вернёмся к Оракулу.",,Richter har tagit över befälet över våra styrkor. Det verkar som om Macil har lurat oss hela tiden. Hans sanna lojalitet var till Orden. Vilken orm. Låt oss gå tillbaka till Oraklet.,Richter kuvvetlerimizin komutasını devraldı. Görünüşe göre Macil başından beri bizi kandırıyormuş. Gerçek bağlılığı Tarikat'a imiş. Ne yılan ama. Kahin'e geri dönelim. Another Sigil piece. We are one step closer to freedom. And you are one step closer to me. Let's get back to the Oracle!,TXT_ILOG83,,,,Další díl Pečeti. Jsme o krok blíž ke svobodě. A ty jsi o krok blíž ke mě. Vraťme se k Věštci.,Endnu et Sigil-stykke. Vi er et skridt nærmere friheden. Og du er et skridt tættere på mig. Lad os komme tilbage til Oraklet!,Ein weiteres Teilstück des Sigils. Wir sind der Freiheit einen Schritt näher gekommen. Lass uns zurückgehen zum Orakel.,,,Otra pieza del Emblema. Estamos un paso más cerca de la libertad. Y estás un paso más cerca de mí. ¡Volvamos con el Oráculo!,Otra pieza del Emblema. Estamos un paso más cerca de la libertad. Y estás un paso más cerca de mí. ¡Regresemos con el Oráculo!,Jälleen uusi Sinetin osanen. Olemme taas askeleen lähempänä vapautta. Ja sinä askeleen lähempänä minua. Palataan Oraakkelin luo!,"Encore une pièce du Sigil. Nous nous rapprochons de la liberté, et tu te rapproche aussi de moi. Retournons à l'Oracle!",Még egy pecsét darab. Egy lépéssel közelebb állunk a szabadsághoz. Te pedig egy lépéssel közelebb vagy hozzám. menjünk vissza az orákulumhoz.,Un altro pezzo del Sigillo. Siamo ancora più vicini alla libertà. E tu sei ancora più vicino a me. Ritorniamo all'Oracolo!,"更なるシジルの欠片だ。私達の自由にまた一歩近づいたわ。 -そして私にも一歩近づいている。",또 다른 시질 조각이야. 자유로 향하는 길이 거의 얼마 남지 않았어. 그리고 나와 만날 순간도 얼마 남지 않았고. 오라클을 만나러 가자!,Nog een Sigil-peijsje. We zijn een stap dichter bij de vrijheid. En je bent een stap dichter bij mij. Laten we teruggaan naar het Orakel!,Enda en Sigil-brikke. Vi er ett skritt nærmere friheten. Og du er ett skritt nærmere meg. La oss gå tilbake til Orakelet!,Kolejny kawałek Sigil. Jesteśmy o krok bliżej wolności. A ty jesteś o krok bliżej mnie. Wracajmy do Wyroczni!,Outra peça do Sigilo. Estamos nos aproximando da liberdade. E você está ficando mais próximo de mim. Vamos voltar para o Oráculo!,,Altă piesă din Sigiliu. Suntem cu un pas mai aproape de libertate. Și tu ești cu un pas mai aproape de mne. Să ne întoarcem la Oracol.,Очередной фрагмент Печати. Теперь мы ещё на шаг ближе к освобождению. А ты — ещё на шаг ближе ко мне. Давай возвращаться к Оракулу!,,Başka bir Sigil parçası. Özgürlüğe bir adım daha yaklaştık. Ve sen de bana bir adım daha yaklaştın. Kahin'e geri dönelim! +そして私にも一歩近づいている。",또 다른 시질 조각이야. 자유로 향하는 길이 거의 얼마 남지 않았어. 그리고 나와 만날 순간도 얼마 남지 않았고. 오라클을 만나러 가자!,Nog een Sigil-peijsje. We zijn een stap dichter bij de vrijheid. En je bent een stap dichter bij mij. Laten we teruggaan naar het Orakel!,Enda en Sigil-brikke. Vi er ett skritt nærmere friheten. Og du er ett skritt nærmere meg. La oss gå tilbake til Orakelet!,Kolejny kawałek Sigil. Jesteśmy o krok bliżej wolności. A ty jesteś o krok bliżej mnie. Wracajmy do Wyroczni!,Outra peça do Sigilo. Estamos nos aproximando da liberdade. E você está ficando mais próximo de mim. Vamos voltar para o Oráculo!,,Altă piesă din Sigiliu. Suntem cu un pas mai aproape de libertate. Și tu ești cu un pas mai aproape de mne. Să ne întoarcem la Oracol.,Очередной фрагмент Печати. Теперь мы ещё на шаг ближе к освобождению. А ты — ещё на шаг ближе ко мне. Давай возвращаться к Оракулу!,,Ännu en Sigil-bit. Vi är ett steg närmare friheten. Och du är ett steg närmare mig. Låt oss gå tillbaka till Oraklet!,Başka bir Sigil parçası. Özgürlüğe bir adım daha yaklaştık. Ve sen de bana bir adım daha yaklaştın. Kahin'e geri dönelim! You wield the power of the complete Sigil. What do you say we get some closure. Let's see what the Loremaster's been protecting.,TXT_ILOG85,,,,"Vládneš mocí složené Pečetě. Co říkáš na to, jít s tím vším skončit? Pojďme se podívat, co to Dějepisec bránil.","Du har magten af det komplette Sigil. Hvad siger du til, at vi får en afslutning? Lad os se, hvad Loremesteren har beskyttet.","Du hältst die Kraft des kompletten Sigils in deinen Händen. Meinst du nicht auch, wir sollten die Sache jetzt zu Ende bringen? Lass und nachsehen, was der Wissensmeister beschützt hat.",,,Empuñas el poder del Emblema completo. Que te parece si conseguimos algo de clausura. Vamos a ver lo que el Maestro del Conocimiento ha estado protegiendo.,Manejas el poder completo del Emblema. ¿Qué dices si conseguimos algún cierre? Veamos qué ha estado protegiendo el Maestro del Conocimiento.,"Täyden Sinetin voima on hallussasi. Mitäpä jos hakisimme päätöstä. Katsotaan, mitä Oppi-Isä oikein on varjellut.",Tu as maintenant le plein pouvoir du Sigil. Je pense qu'il est l'heure d'en finir. Allons voir ce que le Maître des Traditions cachait.,"A kompett pecsét hatalma a kezedben van. Mit szólsz ahhoz, hogy lezárjuk végleg ezt a harcot. Nézzük meg mit is védelmez a Tanmester valójában.",Hai il potere del Sigillo completo. Che ne dici di finire questa storia. Vediamo un pò cosa il Sapiente stava proteggendo.,"貴方はもはや完全なシジルの力を行使できるわけね。 -後は言いがかりでもしてここを閉鎖させましょう。",시질의 완전한 힘은 이제 네 손에 있어. 종지부를 찍을 준비 됐어? 로어마스터가 그토록 지키던 게 무엇인지 확인하자고.,Je gebruikt de kracht van de volledige Sigil. Wat zeg je ervan als we de zaak afsluiten. Laten we eens kijken wat de Kennismeester heeft beschermd.,Du har makten til hele sigillet. Hva sier du til at vi får en avslutning? La oss se hva Loremaster har beskyttet.,"Władasz mocą kompletnego Sigilu. Co powiesz na to, żebyśmy się zamknęli. Zobaczmy, co Loremaster chronił.",Você tem o poder do Sigilo completo nas suas mãos. O que acha de termos um desfecho? Vamos ver o que o Mestre do Conhecimento andou protegendo.,,Ai puterea întregului Sigiliu. Ce zici dacă avem parte de un sfârșit. Să vedem ce poate prezice Maestrul Cunoștiințelor.,"Теперь ты владеешь мощью завершённой Печати. Мы уже близко — давай покончим с этим. Посмотрим, что же охранял Хранитель мудрости.",,"Sigil'in tamamının gücüne sahipsin. Ne dersin, biraz kapanış yapalım mı? Loremaster'ın neyi koruduğunu görelim." +後は言いがかりでもしてここを閉鎖させましょう。",시질의 완전한 힘은 이제 네 손에 있어. 종지부를 찍을 준비 됐어? 로어마스터가 그토록 지키던 게 무엇인지 확인하자고.,Je gebruikt de kracht van de volledige Sigil. Wat zeg je ervan als we de zaak afsluiten. Laten we eens kijken wat de Kennismeester heeft beschermd.,Du har makten til hele sigillet. Hva sier du til at vi får en avslutning? La oss se hva Loremaster har beskyttet.,"Władasz mocą kompletnego Sigilu. Co powiesz na to, żebyśmy się zamknęli. Zobaczmy, co Loremaster chronił.",Você tem o poder do Sigilo completo nas suas mãos. O que acha de termos um desfecho? Vamos ver o que o Mestre do Conhecimento andou protegendo.,,Ai puterea întregului Sigiliu. Ce zici dacă avem parte de un sfârșit. Să vedem ce poate prezice Maestrul Cunoștiințelor.,"Теперь ты владеешь мощью завершённой Печати. Мы уже близко — давай покончим с этим. Посмотрим, что же охранял Хранитель мудрости.",,Du har makten över hela Sigil. Vad sägs om att vi får ett avslut. Låt oss se vad Läromästaren har skyddat.,"Sigil'in tamamının gücüne sahipsin. Ne dersin, biraz kapanış yapalım mı? Loremaster'ın neyi koruduğunu görelim." "Well, so much for prognostication. Hold it, Macil is calling us back. Let's get out of here in one piece.",TXT_ILOG87,,,,"No, tak to by bylo pro předpovědi. Počkej, Macil nás volá zpět. Vypadněme odsud vcelku.","Nå, så meget for prognoser. Vent, Macil kalder os tilbage. Lad os komme ud herfra i ét stykke.","Soviel zum Thema Vorhersagen. Warte, Macil ruft uns zurück. Lass uns hier heile herauskommen.",,,"Bueno, tanto por un presentimiento. Espera, Macil nos reclama. Salgamos de aquí de una pieza.","Bueno, tanto para el pronóstico. Espera, Macil nos está llamando de vuelta. Salgamos de aquí en una pieza.","No, se siitä ennustelusta. Odota, Macil kutsuu meitä takaisin. Häivytään täältä ehjin nahoin.","Bon, je pense que l'heure n'est plus au pronostics.. Attends, Macil nous appelle. Sortons d'ici en vie, si possible.","Hát, ennyit a jóslatról. Várj, Macil visszahív minket. Húzzunk innen míg egy darabban vagyunk.","Alla faccia dei prognostici... Aspetta, Macil ci sta richiamando. Meglio uscire da qua tutti interi.","まあ予言なんてそんなものでしょ。 -ちょっと待って、マシルが帰還するように言ったわ。ここから抜け出しましょう。","웃기네. 이딴 예언 따위. 잠깐만, 마실이 우리들을 부르고 있어. 이제 안전하게 기지로 돌아가자.","Nou, tot zover de prognose. Wacht even, Macil belt ons terug. Laten we hier heelhuids weggaan.","Så mye for spådommer. Vent, Macil kaller oss tilbake. La oss komme oss helskinnet ut herfra.","Cóż, to tyle jeśli chodzi o prognozowanie. Czekajcie, Macil nas wzywa. Wydostańmy się stąd w jednym kawałku.","Bem, acho que ainda não é hora de previsões. Espera, o Macil está nos chamando de volta. Vamos tentar sair daqui inteiros.",,"Atât a fost cu prognoza. Stai, Macil ne sună înapoi. Să ieșim de aici întregi.","Да, это превзошло все наши ожидания. Успокойся, Мэйсил вызывает нас назад. Давай выбираться отсюда.",,"Kehanet için çok fazla. Durun, Macil bizi geri çağırıyor. Buradan tek parça halinde çıkalım." +ちょっと待って、マシルが帰還するように言ったわ。ここから抜け出しましょう。","웃기네. 이딴 예언 따위. 잠깐만, 마실이 우리들을 부르고 있어. 이제 안전하게 기지로 돌아가자.","Nou, tot zover de prognose. Wacht even, Macil belt ons terug. Laten we hier heelhuids weggaan.","Så mye for spådommer. Vent, Macil kaller oss tilbake. La oss komme oss helskinnet ut herfra.","Cóż, to tyle jeśli chodzi o prognozowanie. Czekajcie, Macil nas wzywa. Wydostańmy się stąd w jednym kawałku.","Bem, acho que ainda não é hora de previsões. Espera, o Macil está nos chamando de volta. Vamos tentar sair daqui inteiros.",,"Atât a fost cu prognoza. Stai, Macil ne sună înapoi. Să ieșim de aici întregi.","Да, это превзошло все наши ожидания. Успокойся, Мэйсил вызывает нас назад. Давай выбираться отсюда.",,"Tja, så mycket för prognoser. Vänta, Macil kallar oss tillbaka. Låt oss komma härifrån i ett stycke.","Kehanet için çok fazla. Durun, Macil bizi geri çağırıyor. Buradan tek parça halinde çıkalım." "The factory is next to the mines. Richter must mean the mines of Degnin. The Degnin ore is magnetic and explosive, just the thing for shutting down force fields. Let's get that key from the catacombs, and then off to the mines for some ore.",TXT_ILOG89,,,,"Továrna je vedle dolů. Richter musí mít na mysli doly degninu. Degninská ruda je magnetická a výbušná, perfektní pro vypnutí silového pole. Pojďme z katakomb dostat ten klíč a pak do dolů pro trochu rudy.","Fabrikken ligger ved siden af minerne. Richter må mene Degnin-minerne. Degnin malmen er magnetisk og eksplosiv, lige til at lukke kraftfelter ned med. Lad os hente nøglen fra katakomberne og så til minerne efter malm.","Die Fabrik liegt neben den Minen. Richter muss von den Degnin-Minen reden. Dasa Degnin-Erz ist magnetisch und explosiv., genau das, was wir brauchen, um die Kraftfelder auszuschalten. Lass uns den Schlüssel aus den Katakomben holen, und dann ab in die Minen für etwas Erz.",,,"La fábrica está junto a las minas. Richter debe referirse a las minas de Degnin. El mineral Degnin es magnético y explosivo, justo como para apagar campos de fuerza. Obtengamos esa llave de las catacumbas y luego derechos a las minas a por algo de mineral.",,"Tehdas on kaivoksen vieressä. Richter varmastikin tarkoittaa Degninin kaivosta. Degnin-malmi on magneettista ja räjähdysherkkää, juuri omiaan purkamaan voimakenttiä. Noudetaan avain katakombeista ja sitten matkataan kaivokselle hakemaan malmia.","L'usine est près des mines. Richter doit parler des mines de degnin. Le minérai de degnin est magnétisé et explosif, c'est parfait pour désactiver les champs de force. Récupérons la clé dans les catacombes, puis partons pour les mines pour récupérer du minerai.","A gyár a bánya mellett van. Richter valószínűleg Degnin bányáira gondolt. A degnini érc mágneses és robbanékony, pont tökéletes lesz az erőpajzs kiiktatásához. Menjünk és szerezzük meg azt a kulcsot a katakombákból, és aztán a bányába egy kis ércért.","La Fabbrica si trova accanto alle miniere. Richter starà parlando delle miniere di Degnin. I minerali di Degnin sono magnetici ed esplosivi, giusto ciò che ci serve per disattivare i campi di forza. Prendiamo quella chiave dalle catacombe, e poi andiamo alle miniere a prendere un pò di quei minerali.","工場は鉱山の隣にあるわ。リヒターはデグニン鉱山とも呼んでいる。 デグニン石は綺麗だが可燃性で、フォースフィールドを消すにはうってつけよ。 -そこへのキーを地下墓所から取り、鉱山に向かおう。","공장은 광산 옆에 있어. 아마도 릭터는 데그닌 갱도를 예기한 것 같아. 데그닌 광석은 폭발성이 있는 자기력이 감도는 물질이야. 방어막을 끌 중요한 도구이기도 하지. 고대 무덤에서 그 열쇠를 얻고, 광석을 얻을 광산으로 향하자.","De fabriek ligt naast de mijnen. Richter moet de mijnen van Degnin bedoelen. Het Degnin-erts is magnetisch en explosief, precies het ding voor het afsluiten van krachtvelden. Laten we die sleutel uit de catacomben halen, en dan naar de mijnen gaan voor wat erts.","Fabrikken ligger ved siden av gruvene. Richter må mene gruvene i Degnin. Degnin-malmen er magnetisk og eksplosiv, akkurat det som skal til for å slå ut kraftfelt. La oss hente nøkkelen fra katakombene, og så dra til gruvene etter malm.","Fabryka jest obok kopalni. Richter musi mieć na myśli kopalnie w Degnin. Ruda Degnin jest magnetyczna i wybuchowa, w sam raz do wyłączania pól siłowych. Zdobądźmy ten klucz z katakumb, a potem ruszajmy do kopalni po rudę.","A fábrica fica próxima às minas. O Richter deve estar se referindo às minas de Degnin. O minério de Degnin é magnético e explosivo, o ideal para derrubar campos de força. Vamos pegar aquela chave das catacumbas e depois vamos para as minas pegar esse minério.",,"Fabrica e lângă mine, Richter se referă la minele din Degnin. Minereul de Degni e magnetic și exploziv, exact ceea ce ne trebuie pentru a opri câmpul de forță. Să luăm cheia aceea din catacombe și să ne îndreptăm înspre mine.","Вход на фабрику — рядом со спуском в шахты. Рихтер, должно быть, имел в виду шахты Дегнина. Дегнинская руда магнитна и взрывоопасна — то, что надо, если хочешь отключить силовое поле. Достань ключ из катакомб, а потом спустись в шахты за рудой.",,"Fabrika madenlerin yanında. Richter, Degnin madenlerini kastediyor olmalı. Degnin cevheri manyetik ve patlayıcıdır, tam da güç alanlarını kapatmak için. Hadi şu anahtarı yeraltı mezarlarından alalım, sonra da biraz cevher için madenlere gidelim." +そこへのキーを地下墓所から取り、鉱山に向かおう。","공장은 광산 옆에 있어. 아마도 릭터는 데그닌 갱도를 예기한 것 같아. 데그닌 광석은 폭발성이 있는 자기력이 감도는 물질이야. 방어막을 끌 중요한 도구이기도 하지. 고대 무덤에서 그 열쇠를 얻고, 광석을 얻을 광산으로 향하자.","De fabriek ligt naast de mijnen. Richter moet de mijnen van Degnin bedoelen. Het Degnin-erts is magnetisch en explosief, precies het ding voor het afsluiten van krachtvelden. Laten we die sleutel uit de catacomben halen, en dan naar de mijnen gaan voor wat erts.","Fabrikken ligger ved siden av gruvene. Richter må mene gruvene i Degnin. Degnin-malmen er magnetisk og eksplosiv, akkurat det som skal til for å slå ut kraftfelt. La oss hente nøkkelen fra katakombene, og så dra til gruvene etter malm.","Fabryka jest obok kopalni. Richter musi mieć na myśli kopalnie w Degnin. Ruda Degnin jest magnetyczna i wybuchowa, w sam raz do wyłączania pól siłowych. Zdobądźmy ten klucz z katakumb, a potem ruszajmy do kopalni po rudę.","A fábrica fica próxima às minas. O Richter deve estar se referindo às minas de Degnin. O minério de Degnin é magnético e explosivo, o ideal para derrubar campos de força. Vamos pegar aquela chave das catacumbas e depois vamos para as minas pegar esse minério.",,"Fabrica e lângă mine, Richter se referă la minele din Degnin. Minereul de Degni e magnetic și exploziv, exact ceea ce ne trebuie pentru a opri câmpul de forță. Să luăm cheia aceea din catacombe și să ne îndreptăm înspre mine.","Вход на фабрику — рядом со спуском в шахты. Рихтер, должно быть, имел в виду шахты Дегнина. Дегнинская руда магнитна и взрывоопасна — то, что надо, если хочешь отключить силовое поле. Достань ключ из катакомб, а потом спустись в шахты за рудой.",,"Fabriken ligger bredvid gruvorna. Richter måste mena Degnins gruvor. Degninmalmen är magnetisk och explosiv, precis vad man behöver för att stänga av kraftfält. Låt oss hämta nyckeln från katakomberna och sedan iväg till gruvorna för att hämta malm.","Fabrika madenlerin yanında. Richter, Degnin madenlerini kastediyor olmalı. Degnin cevheri manyetik ve patlayıcıdır, tam da güç alanlarını kapatmak için. Hadi şu anahtarı yeraltı mezarlarından alalım, sonra da biraz cevher için madenlere gidelim." "The factory is next to the mines. The Degnin ore is magnetic and explosive, just the thing for shutting down force fields. Let's get that key from the catacombs, and then we go down for some ore. This must be the ruins Richter's agents were searching for, be careful.",TXT_ILOG93,,,,"Továrna je vedle dolů. Degninská ruda je magnetická a výbušná, perfektní pro vypnutí silového pole. Pojďme z katakomb dostat ten klíč a pak do dolů pro trochu rudy. Tohle musí být ty ruiny, které Richterovi agenti hledali, buď opatrný.","Fabrikken ligger ved siden af minerne. Degnin-malmen er magnetisk og eksplosiv og er lige til at lukke kraftfelter ned med. Lad os hente nøglen fra katakomberne, og så går vi ned efter noget malm. Dette må være ruinerne, som Richters agenter ledte efter, vær forsigtig.","Die Fabrik liegt neben den Minen. Richter muss von den Degnin-Minen reden. Dasa Degnin-Erz ist magnetisch und explosiv., genau das, was wir brauchen, um die Kraftfelder auszuschalten. Lass uns den Schlüssel aus den Katakomben holen, und dann ab in die Minen für etwas Erz. Dies müssen die Ruinen sein, die Richters Agenten gesucht haben. Sei vorsichtig.",,,"La fábrica está junto a las minas. El mineral Degnin es magnético y explosivo, justo vomo para apagar campos de fuerza. Obtengamos esa llave de las catacumbas y luego derechos a las minas a por algo de mineral. Estas deben de ser las ruínas que los agentes de Richter estaban buscando, ten cuidado.",,"Tehdas on kaivoksen vieressä. Degnin-malmi on magneettista ja räjähdysherkkää, juuri omiaan purkamaan voimakenttiä. Noudetaan avain katakombeista ja mennään sitten alas hakemaan malmia. Nämä ovat varmaankin ne rauniot, joita Richterin joukot olivat etsineet; ole varovainen.","L'usine est près des mines. Richter doit parler des mines de degnin. Le minérai de degnin est magnétisé et explosif, c'est parfait pour désactiver les champs de force. Récupérons la clé dans les catacombes, puis partons pour les mines pour récupérer du minerai. Cela doit être les ruines que les agent de Richter cherchaient. Fais attention.","A gyár a bánya mellett van. A degnini érc mágneses és robbanékony, pont tökéletes lesz az erőpajzs kiiktatásához. Menjünk és szerezzük meg azt a kulcsot a katakombákból, és aztán a bányába egy kis ércért. Valószínű, hogy ezek azok a romok, amelyeket Richter ügynökei kerestek, légy óvatos.","La Fabbrica si trova accanto alle miniere. I minerali di Degnin sono magnetici ed esplosivi, giusto ciò che ci serve per disattivare i campi di forza. Prendiamo quella chiave dalle catacombe, e poi andiamo alle miniere a prendere un pò di quei minerali. Devono essere queste le rovine che gli agenti di Richter stavano esplorando, fai attenzione.","工場は鉱山の隣にあるわ。リヒターはデグニン鉱山とも呼んでいる。 デグニン石は綺麗だが可燃性で、フォースフィールドを消すにはうってつけよ。 そこへのキーを地下墓所から取り、鉱山に向かおう。 -ここがリヒターのエージェントが探していた遺跡のはず。気を付けて。",공장은 광산 옆에 있어. 데그닌 광석은 폭발성이 있는 자기력이 감도는 물질이야. 방어막을 끌 중요한 도구이기도 하지. 고대 묘지에 가서 열쇠를 얻고 광석을 좀 구하자. 릭터의 요원들이 정찰하다 사라진 폐허인 것 같아. 조심해.,"De fabriek is naast de mijnen. Het Degnin-erts is magnetisch en explosief, precies het ding voor het afsluiten van krachtvelden. Laten we die sleutel uit de catacomben halen, en dan gaan we naar beneden voor wat erts. Dit moeten de ruïnes zijn waar Richter's agenten naar op zoek waren, wees voorzichtig.","Fabrikken ligger ved siden av gruvene. Degnin-malmen er magnetisk og eksplosiv, akkurat tingen for å stenge ned kraftfelt. Vi henter nøkkelen i katakombene, og så går vi ned etter malm. Dette må være ruinene Richters agenter lette etter. Vær forsiktig.","Fabryka jest obok kopalni. Ruda Degnin jest magnetyczna i wybuchowa, idealna do wyłączania pól siłowych. Zdobądźmy ten klucz z katakumb, a potem zejdźmy na dół po rudę. To muszą być ruiny, których szukali agenci Richtera, bądźcie ostrożni.","A fábrica fica próxima às minas. O minério de Degnin é magnético e explosivo, o ideal para derrubar campos de força. Vamos pegar aquela chave das catacumbas e ir atrás desse minério. Essas devem ser as ruínas que os agentes do Richter estavam procurando. Tome cuidado.",,"Fabrica e lângă mine, Richter se referă la minele din Degnin. Minereul de Degni e magnetic și exploziv, exact ceea ce ne trebuie pentru a opri câmpul de forță. Să luăm cheia aceea din catacombe și să ne îndreptăm înspre mine.","Вход на фабрику — рядом со спуском в шахты. Дегнинская руда магнитна и взрывоопасна — то, что надо, если хочешь отключить силовое поле. Достань ключ в катакомбах, а потом спустись за рудой. Должно быть, именно эти руины искали агенты Рихтера. Будь осторожен.",,"Fabrika madenlerin yanında. Degnin cevheri manyetik ve patlayıcıdır, güç alanlarını kapatmak için birebirdir. Hadi şu anahtarı yeraltı mezarlarından alalım, sonra da biraz cevher için aşağı inelim. Burası Richter'in ajanlarının aradığı kalıntılar olmalı, dikkatli ol." +ここがリヒターのエージェントが探していた遺跡のはず。気を付けて。",공장은 광산 옆에 있어. 데그닌 광석은 폭발성이 있는 자기력이 감도는 물질이야. 방어막을 끌 중요한 도구이기도 하지. 고대 묘지에 가서 열쇠를 얻고 광석을 좀 구하자. 릭터의 요원들이 정찰하다 사라진 폐허인 것 같아. 조심해.,"De fabriek is naast de mijnen. Het Degnin-erts is magnetisch en explosief, precies het ding voor het afsluiten van krachtvelden. Laten we die sleutel uit de catacomben halen, en dan gaan we naar beneden voor wat erts. Dit moeten de ruïnes zijn waar Richter's agenten naar op zoek waren, wees voorzichtig.","Fabrikken ligger ved siden av gruvene. Degnin-malmen er magnetisk og eksplosiv, akkurat tingen for å stenge ned kraftfelt. Vi henter nøkkelen i katakombene, og så går vi ned etter malm. Dette må være ruinene Richters agenter lette etter. Vær forsiktig.","Fabryka jest obok kopalni. Ruda Degnin jest magnetyczna i wybuchowa, idealna do wyłączania pól siłowych. Zdobądźmy ten klucz z katakumb, a potem zejdźmy na dół po rudę. To muszą być ruiny, których szukali agenci Richtera, bądźcie ostrożni.","A fábrica fica próxima às minas. O minério de Degnin é magnético e explosivo, o ideal para derrubar campos de força. Vamos pegar aquela chave das catacumbas e ir atrás desse minério. Essas devem ser as ruínas que os agentes do Richter estavam procurando. Tome cuidado.",,"Fabrica e lângă mine, Richter se referă la minele din Degnin. Minereul de Degni e magnetic și exploziv, exact ceea ce ne trebuie pentru a opri câmpul de forță. Să luăm cheia aceea din catacombe și să ne îndreptăm înspre mine.","Вход на фабрику — рядом со спуском в шахты. Дегнинская руда магнитна и взрывоопасна — то, что надо, если хочешь отключить силовое поле. Достань ключ в катакомбах, а потом спустись за рудой. Должно быть, именно эти руины искали агенты Рихтера. Будь осторожен.",,"Fabriken ligger bredvid gruvorna. Degninmalmen är magnetisk och explosiv, precis vad man behöver för att stänga av kraftfält. Vi hämtar nyckeln från katakomberna och går sedan ner för att hämta malm. Detta måste vara ruinerna som Richters agenter sökte efter, var försiktig.","Fabrika madenlerin yanında. Degnin cevheri manyetik ve patlayıcıdır, güç alanlarını kapatmak için birebirdir. Hadi şu anahtarı yeraltı mezarlarından alalım, sonra da biraz cevher için aşağı inelim. Burası Richter'in ajanlarının aradığı kalıntılar olmalı, dikkatli ol." "The factory is next to the mines. The Degnin ore is magnetic and explosive, just the thing for shutting down force fields. My friend, whatever it is we're fighting, it's more than just the Order. Back to the commons then off to the mines. We need ore.",TXT_ILOG95,,,,"Továrna je vedle dolů. Degninská ruda je magnetická a výbušná, perfektní pro vypnutí silového pole. Příteli, ať už bojujeme s čímkoliv, jde o víc než jen Řád. Zpátky na náves a pak do dolů. Potřebujeme rudu.","Fabrikken ligger ved siden af minerne. Degnin-malmen er magnetisk og eksplosiv, lige til at lukke kraftfelter ned med. Min ven, hvad det end er, vi kæmper imod, er det mere end bare Ordenen. Tilbage til fællesrummet og så til minerne. Vi har brug for malm.","Die Fabrik liegt neben den Minen. Richter muss von den Degnin-Minen reden. Dasa Degnin-Erz ist magnetisch und explosiv., genau das, was wir brauchen, um die Kraftfelder auszuschalten. Mein Freund, was immer wir hier bekämpfen, es ist mehr als der Orden. Zurück zur Mensa, und dann ab in die Minen. Wir brauchen Erz.",,,"La fábrica está junto a las minas. El mineral Degnin es magnético y explosivo, justo como para apagar campos de fuerza. Amigo, lo que sea contra lo que estamos luchando, es más que solo La Orden. Volvamos a los comunes y luego derechos a las minas. Necesitamos mineral.",,"Tehdas on kaivoksen vieressä. Degnin-malmi on magneettista ja räjähdysherkkää, juuri omiaan purkamaan voimakenttiä. Ystäväni, mitä vastaan me taistelemmekaan, se on suurempi kuin pelkkä Veljeskunta. Palatkaamme messiin, josta sitten kaivokseen. Tarvitsemme malmia.","L'usine est près des mines. Richter doit parler des mines de degnin. Le minérai de degnin est magnétisé et explosif, c'est parfait pour désactiver les champs de force. Mon ami, c'est clair que l'on se bat contre plus que juste l'Ordre. Retournons au réfectoire puis aux mines. Il nous faut du minerai.","A gyár a bánya mellett van. A degnini érc mágneses és robbanékony, pont tökéletes lesz az erőpajzs kiiktatásához. Barátom, akármi ellen is harcolunk, több mint a Rend maga. Irány vissza a menzára, aztán a bánya. Szükségünk van ércre.","La Fabbrica si trova accanto alle miniere. I minerali di Degnin sono magnetici ed esplosivi, giusto ciò che ci serve per disattivare i campi di forza. Amico mio, qualsiasi cosa stiamo combattendo, è molto di più del solo Ordine. Ritorniamo ai comuni e poi alle miniere. Ci serve quel minerale.","工場は鉱山の隣にあるわ。リヒターはデグニン鉱山とも呼んでいる。 デグニン石は綺麗だが可燃性で、フォースフィールドを消すにはうってつけよ。 友よ、私達が戦う相手が何であろうとも、オーダー以上のものはない。 -鉱山から離れましょう!","공장은 광산 옆에 있어. 데그닌 광석은 폭발성이 있는 자기력이 감도는 물질이야. 방어막을 끌 중요한 도구이기도 하지. 싸우는 상대가 무엇인지는 모르겠지만, 오더보다 더한 존재인 것 같아. 식당가로 향한 뒤 광산으로 들어가. 광석이 필요하니까.","De fabriek ligt naast de mijnen. Het Degnin-erts is magnetisch en explosief, precies het ding voor het afsluiten van krachtvelden. Mijn vriend, wat het ook is waar we tegen vechten, het is meer dan alleen de Orde. Terug naar de commons en dan naar de mijnen. We hebben erts nodig.","Fabrikken ligger ved siden av gruvene. Degnin-malmen er magnetisk og eksplosiv, perfekt til å slå ut kraftfelt. Min venn, hva det enn er vi kjemper mot, er det mer enn bare Ordenen. Tilbake til allmenningen, og så til gruvene. Vi trenger malm.","Fabryka znajduje się obok kopalni. Ruda Degnin jest magnetyczna i wybuchowa. Nadaje się do wyłączania pól siłowych. Mój przyjacielu, cokolwiek to jest, z czym walczymy, to nie tylko Zakon. Wracamy do komnat, a potem do kopalni. Potrzebujemy rudy.","A fábrica fica próxima às minas. O minério de Degnin é magnético e explosivo, o ideal para derrubar campos de força. Meu amigo, seja lá o que estiver combatendo, é mais do que somente a Ordem. Volte ao refeitório e depois vá para as minas. Precisamos desse minério.",,"Fabrica e lângă mine, Richter se referă la minele din Degnin. Minereul de Degni e magnetic și exploziv, exact ceea ce ne trebuie pentru a opri câmpul de forță. Prietene, orice ar fi, ne luptăm cu ceva mai mult decât Ordinul. Înapoi la comune și dupaia, mine. Ne trebuie minereu.","Вход на фабрику — рядом со спуском в шахты. Дегнинская руда магнитна и взрывоопасна — то, что надо, если хочешь отключить силовое поле. Друг мой, с чем бы мы не сражались, это нечто большее, чем просто Орден. Вернись назад в поселение и спустись в шахты. Нам нужна руда.",,"Fabrika madenlerin yanında. Degnin cevheri manyetik ve patlayıcıdır, tam da güç alanlarını kapatmak için. Dostum, savaştığımız şey her neyse, Düzen'den daha fazlası. Avam kamarasına dönüp madenlere gidelim. Cevhere ihtiyacımız var." +鉱山から離れましょう!","공장은 광산 옆에 있어. 데그닌 광석은 폭발성이 있는 자기력이 감도는 물질이야. 방어막을 끌 중요한 도구이기도 하지. 싸우는 상대가 무엇인지는 모르겠지만, 오더보다 더한 존재인 것 같아. 식당가로 향한 뒤 광산으로 들어가. 광석이 필요하니까.","De fabriek ligt naast de mijnen. Het Degnin-erts is magnetisch en explosief, precies het ding voor het afsluiten van krachtvelden. Mijn vriend, wat het ook is waar we tegen vechten, het is meer dan alleen de Orde. Terug naar de commons en dan naar de mijnen. We hebben erts nodig.","Fabrikken ligger ved siden av gruvene. Degnin-malmen er magnetisk og eksplosiv, perfekt til å slå ut kraftfelt. Min venn, hva det enn er vi kjemper mot, er det mer enn bare Ordenen. Tilbake til allmenningen, og så til gruvene. Vi trenger malm.","Fabryka znajduje się obok kopalni. Ruda Degnin jest magnetyczna i wybuchowa. Nadaje się do wyłączania pól siłowych. Mój przyjacielu, cokolwiek to jest, z czym walczymy, to nie tylko Zakon. Wracamy do komnat, a potem do kopalni. Potrzebujemy rudy.","A fábrica fica próxima às minas. O minério de Degnin é magnético e explosivo, o ideal para derrubar campos de força. Meu amigo, seja lá o que estiver combatendo, é mais do que somente a Ordem. Volte ao refeitório e depois vá para as minas. Precisamos desse minério.",,"Fabrica e lângă mine, Richter se referă la minele din Degnin. Minereul de Degni e magnetic și exploziv, exact ceea ce ne trebuie pentru a opri câmpul de forță. Prietene, orice ar fi, ne luptăm cu ceva mai mult decât Ordinul. Înapoi la comune și dupaia, mine. Ne trebuie minereu.","Вход на фабрику — рядом со спуском в шахты. Дегнинская руда магнитна и взрывоопасна — то, что надо, если хочешь отключить силовое поле. Друг мой, с чем бы мы не сражались, это нечто большее, чем просто Орден. Вернись назад в поселение и спустись в шахты. Нам нужна руда.",,"Fabriken ligger bredvid gruvorna. Degninmalmen är magnetisk och explosiv, precis vad man behöver för att stänga av kraftfält. Min vän, vad det än är vi slåss mot så är det mer än bara Orden. Tillbaka till allmänningen och sedan till gruvorna. Vi behöver malm.","Fabrika madenlerin yanında. Degnin cevheri manyetik ve patlayıcıdır, tam da güç alanlarını kapatmak için. Dostum, savaştığımız şey her neyse, Düzen'den daha fazlası. Avam kamarasına dönüp madenlere gidelim. Cevhere ihtiyacımız var." "The factory is next to the mines. The degnin ore is magnetic and explosive, just the thing for shutting down force fields. Without letting down your guard, look for deposits of ore.",TXT_ILOG96,,,,"Továrna je vedle dolů. Degninská ruda je magnetická a výbušná, perfektní pro vypnutí silového pole. Opatrně se podívej po ložiscích rudy.","Fabrikken ligger ved siden af minerne. Degninmalmen er magnetisk og eksplosiv, lige det rigtige til at lukke kraftfelter. Uden at sænke din vagt, skal du lede efter forekomster af malm.","Die Fabrik liegt neben den Minen. Richter muss von den Degnin-Minen reden. Dasa Degnin-Erz ist magnetisch und explosiv., genau das, was wir brauchen, um die Kraftfelder auszuschalten. Lass uns nach Erz suchen, aber wir müssen vorsichtig sein.",,,"La fábrica está junto a las minas. El mineral Degnin es magnético y explosivo, justo como para apagar campos de fuerza. Sin bajar la guardia, busca depósitos de mineral.",,"Tehdas on kaivoksen vieressä. Degnin-malmi on magneettista ja räjähdysherkkää, juuri omiaan purkamaan voimakenttiä. Etsi malmiesiintymiä varuillasi pysyen.","L'usine est près des mines. Richter doit parler des mines de degnin. Le minérai de degnin est magnétisé et explosif, c'est parfait pour désactiver les champs de force. Cherche des veines de minerai, mais fais attention.","A gyár a bánya mellett van. A degnini érc mágneses és robbanékony, pont tökéletes lesz az erőpajzs kiiktatásához. Figyelj az érc lerakódásokra, de közben figyelj magadra is.","La Fabbrica si trova accanto alle miniere. I minerali di Degnin sono magnetici ed esplosivi, giusto ciò che ci serve per disattivare i campi di forza. Senza abbassare la guardia, cerca di trovare alcuni depositi di minerali.","工場は鉱山の隣にあるわ。リヒターはデグニン鉱山とも呼んでいる。 デグニン石は綺麗だが可燃性で、フォースフィールドを消すにはうってつけよ。 -警戒を緩めることなく、鉱石の堆積所を探しましょう。","공장은 광산 옆에 있어. 데그닌 광석은 폭발성이 있는 자기력이 감도는 물질이야. 방어막을 끌 중요한 도구이기도 하지. 자신을 지킬 준비 단단히 하고, 캔 광석을 두는 곳을 찾아.","De fabriek ligt naast de mijnen. Het degnin-erts is magnetisch en explosief, precies het ding voor het afsluiten van krachtvelden. Zonder je waakzaamheid te laten verslappen, zoek je naar ertsafzettingen.","Fabrikken er ved siden av gruvene. Degnin-malmen er magnetisk og eksplosiv, akkurat det vi trenger for å slå ut kraftfeltene. Uten å senke guarden, se etter forekomster av malm.","Fabryka jest obok kopalni. Ruda degnin jest magnetyczna i wybuchowa, w sam raz do wyłączania pól siłowych. Nie tracąc czujności, szukajcie złóż rudy.","A fábrica fica próxima às minas. O minério de Degnin é magnético e explosivo, o ideal para derrubar campos de força. Não baixe a sua guarda e procure pelos depósitos de minério.",,"Fabrica e lângă mine. Minereul de Degnin e magnetic și exploziv, exact ceea ce ne trebuie pentru câmpul de forță. Fără a lăsa garda jos, uită-te după depozite de minereu.","Вход на фабрику — рядом со спуском в шахты. Дегнинская руда магнитна и взрывоопасна — то, что надо, если хочешь отключить силовое поле. Поищи залежи руды, но не теряй бдительности!",,"Fabrika madenlerin yanında. Degnin cevheri manyetik ve patlayıcıdır, tam da güç alanlarını kapatmak için. Gardınızı düşürmeden, cevher yataklarını arayın." +警戒を緩めることなく、鉱石の堆積所を探しましょう。","공장은 광산 옆에 있어. 데그닌 광석은 폭발성이 있는 자기력이 감도는 물질이야. 방어막을 끌 중요한 도구이기도 하지. 자신을 지킬 준비 단단히 하고, 캔 광석을 두는 곳을 찾아.","De fabriek ligt naast de mijnen. Het degnin-erts is magnetisch en explosief, precies het ding voor het afsluiten van krachtvelden. Zonder je waakzaamheid te laten verslappen, zoek je naar ertsafzettingen.","Fabrikken er ved siden av gruvene. Degnin-malmen er magnetisk og eksplosiv, akkurat det vi trenger for å slå ut kraftfeltene. Uten å senke guarden, se etter forekomster av malm.","Fabryka jest obok kopalni. Ruda degnin jest magnetyczna i wybuchowa, w sam raz do wyłączania pól siłowych. Nie tracąc czujności, szukajcie złóż rudy.","A fábrica fica próxima às minas. O minério de Degnin é magnético e explosivo, o ideal para derrubar campos de força. Não baixe a sua guarda e procure pelos depósitos de minério.",,"Fabrica e lângă mine. Minereul de Degnin e magnetic și exploziv, exact ceea ce ne trebuie pentru câmpul de forță. Fără a lăsa garda jos, uită-te după depozite de minereu.","Вход на фабрику — рядом со спуском в шахты. Дегнинская руда магнитна и взрывоопасна — то, что надо, если хочешь отключить силовое поле. Поищи залежи руды, но не теряй бдительности!",,"Fabriken ligger bredvid gruvorna. Degninmalmen är magnetisk och explosiv, precis vad vi behöver för att stänga av kraftfält. Utan att sänka garden, leta efter malmfyndigheter.","Fabrika madenlerin yanında. Degnin cevheri manyetik ve patlayıcıdır, tam da güç alanlarını kapatmak için. Gardınızı düşürmeden, cevher yataklarını arayın." "Without letting down your guard, look for deposits of ore. These poor souls are drones. Their synaptic functions are being jammed by RC implants. We destroy the transmitter, and they're free.",TXT_ILOG97,,,,"Opatrně se podívej po ložiscích rudy. Tihle chudáci jsou trubcové, jejich synaptické funkce jsou narušené na dálku ovládanými implantáty. Když zničíme vysílačku, budou svobodní!","Uden at sænke paraderne, skal du lede efter malmforekomster. Disse stakkels sjæle er droner. Deres synaptiske funktioner bliver blokeret af RC-implantater. Vi ødelægger senderen, og så er de frie.","Lass uns nach Erz suchen, aber wir müssen vorsichtig sein. Diese armen Seelen sind wie Drohnen. Ihre Gehirnfunktionen werden von Implantaten blockiert. Wir müssen den Transmitter ausschalten, dann sind sie befreit.",,,"Sin bajar la guardia, busca depósitos de mineral. Estas pobres almas son zánganos. Sus funciones sinápticas están bloqueadas por implantes de control remoto. Destruimos el transmisor, y son libres.","Sin bajar la guardia, busca depósitos de mineral. Estas pobres almas son drones. Sus funciones sinápticas están siendo bloqueadas por implantes rc. Debemos destruir el transmisor y serán libres.","Etsi malmiesiintymiä, kuitenkin valppautesi säilyttäen. Nämä sieluparat ovat kuhnureita: Heidän synaptisia toimintojaan häiritään radio-ohjattavilla istutteilla. Me tuhoamme lähettimen, ja he ovat vapaat.","Cherche des veines de minerai, mais fais attention. Ces pauvres esclaves sont des drones. Leurs fonctions synaptiques sont brouillées par des implants radiocommandés. Détruisons le transmetteur pour les libérer.","Figyelj az érc lerakódásokra, de közben figyelj magadra is. Ezek a szerencsétlen lelkek csak drónok. A szinaptikus funkcióikat zavarják távolról irányítható implantátumokkal. Szétromboljuk a jeladókat, és szabaddá vállnak.","Senza abbassare la guardia, cerca di trovare alcuni depositi di minerali. Questi poveracci sono dei droni. Le loro funzioni cerebrali stanno venendo bloccate da degli impianti. Se distruggiamo il trasmettitore, saranno liberi.","警戒を緩めることなく、鉱石の堆積所を探しましょう。 ここの精神の乏しい労働者達は、RCインプラントでシナプス機能を妨害している。 -私達が送信機を破壊し、皆を解放しよう。","자신을 지킬 준비 단단히 하고, 캔 광석을 두는 곳을 찾아. 저 사람들은 불쌍한 광산의 노예들이야. 오더가 이식한 세뇌 장치 때문에 정상적인 뇌 기능을 잃었지. 전송기만 파괴한다면, 그들은 자유를 되찾을 수 있을 거야.","Zonder je waakzaamheid te laten verslappen, zoek je naar ertsafzettingen. Deze arme zielen zijn drones. Hun synaptische functies worden geblokkeerd door RC-implantaten. We vernietigen de zender en ze zijn vrij.","Uten å senke guarden, se etter malmforekomster. Disse stakkarene er droner. Deres synaptiske funksjoner blokkeres av RC-implantater. Vi ødelegger senderen, og de er fri.","Nie opuszczając gardy, szukaj złóż rudy. Te biedne dusze to drony. Ich funkcje synaptyczne są zagłuszane przez implanty RC. Zniszczymy nadajnik, a oni będą wolni.",Não baixe a sua guarda e procure por depósitos de minério. Esses pobres coitados são zangões. Suas funções sinápticas estão sendo bloqueadas por implantes de controle remoto. Se destruirmos o transmissor eles estarão livres.,,"Fără a lăsa garda jos, uită-te după minereu. Sufletele ăstea sărmane sunt drone. Funcțiile lor sinaptice primesc interferență de la implanturile RC. Distrugem transmițătoarele și sunt libere.","Поищи залежи руды, но не теряй бдительности. Эти несчастные души — дроны. Сигнал, поступающий на импланты, полностью подавляет их сознание. Если мы уничтожим передатчик, они свободны.",,"Gardınızı düşürmeden, cevher yataklarını arayın. Bu zavallı ruhlar dron. Sinaptik fonksiyonları RC implantları tarafından engelleniyor. Vericiyi yok edersek özgür kalırlar." +私達が送信機を破壊し、皆を解放しよう。","자신을 지킬 준비 단단히 하고, 캔 광석을 두는 곳을 찾아. 저 사람들은 불쌍한 광산의 노예들이야. 오더가 이식한 세뇌 장치 때문에 정상적인 뇌 기능을 잃었지. 전송기만 파괴한다면, 그들은 자유를 되찾을 수 있을 거야.","Zonder je waakzaamheid te laten verslappen, zoek je naar ertsafzettingen. Deze arme zielen zijn drones. Hun synaptische functies worden geblokkeerd door RC-implantaten. We vernietigen de zender en ze zijn vrij.","Uten å senke guarden, se etter malmforekomster. Disse stakkarene er droner. Deres synaptiske funksjoner blokkeres av RC-implantater. Vi ødelegger senderen, og de er fri.","Nie opuszczając gardy, szukaj złóż rudy. Te biedne dusze to drony. Ich funkcje synaptyczne są zagłuszane przez implanty RC. Zniszczymy nadajnik, a oni będą wolni.",Não baixe a sua guarda e procure por depósitos de minério. Esses pobres coitados são zangões. Suas funções sinápticas estão sendo bloqueadas por implantes de controle remoto. Se destruirmos o transmissor eles estarão livres.,,"Fără a lăsa garda jos, uită-te după minereu. Sufletele ăstea sărmane sunt drone. Funcțiile lor sinaptice primesc interferență de la implanturile RC. Distrugem transmițătoarele și sunt libere.","Поищи залежи руды, но не теряй бдительности. Эти несчастные души — дроны. Сигнал, поступающий на импланты, полностью подавляет их сознание. Если мы уничтожим передатчик, они свободны.",,Utan att sänka garden letar du efter malmfyndigheter. Dessa stackars själar är drönare. Deras synaptiska funktioner blockeras av RC-implantat. Vi förstör sändaren och de är fria.,"Gardınızı düşürmeden, cevher yataklarını arayın. Bu zavallı ruhlar dron. Sinaptik fonksiyonları RC implantları tarafından engelleniyor. Vericiyi yok edersek özgür kalırlar." "The factory is next to the mines. Without letting down your guard, look for deposits of ore. My suggestion is, toss the ore at the force field and then blast it, the resulting compression should create a magnetic blanket and turn off the lights.",TXT_ILOG99,,,,"Továrna je vedle dolů. Opatrně se podívej po ložiscích rudy. Můj návrh je, hoď rudu na to silové pole a pak ji odstřel. Výsledná komprese by měla vytvořit magnetický povlak a vypnout pole.","Fabrikken ligger ved siden af minerne. Uden at sænke din vagt, skal du lede efter malmforekomster. Mit forslag er, at kaste malmen mod kraftfeltet og derefter sprænge det, den resulterende kompression skulle skabe et magnetisk tæppe og slukke lyset.","Die Fabrik liegt neben den Minen. Lass uns nach Erz suchen, aber wir müssen vorsichtig sein. Ich schlage vor, wir werfen das Erz vor das Krsftfeld und sprengen es dann. Die Druckwelle sollte einen Magnetpuls erzeugen, und die Lichter ausschalten.",,,"La fábrica está junto a las minas. Sin bajar la guardia, busca depósitos de mineral. Mi sugerencia es tirar el mineral hacia el campo de fuerza y luego reventarlo; la presión resultante debería crear un manto magnético y apagar las luces.",,"Tehdas on kaivoksen vieressä. Etsi malmiesiintymiä, kuitenkin valppautesi säilyttäen. Ehdotukseni on, että heität malmin voimakentään ja sitten posautat sen. Syntyvän paineaallon pitäisi muodostaa magneettinen peitto ja sammuttaa valot.","L'usine est près des mines. Cherche des veines de minerai, mais fais attention. Je suggère que tu lance du minerai sur le champ de force et que tu tire dessus. Le champ magnétique que l'explosion causera désactivera les lumières.","A gyár a bánya mellett van. Figyelj az érc lerakódásokra, de közben figyelj magadra is. Azt javaslom, hogy dobd az ércet az erőpajzsra, és robbantsd fel. A robbanástól létrejött kompresszió létre kell hogy hozzon egy mágneses palástot, és ezáltal kikapcsolja a lámpákat.","La Fabbrica si trova accanto alle miniere. Senza abbassare la guardia, cerca di trovare alcuni depositi di minerali. Il mio consiglio è, lancia uno dei minerali al campo di forza e poi fallo saltare in aria. Questo dovrebbe sprigionare l'energia sufficiente a disattivare il campo di forza.","工場は鉱山の隣にあるわ。警戒を緩めることなく、鉱石の堆積所を探しましょう。 私の案はフォースフィールドの近くに鉱石を置き撃って爆発させる方法よ。 -その結果、圧縮されていた磁場の反動で光を打ち消すわ。","공장은 광산 옆에 있어. 자신을 지킬 준비 단단히 하고, 캔 광석을 두는 곳을 찾아. 조언을 찾는다면, 광석을 방어막에 가까이 놔둔 뒤 쏴봐. 광석이 커다란 자기장을 만들 테고, 방어막을 완전히 무력화 시킬 거야.","De fabriek ligt naast de mijnen. Zonder je waakzaamheid te laten verslappen, zoek je naar ertsafzettingen. Mijn suggestie is om het erts naar het krachtveld te gooien en het vervolgens op te blazen, de resulterende compressie zou een magnetische deken moeten creëren en de lichten uit moeten doen.","Fabrikken ligger ved siden av gruvene. Uten å senke garden, se etter malmforekomster. Mitt forslag er å kaste malmen mot kraftfeltet og deretter sprenge den, den resulterende kompresjonen bør skape et magnetisk teppe og slå av lysene.","Fabryka jest obok kopalni. Nie spuszczając gardy, szukajcie złóż rudy. Moja propozycja to, podrzuć rudę na pole siłowe, a następnie wysadź je, powstała kompresja powinna stworzyć koc magnetyczny i wyłączyć światła.",A fábrica fica próxima às minas. Não baixe a sua guarda e procure pelos depósitos de minério. Sugiro que você arremesse o minério ao campo de força e detone ele. A explosão deve gerar um campo magnético que vai apagar as luzes.,,"Fabrica e lăngă mine. Fără a lăsa garda jos uită-te dupa depozite de minereu. Sugestia mea e, aruncă minereul la câmpul de forță și aruncă-l în aer, comprimarea ce va rezulta în urma ei ar trebui să creeze o încărcătură magnetică care va distruge luminile.","Вход на фабрику — рядом со спуском в шахты. Поищи залежи руды, но не теряй бдительности. Мой план: бросить руду поближе к силовому полю и взорвать её. Взрыв создаст магнитное поле, которое накроет электронику и отрубит её.",,"Fabrika madenlerin yanında. Gardınızı düşürmeden, cevher yataklarını arayın. Benim önerim, cevheri güç alanına fırlatın ve sonra patlatın, ortaya çıkan sıkıştırma manyetik bir örtü oluşturmalı ve ışıkları kapatmalıdır." +その結果、圧縮されていた磁場の反動で光を打ち消すわ。","공장은 광산 옆에 있어. 자신을 지킬 준비 단단히 하고, 캔 광석을 두는 곳을 찾아. 조언을 찾는다면, 광석을 방어막에 가까이 놔둔 뒤 쏴봐. 광석이 커다란 자기장을 만들 테고, 방어막을 완전히 무력화 시킬 거야.","De fabriek ligt naast de mijnen. Zonder je waakzaamheid te laten verslappen, zoek je naar ertsafzettingen. Mijn suggestie is om het erts naar het krachtveld te gooien en het vervolgens op te blazen, de resulterende compressie zou een magnetische deken moeten creëren en de lichten uit moeten doen.","Fabrikken ligger ved siden av gruvene. Uten å senke garden, se etter malmforekomster. Mitt forslag er å kaste malmen mot kraftfeltet og deretter sprenge den, den resulterende kompresjonen bør skape et magnetisk teppe og slå av lysene.","Fabryka jest obok kopalni. Nie spuszczając gardy, szukajcie złóż rudy. Moja propozycja to, podrzuć rudę na pole siłowe, a następnie wysadź je, powstała kompresja powinna stworzyć koc magnetyczny i wyłączyć światła.",A fábrica fica próxima às minas. Não baixe a sua guarda e procure pelos depósitos de minério. Sugiro que você arremesse o minério ao campo de força e detone ele. A explosão deve gerar um campo magnético que vai apagar as luzes.,,"Fabrica e lăngă mine. Fără a lăsa garda jos uită-te dupa depozite de minereu. Sugestia mea e, aruncă minereul la câmpul de forță și aruncă-l în aer, comprimarea ce va rezulta în urma ei ar trebui să creeze o încărcătură magnetică care va distruge luminile.","Вход на фабрику — рядом со спуском в шахты. Поищи залежи руды, но не теряй бдительности. Мой план: бросить руду поближе к силовому полю и взорвать её. Взрыв создаст магнитное поле, которое накроет электронику и отрубит её.",,"Fabriken ligger bredvid gruvorna. Utan att sänka garden, leta efter malmfyndigheter. Mitt förslag är att kasta malmen mot kraftfältet och sedan spränga det, den resulterande kompressionen bör skapa en magnetisk filt och släcka ljuset.","Fabrika madenlerin yanında. Gardınızı düşürmeden, cevher yataklarını arayın. Benim önerim, cevheri güç alanına fırlatın ve sonra patlatın, ortaya çıkan sıkıştırma manyetik bir örtü oluşturmalı ve ışıkları kapatmalıdır." Now on to the factory. Exit the mines and you can't miss it. Let's find that machine and shut it down!,TXT_ILOG100,,,,A teď do továrny. Vyjdi z dolů a nemůžeš to minout. Pojďme najít ten stroj a vypnout ho!,"Nu videre til fabrikken. Forlad minerne, og du kan ikke undgå at se den. Lad os finde den maskine og lukke den ned!","Und jetzt zur Fabrik. Verlasse die Minen, du kannst sie nicht verpassen. Lass uns die Maschine finden und abschalten.",,,Ahora vamos a la fábrica. Sal de las minas y no puedes perderlo. ¡Encontremos esa máquina y desactivémosla!,,"Nyt sitten tehtaaseen. Poistu kaivoksesta, ja löydät sen varmasti. Etsitään ja sammutetaan se kone!","C'est parti pour l'usine. Sors des mines, tu ne peux pas la rater. Trouvons cette machine et détruisons-la!","Most pedig a gyár. Rögtön szembe van veled ahogy kilépsz a bányából, nem tudod eltéveszteni. Keressük meg azt a gépet, és állítsuk le!",Ora entriamo nella Fabbrica. Uscendo dalle miniere non puoi sbagliare. Troviamo quella macchina e disattiviamola!,"工場へ今すぐ入ろう。鉱山の出口はすぐわかる。 -機械を探してシャットダウンさせろ!",이제 공장으로 향하자. 광산을 나가봐. 이 순간을 놓치면 안 돼. 얼른 그 기계를 찾아서 작동을 멈추자!,Nu naar de fabriek. Verlaat de mijnen en je kunt het niet missen. Laten we die machine vinden en hem uitschakelen!,"Nå videre til fabrikken. Gå ut av gruvene, og du kan ikke gå glipp av den. La oss finne den maskinen og slå den av!",Teraz przejdź do fabryki. Wyjdź z kopalni i nie możesz jej przegapić. Znajdźmy tę maszynę i wyłączmy ją!,"Agora vá para a fábrica. Ao sair das minas você vai encontrá-la, não tem como errar. Vamos achar essa máquina e desligá-la de vez!",,"Acum înspre fabrică. Ieși din mine, nu o poți rata. Să găsim mașina aia și să o oprim!","Теперь — на фабрику. Выйди из шахты, и ты сразу увидишь вход. Найди эту машину и останови её!",,Şimdi fabrikaya gidelim. Madenlerden çıkın ve onu kaçırmayın. Hadi şu makineyi bulup kapatalım! -I'm reading massive neural wave distortions from straight ahead. I think we've found it. Let's get in there and shut it down!,TXT_ILOG102,,,,"Detekuju obří rušení nervových vln přímo před námi. Myslím, že jsme to našli. Pojďme tam a vypněme to!","Jeg kan se massive neurale bølgeforvrængninger lige forude. Jeg tror, vi har fundet den. Lad os komme ind og lukke den ned!","Ich empfange massive neurale Verzerrungen direkt voraus. Ich denke, wir haben sie gefunden. Lass uns reingehen und sie abschalten.",,,Estoy leyendo distorsiones de ondas neuronales masivas adelante. Creo que la hemos encontrado. ¡Entremos ahí y destruyámosla!,,Havaitsen massivisia hermoaaltovääristymiä suoraan edessä. Luulen löytäneemme sen. Mennään sisään ja sammutetaan se!,Je recois des distorsions neurales colossales devant nous. Je crois que nous l'avons trouvé. Détruisons-la!,Erős ideghullám zavaró jeleket fogok. Azt hiszem megtaláltuk. Menjünk be és állítsuk le!,Sto ricevendo potenti segnali distorti proprio davanti a te. Penso che l'abbiamo trovata. Entriamo e spegnamo questa macchina!,重い神経波歪曲が直に届いたわ。私達はそれを見つけたという事よ。,앞쪽에서 거대한 신경교란 파장이 감지되고 있어. 우리가 찾아낸 것 같아. 어서 들어가서 꺼버리자!,Ik lees enorme neurale golfvervormingen van rechtdoor. Ik denk dat we hem gevonden hebben. Laten we naar binnen gaan en de machine stilleggen!,Jeg leser massive nevrale bølgeforvrengninger rett fram. Jeg tror vi har funnet den. La oss gå inn og slå den av!,Odczytuję potężne zniekształcenia fal neuronowych z prostej drogi. Chyba ją znaleźliśmy. Wejdźmy tam i wyłączmy ją!,Estou vendo distorções enormes de ondas neurais. Acho que encontramos. Vamos entrar lá e desligar!,,"Citesc distorsiune neurale masive drept din față, cred că am găsit-o. Să intrăm și să o oprim.","Я вижу мощный источник помех прямо по курсу. Похоже, мы нашли конвертер. Войди и останови его!",,Tam karşıdan büyük sinir dalgası bozulmaları okuyorum. Sanırım onu bulduk. Oraya girelim ve onu kapatalım! +機械を探してシャットダウンさせろ!",이제 공장으로 향하자. 광산을 나가봐. 이 순간을 놓치면 안 돼. 얼른 그 기계를 찾아서 작동을 멈추자!,Nu naar de fabriek. Verlaat de mijnen en je kunt het niet missen. Laten we die machine vinden en hem uitschakelen!,"Nå videre til fabrikken. Gå ut av gruvene, og du kan ikke gå glipp av den. La oss finne den maskinen og slå den av!",Teraz przejdź do fabryki. Wyjdź z kopalni i nie możesz jej przegapić. Znajdźmy tę maszynę i wyłączmy ją!,"Agora vá para a fábrica. Ao sair das minas você vai encontrá-la, não tem como errar. Vamos achar essa máquina e desligá-la de vez!",,"Acum înspre fabrică. Ieși din mine, nu o poți rata. Să găsim mașina aia și să o oprim!","Теперь — на фабрику. Выйди из шахты, и ты сразу увидишь вход. Найди эту машину и останови её!",,Nu fortsätter vi till fabriken. Gå ut ur gruvorna och du kan inte missa den. Låt oss hitta den där maskinen och stänga av den!,Şimdi fabrikaya gidelim. Madenlerden çıkın ve onu kaçırmayın. Hadi şu makineyi bulup kapatalım! +I'm reading massive neural wave distortions from straight ahead. I think we've found it. Let's get in there and shut it down!,TXT_ILOG102,,,,"Detekuju obří rušení nervových vln přímo před námi. Myslím, že jsme to našli. Pojďme tam a vypněme to!","Jeg kan se massive neurale bølgeforvrængninger lige forude. Jeg tror, vi har fundet den. Lad os komme ind og lukke den ned!","Ich empfange massive neurale Verzerrungen direkt voraus. Ich denke, wir haben sie gefunden. Lass uns reingehen und sie abschalten.",,,Estoy leyendo distorsiones de ondas neuronales masivas adelante. Creo que la hemos encontrado. ¡Entremos ahí y destruyámosla!,,Havaitsen massivisia hermoaaltovääristymiä suoraan edessä. Luulen löytäneemme sen. Mennään sisään ja sammutetaan se!,Je recois des distorsions neurales colossales devant nous. Je crois que nous l'avons trouvé. Détruisons-la!,Erős ideghullám zavaró jeleket fogok. Azt hiszem megtaláltuk. Menjünk be és állítsuk le!,Sto ricevendo potenti segnali distorti proprio davanti a te. Penso che l'abbiamo trovata. Entriamo e spegnamo questa macchina!,重い神経波歪曲が直に届いたわ。私達はそれを見つけたという事よ。,앞쪽에서 거대한 신경교란 파장이 감지되고 있어. 우리가 찾아낸 것 같아. 어서 들어가서 꺼버리자!,Ik lees enorme neurale golfvervormingen van rechtdoor. Ik denk dat we hem gevonden hebben. Laten we naar binnen gaan en de machine stilleggen!,Jeg leser massive nevrale bølgeforvrengninger rett fram. Jeg tror vi har funnet den. La oss gå inn og slå den av!,Odczytuję potężne zniekształcenia fal neuronowych z prostej drogi. Chyba ją znaleźliśmy. Wejdźmy tam i wyłączmy ją!,Estou vendo distorções enormes de ondas neurais. Acho que encontramos. Vamos entrar lá e desligar!,,"Citesc distorsiune neurale masive drept din față, cred că am găsit-o. Să intrăm și să o oprim.","Я вижу мощный источник помех прямо по курсу. Похоже, мы нашли конвертер. Войди и останови его!",,Jag läser massiva neurala vågförvrängningar från rakt fram. Jag tror att vi har hittat den. Låt oss gå in där och stänga av den!,Tam karşıdan büyük sinir dalgası bozulmaları okuyorum. Sanırım onu bulduk. Oraya girelim ve onu kapatalım! Just when I think we've seen it all! They go in human and come out... I dont even want to think about it. Destroy this horror!,TXT_ILOG103,,,,"Zrovna, když jsem myslela, že jsme to všechno viděli! Dovnitř jdou jako lidé a vyjdou... ani na to nechci myslet. Znič tu hrůzu!","Lige når jeg tror, vi har set det hele! De går ind i et menneske og kommer ud... Jeg vil ikke engang tænke på det. Ødelæg denne rædsel!","Und da denkt man, man hätte schon alles gesehen. Die kommen als Menschen rein und kommen raus als... Ich möchte gar nicht drüber nachdenken. Zerstöre diesen Horror.",,,¡Justo cuando creía haberlo visto todo! Entran humanos y salen... No quiero ni pensarlo. ¡Destruye este horror!,,Juuri kun luulen nähneemme kaiken! He menevät sisään ihmisinä ja tulevat ulos... En halua edes ajatellakaan sitä. Tuhoa tämä kauhistus!,"Et quand je pense avoir tout vu.. Des humains entrent, et puis.. Non, je ne veux pas y penser. Détruis cette horreur!","Amikor azt hittem, hogy mindent láttunk. Emberként mennek be, és úgy jönnek ki mint egy...nem is akarok rá gondolni. Semmisítsd meg ezt a horrort!",E io che pensavo di averle viste tutte! Entrano umani ed escono fuori... Non ci voglio neanche pensare. Distruggi questo orrore!,"今まで見てきたことについて考えている! 奴は人の内部から出てくる...それについて考えたくないわ。 -この恐怖を打ち消すんだ!",이렇게 끔찍한 모습을 보게 되다니! 멀쩡한 사람이 저곳에 들어갔다 나온 모습을... 차마 생각하기도 싫어. 저 경악스러운 것을 파괴해!,Net nu ik denk dat we alles hebben gezien! Ze gaan menselijk naar binnen en komen eruit.... Ik wil er niet eens over nadenken. Vernietig deze verschrikking!,Akkurat når jeg tror vi har sett alt! De går inn som mennesker og kommer ut... Jeg vil ikke engang tenke på det. Ødelegg denne grusomheten!,"Właśnie wtedy, gdy myślę, że widzieliśmy już wszystko! Wchodzą w człowieka i wychodzą... Nie chcę nawet o tym myśleć. Zniszczyć ten horror!",E eu pensei que já tinha visto de tudo! Eles entram humanos e saem... Eu não quero nem pensar nisso. Destrua essa coisa horripilante!,,Exact când credeam că am văzut tot. Intră oameni și ies...Nici nu vreau să mă gândesc. Distruge-o!,"А я-то думала, что хуже уже не будет! Они входят людьми, а выходят... Не хочу даже думать об этом. Покончи с этим кошмаром!",,Tam da her şeyi gördüğümüzü düşündüğüm anda! İnsana giriyorlar ve çıkıyorlar. Bunu düşünmek bile istemiyorum. Bu dehşeti yok edin! +この恐怖を打ち消すんだ!",이렇게 끔찍한 모습을 보게 되다니! 멀쩡한 사람이 저곳에 들어갔다 나온 모습을... 차마 생각하기도 싫어. 저 경악스러운 것을 파괴해!,Net nu ik denk dat we alles hebben gezien! Ze gaan menselijk naar binnen en komen eruit.... Ik wil er niet eens over nadenken. Vernietig deze verschrikking!,Akkurat når jeg tror vi har sett alt! De går inn som mennesker og kommer ut... Jeg vil ikke engang tenke på det. Ødelegg denne grusomheten!,"Właśnie wtedy, gdy myślę, że widzieliśmy już wszystko! Wchodzą w człowieka i wychodzą... Nie chcę nawet o tym myśleć. Zniszczyć ten horror!",E eu pensei que já tinha visto de tudo! Eles entram humanos e saem... Eu não quero nem pensar nisso. Destrua essa coisa horripilante!,,Exact când credeam că am văzut tot. Intră oameni și ies...Nici nu vreau să mă gândesc. Distruge-o!,"А я-то думала, что хуже уже не будет! Они входят людьми, а выходят... Не хочу даже думать об этом. Покончи с этим кошмаром!",,Precis när jag tror att vi har sett allt! De går in som människor och kommer ut... Jag vill inte ens tänka på det. Förstör denna skräck!,Tam da her şeyi gördüğümüzü düşündüğüm anda! İnsana giriyorlar ve çıkıyorlar. Bunu düşünmek bile istemiyorum. Bu dehşeti yok edin! Macil's gone nuts. He just knowingly sent 200 men to their deaths. I want vengeance! For the dead and for the living dead! Let's get back and find out what's going on.,TXT_ILOG104,,,,"Macil zešílel. Jen tak poslal dvě stě mužů na smrt. Chci odplatu - za mrtvé i živé mrtvé! Vraťme se a pojďme zjistit, co se stalo.","Macil er blevet skør. Han har lige bevidst sendt 200 mænd i døden. Jeg vil have hævn! For de døde og for de levende døde! Lad os tage tilbage og finde ud af, hvad der foregår.","Macil hat den Verstand verloren. Er hat gerade absichtlich 200 unserer Leute in den Tod geschickt. Ich will Rache! Für die Toten und für die lebenden Toten. Lass uns zurückgehen und herausfinden, was da los ist.",,,Macil se ha vuelto loco. Conscientemente ha enviado 200 hombres a su muerte. ¡Quiero venganza! ¡Por los muertos y los muertos vivientes! Regresemos y descubramos que está pasando.,Macil se ha vuelto loco. Conscientemente envió a 200 hombres a su muerte. ¡Quiero venganza! Por los muertos y por los muertos vivientes! Regresemos y veamos que está pasando.,"Macil on tullut hulluksi: Hän juuri lähetti tietoisesti 200 miestä surmaansa. Vaadin kostoa, sekä kuolleitten että elävien kuolleitten puolesta! Palataan ja selvitetään, mitä oikein on meneillään.","Macil a complètement perdu les pédales! Il a envoyé 200 hommes se faire tuer, et il le savait! Il faut les venger, pour eux et pour leurs camarades! On retourne à la base et on va trouver ce qu'il se passe.","Macil megőrült. 200 embert küldött a halálába szándékosan. Bosszút akarok! A halottakért, és az élőhalottakért! Húzzunk vissza és derítsük ki mi folyik.",Macil deve essere impazzito. Ha mandato consciamente 200 uomini verso la morte. Voglio vendetta! Per i morti e per i morti viventi! Ritorniamo alla base e scopriamo cosa sta succedendo.,"オラクルが正しかった。マシルはイカれていたなんて。 彼は故意に200人以上の人々を死に追いやっていた。 復讐しなくては。死んだ人達の為、そして今生きている人達の為にも! -戻って何が起きているかも調べるんだ。",마실이 정신 나갔나 봐. 모든 것을 알면서도 200 명이나 되는 병력을 보내서 죽게 했어. 과부들과 망령들을 위한 복수를 할 시간이야! 기지로 돌아가서 한번 그에게 여쭤봐.,Macil is gek geworden. Hij heeft net bewust 200 mannen naar hun dood gestuurd. Ik wil wraak! Voor de doden en voor de levende doden! Laten we teruggaan en uitzoeken wat er aan de hand is.,Macil har gått fra vettet. Han sendte 200 menn i døden med viten og vilje. Jeg vil ha hevn! For de døde og for de levende døde! La oss dra tilbake og finne ut hva som foregår.,"Macilowi odbiło. Właśnie świadomie wysłał 200 ludzi na śmierć. Chcę zemsty! Za zmarłych i za żywych zmarłych! Wracajmy i dowiedzmy się, co się dzieje.",O Macil enlouqueceu. Ele acabou de mandar 200 homens para as suas mortes e ele sabia disso. Eu quero vingança! Pelos mortos e pelos mortos-vivos! Vamos voltar e descobrir o que está acontecendo.,,Macil a înnebunit. A trimis intenționat 200 oameni la moarte. Vreau răzbunare! Pentru morți și morții vii! Să ne întoarcem și să vedem despre ce e vorba.,"Мэйсил озверел. Он намеренно послал двести человек на верную смерть. Я жажду мести! За убитых и за живых мертвецов! Давай вернёмся и выясним, что происходит.",,Macil çıldırdı. Bile bile 200 adamı ölüme gönderdi. İntikam istiyorum! Ölüler ve yaşayan ölüler için! Geri dönüp neler olduğunu öğrenelim. +戻って何が起きているかも調べるんだ。",마실이 정신 나갔나 봐. 모든 것을 알면서도 200 명이나 되는 병력을 보내서 죽게 했어. 과부들과 망령들을 위한 복수를 할 시간이야! 기지로 돌아가서 한번 그에게 여쭤봐.,Macil is gek geworden. Hij heeft net bewust 200 mannen naar hun dood gestuurd. Ik wil wraak! Voor de doden en voor de levende doden! Laten we teruggaan en uitzoeken wat er aan de hand is.,Macil har gått fra vettet. Han sendte 200 menn i døden med viten og vilje. Jeg vil ha hevn! For de døde og for de levende døde! La oss dra tilbake og finne ut hva som foregår.,"Macilowi odbiło. Właśnie świadomie wysłał 200 ludzi na śmierć. Chcę zemsty! Za zmarłych i za żywych zmarłych! Wracajmy i dowiedzmy się, co się dzieje.",O Macil enlouqueceu. Ele acabou de mandar 200 homens para as suas mortes e ele sabia disso. Eu quero vingança! Pelos mortos e pelos mortos-vivos! Vamos voltar e descobrir o que está acontecendo.,,Macil a înnebunit. A trimis intenționat 200 oameni la moarte. Vreau răzbunare! Pentru morți și morții vii! Să ne întoarcem și să vedem despre ce e vorba.,"Мэйсил озверел. Он намеренно послал двести человек на верную смерть. Я жажду мести! За убитых и за живых мертвецов! Давай вернёмся и выясним, что происходит.",,Macil har blivit galen. Han skickade just medvetet 200 män i döden. Jag vill ha hämnd! För de döda och för de levande döda! Låt oss återvända och ta reda på vad som pågår.,Macil çıldırdı. Bile bile 200 adamı ölüme gönderdi. İntikam istiyorum! Ölüler ve yaşayan ölüler için! Geri dönüp neler olduğunu öğrenelim. "The factory leads to a ""lab"", and they're getting a Sigil piece power signature from within. Back to the factory and our next step to freedom.",TXT_ILOG106,,,,"Továrna vede do „laboratoře“, a z ní detekují energii Pečeťe. Zpátky do továrny a našemu dalšímu kroku ke svobodě.","Fabrikken fører til et ""laboratorium"", og de får en signatur af en Sigil-styks kraft fra det indre. Tilbage til fabrikken og vores næste skridt mod frihed.","In der Fabrik gibt es ein „Labor“, und dort gibt es eine Sigil-Signatur. Zurück zur Fabrik und dem nächsten Schritt zu unserer Freiheit.",,,"La fábrica conduce a un 'laboratorio', y están obteniendo una señal de poder del Emblema desde dentro. De vuelta a la fábrica y nuestro siguiente paso a la libertad.",La Fábrica conduce a un Laboratorio y tiene una firma de poder del Emblema desde adentro. Regresemos a la Fábrica y a nuestro siguiente paso a la libertad.,"Tehdas johtaa ""laboratorioon"", ja he lukevat sisältä Sinettiosasen energiajälkiä. Takaisin tehtaaseen ja kohti seuraavaa askeltamme vapauteen.","L'usine mène à un « laboratoire », et je reçois le signal d'une pièce du Sigil à l'intérieur. Retournons à l'usine pour prendre le prochain pas vers la liberté.","A gyár egy laboratúriumba vezet, és pecsét erő sugárzást észlelünk belülről. Forduljunk vissza a gyárhoz, ezzel közelebb kerülve a szabadsághoz.","La Fabbrica porta a un ""laboratorio"", ed al suo interno è stato identificato un segnale di un pezzo del Sigillo. Ritorniamo alla fabbrica e il nostro prossimo passo per la libertà.","リヒターの報告では我々が破壊した工場は'研究所'に繋がっていて、 -奴等はシジルの調印を内部から得ている。工場に戻って自由への次の段階に進みましょう",이 공장은 '연구소'로 연결돼. 그리고 지금 오더가 그 안에서 시질의 힘을 빌릴 조짐이 보여. 공장으로 돌아가서 자유 투쟁을 계속 진행해!,"De fabriek leidt naar een ""lab"", en ze krijgen een Sigil stuk macht handtekening van binnenuit. Terug naar de fabriek en onze volgende stap naar vrijheid.","Fabrikken fører til et ""laboratorium"", og de får en Sigil-kraftsignatur fra innsiden. Tilbake til fabrikken og vårt neste skritt mot frihet.","Fabryka prowadzi do ""laboratorium"", a z jego wnętrza wydobywa się sygnatura mocy kawałka Sigil. Powrót do fabryki i nasz kolejny krok do wolności.","A fábrica leva a um ""laboratório"" e é de lá de onde eles estão recebendo um sinal da energia de uma peça do Sigilo. De volta à fábrica e ao próximo passo à liberdade.",,"Fabrica duce înspre un laborator, și primesc putere de la o piesă din Sigiliu. Înapoi la fabrică și încă un pas spre libertate.","За фабрикой находится «лаборатория», и мы засекли характерную энергию фрагмента Печати, исходящую оттуда. Вернись на фабрику и сделай ещё один шаг к нашему освобождению.",,"Fabrika bir ""laboratuvara"" açılıyor ve içeriden bir Sigil parçası güç imzası alıyorlar. Fabrikaya geri dönelim ve özgürlüğe bir sonraki adımımızı atalım." -"Find the Bishop and destroy him! Once he's dead, return to the Oracle.",TXT_ILOG120,MAP16: Entrance → Central door.,,,"Najdi Biskupa a znič ho! Až ho zabiješ, vrať se k Věštci.","Find biskoppen og ødelæg ham! Når han er død, skal du vende tilbage til Oraklet.","Finde den Bischof und vernichte ihn. Sobald er tot ist, kehre zum Orakel zurück.",,,"¡Encuentra al Obispo y destrúyelo! En cuanto esté muerto, regresa con el Oráculo.",,"Löydä Piispa ja tuhoa hänet! Kun hän on kuollut, palaa Oraakkelin luokse.","Trouve l'évêque et tues-le! Une fois qu'il est mort, retourne à l'Oracle.","Találd meg a Püspököt és öld meg! Ha meghalt, menj az Orákulumhoz.","Trova il Vescovo e distruggilo! Una volta ucciso, ritorna dall'Oracolo.",ビショップを見つけて殺したらオラクルの元へ戻れ。,비숍을 찾아서 그를 파괴해! 시질 조각을 얻은 뒤 오라클에게 돌아가.,"Vind de bisschop en vernietig hem! Als hij dood is, keer je terug naar het Orakel.","Finn biskopen og tilintetgjør ham! Når han er død, gå tilbake til Oraklet.","Znajdź Bishopa i zniszcz go! Gdy już będzie martwy, wróć do Oracle.",Encontre o Bispo e destrua ele! Assim que ele morrer volte ao Oráculo.,,"Găsește Episcopul și distruge-l! Odată ce e mort, întoarce-te la Oracol.","Найди Епископа и уничтожь его! После, вернись к Оракулу.",,Piskoposu bulun ve onu yok edin! O öldükten sonra Kahin'e dönün. +奴等はシジルの調印を内部から得ている。工場に戻って自由への次の段階に進みましょう",이 공장은 '연구소'로 연결돼. 그리고 지금 오더가 그 안에서 시질의 힘을 빌릴 조짐이 보여. 공장으로 돌아가서 자유 투쟁을 계속 진행해!,"De fabriek leidt naar een ""lab"", en ze krijgen een Sigil stuk macht handtekening van binnenuit. Terug naar de fabriek en onze volgende stap naar vrijheid.","Fabrikken fører til et ""laboratorium"", og de får en Sigil-kraftsignatur fra innsiden. Tilbake til fabrikken og vårt neste skritt mot frihet.","Fabryka prowadzi do ""laboratorium"", a z jego wnętrza wydobywa się sygnatura mocy kawałka Sigil. Powrót do fabryki i nasz kolejny krok do wolności.","A fábrica leva a um ""laboratório"" e é de lá de onde eles estão recebendo um sinal da energia de uma peça do Sigilo. De volta à fábrica e ao próximo passo à liberdade.",,"Fabrica duce înspre un laborator, și primesc putere de la o piesă din Sigiliu. Înapoi la fabrică și încă un pas spre libertate.","За фабрикой находится «лаборатория», и мы засекли характерную энергию фрагмента Печати, исходящую оттуда. Вернись на фабрику и сделай ещё один шаг к нашему освобождению.",,"Fabriken leder till ett ""labb"", och de får en Sigil piece power signatur inifrån. Tillbaka till fabriken och vårt nästa steg mot frihet.","Fabrika bir ""laboratuvara"" açılıyor ve içeriden bir Sigil parçası güç imzası alıyorlar. Fabrikaya geri dönelim ve özgürlüğe bir sonraki adımımızı atalım." +"Find the Bishop and destroy him! Once he's dead, return to the Oracle.",TXT_ILOG120,MAP16: Entrance → Central door.,,,"Najdi Biskupa a znič ho! Až ho zabiješ, vrať se k Věštci.","Find biskoppen og ødelæg ham! Når han er død, skal du vende tilbage til Oraklet.","Finde den Bischof und vernichte ihn. Sobald er tot ist, kehre zum Orakel zurück.",,,"¡Encuentra al Obispo y destrúyelo! En cuanto esté muerto, regresa con el Oráculo.",,"Löydä Piispa ja tuhoa hänet! Kun hän on kuollut, palaa Oraakkelin luokse.","Trouve l'évêque et tues-le! Une fois qu'il est mort, retourne à l'Oracle.","Találd meg a Püspököt és öld meg! Ha meghalt, menj az Orákulumhoz.","Trova il Vescovo e distruggilo! Una volta ucciso, ritorna dall'Oracolo.",ビショップを見つけて殺したらオラクルの元へ戻れ。,비숍을 찾아서 그를 파괴해! 시질 조각을 얻은 뒤 오라클에게 돌아가.,"Vind de bisschop en vernietig hem! Als hij dood is, keer je terug naar het Orakel.","Finn biskopen og tilintetgjør ham! Når han er død, gå tilbake til Oraklet.","Znajdź Bishopa i zniszcz go! Gdy już będzie martwy, wróć do Oracle.",Encontre o Bispo e destrua ele! Assim que ele morrer volte ao Oráculo.,,"Găsește Episcopul și distruge-l! Odată ce e mort, întoarce-te la Oracol.","Найди Епископа и уничтожь его! После, вернись к Оракулу.",,Hitta biskopen och förgöra honom! När han är död återvänder du till oraklet.,Piskoposu bulun ve onu yok edin! O öldükten sonra Kahin'e dönün. The Loremaster's lab is beyond the teleporter that just opened. Let's go find out what he was just yapping about. And our next step to freedom.,TXT_ILOG122,,,,"Dějepiscova laboratoř je za teleportérem, který se právě otevřel. Pojďme se podívat, o čem to blábolil. A k našemu dalšímu kroku ke svobodě.","Loremesterens laboratorium ligger bag teleporteren, der lige er åbnet. Lad os finde ud af, hvad han lige pludrede om. Og vores næste skridt til frihed.","Das Labor des Wissensmeisters ist jenseits des Teleporters, der gerade geöffnet wurde. Lass uns herausfinden, worüber er da gerade geschwafelt hat. Und zum nächsten Schritt für unsere Freiheit.",,,El laboratorio del Maestro del Conocimiento está al otro lado del teletransporte que acaba de abrirse. Vayamos a ver de qué tanto parloteaba. Y nuestro siguiente paso a la libertad.,El laboratorio del Maestro del Conocimiento está más allá del teleporte que se ha abierto. Vamos a encontrar de qué tanto balbucea. Y nuestro siguiente paso a la libertad.,"Oppi-Isän laboratorio on juuri avautuneen kaukosiirtimen tuolla puolen. Mennään ottamaan selvää, mistä hän juuri oikein pälätti, ja kohti seuraavaa askeltamme vapauteen.","Le laboratoire du Maître des Traditions est de l'autre côté du téléporteur que nous venons d'ouvrir. Allons voir pourquoi il était en train de brailler, et prendre le prochain pas vers la liberté.",A Tanmester laborja a most megnyílt teleport túloldalán van. Derítsük ki miről is hadovált az imént. Még egy lépés a szabadság irányába.,Il laboratorio del Sapiente si trova giusto oltre questo teletrasporto. Andiamo a vedere di cosa stava blaterando. E verso il nostro prossimo passo per la libertà.,"ロアマスター研究所は開いたばかりのテレポーターを越えた先だ。 -奴が何をやらかしているか調べろ。次の自由を解放するために。",로어마스터의 연구소는 방금 열린 텔레포터를 통해서 입장이 가능해. 어떤 예언을 지껄이는지 한번 확인하러 가봐. 그리고 자유 투쟁을 계속 진행해!,Het lab van de Kennismeester is voorbij de teleporter die net geopend is. Laten we gaan uitzoeken waar hij net over aan het zeuren was. En onze volgende stap naar vrijheid.,Loremesterens laboratorium er bortenfor teleporteren som nettopp åpnet seg. La oss finne ut hva han snakket om. Og vårt neste skritt mot frihet.,"Laboratorium Loremastera jest za teleporterem, który właśnie się otworzył. Dowiedzmy się, o czym on właśnie gadał. I nasz następny krok do wolności.",O laboratório do Mestre do Conhecimento está depois desse teletransportador que acaba de abrir. Vamos lá descobrir sobre o que ele estava tagarelando. E ao nosso próximo passo à liberdade.,,Laboratorul Maestrului Cunoștiințelor e dincolo de teleportorul care tocmai s-a deschis. Să mergem și să vedem despre ce tot bolborosea. Și următorul nostru pas spre libertate.,"Телепорт, который ты нашёл, приведёт тебя в лабораторию Хранителя мудрости. Давай узнаем, о чём он там бормотал, и сделаем ещё один шаг к освобождению.",,Loremaster'ın laboratuvarı az önce açılan ışınlayıcının ötesinde. Gidip neden bahsettiğini öğrenelim. Ve özgürlüğe giden bir sonraki adımımızı. +奴が何をやらかしているか調べろ。次の自由を解放するために。",로어마스터의 연구소는 방금 열린 텔레포터를 통해서 입장이 가능해. 어떤 예언을 지껄이는지 한번 확인하러 가봐. 그리고 자유 투쟁을 계속 진행해!,Het lab van de Kennismeester is voorbij de teleporter die net geopend is. Laten we gaan uitzoeken waar hij net over aan het zeuren was. En onze volgende stap naar vrijheid.,Loremesterens laboratorium er bortenfor teleporteren som nettopp åpnet seg. La oss finne ut hva han snakket om. Og vårt neste skritt mot frihet.,"Laboratorium Loremastera jest za teleporterem, który właśnie się otworzył. Dowiedzmy się, o czym on właśnie gadał. I nasz następny krok do wolności.",O laboratório do Mestre do Conhecimento está depois desse teletransportador que acaba de abrir. Vamos lá descobrir sobre o que ele estava tagarelando. E ao nosso próximo passo à liberdade.,,Laboratorul Maestrului Cunoștiințelor e dincolo de teleportorul care tocmai s-a deschis. Să mergem și să vedem despre ce tot bolborosea. Și următorul nostru pas spre libertate.,"Телепорт, который ты нашёл, приведёт тебя в лабораторию Хранителя мудрости. Давай узнаем, о чём он там бормотал, и сделаем ещё один шаг к освобождению.",,Läromästarens labb ligger bortom teleportern som just öppnades. Nu går vi och tar reda på vad han just babblade om. Och vårt nästa steg till frihet.,Loremaster'ın laboratuvarı az önce açılan ışınlayıcının ötesinde. Gidip neden bahsettiğini öğrenelim. Ve özgürlüğe giden bir sonraki adımımızı. "Come on, let's get the hell out of here. The force field is down, off to the Bishop's tower. Once he's dead, get back to the Oracle.",TXT_ILOG211,MAP15: Computer destroyed + Room 1,,,"No tak, dostaňme se sakra odsud. Silové pole je kaput, jdeme do Biskupovy věže. Až ho zabiješ, vrať se k Věštci.","Kom nu, lad os komme væk herfra. Kraftfeltet er nede, af sted til biskoppens tårn. Når han er død, så gå tilbage til Oraklet.","Komm schon, lass uns von hier verschwinden. Das Kraftfeld ist abgeschaltet, also ab zum Turm des Bischofs. Sobald er tot ist, geht es zurück zum Orakel",,,"Venga, larguémonos de aquí. El campo de fuerza está desactivado, derechos a la torre del Obispo. En cuanto esté muerto, regresa con el Oráculo.","Vamos, larguémonos de aquí. El campo de fuerza fue desactivado, vamos a la torre del Obispo. Cuando esté muerto, regresa con el Oráculo.","Mennään, häivytään täältä hittoon. Voimakenttä on nurin; suunnatkaamme siis kohti Piispan tornia. Kun hän on kuollut, palaa Oraakkelin luokse.","Allez, il faut qu'on se barre d'ici. Le champ de force est hors-ligne. Entre dans la tour de l'évêque. Quand il sera mort, retourne à l'Oracle.","Na gyerünk, húzzunk innen. Az erőpajzs deaktiválva, irány a Püspök tornya. Ha meghalt menj vissza az Orákulumhoz.","Avanti, andiamo via da qui. Il campo di forza è disattivato, quindi andiamo alla torre del Vescovo. Una volta che è morto, ritorna dall'Oracolo.","頼むからこんな所さっさと出よう。 フォースフィールドは切った、ビショップの塔へ向かおう。 ビショップを殺したらオラクルの元へ戻れ。 -","이제 이곳을 당장 떠나. 방어막이 꺼졌으니! 비숍의 성으로 이동해서 비숍을 죽이고, 오라클을 만나러 가.","Kom op, laten we hier als de sodemieter weggaan. Het krachtveld is naar beneden, op weg naar de bisschopstoren. Als hij dood is, ga dan terug naar het Orakel.","Kom igjen, la oss komme oss vekk herfra. Kraftfeltet er nede, av gårde til biskopens tårn. Når han er død, gå tilbake til oraklet.","Chodź, wynośmy się stąd. Pole siłowe wyłączone, idziemy do wieży biskupa. Kiedy będzie martwy, wróć do Wyroczni.","Vamos dar o fora daqui. O campo de força está desligado. Vamos para a torre do Bispo. Assim que ele morrer, volte ao oráculo.",,"Hai, să ieșim de aici. Câmpul de forță e la pământ, către turnul Episcopului. Odată ce e mort, întoarce-te la Oracol.","Ну же, двигаем отсюда. Силовое поле отключено, пора двигаться к башне Епископа. Когда он умрёт, возвращайся к Оракулу.",,"Hadi, buradan defolup gidelim. Güç alanı kapandı, Piskopos'un kulesine gidiyoruz. O öldüğünde, Kahin'e geri dönün." +","이제 이곳을 당장 떠나. 방어막이 꺼졌으니! 비숍의 성으로 이동해서 비숍을 죽이고, 오라클을 만나러 가.","Kom op, laten we hier als de sodemieter weggaan. Het krachtveld is naar beneden, op weg naar de bisschopstoren. Als hij dood is, ga dan terug naar het Orakel.","Kom igjen, la oss komme oss vekk herfra. Kraftfeltet er nede, av gårde til biskopens tårn. Når han er død, gå tilbake til oraklet.","Chodź, wynośmy się stąd. Pole siłowe wyłączone, idziemy do wieży biskupa. Kiedy będzie martwy, wróć do Wyroczni.","Vamos dar o fora daqui. O campo de força está desligado. Vamos para a torre do Bispo. Assim que ele morrer, volte ao oráculo.",,"Hai, să ieșim de aici. Câmpul de forță e la pământ, către turnul Episcopului. Odată ce e mort, întoarce-te la Oracol.","Ну же, двигаем отсюда. Силовое поле отключено, пора двигаться к башне Епископа. Когда он умрёт, возвращайся к Оракулу.",,"Kom igen, vi sticker härifrån. Kraftfältet är nere, vi går till biskopens torn. När han är död, återvänder vi till Oraklet.","Hadi, buradan defolup gidelim. Güç alanı kapandı, Piskopos'un kulesine gidiyoruz. O öldüğünde, Kahin'e geri dönün." Find the sanctuary by the river. Steal the chalice from inside. Bring it to Harris in the tavern.,TXT_ILOG1001,,,,Najdi svatyni u řeky. Zevnitř ukradni kalich. Přines ho Harrisovi do taverny.,Find helligdommen ved floden. Stjæl bægeret indefra. Bring den til Harris på tavernaen.,"Finde das Heiligtum am Fluss. Stehle den Kelch, der dort aufbewahrt wird und bringe ihn zu Harris in der Taverne.",,,Encuentra el santuario junto al río. Roba el cáliz de dentro. Tráeselo a Harris en la taberna.,Encuentra el santuario junto al río. Roba el cáliz de adentro. Tráeselo a Harris a la taberna.,Löydä pyhäkkö joen varrella. Varasta kalkki sisältä. Vie se Harrisille kapakkaan.,Trouve le sanctuaire près de la rivière. Prends le Calice qui s'y trouve et amène le à Harris dans la taverne.,A szentély a folyó mellett van. Lopd el a serleget bentről. Vidd travishez a kocsmába.,Trova il santuario accanto al fiume. Ruba il calice al suo interno. Portalo ad Harris nella taverna.,"川沿いの 聖域 を探し、中にある聖杯を盗む。 -酒場にいるハリスに渡す。",강 근처에 있는 성소를 찾아서 안에 보관되어있는 성배를 훔치고 선술집으로 향해.,Zoek het heiligdom bij de rivier. Steel de kelk van binnenuit. Breng het naar Harris in de herberg.,Finn helligdommen ved elven. Stjel begeret fra innsiden. Ta det med til Harris i vertshuset.,Znajdź sanktuarium nad rzeką. Ukradnij ze środka kielich. Zanieś go Harrisowi w tawernie.,Encontre o santuário perto do rio. Roube o cálice que está lá dentro. Leve-o para o Harris na taverna.,,Găsește sanctuarul de lângă râu. Fură potirul din interior. Du-l la Harris în tavernă.,Найди святилище возле реки. Проникни туда и выкради чашу. Принеси её Харрису в таверну.,,Nehir kenarındaki tapınağı bulun. İçeriden kadehi çalın. Tavernadaki Harris'e götür. -Find the Governor. Talk to him about your reward.,TXT_ILOG1002,,,,Najdi guvernéra. Promluv si s ním o své odměně.,Find guvernøren. Tal med ham om din belønning.,Finde den Gouverneur. Rede mit ihm über deine Belohnung.,,,Encuentra al Gobernador. Háblale sobre tu recompensa.,Encuentra al Gobernador. Háblale de tu recompensa.,Löydä kuvernööri. Puhu hänen kanssaan palkkiostasi.,Trouve le gouverneur et demande ta récompense.,Keresd meg a Kormányzót. Beszélj vele a jutalomról.,Trova il governatore. Parlargli della tua ricompensa.,知事を探せ。彼と話して報酬を貰う。,총독을 만나서 보상에 대해 예기해.,Vind de Gouverneur. Spreek met hem over je beloning.,Finn guvernøren. Snakk med ham om belønningen din.,Znajdź gubernatora. Porozmawiaj z nim o swojej nagrodzie.,Encontre o Governador. Fale com ele sobre a sua recompensa.,,Găsește Guvernatorul. Vorbește cu el despre recompensa ta.,Найди губернатора. Обсуди с ним свою награду.,,Vali'yi bul. Onunla ödülün hakkında konuş. +酒場にいるハリスに渡す。",강 근처에 있는 성소를 찾아서 안에 보관되어있는 성배를 훔치고 선술집으로 향해.,Zoek het heiligdom bij de rivier. Steel de kelk van binnenuit. Breng het naar Harris in de herberg.,Finn helligdommen ved elven. Stjel begeret fra innsiden. Ta det med til Harris i vertshuset.,Znajdź sanktuarium nad rzeką. Ukradnij ze środka kielich. Zanieś go Harrisowi w tawernie.,Encontre o santuário perto do rio. Roube o cálice que está lá dentro. Leve-o para o Harris na taverna.,,Găsește sanctuarul de lângă râu. Fură potirul din interior. Du-l la Harris în tavernă.,Найди святилище возле реки. Проникни туда и выкради чашу. Принеси её Харрису в таверну.,,Hitta helgedomen vid floden. Stjäl kalken från insidan. Ta med den till Harris i tavernan.,Nehir kenarındaki tapınağı bulun. İçeriden kadehi çalın. Tavernadaki Harris'e götür. +Find the Governor. Talk to him about your reward.,TXT_ILOG1002,,,,Najdi guvernéra. Promluv si s ním o své odměně.,Find guvernøren. Tal med ham om din belønning.,Finde den Gouverneur. Rede mit ihm über deine Belohnung.,,,Encuentra al Gobernador. Háblale sobre tu recompensa.,Encuentra al Gobernador. Háblale de tu recompensa.,Löydä kuvernööri. Puhu hänen kanssaan palkkiostasi.,Trouve le gouverneur et demande ta récompense.,Keresd meg a Kormányzót. Beszélj vele a jutalomról.,Trova il governatore. Parlargli della tua ricompensa.,知事を探せ。彼と話して報酬を貰う。,총독을 만나서 보상에 대해 예기해.,Vind de Gouverneur. Spreek met hem over je beloning.,Finn guvernøren. Snakk med ham om belønningen din.,Znajdź gubernatora. Porozmawiaj z nim o swojej nagrodzie.,Encontre o Governador. Fale com ele sobre a sua recompensa.,,Găsește Guvernatorul. Vorbește cu el despre recompensa ta.,Найди губернатора. Обсуди с ним свою награду.,,Hitta guvernören. Prata med honom om din belöning.,Vali'yi bul. Onunla ödülün hakkında konuş. "Find the sanctuary by the river. Inside someone called Beldin is being held. Shut him up, and bring his ring back to Rowan as proof.",TXT_ILOG1003,MAP02: After accepting Rowan's chore.,,,Najdi svatyni u řeky. Uvnitř je držen jakýsi Beldin. Umlč ho a přines Rowanovi jeho prsten jako důkaz.,"Find helligdommen ved floden. Indenfor bliver en person ved navn Beldin holdt fanget. Få ham til at lukke munden på ham, og giv Rowan hans ring tilbage som bevis.",Finde das Heiligtum am Fluss. Dort drinnen wird jemand namens Beldin festgehalten. Bringe ihn zum Schweigen und gebe Rowan seinen Ring als Beweis.,,Trovu la sanktejo proksime de la rivero. Iu nomata Beldin estas retenita en ĝi. Silentigu lin kaj alportu lian ringon kiel pruvon al Rowan.,Encuentra el santuario junto al río. Dentro alguien llamado Beldin está retenido. Siléncialo y trae de vuelta su anillo a Rowan como prueba.,Encuentra el santuario junto al río. Adentro alguien llamado Beldin está retenido. Siléncialo y tráele su anillo a Rowan como prueba.,"Löydä pyhäkkö joen varrella. Sisällä on vangittuna joku nimeltään Beldin. Vaienna hänet, ja tuo hänen sormuksensa takaisin Rowanille todisteena.","Trouve le sanctuaire près de la rivière. Quelqu'un qui s'appelle Beldin s'y trouve emprisonné. Cloue-lui le bec, et ramène son anneau à Rowan comme preuve.","Megtalálod a szentélyt a folyó mellett. Egy Beldin nevű figurát tartanak fogva. Halgattasd el örökre, és hozd vissza a gyűrűjét Rowannak bizonyítékként.","Trova il santuario accanto al fiume. Dentro, qualcuno chiamato Beldin è sotto chiave. Fallo tacere per sempre, e riporta il suo anello a Rowan come prova.","川沿いの 聖域 を探せ。中にいるベルディンと 呼ばれている捕獲された者を見つけ彼を黙らせる。 -指輪をロワンに渡す。","강 근처에 있는 성소를 찾아서 벨딘이라는 사람을 찾고, 입을 다물게 해. 그 후에 그의 반지를 얻어서 로완에게 그를 죽였다고 증명해.","Zoek het heiligdom bij de rivier. Binnenin wordt iemand met de naam Beldin vastgehouden. Laat hem zwijgen, en breng zijn ring terug naar Rowan als bewijs.","Finn helligdommen ved elven. Der inne holdes en som heter Beldin fanget. Få ham til å holde kjeft, og ta med ringen hans tilbake til Rowan som bevis.",Znajdź sanktuarium nad rzeką. W środku przetrzymywany jest ktoś o imieniu Beldin. Ucisz go i przynieś jego pierścień Rowanowi jako dowód.,Encontre o santuário perto do rio. Dentro há alguém chamado Beldin sendo detido. Cale a boca dele e traga o seu anel de volta ao Rowan como prova.,,Găsește sanctuarul de lângă râu. Înăuntru cineva numit Beldin e reținut. Redu-l la tăcere și întoarce-te cu inelul la Rowan drept dovadă.,"Найди святилище возле реки. Внутри содержится пленник по имени Белдин. Заставь его замолчать, и принеси его кольцо Роуэну в качестве доказательства.",,Nehir kenarındaki sığınağı bul. İçeride Beldin adında biri tutuluyor. Onu susturun ve yüzüğünü kanıt olarak Rowan'a geri getirin. -Find the location of the Front and talk to Macil.,TXT_ILOG1004,MAP02: After getting the com unit from Rowan.,,,Najdi umístění Fronty a promluv si s Macilem.,Find placeringen af fronten og tal med Macil.,Finde die Basis der Front und rede mit Macil.,,,Encuentra la localización del Frente y habla con Macil.,,Löydä Rintaman olinpaikka ja keskustele Macilin kanssa.,Trouve où se cache le Front et parle à Macil.,"Keresd meg a Front központját, és beszélj Macillal.",Trova il quartier generale del Fronte e parla a Macil.,フロントの場所を見つけ、マシルと会話する。,프론트의 기지를 찾아서 마실과 대화해봐.,Zoek de locatie van het Front en praat met Macil.,Finn plasseringen til Fronten og snakk med Macil.,Znajdź lokalizację Frontu i porozmawiaj z Macil.,Ache a localização da Frente e fale com o Macil.,,Găsește locația Frontului și vorbește cu Macil.,Найди базу Сопротивления и поговори с Мэйсилом.,,Cephe'nin yerini bulun ve Macil ile konuşun. -"Go down the stairs, find and talk to Macil.",TXT_ILOG1005,,,,Jdi dolů po schodech a najdi a promluv si s Macilem.,"Gå ned ad trappen, find og tal med Macil.",Geh die Treppe runter und rede mit Macil.,,,Baja por las escaleras. Encuentra y habla con Macil.,,"Kulje portaat alas, löydä Macil ja keskustele hänen kanssaan.","Descends les escaliers, trouve et parle à Macil.","Menj le a lépcsőn, és keresd meg Macilt.","Scendi le scale, e trova e parla con Macil.",階段を降り、マシルと会話する。,계단 밑으로 내려가서 마실과 대화해봐.,"Ga de trap af, zoek en praat met Macil.","Gå ned trappene, finn og snakk med Macil.","Zejdź na dół po schodach, znajdź i porozmawiaj z Macil.","Desça as escadas, encontre e fale com o Macil.",,"Du-te în josul scărilor, găsește-l și vorbește cu Macil.","Спустись на этаж ниже, найди Мэйсила и поговори с ним.",,"Merdivenlerden aşağı inin, Macil'i bulun ve onunla konuşun." +指輪をロワンに渡す。","강 근처에 있는 성소를 찾아서 벨딘이라는 사람을 찾고, 입을 다물게 해. 그 후에 그의 반지를 얻어서 로완에게 그를 죽였다고 증명해.","Zoek het heiligdom bij de rivier. Binnenin wordt iemand met de naam Beldin vastgehouden. Laat hem zwijgen, en breng zijn ring terug naar Rowan als bewijs.","Finn helligdommen ved elven. Der inne holdes en som heter Beldin fanget. Få ham til å holde kjeft, og ta med ringen hans tilbake til Rowan som bevis.",Znajdź sanktuarium nad rzeką. W środku przetrzymywany jest ktoś o imieniu Beldin. Ucisz go i przynieś jego pierścień Rowanowi jako dowód.,Encontre o santuário perto do rio. Dentro há alguém chamado Beldin sendo detido. Cale a boca dele e traga o seu anel de volta ao Rowan como prova.,,Găsește sanctuarul de lângă râu. Înăuntru cineva numit Beldin e reținut. Redu-l la tăcere și întoarce-te cu inelul la Rowan drept dovadă.,"Найди святилище возле реки. Внутри содержится пленник по имени Белдин. Заставь его замолчать, и принеси его кольцо Роуэну в качестве доказательства.",,Hitta helgedomen vid floden. Där inne hålls någon som heter Beldin fången. Få tyst på honom och ta med dig hans ring tillbaka till Rowan som bevis.,Nehir kenarındaki sığınağı bul. İçeride Beldin adında biri tutuluyor. Onu susturun ve yüzüğünü kanıt olarak Rowan'a geri getirin. +Find the location of the Front and talk to Macil.,TXT_ILOG1004,MAP02: After getting the com unit from Rowan.,,,Najdi umístění Fronty a promluv si s Macilem.,Find placeringen af fronten og tal med Macil.,Finde die Basis der Front und rede mit Macil.,,,Encuentra la localización del Frente y habla con Macil.,,Löydä Rintaman olinpaikka ja keskustele Macilin kanssa.,Trouve où se cache le Front et parle à Macil.,"Keresd meg a Front központját, és beszélj Macillal.",Trova il quartier generale del Fronte e parla a Macil.,フロントの場所を見つけ、マシルと会話する。,프론트의 기지를 찾아서 마실과 대화해봐.,Zoek de locatie van het Front en praat met Macil.,Finn plasseringen til Fronten og snakk med Macil.,Znajdź lokalizację Frontu i porozmawiaj z Macil.,Ache a localização da Frente e fale com o Macil.,,Găsește locația Frontului și vorbește cu Macil.,Найди базу Сопротивления и поговори с Мэйсилом.,,Hitta platsen för fronten och prata med Macil.,Cephe'nin yerini bulun ve Macil ile konuşun. +"Go down the stairs, find and talk to Macil.",TXT_ILOG1005,,,,Jdi dolů po schodech a najdi a promluv si s Macilem.,"Gå ned ad trappen, find og tal med Macil.",Geh die Treppe runter und rede mit Macil.,,,Baja por las escaleras. Encuentra y habla con Macil.,,"Kulje portaat alas, löydä Macil ja keskustele hänen kanssaan.","Descends les escaliers, trouve et parle à Macil.","Menj le a lépcsőn, és keresd meg Macilt.","Scendi le scale, e trova e parla con Macil.",階段を降り、マシルと会話する。,계단 밑으로 내려가서 마실과 대화해봐.,"Ga de trap af, zoek en praat met Macil.","Gå ned trappene, finn og snakk med Macil.","Zejdź na dół po schodach, znajdź i porozmawiaj z Macil.","Desça as escadas, encontre e fale com o Macil.",,"Du-te în josul scărilor, găsește-l și vorbește cu Macil.","Спустись на этаж ниже, найди Мэйсила и поговори с ним.",,"Gå ner för trapporna, hitta och prata med Macil.","Merdivenlerden aşağı inin, Macil'i bulun ve onunla konuşun." "Visit Irale, the Front's weapons supplier in town. He's behind the door next to the weapons shop. Then, use the key Macil gave you to talk to the Governor.",TXT_ILOG1006,MAP03: After joining the Front.,,,"Navštiv Iraleho, dodavatele zbraní pro Frontu ve městě. Je za dveřmi vedle obchodu se zbraněmi. Pak použij klíč od Macila, aby sis promluvil s guvernérem.","Besøg Irale, Frontens våbenleverandør i byen. Han befinder sig bag døren ved siden af våbenbutikken. Brug derefter den nøgle, som Macil gav dig, til at tale med guvernøren.","Suche Irale auf, den Waffenbeschaffer der Front in der Stadr. Er hält sich in dem Gebäude neben dem Waffengeschäft auf. Danach benutze den Schlüssel, den Macil dir gegeben hat, um mit dem Gouverneur zu reden",,,"Visita a Irale, el proveedor de armamento del Frente; está pasando la puerta junto a la tienda de armas (Weapons). Luego usa la llave que te dio Macil para hablar con el Gobernador.",,"Tapaa Iralea, joka on Rintaman asetoimittaja kaupungissa. Hän on asekaupan viereisen oven takana. Käytä sen jälkeen Macilin antamaa avainta puhuaksesi kuvernöörin kanssa.","Va voir Irale, le chef de l'arsenal du Front, en ville. Il se trouve derrière la porte à côté du marchand d'armes. Utilise la clé que Macil t'a donné pour parler au gouverneur.","Keresd fel Iralet, a Front fegyver beszállítóját a városban. A fegyverbolt melletti ajtó mögött vár rád. Utána használd a maciltól kapott kulcsot, hogy tudj beszélni a Kormányzóval.","Visita Irale, il fornitore di armi del Fronte in città. Si trova dietro la porta accanto al negozio di armi. Dopodiché, usa la chiave che Macil ti ha dato per andare a parlare al governatore.","町にいるフロントへの武器供給者であるイラールの元を訪ねる。 -彼は武器屋の隣のドアに居る。それで、知事と会う為にマシルから貰ったキーを使う。","프론트의 무기상인 이롤리를 마을에서 찾아. 무기 상점 근처에 문이 있을 거야. 마실이 준 열쇠로 문을 열고 방문한 뒤, 총독과 대화해.","Bezoek Irale, de wapenleverancier van het Front in de stad. Hij zit achter de deur naast de wapenwinkel. Gebruik dan de sleutel die Macil je gaf om met de Gouverneur te praten.","Besøk Irale, Frontens våpenleverandør i byen. Han er bak døren ved siden av våpenbutikken. Bruk nøkkelen Macil ga deg til å snakke med guvernøren.","Odwiedź w mieście Irale, dostawcę broni dla Frontu. Jest on za drzwiami obok sklepu z bronią. Następnie użyj klucza, który dał ci Macil, by porozmawiać z gubernatorem.","Visite o Irale, o fornecedor de armas da Frente. Ele está atrás da porta perto da loja de armas. Depois, use a chave que o Macil te deu para falar com o Governador.",,"Vizitează pe Irale, distribuitorul de arme alFrontului în oraș. E dincolo de ușa de lângă magazinul de arme. Apoi, folosește cheia pe care Macil ți-a dat-o și vorbește cu Guvernatorul.","Посети Ирэйла, поставщика оружия Сопротивления в городе. Он за следующей после оружейного магазина дверью. Затем, воспользуйся ключом, который тебе дал Мэйсил, чтобы поговорить с губернатором.",,"Kasabada Cephe'nin silah tedarikçisi İrale'yi ziyaret edin. Silah dükkanının yanındaki kapının arkasında. Sonra, Vali ile konuşmak için Macil'in size verdiği anahtarı kullanın." +彼は武器屋の隣のドアに居る。それで、知事と会う為にマシルから貰ったキーを使う。","프론트의 무기상인 이롤리를 마을에서 찾아. 무기 상점 근처에 문이 있을 거야. 마실이 준 열쇠로 문을 열고 방문한 뒤, 총독과 대화해.","Bezoek Irale, de wapenleverancier van het Front in de stad. Hij zit achter de deur naast de wapenwinkel. Gebruik dan de sleutel die Macil je gaf om met de Gouverneur te praten.","Besøk Irale, Frontens våpenleverandør i byen. Han er bak døren ved siden av våpenbutikken. Bruk nøkkelen Macil ga deg til å snakke med guvernøren.","Odwiedź w mieście Irale, dostawcę broni dla Frontu. Jest on za drzwiami obok sklepu z bronią. Następnie użyj klucza, który dał ci Macil, by porozmawiać z gubernatorem.","Visite o Irale, o fornecedor de armas da Frente. Ele está atrás da porta perto da loja de armas. Depois, use a chave que o Macil te deu para falar com o Governador.",,"Vizitează pe Irale, distribuitorul de arme alFrontului în oraș. E dincolo de ușa de lângă magazinul de arme. Apoi, folosește cheia pe care Macil ți-a dat-o și vorbește cu Guvernatorul.","Посети Ирэйла, поставщика оружия Сопротивления в городе. Он за следующей после оружейного магазина дверью. Затем, воспользуйся ключом, который тебе дал Мэйсил, чтобы поговорить с губернатором.",,"Besök Irale, frontens vapenleverantör i staden. Han befinner sig bakom dörren bredvid vapenbutiken. Använd sedan nyckeln som Macil gav dig för att prata med guvernören.","Kasabada Cephe'nin silah tedarikçisi İrale'yi ziyaret edin. Silah dükkanının yanındaki kapının arkasında. Sonra, Vali ile konuşmak için Macil'in size verdiği anahtarı kullanın." "Find the power tap on the mains, and shut it off. Bring something back to the Governor as proof.",TXT_ILOG1007,"MAP02: After accepting ""messy"" chore.",,,Najdi stáčedlo energie na síti a vypni jej. Přines guvernérovi něco zpět jako důkaz.,"Find elhanen på hovedledningen, og luk den. Tag noget med tilbage til guvernøren som bevis.",Finde die Energieanzapfung und schalte sie aus. Bringe dem Gouverneur irgend etwas als Beweis.,,,Encuentra la toma en la red eléctrica y destrúyela. Tráele algo al Gobernador como prueba.,,Etsi verkkovirran piilokytkentä ja katkaise se. Tuo kuvernöörille jotain todisteeksi.,Trouve la connection pirate sur le transformateur et enlève la. Amène quelque chose au gouverneur comme preuve.,"Keresd meg a fővonalon az áramkapcsolót, és kapcsold ki. Hozz vissza valamit a kormányzótól bizonyítékként.","Trova il marchingegno che sta venendo usato per rubare energia alla rete, e distruggilo. Porta dei resti al governatore come prova.","電力盗用の場所を見つけ、それを止める。 -知事に渡す証拠も必要だ。",주 동력선 어딘가에 있는 추출기를 처리해. 그 잔해를 총독에게 들고 가서 증명해.,"Zoek het kraantje op het lichtnet, en zet het uit. Breng iets terug naar de Gouverneur als bewijs.","Finn strømbryteren på strømnettet, og slå den av. Ta med noe tilbake til guvernøren som bevis.",Znajdź kurek z prądem w sieci i wyłącz go. Przynieś coś gubernatorowi jako dowód.,Encontre a ligação clandestina no transformador e desligue-a. Traga algo de volta para o Governador como prova.,,Găsește cuplul de putere și oprește-l. Adu ceva drept dovadă Guvernatorului.,Найди нелегальное подключение к энергосети и выведи его из строя. Принеси что-нибудь губернатору в качестве доказательства.,,Şebekedeki güç musluğunu bulun ve kapatın. Kanıt olarak Vali'ye bir şey getirin. +知事に渡す証拠も必要だ。",주 동력선 어딘가에 있는 추출기를 처리해. 그 잔해를 총독에게 들고 가서 증명해.,"Zoek het kraantje op het lichtnet, en zet het uit. Breng iets terug naar de Gouverneur als bewijs.","Finn strømbryteren på strømnettet, og slå den av. Ta med noe tilbake til guvernøren som bevis.",Znajdź kurek z prądem w sieci i wyłącz go. Przynieś coś gubernatorowi jako dowód.,Encontre a ligação clandestina no transformador e desligue-a. Traga algo de volta para o Governador como prova.,,Găsește cuplul de putere și oprește-l. Adu ceva drept dovadă Guvernatorului.,Найди нелегальное подключение к энергосети и выведи его из строя. Принеси что-нибудь губернатору в качестве доказательства.,,Leta reda på strömkranen på elnätet och stäng av den. Ta med dig något tillbaka till guvernören som bevis.,Şebekedeki güç musluğunu bulun ve kapatın. Kanıt olarak Vali'ye bir şey getirin. "Find Derwin in the warehouse of the power station. Kill him, and bring Mourel his ear.",TXT_ILOG1008,"MAP02: After accepting ""bloody"" chore.",,,Najdi Derwina ve skladu elektrárny. Zabij ho a přines Mourelovi jeho ucho.,"Find Derwin i lageret på kraftværket. Dræb ham, og giv Mourel hans øre.",Finde Derwin im Lagerhaus des Kraftwerks. Töte ihn und bringe Mourel sein Ohr.,,,Encuentra a Derwin en el almacén (Warehouse) de la central eléctrica (Power Station). Mátalo y llévale su oreja a Mourel.,,"Etsi Derwin voimalaitoksen varastolta. Tapa hänet, ja tuo Mourelille hänen korvansa.","Trouve Derwin dans l'entrepôt de la centrale électrique. Tue-le, et amène son oreille à Mourel.","Keresd meg Derwint az erőmű raktárjában. öld meg, és vidd vissza Mourelnek a fülét.","Trova Derwin nel magazzino della centrale energetica. Uccidilo, e porta il suo orecchio a Mourel.","発電所の倉庫にいるダーウィンを見つける。 -始末したら、そいつの耳をモーレルに渡す。",발전소 창고 주변에 있는 더윈을 찾아. 그를 죽인 뒤 귀를 뜯어서 모렐 총독에게 건네줘.,"Vind Derwin in het magazijn van de centrale. Dood hem, en breng Mourel zijn oor.","Finn Derwin i lageret på kraftstasjonen. Drep ham, og gi Mourel øret hans.",Znajdź Derwina w magazynie elektrowni. Zabij go i przynieś Mourelowi jego ucho.,Encontre o Derwin no depósito da usina elétrica. Mate-o e leve a sua orelha para o Mourel.,,Găsește-l pe Derwin în depozit. Omoară-l și adu-i urechea lui Mourel.,Найди Дервина на складе электростанции. Убей его и принеси Морелу его ухо.,,Elektrik santralinin deposunda Derwin'i bulun. Onu öldürün ve Mourel'e kulağını getirin. +始末したら、そいつの耳をモーレルに渡す。",발전소 창고 주변에 있는 더윈을 찾아. 그를 죽인 뒤 귀를 뜯어서 모렐 총독에게 건네줘.,"Vind Derwin in het magazijn van de centrale. Dood hem, en breng Mourel zijn oor.","Finn Derwin i lageret på kraftstasjonen. Drep ham, og gi Mourel øret hans.",Znajdź Derwina w magazynie elektrowni. Zabij go i przynieś Mourelowi jego ucho.,Encontre o Derwin no depósito da usina elétrica. Mate-o e leve a sua orelha para o Mourel.,,Găsește-l pe Derwin în depozit. Omoară-l și adu-i urechea lui Mourel.,Найди Дервина на складе электростанции. Убей его и принеси Морелу его ухо.,,Hitta Derwin i lagret i kraftverket. Döda honom och ge Mourel hans öra.,Elektrik santralinin deposunda Derwin'i bulun. Onu öldürün ve Mourel'e kulağını getirin. "Use the pass Mourel gave you to get into the prison. Once inside, talk to Warden Montag. Find a way to free the prisoners.",TXT_ILOG1009,MAP03: After completing Mourel's chore.,,,"Použij propustku od Mourela pro vstup do vězení. Uvnitř si promluv s dozorčím Montagem. Najdi způsob, jak vysvobodit vězně.","Brug det adgangskort, som Mourel gav dig, til at komme ind i fængslet. Når du er inde, skal du tale med direktør Montag. Find en måde at befri fangerne på.","Benutze den Pass, den Mourel dir gegeben hat um in das Gefängnis hereinzukommen. Wenn du drin bist, rede mit Direktor Montag. Finde einen Weg um die Gefangenen zu befreien.",,,"Usa el pase que Mourel te dió para entrar en la prisión. Una vez dentro, habla con el Carcelero Montag. Encuentra una forma de liberar a los prisioneros.",,Käytä Mourelin antamaa pääsylupaa päästäksesi vankilaan. Päästyäsi sisälle puhu vankilanjohtaja Montagin kanssa. Keksi keino vapauttaa vangit.,"Utilise le passe que Mourel t'a donné pour entrer dans la prison. Une fois à l'intérieur, parle au gardien Montag. Trouve un moyen de libérer les prisonniers.","Használd a Mourel által adott belépőt, hogy bejuss a börtönbe. Ha bent vagy, beszélj Montag börtön igazgatóval. Találd meg a módját, hogy kiszabadítsd a rabokat.","Usa il tesserino che Mourel ti ha dato per entrare nella prigione. Una volta dentro, parla con il direttore Montag. Trova un modo per liberare i prigionieri.","モーレルからもらった刑務所の許可証を使って入る。 入ったらモンターグと話し、囚人を解放する方法を探す。 -",총독이 준 감옥 통행증을 이용해서 감옥으로 들어가. 들어간 후에 수감자들을 해방하기 위해 몬탕 간수장과 대화해. ,"Gebruik de pas die Mourel je gaf om in de gevangenis te komen. Eenmaal binnen, praat je met Warden Montag. Zoek een manier om de gevangenen te bevrijden.","Bruk passet Mourel ga deg for å komme inn i fengselet. Når du er inne, snakk med fengselsdirektør Montag. Finn en måte å befri fangene på.","Użyj przepustki, którą dał ci Mourel, aby dostać się do więzienia. Po wejściu do środka porozmawiaj z naczelnikiem Montagiem. Znajdź sposób na uwolnienie więźniów.","Use o passe que o Mourel te deu para entrar na prisão. Após entrar, fale com o Carcereiro Montag. Encontre uma maneira de libertar os prisioneiros.",,"Folosește parola pe care ți-a dat-o Mourel pentru a intra în închisoare. Odată înăuntru, vorbește cu Directorul Montag. Găsește o cale să eliberezi prizonierii.","Используй пропуск, полученный у Морела, чтобы пройти в тюрьму. Когда ты будешь внутри, поговори с тюремщиком Монтагом. Найди способ освободить пленников.",,Hapishaneye girmek için Mourel'in size verdiği kartı kullanın. İçeri girdikten sonra Müdür Montag ile konuşun. Mahkûmları serbest bırakmanın bir yolunu bulun. -Use the Warden's key to get into the prison cell blocks and find a way to free the prisoners.,TXT_ILOG1010,MAP05,,,"Použij dozorčího klíč k dostání se do vězeňského bloku s celami a najdi způsob, jak vysvobodit vězně.",Brug fængselsdirektørens nøgle til at komme ind i fængselscelleblokkene og find en måde at befri fangerne på.,"Benutze den Schlüssel des Direktors um in die Zellenblöcke zu kommen und finde heraus, wie man die Gefangenen befreien kann.",,,Usa la llave del Carcelero para entrar en los bloques de celdas y encuentra una forma de liberar a los prisioneros.,Usa la llave del Carcelero para entrar a los bloques de celdas y encuentra una forma de liberar a los prisioneros.,Käytä vankilanjohtajan avainta päästäksesi vankilan selliosastoille ja keksi keino vapauttaa vangit.,Utilisé la clé du Gardien pour entrer dans les blocs de cellules et trouve un moyen de libérer les prisonners.,"Használd a börtön igazgató kulcsát, hogy bejuss a cella blokkba, és szabadítsd ki a foglyokat.",Usa la chiave del direttore per entrare nella sezione delle celle e trovare un modo per liberare i prigionieri.,ワーデンから鍵を奪って内部に入れ。,"간수장의 열쇠를 써서 감옥 안으로 진입하고, 수감자들을 풀어줄 방법을 찾아봐.",Gebruik de sleutel van de bewaker om in de celblokken van de gevangenis te komen en een manier te vinden om de gevangenen te bevrijden.,Bruk fengselsdirektørens nøkkel for å komme deg inn i fengselsblokkene og finn en måte å befri fangene på.,"Użyj klucza naczelnika, aby dostać się do bloków więziennych i znajdź sposób na uwolnienie więźniów.",Use a chave do Carcereiro para entrar nos blocos de celas e ache uma maneira de libertar os prisioneiros.,,Folosește cheia pe care ți-a dat-o Guvernatorul și găsește o cale să eliberezi prizonierii.,"Используй ключ тюремщика, чтобы пройти к камерам, и найди способ освободить пленников.",,Hapishane hücre bloklarına girmek için Müdürün anahtarını kullanın ve mahkûmları serbest bırakmanın bir yolunu bulun. +",총독이 준 감옥 통행증을 이용해서 감옥으로 들어가. 들어간 후에 수감자들을 해방하기 위해 몬탕 간수장과 대화해. ,"Gebruik de pas die Mourel je gaf om in de gevangenis te komen. Eenmaal binnen, praat je met Warden Montag. Zoek een manier om de gevangenen te bevrijden.","Bruk passet Mourel ga deg for å komme inn i fengselet. Når du er inne, snakk med fengselsdirektør Montag. Finn en måte å befri fangene på.","Użyj przepustki, którą dał ci Mourel, aby dostać się do więzienia. Po wejściu do środka porozmawiaj z naczelnikiem Montagiem. Znajdź sposób na uwolnienie więźniów.","Use o passe que o Mourel te deu para entrar na prisão. Após entrar, fale com o Carcereiro Montag. Encontre uma maneira de libertar os prisioneiros.",,"Folosește parola pe care ți-a dat-o Mourel pentru a intra în închisoare. Odată înăuntru, vorbește cu Directorul Montag. Găsește o cale să eliberezi prizonierii.","Используй пропуск, полученный у Морела, чтобы пройти в тюрьму. Когда ты будешь внутри, поговори с тюремщиком Монтагом. Найди способ освободить пленников.",,Använd passet som Mourel gav dig för att komma in i fängelset. När du väl är inne pratar du med fängelsedirektör Montag. Hitta ett sätt att befria fångarna.,Hapishaneye girmek için Mourel'in size verdiği kartı kullanın. İçeri girdikten sonra Müdür Montag ile konuşun. Mahkûmları serbest bırakmanın bir yolunu bulun. +Use the Warden's key to get into the prison cell blocks and find a way to free the prisoners.,TXT_ILOG1010,MAP05,,,"Použij dozorčího klíč k dostání se do vězeňského bloku s celami a najdi způsob, jak vysvobodit vězně.",Brug fængselsdirektørens nøgle til at komme ind i fængselscelleblokkene og find en måde at befri fangerne på.,"Benutze den Schlüssel des Direktors um in die Zellenblöcke zu kommen und finde heraus, wie man die Gefangenen befreien kann.",,,Usa la llave del Carcelero para entrar en los bloques de celdas y encuentra una forma de liberar a los prisioneros.,Usa la llave del Carcelero para entrar a los bloques de celdas y encuentra una forma de liberar a los prisioneros.,Käytä vankilanjohtajan avainta päästäksesi vankilan selliosastoille ja keksi keino vapauttaa vangit.,Utilisé la clé du Gardien pour entrer dans les blocs de cellules et trouve un moyen de libérer les prisonners.,"Használd a börtön igazgató kulcsát, hogy bejuss a cella blokkba, és szabadítsd ki a foglyokat.",Usa la chiave del direttore per entrare nella sezione delle celle e trovare un modo per liberare i prigionieri.,ワーデンから鍵を奪って内部に入れ。,"간수장의 열쇠를 써서 감옥 안으로 진입하고, 수감자들을 풀어줄 방법을 찾아봐.",Gebruik de sleutel van de bewaker om in de celblokken van de gevangenis te komen en een manier te vinden om de gevangenen te bevrijden.,Bruk fengselsdirektørens nøkkel for å komme deg inn i fengselsblokkene og finn en måte å befri fangene på.,"Użyj klucza naczelnika, aby dostać się do bloków więziennych i znajdź sposób na uwolnienie więźniów.",Use a chave do Carcereiro para entrar nos blocos de celas e ache uma maneira de libertar os prisioneiros.,,Folosește cheia pe care ți-a dat-o Guvernatorul și găsește o cale să eliberezi prizonierii.,"Используй ключ тюремщика, чтобы пройти к камерам, и найди способ освободить пленников.",,Använd fängelsedirektörens nyckel för att ta dig in i fängelsets cellblock och hitta ett sätt att befria fångarna.,Hapishane hücre bloklarına girmek için Müdürün anahtarını kullanın ve mahkûmları serbest bırakmanın bir yolunu bulun. "Destroy the power crystal that runs the power grid which drives the Order's shields. Go visit Worner, a spy we recruited in the warehouse of the power station. Don't forget to visit the medic and the weapons trainer before you go.",TXT_ILOG1011,MAP03: After accepting Macil's second mission.,,,"Znič energetický krystal, který napájí elektrickou síť, kterou jsou poháněné štíty Řádu. Jdi navštívit Wornera, špióna, kterého jsme najali ve skladu elektrárny. Nezapomeň navštívit zdravotníka a učitele střelby, než půjdeš.","Ødelæg energikrystallen, der driver det strømnet, som driver Ordenens skjolde. Besøg Worner, en spion, som vi rekrutterede i lageret på kraftværket. Glem ikke at besøge lægen og våbentræneren, før du går.","Zerstöre den Energiekristall der die Energieversorgung für die Kraftschilde kontrolliert. Suche Worner auf, einen Spion, den wir im Lagerhaus des Kraftwerks rekrutiert haben. Vergiß nicht, den Sanitäter und den Waffentrainer aufzusuchen, bevor du gehst.",,,"Destruye el cristal de poder que impulsa la red eléctrica que alimenta los escudos de La Orden. Busca a Worner, un espía que reclutamos en el almacén de la central eléctrica. Recuerda visitar al médico y al entrenador de armas.",,"Tuhoa kaupungin sähköverkon voimanlähteenä toimiva voimakristalli, jonka voimaa Veljeskunnan kilvet käyttävät. Mene tapaamaan Worneria, vakoojaa, jonka värväsimme voimalaitoksen varastolta. Älä unohda vierailla lääkintämiehen ja asekouluttajan luona, ennen kuin lähdet.","Détruis le cristal qui alimente la grille énergétique des boucliers de l'Ordre. Va voir Worner, un espion que nous avons recruté dans l'entrepôt de la centrale éléctrique. N'oublie pas d'aller voir le maître d'armes et le médecin avant d'y aller.","Semmisítsd meg az erő kristályt, ami a Rend külső védőpajzsát hajtja az elektromos hálózaton keresztül. Keresd fel az erőműtől betoborzott kémünket, Wornert. Ne felejtsd el meglátogatni a szanitécet és a fegyvermestert mielőtt nekiindulsz.","Distruggi il cristallo che fornisce energia agli scudi dell'Ordine. Trova Worner, una spia che abbiamo reclutato nel magazzino della centrale energetica. Non scordarti di passare dal medico e dall'addestratore di armi prima di andare.","送電網を動かしているパワークリスタルを破壊してオーダーのシールドを止める。 発電所の倉庫に潜らせたスパイ、ワーナーを訪ねる。 -その前にメディックと武器トレーナーに会うのを忘れるな。","오더의 방어막을 유지하는 동력 망의 전력원인 수정체를 파괴하자. 우선, 발전소 창고에 있는 우리 쪽 첩자인 워너에게 찾아가 보자. 가기 전에 의무관이랑 무기 담당관을 만나는 것도 잊지 말고!","Vernietig het energiekristal dat het stroomnet dat de schilden van de Orde aandrijft. Ga naar Worner, een spion die we in het magazijn van de centrale hebben gerekruteerd. Vergeet niet om de dokter en de wapentrainer te bezoeken voor je vertrekt.","Ødelegg kraftkrystallen som driver kraftnettet som driver ordenens skjold. Besøk Worner, en spion vi rekrutterte i lageret til kraftstasjonen. Ikke glem å besøke medisineren og våpentreneren før du går.","Zniszcz kryształ mocy, który zasila sieć energetyczną napędzającą tarcze Zakonu. Idź odwiedzić Wornera, szpiega, którego zwerbowaliśmy w magazynie elektrowni. Nie zapomnij przed wyjściem odwiedzić medyka i trenera broni.","Destrua o cristal de energia que alimenta a rede elétrica por trás dos escudos da Ordem. Visite o Worner, um espião que recrutamos no depósito da usina de energia. Não se esqueça de visitar o médico e o treinador de armas antes de ir.",,"Distruge cristalul de nergie care alimentează câmpurile Ordinului. Vizitează pe Worner, un spion recrutat în depozitul stației. Nu uita să vorbești cu medicul și antrenorul de arme înainte.","Уничтожь кристалл, питающий энергосеть, от которой работают щиты Ордена. Поговори с Уорнэром, шпионом Сопротивления, на складе электростанции. Не забудь перед уходом посетить медика и инструктора по стрельбе.",,Tarikat'ın kalkanlarını çalıştıran güç şebekesini çalıştıran güç kristalini yok edin. Güç istasyonunun deposunda işe aldığımız casus Worner'ı ziyaret edin. Gitmeden önce sıhhiyeciyi ve silah eğitmenini ziyaret etmeyi unutmayın. +その前にメディックと武器トレーナーに会うのを忘れるな。","오더의 방어막을 유지하는 동력 망의 전력원인 수정체를 파괴하자. 우선, 발전소 창고에 있는 우리 쪽 첩자인 워너에게 찾아가 보자. 가기 전에 의무관이랑 무기 담당관을 만나는 것도 잊지 말고!","Vernietig het energiekristal dat het stroomnet dat de schilden van de Orde aandrijft. Ga naar Worner, een spion die we in het magazijn van de centrale hebben gerekruteerd. Vergeet niet om de dokter en de wapentrainer te bezoeken voor je vertrekt.","Ødelegg kraftkrystallen som driver kraftnettet som driver ordenens skjold. Besøk Worner, en spion vi rekrutterte i lageret til kraftstasjonen. Ikke glem å besøke medisineren og våpentreneren før du går.","Zniszcz kryształ mocy, który zasila sieć energetyczną napędzającą tarcze Zakonu. Idź odwiedzić Wornera, szpiega, którego zwerbowaliśmy w magazynie elektrowni. Nie zapomnij przed wyjściem odwiedzić medyka i trenera broni.","Destrua o cristal de energia que alimenta a rede elétrica por trás dos escudos da Ordem. Visite o Worner, um espião que recrutamos no depósito da usina de energia. Não se esqueça de visitar o médico e o treinador de armas antes de ir.",,"Distruge cristalul de nergie care alimentează câmpurile Ordinului. Vizitează pe Worner, un spion recrutat în depozitul stației. Nu uita să vorbești cu medicul și antrenorul de arme înainte.","Уничтожь кристалл, питающий энергосеть, от которой работают щиты Ордена. Поговори с Уорнэром, шпионом Сопротивления, на складе электростанции. Не забудь перед уходом посетить медика и инструктора по стрельбе.",,"Förstör kraftkristallen som driver kraftnätet som driver ordens sköldar. Gå och besök Worner, en spion som vi rekryterade i kraftverkets lager. Glöm inte att besöka läkaren och vapentränaren innan du går.",Tarikat'ın kalkanlarını çalıştıran güç şebekesini çalıştıran güç kristalini yok edin. Güç istasyonunun deposunda işe aldığımız casus Worner'ı ziyaret edin. Gitmeden önce sıhhiyeciyi ve silah eğitmenini ziyaret etmeyi unutmayın. Destroy the power crystal that runs the power grid which drives the Order's shields. Use the I.D. to get into the power station. You may want to check out the storeroom above Worner.,TXT_ILOG1012,MAP04: After talking to Worner.,,,"Znič energetický krystal, který napájí elektrickou síť, kterou jsou poháněné štíty Řádu. Použij získanou legitimaci pro přístup do elektrárny. Možná by stálo za to podívat se do skladištní místnosti nad Wornerem.","Ødelæg energikrystallen, der driver det kraftnet, som driver Ordenens skjolde. Brug identifikationskortet til at komme ind i kraftværket. Du kan tjekke lagerrummet over Worner.",Zerstöre den Energiekristall der die Energieversorgung für die Kraftschilde kontrolliert. Benutze die Identitätskarte. um in das Kraftwerk zu gelangen. Du solltest den Abstellraum beim Lagerhaus mal inspizieren.,,,Destruye el cristal de poder que impulsa la red eléctrica que alimenta los escudos de La Orden. Usa la identificación para entrar a la central eléctrica. Quizás quieras revisar el cuarto de almacenamiento encima de Worner.,,"Tuhoa kaupungin sähköverkon voimanlähteenä toimiva voimakristalli, jonka voimaa Veljeskunnan kilvet käyttävät. Käytä henkilötunnistetta päästäksesi voimalaitokselle. Saatat haluta vilkaista varastohuonetta Wornerin yläpuolella.",Détruis le cristal qui alimente la grille énergétique des boucliers de l'Ordre. Utilise la carte d'identité pour entrer dans la centrale. Il faudrait que tu aille voir la salle de stockage au dessus de Worner.,"Semmisítsd meg az erő kristályt, ami a Rend külső védőpajzsát hajtja az elektromos hálózaton keresztül. Használd az igazolványt, hogy bejuss az erőműbe. Jobban jársz, ha benézel a Worner fölötti tárolószobába.",Distruggi il cristallo che fornisce energia agli scudi dell'Ordine. Usa il tesserino d'identificazione per entrare nella centrale energetica. Ti conviene controllare il deposito che si trova sopra Worner.,"送電網を動かしているパワークリスタルを破壊してオーダーのシールドを止める。 手に入れたI.D.を使って発電所に入る。 -ワーナーの言う上階の部屋も余裕があったら調べる。",오더의 방어막을 유지하는 동력 망의 전력원인 수정체를 파괴하자. 신분증을 이용해서 발전소 안으로 들어가. 그리고 워너 위에 창고도 확인하는 거 잊지 마!,Vernietig het energiekristal dat het elektriciteitsnet dat de schilden van de Orde aandrijft. Gebruik de I.D. om in de centrale te komen. Je kunt het magazijn boven Worner bekijken.,Ødelegg kraftkrystallen som driver kraftnettet som driver Ordenens skjold. Bruk I.D. for å komme inn i kraftstasjonen. Det kan være lurt å sjekke ut lagerrommet over Worner.,"Zniszcz kryształ mocy, który zasila sieć energetyczną napędzającą tarcze Zakonu. Użyj I.D., aby dostać się do elektrowni. Możesz chcieć sprawdzić magazyn nad Wornerem.",Destrua o cristal de energia que alimenta a rede elétrica por trás dos escudos da Ordem. Use a identificação para infiltrar a usina de energia. Você pode querer dar uma olhada no depósito acima do Worner.,,Distruge critalul energetic care alimentează scuturile Ordinului. Folosește cardul pentru a intra în stația de alimentare. Ai putea verifica și depozitul de deasupra lui Worner.,"Уничтожь кристалл, питающий энергосеть, от которой работают щиты Ордена. Пройди на электростанцию по удостоверению. Возможно, ты захочешь проверить склад на втором этаже, о котором говорил Уорнэр.",,Tarikat'ın kalkanlarını çalıştıran güç şebekesini çalıştıran güç kristalini yok edin. Güç istasyonuna girmek için kimliği kullanın. Worner'ın üstündeki depoyu kontrol etmek isteyebilirsiniz. +ワーナーの言う上階の部屋も余裕があったら調べる。",오더의 방어막을 유지하는 동력 망의 전력원인 수정체를 파괴하자. 신분증을 이용해서 발전소 안으로 들어가. 그리고 워너 위에 창고도 확인하는 거 잊지 마!,Vernietig het energiekristal dat het elektriciteitsnet dat de schilden van de Orde aandrijft. Gebruik de I.D. om in de centrale te komen. Je kunt het magazijn boven Worner bekijken.,Ødelegg kraftkrystallen som driver kraftnettet som driver Ordenens skjold. Bruk I.D. for å komme inn i kraftstasjonen. Det kan være lurt å sjekke ut lagerrommet over Worner.,"Zniszcz kryształ mocy, który zasila sieć energetyczną napędzającą tarcze Zakonu. Użyj I.D., aby dostać się do elektrowni. Możesz chcieć sprawdzić magazyn nad Wornerem.",Destrua o cristal de energia que alimenta a rede elétrica por trás dos escudos da Ordem. Use a identificação para infiltrar a usina de energia. Você pode querer dar uma olhada no depósito acima do Worner.,,Distruge critalul energetic care alimentează scuturile Ordinului. Folosește cardul pentru a intra în stația de alimentare. Ai putea verifica și depozitul de deasupra lui Worner.,"Уничтожь кристалл, питающий энергосеть, от которой работают щиты Ордена. Пройди на электростанцию по удостоверению. Возможно, ты захочешь проверить склад на втором этаже, о котором говорил Уорнэр.",,Förstör kraftkristallen som driver kraftnätet som driver Ordens sköldar. Använd ID-kortet för att ta dig in i kraftstationen. Du kanske vill kolla in förrådet ovanför Worner.,Tarikat'ın kalkanlarını çalıştıran güç şebekesini çalıştıran güç kristalini yok edin. Güç istasyonuna girmek için kimliği kullanın. Worner'ın üstündeki depoyu kontrol etmek isteyebilirsiniz. Destroy the power crystal that runs the power grid which drives the Order's shields. Go talk to Ketrick in the core area.,TXT_ILOG1013,"MAP04: After talking to ""Mr. Crispy"".",,,"Znič energetický krystal, který napájí elektrickou síť, kterou jsou poháněné štíty Řádu. Jdi za Ketrickem u jádra.","Ødelæg kraftkrystallen, der driver det kraftnet, som driver Ordenens skjolde. Gå hen og tal med Ketrick i kerneområdet.","Zerstöre den Energiekristall der die Energieversorgung für die Kraftschilde kontrolliert. Suche Worner auf, einen Spion, den wir im Lagerhaus des Kraftwerks rekrutiert haben. Vergiß nicht, den Sanitäter und den Waffentrainer aufzusuchen, bevor du gehst.",,,Destruye el cristal de poder que impulsa la red eléctrica que alimenta los escudos de La Orden. Habla con Ketrick en el área del núcleo.,,"Tuhoa kaupungin sähköverkon voimanlähteenä toimiva voimakristalli, jonka voimaa Veljeskunnan kilvet käyttävät. Puhu Ketrickin kanssa reaktorisydämen alueella.",Détruis le cristal qui alimente la grille énergétique des boucliers de l'Ordre. Va parler à Ketrick dans la zone du cœur.,"Semmisítsd meg az erő kristályt, ami a Rend külső védőpajzsát hajtja az elektromos hálózaton keresztül. Megleled Ketricket a mag térségben.",Distruggi il cristallo che fornisce energia agli scudi dell'Ordine. Vai a parlare con Ketrick nell'area del nucleo.,"送電網を動かしているパワークリスタルを破壊してオーダーのシールドを止める。 -コアエリアでケトリックと話す。",오더의 방어막을 유지하는 동력 망의 전력원인 수정체를 파괴하자. 중심부에 있는 케트릭과 대화해.,Vernietig het energiekristal dat het elektriciteitsnet dat de schilden van de Orde aandrijft. Ga in het kerngebied met Ketrick praten.,Ødelegg kraftkrystallen som driver kraftnettet som driver Ordenens skjold. Snakk med Ketrick i kjerneområdet.,"Zniszcz kryształ mocy, który uruchamia sieć energetyczną napędzającą tarcze Zakonu. Idź porozmawiać z Ketrickiem w obszarze rdzenia.",Destrua o cristal de energia que alimenta a rede elétrica por trás dos escudos da Ordem. Fale com o Ketrick na área do núcleo.,,Distruge cristalul de energie care alimentează scuturile Ordinului. Vorbește cu Ketrick în zona nucleului.,"Уничтожь кристалл, питающий энергосеть Ордена и их щиты. Поговори с Кетриком возле реактора.",,Tarikat'ın kalkanlarını çalıştıran güç şebekesini çalıştıran güç kristalini yok edin. Çekirdek alanda Ketrick ile konuş. +コアエリアでケトリックと話す。",오더의 방어막을 유지하는 동력 망의 전력원인 수정체를 파괴하자. 중심부에 있는 케트릭과 대화해.,Vernietig het energiekristal dat het elektriciteitsnet dat de schilden van de Orde aandrijft. Ga in het kerngebied met Ketrick praten.,Ødelegg kraftkrystallen som driver kraftnettet som driver Ordenens skjold. Snakk med Ketrick i kjerneområdet.,"Zniszcz kryształ mocy, który uruchamia sieć energetyczną napędzającą tarcze Zakonu. Idź porozmawiać z Ketrickiem w obszarze rdzenia.",Destrua o cristal de energia que alimenta a rede elétrica por trás dos escudos da Ordem. Fale com o Ketrick na área do núcleo.,,Distruge cristalul de energie care alimentează scuturile Ordinului. Vorbește cu Ketrick în zona nucleului.,"Уничтожь кристалл, питающий энергосеть Ордена и их щиты. Поговори с Кетриком возле реактора.",,Förstör kraftkristallen som driver kraftnätet som driver ordens sköldar. Gå och prata med Ketrick i kärnområdet.,Tarikat'ın kalkanlarını çalıştıran güç şebekesini çalıştıran güç kristalini yok edin. Çekirdek alanda Ketrick ile konuş. "Destroy the power crystal. Go talk to Ketrick, bring the walkway up using the switches, then use this id for the elevator.",TXT_ILOG1014,MAP04: After talking to Sammis.,,,"Znič energetický krystal, který napájí elektrickou síť, kterou jsou poháněné štíty Řádu. Jdi si promluvit s Ketrickem, vyzvedni schodiště pomocí tlačítek a pak ve výtahu použij tuhle kartu.","Ødelæg kraftkrystallen. Gå hen og tal med Ketrick, bring gangbroen op ved hjælp af kontakterne, og brug derefter dette id til elevatoren.",Zerstöre den Energiekristall der die Energieversorgung für die Kraftschilde kontrolliert. Gehe zu Ketrick im Reaktorkern.,,,"Destruye el cristal de poder. Habla con Ketrick, alza la pasarela usando los interruptores, luego usa esta identificación para el ascensor.",,Tuhoa voimakristalli. Mene puhumaan Ketrickin kanssa. Tuo kulkusilta vivuilla ylös ja sitten käytä tätä tunnistetta hissiin.,"Détruis le cristal. Va parler à Ketrick. Fais monter la coursive en utilisant les boutons, puis utilise ta carte d'identité pour accéder à l'ascenseur.","Semmisítsd meg az erő kristályt. Menj és beszélj Kedrickkel, a kapcsolóval emeld meg a hidat, aztán használd az igazolványt a lifthez.","Distruggi il cristallo. Parla con Ketrick, fai alzare la passerella con i pulsanti, e poi usa questo tesserino per l'ascensore.","パワークリスタルを破壊してオーダーのシールドを止める。 -ケトリックと話し、スイッチを動かし通路を上げ、エレベーターにIDを使う。",수정체를 파괴해. 케트릭과 대화하고 나서 스위치를 눌러서 진입로를 작동시켜. 그리고 이 신분증을 이용해서 승강기를 올라타.,"Vernietig het energiekristal. Ga met Ketrick praten, breng de gang naar boven met behulp van de schakelaars, gebruik dan deze id voor de lift.","Ødelegg kraftkrystallen. Snakk med Ketrick, få gangbroen opp ved hjelp av bryterne, og bruk denne id-en til heisen.","Zniszcz kryształ mocy. Idź porozmawiać z Ketrickiem, podnieś chodnik używając przełączników, a następnie użyj tego id do windy.","Destrua o cristal de energia. Fale com o Ketrick, faça a passarela subir usando os interruptores e depois use esta identificação para o elevador.",,"Distruge cristalul energetic. Vorbește cu Ketrick, redă pasarela folosind butoanele, apoi folosește cardul pentru lift.","Уничтожь кристалл. Поговори с Кетриком, пройди наверх с помощью переключателей, затем используй удостоверение для доступа к лифту.",,"Güç kristalini yok et. Ketrick ile konuşun, anahtarları kullanarak geçidi yukarı getirin, sonra asansör için bu kimliği kullanın." +ケトリックと話し、スイッチを動かし通路を上げ、エレベーターにIDを使う。",수정체를 파괴해. 케트릭과 대화하고 나서 스위치를 눌러서 진입로를 작동시켜. 그리고 이 신분증을 이용해서 승강기를 올라타.,"Vernietig het energiekristal. Ga met Ketrick praten, breng de gang naar boven met behulp van de schakelaars, gebruik dan deze id voor de lift.","Ødelegg kraftkrystallen. Snakk med Ketrick, få gangbroen opp ved hjelp av bryterne, og bruk denne id-en til heisen.","Zniszcz kryształ mocy. Idź porozmawiać z Ketrickiem, podnieś chodnik używając przełączników, a następnie użyj tego id do windy.","Destrua o cristal de energia. Fale com o Ketrick, faça a passarela subir usando os interruptores e depois use esta identificação para o elevador.",,"Distruge cristalul energetic. Vorbește cu Ketrick, redă pasarela folosind butoanele, apoi folosește cardul pentru lift.","Уничтожь кристалл. Поговори с Кетриком, пройди наверх с помощью переключателей, затем используй удостоверение для доступа к лифту.",,"Förstör kraftkristallen. Gå och prata med Ketrick, ta upp gångvägen med hjälp av brytarna och använd sedan denna id för hissen.","Güç kristalini yok et. Ketrick ile konuşun, anahtarları kullanarak geçidi yukarı getirin, sonra asansör için bu kimliği kullanın." Find the town entrance that the Order has guarded. Open the door and bring the guard's uniform back to Weran.,TXT_ILOG1015,,,,"Najdi vchod do města, který Řád hlídá. Otevři dveře a přines hlídačovu uniformu Weranovi.","Find byens indgang, som Ordenen har bevogtet. Åbn døren og bring vagtens uniform tilbage til Weran.","Finde den Ausgang zur Stadt, der vom Orden bewacht wird. Öffne dir Tür und bringe die Uniform des Wächters zu Weran.",,,Encuentra la entrada al pueblo que La Orden tiene guardada. Abre la puerta y tráele de vuelta a Weran el uniforme del guardia.,,Löydä Veljeskunnan vartioima kaupungin sisäänkäynti. Avaa ovi ja tuo vartijan univormu Weranille.,Trouve l'entrée de la ville que L'Ordre garde fermée. Ouvre-la et amène l'uniforme du garde à Weran.,"Keresd meg a város bejáratot, amit a Rend őrzött. Nyisd ki az ajtót, és vidd vissza az uniformist Weranhoz.",Trova l'entrata verso la città che l'Ordine ha chiuso. Apri l'ingresso e riporta l'uniforme della guardia a Weran.,"オーダーが封鎖している町への入り口を見つける。 -ドアを開け、ガードの制服をウェランに持って帰る。",오더의 경비가 지키고 있는 마을의 입구를 찾아. 문을 연 뒤 그 경비의 전투복을 챙겨서 워렌에게 전해줘.,Zoek de stadstoegang die de Orde heeft bewaakt. Open de deur en breng het uniform van de bewaker terug naar Weran.,Finn inngangen til byen som Ordenen har bevoktet. Åpne døren og ta med vaktens uniform tilbake til Weran.,"Znajdź wejście do miasta, którego pilnuje Zakon. Otwórz drzwi i przynieś Weranowi mundur strażnika.",Encontre a entrada da cidade que a Ordem está vigiando. Abra a porta e leve o uniforme do guarda de volta para o Weran.,,Găsește intrarea orașului pe care Ordinul a păzit-o. Deschide ușa și du uniforma paznicului la Weran.,"Найди выход в город, охраняемый Орденом. Открой дверь и принеси униформу стражника Уэрану.",,Tarikatın koruduğu kasaba girişini bulun. Kapıyı açın ve muhafız üniformasını Weran'a geri getirin. +ドアを開け、ガードの制服をウェランに持って帰る。",오더의 경비가 지키고 있는 마을의 입구를 찾아. 문을 연 뒤 그 경비의 전투복을 챙겨서 워렌에게 전해줘.,Zoek de stadstoegang die de Orde heeft bewaakt. Open de deur en breng het uniform van de bewaker terug naar Weran.,Finn inngangen til byen som Ordenen har bevoktet. Åpne døren og ta med vaktens uniform tilbake til Weran.,"Znajdź wejście do miasta, którego pilnuje Zakon. Otwórz drzwi i przynieś Weranowi mundur strażnika.",Encontre a entrada da cidade que a Ordem está vigiando. Abra a porta e leve o uniforme do guarda de volta para o Weran.,,Găsește intrarea orașului pe care Ordinul a păzit-o. Deschide ușa și du uniforma paznicului la Weran.,"Найди выход в город, охраняемый Орденом. Открой дверь и принеси униформу стражника Уэрану.",,Hitta stadens ingång som ordern har bevakat. Öppna dörren och ta med dig vaktuniformen tillbaka till Weran.,Tarikatın koruduğu kasaba girişini bulun. Kapıyı açın ve muhafız üniformasını Weran'a geri getirin. "Take the flamethrower parts to Irale. Find the sewer maintenance door. Find and drain the reclamation tank inside the castle. At the bottom is a hidden entrance to the sewers. Down that entrance is where the gate controls are, somewhere.",TXT_ILOG1016,,,,Přines součásti plamenometu k Iralemu. Najdi kanálové údržbové dveře. Najdi a vypusť vodní nádrž uvnitř hradu. Na dně je skrytý vchod do dalších stok. Někde uvnitř je ovládání bran.,"Tag flammekasterens dele med til Irale. Find døren til vedligeholdelse af kloakken. Find og tøm genvindingstanken inde på slottet. I bunden er der en skjult indgang til kloakkerne. Nede ved denne indgang er der et sted, hvor kontrolelementerne til porten er.",Bringe dir Flammenwerferteile zu Irale. Finde die Wartungstür in der Kanalisation. Finde und leere den Sammeltank in der Burg. Am Boden ist ein versteckter Eingang zur Kanalisation. Dort ist die Steuerung für die Tore. Zerstöre sie.,,,"Llévale las partes de lanzallamas a Irale. Encuentra la puerta de mantenimiento de las alcantarillas. Encuentra y drena el tanque de reclamación dentro del castillo. Al fondo hay una entrada oculta a las alcantarillas. Bajando por esa entrada es donde se encuentran los controles de la puerta, en algún lugar.","Llévale las partes del lanzallamas a Irale. Encuentra la puerta de mantenimiento de la alcantarilla. Encuentra y drena el tanque de recuperación adentro del castillo. En el fondo de esa entrada están los controles de las puertas, en algún lugar.","Toimita liekinheittimen osat Iralelle. Etsi viemärin huolto-ovi. Etsi ja tyhjennä nesteentalteenottoallas linnan sisällä. Sen pohjalla on viemärin salainen sisäänkäynti, jonka sisältä portin ohjaimet jostakin löytyvät.",Amène les pièces du lance-flamme à Irale. Trouve l'entrée de maintenance des égouts. Fais vider le réservoir de recyclage du château. Au fond se trouve une entrée cachée vers les égouts. Les contrôles de la porte s'y trouvent.,Vidd a lángszóró darabokat Iralehez. Keresd meg a kanális szervíz ajtaját. Keresd meg a lefolyót és szárító tartályt a kastélyban. Az alján található egy titkos bejárat a kanálishoz. Túl ezen a bejáraton fogod megtalálni a kapu irányítópultot.,"Porta i pezzi del lanciafiamme da Irale. Trova l'entrata di manutenzione per le fogne. Svuota la vasca di recupero fluidi. Nel fondo c'è un'entrata nascosta per le fogne. I controlli dei cancelli sono laggiù, da qualche parte.","火炎放射器の部品をイラールに持っていく。 下水道のメンテナンス室を見つけ、 城内の貯水タンクを見つけて排水。 -その下には下水道への隠された入り口があり、その奥にゲートコントロールがある。","이 화염방사기 부품을 들고 이롤리에게 가져가. 하수도 정비소로 향하는 문을 찾은 뒤, 성안에 있는 수조를 찾고 내용물을 배출해. 그 밑에는 하수도로 향하는 숨겨진 통로가 있어. 그 안에는 분명히 성문 관리 장치가 있을 거야.","Neem de vlammenwerper delen naar Irale. Zoek de deur voor het rioolonderhoud. Zoek en laat de inpolderingstank in het kasteel leeglopen. Onderin is een verborgen ingang naar de riolering. Onderaan die ingang is waar de poortbediening is, ergens.","Ta flammekasterdelene til Irale. Finn vedlikeholdsdøren til kloakken. Finn og tøm gjenvinningstanken inne i slottet. Nederst er det en skjult inngang til kloakken. Ned den inngangen er hvor portkontrollene er, et eller annet sted.",Zabierz części miotacza ognia do Irale. Znajdź drzwi do konserwacji kanałów. Znajdź i osusz zbiornik rekultywacyjny wewnątrz zamku. Na dole jest ukryte wejście do kanałów. Na dole tego wejścia jest gdzieś sterowanie bramą.,Leve as peças do lança-chamas ao Irale. Ache a porta de manutenção do esgoto. Encontre e drene o tanque de recuperação dentro do castelo. No fundo há uma entrada oculta para o esgoto. Entre lá e encontre os controles do portão.,,"Du bucățiile aruncătorului de flăcări la Irale. Găsește ușa de mentenanță de la canale. Găsește și drenează rezervorul de recuperare din interiorul castelului. La fund e o intrare secretă către canale. Jos, se pot acționa porțiile, de undeva.",Отнеси детали огнемёта Ирэйлу. Найди дверь техобслуживания канализации. Найди бак для переработки и слей из него жидкость. На его дне находится потайной вход в стоки. Где-то за ним находится механизм управления воротами.,,Alev makinesi parçalarını İrale'ye götürün. Kanalizasyon bakım kapısını bulun. Kalenin içindeki ıslah tankını bulun ve boşaltın. En altta kanalizasyona giden gizli bir giriş var. O girişin aşağısında kapı kontrollerinin olduğu yer var. +その下には下水道への隠された入り口があり、その奥にゲートコントロールがある。","이 화염방사기 부품을 들고 이롤리에게 가져가. 하수도 정비소로 향하는 문을 찾은 뒤, 성안에 있는 수조를 찾고 내용물을 배출해. 그 밑에는 하수도로 향하는 숨겨진 통로가 있어. 그 안에는 분명히 성문 관리 장치가 있을 거야.","Neem de vlammenwerper delen naar Irale. Zoek de deur voor het rioolonderhoud. Zoek en laat de inpolderingstank in het kasteel leeglopen. Onderin is een verborgen ingang naar de riolering. Onderaan die ingang is waar de poortbediening is, ergens.","Ta flammekasterdelene til Irale. Finn vedlikeholdsdøren til kloakken. Finn og tøm gjenvinningstanken inne i slottet. Nederst er det en skjult inngang til kloakken. Ned den inngangen er hvor portkontrollene er, et eller annet sted.",Zabierz części miotacza ognia do Irale. Znajdź drzwi do konserwacji kanałów. Znajdź i osusz zbiornik rekultywacyjny wewnątrz zamku. Na dole jest ukryte wejście do kanałów. Na dole tego wejścia jest gdzieś sterowanie bramą.,Leve as peças do lança-chamas ao Irale. Ache a porta de manutenção do esgoto. Encontre e drene o tanque de recuperação dentro do castelo. No fundo há uma entrada oculta para o esgoto. Entre lá e encontre os controles do portão.,,"Du bucățiile aruncătorului de flăcări la Irale. Găsește ușa de mentenanță de la canale. Găsește și drenează rezervorul de recuperare din interiorul castelului. La fund e o intrare secretă către canale. Jos, se pot acționa porțiile, de undeva.",Отнеси детали огнемёта Ирэйлу. Найди дверь техобслуживания канализации. Найди бак для переработки и слей из него жидкость. На его дне находится потайной вход в стоки. Где-то за ним находится механизм управления воротами.,,Ta med dig flamethrowerdelarna till Irale. Hitta dörren till underhållet av kloakerna. Hitta och töm återvinningstanken inne i slottet. I botten finns en dold ingång till avloppen. Nere vid den ingången finns portkontrollerna någonstans.,Alev makinesi parçalarını İrale'ye götürün. Kanalizasyon bakım kapısını bulun. Kalenin içindeki ıslah tankını bulun ve boşaltın. En altta kanalizasyona giden gizli bir giriş var. O girişin aşağısında kapı kontrollerinin olduğu yer var. Join the assault on the castle. Find and take out the Programmer. See the medic and the weapons trainer. Spend everything you've got. This is going to be a hell of a fight.,TXT_ILOG1017,,,,"Připoj se k útoku na hrad. Najdi a zabij Programátora. Zajdi si ke zdravotníkovi a učiteli střelby. Utrať vše, co máš. Tohle bude tvrdý boj.","Deltag i angrebet på slottet. Find og dræb programmøren. Se lægen og våbentræneren. Brug alt, hvad du har. Dette bliver en helvedes kamp.","Schließe dich dem Angriff auf die Burg an. Finde den Programmierer und schalte ihn aus. Suche den Sanitäter und den Waffentrainer auf. Kaufe was immer du kannst, das wird ein höllischer Kampf.",,,Únete al asalto en el castillo. Encuentra y elimina al Programador. Ve a ver al médico y entrenador de armas. Gasta todo lo que tengas. Esto va a ser una batalla tremenda.,Únete al asalto en el castillo. Encuentra y elimina al Programador. Ve al médico y al entrenador de armas. Gasta todo lo que tengas. Esta será una tremenda batalla.,Osallistu hyökkäykseen linnaa vastaan. Etsi ja kukista Ohjelmoitsija. Tapaa lääkintämiestä ja asekouluttajaa. Käytä kaikki varasi; tästä tulee hitonmoinen taistelu.,"Rejoins l'assaut sur le château. Trouve et tue le Programmeur. Va voir le médecin et le maître d'armes. Dépense tout ce que tu as, ça va être un sacré bain de sang!",Csatlakozz a kastély ostromához. Keresd meg és iktasd ki a Programozót. Menj a szanitéchoz és a fegyver kiképzőhöz. Költs el mindent amit csak tudsz. Gigászi csata előtt állunk.,"Unisciti all'assalto sul castello. Trova e fai fuori il Programmatore. Passa dal medico e dall'addestratore di armi. Ti conviene spendere più che puoi, sarà una dura battaglia.","城内への突撃部隊に加入し、プログラマーを探す。 メディックと武器トレーナーに会っておく。 -この戦いは激しいものになるだろう、使えるものは全て使うつもりで行け。",성을 공략할 공성전에 참여해. 침투해서 프로그래머를 죽일 수 있게. 의무관이랑 무기 담당관을 만나고 네가 살 수 있는 걸 충분히 사. 왜냐하면 이 교전은 끔찍할 테니까.,Doe mee aan de aanval op het kasteel. Zoek en haal de Programmeur eruit. Zie de dokter en de wapentrainer. Geef alles uit wat je hebt. Dit wordt een hels gevecht.,Bli med i angrepet på slottet. Finn og drep programmereren. Gå til legen og våpentreneren. Bruk alt du har. Dette kommer til å bli litt av en kamp.,"Dołącz do szturmu na zamek. Znajdź i zlikwiduj Programistę. Zobacz medyka i trenera broni. Wydaj wszystko, co masz. To będzie piekielnie trudna walka.",Junte-se ao ataque no castelo. Ache e elimine o Programador. Visite o médico e o treinador de armas. Gaste tudo o que você tem. Essa vai ser uma briga das grandes.,,Alătură-te asaltului asupra castelului. Vezi medicul și antrenorul de arme. Cheltuie tot ce ai. O să fie o luptă pe cnste.,Присоединись к атаке на замок. Найди и убей Программиста. Посети медика и инструктора по стрельбе. Не жалей золота: битва будет чертовски жаркой.,,Kaleye yapılan saldırıya katıl. Programcıyı bul ve etkisiz hale getir. Sıhhiyeciyi ve silah eğitmenini gör. Elinizdeki her şeyi harcayın. Bu cehennem gibi bir savaş olacak. +この戦いは激しいものになるだろう、使えるものは全て使うつもりで行け。",성을 공략할 공성전에 참여해. 침투해서 프로그래머를 죽일 수 있게. 의무관이랑 무기 담당관을 만나고 네가 살 수 있는 걸 충분히 사. 왜냐하면 이 교전은 끔찍할 테니까.,Doe mee aan de aanval op het kasteel. Zoek en haal de Programmeur eruit. Zie de dokter en de wapentrainer. Geef alles uit wat je hebt. Dit wordt een hels gevecht.,Bli med i angrepet på slottet. Finn og drep programmereren. Gå til legen og våpentreneren. Bruk alt du har. Dette kommer til å bli litt av en kamp.,"Dołącz do szturmu na zamek. Znajdź i zlikwiduj Programistę. Zobacz medyka i trenera broni. Wydaj wszystko, co masz. To będzie piekielnie trudna walka.",Junte-se ao ataque no castelo. Ache e elimine o Programador. Visite o médico e o treinador de armas. Gaste tudo o que você tem. Essa vai ser uma briga das grandes.,,Alătură-te asaltului asupra castelului. Vezi medicul și antrenorul de arme. Cheltuie tot ce ai. O să fie o luptă pe cnste.,Присоединись к атаке на замок. Найди и убей Программиста. Посети медика и инструктора по стрельбе. Не жалей золота: битва будет чертовски жаркой.,,Gå med i anfallet mot slottet. Hitta och ta ut programmeraren. Se till sjukvårdaren och vapentränaren. Spendera allt du har. Det här kommer att bli en jäkla kamp.,Kaleye yapılan saldırıya katıl. Programcıyı bul ve etkisiz hale getir. Sıhhiyeciyi ve silah eğitmenini gör. Elinizdeki her şeyi harcayın. Bu cehennem gibi bir savaş olacak. Use the key the false Programmer gave you to open an entrance to the Programmer's keep. It has to be where he's hiding. Find the Programmer and kill him.,TXT_ILOG1018,,,,Použij klíč od falešného Programátora pro otevření vchodu do Programátorova doupěte. Tam se musí nacházet. Najdi Programátora a zabij ho.,"Brug den nøgle, som den falske programmør gav dig, til at åbne en indgang til programmørens tårn. Det må være der, hvor han gemmer sig. Find programmøren og dræb ham.","Benutze den Schlüssel des falschen Programmierers um in die Unterkunft des Programmierers einzudringen. Das ist der Ort, wo er sich verstecken dürfte. Finde und töte ihn.",,,Usa la llave que el falso Programador te dió para abrir una entrada a la guarida del Programador. Tiene que ser ahí donde se oculta. Encuentra al Programador y mátalo.,Usa la llave que el falso Programador te dió para abrir la entrada a la güarida del Programador. Debe ser donde está escondido. Encuentra al Programador y mátalo.,Käytä Valeohjelmoitsijan antamaa avainta avataksesi sisäänkäynnin Ohjelmoitsijan linnakkeeseen. Siellä hän varmastikin piilottelee. Etsi Ohjelmoitsija ja tapa hänet.,Utilise la clé que le faux Programmeur t'a donné pour entrer dans le donjon du Programmeur. Il doit s'y cacher. Trouve-le et tues-le.,"Használd az ál-programozótól kapott kulcsot, hogy bejuss a Programozó tornyába. Minden bizonnyal ott bújkál. Keresd meg a Programozót, és öld meg.",Usa la chiave che il falso Programmatore ti ha dato per entrare nella fortezza del Programmatore. Deve essere là che si nasconde. Trova il Programmatore e uccidilo.,"偽プログラマーから貰ったキーを使って本物がいるはずの砦を開く。 -奴はそこに隠れなければならないはず。プログラマーを見つけて殺す。","프로그래머 더미가 준 열쇠를 이용해서 프로그래머의 거주지로 향하는 문을 열어. 안에는 분명히 그가 있을 거야. 프로그래머를 찾으면, 일이 더 나빠지기 전에 죽여.",Gebruik de sleutel die de valse Programmer je gaf om een ingang te openen naar de wacht van de Programmeur. Het moet zijn waar hij zich verbergt. Zoek de Programmeur en vermoord hem.,Bruk nøkkelen den falske programmereren ga deg til å åpne en inngang til programmererens borg. Det må være der han gjemmer seg. Finn programmereren og drep ham.,"Użyj klucza, który dał ci fałszywy Programista, aby otworzyć wejście do kryjówki Programisty. To musi być miejsce, gdzie on się ukrywa. Znajdź Programistę i zabij go.",Use a chave que o falso Programador te deu para abrir uma entrada à fortaleza do Programador. Tem que ser onde ele está escondido. Encontre o Programador e mate-o.,,Folosește cheia pe care Programator fals ți-a dat-o pentru a deschide intrarea către curtea Programatorului. Trebuie să fie locul în care se ascunde. Găsește Programatorul și ucide-l.,"Используй ключ, полученный от фальшивого Программиста, чтобы открыть вход в цитадель. Скорее всего, именно там прячется настоящий Программист. Найди и убей его.",,Sahte Programcı'nın size verdiği anahtarı kullanarak Programcı'nın kalesine bir giriş açın. Saklandığı yer orası olmalı. Programcıyı bul ve öldür. +奴はそこに隠れなければならないはず。プログラマーを見つけて殺す。","프로그래머 더미가 준 열쇠를 이용해서 프로그래머의 거주지로 향하는 문을 열어. 안에는 분명히 그가 있을 거야. 프로그래머를 찾으면, 일이 더 나빠지기 전에 죽여.",Gebruik de sleutel die de valse Programmer je gaf om een ingang te openen naar de wacht van de Programmeur. Het moet zijn waar hij zich verbergt. Zoek de Programmeur en vermoord hem.,Bruk nøkkelen den falske programmereren ga deg til å åpne en inngang til programmererens borg. Det må være der han gjemmer seg. Finn programmereren og drep ham.,"Użyj klucza, który dał ci fałszywy Programista, aby otworzyć wejście do kryjówki Programisty. To musi być miejsce, gdzie on się ukrywa. Znajdź Programistę i zabij go.",Use a chave que o falso Programador te deu para abrir uma entrada à fortaleza do Programador. Tem que ser onde ele está escondido. Encontre o Programador e mate-o.,,Folosește cheia pe care Programator fals ți-a dat-o pentru a deschide intrarea către curtea Programatorului. Trebuie să fie locul în care se ascunde. Găsește Programatorul și ucide-l.,"Используй ключ, полученный от фальшивого Программиста, чтобы открыть вход в цитадель. Скорее всего, именно там прячется настоящий Программист. Найди и убей его.",,Använd nyckeln som den falska programmeraren gav dig för att öppna en ingång till programmerarens borg. Det måste vara där han gömmer sig. Hitta Programmeraren och döda honom.,Sahte Programcı'nın size verdiği anahtarı kullanarak Programcı'nın kalesine bir giriş açın. Saklandığı yer orası olmalı. Programcıyı bul ve öldür. Seek out the Oracle and ask it about the other Sigil pieces. Take your reward and go across to the medic and weapons trainer for health and training.,TXT_ILOG1019,MAP10: After talking to Macil.,,,Najdi Věštce a zeptej se ho na ostatní díly Pečetě. Převezmi si svou odměnu a navštiv zdravotníka a učitele střelby pro zdraví a výcvik.,Opsøg Oraklet og spørg det om de andre Sigil stykker. Tag din belønning og gå over til lægen og våbentræneren for at få sundhed og træning.,Suche das Orakel auf und frage es nach den anderen Sigil-Teilen. Nimm deine Belohnung und suche den Sanitäter und den Waffentrainer auf.,,,Busca al Oráculo y pregúntale sobre las otras piezas del Emblema. Toma tu recompensa y ve al médico y al entrenador de armas para salud y entrenamiento.,Busca al Oráculo y pregúntale acerca de las otras piezas del Emblema. Toma tú recompensa y dirígete con el médico y el entrenador de armas por salúd y entrenamiento.,Etsi Oraakkeli ja kysy häneltä muista Sinetin osista. Vastaanota palkkiosi ja käy lääkintämiehen ja asekouluttajan luona terveydenhoitoa ja koulutusta varten.,"Trouve l'Oracle et demande lui où se trouve les autres pièces du Sigil. Récupère ta récompense, et va voir le médecin et le maître d'armes pour te soigner et t'entraîner.","Kutasd fel az Orákulumot, és érdeklődj a Pecsét további darabjairól. Zsebeld be a jutalmad, és költsd is el szépen a szanitécnál és a fegyvermesternél.",Raggiungi l'Oracolo e chiedigli degli altri pezzi del Sigillo. Prendi la tua ricompensa e visita il dottore e l'addestratore di armi.,"オラクルに会いシジルの欠片について尋ねる。 -強化のためメディックと武器トレーナーに会っておく。",오라클을 찾아서 다른 시질 조각이 어디에 있는지 물어봐. 보상을 받고 치료와 훈련을 위해 의무관과 무기 담당관에게로 가.,Zoek het Orakel op en vraag het over de andere Sigil stukken. Pak je beloning en ga naar de dokter en wapentrainer voor gezondheid en training.,Oppsøk oraklet og spør det om de andre sigil-brikke. Ta belønningen din og gå over til medisineren og våpentreneren for helse og trening.,Poszukaj Wyroczni i zapytaj ją o pozostałe kawałki Sigila. Odbierz nagrodę i przejdź do medyka i trenera broni po zdrowie i trening.,Procure o Oráculo e pergunte o sobre as outras peças do Sigilo. Pegue a sua recompensa e visite o médico e o treinador de armas para recuperar saúde e receber treinamento.,,Caută Oracolul și întreabă de celelalte piese de Sigiliu. Ia-ți recompensa și du-te la medic și antrenorul de arme.,Найди Оракула и спроси у него про другие фрагменты Печати. Возьми свою награду и посети медика и инструктора по стрельбе.,,Kahin'i bulun ve ona diğer Sigil parçalarını sorun. Ödülünüzü alın ve sağlık ve eğitim için sıhhiyeciye ve silah eğitmenine gidin. +強化のためメディックと武器トレーナーに会っておく。",오라클을 찾아서 다른 시질 조각이 어디에 있는지 물어봐. 보상을 받고 치료와 훈련을 위해 의무관과 무기 담당관에게로 가.,Zoek het Orakel op en vraag het over de andere Sigil stukken. Pak je beloning en ga naar de dokter en wapentrainer voor gezondheid en training.,Oppsøk oraklet og spør det om de andre sigil-brikke. Ta belønningen din og gå over til medisineren og våpentreneren for helse og trening.,Poszukaj Wyroczni i zapytaj ją o pozostałe kawałki Sigila. Odbierz nagrodę i przejdź do medyka i trenera broni po zdrowie i trening.,Procure o Oráculo e pergunte o sobre as outras peças do Sigilo. Pegue a sua recompensa e visite o médico e o treinador de armas para recuperar saúde e receber treinamento.,,Caută Oracolul și întreabă de celelalte piese de Sigiliu. Ia-ți recompensa și du-te la medic și antrenorul de arme.,Найди Оракула и спроси у него про другие фрагменты Печати. Возьми свою награду и посети медика и инструктора по стрельбе.,,Sök upp Oraklet och fråga det om de andra Sigilbitarna. Ta din belöning och gå över till läkaren och vapentränaren för hälsa och träning.,Kahin'i bulun ve ona diğer Sigil parçalarını sorun. Ödülünüzü alın ve sağlık ve eğitim için sıhhiyeciye ve silah eğitmenine gidin. "The second piece lies at the heart of the crimson and obsidian tower. There you must find the Bishop, who awaits you. Take the Oracle's token to the key master in the borderlands. Once you have destroyed the Bishop, return to the Oracle.",TXT_ILOG1020,,,,"Druhý díl leží v srdci věže karmíno-obsidiánové. Tam musíš najít Biskupa, který tě očekává. Vezmi Věštcův pas ke klíčníkovi v pohraničí. Až zabiješ Biskupa, vrať se k Věštci.","Den anden brik ligger i hjertet af det purpurfarvede og obsidianske tårn. Der skal du finde biskoppen, som venter på dig. Tag Oraklets token til nøglemesteren i grænselandet. Når du har udslettet biskoppen, skal du vende tilbage til Oraklet.","Das zweite Teilstück befindet sich im Turm aus Purpur und Obsidian. Dort musst du den Bischof finden, der dich erwartet. Bringe das Symbol des Orakels zum Schlüsselmeister in den Grenzgebieten. Wenn der Bischof ausgeschaltet ist, kehre zum Orakel zurück.",,,"La segunda pieza se encuentra en el corazón e la torre carmesí y obsidiana. Ahí debes encontrar al Obispo, quien espera por ti. Lleva el vale del Oráculo al amo de llaves en las fronteras. En cuanto hayas destruido al Obispo, regresa con el Oráculo.","La segunda pieza está en el corazón de la torre carmesí y obsidiana. Ahí deberás encontrar al Obispo, que te está esperando. Lleva el símbolo del Oráculo al Amo de Llaves en las fronteras. Cuando hayas destruido al Obispo, regresa con el Oráculo.","Toinen osanen piilee purppuranpunaisen laavalasisen tornin sydämessä. Sieltä sinun on löydettävä Piispa, joka odottaa sinua. Toimita Oraakkelin merkki avainmestarille rajaseudulla. Tuhottuasi Piispan palaa Oraakkelin luokse.","La deuxième pièce se trouve au cœur de la tour d'obsidienne et d'écarlate. Tu y trouveras l'évêque, qui t'attend. Amène le jeton de l'Oracle au maître des clés dans les terrains vagues. Quand tu as tué l'évêque, retourne voir l'Oracle.","A második darab a karmazsin és obszidián torony szívében található. Ott fogsz találkozni a már rád váró Püspökre. Vidd az Orákulum zálogát a peremvidéken élő kulcsmesterhez. Amint megölted a Püspököt, irány vissza az orákulumhoz.","Il secondo pezzo si trova nel cuore della torre cremisina e ossidiana. Lì troverai il Vescovo, che ti sta aspettando. Raggiungi il mastro delle chiavi nelle terre di confine. Quando hai distrutto il Vescovo, ritorna dall'Oracolo.","二つ目の欠片は深紅と黒曜石の塔の中心部にある。そこのビショップを討伐せよ。 国境地帯のコモンズ側にいるキーマスターにオラクルのトークンを見せる。 -ビショップを仕留めたらオラクルの元に戻る。","두 번째 시질 조각은 진홍빛 흑요석 탑에 숨어있는 비숍에게 있어. 거기에서 너를 기다리고 있는 비숍을 찾아내야만 해. 오라클의 통행증을 들고 접경지 안의 열쇠지기에게로 가봐. 비숍을 파괴했다면, 오라클에게 돌아가.","Het tweede stuk ligt in het hart van de karmozijnrode en obsidiaan toren. Daar moet je de bisschop vinden, die op je wacht. Breng de orakels naar de belangrijkste meester in de grensgebieden. Als je de bisschop hebt vernietigd, keer je terug naar het Orakel.","Den andre brikken ligger i hjertet av det purpurfargede og obsidianske tårnet. Der må du finne biskopen, som venter på deg. Ta orakelets symbol til nøkkelmesteren i grenselandene. Når du har tilintetgjort biskopen, gå tilbake til oraklet.","Drugi kawałek leży w sercu karmazynowej i obsydianowej wieży. Musisz tam odnaleźć biskupa, który czeka na Ciebie. Zabierz żeton wyroczni do mistrza kluczy na pograniczu. Po zniszczeniu Biskupa wróć do Wyroczni.","A segunda peça está no coração da torre carmesim e obsidiana. Lá você encontrará o Bispo, que está te aguardando. Leve o emblema do Oráculo para o mestre das chaves nas fronteiras. Após destruir o Bispo, volte ao Oráculo.",,A doua piesă e în inima turnului stăveziu din obsidian. Episcopul te va aștepta. Ia semnul Oracolului la stăpânul cheii în mărginime. După ce ai eliminat Episcopul întoarce-te la Oracol.,"Второй фрагмент лежит в сердце багрово-обсидиановой башни. Там ты встретишь Епископа, который ожидает тебя. Отнеси жетон Оракула ключнику в пограничье. Когда уничтожишь Епископа, возвращайся к Оракулу.",,İkinci parça kızıl ve obsidyen kulenin kalbinde yatıyor. Orada sizi bekleyen Piskopos'u bulmalısınız. Kahin'in jetonunu sınır bölgelerindeki anahtar ustasına götürün. Piskoposu yok ettikten sonra Kahin'e geri dönün. +ビショップを仕留めたらオラクルの元に戻る。","두 번째 시질 조각은 진홍빛 흑요석 탑에 숨어있는 비숍에게 있어. 거기에서 너를 기다리고 있는 비숍을 찾아내야만 해. 오라클의 통행증을 들고 접경지 안의 열쇠지기에게로 가봐. 비숍을 파괴했다면, 오라클에게 돌아가.","Het tweede stuk ligt in het hart van de karmozijnrode en obsidiaan toren. Daar moet je de bisschop vinden, die op je wacht. Breng de orakels naar de belangrijkste meester in de grensgebieden. Als je de bisschop hebt vernietigd, keer je terug naar het Orakel.","Den andre brikken ligger i hjertet av det purpurfargede og obsidianske tårnet. Der må du finne biskopen, som venter på deg. Ta orakelets symbol til nøkkelmesteren i grenselandene. Når du har tilintetgjort biskopen, gå tilbake til oraklet.","Drugi kawałek leży w sercu karmazynowej i obsydianowej wieży. Musisz tam odnaleźć biskupa, który czeka na Ciebie. Zabierz żeton wyroczni do mistrza kluczy na pograniczu. Po zniszczeniu Biskupa wróć do Wyroczni.","A segunda peça está no coração da torre carmesim e obsidiana. Lá você encontrará o Bispo, que está te aguardando. Leve o emblema do Oráculo para o mestre das chaves nas fronteiras. Após destruir o Bispo, volte ao Oráculo.",,A doua piesă e în inima turnului stăveziu din obsidian. Episcopul te va aștepta. Ia semnul Oracolului la stăpânul cheii în mărginime. După ce ai eliminat Episcopul întoarce-te la Oracol.,"Второй фрагмент лежит в сердце багрово-обсидиановой башни. Там ты встретишь Епископа, который ожидает тебя. Отнеси жетон Оракула ключнику в пограничье. Когда уничтожишь Епископа, возвращайся к Оракулу.",,Den andra biten finns i hjärtat av det karmosinröda och obsidianiska tornet. Där måste du hitta biskopen som väntar på dig. Ta Orakelns token till nyckelmästaren i gränslandet. När du har förintat biskopen ska du återvända till oraklet.,İkinci parça kızıl ve obsidyen kulenin kalbinde yatıyor. Orada sizi bekleyen Piskopos'u bulmalısınız. Kahin'in jetonunu sınır bölgelerindeki anahtar ustasına götürün. Piskoposu yok ettikten sonra Kahin'e geri dönün. "Find the crimson and obsidian tower. Use the id key the key master gave you to enter the tower. Once inside you must locate the Bishop. Once you have destroyed the Bishop, return to the Oracle.",TXT_ILOG1021,MAP11: After getting the Military ID from the keymaster.,,,"Najdi karmíno-obsidiánovou věž. Použij legitimaci, kterou ti dal klíčník, pro vstup do věže. Uvnitř musíš najít Biskupa. Až zabiješ Biskupa, vrať se k Věštci.","Find det purpurfarvede og obsidianske tårn. Brug den id-nøgle, som nøglemesteren gav dig, til at komme ind i tårnet. Når du er inde, skal du finde biskoppen. Når du har ødelagt biskoppen, skal du vende tilbage til Oracle.","Finde den Turm aus Purpur und Obsidian. Benutze den Schlüssel des Schlüsselmeisters um in den Turm hereinzukommen. In seinem Inneren musst du den Bischof finden. Wenn er ausgeschaltet ist, kehre zum Orakel zurück.",,,"Encuentra la torre carmesí y obsidiana. Usa la llabe que te dio el amo de llaves para entrar en la torre. Una vez dentro debes localizar al Obispo. Una vez hayas destruido al Obispo, regresa con el Oráculo.","Encuentra la torre carmesí y obsidiana. Usa la llave que te dio el Amo de Llaves para entrar en la torre. Una vez adentro localiza al Obispo. Una vez destruido el Obispo, regresa con el Oráculo.",Löydä purppuranpunainen laavalasinen torni. Käytä avainmestarin luovuttamaa tunnusta päästäksesi torniin. Sisään päästyäsi sinun on paikallistettava Piispa. Tuhottuasi hänet palaa Oraakkelin luokse.,"Trouve la tour d'obsidienne et d'écarlate. Utilise la carte magnétique que le maître des clés t'a donnée pour y entrer. A l'intérieur, trouve et tue l'évêque, puis retourne à l'Oracle.","Keresd fel a karamzsin és obszidián tornyot. A bejutáshoz használd az igazolványt amit a kulcsmester adott. Ha bejutottál, kutasd fel a Püspököt. Ha kiiktattad a Püspököt, menj vissza az Orákulumhoz.","Trova la torre cremisina e ossidiana. Con la chiave che ti ha dato il mastro delle chiavi, entra nella torre. Quando sei dentro, devi trovare il Vescovo. Dopo averlo distrutto, ritorna dall'Oracolo.","二つ目の欠片は深紅と黒曜石の塔の中心部にある。そこのビショップを討伐せよ。 キーマスターから貰ったIDキーを使って塔に入る。 -ビショップを仕留めたらオラクルの元に戻る。","진홍빛 흑요석 탑을 찾아. 열쇠지기가 준 신분증을 이용해서 탑으로 들어가. 탑 안으로 들어가서 비숍을 찾아야 해. 비숍을 파괴했다면, 오라클에게 돌아가.","Vind de karmozijnrode en obsidiaan toren. Gebruik de id-toets die de sleutelmeester je gaf om de toren te betreden. Eenmaal binnen moet je de bisschop lokaliseren. Als je de bisschop hebt vernietigd, ga je terug naar het Orakel.","Finn det purpurfargede og obsidianske tårnet. Bruk id-nøkkelen nøkkelmesteren ga deg for å komme inn i tårnet. Når du er inne, må du finne biskopen. Når du har ødelagt biskopen, gå tilbake til oraklet.","Znajdź wieżę z karmazynu i obsydianu. Użyj klucza id, który dał ci mistrz kluczy, aby wejść do wieży. Po wejściu do środka musisz zlokalizować Bishopa. Po zniszczeniu Bishopa wróć do Oracle.","Encontre a torre carmesim e obsidiana. Use a chave de identificação que o mestre da chaves te deu para entrar na torre. Após entrar, você deve localizar o Bispo. Após destruir o Bispo, volte ao Oráculo.",,"Găsește turnul străveziu din obsidian. Folosește cardul pe care ți l-a dat stăpânul cheilor pentru a intra. După aceea, găsește-l pe Episcop. Odată ce l-ai distrus, întoarce-te la Oracol.","Найди багрово-обсидиановую башню. Используй пропуск, полученный у ключника, чтобы войти внутрь. Там ты должен найти Епископа. Когда уничтожишь его, возвращайся к Оракулу.",,Kızıl ve obsidyen kuleyi bulun. Kuleye girmek için anahtar ustasının size verdiği kimlik anahtarını kullanın. İçeri girdikten sonra Piskoposu bulmalısınız. Piskoposu yok ettikten sonra Kahin'e geri dönün. +ビショップを仕留めたらオラクルの元に戻る。","진홍빛 흑요석 탑을 찾아. 열쇠지기가 준 신분증을 이용해서 탑으로 들어가. 탑 안으로 들어가서 비숍을 찾아야 해. 비숍을 파괴했다면, 오라클에게 돌아가.","Vind de karmozijnrode en obsidiaan toren. Gebruik de id-toets die de sleutelmeester je gaf om de toren te betreden. Eenmaal binnen moet je de bisschop lokaliseren. Als je de bisschop hebt vernietigd, ga je terug naar het Orakel.","Finn det purpurfargede og obsidianske tårnet. Bruk id-nøkkelen nøkkelmesteren ga deg for å komme inn i tårnet. Når du er inne, må du finne biskopen. Når du har ødelagt biskopen, gå tilbake til oraklet.","Znajdź wieżę z karmazynu i obsydianu. Użyj klucza id, który dał ci mistrz kluczy, aby wejść do wieży. Po wejściu do środka musisz zlokalizować Bishopa. Po zniszczeniu Bishopa wróć do Oracle.","Encontre a torre carmesim e obsidiana. Use a chave de identificação que o mestre da chaves te deu para entrar na torre. Após entrar, você deve localizar o Bispo. Após destruir o Bispo, volte ao Oráculo.",,"Găsește turnul străveziu din obsidian. Folosește cardul pe care ți l-a dat stăpânul cheilor pentru a intra. După aceea, găsește-l pe Episcop. Odată ce l-ai distrus, întoarce-te la Oracol.","Найди багрово-обсидиановую башню. Используй пропуск, полученный у ключника, чтобы войти внутрь. Там ты должен найти Епископа. Когда уничтожишь его, возвращайся к Оракулу.",,Hitta det karmosinröda och obsidianska tornet. Använd id-nyckeln som nyckelmästaren gav dig för att komma in i tornet. När du väl är inne måste du lokalisera biskopen. När du har förstört biskopen återvänder du till oraklet.,Kızıl ve obsidyen kuleyi bulun. Kuleye girmek için anahtar ustasının size verdiği kimlik anahtarını kullanın. İçeri girdikten sonra Piskoposu bulmalısınız. Piskoposu yok ettikten sonra Kahin'e geri dönün. "Find the security complex, fight through there and use the teleporter to central administration. Destroy the computer core in central administration. This will kill the force field on the Bishop's tower. Once the Bishop's dead, return to the Oracle.",TXT_ILOG1022,MAP17: After talking to Quincy.,,,"Najdi bezpečnostní komplex, probij se skrz a použij teleportér do ústřední administrace. Znič počítačové jádro v ústřední administraci. To zničí silové pole v Biskupově věži. Až zabiješ Biskupa, vrať se k Věštci.","Find sikkerhedskomplekset, kæmp dig igennem der og brug teleporteren til centraladministrationen. Ødelæg computerkernen i centraladministrationen. Dette vil dræbe kraftfeltet på Bishop's tårn. Når biskoppen er død, skal du vende tilbage til Oracle.","Finde den Sicherheitskomplex, kämpfe dich durch und benutze den Teleporter zur Zentralverwaltung. Zerstöre den Computer in der Verwaltung. Das wird alle Kraftfelder am Turm des Bischofs ausschalten. Wenn der Bischof ausgeschaltet ist, kehre zum Orakel zurück.",,,"Encuentra el complejo de seguridad, pelea a través de ahí y usa el teletransporte a administración central. Destruye el núcleo de la computadora en administración central. Esto apagará el campo de fuerza en la torre del Obispo. En cuanto el Obispo esté muerto, regresa con el Oráculo.",,"Löydä turvallisuuskeskus, taistele sen läpi ja kulje kaukosiirtimellä keskushallintoon. Tuhoa siellä keskustietokone. Se sammuttaa Piispan tornin voimakentän. Kun Piispa on kuollut, palaa Oraakkelin luo.","Trouve le complexe de sécurité. Bats-toi pour atteindre le téléporteur vers le centre d'administration. Détruis le cœur informatique qui s'y trouve. Cela désactivera le chap de force de la tour de l'évêque. Un fois qu'il est mort, retourne voir l'Oracle.","Keresd meg a biztonsági központot, harcold magad keresztül rajta, és használd a teleportot a központi adminisztrációhoz. Semmisítsd meg a számítógép magot a központi adminisztrációnál. Ez majd deaktiválja a Püspök tornyának az erőpajzsát. Ha meghalt a Püspök térj vissza az Orákulumhoz.","Trova il complesso di sicurezza, elimina chiunque ti sbarri la strada e trova il teletrasporto per l'amministrazione centrale. Distruggi il nucleo del computer nell'amministrazione centrale. Questo disattiverà il campo di forza nella torre del Vescovo. Quando il Vescovo sarà morto, ritorna dall'Oracolo.","複合警備所を見つけ、そこを制圧し中央管理所へのテレポーターを使う。 そして管理所のコンピューターコアを破壊する。 そうすればビショップの塔へのフォースフィールドを消せる。 -ビショップを仕留めたらオラクルの元に戻る。","보안 담당 기지를 찾고, 경비와 싸워가면서 중앙 처리 본부로 향하는 텔레포터를 사용해. 그곳에서 컴퓨터 중심부를 파괴해. 그러면 비숍의 탑의 보호막을 끌 수 있을 거야. 비숍을 죽이면, 오라클에게 돌아가.","Vind het veiligheidscomplex, vecht daar doorheen en gebruik de teleporter om de centrale administratie te besturen. Vernietig de computerkern in de centrale administratie. Dit zal het krachtveld op de Bisschopstoren doden. Zodra de bisschop dood is, keer je terug naar het Orakel.","Finn sikkerhetskomplekset, kjemp deg gjennom der og bruk teleporteren til sentraladministrasjonen. Ødelegg datakjernen i sentraladministrasjonen. Dette vil drepe kraftfeltet på biskopens tårn. Når biskopen er død, gå tilbake til Orakelet.","Znajdź kompleks bezpieczeństwa, walcz tam i użyj teleportera do centralnej administracji. Zniszcz rdzeń komputera w centralnej administracji. To zabije pole siłowe na wieży Bishopa. Gdy Bishop będzie już martwy, wróć do Oracle.","Encontre o complexo de segurança, lute através de lá e use o teletransportador na administração central. Destrua o núcleo de computação na administração central. Isso vai derrubar o campo de força na torre do Bispo. Após matar o Bispo, volte ao Oráculo.",,"Găsește complexul de securitate, intră în luptă, și folosește teleportorul către administrația centrală. Distruge nucleul calculatorului. Asta va distruge scutul din turnul Episcopului. Odată ce e mort, întoarce-te la Oracol.","Найди охранный комлекс, пробейся внутрь и используй телепорт до центральной администрации. Уничтожь компьютер. Это должно отключить силовое поле башни Епископа. Когда убьёшь Епископа, возвращайся к Оракулу.",,"Güvenlik kompleksini bulun, orada savaşın ve merkezi yönetime giden ışınlayıcıyı kullanın. Merkezi yönetimdeki bilgisayar çekirdeğini yok edin. Bu, Piskopos'un kulesindeki güç alanını öldürecektir. Piskopos öldükten sonra Kahin'e geri dönün." +ビショップを仕留めたらオラクルの元に戻る。","보안 담당 기지를 찾고, 경비와 싸워가면서 중앙 처리 본부로 향하는 텔레포터를 사용해. 그곳에서 컴퓨터 중심부를 파괴해. 그러면 비숍의 탑의 보호막을 끌 수 있을 거야. 비숍을 죽이면, 오라클에게 돌아가.","Vind het veiligheidscomplex, vecht daar doorheen en gebruik de teleporter om de centrale administratie te besturen. Vernietig de computerkern in de centrale administratie. Dit zal het krachtveld op de Bisschopstoren doden. Zodra de bisschop dood is, keer je terug naar het Orakel.","Finn sikkerhetskomplekset, kjemp deg gjennom der og bruk teleporteren til sentraladministrasjonen. Ødelegg datakjernen i sentraladministrasjonen. Dette vil drepe kraftfeltet på biskopens tårn. Når biskopen er død, gå tilbake til Orakelet.","Znajdź kompleks bezpieczeństwa, walcz tam i użyj teleportera do centralnej administracji. Zniszcz rdzeń komputera w centralnej administracji. To zabije pole siłowe na wieży Bishopa. Gdy Bishop będzie już martwy, wróć do Oracle.","Encontre o complexo de segurança, lute através de lá e use o teletransportador na administração central. Destrua o núcleo de computação na administração central. Isso vai derrubar o campo de força na torre do Bispo. Após matar o Bispo, volte ao Oráculo.",,"Găsește complexul de securitate, intră în luptă, și folosește teleportorul către administrația centrală. Distruge nucleul calculatorului. Asta va distruge scutul din turnul Episcopului. Odată ce e mort, întoarce-te la Oracol.","Найди охранный комлекс, пробейся внутрь и используй телепорт до центральной администрации. Уничтожь компьютер. Это должно отключить силовое поле башни Епископа. Когда убьёшь Епископа, возвращайся к Оракулу.",,"Hitta säkerhetskomplexet, kämpa dig igenom där och använd teleportern till centraladministrationen. Förstör datorkärnan i centralförvaltningen. Detta kommer att döda kraftfältet på biskopens torn. När biskopen är död återvänder du till oraklet.","Güvenlik kompleksini bulun, orada savaşın ve merkezi yönetime giden ışınlayıcıyı kullanın. Merkezi yönetimdeki bilgisayar çekirdeğini yok edin. Bu, Piskopos'un kulesindeki güç alanını öldürecektir. Piskopos öldükten sonra Kahin'e geri dönün." Your next challenge will test your spirit. The third piece is held by your own leader. He is the same as that which he sends you to kill. Confront him and resolve your fate.,TXT_ILOG1023,,,,"Tvá další výzva pokusí tvou vůli. Třetí díl je držen tvým vlastním vůdcem. Je stejný, jako ti, které tě posílá zabít. Postav se mu a rozhodni svůj osud.","Din næste udfordring vil teste din ånd. Den tredje brik holdes af din egen leder. Han er den samme som den, som han sender dig til at dræbe. Konfronter ham og løser din skæbne.","Die nächste Herausforderung wird deinen Geist prüfen. Das dritte Teilstück wird von deinem eigenen Anführer, Macil, gehalten. Er ist das Gleiche, was er dich töten lässt. Konfrontiere ihn und kläre dein Schicksal.",,,Tu siguiente desafío pondrá a prueba tu espíritu. La tercera pieza está en manos de tu propio líder. Él es lo mismo que te envía a matar. Confróntalo y resuelve tu destino.,Tú siguiente desafío probará tú espíritu. La tercera pieza la tiene tú propio líder. Él es igual que aquello que te envía a matar. Confróntalo y resuelve tú destino.,"Seuraava haasteesi koettelee sinua henkisesti. Kolmatta osasta pitää hallussaan oma päämiehesi. Hän on sama kuin se, jonka hän lähettää sinut surmaamaan. Kohtaa hänet ja päätä kohtalosi.",Le prochain défi testera votre esprit. Le troisième fragment est possédé par votre leader. Il est le même que celui qu'il vous a envoyé tuer. Confrontez-le et faites face à votre destinée.,"A következő próbatétel próbára teszi a lelkedet. A harmadik darab a saját vezérednél található. Egy és ugyanazon személy akit meg akar öletni veled. Szembesítsd vele, és dönts a sorsod felett.",La tua prossima sfida metterà alla prova il tuo spirito. Il terzo frammento è posseduto dal tuo stesso capo. Lui è uguale a quelli che ti manda ad uccidere. Affrontalo e risolvi il tuo destino.,"次の挑戦は己の精神が試される。三つ目の欠片は我々のリーダーが保持している。 -彼は貴方を殺すために送ったのと同等だと。彼に立ち向かい、己の運命を決断せよ。",다음 도전은 너의 정신을 시험할 거야. 세 번째 조각은 바로 우리의 지도자가 가지고 있어. 그는 너를 시켜서 죽였던 괴물들과 마찬가지인 존재지.,Je volgende uitdaging zal je geest testen. Het derde stuk wordt vastgehouden door je eigen leider. Hij is dezelfde die hij je stuurt om te doden. Confronteer hem en los je lot op.,Din neste utfordring vil sette din ånd på prøve. Den tredje brikken holdes av din egen leder. Han er den samme som han sender deg for å drepe. Konfronter ham og avgjør skjebnen din.,"Twoje kolejne wyzwanie przetestuje twojego ducha. Trzeci element jest w posiadaniu twojego własnego przywódcy. Jest on taki sam jak ten, którego wysyła do zabicia. Zmierz się z nim i rozstrzygnij swój los.",Seu próximo desafio testará o seu espírito. A terceira peça está com o seu próprio líder. Ele é a mesma pessoa que ele quer que você mate. Confronte-o e resolva o seu destino.,,Următoarea provocare îți va testa spiritul. A treia pieșă e ținută de propriul vostru lider. E același ca cel care vă trimite să ucideți. Înfruntă-l și împlinește-ți destinul.,"Следующее задание испытает силу твоего духа. Третий фрагмент у вашего лидера. Он сам — один из тех, кого вы убиваете по его приказу. Сразись с ним и исполни своё предназначение.",,Bir sonraki göreviniz ruhunuzu sınayacak. Üçüncü parça kendi lideriniz tarafından tutuluyor. Sizi öldürmeniz için gönderdiği kişiyle aynı. Onunla yüzleşin ve kaderinizi belirleyin. +彼は貴方を殺すために送ったのと同等だと。彼に立ち向かい、己の運命を決断せよ。",다음 도전은 너의 정신을 시험할 거야. 세 번째 조각은 바로 우리의 지도자가 가지고 있어. 그는 너를 시켜서 죽였던 괴물들과 마찬가지인 존재지.,Je volgende uitdaging zal je geest testen. Het derde stuk wordt vastgehouden door je eigen leider. Hij is dezelfde die hij je stuurt om te doden. Confronteer hem en los je lot op.,Din neste utfordring vil sette din ånd på prøve. Den tredje brikken holdes av din egen leder. Han er den samme som han sender deg for å drepe. Konfronter ham og avgjør skjebnen din.,"Twoje kolejne wyzwanie przetestuje twojego ducha. Trzeci element jest w posiadaniu twojego własnego przywódcy. Jest on taki sam jak ten, którego wysyła do zabicia. Zmierz się z nim i rozstrzygnij swój los.",Seu próximo desafio testará o seu espírito. A terceira peça está com o seu próprio líder. Ele é a mesma pessoa que ele quer que você mate. Confronte-o e resolva o seu destino.,,Următoarea provocare îți va testa spiritul. A treia pieșă e ținută de propriul vostru lider. E același ca cel care vă trimite să ucideți. Înfruntă-l și împlinește-ți destinul.,"Следующее задание испытает силу твоего духа. Третий фрагмент у вашего лидера. Он сам — один из тех, кого вы убиваете по его приказу. Сразись с ним и исполни своё предназначение.",,Din nästa utmaning kommer att sätta din anda på prov. Den tredje biten innehas av din egen ledare. Han är densamma som den som han skickar dig att döda. Konfrontera honom och lös ditt öde.,Bir sonraki göreviniz ruhunuzu sınayacak. Üçüncü parça kendi lideriniz tarafından tutuluyor. Sizi öldürmeniz için gönderdiği kişiyle aynı. Onunla yüzleşin ve kaderinizi belirleyin. "It is the Oracle who holds the third piece. There's your traitor. Return to the Oracle, and take him down. Return to me when it's dead.",TXT_ILOG1024,,,,"Věštec je ten, kdo má u sebe třetí díl. On je ten zrádce. Vrať se k němu a zabij ho. Vrať se ke mě, až bude mrtvý.","Det er Oraklet, der har den tredje brik. Der er din forræder. Vend tilbage til Oraklet, og nedlæg ham. Vend tilbage til mig, når det er dødt.","Es ist das Orakel, das das dritte Teilstück besitzt. Es ist der Verräter. Kehre zu ihm zurück und schalte es aus. Kehre zurück, wenn es tot ist.",,,Es el Oráculo quien tiene la tercera pieza. Ahí está tu traidor. Regresa al Oráculo y acaba con él. Regresa a mí cuando esté muerto.,Es el Oráculo el que tiene la tercera pieza. Ahí está tú traidor. Regresa con el Oráculo y acaba con él. Regresa a mí cuando esté muerto.,Kolmas osanen on Oraakkelin hallussa. Siinä on petturisi. Palaa Oraakkelin luo ja poista hänet päiväjärjestyksestä. Palaa luokseni hänen kuoltuaan.,"C'est l'Oracle qui détient la troisième pièce, est c'est lui qui est le traître. Retourne le voir et détruis-le. Retourne à la base quand il est mort.","Az Orákulumnál található a harmadik darab. Ő lesz az árulód. Térj vissza az Orákulumhoz, és tedd el láb alól. Ha megtörtént, gyere vissza.","È l'Oracolo che tiene il terzo pezzo. Ecco chi è il traditore. Ritorna dall'Oracolo, e fallo fuori. Ritorna da me quando lo hai ucciso.","三つ目の欠片を持つのはオラクルだ。あいつが裏切者だ。 -オラクルの所に戻り討ち倒せ。終わったらマシルの元に戻る。",오라클이 세 번째 조각을 가지고 있어. 그가 배신자야! 오라클을 찾아서 혼쭐을 낸 뒤 마실에게 돌아와.,"Het is het Orakel dat het derde deel vasthoudt. Daar is je verrader. Ga terug naar het Orakel, en neem hem mee naar beneden. Keer terug naar mij als het dood is.",Det er oraklet som har den tredje brikken. Der er forræderen din. Gå tilbake til oraklet og drep ham. Kom tilbake til meg når den er død.,"To Wyrocznia jest w posiadaniu trzeciego kawałka. Oto twój zdrajca. Wróć do Wyroczni i załatw go. Wróć do mnie, gdy będzie martwy.",É o Oráculo que possui a terceira peça. Esse é o seu traidor. Volte ao Oráculo e elimine-o. Volte para mim quando ele estiver morto.,,"E Oracolul cel care deține ultima piesă. Acolo e trădătorul. Întoarce-te la Oracol, și răpune-l. Întoarce-te la mine când ai terminat.",Третий фрагмент хранится у Оракула. Так и кто же из нас предатель? Вернись к Оракулу и расправься с ним. Доложи мне о его смерть.,,Üçüncü parçayı elinde tutan Kahin. İşte haininiz. Kahin'e dön ve onu indir. Öldüğünde bana geri dön. +オラクルの所に戻り討ち倒せ。終わったらマシルの元に戻る。",오라클이 세 번째 조각을 가지고 있어. 그가 배신자야! 오라클을 찾아서 혼쭐을 낸 뒤 마실에게 돌아와.,"Het is het Orakel dat het derde deel vasthoudt. Daar is je verrader. Ga terug naar het Orakel, en neem hem mee naar beneden. Keer terug naar mij als het dood is.",Det er oraklet som har den tredje brikken. Der er forræderen din. Gå tilbake til oraklet og drep ham. Kom tilbake til meg når den er død.,"To Wyrocznia jest w posiadaniu trzeciego kawałka. Oto twój zdrajca. Wróć do Wyroczni i załatw go. Wróć do mnie, gdy będzie martwy.",É o Oráculo que possui a terceira peça. Esse é o seu traidor. Volte ao Oráculo e elimine-o. Volte para mim quando ele estiver morto.,,"E Oracolul cel care deține ultima piesă. Acolo e trădătorul. Întoarce-te la Oracol, și răpune-l. Întoarce-te la mine când ai terminat.",Третий фрагмент хранится у Оракула. Так и кто же из нас предатель? Вернись к Оракулу и расправься с ним. Доложи мне о его смерть.,,Det är oraklet som innehar den tredje biten. Där har du din förrädare. Återvänd till Oraklet och ta ner honom. Återvänd till mig när den är död.,Üçüncü parçayı elinde tutan Kahin. İşte haininiz. Kahin'e dön ve onu indir. Öldüğünde bana geri dön. "You have cut the cancer from your body, but your heart still beats. Next you must find the surgeon who butchers and controls your people.... The Loremaster. Stop him, and the next piece will be yours.",TXT_ILOG1025,,,,"Vyřízl jsi rakovinu ze svého těla, tvé srdce však stále bije. Dále musíš najít doktora, jenž vraždí a ovládá tvé druhy, Dějepisce. Učiň mu přítrž a další díl bude tvůj.","Du har fjernet kræften fra din krop, men dit hjerte slår stadig. Nu skal du finde den kirurg, der slagter og kontrollerer dit folk.... Loremesteren. Stop ham, og det næste stykke vil blive dit.","Du hast das Geschwür aus deinem Körper entferrnt, aber dein Herz schlägt noch. Als Nächstes musst du den Wissensmeister finden, der deine Leute kontrolliert und abschlachtet. Stoppe ihn und das nächste Teilstück ist Dein.",,,"Has cortado el cáncer de tu cuerpo, pero tu corazón aún late. Ahora debes encontrar al cirujano que destroza y controla a tu gente... El Maestro del Conocimiento. Detenlo, y la siguiente pieza será tuya.","Haz cortado el cáncer de tu cuerpo, pero tú corazón todavía late. Ahora debes encontrar al cirujano que encarniza y controla a tú gente... El Maestro del Conocimiento. Deténlo y la siguiente pieza será tuya.","Olet erottanut syövän ruumiistasi, mutta sydämesi silti sykkii. Seuraavaksi pitää sinun löytämän kirugin, joka teurastaa ja hallitsee kansaasi: Oppi-Isän. Pysäytä hänet, ja seuraava osanen on oleva sinun.","Vous avez arraché le cancer de votre corps, mais le cœur bat encore. Vous devez maintenant trouver le chirurgien qui massacre votre peuple, le Maître des traditions. Arrètez-le, et le fragment suivant sera le vôtre.","Kivágtad a rákos részt a szívedből, de az még mindig ver. A következő lépés, hogy felkutatod a sebészt aki lemészárolja és irányítja a néped...a Tanmestert. Állítsd meg , és a következő darab a tied.","Hai eliminato il cancro dal tuo corpo, ma il tuo cuore batte ancora. Adesso devi trovare il chirurgo che macella e controlla la tua gente, il Sapiente. Fermalo e il prossimo pezzo sarà tuo.","己の癌は切除したが動揺は隠せないままだ。 次の欠片は人々を虐殺で支配する外科医... -ロアマスターが所持している。奴を止め、欠片を自分の物にする。","네 몸 안의 암 덩어리를 잘라냈지만, 심장은 여전히 뛰고 있네. 다음은 우리를 향한 도살과 지배를 책임졌던 과학자, 로어마스터를 찾아내야 해. 그를 막아내면, 다음 조각을 얻을 수 있을 거야.","Je hebt de kanker uit je lichaam gesneden, maar je hart klopt nog steeds. Vervolgens moet je de chirurg vinden die je mensen afmaakt en controleert....... De Kennismeester. Stop hem, en het volgende stuk zal van jou zijn.","Du har fjernet kreften fra kroppen din, men hjertet ditt slår fortsatt. Nå må du finne kirurgen som slakter og kontrollerer folket ditt...... .... Loremesteren. Stopp ham, og det neste stykket blir ditt.","Wyciąłeś raka ze swojego ciała, ale twoje serce wciąż bije. Następnie musisz znaleźć chirurga, który rzeźbi i kontroluje twoich ludzi.... Loremaster. Powstrzymaj go, a następny kawałek będzie twój.","Você arrancou o câncer do seu corpo, mas seu coração ainda bate. Agora você deve encontrar o cirurgião que mutila e controla o seu povo... o Mestre do Conhecimento. Detenha-o e a próxima peça será sua.",,"Ai tăiat cancerul din corp, dar inima ta încă bate. Mai departe trebuie să găsești pe chirurgul care vă masacrează oamenii.... Maestrul Cunoștiințelor. Oprește-l, și următoarea piesă va fii a ta.","Ты вырезал опухоль из своего тела, но твоё сердце всё ещё бьётся. Теперь тебе предстоит найти вивисектора, который вскрывает твоих людей и управляет ими — Хранителя мудрости. Останови его, и следующий фрагмент твой.",,"Kanseri vücudundan attın ama kalbin hala atıyor. Şimdi insanlarını kesen ve kontrol eden cerrahı bulmalısın.... Loremaster. Onu durdurursan, bir sonraki parça senin olacak." +ロアマスターが所持している。奴を止め、欠片を自分の物にする。","네 몸 안의 암 덩어리를 잘라냈지만, 심장은 여전히 뛰고 있네. 다음은 우리를 향한 도살과 지배를 책임졌던 과학자, 로어마스터를 찾아내야 해. 그를 막아내면, 다음 조각을 얻을 수 있을 거야.","Je hebt de kanker uit je lichaam gesneden, maar je hart klopt nog steeds. Vervolgens moet je de chirurg vinden die je mensen afmaakt en controleert....... De Kennismeester. Stop hem, en het volgende stuk zal van jou zijn.","Du har fjernet kreften fra kroppen din, men hjertet ditt slår fortsatt. Nå må du finne kirurgen som slakter og kontrollerer folket ditt...... .... Loremesteren. Stopp ham, og det neste stykket blir ditt.","Wyciąłeś raka ze swojego ciała, ale twoje serce wciąż bije. Następnie musisz znaleźć chirurga, który rzeźbi i kontroluje twoich ludzi.... Loremaster. Powstrzymaj go, a następny kawałek będzie twój.","Você arrancou o câncer do seu corpo, mas seu coração ainda bate. Agora você deve encontrar o cirurgião que mutila e controla o seu povo... o Mestre do Conhecimento. Detenha-o e a próxima peça será sua.",,"Ai tăiat cancerul din corp, dar inima ta încă bate. Mai departe trebuie să găsești pe chirurgul care vă masacrează oamenii.... Maestrul Cunoștiințelor. Oprește-l, și următoarea piesă va fii a ta.","Ты вырезал опухоль из своего тела, но твоё сердце всё ещё бьётся. Теперь тебе предстоит найти вивисектора, который вскрывает твоих людей и управляет ими — Хранителя мудрости. Останови его, и следующий фрагмент твой.",,"Du har skurit bort cancern från din kropp, men ditt hjärta slår fortfarande. Nu måste du hitta kirurgen som slaktar och kontrollerar ditt folk.... Läromästaren. Stoppa honom och nästa del blir din.","Kanseri vücudundan attın ama kalbin hala atıyor. Şimdi insanlarını kesen ve kontrol eden cerrahı bulmalısın.... Loremaster. Onu durdurursan, bir sonraki parça senin olacak." "Next you must find the surgeon who butchers and controls your people.... The Loremaster. Stop him, and the next piece will be yours. Use the teleporter I opened to reach him. When he's dead, use the same device to return to me.",TXT_ILOG1026,,,,"Vyřízl jsi rakovinu ze svého těla, tvé srdce však stále bije. Dále musíš najít doktora, jenž vraždí a ovládá tvé druhy, Dějepisce. Učiň mu přítrž a další díl bude tvůj. Použij teleportér, který jsem otevřel, aby ses k němu dostal. Když je mrtev, použij stejné zařízení k návratu ke mě.","Dernæst skal du finde den kirurg, der slagter og kontrollerer dit folk.... Loremesteren. Stop ham, og den næste del bliver din. Brug teleporteren, som jeg åbnede for at nå ham. Når han er død, skal du bruge den samme anordning til at vende tilbage til mig.","Als Nächstes musst du den Wissensmeister finden, der deine Leute kontrolliert und abschlachtet. Stoppe ihn und das nächste Teilstück ist Dein. Benutze den Teleporter, den ich geöffnet habe, um zu ihm zu gelangen. Wenn er tot ist kehre auf dem gleichen Weg zurück.",,,"Ahora debes encontrar al cirujano que destroza y controla a tu gente... El Maestro del Conocimiento. Detenlo, y la siguiente pieza será tuya. Usa el teletransporte que he abierto para alcanzarlo. Cuando esté muerto, usa el mismo dispositivo para regresar a mí.","Ahora debes encontrar al cirujano que encarniza y controla a tú gente... El Maestro del Conocimiento. Deténlo y la siguiente pieza será tuya. Usa el teleporte que he abierto para alcanzarlo. Cuando esté muerto, usa el mismo dispositivo para regresar conmigo.","Seuraavaksi pitää sinun löytämän kirugin, joka teurastaa ja hallitsee kansaasi: Oppi-Isän. Pysäytä hänet, ja seuraava osanen on oleva sinun. Käytä avaamaani kaukosiirrintä tavoittaaksesi hänet. Kun hän on kuollut, käytä samaa laitetta palataksesi tyköni.","Vous devez maintenant trouver le chirurgien qui massacre votre peuple, le Maître des traditions. Arrètez-le, et le fragment suivant sera le vôtre. Utilisez le téléporter qui s'est ouvert pour l'atteindre. Quand il est mort, utilisez le même téléporteur pour retourner à l'Oracle.","A következő lépés, hogy felkutatod a sebészt aki lemészárolja és irányítja a néped...a Tanmestert. Állítsd meg és a következő darab a tied. Most nyitottam ki ezt a teleportot, használd hogy eljuss hozzá. Ha meghalt, használd ugyanezt a visszaútra is.","Adesso devi trovare il chirurgo che macella e controlla la tua gente, il Sapiente. Fermalo e il prossimo pezzo sarà tuo. Usa il teletrasporto che ho sbloccato per raggiungere il Sapiente. Quando è morto, usa lo stesso teletrasporto per tornare da me.","次の欠片は人々を虐殺で支配する外科医... ロアマスターが所持している。奴を止め、欠片を自分の物にする。 -近辺へのテレポーターを使い、奴が死んだら再びテレポーターから戻る。","우리를 향한 도살과 지배를 책임졌던 과학자, 로어마스터를 찾아내야 해. 그를 막아내면, 다음 조각을 얻을 수 있을 거야. 오라클이 열어준 텔레포터를 이용해서 그를 찾아. 그가 죽으면 같은 장치를 이용해서 오라클에게 돌아와.","Vervolgens moet u de chirurg vinden die uw mensen afslacht en onder controle heeft....... De Kennismeester. Stop hem, en het volgende stuk zal van jou zijn. Gebruik de teleporter die ik geopend heb om hem te bereiken. Als hij dood is, gebruik dan hetzelfde apparaat om terug te keren naar mij.","Deretter må du finne kirurgen som slakter og kontrollerer folket ditt.... Loremesteren. Stopp ham, og den neste brikken blir din. Bruk teleporteren jeg åpnet for å nå ham. Når han er død, bruk samme apparat for å komme tilbake til meg.","Następnie musisz znaleźć chirurga, który rzeźbi i kontroluje twoich ludzi.... Loremaster. Zatrzymaj go, a następny kawałek będzie twój. Użyj teleportera, który otworzyłem, aby do niego dotrzeć. Gdy będzie martwy, użyj tego samego urządzenia, by wrócić do mnie.","Agora você deve encontrar o cirurgião que mutila e controla o seu povo... o Mestre do Conhecimento. Detenha-o e a próxima peça será sua. Use o teletransportador que eu abri para chegar até ele. Quando ele estiver morto, use o mesmo dispositivo e volte até mim.",,"Mai departe trebuie să găsești chirurgul care vă masacrează oameni.... Maestrul Cunoștiințelor. Oprește-l, și următoarea piesă va fii a ta.","Тебе предстоит найти вивисектора, который вскрывает твоих людей и управляет ими — Хранителя мудрости. Останови его, и следующий фрагмент твой. Используй открытый мной телепорт, чтобы добраться до него. Когда он умрёт, найди другой телепорт и вернись ко мне.",,"Şimdi halkını katleden ve kontrol eden cerrahı bulmalısın.... Loremaster. Onu durdurun ve bir sonraki parça sizin olsun. Ona ulaşmak için açtığım ışınlayıcıyı kullan. O öldüğünde, bana dönmek için aynı cihazı kullan." +近辺へのテレポーターを使い、奴が死んだら再びテレポーターから戻る。","우리를 향한 도살과 지배를 책임졌던 과학자, 로어마스터를 찾아내야 해. 그를 막아내면, 다음 조각을 얻을 수 있을 거야. 오라클이 열어준 텔레포터를 이용해서 그를 찾아. 그가 죽으면 같은 장치를 이용해서 오라클에게 돌아와.","Vervolgens moet u de chirurg vinden die uw mensen afslacht en onder controle heeft....... De Kennismeester. Stop hem, en het volgende stuk zal van jou zijn. Gebruik de teleporter die ik geopend heb om hem te bereiken. Als hij dood is, gebruik dan hetzelfde apparaat om terug te keren naar mij.","Deretter må du finne kirurgen som slakter og kontrollerer folket ditt.... Loremesteren. Stopp ham, og den neste brikken blir din. Bruk teleporteren jeg åpnet for å nå ham. Når han er død, bruk samme apparat for å komme tilbake til meg.","Następnie musisz znaleźć chirurga, który rzeźbi i kontroluje twoich ludzi.... Loremaster. Zatrzymaj go, a następny kawałek będzie twój. Użyj teleportera, który otworzyłem, aby do niego dotrzeć. Gdy będzie martwy, użyj tego samego urządzenia, by wrócić do mnie.","Agora você deve encontrar o cirurgião que mutila e controla o seu povo... o Mestre do Conhecimento. Detenha-o e a próxima peça será sua. Use o teletransportador que eu abri para chegar até ele. Quando ele estiver morto, use o mesmo dispositivo e volte até mim.",,"Mai departe trebuie să găsești chirurgul care vă masacrează oameni.... Maestrul Cunoștiințelor. Oprește-l, și următoarea piesă va fii a ta.","Тебе предстоит найти вивисектора, который вскрывает твоих людей и управляет ими — Хранителя мудрости. Останови его, и следующий фрагмент твой. Используй открытый мной телепорт, чтобы добраться до него. Когда он умрёт, найди другой телепорт и вернись ко мне.",,Nästa steg är att hitta kirurgen som slaktar och kontrollerar ditt folk.... Läromästaren. Stoppa honom och nästa del blir din. Använd teleportern som jag öppnade för att nå honom. När han är död använder du samma apparat för att återvända till mig.,"Şimdi halkını katleden ve kontrol eden cerrahı bulmalısın.... Loremaster. Onu durdurun ve bir sonraki parça sizin olsun. Ona ulaşmak için açtığım ışınlayıcıyı kullan. O öldüğünde, bana dönmek için aynı cihazı kullan." You have chosen wisely. The third piece is held by your own leader. Destroy that which hides within your heart and return to me.,TXT_ILOG1027,,,,"Rozhodl ses moudře. Třetí díl je držen tvým vlastním vůdcem. Znič to, co se skrývá v tvém srdci, a vrať se ke mně.","Du har truffet et klogt valg. Den tredje brik er i hænderne på din egen leder. Ødelæg det, der gemmer sig i dit hjerte, og vend tilbage til mig.","Du hast weise entschieden. as dritte Teilstück wird von deinem eigenen Anführer, Macil, gehalten. Vernichte, was sich in eurem Herzen versteckt und kehre zu mir zurück.",,,Has elegido sabiamente. La tercera pieza está en manos de tu propio líder. Destroye lo que se esconde en tu corazón y regresa a mí.,Haz escogido sabiamente. La tercera pieza la tiene tú propio líder. Destruye aquello que se oculta en tú corazón y regresa conmigo.,"Olet valinnut viisaasti. Kolmatta osasta pitää hallussaan oma päämiehesi. Tuhoa se, mikä piilee sisällä sydämessäsi ja palaa tyköni.",Vous avez sagement choisi. La troisième pièce est détenue par votre propre leader. Détruisez ce qui se tapit dans son cœur et revenez à moi.,"Bölcsen döntöttél. A harmadik darab a saját vezérednél található. Semmisítsd meg a szíved mélyén megbúvó sötétséget, és térj vissza.",Hai fatto la scelta giusta. Il terzo pezzo è in possesso del tuo stesso capo. Distruggi ciò che si nasconde dentro il tuo cuore e ritorna da me.,"貴方は賢い判断をした。三つ目の欠片は我々のリーダーが保持している。 貴方の胸中に隠れているものを払い彼の元に戻る。 -",좋은 판단이야. 세 번째 시질 조각은 마실이 가지고 있어. 그를 죽여서 조각을 얻은 뒤 오라클에게 돌아와.,Je hebt verstandig gekozen. Het derde stuk wordt vastgehouden door je eigen leider. Vernietig datgene wat zich in je hart verbergt en keer terug naar mij.,"Du har valgt klokt. Den tredje brikken holdes av din egen leder. Ødelegg det som skjuler seg i hjertet ditt, og vend tilbake til meg.","Mądrze wybrałeś. Trzeci kawałek jest w posiadaniu twojego własnego przywódcy. Zniszcz to, co kryje się w twoim sercu i wróć do mnie.",Você escolheu sabiamente. A terceira peça está com o seu próprio líder. Destrua aquilo que se esconde em seu coração e volte a mim.,,Ai ales înțelept. A treia piesă e deținută de liderul vostru. Distruge ceea ce se ascunde în inima ta și întoarce-te la mine.,"Мудрый выбор. Третий фрагмент у вашего лидера. Уничтожь то, что закралось в твоё сердце, и возвращайся ко мне.",,Akıllıca bir seçim yaptın. Üçüncü parça kendi liderinizin elinde. Kalbinde sakladığın şeyi yok et ve bana dön. +",좋은 판단이야. 세 번째 시질 조각은 마실이 가지고 있어. 그를 죽여서 조각을 얻은 뒤 오라클에게 돌아와.,Je hebt verstandig gekozen. Het derde stuk wordt vastgehouden door je eigen leider. Vernietig datgene wat zich in je hart verbergt en keer terug naar mij.,"Du har valgt klokt. Den tredje brikken holdes av din egen leder. Ødelegg det som skjuler seg i hjertet ditt, og vend tilbake til meg.","Mądrze wybrałeś. Trzeci kawałek jest w posiadaniu twojego własnego przywódcy. Zniszcz to, co kryje się w twoim sercu i wróć do mnie.",Você escolheu sabiamente. A terceira peça está com o seu próprio líder. Destrua aquilo que se esconde em seu coração e volte a mim.,,Ai ales înțelept. A treia piesă e deținută de liderul vostru. Distruge ceea ce se ascunde în inima ta și întoarce-te la mine.,"Мудрый выбор. Третий фрагмент у вашего лидера. Уничтожь то, что закралось в твоё сердце, и возвращайся ко мне.",,Du har valt klokt. Den tredje biten innehas av din egen ledare. Förstör det som gömmer sig i ditt hjärta och återvänd till mig.,Akıllıca bir seçim yaptın. Üçüncü parça kendi liderinizin elinde. Kalbinde sakladığın şeyi yok et ve bana dön. "We've found out that the Order is transforming our people into bio-mechanical soldiers. Find the facility where this is being done and close it, permanently! Find Richter in the commons, near the waterfall and he'll tell you how to stop this atrocity.",TXT_ILOG1028,,,,"Zjistili jsme, že Řád přeměňuje naše lidi na biomechanické vojáky. Najdi továrnu, kde se tohle odehrává, a zavři ji, natrvalo. Najdi Richtera na návsi u vodopádů. Řekne ti, jak zastavit tuto ohavnost.","Vi har fundet ud af, at Ordenen forvandler vores folk til biomekaniske soldater. Find det sted, hvor det sker, og luk det for altid! Find Richter i fællesarealerne, nær vandfaldet, og han vil fortælle dig, hvordan du kan stoppe denne grusomhed.","Wir haben herausgefunden, dass der Orden unsere Leute nicht tötet, sondern sie transformiert - int biomechanische Soldaten.Finde die Einrichtung, wo dies passiert und schließe sie - endgültig. Suche Richter beim Wasserfall bei der Mensa. Er wird dir sagen, wie du diese Abscheulichkeit abschaklten kannst.",,,"Hemos descubierto que la Orden está transformando a nuestra gente en soldados biomecánicos. Encuentra la instalación donde esto se está haciendo y ciérrala, ¡Permanentemente! Encuentra a Richter en los comunes, junto a la cascada y te dirá como detener esta atrocidad.","Hemos descubierto que la Orden está transformando a nuestra gente en soldado bio-mecánicos. ¡Encuentra la facilidad donde se está realizando esto y cierrala permanentemente! Encuentra a Richter en los comunes, cerca de la cascada y él te dirá como detener esta atrocidad.","Olemme saaneet selville, että Veljeskunta muuntelee meidän omiamme biomekaanisiksi sotilaiksi. Etsi laitos, jossa tätä tehdään, ja lakkauta se, pysyvästi! Etsi Richter messistä vesiputouksen läheltä, ja hän kertoo sinulle, miten lopettaa tämä kauhistus.",Nous avons découvert que l'Ordre transforme notre peuple en soldats biomécaniques. Trouve l'usine où cela se déroule et détruis-la pour toujours! Trouve Richter dans le Réfectoire près de la cascade et il t'expliquera comment stopper cette atrocité.,"Kiderítettük, hogy a Rend bio-mechanikus katonákká alakítja az embertársainkat. Keresd meg a létesítményt ahol ezt csinálják, és zárd be örökre! Keresd fel Richtert a vízesés melletti étkezdénél, Ő majd elmondja hogyan tudod megállítani ezt a borzalmat.","Abbiamo scoperto che l'Ordine sta trasformando la nostra gente in soldati bio-meccanici. Trova lo stabilimento dove questo sta avvenendo e chiuderlo, permanentemente. Trova Richter nei comuni, accanto alla cascata, e ti spiegherà come fermare questa atrocità.","我等はオーダーが人々をサイボーグ兵に改造しつつある事を発見した。 これが行われている施設を見つけ永久に停止させる。 -コモンズの滝近くにいるリヒターに会い、この残虐な行為を止める方法を聞く。","오더가 우리 사람들을 생체병기로 개조한다는 사실을 알았어. 끔찍한 일이 일어나는 이 시설을 찾아서 작동을 중단시켜, 영원히! 폭포와 가까운 식당가에 있는 릭터를 찾아서 어떻게 하면 중단시킬 수 있는지를 물어봐.","We hebben ontdekt dat de Orde onze mensen transformeert in bio-mechanische soldaten. Vind de faciliteit waar dit gebeurt en sluit deze permanent! Vind Richter in de commons, vlakbij de waterval, en hij zal je vertellen hoe je deze gruweldaad kunt stoppen.","Vi har funnet ut at Ordenen forvandler vårt folk til biomekaniske soldater. Finn anlegget der dette gjøres og steng det, permanent! Finn Richter i allmenningen, nær fossen, og han vil fortelle deg hvordan du kan stoppe denne grusomheten.","Odkryliśmy, że Zakon przekształca naszych ludzi w bio-mechanicznych żołnierzy. Znajdźcie placówkę, w której to się odbywa i zamknijcie ją, na stałe! Znajdź Richtera w komnatach, w pobliżu wodospadu, a on powie ci, jak powstrzymać to okrucieństwo.","Descobrimos que a Ordem está transformando o nosso pessoal em soldados biomecânicos. Encontre a instalação onde isso está sendo feito e feche-a, de uma vez por todas! Encontre o Richter no refeitório próximo à cascata e ele te dirá como parar com essa atrocidade.",,"Am aflat că Ordinul ne transformă oamenii în soldați bio-mecanici. Găsește fabrica unde se întâmplă asta și închide-o, permanent! Găsește-l pe Richter la comune, lângă cascadă și îți va spune cum să oprești atrocitatea.","Мы выяснили, что Орден превращает наших людей в биомеханических солдат. Найди фабрику, где это происходит, и закрой её, навсегда! Найди Рихтера в поселении Ордена, возле водопада — он расскажет тебе, как остановить эти зверства.",,"Tarikat'ın insanlarımızı biyo-mekanik askerlere dönüştürdüğünü öğrendik. Bunun yapıldığı tesisi bulun ve kalıcı olarak kapatın! Ortak alanda, şelalenin yanında Richter'i bulun ve size bu vahşeti nasıl durduracağınızı anlatsın." +コモンズの滝近くにいるリヒターに会い、この残虐な行為を止める方法を聞く。","오더가 우리 사람들을 생체병기로 개조한다는 사실을 알았어. 끔찍한 일이 일어나는 이 시설을 찾아서 작동을 중단시켜, 영원히! 폭포와 가까운 식당가에 있는 릭터를 찾아서 어떻게 하면 중단시킬 수 있는지를 물어봐.","We hebben ontdekt dat de Orde onze mensen transformeert in bio-mechanische soldaten. Vind de faciliteit waar dit gebeurt en sluit deze permanent! Vind Richter in de commons, vlakbij de waterval, en hij zal je vertellen hoe je deze gruweldaad kunt stoppen.","Vi har funnet ut at Ordenen forvandler vårt folk til biomekaniske soldater. Finn anlegget der dette gjøres og steng det, permanent! Finn Richter i allmenningen, nær fossen, og han vil fortelle deg hvordan du kan stoppe denne grusomheten.","Odkryliśmy, że Zakon przekształca naszych ludzi w bio-mechanicznych żołnierzy. Znajdźcie placówkę, w której to się odbywa i zamknijcie ją, na stałe! Znajdź Richtera w komnatach, w pobliżu wodospadu, a on powie ci, jak powstrzymać to okrucieństwo.","Descobrimos que a Ordem está transformando o nosso pessoal em soldados biomecânicos. Encontre a instalação onde isso está sendo feito e feche-a, de uma vez por todas! Encontre o Richter no refeitório próximo à cascata e ele te dirá como parar com essa atrocidade.",,"Am aflat că Ordinul ne transformă oamenii în soldați bio-mecanici. Găsește fabrica unde se întâmplă asta și închide-o, permanent! Găsește-l pe Richter la comune, lângă cascadă și îți va spune cum să oprești atrocitatea.","Мы выяснили, что Орден превращает наших людей в биомеханических солдат. Найди фабрику, где это происходит, и закрой её, навсегда! Найди Рихтера в поселении Ордена, возле водопада — он расскажет тебе, как остановить эти зверства.",,"Vi har fått reda på att Orden förvandlar vårt folk till biomekaniska soldater. Hitta anläggningen där detta görs och stäng den, för gott! Hitta Richter i allmänningen, nära vattenfallet, så berättar han hur du ska stoppa denna grymhet.","Tarikat'ın insanlarımızı biyo-mekanik askerlere dönüştürdüğünü öğrendik. Bunun yapıldığı tesisi bulun ve kalıcı olarak kapatın! Ortak alanda, şelalenin yanında Richter'i bulun ve size bu vahşeti nasıl durduracağınızı anlatsın." "To enter the factory, you need a key. We stole one, but the agent who had it is missing in the catacombs underneath the commons. There's something down there taking our men. Whatever it is, you have to find it and retrieve the key. When you've got it, the factory is next to the mines.",TXT_ILOG1029,,,,"Aby ses dostal do továrny, potřebuješ klíč. Ten jsme ukradli, ale náš agent se ztratil v sítí katakomb pod návsí. Něco je tam dole a zabíjí to naše lidi. Ať je to cokoliv, musíme to najít a získat ten klíč. Až ho získáš, továrna je vedle dolů.","For at komme ind på fabrikken skal du bruge en nøgle. Vi stjal en, men agenten, der havde den, er forsvundet i katakomberne under fællesarealerne. Der er noget dernede, der tager vores mænd. Uanset hvad det er, skal du finde det og hente nøglen. Når du har den, er fabrikken ved siden af minerne.","Um die Fabrik zu betreten, brauchst du einen Schlüssel. Wir haben ihn gestohlen, aber unser Agent ist in den Irrwegen der Katakomben unter der Festung des Ordens verschollen. Irgendetwas ist da unten, das unsere Leute ausschaltet. Was auch immer es ist, du musst es finden und den Schlüssel zurückholen. Wenn du ihn hast - die Fabrik ist direkt neben den Minen.",,,"Para entrar en la fábrica, necesitas una llave. Robamos una, pero el agente que la tiene está perdido en las catacumbas bajo los comunes. Hay algo ahí abajo tomando a nuestros hombres. Sea lo que sea, tienes que encontrarlo y recuperar la llave. Cuando la tengas, la fábrica está junto a las minas.","Para entrar en la Fábrica, necesitas una llave. Robamos una, pero el agente que la tenía está perdido en las catacumbas debajo de los comunes. Hay algo ahí abajo que está tomando nuestros hombres. Sea lo que sea, deberás encontrarlo y recuperar la llave. Cuando la tengas, la Fábrica está junto a las minas.","Päästäksesi sisälle tehtaaseen tarvitset avaimen. Varastimme sellaisen, mutta vakooja, joka sen sai, on kadoksissa katakombeissa messin alapuolella. Jokin siellä alla vie miehiämme. Mikä ikinä se onkaan, sinun on löydettävä se ja noudettava avain. Kun se on hallussasi, tehdas on kaivoksen vieressä.","Pour entrer dans l'usine, il te faura une clé. On en a volé une, mais l'agent qui la possède a disparu dans les catacombes sous le réfectoire. Il y a quelque chose à l'intérieur qui tue nos hommes. Trouve la et récupère la clé. Quand tu l'as, l'usine est près des mines.","Ahhoz, hogy bejuss a gyárba, kell szerezned egy kulcsot. Sikerült lopnunk egyet, de az ügynökünk akinél volt eltünt az étkezde alatti katakombákban. Van valami lent, ami sorra öli a katonáinkat. Akármi is vár lent, meg kell szerezned a kulcsot. Ha végeztél a gyárat megleled a bánya mellett.","Per entrare nella fabbrica ti servirà una chiave. L'abbiamo rubata ma l'agente che l'ha presa è sparito nelle catacombe sotto i comuni. C'è qualcosa là sotto che sta prendendo i nostri uomini. Qualsiasi cosa sia, devi andare laggiù e recuperare la chiave. Quando l'hai presa, la Fabbrica si trova accanto le miniere.","工場に入るにはキーが必要だ。持っていた代理人はコモンズの地下墓所にはいない。 何処かへ連れて行かれたと思われる。それが何であれキーを見つけなければならない。 -キーを手に入れたら工場の隣の鉱山に向かう。","공장으로 들어가기 위해서는 열쇠가 필요해. 열쇠를 훔치기는 했지만, 소유했던 요원이 식당가 밑 고대 무덤 안에서 행방불명 되었데. 우리 병사들을 끌고 가는 무언가가 있는 것 같아. 그게 무엇이든, 파괴해서 열쇠를 얻어. 그리고 광산 옆에 있는 공장을 열쇠로 열어서 들어가.","Om de fabriek binnen te komen, heb je een sleutel nodig. We hebben er een gestolen, maar de agent die hem had, wordt vermist in de catacomben onder de commons. Er is daar beneden iets dat onze mannen meeneemt. Wat het ook is, je moet het vinden en de sleutel ophalen. Als je hem hebt, staat de fabriek naast de mijnen.","For å komme inn i fabrikken trenger du en nøkkel. Vi stjal en, men agenten som hadde den er savnet i katakombene under allmenningen. Det er noe der nede som tar våre menn. Hva det enn er, må du finne det og hente nøkkelen. Når du har den, er fabrikken ved siden av gruvene.","Aby wejść do fabryki, potrzebujesz klucza. Ukradliśmy jeden, ale agent, który go miał, zaginął w katakumbach pod commons. Coś tam jest, co zabiera naszych ludzi. Cokolwiek to jest, musisz to znaleźć i odzyskać klucz. Gdy go zdobędziesz, fabryka znajduje się obok kopalni.","Para entrar na fábrica você precisa de uma chave. Nós roubamos uma, mas o agente que tinha ela desapareceu nas catacumbas sob o refeitório. Há algo lá embaixo que está pegando os nossos homens. Seja lá o que for, você precisa achar e recuperar a chave. Quando conseguir, a fábrica fica próxima às minas.",,"Pentru a intra în fabrică ai nevoie de cheie. Noi am furat una, dar agentul care a luat-o e undeva în caverne, sub comune. E ceva acolo care ne răpește oamenii. Orice ar fi, găsește-l și ia cheia. Când o ai, fabrica e lângă mine.","Тебе нужен ключ, чтобы проникнуть на фабрику. Мы украли один, но наш агент пропал без вести в катакомбах под поселением. Там, внизу, сидит что-то, что убивает наших людей. Что бы это ни было, тебе придётся сразиться с ним. Когда заполучишь ключ, вход на фабрику рядом со спуском в шахты.",,"Fabrikaya girmek için bir anahtara ihtiyacınız var. Bir tane çaldık, ama anahtarı alan ajan avlunun altındaki yeraltı mezarlarında kayıp. Aşağıda adamlarımızı kaçıran bir şey var. O her neyse, onu bulup anahtarı almalısın. Anahtarı aldığında, fabrika madenlerin yanında olacak." -Find the chalice in the sanctuary chapel and bring it to Harris upstairs in the tavern.,TXT_ILOG1101,,,,Najdi kalich v kapli svatyně a přines ho Harrisovi v patře taverny.,Find bægeret i helligkapellet og bring det til Harris ovenpå i tavernaen.,Finde den Kelch im Heiligtum und bringe ihn zu Harris im Obergeschoss der Taverne.,,,Encuentra el cáliz en la capilla del santuario y tráeselo a Harris arriba en la taberna.,,Löydä kalkki pyhäkön kappelista ja tuo se Harrisille kapakan yläkertaan.,Trouve le calice dans la chapelle du sanctuaire et amène la à Harris à l'étage de la taverne.,"Keresd meg a serleget a szent kápolnánál, és vidd Harrishez a kocsma emeletére.",Trova il calice nella cappella del santuario e portalo ad Harris al piano di sopra della Taverna.,聖域でチャリスを探しバーの二階にいるハリスに渡す,"성소에 있는 성배를 찾은 뒤, 선술집에 있는 헤리스에게 전달해.",Vind de kelk in de kapel van het heiligdom en breng hem naar Harris boven in de taverne.,Finn kalken i helligdomskapellet og ta den med til Harris oppe i tavernaen.,Znajdź kielich w kaplicy sanktuarium i zanieś go Harrisowi na górę w tawernie.,Encontre o cálice na capela do santuário e leve ao Harris no andar de cima da taverna.,,Găsește potirul în sanctuarul capelei și du-l lui Harris sus în tavernă.,Найди чашу в святилище и принеси её Харрису на второй этаж таверны.,,Kutsal şapeldeki kadehi bul ve tavernanın üst katındaki Harris'e getir. -Find the Governor's mansion and talk to the Governor to get your reward,TXT_ILOG1102,,,,Najdi guvernérovo sídlo a promluv si s ním pro svou odměnu.,Find guvernørens palæ og tal med guvernøren for at få din belønning,Finde die Villa des Gouverneurs und rede mit ihm über deine Belohnung.,,,Encuentra la mansión del Gobernador y habla con él para obtener tu recompensa,,Löydä kuvernöörin kartano ja puhu kuvernöörin kanssa saadaksesi palkkiosi.,Trouve le manoir du Gouverneur et parle-lui pour réclamer ta récompense.,"Keresd fel a Kormányzót a kúriájában, hogy megkapd a jutalmad.",Trova la dimora del governatore e parlagli della tua ricompensa.,知事のマンションで知事と話し報酬を得る,총독의 거주지를 찾은 뒤 총독을 만나서 보상에 대해 예기해.,Zoek het herenhuis van de Gouverneur en praat met de Gouverneur om je beloning te krijgen.,Finn guvernørens herskapshus og snakk med guvernøren for å få belønningen.,"Znajdź rezydencję gubernatora i porozmawiaj z nim, aby otrzymać nagrodę",Encontre a mansão do Governador e fale com ele para pegar a sua recompensa.,,Găsește complexul Guvernatorului și vorbește cu el pentru a-ți lua recompensa.,Пройди в особняк губернатора и обсуди с Морелом своё вознаграждение.,,Vali'nin konağını bulun ve ödülünüzü almak için Vali ile konuşun +キーを手に入れたら工場の隣の鉱山に向かう。","공장으로 들어가기 위해서는 열쇠가 필요해. 열쇠를 훔치기는 했지만, 소유했던 요원이 식당가 밑 고대 무덤 안에서 행방불명 되었데. 우리 병사들을 끌고 가는 무언가가 있는 것 같아. 그게 무엇이든, 파괴해서 열쇠를 얻어. 그리고 광산 옆에 있는 공장을 열쇠로 열어서 들어가.","Om de fabriek binnen te komen, heb je een sleutel nodig. We hebben er een gestolen, maar de agent die hem had, wordt vermist in de catacomben onder de commons. Er is daar beneden iets dat onze mannen meeneemt. Wat het ook is, je moet het vinden en de sleutel ophalen. Als je hem hebt, staat de fabriek naast de mijnen.","For å komme inn i fabrikken trenger du en nøkkel. Vi stjal en, men agenten som hadde den er savnet i katakombene under allmenningen. Det er noe der nede som tar våre menn. Hva det enn er, må du finne det og hente nøkkelen. Når du har den, er fabrikken ved siden av gruvene.","Aby wejść do fabryki, potrzebujesz klucza. Ukradliśmy jeden, ale agent, który go miał, zaginął w katakumbach pod commons. Coś tam jest, co zabiera naszych ludzi. Cokolwiek to jest, musisz to znaleźć i odzyskać klucz. Gdy go zdobędziesz, fabryka znajduje się obok kopalni.","Para entrar na fábrica você precisa de uma chave. Nós roubamos uma, mas o agente que tinha ela desapareceu nas catacumbas sob o refeitório. Há algo lá embaixo que está pegando os nossos homens. Seja lá o que for, você precisa achar e recuperar a chave. Quando conseguir, a fábrica fica próxima às minas.",,"Pentru a intra în fabrică ai nevoie de cheie. Noi am furat una, dar agentul care a luat-o e undeva în caverne, sub comune. E ceva acolo care ne răpește oamenii. Orice ar fi, găsește-l și ia cheia. Când o ai, fabrica e lângă mine.","Тебе нужен ключ, чтобы проникнуть на фабрику. Мы украли один, но наш агент пропал без вести в катакомбах под поселением. Там, внизу, сидит что-то, что убивает наших людей. Что бы это ни было, тебе придётся сразиться с ним. Когда заполучишь ключ, вход на фабрику рядом со спуском в шахты.",,"För att komma in i fabriken behöver du en nyckel. Vi stal en, men agenten som hade den är försvunnen i katakomberna under allmänningen. Det är något där nere som tar våra män. Vad det än är måste du hitta det och hämta nyckeln. När du har fått den är fabriken bredvid gruvorna.","Fabrikaya girmek için bir anahtara ihtiyacınız var. Bir tane çaldık, ama anahtarı alan ajan avlunun altındaki yeraltı mezarlarında kayıp. Aşağıda adamlarımızı kaçıran bir şey var. O her neyse, onu bulup anahtarı almalısın. Anahtarı aldığında, fabrika madenlerin yanında olacak." +Find the chalice in the sanctuary chapel and bring it to Harris upstairs in the tavern.,TXT_ILOG1101,,,,Najdi kalich v kapli svatyně a přines ho Harrisovi v patře taverny.,Find bægeret i helligkapellet og bring det til Harris ovenpå i tavernaen.,Finde den Kelch im Heiligtum und bringe ihn zu Harris im Obergeschoss der Taverne.,,,Encuentra el cáliz en la capilla del santuario y tráeselo a Harris arriba en la taberna.,,Löydä kalkki pyhäkön kappelista ja tuo se Harrisille kapakan yläkertaan.,Trouve le calice dans la chapelle du sanctuaire et amène la à Harris à l'étage de la taverne.,"Keresd meg a serleget a szent kápolnánál, és vidd Harrishez a kocsma emeletére.",Trova il calice nella cappella del santuario e portalo ad Harris al piano di sopra della Taverna.,聖域でチャリスを探しバーの二階にいるハリスに渡す,"성소에 있는 성배를 찾은 뒤, 선술집에 있는 헤리스에게 전달해.",Vind de kelk in de kapel van het heiligdom en breng hem naar Harris boven in de taverne.,Finn kalken i helligdomskapellet og ta den med til Harris oppe i tavernaen.,Znajdź kielich w kaplicy sanktuarium i zanieś go Harrisowi na górę w tawernie.,Encontre o cálice na capela do santuário e leve ao Harris no andar de cima da taverna.,,Găsește potirul în sanctuarul capelei și du-l lui Harris sus în tavernă.,Найди чашу в святилище и принеси её Харрису на второй этаж таверны.,,Hitta kalken i helgedomens kapell och ta med den till Harris uppe i tavernan.,Kutsal şapeldeki kadehi bul ve tavernanın üst katındaki Harris'e getir. +Find the Governor's mansion and talk to the Governor to get your reward,TXT_ILOG1102,,,,Najdi guvernérovo sídlo a promluv si s ním pro svou odměnu.,Find guvernørens palæ og tal med guvernøren for at få din belønning,Finde die Villa des Gouverneurs und rede mit ihm über deine Belohnung.,,,Encuentra la mansión del Gobernador y habla con él para obtener tu recompensa,,Löydä kuvernöörin kartano ja puhu kuvernöörin kanssa saadaksesi palkkiosi.,Trouve le manoir du Gouverneur et parle-lui pour réclamer ta récompense.,"Keresd fel a Kormányzót a kúriájában, hogy megkapd a jutalmad.",Trova la dimora del governatore e parlagli della tua ricompensa.,知事のマンションで知事と話し報酬を得る,총독의 거주지를 찾은 뒤 총독을 만나서 보상에 대해 예기해.,Zoek het herenhuis van de Gouverneur en praat met de Gouverneur om je beloning te krijgen.,Finn guvernørens herskapshus og snakk med guvernøren for å få belønningen.,"Znajdź rezydencję gubernatora i porozmawiaj z nim, aby otrzymać nagrodę",Encontre a mansão do Governador e fale com ele para pegar a sua recompensa.,,Găsește complexul Guvernatorului și vorbește cu el pentru a-ți lua recompensa.,Пройди в особняк губернатора и обсуди с Морелом своё вознаграждение.,,Hitta guvernörens herrgård och prata med guvernören för att få din belöning.,Vali'nin konağını bulun ve ödülünüzü almak için Vali ile konuşun Congratulations! You have earned our gratitude. Visit the medic and weapons trainer and they will get you ready for what lies ahead. Feel free to wander around within the base.,TXT_ILOG1201,,,,"Gratulujeme! Získal sis naši vděčnost. Navštiv lékaře a učitele střelby a oni tě připraví na to, co číhá dál. Klidně se potloukej po základně.","Tillykke med det! Du har fortjent vores taknemmelighed. Besøg lægen og våbentræneren, og de vil gøre dig klar til det, der venter forude. Du er velkommen til at vandre rundt i basen.","Gratulation. Du hast dir unsere Dankbarkeit verdient. Suche den Sanitäter und den Waffentrainer auf, sie werden dich auf das was vor dir liegt, vorbereiten. Wenn du willst, schau dich in der Basis um.",,,¡Enhorabuena! Te has ganado nuestra gratitud. Visita al médico y al entrenador de armas y te prepararán para lo que viene en adelante. Sé libre de dar un paseo por la base.,¡Felicitaciones! Te ganaste nuestra gratitud. Visita al médico y al entrenador de armas y ellos te dejarán listo para lo que sigue. Sientete libre de andar através de la base.,"Onneksi olkoon! Olet ansainnut kiitollisuutemme. Vieraile lääkintämiehen ja asekouluttajan luona, ja he valmistavat sinut tuleviin koitoksiin. Saat vapaasti kulkea tukikohdan sisällä.",Félicitations! Vous méritez notre gratitude. Allez voir le médecin et le maître d'armes et ils pourront vous préparer pour ce qu'il va suivre. Vous pouvez faire le tour de la base si vous le souhaitez.,"Gratulálok! Kiérdemled a hálánkat! keresd fel a szanitécet és a fegyvermestert, és felkészítenek az előtted álló harcra. Nyugodtan nézz körbe a bázisban.",Congratulazioni! Meriti appieno la nostra gratitudine. Visita il medico e l'addestratore di armi e ti prepareranno per ciò che ci aspetta. Sii anche libero di andare in giro per la base.,"おめでとう!私達は貴方に感謝している。 メディックと武器トレーナーに訪れれば手助けを施せる。 -基地内部も自由に回ってよい。",축하해! 우리 모두 너에게 고마워하고 있어. 의무관과 무기 담당관을 찾아가면 너에게 보답을 할 준비를 할 거야. 그 후엔 기지를 마음껏 돌아다녀 봐!,Gefeliciteerd! Je hebt onze dankbaarheid verdiend. Bezoek de medicus- en wapentrainer en zij zullen je klaarstomen voor wat je te wachten staat. Voel je vrij om rond te dwalen in de basis.,"Gratulerer! Du har fortjent vår takknemlighet. Besøk medisineren og våpentreneren, og de vil gjøre deg klar for det som ligger foran deg. Føl deg fri til å vandre rundt i basen.","Gratulacje!!! Zasłużyłeś na naszą wdzięczność. Odwiedź medyka i trenera broni, a oni przygotują Cię na to, co Cię czeka. Możesz swobodnie poruszać się po bazie.",Parabéns! Você conquistou a nossa gratidão. Visite o médico e o treinador de armas e eles vão te preparar para o que vem adiante. Sinta-se livre para passear pela base.,,Felicitări! Ne-ai câștigat recunoștiința. Vizitează medicul și antrenorul de arme și te vor pregătii pentru ceea ce urmează mai departe. Simte-te liber să te plimbi prin bază.,"Поздравляем! Ты заслужил нашу благодарность. Зайди к медику и инструктору по стрельбе, и они подготовят тебя к тому, что ждёт тебя впереди. Теперь ты можешь свободно передвигаться по нашей базе.",,"Tebrikler! Minnettarlığımızı kazandınız. Sıhhiyeyi ve silah eğitmenini ziyaret edin, onlar sizi ileride olacaklara hazırlayacaktır. Üs içinde dolaşmaktan çekinmeyin." -,,Strife characters,,,,,,,,,,,,,,,,,,,,,,,, -Order Sergeant,TXT_SPEAKER_ORDER_SERGEANT,,,,Seržant Řádu,Ordenens sergent,Soldat des Ordens,,,Sargento de La Orden,,Veljeskunnan kersantti,Sergeant de l'Ordre,Rendi Törzsőrmester,Sergente dell'Ordine,オーダー軍曹,오더 장교,Soldaat van de orde,Ordenssersjant,Sierżant Zakonu,Sargento da Ordem,,Sergent al Ordinului,Сержант Ордена,,Emir Çavuşu -Rowan,TXT_SPEAKER_ROWAN,,,,,,,,,,,,,,,ロワン,로언,,,,,,,Роуэн,,Rowan -Feris,TXT_SPEAKER_FERIS,,,,,,,,,,,,,,,フェリス,페리스,,,,,,,Ферис,,Feris +基地内部も自由に回ってよい。",축하해! 우리 모두 너에게 고마워하고 있어. 의무관과 무기 담당관을 찾아가면 너에게 보답을 할 준비를 할 거야. 그 후엔 기지를 마음껏 돌아다녀 봐!,Gefeliciteerd! Je hebt onze dankbaarheid verdiend. Bezoek de medicus- en wapentrainer en zij zullen je klaarstomen voor wat je te wachten staat. Voel je vrij om rond te dwalen in de basis.,"Gratulerer! Du har fortjent vår takknemlighet. Besøk medisineren og våpentreneren, og de vil gjøre deg klar for det som ligger foran deg. Føl deg fri til å vandre rundt i basen.","Gratulacje!!! Zasłużyłeś na naszą wdzięczność. Odwiedź medyka i trenera broni, a oni przygotują Cię na to, co Cię czeka. Możesz swobodnie poruszać się po bazie.",Parabéns! Você conquistou a nossa gratidão. Visite o médico e o treinador de armas e eles vão te preparar para o que vem adiante. Sinta-se livre para passear pela base.,,Felicitări! Ne-ai câștigat recunoștiința. Vizitează medicul și antrenorul de arme și te vor pregătii pentru ceea ce urmează mai departe. Simte-te liber să te plimbi prin bază.,"Поздравляем! Ты заслужил нашу благодарность. Зайди к медику и инструктору по стрельбе, и они подготовят тебя к тому, что ждёт тебя впереди. Теперь ты можешь свободно передвигаться по нашей базе.",,Gratulerar! Du har förtjänat vår tacksamhet. Besök sjukvårdaren och vapentränaren och de kommer att göra dig redo för vad som väntar dig. Du får gärna vandra runt i basen.,"Tebrikler! Minnettarlığımızı kazandınız. Sıhhiyeyi ve silah eğitmenini ziyaret edin, onlar sizi ileride olacaklara hazırlayacaktır. Üs içinde dolaşmaktan çekinmeyin." +,,Strife characters,,,,,,,,,,,,,,,,,,,,,,,,, +Order Sergeant,TXT_SPEAKER_ORDER_SERGEANT,,,,Seržant Řádu,Ordenens sergent,Soldat des Ordens,,,Sargento de La Orden,,Veljeskunnan kersantti,Sergeant de l'Ordre,Rendi Törzsőrmester,Sergente dell'Ordine,オーダー軍曹,오더 장교,Soldaat van de orde,Ordenssersjant,Sierżant Zakonu,Sargento da Ordem,,Sergent al Ordinului,Сержант Ордена,,Sergeant på orden,Emir Çavuşu +Rowan,TXT_SPEAKER_ROWAN,,,,,,,,,,,,,,,ロワン,로언,,,,,,,Роуэн,,, +Feris,TXT_SPEAKER_FERIS,,,,,,,,,,,,,,,フェリス,페리스,,,,,,,Ферис,,, Prison Guard,TXT_SPEAKER_PRISON_GUARD,,,,Vězeňská stráž,Fængselsbetjent,Gefängniswache,,,Guardia de la Prisión,,Vanginvartija,Garde de la Prison,Börtönőr,Guardia della Prigione,刑務官,간수,Gevangenisbewaker,Fengselsvakt,Strażnik Więzienny,Guarda da Prisão,,Gardian Închisoare,"Страж тюрьмы -",,Hapishane Gardiyanı -Justin,TXT_SPEAKER_JUSTIN,,,,,,,,,,,,,,,ジャスティン,저스틴,,,,,,,Джастин,,Justin -Macil,TXT_SPEAKER_MACIL,,,,,,,,,,,,,,,マシル,마실,,,,,,,Мэйсил,,Macil -Assistant,TXT_SPEAKER_ASSISTANT,,,,Asistent,Assistent,Assistent,,,Asistente,,Avustaja,,Asszisztens,Assistente,アシスタント,조수,Assistent,Assistent,Asystent,Assistente,,Asistent,Ассистент,,Asistan -Key Master,TXT_SPEAKER_KEY_MASTER,,,,Klíčník,Nøglemester,Schlüsselmeister,,,Amo de Llaves,,Avainmestari,Maître des Clés,Kulcsmester,Mastro delle chiavi,キーマスター,열쇠지기,Zeer belangrijke Meester,Nøkkelmester,Klucznik,Mestre das Chaves,,Stăpân al Cheilor,Ключник,,Anahtar Ustası -Bodyguard,TXT_SPEAKER_BODYGUARD,,,,Osobní stráž,Livvagt,Leibwächter,,,Guardaespaldas,,Henkivartija,Garde du corps,Testőr,Guardia del corpo,ボディガード,경호원,Lijfwacht,Livvakt,Ochroniarz,Guarda-costas,,Gardă de Corp,Телохранитель,,Bodyguard -Interrogator,TXT_SPEAKER_INTERROGATOR,"Intended to appear in MAP01 of the Strife teaser, but does not spawn.",,,Vyslýchač,Forhørsleder,Befrager,,,Interrogador,,Kuulustelija,Interrogateur,Kihallgató,Interrogatore,,심문자,Ondervrager,Avhører,Śledczy,Interrogador,,Interogator,Дознаватель,,Sorgulayıcı -Warden Montag,TXT_SPEAKER_WARDEN_MONTAG,,,,Dozorce Montag,Direktør Montag,Direktor Montag,,,Carcelero Montag,,Vankilanjohtaja Montag,Gardien Montag,Montag börtönigazgató,Direttore Montag,モンターグ刑務所長,몬탕 간수장,Directeur Montag,Direktør Montag,Naczelnik Montag,Carcereiro Montag,,Directorul Montag,Тюремщик Монтаг,,Müdür Montag -Richter,TXT_SPEAKER_RICHTER,,,,,,,,,,,,,,,リヒター,릭터,,,,,,,Рихтер,,Richter -Macil's Advisor,TXT_SPEAKER_MACIL_S_ADVISOR,,,,Macilův rádce,Macils rådgiver,Macils Berater,,,Consejero de Macil,,Macilin neuvonantaja,Conseiller de Macil,Macil tanácsosa,Consigliere di Macil,マシルの補佐官,마실의 조언자,Macil's adviseur,Macils rådgiver,Doradca Macila,Conselheiro de Macil,,Sfetnicul lui Macil,Советник Мэйсила,,Macil'in Danışmanı -Judge Wolenick,TXT_SPEAKER_JUDGE_WOLENICK,,,,Soudce Wolenick,Dommer Wolenick,Richter Wolenick,,,Juez Wolenick,,Tuomari Wolenick,Juge Wolenick,Wolenick bíró,Giudice Wolenick,ウォレニック裁判官,울레닉 판사,Rechter Wolenick,Dommer Wolenick,Sędzia Wolenick,Juiz Wolenick,,Judecătorul Wolenick,Судья Уолник,,Yargıç Wolenick -Tevick,TXT_SPEAKER_TEVICK,,,,,,,,,,,,,,,テビック,테빅,,,,,,,Тевик,,Tevak -Harris,TXT_SPEAKER_HARRIS,,,,,,,,,,,,,,,ハリス,해리스,,,,,,,Харрис,,Harris -Foreman,TXT_SPEAKER_FOREMAN,,,,Předák,Formand,Vormann,,,Capataz,,Työnjohtaja,Contremaître,Művezető,Caposquadra,フォアマン,감시원,Voorman,Formann,Brygadzista,Capataz,,,Бригадир,,Ustabaşı -Prisoner,TXT_SPEAKER_PRISONER,,,,Vězeň,Fange,Gefangener,,Kaptito,Prisionero,,Vanki,Prisonnier,Rab,Prigioniero,囚人,죄수,Gevangene,Fange,Więzień,Prisioneiro,,Prizonier,Пленник,,Mahkum -Sammis,TXT_SPEAKER_SAMMIS,,,,,,,,,,,,,,,サムミス,새미스,,,,,,,Сэммис,,Sammis -Weapon Smith,TXT_SPEAKER_WEAPON_SMITH,,,,Zbrojíř,Våbensmed,Waffenschmied,,Armilforĝisto,Forjador de Armas,,Aseseppä,Armurier,Fegyverkovács,Fabbro d'Armi,武器工,무기제조인,Wapen Smith,Våpensmed,Wytwórca Broni,Armeiro,,Făurar Arme,Оружейник,,Silah Ustası -Reactor Guard,TXT_SPEAKER_REACTOR_GUARD,,,,Stráž reaktoru,Reaktorvagt,Reaktorwache,,,Guardia del Reactor,,Reaktorinvartija,Garde du réacteur,Reaktor Őr,Guardia del Reattore,リアクターガード,발전소 경비원,Reactor bewaker,Reaktorvakt,Strażnik Reaktora,Guarda do Reator,,Gardian Reactor,Страж реактора,,Reaktör Muhafızı -Apprentice,TXT_SPEAKER_APPRENTICE,,,,Učeň,Lærling,Lehrling,,,Aprendiz,,Kisälli,Apprenti,Tanonc,Apprendista,見習い,도제,Leerling,Lærling,Uczeń,Aprendiz,,Ucenic,Подмастерье,,Çırak -Door Guard,TXT_SPEAKER_DOOR_GUARD,,,,Dveřní stráž,Dørvagt,Türwache,,,Guarda de la Puerta,,Ovenvartija,Garde de la porte,Ajtónálló,Guardia della Porta,ドアガード,문지기,Deurwacht,Dørvakt,Strażnik Drzwi,Guarda da Porta,,Paznic,Страж входа,,Kapı Koruması -Master Smithy,TXT_SPEAKER_MASTER_SMITHY,,,,Mistr Smithy,Mester Smithy,Meister Smithy,,,Maestro Smithy,,Pajamestari,Maîre Smithy,Smithy mester,Maestro Smithy,マスター スミシー,스미시 제조장관,Meester Smithy,Mester Smithy,Mistrz Smithy,Mestre Smithy,,Maestrul Smithy,Мастер-кузнец,,Demirci Usta -Warehouse Guard,TXT_SPEAKER_WAREHOUSE_GUARD,,,,Stráž skladu,Lagervagt,Lagerhaus-Wache,,,Guardia del Almacén,,Varastonvartija,Garde de l'entrepôt,Raktár Őr,Guardia del Magazzino,倉庫のガード,격납고 감시장,Magazijnwachter,Lagervakt,Strażnik Magazynu,Guarda do Depósito,,Paznic Depozit,Охранник склада,,Depo Görevlisi -Barkeep,TXT_SPEAKER_BARKEEP,,,,Barman,Bartender,Wirt,,Trinkejisto,Tabernero,Barman,Baarimikko,Barman,Bárpultos,Barman,バーテンダー,바텐더,Barman,Bartender,Barman,Taberneiro,,Barman,Хозяин таверны,,Barmen -Timothy,TXT_SPEAKER_TIMOTHY,,,,,,,,,,,,,,,ティモシー,티모시,,,,,,Timotei,Тимоти,,Timothy -James,TXT_SPEAKER_JAMES,,,,,,,,,,,,,,,ジェームス,제임스,,,,,,,Джеймс,,James -Worner,TXT_SPEAKER_WORNER,,,,,,,,,,,,,,,ワーナー,워너,,,,,,,Уорнэр,,Worner -Bailey Guard,TXT_SPEAKER_BAILEY_GUARD,,,,Stráž opevnění,Bailey-vagt,Vorhof-Wache,,,Guardia de la Muralla,,Ulkomuurinvartija,Garde d'enceinte,Várfal Őr,Guardia del Bastione,ベイリー ガード,외벽 파수병,Bailey Guard,Borggården vakt,Strażnik Murów,Guarda da Fortaleza,,Gardian Bailey,Страж крепости,,Dış avlu bekçisi -Drone,TXT_SPEAKER_DRONE,,,,Trubec,,Drohne,,,Dron,,Kuhnuri,,Drón,,労働者,노예,Drone,,Dron,Zangão,,Dronă,Дрон,,Drone -Front Guard,TXT_SPEAKER_FRONT_GUARD,,,,Stráž Fronty,Front vagt,Frontwache,,,Guardia del Frente,,Rintaman vartija,Garde du Front,Front Őr,Guardia del Fronte,フロント ガード,프론트 파수꾼,Voorwacht,Front Guard,Strażnik Frontu,Guarda da Frente,,Gandian Front,Повстанец,,Ön Koruma -Quincy,TXT_SPEAKER_QUINCY,,,,,,,,,,,,,,,クインシー,퀸시,,,,,,,Куинси,,Quincy -Sergeant,TXT_SPEAKER_SERGEANT,,,,Seržant,Sergent,Feldwebel,,,Sargento,,Kersantti,Sergeant,Törzsőrmester,Sergente,軍曹,하사관,Sergeant,Sersjant,Sierżant,Sargento,,Sergent,Сержант,,Çavuş -Temple Guard,TXT_SPEAKER_TEMPLE_GUARD,,,,Stráž chrámu,Tempelvagt,Tempelwache,,,Guardia del Templo,,Temppelinvartija,Garde du Temple,Templom Őr,Guardia del Tempio,テンプル ガード,신전 파수병,Tempelwacht,Tempelvakten,Strażnik Świątyni,Guarda do Templo,,Gardian Templu,Страж храма,,Tapınak Muhafızı -Oracle,TXT_SPEAKER_ORACLE,,,,Věštec,Orakel,Orakel,,Orakolo,Oráculo,,Oraakkeli,,Orákulum,Oracolo,オラクル,오라클,Orakel,Orakel,Wyrocznia,Oráculo,,Oracol,Оракул,,Kahin -Ulaine,TXT_SPEAKER_ULAINE,,,,,,,,,,,,,,,ウレーヌ,울레인,,,,,,,Улейн,,Ulane -Front Soldier,TXT_SPEAKER_FRONT_SOLDIER,,,,Voják Fronty,Frontsoldat,Front-Soldat,,,Soldado del Frente,,Rintaman sotilas,Soldat du Front,Front Katona,Soldato del Fronte,フロント ソルジャー,프론트 저항군,Front Soldier,Frontsoldat,Żołnierz Frontu,Soldado da Frente,,Soldat Front,Повстанец,,Ön Asker -Programmer,TXT_SPEAKER_PROGRAMMER,,,,Programátor,Programmør,Programmierer,,Programisto,Programador,,Ohjelmoitsija,Programmeur,Programozó,Programmatore,プログラマー,프로그래머,Programmeur,Programmerer,Programista,Programador,,Programator,Программист,,Programcı -Medic,TXT_SPEAKER_MEDIC,,,,Zdravotník,Læge,Sanitäter,,Kuracisto,Médico,,Lääkintämies,Médecin,Szanitéc,Medico,メディック,의무병,Paramedicus,Sanitetssoldat,Medyk,Médico,,,Медик,,Medic -Watchman,TXT_SPEAKER_WATCHMAN,,,,Hlídač,Vagtmand,Wächter,,,Celador,,Vahti,Vigie,Őrszem,Vigilante,警備員,감시병,Waker,Vaktmann,Stróż,Vigia,,Străjer,Караульный,,Bekçi -Ketrick,TXT_SPEAKER_KETRICK,,,,,,,,,,,,,,,ケトリック,케트릭,,,,,,,Кетрик,,Ketrick -Weran,TXT_SPEAKER_WERAN,,,,,,,,,,,,,,,ウェラン,워렌,,,,,,,Уэран,,Weran -Advisor,TXT_SPEAKER_ADVISOR,,,,Rádce,Rådgiver,Berater,,,Consejero,,Neuvonantaja,Conseiller,Tanácsadó,Consigliere,補佐官,조언자,Adviseur,Rådgiver,Doradca,Conselheiro,,Sfetnic,Советник,,Danışman -Geoff,TXT_SPEAKER_GEOFF,,,,,,,,,,,,,,,ジェフ,제프,,,,,,,Джефф,,Geoff -Overseer,TXT_SPEAKER_OVERSEER,,,,Dozorčí,Tilsynsførende,Aufseher,,,Superintendente,,Valvoja,Superviseur,Munkavezető,Supervisore,監視人,현장 감독,Opziener,Oppsynsmann,Nadzorca,Supervisor,,Supraveghetor,Надсмотрщик,,Gözetmen +",,Fångvakt,Hapishane Gardiyanı +Justin,TXT_SPEAKER_JUSTIN,,,,,,,,,,,,,,,ジャスティン,저스틴,,,,,,,Джастин,,, +Macil,TXT_SPEAKER_MACIL,,,,,,,,,,,,,,,マシル,마실,,,,,,,Мэйсил,,, +Assistant,TXT_SPEAKER_ASSISTANT,,,,Asistent,Assistent,Assistent,,,Asistente,,Avustaja,,Asszisztens,Assistente,アシスタント,조수,Assistent,Assistent,Asystent,Assistente,,Asistent,Ассистент,,Assistent,Asistan +Key Master,TXT_SPEAKER_KEY_MASTER,,,,Klíčník,Nøglemester,Schlüsselmeister,,,Amo de Llaves,,Avainmestari,Maître des Clés,Kulcsmester,Mastro delle chiavi,キーマスター,열쇠지기,Zeer belangrijke Meester,Nøkkelmester,Klucznik,Mestre das Chaves,,Stăpân al Cheilor,Ключник,,Nyckelmästare,Anahtar Ustası +Bodyguard,TXT_SPEAKER_BODYGUARD,,,,Osobní stráž,Livvagt,Leibwächter,,,Guardaespaldas,,Henkivartija,Garde du corps,Testőr,Guardia del corpo,ボディガード,경호원,Lijfwacht,Livvakt,Ochroniarz,Guarda-costas,,Gardă de Corp,Телохранитель,,Livvakt, +Interrogator,TXT_SPEAKER_INTERROGATOR,"Intended to appear in MAP01 of the Strife teaser, but does not spawn.",,,Vyslýchač,Forhørsleder,Befrager,,,Interrogador,,Kuulustelija,Interrogateur,Kihallgató,Interrogatore,,심문자,Ondervrager,Avhører,Śledczy,Interrogador,,Interogator,Дознаватель,,Förhörsledare,Sorgulayıcı +Warden Montag,TXT_SPEAKER_WARDEN_MONTAG,,,,Dozorce Montag,Direktør Montag,Direktor Montag,,,Carcelero Montag,,Vankilanjohtaja Montag,Gardien Montag,Montag börtönigazgató,Direttore Montag,モンターグ刑務所長,몬탕 간수장,Directeur Montag,Direktør Montag,Naczelnik Montag,Carcereiro Montag,,Directorul Montag,Тюремщик Монтаг,,Direktör Montag,Müdür Montag +Richter,TXT_SPEAKER_RICHTER,,,,,,,,,,,,,,,リヒター,릭터,,,,,,,Рихтер,,, +Macil's Advisor,TXT_SPEAKER_MACIL_S_ADVISOR,,,,Macilův rádce,Macils rådgiver,Macils Berater,,,Consejero de Macil,,Macilin neuvonantaja,Conseiller de Macil,Macil tanácsosa,Consigliere di Macil,マシルの補佐官,마실의 조언자,Macil's adviseur,Macils rådgiver,Doradca Macila,Conselheiro de Macil,,Sfetnicul lui Macil,Советник Мэйсила,,Macils rådgivare,Macil'in Danışmanı +Judge Wolenick,TXT_SPEAKER_JUDGE_WOLENICK,,,,Soudce Wolenick,Dommer Wolenick,Richter Wolenick,,,Juez Wolenick,,Tuomari Wolenick,Juge Wolenick,Wolenick bíró,Giudice Wolenick,ウォレニック裁判官,울레닉 판사,Rechter Wolenick,Dommer Wolenick,Sędzia Wolenick,Juiz Wolenick,,Judecătorul Wolenick,Судья Уолник,,Domare Wolenick,Yargıç Wolenick +Tevick,TXT_SPEAKER_TEVICK,,,,,,,,,,,,,,,テビック,테빅,,,,,,,Тевик,,,Tevak +Harris,TXT_SPEAKER_HARRIS,,,,,,,,,,,,,,,ハリス,해리스,,,,,,,Харрис,,, +Foreman,TXT_SPEAKER_FOREMAN,,,,Předák,Formand,Vormann,,,Capataz,,Työnjohtaja,Contremaître,Művezető,Caposquadra,フォアマン,감시원,Voorman,Formann,Brygadzista,Capataz,,,Бригадир,,Förman,Ustabaşı +Prisoner,TXT_SPEAKER_PRISONER,,,,Vězeň,Fange,Gefangener,,Kaptito,Prisionero,,Vanki,Prisonnier,Rab,Prigioniero,囚人,죄수,Gevangene,Fange,Więzień,Prisioneiro,,Prizonier,Пленник,,Fånge,Mahkum +Sammis,TXT_SPEAKER_SAMMIS,,,,,,,,,,,,,,,サムミス,새미스,,,,,,,Сэммис,,, +Weapon Smith,TXT_SPEAKER_WEAPON_SMITH,,,,Zbrojíř,Våbensmed,Waffenschmied,,Armilforĝisto,Forjador de Armas,,Aseseppä,Armurier,Fegyverkovács,Fabbro d'Armi,武器工,무기제조인,Wapen Smith,Våpensmed,Wytwórca Broni,Armeiro,,Făurar Arme,Оружейник,,Vapen Smith,Silah Ustası +Reactor Guard,TXT_SPEAKER_REACTOR_GUARD,,,,Stráž reaktoru,Reaktorvagt,Reaktorwache,,,Guardia del Reactor,,Reaktorinvartija,Garde du réacteur,Reaktor Őr,Guardia del Reattore,リアクターガード,발전소 경비원,Reactor bewaker,Reaktorvakt,Strażnik Reaktora,Guarda do Reator,,Gardian Reactor,Страж реактора,,Reaktorvakt,Reaktör Muhafızı +Apprentice,TXT_SPEAKER_APPRENTICE,,,,Učeň,Lærling,Lehrling,,,Aprendiz,,Kisälli,Apprenti,Tanonc,Apprendista,見習い,도제,Leerling,Lærling,Uczeń,Aprendiz,,Ucenic,Подмастерье,,Lärling,Çırak +Door Guard,TXT_SPEAKER_DOOR_GUARD,,,,Dveřní stráž,Dørvagt,Türwache,,,Guarda de la Puerta,,Ovenvartija,Garde de la porte,Ajtónálló,Guardia della Porta,ドアガード,문지기,Deurwacht,Dørvakt,Strażnik Drzwi,Guarda da Porta,,Paznic,Страж входа,,Dörrvakt,Kapı Koruması +Master Smithy,TXT_SPEAKER_MASTER_SMITHY,,,,Mistr Smithy,Mester Smithy,Meister Smithy,,,Maestro Smithy,,Pajamestari,Maître Forgeron,Smithy mester,Maestro Smithy,マスター スミシー,스미시 제조장관,Meester Smithy,Mester Smithy,Mistrz Smithy,Mestre Smithy,,Maestrul Smithy,Мастер-кузнец,,Mästersmeden,Demirci Usta +Warehouse Guard,TXT_SPEAKER_WAREHOUSE_GUARD,,,,Stráž skladu,Lagervagt,Lagerhaus-Wache,,,Guardia del Almacén,,Varastonvartija,Garde de l'entrepôt,Raktár Őr,Guardia del Magazzino,倉庫のガード,격납고 감시장,Magazijnwachter,Lagervakt,Strażnik Magazynu,Guarda do Depósito,,Paznic Depozit,Охранник склада,,Lagervakt,Depo Görevlisi +Barkeep,TXT_SPEAKER_BARKEEP,,,,Barman,Bartender,Wirt,,Trinkejisto,Tabernero,Barman,Baarimikko,Barman,Bárpultos,Barman,バーテンダー,바텐더,Barman,Bartender,Barman,Taberneiro,,Barman,Хозяин таверны,,Bartender,Barmen +Timothy,TXT_SPEAKER_TIMOTHY,,,,,,,,,,,,,,,ティモシー,티모시,,,,,,Timotei,Тимоти,,,Timothy +James,TXT_SPEAKER_JAMES,,,,,,,,,,,,,,,ジェームス,제임스,,,,,,,Джеймс,,, +Worner,TXT_SPEAKER_WORNER,,,,,,,,,,,,,,,ワーナー,워너,,,,,,,Уорнэр,,, +Bailey Guard,TXT_SPEAKER_BAILEY_GUARD,,,,Stráž opevnění,Bailey-vagt,Vorhof-Wache,,,Guardia de la Muralla,,Ulkomuurinvartija,Garde d'enceinte,Várfal Őr,Guardia del Bastione,ベイリー ガード,외벽 파수병,,Borggården vakt,Strażnik Murów,Guarda da Fortaleza,,Gardian Bailey,Страж крепости,,Bailey-vakt,Dış avlu bekçisi +Drone,TXT_SPEAKER_DRONE,,,,Trubec,,Drohne,,,Dron,,Kuhnuri,,Drón,,労働者,노예,,,Dron,Zangão,,Dronă,Дрон,,Drönare, +Front Guard,TXT_SPEAKER_FRONT_GUARD,,,,Stráž Fronty,Front vagt,Frontwache,,,Guardia del Frente,,Rintaman vartija,Garde du Front,Front Őr,Guardia del Fronte,フロント ガード,프론트 파수꾼,Voorwacht,,Strażnik Frontu,Guarda da Frente,,Gandian Front,Повстанец,,Frontvakt,Ön Koruma +Quincy,TXT_SPEAKER_QUINCY,,,,,,,,,,,,,,,クインシー,퀸시,,,,,,,Куинси,,,Quincy +Sergeant,TXT_SPEAKER_SERGEANT,,,,Seržant,Sergent,Feldwebel,,,Sargento,,Kersantti,,Törzsőrmester,Sergente,軍曹,하사관,,Sersjant,Sierżant,Sargento,,Sergent,Сержант,,Sergeant,Çavuş +Temple Guard,TXT_SPEAKER_TEMPLE_GUARD,,,,Stráž chrámu,Tempelvagt,Tempelwache,,,Guardia del Templo,,Temppelinvartija,Garde du Temple,Templom Őr,Guardia del Tempio,テンプル ガード,신전 파수병,Tempelwacht,Tempelvakten,Strażnik Świątyni,Guarda do Templo,,Gardian Templu,Страж храма,,Tempelvakt,Tapınak Muhafızı +Oracle,TXT_SPEAKER_ORACLE,,,,Věštec,Orakel,Orakel,,Orakolo,Oráculo,,Oraakkeli,,Orákulum,Oracolo,オラクル,오라클,Orakel,Orakel,Wyrocznia,Oráculo,,Oracol,Оракул,,Orakel,Kahin +Ulaine,TXT_SPEAKER_ULAINE,,,,,,,,,,,,,,,ウレーヌ,울레인,,,,,,,Улейн,,,Ulane +Front Soldier,TXT_SPEAKER_FRONT_SOLDIER,,,,Voják Fronty,Frontsoldat,Front-Soldat,,,Soldado del Frente,,Rintaman sotilas,Soldat du Front,Front Katona,Soldato del Fronte,フロント ソルジャー,프론트 저항군,,Frontsoldat,Żołnierz Frontu,Soldado da Frente,,Soldat Front,Повстанец,,Frontsoldat,Ön Asker +Programmer,TXT_SPEAKER_PROGRAMMER,,,,Programátor,Programmør,Programmierer,,Programisto,Programador,,Ohjelmoitsija,Programmeur,Programozó,Programmatore,プログラマー,프로그래머,Programmeur,Programmerer,Programista,Programador,,Programator,Программист,,Programmerare,Programcı +Medic,TXT_SPEAKER_MEDIC,,,,Zdravotník,Læge,Sanitäter,,Kuracisto,Médico,,Lääkintämies,Médecin,Szanitéc,Medico,メディック,의무병,Paramedicus,Sanitetssoldat,Medyk,Médico,,,Медик,,Sjukvårdare, +Watchman,TXT_SPEAKER_WATCHMAN,,,,Hlídač,Vagtmand,Wächter,,,Celador,,Vahti,Vigie,Őrszem,Vigilante,警備員,감시병,Waker,Vaktmann,Stróż,Vigia,,Străjer,Караульный,,Väktare,Bekçi +Ketrick,TXT_SPEAKER_KETRICK,,,,,,,,,,,,,,,ケトリック,케트릭,,,,,,,Кетрик,,, +Weran,TXT_SPEAKER_WERAN,,,,,,,,,,,,,,,ウェラン,워렌,,,,,,,Уэран,,, +Advisor,TXT_SPEAKER_ADVISOR,,,,Rádce,Rådgiver,Berater,,,Consejero,,Neuvonantaja,Conseiller,Tanácsadó,Consigliere,補佐官,조언자,Adviseur,Rådgiver,Doradca,Conselheiro,,Sfetnic,Советник,,Rådgivare,Danışman +Geoff,TXT_SPEAKER_GEOFF,,,,,,,,,,,,,,,ジェフ,제프,,,,,,,Джефф,,,Geoff +Overseer,TXT_SPEAKER_OVERSEER,,,,Dozorčí,Tilsynsførende,Aufseher,,,Superintendente,,Valvoja,Superviseur,Munkavezető,Supervisore,監視人,현장 감독,Opziener,Oppsynsmann,Nadzorca,Supervisor,,Supraveghetor,Надсмотрщик,,Övervakare,Gözetmen Security Comple,TXT_SPEAKER_SECURITY_COMPLE,"Intended to appear in MAP19, but does not spawn. -",,,,Sikkerhedskomplet,Wache,,,Vigía,,Turvamies,Sécurité,,Guardia del Complesso di Sicurezza,,경비원,Bewaker,Security Comple,Ochroniarz Kompleksu,Vigia,,Paznic Complex de Securitate,Охранник комплекса,,Güvenlik Comple -Computer Tech,TXT_SPEAKER_COMPUTER_TECH,,,,Počítačový technik,,Computertechniker,,,Ingeniero Informático,,Tietokoneteknikko,Technicien Informatique,Számítógép Tech,Tecnico Informatico,機械技術者,컴퓨터 기술자,Computertechniek,Datatekniker,Technik Komputerowy,Técnico de Informática,,Tehnician Calculatoare,Компьютерный техник,,Bilgisayar Teknolojisi -MacGuffin,TXT_SPEAKER_MACGUFFIN,,,,,,,,,,,,,,,マクガフィン,맥거핀,,,,,,,Макгаффин,,MacGuffin -Arion,TXT_SPEAKER_ARION,,,,,,,,,,,,,,,アリオン,아리온,,,,,,,Арион,,Aron -Dock Worker,TXT_SPEAKER_DOCK_WORKER,,,,Přístavní dělník,Dokarbejder,Dockarbeiter,,,Trabajador del Muelle,,Ahtaaja,Docker,Dokk munkás,Operaio Portuale,港湾労働者,항구 일꾼,Dokwerker,Havnearbeider,Pracownik Doku,Operário da Doca,,Muncitor Docuri,Рабочий дока,,Liman İşçisi -Irale,TXT_SPEAKER_IRALE,,,,,,,,,,,,,,,イラール,이롤리,,,,,,,Ирэйл,,İrale -Core Guard,TXT_SPEAKER_CORE_GUARD,,,,Stráž jádra,Kernevagt,Wache,,,Guardia del Núcleo,,Ytimenvartija,Garde du cœur,Mag Őr,Guardia del Cuore,コア ガード,코어 경비병,Kernwacht,Kjernevakt,Strażnik Rdzenia,Guarda do Núcleo,,Gardian Nucleu,Страж ядра,,Çekirdek Koruma -Sewer Guard,TXT_SPEAKER_SEWER_GUARD,,,,Kanální stráž,Kloakvagt,Kanalisationswächter,,,Guardia de la Alcantarilla,,Viemärinvartija,Garde des égouts,Kanális Őr,Guardia della Fogna,下水道ガード,하수도 보초병,Rioolwacht,Kloakkvakt,Strażnik Kanałów,Guarda do Esgoto,,Gardian Canal,Страж канализации,,Kanalizasyon Görevlisi -Technician,TXT_SPEAKER_TECHNICIAN,,,,Technik,Tekniker,Techniker,,,Técnico,,Teknikko,Technicien,Technikus,Tecnico,技術者,기술자,Technicus,Tekniker,Technik,Técnico,,Tehnician,Техник,,Teknisyen -Guard,TXT_SPEAKER_GUARD,,,,Stráž,Vagt,Wache,,Gardisto,Guardia,,Vartija,Garde,Őr,Guardia,ガード,경비병,Bewaker,Vakt,Strażnik,Guarda,,Gardian,Стражник,,Muhafız -Peasant,TXT_SPEAKER_PEASANT,,,,Rolník,Bonde,Einwohner,,Kamparano,Campesino,,Maallikko,Paysan,Jobbágy,Cittadino,庶民,민간인,Boer,Bonde,Kmiot,Cidadão,,Sărman,Работник,,Köylü -Armorer,TXT_SPEAKER_ARMORER,,,Armourer,Kovář,Våbenmekaniker,Waffenmeister,,Armilisto,Armero,,Asemestari,Armurier,Fegyverkovács,Armiere,兵器係,병기공,Pantser,Væpner,Płatnerz,Forjador de Armaduras,,Armurier,Бронник,,Zırhçı -Beldin,TXT_SPEAKER_BELDIN,,,,,,,,,,,,,,,ベルディン,벨딘,,,,,,,Белдин,,Beldin -Gerard,TXT_SPEAKER_GERARD,,,,,,,,,,,,,,,ジェラルド,제랄드,,,,,,,Джерард,,Gerard -Governor Mourel,TXT_SPEAKER_GOVERNOR_MOUREL,,,,Guvernér Mourel,Guvernør Mourel,Gouverneur Mourel,,,Gobernador Mourel,,Kuvernööri Mourel,Gouverneur Mourel,Mourel kormányzó,Governatore Mourel,モーレル知事,모렐 총독,Gouverneur Mourel,Guvernør Mourel,Gubernator Mourel,Governador Mourel,,Guvernatorul Mourel,Губернатор Морел,,Vali Mourel -Bowyer,TXT_SPEAKER_BOWYER,,,,,,,,,,,,,,,ボウヤー,보여,,,,,,,Лучник,,Bowyer -Derwin,TXT_SPEAKER_DERWIN,,,,,,,,,,,,,,,ダーウィン,더윈,,,,,,,Дервин,,Derwin -,,Strife subtitles,,,,,,,,,,,,,,,,,,,,,,,, -The comet struck our planet without warning. We lost our paradise in a single violent stroke.,TXT_SUB_INTRO1,Menu's intro.,,,"Kometa bez varování narazila do naší planety. Jediným, brutálním úderem jsme přišli o náš ráj.",Kometen ramte vores planet uden varsel. Vi mistede vores paradis i et enkelt voldsomt slag.,Der Komet hat unsen Planeten ohne Vorwarnung getroffen. Wir haben unser Paradies in einem einzelnen brutalen Schlag verloren.,,,El cometa se estrelló en nuestro planeta sin previo aviso. Perdimos nuestro paraíso en un único y violento golpe.,,Komeetta iski planeettaamme varoittamatta. Menetimme paratiisimme rajulla kertarysäyksellä.,"La comète frappa notre monde sans prévenir. En un seul moment de violence, nous avons perdu notre paradis.",Egy üstökös csapódott be a bolygónkba minden előjel nélkül. Egy heves vágással elveszítettük az addigi paradicsomi életünket.,"La cometa colpì il nostro pianeta senza preavviso. Perdemmo il nostro paradiso, in un solo violento colpo.",彗星がこの星に突然衝突した。私達の楽園はこの一撃で失われた。,혜성 하나가 아무런 경고도 없이 우리 행성에 충돌했다. 그 강력한 한 방으로 우리의 낙원을 잃어버렸다.,De komeet raakte onze planeet zonder waarschuwing. We verloren ons paradijs in een enkele gewelddadige beroerte.,Kometen traff planeten vår uten forvarsel. Vi mistet paradiset vårt med ett voldsomt slag.,Kometa uderzyła w naszą planetę bez ostrzeżenia. Straciliśmy nasz raj w jednym gwałtownym uderzeniu.,"O cometa atingiu o nosso planeta sem aviso prévio. Num único e violento golpe, nós perdemos o nosso paraíso.",,Cometa ne-a izbit planeta în mod violent. Ne-am pierdut paradisul într-o clipă.,"Никто не ожидал, что на нашу планету обрушится метеорит. Земной рай был разрушен единственным безжалостным ударом.",,Kuyruklu yıldız gezegenimize uyarı vermeden çarptı. Cennetimizi tek bir şiddetli darbeyle kaybettik. +",,,,Sikkerhedskomplet,Wache,,,Vigía,,Turvamies,Sécurité,Védelmi Kvártély,Guardia del Complesso di Sicurezza,,경비원,Bewaker,Security Comple,Ochroniarz Kompleksu,Vigia,,Paznic Complex de Securitate,Охранник комплекса,,Säkerhetskompetens,Güvenlik Comple +Computer Tech,TXT_SPEAKER_COMPUTER_TECH,,,,Počítačový technik,,Computertechniker,,,Ingeniero Informático,,Tietokoneteknikko,Technicien Informatique,Számítógép Tech,Tecnico Informatico,機械技術者,컴퓨터 기술자,Computertechniek,Datatekniker,Technik Komputerowy,Técnico de Informática,,Tehnician Calculatoare,Компьютерный техник,,Datortekniker,Bilgisayar Teknolojisi +MacGuffin,TXT_SPEAKER_MACGUFFIN,,,,,,,,,,,,,,,マクガフィン,맥거핀,,,,,,,Макгаффин,,, +Arion,TXT_SPEAKER_ARION,,,,,,,,,,,,,,,アリオン,아리온,,,,,,,Арион,,,Aron +Dock Worker,TXT_SPEAKER_DOCK_WORKER,,,,Přístavní dělník,Dokarbejder,Dockarbeiter,,,Trabajador del Muelle,,Ahtaaja,Docker,Dokk munkás,Operaio Portuale,港湾労働者,항구 일꾼,Dokwerker,Havnearbeider,Pracownik Doku,Operário da Doca,,Muncitor Docuri,Рабочий дока,,Hamnarbetare,Liman İşçisi +Irale,TXT_SPEAKER_IRALE,,,,,,,,,,,,,,,イラール,이롤리,,,,,,,Ирэйл,,,İrale +Core Guard,TXT_SPEAKER_CORE_GUARD,,,,Stráž jádra,Kernevagt,Wache,,,Guardia del Núcleo,,Ytimenvartija,Garde du cœur,Mag Őr,Guardia del Cuore,コア ガード,코어 경비병,Kernwacht,Kjernevakt,Strażnik Rdzenia,Guarda do Núcleo,,Gardian Nucleu,Страж ядра,,Kärnvårdsvakt,Çekirdek Koruma +Sewer Guard,TXT_SPEAKER_SEWER_GUARD,,,,Kanální stráž,Kloakvagt,Kanalisationswächter,,,Guardia de la Alcantarilla,,Viemärinvartija,Garde des égouts,Kanális Őr,Guardia della Fogna,下水道ガード,하수도 보초병,Rioolwacht,Kloakkvakt,Strażnik Kanałów,Guarda do Esgoto,,Gardian Canal,Страж канализации,,Avloppsvakt,Kanalizasyon Görevlisi +Technician,TXT_SPEAKER_TECHNICIAN,,,,Technik,Tekniker,Techniker,,,Técnico,,Teknikko,Technicien,Technikus,Tecnico,技術者,기술자,Technicus,Tekniker,Technik,Técnico,,Tehnician,Техник,,Tekniker,Teknisyen +Guard,TXT_SPEAKER_GUARD,,,,Stráž,Vagt,Wache,,Gardisto,Guardia,,Vartija,Garde,Őr,Guardia,ガード,경비병,Bewaker,Vakt,Strażnik,Guarda,,Gardian,Стражник,,Väktare,Muhafız +Peasant,TXT_SPEAKER_PEASANT,,,,Rolník,Bonde,Einwohner,,Kamparano,Campesino,,Maallikko,Paysan,Jobbágy,Cittadino,庶民,민간인,Boer,Bonde,Kmiot,Cidadão,,Sărman,Работник,,Bonde,Köylü +Armorer,TXT_SPEAKER_ARMORER,,,Armourer,Kovář,Våbenmekaniker,Waffenmeister,,Armilisto,Armero,,Asemestari,Armurier,Fegyverkovács,Armiere,兵器係,병기공,Pantser,Væpner,Płatnerz,Forjador de Armaduras,,Armurier,Бронник,,Rusthållare,Zırhçı +Beldin,TXT_SPEAKER_BELDIN,,,,,,,,,,,,,,,ベルディン,벨딘,,,,,,,Белдин,,, +Gerard,TXT_SPEAKER_GERARD,,,,,,,,,,,,,,,ジェラルド,제랄드,,,,,,,Джерард,,, +Governor Mourel,TXT_SPEAKER_GOVERNOR_MOUREL,,,,Guvernér Mourel,Guvernør Mourel,Gouverneur Mourel,,,Gobernador Mourel,,Kuvernööri Mourel,Gouverneur Mourel,Mourel kormányzó,Governatore Mourel,モーレル知事,모렐 총독,Gouverneur Mourel,Guvernør Mourel,Gubernator Mourel,Governador Mourel,,Guvernatorul Mourel,Губернатор Морел,,Guvernör Mourel,Vali Mourel +Bowyer,TXT_SPEAKER_BOWYER,,,,,,,,,,,,,,,ボウヤー,보여,,,,,,,Лучник,,, +Derwin,TXT_SPEAKER_DERWIN,,,,,,,,,,,,,,,ダーウィン,더윈,,,,,,,Дервин,,, +,,Strife subtitles,,,,,,,,,,,,,,,,,,,,,,,,, +The comet struck our planet without warning. We lost our paradise in a single violent stroke.,TXT_SUB_INTRO1,Menu's intro.,,,"Kometa bez varování narazila do naší planety. Jediným, brutálním úderem jsme přišli o náš ráj.",Kometen ramte vores planet uden varsel. Vi mistede vores paradis i et enkelt voldsomt slag.,Der Komet hat unsen Planeten ohne Vorwarnung getroffen. Wir haben unser Paradies in einem einzelnen brutalen Schlag verloren.,,,El cometa se estrelló en nuestro planeta sin previo aviso. Perdimos nuestro paraíso en un único y violento golpe.,,Komeetta iski planeettaamme varoittamatta. Menetimme paratiisimme rajulla kertarysäyksellä.,"La comète frappa notre monde sans prévenir. En un seul moment de violence, nous avons perdu notre paradis.",Egy üstökös csapódott be a bolygónkba minden előjel nélkül. Egy heves vágással elveszítettük az addigi paradicsomi életünket.,"La cometa colpì il nostro pianeta senza preavviso. Perdemmo il nostro paradiso, in un solo violento colpo.",彗星がこの星に突然衝突した。私達の楽園はこの一撃で失われた。,혜성 하나가 아무런 경고도 없이 우리 행성에 충돌했다. 그 강력한 한 방으로 우리의 낙원을 잃어버렸다.,De komeet raakte onze planeet zonder waarschuwing. We verloren ons paradijs in een enkele gewelddadige beroerte.,Kometen traff planeten vår uten forvarsel. Vi mistet paradiset vårt med ett voldsomt slag.,Kometa uderzyła w naszą planetę bez ostrzeżenia. Straciliśmy nasz raj w jednym gwałtownym uderzeniu.,"O cometa atingiu o nosso planeta sem aviso prévio. Num único e violento golpe, nós perdemos o nosso paraíso.",,Cometa ne-a izbit planeta în mod violent. Ne-am pierdut paradisul într-o clipă.,"Никто не ожидал, что на нашу планету обрушится метеорит. Земной рай был разрушен единственным безжалостным ударом.",,Kometen träffade vår planet utan förvarning. Vi förlorade vårt paradis i ett enda våldsamt slag.,Kuyruklu yıldız gezegenimize uyarı vermeden çarptı. Cennetimizi tek bir şiddetli darbeyle kaybettik. "The impact released a virus, which swept through the land and killed millions. They turned out to be the lucky ones.",TXT_SUB_INTRO2,〃,,,"Náraz vypustil virus, který se začal šířit krajem a zabil miliony lidí. Ukázalo se, že to byli ti šťastnější.","Sammenstødet frigjorde en virus, som fejede gennem landet og dræbte millioner af mennesker. De viste sig at være de heldige.","Der Einschlag setzte einen Virus frei, der durch das Land fegte und Millionen tötete. Sie hatten Glück.",,,"El impacto liberó un virus, el cual barrió la tierra y mató a millones. Resultaron ser los más afortunados.",,"Törmäys päästi valloilleen viruksen, joka pyyhkäisi halki maan ja tappoi miljoonia. He osoittautuivat kuuluneensa onnekkaiden joukkoon.","L'impact libéra un virus, qui traversa les contrées et tua des millions. Ceux qui moururent furent les plus chanceux.","A becsapódás egy vírust eresztett a világra, mely milliókat ölt meg. Ők voltak a szerencsésebbek.","L'impatto rilasciò un virus, spargendosi ovunque e uccidendo milioni. Quelli che morirono furono i più fortunati.","彗星の衝突によりウィルスが世界中に放たれ、数えきれないほどの人々が死んだ。 -今から考えれば、彼らはまだ運がいい方だった。","충돌의 여파로 바이러스가 사방에 퍼졌고, 이로 인해 수백만명이 목숨을 잃었다. 죽은 자들은 운이 좋은 자들이었다.","Door de inslag kwam er een virus vrij, dat door het land veegde en miljoenen doden veroorzaakte. Zij bleken de gelukkigen te zijn.",Nedslaget utløste et virus som feide gjennom landet og drepte millioner. De viste seg å være de heldige.,"Uderzenie uwolniło wirusa, który przetoczył się przez ziemię i zabił miliony. Okazało się, że byli to ci, którzy mieli szczęście.","O impacto liberou um vírus, que se espalhou pela terra e matou milhões. Esses foram os que tiveram sorte.",,"Impactul a lansat un virus, care a măturat pământul și omorât milioane. Aparent ei au fost cei norocoși.","Удар метеорита выпустил вирус, который пронёсся по землям и истребил миллионы людей. Умершие оказались счастливчиками.",,Çarpışmanın etkisiyle bir virüs salındı ve bu virüs tüm dünyayı kasıp kavurarak milyonları öldürdü. Onlar şanslı olanlardı. +今から考えれば、彼らはまだ運がいい方だった。","충돌의 여파로 바이러스가 사방에 퍼졌고, 이로 인해 수백만명이 목숨을 잃었다. 죽은 자들은 운이 좋은 자들이었다.","Door de inslag kwam er een virus vrij, dat door het land veegde en miljoenen doden veroorzaakte. Zij bleken de gelukkigen te zijn.",Nedslaget utløste et virus som feide gjennom landet og drepte millioner. De viste seg å være de heldige.,"Uderzenie uwolniło wirusa, który przetoczył się przez ziemię i zabił miliony. Okazało się, że byli to ci, którzy mieli szczęście.","O impacto liberou um vírus, que se espalhou pela terra e matou milhões. Esses foram os que tiveram sorte.",,"Impactul a lansat un virus, care a măturat pământul și omorât milioane. Aparent ei au fost cei norocoși.","Удар метеорита выпустил вирус, который пронёсся по землям и истребил миллионы людей. Умершие оказались счастливчиками.",,Genom nedslaget frigjordes ett virus som svepte genom landet och dödade miljontals människor. De visade sig vara de lyckligt lottade.,Çarpışmanın etkisiyle bir virüs salındı ve bu virüs tüm dünyayı kasıp kavurarak milyonları öldürdü. Onlar şanslı olanlardı. "For those who did not die became mutations of humanity. Some became fanatics who heard the voice of a malignant god in their heads and called themselves ""the Order"".",TXT_SUB_INTRO3,〃,,,"Ti, kteří nezemřeli, se totiž stali lidskými mutanty. Někteří se proměnili ve fanatiky, kteří v hlavě začali slyšet hlas zlého boha, a začali si říkat „Řád“.","For de, der ikke døde, blev til mutationer af menneskeheden. Nogle blev fanatikere, der hørte en ondskabsfuld guds stemme i deres hoveder og kaldte sig selv ""Ordenen"".","Diejenigen, die nicht starben, wurden zu Mutanten der Menschheit. Einige wurden Fanatiker, die die Stimme eines bösartigen Gottes in ihrem Kopf hörten und sie nannten sich „Der Orden“.",,,"Ya que aquellos que no murieron se convirtieron en mutaciones de humanidad. Algunos se volvieron fanáticos que oían la voz de un dios maligno en sus cabezas y se hicieron llamar ""la Orden"".",,"Sillä niistä, jotka eivät kuolleet, tuli ihmiskunnan mutaatioita. Joistakin tuli kiihkoilijoita, jotka kuulivat päässään pahansuovan jumalan äänen ja kutsuivat itseään ""Veljeskunnaksi"".","Ceux qui survécurent devinrent les mutants de l'humanité. Certains devinrent des fanatiques qui écoutent la voix d'un dieu maléfique dans leur tête, et se nommèrent « L'Ordre ».","Akik nem haltak meg, emberi mutánsokká válltak. Voltak akik fanatikussá válltak, fejükbe hallották egy gonosz isten szavait, és a ""Rend"" néven hívták magukat.","Coloro che sopravvissero divennero i mutanti dell'umanità. Alcuni sono diventati fanatici che hanno ascoltato la voce di un dio malvagio nelle loro teste e si sono fatti chiamare ""L'Ordine"".","死ななかった人々は、人間から変異して別の物となった。 一部の人々は、頭の中に邪悪な神の声を伝えられた狂信者となり、 -自らの集団を'オーダー'と呼んだ。","죽지 않은 자들에겐 큰 변화가 일어났다. 몇몇은 머릿속으로 악독한 신의 목소리를 듣기 시작했고, 이 광신도들은 그들 자신을 “오더”라고 지칭했다.","Voor degenen die niet stierven werden mutaties van de mensheid. Sommigen werden fanatiekelingen die de stem van een kwaadaardige god in hun hoofd hoorden en zichzelf ""de Orde"" noemden.","For de som ikke døde, ble mutasjoner av menneskeheten. Noen ble fanatikere som hørte stemmen til en ondartet gud i hodet og kalte seg ""Ordenen"".","Ci bowiem, którzy nie zginęli, stali się mutacjami ludzkości. Niektórzy stali się fanatykami, którzy słyszeli w swoich głowach głos złośliwego boga i nazywali siebie ""Zakonem"".","Aqueles que sobreviveram se tornaram mutações de humanidade. Alguns se tornaram fanáticos que ouviam em suas cabeças a voz de um deus malígno e passaram a se chamar ""a Ordem"".",,"Pentru că cei care nu au murit au ajuns mutanți. Unii au devenit fanatici care au auzit vocea unui zeu perfid în capul lor și s-au numit ""Ordinul"".","Выжившие сформировали уродливое подобие прежнего общества. Некоторые услышали голос зловещего бога и стали фанатиками, называющими себя «Орденом».",,"Ölmeyenler ise insanlığın mutasyonları oldular. Bazıları kafalarının içinde kötücül bir tanrının sesini duyan ve kendilerine ""Düzen"" diyen fanatikler haline geldi." +自らの集団を'オーダー'と呼んだ。","죽지 않은 자들에겐 큰 변화가 일어났다. 몇몇은 머릿속으로 악독한 신의 목소리를 듣기 시작했고, 이 광신도들은 그들 자신을 “오더”라고 지칭했다.","Voor degenen die niet stierven werden mutaties van de mensheid. Sommigen werden fanatiekelingen die de stem van een kwaadaardige god in hun hoofd hoorden en zichzelf ""de Orde"" noemden.","For de som ikke døde, ble mutasjoner av menneskeheten. Noen ble fanatikere som hørte stemmen til en ondartet gud i hodet og kalte seg ""Ordenen"".","Ci bowiem, którzy nie zginęli, stali się mutacjami ludzkości. Niektórzy stali się fanatykami, którzy słyszeli w swoich głowach głos złośliwego boga i nazywali siebie ""Zakonem"".","Aqueles que sobreviveram se tornaram mutações de humanidade. Alguns se tornaram fanáticos que ouviam em suas cabeças a voz de um deus malígno e passaram a se chamar ""a Ordem"".",,"Pentru că cei care nu au murit au ajuns mutanți. Unii au devenit fanatici care au auzit vocea unui zeu perfid în capul lor și s-au numit ""Ordinul"".","Выжившие сформировали уродливое подобие прежнего общества. Некоторые услышали голос зловещего бога и стали фанатиками, называющими себя «Орденом».",,"För de som inte dog blev mutationer av mänskligheten. Några blev fanatiker som hörde en ondskefull guds röst i sina huvuden och kallade sig själva för ""Orden"".","Ölmeyenler ise insanlığın mutasyonları oldular. Bazıları kafalarının içinde kötücül bir tanrının sesini duyan ve kendilerine ""Düzen"" diyen fanatikler haline geldi." Those of us who are deaf to this voice suffer horribly and are forced to serve these ruthless psychotics who wield weapons more powerful than anything we can muster.,TXT_SUB_INTRO4,〃,,,"Ti z nás, kdo jsou vůči tomuto hlasu hluší, příšerně trpí a jsou nuceni sloužit těmto bezcitným šílencům, kteří vládnou zbraněmi, proti kterým nemáme šanci se bránit.","De af os, der er døve for denne stemme, lider forfærdeligt og er tvunget til at tjene disse hensynsløse psykopater, der svinger våben, der er stærkere end alt, hvad vi kan mønstre.","Jene, die dieser Stimme gegenüber taub sind, leiden schrecklich und sind gezwungen diesen unbarmherzigen Irren zu dienen. Sie haben Waffen die stärker sind als das, was wir aufbringen können.",,,Aquellos de nosotros sordos a esta voz sufrimos horriblemente y somos forzados a servir a estos psicópatas despiadados que poseen armas más poderosas que cualesquiera que podamos conseguir.,,"Meistä ne, jotka ovat kuuroja tälle äänelle, kärsivät valtavasti ja joutuvat palvelemaan näitä häikäilemättömiä sekopäitä, jotka pitävät hallussaan voimakkaampia aseita kuin me ikinä kykenemme käsiimme saamaan.",Ceux sourds à sa voix souffrent horriblement et sont forcés à vivre au services de ces vicieux psychopathes qui utilisent des armes plus puissantes que tout ce que nous avons.,"Azok akik nem hallják ezeket a hangokat megszenvedik azt, és arra vannak kárhoztatva, hogy ezeket az isten feletti fegyverekkel rendelkező kegyetlen elmebetegeket szolgálják.",Quelli sordi alla sua voce soffrono orribilmente e sono costretti a vivere al servizio di questi malvagi psicopatici che usano armi più potenti di ogni cosa che noi abbiamo.,"その神の声を聞き取れなかった私達は苦しんだ挙げ句、 この無慈悲な狂人どもに仕えるのを強いられた。 -そして奴等は、私達のどんな武器とも比べ物にならないほど強力な兵器を持っているのだ。","신의 목소리를 듣지 못하는 자들은 끔찍한 고통에 시달렸고, 우리가 가진 어떤 무기들보다 강력한 무장을 한 이 무자비한 광신도들을 강제로 섬기게 되었다.","Degenen onder ons die doof zijn voor deze stem lijden vreselijk en worden gedwongen om deze meedogenloze psychoten te dienen, die wapens gebruiken die krachtiger zijn dan alles wat we kunnen verzamelen.","De av oss som er døve for denne stemmen, lider forferdelig og er tvunget til å tjene disse hensynsløse psykotiske som bruker våpen som er kraftigere enn noe vi kan mønstre.","Ci z nas, którzy są głusi na ten głos, cierpią okropnie i są zmuszeni służyć tym bezwzględnym psychotom, którzy władają bronią potężniejszą niż wszystko, co jesteśmy w stanie zebrać.",Nós que não ouvimos essa voz sofremos terrívelmente e somos forçados a servir a esses psicopatas impiedosos que possuem armas mais poderosas do que qualquer coisa ao nosso alcance.,,Noi cei care suntem surzi și nu auzim vocea suferim oribil și suntem forțați să servin pe acești psihopați care cârmuie arme mai puternice decat orice avem.,"Другие — те, кто не слышал этого голоса, — терпели лишения. Их заставили прислуживать этим безжалостным психопатам, чьё оружие превосходило любое наше.",,Bu sese kulaklarını tıkayan bizler ise korkunç acılar çekiyor ve ellerinde toplayabileceğimiz her şeyden daha güçlü silahlar olan bu acımasız psikopatlara hizmet etmek zorunda kalıyoruz. +そして奴等は、私達のどんな武器とも比べ物にならないほど強力な兵器を持っているのだ。","신의 목소리를 듣지 못하는 자들은 끔찍한 고통에 시달렸고, 우리가 가진 어떤 무기들보다 강력한 무장을 한 이 무자비한 광신도들을 강제로 섬기게 되었다.","Degenen onder ons die doof zijn voor deze stem lijden vreselijk en worden gedwongen om deze meedogenloze psychoten te dienen, die wapens gebruiken die krachtiger zijn dan alles wat we kunnen verzamelen.","De av oss som er døve for denne stemmen, lider forferdelig og er tvunget til å tjene disse hensynsløse psykotiske som bruker våpen som er kraftigere enn noe vi kan mønstre.","Ci z nas, którzy są głusi na ten głos, cierpią okropnie i są zmuszeni służyć tym bezwzględnym psychotom, którzy władają bronią potężniejszą niż wszystko, co jesteśmy w stanie zebrać.",Nós que não ouvimos essa voz sofremos terrívelmente e somos forçados a servir a esses psicopatas impiedosos que possuem armas mais poderosas do que qualquer coisa ao nosso alcance.,,Noi cei care suntem surzi și nu auzim vocea suferim oribil și suntem forțați să servin pe acești psihopați care cârmuie arme mai puternice decat orice avem.,"Другие — те, кто не слышал этого голоса, — терпели лишения. Их заставили прислуживать этим безжалостным психопатам, чьё оружие превосходило любое наше.",,De av oss som är döva för denna röst lider fruktansvärt och tvingas tjäna dessa hänsynslösa psykopater som svingar vapen som är kraftfullare än allt vi kan uppbåda.,Bu sese kulaklarını tıkayan bizler ise korkunç acılar çekiyor ve ellerinde toplayabileceğimiz her şeyden daha güçlü silahlar olan bu acımasız psikopatlara hizmet etmek zorunda kalıyoruz. They destroy our women and children so that we must hide them underground and live like animals in constant fear for our lives.,TXT_SUB_INTRO5,〃,,,"Zabíjí naše ženy a děti, takže je musíme ukrývat v podzemí a nechávat je žít jako zvířata v neutrvajícím strachu o naše životy.","De ødelægger vores kvinder og børn, så vi må gemme dem under jorden og leve som dyr i konstant frygt for vores liv.","Sie zerstören unsere Frauen und Kinder, sodass wir uns im Untergrund verstecken müssen, wie die Tiere leben und ständig um unser Leben zu bangen.",,,Destruyen a nuestras mujeres y niños por lo que debemos esconderlos bajo tierra y vivir como animales temiendo constantemente por nuestras vidas.,,"He tuhoavat naisemme ja lapsemme, niin että joudumme kätkemään heidät maan alle ja elämään kuin elukat jatkuvassa pelossa henkemme puolesta.","Ils ont anéanti nos femmes et nos enfants et nous ont forcés à vivre sous terre comme des animaux, terrifiés de perdre nos vies.","Megölik a nőinket és gyermekeinket, ezért a föld alatt kell rejtegetnünk őket, és úgy kell élnünk mint az életét féltő állatoknak.","Distruggono le nostre donne e bambini, per cui li dobbiamo nascondere nel sottosuolo e vivere come animali in una paura costante per le nostre vite.","奴等は女性や子供を殺害していくため、私達はそういった人々を地下に隠さなければならなかった。 -我々は動物のように暮らすのを強いられ、命は常に危険に晒されている。","그들은 우리의 여자와 아이들을 죽였고, 우리는 살아남은 자들을 지하로 대피시켜 죽음의 공포 속에서 짐승처럼 살아가야 했다.",Ze vernietigen onze vrouwen en kinderen zodat we ze ondergronds moeten verbergen en als dieren moeten leven in voortdurende angst voor ons leven.,De ødelegger våre kvinner og barn slik at vi må gjemme dem under jorden og leve som dyr i konstant frykt for våre liv.,"Niszczą nasze kobiety i dzieci tak, że musimy ukrywać je pod ziemią i żyć jak zwierzęta w ciągłym strachu o nasze życie.","Eles destroem nossas mulheres e crianças e por isso nós temos que escondê-las no subterrâneo e viver como animais, temendo constantemente por nossas vidas.",,"Ne distrug femeile și copiii pentru ca noi să ne ascundem sub pământ și să trăim ca animalele, constant în teamă pentru virțiile noastre.","Они истребляют наших женщин и детей, и нам приходится прятать их в подземелье. Мы живём в постоянном страхе за свою жизнь, как животные.",,"Kadınlarımızı ve çocuklarımızı yok ediyorlar, böylece onları yeraltına saklamak ve hayatlarımız için sürekli korku içinde hayvanlar gibi yaşamak zorunda kalıyoruz." +我々は動物のように暮らすのを強いられ、命は常に危険に晒されている。","그들은 우리의 여자와 아이들을 죽였고, 우리는 살아남은 자들을 지하로 대피시켜 죽음의 공포 속에서 짐승처럼 살아가야 했다.",Ze vernietigen onze vrouwen en kinderen zodat we ze ondergronds moeten verbergen en als dieren moeten leven in voortdurende angst voor ons leven.,De ødelegger våre kvinner og barn slik at vi må gjemme dem under jorden og leve som dyr i konstant frykt for våre liv.,"Niszczą nasze kobiety i dzieci tak, że musimy ukrywać je pod ziemią i żyć jak zwierzęta w ciągłym strachu o nasze życie.","Eles destroem nossas mulheres e crianças e por isso nós temos que escondê-las no subterrâneo e viver como animais, temendo constantemente por nossas vidas.",,"Ne distrug femeile și copiii pentru ca noi să ne ascundem sub pământ și să trăim ca animalele, constant în teamă pentru virțiile noastre.","Они истребляют наших женщин и детей, и нам приходится прятать их в подземелье. Мы живём в постоянном страхе за свою жизнь, как животные.",,De förstör våra kvinnor och barn så att vi måste gömma dem under jorden och leva som djur i ständig rädsla för våra liv.,"Kadınlarımızı ve çocuklarımızı yok ediyorlar, böylece onları yeraltına saklamak ve hayatlarımız için sürekli korku içinde hayvanlar gibi yaşamak zorunda kalıyoruz." "But there are whispers of discontent. If we organize, can we defeat our masters? Weapons are being stolen, soldiers are being trained. A movement is born: born of lifelong strife!",TXT_SUB_INTRO6,〃,,,"Vynořují se však nesouhlasná šeptání. Pokud se seskupíme, můžeme porazit naše pány? Kradou se zbraně, cvičí se vojáci. Zrodilo se hnutí, zrozené z věčného sváru!","Men der er hvisken af utilfredshed. Hvis vi organiserer os, kan vi så besejre vores herrer? Våben bliver stjålet, soldater bliver uddannet. En bevægelse er født: født af livslange stridigheder!","Aber es gibt Zeichen der Unzufriedenheit. Wenn wir uns organisieren, können wir unsere Meister besiegen? Waffen werden gestohlen, Soldaten ausgebildet. Eine Bewegung wurde geboren: Geboren aus dem ewigen Konflikt!",,,"Pero hay susurros de descontento. Si nos organizamos, ¿podemos derrotar a nuestros maestros? Se están robando armas, se entrenan soldados. Un movimiento nace - ¡nacido de una lucha de por vida!",,"Mutta tyytymättömyyden äänet kuiskailevat. Jos järjestäydymme, kykenemmekö päihittämään valtiaamme? Aseita anastetaan, sotilaita koulutetaan. Liike on syntynyt, syntynyt elinikäisestä taistelusta!","Mais il y a des murmures de colère qui subsistent. Si nous nous organisons, pouvons nous nous défaire de nos maîtres? Des armes sont volées, des soldats entraînés. Un mouvement est né, né d'un combat sans fin!","Azonban zúgolódó sutyorgásokat hallani. Ha összefogunk vajon legyőzhetjük elnyomóinkat? Fegyvereket lopkodunk, katonákat képzünk. Egy mozgalom születik: az emberöltőnyi küzdelem születik!","Ma ci sono voci di discontento. Se ci organizzassimo, potremmo sconfiggere i nostri padroni? Vengono rubate le armi, vengono addestrati i soldati. È nato un movimento: nato da un eterno conflitto!","だが不満のささやきは常にある。もし私達が力を合わせれば、 支配者たちを倒すことができるだろうか? 奴等の武器は盗まれ続けていて、 我らの兵士たちは訓練され続けている。 -革命への動きは生まれたのだ- 終わりなき闘争(Strife)から!","그러나 불만의 목소리가 커졌다. 우리가 단결하면, 우리의 주인을 물리칠 수 있을까? 그들의 무기를 훔치고, 병사들을 훈련해서 우리의 평생을 바칠 투쟁이 시작된 것이다!","Maar er wordt gefluisterd van ontevredenheid. Als we ons organiseren, kunnen we dan onze meesters verslaan? Wapens worden gestolen, soldaten worden getraind. Een beweging is geboren: geboren uit levenslange strijd!","Men det hviskes om misnøye. Hvis vi organiserer oss, kan vi beseire våre herrer? Våpen blir stjålet, soldater blir trent. En bevegelse er født: født av livslang strid!","Ale są szepty niezadowolenia. Jeśli się zorganizujemy, czy uda nam się pokonać naszych panów? Broń jest kradziona, żołnierze są szkoleni. Rodzi się ruch: zrodzony z życiowej walki!","Mas há sussurros de descontentamento. Se nós nos organizarmos, será que podemos derrotar os nossos mestres? Armas estão sendo roubadas, soldados estão sendo treinados. Um movimento está nascendo. Nascendo por meio de um conflito sem fim!",,"Dar există șoapte ale neliniștii. Dacă ne organizam, am putea să ne înfrângem stăpânii? Armele sunt furate, soldații antrenați. O mișcare se naște: născută din suferința de o viață!","Но шёпот недовольства растёт. Сможем ли мы свергнуть их господство, если объединимся? Мы крадём их оружие, и наши бойцы проходят подготовку. Движение родилось — родилось из борьбы длиною в жизнь!",,"Ama hoşnutsuzluk fısıltıları var. Eğer örgütlenirsek, efendilerimizi yenebilir miyiz? Silahlar çalınıyor, askerler eğitiliyor. Bir hareket doğuyor: yaşam boyu süren mücadeleden doğuyor!" +革命への動きは生まれたのだ- 終わりなき闘争(Strife)から!","그러나 불만의 목소리가 커졌다. 우리가 단결하면, 우리의 주인을 물리칠 수 있을까? 그들의 무기를 훔치고, 병사들을 훈련해서 우리의 평생을 바칠 투쟁이 시작된 것이다!","Maar er wordt gefluisterd van ontevredenheid. Als we ons organiseren, kunnen we dan onze meesters verslaan? Wapens worden gestolen, soldaten worden getraind. Een beweging is geboren: geboren uit levenslange strijd!","Men det hviskes om misnøye. Hvis vi organiserer oss, kan vi beseire våre herrer? Våpen blir stjålet, soldater blir trent. En bevegelse er født: født av livslang strid!","Ale są szepty niezadowolenia. Jeśli się zorganizujemy, czy uda nam się pokonać naszych panów? Broń jest kradziona, żołnierze są szkoleni. Rodzi się ruch: zrodzony z życiowej walki!","Mas há sussurros de descontentamento. Se nós nos organizarmos, será que podemos derrotar os nossos mestres? Armas estão sendo roubadas, soldados estão sendo treinados. Um movimento está nascendo. Nascendo por meio de um conflito sem fim!",,"Dar există șoapte ale neliniștii. Dacă ne organizam, am putea să ne înfrângem stăpânii? Armele sunt furate, soldații antrenați. O mișcare se naște: născută din suferința de o viață!","Но шёпот недовольства растёт. Сможем ли мы свергнуть их господство, если объединимся? Мы крадём их оружие, и наши бойцы проходят подготовку. Движение родилось — родилось из борьбы длиною в жизнь!",,"Men det finns viskningar av missnöje. Om vi organiserar oss kan vi besegra våra herrar? Vapen stjäls, soldater utbildas. En rörelse är född: född av livslång strid!","Ama hoşnutsuzluk fısıltıları var. Eğer örgütlenirsek, efendilerimizi yenebilir miyiz? Silahlar çalınıyor, askerler eğitiliyor. Bir hareket doğuyor: yaşam boyu süren mücadeleden doğuyor!" "Attention, all troops of the Front: he's done it! It's over. Blackbird's soldier has killed the Evil. The Order is no more. Blackbird, do you read me?",TXT_SUB_GOOD1,,,,"Pozor, všechny jednotky Fronty: On to dokázal! Je konec. Straččin voják zabil Zlo. Řád už není. Strako, slyšíš mě?","Hør efter, alle fronttropper: Han har gjort det! Det er slut. Blackbird's soldat har dræbt Ondskaben. Ordenen er ikke mere. Blackbird, kan du høre mig?","Achtung, alle Truppen der Front: Er hat es getan! Es ist vorbei.Blackbirds Soldat hat das Böse vernichtet. Den Orden gibt es nicht mehr. Blackbird, kannst du mich hören?",,,"Atención, todas las tropas del Frente: ¡lo ha hecho! Se acabó. El soldado de Blackbird ha matado al Mal. Es el fin de la Orden. Blackbird, ¿me recibes?",,"Huomio, kaikki Rintaman joukot: Hän teki sen! Se on ohi; Blackbirdin sotilas on tappanut Pahan. Veljeskuntaa ei enää ole. Blackbird, kuuletko minua?","Attention à toutes les troupes du Front: Nous avons réussi! C'est fini, le soldat de Blackbird a anéanti le mal. L'Ordre est sur le point de s'effondrer. Blackbird, me recevez-vous?","Figyelem a Front összes katonájának: megcsinálta! Vége van. Feketerigó katonája megölte magát a gonoszt. A rend nincs többé. Feketerigó, veszed az adást?","Attenzione a tutte le truppe del Fronte: ce l'ha fatta! È finita. Il soldato di Blackbird ha ucciso il Male. L'Ordine non esiste più. Blackbird, mi senti?","フロントの兵士たちよ、聞きたまえ! 彼がすべてを終わらせたのだ。 もうこれで何もかも終わりだ。ブラックバードの兵士が悪を滅ぼしたのだ。 -オーダーはもう存在しない。ブラックバード、聞こえるか?","프론트의 모든 병사는 주목하라. 그가 해냈다! 모든 것이 끝났다. 블랙버드의 병사가 악을 물리치고, 오더는 끝장이 났다. 블랙버드, 내 말 듣고 있나?","Opgelet, alle troepen van het Front: hij heeft het gedaan! Het is voorbij. Blackbird's soldaat heeft het Kwaad gedood. De Orde is niet meer. Blackbird, hoort jou mij?","Oppmerksomhet, alle tropper fra fronten: han har gjort det! Det er over. Blackbirds soldat har drept Ondskapen. Ordenen eksisterer ikke lenger. Blackbird, hører du meg?","Uwaga, wszystkie oddziały Frontu: udało mu się! To już koniec. Żołnierz Blackbird zabił Zło. Nie ma już Zakonu. Blackbird, czy mnie słyszysz?","Atenção, todas as tropas da Frente: ele conseguiu! Está tudo acabado. O soldado de Blackbird matou o Mal. A Ordem não existe mais. Blackbird, consegue me ouvir?",,"Atenție, toate trupele Frontului: e gata! S-a terminat. Soldatul lui Blackbird a distrus Răul. Ordinul nu mai există. Blackbird, m-auzi?","Внимание, всем войскам Фронта! Он справился! Всё кончено! Солдат «Чёрного дрозда» покончил со злом! Ордена больше нет! «Чёрный дрозд», как слышите?",,"Cephe'nin tüm askerlerinin dikkatine: Başardı! Her şey bitti. Karabatak'ın askeri Şeytan'ı öldürdü. Tarikat artık yok. Karatavuk, beni duyuyor musun?" +オーダーはもう存在しない。ブラックバード、聞こえるか?","프론트의 모든 병사는 주목하라. 그가 해냈다! 모든 것이 끝났다. 블랙버드의 병사가 악을 물리치고, 오더는 끝장이 났다. 블랙버드, 내 말 듣고 있나?","Opgelet, alle troepen van het Front: hij heeft het gedaan! Het is voorbij. Blackbird's soldaat heeft het Kwaad gedood. De Orde is niet meer. Blackbird, hoort jou mij?","Oppmerksomhet, alle tropper fra fronten: han har gjort det! Det er over. Blackbirds soldat har drept Ondskapen. Ordenen eksisterer ikke lenger. Blackbird, hører du meg?","Uwaga, wszystkie oddziały Frontu: udało mu się! To już koniec. Żołnierz Blackbird zabił Zło. Nie ma już Zakonu. Blackbird, czy mnie słyszysz?","Atenção, todas as tropas da Frente: ele conseguiu! Está tudo acabado. O soldado de Blackbird matou o Mal. A Ordem não existe mais. Blackbird, consegue me ouvir?",,"Atenție, toate trupele Frontului: e gata! S-a terminat. Soldatul lui Blackbird a distrus Răul. Ordinul nu mai există. Blackbird, m-auzi?","Внимание, всем войскам Фронта! Он справился! Всё кончено! Солдат «Чёрного дрозда» покончил со злом! Ордена больше нет! «Чёрный дрозд», как слышите?",,"Lystring, alla fronttrupper: han har gjort det! Det är över. Blackbirds soldat har dödat ondskan. Orden finns inte längre. Blackbird, hör du mig?","Cephe'nin tüm askerlerinin dikkatine: Başardı! Her şey bitti. Karabatak'ın askeri Şeytan'ı öldürdü. Tarikat artık yok. Karatavuk, beni duyuyor musun?" "I knew you would win, my gallant hero. All fighting has stopped. Your victory will allow us to create a vaccine to purge the virus from our bodies.",TXT_SUB_GOOD2,,,,"Já věděla, že vyhraješ, můj statečný hrdino. Všechen boj ustal. Tvé vítězství nám umožní vyrobit vakcínu, která naše těla vyčistí od viru.","Jeg vidste, du ville vinde, min tapper helt. Alle kampe er stoppet. Din sejr vil give os mulighed for at skabe en vaccine, der kan rense vores kroppe for virussen.","Ich wusste, dass du gewinnen würdest, mein edler Held. Die Kämpfe haben aufgehört. Dein Sieg wird es uns erlauben einen Impfstoff herzustellen, mit dem wir den Virus in unseren Körper bekämpfen können.",,,"Sabía que ganarías, my valiente héroe. La lucha ha terminado. Tu victoria nos permitirá crear una vacuna para purgar el virus de nuestros cuerpos.",,"Tiesin, että voittaisit, uljas sankarini. Kaikki taistelu on tauonnut. Voittosi myötä meidän on mahdollista luoda rokote viruksen poistamiseksi kehoistamme.","Je savais que tu gagnerais, mon vaillant héros. Les combats ont cessé, ta victoire nous permettrera de créer un vaccin et purger le virus de nos corps.","Tudtam, hogy nyerni fogsz vitéz hősöm. Megszűntek a csaták. A győzelmed lehetővé fogja tenni, hogy egy vakcinával kiírtsuk a testünkből ezt a vírust.","Lo sapevo che potevi vincere, mio galante eroe. Tutto il combattimento è cessato. La tua vittoria ci consentirà di creare un vaccino per estirpare il virus dai nostri corpi.","あなたが勝つことは分かっていたわ、私の勇敢なヒーロー。 全ての戦いは終結した。あなたがもたらした勝利のおかげで、 -私達の体からウィルスを根絶するためのワクチンを作ることができる。","나의 용감한 영웅이 이길 줄 알았어. 모든 싸움이 끝이 났고, 당신의 승리 덕분에 우리 몸에 남은 바이러스를 퇴치할 백신을 만들 수 있을 거야.","Ik wist dat je zou winnen, mijn dappere held. Alle gevechten zijn gestopt. Uw overwinning zal ons in staat stellen om een vaccin te creëren om het virus uit ons lichaam te zuiveren.","Jeg visste at du ville vinne, min tapre helt. Alle kampene er over. Din seier vil tillate oss å lage en vaksine for å fjerne viruset fra kroppene våre.","Wiedziałem, że wygrasz, mój dzielny bohaterze. Wszystkie walki zostały przerwane. Twoje zwycięstwo pozwoli nam stworzyć szczepionkę, która usunie wirusa z naszych ciał.","Eu sabia que você conseguiria vencer, meu herói valente. Todo esse conflito chegou ao fim. Sua vitória nos permitirá que criemos uma vacina para eliminar o vírus de nossos corpos.",,"Știam că vei câștiga, eroul meu galant. Lupta a încetat. Vitoria ta ne permite să creăm un vaccin care va elimina virusul din corpul nostru.","Я знала, что ты победишь, мой отважный герой. Война окончена. Твоя победа позволила нам создать вакцину против вируса.",,"Kazanacağını biliyordum, benim cesur kahramanım. Tüm savaşlar durdu. Zaferin, virüsü vücutlarımızdan temizlemek için bir aşı yaratmamızı sağlayacak." +私達の体からウィルスを根絶するためのワクチンを作ることができる。","나의 용감한 영웅이 이길 줄 알았어. 모든 싸움이 끝이 났고, 당신의 승리 덕분에 우리 몸에 남은 바이러스를 퇴치할 백신을 만들 수 있을 거야.","Ik wist dat je zou winnen, mijn dappere held. Alle gevechten zijn gestopt. Uw overwinning zal ons in staat stellen om een vaccin te creëren om het virus uit ons lichaam te zuiveren.","Jeg visste at du ville vinne, min tapre helt. Alle kampene er over. Din seier vil tillate oss å lage en vaksine for å fjerne viruset fra kroppene våre.","Wiedziałem, że wygrasz, mój dzielny bohaterze. Wszystkie walki zostały przerwane. Twoje zwycięstwo pozwoli nam stworzyć szczepionkę, która usunie wirusa z naszych ciał.","Eu sabia que você conseguiria vencer, meu herói valente. Todo esse conflito chegou ao fim. Sua vitória nos permitirá que criemos uma vacina para eliminar o vírus de nossos corpos.",,"Știam că vei câștiga, eroul meu galant. Lupta a încetat. Vitoria ta ne permite să creăm un vaccin care va elimina virusul din corpul nostru.","Я знала, что ты победишь, мой отважный герой. Война окончена. Твоя победа позволила нам создать вакцину против вируса.",,"Jag visste att du skulle vinna, min tappre hjälte. Alla strider har upphört. Din seger kommer att göra det möjligt för oss att skapa ett vaccin för att rensa ut viruset från våra kroppar.","Kazanacağını biliyordum, benim cesur kahramanım. Tüm savaşlar durdu. Zaferin, virüsü vücutlarımızdan temizlemek için bir aşı yaratmamızı sağlayacak." "You have saved our planet and set us free. Now I'd like to thank you... personally. Oh, and by the way: the name is Shauna.",TXT_SUB_GOOD3,,,,Zachránil jsi naši planetu a osvobodil nás. Teď bych ti chtěla poděkovat... osobně. A mimochodem: Mé jméno je Shauna.,"Du har reddet vores planet og befriet os. Nu vil jeg gerne takke dig... personligt. Åh, og forresten: Navnet er Shauna.","Du hast unseren Planeten gerettet und uns befreit. Nun würde ich mich gerne bei dir bedanken... persönlich. Oh, so nebenbei: Mein Name ist Shauna.",,,"Has salvado nuestro planeta y nos has hecho libres. Ahora me gustaría agradecértelo... personalmente. Oh, y por cierto: mi nombre es Shauna.",,"Olet pelastanut planeettamme ja vapauttanut meidät. Tahtoisin nyt kiittää sinua... henkilökohtaisesti. Ja muuten, nimeni on Shauna.","Tu as sauvé notre planète et tu nous as tous libérés. Je veux te récompenser.. Personellement. Oh, et je m'appelle Shauna.","Megmentetted a bolygót, és felszabadítottál minket. Meg akarom ezt köszönni...személyesen. Ja, és a nevem Shauna.","Hai salvato il nostro pianeta e ci hai reso liberi. Ora vorrei ringraziarti ... di persona. Ah, comunque: mi chiamo Shauna.","あなたはこの星を救い、そして自由を取り戻した。さあ、 あなたにお礼をするときが来たわね、個人的な意味で... -ああ、それはそうと、私の本名はシャウナよ。","당신이 우리의 행성을 구하고 우리를 자유롭게 해줬어. 이제... 개인적으로 당신에게 감사하고 싶어. 아, 그리고... 내 이름은 샤나야.","Jullie hebben onze planeet gered en ons bevrijd. Nu wil ik je persoonlijk bedanken.... persoonlijk. Oh, en trouwens: de naam is Shauna.",Du har reddet planeten vår og satt oss fri. Nå vil jeg takke deg... personlig. Og forresten: navnet er Shauna.,"Uratowałeś naszą planetę i uwolniłeś nas. Teraz chciałbym ci podziękować... osobiście. Aha, i przy okazji: mam na imię Shauna.","Você salvou o nosso planeta e nos libertou. Agora, eu gostaria de te agradecer...pessoalmente. Ah, a propósito: meu nome é Shauna.",,"Ai salvat planeta și ne-ai eliberat. Aș vrea să îți mulțumesc, personal... Oh, și apropo: numele e Shauna.","Ты спас нашу планету и освободил нас. Так что я бы хотела поблагодарить тебя... лично. Кстати, меня зовут Шона.",,Gezegenimizi kurtardın ve bizi özgür bıraktın. Şimdi size şahsen teşekkür etmek istiyorum. Bu arada adım Shauna. +ああ、それはそうと、私の本名はシャウナよ。","당신이 우리의 행성을 구하고 우리를 자유롭게 해줬어. 이제... 개인적으로 당신에게 감사하고 싶어. 아, 그리고... 내 이름은 샤나야.","Jullie hebben onze planeet gered en ons bevrijd. Nu wil ik je persoonlijk bedanken.... persoonlijk. Oh, en trouwens: de naam is Shauna.",Du har reddet planeten vår og satt oss fri. Nå vil jeg takke deg... personlig. Og forresten: navnet er Shauna.,"Uratowałeś naszą planetę i uwolniłeś nas. Teraz chciałbym ci podziękować... osobiście. Aha, i przy okazji: mam na imię Shauna.","Você salvou o nosso planeta e nos libertou. Agora, eu gostaria de te agradecer...pessoalmente. Ah, a propósito: meu nome é Shauna.",,"Ai salvat planeta și ne-ai eliberat. Aș vrea să îți mulțumesc, personal... Oh, și apropo: numele e Shauna.","Ты спас нашу планету и освободил нас. Так что я бы хотела поблагодарить тебя... лично. Кстати, меня зовут Шона.",,"Du har räddat vår planet och befriat oss. Nu vill jag tacka dig... personligen. Åh, och förresten: namnet är Shauna.",Gezegenimizi kurtardın ve bizi özgür bıraktın. Şimdi size şahsen teşekkür etmek istiyorum. Bu arada adım Shauna. "Yes, the evil was gone, but our future was uncertain and clouded with doubt.",TXT_SUB_SAD1,,,,"Ano, zlo bylo pryč, ale naše budoucnost byla nejistá a zahalená pochybami.","Ja, ondskaben var væk, men vores fremtid var usikker og omgærdet af tvivl.","Ja, das Böse war fort, aber unsere Zukunft war ungewiss und von Zweifeln getrübt.",,,"Sí, el mal desapareció, pero nuestro futuro fue incierto y oscurecido por dudas.",,"Niin, paha oli kyllä mennyttä, mutta tulevaisuutemme oli epävarma ja hämärän peitossa.","Oui, le mal a disparu, mais notre futur reste incertain et le doute pèse sur nous.","Habár a gonosz eltávozott, a jövőnk mégis bizonytalan és ködös.","Si, il male fu sconfitto, ma il nostro futuro fu incerto e offuscato dal dubbio.","ええ、悪は消え去ったわ。だけども私達の未来は -まだ不安と疑念に満ちている。","그래, 악은 이제 사라졌어. 하지만 우리의 불확실한 앞날은 여전히 근심의 먹구름으로 가득 찼지.","Ja, het kwaad was weg, maar onze toekomst was onzeker en vertroebeld met twijfel.","Ja, ondskapen var borte, men fremtiden vår var usikker og full av tvil.","Tak, zło zniknęło, ale nasza przyszłość była niepewna i spowita wątpliwościami.","Sim, o mal se foi, mas o nosso futuro ainda era incerto e coberto de dúvidas.",,"Da, răul s-a dus dar viitorul nostru era în ceață și neclar.","Да, зло было повержено, но наше будущее было туманно и омрачено тенью сомнений...",,"Evet, kötülük gitmişti ama geleceğimiz belirsizdi ve şüpheyle doluydu." +まだ不安と疑念に満ちている。","그래, 악은 이제 사라졌어. 하지만 우리의 불확실한 앞날은 여전히 근심의 먹구름으로 가득 찼지.","Ja, het kwaad was weg, maar onze toekomst was onzeker en vertroebeld met twijfel.","Ja, ondskapen var borte, men fremtiden vår var usikker og full av tvil.","Tak, zło zniknęło, ale nasza przyszłość była niepewna i spowita wątpliwościami.","Sim, o mal se foi, mas o nosso futuro ainda era incerto e coberto de dúvidas.",,"Da, răul s-a dus dar viitorul nostru era în ceață și neclar.","Да, зло было повержено, но наше будущее было туманно и омрачено тенью сомнений...",,"Ja, ondskan var borta, men vår framtid var osäker och grumlad av tvivel.","Evet, kötülük gitmişti ama geleceğimiz belirsizdi ve şüpheyle doluydu." It would take generations to purge the virus from our people. If we survived that long.,TXT_SUB_SAD2,,,,"Trvalo by to věky, než bychom virus z našeho lidu vypudili. Pokud bychom tak dlouho přežili.",Det ville tage generationer at udrense virussen fra vores folk. Hvis vi overlevede så længe.,"Es würde Generationen dauern, bis wir unser Volk von dem Virus befreien können. Wenn wir so lange überleben...",,,Llevaría generaciones purgar el virus de nuestra gente. Si sobrevivieramos tanto tiempo.,,"Kestäisi sukupolvia hävittää virus keskuudestamme, jos selviäisimme niin pitkälle.","Il faudra des générations pour purger le virus de nos corps, si nous survivons suffisament longtemps.","Generációkba fog kerülni, hogy teljesen kiírtsuk a vírust. Márha élünk addig.",Ci sarebbero volute generazioni per eliminare il virus dalle nostre persone. Se fossimo sopravvissuti così a lungo.,"人間たちからウィルスを根絶するには、あと何世代もかかって -しまうはず。私達がそこまで生き延びられたとしても。",우리 몸속의 바이러스를 퇴치하려면 수 세대의 시간이 걸릴 거야. 우리가 그때까지 살아남는다면.,Het zou generaties vergen om het virus uit ons volk te zuiveren. Als we het zo lang zouden overleven.,Det ville ta generasjoner å fjerne viruset fra folket vårt. Hvis vi overlevde så lenge.,"Potrzeba było pokoleń, by oczyścić nasz lud z wirusa. Jeśli przeżyjemy tak długo.",Levaria gerações para eliminar o vírus de nosso povo. Se sobrevivessemos por todo esse tempo.,,Va dura generații până vom elimina virusul din oamenii noștri. Dacă vom trăi suficient.,"Десятилетия потребуются, чтобы исцелить наших людей от вируса... если нам удастся просуществовать так долго.",,Virüsü insanlarımızdan temizlemek nesiller alacaktı. Tabii o kadar uzun süre hayatta kalabilirsek. +しまうはず。私達がそこまで生き延びられたとしても。",우리 몸속의 바이러스를 퇴치하려면 수 세대의 시간이 걸릴 거야. 우리가 그때까지 살아남는다면.,Het zou generaties vergen om het virus uit ons volk te zuiveren. Als we het zo lang zouden overleven.,Det ville ta generasjoner å fjerne viruset fra folket vårt. Hvis vi overlevde så lenge.,"Potrzeba było pokoleń, by oczyścić nasz lud z wirusa. Jeśli przeżyjemy tak długo.",Levaria gerações para eliminar o vírus de nosso povo. Se sobrevivessemos por todo esse tempo.,,Va dura generații până vom elimina virusul din oamenii noștri. Dacă vom trăi suficient.,"Десятилетия потребуются, чтобы исцелить наших людей от вируса... если нам удастся просуществовать так долго.",,Det skulle ta generationer att rensa ut viruset från vårt folk. Om vi överlevde så länge.,Virüsü insanlarımızdan temizlemek nesiller alacaktı. Tabii o kadar uzun süre hayatta kalabilirsek. "Whatever the evil wanted, it drained from us the one thing we needed: it left us without hope.",TXT_SUB_SAD3,,,,"Ať chtělo zlo cokoliv, vysálo z nás tu jednu věc, kterou jsme potřebovali: Nechalo nás bez naděje.","Uanset hvad ondskaben ville, drænede den os for den eneste ting, vi havde brug for: den efterlod os uden håb.","Was auch immer das Böse wollte, es hat uns das genommen, was wir am meisten brauchten: Es hat uns ohne Hoffnung gelassen.",,,"Sea lo que sea que quisiera el mal, nos despojó de aquello que necesitábamos: nos dejó sin esperanza.",,"Mitä tahansa paha halusikaan, se riisti meiltä sen yhden ainoan asian, jota tarvitsimme: se jätti meidät ilman toivoa.","Quel que soit ce que le mal voulait de nous, il a tout de même pris la dernière chose qui nous restait: notre espoir.",A gonosz megkaparintotta amit akart: megfosztott minket a reményünktől.,"Qualunque cosa il male volesse, ci ha drenato dell'unica cosa di cui avevamo bisogno: ci ha lasciato senza speranza.","あの邪悪な存在が何を求めていたかはともかく、 -奴は人間たちから一番大切な物、希望を奪い去った。","악이 원한 것이 무엇이었든, 그들은 우리에게 필요한 한 가지를 뺏어갔어: 희망이라는 미래지...","Wat het kwaad ook wilde, het heeft ons datgene ontnomen wat we nodig hadden: het heeft ons zonder hoop achtergelaten.","Uansett hva ondskapen ville, tok den fra oss det eneste vi trengte: Den etterlot oss uten håp.","Cokolwiek chciało zło, wyssało z nas jedyną rzecz, której potrzebowaliśmy: pozostawiło nas bez nadziei.","Seja lá o que o mal queria, conseguiu tirar de nós algo que precisávamos: nossas esperanças.",,"Orice ar fi vrut răul, ne-a stors de ceea ce am avut cea mai mare nevoie: speranță.","Чего бы зло ни желало, оно отняло у нас то, в чём мы нуждались больше всего — оно лишило нас надежды.",,"Kötülük her ne istediyse, ihtiyacımız olan tek şeyi bizden çekip aldı: bizi umutsuz bıraktı." +奴は人間たちから一番大切な物、希望を奪い去った。","악이 원한 것이 무엇이었든, 그들은 우리에게 필요한 한 가지를 뺏어갔어: 희망이라는 미래지...","Wat het kwaad ook wilde, het heeft ons datgene ontnomen wat we nodig hadden: het heeft ons zonder hoop achtergelaten.","Uansett hva ondskapen ville, tok den fra oss det eneste vi trengte: Den etterlot oss uten håp.","Cokolwiek chciało zło, wyssało z nas jedyną rzecz, której potrzebowaliśmy: pozostawiło nas bez nadziei.","Seja lá o que o mal queria, conseguiu tirar de nós algo que precisávamos: nossas esperanças.",,"Orice ar fi vrut răul, ne-a stors de ceea ce am avut cea mai mare nevoie: speranță.","Чего бы зло ни желало, оно отняло у нас то, в чём мы нуждались больше всего — оно лишило нас надежды.",,Vad ondskan än ville så tog den från oss det enda vi behövde: den lämnade oss utan hopp.,"Kötülük her ne istediyse, ihtiyacımız olan tek şeyi bizden çekip aldı: bizi umutsuz bıraktı." "The sentient virus hit us like a tidal wave, driving us all mad. We heard the siren's song of death and we danced.",TXT_SUB_BAD1,,,,"Žijící virus nás ochromil jako povodeň, ze které jsme všichni zešíleli. Uslyšeli jsme siréninu píseň smrti a začali tančit.","Den følende virus ramte os som en flodbølge og drev os alle til vanvid. Vi hørte sirenens sang om døden, og vi dansede.",Der Virus traf uns wie eine Flutwelle und machte uns verrückt. Wir hörten den Sirenengesang des Todes - und wir tanzten.,,,"El virus consciente nos golpeó como una marea, volviéndonos a todos locos. Escuchamos la canción de sirena de la muerte y bailamos.",,Tietoinen virus iski meihin kuin hyökyaalto syösten meidät hulluuteen. Kuulimme seireenin kuoleman veisuun ja tanssimme sen tahtiin.,"Le virus devenu intelligent nous a emporté comme un tsunami, nous plongeant dans la folie. Entendant le doux chant de la mort, nous dancions en choeur.","A tudatára ébredt vírus hullámként verte le népünket és őrjített meg minket. Hallottuk a szirének tébolyító halál énekét, és táncolni kezdtünk.","Il virus intelligente ci ha colpito come uno tsunami, immergendoci nella follia. Sentimmo il canto delle sirene della morte, e ci misimo a ballare.","センティエント・ウィルスは私達を津波のように襲い、 全ての人間を狂気に陥れた。セイレーンの死の歌声を聞いたように -なり、死ぬまで踊り続けたのだ。","자각심을 가진 바이러스가 온 땅을 휩쓸었고, 우리 모두를 미치게 했다. 우리는 악이 들려주는 죽음의 노래에 맞춰 춤을 추었다.","Het virus met gevoel raakte ons als een vloedgolf, waardoor we allemaal gek werden. We hoorden het lied van de sirene van de dood en we dansten.",Det følende viruset traff oss som en flodbølge og gjorde oss alle gale. Vi hørte sirenenes dødssang og vi danset.,"Czujący wirus uderzył w nas jak fala pływowa, doprowadzając nas wszystkich do szaleństwa. Słyszeliśmy syreni śpiew śmierci i tańczyliśmy.","O vírus senciente nos atingiu como uma onda gigante, deixando todos nós loucos. Ouviamos a canção da morte da sirene e dançávamos.",,"Virusul viu ne-a lovit ca un val, făcându-ne să o luăm razna. Am auzit cântecul de moarte al sirenelor și am dansat.","Эпидемия захлестнула нас подобно гигантской волне, лишив рассудка каждого. Мы услышали сладкую песнь смерти и подчинились ей.",,Duyarlı virüs bizi bir gelgit dalgası gibi vurdu ve hepimizi delirtti. Sirenin ölüm şarkısını duyduk ve dans ettik. +なり、死ぬまで踊り続けたのだ。","자각심을 가진 바이러스가 온 땅을 휩쓸었고, 우리 모두를 미치게 했다. 우리는 악이 들려주는 죽음의 노래에 맞춰 춤을 추었다.","Het virus met gevoel raakte ons als een vloedgolf, waardoor we allemaal gek werden. We hoorden het lied van de sirene van de dood en we dansten.",Det følende viruset traff oss som en flodbølge og gjorde oss alle gale. Vi hørte sirenenes dødssang og vi danset.,"Czujący wirus uderzył w nas jak fala pływowa, doprowadzając nas wszystkich do szaleństwa. Słyszeliśmy syreni śpiew śmierci i tańczyliśmy.","O vírus senciente nos atingiu como uma onda gigante, deixando todos nós loucos. Ouviamos a canção da morte da sirene e dançávamos.",,"Virusul viu ne-a lovit ca un val, făcându-ne să o luăm razna. Am auzit cântecul de moarte al sirenelor și am dansat.","Эпидемия захлестнула нас подобно гигантской волне, лишив рассудка каждого. Мы услышали сладкую песнь смерти и подчинились ей.",,Det kännande viruset drabbade oss som en flodvåg och drev oss alla till vansinne. Vi hörde sirenens sång av döden och vi dansade.,Duyarlı virüs bizi bir gelgit dalgası gibi vurdu ve hepimizi delirtti. Sirenin ölüm şarkısını duyduk ve dans ettik. "This evil drained us of all human life and, scornful of procreation, recycled our families.",TXT_SUB_BAD2,,,,"Toto zlo z nás vysálo všechen život a, bez možnosti se rozmnožovat, vyhladilo naše rodiny.","Denne ondskab drænede os for alt menneskeligt liv, og foragtede for forplantning og genbrugte vores familier.",Das Böse entzog uns alles menschliche und als Verhöhnung der Fortpflanzung recycelte es unsere Familien.,,,"Este mal nos despojó de nuestra humanidad y despreciando la procreación, recicló nuestras familias.",,Paha imi meistä kaiken ihmiselämän ja lisääntymistä ylenkatsoen kierrätti perheemme.,"La mal nous a drainé de toute vie et haïssant toute procréation, recycla nos familles.","Ez a gonosz tömegével csapolta le az emberi életeket, és egyfajta gúnyos teremtőként újrahasznosította családainkat.","Questo male ci ha drenato di tutta la vita umana e, sprezzante della procreazione, riciclò le nostre famiglie.","この邪悪な存在は人間たちの命と繁殖能力を奪い去り、 -我々の家族を再利用した。","악은 우리에게서 인간적인 삶을 빼앗았고, 우리 인류를 유지해온 생식을 억제했다.","Dit kwaad heeft ons van alle mensenlevens ontdaan en, verachtelijk van voortplanting, onze families gerecycled.",Denne ondskapen tømte oss for alt menneskelig liv og resirkulerte familiene våre med forakt for forplantning.,"To zło pozbawiało nas wszelkiego ludzkiego życia, a gardząc prokreacją, utylizowało nasze rodziny.","O mal tirou de nós toda a vida humana e, deprezando a procriação, reciclou nossas famílias.",,"Acest rău ne-a stors de toată viața umană, detestând procreerea, reciclandu-ne familiile.","Зло истребляло в нас всё человеческое. Не задумываясь о завтрашнем дне, оно перерабатывало целые семьи.",,Bu kötülük bizi tüm insan yaşamından mahrum bıraktı ve üremeyi küçümseyerek ailelerimizi geri dönüştürdü. +我々の家族を再利用した。","악은 우리에게서 인간적인 삶을 빼앗았고, 우리 인류를 유지해온 생식을 억제했다.","Dit kwaad heeft ons van alle mensenlevens ontdaan en, verachtelijk van voortplanting, onze families gerecycled.",Denne ondskapen tømte oss for alt menneskelig liv og resirkulerte familiene våre med forakt for forplantning.,"To zło pozbawiało nas wszelkiego ludzkiego życia, a gardząc prokreacją, utylizowało nasze rodziny.","O mal tirou de nós toda a vida humana e, deprezando a procriação, reciclou nossas famílias.",,"Acest rău ne-a stors de toată viața umană, detestând procreerea, reciclandu-ne familiile.","Зло истребляло в нас всё человеческое. Не задумываясь о завтрашнем дне, оно перерабатывало целые семьи.",,"Denna ondska tömde oss på allt mänskligt liv och, med förakt för fortplantning, återanvände våra familjer.",Bu kötülük bizi tüm insan yaşamından mahrum bıraktı ve üremeyi küçümseyerek ailelerimizi geri dönüştürdü. "Then one day, the evil left. There was simply nothing for it to feed on. We were extinct.",TXT_SUB_BAD3,,,,"A pak, jednoho dne, zlo odešlo. Nemělo se prostě už na čem pást. Vyhynuli jsme.",Så en dag forlod ondskaben os. Der var simpelthen ikke noget for den at spise. Vi var uddøde.,"Dann, eines Tages, war das Böse fort. Es war nichts mehr da, wovon es zehren konnte. Wir waren ausgestorben.",,,"Entonces un día, el mal se fue. Simplemente no quedaba nada con que alimentarse. Nos extinguimos.",,"Sitten eräänä päivänä paha kaikkosi; mitään yksinkertaisesti ei enää ollut, mistä elää. Olimme kuolleet sukupuuttoon.","Puis, un jour, le mal disparut. Il ne restait plus rien d'utile pour lui, nous nous sommes éteints.",Egy napon a gonosz eltűnt. Nem tudott már min táplálkozni. Kipusztultunk.,"Così un giorno, il male se ne andò. Semplicemente non rimase nulla su cui cibarsi. Noi siamo estinti.","そしてある時、邪悪な存在はこの星を後にした。単に、 -奴の糧となる者が一人もいなくなったからだ。我々は滅びたのだ。","그리고 어느 날, 악은 사라졌다. 그들에게 먹을 것이 없었기 때문이다. 우리들이 멸종했기에...",Op een dag vertrok het kwaad. Er was gewoonweg niets om zich op te voeden. We waren uitgestorven.,Så en dag forsvant ondskapen. Det fantes rett og slett ikke noe å livnære seg på. Vi var utryddet.,"Pewnego dnia, zło odeszło. Nie było nic, czym mogłoby się żywić. Wyginęliśmy.","E então um dia, o mal foi embora. Não sobrou mais nada para ele consumir. Estávamos extintos.",,"Apoi, într-o zi, răul a plecat. Pur și simplu nu a mai rămas nimic din care să se hrănească. Eram dispăruți.","Настал день, когда зло ушло. Не осталось ничего, чем оно могло бы питаться. Мы вымерли.",,"Sonra bir gün, kötülük gitti. Beslenebileceği hiçbir şey kalmamıştı. Neslimiz tükenmişti." +奴の糧となる者が一人もいなくなったからだ。我々は滅びたのだ。","그리고 어느 날, 악은 사라졌다. 그들에게 먹을 것이 없었기 때문이다. 우리들이 멸종했기에...",Op een dag vertrok het kwaad. Er was gewoonweg niets om zich op te voeden. We waren uitgestorven.,Så en dag forsvant ondskapen. Det fantes rett og slett ikke noe å livnære seg på. Vi var utryddet.,"Pewnego dnia, zło odeszło. Nie było nic, czym mogłoby się żywić. Wyginęliśmy.","E então um dia, o mal foi embora. Não sobrou mais nada para ele consumir. Estávamos extintos.",,"Apoi, într-o zi, răul a plecat. Pur și simplu nu a mai rămas nimic din care să se hrănească. Eram dispăruți.","Настал день, когда зло ушло. Не осталось ничего, чем оно могло бы питаться. Мы вымерли.",,En dag lämnade ondskan oss. Det fanns helt enkelt ingenting för den att livnära sig på. Vi var utdöda.,"Sonra bir gün, kötülük gitti. Beslenebileceği hiçbir şey kalmamıştı. Neslimiz tükenmişti." "The genetic mutations caused by the virus not only warped the psyches of the Order, but caused their bodies to decay.",TXT_SUB_MAP03_1,MAP03: After destroying the gate controls.,,,"Genetické mutace způsobené virem nejenže pokřivily mysli Řádu, ale také způsobily rozklad jejich těl.","De genetiske mutationer forårsaget af virussen forvrængede ikke kun ordensmændenes psyke, men fik også deres kroppe til at forfalde.","Die genetischen Mutationen, die durch den Virus verursacht wurden, haben nicht nur die Psyche des Ordens beeinflusst, sondern brachten auch ihre Körper zum Verfallen.",,,"Las mutaciones genéticas causadas por el virus no solo retorcieron las mentes de la Orden, sino que también causaron el deterioro de sus cuerpos.",,Viruksen aiheuttamat geneettiset mutaatiot eivät vain vääristäneet Veljeskunnan mieliä vaan myös rappeuttivat heidän ruumiitaan.,"Les mutations géntiques du virus ont non seulement tordu l'esprit de L'Ordre, mais a aussi rendu leur corps invivables.","A vírus genetikai mutációi nem csak a Rend tagjainak elméjét rontotta meg, de testüket is bomlásnak indította.","Le mutazioni genetiche causate dal virus non solo turbavano la psiche dei seguaci dell'Ordine, ma portava i loro corpi a decomporre.","ウィルスからもたらされた遺伝子変異はオーダーの者たちの精神だけではなく、 -肉体すらも蝕んだ。","바이러스로 인한 유전적 변화는 오더의 광신도들을 만들었을 뿐만 아니라, 그들의 육신을 썩어 문드러지게 했습니다.","De genetische mutaties die door het virus werden veroorzaakt, vervormden niet alleen de psyche van de Orde, maar veroorzaakten ook het verval van hun lichaam.","De genetiske mutasjonene forårsaket av viruset forvrengte ikke bare ordenens psyke, men fikk kroppene deres til å forfalle.","Mutacje genetyczne spowodowane przez wirusa nie tylko wypaczyły psychikę Zakonu, ale spowodowały rozkład ich ciał.","As mutações genéticas causadas pelo vírus não somente distorceu as mentes da Ordem, mas também deterioraram nossos corpos.",,"Mutațiile genetice nu numai că au sucit psihicul Ordinului, dar le-a făcut corpul să se deterioreze.","Генетические мутации, которые возникали из-за вируса, не только извращали психику членов Ордена, но и вызывали гниение их тел.",,"Virüsün neden olduğu genetik mutasyonlar sadece Tarikat'ın psikolojisini bozmakla kalmadı, aynı zamanda bedenlerinin de çürümesine neden oldu." +肉体すらも蝕んだ。","바이러스로 인한 유전적 변화는 오더의 광신도들을 만들었을 뿐만 아니라, 그들의 육신을 썩어 문드러지게 했습니다.","De genetische mutaties die door het virus werden veroorzaakt, vervormden niet alleen de psyche van de Orde, maar veroorzaakten ook het verval van hun lichaam.","De genetiske mutasjonene forårsaket av viruset forvrengte ikke bare ordenens psyke, men fikk kroppene deres til å forfalle.","Mutacje genetyczne spowodowane przez wirusa nie tylko wypaczyły psychikę Zakonu, ale spowodowały rozkład ich ciał.","As mutações genéticas causadas pelo vírus não somente distorceu as mentes da Ordem, mas também deterioraram nossos corpos.",,"Mutațiile genetice nu numai că au sucit psihicul Ordinului, dar le-a făcut corpul să se deterioreze.","Генетические мутации, которые возникали из-за вируса, не только извращали психику членов Ордена, но и вызывали гниение их тел.",,"De genetiska mutationer som viruset orsakade förvrängde inte bara ordens psykiska tillstånd, utan fick deras kroppar att förfalla.","Virüsün neden olduğu genetik mutasyonlar sadece Tarikat'ın psikolojisini bozmakla kalmadı, aynı zamanda bedenlerinin de çürümesine neden oldu." "Without procreation, the Order found that biomechanical enhancements were the only way to maintain their strengths and numbers.",TXT_SUB_MAP03_2,〃,,,"Řádu došlo, že bez rozmnožování jsou biomechanická vylepšení jediná možnost, jak zachovat své počty a sílu.","Uden forplantning fandt Ordenen ud af, at biomekaniske forbedringer var den eneste måde at bevare deres styrke og antal på.","Ohne die Möglichkeit der Fortpflanzung fand der Orden heraus, dass biomechanische Erweiterungen der einzige Weg waren, um ihre Kräfe und eine hohe Anzahl beizubehalten.",,,"Sin procreación, la Orden se encontró con que las mejoras biomecánicas eran la única forma de mantener sus fuerzas y números.",,Ilman lisääntymistä Veljeskunta katsoi biomekaanisen parantelun ainoaksi tavakseen ylläpitää vahvuuttaan.,"Sans procréation, l'Ordre découvrirent que les modifications bioméchaniques était leur seule chance de conserver leur force et leur nombre.",A szaporodás nélkül a Rendnek csak egyetlen esélye volt az erejük és számuk megtartására: a biomechanikus testi tuningolás.,"Senza la procreazione, l'Ordine trovò che gli apparati biomeccanici erano l'unico modo per mantenere la loro forza e i loro numeri.","繁殖行為という選択肢がないオーダーは、 -彼らのパワーと数を保つには生体工学による人体改造しかないと判断したのだ。","생식능력이 사라지자, 오더에게 남은 존속 방법은 생체에 기계를 접목한 기술을 발전시키는 것 뿐이었죠.","Zonder voortplanting, vond de Orde dat biomechanische verbeteringen de enige manier waren om hun sterke punten en aantallen te behouden.",Uten forplantning fant ordenen ut at biomekaniske forbedringer var den eneste måten å opprettholde sin styrke og antall på.,"Bez prokreacji Zakon odkrył, że biomechaniczne ulepszenia są jedynym sposobem na utrzymanie siły i liczebności.","Sem procriação, a Ordem descobriu que as modificações biomecânicas eram a única maneira de manter sua força e seus números.",,"Fără procreere, Ordinul a descoperit că îmbunătățirile lor bio-mecanice erau tot ce îi ținea.","Орден обнаружил, что биомеханические улучшения — единственный способ поддержания их численного превосходства при отсутствии деторождения.",,"Üreme olmadan, Düzen güçlerini ve sayılarını korumanın tek yolunun biyomekanik geliştirmeler olduğunu gördü." +彼らのパワーと数を保つには生体工学による人体改造しかないと判断したのだ。","생식능력이 사라지자, 오더에게 남은 존속 방법은 생체에 기계를 접목한 기술을 발전시키는 것 뿐이었죠.","Zonder voortplanting, vond de Orde dat biomechanische verbeteringen de enige manier waren om hun sterke punten en aantallen te behouden.",Uten forplantning fant ordenen ut at biomekaniske forbedringer var den eneste måten å opprettholde sin styrke og antall på.,"Bez prokreacji Zakon odkrył, że biomechaniczne ulepszenia są jedynym sposobem na utrzymanie siły i liczebności.","Sem procriação, a Ordem descobriu que as modificações biomecânicas eram a única maneira de manter sua força e seus números.",,"Fără procreere, Ordinul a descoperit că îmbunătățirile lor bio-mecanice erau tot ce îi ținea.","Орден обнаружил, что биомеханические улучшения — единственный способ поддержания их численного превосходства при отсутствии деторождения.",,Utan fortplantning fann orden att biomekaniska förbättringar var det enda sättet att behålla sin styrka och sitt antal.,"Üreme olmadan, Düzen güçlerini ve sayılarını korumanın tek yolunun biyomekanik geliştirmeler olduğunu gördü." The decay has advanced so that most of the troops we face are more machine than man but we believe that their collective consciousness is controlled by one source...,TXT_SUB_MAP03_3,〃,,,"Rozklad pokročil tak daleko, že většina nepřátel, kterým čelíme, jsou spíše stroje než lidé, ale věříme, že jejich kolektivní vědomí je řízené z jednoho zdroje...","Forfaldet er fremskredet, så de fleste af de tropper, vi står over for, er mere maskiner end mennesker, men vi tror, at deres kollektive bevidsthed styres af én kilde...","Der Verfall ist so weit fortgeschritten, dass die meisten Truppen, denen wir begegnen mehr Maschine als Mensch sind, aber wir glauben, dass ihr kollektives Bewusstsein von einer Quelle kontrolliert wird...",,,El deterioro ha avanzado tanto que la mayoría de tropas a las que nos enfrentamos son más máquina que hombre pero creemos que su consciencia colectiva es controlada por una única fuente...,,"Rappeutuminen on edennyt niin pitkälle, että suurin osa kohtaamistamme joukoista on enemmän koneita kuin ihmisiä, mutta me uskomme, että heidän yhteistä tietoisuuttaan ohjaa yksi lähde...","Les dégradations étaient si avancées que les troupes auxquelles nous faisions face étaient plus machine qu'humains, mais nous pensons que leur conscience collective est contrôlée par une seule source..","A bomlás annyira előrehaladott, hogy a harctéren látott egységek nagyobb részben robotok mint emberek, de úgy gondoljuk hogy az elméjüket egy központi tudat irányítja...","La decomposizione è avanzata a tal punto che molte delle truppe che vediamo sono più macchine che uomini, ma noi crediamo che la loro coscienza collettiva sia controllata da un'unica fonte...","彼らの肉体へのダメージは深刻で、我らが遭遇した兵士たちは人間と言うよりは もはや機械に近いと言える。だが、彼らの集合意識はたった一人によってコントロールされていると -我々は考えている。","부패가 많이 진행되었기에 우리는 사람보다 기계에 가까운 적들과 싸웠고, 우리는 그들의 집단의식이 어떤 하나의 존재가 통제하는 것이라고 생각하고 있습니다...","Het verval is zo ver gevorderd dat de meeste van de troepen die we tegenkomen meer machine zijn dan de mens, maar we geloven dat hun collectieve bewustzijn wordt gecontroleerd door één bron....","Forfallet har gått så langt at de fleste av troppene vi står overfor er mer maskin enn menneske, men vi tror at deres kollektive bevissthet styres av én kilde...","Rozkład postępuje tak, że większość oddziałów, z którymi mamy do czynienia, to bardziej maszyny niż ludzie, ale wierzymy, że ich zbiorowa świadomość jest kontrolowana przez jedno źródło...",A deterioração avançou de tal forma que a maioria dos soldados que enfrentamos são mais máquina do que humano. Mas acreditamos que a consciência coletiva deles é controlada por uma só fonte... ,,Deteriorarea a avansat în așa fel încăt majoritatea soldațiilor pe care îi înfruntăm să fie mai mult mașini decât oameni dar credem că subconștientul lor colectiv e controlat de o singură sursă...,"Гниение распространялось, поэтому большинство их солдат скорее машины, чем люди. Но мы полагаем, что их коллективное сознание управляется из единого центра...",,"Çürüme o kadar ilerledi ki, karşılaştığımız birliklerin çoğu insandan çok makine ama biz onların kolektif bilincinin tek bir kaynak tarafından kontrol edildiğine inanıyoruz..." +我々は考えている。","부패가 많이 진행되었기에 우리는 사람보다 기계에 가까운 적들과 싸웠고, 우리는 그들의 집단의식이 어떤 하나의 존재가 통제하는 것이라고 생각하고 있습니다...","Het verval is zo ver gevorderd dat de meeste van de troepen die we tegenkomen meer machine zijn dan de mens, maar we geloven dat hun collectieve bewustzijn wordt gecontroleerd door één bron....","Forfallet har gått så langt at de fleste av troppene vi står overfor er mer maskin enn menneske, men vi tror at deres kollektive bevissthet styres av én kilde...","Rozkład postępuje tak, że większość oddziałów, z którymi mamy do czynienia, to bardziej maszyny niż ludzie, ale wierzymy, że ich zbiorowa świadomość jest kontrolowana przez jedno źródło...",A deterioração avançou de tal forma que a maioria dos soldados que enfrentamos são mais máquina do que humano. Mas acreditamos que a consciência coletiva deles é controlada por uma só fonte... ,,Deteriorarea a avansat în așa fel încăt majoritatea soldațiilor pe care îi înfruntăm să fie mai mult mașini decât oameni dar credem că subconștientul lor colectiv e controlat de o singură sursă...,"Гниение распространялось, поэтому большинство их солдат скорее машины, чем люди. Но мы полагаем, что их коллективное сознание управляется из единого центра...",,"Förfallet har gått framåt så att de flesta av de trupper vi möter är mer maskiner än människor, men vi tror att deras kollektiva medvetande styrs av en enda källa...","Çürüme o kadar ilerledi ki, karşılaştığımız birliklerin çoğu insandan çok makine ama biz onların kolektif bilincinin tek bir kaynak tarafından kontrol edildiğine inanıyoruz..." "...the Programmer: creator of the AI which controls the Acolytes. Destroy the Programmer, and we may cripple the Order's troops with a single blow. But caution: we have reports he can vaporize attackers.",TXT_SUB_MAP03_4,〃,,,"...Programátor: tvůrce umělé inteligence, která ovládá akolyty. Znič Programátora a dost možná zasadíme vojskům Řádu mocnou ránu. Ale buď opatrný: Máme zprávy, že umí nechat své útočníky vypařit.","...programmøren: Skaberen af den AI, der styrer akolytterne. Hvis vi ødelægger programmøren, kan vi lamme ordenens tropper med et enkelt slag. Men pas på: Vi har rapporter om, at han kan fordampe angribere.","...der Programmierer: Entwickler der KI, die die Ministranten kontrolliert. Vernichte den Programmierer, und wir könnten die Truppen des Ordens mit einem einzigen Schlag lahmlegen. Aber sieh dich vor. Wir haben Meldungen, dass er Angreifer vaporisieren kann.",,,... el Programador - creador de la IA que controla a los Acólitos. Destruye al Programador y podremos herir a las tropas de la Orden de un solo golpe. Pero cuidado: tenemos informes de que puede vaporizar a atacantes.,,"Ohjelmoitsija: akoluutteja ohjaavan tekoälyn luoja. Tuhoa Ohjelmoitsija, ja saatamme rampauttaa Veljeskunnan joukot yhdellä iskulla. Mutta ole varovainen: tietojemme mukaan hän kykenee haihduttamaan vastustajansa.",Le Programmeur: Créateur de l'IA qui contrôle les Acolytes. Détruisez le Programmeur et nous pourrons paralyser les troupes de l'Ordre d'un seul coup. Faites attentions: des rapports nous disent qu'il peut vaporiser ceux qui l'attaquent.,...maga a Programozó: a ministránsokat irányító MI megalkotója. A Programozót megölve megbéníthatjuk a Rend seregét egy csapással. Azonban vigyázz: a jelentések szerint instant el tudja porlasztani támadóit.,"...il Programmatore: creatore dell'Intelligenza Artificiale che controlla gli Accoliti. Distruggi il Programmatore, e noi potremmo rendere inefficienti i soldati dell'Ordine con un colpo solo. Ma attento: i nostri rapporti indicano che può vaporizzare gli aggressori.","その者の名はプログラマーだ。 彼はアコライト達を操作している人工知能の作成者だ。 プログラマーを殺害すれば、それによってオーダーの兵士たちを無力化できるはずだ。 -だが気をつけておけ、ヤツは熱で敵を蒸発させられるとの報告があるからな。","... 프로그래머: 아콜라이트들을 통제하는 인공지능의 창조자 말입니다. 그를 파괴하면 일격으로 오더의 군대를 무력화시킬 수 있을 겁니다. 하지만 조심하세요, 보고에 의하면 그는 자기 상대를 가루로 만들어 버린다는군요.","...de programmeur: maker van de AI die de Acolieten bestuurt. Vernietig de programmeur, en we kunnen de troepen van de Orde met een enkele klap verlammen. Maar opgelet: we hebben meldingen dat hij aanvallers kan verdampen.","...programmereren: skaperen av AI-en som kontrollerer akolyttene. Ødelegger vi Programmereren, kan vi lamme Ordenens tropper med ett slag. Men forsiktighet: Vi har rapporter om at han kan pulverisere angripere.","...Programista: twórca SI, która kontroluje Akolitów. Zniszcz Programistę, a możemy sparaliżować wojska Zakonu jednym uderzeniem. Ale uwaga: mamy doniesienia, że potrafi on wyparować napastników.","...o Programador: o criador da inteligência artificial que controla os Acólitos. Destrua o programador e, assim, poderemos prejudicar as tropas da Ordem com um único golpe. Mas cuidado: temos relatos de que ele pode vaporizar aqueles que atacam.",,"...Programatorul: creatorul inteligenței artificiale care controlează Acoliții. Distruge-l, și vom nimicii trupele Ordinului cu o singură lovitură: avem rapoarte care spun că poate vaporiza atacatorii.","...Программистом — создателем ИИ, контролирующего служителей. Уничтожь Программиста, и мы разделаемся с войсками Ордена одним ударом. Но осторожнее — нам докладывали, что он умеет... испепелять нападающих.",,"...Programcı: Yardımcıları kontrol eden yapay zekanın yaratıcısı. Programcı'yı yok edersek, Tarikat'ın birliklerini tek bir darbeyle etkisiz hale getirebiliriz. Ama dikkat: Saldırganları buharlaştırabildiğine dair raporlarımız var." +だが気をつけておけ、ヤツは熱で敵を蒸発させられるとの報告があるからな。","... 프로그래머: 아콜라이트들을 통제하는 인공지능의 창조자 말입니다. 그를 파괴하면 일격으로 오더의 군대를 무력화시킬 수 있을 겁니다. 하지만 조심하세요, 보고에 의하면 그는 자기 상대를 가루로 만들어 버린다는군요.","...de programmeur: maker van de AI die de Acolieten bestuurt. Vernietig de programmeur, en we kunnen de troepen van de Orde met een enkele klap verlammen. Maar opgelet: we hebben meldingen dat hij aanvallers kan verdampen.","...programmereren: skaperen av AI-en som kontrollerer akolyttene. Ødelegger vi Programmereren, kan vi lamme Ordenens tropper med ett slag. Men forsiktighet: Vi har rapporter om at han kan pulverisere angripere.","...Programista: twórca SI, która kontroluje Akolitów. Zniszcz Programistę, a możemy sparaliżować wojska Zakonu jednym uderzeniem. Ale uwaga: mamy doniesienia, że potrafi on wyparować napastników.","...o Programador: o criador da inteligência artificial que controla os Acólitos. Destrua o programador e, assim, poderemos prejudicar as tropas da Ordem com um único golpe. Mas cuidado: temos relatos de que ele pode vaporizar aqueles que atacam.",,"...Programatorul: creatorul inteligenței artificiale care controlează Acoliții. Distruge-l, și vom nimicii trupele Ordinului cu o singură lovitură: avem rapoarte care spun că poate vaporiza atacatorii.","...Программистом — создателем ИИ, контролирующего служителей. Уничтожь Программиста, и мы разделаемся с войсками Ордена одним ударом. Но осторожнее — нам докладывали, что он умеет... испепелять нападающих.",,...Programmeraren: skaparen av den intelligenta intelligens som kontrollerar akoliterna. Förstör Programmeraren och vi kan lamslå ordens trupper med ett enda slag. Men var försiktig: vi har rapporterat att han kan förånga angripare.,"...Programcı: Yardımcıları kontrol eden yapay zekanın yaratıcısı. Programcı'yı yok edersek, Tarikat'ın birliklerini tek bir darbeyle etkisiz hale getirebiliriz. Ama dikkat: Saldırganları buharlaştırabildiğine dair raporlarımız var." "Fragments assembled from the Programmers files tell us that the Order is worshipping an intelligent weapon. They call it ""the Sigil"".",TXT_SUB_MAP10_1,MAP10: Macil.,,,"Útržky poskládané z Programátorových souborů nám říkají, že Řád uctívá inteligentní zbraň. Říkají jí „Pečeť“.","Fragmenter, der er samlet fra Programmerens filer, fortæller os, at Ordenen tilbeder et intelligent våben. De kalder det ""Sigil"".","Fragmente, zusammengestellt aus den Dateien des Programmierers, sagen uns, dass der Orden eine intelligente Waffe verehrt. Sie nennen sie „Das Sigil“.",,,"Fragmentos reunidos de los archivos del Programador nos dicen que la Orden adora un arma inteligente. La llaman ""el Emblema"".",,Ohjelmoitsijan tiedostoista kerättyjen pirstaleiden mukaan Veljeskunta palvoo älykästä asetta. He kutsuvat sitä Sinetiksi.,"Des fragments des fichiers du Programmeur que nous avons assemblés nous disent que l'Ordre vénère une arme intelligente. Ils l'appelent le ""Sigil"".","A Programozó fájljainak töredékeiből kiderítettük, hogy a Rend egy intelligens fegyverhez imádkozik. Csak ""Pecsét"" néven említik.","Frammenti dei file del Programmatore che abbiamo assemblato ci dicono che l'Ordine venera un'arma intelligente. La chiamano ""il Sigillo"".","プログラマーの資料を要約するとその欠片はオーダー達が崇拝する知性を持った武器、 -'シジル'だ。","프로그래머의 파괴된 기록들을 복원해보니, 오더가 자아를 가진 한 무기를 숭배하고 있다는군요. 그들은 이걸 “시질”이라고 부릅니다.","Fragmenten uit de Programmers bestanden vertellen ons dat de Orde een intelligent wapen aanbidt. Ze noemen het ""de Sigil"".","Fragmenter fra Programmererens filer forteller oss at Ordenen tilber et intelligent våpen. De kaller det ""Sigil"".","Fragmenty zebrane z akt Programistów mówią nam, że Zakon czci inteligentną broń. Nazywają ją ""Sigil"".","Os fragmentos dos relatórios sobre o Programador que conseguimos juntar dizem que a Ordem está venerando uma arma inteligente. Eles a chamam de ""Sigilo"".",,"Fragmentele asamblate din fișierele Programatorului ne spun că Ordinul venerează o armă inteligentă. O numesc ""Sigiliul"".","Мы собирали информацию по крупицам из обрывков файлов Программиста и выяснили, что Орден поклоняется разумному оружию. Они называют его «Печатью».",,"Programcıların dosyalarından toplanan parçalar bize Tarikat'ın akıllı bir silaha taptığını söylüyor. Ona ""Sigil"" diyorlar." +'シジル'だ。","프로그래머의 파괴된 기록들을 복원해보니, 오더가 자아를 가진 한 무기를 숭배하고 있다는군요. 그들은 이걸 “시질”이라고 부릅니다.","Fragmenten uit de Programmers bestanden vertellen ons dat de Orde een intelligent wapen aanbidt. Ze noemen het ""de Sigil"".","Fragmenter fra Programmererens filer forteller oss at Ordenen tilber et intelligent våpen. De kaller det ""Sigil"".","Fragmenty zebrane z akt Programistów mówią nam, że Zakon czci inteligentną broń. Nazywają ją ""Sigil"".","Os fragmentos dos relatórios sobre o Programador que conseguimos juntar dizem que a Ordem está venerando uma arma inteligente. Eles a chamam de ""Sigilo"".",,"Fragmentele asamblate din fișierele Programatorului ne spun că Ordinul venerează o armă inteligentă. O numesc ""Sigiliul"".","Мы собирали информацию по крупицам из обрывков файлов Программиста и выяснили, что Орден поклоняется разумному оружию. Они называют его «Печатью».",,"Fragment som samlats ihop från Programmerarens filer säger oss att Orden dyrkar ett intelligent vapen. De kallar det ""Sigil"".","Programcıların dosyalarından toplanan parçalar bize Tarikat'ın akıllı bir silaha taptığını söylüyor. Ona ""Sigil"" diyorlar." "The piece you touched and recovered is one of five. It wields power drawn from the user's own life force. While you live, you control its power.",TXT_SUB_MAP10_2,〃,,,"Díl, kterého jsi se dotknul a ponechal si je jeden z pěti. Mocní se silou, napájenou ze životní energie jejího majitele. Dokud žiješ, ovládáš jeho sílu.","Det stykke, du rørte og fandt, er et af fem. Det udøver kraft fra brugerens egen livskraft. Mens du lever, kontrollerer du dens kraft.","Das Teil, das du berührt und gefunden hast, ist eines von fünf. Es bezieht die Kraft von der Lebensenergie des Benutzers. So lange du lebst, kontrollierst du seine Kraft.",,,"La pieza que has tocado y recuperado es una de cinco. Esgrime poder tomado de la propia fuerza de vida del usuario. Mientras vivas, controlas su poder.",,"Koskettamasi osanen, jonka otit talteen, on yksi viidestä. Se saa voimansa käyttäjänsä omasta elämänvoimasta. Niin kauan kuin sinä elät, hallitset sen voimaa.","La pièce que vous avez touché et récupéré n'est qu'une parmi cinq. Elle utilise la force vitale de son utilisateur. Tant que vous êtes en vie, vous son pouvoir sous votre contrôle.","A darabka amit megérintettél és visszaszereztél csak egy az ötből. Erejét a hordozója életerejéből meríti. Amíg tehát élsz, tudod irányítani.","Il pezzo che hai toccato e recuperato è solo uno di cinque. Utilizza la forza vitale dell'utilizzatore. Finchè sei vivo, hai il potere sotto il tuo controllo.","君が欠片を取り戻したがそれは5つある内の1つだ。 使用者の生命を吸い上げ激しい力を引き出す。 -ただ制御下におけるのは生きている間だけだ。","당신이 건져낸 조각은 다섯 개의 조각 중 하나입니다. 이것은 사용자의 생명력을 빨아들여 위력을 발휘합니다. 당신이 살아있는 동안, 녀석의 힘은 당신의 것입니다.","Het stuk dat je hebt aangeraakt en teruggevonden is een van de vijf. Het heeft kracht die getrokken wordt uit de eigen levenskracht van de gebruiker. Terwijl je leeft, heb je de macht ervan in handen.","Brikken du berørte og gjenopprettet er en av fem. Den har kraft hentet fra brukerens egen livskraft. Mens du lever, kontrollerer du dens kraft.","Kawałek, który dotknąłeś i odzyskałeś, jest jednym z pięciu. Włada mocą czerpaną z własnej siły życiowej użytkownika. Póki żyjesz, kontrolujesz jego moc.","A peça que você tocou e recuperou é uma das cinco peças. Seu poder vem da própria energia de vida de quem a usa. Enquanto você viver, você controla o poder dela.",,"Piesa pe care ai atins-o și recuperat-o e una din cinci. Își trage puterea din deținător. Cât trăiești, o controlezi.","Тот фрагмент, что ты подобрал и активировал, — один из пяти. Он использует мощь, которую черпает из жизненных сил владельца. Пока ты жив, она подвластна тебе.",,"Dokunduğunuz ve kurtardığınız parça beş taneden biri. Kullanıcının kendi yaşam gücünden alınan gücü kullanıyor. Yaşadığın sürece, onun gücünü kontrol ediyorsun." +ただ制御下におけるのは生きている間だけだ。","당신이 건져낸 조각은 다섯 개의 조각 중 하나입니다. 이것은 사용자의 생명력을 빨아들여 위력을 발휘합니다. 당신이 살아있는 동안, 녀석의 힘은 당신의 것입니다.","Het stuk dat je hebt aangeraakt en teruggevonden is een van de vijf. Het heeft kracht die getrokken wordt uit de eigen levenskracht van de gebruiker. Terwijl je leeft, heb je de macht ervan in handen.","Brikken du berørte og gjenopprettet er en av fem. Den har kraft hentet fra brukerens egen livskraft. Mens du lever, kontrollerer du dens kraft.","Kawałek, który dotknąłeś i odzyskałeś, jest jednym z pięciu. Włada mocą czerpaną z własnej siły życiowej użytkownika. Póki żyjesz, kontrolujesz jego moc.","A peça que você tocou e recuperou é uma das cinco peças. Seu poder vem da própria energia de vida de quem a usa. Enquanto você viver, você controla o poder dela.",,"Piesa pe care ai atins-o și recuperat-o e una din cinci. Își trage puterea din deținător. Cât trăiești, o controlezi.","Тот фрагмент, что ты подобрал и активировал, — один из пяти. Он использует мощь, которую черпает из жизненных сил владельца. Пока ты жив, она подвластна тебе.",,Den bit som du rörde vid och återfann är en av fem. Den använder kraft som hämtas från användarens egen livskraft. Så länge du lever kontrollerar du dess kraft.,"Dokunduğunuz ve kurtardığınız parça beş taneden biri. Kullanıcının kendi yaşam gücünden alınan gücü kullanıyor. Yaşadığın sürece, onun gücünü kontrol ediyorsun." "The shock which knocked you out was the Sigil piece tuning itself to you, your pulse and brain waves. You can wield it, but at a cost: it will drain you dry.",TXT_SUB_MAP10_3,〃,,,"Ránu, která tě uspala, způsobil ten díl Pečeti, ladící sám sebe k tobě, tvému pulzu a mozkovým vlnám. Můžeš jej používat, ale za určitou cenu: Bude tě vysilovat.","Det chok, der slog dig bevidstløs, var Sigilstykket, der indstillede sig på dig, din puls og dine hjernebølger. Du kan bruge det, men det har en pris: det vil dræne dig for energi.","Der Schock, durch den du das Bewusstsein verloren hast, wurde verursacht, als das Sigilteil sich auf dich, deinen Puls und deine Gehirnwellen eingestellt hat. Du kannst es benutzen, aber es wird dich austrocknen.",,,"El choque que te derribó fue la pieza del Emblema sintonizándose contigo, con tu pulso y ondas cerebrales. Puedes empuñarla, pero con un precio: Te dejará seco.",,"Kokemasi sysäys, joka tyrmäsi sinut, oli Sinetin virittäytymistä sinuun, sinun sykkeeseesi ja aivoaaltoihisi. Hallitset sitä, mutta sillä hinnalla, että se imee sinut kuiviin.","Le choc qui vous a rendu inconscient venait de la pièce du Sigil qui s'est alignée sur votre énergie vitale, votre pouls et vos ondes cérébrales. Vous pouvez l'utiliser, mais au coût de votre vie.","A sokk ami kiütött nem volt más, mint maga a Pecsét ráhangolódása a pulzusodra és agyhullámodra. Forgathatod mint egy kardot, de ára van: kiszívja az életerődet.","Lo schock che ti ha fatto perdere i sensi era un pezzo del Sigillo che si è allineato con la tua energia vitale, il tuo polso e le tue onde cerebrali. Puoi utilizzarlo, ma ad un costo: ti prosciugherà in pieno.","君を気絶させた衝撃は、シジルの欠片が脈拍と脳波を同期させた際に起こした様だ。 -それを振り回す時は気を付けろ、代償で体が干上がってしまうらしい。","당신을 기절시킨 충격은 시질이 당신의 심박과 뇌파와 반응하면서 비롯되었습니다. 이 무기를 써도 되지만, 조심하세요: 당신을 말려 죽일 수도 있으니까.","De schok die je bewusteloos maakte, was de Sigil die zich op jou, je pols en hersengolven, afstemde. Je kunt het gebruiken, maar tegen een prijs: het zal je droog laten vallen.","Sjokket som slo deg ut var Sigil-brikken som innstilte seg på deg, pulsen din og hjernebølgene dine. Du kan bruke det, men det koster: det vil tappe deg for krefter.","Wstrząs, który cię znokautował, to kawałek Sigilu, który dostroił się do ciebie, twojego pulsu i fal mózgowych. Możesz nim władać, ale za pewną cenę: wyczerpie cię do cna.","O choque que te derrubou foi da peça do Sigilo se calibrando a você, com o seu pulso e suas ondas cerebrais. Você pode usá-la, mas tem um custo: ela vai te drenar por completo.",,"Șocul care te-a lăsat inconștient a fost piesa care s-a întors asupra ta. O controlezi, dar cu un preț: o să te sece.","Ты потерял сознание, потому что фрагмент Печати подстраивался под тебя, под твоё сердцебиение и мозговые ритмы. Теперь ты сможешь им пользоваться, но он будет взымать свою плату, иссушая тебя.",,"Sizi bayıltan şok, Sigil parçasının kendisini size, nabzınıza ve beyin dalgalarınıza göre ayarlamasıydı. Onu kullanabilirsin ama bir bedeli var: Seni kurutacak." +それを振り回す時は気を付けろ、代償で体が干上がってしまうらしい。","당신을 기절시킨 충격은 시질이 당신의 심박과 뇌파와 반응하면서 비롯되었습니다. 이 무기를 써도 되지만, 조심하세요: 당신을 말려 죽일 수도 있으니까.","De schok die je bewusteloos maakte, was de Sigil die zich op jou, je pols en hersengolven, afstemde. Je kunt het gebruiken, maar tegen een prijs: het zal je droog laten vallen.","Sjokket som slo deg ut var Sigil-brikken som innstilte seg på deg, pulsen din og hjernebølgene dine. Du kan bruke det, men det koster: det vil tappe deg for krefter.","Wstrząs, który cię znokautował, to kawałek Sigilu, który dostroił się do ciebie, twojego pulsu i fal mózgowych. Możesz nim władać, ale za pewną cenę: wyczerpie cię do cna.","O choque que te derrubou foi da peça do Sigilo se calibrando a você, com o seu pulso e suas ondas cerebrais. Você pode usá-la, mas tem um custo: ela vai te drenar por completo.",,"Șocul care te-a lăsat inconștient a fost piesa care s-a întors asupra ta. O controlezi, dar cu un preț: o să te sece.","Ты потерял сознание, потому что фрагмент Печати подстраивался под тебя, под твоё сердцебиение и мозговые ритмы. Теперь ты сможешь им пользоваться, но он будет взымать свою плату, иссушая тебя.",,"Den chock som slog dig medvetslös var att Sigilstycket anpassade sig till dig, din puls och dina hjärnvågor. Du kan använda den, men till ett pris: den kommer att tömma dig på vatten.","Sizi bayıltan şok, Sigil parçasının kendisini size, nabzınıza ve beyin dalgalarınıza göre ayarlamasıydı. Onu kullanabilirsin ama bir bedeli var: Seni kurutacak." One piece constitutes awesome power. Possession of all five pieces would be devastating and would give the user total control of the planet.,TXT_SUB_MAP10_4,〃,,,Jen jeden díl obsahuje ohromnou sílu. Vlastnictví všech pěti dílů by bylo devastující a jeho majitel by byl schopen ovládat celou planetu.,Et stykke udgør en fantastisk kraft. Besiddelse af alle fem stykker ville være ødelæggende og ville give brugeren total kontrol over planeten.,"Ein Teil stellt große Macht dar. Der Besitz aller fünf Teile wäre verheerend, und der Nutzer hätte die totale Kontrolle über den Planeten.",,,"Una pieza constituye un poder impresionante, poseer las cinco piezas sería devastador y daría al usuario control total del planeta.",,Jo yhdessä osasessa piilee valtava mahti. Kaikkien viiden osasen hallitseminen olisi tuhoisaa ja antaisi käyttäjälleen täydellisen otteen planeetasta.,Une pièce représente un pouvoir phénoménal. Posséder toutes les cinq serait dévastateur: cela donnerait à l'utilisateur le contrôle total sur la planète.,"Egy darab nagy hatalmat biztosít hordozójának. Azonban mind az öt darabka együtt emberfeletti erővel ruházná fel, és az egész bolygó felett átvenné a hatalmat.",Un pezzo costituisce un potere fenomenale. Il possesso di tutti i cinque pezzi sarebbe devastante: darebbe all'utilizzatore il controllo totale sul pianeta.,"だがたった一つでも相当な力を放つ。 -それが5つ揃った時は圧倒的な力で世界をも支配下に置けるだろう。","하나의 조각으로도 엄청난 위력을 가지게 되고, 다섯 조각 모두를 얻으면 이 세상을 평정할 만큼 강력한 위력을 발휘할 것입니다.",Een stuk vormt ontzagwekkende kracht. Het bezit van alle vijf de stukken zou verwoestend zijn en zou de gebruiker de volledige controle over de planeet geven.,Ett stykke utgjør en fantastisk kraft. Besittelse av alle fem brikkene ville være ødeleggende og gi brukeren total kontroll over planeten.,Jeden kawałek stanowi niesamowitą moc. Posiadanie wszystkich pięciu kawałków byłoby niszczące i dałoby użytkownikowi całkowitą kontrolę nad planetą.,Uma das peças possui um poder tremendo. Possuir todas as cinco peças seria devastador e daria controle total do planeta ao utilizador.,,O piesă constituie putere uimitoare. Posesiunea tuturor pieselor ar fi devastatore și ar da deținătorului control asupra întregii planete.,Один фрагмент — уже немалая сила. Пять фрагментов будут опустошающей силой. Их владелец получит полную власть над планетой.,,Tek bir parça müthiş bir güç demektir. Beş parçaya birden sahip olmak yıkıcı olur ve kullanıcıya gezegenin kontrolünü tamamen verir. +それが5つ揃った時は圧倒的な力で世界をも支配下に置けるだろう。","하나의 조각으로도 엄청난 위력을 가지게 되고, 다섯 조각 모두를 얻으면 이 세상을 평정할 만큼 강력한 위력을 발휘할 것입니다.",Een stuk vormt ontzagwekkende kracht. Het bezit van alle vijf de stukken zou verwoestend zijn en zou de gebruiker de volledige controle over de planeet geven.,Ett stykke utgjør en fantastisk kraft. Besittelse av alle fem brikkene ville være ødeleggende og gi brukeren total kontroll over planeten.,Jeden kawałek stanowi niesamowitą moc. Posiadanie wszystkich pięciu kawałków byłoby niszczące i dałoby użytkownikowi całkowitą kontrolę nad planetą.,Uma das peças possui um poder tremendo. Possuir todas as cinco peças seria devastador e daria controle total do planeta ao utilizador.,,O piesă constituie putere uimitoare. Posesiunea tuturor pieselor ar fi devastatore și ar da deținătorului control asupra întregii planete.,Один фрагмент — уже немалая сила. Пять фрагментов будут опустошающей силой. Их владелец получит полную власть над планетой.,,Ett stycke utgör en fantastisk kraft. Att äga alla fem delar skulle vara förödande och ge användaren total kontroll över planeten.,Tek bir parça müthiş bir güç demektir. Beş parçaya birden sahip olmak yıkıcı olur ve kullanıcıya gezegenin kontrolünü tamamen verir. "Listen, this com unit tells me that you're 100% human. I've been ordered to bring you in, we're talking trust here. Betray me and pay. Oh, and by the way, you can call me Blackbird.",TXT_SUB_LOG2,MAP02: After getting the com unit from Rowan and leaving his room.,,,"Poslyš, tento komunikátor mi říká, že jsi na sto procent člověkem. Dostala jsem rozkaz tě přivést tě k nám; jde o důvěryhodnou záležitost - zraď mě a zaplatíš. Jo, a mimochodem, můžeš mi říkat Straka.","Hør, denne com-enhed fortæller mig, at du er 100 % menneskelig. Jeg er blevet beordret til at bringe dig ind, vi taler om tillid her. Forråd mig og betal. Og forresten, du kan kalde mig Blackbird.","Hör zu, dieser Kommunikator sagt mit, dass du noch 100% menschlich bist. Mir wurde aufgetragen, dich zu unserer Zentrale zu führen. Wir reden über Vertrauen, wenn du mich verrätst, wirst du bezahlen. Übrigens, du kannst mich Blackbird nennen.",,,"Escucha, este intercomunicador me dice que eres 100% humano. Se me ha ordenado dejarte entrar, así que hablamos en confianza. Traicióname y pagarás. Ah, por cierto, puedes llamarme BlackBird.","Escucha, este intercomunicador me dice que eres 100% humano. Se ordenadó dejarte entrar, así que hablamos en confianza. Traicióname y te vas a arrepentir. Ah, por cierto, puedes llamarme BlackBird.","Kuule, tämä viestintälaite ilmaisee sinun olevan sataprosenttisesti ihminen. Minut on määrätty tuomaan sinut meidän joukkoomme; puhumme luottamuksellisesti. Petä minut ja saat luvan maksaa. Ja muuten, voit kutsua minua Blackbirdiksi.","Ecoute, ce communicateur me dit que tu est 100% humain. On m'a ordonnée de te ramener, c'est une question de confiance. Trahis-moi et tu paieras. Oh, et tu peux m'appeler Blackbird.","Figyelj csak, azt mutatja ez a kommunikációs egység hogy 100%-ban ember vagy. Azt az utasítást kaptam, hogy hozzalak be. Vakon beléd vetjük a bizalmunkat, de tudd, hogy ha elárulsz minket meglakolsz. Ja, és hívhatsz Feketerigónak.","Ascolta, questa unità di comunicazione mi dice che sei 100% umano. Ho l'ordine di farti arrivare da noi, e quindi stiamo parlando di fiducia. Se mi tradisci la pagherai cara. Comunque, mi puoi chiamare Blackbird.","聞こえるか、この無線機がアナタは100%人間だと判断した。 私はアナタを信頼して良いとみて連れて来るよう命じられた、 -反乱への報酬は期待して良いわ。ああ、それと、私の名はブラックバードよ。","잘 들어, 이 통신기에 따르면 넌 100% 인간이야. 너를 믿어도 될 거 같으니 우리 편으로 끌어모으라는 지시를 받았어. 배신했다간 대가를 치를 거야. 아, 그리고, 날 블랙버드라고 불러줘.","Luister, deze com-unit zegt me dat je 100% menselijk bent. Ik heb opdracht gekregen om je binnen te halen, we hebben het hier over vertrouwen. Verraad me en betaal. Oh, en trouwens, je mag me Blackbird noemen.","Denne kommunikasjonsenheten forteller meg at du er 100 % menneskelig. Jeg har fått ordre om å hente deg inn, vi snakker om tillit her. Forråd meg og betal. Og forresten, du kan kalle meg Blackbird.","Słuchaj, to urządzenie mówi mi, że jesteś w 100% człowiekiem. Otrzymałem rozkaz sprowadzenia cię, mówimy tu o zaufaniu. Zdradzisz mnie i zapłacisz. Aha, i przy okazji, możesz mi mówić Blackbird.","Ouça, este comunicador me diz que você é 100% humano. Recebi ordens para te trazer até aqui. É melhor você ser de confiança. Se você me trair, você me paga. Ah, a propósito, pode me chamar de Blackbird.",,"Ascultă, unitatea asta îmi spune că ești 100% uman. Am primit ordin să te aduc, vorbim de încredere aici. Trădează-mă și plătești. Oh, și apropo, îmi poți spune Blackbird.","Слушай — судя по этому передатчику, ты на сто процентов человек. Я получила приказ показать тебе дорогу к нам. Как видишь, тебе доверяют, но если предашь меня — пожалеешь. И да, обращайся ко мне «Чёрный дрозд». ",,"Dinle, bu iletişim birimi bana senin %100 insan olduğunu söylüyor. Seni getirmem emredildi, burada güvenden bahsediyoruz. Bana ihanet edersen bedelini ödersin. Bu arada bana Karatavuk diyebilirsin." +反乱への報酬は期待して良いわ。ああ、それと、私の名はブラックバードよ。","잘 들어, 이 통신기에 따르면 넌 100% 인간이야. 너를 믿어도 될 거 같으니 우리 편으로 끌어모으라는 지시를 받았어. 배신했다간 대가를 치를 거야. 아, 그리고, 날 블랙버드라고 불러줘.","Luister, deze com-unit zegt me dat je 100% menselijk bent. Ik heb opdracht gekregen om je binnen te halen, we hebben het hier over vertrouwen. Verraad me en betaal. Oh, en trouwens, je mag me Blackbird noemen.","Denne kommunikasjonsenheten forteller meg at du er 100 % menneskelig. Jeg har fått ordre om å hente deg inn, vi snakker om tillit her. Forråd meg og betal. Og forresten, du kan kalle meg Blackbird.","Słuchaj, to urządzenie mówi mi, że jesteś w 100% człowiekiem. Otrzymałem rozkaz sprowadzenia cię, mówimy tu o zaufaniu. Zdradzisz mnie i zapłacisz. Aha, i przy okazji, możesz mi mówić Blackbird.","Ouça, este comunicador me diz que você é 100% humano. Recebi ordens para te trazer até aqui. É melhor você ser de confiança. Se você me trair, você me paga. Ah, a propósito, pode me chamar de Blackbird.",,"Ascultă, unitatea asta îmi spune că ești 100% uman. Am primit ordin să te aduc, vorbim de încredere aici. Trădează-mă și plătești. Oh, și apropo, îmi poți spune Blackbird.","Слушай — судя по этому передатчику, ты на сто процентов человек. Я получила приказ показать тебе дорогу к нам. Как видишь, тебе доверяют, но если предашь меня — пожалеешь. И да, обращайся ко мне «Чёрный дрозд». ",,"Lyssna, den här kommunikationsenheten säger mig att du är 100 % mänsklig. Jag har fått order att ta in dig, vi pratar om förtroende här. Förråda mig och betala. Och förresten, du kan kalla mig Blackbird.","Dinle, bu iletişim birimi bana senin %100 insan olduğunu söylüyor. Seni getirmem emredildi, burada güvenden bahsediyoruz. Bana ihanet edersen bedelini ödersin. Bu arada bana Karatavuk diyebilirsin." "Head over to the old town hall. After the Order bombed it, Macil had a tunnel built that lets us get in and out without the acolytes' knowledge.",TXT_SUB_LOG3,MAP02: On the bridge with the com unit.,,,"Zamiř ke staré radnici. Když ji Řád vybombardoval, Macil nechal postavit tunel, který nám umožňuje bez vědomí akolytů dostat se dovnitř a ven.","Gå over til det gamle rådhus. Efter at Ordenen bombede det, fik Macil bygget en tunnel, som lader os komme ind og ud uden acolytes' viden.","Geh zum alten Rathaus. Macil hat einen Tunnel bauen lassen, durch den wir dort reinkommen, ohne dass die Ministranten das mitbekommen.",,,"Dirígete al antiguo ayuntamiento. Después de que lo bombardeara La Orden, Macil hizo construir un túnel que nos permite entrar y salir sin que los acólitos lo sepan.",,"Suuntaa kohti vanhaa kaupungintaloa. Sen jälkeen kun Veljeskunta oli pommittanut sen, Macil rakennutti tunnelin, jonka avulla voimme päästä sisään ja ulos akoluuttien tietämättä.",Dirige-toi vers l'ancienne mairie. Macil a fait construire un tunnel après que L'Ordre l'ait bombardée. Il nous permet d'y entrer sans que l'Ordre nous remarque.,"Menj a régi városközpontba. Miután a Rend lebombázta, Macil építtetett egy titkos alagutat, amin észrevétlenül tudunk ki- és bemenni a ministránsok tudta nélkül.",Raggiungi il vecchio Municipio. Macil ha fatto costruire un tunnel che ci fa entrare ed uscire senza che gli accoliti lo sappiano.,"旧市庁舎に向かうんだ。オーダーに爆撃された後 -そこにマシルがアコライトに関わる者を欺く為の抜け道を用意している。",구 시청으로 향해. 오더가 이곳을 폭격한 후에 마실이 그곳에 아콜라이트들이 모르는 통행로를 만들어놨어.,"Ga naar het oude stadhuis. Nadat de Orde het gebombardeerd had, liet Macil een tunnel bouwen die ons in en uit laat stappen zonder dat de acolieten het wisten.","Dra til det gamle rådhuset. Etter at Ordenen bombet det, fikk Macil bygget en tunnel som lar oss komme inn og ut uten at akolyttene vet om det.","Udaj się do starego ratusza. Po zbombardowaniu go przez Zakon, Macil kazał wybudować tunel, który pozwala nam wejść i wyjść bez wiedzy akolitów.","Vá até à antiga prefeitura. Depois que a Ordem a bombardeou, Macil mandou construir um túnel que nos leva e tira de lá sem os acólitos perceberem.",,"Du-te la vechea hală a orașului, Macil a construit un tunel care permite trecerea fără a fi detectat.","Отправляйся к старой ратуше. После того, как Орден взорвал её, Мэйсил построил там туннель, который позволяет нам входить и выходить без ведома служителей.",,"Eski belediye binasına git. Tarikat orayı bombaladıktan sonra Macil, yardımcıların haberi olmadan girip çıkmamızı sağlayan bir tünel inşa ettirdi." +そこにマシルがアコライトに関わる者を欺く為の抜け道を用意している。",구 시청으로 향해. 오더가 이곳을 폭격한 후에 마실이 그곳에 아콜라이트들이 모르는 통행로를 만들어놨어.,"Ga naar het oude stadhuis. Nadat de Orde het gebombardeerd had, liet Macil een tunnel bouwen die ons in en uit laat stappen zonder dat de acolieten het wisten.","Dra til det gamle rådhuset. Etter at Ordenen bombet det, fikk Macil bygget en tunnel som lar oss komme inn og ut uten at akolyttene vet om det.","Udaj się do starego ratusza. Po zbombardowaniu go przez Zakon, Macil kazał wybudować tunel, który pozwala nam wejść i wyjść bez wiedzy akolitów.","Vá até à antiga prefeitura. Depois que a Ordem a bombardeou, Macil mandou construir um túnel que nos leva e tira de lá sem os acólitos perceberem.",,"Du-te la vechea hală a orașului, Macil a construit un tunel care permite trecerea fără a fi detectat.","Отправляйся к старой ратуше. После того, как Орден взорвал её, Мэйсил построил там туннель, который позволяет нам входить и выходить без ведома служителей.",,Gå till det gamla stadshuset. Efter att Orden bombade det lät Macil bygga en tunnel som gör att vi kan ta oss in och ut utan acolytternas vetskap.,"Eski belediye binasına git. Tarikat orayı bombaladıktan sonra Macil, yardımcıların haberi olmadan girip çıkmamızı sağlayan bir tünel inşa ettirdi." "Go through the door on your left, then the one on the right. The guard's name is Geoff. Tell him you need gold.",TXT_SUB_LOG4,MAP02: In hall town with the com unit.,,,"Projdi dveřmi nalevo a pak napravo. Hlídač se jmenuje Geoff. Řekni mu, že potřebuješ zlato.","Gå gennem døren til venstre og derefter gennem den til højre. Vagtens navn er Geoff. Sig til ham, at du har brug for guld.","Geh durch die linke Tür, dann durch die rechte. Der Wächter heißt Geoff. Sag ihm du brauchst Gold.",,"Iru tra la maldekstra pordo kaj poste tra la dekstra. La nomo de la gardisto estas Geoff; diru al li «Saluton, mi bezonas oron».","Ve por la puerta izquierda y luego por la derecha. El guardia se llama Geoff; dile «Buenas, necesito oro».",,"Kulje sinusta katsottuna vasemmalla puolella olevan oven läpi, sitten oikeanpuoleisesta ovesta. Vartijan nimi on Geoff. Kerro hänelle tarvitsevasi kultaa.",Passe par la porte à gauche puis celle à droite. Le garde s'appelle Geoff. Dis-lui que tu as besoin d'argent.,"Menj át a bal oldali ajtón, majd a jobb oldalin. Az őr neve Geoff. Mond neki, hogy aranyra van szükséged.","Vai oltre la porta alla tua sinistra, e poi la porta alla tua destra. Il nome della guardia è Geoff. Digli che ti serve dell'oro.","すぐ左のドアを通り、右のドアから小部屋に入るんだ。 -見張りの名はジェフ。金が必要だ と言えば通じる。","네 왼쪽의 문으로 들어간 후, 다시 오른쪽의 문으로 가. 경비의 이름은 제프야. 그에게 골드가 필요하다고 얘기해.","Ga door de deur links van je, dan die rechts van je. De bewaker heet Geoff. Zeg hem dat je goud nodig hebt.","Gå gjennom døren til venstre, så den til høyre. Vakten heter Geoff. Si at du trenger gull.","Przejdź przez drzwi po lewej, a potem przez te po prawej. Strażnik ma na imię Geoff. Powiedz mu, że potrzebujesz złota.",Vá pela porta à sua esquerda e depois a da direita. O nome do guarda é Geoff. Diga a ele que você precisa de ouro.,,"Du-te prin ușa la stânga, apoi dreapta. Numele gardianului e Geoff. Spune-i că ai nevoie de aur.","Пройди за левую дверь, затем иди направо. Стражника зовут Джефф. Скажи ему, что тебе нужно золото.",,"Solundaki kapıdan geç, sonra sağdakinden. Muhafızın adı Geoff. Ona altına ihtiyacın olduğunu söyle." +見張りの名はジェフ。金が必要だ と言えば通じる。","네 왼쪽의 문으로 들어간 후, 다시 오른쪽의 문으로 가. 경비의 이름은 제프야. 그에게 골드가 필요하다고 얘기해.","Ga door de deur links van je, dan die rechts van je. De bewaker heet Geoff. Zeg hem dat je goud nodig hebt.","Gå gjennom døren til venstre, så den til høyre. Vakten heter Geoff. Si at du trenger gull.","Przejdź przez drzwi po lewej, a potem przez te po prawej. Strażnik ma na imię Geoff. Powiedz mu, że potrzebujesz złota.",Vá pela porta à sua esquerda e depois a da direita. O nome do guarda é Geoff. Diga a ele que você precisa de ouro.,,"Du-te prin ușa la stânga, apoi dreapta. Numele gardianului e Geoff. Spune-i că ai nevoie de aur.","Пройди за левую дверь, затем иди направо. Стражника зовут Джефф. Скажи ему, что тебе нужно золото.",,Gå genom dörren till vänster och sedan genom dörren till höger. Vaktens namn är Geoff. Säg till honom att du behöver guld.,"Solundaki kapıdan geç, sonra sağdakinden. Muhafızın adı Geoff. Ona altına ihtiyacın olduğunu söyle." "Irale is the Front's ""fixer"". He's behind the unmarked door next to the weapons shop.",TXT_SUB_LOG5,MAP03: After joining the Front.,,,Irale je „kutil“ Fronty. Je za neoznačenými dveřmi vedle obchodu se zbraněmi.,"Irale er frontens ""fixer"". Han befinder sig bag den umærkede dør ved siden af våbenbutikken.",Irale ist der „Bastler“ der Front. Er ist hinter der unmarkierten Tür neben dem Waffengeschäft.,,,Irale es el «apañador» del Frente. Está pasando la puerta sin cartel junto a la tienda de armas.,Irale es el «soluccionador» del Frente. Está pasando la puerta sin cartel junto a la tienda de armas.,"Irale on Rintaman ""järkkäri"". Hänet löytää merkkaamattoman oven takaa asekaupan vierestä.",Irale est le receleur du front. Il est derrière la porte non marquée à côté du magasin d'armes.,"Irale a Front ""ezermestere"". A jelöletlen ajtó mögött lesz a fegyverbolt mellett.",Irale è un fornitore di armi per il Fronte. Si trova dietro la porta accanto al negozio di armi.,"イラールとはフロントの'仲介者'よ。彼は武器屋の隣のマークされてないドアに居る。 -発電所に近い所だ。",이롤리는 프론트의 수리공이기도 해. 무기상점 근처에 그의 가게로 향하는 문이 있을 거야.,"Irale is de ""fixer"" van de Front. Hij zit achter de ongemarkeerde deur naast de wapenwinkel.","Irale er Frontens ""fikser"". Han er bak den umerkede døren ved siden av våpenbutikken.","Irale to ""załatwiacz"" Frontu. Jest za nieoznakowanymi drzwiami obok sklepu z bronią.","Irale é o ""quebra-galho"" da Frente. Ele está atrás da porta desmarcada próxima ao depósito de armas.",,"Irale e ""reparatorul"" Frontului. E în spatele ușii fără însemn lângă magazinul de arme.",Ирэйл — «наладчик» Сопротивления. Ты найдёшь его за дверью без вывески возле оружейного магазина.,,"İrale, Cephe'nin ""iş bitiricisi"". Silah dükkanının yanındaki işaretlenmemiş kapının arkasında." -Remember: kill with stealth instead of force. You won't set off the alarms.,TXT_SUB_LOG6,MAP02,,,Pamatuj: Zabíjej potichu. Nespustíš poplach.,Husk: Dræb med list i stedet for med magt. Du vil ikke udløse alarmen.,Denk daran: Töte lautlos und du wirst den Alarm nicht auslösen.,,,Recuerda: mata con sigilo y no con fuerza para no activar las alarmas.,,Muista: tapa huomaamattomasti voiman sijasta. Niin vältät hälytyksen.,"Souviens-toi: Tue avec discrétion, pas avec force, et tu n'activeras pas les alarmes.","Figyelj arra, hogy lopakodva ölj, ne erővel. Így nem indítod be a riasztót.",Ricorda: uccidi silenziosamente invece di usare la forza. Così facendo non attiverai gli allarmi.,覚えておいて:静かに殺す時はナイフか毒矢だ。警報を鳴らすと厄介なことになる。,기억해: 소음 없이 조용히 죽여. 그럼 경보를 울리지 않을 테니까.,Onthoud: dood met heimelijke in plaats van met geweld. Je laat de alarmen niet afgaan.,"Husk: drep i det skjulte, ikke med makt. Du vil ikke utløse alarmen.","Pamiętaj: zabijaj ukradkiem, a nie siłą. Nie uruchomisz w ten sposób alarmów.",Lembre-se: mate com cautela ao invés de força. Assim você não ativará os alarmes.,,Ține minte: ucide subtil în loc de forță brută. Nu vei declanșa alarma.,"Запомни: убивай бесшумно, не лезь на рожон, и ты не поднимешь тревогу.",,Unutmayın: güç yerine gizlilikle öldürün. Alarmları çalıştırmazsın. +発電所に近い所だ。",이롤리는 프론트의 수리공이기도 해. 무기상점 근처에 그의 가게로 향하는 문이 있을 거야.,"Irale is de ""fixer"" van de Front. Hij zit achter de ongemarkeerde deur naast de wapenwinkel.","Irale er Frontens ""fikser"". Han er bak den umerkede døren ved siden av våpenbutikken.","Irale to ""załatwiacz"" Frontu. Jest za nieoznakowanymi drzwiami obok sklepu z bronią.","Irale é o ""quebra-galho"" da Frente. Ele está atrás da porta desmarcada próxima ao depósito de armas.",,"Irale e ""reparatorul"" Frontului. E în spatele ușii fără însemn lângă magazinul de arme.",Ирэйл — «наладчик» Сопротивления. Ты найдёшь его за дверью без вывески возле оружейного магазина.,,"Irale är frontens ""fixare"". Han finns bakom den omärkta dörren bredvid vapenbutiken.","İrale, Cephe'nin ""iş bitiricisi"". Silah dükkanının yanındaki işaretlenmemiş kapının arkasında." +Remember: kill with stealth instead of force. You won't set off the alarms.,TXT_SUB_LOG6,MAP02,,,Pamatuj: Zabíjej potichu. Nespustíš poplach.,Husk: Dræb med list i stedet for med magt. Du vil ikke udløse alarmen.,Denk daran: Töte lautlos und du wirst den Alarm nicht auslösen.,,,Recuerda: mata con sigilo y no con fuerza para no activar las alarmas.,,Muista: tapa huomaamattomasti voiman sijasta. Niin vältät hälytyksen.,"Souviens-toi: Tue avec discrétion, pas avec force, et tu n'activeras pas les alarmes.","Figyelj arra, hogy lopakodva ölj, ne erővel. Így nem indítod be a riasztót.",Ricorda: uccidi silenziosamente invece di usare la forza. Così facendo non attiverai gli allarmi.,覚えておいて:静かに殺す時はナイフか毒矢だ。警報を鳴らすと厄介なことになる。,기억해: 소음 없이 조용히 죽여. 그럼 경보를 울리지 않을 테니까.,Onthoud: dood met heimelijke in plaats van met geweld. Je laat de alarmen niet afgaan.,"Husk: drep i det skjulte, ikke med makt. Du vil ikke utløse alarmen.","Pamiętaj: zabijaj ukradkiem, a nie siłą. Nie uruchomisz w ten sposób alarmów.",Lembre-se: mate com cautela ao invés de força. Assim você não ativará os alarmes.,,Ține minte: ucide subtil în loc de forță brută. Nu vei declanșa alarma.,"Запомни: убивай бесшумно, не лезь на рожон, и ты не поднимешь тревогу.",,Kom ihåg: döda med smygande i stället för med våld. Du kommer inte att utlösa larmen.,Unutmayın: güç yerine gizlilikle öldürün. Alarmları çalıştırmazsın. "All I know about the governor is that he's playing both sides to the middle. Here's his so-called ""mansion.""",TXT_SUB_LOG7,MAP03: After joining the Front and going to Mourel's mansion.,,,"O guvernérovi vím jen to, že se snaží uhrávat sympatie obou stran. Tohle je jeho rádoby „sídlo“.","Alt jeg ved om guvernøren er, at han spiller begge sider til midten. Her er hans såkaldte ""palæ"".","Vom Gouverneur weiß ich nur, dass er beide Seiten gegeneinander ausspielt. Hier ist seine sogenannte „Villa.“",,,Todo lo que sé del gobernador es que juega entre ambos bandos. Aquí está su supesta «mansión».,,"Tiedän kuvernööristä vain sen, että hän pelaa keskellä molemmilla puolilla. Tässä on hänen niin sanottu ""kartanonsa"".","Tout ce que je sais au sujet du gouverneur est qu'il est un agent double de chaque côté. Voilà son soi-disant ""manoir"".","Csak annyit tudok a kormányzóról, hogy mindenkét oldalnak dolgozik. Itt az úgynevezett ""kúriája"".",Tutto ciò che so sul governatore è che cerca di mettere gli uni contro gli altri per beneficio personale. Ecco la sua cosidetta dimora.,"私が知事について知っていることは、町の中央で双方を遊ばせてる様だ。 -ソイツがここいらを'マンション'と呼んでいる。",내가 알기로는 모렐 총독은 두 세력을 가지고 노는 걸 좋아한대. 여기는 그의 '저택'이라는 곳이야.,"Het enige wat ik van de gouverneur weet is dat hij beide kanten van de gouverneur naar het midden speelt. Hier is zijn zogenaamde ""herenhuis"".","Alt jeg vet om guvernøren, er at han spiller på begge sider. Her er hans såkalte ""herskapshus"".","O gubernatorze wiem tylko tyle, że gra na dwie strony. Oto jego tak zwana ""rezydencja"".","Tudo o que eu sei sobre o governador é que ele está jogando entre dois lados. Aqui fica a sua suposta ""mansão"".",,"Tot ce știu despre Guvernator e că plătește ambele tabere. Aici e așa-zisul lui ""complex"".","Я знаю о губернаторе только то, что он пытается подыграть обеим сторонам, оставаясь посередине. Вот его так называемый «особняк».",,"Vali hakkında bildiğim tek şey, iki tarafı da ortada oynaması. İşte onun sözde ""malikanesi""." -Ugh. The dregs of humanity have certainly found a home.,TXT_SUB_LOG8,,,,Fuj. Spodina lidstva si rozhodně našla domov.,Ugh. Menneskehedens bundfald har bestemt fundet et hjem.,Ugh. Der Bodensatz der Menschheit hat definitiv ein Zuhause gefunden.,,,Ugh. La basura humana ciertamente ha encontrado un hogar.,,"Yöh, ihmiskunnan pohjasakka on selvästikin löytänyt kodin.","Eugh, les loques de l'humanité ont trouvé leur maison, on dirait.",Fúj. Az emberiség söpredéke csak talált magának egy otthont.,Ugh. La feccia dell'umanità ha certamente trovato una casa adatta.,,"으윽, 우리 중 나쁜 놈들만 보금자리를 구한 것 같네.",Ugh. De bezinksels van de mensheid hebben zeker een thuis gevonden.,Ugh. Menneskehetens bunnfall har virkelig funnet et hjem.,Ugh. Resztki ludzkości na pewno znalazły dom.,Urgh. A escória da humanidade certamente encontrou um lar.,,Ugh. Scursurile umanității și-au găsit o casă cu siguranță.,Фу. Самое место для отбросов человечества.,,Ugh. İnsanlığın tortuları kesinlikle bir yuva bulmuş. +ソイツがここいらを'マンション'と呼んでいる。",내가 알기로는 모렐 총독은 두 세력을 가지고 노는 걸 좋아한대. 여기는 그의 '저택'이라는 곳이야.,"Het enige wat ik van de gouverneur weet is dat hij beide kanten van de gouverneur naar het midden speelt. Hier is zijn zogenaamde ""herenhuis"".","Alt jeg vet om guvernøren, er at han spiller på begge sider. Her er hans såkalte ""herskapshus"".","O gubernatorze wiem tylko tyle, że gra na dwie strony. Oto jego tak zwana ""rezydencja"".","Tudo o que eu sei sobre o governador é que ele está jogando entre dois lados. Aqui fica a sua suposta ""mansão"".",,"Tot ce știu despre Guvernator e că plătește ambele tabere. Aici e așa-zisul lui ""complex"".","Я знаю о губернаторе только то, что он пытается подыграть обеим сторонам, оставаясь посередине. Вот его так называемый «особняк».",,"Allt jag vet om guvernören är att han spelar båda sidor till mitten. Här är hans så kallade ""herrgård"".","Vali hakkında bildiğim tek şey, iki tarafı da ortada oynaması. İşte onun sözde ""malikanesi""." +Ugh. The dregs of humanity have certainly found a home.,TXT_SUB_LOG8,,,,Fuj. Spodina lidstva si rozhodně našla domov.,Ugh. Menneskehedens bundfald har bestemt fundet et hjem.,Ugh. Der Bodensatz der Menschheit hat definitiv ein Zuhause gefunden.,,,Ugh. La basura humana ciertamente ha encontrado un hogar.,,"Yöh, ihmiskunnan pohjasakka on selvästikin löytänyt kodin.","Eugh, les loques de l'humanité ont trouvé leur maison, on dirait.",Fúj. Az emberiség söpredéke csak talált magának egy otthont.,Ugh. La feccia dell'umanità ha certamente trovato una casa adatta.,,"으윽, 우리 중 나쁜 놈들만 보금자리를 구한 것 같네.",Ugh. De bezinksels van de mensheid hebben zeker een thuis gevonden.,Ugh. Menneskehetens bunnfall har virkelig funnet et hjem.,Ugh. Resztki ludzkości na pewno znalazły dom.,Urgh. A escória da humanidade certamente encontrou um lar.,,Ugh. Scursurile umanității și-au găsit o casă cu siguranță.,Фу. Самое место для отбросов человечества.,,Usch. Mänsklighetens avskum har verkligen hittat ett hem.,Ugh. İnsanlığın tortuları kesinlikle bir yuva bulmuş. Calling Mourel sleazy is paying him a compliment. He's mongrel turd on a stick.,TXT_SUB_LOG9,"MAP02: After accepting ""bloody"" chore.",,,"Nazývat Mourela slizákem by mu lichotilo, svinský parchant jeden prohnilý.",At kalde Mourel sleazy er at give ham en kompliment. Han er en mongolsk lort på en pind.,"Mourel als 'verschlagen' zu bezeichnen wäre, ihm ein Kompliment zu machen. Er ist ein Haufen Hundescheiße.",,,Decirle «sucio» a Mourel es un halago. Es mierda de perro callejero en un palo.,,"Viheliäiseksi nimitteleminen olisi Mourelille vain kohteliaisuus. Hän on kapinen koira, iljettävä paskiainen.",Appeler Mourel un rat serait être gentil. Il est une sacrée brochette de merde.,Mourelt mocskosnak hívni egyfajta bók. Én egy alávaló pálcára húzott szarnak hívnám.,Chiamare Mourel squallido significa fargli un complimento. È uno stronzo bastardo su un palo.,"モーレルにとって汚職議員は誉め言葉だ。 -ソイツはクソを漏らした'駄犬'でしかないからな。",모렐에게 행실이 지저분하다고 말하는 건 칭찬에 불과해. 저놈은 이기적인 똥개새끼라고.,Mourel slordig noemen is een compliment voor hem. Hij is een bastaard op een stokje.,Å kalle Mourel snuskete er å gi ham en kompliment. Han er en kjøterbæsj på en pinne.,Nazwanie Mourela obskurnym to komplement. On jest kundlem na patyku.,Chamar o Mourel de picareta é elogio. Ele é um total desgraçado de merda.,,Numindu-l pe Mourel zgârcit e un compliment. E o corcitură de rahat pe băț.,"Назвать Моурела подлым, значит сделать ему комплимент. Кусок дерьма на палочке...",,Mourel'e adi demek ona iltifat etmektir. O bir sopa üzerindeki melez bok. +ソイツはクソを漏らした'駄犬'でしかないからな。",모렐에게 행실이 지저분하다고 말하는 건 칭찬에 불과해. 저놈은 이기적인 똥개새끼라고.,Mourel slordig noemen is een compliment voor hem. Hij is een bastaard op een stokje.,Å kalle Mourel snuskete er å gi ham en kompliment. Han er en kjøterbæsj på en pinne.,Nazwanie Mourela obskurnym to komplement. On jest kundlem na patyku.,Chamar o Mourel de picareta é elogio. Ele é um total desgraçado de merda.,,Numindu-l pe Mourel zgârcit e un compliment. E o corcitură de rahat pe băț.,"Назвать Моурела подлым, значит сделать ему комплимент. Кусок дерьма на палочке...",,Att kalla Mourel sliskig är en komplimang. Han är en mongolisk skit på en pinne.,Mourel'e adi demek ona iltifat etmektir. O bir sopa üzerindeki melez bok. We need to speak with someone who knows the old town and where this coupling is. Command says: find MacGuffin. ,TXT_SUB_LOG10,"MAP02: After accepting ""messy"" chore and leaving Mourel's room.",,,"Musíme si promluvit s někým, kdo zná staré město a ví, kde se tahle spojka nalézá. Vedení říká najít MacGuffina.","Vi må tale med nogen, der kender den gamle by og ved, hvor denne kobling er. Kommandoen siger: Find MacGuffin.","Wir müssen mit jemandem reden, der die alte Stadt kennt und weiß, wo diese Anzapfung it. Die Kommandozentrale sagt, finde MacGuffin.",,,Necesitamos hablar con alguien que conozca el viejo pueblo y donde se encuentra el acoplamiento. El Comando dice: encuentra a MacGuffin.,,"Meidän täytyy puhua jollekulle, joka tietää vanhan kaupungin ja missä tämä liitin on. Komentokeskus käskee etsiä MacGuffinia.",On doit parler à quelqu'un qui connaît la vieille ville et où se trouve le coupleur. Le commandement me dit qu'il faut trouver MacGuffin.,"Beszélnünk kell valakivel aki ismeri a régi várost, és tudja hol ez az elágazás. A központ szerint fel kell keresnünk MacGuffin-t.",Dobbiamo parlare con qualcuno che conosce la vecchia città e sa dove poter trovare questo aggeggio. Il comando dice: trovate MacGuffin.,"我々は何処にあるかについてはオールドタウンに知っている者がいる。 -指令が言うには マクガフィンに会え。",동력선의 위치를 알 수 있을 만한 토박이 주민과 이야기해봐. 본부가 말하길: 맥거핀을 찾으래.,We moeten met iemand spreken die de oude stad kent en waar deze koppeling is. Het commando zegt: zoek MacGuffin.,Vi må snakke med noen som kjenner gamlebyen og vet hvor koblingen er. Kommandoen sier: Finn MacGuffin.,"Musimy porozmawiać z kimś, kto zna stare miasto i wie, gdzie jest to sprzęgło. Rozkaz mówi: znaleźć MacGuffina.",Precisamos falar com alguém que conheça a velha cidade e onde fica essa conexão. O comando diz: encontre MacGuffin.,,Avem nevoie să vorbim cu cineva care cunoaște vechiul oraș și unde e cuplajul. Centrul de comandă zice: găsește-l pe MacGuffin.,"Нам нужен кто-то, кто знает старый город и может подсказать, где эта муфта. В штабе говорят, что тебе поможет Макгаффин.",,Eski şehri ve bu kuplajın nerede olduğunu bilen biriyle konuşmalıyız. Komuta diyor ki: MacGuffin'i bulun. +指令が言うには マクガフィンに会え。",동력선의 위치를 알 수 있을 만한 토박이 주민과 이야기해봐. 본부가 말하길: 맥거핀을 찾으래.,We moeten met iemand spreken die de oude stad kent en waar deze koppeling is. Het commando zegt: zoek MacGuffin.,Vi må snakke med noen som kjenner gamlebyen og vet hvor koblingen er. Kommandoen sier: Finn MacGuffin.,"Musimy porozmawiać z kimś, kto zna stare miasto i wie, gdzie jest to sprzęgło. Rozkaz mówi: znaleźć MacGuffina.",Precisamos falar com alguém que conheça a velha cidade e onde fica essa conexão. O comando diz: encontre MacGuffin.,,Avem nevoie să vorbim cu cineva care cunoaște vechiul oraș și unde e cuplajul. Centrul de comandă zice: găsește-l pe MacGuffin.,"Нам нужен кто-то, кто знает старый город и может подсказать, где эта муфта. В штабе говорят, что тебе поможет Макгаффин.",,Vi måste tala med någon som känner till den gamla staden och vet var den här kopplingen finns. Kommandot säger: hitta MacGuffin.,Eski şehri ve bu kuplajın nerede olduğunu bilen biriyle konuşmalıyız. Komuta diyor ki: MacGuffin'i bulun. "He's in what's politely called the ""bum hole"". Take the walkway by the sewage plant and head down the stairs.",TXT_SUB_LOG11,"MAP02: After accepting ""messy"" chore and leaving Mourel's mansion.",,,"Najdeš ho na místě, kterému zdvořile říkají „zadnice“. Jdi přes chodník u čističky a sejdi schody.","Han er i det, der høfligt kaldes ""bumshullet"". Tag gangen ved kloakanlægget og gå ned ad trappen.","Er ist, was höflich gesagt, das „Pennerloch“ genannt wird. Gehe zum Weg zur Kläranlage und von dort die Treppe herunter.",,,Está en lo que se conoce educadamente como «la cueva del vagabundo». Toma la pasarela junto a la planta de aguas residuales y baja por las escaleras.,,"Hän majailee kiltisti sanottuna ""pepunreiässä"". Kulje jätelaitoksen viereistä kulkukäytävää pitkin ja portaat alas.","Il se trouve dans ce qu'on appelle poliment le ""trou à rats"", suis la coursive près de la centrale de traitement des égouts et descend les escaliers.","Ott van az udvariasan csak ""kotoréknak"" nevezett helyen. Gyalogolj végig a szennyvíz tisztító hídján, majd le a lépcsőkön.","Si trova in quello che viene affeziosamente chiamato ""il buco dei barboni"". Prendi la passerella dell'impianto fognario e vai sotto le scale.","彼は行儀よく'バムホール'と呼ばれる場所に居る。 -下水処理場の側の階段を下りた小さい部屋だ。",겸손하게 말하자면 그는 “노숙자 굴”에 살아. 하수도에서 보도를 지나간 뒤 계단을 건너.,"Hij zit in wat beleefd het ""kontje"" wordt genoemd. Neem de loopbrug bij de rioolwaterzuiveringsinstallatie en ga de trap af.","Han er i det som høflig kalles ""rumpehullet"". Ta gangveien ved kloakkanlegget og gå ned trappene.","Jest w miejscu, które grzecznie nazywa się ""bum hole"". Skorzystaj z przejścia przy oczyszczalni ścieków i skieruj się w dół po schodach.","Ele está num lugar chamado ""toca de rato"". Vá pela passarela perto da usina de tratamento e desça as escadas.",,"E în ceea ce se cheamă politicos ""groapa de ardere"". Ia pasarela de lângă fabrica de deșeuri și coboară scările.","Он в том месте, что вежливо называют «бомжевая нора». Пройди к очистным сооружениям и спустись по лестнице.",,"Kibarca ""serseri deliği"" denilen yerde. Lağım tesisinin yanındaki geçidi kullanın ve merdivenlerden aşağı inin." -Take your time with this mission. I can't get intel on this from Command.,TXT_SUB_LOG12,"MAP02: During ""messy"" chore.",,,Dej si s touhle misí na čas. Nemůžu z velení dostat žádné informace.,Tag dig god tid med denne mission. Jeg kan ikke få oplysninger om dette fra Command.,Nimm dir Zeit für diese Mission. Ich erhalte keine Informationen aus der Kommandozentrale.,,,Tómate tu tiempo en esta misión. No consigo información de esto con el Comando.,,Ei mitään kiirettä tämän tehtävän kanssa; komentokeskuksella ei ole antaa tiedustelutietoja.,"Prends ton temps, le commandement n'a rien à me donner au niveau informations.",Ne siesd el a küldetést. Nem tudtam kideríteni semmi érdemlegeset az Irányítástól.,Prenditi il tempo che ti serve per questa missione. Non mi stanno dando molte informazioni dal comando.,この任務は時間が掛かりそうだ。私は司令部からこれ以上の情報は得る事は出来ない。,느긋하게 수행해도 좋아. 본부에도 이 정보를 모으는 데 문제가 있데.,Neem je tijd met deze missie. Ik kan hier geen informatie over krijgen van de Commandant.,Ta deg god tid med dette oppdraget. Jeg kan ikke få informasjon om dette fra kommandoen.,Nie spiesz się z tą misją. Nie mogę uzyskać informacji na ten temat od dowództwa.,Não tenha pressa nesta missão. Não estou conseguindo obter inteligência sobre isso pelo Comando.,,Poți să petreci mai mult timp cu misiunea. Nu pot găsi mai multe informații de la Centru.,Не торопись с выполнением этого задания. Я не могу получить разведданные от штаба.,,Bu görevde acele etmeyin. Komuta'dan bu konuda bilgi alamıyorum. +下水処理場の側の階段を下りた小さい部屋だ。",겸손하게 말하자면 그는 “노숙자 굴”에 살아. 하수도에서 보도를 지나간 뒤 계단을 건너.,"Hij zit in wat beleefd het ""kontje"" wordt genoemd. Neem de loopbrug bij de rioolwaterzuiveringsinstallatie en ga de trap af.","Han er i det som høflig kalles ""rumpehullet"". Ta gangveien ved kloakkanlegget og gå ned trappene.","Jest w miejscu, które grzecznie nazywa się ""bum hole"". Skorzystaj z przejścia przy oczyszczalni ścieków i skieruj się w dół po schodach.","Ele está num lugar chamado ""toca de rato"". Vá pela passarela perto da usina de tratamento e desça as escadas.",,"E în ceea ce se cheamă politicos ""groapa de ardere"". Ia pasarela de lângă fabrica de deșeuri și coboară scările.","Он в том месте, что вежливо называют «бомжевая нора». Пройди к очистным сооружениям и спустись по лестнице.",,"Han är i det som artigt kallas ""bum-hålet"". Ta gången vid avloppsanläggningen och gå ner för trapporna.","Kibarca ""serseri deliği"" denilen yerde. Lağım tesisinin yanındaki geçidi kullanın ve merdivenlerden aşağı inin." +Take your time with this mission. I can't get intel on this from Command.,TXT_SUB_LOG12,"MAP02: During ""messy"" chore.",,,Dej si s touhle misí na čas. Nemůžu z velení dostat žádné informace.,Tag dig god tid med denne mission. Jeg kan ikke få oplysninger om dette fra Command.,Nimm dir Zeit für diese Mission. Ich erhalte keine Informationen aus der Kommandozentrale.,,,Tómate tu tiempo en esta misión. No consigo información de esto con el Comando.,,Ei mitään kiirettä tämän tehtävän kanssa; komentokeskuksella ei ole antaa tiedustelutietoja.,"Prends ton temps, le commandement n'a rien à me donner au niveau informations.",Ne siesd el a küldetést. Nem tudtam kideríteni semmi érdemlegeset az Irányítástól.,Prenditi il tempo che ti serve per questa missione. Non mi stanno dando molte informazioni dal comando.,この任務は時間が掛かりそうだ。私は司令部からこれ以上の情報は得る事は出来ない。,느긋하게 수행해도 좋아. 본부에도 이 정보를 모으는 데 문제가 있데.,Neem je tijd met deze missie. Ik kan hier geen informatie over krijgen van de Commandant.,Ta deg god tid med dette oppdraget. Jeg kan ikke få informasjon om dette fra kommandoen.,Nie spiesz się z tą misją. Nie mogę uzyskać informacji na ten temat od dowództwa.,Não tenha pressa nesta missão. Não estou conseguindo obter inteligência sobre isso pelo Comando.,,Poți să petreci mai mult timp cu misiunea. Nu pot găsi mai multe informații de la Centru.,Не торопись с выполнением этого задания. Я не могу получить разведданные от штаба.,,Ta god tid på dig med det här uppdraget. Jag kan inte få information om detta från kommandot.,Bu görevde acele etmeyin. Komuta'dan bu konuda bilgi alamıyorum. "You idiot! You've shut off the power to the jamming circuits we use to conceal our base from the Order. Head over to the town hall and take out the scanning crew, now!",TXT_SUB_LOG13,MAP02: After destroying Front's power coupling.,,,"Ty debile! Odstřihnul jsi přívod proudu do rušiček, které používáme, abychom ukryli naší základnu před Řádem. Okamžitě si to zamiř k radnici a vybij průzkumnou četu!","Din idiot! Du har slukket for strømmen til de jamming-kredsløb, vi bruger til at skjule vores base for Ordenen. Gå over til rådhuset og udryd scanningsholdet, nu!","Du Idiot! Du hast die Energie für unsere Störsender unterbrochen, mit denen wir unsere Basis vor dem Orden verborgen haben. Geh schnell zum Rathaus und schalte den Suchtrupp aus. ",,,"¡Idiota! Has apagado la energía de los circuitos de interferencia que usamos para ocultarle nuestra base a La Orden. Dirígete al ayuntamiento y elimina al equipo de escaneo, ¡ya!","¡Idiota! Apagaste la energía de los circuitos de interferencia que usamos para ocultarle nuestra base a La Orden. Dirígete al ayuntamiento y elimina al equipo de escaneo, ¡ya!","Sinä idiootti! Olet katkaissut virran häirintäpiireihin, joilla piilotamme sijaintimme Veljeskunnalta. Suuntaa kaupungintalolle ja hoitele tiedusteluryhmä, heti paikalla!",Idiot! Tu as désactivé les circuits brouilleurs qui cachaient notre base des senseurs de l'Ordre. Retourne vite à la mairie et tue l'équipe de scan maintenant!,"Te idióta! Lelőtted az áramot a zavaró áramkörökhöz, amivel a Rend elől rejtettük el a bázist. Menj a városházára, és iktasd ki a szkennelő legénységet azonnal!","Idiota! Hai interrotto il flusso di energia dei circuiti che usavamo per nascondere la nostra base dall'Ordine. Ritorna subito al municipio e fai fuori il gruppo venuto a perlustare la zona, ora!","馬鹿者!お前はオーダーから我々の基地を隠す妨害回路を壊してしまった! -市庁舎に調査隊が向かった、今すぐ片付けろ!",이 멍청이야! 우리 기지를 오더로부터 은폐시켜주는 교란 장치의 동력을 끊어버렸잖아. 당장 시청으로 가서 탐색반들을 쓸어버려! 그다음에 총독에게 부서진 장치를 전해. 당장!,"Idioot! Je hebt de stroom naar de stoorcircuits die we gebruiken om onze basis te verbergen voor de Orde uitgeschakeld. Ga naar het stadhuis en haal de scannende bemanning eruit, nu!","Din idiot! Du har slått av strømmen til blokkeringskretsene vi bruker for å skjule basen vår for Ordenen. Dra til rådhuset og drep skannerne, nå!","Ty idioto! Wyłączyłeś zasilanie obwodów zagłuszających, których używamy do ukrycia naszej bazy przed Zakonem. Idź do ratusza i zdejmij ekipę skanującą, natychmiast!",Seu idiota! Você desligou a energia para os circuitos de interferência que usamos para esconder a nossa base dos sensores da Ordem. Vá até a prefeitura e tire a equipe de busca de lá imediatamente!,,"Idiotule! Ai oprit energia către circuitele noastre care ne permiteau să ne ascundem de Ordin. Du-te în hala vechiului oraș și elimină echipajul, acum!","Идиот! Ты обесточил генератор радиопомех, с помощью которого мы скрывали местоположение нашей базы от Ордена. Возвращайся к ратуше и уничтожь разведывательную группу как можно скорее!",,"Seni salak! Üssümüzü Düzen'den gizlemek için kullandığımız sinyal bozucu devrelerin gücünü kesmişsin. Belediye binasına git ve tarama ekibini indir, hemen!" -"OK, ""Trust no one"" is the name of the game! Let's get that pass from the Governor and free those prisoners.",TXT_SUB_LOG14,MAP02: After destroying Front's power coupling and killing all blue acolytes in the town hall.,,,"Dobře, „Nevěř nikomu“ je motto hry! Pojďme od guvernéra dostat tu propustku a osvoboďme ty vězně.","Okay, ""Stol ikke på nogen"" er det, der gælder! Lad os få den tilladelse fra guvernøren og befri de fanger.","Ok, „Trau keinem“ heißt dieses Spiel. Lass uns den Gefängnispass vom Gouverneur holen und die Gefangenen befreien.",,,"Vale, ¡«No te fies de nadie» se llama el juego! Ya es hora de conseguir ese pase del Gobernador y liberar a esos prisioneros.","Bueno, ¡«No confíes en nadie» se llama el juego! Ya es hora de conseguir ese pase del Gobernador y liberar a esos prisioneros.","Selvä, ""Älä luota kehenkään"" on näköjään pelin nimi! Hankitaan pääsylupa kuvernööriltä ja vapautetaan ne vangit.","Ok, ""ne fais confiance à personne"" est le thème du jour. Récupérons le passe du gouverneur et libérons les prisonniers.","Rendben, a ""ne bízz senkiben"" elv szerint játszunk. Akkor vegyük el a kormányzótól a belépőt, és szabadítsuk ki a rabokat.","OK, ""Non fidarti di nessuno"" è il gioco che stiamo giocando qua! Prendiamo quel pass per la prigione dal governatore.",よし、'信用しない'のが最も重要なことだ!壊れた配電機を渡して囚人を解放するんだ。,"좋아, '아무도 믿지 말라'가 이 게임의 이름이겠군! 그냥 총독과 대화하고 수감자들을 구출하자.","OK, ""Vertrouw niemand"" is de naam van het spel! Laten we die pas van de gouverneur halen en die gevangenen vrijlaten.","OK, ""Stol ikke på noen"" er navnet på spillet! La oss få det passet fra guvernøren og befri fangene.","OK, ""Nie ufaj nikomu"" to nazwa gry! Zdobądźmy tę przepustkę od gubernatora i uwolnijmy tych więźniów.","Ok, ""não confie em ninguém"" é o nome do jogo! Vamos pegar aquele passe do Governador e libertar esses prisioneiros.",,"OK, ""N-ai încredere în nimeni"" e numele jocului. Să luăm acea parolă de la guvernator și să eliberăm prizonierii.","Что ж, эта игра называется «не верь никому»! Давай получим у губернатора пропуск в тюрьму и освободим пленников.",,"Tamam, ""Kimseye güvenme"" oyunun adı! Vali'den o izni alalım ve mahkumları serbest bırakalım." +市庁舎に調査隊が向かった、今すぐ片付けろ!",이 멍청이야! 우리 기지를 오더로부터 은폐시켜주는 교란 장치의 동력을 끊어버렸잖아. 당장 시청으로 가서 탐색반들을 쓸어버려! 그다음에 총독에게 부서진 장치를 전해. 당장!,"Idioot! Je hebt de stroom naar de stoorcircuits die we gebruiken om onze basis te verbergen voor de Orde uitgeschakeld. Ga naar het stadhuis en haal de scannende bemanning eruit, nu!","Din idiot! Du har slått av strømmen til blokkeringskretsene vi bruker for å skjule basen vår for Ordenen. Dra til rådhuset og drep skannerne, nå!","Ty idioto! Wyłączyłeś zasilanie obwodów zagłuszających, których używamy do ukrycia naszej bazy przed Zakonem. Idź do ratusza i zdejmij ekipę skanującą, natychmiast!",Seu idiota! Você desligou a energia para os circuitos de interferência que usamos para esconder a nossa base dos sensores da Ordem. Vá até a prefeitura e tire a equipe de busca de lá imediatamente!,,"Idiotule! Ai oprit energia către circuitele noastre care ne permiteau să ne ascundem de Ordin. Du-te în hala vechiului oraș și elimină echipajul, acum!","Идиот! Ты обесточил генератор радиопомех, с помощью которого мы скрывали местоположение нашей базы от Ордена. Возвращайся к ратуше и уничтожь разведывательную группу как можно скорее!",,"Din idiot! Du har stängt av strömmen till störningskretsarna som vi använder för att dölja vår bas för Orden. Gå över till stadshuset och ta ut skanningspersonalen, nu!","Seni salak! Üssümüzü Düzen'den gizlemek için kullandığımız sinyal bozucu devrelerin gücünü kesmişsin. Belediye binasına git ve tarama ekibini indir, hemen!" +"OK, ""Trust no one"" is the name of the game! Let's get that pass from the Governor and free those prisoners.",TXT_SUB_LOG14,MAP02: After destroying Front's power coupling and killing all blue acolytes in the town hall.,,,"Dobře, „Nevěř nikomu“ je motto hry! Pojďme od guvernéra dostat tu propustku a osvoboďme ty vězně.","Okay, ""Stol ikke på nogen"" er det, der gælder! Lad os få den tilladelse fra guvernøren og befri de fanger.","Ok, „Trau keinem“ heißt dieses Spiel. Lass uns den Gefängnispass vom Gouverneur holen und die Gefangenen befreien.",,,"Vale, ¡«No te fies de nadie» se llama el juego! Ya es hora de conseguir ese pase del Gobernador y liberar a esos prisioneros.","Bueno, ¡«No confíes en nadie» se llama el juego! Ya es hora de conseguir ese pase del Gobernador y liberar a esos prisioneros.","Selvä, ""Älä luota kehenkään"" on näköjään pelin nimi! Hankitaan pääsylupa kuvernööriltä ja vapautetaan ne vangit.","Ok, ""ne fais confiance à personne"" est le thème du jour. Récupérons le passe du gouverneur et libérons les prisonniers.","Rendben, a ""ne bízz senkiben"" elv szerint játszunk. Akkor vegyük el a kormányzótól a belépőt, és szabadítsuk ki a rabokat.","OK, ""Non fidarti di nessuno"" è il gioco che stiamo giocando qua! Prendiamo quel pass per la prigione dal governatore.",よし、'信用しない'のが最も重要なことだ!壊れた配電機を渡して囚人を解放するんだ。,"좋아, '아무도 믿지 말라'가 이 게임의 이름이겠군! 그냥 총독과 대화하고 수감자들을 구출하자.","OK, ""Vertrouw niemand"" is de naam van het spel! Laten we die pas van de gouverneur halen en die gevangenen vrijlaten.","OK, ""Stol ikke på noen"" er navnet på spillet! La oss få det passet fra guvernøren og befri fangene.","OK, ""Nie ufaj nikomu"" to nazwa gry! Zdobądźmy tę przepustkę od gubernatora i uwolnijmy tych więźniów.","Ok, ""não confie em ninguém"" é o nome do jogo! Vamos pegar aquele passe do Governador e libertar esses prisioneiros.",,"OK, ""N-ai încredere în nimeni"" e numele jocului. Să luăm acea parolă de la guvernator și să eliberăm prizonierii.","Что ж, эта игра называется «не верь никому»! Давай получим у губернатора пропуск в тюрьму и освободим пленников.",,"Okej, ""Lita inte på någon"" är vad som gäller! Låt oss få det där passet från guvernören och befria fångarna.","Tamam, ""Kimseye güvenme"" oyunun adı! Vali'den o izni alalım ve mahkumları serbest bırakalım." Good move! The Governor is a lousy liar. That's our power coupling. Now let's get that pass.,TXT_SUB_LOG15,MAP02: After finding the broken power coupling.,,,"Dobrý tah! Guvernér je mizerný lhář, tohle je naše spojka. Tak si pojďme pro tu propustku.",Godt gået! Guvernøren er en elendig løgner. Det er vores kraftkobling. Lad os nu få fat i det pas.,Das war klasse! Der Gouverneur ist ein lausiger Lügner. Das war unsere Anzapfung. Nun lass uns den Pass holen.,,,¡Buen ojo! El gobernador es un mentiroso: ese era nuestro acoplador de energía. Ahora consigamos ese pase.,,Hyvä veto! Kuvernööri on surkea valehtelija. Se on meidän virtaliittimemme. Nyt sitten hankitaan se pääsylupa.,Bien joué! Le gouverneur est un menteur. Voilà notre coupleur. Allons récupérer le passe.,Jól tetted! A Kormányzó egy hazug disznó. Az a mi áramcsatolónk. Most pedig irány a belépő.,Ottima mossa! Il governatore è un bugiardo. Eravamo noi a utilizzare questo marchingegno collegato alla rete. Ora andiamo a prendere quel pass.,"良い判断よ!知事は粗末な嘘を付いている。 あれはオーダーから基地を隠す為に使用している我々の配電機だ。 -この壊れた配電機を渡して彼を騙し返そう。",참 잘했어! 총독이 거짓말을 했군. 이건 우리의 동력 장치야. 어서 전해주자!,Goede zet! De Gouverneur is een slechte leugenaar. Dat is onze krachtkoppeling. Laten we nu die pas pakken.,Godt trekk! Guvernøren er en elendig løgner. Det er kraftkoblingen vår. La oss få tak i passet.,Dobry ruch! Gubernator to kiepski kłamca. To nasze połączenie sił. Teraz zdobądźmy tę przepustkę.,"Boa! O Governador é um mentiroso desgraçado. Esse é a nossa conexão. Agora, vamos pegar aquele passe.",,Bună mutare! Gvuvernatorul e un mincinos prost. Acela e cuplajul nostru. Acum să luăm parola.,Отличный ход! Губернатор — мерзкий лжец. Это наше подключение к силовой линии. Теперь получи пропуск.,,İyi hamle! Vali berbat bir yalancı. Bu bizim güç birleşimimiz. Şimdi şu izni alalım. -The warehouse is in the power station. Let's make this short and sweet.,TXT_SUB_LOG16,"MAP02: After accepting ""bloody"" chore.",,,"Skladiště je uvnitř elektrárny. Pojďme na to, ať to máme rychle za sebou.",Lageret er i kraftværket. Lad os gøre det kort og godt.,Das Lagerhaus ist im Kraftwerk. Lass uns das schnell erledigen.,,,El almacén está en la central eléctrica. Hagamos esto bien rápido.,,Varasto on voimalaitoksella. Hoidetaan tämä nätisti ja pikaisesti.,L'entrepôt se trouve dans la centrale électrique. On va faire ça rapidement et proprement.,A raktár egy erőmű. Oldjuk meg gyorsan és hatékonyan.,Il magazzino si trova nella centrale energetica. Cerchiamo di essere rapidi e puliti.,倉庫は発電所にある。さっさと済ませよう。,창고는 발전소 근처에 있어. 어서 신속하고 죽여주게 끝내자.,Het magazijn is in de energiecentrale. Laten we dit kort en bondig houden.,Lageret er i kraftstasjonen. La oss gjøre det kort og godt.,Magazyn jest w elektrowni. Niech to będzie krótkie i słodkie.,O depósito fica na usina de energia. Vamos fazer isso bem rápido.,,Depozitul e în stația de energie. Scurt și dulce.,Речь идёт о складе в электростанции. Давай сделаем это быстро и с огоньком.,,Depo elektrik santralinde. Bunu kısa ve tatlı tutalım. -I never thought I'd break into prison...,TXT_SUB_LOG17,MAP02: About to enter Norwall Prison.,,,"Nikdy by mě nenapadlo, že se budu vkrádat do vězení...","Jeg troede aldrig, at jeg skulle bryde ind i et fængsel...","Ich hätte nie gedacht, in ein Gefängnis einzubrechen...",,"Mi neniam pensis, ke mi invadus malliberejon...",Nunca imaginé que irrumpiría en una prisión...,,En olisi ikinä uskonut murtautuvani vankilaan...,J'aurais jamais cru entrer de force dans une prison..,"Sosem gondoltam volna, hogy betörök egy börtönbe...",Non avrei mai pensato di entrare in prigione...,刑務所にお勤めになるなぞ考えた事もないぞ...,"감옥을 뚫고 들어가다니, 생각도 못 했는데?",Ik had nooit gedacht dat ik zou inbreken in de gevangenis....,Jeg trodde aldri jeg skulle bryte meg inn i et fengsel...,"Nigdy nie sądziłem, że włamię się do więzienia...",Nunca achei que eu invadiria uma prisão...,,N-am crezut că o să intru într-o închisoare...,"Никогда не думала, что приду в тюрьму добровольно...",,Hapishaneye gireceğimi hiç düşünmemiştim. -Guess there's no free lunch. Time to lock and load.,TXT_SUB_LOG18,MAP05: After crossing the alarm green door.,,,Holt nic není zadarmo. Nabij zbraň a jdi do toho.,Der er vist ingen gratis frokost. Tid til at låse og læsse.,Es gibt wohl keine freie Mahlzeit. Ran an die Action.,,,Supongo que no hay comida gratis. Hora de la acción.,,Ilmaista lounasta ei kai olekaan. Aika laittaa kovat piippuun.,"On dirait qu'il n'y a pas de repas gratuit, il est temps de se préparer au combat.",Úgy néz ki nincs ingyen ebéd. Akkor idő felfegyverkezni.,Immagino non ci sia del pranzo gratuito. È ora di dargli una lezione.,まあタダでは済まないか。派手に暴れてやれ。,급식 먹을 시간은 없겠네. 요리할 시간이야.,Ik denk dat er geen gratis lunch is. Tijd om te sluiten en te laden.,Man får visst ikke noe gratis. På tide å låse og laste.,Chyba nie ma darmowego lunchu. Czas zamknąć i załadować.,Parece que não existe almoço grátis. É hora da ação.,,Presupun că nu e niciun prânz gratuit. Timpul să ne pregătim.,"Что ж, бесплатный сыр бывает только в мышеловке. Оружие к бою! ",,Sanırım bedava öğle yemeği yok. Kilitleme ve yükleme zamanı. +この壊れた配電機を渡して彼を騙し返そう。",참 잘했어! 총독이 거짓말을 했군. 이건 우리의 동력 장치야. 어서 전해주자!,Goede zet! De Gouverneur is een slechte leugenaar. Dat is onze krachtkoppeling. Laten we nu die pas pakken.,Godt trekk! Guvernøren er en elendig løgner. Det er kraftkoblingen vår. La oss få tak i passet.,Dobry ruch! Gubernator to kiepski kłamca. To nasze połączenie sił. Teraz zdobądźmy tę przepustkę.,"Boa! O Governador é um mentiroso desgraçado. Esse é a nossa conexão. Agora, vamos pegar aquele passe.",,Bună mutare! Gvuvernatorul e un mincinos prost. Acela e cuplajul nostru. Acum să luăm parola.,Отличный ход! Губернатор — мерзкий лжец. Это наше подключение к силовой линии. Теперь получи пропуск.,,Bra gjort! Guvernören är en usel lögnare. Det är vår maktkoppling. Nu ska vi få det där passet.,İyi hamle! Vali berbat bir yalancı. Bu bizim güç birleşimimiz. Şimdi şu izni alalım. +The warehouse is in the power station. Let's make this short and sweet.,TXT_SUB_LOG16,"MAP02: After accepting ""bloody"" chore.",,,"Skladiště je uvnitř elektrárny. Pojďme na to, ať to máme rychle za sebou.",Lageret er i kraftværket. Lad os gøre det kort og godt.,Das Lagerhaus ist im Kraftwerk. Lass uns das schnell erledigen.,,,El almacén está en la central eléctrica. Hagamos esto bien rápido.,,Varasto on voimalaitoksella. Hoidetaan tämä nätisti ja pikaisesti.,L'entrepôt se trouve dans la centrale électrique. On va faire ça rapidement et proprement.,A raktár egy erőmű. Oldjuk meg gyorsan és hatékonyan.,Il magazzino si trova nella centrale energetica. Cerchiamo di essere rapidi e puliti.,倉庫は発電所にある。さっさと済ませよう。,창고는 발전소 근처에 있어. 어서 신속하고 죽여주게 끝내자.,Het magazijn is in de energiecentrale. Laten we dit kort en bondig houden.,Lageret er i kraftstasjonen. La oss gjøre det kort og godt.,Magazyn jest w elektrowni. Niech to będzie krótkie i słodkie.,O depósito fica na usina de energia. Vamos fazer isso bem rápido.,,Depozitul e în stația de energie. Scurt și dulce.,Речь идёт о складе в электростанции. Давай сделаем это быстро и с огоньком.,,Magasinet finns i kraftstationen. Låt oss göra det här kort och gott.,Depo elektrik santralinde. Bunu kısa ve tatlı tutalım. +I never thought I'd break into prison...,TXT_SUB_LOG17,MAP02: About to enter Norwall Prison.,,,"Nikdy by mě nenapadlo, že se budu vkrádat do vězení...","Jeg troede aldrig, at jeg skulle bryde ind i et fængsel...","Ich hätte nie gedacht, in ein Gefängnis einzubrechen...",,"Mi neniam pensis, ke mi invadus malliberejon...",Nunca imaginé que irrumpiría en una prisión...,,En olisi ikinä uskonut murtautuvani vankilaan...,J'aurais jamais cru entrer de force dans une prison..,"Sosem gondoltam volna, hogy betörök egy börtönbe...",Non avrei mai pensato di entrare in prigione...,刑務所にお勤めになるなぞ考えた事もないぞ...,"감옥을 뚫고 들어가다니, 생각도 못 했는데?",Ik had nooit gedacht dat ik zou inbreken in de gevangenis....,Jeg trodde aldri jeg skulle bryte meg inn i et fengsel...,"Nigdy nie sądziłem, że włamię się do więzienia...",Nunca achei que eu invadiria uma prisão...,,N-am crezut că o să intru într-o închisoare...,"Никогда не думала, что приду в тюрьму добровольно...",,Jag trodde aldrig att jag skulle bryta mig in i ett fängelse...,Hapishaneye gireceğimi hiç düşünmemiştim. +Guess there's no free lunch. Time to lock and load.,TXT_SUB_LOG18,MAP05: After crossing the alarm green door.,,,Holt nic není zadarmo. Nabij zbraň a jdi do toho.,Der er vist ingen gratis frokost. Tid til at låse og læsse.,Es gibt wohl keine freie Mahlzeit. Ran an die Action.,,,Supongo que no hay comida gratis. Hora de la acción.,,Ilmaista lounasta ei kai olekaan. Aika laittaa kovat piippuun.,"On dirait qu'il n'y a pas de repas gratuit, il est temps de se préparer au combat.",Úgy néz ki nincs ingyen ebéd. Akkor idő felfegyverkezni.,Immagino non ci sia del pranzo gratuito. È ora di dargli una lezione.,まあタダでは済まないか。派手に暴れてやれ。,급식 먹을 시간은 없겠네. 요리할 시간이야.,Ik denk dat er geen gratis lunch is. Tijd om te sluiten en te laden.,Man får visst ikke noe gratis. På tide å låse og laste.,Chyba nie ma darmowego lunchu. Czas zamknąć i załadować.,Parece que não existe almoço grátis. É hora da ação.,,Presupun că nu e niciun prânz gratuit. Timpul să ne pregătim.,"Что ж, бесплатный сыр бывает только в мышеловке. Оружие к бою! ",,Det finns ingen gratis lunch. Dags att låsa och ladda.,Sanırım bedava öğle yemeği yok. Kilitleme ve yükleme zamanı. "OK. You've pleased the Governor, splattered the Warden... Now it looks like we got to have to do a little surgery.",TXT_SUB_LOG19,MAP05: After getting to Main Control.,,,"Dobrá. Uspokojil jsi guvernéra, rozmetal dozorčího... Vypadá to, že teď budeme muset provést menší operaci.","OKAY. Du har tilfredsstillet guvernøren, plettet fængselsinspektøren... Nu ser det ud til, at vi må foretage en lille operation.","Ok, du hast den Gouverneur zufriedengestellt, den Direktor abgemetzelt... Und jetzt sieht es aus als ob eine kleine Operation nötig ist.",,,"Bueno, has satisfecho al Gobernador, despedazado al Carcelero... Y ahora parece que tendremos que hacer algo de cirugía.",,"No niin, olet tehnyt kuvernöörille mieliksi: suolannut vankilanjohtajan... Mutta näyttää siltä, että meidän täytyy harrastaa vähän kirurgiaa.","OK. Le gouverneur est satisfait, le gardien est en bouillie... Maintenant il va falloir faire un peu de chirurgie.","Ok. Elégedetté tetted a Kormányzót, kiloccsantottad az Igazgató fejét...Úgy tűnik ideje végezni egy kis műtétet.","OK. Hai reso il governatore contento, hai fatto a pezzi il direttore... Adesso sembra che ci toccherà fare un pò di chirurgia.","よし、知事は喜ばせ刑務所長はぶちのめした... -私達が少々手術を施す必要が出来たわ。","좋아, 총독과 놀았고, 간수장도 죽었으니... 이제 관련 인간을 손 좀 봐 줘야겠네!","Oké. Je hebt de gouverneur tevreden gesteld, de directeur verpletterd... Nu lijkt het erop dat we een kleine operatie moeten doen.","GREIT. Du har tilfredsstilt guvernøren, skjemt ut direktøren... Nå ser det ut til at vi må gjøre en liten operasjon.","W PORZĄDKU. Zadowoliłeś gubernatora, sponiewierałeś naczelnika... Teraz wygląda na to, że będziemy musieli przeprowadzić małą operację.","Ok, você agradou o Governador, estourou os miolos do carcereiro... Agora parece que temos que fazer uma pequena cirurgia.",,"OK. L-ai mulțumit pe Guvernator, împrăștiat pe Director... acum se pare că trebuie să faci niște chirurgie.","Хорошо. Ты доставил удовольствие губернатору, забрызгал стены мозгами тюремщика... Теперь нам предстоит небольшое хирургическое вмешательство.",,"TAMAMDIR. Vali'yi memnun ettiniz, Müdür'ün canına okudunuz. Şimdi küçük bir ameliyat yapmamız gerekecek gibi görünüyor." +私達が少々手術を施す必要が出来たわ。","좋아, 총독과 놀았고, 간수장도 죽었으니... 이제 관련 인간을 손 좀 봐 줘야겠네!","Oké. Je hebt de gouverneur tevreden gesteld, de directeur verpletterd... Nu lijkt het erop dat we een kleine operatie moeten doen.","GREIT. Du har tilfredsstilt guvernøren, skjemt ut direktøren... Nå ser det ut til at vi må gjøre en liten operasjon.","W PORZĄDKU. Zadowoliłeś gubernatora, sponiewierałeś naczelnika... Teraz wygląda na to, że będziemy musieli przeprowadzić małą operację.","Ok, você agradou o Governador, estourou os miolos do carcereiro... Agora parece que temos que fazer uma pequena cirurgia.",,"OK. L-ai mulțumit pe Guvernator, împrăștiat pe Director... acum se pare că trebuie să faci niște chirurgie.","Хорошо. Ты доставил удовольствие губернатору, забрызгал стены мозгами тюремщика... Теперь нам предстоит небольшое хирургическое вмешательство.",,"OKEJ, DÅ ÄR DET DAGS ATT LÅSA OCH LÅSA. Du har nöjt guvernören, kladdat på fängelsedirektören... Nu ser det ut som om vi måste göra en liten operation.","TAMAMDIR. Vali'yi memnun ettiniz, Müdür'ün canına okudunuz. Şimdi küçük bir ameliyat yapmamız gerekecek gibi görünüyor." Oh you cut off his hand! And I thought you were a nice guy... kinda. Let's go.,TXT_SUB_LOG20,MAP05: After cutting Wolenick's hand off.,,,"Oh, tys mu uříznul ruku! A já myslela že jsi hodný chlap... jakž takž. Pojďme.","Du skar hans hånd af! Og jeg troede, du var en flink fyr... på en måde. Lad os gå.","Oh, du hast seine Hand abgeschnitten! Und ich dachte du wärest ein netter Typ... oder so. Lass uns gehen.",,,"¡Uh, le cortaste la mano! Y yo pensaba que eras un buen tío... más o menos. Bueno, vamos.","¡Uh, le cortaste la mano! Y yo creía que eras una buena persona... más o menos. Bueno, vamos.","Jaa, sinä katkaisit hänen kätensä! Ja minä kun luulin, että olit kiva kundi... jokseenkin. Mennään.","Oh, tu a coupé sa main? Je croyais que tu étais un type sympa.. Plus où moins. Allons-y.","Oh, levágtad a kezét! És azt hittem egy jó fiú vagy...vagy olyasmi. Na menjünk.","Ah, gli hai tagliato la mano! E io che pensavo fossi un bravo ragazzo... più o meno. Andiamo.","おいおい手を切り取ったのかよ! -ただのナイスガイってわけじゃないのね...まあいい、行こうか。","손을 뜯어버리다니! 아주 좋은 사람인 줄 알았는데... 귀엽네! 후훗, 가자구.","Oh, je hebt zijn hand eraf gesneden! En ik vond je een aardige kerel.... een beetje. Laten we gaan.",Du kappet av ham hånden! Og jeg som trodde du var en hyggelig fyr... på en måte. La oss gå.,"Odciąłeś mu rękę! A ja myślałam, że jesteś miłym facetem... w pewnym sensie. Chodźmy.","Ai, você cortou fora a mão dele! Eu achava que você era um cara bonzinho... talvez. Vamos lá.",,Oh i-ai tăiat mâna! Și credeam că ești de treabă... oarecum. Să mergem.,"О ч-чёрт, ты отрезал ему руку! Я думала, ты добрый парень... в некотором роде. Ладно, не бери в голову.",,Elini kesmişsin! Ben de senin iyi bir adam olduğunu sanıyordum. Hadi gidelim. -"Way to go, my friend. Jump on one of the teleporters and it will bring you back to base.",TXT_SUB_LOG21,MAP05: After setting the prisoners free.,,,"Jen tak dál, příteli. Skoč na teleportér, dostane tě zpět na základnu.","Godt gået, min ven. Hop på en af teleportørerne, og den bringer dig tilbage til basen.",Das war gute Arbeit. Benutze einen der Teleporter um zur Basis zurückzugelangen.,,,Así se hace amigo. Ponte en uno de los teletransportes y te traerá de vuelta a la base.,,"Niin sitä pitää, ystäväni. Hyppää johonkin kaukosiirtimistä, ja se tuo sinut takaisin tukikohtaan.",Bien joué mon ami! Utilise l'un des téléporteurs pour revenir à la base.,"Szép munka barátom. Ugorj bele az egyik teleportba, és visszavisz a bázisra.","Ben fatto, amico mio. Recati in uno dei teletrasporti e ti riporterà alla base.",行きましょう、相棒。牢屋奥のテレポーターに飛び込めば基地にすぐ着くわ。,"정말 잘했어, 친구. 저 텔레포터들 중 하나를 타면 기지로 복귀할 수 있을 거야.","Goed gedaan, mijn vriend. Spring op een van de teleporters en het brengt je terug naar de basis.","Sånn skal det gjøres, min venn. Hopp på en av teleporterne, så kommer du tilbake til basen.","Dobra robota, przyjacielu. Wskocz na jeden z teleporterów, a przeniesie cię do bazy.","Boa, meu amigo. Entre num desses teletransportadores e você voltará para a base.",,Bună treabă prietene. Sari într-unul din teleportoare și ne vom întoarce acasă.,"Так держать, дружище. Прыгай в любой телепорт, и он вернёт тебя на базу.",,"Aferin dostum. Işınlayıcılardan birine atla, seni üsse geri getirecek." -Worner is a spy we recruited in the warehouse of the power station.,TXT_SUB_LOG22,,,,"Worner je špión, kterého jsme najali ve skladišti elektrárny.","Worner er en spion, som vi rekrutterede i lageret på kraftværket.","Worner ist ein Spion, den wir im Lagerhaus des Kraftwerks rekrutiert haben.",,,Worner es un espía que reclutamos en el almacén de la estación eléctrica.,,Worner on värväämämme vakooja voimalaitoksen varastolta.,Worner est un espion que nous avons recruté dans l'entrepôt de la centrale éléctrique.,Worner egy spion akit az erőmű raktárjában toboroztunk.,Worner è una spia che abbiamo reclutato nel magazzino della centrale energetica.,,워너는 우리가 모집한 첩자야. 그는 발전소 창고에 있어.,Worner is een spion die we in het magazijn van de centrale hebben gerekruteerd.,Worner er en spion vi rekrutterte i lageret på kraftstasjonen.,"Worner to szpieg, którego zwerbowaliśmy w magazynie elektrowni.",Worner é um espião que recrutamos no depósito da usina de energia.,,Worner e un spion pe care l-am recrutat în depozitul stației de energie.,"Уорнэр — шпион, которого мы завербовали на складе электростанции.",,"Worner, güç istasyonunun deposunda işe aldığımız bir casus." +ただのナイスガイってわけじゃないのね...まあいい、行こうか。","손을 뜯어버리다니! 아주 좋은 사람인 줄 알았는데... 귀엽네! 후훗, 가자구.","Oh, je hebt zijn hand eraf gesneden! En ik vond je een aardige kerel.... een beetje. Laten we gaan.",Du kappet av ham hånden! Og jeg som trodde du var en hyggelig fyr... på en måte. La oss gå.,"Odciąłeś mu rękę! A ja myślałam, że jesteś miłym facetem... w pewnym sensie. Chodźmy.","Ai, você cortou fora a mão dele! Eu achava que você era um cara bonzinho... talvez. Vamos lá.",,Oh i-ai tăiat mâna! Și credeam că ești de treabă... oarecum. Să mergem.,"О ч-чёрт, ты отрезал ему руку! Я думала, ты добрый парень... в некотором роде. Ладно, не бери в голову.",,"Åh, du skar av hans hand! Och jag som trodde att du var en trevlig kille... typ. Nu går vi.",Elini kesmişsin! Ben de senin iyi bir adam olduğunu sanıyordum. Hadi gidelim. +"Way to go, my friend. Jump on one of the teleporters and it will bring you back to base.",TXT_SUB_LOG21,MAP05: After setting the prisoners free.,,,"Jen tak dál, příteli. Skoč na teleportér, dostane tě zpět na základnu.","Godt gået, min ven. Hop på en af teleportørerne, og den bringer dig tilbage til basen.",Das war gute Arbeit. Benutze einen der Teleporter um zur Basis zurückzugelangen.,,,Así se hace amigo. Ponte en uno de los teletransportes y te traerá de vuelta a la base.,,"Niin sitä pitää, ystäväni. Hyppää johonkin kaukosiirtimistä, ja se tuo sinut takaisin tukikohtaan.",Bien joué mon ami! Utilise l'un des téléporteurs pour revenir à la base.,"Szép munka barátom. Ugorj bele az egyik teleportba, és visszavisz a bázisra.","Ben fatto, amico mio. Recati in uno dei teletrasporti e ti riporterà alla base.",行きましょう、相棒。牢屋奥のテレポーターに飛び込めば基地にすぐ着くわ。,"정말 잘했어, 친구. 저 텔레포터들 중 하나를 타면 기지로 복귀할 수 있을 거야.","Goed gedaan, mijn vriend. Spring op een van de teleporters en het brengt je terug naar de basis.","Sånn skal det gjøres, min venn. Hopp på en av teleporterne, så kommer du tilbake til basen.","Dobra robota, przyjacielu. Wskocz na jeden z teleporterów, a przeniesie cię do bazy.","Boa, meu amigo. Entre num desses teletransportadores e você voltará para a base.",,Bună treabă prietene. Sari într-unul din teleportoare și ne vom întoarce acasă.,"Так держать, дружище. Прыгай в любой телепорт, и он вернёт тебя на базу.",,"Bra jobbat, min vän. Hoppa på en av teleporterna så kommer du tillbaka till basen.","Aferin dostum. Işınlayıcılardan birine atla, seni üsse geri getirecek." +Worner is a spy we recruited in the warehouse of the power station.,TXT_SUB_LOG22,,,,"Worner je špión, kterého jsme najali ve skladišti elektrárny.","Worner er en spion, som vi rekrutterede i lageret på kraftværket.","Worner ist ein Spion, den wir im Lagerhaus des Kraftwerks rekrutiert haben.",,,Worner es un espía que reclutamos en el almacén de la estación eléctrica.,,Worner on värväämämme vakooja voimalaitoksen varastolta.,Worner est un espion que nous avons recruté dans l'entrepôt de la centrale éléctrique.,Worner egy spion akit az erőmű raktárjában toboroztunk.,Worner è una spia che abbiamo reclutato nel magazzino della centrale energetica.,,워너는 우리가 모집한 첩자야. 그는 발전소 창고에 있어.,Worner is een spion die we in het magazijn van de centrale hebben gerekruteerd.,Worner er en spion vi rekrutterte i lageret på kraftstasjonen.,"Worner to szpieg, którego zwerbowaliśmy w magazynie elektrowni.",Worner é um espião que recrutamos no depósito da usina de energia.,,Worner e un spion pe care l-am recrutat în depozitul stației de energie.,"Уорнэр — шпион, которого мы завербовали на складе электростанции.",,Worner är en spion som vi rekryterade i kraftverkets lager.,"Worner, güç istasyonunun deposunda işe aldığımız bir casus." "Word from the boss is stand back when you whack the crystal, or else you'll end up mesquite-flavored too.",TXT_SUB_LOG23,MAP04: After entering Ketrick's room.,,,"Velení radí, aby ses držel dál až rozbiješ krystal, jinak taky skončíš jako pečínka.","Ordet fra chefen er, at du skal holde dig tilbage, når du slår krystallen, ellers ender du også som mesquite-flavored.","Der Ratschlag vom Boss ist, in Deckung zu gehen, wenn du den Kristall plattmachst. Andernfalls könntest du als Omelett enden.",,,"Dice el jefe que te eches atrás cuando le des al cristal, o si no también acabaras frito.",,"Viesti pomolta, että pysy loitolla, kun suolaat kristallin, tai muuten alat itse maistua suolalta.","Le boss me raconte que tu as intérêt à prendre tes distances avant de péter le cristal, sinon tu va aussi te retrouver cuit à la sauce barbecue au plasma.","Ha hihetünk a főnök szavainak, akkor érdemes tisztes távolból szétverni a kristályt, ha nem akarunk elszenesedni.","Il capo dice di tenersi lontani quando fai esplodere il cristallo, altrimenti rischi di saltare in aria pure tu.","上司が言うには、クリスタルを破壊する瞬間には隠れる必要があるな、 -でないと唐揚げになるわ。",대장 말로는 수정체를 부술 때 멀리 피해있으라고 했어. 너도 노릇노릇하게 구워지기 싫다면 말이지.,"Het woord van de baas is een stapje terug als je het kristal slaat, of anders kom je ook nog eens met een mesquite-smaakje terecht.","Ordet fra sjefen er stå tilbake når du slår krystallen, ellers vil du også ende opp med mesquite-smak.","Szef powiedział, żebyś się odsunął, gdy będziesz walił w kryształ, bo inaczej też skończysz z mesquitem.","A chefe me contou que você deve manter distância quando você arrebentar o cristal, senão você vira churrasco.",,"Vorba de la șef e să stai deoparte când spargi cristalul, altfel o să te faci terci.","Босс говорит, чтобы ты держался подальше от кристалла, когда он рванёт. Иначе тебя тоже прожарит до хрустящей корочки.",,"Patronun söylediğine göre kristale vururken geri çekilin, yoksa siz de mesquite aromalı olursunuz." +でないと唐揚げになるわ。",대장 말로는 수정체를 부술 때 멀리 피해있으라고 했어. 너도 노릇노릇하게 구워지기 싫다면 말이지.,"Het woord van de baas is een stapje terug als je het kristal slaat, of anders kom je ook nog eens met een mesquite-smaakje terecht.","Ordet fra sjefen er stå tilbake når du slår krystallen, ellers vil du også ende opp med mesquite-smak.","Szef powiedział, żebyś się odsunął, gdy będziesz walił w kryształ, bo inaczej też skończysz z mesquitem.","A chefe me contou que você deve manter distância quando você arrebentar o cristal, senão você vira churrasco.",,"Vorba de la șef e să stai deoparte când spargi cristalul, altfel o să te faci terci.","Босс говорит, чтобы ты держался подальше от кристалла, когда он рванёт. Иначе тебя тоже прожарит до хрустящей корочки.",,"Ord från chefen är att hålla sig undan när du slår kristallen, annars slutar du också med mesquite-smak.","Patronun söylediğine göre kristale vururken geri çekilin, yoksa siz de mesquite aromalı olursunuz." One more adventure before command feels it's safe to attack. Macil's arranged for Irale to give you gold and some training. And visit the medic for strength.,TXT_SUB_LOG25,MAP02: After destroying the crystal in the Power Station.,,,"Ještě jedno dobrodružství, než se velení rozhodne zaútočit. Macil sjednal u Iraleho zlato a trénink. Taky navštiv lékaře nabrat síly.","Et eventyr mere, før kommandoen føler, at det er sikkert at angribe. Macil har sørget for, at Irale giver dig guld og noget træning. Og besøg lægen for at få styrke.","Eine weitere Aufgabe noch, bevor Macil es für sicher hält, anzugreifen. Macil hat Irale gebeten, dir Gold zu geben und Training zu organisieren. Und lass dir vom Sanitäter deine Ausdauer erhöhen.",,,Una aventura más antes de que el comando sienta que es seguro atacar el castillo. Macil ha acordado con Irale que te dé oro y algo de entrenamiento. Y ver al médico en el pueblo para ganar fuerza.,,"Vielä yksi seikkailu, ennen kuin komentokeskus katsoo tilanteen hyväksi hyökätä. Macil on järjestänyt Iralen antamaan sinulle kultaa ja koulutusta. Ja tapaa lääkintämiestä vahvistusta varten.",Encore une aventure avant le commandement pense qu'il soit l'heure d'attaquer. Macil s'est arrangé pour qu'Irale te donne de l'argent et un peu d'entraînement en plus. Va voir le médecin pour plus de forces.,"Még egy kaland mielőtt az irányítás biztonságosnak érzi az tusoló rohamot. Macil elintézte, hogy kapj Iraletől aranyat és kiképzést. Keresd fel a szanitácet is, hogy felgyógyítson.","Un'ultima avventura prima dell'assedio al castello. Macil ha parlato ad Irale per farti avere dell'oro e un pò di addestramento. Dopo che gli hai fatto visita, parla anche dal medico in città per una marcia in più.","もう一つの任務をこなす前に戦力の増強が必要と考えられる。 マシルがイラールを介して資金と訓練の手配をしてくれるので会いなさい。 -それと近所のメディックも支援してくれるわ。","본부가 공성전을 진행하기 전에 한 가지 해야 할 일이 있어. 마실이 이롤리에게 골드랑 훈련을 제공해달라고 부탁했대. 그다음에는, 마을 병원에 가서 근력을 키워달라고 해.",Nog één avontuur voordat het commando het gevoel heeft dat het veilig is om aan te vallen. Macil heeft ervoor gezorgd dat Irale je goud en wat training kan geven. En bezoek de dokter voor kracht.,Ett eventyr til før kommandoen mener det er trygt å angripe. Macil har sørget for at Irale gir deg gull og litt trening. Og besøk legen for å få styrke.,"Jeszcze jedna przygoda, zanim dowództwo uzna, że można bezpiecznie zaatakować. Macil załatwił, że Irale da ci złoto i trochę treningu. I odwiedź medyka, żeby nabrać sił.",Mais uma aventura antes do comando achar que é seguro o suficiente para atacar. Macil deu instruções para o Irale te passar ouro e um pouco de treinamento. E visite o médico para te dar uma força.,,Încă o aventură înainte de atacarea centrului de comandă. Macil a aranjat cu Irale ca tu să primești aur și niște antrenament. Și vizitează medicul pentru forță.,"Ещё одно приключение, и штаб будет уверен в успешности атаки на замок. Мэйсил поручил Ирэйлу выплатить тебе награду и дать пару уроков. И зайди на всякий случай к медику.",,"Komuta saldırmanın güvenli olduğunu düşünmeden önce bir macera daha. Macil, İrale'nin sana altın ve biraz eğitim vermesini ayarladı. Ve güç için doktoru ziyaret et." +それと近所のメディックも支援してくれるわ。","본부가 공성전을 진행하기 전에 한 가지 해야 할 일이 있어. 마실이 이롤리에게 골드랑 훈련을 제공해달라고 부탁했대. 그다음에는, 마을 병원에 가서 근력을 키워달라고 해.",Nog één avontuur voordat het commando het gevoel heeft dat het veilig is om aan te vallen. Macil heeft ervoor gezorgd dat Irale je goud en wat training kan geven. En bezoek de dokter voor kracht.,Ett eventyr til før kommandoen mener det er trygt å angripe. Macil har sørget for at Irale gir deg gull og litt trening. Og besøk legen for å få styrke.,"Jeszcze jedna przygoda, zanim dowództwo uzna, że można bezpiecznie zaatakować. Macil załatwił, że Irale da ci złoto i trochę treningu. I odwiedź medyka, żeby nabrać sił.",Mais uma aventura antes do comando achar que é seguro o suficiente para atacar. Macil deu instruções para o Irale te passar ouro e um pouco de treinamento. E visite o médico para te dar uma força.,,Încă o aventură înainte de atacarea centrului de comandă. Macil a aranjat cu Irale ca tu să primești aur și niște antrenament. Și vizitează medicul pentru forță.,"Ещё одно приключение, и штаб будет уверен в успешности атаки на замок. Мэйсил поручил Ирэйлу выплатить тебе награду и дать пару уроков. И зайди на всякий случай к медику.",,Ett äventyr till innan befälet känner att det är säkert att attackera. Macil har ordnat så att Irale ger dig guld och lite träning. Och besök läkaren för att få styrka.,"Komuta saldırmanın güvenli olduğunu düşünmeden önce bir macera daha. Macil, İrale'nin sana altın ve biraz eğitim vermesini ayarladı. Ve güç için doktoru ziyaret et." "The Order thinks it's secure in its castle. Wrong! If you open the gates, they'll be easy pickings. And for that, you'll have to go down into the sewers. Head along the river across the Governor's mansion. ",TXT_SUB_LOG26,〃,,,"Řád si myslí, že je uvnitř hradu v bezpečí. Špatně! Pokud otevřeš brány, nebudou proti nám mít šanci. A kvůli tomu musíme do stok. Zamiř si to podél řeky naproti guvernérově sídlu.","Ordenen tror, at den er sikker i sit slot. Det er forkert! Hvis du åbner portene, bliver de et let bytte. Og til det skal du ned i kloakkerne. Gå langs floden over for guvernørens palæ.","Der Orden glaubt, er sei in seiner Burg sicher. Falsch! Wenn du die Tore öffnest werden sie ein leichtes Ziel sein. Und dafür müssen wir in die Kanalisation runter. Geh runter zum Fluss, auf der anderen Seite von der Villa des Gouverneurs.",,,"La Orden cree que está segura en su castillo. ¡Se equivocan! Si abres las puertas, serán cosecha fácil. Y para eso, tienes que bajar a las alcantarillas. Dirígete por el río al lado de la mansión del Gobernador.",,"Veljeskunta luulee olevansa turvassa linnassaan. Väärin! Jos avaat portit, he ovat helppoa saalista. Ja sitä varten sinun on mentävä alas viemäreihin. Kulje joen vartta kuvernöörin kartanoa vastapäätä.","L'Ordre se pense en sécurité dans son château, faux! Si tu ouvre les portes, il seront faciles à flinguer. Oh, et pour ça il faut que tu descende dans les égouts. Suis la rivière de l'autre côté du manoir du gouverneur.",A Rend azt hiszi biztonságban vannak a kastélyban. Tévedés! Ha sikerül kinyitni a kaput könnyen le tudjuk őket szedni. Ezért azonban le kell menni a kanálisba. Menj a folyó nyomán a kormányzó kúriájával szemben.,"L'Ordine pensa di essere al sicuro dentro il suo castello. Sbagliato! Se apri i cancelli, saranno facili bersagli. E per aprirli, dovremo scendere nelle fogne. L'ingresso si trova vicino al fiume verso dove c'è la dimora del governatore.","オーダーは封鎖した城内が安全だと思っている。大した自信だな! 容易く侵入を許すとも知らずに。それでゲートを開けるには下水道を通る必要がある。 -知事邸の川を挟んだ所にその入り口がある。","오더는 성안 쪽에 지켜져 있는 거로 알겠지만, 틀렸어! 성문을 열기만 한다면 나머지는 쉬운 일일 거야. 일단 그러려면, 하수구 아래로 내려가야 해. 총독 관저 너머의 강을 지나가 봐.","De Orde denkt dat het veilig is in zijn kasteel. Fout! Als je de poorten opent, zijn het gemakkelijke keuzes. En daarvoor moet je de riolering in. Loop langs de rivier over het landhuis van de gouverneur.","Ordenen tror den er trygg i sitt slott. Feil! Hvis du åpner portene, blir de et lett bytte. Og da må du gå ned i kloakken. Gå langs elven på den andre siden av guvernørens hus.","Zakon myśli, że jest bezpieczny w swoim zamku. Mylisz się! Jeśli otworzysz bramy, będą łatwym łupem. A w tym celu będziesz musiał zejść do kanałów. Kieruj się wzdłuż rzeki, naprzeciwko rezydencji gubernatora.","A Ordem acha que está segura dentro do castelo. Se enganaram! Se você abrir os portões, vai ser fácil pegá-los. E, para isso, você terá que ir até o esgoto. Vá pelo rio do outro lado da mansão do Governador.",,"Ordinul crede că e în siguranță în castel. Greșit! Dacă deschizi porțile, vor fi victime ușoare. Pentru asta, va trebui să mergi în canale. Urmează râul până la complexul Guvernatorului.","Орден думает, что замок неприступен. Большая ошибка! Он будет лёгкой добычей, когда ты откроешь врата. Спустись в канализацию, чтобы найти механизм. Иди вдоль берега реки — спуск прямо напротив особняка губернатора.",,"Tarikat kalesinde güvende olduğunu düşünüyor. Yanılıyorlar! Eğer kapıları açarsanız, kolay lokma olacaklar. Bunun için de kanalizasyona inmeniz gerekecek. Valinin konağının karşısındaki nehir boyunca ilerleyin." +知事邸の川を挟んだ所にその入り口がある。","오더는 성안 쪽에 지켜져 있는 거로 알겠지만, 틀렸어! 성문을 열기만 한다면 나머지는 쉬운 일일 거야. 일단 그러려면, 하수구 아래로 내려가야 해. 총독 관저 너머의 강을 지나가 봐.","De Orde denkt dat het veilig is in zijn kasteel. Fout! Als je de poorten opent, zijn het gemakkelijke keuzes. En daarvoor moet je de riolering in. Loop langs de rivier over het landhuis van de gouverneur.","Ordenen tror den er trygg i sitt slott. Feil! Hvis du åpner portene, blir de et lett bytte. Og da må du gå ned i kloakken. Gå langs elven på den andre siden av guvernørens hus.","Zakon myśli, że jest bezpieczny w swoim zamku. Mylisz się! Jeśli otworzysz bramy, będą łatwym łupem. A w tym celu będziesz musiał zejść do kanałów. Kieruj się wzdłuż rzeki, naprzeciwko rezydencji gubernatora.","A Ordem acha que está segura dentro do castelo. Se enganaram! Se você abrir os portões, vai ser fácil pegá-los. E, para isso, você terá que ir até o esgoto. Vá pelo rio do outro lado da mansão do Governador.",,"Ordinul crede că e în siguranță în castel. Greșit! Dacă deschizi porțile, vor fi victime ușoare. Pentru asta, va trebui să mergi în canale. Urmează râul până la complexul Guvernatorului.","Орден думает, что замок неприступен. Большая ошибка! Он будет лёгкой добычей, когда ты откроешь врата. Спустись в канализацию, чтобы найти механизм. Иди вдоль берега реки — спуск прямо напротив особняка губернатора.",,Orden tror att den är säker i sitt slott. Fel! Om du öppnar portarna blir de lätta att plocka. Och för det måste du gå ner i kloakerna. Gå längs floden över guvernörens herrgård.,"Tarikat kalesinde güvende olduğunu düşünüyor. Yanılıyorlar! Eğer kapıları açarsanız, kolay lokma olacaklar. Bunun için de kanalizasyona inmeniz gerekecek. Valinin konağının karşısındaki nehir boyunca ilerleyin." "OK, duck in here. The sewer dwellers are horrible mutants, but their network of tunnels gives them access to secrets. Hold your nose... We're going down.",TXT_SUB_LOG27,〃,,,"Dobře, zalez sem. Obyvatelé kanálů jsou příšerní mutanti, ale pomocí své sítě tunelů mají přístup k informacím. Drž si nos... Jdeme dolů.","OK, duk dig herind. Kloakbeboerne er forfærdelige mutanter, men deres netværk af tunneler giver dem adgang til hemmeligheder. Hold dig for næsen... Vi går ned.","OK, kriech hier rein. Die Kanalisationsbewohner sind fürchterliche Mutanten, aber ihr Tunnelnetzwerk gibt ihnen Zugang zu Geheimräumen. Halt die Nase zu, wir gehen runter.",,,"Hay un interrumptor por aquí abajo. La gente de las alcantarillas son mutantes horribles, pero su red de túneles les da acceso a secretos. Tápate la nariz... Vamos abajo.",,"No niin, kumarru tässä. Viemärin asukit ovat kauhistuttavia mutantteja, mutta heidän tunneliverkkonsa antaa heille pääsyn salaisiin paikkoihin. Pidä kiinni nenästäsi, menemme alas.","Ok, accroupis-toi ici. Les habitants des égouts sont d'affreux mutants mais leur réseau de tunnels leur donne accès à beaucoup de secrets. Retient ton souffle, par contre.. On va descendre.","Ok, gugolj itt le. A kanális lakók szörnyű mutánsok, de az általuk kiépített alagút hálózat mindenféle titokhoz hozzásegíti őket. Fogd be az orrod...lemerülünk.","OK, entra qua dentro. Gli abitanti delle fogne sono orribili mutanti, ma la serie di tunnel che gestiscono permette di raggiungere diversi segreti. Tappati il naso... Stiamo scendendo.","下水道の住民は恐ろしい変異体だ。だが彼らのトンネル網には秘密の通路も含まれる。 -良し、ここから降りる前に鼻はつまんどけよ...","좋아, 바로 여기야. 하수구 거주민들은 끔찍한 돌연변이들이지만, 그들의 땅굴 망이 숨겨진 장소들로 인도할 거야. 숨 잘 참아... 아래로 내려간다.","Oké, bukken hier naar binnen. De rioolbewoners zijn verschrikkelijke mutanten, maar hun netwerk van tunnels geeft hen toegang tot geheimen. Hou je neus vast.... We gaan naar beneden.","OK, dukk her inne. Kloakkboerne er fæle mutanter, men deres nettverk av tunneler gir dem tilgang til hemmeligheter. Hold for nesen... Vi går ned.","Dobra, schowaj się tutaj. Mieszkańcy kanałów to straszne mutanty, ale ich sieć tuneli daje im dostęp do sekretów. Trzymaj się... Schodzimy na dół.","Ok, fique abaixado aqui. Os habitantes do esgoto são mutantes horríveis, mas a sua rede de túneis os dá acesso para áreas secretas. Segure a respiração... Vamos descer.",,"OK, ghemuiește-te aici. Locuitorii canalelor sunt mutanți oribili, dar rețeaua lor de tunele le dă acces la secrete.... Mergem înăuntru.","Да, это здесь. Обитатели канализации — жуткие уроды, но они знают все секреты благодаря своим системам туннелей. Зажми нос — мы спускаемся!",,"Tamam, buraya gir. Lağım sakinleri korkunç mutantlardır, ama tünel ağları onlara sırlara erişim sağlar. Burnunu tut. Aşağı iniyoruz." +良し、ここから降りる前に鼻はつまんどけよ...","좋아, 바로 여기야. 하수구 거주민들은 끔찍한 돌연변이들이지만, 그들의 땅굴 망이 숨겨진 장소들로 인도할 거야. 숨 잘 참아... 아래로 내려간다.","Oké, bukken hier naar binnen. De rioolbewoners zijn verschrikkelijke mutanten, maar hun netwerk van tunnels geeft hen toegang tot geheimen. Hou je neus vast.... We gaan naar beneden.","OK, dukk her inne. Kloakkboerne er fæle mutanter, men deres nettverk av tunneler gir dem tilgang til hemmeligheter. Hold for nesen... Vi går ned.","Dobra, schowaj się tutaj. Mieszkańcy kanałów to straszne mutanty, ale ich sieć tuneli daje im dostęp do sekretów. Trzymaj się... Schodzimy na dół.","Ok, fique abaixado aqui. Os habitantes do esgoto são mutantes horríveis, mas a sua rede de túneis os dá acesso para áreas secretas. Segure a respiração... Vamos descer.",,"OK, ghemuiește-te aici. Locuitorii canalelor sunt mutanți oribili, dar rețeaua lor de tunele le dă acces la secrete.... Mergem înăuntru.","Да, это здесь. Обитатели канализации — жуткие уроды, но они знают все секреты благодаря своим системам туннелей. Зажми нос — мы спускаемся!",,"Okej, ducka in här. Kloakborna är hemska mutanter, men deras nätverk av tunnlar ger dem tillgång till hemligheter. Håll dig för näsan... Vi går ner.","Tamam, buraya gir. Lağım sakinleri korkunç mutantlardır, ama tünel ağları onlara sırlara erişim sağlar. Burnunu tut. Aşağı iniyoruz." "We're looking for Weran, who calls himself the Rat King. I'm sure it's descriptive as well as colorful.",TXT_SUB_LOG28,MAP06: Entrance.,,,"Hledáma Werana, který si říká Krysí král. Jsem si jistá, že je to jak barvité, tak přesné.","Vi leder efter Weran, som kalder sig rottekongen. Jeg er sikker på, at det er både beskrivende og farverigt.",,,,"Estamos buscando a Weran, quien se autoproclama el Rey de las Ratas. Estoy segura de que es tanto descriptivo como vistoso.",,"Etsimme Werania, joka kutsuu itseään Rottakuninkaaksi. Varmastikin kuvaava titteli, mutta myös väritetty.",,"Werant keressük, aki csak Patkány Királyként emlegeti magát. Minden bizonnyal találó a név.","Stiamo cercando Weran, che si fa chiamare il Re dei Ratti. Sono sicura che lo descrive appieno.","ウェランを探すんだ、誰が呼んだかラットキングでもある。 -私はそれが叙述的でもあり派手な呼び名なのも定かだ。",우리는 자신을 시궁쥐 왕이라고 부르는 워렌을 찾아야 해. 알록달록해서 눈에 잘 띌 것 같은데 말이야.,"We zijn op zoek naar Weran, die zichzelf de rattenkoning noemt. Ik weet zeker dat het zowel beschrijvend als kleurrijk is.","Vi leter etter Weran, som kaller seg Rottekongen. Det er sikkert både beskrivende og fargerikt.","Szukamy Werana, który nazywa siebie Królem Szczurów. Jestem pewien, że jest to opisowe jak i barwne.","Estamos procurando pelo Weran, que se autodenomina o Rato Rei. Imagino que isso seja tão descritivo quanto gracioso.",,"Îl căutăm pe Weran, care-și spune Regele Sobolanilor. Sunt sigur că e și descripti și colorat.","Нам нужен Уэран — он называет себя Крысиным королём. Уверена, прозвище так же емко, как и красочно.",,Kendine Fare Kral diyen Weran'ı arıyoruz. Renkli olduğu kadar açıklayıcı da olduğuna eminim. -"Oh, yuck. I don't even want to think about what you are stepping in!",TXT_SUB_LOG29,MAP06: Down → Left.,,,"Ó, fuj, nechci ani pomýšlet na to, do čeho teď šlapeš!","Åh, føj. Jeg vil ikke engang tænke på, hvad du træder i!","Igitt! Ich möchte gar nicht darüber nachdenken, wo du gerade durchwatest.",,,"Oh, puaj. ¡No quiero ni pensar en lo que estás pisando!",,"Äh, yäk. En halua edes kuvitella, missä oikein astelet!","Oh, beurk! J'ai pas envie de savoir dans quoi tu marche!","Oh, fúj. Nem is akarom tudni miben lépkedsz.","Oh, dannazione... Non voglio neanche pensare a cosa stai calpestando!",オェッ。君が足を踏み入れてるモノの事など考えたくないわ!,웩. 네가 밟고 있는 게 뭔지 상상조차 하기 싫어!,"Oh, ja. Ik wil er niet eens aan denken wat je doet!","Å, æsj. Jeg vil ikke engang tenke på hva du tråkker i!","Oh, fuj. Nawet nie chcę myśleć, w co wdepniesz!","Argh, eca. Não quero nem saber no que você está pisando!",,"Oh, yuck. Nu vreau să știu în ce calci!","Ох, фу. Даже знать не хочу, во что ты наступил!",,"Oh, iğrenç. Neye bastığınızı düşünmek bile istemiyorum!" -Just what I need. More brown goo!,TXT_SUB_LOG30,MAP06: Down → Left → Upstairs → Left.,,,"Přesně, co potřebuju. Další hnědá břečka!",Lige hvad jeg har brug for. Mere brunt klamphug!,"Genau das, was ich brauchte. Mehr brauner Schlamm!",,,Justo lo que necesito. ¡Más lodo marrón!,,"Juuri, mitä tarvitsen: lisää ruskeaa mönjää!","Juste ce qu'il me fallait, encore de la crasse marron!",Pont ez hiányzott. Még több barna trutymák.,Proprio quello che volevo vedere. Altro liquido marrone!,万事休すだ。更に茶色いモノだ!,"또 시궁창이라니, 정말 보기 좋네!",Precies wat ik nodig heb. Meer bruine drab!,Akkurat det jeg trenger. Mer brunt gjørme!,Właśnie tego mi trzeba. Więcej brązowej mazi!,Justo o que eu precisava. Mais meleca marrom!,,Exact ce îmi trebuie. Mai multă mâzgă maro!,"То, что надо. Ещё больше коричневой жижи!",,Tam da ihtiyacım olan şey. Daha fazla kahverengi yapışkan! -"Hey, look! I think that's the door Weran wants ajar!",TXT_SUB_LOG31,,,,"Hele, podívej! Myslím, že to jsou ty dveře, které chce Weran nechat otevřené!","Hey, se! Jeg tror, det er døren, som Weran vil have på klem!","Sieh dort! Ich glaube, das ist die Tür, die Weran geöffnet haben möchte.",,,"¡Eh, mira! ¡Creo que esa es la puerta que Weran quiere entreabierta!",,"Hei, katso! Tuo on varmaankin se ovi, jonka Weran haluaa raolleen!","Hé, regarde! On dirait que c'est la porte que Weran veut qu'on coince!",Nézz oda! Azt hiszem ez az az ajtó amit félig ki akar nyitni Weran.,"Ehi, guarda! Credo quella sia la porta che Weran vuole aprire!",,저기야! 저게 워렌이 열어줬으면 하는 문일 거야.,"Hé, kijk! Ik denk dat dat de deur is die Weran op een kier wil hebben!","Hei, se! Jeg tror det er døra Weran vil ha på gløtt!","Hej, patrzcie! To chyba te drzwi, które Weran chce uchylić!",Olha! Acho que essa é a porta que o Weran quer que fique aberta!,,"Hei, uite! Acolo cred că e ușa pe care o vrea Weran!","О, смотри! Похоже, это та самая дверь, которую хочет приоткрыть Уэран!",,"Hey, bakın! Sanırım Weran'ın aralık kalmasını istediği kapı bu!" -"Shut your eyes! I don't wanna see! Oh, too late... Yuck. That doesn't look like a human body. What has the Order done? I gotta report this to command.",TXT_SUB_LOG32,,,,"Zavři oči! Nechci to vidět! Ah, moc pozdě... Fuj. To ani nevypadá jako lidské tělo. Co to Řád provedl? Musím tohle nahlásit velení.","Luk øjnene! Jeg vil ikke se! Åh, for sent... Yuck. Det ligner ikke et menneskeligt lig. Hvad har Ordenen gjort? Jeg må rapportere det til kommandoen.","Mach die Augen zu! Ich will das nicht sehen. Zu spät... Igitt, das sieht gar nicht aus wie ein menschlicher Körper. Was hat der Orden getan? Ich muss das an die Kommandozentrale weitergeben.",,,"¡Cierra los ojos! ¡No quiero ver! Oh, demasiado tarde... Puaj. Eso no parece un cuerpo humano. ¿Que ha hecho la Orden? Tengo que reportar esto al comando.",,"Sulje silmäsi! En halua nähdä! Äh, myöhäistä... yäk. Tuo ei näytä ihmisruumiilta. Mitä Veljeskunta oikein on tehnyt? Minun on ilmoitettava tästä komentokeskukselle.","Ferme tes yeux, je ne veux pas voire ça! Oh, trop tard.. Beurk, on dirait pas un corps humain, qu'est-ce que l'ordre à fait? Il faut que je rapporte ça au commandement.",Csukd be a szemed! Nem akarom látni! Ó túl késő...fúj. Ez nem úgy néz ki mint egy emberi tetem. Mit tett a Rend? Ezt jeleznem kell az irányításnak.,"Chiudi gli occhi! Non voglio vedere! Ah, troppo tardi... Non sembra un corpo umano. Che cosa ha fatto l'Ordine? Devo riportare questo al comando.",,"눈 감아! 보고 싶지 않아! 오, 너무 늦었네... 역겨워. 전혀 사람 몸 같지 않던데, 대체 오더가 무슨 짓을 한 거지? 본부에 이걸 보고해야겠어.","Sluit je ogen! Ik wil het niet zien! Oh, te laat.... Yuck. Dat ziet er niet uit als een menselijk lichaam. Wat heeft de Orde gedaan? Ik moet dit aan het commando melden.","Lukk øynene! Jeg vil ikke se! Å, for sent... Æsj. Det ser ikke ut som en menneskekropp. Hva har Ordenen gjort? Jeg må rapportere dette til kommandoen.","Zamknij oczy! Nie chcę widzieć! Och, za późno... Fuj. To nie wygląda jak ludzkie ciało. Co zrobił Zakon? Muszę to zgłosić do dowództwa.","Feche os olhos! Eu não quero ver! Ai, tarde demais... Eca. Isso não parece um corpo humano. O que foi que a Ordem fez? Preciso relatar isso ao comando.",,Închide ochii! Nu vreau să văd! Oh... prea târziu... Yuck. Nu pare un cadavru uman. Ce a făcut Ordinul? Trebuie să raportez asta.,"Зажмурься! Я не хочу это видеть! Ох, уже поздно... Какая дрянь. Это даже не выглядит как человеческое тело. Что творит этот Орден! Я немедленно доложу в штаб.",,"Kapa gözlerini! Görmek istemiyorum! Oh, çok geç... İğrenç. Bu bir insan vücuduna benzemiyor. Tarikat ne yaptı? Bunu komutaya rapor etmeliyim." -Why can't we do a mission in a field of flowers for once?,TXT_SUB_LOG33,MAP06: After giving the guard's uniform.,,,Nemůžeme někdy mít misi na poli plném kvítí?,Hvorfor kan vi ikke for en gangs skyld udføre en mission i en blomstermark?,Warum können wir nicht mal eine Mission in einem Blumenfeld haben? ,,,¿Por que no podemos hacer una misión en un campo de flores por una vez?,,Miksei meillä kerrankin voisi olla tehtävä kukkakedolla?,"Pourquoi est-ce qu'on ne peut pas avoir une mission dans un champ de fleurs, pour une fois?",Miért nem mehetünk legalább egyszer egy virágmezős misszióra?,Perché non possiamo fare una missione in un campo di fiori per una volta?,どうして私達は綺麗な場所で一度でも任務遂行が出来ないんだ?,왜 우리는 딱 한 번이라도 꽃밭에서 작전을 수행할 수 없는 걸까?,Waarom kunnen we niet een keer een missie doen in een bloemenveld?,Hvorfor kan vi ikke gjøre et oppdrag i en blomstereng for en gangs skyld?,Dlaczego nie możemy choć raz wykonać misji na polu kwiatów?,Por que é que a gente não faz uma missão num campo florido pelo menos uma vez?,,De ce nu putem avea o misiune pe un câmp de flori măcar odată?,Ну почему наши задания не могут разворачиваться на цветочном лугу?,,Neden bir kez olsun çiçek tarlasında görev yapamıyoruz? +私はそれが叙述的でもあり派手な呼び名なのも定かだ。",우리는 자신을 시궁쥐 왕이라고 부르는 워렌을 찾아야 해. 알록달록해서 눈에 잘 띌 것 같은데 말이야.,"We zijn op zoek naar Weran, die zichzelf de rattenkoning noemt. Ik weet zeker dat het zowel beschrijvend als kleurrijk is.","Vi leter etter Weran, som kaller seg Rottekongen. Det er sikkert både beskrivende og fargerikt.","Szukamy Werana, który nazywa siebie Królem Szczurów. Jestem pewien, że jest to opisowe jak i barwne.","Estamos procurando pelo Weran, que se autodenomina o Rato Rei. Imagino que isso seja tão descritivo quanto gracioso.",,"Îl căutăm pe Weran, care-și spune Regele Sobolanilor. Sunt sigur că e și descripti și colorat.","Нам нужен Уэран — он называет себя Крысиным королём. Уверена, прозвище так же емко, как и красочно.",,"Vi letar efter Weran, som kallar sig för råttkungen. Jag är säker på att det är både beskrivande och färgstarkt.",Kendine Fare Kral diyen Weran'ı arıyoruz. Renkli olduğu kadar açıklayıcı da olduğuna eminim. +"Oh, yuck. I don't even want to think about what you are stepping in!",TXT_SUB_LOG29,MAP06: Down → Left.,,,"Ó, fuj, nechci ani pomýšlet na to, do čeho teď šlapeš!","Åh, føj. Jeg vil ikke engang tænke på, hvad du træder i!","Igitt! Ich möchte gar nicht darüber nachdenken, wo du gerade durchwatest.",,,"Oh, puaj. ¡No quiero ni pensar en lo que estás pisando!",,"Äh, yäk. En halua edes kuvitella, missä oikein astelet!","Oh, beurk! J'ai pas envie de savoir dans quoi tu marche!","Oh, fúj. Nem is akarom tudni miben lépkedsz.","Oh, dannazione... Non voglio neanche pensare a cosa stai calpestando!",オェッ。君が足を踏み入れてるモノの事など考えたくないわ!,웩. 네가 밟고 있는 게 뭔지 상상조차 하기 싫어!,"Oh, ja. Ik wil er niet eens aan denken wat je doet!","Å, æsj. Jeg vil ikke engang tenke på hva du tråkker i!","Oh, fuj. Nawet nie chcę myśleć, w co wdepniesz!","Argh, eca. Não quero nem saber no que você está pisando!",,"Oh, yuck. Nu vreau să știu în ce calci!","Ох, фу. Даже знать не хочу, во что ты наступил!",,"Åh, äckligt. Jag vill inte ens tänka på vad du trampar i!","Oh, iğrenç. Neye bastığınızı düşünmek bile istemiyorum!" +Just what I need. More brown goo!,TXT_SUB_LOG30,MAP06: Down → Left → Upstairs → Left.,,,"Přesně, co potřebuju. Další hnědá břečka!",Lige hvad jeg har brug for. Mere brunt klamphug!,"Genau das, was ich brauchte. Mehr brauner Schlamm!",,,Justo lo que necesito. ¡Más lodo marrón!,,"Juuri, mitä tarvitsen: lisää ruskeaa mönjää!","Juste ce qu'il me fallait, encore de la crasse marron!",Pont ez hiányzott. Még több barna trutymák.,Proprio quello che volevo vedere. Altro liquido marrone!,万事休すだ。更に茶色いモノだ!,"또 시궁창이라니, 정말 보기 좋네!",Precies wat ik nodig heb. Meer bruine drab!,Akkurat det jeg trenger. Mer brunt gjørme!,Właśnie tego mi trzeba. Więcej brązowej mazi!,Justo o que eu precisava. Mais meleca marrom!,,Exact ce îmi trebuie. Mai multă mâzgă maro!,"То, что надо. Ещё больше коричневой жижи!",,Precis vad jag behöver. Mer brunt kladd!,Tam da ihtiyacım olan şey. Daha fazla kahverengi yapışkan! +"Hey, look! I think that's the door Weran wants ajar!",TXT_SUB_LOG31,,,,"Hele, podívej! Myslím, že to jsou ty dveře, které chce Weran nechat otevřené!","Hey, se! Jeg tror, det er døren, som Weran vil have på klem!","Sieh dort! Ich glaube, das ist die Tür, die Weran geöffnet haben möchte.",,,"¡Eh, mira! ¡Creo que esa es la puerta que Weran quiere entreabierta!",,"Hei, katso! Tuo on varmaankin se ovi, jonka Weran haluaa raolleen!","Hé, regarde! On dirait que c'est la porte que Weran veut qu'on coince!",Nézz oda! Azt hiszem ez az az ajtó amit félig ki akar nyitni Weran.,"Ehi, guarda! Credo quella sia la porta che Weran vuole aprire!",,저기야! 저게 워렌이 열어줬으면 하는 문일 거야.,"Hé, kijk! Ik denk dat dat de deur is die Weran op een kier wil hebben!","Hei, se! Jeg tror det er døra Weran vil ha på gløtt!","Hej, patrzcie! To chyba te drzwi, które Weran chce uchylić!",Olha! Acho que essa é a porta que o Weran quer que fique aberta!,,"Hei, uite! Acolo cred că e ușa pe care o vrea Weran!","О, смотри! Похоже, это та самая дверь, которую хочет приоткрыть Уэран!",,Titta! Jag tror att det är dörren som Weran vill ha på glänt!,"Hey, bakın! Sanırım Weran'ın aralık kalmasını istediği kapı bu!" +"Shut your eyes! I don't wanna see! Oh, too late... Yuck. That doesn't look like a human body. What has the Order done? I gotta report this to command.",TXT_SUB_LOG32,,,,"Zavři oči! Nechci to vidět! Ah, moc pozdě... Fuj. To ani nevypadá jako lidské tělo. Co to Řád provedl? Musím tohle nahlásit velení.","Luk øjnene! Jeg vil ikke se! Åh, for sent... Yuck. Det ligner ikke et menneskeligt lig. Hvad har Ordenen gjort? Jeg må rapportere det til kommandoen.","Mach die Augen zu! Ich will das nicht sehen. Zu spät... Igitt, das sieht gar nicht aus wie ein menschlicher Körper. Was hat der Orden getan? Ich muss das an die Kommandozentrale weitergeben.",,,"¡Cierra los ojos! ¡No quiero ver! Oh, demasiado tarde... Puaj. Eso no parece un cuerpo humano. ¿Que ha hecho la Orden? Tengo que reportar esto al comando.",,"Sulje silmäsi! En halua nähdä! Äh, myöhäistä... yäk. Tuo ei näytä ihmisruumiilta. Mitä Veljeskunta oikein on tehnyt? Minun on ilmoitettava tästä komentokeskukselle.","Ferme tes yeux, je ne veux pas voire ça! Oh, trop tard.. Beurk, on dirait pas un corps humain, qu'est-ce que l'ordre à fait? Il faut que je rapporte ça au commandement.",Csukd be a szemed! Nem akarom látni! Ó túl késő...fúj. Ez nem úgy néz ki mint egy emberi tetem. Mit tett a Rend? Ezt jeleznem kell az irányításnak.,"Chiudi gli occhi! Non voglio vedere! Ah, troppo tardi... Non sembra un corpo umano. Che cosa ha fatto l'Ordine? Devo riportare questo al comando.",,"눈 감아! 보고 싶지 않아! 오, 너무 늦었네... 역겨워. 전혀 사람 몸 같지 않던데, 대체 오더가 무슨 짓을 한 거지? 본부에 이걸 보고해야겠어.","Sluit je ogen! Ik wil het niet zien! Oh, te laat.... Yuck. Dat ziet er niet uit als een menselijk lichaam. Wat heeft de Orde gedaan? Ik moet dit aan het commando melden.","Lukk øynene! Jeg vil ikke se! Å, for sent... Æsj. Det ser ikke ut som en menneskekropp. Hva har Ordenen gjort? Jeg må rapportere dette til kommandoen.","Zamknij oczy! Nie chcę widzieć! Och, za późno... Fuj. To nie wygląda jak ludzkie ciało. Co zrobił Zakon? Muszę to zgłosić do dowództwa.","Feche os olhos! Eu não quero ver! Ai, tarde demais... Eca. Isso não parece um corpo humano. O que foi que a Ordem fez? Preciso relatar isso ao comando.",,Închide ochii! Nu vreau să văd! Oh... prea târziu... Yuck. Nu pare un cadavru uman. Ce a făcut Ordinul? Trebuie să raportez asta.,"Зажмурься! Я не хочу это видеть! Ох, уже поздно... Какая дрянь. Это даже не выглядит как человеческое тело. Что творит этот Орден! Я немедленно доложу в штаб.",,"Håll ögonen! Jag vill inte se! Åh, för sent... Usch. Det ser inte ut som en människokropp. Vad har Orden gjort? Jag måste rapportera det här till befälet.","Kapa gözlerini! Görmek istemiyorum! Oh, çok geç... İğrenç. Bu bir insan vücuduna benzemiyor. Tarikat ne yaptı? Bunu komutaya rapor etmeliyim." +Why can't we do a mission in a field of flowers for once?,TXT_SUB_LOG33,MAP06: After giving the guard's uniform.,,,Nemůžeme někdy mít misi na poli plném kvítí?,Hvorfor kan vi ikke for en gangs skyld udføre en mission i en blomstermark?,Warum können wir nicht mal eine Mission in einem Blumenfeld haben? ,,,¿Por que no podemos hacer una misión en un campo de flores por una vez?,,Miksei meillä kerrankin voisi olla tehtävä kukkakedolla?,"Pourquoi est-ce qu'on ne peut pas avoir une mission dans un champ de fleurs, pour une fois?",Miért nem mehetünk legalább egyszer egy virágmezős misszióra?,Perché non possiamo fare una missione in un campo di fiori per una volta?,どうして私達は綺麗な場所で一度でも任務遂行が出来ないんだ?,왜 우리는 딱 한 번이라도 꽃밭에서 작전을 수행할 수 없는 걸까?,Waarom kunnen we niet een keer een missie doen in een bloemenveld?,Hvorfor kan vi ikke gjøre et oppdrag i en blomstereng for en gangs skyld?,Dlaczego nie możemy choć raz wykonać misji na polu kwiatów?,Por que é que a gente não faz uma missão num campo florido pelo menos uma vez?,,De ce nu putem avea o misiune pe un câmp de flori măcar odată?,Ну почему наши задания не могут разворачиваться на цветочном лугу?,,Varför kan vi inte göra ett uppdrag på ett blomsterfält för en gångs skull?,Neden bir kez olsun çiçek tarlasında görev yapamıyoruz? I hate to say it but this reminds me of home. I'm underground not that far from here.,TXT_SUB_LOG34,MAP06: Weran's hideout.,,,"Říká se mi to těžko, ale tohle mi připomíná domov. Jsem v podzemí ne tak daleko odsud.","Jeg hader at sige det, men det her minder mig om mit hjem. Jeg er under jorden ikke så langt herfra.","Ich sage es nicht gerne, aber das erinnert mich an Zuhause. Ich bin auch im Untergrund, nicht weit von hier.",,,Odio decirlo pero esto me recuerda a mi hogar. Estoy bajo tierra no muy lejos de aquí.,,"Inhottaa sanoa, mutta tästä tulee koti mieleen: Olen maan alla, en niin kaukana täältä.","J'ai vraiment pas envie de l'admettre, mais ça me rappelle ma maison.. Je suis sous terre pas loin d'ici.","Nem szívesen mondom ezt, de ez az otthonomra emlékeztet. Föld alatt van az is nem túl messze innen.","Mi duole dirlo, ma tutto ciò mi ricorda casa. Anche io mi trovo sottoterra, non troppo lontano da qui.","言いたくないが私の家の事を思い出させるわ。 -私はこの地下から遠くない場所にいたのよ。","말하긴 싫지만, 여긴 꼭 내 집을 보는 것 같아... 난 여기서 멀지 않은 지하에 있어.","Ik haat het om het te zeggen, maar dit doet me denken aan thuis. Ik ben niet zo ver van hier ondergronds.","Jeg hater å si det, men dette minner meg om hjemme. Jeg er under jorden ikke så langt herfra.","Nie chcę tego mówić, ale to przypomina mi dom. Jestem pod ziemią, nie tak daleko stąd.",Odeio dizer isso mas isso lembra a minha casa. Estou sob o solo não muito longe daqui.,,Îmi pare rău s-o spun dar asta îmi aduce aminte de casă. Stau sub pământ nu departe de aici.,"Не хотела говорить, но это место напоминает мне о доме. Сейчас я в подземелье, которое не так уж далеко отсюда.",,"Bunu söylemekten nefret ediyorum ama bu bana evimi hatırlatıyor. Yeraltındayım, buradan çok uzakta değilim." -"Don't ask me where we are. I'm lost, too. Sorry.",TXT_SUB_LOG35,MAP06: Exit of the secret entrance.,,,"Neptej se mě, kde jsme. Taky jsem ztracená. Promiň.","Spørg mig ikke, hvor vi er. Jeg er også faret vild. Jeg er også fortabt. Undskyld.","Frag mich nicht, wo wir sind, ich habe keine Ahnung. Tut mir leid.",,,"No me preguntes en dónde estamos, que yo también estoy perdida. Perdón.",,"Älä kysy minulta, missä olemme. Olen myös eksyksissä; pahoittelut.","Me demande pas où on est, je suis aussi perdue que toi, désolée..","Ne kérdezd hol vagyunk. Én is el vagyok veszve, sajnálom.",Non chiedermi dove siamo. Mi sono persa anche io. Mi spiace...,今いる場所について私に聞かないでくれ。私も迷った。すまない。,"여기가 어딘지 묻지 마. 나도 길을 잃었거든, 미안해.",Vraag me niet waar we zijn. Ik ben ook verdwaald. Sorry.,Ikke spør meg hvor vi er. Jeg har også gått meg vill. Unnskyld meg.,"Nie pytaj mnie, gdzie jesteśmy. Ja też się zgubiłem. Przepraszam.",Não me pergunte onde estamos. Já me perdi. Desculpe.,,"Numă întreba unde suntem, și eu sunt pierdut. Scuze.","Даже не спрашивай, где мы. Я сама не знаю, извини.",,Bana nerede olduğumuzu sorma. Ben de kayboldum. Özür dilerim. -That brick... Didn't we pass that brick? No...,TXT_SUB_LOG36,MAP06: Secret entrance from the castle.,,,Ta cihla... Neminuli jsme tamtu cihlu? Ne...,Den mursten... Har vi ikke passeret den mursten? Nej...,Der Stein... Sind wir nicht an dem Stein vorbeigekommen? Nein...,,,"Ese ladrillo... ¿No habíamos pasado ya por ese ladrillo? Ah, no...",,Tuo tiilenmurikka... Emmekö jo menneet sen ohitse? Ei kun...,Cette brique.. On n'a pas passé cette brique avant? Non..,Az a tégla...Nem hagytuk már el azt a téglát egyszer? Nem...,Quel mattone... Abbiamo già superato quel mattone? No...,あの煉瓦...前通ったレンガか?いや...,저 벽... 아까 저 벽을 지나가지 않았던가? 아닌데...,Die steen.... Hebben we die steen niet gepasseerd? Nee....,Den mursteinen... Passerte vi ikke den mursteinen? Nei...,Ta cegła... Czy nie minęliśmy tej cegły? Nie...,Aquele tijolo... Já não passamos daquele tijolo? Não...,,Cărpmida aceea... Nu am trecut de ea? Nu...,Этот кирпич... Разве мы здесь не были? Нет...,,Şu tuğla. O tuğlayı geçmemiş miydik? Hayır. -"Command, he's done it! The gates are open. Send in the shock troops and tell Macil we're coming in! ",TXT_SUB_LOG37,MAP06: After destroying the gate controls.,,,"Velení, dokázal to! Brány jsou otevřené. Pošlete tam úderníky a řekněte Macilovi, že přicházíme!","Kommando, han har gjort det! Portene er åbne. Send choktropperne ind og fortæl Macil, at vi kommer ind!",Kommandozentrale: Er hat's geschafft! Die Tore sind offen. Schickt die Schocktruppen hinein und sagt Macil das wir auf dem Weg sind! Lass uns zur Frontbasis zurückkehren.,,,"Comando, ¡Lo ha hecho! Las puertas están abiertas. ¡Enviad a las tropas de choque y decidle a Macil que venimos adentro!","Comando, ¡Lo ha hecho! Las puertas están abiertas. ¡Envíen las tropas de choque y díganle a Macil que estamos entrando!","Komentokeskus, hän teki sen! Portit ovat auki; lähettäkää iskujoukot ja kertokaa Macilille, että vyörymme sisään!","C'est bon, commandement, il a réussi! Les portes sont ouvertes, envoyez les soldats de choc et dites à Macil que l'on arrive!","Irányítás, sikerült neki! A kapuk nyitva állnak. Küldjétek be a sokkolós egységeket, és mondjátok meg Macilnak, hogy behatolunk!","Comando, ce l'ha fatta! I cancelli sono aperti. Mandate avanti le truppe e dite a Macil che stiamo arrivando!","司令官、彼はやったぞ! -ゲートが開いた。突撃部隊を送って我々も続くとマシルに伝えてくれ!","본부, 그가 해냈습니다! 성문이 열렸습니다. 공습부대를 성문으로 이동시키고 사령관님께 우리들도 따라올 거라고 전해주세요.","Commando, hij heeft het gedaan! De poorten zijn open. Stuur de stoottroepen naar binnen en zeg Macil dat we binnenkomen!","Kommando, han har klart det! Portene er åpne. Send inn sjokktroppene og si til Macil at vi kommer inn!","Dowództwo, on to zrobił! Brama jest otwarta. Wyślijcie oddziały uderzeniowe i powiedzcie Macilowi, że wchodzimy!","Comando, ele conseguiu! Os portões estão abertos. Enviem as tropas de choque e digam ao Macil que estamos entrando!",,"Centru, am reușit! Porțile sunt deschise. Trimite trupele de șoc si spune-i lui Macil că intrăm!","Штаб, он выполнил задание! Ворота открыты. Посылайте ударный отряд и доложите Мэйсилу, что мы пробились!",,"Komuta, başardı! Kapılar açıldı. Şok birliklerini gönderin ve Macil'e geldiğimizi söyleyin!" +私はこの地下から遠くない場所にいたのよ。","말하긴 싫지만, 여긴 꼭 내 집을 보는 것 같아... 난 여기서 멀지 않은 지하에 있어.","Ik haat het om het te zeggen, maar dit doet me denken aan thuis. Ik ben niet zo ver van hier ondergronds.","Jeg hater å si det, men dette minner meg om hjemme. Jeg er under jorden ikke så langt herfra.","Nie chcę tego mówić, ale to przypomina mi dom. Jestem pod ziemią, nie tak daleko stąd.",Odeio dizer isso mas isso lembra a minha casa. Estou sob o solo não muito longe daqui.,,Îmi pare rău s-o spun dar asta îmi aduce aminte de casă. Stau sub pământ nu departe de aici.,"Не хотела говорить, но это место напоминает мне о доме. Сейчас я в подземелье, которое не так уж далеко отсюда.",,"Jag hatar att säga det, men det här påminner mig om mitt hem. Jag är underjordisk inte så långt härifrån.","Bunu söylemekten nefret ediyorum ama bu bana evimi hatırlatıyor. Yeraltındayım, buradan çok uzakta değilim." +"Don't ask me where we are. I'm lost, too. Sorry.",TXT_SUB_LOG35,MAP06: Exit of the secret entrance.,,,"Neptej se mě, kde jsme. Taky jsem ztracená. Promiň.","Spørg mig ikke, hvor vi er. Jeg er også faret vild. Jeg er også fortabt. Undskyld.","Frag mich nicht, wo wir sind, ich habe keine Ahnung. Tut mir leid.",,,"No me preguntes en dónde estamos, que yo también estoy perdida. Perdón.",,"Älä kysy minulta, missä olemme. Olen myös eksyksissä; pahoittelut.","Me demande pas où on est, je suis aussi perdue que toi, désolée..","Ne kérdezd hol vagyunk. Én is el vagyok veszve, sajnálom.",Non chiedermi dove siamo. Mi sono persa anche io. Mi spiace...,今いる場所について私に聞かないでくれ。私も迷った。すまない。,"여기가 어딘지 묻지 마. 나도 길을 잃었거든, 미안해.",Vraag me niet waar we zijn. Ik ben ook verdwaald. Sorry.,Ikke spør meg hvor vi er. Jeg har også gått meg vill. Unnskyld meg.,"Nie pytaj mnie, gdzie jesteśmy. Ja też się zgubiłem. Przepraszam.",Não me pergunte onde estamos. Já me perdi. Desculpe.,,"Numă întreba unde suntem, și eu sunt pierdut. Scuze.","Даже не спрашивай, где мы. Я сама не знаю, извини.",,Fråga mig inte var vi är. Jag är också vilse. Jag är också vilse.,Bana nerede olduğumuzu sorma. Ben de kayboldum. Özür dilerim. +That brick... Didn't we pass that brick? No...,TXT_SUB_LOG36,MAP06: Secret entrance from the castle.,,,Ta cihla... Neminuli jsme tamtu cihlu? Ne...,Den mursten... Har vi ikke passeret den mursten? Nej...,Der Stein... Sind wir nicht an dem Stein vorbeigekommen? Nein...,,,"Ese ladrillo... ¿No habíamos pasado ya por ese ladrillo? Ah, no...",,Tuo tiilenmurikka... Emmekö jo menneet sen ohitse? Ei kun...,Cette brique.. On n'a pas passé cette brique avant? Non..,Az a tégla...Nem hagytuk már el azt a téglát egyszer? Nem...,Quel mattone... Abbiamo già superato quel mattone? No...,あの煉瓦...前通ったレンガか?いや...,저 벽... 아까 저 벽을 지나가지 않았던가? 아닌데...,Die steen.... Hebben we die steen niet gepasseerd? Nee....,Den mursteinen... Passerte vi ikke den mursteinen? Nei...,Ta cegła... Czy nie minęliśmy tej cegły? Nie...,Aquele tijolo... Já não passamos daquele tijolo? Não...,,Cărpmida aceea... Nu am trecut de ea? Nu...,Этот кирпич... Разве мы здесь не были? Нет...,,Den där tegelstenen... Passerade vi inte den stenen? Nej...,Şu tuğla. O tuğlayı geçmemiş miydik? Hayır. +"Command, he's done it! The gates are open. Send in the shock troops and tell Macil we're coming in! ",TXT_SUB_LOG37,MAP06: After destroying the gate controls.,,,"Velení, dokázal to! Brány jsou otevřené. Pošlete tam úderníky a řekněte Macilovi, že přicházíme!","Kommando, han har gjort det! Portene er åbne. Send choktropperne ind og fortæl Macil, at vi kommer ind!",Kommandozentrale: Er hat's geschafft! Die Tore sind offen. Schickt die Schocktruppen hinein und sagt Macil das wir auf dem Weg sind! Lass uns zur Frontbasis zurückkehren.,,,"Comando, ¡lo ha conseguido! Las puertas están abiertas. ¡Enviad a las tropas de choque y decidle a Macil que estamos entrando!","Comando, ¡lo logró! Las puertas están abiertas. ¡Envíen las tropas de choque y díganle a Macil que estamos entrando!","Komentokeskus, hän teki sen! Portit ovat auki; lähettäkää iskujoukot ja kertokaa Macilille, että vyörymme sisään!","C'est bon, commandement, il a réussi! Les portes sont ouvertes, envoyez les soldats de choc et dites à Macil que l'on arrive!","Irányítás, sikerült neki! A kapuk nyitva állnak. Küldjétek be a sokkolós egységeket, és mondjátok meg Macilnak, hogy behatolunk!","Comando, ce l'ha fatta! I cancelli sono aperti. Mandate avanti le truppe e dite a Macil che stiamo arrivando!","司令官、彼はやったぞ! +ゲートが開いた。突撃部隊を送って我々も続くとマシルに伝えてくれ!","본부, 그가 해냈습니다! 성문이 열렸습니다. 공습부대를 성문으로 이동시키고 사령관님께 우리들도 따라올 거라고 전해주세요.","Commando, hij heeft het gedaan! De poorten zijn open. Stuur de stoottroepen naar binnen en zeg Macil dat we binnenkomen!","Kommando, han har klart det! Portene er åpne. Send inn sjokktroppene og si til Macil at vi kommer inn!","Dowództwo, on to zrobił! Brama jest otwarta. Wyślijcie oddziały uderzeniowe i powiedzcie Macilowi, że wchodzimy!","Comando, ele conseguiu! Os portões estão abertos. Enviem as tropas de choque e digam ao Macil que estamos entrando!",,"Centru, am reușit! Porțile sunt deschise. Trimite trupele de șoc si spune-i lui Macil că intrăm!","Штаб, он выполнил задание! Ворота открыты. Посылайте ударный отряд и доложите Мэйсилу, что мы пробились!",,"Kommando, han har gjort det! Portarna är öppna. Skicka in chocktrupperna och säg till Macil att vi kommer in!","Komuta, başardı! Kapılar açıldı. Şok birliklerini gönderin ve Macil'e geldiğimizi söyleyin!" "We have conflicting reports about the Programmer's location. One say he's in a computer room, another that he's in a keep and yet another that mentions a long hallway. Sorry. ",TXT_SUB_LOG38,MAP07: Entrace.,,,"Máme rozcházející se zprávy o Programátorově pozici. Jedna mluví o místnosti s počítači, druhá, že je v nějaké pevnosti a třetí zmiňuje dlouhou chodbu. Promiň.","Vi har modstridende rapporter om programmørens placering. En siger, at han er i et computerrum, en anden, at han er i et tårn og endnu en anden, der nævner en lang gang. Undskyld.","Wir haben widersprüchliche Angaben über seinen Aufenthaltsort. Eine sagt, in einem Computerraum, ein anderer, dass er sich in einem Tempelkeller versteckt und noch ein anderer sagt was vom Ende eines langen Flurs.",,,"Tenemos informes contradictorios sobre la ubicación del Programador: uno dice que está en una sala de ordenadores, otro que está en un torreón y otro más menciona un pasillo largo. Perdón.","Tenemos informes contradictorios sobre la ubicación del Programador: uno dice que está en una sala de computadoras, otro que está en un torreón y otro más menciona un pasillo largo. Perdón.","Meillä eriäviä tietoja Ohjelmoitsijan sijainnista: Yhden mukaan hän on tietokonehuoneessa, toisen mukaan linnakkeessa ja vielä kolmas, joka mainitsee pitkän käytävän. Valitan.","On a des rapports contradictoires au sujet d'où se trouve le programmeur. On me dit d'un côté qu'il est dans une salle des ordinateurs, un autre me dit qu'il est dans un donjon, et un autre me dit qu'il est dans un long couloir.. Désolé.","Ellentmondásos jelentéseink vannak a Programozó hollétéről. Egy szerint a számítógép szobában van, másik szerint a vártoronyban, harmadik egy hosszú folyosót említ. Sajnálom.","I rapporti che abbiamo sulla sua posizione si contraddicono. Uno lo piazza in una stanza di computer, un altro in un tempio di sottolivello, e un altro ancora alla fine di un lungo corridoio.","プログラマーの居場所について矛盾する報告もあるわ。 ある人はコンピューター室にいる、別の人は保管室にいる、 -また別の人は長い廊下にいるとも言っていたわ。何とも言えない。","프로그래머의 위치에 관한 보고들이 전부 제각각이야. 하나는 컴퓨터실에, 또 하나는 성채에, 다른 하나는 긴 복도에 있대. 정말 유감이야.","We hebben tegenstrijdige berichten over de locatie van de programmeur. De een zegt dat hij in een computerkamer is, de ander dat hij in een donjon zit en weer een ander die een lange gang noemt. Sorry.","Vi har motstridende rapporter om hvor programmereren befinner seg. En sier at han er i et datarom, en annen at han er i en borg og en tredje nevner en lang korridor. Unnskyld.","Mamy sprzeczne raporty na temat lokalizacji Programisty. Jeden mówi, że jest w sali komputerowej, inny, że w magazynie, a jeszcze inny, że wspomina o długim korytarzu. Przepraszam.","Temos relatos conflitantes sobre onde o Programador se encontra. Um deles diz que ele está na sala de informática, outro que ele está na fortaleza e outro diz que ele está no fim de um longo corredor. Desculpe.",,"Avem rapoarte conflictuale în privința locației Programatorului. Unul zice că e într-o sală de calculatoare, altul într-o curte, iar altul că e intr-un hol lung. Scuze.","Наши сведения о местонахождении Программиста противоречивы. Одни говорят, что он в компьютерной комнате, другие, что он укрывается в цитадели, а третьи, что он в конце длинного коридора. Извини.",,"Programcının yeri hakkında çelişkili raporlarımız var. Biri bir bilgisayar odasında olduğunu söylüyor, diğeri bir mahzende ve bir başkası da uzun bir koridordan bahsediyor. Özür dilerim." -"Ah, it's good to be on the offensive again. Give 'em hell, guys!",TXT_SUB_LOG39,MAP07: Near the crusaders.,,,"Á, je to fajn být zase na straně ofenzívy. Jen jim dejte, chlapi!","Ah, det er godt at være i offensiven igen. Giv dem en røvfuld, gutter!","Ah, es ist gut, wieder in der Offensive zu sein. Macht sie fertig, Leute!",,,"Ah, sienta bien estar a la ofensiva de nuevo. ¡Dadles caña, chicos!",,"Aah, tekeepä hyvää olla taas vaihteeksi hyökkäävänä osapuolena. Hakkaa päälle, pojat!","Ah, ça fait du bien d'être sur l'offensive une fois de plus! Foutez leur la misère, les gars!","Áh, jó újra támadásba lendülni. Leckéztessétek meg őket!","Ah, che bello essere di nuovo all'offensiva! Mostrategli la via per l'inferno, ragazzi!",再襲撃するには良い機会だ。地獄に送ってやれ、皆!,"아, 이렇게 다시 공격적으로 나가니 좋다. 맛 좀 보여줘, 얘들아!","Ah, het is goed om weer in de aanval te zijn. Geef ze de hel, jongens!","Ah, det er godt å være på offensiven igjen. Gi dem helvete, folkens!","Dobrze jest być znowu w ofensywie. Zróbcie im piekło, chłopaki!","Ah, é bom estar na ofensiva mais uma vez. Chumbo neles, pessoal!",,"Ah, e bine că mă regăsesc din nou pe partea ofensivă. Dați-le bătaie!","Наконец-то, мы снова переходим в наступление! Всыпьте им как следует, парни!",,Tekrar saldırıya geçmek güzel. Canlarına okuyun çocuklar! +また別の人は長い廊下にいるとも言っていたわ。何とも言えない。","프로그래머의 위치에 관한 보고들이 전부 제각각이야. 하나는 컴퓨터실에, 또 하나는 성채에, 다른 하나는 긴 복도에 있대. 정말 유감이야.","We hebben tegenstrijdige berichten over de locatie van de programmeur. De een zegt dat hij in een computerkamer is, de ander dat hij in een donjon zit en weer een ander die een lange gang noemt. Sorry.","Vi har motstridende rapporter om hvor programmereren befinner seg. En sier at han er i et datarom, en annen at han er i en borg og en tredje nevner en lang korridor. Unnskyld.","Mamy sprzeczne raporty na temat lokalizacji Programisty. Jeden mówi, że jest w sali komputerowej, inny, że w magazynie, a jeszcze inny, że wspomina o długim korytarzu. Przepraszam.","Temos relatos conflitantes sobre onde o Programador se encontra. Um deles diz que ele está na sala de informática, outro que ele está na fortaleza e outro diz que ele está no fim de um longo corredor. Desculpe.",,"Avem rapoarte conflictuale în privința locației Programatorului. Unul zice că e într-o sală de calculatoare, altul într-o curte, iar altul că e intr-un hol lung. Scuze.","Наши сведения о местонахождении Программиста противоречивы. Одни говорят, что он в компьютерной комнате, другие, что он укрывается в цитадели, а третьи, что он в конце длинного коридора. Извини.",,"Vi har motstridiga rapporter om var programmeraren befinner sig. En säger att han är i ett datorrum, en annan att han är i ett torn och ytterligare en annan nämner en lång korridor. Jag är ledsen.","Programcının yeri hakkında çelişkili raporlarımız var. Biri bir bilgisayar odasında olduğunu söylüyor, diğeri bir mahzende ve bir başkası da uzun bir koridordan bahsediyor. Özür dilerim." +"Ah, it's good to be on the offensive again. Give 'em hell, guys!",TXT_SUB_LOG39,MAP07: Near the crusaders.,,,"Á, je to fajn být zase na straně ofenzívy. Jen jim dejte, chlapi!","Ah, det er godt at være i offensiven igen. Giv dem en røvfuld, gutter!","Ah, es ist gut, wieder in der Offensive zu sein. Macht sie fertig, Leute!",,,"Ah, sienta bien estar a la ofensiva de nuevo. ¡Dadles caña, chicos!",,"Aah, tekeepä hyvää olla taas vaihteeksi hyökkäävänä osapuolena. Hakkaa päälle, pojat!","Ah, ça fait du bien d'être sur l'offensive une fois de plus! Foutez leur la misère, les gars!","Áh, jó újra támadásba lendülni. Leckéztessétek meg őket!","Ah, che bello essere di nuovo all'offensiva! Mostrategli la via per l'inferno, ragazzi!",再襲撃するには良い機会だ。地獄に送ってやれ、皆!,"아, 이렇게 다시 공격적으로 나가니 좋다. 맛 좀 보여줘, 얘들아!","Ah, het is goed om weer in de aanval te zijn. Geef ze de hel, jongens!","Ah, det er godt å være på offensiven igjen. Gi dem helvete, folkens!","Dobrze jest być znowu w ofensywie. Zróbcie im piekło, chłopaki!","Ah, é bom estar na ofensiva mais uma vez. Chumbo neles, pessoal!",,"Ah, e bine că mă regăsesc din nou pe partea ofensivă. Dați-le bătaie!","Наконец-то, мы снова переходим в наступление! Всыпьте им как следует, парни!",,"Ah, det är skönt att vara på offensiven igen. Ge dem ett helvete, killar!",Tekrar saldırıya geçmek güzel. Canlarına okuyun çocuklar! This looks good. Computers... Programmer... What do you think?,TXT_SUB_LOG40,MAP07: Computer room.,,,Tohle vypadá dobře. Počítače... Programátor... Co myslíš?,Det ser godt ud. Computere... Programmør... Hvad synes du?,Das sieht gut aus. Computer... Programmierer... Was denkst du?,,,Esto pinta bien. Computadoras... Programador... ¿Tú que crees?,,"Tämä näyttää hyvältä. Tietokoneita, ohjelmoitsija... Mitä tuumit?","Tout à l'air bien. Ordinateurs, Programmeur, tu en pense quoi?",Ez jól néz ki. Számítógépek... Programozó... Mit gondolsz?,Promette bene. Computer... Programmatore... Che ne pensi?,"これは良い。コンピューター... -プログラマー...アンタはどう思う?",이거 괜찮아 보이네. 컴퓨터들과... 프로그래머... 어떻게 생각해?,Dit ziet er goed uit. Computers.... Programmeur.... Wat vind je ervan?,Dette ser bra ut. Datamaskiner... Programmerer... Hva syns du?,To wygląda dobrze. Komputery... Programista... Co o tym sądzisz?,Isto parece bom. Computadores... Programador... O que você acha?,,Arată bine. Calculatoare... Programator... Ce zici?,"Похоже, это здесь. Компьютеры... Программист... Что скажешь?",,Bu iyi görünüyor. Bilgisayarlar. Programcı. Ne düşünüyorsun? -This must be the long hallway. Either that or my sense of scale is shot to hell.,TXT_SUB_LOG41,MAP07: Building before the brigde.,,,"Tohle musí být ta dlouhá chodba. Buď, a nebo už špatně vidím.","Dette må være den lange gang. Enten det, eller også er min fornemmelse for skalaer skudt ad helvede til.","Das muss der lange Flur sein. Entweder das, oder mein Sinn für Größe ist nicht in Ordnung.",,,Este debe ser el pasillo largo. O es eso o mi sentido de la escala está fastidiado.,,"Tämä on varmaankin se pitkä käytävä. Joko niin, tai sitten olen ihan pihalla mittasuhteista.","Ca doit être le long couloir, ça où ma perception des choses est un peu foutue..","Ez lehet a hosszú folyosó. Vagy ez, vagy a térérzékem tropára ment.",Questo deve essere il lungo corridoio. Oppure il mio senso della prospettiva è proprio andato a farsi benedire.,この長い廊下に違いない。それか私のスケール感とどちらかが撃ち落されるな。,"여기가 바로 긴 복도겠네. 아주 길다고 생각해, 아니면 내 머리가 이상하겠지.",Dit moet de lange gang zijn. Of dat of mijn gevoel voor schaalvergroting is naar de hel geschoten.,"Dette må være den lange gangen. Enten det, eller så er målestokkfølelsen min ødelagt.","To musi być ten długi korytarz. Albo to, albo moje wyczucie skali jest do dupy.",Esse deve ser o longo corredor. Ou isso ou o meu senso de escala foi pro saco.,,"Ăsta trebuie să fie holul lung. Fie asta, fie capacitatea mea de a aprecia scara e varză.","Должно быть, длинный коридор — это здесь. Ну или у меня всё плохо с глазомером.",,Burası uzun koridor olmalı. Ya öyle ya da benim ölçek algım cehenneme döndü. +プログラマー...アンタはどう思う?",이거 괜찮아 보이네. 컴퓨터들과... 프로그래머... 어떻게 생각해?,Dit ziet er goed uit. Computers.... Programmeur.... Wat vind je ervan?,Dette ser bra ut. Datamaskiner... Programmerer... Hva syns du?,To wygląda dobrze. Komputery... Programista... Co o tym sądzisz?,Isto parece bom. Computadores... Programador... O que você acha?,,Arată bine. Calculatoare... Programator... Ce zici?,"Похоже, это здесь. Компьютеры... Программист... Что скажешь?",,Det här ser bra ut. Datorer... Programmerare... Vad tycker du?,Bu iyi görünüyor. Bilgisayarlar. Programcı. Ne düşünüyorsun? +This must be the long hallway. Either that or my sense of scale is shot to hell.,TXT_SUB_LOG41,MAP07: Building before the brigde.,,,"Tohle musí být ta dlouhá chodba. Buď, a nebo už špatně vidím.","Dette må være den lange gang. Enten det, eller også er min fornemmelse for skalaer skudt ad helvede til.","Das muss der lange Flur sein. Entweder das, oder mein Sinn für Größe ist nicht in Ordnung.",,,Este debe ser el pasillo largo. O es eso o mi sentido de la escala está fastidiado.,,"Tämä on varmaankin se pitkä käytävä. Joko niin, tai sitten olen ihan pihalla mittasuhteista.","Ca doit être le long couloir, ça où ma perception des choses est un peu foutue..","Ez lehet a hosszú folyosó. Vagy ez, vagy a térérzékem tropára ment.",Questo deve essere il lungo corridoio. Oppure il mio senso della prospettiva è proprio andato a farsi benedire.,この長い廊下に違いない。それか私のスケール感とどちらかが撃ち落されるな。,"여기가 바로 긴 복도겠네. 아주 길다고 생각해, 아니면 내 머리가 이상하겠지.",Dit moet de lange gang zijn. Of dat of mijn gevoel voor schaalvergroting is naar de hel geschoten.,"Dette må være den lange gangen. Enten det, eller så er målestokkfølelsen min ødelagt.","To musi być ten długi korytarz. Albo to, albo moje wyczucie skali jest do dupy.",Esse deve ser o longo corredor. Ou isso ou o meu senso de escala foi pro saco.,,"Ăsta trebuie să fie holul lung. Fie asta, fie capacitatea mea de a aprecia scara e varză.","Должно быть, длинный коридор — это здесь. Ну или у меня всё плохо с глазомером.",,Det här måste vara den långa korridoren. Antingen det eller så är min skalförståelse helt borta.,Burası uzun koridor olmalı. Ya öyle ya da benim ölçek algım cehenneme döndü. "This is all the hallmarks of a temple of evil. Severe architecture, big banner... I'd say bingo!",TXT_SUB_LOG42,MAP07: Northeast bulding.,,,"Tohle jsou všechno puncy chrámu zla - hrubá architektura, velký prapor... řekla bych, že bingo!","Dette er alle kendetegnene på et ondskabens tempel. Alvorlig arkitektur, stort banner... Jeg ville sige bingo!","Das sind alles die Zeichen für einen Tempel des Bösen. Strenge Architektur, große Banner... Ich würde sagen: „Bingo!“",,,"Esto tiene toda la pinta de un templo maligno. Arquitectura austera, gran estandarte... ¡Yo diría bingo!",,"Tämä täyttää pahuuden temppelin kaikki tunnusmerkit: tuima arkkitehtuuri, suuri tunnuslippu... Sanoisin, että bingo!","Ca a le décor d'un temple maléfique.. Architecture sinistre, énorme bannière, je dis bingo!","Ha gonosz templom lennék, így néznék ki. Kimért architektúra, óriási lobogó... amondó vagyok megleltük.","Questo ha proprio tutti i tratti di un tempio del male. Architettura minacciosa, grosso stemma... Io direi che abbiamo fatto centro!","これら全部悪の神殿の特徴だ。重苦しい建築物、デカいバナー... -ビンゴだわ!","악당 같은 요소가 모인 건물이네! 엄격한 건물 구조, 커다란 기... 완전 만장일치야.","Dit zijn alle kenmerken van een tempel van het kwaad. Strenge architectuur, grote spandoeken.... Ik zou zeggen bingo!","Dette er alle kjennetegnene på et ondskapens tempel. Streng arkitektur, stort banner... Jeg vil si bingo!","To wszystko ma znamiona świątyni zła. Surowa architektura, wielki baner... Powiedziałbym, że bingo!","Isso tem bem cara de templo malígno. Arquitetura sinístra, estandarte grande... Acho que acertamos na mosca!",,"Ăsta e însemnul unui templu malefic. Arhitectura, steagurile... Eu zic bingo!","Всё это очень похоже на зловещий храм. Строгая архитектура, огромное знамя... Да, это определённо он!",,"Burası bir şeytan tapınağının tüm özelliklerini taşıyor. Sert mimari, büyük afiş. Bingo derdim!" -This is the almighty Programmer? No way!,TXT_SUB_LOG43,,,,Tohle je ten všemocný Programátor? To není možné!,Er dette den almægtige programmør? Det kan ikke passe!,Das ist der allmächtige Programmierer? Niemals!,,,¿Este es el todopoderoso Programador? ¡Ni hablar!,,Tämäkö muka kaikkivoipa Ohjelmoitsija? Ei todellakaan!,Ca c'est le surpuissant Programmeur? Vraiment?,Ez a hírhedt Progamozó? Nincs az az isten!,Sarebbe questo il potente Programmatore? Non è possibile!,,저게 위대한 프로그래머라고? 말도 안 돼!,Dit is de almachtige programmeur? Echt niet!,Er dette den allmektige programmereren? Aldri i livet!,To jest wszechmocny Programista? Nie ma mowy!,Esse é o Programador todo-poderoso? Tá de sacanagem comigo!,,Ăsta e marele Programator? Nici vorbă!,Вот это — всемогущий Программист? Быть не может!,,Bu yüce Programcı mı? Yok artık! -"I don't know what to believe anymore. The only thing that says ""keep"" to me is that huge monstrosity to the left. But I have no idea how to get in. ",TXT_SUB_LOG44,,,,"Už nevím, čemu věřit. Jediné, co mi říká „pevnost“, je tamta obří hrůza nalevo. Ale nemám tušení, jak se dostat dovnitř.","Jeg ved ikke længere, hvad jeg skal tro. Det eneste, der siger mig ""beholde"", er det store uhyre til venstre. Men jeg har ingen idé om, hvordan jeg kommer ind.","Ich weiß nicht mehr, was ich glauben soll. Das einzige, was ein „Tempel“ sein könnte, ist diese riesige Monströsität da drüben links. Aber ich wüßte nicht wie wir da rein kämen. ",,,"Ya no sé qué creer. Lo único que me dice ""torreón"" es esa monstruosidad enorme a la izquierda. Pero no tengo ni idea de como entrar.",,"En tiedä enää, mitä uskoa. Ainoa asia, joka näyttäytyy minulle ""linnakkeena"", on tuo valtava rumilus vasemmalla. Mutta minulla ei ole aavistustakaan, miten päästä sisään.","Je ne sais pas quoi penser maintenant. Le seul truc qui sonne comme ""donjon"" pour moi c'est l'énorme monstrosité à gauche, mais je ne sais pas comment y entrer.",Nem tudom mit kéne hinnem már. Az egyetlen vártorony szerűség a bal oldalt levő szörnyűség. Ötletem sincs hogy juthatnánk be.,"Non so più a cosa credere. L'unica cosa che mi dice ""fortezza"" è quell'enorme mostruosità alla sinistra, ma non so come entrarvi.",,이젠 누가 맞는 건지 생각이 전혀 안나. “성채”라고 말하는 곳은 분명히 저 왼쪽에 있는 커다란 건물일 거야. 그런데 그곳으로 어떻게 들어가야 하지?,"Ik weet niet meer wat ik moet geloven. Het enige dat tegen mij zegt ""houd"" is dat grote gedrocht aan de linkerkant. Maar ik heb geen idee hoe ik binnen kan komen.","Jeg vet ikke hva jeg skal tro lenger. Det eneste som sier ""hold"" til meg er den enorme monstrøsiteten til venstre. Men jeg aner ikke hvordan jeg skal komme meg inn.","Już nie wiem, w co wierzyć. Jedyne co mówi mi ""trzymaj"" to ta ogromna potworność po lewej stronie. Ale nie mam pojęcia, jak się tam dostać.",Eu não sei mais no que acreditar. A única coisa que parece uma fortaleza pra mim é aquela monstrosidade à esquerda. Mas não faço a menor idéia de como entrar.,,"Nu știu ce să mai cred. Singurul lucru care îmi spune ""curte"" e acea monstruozitate la stânga. Dar n-am idee cum să intrăm.","Не знаю, кому и верить. По-моему, «Цитаделью» можно назвать только ту уродливую громадину слева. Но как туда попасть, я понятия не имею.",,"Artık neye inanacağımı bilmiyorum. Bana ""kalsın"" diyen tek şey soldaki devasa canavar. Ama nasıl gireceğimi bilmiyorum." +ビンゴだわ!","악당 같은 요소가 모인 건물이네! 엄격한 건물 구조, 커다란 기... 완전 만장일치야.","Dit zijn alle kenmerken van een tempel van het kwaad. Strenge architectuur, grote spandoeken.... Ik zou zeggen bingo!","Dette er alle kjennetegnene på et ondskapens tempel. Streng arkitektur, stort banner... Jeg vil si bingo!","To wszystko ma znamiona świątyni zła. Surowa architektura, wielki baner... Powiedziałbym, że bingo!","Isso tem bem cara de templo malígno. Arquitetura sinístra, estandarte grande... Acho que acertamos na mosca!",,"Ăsta e însemnul unui templu malefic. Arhitectura, steagurile... Eu zic bingo!","Всё это очень похоже на зловещий храм. Строгая архитектура, огромное знамя... Да, это определённо он!",,"Det här har alla kännetecken på ett ondskans tempel. Stark arkitektur, stora banderoller... Jag skulle säga bingo!","Burası bir şeytan tapınağının tüm özelliklerini taşıyor. Sert mimari, büyük afiş. Bingo derdim!" +This is the almighty Programmer? No way!,TXT_SUB_LOG43,,,,Tohle je ten všemocný Programátor? To není možné!,Er dette den almægtige programmør? Det kan ikke passe!,Das ist der allmächtige Programmierer? Niemals!,,,¿Este es el todopoderoso Programador? ¡Ni hablar!,,Tämäkö muka kaikkivoipa Ohjelmoitsija? Ei todellakaan!,Ca c'est le surpuissant Programmeur? Vraiment?,Ez a hírhedt Progamozó? Nincs az az isten!,Sarebbe questo il potente Programmatore? Non è possibile!,,저게 위대한 프로그래머라고? 말도 안 돼!,Dit is de almachtige programmeur? Echt niet!,Er dette den allmektige programmereren? Aldri i livet!,To jest wszechmocny Programista? Nie ma mowy!,Esse é o Programador todo-poderoso? Tá de sacanagem comigo!,,Ăsta e marele Programator? Nici vorbă!,Вот это — всемогущий Программист? Быть не может!,,Är detta den allsmäktige programmeraren? Inte en chans!,Bu yüce Programcı mı? Yok artık! +"I don't know what to believe anymore. The only thing that says ""keep"" to me is that huge monstrosity to the left. But I have no idea how to get in. ",TXT_SUB_LOG44,,,,"Už nevím, čemu věřit. Jediné, co mi říká „pevnost“, je tamta obří hrůza nalevo. Ale nemám tušení, jak se dostat dovnitř.","Jeg ved ikke længere, hvad jeg skal tro. Det eneste, der siger mig ""beholde"", er det store uhyre til venstre. Men jeg har ingen idé om, hvordan jeg kommer ind.","Ich weiß nicht mehr, was ich glauben soll. Das einzige, was ein „Tempel“ sein könnte, ist diese riesige Monströsität da drüben links. Aber ich wüßte nicht wie wir da rein kämen. ",,,"Ya no sé qué creer. Lo único que me dice ""torreón"" es esa monstruosidad enorme a la izquierda. Pero no tengo ni idea de como entrar.",,"En tiedä enää, mitä uskoa. Ainoa asia, joka näyttäytyy minulle ""linnakkeena"", on tuo valtava rumilus vasemmalla. Mutta minulla ei ole aavistustakaan, miten päästä sisään.","Je ne sais pas quoi penser maintenant. Le seul truc qui sonne comme ""donjon"" pour moi c'est l'énorme monstrosité à gauche, mais je ne sais pas comment y entrer.",Nem tudom mit kéne hinnem már. Az egyetlen vártorony szerűség a bal oldalt levő szörnyűség. Ötletem sincs hogy juthatnánk be.,"Non so più a cosa credere. L'unica cosa che mi dice ""fortezza"" è quell'enorme mostruosità alla sinistra, ma non so come entrarvi.",,이젠 누가 맞는 건지 생각이 전혀 안나. “성채”라고 말하는 곳은 분명히 저 왼쪽에 있는 커다란 건물일 거야. 그런데 그곳으로 어떻게 들어가야 하지?,"Ik weet niet meer wat ik moet geloven. Het enige dat tegen mij zegt ""houd"" is dat grote gedrocht aan de linkerkant. Maar ik heb geen idee hoe ik binnen kan komen.","Jeg vet ikke hva jeg skal tro lenger. Det eneste som sier ""hold"" til meg er den enorme monstrøsiteten til venstre. Men jeg aner ikke hvordan jeg skal komme meg inn.","Już nie wiem, w co wierzyć. Jedyne co mówi mi ""trzymaj"" to ta ogromna potworność po lewej stronie. Ale nie mam pojęcia, jak się tam dostać.",Eu não sei mais no que acreditar. A única coisa que parece uma fortaleza pra mim é aquela monstrosidade à esquerda. Mas não faço a menor idéia de como entrar.,,"Nu știu ce să mai cred. Singurul lucru care îmi spune ""curte"" e acea monstruozitate la stânga. Dar n-am idee cum să intrăm.","Не знаю, кому и верить. По-моему, «Цитаделью» можно назвать только ту уродливую громадину слева. Но как туда попасть, я понятия не имею.",,"Jag vet inte vad jag ska tro längre. Det enda som säger ""behåll"" för mig är det enorma monstret till vänster. Men jag har ingen aning om hur jag ska ta mig in.","Artık neye inanacağımı bilmiyorum. Bana ""kalsın"" diyen tek şey soldaki devasa canavar. Ama nasıl gireceğimi bilmiyorum." "When the going gets weird, the weird get going. Watch yourself.",TXT_SUB_LOG45,"MAP09: Entrance. -(Probably a reference to Hunter S. Thompson’s quote, “When the going gets weird, the weird turn pro.”)",,,Divné klima lahodí podivínům. Dávej si na sebe pozor.,"Når det bliver mærkeligt, så bliver det mærkelige også mærkeligt. Pas på dig selv.",Die ganze Sache kommt mir spanisch vor. Pass auf dich auf.,,,La cosa se está poniendo fea. Ten cuidado.,Esto se va a poner feo. Ve con cuidado.,"Kun meininki muuttuu kummaksi, kummat alkavat meinata. Pidä varasi.","Quand les choses tournent au pire, le pire se tourne vers nous.. Fais attention à toi.",Egy fura világban furának kell lenned. Vigyázz magadra.,"Quando il gioco si fa strano, quelli strani si mettono in gioco. Fai attenzione.",怪しい状況では怪しい影が映る。気を付けて。,"상황이 이상해지면, 이상한 일이 계속 일어난다니까... 부디 조심해.","Als het gaat raar wordt, gaat het vreemde aan de slag. Kijk uit.","Når det blir merkelig, blir det merkelige merkelig. Vær forsiktig.","Kiedy robi się dziwnie, dziwacy zaczynają się ruszać. Uważaj na siebie.",A coisa tá ficando feia. Toma cuidado.,,"Cand lucrurile devin ciudate, ai grija.","Если видишь, что что-то не так, остановись и подумай. Будь осторожен.",,"İşler garipleştiğinde, garipler de gider. Kendine dikkat et." -"The Oracle resides in the borderlands, just outside of town. Cross the river, head towards the castle and go left through the archway.",TXT_SUB_LOG46,,,,"Věštec přebývá v pohraničí, hned za městem. Překroč řeku, zamiř k hradu a jdi vlevo pod obloukem.","Oraklet befinder sig i grænselandet, lige uden for byen. Kryds floden, gå mod slottet og gå til venstre gennem buegangen.","Das Orakel hält sich in den Grenzgebieten auf, direkt vor der Stadt. Überquere den Fluss, gehe in Richtung Burg und dann links durchs Tor.",,,"El Oráculo reside en las fronteras, justo fuera del pueblo. Cruza el río, dirígete al castillo y ve a la izquierda a través del arco.",,"Oraakkeli asuu rajamailla aivan kaupungin liepeillä. Ylitä joki, kulje kohti linnaa ja mene vasemmalle kaarikäytävän läpi.","L'Oracle se trouve dans les terrains vagues, à l'extérieur de la ville. Traverse la rivière, va vers le château et à gauche à travers l'arche.","Az Orákulum a peremvidéken tartózkodik, rögtön a városhatárokon túl. Elhagyva a folyót, menj a kastély irányába és fordulj balra a boltívnél.","L'Oracolo risiede nelle terre di confine, subito dopo la città. Attraversa il fiume, vai nella direzione del castello e poi a sinistra oltre l'arco.",,"오라클은 도시 외곽에 있는 접경지 근처에 있어. 강을 넘은 뒤, 성 쪽으로 향하고 아치 밑의 통로를 통해 왼쪽으로 이동해.","Het Orakel woont in de grensgebieden, net buiten de stad. Steek de rivier over, ga naar het kasteel en ga linksaf door de poort.","Orakelet ligger i grenselandet, like utenfor byen. Kryss elven, gå mot slottet og gå til venstre gjennom buegangen.","Wyrocznia mieszka na pograniczu, tuż za miastem. Przejdź przez rzekę, skieruj się w stronę zamku i przejdź w lewo przez łuki.","O Oráculo reside nas fronteiras do lado de fora da cidade. Atravesse o rio, vá em direção ao catelo e vá para a esquerda através do arco.",,"Oracolul locuiește în mărginime, chiar la ieșirea orașului. Treci râul, du-te spre castle, și treci prin arcadă.","Резиденция Оракула находится в пограничье, сразу за городской чертой. Пересеки реку, иди в сторону крепости и сверни налево, пройдя через арку.",,"Kahin, kasabanın hemen dışındaki sınır bölgesinde bulunuyor. Nehri geç, kaleye doğru git ve kemerden sola dön." -The Oracle is a supposedly sympathetic high priest who operates outside the Order.,TXT_SUB_LOG47,MAP02: Castle's entrance (MAP10).,,,"Věštec je údajně sympatizující velekněz, operující mimo samotný Řád.","Oraklet er en formodet sympatisk ypperstepræst, der opererer uden for ordenen.","Das Orakel ist ein angeblich verständnisvoller Hohepriester, der außerhalb des Ordens tätig ist.",,,El Oráculo es supuestamente un amable alto sacerdote que opera fuera de la Orden.,,"Oraakkeli on tiettävästi aatteellemme myötämielinen ylipappi, joka toimii Veljeskunnan vaikutuspiirin ulkopuolella.",L'Oracle est supposément un grand prêtre bienveillant qui opère hors du domaine de l'Ordre.,"Az Orákulum állítólag egy megértő főpap, aki nem tartozik a Rend rendjéhez.",L'Oracolo è un alto sacerdote apparentemente approciabile che opera al di fuori dell'Ordine.,オラクルはオーダーとは別の活動をしている同情的な大司祭よ。,"오라클은 인류에 동정을 가지고 있다고 하고, 오더의 바깥에서 활동하는 대사제야.",Het Orakel is een zogenaamd sympathieke hogepriester die buiten de Orde opereert.,Oraklet er en angivelig sympatisk yppersteprest som opererer utenfor ordenen.,"Wyrocznia jest rzekomo sympatycznym arcykapłanem, który działa poza Zakonem.",O Oráculo é supostamente um grande sacerdote benevolente que opera fora da Ordem.,,"Oracolul e un preot care simpatizează cu noi, și care se spune că operează din afara Ordinului.","Похоже, этот Оракул — сочувствующий Сопротивлению верховный жрец, который действует без ведома Ордена.",,"Kahin, Düzen'in dışında faaliyet gösteren sözde sempatik bir baş rahiptir." -"The Oracle's temple is in the Borderlands, on the outskirts of town.",TXT_SUB_LOG48,MAP10: After talking to Macil and moving a bit.,,,"Věštcův chrám je v pohraničí, na okraji města.","Oraklets tempel ligger i grænselandet, i udkanten af byen.","Der Tempel des Orakels ist in den Grenzgebieten, direkt vor der Stadt.",,,"El templo del Oráculo está en las Fronteras, a las afueras del pueblo.",,Oraakkelin temppeli sijaitsee rajaseudulla kaupungin laitamilla.,Le temple de l'Oracle se trouve dans les terrains vagues à l'extérieur de la ville.,Az Orákulum temploma a határvidéken található a külvárosban.,"Il tempio dell'Oracolo è nelle terre di confine, fuori città.",オラクルの寺院は町の郊外にある国境地帯の西側にあるわ。,오라클은 도시 외곽에 있는 접경지 근처에 있어.,"De tempel van het Orakel staat in de grensstreek van Nederland, aan de rand van de stad.","Orakelets tempel ligger i Grenselandene, i utkanten av byen.","Świątynia Wyroczni znajduje się na Kresach, na obrzeżach miasta.","O tempo do Oráculo está nas fronteiras, fora da cidade.",,"Templul Oracolului e în Mărginime, la ieșirea din oraș.","Храм Оракула находится в пограничье, на окраине города.",,"Kahin'in tapınağı Sınır Toprakları'nda, şehrin eteklerinde." -The Order has taken our beautiful planet and turned it into a dump.,TXT_SUB_LOG49,MAP11: Entrance.,,,Řád vzal naši krásnou planetu a proměnil ji ve skládku.,Ordenen har taget vores smukke planet og forvandlet den til en losseplads.,Der Orden hat unseren schönen Planeten in einen Müllplatz verwandelt.,,,La Orden ha tomado nuestro bello planeta y lo ha convertido en un vertedero.,,Veljeskunta on riistänyt planeettamme ja tehnyt siitä kaatopaikan.,L'Ordre a pris notre belle planète et la transformée en dépotoir.,"A Rend kizsigerelte ezt a gyönyörű bolygót, és egy lepratelepet csinált belőle.",L'Ordine ha preso il nostro bellissimo pianeta e l'ha trasformato in una discarica.,オーダーは我々の立つこの惑星を奪い、それをゴミへと変えた。,오더가 이 이쁘고 푸른 행성을 완전 쓰레기장으로 만들어버렸어...,De Orde heeft onze mooie planeet in beslag genomen en er een vuilnisbelt van gemaakt.,Ordenen har tatt vår vakre planet og gjort den til en søppelplass.,Zakon zabrał naszą piękną planetę i zamienił ją w wysypisko śmieci.,A Ordem transformou este lindo planeta em um depósito de lixo.,,Ordinul ne-a luat planeta minunată și a transformat-o într-o groapă de gunoi.,Орден превратил нашу прекрасную планету в помойку.,,Tarikat güzel gezegenimizi aldı ve onu bir çöplüğe çevirdi. +(Probably a reference to Hunter S. Thompson’s quote, “When the going gets weird, the weird turn pro.”)",,,Divné klima lahodí podivínům. Dávej si na sebe pozor.,"Når det bliver mærkeligt, så bliver det mærkelige også mærkeligt. Pas på dig selv.",Die ganze Sache kommt mir spanisch vor. Pass auf dich auf.,,,La cosa se está poniendo fea. Ten cuidado.,Esto se va a poner feo. Ve con cuidado.,"Kun meininki muuttuu kummaksi, kummat alkavat meinata. Pidä varasi.","Quand les choses tournent au pire, le pire se tourne vers nous.. Fais attention à toi.",Egy fura világban furának kell lenned. Vigyázz magadra.,"Quando il gioco si fa strano, quelli strani si mettono in gioco. Fai attenzione.",怪しい状況では怪しい影が映る。気を付けて。,"상황이 이상해지면, 이상한 일이 계속 일어난다니까... 부디 조심해.","Als het gaat raar wordt, gaat het vreemde aan de slag. Kijk uit.","Når det blir merkelig, blir det merkelige merkelig. Vær forsiktig.","Kiedy robi się dziwnie, dziwacy zaczynają się ruszać. Uważaj na siebie.",A coisa tá ficando feia. Toma cuidado.,,"Cand lucrurile devin ciudate, ai grija.","Если видишь, что что-то не так, остановись и подумай. Будь осторожен.",,"När det blir konstigt, blir det konstiga som går. Se upp för dig själv.","İşler garipleştiğinde, garipler de gider. Kendine dikkat et." +"The Oracle resides in the borderlands, just outside of town. Cross the river, head towards the castle and go left through the archway.",TXT_SUB_LOG46,,,,"Věštec přebývá v pohraničí, hned za městem. Překroč řeku, zamiř k hradu a jdi vlevo pod obloukem.","Oraklet befinder sig i grænselandet, lige uden for byen. Kryds floden, gå mod slottet og gå til venstre gennem buegangen.","Das Orakel hält sich in den Grenzgebieten auf, direkt vor der Stadt. Überquere den Fluss, gehe in Richtung Burg und dann links durchs Tor.",,,"El Oráculo reside en las fronteras, justo fuera del pueblo. Cruza el río, dirígete al castillo y ve a la izquierda a través del arco.",,"Oraakkeli asuu rajamailla aivan kaupungin liepeillä. Ylitä joki, kulje kohti linnaa ja mene vasemmalle kaarikäytävän läpi.","L'Oracle se trouve dans les terrains vagues, à l'extérieur de la ville. Traverse la rivière, va vers le château et à gauche à travers l'arche.","Az Orákulum a peremvidéken tartózkodik, rögtön a városhatárokon túl. Elhagyva a folyót, menj a kastély irányába és fordulj balra a boltívnél.","L'Oracolo risiede nelle terre di confine, subito dopo la città. Attraversa il fiume, vai nella direzione del castello e poi a sinistra oltre l'arco.",,"오라클은 도시 외곽에 있는 접경지 근처에 있어. 강을 넘은 뒤, 성 쪽으로 향하고 아치 밑의 통로를 통해 왼쪽으로 이동해.","Het Orakel woont in de grensgebieden, net buiten de stad. Steek de rivier over, ga naar het kasteel en ga linksaf door de poort.","Orakelet ligger i grenselandet, like utenfor byen. Kryss elven, gå mot slottet og gå til venstre gjennom buegangen.","Wyrocznia mieszka na pograniczu, tuż za miastem. Przejdź przez rzekę, skieruj się w stronę zamku i przejdź w lewo przez łuki.","O Oráculo reside nas fronteiras do lado de fora da cidade. Atravesse o rio, vá em direção ao catelo e vá para a esquerda através do arco.",,"Oracolul locuiește în mărginime, chiar la ieșirea orașului. Treci râul, du-te spre castle, și treci prin arcadă.","Резиденция Оракула находится в пограничье, сразу за городской чертой. Пересеки реку, иди в сторону крепости и сверни налево, пройдя через арку.",,"Oraklet bor i gränslandet, strax utanför staden. Korsa floden, gå mot slottet och gå till vänster genom valvet.","Kahin, kasabanın hemen dışındaki sınır bölgesinde bulunuyor. Nehri geç, kaleye doğru git ve kemerden sola dön." +The Oracle is a supposedly sympathetic high priest who operates outside the Order.,TXT_SUB_LOG47,MAP02: Castle's entrance (MAP10).,,,"Věštec je údajně sympatizující velekněz, operující mimo samotný Řád.","Oraklet er en formodet sympatisk ypperstepræst, der opererer uden for ordenen.","Das Orakel ist ein angeblich verständnisvoller Hohepriester, der außerhalb des Ordens tätig ist.",,,El Oráculo es supuestamente un amable alto sacerdote que opera fuera de la Orden.,,"Oraakkeli on tiettävästi aatteellemme myötämielinen ylipappi, joka toimii Veljeskunnan vaikutuspiirin ulkopuolella.",L'Oracle est supposément un grand prêtre bienveillant qui opère hors du domaine de l'Ordre.,"Az Orákulum állítólag egy megértő főpap, aki nem tartozik a Rend rendjéhez.",L'Oracolo è un alto sacerdote apparentemente approciabile che opera al di fuori dell'Ordine.,オラクルはオーダーとは別の活動をしている同情的な大司祭よ。,"오라클은 인류에 동정을 가지고 있다고 하고, 오더의 바깥에서 활동하는 대사제야.",Het Orakel is een zogenaamd sympathieke hogepriester die buiten de Orde opereert.,Oraklet er en angivelig sympatisk yppersteprest som opererer utenfor ordenen.,"Wyrocznia jest rzekomo sympatycznym arcykapłanem, który działa poza Zakonem.",O Oráculo é supostamente um grande sacerdote benevolente que opera fora da Ordem.,,"Oracolul e un preot care simpatizează cu noi, și care se spune că operează din afara Ordinului.","Похоже, этот Оракул — сочувствующий Сопротивлению верховный жрец, который действует без ведома Ордена.",,Oraklet är en förmodat sympatisk överstepräst som verkar utanför orden.,"Kahin, Düzen'in dışında faaliyet gösteren sözde sempatik bir baş rahiptir." +"The Oracle's temple is in the Borderlands, on the outskirts of town.",TXT_SUB_LOG48,MAP10: After talking to Macil and moving a bit.,,,"Věštcův chrám je v pohraničí, na okraji města.","Oraklets tempel ligger i grænselandet, i udkanten af byen.","Der Tempel des Orakels ist in den Grenzgebieten, direkt vor der Stadt.",,,"El templo del Oráculo está en las Fronteras, a las afueras del pueblo.",,Oraakkelin temppeli sijaitsee rajaseudulla kaupungin laitamilla.,Le temple de l'Oracle se trouve dans les terrains vagues à l'extérieur de la ville.,Az Orákulum temploma a határvidéken található a külvárosban.,"Il tempio dell'Oracolo è nelle terre di confine, fuori città.",オラクルの寺院は町の郊外にある国境地帯の西側にあるわ。,오라클은 도시 외곽에 있는 접경지 근처에 있어.,"De tempel van het Orakel staat in de grensstreek van Nederland, aan de rand van de stad.","Orakelets tempel ligger i Grenselandene, i utkanten av byen.","Świątynia Wyroczni znajduje się na Kresach, na obrzeżach miasta.","O tempo do Oráculo está nas fronteiras, fora da cidade.",,"Templul Oracolului e în Mărginime, la ieșirea din oraș.","Храм Оракула находится в пограничье, на окраине города.",,"Oraklets tempel ligger i gränslandet, i utkanten av staden.","Kahin'in tapınağı Sınır Toprakları'nda, şehrin eteklerinde." +The Order has taken our beautiful planet and turned it into a dump.,TXT_SUB_LOG49,MAP11: Entrance.,,,Řád vzal naši krásnou planetu a proměnil ji ve skládku.,Ordenen har taget vores smukke planet og forvandlet den til en losseplads.,Der Orden hat unseren schönen Planeten in einen Müllplatz verwandelt.,,,La Orden ha tomado nuestro bello planeta y lo ha convertido en un vertedero.,,Veljeskunta on riistänyt planeettamme ja tehnyt siitä kaatopaikan.,L'Ordre a pris notre belle planète et la transformée en dépotoir.,"A Rend kizsigerelte ezt a gyönyörű bolygót, és egy lepratelepet csinált belőle.",L'Ordine ha preso il nostro bellissimo pianeta e l'ha trasformato in una discarica.,オーダーは我々の立つこの惑星を奪い、それをゴミへと変えた。,오더가 이 이쁘고 푸른 행성을 완전 쓰레기장으로 만들어버렸어...,De Orde heeft onze mooie planeet in beslag genomen en er een vuilnisbelt van gemaakt.,Ordenen har tatt vår vakre planet og gjort den til en søppelplass.,Zakon zabrał naszą piękną planetę i zamienił ją w wysypisko śmieci.,A Ordem transformou este lindo planeta em um depósito de lixo.,,Ordinul ne-a luat planeta minunată și a transformat-o într-o groapă de gunoi.,Орден превратил нашу прекрасную планету в помойку.,,Orden har tagit vår vackra planet och förvandlat den till en soptipp.,Tarikat güzel gezegenimizi aldı ve onu bir çöplüğe çevirdi. "Here it is. I'm recording everything, it's not that I don't have faith that you'll survive, it's just that we can't let the Order control the Sigil.",TXT_SUB_LOG50,MAP11: Entrance to cave.,,,"Tady to je. Všechno nahrávám, ne že bych neměla důvěru v tvé přežití, ale prostě nemůžeme dovolit Řádu ovládat Pečeť.","Her er den. Jeg optager alt, det er ikke fordi jeg ikke tror på, at I vil overleve, men vi kan ikke lade Ordenen kontrollere Sigil.","Hier ist es. Ich zeichne alles auf, nicht dass ich kein Vertrauen in dich habe, aber wir können nicht erlauben, dass der Orden das Sigil kontrolliert.",,,"Aquí está. Lo estoy grabando todo, no es que tenga fe en que sobrevivas, es solo que no puedo dejar que la Orden controle el Emblema.",,"Tässä se on. Tallennan kaiken. Tässä ei ole kyse siitä, etteikö minulla olisi täysi luotto, että selviäisit. Emme vain voi antaa Veljeskunnan hallita Sinettiä.","Voilà, j'enregistre tout. C'est pas qu'on a pas confiance en toi, c'est juste que on ne peut pas laisser l'Ordre contrôler le Sigil.","Itt is van. Minden felveszek, nem azért mert nem bíznék benned, csak ne kerüljön a Rend kezébe a pecsét.",Ecco qua. Sto registrando tutto. Non è che non penso che sopravviverai. È solo che non possiamo lasciare che l'Ordine controlli il Sigillo.,"ここよ。私は全て記録している、貴方が生き残れる可能性が無いわけではなく、 -オーダー如きにシジルを制御できるわけがないという事だ。","여기야. 난 지금 모든 걸 녹음하고 있어. 네가 살아남을 거라는 믿음을 버린게 아니라, 오더가 시질을 손에 잡게 내버려 둘 수가 없어서 말이야.","Hier is het. Ik ben alles aan het opnemen, het is niet dat ik geen vertrouwen heb dat je het zult overleven, maar het is gewoon dat we de Orde de Sigil niet kunnen laten controleren door de Orde.","Her er det. Jeg tar opp alt, det er ikke det at jeg ikke har tro på at du vil overleve, men vi kan ikke la Ordenen kontrollere sigillet.","Oto ona. Nagrywam wszystko, to nie tak, że nie mam wiary, że przeżyjesz, po prostu nie możemy pozwolić, by Zakon kontrolował Sigil.","Certo, estou gravando tudo. Não é que eu não tenha fé de que você vá sobreviver, mas não podemos deixar a Ordem controlar o Sigilo.",,"Aici e. Înregistrez totul. Nu e vorba c nu vei supraviețui, dar nu putem permite Ordinului să controleze Sigiliul.","Так. Я всё записываю на плёнку. Это не потому, что я не верю, что ты уцелеешь. Просто мы не можем позволить Ордену заполучить Печать.",,"İşte burası. Her şeyi kaydediyorum, hayatta kalacağınıza inanmadığımdan değil, sadece Düzen'in Sigil'i kontrol etmesine izin veremeyiz." -"You are brave, my comrade. I'm proud to be along for the ride.",TXT_SUB_LOG51,MAP12: Bridge to sanctum's normal entrance.,,,"Jsi statečný, můj příteli. Jsem pyšná, že u tohohle můžu být.","Du er modig, min kammerat. Jeg er stolt af at være med på turen.","Du bist tapfer, mein Kamerad. Ich bin stolz darauf, mit von der Partie zu sein.",,,"Eres valiente, mi camarada. Estoy orgullosa de acompañarte.",,"Olet urhea, toverini. Olen ylpeä, että saan olla matkassa mukana.","Tu est courageux, mon camarade, je suis fière de te suivre.","Felettébb bátor vagy bajtárs. Büszke vagyok, hogy veled harcolhatok.","Sei coraggioso, compagno. Sono orgogliosa di essere insieme a te in questo viaggio.",貴方は勇敢で、私の同志。貴方に就けた事を私は誇りに思ってるわ。,"넌 정말 용맹해, 동지. 너랑 같이 일할 수 있는 게 정말 자랑스러워.","Je bent dapper, mijn kameraad. Ik ben er trots op dat ik meega voor de rit.","Du er modig, min kamerat. Jeg er stolt over å være med på turen.","Jesteś odważny, mój towarzyszu. Jestem dumny, że mogę być przy tobie.","Você é corajoso, meu companheiro. Tenho orgulho de estar junto com você.",,"Ești viteaz, soldatul meu. Sunt mândru să lupt alături de tne.","Я хотела сказать тебе, что ты очень храбрый. Я так счастлива, что мне с тобой по пути.",,"Cesursun, yoldaşım. Seninle birlikte olmaktan gurur duyuyorum." +オーダー如きにシジルを制御できるわけがないという事だ。","여기야. 난 지금 모든 걸 녹음하고 있어. 네가 살아남을 거라는 믿음을 버린게 아니라, 오더가 시질을 손에 잡게 내버려 둘 수가 없어서 말이야.","Hier is het. Ik ben alles aan het opnemen, het is niet dat ik geen vertrouwen heb dat je het zult overleven, maar het is gewoon dat we de Orde de Sigil niet kunnen laten controleren door de Orde.","Her er det. Jeg tar opp alt, det er ikke det at jeg ikke har tro på at du vil overleve, men vi kan ikke la Ordenen kontrollere sigillet.","Oto ona. Nagrywam wszystko, to nie tak, że nie mam wiary, że przeżyjesz, po prostu nie możemy pozwolić, by Zakon kontrolował Sigil.","Certo, estou gravando tudo. Não é que eu não tenha fé de que você vá sobreviver, mas não podemos deixar a Ordem controlar o Sigilo.",,"Aici e. Înregistrez totul. Nu e vorba c nu vei supraviețui, dar nu putem permite Ordinului să controleze Sigiliul.","Так. Я всё записываю на плёнку. Это не потому, что я не верю, что ты уцелеешь. Просто мы не можем позволить Ордену заполучить Печать.",,"Här är den. Jag spelar in allting, det är inte så att jag inte tror på att du kommer att överleva, det är bara det att vi inte kan låta Orden kontrollera Sigil.","İşte burası. Her şeyi kaydediyorum, hayatta kalacağınıza inanmadığımdan değil, sadece Düzen'in Sigil'i kontrol etmesine izin veremeyiz." +"You are brave, my comrade. I'm proud to be along for the ride.",TXT_SUB_LOG51,MAP12: Bridge to sanctum's normal entrance.,,,"Jsi statečný, můj příteli. Jsem pyšná, že u tohohle můžu být.","Du er modig, min kammerat. Jeg er stolt af at være med på turen.","Du bist tapfer, mein Kamerad. Ich bin stolz darauf, mit von der Partie zu sein.",,,"Eres valiente, mi camarada. Estoy orgullosa de acompañarte.",,"Olet urhea, toverini. Olen ylpeä, että saan olla matkassa mukana.","Tu est courageux, mon camarade, je suis fière de te suivre.","Felettébb bátor vagy bajtárs. Büszke vagyok, hogy veled harcolhatok.","Sei coraggioso, compagno. Sono orgogliosa di essere insieme a te in questo viaggio.",貴方は勇敢で、私の同志。貴方に就けた事を私は誇りに思ってるわ。,"넌 정말 용맹해, 동지. 너랑 같이 일할 수 있는 게 정말 자랑스러워.","Je bent dapper, mijn kameraad. Ik ben er trots op dat ik meega voor de rit.","Du er modig, min kamerat. Jeg er stolt over å være med på turen.","Jesteś odważny, mój towarzyszu. Jestem dumny, że mogę być przy tobie.","Você é corajoso, meu companheiro. Tenho orgulho de estar junto com você.",,"Ești viteaz, soldatul meu. Sunt mândru să lupt alături de tne.","Я хотела сказать тебе, что ты очень храбрый. Я так счастлива, что мне с тобой по пути.",,"Du är modig, min kamrat. Jag är stolt över att vara med på resan.","Cesursun, yoldaşım. Seninle birlikte olmaktan gurur duyuyorum." Could you pause for a second? I'm getting a little sick.,TXT_SUB_LOG52,"(Strife: Veteran Edition) -Random comment when the player dies with Classic Mode turned off",,,Mohl by ses na chvíli zastavit? Bude mi zle.,Kan du holde en pause et øjeblik? Jeg er ved at få det lidt dårligt.,Kannst du mal kurz warten? Mir wird etwas übel.,,,¿Puedes parar un segundo? Que me estoy mareando.,,Voisitko pysähtyä hetkeksi? Alan voida hieman pahoin.,Tu peux t'arrêter pour un moment? J'ai l'impression d'avoir la nausée.,Meg tudnál állni egy pillanatra? Elég rosszul vagyok.,Puoi fermarti per un secondo? Mi sento un pò nauseata.,ちょっと待ってもらえる?少しばかりうんざりしてるわ。,잠깐만 멈춰줄래? 속이 울렁거려...,Kun je even pauzeren? Ik word een beetje ziek.,Kan du ta en pause? Jeg begynner å bli litt kvalm.,Możesz się zatrzymać na chwilę? Robi mi się trochę niedobrze.,Pode parar por um minuto? Estou ficando com enjôo.,,Poți să te opreși un moment? Mi se face rău.,Мы можем остановиться на секунду? Что-то мне дурно.,,Bir saniye durabilir misin? Biraz midem bulanıyor. -Why do we have to spend so much time underground? I've seen underground.,TXT_SUB_LOG53,MAP12: Downstairs.,,,Proč musíme tolik času strávit v podzemí? Podzemí jsem viděla.,Hvorfor skal vi tilbringe så meget tid under jorden? Jeg har set under jorden.,Warum müssen wir so viel Zeit im Untergrund verbringen.? Ich kenne den Untergrund.,,,¿Por que tenemos que pasar tanto tiempo bajo tierra? Ya lo tengo muy visto.,,Miksi olemme niin paljon maan alla? Nähty juttu.,Pourquoi on passe tout notre temps sous terre? J'ai déja tout vu sous terre.,Miért kell ilyen sok időt föld alatt töltenünk? Már láttam elég föld alatti részt.,Ma perché passiamo così tanto tempo sotto terra? Già conosco molto bene posti come questo.,何故私達は地下に長居せねばならないの?地下はもうわかったから。,왜 지하에서 시간을 낭비해야 되는 거지? 난 이미 지하에 있다고.,Waarom moeten we zoveel tijd onder de grond doorbrengen? Ik heb ondergronds gezien.,Hvorfor må vi tilbringe så mye tid under jorden? Jeg har sett undergrunnen.,Dlaczego musimy spędzać tyle czasu pod ziemią? Widziałem już podziemia.,Por que a gente tem que ficar tanto tempo no subterrâneo? Já vi bastante do subterrâneo.,,De ce trebuie să petrecem atâta timp sub pământ? Am văzut subteranul.,Почему нам приходится проводить кучу времени под землёй? Я на десять лет вперед насмотрелась на подземелья.,,Neden yeraltında bu kadar çok vakit geçirmek zorundayız? Yeraltını gördüm. -Are we really supposed to trust a guy whose inner sanctum is green?,TXT_SUB_LOG54,MAP12: Sanctum's normal entrance.,,,"Fakt máme věřit chlápkovi, jehož svatyně je zelená?","Skal vi virkelig stole på en fyr, hvis indre helligdom er grøn?","Sollen wir wirklich einem Typen vertrauen, dessen Räume grün sind?",,"Ĉu ni vere devas fidi al iu, kies sekreta templo estas verda?",¿En serio hay que fiarse de un tipo cuyo templo secreto es verde?,¿En serio hay que confiar en un tipo cuyo templo secreto es verde?,"Tuleeko meidän todella luottaa kaveriin, jolla on vihreä pyhäkkö?",On est vraiment obligé de faire confiance à un type qui a un sanctuaire peint en vert?,"Egy olyan ürgében kéne megbíznunk, akinek zöld színű a szentélye?",Davvero dovremmo fidarci di qualcuno che ha un santuario verde?,聖域内部と全身が緑色の者を信用するべきなの?,성소가 더럽게 초록색인데 이 녀석을 정말 믿어야 해?,Moeten we echt vertrouwen hebben in een man wiens innerlijke heiligdom groen is?,Skal vi virkelig stole på en fyr hvis indre er grønt?,"Czy naprawdę mamy ufać facetowi, którego wewnętrzne sanktuarium jest zielone?",Será que a gente deve mesmo confiar num cara cujo grande santuário é verde?,,Chiar ar trebui să avem încredere în cineva în cineva al cărui sanctuar e verde?,"Мы точно можем доверять парню, чьи внутренние покои зелёного цвета?",,Kutsal alanı yeşil olan bir adama gerçekten güvenmemiz mi gerekiyor? -Crimson and Obsidian? Why can't he say red and black.,TXT_SUB_LOG55,MAP12: After talking to the Oracle.,,,Karmíno-obsidiánová? Proč nemůže říct červeno-černá?,Purpur og Obsidian? Hvorfor kan han ikke sige rød og sort.,Purpur und Obsidian? Warum kann er nicht Rot und Schwarz sagen?,,Ĉu «karmezina kaj obsidiankolora»? Kial li ne diras «ruĝa kaj nigra»?,"¿«Carmesí y obsidiana»?, ¿tanto le cuesta decir «roja y negra»?",,Purppuranpunainen ja laavalasinen? Miksei hän voi sanoa punainen ja musta?,Cramoisi et obsidienne? Il peut pas dire juste rouge et noir?,"Karmazsin és obszidián? Miért nem tudja azt mondani, hogy piros és fekete.",Cremisina e ossidiana? Non bastava dire rossa e nera?,深紅と黒曜石?何故彼は赤と黒と言わないの。,진홍빛 흑요석? 빨간 검은색이라고 말하면 어디 덧나나?,Crimson en Obsidian? Waarom kan hij niet rood en zwart zeggen.,Purpur og Obsidian? Hvorfor kan han ikke si rødt og svart?,Karmazyn i Obsydian? Dlaczego nie może powiedzieć: czerwony i czarny.,Carmesim e Obsidiana? Por que ele não diz logo vermelho e preto?,,Străveziu și Obsidian? De ce nu poate spune roșu și negru.,Багрово-обсидиановая? Почему бы не сказать просто — «красно-чёрная»!,,Crimson ve Obsidian? Neden kırmızı ve siyah diyemiyor? +Random comment when the player dies with Classic Mode turned off",,,Mohl by ses na chvíli zastavit? Bude mi zle.,Kan du holde en pause et øjeblik? Jeg er ved at få det lidt dårligt.,Kannst du mal kurz warten? Mir wird etwas übel.,,,¿Puedes parar un segundo? Que me estoy mareando.,,Voisitko pysähtyä hetkeksi? Alan voida hieman pahoin.,Tu peux t'arrêter pour un moment? J'ai l'impression d'avoir la nausée.,Meg tudnál állni egy pillanatra? Elég rosszul vagyok.,Puoi fermarti per un secondo? Mi sento un pò nauseata.,ちょっと待ってもらえる?少しばかりうんざりしてるわ。,잠깐만 멈춰줄래? 속이 울렁거려...,Kun je even pauzeren? Ik word een beetje ziek.,Kan du ta en pause? Jeg begynner å bli litt kvalm.,Możesz się zatrzymać na chwilę? Robi mi się trochę niedobrze.,Pode parar por um minuto? Estou ficando com enjôo.,,Poți să te opreși un moment? Mi se face rău.,Мы можем остановиться на секунду? Что-то мне дурно.,,Kan du stanna upp en stund? Jag börjar bli lite sjuk.,Bir saniye durabilir misin? Biraz midem bulanıyor. +Why do we have to spend so much time underground? I've seen underground.,TXT_SUB_LOG53,MAP12: Downstairs.,,,Proč musíme tolik času strávit v podzemí? Podzemí jsem viděla.,Hvorfor skal vi tilbringe så meget tid under jorden? Jeg har set under jorden.,Warum müssen wir so viel Zeit im Untergrund verbringen.? Ich kenne den Untergrund.,,,¿Por que tenemos que pasar tanto tiempo bajo tierra? Ya lo tengo muy visto.,,Miksi olemme niin paljon maan alla? Nähty juttu.,Pourquoi on passe tout notre temps sous terre? J'ai déja tout vu sous terre.,Miért kell ilyen sok időt föld alatt töltenünk? Már láttam elég föld alatti részt.,Ma perché passiamo così tanto tempo sotto terra? Già conosco molto bene posti come questo.,何故私達は地下に長居せねばならないの?地下はもうわかったから。,왜 지하에서 시간을 낭비해야 되는 거지? 난 이미 지하에 있다고.,Waarom moeten we zoveel tijd onder de grond doorbrengen? Ik heb ondergronds gezien.,Hvorfor må vi tilbringe så mye tid under jorden? Jeg har sett undergrunnen.,Dlaczego musimy spędzać tyle czasu pod ziemią? Widziałem już podziemia.,Por que a gente tem que ficar tanto tempo no subterrâneo? Já vi bastante do subterrâneo.,,De ce trebuie să petrecem atâta timp sub pământ? Am văzut subteranul.,Почему нам приходится проводить кучу времени под землёй? Я на десять лет вперед насмотрелась на подземелья.,,Varför måste vi tillbringa så mycket tid under jord? Jag har sett underjorden.,Neden yeraltında bu kadar çok vakit geçirmek zorundayız? Yeraltını gördüm. +Are we really supposed to trust a guy whose inner sanctum is green?,TXT_SUB_LOG54,MAP12: Sanctum's normal entrance.,,,"Fakt máme věřit chlápkovi, jehož svatyně je zelená?","Skal vi virkelig stole på en fyr, hvis indre helligdom er grøn?","Sollen wir wirklich einem Typen vertrauen, dessen Räume grün sind?",,"Ĉu ni vere devas fidi al iu, kies sekreta templo estas verda?",¿En serio hay que fiarse de un tipo cuyo templo secreto es verde?,¿En serio hay que confiar en un tipo cuyo templo secreto es verde?,"Tuleeko meidän todella luottaa kaveriin, jolla on vihreä pyhäkkö?",On est vraiment obligé de faire confiance à un type qui a un sanctuaire peint en vert?,"Egy olyan ürgében kéne megbíznunk, akinek zöld színű a szentélye?",Davvero dovremmo fidarci di qualcuno che ha un santuario verde?,聖域内部と全身が緑色の者を信用するべきなの?,성소가 더럽게 초록색인데 이 녀석을 정말 믿어야 해?,Moeten we echt vertrouwen hebben in een man wiens innerlijke heiligdom groen is?,Skal vi virkelig stole på en fyr hvis indre er grønt?,"Czy naprawdę mamy ufać facetowi, którego wewnętrzne sanktuarium jest zielone?",Será que a gente deve mesmo confiar num cara cujo grande santuário é verde?,,Chiar ar trebui să avem încredere în cineva în cineva al cărui sanctuar e verde?,"Мы точно можем доверять парню, чьи внутренние покои зелёного цвета?",,Är det verkligen meningen att vi ska lita på en kille vars inre helgedom är grön?,Kutsal alanı yeşil olan bir adama gerçekten güvenmemiz mi gerekiyor? +Crimson and Obsidian? Why can't he say red and black.,TXT_SUB_LOG55,MAP12: After talking to the Oracle.,,,Karmíno-obsidiánová? Proč nemůže říct červeno-černá?,Purpur og Obsidian? Hvorfor kan han ikke sige rød og sort.,Purpur und Obsidian? Warum kann er nicht Rot und Schwarz sagen?,,Ĉu «karmezina kaj obsidiankolora»? Kial li ne diras «ruĝa kaj nigra»?,"¿«Carmesí y obsidiana»?, ¿tanto le cuesta decir «roja y negra»?",,Purppuranpunainen ja laavalasinen? Miksei hän voi sanoa punainen ja musta?,Cramoisi et obsidienne? Il peut pas dire juste rouge et noir?,"Karmazsin és obszidián? Miért nem tudja azt mondani, hogy piros és fekete.",Cremisina e ossidiana? Non bastava dire rossa e nera?,深紅と黒曜石?何故彼は赤と黒と言わないの。,진홍빛 흑요석? 빨간 검은색이라고 말하면 어디 덧나나?,Crimson en Obsidian? Waarom kan hij niet rood en zwart zeggen.,Purpur og Obsidian? Hvorfor kan han ikke si rødt og svart?,Karmazyn i Obsydian? Dlaczego nie może powiedzieć: czerwony i czarny.,Carmesim e Obsidiana? Por que ele não diz logo vermelho e preto?,,Străveziu și Obsidian? De ce nu poate spune roșu și negru.,Багрово-обсидиановая? Почему бы не сказать просто — «красно-чёрная»!,,Karminrött och Obsidian? Varför kan han inte säga röd och svart.,Crimson ve Obsidian? Neden kırmızı ve siyah diyemiyor? "The Bishop is the Order's military leader. He plots their tactics, runs their spies and is charged with controlling us. We off him and we score twice.",TXT_SUB_LOG56,MAP11: Afther talking to the Oracle and leaving the cave.,,,"Biskup velí armádě Řádu. Plánuje jejich taktiky, velí jejich špiónům a má za úkol ovládat nás. Odděláme ho a zabodujeme dvakrát.","Biskoppen er ordenens militære leder. Han udtænker deres taktik, leder deres spioner og har til opgave at kontrollere os. Hvis vi dræber ham, scorer vi to gange.","Der Bischof ist der militärische Anführer des Ordens. Er plant die Strategien, beaufsichtigt die Spione und ist beauftragt, uns zu kontrollieren. Wenn wir ihn ausschalten, gewinnen wir doppelt.",,,"El Obispo es el líder militar de La Orden: planea sus tácticas, maneja a sus espías y está al cargo de controlarnos. Nos lo cargamos y ganamos dos puntos.","El Obispo es el líder militar de La Orden: planea sus tácticas, maneja a sus espías y está al cargo de controlarnos. Lo matamos y premios dobles.","Piispa on Veljeskunnan sotapäällikkö. Hän laatii heidän taktiikkansa, johtaa heidän vakoojiaan ja vastaa meidän hallinnasta. Teemme hänestä lopun ja pokkaamme kaksi pistettä. ","L'évèque est le leader militaire de l'Ordre. C'est lui qui s'occupe de leur tactiques, gère leurs espions, et est en charge de nous contrôler. On l'élimine, on marque deux points.","A Püspök a Rend katonai vezetője. Ő agyalja ki a taktikákat, irányítja a kémeket, és rá van bízva a mi irányításunk is. A kiiktatásával két legyet ütünk egy csapásra.",Il Vescovo è il capo militare dell'Ordine. È lui a pianificare le loro tattiche e gestire le loro spie al fine di controllarci tutti. Farlo fuori sarebbe un enorme vantaggio.,"ビショップはオーダーの軍事指揮官よ。 奴等の戦術を企てスパイを駆り立て私達の支配が管轄だ。 -奴を仕留めれば得点は倍額でしょう。","비숍은 그들의 잔혹한 군사 지도자이지. 그는 전술을 획책하고, 첩자를 부리고, 우리들을 통제하고 있어. 그를 죽이면 두 배로 이득이 갈 거야.","De bisschop is de militaire leider van de Orde. Hij zet hun tactiek uit, leidt hun spionnen en heeft de opdracht ons te controleren. We gaan van hem af en we scoren twee keer.","Biskopen er ordenens militære leder. Han planlegger taktikken deres, styrer spionene deres og har ansvaret for å kontrollere oss. Dreper vi ham, scorer vi to ganger.","Biskup jest przywódcą wojskowym Zakonu. Tworzy ich taktykę, prowadzi ich szpiegów i ma za zadanie kontrolować nas. Zdejmiemy go i zdobędziemy dwa punkty.","O Bispo é o líder militar da Ordem. Ele planeja suas táticas, comanda seus espiões e é encarregado de nos controlar. Eliminamos ele e é dois coelhos numa tacada só.",,"Episcopul e liderul militar al Ordinului. Le planifică schemele, tacticile, spionează, și ne controlează. Îl eliminăm și înscriem de două ori.","Епископ — военный лидер Ордена. Он обучает их тактике, управляет их шпионами и жаждет контроля над нами. От его убийства мы выигрываем вдвойне.",,"Piskopos, Tarikat'ın askeri lideridir. Taktiklerini planlar, casuslarını yönetir ve bizi kontrol etmekle görevlidir. Ondan kurtulursak iki kere kazanırız." -The Bishop is going to be heavily guarded so why don't we swipe a uniform and blend in?,TXT_SUB_LOG57,MAP11: Officer's uniform room.,,,"Biskup bude silně strážen, co takhle sebrat uniformu a splynout s davem?","Biskoppen vil være stærkt bevogtet, så hvorfor tager vi ikke en uniform og falder ind i mængden?","Der Bischof wird schwer bewacht sein, so warum stibitzen wir nicht eine Uniform um uns besser anzupassen?",,,El Obispo estará bien guardado asi que ¿por que no pillamos un uniforme y nos mezclamos?,,"Piispa on taatusti tarkoin vartioitu, joten miksemme kähveltäisi univormua ja sulautuisi joukkoon?","L'évèque sera lourdement protégé, pourquoi ne pas trouver un uniforme et se mêler à la foule?","A Püspök elég izmos védelmet élvez, érdemes lesz lopnunk egy uniformist a beilleszkedés jegyében.","Il Vescovo sarà sicuramente ben protetto, quindi perché non camuffarsi con un'uniforme?",ビショップのいる場所の警備は厳重なので、奴等の制服を盗み紛れ込む方が良いのでは?,"비숍은 군사 지도자니까, 삼엄한 경비에 의해 지켜질 거야. 그러니 전투복을 입고 잠입하는 게 어때?","De bisschop zal zwaar bewaakt worden, dus waarom vegen we er niet een uniform overheen en mengen we ons in de bisschop?","Biskopen kommer til å være tungt bevoktet, så hvorfor tar vi ikke en uniform og smelter inn?","Biskup będzie pilnie strzeżony, więc czemu nie weźmiemy munduru i nie wtopimy się w tłum?","O Bispo está protegido por vários guardas, então que tal roubar um uniforme e se mesclar?",,Episcopul o să fie extrem de bine păzit deci de ce nu luăm o uniformă și ne camuflăm?,"Похоже, что Епископа неплохо охраняют. Предлагаю стянуть униформу и прокрасться внутрь.",,"Piskopos çok sıkı korunuyor olacak, neden bir üniforma çalıp aralarına karışmıyoruz?" -"Remind me, we win this thing and I'll call in a decorator.",TXT_SUB_LOG58,,,,"Připomeň mi až vyhrajeme, abych zavolala malíře.","Mind mig om, at hvis vi vinder det her, så tilkalder jeg en dekoratør.","Bitte erinnere mich daran, dass wir einen Dekorateur bestellen, nachdem wir gewonnen haben.",,,"Recuérdame, nos ganamos esto y llamo a un decorador.",,"Muistuta minua, että jos voitamme tämän, niin kutsun paikalle sisustussuunnittelijan.","Rappelle-moi, quand on a fini, il faut que j'appelle un décorateur.","Emlékeztess rá, hogy ha túlvagyunk ezen hívjak egy szobafestőt.","Ricordamelo, appena vinciamo questa battaglia bisogna chiamare qualcuno per ridecorare.",,"우리가 이길 수만 있다면, 축제 분위기 나게 장식할 사람을 부를 거야.","Herinner me eraan, we winnen dit ding en ik zal een decorateur inschakelen.","Minn meg på at hvis vi vinner, ringer jeg etter en dekoratør.","Przypomnij mi, że jak wygramy to wezwę dekoratora.","Não deixa eu esquecer, depois de vencermos vou chamar um decorador.",,"Adu-mi aminte, câștigăm și chem să ne decoreze.","Напомни мне позвать декоратора после того, как мы победим.",,"Hatırlat bana, bu şeyi kazanırsak bir dekoratör çağıracağım." +奴を仕留めれば得点は倍額でしょう。","비숍은 그들의 잔혹한 군사 지도자이지. 그는 전술을 획책하고, 첩자를 부리고, 우리들을 통제하고 있어. 그를 죽이면 두 배로 이득이 갈 거야.","De bisschop is de militaire leider van de Orde. Hij zet hun tactiek uit, leidt hun spionnen en heeft de opdracht ons te controleren. We gaan van hem af en we scoren twee keer.","Biskopen er ordenens militære leder. Han planlegger taktikken deres, styrer spionene deres og har ansvaret for å kontrollere oss. Dreper vi ham, scorer vi to ganger.","Biskup jest przywódcą wojskowym Zakonu. Tworzy ich taktykę, prowadzi ich szpiegów i ma za zadanie kontrolować nas. Zdejmiemy go i zdobędziemy dwa punkty.","O Bispo é o líder militar da Ordem. Ele planeja suas táticas, comanda seus espiões e é encarregado de nos controlar. Eliminamos ele e é dois coelhos numa tacada só.",,"Episcopul e liderul militar al Ordinului. Le planifică schemele, tacticile, spionează, și ne controlează. Îl eliminăm și înscriem de două ori.","Епископ — военный лидер Ордена. Он обучает их тактике, управляет их шпионами и жаждет контроля над нами. От его убийства мы выигрываем вдвойне.",,"Biskopen är ordens militära ledare. Han planerar deras taktik, leder deras spioner och har till uppgift att kontrollera oss. Om vi dödar honom får vi två poäng.","Piskopos, Tarikat'ın askeri lideridir. Taktiklerini planlar, casuslarını yönetir ve bizi kontrol etmekle görevlidir. Ondan kurtulursak iki kere kazanırız." +The Bishop is going to be heavily guarded so why don't we swipe a uniform and blend in?,TXT_SUB_LOG57,MAP11: Officer's uniform room.,,,"Biskup bude silně strážen, co takhle sebrat uniformu a splynout s davem?","Biskoppen vil være stærkt bevogtet, så hvorfor tager vi ikke en uniform og falder ind i mængden?","Der Bischof wird schwer bewacht sein, so warum stibitzen wir nicht eine Uniform um uns besser anzupassen?",,,El Obispo estará bien guardado asi que ¿por que no pillamos un uniforme y nos mezclamos?,,"Piispa on taatusti tarkoin vartioitu, joten miksemme kähveltäisi univormua ja sulautuisi joukkoon?","L'évèque sera lourdement protégé, pourquoi ne pas trouver un uniforme et se mêler à la foule?","A Püspök elég izmos védelmet élvez, érdemes lesz lopnunk egy uniformist a beilleszkedés jegyében.","Il Vescovo sarà sicuramente ben protetto, quindi perché non camuffarsi con un'uniforme?",ビショップのいる場所の警備は厳重なので、奴等の制服を盗み紛れ込む方が良いのでは?,"비숍은 군사 지도자니까, 삼엄한 경비에 의해 지켜질 거야. 그러니 전투복을 입고 잠입하는 게 어때?","De bisschop zal zwaar bewaakt worden, dus waarom vegen we er niet een uniform overheen en mengen we ons in de bisschop?","Biskopen kommer til å være tungt bevoktet, så hvorfor tar vi ikke en uniform og smelter inn?","Biskup będzie pilnie strzeżony, więc czemu nie weźmiemy munduru i nie wtopimy się w tłum?","O Bispo está protegido por vários guardas, então que tal roubar um uniforme e se mesclar?",,Episcopul o să fie extrem de bine păzit deci de ce nu luăm o uniformă și ne camuflăm?,"Похоже, что Епископа неплохо охраняют. Предлагаю стянуть униформу и прокрасться внутрь.",,Biskopen kommer att vara tungt bevakad så varför tar vi inte en uniform och smälter in?,"Piskopos çok sıkı korunuyor olacak, neden bir üniforma çalıp aralarına karışmıyoruz?" +"Remind me, we win this thing and I'll call in a decorator.",TXT_SUB_LOG58,,,,"Připomeň mi až vyhrajeme, abych zavolala malíře.","Mind mig om, at hvis vi vinder det her, så tilkalder jeg en dekoratør.","Bitte erinnere mich daran, dass wir einen Dekorateur bestellen, nachdem wir gewonnen haben.",,,"Recuérdame, nos ganamos esto y llamo a un decorador.",,"Muistuta minua, että jos voitamme tämän, niin kutsun paikalle sisustussuunnittelijan.","Rappelle-moi, quand on a fini, il faut que j'appelle un décorateur.","Emlékeztess rá, hogy ha túlvagyunk ezen hívjak egy szobafestőt.","Ricordamelo, appena vinciamo questa battaglia bisogna chiamare qualcuno per ridecorare.",,"우리가 이길 수만 있다면, 축제 분위기 나게 장식할 사람을 부를 거야.","Herinner me eraan, we winnen dit ding en ik zal een decorateur inschakelen.","Minn meg på at hvis vi vinner, ringer jeg etter en dekoratør.","Przypomnij mi, że jak wygramy to wezwę dekoratora.","Não deixa eu esquecer, depois de vencermos vou chamar um decorador.",,"Adu-mi aminte, câștigăm și chem să ne decoreze.","Напомни мне позвать декоратора после того, как мы победим.",,Påminn mig om att om vi vinner det här så ska jag kalla in en dekoratör.,"Hatırlat bana, bu şeyi kazanırsak bir dekoratör çağıracağım." "I just got word we got an informer inside the fortress. Let's head toward what they call the hospital, he works there.",TXT_SUB_LOG59,MAP17: Bailey → Upstairs.,,,"Právě jsem dostala zprávu, že máme v pevnosti informátora. Měli bychom zamířit k nemocnici, pracuje tam.","Jeg har lige hørt, at vi har en stikker inde i fæstningen. Lad os gå mod det, de kalder hospitalet. Han arbejder der.","Ich habe gerade gehört, dass wir einen Informanten in der Festung haben. Geh rüber um Hospital, dort arbeitet er.",,"Mi ĵus estis sciigita, ke ni havas informanton en la fortreso. Ni iru al tio, kion ili nomas «la malsanulejo», lia laborejo.","Acaban de decirme que tenemos un informante dentro de la fortaleza. Vayamos a lo que llaman «el hospital», que es donde trabaja.","Acaban de decirme que tenemos un informante adentro de la fortaleza. Vayamos a lo que le dicen «el hospital», que es donde trabaja.","Sain juuri tiedon ilmiantajasta linnoituksessa. Suunnataan kohti paikkaa, jota he kutsuvat sairaalaksi; hän työskentelee siellä.","J'entends qu'un de nos informants se trouve dans la forteresse. Allons dans ce qu'ils appellent l'hôpital, il y travaille.","Most kaptam a hírt, hogy van egy besúgónk az erődítményben. Menjünk a kórháznak nevezett részlegbe, ott dolgozik.","Ho appena scoperto che abbiamo un informatore dentro la fortezza. Rechiamoci verso ciò che chiamano l'ospedale, lui lavora là.","要塞の中に情報提供者がいるという話を聞いた。 -奴等が病院と呼んでいる場所に勤めているので向かいましょう。","요새 안에 우리들을 도울 정보원이 있다는 보고를 들었어. 그는 오더가 병원이라고 부르는 곳 안에 있는데, 그곳으로 찾아가 봐.","Ik heb net gehoord dat we een informant in het fort hebben. Laten we naar wat ze het ziekenhuis noemen gaan, hij werkt daar.",Jeg hørte nettopp at vi har en informant inne i festningen. La oss dra til det de kaller sykehuset. Han jobber der.,"Właśnie dostałem wiadomość, że mamy informatora w twierdzy. Kierujmy się w stronę tego, co nazywają szpitalem, on tam pracuje.","Acabei de receber a informação de que temos um informante dentro da fortaleza. Vamos para onde eles chamam de ""hospital"". Ele trabalha lá.",,"Tocmai am primit ceva de la un informator din interiorul fortăreței. Să merge înspre ceea ce ei numesc spital, lucrează acolo.","Мне только что сказали, что у нас есть информатор внутри крепости. Нам нужно место, которое они называют госпиталем — он работает там.",,"Az önce kalenin içinde bir muhbirimiz olduğu haberini aldım. Hastane dedikleri yere doğru gidelim, orada çalışıyor." -"Grab the plans and knock out the computer, ok?",TXT_SUB_LOG60,MAP17: Security Complex,,,"Seber plány a znič počítač, dobře?","Tag tegningerne og slå computeren ud, okay?","Nimm die Plane und schalte den Computer aus, ok?",,,"Coge los planos y destruye el ordenador, ¿sí?","Toma los planos y destruye la computadora, ¿sí?","Nappaa suunnitelmat ja hajota tietokone, eikö niin?","Récupère les plans et détruis l'ordinateur, ok?","Kapd fel a terveket, és nyírd ki a számítógépet, rendben?","Prendi i piani e distruggi il computer, ok?",計画を奪いにコンピューターを破壊する、いけるわね?,계획서를 집고 컴퓨터를 파괴해. 간단하지?,"Pak de plannen en sla de computer eruit, oké?","Ta tegningene og slå ut datamaskinen, ok?","Weź plany i wywal komputer, ok?","Pegue os planos e destrua o computador, ok?",,"Ia planurile și distruge calculatorul, ok?","Хватаем планы и ломаем компьютер, лады?",,"Planları al ve bilgisayarı devre dışı bırak, tamam mı?" +奴等が病院と呼んでいる場所に勤めているので向かいましょう。","요새 안에 우리들을 도울 정보원이 있다는 보고를 들었어. 그는 오더가 병원이라고 부르는 곳 안에 있는데, 그곳으로 찾아가 봐.","Ik heb net gehoord dat we een informant in het fort hebben. Laten we naar wat ze het ziekenhuis noemen gaan, hij werkt daar.",Jeg hørte nettopp at vi har en informant inne i festningen. La oss dra til det de kaller sykehuset. Han jobber der.,"Właśnie dostałem wiadomość, że mamy informatora w twierdzy. Kierujmy się w stronę tego, co nazywają szpitalem, on tam pracuje.","Acabei de receber a informação de que temos um informante dentro da fortaleza. Vamos para onde eles chamam de ""hospital"". Ele trabalha lá.",,"Tocmai am primit ceva de la un informator din interiorul fortăreței. Să merge înspre ceea ce ei numesc spital, lucrează acolo.","Мне только что сказали, что у нас есть информатор внутри крепости. Нам нужно место, которое они называют госпиталем — он работает там.",,"Jag fick just höra att vi har en informatör inne i fästningen. Vi går mot det som de kallar sjukhuset, han arbetar där.","Az önce kalenin içinde bir muhbirimiz olduğu haberini aldım. Hastane dedikleri yere doğru gidelim, orada çalışıyor." +"Grab the plans and knock out the computer, ok?",TXT_SUB_LOG60,MAP17: Security Complex,,,"Seber plány a znič počítač, dobře?","Tag tegningerne og slå computeren ud, okay?","Nimm die Plane und schalte den Computer aus, ok?",,,"Coge los planos y destruye el ordenador, ¿sí?","Toma los planos y destruye la computadora, ¿sí?","Nappaa suunnitelmat ja hajota tietokone, eikö niin?","Récupère les plans et détruis l'ordinateur, ok?","Kapd fel a terveket, és nyírd ki a számítógépet, rendben?","Prendi i piani e distruggi il computer, ok?",計画を奪いにコンピューターを破壊する、いけるわね?,계획서를 집고 컴퓨터를 파괴해. 간단하지?,"Pak de plannen en sla de computer eruit, oké?","Ta tegningene og slå ut datamaskinen, ok?","Weź plany i wywal komputer, ok?","Pegue os planos e destrua o computador, ok?",,"Ia planurile și distruge calculatorul, ok?","Хватаем планы и ломаем компьютер, лады?",,"Ta ritningarna och slå ut datorn, okej?","Planları al ve bilgisayarı devre dışı bırak, tamam mı?" "Alright, I'm not complaining, but next time we might try the way that isn't buckets of blood.",TXT_SUB_LOG61,"(Strife: Veteran Edition) -Random comment when the player dies with Classic Mode turned off",,,"Dobře, nestěžuju si, ale příště bychom mohli zkusit způsob, po kterém nezůstanou kýble krve.","Okay, jeg klager ikke, men næste gang kan vi måske prøve den måde, der ikke er spandevis af blod.","Ok, ich will nicht meckern, aber beim nächsten Mal sollte das mit weniger Blutvergießen vonstatten gehen.",,,"Muy bien, no me quejo, pero la próxima vez deberíamos probar el método que no sea una masacre.",,"Hyvä on, en minä mitään valita, mutta ensi kerralla voisimme kokeilla tapaa, joka ei sisällä ämpärikaupalla verta.","Bon, je ne me plains pas, mais la prochaine fois, essayons de faire sans foutre du sang partout?","Igazából nem akarok panaszkodni, de legközelebb próbáljunk meg egy kevsébé véres módszert.","Va bene, non che voglia lamentarmi, ma magari la prossima volta ",大丈夫、次は血のバケツをぶち撒けない方法を試した方がいい。,"이런... 비꼬는 건 아닌데, 다음번엔 유혈사태를 일으키지 않고 일을 해결해보자.","Oké, ik klaag niet, maar de volgende keer kunnen we misschien de manier proberen waarop dat geen emmers bloed is.","Greit, jeg klager ikke, men neste gang kan vi prøve en vei som ikke er bøtter med blod.","Dobra, nie narzekam, ale następnym razem może spróbujemy drogi, która nie jest wiadrami krwi.","Tá bem, não estou reclamando. Mas da próxima vez vamos tentar de um jeito que não seja sangue jorrando pra tudo que é lado.",,"În regulă, nu mă plâng, dar data viitoare încercăm calea care nu duce la găleți de sânge.","Я не жалуюсь, но, может, в следующий раз попробуем не проливать реки крови?",,"Pekala, şikayet etmiyorum ama bir dahaki sefere kova kova kan olmayan yolu deneyebiliriz." +Random comment when the player dies with Classic Mode turned off",,,"Dobře, nestěžuju si, ale příště bychom mohli zkusit způsob, po kterém nezůstanou kýble krve.","Okay, jeg klager ikke, men næste gang kan vi måske prøve den måde, der ikke er spandevis af blod.","Ok, ich will nicht meckern, aber beim nächsten Mal sollte das mit weniger Blutvergießen vonstatten gehen.",,,"Muy bien, no me quejo, pero la próxima vez deberíamos probar el método que no sea una masacre.",,"Hyvä on, en minä mitään valita, mutta ensi kerralla voisimme kokeilla tapaa, joka ei sisällä ämpärikaupalla verta.","Bon, je ne me plains pas, mais la prochaine fois, essayons de faire sans foutre du sang partout?","Igazából nem akarok panaszkodni, de legközelebb próbáljunk meg egy kevsébé véres módszert.","Va bene, non che voglia lamentarmi, ma magari la prossima volta ",大丈夫、次は血のバケツをぶち撒けない方法を試した方がいい。,"이런... 비꼬는 건 아닌데, 다음번엔 유혈사태를 일으키지 않고 일을 해결해보자.","Oké, ik klaag niet, maar de volgende keer kunnen we misschien de manier proberen waarop dat geen emmers bloed is.","Greit, jeg klager ikke, men neste gang kan vi prøve en vei som ikke er bøtter med blod.","Dobra, nie narzekam, ale następnym razem może spróbujemy drogi, która nie jest wiadrami krwi.","Tá bem, não estou reclamando. Mas da próxima vez vamos tentar de um jeito que não seja sangue jorrando pra tudo que é lado.",,"În regulă, nu mă plâng, dar data viitoare încercăm calea care nu duce la găleți de sânge.","Я не жалуюсь, но, может, в следующий раз попробуем не проливать реки крови?",,"Okej, jag klagar inte, men nästa gång kanske vi ska försöka på det sätt som inte innebär hinkar med blod.","Pekala, şikayet etmiyorum ama bir dahaki sefere kova kova kan olmayan yolu deneyebiliriz." "We've been through endless hallways before, but I swear, these walls are moving as we pass.",TXT_SUB_LOG62,MAP19: Cross-shaped room at the beginning.,,,"Už jsme předtím byli v nekonečných chodbách, ale přísahám, že tyhle stěny se hýbou.","Vi har været igennem endeløse gange før, men jeg sværger, at disse vægge bevæger sig, mens vi passerer.","Wir sind ja schon durch endlose Flure gegangen, aber ich könnte schwören, dass sich die Wände hier bewegen.",,,"Ya hemos pasado por pasillos sin fin otras veces, pero juro que estas paredes se están moviendo a nuestro paso.",,"Olemme ennenkin kulkeneet loputtomia käytäviä pitkin, mutta voisin melkein vannoa näiden seinien liikkuvan sitä mukaa kun läpi käymme.","J'ai déja fais un tour dans un couloir sans fin comme ça, mais je jure que les murs bougent avec nous.","Volt már dolgunk végtelen hosszú folyosóval, de esküszöm olyan érzésem van, mintha velünk együtt mozognának a falak.","Abbiamo superato chissà quanti corridoi fino ad ora, ma ti giuro, questi muri si muovono mentre camminiamo.","以前に私達は無限へ通じる玄関を通ったかと思うが、誓おう、 -通り過ぎた時に壁が動いていたからだと。","난감한 곳들을 다녀갔지만, 여기는 뭔가 새로워. 걸어갈 때마다 벽이 움직이는 것 같거든...","We zijn al eens door eindeloze gangen geweest, maar ik zweer het, deze muren bewegen zich in de loop van de tijd.","Vi har gått gjennom endeløse korridorer før, men disse veggene beveger seg når vi går forbi.","Przechodziliśmy już przez nieskończone korytarze, ale przysięgam, że te ściany się ruszają, gdy przechodzimy.","Já passamos por inúmeros corredores antes, mas eu juro, essas paredes ficam se mexendo enquanto a gente passa.",,Am mai fost prin holuri nesfârșite dar jur că zidurile ăstea se mișcă odată cu noi.,"Мы уже повидали достаточно бесконечных коридоров, но я готова поклясться: эти стены передвигаются, когда мы на них не смотрим.",,"Daha önce de sonsuz koridorlardan geçtik, ama yemin ederim, bu duvarlar biz geçerken hareket ediyor." -"Well, you gotta figure. Military leader equals lots of bad guys.",TXT_SUB_LOG63,MAP16,,,"No, dává to smysl. Armádní vůdce rovná se hodně padouchů.",Det må man regne ud. Militær leder er lig med masser af skurke.,Das war ja klar. Militärischer Anführer bedeutet jede Menge Bösewichte.,,"Nu, ĉi tio estis divenebla: «Militestro» estas egala al multaj malbonuloj.","Bueno, era de imaginar: «Líder militar» equivale a muchos tipos malos.",,Mietipä sitä; sotapäällikkö vastaa monta pahista.,"Bon, fallait y penser. Chef militaire, ça veut dire beaucoup de types armés.","Ki gondolta volna, hogy egy katonai vezetőt egy rakás rossz fiú fog védeni.","Beh, c'era da aspettarselo. Capo militare significa un sacco di cattivi.",さて、貴方はフィギュアを得た。軍隊指揮者は大勢の悪人に匹敵するわ。,이거 정말 뻔하네. 군대 우두머리의 심복들은 다 난폭하고 둔하지.,"Nou ja, je moet het wel beseffen. Militair leider is gelijk aan veel slechteriken.","Vel, du må skjønne. Militærleder er lik mange skurker.","No cóż, trzeba to sobie wyobrazić. Przywódca wojskowy równa się wielu złym ludziom.","Olha só, quem diria. Líder militar é igual a um monte de caras malvados.",,"Ei, dă-ți seama. Lider militar înseamnă mulți băieți răi.",Сам понимаешь. Военный лидер — всё равно что куча плохих парней.,,Bunu anlamalısın. Askeri lider eşittir bir sürü kötü adam. -Don't give up. This is it. Straight ahead.,TXT_SUB_LOG64,MAP19: Last room (southwestern).,,,"Nevzdávej se, tohle je ono. Jdi rovně.",Du må ikke give op. Det er nu. Lige fremad.,Gib nicht auf. Direkt voraus.,,,No te rindas. Vas bien: justo adelante.,,"Älä luovuta. So nyt tässä, suoraan edessä.","Abandonne pas, on y est. Juste devant.",Ne add fel. Ez lesz az. Éppen előttünk.,Non arrenderti. Siamo arrivati. Dritto in fronte a te.,諦めないで。これでいいんだ。真っ直ぐ行こう。,포기하지 마. 거의 다 왔어. 가까이 왔다고.,Geef niet op. Dit is het. Rechtdoor.,Ikke gi opp. Her er det. Rett fram.,Nie poddawaj się. To jest to. Prosto przed siebie.,Não desista. Esta é a hora. Siga reto adiante.,,Nu te da bătut. Asta e. Drept înainte.,Не падай духом. Вот оно. Впереди.,,Sakın pes etme. İşte burası. Dümdüz ilerle. -"Next time, we stop at a gas station and ask for directions.",TXT_SUB_LOG65,,,,Příště se zastavíme na benzince a zeptáme se na cestu.,Næste gang stopper vi ved en tankstation og spørger om vej.,Nächstes Mal halten wir an einer Tankstelle und fragen nach der Richtung.,,,A la próxima paramos en una gasolinera y preguntamos la dirección.,,Ensi kerralla pysähdytään huoltoasemalle kysymään suuntaneuvoja.,"La prochaine fois, on s'arrète à une station-service et on demande notre chemin.","Legközelebb amikor megállunk egy benzinkútnál, körbekérdezünk az irányzékkal kapcsolatban.","La prossima volta, ci fermiamo ad una stazione di servizio per chiedere indicazioni.",,다음엔 편의점 같은 건물에 들러서 그냥 방향을 묻자.,De volgende keer stoppen we bij een tankstation en vragen we de weg.,Neste gang stopper vi på en bensinstasjon og spør om veien.,Następnym razem zatrzymamy się na stacji benzynowej i zapytamy o drogę.,Da próxima vez vamos parar num posto de gasolina e perguntar onde fica.,,Data viitoare ne oprim la o benzinărie și întrebăm despre repere.,В следующий раз остановимся на заправке и спросим дорогу.,,Bir dahaki sefere benzin istasyonunda durup yol sorarız. -Oh no! More bells and whistles and nasty guys chasing us.,TXT_SUB_LOG66,MAP19: After coming across an alarm green door.,,,"Ale ne! Další fešné vymoženosti a zmetci, co nás pronásledují.","Åh nej! Flere klokker og fløjter og grimme fyre, der jagter os.",Oh nein. Noch mehr Lärm und Bösewichte auf unseren Fersen.,,,¡No puede ser! Más bombos y platillos y tipos malos persiguiéndonos.,,Voi ei! Lisää härpäkkeitä ja pahiksia jahtaamassa meitä.,Oh non! Encore des trucs et des choses et des sales types qui nous prennent en chasse.,"Jaj ne! Még több csicsás rész, és még annál is több gonosz a nyomunkban.",Oh no! Campane e fischietti e altri cattivi che ci inseguono.,あーらら!鐘と笛で更に厄介な奴等を呼び込んできたな。,"오, 안 돼! 삼엄한 경비에 피할 수도 없는 선택지라니.",Oh nee! Nog meer toeters en bellen en vervelende jongens die ons achterna zitten.,"Å, nei! Flere bjeller og fløyter og ekle fyrer som jager oss.","O nie! Więcej dzwonków i gwizdków i wrednych facetów, którzy nas gonią.",Ai não! Mais bugigangas e capangas vindo atrás de nós.,,Oh nu! Mai mulți băieți răi ne urmăresc!,"О, нет! Ещё больше свистелок, перделок и плохих парней, которые за нами гонятся.",,Olamaz! Daha fazla zil ve düdük ve bizi kovalayan kötü adamlar. -"You know, from the outside, this place looks tiny.",TXT_SUB_LOG67,MAP15: After using a big lift next to a Reaver.,,,Zvenku tohle místo vypadalo drobounké.,Udefra ser det her sted lille ud.,Von außen sieht das hier irgendwie mickrig aus.,,"Nu, ĉi tiu loko aspektis malgranda de ekstere.","O sea, este lugar se veía enano desde fuera.","O sea, este lugar se veía enano desde afuera.","Oletko muuten huomannut, että ulkopuolelta katsottuna tämä paikka näyttää tosi pieneltä.","Tu sais, de l'extérieur, cet endroit à l'air super petit.","Azt hinné az ember, hogy sokkal kisebb ez a hely a kinti kinézet alapján.","Lo sai, da fuori, questo posto sembra piccolo.",外から見ると、此処は小さいみたいね。,"궁금한 게 있는데, 왜 안에 들어가면 커지는 걸까?","Weet je, van buitenaf ziet deze plek er klein uit.","Du vet, fra utsiden ser dette stedet lite ut.","Wiesz, z zewnątrz to miejsce wygląda na malutkie.","Sabe, vendo de longe esse lugar parece minúsculo.",,"Știi, din afară, locul ăsta arată mărunt.","Знаешь, снаружи это место кажется крошечным.",,Dışarıdan bakınca burası çok küçük görünüyor. -"I'm getting a new enemy reading. Don't stop and stare, just waste 'em.",TXT_SUB_LOG68,,,,Zaznamenávám nového nepřítele. Nestůj tam a znič ho!,"Jeg får en ny fjendeudlæsning. Lad være med at stoppe op og stirre, bare smadr dem.","Ich habe eine neue Feindortung. Warum wartest du, mach sie alle!",,,"Tengo señales de un nuevo enemigo. No te pares a mirar, solo cárgatelo.",,Saan uuden lukeman vihollisista. Älä siihen jää töllöttämään; listi ne!,"J'ai un ping ennemi sur mon radar. Ne t'arrète pas, flingue-les.","Új ellenséget észlelek. Ne állj meg nézelődni, hanem nyírd ki őket.","Sto ricevendo segnali di altri nemici. Non fermarti a guardare, distruggili.",,네 주변에 적이 포착됐어. 그냥 쳐다보지 말고 어떻게든 해봐.,"Ik krijg een nieuwe vijandelijke lezing. Niet stoppen en staren, maar ze gewoon verspillen.","Jeg får en ny fiende på skjermen. Ikke stopp og stir, bare skyt dem.","Dostaję nowy odczyt wroga. Nie zatrzymuj się i nie gap, po prostu je zmarnuj.","Estou recebendo sinais de um novo inimigo. Nâo fique parado olhando, mete bala neles.",,"Citesc inamici în apropiere. Nu te oprii și holba, fă-i bucăți.","Вижу врагов. Не стой столбом, мочи их!",,"Yeni bir düşman okuması alıyorum. Durup bakma, sadece harca onları." -"I hate these forcefields. Look for the shut-off switch, it's gotta be nearby.",TXT_SUB_LOG69,STRIFE1.WAD: MAP15,,,"Nesnáším tahle silová pole. Porozhlédni se po nějakém vypínači, měl by být nablízku.",Jeg hader disse kraftfelter. Se efter slukkontakten. Den må være i nærheden.,"Ich hasse diese Kraftfelder. Such nach einem Schalter, er müsste in der Nähe sein.",,,"Odio estos campos de fuerza. Busca el interruptor de apagado, tiene que estar cerca.",,Vihaan näitä voimakenttiä. Etsi virtakatkaisinta; sen on pakko olla jossain lähettyvillä.,"Je déteste les champs de force. Trouve leur commandes, elles ne doivent pas être loin.","Utálom ezket az erőpajzsokat. Keresd egy kikapcsoló gombot, itt kell lennie valahol.","Odio questi campi di forza. Cerca il pulsante per disattivarlo, deve essere vicino.",私はフォースフィールドが憎いわ。遮断させるスイッチが近くにあるはずだわ。,이런 방어막들 정말 싫다니까. 저걸 끌 스위치를 찾아봐. 가까이에 있을 거야.,"Ik haat deze krachtvelden. Zoek naar de afsluitschakelaar, die moet in de buurt zijn.",Jeg hater disse kraftfeltene. Se etter bryteren. Den må være i nærheten.,"Nienawidzę tych pól siłowych. Szukajcie wyłącznika, musi być w pobliżu.","Odeio esses campos de força. Procure pelo interruptor de desligar, deve estar por perto.",,"Urăsc compurile de forță. Uită-te după un buton de oprire, trebuie să fie în apropiere.","Ненавижу эти силовые поля. Поищи выключатель, он где-то неподалёку.",,"Bu güç alanlarından nefret ediyorum. Kapatma düğmesini ara, yakında olmalı." -"Ooh, very impressive. Let's blow it up!",TXT_SUB_LOG70,MAP15: After pressing the switch to reveal the computer.,,,"Ó, velmi působivé. Co to nechat vybouchnout?",Meget imponerende. Lad os sprænge den i luften!,"Oh, sehr imposant. Jag ihn hoch!",,,Muy impresionante. ¡Destruyámoslo!,Muy impresionante. ¡Vamos a destruirla!,"Oo, aika vaikuttava. Posautetaan se!","Oooh, très impressionant! Faisons tout péter!",Felettébb lenyűgöző. Robbantsuk is fel!,"Aah, molto impressionante! Facciamolo saltare in aria!",あら、見事な物ね。是非とも火薬を献上しましょう。,"오우, 정말 이쁘네! 이제 터뜨리자!","Ooh, heel indrukwekkend. Laten we hem opblazen!",Veldig imponerende. La oss sprenge den!,"Ooh, bardzo imponujące. Wysadźmy to w powietrze!","Oohh, que impressionante! Vamos detoná-lo.",,"ooh, foarte impresionant. Să-l aruncăm în aer!",Очень впечатляюще. Давай взорвём!,,"Ooh, çok etkileyici. Hadi havaya uçuralım!" -"Jump on the teleporter, let's blow this pop stand.",TXT_SUB_LOG71,,,,Skoč na teleportér a odpalme tenhle stánek se zmrzlinou.,"Hop på teleporteren, lad os sprænge denne popstand.",Spring in den Teleporter und jag das Ding hoch.,,,"Súbete al teletransporte, carguémonos este tinglado.",,Loikkaa kaukosiirtimelle; häivytään tästä mestasta.,"Saute dans le téléporteur, cassons nous d'ici.","Ugrás a teleportba, és robbantsuk az égig ezt a kuplerájt.","Salta sul teletrasporto, facciamo esplodere questo mortorio.",,텔레포터를 타고 이 놀이터를 벗어나자.,"Spring op de teleporter, laten we deze popstandaard opblazen.","Hopp på teleporteren, la oss sprenge denne kiosken.","Wskakuj do teleportera, wysadźmy to stoisko z popem.","Entre no teletransportador, vamos explodir este muquifo.",,"Sari în teleportor, să aruncăm în aer totul.",Прыгай в телепорт. Пора валить отсюда.,,"Işınlayıcıya atla, hadi şu pop standını havaya uçuralım." +通り過ぎた時に壁が動いていたからだと。","난감한 곳들을 다녀갔지만, 여기는 뭔가 새로워. 걸어갈 때마다 벽이 움직이는 것 같거든...","We zijn al eens door eindeloze gangen geweest, maar ik zweer het, deze muren bewegen zich in de loop van de tijd.","Vi har gått gjennom endeløse korridorer før, men disse veggene beveger seg når vi går forbi.","Przechodziliśmy już przez nieskończone korytarze, ale przysięgam, że te ściany się ruszają, gdy przechodzimy.","Já passamos por inúmeros corredores antes, mas eu juro, essas paredes ficam se mexendo enquanto a gente passa.",,Am mai fost prin holuri nesfârșite dar jur că zidurile ăstea se mișcă odată cu noi.,"Мы уже повидали достаточно бесконечных коридоров, но я готова поклясться: эти стены передвигаются, когда мы на них не смотрим.",,"Vi har gått igenom ändlösa korridorer förut, men jag svär att de här väggarna rör sig när vi passerar.","Daha önce de sonsuz koridorlardan geçtik, ama yemin ederim, bu duvarlar biz geçerken hareket ediyor." +"Well, you gotta figure. Military leader equals lots of bad guys.",TXT_SUB_LOG63,MAP16,,,"No, dává to smysl. Armádní vůdce rovná se hodně padouchů.",Det må man regne ud. Militær leder er lig med masser af skurke.,Das war ja klar. Militärischer Anführer bedeutet jede Menge Bösewichte.,,"Nu, ĉi tio estis divenebla: «Militestro» estas egala al multaj malbonuloj.","Bueno, era de imaginar: «Líder militar» equivale a muchos tipos malos.",,Mietipä sitä; sotapäällikkö vastaa monta pahista.,"Bon, fallait y penser. Chef militaire, ça veut dire beaucoup de types armés.","Ki gondolta volna, hogy egy katonai vezetőt egy rakás rossz fiú fog védeni.","Beh, c'era da aspettarselo. Capo militare significa un sacco di cattivi.",さて、貴方はフィギュアを得た。軍隊指揮者は大勢の悪人に匹敵するわ。,이거 정말 뻔하네. 군대 우두머리의 심복들은 다 난폭하고 둔하지.,"Nou ja, je moet het wel beseffen. Militair leider is gelijk aan veel slechteriken.","Vel, du må skjønne. Militærleder er lik mange skurker.","No cóż, trzeba to sobie wyobrazić. Przywódca wojskowy równa się wielu złym ludziom.","Olha só, quem diria. Líder militar é igual a um monte de caras malvados.",,"Ei, dă-ți seama. Lider militar înseamnă mulți băieți răi.",Сам понимаешь. Военный лидер — всё равно что куча плохих парней.,,Det måste man räkna ut. Militär ledare är lika med många skurkar.,Bunu anlamalısın. Askeri lider eşittir bir sürü kötü adam. +Don't give up. This is it. Straight ahead.,TXT_SUB_LOG64,MAP19: Last room (southwestern).,,,"Nevzdávej se, tohle je ono. Jdi rovně.",Du må ikke give op. Det er nu. Lige fremad.,Gib nicht auf. Direkt voraus.,,,No te rindas. Vas bien: justo adelante.,,"Älä luovuta. So nyt tässä, suoraan edessä.","Abandonne pas, on y est. Juste devant.",Ne add fel. Ez lesz az. Éppen előttünk.,Non arrenderti. Siamo arrivati. Dritto in fronte a te.,諦めないで。これでいいんだ。真っ直ぐ行こう。,포기하지 마. 거의 다 왔어. 가까이 왔다고.,Geef niet op. Dit is het. Rechtdoor.,Ikke gi opp. Her er det. Rett fram.,Nie poddawaj się. To jest to. Prosto przed siebie.,Não desista. Esta é a hora. Siga reto adiante.,,Nu te da bătut. Asta e. Drept înainte.,Не падай духом. Вот оно. Впереди.,,Ge inte upp. Det här är det. Rakt fram.,Sakın pes etme. İşte burası. Dümdüz ilerle. +"Next time, we stop at a gas station and ask for directions.",TXT_SUB_LOG65,,,,Příště se zastavíme na benzince a zeptáme se na cestu.,Næste gang stopper vi ved en tankstation og spørger om vej.,Nächstes Mal halten wir an einer Tankstelle und fragen nach der Richtung.,,,A la próxima paramos en una gasolinera y preguntamos la dirección.,,Ensi kerralla pysähdytään huoltoasemalle kysymään suuntaneuvoja.,"La prochaine fois, on s'arrète à une station-service et on demande notre chemin.","Legközelebb amikor megállunk egy benzinkútnál, körbekérdezünk az irányzékkal kapcsolatban.","La prossima volta, ci fermiamo ad una stazione di servizio per chiedere indicazioni.",,다음엔 편의점 같은 건물에 들러서 그냥 방향을 묻자.,De volgende keer stoppen we bij een tankstation en vragen we de weg.,Neste gang stopper vi på en bensinstasjon og spør om veien.,Następnym razem zatrzymamy się na stacji benzynowej i zapytamy o drogę.,Da próxima vez vamos parar num posto de gasolina e perguntar onde fica.,,Data viitoare ne oprim la o benzinărie și întrebăm despre repere.,В следующий раз остановимся на заправке и спросим дорогу.,,Nästa gång stannar vi vid en bensinstation och frågar efter vägen.,Bir dahaki sefere benzin istasyonunda durup yol sorarız. +Oh no! More bells and whistles and nasty guys chasing us.,TXT_SUB_LOG66,MAP19: After coming across an alarm green door.,,,"Ale ne! Další fešné vymoženosti a zmetci, co nás pronásledují.","Åh nej! Flere klokker og fløjter og grimme fyre, der jagter os.",Oh nein. Noch mehr Lärm und Bösewichte auf unseren Fersen.,,,¡No puede ser! Más bombos y platillos y tipos malos persiguiéndonos.,,Voi ei! Lisää härpäkkeitä ja pahiksia jahtaamassa meitä.,Oh non! Encore des trucs et des choses et des sales types qui nous prennent en chasse.,"Jaj ne! Még több csicsás rész, és még annál is több gonosz a nyomunkban.",Oh no! Campane e fischietti e altri cattivi che ci inseguono.,あーらら!鐘と笛で更に厄介な奴等を呼び込んできたな。,"오, 안 돼! 삼엄한 경비에 피할 수도 없는 선택지라니.",Oh nee! Nog meer toeters en bellen en vervelende jongens die ons achterna zitten.,"Å, nei! Flere bjeller og fløyter og ekle fyrer som jager oss.","O nie! Więcej dzwonków i gwizdków i wrednych facetów, którzy nas gonią.",Ai não! Mais bugigangas e capangas vindo atrás de nós.,,Oh nu! Mai mulți băieți răi ne urmăresc!,"О, нет! Ещё больше свистелок, перделок и плохих парней, которые за нами гонятся.",,Åh nej! Fler klockor och visselpipor och otäcka killar som jagar oss.,Olamaz! Daha fazla zil ve düdük ve bizi kovalayan kötü adamlar. +"You know, from the outside, this place looks tiny.",TXT_SUB_LOG67,MAP15: After using a big lift next to a Reaver.,,,Zvenku tohle místo vypadalo drobounké.,Udefra ser det her sted lille ud.,Von außen sieht das hier irgendwie mickrig aus.,,"Nu, ĉi tiu loko aspektis malgranda de ekstere.","O sea, este lugar se veía enano desde fuera.","O sea, este lugar se veía enano desde afuera.","Oletko muuten huomannut, että ulkopuolelta katsottuna tämä paikka näyttää tosi pieneltä.","Tu sais, de l'extérieur, cet endroit à l'air super petit.","Azt hinné az ember, hogy sokkal kisebb ez a hely a kinti kinézet alapján.","Lo sai, da fuori, questo posto sembra piccolo.",外から見ると、此処は小さいみたいね。,"궁금한 게 있는데, 왜 안에 들어가면 커지는 걸까?","Weet je, van buitenaf ziet deze plek er klein uit.","Du vet, fra utsiden ser dette stedet lite ut.","Wiesz, z zewnątrz to miejsce wygląda na malutkie.","Sabe, vendo de longe esse lugar parece minúsculo.",,"Știi, din afară, locul ăsta arată mărunt.","Знаешь, снаружи это место кажется крошечным.",,"Du vet, från utsidan ser det här stället pyttelitet ut.",Dışarıdan bakınca burası çok küçük görünüyor. +"I'm getting a new enemy reading. Don't stop and stare, just waste 'em.",TXT_SUB_LOG68,,,,Zaznamenávám nového nepřítele. Nestůj tam a znič ho!,"Jeg får en ny fjendeudlæsning. Lad være med at stoppe op og stirre, bare smadr dem.","Ich habe eine neue Feindortung. Warum wartest du, mach sie alle!",,,"Tengo señales de un nuevo enemigo. No te pares a mirar, solo cárgatelo.",,Saan uuden lukeman vihollisista. Älä siihen jää töllöttämään; listi ne!,"J'ai un ping ennemi sur mon radar. Ne t'arrète pas, flingue-les.","Új ellenséget észlelek. Ne állj meg nézelődni, hanem nyírd ki őket.","Sto ricevendo segnali di altri nemici. Non fermarti a guardare, distruggili.",,네 주변에 적이 포착됐어. 그냥 쳐다보지 말고 어떻게든 해봐.,"Ik krijg een nieuwe vijandelijke lezing. Niet stoppen en staren, maar ze gewoon verspillen.","Jeg får en ny fiende på skjermen. Ikke stopp og stir, bare skyt dem.","Dostaję nowy odczyt wroga. Nie zatrzymuj się i nie gap, po prostu je zmarnuj.","Estou recebendo sinais de um novo inimigo. Nâo fique parado olhando, mete bala neles.",,"Citesc inamici în apropiere. Nu te oprii și holba, fă-i bucăți.","Вижу врагов. Не стой столбом, мочи их!",,"Jag får en ny fiende som läser av. Stanna inte och stirra, bara döda dem.","Yeni bir düşman okuması alıyorum. Durup bakma, sadece harca onları." +"I hate these forcefields. Look for the shut-off switch, it's gotta be nearby.",TXT_SUB_LOG69,STRIFE1.WAD: MAP15,,,"Nesnáším tahle silová pole. Porozhlédni se po nějakém vypínači, měl by být nablízku.",Jeg hader disse kraftfelter. Se efter slukkontakten. Den må være i nærheden.,"Ich hasse diese Kraftfelder. Such nach einem Schalter, er müsste in der Nähe sein.",,,"Odio estos campos de fuerza. Busca el interruptor de apagado, tiene que estar cerca.",,Vihaan näitä voimakenttiä. Etsi virtakatkaisinta; sen on pakko olla jossain lähettyvillä.,"Je déteste les champs de force. Trouve leur commandes, elles ne doivent pas être loin.","Utálom ezket az erőpajzsokat. Keresd egy kikapcsoló gombot, itt kell lennie valahol.","Odio questi campi di forza. Cerca il pulsante per disattivarlo, deve essere vicino.",私はフォースフィールドが憎いわ。遮断させるスイッチが近くにあるはずだわ。,이런 방어막들 정말 싫다니까. 저걸 끌 스위치를 찾아봐. 가까이에 있을 거야.,"Ik haat deze krachtvelden. Zoek naar de afsluitschakelaar, die moet in de buurt zijn.",Jeg hater disse kraftfeltene. Se etter bryteren. Den må være i nærheten.,"Nienawidzę tych pól siłowych. Szukajcie wyłącznika, musi być w pobliżu.","Odeio esses campos de força. Procure pelo interruptor de desligar, deve estar por perto.",,"Urăsc compurile de forță. Uită-te după un buton de oprire, trebuie să fie în apropiere.","Ненавижу эти силовые поля. Поищи выключатель, он где-то неподалёку.",,"Jag hatar de här kraftfälten. Leta efter avstängningsknappen, den måste vara i närheten.","Bu güç alanlarından nefret ediyorum. Kapatma düğmesini ara, yakında olmalı." +"Ooh, very impressive. Let's blow it up!",TXT_SUB_LOG70,MAP15: After pressing the switch to reveal the computer.,,,"Ó, velmi působivé. Co to nechat vybouchnout?",Meget imponerende. Lad os sprænge den i luften!,"Oh, sehr imposant. Jag ihn hoch!",,,Muy impresionante. ¡Destruyámoslo!,Muy impresionante. ¡Vamos a destruirla!,"Oo, aika vaikuttava. Posautetaan se!","Oooh, très impressionant! Faisons tout péter!",Felettébb lenyűgöző. Robbantsuk is fel!,"Aah, molto impressionante! Facciamolo saltare in aria!",あら、見事な物ね。是非とも火薬を献上しましょう。,"오우, 정말 이쁘네! 이제 터뜨리자!","Ooh, heel indrukwekkend. Laten we hem opblazen!",Veldig imponerende. La oss sprenge den!,"Ooh, bardzo imponujące. Wysadźmy to w powietrze!","Oohh, que impressionante! Vamos detoná-lo.",,"ooh, foarte impresionant. Să-l aruncăm în aer!",Очень впечатляюще. Давай взорвём!,,"Ooh, väldigt imponerande. Vi spränger den!","Ooh, çok etkileyici. Hadi havaya uçuralım!" +"Jump on the teleporter, let's blow this pop stand.",TXT_SUB_LOG71,,,,Skoč na teleportér a odpalme tenhle stánek se zmrzlinou.,"Hop på teleporteren, lad os sprænge denne popstand.",Spring in den Teleporter und jag das Ding hoch.,,,"Súbete al teletransporte, carguémonos este tinglado.",,Loikkaa kaukosiirtimelle; häivytään tästä mestasta.,"Saute dans le téléporteur, cassons nous d'ici.","Ugrás a teleportba, és robbantsuk az égig ezt a kuplerájt.","Salta sul teletrasporto, facciamo esplodere questo mortorio.",,텔레포터를 타고 이 놀이터를 벗어나자.,"Spring op de teleporter, laten we deze popstandaard opblazen.","Hopp på teleporteren, la oss sprenge denne kiosken.","Wskakuj do teleportera, wysadźmy to stoisko z popem.","Entre no teletransportador, vamos explodir este muquifo.",,"Sari în teleportor, să aruncăm în aer totul.",Прыгай в телепорт. Пора валить отсюда.,,"Hoppa på teleportern, låt oss spränga det här popståndet.","Işınlayıcıya atla, hadi şu pop standını havaya uçuralım." "Wait, the Oracle said we would know him by his symbol of power. Are you thinking what I'm thinking?",TXT_SUB_LOG72,MAP16: Entrance.,,,"Počkat, Věštec říkal, že ho poznáme podle jeho symbolu moci. Myslíš na to samé, co já?","Vent, Oraklet sagde, at vi ville kende ham på hans kraftsymbol. Tænker du det samme som mig?","Warte, das Orakel sagte wir würden ihn an seinem Machtsymbol erkennen. Denkst du, was ich denke?",,,"Momento, el Oráculo ha dicho que lo reconoceríamos por su símbolo de poder. ¿Estás pensando lo mismo que yo?","Momento, el Oráculo dijo que lo reconoceríamos por su símbolo de poder. ¿Estás pensando lo mismo que yo?","Odota; Oraakkeli sanoi, että tunnistaisimme hänet hänen valtansa merkistä. Mietitkö samaa mitä minäkin?","Attend, l'Oracle nous a dit qu'on le reconnaitrerait de par son symbole de pouvoir.. Tu pense à la même chose que moi?","Várjunk csak, azt mondta az Orákulum, hogy felismerjük a jeléről. Te is arra gondolsz amire Én?","Aspetta, l'Oracolo aveva detto che lo avremmo riconosciuto tramite il suo simbolo del potere. Stai pensando quello che penso io?","ちょっと待って、オラクルは私達に彼のシンボルを辿ればわかると述べたか。 -貴方今、私と同じ事考えてる?","잠깐, 오라클이 전에 권력을 상징하는 문양을 따라가면 만날 수 있다고 했지? 너 나랑 같은 생각 하고 있지?","Wacht, het Orakel zei dat we hem zouden kennen aan zijn machtssymbool. Denk jij wat ik denk?","Vent, oraklet sa at vi ville kjenne ham igjen på maktsymbolet hans. Tenker du det samme som meg?","Czekaj, Wyrocznia powiedziała, że poznamy go po symbolu mocy. Myślisz o tym, co ja myślę?","Peraí, o Oráculo disse que reconheceríamos ele pelo seu símbolo de poder. Você está pensando o mesmo que eu?",,"Stai, Oracolul zicea că îl vom cunoaște după însemnul lui. Te gândeștila același lucru?","Подожди — Оракул сказал, что мы найдём его по символу власти. Ты думаешь о том же, о чём и я?",,"Bekle, Kahin onu güç sembolünden tanıyacağımızı söylemişti. Sen de benim düşündüğümü mü düşünüyorsun?" -"These guys got a decorating idea that works, and they just beat it to death.",TXT_SUB_LOG73,,,,Tihle lidi dostali dobrý nápad na výzdobu a pak ho zadupali do země.,"Disse fyre har en dekorativ idé, som virker, og de slår den bare ihjel.","Diese Typen haben ein Design das funktioniert, aber sie haben es total übertrieben.",,,"Estos tipos tuvieron una idea de decoración que funciona, y la han matado a palos.",,"Näille tyypeille välähti yksi toimiva sisustusidea, ja he vain kuluttivat sen loppuun.",Cest types avaient une super bonne idée déco et ils ont fait n'importe quoi avec.,"Ezeknek az embereknek volt egy jó dekorációs ötlete, csak némileg túlzásba vitték.","Questi qua hanno avuto una buona idea di come decorare, e poi ci sono andati ben troppo oltre.",,"저놈들은 도움이 되는 생각을 가지고 있기는 한데, 다 쓸데없이 망치고 있어.","Deze jongens hebben een decoratief idee dat werkt, en ze hebben het gewoon doodgeslagen.","De har en dekorasjonsidé som funker, og så slår de den i hjel.","Ci kolesie mają pomysł na wystrój, który działa, a oni go po prostu zepsuli na śmierć.",Esses caras tinham uma idéia de decoração que funcionava e depois mandaram tudo pro saco.,,Tipii ăștia au o idee despre decorații în aplicare.,"У этих ребят была отличная идея декора, но они загубили её на корню.",,Bu adamların işe yarayan bir dekorasyon fikri var ve onu öldüresiye dövüyorlar. +貴方今、私と同じ事考えてる?","잠깐, 오라클이 전에 권력을 상징하는 문양을 따라가면 만날 수 있다고 했지? 너 나랑 같은 생각 하고 있지?","Wacht, het Orakel zei dat we hem zouden kennen aan zijn machtssymbool. Denk jij wat ik denk?","Vent, oraklet sa at vi ville kjenne ham igjen på maktsymbolet hans. Tenker du det samme som meg?","Czekaj, Wyrocznia powiedziała, że poznamy go po symbolu mocy. Myślisz o tym, co ja myślę?","Peraí, o Oráculo disse que reconheceríamos ele pelo seu símbolo de poder. Você está pensando o mesmo que eu?",,"Stai, Oracolul zicea că îl vom cunoaște după însemnul lui. Te gândeștila același lucru?","Подожди — Оракул сказал, что мы найдём его по символу власти. Ты думаешь о том же, о чём и я?",,"Vänta, Oraklet sa att vi skulle känna igen honom på hans kraftsymbol. Tänker du samma sak som jag?","Bekle, Kahin onu güç sembolünden tanıyacağımızı söylemişti. Sen de benim düşündüğümü mü düşünüyorsun?" +"These guys got a decorating idea that works, and they just beat it to death.",TXT_SUB_LOG73,,,,Tihle lidi dostali dobrý nápad na výzdobu a pak ho zadupali do země.,"Disse fyre har en dekorativ idé, som virker, og de slår den bare ihjel.","Diese Typen haben ein Design das funktioniert, aber sie haben es total übertrieben.",,,"Estos tipos tuvieron una idea de decoración que funciona, y la han matado a palos.",,"Näille tyypeille välähti yksi toimiva sisustusidea, ja he vain kuluttivat sen loppuun.",Cest types avaient une super bonne idée déco et ils ont fait n'importe quoi avec.,"Ezeknek az embereknek volt egy jó dekorációs ötlete, csak némileg túlzásba vitték.","Questi qua hanno avuto una buona idea di come decorare, e poi ci sono andati ben troppo oltre.",,"저놈들은 도움이 되는 생각을 가지고 있기는 한데, 다 쓸데없이 망치고 있어.","Deze jongens hebben een decoratief idee dat werkt, en ze hebben het gewoon doodgeslagen.","De har en dekorasjonsidé som funker, og så slår de den i hjel.","Ci kolesie mają pomysł na wystrój, który działa, a oni go po prostu zepsuli na śmierć.",Esses caras tinham uma idéia de decoração que funcionava e depois mandaram tudo pro saco.,,Tipii ăștia au o idee despre decorații în aplicare.,"У этих ребят была отличная идея декора, но они загубили её на корню.",,"De här killarna har en dekorationsidé som fungerar, och de bara slår ihjäl den.",Bu adamların işe yarayan bir dekorasyon fikri var ve onu öldüresiye dövüyorlar. Did you see that weird spectre that came out of the Bishop's body? Where have I seen that before?,TXT_SUB_LOG74,"STRIFE1.WAD: MAP16 (After defeating the Bishop)",,,"Viděl jsi ten divný přízrak, který vyšel z Biskupova těla? Kde jsem ho jen předtím viděla?","Så du det underlige spøgelse, der kom ud af biskoppens krop? Hvor har jeg set det før?","Hast du diesen seltsamen Schemen gesehen, der aus seinem Körper herauskam? Wo haben wir das schonmal gesehen?",,,¿Viste ese extraño espectro que salió del cuerpo del Obispo? ¿Donde lo he visto antes?,,"Näitkö tuon oudon aaveen, joka nousi Piispan ruumiista? Missä olen nähnyt sen aiemmin?",Tu a vu ce spectre bizarre qui est sorti du corps de l'évèque? On a pas vu ça quelque part avant?,Láttad azt a fura szellemet ami kijött a Püspök teteméből? Hol láttam én már azt?,Hai visto quello strano spettro che è uscito dal corpo del Vescovo? Dove l'ho già visto prima?,"ビショップの体から出てきたあの奇妙な幽体を見た? -以前に何処かで見た気がするけど?",그나저나 비숍 몸에서 튀어나왔던 검은 물체 봤어? 전에 본 적이 있나?,Zag je dat rare spook dat uit het lichaam van de bisschop kwam? Waar heb ik dat eerder gezien?,Så du det rare spøkelset som kom ut av biskopens kropp? Hvor har jeg sett det før?,"Widziałeś to dziwne widmo, które wyszło z ciała biskupa? Gdzie ja to już widziałem?",Você viu aquele espectro estranho que saiu do corpo do BIspo? Onde foi que eu já vi isso antes?,,Ai văzut acel spectru ieșind din Episcop? Unde am mai văzut asta?,"Видел тот странный фантом, вышедший из тела Епископа? Где я могла видеть такое раньше?",,Piskoposun bedeninden çıkan o garip hayaleti gördün mü? Bunu daha önce nerede görmüştüm? -Judgment call time. Now that we got two pieces we might wanna return to base. What does your instinct tell you?,TXT_SUB_LOG75,,,,"Čas se rozhodnout. Teď, když máme dva díly, bychom se možná měli vrátit na základnu. Co ti říká intuice?","Det er tid til at dømme. Nu hvor vi har to stykker, bør vi måske vende tilbage til basen. Hvad siger dit instinkt dig?","Zeit für eine Gewissensentscheidung. Jetzt wo wir zwei Teile haben, sollten wir zur Basis zurückkehren. Was denkst du?",,,Hora del Juicio. Ahora que tienes dos piezas podríamos regresar a la base. ¿Qué te dice tú instinto?,,"Aika tehdä päätös: Nyt, kun meillä on kaksi osasta, saattaisimme haluta palata tukikohtaan. Mitä vaistosi sanoo?","C'est l'heure du jugement, on a deux pièce, il est temps de retourner à la base. Que te dit ton instinct?","Kupaktanács. Most, hogy megszereztün két darabot, vissza is térhetünk a bázisba. mit mond az ösztönöd?",È l'ora di decidere. Adesso che abbiamo due pezzi sarebbe il caso di tornare alla base. Cosa dice il tuo istinto?,,심판의 시간이야. 시질 두 조각을 모았으니 본부로 돌아가자. 이제 너의 본능은 무슨 해답을 내놓을까?,"Oordeel roep tijd. Nu we twee stukken hebben, willen we misschien terug naar de basis. Wat zegt je instinct je?","Tid for domsavsigelse. Nå som vi har to stykker, bør vi kanskje dra tilbake til basen. Hva sier instinktet ditt?","Czas na osąd. Teraz, kiedy mamy dwa kawałki, możemy chcieć wrócić do bazy. Co mówi ci twój instynkt?","Hora do julgamento. Agora que temos duas peças, talvez a gente queira voltar pra base. O que o seu instinto diz?",,Timpul să judecăm. Acum că avem două piese ne putem întoarce la bază. Ce-ți zice instinctul?,"Время решать. Теперь, когда у нас есть две части, мы можем вернуться на базу. Что твоя интуиция подсказывает тебе?",,Karar verme zamanı. Elimizde iki parça olduğuna göre üsse dönmek isteyebiliriz. İçgüdülerin sana ne söylüyor? +以前に何処かで見た気がするけど?",그나저나 비숍 몸에서 튀어나왔던 검은 물체 봤어? 전에 본 적이 있나?,Zag je dat rare spook dat uit het lichaam van de bisschop kwam? Waar heb ik dat eerder gezien?,Så du det rare spøkelset som kom ut av biskopens kropp? Hvor har jeg sett det før?,"Widziałeś to dziwne widmo, które wyszło z ciała biskupa? Gdzie ja to już widziałem?",Você viu aquele espectro estranho que saiu do corpo do BIspo? Onde foi que eu já vi isso antes?,,Ai văzut acel spectru ieșind din Episcop? Unde am mai văzut asta?,"Видел тот странный фантом, вышедший из тела Епископа? Где я могла видеть такое раньше?",,Såg du det konstiga spöket som kom ut ur biskopens kropp? Var har jag sett det förut?,Piskoposun bedeninden çıkan o garip hayaleti gördün mü? Bunu daha önce nerede görmüştüm? +Judgment call time. Now that we got two pieces we might wanna return to base. What does your instinct tell you?,TXT_SUB_LOG75,,,,"Čas se rozhodnout. Teď, když máme dva díly, bychom se možná měli vrátit na základnu. Co ti říká intuice?","Det er tid til at dømme. Nu hvor vi har to stykker, bør vi måske vende tilbage til basen. Hvad siger dit instinkt dig?","Zeit für eine Gewissensentscheidung. Jetzt wo wir zwei Teile haben, sollten wir zur Basis zurückkehren. Was denkst du?",,,Hora del Juicio. Ahora que tienes dos piezas podríamos regresar a la base. ¿Qué te dice tú instinto?,,"Aika tehdä päätös: Nyt, kun meillä on kaksi osasta, saattaisimme haluta palata tukikohtaan. Mitä vaistosi sanoo?","C'est l'heure du jugement, on a deux pièce, il est temps de retourner à la base. Que te dit ton instinct?","Kupaktanács. Most, hogy megszereztün két darabot, vissza is térhetünk a bázisba. mit mond az ösztönöd?",È l'ora di decidere. Adesso che abbiamo due pezzi sarebbe il caso di tornare alla base. Cosa dice il tuo istinto?,,심판의 시간이야. 시질 두 조각을 모았으니 본부로 돌아가자. 이제 너의 본능은 무슨 해답을 내놓을까?,"Oordeel roep tijd. Nu we twee stukken hebben, willen we misschien terug naar de basis. Wat zegt je instinct je?","Tid for domsavsigelse. Nå som vi har to stykker, bør vi kanskje dra tilbake til basen. Hva sier instinktet ditt?","Czas na osąd. Teraz, kiedy mamy dwa kawałki, możemy chcieć wrócić do bazy. Co mówi ci twój instynkt?","Hora do julgamento. Agora que temos duas peças, talvez a gente queira voltar pra base. O que o seu instinto diz?",,Timpul să judecăm. Acum că avem două piese ne putem întoarce la bază. Ce-ți zice instinctul?,"Время решать. Теперь, когда у нас есть две части, мы можем вернуться на базу. Что твоя интуиция подсказывает тебе?",,Det är dags att döma. Nu när vi har två delar kanske vi borde återvända till basen. Vad säger din instinkt dig?,Karar verme zamanı. Elimizde iki parça olduğuna göre üsse dönmek isteyebiliriz. İçgüdülerin sana ne söylüyor? "I have a report that the spectral energy we found near the Bishop is also present by the Oracle, let's be careful.",TXT_SUB_LOG76,STRIFE1.WAD: MAP11,,,"Mám hlášení, že stejná přízračná energie, kterou jsme našli u Biskupa, se nachází také u Věštce. Měli bychom být opatrní.","Jeg har en rapport om, at den spektrale energi, vi fandt i nærheden af biskoppen, også er til stede ved oraklet, så lad os være forsigtige.","Ich habe einen Report, dass die spektrale Energie, die wir beim Bischof gefunden haben, auch beim Orakel präsent ist. Sei vorsichtig.",,,"Tengo un informe de que la energía espectral que encontramos cerca del Obispo también está presente junto al Oráculo, vayamos con cuidado",,"Sain tiedon, että aave-energiaa, jota löysimme Piispan läheltä, on läsnä myös Oraakkelin luona. Ollaan varovaisia.",J'ai un rapport que l'énergie spectrale que l'on a trouvé près de l'évèque est aussi près de l'Oracle. Faisons attention.,Egy beszámoló szerint az Orákulum körülötti lelki színkép megegyezik a Püspökével. Legyünk tehát óvatosak.,"Ho qua un rapporto che ci informa che l'energia spettrale che abbiamo trovato vicino il Vescovo è anche presente vicino l'Oracolo, dobbiamo essere attenti.","ビショップにもあったスペクトラルエネルギーがオラクルにも宿っているという -報告があるわ、気を付けて。","지금 보고를 받았는데, 비숍을 죽인 뒤에 나온 혼령의 기운이 오라클에게도 있데. 조심하자.","Ik heb een verslag dat de spectrale energie die we in de buurt van de bisschop vonden ook aanwezig is bij het Orakel, laten we voorzichtig zijn.","Jeg har en rapport om at den spektrale energien vi fant nær biskopen også er til stede ved oraklet, la oss være forsiktige.","Mam raport, że energia widmowa, którą znaleźliśmy przy Bishopie, jest również obecna przy Wyroczni. Bądźmy ostrożni.",Tenho relatos de que a energia espectral que encontramos perto do Bispo também está presente pelo Oráculo. Vamos com cuidado.,,"Am un raport care spune că energia spectrală a Episcopului e aceeași de pe Oracol, să fim atenți.","Мне доложили, что от Оракула исходит та же энергия, что и от того фантома, которого мы видели у Епископа. Будь начеку!",,"Piskopos'un yanında bulduğumuz spektral enerjinin Kahin'de de olduğuna dair bir rapor aldım, dikkatli olalım." -Macil? Part of this mess? I don't know what to think. I hope you make the right decision.,TXT_SUB_LOG77,,,,"Macil? Částí tohohle bordelu? Nevím, co si o tom mám myslet. Doufám, že se rozhodneš správně.","Macil? En del af dette rod? Jeg ved ikke, hvad jeg skal tro. Jeg håber, du træffer den rigtige beslutning.","Macil? Ein Teil dieser Schweinerei? Ich weiß nicht, was ich denken soll. Hoffentlich triffst du die richtige Entscheidung.",,,¿Macil? ¿Parte de este lío? No sé que pensar. Espero que tomes la decisión correcta.,,"Macil osa tätä sotkua? En tiedä, mitä ajatella. Toivon, että teet oikean päätöksen.","Macil fait partie de tout ce bordel? Je ne sais pas quoi penser, j'espère que tu feras le bon choix..",Macil? Benne lenne ebben a zűrzavarban? nem tudom mit higgyek. Remélem a jó döntést fogod hozni.,Macil? Parte di questa follia? Non so cosa pensare. Spero farai la decisione giusta.,,마실? 이 문제의 장본인 중 한 명이라고? 정말이지 모르겠어. 부디 현명한 판단을 내리길 바래.,Macil? Een deel van deze puinhoop? Ik weet niet wat ik moet denken. Ik hoop dat je de juiste beslissing neemt.,Macil? En del av dette rotet? Jeg vet ikke hva jeg skal tro. Jeg håper du tar den rette avgjørelsen.,"Macil? Część tego bałaganu? Nie wiem, co myśleć. Mam nadzieję, że podejmiesz właściwą decyzję.",O Macil? Fazendo parte dessa confusão toda? Eu não sei o que pensar. Espero que você tome a decisão certa.,,Macil? Parte la dezastrul ăsta? Nu știu ce să cred. Sper să iei decizia bună.,"Мэйсил? Замешан в этом дерьме? Я даже не знаю, что и думать. Я надеюсь, ты сделаешь правильный выбор.",,Macil mi? Bu karmaşanın bir parçası mı? Ne düşüneceğimi bilmiyorum. Umarım doğru kararı verirsiniz. -"Do I trust Macil, who has risked his life for the Front, or some ugly spook? I don't know. But you I trust.",TXT_SUB_LOG78,,,,"Mám věřit Macilovi, který riskoval svůj život kvůli Frontě, nebo nějakému ošklivovi? Já nevím. Ale tobě věřím.","Skal jeg stole på Macil, som har risikeret sit liv for fronten, eller på en grim spøgelse? Jeg ved det ikke. Men jeg stoler på dig.","Ob ich Macil vertraue, der sein Leben für die Front riskiert hat, oder einer hässlichen Schreckgestalt? Ich weiß nicht - aber dir vertraue ich. ",,,"¿Confío en Macil, que ha arriesgado su vida por el Frente, o en un espectro feo? No lo sé. Pero en ti sí confío.",,"Luotanko Maciliin, joka on antanut henkensä alttiiksi Rintamalle, vai johonkin rumaan kummitukseen? En tiedä. Mutta sinuun minä luotan.","Et ce que je fais confiance à Macil qui a risqué sa vie pour le Front, où un affreux jojo? J'en sais rien, mais je fais confiance à toi.","Macilnak hiszek aki kockára tette az életét a Frontért, vagy egy semmirekellőnek? Nem is tudom...de neked biztosan hiszek.","Di chi mi posso fidare, di Macil, che ha rischiato la vita per il Fronte, o di questo essere spettrale? Non lo so. Ma di te mi fido.",,"마실은 프론트를 위해 싸워온 사람이라 의심할 수가 없어. 저 못난이가 거짓말을 하는 걸까? 모르지만, 난 너 만을 믿어.","Vertrouw ik Macil, die zijn leven heeft geriskeerd voor het Front, of een lelijke spook? Ik weet het niet. Maar jij vertrouw ik.","Stoler jeg på Macil, som har risikert livet for Fronten, eller et stygt spøkelse? Jeg vet ikke. Men deg stoler jeg på.","Czy ufać Macilowi, który ryzykował życie dla Frontu, czy jakiemuś brzydkiemu upiorowi? Nie wiem. Ale tobie ufam.","Se eu confio no Macil, que arriscou a sua vida pela Frente, ou num fantasma horroroso? Eu não sei, mas eu você eu confio.",,"Dacă îl cred pe Macil, care și-a riscat viața pentru Front, sau un tip în armură? Nu știu. Dar în tine, cred.","Кому верить: Мэйсилу, который не щадил своей жизни ради Сопротивления, или какому-то уродливому пугалу? Не знаю. Но я доверяю тебе. ",,"Cephe için hayatını riske atan Macil'e mi güveneyim, yoksa çirkin bir hortlağa mı? Bilmiyorum. Ama sana güveniyorum." +報告があるわ、気を付けて。","지금 보고를 받았는데, 비숍을 죽인 뒤에 나온 혼령의 기운이 오라클에게도 있데. 조심하자.","Ik heb een verslag dat de spectrale energie die we in de buurt van de bisschop vonden ook aanwezig is bij het Orakel, laten we voorzichtig zijn.","Jeg har en rapport om at den spektrale energien vi fant nær biskopen også er til stede ved oraklet, la oss være forsiktige.","Mam raport, że energia widmowa, którą znaleźliśmy przy Bishopie, jest również obecna przy Wyroczni. Bądźmy ostrożni.",Tenho relatos de que a energia espectral que encontramos perto do Bispo também está presente pelo Oráculo. Vamos com cuidado.,,"Am un raport care spune că energia spectrală a Episcopului e aceeași de pe Oracol, să fim atenți.","Мне доложили, что от Оракула исходит та же энергия, что и от того фантома, которого мы видели у Епископа. Будь начеку!",,"Jag har en rapport om att den spektrala energin som vi hittade nära biskopen också finns hos oraklet, vi måste vara försiktiga.","Piskopos'un yanında bulduğumuz spektral enerjinin Kahin'de de olduğuna dair bir rapor aldım, dikkatli olalım." +Macil? Part of this mess? I don't know what to think. I hope you make the right decision.,TXT_SUB_LOG77,,,,"Macil? Částí tohohle bordelu? Nevím, co si o tom mám myslet. Doufám, že se rozhodneš správně.","Macil? En del af dette rod? Jeg ved ikke, hvad jeg skal tro. Jeg håber, du træffer den rigtige beslutning.","Macil? Ein Teil dieser Schweinerei? Ich weiß nicht, was ich denken soll. Hoffentlich triffst du die richtige Entscheidung.",,,¿Macil? ¿Parte de este lío? No sé que pensar. Espero que tomes la decisión correcta.,,"Macil osa tätä sotkua? En tiedä, mitä ajatella. Toivon, että teet oikean päätöksen.","Macil fait partie de tout ce bordel? Je ne sais pas quoi penser, j'espère que tu feras le bon choix..",Macil? Benne lenne ebben a zűrzavarban? nem tudom mit higgyek. Remélem a jó döntést fogod hozni.,Macil? Parte di questa follia? Non so cosa pensare. Spero farai la decisione giusta.,,마실? 이 문제의 장본인 중 한 명이라고? 정말이지 모르겠어. 부디 현명한 판단을 내리길 바래.,Macil? Een deel van deze puinhoop? Ik weet niet wat ik moet denken. Ik hoop dat je de juiste beslissing neemt.,Macil? En del av dette rotet? Jeg vet ikke hva jeg skal tro. Jeg håper du tar den rette avgjørelsen.,"Macil? Część tego bałaganu? Nie wiem, co myśleć. Mam nadzieję, że podejmiesz właściwą decyzję.",O Macil? Fazendo parte dessa confusão toda? Eu não sei o que pensar. Espero que você tome a decisão certa.,,Macil? Parte la dezastrul ăsta? Nu știu ce să cred. Sper să iei decizia bună.,"Мэйсил? Замешан в этом дерьме? Я даже не знаю, что и думать. Я надеюсь, ты сделаешь правильный выбор.",,Macil? En del av den här röran? Jag vet inte vad jag ska tro. Jag hoppas att du fattar rätt beslut.,Macil mi? Bu karmaşanın bir parçası mı? Ne düşüneceğimi bilmiyorum. Umarım doğru kararı verirsiniz. +"Do I trust Macil, who has risked his life for the Front, or some ugly spook? I don't know. But you I trust.",TXT_SUB_LOG78,,,,"Mám věřit Macilovi, který riskoval svůj život kvůli Frontě, nebo nějakému ošklivovi? Já nevím. Ale tobě věřím.","Skal jeg stole på Macil, som har risikeret sit liv for fronten, eller på en grim spøgelse? Jeg ved det ikke. Men jeg stoler på dig.","Ob ich Macil vertraue, der sein Leben für die Front riskiert hat, oder einer hässlichen Schreckgestalt? Ich weiß nicht - aber dir vertraue ich. ",,,"¿Confío en Macil, que ha arriesgado su vida por el Frente, o en un espectro feo? No lo sé. Pero en ti sí confío.",,"Luotanko Maciliin, joka on antanut henkensä alttiiksi Rintamalle, vai johonkin rumaan kummitukseen? En tiedä. Mutta sinuun minä luotan.","Et ce que je fais confiance à Macil qui a risqué sa vie pour le Front, où un affreux jojo? J'en sais rien, mais je fais confiance à toi.","Macilnak hiszek aki kockára tette az életét a Frontért, vagy egy semmirekellőnek? Nem is tudom...de neked biztosan hiszek.","Di chi mi posso fidare, di Macil, che ha rischiato la vita per il Fronte, o di questo essere spettrale? Non lo so. Ma di te mi fido.",,"마실은 프론트를 위해 싸워온 사람이라 의심할 수가 없어. 저 못난이가 거짓말을 하는 걸까? 모르지만, 난 너 만을 믿어.","Vertrouw ik Macil, die zijn leven heeft geriskeerd voor het Front, of een lelijke spook? Ik weet het niet. Maar jij vertrouw ik.","Stoler jeg på Macil, som har risikert livet for Fronten, eller et stygt spøkelse? Jeg vet ikke. Men deg stoler jeg på.","Czy ufać Macilowi, który ryzykował życie dla Frontu, czy jakiemuś brzydkiemu upiorowi? Nie wiem. Ale tobie ufam.","Se eu confio no Macil, que arriscou a sua vida pela Frente, ou num fantasma horroroso? Eu não sei, mas eu você eu confio.",,"Dacă îl cred pe Macil, care și-a riscat viața pentru Front, sau un tip în armură? Nu știu. Dar în tine, cred.","Кому верить: Мэйсилу, который не щадил своей жизни ради Сопротивления, или какому-то уродливому пугалу? Не знаю. Но я доверяю тебе. ",,"Ska jag lita på Macil, som har riskerat sitt liv för fronten, eller på något fult spöke? Jag vet inte. Men dig litar jag på.","Cephe için hayatını riske atan Macil'e mi güveneyim, yoksa çirkin bir hortlağa mı? Bilmiyorum. Ama sana güveniyorum." Richter has taken over command of our forces. It looks like Macil has been deceiving us all along. His true allegiance was to the Order. What a snake.,TXT_SUB_LOG79,"STRIFE1.WAD: MAP10 (After killing Macil without having destroyed the converter in MAP24)",,,"Richter převzal velení našich sil. Zdá se, že nás Macil celou dobu klamal. Ve skutečnosti byl věrný Řádu. Slizák jeden.","Richter har overtaget kommandoen over vores styrker. Det ser ud til, at Macil har bedraget os hele tiden. Hans sande loyalitet var over for Ordenen. Sikke en slange.","Richter hat das Kommando über unsere Truppen übernommen. Es sieh aus, als ob Macil uns alle hintergangen hat und die ganze Zeit für den Orden arbeitete. Was für eine Ratte.",,,Richter ha tomado el mando de nuestras fuerzas. Parece que Macil nos ha estado engañando todo este tiempo. Su verdadera lealtad era a la Orden. Menuda serpiente.,,"Richter on ottanut joukkomme komentoonsa. Näyttää siltä, että Macil on pettänyt meitä alusta alkaen. Hänen todellinen uskollisuutensa on ollut Veljeskunnalle; mikä käärme.","Richter à pris le contrôle de nos forces. Il semble que Macil nous a trompé tout ce temps. Sa vraie allégiance appartenait à l'Ordre, quel ordure..",Richter átvette az irányítást az egységeink felett. Úgy néz ki Macil mindvégig átvert minket. Igazából a Rend embere volt. Micsoda álnok kígyó.,Richter ha assunto il comando delle nostre forze. Sembra che Macil ci avesse ingannato fin dall'inizio. In realtà è sempre stato alleato con l'Ordine. Che serpente.,"リヒターが指揮官の任を引き継いだ。マシルはずっと私達を騙していたなんて。 -あの人がオーダーに真の忠誠を誓っていたなんて、とんだ蛇神憑きだわ。",릭터가 저항군의 새로운 지도자가 될 거야. 내 생각엔 마실이 오랫동안 우리들을 속인 것 같아... 뱀 같은 자식.,Richter heeft het bevel over onze troepen overgenomen. Het lijkt erop dat Macil ons de hele tijd heeft bedrogen. Zijn ware trouw was aan de Orde. Wat een slang.,Richter har overtatt kommandoen over styrkene våre. Det ser ut til at Macil har lurt oss hele tiden. Hans sanne lojalitet var til Ordenen. For en slange.,"Richter przejął dowodzenie nad naszymi siłami. Wygląda na to, że Macil cały czas nas zwodził. Jego prawdziwa wierność była dla Zakonu. Co za wąż.",O Richter assumiu o comando de nossas forças. Parece que o Macil nos enganou esse tempo todo. Sua verdadeira lealdade era à Ordem. Que traíra!,,Richter a preluat controlul asupra forțelor noastre. Se pare că Macil ne-a înșelat în tot acest timp. Aderărata lui loialitate era față de Ordin. Ce șarpe.,"Рихтер принял на себя командование нашими силами. Похоже, что Мэйсил обманывал всех нас с самого начала. На самом деле он был предан Ордену. Подлец.",,Richter kuvvetlerimizin komutasını devraldı. Görünüşe göre Macil başından beri bizi kandırıyormuş. Onun gerçek bağlılığı Tarikat'a imiş. Ne yılan ama. -Damned impressing entranceway. But what we are searching for is on another level. Head down.,TXT_SUB_LOG80,STRIFE1.WAD: MAP26,,,"Zatraceně působivý vchod. Ale to, co hledáme, je na jiném patře. Jdi dolů.","Forbandede imponerende indgang. Men det, vi leder efter, er på et andet niveau. Hovedet nedad.",Verdammt eindrucksvoller Eingang. Aber was wir suchen ist woanders. Lass uns runtergehen.,,,Una entrada tremendamente impresionante. Pero lo que buscamos está en otro nivel. Ve abajo.,,Pahuksen vaikuttava sisäänkäynti. Mutta etsimämme on eri kerroksessa. Suuntaa alas.,"Une entrée sérieusement impressionante. Ce que l'on cherche est à un autre étage, descends.","Elég menő bejárat. Azonban másik emeleten van, amit keresünk. Irány lefelé.",Come ingresso è davvero notevole. Ma quello che cerchiamo si trova su un altro piano. Vai giù.,威風堂々とした玄関ね。でも私達が調べるのは別の階よ。慎重にね。,또 전형적인 멋진 입구네. 하지만 우리가 찾는 것은 또 다른 구역에 있어. 밑으로 향해.,Vervloekt indrukwekkende toegangsweg. Maar wat we zoeken is op een ander niveau. Hoofd naar beneden.,Imponerende inngangsparti. Men det vi leter etter er på et annet nivå. Ned med hodet.,"Cholernie imponujące wejście. Ale to, czego szukamy, jest na innym poziomie. Głowa w dół.",Que entrada bem impressionante. Mas o que procuramos está em outro nível. Desça.,,Impresionantă intrare. Dar ceea ce căutăm e la alt nivel. Mergi jos.,Этот чёртов фасад впечатляет! Но нам нужно на другой этаж. Не высовывайся!,,Etkileyici bir giriş yolu. Ama aradığımız şey başka bir seviyede. Baş aşağı. -What a shame. Our technology is being wasted on torture instead of life.,TXT_SUB_LOG81,STRIFE1.WAD: MAP24,,,Taková škoda. Naše technologie je plýtvána na mučení místo života.,Sikke en skam. Vores teknologi bliver spildt på tortur i stedet for liv.,Was für eine Schande. Unsere Technologie wird für Folter anstatt für Leben verschwendet.,,,Que pena. Nuestra tecnología se está desperdiciando en tortura en vez de vida.,,"Mikä häpeä: Teknologiaamme tuhlataan kidutukseen, sen sijaan että parantaisimme elämää.","C'est tellement dommage. Notre technologie est gâchée, utilisée pour la torture plutôt que sauver des vies.",Milyen kár. A technológiánkat kínzásra pazarolják az élet helyett.,Che peccato. La nostra tecnologia viene sprecata per la tortura invece che per la vita.,残念だな。我々の技術が拷問の為だけに浪費されるとは。,비극적이야. 우리 기술이 생명을 살리는 데 쓰이기는 커녕 고문하는 데 쓰이고 있잖아.,Wat jammer. Onze technologie wordt verspild aan marteling in plaats van leven.,For en skam. Teknologien vår kastes bort på tortur i stedet for liv.,Co za wstyd. Nasza technologia jest marnowana na tortury zamiast na życie.,É uma pena. Nossa tecnologia sendo desperdiçada com tortura ao invés de salvar vidas.,,Ce rușine. Tehnologia noastră e risipită pentru tortură în loc de a crea viață.,"Какой кошмар. Наша технология используется для пыток, а не для жизни.",,Ne utanç verici. Teknolojimiz yaşam yerine işkence için harcanıyor. -"Being vain as hell, they mark their temples with big banners.",TXT_SUB_LOG82,STRIFE1.WAD: MAP21,,,"S takovou ješitností není divu, že si své chrámy značí velkými prapory.","Fordi de er forfængelige som helvede, markerer de deres templer med store bannere.","Eitel wie sie sind, markieren sie ihre Tempel mit riesigen Bannern.",,,"Siendo tan malditamente engreídos, marcan sus templos con grandes estandartes.",,"Läpeensä turhamaisia kun ovat, he vuoraavat temppelinsä suurin tunnuslipuin.","Avec leur orgeuil à la noix, je me ne doutais pas un instant qu'ils allaient mettre d'énormes bannières partout.","Miután felettébb hiúk, ezért hatalmas zászlókkal díszítik a templomaikat.","Essendo vanitosi come pochi, marchiano i loro templi con degli stemmi.",うぬぼれが酷いな、あいつらの寺院はデカいバナーが目に付く。,"고통을 더하자면, 자기네 신전에 커다란 기를 세웠어.","Tevergeefs als de hel, markeren ze hun tempels met grote spandoeken.","Forfengelige som faen, markerer de templene sine med store bannere.","Próżni jak diabli, oznaczają swoje świątynie wielkimi transparentami.",Esses caras são vaidosos pra caramba. Eles marcam os seus templos com esses grandes estandartes.,,"Vanitate la maxim, își marchează templele cu steaguri imense.","Они спесивы до ужаса, раз украшают свои храмы большими флагами.",,"Cehennem kadar kibirli oldukları için, tapınaklarını büyük pankartlarla işaretliyorlar." +あの人がオーダーに真の忠誠を誓っていたなんて、とんだ蛇神憑きだわ。",릭터가 저항군의 새로운 지도자가 될 거야. 내 생각엔 마실이 오랫동안 우리들을 속인 것 같아... 뱀 같은 자식.,Richter heeft het bevel over onze troepen overgenomen. Het lijkt erop dat Macil ons de hele tijd heeft bedrogen. Zijn ware trouw was aan de Orde. Wat een slang.,Richter har overtatt kommandoen over styrkene våre. Det ser ut til at Macil har lurt oss hele tiden. Hans sanne lojalitet var til Ordenen. For en slange.,"Richter przejął dowodzenie nad naszymi siłami. Wygląda na to, że Macil cały czas nas zwodził. Jego prawdziwa wierność była dla Zakonu. Co za wąż.",O Richter assumiu o comando de nossas forças. Parece que o Macil nos enganou esse tempo todo. Sua verdadeira lealdade era à Ordem. Que traíra!,,Richter a preluat controlul asupra forțelor noastre. Se pare că Macil ne-a înșelat în tot acest timp. Aderărata lui loialitate era față de Ordin. Ce șarpe.,"Рихтер принял на себя командование нашими силами. Похоже, что Мэйсил обманывал всех нас с самого начала. На самом деле он был предан Ордену. Подлец.",,Richter har tagit över befälet över våra styrkor. Det verkar som om Macil har lurat oss hela tiden. Hans sanna lojalitet var till Orden. Vilken orm.,Richter kuvvetlerimizin komutasını devraldı. Görünüşe göre Macil başından beri bizi kandırıyormuş. Onun gerçek bağlılığı Tarikat'a imiş. Ne yılan ama. +Damned impressing entranceway. But what we are searching for is on another level. Head down.,TXT_SUB_LOG80,STRIFE1.WAD: MAP26,,,"Zatraceně působivý vchod. Ale to, co hledáme, je na jiném patře. Jdi dolů.","Forbandede imponerende indgang. Men det, vi leder efter, er på et andet niveau. Hovedet nedad.",Verdammt eindrucksvoller Eingang. Aber was wir suchen ist woanders. Lass uns runtergehen.,,,Una entrada tremendamente impresionante. Pero lo que buscamos está en otro nivel. Ve abajo.,,Pahuksen vaikuttava sisäänkäynti. Mutta etsimämme on eri kerroksessa. Suuntaa alas.,"Une entrée sérieusement impressionante. Ce que l'on cherche est à un autre étage, descends.","Elég menő bejárat. Azonban másik emeleten van, amit keresünk. Irány lefelé.",Come ingresso è davvero notevole. Ma quello che cerchiamo si trova su un altro piano. Vai giù.,威風堂々とした玄関ね。でも私達が調べるのは別の階よ。慎重にね。,또 전형적인 멋진 입구네. 하지만 우리가 찾는 것은 또 다른 구역에 있어. 밑으로 향해.,Vervloekt indrukwekkende toegangsweg. Maar wat we zoeken is op een ander niveau. Hoofd naar beneden.,Imponerende inngangsparti. Men det vi leter etter er på et annet nivå. Ned med hodet.,"Cholernie imponujące wejście. Ale to, czego szukamy, jest na innym poziomie. Głowa w dół.",Que entrada bem impressionante. Mas o que procuramos está em outro nível. Desça.,,Impresionantă intrare. Dar ceea ce căutăm e la alt nivel. Mergi jos.,Этот чёртов фасад впечатляет! Но нам нужно на другой этаж. Не высовывайся!,,Jävligt imponerande entré. Men det vi söker är på en annan nivå. Huvudet neråt.,Etkileyici bir giriş yolu. Ama aradığımız şey başka bir seviyede. Baş aşağı. +What a shame. Our technology is being wasted on torture instead of life.,TXT_SUB_LOG81,STRIFE1.WAD: MAP24,,,Taková škoda. Naše technologie je plýtvána na mučení místo života.,Sikke en skam. Vores teknologi bliver spildt på tortur i stedet for liv.,Was für eine Schande. Unsere Technologie wird für Folter anstatt für Leben verschwendet.,,,Que pena. Nuestra tecnología se está desperdiciando en tortura en vez de vida.,,"Mikä häpeä: Teknologiaamme tuhlataan kidutukseen, sen sijaan että parantaisimme elämää.","C'est tellement dommage. Notre technologie est gâchée, utilisée pour la torture plutôt que sauver des vies.",Milyen kár. A technológiánkat kínzásra pazarolják az élet helyett.,Che peccato. La nostra tecnologia viene sprecata per la tortura invece che per la vita.,残念だな。我々の技術が拷問の為だけに浪費されるとは。,비극적이야. 우리 기술이 생명을 살리는 데 쓰이기는 커녕 고문하는 데 쓰이고 있잖아.,Wat jammer. Onze technologie wordt verspild aan marteling in plaats van leven.,For en skam. Teknologien vår kastes bort på tortur i stedet for liv.,Co za wstyd. Nasza technologia jest marnowana na tortury zamiast na życie.,É uma pena. Nossa tecnologia sendo desperdiçada com tortura ao invés de salvar vidas.,,Ce rușine. Tehnologia noastră e risipită pentru tortură în loc de a crea viață.,"Какой кошмар. Наша технология используется для пыток, а не для жизни.",,Vilken skam. Vår teknik slösas bort på tortyr i stället för liv.,Ne utanç verici. Teknolojimiz yaşam yerine işkence için harcanıyor. +"Being vain as hell, they mark their temples with big banners.",TXT_SUB_LOG82,STRIFE1.WAD: MAP21,,,"S takovou ješitností není divu, že si své chrámy značí velkými prapory.","Fordi de er forfængelige som helvede, markerer de deres templer med store bannere.","Eitel wie sie sind, markieren sie ihre Tempel mit riesigen Bannern.",,,"Siendo tan malditamente engreídos, marcan sus templos con grandes estandartes.",,"Läpeensä turhamaisia kun ovat, he vuoraavat temppelinsä suurin tunnuslipuin.","Avec leur orgeuil à la noix, je me ne doutais pas un instant qu'ils allaient mettre d'énormes bannières partout.","Miután felettébb hiúk, ezért hatalmas zászlókkal díszítik a templomaikat.","Essendo vanitosi come pochi, marchiano i loro templi con degli stemmi.",うぬぼれが酷いな、あいつらの寺院はデカいバナーが目に付く。,"고통을 더하자면, 자기네 신전에 커다란 기를 세웠어.","Tevergeefs als de hel, markeren ze hun tempels met grote spandoeken.","Forfengelige som faen, markerer de templene sine med store bannere.","Próżni jak diabli, oznaczają swoje świątynie wielkimi transparentami.",Esses caras são vaidosos pra caramba. Eles marcam os seus templos com esses grandes estandartes.,,"Vanitate la maxim, își marchează templele cu steaguri imense.","Они спесивы до ужаса, раз украшают свои храмы большими флагами.",,Eftersom de är fåfänga som fan markerar de sina tempel med stora banderoller.,"Cehennem kadar kibirli oldukları için, tapınaklarını büyük pankartlarla işaretliyorlar." Another Sigil piece. We are one step closer to freedom. And you are one step closer to me.,TXT_SUB_LOG83,"STRIFE1.WAD: MAP27 (After defeating the Loremaster and collecting the fourth Sigil piece with either Macil or the Oracle alive)",,,Další díl Pečeti. Jsme o krok blíž ke svobodě. A ty jsi o krok blíž ke mě.,Endnu et Sigil-stykke. Vi er et skridt nærmere friheden. Og du er et skridt tættere på mig.,Noch ein Sigil-Teil. Wir sind der Freiheit einen Schritt näher. Und du bist mir einen Schritt näher.,,,Otra pieza del emblema. Estamos un paso más cerca de la libertad. Y tú un paso más cerca de mí.,,Jälleen uusi Sinetin osanen. Olemme taas askeleen lähempänä vapautta. Ja sinä askeleen lähempänä minua.,"Encore une pièce du Sigil. Un pas de plus vers la liberté, et un pas de plus vers moi.",Egy másik pecsét darab. Egy lépéssel közelebb vagyunk a szabadsághoz. Te pedig egy lépéssel közelebb hozzám.,Un altro pezzo del Sigillo. Siamo ancora più vicini alla libertà. E tu sei ancora più vicino a me.,"更なるシジルの欠片だ。私達の自由にまた一歩近づいたわ。 -そして私にも一歩近づいている。",또 다른 시질 조각이야. 자유를 향한 길이 거의 얼마 안 남았어. 나와 만나는 길도 얼마 안 남았고.,Nog een Sigil stuk. We zijn een stap dichter bij de vrijheid. En jij bent een stap dichter bij mij.,Enda en Sigil-brikke. Vi er ett skritt nærmere friheten. Og du er ett skritt nærmere meg.,Kolejny kawałek Sigil. Jesteśmy o krok bliżej wolności. A ty jesteś o krok bliżej mnie.,Mais uma peça do Sigilo. Estamos cada vez mais próximos da liberdade. E você cada vez mais próximo de mim.,,Altă piesă de Sigiul. Suntem cu un pas mai aproape de libertate. Și tu ești cu un pas mai aproape de mine.,Очередной фрагмент Печати. Теперь мы ещё на шаг ближе к освобождению. А ты — ещё на шаг ближе ко мне.,,Başka bir Sigil parçası. Özgürlüğe bir adım daha yaklaştık. Ve sen de bana bir adım daha yaklaştın. +そして私にも一歩近づいている。",또 다른 시질 조각이야. 자유를 향한 길이 거의 얼마 안 남았어. 나와 만나는 길도 얼마 안 남았고.,Nog een Sigil stuk. We zijn een stap dichter bij de vrijheid. En jij bent een stap dichter bij mij.,Enda en Sigil-brikke. Vi er ett skritt nærmere friheten. Og du er ett skritt nærmere meg.,Kolejny kawałek Sigil. Jesteśmy o krok bliżej wolności. A ty jesteś o krok bliżej mnie.,Mais uma peça do Sigilo. Estamos cada vez mais próximos da liberdade. E você cada vez mais próximo de mim.,,Altă piesă de Sigiul. Suntem cu un pas mai aproape de libertate. Și tu ești cu un pas mai aproape de mine.,Очередной фрагмент Печати. Теперь мы ещё на шаг ближе к освобождению. А ты — ещё на шаг ближе ко мне.,,Ännu ett Sigil-stycke. Vi är ett steg närmare friheten. Och du är ett steg närmare mig.,Başka bir Sigil parçası. Özgürlüğe bir adım daha yaklaştık. Ve sen de bana bir adım daha yaklaştın. "From the looks of it, we need the full Sigil to unlock this puppy. Something tells me this is the end of the rainbow.",TXT_SUB_LOG84,STRIFE1.WAD: MAP27,,,"Vypadá to, že tohohle mazlíčka jde otevřít pouze s úplnou Pečetí. Něco mi říká, že jsme našli konec duhy.","Som det ser ud nu, skal vi bruge hele Sigil'en for at låse denne hvalp op. Noget siger mig, at dette er enden af regnbuen.","Wie es aussieht brauchen wir das komplette Sigil um das Ding hier zu öffnen. Etwas sagt mir, dass wir am Ende unserer Reise angekommen sind.",,,Parece que necesitamos el Emblema completo para abrir este pequeñín. Algo me dice que este es el final del arcoiris.,,"Näyttää siltä, että tarvitsemme täyden Sinetin tämän veijarin avaamiseksi. Jotenkin tuntuu siltä, että sateenkaari päätyy tänne.",On dirait qu'il nous faut toutes les pièces du Sigil pour ouvrir ce joujou. Quelque chose me dit que c'est là que l'arc-en-ciel finit.,"Úgy néz ki az egész pecsét kell, hogy bejussunk itt. Azt sugallja nekem, hogy ez lesz valószínűleg a végkifejlett.","Da quel che sembra, abbiamo bisogno del Sigillo intero per accedere qua. Qualcosa mi dice che siamo alla fine del tunnel.","この形状を見た所、解除するには完成したシジルを持って、ちっこい台座に乗るんだわ。 -誰もが雨上がりの虹を見るために。","열쇠 구멍의 모습을 보아하니, 완성된 시질이 있어야만 열 수 있는 것 같아. 이 모든 모험의 도착지점인 것 같기도 하고.","Zoals het er nu uitziet, hebben we de volledige Sigil nodig om deze pup te ontgrendelen. Iets zegt me dat dit het einde van de regenboog is.",Det ser ut til at vi trenger hele sigillet for å låse opp denne valpen. Noe sier meg at dette er enden på regnbuen.,"Wygląda na to, że potrzebujemy pełnego Sigilu, aby odblokować tego szczeniaka. Coś mi mówi, że to koniec tęczy.","Pelo que parece, precisamos do Sigilo completo para destrancar essa belezinha. Algo me diz que este é o fim do arco-íris.",,"Din câte se pare, aven nevoie de întreg Sigiliul pentru a deschide puiul. Ceva îmi spune că ăsta e capătul curcubeului.","Судя по всему, открыть этот замок сможет только завершённая Печать. Что-то мне подсказывает, что мы достигли конца радуги!",,"Görünüşe göre, bu yavruyu açmak için Sigil'in tamamına ihtiyacımız var. İçimden bir ses bunun gökkuşağının sonu olduğunu söylüyor." +誰もが雨上がりの虹を見るために。","열쇠 구멍의 모습을 보아하니, 완성된 시질이 있어야만 열 수 있는 것 같아. 이 모든 모험의 도착지점인 것 같기도 하고.","Zoals het er nu uitziet, hebben we de volledige Sigil nodig om deze pup te ontgrendelen. Iets zegt me dat dit het einde van de regenboog is.",Det ser ut til at vi trenger hele sigillet for å låse opp denne valpen. Noe sier meg at dette er enden på regnbuen.,"Wygląda na to, że potrzebujemy pełnego Sigilu, aby odblokować tego szczeniaka. Coś mi mówi, że to koniec tęczy.","Pelo que parece, precisamos do Sigilo completo para destrancar essa belezinha. Algo me diz que este é o fim do arco-íris.",,"Din câte se pare, aven nevoie de întreg Sigiliul pentru a deschide puiul. Ceva îmi spune că ăsta e capătul curcubeului.","Судя по всему, открыть этот замок сможет только завершённая Печать. Что-то мне подсказывает, что мы достигли конца радуги!",,Som det ser ut nu behöver vi hela Sigil för att låsa upp den här valpen. Något säger mig att det här är slutet på regnbågen.,"Görünüşe göre, bu yavruyu açmak için Sigil'in tamamına ihtiyacımız var. İçimden bir ses bunun gökkuşağının sonu olduğunu söylüyor." You wield the power of the complete Sigil. What do you say we go get some closure.,TXT_SUB_LOG85,"STRIFE1.WAD: MAP12 (After killing the Oracle and collecting the final Sigil piece with both Macil and the Loremaster dead) @@ -12133,48 +12615,48 @@ MAP27 (After defeating the Loremaster and collecting the final Sigil piece with Macil and the Oracle dead)",,,"Vládneš mocí složené Pečetě. Co říkáš na to, završit to tady?","Du har magten af det komplette sigil. Hvad siger du til, at vi får en afslutning?","Du hast die Macht des kompletten Sigils. Was hälst du davon, wenn wir das hier beenden?",,,Empuñas el poder del Emblema completo. Que te parece si conseguimos algo de clausura.,,Täyden Sinetin voima on hallussasi. Mitäpä jos hakisimme päätöstä. ,Tu possède le pouvoir du Sigil complet. Ca te dit qu'on aille finir tout ça?,"Tied a Pecsét teljes ereje. Mit szólnál ahhoz, ha rövidre zárnánk a dolgokat.",Hai il potere del Sigillo completo. Che ne dici di mettere fine a questa faccenda.,"貴方はもはや完全なシジルの力を行使できるわけね。 後は言いがかりでもしてここを閉鎖させましょう。 -",시질의 완전한 힘은 이제 네 손에 있어. 종지부를 찍을 준비 됐어?,Je gebruikt de kracht van de hele Sigil. Wat zeg je ervan als we de zaak gaan afsluiten.,"Du har kraften til hele sigillet, og du kan bruke det. Hva sier du til å få en avslutning?","Władasz mocą kompletnego Sigilu. Co powiesz na to, żebyśmy się zamknęli.",Você tem o poder do Sigilo completo em suas mãos. Que tal a gente ir atrás de um desfecho?,,Ai puterea întregului Sigiliu. Ce zici dacă primim o încheiere?,Теперь ты владеешь мощью завершённой Печати. Мы уже близко — давай покончим с этим.,,"Sigil'in tamamının gücüne sahipsin. Ne dersin, gidip biraz kapanış yapalım mı?" -"High noon, my hero. Prepare to embrace glory.",TXT_SUB_LOG86,,,,"Souboj v pravé poledne, můj hrdino. Připrav se přijmout slávu.","Klokken tolv, min helt. Gør dig klar til at omfavne æren.","Die Stunde ist gekommen, mein Held. Bereite dich auf Ruhm vor.",,,"Es la hora final, mi héroe. Prepárate para la gloria.",,"Ratkaisun hetki, sankarini. Valmistaudu pukeutumaan kunniaan.","Le soleil est au zénith, mon héros. Prépare toi à rencontrer ta gloire.",Eljött az idő hősöm. Ragadd meg a lehetőséget.,"Mezzogiorno di fuoco, mio eroe. Preparati ad abbracciare la gloria.",いい気分でしょ、私の英雄。栄光を受け入れる準備をしなさい。,"석양이 지고 있어, 나의 영웅. 영광을 누릴 준비해!","Hoog middaguur, mijn held. Bereid je voor om de glorie te omarmen.","Klokka er tolv, min helt. Forbered deg på å omfavne æren.","W samo południe, mój bohaterze. Przygotuj się na przyjęcie chwały.","Chegou a hora, meu herói. Se prepare para abraçar a glória.",,"Timpul pentru glorie, eroul meu.","Самое время, мой герой! Ты будешь купаться в славе.",,"Öğle vakti, kahramanım. Zaferi kucaklamaya hazırlan." +",시질의 완전한 힘은 이제 네 손에 있어. 종지부를 찍을 준비 됐어?,Je gebruikt de kracht van de hele Sigil. Wat zeg je ervan als we de zaak gaan afsluiten.,"Du har kraften til hele sigillet, og du kan bruke det. Hva sier du til å få en avslutning?","Władasz mocą kompletnego Sigilu. Co powiesz na to, żebyśmy się zamknęli.",Você tem o poder do Sigilo completo em suas mãos. Que tal a gente ir atrás de um desfecho?,,Ai puterea întregului Sigiliu. Ce zici dacă primim o încheiere?,Теперь ты владеешь мощью завершённой Печати. Мы уже близко — давай покончим с этим.,,Du har makten över hela Sigil. Vad sägs om att vi går och avslutar det hela.,"Sigil'in tamamının gücüne sahipsin. Ne dersin, gidip biraz kapanış yapalım mı?" +"High noon, my hero. Prepare to embrace glory.",TXT_SUB_LOG86,,,,"Souboj v pravé poledne, můj hrdino. Připrav se přijmout slávu.","Klokken tolv, min helt. Gør dig klar til at omfavne æren.","Die Stunde ist gekommen, mein Held. Bereite dich auf Ruhm vor.",,,"Es la hora final, mi héroe. Prepárate para la gloria.",,"Ratkaisun hetki, sankarini. Valmistaudu pukeutumaan kunniaan.","Le soleil est au zénith, mon héros. Prépare toi à rencontrer ta gloire.",Eljött az idő hősöm. Ragadd meg a lehetőséget.,"Mezzogiorno di fuoco, mio eroe. Preparati ad abbracciare la gloria.",いい気分でしょ、私の英雄。栄光を受け入れる準備をしなさい。,"석양이 지고 있어, 나의 영웅. 영광을 누릴 준비해!","Hoog middaguur, mijn held. Bereid je voor om de glorie te omarmen.","Klokka er tolv, min helt. Forbered deg på å omfavne æren.","W samo południe, mój bohaterze. Przygotuj się na przyjęcie chwały.","Chegou a hora, meu herói. Se prepare para abraçar a glória.",,"Timpul pentru glorie, eroul meu.","Самое время, мой герой! Ты будешь купаться в славе.",,"Klockan tolv, min hjälte. Förbered dig på att omfamna ära.","Öğle vakti, kahramanım. Zaferi kucaklamaya hazırlan." "Well, so much for prognostication. Hold it, Macil is calling us back. Let's get out of here in one piece.",TXT_SUB_LOG87,"STRIFE1.WAD: MAP12 (After killing the Oracle with Macil alive)",,,"No, to by bylo pro prorokování. Počkat, Macil nás volá zpět. Vypadněme odsud vcelku.","Så meget for prognoser. Vent, Macil kalder os tilbage. Lad os komme ud herfra i ét stykke.","Nun, so viel zu Vorraussagungen. Moment, Macil ruft uns zurück. Lass uns hier heile heraus kommen.",,,"Bueno, tanto por un presentimiento. Espera, Macil nos reclama. Salgamos de aquí de una pieza.",,"No, se siitä ennustelusta. Odota, Macil kutsuu meitä takaisin. Häivytään täältä ehjin nahoin.","Bon, tant pis pour les pronostics. Attends, Macil nous demande de revenir. Rentrons un seul morceau.","Ennyit az előrejelzésről. Várj, Macil visszahív minket. Húzzunk el, míg egy darabban vagyunk.","Alla faccia dei prognostici... Aspetta, Macil ci sta richiamando. Meglio uscire da qua tutti interi.","まあ予言なんてそんなものでしょ。 -ちょっと待って、マシルが帰還するように言ったわ。ここから抜け出しましょう。","웃기네. 이딴 예언 따위. 잠깐만, 마실이 우리들을 부르고 있어. 이제 여기를 나가자.","Nou, tot zover de prognose. Wacht even, Macil roept ons terug. Laten we hier heelhuids weggaan.","Så mye for spådommer. Vent, Macil kaller oss tilbake. La oss komme oss helskinnet ut herfra.","Cóż, to tyle jeśli chodzi o prognozowanie. Czekajcie, Macil nas wzywa. Wynośmy się stąd w jednym kawałku.","Bem, parece que não é hora de previsões. Peraí, o Macil está nos chamando de volta. Vamos tentar sair daqui inteiros.",,"Atât a fost cu prognosticul. Stai, Macil ne sună înapoi. Să ieșim întregi de aici.","Да, это превзошло все наши ожидания. Подожди — Мэйсил вызывает нас назад. Давай выбираться отсюда.",,"Kehanet buraya kadarmış. Durun, Macil bizi geri çağırıyor. Buradan tek parça halinde çıkalım." -"I'm sorry, after up to my hips in blood I can't think of anything witty to say right now. Let's get back to Macil.",TXT_SUB_LOG88,,,,"Je mi líto; když jsem po boky v krvi, nemám nic co vtipného říct. Vraťme se k Macilovi.","Jeg er ked af det, men efter at have stået op til hofterne i blod kan jeg ikke finde på noget vittigt at sige lige nu. Lad os gå tilbage til Macil.","Tut mir leid, aber bei so viel Blut fällt mir nicht Flapsiges mehr ein. Lass uns zu Macil zurückgehen.",,,,,Anteeksi; oltuani lanteitani myöten veressä en keksi juuri nyt mitään nokkelaa sanottavaa. Palataan Macilin luokse.,"Désolée, après m'être retrouvée jusqu'au hanches dans le sang, je n'ai rien de malin à dire. Rentrons voir Macil.","Bocs, de miután nyakig vérben úsztam, semmi szellemes nem jut az eszembe. Irány vissza Macilhoz.","Mi spiace, ma dopo essere nel sangue fino alle caviglie non ho in mente nulla di interessante di dire al momento. Ritorniamo da Macil.",,미안. 피칠갑을 한 너의 모습을 보느라 할 말을 잃었어. 그냥 마실에게로 돌아가자.,"Het spijt me, na tot aan mijn heupen in bloed kan ik nu niets geestigs bedenken om te zeggen. Laten we teruggaan naar Macil.","Beklager, etter å ha stått i blod til hoftene kommer jeg ikke på noe vittig å si akkurat nå. La oss gå tilbake til Macil.","Przepraszam, ale po tym, jak jestem po biodra we krwi, nie mam teraz nic dowcipnego do powiedzenia. Wracajmy do Macil.",Desculpa. Após ficar coberta de sangue não consigo pensar em nada interessante pra dizer agora. Vamos voltar pro Macil.,,"Îmi pare rău, dar nu mă pot gândi să zic nimic acum. Să ne întoarcem la Macil.","Извини, после того, как я по бёдра в крови, я не могу придумать ничего остроумного, чтобы сказать сейчас. Давай вернёмся к Мэйсилу.",,"Üzgünüm, kalçalarıma kadar kana bulandıktan sonra şu anda söyleyecek esprili bir şey bulamıyorum. Macil'e geri dönelim." +ちょっと待って、マシルが帰還するように言ったわ。ここから抜け出しましょう。","웃기네. 이딴 예언 따위. 잠깐만, 마실이 우리들을 부르고 있어. 이제 여기를 나가자.","Nou, tot zover de prognose. Wacht even, Macil roept ons terug. Laten we hier heelhuids weggaan.","Så mye for spådommer. Vent, Macil kaller oss tilbake. La oss komme oss helskinnet ut herfra.","Cóż, to tyle jeśli chodzi o prognozowanie. Czekajcie, Macil nas wzywa. Wynośmy się stąd w jednym kawałku.","Bem, parece que não é hora de previsões. Peraí, o Macil está nos chamando de volta. Vamos tentar sair daqui inteiros.",,"Atât a fost cu prognosticul. Stai, Macil ne sună înapoi. Să ieșim întregi de aici.","Да, это превзошло все наши ожидания. Подожди — Мэйсил вызывает нас назад. Давай выбираться отсюда.",,"Så mycket för prognoser. Vänta, Macil kallar oss tillbaka. Låt oss komma härifrån i ett stycke.","Kehanet buraya kadarmış. Durun, Macil bizi geri çağırıyor. Buradan tek parça halinde çıkalım." +"I'm sorry, after up to my hips in blood I can't think of anything witty to say right now. Let's get back to Macil.",TXT_SUB_LOG88,,,,"Je mi líto; když jsem po boky v krvi, nemám nic co vtipného říct. Vraťme se k Macilovi.","Jeg er ked af det, men efter at have stået op til hofterne i blod kan jeg ikke finde på noget vittigt at sige lige nu. Lad os gå tilbage til Macil.","Tut mir leid, aber bei so viel Blut fällt mir nicht Flapsiges mehr ein. Lass uns zu Macil zurückgehen.",,,,,Anteeksi; oltuani lanteitani myöten veressä en keksi juuri nyt mitään nokkelaa sanottavaa. Palataan Macilin luokse.,"Désolée, après m'être retrouvée jusqu'au hanches dans le sang, je n'ai rien de malin à dire. Rentrons voir Macil.","Bocs, de miután nyakig vérben úsztam, semmi szellemes nem jut az eszembe. Irány vissza Macilhoz.","Mi spiace, ma dopo essere nel sangue fino alle caviglie non ho in mente nulla di interessante di dire al momento. Ritorniamo da Macil.",,미안. 피칠갑을 한 너의 모습을 보느라 할 말을 잃었어. 그냥 마실에게로 돌아가자.,"Het spijt me, na tot aan mijn heupen in bloed kan ik nu niets geestigs bedenken om te zeggen. Laten we teruggaan naar Macil.","Beklager, etter å ha stått i blod til hoftene kommer jeg ikke på noe vittig å si akkurat nå. La oss gå tilbake til Macil.","Przepraszam, ale po tym, jak jestem po biodra we krwi, nie mam teraz nic dowcipnego do powiedzenia. Wracajmy do Macil.",Desculpa. Após ficar coberta de sangue não consigo pensar em nada interessante pra dizer agora. Vamos voltar pro Macil.,,"Îmi pare rău, dar nu mă pot gândi să zic nimic acum. Să ne întoarcem la Macil.","Извини, после того, как я по бёдра в крови, я не могу придумать ничего остроумного, чтобы сказать сейчас. Давай вернёмся к Мэйсилу.",,"Jag är ledsen, men efter att ha varit upp till höfterna i blod kan jag inte komma på något roligt att säga just nu. Vi återvänder till Macil.","Üzgünüm, kalçalarıma kadar kana bulandıktan sonra şu anda söyleyecek esprili bir şey bulamıyorum. Macil'e geri dönelim." "The factory is next to the mines. Richter must mean the mines of Degnin. The Degnin ore is magnetic and explosive, just the thing for shutting down force fields.",TXT_SUB_LOG89,STRIFE1.WAD: MAP23,,,"Továrna je vedle dolů. Richter musí mít na mysli doly degninu. Degninská ruda je magnetická a výbušná, perfektní pro vypnutí silového pole.","Fabrikken ligger ved siden af minerne. Richter må mene Degnin-minerne. Degnin-malmen er magnetisk og eksplosiv, lige til at lukke kraftfelter ned med.","Die Fabrik liegt neben den Minen. Richter muss von den Degnin-Minen reden. Das Degnin-Erz ist magnetisch und explosiv., genau das, was wir brauchen, um die Kraftfelder auszuschalten.",,,"La fábrica está junto a las minas. Richter debe referirse a las minas de Degnin. El mineral Degnin es magnético y explosivo, justo para apagar campos de fuerza. ",,"Tehdas on kaivoksen vieressä. Richter varmastikin tarkoittaa Degninin kaivosta. Degnin-malmi on magneettista ja räjähdysherkkää, juuri omiaan purkamaan voimakenttiä.","L'usine est près des mines. Richter doit parler des mines de degnin. Le minérai de degnin est magnétisé et explosif, c'est parfait pour désactiver les champs de force. ","A gyár a bánya mellett van. Richter valószínűleg a Degnin bányákra utalt. A degnini érc mágneses és robbanékony, egy tökéletes megoldás az erőpajzs kiiktatására.","La Fabbrica si trova accanto alle miniere. Richter starà parlando delle miniere di Degnin. I minerali di Degnin sono magnetici ed esplosivi, giusto ciò che ci serve per disattivare i campi di forza.","工場は鉱山の隣にあるわ。リヒターはデグニン鉱山とも呼んでいる。 -デグニン石は綺麗だが可燃性で、フォースフィールドを消すにはうってつけよ。",공장은 광산 옆에 있어. 릭터가 데그닌 광산을 이야기한 것 같아. 데그닌 광석은 폭발성이 있는 자기력이 감도는 물질이야. 방어막을 끌 중요한 도구이기도 하지.,"De fabriek ligt naast de mijnen. Richter moet de mijnen van Degnin bedoelen. Het Degnin-erts is magnetisch en explosief, precies het ding voor het afsluiten van krachtvelden.","Fabrikken ligger ved siden av gruvene. Richter må mene gruvene i Degnin. Degnin-malmen er magnetisk og eksplosiv, som skapt for å slå ut kraftfelt.","Fabryka jest obok kopalni. Richter musi mieć na myśli kopalnie w Degnin. Ruda Degnin jest magnetyczna i wybuchowa, w sam raz do wyłączania pól siłowych.","A fábrica fica próxima às minas. O Richter provavelmente se refere às minas de Degnin. O minério de Degnin é magnético e explosivo, perfeito para derrubar os campos de força.",,"Fabrica e lângă mine. Richter probabil s-a referit la minele de Degnin. Mineralul de Degnin e magnetic și exploziv, exact ce ne trebuie pentru scuturi.","Вход на фабрику — рядом со спуском в шахты. Рихтер, должно быть, имел в виду шахты Дегнина. Дегнинская руда магнитна и взрывоопасна — то, что надо, если хочешь отключить силовое поле. ",,"Fabrika madenlerin yanında. Richter, Degnin madenlerini kastediyor olmalı. Degnin cevheri manyetik ve patlayıcıdır, tam da güç alanlarını kapatmak için." -"Mines, catacombs, sewers... What a first date!",TXT_SUB_LOG90,STRIFE1.WAD: MAP13,,,"Doly, kobky, stoky... skvělé první rande!","Minerne, katakomberne, kloakkerne... Sikke en første date!","Minen, Katakomben, Kanalisationen... was für ein erstes Date!",,,"Minas, catacumbas, alcantarillas... ¡Menuda primera cita!",,"Kaivoksia, katakombeja, viemäreitä... Mitkä ensitreffit!","Mines, catacombes, égouts.. Super premier rendez-vous!","Bányák, katakombák, kanálisok... Micsoda első randi!","Miniere, catacombe, fogne... Che primo appuntamento!",鉱山、地下墓所、下水道...とんだ初デートだな!,"광산, 고대 묘지, 하수도. 데이트하기엔 딱 맞는 장소들이네!","Mijnen, catacomben, rioleringen.... Wat een eerste afspraakje!","Gruver, katakomber, kloakker... For en første date!","Kopalnie, katakumby, kanały... Co za pierwsza randka!","Minas, catacumbas, esgotos... Que belo primeiro encontro!",,"Mine, catacombe, canale... Ce întâlnire!","Шахты, катакомбы, канализации... Замечательное первое свидание!",,"Madenler, yeraltı mezarları, kanalizasyonlar. Ne ilk randevu ama!" +デグニン石は綺麗だが可燃性で、フォースフィールドを消すにはうってつけよ。",공장은 광산 옆에 있어. 릭터가 데그닌 광산을 이야기한 것 같아. 데그닌 광석은 폭발성이 있는 자기력이 감도는 물질이야. 방어막을 끌 중요한 도구이기도 하지.,"De fabriek ligt naast de mijnen. Richter moet de mijnen van Degnin bedoelen. Het Degnin-erts is magnetisch en explosief, precies het ding voor het afsluiten van krachtvelden.","Fabrikken ligger ved siden av gruvene. Richter må mene gruvene i Degnin. Degnin-malmen er magnetisk og eksplosiv, som skapt for å slå ut kraftfelt.","Fabryka jest obok kopalni. Richter musi mieć na myśli kopalnie w Degnin. Ruda Degnin jest magnetyczna i wybuchowa, w sam raz do wyłączania pól siłowych.","A fábrica fica próxima às minas. O Richter provavelmente se refere às minas de Degnin. O minério de Degnin é magnético e explosivo, perfeito para derrubar os campos de força.",,"Fabrica e lângă mine. Richter probabil s-a referit la minele de Degnin. Mineralul de Degnin e magnetic și exploziv, exact ce ne trebuie pentru scuturi.","Вход на фабрику — рядом со спуском в шахты. Рихтер, должно быть, имел в виду шахты Дегнина. Дегнинская руда магнитна и взрывоопасна — то, что надо, если хочешь отключить силовое поле. ",,"Fabriken ligger bredvid gruvorna. Richter måste mena Degnins gruvor. Degninmalmen är magnetisk och explosiv, precis vad man behöver för att stänga av kraftfält.","Fabrika madenlerin yanında. Richter, Degnin madenlerini kastediyor olmalı. Degnin cevheri manyetik ve patlayıcıdır, tam da güç alanlarını kapatmak için." +"Mines, catacombs, sewers... What a first date!",TXT_SUB_LOG90,STRIFE1.WAD: MAP13,,,"Doly, kobky, stoky... skvělé první rande!","Minerne, katakomberne, kloakkerne... Sikke en første date!","Minen, Katakomben, Kanalisationen... was für ein erstes Date!",,,"Minas, catacumbas, alcantarillas... ¡Menuda primera cita!",,"Kaivoksia, katakombeja, viemäreitä... Mitkä ensitreffit!","Mines, catacombes, égouts.. Super premier rendez-vous!","Bányák, katakombák, kanálisok... Micsoda első randi!","Miniere, catacombe, fogne... Che primo appuntamento!",鉱山、地下墓所、下水道...とんだ初デートだな!,"광산, 고대 묘지, 하수도. 데이트하기엔 딱 맞는 장소들이네!","Mijnen, catacomben, rioleringen.... Wat een eerste afspraakje!","Gruver, katakomber, kloakker... For en første date!","Kopalnie, katakumby, kanały... Co za pierwsza randka!","Minas, catacumbas, esgotos... Que belo primeiro encontro!",,"Mine, catacombe, canale... Ce întâlnire!","Шахты, катакомбы, канализации... Замечательное первое свидание!",,"Gruvor, katakomber, kloaker... Vilken första träff!","Madenler, yeraltı mezarları, kanalizasyonlar. Ne ilk randevu ama!" "I wish Richter had been a touch more specific. Hm, let's try over here.",TXT_SUB_LOG91,STRIFE1.WAD: MAP13,,,"Přála bych si, aby byl Richter trochu přesnější. Hm, zkusme to tadyhle.","Jeg ville ønske, Richter havde været lidt mere specifik. Hm, lad os prøve herovre.","Ich wünschte mir, dass Richter etwas präziser gewesen wäre. Hmm, lass es uns mal hier versuchen.",,,"Ojalá Richter hubiera sido un pelín más específico. Hm, probemos por aquí.",,"Kunpa Richter olisi ollut hivenen tarkempi. Hm, kokeillaan täältä.",J'aurais bien voulu que Richter soit un peu plus spécifique. Hm.. Essayons ici.,"Nem bántam volna, ha Richter egy csöppnyivel pontosabb leírást ad. Hm, próbáljuk meg itt.","Vorrei che Richter fosse stato un poco più preciso. Mh, vediamo di là.","リヒターがもっと具体的な部分に触れてくれて欲しいが。 -あー、私らが試してみようか。","릭터가 좀 더 자세히 설명해 줬으면 좋았을 텐데. 흠, 여기서 해보자.","Ik wou dat Richter een beetje specifieker was geweest. Hm, laten we het hier eens proberen.","Skulle ønske Richter hadde vært litt mer spesifikk. Hm, la oss prøve her borte.","Szkoda, że Richter nie był bardziej konkretny. Hm, spróbujmy tutaj.","Bem que o Richter podia ter sido um pouco mais específico. Hmm, vamos tentar por alí.",,Îmi doresc ca Richter să fii fost mai specific. Să încercăm acolo.,"Я надеялась, что Рихтер будет чуть более конкретным. Ладно, давай посмотрим, что там.",,Keşke Richter biraz daha spesifik olsaydı. Şurayı deneyelim. +あー、私らが試してみようか。","릭터가 좀 더 자세히 설명해 줬으면 좋았을 텐데. 흠, 여기서 해보자.","Ik wou dat Richter een beetje specifieker was geweest. Hm, laten we het hier eens proberen.","Skulle ønske Richter hadde vært litt mer spesifikk. Hm, la oss prøve her borte.","Szkoda, że Richter nie był bardziej konkretny. Hm, spróbujmy tutaj.","Bem que o Richter podia ter sido um pouco mais específico. Hmm, vamos tentar por alí.",,Îmi doresc ca Richter să fii fost mai specific. Să încercăm acolo.,"Я надеялась, что Рихтер будет чуть более конкретным. Ладно, давай посмотрим, что там.",,"Jag önskar att Richter hade varit lite mer specifik. Hm, vi försöker här borta.",Keşke Richter biraz daha spesifik olsaydı. Şurayı deneyelim. "I think we're... Oh, crap. I have no idea where we are.",TXT_SUB_LOG92,STRIFE1.WAD: MAP13,,,"Myslím, že jsme... sakra. Nemám tušení, kde jsme.","Jeg tror, vi er... Åh, pis. Jeg har ingen idé om, hvor vi er.","Ich glaube wir sind... Oh, Mist. Ich habe keine Ahnung wo wir sind.",,,"Creo que estamos... Oh, mierda. No tengo ni idea de donde estamos.",,"Luulen, että olemme... Perhana, minulla ei ole aavistustakaan, missä olemme.","Je crois que.. Non, merde, j'ai aucune idée d'où on est!","Azt hiszem éppen...Oh, franc. Ötletem sincs hol vagyunk.","Credo che siamo... Ah, merda, non ne ho proprio idea.","私が思うに...ああ、クソ。 -何処にあるかさっぱりわからないわ。",우리는 지금... 이런 제길. 여기가 어딘지 모르겠어.,"Ik denk dat we.... Oh, shit. Ik heb geen idee waar we zijn.","Jeg tror vi... Å, pokker. Jeg aner ikke hvor vi er.","Chyba jesteśmy... O, cholera. Nie mam pojęcia, gdzie jesteśmy.","Acho que estamos... Ah, merda. Não faço a menor idéia onde estamos.",,"Cred că suntem... Oh, la naiba. Nu știu unde suntem.","Я думаю, мы... О, чёрт. Я понятия не имею, где мы.",,"Sanırım biz... Oh, kahretsin. Nerede olduğumuz hakkında hiçbir fikrim yok." +何処にあるかさっぱりわからないわ。",우리는 지금... 이런 제길. 여기가 어딘지 모르겠어.,"Ik denk dat we.... Oh, shit. Ik heb geen idee waar we zijn.","Jeg tror vi... Å, pokker. Jeg aner ikke hvor vi er.","Chyba jesteśmy... O, cholera. Nie mam pojęcia, gdzie jesteśmy.","Acho que estamos... Ah, merda. Não faço a menor idéia onde estamos.",,"Cred că suntem... Oh, la naiba. Nu știu unde suntem.","Я думаю, мы... О, чёрт. Я понятия не имею, где мы.",,"Jag tror att vi är... Åh, skit. Jag har ingen aning om var vi är.","Sanırım biz... Oh, kahretsin. Nerede olduğumuz hakkında hiçbir fikrim yok." "This must be the ruins Richter's agents were searching for. Oh, watch out! Crusaders!",TXT_SUB_LOG93,STRIFE1.WAD: MAP25,,,"Tohle musí být ty ruiny, které Richterovi agenti hledali. A, bacha! Křižáci!","Det må være ruinerne, som Richters agenter ledte efter. Åh, pas på! Korsfarere!","Dies müssen die Ruinen sein, die Richters Agent gesucht hat. Oh, aufpassen! Ordensritter!",,,"Estas deben ser las ruinas que el agente de Richter estaba buscando. Oh, ¡cuidado! ¡Cruzados!",,"Nämä ovat varmaankin ne rauniot, joita Richterin joukot olivat etsineet. Oho, varo: ristiretkeläisiä!","Ca doit être les ruines que les agents de Richter cherchaient. Attention, des croisés!","Ezek lehetnek a romok, amit Richter ügynökei kerestek. Vigyázz! Keresztesek!","Queste devono essere le rovine che gli agenti di Richter stavano cercando. Ah, attento! Crociati!","ここがリヒターのエージェントが探していた遺跡のはず。 -あっと、気を付けて!クルセイダーよ!","릭터의 요원이 수색하던 유적지인가봐... 잠깐, 조심해! 크루세이더야!","Dit moet de ruïnes zijn waar de agenten van Richter naar op zoek waren. Oh, kijk uit! Kruisvaarders!",Dette må være ruinene Richters agenter lette etter. Se opp! Korsfarere!,"To muszą być ruiny, których szukali agenci Richtera. Och, uważaj! Krzyżowcy!","Estas devem ser as ruínas que o agente de Richter estava procurando. Ah, cuidado! Cruzados!",,Ăstea ar trebui să fie ruinele pe care le căutau agenții lui Richter. Ai grijă! Cruciați!,"Возможно, это те самые руины, которые искали агенты Рихтера... Осторожно! Крестоносцы!",,"Richter'in ajanlarının aradığı harabeler burası olmalı. Oh, dikkat et! Haçlılar!" -"Ugh, it's trying to regenerate. Blast it before I throw up!",TXT_SUB_LOG94,,,,"Fuj, snaží se to oživit. Odstřel to, než začnu zvracet!","Ugh, den prøver at regenerere. Skyd den, før jeg kaster op!","Ugh, es versucht, sich zu regenerieren. Mach es fertig, bevor ich anfange zu kotzen.",,,"Ugh, está intentando regenerarse. ¡Reviéntalo antes de que vomite!",,"Yöh, se yrittää uusiutua. Posauta se, ennen kuin laattaan!","Beurk, il essaie de se régénérer, incinère le avant que je ne vomisse!","Fúj, regenerálódni próbál. Lődd szét mielőtt ide hányok!","Dannazione, sta cercando di rigenerarsi! Distruggilo prima che mi venga da vomitare.",,"으윽, 이게 재생하기 시작했어. 내가 토하기 전에 파괴해!","Ugh, het probeert te regenereren. Blast het voordat ik overgeven!",Den prøver å regenerere. Spreng den før jeg spyr!,"Ugh, próbuje się zregenerować. Rozwal to, zanim zwymiotuję!","Argh, está tentando se regenerar. Detona essa coisa antes que eu vomite!",,"Ugh, încearcă să se regenereze. Aruncă-l în aer înainte să vomit.","О-о, оно пытается восстановиться. Добей его, пока меня не стошнило!",,Yenilenmeye çalışıyor. Kusmadan önce patlat şunu! +あっと、気を付けて!クルセイダーよ!","릭터의 요원이 수색하던 유적지인가봐... 잠깐, 조심해! 크루세이더야!","Dit moet de ruïnes zijn waar de agenten van Richter naar op zoek waren. Oh, kijk uit! Kruisvaarders!",Dette må være ruinene Richters agenter lette etter. Se opp! Korsfarere!,"To muszą być ruiny, których szukali agenci Richtera. Och, uważaj! Krzyżowcy!","Estas devem ser as ruínas que o agente de Richter estava procurando. Ah, cuidado! Cruzados!",,Ăstea ar trebui să fie ruinele pe care le căutau agenții lui Richter. Ai grijă! Cruciați!,"Возможно, это те самые руины, которые искали агенты Рихтера... Осторожно! Крестоносцы!",,"Det här måste vara ruinerna som Richters agenter sökte efter. Åh, se upp! Korsfarare!","Richter'in ajanlarının aradığı harabeler burası olmalı. Oh, dikkat et! Haçlılar!" +"Ugh, it's trying to regenerate. Blast it before I throw up!",TXT_SUB_LOG94,,,,"Fuj, snaží se to oživit. Odstřel to, než začnu zvracet!","Ugh, den prøver at regenerere. Skyd den, før jeg kaster op!","Ugh, es versucht, sich zu regenerieren. Mach es fertig, bevor ich anfange zu kotzen.",,,"Ugh, está intentando regenerarse. ¡Reviéntalo antes de que vomite!",,"Yöh, se yrittää uusiutua. Posauta se, ennen kuin laattaan!","Beurk, il essaie de se régénérer, incinère le avant que je ne vomisse!","Fúj, regenerálódni próbál. Lődd szét mielőtt ide hányok!","Dannazione, sta cercando di rigenerarsi! Distruggilo prima che mi venga da vomitare.",,"으윽, 이게 재생하기 시작했어. 내가 토하기 전에 파괴해!","Ugh, het probeert te regenereren. Blast het voordat ik overgeven!",Den prøver å regenerere. Spreng den før jeg spyr!,"Ugh, próbuje się zregenerować. Rozwal to, zanim zwymiotuję!","Argh, está tentando se regenerar. Detona essa coisa antes que eu vomite!",,"Ugh, încearcă să se regenereze. Aruncă-l în aer înainte să vomit.","О-о, оно пытается восстановиться. Добей его, пока меня не стошнило!",,"Ugh, den försöker att regenerera. Skjut den innan jag spyr!",Yenilenmeye çalışıyor. Kusmadan önce patlat şunu! "My friend, whatever it is we're fighting, it's more than the Order. Off to the mines!",TXT_SUB_LOG95,STRIFE1.WAD: MAP25,,,"Příteli, ať už bojujeme s čímkoliv, jde o víc než jen Řád. Do dolů!","Min ven, hvad det end er, vi kæmper imod, er det mere end Ordenen. Af sted til minerne!","Mein Freund, was auch immer es ist, dass wir bekämpfen, es ist mehr als der Orden. Ab zu den Minen!",,,"Amigo mío, lo que sea contra que estemos luchando, es más que la Orden. ¡A las minas!",,"Ystäväni, mitä vastaan me taistelemmekaan, se on suurempi kuin Veljeskunta. Matkatkaamme kaivokselle!","Mon ami, je ne sais ce contre quoi on se bat, mais c'est plus que l'Ordre. Allons dans les mines!","Nos barátom, bármivel is állunk szemben, több az mint maga a Rend. Irány a bánya!","Amico mio, qualsiasi cosa stiamo combattendo, è molto più dell'Ordine. Alle miniere!","友よ、私達が戦う相手が何であろうとも、オーダー以上のものはない。 -鉱山から離れましょう!","친구야, 우리가 싸우는 상대가 무엇인지는 모르겠지만, 오더보다 더한 존재인 것 같아. 광산으로 향하자!","Mijn vriend, wat het ook is waar we tegen vechten, het is meer dan de Orde. Naar de mijnen!","Min venn, hva det enn er vi kjemper mot, så er det mer enn Ordenen. Av sted til gruvene!","Mój przyjacielu, cokolwiek to jest, z czym walczymy, to coś więcej niż Zakon. Do kopalni!","Meu amigo, seja lá o que estamos combatendo, é mais do que somente a Ordem. Vamos para as minas!",,"Prietene, orice ar fi ceea ce înfruntăm, e mai mult decât Ordinul. Către mine!","Друг мой, с чем бы мы ни сражались, это нечто большее, чем просто Орден. К шахтам!",,"Dostum, savaştığımız şey her neyse, Tarikat'tan daha fazlası. Madenlere!" -"Without letting down your guard, look for deposits of ore.",TXT_SUB_LOG96,STRIFE1.WAD: MAP14,,,Opatrně se zkus podívat po ložiscích rudy.,"Uden at sænke din vagt, skal du lede efter malmforekomster.",Sei vorsichtig und halte Ausschau nach Erzvorkommen.,,,"Sin bajar la guardia, busca depósitos de mineral.",,"Etsi malmiesiintymiä, kuitenkin valppautesi säilyttäen.","Sans arrêter de faire attention, cherche des veines de minerai.","Keress érceket, de figyelj a hátad mögé közben.","Senza abbassare la guardia, cerca di trovare alcuni depositi di minerali.",警戒を緩めることなく、鉱石の堆積所を探しましょう。,"조심해가면서, 그들이 캔 광석을 두는 곳을 찾아.","Zonder je waakzaamheid te laten verslappen, zoek je naar ertsafzettingen.","Uten å senke garden, let etter malmforekomster.","Nie spuszczając gardy, szukajcie złóż rudy.",Não baixe a sua guarda. Vamos procurar por depósitos de minério.,,"Fără a lăsa garda jos, uită-te dupa depozite de minereu.","Поищи залежи руды, но не теряй бдительности!",,"Gardınızı düşürmeden, maden yataklarını arayın." +鉱山から離れましょう!","친구야, 우리가 싸우는 상대가 무엇인지는 모르겠지만, 오더보다 더한 존재인 것 같아. 광산으로 향하자!","Mijn vriend, wat het ook is waar we tegen vechten, het is meer dan de Orde. Naar de mijnen!","Min venn, hva det enn er vi kjemper mot, så er det mer enn Ordenen. Av sted til gruvene!","Mój przyjacielu, cokolwiek to jest, z czym walczymy, to coś więcej niż Zakon. Do kopalni!","Meu amigo, seja lá o que estamos combatendo, é mais do que somente a Ordem. Vamos para as minas!",,"Prietene, orice ar fi ceea ce înfruntăm, e mai mult decât Ordinul. Către mine!","Друг мой, с чем бы мы ни сражались, это нечто большее, чем просто Орден. К шахтам!",,"Min vän, vad det än är vi slåss mot, så är det mer än Orden. Iväg till gruvorna!","Dostum, savaştığımız şey her neyse, Tarikat'tan daha fazlası. Madenlere!" +"Without letting down your guard, look for deposits of ore.",TXT_SUB_LOG96,STRIFE1.WAD: MAP14,,,Opatrně se zkus podívat po ložiscích rudy.,"Uden at sænke din vagt, skal du lede efter malmforekomster.",Sei vorsichtig und halte Ausschau nach Erzvorkommen.,,,"Sin bajar la guardia, busca depósitos de mineral.",,"Etsi malmiesiintymiä, kuitenkin valppautesi säilyttäen.","Sans arrêter de faire attention, cherche des veines de minerai.","Keress érceket, de figyelj a hátad mögé közben.","Senza abbassare la guardia, cerca di trovare alcuni depositi di minerali.",警戒を緩めることなく、鉱石の堆積所を探しましょう。,"조심해가면서, 그들이 캔 광석을 두는 곳을 찾아.","Zonder je waakzaamheid te laten verslappen, zoek je naar ertsafzettingen.","Uten å senke garden, let etter malmforekomster.","Nie spuszczając gardy, szukajcie złóż rudy.",Não baixe a sua guarda. Vamos procurar por depósitos de minério.,,"Fără a lăsa garda jos, uită-te dupa depozite de minereu.","Поищи залежи руды, но не теряй бдительности!",,"Utan att sänka garden, leta efter malmfyndigheter.","Gardınızı düşürmeden, maden yataklarını arayın." "These poor souls are drones, their synaptic functions are jammed by RC implants. We destroy the transmitter and they are free!",TXT_SUB_LOG97,STRIFE1.WAD: MAP14,,,"Tihle chudáci jsou trubci, jejich synaptické funkce jsou narušené na dálku ovládanými implantáty. Když zničíme vysílačku, budou svobodní!","Disse stakkels sjæle er droner, deres synaptiske funktioner er blokeret af RC-implantater. Vi ødelægger senderen, og de er frie!","Diese armen Seelen sind Drohnen, ihre synaptischen Funktionen werden von Implantaten blockiert. Wenn wir den Transmitter zerstören, sind sie frei.",,,"Estas pobres almas son zánganos. Sus funciones sinápticas están bloqueadas por implantes de control remoto. ¡Destruimos el transmisor, y son libres!",,"Nämä sieluparat ovat kuhnureita: Heidän synaptisia toimintojaan häiritään radio-ohjattavilla istutteilla. Me tuhoamme lähettimen, ja he ovat vapaat!","Ces pauvres âmes sont des drones, leurs fonctions synaptiques sont brouillées par des implants radiocommandés. On détruit le transmetteur et ils sont libres!","Ezek a szerencsétlen lelkek csak drónok. A szinaptikus funkcióikat zavarják távolról irányítható implantátumokkal. Szétromboljuk a jeladókat, és szabaddá vállnak.","Questi poveracci sono dei droni. Le loro funzioni cerebrali stanno venendo bloccate da degli impianti. Se distruggiamo il trasmettitore, saranno liberi!","これら精神の乏しい労働者達は、シナプス機能をRCインプラントで妨害している。 -私達が送信機を破壊し皆を解放するんだ!","저 사람들은 불쌍한 광산의 노예들이야. 오더가 이식한 세뇌 장치 때문에 정상적인 뇌 기능을 잃었지. 전송기만 파괴한다면, 그들은 자유를 되찾을 수 있을 거야!","Deze arme zielen zijn drones, hun synaptische functies worden verstoord door RC-implantaten. We vernietigen de zender en ze zijn vrij!","Disse stakkarene er droner, deres synaptiske funksjoner er blokkert av RC-implantater. Vi ødelegger senderen, og de er fri!","Te biedne dusze są dronami, ich funkcje synaptyczne są zagłuszane przez implanty RC. Zniszczymy nadajnik i są wolne!",Esses pobres coitados são zangões. Suas funções sinápticas estão sendo bloqueadas por implantes de controle remoto. Se destruirmos o transmissor eles estarão livres!,,Sufletele ăstea sărmane sunt drone. Funcțiile lor sinaptice sunt întrerupte de implanturi RC. Distrugem transmițătorul și sunt libere!,"Эти несчастные души — дроны. Сигнал, поступающий на импланты, полностью подавляет их сознание. Давай уничтожим передатчик и освободим их!",,"Bu zavallı ruhlar dron, sinaptik fonksiyonları RC implantları tarafından engellenmiş. Vericiyi yok edersek özgür kalırlar!" +私達が送信機を破壊し皆を解放するんだ!","저 사람들은 불쌍한 광산의 노예들이야. 오더가 이식한 세뇌 장치 때문에 정상적인 뇌 기능을 잃었지. 전송기만 파괴한다면, 그들은 자유를 되찾을 수 있을 거야!","Deze arme zielen zijn drones, hun synaptische functies worden verstoord door RC-implantaten. We vernietigen de zender en ze zijn vrij!","Disse stakkarene er droner, deres synaptiske funksjoner er blokkert av RC-implantater. Vi ødelegger senderen, og de er fri!","Te biedne dusze są dronami, ich funkcje synaptyczne są zagłuszane przez implanty RC. Zniszczymy nadajnik i są wolne!",Esses pobres coitados são zangões. Suas funções sinápticas estão sendo bloqueadas por implantes de controle remoto. Se destruirmos o transmissor eles estarão livres!,,Sufletele ăstea sărmane sunt drone. Funcțiile lor sinaptice sunt întrerupte de implanturi RC. Distrugem transmițătorul și sunt libere!,"Эти несчастные души — дроны. Сигнал, поступающий на импланты, полностью подавляет их сознание. Давай уничтожим передатчик и освободим их!",,"Dessa stackars själar är drönare, deras synaptiska funktioner är blockerade av RC-implantat. Vi förstör sändaren och de är fria!","Bu zavallı ruhlar dron, sinaptik fonksiyonları RC implantları tarafından engellenmiş. Vericiyi yok edersek özgür kalırlar!" "Command says the transmitter is shielded by a force field. So two birds, one stone, free the drones and practice with the ore.",TXT_SUB_LOG98,STRIFE1.WAD: MAP14,,,"Velení říká, že vysílačka je chráněná silovým polem. Dvě mouchy jednou ranou: osvobodíme vězně a vyzkoušíme si, jak s tou rudou.","Kommandocentralen siger, at senderen er beskyttet af et kraftfelt. Så to fluer i et smæk, befri dronerne og øv dig med malmen.","Die Kommandozentale sagt, der Transmitter sei von einem Kraftfeld geschützt. So, zwei Fliegen, eine Klatsche, befreie die Drohnen und übe mit dem Erz.",,,"El Comando dice que el transmisor está protegido por un campo de fuerza. Dos pájaros de un tiro, libera a los zánganos y practica con el mineral.",,"Komentokeskus sanoo, että lähetin on voimakentän suojaama. Siispä kaksi kärpästä yhdellä iskulla: vapautamme kuhnurit ja samalla harjoittelemme malmilla.","La commandement me dit que le transmetteur est protégé par un champ de force. Ca fait d'une pierre de coups. On libère les drones, et on s'entraîne avec le minerai.",Az irányítás szerint a jeladó el van szeparálva egy erőpajzzsal. Tehát két légy és egy csapás: szabadítsuk ki a drónokat és gyakoroljunk az érccel.,"Il comando dice che il trasmettitore è protetto da un campo di forza. Quindi, due piccioni con una fava. Liberiamo i droni e facciamo pratica con il minerale.","司令官は送信機がフォースフィールドに守られていると言っていた。 -そこを潰せば鉱山と労働者を解放、一石二鳥だな。",본부가 말하길 전송기는 방어막에 의해 보호받고 있대. 광석을 사용하는 방법을 연습하면서 노예들을 해방한다면 일석이조일 거야.,"Het commando zegt dat de zender is afgeschermd door een krachtveld. Dus twee vogels, een steen, bevrijden de drones en oefenen met het erts.","Kommandoen sier at senderen er beskyttet av et kraftfelt. Så to fluer i en smekk, frigjør dronene og øv med malmen.","Dowództwo mówi, że nadajnik jest osłonięty przez pole siłowe. Więc dwie pieczenie na jednym ogniu, uwolnić drony i poćwiczyć z rudą.",O comando diz que o transmissor está protegido por um campo de força. Dois coelhos numa tacada só. Liberte os zangões e teste o minério.,,"Centrul de comandă e prtejat de un câmp de forță. Deci, două păsări, o piatră.","Штаб говорит, что передатчик защищён силовым полем. Ты освободишь дронов и испытаешь руду — одним выстрелом двух зайцев!",,"Komuta vericinin bir güç alanı tarafından korunduğunu söylüyor. Yani bir taşla iki kuş, dronları serbest bırak ve cevherle pratik yap." +そこを潰せば鉱山と労働者を解放、一石二鳥だな。",본부가 말하길 전송기는 방어막에 의해 보호받고 있대. 광석을 사용하는 방법을 연습하면서 노예들을 해방한다면 일석이조일 거야.,"Het commando zegt dat de zender is afgeschermd door een krachtveld. Dus twee vogels, een steen, bevrijden de drones en oefenen met het erts.","Kommandoen sier at senderen er beskyttet av et kraftfelt. Så to fluer i en smekk, frigjør dronene og øv med malmen.","Dowództwo mówi, że nadajnik jest osłonięty przez pole siłowe. Więc dwie pieczenie na jednym ogniu, uwolnić drony i poćwiczyć z rudą.",O comando diz que o transmissor está protegido por um campo de força. Dois coelhos numa tacada só. Liberte os zangões e teste o minério.,,"Centrul de comandă e prtejat de un câmp de forță. Deci, două păsări, o piatră.","Штаб говорит, что передатчик защищён силовым полем. Ты освободишь дронов и испытаешь руду — одним выстрелом двух зайцев!",,"Ledningen säger att sändaren är skyddad av ett kraftfält. Så två flugor i en smäll, frigör drönarna och öva med malmen.","Komuta vericinin bir güç alanı tarafından korunduğunu söylüyor. Yani bir taşla iki kuş, dronları serbest bırak ve cevherle pratik yap." "My suggestion is, toss the ore at the forcefield and then blast it. The resulting compression should create a magnetic blanket and turn off the lights.",TXT_SUB_LOG99,STRIFE1.WAD: MAP14,,,"Můj návrh je, hoď rudu na to silové pole a pak ji odstřel. Výsledná komprese by měla vytvořit magnetický povlak a vypnout pole.","Mit forslag er, at kaste malmen mod kraftfeltet og derefter sprænge det. Den resulterende kompression skulle skabe et magnetisk tæppe og slukke lyset.","Mein Vorschlag wäre, das Erz vor das Kraftfeld zu legen und dann explodieren zu lassen. Die resultierende Kompression sollte ein Magnetfeld erzeugen und die Lichter ausgehen lassen.",,,"Mi sugerencia es, tirar el mineral hacia el campo de fuerza y luego reventarlo, la presión resultante debería crear un manto magnético y apagar las luces.",,"Ehdotukseni on, että heität malmin voimakentään ja sitten posautat sen. Syntyvän paineaallon pitäisi muodostaa magneettinen peitto ja sammuttaa valot.",Ma suggestion: jette le minerai sur le champ de force puis tire dessus. La compression qui en résulte devrait créer un champ magnétique qui va désactiver les lumières.,"Az a tanácsom, hogy dobd az ércet az erőpajzsra, és robbantsd fel. A keletkező kompresszió egy mágneses takarót kéne hogy képezzen, így kikapcsolva a fényeket.","Il mio consiglio è, lancia uno dei minerali al campo di forza e poi fallo saltare in aria. Questo dovrebbe sprigionare l'energia sufficiente a disattivare il campo di forza.","私の案はフォースフィールドの近くに鉱石を置き撃って爆発させる方法よ。 -その結果、圧縮されていた磁場の反動で光を打ち消すわ。","조언을 찾는다면, 광석을 방어막에 가까이 놔둔 뒤 쏴봐. 광석이 커다란 자기장을 만들 테고, 방어막을 완전히 무력화 시킬 거야. 불 끄는거지!",Mijn suggestie is om het erts naar het krachtveld te gooien en het vervolgens op te blazen. De resulterende compressie zou een magnetische deken moeten creëren en de lichten moeten doven.,Mitt forslag er å kaste malmen mot kraftfeltet og sprenge det. Den resulterende kompresjonen bør skape et magnetisk teppe og slå av lysene.,Proponuję rzucić rudę w pole siłowe i wysadzić je. Powstała kompresja powinna stworzyć koc magnetyczny i wyłączyć światła.,Minha sugestão é que você arremesse o minério no campo de força e o detone. A explosão vai criar um campo magnético e apagar as luzes.,,"Sugstia mea e, aruncă minereul în scut și aruncă-l în aer. Comprimarea rezultată ar trebui să creeze un câmp magnetic care sp oprească luminile.","Мой план: бросить руду поближе к силовому полю и взорвать её. Взрыв создаст магнитное поле, которое накроет электронику и отрубит её.",,"Benim önerim, cevheri güç alanına fırlatın ve sonra patlatın. Ortaya çıkan sıkıştırma manyetik bir örtü oluşturmalı ve ışıkları kapatmalı." -Now on to the factory. Exit the mines and you can't miss it!,TXT_SUB_LOG100,STRIFE1.WAD: MAP16,,,A teď do továrny. Vyjdi z dolů a nemůžeš to minout.,"Nu videre til fabrikken. Gå ud af minerne, og du kan ikke undgå at se den!",Und nun zur Fabrik. Verlasse die Minen und du kannst sie nicht verpassen.,,,Ahora vamos a la fábrica. ¡Sal de las minas y no puedes perderlo!,,"Nyt sitten tehtaaseen. Poistu kaivoksesta, ja löydät sen varmasti!","Bon, maintenant, l'usine! Sors des mines et tu peux pas la rater!",Most pedig irány a gyár. Kilépve a bányából nem tudod eltéveszteni.,Ora entriamo nella Fabbrica. Uscendo dalle miniere non puoi sbagliare.,今すぐ工場へ向かおう。鉱山を出たら見逃すなよ!,이제 공장으로 향하자. 광산을 나가면 더 재밌는 모험이 펼쳐질 거야!,Nu naar de fabriek. Verlaat de mijnen en je kunt het niet missen!,"Nå videre til fabrikken. Gå ut av gruvene, og du kan ikke gå glipp av den!",Teraz przejdź do fabryki. Wyjdź z kopalni i nie możesz jej przegapić!,"Agora, para a fábrica. Saia das minas e não vai ter como errar.",,Acum către fabrică. Ieși din mine și nu o poți rata.,"Теперь — на фабрику. Выйди из шахты, и ты сразу увидишь вход!",,Şimdi fabrikaya gidelim. Madenlerden çıkın ve onu kaçırmayın! -"Sorry, hero, this is all new to me.",TXT_SUB_LOG101,STRIFE1.WAD: MAP20,,,"Promiň, hrdino, tohle všechno je pro mě nové.","Undskyld, helt, det er alt sammen nyt for mig.","Entschuldigung, mein Held, das ist alles neu für mich.",,,"Lo siento, héroe, esto es nuevo para mí.",,"Pahoittelut, sankari; tämä kaikki on uutta minulle.","Désolé, héros, tout cela est nouveau pour moi.","Sajnálom hősöm, ez mind rendkívűl új számomra.","Mi spiace, eroe, ma tutto ciò è nuovo per me.",ごめんなさい、これは初耳なの。,"미안, 영웅 친구... 이런 곳은 처음 봐.","Sorry, held, dit is allemaal nieuw voor mij.","Beklager, helt, dette er nytt for meg.","Wybacz, bohaterze, to wszystko jest dla mnie nowe.","Foi mal, meu herói, tudo isso é novo pra mim.",,"Scuze, eroule, asta e nou pentru mine.","Извини, герой. Для меня это всё в новинку.",,"Üzgünüm kahraman, bunların hepsi benim için yeni." -I'm reading massive neural wave distortions from straight ahead. I think we've found it.,TXT_SUB_LOG102,STRIFE1.WAD: MAP20,,,"Detekuju obří rušení nervových vln přímo před námi. Myslím, že jsme to našli.","Jeg læser massive neurale bølgeforvridninger lige forude. Jeg tror, vi har fundet det.","Ich empfange massive neurale Verzerrungen direkt voraus. Ich denke, wir haben sie gefunden.",,,Estoy leyendo distorsiones de ondas neuronales masivas adelante. Creo que la hemos encontrado.,Estoy leyendo distorsiones neuronales masivas adelante. Creo que la hemos encontrado.,Havaitsen massivisia hermoaaltovääristymiä suoraan edessä. Luulen löytäneemme sen.,Je recois des distorsions neurales colossales devant nous. Je crois que nous l'avons trouvé. ,Erős ideghullám zavaró jeleket fogok. Azt hiszem megtaláltuk.,Sto ricevendo potenti segnali distorti proprio davanti a te. Penso che l'abbiamo trovata.,重い神経波の歪曲が直に届いたわ。私達はそれを見つけたという事よ。,앞쪽에서 거대한 신경교란 파장이 감지되고 있어. 우리가 찾아낸 것 같아.,Ik lees enorme neurale golfvervormingen van rechtdoor. Ik denk dat we het gevonden hebben.,Jeg leser massive nevrale bølgeforvrengninger rett fram. Jeg tror vi har funnet den.,Odczytuję masywne zakłócenia fal neuronowych z prostej drogi. Chyba to znaleźliśmy.,Estou captando enormes distorções de rede neural mais adiante. Acho que encontramos.,,Citesc distorsiuni neurale masive drept din față. Cred că am găsit-o.,"Я вижу мощный источник помех прямо по курсу. Похоже, мы нашли конвертер.",,Tam karşıdan büyük sinirsel dalga bozulmaları okuyorum. Sanırım onu bulduk. +その結果、圧縮されていた磁場の反動で光を打ち消すわ。","조언을 찾는다면, 광석을 방어막에 가까이 놔둔 뒤 쏴봐. 광석이 커다란 자기장을 만들 테고, 방어막을 완전히 무력화 시킬 거야. 불 끄는거지!",Mijn suggestie is om het erts naar het krachtveld te gooien en het vervolgens op te blazen. De resulterende compressie zou een magnetische deken moeten creëren en de lichten moeten doven.,Mitt forslag er å kaste malmen mot kraftfeltet og sprenge det. Den resulterende kompresjonen bør skape et magnetisk teppe og slå av lysene.,Proponuję rzucić rudę w pole siłowe i wysadzić je. Powstała kompresja powinna stworzyć koc magnetyczny i wyłączyć światła.,Minha sugestão é que você arremesse o minério no campo de força e o detone. A explosão vai criar um campo magnético e apagar as luzes.,,"Sugstia mea e, aruncă minereul în scut și aruncă-l în aer. Comprimarea rezultată ar trebui să creeze un câmp magnetic care sp oprească luminile.","Мой план: бросить руду поближе к силовому полю и взорвать её. Взрыв создаст магнитное поле, которое накроет электронику и отрубит её.",,Mitt förslag är att kasta malmen mot kraftfältet och sedan spränga det. Den resulterande kompressionen bör skapa ett magnetiskt täcke och släcka ljuset.,"Benim önerim, cevheri güç alanına fırlatın ve sonra patlatın. Ortaya çıkan sıkıştırma manyetik bir örtü oluşturmalı ve ışıkları kapatmalı." +Now on to the factory. Exit the mines and you can't miss it!,TXT_SUB_LOG100,STRIFE1.WAD: MAP16,,,A teď do továrny. Vyjdi z dolů a nemůžeš to minout.,"Nu videre til fabrikken. Gå ud af minerne, og du kan ikke undgå at se den!",Und nun zur Fabrik. Verlasse die Minen und du kannst sie nicht verpassen.,,,Ahora vamos a la fábrica. ¡Sal de las minas y no puedes perderlo!,,"Nyt sitten tehtaaseen. Poistu kaivoksesta, ja löydät sen varmasti!","Bon, maintenant, l'usine! Sors des mines et tu peux pas la rater!",Most pedig irány a gyár. Kilépve a bányából nem tudod eltéveszteni.,Ora entriamo nella Fabbrica. Uscendo dalle miniere non puoi sbagliare.,今すぐ工場へ向かおう。鉱山を出たら見逃すなよ!,이제 공장으로 향하자. 광산을 나가면 더 재밌는 모험이 펼쳐질 거야!,Nu naar de fabriek. Verlaat de mijnen en je kunt het niet missen!,"Nå videre til fabrikken. Gå ut av gruvene, og du kan ikke gå glipp av den!",Teraz przejdź do fabryki. Wyjdź z kopalni i nie możesz jej przegapić!,"Agora, para a fábrica. Saia das minas e não vai ter como errar.",,Acum către fabrică. Ieși din mine și nu o poți rata.,"Теперь — на фабрику. Выйди из шахты, и ты сразу увидишь вход!",,Nu till fabriken. Gå ut ur gruvorna och du kan inte missa den!,Şimdi fabrikaya gidelim. Madenlerden çıkın ve onu kaçırmayın! +"Sorry, hero, this is all new to me.",TXT_SUB_LOG101,STRIFE1.WAD: MAP20,,,"Promiň, hrdino, tohle všechno je pro mě nové.","Undskyld, helt, det er alt sammen nyt for mig.","Entschuldigung, mein Held, das ist alles neu für mich.",,,"Lo siento, héroe, esto es nuevo para mí.",,"Pahoittelut, sankari; tämä kaikki on uutta minulle.","Désolé, héros, tout cela est nouveau pour moi.","Sajnálom hősöm, ez mind rendkívűl új számomra.","Mi spiace, eroe, ma tutto ciò è nuovo per me.",ごめんなさい、これは初耳なの。,"미안, 영웅 친구... 이런 곳은 처음 봐.","Sorry, held, dit is allemaal nieuw voor mij.","Beklager, helt, dette er nytt for meg.","Wybacz, bohaterze, to wszystko jest dla mnie nowe.","Foi mal, meu herói, tudo isso é novo pra mim.",,"Scuze, eroule, asta e nou pentru mine.","Извини, герой. Для меня это всё в новинку.",,"Ledsen, hjälte, allt detta är nytt för mig.","Üzgünüm kahraman, bunların hepsi benim için yeni." +I'm reading massive neural wave distortions from straight ahead. I think we've found it.,TXT_SUB_LOG102,STRIFE1.WAD: MAP20,,,"Detekuju obří rušení nervových vln přímo před námi. Myslím, že jsme to našli.","Jeg læser massive neurale bølgeforvridninger lige forude. Jeg tror, vi har fundet det.","Ich empfange massive neurale Verzerrungen direkt voraus. Ich denke, wir haben sie gefunden.",,,Estoy leyendo distorsiones de ondas neuronales masivas adelante. Creo que la hemos encontrado.,Estoy leyendo distorsiones neuronales masivas adelante. Creo que la hemos encontrado.,Havaitsen massivisia hermoaaltovääristymiä suoraan edessä. Luulen löytäneemme sen.,Je recois des distorsions neurales colossales devant nous. Je crois que nous l'avons trouvé. ,Erős ideghullám zavaró jeleket fogok. Azt hiszem megtaláltuk.,Sto ricevendo potenti segnali distorti proprio davanti a te. Penso che l'abbiamo trovata.,重い神経波の歪曲が直に届いたわ。私達はそれを見つけたという事よ。,앞쪽에서 거대한 신경교란 파장이 감지되고 있어. 우리가 찾아낸 것 같아.,Ik lees enorme neurale golfvervormingen van rechtdoor. Ik denk dat we het gevonden hebben.,Jeg leser massive nevrale bølgeforvrengninger rett fram. Jeg tror vi har funnet den.,Odczytuję masywne zakłócenia fal neuronowych z prostej drogi. Chyba to znaleźliśmy.,Estou captando enormes distorções de rede neural mais adiante. Acho que encontramos.,,Citesc distorsiuni neurale masive drept din față. Cred că am găsit-o.,"Я вижу мощный источник помех прямо по курсу. Похоже, мы нашли конвертер.",,Jag läser massiva neurala vågförvrängningar rakt fram. Jag tror att vi har hittat den.,Tam karşıdan büyük sinirsel dalga bozulmaları okuyorum. Sanırım onu bulduk. Just when I think we've seen it all! They go in human and come out... I dont even want to think about it.,TXT_SUB_LOG103,STRIFE1.WAD: MAP24,,,"Zrovna, když jsem myslela, že jsme už viděli všechno! Dovnitř jdou jako lidé a ven vyjdou... ani na to nechci myslet.","Lige når jeg tror, vi har set det hele! De går ind i et menneske og kommer ud... Jeg vil ikke engang tænke på det.","Und da denkt man, man hätte schon alles gesehen. Die kommen als Menschen rein und kommen raus als... Ich möchte gar nicht drüber nachdenken.",,,¡Justo cuando creía haberlo visto todo! Entran humanos y salen... No quiero ni pensarlo. ,¡Justo cuando creía haberlo visto todo! Entran humanos y salen... No quiero ni pensarlo.,Juuri kun luulen nähneemme kaiken! He menevät sisään ihmisinä ja tulevat ulos... En halua edes ajatellakaan sitä.,"Et quand je pense avoir tout vu.. Des humains entrent, et puis.. Non, je ne veux pas y penser. ","Amikor azt hittem, hogy mindent láttunk. Emberként mennek be, és úgy jönnek ki mint egy...nem is akarok rá gondolni.",E io che pensavo di averle viste tutte! Entrano umani ed escono fuori... Non ci voglio neanche pensare.,"今まで見てきたことについて考えている! -奴は人の内部から出てくる...それについて考えたくないわ。",이렇게 끔찍한 모습을 보게 되다니! 멀쩡한 사람이 저곳에 들어갔다 나온 모습을... 차마 생각하기도 싫어.,Net nu ik denk dat we het allemaal hebben gezien! Ze gaan in de mens en komen eruit.... Ik wil er niet eens over nadenken.,Akkurat når jeg tror vi har sett alt! De går inn som mennesker og kommer ut... Jeg vil ikke engang tenke på det.,"Właśnie wtedy, gdy myślałem, że widzieliśmy już wszystko! Wchodzą w człowieka i wychodzą... Nawet nie chcę o tym myśleć.",E eu achei que já tinha visto de tudo! Eles entram humanos e saem... eu não quero nem pensar nisso.,,Tocmai când credeam că am văzut tot! Intră oameni și ies... nici nu vreau să mă gândesc.,"А я-то думала, что хуже уже не будет! Они входят людьми, а выходят... Не хочу даже думать об этом.",,Tam da her şeyi gördüğümüzü düşündüğüm anda! İnsana giriyorlar ve çıkıyorlar. Bunu düşünmek bile istemiyorum. +奴は人の内部から出てくる...それについて考えたくないわ。",이렇게 끔찍한 모습을 보게 되다니! 멀쩡한 사람이 저곳에 들어갔다 나온 모습을... 차마 생각하기도 싫어.,Net nu ik denk dat we het allemaal hebben gezien! Ze gaan in de mens en komen eruit.... Ik wil er niet eens over nadenken.,Akkurat når jeg tror vi har sett alt! De går inn som mennesker og kommer ut... Jeg vil ikke engang tenke på det.,"Właśnie wtedy, gdy myślałem, że widzieliśmy już wszystko! Wchodzą w człowieka i wychodzą... Nawet nie chcę o tym myśleć.",E eu achei que já tinha visto de tudo! Eles entram humanos e saem... eu não quero nem pensar nisso.,,Tocmai când credeam că am văzut tot! Intră oameni și ies... nici nu vreau să mă gândesc.,"А я-то думала, что хуже уже не будет! Они входят людьми, а выходят... Не хочу даже думать об этом.",,Precis när jag tror att vi har sett allt! De går in i en människa och kommer ut... Jag vill inte ens tänka på det.,Tam da her şeyi gördüğümüzü düşündüğüm anda! İnsana giriyorlar ve çıkıyorlar. Bunu düşünmek bile istemiyorum. The Oracle was right. Macil's gone nuts. He just knowingly sent 200 men to their death. I want vengeance. For the dead and for the living dead!,TXT_SUB_LOG104,STRIFE1.WAD: MAP24,,,Věštec měl pravdu. Macil zešílel. Vědomě poslal dvě stě mužů na smrt. Chci odplatu - za mrtvé i živé mrtvé!,Oraklet havde ret. Macil er blevet skør. Han har lige bevidst sendt 200 mænd i døden. Jeg vil have hævn. For de døde og for de levende døde!,Das Orakel hatte Recht. Macil hat den Verstand verloren. Er hat gerade absichtlich 200 unserer Leute in den Tod geschickt. Ich will Rache! Für die Toten und für die lebenden Toten.,,,Macil se ha vuelto loco. Conscientemente ha enviado 200 hombres a su muerte. ¡Quiero venganza! ¡Por los muertos y los muertos vivientes!,Macil se ha vuelto loco. Conscientemente envió a 200 hombres a su muerte. ¡Quiero venganza! Por los muertos y por los muertos vivientes!,"Oraakkeli oli oikeassa: Macil on tullut hulluksi. Hän juuri lähetti tietoisesti 200 miestä surmaansa. Vaadin kostoa, sekä kuolleitten että elävien kuolleitten puolesta!","Macil a complètement perdu les pédales! Il a envoyé 200 hommes se faire tuer, et il le savait! Il faut les venger, pour eux et pour leurs camarades!",Az Orákulumnak igaza volt. macil megőrült. Szándékosan küldött 200 emberünket a halálába. Meg akarom bosszúlni a halottak és az élő halottak nevében!,L'Oracolo aveva ragione. Macil deve essere impazzito. Ha mandato consciamente 200 uomini verso la morte. Voglio vendetta! Per i morti e per i morti viventi!,"オラクルが正しかった。マシルはイカれていたなんて。 彼は故意に200人以上の人々を死に追いやっていた。 -復讐しなくては。死んだ人達の為、そして今生きている人達の為にも!",마실이 정신 나갔나 봐. 모든 것을 알면서도 200 명이나 되는 병력을 보내서 죽게 했어. 과부들과 망령들을 위한 복수를 할 시간이야!,Het Orakel had gelijk. Macil is gek geworden. Hij stuurde gewoon bewust 200 mannen naar hun dood. Ik wil wraak. Voor de doden en voor de levende doden!,Oraklet hadde rett. Macil har gått fra vettet. Han sendte 200 menn i døden med viten og vilje. Jeg vil ha hevn. For de døde og for de levende døde!,Wyrocznia miała rację. Macilowi odbiło. Właśnie świadomie wysłał 200 ludzi na śmierć. Chcę zemsty. Za zmarłych i za żywych zmarłych!,O Oráculo estava certo. O Macil enlouqueceu. Ele mandou 200 homens para as suas mortes sabendo disso. Eu quero vingança. Pelos mortos e pelos mortos-vivos!,,Oracolul avea dreptate. Macil a înnebunit. A trimis în mod voit 200 oameni la moarte. Vreau răzbunare! Pentru morți și morții vii!,Оракул сказал правду: Мэйсил озверел. Он намеренно послал двести человек на верную смерть. Я жажду мести! За убитых и за живых мертвецов!,,Kahin haklıydı. Macil delirmiş. Bile bile 200 adamı ölüme gönderdi. İntikam istiyorum. Ölüler ve yaşayan ölüler için! -"Macil? Infected and with a Sigil piece. All these years of believing in him, in the cause. And for what?",TXT_SUB_LOG105,,,,"Macil? Nakažený a s dílem Pečeti? Všechny ty roky, kdy jsme mu a naší věci důvěřovali. A k čemu?","Macil? Inficeret og med et Sigil stykke. I alle disse år har jeg troet på ham, på sagen. Og for hvad?","Macil? Infiziert und mit einen Sigli-Teil? All diese Jahre, die ich an ihn geglaubt habe - an die Sache. Und für was?",,,"¿Macil? Infectado con una pieza del Emblema. Todos estos años de creer en el, en la causa. ¿Y para que?",,"Macil, tartunnan saanut ja pitää hallussaan Sinetin osasta? Kaikki nämä vuodet uskoen häneen, aatteeseen. Ja minkä tähden?",Macil? Infecté par une pièce du Sigil. Toutes ces années où je lui ai fait confiance.. à la cause.. Et pour quoi à la fin?,"Macil? Meg van fertőzve, és van nála egy Pecsét darab is. Én pedig hittem neki évekig, hittem az ügyben. És miért?","Macil? Infettato e con un pezzo del Sigillo. Tutti questi anni passati a credere in lui, e alla causa. E per cosa?",,마실? 시질 조각에 의해 오염됬어. 수 년 동안 믿어온 우리가 바보인가? 아니면 이 운명을 피할 수 없었던 걸까?,"Macil? Geïnfecteerd en met een Sigil stuk. Al die jaren van geloof in hem, in de oorzaak. En waarvoor?","Macil? Infisert og med en Sigil-brikke. I alle disse årene har jeg trodd på ham, på saken... Og for hva?","Macil? Zainfekowany i z kawałkiem Sigil. Przez te wszystkie lata wierzyłem w niego, w sprawę. I po co?","Macil? Infectado e com uma peça do Sigilo. Todos esses anos acreditando nele, acreditando na causa. E pra quê?",,"Macil? Infectat și cu o bucată de Sigiliu. Toți anii crezând în cauza lui, și pentru ce?","Мэйсил? Заражённый... И у него фрагмент Печати. Все эти годы я верила ему, верила в нашу миссию. А теперь?",,"Macil mi? Enfekte olmuş ve bir Sigil parçasıyla. Bunca yıl ona inandım, davaya inandım. Peki ne için?" +復讐しなくては。死んだ人達の為、そして今生きている人達の為にも!",마실이 정신 나갔나 봐. 모든 것을 알면서도 200 명이나 되는 병력을 보내서 죽게 했어. 과부들과 망령들을 위한 복수를 할 시간이야!,Het Orakel had gelijk. Macil is gek geworden. Hij stuurde gewoon bewust 200 mannen naar hun dood. Ik wil wraak. Voor de doden en voor de levende doden!,Oraklet hadde rett. Macil har gått fra vettet. Han sendte 200 menn i døden med viten og vilje. Jeg vil ha hevn. For de døde og for de levende døde!,Wyrocznia miała rację. Macilowi odbiło. Właśnie świadomie wysłał 200 ludzi na śmierć. Chcę zemsty. Za zmarłych i za żywych zmarłych!,O Oráculo estava certo. O Macil enlouqueceu. Ele mandou 200 homens para as suas mortes sabendo disso. Eu quero vingança. Pelos mortos e pelos mortos-vivos!,,Oracolul avea dreptate. Macil a înnebunit. A trimis în mod voit 200 oameni la moarte. Vreau răzbunare! Pentru morți și morții vii!,Оракул сказал правду: Мэйсил озверел. Он намеренно послал двести человек на верную смерть. Я жажду мести! За убитых и за живых мертвецов!,,Oraklet hade rätt. Macil har blivit galen. Han skickade just medvetet 200 män i döden. Jag vill ha hämnd. För de döda och för de levande döda!,Kahin haklıydı. Macil delirmiş. Bile bile 200 adamı ölüme gönderdi. İntikam istiyorum. Ölüler ve yaşayan ölüler için! +"Macil? Infected and with a Sigil piece. All these years of believing in him, in the cause. And for what?",TXT_SUB_LOG105,,,,"Macil? Nakažený a s dílem Pečeti? Všechny ty roky, kdy jsme mu a naší věci důvěřovali. A k čemu?","Macil? Inficeret og med et Sigil stykke. I alle disse år har jeg troet på ham, på sagen. Og for hvad?","Macil? Infiziert und mit einen Sigli-Teil? All diese Jahre, die ich an ihn geglaubt habe - an die Sache. Und für was?",,,"¿Macil? Infectado con una pieza del Emblema. Todos estos años de creer en el, en la causa. ¿Y para que?",,"Macil, tartunnan saanut ja pitää hallussaan Sinetin osasta? Kaikki nämä vuodet uskoen häneen, aatteeseen. Ja minkä tähden?",Macil? Infecté par une pièce du Sigil. Toutes ces années où je lui ai fait confiance.. à la cause.. Et pour quoi à la fin?,"Macil? Meg van fertőzve, és van nála egy Pecsét darab is. Én pedig hittem neki évekig, hittem az ügyben. És miért?","Macil? Infettato e con un pezzo del Sigillo. Tutti questi anni passati a credere in lui, e alla causa. E per cosa?",,마실? 시질 조각에 의해 오염됬어. 수 년 동안 믿어온 우리가 바보인가? 아니면 이 운명을 피할 수 없었던 걸까?,"Macil? Geïnfecteerd en met een Sigil stuk. Al die jaren van geloof in hem, in de oorzaak. En waarvoor?","Macil? Infisert og med en Sigil-brikke. I alle disse årene har jeg trodd på ham, på saken... Og for hva?","Macil? Zainfekowany i z kawałkiem Sigil. Przez te wszystkie lata wierzyłem w niego, w sprawę. I po co?","Macil? Infectado e com uma peça do Sigilo. Todos esses anos acreditando nele, acreditando na causa. E pra quê?",,"Macil? Infectat și cu o bucată de Sigiliu. Toți anii crezând în cauza lui, și pentru ce?","Мэйсил? Заражённый... И у него фрагмент Печати. Все эти годы я верила ему, верила в нашу миссию. А теперь?",,"Macil? Infekterad och med en Sigil-bit. Under alla dessa år har jag trott på honom, på saken. Och för vad?","Macil mi? Enfekte olmuş ve bir Sigil parçasıyla. Bunca yıl ona inandım, davaya inandım. Peki ne için?" "Richter reports that the factory we destroyed leads to a ""lab"", and they're getting a Sigil power signature from within. Back to the factory and our next step to freedom.",TXT_SUB_LOG106,"STRIFE1.WAD: MAP10 (After killing Macil while having destroyed the converter in MAP24)",,,"Richter hlásí, že továrna, kterou jsme zničili, vede do „laboratoře“ a detekují z ní energii Pečetě. Zpátky do továrny a našemu dalšímu kroku ke svobodě.","Richter rapporterer, at den fabrik, vi ødelagde, fører til et ""laboratorium"", og at de får en Sigil-kraftsignatur derindefra. Tilbage til fabrikken og vores næste skridt mod frihed.","Richter sagt, in der Fabrik, die wir zerstört haben, gäbe es ein „Labor“, und dort gibt es eine Sigil-Signatur. Zurück zur Fabrik und dem nächsten Schritt zu unserer Freiheit.",,,"Richter informa de que la fábrica que destruimos conduce a un ""laboratorio"", y están recibiendo una señal de poder del Emblema de adentro. De vuelta a la fábrica y nuestro siguiente paso a la libertad.",,"Richter ilmoittaa, että tuhoamamme tehdas johtaa ""laboratorioon"", ja he lukevat sisältä Sinettiosasen energiajälkiä. Takaisin tehtaaseen ja kohti seuraavaa askeltamme vapauteen.","Richter rapporte que l'usine que l'on a détruit mène à un ""laboratoire"" et qu'il s'y trouve une signature de pièce du Sigil à l'intérieur. Retourne à l'usine et on fera un autre pas vers la liberté.","Richter jelentése szerint a felrobbantott gyár egy ""laboratóriumba"" vezet, és a Pecsét jelét sugározza belülről. Tehát a szabadságunk felé teendő következő lépés a gyárnál kezdődik.","Richter ci comunica che la Fabbrica che abbiamo distrutto porta a un ""laboratorio"", ed al suo interno è stato identificato un segnale di un pezzo del Sigillo. Ritorniamo alla fabbrica e il nostro prossimo passo per la libertà.","リヒターの報告では我々が破壊した工場は'研究所'に繋がっていて、 -奴等はシジルの調印を内部から得ている。工場に戻って自由への次の段階に進みましょう",릭터가 말하길 우리가 파괴한 공장은 연구소로 향하는 길이 있대. 그리고 그곳에는 시질 특유의 힘이 감지됐어. 공장으로 돌아가서 자유를 위해 계속 투쟁을 하자.,"Richter meldt dat de fabriek die we vernietigd hebben, leidt naar een ""lab"", en ze krijgen een Sigil power signatuur van binnenuit. Terug naar de fabriek en onze volgende stap naar vrijheid.","Richter rapporterer at fabrikken vi ødela fører til en ""lab"", og at de får en Sigil-kraftsignatur innenfra. Tilbake til fabrikken og vårt neste skritt mot frihet.","Richter donosi, że zniszczona przez nas fabryka prowadzi do ""laboratorium"", a oni otrzymują z niego sygnaturę mocy Sigil. Wracamy do fabryki i naszego kolejnego kroku do wolności.","O Richter disse que a fábrica que destruímos leva a um ""laboratório"" e eles estão captando um sinal de energia lá de dentro. De volta à fábrica e ao nosso próximo passo à liberdade.",,"Richter raportează că fabrica duce către un laborator, și sunt alimentați e puterea unui Sigiliu din interior. Înapoi la fabrică și următorul pas spre libertate.","Рихтер сообщает, что за разрушенной нами фабрикой лежит «лаборатория», и мы засекли характерную энергию фрагмента Печати, исходящую оттуда. Возвращайся на фабрику — сделаем ещё один шаг к нашему освобождению.",,"Richter, yok ettiğimiz fabrikanın bir laboratuvara çıktığını ve oradan Sigil gücü sinyali aldıklarını bildirdi. Fabrikaya ve özgürlüğe giden bir sonraki adımımıza dönelim." +奴等はシジルの調印を内部から得ている。工場に戻って自由への次の段階に進みましょう",릭터가 말하길 우리가 파괴한 공장은 연구소로 향하는 길이 있대. 그리고 그곳에는 시질 특유의 힘이 감지됐어. 공장으로 돌아가서 자유를 위해 계속 투쟁을 하자.,"Richter meldt dat de fabriek die we vernietigd hebben, leidt naar een ""lab"", en ze krijgen een Sigil power signatuur van binnenuit. Terug naar de fabriek en onze volgende stap naar vrijheid.","Richter rapporterer at fabrikken vi ødela fører til en ""lab"", og at de får en Sigil-kraftsignatur innenfra. Tilbake til fabrikken og vårt neste skritt mot frihet.","Richter donosi, że zniszczona przez nas fabryka prowadzi do ""laboratorium"", a oni otrzymują z niego sygnaturę mocy Sigil. Wracamy do fabryki i naszego kolejnego kroku do wolności.","O Richter disse que a fábrica que destruímos leva a um ""laboratório"" e eles estão captando um sinal de energia lá de dentro. De volta à fábrica e ao nosso próximo passo à liberdade.",,"Richter raportează că fabrica duce către un laborator, și sunt alimentați e puterea unui Sigiliu din interior. Înapoi la fabrică și următorul pas spre libertate.","Рихтер сообщает, что за разрушенной нами фабрикой лежит «лаборатория», и мы засекли характерную энергию фрагмента Печати, исходящую оттуда. Возвращайся на фабрику — сделаем ещё один шаг к нашему освобождению.",,"Richter rapporterar att fabriken som vi förstörde leder till ett ""labb"" och att de får en Sigil-kraftsignatur därifrån. Tillbaka till fabriken och vårt nästa steg mot frihet.","Richter, yok ettiğimiz fabrikanın bir laboratuvara çıktığını ve oradan Sigil gücü sinyali aldıklarını bildirdi. Fabrikaya ve özgürlüğe giden bir sonraki adımımıza dönelim." Who dares to defy me and enter my fortress? A worthless human? Face me and die!,TXT_SUB_LOG120,MAP16: Entrance → Central door.,,,Kdo se to opovažuje mi vzdorovat a vkročit do mé pevnosti? Bezcenný člověk? Postav se mi a zemři!,Hvem vover at trodse mig og gå ind i min fæstning? Et værdiløst menneske? Se mig i øjnene og dø!,Wer wagt es mir zu trotzen und meine Festung zu betreten? Ein wertloser Mensch? Stelle dich mir und stirb!,,,¿Quién se atreve a desafiarme y entrar en mi fortaleza? ¿Un insignificante humano? ¡Enfréntate a mí y muere!,¿Quién se atreve a desafiarme y entrar a mi fortaleza? ¿Un insignificante humano? ¡Enfréntate a mí y muere!,Kuka kehtaa uhmata minua ja astua sisään linnoitukseeni? Arvoton ihminen? Kohtaa minut ja kuole!,Qui ose me défier et pénétrer ma forteresse? Un humain sans valeur? Faites face à moi et mourrez!,"Ki mer belépni az erődítményebe és ellenszegülni nekem? Egy jelentéktelen ember? Gyere állj ki ellenem, had szedjelek szét!",Chi osa sfidarmi ed entrare nella mia fortezza? Un inutile umano? Affrontami e muori!,"我に歯向かう為に敢えて私の要塞に来たのか?無価値な人間よ? -死をくれてやろう!",감히 어떤 자가 이 몸을 반역하고 요새를 침입한 것이더냐? 나약한 인간이구나. 이 몸의 의해 소멸당해라.,Wie durft mij uit te dagen en mijn vesting binnen te gaan? Een waardeloos mens? Kijk me aan en sterf!,Hvem våger å trosse meg og gå inn i festningen min? Et verdiløst menneske? Møt meg og dø!,Kto ośmieli się przeciwstawić mi i wejść do mojej twierdzy? Bezwartościowy człowiek? Zmierz się ze mną i zgiń!,Quem ousa me desafiar e entrar na minha fortaleza? Um humano insignificante? Enfrente-me e morra!,,Cine îndrăznește să mă înfrunte? Un om jalnic? Înfruntă-mă și mori!,Кто смеет бросать мне вызов и вторгаться в мою крепость? Жалкий человечишка? Сразись со мной и умри!,,Kim bana meydan okuyup kaleme girmeye cüret eder? Değersiz bir insan mı? Benimle yüzleş ve öl! -You cannot kill me. You are just human. And I am more than human.,TXT_SUB_LOG121,STRIFE1.WAD: MAP16,,,Nemůžeš mě zabít. Jsi jen člověk a já jsem víc než člověk.,Du kan ikke dræbe mig. Du er bare et menneske. Og jeg er mere end et menneske.,Du kannst mich nicht töten. Du bist nur ein Mensch. Und ich bin mehr als das.,,,No puedes matarme. Eres solo humano. Y yo soy más que humano.,,"Et voi tappaa minua. Sinä olet vain ihminen, ja minä olen enemmän kuin ihminen.",Vous ne pouvez me tuer. Vous n'êtes qu'un humain. Je suis plus qu'un humain.,Nem tudsz megölni. Csak egy ember vagy. Én pedig már több vagyok mint ember.,Non puoi uccidermi. Tu sei solo umano. E io sono più che umano.,我を殺すことはできまい。貴様は人間。そして私は人間を超えし者だ。,"이 몸은 너에게 사살 당할 수 없다. 이 몸은 초월한 존재, 인간 따위를 넘었기에!",Je kunt me niet doden. Je bent gewoon een mens. En ik ben meer dan een mens.,Du kan ikke drepe meg. Du er bare et menneske. Og jeg er mer enn et menneske.,Nie możesz mnie zabić. Jesteś tylko człowiekiem. A ja jestem czymś więcej niż człowiekiem.,Você não pode me matar. Você é apenas humano. E eu sou mais do que humano.,,"Nu mă poți ucide. Ești doar un om, iar eu sunt mai mult decât atât.","Тебе не убить меня. Ты всего лишь человек. А я нечто большее, чем человек!",,Beni öldüremezsin. Sen sadece insansın. Ve ben insandan daha fazlasıyım. +死をくれてやろう!",감히 어떤 자가 이 몸을 반역하고 요새를 침입한 것이더냐? 나약한 인간이구나. 이 몸의 의해 소멸당해라.,Wie durft mij uit te dagen en mijn vesting binnen te gaan? Een waardeloos mens? Kijk me aan en sterf!,Hvem våger å trosse meg og gå inn i festningen min? Et verdiløst menneske? Møt meg og dø!,Kto ośmieli się przeciwstawić mi i wejść do mojej twierdzy? Bezwartościowy człowiek? Zmierz się ze mną i zgiń!,Quem ousa me desafiar e entrar na minha fortaleza? Um humano insignificante? Enfrente-me e morra!,,Cine îndrăznește să mă înfrunte? Un om jalnic? Înfruntă-mă și mori!,Кто смеет бросать мне вызов и вторгаться в мою крепость? Жалкий человечишка? Сразись со мной и умри!,,Vem vågar trotsa mig och gå in i min fästning? En värdelös människa? Ställ dig inför mig och dö!,Kim bana meydan okuyup kaleme girmeye cüret eder? Değersiz bir insan mı? Benimle yüzleş ve öl! +You cannot kill me. You are just human. And I am more than human.,TXT_SUB_LOG121,STRIFE1.WAD: MAP16,,,Nemůžeš mě zabít. Jsi jen člověk a já jsem víc než člověk.,Du kan ikke dræbe mig. Du er bare et menneske. Og jeg er mere end et menneske.,Du kannst mich nicht töten. Du bist nur ein Mensch. Und ich bin mehr als das.,,,No puedes matarme. Eres solo humano. Y yo soy más que humano.,,"Et voi tappaa minua. Sinä olet vain ihminen, ja minä olen enemmän kuin ihminen.",Vous ne pouvez me tuer. Vous n'êtes qu'un humain. Je suis plus qu'un humain.,Nem tudsz megölni. Csak egy ember vagy. Én pedig már több vagyok mint ember.,Non puoi uccidermi. Tu sei solo umano. E io sono più che umano.,我を殺すことはできまい。貴様は人間。そして私は人間を超えし者だ。,"이 몸은 너에게 사살 당할 수 없다. 이 몸은 초월한 존재, 인간 따위를 넘었기에!",Je kunt me niet doden. Je bent gewoon een mens. En ik ben meer dan een mens.,Du kan ikke drepe meg. Du er bare et menneske. Og jeg er mer enn et menneske.,Nie możesz mnie zabić. Jesteś tylko człowiekiem. A ja jestem czymś więcej niż człowiekiem.,Você não pode me matar. Você é apenas humano. E eu sou mais do que humano.,,"Nu mă poți ucide. Ești doar un om, iar eu sunt mai mult decât atât.","Тебе не убить меня. Ты всего лишь человек. А я нечто большее, чем человек!",,Du kan inte döda mig. Du är bara en människa. Och jag är mer än människa.,Beni öldüremezsin. Sen sadece insansın. Ve ben insandan daha fazlasıyım. "No death, eternal life and more. Much more! This is my task: cyborgs, half flesh, half steel, all to serve the One God. You do not serve? You die! This putz has another piece of the Sigil.",TXT_SUB_LOG122,"Strife: Veteran Edition: MAP12 @@ -12191,14 +12673,15 @@ Denne tosken har enda en bit av sigillet.","Nie ma śmierci, życie wieczne i je Ten pajac ma kolejny kawałek Sigilu.","Nada de morte. Vida eterna e mais, muito mais! Essa é a minha tarefa: cibórgues, metade carne, metade aço, todos servindo ao Deus Único. Se você não serve, você morre! Esse imbecil possui outra peça do Sigilo.",,"Nu moarte, viață eternă, și mai mult decât atât. Mult mai mult! Asta e misiunea mea: oameni cibernetici, jumătate oțel, jumătate carne, toți servind Adevăratul Zeu. Nu serviți? Muriți! Am altă bucată de Sigiliu.","— Никакой смерти. Вечная жизнь, и не только. Гораздо большее. И всё это — моя работа. Киборги — наполовину из плоти, наполовину из стали — всецело служат Единому Богу. Следуй истинной вере или умри! — У этого мудака следующий фрагмент Печати. -",,"Ölüm yok, sonsuz yaşam ve daha fazlası. Çok daha fazlası! Benim görevim bu: Cyborglar, yarı et, yarı çelik, hepsi Tek Tanrı'ya hizmet etmek için. Hizmet etmiyor musun? Ölürsünüz! +",,"Ingen död, evigt liv och mycket mer. Mycket mer! Detta är min uppgift: cyborgs, halvt kött, halvt stål, allt för att tjäna den ende Guden. Du tjänar inte? Du dör! +Den här idioten har ytterligare en bit av Sigillet.","Ölüm yok, sonsuz yaşam ve daha fazlası. Çok daha fazlası! Benim görevim bu: Cyborglar, yarı et, yarı çelik, hepsi Tek Tanrı'ya hizmet etmek için. Hizmet etmiyor musun? Ölürsünüz! Bu salakta Sigil'in bir parçası daha var." "Ha ha! Welcome. I have waited for this moment. I have waited for a fool like you to bring me my freedom. Your tiny planet is mine, and you will wish you were never born! ",TXT_SUB_LOG128,"STRIFE1.WAD: MAP29 (If the player is progressing through the mediocre ending)",,,"Ha há! Vítej. Čekala jsem na tento okamžik. Čekala jsem na blázna jako ty, který by mi přinesl svobodu. Tvá drobná planeta je moje a ty si budeš přát, že ses nikdy nenarodil!","Ha ha! Velkommen. Jeg har ventet på dette øjeblik. Jeg har ventet på at et fjols som dig skulle bringe mig min frihed. Din lille planet er min, og du vil ønske, at du aldrig var blevet født!","Ha ha! Willkommen. Ich habe auf diesen Moment gewartet, dass ein Narr wie du mir meine Freiheit bringt. Dein kleiner Planet ist mein, und du wirst dir wünschen nie geboren worden zu sein!",,,"¡Ha ha! Bienvenido. He estado esperando este momento. He estado esperando a un necio como tú para traerme mi libertad. ¡Tu pequeño planeta es mío, y desearás no haber nacido!",,"Hahaa! Tervetuloa, olen odottanut tätä hetkeä. Olen odottanut kaltaistasi hölmöä tuomaan minulle minun vapauteni. Pikkuinen planeettanne on minun, ja tulet toivomaan, ettet olisi ikinä syntynytkään!","Ha ha! Bienvenue, j'ai attendu ce moment. J'ai attendu qu'un idiot comme vous me rende ma liberté. Votre pathétique planète m'appartient, et bientôt, vous allez tous regretter d'être nés!","Há há! Nincs mit. Erre a pillanatra vágytam. Arra vártom, hogy egy bolond elhozza nekem a szabadságot. A kicsike bolygód immáron az enyém, és azt fogod kívánni hogy bárcsak meg se születtél volna.","Ha ha! Benvenuto. Ho aspettato questo momento. Ho aspettato uno stolto come te per ridarmi la libertà. Il tuo patetico pianeta è nelle mie mani, e tu presto rimpiangerai di essere nato.","ハッハッハ!ようこそ。私はこの瞬間を待ってイタ。 自由を得る為、アンタの様な愚か者を待っていたノダ。 キサマのワクセイはワタシのモノだ、ソシテ生マレタコトニ後悔スルデアロウ。 -","하하, 이 순간만을 기다리고 있었노라. 그대와 같은 어리석은 자가 짐을 풀어줄 순간을. 그대의 조그만 행성은 이제 짐의 것이고, 그대는 태어난 것을 후회하게 될 것이니라!","Ha ha! Welkom. Ik heb op dit moment gewacht. Ik heb gewacht op een dwaas als jij om mij mijn vrijheid te brengen. Jouw kleine planeet is de mijne, en je zult wensen dat je nooit geboren was!","Ha ha! Velkommen. Jeg har ventet på dette øyeblikket. Jeg har ventet på dette øyeblikket. Jeg har ventet på at en tosk som deg skulle gi meg min frihet. Din lille planet er min, og du vil ønske at du aldri ble født!","Ha ha! Witam. Czekałem na tę chwilę. Czekałem, aż taki głupiec jak ty przyniesie mi wolność. Twoja mała planeta jest moja, a ty będziesz żałował, że się nie urodziłeś!",Ha ha! Bem-vindo. Eu esperei por este momento. Esperei por um tolo como você trazer a minha liberdade. O seu planeta insignificante é meu e você vai desejar nunca ter nascido!,,"Ha ha! Bun-venit. Am așteptat momentul. Am așteptat pentru un prost ca tine să îmi aducă libertatea. Planeta la minusculă e a mea, și tu îți vei dori să nu te fii născut!","Ха-ха! Приветствую. Я так долго ждала! Я ждала, что идиот вроде тебя освободит меня. Эта крошечная планета моя, и сейчас ты пожалеешь, что родился на свет!",,Ha ha! Hoş geldiniz. Bu anı bekledim. Senin gibi bir aptalın bana özgürlüğümü getirmesini bekledim. Küçük gezegenin benim olacak ve sen hiç doğmamış olmayı dileyeceksin! +","하하, 이 순간만을 기다리고 있었노라. 그대와 같은 어리석은 자가 짐을 풀어줄 순간을. 그대의 조그만 행성은 이제 짐의 것이고, 그대는 태어난 것을 후회하게 될 것이니라!","Ha ha! Welkom. Ik heb op dit moment gewacht. Ik heb gewacht op een dwaas als jij om mij mijn vrijheid te brengen. Jouw kleine planeet is de mijne, en je zult wensen dat je nooit geboren was!","Ha ha! Velkommen. Jeg har ventet på dette øyeblikket. Jeg har ventet på dette øyeblikket. Jeg har ventet på at en tosk som deg skulle gi meg min frihet. Din lille planet er min, og du vil ønske at du aldri ble født!","Ha ha! Witam. Czekałem na tę chwilę. Czekałem, aż taki głupiec jak ty przyniesie mi wolność. Twoja mała planeta jest moja, a ty będziesz żałował, że się nie urodziłeś!",Ha ha! Bem-vindo. Eu esperei por este momento. Esperei por um tolo como você trazer a minha liberdade. O seu planeta insignificante é meu e você vai desejar nunca ter nascido!,,"Ha ha! Bun-venit. Am așteptat momentul. Am așteptat pentru un prost ca tine să îmi aducă libertatea. Planeta la minusculă e a mea, și tu îți vei dori să nu te fii născut!","Ха-ха! Приветствую. Я так долго ждала! Я ждала, что идиот вроде тебя освободит меня. Эта крошечная планета моя, и сейчас ты пожалеешь, что родился на свет!",,"Ha ha! Välkommen. Jag har väntat på det här ögonblicket. Jag har väntat på att en idiot som du ska ge mig min frihet. Din lilla planet är min, och du kommer att önska att du aldrig föddes!",Ha ha! Hoş geldiniz. Bu anı bekledim. Senin gibi bir aptalın bana özgürlüğümü getirmesini bekledim. Küçük gezegenin benim olacak ve sen hiç doğmamış olmayı dileyeceksin! "The truth can only be found in universal will. You will fall on your knees in front of the True God, the One Light. Join me and I will complete the Sigil. I'm sick of this mystical double talk.",TXT_SUB_LOG129,STRIFE1.WAD: MAP27,,,"- Pravda může být nalezena jedině v přání jsoucna. Padneš na kolena před Pravým bohem, Jedním světlem. Připoj se ke mě a já složím Pečeť. - Tenhle tajemný dvojhlas už mi leze krkem.","Sandheden kan kun findes i den universelle vilje. Du vil falde på knæ foran den sande Gud, det ene lys. Slut dig til mig, og jeg vil fuldende sigilet. @@ -12215,90 +12698,91 @@ Ik ben deze mystieke dubbelzinnigheid beu.","Sannheten kan bare finnes i den uni Jeg er lei av denne mystiske dobbeltkommunikasjonen.","Prawda może być znaleziona tylko w powszechnej woli. Padniesz na kolana przed Prawdziwym Bogiem, Jedynym Światłem. Dołącz do mnie, a ja uzupełnię Sigil. Mam dość tego mistycznego gadania.","A verdade só pode ser encontrada na vontade universal. Você cairá de joelhos na frente do Deus Único, a Luz Única. Junte-se a mim e completarei o Sigilo. Já estou cansada de toda essa ladainha mística.",,"Adevărul poate fi găsit doar în voința universală. Vei cădea în genunchi în fața Adevăratului Zeu, Singura Lumină. Alătură-mi-te și voi completa Sigiliul. M-am săturat de vorbitul ăsta mistic duplicitar.","— Истина одна — она в единой воле. Ты упадёшь на колени пред Истинным Богом, единым светом. Присоединись ко мне, и я соберу Печать! -— Меня тошнит от этой таинственной двуличной болтовни!",,"Gerçek sadece evrensel iradede bulunabilir. Gerçek Tanrı'nın, Tek Işık'ın önünde diz çökeceksin. Bana katılın ve ben de Sigil'i tamamlayayım. +— Меня тошнит от этой таинственной двуличной болтовни!",,"Sanningen kan bara hittas i den universella viljan. Ni kommer att falla på knä framför den sanna guden, det enda ljuset. Gör mig sällskap och jag kommer att fullborda Sigillet. +Jag är trött på detta mystiska dubbelprat.","Gerçek sadece evrensel iradede bulunabilir. Gerçek Tanrı'nın, Tek Işık'ın önünde diz çökeceksin. Bana katılın ve ben de Sigil'i tamamlayayım. Bu mistik ikili konuşmalardan bıktım." "You... You have crushed my Order, torn through my ruses and threatened centuries of desire. But I will prevail, I will infect you and twist you to my will...",TXT_SUB_LOG130,"STRIFE1.WAD: MAP29 (If the player is progressing through the good ending)",,,"Ty... Tys rozdrtil můj Řád, proskočil mými lstmi a ohrozil staletí chtíče. Ale já přetrvám. Já tě nakazím a zkazím, tak, jak chci...","Du... Du har knust min orden, revet mine kneb igennem og truet århundreders begær. Men jeg vil sejre, jeg vil inficere dig og dreje dig til min vilje...","Du... du hast meinen Orden zerstört, meine Fallen überwunden und jahrelange Wünsche gefährdet. Aber ich werde siegen, ich werde dich infizieren und dich meinem Willen beugen...",,,"Tú... Tú has aplastado mi Orden, destrozado mis engaños y amenazado siglos de deseo. Pero yo prevareceré, te infectaré y retorceré a mi voluntad...",,"Sinä... Sinä olet murskannut Veljeskuntani, tunkenut läpi ansojeni ja uhannut vuosisatoja palanutta halua. Mutta olen vielä voittava; tartutan sinut ja väännän sinut tahtooni...","Vous.. Vous avez anéanti mon Ordre, percé à travers le voile de mes ruses et menacé des siècle de désirs. Mais je gagnerai, je vous infecterai et vous plierai à ma volonté...","Te...Te voltál aki szétmorzsolta a Rendemet, letépted a trükkök palástyát, és évszázadok kívánatát borítottad fel. Akkor is győzedelmeskedni fogok, megferzőzlek és az akaratomnak megfelelően foglak torzítani...","Tu... hai schiacciato il mio Ordine, hai rovinato i miei piani e minacciato secoli di desideri. Ma io vincerò, ti infetterò e ti piegherò alla mia volontà...","キサマ...キサマハ我ガオーダーヲ破壊シニシタ、 我ノ詭謀ヲ截チ何世紀ニモワタル望ミヲ脅カシタ。 ダガマダ終ワリデハナイ、キサマニ憑キ意志ヲヒネリ出セバ... -","그대... 짐의 명령을 거부하고, 많은 것을 빼앗았고, 수 백 년 동안의 욕망을 위협했느니라. 그러나 짐은, 그대를 침식하여 짐의 의지에 복종하도록 만들 것이니라...","Jullie hebben mijn Orde verpletterd, door mijn listen heen gescheurd en eeuwen van verlangen bedreigd. Maar ik zal zegevieren, ik zal je besmetten en je naar mijn wil draaien....","Du... Du har knust min Orden, gjennomskuet mine knep og truet århundrer av begjær. Men jeg vil seire, jeg vil infisere deg og vri deg til min vilje...","Ty... Zmiażdżyłeś mój Zakon, przedarłeś się przez moje podstępy i zagroziłeś wiekom pożądania. Ale ja zwyciężę, zainfekuję cię i zmienię na swoją wolę...","Você... você destruiu a minha Ordem, destroçou meus truques e ameaçou séculos de desejo. Mas eu vou prevalecer. Infectarei você e vou manipulá-lo à minha vontade...",,"Tu... Tu mi-ai strivit Ordinul, și mi-ai amenințat secole de dorință. Dar voi învinge, te voi infecta și îți voi pervertii voința...","Ты... Ты разгромил мой Орден, прорвался через мои ловушки и сделал столетия ожидания напрасными. Но тебе не победить — я заражу тебя и подчиню своей воле!",,"Sen... Düzenimi yıktın, hilelerimi parçaladın ve yüzyıllardır süren arzularımı tehdit ettin. Ama ben galip geleceğim, sana bulaşacağım ve seni kendi isteğime dönüştüreceğim." -"Sounds like a dream job, doesn't it?",TXT_SUB_LOG200,,,,"Zní jako práce snů, ne?","Det lyder som et drømmejob, ikke sandt?","Hört sich wie ein Traumjob an, nicht wahr?",,,"Suena a un trabajo ideal, ¿no?",,Eikö kuulostakin unelmapestiltä?,"Le job de vos rêves, non?","Úgy tűnik mint egy álam meló, ugye?","Sembra un lavoro da sogno, no?",,바라던 일 같네. 그렇지 않아?,"Klinkt als een droombaan, nietwaar?","Høres ut som en drømmejobb, ikke sant?","Brzmi jak praca marzeń, prawda?","Parece ser o emprego ideal, não é mesmo?",,"Sună a vis, nu?","Звучит как работа мечты, не так ли?",,"Rüya gibi bir iş, değil mi?" -"You've seen too much. Ice him, Macil!",TXT_SUB_LOG201,,,,"Viděl jsi moc. Zab ho, Macile!","Du har set for meget. Islæg ham, Macil!","Du hast genug gesehen. Mach ihn kalt, Macil!",,,"Has visto demasiado. ¡Acaba con él, Macil!",,"Olet nähnyt liikaa. Murskaa hänet, Macil!","Vous en avez trop vu. Descend-le, Macil!",Túl sokat láttál. öld meg Macil!,"Hai visto troppo. Fallo fuori, Macil!",,"넌 많은 걸 봤어. 얼려버려, 마실!","Je hebt te veel gezien. Ijs hem, Macil!","Du har sett for mye. Legg ham på is, Macil!","Widziałeś już zbyt wiele. Lód, Macil!","Você já viu demais. Acaba com ele, Macil!",,"Ai văzut prea mult. Îngheață-l, Macil!","Ты слишком много видел. Заморозь его, Мэйсил!",,"Çok fazla şey gördün. Buzla onu, Macil!" +","그대... 짐의 명령을 거부하고, 많은 것을 빼앗았고, 수 백 년 동안의 욕망을 위협했느니라. 그러나 짐은, 그대를 침식하여 짐의 의지에 복종하도록 만들 것이니라...","Jullie hebben mijn Orde verpletterd, door mijn listen heen gescheurd en eeuwen van verlangen bedreigd. Maar ik zal zegevieren, ik zal je besmetten en je naar mijn wil draaien....","Du... Du har knust min Orden, gjennomskuet mine knep og truet århundrer av begjær. Men jeg vil seire, jeg vil infisere deg og vri deg til min vilje...","Ty... Zmiażdżyłeś mój Zakon, przedarłeś się przez moje podstępy i zagroziłeś wiekom pożądania. Ale ja zwyciężę, zainfekuję cię i zmienię na swoją wolę...","Você... você destruiu a minha Ordem, destroçou meus truques e ameaçou séculos de desejo. Mas eu vou prevalecer. Infectarei você e vou manipulá-lo à minha vontade...",,"Tu... Tu mi-ai strivit Ordinul, și mi-ai amenințat secole de dorință. Dar voi învinge, te voi infecta și îți voi pervertii voința...","Ты... Ты разгромил мой Орден, прорвался через мои ловушки и сделал столетия ожидания напрасными. Но тебе не победить — я заражу тебя и подчиню своей воле!",,"Du... Du har krossat min ordning, slitit igenom mina knep och hotat århundraden av begär. Men jag kommer att segra, jag kommer att infektera dig och vrida dig till min vilja...","Sen... Düzenimi yıktın, hilelerimi parçaladın ve yüzyıllardır süren arzularımı tehdit ettin. Ama ben galip geleceğim, sana bulaşacağım ve seni kendi isteğime dönüştüreceğim." +"Sounds like a dream job, doesn't it?",TXT_SUB_LOG200,,,,"Zní jako práce snů, ne?","Det lyder som et drømmejob, ikke sandt?","Hört sich wie ein Traumjob an, nicht wahr?",,,"Suena a un trabajo ideal, ¿no?",,Eikö kuulostakin unelmapestiltä?,"Le job de vos rêves, non?","Úgy tűnik mint egy álam meló, ugye?","Sembra un lavoro da sogno, no?",,바라던 일 같네. 그렇지 않아?,"Klinkt als een droombaan, nietwaar?","Høres ut som en drømmejobb, ikke sant?","Brzmi jak praca marzeń, prawda?","Parece ser o emprego ideal, não é mesmo?",,"Sună a vis, nu?","Звучит как работа мечты, не так ли?",,"Låter som ett drömjobb, eller hur?","Rüya gibi bir iş, değil mi?" +"You've seen too much. Ice him, Macil!",TXT_SUB_LOG201,,,,"Viděl jsi moc. Zab ho, Macile!","Du har set for meget. Islæg ham, Macil!","Du hast genug gesehen. Mach ihn kalt, Macil!",,,"Has visto demasiado. ¡Acaba con él, Macil!",,"Olet nähnyt liikaa. Murskaa hänet, Macil!","Vous en avez trop vu. Descend-le, Macil!",Túl sokat láttál. öld meg Macil!,"Hai visto troppo. Fallo fuori, Macil!",,"넌 많은 걸 봤어. 얼려버려, 마실!","Je hebt te veel gezien. Ijs hem, Macil!","Du har sett for mye. Legg ham på is, Macil!","Widziałeś już zbyt wiele. Lód, Macil!","Você já viu demais. Acaba com ele, Macil!",,"Ai văzut prea mult. Îngheață-l, Macil!","Ты слишком много видел. Заморозь его, Мэйсил!",,"Du har sett för mycket. Isa honom, Macil!","Çok fazla şey gördün. Buzla onu, Macil!" "Next time, you'll listen to me.",TXT_SUB_LOG202,"(Strife: Veteran Edition) -Random comment when the player dies with Classic Mode turned off",,,Příště budeš poslouchat mě.,Næste gang vil du lytte til mig.,Nächstes Mal hörst du auf mich.,,,"La próxima vez, me harás caso.",,Ensi kerralla saat luvan kuunnella minua.,"La prochaine fois, tu m'écouteras.",Majd legközelebb hallgatsz rám.,"La prossima volta, mi ascolterai.",今度は、私の言う事を聞きなさいよ。,"다음번엔, 내 말을 좀 들어. ",Volgende keer luister je naar me.,Neste gang hører du på meg.,Następnym razem mnie posłuchasz.,"Da próxima vez, você vai me ouvir.",,"Data viitoare, o să mă asculți.","Будешь знать, как меня не слушать.",,Bir dahaki sefere beni dinlersin. -"Ugh, these post-apocalyptic prices...",TXT_SUB_LOG203,,,,"Uf, tyhle postapokalyptické ceny...",Disse post-apokalyptiske priser...,"Ugh, diese postapokalyptischen Preise...",,,"Ugh, estos precios post-apocalípticos...",,"Ääh, näitä maailmanlopun jälkeisiä hintoja...","Eugh, ces prix post-apocalyptiques..","Fú, ezek az apokalipszis utáni árak...","Ugh, questi prezzi post-apocalittici...",,"으윽, 세기말 가격이네.","Ugh, deze post-apocalyptische prijzen....",Disse postapokalyptiske prisene...,"Ugh, te postapokaliptyczne ceny...","Urgh, esses preços pós-apocalípticos...",,"Ugh, prețurile ăstea post-apocaliptice...","Ух, эти цены после апокалипсиса...",,Bu kıyamet sonrası fiyatları. -Take the big one. He won't stop you.,TXT_SUB_LOG204,,,,Rozdej si to s tím velkým. Nezastaví tě.,Tag den store. Han vil ikke stoppe dig.,"Nimm das große, Er wird dich nicht stoppen.",,,Toma el grande. No te detendrá.,,Ota iso. Hän ei estä sinua.,"Prends le gros, il ne t'arrètera pas.",Vidd el a nagyot. Nem fog beléd kötni.,Prendi quello più grande. Non ti fermerà.,,커다란 놈을 막아. 둔하니까.,Neem de grote. Hij zal je niet tegenhouden.,Ta den store. Han vil ikke stoppe deg.,Weź dużą. Nie zatrzyma cię.,Leve o grandão. Ele não vai te deter.,,"Ia-l pe cel mare, nu te va opri.",Бери самую крупную. Он тебя не остановит.,,Büyük olanı al. Seni durdurmayacak. -Don't dawdle. Straight ahead!,TXT_SUB_LOG205,,,,Neloudej se. Jdi rovně!,Du skal ikke tøve. Lige fremad!,Trödel nicht rum. Direkt voraus!,,,No te pares. ¡Sigue adelante!,,Älä vitkastele. Suoraan eteenpäin!,"Ne traîne pas, tout devant!",Ne vesztegesd az időt. Csak egyenesen!,Non indulgiare. Vai avanti!,,꾸물거리지 말고 빨리 움직여야 해! ,Niet treuzelen. Rechtdoor!,Ikke somle. Rett fram!,Nie ociągaj się. Prosto przed siebie!,Não pare. Siga adiante!,,Nu te lenevi. Drept în față!,Не мешкай. Прямо вперёд!,,Oyalanma. Dümdüz ilerle! -You ever notice how these corridors look the same?,TXT_SUB_LOG206,,,,"Všimnul sis, jak všechny to chodby vypadají stejně?","Har du nogensinde lagt mærke til, at disse korridorer ser ens ud?","Ist dir schon mal aufgefallen, dass diese Flure alle gleich aussehen?",,,¿Alguna vez te has fijado en como estos pasillos parecen iguales?,,"Oletko koskaan huomannut, miten samanlaisilta nämä käyttävät näyttävät?",T'as pas l'impression que ces couloirs ont tous la même tête?,"Feltűnt, hogy minden folyosó ugyanúgy néz ki?",Ti sei mai accorto come tutti questi corridoi si assomiglino?,,갈 때마다 보이는 복도가 다 똑같다고 생각해본 적 있어? ,Heb je ooit gemerkt hoe deze gangen er hetzelfde uitzien?,Har du lagt merke til at korridorene ser like ut?,"Zauważyłeś, że te korytarze wyglądają tak samo?",Você já reparou como esses corredores parecem todos iguais?,,Nu observi cum coridoarele ăstea arată mereu la fel?,"Ты когда-нибудь замечал, что эти коридоры выглядят одинаково?",,Bu koridorların nasıl aynı göründüğünü hiç fark ettin mi? -"Hey, sometimes I have to guess too!",TXT_SUB_LOG207,,,,"Hej, já taky musím někdy hádat!",Nogle gange er jeg også nødt til at gætte!,"Hey, manchmal muss auch ich raten!",,,"¡Eh, a veces tambien tengo que adivinar!",,"Hei, joskus minunkin täytyy arvata!","Hé, il y a des fois où il faut aussi que je devine!",Nekem is néha találgatnom kell.,"Ehi, a volte anche io devo tirare a indovinare!",,"야, 어쩔 때는 나도 추측을 해본다고! ","Hé, soms moet ik ook raden!",Noen ganger må jeg også gjette!,"Hej, czasami ja też muszę zgadywać!","Ei, as vezes tenho que adivinhar também!",,"Hei, uneori și eu ghicesc!","Эй, иногда мне тоже приходится угадывать!",,"Hey, bazen ben de tahmin etmek zorunda kalıyorum!" -"Oh, and watch out for the alarm.",TXT_SUB_LOG208,,,,"Oh, a dávej pozor na alarm.","Åh, og pas på alarmen.","Oh, und achte auf den Alarm.",,,"Ah, y ten cuidado con la alarma.",,"Ja muuten, varo hälytystä.","Oh, et fais attention à l'alarme.","Ja, és vigyázz a riasztóval.","Oh, e fai attenzione all'allarme.",,"오, 그리고 경보를 조심해.","Oh, en kijk uit voor het alarm.",Se opp for alarmen.,"Aha, i uważaj na alarm.","Ah, e cuidado com o alarme.",,"Oh, și ai grijă la alarmă!",И остерегайся сигнализации.,,"Oh, ve alarma dikkat et." +Random comment when the player dies with Classic Mode turned off",,,Příště budeš poslouchat mě.,Næste gang vil du lytte til mig.,Nächstes Mal hörst du auf mich.,,,"La próxima vez, me harás caso.",,Ensi kerralla saat luvan kuunnella minua.,"La prochaine fois, tu m'écouteras.",Majd legközelebb hallgatsz rám.,"La prossima volta, mi ascolterai.",今度は、私の言う事を聞きなさいよ。,"다음번엔, 내 말을 좀 들어. ",Volgende keer luister je naar me.,Neste gang hører du på meg.,Następnym razem mnie posłuchasz.,"Da próxima vez, você vai me ouvir.",,"Data viitoare, o să mă asculți.","Будешь знать, как меня не слушать.",,Nästa gång lyssnar du på mig.,Bir dahaki sefere beni dinlersin. +"Ugh, these post-apocalyptic prices...",TXT_SUB_LOG203,,,,"Uf, tyhle postapokalyptické ceny...",Disse post-apokalyptiske priser...,"Ugh, diese postapokalyptischen Preise...",,,"Ugh, estos precios post-apocalípticos...",,"Ääh, näitä maailmanlopun jälkeisiä hintoja...","Eugh, ces prix post-apocalyptiques..","Fú, ezek az apokalipszis utáni árak...","Ugh, questi prezzi post-apocalittici...",,"으윽, 세기말 가격이네.","Ugh, deze post-apocalyptische prijzen....",Disse postapokalyptiske prisene...,"Ugh, te postapokaliptyczne ceny...","Urgh, esses preços pós-apocalípticos...",,"Ugh, prețurile ăstea post-apocaliptice...","Ух, эти цены после апокалипсиса...",,De här postapokalyptiska priserna...,Bu kıyamet sonrası fiyatları. +Take the big one. He won't stop you.,TXT_SUB_LOG204,,,,Rozdej si to s tím velkým. Nezastaví tě.,Tag den store. Han vil ikke stoppe dig.,"Nimm das große, Er wird dich nicht stoppen.",,,Toma el grande. No te detendrá.,,Ota iso. Hän ei estä sinua.,"Prends le gros, il ne t'arrètera pas.",Vidd el a nagyot. Nem fog beléd kötni.,Prendi quello più grande. Non ti fermerà.,,커다란 놈을 막아. 둔하니까.,Neem de grote. Hij zal je niet tegenhouden.,Ta den store. Han vil ikke stoppe deg.,Weź dużą. Nie zatrzyma cię.,Leve o grandão. Ele não vai te deter.,,"Ia-l pe cel mare, nu te va opri.",Бери самую крупную. Он тебя не остановит.,,Ta den stora. Han kommer inte att stoppa dig.,Büyük olanı al. Seni durdurmayacak. +Don't dawdle. Straight ahead!,TXT_SUB_LOG205,,,,Neloudej se. Jdi rovně!,Du skal ikke tøve. Lige fremad!,Trödel nicht rum. Direkt voraus!,,,No te pares. ¡Sigue adelante!,,Älä vitkastele. Suoraan eteenpäin!,"Ne traîne pas, tout devant!",Ne vesztegesd az időt. Csak egyenesen!,Non indulgiare. Vai avanti!,,꾸물거리지 말고 빨리 움직여야 해! ,Niet treuzelen. Rechtdoor!,Ikke somle. Rett fram!,Nie ociągaj się. Prosto przed siebie!,Não pare. Siga adiante!,,Nu te lenevi. Drept în față!,Не мешкай. Прямо вперёд!,,Tröna inte. Rakt fram!,Oyalanma. Dümdüz ilerle! +You ever notice how these corridors look the same?,TXT_SUB_LOG206,,,,"Všimnul sis, jak všechny to chodby vypadají stejně?","Har du nogensinde lagt mærke til, at disse korridorer ser ens ud?","Ist dir schon mal aufgefallen, dass diese Flure alle gleich aussehen?",,,¿Alguna vez te has fijado en como estos pasillos parecen iguales?,,"Oletko koskaan huomannut, miten samanlaisilta nämä käyttävät näyttävät?",T'as pas l'impression que ces couloirs ont tous la même tête?,"Feltűnt, hogy minden folyosó ugyanúgy néz ki?",Ti sei mai accorto come tutti questi corridoi si assomiglino?,,갈 때마다 보이는 복도가 다 똑같다고 생각해본 적 있어? ,Heb je ooit gemerkt hoe deze gangen er hetzelfde uitzien?,Har du lagt merke til at korridorene ser like ut?,"Zauważyłeś, że te korytarze wyglądają tak samo?",Você já reparou como esses corredores parecem todos iguais?,,Nu observi cum coridoarele ăstea arată mereu la fel?,"Ты когда-нибудь замечал, что эти коридоры выглядят одинаково?",,Har du någonsin lagt märke till att korridorerna ser likadana ut?,Bu koridorların nasıl aynı göründüğünü hiç fark ettin mi? +"Hey, sometimes I have to guess too!",TXT_SUB_LOG207,,,,"Hej, já taky musím někdy hádat!",Nogle gange er jeg også nødt til at gætte!,"Hey, manchmal muss auch ich raten!",,,"¡Eh, a veces tambien tengo que adivinar!",,"Hei, joskus minunkin täytyy arvata!","Hé, il y a des fois où il faut aussi que je devine!",Nekem is néha találgatnom kell.,"Ehi, a volte anche io devo tirare a indovinare!",,"야, 어쩔 때는 나도 추측을 해본다고! ","Hé, soms moet ik ook raden!",Noen ganger må jeg også gjette!,"Hej, czasami ja też muszę zgadywać!","Ei, as vezes tenho que adivinhar também!",,"Hei, uneori și eu ghicesc!","Эй, иногда мне тоже приходится угадывать!",,Ibland måste jag också gissa!,"Hey, bazen ben de tahmin etmek zorunda kalıyorum!" +"Oh, and watch out for the alarm.",TXT_SUB_LOG208,,,,"Oh, a dávej pozor na alarm.","Åh, og pas på alarmen.","Oh, und achte auf den Alarm.",,,"Ah, y ten cuidado con la alarma.",,"Ja muuten, varo hälytystä.","Oh, et fais attention à l'alarme.","Ja, és vigyázz a riasztóval.","Oh, e fai attenzione all'allarme.",,"오, 그리고 경보를 조심해.","Oh, en kijk uit voor het alarm.",Se opp for alarmen.,"Aha, i uważaj na alarm.","Ah, e cuidado com o alarme.",,"Oh, și ai grijă la alarmă!",И остерегайся сигнализации.,,"Åh, och se upp för larmet.","Oh, ve alarma dikkat et." "Oh, jeez. Now look what you've done!",TXT_SUB_LOG209,"(Strife: Veteran Edition) -Random comment when the player dies with Classic Mode turned off",,,"No sakra. Koukej, cos udělal!","Åh, for pokker. Se nu, hvad du har gjort!","Oh je. Sieh nur, was du getan hast.",,,Joder. ¡Mira lo que has hecho!,Dios. ¡Mira lo que hiciste!,"Voi hemmetti. Katso nyt, mitä olet tehnyt!","Oh, zut, regarde ce que tu as fait!","Jézusom, nézd mit műveltél!","Ah, dannazione. Guarda che cosa hai fatto!",ああ、そうね。今貴方の仕出かした事を見直しなさい。,"맙소사, 무슨 짓을 저질렀는지 알기나 해?","Oh, jeez. Kijk nu wat je hebt gedaan!","Å, jøss. Se hva du har gjort!","Oh, jeezu. Zobacz, co zrobiłeś!","Ai, caramba. Olha só o que você fez!",,"Oh, vai. Ia uite ce ai făcut.","Ну блин. Только посмотри, что ты наделал!",,"Oh, Tanrım. Bak ne yaptın!" +Random comment when the player dies with Classic Mode turned off",,,"No sakra. Koukej, cos udělal!","Åh, for pokker. Se nu, hvad du har gjort!","Oh je. Sieh nur, was du getan hast.",,,Joder. ¡Mira lo que has hecho!,Dios. ¡Mira lo que hiciste!,"Voi hemmetti. Katso nyt, mitä olet tehnyt!","Oh, zut, regarde ce que tu as fait!","Jézusom, nézd mit műveltél!","Ah, dannazione. Guarda che cosa hai fatto!",ああ、そうね。今貴方の仕出かした事を見直しなさい。,"맙소사, 무슨 짓을 저질렀는지 알기나 해?","Oh, jeez. Kijk nu wat je hebt gedaan!","Å, jøss. Se hva du har gjort!","Oh, jeezu. Zobacz, co zrobiłeś!","Ai, caramba. Olha só o que você fez!",,"Oh, vai. Ia uite ce ai făcut.","Ну блин. Только посмотри, что ты наделал!",,"Åh, herregud. Se vad du har gjort!","Oh, Tanrım. Bak ne yaptın!" Shit. Now you've blown it!,TXT_SUB_LOG210,"(Strife: Veteran Edition) -Random comment when the player dies with Classic Mode turned off",,,Do prdele. Teď jsi to podělal!,Pis. Nu har du ødelagt det!,"Mist, du hast es verbockt.",,,Mierda. ¡Ya la has liado!,Carajo. ¡Ya metiste la pata!,"Vittu, nyt meni ihan reisille!","Merde, t'as vraiment tout foutu en l'air!",Francba. Lebuktattál minket!,Merda. Ora hai davvero rovinato tutto!,クソが。アンタ今、台無しにしたぞ!,"제길, 다 망쳐 놓았네!",Shit. Nu heb je het verpest!,Pokker... Nå har du ødelagt det!,Cholera. Teraz to spieprzyłeś!,Merda. Agora você ferrou tudo!,,Rahat. Acum ai distrus totul!,"Чёрт, ты всё испортил!",,Kahretsin. Şimdi de sen mahvettin! -Come on! Let's get the hell out of here.,TXT_SUB_LOG211,MAP15: Computer destroyed + Room 1,,,No tak! Dostaňme se sakra odsud.,Kom nu! Lad os komme væk herfra.,Komm schon! Lass uns auf der Stelle von hier verschwinden.,,,¡Venga! Larguémonos de aquí.,¡Vamos! Vayámonos de aquí.,Mennään! Häivytään täältä hittoon.,Allez! Sortons d'ici!,Gyerünk húzzunk innen a francba!,Avanti! Andiamocene da qui!,頼むぞ!こっからとっとと失せろ!,빨리! 여길 어서 벗어나야 해!,Kom op! Laten we hier als de sodemieter weggaan.,Nå har du ødelagt det! Kom igjen! La oss komme oss til helvete ut herfra.,No dalej! Wynośmy się stąd.,Vem! Vamos vazar daqui.,,"Haide, să ieșim de aici.",Ну же! Двигаем отсюда!,,"Hadi, hadi! Buradan defolup gidelim." -Ooh. You don't mess around.,TXT_SUB_LOG212,,,,"Hmm, ty se nepáráš.",Ooh. Du laver ikke sjov.,Oh. Du lässt nichts anbrennen.,,,Ooh. No pierdes el tiempo.,,"Ooh, et turhia pelleile.","Oooh, tu n'y va pas de main morte.","Ajaj, látom nem tökölsz.",Ooh. Non sei uno che scherza.,,"오, 너 이 일에 정말 진지하구나?",Ooh. Je rotzooit niet.,Ooh. Du tuller ikke.,Ooh. Nie wygłupiaj się.,Oooh. Você não perde tempo mesmo.,,Ooh. Nu te joci.,Ооо. Ты знаешь своё дело.,,Ooh. Hiç oyalanmıyorsun. -You're going to mount them on the wall! Keep going!,TXT_SUB_LOG213,,,,Takhle je přišpendlíš ke zdi! Pokračuj a jdi dál!,Du skal montere dem på væggen! Fortsæt!,Willst du sie an der Wand anmontieren? Geh weiter!,,,¡Vas a montarlos en la pared! ¡Sigue!,,Ripustat heidät seinälle! Jatka vain!,Tu vas les clouer au mur! Continue!,Majd szépen kirakod a fejüket trófeának. Csak így tovább!,Li incollerai al muro! Continua così!,,저 녀석들을 모두 벽에 처박아놓자. 힘내! ,Je gaat ze aan de muur bevestigen! Ga door!,Du skal montere dem på veggen! Fortsett!,Zamierzasz je zamontować na ścianie! Dalej!,Você vai montá-los na parede! Continua!,,O să le pună pe zid! Continuă să mergi!,Тебе нужно закрепить их на стене! Продолжай в том же духе!,,Onları duvara monte edeceksin! Devam et! -Mm. You are a brute.,TXT_SUB_LOG214,,,,"Mhm, ty jsi ale surovec.",Mm. Du er en brutal mand.,Hm. Du bist aber ein Rohling.,,,Mm. Eres un bruto.,,"Mm, olet julma peto.","Mm, tu est une brute.",Hm. Egy állat vagy.,Mm. Sei un bruto.,,"음, 넌 괴물이야.",Mm. Je bent een bruut.,Mm. Du er et råskinn.,Mm. Jesteś brutalem.,"Hmm, seu brutamontes.",,Mm. Ești o brută.,Мм. Ты грубиян.,,Mm. Sen bir hayvansın. -Got a nice rhythm going here.,TXT_SUB_LOG215,,,,Máme tu teď hezký rytmus.,Du har en god rytme her.,Wir haben hier einen netten Rhythmus drauf.,,,Estás siguiendo un buen ritmo.,,Ehti kiva rytmi muodostua.,On a un bon rythme là.,Jó ütemben haladunk.,Siamo entrati in un bel ritmo qua.,,생각보다 박자가 잘 맞는데?,Ik heb hier een mooi ritme.,Har en fin rytme her.,Mamy tu ładny rytm.,Tá rolando um rítmo bom.,,Mișto ritm.,У тебя хороший ритм.,,Burada güzel bir ritim var. -Ooh. Love that boom-boom stick.,TXT_SUB_LOG216,,,,"Oh, pěkná brokáda.",Ooh. Jeg elsker den boom-boom-pind.,Ooh. Tolles Schießeisen.,,,Ooh. Me encanta.,,"Ooh, rakastan tuota tussaria.","Ooh, j'adore ce truc qui fait boum.","Áhh, imádom a söri-sörétest.",Ooh. Adoro quel fucile.,,저 빵야-빵야 막대기 너무나도 좋은걸? ,Ooh. Ik hou van die boom-boom stok.,Ooh. Elsker den boom-boom pinnen.,Ooh. Kocham ten boom-boom stick.,"Oooh, adoro.",,Ooh. Îmi place arma aceea nimicitoare.,О. Обожаю эту палку-взрывалку.,,Ooh. Bu bum-bum sopasını seviyorum. -Mm. I like the way you carry yourself.,TXT_SUB_LOG217,,,,"Mhm, líbí se mi, jak se neseš.","Jeg elsker denne boom-boom-boom. Jeg kan godt lide den måde, du bærer dig selv på.","Hm. Ich finde es toll, wie du dich präsentierst.",,,Mm. Me gusta como te lo montas.,,"Mm, pidän käytöksestäsi.","Mm, j'aime comment tu te porte.",Hm. Tetszik a magabiztosságod.,Mi piace il modo in cui ti comporti.,,너 스스로 챙기는 모습이 정말 보기 좋아. ,Mm. Ik hou van de manier waarop je jezelf draagt.,Mm. Jeg liker måten du bærer deg selv på.,"Mm. Lubię sposób, w jaki się nosisz.","Hmm, estou gostando de como você está indo.",,Ooh. Îmi place cum te descuri.,"Мм. Мне нравится, как ты ведёшь дело.",,Mm. Kendini taşıma şeklini seviyorum. -Blast away! They're not human!,TXT_SUB_LOG218,,,,Jen střílej! Nejsou to lidé!,Blast away! De er ikke menneskelige!,Mach sie alle! Das sind keine Menschen!,,,¡Reviéntalos! ¡No son humanos!,,Antaa palaa! Ne eivät ole ihmisiä!,"Eclate-les, ils ne sont pas humains!",Meghalsz! Nem is vagy ember!,Falli fuori! Non sono umani!,,날려버려! 저놈들은 인간이 아니야! ,Blast away! Ze zijn niet menselijk!,Skyt i vei! De er ikke mennesker!,Do dzieła! To nie są ludzie!,Arrebenta neles! Eles não são humanos!,,La naiba! Nu sunt umane!,Взрывай! Они не люди!,,Patlat! Onlar insan değil! +Random comment when the player dies with Classic Mode turned off",,,Do prdele. Teď jsi to podělal!,Pis. Nu har du ødelagt det!,"Mist, du hast es verbockt.",,,Mierda. ¡Ya la has liado!,Carajo. ¡Ya metiste la pata!,"Vittu, nyt meni ihan reisille!","Merde, t'as vraiment tout foutu en l'air!",Francba. Lebuktattál minket!,Merda. Ora hai davvero rovinato tutto!,クソが。アンタ今、台無しにしたぞ!,"제길, 다 망쳐 놓았네!",Shit. Nu heb je het verpest!,Pokker... Nå har du ødelagt det!,Cholera. Teraz to spieprzyłeś!,Merda. Agora você ferrou tudo!,,Rahat. Acum ai distrus totul!,"Чёрт, ты всё испортил!",,Fan också. Nu har du förstört det!,Kahretsin. Şimdi de sen mahvettin! +Come on! Let's get the hell out of here.,TXT_SUB_LOG211,MAP15: Computer destroyed + Room 1,,,No tak! Dostaňme se sakra odsud.,Kom nu! Lad os komme væk herfra.,Komm schon! Lass uns auf der Stelle von hier verschwinden.,,,¡Venga! Larguémonos de aquí.,¡Vamos! Vayámonos de aquí.,Mennään! Häivytään täältä hittoon.,Allez! Sortons d'ici!,Gyerünk húzzunk innen a francba!,Avanti! Andiamocene da qui!,頼むぞ!こっからとっとと失せろ!,빨리! 여길 어서 벗어나야 해!,Kom op! Laten we hier als de sodemieter weggaan.,Nå har du ødelagt det! Kom igjen! La oss komme oss til helvete ut herfra.,No dalej! Wynośmy się stąd.,Vem! Vamos vazar daqui.,,"Haide, să ieșim de aici.",Ну же! Двигаем отсюда!,,Kom igen! Nu sticker vi härifrån.,"Hadi, hadi! Buradan defolup gidelim." +Ooh. You don't mess around.,TXT_SUB_LOG212,,,,"Hmm, ty se nepáráš.",Ooh. Du laver ikke sjov.,Oh. Du lässt nichts anbrennen.,,,Ooh. No pierdes el tiempo.,,"Ooh, et turhia pelleile.","Oooh, tu n'y va pas de main morte.","Ajaj, látom nem tökölsz.",Ooh. Non sei uno che scherza.,,"오, 너 이 일에 정말 진지하구나?",Ooh. Je rotzooit niet.,Ooh. Du tuller ikke.,Ooh. Nie wygłupiaj się.,Oooh. Você não perde tempo mesmo.,,Ooh. Nu te joci.,Ооо. Ты знаешь своё дело.,,Ooh. Du är inte en sån jävel.,Ooh. Hiç oyalanmıyorsun. +You're going to mount them on the wall! Keep going!,TXT_SUB_LOG213,,,,Takhle je přišpendlíš ke zdi! Pokračuj a jdi dál!,Du skal montere dem på væggen! Fortsæt!,Willst du sie an der Wand anmontieren? Geh weiter!,,,¡Vas a montarlos en la pared! ¡Sigue!,,Ripustat heidät seinälle! Jatka vain!,Tu vas les clouer au mur! Continue!,Majd szépen kirakod a fejüket trófeának. Csak így tovább!,Li incollerai al muro! Continua così!,,저 녀석들을 모두 벽에 처박아놓자. 힘내! ,Je gaat ze aan de muur bevestigen! Ga door!,Du skal montere dem på veggen! Fortsett!,Zamierzasz je zamontować na ścianie! Dalej!,Você vai montá-los na parede! Continua!,,O să le pună pe zid! Continuă să mergi!,Тебе нужно закрепить их на стене! Продолжай в том же духе!,,Du ska montera dem på väggen! Fortsätt!,Onları duvara monte edeceksin! Devam et! +Mm. You are a brute.,TXT_SUB_LOG214,,,,"Mhm, ty jsi ale surovec.",Mm. Du er en brutal mand.,Hm. Du bist aber ein Rohling.,,,Mm. Eres un bruto.,,"Mm, olet julma peto.","Mm, tu est une brute.",Hm. Egy állat vagy.,Mm. Sei un bruto.,,"음, 넌 괴물이야.",Mm. Je bent een bruut.,Mm. Du er et råskinn.,Mm. Jesteś brutalem.,"Hmm, seu brutamontes.",,Mm. Ești o brută.,Мм. Ты грубиян.,,Mm. Du är ett vilddjur.,Mm. Sen bir hayvansın. +Got a nice rhythm going here.,TXT_SUB_LOG215,,,,Máme tu teď hezký rytmus.,Du har en god rytme her.,Wir haben hier einen netten Rhythmus drauf.,,,Estás siguiendo un buen ritmo.,,Ehti kiva rytmi muodostua.,On a un bon rythme là.,Jó ütemben haladunk.,Siamo entrati in un bel ritmo qua.,,생각보다 박자가 잘 맞는데?,Ik heb hier een mooi ritme.,Har en fin rytme her.,Mamy tu ładny rytm.,Tá rolando um rítmo bom.,,Mișto ritm.,У тебя хороший ритм.,,Du har en bra rytm.,Burada güzel bir ritim var. +Ooh. Love that boom-boom stick.,TXT_SUB_LOG216,,,,"Oh, pěkná brokáda.",Ooh. Jeg elsker den boom-boom-pind.,Ooh. Tolles Schießeisen.,,,Ooh. Me encanta.,,"Ooh, rakastan tuota tussaria.","Ooh, j'adore ce truc qui fait boum.","Áhh, imádom a söri-sörétest.",Ooh. Adoro quel fucile.,,저 빵야-빵야 막대기 너무나도 좋은걸? ,Ooh. Ik hou van die boom-boom stok.,Ooh. Elsker den boom-boom pinnen.,Ooh. Kocham ten boom-boom stick.,"Oooh, adoro.",,Ooh. Îmi place arma aceea nimicitoare.,О. Обожаю эту палку-взрывалку.,,Ooh. Jag älskar den där boom-boom-pinnen.,Ooh. Bu bum-bum sopasını seviyorum. +Mm. I like the way you carry yourself.,TXT_SUB_LOG217,,,,"Mhm, líbí se mi, jak se neseš.","Jeg elsker denne boom-boom-boom. Jeg kan godt lide den måde, du bærer dig selv på.","Hm. Ich finde es toll, wie du dich präsentierst.",,,Mm. Me gusta como te lo montas.,,"Mm, pidän käytöksestäsi.","Mm, j'aime comment tu te porte.",Hm. Tetszik a magabiztosságod.,Mi piace il modo in cui ti comporti.,,너 스스로 챙기는 모습이 정말 보기 좋아. ,Mm. Ik hou van de manier waarop je jezelf draagt.,Mm. Jeg liker måten du bærer deg selv på.,"Mm. Lubię sposób, w jaki się nosisz.","Hmm, estou gostando de como você está indo.",,Ooh. Îmi place cum te descuri.,"Мм. Мне нравится, как ты ведёшь дело.",,Jag gillar den här bommen. Jag gillar ditt sätt att bära dig själv.,Mm. Kendini taşıma şeklini seviyorum. +Blast away! They're not human!,TXT_SUB_LOG218,,,,Jen střílej! Nejsou to lidé!,Blast away! De er ikke menneskelige!,Mach sie alle! Das sind keine Menschen!,,,¡Reviéntalos! ¡No son humanos!,,Antaa palaa! Ne eivät ole ihmisiä!,"Eclate-les, ils ne sont pas humains!",Meghalsz! Nem is vagy ember!,Falli fuori! Non sono umani!,,날려버려! 저놈들은 인간이 아니야! ,Blast away! Ze zijn niet menselijk!,Skyt i vei! De er ikke mennesker!,Do dzieła! To nie są ludzie!,Arrebenta neles! Eles não são humanos!,,La naiba! Nu sunt umane!,Взрывай! Они не люди!,,Blast away! De är inte mänskliga!,Patlat! Onlar insan değil! Wow! Blackened Acolyte! The new taste sensation...,TXT_SUB_LOG219,"(Strife: Veteran Edition) -When obtaining the “Spontaneous Combustion” achievement",,,Wow! Zčernalý akolyta! Nové kulinářské šílenství...,Wow! Sorte Acolyt! Den nye smagsoplevelse...,Wow! Geschmorter Ministrant! Neue Geschmackssensation...,,,¡Guau! ¡Acólito ennegrecido! La nueva sensación de sabor...,,Vau! Mustaa akoluuttia! Uutuusmakuelämys!,Wow! Acolyte noirci! Goûte à la nouvelle saveur sensationelle!,Wow! Pörkölt ministráns! A szezon új íze...,Wow! Accolito scuro! Il nuovo sensazionale sapore!,うぉう!黒ずんだアコライト!新しい趣味に目覚めそうだわ...,숯 빛깔 아콜라이트라! 맛과 감각을 잘 살렸는데? ,Wow! Zwarte acoliet! De nieuwe smaaksensatie....,Jøss! Svertet akolytt! Den nye smakssensasjonen...,Wow! Czarnoskóry akolita! Nowe doznanie smakowe...,Uau! Acólito assado! Uma nova sensação de sabor...,,"Wow, Acolit Înegrit! Noua senzație...","Ух ты, обугленный служитель! Совсем другое ощущение...",,Vay canına! Karartılmış yardımcı! Yeni tat hissi... -Keep doing that and you'll go blind... but I like it.,TXT_SUB_LOG220,,,,Pokračuj s tím a oslepneš... ale líbí se mi to.,"Bliv ved med det, og du bliver blind... men jeg kan lide det.",Mach so weiter und du wirst blind... aber ich finde es toll.,,,Sigue haciendo eso y te quedarás ciego... pero me gusta.,,Jatka tuota samaan malliin ja sokeudut... mutta pidän siitä.,Continue et tu vas te rendre aveugle.. j'aime bien par contre.,Ha tovább csinálod megvakulsz...mondjuk bejön.,Se continui così diventerai cieco... ma a me piace.,,이 걸 하다보면 네 눈이 좀 멀겠지만... 아찔하고 재밌는 것 같아.,Blijf dat doen en je wordt blind.... maar ik vind het leuk.,"Fortsett med det, og du blir blind... men jeg liker det.","Rób tak dalej, a oślepniesz... ale mi się podoba.",Continua fazendo isso e você ficará cego... mas eu gosto.,,Continuă să faci asta și o să orbești... dar îmi place.,Продолжай в том же духе и ты ослепнешь... но мне это нравится.,,Bunu yapmaya devam edersen kör olacaksın... ama hoşuma gitti. -Guess they won't be inviting us back to dinner!,TXT_SUB_LOG221,,,,"Hádám, že tihle nás už na večeři zvát nebudou!","Jeg tror ikke, de inviterer os tilbage til middag!","Ich glaube nicht, dass sie uns nochmal einladen werden...",,,¡Supongo que no nos invitarán a cenar!,,Eivät varmaankaan kutsu meitä takaisin illalliselle!,Je pense qu'ils ne vont pas nous inviter à diner!,Szerintem nem hívnak vissza vacsorára.,Mi sa che non ci riinviteranno per cena!,,보답으로 저녁에 초대하지 않을 것 같아서 아쉽네! ,Ik denk dat ze ons niet meer zullen uitnodigen om terug te komen eten!,Antar de ikke vil invitere oss på middag igjen!,Chyba nie zaproszą nas z powrotem na kolację!,Acho que não vão nos convidar para jantar!,,Cred că n-o să ne invite la cină!,"Думаю, они не пригласят нас на ужин!",,Sanırım bizi tekrar yemeğe davet etmeyecekler! -We need to get to the top floor.,TXT_SUB_LOG222,,,,Musíme se dostat na vrchní podlaží.,Vi må op på øverste etage.,Wir müssen in die oberste Etage gelangen.,,,Necesitamos llegar a la planta más alta.,,Meidän tarvitsee päästä ylimmälle kerrokselle.,Il faut que l'on aille au dernier étage.,Fel kell jutnunk a legfelső szintre.,Dobbiamo andare al piano di sopra.,,최상층으로 올라가야 해. ,We moeten naar de bovenste verdieping.,Vi må komme oss til øverste etasje.,Musimy dostać się na ostatnie piętro.,Precisamos chegar até o último andar.,,Trebuie să ajungem la ultimul etaj.,Нам нужно попасть на верхний этаж.,,En üst kata çıkmalıyız. -Wait... This looks interesting. Check it out.,TXT_SUB_LOG223,,,,Počkej... Tohle vypadá zajímavě. Pojďme to omrknout.,Vent... Det her ser interessant ud. Tjek det ud.,Warte... Das sieht interessant aus. Sieh mal nach.,,,Espera... Esto parece interesante. Échale un vistazo.,,Odota... Tämä näyttää mielenkiintoiselta. Vilkaisepa.,"Attends.. Ca à l'air intéressant, va voir.",Várjunk csak... érdekesen néz ki. Nézd csak meg.,Aspetta... Questo sembra interessante. Guarda qua.,,잠깐... 저거 뭔가 흥미로워. 확인해보자.,Wacht..... Dit ziet er interessant uit. Kijk maar eens.,Vent litt... Dette ser interessant ut. Sjekk det ut.,Czekaj... To wygląda ciekawie. Sprawdźcie to.,Peraí.... Isso parece interessante. Dá só uma olhada.,,"Stai, asta pare interesant. Ia uite.",Подожди... Выглядит интересно. Проверь.,,Bekle. Bu ilginç görünüyor. Şuna bir bak. -Ugh. That guy gives me the creeps. Let's steer clear.,TXT_SUB_LOG224,,,,"Brr, z toho chlápka mi mrazí v zádech. Radši se mu vyhněme.",Ugh. Den fyr giver mig myrekryb. Lad os holde os væk.,Ugh. da kriegt man ja 'ne Gänsehaut. ,,,Ugh. Ese tipo me da mala espina. Alejémonos.,,"Yöh, onpa puistattava kaveri. Pysytään loitolla.","Eugh, ce type me fout les jetons. Evite le.",Rámjön a frász attól az ürgétől. Húzzunk innen.,Ugh. Quel tizio mi fa venire la pelle d'oca. Stiamogli alla larga.,,"윽, 정말 혐오스러운 녀석들. 청소할 준비를 하자.",Ugh. Die kerel geeft me de kriebels. Laten we wegblijven.,Æsj. Den fyren gir meg frysninger. La oss holde oss unna.,Ugh. Ten facet przyprawia mnie o dreszcze. Odsuńmy się od niego.,Urgh. Esse cara me dá arrepios. Vamos passar longe.,,Ugh. Tipul ăla mă sperie.,Ух. У меня от этого парня мурашки по коже. Давай держаться от него подальше.,,Ugh. Bu adam beni ürpertiyor. Uzak duralım. -"Left! Turn left!... Oh, other left!",TXT_SUB_LOG225,,,,"Doleva! Jdi doleva...! Aha, další doleva!","Til venstre! Drej til venstre!... Åh, anden venstre!",Links! Geh nach links... Zur anderen Seite - links!,,,"¡Izquierda! ¡Gira a la izquierda!... Oh, ¡la otra izquierda!",,"Vasemmalle! Käänny vasemmalle! Aa, toinen vasen!",Gauche! A Gauche... L'autre gauche!,"Balra! Fordulj balra!... Áh, a másik balra!","Sinistra! Vai a sinistra!... Oh, l'altra sinistra!",,"왼쪽! 왼쪽으로 이동해!... 잠깐, 다른 왼쪽!","Links! Sla linksaf!...... Oh, andere links!","Til venstre! Sving til venstre!... Å, andre venstre!","W lewo! Skręć w lewo!... Och, inna lewa!","Esquerda! Vira à esquerda!... Ai, a outra esquerda!",,"Stânga! Stânga!... Oh, cealaltă stânga!","Налево! Поверни налево!... Ой, другое лево!",,"Sola dön! Sola dön!... Oh, diğer sol!" -Typical stubborn pig-headed male!... Unless you're a girl.,TXT_SUB_LOG226,,,,"Typický, tvrdohlavý, paličatý muž! ...Leda že bys byla holka.","Typisk stædig, stædig mand!... Medmindre du er en pige.",Typischer sturer Mann... Sofern du kein Mädchen bist.,,,Típico hombre cabezotan con cara de cerdo!... A menos que seas chica.,,Tyypillinen itsepäinen uppiniskainen mies! Ellet sitten ole tyttö.,"Typique d'un mec borné comme un porc- Sauf si tu est une fille, bien entendu.",Tipikus csökönyös férfi!... Kivétel ha nő vagy.,Tipico testardo maschio dalla testa di maiale!... A meno che tu non sia una ragazza.,,"뻔뻔한 고집불통 남충 놈!... 걱정 마, 너 말고.",Typisch koppig koppig mannetje!...... Tenzij je een meisje bent.,Typisk sta og sta mann!.... Med mindre du er en jente.,"Typowy uparty świniopas!... Chyba, że jesteś dziewczyną.",Típico macho teimoso com cara de porco!... A não ser que você seja menina.,,Bărbat încăpățânat tipic... Asta dacă nu ești femeie.,Типичный упрямый свинопас!... Если только ты не девушка.,,Tipik inatçı domuz kafalı erkek!... Tabii kız değilsen. -"Strong, brutal and silent. My kind of partner.",TXT_SUB_LOG227,,,,"Silný, hrubý a tichý. Přesně můj typ.","Stærk, brutal og tavs. Min type partner.","Stark, brutal und leise. Mein Typ von Partner.",,,"Fuerte, brutal y callado. Mi tipo de compañero.",,"Vahva, raaka ja hiljainen. Mieleiseni kumppani.","Fort, brutal et silencieux. Mon type préféré.","Erős , brutális és csendes. Nekem való partner.","Forte, brutale e silenzioso. Il mio tipo di partner.",,"크고, 아름답고, 과묵하네. 같이 있고 싶은 타입이야.","Sterk, wreed en stil. Mijn soort partner.","Sterk, brutal og stille. Min type partner.","Silny, brutalny i milczący. Mój typ partnera.","Forte, bruto e silencioso. Meu tipo de parceiro.",,"Puternic, brutal și silențios. Genul meu de partener.","Сильный, брутальный и молчаливый. Мой типаж.",,"Güçlü, acımasız ve sessiz. Tam bana göre bir partner." -Okay! I was wrong!,TXT_SUB_LOG228,,,,Dobře! Mýlila jsem se!,Okay! Jeg tog fejl!,"Ok, ich habe mich geirrt.",,,¡OK! ¡Estaba equivocada!,,"Okei, olin väärässä!","Ok, j'avais tort!",Jólvan na! Tévedtem!,Okay! Mi sbagliavo!,,아마도 아니었던 것 같네! ,Oké! Ik had het mis!,Okay! Jeg tok feil!,Dobra! Myliłem się!,Ok! Eu estava errada!,,Bine! Am greșit!,Хорошо! Я была неправа!,,"Tamam, tamam! Yanılmışım!" +When obtaining the “Spontaneous Combustion” achievement",,,Wow! Zčernalý akolyta! Nové kulinářské šílenství...,Wow! Sorte Acolyt! Den nye smagsoplevelse...,Wow! Geschmorter Ministrant! Neue Geschmackssensation...,,,¡Guau! ¡Acólito ennegrecido! La nueva sensación de sabor...,,Vau! Mustaa akoluuttia! Uutuusmakuelämys!,Wow! Acolyte noirci! Goûte à la nouvelle saveur sensationelle!,Wow! Pörkölt ministráns! A szezon új íze...,Wow! Accolito scuro! Il nuovo sensazionale sapore!,うぉう!黒ずんだアコライト!新しい趣味に目覚めそうだわ...,숯 빛깔 아콜라이트라! 맛과 감각을 잘 살렸는데? ,Wow! Zwarte acoliet! De nieuwe smaaksensatie....,Jøss! Svertet akolytt! Den nye smakssensasjonen...,Wow! Czarnoskóry akolita! Nowe doznanie smakowe...,Uau! Acólito assado! Uma nova sensação de sabor...,,"Wow, Acolit Înegrit! Noua senzație...","Ух ты, обугленный служитель! Совсем другое ощущение...",,Wow! Svartklädd akolyt! Den nya smaksensationen...,Vay canına! Karartılmış yardımcı! Yeni tat hissi... +Keep doing that and you'll go blind... but I like it.,TXT_SUB_LOG220,,,,Pokračuj s tím a oslepneš... ale líbí se mi to.,"Bliv ved med det, og du bliver blind... men jeg kan lide det.",Mach so weiter und du wirst blind... aber ich finde es toll.,,,Sigue haciendo eso y te quedarás ciego... pero me gusta.,,Jatka tuota samaan malliin ja sokeudut... mutta pidän siitä.,Continue et tu vas te rendre aveugle.. j'aime bien par contre.,Ha tovább csinálod megvakulsz...mondjuk bejön.,Se continui così diventerai cieco... ma a me piace.,,이 걸 하다보면 네 눈이 좀 멀겠지만... 아찔하고 재밌는 것 같아.,Blijf dat doen en je wordt blind.... maar ik vind het leuk.,"Fortsett med det, og du blir blind... men jeg liker det.","Rób tak dalej, a oślepniesz... ale mi się podoba.",Continua fazendo isso e você ficará cego... mas eu gosto.,,Continuă să faci asta și o să orbești... dar îmi place.,Продолжай в том же духе и ты ослепнешь... но мне это нравится.,,Fortsätt med det där och du blir blind... men jag gillar det.,Bunu yapmaya devam edersen kör olacaksın... ama hoşuma gitti. +Guess they won't be inviting us back to dinner!,TXT_SUB_LOG221,,,,"Hádám, že tihle nás už na večeři zvát nebudou!","Jeg tror ikke, de inviterer os tilbage til middag!","Ich glaube nicht, dass sie uns nochmal einladen werden...",,,¡Supongo que no nos invitarán a cenar!,,Eivät varmaankaan kutsu meitä takaisin illalliselle!,Je pense qu'ils ne vont pas nous inviter à diner!,Szerintem nem hívnak vissza vacsorára.,Mi sa che non ci riinviteranno per cena!,,보답으로 저녁에 초대하지 않을 것 같아서 아쉽네! ,Ik denk dat ze ons niet meer zullen uitnodigen om terug te komen eten!,Antar de ikke vil invitere oss på middag igjen!,Chyba nie zaproszą nas z powrotem na kolację!,Acho que não vão nos convidar para jantar!,,Cred că n-o să ne invite la cină!,"Думаю, они не пригласят нас на ужин!",,Jag antar att de inte kommer att bjuda oss på middag igen!,Sanırım bizi tekrar yemeğe davet etmeyecekler! +We need to get to the top floor.,TXT_SUB_LOG222,,,,Musíme se dostat na vrchní podlaží.,Vi må op på øverste etage.,Wir müssen in die oberste Etage gelangen.,,,Necesitamos llegar a la planta más alta.,,Meidän tarvitsee päästä ylimmälle kerrokselle.,Il faut que l'on aille au dernier étage.,Fel kell jutnunk a legfelső szintre.,Dobbiamo andare al piano di sopra.,,최상층으로 올라가야 해. ,We moeten naar de bovenste verdieping.,Vi må komme oss til øverste etasje.,Musimy dostać się na ostatnie piętro.,Precisamos chegar até o último andar.,,Trebuie să ajungem la ultimul etaj.,Нам нужно попасть на верхний этаж.,,Vi måste ta oss till översta våningen.,En üst kata çıkmalıyız. +Wait... This looks interesting. Check it out.,TXT_SUB_LOG223,,,,Počkej... Tohle vypadá zajímavě. Pojďme to omrknout.,Vent... Det her ser interessant ud. Tjek det ud.,Warte... Das sieht interessant aus. Sieh mal nach.,,,Espera... Esto parece interesante. Échale un vistazo.,,Odota... Tämä näyttää mielenkiintoiselta. Vilkaisepa.,"Attends.. Ca à l'air intéressant, va voir.",Várjunk csak... érdekesen néz ki. Nézd csak meg.,Aspetta... Questo sembra interessante. Guarda qua.,,잠깐... 저거 뭔가 흥미로워. 확인해보자.,Wacht..... Dit ziet er interessant uit. Kijk maar eens.,Vent litt... Dette ser interessant ut. Sjekk det ut.,Czekaj... To wygląda ciekawie. Sprawdźcie to.,Peraí.... Isso parece interessante. Dá só uma olhada.,,"Stai, asta pare interesant. Ia uite.",Подожди... Выглядит интересно. Проверь.,,Vänta lite... Det här ser intressant ut. Kolla in det.,Bekle. Bu ilginç görünüyor. Şuna bir bak. +Ugh. That guy gives me the creeps. Let's steer clear.,TXT_SUB_LOG224,,,,"Brr, z toho chlápka mi mrazí v zádech. Radši se mu vyhněme.",Ugh. Den fyr giver mig myrekryb. Lad os holde os væk.,Ugh. da kriegt man ja 'ne Gänsehaut. ,,,Ugh. Ese tipo me da mala espina. Alejémonos.,,"Yöh, onpa puistattava kaveri. Pysytään loitolla.","Eugh, ce type me fout les jetons. Evite le.",Rámjön a frász attól az ürgétől. Húzzunk innen.,Ugh. Quel tizio mi fa venire la pelle d'oca. Stiamogli alla larga.,,"윽, 정말 혐오스러운 녀석들. 청소할 준비를 하자.",Ugh. Die kerel geeft me de kriebels. Laten we wegblijven.,Æsj. Den fyren gir meg frysninger. La oss holde oss unna.,Ugh. Ten facet przyprawia mnie o dreszcze. Odsuńmy się od niego.,Urgh. Esse cara me dá arrepios. Vamos passar longe.,,Ugh. Tipul ăla mă sperie.,Ух. У меня от этого парня мурашки по коже. Давай держаться от него подальше.,,Usch. Den killen ger mig kalla kårar. Vi håller oss undan.,Ugh. Bu adam beni ürpertiyor. Uzak duralım. +"Left! Turn left!... Oh, other left!",TXT_SUB_LOG225,,,,"Doleva! Jdi doleva...! Aha, další doleva!","Til venstre! Drej til venstre!... Åh, anden venstre!",Links! Geh nach links... Zur anderen Seite - links!,,,"¡Izquierda! ¡Gira a la izquierda!... Oh, ¡la otra izquierda!",,"Vasemmalle! Käänny vasemmalle! Aa, toinen vasen!",Gauche! A Gauche... L'autre gauche!,"Balra! Fordulj balra!... Áh, a másik balra!","Sinistra! Vai a sinistra!... Oh, l'altra sinistra!",,"왼쪽! 왼쪽으로 이동해!... 잠깐, 다른 왼쪽!","Links! Sla linksaf!...... Oh, andere links!","Til venstre! Sving til venstre!... Å, andre venstre!","W lewo! Skręć w lewo!... Och, inna lewa!","Esquerda! Vira à esquerda!... Ai, a outra esquerda!",,"Stânga! Stânga!... Oh, cealaltă stânga!","Налево! Поверни налево!... Ой, другое лево!",,"Vänster! Sväng vänster!... Åh, en annan vänster!","Sola dön! Sola dön!... Oh, diğer sol!" +Typical stubborn pig-headed male!... Unless you're a girl.,TXT_SUB_LOG226,,,,"Typický, tvrdohlavý, paličatý muž! ...Leda že bys byla holka.","Typisk stædig, stædig mand!... Medmindre du er en pige.",Typischer sturer Mann... Sofern du kein Mädchen bist.,,,Típico hombre cabezotan con cara de cerdo!... A menos que seas chica.,,Tyypillinen itsepäinen uppiniskainen mies! Ellet sitten ole tyttö.,"Typique d'un mec borné comme un porc- Sauf si tu est une fille, bien entendu.",Tipikus csökönyös férfi!... Kivétel ha nő vagy.,Tipico testardo maschio dalla testa di maiale!... A meno che tu non sia una ragazza.,,"뻔뻔한 고집불통 남충 놈!... 걱정 마, 너 말고.",Typisch koppig koppig mannetje!...... Tenzij je een meisje bent.,Typisk sta og sta mann!.... Med mindre du er en jente.,"Typowy uparty świniopas!... Chyba, że jesteś dziewczyną.",Típico macho teimoso com cara de porco!... A não ser que você seja menina.,,Bărbat încăpățânat tipic... Asta dacă nu ești femeie.,Типичный упрямый свинопас!... Если только ты не девушка.,,Typiskt en envis svinhuvudman!... Om du inte är en tjej.,Tipik inatçı domuz kafalı erkek!... Tabii kız değilsen. +"Strong, brutal and silent. My kind of partner.",TXT_SUB_LOG227,,,,"Silný, hrubý a tichý. Přesně můj typ.","Stærk, brutal og tavs. Min type partner.","Stark, brutal und leise. Mein Typ von Partner.",,,"Fuerte, brutal y callado. Mi tipo de compañero.",,"Vahva, raaka ja hiljainen. Mieleiseni kumppani.","Fort, brutal et silencieux. Mon type préféré.","Erős , brutális és csendes. Nekem való partner.","Forte, brutale e silenzioso. Il mio tipo di partner.",,"크고, 아름답고, 과묵하네. 같이 있고 싶은 타입이야.","Sterk, wreed en stil. Mijn soort partner.","Sterk, brutal og stille. Min type partner.","Silny, brutalny i milczący. Mój typ partnera.","Forte, bruto e silencioso. Meu tipo de parceiro.",,"Puternic, brutal și silențios. Genul meu de partener.","Сильный, брутальный и молчаливый. Мой типаж.",,"Stark, brutal och tyst. Min typ av partner.","Güçlü, acımasız ve sessiz. Tam bana göre bir partner." +Okay! I was wrong!,TXT_SUB_LOG228,,,,Dobře! Mýlila jsem se!,Okay! Jeg tog fejl!,"Ok, ich habe mich geirrt.",,,¡OK! ¡Estaba equivocada!,,"Okei, olin väärässä!","Ok, j'avais tort!",Jólvan na! Tévedtem!,Okay! Mi sbagliavo!,,아마도 아니었던 것 같네! ,Oké! Ik had het mis!,Okay! Jeg tok feil!,Dobra! Myliłem się!,Ok! Eu estava errada!,,Bine! Am greșit!,Хорошо! Я была неправа!,,Okej! Jag hade fel!,"Tamam, tamam! Yanılmışım!" Too bad we never met... face-to-face.,TXT_SUB_LOG229,"(Strife: Veteran Edition) -Random comment when the player dies with Classic Mode turned off",,,"Škoda, že jsme se nikdy nepotkali... tváří v tvář.",Ærgerligt at vi aldrig mødtes... ansigt til ansigt.,"Schade, dass wir uns noch nie begegnet sind...",,,Una pena que nunca nos conocieramos... cara a cara.,,"Sääli, ettemme koskaan tavanneet... kasvokkain.",C'est dommage qu'on s'est jamais rencontré.. En face à face.,"Kár, hogy sohasem találkoztunk... szemtől szembe.",Peccato che non ci siamo mai incontrati... faccia a faccia.,私達はもう会えなくなったわ...面と向かって。,만나지 못한 게 유감스럽네... 가까이서. ,Jammer dat we elkaar nooit ontmoet hebben..... persoonlijk.,Synd vi aldri møttes... ansikt til ansikt.,"Szkoda, że nigdy nie spotkaliśmy się... twarzą w twarz.",Pena que nunca nos encontramos... cara a cara.,,Păcat că nu ne-am întâlnit... față în față.,"Жаль, мы раньше не встречались... лицом к лицу.",,Hiç tanışmamış olmamız çok kötü... yüz yüze. +Random comment when the player dies with Classic Mode turned off",,,"Škoda, že jsme se nikdy nepotkali... tváří v tvář.",Ærgerligt at vi aldrig mødtes... ansigt til ansigt.,"Schade, dass wir uns noch nie begegnet sind...",,,Una pena que nunca nos conocieramos... cara a cara.,,"Sääli, ettemme koskaan tavanneet... kasvokkain.",C'est dommage qu'on s'est jamais rencontré.. En face à face.,"Kár, hogy sohasem találkoztunk... szemtől szembe.",Peccato che non ci siamo mai incontrati... faccia a faccia.,私達はもう会えなくなったわ...面と向かって。,만나지 못한 게 유감스럽네... 가까이서. ,Jammer dat we elkaar nooit ontmoet hebben..... persoonlijk.,Synd vi aldri møttes... ansikt til ansikt.,"Szkoda, że nigdy nie spotkaliśmy się... twarzą w twarz.",Pena que nunca nos encontramos... cara a cara.,,Păcat că nu ne-am întâlnit... față în față.,"Жаль, мы раньше не встречались... лицом к лицу.",,Synd att vi aldrig träffades... ansikte mot ansikte.,Hiç tanışmamış olmamız çok kötü... yüz yüze. I had dreams for you... Tough shit.,TXT_SUB_LOG230,"(Strife: Veteran Edition) -Random comment when the player dies with Classic Mode turned off",,,Snila jsem o tobě... Kurva.,Jeg havde drømme om dig... Det er sgu hårdt.,Ich hatte Träume für dich. Scheiße.,,,Tenía sueños para ti... Lástima.,,Elättelin toiveita sinusta... Paska mäihä.,J'avais des grands rêves pour toi.. Franchement dommage.,Álmodtam számodra valamit... Szar ügy.,Ho fatto sogni per te... Che peccato.,私は貴方に希望を抱いていた...クソ世知辛いわ。,너를 꿈꿔왔어... 꿈은 꿈이였나봐.,Ik had dromen voor je.... Moeilijke shit.,Jeg hadde drømmer for deg... Synd for deg.,Miałem dla ciebie marzenia... Twarde gówno.,Eu tinha uma grande expectativa sobre você... Que merda.,,Aveam visuri pentru tine... Rahatule...,Я так надеялся на тебя... Упрямый засранец.,,Senin için hayallerim vardı. Zor iş. -"No. Don't enter the town hall. It's not safe anymore. Our cover's been blown. That's why it's raining heavy metal. Kill as many of those big boys as you can. They're called ""Crusaders"". When you're done, I'll guide you to Macil.",TXT_SUB_LOG231,,,,"Ne. Nechoď do radnice, už není bezpečná. Byli jsme odhaleni, proto nám prší olovo na hlavu. Zabij kolik těch velkých kluků můžeš. Říká se jim Křižáci. Když jsi hotový, nasměruju tě k Macilovi.","Nej. Du må ikke gå ind på rådhuset. Det er ikke sikkert længere. Vores dække er blevet afsløret. Det er derfor, det regner heavy metal. Dræb så mange af de store drenge, som du kan. De kaldes ""Crusaders"". Når I er færdige, fører jeg jer til Macil.","Nein, betrete das Rathaus nicht. Es ist nicht mehr sicher. Unsere Tarnung ist aufgeflogen. Darum regnet es Schwermetall. Erledige so viele von den großen Robotern, wie du kannst. Sie werden „Ordensritter“ genannt. Wenn du das erledigt hast führe ich dich zu Macil.",,,"No. No entres en el ayuntamiento. Ya no es seguro. Nuestra tapadera ha sido descubierta. Por eso está lloviendo metal. Mata a tantos de esos grandotes como puedas. Se llaman ""Cruzados"". Cuando hayas terminado, te guiaré hasta Macil.",,"Ei, älä mene kaupungintaloon. Se ei ole enää turvallista; olemme paljastuneet. Sen takia sataa metallia. Tapa noita isoja poikia niin monta kuin pysyt. Niitä kutsutaan ""ristiretkeläisiksi"". Kun olet valmis, johdatan sinut Macilin luokse.","Non, n'entre pas dans la mairie, notre couverture est foutue. C'est pour ça que tout est en train de péter. Détruis tous les gros machins que tu croise, on les appelle les ""Croisés"". Quand tu as fini, je te dirais où se trouve Macil.","Ne menj be a városházára. Már nem biztonságos. Lelepleződtünk. Ezért ennyire sűrű az ólomeső. Ölj meg annyi nagy fiút, amennyit csak tudsz. ""Keresztes"" névre hallgatnak. Ha kész vagy, elvezetlek macilhoz.","No. Non entrare nel municipio. Non è più sicuro. La nostra copertura è saltata. È per questo che sta piovendo piombo. Distruggi più di questi grossi robot che puoi. Si chiamano ""Crociati"". Quando hai finito, di guiderò da Macil.",,"잠깐, 시청으로 가지 마. 이미 발각되어서 이젠 안전하지 않아. 아마도 총알의 비가 내리는 유일한 이유일 거야. 최선을 다해서 저 커다란 친구들을 격파해봐. 저놈들은 ""크루세이더"" 라고 해. 이 일을 끝마치면, 마실이 있는 곳으로 안내해줄게. ","Nee. Ga het stadhuis niet binnen. Het is niet meer veilig. Onze dekmantel is opgeblazen. Daarom regent het zwaar metaal. Dood zoveel mogelijk van die grote jongens als je kunt. Ze worden ""Kruisvaarders"" genoemd. Als je klaar bent, begeleid ik je naar Macil.","Nei. Ikke gå inn i rådhuset. Det er ikke trygt lenger. Vi er avslørt. Det er derfor det regner heavy metal. Drep så mange av de store gutta du kan. De kalles ""korsfarere"". Når du er ferdig, viser jeg deg veien til Macil.","Nie. Nie wchodź do ratusza. To już nie jest bezpieczne. Nasza przykrywka została zdmuchnięta. To dlatego pada heavy metal. Zabij jak najwięcej tych wielkich chłopców. Nazywają się ""Crusaders"". Kiedy skończysz, zaprowadzę cię do Macil.","Não. Não entre na prefeitura. Não é mais seguro. Fomos descobertos. É por isso que está vindo chumbo grosso pra todo lado. Mate o máximo possível desses grandalhões. São chamados de ""Cruzados"". Quando você terminar, eu te levo pro Macil.",,"Nu. Nu intra în oraș. Ni s-a dus acoperirea. De asta plouă cu metale grele. Omoară cât de mulți băieți duri poți. Se cheamă ""Cruciați"". Când ești gata o să te îndrum spre Macil.","Нет. Не входи в ратушу. Там небезопасно. Наше прикрытие сорвано. Вот почему идёт дождь из тяжёлого металла. Убей как можно больше этих здоровяков. Они называются «Крестоносцы». Когда закончишь, я отведу тебя к Мэйсилу.",,"Hayır. Belediye binasına girme. Artık güvenli değil. Kimliğimiz açığa çıktı. Bu yüzden heavy metal yağıyor. O koca oğlanlardan öldürebildiğiniz kadarını öldürün. Onlara ""Haçlılar"" deniyor. İşiniz bittiğinde, sizi Macil'e götüreceğim." -"Good work, friend! It's time to bring you inside.",TXT_SUB_LOG232,,,,"Dobrá práce, kamaráde! Je čas přivést tě dovnitř.","Godt arbejde, min ven! Det er tid til at bringe dig indenfor.","Gute Arbeit, mein Freund. Es ist Zeit dich hereinzubringen.",,,"¡Buen trabajo, amigo! Es hora de traerte adentro.",,"Hyvää työtä, ystävä! On aika tuoda sinut sisälle.","Bien joué, mon ami! Il est temps de te faire rentrer.",Szép munka barátom! Ideje bevinnelek.,"Ottimo lavoro, amico! È ora di farti entrare.",,"건투를 빌어, 친구! 안으로 들여보내 줄게. ","Goed werk, vriend! Het is tijd om je binnen te brengen.","Godt jobbet, min venn! Det er på tide å få deg inn.","Dobra robota, przyjacielu! Czas wprowadzić cię do środka.","Bom trabalho, amigo! Hora de trazê-lo pra dentro.",,"Bună treabă, prietene! E timpul să te aduc înăuntru!","Хорошая работа, друг! Пришло время впустить тебя внутрь.",,"İyi iş, dostum! Seni içeri götürme vakti geldi." -"Watch out for those Crusaders. They're big, hunking robots, and mean as hell. We don't know jack about their weapons, but odds are... you're outmatched. Careful.",TXT_SUB_LOG233,,,,"Pozor na ty Křižáky. Jsou to velcí, mohutní roboti a zatraceně zlí. Nevíme nic o jejich zbraních. Vypadá to že... jsou v přesile. Opatrně.","Pas på de korsfarere. De er store, store robotter, og onde som bare fanden. Vi ved ikke noget om deres våben, men oddsene er... at I er underlegne. Pas på.",Sieh dich vor den Ordensrittern vor. Das sind große und mächtige Roboter und höllisch gefährlich. Wir wissen nichts über ihre Waffen aber sie übertreffen deine bei weitem. Vorsicht!,,,"Ten cuidado con esos Cruzados. Son unos robots enormes y despiadados. No sabemos nada sobre sus armas, pero lo probable es... que te lleven ventaja. Cuidado.",,"Varo noita ristiretkeläisiä. Ne ovat isoja järkälemäisiä robotteja ja helvetin häijyjä. Emme tiedä yhtikäs mitään niiden aseista, mutta todennäköisyys on... että olet heikoilla. Varovaisesti.","Fais attention aux croisés, ce sont des sacrément grosses machines, et salement méchantes, aussi. On ne sait pas quelles armes ils utilisent, mais il est probable qu'ils en ont.. Plus que toi. Fais attention.","Vigyázz azokkal a keresztesekkel. Nagy, testes robotok, és morcosok is. nem sokat tudunk a fegyvereikről, de az esélyied... nem túl fényesek. Vigyázz magadra.","Attento a questi Crociati. Sono grossi, potenti robot e davvero pericolosi. Non sappiamo nulla sulle loro armi ma è molto probabile... che tu sia surclassato. Attento.",,"크루세이더를 조심해. 저놈들은 커다랗고 강력한 기동 병기야. 난폭하기도 하지. 놈들의 무장이 뭔지 모르지만, 중요한 점은 넌 포위됐다는 거지. 조심해. ","Kijk uit voor die kruisvaarders. Het zijn grote, hangende robots, en gemeen als de hel. We weten niet hoe het met hun wapens zit, maar de kans is groot dat je niet bij elkaar past. Voorzichtig.","Se opp for korsfarerne. De er store, kjekke roboter, og slemme som faen. Vi vet ingenting om våpnene deres, men det er sannsynlig at dere er underlegne. Forsiktig.","Uważaj na tych Krzyżowców. To wielkie, potężne roboty i wredne jak diabli. Nie wiemy nic o ich broni, ale prawdopodobnie... nie macie szans. Ostrożnie.","Cuidado com esses Cruzados. São robôs grandes e perigosos pra caramba. Não sabemos merda nenhuma sobre as suas armas, mas as chances são de que... você está em desvantagem. Cuidado.",,"Ai grijă la Cruciați. Sunt roboți imenși, și duri ca naiba. Nu știm absolut nimic despre armamentul lor, dar șansele sunt... nu ești pe măsura lor. Grijă.","Остерегайся крестоносцев. Они большие, громадные роботы, и чертовски злые. Мы не знаем ничего об их оружии, но, скорее всего... ты не справишься. Будь осторожен.",,"Şu Haçlılara dikkat et. Onlar büyük, iri robotlar ve çok acımasızlar. Silahları hakkında bir şey bilmiyoruz, ama ihtimaller... rakibiniz yok. Dikkatli olun." -"Great job. You're my idea of a good time. Now, without anyone seeing you, go through the door on the right, head on upstairs and meet the man.",TXT_SUB_LOG234,,,,"Skvělá práce. Vypadáš jako člověk do nepohody. A teď, bez toho, aby tě někdo uviděl, projdi dveřmi napravo, jdi po schodech nahoru a setkej se s ním.","Godt gået. Du er min idé om en god tid. Gå nu, uden at nogen ser dig, gennem døren til højre, gå op ad trappen og mød manden.","Gute Arbeit. Das macht mir richtig Freude. Nun gehe - ohne dass man dich sieht - durch die Tür da rechts, und treffe den Mann.",,,"Buen trabajo. Eres mi idea de una buena juerga. Ahora, sin que te vean, ve por la puerta a la derecha, sube las escaleras y conoce al hombre.",,"Hyvää työtä. Vastaat mielikuvaani hyvästä ajanvietteestä. Mene nyt kenenkään näkemättä oikeanpuoleisen oven läpi, kulje yläkertaan ja tapaa mies.","Bien joué, tu connaîs bien mon idée d'une bonne fête. Maintenant, sans que personne ne te voie, passe par la porte à droite, monte à l'étage et rencontre le type.","Remek munka. Te vagy a jól eltöltött idő definíciója. Most pedig anélkül, hogy bárki meglátna, menj a jobb oldalon levő ajtóhoz, majd az emeleten találkozz az emberünkkel.","Ottimo lavoro. Tu si che mi fai divertire. Ora, senza che nessuno ti veda, attraversa la porta alla tua destra, vai di sopra e incontralo.",,"잘 싸웠어. 내가 생각지도 못한 기발한 생각을 많이 하네. 이제, 모두가 너를 보지 않는 동안 오른쪽 문으로 들어가서 계단을 올라가고 남자를 만나.","Goed werk. Jij bent mijn idee van een goede tijd. Nu, zonder dat iemand je ziet, ga door de deur aan de rechterkant, ga naar boven en ontmoet de man.","Bra jobbet. Du er min idé om en god tid. Nå, uten at noen ser deg, gå gjennom døren til høyre, gå ovenpå og møt mannen.","Świetna robota. Jesteś moim pomysłem na dobrą zabawę. Przejdź przez drzwi po prawej, wejdź na górę i spotkaj się z tym człowiekiem.","Muito bom. Você sabe mesmo como entreter alguém. Agora, sem ninguém te ver, entre pela porta à direita, suba as escadas e encontre o cara.",,"Bună treabă. Acum, fără nimeni care să te vadă, du-te prin ușa de la dreapta, la etaj, și întâlnește-l.","Отличная работа. Ты - мой способ хорошо провести время. Теперь, чтобы никто тебя не увидел, пройди через дверь справа, поднимись наверх и встреться с мужчиной.",,"İyi iş çıkardın. Sen benim iyi vakit geçirme anlayışımsın. Şimdi, kimse seni görmeden, sağdaki kapıdan geç, yukarı çık ve adamla buluş." -"You let anyone see you, we'll have your head.",TXT_SUB_LOG235,,,,"Dovolíš, aby tě někdo uviděl, a budeme mít tvou hlavu.","Hvis du lader nogen se dig, får vi dit hoved.","Wenn man dich sieht, machen wir dich alle.",,,"Si dejas que te vean, tomaremos tu cabeza.",,"Jos annat kenenkään nähdä sinut, pääsi on vadilla.","Si qui que ce soit te voit, on aura ta tête.","Ha bárki meglát, levesszük a fejed.","Se ti vede qualcuno, avremo la tua testa.",,결국엔 사람들이 너를 보았네. 사적인 건 아니지만 넌 죽어줘야겠어. ,"Als je iemand je laat zien, hebben we je hoofd.","Hvis noen ser deg, tar vi hodet ditt.","Jeśli ktoś cię zobaczy, dostaniesz głowę.","Se você deixar alguém te ver, a sua cabeça é nossa.",,Lași pe cineva să te vadă și-ți luăm capul.,"Если ты позволишь кому-нибудь увидеть себя, мы получим твою голову.",,"Birinin seni görmesine izin verirsen, kelleni alırız." -"You stupid, stumbling, club-footed hunchback imbecile! You've given us away!",TXT_SUB_LOG236,,,,"Ty hloupý, klopýtavý, těžkopádný idiotský hrbáči! Prozradils nás!","Din dumme, snublende, klumpfodede, pukkelryggede idiot! Du har afsløret os!","Du dummer, ungeschickter, klumpfüßiger, buckliger Trottel. Du hast uns verraten.",,,¡Estúpido patán! ¡Nos has traicionado!,,"Sinä typerä, kömpelö, kampurajalkainen imbesilli! Olet paljastanut meidät!","Espèce d'abruti, crétin bossu pas foutu de marcher droit! Tu fait foirer notre couverture!",Te hülye botladozó kétballábú púpos állat! Észrevettek minket miattad!,"Stupido, impiastro, gobbo imbecille! Ci hai fatto scoprire!",,"이 어리석은, 멍청한, 짜리몽땅한 말미잘 얼간이! 우리 곁을 떠나다니!","Jij stomme, struikelende, knotsvoetige bochelende imbeciel! Je hebt ons weggegeven!","Din dumme, klumpfotete, pukkelryggede idiot! Du har avslørt oss!","Ty głupi, potykający się, garbaty imbecylu! Wydałeś nas!",Seu imbecil idiota estúpido duma figa! Você nos entregou!,,Imbecilule! Ne-ai dat de gol!,"Ты тупой, неуклюжий, косолапый горбатый имбецил! Ты нас выдал!",,"Seni aptal, tökezleyen, sopa ayaklı, kambur embesil! Bizi ele verdin!" -"I wish I was waiting for you behind that door... but I've got to stay underground. It's time for you to meet our leader, Macil.",TXT_SUB_LOG237,,,,"Přála bych si, abych to byla já, kdo bude čekat za těmi dveřmi... ale musím zůstat v podzemí. Je čas setkat se s naším vůdcem, Macilem.","Jeg ville ønske, jeg ventede på dig bag den dør ... men jeg må blive under jorden. Det er tid til at du skal møde vores leder, Macil.","Ich wünschte, ich würde hinter der Tür dort warten... aber ich muss im Untergrund bleiben. Es ist Zeit, unseren Anführer, Macil, zu treffen.",,,"Ojalá fuera yo esperando tras esa puerta... Pero debo mantenerme bajo tierra. Es hora de que conozcas a nuestro lider, Macil.",,"Kunpa olisin voinut olla sinua ovella vastassa, mutta minun on pysyttävä maan alla. Sinun on aika tavata johtajamme, Macilin.","J'aurais adoré être de l'autre côté de cette porte.. Mais il faut que je reste sous terre. Il est temps que tu rencontre notre leader, Macil.","Bárcsak Én várhatnálak az ajtó mögött... de a föld alatt kell maradnom. Itt az ideje, hogy megismerd a vezetőnket, Macilt.","Vorrei esserci io ad attenderti dietro la porta... ma devo rimanere sottoterra. È tempo per te di incontrare il nostro leader, Macil.",,저 문 앞에서 내가 기다리고 있었으면 얼마나 좋을까... 하지만 난 지하에서 임무를 수행해야 해. 마실 사령관을 만날 준비를 해.,Ik wou dat ik achter die deur op je zat te wachten.... maar ik moet ondergronds blijven. Het is tijd om onze leider Macil te ontmoeten.,"Jeg skulle ønske jeg ventet på deg bak den døra, men jeg må holde meg under jorden. Det er på tide at du møter lederen vår, Macil.","Chciałbym czekać na ciebie za tymi drzwiami... ale muszę zostać pod ziemią. Czas, byś poznał naszego przywódcę, Macila.","Eu queria estar te esperando por trás daquela porta... mas eu tenho que ficar no subterrâneo. É hora de você conhecer o nosso líder, Macil.",,"Speram ca eu să te aștept în spatele ușii... dar trebuie să rămân în subteran. E timpul să ne cunoști liderul, Macil.","Хотела бы я ждать тебя за этой дверью... но я должна оставаться под землёй. Пришло время познакомить тебя с нашим лидером, Мэйсилом.",,Keşke o kapının arkasında seni bekliyor olsaydım... ama yeraltında kalmalıyım. Liderimiz Macil ile tanışma vaktin geldi. -,,Blackbird's remarks embedded in other conversations,,,,,,,,,,,,,,,,,,,,,,,, +Random comment when the player dies with Classic Mode turned off",,,Snila jsem o tobě... Kurva.,Jeg havde drømme om dig... Det er sgu hårdt.,Ich hatte Träume für dich. Scheiße.,,,Tenía sueños para ti... Lástima.,,Elättelin toiveita sinusta... Paska mäihä.,J'avais des grands rêves pour toi.. Franchement dommage.,Álmodtam számodra valamit... Szar ügy.,Ho fatto sogni per te... Che peccato.,私は貴方に希望を抱いていた...クソ世知辛いわ。,너를 꿈꿔왔어... 꿈은 꿈이였나봐.,Ik had dromen voor je.... Moeilijke shit.,Jeg hadde drømmer for deg... Synd for deg.,Miałem dla ciebie marzenia... Twarde gówno.,Eu tinha uma grande expectativa sobre você... Que merda.,,Aveam visuri pentru tine... Rahatule...,Я так надеялся на тебя... Упрямый засранец.,,Jag hade drömmar om dig... Det är jobbigt.,Senin için hayallerim vardı. Zor iş. +"No. Don't enter the town hall. It's not safe anymore. Our cover's been blown. That's why it's raining heavy metal. Kill as many of those big boys as you can. They're called ""Crusaders"". When you're done, I'll guide you to Macil.",TXT_SUB_LOG231,,,,"Ne. Nechoď do radnice, už není bezpečná. Byli jsme odhaleni, proto nám prší olovo na hlavu. Zabij kolik těch velkých kluků můžeš. Říká se jim Křižáci. Když jsi hotový, nasměruju tě k Macilovi.","Nej. Du må ikke gå ind på rådhuset. Det er ikke sikkert længere. Vores dække er blevet afsløret. Det er derfor, det regner heavy metal. Dræb så mange af de store drenge, som du kan. De kaldes ""korsfarere"". Når I er færdige, fører jeg jer til Macil.","Nein, betrete das Rathaus nicht. Es ist nicht mehr sicher. Unsere Tarnung ist aufgeflogen. Darum regnet es Schwermetall. Erledige so viele von den großen Robotern, wie du kannst. Sie werden „Ordensritter“ genannt. Wenn du das erledigt hast führe ich dich zu Macil.",,,"No. No entres en el ayuntamiento. Ya no es seguro. Nuestra tapadera ha sido descubierta. Por eso está lloviendo metal. Mata a tantos de esos grandotes como puedas. Se llaman ""Cruzados"". Cuando hayas terminado, te guiaré hasta Macil.",,"Ei, älä mene kaupungintaloon. Se ei ole enää turvallista; olemme paljastuneet. Sen takia sataa metallia. Tapa noita isoja poikia niin monta kuin pysyt. Niitä kutsutaan ""ristiretkeläisiksi"". Kun olet valmis, johdatan sinut Macilin luokse.","Non, n'entre pas dans la mairie, notre couverture est foutue. C'est pour ça que tout est en train de péter. Détruis tous les gros machins que tu croise, on les appelle les ""Croisés"". Quand tu as fini, je te dirais où se trouve Macil.","Ne menj be a városházára. Már nem biztonságos. Lelepleződtünk. Ezért ennyire sűrű az ólomeső. Ölj meg annyi nagy fiút, amennyit csak tudsz. ""Keresztes"" névre hallgatnak. Ha kész vagy, elvezetlek macilhoz.","No. Non entrare nel municipio. Non è più sicuro. La nostra copertura è saltata. È per questo che sta piovendo piombo. Distruggi più di questi grossi robot che puoi. Si chiamano ""Crociati"". Quando hai finito, di guiderò da Macil.",,"잠깐, 시청으로 가지 마. 이미 발각되어서 이젠 안전하지 않아. 아마도 총알의 비가 내리는 유일한 이유일 거야. 최선을 다해서 저 커다란 친구들을 격파해봐. 저놈들은 ""크루세이더"" 라고 해. 이 일을 끝마치면, 마실이 있는 곳으로 안내해줄게. ","Nee. Ga het stadhuis niet binnen. Het is niet meer veilig. Onze dekmantel is opgeblazen. Daarom regent het zwaar metaal. Dood zoveel mogelijk van die grote jongens als je kunt. Ze worden ""Kruisvaarders"" genoemd. Als je klaar bent, begeleid ik je naar Macil.","Nei. Ikke gå inn i rådhuset. Det er ikke trygt lenger. Vi er avslørt. Det er derfor det regner heavy metal. Drep så mange av de store gutta du kan. De kalles ""korsfarere"". Når du er ferdig, viser jeg deg veien til Macil.","Nie. Nie wchodź do ratusza. To już nie jest bezpieczne. Nasza przykrywka została zdmuchnięta. To dlatego pada heavy metal. Zabij jak najwięcej tych wielkich chłopców. Nazywają się ""krzyżowcami"". Kiedy skończysz, zaprowadzę cię do Macil.","Não. Não entre na prefeitura. Não é mais seguro. Fomos descobertos. É por isso que está vindo chumbo grosso pra todo lado. Mate o máximo possível desses grandalhões. São chamados de ""Cruzados"". Quando você terminar, eu te levo pro Macil.",,"Nu. Nu intra în oraș. Ni s-a dus acoperirea. De asta plouă cu metale grele. Omoară cât de mulți băieți duri poți. Se cheamă ""Cruciați"". Când ești gata o să te îndrum spre Macil.","Нет. Не входи в ратушу. Там небезопасно. Наше прикрытие сорвано. Вот почему идёт дождь из тяжёлого металла. Убей как можно больше этих здоровяков. Они называются «Крестоносцы». Когда закончишь, я отведу тебя к Мэйсилу.",,"Nej. Gå inte in i stadshuset. Det är inte säkert längre. Vår täckmantel är avslöjad. Det är därför det regnar heavy metal. Döda så många av de stora pojkarna som du kan. De kallas ""korsfarare"". När du är klar guidar jag dig till Macil.","Hayır. Belediye binasına girme. Artık güvenli değil. Kimliğimiz açığa çıktı. Bu yüzden heavy metal yağıyor. O koca oğlanlardan öldürebildiğiniz kadarını öldürün. Onlara ""Haçlılar"" deniyor. İşiniz bittiğinde, sizi Macil'e götüreceğim." +"Good work, friend! It's time to bring you inside.",TXT_SUB_LOG232,,,,"Dobrá práce, kamaráde! Je čas přivést tě dovnitř.","Godt arbejde, min ven! Det er tid til at bringe dig indenfor.","Gute Arbeit, mein Freund. Es ist Zeit dich hereinzubringen.",,,"¡Buen trabajo, amigo! Es hora de traerte adentro.",,"Hyvää työtä, ystävä! On aika tuoda sinut sisälle.","Bien joué, mon ami! Il est temps de te faire rentrer.",Szép munka barátom! Ideje bevinnelek.,"Ottimo lavoro, amico! È ora di farti entrare.",,"건투를 빌어, 친구! 안으로 들여보내 줄게. ","Goed werk, vriend! Het is tijd om je binnen te brengen.","Godt jobbet, min venn! Det er på tide å få deg inn.","Dobra robota, przyjacielu! Czas wprowadzić cię do środka.","Bom trabalho, amigo! Hora de trazê-lo pra dentro.",,"Bună treabă, prietene! E timpul să te aduc înăuntru!","Хорошая работа, друг! Пришло время впустить тебя внутрь.",,"Bra jobbat, min vän! Det är dags att ta in dig.","İyi iş, dostum! Seni içeri götürme vakti geldi." +"Watch out for those Crusaders. They're big, hunking robots, and mean as hell. We don't know jack about their weapons, but odds are... you're outmatched. Careful.",TXT_SUB_LOG233,,,,"Pozor na ty Křižáky. Jsou to velcí, mohutní roboti a zatraceně zlí. Nevíme nic o jejich zbraních. Vypadá to že... jsou v přesile. Opatrně.","Pas på de korsfarere. De er store, store robotter, og onde som bare fanden. Vi ved ikke noget om deres våben, men oddsene er... at I er underlegne. Pas på.",Sieh dich vor den Ordensrittern vor. Das sind große und mächtige Roboter und höllisch gefährlich. Wir wissen nichts über ihre Waffen aber sie übertreffen deine bei weitem. Vorsicht!,,,"Ten cuidado con esos Cruzados. Son unos robots enormes y despiadados. No sabemos nada sobre sus armas, pero lo probable es... que te lleven ventaja. Cuidado.",,"Varo noita ristiretkeläisiä. Ne ovat isoja järkälemäisiä robotteja ja helvetin häijyjä. Emme tiedä yhtikäs mitään niiden aseista, mutta todennäköisyys on... että olet heikoilla. Varovaisesti.","Fais attention aux croisés, ce sont des sacrément grosses machines, et salement méchantes, aussi. On ne sait pas quelles armes ils utilisent, mais il est probable qu'ils en ont.. Plus que toi. Fais attention.","Vigyázz azokkal a keresztesekkel. Nagy, testes robotok, és morcosok is. nem sokat tudunk a fegyvereikről, de az esélyied... nem túl fényesek. Vigyázz magadra.","Attento a questi Crociati. Sono grossi, potenti robot e davvero pericolosi. Non sappiamo nulla sulle loro armi ma è molto probabile... che tu sia surclassato. Attento.",,"크루세이더를 조심해. 저놈들은 커다랗고 강력한 기동 병기야. 난폭하기도 하지. 놈들의 무장이 뭔지 모르지만, 중요한 점은 넌 포위됐다는 거지. 조심해. ","Kijk uit voor die kruisvaarders. Het zijn grote, hangende robots, en gemeen als de hel. We weten niet hoe het met hun wapens zit, maar de kans is groot dat je niet bij elkaar past. Voorzichtig.","Se opp for korsfarerne. De er store, kjekke roboter, og slemme som faen. Vi vet ingenting om våpnene deres, men det er sannsynlig at dere er underlegne. Forsiktig.","Uważaj na tych Krzyżowców. To wielkie, potężne roboty i wredne jak diabli. Nie wiemy nic o ich broni, ale prawdopodobnie... nie macie szans. Ostrożnie.","Cuidado com esses Cruzados. São robôs grandes e perigosos pra caramba. Não sabemos merda nenhuma sobre as suas armas, mas as chances são de que... você está em desvantagem. Cuidado.",,"Ai grijă la Cruciați. Sunt roboți imenși, și duri ca naiba. Nu știm absolut nimic despre armamentul lor, dar șansele sunt... nu ești pe măsura lor. Grijă.","Остерегайся крестоносцев. Они большие, громадные роботы, и чертовски злые. Мы не знаем ничего об их оружии, но, скорее всего... ты не справишься. Будь осторожен.",,"Se upp för de där korsfararna. De är stora, jättelika robotar och elaka som fan. Vi vet inget om deras vapen, men oddsen är... att ni är underlägsna. Var försiktig.","Şu Haçlılara dikkat et. Onlar büyük, iri robotlar ve çok acımasızlar. Silahları hakkında bir şey bilmiyoruz, ama ihtimaller... rakibiniz yok. Dikkatli olun." +"Great job. You're my idea of a good time. Now, without anyone seeing you, go through the door on the right, head on upstairs and meet the man.",TXT_SUB_LOG234,,,,"Skvělá práce. Vypadáš jako člověk do nepohody. A teď, bez toho, aby tě někdo uviděl, projdi dveřmi napravo, jdi po schodech nahoru a setkej se s ním.","Godt gået. Du er min idé om en god tid. Gå nu, uden at nogen ser dig, gennem døren til højre, gå op ad trappen og mød manden.","Gute Arbeit. Das macht mir richtig Freude. Nun gehe - ohne dass man dich sieht - durch die Tür da rechts, und treffe den Mann.",,,"Buen trabajo. Eres mi idea de una buena juerga. Ahora, sin que te vean, ve por la puerta a la derecha, sube las escaleras y conoce al hombre.",,"Hyvää työtä. Vastaat mielikuvaani hyvästä ajanvietteestä. Mene nyt kenenkään näkemättä oikeanpuoleisen oven läpi, kulje yläkertaan ja tapaa mies.","Bien joué, tu connaîs bien mon idée d'une bonne fête. Maintenant, sans que personne ne te voie, passe par la porte à droite, monte à l'étage et rencontre le type.","Remek munka. Te vagy a jól eltöltött idő definíciója. Most pedig anélkül, hogy bárki meglátna, menj a jobb oldalon levő ajtóhoz, majd az emeleten találkozz az emberünkkel.","Ottimo lavoro. Tu si che mi fai divertire. Ora, senza che nessuno ti veda, attraversa la porta alla tua destra, vai di sopra e incontralo.",,"잘 싸웠어. 내가 생각지도 못한 기발한 생각을 많이 하네. 이제, 모두가 너를 보지 않는 동안 오른쪽 문으로 들어가서 계단을 올라가고 남자를 만나.","Goed werk. Jij bent mijn idee van een goede tijd. Nu, zonder dat iemand je ziet, ga door de deur aan de rechterkant, ga naar boven en ontmoet de man.","Bra jobbet. Du er min idé om en god tid. Nå, uten at noen ser deg, gå gjennom døren til høyre, gå ovenpå og møt mannen.","Świetna robota. Jesteś moim pomysłem na dobrą zabawę. Przejdź przez drzwi po prawej, wejdź na górę i spotkaj się z tym człowiekiem.","Muito bom. Você sabe mesmo como entreter alguém. Agora, sem ninguém te ver, entre pela porta à direita, suba as escadas e encontre o cara.",,"Bună treabă. Acum, fără nimeni care să te vadă, du-te prin ușa de la dreapta, la etaj, și întâlnește-l.","Отличная работа. Ты - мой способ хорошо провести время. Теперь, чтобы никто тебя не увидел, пройди через дверь справа, поднимись наверх и встреться с мужчиной.",,"Bra jobbat. Du är min idé om att ha roligt. Nu, utan att någon ser dig, gå genom dörren till höger, gå upp på övervåningen och möt mannen.","İyi iş çıkardın. Sen benim iyi vakit geçirme anlayışımsın. Şimdi, kimse seni görmeden, sağdaki kapıdan geç, yukarı çık ve adamla buluş." +"You let anyone see you, we'll have your head.",TXT_SUB_LOG235,,,,"Dovolíš, aby tě někdo uviděl, a budeme mít tvou hlavu.","Hvis du lader nogen se dig, får vi dit hoved.","Wenn man dich sieht, machen wir dich alle.",,,"Si dejas que te vean, tomaremos tu cabeza.",,"Jos annat kenenkään nähdä sinut, pääsi on vadilla.","Si qui que ce soit te voit, on aura ta tête.","Ha bárki meglát, levesszük a fejed.","Se ti vede qualcuno, avremo la tua testa.",,결국엔 사람들이 너를 보았네. 사적인 건 아니지만 넌 죽어줘야겠어. ,"Als je iemand je laat zien, hebben we je hoofd.","Hvis noen ser deg, tar vi hodet ditt.","Jeśli ktoś cię zobaczy, dostaniesz głowę.","Se você deixar alguém te ver, a sua cabeça é nossa.",,Lași pe cineva să te vadă și-ți luăm capul.,"Если ты позволишь кому-нибудь увидеть себя, мы получим твою голову.",,"Om någon ser dig, så tar vi ditt huvud.","Birinin seni görmesine izin verirsen, kelleni alırız." +"You stupid, stumbling, club-footed hunchback imbecile! You've given us away!",TXT_SUB_LOG236,,,,"Ty hloupý, klopýtavý, těžkopádný idiotský hrbáči! Prozradils nás!","Din dumme, snublende, klumpfodede, pukkelryggede idiot! Du har afsløret os!","Du dummer, ungeschickter, klumpfüßiger, buckliger Trottel. Du hast uns verraten.",,,¡Estúpido patán! ¡Nos has traicionado!,,"Sinä typerä, kömpelö, kampurajalkainen imbesilli! Olet paljastanut meidät!","Espèce d'abruti, crétin bossu pas foutu de marcher droit! Tu fait foirer notre couverture!",Te hülye botladozó kétballábú púpos állat! Észrevettek minket miattad!,"Stupido, impiastro, gobbo imbecille! Ci hai fatto scoprire!",,"이 어리석은, 멍청한, 짜리몽땅한 말미잘 얼간이! 우리 곁을 떠나다니!","Jij stomme, struikelende, knotsvoetige bochelende imbeciel! Je hebt ons weggegeven!","Din dumme, klumpfotete, pukkelryggede idiot! Du har avslørt oss!","Ty głupi, potykający się, garbaty imbecylu! Wydałeś nas!",Seu imbecil idiota estúpido duma figa! Você nos entregou!,,Imbecilule! Ne-ai dat de gol!,"Ты тупой, неуклюжий, косолапый горбатый имбецил! Ты нас выдал!",,"Din dumma, snubblande, klumpfotade puckelryggiga idiot! Du har avslöjat oss!","Seni aptal, tökezleyen, sopa ayaklı, kambur embesil! Bizi ele verdin!" +"I wish I was waiting for you behind that door... but I've got to stay underground. It's time for you to meet our leader, Macil.",TXT_SUB_LOG237,,,,"Přála bych si, abych to byla já, kdo bude čekat za těmi dveřmi... ale musím zůstat v podzemí. Je čas setkat se s naším vůdcem, Macilem.","Jeg ville ønske, jeg ventede på dig bag den dør ... men jeg må blive under jorden. Det er tid til at du skal møde vores leder, Macil.","Ich wünschte, ich würde hinter der Tür dort warten... aber ich muss im Untergrund bleiben. Es ist Zeit, unseren Anführer, Macil, zu treffen.",,,"Ojalá fuera yo esperando tras esa puerta... Pero debo mantenerme bajo tierra. Es hora de que conozcas a nuestro lider, Macil.",,"Kunpa olisin voinut olla sinua ovella vastassa, mutta minun on pysyttävä maan alla. Sinun on aika tavata johtajamme, Macilin.","J'aurais adoré être de l'autre côté de cette porte.. Mais il faut que je reste sous terre. Il est temps que tu rencontre notre leader, Macil.","Bárcsak Én várhatnálak az ajtó mögött... de a föld alatt kell maradnom. Itt az ideje, hogy megismerd a vezetőnket, Macilt.","Vorrei esserci io ad attenderti dietro la porta... ma devo rimanere sottoterra. È tempo per te di incontrare il nostro leader, Macil.",,저 문 앞에서 내가 기다리고 있었으면 얼마나 좋을까... 하지만 난 지하에서 임무를 수행해야 해. 마실 사령관을 만날 준비를 해.,Ik wou dat ik achter die deur op je zat te wachten.... maar ik moet ondergronds blijven. Het is tijd om onze leider Macil te ontmoeten.,"Jeg skulle ønske jeg ventet på deg bak den døra, men jeg må holde meg under jorden. Det er på tide at du møter lederen vår, Macil.","Chciałbym czekać na ciebie za tymi drzwiami... ale muszę zostać pod ziemią. Czas, byś poznał naszego przywódcę, Macila.","Eu queria estar te esperando por trás daquela porta... mas eu tenho que ficar no subterrâneo. É hora de você conhecer o nosso líder, Macil.",,"Speram ca eu să te aștept în spatele ușii... dar trebuie să rămân în subteran. E timpul să ne cunoști liderul, Macil.","Хотела бы я ждать тебя за этой дверью... но я должна оставаться под землёй. Пришло время познакомить тебя с нашим лидером, Мэйсилом.",,"Jag önskar att jag väntade på er bakom den dörren... men jag måste stanna under jorden. Det är dags för dig att träffa vår ledare, Macil.",Keşke o kapının arkasında seni bekliyor olsaydım... ama yeraltında kalmalıyım. Liderimiz Macil ile tanışma vaktin geldi. +,,Blackbird's remarks embedded in other conversations,,,,,,,,,,,,,,,,,,,,,,,,, "Bloated pig. I know nothing about this so-called power coupling, so let's go slow.",TXT_BBSUB_SCRIPT02_D57608_IFIKN,MAP02: Mourel.,,,"Prohnilá svině. O téhle jakési spojce nic nevím, tak na to pojďme pomalu.","Oppustet gris. Jeg ved intet om denne såkaldte kraftkobling, så lad os gå langsomt frem.",Aufgeblasener Mistkerl. Ich weiß nichts über diese sogenannte Anzapfung so lass uns vorsichtig sein.,,,"Cerdo hinchado. No sé nada sobre ese supuesto acoplamiento de energía, así que vayamos con calma.",,"Pöhöttynyt sika. En tiedä mitään tästä niin sanotusta virtaliittimestä, joten otetaan rauhallisesti.","Quel porc. Je ne sais rien sur ce coupleur énergétique, allons-y doucement.","Te dagadt disznó. Nem tudok semmit erről az úgynevezett áramelosztóról, szóval menjünk csak lassan.","Che pallone gonfiato. Non so nulla su questo aggeggio, quindi andiamoci piano.","慢心してた。私はこの配電機と言われている物について何も知らない。 -まあゆっくりやろう。",배부른 돼지 같은 녀석. 난 이 추출기에 대해서 아무것도 몰라. 일단 성급하지 말자.,"Opgeblazen varken. Ik weet niets van deze zogenaamde stroomkoppeling, dus laten we langzaam gaan.","Oppblåste gris. Jeg vet ingenting om denne såkalte kraftkoblingen, så la oss ta det rolig.","Nadęta świnia. Nie wiem nic o tym tak zwanym sprzężeniu mocy, więc chodźmy powoli.","Que porco nojento. Eu não sei nada sobre essa tal ligação de energia, então vamos devagar.",,"Porcule. Nu știu nimic despre așa-zisul cuplaj de putere, așa că să mergem încet.",Жирная свинья. Я ничего не знаю об этой «соединительной муфте». Давай не будем торопиться.,,"Şişirilmiş domuz. Bu sözde güç birleşmesi hakkında hiçbir şey bilmiyorum, o yüzden yavaş gidelim." -"Sounds like a dream job, doesn't it?",TXT_BBSUB_SCRIPT03_D4548_GOODB,MAP03: Macil.,,,"To zní jako práce snů, ne?","Det lyder som et drømmejob, ikke sandt?","Hört sich an wie ein Traumjob, nicht wahr?",,,"Suena a un trabajo ideal, ¿no?",,Eikö kuulostakin unelmapestiltä?,"On dirait que c'est le boulot idéal, non?","Olyan mint egy álom meló, ugye?","Sembra un lavoro da sogno, no?",夢の様な仕事ね、そう思わない?,"듣기만 해도 꿈에 그리던 일만 같네, 그렇지?","Klinkt als een droombaan, nietwaar?","Høres ut som en drømmejobb, ikke sant?","Brzmi jak praca marzeń, prawda?","Parece ser o emprego dos sonhos, não é mesmo?",,"Sună ca un vis, nu?","Это же работа мечты, разве нет?",,"Rüya gibi bir iş, değil mi?" -And I'll be right there with you.,TXT_BBSUB_SCRIPT03_D7580_TAKET,〃,,,A já tam budu s tebou.,Og jeg vil være lige der sammen med dig.,Und ich werde bei deiner Seite sein.,,,Y estaré justo ahí contigo.,,Ja olen kanssasi koko ajan.,Et je serais là pour toi.,Mindig ott leszek neked.,E io sarò lì con te.,それで貴方のすぐ傍にいるわ。,그리고 내가 너와 함께 있어 줄께.,En ik zal er zo bij je zijn.,Og jeg blir med deg.,A ja będę tam z tobą.,E eu vou estar bem alí do seu lado.,,O să fie alături de tine.,А я буду рядом с тобой.,,Ben de senin yanında olacağım. -Worner's a spy we recruited in the warehouse of the power station.,TXT_BBSUB_SCRIPT03_D12128_ASING,〃,,,"Worner je špión, kterého jsme najali ve skladišti elektrárny.","Worner er en spion, som vi rekrutterede i lageret på kraftværket.","Worner ist ein Spion, den wir im Lagerhaus des Kraftwerks rekrutiert haben.",,,Worner es un espía que reclutamos en el almacén de la central eléctrica.,,Worner on värväämämme vakooja voimalaitoksen varastolta.,Worner est un espion que l'on a recruté dans l'entrepôt de la centrale électrique.,"Worner egy spion, akit átállítottunk az oldalunkra az erőmű raktárjában.",Worner è una spia che noi avevamo reclutato nel magazzino della centrale elettrica.,ワーナーは発電所の倉庫に送った我々のスパイよ。,워너는 우리가 모집한 첩자야. 그는 발전소 창고에 있어.,Worner is een spion die we in het magazijn van de centrale hebben gerekruteerd.,Worner er en spion vi rekrutterte på lageret til kraftstasjonen.,"Worner to szpieg, którego zwerbowaliśmy w magazynie elektrowni.",O Worner é um espião que recrutamos no depósito da usina elétrica.,,Worner e un spion pe care l-am recrutat în depozitul stației de energie.,"Уорнэр — шпион, которого мы завербовали на складе электростанции.",,"Worner, güç istasyonunun deposunda işe aldığımız bir casus." +まあゆっくりやろう。",배부른 돼지 같은 녀석. 난 이 추출기에 대해서 아무것도 몰라. 일단 성급하지 말자.,"Opgeblazen varken. Ik weet niets van deze zogenaamde stroomkoppeling, dus laten we langzaam gaan.","Oppblåste gris. Jeg vet ingenting om denne såkalte kraftkoblingen, så la oss ta det rolig.","Nadęta świnia. Nie wiem nic o tym tak zwanym sprzężeniu mocy, więc chodźmy powoli.","Que porco nojento. Eu não sei nada sobre essa tal ligação de energia, então vamos devagar.",,"Porcule. Nu știu nimic despre așa-zisul cuplaj de putere, așa că să mergem încet.",Жирная свинья. Я ничего не знаю об этой «соединительной муфте». Давай не будем торопиться.,,"Uppblåsta gris. Jag vet inget om den här så kallade maktkopplingen, så vi går långsamt fram.","Şişirilmiş domuz. Bu sözde güç birleşmesi hakkında hiçbir şey bilmiyorum, o yüzden yavaş gidelim." +"Sounds like a dream job, doesn't it?",TXT_BBSUB_SCRIPT03_D4548_GOODB,MAP03: Macil.,,,"To zní jako práce snů, ne?","Det lyder som et drømmejob, ikke sandt?","Hört sich an wie ein Traumjob, nicht wahr?",,,"Suena a un trabajo ideal, ¿no?",,Eikö kuulostakin unelmapestiltä?,"On dirait que c'est le boulot idéal, non?","Olyan mint egy álom meló, ugye?","Sembra un lavoro da sogno, no?",夢の様な仕事ね、そう思わない?,"듣기만 해도 꿈에 그리던 일만 같네, 그렇지?","Klinkt als een droombaan, nietwaar?","Høres ut som en drømmejobb, ikke sant?","Brzmi jak praca marzeń, prawda?","Parece ser o emprego dos sonhos, não é mesmo?",,"Sună ca un vis, nu?","Это же работа мечты, разве нет?",,"Låter som ett drömjobb, eller hur?","Rüya gibi bir iş, değil mi?" +And I'll be right there with you.,TXT_BBSUB_SCRIPT03_D7580_TAKET,〃,,,A já tam budu s tebou.,Og jeg vil være lige der sammen med dig.,Und ich werde bei deiner Seite sein.,,,Y estaré justo ahí contigo.,,Ja olen kanssasi koko ajan.,Et je serais là pour toi.,Mindig ott leszek neked.,E io sarò lì con te.,それで貴方のすぐ傍にいるわ。,그리고 내가 너와 함께 있어 줄께.,En ik zal er zo bij je zijn.,Og jeg blir med deg.,A ja będę tam z tobą.,E eu vou estar bem alí do seu lado.,,O să fie alături de tine.,А я буду рядом с тобой.,,Och jag kommer att vara där med dig.,Ben de senin yanında olacağım. +Worner's a spy we recruited in the warehouse of the power station.,TXT_BBSUB_SCRIPT03_D12128_ASING,〃,,,"Worner je špión, kterého jsme najali ve skladišti elektrárny.","Worner er en spion, som vi rekrutterede i lageret på kraftværket.","Worner ist ein Spion, den wir im Lagerhaus des Kraftwerks rekrutiert haben.",,,Worner es un espía que reclutamos en el almacén de la central eléctrica.,,Worner on värväämämme vakooja voimalaitoksen varastolta.,Worner est un espion que l'on a recruté dans l'entrepôt de la centrale électrique.,"Worner egy spion, akit átállítottunk az oldalunkra az erőmű raktárjában.",Worner è una spia che noi avevamo reclutato nel magazzino della centrale elettrica.,ワーナーは発電所の倉庫に送った我々のスパイよ。,워너는 우리가 모집한 첩자야. 그는 발전소 창고에 있어.,Worner is een spion die we in het magazijn van de centrale hebben gerekruteerd.,Worner er en spion vi rekrutterte på lageret til kraftstasjonen.,"Worner to szpieg, którego zwerbowaliśmy w magazynie elektrowni.",O Worner é um espião que recrutamos no depósito da usina elétrica.,,Worner e un spion pe care l-am recrutat în depozitul stației de energie.,"Уорнэр — шпион, которого мы завербовали на складе электростанции.",,Worner är en spion som vi rekryterade i kraftverkets lager.,"Worner, güç istasyonunun deposunda işe aldığımız bir casus." Make sure you're ready for the fight of your life. No scrimping. Spend everything you've got.,TXT_BBSUB_SCRIPT03_D16676_THEPR,〃,,,"Ujisti se, že jsi připraven na souboj svého života. Žádné škudlení. Utrať všechno, co máš.","Sørg for, at du er klar til dit livs kamp. Ingen spareøvelser. Brug alt, hvad du har.","Bereite dich auf den Kampf deines Lebens vor. Kein falsche Sparsamkeit, benutze alles, was du hast.",,,Asegúrate de estar preparado para la pelea de tu vida. No escatimes. Gástate todo lo que tengas.,,"Pidä huoli, että olet valmis taisteluun elämästäsi. Ei pihistelyä, käytä kaikki varasi.","Sois sûr que tu est prêt pour le combat le plus brutal de ta vie. Pas d'avarice, dépense tout ce que tu as.","Remélem készen állsz életed harcára. Ne kicsinyeskedj, költsd el minden pénzed.",Preparati per la lotta della tua vita. Non risparmiare. Spendi tutto ciò che hai.,"己の命の為に戦う準備が出来ているか確認して。 -ケチケチせずに。持ってる物全て使うのよ。",일생일대의 격전에 대비해. 돈 아끼지 말고 있는 대로 다 써.,Zorg ervoor dat je klaar bent voor de strijd van je leven. Geen krassen. Besteed alles wat je hebt.,Sørg for at du er klar for ditt livs kamp. Ikke spar på noe. Bruk alt du har.,"Upewnij się, że jesteś gotowy na walkę swojego życia. Nie oszczędzaj. Wydajcie wszystko, co macie.",Tenha certeza de que você estará preparado para lutar pela sua vida. Não poupa nada. Vai com tudo.,,Pregătește-te pentru lupta vieții tale. Cheltuie tot ce ai.,Приготовься к главному бою в своей жизни. Не скупись. Потрать на подготовку всё золото.,,Hayatının savaşına hazır olduğundan emin ol. Cimrilik yok. Sahip olduğun her şeyi harca. -"Excuse me, I'm gonna be sick.",TXT_BBSUB_SCRIPT04_D21224_BUSIN,MAP04: Derwin.,,,"Omluv mě, budu zvracet.","Undskyld mig, jeg bliver syg.","Entschuldige, aber mir wird übel.",,,"Disculpa, pero me voy a poner mala.","Disculpa, pero me voy a enfermar.","Suo anteeksi, kohta lentää laatta.","Pardon, je crois que je vais vomir.","Bocs, de mindjárt rosszul leszek.","Scusami, sto per sentirmi male.",失礼ながら、しゃくに障るわ。,"실례지만, 이거 좀 골때리겠는데?","Excuseer me, ik word ziek.","Unnskyld meg, jeg må kaste opp.","Przepraszam, będę chory.","Desculpa, estou passando mal.",,"Scuză-mă, o să mi se facă rău.","Прости, меня сейчас вырвет.",,"Affedersiniz, hasta olacağım." -Mmm. Sounds like weapons. We can always use more firepower.,TXT_BBSUB_SCRIPT04_D25772_TELLW,MAP04: Worner.,,,"Mhmm, to zní jako zbraně. Palebná síla se nám vždycky hodí.",Jeg er syg. Lyder som våben. Vi kan altid bruge mere ildkraft.,Hm... Klingt wie Waffen. Mehr Feuerkraft können wir immer gebrauchen.,,,Mmm. Suena a armas. Siempre nos viene bien más potencia de fuego.,,"Mmm, kuulostaa aseilta. Lisätulivoima aina kelpaa.",Mmmh. On dirait des armes. On peut toujours faire avec plus de puissance de feu.,Hmmm. Még több fegyvernek hangzik. Sosem lehet elég fegyverünk.,Mm. Sembrano delle armi. Ci fanno sempre comodo armi pesanti.,フーム。聞く限り武器の様ね。いつも以上の火力を出せそうだ。,으음. 왠지 무기 같은데. 화력이야 더 많으면 좋지.,Mmm. Klinkt als wapens. We kunnen altijd meer vuurkracht gebruiken.,Mmm. Høres ut som våpen. Vi kan alltids bruke mer ildkraft.,Mmm. Brzmi jak broń. Zawsze możemy użyć więcej siły ognia.,Hmmm. Sinto cheiro de armas. Poder de fogo a mais é sempre bem-vindo.,,Mmm. Sună a arme. Putem folosi mai multă putere de foc oricând.,"М-м-м. Похоже, там оружие. Лишняя огневая мощь не помешает.",,Mmm. Silahlara benziyor. Her zaman daha fazla ateş gücü kullanabiliriz. -"This sounds too easy, but let's give it a shot.",TXT_BBSUB_SCRIPT04_D31836_WHATD,MAP04: Reactor Core → Northern alarm door,,,"To zní až moc snadně, ale zkusme to.","Det lyder for nemt, men lad os prøve.","Das klingt zu einfach, aber lass es uns versuchen.",,,"Esto suena muy fácil, pero intentémoslo.",,"Kuulostaa liian helpolta, mutta yritetään.",Ca à l'air trop facile mais ça vaut le coup d'essayer.,"Túl könnyűnek hangzik, de próbálkozzunk meg vele.","Sembra troppo facile, ma proviamoci.",簡単すぎるけど、一発かましてみましょうか。,"쉬운 일 같지만, 일단 한번 해보자고.","Dit klinkt te gemakkelijk, maar laten we het eens proberen.","Dette høres for enkelt ut, men la oss prøve.","To brzmi zbyt łatwo, ale spróbujmy.","Tá parecendo fácil demais, mas vamos tentar.",,"Sună ușor, dar să încercăm.",Слишком уж заманчиво. Хотя давай попытаемся.,,Kulağa çok kolay geliyor ama bir deneyelim. -Who cares. Nobody listens to programmers anyway.,TXT_BBSUB_SCRIPT04_D40932_LETME,MAP04: Reactor Core → Southern alarm door,,,"Koho to zajímá, programátory stejně nikdo neposlouchá.",Det er ligegyldigt. Ingen lytter til programmører alligevel.,Egal! Wer hört schon auf Programmierer.,,,¿A quién le importa? Si nadie escucha a los programadores.,,Mitä väliä. Kukaan ei muutenkaan kuuntele ohjelmoijia.,"On s'en fout, personne n'écoute les programmeurs de toute manières.",Kit érdekel. Senki sem hallgat a programozókra.,A chi importa. Tanto nessuno sta a sentire i programmatori.,面倒ね。プログラマーについて知ってるのは誰もいないわ。,어쩌라고. 아무도 프로그래머들 이야기는 안 듣는데.,Wat maakt het uit. Niemand luistert sowieso naar programmeurs.,Hvem bryr seg? Ingen hører på programmerere uansett.,Kogo to obchodzi. I tak nikt nie słucha programistów.,Quem liga? Ninguém dá bola pros programadores mesmo.,,Cui îi pasă. Nimeni nu ascultă de programatori oricum.,Какая разница? Программистов всё равно никто не слушает.,,Kimin umurunda. Kimse programcıları dinlemiyor zaten. -"Ooh. Glad I'm in hiding, if you know what I mean.",TXT_BBSUB_SCRIPT04_D54576_ITSAS,〃,,,"Ou, jsem ráda, že se schovávám, jestli víš, co tím myslím.","Ooh. Jeg er glad for, at jeg gemmer mig, hvis du forstår, hvad jeg mener.","Uh. Wie gut, dass ich mich verstecke - du weißt schon was ich meine.",,,"Ooh. Menos mal que estoy escondida, si sabes a lo que me refiero.",,"Oo, onneksi olen piilossa, tiedätkö.","Ooh, je suis contente d'être cachée, si tu vois ce que je veux dire.","Óh. Még jó hogy ebújtam, már ha érted mire gondolok.","Ooh. Per fortuna che sono nascosta, se capisci cosa intendo.",オオゥ。私が言わなくてもわかるけど、隠れた方がいいわね。,"오, 내가 숨어있어서 다행이야. 무슨 뜻인지 알겠지?","Ooh. Blij dat ik ondergedoken zit, als je begrijpt wat ik bedoel.","Ooh. Jeg er glad jeg er i skjul, hvis du skjønner hva jeg mener.","Ooh. Cieszę się, że się ukrywam, jeśli wiesz, co mam na myśli.","Oooh. Ainda bem que estou escondida, se é que você me entende.",,"Ooh. Mă bucur că mă ascund, dacă știi ce zic.","Ой. Хорошо, что я в укрытии, если ты понимаешь, о чём я.",,"Ooh. Saklandığıma sevindim, ne demek istediğimi anlıyorsan." -What a grouch. I hope you get to kill him later.,TXT_BBSUB_SCRIPT05_D1516_OKBUT,MAP05: Door Guard.,,,"Takový mrzout. Doufám, že ho pak zabijeme.","Sikke en gnavpot. Jeg håber, du får lov til at dræbe ham senere.",Was für ein Ekel. Hoffentlich kannst du ihn später mal erledigen.,,"Kiel grumblema. Mi esperas, ke vi mortigos lin poste.",Qué gruñón. Espero que lo mates luego.,,Mikä hapannaama. Toivottavasti pääset tappamaan hänet myöhemmin.,Quel grincheux. J'espère qu'on va le buter plus tard.,Micsoda mogorva barom. Remélem később lehetőséged lesz megölni.,Che brontolone. Spero che ti ritrovi a ucciderlo dopo.,なに拗ねてるの。後で彼を殺すのを期待してるわ。,뭐가 이리 불만이야. 나중에 얘 좀 꼭 처리해줘.,Wat een humeur. Ik hoop dat je hem later kunt vermoorden.,For en grinebiter. Jeg håper du får drepe ham senere.,"Co za zrzęda. Mam nadzieję, że będziesz mógł go później zabić.",Que rabugento! Espero que você mate ele depois.,,Ce dobitoc. Sper să îl omori mai târziu.,"Ну и зануда. Надеюсь, ты потом вернёшься и снесёшь ему башку.",,Ne huysuz. Umarım onu daha sonra öldürürsün. -"""This area's off limits!"" Pompous so-and-so.",TXT_BBSUB_SCRIPT05_D3032_DOILO,〃,,,„Do této oblasti je vstup zakázán!“ Pompézní hajzl.,Dette område er forbudt område! Opblæste sådan-og-så.,„Zutritt verboten!“ Elendiger Wichtigtuer.,,,«Istí firi di lis límitis». Qué estirado.,«Istí firi di lis límitis». Pero qué creído.,"""Alueeseen on pääsy kielletty!"" Tärkeilevä mitäänsanomattomuus.","""Cette zone est à accès restreint!"" Pompeux anonyme, va.","""Tiltott a belépés!"" Persze már.","""Quest'area è ad accesso riservato!"" Pomposo miserabile.",この区域は立入禁止!'そんなワザとらしい。,“이곳은 통행 금지야!” 웃기고 앉아있네.,Dit gebied is verboden terrein! Pompous zo-en-zo.,Dette området er forbudt område! Pompøse så-og-så.,Ten teren jest niedostępny! Nadęty taki i taki.,"""Proibido entrar nessa área!"" Que miserável prepotente.",,"""Zona asta e interzisă!"" Pompos așa-și-așa.",«Здесь закрытая территория!» Надутый индюк.,,Burası yasak bölge! Kendini beğenmiş herif. -What an up guy.,TXT_BBSUB_SCRIPT05_D4548_THEOR,MAP05: Prison Guard.,,,Takový veselý chlapík!,Sikke en opblæst fyr.,Was für ein Blödmann.,,,Menudo idiota.,Qué «agradable» sujeto.,Mikä höhlä.,Quel type honnête.,De egy hülye.,Che idiota.,あら、いい男。,아주 들떠있는 녀석이네.,Wat een geweldige kerel.,For en oppblåst fyr.,Co za gość.,Que imbecil.,,Ce tip.,Какой хороший мальчик!,,Ne adam ama. -"Maybe it's because you didn't say ""please"".",TXT_BBSUB_SCRIPT05_D7580_OVERM,MAP05: Montag.,,,"Možná to je tím, žes neřekl „prosím“.","Måske er det fordi du ikke sagde ""tak"".",Vielleicht hättest du „Bitte“ sagen sollen.,,Eble ĉar vi ne diris «bonvolu».,Habrá sido porque no has dicho «por favor».,Habrá sido porque no dijiste «por favor».,"Ehkä, koska et pyytänyt riittävän nätisi.","Peut être, c'est parce que tu n'a pas dit ""s'il vous plaît.""","Lehet mert nem mondtad hogy ""kérem szépen"".","Forse perché non hai detto ""per favore"".",多分貴方が'お願いします'と言わなかったからよ。,아마 네가 “부탁”을 안 해서 이러나 봐.,"Misschien is het omdat je niet ""alsjeblieft"" hebt gezegd.","Kanskje det er fordi du ikke sa ""vær så snill""?","Może to dlatego, że nie powiedziałeś ""proszę"".","Deve ser porque você não disse ""por favor"".",,"Poate pentru nu ai spus ""te rog"".","Наверное, ты забыл сказать «пожалуйста»?",,"Belki de ""lütfen"" demediğin içindir." +ケチケチせずに。持ってる物全て使うのよ。",일생일대의 격전에 대비해. 돈 아끼지 말고 있는 대로 다 써.,Zorg ervoor dat je klaar bent voor de strijd van je leven. Geen krassen. Besteed alles wat je hebt.,Sørg for at du er klar for ditt livs kamp. Ikke spar på noe. Bruk alt du har.,"Upewnij się, że jesteś gotowy na walkę swojego życia. Nie oszczędzaj. Wydajcie wszystko, co macie.",Tenha certeza de que você estará preparado para lutar pela sua vida. Não poupa nada. Vai com tudo.,,Pregătește-te pentru lupta vieții tale. Cheltuie tot ce ai.,Приготовься к главному бою в своей жизни. Не скупись. Потрать на подготовку всё золото.,,Se till att du är redo för ditt livs kamp. Ingen snålhet. Spendera allt du har.,Hayatının savaşına hazır olduğundan emin ol. Cimrilik yok. Sahip olduğun her şeyi harca. +"Excuse me, I'm gonna be sick.",TXT_BBSUB_SCRIPT04_D21224_BUSIN,MAP04: Derwin.,,,"Omluv mě, budu zvracet.","Undskyld mig, jeg bliver syg.","Entschuldige, aber mir wird übel.",,,"Disculpa, pero me voy a poner mala.","Disculpa, pero me voy a enfermar.","Suo anteeksi, kohta lentää laatta.","Pardon, je crois que je vais vomir.","Bocs, de mindjárt rosszul leszek.","Scusami, sto per sentirmi male.",失礼ながら、しゃくに障るわ。,"실례지만, 이거 좀 골때리겠는데?","Excuseer me, ik word ziek.","Unnskyld meg, jeg må kaste opp.","Przepraszam, będę chory.","Desculpa, estou passando mal.",,"Scuză-mă, o să mi se facă rău.","Прости, меня сейчас вырвет.",,"Ursäkta mig, jag måste spy.","Affedersiniz, hasta olacağım." +Mmm. Sounds like weapons. We can always use more firepower.,TXT_BBSUB_SCRIPT04_D25772_TELLW,MAP04: Worner.,,,"Mhmm, to zní jako zbraně. Palebná síla se nám vždycky hodí.",Jeg er syg. Lyder som våben. Vi kan altid bruge mere ildkraft.,Hm... Klingt wie Waffen. Mehr Feuerkraft können wir immer gebrauchen.,,,Mmm. Suena a armas. Siempre nos viene bien más potencia de fuego.,,"Mmm, kuulostaa aseilta. Lisätulivoima aina kelpaa.",Mmmh. On dirait des armes. On peut toujours faire avec plus de puissance de feu.,Hmmm. Még több fegyvernek hangzik. Sosem lehet elég fegyverünk.,Mm. Sembrano delle armi. Ci fanno sempre comodo armi pesanti.,フーム。聞く限り武器の様ね。いつも以上の火力を出せそうだ。,으음. 왠지 무기 같은데. 화력이야 더 많으면 좋지.,Mmm. Klinkt als wapens. We kunnen altijd meer vuurkracht gebruiken.,Mmm. Høres ut som våpen. Vi kan alltids bruke mer ildkraft.,Mmm. Brzmi jak broń. Zawsze możemy użyć więcej siły ognia.,Hmmm. Sinto cheiro de armas. Poder de fogo a mais é sempre bem-vindo.,,Mmm. Sună a arme. Putem folosi mai multă putere de foc oricând.,"М-м-м. Похоже, там оружие. Лишняя огневая мощь не помешает.",,"Jag är sjuk, jag måste bli sjuk. Låter som vapen. Vi kan alltid behöva mer eldkraft.",Mmm. Silahlara benziyor. Her zaman daha fazla ateş gücü kullanabiliriz. +"This sounds too easy, but let's give it a shot.",TXT_BBSUB_SCRIPT04_D31836_WHATD,MAP04: Reactor Core → Northern alarm door,,,"To zní až moc snadně, ale zkusme to.","Det lyder for nemt, men lad os prøve.","Das klingt zu einfach, aber lass es uns versuchen.",,,"Esto suena muy fácil, pero intentémoslo.",,"Kuulostaa liian helpolta, mutta yritetään.",Ca à l'air trop facile mais ça vaut le coup d'essayer.,"Túl könnyűnek hangzik, de próbálkozzunk meg vele.","Sembra troppo facile, ma proviamoci.",簡単すぎるけど、一発かましてみましょうか。,"쉬운 일 같지만, 일단 한번 해보자고.","Dit klinkt te gemakkelijk, maar laten we het eens proberen.","Dette høres for enkelt ut, men la oss prøve.","To brzmi zbyt łatwo, ale spróbujmy.","Tá parecendo fácil demais, mas vamos tentar.",,"Sună ușor, dar să încercăm.",Слишком уж заманчиво. Хотя давай попытаемся.,,"Det här låter för enkelt, men vi gör ett försök.",Kulağa çok kolay geliyor ama bir deneyelim. +Who cares. Nobody listens to programmers anyway.,TXT_BBSUB_SCRIPT04_D40932_LETME,MAP04: Reactor Core → Southern alarm door,,,"Koho to zajímá, programátory stejně nikdo neposlouchá.",Det er ligegyldigt. Ingen lytter til programmører alligevel.,Egal! Wer hört schon auf Programmierer.,,,¿A quién le importa? Si nadie escucha a los programadores.,,Mitä väliä. Kukaan ei muutenkaan kuuntele ohjelmoijia.,"On s'en fout, personne n'écoute les programmeurs de toute manières.",Kit érdekel. Senki sem hallgat a programozókra.,A chi importa. Tanto nessuno sta a sentire i programmatori.,面倒ね。プログラマーについて知ってるのは誰もいないわ。,어쩌라고. 아무도 프로그래머들 이야기는 안 듣는데.,Wat maakt het uit. Niemand luistert sowieso naar programmeurs.,Hvem bryr seg? Ingen hører på programmerere uansett.,Kogo to obchodzi. I tak nikt nie słucha programistów.,Quem liga? Ninguém dá bola pros programadores mesmo.,,Cui îi pasă. Nimeni nu ascultă de programatori oricum.,Какая разница? Программистов всё равно никто не слушает.,,Vem bryr sig? Ingen lyssnar på programmerare ändå.,Kimin umurunda. Kimse programcıları dinlemiyor zaten. +"Ooh. Glad I'm in hiding, if you know what I mean.",TXT_BBSUB_SCRIPT04_D54576_ITSAS,〃,,,"Ou, jsem ráda, že se schovávám, jestli víš, co tím myslím.","Ooh. Jeg er glad for, at jeg gemmer mig, hvis du forstår, hvad jeg mener.","Uh. Wie gut, dass ich mich verstecke - du weißt schon was ich meine.",,,"Ooh. Menos mal que estoy escondida, si sabes a lo que me refiero.",,"Oo, onneksi olen piilossa, tiedätkö.","Ooh, je suis contente d'être cachée, si tu vois ce que je veux dire.","Óh. Még jó hogy ebújtam, már ha érted mire gondolok.","Ooh. Per fortuna che sono nascosta, se capisci cosa intendo.",オオゥ。私が言わなくてもわかるけど、隠れた方がいいわね。,"오, 내가 숨어있어서 다행이야. 무슨 뜻인지 알겠지?","Ooh. Blij dat ik ondergedoken zit, als je begrijpt wat ik bedoel.","Ooh. Jeg er glad jeg er i skjul, hvis du skjønner hva jeg mener.","Ooh. Cieszę się, że się ukrywam, jeśli wiesz, co mam na myśli.","Oooh. Ainda bem que estou escondida, se é que você me entende.",,"Ooh. Mă bucur că mă ascund, dacă știi ce zic.","Ой. Хорошо, что я в укрытии, если ты понимаешь, о чём я.",,"Ooh. Jag är glad att jag gömmer mig, om du förstår vad jag menar.","Ooh. Saklandığıma sevindim, ne demek istediğimi anlıyorsan." +What a grouch. I hope you get to kill him later.,TXT_BBSUB_SCRIPT05_D1516_OKBUT,MAP05: Door Guard.,,,"Takový mrzout. Doufám, že ho pak zabijeme.","Sikke en gnavpot. Jeg håber, du får lov til at dræbe ham senere.",Was für ein Ekel. Hoffentlich kannst du ihn später mal erledigen.,,"Kiel grumblema. Mi esperas, ke vi mortigos lin poste.",Qué gruñón. Espero que lo mates luego.,,Mikä hapannaama. Toivottavasti pääset tappamaan hänet myöhemmin.,Quel grincheux. J'espère qu'on va le buter plus tard.,Micsoda mogorva barom. Remélem később lehetőséged lesz megölni.,Che brontolone. Spero che ti ritrovi a ucciderlo dopo.,なに拗ねてるの。後で彼を殺すのを期待してるわ。,뭐가 이리 불만이야. 나중에 얘 좀 꼭 처리해줘.,Wat een humeur. Ik hoop dat je hem later kunt vermoorden.,For en grinebiter. Jeg håper du får drepe ham senere.,"Co za zrzęda. Mam nadzieję, że będziesz mógł go później zabić.",Que rabugento! Espero que você mate ele depois.,,Ce dobitoc. Sper să îl omori mai târziu.,"Ну и зануда. Надеюсь, ты потом вернёшься и снесёшь ему башку.",,Vilken gnällspik. Jag hoppas att du får döda honom senare.,Ne huysuz. Umarım onu daha sonra öldürürsün. +"""This area's off limits!"" Pompous so-and-so.",TXT_BBSUB_SCRIPT05_D3032_DOILO,〃,,,„Do této oblasti je vstup zakázán!“ Pompézní hajzl.,Dette område er forbudt område! Opblæste sådan-og-så.,„Zutritt verboten!“ Elendiger Wichtigtuer.,,,«Istí firi di lis límitis». Qué estirado.,«Istí firi di lis límitis». Pero qué creído.,"""Alueeseen on pääsy kielletty!"" Tärkeilevä mitäänsanomattomuus.","""Cette zone est à accès restreint!"" Pompeux anonyme, va.","""Tiltott a belépés!"" Persze már.","""Quest'area è ad accesso riservato!"" Pomposo miserabile.",この区域は立入禁止!'そんなワザとらしい。,“이곳은 통행 금지야!” 웃기고 앉아있네.,Dit gebied is verboden terrein! Pompous zo-en-zo.,Dette området er forbudt område! Pompøse så-og-så.,Ten teren jest niedostępny! Nadęty taki i taki.,"""Proibido entrar nessa área!"" Que miserável prepotente.",,"""Zona asta e interzisă!"" Pompos așa-și-așa.",«Здесь закрытая территория!» Надутый индюк.,,Det här området är förbjudet område! Pompösa sån och sån.,Burası yasak bölge! Kendini beğenmiş herif. +What an up guy.,TXT_BBSUB_SCRIPT05_D4548_THEOR,MAP05: Prison Guard.,,,Takový veselý chlapík!,Sikke en opblæst fyr.,Was für ein Blödmann.,,,Menudo idiota.,Qué «agradable» sujeto.,Mikä höhlä.,Quel type honnête.,De egy hülye.,Che idiota.,あら、いい男。,아주 들떠있는 녀석이네.,Wat een geweldige kerel.,For en oppblåst fyr.,Co za gość.,Que imbecil.,,Ce tip.,Какой хороший мальчик!,,Vilken uppkäftig kille.,Ne adam ama. +"Maybe it's because you didn't say ""please"".",TXT_BBSUB_SCRIPT05_D7580_OVERM,MAP05: Montag.,,,"Možná to je tím, žes neřekl „prosím“.","Måske er det fordi du ikke sagde ""tak"".",Vielleicht hättest du „Bitte“ sagen sollen.,,Eble ĉar vi ne diris «bonvolu».,Habrá sido porque no has dicho «por favor».,Habrá sido porque no dijiste «por favor».,"Ehkä, koska et pyytänyt riittävän nätisi.","Peut être, c'est parce que tu n'a pas dit ""s'il vous plaît.""","Lehet mert nem mondtad hogy ""kérem szépen"".","Forse perché non hai detto ""per favore"".",多分貴方が'お願いします'と言わなかったからよ。,아마 네가 “부탁”을 안 해서 이러나 봐.,"Misschien is het omdat je niet ""alsjeblieft"" hebt gezegd.","Kanskje det er fordi du ikke sa ""vær så snill""?","Może to dlatego, że nie powiedziałeś ""proszę"".","Deve ser porque você não disse ""por favor"".",,"Poate pentru nu ai spus ""te rog"".","Наверное, ты забыл сказать «пожалуйста»?",,"Kanske är det för att du inte sa ""snälla"".","Belki de ""lütfen"" demediğin içindir." "Everybody is so needy. ",TXT_BBSUB_SCRIPT06_D1516_DOMYF,MAP06: Weran.,,,Každý toho tolik potřebuje.,"Alle er så trængende. ",Jeder hier ist so bedürftig!,,,Todo el mundo es tan necesitado.,,Kylläpä sitä nyt ollaan niin kaiken tarpeessa.,Tout le monde est tellement demandant.,Mindenkinek kell valami.,Tutti sono così bisognosi.,誰もがとても貧しいのよ。,다들 참 궁색하게 사네.,Iedereen is zo behoeftig.,"Alle er så trengende. ","Wszyscy są tacy potrzebujący. -",Por que todo mundo é tão mimimizento?,,Toată lumea e așa neajutorată!,Тут все такие нуждающиеся!,,"Herkes çok muhtaç. +",Por que todo mundo é tão mimimizento?,,Toată lumea e așa neajutorată!,Тут все такие нуждающиеся!,,"Alla är så behövande. +","Herkes çok muhtaç. " -Great. Now we're shopping for the Rat King.,TXT_BBSUB_SCRIPT06_D3032_BRING,〃,,,"Super, teď máme nakupovat pro Krysího krále.",Alle er så trængende. Nu skal vi købe ind til rottekongen.,"Klasse, jetzt machen wir die Arbeit für den Rattenkönig.",,,Genial. Ahora vamos de compras para el Rey de las Ratas.,,"Loistavaa, hoidamme nyt Rottakuninkaan ostoksia.","Parfait, maintenant on fait du shopping pour le roi des rats.",Kiváló. A Patkány Király bevásárlói lettünk.,Grandioso. Adesso stiamo facendo shopping con il re dei ratti.,素敵ね。私達がラットキングのために買い物とか。,끝내준다. 이제 시궁쥐 왕의 심부름도 해야 한다니.,Geweldig. Nu zijn we aan het winkelen voor de rattenkoning.,Flott. Nå handler vi til Rottekongen.,Świetnie. Teraz robimy zakupy dla Króla Szczurów.,Que beleza. Agora estamos fazendo comprinhas pro Rato-Rei.,,Grozav. Acum facem cumpărături pentru Regele Șobolanilor.,Классно. Мы идём за покупками для Крысиного короля.,,Harika. Şimdi de Fare Kral için alışveriş yapıyoruz. -"I bet this guy smells really bad, too.",TXT_BBSUB_SCRIPT06_D4548_OPENT,〃,,,"Hádám, že tenhle chlápek taky pěkně smrdí.","Jeg vil vædde med, at han også lugter rigtig dårligt.","Ich wette, dieser Kerl riecht auch übel.",,,"Apuesto a que este tipo huele muy mal, también.",,"Lyön vetoa, että tämä tyyppi myös haisee tosi pahalta.","Je parie que ce type sent salement mauvais, aussi.","Le merném fogadni, hogy ez a pacák is büdös.",Scommetto che questo tizio ha pure un cattivo odore.,この男も酷い悪臭がすると賭けるわ。,얘도 분명 냄새 하나는 죽여줄 거야.,Ik durf te wedden dat deze kerel ook heel erg stinkt.,Jeg vedder på at denne fyren også lukter fælt.,"Założę się, że ten facet też bardzo śmierdzi.",Aposto que esse cara fede pra caramba também.,,Pun pariu că tipul ăsta mai și pute.,"Уверена, этот парень воняет особенно ужасно.",,Eminim bu adam da çok kötü kokuyordur. -More sewers... Great. Wonder what lives down there.,TXT_BBSUB_SCRIPT06_D9096_YOUHA,〃,,,"Další stoky... skvělý. Zajímalo by mě, co tam dole žije.",Flere kloakker... Fedt. Gad vide hvad der bor dernede.,"Mehr Kanäle, toll... Ich frage mich, was da unten lebt.",,,Más alcantarillas... Genial. Me pregunto qué vivirá ahí abajo.,,Lisää viemäreitä... Mahtavaa. Kukakohan elää täällä alhaalla.,Plus d'égouts.. Youpi. Je me demande qui vit là dedans.,Még több kanális... kiváló. Mi lakhat odalent?,Altre fogne... fantastico. Mi domando cosa vive qua giù.,更なる下水道...ヤッバ。下に何が住んでるのか不思議に思うわ。,또 하수도라... 끝내준다. 저 아래에 또 뭐가 살고 있을까?,Meer riolering.... Geweldig. Ik vraag me af wat daar beneden leeft.,Mer kloakk... Flott. Lurer på hva som bor der nede.,Więcej kanałów... Świetnie. Ciekawe co tam mieszka.,Mais esgotos... Que legal. O que será que vive lá embaixo?,,Mai multe canale... Grozav. Mă întreb ce-o mai trăi jos aici.,"Снова канализация... Замечательно. Интересно, кого мы там встретим?",,Daha fazla kanalizasyon. Harika. Acaba orada ne yaşıyor? -Dead end here. We'd better keep looking.,TXT_BBSUB_SCRIPT07_D6064_PROGR,MAP07: Computer room.,,,Tudy cesta nevede. Měli bychom se podívat dál.,Det er en blindgyde her. Vi må hellere lede videre.,Sackgasse. Wir sollten es woanders versuchen.,,,Un callejón sin salida. Deberíamos seguir buscando.,,Umpikuja tässä. Parasta jatkaa etsintää.,"Une impasse. Bon, on continue de chercher.",Zsákutca. Folytatnunk kell a keresést.,Qui c'è un vicolo cieco. Meglio continuare a guardare.,行き止まりだ。私達はまだこの景色を楽しめるわ。,여기가 아닌가 봐. 다른 곳을 찾아봐야겠어.,Doodlopend hier. We kunnen maar beter blijven zoeken.,Blindvei her. Vi får lete videre.,Tu jest ślepy zaułek. Lepiej szukajmy dalej.,Sem saída aqui. Melhor seguirmos procurando.,,Capăt de linie. Mai bine ne mai uităm împrejur.,Тупик. Давай продолжать поиски.,,Burası çıkmaz sokak. Aramaya devam etsek iyi olur. +Great. Now we're shopping for the Rat King.,TXT_BBSUB_SCRIPT06_D3032_BRING,〃,,,"Super, teď máme nakupovat pro Krysího krále.",Alle er så trængende. Nu skal vi købe ind til rottekongen.,"Klasse, jetzt machen wir die Arbeit für den Rattenkönig.",,,Genial. Ahora vamos de compras para el Rey de las Ratas.,,"Loistavaa, hoidamme nyt Rottakuninkaan ostoksia.","Parfait, maintenant on fait du shopping pour le roi des rats.",Kiváló. A Patkány Király bevásárlói lettünk.,Grandioso. Adesso stiamo facendo shopping con il re dei ratti.,素敵ね。私達がラットキングのために買い物とか。,끝내준다. 이제 시궁쥐 왕의 심부름도 해야 한다니.,Geweldig. Nu zijn we aan het winkelen voor de rattenkoning.,Flott. Nå handler vi til Rottekongen.,Świetnie. Teraz robimy zakupy dla Króla Szczurów.,Que beleza. Agora estamos fazendo comprinhas pro Rato-Rei.,,Grozav. Acum facem cumpărături pentru Regele Șobolanilor.,Классно. Мы идём за покупками для Крысиного короля.,,Toppen. Nu ska vi shoppa för råttkungen.,Harika. Şimdi de Fare Kral için alışveriş yapıyoruz. +"I bet this guy smells really bad, too.",TXT_BBSUB_SCRIPT06_D4548_OPENT,〃,,,"Hádám, že tenhle chlápek taky pěkně smrdí.","Jeg vil vædde med, at han også lugter rigtig dårligt.","Ich wette, dieser Kerl riecht auch übel.",,,"Apuesto a que este tipo huele muy mal, también.",,"Lyön vetoa, että tämä tyyppi myös haisee tosi pahalta.","Je parie que ce type sent salement mauvais, aussi.","Le merném fogadni, hogy ez a pacák is büdös.",Scommetto che questo tizio ha pure un cattivo odore.,この男も酷い悪臭がすると賭けるわ。,얘도 분명 냄새 하나는 죽여줄 거야.,Ik durf te wedden dat deze kerel ook heel erg stinkt.,Jeg vedder på at denne fyren også lukter fælt.,"Założę się, że ten facet też bardzo śmierdzi.",Aposto que esse cara fede pra caramba também.,,Pun pariu că tipul ăsta mai și pute.,"Уверена, этот парень воняет особенно ужасно.",,Jag slår vad om att den här killen luktar riktigt illa också.,Eminim bu adam da çok kötü kokuyordur. +More sewers... Great. Wonder what lives down there.,TXT_BBSUB_SCRIPT06_D9096_YOUHA,〃,,,"Další stoky... skvělý. Zajímalo by mě, co tam dole žije.",Flere kloakker... Fedt. Gad vide hvad der bor dernede.,"Mehr Kanäle, toll... Ich frage mich, was da unten lebt.",,,Más alcantarillas... Genial. Me pregunto qué vivirá ahí abajo.,,Lisää viemäreitä... Mahtavaa. Kukakohan elää täällä alhaalla.,Plus d'égouts.. Youpi. Je me demande qui vit là dedans.,Még több kanális... kiváló. Mi lakhat odalent?,Altre fogne... fantastico. Mi domando cosa vive qua giù.,更なる下水道...ヤッバ。下に何が住んでるのか不思議に思うわ。,또 하수도라... 끝내준다. 저 아래에 또 뭐가 살고 있을까?,Meer riolering.... Geweldig. Ik vraag me af wat daar beneden leeft.,Mer kloakk... Flott. Lurer på hva som bor der nede.,Więcej kanałów... Świetnie. Ciekawe co tam mieszka.,Mais esgotos... Que legal. O que será que vive lá embaixo?,,Mai multe canale... Grozav. Mă întreb ce-o mai trăi jos aici.,"Снова канализация... Замечательно. Интересно, кого мы там встретим?",,Mer kloaker... Toppen. Undrar vad som bor där nere.,Daha fazla kanalizasyon. Harika. Acaba orada ne yaşıyor? +Dead end here. We'd better keep looking.,TXT_BBSUB_SCRIPT07_D6064_PROGR,MAP07: Computer room.,,,Tudy cesta nevede. Měli bychom se podívat dál.,Det er en blindgyde her. Vi må hellere lede videre.,Sackgasse. Wir sollten es woanders versuchen.,,,Un callejón sin salida. Deberíamos seguir buscando.,,Umpikuja tässä. Parasta jatkaa etsintää.,"Une impasse. Bon, on continue de chercher.",Zsákutca. Folytatnunk kell a keresést.,Qui c'è un vicolo cieco. Meglio continuare a guardare.,行き止まりだ。私達はまだこの景色を楽しめるわ。,여기가 아닌가 봐. 다른 곳을 찾아봐야겠어.,Doodlopend hier. We kunnen maar beter blijven zoeken.,Blindvei her. Vi får lete videre.,Tu jest ślepy zaułek. Lepiej szukajmy dalej.,Sem saída aqui. Melhor seguirmos procurando.,,Capăt de linie. Mai bine ne mai uităm împrejur.,Тупик. Давай продолжать поиски.,,Det är en återvändsgränd här. Det är bäst att fortsätta leta.,Burası çıkmaz sokak. Aramaya devam etsek iyi olur. "Onward, my champion. Let's make Mr. Ugly twist and shout. ",TXT_BBSUB_SCRIPT10_D10612_YOUHA,,,,"Kupředu, můj šampióne. Pojďme pana Ošklivu hezky nakopat.","Fremad, min mester. Lad os få hr. Grimme til at vride sig og skrige. -",Und weiter gehts. Lass die Hackfresse zittern!,,,"Adelante, mi campeón. Hagamos al Sr. Feo retorcerse y gritar.",,"Eteenpäin, sotaurhoni. Pannaan Herra Rumilus vääntelehtimään ja huutamaan.",Allons-y mon champion. Allons tordre de douleur Monsieur Sale-geule.,Gyerünk bajnokom. Ne várakoztassuk meg Ocsmány urat.,"Vai avanti, mio campione. Facciamo agitare e urlare il signor Brutto.",進み出よ、わがチャンピオン。ミスター生塵を捻りつぶしてやれ。,"어서 가자, 나의 영웅. 그 못생긴 녀석에게 본때를 보여주자고.","Vooruit, mijn kampioen. Laten we Mr. Ugly aan het draaien en schreeuwen zetten.","Fremad, min mester. La oss få Mr. Ugly til å vri seg og rope. -","Naprzód, mój mistrzu. Sprawmy, by Pan Brzydki skręcał się i krzyczał. -","Vai em frente, meu campeão. Vamos fazer o Sr. Feioso soltar a franga.",,"Drept în față, campionul meu. Să-l facem pe dl. Urât să țipe.","Вперёд, мой защитник. Заставим Г-на Урода сплясать и спеть.",,"İleri, şampiyonum. Bay Çirkin'i döndürelim ve bağırtalım. +",Und weiter gehts. Lass die Hackfresse zittern!,,,"Adelante, mi campeón. Hagamos al Sr. Feo retorcerse y gritar.",,"Eteenpäin, sotaurhoni. Pannaan Herra Rumilus vääntelehtimään ja huutamaan.",Allons-y mon champion. Allons tordre de douleur Monsieur Sale-geule.,Gyerünk bajnokom. Ne várakoztassuk meg Ocsmány urat.,"Vai avanti, mio campione. Facciamo agitare e urlare il signor Brutto.",進み出よ、わがチャンピオン。ミスター生塵を捻りつぶしてやれ。,"어서 가자, 나의 영웅. 그 못생긴 녀석에게 본때를 보여주자고.","Voorwaarts, mijn kampioen. Laten we Mr Lelijk laten draaien en schreeuwen.","Fremad, min mester. La oss få herr Stygg til å vri seg og rope.","Naprzód, mój mistrzu. Sprawmy, by Pan Brzydki skręcał się i krzyczał. +","Vai em frente, meu campeão. Vamos fazer o Sr. Feioso soltar a franga.",,"Drept în față, campionul meu. Să-l facem pe dl. Urât să țipe.","Вперёд, мой защитник. Заставим Г-на Урода сплясать и спеть.",,"Framåt, min mästare. Låt oss få herr Ful att vrida sig och skrika.","İleri, şampiyonum. Bay Çirkin'i döndürelim ve bağırtalım. " "Biomechanical? Well, that explains their seemingly endless supply of troops! And their bad attitude. ",TXT_BBSUB_SCRIPT10_D12128_THERE,,,,Biomechanické? Tak to vysvětluje jejich zdánlivě nekonečné zásoby vojáků! A jejich špatnou náladu.,"Biomekanisk? Nå, det forklarer deres tilsyneladende uendelige forsyning af tropper! Og deres dårlige indstilling. @@ -12306,22 +12790,25 @@ Dead end here. We'd better keep looking.,TXT_BBSUB_SCRIPT07_D6064_PROGR,MAP07: C それと態度が悪いことも。 ","인간개조? 음, 이거 때문에 녀석들이 끊임없이 나오는 거였어! 녀석들 성질 더러운 것도 그렇고.","Biomechanisch? Nou, dat verklaart hun schijnbaar eindeloze voorraad aan troepen! En hun slechte houding.","Biomekanisk? Vel, det forklarer deres tilsynelatende endeløse tilførsel av tropper! Og den dårlige holdningen deres. ","Biomechaniczne? To wyjaśnia ich pozornie nieskończoną ilość żołnierzy! I ich złe nastawienie. -","Biomecânicos? Bom, deve ser por isso que o número de soldados parece não ter fim! Deve explicar os péssimos comportamentos também.",,Biomecanic? Asta explică rezerva lor de trupe aproape infinită! Și atitudinea lor oribilă.,"Биомеханических? Что ж, теперь ясно, почему их солдаты не заканчиваются! И почему они так отвратительно себя ведут.",,"Biyomekanik mi? Bu onların görünüşte sonsuz asker kaynağını açıklıyor! Ve kötü tutumlarını. +","Biomecânicos? Bom, deve ser por isso que o número de soldados parece não ter fim! Deve explicar os péssimos comportamentos também.",,Biomecanic? Asta explică rezerva lor de trupe aproape infinită! Și atitudinea lor oribilă.,"Биомеханических? Что ж, теперь ясно, почему их солдаты не заканчиваются! И почему они так отвратительно себя ведут.",,"Biomekaniskt? Det förklarar deras till synes oändliga tillgång på trupper! Och deras dåliga attityd. +","Biyomekanik mi? Bu onların görünüşte sonsuz asker kaynağını açıklıyor! Ve kötü tutumlarını. " -Sick fuck... Waste him!,TXT_BBSUB_SCRIPT10_D16676_IAMTH,,,,Podlý sráč... Zab ho!,Syge svin... Smid ham ud!,Der Typ ist doch krank. Mach ihn alle.,,,Maldito enfermo... ¡Cárgatelo!,,Sairas kusipää... Listi hänet!,"Quel salaud, bute le!",Beteg állat... Nyírd ki!,È malato marcio... Fallo fuori!,クソ腹立つ...!野郎を消せ!,역겨운 자식... 죽여버려!,Zieke klootzakken.... Verspil hem!,Syke jævel... Drep ham!,Chory skurwiel... Zmarnuj go!,Doente do caralho... Acaba com ele!,,Dobitoc bolnav... Nimicește-l!,Больной ублюдок... Мочи его!,,Hasta herif. Harca onu! -"He may be ugly, but it seems like he's on our side.",TXT_BBSUB_SCRIPT12_D12128_USETH,,,,"Možná je ošklivý, ale zdá se, že je na naší straně.","Han er måske grim, men det ser ud til, at han er på vores side.","Er mag ja hässlich sein, aber es sieht aus als ob er auf unserer Seite sei.",,,"Puede que sea feo, pero parece que está de nuestro lado.",,"Hän on ehkä ruma, mutta hän vaikuttaa olevan meidän puolellamme.","Il est hideux, mais il semble qu'il soit de notre côté.","Lehet hogy igen ronda szegény, de legalább a mi oldalunkon áll.","Può essere brutto, ma sembra che sia dalla nostra parte.",彼は醜いだろうが、我々に味方している。,"이 양반 못생기긴 했어도, 우리 편인 것 같네.","Hij is misschien lelijk, maar het lijkt erop dat hij aan onze kant staat.","Han er kanskje stygg, men det virker som om han er på vår side.","Może i jest brzydki, ale wygląda na to, że jest po naszej stronie.","Ele pode ser feio, mas parece que ele está no nosso lado.",,"O fi urât, dar pare să fie de partea noastră.","Пусть он и урод, но, похоже, он на нашей стороне.",,Çirkin olabilir ama bizim tarafımızda gibi görünüyor. -"Judging by recent history, I guess stealth is out.",TXT_BBSUB_SCRIPT17_D10612_OHSUR,,,,"Soudě podle naší nedávné historie hádám, že pokradmu to nepůjde.","At dømme ud fra den seneste historie, så er det vist ikke muligt at gå i smug.","Nach den jüngsten Geschehnissen zu urteilen, ist Tarnung nicht drin.",,,"Juzgando por nuestro historial reciente, supongo que el sigilo queda descartado.",,Lähimenneisyyden perusteella hiiviskely ei varmaankaan tule kysymykseen.,"En se basant sur ce qui vient de se passer, je pense que la discrétion n'est pas une option.",A rövidmúltból kiindulva a lopakodás nem lehetőség.,"A giudicare dalla storia recente, suppongo che essere furtivi sia da scartare.",最近の記録から判断すると、秘密は公になると私は思う。,"최근 상황을 보건대, 잠입 작전은 힘들 것 같아.","Te oordelen naar de recente geschiedenis, denk ik dat heimelijkheid uit is.","Å dømme etter det som har skjedd, er det visst slutt på å snike.","Sądząc po ostatniej historii, chyba nie ma mowy o ukrywaniu się.","Julgando pelo nosso histórico recente, acho que cautela está fora de questão.",,"Uitându-ne la istoria recentă, cred că silențiozitatea iese din ecuație.","Судя по недавним событиям, можно больше не прятаться.",,"Yakın geçmişe bakılırsa, sanırım gizlilik devre dışı." +Sick fuck... Waste him!,TXT_BBSUB_SCRIPT10_D16676_IAMTH,,,,Podlý sráč... Zab ho!,Syge svin... Smid ham ud!,Der Typ ist doch krank. Mach ihn alle.,,,Maldito enfermo... ¡Cárgatelo!,,Sairas kusipää... Listi hänet!,"Quel salaud, bute le!",Beteg állat... Nyírd ki!,È malato marcio... Fallo fuori!,クソ腹立つ...!野郎を消せ!,역겨운 자식... 죽여버려!,Zieke klootzakken.... Verspil hem!,Syke jævel... Drep ham!,Chory skurwiel... Zmarnuj go!,Doente do caralho... Acaba com ele!,,Dobitoc bolnav... Nimicește-l!,Больной ублюдок... Мочи его!,,Sjuka jävlar... Slå honom ihjäl!,Hasta herif. Harca onu! +"He may be ugly, but it seems like he's on our side.",TXT_BBSUB_SCRIPT12_D12128_USETH,,,,"Možná je ošklivý, ale zdá se, že je na naší straně.","Han er måske grim, men det ser ud til, at han er på vores side.","Er mag ja hässlich sein, aber es sieht aus als ob er auf unserer Seite sei.",,,"Puede que sea feo, pero parece que está de nuestro lado.",,"Hän on ehkä ruma, mutta hän vaikuttaa olevan meidän puolellamme.","Il est hideux, mais il semble qu'il soit de notre côté.","Lehet hogy igen ronda szegény, de legalább a mi oldalunkon áll.","Può essere brutto, ma sembra che sia dalla nostra parte.",彼は醜いだろうが、我々に味方している。,"이 양반 못생기긴 했어도, 우리 편인 것 같네.","Hij is misschien lelijk, maar het lijkt erop dat hij aan onze kant staat.","Han er kanskje stygg, men det virker som om han er på vår side.","Może i jest brzydki, ale wygląda na to, że jest po naszej stronie.","Ele pode ser feio, mas parece que ele está no nosso lado.",,"O fi urât, dar pare să fie de partea noastră.","Пусть он и урод, но, похоже, он на нашей стороне.",,"Han må vara ful, men det verkar som om han är på vår sida.",Çirkin olabilir ama bizim tarafımızda gibi görünüyor. +"Judging by recent history, I guess stealth is out.",TXT_BBSUB_SCRIPT17_D10612_OHSUR,,,,"Soudě podle naší nedávné historie hádám, že pokradmu to nepůjde.","At dømme ud fra den seneste historie, så er det vist ikke muligt at gå i smug.","Nach den jüngsten Geschehnissen zu urteilen, ist Tarnung nicht drin.",,,"Juzgando por nuestro historial reciente, supongo que el sigilo queda descartado.",,Lähimenneisyyden perusteella hiiviskely ei varmaankaan tule kysymykseen.,"En se basant sur ce qui vient de se passer, je pense que la discrétion n'est pas une option.",A rövidmúltból kiindulva a lopakodás nem lehetőség.,"A giudicare dalla storia recente, suppongo che essere furtivi sia da scartare.",最近の記録から判断すると、秘密は公になると私は思う。,"최근 상황을 보건대, 잠입 작전은 힘들 것 같아.","Te oordelen naar de recente geschiedenis, denk ik dat heimelijkheid uit is.","Å dømme etter det som har skjedd, er det visst slutt på å snike.","Sądząc po ostatniej historii, chyba nie ma mowy o ukrywaniu się.","Julgando pelo nosso histórico recente, acho que cautela está fora de questão.",,"Uitându-ne la istoria recentă, cred că silențiozitatea iese din ecuație.","Судя по недавним событиям, можно больше не прятаться.",,"Att döma av den senaste historien, antar jag att smygande är uteslutet.","Yakın geçmişe bakılırsa, sanırım gizlilik devre dışı." "Hmm. No fuss, no muss, nothing for mom to clean up... Get me one, please. ",TXT_BBSUB_SCRIPT17_D13644_OHWEL,This remark is for information about the maulers in the warehouse.,,,"Hmm. Žádný rámus, žádný bordel, maminka nemusí nic uklízet... Taky mi jeden vem, prosím!","Hmm. Ingen ballade, ingen ballade, intet for mor at rydde op... Giv mig en, tak. -",Hmm. Lass nichts anbrennen. Hol mir bitte so ein Ding.,,,"Hmm. Sin dejar restos, nada que mamá tenga que limpiar... Dame uno, por favor.",,"Hmm, pulinat pois, ei jätetä äidille mitään siivottavaa... Saisinko yhden, kiitos.","Hmm. Pas de boucan, pas de bordel, rien que maman à besoin de nettoyer après.. Récupère en un pour moi, s'il te plaît.",Hmm. Könnyen ment mint az ágybavizelés... Hozz nekem egyet kérlek.,"Mm. Non protesta, fa zero residui, nulla da far pulire a mamma... Dammene uno, per favore.","うーむ。慌てず、騒がず、ママの掃除も無し... +",Hmm. Lass nichts anbrennen. Hol mir bitte so ein Ding.,,,"Hmm. Sin dejar restos, nada que mamá tenga que limpiar... Dame uno, por favor.",,"Hmm, pulinat pois, ei jätetä äidille mitään siivottavaa... Saisinko yhden, kiitos.","Hmm. Pas de boucan, pas de bordel, rien que maman ait besoin de nettoyer après.. Récupère en un pour moi, s'il te plaît.",Hmm. Könnyen ment mint az ágybavizelés... Hozz nekem egyet kérlek.,"Mm. Non protesta, fa zero residui, nulla da far pulire a mamma... Dammene uno, per favore.","うーむ。慌てず、騒がず、ママの掃除も無し... 何か一杯お願い。",흠. 이유 없이 그런 소문이 났을 리는 없을 테고... 나도 그 무기 하나만 가져다줘.,"Hmm. Geen gedoe, geen muss, niets voor mama om op te ruimen... Haal me er een, alsjeblieft.","Ikke noe oppstyr, ikke noe for mamma å rydde opp... Gi meg en, er du snill. ","Hmm. Żadnego zamieszania, żadnego bałaganu, nic dla mamy do sprzątania... Daj mi jeden, proszę. -","Hmm. Sem choradeira, nem sujeira, nada pra mamãe ter que limpar... Pega um pra mim, por favor.",,"Hmm. Nu-i deranj, nu mizerie, nu nimic... Adu-mi unul, te rog.","Хм-м. Ни шума, ни пыли, мама не заставит убираться... Достань мне одно такое, пожалуйста!",,"Hmm. Yaygara yok, karışıklık yok, annemin temizleyeceği bir şey yok... Bana bir tane getir, lütfen. +","Hmm. Sem choradeira, nem sujeira, nada pra mamãe ter que limpar... Pega um pra mim, por favor.",,"Hmm. Nu-i deranj, nu mizerie, nu nimic... Adu-mi unul, te rog.","Хм-м. Ни шума, ни пыли, мама не заставит убираться... Достань мне одно такое, пожалуйста!",,"Hmm. Inget krångel, inget krångel, inget för mamma att städa upp... Ge mig en, tack. +","Hmm. Yaygara yok, karışıklık yok, annemin temizleyeceği bir şey yok... Bana bir tane getir, lütfen. " "You think I'd get tired of all this killing everyone stuff, but I know I'm going to miss it when it's over. ",TXT_BBSUB_SCRIPT31_D0_OHNOI,MAP31,,,"Řekl bys, že by mě všechno tohle zabíjení začalo unavovat, ale stejně vím, že mi to bude chybět, až tohle všechno skončí.","Man skulle tro, at jeg ville blive træt af alt det her med at dræbe alle, men jeg ved, at jeg kommer til at savne det, når det er slut. ","Man könnte denken, dass man von dieser „alle töten“-Sache müde wird, aber ich weiß, ich werde es vermissen, wenn alles vorbei ist.",,,"Pensarás que me cansaría de esto de matar a todo el mundo, pero sé que lo echaré de menos cuando se acabe.",,"Sitä luulisi, että kyllästyisin tähän ""tapan kaikki""-touhuun, mutta tiedän, että jään kaipaamaan sitä, kun tämä on ohi.","On pensrai que j'en aurai marre de cette routine de ""tue tout le monde"", mais je crois que ça va me manquer quand on en aura fini.","Azt hinné az ember, hogy belefáradok ebbe a gyilkolászósdiba, de tudom hogy hiányozni fog ha mind ennek vége.","Potresti pensare che io mi stia stancando di questa routine di ""uccidere tutti"", ma so già che mi mancherà quando tutto sarà finito.","貴方は全ての人々が殺害される事にうんざりしていると思うわ、 でも私は全てが終わったら見逃すと知っている。","내가 사람들 죽이는 걸 지겨워할 것 같지만, 이 일이 모두 끝나면 아마 그리워할 거야.","Je denkt dat ik moe zou worden van al deze moorden, maar ik weet dat ik het ga missen als het voorbij is.","Man skulle tro jeg ville bli lei av å drepe alle, men jeg kommer til å savne det når det er over. ","Myślisz, że znudzi mnie to całe zabijanie wszystkich, ale wiem, że będzie mi tego brakowało, kiedy to się skończy. -","Você deve achar que fico cansada de toda essa matança, mas sei que vou sentir falta disso quando acabar.",,"Crezi că m-am săturat de toată chestia asta de a ucide totul, dar îmi va lipsi odată ce totul se va termina.","Ты думаешь, что я устану от всех этих убийств? Нет, на самом деле мне их будет не хватать.",,"Tüm bu herkesi öldürme işinden yorulacağımı sanıyorsunuz ama bittiğinde özleyeceğimi biliyorum. +","Você deve achar que fico cansada de toda essa matança, mas sei que vou sentir falta disso quando acabar.",,"Crezi că m-am săturat de toată chestia asta de a ucide totul, dar îmi va lipsi odată ce totul se va termina.","Ты думаешь, что я устану от всех этих убийств? Нет, на самом деле мне их будет не хватать.",,"Man tror att jag skulle tröttna på allt det här med att döda alla, men jag vet att jag kommer att sakna det när det är över. +","Tüm bu herkesi öldürme işinden yorulacağımı sanıyorsunuz ama bittiğinde özleyeceğimi biliyorum. " \ No newline at end of file From 79831526cd888d33e35821ded9cbba02e9d1f272 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 Sep 2023 23:17:30 +0200 Subject: [PATCH 158/223] - disable survey code again. --- src/d_anonstats.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_anonstats.cpp b/src/d_anonstats.cpp index 1c3a240b6..b302ad189 100644 --- a/src/d_anonstats.cpp +++ b/src/d_anonstats.cpp @@ -1,4 +1,4 @@ -//#define NO_SEND_STATS +#define NO_SEND_STATS #ifdef NO_SEND_STATS void D_DoAnonStats() @@ -306,7 +306,7 @@ static FString GetDeviceName() if (pos >= 0) device.Truncate(pos); } - auto pos = device.IndexOf("(LLVM"); + pos = device.IndexOf("(LLVM"); if (pos >= 0) device.Truncate(pos); pos = device.IndexOf("(DRM"); if (pos >= 0) device.Truncate(pos); From 22e8bea91bf008a1481f71c5098995cab7878e16 Mon Sep 17 00:00:00 2001 From: Professor Hastig Date: Mon, 25 Sep 2023 08:42:30 +0200 Subject: [PATCH 159/223] fixed actor class creation for DSDHacked * the did not get defaults assigned. * the RETARGETAFTERSLAM flag must also be set for newly created classes here --- src/gamedata/d_dehacked.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 9eb143817..6b91694d0 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -134,15 +134,15 @@ static PClassActor* FindInfoName(int index, bool mustexist = false) { FStringf name("~Dsdhacked~%d", index); auto cls = PClass::FindActor(name); - if (cls) - { - GetDefaultByType(cls)->flags8 |= MF8_RETARGETAFTERSLAM; // This flag is not a ZDoom default, but it must be a Dehacked default. - return cls; - } if (!mustexist) { cls = static_cast(RUNTIME_CLASS(AActor)->CreateDerivedClass(name.GetChars(), (unsigned)sizeof(AActor))); NewClassType(cls, -1); // This needs a VM type to work as intended. + cls->InitializeDefaults(); + } + if (cls) + { + GetDefaultByType(cls)->flags8 |= MF8_RETARGETAFTERSLAM; // This flag is not a ZDoom default, but it must be a Dehacked default. return cls; } } From 3d6664c28ebcc1d8086607a9934c41a935e59b59 Mon Sep 17 00:00:00 2001 From: Professor Hastig Date: Mon, 25 Sep 2023 08:56:04 +0200 Subject: [PATCH 160/223] fix DSDHacked state creation. Several problems here: * the crucial call did not override 'mustexist'. * once created an extended stare would not be looked at anymore. * extended states received no usage flags. --- src/gamedata/d_dehacked.cpp | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 6b91694d0..3ba05e833 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -557,7 +557,7 @@ static FState *FindState (int statenum, bool mustexist) { if (stateacc <= statenum && stateacc + StateMap[i].StateSpan > statenum) { - if (StateMap[i].State != NULL) + if (StateMap[i].State != nullptr) { if (StateMap[i].OwnerIsPickup) { @@ -565,23 +565,28 @@ static FState *FindState (int statenum, bool mustexist) } return StateMap[i].State + statenum - stateacc; } - else return NULL; + else break; } stateacc += StateMap[i].StateSpan; } - if (dsdhacked && !mustexist) + if (dsdhacked) { auto p = dehExtStates.CheckKey(statenum); if (p) return *p; - auto state = (FState*)ClassDataAllocator.Alloc(sizeof(FState)); - dehExtStates.Insert(statenum, state); - memset(state, 0, sizeof(*state)); - state->Tics = -1; - state->NextState = state; - state->DehIndex = statenum; + if (!mustexist) + { + auto state = (FState*)ClassDataAllocator.Alloc(sizeof(FState)); + dehExtStates.Insert(statenum, state); + memset(state, 0, sizeof(*state)); + state->Tics = -1; + state->NextState = state; + state->DehIndex = statenum; + state->UseFlags = SUF_ACTOR | SUF_OVERLAY | SUF_WEAPON | SUF_ITEM; + return state; + } } - return NULL; + return nullptr; } int FindStyle (const char *namestr) @@ -1832,7 +1837,7 @@ static int PatchFrame (int frameNum) int tics, misc1, frame; FState *info, dummy; - info = FindState (frameNum); + info = FindState (frameNum, false); if (info) { DPrintf (DMSG_SPAMMY, "Frame %d\n", frameNum); From 678cab799449a35e55f5a4d63c8f2450f905888d Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 26 Sep 2023 09:48:11 +0300 Subject: [PATCH 161/223] - fixed `DumpCPUInfo()` definition for non-x64 platforms fix #2188 --- src/common/utility/x86.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/utility/x86.cpp b/src/common/utility/x86.cpp index 78d74fff9..5707c6572 100644 --- a/src/common/utility/x86.cpp +++ b/src/common/utility/x86.cpp @@ -45,7 +45,7 @@ void CheckCPUID(CPUInfo *cpu) cpu->DataL1LineSize = 32; // Assume a 32-byte cache line } -FString DumpCPUInfo(const CPUInfo *cpu) +FString DumpCPUInfo(const CPUInfo *cpu, bool brief) { return FString(); } From b91300316875266e852e8b5890e188870189d4a6 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Tue, 26 Sep 2023 05:56:22 -0400 Subject: [PATCH 162/223] - update soundfont --- soundfont/gzdoom.sf2 | Bin 3283278 -> 3299098 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/soundfont/gzdoom.sf2 b/soundfont/gzdoom.sf2 index 27cc01c187c9b4bb48c0ac76c773dd221274412d..702f7ffcdd6cdd65b4e4aad4e2dd0591d5344461 100644 GIT binary patch delta 30185 zcmX@N=>+4fbtf4GgFM~bgu;y&iqn#^eLRCh7EBZrp6Dbj4QZ!xxbJAGiD_O z34DO&*M3hR7Bt2qSDOA17EOW#1fD5M$GkWgH-S^RhDwAPl#w zVGzcgyT91MQq!Kcuz?v;Z+svIr@ae-NbUOiObsNpeSr+47%!N$O_TAFESNRJoiR=j z%=#9=_`m_ox;B$h#vIK0bb;}hD44b58RH2aFstD+qn#y~wNHmBNCV6g2xTgh1hd-m zn4XA$Sy|0YDO_OIxn3qe2uo%L(><`?w*Okl6b5$i_J9>khah4?o0wD}VrDy-+?c_7 zYj!h9KwLWI29uQ-SnS+8rbB#S)`Y)Id-%aDA717zh~8_$%xfU5CMjkKZ~$(fCC^*~ z4zTTF8q6UOR+a%XBzU*8nZfiy7D+}u(3lL-bF$>mBePC9_an>@3*WR6FwSjm|>oV&q2b z|J-5~0;i?ze0Nx*z{YLQc*mLn3FZsmSzC0#=7p%R-7o~Rbi&v+Kmzt<7cSg~(A+dWA5%z4J< z0L~xV?|fui1POsUOZJpRupy6Tv1b^7Szf2v_dwDT+f(*)5Jz2k!CnUOq}Mz49EjMq zkL(2y@2Y)ahh&}Y8DH7mATC(9M^*mfH)G3QnnUi$L6RPlx*g zBofvca5q5$&A^oV9EA1HlKT!s?=45}9tbPVlY0Xs0>%8fQy`{Pg>t_GyKi|$8aE_S zW#n=5Ks1z;avy?NVOGf<2R3;6hP_-Y+h^2rCqTmgM;*5sSpRmpe(nR1@VYmXn*(Ch zvxVIIz}mJiS;oBrVwBG+ZYKzYpLCX6yS^f@4f`6ySZvzQ% zEi3*_;3{?d9bbL{NCtWn$vaLle_2Mu9AdTU-@U|jEevt8&KY57Cn%B!sqAwUMOYxoxj;|k3&gS%Ly;zkC!g7fJb?tpDOZsi za2YWDz;0fa?Ot9Y8j4`Q6lIItfuu6Oc9CEPDay@ObQw6*m%s5Ah4|o2h-eW+SzNv-7bJi)8bzTQ za!H>kv{ANewkR}m{>>Gg1hIC)Qc*|~a{7csUY6}O`$R8+18Dk$rJ^j`gD#5-K&(xA zCE5XY{MJ`uVqg{9M8zB+8Qmd4Yy%`IerOf@14)W+mWW*gE8Bi(r&tdps{QVWt%4LQ zKc0!bfv}!@6gvcQ$+Dkf&@7epUu+(vK;U2&w}Y_U*u?i$fPkDMcv=`Kj9ZAg^PgJfX2snVw)W%i3h(o7IL zUcHc(f`l^*pNt74+gfPJL_r$Rlk8=FK#JwANErc0dYDx#!vzsr(jyb#26pL}OEN5w z#?cQ+SrH=>^TT4&r((llFwSKWFZ}l z?PsiIQy@iyfrsq0a~DtKRbx}wQ?PhGWo$Bxg-e7iASCf z5(NP|@+Od0T8oSPDKD@Nzkc~LNN^w7Bd-Jr+GjW9Dbt*qFY@4PCE%P{LD&~NLV0+0dMQA`(%vOX1RM{LwXh2oWRRpVA zUNH~C*j_PT@ew3;qSh#0fP}x+MnxM4D{ZSHG_4-lp{M}K^H0tzmOwfj5nM`fkV<5m zsge!Eai1)dy1)g|_8NC3CP-edi&mNx0}fDu9ZD-8LA!%V`2-~J8qAbAAmwX^tMV*} zTa<#7dms_Cu2ES75`EY9E7w7CU&wFeE0DI6hLOrCNWT7*uEGIH@xN+Rtir&ynOs&` z1Yup%RLy~uN=~J!&kDe@8qZXZKSSwY-9!%wXX5*bPnYVRPf5=d2h z0!boYYSk8af=!unTx|g)N=?409fDM!-(=O7L8|CEZt4P%JiI1FeG(-6>}u47AZ`gb zt{wzQ`-?<1wnc)?i^$g~gZT2?Dvc(Hy#d=bwm}jL+dYj4NLa)2DM`3sUX zxAkehgCxx*i!_~}wbEM6JCJhh&~MEX5Z8B!XuW~BrA$Yw4U+%=6lrNdIzlRowVWWi zFKww7v?BerOv?_OaJE~l(BcELmba`=&cuA0Uoj^ipdd z#K{RiwI)E)?FVLUCrGduDQSO$6h#^~+BJ|$YKfn=2_*U52-4mHNme~!+D{;Dv4RY3 zKZtGn^0lD>dXNCRB&)Lsl3YrHb-W;++!w0D z0!fI6I&=;|s*9$BIxUby%yvQN5X9aS4|Sv`=vtH4dQ02YTYb|9ZNcNw?UF=)FjXde4ifYVv-D(y!Rggzt==05OXHy4IY?l9JEM06;^b2| z^|ByhCQtSFAS|a3dJPb79QvvE1LFE!jQU$3tUONr1?gau`3m(PL2~7XUHWd22sAsX zzXDQ(-}|Qj1LEIn|Miu?zGMRpt1-z;|HoqBr_aQ|zyQMmnTdJ%3Wg~RC_sRLg@J{E z0fMJjvl>WqvoWwSFhKD1g{%hB{2UA%3=D7_F#RK|fhaEn0~Z5mJP(YgzhyO$HsoR8 zVPJq`kNmvsO5KwDyljMp%nS?+d<=YGl7WG5x+R-|G`9eQ00RRAPmgCakTw)z5Mp3} zW0%yD(!A6Z1=j!tLzqb{3>*w13?d8+5IlV~$Q&^S(C8x=PrnE1_1^+1~~=>2%etFZXnIA zz@Wgu0KwDyLFOniC^0a=v1ejYL2+hsMt%_@2G|$`7*rTk7#JXU`fZRoY7A-&3=lk> zk;6dRP=i5(fdP)4Q*%;_OA--|fkurMgBAk=1W)(nFpxIYVbEb=_Pr~C>e zji9L0W6)z@fa9>~3(XCLr*GgeVBt1kFkoPS;OYB045ayu7(hV>!@kq`Il;-mgu#S? z0fMJ*egB^n%0|Nw4KMAtlfx&@+0fMK$2btr<;KaZH z$FSt&U!(_5P67-Z3@!{V3=9xF-I~iln%j-Rje!Azrzdh5NE>=EcrY-)v42r|Vx9sh zG(awaU_k~31}_FLFv-B+HGM5en-7Bz0|OjGw3$NGLrFmf1qMF`KL!Q}p8gYLeE>rM zXtW%Jr^|C2NE-$*1Tiqcv2#XgQF4ZYe^I&~+zrAE91I~0Aq)%*aSMJbv2c?xbtQ0Fj+GB7YiF+_n$28O8VcR|`>7-AS0;MgOv zC^tVZGZ{G@f^uFQLmUGG1W(uGF_7j?U`SwKfZ*x=JOZW({8Ax+CFf=eQK=AbSAaj}+niv@1*u6v#7O}-JZ^$z+FtjkVfJp|1mg&Di z=Cm=iF)%>zbVYsxX~PbN4h9A|cFW95Pc2GKQE)1ThlnBr149=>7no#V=$f7j($>S! z!@vN?ZbhjjIjP0P$l8<{7#R8(`oJUuL*MkB{07q86Bs5iFhKD1`yg{BF-&4$faBoG zypjwBr^Mo7M2!I|Q>QRYVPJsZ>DmGY(%jP+rZF%;@bo|d18Kt<3^N!Q;26mqcpg({ zU|^WVFbhmFFwB}h7o=?t!yE<%I1VaJN=hvP+Ybvw26YAjhItJ07#JXU`b&`Y3m6tK zFhKBhenA6i!$k~>7#QFDqkNE_~8*ulU6$HA3(dch?{nR)5O#!we97%^}#>|)r(zyQJ1 z|AMsbVc5gK0LRW5`I$uuj)@uYL=35)_A%^ZV1VH1p27yw+y@vAFfc&y^n76hX~RPd zhZq>(IJhz|45h+kU;tNbM;MMUFhKD1-5_(0F&txHfZ*v5LFSxbIKjXG$00@exk;cI zPnaJV7#J)W7#L15oC1>!45y~+iWo>6o?$q{zyQY~rAg?~53U~1F`Q#yfZ*wsA_mgj z7Z@%uFhKD1`5<#HF9HVfcNp$4Fu<{6USdvux)Yi<0fu`F z_ZS!;c=}3F18MFD3=bF>Ab9$DkU5VS9x*V$F_Jm(+-T1r!0?3O2?GNJPnQ-mkmi2I z@Qi^0f~Px*8AuzxV0gj60LLMzdHF>O!HJ+U7ZxF)2Er?bR}2ggJiQmB?G3{l1_n6x zPs&HFrl75bcMR_s7$A81O_22;7(OsCK=AbcAag!3d}3gLW9OX2qRhNhP@Mp?oxz=f zf#D0o7cj}d@MXHUxPdhHH->Kv3=llMP~1S;@CU;W1_n3|N(EKisfa8MZFT%&_{G2g z!PEDGwEbcD!@vN?PWdGzIjIUxIr-&q>p|_4e+>T^7$A5$r-Xqt4+A3uBLf2jPdAV- zkTPOoWMX7sfMNe+kUvlps6VJ9!N|hMzyQJ1Ya|S$BG?$&7#SE~IJmGhu?Q_B0~i1hvzo z7^N5)7$A7MoRoo-kqn~@BLf2ryCvq8Bo=3)1UslXC&wtq$iM)>)3c-uq<9n<6&M*9 zAb9!&kV#66N{kE)FdSTvn4GE*mYkcv=aRAXddfMMU% zlEfT^07RfLFfhb|`X`JUj0_Ag?2(w0kERIRD%4`sVq{=|;OTzS22w^kj5>@A3^44O zoT?C%h}s|nH6ZmE^%xl#Ab9#LX#*)914aWz1_lV8egI^W5u*_!0|N{PSLP}BCg$WI z=d>gSMg|i`6GjFG2%gR(V;~h_#%RXKzyQNeMVaXtC3&gENRc3=llMPR2mW$cE8|k%0k*U6V8N6`YWIKHx?zBZD2I9U}t+1W!LD zV<5%j!05opzyQJ1KY&bfVsv6;V1VJ^%#uWu%nxl1yD+*iGB7~!bQ@U%sR%blH%0~q z7en!OFfuT}aBxOqZf0>Rs09pH25L!rF?umFFhKD1b+QIhMm~%_ zj0_Ag9Fmw>oRP2KonL~mBb$MP!H?08k%0k%r~i^Qkm3no3}9qnfZ*v0at2aHL5x9+ z3=A;rmYI@*)-eD#%0n1K7#SEKczTYUfmB2oV;Ca?0}O{`=4FElIOH$}wPPX}BN!PN zVAwG|KONyhh!+b%9UjIgMg|55o_-JHsu;!?Mg|5L4$sd|Ny^DjMjF##040<-#yCa> z1_++6C2t_blfan3$iM)>(*xuUq>PdnlNcEoVAwf7FFCcSM8OHv?Swdhp#;?PVN79U zV1VH1bL0)ABGMSs7#SE~*f%vNUr!+3o?{4a4=*rW-u}^z%Zn)b}1^&g&NJk z0PcBYF=jC`FhKBhJ_Q3Qqa4N@Mg|5LcFjpmRtQKfN(Qy`pjyiqI2rO7^B5TzAb5I| zf`JrI0b>Cp0|Nw4ZvdH8#8|}0zyQPUC3?=KB?^A|nZ=-t0XD0Gfsvtvv4oL<0fMKW zQ818-C}S*RWMF_{r=rxvk_=RRl?)6F6^s>(AQFPza`e1YD;1n`G7(Wx$-u}^#aPA2 zzyQJ1?Gz29jA|Hb7#SE~7`yL<1_l@gnU0h&z?!QWm>K#Q z`xqG*Ab9#NB?Bp*35*jM85kgV`U8+jlNcv4GBCifOMZTlb5Uwyc4i*jDK!jC3{x1V zFfuSe@N^wz1F48VIJc= zMg|55p8iVNK#FGp;{rwo1_+)mpkg3pw1{yLBLf2rgG_QRN-RcpX)OZ_!xF|Nj0_AA zJUvFmKq_Jx<1$7D1{e-0LaUw_KrUcoSi!i0k%0k*y;4gGauShU2~x$*u!?aNBLf2j zPd^88)f&b%j0_Ag>{MD*jFxE_Y8f~g)-kSQWMF{c=~Ai&Qal?NH!w0VK=5=2RRbxb zO^llu85m$VI2n{aks=Q~62Qc;g>efb0|Nw4?@=|7irB`ujgf%?hCNafL8Ve^B2o*r zj)8??2jdP#1_l^*%g-+-R4w%kj12o2_c1asK=5=gH3KQ01B?e485kgVdV!jOl+hu^LyQazFdSTxn3s}> zo|hUJjxZi!WMF{c>3h@+q#}+n9%E!+fZ>4ra@0mMc;RNFeMg|5L29<*)MW7Kb zNZJIE5)2Itrx;H$GB7~!bUk$gDWfxtXBZh6VAw0M3N%s!QVz!o3=ItD7|$^>FhKD1 zDs=-Xo(qf@7#SEKc=`f$11YmhjF%W07+^Tq4b-lK8v1GUw`YCuFmQet`xJBS5oz{92hK*R4K3>xqU4SlmsH`Fi?PUU0(4dyd2a3hW0 z^D;0n@PmT}GBghw+5}$G=A$m{jY|B zv@B?l)tiBV0fa&Q7hmY;DX0q)FkMsAK)F5~X_zyTfq?;pL4%s0RxWHT6V!4AVbG{$ zJZzwnfq?T;ctHai`=MhP2d5v@G7x43jVYX-ei6hx4;mJj{!q(cwkW7m z_#4!pgLdIS9W>VIo!SP@(@$s{1WXsvG0>Q9p<|#hJp@D)=oolR-=bq6V4DeTFJvRN z5^@4Q4$B?c8mw4gwFMREE?Qv*?E9R~0WmoTIG^!Ka=qPk8D z*k-bP89cGfZv{ixHAYI?EYALv-kKO7+txg0!?UV4HC2hHBA6Y5Pu`ZfI^GDn6aT8Oz+#oaz1? z2BMPl8L-VDEoOks7%?uNevrdJRCg_dZ(>nqF50-&W(GejqT8lF1lhWi0o#Pop6T_R z2BNzA8L&-`*`{t=|*6g=#aXL!ysm>H-SgQiOo^ALl=7p70NFc1~L z%mA5{K@NEahHKN;a~X*0-hxVkiYaK6F)%RPhl;|7CBagUrYmwAi0VFLaK^R zh%x$A=H!ECDv(luEJ7412viucO{!=!P8Z-c5YaVe#5Q+g!3e4V(PuF1r^j0vi0ZmC zVw)!MV|32QFDflY)f7B^p_PHCLyv`K=8^b*mY%&2cn?L>1gpQ&W->5&enQ>4DY;q7t2q*rqf38K)QU8;IymVZ=6T zF`F?sC$RuL1%OCx42!1k2f1M>BcykRIzh1#A_@{TG=Ptg@NJ3^n4owQQZq*Nl+~ZPPkCwCZls|P7YGa0E<7G zz7gbxmyFmZ5-8?#Sg0uQ1iB`8o(WkN;asRAU(kPGq^Xc7!% z*u9WxdV;8dh;BI((qK9~Xls%6z>RC3u5WK3s@smN1uogm6r5jB1X@>uJf1#rdZE36 zsKg8=Y(wn}nWj$=GZ4{T$%Ji0eJzt~UV2VuafSkD$^z^a&{Wd&`ye-LW5PCgzKba! zGdVdQE!iHJuIOMODshMj+c^0#rs)U74McQLGGQAIKg$%Hk(gbY0qUy2T)@C^etN%y zfvE0fCTs)W*O?&0+9>0>3^%7=1i9e>6SmRpCrr~nNEnFdK4-!T;0UT`sl zMs^*Ur#HwLi0C;pV;jG9hlmCwBD%B;3=F=^(*v9hM4|$jv5nLQLqrk95je8Kn6Zt{ zMlxd?jZI*lzCqSNL@$LI+n8%Qvv*<+Mnf!{d76uXNK_s(w!zgBkTrRUs6{nH6*IO0 z)p}-Z1E?L$(;vtgi0E}OV;d&zVRlX|E=kNwEkPbM=wqI~0pz9$%-9A*Cov<2JK^ON z!(1d$cu~YK9~Ai|849R_o(q|$3n&%{L*ajDmFi$T~G7!-{ z2G)a?E*VZRhot7Dg17A=RX?Yu?{_m0)jh+EZLIJdSQOb}5c|S(Mt1{IiA&7b1^}-x zPhX&HAfkJX88kSDKFoImEE-&r59(Hf%mU+E)AQX8M0M|gCDF(8?lA{v7NJgJfM%Gd zZv?sF5i_Pu5v46}#`T3wx36Nvq*oFn$P*@cUD4(DYeeGbGZlG=;qW6sj)V_xs0cDu5Iu(_o z45Wf2idd&Ncp8XUY+%JUl=Ys~)!!4O3 zI@6s%L>7pc1R{2Uh(}%qBGW&C2qtd>5#={5K@5Lbf*E*NLl|UOL%~>!HH^WMHJrhN zHG(0WHFCPHw}GtoHr9BCW2^}b*H{x7p0Xw}d}U2$U}Z~T5M@gRV->bE24l8#1}C6zXJiuxPb@)`EA6)>D-D`dFCR>bgun%8{gAhTMExc9W`>9CEes#nTN(bdw=wW>w1crcM+bueM<*CNaC9*QaC9>yaP)w2 zK1VM@Jx3qI1de_%p2snPVJ*i*hTR;K7*29bX1KvI1&p6@OlA1WF^z$lb2@_{=L`k~ z&Y56rz&VS-fpazp*E0lg&S6O4oD0SUobwp!Ip>3MKj#95`J4;Ecpc{=hP|AN8P0Gn z0pq)zOBvpAE@Sx5xg3o7xK=R8ajgVneXdmu_FSvM*pF)sLoC-?FwWsx$573+9*ldq zHZaWL+Q=}6t9~QHO0G=|Te&tf9Ol{r#+SIZGCbtk#_)-2I|DQK4lowx-pQcMy$g(u zxOX!+aqnRW;@%6!N!<6#a}13<=NTsQTma+wJQo?(@?2ur z%X69GEYB4%e#CQ?;Tz9225#Q#3<|tA7)*I@PS^D{keu%1YalZ{3Pcovh%OMZ$k#wY zIFSD@Lp=XKhFt#t47L0WjJ^Df)6e=E$WDLeYoIWl$ewBa-;|>8)#^VBFj8_H3 z8J`G9fbkarNk&#dDMnF2X+||c889{$lx1`jlw1l(;3S|Gr+i6G?Q_nXcprF(QL-`qB)FvMRURUjA$O?ZP9$jSE2=szeEec zm_@8;`c!`d$?2>74HTvy^EXhL{>7`V>QY7j3$x`z}Q)GA!CT-BE}@i#f-(0OQuH# z80gynlU&EhFSVXgL23h|fz(DYc97b{7$CKoFk1KF+vA z`UDtnl|IRMO!^e#b?MV!{7m``<2UKEjBGOJz*tn~{B+hp1I_7Lfd(4W{Q?aXre_5j zC`e1ly=T;r`@m=+_mRjr@mdJrg~2N|eLuL?3y;15?aX39`9VX9Oz zW$I8eo4zo}K(zjZk`>cUC2OXaN;XVCm2AP7OWBS|TG^gSN7(_4?UWsv{FI%T5|o{p zij-ZLT9jSEc&f4+69_L+c4ykG?7?(M*%OSfD0?wIQT7JoZ^}MQoGQLdGAe#xtgGVB z1j3Fg0ZgGPfig^)DnVdeuM*5OStW#Nxk@M)Z&L}It{7|}ThFB$!z8I1%cQ9q$7HD* z5614Q2~5GNiC~1)EmJ#TfK>? zUcH%VvU&>`FH>)2+Ns{gbXL8c>7jZD7=KdlWMbCnViM6X?PgNZ=mBFBjb0`fjXtJO zjeamr(U`zgtTBpWa||*XEPaU&S7%YoD0T*n)8?v zHRm%GYAyid2F-;`6Eqir@qEq2OzSk4fblNPrA#1vQga#8bzHD-)-&a3Z2;p2t&L0#S{p@}CTneCTBfxbjCW~mVLGR^ zb^6>816gw|?cGck+IyHhwf8bbY3~E$Z0-F_HQEQjxJUaS(;V$XOl!0cgYh2iBTQ$s zk50cEVjwyFQ;30taIMaHrinTin3n2XWZJ27iRrA)<>{iK2CC}zy0@9Ub?<<2lKJuff<*?+p_OJL$b;0^uONcT6Chp!c2$ zg!A=2FoAHj-bW@7ZrA(7G+FO67%$NK!UV$W^u99f(fh`9O7A-uU)B4;1i~-$elmgZ zC%s=xAk3uyn~6#PcRiD^{vR-w(f`W?!s`0}m_XP}|34E5JLxkpgK&^OBQpr6=rb{c zaK1h>GYD7dvoM2jhdwJa2v62$V+P^*`s~agyi%Wo8HBg%b25YQQGG6E5Wb<$&3r?@ zo}2lVJ`Wgw*XLyhVHN{EW)K!M;AaM5B?AFw5H>LoWCmde10iM*_AwA<2H|i65oQoh zHV|b7;d}!zW)QA25N8JAb^{4!5T0Zp$qd5t45XMrc$I-P^C~t2Y34l!GSe-?41P}6 z3pe;NT`9ug$8@nsgCEnmq6~ga{|6#IMH~E>{w&7e&-8n-27AoXy-iq)yiHjfyv20kwahI7+R4;m`+$wV+P=tnXzT#sO2;E$Z1a?ntLH#U-i z;b9~L!@@`ghJ({5f^_mnF)&PsVqge}Vqhqkz8|D>Ulap_YCHo&Y#ajvYy9+gAf3VS z3=E7(3=B^b7#JQ-mp){u$fuvgz>t*2z_2Hkfx#(ly4N8?1-=Ps3=9Xd7#N(g7#J30 zO|Lj)sKEO!i-F;19s|R)JO+lF)0ZAHROD69XJB9{W?)!f#K7=m`sG80iZ({Y3=AP< z3=A(z85m5;7#Nho7#L#zfaazx3@n_(%|IK75dDCrG6sguas~#eat4OX^63VL4Hfvd zmoqRpR5LJKFK1v-sGc4N63eS*U^v*vz>wX-z_74ydJjnKeIElu)Kmrr{(c4qtEtm> zfy6qdGB89gVPNoBz`$U+Wcmw`So;zN2C=ma42#wWn~}lMf{_8V^ia`adIU%;--40hpc5m*GDk*+g-+AkKw|Hm z7#Tpz_jKJE86LV%-*VJY!A9SMk-^NDk)h3pkwMIt5gg{m(qNaz2RlZXffk^{9nO&A z%gA6H#K^ENkdZ++Xu7~LLj}IXAV!9qP(}uxP(}uy(CKy{v00&v4AD`H3=&a{4AxQ8 zb3kI9QH%`Lv5XA*v5XASvD0UP#8$>KGHAy$GF*>iWZ;gUegY&G8PCXYG?$TKMGhmw z(%k9aKw_VB85urQFftq|XJoigF1JeL>Stt_ z-^a-CsBiimkeER~Bg34Dj0^@785wFOPUkvdsK9q>A|u0#sf-MzQyCdfOr3545)+%o z$e=Kbk-=pqXmQf?G?19zEJlVua~K)I=P)wdnKOOL2}1=Nt+|X0{tFlxqUSR*=r4e{ zT<0&u<-x&zXklKvfRSPLLPiF!g^Uc<3#WeonR;>|Bg2vPj0|#X85x$WpDuUOP=W8$ zdPas5`xzN-?PO$Fv46S`NbK8wMuz{#85y=7XJoj4e0mi~O!ovMgY6kchQFs78D!5) zUjY)!KEudR^_Y=C;xQvb)Z^*bP8urkuXxPJ@PvVh;p2Zsh9eA2(^*d$%G(GrGBM~W zGBG@tXJX(}WCAA_&`vT&2B#p$;9yHLlt7PBWMX(`%EU0+l!@V(>GXtCh6;QlW=ssB zwoD8rW=ssGw$uASV$HTp4Bm-M42x}<7_<|o?*WNbCNeRc&tqa>%VT0#pEvy#NbGMO z6N6JF6T^=RCI+R-=@O?675EA&nHbJCF){QuF)^%dn(hV?``yIEU^AbIL8h6BL1zB+ zlGBC?Hd*tT7#2TcVwk*;iJ|!!#O3ac;6Mi@bYsxoLqtNq_>76+%}XYRg)f*G&b*v{ z0c5JwD<*~+Zp+7NgtUQ3Vty$G<{@Z2>3O98%S*4FD3@V z|4a<~elal!{-6HjjG=-}{C_5fMp0&lc6MflL{VmNn0qjTT<+}X()hSSE(3>n7E46BW&&jE@3 zG-hVVv|wfkF=J-%w3vPhBsSfGnPIIxGeeavGefWa^dBIx+xE;1sxHh79L~%PtS-~l z&KWB31-mdaM7l9ENVqXGSh`IQIcKO~)9%L1aNL8LVYNFm!*UOZ%YDHGy0fcKaEK#f ztQHjVUp<%^mUuEVxOp-&w0KV605bKGCo{vLcxHx*cxHx0@zd{t#6H9`GuW3iGyE@O zW{@wR&U4;SfiJh5nc-~>Ged7VGsD@M=~f^y=~`xnvkRCR^jeu2)-ITy0TTPYfSIA^ zA~QqEdS-^4i_@op#CBa|W;pkfnPKA#W`=byryn_Qs9^KwB{ReBZ_Eq@-V0BK8|6oW}rQwhpaaDHcI=>IWY;ew$8-`yX~3>Ckb88-Z4W{CJb z-47(T>^C!m&0l7Q6MvW)Wd2UC0f}Y(WoBsl$IM{ykC`Fq-}F@=u?_#284Uk3GkpBV z3`zwzKw|O#nHe7aXJ)AX&&+V>|8%yCh6;S3UD+3eSs3DkSQs`4PdB+}s9^I?n1$hn z5(`7RA`8O~B^GdMvH1^ixu1K8nK{JCP?AlVg~3&yg~3^mg+Wz+`UH@v#riA^2Q63_ z0?b($7FtZ-2NHX4!NTyzk%eK8BMZYF$LViCVp>it48ATb440i*7<65xOICAhAoKEDY6QEDTIxEDX_M)0bQ_ zRIphY#=^iA&cbjqjD_J<7{ujnFTpPN4|no0GlRMrLRo~fFzk+JVTcH4VVE61?XsZ) z-^+LwhTcjR2F?T)hTO{OdLXggl`IT)vsf5DHM20t&6*wq63dyz!oaeLg`sB_3&WF* z)4M=oMw?g|)*fSF2-?KL(0gq94v^UGV=N2{FR?KEKE}e(cxn1Gkl6W4EDYASSs0ez zWMPoLJzeCAp@L23Z5D>Uhb#=g@3AoCJ%l*i;tAN{@%};XW~hbYo`)<95>Htec%QH^ z{CG0G;EJIFpW9OwhL~3@42-W>7;Iimp9d1_dd0$U_$>=V^IH~%#c!vd0f~Kl%fg_> z$;u$i#>&9PIsF$%EQFJlK~{*BVTvFt!(YMa8dnV!_`HQ!8I;sm85W4MGBBx44+Dt> zsIfAfv}R?{wq|8mX+6E=s-c3-cWYLL+n%fpHJ+>tyFFRKi3O5DUHsjh!qJjBrxzm6f5kn3aL2h?OC>c)ATp zY;`d!!<+_IhW>h1hMI=ySs<}f4Xg~uJ6RdNcCa!m@0>mZB=)tFl|gYLD?`l$RtCn2 z(~p6~{3o(9NKIvBSU821;n$SuU#=M{*mz83WjH&Nl_75?E5q8E5SKfGix!vQ5cd#E zBSD)0%-Wo5WMkCkEeJXVI?^QPB<#5m`(GH5Mi zWq7rKm4R#F^fe%{h=r^S^A@u*R4im=s9QY!7D(*OVpfJ(%UKzIFJon>T0WiQhM@xA ziRG*ed8=6&{;gtV@LN6I3?w#ZH7i5NI#vdjb*u~~>!zpNFjTNr@ounSsS@$g1g2B}@F439UmGW^;({Q$^Rk6o+`8v9roGWN1EaO|7@ z4kQ+~kCkE1K~@ICgRBg54o;W3X{f;W>L4q_>cgxI!G~EHx(`qH0*T!`%*ycMC@aI{ zqpS=kj!v%tiHRL!Wms{Hl_BF8D?`Vz>B~T3*N(9=oIJiZ@5ips80_89Z;WGCaG^%Ak2;y1^|&1-|kdtPI<3 zu`=Y`Vr7_iYkC|=?8z-wh8cHQ8JzF1GF04|-UAXlc88V0{T?gB*So9?>i4Ga0*RI0 zV`bQMpOwM*J}bkd`_o^5#2(ydWl;Xj$`JO6m4W&9bg|op3VeaTSs5n&Wo1zM%gRvr zce=}MLj{}te_0tm|6^rX{g0L5@;`{nL%G0V?jPiCXo*@VD*k6>xcHxyVd8&QhK>KH zF94bP|35239X}gGA|D$=9RKulAh9+4Yz*7P*ci0M*chgXP5%QDdm_fh&@IEppdiD> zkS#M^>yDuU-%c4eh9)gGhF(QBh9s@&5g@S*T5JqzmTU|^_1PHMET^}D#6m3D7+$!s zF*w+1BtDyVq=J&$i^_WpN+wK;`AJlSm#7G zhPeyb7#bF^G1M-cJ_{svdLbLb>XmE^-YeM{x>rs=0TR2pl8xc%MmC1hjcg1@H%|Ws z5)aO6>REvvN5dN$HtJekBy;kAH?MmGN3Sb^9c=cMQbYF z*~i8peVC2m_8~Tg--o6*+%r_*^E}MPAb*UF;r>xJhW|&WuLFts9%Ex*yv)Wh^CTO? z!%NfefW-7KvoQ!gU}Ly_m5t%k{pnoy4Hftt9!4EDP042N8%e*l>(;L6Ux;m^)s;L6VM!f(3V149KqGkR}AhF1N zc81gW>GV3MAHEz|OFuo}FQGEjvR;{d9>( zh6;Sw>e(5}d)XQMyV)7Sd#AgB#FqB5GxW@0XP7>Xogrt&^pZ!03O2iDurtIjWM^2t zfStj9A;jegY@jgraPo8aN2`f?7qT;OFK1_1yO5pX^|I*~K&DzQXJ`1hft?|8IXlC} z4b%UD#N;=!Gq7)GXRzPM&hUKObe+eB3Vf#9*%@XZV`m86&dyMMY2pA07o|8DJmfeS9?EhsXvj@J z1rjTh<6wwZXa7`l8p z7<2-rhdeb@u&D~*U~o*}U@Xv*cvBX2A(6 z(Ai!XD)5C^axyG;;AGHu;ACibm~QgIP{HP^11E!}8z;k0S55{=H%@Sv2iyU<+}l6I zKi<&@#pUU4oD7-noD7=ooD81s(uZD7fycz5}Ut}li|cFPKNypIT=>0nlAOyP=W8;DozIfJ)8_;t2r6;_e}QyiPi4m zWN^OC$uM^hCxi0s>180X!rPn-4i7jPCf?>`PAVM=44RKQ8TuY@GH^bI zxZM66$mPD%AAT?t<_mw!$=V$*}MpCxg=a>3Sfs zg7=&Zl^-}6CcNili2N`;1|+up11Ce^M^1+0A2=BdKThugiPeAPWcc!tlVScxPKGNV zr|$rXDShH(X!^v-;Pi=;A?effXCSc+pEwx=K65f$_{7QZ;nQ@H*M z-2ThS;Q9~ZR!CFD*VoB0*aW^L6x=|Z{Ew4i3kMg2H3t{N6b`QGg|7|e`5tj_G34@c zF&yXNV({giKJT@m0^e+2E`|-FTnxK;xfmvhPCo+@yC=%UP%6vCz%0$h5Gp(U7f5We zEEfZ-3Kzp{WiE!N%F{L87%K1?t8g*&s&X;-s&X;ps!k6BiS1V9Vu;b^Vu;q_VzAMk z-txv!!KO=_i{Xww7el2!7sDQXE^q>Yl;OUiA?_h)H9nUC7lVco7sCrfE(Q*x=?_4r zh8b}&oN?k}$aLajSmQLE@2#N%-!CUFh7$o?3=sib3@ZYr+knKr1#mIg#&I#MiREID zjhmhY63dR`VmOk?#ZZ^Y#jqrE`V5fRr%Wyey<9E^%N#BSzTD}@Kw>euTnzULxEN}3 zxfu2pO#kxMP{D?$kc(k)6BomTIxdFhCWy-oz{QDQq>sO!DQap)@$7H~0`tl?rT_HSnpe3Pu3h0`;JgZPxvLx~Y5P0*yT+TNx;*?U z7sH|3TntUOxfmARo_+vi>WAB044>|BF>JcS#c=7)^miaJg}Yn~Cm(PzL_XkRSovVO z%m+gSzV8pX7`)$dF)+O4V$gm&-3ugE`Id{}$agM=mhW5)OTJI9_+Y5O|LHpyLo72l zgDf*QgDo@n^yME6<@vjrxf#~+aWkxD=4R;QGh z(+g-16C;Dahev$8nE~k33UD$95nm;^8OrRq8J6mEGlbbqH~46%z_-MXn;|-on_;p) zH-mNH^f-`MXCODjiv(_lu6S;S6A9CMKw@Hv+zbiX+zivRxEUO>r|$xZ^<{H2Y^~vD zcvH>IFtuj-3y|338g2%OCT@lWjob`B8mEhW0`+j4xEW@*b2DhSb2C)8Pj~rbs9s4+B-%H#KQ?E{s0Es=m%FR%AlbhlAb#8{Ro73AsVoPpvGaUQM&2Zu~H^Z{8 z)3e^DtDh@J|2!#ZaE_I14XB zml7|-PZ?f@ET!oxUkw#(b|~>OoN?e~cy7(hu*QKG>~ueHCJpd(^h0kV{&L`DI2Fsw z5EQ}7uqt+X!&gHEz8|r?436cz3>?M042tE`*MY?H%Xt|px_BA(cJeYrbWOhl5?j{A z%TV0U%fQ&r%Mjc@o$H&S0^h=ZUWTGcybMN@co~8wO}7AvEttg1pg)C|;r(P@2L372 z(?DXeQ+OG+FX3gVox;m7eaZAG-wYLOo-W~K*u0#VfonN0!{p@e z?>BiF7TlWd0}^|8iZM_vZ|kGu?%KTfauZm7Wj@FOq7Ar?M{auz;@MJ#;NSAI8? z=lj6I#}F&d#~>@t$6zZy{TfJfw>Td|n<^iJn<^hen(B0xABGAxTU7ZN91Qpvyfpb3 z6b$&lf$nAiDqjNp1HvNA4N)rnJdjFTK8A^=d<wB_D(NYCeYVtN0kiS5LnHGBtHIA4BjO zJ_g}6d<@2GrvC$pHLl@fII)(GVbvNwh81h4>-+*WP1f=;B(CFQ5L?H`;J9vj6iBRp z9Up`6dOn7O>-ZQxubbWh5_4S7#}K@gk74F!J_h5h)3<@d8n^N>=zQd3s5r^T!1HnX zlV64kHc=n>7!FGEGfZOQXILo74-RwC`5KH2!H(eu@#d%_MDHc}8H^nH8I(2o8H60C zJN!0O;7f4iXPD&7&yeZF&rsw%Jr5*yz?q-ng$qA}iwi%)376?}Kw@I9{0zHX`57Wy z`59)pPCo?_d*RB@;N`~8!0E=%pyf9G2S}{Kji2F$8$ZJgH-3g4ZqwEN7%K3wx$`rm zx$`rqx$`r)xla%IW2j&=#hstwi#tEV7I%JzEA9}NXMsnEf*r%-W3`ri-H-Jpt;K9!z;K|Q$!GoXSgU9rHATc{neulXj{0y$~{0y}j(|P_HD)61o z;AhBh;Ac2c&d=cAFx?6yHn)MFL2m{>L*N8{2EG~7GeBZ7Gx!;tSMW0!FXm@ZUNL*vJ%h zcO1_xeum{A_!&&!^E0%6n6B{8P=W922Y!ZQ|M(fI|M4>{`#0V1pP>T(mw)^W6F3AI z0yqR13OEF&*Zwn<=iA32z~HGQz;KU4fI(Af`YMp-awP!<1~&nQ=}H0&4_v3;0Ey|j z2{71(2{8D%2{6cpO=tUWsKA#UCcwbgBf!udCcyBnd%DSgLj@a~9svfmegTG<9svfn zegSZD@e~0i^k5H1?@%+;7Gp@i07LaM0S4>20u0g1rcVHwx^kHS!@ivY4Az?j80PJq zz7Hh!W~Ttd;?n{QI}ZymG@qXS1|)Xzv;afn1p$U%=LHxNFHDs(Qs7&EL4ZN?iU7ma z%K{9XSEhOxDe#3~5nz~gU4S9#x&TAf^{Hh>3VbK73owM-6krg!DZpTIbLtW!1)HXu z0t`j>1Q-_G6krIt2XVDL#MPdDuJNX*iG0C50fv?L1sGWF3ovxvpT=mUz<2$=07LEr z0S2xI0t~(nrt5*kW9u7!}3Q04C#*q7}_6Ae+Ck}`bdDm^sxZL*GB>jqK~JG zFc~S>BtI5l*z!_GMEhE$;*vgg*!{Tz)UW@cI4pGaxa?4+0Due+w`qeh^@o z_UIZ+aL=?1`QrLz00Y zgOY(DgOkDZ7G@&_n+XPj3|q|w8EQ-g8K#;Gf)k1fc%&lO-^bejfE@whJ=sTQA7)XxsD|ATfjOf($Wx1sMXi3o_X3oqh}? z*0ooV!QiSOgXKv<27#;7zpxl7*v4HIWC;2q$gt+6AcN5th|3NBfx|p76eG+Vz6dhN z3kfkOum~~y7ZjQv$Z90d=PM+{FkM%OVVi^yL%HtsI#weEzN5NA3|$^V3|mcw7_vO3 zuK|he@DO5<2^M1b;w{ARCusUDkeFAn5Q9gZ5X0wSAqI`Q=^SiE3VdaCLJZ4S3NcKo z7h-5%Io%8-c6Fr?L)LjA2K7}!3|{A_r?43**vvRD#PFJ3m|@2aA%@fJ!r(x62KV=a zgF}LhEl|_BB!@7=ZFyma58T2GyXB`J0GZ0EAk3g-B+MYIDa^oRH2ob&EWk*Z!PiEZ zf!9WuLDy!w47-s6U$u=egQBA_!)zO221du}ULY}lM`4Dg?!pZDj=~JB?$awkVwc^8 z8B{}r87zW?8CXN6F9V4MhX^w;R|+$HE)iyUTrvF$yODy8VWlub;sjxa=iR~#juRj* z2enif8G=K6+(S&wQJUxd6NDK8mIyO2FBWDnSTfy!!$^UzZiz6%#vQ^8Q??5;Ox!U& z4kUJehcLtO`z6faqcB~J(@24DmVyXFsILfvuA&Hosqb_bP9p`IW?vBo zxoi;zZa)!*e_0~nFpuB>Czp_5j{q~&d1s$&5r*7C5r&*>5eDDF=?g%n&Mp*TxYi=V zFtJ{QVOz`eb09I6RuP5?Jt7P$ts)EsJ=6by#P;=wFq}On!XR~4gkkNu=~`Sy3VgrM zi7-Um6=CSRBf?;DcX|X!tnID{L+o=A2I1!-47Sgww}HgEpNlZ?ycJ&70|4 zxQrBRtlo++aEOR9gbRr>ybu-zyBu_|C?i8~q*Jhwi3Lh?%S=R+p-MrNflXeNAxdGo z0Jo6>-wFj$hB_Tl1`{1ohB%$+b|A4eI-(5c{Y4pK{X`ko`%ljSiT(8#W%!sb%5WuB zl;L9f^jRP=`3zA8g-lU~2^pdc44KnUfW-VVMHzl%iZV>e6lJ)PIsF?*Of5^4VQH2q zLs*t5Lu=M_6&@o6o6A|E3|85q4BxXv8KklyF86*74)aJqXCDjHiHeMDQHB%Qq6{6` zq6{mtr#J8zDe!&E7G>C*FUnw=FUl}CfBHI**z0^z2I*E&2JQk;hTkpI?|{TSTSXZb zc8fA(wu&+|c2DQxHB#U^-!00}H(8W{f3he;-sI^PAhA7@MH!yV5M^kXAeG0FUf{o(}Q3jcS4CSXq8IBziWe7h#y$U3@^t330&UsOWqo+j~c+O8>0TPQkFUnATRg|IX zyeLET)#=wjVk@tTGJO6b%E0nml;QH1=`8$43O0&gMHz0fh%q>R6=m4PA_h(^pfjBr z8A3oqa%eN=9IRpt;SypD&&0$S%q6BL@Ea-cwMvLF)ToIuyipZnh*6u~2NGMQCdLr$ zD8_I~O^m_Xarz#RSf`^HL!XlvgQAldL!Q(0S0J%HPGSslF=7nD5n>GgqNhs;7%A}i z#E3EURERO;#E3EER7`gRiS4QoW4Kc<#_+pZjA2jx^b!Fh1skpgF^1C}Vhr=!#TZt1 zKwPc?9_|kb@^$hn>sZ*wiF?^US#t=VOjN!uE>Hk1t za`VI(*p`Vg%vvhO@NDUH9YG@nK9gl)49_-*F-+JX#&B%I^eB*+$VM@S((PglrrX6B zLbp%v0EsQ$F2+!~TZ}w8LTy2Tq7F1e_3KSa4#xgOHH|-@6lH3<_t( z80MT2V_-NtJr5-2cUFuc^@13K`~@)v*9+6@(+^&i-cw7@>;J7BnpmA-wnlPw#x+ccJeOHX((rqz@*LS9e z2pcKbSl$(5`0`MU!SSIO!SF_?tK+w z$oV$i3M97cn;3)CFENG*KgAe+{hXcw67%>a#t`#QjN!vyF$SA|)2E3TDe!mw6Ju~; z6leIvAkLt|C_eqDh>^T)5u-T6Rc3L9sm$UGTbaed3Efv5>~wGzH3tn4!7($7IKvWF zafTFDafTLF@#%`9M)LfZSj8D8u!}PUu!}Pku!~Rk2MO+D7iZ`Z7H7D}F3yl6EIz#! zB)CghoZ+XKIKwSrafX{>;?q})8p-pii;FXetBW&Ck`-t8t~ULKsF4DntGYPD4+n7u zYddj<8xGUi#Eca9)EvbbW<`iIwUoO zt}st0*LVxmLj7r)I74uOIK$q2aR%dp=@USvHWr98L{y10{H+vcu&A284k(&=og~h1Vxl<1--*-9Kw{pL#2H>s6K7a9O`PHMwCPL4jTCGor;9Uuoh8n&b(T28 z)madi2R{dedzh!ckDnuIl2M*5&Twa*I79n9afUtfrb!qn@Nvx-XV`T~oZ-i6afVr! zrt5*kUR)Aq*!5kUf#b3`!>sSqW58nH#Tj1z6KCM~ACYvMo@gd#m|2{c&c(pM;HsNjs$gi~ zZOGsm>=q)yz`)>Go>-QuP-dcMVHND=>Jp+*W~gUmVKp(>R7-?`fx*(uz|zP-p)9pX zPr*>nz(CK?i~(e@0gC}caY{*Iac)753d_c0XSg@7+6d&Wz~6Fl2}zA@TaZeOO)6r{0TB!a0-a{IDErY9oXm$fmaaBWwc$mGYh zeZp*}dz{<5mNJF0ZU3{H=@94kTU(h_*tSdUVRB>MUbCM`LU#LxJ4{w$+u1%d9pc;m zgpqj<|MoqC%w25TlO&keux;0pXO>{y9;d=w!?FFF4s!^{_B2!GIjq~|tU+pyI5Jl; zZI5zcwvgGrE`j-t{Pt}P%s~R%RVFegaBN>NlQ~XryVMEh9ah`lF|kxQY;SUA3DVsD zA&2D%-}VdDEEn9j?>Wr!Mr!+!dn~6!wy*lk@=Iv@0XEh{7Tf39vu^6!o^y`1jBWeB zE37uG+rw_Lu43IT^MF-@X?wyWRw2gieUDkAgtoJMW6j{)-tnKcMQ6K)4%-dG?J{v} z8<@AhNMzf=wtY_qn*!(dABAi=eA^ou*sgGFFX&|RVcCA8m+b({_AQgx<}q&1o5H4` zvwhV8wtITpm%L|l;NJF|ZIS!-eNOBtiQDa#uxA)-KXiqCkL31Q@7T{VZ*Td;UdFmz z><4=e^Y(ea*$bGqYyD$)V%*;GpWTgd>nn}}>f4WLaD0*7e$9%Awy!AS zh!WZ^*UHhxvi(3OhaUHKuBjXz;@k7qa7EaQ|A+&*VJXBW?Qrz4y{*tUnA=FH*Re(x&hCbsQs z?r^R$+g>EhbxCl0f-2WL_3c@{Tt?d4cT{k3$ZWqeh3kXB_7_XJeyD8!bBc>icDvjQ zE+wh$F-+W6LfbcqaL?e|o~F!wjeUEBHn$h&_I)PYB5d2=S#e)r-hRuDyNP9cg){d# zmhDL%+;`ZwM+I>Auy1FI;NHNx{ah?}3fp$S6z+Ed%Ogs;IkuP7a`UinpVPv9h!a zw`+y*=*Vs_D(19R;c*xfzx3!GFNqW18 z3_qXPb~_{f4#Dk@ocV3Iw_Ex1ZxY_lk<2f^v)v@0pG$swR3HBl*6mhP_`~$KuQ|*g zCca(nHh+=$_BEgQ?}%()!Y-gDu>G01K$hJ095Vqu_U+qj1-RI@-*Fb$W3qiqg}^(F z?fVuAoRi2XyM5ITQ5UA|T)Ralv2WjTNc4ro_C2>nuZe75_d!%deEU6iu@15AO>$yl zBHOnZi8*+07pN24pt}9eVzEDR+rJzVyC$;z*>$lVrR{yc#8z=_4`CI5!?is|K>QH< zb}I?-Bdpt{cFAQy+atK7j#+QFa+Aui*}kty z>Vf6%y`9hl}hTj_n_OWi!~emxRc&FmIm{ zE-S;d{Y<3nIi~H~Vr0b_x4(#$^v;9oA?6mUjb&qBF0=KU)kvrzMy{lPn z3Cnh`4!H?T+rM?mbuez9)g#BkIDJ>I+`sKt`sA1xmw)P)W1P-6QSRS%jY)E#6g64y zpWXI^OL86h+gX_8lk~SY8Orl1Y+n;7Zz8e%Pp14SukDYv$d~DEFL@-dB(r_fKluvb z?QTK}VaD5cxGDs>Z&&M8h*Q|UV68$+_I3wJMKQMRMe>S$dfR3E6tmQ}FDg-7r@TF9 zhT;Ow?HY>|P1v_rtW-S4wmoWtVg&Q{bDI?vxVCfcQw(C-UU5J%hjH5>MHa^C3WpW{ zZMQn2$i%oj;;16y@{(hUjN2z1SA4{?z3+#Vn@sH$8s+a405a>{hO)g%=T(d}`|Rjk6c zZ~3dTC~SLCh-!}a_FwZ=pA~HXBcOIffBPK=wIY@6S*dDPBHIsCs&#R0Pit0t$Fsd) zg4z>_?FB2<7I<#g`K-1;Z~F^H^+W30k9n#u)7aioq%I)0eai&(N#fg+R;UYkZ=dj4 zJ;-nSKSzyik=rlK)+n>yo^)NKiD%mrjcsb%FL7x`@NajM(u`}_eqf&FFPZJvc5A*9 z-u~dcrW5yeyW5&~e7BovYMqeSF6E^4Mtr+clvbPD_9F|lGz_+LT-0)6+MaeiQsmT8QOmA+w10QH}PzjS)+Z) zZadd&?Je@#Z*l3|Q`>&UP)AQ@yPTiSBGc`6nsvOGwmY@yuo!Po+NpEEV!PcZoff{W z_jC^lZr>xMDNh;ILsq|3y+U7$es4f}S93S9%1?I|_7 zCEVM;wChgc+P-9x?h=meDYJF+*tWl0s4K?0U17Pd1k3i2)w*s>+qbRN&Enl|vs-r? z=XSoMy0bX9A33Lci)Z_;+q(Zaw_kax>%+0!=AAD4_K2^#864a1{MFsUx_u3^9vkcS za~yh2%-eH#^!6}scM;ILBfi~6L+=3Fb_snw1%>S){(8%dw~ICFY3Of{+N38Zvwg}r zJsIKcXCCUk5#D~~tKK>8?fV$@ukdVN$ETmgz1>7gpO1TcoT`2U=k{NE`ajsW^O@^! zVc&kwPJcoA_F2pHA9-${@j>5>Z~L!*`YUv|@6$2(!Lj|4seuyfbOCDv7A8ND>0;If zew++2Fg@4WK-!QQ#s$*>nTdJ%3PxZyj9_G7U|@l97#ODSv^J3DWmzgHWz|5Jwn7xL^`wJujFA zCZ^8?Y2yd8VFX-T8B7G^Y5@iT1b6yNkoAH{0{pfH(uP6^0R{#Jm(-Hdywns0*8oH? zurhEkfO9vjdN;@%MI?cZAaj%v0t^fc;h9NAi3J(?d8r6tZUznp zRRnkXUpoV7el>&u0|SHKbVhpvQCiH)p=NF}9=I1GRmcS%L88{eRU>pX9>C#RH(%h~{0*+1w(uVE`0Z?+N z%*oHwEiNh2bBCJ)$_SnaRnvPx+Po10Fl`F%CCJ%9fpBIjN~BNr}l|vtSZ(3>*vzFb)I5 z^tT{wi3kA(1_t*MJq0(YR+xl50|!GgjKjb%-O|-SnmYwaAl}tL+As|vz`(!|keQsF znxf!@C>I$Rlo%KoG7ze!uLhZug(PqhWDcT80LcXBBo-(*B^DPW3Tkk%ln0W8;OVk% z2GWKF5Dt_KuFNaR0BJKcfM+Q+21bS=s641V&vY}8<}OAO=m(htPr6_UusIO>;iZE* z0|x_A{WJYG$eePpaxgKS(cM7Wuma465y3h6WDCeWtsCG^e~V%Y)1$%Ffas{6lLb6BZV0Q1A_qr14Ac5)%04Bwr+#~NE^ua zXnH}>(t}Vn{UpfxJ|uznAaf=l1VH9g=IKF=foBg;(KivHYPz+jfi(AIB!NUv18Kvl z2muBLhOqq1CaNCNU+2GWM}5CRMg3?W7Nxk>qXsYpqh!IFWIVF5zb^lUE!Y3_wc0uw>zEJg@` zvUpKyUUG(lM}AQr+#{emV<|$_^t&K!%Mk($3=B?1pzH(+e}u3t0|Ubf1b4cow}CYG zDkK4aZv$z=)d&GdY?NdufK3BM0$9$DfrDW!m<1-L&jy*Z4$KA<(+`5oSr2Bz2xuMy zxeA`g>=`&1Ho_DzFihw5F_1Rggb)B(pI=Y}YR3jABC;B&rrV5AH9gYDK$?3il0ZGk zob3n!P;ev`WtMi6iHw`$eiN{0Zm!E+Y&sAiR2Yv=p_1BR^7#M;R%TbL1bu}0m z7;d1eLg9lrfeefcw?GUycF9jJ$uCj}Mh@XX1`dWha1{&;45|#lm3ey3i8(o$`2}#- zgIWc5k(5oJ=WifobRS8Cfx$T=u_!Sw9YqY(PI!nUGX0gmffUbUWD$V?11Y1YNFodj zpt?#yO~EHM5mB*%nhwvAR85ZwFp!FPi6p|n5T00+s}O*siGhJ3l7WHYHHxZ${G7^S zP?d-z3Tk$|LE=w82XfUrBoPJ%r~LBN6b1L3#A0{>!vJb`d_Yn)T`JH(isuuuh(n-( zl+hO?5eA0f^3>D67BFfe>WQZ>CN&_F8U2a*T_LvVg+UP?((VsbV@7}R3kQzQ&VM9T)4hTWq<9!X z9b~BJ^nxG*DI;bi5e5d=0Td;|NUEm42{w?55JeJUVDL`N$;?dx#TeLfFae4u zF%(r!iRlHIh^z-zmCL}uAc3T6dR&Nsl#vvY2m?cKMq*xKCRjO~069|zN!9dKAqG-B za>ybVKqe_5iGW%*si`>%E=8rehzJBVm6VWFO_vEZkcv=25@BF)PAo1-%u6jn=we_f zX5e5@Ls1oyn3)Z77u=By3=E(qggTO{>3yLFQbw9cA`A?^sX6(23L*KqNS)kLP#X|Q z)%07T22wmaNFvk145W;7kpvhREDS6_#vt3zP{zQ)ppT?#x=)yaRD=PN2m?b-44 z7(y~i^HNel5e;_$LlpxPgB^;h@XS0!sSH(E#lXy9kECk)JCLg!kwh36oJy0D(5g~~ zDh5^tCnQzVts)GhcwCT05+V$wjNFh!7#KYAi;7cq-4k29MO7%;fxn66B}=b#lUxR87AVX&@C5fg}RT zenq;$C5SKqMNTaP6GIe+ssQ9V4BUlcW{5#jHQg`DK*}f%Nd#1U7Nw$;%wT=24Dm>+ zrq7Bpkm5-|7C8ViDG^Bol+qK6iZe3daR+fH2SYNFs_8t@22v3zNFodjjs*odiKU2K z1=3f?z`&4-qRJ<+G(95|wH;E&z{rq}q-uIyw1JdS29gK^LqKU>GE#>eWH>_|12aPw zlB(&aq79^YvXMnTfK19o5@BF)FU?a3&d3LqX<$=81gKA%hoow{O^kt5L;;cr1A|Xu zacWU|DM}#MGcYj}p{R1LD9Fh#&O~Wk*E29Plpv{^zAnZ<%BT!Ugn=O_KOaZB$dQPl?lxaPZ z2&k`BT8tjT8Vn5#jVP)DrZ;*Ri1IZsG$RR5zZYvDRo{vv!oc9_4{B0_EJxt~4F4J0 zP*fEpC8oKAObiSRpcw$r06QxK0|Q73G?LH3zyKaD294EoGcYiKhUh^9@Srhw z(1^MqXvhXMa1I)b6bDtu;2|{z@HjPSXj+DWfkAfq**F7ZRviWg2Hokr@dnb<4dM+X z1VJ52&~PPaFwzm!JDQ#glA923ATfPSyn#$4Xc!FCPz5zZL1SB>W@Rh`0|RIj3)C^h0|Tg| zc8Gz20n~*$#lXM->N%ZZU|=}Mz`$^R`q4y#+0#>!3`C~aBpKLD-;-qEGo2^dKxMi~ zvVqL>5D-z4Y~bPw%7mb7m&wQg&RC$Vl*7ot0Lno5j0_B*3{l9)08aA7j11sJUCPM7 z07}ZBgj&JKz)(3|HpM`iwSkd=p>euvih=R;h7_A0~^ufAnSAU zQ$Ps-mY^87FHALvW@qG@o^Nd+sw=_(nW#Zj3?PMa41rkYkTj-0v^EfBHiAwJiQ6!E zXzi^ftrdSji6DB>5aJtqT*f*@W~vg1c>sRKHtVbR5u7Ai8Rs{$^ag@hw1|< z2jR%+g0=>ty75>ibyDF586g>zG2JlFKvX;*>-YjXF_IJ zgvDnwL{#SFgX?jaeg+1Hxzh{n4McV4GdN?JPFcv{oLH2ZlY>%bGAx-sG2cK`d^y&c zlaZGL1eR118B2JDda(-(rYY=nnB@>Iwcs20%38dx=$*fHI)z(7=d z7tGZtvmSe=$2%H`>K;IrgpVy9VF*f1O@U0@fQe5_9wO zGLu0?30OS?1H%;tr^LLJ{Jd0@z`4obhh+le-t>Ma15w>45J}L$JW@OU6+#p#e|(tE z=xiXW`wi=i#9szqklo1RzzhrwjMEnu8i-1;Gh&;3;A5PAz}Y}VSA@|y19Of+g3-6M z1k_0{K~9x2)A@@GM0FJz-LOn2s4@DNr52?WWtOEXAf{@xrw0}ph)NhU!iN7ro`nUO z731^|E(RjHj*QqQ2%H!llk-c9OF*d{G2rhyeLu(zUX0l00{j?3J%*gr;$q}Ef{^Kq z#Rj4hQH-E20c6-65wJ0g(-qtdM0DdB!6SyC5fh}*{UnGeL=!yCq)yK-HW1a#K$e6j z;atX`(xjx+BCsBqPZB2^k5MD_fI#8+4=M@|1dt#D<8=Kp15sTTCU6o%8{Fn(a?DH2 z$xjCx2M=1l>4jwmq7uT$THr}cjA^=nkAaA;BvUY!;c7W1$DERU1*CyzkRw#4-v_xt zhsg=c$h0w&e^NfE9RyMd$7a(N%MC;&te8NV0(}tLmT9_!uYriJ0~5BfW>+TkQDcy) zZqxhA4McT4nF6p4D>FIemz3nBDmdljg9ZaY8bGT7E`r?P&lHYj1UZOldV!yTh;Aqo zwsGPxs3^oB7#TC&z5-OSGhrJLP6Ua5UZzq7oUPxWE|D&1Rauz~4YbH;)P1 zux&mQXpmST45gN4D4PDh!ay{t7#y(ZX|pwd7js)q^Nm})A$%Jhv?-vucp}XHq(?5h8 zi0J)c!Ztwnm&qx!2-MpI84Jh%n5G}7H4xGL&xCC#j)57Z2T@5vv@uR+tTPamU}8p$ z!XW~lnR&WGq=ASo3p2J+G*;%|G^dAqPpzN*oMnEn4J@gbY1h(Gm)2Z zaZcX|aswAw5`7Gen|XRbl!1sY4|8xP=13PWb4U?dIl{oez&BmK-au5BpBa=<(TB7I zn4LfT zvby>sEt-PpWiV#VOiE0@ATnL0(Lir{Sfhc)^d=Co4n*7n5o}Ec8qyaP%n<0R6 z4nqRxT!sS9c?|WO^BMX%7ck7{T*$DFa}mQ{&czI8IF~To5X8NgA&Gk*LlO6Wh9>R<43oJJ zGA!Xf#ITk7@brf*2BO+BJSQ3Scup}m@SJ7{;yJ^R%5#>XnCBcrBhPt;i98n==JQ-+ zSj%&XVK2|+>4vQalKd{bw-`crZ!;wG-eD-_y*oXz)j)Q7Q>%f*^m(lY62i;*J~C|M z`^0dJ?=!g>wS#e; z)XwRRod%NDa?%GF4Wth;I!Pa543<93m@IvSu~_;jV~g}L#wpUr8J9?(VB9KwlJS`I zDaPy4rx~9~pJDtaeU_0;=G^p;od%lI<+==1rn_|+$V^WI5p7)t64MuT8Hku)mix{4 zMD7pcSGm88?DGE@#pVAqs>w4jnaDFTxyUmy1<5lr#mloW<;t@%Rm-z6b;`3dO_%4G z&e&}rsm`Uq&m^HBz@(-i$Yi1*#N@0X%oL~~!jzyO%9O7l##E;u&eW?QF+H%`KyrFs zw}Hg;u5JT`>Fc@;Wb`wXOqeQ_Oqn{A%$Q~58%!(-UQHrfBHjb+kQjbpM@jc0OKO<)RE zO=L<@O=2ohO`d+S$3Rs7o@yr3d(|u^2DNM^9<>}MX|-G?O|?8GTeW;9AGHFe7_~yC zY_%e$dbMJvZncu>hP?)&>aWzQn0~2MGjXZcFo~|3(a)5kF@dRAV68Vzt&YaJ?+ep9y{}Ar^u95j()-SI zRqqGW3%#FApY(n)G3ozi64w92B%}YANnQURlbQa1CMSIc<{*7W<`jJ<=6ro-<|=&_ z<_>*U=E?eO%=7ixnOEv_FmKoAWIn3T<-&YJpPTuWJ`eMEeO_i313qR!1Ab;D0|90e z13_j710iM~17YTH0}8Awl;ooMiLy3{0t zFVlr48+@70HO1h|bf&2WU#9;85uc_Re3|}gy1|d>&t@3xV9U(SPvJ0GE-=f$WV+8e z0}c*mhRpQTyb|5^m~#f(W6l{C=}v$5*U*pm2`dA`WNroq4{ipA;_06M3>A4db2Bjb zDKjwqR$ySzn_dnQ%2Q@wIHb?O(67V5uxR>HkkBK228L`)1_oAh1_tlxmq9|^mJAFl z!WkG&crq|_OlSOWsK|FBoPptX1Or2J1OvnFi0KCZ4HbBQM=&tdM=~(jM=~(PPmld? zsK`4%l7T@XihsZ+&_6!>1GGB8MFF)+-^WMKG_In~8Tf!897fx$VCf#E?e z1B3F^LL)`q#z>wd}z_7G;dIU)9 zX)gmqz!U}s);bM zSk1to6vn`i@QZE8yIyD&??rKi|1`?CiVr1B9#>h}<#>g~6)#4H6z}QlKw?Y085xQL7#ZIAGcp7ROuqvXn;gK%FfW*q z!7iAQp)Pnj7mJYs-@af*hWZFb2Ac>*hWLo-79g?t5sVBIqZt`oqZt_rqo=2V#5P7V zG8o4)GTe`0WDt&>K83|d!6rDCkzs!}Bg3LBMuz#>5SN=Vf?V$8=pGPYW`Yvt_p=!p z?vybyY$#=9*i$zB1IW}rWsD5Ab&L$(YZ)12>!!=G8Y%F_)-f_jw=psVwK6jNZk_G} z60>e&WJu^_WO&}e$l%a9y$U4O(8+qAhBybj0{fwj11TM7#WoM zr(Xk!CG|5hG)!h>;GN9KkT7{V3!9OG&4S5{46CLyGMt;n$j~(%;&L}|m^(T8dHGww z2YA6L=G1gXhKgB?43}pzGDOUpp1@|Lz&B$SBg5Xgj0`8|Ffz=YJG~Dic6Tl#!|!>F z46EibGTfdweGf=XdOjnA*jh%0f>n$R-_}fj1rjq`%gDg9mytnkJ0ruJJ<}!FjTHEF z_A)Y<9%W>BeT0!g^yqXqkXYzZMuyarj0~zL85vwpPA_3MQm}13$;dF}0V9La14f3D z2N0J#yab1NkYjMLIchrJ@_>=y!(T>*zke7RF8pPjev#cso=@N(BZH0{6T?#(CI%k4 z>Hk1h`N%ObTr*-~=r&?v*k&|chr>vL@0$@5gSizGgP1WBgSgf7D3DmV6%&Je91}yi z6%)h%*y$Z0G5a_shN;<13}>>K7)rCJZv%;K&1PcwRm#M$p_GZ?R_XL797YN@Qe{jG z<@HPq=JiYr;q^@5gbvA~PN7adu4Wb}$z^&y6T^+!Obk2fnHYA=p6!MHWP#4 zV!~!2PG2}dBVo-d_#NhL6`W%p0&od?lu9r*4d zx6?zoj1+9RYk=le7@QrQ9OKPEYt+Fh1x%d!#>5c&n~CAo zHzo$#-_tjMOs)OR#4ulwnPDk2Gef=L^m`z&{esL4JzC5R{!+{gIa*+_hjTCH_S~D}ew`XR!WXH^K-kup8=9h^L#WGiKaki|7iI<*S7wH1F3b!n zuG4EkVkxf73?b3X3|!I73?|XjSAoPzqL~>E7cnz57cny|E}DJ=B=)$7nIXA?nSr^O znZdbYIvcN%0$+0lGlS_IW`=1E%nYJ)rkn5@DcFS0VP<%ChM8gCDrSabXCN+jc>{L2 zN06U8T9~t)WoD3i%FOWhF*C!jC(|c@OtpH-%<%IgGsC)%%nUa_PTvO-ll;WYaQ`zi zgXJe?hW($XzX6H;|IExV>l-t}rLW8kRo|vd@fj)b?fS;d5b%SU;m&tv27@2dJwRdw zKbRRhelj!I{bXjy_&L1{B(~xwGlS+YW`>tPnHe~LO<%%iq+sLui<#lfFJ^|!U(5_^ zenDKW07)%Ae(oVAsOvo5fK>6ZFj(=jF!b^JHyAquuPVP!BmEYp-pzW9!Tt% zEDHmx77GKjCJVz;&FL{9F;y)VhGJtD1|}mGhG66AT_CZ^#w-jAY*-i)Y*-i?Y^Lu3 zi5;+EVR&rE!jNgl!f@Db`ZJIivpow#l?w|)wlfPul*@Dx0V4&QSuQLLasez1oPI0} z|NL3NiADAkILQ5jFsKKzFn9z` zp9d1_2xMX4j$&b05y-;uI&%6MkeGH93&Z(h76$Jq7KZi3(|>`)-WRhl6is1aP^)8M z2%0ioL(oWpZ_*SN2CX$L44bB~FmSDz9tINgTEoI{^Z*M()*2Rur3a?B2pTEaJUzg| zu=)%O1M5K+hVC;Em%A&1T^{crmwT^5EL_omx`#3b&sFz7vDVYvL5g@NzM^em8= z-xC&w_U9}N?$22m(w|SC0TNsOoQ2^I6Dz~X|11o9n5G{CiTz<>WjM;s%3#CI%CMAs z`WGRP%eh$@_Q&?tuK|gD^k!x7i(_S|@MmSv zi<^E6B$gM)%5X7u`-m*VP)`}#mW#e zXZkXb*pxY}3`q-E84k~9WpG+B{felOf=$x`RtAkFtPDFAvodfjfjHcj3*>ND5C0%P za|4vb;<1F4fnhl-!-i$73=ft~HvqMa6_&Fy7_VYw_`H&pL3q{lIFMNIDprP7n^+l& zSFtj5ZJOQ#5<9htm0{I3R)$wwSsA*vP2U9;+s4XZu#1&p=}uM#fnC#IfW!iJu`&qm zVP)94o0Z|??&)IUMhbj}dsrD9_OUX&-pk6Muy4AHxRHWQ!ai1pPy1LIHtl0&xU>)A z@mi~2tPHHjSs84Pu`)b8HhlreRMq3G45?>W8E&6uWpF(+{TxWF^$aUR z<^@&;whOEbo)@P70f}{9U}ZRQiIt)55-Y=sOVhO^K>dMBtPFFmurjz`VP&YfGCcw$ zw&w~fgY7j|hSyhF8Dy_bZv%`1^^K!Qd4u z!`)91m-~Y=sH=aFyP-L1GMD|#$`JdNmEqkNRtDRz(*-0!joh!S3>&|(GGu;ZWtjMF zx*bUD;x|@?#_y~Qj^9}s62DK+0f{aA&dQ*`&c?vZ#>T+FK7AHQ%z>Sa!HbWLVLvY$ zgBIWP6CklHJ~jqH5jKWp!fXs5g{OZ5i5ZHpG5k_wV_=nJW4NU_T}2AiYEfcim|(!h zkgU$eP+-6Y&Y;16!KuYR$lcfyHJNWPU}JExV`G?O%Eq8#H@!j1NP#cKj*a1NFdIXF zFB`+&;OXl?Vt<3#7-l4}F*wJvF;pZ>zXKB6k-)~VwvdhCMgki{Z{c(GGI#t^)KjbZYF=~JYQ z6l^XpU}Lzyf{h`61slWu6%dzuf>Vo|PiTm%xg|p zyMc|NXDb_n*H$)$oUPO4WI!#Ht!xahcd{|8-pR&rdgpW>kQnzaHin0L*ccY>VPiPB zXL=P#jBzg;!`72*488~07^a?_z5*n6^&}g^j%#cTjc3>xW?Y+o4J3Bs8XH6CT{ecC zJ8TT5cc-(+8Y$S6-eqHOVrFN!$jHv1#LNy3bCv&~Fn0?I@d-9TZ7C)(voml@vNJeI zurs`tn4TbOq`;>w$<7e3%+ByyiJie-d3qm6tX`R&!O5DPVZJgugOc_1Js`0pYj%bx zS9XRbYjy@J*Xgf7VpXo}3}No<3az+X^w>{Yz8k5)=etWVrBql*z9s+J}c{m37`kSHF{R@-W z8N8F(84f0~GiWDIzW_2dJDHu~T{1gEcQQM}x#a2pKw^9;>skc80Ulrssjgc&D>7bkAXD(4EfC zkUeMm9FW-RIqVF{%h(xC&tYe9UN-#{NUV7oJ45ywc80~v*crUnO#cBA>t4go@NqXg z!|FBc3>SA#S5q`n;1k@#&TwfTJA>gKc7{#+riUmRDcF44$IeiDjh$iIWp;+xYY>-f zfh!^pe?RX?Gb5D!=yR{JGiW?wXV7@a&cN|#`Ua4x9*@`=9=>H~$au@naPaN)dx}O1 z{EY9|8T@~+Gw}alXVCw_KAl&|NS-hM2RlO&0|!Ipe|82ZhUr#HMhbjQ3>*y8`8gOC zF>o-H^H0wJiEZcSV9*ohU^p(s!N4axeHuv2Pnd(jSd4?=vnU6Hu-Nn?N}wLJ7ze{d z0}h6(+8hjp1{~mo4(d!WGI#_91bdpHRz({PI2brwIT+lWI2c~IOjl4gQsC2YH9!p-JdxaCNXj{oc+haP{cU>4M=PgBPT--Hz&hW4o-#~ z?&(shphAe7lVOn}C&L+TPKGAM=^h}lLyDXX{Ysn+j}$o>@|C8SfyCA;aWec;<77Cm z#K~|=ZTb>bP=T(_$snN1$#6i2li`C7CpgUABteCXw||I#ys0_3y#gZ)bU7KCO*k32 zO*k2nO{S?CDex^e;bdU9;$%2($;t5Ca=IQ!Ox=o;LDQO(;iVNP1E=-$7?7B!H7CRD z08WNXYfgshfazTzvE2cj45Cvx8Eyw~GJKsfeFsR)bSfu9+&oT((5ajZcJrn`1Bunm z<7BwLo|9qTJWht~>!*vT8!6a)U(d;~_Z%mK_y$gfx#u7b2W{nKWbkziat=o85#2q< z$*|@!C&S-!oD4merx&P$Iu@5X8QQOLGQ7FW$&h|+`aF=>@@t$7SMPB$9KXiNu=U>b zGa#|A_c$3^9&s`}e#ps?@@V=mkl2z(oD6Fpb21!x#L3Y6c)ErLsCIhH$x!};li}@S zPKNL&)5Abw)1PoM@I2*Y*#3l*;mwojEgD7&Habr^8G4>_GWa~@WXO36ae06&D9C-? zg9C#sQEUG-PdOQQo^djqdCJM~=IQhYAX9aoaWVvd0dOB6l~6laWSY%a4|d= z=VD-&-~y+XC?2rWLqps{Oi-QfF2Tj{LY9l+xeOP>3EAlZT1EM+o8h6pl8a(aN2~6fzNdMEs&U>DHnr`GZ(`e zCoYCRPSZKGjTHE7oVgg91GpGI`ExNO2TV5ui7gJ`V)zry#jq`!i{Vc6^b~C)1sjK|i4Evh67$jP!%jg&>@I|z8F|KGw*z`D%*z;pt3_)kP7=+GpF&Lel-UAXVI?KgS za*m6^^k&8k0()1S~vDiyo3>)upF{It&VwiYux|p7k z0^h}ZTnsWVxft%e;9~gmV!Df-k%FzwOD=}xU$_|3zi=_Me}T9>{yEs?&VKHWXgT!w z7cPcZ|G5~Rf8k;{^`C3{LOmmSJ}w4shOeC53|b7_3|Bd)p95JX%EiqvO`n_Lr~)@b znf~-YAhB)w+zh!++zd+{xEXw%rfcaNDe(0=aWlLLPLoU=}mI4J1|;!_6=^mz&{A4mU$>?({ACMhZ52bGaEl6>&3E6>&3MD&hvGb8Cpx z!(4*G&>HAM#oP?(72FKp%eficE2aw=7%A|zS8y|U)^Ibts^(_UteI{H63eXNX3(zZ zW_Vr4&A?qhJqIM_UC+(%tAU$gR|7Z0t%m8dKw?sj+zd0CxEXAlxEU&%rk?W)NfKVR-P5o8cS7^mQOH zGe#bU6Z||3)qFe*EBL410g1if=V8cq)3q z71J$1Vt*@m81^jTVThZ{!!T#b^fZvzoh3XB4ySn-0*~@AD4d=?#R$}$JI%u|`3nz& z#d{ux;x9blFn0itp9gq4`uU@U`Q|S?3}r&R3{QD@8N!67e*l>}O^BCal>slqQEgs^ zE`#ZE#zqQ!rwn)*X8H0mD0%QQRQXQ#0g3JM&SGMuV58N< z%doSVm!YzmmtkfzFWBXfj%a{qaEK3DLciI}%V0c(m*HnKFN5%u=?NxA3Vgv+co`I@ z^DvH_?uO~FKw`NY zco|qu@iJJSm?A451BAK2-^;DjFF?-Lnsi8@p?osExSk_aC|kO&_` zk;wE5AgeZs@G;oQ^D%fx@G;2APyYuJi<9SLu+rgUXjI{2kkXm1V`ikl7p23;;AF|i z@ZXS+LCJD@6i6(|l8@oID<4CXB_G3b*XbP~vFEOQ4DU1e7{Vj@7|v%*-v$!n&*Wn$ z?BQc@sNrJ>?3w<=%t*mzVh%&zwF7 zBzAo!AH&gEdgU%d22EN&R3_NqD{{V^k%;96$K8KGXXAU33 z^f}YjEQ}QRuFv6Ph@Q*Gz&V$X!FulW5DOy(o9elI484o_7%ng5W5`_$akVGAH#n3>Gwcl|JnH&ob>q_ zjK%pGl=P?bSQ;ttCF%1sOflqV$Tr|-C^4LF1rpn0$j@-ch@Zj2h@WAP(ewLy{RkLzCI`RUolLX8a6_Vf+jyefSv|!=~Q=i8+Sx zGd#`ZXE00UXE>TWoz2=vfsZwhpJ7@nKf}&ieulEv=_b}j3O3tX`5ER;?`ux+&Y>X86^7#cAei#Wb^z#ca+%THH#KuU$ zM#5NtLETw^!NOR8f!$dE9O$64Mi?1_T^-}mhq>IH1sGmc2r#5O3ox9jm}YCFz{gc7 z!0@G7fI+KLfZKEl{U&O^ygK95^b#&~Q|MVZqVq z1$IUXd=HKaFkCn#z`$@!fMLU_>GMEhA5IA{{5&nd5OP|8;pXY-XFy_-X9O75pAlg2 zIU~T(e`fkGkl6V%0t|*{1sL9+5nvEJJ6*%xNP#c#tN_EtvjPl-X9XB0o}C^B61#X- zfWh#b0K><#0t|xZrnlG|DcA&_6JXeQPJp5CoB+eba}by3g2#%2J^ftcolsqV@tgpI z;dudukLLs!1kX=@05Uc3ya2xKZs^y>l)udYwG z0f}kd5Ma=_CBX3frT_!St?5}HF^^jU4A*Z9FigKKz_9)H^cf(r@3#dQ(w_@3h~E)l zaDP7i7)Y%Bxd6jL7D0v|41x@eEYrU@7%A8sWD#TtkP>8I6%k}GkP-wZ7Ht-A4)qCe z3bsIP<`zf^GQ5)(WLPIH$Z$@2dVr&m0w14@AcL{8Aj2;OK?Y&v>2)BnU}ZrD6J0@u zVr4-F5#8x)Kw=@ff(*6Mf(*KTf()_I({F*q=0*!LTx<|zh%Oam*w`?g!wEEi-XO@Z zZI&Q|aho8+v{}>5Kw{Ts2{KqM5@h%`OOQco(exB2BL$nNMS=`%D+C#;76~$>t$?^( z1w2m_92n{tWP&=fxNL?Ob23uo zyD!Kf|5uPf;k_Wk|38A$Wu1-W`RxA+GIUA^F|1$~V#t)3?&WNxz_(IDh#}8dh+(FJ z5QCrb^a_wzpRo|bCtD$gQ)WU8mu#mm1BnUQ2{8y{3Nh@q6Jq#~G5w0Ok%EmurVvBo z6d?wmEFlKRDMH{dcLk4f1qX)&8Csy$p^a077{qo7FkRnyOb#MV~{GZgd*Gbr~8GX(Ta{{s@6&?n4rc#$x} zvW3D7ix*ATax+rkd%Q@P;q*pfhW8tU8CGwc9sv@2y-}E9%3fiHZF__nO7>1~1Bq?f zE6gDKSeQZlfH1?~N7J{s87bJRLpm=FpUWtbQ&%HR|%%1{_Q{R7CvN~C0ExZN6=iTQ5oO@d6J<~@nSKo^P&v*?@YhoW2C?@ ze^->@#v4%v`@5nHJKl&+|LVF_Xk73pFO)04#* zBGRWj_<@G?)5RDf3&a?7^Tik}3#R9R#3~EK7@k#&G00YnF&wL&J_jVmRwKrc)GEes zu|#26+og19_P6ykDUCqGNn;s48v#2C&j z5o73CBF3<0$@C2%Q{OBRV`y6?#_)Wl7(?2s>Gwcl%T|doTv#v0kg#5iVZ-|AJOM@u zd>__}F(_>jW0<#DjDcy(bSsdU(-tv?$n9bb!rR3dEVob30Ety@7h`y`Q;cEBPBDff zJEu{+HVt+4-G2FQ!#_;*N7{i_$({F&p{@f5_ zV7e>D5OPP1;nAJxY(Yi}d`fr47@8i4G5okM#*p-2x=E0cg6*OQVhr1!h%tCQ5o4J4 z1mbc#NSK4OC~5=X+7mH`3D3nC?4FA;6g(H3J~7Bho`1u0F$UpRVhopGiZOhCDK>pS zNYMC|7{ishv^*hrrL(pxcx1wX|Y zKD`xVX!t2M-4i5u;HMbF|36|34}OX<-2Wpsy*$`Ro=^U-7z01AI71h+IKz9M=}Ur* z6m0Z)#Tg!{i8H9Gh%+2g69=buP-rtUgn2r-#-pwOV^SAqD6GQI74lyIK$`A=`kQN<1ldst^{$0_3`2iui~e7 zfyA^D#2G%OiZi6AiZfhHoxTGkCYUD95S=5=a3@=w!8&L9GmuzyjyQurkvPNJLUD!< zh0{esLG70!afa#T;tWpZ;tb{G5Qn>f=XAq7{eAo_P*+85FBfMBuMuYusu5=}ubEyD zYNWtdUL(#B+#t>%+#t?i+%SC}NUXR)oI$5WoZ))2I0H}1^fMqapB8b3KikC_tR{*x z+}S?;7f4KIhd9H#JK_vBJH#2z-I=Zt25N)e6=x89BF><9SDfMF Date: Tue, 26 Sep 2023 11:38:22 +0200 Subject: [PATCH 163/223] added missing hit obituaries to Hexen's Chaos Serpents. --- wadsrc/static/zscript/actors/hexen/demons.zs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wadsrc/static/zscript/actors/hexen/demons.zs b/wadsrc/static/zscript/actors/hexen/demons.zs index 08f81b2a8..41fdf8873 100644 --- a/wadsrc/static/zscript/actors/hexen/demons.zs +++ b/wadsrc/static/zscript/actors/hexen/demons.zs @@ -20,6 +20,7 @@ class Demon1 : Actor DeathSound "DemonDeath"; ActiveSound "DemonActive"; Obituary "$OB_DEMON1"; + HitObituary "$OB_DEMON1HIT"; Tag "$FN_DEMON1"; } @@ -230,6 +231,7 @@ class Demon2 : Demon1 Default { Obituary "$OB_DEMON2"; + HitObituary "$OB_DEMON2HIT"; Species "Demon2"; } States From d33f2697a3ec128d9385bb0d07c5f6f6161fff83 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 1 Oct 2023 10:34:35 -0400 Subject: [PATCH 164/223] - set default backend to Vulkan, if Vulkan fails go GLES not OpenGL --- src/common/platform/posix/cocoa/i_video.mm | 2 +- src/common/platform/posix/sdl/sdlglvideo.cpp | 2 +- src/common/platform/win32/win32glvideo.cpp | 2 +- src/common/rendering/v_video.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/platform/posix/cocoa/i_video.mm b/src/common/platform/posix/cocoa/i_video.mm index 9a2737ccf..88c1b9b7e 100644 --- a/src/common/platform/posix/cocoa/i_video.mm +++ b/src/common/platform/posix/cocoa/i_video.mm @@ -462,7 +462,7 @@ public: if (fb == nullptr) { #ifdef HAVE_GLES2 - if(V_GetBackend() == 2) + if(V_GetBackend() != 0) fb = new OpenGLESRenderer::OpenGLFrameBuffer(0, vid_fullscreen); else #endif diff --git a/src/common/platform/posix/sdl/sdlglvideo.cpp b/src/common/platform/posix/sdl/sdlglvideo.cpp index 326a5c9d9..86a31c0c3 100644 --- a/src/common/platform/posix/sdl/sdlglvideo.cpp +++ b/src/common/platform/posix/sdl/sdlglvideo.cpp @@ -315,7 +315,7 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer () if (fb == nullptr) { #ifdef HAVE_GLES2 - if (V_GetBackend() == 2) + if (V_GetBackend() != 0) fb = new OpenGLESRenderer::OpenGLFrameBuffer(0, vid_fullscreen); else #endif diff --git a/src/common/platform/win32/win32glvideo.cpp b/src/common/platform/win32/win32glvideo.cpp index ebeb13cc9..c972940a5 100644 --- a/src/common/platform/win32/win32glvideo.cpp +++ b/src/common/platform/win32/win32glvideo.cpp @@ -109,7 +109,7 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer() SystemGLFrameBuffer *fb; #ifdef HAVE_GLES2 - if (V_GetBackend() == 2) + if (V_GetBackend() != 0) fb = new OpenGLESRenderer::OpenGLFrameBuffer(m_hMonitor, vid_fullscreen); else #endif diff --git a/src/common/rendering/v_video.cpp b/src/common/rendering/v_video.cpp index 47caad55e..7c79e8bea 100644 --- a/src/common/rendering/v_video.cpp +++ b/src/common/rendering/v_video.cpp @@ -93,7 +93,7 @@ CUSTOM_CVAR(Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) } } -CUSTOM_CVAR(Int, vid_preferbackend, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +CUSTOM_CVAR(Int, vid_preferbackend, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { // [SP] This may seem pointless - but I don't want to implement live switching just // yet - I'm pretty sure it's going to require a lot of reinits and destructions to From a53d3d6a6e0b04f2b9c473179c583698de0d57a6 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Thu, 28 Sep 2023 20:35:41 -0400 Subject: [PATCH 165/223] - add 'mapinfo' ccmd --- src/console/c_cmds.cpp | 82 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/console/c_cmds.cpp b/src/console/c_cmds.cpp index 6e21cfcc2..9afa8c776 100644 --- a/src/console/c_cmds.cpp +++ b/src/console/c_cmds.cpp @@ -1270,3 +1270,85 @@ CCMD(dumpactors) } } } + +const char* testlocalised(const char* in) +{ + const char *out = GStrings.GetLanguageString(in, FStringTable::default_table); + if (in[0] == '$') + out = GStrings.GetLanguageString(in + 1, FStringTable::default_table); + if (out) + return out; + return in; +} + +CCMD (mapinfo) +{ + level_info_t *myLevel = nullptr; + if (players[consoleplayer].mo && players[consoleplayer].mo->Level) + myLevel = players[consoleplayer].mo->Level->info; + + if (argv.argc() > 1) + { + if (P_CheckMapData(argv[1])) + myLevel = FindLevelInfo(argv[1]); + else + { + Printf("Mapname '%s' not found\n", argv[1]); + return; + } + } + + if (!myLevel) + { + Printf("Not in a level\n"); + return; + } + + Printf("[ Map Info For: '%s' ]\n\n", myLevel->MapName); + + if (myLevel->LevelName.IsNotEmpty()) + Printf(" LevelName: %s\n", testlocalised(myLevel->LevelName)); + + if (myLevel->AuthorName.IsNotEmpty()) + Printf(" AuthorName: %s\n", testlocalised(myLevel->AuthorName)); + + if (myLevel->levelnum) + Printf(" LevelNum: %i\n", myLevel->levelnum); + + if (myLevel->NextMap.IsNotEmpty()) + Printf(" Next: %s\n", myLevel->NextMap); + + if (myLevel->NextSecretMap.IsNotEmpty()) + Printf(" SecretNext: %s\n", myLevel->NextSecretMap); + + if (myLevel->Music.IsNotEmpty()) + Printf(" Music: %s\n", testlocalised(myLevel->Music)); + + Printf(" PixelStretch: %f\n", myLevel->pixelstretch); + + if (myLevel->RedirectType.GetChars()) + Printf(" Redirect (Item): %s\n", myLevel->RedirectType.GetChars()); + + if (myLevel->RedirectMapName.IsNotEmpty()) + Printf(" Redirect (Map): %s\n", myLevel->RedirectMapName); + + if (myLevel->RedirectCVAR.GetChars()) + Printf("CVAR_Redirect (CVAR): %s\n", myLevel->RedirectCVAR.GetChars()); + + if (myLevel->RedirectCVARMapName.IsNotEmpty()) + Printf(" CVAR_Redirect (Map): %s\n", myLevel->RedirectCVARMapName); + + Printf(" LightMode: %i\n", (int8_t)myLevel->lightmode); + + if (players[consoleplayer].mo && players[consoleplayer].mo->Level) + { + level_info_t *check = myLevel->CheckLevelRedirect(); + if (check) + Printf("Level IS currently being redirected to '%s'!\n", check->MapName); + else + Printf("Level is currently NOT being redirected!\n"); + } + else + Printf("Level redirection is currently not being tested - not in game!\n"); +} + From 99fac235eb87e28281712fc687c85c6019386a72 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Thu, 28 Sep 2023 20:58:21 -0400 Subject: [PATCH 166/223] - make clang happy --- src/console/c_cmds.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/console/c_cmds.cpp b/src/console/c_cmds.cpp index 9afa8c776..0d8be2dd3 100644 --- a/src/console/c_cmds.cpp +++ b/src/console/c_cmds.cpp @@ -1304,7 +1304,7 @@ CCMD (mapinfo) return; } - Printf("[ Map Info For: '%s' ]\n\n", myLevel->MapName); + Printf("[ Map Info For: '%s' ]\n\n", myLevel->MapName.GetChars()); if (myLevel->LevelName.IsNotEmpty()) Printf(" LevelName: %s\n", testlocalised(myLevel->LevelName)); @@ -1316,10 +1316,10 @@ CCMD (mapinfo) Printf(" LevelNum: %i\n", myLevel->levelnum); if (myLevel->NextMap.IsNotEmpty()) - Printf(" Next: %s\n", myLevel->NextMap); + Printf(" Next: %s\n", myLevel->NextMap.GetChars()); if (myLevel->NextSecretMap.IsNotEmpty()) - Printf(" SecretNext: %s\n", myLevel->NextSecretMap); + Printf(" SecretNext: %s\n", myLevel->NextSecretMap.GetChars()); if (myLevel->Music.IsNotEmpty()) Printf(" Music: %s\n", testlocalised(myLevel->Music)); @@ -1330,13 +1330,13 @@ CCMD (mapinfo) Printf(" Redirect (Item): %s\n", myLevel->RedirectType.GetChars()); if (myLevel->RedirectMapName.IsNotEmpty()) - Printf(" Redirect (Map): %s\n", myLevel->RedirectMapName); + Printf(" Redirect (Map): %s\n", myLevel->RedirectMapName.GetChars()); if (myLevel->RedirectCVAR.GetChars()) Printf("CVAR_Redirect (CVAR): %s\n", myLevel->RedirectCVAR.GetChars()); if (myLevel->RedirectCVARMapName.IsNotEmpty()) - Printf(" CVAR_Redirect (Map): %s\n", myLevel->RedirectCVARMapName); + Printf(" CVAR_Redirect (Map): %s\n", myLevel->RedirectCVARMapName.GetChars()); Printf(" LightMode: %i\n", (int8_t)myLevel->lightmode); @@ -1344,7 +1344,7 @@ CCMD (mapinfo) { level_info_t *check = myLevel->CheckLevelRedirect(); if (check) - Printf("Level IS currently being redirected to '%s'!\n", check->MapName); + Printf("Level IS currently being redirected to '%s'!\n", check->MapName.GetChars()); else Printf("Level is currently NOT being redirected!\n"); } From a7258de82e00ca968c8a79859c29e0a1e47ec394 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 1 Oct 2023 23:38:14 +0200 Subject: [PATCH 167/223] print proper level and music names for mapinfo CCMD --- src/console/c_cmds.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/console/c_cmds.cpp b/src/console/c_cmds.cpp index 0d8be2dd3..706e6ec75 100644 --- a/src/console/c_cmds.cpp +++ b/src/console/c_cmds.cpp @@ -1110,7 +1110,7 @@ CCMD(secret) { FString levelname; level_info_t *info = FindLevelInfo(mapname); - const char *ln = !(info->flags & LEVEL_LOOKUPLEVELNAME)? info->LevelName.GetChars() : GStrings[info->LevelName.GetChars()]; + const char* ln = info->LookupLevelName(); levelname.Format("%s - %s", mapname, ln); Printf(TEXTCOLOR_YELLOW "%s\n", levelname.GetChars()); size_t llen = levelname.Len(); @@ -1307,7 +1307,7 @@ CCMD (mapinfo) Printf("[ Map Info For: '%s' ]\n\n", myLevel->MapName.GetChars()); if (myLevel->LevelName.IsNotEmpty()) - Printf(" LevelName: %s\n", testlocalised(myLevel->LevelName)); + Printf(" LevelName: %s\n", myLevel->LookupLevelName()); if (myLevel->AuthorName.IsNotEmpty()) Printf(" AuthorName: %s\n", testlocalised(myLevel->AuthorName)); @@ -1322,7 +1322,7 @@ CCMD (mapinfo) Printf(" SecretNext: %s\n", myLevel->NextSecretMap.GetChars()); if (myLevel->Music.IsNotEmpty()) - Printf(" Music: %s\n", testlocalised(myLevel->Music)); + Printf(" Music: %s%s\n", myLevel->Music[0] == '$'? "D_" : "", testlocalised(myLevel->Music)); Printf(" PixelStretch: %f\n", myLevel->pixelstretch); From a3eb1ec1fd3fdba292668e7069894fb548b578a7 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 2 Oct 2023 10:24:24 +0300 Subject: [PATCH 168/223] - fixed compilation with Clang src/console/c_cmds.cpp:1310:40: error: cannot pass non-trivial object of type 'FString' to variadic function; expected type from format string was 'char *' [-Wnon-pod-varargs] --- src/console/c_cmds.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console/c_cmds.cpp b/src/console/c_cmds.cpp index 706e6ec75..7743997d9 100644 --- a/src/console/c_cmds.cpp +++ b/src/console/c_cmds.cpp @@ -1307,7 +1307,7 @@ CCMD (mapinfo) Printf("[ Map Info For: '%s' ]\n\n", myLevel->MapName.GetChars()); if (myLevel->LevelName.IsNotEmpty()) - Printf(" LevelName: %s\n", myLevel->LookupLevelName()); + Printf(" LevelName: %s\n", myLevel->LookupLevelName().GetChars()); if (myLevel->AuthorName.IsNotEmpty()) Printf(" AuthorName: %s\n", testlocalised(myLevel->AuthorName)); From 1717ff47b2d2e82a43b407a4f5dea264e2f39b49 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Oct 2023 14:27:13 +0200 Subject: [PATCH 169/223] add GetChars() accessors to many FString uses where const char* is wanted. By no means complete, it's just a start to get rid of that automatic type conversion operator. --- src/am_map.cpp | 14 ++++++------ src/common/console/c_bind.cpp | 12 +++++----- src/common/console/c_cvars.h | 4 ++-- src/common/engine/stringtable.cpp | 8 ++----- src/common/platform/win32/i_dijoy.cpp | 2 +- src/common/platform/win32/i_mainwindow.cpp | 2 +- src/common/platform/win32/i_rawps2.cpp | 4 ++-- src/common/platform/win32/i_specialpaths.cpp | 22 +++++++++---------- src/common/platform/win32/i_system.cpp | 4 ++-- src/common/rendering/gles/gles_shader.cpp | 21 +++++++++--------- .../rendering/gles/gles_shaderprogram.cpp | 6 ++--- .../vulkan/renderer/vk_renderpass.cpp | 6 ++--- .../rendering/vulkan/shaders/vk_ppshader.cpp | 2 +- .../rendering/vulkan/shaders/vk_shader.cpp | 6 ++--- src/common/scripting/backend/codegen.cpp | 6 ++--- src/common/utility/cmdlib.cpp | 6 ++--- src/common/utility/configfile.cpp | 10 ++++----- src/common/utility/findfile.cpp | 10 ++++----- src/ct_chat.cpp | 4 ++-- src/gamedata/a_keys.cpp | 2 +- src/gamedata/a_weapons.cpp | 8 +++---- src/gamedata/textures/animations.cpp | 6 ++--- src/gamedata/textures/buildloader.cpp | 4 ++-- src/playsim/bots/b_game.cpp | 6 ++--- src/rendering/swrenderer/r_swcolormaps.cpp | 4 ++-- src/rendering/swrenderer/r_swrenderer.cpp | 2 +- src/scripting/backend/codegen_doom.cpp | 6 ++--- src/win32/i_steam.cpp | 2 +- 28 files changed, 92 insertions(+), 97 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 8510eafa1..efd33ae70 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -792,9 +792,9 @@ void FMapInfoParser::ParseAMColors(bool overlay) { sc.MustGetToken(TK_StringConst); FString color = sc.String; - FString colorName = V_GetColorStringByName(color); + FString colorName = V_GetColorStringByName(color.GetChars()); if(!colorName.IsEmpty()) color = colorName; - int colorval = V_GetColorFromString(color); + int colorval = V_GetColorFromString(color.GetChars()); cset.c[i].FromRGB(RPART(colorval), GPART(colorval), BPART(colorval)); colorset = true; break; @@ -872,10 +872,10 @@ void AM_StaticInit() CheatKey.Clear(); EasyKey.Clear(); - if (gameinfo.mMapArrow.IsNotEmpty()) AM_ParseArrow(MapArrow, gameinfo.mMapArrow); - if (gameinfo.mCheatMapArrow.IsNotEmpty()) AM_ParseArrow(CheatMapArrow, gameinfo.mCheatMapArrow); - AM_ParseArrow(CheatKey, gameinfo.mCheatKey); - AM_ParseArrow(EasyKey, gameinfo.mEasyKey); + if (gameinfo.mMapArrow.IsNotEmpty()) AM_ParseArrow(MapArrow, gameinfo.mMapArrow.GetChars()); + if (gameinfo.mCheatMapArrow.IsNotEmpty()) AM_ParseArrow(CheatMapArrow, gameinfo.mCheatMapArrow.GetChars()); + AM_ParseArrow(CheatKey, gameinfo.mCheatKey.GetChars()); + AM_ParseArrow(EasyKey, gameinfo.mEasyKey.GetChars()); if (MapArrow.Size() == 0) I_FatalError("No automap arrow defined"); char namebuf[9]; @@ -1360,7 +1360,7 @@ void DAutomap::LevelInit () } else { - mapback = TexMan.CheckForTexture(Level->info->MapBackground, ETextureType::MiscPatch); + mapback = TexMan.CheckForTexture(Level->info->MapBackground.GetChars(), ETextureType::MiscPatch); } clearMarks(); diff --git a/src/common/console/c_bind.cpp b/src/common/console/c_bind.cpp index 57499e68c..fe794c736 100644 --- a/src/common/console/c_bind.cpp +++ b/src/common/console/c_bind.cpp @@ -429,14 +429,14 @@ void FKeyBindings::ArchiveBindings(FConfigFile *f, const char *matchcmd) f->ClearKey(ConfigKeyName(i)); } } - else if (matchcmd == nullptr || stricmp(Binds[i], matchcmd) == 0) + else if (matchcmd == nullptr || Binds[i].CompareNoCase(matchcmd) == 0) { if (Binds[i][0] == '\1') { Binds[i] = ""; continue; } - f->SetValueForKey(ConfigKeyName(i), Binds[i]); + f->SetValueForKey(ConfigKeyName(i), Binds[i].GetChars()); if (matchcmd != nullptr) { // If saving a specific command, set a marker so that // it does not get saved in the general binding list. @@ -465,7 +465,7 @@ int FKeyBindings::GetKeysForCommand (const char *cmd, int *first, int *second) while (i < NUM_KEYS && c < 2) { - if (stricmp (cmd, Binds[i]) == 0) + if (stricmp (cmd, Binds[i].GetChars()) == 0) { if (c++ == 0) *first = i; @@ -490,7 +490,7 @@ TArray FKeyBindings::GetKeysForCommand (const char *cmd) while (i < NUM_KEYS) { - if (stricmp (cmd, Binds[i]) == 0) + if (stricmp (cmd, Binds[i].GetChars()) == 0) { result.Push(i); } @@ -511,7 +511,7 @@ void FKeyBindings::UnbindACommand (const char *str) for (i = 0; i < NUM_KEYS; i++) { - if (!stricmp (str, Binds[i])) + if (!stricmp (str, Binds[i].GetChars())) { Binds[i] = ""; } @@ -538,7 +538,7 @@ void FKeyBindings::DefaultBind(const char *keyname, const char *cmd) } for (int i = 0; i < NUM_KEYS; ++i) { - if (!Binds[i].IsEmpty() && stricmp (Binds[i], cmd) == 0) + if (!Binds[i].IsEmpty() && stricmp (Binds[i].GetChars(), cmd) == 0) { // This command is already bound to a key. return; } diff --git a/src/common/console/c_cvars.h b/src/common/console/c_cvars.h index 4d2737ab3..c560bb165 100644 --- a/src/common/console/c_cvars.h +++ b/src/common/console/c_cvars.h @@ -412,8 +412,8 @@ public: const char *operator= (const char *stringrep) { UCVarValue val; val.String = const_cast(stringrep); SetGenericRep (val, CVAR_String); return stringrep; } - inline operator const char * () const { return mValue; } - inline const char *operator *() const { return mValue; } + inline operator const char * () const { return mValue.GetChars(); } + inline const char *operator *() const { return mValue.GetChars(); } protected: virtual void DoSet (UCVarValue value, ECVarType type); diff --git a/src/common/engine/stringtable.cpp b/src/common/engine/stringtable.cpp index ef3236942..0774a7a9b 100644 --- a/src/common/engine/stringtable.cpp +++ b/src/common/engine/stringtable.cpp @@ -165,10 +165,7 @@ bool FStringTable::readMacros(int lumpnum) for (unsigned i = 1; i < data.Size(); i++) { auto macroname = data[i][0]; - auto language = data[i][1]; - if (macroname.IsEmpty() || language.IsEmpty()) continue; - FStringf combined_name("%s/%s", language.GetChars(), macroname.GetChars()); - FName name = combined_name.GetChars(); + FName name = macroname.GetChars(); StringMacro macro; @@ -446,9 +443,8 @@ void FStringTable::InsertString(int lumpnum, int langid, FName label, const FStr break; } FString macroname(te.strings[0].GetChars() + index + 2, endindex - index - 2); - FStringf lookupstr("%s/%s", strlangid, macroname.GetChars()); FStringf replacee("@[%s]", macroname.GetChars()); - FName lookupname(lookupstr.GetChars(), true); + FName lookupname(macroname.GetChars(), true); auto replace = allMacros.CheckKey(lookupname); for (int i = 0; i < 4; i++) { diff --git a/src/common/platform/win32/i_dijoy.cpp b/src/common/platform/win32/i_dijoy.cpp index c22c5492b..a81fa1a26 100644 --- a/src/common/platform/win32/i_dijoy.cpp +++ b/src/common/platform/win32/i_dijoy.cpp @@ -898,7 +898,7 @@ const char *FDInputJoystick::GetAxisName(int axis) { if (unsigned(axis) < Axes.Size()) { - return Axes[axis].Name; + return Axes[axis].Name.GetChars(); } return "Invalid"; } diff --git a/src/common/platform/win32/i_mainwindow.cpp b/src/common/platform/win32/i_mainwindow.cpp index 4c4f61568..64ddaa5da 100644 --- a/src/common/platform/win32/i_mainwindow.cpp +++ b/src/common/platform/win32/i_mainwindow.cpp @@ -738,7 +738,7 @@ void MainWindow::FlushBufferedConsoleStuff() { for (unsigned i = 0; i < bufferedConsoleStuff.Size(); i++) { - DoPrintStr(bufferedConsoleStuff[i]); + DoPrintStr(bufferedConsoleStuff[i].GetChars()); } bufferedConsoleStuff.Clear(); } diff --git a/src/common/platform/win32/i_rawps2.cpp b/src/common/platform/win32/i_rawps2.cpp index 834431580..d406d61ea 100644 --- a/src/common/platform/win32/i_rawps2.cpp +++ b/src/common/platform/win32/i_rawps2.cpp @@ -1242,8 +1242,8 @@ int FRawPS2Manager::DeviceSort(const void *a, const void *b) if (lex == 0) { // Skip device part of the ID and sort the connection part - const char *ca = strchr(ha->DeviceID, '#'); - const char *cb = strchr(hb->DeviceID, '#'); + const char *ca = strchr(ha->DeviceID.GetChars(), '#'); + const char *cb = strchr(hb->DeviceID.GetChars(), '#'); const char *ea, *eb; // The last bit looks like a controller number. Strip it out to be safe // if this is a multi-controller adapter. diff --git a/src/common/platform/win32/i_specialpaths.cpp b/src/common/platform/win32/i_specialpaths.cpp index 3bfee00ea..62e1766d4 100644 --- a/src/common/platform/win32/i_specialpaths.cpp +++ b/src/common/platform/win32/i_specialpaths.cpp @@ -91,7 +91,7 @@ bool IsPortable() // A portable INI means that this storage location should also be portable if the file can be written to. FStringf path("%s" GAMENAMELOWERCASE "_portable.ini", progdir.GetChars()); - if (FileExists(path)) + if (FileExists(path.GetChars())) { file = CreateFile(path.WideString().c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -145,7 +145,7 @@ FString M_GetAppDataPath(bool create) path += "/" GAMENAMELOWERCASE; if (create) { - CreatePath(path); + CreatePath(path.GetChars()); } return path; } @@ -167,7 +167,7 @@ FString M_GetCachePath(bool create) path += "/zdoom/cache"; if (create) { - CreatePath(path); + CreatePath(path.GetChars()); } return path; } @@ -217,7 +217,7 @@ FString M_GetOldConfigPath(int& type) } path << GAMENAMELOWERCASE "-" << FString(uname) << ".ini"; type = 0; - if (FileExists(path)) + if (FileExists(path.GetChars())) return path; } @@ -226,7 +226,7 @@ FString M_GetOldConfigPath(int& type) path = GetKnownFolder(CSIDL_APPDATA, FOLDERID_RoamingAppData, true); path += "/" GAME_DIR "/" GAMENAMELOWERCASE ".ini"; type = 1; - if (FileExists(path)) + if (FileExists(path.GetChars())) return path; return ""; @@ -283,9 +283,9 @@ FString M_GetConfigPath(bool for_reading) // Construct a user-specific config name FString path = GetKnownFolder(CSIDL_APPDATA, FOLDERID_Documents, true); path += "/My Games/" GAME_DIR; - CreatePath(path); + CreatePath(path.GetChars()); path += "/" GAMENAMELOWERCASE ".ini"; - if (!for_reading || FileExists(path)) + if (!for_reading || FileExists(path.GetChars())) return path; // No config was found in the accepted locations. @@ -305,7 +305,7 @@ FString M_GetConfigPath(bool for_reading) isportable = true; } } - bool res = MoveFileExW(WideString(oldpath).c_str(), WideString(path).c_str(), MOVEFILE_COPY_ALLOWED); + bool res = MoveFileExW(WideString(oldpath.GetChars()).c_str(), WideString(path.GetChars()).c_str(), MOVEFILE_COPY_ALLOWED); if (res) return path; else return oldpath; // if we cannot move, just use the config where it was. It won't be written back, though and never be used again if a new one gets saved. } @@ -314,7 +314,7 @@ FString M_GetConfigPath(bool for_reading) // If we are reading the config file, check if it exists. If not, fallback to base version. if (for_reading) { - if (!FileExists(path)) + if (!FileExists(path.GetChars())) { path = progdir; path << GAMENAMELOWERCASE ".ini"; @@ -351,7 +351,7 @@ FString M_GetScreenshotsPath() path = GetKnownFolder(CSIDL_MYPICTURES, FOLDERID_Pictures, true); path << "/Screenshots/" GAMENAME "/"; } - CreatePath(path); + CreatePath(path.GetChars()); return path; } @@ -402,7 +402,7 @@ FString M_GetDocumentsPath() // I assume since this isn't a standard folder, it doesn't have a localized name either. path = GetKnownFolder(CSIDL_PERSONAL, FOLDERID_Documents, true); path << "/My Games/" GAMENAME "/"; - CreatePath(path); + CreatePath(path.GetChars()); } return path; } diff --git a/src/common/platform/win32/i_system.cpp b/src/common/platform/win32/i_system.cpp index 0a9843e94..6da33867f 100644 --- a/src/common/platform/win32/i_system.cpp +++ b/src/common/platform/win32/i_system.cpp @@ -409,9 +409,9 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa ctrl = GetDlgItem(hDlg, IDC_IWADLIST); for (i = 0; i < NumWads; i++) { - const char *filepart = strrchr(WadList[i].Path, '/'); + const char *filepart = strrchr(WadList[i].Path.GetChars(), '/'); if (filepart == NULL) - filepart = WadList[i].Path; + filepart = WadList[i].Path.GetChars(); else filepart++; diff --git a/src/common/rendering/gles/gles_shader.cpp b/src/common/rendering/gles/gles_shader.cpp index 4fffa8b90..f037e3e4a 100644 --- a/src/common/rendering/gles/gles_shader.cpp +++ b/src/common/rendering/gles/gles_shader.cpp @@ -119,7 +119,7 @@ static FString CalcProgramBinaryChecksum(const FString &vertex, const FString &f static FString CreateProgramCacheName(bool create) { FString path = M_GetCachePath(create); - if (create) CreatePath(path); + if (create) CreatePath(path.GetChars()); path << "/shadercache.zdsc"; return path; } @@ -135,7 +135,7 @@ static void LoadShaders() { FString path = CreateProgramCacheName(false); FileReader fr; - if (!fr.OpenFile(path)) + if (!fr.OpenFile(path.GetChars())) I_Error("Could not open shader file"); char magic[4]; @@ -176,7 +176,7 @@ static void LoadShaders() static void SaveShaders() { FString path = CreateProgramCacheName(true); - std::unique_ptr fw(FileWriter::Open(path)); + std::unique_ptr fw(FileWriter::Open(path.GetChars())); if (fw) { uint32_t count = (uint32_t)ShaderCache.size(); @@ -234,7 +234,7 @@ bool FShader::Configure(const char* name, const char* vert_prog_lump, const char void FShader::LoadVariant() { //mDefinesBase - Load(mName.GetChars(), mVertProg, mFragProg, mFragProg2, mLightProg, mDefinesBase); + Load(mName.GetChars(), mVertProg.GetChars(), mFragProg.GetChars(), mFragProg2.GetChars(), mLightProg.GetChars(), mDefinesBase.GetChars()); } bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * frag_prog_lump_, const char * proc_prog_lump_, const char * light_fragprog_, const char * defines) @@ -381,11 +381,11 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * i_data += "#define NPOT_EMULATION\nuniform vec2 uNpotEmulation;\n"; #endif - int vp_lump = fileSystem.CheckNumForFullName(vert_prog_lump, 0); + int vp_lump = fileSystem.CheckNumForFullName(vert_prog_lump.GetChars(), 0); if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump.GetChars()); auto vp_data = fileSystem.ReadFile(vp_lump); - int fp_lump = fileSystem.CheckNumForFullName(frag_prog_lump, 0); + int fp_lump = fileSystem.CheckNumForFullName(frag_prog_lump.GetChars(), 0); if (fp_lump == -1) I_Error("Unable to load '%s'", frag_prog_lump.GetChars()); auto fp_data = fileSystem.ReadFile(fp_lump); @@ -418,9 +418,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * { fp_comb << "#line 1\n"; - if (*proc_prog_lump != '#') + if (proc_prog_lump[0] != '#') { - int pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump); + int pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump.GetChars()); if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump.GetChars()); auto ppf = fileSystem.ReadFile(pp_lump); FString pp_data = GetStringFromLump(pp_lump); @@ -485,7 +485,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * if (light_fragprog.Len()) { - int pp_lump = fileSystem.CheckNumForFullName(light_fragprog, 0); + int pp_lump = fileSystem.CheckNumForFullName(light_fragprog.GetChars(), 0); if (pp_lump == -1) I_Error("Unable to load '%s'", light_fragprog.GetChars()); fp_comb << GetStringFromLump(pp_lump) << "\n"; } @@ -722,8 +722,7 @@ bool FShader::Bind(ShaderFlavourData& flavour) //Printf("Shader: %s, %08x %s", mFragProg2.GetChars(), tag, variantConfig.GetChars()); - Load(mName.GetChars(), mVertProg, mFragProg, mFragProg2, mLightProg, mDefinesBase + variantConfig); - + Load(mName.GetChars(), mVertProg.GetChars(), mFragProg.GetChars(), mFragProg2.GetChars(), mLightProg.GetChars(), (mDefinesBase + variantConfig).GetChars()); variants.insert(std::make_pair(tag, cur)); } else diff --git a/src/common/rendering/gles/gles_shaderprogram.cpp b/src/common/rendering/gles/gles_shaderprogram.cpp index 289008c21..a6f0453c2 100644 --- a/src/common/rendering/gles/gles_shaderprogram.cpp +++ b/src/common/rendering/gles/gles_shaderprogram.cpp @@ -165,7 +165,7 @@ void FShaderProgram::Link(const char *name) glUseProgram(mProgram); for (auto &uni : samplerstobind) { - auto index = glGetUniformLocation(mProgram, uni.first); + auto index = glGetUniformLocation(mProgram, uni.first.GetChars()); if (index >= 0) { glUniform1i(index, uni.second); @@ -266,8 +266,8 @@ void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program FString prolog = Uniforms.CreateDeclaration("Uniforms", PresentUniforms::Desc()); mShader.reset(new FShaderProgram()); - mShader->Compile(FShaderProgram::Vertex, "shaders_gles/pp/screenquad.vp", prolog, 330); - mShader->Compile(FShaderProgram::Fragment, vtx_shader_name, prolog, 330); + mShader->Compile(FShaderProgram::Vertex, "shaders_gles/pp/screenquad.vp", prolog.GetChars(), 330); + mShader->Compile(FShaderProgram::Fragment, vtx_shader_name, prolog.GetChars(), 330); mShader->Link(program_name); mShader->Bind(); Uniforms.Init(); diff --git a/src/common/rendering/vulkan/renderer/vk_renderpass.cpp b/src/common/rendering/vulkan/renderer/vk_renderpass.cpp index e445723d0..5917afd11 100644 --- a/src/common/rendering/vulkan/renderer/vk_renderpass.cpp +++ b/src/common/rendering/vulkan/renderer/vk_renderpass.cpp @@ -40,7 +40,7 @@ VkRenderPassManager::VkRenderPassManager(VulkanRenderDevice* fb) : fb(fb) { FString path = M_GetCachePath(true); - CreatePath(path); + CreatePath(path.GetChars()); CacheFilename = path + "/pipelinecache.zdpc"; PipelineCacheBuilder builder; @@ -49,7 +49,7 @@ VkRenderPassManager::VkRenderPassManager(VulkanRenderDevice* fb) : fb(fb) try { FileReader fr; - if (fr.OpenFile(CacheFilename)) + if (fr.OpenFile(CacheFilename.GetChars())) { std::vector data; data.resize(fr.GetLength()); @@ -71,7 +71,7 @@ VkRenderPassManager::~VkRenderPassManager() try { auto data = PipelineCache->GetCacheData(); - std::unique_ptr fw(FileWriter::Open(CacheFilename)); + std::unique_ptr fw(FileWriter::Open(CacheFilename.GetChars())); if (fw) fw->Write(data.data(), data.size()); } diff --git a/src/common/rendering/vulkan/shaders/vk_ppshader.cpp b/src/common/rendering/vulkan/shaders/vk_ppshader.cpp index 3aa6861eb..dc4ace0f9 100644 --- a/src/common/rendering/vulkan/shaders/vk_ppshader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_ppshader.cpp @@ -67,7 +67,7 @@ void VkPPShader::Reset() FString VkPPShader::LoadShaderCode(const FString &lumpName, const FString &defines, int version) { - int lump = fileSystem.CheckNumForFullName(lumpName); + int lump = fileSystem.CheckNumForFullName(lumpName.GetChars()); if (lump == -1) I_FatalError("Unable to load '%s'", lumpName.GetChars()); auto sp = fileSystem.ReadFile(lump); FString code = GetStringFromLump(lump); diff --git a/src/common/rendering/vulkan/shaders/vk_shader.cpp b/src/common/rendering/vulkan/shaders/vk_shader.cpp index 0140aa6cb..227b8cca6 100644 --- a/src/common/rendering/vulkan/shaders/vk_shader.cpp +++ b/src/common/rendering/vulkan/shaders/vk_shader.cpp @@ -73,12 +73,12 @@ bool VkShaderManager::CompileNextShader() { // user shaders - const FString& name = ExtractFileBase(usershaders[i].shader); + const FString& name = ExtractFileBase(usershaders[i].shader.GetChars()); FString defines = defaultshaders[usershaders[i].shaderType].Defines + usershaders[i].defines; VkShaderProgram prog; - prog.vert = LoadVertShader(name, mainvp, defines); - prog.frag = LoadFragShader(name, mainfp, usershaders[i].shader, defaultshaders[usershaders[i].shaderType].lightfunc, defines, true, compilePass == GBUFFER_PASS); + prog.vert = LoadVertShader(name, mainvp, defines.GetChars()); + prog.frag = LoadFragShader(name, mainfp, usershaders[i].shader.GetChars(), defaultshaders[usershaders[i].shaderType].lightfunc, defines.GetChars(), true, compilePass == GBUFFER_PASS); mMaterialShaders[compilePass].push_back(std::move(prog)); compileIndex++; diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 5bf359e32..08668dd51 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -1394,7 +1394,7 @@ FxExpression *FxColorCast::Resolve(FCompileContext &ctx) } else { - FxExpression *x = new FxConstant(V_GetColor(constval.GetString(), &ScriptPosition), ScriptPosition); + FxExpression *x = new FxConstant(V_GetColor(constval.GetString().GetChars(), &ScriptPosition), ScriptPosition); delete this; return x; } @@ -1474,7 +1474,7 @@ FxExpression *FxSoundCast::Resolve(FCompileContext &ctx) if (basex->isConstant()) { ExpVal constval = static_cast(basex)->GetValue(); - FxExpression *x = new FxConstant(S_FindSound(constval.GetString()), ScriptPosition); + FxExpression *x = new FxConstant(S_FindSound(constval.GetString().GetChars()), ScriptPosition); delete this; return x; } @@ -1552,7 +1552,7 @@ FxExpression *FxFontCast::Resolve(FCompileContext &ctx) else if ((basex->ValueType == TypeString || basex->ValueType == TypeName) && basex->isConstant()) { ExpVal constval = static_cast(basex)->GetValue(); - FFont *font = V_GetFont(constval.GetString()); + FFont *font = V_GetFont(constval.GetString().GetChars()); // Font must exist. Most internal functions working with fonts do not like null pointers. // If checking is needed scripts will have to call Font.GetFont themselves. if (font == nullptr) diff --git a/src/common/utility/cmdlib.cpp b/src/common/utility/cmdlib.cpp index 28cba8fcd..0086d1cd8 100644 --- a/src/common/utility/cmdlib.cpp +++ b/src/common/utility/cmdlib.cpp @@ -528,7 +528,7 @@ void CreatePath(const char *fn) { FString name(fn); name += '/'; - DoCreatePath(name); + DoCreatePath(name.GetChars()); } else { @@ -805,13 +805,13 @@ FString ExpandEnvVars(const char *searchpathstring) if (length != 0) { FString varname = FString(dollar + 1, length); - if (stricmp(varname, "progdir") == 0) + if (varname.Compare("progdir") == 0) { out += progdir; } else { - char *varvalue = getenv(varname); + char *varvalue = getenv(varname.GetChars()); if ( (varvalue != NULL) && (strlen(varvalue) != 0) ) { out += varvalue; diff --git a/src/common/utility/configfile.cpp b/src/common/utility/configfile.cpp index 52bb4bcae..cdd4e9519 100644 --- a/src/common/utility/configfile.cpp +++ b/src/common/utility/configfile.cpp @@ -85,7 +85,7 @@ FConfigFile::FConfigFile (const FConfigFile &other) Sections = CurrentSection = NULL; LastSectionPtr = &Sections; CurrentEntry = NULL; - ChangePathName (other.PathName); + ChangePathName (other.PathName.GetChars()); *this = other; OkayToWrite = other.OkayToWrite; FileExisted = other.FileExisted; @@ -134,7 +134,7 @@ FConfigFile &FConfigFile::operator = (const FConfigFile &other) while (fromsection != NULL) { fromentry = fromsection->RootEntry; - tosection = NewConfigSection (fromsection->SectionName); + tosection = NewConfigSection (fromsection->SectionName.GetChars()); while (fromentry != NULL) { NewConfigEntry (tosection, fromentry->Key, fromentry->Value); @@ -602,7 +602,7 @@ void FConfigFile::LoadConfigFile () bool succ; FileExisted = false; - if (!file.OpenFile (PathName)) + if (!file.OpenFile (PathName.GetChars())) { return; } @@ -739,7 +739,7 @@ FConfigFile::FConfigEntry *FConfigFile::ReadMultiLineValue(FileReader *file, FCo // Append this line to the value. value << readbuf; } - return NewConfigEntry(section, key, value); + return NewConfigEntry(section, key, value.GetChars()); } //==================================================================== @@ -787,7 +787,7 @@ bool FConfigFile::WriteConfigFile () const return true; } - FileWriter *file = FileWriter::Open (PathName); + FileWriter *file = FileWriter::Open (PathName.GetChars()); FConfigSection *section; FConfigEntry *entry; diff --git a/src/common/utility/findfile.cpp b/src/common/utility/findfile.cpp index e2c2ee707..86d7098ec 100644 --- a/src/common/utility/findfile.cpp +++ b/src/common/utility/findfile.cpp @@ -146,7 +146,7 @@ void D_AddWildFile(std::vector& wadfiles, const char* value, const auto path = ExtractFilePath(value); auto name = ExtractFileBase(value, true); if (path.IsEmpty()) path = "."; - if (FileSys::ScanDirectory(list, path, name, true)) + if (FileSys::ScanDirectory(list, path.GetChars(), name.GetChars(), true)) { for(auto& entry : list) { @@ -178,7 +178,7 @@ void D_AddConfigFiles(std::vector& wadfiles, const char* section, c { // D_AddWildFile resets config's position, so remember it config->GetPosition(pos); - D_AddWildFile(wadfiles, ExpandEnvVars(value), extension, config); + D_AddWildFile(wadfiles, ExpandEnvVars(value).GetChars(), extension, config); // Reset config's position to get next wad config->SetPosition(pos); } @@ -230,7 +230,7 @@ const char* BaseFileSearch(const char* file, const char* ext, bool lookfirstinpr if (lookfirstinprogdir) { BFSwad.Format("%s%s%s", progdir.GetChars(), progdir.Back() == '/' ? "" : "/", file); - if (DirEntryExists(BFSwad)) + if (DirEntryExists(BFSwad.GetChars())) { return BFSwad.GetChars(); } @@ -257,7 +257,7 @@ const char* BaseFileSearch(const char* file, const char* ext, bool lookfirstinpr if (dir.IsNotEmpty()) { BFSwad.Format("%s%s%s", dir.GetChars(), dir.Back() == '/' ? "" : "/", file); - if (DirEntryExists(BFSwad)) + if (DirEntryExists(BFSwad.GetChars())) { return BFSwad.GetChars(); } @@ -271,7 +271,7 @@ const char* BaseFileSearch(const char* file, const char* ext, bool lookfirstinpr { FString tmp = file; DefaultExtension(tmp, ext); - return BaseFileSearch(tmp, nullptr, lookfirstinprogdir, config); + return BaseFileSearch(tmp.GetChars(), nullptr, lookfirstinprogdir, config); } return nullptr; } diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index 1ced34702..acad5b35a 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -173,7 +173,7 @@ bool CT_Responder (event_t *ev) else if (ev->data1 == 'V' && (ev->data3 & GKM_CTRL)) #endif // __APPLE__ { - CT_PasteChat(I_GetFromClipboard(false)); + CT_PasteChat(I_GetFromClipboard(false).GetChars()); } } else if (ev->subtype == EV_GUI_Char) @@ -291,7 +291,7 @@ void CT_Drawer (void) DrawText(drawer, displayfont, CR_GREEN, 0, y, prompt.GetChars(), DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE); - DrawText(drawer, displayfont, CR_GREY, promptwidth, y, printstr, + DrawText(drawer, displayfont, CR_GREY, promptwidth, y, printstr.GetChars(), DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE); } } diff --git a/src/gamedata/a_keys.cpp b/src/gamedata/a_keys.cpp index e3defc739..e61880dc2 100644 --- a/src/gamedata/a_keys.cpp +++ b/src/gamedata/a_keys.cpp @@ -487,7 +487,7 @@ int P_CheckKeys (AActor *owner, int keynum, bool remote, bool quiet) { if (lock->check(owner)) return true; if (quiet) return false; - failtext = remote? lock->RemoteMsg : lock->Message; + failtext = remote? lock->RemoteMsg.GetChars() : lock->Message.GetChars(); failsound = &lock->locksound[0]; numfailsounds = lock->locksound.Size(); } diff --git a/src/gamedata/a_weapons.cpp b/src/gamedata/a_weapons.cpp index fa527d770..5aa147386 100644 --- a/src/gamedata/a_weapons.cpp +++ b/src/gamedata/a_weapons.cpp @@ -408,9 +408,9 @@ void FWeaponSlots::LocalSetup(PClassActor *type) { FString sectionclass(WeaponSection); sectionclass << '.' << type->TypeName.GetChars(); - if (RestoreSlots(GameConfig, sectionclass) == 0) + if (RestoreSlots(GameConfig, sectionclass.GetChars()) == 0) { - RestoreSlots(GameConfig, WeaponSection); + RestoreSlots(GameConfig, WeaponSection.GetChars()); } } else @@ -504,7 +504,7 @@ int FWeaponSlots::RestoreSlots(FConfigFile *config, const char *section) int slotsread = 0; section_name += ".Weapons"; - if (!config->SetSection(section_name)) + if (!config->SetSection(section_name.GetChars())) { return 0; } @@ -742,7 +742,7 @@ void P_PlaybackKeyConfWeapons(FWeaponSlots *slots) PlayingKeyConf = slots; for (unsigned int i = 0; i < KeyConfWeapons.Size(); ++i) { - AddCommandString(KeyConfWeapons[i]); + AddCommandString(KeyConfWeapons[i].GetChars()); } PlayingKeyConf = nullptr; } diff --git a/src/gamedata/textures/animations.cpp b/src/gamedata/textures/animations.cpp index 202b5bdb6..c2f903e30 100644 --- a/src/gamedata/textures/animations.cpp +++ b/src/gamedata/textures/animations.cpp @@ -723,9 +723,9 @@ void FTextureAnimator::ParseCameraTexture(FScanner &sc) width = sc.Number; sc.MustGetNumber (); height = sc.Number; - FTextureID picnum = TexMan.CheckForTexture (picname, ETextureType::Flat, texflags); + FTextureID picnum = TexMan.CheckForTexture (picname.GetChars(), ETextureType::Flat, texflags); auto canvas = new FCanvasTexture(width, height); - FGameTexture *viewer = MakeGameTexture(canvas, picname, ETextureType::Wall); + FGameTexture *viewer = MakeGameTexture(canvas, picname.GetChars(), ETextureType::Wall); if (picnum.Exists()) { auto oldtex = TexMan.GameTexture(picnum); @@ -805,7 +805,7 @@ void FTextureAnimator::FixAnimations () bool noremap = false; const char *name; - name = TexMan.GameTexture(anim->BasePic)->GetName(); + name = TexMan.GameTexture(anim->BasePic)->GetName().GetChars(); nodecals = TexMan.GameTexture(anim->BasePic)->allowNoDecals(); for (j = 0; j < anim->NumFrames; ++j) { diff --git a/src/gamedata/textures/buildloader.cpp b/src/gamedata/textures/buildloader.cpp index 2f076e29c..a3955d6d8 100644 --- a/src/gamedata/textures/buildloader.cpp +++ b/src/gamedata/textures/buildloader.cpp @@ -158,7 +158,7 @@ void AddTiles(const FString& pathprefix, const void* tiles, FRemapTable *remap) if (width <= 0 || height <= 0) continue; FStringf name("%sBTIL%04d", pathprefix.GetChars(), i); - auto tex = MakeGameTexture(new FImageTexture(new FBuildTexture(pathprefix, i, tiledata, remap, width, height, xoffs, yoffs)), name, ETextureType::Override); + auto tex = MakeGameTexture(new FImageTexture(new FBuildTexture(pathprefix, i, tiledata, remap, width, height, xoffs, yoffs)), name.GetChars(), ETextureType::Override); texnum = TexMan.AddGameTexture(tex); tiledata += size; @@ -276,7 +276,7 @@ void InitBuildTiles() // only read from the same source as the palette. // The entire format here is just too volatile to allow liberal mixing. // An .ART set must be treated as one unit. - lumpnum = fileSystem.CheckNumForFullName(artpath, fileSystem.GetFileContainer(i)); + lumpnum = fileSystem.CheckNumForFullName(artpath.GetChars(), fileSystem.GetFileContainer(i)); if (lumpnum < 0) { break; diff --git a/src/playsim/bots/b_game.cpp b/src/playsim/bots/b_game.cpp index a43c83ce0..9cdde72ab 100644 --- a/src/playsim/bots/b_game.cpp +++ b/src/playsim/bots/b_game.cpp @@ -142,7 +142,7 @@ void FCajunMaster::Main(FLevelLocals *Level) { if (t_join == ((wanted_botnum - botnum) * SPAWN_DELAY)) { - if (!SpawnBot (getspawned[spawn_tries])) + if (!SpawnBot (getspawned[spawn_tries].GetChars())) wanted_botnum--; spawn_tries++; } @@ -309,7 +309,7 @@ bool FCajunMaster::SpawnBot (const char *name, int color) { // Keep the bot on the same team when switching levels concat.AppendFormat("\\team\\%d\n", thebot->lastteam); } - Net_WriteString (concat); + Net_WriteString (concat.GetChars()); } Net_WriteByte(thebot->skill.aiming); Net_WriteByte(thebot->skill.perfection); @@ -525,7 +525,7 @@ bool FCajunMaster::LoadBots () DPrintf (DMSG_ERROR, "No " BOTFILENAME ", so no bots\n"); return false; } - if (!sc.OpenFile(tmp)) + if (!sc.OpenFile(tmp.GetChars())) { Printf("Unable to open %s. So no bots\n", tmp.GetChars()); return false; diff --git a/src/rendering/swrenderer/r_swcolormaps.cpp b/src/rendering/swrenderer/r_swcolormaps.cpp index b303712eb..1ff95c8b3 100644 --- a/src/rendering/swrenderer/r_swcolormaps.cpp +++ b/src/rendering/swrenderer/r_swcolormaps.cpp @@ -515,7 +515,7 @@ CCMD (testfade) { if ( !(colorstring = V_GetColorStringByName (argv[1])).IsEmpty() ) { - color = V_GetColorFromString (colorstring); + color = V_GetColorFromString (colorstring.GetChars()); } else { @@ -549,7 +549,7 @@ CCMD (testcolor) { if ( !(colorstring = V_GetColorStringByName (argv[1])).IsEmpty() ) { - color = V_GetColorFromString (colorstring); + color = V_GetColorFromString (colorstring.GetChars()); } else { diff --git a/src/rendering/swrenderer/r_swrenderer.cpp b/src/rendering/swrenderer/r_swrenderer.cpp index 4c2414db5..b449baef4 100644 --- a/src/rendering/swrenderer/r_swrenderer.cpp +++ b/src/rendering/swrenderer/r_swrenderer.cpp @@ -273,7 +273,7 @@ void FSoftwareRenderer::SetColormap(FLevelLocals *Level) NormalLight.ChangeFade(Level->fadeto); if (Level->fadeto == 0) { - SetDefaultColormap(Level->info->FadeTable); + SetDefaultColormap(Level->info->FadeTable.GetChars()); } } diff --git a/src/scripting/backend/codegen_doom.cpp b/src/scripting/backend/codegen_doom.cpp index 9f2b37e84..f93422e30 100644 --- a/src/scripting/backend/codegen_doom.cpp +++ b/src/scripting/backend/codegen_doom.cpp @@ -92,7 +92,7 @@ static FxExpression *CustomTypeCast(FxTypeCast *func, FCompileContext &ctx) delete func; return nullptr; } - FxExpression *x = new FxMultiNameState(s, basex->ScriptPosition); + FxExpression *x = new FxMultiNameState(s.GetChars(), basex->ScriptPosition); x = x->Resolve(ctx); basex = nullptr; delete func; @@ -811,10 +811,10 @@ FxMultiNameState::FxMultiNameState(const char *_statestring, const FScriptPositi if (scopeindex >= 0) { - scopename = FName(statestring, scopeindex, false); + scopename = FName(statestring.GetChars(), scopeindex, false); statestring = statestring.Right((ptrdiff_t)statestring.Len() - scopeindex - 2); } - names = MakeStateNameList(statestring); + names = MakeStateNameList(statestring.GetChars()); names.Insert(0, scopename); scope = checkclass; } diff --git a/src/win32/i_steam.cpp b/src/win32/i_steam.cpp index 5b62ae435..b066b9572 100644 --- a/src/win32/i_steam.cpp +++ b/src/win32/i_steam.cpp @@ -354,7 +354,7 @@ TArray I_GetSteamPath() return result; } - TArray paths = ParseSteamRegistry(steamPath + "/config/config.vdf"); + TArray paths = ParseSteamRegistry((steamPath + "/config/config.vdf").GetChars()); for(FString &path : paths) { From 48ba63c0226640d886a7f1c408e59ba06746fa5f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 3 Oct 2023 15:55:08 +0200 Subject: [PATCH 170/223] added even more explicit GetChars() calls. --- src/common/2d/v_2ddrawer.cpp | 2 +- src/common/audio/music/i_soundfont.cpp | 4 +- src/common/audio/sound/s_soundinternal.h | 5 ++ src/common/console/c_console.cpp | 10 +-- src/common/console/c_cvars.cpp | 16 ++--- src/common/console/c_dispatch.cpp | 30 ++++----- src/common/console/c_enginecmds.cpp | 6 +- src/common/engine/date.cpp | 2 +- src/common/fonts/font.cpp | 6 +- src/common/fonts/v_font.cpp | 6 +- src/common/models/model.cpp | 10 +-- src/common/platform/win32/i_specialpaths.cpp | 10 +-- .../postprocessing/hw_postprocess.cpp | 2 +- src/common/scripting/backend/vmbuilder.cpp | 4 +- src/common/scripting/frontend/zcc_compile.cpp | 2 +- src/common/scripting/frontend/zcc_parser.cpp | 4 +- src/common/scripting/interface/vmnatives.cpp | 26 ++++---- src/common/scripting/vm/vmexec.h | 2 +- src/common/utility/cmdlib.h | 4 ++ src/console/c_cmds.cpp | 38 +++++------ src/d_defcvars.cpp | 12 ++-- src/d_defcvars.h | 2 +- src/d_iwad.cpp | 26 ++++---- src/d_main.cpp | 65 +++++++++---------- src/d_net.cpp | 8 +-- src/g_game.cpp | 2 +- src/gamedata/d_dehacked.cpp | 20 +++--- src/gamedata/decallib.cpp | 12 ++-- src/gamedata/umapinfo.cpp | 4 +- src/maploader/maploader.h | 4 ++ src/maploader/udmf.cpp | 2 +- src/menu/doommenu.cpp | 6 +- src/playsim/fragglescript/t_func.cpp | 8 +-- src/playsim/fragglescript/t_load.cpp | 2 +- src/playsim/fragglescript/t_oper.cpp | 2 +- src/playsim/fragglescript/t_prepro.cpp | 2 +- src/playsim/fragglescript/t_script.h | 2 +- src/playsim/fragglescript/t_variable.cpp | 10 +-- src/scripting/vmthunks.cpp | 16 ++--- src/scripting/zscript/zcc_compile_doom.cpp | 8 +-- src/sound/s_doomsound.h | 4 ++ src/wi_stuff.cpp | 38 +++++------ 42 files changed, 230 insertions(+), 214 deletions(-) diff --git a/src/common/2d/v_2ddrawer.cpp b/src/common/2d/v_2ddrawer.cpp index d6cf06af0..e12c5a61c 100644 --- a/src/common/2d/v_2ddrawer.cpp +++ b/src/common/2d/v_2ddrawer.cpp @@ -1249,7 +1249,7 @@ public: FCanvas* GetTextureCanvas(const FString& texturename) { - FTextureID textureid = TexMan.CheckForTexture(texturename, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); + FTextureID textureid = TexMan.CheckForTexture(texturename.GetChars(), ETextureType::Wall, FTextureManager::TEXMAN_Overridable); if (textureid.isValid()) { // Only proceed if the texture is a canvas texture. diff --git a/src/common/audio/music/i_soundfont.cpp b/src/common/audio/music/i_soundfont.cpp index bac39d3a1..dd610e0b4 100644 --- a/src/common/audio/music/i_soundfont.cpp +++ b/src/common/audio/music/i_soundfont.cpp @@ -316,7 +316,7 @@ FileReader FLumpPatchSetReader::OpenFile(const char *name) FString path; if (IsAbsPath(name)) return FileReader(); // no absolute paths in the lump directory. path = mBasePath + name; - auto index = fileSystem.CheckNumForFullName(path); + auto index = fileSystem.CheckNumForFullName(path.GetChars()); if (index < 0) return FileReader(); return fileSystem.ReopenFileReader(index); } @@ -426,7 +426,7 @@ void FSoundFontManager::CollectSoundfonts() if (soundfonts.Size() == 0) { - ProcessOneFile(NicePath("$PROGDIR/soundfonts/" GAMENAMELOWERCASE ".sf2")); + ProcessOneFile(NicePath("$PROGDIR/soundfonts/" GAMENAMELOWERCASE ".sf2").GetChars()); } } diff --git a/src/common/audio/sound/s_soundinternal.h b/src/common/audio/sound/s_soundinternal.h index d8c07742c..cb38386a3 100644 --- a/src/common/audio/sound/s_soundinternal.h +++ b/src/common/audio/sound/s_soundinternal.h @@ -426,4 +426,9 @@ inline FSoundID S_FindSound(const char* name) return soundEngine->FindSound(name); } +inline FSoundID S_FindSound(const FString& name) +{ + return soundEngine->FindSound(name.GetChars()); +} + int SoundEnabled(); diff --git a/src/common/console/c_console.cpp b/src/common/console/c_console.cpp index c909592a5..44c8ffacf 100644 --- a/src/common/console/c_console.cpp +++ b/src/common/console/c_console.cpp @@ -295,7 +295,7 @@ void C_DeinitConsole () while (cmd != NULL) { GameAtExit *next = cmd->Next; - AddCommandString (cmd->Command); + AddCommandString (cmd->Command.GetChars()); delete cmd; cmd = next; } @@ -661,11 +661,11 @@ void C_DrawConsole () { if (textScale == 1) { - DrawText(twod, CurrentConsoleFont, CR_TAN, LEFTMARGIN, offset + lines * CurrentConsoleFont->GetHeight(), p->Text, TAG_DONE); + DrawText(twod, CurrentConsoleFont, CR_TAN, LEFTMARGIN, offset + lines * CurrentConsoleFont->GetHeight(), p->Text.GetChars(), TAG_DONE); } else { - DrawText(twod, CurrentConsoleFont, CR_TAN, LEFTMARGIN, offset + lines * CurrentConsoleFont->GetHeight(), p->Text, + DrawText(twod, CurrentConsoleFont, CR_TAN, LEFTMARGIN, offset + lines * CurrentConsoleFont->GetHeight(), p->Text.GetChars(), DTA_VirtualWidth, twod->GetWidth() / textScale, DTA_VirtualHeight, twod->GetHeight() / textScale, DTA_KeepRatio, true, TAG_DONE); @@ -1012,7 +1012,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) } HistPos = NULL; buffer.SetString(""); - AddCommandString(bufferText); + AddCommandString(bufferText.GetChars()); TabbedLast = false; TabbedList = false; break; @@ -1060,7 +1060,7 @@ static bool C_HandleKey (event_t *ev, FCommandBuffer &buffer) { // copy to clipboard if (buffer.TextLength() > 0) { - I_PutInClipboard(buffer.GetText()); + I_PutInClipboard(buffer.GetText().GetChars()); } } else diff --git a/src/common/console/c_cvars.cpp b/src/common/console/c_cvars.cpp index 0f92791b2..e8d94acea 100644 --- a/src/common/console/c_cvars.cpp +++ b/src/common/console/c_cvars.cpp @@ -209,12 +209,12 @@ FBaseCVar::~FBaseCVar () { FBaseCVar *var, *prev; - var = FindCVar (VarName, &prev); + var = FindCVar (VarName.GetChars(), &prev); if (var == this) { cvarMap.Remove(var->VarName); - C_RemoveTabCommand(VarName); + C_RemoveTabCommand(VarName.GetChars()); } } } @@ -864,27 +864,27 @@ ECVarType FStringCVar::GetRealType () const UCVarValue FStringCVar::GetGenericRep (ECVarType type) const { - return FromString (mValue, type); + return FromString (mValue.GetChars(), type); } UCVarValue FStringCVar::GetFavoriteRep (ECVarType *type) const { UCVarValue ret; *type = CVAR_String; - ret.String = mValue; + ret.String = mValue.GetChars(); return ret; } UCVarValue FStringCVar::GetGenericRepDefault (ECVarType type) const { - return FromString (mDefaultValue, type); + return FromString (mDefaultValue.GetChars(), type); } UCVarValue FStringCVar::GetFavoriteRepDefault (ECVarType *type) const { UCVarValue ret; *type = CVAR_String; - ret.String = mDefaultValue; + ret.String = mDefaultValue.GetChars(); return ret; } @@ -969,7 +969,7 @@ int FColorCVar::ToInt2 (UCVarValue value, ECVarType type) if (string.IsNotEmpty()) { - ret = V_GetColorFromString (string); + ret = V_GetColorFromString (string.GetChars()); } else { @@ -1394,7 +1394,7 @@ void C_RestoreCVars (void) { for (unsigned int i = 0; i < CVarBackups.Size(); ++i) { - cvar_set(CVarBackups[i].Name, CVarBackups[i].String); + cvar_set(CVarBackups[i].Name.GetChars(), CVarBackups[i].String.GetChars()); } C_ForgetCVars(); } diff --git a/src/common/console/c_dispatch.cpp b/src/common/console/c_dispatch.cpp index 7bac0b698..8b6d738a0 100644 --- a/src/common/console/c_dispatch.cpp +++ b/src/common/console/c_dispatch.cpp @@ -79,7 +79,7 @@ public: if (--TicsLeft == 0) { UnsafeExecutionScope scope(IsUnsafe); - AddCommandString(Command); + AddCommandString(Command.GetChars()); return true; } return false; @@ -101,7 +101,7 @@ public: { if (Text.IsNotEmpty() && Command != nullptr) { - FCommandLine args(Text); + FCommandLine args(Text.GetChars()); Command->Run(args, 0); } return true; @@ -301,7 +301,7 @@ void C_DoCommand (const char *cmd, int keynum) } else { // Get the variable's value - if (var->GetDescription().Len()) Printf("%s\n", GStrings.localize(var->GetDescription())); + if (var->GetDescription().Len()) Printf("%s\n", GStrings.localize(var->GetDescription().GetChars())); Printf ("\"%s\" is \"%s\" ", var->GetName(), var->GetHumanString()); Printf ("(default: \"%s\")\n", var->GetHumanStringDefault()); } @@ -400,7 +400,7 @@ static FConsoleCommand *ScanChainForName (FConsoleCommand *start, const char *na *prev = NULL; while (start) { - comp = strnicmp (start->m_Name, name, namelen); + comp = start->m_Name.CompareNoCase(name, namelen); if (comp > 0) return NULL; else if (comp == 0 && start->m_Name[namelen] == 0) @@ -424,10 +424,10 @@ bool FConsoleCommand::AddToHash (FConsoleCommand **table) unsigned int key; FConsoleCommand *insert, **bucket; - key = MakeKey (m_Name); + key = MakeKey (m_Name.GetChars()); bucket = &table[key % HASH_SIZE]; - if (ScanChainForName (*bucket, m_Name, strlen (m_Name), &insert)) + if (ScanChainForName (*bucket, m_Name.GetChars(), m_Name.Len(), &insert)) { return false; } @@ -477,7 +477,7 @@ FConsoleCommand::~FConsoleCommand () *m_Prev = m_Next; if (m_Next) m_Next->m_Prev = m_Prev; - C_RemoveTabCommand (m_Name); + C_RemoveTabCommand (m_Name.GetChars()); } void FConsoleCommand::Run(FCommandLine &argv, int key) @@ -530,7 +530,7 @@ FString BuildString (int argc, FString *argv) { // It's an empty argument, we need to convert it to '""' buf << "\"\" "; } - else if (strchr(argv[arg], '"')) + else if (strchr(argv[arg].GetChars(), '"')) { // If it contains one or more quotes, we need to escape them. buf << '"'; ptrdiff_t substr_start = 0, quotepos; @@ -545,7 +545,7 @@ FString BuildString (int argc, FString *argv) } buf << argv[arg].Mid(substr_start) << "\" "; } - else if (strchr(argv[arg], ' ')) + else if (strchr(argv[arg].GetChars(), ' ')) { // If it contains a space, it needs to be quoted. buf << '"' << argv[arg] << "\" "; } @@ -674,7 +674,7 @@ static int DumpHash (FConsoleCommand **table, bool aliases, const char *pattern= cmd = table[bucket]; while (cmd) { - if (CheckWildcards (pattern, cmd->m_Name)) + if (CheckWildcards (pattern, cmd->m_Name.GetChars())) { if (cmd->IsAlias()) { @@ -712,8 +712,8 @@ void FConsoleAlias::Archive (FConfigFile *f) { if (f != NULL && !m_Command[0].IsEmpty()) { - f->SetValueForKey ("Name", m_Name, true); - f->SetValueForKey ("Command", m_Command[0], true); + f->SetValueForKey ("Name", m_Name.GetChars(), true); + f->SetValueForKey ("Command", m_Command[0].GetChars(), true); } } @@ -923,7 +923,7 @@ void FConsoleAlias::Run (FCommandLine &args, int key) } bRunning = true; - AddCommandString (mycommand, key); + AddCommandString (mycommand.GetChars(), key); bRunning = false; if (m_Command[index].IsEmpty()) { // The alias is unchanged, so put the command back so it can be used again. @@ -999,7 +999,7 @@ void FExecList::ExecCommands() const { for (unsigned i = 0; i < Commands.Size(); ++i) { - AddCommandString(Commands[i]); + AddCommandString(Commands[i].GetChars()); } } @@ -1007,7 +1007,7 @@ void FExecList::AddPullins(std::vector& wads, FConfigFile *config) { for (unsigned i = 0; i < Pullins.Size(); ++i) { - D_AddFile(wads, Pullins[i], true, -1, config); + D_AddFile(wads, Pullins[i].GetChars(), true, -1, config); } } diff --git a/src/common/console/c_enginecmds.cpp b/src/common/console/c_enginecmds.cpp index f6b8732de..4911b9f44 100644 --- a/src/common/console/c_enginecmds.cpp +++ b/src/common/console/c_enginecmds.cpp @@ -189,11 +189,11 @@ UNSAFE_CCMD (dir) { path = I_GetCWD();; } - auto base = ExtractFileBase(path, true); + auto base = ExtractFileBase(path.GetChars(), true); FString bpath; if (base.IndexOfAny("*?") >= 0) { - bpath = ExtractFilePath(path); + bpath = ExtractFilePath(path.GetChars()); } else { @@ -202,7 +202,7 @@ UNSAFE_CCMD (dir) } FileSys::FileList list; - if (!FileSys::ScanDirectory(list, bpath, base, true)) + if (!FileSys::ScanDirectory(list, bpath.GetChars(), base.GetChars(), true)) { Printf ("Nothing matching %s\n", path.GetChars()); } diff --git a/src/common/engine/date.cpp b/src/common/engine/date.cpp index c409416f8..63e3776b7 100644 --- a/src/common/engine/date.cpp +++ b/src/common/engine/date.cpp @@ -224,7 +224,7 @@ static void FormatTime(const FString& timeForm, int timeVal, FString* result) if (timeinfo != nullptr) { char timeString[1024]; - if (strftime(timeString, sizeof(timeString), timeForm, timeinfo)) + if (strftime(timeString, sizeof(timeString), timeForm.GetChars(), timeinfo)) *result = timeString; } } diff --git a/src/common/fonts/font.cpp b/src/common/fonts/font.cpp index 8b1542898..c12d254b1 100644 --- a/src/common/fonts/font.cpp +++ b/src/common/fonts/font.cpp @@ -97,7 +97,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla FStringf path("fonts/%s/", filetemplate); // If a name template is given, collect data from all resource files. // For anything else, each folder is being treated as an atomic, self-contained unit and mixing from different glyph sets is blocked. - fileSystem.GetFilesInFolder(path, folderdata, nametemplate == nullptr); + fileSystem.GetFilesInFolder(path.GetChars(), folderdata, nametemplate == nullptr); //if (nametemplate == nullptr) { @@ -231,8 +231,8 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla // provide STCFN120 (x) and STCFN122 (z) for STCFN121 to load as a 'y'. FStringf c120(nametemplate, 120); FStringf c122(nametemplate, 122); - if (!TexMan.CheckForTexture(c120, ETextureType::MiscPatch).isValid() || - !TexMan.CheckForTexture(c122, ETextureType::MiscPatch).isValid()) + if (!TexMan.CheckForTexture(c120.GetChars(), ETextureType::MiscPatch).isValid() || + !TexMan.CheckForTexture(c122.GetChars(), ETextureType::MiscPatch).isValid()) { // insert the incorrectly named '|' graphic in its correct position. position = 124; diff --git a/src/common/fonts/v_font.cpp b/src/common/fonts/v_font.cpp index 591edb208..f516a2091 100644 --- a/src/common/fonts/v_font.cpp +++ b/src/common/fonts/v_font.cpp @@ -113,7 +113,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) FStringf path("fonts/%s/", name); // Use a folder-based font only if it comes from a later file than the single lump version. - if (fileSystem.GetFilesInFolder(path, folderdata, true)) + if (fileSystem.GetFilesInFolder(path.GetChars(), folderdata, true)) { // This assumes that any custom font comes in one piece and not distributed across multiple resource files. folderfile = fileSystem.GetFileContainer(folderdata[0].lumpnum); @@ -300,7 +300,7 @@ void V_InitCustomFonts() } if (format == 1) { - FFont *fnt = new FFont (namebuffer, templatebuf, nullptr, first, count, start, llump, spacewidth, donttranslate); + FFont *fnt = new FFont(namebuffer.GetChars(), templatebuf.GetChars(), nullptr, first, count, start, llump, spacewidth, donttranslate); fnt->SetCursor(cursor); fnt->SetKerning(kerning); if (ignoreoffsets) fnt->ClearOffsets(); @@ -326,7 +326,7 @@ void V_InitCustomFonts() if (count > 0) { FFont *CreateSpecialFont (const char *name, int first, int count, FGameTexture **lumplist, const bool *notranslate, int lump, bool donttranslate); - FFont *fnt = CreateSpecialFont (namebuffer, first, count, &lumplist[first], notranslate, llump, donttranslate); + FFont *fnt = CreateSpecialFont(namebuffer.GetChars(), first, count, &lumplist[first], notranslate, llump, donttranslate); fnt->SetCursor(cursor); fnt->SetKerning(kerning); if (spacewidth >= 0) fnt->SpaceWidth = spacewidth; diff --git a/src/common/models/model.cpp b/src/common/models/model.cpp index f8eb12feb..2df92a370 100644 --- a/src/common/models/model.cpp +++ b/src/common/models/model.cpp @@ -89,7 +89,7 @@ void FModel::DestroyVertexBuffer() static int FindGFXFile(FString & fn) { - int lump = fileSystem.CheckNumForFullName(fn); // if we find something that matches the name plus the extension, return it and do not enter the substitution logic below. + int lump = fileSystem.CheckNumForFullName(fn.GetChars()); // if we find something that matches the name plus the extension, return it and do not enter the substitution logic below. if (lump != -1) return lump; int best = -1; @@ -101,7 +101,7 @@ static int FindGFXFile(FString & fn) for (const char ** extp=extensions; *extp; extp++) { - lump = fileSystem.CheckNumForFullName(fn + *extp); + lump = fileSystem.CheckNumForFullName((fn + *extp).GetChars()); if (lump >= best) best = lump; } return best; @@ -149,7 +149,7 @@ unsigned FindModel(const char * path, const char * modelfile, bool silent) if (path) fullname.Format("%s%s", path, modelfile); else fullname = modelfile; - int lump = fileSystem.CheckNumForFullName(fullname); + int lump = fileSystem.CheckNumForFullName(fullname.GetChars()); if (lump<0) { @@ -170,7 +170,7 @@ unsigned FindModel(const char * path, const char * modelfile, bool silent) { FString anivfile = fullname.GetChars(); anivfile.Substitute("_d.3d","_a.3d"); - if ( fileSystem.CheckNumForFullName(anivfile) > 0 ) + if ( fileSystem.CheckNumForFullName(anivfile.GetChars()) > 0 ) { model = new FUE1Model; } @@ -179,7 +179,7 @@ unsigned FindModel(const char * path, const char * modelfile, bool silent) { FString datafile = fullname.GetChars(); datafile.Substitute("_a.3d","_d.3d"); - if ( fileSystem.CheckNumForFullName(datafile) > 0 ) + if ( fileSystem.CheckNumForFullName(datafile.GetChars()) > 0 ) { model = new FUE1Model; } diff --git a/src/common/platform/win32/i_specialpaths.cpp b/src/common/platform/win32/i_specialpaths.cpp index 62e1766d4..8862024b7 100644 --- a/src/common/platform/win32/i_specialpaths.cpp +++ b/src/common/platform/win32/i_specialpaths.cpp @@ -91,7 +91,7 @@ bool IsPortable() // A portable INI means that this storage location should also be portable if the file can be written to. FStringf path("%s" GAMENAMELOWERCASE "_portable.ini", progdir.GetChars()); - if (FileExists(path.GetChars())) + if (FileExists(path)) { file = CreateFile(path.WideString().c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -217,7 +217,7 @@ FString M_GetOldConfigPath(int& type) } path << GAMENAMELOWERCASE "-" << FString(uname) << ".ini"; type = 0; - if (FileExists(path.GetChars())) + if (FileExists(path)) return path; } @@ -226,7 +226,7 @@ FString M_GetOldConfigPath(int& type) path = GetKnownFolder(CSIDL_APPDATA, FOLDERID_RoamingAppData, true); path += "/" GAME_DIR "/" GAMENAMELOWERCASE ".ini"; type = 1; - if (FileExists(path.GetChars())) + if (FileExists(path)) return path; return ""; @@ -285,7 +285,7 @@ FString M_GetConfigPath(bool for_reading) path += "/My Games/" GAME_DIR; CreatePath(path.GetChars()); path += "/" GAMENAMELOWERCASE ".ini"; - if (!for_reading || FileExists(path.GetChars())) + if (!for_reading || FileExists(path)) return path; // No config was found in the accepted locations. @@ -314,7 +314,7 @@ FString M_GetConfigPath(bool for_reading) // If we are reading the config file, check if it exists. If not, fallback to base version. if (for_reading) { - if (!FileExists(path.GetChars())) + if (!FileExists(path)) { path = progdir; path << GAMENAMELOWERCASE ".ini"; diff --git a/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp b/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp index 9cf1badb7..e339f9267 100644 --- a/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp +++ b/src/common/rendering/hwrenderer/postprocessing/hw_postprocess.cpp @@ -1013,7 +1013,7 @@ void PPCustomShaderInstance::SetTextures(PPRenderState *renderstate) while (it.NextPair(pair)) { FString name = pair->Value; - auto gtex = TexMan.GetGameTexture(TexMan.CheckForTexture(name, ETextureType::Any), true); + auto gtex = TexMan.GetGameTexture(TexMan.CheckForTexture(name.GetChars(), ETextureType::Any), true); if (gtex && gtex->isValid()) { // Why does this completely circumvent the normal way of handling textures? diff --git a/src/common/scripting/backend/vmbuilder.cpp b/src/common/scripting/backend/vmbuilder.cpp index ae34ea4c5..ffd29d4dd 100644 --- a/src/common/scripting/backend/vmbuilder.cpp +++ b/src/common/scripting/backend/vmbuilder.cpp @@ -790,7 +790,7 @@ VMFunction *FFunctionBuildList::AddFunction(PNamespace *gnspc, const VersionInfo it.PrintableName = name; it.Function = new VMScriptFunction; it.Function->Name = functype->SymbolName; - it.Function->QualifiedName = it.Function->PrintableName = ClassDataAllocator.Strdup(name); + it.Function->QualifiedName = it.Function->PrintableName = ClassDataAllocator.Strdup(name.GetChars()); it.Function->ImplicitArgs = functype->GetImplicitArgs(); it.Proto = nullptr; it.FromDecorate = fromdecorate; @@ -1148,7 +1148,7 @@ void VMDisassemblyDumper::Write(VMScriptFunction *sfunc, const FString &fname) assert(sfunc != nullptr); - DumpFunction(dump, sfunc, fname, (int)fname.Len()); + DumpFunction(dump, sfunc, fname.GetChars(), (int)fname.Len()); codesize += sfunc->CodeSize; datasize += sfunc->LineInfoCount * sizeof(FStatementInfo) + sfunc->ExtraSpace + sfunc->NumKonstD * sizeof(int) + sfunc->NumKonstA * sizeof(void*) + sfunc->NumKonstF * sizeof(double) + sfunc->NumKonstS * sizeof(FString); diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index fb21526f1..db69835f8 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -662,7 +662,7 @@ void ZCCCompiler::MessageV(ZCC_TreeNode *node, const char *txtcolor, const char composed.Format("%s%s, line %d: ", txtcolor, node->SourceName->GetChars(), node->SourceLoc); composed.VAppendFormat(msg, argptr); composed += '\n'; - PrintString(PRINT_HIGH, composed); + PrintString(PRINT_HIGH, composed.GetChars()); } //========================================================================== diff --git a/src/common/scripting/frontend/zcc_parser.cpp b/src/common/scripting/frontend/zcc_parser.cpp index 978006054..6ba675744 100644 --- a/src/common/scripting/frontend/zcc_parser.cpp +++ b/src/common/scripting/frontend/zcc_parser.cpp @@ -471,7 +471,7 @@ PNamespace *ParseOneScript(const int baselump, ZCCParseState &state) ParseSingleFile(&sc, nullptr, lumpnum, parser, state); for (unsigned i = 0; i < Includes.Size(); i++) { - lumpnum = fileSystem.CheckNumForFullName(Includes[i], true); + lumpnum = fileSystem.CheckNumForFullName(Includes[i].GetChars(), true); if (lumpnum == -1) { IncludeLocs[i].Message(MSG_ERROR, "Include script lump %s not found", Includes[i].GetChars()); @@ -518,7 +518,7 @@ PNamespace *ParseOneScript(const int baselump, ZCCParseState &state) FString filename = fileSystem.GetFileFullPath(baselump).c_str(); filename.ReplaceChars(":\\/?|", '.'); filename << ".ast"; - FileWriter *ff = FileWriter::Open(filename); + FileWriter *ff = FileWriter::Open(filename.GetChars()); if (ff != NULL) { ff->Write(ast.GetChars(), ast.Len()); diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index 350bf5ce3..daed2f091 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -148,7 +148,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawTexture, SBar_DrawTexture) void SBar_DrawImage(DStatusBarCore* self, const FString& texid, double x, double y, int flags, double alpha, double w, double h, double scaleX, double scaleY, int style, int color, int translation, double clipwidth) { if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); - self->DrawGraphic(TexMan.CheckForTexture(texid, ETextureType::Any), x, y, flags, alpha, w, h, scaleX, scaleY, ERenderStyle(style), color, translation, clipwidth); + self->DrawGraphic(TexMan.CheckForTexture(texid.GetChars(), ETextureType::Any), x, y, flags, alpha, w, h, scaleX, scaleY, ERenderStyle(style), color, translation, clipwidth); } DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawImage, SBar_DrawImage) @@ -174,7 +174,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawImage, SBar_DrawImage) void SBar_DrawImageRotated(DStatusBarCore* self, const FString& texid, double x, double y, int flags, double angle, double alpha, double scaleX, double scaleY, int style, int color, int translation) { if (!twod->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); - self->DrawRotated(TexMan.CheckForTexture(texid, ETextureType::Any), x, y, flags, angle, alpha, scaleX, scaleY, color, translation, (ERenderStyle)style); + self->DrawRotated(TexMan.CheckForTexture(texid.GetChars(), ETextureType::Any), x, y, flags, angle, alpha, scaleX, scaleY, color, translation, (ERenderStyle)style); } DEFINE_ACTION_FUNCTION_NATIVE(DStatusBarCore, DrawImageRotated, SBar_DrawImageRotated) @@ -433,7 +433,7 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetName) static int CheckForTexture(const FString& name, int type, int flags) { - return TexMan.CheckForTexture(name, static_cast(type), flags).GetIndex(); + return TexMan.CheckForTexture(name.GetChars(), static_cast(type), flags).GetIndex(); } DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, CheckForTexture, CheckForTexture) @@ -560,7 +560,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, CheckRealHeight, CheckRealHeight) static int OkForLocalization_(int index, const FString& substitute) { - return sysCallbacks.OkForLocalization? sysCallbacks.OkForLocalization(FSetTextureID(index), substitute) : false; + return sysCallbacks.OkForLocalization? sysCallbacks.OkForLocalization(FSetTextureID(index), substitute.GetChars()) : false; } DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, OkForLocalization, OkForLocalization_) @@ -788,14 +788,14 @@ DEFINE_ACTION_FUNCTION(_Wads, CheckNumForName) PARAM_INT(ns); PARAM_INT(wadnum); PARAM_BOOL(exact); - ACTION_RETURN_INT(fileSystem.CheckNumForName(name, ns, wadnum, exact)); + ACTION_RETURN_INT(fileSystem.CheckNumForName(name.GetChars(), ns, wadnum, exact)); } DEFINE_ACTION_FUNCTION(_Wads, CheckNumForFullName) { PARAM_PROLOGUE; PARAM_STRING(name); - ACTION_RETURN_INT(fileSystem.CheckNumForFullName(name)); + ACTION_RETURN_INT(fileSystem.CheckNumForFullName(name.GetChars())); } DEFINE_ACTION_FUNCTION(_Wads, FindLump) @@ -805,7 +805,7 @@ DEFINE_ACTION_FUNCTION(_Wads, FindLump) PARAM_INT(startlump); PARAM_INT(ns); const bool isLumpValid = startlump >= 0 && startlump < fileSystem.GetNumEntries(); - ACTION_RETURN_INT(isLumpValid ? fileSystem.FindLump(name, &startlump, 0 != ns) : -1); + ACTION_RETURN_INT(isLumpValid ? fileSystem.FindLump(name.GetChars(), &startlump, 0 != ns) : -1); } DEFINE_ACTION_FUNCTION(_Wads, FindLumpFullName) @@ -815,7 +815,7 @@ DEFINE_ACTION_FUNCTION(_Wads, FindLumpFullName) PARAM_INT(startlump); PARAM_BOOL(noext); const bool isLumpValid = startlump >= 0 && startlump < fileSystem.GetNumEntries(); - ACTION_RETURN_INT(isLumpValid ? fileSystem.FindLumpFullName(name, &startlump, noext) : -1); + ACTION_RETURN_INT(isLumpValid ? fileSystem.FindLumpFullName(name.GetChars(), &startlump, noext) : -1); } DEFINE_ACTION_FUNCTION(_Wads, GetLumpName) @@ -1023,7 +1023,7 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, SetBind) } - self->SetBind(k, cmd); + self->SetBind(k, cmd.GetChars()); return 0; } @@ -1062,7 +1062,7 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, GetAllKeysForCommand) PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); PARAM_POINTER(array, TArray); PARAM_STRING(cmd); - *array = self->GetKeysForCommand(cmd); + *array = self->GetKeysForCommand(cmd.GetChars()); return 0; } @@ -1084,7 +1084,7 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, UnbindACommand) I_FatalError("Attempt to unbind key bindings for '%s' outside of menu code", cmd.GetChars()); } - self->UnbindACommand(cmd); + self->UnbindACommand(cmd.GetChars()); return 0; } @@ -1102,7 +1102,7 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand) } UnsafeExecutionScope scope(unsafe); - AddCommandString(cmd); + AddCommandString(cmd.GetChars()); return 0; } @@ -1147,7 +1147,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_System, StopAllSounds, StopAllSounds) static int PlayMusic(const FString& musname, int order, int looped) { - return S_ChangeMusic(musname, order, !!looped, true); + return S_ChangeMusic(musname.GetChars(), order, !!looped, true); } DEFINE_ACTION_FUNCTION_NATIVE(_System, PlayMusic, PlayMusic) diff --git a/src/common/scripting/vm/vmexec.h b/src/common/scripting/vm/vmexec.h index 5ddac8bd4..f1e0cb235 100644 --- a/src/common/scripting/vm/vmexec.h +++ b/src/common/scripting/vm/vmexec.h @@ -2117,7 +2117,7 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c case CAST_S2Co: ASSERTD(a); ASSERTS(b); - reg.d[a] = V_GetColor(reg.s[b]); + reg.d[a] = V_GetColor(reg.s[b].GetChars()); break; case CAST_Co2S: diff --git a/src/common/utility/cmdlib.h b/src/common/utility/cmdlib.h index 6f40c184c..6f5c6b584 100644 --- a/src/common/utility/cmdlib.h +++ b/src/common/utility/cmdlib.h @@ -34,6 +34,10 @@ char(&_ArraySizeHelper(T(&array)[N]))[N]; #define myoffsetof(type,identifier) ((size_t)&((type *)alignof(type))->identifier - alignof(type)) bool FileExists (const char *filename); +inline bool FileExists(const FString& filename) +{ + return FileExists(filename.GetChars()); +} bool FileReadable (const char *filename); bool DirExists(const char *filename); bool DirEntryExists (const char *pathname, bool *isdir = nullptr); diff --git a/src/console/c_cmds.cpp b/src/console/c_cmds.cpp index 7743997d9..71f9a40b5 100644 --- a/src/console/c_cmds.cpp +++ b/src/console/c_cmds.cpp @@ -309,12 +309,12 @@ CCMD (idclev) // Catch invalid maps. mapname = CalcMapName (epsd, map); - if (!P_CheckMapData(mapname)) + if (!P_CheckMapData(mapname.GetChars())) return; // So be it. Printf ("%s\n", GStrings("STSTR_CLEV")); - G_DeferedInitNew (mapname); + G_DeferedInitNew (mapname.GetChars()); //players[0].health = 0; // Force reset } } @@ -334,11 +334,11 @@ CCMD (hxvisit) { // Just because it's in MAPINFO doesn't mean it's in the wad. - if (P_CheckMapData(mapname)) + if (P_CheckMapData(mapname.GetChars())) { // So be it. Printf ("%s\n", GStrings("STSTR_CLEV")); - G_DeferedInitNew (mapname); + G_DeferedInitNew (mapname.GetChars()); return; } } @@ -686,8 +686,8 @@ UNSAFE_CCMD (load) return; } #endif - fname = G_BuildSaveName(fname); - G_LoadGame (fname); + fname = G_BuildSaveName(fname.GetChars()); + G_LoadGame (fname.GetChars()); } //========================================================================== @@ -725,8 +725,8 @@ UNSAFE_CCMD(save) return; } #endif - fname = G_BuildSaveName(fname); - G_SaveGame (fname, argv.argc() > 2 ? argv[2] : argv[1]); + fname = G_BuildSaveName(fname.GetChars()); + G_SaveGame (fname.GetChars(), argv.argc() > 2 ? argv[2] : argv[1]); } @@ -971,7 +971,7 @@ CCMD(nextmap) if (primaryLevel->NextMap.Len() > 0 && primaryLevel->NextMap.Compare("enDSeQ", 6)) { - G_DeferedInitNew(primaryLevel->NextMap); + G_DeferedInitNew(primaryLevel->NextMap.GetChars()); } else { @@ -995,7 +995,7 @@ CCMD(nextsecret) if (primaryLevel->NextSecretMap.Len() > 0 && primaryLevel->NextSecretMap.Compare("enDSeQ", 6)) { - G_DeferedInitNew(primaryLevel->NextSecretMap); + G_DeferedInitNew(primaryLevel->NextSecretMap.GetChars()); } else { @@ -1085,7 +1085,7 @@ static void PrintSecretString(const char *string, bool thislevel) CCMD(secret) { const char *mapname = argv.argc() < 2? primaryLevel->MapName.GetChars() : argv[1]; - bool thislevel = !stricmp(mapname, primaryLevel->MapName); + bool thislevel = !stricmp(mapname, primaryLevel->MapName.GetChars()); bool foundsome = false; int lumpno=fileSystem.CheckNumForName("SECRETS"); @@ -1105,13 +1105,13 @@ CCMD(secret) { if (readbuffer[0] == '[') { - inlevel = !strnicmp(readbuffer, maphdr, maphdr.Len()); + inlevel = !strnicmp(readbuffer, maphdr.GetChars(), maphdr.Len()); if (!foundsome) { FString levelname; level_info_t *info = FindLevelInfo(mapname); - const char* ln = info->LookupLevelName(); - levelname.Format("%s - %s", mapname, ln); + FString ln = info->LookupLevelName(); + levelname.Format("%s - %s", mapname, ln.GetChars()); Printf(TEXTCOLOR_YELLOW "%s\n", levelname.GetChars()); size_t llen = levelname.Len(); levelname = ""; @@ -1132,7 +1132,7 @@ CCMD(secret) // line complete so print it. linebuild.Substitute("\r", ""); linebuild.StripRight(" \t\n"); - PrintSecretString(linebuild, thislevel); + PrintSecretString(linebuild.GetChars(), thislevel); linebuild = ""; } } @@ -1209,11 +1209,11 @@ CCMD(idmus) map = CalcMapName(argv[1][0] - '0', argv[1][1] - '0'); } - if ((info = FindLevelInfo(map))) + if ((info = FindLevelInfo(map.GetChars()))) { if (info->Music.IsNotEmpty()) { - S_ChangeMusic(info->Music, info->musicorder); + S_ChangeMusic(info->Music.GetChars(), info->musicorder); Printf("%s\n", GStrings("STSTR_MUS")); } } @@ -1310,7 +1310,7 @@ CCMD (mapinfo) Printf(" LevelName: %s\n", myLevel->LookupLevelName().GetChars()); if (myLevel->AuthorName.IsNotEmpty()) - Printf(" AuthorName: %s\n", testlocalised(myLevel->AuthorName)); + Printf(" AuthorName: %s\n", testlocalised(myLevel->AuthorName.GetChars())); if (myLevel->levelnum) Printf(" LevelNum: %i\n", myLevel->levelnum); @@ -1322,7 +1322,7 @@ CCMD (mapinfo) Printf(" SecretNext: %s\n", myLevel->NextSecretMap.GetChars()); if (myLevel->Music.IsNotEmpty()) - Printf(" Music: %s%s\n", myLevel->Music[0] == '$'? "D_" : "", testlocalised(myLevel->Music)); + Printf(" Music: %s%s\n", myLevel->Music[0] == '$'? "D_" : "", testlocalised(myLevel->Music.GetChars())); Printf(" PixelStretch: %f\n", myLevel->pixelstretch); diff --git a/src/d_defcvars.cpp b/src/d_defcvars.cpp index d066647b2..bcd8ad194 100644 --- a/src/d_defcvars.cpp +++ b/src/d_defcvars.cpp @@ -81,17 +81,17 @@ void D_GrabCVarDefaults() CurrentFindCVar.ToLower(); // these two got renamed - if (strcmp(CurrentFindCVar, "gamma") == 0) + if (CurrentFindCVar.Compare("gamma") == 0) { CurrentFindCVar = "vid_gamma"; } - if (strcmp(CurrentFindCVar, "fullscreen") == 0) + if (CurrentFindCVar.Compare("fullscreen") == 0) { CurrentFindCVar = "vid_fullscreen"; } // this was removed - if (strcmp(CurrentFindCVar, "cd_drive") == 0) + if (CurrentFindCVar.Compare("cd_drive") == 0) break; } if (lumpversion < 221) @@ -100,9 +100,9 @@ void D_GrabCVarDefaults() // this one doesn't matter as much, since it depended on platform-specific values, // and is something the user should change anyhow, so, let's just throw this value // out. - if (strcmp(CurrentFindCVar, "mouse_sensitivity") == 0) + if (CurrentFindCVar.Compare("mouse_sensitivity") == 0) break; - if (strcmp(CurrentFindCVar, "m_noprescale") == 0) + if (CurrentFindCVar.Compare("m_noprescale") == 0) break; } @@ -132,7 +132,7 @@ void D_GrabCVarDefaults() SHOULD_BLACKLIST(anonstats_host) SHOULD_BLACKLIST(sentstats_hwr_done) - var = FindCVar(CurrentFindCVar, NULL); + var = FindCVar(CurrentFindCVar.GetChars(), NULL); if (blacklisted) { diff --git a/src/d_defcvars.h b/src/d_defcvars.h index 8bf3d7c18..caaca508b 100644 --- a/src/d_defcvars.h +++ b/src/d_defcvars.h @@ -23,6 +23,6 @@ #define SHOULD_BLACKLIST(name) \ if (#name[0]==CurrentFindCVar[0]) \ - if (strcmp(CurrentFindCVar, #name) == 0) \ + if (CurrentFindCVar.Compare(#name) == 0) \ blacklisted = true; diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index ab562f283..6cbde02f7 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -360,7 +360,7 @@ int FIWadManager::ScanIWAD (const char *iwad) if (full && strnicmp(full, "maps/", 5) == 0) { FString mapname(&full[5], strcspn(&full[5], ".")); - CheckFileName(mapname); + CheckFileName(mapname.GetChars()); } } } @@ -490,7 +490,7 @@ void FIWadManager::AddIWADCandidates(const char *dir) } for (auto &name : mIWadNames) { - if (!stricmp(name, entry.FileName.c_str())) + if (!name.CompareNoCase(entry.FileName.c_str())) { mFoundWads.Push(FFoundWadInfo{ entry.FilePath.c_str(), "", -1 }); } @@ -515,14 +515,14 @@ void FIWadManager::ValidateIWADs() for (auto &p : mFoundWads) { int index; - auto x = strrchr(p.mFullPath, '.'); + auto x = strrchr(p.mFullPath.GetChars(), '.'); if (x != nullptr && (!stricmp(x, ".iwad") || !stricmp(x, ".ipk3") || !stricmp(x, ".ipk7"))) { - index = CheckIWADInfo(p.mFullPath); + index = CheckIWADInfo(p.mFullPath.GetChars()); } else { - index = ScanIWAD(p.mFullPath); + index = ScanIWAD(p.mFullPath.GetChars()); } p.mInfoIndex = index; } @@ -561,7 +561,7 @@ int FIWadManager::IdentifyVersion (std::vector&wadfiles, const char // Collect all IWADs in the search path for (auto &dir : mSearchPaths) { - AddIWADCandidates(dir); + AddIWADCandidates(dir.GetChars()); } unsigned numFoundWads = mFoundWads.Size(); @@ -608,7 +608,7 @@ int FIWadManager::IdentifyVersion (std::vector&wadfiles, const char // Check for symbolic links leading to non-existent files and for files that are unreadable. for (unsigned int i = 0; i < mFoundWads.Size(); i++) { - if (!FileExists(mFoundWads[i].mFullPath) || !FileReadable(mFoundWads[i].mFullPath)) mFoundWads.Delete(i--); + if (!FileExists(mFoundWads[i].mFullPath) || !FileReadable(mFoundWads[i].mFullPath.GetChars())) mFoundWads.Delete(i--); } // Now check if what got collected actually is an IWAD. @@ -729,7 +729,7 @@ int FIWadManager::IdentifyVersion (std::vector&wadfiles, const char for (unsigned i = 0; i < picks.Size(); ++i) { FString &basename = mIWadInfos[picks[i].mInfoIndex].Name; - if (stricmp(basename, defaultiwad) == 0) + if (basename.CompareNoCase(defaultiwad) == 0) { pick = i; break; @@ -745,7 +745,7 @@ int FIWadManager::IdentifyVersion (std::vector&wadfiles, const char { WadStuff stuff; stuff.Name = mIWadInfos[found.mInfoIndex].Name; - stuff.Path = ExtractFileBase(found.mFullPath); + stuff.Path = ExtractFileBase(found.mFullPath.GetChars()); wads.Push(stuff); } int flags = 0;; @@ -764,7 +764,7 @@ int FIWadManager::IdentifyVersion (std::vector&wadfiles, const char autoloadwidescreen = !!(flags & 8); // The newly selected IWAD becomes the new default - defaultiwad = mIWadInfos[picks[pick].mInfoIndex].Name; + defaultiwad = mIWadInfos[picks[pick].mInfoIndex].Name.GetChars(); } else { @@ -789,10 +789,10 @@ int FIWadManager::IdentifyVersion (std::vector&wadfiles, const char fileSystem.SetIwadNum(iwadnum); if (picks[pick].mRequiredPath.IsNotEmpty()) { - D_AddFile (wadfiles, picks[pick].mRequiredPath, true, -1, GameConfig); + D_AddFile (wadfiles, picks[pick].mRequiredPath.GetChars(), true, -1, GameConfig); iwadnum++; } - D_AddFile (wadfiles, picks[pick].mFullPath, true, -1, GameConfig); + D_AddFile (wadfiles, picks[pick].mFullPath.GetChars(), true, -1, GameConfig); fileSystem.SetMaxIwadNum(iwadnum); auto info = mIWadInfos[picks[pick].mInfoIndex]; @@ -813,7 +813,7 @@ int FIWadManager::IdentifyVersion (std::vector&wadfiles, const char path = FString(picks[pick].mFullPath.GetChars(), lastslash + 1); } path += info.Load[i]; - D_AddFile(wadfiles, path, true, -1, GameConfig); + D_AddFile(wadfiles, path.GetChars(), true, -1, GameConfig); } else { diff --git a/src/d_main.cpp b/src/d_main.cpp index e34b59459..cf1d7785c 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -277,7 +277,7 @@ CUSTOM_CVAR (String, vid_cursor, "None", CVAR_ARCHIVE | CVAR_NOINITCALL) if (!stricmp(self, "None" ) && gameinfo.CursorPic.IsNotEmpty()) { - res = I_SetCursor(TexMan.GetGameTextureByName(gameinfo.CursorPic)); + res = I_SetCursor(TexMan.GetGameTextureByName(gameinfo.CursorPic.GetChars())); } else { @@ -1082,7 +1082,7 @@ void D_Display () } if ( !skip ) { - auto tex = TexMan.GetGameTextureByName(gameinfo.PauseSign, true); + auto tex = TexMan.GetGameTextureByName(gameinfo.PauseSign.GetChars(), true); double x = (SCREENWIDTH - tex->GetDisplayWidth() * CleanXfac)/2 + tex->GetDisplayLeftOffset() * CleanXfac; DrawTexture(twod, tex, x, 4, DTA_CleanNoMove, true, TAG_DONE); @@ -1093,7 +1093,7 @@ void D_Display () pstring.Substitute("%s", players[paused - 1].userinfo.GetName()); DrawText(twod, font, CR_RED, (twod->GetWidth() - font->StringWidth(pstring)*CleanXfac) / 2, - (tex->GetDisplayHeight() * CleanYfac) + 4, pstring, DTA_CleanNoMove, true, TAG_DONE); + (tex->GetDisplayHeight() * CleanYfac) + 4, pstring.GetChars(), DTA_CleanNoMove, true, TAG_DONE); } } } @@ -1515,7 +1515,7 @@ void D_DoAdvanceDemo (void) gamestate = GS_DEMOSCREEN; pagename = gameinfo.TitlePage; pagetic = (int)(gameinfo.titleTime * TICRATE); - if (!playedtitlemusic) S_ChangeMusic (gameinfo.titleMusic, gameinfo.titleOrder, false); + if (!playedtitlemusic) S_ChangeMusic (gameinfo.titleMusic.GetChars(), gameinfo.titleOrder, false); playedtitlemusic = true; demosequence = 3; pagecount = 0; @@ -1537,7 +1537,7 @@ void D_DoAdvanceDemo (void) if (pagename.IsNotEmpty()) { - Page = TexMan.CheckForTexture(pagename, ETextureType::MiscPatch); + Page = TexMan.CheckForTexture(pagename.GetChars(), ETextureType::MiscPatch); } } @@ -1716,7 +1716,7 @@ void ParseCVarInfo() } } // Now create the cvar. - cvar = customCVar ? C_CreateZSCustomCVar(cvarname, cvartype, cvarflags, customCVarClassName) : C_CreateCVar(cvarname, cvartype, cvarflags); + cvar = customCVar ? C_CreateZSCustomCVar(cvarname.GetChars(), cvartype, cvarflags, customCVarClassName) : C_CreateCVar(cvarname.GetChars(), cvartype, cvarflags); if (cvardefault != NULL) { UCVarValue val; @@ -1732,7 +1732,7 @@ void ParseCVarInfo() // clutter up the cvar space when not playing mods with custom cvars. if (addedcvars) { - GameConfig->DoModSetup (gameinfo.ConfigName); + GameConfig->DoModSetup (gameinfo.ConfigName.GetChars()); } } @@ -1753,8 +1753,8 @@ bool ConsiderPatches (const char *arg) argc = Args->CheckParmList(arg, &args); for (i = 0; i < argc; ++i) { - if ( (f = BaseFileSearch(args[i], ".deh", false, GameConfig)) || - (f = BaseFileSearch(args[i], ".bex", false, GameConfig)) ) + if ( (f = BaseFileSearch(args[i].GetChars(), ".deh", false, GameConfig)) || + (f = BaseFileSearch(args[i].GetChars(), ".bex", false, GameConfig)) ) { D_LoadDehFile(f); } @@ -1785,7 +1785,7 @@ static void GetCmdLineFiles(std::vector& wadfiles) argc = Args->CheckParmList("-file", &args); for (i = 0; i < argc; ++i) { - D_AddWildFile(wadfiles, args[i], ".wad", GameConfig); + D_AddWildFile(wadfiles, args[i].GetChars(), ".wad", GameConfig); } } @@ -1830,13 +1830,13 @@ static FString ParseGameInfo(std::vector &pwads, const char *fn, co { checkpath = sc.String; } - if (!DirEntryExists(checkpath, &isDir)) + if (!DirEntryExists(checkpath.GetChars(), &isDir)) { pos += D_AddFile(pwads, sc.String, true, pos, GameConfig); } else { - pos += D_AddFile(pwads, checkpath, true, pos, GameConfig); + pos += D_AddFile(pwads, checkpath.GetChars(), true, pos, GameConfig); } } while (sc.CheckToken(',')); @@ -2037,7 +2037,7 @@ static void AddAutoloadFiles(const char *autoname, std::vector& all file = progdir; #endif file += "skins"; - D_AddDirectory (allwads, file, "*.wad", GameConfig); + D_AddDirectory (allwads, file.GetChars(), "*.wad", GameConfig); #ifdef __unix__ file = NicePath("$HOME/" GAME_DIR "/skins"); @@ -2053,7 +2053,7 @@ static void AddAutoloadFiles(const char *autoname, std::vector& all while ((len = LumpFilterIWAD.IndexOf('.', lastpos+1)) > 0) { file = LumpFilterIWAD.Left(len) + ".Autoload"; - D_AddConfigFiles(allwads, file, "*.wad", GameConfig); + D_AddConfigFiles(allwads, file.GetChars(), "*.wad", GameConfig); lastpos = len; } } @@ -2140,7 +2140,7 @@ static void CheckCmdLine() FString mapvalue = Args->TakeValue("+map"); if (mapvalue.IsNotEmpty()) { - if (!P_CheckMapData(mapvalue)) + if (!P_CheckMapData(mapvalue.GetChars())) { Printf ("Can't find map %s\n", mapvalue.GetChars()); } @@ -2192,9 +2192,8 @@ static void CheckCmdLine() StartScreen->AppendStatusLine("Respawning..."); if (autostart) { - FString temp; - temp.Format ("Warp to map %s, Skill %d ", startmap.GetChars(), gameskill + 1); - StartScreen->AppendStatusLine(temp); + FStringf temp("Warp to map %s, Skill %d ", startmap.GetChars(), gameskill + 1); + StartScreen->AppendStatusLine(temp.GetChars()); } } @@ -3117,15 +3116,15 @@ static int D_InitGame(const FIWADInfo* iwad_info, std::vector& allw FRandom::StaticClearRandom (); FBaseCVar::DisableCallbacks(); - GameConfig->DoGameSetup (gameinfo.ConfigName); + GameConfig->DoGameSetup (gameinfo.ConfigName.GetChars()); - AddAutoloadFiles(iwad_info->Autoname, allwads); + AddAutoloadFiles(iwad_info->Autoname.GetChars(), allwads); // Process automatically executed files FExecList *exec; FArgs *execFiles = new FArgs; if (!(Args->CheckParm("-noautoexec"))) - GameConfig->AddAutoexec(execFiles, gameinfo.ConfigName); + GameConfig->AddAutoexec(execFiles, gameinfo.ConfigName.GetChars()); exec = D_MultiExec(execFiles, NULL); delete execFiles; @@ -3145,7 +3144,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, std::vector& allw if (!batchrun) Printf ("W_Init: Init WADfiles.\n"); LumpFilterInfo lfi; - lfi.dotFilter = LumpFilterIWAD; + lfi.dotFilter = LumpFilterIWAD.GetChars(); static const struct { int match; const char* name; } blanket[] = { @@ -3208,7 +3207,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, std::vector& allw StartScreen = nostartscreen? nullptr : GetGameStartScreen(per_shader_progress > 0 ? max_progress * 10 / 9 : max_progress + 3); - GameConfig->DoKeySetup(gameinfo.ConfigName); + GameConfig->DoKeySetup(gameinfo.ConfigName.GetChars()); // Now that wads are loaded, define mod-specific cvars. ParseCVarInfo(); @@ -3312,7 +3311,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, std::vector& allw }, CheckForHacks, InitBuildTiles); PatchTextures(); TexAnim.Init(); - C_InitConback(TexMan.CheckForTexture(gameinfo.BorderFlat, ETextureType::Flat), true, 0.25); + C_InitConback(TexMan.CheckForTexture(gameinfo.BorderFlat.GetChars(), ETextureType::Flat), true, 0.25); FixWideStatusBar(); @@ -3521,7 +3520,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, std::vector& allw { I_FatalError("Cannot find savegame %s", file.GetChars()); } - G_LoadGame(file); + G_LoadGame(file.GetChars()); } v = Args->CheckValue("-playdemo"); @@ -3550,11 +3549,11 @@ static int D_InitGame(const FIWADInfo* iwad_info, std::vector& allw } CheckWarpTransMap(startmap, true); if (demorecording) - G_BeginRecording(startmap); - G_InitNew(startmap, false); + G_BeginRecording(startmap.GetChars()); + G_InitNew(startmap.GetChars(), false); if (StoredWarp.IsNotEmpty()) { - AddCommandString(StoredWarp); + AddCommandString(StoredWarp.GetChars()); StoredWarp = ""; } } @@ -3670,7 +3669,7 @@ static int D_DoomMain_Internal (void) FString logfile = Args->TakeValue("+logfile"); if (logfile.IsNotEmpty()) { - execLogfile(logfile); + execLogfile(logfile.GetChars()); } else if (batchout != NULL && *batchout != 0) { @@ -3694,7 +3693,7 @@ static int D_DoomMain_Internal (void) FString optionalwad = BaseFileSearch(OPTIONALWAD, NULL, true, GameConfig); - iwad_man = new FIWadManager(basewad, optionalwad); + iwad_man = new FIWadManager(basewad.GetChars(), optionalwad.GetChars()); // Now that we have the IWADINFO, initialize the autoload ini sections. GameConfig->DoAutoloadSetup(iwad_man); @@ -3714,7 +3713,7 @@ static int D_DoomMain_Internal (void) if (iwad_man == NULL) { - iwad_man = new FIWadManager(basewad, optionalwad); + iwad_man = new FIWadManager(basewad.GetChars(), optionalwad.GetChars()); } // Load zdoom.pk3 alone so that we can get access to the internal gameinfos before @@ -3730,7 +3729,7 @@ static int D_DoomMain_Internal (void) std::vector allwads; - const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad, basewad, optionalwad); + const FIWADInfo *iwad_info = iwad_man->FindIWAD(allwads, iwad.GetChars(), basewad.GetChars(), optionalwad.GetChars()); if (!iwad_info) return 0; // user exited the selection popup via cancel button. if ((iwad_info->flags & GI_SHAREWARE) && pwads.size() > 0) { @@ -3955,7 +3954,7 @@ void I_UpdateWindowTitle() // Strip out any color escape sequences before setting a window title TArray copy(titlestr.Len() + 1); - const char* srcp = titlestr; + const char* srcp = titlestr.GetChars(); char* dstp = copy.Data(); while (*srcp != 0) diff --git a/src/d_net.cpp b/src/d_net.cpp index 4f86f0da4..c98f2b1e9 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -1535,7 +1535,7 @@ bool DoArbitrate (void *userdata) netbuffer[1] = (uint8_t)doomcom.ticdup; netbuffer[2] = NetMode; stream = &netbuffer[3]; - WriteString (startmap, &stream); + WriteString (startmap.GetChars(), &stream); WriteLong (rngseed, &stream); C_WriteCVars (&stream, CVAR_SERVERINFO, true); @@ -2452,8 +2452,8 @@ void Net_DoCommand (int type, uint8_t **stream, int player) { // Paths sent over the network will be valid for the system that sent // the save command. For other systems, the path needs to be changed. - FString basename = ExtractFileBase(savegamefile, true); - savegamefile = G_BuildSaveName (basename); + FString basename = ExtractFileBase(savegamefile.GetChars(), true); + savegamefile = G_BuildSaveName (basename.GetChars()); } } gameaction = ga_savegame; @@ -2732,7 +2732,7 @@ static void RunScript(uint8_t **stream, AActor *pawn, int snum, int argn, int al arg[i] = argval; } } - P_StartScript(pawn->Level, pawn, NULL, snum, primaryLevel->MapName, arg, min(countof(arg), argn), ACS_NET | always); + P_StartScript(pawn->Level, pawn, NULL, snum, primaryLevel->MapName.GetChars(), arg, min(countof(arg), argn), ACS_NET | always); } void Net_SkipCommand (int type, uint8_t **stream) diff --git a/src/g_game.cpp b/src/g_game.cpp index f68fca225..2d69009e8 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1723,7 +1723,7 @@ void FLevelLocals::DoReborn (int playernum, bool freshbot) if (!multiplayer && !(flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn && !G_SkillProperty(SKILLP_PlayerRespawn)) { - if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars())) + if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName)) { // Load game from the last point it was saved savename = BackupSaveName; gameaction = ga_autoloadgame; diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 3ba05e833..31f2d7137 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -154,7 +154,7 @@ static FSoundID DehFindSound(int index,bool mustexist = false) if (index < 0) return NO_SOUND; if (index < (int) SoundMap.Size()) return SoundMap[index]; FStringf name("~dsdhacked/#%d", index); - if (dsdhacked && !mustexist) return soundEngine->FindSoundTentative(name); + if (dsdhacked && !mustexist) return soundEngine->FindSoundTentative(name.GetChars()); return NO_SOUND; } @@ -165,7 +165,7 @@ static void ReplaceSoundName(int index, const char* newname) if (snd == NO_SOUND) return; auto sfx = soundEngine->GetWritableSfx(snd); FStringf dsname("ds%s", newname); - sfx->lumpnum = fileSystem.CheckNumForName(dsname, FileSys::ns_sounds); + sfx->lumpnum = fileSystem.CheckNumForName(dsname.GetChars(), FileSys::ns_sounds); sfx->bTentative = false; sfx->bRandomHeader = false; sfx->bLoadRAW = false; @@ -1118,7 +1118,7 @@ static void SetDehParams(FState *state, int codepointer, VMDisassemblyDumper &di sfunc->NumArgs = numargs; sfunc->ImplicitArgs = numargs; state->SetAction(sfunc); - sfunc->PrintableName = ClassDataAllocator.Strdup(FStringf("Dehacked.%s.%d.%d", MBFCodePointers[codepointer].name.GetChars(), value1, value2)); + sfunc->PrintableName = ClassDataAllocator.Strdup(FStringf("Dehacked.%s.%d.%d", MBFCodePointers[codepointer].name.GetChars(), value1, value2).GetChars()); disasmdump.Write(sfunc, sfunc->PrintableName); @@ -2939,7 +2939,7 @@ static int PatchSoundNames (int dummy) { stripwhite(Line2); FString newname = skipwhite (Line2); - ReplaceSoundName((int)strtoll(Line1, nullptr, 10), newname); + ReplaceSoundName((int)strtoll(Line1, nullptr, 10), newname.GetChars()); DPrintf (DMSG_SPAMMY, "Sound %d set to:\n%s\n", Line1, newname.GetChars()); } @@ -2972,7 +2972,7 @@ static int PatchSpriteNames (int dummy) OrgSprNames[o] = nulname; } } - int v = GetSpriteIndex(newname); + int v = GetSpriteIndex(newname.GetChars()); memcpy(OrgSprNames[line1val].c, sprites[v].name, 5); DPrintf (DMSG_SPAMMY, "Sprite %d set to:\n%s\n", Line1, newname.GetChars()); @@ -3028,15 +3028,15 @@ static int DoInclude (int dummy) // Try looking for the included file in the same directory // as the patch before looking in the current file. - const char *lastSlash = strrchr(savepatchname, '/'); + const char *lastSlash = strrchr(savepatchname.GetChars(), '/'); char *path = data; if (lastSlash != NULL) { - size_t pathlen = lastSlash - savepatchname + strlen (data) + 2; + size_t pathlen = lastSlash - savepatchname.GetChars() + strlen (data) + 2; path = new char[pathlen]; - strncpy (path, savepatchname, (lastSlash - savepatchname) + 1); - strcpy (path + (lastSlash - savepatchname) + 1, data); + strncpy (path, savepatchname.GetChars(), (lastSlash - savepatchname.GetChars()) + 1); + strcpy (path + (lastSlash - savepatchname.GetChars()) + 1, data); if (!FileExists (path)) { delete[] path; @@ -3171,7 +3171,7 @@ bool D_LoadDehFile(const char *patchfile) // some WAD may need it. Should be deleted if it can // be confirmed that nothing uses this case. FString filebase(ExtractFileBase(patchfile)); - lumpnum = fileSystem.CheckNumForName(filebase); + lumpnum = fileSystem.CheckNumForName(filebase.GetChars()); } if (lumpnum >= 0) { diff --git a/src/gamedata/decallib.cpp b/src/gamedata/decallib.cpp index 961b63f30..cb906fc06 100644 --- a/src/gamedata/decallib.cpp +++ b/src/gamedata/decallib.cpp @@ -376,7 +376,7 @@ void FDecalLib::ParseDecal (FScanner &sc) sc.MustGetString (); if (sc.Compare ("}")) { - AddDecal (decalName, decalNum, newdecal); + AddDecal(decalName.GetChars(), decalNum, newdecal); break; } switch (sc.MustMatchString (DecalKeywords)) @@ -577,7 +577,7 @@ void FDecalLib::ParseFader (FScanner &sc) sc.MustGetString (); if (sc.Compare ("}")) { - FDecalFaderAnim *fader = new FDecalFaderAnim (faderName); + FDecalFaderAnim *fader = new FDecalFaderAnim (faderName.GetChars()); fader->DecayStart = startTime; fader->DecayTime = decayTime; Animators.Push (fader); @@ -617,7 +617,7 @@ void FDecalLib::ParseStretcher (FScanner &sc) { if (goalX >= 0 || goalY >= 0) { - FDecalStretcherAnim *stretcher = new FDecalStretcherAnim (stretcherName); + FDecalStretcherAnim *stretcher = new FDecalStretcherAnim (stretcherName.GetChars()); stretcher->StretchStart = startTime; stretcher->StretchTime = takeTime; stretcher->GoalX = goalX; @@ -668,7 +668,7 @@ void FDecalLib::ParseSlider (FScanner &sc) { if ((/*distX |*/ distY) != 0) { - FDecalSliderAnim *slider = new FDecalSliderAnim (sliderName); + FDecalSliderAnim *slider = new FDecalSliderAnim (sliderName.GetChars()); slider->SlideStart = startTime; slider->SlideTime = takeTime; /*slider->DistX = distX;*/ @@ -719,7 +719,7 @@ void FDecalLib::ParseColorchanger (FScanner &sc) sc.MustGetString (); if (sc.Compare ("}")) { - FDecalColorerAnim *fader = new FDecalColorerAnim (faderName); + FDecalColorerAnim *fader = new FDecalColorerAnim (faderName.GetChars()); fader->DecayStart = startTime; fader->DecayTime = decayTime; fader->GoalColor = goal; @@ -772,7 +772,7 @@ void FDecalLib::ParseCombiner (FScanner &sc) if (last > first) { - FDecalCombinerAnim *combiner = new FDecalCombinerAnim (combinerName); + FDecalCombinerAnim *combiner = new FDecalCombinerAnim (combinerName.GetChars()); combiner->FirstAnimator = (int)first; combiner->NumAnimators = (int)(last - first); Animators.Push (combiner); diff --git a/src/gamedata/umapinfo.cpp b/src/gamedata/umapinfo.cpp index 006e4629a..bb442f78d 100644 --- a/src/gamedata/umapinfo.cpp +++ b/src/gamedata/umapinfo.cpp @@ -230,7 +230,7 @@ static int ParseStandardProperty(FScanner &scanner, UMapEntry *mape) if (split.Size() > 1) { - epi.mEpisodeName = strbin1(split[1]); + epi.mEpisodeName = strbin1(split[1].GetChars()); } if (split.Size() > 2 && split[2].IsNotEmpty()) { @@ -389,7 +389,7 @@ void CommitUMapinfo(level_info_t *defaultinfo) { for (auto &map : Maps) { - auto levelinfo = FindLevelInfo(map.MapName, false); + auto levelinfo = FindLevelInfo(map.MapName.GetChars(), false); if (levelinfo == nullptr) { // Map did not exist yet. diff --git a/src/maploader/maploader.h b/src/maploader/maploader.h index 6ea2e6121..8390aca04 100644 --- a/src/maploader/maploader.h +++ b/src/maploader/maploader.h @@ -212,6 +212,10 @@ private: void Spawn3DFloors (); void SetTexture(side_t *side, int position, const char *name, FMissingTextureTracker &track); + void SetTexture(side_t* side, int position, const FString& name, FMissingTextureTracker& track) + { + SetTexture(side, position, name.GetChars(), track); + } void SetTexture(sector_t *sector, int index, int position, const char *name, FMissingTextureTracker &track, bool truncate); void SetTexture(side_t *side, int position, uint32_t *blend, const char *name); void SetTextureNoErr(side_t *side, int position, uint32_t *color, const char *name, bool *validcolor, bool isFog); diff --git a/src/maploader/udmf.cpp b/src/maploader/udmf.cpp index d02ee237e..e51a82433 100644 --- a/src/maploader/udmf.cpp +++ b/src/maploader/udmf.cpp @@ -279,7 +279,7 @@ const char *UDMFParserBase::CheckString(FName key) { sc.ScriptMessage("String value expected for key '%s'", key.GetChars()); } - return parsedString; + return parsedString.GetChars(); } //=========================================================================== diff --git a/src/menu/doommenu.cpp b/src/menu/doommenu.cpp index 200dc90fc..50857f76a 100644 --- a/src/menu/doommenu.cpp +++ b/src/menu/doommenu.cpp @@ -221,7 +221,7 @@ bool M_SetSpecialMenu(FName& menu, int param) NewGameStartupInfo.Skill = param; LastSkill = param; - const char *msg = AllSkills[param].MustConfirmText; + const char *msg = AllSkills[param].MustConfirmText.GetChars(); if (*msg==0) msg = GStrings("NIGHTMARE"); M_StartMessage (msg, 0, NAME_StartgameConfirmed); return false; @@ -287,7 +287,7 @@ bool M_SetSpecialMenu(FName& menu, int param) { if ((*desc)->mNetgameMessage.IsNotEmpty() && netgame && !demoplayback) { - M_StartMessage((*desc)->mNetgameMessage, 1); + M_StartMessage((*desc)->mNetgameMessage.GetChars(), 1); return false; } } @@ -389,7 +389,7 @@ CCMD (menu_quit) const size_t messageindex = static_cast(gametic) % gameinfo.quitmessages.Size(); FString EndString; - const char *msg = gameinfo.quitmessages[messageindex]; + const char *msg = gameinfo.quitmessages[messageindex].GetChars(); if (msg[0] == '$') { if (msg[1] == '*') diff --git a/src/playsim/fragglescript/t_func.cpp b/src/playsim/fragglescript/t_func.cpp index fc711eac9..28ff091c6 100644 --- a/src/playsim/fragglescript/t_func.cpp +++ b/src/playsim/fragglescript/t_func.cpp @@ -559,7 +559,7 @@ void FParser::SF_Include(void) { if(t_argv[0].type == svt_string) { - strncpy(tempstr, t_argv[0].string, 8); + strncpy(tempstr, t_argv[0].string.GetChars(), 8); tempstr[8]=0; } else @@ -1869,7 +1869,7 @@ void FParser::SF_FloorTexture(void) if(t_argc > 1) { int i = -1; - FTextureID picnum = TexMan.GetTextureID(t_argv[1].string, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); + FTextureID picnum = TexMan.GetTextureID(t_argv[1].string.GetChars(), ETextureType::Flat, FTextureManager::TEXMAN_Overridable); // set all sectors with tag auto itr = Level->GetSectorTagIterator(tagnum); @@ -1959,7 +1959,7 @@ void FParser::SF_CeilingTexture(void) if(t_argc > 1) { int i = -1; - FTextureID picnum = TexMan.GetTextureID(t_argv[1].string, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); + FTextureID picnum = TexMan.GetTextureID(t_argv[1].string.GetChars(), ETextureType::Flat, FTextureManager::TEXMAN_Overridable); // set all sectors with tag auto itr = Level->GetSectorTagIterator(tagnum); @@ -2229,7 +2229,7 @@ void FParser::SF_SetLineTexture(void) } else // and an improved legacy version { - FTextureID picnum = TexMan.GetTextureID(t_argv[1].string, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); + FTextureID picnum = TexMan.GetTextureID(t_argv[1].string.GetChars(), ETextureType::Wall, FTextureManager::TEXMAN_Overridable); side = !!intvalue(t_argv[2]); int sections = intvalue(t_argv[3]); diff --git a/src/playsim/fragglescript/t_load.cpp b/src/playsim/fragglescript/t_load.cpp index efd27a070..32518aa19 100644 --- a/src/playsim/fragglescript/t_load.cpp +++ b/src/playsim/fragglescript/t_load.cpp @@ -137,7 +137,7 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc) sc.MustGetString(); if (!FS_ChangeMusic(sc.String)) { - S_ChangeMusic(Level->Music, Level->musicorder); + S_ChangeMusic(Level->Music.GetChars(), Level->musicorder); } } else if (sc.Compare("skyname")) diff --git a/src/playsim/fragglescript/t_oper.cpp b/src/playsim/fragglescript/t_oper.cpp index 8b4368db7..beac99d0e 100644 --- a/src/playsim/fragglescript/t_oper.cpp +++ b/src/playsim/fragglescript/t_oper.cpp @@ -167,7 +167,7 @@ void FParser::OPcmp(svalue_t &result, int start, int n, int stop) if(left.type == svt_string && right.type == svt_string) { - result.value.i = !strcmp(left.string, right.string); + result.value.i = !strcmp(left.string.GetChars(), right.string.GetChars()); return; } diff --git a/src/playsim/fragglescript/t_prepro.cpp b/src/playsim/fragglescript/t_prepro.cpp index 495092581..f5a8cee45 100644 --- a/src/playsim/fragglescript/t_prepro.cpp +++ b/src/playsim/fragglescript/t_prepro.cpp @@ -284,7 +284,7 @@ char *DFsScript::ProcessFindChar(char *datap, char find) Printf(PRINT_BOLD,"Script %d: ':' encountrered in incorrect position!\n",scriptnum); } - DFsVariable *newlabel = NewVariable(labelname, svt_label); + DFsVariable *newlabel = NewVariable(labelname.GetChars(), svt_label); newlabel->value.i = MakeIndex(labelptr); } diff --git a/src/playsim/fragglescript/t_script.h b/src/playsim/fragglescript/t_script.h index a80987078..767778628 100644 --- a/src/playsim/fragglescript/t_script.h +++ b/src/playsim/fragglescript/t_script.h @@ -273,7 +273,7 @@ public: CFsError(const FString &in) { - strncpy(msg, in, 2047); + strncpy(msg, in.GetChars(), 2047); msg[2047]=0; } }; diff --git a/src/playsim/fragglescript/t_variable.cpp b/src/playsim/fragglescript/t_variable.cpp index 424490805..f3ab23883 100644 --- a/src/playsim/fragglescript/t_variable.cpp +++ b/src/playsim/fragglescript/t_variable.cpp @@ -54,7 +54,7 @@ int intvalue(const svalue_t &v) { - return (v.type == svt_string ? atoi(v.string) : + return (v.type == svt_string ? atoi(v.string.GetChars()) : v.type == svt_fixed ? (int)(v.value.f / 65536.) : v.type == svt_mobj ? -1 : v.value.i ); } @@ -68,7 +68,7 @@ int intvalue(const svalue_t &v) fsfix fixedvalue(const svalue_t &v) { return (v.type == svt_fixed ? v.value.f : - v.type == svt_string ? (fsfix)(atof(v.string) * 65536.) : + v.type == svt_string ? (fsfix)(atof(v.string.GetChars()) * 65536.) : v.type == svt_mobj ? -65536 : v.value.i * 65536 ); } @@ -81,7 +81,7 @@ fsfix fixedvalue(const svalue_t &v) double floatvalue(const svalue_t &v) { return - v.type == svt_string ? atof(v.string) : + v.type == svt_string ? atof(v.string.GetChars()) : v.type == svt_fixed ? v.value.f / 65536. : v.type == svt_mobj ? -1. : (double)v.value.i; } @@ -99,7 +99,7 @@ const char *stringvalue(const svalue_t & v) switch(v.type) { case svt_string: - return v.string; + return v.string.GetChars(); case svt_mobj: // return the class name @@ -349,7 +349,7 @@ DFsVariable *DFsScript::VariableForName(const char *name) while(current) { - if(!strcmp(name, current->Name)) // found it? + if(!strcmp(name, current->Name.GetChars())) // found it? return current; current = current->next; // check next in chain } diff --git a/src/scripting/vmthunks.cpp b/src/scripting/vmthunks.cpp index 0ece588e5..3b7a1898e 100644 --- a/src/scripting/vmthunks.cpp +++ b/src/scripting/vmthunks.cpp @@ -80,7 +80,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, SetCameraToTexture, SetCameraToTexture) static void SetCameraTextureAspectRatio(const FString &texturename, double aspectScale, bool useTextureRatio) { - FTextureID textureid = TexMan.CheckForTexture(texturename, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); + FTextureID textureid = TexMan.CheckForTexture(texturename.GetChars(), ETextureType::Wall, FTextureManager::TEXMAN_Overridable); if (textureid.isValid()) { // Only proceed if the texture actually has a canvas. @@ -1026,7 +1026,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXOffset, SetXOffset) static void SetEnvironment(sector_t *self, const FString &env) { - self->Level->Zones[self->ZoneNumber].Environment = S_FindEnvironment(env); + self->Level->Zones[self->ZoneNumber].Environment = S_FindEnvironment(env.GetChars()); } DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetEnvironment, SetEnvironment) @@ -1723,7 +1723,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXOffset, SetXOffset) // This is needed to convert the strings to char pointers. static void ReplaceTextures(FLevelLocals *self, const FString &from, const FString &to, int flags) { - self->ReplaceTextures(from, to, flags); + self->ReplaceTextures(from.GetChars(), to.GetChars(), flags); } DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, ReplaceTextures, ReplaceTextures) @@ -1732,7 +1732,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, ReplaceTextures, ReplaceTextures) PARAM_STRING(from); PARAM_STRING(to); PARAM_INT(flags); - self->ReplaceTextures(from, to, flags); + self->ReplaceTextures(from.GetChars(), to.GetChars(), flags); return 0; } @@ -2097,7 +2097,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, Draw, SBar_Draw) static void SetMugshotState(DBaseStatusBar *self, const FString &statename, bool wait, bool reset) { - self->mugshot.SetState(statename, wait, reset); + self->mugshot.SetState(statename.GetChars(), wait, reset); } DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, SetMugshotState, SetMugshotState) @@ -2106,7 +2106,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, SetMugshotState, SetMugshotState) PARAM_STRING(statename); PARAM_BOOL(wait); PARAM_BOOL(reset); - self->mugshot.SetState(statename, wait, reset); + self->mugshot.SetState(statename.GetChars(), wait, reset); return 0; } @@ -2201,7 +2201,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, ReceivedWeapon, ReceivedWeapon) static int GetMugshot(DBaseStatusBar *self, int accuracy, int stateflags, const FString &def_face) { - auto tex = self->mugshot.GetFace(self->CPlayer, def_face, accuracy, (FMugShot::StateFlags)stateflags); + auto tex = self->mugshot.GetFace(self->CPlayer, def_face.GetChars(), accuracy, (FMugShot::StateFlags)stateflags); return (tex ? tex->GetID().GetIndex() : -1); } @@ -2614,7 +2614,7 @@ DEFINE_ACTION_FUNCTION(DObject, S_ChangeMusic) PARAM_INT(order); PARAM_BOOL(looping); PARAM_BOOL(force); - ACTION_RETURN_BOOL(S_ChangeMusic(music, order, looping, force)); + ACTION_RETURN_BOOL(S_ChangeMusic(music.GetChars(), order, looping, force)); } diff --git a/src/scripting/zscript/zcc_compile_doom.cpp b/src/scripting/zscript/zcc_compile_doom.cpp index 642fac09f..d6b8780f9 100644 --- a/src/scripting/zscript/zcc_compile_doom.cpp +++ b/src/scripting/zscript/zcc_compile_doom.cpp @@ -650,7 +650,7 @@ void ZCCDoomCompiler::ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt } - FPropertyInfo *property = FindProperty(propname); + FPropertyInfo *property = FindProperty(propname.GetChars()); if (property != nullptr && property->category != CAT_INFO) { @@ -987,7 +987,7 @@ void ZCCDoomCompiler::CompileStates() { auto sl = static_cast(st); statename = FName(sl->Label).GetChars(); - statedef.AddStateLabel(statename); + statedef.AddStateLabel(statename.GetChars()); break; } case AST_StateLine: @@ -1046,7 +1046,7 @@ void ZCCDoomCompiler::CompileStates() auto l = sl->Lights; do { - AddStateLight(&state, StringConstFromNode(l, c->Type())); + AddStateLight(&state, StringConstFromNode(l, c->Type()).GetChars()); l = static_cast(l->SiblingNext); } while (l != sl->Lights); } @@ -1097,7 +1097,7 @@ void ZCCDoomCompiler::CompileStates() statename.AppendFormat("+%d", offset); } } - if (!statedef.SetGotoLabel(statename)) + if (!statedef.SetGotoLabel(statename.GetChars())) { Error(sg, "GOTO before first state"); } diff --git a/src/sound/s_doomsound.h b/src/sound/s_doomsound.h index b6c6dc336..3dab94ace 100644 --- a/src/sound/s_doomsound.h +++ b/src/sound/s_doomsound.h @@ -20,6 +20,10 @@ inline void S_Sound(int channel, EChanFlags flags, const char* sfxid, float volu { S_Sound(channel, flags, S_FindSound(sfxid), volume, attenuation); } +inline void S_Sound(int channel, EChanFlags flags, const FString& sfxid, float volume, float attenuation) +{ + S_Sound(channel, flags, S_FindSound(sfxid), volume, attenuation); +} void S_SoundPitch(int channel, EChanFlags flags, FSoundID sfxid, float volume, float attenuation, float pitch, float startTime = 0.f); diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index a37073a43..dddc37c31 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -281,20 +281,20 @@ bool DInterBackground::LoadBackground(bool isenterpic) if (!isenterpic) tilebackground = false; texture.SetInvalid(); - level_info_t* li = FindLevelInfo(wbs->current); + level_info_t* li = FindLevelInfo(wbs->current.GetChars()); if (li != nullptr) { - exitpic = li->ExitPic; + exitpic = li->ExitPic.GetChars(); if (li->ExitPic.IsNotEmpty()) tilebackground = false; } lumpname = exitpic; if (isenterpic) { - level_info_t* li = FindLevelInfo(wbs->next); + level_info_t* li = FindLevelInfo(wbs->next.GetChars()); if (li != NULL) { - lumpname = li->EnterPic; + lumpname = li->EnterPic.GetChars(); if (li->EnterPic.IsNotEmpty()) tilebackground = false; } } @@ -309,7 +309,7 @@ bool DInterBackground::LoadBackground(bool isenterpic) case GAME_Doom: if (!(gameinfo.flags & GI_MAPxx)) { - const char* levelname = isenterpic ? wbs->next : wbs->current; + const char* levelname = isenterpic ? wbs->next.GetChars() : wbs->current.GetChars(); if (IsExMy(levelname)) { mysnprintf(buffer, countof(buffer), "$IN_EPI%c", levelname[1]); @@ -331,10 +331,10 @@ bool DInterBackground::LoadBackground(bool isenterpic) if (!(gameinfo.flags & GI_MAPxx)) { // not if the last level is not from the first 3 episodes - if (!IsExMy(wbs->current)) return false; + if (!IsExMy(wbs->current.GetChars())) return false; // not if the next level is one of the first 3 episodes - if (IsExMy(wbs->next)) return false; + if (IsExMy(wbs->next.GetChars())) return false; } } lumpname = "INTERPIC"; @@ -345,7 +345,7 @@ bool DInterBackground::LoadBackground(bool isenterpic) case GAME_Heretic: if (isenterpic) { - if (IsExMy(wbs->next)) + if (IsExMy(wbs->next.GetChars())) { mysnprintf(buffer, countof(buffer), "$IN_HTC%c", wbs->next[1]); lumpname = buffer; @@ -369,7 +369,7 @@ bool DInterBackground::LoadBackground(bool isenterpic) default: // Strife doesn't have an intermission pic so choose something neutral. if (isenterpic) return false; - lumpname = gameinfo.BorderFlat; + lumpname = gameinfo.BorderFlat.GetChars(); tilebackground = true; break; } @@ -664,38 +664,38 @@ void DInterBackground::drawBackground(int state, bool drawsplat, bool snl_pointe switch (a->type & ANIM_CONDITION) { case ANIM_IFVISITED: - li = FindLevelInfo(a->LevelName); + li = FindLevelInfo(a->LevelName.GetChars()); if (li == NULL || !(li->flags & LEVEL_VISITED)) continue; break; case ANIM_IFNOTVISITED: - li = FindLevelInfo(a->LevelName); + li = FindLevelInfo(a->LevelName.GetChars()); if (li == NULL || (li->flags & LEVEL_VISITED)) continue; break; // StatCount means 'leaving' - everything else means 'entering'! case ANIM_IFENTERING: - if (state == StatCount || strnicmp(a->LevelName, wbs->next, 8)) continue; + if (state == StatCount || a->LevelName.CompareNoCase(wbs->next, 8)) continue; break; case ANIM_IFNOTENTERING: - if (state != StatCount && !strnicmp(a->LevelName, wbs->next, 8)) continue; + if (state != StatCount && !a->LevelName.CompareNoCase(wbs->next, 8)) continue; break; case ANIM_IFLEAVING: - if (state != StatCount || strnicmp(a->LevelName, wbs->current, 8)) continue; + if (state != StatCount || a->LevelName.CompareNoCase(wbs->current, 8)) continue; break; case ANIM_IFNOTLEAVING: - if (state == StatCount && !strnicmp(a->LevelName, wbs->current, 8)) continue; + if (state == StatCount && !a->LevelName.CompareNoCase(wbs->current, 8)) continue; break; case ANIM_IFTRAVELLING: - if (strnicmp(a->LevelName2, wbs->current, 8) || strnicmp(a->LevelName, wbs->next, 8)) continue; + if (a->LevelName2.CompareNoCase(wbs->current, 8) || a->LevelName.CompareNoCase(wbs->next, 8)) continue; break; case ANIM_IFNOTTRAVELLING: - if (!strnicmp(a->LevelName2, wbs->current, 8) && !strnicmp(a->LevelName, wbs->next, 8)) continue; + if (!a->LevelName2.CompareNoCase(wbs->current, 8) && !a->LevelName.CompareNoCase(wbs->next, 8)) continue; break; } if (a->ctr >= 0) @@ -707,7 +707,7 @@ void DInterBackground::drawBackground(int state, bool drawsplat, bool snl_pointe { for (i = 0; iflags & LEVEL_VISITED) drawOnLnode(i, &splat, 1, animwidth, animheight); // draw a splat on taken cities. } } @@ -715,7 +715,7 @@ void DInterBackground::drawBackground(int state, bool drawsplat, bool snl_pointe // draw flashing ptr if (snl_pointeron && yah.Size()) { - unsigned int v = MapToIndex(wbs->next); + unsigned int v = MapToIndex(wbs->next.GetChars()); // Draw only if it points to a valid level on the current screen! if (v Date: Wed, 4 Oct 2023 09:58:18 +0200 Subject: [PATCH 171/223] removed several bad casts to 'long'. The 'long' type should generally be avoided because its size differs on Windows and Linux/Mac so it is almost guaranteed to cause undefined behavior --- src/common/filesystem/source/file_7z.cpp | 4 ++-- src/common/filesystem/source/file_zip.cpp | 2 +- src/common/filesystem/source/files_decompress.cpp | 6 +++--- .../rendering/hwrenderer/data/hw_shaderpatcher.cpp | 2 +- src/common/textures/formats/ddstexture.cpp | 2 +- src/common/textures/formats/tgatexture.cpp | 2 +- src/common/utility/cmdlib.cpp | 2 +- src/common/utility/zstring.cpp | 2 +- src/console/c_cmds.cpp | 2 +- src/d_main.cpp | 8 ++++---- src/gamedata/d_dehacked.cpp | 10 ++++++---- src/gamedata/decallib.cpp | 2 +- src/playsim/p_acs.cpp | 8 ++++---- src/rendering/hwrenderer/scene/hw_portal.cpp | 2 +- src/utility/nodebuilder/nodebuild_utility.cpp | 2 +- 15 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/common/filesystem/source/file_7z.cpp b/src/common/filesystem/source/file_7z.cpp index c51a566b9..9201ead99 100644 --- a/src/common/filesystem/source/file_7z.cpp +++ b/src/common/filesystem/source/file_7z.cpp @@ -65,7 +65,7 @@ struct CZDFileInStream static SRes Read(const ISeekInStream *pp, void *buf, size_t *size) { CZDFileInStream *p = (CZDFileInStream *)pp; - auto numread = p->File.Read(buf, (long)*size); + auto numread = p->File.Read(buf, (ptrdiff_t)*size); if (numread < 0) { *size = 0; @@ -96,7 +96,7 @@ struct CZDFileInStream { return 1; } - res = (int)p->File.Seek((long)*pos, move_method); + res = (int)p->File.Seek((ptrdiff_t)*pos, move_method); *pos = p->File.Tell(); return res; } diff --git a/src/common/filesystem/source/file_zip.cpp b/src/common/filesystem/source/file_zip.cpp index c85788fe5..28c2dedec 100644 --- a/src/common/filesystem/source/file_zip.cpp +++ b/src/common/filesystem/source/file_zip.cpp @@ -537,7 +537,7 @@ FResourceFile *CheckZip(const char *filename, FileReader &file, LumpFilterInfo* { char head[4]; - if (file.GetLength() >= (long)sizeof(FZipLocalFileHeader)) + if (file.GetLength() >= (ptrdiff_t)sizeof(FZipLocalFileHeader)) { file.Seek(0, FileReader::SeekSet); file.Read(&head, 4); diff --git a/src/common/filesystem/source/files_decompress.cpp b/src/common/filesystem/source/files_decompress.cpp index a49906a1f..1b6c373b3 100644 --- a/src/common/filesystem/source/files_decompress.cpp +++ b/src/common/filesystem/source/files_decompress.cpp @@ -402,7 +402,7 @@ public: OutProcessed = 0; // Read zip LZMA properties header - if (File->Read(header, sizeof(header)) < (long)sizeof(header)) + if (File->Read(header, sizeof(header)) < (ptrdiff_t)sizeof(header)) { DecompressionError("DecompressorLZMA: File too short\n"); return false; @@ -488,7 +488,7 @@ public: return 0; } - return (long)(next_out - (Byte *)buffer); + return (ptrdiff_t)(next_out - (Byte *)buffer); } void FillBuffer () @@ -698,7 +698,7 @@ public: while(AvailOut && Stream.State != STREAM_FINAL); assert(AvailOut == 0); - return (long)(Out - (uint8_t*)buffer); + return (ptrdiff_t)(Out - (uint8_t*)buffer); } }; diff --git a/src/common/rendering/hwrenderer/data/hw_shaderpatcher.cpp b/src/common/rendering/hwrenderer/data/hw_shaderpatcher.cpp index 50fed5a94..2b391d185 100644 --- a/src/common/rendering/hwrenderer/data/hw_shaderpatcher.cpp +++ b/src/common/rendering/hwrenderer/data/hw_shaderpatcher.cpp @@ -246,7 +246,7 @@ FString RemoveLayoutLocationDecl(FString code, const char *inoutkeyword) // keyword following the declaration? bool keywordFound = true; - long i; + ptrdiff_t i; for (i = 0; inoutkeyword[i] != 0; i++) { if (chars[endIndex + i] != inoutkeyword[i]) diff --git a/src/common/textures/formats/ddstexture.cpp b/src/common/textures/formats/ddstexture.cpp index 3949c3d88..6105ea99b 100644 --- a/src/common/textures/formats/ddstexture.cpp +++ b/src/common/textures/formats/ddstexture.cpp @@ -665,7 +665,7 @@ void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode) { - const long blocklinelen = ((Width + 3) >> 2) << 4; + const size_t blocklinelen = ((Width + 3) >> 2) << 4; uint8_t *blockbuff = new uint8_t[blocklinelen]; uint8_t *block; PalEntry color[4]; diff --git a/src/common/textures/formats/tgatexture.cpp b/src/common/textures/formats/tgatexture.cpp index 2318e4199..7577f79ff 100644 --- a/src/common/textures/formats/tgatexture.cpp +++ b/src/common/textures/formats/tgatexture.cpp @@ -97,7 +97,7 @@ FImageSource *TGAImage_TryCreate(FileReader & file, int lumpnum) { TGAHeader hdr; - if (file.GetLength() < (long)sizeof(hdr)) return NULL; + if (file.GetLength() < (ptrdiff_t)sizeof(hdr)) return NULL; file.Seek(0, FileReader::SeekSet); file.Read(&hdr, sizeof(hdr)); diff --git a/src/common/utility/cmdlib.cpp b/src/common/utility/cmdlib.cpp index 0086d1cd8..b5fd87224 100644 --- a/src/common/utility/cmdlib.cpp +++ b/src/common/utility/cmdlib.cpp @@ -986,7 +986,7 @@ void md5Update(FileReader& file, MD5Context& md5, unsigned len) { t = std::min(len, sizeof(readbuf)); len -= t; - t = (long)file.Read(readbuf, t); + t = (unsigned)file.Read(readbuf, t); md5.Update(readbuf, t); } } diff --git a/src/common/utility/zstring.cpp b/src/common/utility/zstring.cpp index e32dd97a0..c8d8e7b5b 100644 --- a/src/common/utility/zstring.cpp +++ b/src/common/utility/zstring.cpp @@ -603,7 +603,7 @@ ptrdiff_t FString::LastIndexOfAny (const FString &charset) const ptrdiff_t FString::LastIndexOfAny (const char *charset) const { - return LastIndexOfAny (charset, long(Len())); + return LastIndexOfAny (charset, ptrdiff_t(Len())); } ptrdiff_t FString::LastIndexOfAny (const FString &charset, ptrdiff_t endIndex) const diff --git a/src/console/c_cmds.cpp b/src/console/c_cmds.cpp index 71f9a40b5..af88ce41e 100644 --- a/src/console/c_cmds.cpp +++ b/src/console/c_cmds.cpp @@ -1049,7 +1049,7 @@ static void PrintSecretString(const char *string, bool thislevel) } else if (string[1] == 'T' || string[1] == 't') { - long tid = (long)strtoll(string+2, (char**)&string, 10); + int tid = (int)strtoll(string+2, (char**)&string, 10); if (*string == ';') string++; auto it = primaryLevel->GetActorIterator(tid); AActor *actor; diff --git a/src/d_main.cpp b/src/d_main.cpp index cf1d7785c..70c938ebf 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2413,7 +2413,7 @@ void RenameNerve(FileSystem& fileSystem) continue; } for (int icheck = 0; icheck < numnerveversions; icheck++) - if (fr->GetLength() == (long)nervesize[icheck]) + if (fr->GetLength() == (ptrdiff_t)nervesize[icheck]) isizecheck = icheck; if (isizecheck == -1) { @@ -2474,9 +2474,9 @@ void FixMacHexen(FileSystem& fileSystem) FileReader* reader = fileSystem.GetFileReader(fileSystem.GetIwadNum()); auto iwadSize = reader->GetLength(); - static const long DEMO_SIZE = 13596228; - static const long BETA_SIZE = 13749984; - static const long FULL_SIZE = 21078584; + static const ptrdiff_t DEMO_SIZE = 13596228; + static const ptrdiff_t BETA_SIZE = 13749984; + static const ptrdiff_t FULL_SIZE = 21078584; if (DEMO_SIZE != iwadSize && BETA_SIZE != iwadSize diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index 31f2d7137..b0231627c 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -1400,7 +1400,7 @@ static int PatchThing (int thingy) { if (IsNum(strval)) { - value |= (unsigned long)strtoll(strval, NULL, 10); + value |= (uint32_t)strtoll(strval, NULL, 10); vchanged = true; } else @@ -1526,7 +1526,7 @@ static int PatchThing (int thingy) { if (IsNum (strval)) { - value[0] |= (unsigned long)strtoll(strval, NULL, 10); + value[0] |= (uint32_t)strtoll(strval, NULL, 10); vchanged[0] = true; } else @@ -1918,7 +1918,7 @@ static int PatchFrame (int frameNum) { if (IsNum(strval)) { - value |= (unsigned long)strtoll(strval, NULL, 10); + value |= (uint32_t)strtoll(strval, NULL, 10); vchanged = true; } else @@ -2223,7 +2223,7 @@ static int PatchWeapon (int weapNum) { if (IsNum(strval)) { - value |= (unsigned long)strtoll(strval, NULL, 10); + value |= (uint32_t)strtoll(strval, NULL, 10); vchanged = true; } else @@ -3713,8 +3713,10 @@ void FinishDehPatch () type->ActorInfo()->Replacement = subclass; subclass->ActorInfo()->Replacee = type; + subclass->ActorInfo()->LightAssociations = type->ActorInfo()->LightAssociations; // If this actor was already replaced by another actor, copy that // replacement over to this item. + if (old_replacement != NULL) { subclass->ActorInfo()->Replacement = old_replacement; diff --git a/src/gamedata/decallib.cpp b/src/gamedata/decallib.cpp index cb906fc06..06ba2c83f 100644 --- a/src/gamedata/decallib.cpp +++ b/src/gamedata/decallib.cpp @@ -342,7 +342,7 @@ uint16_t FDecalLib::GetDecalID (FScanner &sc) } else { - unsigned long num = strtoul (sc.String, NULL, 10); + uint64_t num = strtoull (sc.String, NULL, 10); if (num < 1 || num > 65535) { sc.ScriptError ("Decal ID must be between 1 and 65535"); diff --git a/src/playsim/p_acs.cpp b/src/playsim/p_acs.cpp index 6aa85943b..fdaebf97f 100644 --- a/src/playsim/p_acs.cpp +++ b/src/playsim/p_acs.cpp @@ -10741,7 +10741,7 @@ static int sort_by_runs(const void *a_, const void *b_) return b->ProfileData->NumRuns - a->ProfileData->NumRuns; } -static void ShowProfileData(TArray &profiles, long ilimit, +static void ShowProfileData(TArray &profiles, int ilimit, int (*sorter)(const void *, const void *), bool functions) { static const char *const typelabels[2] = { "script", "function" }; @@ -10759,7 +10759,7 @@ static void ShowProfileData(TArray &profiles, long ilimit, if (ilimit > 0) { - Printf(TEXTCOLOR_ORANGE "Top %ld %ss:\n", ilimit, typelabels[functions]); + Printf(TEXTCOLOR_ORANGE "Top %lld %ss:\n", ilimit, typelabels[functions]); limit = (unsigned int)ilimit; } else @@ -10825,7 +10825,7 @@ void ACSProfile(FLevelLocals *Level, FCommandLine &argv) static const uint8_t sort_match_len[] = { 1, 2, 2, 1, 1 }; TArray ScriptProfiles, FuncProfiles; - long limit = 10; + int limit = 10; int (*sorter)(const void *, const void *) = sort_by_total_instr; assert(countof(sort_names) == countof(sort_match_len)); @@ -10847,7 +10847,7 @@ void ACSProfile(FLevelLocals *Level, FCommandLine &argv) { // If it's a number, set the display limit. char *endptr; - long num = strtol(argv[i], &endptr, 0); + int num = (int)strtoll(argv[i], &endptr, 0); if (endptr != argv[i]) { limit = num; diff --git a/src/rendering/hwrenderer/scene/hw_portal.cpp b/src/rendering/hwrenderer/scene/hw_portal.cpp index aaf7ae06c..18de9babf 100644 --- a/src/rendering/hwrenderer/scene/hw_portal.cpp +++ b/src/rendering/hwrenderer/scene/hw_portal.cpp @@ -107,7 +107,7 @@ void FPortalSceneState::EndFrame(HWDrawInfo *di, FRenderState &state) if (gl_portalinfo) { - indent.Truncate(long(indent.Len()-2)); + indent.Truncate(indent.Len()-2); Printf("%s}\n", indent.GetChars()); if (indent.Len() == 0) gl_portalinfo = false; } diff --git a/src/utility/nodebuilder/nodebuild_utility.cpp b/src/utility/nodebuilder/nodebuild_utility.cpp index 30ead3424..de3e32759 100644 --- a/src/utility/nodebuilder/nodebuild_utility.cpp +++ b/src/utility/nodebuilder/nodebuild_utility.cpp @@ -460,7 +460,7 @@ void FNodeBuilder::FindPolyContainers (TArray &spots, TArray= 0) { closestdist = dist; - closestseg = (long)j; + closestseg = j; } } } From 3e7de9aafa92e317b20c0accb4a93b51cd9cffa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Thu, 5 Oct 2023 11:40:28 -0300 Subject: [PATCH 172/223] Fix inheritance for bNoSaveGame --- src/gamedata/info.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gamedata/info.cpp b/src/gamedata/info.cpp index 2e0109db4..5942ae2d3 100644 --- a/src/gamedata/info.cpp +++ b/src/gamedata/info.cpp @@ -487,6 +487,8 @@ void PClassActor::InitializeDefaults() { memset(Defaults + ParentClass->Size, 0, Size - ParentClass->Size); } + + optr->ObjectFlags = ((DObject*)ParentClass->Defaults)->ObjectFlags & OF_Transient; } else { From 29368f0f4e182580c60cb5dbee44fe0f0a001159 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Thu, 5 Oct 2023 12:29:20 -0400 Subject: [PATCH 173/223] - make zs Actor.GetReplacement and Actor.GetReplacee clearscope --- wadsrc/static/zscript/actors/actor.zs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wadsrc/static/zscript/actors/actor.zs b/wadsrc/static/zscript/actors/actor.zs index 17949c18f..52085804c 100644 --- a/wadsrc/static/zscript/actors/actor.zs +++ b/wadsrc/static/zscript/actors/actor.zs @@ -645,8 +645,8 @@ class Actor : Thinker native virtual void PostTeleport( Vector3 destpos, double destangle, int flags ) {} native virtual bool OkayToSwitchTarget(Actor other); - native static class GetReplacement(class cls); - native static class GetReplacee(class cls); + native clearscope static class GetReplacement(class cls); + native clearscope static class GetReplacee(class cls); native static int GetSpriteIndex(name sprt); native clearscope static double GetDefaultSpeed(class type); native static class GetSpawnableType(int spawnnum); From 766c61b3edbeabcad29959465e0a7b02afd5573d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Fri, 10 Feb 2023 23:35:54 -0300 Subject: [PATCH 174/223] Deduplicate Map/MapIterator Types' Code --- src/common/scripting/core/types.cpp | 329 +++++----------------------- 1 file changed, 55 insertions(+), 274 deletions(-) diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index 078845d6d..9f777da38 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -2377,60 +2377,50 @@ void PMap::GetTypeIDs(intptr_t &id1, intptr_t &id2) const // //========================================================================== +#define FOR_EACH_MAP_TYPE(FN) \ + case PMap::MAP_I32_I8: \ + FN( uint32_t , uint8_t ) \ + case PMap::MAP_I32_I16: \ + FN( uint32_t , uint16_t ) \ + case PMap::MAP_I32_I32: \ + FN( uint32_t , uint32_t ) \ + case PMap::MAP_I32_F32: \ + FN( uint32_t , float ) \ + case PMap::MAP_I32_F64: \ + FN( uint32_t , double ) \ + case PMap::MAP_I32_OBJ: \ + FN( uint32_t , DObject* ) \ + case PMap::MAP_I32_PTR: \ + FN( uint32_t , void* ) \ + case PMap::MAP_I32_STR: \ + FN( uint32_t , FString ) \ + case PMap::MAP_STR_I8: \ + FN( FString , uint8_t ) \ + case PMap::MAP_STR_I16: \ + FN( FString , uint16_t ) \ + case PMap::MAP_STR_I32: \ + FN( FString , uint32_t ) \ + case PMap::MAP_STR_F32: \ + FN( FString , float ) \ + case PMap::MAP_STR_F64: \ + FN( FString , double ) \ + case PMap::MAP_STR_OBJ: \ + FN( FString , DObject* ) \ + case PMap::MAP_STR_PTR: \ + FN( FString , void* ) \ + case PMap::MAP_STR_STR: \ + FN( FString , FString ) + void PMap::Construct(void * addr) const { switch(BackingClass) { - case MAP_I32_I8: - new(addr) ZSMap(); - break; - case MAP_I32_I16: - new(addr) ZSMap(); - break; - case MAP_I32_I32: - new(addr) ZSMap(); - break; - case MAP_I32_F32: - new(addr) ZSMap(); - break; - case MAP_I32_F64: - new(addr) ZSMap(); - break; - case MAP_I32_OBJ: - new(addr) ZSMap(); - break; - case MAP_I32_PTR: - new(addr) ZSMap(); - break; - case MAP_I32_STR: - new(addr) ZSMap(); - break; - case MAP_STR_I8: - new(addr) ZSMap(); - break; - case MAP_STR_I16: - new(addr) ZSMap(); - break; - case MAP_STR_I32: - new(addr) ZSMap(); - break; - case MAP_STR_F32: - new(addr) ZSMap(); - break; - case MAP_STR_F64: - new(addr) ZSMap(); - break; - case MAP_STR_OBJ: - new(addr) ZSMap(); - break; - case MAP_STR_PTR: - new(addr) ZSMap(); - break; - case MAP_STR_STR: - new(addr) ZSMap(); - break; + #define MAP_CONSTRUCT(KT, VT) new(addr) ZSMap< KT, VT >(); break; + FOR_EACH_MAP_TYPE(MAP_CONSTRUCT) + #undef MAP_CONSTRUCT }; } + void PMap::InitializeValue(void *addr, const void *def) const { Construct(addr); @@ -2446,54 +2436,9 @@ void PMap::DestroyValue(void *addr) const { switch(BackingClass) { - case MAP_I32_I8: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_I32_I16: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_I32_I32: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_I32_F32: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_I32_F64: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_I32_OBJ: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_I32_PTR: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_I32_STR: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_STR_I8: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_STR_I16: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_STR_I32: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_STR_F32: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_STR_F64: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_STR_OBJ: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_STR_PTR: - static_cast*>(addr)->~ZSMap(); - break; - case MAP_STR_STR: - static_cast*>(addr)->~ZSMap(); - break; + #define MAP_DESTRUCT(KT, VT) static_cast*>(addr)->~ZSMap(); break; + FOR_EACH_MAP_TYPE(MAP_DESTRUCT) + #undef MAP_DESTRUCT } } @@ -2568,54 +2513,9 @@ void PMap::WriteValue(FSerializer &ar, const char *key, const void *addr) const { switch(BackingClass) { - case MAP_I32_I8: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_I32_I16: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_I32_I32: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_I32_F32: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_I32_F64: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_I32_OBJ: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_I32_PTR: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_I32_STR: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_STR_I8: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_STR_I16: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_STR_I32: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_STR_F32: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_STR_F64: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_STR_OBJ: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_STR_PTR: - PMapValueWriter(ar, static_cast*>(addr), this); - break; - case MAP_STR_STR: - PMapValueWriter(ar, static_cast*>(addr), this); - break; + #define MAP_WRITE(KT, VT) PMapValueWriter(ar, static_cast*>(addr), this); break; + FOR_EACH_MAP_TYPE(MAP_WRITE) + #undef MAP_WRITE } ar.EndObject(); } @@ -2668,38 +2568,9 @@ bool PMap::ReadValue(FSerializer &ar, const char *key, void *addr) const { switch(BackingClass) { - case MAP_I32_I8: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_I32_I16: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_I32_I32: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_I32_F32: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_I32_F64: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_I32_OBJ: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_I32_PTR: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_I32_STR: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_STR_I8: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_STR_I16: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_STR_I32: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_STR_F32: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_STR_F64: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_STR_OBJ: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_STR_PTR: - return PMapValueReader(ar, static_cast*>(addr), this); - case MAP_STR_STR: - return PMapValueReader(ar, static_cast*>(addr), this); + #define MAP_READ(KT, VT) return PMapValueReader(ar, static_cast*>(addr), this); + FOR_EACH_MAP_TYPE(MAP_READ) + #undef MAP_READ } } return false; @@ -2790,11 +2661,11 @@ PMap *NewMap(PType *keyType, PType *valueType) return (PMap *)mapType; } -/* PMap *******************************************************************/ +/* PMapIterator ***********************************************************/ //========================================================================== // -// PMap - Parameterized Constructor +// PMapIterator - Parameterized Constructor // //========================================================================== @@ -2844,54 +2715,9 @@ void PMapIterator::GetTypeIDs(intptr_t &id1, intptr_t &id2) const void PMapIterator::Construct(void * addr) const { switch(BackingClass) { - case PMap::MAP_I32_I8: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_I32_I16: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_I32_I32: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_I32_F32: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_I32_F64: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_I32_OBJ: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_I32_PTR: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_I32_STR: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_STR_I8: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_STR_I16: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_STR_I32: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_STR_F32: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_STR_F64: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_STR_OBJ: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_STR_PTR: - new(addr) ZSMapIterator(); - break; - case PMap::MAP_STR_STR: - new(addr) ZSMapIterator(); - break; + #define MAP_IT_CONSTRUCT(KT, VT) new(addr) ZSMapIterator< KT, VT >(); break; + FOR_EACH_MAP_TYPE(MAP_IT_CONSTRUCT) + #undef MAP_IT_CONSTRUCT }; } @@ -2910,54 +2736,9 @@ void PMapIterator::DestroyValue(void *addr) const { switch(BackingClass) { - case PMap::MAP_I32_I8: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_I32_I16: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_I32_I32: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_I32_F32: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_I32_F64: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_I32_OBJ: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_I32_PTR: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_I32_STR: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_STR_I8: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_STR_I16: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_STR_I32: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_STR_F32: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_STR_F64: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_STR_OBJ: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_STR_PTR: - static_cast*>(addr)->~ZSMapIterator(); - break; - case PMap::MAP_STR_STR: - static_cast*>(addr)->~ZSMapIterator(); - break; + #define MAP_IT_DESTROY(KT, VT) static_cast*>(addr)->~ZSMapIterator(); break; + FOR_EACH_MAP_TYPE(MAP_IT_DESTROY) + #undef MAP_IT_DESTROY } } From 87fcaab5124ff8e135bf7ab3eb51ee47013114a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 22 Feb 2023 13:26:49 -0300 Subject: [PATCH 175/223] Fix Typo in Comment --- src/common/scripting/frontend/zcc_parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/scripting/frontend/zcc_parser.cpp b/src/common/scripting/frontend/zcc_parser.cpp index 6ba675744..7dd86fba0 100644 --- a/src/common/scripting/frontend/zcc_parser.cpp +++ b/src/common/scripting/frontend/zcc_parser.cpp @@ -52,7 +52,7 @@ static FString ResolveIncludePath(const FString &path,const FString &lumpname){ auto end = lumpname.LastIndexOf("/"); // find last '/' - // it's a top-level file, if it's a folder being loaded ( /xxx/yyy/:whatever.zs ) end is before than start, or if it's a zip ( xxx.zip/whatever.zs ) end would be -1 + // it's a top-level file, if it's a folder being loaded ( /xxx/yyy/:whatever.zs ) end is before than start, or if it's a zip ( xxx.zip:whatever.zs ) end would be -1 bool topLevelFile = start > end ; FString fullPath = topLevelFile ? FString {} : lumpname.Mid(start + 1, end - start - 1); // get path from lumpname (format 'wad:filepath/filename') From 3fc195c5b27ea82d20beae504b01d947c19bbdda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 22 Feb 2023 15:43:32 -0300 Subject: [PATCH 176/223] Improve handling of field names in error messages during Map/MapIterator compilation --- src/common/scripting/frontend/zcc_compile.cpp | 50 +++++++++++-------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index db69835f8..a21fd210a 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -1866,19 +1866,17 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n auto keytype = DetermineType(outertype, field, name, mtype->KeyType, false, false); auto valuetype = DetermineType(outertype, field, name, mtype->ValueType, false, false); - if (keytype->GetRegType() == REGT_INT) + if (keytype->GetRegType() != REGT_STRING && !(keytype->GetRegType() == REGT_INT && keytype->Size == 4)) { - if (keytype->Size != 4) + if(name != NAME_None) + { + Error(field, "%s : Map<%s , ...> not implemented yet", name.GetChars(), keytype->DescriptiveName()); + } + else { Error(field, "Map<%s , ...> not implemented yet", keytype->DescriptiveName()); - break; } } - else if (keytype->GetRegType() != REGT_STRING) - { - Error(field, "Map<%s , ...> not implemented yet", keytype->DescriptiveName()); - break; - } switch(valuetype->GetRegType()) { @@ -1888,14 +1886,20 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n case REGT_POINTER: if (valuetype->GetRegCount() > 1) { - Error(field, "%s : Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName()); + default: + if(name != NAME_None) + { + Error(field, "%s : Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName()); + } + else + { + Error(field, "Base type for map value types must be integral, but got %s", valuetype->DescriptiveName()); + } break; } retval = NewMap(keytype, valuetype); break; - default: - Error(field, "%s: Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName()); } break; @@ -1913,17 +1917,17 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n auto keytype = DetermineType(outertype, field, name, mtype->KeyType, false, false); auto valuetype = DetermineType(outertype, field, name, mtype->ValueType, false, false); - if (keytype->GetRegType() == REGT_INT) + if (keytype->GetRegType() != REGT_STRING && !(keytype->GetRegType() == REGT_INT && keytype->Size == 4)) { - if (keytype->Size != 4) + if(name != NAME_None) + { + Error(field, "%s : MapIterator<%s , ...> not implemented yet", name.GetChars(), keytype->DescriptiveName()); + } + else { Error(field, "MapIterator<%s , ...> not implemented yet", keytype->DescriptiveName()); } } - else if (keytype->GetRegType() != REGT_STRING) - { - Error(field, "MapIterator<%s , ...> not implemented yet", keytype->DescriptiveName()); - } switch(valuetype->GetRegType()) { @@ -1933,13 +1937,19 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n case REGT_POINTER: if (valuetype->GetRegCount() > 1) { - Error(field, "%s : Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName()); + default: + if(name != NAME_None) + { + Error(field, "%s : Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName()); + } + else + { + Error(field, "Base type for map value types must be integral, but got %s", valuetype->DescriptiveName()); + } break; } retval = NewMapIterator(keytype, valuetype); break; - default: - Error(field, "%s: Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName()); } break; } From fad350ff80d7aae133663b78be9678e44211f696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Thu, 23 Feb 2023 13:31:30 -0300 Subject: [PATCH 177/223] Make sure maps in return type don't segfault --- src/common/scripting/frontend/zcc_compile.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index a21fd210a..216657895 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -2254,6 +2254,11 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool Error(f, "The return type of a function cannot be a dynamic array"); break; } + else if (type->isMap()) + { + Error(f, "The return type of a function cannot be a map"); + break; + } else if (type == TypeFVector2) { type = TypeVector2; From 86e4d064e2955468a218c39599a2e4ffeb2d875a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 5 Mar 2023 12:19:36 -0300 Subject: [PATCH 178/223] fix possible null dereference in FxStructMember::RequestAddress --- src/common/scripting/backend/codegen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 08668dd51..8932d91d6 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -7180,7 +7180,7 @@ bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable) if (membervar->Flags & VARF_Meta) { // Meta variables are read only. - *writable = false; + if(writable != nullptr) *writable = false; } else if (writable != nullptr) { From b60b3fc09af13dddef80778353a220366b3b953a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 26 Mar 2023 01:31:07 -0300 Subject: [PATCH 179/223] fix PStruct::AddField not passing mDefFileNo --- src/common/scripting/core/types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index 9f777da38..6543dde9e 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -2957,7 +2957,7 @@ bool PStruct::ReadValue(FSerializer &ar, const char *key, void *addr) const PField *PStruct::AddField(FName name, PType *type, uint32_t flags) { assert(type->Size > 0); - return Symbols.AddField(name, type, flags, Size, &Align); + return Symbols.AddField(name, type, flags, Size, &Align, mDefFileNo); } //========================================================================== From 65ea4f91b66093f28bdfe6809aebbf9c348c60d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 1 Apr 2023 01:04:43 -0300 Subject: [PATCH 180/223] fix TMap move insertion, was using the copy constructor due to a missing std::move --- src/common/utility/tarray.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/utility/tarray.h b/src/common/utility/tarray.h index 3d49f1868..feb361bf8 100644 --- a/src/common/utility/tarray.h +++ b/src/common/utility/tarray.h @@ -1128,12 +1128,12 @@ public: Node *n = FindKey(key); if (n != NULL) { - n->Pair.Value = value; + n->Pair.Value = std::move(value); } else { n = NewKey(key); - ::new(&n->Pair.Value) VT(value); + ::new(&n->Pair.Value) VT(std::move(value)); } return n->Pair.Value; } From fa8df5a4e5698224ba6024b075b72893956ac0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 1 Apr 2023 22:32:30 -0300 Subject: [PATCH 181/223] make Array::Append faster for simple structs This makes appending arrays of simple types faster --- src/common/utility/tarray.h | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/common/utility/tarray.h b/src/common/utility/tarray.h index feb361bf8..c377f330b 100644 --- a/src/common/utility/tarray.h +++ b/src/common/utility/tarray.h @@ -399,9 +399,16 @@ public: Grow(item.Size()); Count += item.Size(); - for (unsigned i = 0; i < item.Size(); i++) + if constexpr (std::is_trivially_copyable::value) { - new(&Array[start + i]) T(item[i]); + memcpy(Array + start,item.Array,item.Size() * sizeof(T)); + } + else + { + for (unsigned i = 0; i < item.Size(); i++) + { + new(&Array[start + i]) T(item[i]); + } } return start; } @@ -413,9 +420,16 @@ public: Grow(item.Size()); Count += item.Size(); - for (unsigned i = 0; i < item.Size(); i++) + if constexpr (std::is_trivially_copyable::value) { - new(&Array[start + i]) T(std::move(item[i])); + memcpy(Array + start,item.Array,item.Size() * sizeof(T)); + } + else + { + for (unsigned i = 0; i < item.Size(); i++) + { + new(&Array[start + i]) T(std::move(item[i])); + } } item.Clear(); return start; From 3cb8f1be44d9eacbda2d0ced20d47597bd139947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 2 Apr 2023 08:21:45 -0300 Subject: [PATCH 182/223] Don't try to generate code for abstract functions during JIT dump --- src/common/scripting/jit/jit.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/common/scripting/jit/jit.cpp b/src/common/scripting/jit/jit.cpp index 27b69cac4..7ccd1a733 100644 --- a/src/common/scripting/jit/jit.cpp +++ b/src/common/scripting/jit/jit.cpp @@ -44,6 +44,13 @@ void JitDumpLog(FILE *file, VMScriptFunction *sfunc) { using namespace asmjit; StringLogger logger; + + if(sfunc->VarFlags & VARF_Abstract) + { + // Printf(TEXTCOLOR_ORANGE "Skipping abstract function during JIT dump: %s\n", sfunc->PrintableName.GetChars()); + return; + } + try { ThrowingErrorHandler errorHandler; From 7a9ca1ad3ffc7968f80d16ca190789f20ee81d5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 2 Apr 2023 08:30:49 -0300 Subject: [PATCH 183/223] Allow dumping jit for mod functions only --- src/common/scripting/backend/vmbuilder.cpp | 11 ++++++++--- src/common/scripting/backend/vmbuilder.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/common/scripting/backend/vmbuilder.cpp b/src/common/scripting/backend/vmbuilder.cpp index ffd29d4dd..d063790d2 100644 --- a/src/common/scripting/backend/vmbuilder.cpp +++ b/src/common/scripting/backend/vmbuilder.cpp @@ -37,6 +37,7 @@ #include "m_argv.h" #include "c_cvars.h" #include "jit.h" +#include "filesystem.h" CVAR(Bool, strictdecorate, false, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) @@ -922,13 +923,17 @@ void FFunctionBuildList::Build() VMFunction::CreateRegUseInfo(); FScriptPosition::StrictErrors = strictdecorate; - if (FScriptPosition::ErrorCounter == 0 && Args->CheckParm("-dumpjit")) DumpJit(); + if (FScriptPosition::ErrorCounter == 0) + { + if (Args->CheckParm("-dumpjit")) DumpJit(true); + else if (Args->CheckParm("-dumpjitmod")) DumpJit(false); + } mItems.Clear(); mItems.ShrinkToFit(); FxAlloc.FreeAllBlocks(); } -void FFunctionBuildList::DumpJit() +void FFunctionBuildList::DumpJit(bool include_gzdoom_pk3) { #ifdef HAVE_VM_JIT FILE *dump = fopen("dumpjit.txt", "w"); @@ -937,7 +942,7 @@ void FFunctionBuildList::DumpJit() for (auto &item : mItems) { - JitDumpLog(dump, item.Function); + if(include_gzdoom_pk3 || fileSystem.GetFileContainer(item.Lump)) JitDumpLog(dump, item.Function); } fclose(dump); diff --git a/src/common/scripting/backend/vmbuilder.h b/src/common/scripting/backend/vmbuilder.h index 8bb43565e..43ef1bc4c 100644 --- a/src/common/scripting/backend/vmbuilder.h +++ b/src/common/scripting/backend/vmbuilder.h @@ -155,7 +155,7 @@ class FFunctionBuildList TArray mItems; - void DumpJit(); + void DumpJit(bool include_gzdoom_pk3); public: VMFunction *AddFunction(PNamespace *curglobals, const VersionInfo &ver, PFunction *func, FxExpression *code, const FString &name, bool fromdecorate, int currentstate, int statecnt, int lumpnum); From a13b19815ce7510f388ef55851f604c4aedd5ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 7 Oct 2023 11:30:28 -0300 Subject: [PATCH 184/223] allow "&" instead of "out" in function parameters --- src/common/scripting/frontend/zcc-parse.lemon | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/common/scripting/frontend/zcc-parse.lemon b/src/common/scripting/frontend/zcc-parse.lemon index 71385c582..db41d42a6 100644 --- a/src/common/scripting/frontend/zcc-parse.lemon +++ b/src/common/scripting/frontend/zcc-parse.lemon @@ -1285,6 +1285,26 @@ func_param(X) ::= func_param_flags(A) type(B) IDENTIFIER(C) EQ expr(D). X = parm; } +func_param(X) ::= func_param_flags(A) type(B) AND IDENTIFIER(C). +{ + NEW_AST_NODE(FuncParamDecl,parm,A.SourceLoc ? A.SourceLoc : B->SourceLoc); + parm->Type = B; + parm->Name = C.Name(); + parm->Flags = A.Int | ZCC_Out; + parm->Default = nullptr; + X = parm; +} + +func_param(X) ::= func_param_flags(A) type(B) AND IDENTIFIER(C) EQ expr(D). +{ + NEW_AST_NODE(FuncParamDecl,parm,A.SourceLoc ? A.SourceLoc : B->SourceLoc); + parm->Type = B; + parm->Name = C.Name(); + parm->Flags = A.Int | ZCC_Out; + parm->Default = D; + X = parm; +} + func_param_flags(X) ::= . { X.Int = 0; X.SourceLoc = 0; } func_param_flags(X) ::= func_param_flags(A) IN(T). { X.Int = A.Int | ZCC_In; X.SourceLoc = T.SourceLoc; } func_param_flags(X) ::= func_param_flags(A) OUT(T). { X.Int = A.Int | ZCC_Out; X.SourceLoc = T.SourceLoc; } From b9104e8aa9e0244ad9530d63910628c44fd076b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 5 Mar 2023 12:20:35 -0300 Subject: [PATCH 185/223] Turn Map/Array assignments into Copy Better error checking for struct assignment Lock assignments behind version, don't break or "fix" existing code using older ZScript versions --- src/common/scripting/backend/codegen.cpp | 117 +++++++++++++++++++---- 1 file changed, 98 insertions(+), 19 deletions(-) diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 8932d91d6..758f3cd6c 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -2454,7 +2454,17 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx) SAFE_RESOLVE(Right, ctx); } } - else if (Base->ValueType == Right->ValueType) + else if (Right->IsNativeStruct() && Base->ValueType->isRealPointer() && Base->ValueType->toPointer()->PointedType == Right->ValueType) + { + // allow conversion of native structs to pointers of the same type. This is necessary to assign elements from global arrays like players, sectors, etc. to local pointers. + // For all other types this is not needed. Structs are not assignable and classes can only exist as references. + Right->RequestAddress(ctx, nullptr); + Right->ValueType = Base->ValueType; + } + else if ( Base->ValueType == Right->ValueType + || (Base->ValueType->isRealPointer() && Base->ValueType->toPointer()->PointedType == Right->ValueType) + || (Right->ValueType->isRealPointer() && Right->ValueType->toPointer()->PointedType == Base->ValueType) + ) { if (Base->ValueType->isArray()) { @@ -2462,28 +2472,97 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx) delete this; return nullptr; } - else if (Base->IsDynamicArray()) + else if(!Base->IsVector() && !Base->IsQuaternion()) { - ScriptPosition.Message(MSG_ERROR, "Cannot assign dynamic arrays, use Copy() or Move() function instead"); - delete this; - return nullptr; - } - if (!Base->IsVector() && !Base->IsQuaternion() && Base->ValueType->isStruct()) - { - ScriptPosition.Message(MSG_ERROR, "Struct assignment not implemented yet"); - delete this; - return nullptr; + PType * btype = Base->ValueType; + + if(btype->isRealPointer()) + { + PType * p = static_cast(btype)->PointedType; + if( p->isDynArray() || p->isMap() + || (p->isStruct() && !static_cast(p)->isNative) + ) + { //un-pointer dynarrays, maps and non-native structs for assignment checking + btype = p; + } + } + + if (btype->isDynArray()) + { + if(ctx.Version >= MakeVersion(4, 11, 0)) + { + FArgumentList args; + args.Push(Right); + auto call = new FxMemberFunctionCall(Base, NAME_Copy, args, ScriptPosition); + Right = Base = nullptr; + delete this; + return call->Resolve(ctx); + } + else + { + if(Base->ValueType->isRealPointer() && Right->ValueType->isRealPointer()) + { + ScriptPosition.Message(MSG_WARNING, "Dynamic Array assignments not allowed in ZScript versions below 4.11, use the Copy() or Move() functions instead\n" + TEXTCOLOR_RED "!! Assigning an out array pointer to another out array pointer does not alter either of the underlying arrays' values below ZScript version 4.11 !!"); + } + else + { + ScriptPosition.Message(MSG_ERROR, "Dynamic Array assignments not allowed in ZScript versions below 4.11, use the Copy() or Move() functions instead"); + delete this; + return nullptr; + } + } + } + else if (btype->isMap()) + { + if(ctx.Version >= MakeVersion(4, 11, 0)) + { + FArgumentList args; + args.Push(Right); + auto call = new FxMemberFunctionCall(Base, NAME_Copy, args, ScriptPosition); + Right = Base = nullptr; + delete this; + return call->Resolve(ctx); + } + else + { + if(Base->ValueType->isRealPointer() && Right->ValueType->isRealPointer()) + { // don't break existing code, but warn that it's a no-op + ScriptPosition.Message(MSG_WARNING, "Map assignments not allowed in ZScript versions below 4.11, use the Copy() or Move() functions instead\n" + TEXTCOLOR_RED "!! Assigning an out map pointer to another out map pointer does not alter either of the underlying maps' values below ZScript version 4.11 !!"); + } + else + { + ScriptPosition.Message(MSG_ERROR, "Map assignments not allowed in ZScript versions below 4.11, use the Copy() or Move() functions instead"); + delete this; + return nullptr; + } + } + } + else if (btype->isMapIterator()) + { + ScriptPosition.Message(MSG_ERROR, "Cannot assign map iterators"); + delete this; + return nullptr; + } + else if (btype->isStruct()) + { + if(Base->ValueType->isRealPointer() && Right->ValueType->isRealPointer()) + { // don't break existing code, but warn that it's a no-op + ScriptPosition.Message(MSG_WARNING, "Struct assignment not implemented yet\n" + TEXTCOLOR_RED "!! Assigning an out struct pointer to another out struct pointer does not alter either of the underlying structs' values !!"); + } + else + { + ScriptPosition.Message(MSG_ERROR, "Struct assignment not implemented yet"); + delete this; + return nullptr; + } + } } + // Both types are the same so this is ok. } - else if (Right->IsNativeStruct() && Base->ValueType->isRealPointer() && Base->ValueType->toPointer()->PointedType == Right->ValueType) - { - // allow conversion of native structs to pointers of the same type. This is necessary to assign elements from global arrays like players, sectors, etc. to local pointers. - // For all other types this is not needed. Structs are not assignable and classes can only exist as references. - bool writable; - Right->RequestAddress(ctx, &writable); - Right->ValueType = Base->ValueType; - } else { // pass it to FxTypeCast for complete handling. From 42df40941c3a63b1a8046e6a9b5d2405c5e1caa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 7 Oct 2023 11:44:44 -0300 Subject: [PATCH 186/223] change version, improve errors for array/map/struct copy --- src/common/scripting/backend/codegen.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 758f3cd6c..9711abf72 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -2489,7 +2489,7 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx) if (btype->isDynArray()) { - if(ctx.Version >= MakeVersion(4, 11, 0)) + if(ctx.Version >= MakeVersion(4, 11, 1)) { FArgumentList args; args.Push(Right); @@ -2502,12 +2502,14 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx) { if(Base->ValueType->isRealPointer() && Right->ValueType->isRealPointer()) { - ScriptPosition.Message(MSG_WARNING, "Dynamic Array assignments not allowed in ZScript versions below 4.11, use the Copy() or Move() functions instead\n" - TEXTCOLOR_RED "!! Assigning an out array pointer to another out array pointer does not alter either of the underlying arrays' values below ZScript version 4.11 !!"); + ScriptPosition.Message(MSG_WARNING, "Dynamic Array assignments not allowed in ZScript versions below 4.11.1, use the Copy() or Move() functions instead\n" + TEXTCOLOR_RED " Assigning an out array pointer to another out array pointer\n" + " does not alter either of the underlying arrays' values\n" + " it only swaps the pointers below ZScript version 4.11.1!!"); } else { - ScriptPosition.Message(MSG_ERROR, "Dynamic Array assignments not allowed in ZScript versions below 4.11, use the Copy() or Move() functions instead"); + ScriptPosition.Message(MSG_ERROR, "Dynamic Array assignments not allowed in ZScript versions below 4.11.1, use the Copy() or Move() functions instead"); delete this; return nullptr; } @@ -2515,7 +2517,7 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx) } else if (btype->isMap()) { - if(ctx.Version >= MakeVersion(4, 11, 0)) + if(ctx.Version >= MakeVersion(4, 11, 1)) { FArgumentList args; args.Push(Right); @@ -2528,12 +2530,14 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx) { if(Base->ValueType->isRealPointer() && Right->ValueType->isRealPointer()) { // don't break existing code, but warn that it's a no-op - ScriptPosition.Message(MSG_WARNING, "Map assignments not allowed in ZScript versions below 4.11, use the Copy() or Move() functions instead\n" - TEXTCOLOR_RED "!! Assigning an out map pointer to another out map pointer does not alter either of the underlying maps' values below ZScript version 4.11 !!"); + ScriptPosition.Message(MSG_WARNING, "Map assignments not allowed in ZScript versions below 4.11.1, use the Copy() or Move() functions instead\n" + TEXTCOLOR_RED " Assigning an out map pointer to another out map pointer\n" + " does not alter either of the underlying maps' values\n" + " it only swaps the pointers below ZScript version 4.11.1!!"); } else { - ScriptPosition.Message(MSG_ERROR, "Map assignments not allowed in ZScript versions below 4.11, use the Copy() or Move() functions instead"); + ScriptPosition.Message(MSG_ERROR, "Map assignments not allowed in ZScript versions below 4.11.1, use the Copy() or Move() functions instead"); delete this; return nullptr; } @@ -2550,7 +2554,9 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx) if(Base->ValueType->isRealPointer() && Right->ValueType->isRealPointer()) { // don't break existing code, but warn that it's a no-op ScriptPosition.Message(MSG_WARNING, "Struct assignment not implemented yet\n" - TEXTCOLOR_RED "!! Assigning an out struct pointer to another out struct pointer does not alter either of the underlying structs' values !!"); + TEXTCOLOR_RED " Assigning an out struct pointer to another out struct pointer\n" + " does not alter either of the underlying structs' values\n" + " it only swaps the pointers!!"); } else { From 5e96dbc9817ce24ed092db42ecebc3f01f1b93c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 1 Oct 2023 18:36:42 -0300 Subject: [PATCH 187/223] Add final and sealed as class options --- src/common/engine/sc_man_scanner.re | 1 + src/common/engine/sc_man_tokens.h | 1 + src/common/objects/dobjtype.h | 3 ++ src/common/scripting/frontend/zcc-parse.lemon | 18 +++++---- src/common/scripting/frontend/zcc_compile.cpp | 38 ++++++++++++++++++- src/common/scripting/frontend/zcc_parser.cpp | 1 + src/common/scripting/frontend/zcc_parser.h | 2 + 7 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/common/engine/sc_man_scanner.re b/src/common/engine/sc_man_scanner.re index b5cce6d09..dfc3f050f 100644 --- a/src/common/engine/sc_man_scanner.re +++ b/src/common/engine/sc_man_scanner.re @@ -204,6 +204,7 @@ std2: 'stop' { RET(TK_Stop); } 'null' { RET(TK_Null); } 'nullptr' { RET(ParseVersion >= MakeVersion(4, 9, 0)? TK_Null : TK_Identifier); } + 'sealed' { RET(ParseVersion >= MakeVersion(4, 12, 0)? TK_Sealed : TK_Identifier); } 'is' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Is : TK_Identifier); } 'replaces' { RET(ParseVersion >= MakeVersion(1, 0, 0)? TK_Replaces : TK_Identifier); } diff --git a/src/common/engine/sc_man_tokens.h b/src/common/engine/sc_man_tokens.h index d93e5be62..8fb2f88e3 100644 --- a/src/common/engine/sc_man_tokens.h +++ b/src/common/engine/sc_man_tokens.h @@ -122,6 +122,7 @@ xx(TK_Null, "'null'") xx(TK_Global, "'global'") xx(TK_Stop, "'stop'") xx(TK_Include, "'include'") +xx(TK_Sealed, "'sealed'") xx(TK_Is, "'is'") xx(TK_Replaces, "'replaces'") diff --git a/src/common/objects/dobjtype.h b/src/common/objects/dobjtype.h index c8464a030..81fbe3aac 100644 --- a/src/common/objects/dobjtype.h +++ b/src/common/objects/dobjtype.h @@ -66,11 +66,14 @@ public: bool bRuntimeClass = false; // class was defined at run-time, not compile-time bool bDecorateClass = false; // may be subject to some idiosyncracies due to DECORATE backwards compatibility bool bAbstract = false; + bool bSealed = false; + bool bFinal = false; bool bOptional = false; TArray Virtuals; // virtual function table TArray MetaInits; TArray SpecialInits; TArray Fields; + TArray SealedRestriction; PClassType *VMType = nullptr; void (*ConstructNative)(void *); diff --git a/src/common/scripting/frontend/zcc-parse.lemon b/src/common/scripting/frontend/zcc-parse.lemon index db41d42a6..d25820dda 100644 --- a/src/common/scripting/frontend/zcc-parse.lemon +++ b/src/common/scripting/frontend/zcc-parse.lemon @@ -78,6 +78,7 @@ static void SetNodeLine(ZCC_TreeNode *name, int line) struct ClassFlagsBlock { VM_UWORD Flags; ZCC_Identifier *Replaces; + ZCC_Identifier *Sealed; VersionInfo Version; }; @@ -242,6 +243,7 @@ class_head(X) ::= CLASS(T) IDENTIFIER(A) class_ancestry(B) class_flags(C). head->ParentName = B; head->Flags = C.Flags; head->Replaces = C.Replaces; + head->Sealed = C.Sealed; head->Version = C.Version; head->Type = nullptr; head->Symbol = nullptr; @@ -253,13 +255,15 @@ class_ancestry(X) ::= . { X = NULL; } class_ancestry(X) ::= COLON dottable_id(A). { X = A; /*X-overwrites-A*/ } %type class_flags{ClassFlagsBlock} -class_flags(X) ::= . { X.Flags = 0; X.Replaces = NULL; X.Version = {0,0}; } -class_flags(X) ::= class_flags(A) ABSTRACT. { X.Flags = A.Flags | ZCC_Abstract; X.Replaces = A.Replaces; } -class_flags(X) ::= class_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; X.Replaces = A.Replaces; } -class_flags(X) ::= class_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; X.Replaces = A.Replaces; } -class_flags(X) ::= class_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; X.Replaces = A.Replaces; } -class_flags(X) ::= class_flags(A) REPLACES dottable_id(B). { X.Flags = A.Flags; X.Replaces = B; } -class_flags(X) ::= class_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Replaces = A.Replaces; X.Version = C.String->GetChars(); } +class_flags(X) ::= . { X.Flags = 0; X.Replaces = NULL; X.Version = {0,0}; X.Sealed = NULL; } +class_flags(X) ::= class_flags(A) ABSTRACT. { X.Flags = A.Flags | ZCC_Abstract; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; } +class_flags(X) ::= class_flags(A) FINAL. { X.Flags = A.Flags | ZCC_Final; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed;} +class_flags(X) ::= class_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; } +class_flags(X) ::= class_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; } +class_flags(X) ::= class_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; } +class_flags(X) ::= class_flags(A) REPLACES dottable_id(B). { X.Flags = A.Flags; X.Replaces = B; X.Version = A.Version; X.Sealed = A.Sealed; } +class_flags(X) ::= class_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Replaces = A.Replaces; X.Version = C.String->GetChars(); X.Sealed = A.Sealed; } +class_flags(X) ::= class_flags(A) SEALED LPAREN states_opt(B) RPAREN. { X.Flags = A.Flags | ZCC_Sealed; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = B; } /*----- Dottable Identifier -----*/ // This can be either a single identifier or two identifiers connected by a . diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index 216657895..b43e9622f 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -792,8 +792,14 @@ void ZCCCompiler::CreateClassTypes() PClass *parent; auto ParentName = c->cls->ParentName; - if (ParentName != nullptr && ParentName->SiblingNext == ParentName) parent = PClass::FindClass(ParentName->Id); - else if (ParentName == nullptr) parent = RUNTIME_CLASS(DObject); + if (ParentName != nullptr && ParentName->SiblingNext == ParentName) + { + parent = PClass::FindClass(ParentName->Id); + } + else if (ParentName == nullptr) + { + parent = RUNTIME_CLASS(DObject); + } else { // The parent is a dotted name which the type system currently does not handle. @@ -813,6 +819,15 @@ void ZCCCompiler::CreateClassTypes() if (parent != nullptr && (parent->VMType != nullptr || c->NodeName() == NAME_Object)) { + if(parent->bFinal) + { + Error(c->cls, "Class '%s' cannot extend final class '%s'", FName(c->NodeName()).GetChars(), parent->TypeName.GetChars()); + } + else if(parent->bSealed && !parent->SealedRestriction.Contains(c->NodeName())) + { + Error(c->cls, "Class '%s' cannot extend sealed class '%s'", FName(c->NodeName()).GetChars(), parent->TypeName.GetChars()); + } + // The parent exists, we may create a type for this class if (c->cls->Flags & ZCC_Native) { @@ -874,6 +889,25 @@ void ZCCCompiler::CreateClassTypes() { c->Type()->mVersion = c->cls->Version; } + + + if (c->cls->Flags & ZCC_Final) + { + c->ClassType()->bFinal = true; + } + + if (c->cls->Flags & ZCC_Sealed) + { + PClass * ccls = c->ClassType(); + ccls->bSealed = true; + ZCC_Identifier * it = c->cls->Sealed; + if(it) do + { + ccls->SealedRestriction.Push(FName(it->Id)); + it = (ZCC_Identifier*) it->SiblingNext; + } + while(it != c->cls->Sealed); + } // if (mVersion >= MakeVersion(2, 4, 0)) { diff --git a/src/common/scripting/frontend/zcc_parser.cpp b/src/common/scripting/frontend/zcc_parser.cpp index 7dd86fba0..e689d4249 100644 --- a/src/common/scripting/frontend/zcc_parser.cpp +++ b/src/common/scripting/frontend/zcc_parser.cpp @@ -232,6 +232,7 @@ static void InitTokenMap() TOKENDEF (TK_Out, ZCC_OUT); TOKENDEF (TK_Super, ZCC_SUPER); TOKENDEF (TK_Null, ZCC_NULLPTR); + TOKENDEF (TK_Sealed, ZCC_SEALED); TOKENDEF ('~', ZCC_TILDE); TOKENDEF ('!', ZCC_BANG); TOKENDEF (TK_SizeOf, ZCC_SIZEOF); diff --git a/src/common/scripting/frontend/zcc_parser.h b/src/common/scripting/frontend/zcc_parser.h index 25a60d9ad..e4e4ea363 100644 --- a/src/common/scripting/frontend/zcc_parser.h +++ b/src/common/scripting/frontend/zcc_parser.h @@ -64,6 +64,7 @@ enum ZCC_VirtualScope = 1 << 20, ZCC_Version = 1 << 21, ZCC_Internal = 1 << 22, + ZCC_Sealed = 1 << 23, }; // Function parameter modifiers @@ -251,6 +252,7 @@ struct ZCC_Class : ZCC_Struct { ZCC_Identifier *ParentName; ZCC_Identifier *Replaces; + ZCC_Identifier *Sealed; PClass *CType() { return static_cast(Type)->Descriptor; } }; From 4497d7fdaa9b0b4520416885c75742bf857bed66 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Sep 2023 01:42:53 +0600 Subject: [PATCH 188/223] Update LZMA SDK to 23.01 As a bonus, add support for XZ-compressed files in ZIP --- libraries/lzma/C/7z.h | 12 +- libraries/lzma/C/7zAlloc.c | 89 + libraries/lzma/C/7zAlloc.h | 19 + libraries/lzma/C/7zArcIn.c | 405 +-- libraries/lzma/C/7zBuf.h | 6 +- libraries/lzma/C/7zBuf2.c | 52 + libraries/lzma/C/7zCrc.c | 130 +- libraries/lzma/C/7zCrc.h | 14 +- libraries/lzma/C/7zCrcOpt.c | 16 +- libraries/lzma/C/7zDec.c | 172 +- libraries/lzma/C/7zFile.c | 443 +++ libraries/lzma/C/7zFile.h | 92 + libraries/lzma/C/7zStream.c | 67 +- libraries/lzma/C/7zTypes.h | 274 +- libraries/lzma/C/7zVersion.h | 10 +- libraries/lzma/C/7zWindows.h | 101 + libraries/lzma/C/Aes.c | 393 +++ libraries/lzma/C/Aes.h | 60 + libraries/lzma/C/AesOpt.c | 840 +++++ libraries/lzma/C/Alloc.c | 535 +++ libraries/lzma/C/Alloc.h | 71 + libraries/lzma/C/Bcj2.c | 325 +- libraries/lzma/C/Bcj2.h | 270 +- libraries/lzma/C/Bcj2Enc.c | 506 +++ libraries/lzma/C/Bra.c | 528 ++- libraries/lzma/C/Bra.h | 117 +- libraries/lzma/C/Bra86.c | 221 +- libraries/lzma/C/BraIA64.c | 57 +- libraries/lzma/C/Compiler.h | 162 +- libraries/lzma/C/CpuArch.c | 847 +++-- libraries/lzma/C/CpuArch.h | 243 +- libraries/lzma/C/Delta.h | 6 +- libraries/lzma/C/DllSecur.c | 111 + libraries/lzma/C/DllSecur.h | 20 + libraries/lzma/C/LzFind.c | 519 +-- libraries/lzma/C/LzFind.h | 53 +- libraries/lzma/C/LzFindMt.c | 70 +- libraries/lzma/C/LzFindMt.h | 10 +- libraries/lzma/C/LzFindOpt.c | 14 +- libraries/lzma/C/LzHash.h | 8 +- libraries/lzma/C/Lzma2Dec.c | 12 +- libraries/lzma/C/Lzma2Dec.h | 15 +- libraries/lzma/C/Lzma2DecMt.c | 1095 +++++++ libraries/lzma/C/Lzma2DecMt.h | 81 + libraries/lzma/C/Lzma2Enc.c | 805 +++++ libraries/lzma/C/Lzma2Enc.h | 57 + libraries/lzma/C/Lzma86.h | 111 + libraries/lzma/C/Lzma86Dec.c | 53 + libraries/lzma/C/Lzma86Enc.c | 103 + libraries/lzma/C/LzmaDec.c | 190 +- libraries/lzma/C/LzmaDec.h | 17 +- libraries/lzma/C/LzmaEnc.c | 389 ++- libraries/lzma/C/LzmaEnc.h | 23 +- libraries/lzma/C/LzmaLib.c | 42 + libraries/lzma/C/LzmaLib.h | 138 + libraries/lzma/C/MtCoder.c | 571 ++++ libraries/lzma/C/MtCoder.h | 141 + libraries/lzma/C/MtDec.c | 1114 +++++++ libraries/lzma/C/MtDec.h | 202 ++ libraries/lzma/C/Ppmd.h | 12 +- libraries/lzma/C/Ppmd7.c | 186 +- libraries/lzma/C/Ppmd7.h | 10 +- libraries/lzma/C/Ppmd7Dec.c | 57 +- libraries/lzma/C/Ppmd7Enc.c | 338 ++ libraries/lzma/C/Precomp.h | 6 +- libraries/lzma/C/RotateDefs.h | 50 + libraries/lzma/C/Sha256.c | 516 +++ libraries/lzma/C/Sha256.h | 76 + libraries/lzma/C/Sha256Opt.c | 386 +++ libraries/lzma/C/Sort.c | 141 + libraries/lzma/C/Sort.h | 18 + libraries/lzma/C/SwapBytes.c | 800 +++++ libraries/lzma/C/SwapBytes.h | 17 + libraries/lzma/C/Threads.c | 86 +- libraries/lzma/C/Threads.h | 50 +- libraries/lzma/C/Xz.c | 90 + libraries/lzma/C/Xz.h | 535 +++ libraries/lzma/C/XzCrc64.c | 80 + libraries/lzma/C/XzCrc64.h | 26 + libraries/lzma/C/XzCrc64Opt.c | 61 + libraries/lzma/C/XzDec.c | 2875 +++++++++++++++++ libraries/lzma/C/XzEnc.c | 1362 ++++++++ libraries/lzma/C/XzEnc.h | 61 + libraries/lzma/C/XzIn.c | 340 ++ libraries/lzma/CMakeLists.txt | 26 + src/common/filesystem/include/fs_files.h | 1 + src/common/filesystem/source/file_7z.cpp | 2 +- src/common/filesystem/source/file_zip.cpp | 4 +- .../filesystem/source/files_decompress.cpp | 151 + 89 files changed, 19298 insertions(+), 2112 deletions(-) create mode 100644 libraries/lzma/C/7zAlloc.c create mode 100644 libraries/lzma/C/7zAlloc.h create mode 100644 libraries/lzma/C/7zBuf2.c create mode 100644 libraries/lzma/C/7zFile.c create mode 100644 libraries/lzma/C/7zFile.h create mode 100644 libraries/lzma/C/7zWindows.h create mode 100644 libraries/lzma/C/Aes.c create mode 100644 libraries/lzma/C/Aes.h create mode 100644 libraries/lzma/C/AesOpt.c create mode 100644 libraries/lzma/C/Alloc.c create mode 100644 libraries/lzma/C/Alloc.h create mode 100644 libraries/lzma/C/Bcj2Enc.c create mode 100644 libraries/lzma/C/DllSecur.c create mode 100644 libraries/lzma/C/DllSecur.h create mode 100644 libraries/lzma/C/Lzma2DecMt.c create mode 100644 libraries/lzma/C/Lzma2DecMt.h create mode 100644 libraries/lzma/C/Lzma2Enc.c create mode 100644 libraries/lzma/C/Lzma2Enc.h create mode 100644 libraries/lzma/C/Lzma86.h create mode 100644 libraries/lzma/C/Lzma86Dec.c create mode 100644 libraries/lzma/C/Lzma86Enc.c create mode 100644 libraries/lzma/C/LzmaLib.c create mode 100644 libraries/lzma/C/LzmaLib.h create mode 100644 libraries/lzma/C/MtCoder.c create mode 100644 libraries/lzma/C/MtCoder.h create mode 100644 libraries/lzma/C/MtDec.c create mode 100644 libraries/lzma/C/MtDec.h create mode 100644 libraries/lzma/C/Ppmd7Enc.c create mode 100644 libraries/lzma/C/RotateDefs.h create mode 100644 libraries/lzma/C/Sha256.c create mode 100644 libraries/lzma/C/Sha256.h create mode 100644 libraries/lzma/C/Sha256Opt.c create mode 100644 libraries/lzma/C/Sort.c create mode 100644 libraries/lzma/C/Sort.h create mode 100644 libraries/lzma/C/SwapBytes.c create mode 100644 libraries/lzma/C/SwapBytes.h create mode 100644 libraries/lzma/C/Xz.c create mode 100644 libraries/lzma/C/Xz.h create mode 100644 libraries/lzma/C/XzCrc64.c create mode 100644 libraries/lzma/C/XzCrc64.h create mode 100644 libraries/lzma/C/XzCrc64Opt.c create mode 100644 libraries/lzma/C/XzDec.c create mode 100644 libraries/lzma/C/XzEnc.c create mode 100644 libraries/lzma/C/XzEnc.h create mode 100644 libraries/lzma/C/XzIn.c diff --git a/libraries/lzma/C/7z.h b/libraries/lzma/C/7z.h index 304f75ffc..9e27c0152 100644 --- a/libraries/lzma/C/7z.h +++ b/libraries/lzma/C/7z.h @@ -1,8 +1,8 @@ /* 7z.h -- 7z interface -2018-07-02 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __7Z_H -#define __7Z_H +#ifndef ZIP7_INC_7Z_H +#define ZIP7_INC_7Z_H #include "7zTypes.h" @@ -98,7 +98,7 @@ typedef struct UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex); SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, - ILookInStream *stream, UInt64 startPos, + ILookInStreamPtr stream, UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAllocPtr allocMain); @@ -174,7 +174,7 @@ UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 SRes SzArEx_Extract( const CSzArEx *db, - ILookInStream *inStream, + ILookInStreamPtr inStream, UInt32 fileIndex, /* index of file */ UInt32 *blockIndex, /* index of solid block */ Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ @@ -196,7 +196,7 @@ SZ_ERROR_INPUT_EOF SZ_ERROR_FAIL */ -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, +SRes SzArEx_Open(CSzArEx *p, ILookInStreamPtr inStream, ISzAllocPtr allocMain, ISzAllocPtr allocTemp); EXTERN_C_END diff --git a/libraries/lzma/C/7zAlloc.c b/libraries/lzma/C/7zAlloc.c new file mode 100644 index 000000000..2f0659af6 --- /dev/null +++ b/libraries/lzma/C/7zAlloc.c @@ -0,0 +1,89 @@ +/* 7zAlloc.c -- Allocation functions for 7z processing +2023-03-04 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zAlloc.h" + +/* #define SZ_ALLOC_DEBUG */ +/* use SZ_ALLOC_DEBUG to debug alloc/free operations */ + +#ifdef SZ_ALLOC_DEBUG + +/* +#ifdef _WIN32 +#include "7zWindows.h" +#endif +*/ + +#include +static int g_allocCount = 0; +static int g_allocCountTemp = 0; + +static void Print_Alloc(const char *s, size_t size, int *counter) +{ + const unsigned size2 = (unsigned)size; + fprintf(stderr, "\n%s count = %10d : %10u bytes; ", s, *counter, size2); + (*counter)++; +} +static void Print_Free(const char *s, int *counter) +{ + (*counter)--; + fprintf(stderr, "\n%s count = %10d", s, *counter); +} +#endif + +void *SzAlloc(ISzAllocPtr p, size_t size) +{ + UNUSED_VAR(p) + if (size == 0) + return 0; + #ifdef SZ_ALLOC_DEBUG + Print_Alloc("Alloc", size, &g_allocCount); + #endif + return malloc(size); +} + +void SzFree(ISzAllocPtr p, void *address) +{ + UNUSED_VAR(p) + #ifdef SZ_ALLOC_DEBUG + if (address) + Print_Free("Free ", &g_allocCount); + #endif + free(address); +} + +void *SzAllocTemp(ISzAllocPtr p, size_t size) +{ + UNUSED_VAR(p) + if (size == 0) + return 0; + #ifdef SZ_ALLOC_DEBUG + Print_Alloc("Alloc_temp", size, &g_allocCountTemp); + /* + #ifdef _WIN32 + return HeapAlloc(GetProcessHeap(), 0, size); + #endif + */ + #endif + return malloc(size); +} + +void SzFreeTemp(ISzAllocPtr p, void *address) +{ + UNUSED_VAR(p) + #ifdef SZ_ALLOC_DEBUG + if (address) + Print_Free("Free_temp ", &g_allocCountTemp); + /* + #ifdef _WIN32 + HeapFree(GetProcessHeap(), 0, address); + return; + #endif + */ + #endif + free(address); +} diff --git a/libraries/lzma/C/7zAlloc.h b/libraries/lzma/C/7zAlloc.h new file mode 100644 index 000000000..b2b8b0cdd --- /dev/null +++ b/libraries/lzma/C/7zAlloc.h @@ -0,0 +1,19 @@ +/* 7zAlloc.h -- Allocation functions +2023-03-04 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_7Z_ALLOC_H +#define ZIP7_INC_7Z_ALLOC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +void *SzAlloc(ISzAllocPtr p, size_t size); +void SzFree(ISzAllocPtr p, void *address); + +void *SzAllocTemp(ISzAllocPtr p, size_t size); +void SzFreeTemp(ISzAllocPtr p, void *address); + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/7zArcIn.c b/libraries/lzma/C/7zArcIn.c index 0d9dec41e..43fa7c214 100644 --- a/libraries/lzma/C/7zArcIn.c +++ b/libraries/lzma/C/7zArcIn.c @@ -1,5 +1,5 @@ /* 7zArcIn.c -- 7z Input functions -2021-02-09 : Igor Pavlov : Public domain */ +2023-05-11 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -10,10 +10,11 @@ #include "7zCrc.h" #include "CpuArch.h" -#define MY_ALLOC(T, p, size, alloc) { \ - if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; } +#define MY_ALLOC(T, p, size, alloc) \ + { if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; } -#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) } +#define MY_ALLOC_ZE(T, p, size, alloc) \ + { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) } #define MY_ALLOC_AND_CPY(to, size, from, alloc) \ { MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); } @@ -58,7 +59,7 @@ enum EIdEnum const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; -#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; } +#define SzBitUi32s_INIT(p) { (p)->Defs = NULL; (p)->Vals = NULL; } static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc) { @@ -69,8 +70,8 @@ static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc) } else { - MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc); - MY_ALLOC(UInt32, p->Vals, num, alloc); + MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc) + MY_ALLOC(UInt32, p->Vals, num, alloc) } return SZ_OK; } @@ -81,7 +82,7 @@ static void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc) ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL; } -#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; } +#define SzBitUi64s_INIT(p) { (p)->Defs = NULL; (p)->Vals = NULL; } static void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc) { @@ -96,7 +97,7 @@ static void SzAr_Init(CSzAr *p) p->NumFolders = 0; p->PackPositions = NULL; - SzBitUi32s_Init(&p->FolderCRCs); + SzBitUi32s_INIT(&p->FolderCRCs) p->FoCodersOffsets = NULL; p->FoStartPackStreamIndex = NULL; @@ -142,11 +143,11 @@ void SzArEx_Init(CSzArEx *p) p->FileNameOffsets = NULL; p->FileNames = NULL; - SzBitUi32s_Init(&p->CRCs); - SzBitUi32s_Init(&p->Attribs); - // SzBitUi32s_Init(&p->Parents); - SzBitUi64s_Init(&p->MTime); - SzBitUi64s_Init(&p->CTime); + SzBitUi32s_INIT(&p->CRCs) + SzBitUi32s_INIT(&p->Attribs) + // SzBitUi32s_INIT(&p->Parents) + SzBitUi64s_INIT(&p->MTime) + SzBitUi64s_INIT(&p->CTime) } void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc) @@ -180,11 +181,20 @@ static int TestSignatureCandidate(const Byte *testBytes) return 1; } -#define SzData_Clear(p) { (p)->Data = NULL; (p)->Size = 0; } +#define SzData_CLEAR(p) { (p)->Data = NULL; (p)->Size = 0; } + +#define SZ_READ_BYTE_SD_NOCHECK(_sd_, dest) \ + (_sd_)->Size--; dest = *(_sd_)->Data++; + +#define SZ_READ_BYTE_SD(_sd_, dest) \ + if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; \ + SZ_READ_BYTE_SD_NOCHECK(_sd_, dest) -#define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++; #define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest) -#define SZ_READ_BYTE_2(dest) if (sd.Size == 0) return SZ_ERROR_ARCHIVE; sd.Size--; dest = *sd.Data++; + +#define SZ_READ_BYTE_2(dest) \ + if (sd.Size == 0) return SZ_ERROR_ARCHIVE; \ + sd.Size--; dest = *sd.Data++; #define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); } #define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); } @@ -192,25 +202,25 @@ static int TestSignatureCandidate(const Byte *testBytes) #define SZ_READ_32(dest) if (sd.Size < 4) return SZ_ERROR_ARCHIVE; \ dest = GetUi32(sd.Data); SKIP_DATA2(sd, 4); -static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value) +static Z7_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value) { Byte firstByte, mask; unsigned i; UInt32 v; - SZ_READ_BYTE(firstByte); + SZ_READ_BYTE(firstByte) if ((firstByte & 0x80) == 0) { *value = firstByte; return SZ_OK; } - SZ_READ_BYTE(v); + SZ_READ_BYTE(v) if ((firstByte & 0x40) == 0) { *value = (((UInt32)firstByte & 0x3F) << 8) | v; return SZ_OK; } - SZ_READ_BYTE(mask); + SZ_READ_BYTE(mask) *value = v | ((UInt32)mask << 8); mask = 0x20; for (i = 2; i < 8; i++) @@ -218,11 +228,11 @@ static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value) Byte b; if ((firstByte & mask) == 0) { - UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1); + const UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1); *value |= (highPart << (8 * i)); return SZ_OK; } - SZ_READ_BYTE(b); + SZ_READ_BYTE(b) *value |= ((UInt64)b << (8 * i)); mask >>= 1; } @@ -230,7 +240,7 @@ static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value) } -static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) +static Z7_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) { Byte firstByte; UInt64 value64; @@ -244,7 +254,7 @@ static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) sd->Size--; return SZ_OK; } - RINOK(ReadNumber(sd, &value64)); + RINOK(ReadNumber(sd, &value64)) if (value64 >= (UInt32)0x80000000 - 1) return SZ_ERROR_UNSUPPORTED; if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 4))) @@ -258,10 +268,10 @@ static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) static SRes SkipData(CSzData *sd) { UInt64 size; - RINOK(ReadNumber(sd, &size)); + RINOK(ReadNumber(sd, &size)) if (size > sd->Size) return SZ_ERROR_ARCHIVE; - SKIP_DATA(sd, size); + SKIP_DATA(sd, size) return SZ_OK; } @@ -270,22 +280,22 @@ static SRes WaitId(CSzData *sd, UInt32 id) for (;;) { UInt64 type; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == id) return SZ_OK; if (type == k7zIdEnd) return SZ_ERROR_ARCHIVE; - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } } static SRes RememberBitVector(CSzData *sd, UInt32 numItems, const Byte **v) { - UInt32 numBytes = (numItems + 7) >> 3; + const UInt32 numBytes = (numItems + 7) >> 3; if (numBytes > sd->Size) return SZ_ERROR_ARCHIVE; *v = sd->Data; - SKIP_DATA(sd, numBytes); + SKIP_DATA(sd, numBytes) return SZ_OK; } @@ -307,48 +317,48 @@ static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems) return sum; } -static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc) +static Z7_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAllocPtr alloc) { Byte allAreDefined; Byte *v2; - UInt32 numBytes = (numItems + 7) >> 3; + const UInt32 numBytes = (numItems + 7) >> 3; *v = NULL; - SZ_READ_BYTE(allAreDefined); + SZ_READ_BYTE(allAreDefined) if (numBytes == 0) return SZ_OK; if (allAreDefined == 0) { if (numBytes > sd->Size) return SZ_ERROR_ARCHIVE; - MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc); - SKIP_DATA(sd, numBytes); + MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc) + SKIP_DATA(sd, numBytes) return SZ_OK; } - MY_ALLOC(Byte, *v, numBytes, alloc); + MY_ALLOC(Byte, *v, numBytes, alloc) v2 = *v; memset(v2, 0xFF, (size_t)numBytes); { - unsigned numBits = (unsigned)numItems & 7; + const unsigned numBits = (unsigned)numItems & 7; if (numBits != 0) v2[(size_t)numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits)); } return SZ_OK; } -static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) +static Z7_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) { UInt32 i; CSzData sd; UInt32 *vals; const Byte *defs; - MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc); + MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc) sd = *sd2; defs = crcs->Defs; vals = crcs->Vals; for (i = 0; i < numItems; i++) if (SzBitArray_Check(defs, i)) { - SZ_READ_32(vals[i]); + SZ_READ_32(vals[i]) } else vals[i] = 0; @@ -359,7 +369,7 @@ static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *c static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) { SzBitUi32s_Free(crcs, alloc); - RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc)); + RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc)) return ReadUi32s(sd, numItems, crcs, alloc); } @@ -367,36 +377,36 @@ static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems) { Byte allAreDefined; UInt32 numDefined = numItems; - SZ_READ_BYTE(allAreDefined); + SZ_READ_BYTE(allAreDefined) if (!allAreDefined) { - size_t numBytes = (numItems + 7) >> 3; + const size_t numBytes = (numItems + 7) >> 3; if (numBytes > sd->Size) return SZ_ERROR_ARCHIVE; numDefined = CountDefinedBits(sd->Data, numItems); - SKIP_DATA(sd, numBytes); + SKIP_DATA(sd, numBytes) } if (numDefined > (sd->Size >> 2)) return SZ_ERROR_ARCHIVE; - SKIP_DATA(sd, (size_t)numDefined * 4); + SKIP_DATA(sd, (size_t)numDefined * 4) return SZ_OK; } static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc) { - RINOK(SzReadNumber32(sd, &p->NumPackStreams)); + RINOK(SzReadNumber32(sd, &p->NumPackStreams)) - RINOK(WaitId(sd, k7zIdSize)); - MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc); + RINOK(WaitId(sd, k7zIdSize)) + MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc) { UInt64 sum = 0; UInt32 i; - UInt32 numPackStreams = p->NumPackStreams; + const UInt32 numPackStreams = p->NumPackStreams; for (i = 0; i < numPackStreams; i++) { UInt64 packSize; p->PackPositions[i] = sum; - RINOK(ReadNumber(sd, &packSize)); + RINOK(ReadNumber(sd, &packSize)) sum += packSize; if (sum < packSize) return SZ_ERROR_ARCHIVE; @@ -407,16 +417,16 @@ static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc) for (;;) { UInt64 type; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdEnd) return SZ_OK; if (type == k7zIdCRC) { /* CRC of packed streams is unused now */ - RINOK(SkipBitUi32s(sd, p->NumPackStreams)); + RINOK(SkipBitUi32s(sd, p->NumPackStreams)) continue; } - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } } @@ -442,7 +452,7 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd) f->NumPackStreams = 0; f->UnpackStream = 0; - RINOK(SzReadNumber32(sd, &numCoders)); + RINOK(SzReadNumber32(sd, &numCoders)) if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX) return SZ_ERROR_UNSUPPORTED; @@ -453,7 +463,7 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd) unsigned idSize, j; UInt64 id; - SZ_READ_BYTE(mainByte); + SZ_READ_BYTE(mainByte) if ((mainByte & 0xC0) != 0) return SZ_ERROR_UNSUPPORTED; @@ -481,12 +491,12 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd) { UInt32 numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); + RINOK(SzReadNumber32(sd, &numStreams)) if (numStreams > k_NumCodersStreams_in_Folder_MAX) return SZ_ERROR_UNSUPPORTED; coder->NumStreams = (Byte)numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); + RINOK(SzReadNumber32(sd, &numStreams)) if (numStreams != 1) return SZ_ERROR_UNSUPPORTED; } @@ -499,7 +509,7 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd) if ((mainByte & 0x20) != 0) { UInt32 propsSize = 0; - RINOK(SzReadNumber32(sd, &propsSize)); + RINOK(SzReadNumber32(sd, &propsSize)) if (propsSize > sd->Size) return SZ_ERROR_ARCHIVE; if (propsSize >= 0x80) @@ -549,12 +559,12 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd) { CSzBond *bp = f->Bonds + i; - RINOK(SzReadNumber32(sd, &bp->InIndex)); + RINOK(SzReadNumber32(sd, &bp->InIndex)) if (bp->InIndex >= numInStreams || streamUsed[bp->InIndex]) return SZ_ERROR_ARCHIVE; streamUsed[bp->InIndex] = True; - RINOK(SzReadNumber32(sd, &bp->OutIndex)); + RINOK(SzReadNumber32(sd, &bp->OutIndex)) if (bp->OutIndex >= numCoders || coderUsed[bp->OutIndex]) return SZ_ERROR_ARCHIVE; coderUsed[bp->OutIndex] = True; @@ -584,7 +594,7 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd) for (i = 0; i < numPackStreams; i++) { UInt32 index; - RINOK(SzReadNumber32(sd, &index)); + RINOK(SzReadNumber32(sd, &index)) if (index >= numInStreams || streamUsed[index]) return SZ_ERROR_ARCHIVE; streamUsed[index] = True; @@ -598,7 +608,7 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd) } -static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) +static Z7_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) { CSzData sd; sd = *sd2; @@ -606,7 +616,7 @@ static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) { Byte firstByte, mask; unsigned i; - SZ_READ_BYTE_2(firstByte); + SZ_READ_BYTE_2(firstByte) if ((firstByte & 0x80) == 0) continue; if ((firstByte & 0x40) == 0) @@ -622,7 +632,7 @@ static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) mask >>= 1; if (i > sd.Size) return SZ_ERROR_ARCHIVE; - SKIP_DATA2(sd, i); + SKIP_DATA2(sd, i) } *sd2 = sd; return SZ_OK; @@ -645,30 +655,30 @@ static SRes ReadUnpackInfo(CSzAr *p, const Byte *startBufPtr; Byte external; - RINOK(WaitId(sd2, k7zIdFolder)); + RINOK(WaitId(sd2, k7zIdFolder)) - RINOK(SzReadNumber32(sd2, &numFolders)); + RINOK(SzReadNumber32(sd2, &numFolders)) if (numFolders > numFoldersMax) return SZ_ERROR_UNSUPPORTED; p->NumFolders = numFolders; - SZ_READ_BYTE_SD(sd2, external); + SZ_READ_BYTE_SD(sd2, external) if (external == 0) sd = *sd2; else { UInt32 index; - RINOK(SzReadNumber32(sd2, &index)); + RINOK(SzReadNumber32(sd2, &index)) if (index >= numTempBufs) return SZ_ERROR_ARCHIVE; sd.Data = tempBufs[index].data; sd.Size = tempBufs[index].size; } - MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc); - MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc); - MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc); - MY_ALLOC_ZE(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc); + MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc) + MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc) + MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc) + MY_ALLOC_ZE(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc) startBufPtr = sd.Data; @@ -681,7 +691,7 @@ static SRes ReadUnpackInfo(CSzAr *p, p->FoCodersOffsets[fo] = (size_t)(sd.Data - startBufPtr); - RINOK(SzReadNumber32(&sd, &numCoders)); + RINOK(SzReadNumber32(&sd, &numCoders)) if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX) return SZ_ERROR_UNSUPPORTED; @@ -691,7 +701,7 @@ static SRes ReadUnpackInfo(CSzAr *p, unsigned idSize; UInt32 coderInStreams; - SZ_READ_BYTE_2(mainByte); + SZ_READ_BYTE_2(mainByte) if ((mainByte & 0xC0) != 0) return SZ_ERROR_UNSUPPORTED; idSize = (mainByte & 0xF); @@ -699,15 +709,15 @@ static SRes ReadUnpackInfo(CSzAr *p, return SZ_ERROR_UNSUPPORTED; if (idSize > sd.Size) return SZ_ERROR_ARCHIVE; - SKIP_DATA2(sd, idSize); + SKIP_DATA2(sd, idSize) coderInStreams = 1; if ((mainByte & 0x10) != 0) { UInt32 coderOutStreams; - RINOK(SzReadNumber32(&sd, &coderInStreams)); - RINOK(SzReadNumber32(&sd, &coderOutStreams)); + RINOK(SzReadNumber32(&sd, &coderInStreams)) + RINOK(SzReadNumber32(&sd, &coderOutStreams)) if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX || coderOutStreams != 1) return SZ_ERROR_UNSUPPORTED; } @@ -717,10 +727,10 @@ static SRes ReadUnpackInfo(CSzAr *p, if ((mainByte & 0x20) != 0) { UInt32 propsSize; - RINOK(SzReadNumber32(&sd, &propsSize)); + RINOK(SzReadNumber32(&sd, &propsSize)) if (propsSize > sd.Size) return SZ_ERROR_ARCHIVE; - SKIP_DATA2(sd, propsSize); + SKIP_DATA2(sd, propsSize) } } @@ -734,7 +744,7 @@ static SRes ReadUnpackInfo(CSzAr *p, Byte coderUsed[k_Scan_NumCoders_MAX]; UInt32 i; - UInt32 numBonds = numCoders - 1; + const UInt32 numBonds = numCoders - 1; if (numInStreams < numBonds) return SZ_ERROR_ARCHIVE; @@ -750,12 +760,12 @@ static SRes ReadUnpackInfo(CSzAr *p, { UInt32 index; - RINOK(SzReadNumber32(&sd, &index)); + RINOK(SzReadNumber32(&sd, &index)) if (index >= numInStreams || streamUsed[index]) return SZ_ERROR_ARCHIVE; streamUsed[index] = True; - RINOK(SzReadNumber32(&sd, &index)); + RINOK(SzReadNumber32(&sd, &index)) if (index >= numCoders || coderUsed[index]) return SZ_ERROR_ARCHIVE; coderUsed[index] = True; @@ -767,7 +777,7 @@ static SRes ReadUnpackInfo(CSzAr *p, for (i = 0; i < numPackStreams; i++) { UInt32 index; - RINOK(SzReadNumber32(&sd, &index)); + RINOK(SzReadNumber32(&sd, &index)) if (index >= numInStreams || streamUsed[index]) return SZ_ERROR_ARCHIVE; streamUsed[index] = True; @@ -802,7 +812,7 @@ static SRes ReadUnpackInfo(CSzAr *p, const size_t dataSize = (size_t)(sd.Data - startBufPtr); p->FoStartPackStreamIndex[fo] = packStreamIndex; p->FoCodersOffsets[fo] = dataSize; - MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc); + MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc) } if (external != 0) @@ -812,21 +822,21 @@ static SRes ReadUnpackInfo(CSzAr *p, sd = *sd2; } - RINOK(WaitId(&sd, k7zIdCodersUnpackSize)); + RINOK(WaitId(&sd, k7zIdCodersUnpackSize)) - MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc); + MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc) { UInt32 i; for (i = 0; i < numCodersOutStreams; i++) { - RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i)); + RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i)) } } for (;;) { UInt64 type; - RINOK(ReadID(&sd, &type)); + RINOK(ReadID(&sd, &type)) if (type == k7zIdEnd) { *sd2 = sd; @@ -834,10 +844,10 @@ static SRes ReadUnpackInfo(CSzAr *p, } if (type == k7zIdCRC) { - RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc)); + RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc)) continue; } - RINOK(SkipData(&sd)); + RINOK(SkipData(&sd)) } } @@ -862,13 +872,13 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi) { UInt64 type = 0; UInt32 numSubDigests = 0; - UInt32 numFolders = p->NumFolders; + const UInt32 numFolders = p->NumFolders; UInt32 numUnpackStreams = numFolders; UInt32 numUnpackSizesInData = 0; for (;;) { - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdNumUnpackStream) { UInt32 i; @@ -878,7 +888,7 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi) for (i = 0; i < numFolders; i++) { UInt32 numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); + RINOK(SzReadNumber32(sd, &numStreams)) if (numUnpackStreams > numUnpackStreams + numStreams) return SZ_ERROR_UNSUPPORTED; numUnpackStreams += numStreams; @@ -892,7 +902,7 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi) } if (type == k7zIdCRC || type == k7zIdSize || type == k7zIdEnd) break; - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } if (!ssi->sdNumSubStreams.Data) @@ -908,9 +918,9 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi) if (type == k7zIdSize) { ssi->sdSizes.Data = sd->Data; - RINOK(SkipNumbers(sd, numUnpackSizesInData)); + RINOK(SkipNumbers(sd, numUnpackSizesInData)) ssi->sdSizes.Size = (size_t)(sd->Data - ssi->sdSizes.Data); - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } for (;;) @@ -920,14 +930,14 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi) if (type == k7zIdCRC) { ssi->sdCRCs.Data = sd->Data; - RINOK(SkipBitUi32s(sd, numSubDigests)); + RINOK(SkipBitUi32s(sd, numSubDigests)) ssi->sdCRCs.Size = (size_t)(sd->Data - ssi->sdCRCs.Data); } else { - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } } @@ -940,31 +950,31 @@ static SRes SzReadStreamsInfo(CSzAr *p, { UInt64 type; - SzData_Clear(&ssi->sdSizes); - SzData_Clear(&ssi->sdCRCs); - SzData_Clear(&ssi->sdNumSubStreams); + SzData_CLEAR(&ssi->sdSizes) + SzData_CLEAR(&ssi->sdCRCs) + SzData_CLEAR(&ssi->sdNumSubStreams) *dataOffset = 0; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdPackInfo) { - RINOK(ReadNumber(sd, dataOffset)); + RINOK(ReadNumber(sd, dataOffset)) if (*dataOffset > p->RangeLimit) return SZ_ERROR_ARCHIVE; - RINOK(ReadPackInfo(p, sd, alloc)); + RINOK(ReadPackInfo(p, sd, alloc)) if (p->PackPositions[p->NumPackStreams] > p->RangeLimit - *dataOffset) return SZ_ERROR_ARCHIVE; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } if (type == k7zIdUnpackInfo) { - RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc)); - RINOK(ReadID(sd, &type)); + RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc)) + RINOK(ReadID(sd, &type)) } if (type == k7zIdSubStreamsInfo) { - RINOK(ReadSubStreamsInfo(p, sd, ssi)); - RINOK(ReadID(sd, &type)); + RINOK(ReadSubStreamsInfo(p, sd, ssi)) + RINOK(ReadID(sd, &type)) } else { @@ -976,7 +986,7 @@ static SRes SzReadStreamsInfo(CSzAr *p, } static SRes SzReadAndDecodePackedStreams( - ILookInStream *inStream, + ILookInStreamPtr inStream, CSzData *sd, CBuf *tempBufs, UInt32 numFoldersMax, @@ -988,7 +998,7 @@ static SRes SzReadAndDecodePackedStreams( UInt32 fo; CSubStreamInfo ssi; - RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp)); + RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp)) dataStartPos += baseOffset; if (p->NumFolders == 0) @@ -1000,7 +1010,7 @@ static SRes SzReadAndDecodePackedStreams( for (fo = 0; fo < p->NumFolders; fo++) { CBuf *tempBuf = tempBufs + fo; - UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo); + const UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo); if ((size_t)unpackSize != unpackSize) return SZ_ERROR_MEM; if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp)) @@ -1010,8 +1020,8 @@ static SRes SzReadAndDecodePackedStreams( for (fo = 0; fo < p->NumFolders; fo++) { const CBuf *tempBuf = tempBufs + fo; - RINOK(LookInStream_SeekTo(inStream, dataStartPos)); - RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp)); + RINOK(LookInStream_SeekTo(inStream, dataStartPos)) + RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp)) } return SZ_OK; @@ -1046,7 +1056,7 @@ static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; } -static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, +static Z7_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, CSzData *sd2, const CBuf *tempBufs, UInt32 numTempBufs, ISzAllocPtr alloc) @@ -1057,22 +1067,22 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, Byte *defs; Byte external; - RINOK(ReadBitVector(sd2, num, &p->Defs, alloc)); + RINOK(ReadBitVector(sd2, num, &p->Defs, alloc)) - SZ_READ_BYTE_SD(sd2, external); + SZ_READ_BYTE_SD(sd2, external) if (external == 0) sd = *sd2; else { UInt32 index; - RINOK(SzReadNumber32(sd2, &index)); + RINOK(SzReadNumber32(sd2, &index)) if (index >= numTempBufs) return SZ_ERROR_ARCHIVE; sd.Data = tempBufs[index].data; sd.Size = tempBufs[index].size; } - MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc); + MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc) vals = p->Vals; defs = p->Defs; for (i = 0; i < num; i++) @@ -1082,7 +1092,7 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, return SZ_ERROR_ARCHIVE; vals[i].Low = GetUi32(sd.Data); vals[i].High = GetUi32(sd.Data + 4); - SKIP_DATA2(sd, 8); + SKIP_DATA2(sd, 8) } else vals[i].High = vals[i].Low = 0; @@ -1100,7 +1110,7 @@ static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num, static SRes SzReadHeader2( CSzArEx *p, /* allocMain */ CSzData *sd, - ILookInStream *inStream, + ILookInStreamPtr inStream, CBuf *tempBufs, UInt32 *numTempBufs, ISzAllocPtr allocMain, ISzAllocPtr allocTemp @@ -1111,26 +1121,26 @@ static SRes SzReadHeader2( { UInt64 type; - SzData_Clear(&ssi.sdSizes); - SzData_Clear(&ssi.sdCRCs); - SzData_Clear(&ssi.sdNumSubStreams); + SzData_CLEAR(&ssi.sdSizes) + SzData_CLEAR(&ssi.sdCRCs) + SzData_CLEAR(&ssi.sdNumSubStreams) ssi.NumSubDigests = 0; ssi.NumTotalSubStreams = 0; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdArchiveProperties) { for (;;) { UInt64 type2; - RINOK(ReadID(sd, &type2)); + RINOK(ReadID(sd, &type2)) if (type2 == k7zIdEnd) break; - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } if (type == k7zIdAdditionalStreamsInfo) @@ -1148,15 +1158,15 @@ static SRes SzReadHeader2( if (res != SZ_OK) return res; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } if (type == k7zIdMainStreamsInfo) { RINOK(SzReadStreamsInfo(&p->db, sd, (UInt32)1 << 30, tempBufs, *numTempBufs, - &p->dataPos, &ssi, allocMain)); + &p->dataPos, &ssi, allocMain)) p->dataPos += p->startPosAfterHeader; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) } if (type == k7zIdEnd) @@ -1174,23 +1184,23 @@ static SRes SzReadHeader2( const Byte *emptyStreams = NULL; const Byte *emptyFiles = NULL; - RINOK(SzReadNumber32(sd, &numFiles)); + RINOK(SzReadNumber32(sd, &numFiles)) p->NumFiles = numFiles; for (;;) { UInt64 type; UInt64 size; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdEnd) break; - RINOK(ReadNumber(sd, &size)); + RINOK(ReadNumber(sd, &size)) if (size > sd->Size) return SZ_ERROR_ARCHIVE; if (type >= ((UInt32)1 << 8)) { - SKIP_DATA(sd, size); + SKIP_DATA(sd, size) } else switch ((unsigned)type) { @@ -1200,7 +1210,7 @@ static SRes SzReadHeader2( const Byte *namesData; Byte external; - SZ_READ_BYTE(external); + SZ_READ_BYTE(external) if (external == 0) { namesSize = (size_t)size - 1; @@ -1209,7 +1219,7 @@ static SRes SzReadHeader2( else { UInt32 index; - RINOK(SzReadNumber32(sd, &index)); + RINOK(SzReadNumber32(sd, &index)) if (index >= *numTempBufs) return SZ_ERROR_ARCHIVE; namesData = (tempBufs)[index].data; @@ -1218,25 +1228,25 @@ static SRes SzReadHeader2( if ((namesSize & 1) != 0) return SZ_ERROR_ARCHIVE; - MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); - MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain); + MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain) + MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain) RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets)) if (external == 0) { - SKIP_DATA(sd, namesSize); + SKIP_DATA(sd, namesSize) } break; } case k7zIdEmptyStream: { - RINOK(RememberBitVector(sd, numFiles, &emptyStreams)); + RINOK(RememberBitVector(sd, numFiles, &emptyStreams)) numEmptyStreams = CountDefinedBits(emptyStreams, numFiles); emptyFiles = NULL; break; } case k7zIdEmptyFile: { - RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles)); + RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles)) break; } case k7zIdWinAttrib: @@ -1245,22 +1255,22 @@ static SRes SzReadHeader2( CSzData sdSwitch; CSzData *sdPtr; SzBitUi32s_Free(&p->Attribs, allocMain); - RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain)); + RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain)) - SZ_READ_BYTE(external); + SZ_READ_BYTE(external) if (external == 0) sdPtr = sd; else { UInt32 index; - RINOK(SzReadNumber32(sd, &index)); + RINOK(SzReadNumber32(sd, &index)) if (index >= *numTempBufs) return SZ_ERROR_ARCHIVE; sdSwitch.Data = (tempBufs)[index].data; sdSwitch.Size = (tempBufs)[index].size; sdPtr = &sdSwitch; } - RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain)); + RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain)) break; } /* @@ -1273,11 +1283,11 @@ static SRes SzReadHeader2( break; } */ - case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break; - case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break; + case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)) break; + case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)) break; default: { - SKIP_DATA(sd, size); + SKIP_DATA(sd, size) } } } @@ -1288,10 +1298,10 @@ static SRes SzReadHeader2( for (;;) { UInt64 type; - RINOK(ReadID(sd, &type)); + RINOK(ReadID(sd, &type)) if (type == k7zIdEnd) break; - RINOK(SkipData(sd)); + RINOK(SkipData(sd)) } { @@ -1303,40 +1313,37 @@ static SRes SzReadHeader2( UInt64 unpackPos = 0; const Byte *digestsDefs = NULL; const Byte *digestsVals = NULL; - UInt32 digestsValsIndex = 0; - UInt32 digestIndex; - Byte allDigestsDefined = 0; + UInt32 digestIndex = 0; Byte isDirMask = 0; Byte crcMask = 0; Byte mask = 0x80; - MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain); - MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain); - MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain); - MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain); + MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain) + MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain) + MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain) + MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain) - RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain)); + RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain)) if (ssi.sdCRCs.Size != 0) { - SZ_READ_BYTE_SD(&ssi.sdCRCs, allDigestsDefined); + Byte allDigestsDefined = 0; + SZ_READ_BYTE_SD_NOCHECK(&ssi.sdCRCs, allDigestsDefined) if (allDigestsDefined) digestsVals = ssi.sdCRCs.Data; else { - size_t numBytes = (ssi.NumSubDigests + 7) >> 3; + const size_t numBytes = (ssi.NumSubDigests + 7) >> 3; digestsDefs = ssi.sdCRCs.Data; digestsVals = digestsDefs + numBytes; } } - digestIndex = 0; - for (i = 0; i < numFiles; i++, mask >>= 1) { if (mask == 0) { - UInt32 byteIndex = (i - 1) >> 3; + const UInt32 byteIndex = (i - 1) >> 3; p->IsDirs[byteIndex] = isDirMask; p->CRCs.Defs[byteIndex] = crcMask; isDirMask = 0; @@ -1374,18 +1381,17 @@ static SRes SzReadHeader2( numSubStreams = 1; if (ssi.sdNumSubStreams.Data) { - RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)); + RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)) } remSubStreams = numSubStreams; if (numSubStreams != 0) break; { - UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + const UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); unpackPos += folderUnpackSize; if (unpackPos < folderUnpackSize) return SZ_ERROR_ARCHIVE; } - folderIndex++; } } @@ -1397,47 +1403,44 @@ static SRes SzReadHeader2( if (--remSubStreams == 0) { - UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); - UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]]; + const UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + const UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]]; if (folderUnpackSize < unpackPos - startFolderUnpackPos) return SZ_ERROR_ARCHIVE; unpackPos = startFolderUnpackPos + folderUnpackSize; if (unpackPos < folderUnpackSize) return SZ_ERROR_ARCHIVE; - if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i)) + if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, folderIndex)) { p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex]; crcMask |= mask; } - else if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex))) - { - p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4); - digestsValsIndex++; - crcMask |= mask; - } - folderIndex++; } else { UInt64 v; - RINOK(ReadNumber(&ssi.sdSizes, &v)); + RINOK(ReadNumber(&ssi.sdSizes, &v)) unpackPos += v; if (unpackPos < v) return SZ_ERROR_ARCHIVE; - if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex))) + } + if ((crcMask & mask) == 0 && digestsVals) + { + if (!digestsDefs || SzBitArray_Check(digestsDefs, digestIndex)) { - p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4); - digestsValsIndex++; + p->CRCs.Vals[i] = GetUi32(digestsVals); + digestsVals += 4; crcMask |= mask; } + digestIndex++; } } if (mask != 0x80) { - UInt32 byteIndex = (i - 1) >> 3; + const UInt32 byteIndex = (i - 1) >> 3; p->IsDirs[byteIndex] = isDirMask; p->CRCs.Defs[byteIndex] = crcMask; } @@ -1454,7 +1457,7 @@ static SRes SzReadHeader2( break; if (!ssi.sdNumSubStreams.Data) return SZ_ERROR_ARCHIVE; - RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)); + RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams)) if (numSubStreams != 0) return SZ_ERROR_ARCHIVE; /* @@ -1479,7 +1482,7 @@ static SRes SzReadHeader2( static SRes SzReadHeader( CSzArEx *p, CSzData *sd, - ILookInStream *inStream, + ILookInStreamPtr inStream, ISzAllocPtr allocMain, ISzAllocPtr allocTemp) { @@ -1498,7 +1501,7 @@ static SRes SzReadHeader( for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++) Buf_Free(tempBufs + i, allocTemp); - RINOK(res); + RINOK(res) if (sd->Size != 0) return SZ_ERROR_FAIL; @@ -1508,7 +1511,7 @@ static SRes SzReadHeader( static SRes SzArEx_Open2( CSzArEx *p, - ILookInStream *inStream, + ILookInStreamPtr inStream, ISzAllocPtr allocMain, ISzAllocPtr allocTemp) { @@ -1521,9 +1524,9 @@ static SRes SzArEx_Open2( SRes res; startArcPos = 0; - RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR)); + RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR)) - RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); + RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)) if (!TestSignatureCandidate(header)) return SZ_ERROR_NO_ARCHIVE; @@ -1552,14 +1555,14 @@ static SRes SzArEx_Open2( { Int64 pos = 0; - RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END)); + RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END)) if ((UInt64)pos < (UInt64)startArcPos + nextHeaderOffset || (UInt64)pos < (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset || (UInt64)pos < (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) return SZ_ERROR_INPUT_EOF; } - RINOK(LookInStream_SeekTo(inStream, (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset)); + RINOK(LookInStream_SeekTo(inStream, (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset)) if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp)) return SZ_ERROR_MEM; @@ -1634,10 +1637,10 @@ static SRes SzArEx_Open2( } -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, +SRes SzArEx_Open(CSzArEx *p, ILookInStreamPtr inStream, ISzAllocPtr allocMain, ISzAllocPtr allocTemp) { - SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); + const SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); if (res != SZ_OK) SzArEx_Free(p, allocMain); return res; @@ -1646,7 +1649,7 @@ SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, SRes SzArEx_Extract( const CSzArEx *p, - ILookInStream *inStream, + ILookInStreamPtr inStream, UInt32 fileIndex, UInt32 *blockIndex, Byte **tempBuf, @@ -1656,7 +1659,7 @@ SRes SzArEx_Extract( ISzAllocPtr allocMain, ISzAllocPtr allocTemp) { - UInt32 folderIndex = p->FileToFolder[fileIndex]; + const UInt32 folderIndex = p->FileToFolder[fileIndex]; SRes res = SZ_OK; *offset = 0; @@ -1673,13 +1676,13 @@ SRes SzArEx_Extract( if (*tempBuf == NULL || *blockIndex != folderIndex) { - UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex); + const UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex); /* UInt64 unpackSizeSpec = p->UnpackPositions[p->FolderToFile[(size_t)folderIndex + 1]] - p->UnpackPositions[p->FolderToFile[folderIndex]]; */ - size_t unpackSize = (size_t)unpackSizeSpec; + const size_t unpackSize = (size_t)unpackSizeSpec; if (unpackSize != unpackSizeSpec) return SZ_ERROR_MEM; @@ -1707,7 +1710,7 @@ SRes SzArEx_Extract( if (res == SZ_OK) { - UInt64 unpackPos = p->UnpackPositions[fileIndex]; + const UInt64 unpackPos = p->UnpackPositions[fileIndex]; *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]); *outSizeProcessed = (size_t)(p->UnpackPositions[(size_t)fileIndex + 1] - unpackPos); if (*offset + *outSizeProcessed > *outBufferSize) @@ -1723,8 +1726,8 @@ SRes SzArEx_Extract( size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) { - size_t offs = p->FileNameOffsets[fileIndex]; - size_t len = p->FileNameOffsets[fileIndex + 1] - offs; + const size_t offs = p->FileNameOffsets[fileIndex]; + const size_t len = p->FileNameOffsets[fileIndex + 1] - offs; if (dest != 0) { size_t i; diff --git a/libraries/lzma/C/7zBuf.h b/libraries/lzma/C/7zBuf.h index 81d1b5b64..c0ba8a7b6 100644 --- a/libraries/lzma/C/7zBuf.h +++ b/libraries/lzma/C/7zBuf.h @@ -1,8 +1,8 @@ /* 7zBuf.h -- Byte Buffer -2017-04-03 : Igor Pavlov : Public domain */ +2023-03-04 : Igor Pavlov : Public domain */ -#ifndef __7Z_BUF_H -#define __7Z_BUF_H +#ifndef ZIP7_INC_7Z_BUF_H +#define ZIP7_INC_7Z_BUF_H #include "7zTypes.h" diff --git a/libraries/lzma/C/7zBuf2.c b/libraries/lzma/C/7zBuf2.c new file mode 100644 index 000000000..208347416 --- /dev/null +++ b/libraries/lzma/C/7zBuf2.c @@ -0,0 +1,52 @@ +/* 7zBuf2.c -- Byte Buffer +2017-04-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zBuf.h" + +void DynBuf_Construct(CDynBuf *p) +{ + p->data = 0; + p->size = 0; + p->pos = 0; +} + +void DynBuf_SeekToBeg(CDynBuf *p) +{ + p->pos = 0; +} + +int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc) +{ + if (size > p->size - p->pos) + { + size_t newSize = p->pos + size; + Byte *data; + newSize += newSize / 4; + data = (Byte *)ISzAlloc_Alloc(alloc, newSize); + if (!data) + return 0; + p->size = newSize; + if (p->pos != 0) + memcpy(data, p->data, p->pos); + ISzAlloc_Free(alloc, p->data); + p->data = data; + } + if (size != 0) + { + memcpy(p->data + p->pos, buf, size); + p->pos += size; + } + return 1; +} + +void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->data); + p->data = 0; + p->size = 0; + p->pos = 0; +} diff --git a/libraries/lzma/C/7zCrc.c b/libraries/lzma/C/7zCrc.c index f186324dd..c995a8be4 100644 --- a/libraries/lzma/C/7zCrc.c +++ b/libraries/lzma/C/7zCrc.c @@ -1,5 +1,5 @@ -/* 7zCrc.c -- CRC32 init -2021-04-01 : Igor Pavlov : Public domain */ +/* 7zCrc.c -- CRC32 calculation and init +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -13,22 +13,20 @@ #else #define CRC_NUM_TABLES 9 - #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) - - UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); - UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table); + UInt32 Z7_FASTCALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); + UInt32 Z7_FASTCALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table); #endif #ifndef MY_CPU_BE - UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); - UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); + UInt32 Z7_FASTCALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); + UInt32 Z7_FASTCALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); #endif -typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); - +/* extern CRC_FUNC g_CrcUpdateT4; CRC_FUNC g_CrcUpdateT4; +*/ extern CRC_FUNC g_CrcUpdateT8; CRC_FUNC g_CrcUpdateT8; @@ -44,20 +42,22 @@ CRC_FUNC g_CrcUpdate; UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; -UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) +UInt32 Z7_FASTCALL CrcUpdate(UInt32 v, const void *data, size_t size) { return g_CrcUpdate(v, data, size, g_CrcTable); } -UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) +UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size) { return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; } +#if CRC_NUM_TABLES < 4 \ + || (CRC_NUM_TABLES == 4 && defined(MY_CPU_BE)) \ + || (!defined(MY_CPU_LE) && !defined(MY_CPU_BE)) #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); -UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) +UInt32 Z7_FASTCALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); +UInt32 Z7_FASTCALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) { const Byte *p = (const Byte *)data; const Byte *pEnd = p + size; @@ -65,7 +65,7 @@ UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const U v = CRC_UPDATE_BYTE_2(v, *p); return v; } - +#endif /* ---------- hardware CRC ---------- */ @@ -78,16 +78,29 @@ UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const U #if defined(_MSC_VER) #if defined(MY_CPU_ARM64) #if (_MSC_VER >= 1910) + #ifndef __clang__ #define USE_ARM64_CRC + #include + #endif #endif #endif #elif (defined(__clang__) && (__clang_major__ >= 3)) \ || (defined(__GNUC__) && (__GNUC__ > 4)) #if !defined(__ARM_FEATURE_CRC32) #define __ARM_FEATURE_CRC32 1 - #if (!defined(__clang__) || (__clang_major__ > 3)) // fix these numbers + #if defined(__clang__) + #if defined(MY_CPU_ARM64) + #define ATTRIB_CRC __attribute__((__target__("crc"))) + #else + #define ATTRIB_CRC __attribute__((__target__("armv8-a,crc"))) + #endif + #else + #if defined(MY_CPU_ARM64) + #define ATTRIB_CRC __attribute__((__target__("+crc"))) + #else #define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc"))) #endif + #endif #endif #if defined(__ARM_FEATURE_CRC32) #define USE_ARM64_CRC @@ -105,7 +118,7 @@ UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const U #pragma message("ARM64 CRC emulation") -MY_FORCE_INLINE +Z7_FORCE_INLINE UInt32 __crc32b(UInt32 v, UInt32 data) { const UInt32 *table = g_CrcTable; @@ -113,7 +126,7 @@ UInt32 __crc32b(UInt32 v, UInt32 data) return v; } -MY_FORCE_INLINE +Z7_FORCE_INLINE UInt32 __crc32w(UInt32 v, UInt32 data) { const UInt32 *table = g_CrcTable; @@ -124,7 +137,7 @@ UInt32 __crc32w(UInt32 v, UInt32 data) return v; } -MY_FORCE_INLINE +Z7_FORCE_INLINE UInt32 __crc32d(UInt32 v, UInt64 data) { const UInt32 *table = g_CrcTable; @@ -156,9 +169,9 @@ UInt32 __crc32d(UInt32 v, UInt64 data) // #pragma message("USE ARM HW CRC") ATTRIB_CRC -UInt32 MY_FAST_CALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, const UInt32 *table); +UInt32 Z7_FASTCALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, const UInt32 *table); ATTRIB_CRC -UInt32 MY_FAST_CALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, const UInt32 *table) +UInt32 Z7_FASTCALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, const UInt32 *table) { const Byte *p = (const Byte *)data; UNUSED_VAR(table); @@ -188,9 +201,9 @@ UInt32 MY_FAST_CALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, cons } ATTRIB_CRC -UInt32 MY_FAST_CALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, const UInt32 *table); +UInt32 Z7_FASTCALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, const UInt32 *table); ATTRIB_CRC -UInt32 MY_FAST_CALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, const UInt32 *table) +UInt32 Z7_FASTCALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, const UInt32 *table) { const Byte *p = (const Byte *)data; UNUSED_VAR(table); @@ -219,6 +232,9 @@ UInt32 MY_FAST_CALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, cons return v; } +#undef T0_32_UNROLL_BYTES +#undef T0_64_UNROLL_BYTES + #endif // defined(USE_ARM64_CRC) || defined(USE_CRC_EMU) #endif // MY_CPU_LE @@ -226,7 +242,7 @@ UInt32 MY_FAST_CALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, cons -void MY_FAST_CALL CrcGenerateTable() +void Z7_FASTCALL CrcGenerateTable(void) { UInt32 i; for (i = 0; i < 256; i++) @@ -239,64 +255,62 @@ void MY_FAST_CALL CrcGenerateTable() } for (i = 256; i < 256 * CRC_NUM_TABLES; i++) { - UInt32 r = g_CrcTable[(size_t)i - 256]; + const UInt32 r = g_CrcTable[(size_t)i - 256]; g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); } #if CRC_NUM_TABLES < 4 - - g_CrcUpdate = CrcUpdateT1; - - #else - - #ifdef MY_CPU_LE - - g_CrcUpdateT4 = CrcUpdateT4; - g_CrcUpdate = CrcUpdateT4; - - #if CRC_NUM_TABLES >= 8 + g_CrcUpdate = CrcUpdateT1; + #elif defined(MY_CPU_LE) + // g_CrcUpdateT4 = CrcUpdateT4; + #if CRC_NUM_TABLES < 8 + g_CrcUpdate = CrcUpdateT4; + #else // CRC_NUM_TABLES >= 8 g_CrcUpdateT8 = CrcUpdateT8; - + /* #ifdef MY_CPU_X86_OR_AMD64 if (!CPU_Is_InOrder()) #endif - g_CrcUpdate = CrcUpdateT8; + */ + g_CrcUpdate = CrcUpdateT8; #endif - #else { - #ifndef MY_CPU_BE + #ifndef MY_CPU_BE UInt32 k = 0x01020304; const Byte *p = (const Byte *)&k; if (p[0] == 4 && p[1] == 3) { - g_CrcUpdateT4 = CrcUpdateT4; - g_CrcUpdate = CrcUpdateT4; - #if CRC_NUM_TABLES >= 8 - g_CrcUpdateT8 = CrcUpdateT8; - g_CrcUpdate = CrcUpdateT8; + #if CRC_NUM_TABLES < 8 + // g_CrcUpdateT4 = CrcUpdateT4; + g_CrcUpdate = CrcUpdateT4; + #else // CRC_NUM_TABLES >= 8 + g_CrcUpdateT8 = CrcUpdateT8; + g_CrcUpdate = CrcUpdateT8; #endif } else if (p[0] != 1 || p[1] != 2) g_CrcUpdate = CrcUpdateT1; else - #endif + #endif // MY_CPU_BE { for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) { - UInt32 x = g_CrcTable[(size_t)i - 256]; - g_CrcTable[i] = CRC_UINT32_SWAP(x); + const UInt32 x = g_CrcTable[(size_t)i - 256]; + g_CrcTable[i] = Z7_BSWAP32(x); } - g_CrcUpdateT4 = CrcUpdateT1_BeT4; - g_CrcUpdate = CrcUpdateT1_BeT4; - #if CRC_NUM_TABLES >= 8 - g_CrcUpdateT8 = CrcUpdateT1_BeT8; - g_CrcUpdate = CrcUpdateT1_BeT8; + #if CRC_NUM_TABLES <= 4 + g_CrcUpdate = CrcUpdateT1; + #elif CRC_NUM_TABLES <= 8 + // g_CrcUpdateT4 = CrcUpdateT1_BeT4; + g_CrcUpdate = CrcUpdateT1_BeT4; + #else // CRC_NUM_TABLES > 8 + g_CrcUpdateT8 = CrcUpdateT1_BeT8; + g_CrcUpdate = CrcUpdateT1_BeT8; #endif } } - #endif - #endif + #endif // CRC_NUM_TABLES < 4 #ifdef MY_CPU_LE #ifdef USE_ARM64_CRC @@ -320,3 +334,7 @@ void MY_FAST_CALL CrcGenerateTable() #endif #endif } + +#undef kCrcPoly +#undef CRC64_NUM_TABLES +#undef CRC_UPDATE_BYTE_2 diff --git a/libraries/lzma/C/7zCrc.h b/libraries/lzma/C/7zCrc.h index 8fd579587..4afaeae4a 100644 --- a/libraries/lzma/C/7zCrc.h +++ b/libraries/lzma/C/7zCrc.h @@ -1,8 +1,8 @@ /* 7zCrc.h -- CRC32 calculation -2013-01-18 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __7Z_CRC_H -#define __7Z_CRC_H +#ifndef ZIP7_INC_7Z_CRC_H +#define ZIP7_INC_7Z_CRC_H #include "7zTypes.h" @@ -11,14 +11,16 @@ EXTERN_C_BEGIN extern UInt32 g_CrcTable[]; /* Call CrcGenerateTable one time before other CRC functions */ -void MY_FAST_CALL CrcGenerateTable(void); +void Z7_FASTCALL CrcGenerateTable(void); #define CRC_INIT_VAL 0xFFFFFFFF #define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) #define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) -UInt32 MY_FAST_CALL CrcUpdate(UInt32 crc, const void *data, size_t size); -UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size); +UInt32 Z7_FASTCALL CrcUpdate(UInt32 crc, const void *data, size_t size); +UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size); + +typedef UInt32 (Z7_FASTCALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); EXTERN_C_END diff --git a/libraries/lzma/C/7zCrcOpt.c b/libraries/lzma/C/7zCrcOpt.c index 69fad9ca2..9c649290d 100644 --- a/libraries/lzma/C/7zCrcOpt.c +++ b/libraries/lzma/C/7zCrcOpt.c @@ -1,5 +1,5 @@ /* 7zCrcOpt.c -- CRC32 calculation -2021-02-09 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -9,8 +9,8 @@ #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) -UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); -UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) +UInt32 Z7_FASTCALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); +UInt32 Z7_FASTCALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table) { const Byte *p = (const Byte *)data; for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) @@ -29,8 +29,8 @@ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const U return v; } -UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); -UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table) +UInt32 Z7_FASTCALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); +UInt32 Z7_FASTCALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table) { const Byte *p = (const Byte *)data; for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++) @@ -61,11 +61,11 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U #ifndef MY_CPU_LE -#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) +#define CRC_UINT32_SWAP(v) Z7_BSWAP32(v) #define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8)) -UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table) +UInt32 Z7_FASTCALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table) { const Byte *p = (const Byte *)data; table += 0x100; @@ -86,7 +86,7 @@ UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, co return CRC_UINT32_SWAP(v); } -UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table) +UInt32 Z7_FASTCALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table) { const Byte *p = (const Byte *)data; table += 0x100; diff --git a/libraries/lzma/C/7zDec.c b/libraries/lzma/C/7zDec.c index fbfd016e1..96c60359a 100644 --- a/libraries/lzma/C/7zDec.c +++ b/libraries/lzma/C/7zDec.c @@ -1,11 +1,11 @@ /* 7zDec.c -- Decoding from 7z folder -2021-02-09 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" #include -/* #define _7ZIP_PPMD_SUPPPORT */ +/* #define Z7_PPMD_SUPPORT */ #include "7z.h" #include "7zCrc.h" @@ -16,27 +16,49 @@ #include "Delta.h" #include "LzmaDec.h" #include "Lzma2Dec.h" -#ifdef _7ZIP_PPMD_SUPPPORT +#ifdef Z7_PPMD_SUPPORT #include "Ppmd7.h" #endif #define k_Copy 0 -#ifndef _7Z_NO_METHOD_LZMA2 +#ifndef Z7_NO_METHOD_LZMA2 #define k_LZMA2 0x21 #endif #define k_LZMA 0x30101 #define k_BCJ2 0x303011B -#ifndef _7Z_NO_METHODS_FILTERS + +#if !defined(Z7_NO_METHODS_FILTERS) +#define Z7_USE_BRANCH_FILTER +#endif + +#if !defined(Z7_NO_METHODS_FILTERS) || \ + defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARM64) +#define Z7_USE_FILTER_ARM64 +#ifndef Z7_USE_BRANCH_FILTER +#define Z7_USE_BRANCH_FILTER +#endif +#define k_ARM64 0xa +#endif + +#if !defined(Z7_NO_METHODS_FILTERS) || \ + defined(Z7_USE_NATIVE_BRANCH_FILTER) && defined(MY_CPU_ARMT) +#define Z7_USE_FILTER_ARMT +#ifndef Z7_USE_BRANCH_FILTER +#define Z7_USE_BRANCH_FILTER +#endif +#define k_ARMT 0x3030701 +#endif + +#ifndef Z7_NO_METHODS_FILTERS #define k_Delta 3 #define k_BCJ 0x3030103 #define k_PPC 0x3030205 #define k_IA64 0x3030401 #define k_ARM 0x3030501 -#define k_ARMT 0x3030701 #define k_SPARC 0x3030805 #endif -#ifdef _7ZIP_PPMD_SUPPPORT +#ifdef Z7_PPMD_SUPPORT #define k_PPMD 0x30401 @@ -49,12 +71,12 @@ typedef struct UInt64 processed; BoolInt extra; SRes res; - const ILookInStream *inStream; + ILookInStreamPtr inStream; } CByteInToLook; -static Byte ReadByte(const IByteIn *pp) +static Byte ReadByte(IByteInPtr pp) { - CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CByteInToLook) if (p->cur != p->end) return *p->cur++; if (p->res == SZ_OK) @@ -67,13 +89,13 @@ static Byte ReadByte(const IByteIn *pp) p->cur = p->begin; p->end = p->begin + size; if (size != 0) - return *p->cur++;; + return *p->cur++; } p->extra = True; return 0; } -static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream, +static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) { CPpmd7 ppmd; @@ -138,14 +160,14 @@ static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, c #endif -static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, +static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) { CLzmaDec state; SRes res = SZ_OK; - LzmaDec_Construct(&state); - RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain)); + LzmaDec_CONSTRUCT(&state) + RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain)) state.dic = outBuffer; state.dicBufSize = outSize; LzmaDec_Init(&state); @@ -196,18 +218,18 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I } -#ifndef _7Z_NO_METHOD_LZMA2 +#ifndef Z7_NO_METHOD_LZMA2 -static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream, +static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain) { CLzma2Dec state; SRes res = SZ_OK; - Lzma2Dec_Construct(&state); + Lzma2Dec_CONSTRUCT(&state) if (propsSize != 1) return SZ_ERROR_DATA; - RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain)); + RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain)) state.decoder.dic = outBuffer; state.decoder.dicBufSize = outSize; Lzma2Dec_Init(&state); @@ -257,7 +279,7 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, #endif -static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer) +static SRes SzDecodeCopy(UInt64 inSize, ILookInStreamPtr inStream, Byte *outBuffer) { while (inSize > 0) { @@ -265,13 +287,13 @@ static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer size_t curSize = (1 << 18); if (curSize > inSize) curSize = (size_t)inSize; - RINOK(ILookInStream_Look(inStream, &inBuf, &curSize)); + RINOK(ILookInStream_Look(inStream, &inBuf, &curSize)) if (curSize == 0) return SZ_ERROR_INPUT_EOF; memcpy(outBuffer, inBuf, curSize); outBuffer += curSize; inSize -= curSize; - RINOK(ILookInStream_Skip(inStream, curSize)); + RINOK(ILookInStream_Skip(inStream, curSize)) } return SZ_OK; } @@ -282,12 +304,12 @@ static BoolInt IS_MAIN_METHOD(UInt32 m) { case k_Copy: case k_LZMA: - #ifndef _7Z_NO_METHOD_LZMA2 + #ifndef Z7_NO_METHOD_LZMA2 case k_LZMA2: - #endif - #ifdef _7ZIP_PPMD_SUPPPORT + #endif + #ifdef Z7_PPMD_SUPPORT case k_PPMD: - #endif + #endif return True; } return False; @@ -317,7 +339,7 @@ static SRes CheckSupportedFolder(const CSzFolder *f) } - #ifndef _7Z_NO_METHODS_FILTERS + #if defined(Z7_USE_BRANCH_FILTER) if (f->NumCoders == 2) { @@ -333,13 +355,20 @@ static SRes CheckSupportedFolder(const CSzFolder *f) return SZ_ERROR_UNSUPPORTED; switch ((UInt32)c->MethodID) { + #if !defined(Z7_NO_METHODS_FILTERS) case k_Delta: case k_BCJ: case k_PPC: case k_IA64: case k_SPARC: case k_ARM: + #endif + #ifdef Z7_USE_FILTER_ARM64 + case k_ARM64: + #endif + #ifdef Z7_USE_FILTER_ARMT case k_ARMT: + #endif break; default: return SZ_ERROR_UNSUPPORTED; @@ -372,15 +401,16 @@ static SRes CheckSupportedFolder(const CSzFolder *f) return SZ_ERROR_UNSUPPORTED; } -#ifndef _7Z_NO_METHODS_FILTERS -#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; -#endif + + + + static SRes SzFolder_Decode2(const CSzFolder *folder, const Byte *propsData, const UInt64 *unpackSizes, const UInt64 *packPositions, - ILookInStream *inStream, UInt64 startPos, + ILookInStreamPtr inStream, UInt64 startPos, Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain, Byte *tempBuf[]) { @@ -389,7 +419,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, SizeT tempSize3 = 0; Byte *tempBuf3 = 0; - RINOK(CheckSupportedFolder(folder)); + RINOK(CheckSupportedFolder(folder)) for (ci = 0; ci < folder->NumCoders; ci++) { @@ -404,8 +434,8 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, SizeT outSizeCur = outSize; if (folder->NumCoders == 4) { - UInt32 indices[] = { 3, 2, 0 }; - UInt64 unpackSize = unpackSizes[ci]; + const UInt32 indices[] = { 3, 2, 0 }; + const UInt64 unpackSize = unpackSizes[ci]; si = indices[ci]; if (ci < 2) { @@ -431,37 +461,37 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, } offset = packPositions[si]; inSize = packPositions[(size_t)si + 1] - offset; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + RINOK(LookInStream_SeekTo(inStream, startPos + offset)) if (coder->MethodID == k_Copy) { if (inSize != outSizeCur) /* check it */ return SZ_ERROR_DATA; - RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); + RINOK(SzDecodeCopy(inSize, inStream, outBufCur)) } else if (coder->MethodID == k_LZMA) { - RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); + RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)) } - #ifndef _7Z_NO_METHOD_LZMA2 + #ifndef Z7_NO_METHOD_LZMA2 else if (coder->MethodID == k_LZMA2) { - RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); + RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)) } - #endif - #ifdef _7ZIP_PPMD_SUPPPORT + #endif + #ifdef Z7_PPMD_SUPPORT else if (coder->MethodID == k_PPMD) { - RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)); + RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain)) } - #endif + #endif else return SZ_ERROR_UNSUPPORTED; } else if (coder->MethodID == k_BCJ2) { - UInt64 offset = packPositions[1]; - UInt64 s3Size = packPositions[2] - offset; + const UInt64 offset = packPositions[1]; + const UInt64 s3Size = packPositions[2] - offset; if (ci != 3) return SZ_ERROR_UNSUPPORTED; @@ -473,8 +503,8 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, if (!tempBuf[2] && tempSizes[2] != 0) return SZ_ERROR_MEM; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2])); + RINOK(LookInStream_SeekTo(inStream, startPos + offset)) + RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2])) if ((tempSizes[0] & 3) != 0 || (tempSizes[1] & 3) != 0 || @@ -493,26 +523,22 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, p.destLim = outBuffer + outSize; Bcj2Dec_Init(&p); - RINOK(Bcj2Dec_Decode(&p)); + RINOK(Bcj2Dec_Decode(&p)) { unsigned i; for (i = 0; i < 4; i++) if (p.bufs[i] != p.lims[i]) return SZ_ERROR_DATA; - - if (!Bcj2Dec_IsFinished(&p)) - return SZ_ERROR_DATA; - - if (p.dest != p.destLim - || p.state != BCJ2_STREAM_MAIN) + if (p.dest != p.destLim || !Bcj2Dec_IsMaybeFinished(&p)) return SZ_ERROR_DATA; } } } - #ifndef _7Z_NO_METHODS_FILTERS + #if defined(Z7_USE_BRANCH_FILTER) else if (ci == 1) { + #if !defined(Z7_NO_METHODS_FILTERS) if (coder->MethodID == k_Delta) { if (coder->PropsSize != 1) @@ -522,31 +548,53 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, Delta_Init(state); Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize); } + continue; } - else + #endif + + #ifdef Z7_USE_FILTER_ARM64 + if (coder->MethodID == k_ARM64) + { + UInt32 pc = 0; + if (coder->PropsSize == 4) + pc = GetUi32(propsData + coder->PropsOffset); + else if (coder->PropsSize != 0) + return SZ_ERROR_UNSUPPORTED; + z7_BranchConv_ARM64_Dec(outBuffer, outSize, pc); + continue; + } + #endif + + #if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT) { if (coder->PropsSize != 0) return SZ_ERROR_UNSUPPORTED; + #define CASE_BRA_CONV(isa) case k_ ## isa: Z7_BRANCH_CONV_DEC(isa)(outBuffer, outSize, 0); break; // pc = 0; switch (coder->MethodID) { + #if !defined(Z7_NO_METHODS_FILTERS) case k_BCJ: { - UInt32 state; - x86_Convert_Init(state); - x86_Convert(outBuffer, outSize, 0, &state, 0); + UInt32 state = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + z7_BranchConvSt_X86_Dec(outBuffer, outSize, 0, &state); // pc = 0 break; } CASE_BRA_CONV(PPC) CASE_BRA_CONV(IA64) CASE_BRA_CONV(SPARC) CASE_BRA_CONV(ARM) + #endif + #if !defined(Z7_NO_METHODS_FILTERS) || defined(Z7_USE_FILTER_ARMT) CASE_BRA_CONV(ARMT) + #endif default: return SZ_ERROR_UNSUPPORTED; } + continue; } - } - #endif + #endif + } // (c == 1) + #endif else return SZ_ERROR_UNSUPPORTED; } @@ -556,7 +604,7 @@ static SRes SzFolder_Decode2(const CSzFolder *folder, SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, - ILookInStream *inStream, UInt64 startPos, + ILookInStreamPtr inStream, UInt64 startPos, Byte *outBuffer, size_t outSize, ISzAllocPtr allocMain) { diff --git a/libraries/lzma/C/7zFile.c b/libraries/lzma/C/7zFile.c new file mode 100644 index 000000000..ba5daa133 --- /dev/null +++ b/libraries/lzma/C/7zFile.c @@ -0,0 +1,443 @@ +/* 7zFile.c -- File IO +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "7zFile.h" + +#ifndef USE_WINDOWS_FILE + + #include + + #ifndef USE_FOPEN + #include + #include + #ifdef _WIN32 + #include + typedef int ssize_t; + typedef int off_t; + #else + #include + #endif + #endif + +#else + +/* + ReadFile and WriteFile functions in Windows have BUG: + If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) + from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES + (Insufficient system resources exist to complete the requested service). + Probably in some version of Windows there are problems with other sizes: + for 32 MB (maybe also for 16 MB). + And message can be "Network connection was lost" +*/ + +#endif + +#define kChunkSizeMax (1 << 22) + +void File_Construct(CSzFile *p) +{ + #ifdef USE_WINDOWS_FILE + p->handle = INVALID_HANDLE_VALUE; + #elif defined(USE_FOPEN) + p->file = NULL; + #else + p->fd = -1; + #endif +} + +#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) + +static WRes File_Open(CSzFile *p, const char *name, int writeMode) +{ + #ifdef USE_WINDOWS_FILE + + p->handle = CreateFileA(name, + writeMode ? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, NULL, + writeMode ? CREATE_ALWAYS : OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); + + #elif defined(USE_FOPEN) + + p->file = fopen(name, writeMode ? "wb+" : "rb"); + return (p->file != 0) ? 0 : + #ifdef UNDER_CE + 2; /* ENOENT */ + #else + errno; + #endif + + #else + + int flags = (writeMode ? (O_CREAT | O_EXCL | O_WRONLY) : O_RDONLY); + #ifdef O_BINARY + flags |= O_BINARY; + #endif + p->fd = open(name, flags, 0666); + return (p->fd != -1) ? 0 : errno; + + #endif +} + +WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } + +WRes OutFile_Open(CSzFile *p, const char *name) +{ + #if defined(USE_WINDOWS_FILE) || defined(USE_FOPEN) + return File_Open(p, name, 1); + #else + p->fd = creat(name, 0666); + return (p->fd != -1) ? 0 : errno; + #endif +} + +#endif + + +#ifdef USE_WINDOWS_FILE +static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) +{ + p->handle = CreateFileW(name, + writeMode ? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, NULL, + writeMode ? CREATE_ALWAYS : OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); +} +WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } +WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } +#endif + +WRes File_Close(CSzFile *p) +{ + #ifdef USE_WINDOWS_FILE + + if (p->handle != INVALID_HANDLE_VALUE) + { + if (!CloseHandle(p->handle)) + return GetLastError(); + p->handle = INVALID_HANDLE_VALUE; + } + + #elif defined(USE_FOPEN) + + if (p->file != NULL) + { + int res = fclose(p->file); + if (res != 0) + { + if (res == EOF) + return errno; + return res; + } + p->file = NULL; + } + + #else + + if (p->fd != -1) + { + if (close(p->fd) != 0) + return errno; + p->fd = -1; + } + + #endif + + return 0; +} + + +WRes File_Read(CSzFile *p, void *data, size_t *size) +{ + size_t originalSize = *size; + *size = 0; + if (originalSize == 0) + return 0; + + #ifdef USE_WINDOWS_FILE + + do + { + const DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; + DWORD processed = 0; + const BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); + data = (void *)((Byte *)data + processed); + originalSize -= processed; + *size += processed; + if (!res) + return GetLastError(); + // debug : we can break here for partial reading mode + if (processed == 0) + break; + } + while (originalSize > 0); + + #elif defined(USE_FOPEN) + + do + { + const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize; + const size_t processed = fread(data, 1, curSize, p->file); + data = (void *)((Byte *)data + (size_t)processed); + originalSize -= processed; + *size += processed; + if (processed != curSize) + return ferror(p->file); + // debug : we can break here for partial reading mode + if (processed == 0) + break; + } + while (originalSize > 0); + + #else + + do + { + const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize; + const ssize_t processed = read(p->fd, data, curSize); + if (processed == -1) + return errno; + if (processed == 0) + break; + data = (void *)((Byte *)data + (size_t)processed); + originalSize -= (size_t)processed; + *size += (size_t)processed; + // debug : we can break here for partial reading mode + // break; + } + while (originalSize > 0); + + #endif + + return 0; +} + + +WRes File_Write(CSzFile *p, const void *data, size_t *size) +{ + size_t originalSize = *size; + *size = 0; + if (originalSize == 0) + return 0; + + #ifdef USE_WINDOWS_FILE + + do + { + const DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; + DWORD processed = 0; + const BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); + data = (const void *)((const Byte *)data + processed); + originalSize -= processed; + *size += processed; + if (!res) + return GetLastError(); + if (processed == 0) + break; + } + while (originalSize > 0); + + #elif defined(USE_FOPEN) + + do + { + const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize; + const size_t processed = fwrite(data, 1, curSize, p->file); + data = (void *)((Byte *)data + (size_t)processed); + originalSize -= processed; + *size += processed; + if (processed != curSize) + return ferror(p->file); + if (processed == 0) + break; + } + while (originalSize > 0); + + #else + + do + { + const size_t curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : originalSize; + const ssize_t processed = write(p->fd, data, curSize); + if (processed == -1) + return errno; + if (processed == 0) + break; + data = (const void *)((const Byte *)data + (size_t)processed); + originalSize -= (size_t)processed; + *size += (size_t)processed; + } + while (originalSize > 0); + + #endif + + return 0; +} + + +WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin) +{ + #ifdef USE_WINDOWS_FILE + + DWORD moveMethod; + UInt32 low = (UInt32)*pos; + LONG high = (LONG)((UInt64)*pos >> 16 >> 16); /* for case when UInt64 is 32-bit only */ + // (int) to eliminate clang warning + switch ((int)origin) + { + case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; + case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; + case SZ_SEEK_END: moveMethod = FILE_END; break; + default: return ERROR_INVALID_PARAMETER; + } + low = SetFilePointer(p->handle, (LONG)low, &high, moveMethod); + if (low == (UInt32)0xFFFFFFFF) + { + WRes res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *pos = ((Int64)high << 32) | low; + return 0; + + #else + + int moveMethod; // = origin; + + switch ((int)origin) + { + case SZ_SEEK_SET: moveMethod = SEEK_SET; break; + case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; + case SZ_SEEK_END: moveMethod = SEEK_END; break; + default: return EINVAL; + } + + #if defined(USE_FOPEN) + { + int res = fseek(p->file, (long)*pos, moveMethod); + if (res == -1) + return errno; + *pos = ftell(p->file); + if (*pos == -1) + return errno; + return 0; + } + #else + { + off_t res = lseek(p->fd, (off_t)*pos, moveMethod); + if (res == -1) + return errno; + *pos = res; + return 0; + } + + #endif // USE_FOPEN + #endif // USE_WINDOWS_FILE +} + + +WRes File_GetLength(CSzFile *p, UInt64 *length) +{ + #ifdef USE_WINDOWS_FILE + + DWORD sizeHigh; + DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); + if (sizeLow == 0xFFFFFFFF) + { + DWORD res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *length = (((UInt64)sizeHigh) << 32) + sizeLow; + return 0; + + #elif defined(USE_FOPEN) + + long pos = ftell(p->file); + int res = fseek(p->file, 0, SEEK_END); + *length = ftell(p->file); + fseek(p->file, pos, SEEK_SET); + return res; + + #else + + off_t pos; + *length = 0; + pos = lseek(p->fd, 0, SEEK_CUR); + if (pos != -1) + { + const off_t len2 = lseek(p->fd, 0, SEEK_END); + const off_t res2 = lseek(p->fd, pos, SEEK_SET); + if (len2 != -1) + { + *length = (UInt64)len2; + if (res2 != -1) + return 0; + } + } + return errno; + + #endif +} + + +/* ---------- FileSeqInStream ---------- */ + +static SRes FileSeqInStream_Read(ISeqInStreamPtr pp, void *buf, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileSeqInStream) + const WRes wres = File_Read(&p->file, buf, size); + p->wres = wres; + return (wres == 0) ? SZ_OK : SZ_ERROR_READ; +} + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p) +{ + p->vt.Read = FileSeqInStream_Read; +} + + +/* ---------- FileInStream ---------- */ + +static SRes FileInStream_Read(ISeekInStreamPtr pp, void *buf, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileInStream) + const WRes wres = File_Read(&p->file, buf, size); + p->wres = wres; + return (wres == 0) ? SZ_OK : SZ_ERROR_READ; +} + +static SRes FileInStream_Seek(ISeekInStreamPtr pp, Int64 *pos, ESzSeek origin) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileInStream) + const WRes wres = File_Seek(&p->file, pos, origin); + p->wres = wres; + return (wres == 0) ? SZ_OK : SZ_ERROR_READ; +} + +void FileInStream_CreateVTable(CFileInStream *p) +{ + p->vt.Read = FileInStream_Read; + p->vt.Seek = FileInStream_Seek; +} + + +/* ---------- FileOutStream ---------- */ + +static size_t FileOutStream_Write(ISeqOutStreamPtr pp, const void *data, size_t size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CFileOutStream) + const WRes wres = File_Write(&p->file, data, &size); + p->wres = wres; + return size; +} + +void FileOutStream_CreateVTable(CFileOutStream *p) +{ + p->vt.Write = FileOutStream_Write; +} diff --git a/libraries/lzma/C/7zFile.h b/libraries/lzma/C/7zFile.h new file mode 100644 index 000000000..f5069cd9e --- /dev/null +++ b/libraries/lzma/C/7zFile.h @@ -0,0 +1,92 @@ +/* 7zFile.h -- File IO +2023-03-05 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_FILE_H +#define ZIP7_INC_FILE_H + +#ifdef _WIN32 +#define USE_WINDOWS_FILE +// #include +#endif + +#ifdef USE_WINDOWS_FILE +#include "7zWindows.h" + +#else +// note: USE_FOPEN mode is limited to 32-bit file size +// #define USE_FOPEN +// #include +#endif + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* ---------- File ---------- */ + +typedef struct +{ + #ifdef USE_WINDOWS_FILE + HANDLE handle; + #elif defined(USE_FOPEN) + FILE *file; + #else + int fd; + #endif +} CSzFile; + +void File_Construct(CSzFile *p); +#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) +WRes InFile_Open(CSzFile *p, const char *name); +WRes OutFile_Open(CSzFile *p, const char *name); +#endif +#ifdef USE_WINDOWS_FILE +WRes InFile_OpenW(CSzFile *p, const WCHAR *name); +WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); +#endif +WRes File_Close(CSzFile *p); + +/* reads max(*size, remain file's size) bytes */ +WRes File_Read(CSzFile *p, void *data, size_t *size); + +/* writes *size bytes */ +WRes File_Write(CSzFile *p, const void *data, size_t *size); + +WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin); +WRes File_GetLength(CSzFile *p, UInt64 *length); + + +/* ---------- FileInStream ---------- */ + +typedef struct +{ + ISeqInStream vt; + CSzFile file; + WRes wres; +} CFileSeqInStream; + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p); + + +typedef struct +{ + ISeekInStream vt; + CSzFile file; + WRes wres; +} CFileInStream; + +void FileInStream_CreateVTable(CFileInStream *p); + + +typedef struct +{ + ISeqOutStream vt; + CSzFile file; + WRes wres; +} CFileOutStream; + +void FileOutStream_CreateVTable(CFileOutStream *p); + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/7zStream.c b/libraries/lzma/C/7zStream.c index 28a14604f..74e75b65a 100644 --- a/libraries/lzma/C/7zStream.c +++ b/libraries/lzma/C/7zStream.c @@ -1,5 +1,5 @@ /* 7zStream.c -- 7z Stream functions -2021-02-09 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -7,12 +7,33 @@ #include "7zTypes.h" -SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType) + +SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize) +{ + size_t size = *processedSize; + *processedSize = 0; + while (size != 0) + { + size_t cur = size; + const SRes res = ISeqInStream_Read(stream, buf, &cur); + *processedSize += cur; + buf = (void *)((Byte *)buf + cur); + size -= cur; + if (res != SZ_OK) + return res; + if (cur == 0) + return SZ_OK; + } + return SZ_OK; +} + +/* +SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType) { while (size != 0) { size_t processed = size; - RINOK(ISeqInStream_Read(stream, buf, &processed)); + RINOK(ISeqInStream_Read(stream, buf, &processed)) if (processed == 0) return errorType; buf = (void *)((Byte *)buf + processed); @@ -21,42 +42,44 @@ SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes return SZ_OK; } -SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size) +SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size) { return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); } +*/ -SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf) + +SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf) { size_t processed = 1; - RINOK(ISeqInStream_Read(stream, buf, &processed)); + RINOK(ISeqInStream_Read(stream, buf, &processed)) return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; } -SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset) +SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset) { Int64 t = (Int64)offset; return ILookInStream_Seek(stream, &t, SZ_SEEK_SET); } -SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size) +SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size) { const void *lookBuf; if (*size == 0) return SZ_OK; - RINOK(ILookInStream_Look(stream, &lookBuf, size)); + RINOK(ILookInStream_Look(stream, &lookBuf, size)) memcpy(buf, lookBuf, *size); return ILookInStream_Skip(stream, *size); } -SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType) +SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType) { while (size != 0) { size_t processed = size; - RINOK(ILookInStream_Read(stream, buf, &processed)); + RINOK(ILookInStream_Read(stream, buf, &processed)) if (processed == 0) return errorType; buf = (void *)((Byte *)buf + processed); @@ -65,16 +88,16 @@ SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRe return SZ_OK; } -SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size) +SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size) { return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); } -#define GET_LookToRead2 CLookToRead2 *p = CONTAINER_FROM_VTBL(pp, CLookToRead2, vt); +#define GET_LookToRead2 Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLookToRead2) -static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf, size_t *size) +static SRes LookToRead2_Look_Lookahead(ILookInStreamPtr pp, const void **buf, size_t *size) { SRes res = SZ_OK; GET_LookToRead2 @@ -93,7 +116,7 @@ static SRes LookToRead2_Look_Lookahead(const ILookInStream *pp, const void **buf return res; } -static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, size_t *size) +static SRes LookToRead2_Look_Exact(ILookInStreamPtr pp, const void **buf, size_t *size) { SRes res = SZ_OK; GET_LookToRead2 @@ -113,14 +136,14 @@ static SRes LookToRead2_Look_Exact(const ILookInStream *pp, const void **buf, si return res; } -static SRes LookToRead2_Skip(const ILookInStream *pp, size_t offset) +static SRes LookToRead2_Skip(ILookInStreamPtr pp, size_t offset) { GET_LookToRead2 p->pos += offset; return SZ_OK; } -static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size) +static SRes LookToRead2_Read(ILookInStreamPtr pp, void *buf, size_t *size) { GET_LookToRead2 size_t rem = p->size - p->pos; @@ -134,7 +157,7 @@ static SRes LookToRead2_Read(const ILookInStream *pp, void *buf, size_t *size) return SZ_OK; } -static SRes LookToRead2_Seek(const ILookInStream *pp, Int64 *pos, ESzSeek origin) +static SRes LookToRead2_Seek(ILookInStreamPtr pp, Int64 *pos, ESzSeek origin) { GET_LookToRead2 p->pos = p->size = 0; @@ -153,9 +176,9 @@ void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead) -static SRes SecToLook_Read(const ISeqInStream *pp, void *buf, size_t *size) +static SRes SecToLook_Read(ISeqInStreamPtr pp, void *buf, size_t *size) { - CSecToLook *p = CONTAINER_FROM_VTBL(pp, CSecToLook, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSecToLook) return LookInStream_LookRead(p->realStream, buf, size); } @@ -164,9 +187,9 @@ void SecToLook_CreateVTable(CSecToLook *p) p->vt.Read = SecToLook_Read; } -static SRes SecToRead_Read(const ISeqInStream *pp, void *buf, size_t *size) +static SRes SecToRead_Read(ISeqInStreamPtr pp, void *buf, size_t *size) { - CSecToRead *p = CONTAINER_FROM_VTBL(pp, CSecToRead, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSecToRead) return ILookInStream_Read(p->realStream, buf, size); } diff --git a/libraries/lzma/C/7zTypes.h b/libraries/lzma/C/7zTypes.h index fe4fde3ff..1fcb2473e 100644 --- a/libraries/lzma/C/7zTypes.h +++ b/libraries/lzma/C/7zTypes.h @@ -1,8 +1,8 @@ /* 7zTypes.h -- Basic types -2021-12-25 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __7Z_TYPES_H -#define __7Z_TYPES_H +#ifndef ZIP7_7Z_TYPES_H +#define ZIP7_7Z_TYPES_H #ifdef _WIN32 /* #include */ @@ -52,6 +52,11 @@ typedef int SRes; #define MY_ALIGN(n) #endif #else + /* + // C11/C++11: + #include + #define MY_ALIGN(n) alignas(n) + */ #define MY_ALIGN(n) __attribute__ ((aligned(n))) #endif @@ -62,7 +67,7 @@ typedef int SRes; typedef unsigned WRes; #define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x) -// #define MY_HRES_ERROR__INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR) +// #define MY_HRES_ERROR_INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR) #else // _WIN32 @@ -70,13 +75,13 @@ typedef unsigned WRes; typedef int WRes; // (FACILITY_ERRNO = 0x800) is 7zip's FACILITY constant to represent (errno) errors in HRESULT -#define MY__FACILITY_ERRNO 0x800 -#define MY__FACILITY_WIN32 7 -#define MY__FACILITY__WRes MY__FACILITY_ERRNO +#define MY_FACILITY_ERRNO 0x800 +#define MY_FACILITY_WIN32 7 +#define MY_FACILITY_WRes MY_FACILITY_ERRNO #define MY_HRESULT_FROM_errno_CONST_ERROR(x) ((HRESULT)( \ ( (HRESULT)(x) & 0x0000FFFF) \ - | (MY__FACILITY__WRes << 16) \ + | (MY_FACILITY_WRes << 16) \ | (HRESULT)0x80000000 )) #define MY_SRes_HRESULT_FROM_WRes(x) \ @@ -120,23 +125,19 @@ typedef int WRes; #define ERROR_INVALID_REPARSE_DATA ((HRESULT)0x80071128L) #define ERROR_REPARSE_TAG_INVALID ((HRESULT)0x80071129L) -// if (MY__FACILITY__WRes != FACILITY_WIN32), +// if (MY_FACILITY_WRes != FACILITY_WIN32), // we use FACILITY_WIN32 for COM errors: #define E_OUTOFMEMORY ((HRESULT)0x8007000EL) #define E_INVALIDARG ((HRESULT)0x80070057L) -#define MY__E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L) +#define MY_E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L) /* // we can use FACILITY_ERRNO for some COM errors, that have errno equivalents: #define E_OUTOFMEMORY MY_HRESULT_FROM_errno_CONST_ERROR(ENOMEM) #define E_INVALIDARG MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) -#define MY__E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) +#define MY_E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL) */ -// gcc / clang : (sizeof(long) == sizeof(void*)) in 32/64 bits -typedef long INT_PTR; -typedef unsigned long UINT_PTR; - #define TEXT(quote) quote #define FILE_ATTRIBUTE_READONLY 0x0001 @@ -160,18 +161,18 @@ typedef unsigned long UINT_PTR; #ifndef RINOK -#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#define RINOK(x) { const int _result_ = (x); if (_result_ != 0) return _result_; } #endif #ifndef RINOK_WRes -#define RINOK_WRes(x) { WRes __result__ = (x); if (__result__ != 0) return __result__; } +#define RINOK_WRes(x) { const WRes _result_ = (x); if (_result_ != 0) return _result_; } #endif typedef unsigned char Byte; typedef short Int16; typedef unsigned short UInt16; -#ifdef _LZMA_UINT32_IS_ULONG +#ifdef Z7_DECL_Int32_AS_long typedef long Int32; typedef unsigned long UInt32; #else @@ -210,37 +211,51 @@ typedef size_t SIZE_T; #endif // _WIN32 -#define MY_HRES_ERROR__INTERNAL_ERROR ((HRESULT)0x8007054FL) +#define MY_HRES_ERROR_INTERNAL_ERROR ((HRESULT)0x8007054FL) -#ifdef _SZ_NO_INT_64 - -/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. - NOTES: Some code will work incorrectly in that case! */ +#ifdef Z7_DECL_Int64_AS_long typedef long Int64; typedef unsigned long UInt64; #else -#if defined(_MSC_VER) || defined(__BORLANDC__) +#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__clang__) typedef __int64 Int64; typedef unsigned __int64 UInt64; -#define UINT64_CONST(n) n +#else +#if defined(__clang__) || defined(__GNUC__) +#include +typedef int64_t Int64; +typedef uint64_t UInt64; #else typedef long long int Int64; typedef unsigned long long int UInt64; -#define UINT64_CONST(n) n ## ULL +// #define UINT64_CONST(n) n ## ULL +#endif #endif #endif -#ifdef _LZMA_NO_SYSTEM_SIZE_T -typedef UInt32 SizeT; +#define UINT64_CONST(n) n + + +#ifdef Z7_DECL_SizeT_AS_unsigned_int +typedef unsigned int SizeT; #else typedef size_t SizeT; #endif +/* +#if (defined(_MSC_VER) && _MSC_VER <= 1200) +typedef size_t MY_uintptr_t; +#else +#include +typedef uintptr_t MY_uintptr_t; +#endif +*/ + typedef int BoolInt; /* typedef BoolInt Bool; */ #define True 1 @@ -248,23 +263,23 @@ typedef int BoolInt; #ifdef _WIN32 -#define MY_STD_CALL __stdcall +#define Z7_STDCALL __stdcall #else -#define MY_STD_CALL +#define Z7_STDCALL #endif #ifdef _MSC_VER #if _MSC_VER >= 1300 -#define MY_NO_INLINE __declspec(noinline) +#define Z7_NO_INLINE __declspec(noinline) #else -#define MY_NO_INLINE +#define Z7_NO_INLINE #endif -#define MY_FORCE_INLINE __forceinline +#define Z7_FORCE_INLINE __forceinline -#define MY_CDECL __cdecl -#define MY_FAST_CALL __fastcall +#define Z7_CDECL __cdecl +#define Z7_FASTCALL __fastcall #else // _MSC_VER @@ -272,27 +287,25 @@ typedef int BoolInt; || (defined(__clang__) && (__clang_major__ >= 4)) \ || defined(__INTEL_COMPILER) \ || defined(__xlC__) -#define MY_NO_INLINE __attribute__((noinline)) -// #define MY_FORCE_INLINE __attribute__((always_inline)) inline +#define Z7_NO_INLINE __attribute__((noinline)) +#define Z7_FORCE_INLINE __attribute__((always_inline)) inline #else -#define MY_NO_INLINE +#define Z7_NO_INLINE +#define Z7_FORCE_INLINE #endif -#define MY_FORCE_INLINE - - -#define MY_CDECL +#define Z7_CDECL #if defined(_M_IX86) \ || defined(__i386__) -// #define MY_FAST_CALL __attribute__((fastcall)) -// #define MY_FAST_CALL __attribute__((cdecl)) -#define MY_FAST_CALL +// #define Z7_FASTCALL __attribute__((fastcall)) +// #define Z7_FASTCALL __attribute__((cdecl)) +#define Z7_FASTCALL #elif defined(MY_CPU_AMD64) -// #define MY_FAST_CALL __attribute__((ms_abi)) -#define MY_FAST_CALL +// #define Z7_FASTCALL __attribute__((ms_abi)) +#define Z7_FASTCALL #else -#define MY_FAST_CALL +#define Z7_FASTCALL #endif #endif // _MSC_VER @@ -300,41 +313,49 @@ typedef int BoolInt; /* The following interfaces use first parameter as pointer to structure */ -typedef struct IByteIn IByteIn; -struct IByteIn +// #define Z7_C_IFACE_CONST_QUAL +#define Z7_C_IFACE_CONST_QUAL const + +#define Z7_C_IFACE_DECL(a) \ + struct a ## _; \ + typedef Z7_C_IFACE_CONST_QUAL struct a ## _ * a ## Ptr; \ + typedef struct a ## _ a; \ + struct a ## _ + + +Z7_C_IFACE_DECL (IByteIn) { - Byte (*Read)(const IByteIn *p); /* reads one byte, returns 0 in case of EOF or error */ + Byte (*Read)(IByteInPtr p); /* reads one byte, returns 0 in case of EOF or error */ }; #define IByteIn_Read(p) (p)->Read(p) -typedef struct IByteOut IByteOut; -struct IByteOut +Z7_C_IFACE_DECL (IByteOut) { - void (*Write)(const IByteOut *p, Byte b); + void (*Write)(IByteOutPtr p, Byte b); }; #define IByteOut_Write(p, b) (p)->Write(p, b) -typedef struct ISeqInStream ISeqInStream; -struct ISeqInStream +Z7_C_IFACE_DECL (ISeqInStream) { - SRes (*Read)(const ISeqInStream *p, void *buf, size_t *size); + SRes (*Read)(ISeqInStreamPtr p, void *buf, size_t *size); /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. (output(*size) < input(*size)) is allowed */ }; #define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size) +/* try to read as much as avail in stream and limited by (*processedSize) */ +SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize); /* it can return SZ_ERROR_INPUT_EOF */ -SRes SeqInStream_Read(const ISeqInStream *stream, void *buf, size_t size); -SRes SeqInStream_Read2(const ISeqInStream *stream, void *buf, size_t size, SRes errorType); -SRes SeqInStream_ReadByte(const ISeqInStream *stream, Byte *buf); +// SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size); +// SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType); +SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf); -typedef struct ISeqOutStream ISeqOutStream; -struct ISeqOutStream +Z7_C_IFACE_DECL (ISeqOutStream) { - size_t (*Write)(const ISeqOutStream *p, const void *buf, size_t size); + size_t (*Write)(ISeqOutStreamPtr p, const void *buf, size_t size); /* Returns: result - the number of actually written bytes. (result < size) means error */ }; @@ -348,29 +369,26 @@ typedef enum } ESzSeek; -typedef struct ISeekInStream ISeekInStream; -struct ISeekInStream +Z7_C_IFACE_DECL (ISeekInStream) { - SRes (*Read)(const ISeekInStream *p, void *buf, size_t *size); /* same as ISeqInStream::Read */ - SRes (*Seek)(const ISeekInStream *p, Int64 *pos, ESzSeek origin); + SRes (*Read)(ISeekInStreamPtr p, void *buf, size_t *size); /* same as ISeqInStream::Read */ + SRes (*Seek)(ISeekInStreamPtr p, Int64 *pos, ESzSeek origin); }; #define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size) #define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) -typedef struct ILookInStream ILookInStream; -struct ILookInStream +Z7_C_IFACE_DECL (ILookInStream) { - SRes (*Look)(const ILookInStream *p, const void **buf, size_t *size); + SRes (*Look)(ILookInStreamPtr p, const void **buf, size_t *size); /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. (output(*size) > input(*size)) is not allowed (output(*size) < input(*size)) is allowed */ - SRes (*Skip)(const ILookInStream *p, size_t offset); + SRes (*Skip)(ILookInStreamPtr p, size_t offset); /* offset must be <= output(*size) of Look */ - - SRes (*Read)(const ILookInStream *p, void *buf, size_t *size); + SRes (*Read)(ILookInStreamPtr p, void *buf, size_t *size); /* reads directly (without buffer). It's same as ISeqInStream::Read */ - SRes (*Seek)(const ILookInStream *p, Int64 *pos, ESzSeek origin); + SRes (*Seek)(ILookInStreamPtr p, Int64 *pos, ESzSeek origin); }; #define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size) @@ -379,19 +397,18 @@ struct ILookInStream #define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin) -SRes LookInStream_LookRead(const ILookInStream *stream, void *buf, size_t *size); -SRes LookInStream_SeekTo(const ILookInStream *stream, UInt64 offset); +SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size); +SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset); /* reads via ILookInStream::Read */ -SRes LookInStream_Read2(const ILookInStream *stream, void *buf, size_t size, SRes errorType); -SRes LookInStream_Read(const ILookInStream *stream, void *buf, size_t size); - +SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType); +SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size); typedef struct { ILookInStream vt; - const ISeekInStream *realStream; + ISeekInStreamPtr realStream; size_t pos; size_t size; /* it's data size */ @@ -403,13 +420,13 @@ typedef struct void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead); -#define LookToRead2_Init(p) { (p)->pos = (p)->size = 0; } +#define LookToRead2_INIT(p) { (p)->pos = (p)->size = 0; } typedef struct { ISeqInStream vt; - const ILookInStream *realStream; + ILookInStreamPtr realStream; } CSecToLook; void SecToLook_CreateVTable(CSecToLook *p); @@ -419,20 +436,19 @@ void SecToLook_CreateVTable(CSecToLook *p); typedef struct { ISeqInStream vt; - const ILookInStream *realStream; + ILookInStreamPtr realStream; } CSecToRead; void SecToRead_CreateVTable(CSecToRead *p); -typedef struct ICompressProgress ICompressProgress; - -struct ICompressProgress +Z7_C_IFACE_DECL (ICompressProgress) { - SRes (*Progress)(const ICompressProgress *p, UInt64 inSize, UInt64 outSize); + SRes (*Progress)(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize); /* Returns: result. (result != SZ_OK) means break. Value (UInt64)(Int64)-1 for size means unknown value. */ }; + #define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize) @@ -470,13 +486,13 @@ struct ISzAlloc -#ifndef MY_container_of +#ifndef Z7_container_of /* -#define MY_container_of(ptr, type, m) container_of(ptr, type, m) -#define MY_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m) -#define MY_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m))) -#define MY_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m)))) +#define Z7_container_of(ptr, type, m) container_of(ptr, type, m) +#define Z7_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m) +#define Z7_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m))) +#define Z7_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m)))) */ /* @@ -485,24 +501,64 @@ struct ISzAlloc GCC 4.8.1 : classes with non-public variable members" */ -#define MY_container_of(ptr, type, m) ((type *)(void *)((char *)(void *)(1 ? (ptr) : &((type *)0)->m) - MY_offsetof(type, m))) +#define Z7_container_of(ptr, type, m) \ + ((type *)(void *)((char *)(void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) + +#define Z7_container_of_CONST(ptr, type, m) \ + ((const type *)(const void *)((const char *)(const void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) + +/* +#define Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) \ + ((type *)(void *)(const void *)((const char *)(const void *) \ + (1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m))) +*/ #endif -#define CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr)) +#define Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr)) +// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +#define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of(ptr, type, m) +// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) + +#define Z7_CONTAINER_FROM_VTBL_CONST(ptr, type, m) Z7_container_of_CONST(ptr, type, m) + +#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) /* -#define CONTAINER_FROM_VTBL(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) +#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL(ptr, type, m) */ -#define CONTAINER_FROM_VTBL(ptr, type, m) MY_container_of(ptr, type, m) +#if defined (__clang__) || defined(__GNUC__) +#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_CAST_QUAL \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") +#define Z7_DIAGNOSCTIC_IGNORE_END_CAST_QUAL \ + _Pragma("GCC diagnostic pop") +#else +#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_CAST_QUAL +#define Z7_DIAGNOSCTIC_IGNORE_END_CAST_QUAL +#endif -#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) -/* -#define CONTAINER_FROM_VTBL_CLS(ptr, type, m) CONTAINER_FROM_VTBL(ptr, type, m) -*/ +#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(ptr, type, m, p) \ + Z7_DIAGNOSCTIC_IGNORE_BEGIN_CAST_QUAL \ + type *p = Z7_CONTAINER_FROM_VTBL(ptr, type, m); \ + Z7_DIAGNOSCTIC_IGNORE_END_CAST_QUAL + +#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(type) \ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(pp, type, vt, p) -#define MY_memset_0_ARRAY(a) memset((a), 0, sizeof(a)) +// #define ZIP7_DECLARE_HANDLE(name) typedef void *name; +#define Z7_DECLARE_HANDLE(name) struct name##_dummy{int unused;}; typedef struct name##_dummy *name; + + +#define Z7_memset_0_ARRAY(a) memset((a), 0, sizeof(a)) + +#ifndef Z7_ARRAY_SIZE +#define Z7_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + #ifdef _WIN32 @@ -520,6 +576,22 @@ struct ISzAlloc #endif +#define k_PropVar_TimePrec_0 0 +#define k_PropVar_TimePrec_Unix 1 +#define k_PropVar_TimePrec_DOS 2 +#define k_PropVar_TimePrec_HighPrec 3 +#define k_PropVar_TimePrec_Base 16 +#define k_PropVar_TimePrec_100ns (k_PropVar_TimePrec_Base + 7) +#define k_PropVar_TimePrec_1ns (k_PropVar_TimePrec_Base + 9) + EXTERN_C_END #endif + +/* +#ifndef Z7_ST +#ifdef _7ZIP_ST +#define Z7_ST +#endif +#endif +*/ diff --git a/libraries/lzma/C/7zVersion.h b/libraries/lzma/C/7zVersion.h index e9363d37b..754923961 100644 --- a/libraries/lzma/C/7zVersion.h +++ b/libraries/lzma/C/7zVersion.h @@ -1,7 +1,7 @@ -#define MY_VER_MAJOR 21 -#define MY_VER_MINOR 07 +#define MY_VER_MAJOR 23 +#define MY_VER_MINOR 01 #define MY_VER_BUILD 0 -#define MY_VERSION_NUMBERS "21.07" +#define MY_VERSION_NUMBERS "23.01" #define MY_VERSION MY_VERSION_NUMBERS #ifdef MY_CPU_NAME @@ -10,12 +10,12 @@ #define MY_VERSION_CPU MY_VERSION #endif -#define MY_DATE "2021-12-26" +#define MY_DATE "2023-06-20" #undef MY_COPYRIGHT #undef MY_VERSION_COPYRIGHT_DATE #define MY_AUTHOR_NAME "Igor Pavlov" #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" -#define MY_COPYRIGHT_CR "Copyright (c) 1999-2021 Igor Pavlov" +#define MY_COPYRIGHT_CR "Copyright (c) 1999-2023 Igor Pavlov" #ifdef USE_COPYRIGHT_CR #define MY_COPYRIGHT MY_COPYRIGHT_CR diff --git a/libraries/lzma/C/7zWindows.h b/libraries/lzma/C/7zWindows.h new file mode 100644 index 000000000..42c6db8bf --- /dev/null +++ b/libraries/lzma/C/7zWindows.h @@ -0,0 +1,101 @@ +/* 7zWindows.h -- StdAfx +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_7Z_WINDOWS_H +#define ZIP7_INC_7Z_WINDOWS_H + +#ifdef _WIN32 + +#if defined(__clang__) +# pragma clang diagnostic push +#endif + +#if defined(_MSC_VER) + +#pragma warning(push) +#pragma warning(disable : 4668) // '_WIN32_WINNT' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' + +#if _MSC_VER == 1900 +// for old kit10 versions +// #pragma warning(disable : 4255) // winuser.h(13979): warning C4255: 'GetThreadDpiAwarenessContext': +#endif +// win10 Windows Kit: +#endif // _MSC_VER + +#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64) +// for msvc6 without sdk2003 +#define RPC_NO_WINDOWS_H +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +// #if defined(__GNUC__) && !defined(__clang__) +#include +#else +#include +#endif +// #include +// #include + +// but if precompiled with clang-cl then we need +// #include +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +#if defined(__clang__) +# pragma clang diagnostic pop +#endif + +#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64) +#ifndef _W64 + +typedef long LONG_PTR, *PLONG_PTR; +typedef unsigned long ULONG_PTR, *PULONG_PTR; +typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; + +#define Z7_OLD_WIN_SDK +#endif // _W64 +#endif // _MSC_VER == 1200 + +#ifdef Z7_OLD_WIN_SDK + +#ifndef INVALID_FILE_ATTRIBUTES +#define INVALID_FILE_ATTRIBUTES ((DWORD)-1) +#endif +#ifndef INVALID_SET_FILE_POINTER +#define INVALID_SET_FILE_POINTER ((DWORD)-1) +#endif +#ifndef FILE_SPECIAL_ACCESS +#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) +#endif + +// ShlObj.h: +// #define BIF_NEWDIALOGSTYLE 0x0040 + +#pragma warning(disable : 4201) +// #pragma warning(disable : 4115) + +#undef VARIANT_TRUE +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#endif + +#endif // Z7_OLD_WIN_SDK + +#ifdef UNDER_CE +#undef VARIANT_TRUE +#define VARIANT_TRUE ((VARIANT_BOOL)-1) +#endif + + +#if defined(_MSC_VER) +#if _MSC_VER >= 1400 && _MSC_VER <= 1600 + // BaseTsd.h(148) : 'HandleToULong' : unreferenced inline function has been removed + // string.h + // #pragma warning(disable : 4514) +#endif +#endif + + +/* #include "7zTypes.h" */ + +#endif diff --git a/libraries/lzma/C/Aes.c b/libraries/lzma/C/Aes.c new file mode 100644 index 000000000..bcaafab11 --- /dev/null +++ b/libraries/lzma/C/Aes.c @@ -0,0 +1,393 @@ +/* Aes.c -- AES encryption / decryption +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" +#include "Aes.h" + +AES_CODE_FUNC g_AesCbc_Decode; +#ifndef Z7_SFX +AES_CODE_FUNC g_AesCbc_Encode; +AES_CODE_FUNC g_AesCtr_Code; +UInt32 g_Aes_SupportedFunctions_Flags; +#endif + +static UInt32 T[256 * 4]; +static const Byte Sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; + + +static UInt32 D[256 * 4]; +static Byte InvS[256]; + +#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) + +#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24)) + +#define gb0(x) ( (x) & 0xFF) +#define gb1(x) (((x) >> ( 8)) & 0xFF) +#define gb2(x) (((x) >> (16)) & 0xFF) +#define gb3(x) (((x) >> (24))) + +#define gb(n, x) gb ## n(x) + +#define TT(x) (T + (x << 8)) +#define DD(x) (D + (x << 8)) + + +// #define Z7_SHOW_AES_STATUS + +#ifdef MY_CPU_X86_OR_AMD64 + #define USE_HW_AES +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + #if defined(__clang__) + #if (__clang_major__ >= 8) // fix that check + #define USE_HW_AES + #endif + #elif defined(__GNUC__) + #if (__GNUC__ >= 6) // fix that check + #define USE_HW_AES + #endif + #elif defined(_MSC_VER) + #if _MSC_VER >= 1910 + #define USE_HW_AES + #endif + #endif +#endif + +#ifdef USE_HW_AES +#ifdef Z7_SHOW_AES_STATUS +#include +#define PRF(x) x +#else +#define PRF(x) +#endif +#endif + + +void AesGenTables(void) +{ + unsigned i; + for (i = 0; i < 256; i++) + InvS[Sbox[i]] = (Byte)i; + + for (i = 0; i < 256; i++) + { + { + const UInt32 a1 = Sbox[i]; + const UInt32 a2 = xtime(a1); + const UInt32 a3 = a2 ^ a1; + TT(0)[i] = Ui32(a2, a1, a1, a3); + TT(1)[i] = Ui32(a3, a2, a1, a1); + TT(2)[i] = Ui32(a1, a3, a2, a1); + TT(3)[i] = Ui32(a1, a1, a3, a2); + } + { + const UInt32 a1 = InvS[i]; + const UInt32 a2 = xtime(a1); + const UInt32 a4 = xtime(a2); + const UInt32 a8 = xtime(a4); + const UInt32 a9 = a8 ^ a1; + const UInt32 aB = a8 ^ a2 ^ a1; + const UInt32 aD = a8 ^ a4 ^ a1; + const UInt32 aE = a8 ^ a4 ^ a2; + DD(0)[i] = Ui32(aE, a9, aD, aB); + DD(1)[i] = Ui32(aB, aE, a9, aD); + DD(2)[i] = Ui32(aD, aB, aE, a9); + DD(3)[i] = Ui32(a9, aD, aB, aE); + } + } + + { + AES_CODE_FUNC d = AesCbc_Decode; + #ifndef Z7_SFX + AES_CODE_FUNC e = AesCbc_Encode; + AES_CODE_FUNC c = AesCtr_Code; + UInt32 flags = 0; + #endif + + #ifdef USE_HW_AES + if (CPU_IsSupported_AES()) + { + // #pragma message ("AES HW") + PRF(printf("\n===AES HW\n")); + d = AesCbc_Decode_HW; + + #ifndef Z7_SFX + e = AesCbc_Encode_HW; + c = AesCtr_Code_HW; + flags = k_Aes_SupportedFunctions_HW; + #endif + + #ifdef MY_CPU_X86_OR_AMD64 + if (CPU_IsSupported_VAES_AVX2()) + { + PRF(printf("\n===vaes avx2\n")); + d = AesCbc_Decode_HW_256; + #ifndef Z7_SFX + c = AesCtr_Code_HW_256; + flags |= k_Aes_SupportedFunctions_HW_256; + #endif + } + #endif + } + #endif + + g_AesCbc_Decode = d; + #ifndef Z7_SFX + g_AesCbc_Encode = e; + g_AesCtr_Code = c; + g_Aes_SupportedFunctions_Flags = flags; + #endif + } +} + + +#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])] + +#define HT4(m, i, s, p) m[i] = \ + HT(i, 0, s) ^ \ + HT(i, 1, s) ^ \ + HT(i, 2, s) ^ \ + HT(i, 3, s) ^ w[p + i] + +#define HT16(m, s, p) \ + HT4(m, 0, s, p); \ + HT4(m, 1, s, p); \ + HT4(m, 2, s, p); \ + HT4(m, 3, s, p); \ + +#define FT(i, x) Sbox[gb(x, m[(i + x) & 3])] +#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i]; + + +#define HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3])] + +#define HD4(m, i, s, p) m[i] = \ + HD(i, 0, s) ^ \ + HD(i, 1, s) ^ \ + HD(i, 2, s) ^ \ + HD(i, 3, s) ^ w[p + i]; + +#define HD16(m, s, p) \ + HD4(m, 0, s, p); \ + HD4(m, 1, s, p); \ + HD4(m, 2, s, p); \ + HD4(m, 3, s, p); \ + +#define FD(i, x) InvS[gb(x, m[(i - x) & 3])] +#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; + +void Z7_FASTCALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize) +{ + unsigned i, m; + const UInt32 *wLim; + UInt32 t; + UInt32 rcon = 1; + + keySize /= 4; + w[0] = ((UInt32)keySize / 2) + 3; + w += 4; + + for (i = 0; i < keySize; i++, key += 4) + w[i] = GetUi32(key); + + t = w[(size_t)keySize - 1]; + wLim = w + (size_t)keySize * 3 + 28; + m = 0; + do + { + if (m == 0) + { + t = Ui32(Sbox[gb1(t)] ^ rcon, Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]); + rcon <<= 1; + if (rcon & 0x100) + rcon = 0x1b; + m = keySize; + } + else if (m == 4 && keySize > 6) + t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]); + m--; + t ^= w[0]; + w[keySize] = t; + } + while (++w != wLim); +} + +void Z7_FASTCALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize) +{ + unsigned i, num; + Aes_SetKey_Enc(w, key, keySize); + num = keySize + 20; + w += 8; + for (i = 0; i < num; i++) + { + UInt32 r = w[i]; + w[i] = + DD(0)[Sbox[gb0(r)]] ^ + DD(1)[Sbox[gb1(r)]] ^ + DD(2)[Sbox[gb2(r)]] ^ + DD(3)[Sbox[gb3(r)]]; + } +} + +/* Aes_Encode and Aes_Decode functions work with little-endian words. + src and dest are pointers to 4 UInt32 words. + src and dest can point to same block */ + +// Z7_FORCE_INLINE +static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src) +{ + UInt32 s[4]; + UInt32 m[4]; + UInt32 numRounds2 = w[0]; + w += 4; + s[0] = src[0] ^ w[0]; + s[1] = src[1] ^ w[1]; + s[2] = src[2] ^ w[2]; + s[3] = src[3] ^ w[3]; + w += 4; + for (;;) + { + HT16(m, s, 0) + if (--numRounds2 == 0) + break; + HT16(s, m, 4) + w += 8; + } + w += 4; + FT4(0) + FT4(1) + FT4(2) + FT4(3) +} + +Z7_FORCE_INLINE +static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src) +{ + UInt32 s[4]; + UInt32 m[4]; + UInt32 numRounds2 = w[0]; + w += 4 + numRounds2 * 8; + s[0] = src[0] ^ w[0]; + s[1] = src[1] ^ w[1]; + s[2] = src[2] ^ w[2]; + s[3] = src[3] ^ w[3]; + for (;;) + { + w -= 8; + HD16(m, s, 4) + if (--numRounds2 == 0) + break; + HD16(s, m, 0) + } + FD4(0) + FD4(1) + FD4(2) + FD4(3) +} + +void AesCbc_Init(UInt32 *p, const Byte *iv) +{ + unsigned i; + for (i = 0; i < 4; i++) + p[i] = GetUi32(iv + i * 4); +} + +void Z7_FASTCALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks) +{ + for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) + { + p[0] ^= GetUi32(data); + p[1] ^= GetUi32(data + 4); + p[2] ^= GetUi32(data + 8); + p[3] ^= GetUi32(data + 12); + + Aes_Encode(p + 4, p, p); + + SetUi32(data, p[0]) + SetUi32(data + 4, p[1]) + SetUi32(data + 8, p[2]) + SetUi32(data + 12, p[3]) + } +} + +void Z7_FASTCALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks) +{ + UInt32 in[4], out[4]; + for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) + { + in[0] = GetUi32(data); + in[1] = GetUi32(data + 4); + in[2] = GetUi32(data + 8); + in[3] = GetUi32(data + 12); + + Aes_Decode(p + 4, out, in); + + SetUi32(data, p[0] ^ out[0]) + SetUi32(data + 4, p[1] ^ out[1]) + SetUi32(data + 8, p[2] ^ out[2]) + SetUi32(data + 12, p[3] ^ out[3]) + + p[0] = in[0]; + p[1] = in[1]; + p[2] = in[2]; + p[3] = in[3]; + } +} + +void Z7_FASTCALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks) +{ + for (; numBlocks != 0; numBlocks--) + { + UInt32 temp[4]; + unsigned i; + + if (++p[0] == 0) + p[1]++; + + Aes_Encode(p + 4, temp, p); + + for (i = 0; i < 4; i++, data += 4) + { + const UInt32 t = temp[i]; + + #ifdef MY_CPU_LE_UNALIGN + *((UInt32 *)(void *)data) ^= t; + #else + data[0] = (Byte)(data[0] ^ (t & 0xFF)); + data[1] = (Byte)(data[1] ^ ((t >> 8) & 0xFF)); + data[2] = (Byte)(data[2] ^ ((t >> 16) & 0xFF)); + data[3] = (Byte)(data[3] ^ ((t >> 24))); + #endif + } + } +} + +#undef xtime +#undef Ui32 +#undef gb0 +#undef gb1 +#undef gb2 +#undef gb3 +#undef gb +#undef TT +#undef DD +#undef USE_HW_AES +#undef PRF diff --git a/libraries/lzma/C/Aes.h b/libraries/lzma/C/Aes.h new file mode 100644 index 000000000..7f0182ac0 --- /dev/null +++ b/libraries/lzma/C/Aes.h @@ -0,0 +1,60 @@ +/* Aes.h -- AES encryption / decryption +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_AES_H +#define ZIP7_INC_AES_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define AES_BLOCK_SIZE 16 + +/* Call AesGenTables one time before other AES functions */ +void AesGenTables(void); + +/* UInt32 pointers must be 16-byte aligned */ + +/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */ +#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4) + +/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */ +/* keySize = 16 or 24 or 32 (bytes) */ +typedef void (Z7_FASTCALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize); +void Z7_FASTCALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize); +void Z7_FASTCALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize); + +/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */ +void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ + +/* data - 16-byte aligned pointer to data */ +/* numBlocks - the number of 16-byte blocks in data array */ +typedef void (Z7_FASTCALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks); + +extern AES_CODE_FUNC g_AesCbc_Decode; +#ifndef Z7_SFX +extern AES_CODE_FUNC g_AesCbc_Encode; +extern AES_CODE_FUNC g_AesCtr_Code; +#define k_Aes_SupportedFunctions_HW (1 << 2) +#define k_Aes_SupportedFunctions_HW_256 (1 << 3) +extern UInt32 g_Aes_SupportedFunctions_Flags; +#endif + + +#define Z7_DECLARE_AES_CODE_FUNC(funcName) \ + void Z7_FASTCALL funcName(UInt32 *ivAes, Byte *data, size_t numBlocks); + +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Encode) +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode) +Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code) + +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Encode_HW) +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode_HW) +Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code_HW) + +Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode_HW_256) +Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code_HW_256) + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/AesOpt.c b/libraries/lzma/C/AesOpt.c new file mode 100644 index 000000000..cfa6413f4 --- /dev/null +++ b/libraries/lzma/C/AesOpt.c @@ -0,0 +1,840 @@ +/* AesOpt.c -- AES optimized code for x86 AES hardware instructions +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Aes.h" +#include "CpuArch.h" + +#ifdef MY_CPU_X86_OR_AMD64 + + #if defined(__INTEL_COMPILER) + #if (__INTEL_COMPILER >= 1110) + #define USE_INTEL_AES + #if (__INTEL_COMPILER >= 1900) + #define USE_INTEL_VAES + #endif + #endif + #elif defined(__clang__) && (__clang_major__ > 3 || __clang_major__ == 3 && __clang_minor__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4) + #define USE_INTEL_AES + #if !defined(__AES__) + #define ATTRIB_AES __attribute__((__target__("aes"))) + #endif + #if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 8) + #define USE_INTEL_VAES + #if !defined(__AES__) || !defined(__VAES__) || !defined(__AVX__) || !defined(__AVX2__) + #define ATTRIB_VAES __attribute__((__target__("aes,vaes,avx,avx2"))) + #endif + #endif + #elif defined(_MSC_VER) + #if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729) + #define USE_INTEL_AES + #if (_MSC_VER >= 1910) + #define USE_INTEL_VAES + #endif + #endif + #endif + +#ifndef ATTRIB_AES + #define ATTRIB_AES +#endif +#ifndef ATTRIB_VAES + #define ATTRIB_VAES +#endif + + +#ifdef USE_INTEL_AES + +#include + +#ifndef USE_INTEL_VAES +#define AES_TYPE_keys UInt32 +#define AES_TYPE_data Byte +// #define AES_TYPE_keys __m128i +// #define AES_TYPE_data __m128i +#endif + +#define AES_FUNC_START(name) \ + void Z7_FASTCALL name(UInt32 *ivAes, Byte *data8, size_t numBlocks) + // void Z7_FASTCALL name(__m128i *p, __m128i *data, size_t numBlocks) + +#define AES_FUNC_START2(name) \ +AES_FUNC_START (name); \ +ATTRIB_AES \ +AES_FUNC_START (name) + +#define MM_OP(op, dest, src) dest = op(dest, src); +#define MM_OP_m(op, src) MM_OP(op, m, src) + +#define MM_XOR( dest, src) MM_OP(_mm_xor_si128, dest, src) +#define AVX_XOR(dest, src) MM_OP(_mm256_xor_si256, dest, src) + + +AES_FUNC_START2 (AesCbc_Encode_HW) +{ + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; + __m128i m = *p; + const __m128i k0 = p[2]; + const __m128i k1 = p[3]; + const UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; + for (; numBlocks != 0; numBlocks--, data++) + { + UInt32 r = numRounds2; + const __m128i *w = p + 4; + __m128i temp = *data; + MM_XOR (temp, k0) + MM_XOR (m, temp) + MM_OP_m (_mm_aesenc_si128, k1) + do + { + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenc_si128, w[1]) + w += 2; + } + while (--r); + MM_OP_m (_mm_aesenclast_si128, w[0]) + *data = m; + } + *p = m; +} + + +#define WOP_1(op) +#define WOP_2(op) WOP_1 (op) op (m1, 1) +#define WOP_3(op) WOP_2 (op) op (m2, 2) +#define WOP_4(op) WOP_3 (op) op (m3, 3) +#ifdef MY_CPU_AMD64 +#define WOP_5(op) WOP_4 (op) op (m4, 4) +#define WOP_6(op) WOP_5 (op) op (m5, 5) +#define WOP_7(op) WOP_6 (op) op (m6, 6) +#define WOP_8(op) WOP_7 (op) op (m7, 7) +#endif +/* +#define WOP_9(op) WOP_8 (op) op (m8, 8); +#define WOP_10(op) WOP_9 (op) op (m9, 9); +#define WOP_11(op) WOP_10(op) op (m10, 10); +#define WOP_12(op) WOP_11(op) op (m11, 11); +#define WOP_13(op) WOP_12(op) op (m12, 12); +#define WOP_14(op) WOP_13(op) op (m13, 13); +*/ + +#ifdef MY_CPU_AMD64 + #define NUM_WAYS 8 + #define WOP_M1 WOP_8 +#else + #define NUM_WAYS 4 + #define WOP_M1 WOP_4 +#endif + +#define WOP(op) op (m0, 0) WOP_M1(op) + + +#define DECLARE_VAR(reg, ii) __m128i reg; +#define LOAD_data( reg, ii) reg = data[ii]; +#define STORE_data( reg, ii) data[ii] = reg; +#if (NUM_WAYS > 1) +#define XOR_data_M1(reg, ii) MM_XOR (reg, data[ii- 1]) +#endif + +#define AVX_DECLARE_VAR(reg, ii) __m256i reg; +#define AVX_LOAD_data( reg, ii) reg = ((const __m256i *)(const void *)data)[ii]; +#define AVX_STORE_data( reg, ii) ((__m256i *)(void *)data)[ii] = reg; +#define AVX_XOR_data_M1(reg, ii) AVX_XOR (reg, (((const __m256i *)(const void *)(data - 1))[ii])) + +#define MM_OP_key(op, reg) MM_OP(op, reg, key); + +#define AES_DEC( reg, ii) MM_OP_key (_mm_aesdec_si128, reg) +#define AES_DEC_LAST( reg, ii) MM_OP_key (_mm_aesdeclast_si128, reg) +#define AES_ENC( reg, ii) MM_OP_key (_mm_aesenc_si128, reg) +#define AES_ENC_LAST( reg, ii) MM_OP_key (_mm_aesenclast_si128, reg) +#define AES_XOR( reg, ii) MM_OP_key (_mm_xor_si128, reg) + + +#define AVX_AES_DEC( reg, ii) MM_OP_key (_mm256_aesdec_epi128, reg) +#define AVX_AES_DEC_LAST( reg, ii) MM_OP_key (_mm256_aesdeclast_epi128, reg) +#define AVX_AES_ENC( reg, ii) MM_OP_key (_mm256_aesenc_epi128, reg) +#define AVX_AES_ENC_LAST( reg, ii) MM_OP_key (_mm256_aesenclast_epi128, reg) +#define AVX_AES_XOR( reg, ii) MM_OP_key (_mm256_xor_si256, reg) + +#define CTR_START(reg, ii) MM_OP (_mm_add_epi64, ctr, one) reg = ctr; +#define CTR_END( reg, ii) MM_XOR (data[ii], reg) + +#define AVX_CTR_START(reg, ii) MM_OP (_mm256_add_epi64, ctr2, two) reg = _mm256_xor_si256(ctr2, key); +#define AVX_CTR_END( reg, ii) AVX_XOR (((__m256i *)(void *)data)[ii], reg) + +#define WOP_KEY(op, n) { \ + const __m128i key = w[n]; \ + WOP(op); } + +#define AVX_WOP_KEY(op, n) { \ + const __m256i key = w[n]; \ + WOP(op); } + + +#define WIDE_LOOP_START \ + dataEnd = data + numBlocks; \ + if (numBlocks >= NUM_WAYS) \ + { dataEnd -= NUM_WAYS; do { \ + + +#define WIDE_LOOP_END \ + data += NUM_WAYS; \ + } while (data <= dataEnd); \ + dataEnd += NUM_WAYS; } \ + + +#define SINGLE_LOOP \ + for (; data < dataEnd; data++) + + +#define NUM_AES_KEYS_MAX 15 + +#define WIDE_LOOP_START_AVX(OP) \ + dataEnd = data + numBlocks; \ + if (numBlocks >= NUM_WAYS * 2) \ + { __m256i keys[NUM_AES_KEYS_MAX]; \ + UInt32 ii; \ + OP \ + for (ii = 0; ii < numRounds; ii++) \ + keys[ii] = _mm256_broadcastsi128_si256(p[ii]); \ + dataEnd -= NUM_WAYS * 2; do { \ + + +#define WIDE_LOOP_END_AVX(OP) \ + data += NUM_WAYS * 2; \ + } while (data <= dataEnd); \ + dataEnd += NUM_WAYS * 2; \ + OP \ + _mm256_zeroupper(); \ + } \ + +/* MSVC for x86: If we don't call _mm256_zeroupper(), and -arch:IA32 is not specified, + MSVC still can insert vzeroupper instruction. */ + + +AES_FUNC_START2 (AesCbc_Decode_HW) +{ + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; + __m128i iv = *p; + const __m128i *wStart = p + *(const UInt32 *)(p + 1) * 2 + 2 - 1; + const __m128i *dataEnd; + p += 2; + + WIDE_LOOP_START + { + const __m128i *w = wStart; + + WOP (DECLARE_VAR) + WOP (LOAD_data) + WOP_KEY (AES_XOR, 1) + + do + { + WOP_KEY (AES_DEC, 0) + w--; + } + while (w != p); + WOP_KEY (AES_DEC_LAST, 0) + + MM_XOR (m0, iv) + WOP_M1 (XOR_data_M1) + iv = data[NUM_WAYS - 1]; + WOP (STORE_data) + } + WIDE_LOOP_END + + SINGLE_LOOP + { + const __m128i *w = wStart - 1; + __m128i m = _mm_xor_si128 (w[2], *data); + do + { + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdec_si128, w[0]) + w -= 2; + } + while (w != p); + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdeclast_si128, w[0]) + + MM_XOR (m, iv) + iv = *data; + *data = m; + } + + p[-2] = iv; +} + + +AES_FUNC_START2 (AesCtr_Code_HW) +{ + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; + __m128i ctr = *p; + UInt32 numRoundsMinus2 = *(const UInt32 *)(p + 1) * 2 - 1; + const __m128i *dataEnd; + __m128i one = _mm_cvtsi32_si128(1); + + p += 2; + + WIDE_LOOP_START + { + const __m128i *w = p; + UInt32 r = numRoundsMinus2; + WOP (DECLARE_VAR) + WOP (CTR_START) + WOP_KEY (AES_XOR, 0) + w += 1; + do + { + WOP_KEY (AES_ENC, 0) + w += 1; + } + while (--r); + WOP_KEY (AES_ENC_LAST, 0) + + WOP (CTR_END) + } + WIDE_LOOP_END + + SINGLE_LOOP + { + UInt32 numRounds2 = *(const UInt32 *)(p - 2 + 1) - 1; + const __m128i *w = p; + __m128i m; + MM_OP (_mm_add_epi64, ctr, one) + m = _mm_xor_si128 (ctr, p[0]); + w += 1; + do + { + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenc_si128, w[1]) + w += 2; + } + while (--numRounds2); + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenclast_si128, w[1]) + MM_XOR (*data, m) + } + + p[-2] = ctr; +} + + + +#ifdef USE_INTEL_VAES + +/* +GCC before 2013-Jun: + : + #ifdef __AVX__ + #include + #endif +GCC after 2013-Jun: + : + #include +CLANG 3.8+: +{ + : + #if !defined(_MSC_VER) || defined(__AVX__) + #include + #endif + + if (the compiler is clang for Windows and if global arch is not set for __AVX__) + [ if (defined(_MSC_VER) && !defined(__AVX__)) ] + { + doesn't include + and we have 2 ways to fix it: + 1) we can define required __AVX__ before + or + 2) we can include after + } +} + +If we include manually for GCC/CLANG, it's +required that must be included before . +*/ + +/* +#if defined(__clang__) && defined(_MSC_VER) +#define __AVX__ +#define __AVX2__ +#define __VAES__ +#endif +*/ + +#include +#if defined(__clang__) && defined(_MSC_VER) + #if !defined(__AVX__) + #include + #endif + #if !defined(__AVX2__) + #include + #endif + #if !defined(__VAES__) + #include + #endif +#endif // __clang__ && _MSC_VER + + +#define VAES_FUNC_START2(name) \ +AES_FUNC_START (name); \ +ATTRIB_VAES \ +AES_FUNC_START (name) + +VAES_FUNC_START2 (AesCbc_Decode_HW_256) +{ + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; + __m128i iv = *p; + const __m128i *dataEnd; + UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1; + p += 2; + + WIDE_LOOP_START_AVX(;) + { + const __m256i *w = keys + numRounds - 2; + + WOP (AVX_DECLARE_VAR) + WOP (AVX_LOAD_data) + AVX_WOP_KEY (AVX_AES_XOR, 1) + + do + { + AVX_WOP_KEY (AVX_AES_DEC, 0) + w--; + } + while (w != keys); + AVX_WOP_KEY (AVX_AES_DEC_LAST, 0) + + AVX_XOR (m0, _mm256_setr_m128i(iv, data[0])) + WOP_M1 (AVX_XOR_data_M1) + iv = data[NUM_WAYS * 2 - 1]; + WOP (AVX_STORE_data) + } + WIDE_LOOP_END_AVX(;) + + SINGLE_LOOP + { + const __m128i *w = p + *(const UInt32 *)(p + 1 - 2) * 2 + 1 - 3; + __m128i m = _mm_xor_si128 (w[2], *data); + do + { + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdec_si128, w[0]) + w -= 2; + } + while (w != p); + MM_OP_m (_mm_aesdec_si128, w[1]) + MM_OP_m (_mm_aesdeclast_si128, w[0]) + + MM_XOR (m, iv) + iv = *data; + *data = m; + } + + p[-2] = iv; +} + + +/* +SSE2: _mm_cvtsi32_si128 : movd +AVX: _mm256_setr_m128i : vinsertf128 +AVX2: _mm256_add_epi64 : vpaddq ymm, ymm, ymm + _mm256_extracti128_si256 : vextracti128 + _mm256_broadcastsi128_si256 : vbroadcasti128 +*/ + +#define AVX_CTR_LOOP_START \ + ctr2 = _mm256_setr_m128i(_mm_sub_epi64(ctr, one), ctr); \ + two = _mm256_setr_m128i(one, one); \ + two = _mm256_add_epi64(two, two); \ + +// two = _mm256_setr_epi64x(2, 0, 2, 0); + +#define AVX_CTR_LOOP_ENC \ + ctr = _mm256_extracti128_si256 (ctr2, 1); \ + +VAES_FUNC_START2 (AesCtr_Code_HW_256) +{ + __m128i *p = (__m128i *)(void *)ivAes; + __m128i *data = (__m128i *)(void *)data8; + __m128i ctr = *p; + UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1; + const __m128i *dataEnd; + __m128i one = _mm_cvtsi32_si128(1); + __m256i ctr2, two; + p += 2; + + WIDE_LOOP_START_AVX (AVX_CTR_LOOP_START) + { + const __m256i *w = keys; + UInt32 r = numRounds - 2; + WOP (AVX_DECLARE_VAR) + AVX_WOP_KEY (AVX_CTR_START, 0) + + w += 1; + do + { + AVX_WOP_KEY (AVX_AES_ENC, 0) + w += 1; + } + while (--r); + AVX_WOP_KEY (AVX_AES_ENC_LAST, 0) + + WOP (AVX_CTR_END) + } + WIDE_LOOP_END_AVX (AVX_CTR_LOOP_ENC) + + SINGLE_LOOP + { + UInt32 numRounds2 = *(const UInt32 *)(p - 2 + 1) - 1; + const __m128i *w = p; + __m128i m; + MM_OP (_mm_add_epi64, ctr, one) + m = _mm_xor_si128 (ctr, p[0]); + w += 1; + do + { + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenc_si128, w[1]) + w += 2; + } + while (--numRounds2); + MM_OP_m (_mm_aesenc_si128, w[0]) + MM_OP_m (_mm_aesenclast_si128, w[1]) + MM_XOR (*data, m) + } + + p[-2] = ctr; +} + +#endif // USE_INTEL_VAES + +#else // USE_INTEL_AES + +/* no USE_INTEL_AES */ + +#pragma message("AES HW_SW stub was used") + +#define AES_TYPE_keys UInt32 +#define AES_TYPE_data Byte + +#define AES_FUNC_START(name) \ + void Z7_FASTCALL name(UInt32 *p, Byte *data, size_t numBlocks) \ + +#define AES_COMPAT_STUB(name) \ + AES_FUNC_START(name); \ + AES_FUNC_START(name ## _HW) \ + { name(p, data, numBlocks); } + +AES_COMPAT_STUB (AesCbc_Encode) +AES_COMPAT_STUB (AesCbc_Decode) +AES_COMPAT_STUB (AesCtr_Code) + +#endif // USE_INTEL_AES + + +#ifndef USE_INTEL_VAES + +#pragma message("VAES HW_SW stub was used") + +#define VAES_COMPAT_STUB(name) \ + void Z7_FASTCALL name ## _256(UInt32 *p, Byte *data, size_t numBlocks); \ + void Z7_FASTCALL name ## _256(UInt32 *p, Byte *data, size_t numBlocks) \ + { name((AES_TYPE_keys *)(void *)p, (AES_TYPE_data *)(void *)data, numBlocks); } + +VAES_COMPAT_STUB (AesCbc_Decode_HW) +VAES_COMPAT_STUB (AesCtr_Code_HW) + +#endif // ! USE_INTEL_VAES + + +#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) + + #if defined(__clang__) + #if (__clang_major__ >= 8) // fix that check + #define USE_HW_AES + #endif + #elif defined(__GNUC__) + #if (__GNUC__ >= 6) // fix that check + #define USE_HW_AES + #endif + #elif defined(_MSC_VER) + #if _MSC_VER >= 1910 + #define USE_HW_AES + #endif + #endif + +#ifdef USE_HW_AES + +// #pragma message("=== AES HW === ") + +#if defined(__clang__) || defined(__GNUC__) + #ifdef MY_CPU_ARM64 + #define ATTRIB_AES __attribute__((__target__("+crypto"))) + #else + #define ATTRIB_AES __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) + #endif +#else + // _MSC_VER + // for arm32 + #define _ARM_USE_NEW_NEON_INTRINSICS +#endif + +#ifndef ATTRIB_AES + #define ATTRIB_AES +#endif + +#if defined(_MSC_VER) && defined(MY_CPU_ARM64) +#include +#else +#include +#endif + +typedef uint8x16_t v128; + +#define AES_FUNC_START(name) \ + void Z7_FASTCALL name(UInt32 *ivAes, Byte *data8, size_t numBlocks) + // void Z7_FASTCALL name(v128 *p, v128 *data, size_t numBlocks) + +#define AES_FUNC_START2(name) \ +AES_FUNC_START (name); \ +ATTRIB_AES \ +AES_FUNC_START (name) + +#define MM_OP(op, dest, src) dest = op(dest, src); +#define MM_OP_m(op, src) MM_OP(op, m, src) +#define MM_OP1_m(op) m = op(m); + +#define MM_XOR( dest, src) MM_OP(veorq_u8, dest, src) +#define MM_XOR_m( src) MM_XOR(m, src) + +#define AES_E_m(k) MM_OP_m (vaeseq_u8, k) +#define AES_E_MC_m(k) AES_E_m (k) MM_OP1_m(vaesmcq_u8) + + +AES_FUNC_START2 (AesCbc_Encode_HW) +{ + v128 *p = (v128*)(void*)ivAes; + v128 *data = (v128*)(void*)data8; + v128 m = *p; + const v128 k0 = p[2]; + const v128 k1 = p[3]; + const v128 k2 = p[4]; + const v128 k3 = p[5]; + const v128 k4 = p[6]; + const v128 k5 = p[7]; + const v128 k6 = p[8]; + const v128 k7 = p[9]; + const v128 k8 = p[10]; + const v128 k9 = p[11]; + const UInt32 numRounds2 = *(const UInt32 *)(p + 1); + const v128 *w = p + ((size_t)numRounds2 * 2); + const v128 k_z1 = w[1]; + const v128 k_z0 = w[2]; + for (; numBlocks != 0; numBlocks--, data++) + { + MM_XOR_m (*data); + AES_E_MC_m (k0) + AES_E_MC_m (k1) + AES_E_MC_m (k2) + AES_E_MC_m (k3) + AES_E_MC_m (k4) + AES_E_MC_m (k5) + AES_E_MC_m (k6) + AES_E_MC_m (k7) + AES_E_MC_m (k8) + if (numRounds2 >= 6) + { + AES_E_MC_m (k9) + AES_E_MC_m (p[12]) + if (numRounds2 != 6) + { + AES_E_MC_m (p[13]) + AES_E_MC_m (p[14]) + } + } + AES_E_m (k_z1) + MM_XOR_m (k_z0); + *data = m; + } + *p = m; +} + + +#define WOP_1(op) +#define WOP_2(op) WOP_1 (op) op (m1, 1) +#define WOP_3(op) WOP_2 (op) op (m2, 2) +#define WOP_4(op) WOP_3 (op) op (m3, 3) +#define WOP_5(op) WOP_4 (op) op (m4, 4) +#define WOP_6(op) WOP_5 (op) op (m5, 5) +#define WOP_7(op) WOP_6 (op) op (m6, 6) +#define WOP_8(op) WOP_7 (op) op (m7, 7) + + #define NUM_WAYS 8 + #define WOP_M1 WOP_8 + +#define WOP(op) op (m0, 0) WOP_M1(op) + +#define DECLARE_VAR(reg, ii) v128 reg; +#define LOAD_data( reg, ii) reg = data[ii]; +#define STORE_data( reg, ii) data[ii] = reg; +#if (NUM_WAYS > 1) +#define XOR_data_M1(reg, ii) MM_XOR (reg, data[ii- 1]) +#endif + +#define MM_OP_key(op, reg) MM_OP (op, reg, key) + +#define AES_D_m(k) MM_OP_m (vaesdq_u8, k) +#define AES_D_IMC_m(k) AES_D_m (k) MM_OP1_m (vaesimcq_u8) + +#define AES_XOR( reg, ii) MM_OP_key (veorq_u8, reg) +#define AES_D( reg, ii) MM_OP_key (vaesdq_u8, reg) +#define AES_E( reg, ii) MM_OP_key (vaeseq_u8, reg) + +#define AES_D_IMC( reg, ii) AES_D (reg, ii) reg = vaesimcq_u8(reg); +#define AES_E_MC( reg, ii) AES_E (reg, ii) reg = vaesmcq_u8(reg); + +#define CTR_START(reg, ii) MM_OP (vaddq_u64, ctr, one) reg = vreinterpretq_u8_u64(ctr); +#define CTR_END( reg, ii) MM_XOR (data[ii], reg) + +#define WOP_KEY(op, n) { \ + const v128 key = w[n]; \ + WOP(op) } + +#define WIDE_LOOP_START \ + dataEnd = data + numBlocks; \ + if (numBlocks >= NUM_WAYS) \ + { dataEnd -= NUM_WAYS; do { \ + +#define WIDE_LOOP_END \ + data += NUM_WAYS; \ + } while (data <= dataEnd); \ + dataEnd += NUM_WAYS; } \ + +#define SINGLE_LOOP \ + for (; data < dataEnd; data++) + + +AES_FUNC_START2 (AesCbc_Decode_HW) +{ + v128 *p = (v128*)(void*)ivAes; + v128 *data = (v128*)(void*)data8; + v128 iv = *p; + const v128 *wStart = p + ((size_t)*(const UInt32 *)(p + 1)) * 2; + const v128 *dataEnd; + p += 2; + + WIDE_LOOP_START + { + const v128 *w = wStart; + WOP (DECLARE_VAR) + WOP (LOAD_data) + WOP_KEY (AES_D_IMC, 2) + do + { + WOP_KEY (AES_D_IMC, 1) + WOP_KEY (AES_D_IMC, 0) + w -= 2; + } + while (w != p); + WOP_KEY (AES_D, 1) + WOP_KEY (AES_XOR, 0) + MM_XOR (m0, iv); + WOP_M1 (XOR_data_M1) + iv = data[NUM_WAYS - 1]; + WOP (STORE_data) + } + WIDE_LOOP_END + + SINGLE_LOOP + { + const v128 *w = wStart; + v128 m = *data; + AES_D_IMC_m (w[2]) + do + { + AES_D_IMC_m (w[1]); + AES_D_IMC_m (w[0]); + w -= 2; + } + while (w != p); + AES_D_m (w[1]); + MM_XOR_m (w[0]); + MM_XOR_m (iv); + iv = *data; + *data = m; + } + + p[-2] = iv; +} + + +AES_FUNC_START2 (AesCtr_Code_HW) +{ + v128 *p = (v128*)(void*)ivAes; + v128 *data = (v128*)(void*)data8; + uint64x2_t ctr = vreinterpretq_u64_u8(*p); + const v128 *wEnd = p + ((size_t)*(const UInt32 *)(p + 1)) * 2; + const v128 *dataEnd; + uint64x2_t one = vdupq_n_u64(0); + one = vsetq_lane_u64(1, one, 0); + p += 2; + + WIDE_LOOP_START + { + const v128 *w = p; + WOP (DECLARE_VAR) + WOP (CTR_START) + do + { + WOP_KEY (AES_E_MC, 0) + WOP_KEY (AES_E_MC, 1) + w += 2; + } + while (w != wEnd); + WOP_KEY (AES_E_MC, 0) + WOP_KEY (AES_E, 1) + WOP_KEY (AES_XOR, 2) + WOP (CTR_END) + } + WIDE_LOOP_END + + SINGLE_LOOP + { + const v128 *w = p; + v128 m; + CTR_START (m, 0); + do + { + AES_E_MC_m (w[0]); + AES_E_MC_m (w[1]); + w += 2; + } + while (w != wEnd); + AES_E_MC_m (w[0]) + AES_E_m (w[1]) + MM_XOR_m (w[2]) + CTR_END (m, 0) + } + + p[-2] = vreinterpretq_u8_u64(ctr); +} + +#endif // USE_HW_AES + +#endif // MY_CPU_ARM_OR_ARM64 + +#undef NUM_WAYS +#undef WOP_M1 +#undef WOP +#undef DECLARE_VAR +#undef LOAD_data +#undef STORE_data +#undef USE_INTEL_AES +#undef USE_HW_AES diff --git a/libraries/lzma/C/Alloc.c b/libraries/lzma/C/Alloc.c new file mode 100644 index 000000000..d841bf20a --- /dev/null +++ b/libraries/lzma/C/Alloc.c @@ -0,0 +1,535 @@ +/* Alloc.c -- Memory allocation functions +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#ifdef _WIN32 +#include "7zWindows.h" +#endif +#include + +#include "Alloc.h" + +#ifdef _WIN32 +#ifdef Z7_LARGE_PAGES +#if defined(__clang__) || defined(__GNUC__) +typedef void (*Z7_voidFunction)(void); +#define MY_CAST_FUNC (Z7_voidFunction) +#elif defined(_MSC_VER) && _MSC_VER > 1920 +#define MY_CAST_FUNC (void *) +// #pragma warning(disable : 4191) // 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)()' +#else +#define MY_CAST_FUNC +#endif +#endif // Z7_LARGE_PAGES +#endif // _WIN32 + +// #define SZ_ALLOC_DEBUG +/* #define SZ_ALLOC_DEBUG */ + +/* use SZ_ALLOC_DEBUG to debug alloc/free operations */ +#ifdef SZ_ALLOC_DEBUG + +#include +#include +static int g_allocCount = 0; +#ifdef _WIN32 +static int g_allocCountMid = 0; +static int g_allocCountBig = 0; +#endif + + +#define CONVERT_INT_TO_STR(charType, tempSize) \ + char temp[tempSize]; unsigned i = 0; \ + while (val >= 10) { temp[i++] = (char)('0' + (unsigned)(val % 10)); val /= 10; } \ + *s++ = (charType)('0' + (unsigned)val); \ + while (i != 0) { i--; *s++ = temp[i]; } \ + *s = 0; + +static void ConvertUInt64ToString(UInt64 val, char *s) +{ + CONVERT_INT_TO_STR(char, 24) +} + +#define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10))))) + +static void ConvertUInt64ToHex(UInt64 val, char *s) +{ + UInt64 v = val; + unsigned i; + for (i = 1;; i++) + { + v >>= 4; + if (v == 0) + break; + } + s[i] = 0; + do + { + unsigned t = (unsigned)(val & 0xF); + val >>= 4; + s[--i] = GET_HEX_CHAR(t); + } + while (i); +} + +#define DEBUG_OUT_STREAM stderr + +static void Print(const char *s) +{ + fputs(s, DEBUG_OUT_STREAM); +} + +static void PrintAligned(const char *s, size_t align) +{ + size_t len = strlen(s); + for(;;) + { + fputc(' ', DEBUG_OUT_STREAM); + if (len >= align) + break; + ++len; + } + Print(s); +} + +static void PrintLn(void) +{ + Print("\n"); +} + +static void PrintHex(UInt64 v, size_t align) +{ + char s[32]; + ConvertUInt64ToHex(v, s); + PrintAligned(s, align); +} + +static void PrintDec(int v, size_t align) +{ + char s[32]; + ConvertUInt64ToString((unsigned)v, s); + PrintAligned(s, align); +} + +static void PrintAddr(void *p) +{ + PrintHex((UInt64)(size_t)(ptrdiff_t)p, 12); +} + + +#define PRINT_REALLOC(name, cnt, size, ptr) { \ + Print(name " "); \ + if (!ptr) PrintDec(cnt++, 10); \ + PrintHex(size, 10); \ + PrintAddr(ptr); \ + PrintLn(); } + +#define PRINT_ALLOC(name, cnt, size, ptr) { \ + Print(name " "); \ + PrintDec(cnt++, 10); \ + PrintHex(size, 10); \ + PrintAddr(ptr); \ + PrintLn(); } + +#define PRINT_FREE(name, cnt, ptr) if (ptr) { \ + Print(name " "); \ + PrintDec(--cnt, 10); \ + PrintAddr(ptr); \ + PrintLn(); } + +#else + +#ifdef _WIN32 +#define PRINT_ALLOC(name, cnt, size, ptr) +#endif +#define PRINT_FREE(name, cnt, ptr) +#define Print(s) +#define PrintLn() +#define PrintHex(v, align) +#define PrintAddr(p) + +#endif + + +/* +by specification: + malloc(non_NULL, 0) : returns NULL or a unique pointer value that can later be successfully passed to free() + realloc(NULL, size) : the call is equivalent to malloc(size) + realloc(non_NULL, 0) : the call is equivalent to free(ptr) + +in main compilers: + malloc(0) : returns non_NULL + realloc(NULL, 0) : returns non_NULL + realloc(non_NULL, 0) : returns NULL +*/ + + +void *MyAlloc(size_t size) +{ + if (size == 0) + return NULL; + // PRINT_ALLOC("Alloc ", g_allocCount, size, NULL) + #ifdef SZ_ALLOC_DEBUG + { + void *p = malloc(size); + if (p) + { + PRINT_ALLOC("Alloc ", g_allocCount, size, p) + } + return p; + } + #else + return malloc(size); + #endif +} + +void MyFree(void *address) +{ + PRINT_FREE("Free ", g_allocCount, address) + + free(address); +} + +void *MyRealloc(void *address, size_t size) +{ + if (size == 0) + { + MyFree(address); + return NULL; + } + // PRINT_REALLOC("Realloc ", g_allocCount, size, address) + #ifdef SZ_ALLOC_DEBUG + { + void *p = realloc(address, size); + if (p) + { + PRINT_REALLOC("Realloc ", g_allocCount, size, address) + } + return p; + } + #else + return realloc(address, size); + #endif +} + + +#ifdef _WIN32 + +void *MidAlloc(size_t size) +{ + if (size == 0) + return NULL; + #ifdef SZ_ALLOC_DEBUG + { + void *p = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); + if (p) + { + PRINT_ALLOC("Alloc-Mid", g_allocCountMid, size, p) + } + return p; + } + #else + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); + #endif +} + +void MidFree(void *address) +{ + PRINT_FREE("Free-Mid", g_allocCountMid, address) + + if (!address) + return; + VirtualFree(address, 0, MEM_RELEASE); +} + +#ifdef Z7_LARGE_PAGES + +#ifdef MEM_LARGE_PAGES + #define MY__MEM_LARGE_PAGES MEM_LARGE_PAGES +#else + #define MY__MEM_LARGE_PAGES 0x20000000 +#endif + +extern +SIZE_T g_LargePageSize; +SIZE_T g_LargePageSize = 0; +typedef SIZE_T (WINAPI *Func_GetLargePageMinimum)(VOID); + +void SetLargePageSize(void) +{ + #ifdef Z7_LARGE_PAGES + SIZE_T size; + const + Func_GetLargePageMinimum fn = + (Func_GetLargePageMinimum) MY_CAST_FUNC GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), + "GetLargePageMinimum"); + if (!fn) + return; + size = fn(); + if (size == 0 || (size & (size - 1)) != 0) + return; + g_LargePageSize = size; + #endif +} + +#endif // Z7_LARGE_PAGES + +void *BigAlloc(size_t size) +{ + if (size == 0) + return NULL; + + PRINT_ALLOC("Alloc-Big", g_allocCountBig, size, NULL) + + #ifdef Z7_LARGE_PAGES + { + SIZE_T ps = g_LargePageSize; + if (ps != 0 && ps <= (1 << 30) && size > (ps / 2)) + { + size_t size2; + ps--; + size2 = (size + ps) & ~ps; + if (size2 >= size) + { + void *p = VirtualAlloc(NULL, size2, MEM_COMMIT | MY__MEM_LARGE_PAGES, PAGE_READWRITE); + if (p) + { + PRINT_ALLOC("Alloc-BM ", g_allocCountMid, size2, p) + return p; + } + } + } + } + #endif + + return MidAlloc(size); +} + +void BigFree(void *address) +{ + PRINT_FREE("Free-Big", g_allocCountBig, address) + MidFree(address); +} + +#endif // _WIN32 + + +static void *SzAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return MyAlloc(size); } +static void SzFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) MyFree(address); } +const ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +#ifdef _WIN32 +static void *SzMidAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return MidAlloc(size); } +static void SzMidFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) MidFree(address); } +static void *SzBigAlloc(ISzAllocPtr p, size_t size) { UNUSED_VAR(p) return BigAlloc(size); } +static void SzBigFree(ISzAllocPtr p, void *address) { UNUSED_VAR(p) BigFree(address); } +const ISzAlloc g_MidAlloc = { SzMidAlloc, SzMidFree }; +const ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree }; +#endif + +/* + uintptr_t : C99 (optional) + : unsupported in VS6 +*/ + +#ifdef _WIN32 + typedef UINT_PTR UIntPtr; +#else + /* + typedef uintptr_t UIntPtr; + */ + typedef ptrdiff_t UIntPtr; +#endif + + +#define ADJUST_ALLOC_SIZE 0 +/* +#define ADJUST_ALLOC_SIZE (sizeof(void *) - 1) +*/ +/* + Use (ADJUST_ALLOC_SIZE = (sizeof(void *) - 1)), if + MyAlloc() can return address that is NOT multiple of sizeof(void *). +*/ + + +/* +#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((char *)(p) - ((size_t)(UIntPtr)(p) & ((align) - 1)))) +*/ +#define MY_ALIGN_PTR_DOWN(p, align) ((void *)((((UIntPtr)(p)) & ~((UIntPtr)(align) - 1)))) + + +#if !defined(_WIN32) && defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L) + #define USE_posix_memalign +#endif + +#ifndef USE_posix_memalign +#define MY_ALIGN_PTR_UP_PLUS(p, align) MY_ALIGN_PTR_DOWN(((char *)(p) + (align) + ADJUST_ALLOC_SIZE), align) +#endif + +/* + This posix_memalign() is for test purposes only. + We also need special Free() function instead of free(), + if this posix_memalign() is used. +*/ + +/* +static int posix_memalign(void **ptr, size_t align, size_t size) +{ + size_t newSize = size + align; + void *p; + void *pAligned; + *ptr = NULL; + if (newSize < size) + return 12; // ENOMEM + p = MyAlloc(newSize); + if (!p) + return 12; // ENOMEM + pAligned = MY_ALIGN_PTR_UP_PLUS(p, align); + ((void **)pAligned)[-1] = p; + *ptr = pAligned; + return 0; +} +*/ + +/* + ALLOC_ALIGN_SIZE >= sizeof(void *) + ALLOC_ALIGN_SIZE >= cache_line_size +*/ + +#define ALLOC_ALIGN_SIZE ((size_t)1 << 7) + +static void *SzAlignedAlloc(ISzAllocPtr pp, size_t size) +{ + #ifndef USE_posix_memalign + + void *p; + void *pAligned; + size_t newSize; + UNUSED_VAR(pp) + + /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned + block to prevent cache line sharing with another allocated blocks */ + + newSize = size + ALLOC_ALIGN_SIZE * 1 + ADJUST_ALLOC_SIZE; + if (newSize < size) + return NULL; + + p = MyAlloc(newSize); + + if (!p) + return NULL; + pAligned = MY_ALIGN_PTR_UP_PLUS(p, ALLOC_ALIGN_SIZE); + + Print(" size="); PrintHex(size, 8); + Print(" a_size="); PrintHex(newSize, 8); + Print(" ptr="); PrintAddr(p); + Print(" a_ptr="); PrintAddr(pAligned); + PrintLn(); + + ((void **)pAligned)[-1] = p; + + return pAligned; + + #else + + void *p; + UNUSED_VAR(pp) + if (posix_memalign(&p, ALLOC_ALIGN_SIZE, size)) + return NULL; + + Print(" posix_memalign="); PrintAddr(p); + PrintLn(); + + return p; + + #endif +} + + +static void SzAlignedFree(ISzAllocPtr pp, void *address) +{ + UNUSED_VAR(pp) + #ifndef USE_posix_memalign + if (address) + MyFree(((void **)address)[-1]); + #else + free(address); + #endif +} + + +const ISzAlloc g_AlignedAlloc = { SzAlignedAlloc, SzAlignedFree }; + + + +#define MY_ALIGN_PTR_DOWN_1(p) MY_ALIGN_PTR_DOWN(p, sizeof(void *)) + +/* we align ptr to support cases where CAlignOffsetAlloc::offset is not multiply of sizeof(void *) */ +#define REAL_BLOCK_PTR_VAR(p) ((void **)MY_ALIGN_PTR_DOWN_1(p))[-1] +/* +#define REAL_BLOCK_PTR_VAR(p) ((void **)(p))[-1] +*/ + +static void *AlignOffsetAlloc_Alloc(ISzAllocPtr pp, size_t size) +{ + const CAlignOffsetAlloc *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CAlignOffsetAlloc, vt); + void *adr; + void *pAligned; + size_t newSize; + size_t extra; + size_t alignSize = (size_t)1 << p->numAlignBits; + + if (alignSize < sizeof(void *)) + alignSize = sizeof(void *); + + if (p->offset >= alignSize) + return NULL; + + /* also we can allocate additional dummy ALLOC_ALIGN_SIZE bytes after aligned + block to prevent cache line sharing with another allocated blocks */ + extra = p->offset & (sizeof(void *) - 1); + newSize = size + alignSize + extra + ADJUST_ALLOC_SIZE; + if (newSize < size) + return NULL; + + adr = ISzAlloc_Alloc(p->baseAlloc, newSize); + + if (!adr) + return NULL; + + pAligned = (char *)MY_ALIGN_PTR_DOWN((char *)adr + + alignSize - p->offset + extra + ADJUST_ALLOC_SIZE, alignSize) + p->offset; + + PrintLn(); + Print("- Aligned: "); + Print(" size="); PrintHex(size, 8); + Print(" a_size="); PrintHex(newSize, 8); + Print(" ptr="); PrintAddr(adr); + Print(" a_ptr="); PrintAddr(pAligned); + PrintLn(); + + REAL_BLOCK_PTR_VAR(pAligned) = adr; + + return pAligned; +} + + +static void AlignOffsetAlloc_Free(ISzAllocPtr pp, void *address) +{ + if (address) + { + const CAlignOffsetAlloc *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CAlignOffsetAlloc, vt); + PrintLn(); + Print("- Aligned Free: "); + PrintLn(); + ISzAlloc_Free(p->baseAlloc, REAL_BLOCK_PTR_VAR(address)); + } +} + + +void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p) +{ + p->vt.Alloc = AlignOffsetAlloc_Alloc; + p->vt.Free = AlignOffsetAlloc_Free; +} diff --git a/libraries/lzma/C/Alloc.h b/libraries/lzma/C/Alloc.h new file mode 100644 index 000000000..fac5b62fb --- /dev/null +++ b/libraries/lzma/C/Alloc.h @@ -0,0 +1,71 @@ +/* Alloc.h -- Memory allocation functions +2023-03-04 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_ALLOC_H +#define ZIP7_INC_ALLOC_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +/* + MyFree(NULL) : is allowed, as free(NULL) + MyAlloc(0) : returns NULL : but malloc(0) is allowed to return NULL or non_NULL + MyRealloc(NULL, 0) : returns NULL : but realloc(NULL, 0) is allowed to return NULL or non_NULL +MyRealloc() is similar to realloc() for the following cases: + MyRealloc(non_NULL, 0) : returns NULL and always calls MyFree(ptr) + MyRealloc(NULL, non_ZERO) : returns NULL, if allocation failed + MyRealloc(non_NULL, non_ZERO) : returns NULL, if reallocation failed +*/ + +void *MyAlloc(size_t size); +void MyFree(void *address); +void *MyRealloc(void *address, size_t size); + +#ifdef _WIN32 + +#ifdef Z7_LARGE_PAGES +void SetLargePageSize(void); +#endif + +void *MidAlloc(size_t size); +void MidFree(void *address); +void *BigAlloc(size_t size); +void BigFree(void *address); + +#else + +#define MidAlloc(size) MyAlloc(size) +#define MidFree(address) MyFree(address) +#define BigAlloc(size) MyAlloc(size) +#define BigFree(address) MyFree(address) + +#endif + +extern const ISzAlloc g_Alloc; + +#ifdef _WIN32 +extern const ISzAlloc g_BigAlloc; +extern const ISzAlloc g_MidAlloc; +#else +#define g_BigAlloc g_AlignedAlloc +#define g_MidAlloc g_AlignedAlloc +#endif + +extern const ISzAlloc g_AlignedAlloc; + + +typedef struct +{ + ISzAlloc vt; + ISzAllocPtr baseAlloc; + unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */ + size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */ +} CAlignOffsetAlloc; + +void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p); + + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/Bcj2.c b/libraries/lzma/C/Bcj2.c index c7b956708..7cb57ad62 100644 --- a/libraries/lzma/C/Bcj2.c +++ b/libraries/lzma/C/Bcj2.c @@ -1,29 +1,24 @@ /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code) -2021-02-09 : Igor Pavlov : Public domain */ +2023-03-01 : Igor Pavlov : Public domain */ #include "Precomp.h" #include "Bcj2.h" #include "CpuArch.h" -#define CProb UInt16 - #define kTopValue ((UInt32)1 << 24) -#define kNumModelBits 11 -#define kBitModelTotal (1 << kNumModelBits) +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) #define kNumMoveBits 5 -#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound) -#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits)); +// UInt32 bcj2_stats[256 + 2][2]; void Bcj2Dec_Init(CBcj2Dec *p) { unsigned i; - - p->state = BCJ2_DEC_STATE_OK; + p->state = BCJ2_STREAM_RC; // BCJ2_DEC_STATE_OK; p->ip = 0; - p->temp[3] = 0; + p->temp = 0; p->range = 0; p->code = 0; for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) @@ -32,217 +27,248 @@ void Bcj2Dec_Init(CBcj2Dec *p) SRes Bcj2Dec_Decode(CBcj2Dec *p) { + UInt32 v = p->temp; + // const Byte *src; if (p->range <= 5) { - p->state = BCJ2_DEC_STATE_OK; + UInt32 code = p->code; + p->state = BCJ2_DEC_STATE_ERROR; /* for case if we return SZ_ERROR_DATA; */ for (; p->range != 5; p->range++) { - if (p->range == 1 && p->code != 0) + if (p->range == 1 && code != 0) return SZ_ERROR_DATA; - if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) { p->state = BCJ2_STREAM_RC; return SZ_OK; } - - p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; + code = (code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; + p->code = code; } - - if (p->code == 0xFFFFFFFF) + if (code == 0xffffffff) return SZ_ERROR_DATA; - - p->range = 0xFFFFFFFF; + p->range = 0xffffffff; } - else if (p->state >= BCJ2_DEC_STATE_ORIG_0) + // else { - while (p->state <= BCJ2_DEC_STATE_ORIG_3) + unsigned state = p->state; + // we check BCJ2_IS_32BIT_STREAM() here instead of check in the main loop + if (BCJ2_IS_32BIT_STREAM(state)) + { + const Byte *cur = p->bufs[state]; + if (cur == p->lims[state]) + return SZ_OK; + p->bufs[state] = cur + 4; + { + const UInt32 ip = p->ip + 4; + v = GetBe32a(cur) - ip; + p->ip = ip; + } + state = BCJ2_DEC_STATE_ORIG_0; + } + if ((unsigned)(state - BCJ2_DEC_STATE_ORIG_0) < 4) { Byte *dest = p->dest; - if (dest == p->destLim) - return SZ_OK; - *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0]; - p->state++; - p->dest = dest + 1; - } - } - - /* - if (BCJ2_IS_32BIT_STREAM(p->state)) - { - const Byte *cur = p->bufs[p->state]; - if (cur == p->lims[p->state]) - return SZ_OK; - p->bufs[p->state] = cur + 4; - - { - UInt32 val; - Byte *dest; - SizeT rem; - - p->ip += 4; - val = GetBe32(cur) - p->ip; - dest = p->dest; - rem = p->destLim - dest; - if (rem < 4) + for (;;) { - SizeT i; - SetUi32(p->temp, val); - for (i = 0; i < rem; i++) - dest[i] = p->temp[i]; - p->dest = dest + rem; - p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; - return SZ_OK; + if (dest == p->destLim) + { + p->state = state; + p->temp = v; + return SZ_OK; + } + *dest++ = (Byte)v; + p->dest = dest; + if (++state == BCJ2_DEC_STATE_ORIG_3 + 1) + break; + v >>= 8; } - SetUi32(dest, val); - p->temp[3] = (Byte)(val >> 24); - p->dest = dest + 4; - p->state = BCJ2_DEC_STATE_OK; } } - */ + // src = p->bufs[BCJ2_STREAM_MAIN]; for (;;) { + /* if (BCJ2_IS_32BIT_STREAM(p->state)) p->state = BCJ2_DEC_STATE_OK; else + */ { if (p->range < kTopValue) { if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC]) { p->state = BCJ2_STREAM_RC; + p->temp = v; return SZ_OK; } p->range <<= 8; p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; } - { const Byte *src = p->bufs[BCJ2_STREAM_MAIN]; const Byte *srcLim; - Byte *dest; - SizeT num = (SizeT)(p->lims[BCJ2_STREAM_MAIN] - src); - - if (num == 0) + Byte *dest = p->dest; { - p->state = BCJ2_STREAM_MAIN; - return SZ_OK; + const SizeT rem = (SizeT)(p->lims[BCJ2_STREAM_MAIN] - src); + SizeT num = (SizeT)(p->destLim - dest); + if (num >= rem) + num = rem; + #define NUM_ITERS 4 + #if (NUM_ITERS & (NUM_ITERS - 1)) == 0 + num &= ~((SizeT)NUM_ITERS - 1); // if (NUM_ITERS == (1 << x)) + #else + num -= num % NUM_ITERS; // if (NUM_ITERS != (1 << x)) + #endif + srcLim = src + num; } - - dest = p->dest; - if (num > (SizeT)(p->destLim - dest)) + + #define NUM_SHIFT_BITS 24 + #define ONE_ITER(indx) { \ + const unsigned b = src[indx]; \ + *dest++ = (Byte)b; \ + v = (v << NUM_SHIFT_BITS) | b; \ + if (((b + (0x100 - 0xe8)) & 0xfe) == 0) break; \ + if (((v - (((UInt32)0x0f << (NUM_SHIFT_BITS)) + 0x80)) & \ + ((((UInt32)1 << (4 + NUM_SHIFT_BITS)) - 0x1) << 4)) == 0) break; \ + /* ++dest */; /* v = b; */ } + + if (src != srcLim) + for (;;) { - num = (SizeT)(p->destLim - dest); - if (num == 0) + /* The dependency chain of 2-cycle for (v) calculation is not big problem here. + But we can remove dependency chain with v = b in the end of loop. */ + ONE_ITER(0) + #if (NUM_ITERS > 1) + ONE_ITER(1) + #if (NUM_ITERS > 2) + ONE_ITER(2) + #if (NUM_ITERS > 3) + ONE_ITER(3) + #if (NUM_ITERS > 4) + ONE_ITER(4) + #if (NUM_ITERS > 5) + ONE_ITER(5) + #if (NUM_ITERS > 6) + ONE_ITER(6) + #if (NUM_ITERS > 7) + ONE_ITER(7) + #endif + #endif + #endif + #endif + #endif + #endif + #endif + + src += NUM_ITERS; + if (src == srcLim) + break; + } + + if (src == srcLim) + #if (NUM_ITERS > 1) + for (;;) + #endif + { + #if (NUM_ITERS > 1) + if (src == p->lims[BCJ2_STREAM_MAIN] || dest == p->destLim) + #endif { - p->state = BCJ2_DEC_STATE_ORIG; + const SizeT num = (SizeT)(src - p->bufs[BCJ2_STREAM_MAIN]); + p->bufs[BCJ2_STREAM_MAIN] = src; + p->dest = dest; + p->ip += (UInt32)num; + /* state BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ + p->state = + src == p->lims[BCJ2_STREAM_MAIN] ? + (unsigned)BCJ2_STREAM_MAIN : + (unsigned)BCJ2_DEC_STATE_ORIG; + p->temp = v; return SZ_OK; } + #if (NUM_ITERS > 1) + ONE_ITER(0) + src++; + #endif } - - srcLim = src + num; - if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80) - *dest = src[0]; - else for (;;) { - Byte b = *src; - *dest = b; - if (b != 0x0F) - { - if ((b & 0xFE) == 0xE8) - break; - dest++; - if (++src != srcLim) - continue; - break; - } - dest++; - if (++src == srcLim) - break; - if ((*src & 0xF0) != 0x80) - continue; - *dest = *src; - break; - } - - num = (SizeT)(src - p->bufs[BCJ2_STREAM_MAIN]); - - if (src == srcLim) - { - p->temp[3] = src[-1]; - p->bufs[BCJ2_STREAM_MAIN] = src; + const SizeT num = (SizeT)(dest - p->dest); + p->dest = dest; // p->dest += num; + p->bufs[BCJ2_STREAM_MAIN] += num; // = src; p->ip += (UInt32)num; - p->dest += num; - p->state = - p->bufs[BCJ2_STREAM_MAIN] == - p->lims[BCJ2_STREAM_MAIN] ? - (unsigned)BCJ2_STREAM_MAIN : - (unsigned)BCJ2_DEC_STATE_ORIG; - return SZ_OK; } - { UInt32 bound, ttt; - CProb *prob; - Byte b = src[0]; - Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]); - - p->temp[3] = b; - p->bufs[BCJ2_STREAM_MAIN] = src + 1; - num++; - p->ip += (UInt32)num; - p->dest += num; - - prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0)); - - _IF_BIT_0 + CBcj2Prob *prob; // unsigned index; + /* + prob = p->probs + (unsigned)((Byte)v == 0xe8 ? + 2 + (Byte)(v >> 8) : + ((v >> 5) & 1)); // ((Byte)v < 0xe8 ? 0 : 1)); + */ { - _UPDATE_0 + const unsigned c = ((v + 0x17) >> 6) & 1; + prob = p->probs + (unsigned) + (((0 - c) & (Byte)(v >> NUM_SHIFT_BITS)) + c + ((v >> 5) & 1)); + // (Byte) + // 8x->0 : e9->1 : xxe8->xx+2 + // 8x->0x100 : e9->0x101 : xxe8->xx + // (((0x100 - (e & ~v)) & (0x100 | (v >> 8))) + (e & v)); + // (((0x101 + (~e | v)) & (0x100 | (v >> 8))) + (e & v)); + } + ttt = *prob; + bound = (p->range >> kNumBitModelTotalBits) * ttt; + if (p->code < bound) + { + // bcj2_stats[prob - p->probs][0]++; + p->range = bound; + *prob = (CBcj2Prob)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); continue; } - _UPDATE_1 - + { + // bcj2_stats[prob - p->probs][1]++; + p->range -= bound; + p->code -= bound; + *prob = (CBcj2Prob)(ttt - (ttt >> kNumMoveBits)); + } } } } - { - UInt32 val; - unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; + /* (v == 0xe8 ? 0 : 1) uses setcc instruction with additional zero register usage in x64 MSVC. */ + // const unsigned cj = ((Byte)v == 0xe8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP; + const unsigned cj = (((v + 0x57) >> 6) & 1) + BCJ2_STREAM_CALL; const Byte *cur = p->bufs[cj]; Byte *dest; SizeT rem; - if (cur == p->lims[cj]) { p->state = cj; break; } - - val = GetBe32(cur); + v = GetBe32a(cur); p->bufs[cj] = cur + 4; - - p->ip += 4; - val -= p->ip; + { + const UInt32 ip = p->ip + 4; + v -= ip; + p->ip = ip; + } dest = p->dest; rem = (SizeT)(p->destLim - dest); - if (rem < 4) { - p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8; - p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8; - p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8; - p->temp[3] = (Byte)val; + if ((unsigned)rem > 0) { dest[0] = (Byte)v; v >>= 8; + if ((unsigned)rem > 1) { dest[1] = (Byte)v; v >>= 8; + if ((unsigned)rem > 2) { dest[2] = (Byte)v; v >>= 8; }}} + p->temp = v; p->dest = dest + rem; p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem; break; } - - SetUi32(dest, val); - p->temp[3] = (Byte)(val >> 24); + SetUi32(dest, v) + v >>= 24; p->dest = dest + 4; } } @@ -252,6 +278,13 @@ SRes Bcj2Dec_Decode(CBcj2Dec *p) p->range <<= 8; p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++; } - return SZ_OK; } + +#undef NUM_ITERS +#undef ONE_ITER +#undef NUM_SHIFT_BITS +#undef kTopValue +#undef kNumBitModelTotalBits +#undef kBitModelTotal +#undef kNumMoveBits diff --git a/libraries/lzma/C/Bcj2.h b/libraries/lzma/C/Bcj2.h index 8824080ac..4575545b6 100644 --- a/libraries/lzma/C/Bcj2.h +++ b/libraries/lzma/C/Bcj2.h @@ -1,8 +1,8 @@ -/* Bcj2.h -- BCJ2 Converter for x86 code -2014-11-10 : Igor Pavlov : Public domain */ +/* Bcj2.h -- BCJ2 converter for x86 code (Branch CALL/JUMP variant2) +2023-03-02 : Igor Pavlov : Public domain */ -#ifndef __BCJ2_H -#define __BCJ2_H +#ifndef ZIP7_INC_BCJ2_H +#define ZIP7_INC_BCJ2_H #include "7zTypes.h" @@ -26,37 +26,68 @@ enum BCJ2_DEC_STATE_ORIG_3, BCJ2_DEC_STATE_ORIG, - BCJ2_DEC_STATE_OK + BCJ2_DEC_STATE_ERROR /* after detected data error */ }; enum { BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, - BCJ2_ENC_STATE_OK + BCJ2_ENC_STATE_FINISHED /* it's state after fully encoded stream */ }; -#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) +/* #define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) */ +#define BCJ2_IS_32BIT_STREAM(s) ((unsigned)((unsigned)(s) - (unsigned)BCJ2_STREAM_CALL) < 2) /* CBcj2Dec / CBcj2Enc bufs sizes: BUF_SIZE(n) = lims[n] - bufs[n] -bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4: +bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be multiply of 4: (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0 (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0 */ +// typedef UInt32 CBcj2Prob; +typedef UInt16 CBcj2Prob; + +/* +BCJ2 encoder / decoder internal requirements: + - If last bytes of stream contain marker (e8/e8/0f8x), then + there is also encoded symbol (0 : no conversion) in RC stream. + - One case of overlapped instructions is supported, + if last byte of converted instruction is (0f) and next byte is (8x): + marker [xx xx xx 0f] 8x + then the pair (0f 8x) is treated as marker. +*/ + +/* ---------- BCJ2 Decoder ---------- */ + /* CBcj2Dec: -dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: +(dest) is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: bufs[BCJ2_STREAM_MAIN] >= dest && - bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv + + bufs[BCJ2_STREAM_MAIN] - dest >= BUF_SIZE(BCJ2_STREAM_CALL) + BUF_SIZE(BCJ2_STREAM_JUMP) - tempReserv = 0 : for first call of Bcj2Dec_Decode - tempReserv = 4 : for any other calls of Bcj2Dec_Decode - overlap with offset = 1 is not allowed + reserve = bufs[BCJ2_STREAM_MAIN] - dest - + ( BUF_SIZE(BCJ2_STREAM_CALL) + + BUF_SIZE(BCJ2_STREAM_JUMP) ) + and additional conditions: + if (it's first call of Bcj2Dec_Decode() after Bcj2Dec_Init()) + { + (reserve != 1) : if (ver < v23.00) + } + else // if there are more than one calls of Bcj2Dec_Decode() after Bcj2Dec_Init()) + { + (reserve >= 6) : if (ver < v23.00) + (reserve >= 4) : if (ver >= v23.00) + We need that (reserve) because after first call of Bcj2Dec_Decode(), + CBcj2Dec::temp can contain up to 4 bytes for writing to (dest). + } + (reserve == 0) is allowed, if we decode full stream via single call of Bcj2Dec_Decode(). + (reserve == 0) also is allowed in case of multi-call, if we use fixed buffers, + and (reserve) is calculated from full (final) sizes of all streams before first call. */ typedef struct @@ -68,22 +99,66 @@ typedef struct unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ - UInt32 ip; - Byte temp[4]; + UInt32 ip; /* property of starting base for decoding */ + UInt32 temp; /* Byte temp[4]; */ UInt32 range; UInt32 code; - UInt16 probs[2 + 256]; + CBcj2Prob probs[2 + 256]; } CBcj2Dec; + +/* Note: + Bcj2Dec_Init() sets (CBcj2Dec::ip = 0) + if (ip != 0) property is required, the caller must set CBcj2Dec::ip after Bcj2Dec_Init() +*/ void Bcj2Dec_Init(CBcj2Dec *p); -/* Returns: SZ_OK or SZ_ERROR_DATA */ + +/* Bcj2Dec_Decode(): + returns: + SZ_OK + SZ_ERROR_DATA : if data in 5 starting bytes of BCJ2_STREAM_RC stream are not correct +*/ SRes Bcj2Dec_Decode(CBcj2Dec *p); -#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0) +/* To check that decoding was finished you can compare + sizes of processed streams with sizes known from another sources. + You must do at least one mandatory check from the two following options: + - the check for size of processed output (ORIG) stream. + - the check for size of processed input (MAIN) stream. + additional optional checks: + - the checks for processed sizes of all input streams (MAIN, CALL, JUMP, RC) + - the checks Bcj2Dec_IsMaybeFinished*() + also before actual decoding you can check that the + following condition is met for stream sizes: + ( size(ORIG) == size(MAIN) + size(CALL) + size(JUMP) ) +*/ + +/* (state == BCJ2_STREAM_MAIN) means that decoder is ready for + additional input data in BCJ2_STREAM_MAIN stream. + Note that (state == BCJ2_STREAM_MAIN) is allowed for non-finished decoding. +*/ +#define Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) ((_p_)->state == BCJ2_STREAM_MAIN) + +/* if the stream decoding was finished correctly, then range decoder + part of CBcj2Dec also was finished, and then (CBcj2Dec::code == 0). + Note that (CBcj2Dec::code == 0) is allowed for non-finished decoding. +*/ +#define Bcj2Dec_IsMaybeFinished_code(_p_) ((_p_)->code == 0) + +/* use Bcj2Dec_IsMaybeFinished() only as additional check + after at least one mandatory check from the two following options: + - the check for size of processed output (ORIG) stream. + - the check for size of processed input (MAIN) stream. +*/ +#define Bcj2Dec_IsMaybeFinished(_p_) ( \ + Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) && \ + Bcj2Dec_IsMaybeFinished_code(_p_)) +/* ---------- BCJ2 Encoder ---------- */ + typedef enum { BCJ2_ENC_FINISH_MODE_CONTINUE, @@ -91,6 +166,91 @@ typedef enum BCJ2_ENC_FINISH_MODE_END_STREAM } EBcj2Enc_FinishMode; +/* + BCJ2_ENC_FINISH_MODE_CONTINUE: + process non finished encoding. + It notifies the encoder that additional further calls + can provide more input data (src) than provided by current call. + In that case the CBcj2Enc encoder still can move (src) pointer + up to (srcLim), but CBcj2Enc encoder can store some of the last + processed bytes (up to 4 bytes) from src to internal CBcj2Enc::temp[] buffer. + at return: + (CBcj2Enc::src will point to position that includes + processed data and data copied to (temp[]) buffer) + That data from (temp[]) buffer will be used in further calls. + + BCJ2_ENC_FINISH_MODE_END_BLOCK: + finish encoding of current block (ended at srcLim) without RC flushing. + at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_ORIG) && + CBcj2Enc::src == CBcj2Enc::srcLim) + : it shows that block encoding was finished. And the encoder is + ready for new (src) data or for stream finish operation. + finished block means + { + CBcj2Enc has completed block encoding up to (srcLim). + (1 + 4 bytes) or (2 + 4 bytes) CALL/JUMP cortages will + not cross block boundary at (srcLim). + temporary CBcj2Enc buffer for (ORIG) src data is empty. + 3 output uncompressed streams (MAIN, CALL, JUMP) were flushed. + RC stream was not flushed. And RC stream will cross block boundary. + } + Note: some possible implementation of BCJ2 encoder could + write branch marker (e8/e8/0f8x) in one call of Bcj2Enc_Encode(), + and it could calculate symbol for RC in another call of Bcj2Enc_Encode(). + BCJ2 encoder uses ip/fileIp/fileSize/relatLimit values to calculate RC symbol. + And these CBcj2Enc variables can have different values in different Bcj2Enc_Encode() calls. + So caller must finish each block with BCJ2_ENC_FINISH_MODE_END_BLOCK + to ensure that RC symbol is calculated and written in proper block. + + BCJ2_ENC_FINISH_MODE_END_STREAM + finish encoding of stream (ended at srcLim) fully including RC flushing. + at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_FINISHED) + : it shows that stream encoding was finished fully, + and all output streams were flushed fully. + also Bcj2Enc_IsFinished() can be called. +*/ + + +/* + 32-bit relative offset in JUMP/CALL commands is + - (mod 4 GiB) for 32-bit x86 code + - signed Int32 for 64-bit x86-64 code + BCJ2 encoder also does internal relative to absolute address conversions. + And there are 2 possible ways to do it: + before v23: we used 32-bit variables and (mod 4 GiB) conversion + since v23: we use 64-bit variables and (signed Int32 offset) conversion. + The absolute address condition for conversion in v23: + ((UInt64)((Int64)ip64 - (Int64)fileIp64 + 5 + (Int32)offset) < (UInt64)fileSize64) + note that if (fileSize64 > 2 GiB). there is difference between + old (mod 4 GiB) way (v22) and new (signed Int32 offset) way (v23). + And new (v23) way is more suitable to encode 64-bit x86-64 code for (fileSize64 > 2 GiB) cases. +*/ + +/* +// for old (v22) way for conversion: +typedef UInt32 CBcj2Enc_ip_unsigned; +typedef Int32 CBcj2Enc_ip_signed; +#define BCJ2_ENC_FileSize_MAX ((UInt32)1 << 31) +*/ +typedef UInt64 CBcj2Enc_ip_unsigned; +typedef Int64 CBcj2Enc_ip_signed; + +/* maximum size of file that can be used for conversion condition */ +#define BCJ2_ENC_FileSize_MAX ((CBcj2Enc_ip_unsigned)0 - 2) + +/* default value of fileSize64_minus1 variable that means + that absolute address limitation will not be used */ +#define BCJ2_ENC_FileSizeField_UNLIMITED ((CBcj2Enc_ip_unsigned)0 - 1) + +/* calculate value that later can be set to CBcj2Enc::fileSize64_minus1 */ +#define BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize) \ + ((CBcj2Enc_ip_unsigned)(fileSize) - 1) + +/* set CBcj2Enc::fileSize64_minus1 variable from size of file */ +#define Bcj2Enc_SET_FileSize(p, fileSize) \ + (p)->fileSize64_minus1 = BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize); + + typedef struct { Byte *bufs[BCJ2_NUM_STREAMS]; @@ -101,45 +261,71 @@ typedef struct unsigned state; EBcj2Enc_FinishMode finishMode; - Byte prevByte; + Byte context; + Byte flushRem; + Byte isFlushState; Byte cache; UInt32 range; UInt64 low; UInt64 cacheSize; + + // UInt32 context; // for marker version, it can include marker flag. - UInt32 ip; - - /* 32-bit ralative offset in JUMP/CALL commands is - - (mod 4 GB) in 32-bit mode - - signed Int32 in 64-bit mode - We use (mod 4 GB) check for fileSize. - Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */ - UInt32 fileIp; - UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */ - UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */ + /* (ip64) and (fileIp64) correspond to virtual source stream position + that doesn't include data in temp[] */ + CBcj2Enc_ip_unsigned ip64; /* current (ip) position */ + CBcj2Enc_ip_unsigned fileIp64; /* start (ip) position of current file */ + CBcj2Enc_ip_unsigned fileSize64_minus1; /* size of current file (for conversion limitation) */ + UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)) : 0 means disable_conversion */ + // UInt32 relatExcludeBits; UInt32 tempTarget; - unsigned tempPos; - Byte temp[4 * 2]; - - unsigned flushPos; - - UInt16 probs[2 + 256]; + unsigned tempPos; /* the number of bytes that were copied to temp[] buffer + (tempPos <= 4) outside of Bcj2Enc_Encode() */ + // Byte temp[4]; // for marker version + Byte temp[8]; + CBcj2Prob probs[2 + 256]; } CBcj2Enc; void Bcj2Enc_Init(CBcj2Enc *p); + + +/* +Bcj2Enc_Encode(): at exit: + p->State < BCJ2_NUM_STREAMS : we need more buffer space for output stream + (bufs[p->State] == lims[p->State]) + p->State == BCJ2_ENC_STATE_ORIG : we need more data in input src stream + (src == srcLim) + p->State == BCJ2_ENC_STATE_FINISHED : after fully encoded stream +*/ void Bcj2Enc_Encode(CBcj2Enc *p); -#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos) -#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5) +/* Bcj2Enc encoder can look ahead for up 4 bytes of source stream. + CBcj2Enc::tempPos : is the number of bytes that were copied from input stream to temp[] buffer. + (CBcj2Enc::src) after Bcj2Enc_Encode() is starting position after + fully processed data and after data copied to temp buffer. + So if the caller needs to get real number of fully processed input + bytes (without look ahead data in temp buffer), + the caller must subtruct (CBcj2Enc::tempPos) value from processed size + value that is calculated based on current (CBcj2Enc::src): + cur_processed_pos = Calc_Big_Processed_Pos(enc.src)) - + Bcj2Enc_Get_AvailInputSize_in_Temp(&enc); +*/ +/* get the size of input data that was stored in temp[] buffer: */ +#define Bcj2Enc_Get_AvailInputSize_in_Temp(p) ((p)->tempPos) +#define Bcj2Enc_IsFinished(p) ((p)->flushRem == 0) -#define BCJ2_RELAT_LIMIT_NUM_BITS 26 -#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS) - -/* limit for CBcj2Enc::fileSize variable */ -#define BCJ2_FileSize_MAX ((UInt32)1 << 31) +/* Note : the decoder supports overlapping of marker (0f 80). + But we can eliminate such overlapping cases by setting + the limit for relative offset conversion as + CBcj2Enc::relatLimit <= (0x0f << 24) == (240 MiB) +*/ +/* default value for CBcj2Enc::relatLimit */ +#define BCJ2_ENC_RELAT_LIMIT_DEFAULT ((UInt32)0x0f << 24) +#define BCJ2_ENC_RELAT_LIMIT_MAX ((UInt32)1 << 31) +// #define BCJ2_RELAT_EXCLUDE_NUM_BITS 5 EXTERN_C_END diff --git a/libraries/lzma/C/Bcj2Enc.c b/libraries/lzma/C/Bcj2Enc.c new file mode 100644 index 000000000..79460bb15 --- /dev/null +++ b/libraries/lzma/C/Bcj2Enc.c @@ -0,0 +1,506 @@ +/* Bcj2Enc.c -- BCJ2 Encoder converter for x86 code (Branch CALL/JUMP variant2) +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +/* #define SHOW_STAT */ +#ifdef SHOW_STAT +#include +#define PRF2(s) printf("%s ip=%8x tempPos=%d src= %8x\n", s, (unsigned)p->ip64, p->tempPos, (unsigned)(p->srcLim - p->src)); +#else +#define PRF2(s) +#endif + +#include "Bcj2.h" +#include "CpuArch.h" + +#define kTopValue ((UInt32)1 << 24) +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +void Bcj2Enc_Init(CBcj2Enc *p) +{ + unsigned i; + p->state = BCJ2_ENC_STATE_ORIG; + p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + p->context = 0; + p->flushRem = 5; + p->isFlushState = 0; + p->cache = 0; + p->range = 0xffffffff; + p->low = 0; + p->cacheSize = 1; + p->ip64 = 0; + p->fileIp64 = 0; + p->fileSize64_minus1 = BCJ2_ENC_FileSizeField_UNLIMITED; + p->relatLimit = BCJ2_ENC_RELAT_LIMIT_DEFAULT; + // p->relatExcludeBits = 0; + p->tempPos = 0; + for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++) + p->probs[i] = kBitModelTotal >> 1; +} + +// Z7_NO_INLINE +Z7_FORCE_INLINE +static BoolInt Bcj2_RangeEnc_ShiftLow(CBcj2Enc *p) +{ + const UInt32 low = (UInt32)p->low; + const unsigned high = (unsigned) + #if defined(Z7_MSC_VER_ORIGINAL) \ + && defined(MY_CPU_X86) \ + && defined(MY_CPU_LE) \ + && !defined(MY_CPU_64BIT) + // we try to rid of __aullshr() call in MSVS-x86 + (((const UInt32 *)&p->low)[1]); // [1] : for little-endian only + #else + (p->low >> 32); + #endif + if (low < (UInt32)0xff000000 || high != 0) + { + Byte *buf = p->bufs[BCJ2_STREAM_RC]; + do + { + if (buf == p->lims[BCJ2_STREAM_RC]) + { + p->state = BCJ2_STREAM_RC; + p->bufs[BCJ2_STREAM_RC] = buf; + return True; + } + *buf++ = (Byte)(p->cache + high); + p->cache = 0xff; + } + while (--p->cacheSize); + p->bufs[BCJ2_STREAM_RC] = buf; + p->cache = (Byte)(low >> 24); + } + p->cacheSize++; + p->low = low << 8; + return False; +} + + +/* +We can use 2 alternative versions of code: +1) non-marker version: + Byte CBcj2Enc::context + Byte temp[8]; + Last byte of marker (e8/e9/[0f]8x) can be written to temp[] buffer. + Encoder writes last byte of marker (e8/e9/[0f]8x) to dest, only in conjunction + with writing branch symbol to range coder in same Bcj2Enc_Encode_2() call. + +2) marker version: + UInt32 CBcj2Enc::context + Byte CBcj2Enc::temp[4]; + MARKER_FLAG in CBcj2Enc::context shows that CBcj2Enc::context contains finded marker. + it's allowed that + one call of Bcj2Enc_Encode_2() writes last byte of marker (e8/e9/[0f]8x) to dest, + and another call of Bcj2Enc_Encode_2() does offset conversion. + So different values of (fileIp) and (fileSize) are possible + in these different Bcj2Enc_Encode_2() calls. + +Also marker version requires additional if((v & MARKER_FLAG) == 0) check in main loop. +So we use non-marker version. +*/ + +/* + Corner cases with overlap in multi-block. + before v23: there was one corner case, where converted instruction + could start in one sub-stream and finish in next sub-stream. + If multi-block (solid) encoding is used, + and BCJ2_ENC_FINISH_MODE_END_BLOCK is used for each sub-stream. + and (0f) is last byte of previous sub-stream + and (8x) is first byte of current sub-stream + then (0f 8x) pair is treated as marker by BCJ2 encoder and decoder. + BCJ2 encoder can converts 32-bit offset for that (0f 8x) cortage, + if that offset meets limit requirements. + If encoder allows 32-bit offset conversion for such overlap case, + then the data in 3 uncompressed BCJ2 streams for some sub-stream + can depend from data of previous sub-stream. + That corner case is not big problem, and it's rare case. + Since v23.00 we do additional check to prevent conversions in such overlap cases. +*/ + +/* + Bcj2Enc_Encode_2() output variables at exit: + { + if (Bcj2Enc_Encode_2() exits with (p->state == BCJ2_ENC_STATE_ORIG)) + { + it means that encoder needs more input data. + if (p->srcLim == p->src) at exit, then + { + (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM) + all input data were read and processed, and we are ready for + new input data. + } + else + { + (p->srcLim != p->src) + (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE) + The encoder have found e8/e9/0f_8x marker, + and p->src points to last byte of that marker, + Bcj2Enc_Encode_2() needs more input data to get totally + 5 bytes (last byte of marker and 32-bit branch offset) + as continuous array starting from p->src. + (p->srcLim - p->src < 5) requirement is met after exit. + So non-processed resedue from p->src to p->srcLim is always less than 5 bytes. + } + } + } +*/ + +Z7_NO_INLINE +static void Bcj2Enc_Encode_2(CBcj2Enc *p) +{ + if (!p->isFlushState) + { + const Byte *src; + UInt32 v; + { + const unsigned state = p->state; + if (BCJ2_IS_32BIT_STREAM(state)) + { + Byte *cur = p->bufs[state]; + if (cur == p->lims[state]) + return; + SetBe32a(cur, p->tempTarget) + p->bufs[state] = cur + 4; + } + } + p->state = BCJ2_ENC_STATE_ORIG; // for main reason of exit + src = p->src; + v = p->context; + + // #define WRITE_CONTEXT p->context = v; // for marker version + #define WRITE_CONTEXT p->context = (Byte)v; + #define WRITE_CONTEXT_AND_SRC p->src = src; WRITE_CONTEXT + + for (;;) + { + // const Byte *src; + // UInt32 v; + CBcj2Enc_ip_unsigned ip; + if (p->range < kTopValue) + { + // to reduce register pressure and code size: we save and restore local variables. + WRITE_CONTEXT_AND_SRC + if (Bcj2_RangeEnc_ShiftLow(p)) + return; + p->range <<= 8; + src = p->src; + v = p->context; + } + // src = p->src; + // #define MARKER_FLAG ((UInt32)1 << 17) + // if ((v & MARKER_FLAG) == 0) // for marker version + { + const Byte *srcLim; + Byte *dest = p->bufs[BCJ2_STREAM_MAIN]; + { + const SizeT remSrc = (SizeT)(p->srcLim - src); + SizeT rem = (SizeT)(p->lims[BCJ2_STREAM_MAIN] - dest); + if (rem >= remSrc) + rem = remSrc; + srcLim = src + rem; + } + /* p->context contains context of previous byte: + bits [0 : 7] : src[-1], if (src) was changed in this call + bits [8 : 31] : are undefined for non-marker version + */ + // v = p->context; + #define NUM_SHIFT_BITS 24 + #define CONV_FLAG ((UInt32)1 << 16) + #define ONE_ITER { \ + b = src[0]; \ + *dest++ = (Byte)b; \ + v = (v << NUM_SHIFT_BITS) | b; \ + if (((b + (0x100 - 0xe8)) & 0xfe) == 0) break; \ + if (((v - (((UInt32)0x0f << (NUM_SHIFT_BITS)) + 0x80)) & \ + ((((UInt32)1 << (4 + NUM_SHIFT_BITS)) - 0x1) << 4)) == 0) break; \ + src++; if (src == srcLim) { break; } } + + if (src != srcLim) + for (;;) + { + /* clang can generate ineffective code with setne instead of two jcc instructions. + we can use 2 iterations and external (unsigned b) to avoid that ineffective code genaration. */ + unsigned b; + ONE_ITER + ONE_ITER + } + + ip = p->ip64 + (CBcj2Enc_ip_unsigned)(SizeT)(dest - p->bufs[BCJ2_STREAM_MAIN]); + p->bufs[BCJ2_STREAM_MAIN] = dest; + p->ip64 = ip; + + if (src == srcLim) + { + WRITE_CONTEXT_AND_SRC + if (src != p->srcLim) + { + p->state = BCJ2_STREAM_MAIN; + return; + } + /* (p->src == p->srcLim) + (p->state == BCJ2_ENC_STATE_ORIG) */ + if (p->finishMode != BCJ2_ENC_FINISH_MODE_END_STREAM) + return; + /* (p->finishMode == BCJ2_ENC_FINISH_MODE_END_STREAM */ + // (p->flushRem == 5); + p->isFlushState = 1; + break; + } + src++; + // p->src = src; + } + // ip = p->ip; // for marker version + /* marker was found */ + /* (v) contains marker that was found: + bits [NUM_SHIFT_BITS : NUM_SHIFT_BITS + 7] + : value of src[-2] : xx/xx/0f + bits [0 : 7] : value of src[-1] : e8/e9/8x + */ + { + { + #if NUM_SHIFT_BITS != 24 + v &= ~(UInt32)CONV_FLAG; + #endif + // UInt32 relat = 0; + if ((SizeT)(p->srcLim - src) >= 4) + { + /* + if (relat != 0 || (Byte)v != 0xe8) + BoolInt isBigOffset = True; + */ + const UInt32 relat = GetUi32(src); + /* + #define EXCLUDE_FLAG ((UInt32)1 << 4) + #define NEED_CONVERT(rel) ((((rel) + EXCLUDE_FLAG) & (0 - EXCLUDE_FLAG * 2)) != 0) + if (p->relatExcludeBits != 0) + { + const UInt32 flag = (UInt32)1 << (p->relatExcludeBits - 1); + isBigOffset = (((relat + flag) & (0 - flag * 2)) != 0); + } + // isBigOffset = False; // for debug + */ + ip -= p->fileIp64; + // Use the following if check, if (ip) is 64-bit: + if (ip > (((v + 0x20) >> 5) & 1)) // 23.00 : we eliminate milti-block overlap for (Of 80) and (e8/e9) + if ((CBcj2Enc_ip_unsigned)((CBcj2Enc_ip_signed)ip + 4 + (Int32)relat) <= p->fileSize64_minus1) + if (((UInt32)(relat + p->relatLimit) >> 1) < p->relatLimit) + v |= CONV_FLAG; + } + else if (p->finishMode == BCJ2_ENC_FINISH_MODE_CONTINUE) + { + // (p->srcLim - src < 4) + // /* + // for non-marker version + p->ip64--; // p->ip = ip - 1; + p->bufs[BCJ2_STREAM_MAIN]--; + src--; + v >>= NUM_SHIFT_BITS; + // (0 < p->srcLim - p->src <= 4) + // */ + // v |= MARKER_FLAG; // for marker version + /* (p->state == BCJ2_ENC_STATE_ORIG) */ + WRITE_CONTEXT_AND_SRC + return; + } + { + const unsigned c = ((v + 0x17) >> 6) & 1; + CBcj2Prob *prob = p->probs + (unsigned) + (((0 - c) & (Byte)(v >> NUM_SHIFT_BITS)) + c + ((v >> 5) & 1)); + /* + ((Byte)v == 0xe8 ? 2 + ((Byte)(v >> 8)) : + ((Byte)v < 0xe8 ? 0 : 1)); // ((v >> 5) & 1)); + */ + const unsigned ttt = *prob; + const UInt32 bound = (p->range >> kNumBitModelTotalBits) * ttt; + if ((v & CONV_FLAG) == 0) + { + // static int yyy = 0; yyy++; printf("\n!needConvert = %d\n", yyy); + // v = (Byte)v; // for marker version + p->range = bound; + *prob = (CBcj2Prob)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); + // WRITE_CONTEXT_AND_SRC + continue; + } + p->low += bound; + p->range -= bound; + *prob = (CBcj2Prob)(ttt - (ttt >> kNumMoveBits)); + } + // p->context = src[3]; + { + // const unsigned cj = ((Byte)v == 0xe8 ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP); + const unsigned cj = (((v + 0x57) >> 6) & 1) + BCJ2_STREAM_CALL; + ip = p->ip64; + v = GetUi32(src); // relat + ip += 4; + p->ip64 = ip; + src += 4; + // p->src = src; + { + const UInt32 absol = (UInt32)ip + v; + Byte *cur = p->bufs[cj]; + v >>= 24; + // WRITE_CONTEXT + if (cur == p->lims[cj]) + { + p->state = cj; + p->tempTarget = absol; + WRITE_CONTEXT_AND_SRC + return; + } + SetBe32a(cur, absol) + p->bufs[cj] = cur + 4; + } + } + } + } + } // end of loop + } + + for (; p->flushRem != 0; p->flushRem--) + if (Bcj2_RangeEnc_ShiftLow(p)) + return; + p->state = BCJ2_ENC_STATE_FINISHED; +} + + +/* +BCJ2 encoder needs look ahead for up to 4 bytes in (src) buffer. +So base function Bcj2Enc_Encode_2() + in BCJ2_ENC_FINISH_MODE_CONTINUE mode can return with + (p->state == BCJ2_ENC_STATE_ORIG && p->src < p->srcLim) +Bcj2Enc_Encode() solves that look ahead problem by using p->temp[] buffer. + so if (p->state == BCJ2_ENC_STATE_ORIG) after Bcj2Enc_Encode(), + then (p->src == p->srcLim). + And the caller's code is simpler with Bcj2Enc_Encode(). +*/ + +Z7_NO_INLINE +void Bcj2Enc_Encode(CBcj2Enc *p) +{ + PRF2("\n----") + if (p->tempPos != 0) + { + /* extra: number of bytes that were copied from (src) to (temp) buffer in this call */ + unsigned extra = 0; + /* We will touch only minimal required number of bytes in input (src) stream. + So we will add input bytes from (src) stream to temp[] with step of 1 byte. + We don't add new bytes to temp[] before Bcj2Enc_Encode_2() call + in first loop iteration because + - previous call of Bcj2Enc_Encode() could use another (finishMode), + - previous call could finish with (p->state != BCJ2_ENC_STATE_ORIG). + the case with full temp[] buffer (p->tempPos == 4) is possible here. + */ + for (;;) + { + // (0 < p->tempPos <= 5) // in non-marker version + /* p->src : the current src data position including extra bytes + that were copied to temp[] buffer in this call */ + const Byte *src = p->src; + const Byte *srcLim = p->srcLim; + const EBcj2Enc_FinishMode finishMode = p->finishMode; + if (src != srcLim) + { + /* if there are some src data after the data copied to temp[], + then we use MODE_CONTINUE for temp data */ + p->finishMode = BCJ2_ENC_FINISH_MODE_CONTINUE; + } + p->src = p->temp; + p->srcLim = p->temp + p->tempPos; + PRF2(" ") + Bcj2Enc_Encode_2(p); + { + const unsigned num = (unsigned)(p->src - p->temp); + const unsigned tempPos = p->tempPos - num; + unsigned i; + p->tempPos = tempPos; + for (i = 0; i < tempPos; i++) + p->temp[i] = p->temp[(SizeT)i + num]; + // tempPos : number of bytes in temp buffer + p->src = src; + p->srcLim = srcLim; + p->finishMode = finishMode; + if (p->state != BCJ2_ENC_STATE_ORIG) + { + // (p->tempPos <= 4) // in non-marker version + /* if (the reason of exit from Bcj2Enc_Encode_2() + is not BCJ2_ENC_STATE_ORIG), + then we exit from Bcj2Enc_Encode() with same reason */ + // optional code begin : we rollback (src) and tempPos, if it's possible: + if (extra >= tempPos) + extra = tempPos; + p->src = src - extra; + p->tempPos = tempPos - extra; + // optional code end : rollback of (src) and tempPos + return; + } + /* (p->tempPos <= 4) + (p->state == BCJ2_ENC_STATE_ORIG) + so encoder needs more data than in temp[] */ + if (src == srcLim) + return; // src buffer has no more input data. + /* (src != srcLim) + so we can provide more input data from src for Bcj2Enc_Encode_2() */ + if (extra >= tempPos) + { + /* (extra >= tempPos) means that temp buffer contains + only data from src buffer of this call. + So now we can encode without temp buffer */ + p->src = src - tempPos; // rollback (src) + p->tempPos = 0; + break; + } + // we append one additional extra byte from (src) to temp[] buffer: + p->temp[tempPos] = *src; + p->tempPos = tempPos + 1; + // (0 < p->tempPos <= 5) // in non-marker version + p->src = src + 1; + extra++; + } + } + } + + PRF2("++++") + // (p->tempPos == 0) + Bcj2Enc_Encode_2(p); + PRF2("====") + + if (p->state == BCJ2_ENC_STATE_ORIG) + { + const Byte *src = p->src; + const Byte *srcLim = p->srcLim; + const unsigned rem = (unsigned)(srcLim - src); + /* (rem <= 4) here. + if (p->src != p->srcLim), then + - we copy non-processed bytes from (p->src) to temp[] buffer, + - we set p->src equal to p->srcLim. + */ + if (rem) + { + unsigned i = 0; + p->src = srcLim; + p->tempPos = rem; + // (0 < p->tempPos <= 4) + do + p->temp[i] = src[i]; + while (++i != rem); + } + // (p->tempPos <= 4) + // (p->src == p->srcLim) + } +} + +#undef PRF2 +#undef CONV_FLAG +#undef MARKER_FLAG +#undef WRITE_CONTEXT +#undef WRITE_CONTEXT_AND_SRC +#undef ONE_ITER +#undef NUM_SHIFT_BITS +#undef kTopValue +#undef kNumBitModelTotalBits +#undef kBitModelTotal +#undef kNumMoveBits diff --git a/libraries/lzma/C/Bra.c b/libraries/lzma/C/Bra.c index 3b854d9ca..22e0e478e 100644 --- a/libraries/lzma/C/Bra.c +++ b/libraries/lzma/C/Bra.c @@ -1,230 +1,420 @@ -/* Bra.c -- Converters for RISC code -2021-02-09 : Igor Pavlov : Public domain */ +/* Bra.c -- Branch converters for RISC code +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" -#include "CpuArch.h" #include "Bra.h" +#include "CpuArch.h" +#include "RotateDefs.h" -SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +#if defined(MY_CPU_SIZEOF_POINTER) \ + && ( MY_CPU_SIZEOF_POINTER == 4 \ + || MY_CPU_SIZEOF_POINTER == 8) + #define BR_CONV_USE_OPT_PC_PTR +#endif + +#ifdef BR_CONV_USE_OPT_PC_PTR +#define BR_PC_INIT pc -= (UInt32)(SizeT)p; +#define BR_PC_GET (pc + (UInt32)(SizeT)p) +#else +#define BR_PC_INIT pc += (UInt32)size; +#define BR_PC_GET (pc - (UInt32)(SizeT)(lim - p)) +// #define BR_PC_INIT +// #define BR_PC_GET (pc + (UInt32)(SizeT)(p - data)) +#endif + +#define BR_CONVERT_VAL(v, c) if (encoding) v += c; else v -= c; +// #define BR_CONVERT_VAL(v, c) if (!encoding) c = (UInt32)0 - c; v += c; + +#define Z7_BRANCH_CONV(name) z7_BranchConv_ ## name + +#define Z7_BRANCH_FUNC_MAIN(name) \ +static \ +Z7_FORCE_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *Z7_BRANCH_CONV(name)(Byte *p, SizeT size, UInt32 pc, int encoding) + +#define Z7_BRANCH_FUNC_IMP(name, m, encoding) \ +Z7_NO_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *m(name)(Byte *data, SizeT size, UInt32 pc) \ + { return Z7_BRANCH_CONV(name)(data, size, pc, encoding); } \ + +#ifdef Z7_EXTRACT_ONLY +#define Z7_BRANCH_FUNCS_IMP(name) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_DEC, 0) +#else +#define Z7_BRANCH_FUNCS_IMP(name) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_DEC, 0) \ + Z7_BRANCH_FUNC_IMP(name, Z7_BRANCH_CONV_ENC, 1) +#endif + +#if defined(__clang__) +#define BR_EXTERNAL_FOR +#define BR_NEXT_ITERATION continue; +#else +#define BR_EXTERNAL_FOR for (;;) +#define BR_NEXT_ITERATION break; +#endif + +#if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 1000) \ + // GCC is not good for __builtin_expect() here + /* || defined(_MSC_VER) && (_MSC_VER >= 1920) */ + // #define Z7_unlikely [[unlikely]] + // #define Z7_LIKELY(x) (__builtin_expect((x), 1)) + #define Z7_UNLIKELY(x) (__builtin_expect((x), 0)) + // #define Z7_likely [[likely]] +#else + // #define Z7_LIKELY(x) (x) + #define Z7_UNLIKELY(x) (x) + // #define Z7_likely +#endif + + +Z7_BRANCH_FUNC_MAIN(ARM64) { - Byte *p; + // Byte *p = data; const Byte *lim; - size &= ~(size_t)3; - ip += 4; - p = data; - lim = data + size; - - if (encoding) - - for (;;) + const UInt32 flag = (UInt32)1 << (24 - 4); + const UInt32 mask = ((UInt32)1 << 24) - (flag << 1); + size &= ~(SizeT)3; + // if (size == 0) return p; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction + + BR_EXTERNAL_FOR { + // Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE for (;;) { - if (p >= lim) - return (SizeT)(p - data); + UInt32 v; + if Z7_UNLIKELY(p == lim) + return p; + v = GetUi32a(p); p += 4; - if (p[-1] == 0xEB) - break; - } - { - UInt32 v = GetUi32(p - 4); - v <<= 2; - v += ip + (UInt32)(p - data); - v >>= 2; - v &= 0x00FFFFFF; - v |= 0xEB000000; - SetUi32(p - 4, v); - } - } - - for (;;) - { - for (;;) - { - if (p >= lim) - return (SizeT)(p - data); - p += 4; - if (p[-1] == 0xEB) - break; - } - { - UInt32 v = GetUi32(p - 4); - v <<= 2; - v -= ip + (UInt32)(p - data); - v >>= 2; - v &= 0x00FFFFFF; - v |= 0xEB000000; - SetUi32(p - 4, v); + if Z7_UNLIKELY(((v - 0x94000000) & 0xfc000000) == 0) + { + UInt32 c = BR_PC_GET >> 2; + BR_CONVERT_VAL(v, c) + v &= 0x03ffffff; + v |= 0x94000000; + SetUi32a(p - 4, v) + BR_NEXT_ITERATION + } + // v = rotlFixed(v, 8); v += (flag << 8) - 0x90; if Z7_UNLIKELY((v & ((mask << 8) + 0x9f)) == 0) + v -= 0x90000000; if Z7_UNLIKELY((v & 0x9f000000) == 0) + { + UInt32 z, c; + // v = rotrFixed(v, 8); + v += flag; if Z7_UNLIKELY(v & mask) continue; + z = (v & 0xffffffe0) | (v >> 26); + c = (BR_PC_GET >> (12 - 3)) & ~(UInt32)7; + BR_CONVERT_VAL(z, c) + v &= 0x1f; + v |= 0x90000000; + v |= z << 26; + v |= 0x00ffffe0 & ((z & (((flag << 1) - 1))) - flag); + SetUi32a(p - 4, v) + } } } } +Z7_BRANCH_FUNCS_IMP(ARM64) -SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +Z7_BRANCH_FUNC_MAIN(ARM) { - Byte *p; + // Byte *p = data; const Byte *lim; - size &= ~(size_t)1; - p = data; - lim = data + size - 4; - - if (encoding) + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + /* in ARM: branch offset is relative to the +2 instructions from current instruction. + (p) will point to next instruction */ + pc += 8 - 4; for (;;) { - UInt32 b1; for (;;) { - UInt32 b3; - if (p > lim) - return (SizeT)(p - data); - b1 = p[1]; - b3 = p[3]; - p += 2; - b1 ^= 8; - if ((b3 & b1) >= 0xF8) - break; + if Z7_UNLIKELY(p >= lim) { return p; } p += 4; if Z7_UNLIKELY(p[-1] == 0xeb) break; + if Z7_UNLIKELY(p >= lim) { return p; } p += 4; if Z7_UNLIKELY(p[-1] == 0xeb) break; } { - UInt32 v = - ((UInt32)b1 << 19) - + (((UInt32)p[1] & 0x7) << 8) - + (((UInt32)p[-2] << 11)) - + (p[0]); - - p += 2; - { - UInt32 cur = (ip + (UInt32)(p - data)) >> 1; - v += cur; - } - - p[-4] = (Byte)(v >> 11); - p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); - p[-2] = (Byte)v; - p[-1] = (Byte)(0xF8 | (v >> 8)); - } - } - - for (;;) - { - UInt32 b1; - for (;;) - { - UInt32 b3; - if (p > lim) - return (SizeT)(p - data); - b1 = p[1]; - b3 = p[3]; - p += 2; - b1 ^= 8; - if ((b3 & b1) >= 0xF8) - break; - } - { - UInt32 v = - ((UInt32)b1 << 19) - + (((UInt32)p[1] & 0x7) << 8) - + (((UInt32)p[-2] << 11)) - + (p[0]); - - p += 2; - { - UInt32 cur = (ip + (UInt32)(p - data)) >> 1; - v -= cur; - } - - /* - SetUi16(p - 4, (UInt16)(((v >> 11) & 0x7FF) | 0xF000)); - SetUi16(p - 2, (UInt16)(v | 0xF800)); - */ - - p[-4] = (Byte)(v >> 11); - p[-3] = (Byte)(0xF0 | ((v >> 19) & 0x7)); - p[-2] = (Byte)v; - p[-1] = (Byte)(0xF8 | (v >> 8)); + UInt32 v = GetUi32a(p - 4); + UInt32 c = BR_PC_GET >> 2; + BR_CONVERT_VAL(v, c) + v &= 0x00ffffff; + v |= 0xeb000000; + SetUi32a(p - 4, v) } } } +Z7_BRANCH_FUNCS_IMP(ARM) -SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +Z7_BRANCH_FUNC_MAIN(PPC) { - Byte *p; + // Byte *p = data; const Byte *lim; - size &= ~(size_t)3; - ip -= 4; - p = data; - lim = data + size; - + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction + for (;;) { + UInt32 v; for (;;) { - if (p >= lim) - return (SizeT)(p - data); + if Z7_UNLIKELY(p == lim) + return p; + // v = GetBe32a(p); + v = *(UInt32 *)(void *)p; p += 4; - /* if ((v & 0xFC000003) == 0x48000001) */ - if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) - break; + // if ((v & 0xfc000003) == 0x48000001) break; + // if ((p[-4] & 0xFC) == 0x48 && (p[-1] & 3) == 1) break; + if Z7_UNLIKELY( + ((v - Z7_CONV_BE_TO_NATIVE_CONST32(0x48000001)) + & Z7_CONV_BE_TO_NATIVE_CONST32(0xfc000003)) == 0) break; } { - UInt32 v = GetBe32(p - 4); - if (encoding) - v += ip + (UInt32)(p - data); - else - v -= ip + (UInt32)(p - data); - v &= 0x03FFFFFF; + v = Z7_CONV_NATIVE_TO_BE_32(v); + { + UInt32 c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + } + v &= 0x03ffffff; v |= 0x48000000; - SetBe32(p - 4, v); + SetBe32a(p - 4, v) } } } +Z7_BRANCH_FUNCS_IMP(PPC) -SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) +#ifdef Z7_CPU_FAST_ROTATE_SUPPORTED +#define BR_SPARC_USE_ROTATE +#endif + +Z7_BRANCH_FUNC_MAIN(SPARC) { - Byte *p; + // Byte *p = data; const Byte *lim; - size &= ~(size_t)3; - ip -= 4; - p = data; - lim = data + size; - + const UInt32 flag = (UInt32)1 << 22; + size &= ~(SizeT)3; + lim = p + size; + BR_PC_INIT + pc -= 4; // because (p) will point to next instruction for (;;) { + UInt32 v; for (;;) { - if (p >= lim) - return (SizeT)(p - data); - /* - v = GetBe32(p); - p += 4; - m = v + ((UInt32)5 << 29); - m ^= (UInt32)7 << 29; - m += (UInt32)1 << 22; - if ((m & ((UInt32)0x1FF << 23)) == 0) - break; + if Z7_UNLIKELY(p == lim) + return p; + /* // the code without GetBe32a(): + { const UInt32 v = GetUi16a(p) & 0xc0ff; p += 4; if (v == 0x40 || v == 0xc07f) break; } */ + v = GetBe32a(p); p += 4; - if ((p[-4] == 0x40 && (p[-3] & 0xC0) == 0) || - (p[-4] == 0x7F && (p[-3] >= 0xC0))) + #ifdef BR_SPARC_USE_ROTATE + v = rotlFixed(v, 2); + v += (flag << 2) - 1; + if Z7_UNLIKELY((v & (3 - (flag << 3))) == 0) + #else + v += (UInt32)5 << 29; + v ^= (UInt32)7 << 29; + v += flag; + if Z7_UNLIKELY((v & (0 - (flag << 1))) == 0) + #endif break; } { - UInt32 v = GetBe32(p - 4); + // UInt32 v = GetBe32a(p - 4); + #ifndef BR_SPARC_USE_ROTATE v <<= 2; - if (encoding) - v += ip + (UInt32)(p - data); - else - v -= ip + (UInt32)(p - data); - - v &= 0x01FFFFFF; - v -= (UInt32)1 << 24; - v ^= 0xFF000000; + #endif + { + UInt32 c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + } + v &= (flag << 3) - 1; + #ifdef BR_SPARC_USE_ROTATE + v -= (flag << 2) - 1; + v = rotrFixed(v, 2); + #else + v -= (flag << 2); v >>= 2; - v |= 0x40000000; - SetBe32(p - 4, v); + v |= (UInt32)1 << 30; + #endif + SetBe32a(p - 4, v) } } } +Z7_BRANCH_FUNCS_IMP(SPARC) + + +Z7_BRANCH_FUNC_MAIN(ARMT) +{ + // Byte *p = data; + Byte *lim; + size &= ~(SizeT)1; + // if (size == 0) return p; + if (size <= 2) return p; + size -= 2; + lim = p + size; + BR_PC_INIT + /* in ARM: branch offset is relative to the +2 instructions from current instruction. + (p) will point to the +2 instructions from current instruction */ + // pc += 4 - 4; + // if (encoding) pc -= 0xf800 << 1; else pc += 0xf800 << 1; + // #define ARMT_TAIL_PROC { goto armt_tail; } + #define ARMT_TAIL_PROC { return p; } + + do + { + /* in MSVC 32-bit x86 compilers: + UInt32 version : it loads value from memory with movzx + Byte version : it loads value to 8-bit register (AL/CL) + movzx version is slightly faster in some cpus + */ + unsigned b1; + // Byte / unsigned + b1 = p[1]; + // optimized version to reduce one (p >= lim) check: + // unsigned a1 = p[1]; b1 = p[3]; p += 2; if Z7_LIKELY((b1 & (a1 ^ 8)) < 0xf8) + for (;;) + { + unsigned b3; // Byte / UInt32 + /* (Byte)(b3) normalization can use low byte computations in MSVC. + It gives smaller code, and no loss of speed in some compilers/cpus. + But new MSVC 32-bit x86 compilers use more slow load + from memory to low byte register in that case. + So we try to use full 32-bit computations for faster code. + */ + // if (p >= lim) { ARMT_TAIL_PROC } b3 = b1 + 8; b1 = p[3]; p += 2; if ((b3 & b1) >= 0xf8) break; + if Z7_UNLIKELY(p >= lim) { ARMT_TAIL_PROC } b3 = p[3]; p += 2; if Z7_UNLIKELY((b3 & (b1 ^ 8)) >= 0xf8) break; + if Z7_UNLIKELY(p >= lim) { ARMT_TAIL_PROC } b1 = p[3]; p += 2; if Z7_UNLIKELY((b1 & (b3 ^ 8)) >= 0xf8) break; + } + { + /* we can adjust pc for (0xf800) to rid of (& 0x7FF) operation. + But gcc/clang for arm64 can use bfi instruction for full code here */ + UInt32 v = + ((UInt32)GetUi16a(p - 2) << 11) | + ((UInt32)GetUi16a(p) & 0x7FF); + /* + UInt32 v = + ((UInt32)p[1 - 2] << 19) + + (((UInt32)p[1] & 0x7) << 8) + + (((UInt32)p[-2] << 11)) + + (p[0]); + */ + p += 2; + { + UInt32 c = BR_PC_GET >> 1; + BR_CONVERT_VAL(v, c) + } + SetUi16a(p - 4, (UInt16)(((v >> 11) & 0x7ff) | 0xf000)) + SetUi16a(p - 2, (UInt16)(v | 0xf800)) + /* + p[-4] = (Byte)(v >> 11); + p[-3] = (Byte)(0xf0 | ((v >> 19) & 0x7)); + p[-2] = (Byte)v; + p[-1] = (Byte)(0xf8 | (v >> 8)); + */ + } + } + while (p < lim); + return p; + // armt_tail: + // if ((Byte)((lim[1] & 0xf8)) != 0xf0) { lim += 2; } return lim; + // return (Byte *)(lim + ((Byte)((lim[1] ^ 0xf0) & 0xf8) == 0 ? 0 : 2)); + // return (Byte *)(lim + (((lim[1] ^ ~0xfu) & ~7u) == 0 ? 0 : 2)); + // return (Byte *)(lim + 2 - (((((unsigned)lim[1] ^ 8) + 8) >> 7) & 2)); +} +Z7_BRANCH_FUNCS_IMP(ARMT) + + +// #define BR_IA64_NO_INLINE + +Z7_BRANCH_FUNC_MAIN(IA64) +{ + // Byte *p = data; + const Byte *lim; + size &= ~(SizeT)15; + lim = p + size; + pc -= 1 << 4; + pc >>= 4 - 1; + // pc -= 1 << 1; + + for (;;) + { + unsigned m; + for (;;) + { + if Z7_UNLIKELY(p == lim) + return p; + m = (unsigned)((UInt32)0x334b0000 >> (*p & 0x1e)); + p += 16; + pc += 1 << 1; + if (m &= 3) + break; + } + { + p += (ptrdiff_t)m * 5 - 20; // negative value is expected here. + do + { + const UInt32 t = + #if defined(MY_CPU_X86_OR_AMD64) + // we use 32-bit load here to reduce code size on x86: + GetUi32(p); + #else + GetUi16(p); + #endif + UInt32 z = GetUi32(p + 1) >> m; + p += 5; + if (((t >> m) & (0x70 << 1)) == 0 + && ((z - (0x5000000 << 1)) & (0xf000000 << 1)) == 0) + { + UInt32 v = (UInt32)((0x8fffff << 1) | 1) & z; + z ^= v; + #ifdef BR_IA64_NO_INLINE + v |= (v & ((UInt32)1 << (23 + 1))) >> 3; + { + UInt32 c = pc; + BR_CONVERT_VAL(v, c) + } + v &= (0x1fffff << 1) | 1; + #else + { + if (encoding) + { + // pc &= ~(0xc00000 << 1); // we just need to clear at least 2 bits + pc &= (0x1fffff << 1) | 1; + v += pc; + } + else + { + // pc |= 0xc00000 << 1; // we need to set at least 2 bits + pc |= ~(UInt32)((0x1fffff << 1) | 1); + v -= pc; + } + } + v &= ~(UInt32)(0x600000 << 1); + #endif + v += (0x700000 << 1); + v &= (0x8fffff << 1) | 1; + z |= v; + z <<= m; + SetUi32(p + 1 - 5, z) + } + m++; + } + while (m &= 3); // while (m < 4); + } + } +} +Z7_BRANCH_FUNCS_IMP(IA64) diff --git a/libraries/lzma/C/Bra.h b/libraries/lzma/C/Bra.h index 855e37a6b..a4ee568e2 100644 --- a/libraries/lzma/C/Bra.h +++ b/libraries/lzma/C/Bra.h @@ -1,64 +1,99 @@ /* Bra.h -- Branch converters for executables -2013-01-18 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __BRA_H -#define __BRA_H +#ifndef ZIP7_INC_BRA_H +#define ZIP7_INC_BRA_H #include "7zTypes.h" EXTERN_C_BEGIN -/* -These functions convert relative addresses to absolute addresses -in CALL instructions to increase the compression ratio. - - In: - data - data buffer - size - size of data - ip - current virtual Instruction Pinter (IP) value - state - state variable for x86 converter - encoding - 0 (for decoding), 1 (for encoding) - - Out: - state - state variable for x86 converter +#define Z7_BRANCH_CONV_DEC(name) z7_BranchConv_ ## name ## _Dec +#define Z7_BRANCH_CONV_ENC(name) z7_BranchConv_ ## name ## _Enc +#define Z7_BRANCH_CONV_ST_DEC(name) z7_BranchConvSt_ ## name ## _Dec +#define Z7_BRANCH_CONV_ST_ENC(name) z7_BranchConvSt_ ## name ## _Enc - Returns: - The number of processed bytes. If you call these functions with multiple calls, - you must start next call with first byte after block of processed bytes. +#define Z7_BRANCH_CONV_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc) +#define Z7_BRANCH_CONV_ST_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc, UInt32 *state) + +typedef Z7_BRANCH_CONV_DECL( (*z7_Func_BranchConv)); +typedef Z7_BRANCH_CONV_ST_DECL((*z7_Func_BranchConvSt)); + +#define Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL 0 +Z7_BRANCH_CONV_ST_DECL(Z7_BRANCH_CONV_ST_DEC(X86)); +Z7_BRANCH_CONV_ST_DECL(Z7_BRANCH_CONV_ST_ENC(X86)); + +#define Z7_BRANCH_FUNCS_DECL(name) \ +Z7_BRANCH_CONV_DECL(Z7_BRANCH_CONV_DEC(name)); \ +Z7_BRANCH_CONV_DECL(Z7_BRANCH_CONV_ENC(name)); + +Z7_BRANCH_FUNCS_DECL(ARM64) +Z7_BRANCH_FUNCS_DECL(ARM) +Z7_BRANCH_FUNCS_DECL(ARMT) +Z7_BRANCH_FUNCS_DECL(PPC) +Z7_BRANCH_FUNCS_DECL(SPARC) +Z7_BRANCH_FUNCS_DECL(IA64) + +/* +These functions convert data that contain CPU instructions. +Each such function converts relative addresses to absolute addresses in some +branch instructions: CALL (in all converters) and JUMP (X86 converter only). +Such conversion allows to increase compression ratio, if we compress that data. + +There are 2 types of converters: + Byte * Conv_RISC (Byte *data, SizeT size, UInt32 pc); + Byte * ConvSt_X86(Byte *data, SizeT size, UInt32 pc, UInt32 *state); +Each Converter supports 2 versions: one for encoding +and one for decoding (_Enc/_Dec postfixes in function name). + +In params: + data : data buffer + size : size of data + pc : current virtual Program Counter (Instruction Pinter) value +In/Out param: + state : pointer to state variable (for X86 converter only) + +Return: + The pointer to position in (data) buffer after last byte that was processed. + If the caller calls converter again, it must call it starting with that position. + But the caller is allowed to move data in buffer. so pointer to + current processed position also will be changed for next call. + Also the caller must increase internal (pc) value for next call. +Each converter has some characteristics: Endian, Alignment, LookAhead. Type Endian Alignment LookAhead - x86 little 1 4 + X86 little 1 4 ARMT little 2 2 ARM little 4 0 + ARM64 little 4 0 PPC big 4 0 SPARC big 4 0 IA64 little 16 0 - size must be >= Alignment + LookAhead, if it's not last block. - If (size < Alignment + LookAhead), converter returns 0. + (data) must be aligned for (Alignment). + processed size can be calculated as: + SizeT processed = Conv(data, size, pc) - data; + if (processed == 0) + it means that converter needs more data for processing. + If (size < Alignment + LookAhead) + then (processed == 0) is allowed. - Example: - - UInt32 ip = 0; - for () - { - ; size must be >= Alignment + LookAhead, if it's not last block - SizeT processed = Convert(data, size, ip, 1); - data += processed; - size -= processed; - ip += processed; - } +Example code for conversion in loop: + UInt32 pc = 0; + size = 0; + for (;;) + { + size += Load_more_input_data(data + size); + SizeT processed = Conv(data, size, pc) - data; + if (processed == 0 && no_more_input_data_after_size) + break; // we stop convert loop + data += processed; + size -= processed; + pc += processed; + } */ -#define x86_Convert_Init(state) { state = 0; } -SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding); -SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); -SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding); - EXTERN_C_END #endif diff --git a/libraries/lzma/C/Bra86.c b/libraries/lzma/C/Bra86.c index 10a0fbd16..d81f392ae 100644 --- a/libraries/lzma/C/Bra86.c +++ b/libraries/lzma/C/Bra86.c @@ -1,82 +1,187 @@ -/* Bra86.c -- Converter for x86 code (BCJ) -2021-02-09 : Igor Pavlov : Public domain */ +/* Bra86.c -- Branch converter for X86 code (BCJ) +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" #include "Bra.h" +#include "CpuArch.h" -#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0) -SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding) +#if defined(MY_CPU_SIZEOF_POINTER) \ + && ( MY_CPU_SIZEOF_POINTER == 4 \ + || MY_CPU_SIZEOF_POINTER == 8) + #define BR_CONV_USE_OPT_PC_PTR +#endif + +#ifdef BR_CONV_USE_OPT_PC_PTR +#define BR_PC_INIT pc -= (UInt32)(SizeT)p; // (MY_uintptr_t) +#define BR_PC_GET (pc + (UInt32)(SizeT)p) +#else +#define BR_PC_INIT pc += (UInt32)size; +#define BR_PC_GET (pc - (UInt32)(SizeT)(lim - p)) +// #define BR_PC_INIT +// #define BR_PC_GET (pc + (UInt32)(SizeT)(p - data)) +#endif + +#define BR_CONVERT_VAL(v, c) if (encoding) v += c; else v -= c; +// #define BR_CONVERT_VAL(v, c) if (!encoding) c = (UInt32)0 - c; v += c; + +#define Z7_BRANCH_CONV_ST(name) z7_BranchConvSt_ ## name + +#define BR86_NEED_CONV_FOR_MS_BYTE(b) ((((b) + 1) & 0xfe) == 0) + +#ifdef MY_CPU_LE_UNALIGN + #define BR86_PREPARE_BCJ_SCAN const UInt32 v = GetUi32(p) ^ 0xe8e8e8e8; + #define BR86_IS_BCJ_BYTE(n) ((v & ((UInt32)0xfe << (n) * 8)) == 0) +#else + #define BR86_PREPARE_BCJ_SCAN + // bad for MSVC X86 (partial write to byte reg): + #define BR86_IS_BCJ_BYTE(n) ((p[n - 4] & 0xfe) == 0xe8) + // bad for old MSVC (partial write to byte reg): + // #define BR86_IS_BCJ_BYTE(n) (((*p ^ 0xe8) & 0xfe) == 0) +#endif + +static +Z7_FORCE_INLINE +Z7_ATTRIB_NO_VECTOR +Byte *Z7_BRANCH_CONV_ST(X86)(Byte *p, SizeT size, UInt32 pc, UInt32 *state, int encoding) { - SizeT pos = 0; - UInt32 mask = *state & 7; if (size < 5) - return 0; - size -= 4; - ip += 5; + return p; + { + // Byte *p = data; + const Byte *lim = p + size - 4; + unsigned mask = (unsigned)*state; // & 7; +#ifdef BR_CONV_USE_OPT_PC_PTR + /* if BR_CONV_USE_OPT_PC_PTR is defined: we need to adjust (pc) for (+4), + because call/jump offset is relative to the next instruction. + if BR_CONV_USE_OPT_PC_PTR is not defined : we don't need to adjust (pc) for (+4), + because BR_PC_GET uses (pc - (lim - p)), and lim was adjusted for (-4) before. + */ + pc += 4; +#endif + BR_PC_INIT + goto start; - for (;;) + for (;; mask |= 4) { - Byte *p = data + pos; - const Byte *limit = data + size; - for (; p < limit; p++) - if ((*p & 0xFE) == 0xE8) - break; - + // cont: mask |= 4; + start: + if (p >= lim) + goto fin; { - SizeT d = (SizeT)(p - data) - pos; - pos = (SizeT)(p - data); - if (p >= limit) - { - *state = (d > 2 ? 0 : mask >> (unsigned)d); - return pos; - } - if (d > 2) - mask = 0; - else - { - mask >>= (unsigned)d; - if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(size_t)(mask >> 1) + 1]))) - { - mask = (mask >> 1) | 4; - pos++; - continue; - } - } + BR86_PREPARE_BCJ_SCAN + p += 4; + if (BR86_IS_BCJ_BYTE(0)) { goto m0; } mask >>= 1; + if (BR86_IS_BCJ_BYTE(1)) { goto m1; } mask >>= 1; + if (BR86_IS_BCJ_BYTE(2)) { goto m2; } mask = 0; + if (BR86_IS_BCJ_BYTE(3)) { goto a3; } } + goto main_loop; - if (Test86MSByte(p[4])) + m0: p--; + m1: p--; + m2: p--; + if (mask == 0) + goto a3; + if (p > lim) + goto fin_p; + + // if (((0x17u >> mask) & 1) == 0) + if (mask > 4 || mask == 3) { - UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]); - UInt32 cur = ip + (UInt32)pos; - pos += 5; - if (encoding) - v += cur; - else - v -= cur; - if (mask != 0) + mask >>= 1; + continue; // goto cont; + } + mask >>= 1; + if (BR86_NEED_CONV_FOR_MS_BYTE(p[mask])) + continue; // goto cont; + // if (!BR86_NEED_CONV_FOR_MS_BYTE(p[3])) continue; // goto cont; + { + UInt32 v = GetUi32(p); + UInt32 c; + v += (1 << 24); if (v & 0xfe000000) continue; // goto cont; + c = BR_PC_GET; + BR_CONVERT_VAL(v, c) { - unsigned sh = (mask & 6) << 2; - if (Test86MSByte((Byte)(v >> sh))) + mask <<= 3; + if (BR86_NEED_CONV_FOR_MS_BYTE(v >> mask)) { - v ^= (((UInt32)0x100 << sh) - 1); - if (encoding) - v += cur; - else - v -= cur; + v ^= (((UInt32)0x100 << mask) - 1); + #ifdef MY_CPU_X86 + // for X86 : we can recalculate (c) to reduce register pressure + c = BR_PC_GET; + #endif + BR_CONVERT_VAL(v, c) } mask = 0; } - p[1] = (Byte)v; - p[2] = (Byte)(v >> 8); - p[3] = (Byte)(v >> 16); - p[4] = (Byte)(0 - ((v >> 24) & 1)); + // v = (v & ((1 << 24) - 1)) - (v & (1 << 24)); + v &= (1 << 25) - 1; v -= (1 << 24); + SetUi32(p, v) + p += 4; + goto main_loop; } - else + + main_loop: + if (p >= lim) + goto fin; + for (;;) { - mask = (mask >> 1) | 4; - pos++; + BR86_PREPARE_BCJ_SCAN + p += 4; + if (BR86_IS_BCJ_BYTE(0)) { goto a0; } + if (BR86_IS_BCJ_BYTE(1)) { goto a1; } + if (BR86_IS_BCJ_BYTE(2)) { goto a2; } + if (BR86_IS_BCJ_BYTE(3)) { goto a3; } + if (p >= lim) + goto fin; + } + + a0: p--; + a1: p--; + a2: p--; + a3: + if (p > lim) + goto fin_p; + // if (!BR86_NEED_CONV_FOR_MS_BYTE(p[3])) continue; // goto cont; + { + UInt32 v = GetUi32(p); + UInt32 c; + v += (1 << 24); if (v & 0xfe000000) continue; // goto cont; + c = BR_PC_GET; + BR_CONVERT_VAL(v, c) + // v = (v & ((1 << 24) - 1)) - (v & (1 << 24)); + v &= (1 << 25) - 1; v -= (1 << 24); + SetUi32(p, v) + p += 4; + goto main_loop; } } + +fin_p: + p--; +fin: + // the following processing for tail is optional and can be commented + /* + lim += 4; + for (; p < lim; p++, mask >>= 1) + if ((*p & 0xfe) == 0xe8) + break; + */ + *state = (UInt32)mask; + return p; + } } + + +#define Z7_BRANCH_CONV_ST_FUNC_IMP(name, m, encoding) \ +Z7_NO_INLINE \ +Z7_ATTRIB_NO_VECTOR \ +Byte *m(name)(Byte *data, SizeT size, UInt32 pc, UInt32 *state) \ + { return Z7_BRANCH_CONV_ST(name)(data, size, pc, state, encoding); } + +Z7_BRANCH_CONV_ST_FUNC_IMP(X86, Z7_BRANCH_CONV_ST_DEC, 0) +#ifndef Z7_EXTRACT_ONLY +Z7_BRANCH_CONV_ST_FUNC_IMP(X86, Z7_BRANCH_CONV_ST_ENC, 1) +#endif diff --git a/libraries/lzma/C/BraIA64.c b/libraries/lzma/C/BraIA64.c index d1dbc62c5..9dfe3e289 100644 --- a/libraries/lzma/C/BraIA64.c +++ b/libraries/lzma/C/BraIA64.c @@ -1,53 +1,14 @@ /* BraIA64.c -- Converter for IA-64 code -2017-01-26 : Igor Pavlov : Public domain */ +2023-02-20 : Igor Pavlov : Public domain */ #include "Precomp.h" -#include "CpuArch.h" -#include "Bra.h" +// the code was moved to Bra.c -SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding) -{ - SizeT i; - if (size < 16) - return 0; - size -= 16; - i = 0; - do - { - unsigned m = ((UInt32)0x334B0000 >> (data[i] & 0x1E)) & 3; - if (m) - { - m++; - do - { - Byte *p = data + (i + (size_t)m * 5 - 8); - if (((p[3] >> m) & 15) == 5 - && (((p[-1] | ((UInt32)p[0] << 8)) >> m) & 0x70) == 0) - { - unsigned raw = GetUi32(p); - unsigned v = raw >> m; - v = (v & 0xFFFFF) | ((v & (1 << 23)) >> 3); - - v <<= 4; - if (encoding) - v += ip + (UInt32)i; - else - v -= ip + (UInt32)i; - v >>= 4; - - v &= 0x1FFFFF; - v += 0x700000; - v &= 0x8FFFFF; - raw &= ~((UInt32)0x8FFFFF << m); - raw |= (v << m); - SetUi32(p, raw); - } - } - while (++m <= 4); - } - i += 16; - } - while (i <= size); - return i; -} +#ifdef _MSC_VER +#pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty +#endif + +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wempty-translation-unit" +#endif diff --git a/libraries/lzma/C/Compiler.h b/libraries/lzma/C/Compiler.h index a9816fa5a..185a52deb 100644 --- a/libraries/lzma/C/Compiler.h +++ b/libraries/lzma/C/Compiler.h @@ -1,12 +1,37 @@ -/* Compiler.h -2021-01-05 : Igor Pavlov : Public domain */ +/* Compiler.h : Compiler specific defines and pragmas +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __7Z_COMPILER_H -#define __7Z_COMPILER_H +#ifndef ZIP7_INC_COMPILER_H +#define ZIP7_INC_COMPILER_H + +#if defined(__clang__) +# define Z7_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) +#endif +#if defined(__clang__) && defined(__apple_build_version__) +# define Z7_APPLE_CLANG_VERSION Z7_CLANG_VERSION +#elif defined(__clang__) +# define Z7_LLVM_CLANG_VERSION Z7_CLANG_VERSION +#elif defined(__GNUC__) +# define Z7_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#ifdef _MSC_VER +#if !defined(__clang__) && !defined(__GNUC__) +#define Z7_MSC_VER_ORIGINAL _MSC_VER +#endif +#endif + +#if defined(__MINGW32__) || defined(__MINGW64__) +#define Z7_MINGW +#endif + +// #pragma GCC diagnostic ignored "-Wunknown-pragmas" + +#ifdef __clang__ +// padding size of '' with 4 bytes to alignment boundary +#pragma GCC diagnostic ignored "-Wpadded" +#endif - #ifdef __clang__ - #pragma clang diagnostic ignored "-Wunused-private-field" - #endif #ifdef _MSC_VER @@ -17,24 +42,115 @@ #pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int #endif - #if _MSC_VER >= 1300 - #pragma warning(disable : 4996) // This function or variable may be unsafe - #else - #pragma warning(disable : 4511) // copy constructor could not be generated - #pragma warning(disable : 4512) // assignment operator could not be generated - #pragma warning(disable : 4514) // unreferenced inline function has been removed - #pragma warning(disable : 4702) // unreachable code - #pragma warning(disable : 4710) // not inlined - #pragma warning(disable : 4714) // function marked as __forceinline not inlined - #pragma warning(disable : 4786) // identifier was truncated to '255' characters in the debug information - #endif +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#pragma warning(disable : 4464) // relative include path contains '..' +#endif - #ifdef __clang__ - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - #pragma clang diagnostic ignored "-Wmicrosoft-exception-spec" - // #pragma clang diagnostic ignored "-Wreserved-id-macro" - #endif +// == 1200 : -O1 : for __forceinline +// >= 1900 : -O1 : for printf +#pragma warning(disable : 4710) // function not inlined +#if _MSC_VER < 1900 +// winnt.h: 'Int64ShllMod32' +#pragma warning(disable : 4514) // unreferenced inline function has been removed +#endif + +#if _MSC_VER < 1300 +// #pragma warning(disable : 4702) // unreachable code +// Bra.c : -O1: +#pragma warning(disable : 4714) // function marked as __forceinline not inlined +#endif + +/* +#if _MSC_VER > 1400 && _MSC_VER <= 1900 +// strcat: This function or variable may be unsafe +// sysinfoapi.h: kit10: GetVersion was declared deprecated +#pragma warning(disable : 4996) +#endif +*/ + +#if _MSC_VER > 1200 +// -Wall warnings + +#pragma warning(disable : 4711) // function selected for automatic inline expansion +#pragma warning(disable : 4820) // '2' bytes padding added after data member + +#if _MSC_VER >= 1400 && _MSC_VER < 1920 +// 1400: string.h: _DBG_MEMCPY_INLINE_ +// 1600 - 191x : smmintrin.h __cplusplus' +// is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' +#pragma warning(disable : 4668) + +// 1400 - 1600 : WinDef.h : 'FARPROC' : +// 1900 - 191x : immintrin.h: _readfsbase_u32 +// no function prototype given : converting '()' to '(void)' +#pragma warning(disable : 4255) +#endif + +#if _MSC_VER >= 1914 +// Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified +#pragma warning(disable : 5045) +#endif + +#endif // _MSC_VER > 1200 +#endif // _MSC_VER + + +#if defined(__clang__) && (__clang_major__ >= 4) + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + _Pragma("clang loop unroll(disable)") \ + _Pragma("clang loop vectorize(disable)") + #define Z7_ATTRIB_NO_VECTORIZE +#elif defined(__GNUC__) && (__GNUC__ >= 5) + #define Z7_ATTRIB_NO_VECTORIZE __attribute__((optimize("no-tree-vectorize"))) + // __attribute__((optimize("no-unroll-loops"))); + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE +#elif defined(_MSC_VER) && (_MSC_VER >= 1920) + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \ + _Pragma("loop( no_vector )") + #define Z7_ATTRIB_NO_VECTORIZE +#else + #define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + #define Z7_ATTRIB_NO_VECTORIZE +#endif + +#if defined(MY_CPU_X86_OR_AMD64) && ( \ + defined(__clang__) && (__clang_major__ >= 4) \ + || defined(__GNUC__) && (__GNUC__ >= 5)) + #define Z7_ATTRIB_NO_SSE __attribute__((__target__("no-sse"))) +#else + #define Z7_ATTRIB_NO_SSE +#endif + +#define Z7_ATTRIB_NO_VECTOR \ + Z7_ATTRIB_NO_VECTORIZE \ + Z7_ATTRIB_NO_SSE + + +#if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 1000) \ + /* || defined(_MSC_VER) && (_MSC_VER >= 1920) */ + // GCC is not good for __builtin_expect() + #define Z7_LIKELY(x) (__builtin_expect((x), 1)) + #define Z7_UNLIKELY(x) (__builtin_expect((x), 0)) + // #define Z7_unlikely [[unlikely]] + // #define Z7_likely [[likely]] +#else + #define Z7_LIKELY(x) (x) + #define Z7_UNLIKELY(x) (x) + // #define Z7_likely +#endif + + +#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 36000)) +#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreserved-macro-identifier\"") +#define Z7_DIAGNOSCTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER \ + _Pragma("GCC diagnostic pop") +#else +#define Z7_DIAGNOSCTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER +#define Z7_DIAGNOSCTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER #endif #define UNUSED_VAR(x) (void)x; diff --git a/libraries/lzma/C/CpuArch.c b/libraries/lzma/C/CpuArch.c index fa9afe397..33f8a3ab4 100644 --- a/libraries/lzma/C/CpuArch.c +++ b/libraries/lzma/C/CpuArch.c @@ -1,187 +1,318 @@ /* CpuArch.c -- CPU specific code -2021-07-13 : Igor Pavlov : Public domain */ +2023-05-18 : Igor Pavlov : Public domain */ #include "Precomp.h" +// #include + #include "CpuArch.h" #ifdef MY_CPU_X86_OR_AMD64 -#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) -#define USE_ASM +#undef NEED_CHECK_FOR_CPUID +#if !defined(MY_CPU_AMD64) +#define NEED_CHECK_FOR_CPUID #endif -#if !defined(USE_ASM) && _MSC_VER >= 1500 -#include +/* + cpuid instruction supports (subFunction) parameter in ECX, + that is used only with some specific (function) parameter values. + But we always use only (subFunction==0). +*/ +/* + __cpuid(): MSVC and GCC/CLANG use same function/macro name + but parameters are different. + We use MSVC __cpuid() parameters style for our z7_x86_cpuid() function. +*/ + +#if defined(__GNUC__) /* && (__GNUC__ >= 10) */ \ + || defined(__clang__) /* && (__clang_major__ >= 10) */ + +/* there was some CLANG/GCC compilers that have issues with + rbx(ebx) handling in asm blocks in -fPIC mode (__PIC__ is defined). + compiler's contains the macro __cpuid() that is similar to our code. + The history of __cpuid() changes in CLANG/GCC: + GCC: + 2007: it preserved ebx for (__PIC__ && __i386__) + 2013: it preserved rbx and ebx for __PIC__ + 2014: it doesn't preserves rbx and ebx anymore + we suppose that (__GNUC__ >= 5) fixed that __PIC__ ebx/rbx problem. + CLANG: + 2014+: it preserves rbx, but only for 64-bit code. No __PIC__ check. + Why CLANG cares about 64-bit mode only, and doesn't care about ebx (in 32-bit)? + Do we need __PIC__ test for CLANG or we must care about rbx even if + __PIC__ is not defined? +*/ + +#define ASM_LN "\n" + +#if defined(MY_CPU_AMD64) && defined(__PIC__) \ + && ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__)) + +#define x86_cpuid_MACRO(p, func) { \ + __asm__ __volatile__ ( \ + ASM_LN "mov %%rbx, %q1" \ + ASM_LN "cpuid" \ + ASM_LN "xchg %%rbx, %q1" \ + : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(0)); } + + /* "=&r" selects free register. It can select even rbx, if that register is free. + "=&D" for (RDI) also works, but the code can be larger with "=&D" + "2"(0) means (subFunction = 0), + 2 is (zero-based) index in the output constraint list "=c" (ECX). */ + +#elif defined(MY_CPU_X86) && defined(__PIC__) \ + && ((defined (__GNUC__) && (__GNUC__ < 5)) || defined(__clang__)) + +#define x86_cpuid_MACRO(p, func) { \ + __asm__ __volatile__ ( \ + ASM_LN "mov %%ebx, %k1" \ + ASM_LN "cpuid" \ + ASM_LN "xchg %%ebx, %k1" \ + : "=a" ((p)[0]), "=&r" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(0)); } + +#else + +#define x86_cpuid_MACRO(p, func) { \ + __asm__ __volatile__ ( \ + ASM_LN "cpuid" \ + : "=a" ((p)[0]), "=b" ((p)[1]), "=c" ((p)[2]), "=d" ((p)[3]) : "0" (func), "2"(0)); } + #endif -#if defined(USE_ASM) && !defined(MY_CPU_AMD64) -static UInt32 CheckFlag(UInt32 flag) + +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) { - #ifdef _MSC_VER - __asm pushfd; - __asm pop EAX; - __asm mov EDX, EAX; - __asm xor EAX, flag; - __asm push EAX; - __asm popfd; - __asm pushfd; - __asm pop EAX; - __asm xor EAX, EDX; - __asm push EDX; - __asm popfd; - __asm and flag, EAX; - #else - __asm__ __volatile__ ( - "pushf\n\t" - "pop %%EAX\n\t" - "movl %%EAX,%%EDX\n\t" - "xorl %0,%%EAX\n\t" - "push %%EAX\n\t" - "popf\n\t" - "pushf\n\t" - "pop %%EAX\n\t" - "xorl %%EDX,%%EAX\n\t" - "push %%EDX\n\t" - "popf\n\t" - "andl %%EAX, %0\n\t": - "=c" (flag) : "c" (flag) : - "%eax", "%edx"); - #endif - return flag; + x86_cpuid_MACRO(p, func) } -#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False; + + +Z7_NO_INLINE +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + #if defined(NEED_CHECK_FOR_CPUID) + #define EFALGS_CPUID_BIT 21 + UInt32 a; + __asm__ __volatile__ ( + ASM_LN "pushf" + ASM_LN "pushf" + ASM_LN "pop %0" + // ASM_LN "movl %0, %1" + // ASM_LN "xorl $0x200000, %0" + ASM_LN "btc %1, %0" + ASM_LN "push %0" + ASM_LN "popf" + ASM_LN "pushf" + ASM_LN "pop %0" + ASM_LN "xorl (%%esp), %0" + + ASM_LN "popf" + ASM_LN + : "=&r" (a) // "=a" + : "i" (EFALGS_CPUID_BIT) + ); + if ((a & (1 << EFALGS_CPUID_BIT)) == 0) + return 0; + #endif + { + UInt32 p[4]; + x86_cpuid_MACRO(p, 0) + return p[0]; + } +} + +#undef ASM_LN + +#elif !defined(_MSC_VER) + +/* +// for gcc/clang and other: we can try to use __cpuid macro: +#include +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + __cpuid(func, p[0], p[1], p[2], p[3]); +} +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + return (UInt32)__get_cpuid_max(0, NULL); +} +*/ +// for unsupported cpuid: +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + UNUSED_VAR(func) + p[0] = p[1] = p[2] = p[3] = 0; +} +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + return 0; +} + +#else // _MSC_VER + +#if !defined(MY_CPU_AMD64) + +UInt32 __declspec(naked) Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + #if defined(NEED_CHECK_FOR_CPUID) + #define EFALGS_CPUID_BIT 21 + __asm pushfd + __asm pushfd + /* + __asm pop eax + // __asm mov edx, eax + __asm btc eax, EFALGS_CPUID_BIT + __asm push eax + */ + __asm btc dword ptr [esp], EFALGS_CPUID_BIT + __asm popfd + __asm pushfd + __asm pop eax + // __asm xor eax, edx + __asm xor eax, [esp] + // __asm push edx + __asm popfd + __asm and eax, (1 shl EFALGS_CPUID_BIT) + __asm jz end_func + #endif + __asm push ebx + __asm xor eax, eax // func + __asm xor ecx, ecx // subFunction (optional) for (func == 0) + __asm cpuid + __asm pop ebx + #if defined(NEED_CHECK_FOR_CPUID) + end_func: + #endif + __asm ret 0 +} + +void __declspec(naked) Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + UNUSED_VAR(p) + UNUSED_VAR(func) + __asm push ebx + __asm push edi + __asm mov edi, ecx // p + __asm mov eax, edx // func + __asm xor ecx, ecx // subfunction (optional) for (func == 0) + __asm cpuid + __asm mov [edi ], eax + __asm mov [edi + 4], ebx + __asm mov [edi + 8], ecx + __asm mov [edi + 12], edx + __asm pop edi + __asm pop ebx + __asm ret 0 +} + +#else // MY_CPU_AMD64 + + #if _MSC_VER >= 1600 + #include + #define MY_cpuidex __cpuidex + #else +/* + __cpuid (func == (0 or 7)) requires subfunction number in ECX. + MSDN: The __cpuid intrinsic clears the ECX register before calling the cpuid instruction. + __cpuid() in new MSVC clears ECX. + __cpuid() in old MSVC (14.00) x64 doesn't clear ECX + We still can use __cpuid for low (func) values that don't require ECX, + but __cpuid() in old MSVC will be incorrect for some func values: (func == 7). + So here we use the hack for old MSVC to send (subFunction) in ECX register to cpuid instruction, + where ECX value is first parameter for FASTCALL / NO_INLINE func, + So the caller of MY_cpuidex_HACK() sets ECX as subFunction, and + old MSVC for __cpuid() doesn't change ECX and cpuid instruction gets (subFunction) value. + +DON'T remove Z7_NO_INLINE and Z7_FASTCALL for MY_cpuidex_HACK(): !!! +*/ +static +Z7_NO_INLINE void Z7_FASTCALL MY_cpuidex_HACK(UInt32 subFunction, UInt32 func, int *CPUInfo) +{ + UNUSED_VAR(subFunction) + __cpuid(CPUInfo, func); +} + #define MY_cpuidex(info, func, func2) MY_cpuidex_HACK(func2, func, info) + #pragma message("======== MY_cpuidex_HACK WAS USED ========") + #endif // _MSC_VER >= 1600 + +#if !defined(MY_CPU_AMD64) +/* inlining for __cpuid() in MSVC x86 (32-bit) produces big ineffective code, + so we disable inlining here */ +Z7_NO_INLINE +#endif +void Z7_FASTCALL z7_x86_cpuid(UInt32 p[4], UInt32 func) +{ + MY_cpuidex((int *)p, (int)func, 0); +} + +Z7_NO_INLINE +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void) +{ + int a[4]; + MY_cpuidex(a, 0, 0); + return a[0]; +} + +#endif // MY_CPU_AMD64 +#endif // _MSC_VER + +#if defined(NEED_CHECK_FOR_CPUID) +#define CHECK_CPUID_IS_SUPPORTED { if (z7_x86_cpuid_GetMaxFunc() == 0) return 0; } #else #define CHECK_CPUID_IS_SUPPORTED #endif +#undef NEED_CHECK_FOR_CPUID -#ifndef USE_ASM - #ifdef _MSC_VER - #if _MSC_VER >= 1600 - #define MY__cpuidex __cpuidex - #else - -/* - __cpuid (function == 4) requires subfunction number in ECX. - MSDN: The __cpuid intrinsic clears the ECX register before calling the cpuid instruction. - __cpuid() in new MSVC clears ECX. - __cpuid() in old MSVC (14.00) doesn't clear ECX - We still can use __cpuid for low (function) values that don't require ECX, - but __cpuid() in old MSVC will be incorrect for some function values: (function == 4). - So here we use the hack for old MSVC to send (subFunction) in ECX register to cpuid instruction, - where ECX value is first parameter for FAST_CALL / NO_INLINE function, - So the caller of MY__cpuidex_HACK() sets ECX as subFunction, and - old MSVC for __cpuid() doesn't change ECX and cpuid instruction gets (subFunction) value. - - DON'T remove MY_NO_INLINE and MY_FAST_CALL for MY__cpuidex_HACK() !!! -*/ static -MY_NO_INLINE -void MY_FAST_CALL MY__cpuidex_HACK(UInt32 subFunction, int *CPUInfo, UInt32 function) -{ - UNUSED_VAR(subFunction); - __cpuid(CPUInfo, function); -} - - #define MY__cpuidex(info, func, func2) MY__cpuidex_HACK(func2, info, func) - #pragma message("======== MY__cpuidex_HACK WAS USED ========") - #endif - #else - #define MY__cpuidex(info, func, func2) __cpuid(info, func) - #pragma message("======== (INCORRECT ?) cpuid WAS USED ========") - #endif -#endif - - - - -void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d) -{ - #ifdef USE_ASM - - #ifdef _MSC_VER - - UInt32 a2, b2, c2, d2; - __asm xor EBX, EBX; - __asm xor ECX, ECX; - __asm xor EDX, EDX; - __asm mov EAX, function; - __asm cpuid; - __asm mov a2, EAX; - __asm mov b2, EBX; - __asm mov c2, ECX; - __asm mov d2, EDX; - - *a = a2; - *b = b2; - *c = c2; - *d = d2; - - #else - - __asm__ __volatile__ ( - #if defined(MY_CPU_AMD64) && defined(__PIC__) - "mov %%rbx, %%rdi;" - "cpuid;" - "xchg %%rbx, %%rdi;" - : "=a" (*a) , - "=D" (*b) , - #elif defined(MY_CPU_X86) && defined(__PIC__) - "mov %%ebx, %%edi;" - "cpuid;" - "xchgl %%ebx, %%edi;" - : "=a" (*a) , - "=D" (*b) , - #else - "cpuid" - : "=a" (*a) , - "=b" (*b) , - #endif - "=c" (*c) , - "=d" (*d) - : "0" (function), "c"(0) ) ; - - #endif - - #else - - int CPUInfo[4]; - - MY__cpuidex(CPUInfo, (int)function, 0); - - *a = (UInt32)CPUInfo[0]; - *b = (UInt32)CPUInfo[1]; - *c = (UInt32)CPUInfo[2]; - *d = (UInt32)CPUInfo[3]; - - #endif -} - -BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p) +BoolInt x86cpuid_Func_1(UInt32 *p) { CHECK_CPUID_IS_SUPPORTED - MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); - MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); + z7_x86_cpuid(p, 1); return True; } -static const UInt32 kVendors[][3] = +/* +static const UInt32 kVendors[][1] = { - { 0x756E6547, 0x49656E69, 0x6C65746E}, - { 0x68747541, 0x69746E65, 0x444D4163}, - { 0x746E6543, 0x48727561, 0x736C7561} + { 0x756E6547 }, // , 0x49656E69, 0x6C65746E }, + { 0x68747541 }, // , 0x69746E65, 0x444D4163 }, + { 0x746E6543 } // , 0x48727561, 0x736C7561 } }; +*/ + +/* +typedef struct +{ + UInt32 maxFunc; + UInt32 vendor[3]; + UInt32 ver; + UInt32 b; + UInt32 c; + UInt32 d; +} Cx86cpuid; + +enum +{ + CPU_FIRM_INTEL, + CPU_FIRM_AMD, + CPU_FIRM_VIA +}; +int x86cpuid_GetFirm(const Cx86cpuid *p); +#define x86cpuid_ver_GetFamily(ver) (((ver >> 16) & 0xff0) | ((ver >> 8) & 0xf)) +#define x86cpuid_ver_GetModel(ver) (((ver >> 12) & 0xf0) | ((ver >> 4) & 0xf)) +#define x86cpuid_ver_GetStepping(ver) (ver & 0xf) int x86cpuid_GetFirm(const Cx86cpuid *p) { unsigned i; - for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) + for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[0]); i++) { const UInt32 *v = kVendors[i]; - if (v[0] == p->vendor[0] && - v[1] == p->vendor[1] && - v[2] == p->vendor[2]) + if (v[0] == p->vendor[0] + // && v[1] == p->vendor[1] + // && v[2] == p->vendor[2] + ) return (int)i; } return -1; @@ -190,41 +321,55 @@ int x86cpuid_GetFirm(const Cx86cpuid *p) BoolInt CPU_Is_InOrder() { Cx86cpuid p; - int firm; UInt32 family, model; if (!x86cpuid_CheckAndRead(&p)) return True; - family = x86cpuid_GetFamily(p.ver); - model = x86cpuid_GetModel(p.ver); - - firm = x86cpuid_GetFirm(&p); + family = x86cpuid_ver_GetFamily(p.ver); + model = x86cpuid_ver_GetModel(p.ver); - switch (firm) + switch (x86cpuid_GetFirm(&p)) { case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && ( - /* In-Order Atom CPU */ - model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */ - || model == 0x26 /* 45 nm, Z6xx */ - || model == 0x27 /* 32 nm, Z2460 */ - || model == 0x35 /* 32 nm, Z2760 */ - || model == 0x36 /* 32 nm, N2xxx, D2xxx */ + // In-Order Atom CPU + model == 0x1C // 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 + || model == 0x26 // 45 nm, Z6xx + || model == 0x27 // 32 nm, Z2460 + || model == 0x35 // 32 nm, Z2760 + || model == 0x36 // 32 nm, N2xxx, D2xxx ))); case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA))); case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); } - return True; + return False; // v23 : unknown processors are not In-Order } +*/ + +#ifdef _WIN32 +#include "7zWindows.h" +#endif #if !defined(MY_CPU_AMD64) && defined(_WIN32) -#include -static BoolInt CPU_Sys_Is_SSE_Supported() + +/* for legacy SSE ia32: there is no user-space cpu instruction to check + that OS supports SSE register storing/restoring on context switches. + So we need some OS-specific function to check that it's safe to use SSE registers. +*/ + +Z7_FORCE_INLINE +static BoolInt CPU_Sys_Is_SSE_Supported(void) { - OSVERSIONINFO vi; - vi.dwOSVersionInfoSize = sizeof(vi); - if (!GetVersionEx(&vi)) - return False; - return (vi.dwMajorVersion >= 5); +#ifdef _MSC_VER + #pragma warning(push) + #pragma warning(disable : 4996) // `GetVersion': was declared deprecated +#endif + /* low byte is major version of Windows + We suppose that any Windows version since + Windows2000 (major == 5) supports SSE registers */ + return (Byte)GetVersion() >= 5; +#if defined(_MSC_VER) + #pragma warning(pop) +#endif } #define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; #else @@ -232,94 +377,300 @@ static BoolInt CPU_Sys_Is_SSE_Supported() #endif -static UInt32 X86_CPUID_ECX_Get_Flags() +#if !defined(MY_CPU_AMD64) + +BoolInt CPU_IsSupported_CMOV(void) { - Cx86cpuid p; - CHECK_SYS_SSE_SUPPORT - if (!x86cpuid_CheckAndRead(&p)) + UInt32 a[4]; + if (!x86cpuid_Func_1(&a[0])) return 0; - return p.c; + return (a[3] >> 15) & 1; } -BoolInt CPU_IsSupported_AES() +BoolInt CPU_IsSupported_SSE(void) { - return (X86_CPUID_ECX_Get_Flags() >> 25) & 1; -} - -BoolInt CPU_IsSupported_SSSE3() -{ - return (X86_CPUID_ECX_Get_Flags() >> 9) & 1; -} - -BoolInt CPU_IsSupported_SSE41() -{ - return (X86_CPUID_ECX_Get_Flags() >> 19) & 1; -} - -BoolInt CPU_IsSupported_SHA() -{ - Cx86cpuid p; + UInt32 a[4]; CHECK_SYS_SSE_SUPPORT - if (!x86cpuid_CheckAndRead(&p)) - return False; + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (a[3] >> 25) & 1; +} - if (p.maxFunc < 7) +BoolInt CPU_IsSupported_SSE2(void) +{ + UInt32 a[4]; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_Func_1(&a[0])) + return 0; + return (a[3] >> 26) & 1; +} + +#endif + + +static UInt32 x86cpuid_Func_1_ECX(void) +{ + UInt32 a[4]; + CHECK_SYS_SSE_SUPPORT + if (!x86cpuid_Func_1(&a[0])) + return 0; + return a[2]; +} + +BoolInt CPU_IsSupported_AES(void) +{ + return (x86cpuid_Func_1_ECX() >> 25) & 1; +} + +BoolInt CPU_IsSupported_SSSE3(void) +{ + return (x86cpuid_Func_1_ECX() >> 9) & 1; +} + +BoolInt CPU_IsSupported_SSE41(void) +{ + return (x86cpuid_Func_1_ECX() >> 19) & 1; +} + +BoolInt CPU_IsSupported_SHA(void) +{ + CHECK_SYS_SSE_SUPPORT + + if (z7_x86_cpuid_GetMaxFunc() < 7) return False; { - UInt32 d[4] = { 0 }; - MyCPUID(7, &d[0], &d[1], &d[2], &d[3]); + UInt32 d[4]; + z7_x86_cpuid(d, 7); return (d[1] >> 29) & 1; } } -// #include +/* +MSVC: _xgetbv() intrinsic is available since VS2010SP1. + MSVC also defines (_XCR_XFEATURE_ENABLED_MASK) macro in + that we can use or check. + For any 32-bit x86 we can use asm code in MSVC, + but MSVC asm code is huge after compilation. + So _xgetbv() is better -#ifdef _WIN32 -#include +ICC: _xgetbv() intrinsic is available (in what version of ICC?) + ICC defines (__GNUC___) and it supports gnu assembler + also ICC supports MASM style code with -use-msasm switch. + but ICC doesn't support __attribute__((__target__)) + +GCC/CLANG 9: + _xgetbv() is macro that works via __builtin_ia32_xgetbv() + and we need __attribute__((__target__("xsave")). + But with __target__("xsave") the function will be not + inlined to function that has no __target__("xsave") attribute. + If we want _xgetbv() call inlining, then we should use asm version + instead of calling _xgetbv(). + Note:intrinsic is broke before GCC 8.2: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85684 +*/ + +#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1100) \ + || defined(_MSC_VER) && (_MSC_VER >= 1600) && (_MSC_FULL_VER >= 160040219) \ + || defined(__GNUC__) && (__GNUC__ >= 9) \ + || defined(__clang__) && (__clang_major__ >= 9) +// we define ATTRIB_XGETBV, if we want to use predefined _xgetbv() from compiler +#if defined(__INTEL_COMPILER) +#define ATTRIB_XGETBV +#elif defined(__GNUC__) || defined(__clang__) +// we don't define ATTRIB_XGETBV here, because asm version is better for inlining. +// #define ATTRIB_XGETBV __attribute__((__target__("xsave"))) +#else +#define ATTRIB_XGETBV +#endif #endif -BoolInt CPU_IsSupported_AVX2() -{ - Cx86cpuid p; - CHECK_SYS_SSE_SUPPORT +#if defined(ATTRIB_XGETBV) +#include +#endif + +// XFEATURE_ENABLED_MASK/XCR0 +#define MY_XCR_XFEATURE_ENABLED_MASK 0 + +#if defined(ATTRIB_XGETBV) +ATTRIB_XGETBV +#endif +static UInt64 x86_xgetbv_0(UInt32 num) +{ +#if defined(ATTRIB_XGETBV) + { + return + #if (defined(_MSC_VER)) + _xgetbv(num); + #else + __builtin_ia32_xgetbv( + #if !defined(__clang__) + (int) + #endif + num); + #endif + } + +#elif defined(__GNUC__) || defined(__clang__) || defined(__SUNPRO_CC) + + UInt32 a, d; + #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) + __asm__ + ( + "xgetbv" + : "=a"(a), "=d"(d) : "c"(num) : "cc" + ); + #else // is old gcc + __asm__ + ( + ".byte 0x0f, 0x01, 0xd0" "\n\t" + : "=a"(a), "=d"(d) : "c"(num) : "cc" + ); + #endif + return ((UInt64)d << 32) | a; + // return a; + +#elif defined(_MSC_VER) && !defined(MY_CPU_AMD64) + + UInt32 a, d; + __asm { + push eax + push edx + push ecx + mov ecx, num; + // xor ecx, ecx // = MY_XCR_XFEATURE_ENABLED_MASK + _emit 0x0f + _emit 0x01 + _emit 0xd0 + mov a, eax + mov d, edx + pop ecx + pop edx + pop eax + } + return ((UInt64)d << 32) | a; + // return a; + +#else // it's unknown compiler + // #error "Need xgetbv function" + UNUSED_VAR(num) + // for MSVC-X64 we could call external function from external file. + /* Actually we had checked OSXSAVE/AVX in cpuid before. + So it's expected that OS supports at least AVX and below. */ + // if (num != MY_XCR_XFEATURE_ENABLED_MASK) return 0; // if not XCR0 + return + // (1 << 0) | // x87 + (1 << 1) // SSE + | (1 << 2); // AVX + +#endif +} + +#ifdef _WIN32 +/* + Windows versions do not know about new ISA extensions that + can be introduced. But we still can use new extensions, + even if Windows doesn't report about supporting them, + But we can use new extensions, only if Windows knows about new ISA extension + that changes the number or size of registers: SSE, AVX/XSAVE, AVX512 + So it's enough to check + MY_PF_AVX_INSTRUCTIONS_AVAILABLE + instead of + MY_PF_AVX2_INSTRUCTIONS_AVAILABLE +*/ +#define MY_PF_XSAVE_ENABLED 17 +// #define MY_PF_SSSE3_INSTRUCTIONS_AVAILABLE 36 +// #define MY_PF_SSE4_1_INSTRUCTIONS_AVAILABLE 37 +// #define MY_PF_SSE4_2_INSTRUCTIONS_AVAILABLE 38 +// #define MY_PF_AVX_INSTRUCTIONS_AVAILABLE 39 +// #define MY_PF_AVX2_INSTRUCTIONS_AVAILABLE 40 +// #define MY_PF_AVX512F_INSTRUCTIONS_AVAILABLE 41 +#endif + +BoolInt CPU_IsSupported_AVX(void) +{ #ifdef _WIN32 - #define MY__PF_XSAVE_ENABLED 17 - if (!IsProcessorFeaturePresent(MY__PF_XSAVE_ENABLED)) + if (!IsProcessorFeaturePresent(MY_PF_XSAVE_ENABLED)) return False; + /* PF_AVX_INSTRUCTIONS_AVAILABLE probably is supported starting from + some latest Win10 revisions. But we need AVX in older Windows also. + So we don't use the following check: */ + /* + if (!IsProcessorFeaturePresent(MY_PF_AVX_INSTRUCTIONS_AVAILABLE)) + return False; + */ #endif - if (!x86cpuid_CheckAndRead(&p)) + /* + OS must use new special XSAVE/XRSTOR instructions to save + AVX registers when it required for context switching. + At OS statring: + OS sets CR4.OSXSAVE flag to signal the processor that OS supports the XSAVE extensions. + Also OS sets bitmask in XCR0 register that defines what + registers will be processed by XSAVE instruction: + XCR0.SSE[bit 0] - x87 registers and state + XCR0.SSE[bit 1] - SSE registers and state + XCR0.AVX[bit 2] - AVX registers and state + CR4.OSXSAVE is reflected to CPUID.1:ECX.OSXSAVE[bit 27]. + So we can read that bit in user-space. + XCR0 is available for reading in user-space by new XGETBV instruction. + */ + { + const UInt32 c = x86cpuid_Func_1_ECX(); + if (0 == (1 + & (c >> 28) // AVX instructions are supported by hardware + & (c >> 27))) // OSXSAVE bit: XSAVE and related instructions are enabled by OS. + return False; + } + + /* also we can check + CPUID.1:ECX.XSAVE [bit 26] : that shows that + XSAVE, XRESTOR, XSETBV, XGETBV instructions are supported by hardware. + But that check is redundant, because if OSXSAVE bit is set, then XSAVE is also set */ + + /* If OS have enabled XSAVE extension instructions (OSXSAVE == 1), + in most cases we expect that OS also will support storing/restoring + for AVX and SSE states at least. + But to be ensure for that we call user-space instruction + XGETBV(0) to get XCR0 value that contains bitmask that defines + what exact states(registers) OS have enabled for storing/restoring. + */ + + { + const UInt32 bm = (UInt32)x86_xgetbv_0(MY_XCR_XFEATURE_ENABLED_MASK); + // printf("\n=== XGetBV=%d\n", bm); + return 1 + & (bm >> 1) // SSE state is supported (set by OS) for storing/restoring + & (bm >> 2); // AVX state is supported (set by OS) for storing/restoring + } + // since Win7SP1: we can use GetEnabledXStateFeatures(); +} + + +BoolInt CPU_IsSupported_AVX2(void) +{ + if (!CPU_IsSupported_AVX()) return False; - if (p.maxFunc < 7) + if (z7_x86_cpuid_GetMaxFunc() < 7) return False; { - UInt32 d[4] = { 0 }; - MyCPUID(7, &d[0], &d[1], &d[2], &d[3]); + UInt32 d[4]; + z7_x86_cpuid(d, 7); // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); return 1 & (d[1] >> 5); // avx2 } } -BoolInt CPU_IsSupported_VAES_AVX2() +BoolInt CPU_IsSupported_VAES_AVX2(void) { - Cx86cpuid p; - CHECK_SYS_SSE_SUPPORT - - #ifdef _WIN32 - #define MY__PF_XSAVE_ENABLED 17 - if (!IsProcessorFeaturePresent(MY__PF_XSAVE_ENABLED)) + if (!CPU_IsSupported_AVX()) return False; - #endif - - if (!x86cpuid_CheckAndRead(&p)) - return False; - if (p.maxFunc < 7) + if (z7_x86_cpuid_GetMaxFunc() < 7) return False; { - UInt32 d[4] = { 0 }; - MyCPUID(7, &d[0], &d[1], &d[2], &d[3]); + UInt32 d[4]; + z7_x86_cpuid(d, 7); // printf("\ncpuid(7): ebx=%8x ecx=%8x\n", d[1], d[2]); return 1 & (d[1] >> 5) // avx2 @@ -328,20 +679,15 @@ BoolInt CPU_IsSupported_VAES_AVX2() } } -BoolInt CPU_IsSupported_PageGB() +BoolInt CPU_IsSupported_PageGB(void) { - Cx86cpuid cpuid; - if (!x86cpuid_CheckAndRead(&cpuid)) - return False; + CHECK_CPUID_IS_SUPPORTED { - UInt32 d[4] = { 0 }; - MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]); + UInt32 d[4]; + z7_x86_cpuid(d, 0x80000000); if (d[0] < 0x80000001) return False; - } - { - UInt32 d[4] = { 0 }; - MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]); + z7_x86_cpuid(d, 0x80000001); return (d[3] >> 26) & 1; } } @@ -351,11 +697,11 @@ BoolInt CPU_IsSupported_PageGB() #ifdef _WIN32 -#include +#include "7zWindows.h" -BoolInt CPU_IsSupported_CRC32() { return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } -BoolInt CPU_IsSupported_CRYPTO() { return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } -BoolInt CPU_IsSupported_NEON() { return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } +BoolInt CPU_IsSupported_CRC32(void) { return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } +BoolInt CPU_IsSupported_CRYPTO(void) { return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } +BoolInt CPU_IsSupported_NEON(void) { return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) ? 1 : 0; } #else @@ -378,28 +724,27 @@ static void Print_sysctlbyname(const char *name) } } */ +/* + Print_sysctlbyname("hw.pagesize"); + Print_sysctlbyname("machdep.cpu.brand_string"); +*/ -static BoolInt My_sysctlbyname_Get_BoolInt(const char *name) +static BoolInt z7_sysctlbyname_Get_BoolInt(const char *name) { UInt32 val = 0; - if (My_sysctlbyname_Get_UInt32(name, &val) == 0 && val == 1) + if (z7_sysctlbyname_Get_UInt32(name, &val) == 0 && val == 1) return 1; return 0; } - /* - Print_sysctlbyname("hw.pagesize"); - Print_sysctlbyname("machdep.cpu.brand_string"); - */ - BoolInt CPU_IsSupported_CRC32(void) { - return My_sysctlbyname_Get_BoolInt("hw.optional.armv8_crc32"); + return z7_sysctlbyname_Get_BoolInt("hw.optional.armv8_crc32"); } BoolInt CPU_IsSupported_NEON(void) { - return My_sysctlbyname_Get_BoolInt("hw.optional.neon"); + return z7_sysctlbyname_Get_BoolInt("hw.optional.neon"); } #ifdef MY_CPU_ARM64 @@ -461,15 +806,15 @@ MY_HWCAP_CHECK_FUNC (AES) #include -int My_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize) +int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize) { return sysctlbyname(name, buf, bufSize, NULL, 0); } -int My_sysctlbyname_Get_UInt32(const char *name, UInt32 *val) +int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val) { size_t bufSize = sizeof(*val); - int res = My_sysctlbyname_Get(name, val, &bufSize); + const int res = z7_sysctlbyname_Get(name, val, &bufSize); if (res == 0 && bufSize != sizeof(*val)) return EFAULT; return res; diff --git a/libraries/lzma/C/CpuArch.h b/libraries/lzma/C/CpuArch.h index 529d3a502..8e5d8a543 100644 --- a/libraries/lzma/C/CpuArch.h +++ b/libraries/lzma/C/CpuArch.h @@ -1,8 +1,8 @@ /* CpuArch.h -- CPU specific code -2021-07-13 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __CPU_ARCH_H -#define __CPU_ARCH_H +#ifndef ZIP7_INC_CPU_ARCH_H +#define ZIP7_INC_CPU_ARCH_H #include "7zTypes.h" @@ -51,7 +51,13 @@ MY_CPU_64BIT means that processor can work with 64-bit registers. || defined(__AARCH64EB__) \ || defined(__aarch64__) #define MY_CPU_ARM64 - #define MY_CPU_NAME "arm64" + #ifdef __ILP32__ + #define MY_CPU_NAME "arm64-32" + #define MY_CPU_SIZEOF_POINTER 4 + #else + #define MY_CPU_NAME "arm64" + #define MY_CPU_SIZEOF_POINTER 8 + #endif #define MY_CPU_64BIT #endif @@ -68,8 +74,10 @@ MY_CPU_64BIT means that processor can work with 64-bit registers. #define MY_CPU_ARM #if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT) + #define MY_CPU_ARMT #define MY_CPU_NAME "armt" #else + #define MY_CPU_ARM32 #define MY_CPU_NAME "arm" #endif /* #define MY_CPU_32BIT */ @@ -103,6 +111,8 @@ MY_CPU_64BIT means that processor can work with 64-bit registers. || defined(__PPC__) \ || defined(_POWER) +#define MY_CPU_PPC_OR_PPC64 + #if defined(__ppc64__) \ || defined(__powerpc64__) \ || defined(_LP64) \ @@ -123,12 +133,15 @@ MY_CPU_64BIT means that processor can work with 64-bit registers. #endif -#if defined(__sparc64__) - #define MY_CPU_NAME "sparc64" - #define MY_CPU_64BIT -#elif defined(__sparc__) - #define MY_CPU_NAME "sparc" - /* #define MY_CPU_32BIT */ +#if defined(__riscv) \ + || defined(__riscv__) + #if __riscv_xlen == 32 + #define MY_CPU_NAME "riscv32" + #elif __riscv_xlen == 64 + #define MY_CPU_NAME "riscv64" + #else + #define MY_CPU_NAME "riscv" + #endif #endif @@ -194,6 +207,9 @@ MY_CPU_64BIT means that processor can work with 64-bit registers. #error Stop_Compiling_Bad_Endian #endif +#if !defined(MY_CPU_LE) && !defined(MY_CPU_BE) + #error Stop_Compiling_CPU_ENDIAN_must_be_detected_at_compile_time +#endif #if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT) #error Stop_Compiling_Bad_32_64_BIT @@ -250,6 +266,67 @@ MY_CPU_64BIT means that processor can work with 64-bit registers. +#ifdef __has_builtin + #define Z7_has_builtin(x) __has_builtin(x) +#else + #define Z7_has_builtin(x) 0 +#endif + + +#define Z7_BSWAP32_CONST(v) \ + ( (((UInt32)(v) << 24) ) \ + | (((UInt32)(v) << 8) & (UInt32)0xff0000) \ + | (((UInt32)(v) >> 8) & (UInt32)0xff00 ) \ + | (((UInt32)(v) >> 24) )) + + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) + +#include + +/* Note: these macros will use bswap instruction (486), that is unsupported in 386 cpu */ + +#pragma intrinsic(_byteswap_ushort) +#pragma intrinsic(_byteswap_ulong) +#pragma intrinsic(_byteswap_uint64) + +#define Z7_BSWAP16(v) _byteswap_ushort(v) +#define Z7_BSWAP32(v) _byteswap_ulong (v) +#define Z7_BSWAP64(v) _byteswap_uint64(v) +#define Z7_CPU_FAST_BSWAP_SUPPORTED + +#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \ + || (defined(__clang__) && Z7_has_builtin(__builtin_bswap16)) + +#define Z7_BSWAP16(v) __builtin_bswap16(v) +#define Z7_BSWAP32(v) __builtin_bswap32(v) +#define Z7_BSWAP64(v) __builtin_bswap64(v) +#define Z7_CPU_FAST_BSWAP_SUPPORTED + +#else + +#define Z7_BSWAP16(v) ((UInt16) \ + ( ((UInt32)(v) << 8) \ + | ((UInt32)(v) >> 8) \ + )) + +#define Z7_BSWAP32(v) Z7_BSWAP32_CONST(v) + +#define Z7_BSWAP64(v) \ + ( ( ( (UInt64)(v) ) << 8 * 7 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 1) ) << 8 * 5 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 2) ) << 8 * 3 ) \ + | ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 3) ) << 8 * 1 ) \ + | ( ( (UInt64)(v) >> 8 * 1 ) & ((UInt32)0xff << 8 * 3) ) \ + | ( ( (UInt64)(v) >> 8 * 3 ) & ((UInt32)0xff << 8 * 2) ) \ + | ( ( (UInt64)(v) >> 8 * 5 ) & ((UInt32)0xff << 8 * 1) ) \ + | ( ( (UInt64)(v) >> 8 * 7 ) ) \ + ) + +#endif + + + #ifdef MY_CPU_LE #if defined(MY_CPU_X86_OR_AMD64) \ || defined(MY_CPU_ARM64) @@ -269,13 +346,11 @@ MY_CPU_64BIT means that processor can work with 64-bit registers. #define GetUi32(p) (*(const UInt32 *)(const void *)(p)) #ifdef MY_CPU_LE_UNALIGN_64 #define GetUi64(p) (*(const UInt64 *)(const void *)(p)) +#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); } #endif #define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); } #define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); } -#ifdef MY_CPU_LE_UNALIGN_64 -#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); } -#endif #else @@ -302,51 +377,26 @@ MY_CPU_64BIT means that processor can work with 64-bit registers. #endif -#ifndef MY_CPU_LE_UNALIGN_64 - +#ifndef GetUi64 #define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32)) +#endif +#ifndef SetUi64 #define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \ - SetUi32(_ppp2_ , (UInt32)_vvv2_); \ - SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); } - + SetUi32(_ppp2_ , (UInt32)_vvv2_) \ + SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)) } #endif +#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED) +#define GetBe32(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p)) +#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); } -#ifdef __has_builtin - #define MY__has_builtin(x) __has_builtin(x) -#else - #define MY__has_builtin(x) 0 +#if defined(MY_CPU_LE_UNALIGN_64) +#define GetBe64(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p)) #endif -#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ defined(_MSC_VER) && (_MSC_VER >= 1300) - -/* Note: we use bswap instruction, that is unsupported in 386 cpu */ - -#include - -#pragma intrinsic(_byteswap_ushort) -#pragma intrinsic(_byteswap_ulong) -#pragma intrinsic(_byteswap_uint64) - -/* #define GetBe16(p) _byteswap_ushort(*(const UInt16 *)(const Byte *)(p)) */ -#define GetBe32(p) _byteswap_ulong (*(const UInt32 *)(const void *)(p)) -#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const void *)(p)) - -#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v) - -#elif defined(MY_CPU_LE_UNALIGN) && ( \ - (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \ - || (defined(__clang__) && MY__has_builtin(__builtin_bswap16)) ) - -/* #define GetBe16(p) __builtin_bswap16(*(const UInt16 *)(const void *)(p)) */ -#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const void *)(p)) -#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const void *)(p)) - -#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v) - #else #define GetBe32(p) ( \ @@ -355,8 +405,6 @@ MY_CPU_64BIT means that processor can work with 64-bit registers. ((UInt32)((const Byte *)(p))[2] << 8) | \ ((const Byte *)(p))[3] ) -#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) - #define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \ _ppp_[0] = (Byte)(_vvv_ >> 24); \ _ppp_[1] = (Byte)(_vvv_ >> 16); \ @@ -365,50 +413,83 @@ MY_CPU_64BIT means that processor can work with 64-bit registers. #endif +#ifndef GetBe64 +#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4)) +#endif #ifndef GetBe16 - #define GetBe16(p) ( (UInt16) ( \ ((UInt16)((const Byte *)(p))[0] << 8) | \ ((const Byte *)(p))[1] )) - #endif +#if defined(MY_CPU_BE) +#define Z7_CONV_BE_TO_NATIVE_CONST32(v) (v) +#define Z7_CONV_LE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v) +#define Z7_CONV_NATIVE_TO_BE_32(v) (v) +#elif defined(MY_CPU_LE) +#define Z7_CONV_BE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v) +#define Z7_CONV_LE_TO_NATIVE_CONST32(v) (v) +#define Z7_CONV_NATIVE_TO_BE_32(v) Z7_BSWAP32(v) +#else +#error Stop_Compiling_Unknown_Endian_CONV +#endif + + +#if defined(MY_CPU_BE) + +#define GetBe32a(p) (*(const UInt32 *)(const void *)(p)) +#define GetBe16a(p) (*(const UInt16 *)(const void *)(p)) +#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); } +#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); } + +#define GetUi32a(p) GetUi32(p) +#define GetUi16a(p) GetUi16(p) +#define SetUi32a(p, v) SetUi32(p, v) +#define SetUi16a(p, v) SetUi16(p, v) + +#elif defined(MY_CPU_LE) + +#define GetUi32a(p) (*(const UInt32 *)(const void *)(p)) +#define GetUi16a(p) (*(const UInt16 *)(const void *)(p)) +#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); } +#define SetUi16a(p, v) { *(UInt16 *)(void *)(p) = (v); } + +#define GetBe32a(p) GetBe32(p) +#define GetBe16a(p) GetBe16(p) +#define SetBe32a(p, v) SetBe32(p, v) +#define SetBe16a(p, v) SetBe16(p, v) + +#else +#error Stop_Compiling_Unknown_Endian_CPU_a +#endif + + +#if defined(MY_CPU_X86_OR_AMD64) \ + || defined(MY_CPU_ARM_OR_ARM64) \ + || defined(MY_CPU_PPC_OR_PPC64) + #define Z7_CPU_FAST_ROTATE_SUPPORTED +#endif + #ifdef MY_CPU_X86_OR_AMD64 -typedef struct -{ - UInt32 maxFunc; - UInt32 vendor[3]; - UInt32 ver; - UInt32 b; - UInt32 c; - UInt32 d; -} Cx86cpuid; - -enum -{ - CPU_FIRM_INTEL, - CPU_FIRM_AMD, - CPU_FIRM_VIA -}; - -void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d); - -BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p); -int x86cpuid_GetFirm(const Cx86cpuid *p); - -#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF)) -#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF)) -#define x86cpuid_GetStepping(ver) (ver & 0xF) - -BoolInt CPU_Is_InOrder(void); +void Z7_FASTCALL z7_x86_cpuid(UInt32 a[4], UInt32 function); +UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void); +#if defined(MY_CPU_AMD64) +#define Z7_IF_X86_CPUID_SUPPORTED +#else +#define Z7_IF_X86_CPUID_SUPPORTED if (z7_x86_cpuid_GetMaxFunc()) +#endif BoolInt CPU_IsSupported_AES(void); +BoolInt CPU_IsSupported_AVX(void); BoolInt CPU_IsSupported_AVX2(void); BoolInt CPU_IsSupported_VAES_AVX2(void); +BoolInt CPU_IsSupported_CMOV(void); +BoolInt CPU_IsSupported_SSE(void); +BoolInt CPU_IsSupported_SSE2(void); BoolInt CPU_IsSupported_SSSE3(void); BoolInt CPU_IsSupported_SSE41(void); BoolInt CPU_IsSupported_SHA(void); @@ -433,8 +514,8 @@ BoolInt CPU_IsSupported_AES(void); #endif #if defined(__APPLE__) -int My_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize); -int My_sysctlbyname_Get_UInt32(const char *name, UInt32 *val); +int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize); +int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val); #endif EXTERN_C_END diff --git a/libraries/lzma/C/Delta.h b/libraries/lzma/C/Delta.h index 2fa54ad67..706095417 100644 --- a/libraries/lzma/C/Delta.h +++ b/libraries/lzma/C/Delta.h @@ -1,8 +1,8 @@ /* Delta.h -- Delta converter -2013-01-18 : Igor Pavlov : Public domain */ +2023-03-03 : Igor Pavlov : Public domain */ -#ifndef __DELTA_H -#define __DELTA_H +#ifndef ZIP7_INC_DELTA_H +#define ZIP7_INC_DELTA_H #include "7zTypes.h" diff --git a/libraries/lzma/C/DllSecur.c b/libraries/lzma/C/DllSecur.c new file mode 100644 index 000000000..02a0f977e --- /dev/null +++ b/libraries/lzma/C/DllSecur.c @@ -0,0 +1,111 @@ +/* DllSecur.c -- DLL loading security +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#ifdef _WIN32 + +#include "7zWindows.h" + +#include "DllSecur.h" + +#ifndef UNDER_CE + +#if (defined(__GNUC__) && (__GNUC__ >= 8)) || defined(__clang__) + // #pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + +#if defined(__clang__) || defined(__GNUC__) +typedef void (*Z7_voidFunction)(void); +#define MY_CAST_FUNC (Z7_voidFunction) +#elif defined(_MSC_VER) && _MSC_VER > 1920 +#define MY_CAST_FUNC (void *) +// #pragma warning(disable : 4191) // 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)()' +#else +#define MY_CAST_FUNC +#endif + +typedef BOOL (WINAPI *Func_SetDefaultDllDirectories)(DWORD DirectoryFlags); + +#define MY_LOAD_LIBRARY_SEARCH_USER_DIRS 0x400 +#define MY_LOAD_LIBRARY_SEARCH_SYSTEM32 0x800 + +#define DELIM "\0" + +static const char * const g_Dlls = + "userenv" + DELIM "setupapi" + DELIM "apphelp" + DELIM "propsys" + DELIM "dwmapi" + DELIM "cryptbase" + DELIM "oleacc" + DELIM "clbcatq" + DELIM "version" + #ifndef _CONSOLE + DELIM "uxtheme" + #endif + DELIM; + +#endif + +#ifdef __clang__ + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif +#if defined (_MSC_VER) && _MSC_VER >= 1900 +// sysinfoapi.h: kit10: GetVersion was declared deprecated +#pragma warning(disable : 4996) +#endif + +#define IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN \ + if ((UInt16)GetVersion() != 6) { \ + const \ + Func_SetDefaultDllDirectories setDllDirs = \ + (Func_SetDefaultDllDirectories) MY_CAST_FUNC GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), \ + "SetDefaultDllDirectories"); \ + if (setDllDirs) if (setDllDirs(MY_LOAD_LIBRARY_SEARCH_SYSTEM32 | MY_LOAD_LIBRARY_SEARCH_USER_DIRS)) return; } + +void My_SetDefaultDllDirectories(void) +{ + #ifndef UNDER_CE + IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN + #endif +} + + +void LoadSecurityDlls(void) +{ + #ifndef UNDER_CE + // at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ??? + IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN + { + wchar_t buf[MAX_PATH + 100]; + const char *dll; + unsigned pos = GetSystemDirectoryW(buf, MAX_PATH + 2); + if (pos == 0 || pos > MAX_PATH) + return; + if (buf[pos - 1] != '\\') + buf[pos++] = '\\'; + for (dll = g_Dlls; *dll != 0;) + { + wchar_t *dest = &buf[pos]; + for (;;) + { + const char c = *dll++; + if (c == 0) + break; + *dest++ = (Byte)c; + } + dest[0] = '.'; + dest[1] = 'd'; + dest[2] = 'l'; + dest[3] = 'l'; + dest[4] = 0; + // lstrcatW(buf, L".dll"); + LoadLibraryExW(buf, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + } + } + #endif +} + +#endif // _WIN32 diff --git a/libraries/lzma/C/DllSecur.h b/libraries/lzma/C/DllSecur.h new file mode 100644 index 000000000..9fa415382 --- /dev/null +++ b/libraries/lzma/C/DllSecur.h @@ -0,0 +1,20 @@ +/* DllSecur.h -- DLL loading for security +2023-03-03 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_DLL_SECUR_H +#define ZIP7_INC_DLL_SECUR_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#ifdef _WIN32 + +void My_SetDefaultDllDirectories(void); +void LoadSecurityDlls(void); + +#endif + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/LzFind.c b/libraries/lzma/C/LzFind.c index 1b73c2848..0fbd5aae5 100644 --- a/libraries/lzma/C/LzFind.c +++ b/libraries/lzma/C/LzFind.c @@ -1,5 +1,5 @@ /* LzFind.c -- Match finder for LZ algorithms -2021-11-29 : Igor Pavlov : Public domain */ +2023-03-14 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -17,7 +17,7 @@ #define kEmptyHashValue 0 #define kMaxValForNormalize ((UInt32)0) -// #define kMaxValForNormalize ((UInt32)(1 << 20) + 0xFFF) // for debug +// #define kMaxValForNormalize ((UInt32)(1 << 20) + 0xfff) // for debug // #define kNormalizeAlign (1 << 7) // alignment for speculated accesses @@ -67,10 +67,10 @@ static void LzInWindow_Free(CMatchFinder *p, ISzAllocPtr alloc) { - if (!p->directInput) + // if (!p->directInput) { - ISzAlloc_Free(alloc, p->bufferBase); - p->bufferBase = NULL; + ISzAlloc_Free(alloc, p->bufBase); + p->bufBase = NULL; } } @@ -79,7 +79,7 @@ static int LzInWindow_Create2(CMatchFinder *p, UInt32 blockSize, ISzAllocPtr all { if (blockSize == 0) return 0; - if (!p->bufferBase || p->blockSize != blockSize) + if (!p->bufBase || p->blockSize != blockSize) { // size_t blockSizeT; LzInWindow_Free(p, alloc); @@ -101,11 +101,11 @@ static int LzInWindow_Create2(CMatchFinder *p, UInt32 blockSize, ISzAllocPtr all #endif */ - p->bufferBase = (Byte *)ISzAlloc_Alloc(alloc, blockSize); - // printf("\nbufferBase = %p\n", p->bufferBase); + p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, blockSize); + // printf("\nbufferBase = %p\n", p->bufBase); // return 0; // for debug } - return (p->bufferBase != NULL); + return (p->bufBase != NULL); } static const Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } @@ -113,7 +113,7 @@ static const Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return GET_AVAIL_BYTES(p); } -MY_NO_INLINE +Z7_NO_INLINE static void MatchFinder_ReadBlock(CMatchFinder *p) { if (p->streamEndWasReached || p->result != SZ_OK) @@ -127,8 +127,8 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) UInt32 curSize = 0xFFFFFFFF - GET_AVAIL_BYTES(p); if (curSize > p->directInputRem) curSize = (UInt32)p->directInputRem; - p->directInputRem -= curSize; p->streamPos += curSize; + p->directInputRem -= curSize; if (p->directInputRem == 0) p->streamEndWasReached = 1; return; @@ -136,8 +136,8 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) for (;;) { - Byte *dest = p->buffer + GET_AVAIL_BYTES(p); - size_t size = (size_t)(p->bufferBase + p->blockSize - dest); + const Byte *dest = p->buffer + GET_AVAIL_BYTES(p); + size_t size = (size_t)(p->bufBase + p->blockSize - dest); if (size == 0) { /* we call ReadBlock() after NeedMove() and MoveBlock(). @@ -153,7 +153,14 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) // #define kRead 3 // if (size > kRead) size = kRead; // for debug - p->result = ISeqInStream_Read(p->stream, dest, &size); + /* + // we need cast (Byte *)dest. + #ifdef __clang__ + #pragma GCC diagnostic ignored "-Wcast-qual" + #endif + */ + p->result = ISeqInStream_Read(p->stream, + p->bufBase + (dest - p->bufBase), &size); if (p->result != SZ_OK) return; if (size == 0) @@ -173,14 +180,14 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) -MY_NO_INLINE +Z7_NO_INLINE void MatchFinder_MoveBlock(CMatchFinder *p) { - const size_t offset = (size_t)(p->buffer - p->bufferBase) - p->keepSizeBefore; + const size_t offset = (size_t)(p->buffer - p->bufBase) - p->keepSizeBefore; const size_t keepBefore = (offset & (kBlockMoveAlign - 1)) + p->keepSizeBefore; - p->buffer = p->bufferBase + keepBefore; - memmove(p->bufferBase, - p->bufferBase + (offset & ~((size_t)kBlockMoveAlign - 1)), + p->buffer = p->bufBase + keepBefore; + memmove(p->bufBase, + p->bufBase + (offset & ~((size_t)kBlockMoveAlign - 1)), keepBefore + (size_t)GET_AVAIL_BYTES(p)); } @@ -198,7 +205,7 @@ int MatchFinder_NeedMove(CMatchFinder *p) return 0; if (p->streamEndWasReached || p->result != SZ_OK) return 0; - return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); + return ((size_t)(p->bufBase + p->blockSize - p->buffer) <= p->keepSizeAfter); } void MatchFinder_ReadIfRequired(CMatchFinder *p) @@ -214,6 +221,8 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p) p->cutValue = 32; p->btMode = 1; p->numHashBytes = 4; + p->numHashBytes_Min = 2; + p->numHashOutBits = 0; p->bigHash = 0; } @@ -222,8 +231,10 @@ static void MatchFinder_SetDefaultSettings(CMatchFinder *p) void MatchFinder_Construct(CMatchFinder *p) { unsigned i; - p->bufferBase = NULL; + p->buffer = NULL; + p->bufBase = NULL; p->directInput = 0; + p->stream = NULL; p->hash = NULL; p->expectedDataSize = (UInt64)(Int64)-1; MatchFinder_SetDefaultSettings(p); @@ -238,6 +249,8 @@ void MatchFinder_Construct(CMatchFinder *p) } } +#undef kCrcPoly + static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAllocPtr alloc) { ISzAlloc_Free(alloc, p->hash); @@ -252,7 +265,7 @@ void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc) static CLzRef* AllocRefs(size_t num, ISzAllocPtr alloc) { - size_t sizeInBytes = (size_t)num * sizeof(CLzRef); + const size_t sizeInBytes = (size_t)num * sizeof(CLzRef); if (sizeInBytes / sizeof(CLzRef) != num) return NULL; return (CLzRef *)ISzAlloc_Alloc(alloc, sizeInBytes); @@ -298,6 +311,62 @@ static UInt32 GetBlockSize(CMatchFinder *p, UInt32 historySize) } +// input is historySize +static UInt32 MatchFinder_GetHashMask2(CMatchFinder *p, UInt32 hs) +{ + if (p->numHashBytes == 2) + return (1 << 16) - 1; + if (hs != 0) + hs--; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + // we propagated 16 bits in (hs). Low 16 bits must be set later + if (hs >= (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ + } + // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) + hs |= (1 << 16) - 1; /* don't change it! */ + // bt5: we adjust the size with recommended minimum size + if (p->numHashBytes >= 5) + hs |= (256 << kLzHash_CrcShift_2) - 1; + return hs; +} + +// input is historySize +static UInt32 MatchFinder_GetHashMask(CMatchFinder *p, UInt32 hs) +{ + if (p->numHashBytes == 2) + return (1 << 16) - 1; + if (hs != 0) + hs--; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + // we propagated 16 bits in (hs). Low 16 bits must be set later + hs >>= 1; + if (hs >= (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + else + hs >>= 1; + /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ + } + // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) + hs |= (1 << 16) - 1; /* don't change it! */ + // bt5: we adjust the size with recommended minimum size + if (p->numHashBytes >= 5) + hs |= (256 << kLzHash_CrcShift_2) - 1; + return hs; +} + + int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc) @@ -318,78 +387,91 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, p->blockSize = 0; if (p->directInput || LzInWindow_Create2(p, GetBlockSize(p, historySize), alloc)) { - const UInt32 newCyclicBufferSize = historySize + 1; // do not change it - UInt32 hs; - p->matchMaxLen = matchMaxLen; + size_t hashSizeSum; { - // UInt32 hs4; - p->fixedHashSize = 0; - hs = (1 << 16) - 1; - if (p->numHashBytes != 2) + UInt32 hs; + UInt32 hsCur; + + if (p->numHashOutBits != 0) { - hs = historySize; - if (hs > p->expectedDataSize) - hs = (UInt32)p->expectedDataSize; - if (hs != 0) - hs--; - hs |= (hs >> 1); - hs |= (hs >> 2); - hs |= (hs >> 4); - hs |= (hs >> 8); - // we propagated 16 bits in (hs). Low 16 bits must be set later - hs >>= 1; - if (hs >= (1 << 24)) - { - if (p->numHashBytes == 3) - hs = (1 << 24) - 1; - else - hs >>= 1; - /* if (bigHash) mode, GetHeads4b() in LzFindMt.c needs (hs >= ((1 << 24) - 1))) */ - } - - // hs = ((UInt32)1 << 25) - 1; // for test - + unsigned numBits = p->numHashOutBits; + const unsigned nbMax = + (p->numHashBytes == 2 ? 16 : + (p->numHashBytes == 3 ? 24 : 32)); + if (numBits > nbMax) + numBits = nbMax; + if (numBits >= 32) + hs = (UInt32)0 - 1; + else + hs = ((UInt32)1 << numBits) - 1; // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2) hs |= (1 << 16) - 1; /* don't change it! */ - - // bt5: we adjust the size with recommended minimum size if (p->numHashBytes >= 5) hs |= (256 << kLzHash_CrcShift_2) - 1; + { + const UInt32 hs2 = MatchFinder_GetHashMask2(p, historySize); + if (hs > hs2) + hs = hs2; + } + hsCur = hs; + if (p->expectedDataSize < historySize) + { + const UInt32 hs2 = MatchFinder_GetHashMask2(p, (UInt32)p->expectedDataSize); + if (hsCur > hs2) + hsCur = hs2; + } + } + else + { + hs = MatchFinder_GetHashMask(p, historySize); + hsCur = hs; + if (p->expectedDataSize < historySize) + { + hsCur = MatchFinder_GetHashMask(p, (UInt32)p->expectedDataSize); + if (hsCur > hs) // is it possible? + hsCur = hs; + } } - p->hashMask = hs; - hs++; - /* - hs4 = (1 << 20); - if (hs4 > hs) - hs4 = hs; - // hs4 = (1 << 16); // for test - p->hash4Mask = hs4 - 1; - */ + p->hashMask = hsCur; - if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; - if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; - // if (p->numHashBytes > 4) p->fixedHashSize += hs4; // kHash4Size; - hs += p->fixedHashSize; + hashSizeSum = hs; + hashSizeSum++; + if (hashSizeSum < hs) + return 0; + { + UInt32 fixedHashSize = 0; + if (p->numHashBytes > 2 && p->numHashBytes_Min <= 2) fixedHashSize += kHash2Size; + if (p->numHashBytes > 3 && p->numHashBytes_Min <= 3) fixedHashSize += kHash3Size; + // if (p->numHashBytes > 4) p->fixedHashSize += hs4; // kHash4Size; + hashSizeSum += fixedHashSize; + p->fixedHashSize = fixedHashSize; + } } + p->matchMaxLen = matchMaxLen; + { size_t newSize; size_t numSons; + const UInt32 newCyclicBufferSize = historySize + 1; // do not change it p->historySize = historySize; - p->hashSizeSum = hs; p->cyclicBufferSize = newCyclicBufferSize; // it must be = (historySize + 1) numSons = newCyclicBufferSize; if (p->btMode) numSons <<= 1; - newSize = hs + numSons; + newSize = hashSizeSum + numSons; + + if (numSons < newCyclicBufferSize || newSize < numSons) + return 0; // aligned size is not required here, but it can be better for some loops #define NUM_REFS_ALIGN_MASK 0xF newSize = (newSize + NUM_REFS_ALIGN_MASK) & ~(size_t)NUM_REFS_ALIGN_MASK; - if (p->hash && p->numRefs == newSize) + // 22.02: we don't reallocate buffer, if old size is enough + if (p->hash && p->numRefs >= newSize) return 1; MatchFinder_FreeThisClassMemory(p, alloc); @@ -398,7 +480,7 @@ int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, if (p->hash) { - p->son = p->hash + p->hashSizeSum; + p->son = p->hash + hashSizeSum; return 1; } } @@ -470,7 +552,8 @@ void MatchFinder_Init_HighHash(CMatchFinder *p) void MatchFinder_Init_4(CMatchFinder *p) { - p->buffer = p->bufferBase; + if (!p->directInput) + p->buffer = p->bufBase; { /* kEmptyHashValue = 0 (Zero) is used in hash tables as NO-VALUE marker. the code in CMatchFinderMt expects (pos = 1) */ @@ -507,20 +590,20 @@ void MatchFinder_Init(CMatchFinder *p) #ifdef MY_CPU_X86_OR_AMD64 - #if defined(__clang__) && (__clang_major__ >= 8) \ - || defined(__GNUC__) && (__GNUC__ >= 8) \ - || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1900) - #define USE_SATUR_SUB_128 - #define USE_AVX2 - #define ATTRIB_SSE41 __attribute__((__target__("sse4.1"))) - #define ATTRIB_AVX2 __attribute__((__target__("avx2"))) + #if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40701) + // || defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1900) + + #define USE_LZFIND_SATUR_SUB_128 + #define USE_LZFIND_SATUR_SUB_256 + #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("sse4.1"))) + #define LZFIND_ATTRIB_AVX2 __attribute__((__target__("avx2"))) #elif defined(_MSC_VER) #if (_MSC_VER >= 1600) - #define USE_SATUR_SUB_128 - #if (_MSC_VER >= 1900) - #define USE_AVX2 - #include // avx - #endif + #define USE_LZFIND_SATUR_SUB_128 + #endif + #if (_MSC_VER >= 1900) + #define USE_LZFIND_SATUR_SUB_256 #endif #endif @@ -529,16 +612,16 @@ void MatchFinder_Init(CMatchFinder *p) #if defined(__clang__) && (__clang_major__ >= 8) \ || defined(__GNUC__) && (__GNUC__ >= 8) - #define USE_SATUR_SUB_128 + #define USE_LZFIND_SATUR_SUB_128 #ifdef MY_CPU_ARM64 - // #define ATTRIB_SSE41 __attribute__((__target__(""))) + // #define LZFIND_ATTRIB_SSE41 __attribute__((__target__(""))) #else - // #define ATTRIB_SSE41 __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) + // #define LZFIND_ATTRIB_SSE41 __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) #endif #elif defined(_MSC_VER) #if (_MSC_VER >= 1910) - #define USE_SATUR_SUB_128 + #define USE_LZFIND_SATUR_SUB_128 #endif #endif @@ -550,121 +633,130 @@ void MatchFinder_Init(CMatchFinder *p) #endif -/* -#ifndef ATTRIB_SSE41 - #define ATTRIB_SSE41 -#endif -#ifndef ATTRIB_AVX2 - #define ATTRIB_AVX2 -#endif -*/ -#ifdef USE_SATUR_SUB_128 +#ifdef USE_LZFIND_SATUR_SUB_128 -// #define _SHOW_HW_STATUS +// #define Z7_SHOW_HW_STATUS -#ifdef _SHOW_HW_STATUS +#ifdef Z7_SHOW_HW_STATUS #include -#define _PRF(x) x -_PRF(;) +#define PRF(x) x +PRF(;) #else -#define _PRF(x) +#define PRF(x) #endif + #ifdef MY_CPU_ARM_OR_ARM64 #ifdef MY_CPU_ARM64 -// #define FORCE_SATUR_SUB_128 +// #define FORCE_LZFIND_SATUR_SUB_128 #endif +typedef uint32x4_t LzFind_v128; +#define SASUB_128_V(v, s) \ + vsubq_u32(vmaxq_u32(v, s), s) -typedef uint32x4_t v128; -#define SASUB_128(i) \ - *(v128 *)(void *)(items + (i) * 4) = \ - vsubq_u32(vmaxq_u32(*(const v128 *)(const void *)(items + (i) * 4), sub2), sub2); - -#else +#else // MY_CPU_ARM_OR_ARM64 #include // sse4.1 -typedef __m128i v128; +typedef __m128i LzFind_v128; +// SSE 4.1 +#define SASUB_128_V(v, s) \ + _mm_sub_epi32(_mm_max_epu32(v, s), s) + +#endif // MY_CPU_ARM_OR_ARM64 + + #define SASUB_128(i) \ - *(v128 *)(void *)(items + (i) * 4) = \ - _mm_sub_epi32(_mm_max_epu32(*(const v128 *)(const void *)(items + (i) * 4), sub2), sub2); // SSE 4.1 - -#endif + *( LzFind_v128 *)( void *)(items + (i) * 4) = SASUB_128_V( \ + *(const LzFind_v128 *)(const void *)(items + (i) * 4), sub2); - -MY_NO_INLINE +Z7_NO_INLINE static -#ifdef ATTRIB_SSE41 -ATTRIB_SSE41 +#ifdef LZFIND_ATTRIB_SSE41 +LZFIND_ATTRIB_SSE41 #endif void -MY_FAST_CALL +Z7_FASTCALL LzFind_SaturSub_128(UInt32 subValue, CLzRef *items, const CLzRef *lim) { - v128 sub2 = + const LzFind_v128 sub2 = #ifdef MY_CPU_ARM_OR_ARM64 vdupq_n_u32(subValue); #else _mm_set_epi32((Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue); #endif + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE do { - SASUB_128(0) - SASUB_128(1) - SASUB_128(2) - SASUB_128(3) - items += 4 * 4; + SASUB_128(0) SASUB_128(1) items += 2 * 4; + SASUB_128(0) SASUB_128(1) items += 2 * 4; } while (items != lim); } -#ifdef USE_AVX2 +#ifdef USE_LZFIND_SATUR_SUB_256 #include // avx +/* +clang :immintrin.h uses +#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \ + defined(__AVX2__) +#include +#endif +so we need for clang-cl */ -#define SASUB_256(i) *(__m256i *)(void *)(items + (i) * 8) = _mm256_sub_epi32(_mm256_max_epu32(*(const __m256i *)(const void *)(items + (i) * 8), sub2), sub2); // AVX2 +#if defined(__clang__) +#include +#include +#endif -MY_NO_INLINE +// AVX2: +#define SASUB_256(i) \ + *( __m256i *)( void *)(items + (i) * 8) = \ + _mm256_sub_epi32(_mm256_max_epu32( \ + *(const __m256i *)(const void *)(items + (i) * 8), sub2), sub2); + +Z7_NO_INLINE static -#ifdef ATTRIB_AVX2 -ATTRIB_AVX2 +#ifdef LZFIND_ATTRIB_AVX2 +LZFIND_ATTRIB_AVX2 #endif void -MY_FAST_CALL +Z7_FASTCALL LzFind_SaturSub_256(UInt32 subValue, CLzRef *items, const CLzRef *lim) { - __m256i sub2 = _mm256_set_epi32( + const __m256i sub2 = _mm256_set_epi32( (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue, (Int32)subValue); + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE do { - SASUB_256(0) - SASUB_256(1) - items += 2 * 8; + SASUB_256(0) SASUB_256(1) items += 2 * 8; + SASUB_256(0) SASUB_256(1) items += 2 * 8; } while (items != lim); } -#endif // USE_AVX2 +#endif // USE_LZFIND_SATUR_SUB_256 -#ifndef FORCE_SATUR_SUB_128 -typedef void (MY_FAST_CALL *LZFIND_SATUR_SUB_CODE_FUNC)( +#ifndef FORCE_LZFIND_SATUR_SUB_128 +typedef void (Z7_FASTCALL *LZFIND_SATUR_SUB_CODE_FUNC)( UInt32 subValue, CLzRef *items, const CLzRef *lim); static LZFIND_SATUR_SUB_CODE_FUNC g_LzFind_SaturSub; -#endif // FORCE_SATUR_SUB_128 +#endif // FORCE_LZFIND_SATUR_SUB_128 -#endif // USE_SATUR_SUB_128 +#endif // USE_LZFIND_SATUR_SUB_128 // kEmptyHashValue must be zero -// #define SASUB_32(i) v = items[i]; m = v - subValue; if (v < subValue) m = kEmptyHashValue; items[i] = m; -#define SASUB_32(i) v = items[i]; if (v < subValue) v = subValue; items[i] = v - subValue; +// #define SASUB_32(i) { UInt32 v = items[i]; UInt32 m = v - subValue; if (v < subValue) m = kEmptyHashValue; items[i] = m; } +#define SASUB_32(i) { UInt32 v = items[i]; if (v < subValue) v = subValue; items[i] = v - subValue; } -#ifdef FORCE_SATUR_SUB_128 +#ifdef FORCE_LZFIND_SATUR_SUB_128 #define DEFAULT_SaturSub LzFind_SaturSub_128 @@ -672,24 +764,19 @@ static LZFIND_SATUR_SUB_CODE_FUNC g_LzFind_SaturSub; #define DEFAULT_SaturSub LzFind_SaturSub_32 -MY_NO_INLINE +Z7_NO_INLINE static void -MY_FAST_CALL +Z7_FASTCALL LzFind_SaturSub_32(UInt32 subValue, CLzRef *items, const CLzRef *lim) { + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE do { - UInt32 v; - SASUB_32(0) - SASUB_32(1) - SASUB_32(2) - SASUB_32(3) - SASUB_32(4) - SASUB_32(5) - SASUB_32(6) - SASUB_32(7) - items += 8; + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; + SASUB_32(0) SASUB_32(1) items += 2; } while (items != lim); } @@ -697,27 +784,23 @@ LzFind_SaturSub_32(UInt32 subValue, CLzRef *items, const CLzRef *lim) #endif -MY_NO_INLINE +Z7_NO_INLINE void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems) { - #define K_NORM_ALIGN_BLOCK_SIZE (1 << 6) - - CLzRef *lim; - - for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (K_NORM_ALIGN_BLOCK_SIZE - 1)) != 0; numItems--) + #define LZFIND_NORM_ALIGN_BLOCK_SIZE (1 << 7) + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (LZFIND_NORM_ALIGN_BLOCK_SIZE - 1)) != 0; numItems--) { - UInt32 v; - SASUB_32(0); + SASUB_32(0) items++; } - { - #define K_NORM_ALIGN_MASK (K_NORM_ALIGN_BLOCK_SIZE / 4 - 1) - lim = items + (numItems & ~(size_t)K_NORM_ALIGN_MASK); - numItems &= K_NORM_ALIGN_MASK; + const size_t k_Align_Mask = (LZFIND_NORM_ALIGN_BLOCK_SIZE / 4 - 1); + CLzRef *lim = items + (numItems & ~(size_t)k_Align_Mask); + numItems &= k_Align_Mask; if (items != lim) { - #if defined(USE_SATUR_SUB_128) && !defined(FORCE_SATUR_SUB_128) + #if defined(USE_LZFIND_SATUR_SUB_128) && !defined(FORCE_LZFIND_SATUR_SUB_128) if (g_LzFind_SaturSub) g_LzFind_SaturSub(subValue, items, lim); else @@ -726,12 +809,10 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems) } items = lim; } - - + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE for (; numItems != 0; numItems--) { - UInt32 v; - SASUB_32(0); + SASUB_32(0) items++; } } @@ -740,7 +821,7 @@ void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems) // call MatchFinder_CheckLimits() only after (p->pos++) update -MY_NO_INLINE +Z7_NO_INLINE static void MatchFinder_CheckLimits(CMatchFinder *p) { if (// !p->streamEndWasReached && p->result == SZ_OK && @@ -768,11 +849,14 @@ static void MatchFinder_CheckLimits(CMatchFinder *p) const UInt32 subValue = (p->pos - p->historySize - 1) /* & ~(UInt32)(kNormalizeAlign - 1) */; // const UInt32 subValue = (1 << 15); // for debug // printf("\nMatchFinder_Normalize() subValue == 0x%x\n", subValue); - size_t numSonRefs = p->cyclicBufferSize; - if (p->btMode) - numSonRefs <<= 1; - Inline_MatchFinder_ReduceOffsets(p, subValue); - MatchFinder_Normalize3(subValue, p->hash, (size_t)p->hashSizeSum + numSonRefs); + MatchFinder_REDUCE_OFFSETS(p, subValue) + MatchFinder_Normalize3(subValue, p->hash, (size_t)p->hashMask + 1 + p->fixedHashSize); + { + size_t numSonRefs = p->cyclicBufferSize; + if (p->btMode) + numSonRefs <<= 1; + MatchFinder_Normalize3(subValue, p->son, numSonRefs); + } } if (p->cyclicBufferPos == p->cyclicBufferSize) @@ -785,7 +869,7 @@ static void MatchFinder_CheckLimits(CMatchFinder *p) /* (lenLimit > maxLen) */ -MY_FORCE_INLINE +Z7_FORCE_INLINE static UInt32 * Hc_GetMatchesSpec(size_t lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, UInt32 *d, unsigned maxLen) @@ -867,7 +951,7 @@ static UInt32 * Hc_GetMatchesSpec(size_t lenLimit, UInt32 curMatch, UInt32 pos, } -MY_FORCE_INLINE +Z7_FORCE_INLINE UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, UInt32 *d, UInt32 maxLen) @@ -1004,7 +1088,7 @@ static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const #define MOVE_POS_RET MOVE_POS return distances; -MY_NO_INLINE +Z7_NO_INLINE static void MatchFinder_MovePos(CMatchFinder *p) { /* we go here at the end of stream data, when (avail < num_hash_bytes) @@ -1015,11 +1099,11 @@ static void MatchFinder_MovePos(CMatchFinder *p) if (p->btMode) p->sons[(p->cyclicBufferPos << p->btMode) + 1] = 0; // kEmptyHashValue */ - MOVE_POS; + MOVE_POS } #define GET_MATCHES_HEADER2(minLen, ret_op) \ - unsigned lenLimit; UInt32 hv; Byte *cur; UInt32 curMatch; \ + unsigned lenLimit; UInt32 hv; const Byte *cur; UInt32 curMatch; \ lenLimit = (unsigned)p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ cur = p->buffer; @@ -1028,11 +1112,11 @@ static void MatchFinder_MovePos(CMatchFinder *p) #define MF_PARAMS(p) lenLimit, curMatch, p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue -#define SKIP_FOOTER SkipMatchesSpec(MF_PARAMS(p)); MOVE_POS; } while (--num); +#define SKIP_FOOTER SkipMatchesSpec(MF_PARAMS(p)); MOVE_POS } while (--num); #define GET_MATCHES_FOOTER_BASE(_maxLen_, func) \ distances = func(MF_PARAMS(p), \ - distances, (UInt32)_maxLen_); MOVE_POS_RET; + distances, (UInt32)_maxLen_); MOVE_POS_RET #define GET_MATCHES_FOOTER_BT(_maxLen_) \ GET_MATCHES_FOOTER_BASE(_maxLen_, GetMatchesSpec1) @@ -1052,7 +1136,7 @@ static void MatchFinder_MovePos(CMatchFinder *p) static UInt32* Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) { GET_MATCHES_HEADER(2) - HASH2_CALC; + HASH2_CALC curMatch = p->hash[hv]; p->hash[hv] = p->pos; GET_MATCHES_FOOTER_BT(1) @@ -1061,7 +1145,7 @@ static UInt32* Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) { GET_MATCHES_HEADER(3) - HASH_ZIP_CALC; + HASH_ZIP_CALC curMatch = p->hash[hv]; p->hash[hv] = p->pos; GET_MATCHES_FOOTER_BT(2) @@ -1082,7 +1166,7 @@ static UInt32* Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) UInt32 *hash; GET_MATCHES_HEADER(3) - HASH3_CALC; + HASH3_CALC hash = p->hash; pos = p->pos; @@ -1107,7 +1191,7 @@ static UInt32* Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) if (maxLen == lenLimit) { SkipMatchesSpec(MF_PARAMS(p)); - MOVE_POS_RET; + MOVE_POS_RET } } @@ -1123,7 +1207,7 @@ static UInt32* Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) UInt32 *hash; GET_MATCHES_HEADER(4) - HASH4_CALC; + HASH4_CALC hash = p->hash; pos = p->pos; @@ -1190,7 +1274,7 @@ static UInt32* Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) UInt32 *hash; GET_MATCHES_HEADER(5) - HASH5_CALC; + HASH5_CALC hash = p->hash; pos = p->pos; @@ -1246,7 +1330,7 @@ static UInt32* Bt5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) if (maxLen == lenLimit) { SkipMatchesSpec(MF_PARAMS(p)); - MOVE_POS_RET; + MOVE_POS_RET } break; } @@ -1263,7 +1347,7 @@ static UInt32* Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) UInt32 *hash; GET_MATCHES_HEADER(4) - HASH4_CALC; + HASH4_CALC hash = p->hash; pos = p->pos; @@ -1314,12 +1398,12 @@ static UInt32* Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) if (maxLen == lenLimit) { p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS_RET; + MOVE_POS_RET } break; } - GET_MATCHES_FOOTER_HC(maxLen); + GET_MATCHES_FOOTER_HC(maxLen) } @@ -1330,7 +1414,7 @@ static UInt32 * Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) UInt32 *hash; GET_MATCHES_HEADER(5) - HASH5_CALC; + HASH5_CALC hash = p->hash; pos = p->pos; @@ -1386,19 +1470,19 @@ static UInt32 * Hc5_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) if (maxLen == lenLimit) { p->son[p->cyclicBufferPos] = curMatch; - MOVE_POS_RET; + MOVE_POS_RET } break; } - GET_MATCHES_FOOTER_HC(maxLen); + GET_MATCHES_FOOTER_HC(maxLen) } UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) { GET_MATCHES_HEADER(3) - HASH_ZIP_CALC; + HASH_ZIP_CALC curMatch = p->hash[hv]; p->hash[hv] = p->pos; GET_MATCHES_FOOTER_HC(2) @@ -1409,7 +1493,7 @@ static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { SKIP_HEADER(2) { - HASH2_CALC; + HASH2_CALC curMatch = p->hash[hv]; p->hash[hv] = p->pos; } @@ -1420,7 +1504,7 @@ void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { SKIP_HEADER(3) { - HASH_ZIP_CALC; + HASH_ZIP_CALC curMatch = p->hash[hv]; p->hash[hv] = p->pos; } @@ -1433,7 +1517,7 @@ static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { UInt32 h2; UInt32 *hash; - HASH3_CALC; + HASH3_CALC hash = p->hash; curMatch = (hash + kFix3HashSize)[hv]; hash[h2] = @@ -1448,7 +1532,7 @@ static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { UInt32 h2, h3; UInt32 *hash; - HASH4_CALC; + HASH4_CALC hash = p->hash; curMatch = (hash + kFix4HashSize)[hv]; hash [h2] = @@ -1464,7 +1548,7 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { UInt32 h2, h3; UInt32 *hash; - HASH5_CALC; + HASH5_CALC hash = p->hash; curMatch = (hash + kFix5HashSize)[hv]; hash [h2] = @@ -1478,7 +1562,7 @@ static void Bt5_MatchFinder_Skip(CMatchFinder *p, UInt32 num) #define HC_SKIP_HEADER(minLen) \ do { if (p->lenLimit < minLen) { MatchFinder_MovePos(p); num--; continue; } { \ - Byte *cur; \ + const Byte *cur; \ UInt32 *hash; \ UInt32 *son; \ UInt32 pos = p->pos; \ @@ -1510,7 +1594,7 @@ static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) HC_SKIP_HEADER(4) UInt32 h2, h3; - HASH4_CALC; + HASH4_CALC curMatch = (hash + kFix4HashSize)[hv]; hash [h2] = (hash + kFix3HashSize)[h3] = @@ -1540,7 +1624,7 @@ void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) { HC_SKIP_HEADER(3) - HASH_ZIP_CALC; + HASH_ZIP_CALC curMatch = hash[hv]; hash[hv] = pos; @@ -1590,17 +1674,17 @@ void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *vTable) -void LzFindPrepare() +void LzFindPrepare(void) { - #ifndef FORCE_SATUR_SUB_128 - #ifdef USE_SATUR_SUB_128 + #ifndef FORCE_LZFIND_SATUR_SUB_128 + #ifdef USE_LZFIND_SATUR_SUB_128 LZFIND_SATUR_SUB_CODE_FUNC f = NULL; #ifdef MY_CPU_ARM_OR_ARM64 { if (CPU_IsSupported_NEON()) { // #pragma message ("=== LzFind NEON") - _PRF(printf("\n=== LzFind NEON\n")); + PRF(printf("\n=== LzFind NEON\n")); f = LzFind_SaturSub_128; } // f = 0; // for debug @@ -1609,20 +1693,25 @@ void LzFindPrepare() if (CPU_IsSupported_SSE41()) { // #pragma message ("=== LzFind SSE41") - _PRF(printf("\n=== LzFind SSE41\n")); + PRF(printf("\n=== LzFind SSE41\n")); f = LzFind_SaturSub_128; - #ifdef USE_AVX2 + #ifdef USE_LZFIND_SATUR_SUB_256 if (CPU_IsSupported_AVX2()) { // #pragma message ("=== LzFind AVX2") - _PRF(printf("\n=== LzFind AVX2\n")); + PRF(printf("\n=== LzFind AVX2\n")); f = LzFind_SaturSub_256; } #endif } #endif // MY_CPU_ARM_OR_ARM64 g_LzFind_SaturSub = f; - #endif // USE_SATUR_SUB_128 - #endif // FORCE_SATUR_SUB_128 + #endif // USE_LZFIND_SATUR_SUB_128 + #endif // FORCE_LZFIND_SATUR_SUB_128 } + + +#undef MOVE_POS +#undef MOVE_POS_RET +#undef PRF diff --git a/libraries/lzma/C/LzFind.h b/libraries/lzma/C/LzFind.h index eea873ff6..a3f72c987 100644 --- a/libraries/lzma/C/LzFind.h +++ b/libraries/lzma/C/LzFind.h @@ -1,8 +1,8 @@ /* LzFind.h -- Match finder for LZ algorithms -2021-07-13 : Igor Pavlov : Public domain */ +2023-03-04 : Igor Pavlov : Public domain */ -#ifndef __LZ_FIND_H -#define __LZ_FIND_H +#ifndef ZIP7_INC_LZ_FIND_H +#define ZIP7_INC_LZ_FIND_H #include "7zTypes.h" @@ -10,9 +10,9 @@ EXTERN_C_BEGIN typedef UInt32 CLzRef; -typedef struct _CMatchFinder +typedef struct { - Byte *buffer; + const Byte *buffer; UInt32 pos; UInt32 posLimit; UInt32 streamPos; /* wrap over Zero is allowed (streamPos < pos). Use (UInt32)(streamPos - pos) */ @@ -32,8 +32,8 @@ typedef struct _CMatchFinder UInt32 hashMask; UInt32 cutValue; - Byte *bufferBase; - ISeqInStream *stream; + Byte *bufBase; + ISeqInStreamPtr stream; UInt32 blockSize; UInt32 keepSizeBefore; @@ -43,7 +43,9 @@ typedef struct _CMatchFinder size_t directInputRem; UInt32 historySize; UInt32 fixedHashSize; - UInt32 hashSizeSum; + Byte numHashBytes_Min; + Byte numHashOutBits; + Byte _pad2_[2]; SRes result; UInt32 crc[256]; size_t numRefs; @@ -69,24 +71,45 @@ void MatchFinder_ReadIfRequired(CMatchFinder *p); void MatchFinder_Construct(CMatchFinder *p); -/* Conditions: - historySize <= 3 GB - keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB +/* (directInput = 0) is default value. + It's required to provide correct (directInput) value + before calling MatchFinder_Create(). + You can set (directInput) by any of the following calls: + - MatchFinder_SET_DIRECT_INPUT_BUF() + - MatchFinder_SET_STREAM() + - MatchFinder_SET_STREAM_MODE() */ + +#define MatchFinder_SET_DIRECT_INPUT_BUF(p, _src_, _srcLen_) { \ + (p)->stream = NULL; \ + (p)->directInput = 1; \ + (p)->buffer = (_src_); \ + (p)->directInputRem = (_srcLen_); } + +/* +#define MatchFinder_SET_STREAM_MODE(p) { \ + (p)->directInput = 0; } +*/ + +#define MatchFinder_SET_STREAM(p, _stream_) { \ + (p)->stream = _stream_; \ + (p)->directInput = 0; } + + int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc); void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc); void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems); -// void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); /* -#define Inline_MatchFinder_InitPos(p, val) \ +#define MatchFinder_INIT_POS(p, val) \ (p)->pos = (val); \ (p)->streamPos = (val); */ -#define Inline_MatchFinder_ReduceOffsets(p, subValue) \ +// void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); +#define MatchFinder_REDUCE_OFFSETS(p, subValue) \ (p)->pos -= (subValue); \ (p)->streamPos -= (subValue); @@ -107,7 +130,7 @@ typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); typedef UInt32 * (*Mf_GetMatches_Func)(void *object, UInt32 *distances); typedef void (*Mf_Skip_Func)(void *object, UInt32); -typedef struct _IMatchFinder +typedef struct { Mf_Init_Func Init; Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; diff --git a/libraries/lzma/C/LzFindMt.c b/libraries/lzma/C/LzFindMt.c index 4e67fc3f2..5253e6ebb 100644 --- a/libraries/lzma/C/LzFindMt.c +++ b/libraries/lzma/C/LzFindMt.c @@ -1,5 +1,5 @@ /* LzFindMt.c -- multithreaded Match finder for LZ algorithms -2021-12-21 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -69,7 +69,7 @@ extern UInt64 g_NumIters_Bytes; UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ h3 = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } -#define __MT_HASH4_CALC { \ +#define MT_HASH4_CALC { \ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ h2 = temp & (kHash2Size - 1); \ temp ^= ((UInt32)cur[2] << 8); \ @@ -79,14 +79,14 @@ extern UInt64 g_NumIters_Bytes; */ -MY_NO_INLINE +Z7_NO_INLINE static void MtSync_Construct(CMtSync *p) { p->affinity = 0; p->wasCreated = False; p->csWasInitialized = False; p->csWasEntered = False; - Thread_Construct(&p->thread); + Thread_CONSTRUCT(&p->thread) Event_Construct(&p->canStart); Event_Construct(&p->wasStopped); Semaphore_Construct(&p->freeSemaphore); @@ -116,7 +116,7 @@ static void MtSync_Construct(CMtSync *p) (p)->csWasEntered = False; } -MY_NO_INLINE +Z7_NO_INLINE static UInt32 MtSync_GetNextBlock(CMtSync *p) { UInt32 numBlocks = 0; @@ -140,14 +140,14 @@ static UInt32 MtSync_GetNextBlock(CMtSync *p) // buffer is UNLOCKED here Semaphore_Wait(&p->filledSemaphore); - LOCK_BUFFER(p); + LOCK_BUFFER(p) return numBlocks; } /* if Writing (Processing) thread was started, we must call MtSync_StopWriting() */ -MY_NO_INLINE +Z7_NO_INLINE static void MtSync_StopWriting(CMtSync *p) { if (!Thread_WasCreated(&p->thread) || p->needStart) @@ -185,7 +185,7 @@ static void MtSync_StopWriting(CMtSync *p) } -MY_NO_INLINE +Z7_NO_INLINE static void MtSync_Destruct(CMtSync *p) { PRF(printf("\nMtSync_Destruct %p\n", p)); @@ -220,11 +220,11 @@ static void MtSync_Destruct(CMtSync *p) // #define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } // we want to get real system error codes here instead of SZ_ERROR_THREAD -#define RINOK_THREAD(x) RINOK(x) +#define RINOK_THREAD(x) RINOK_WRes(x) // call it before each new file (when new starting is required): -MY_NO_INLINE +Z7_NO_INLINE static SRes MtSync_Init(CMtSync *p, UInt32 numBlocks) { WRes wres; @@ -245,12 +245,12 @@ static WRes MtSync_Create_WRes(CMtSync *p, THREAD_FUNC_TYPE startAddress, void * if (p->wasCreated) return SZ_OK; - RINOK_THREAD(CriticalSection_Init(&p->cs)); + RINOK_THREAD(CriticalSection_Init(&p->cs)) p->csWasInitialized = True; p->csWasEntered = False; - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart)); - RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped)); + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->canStart)) + RINOK_THREAD(AutoResetEvent_CreateNotSignaled(&p->wasStopped)) p->needStart = True; p->exit = True; /* p->exit is unused before (canStart) Event. @@ -264,13 +264,13 @@ static WRes MtSync_Create_WRes(CMtSync *p, THREAD_FUNC_TYPE startAddress, void * else wres = Thread_Create(&p->thread, startAddress, obj); - RINOK_THREAD(wres); + RINOK_THREAD(wres) p->wasCreated = True; return SZ_OK; } -MY_NO_INLINE +Z7_NO_INLINE static SRes MtSync_Create(CMtSync *p, THREAD_FUNC_TYPE startAddress, void *obj) { const WRes wres = MtSync_Create_WRes(p, startAddress, obj); @@ -519,7 +519,7 @@ static void HashThreadFunc(CMatchFinderMt *mt) if (mf->pos > (UInt32)kMtMaxValForNormalize - num) { const UInt32 subValue = (mf->pos - mf->historySize - 1); // & ~(UInt32)(kNormalizeAlign - 1); - Inline_MatchFinder_ReduceOffsets(mf, subValue); + MatchFinder_REDUCE_OFFSETS(mf, subValue) MatchFinder_Normalize3(subValue, mf->hash + mf->fixedHashSize, (size_t)mf->hashMask + 1); } @@ -560,7 +560,7 @@ static void HashThreadFunc(CMatchFinderMt *mt) */ -UInt32 * MY_FAST_CALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, +UInt32 * Z7_FASTCALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 *posRes); @@ -749,7 +749,7 @@ static void BtFillBlock(CMatchFinderMt *p, UInt32 globalBlockIndex) } -MY_NO_INLINE +Z7_NO_INLINE static void BtThreadFunc(CMatchFinderMt *mt) { CMtSync *p = &mt->btSync; @@ -864,15 +864,15 @@ SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddB if (!MatchFinder_Create(mf, historySize, keepAddBufferBefore, matchMaxLen, keepAddBufferAfter, alloc)) return SZ_ERROR_MEM; - RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p)); - RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p)); + RINOK(MtSync_Create(&p->hashSync, HashThreadFunc2, p)) + RINOK(MtSync_Create(&p->btSync, BtThreadFunc2, p)) return SZ_OK; } SRes MatchFinderMt_InitMt(CMatchFinderMt *p) { - RINOK(MtSync_Init(&p->hashSync, kMtHashNumBlocks)); + RINOK(MtSync_Init(&p->hashSync, kMtHashNumBlocks)) return MtSync_Init(&p->btSync, kMtBtNumBlocks); } @@ -941,7 +941,7 @@ void MatchFinderMt_ReleaseStream(CMatchFinderMt *p) } -MY_NO_INLINE +Z7_NO_INLINE static UInt32 MatchFinderMt_GetNextBlock_Bt(CMatchFinderMt *p) { if (p->failure_LZ_BT) @@ -1163,7 +1163,7 @@ UInt32* MatchFinderMt_GetMatches_Bt4(CMatchFinderMt *p, UInt32 *d) */ -static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) +static UInt32 * MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) { UInt32 h2, h3, /* h4, */ c2, c3 /* , c4 */; UInt32 *hash = p->hash; @@ -1179,9 +1179,8 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) (hash + kFix3HashSize)[h3] = m; // (hash + kFix4HashSize)[h4] = m; - #define _USE_H2 - - #ifdef _USE_H2 + // #define BT5_USE_H2 + // #ifdef BT5_USE_H2 if (c2 >= matchMinPos && cur[(ptrdiff_t)c2 - (ptrdiff_t)m] == cur[0]) { d[1] = m - c2 - 1; @@ -1197,8 +1196,8 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) } d[0] = 3; d += 2; - - #ifdef _USE_H4 + + #ifdef BT5_USE_H4 if (c4 >= matchMinPos) if ( cur[(ptrdiff_t)c4 - (ptrdiff_t)m] == cur[0] && @@ -1214,7 +1213,7 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) d[0] = 2; d += 2; } - #endif + // #endif if (c3 >= matchMinPos && cur[(ptrdiff_t)c3 - (ptrdiff_t)m] == cur[0]) { @@ -1228,7 +1227,7 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) d += 2; } - #ifdef _USE_H4 + #ifdef BT5_USE_H4 if (c4 >= matchMinPos) if ( cur[(ptrdiff_t)c4 - (ptrdiff_t)m] == cur[0] && @@ -1244,7 +1243,7 @@ static UInt32 *MixMatches4(CMatchFinderMt *p, UInt32 matchMinPos, UInt32 *d) } -static UInt32* MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *d) +static UInt32 * MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *d) { const UInt32 *bt = p->btBufPos; const UInt32 len = *bt++; @@ -1268,7 +1267,7 @@ static UInt32* MatchFinderMt2_GetMatches(CMatchFinderMt *p, UInt32 *d) -static UInt32* MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *d) +static UInt32 * MatchFinderMt_GetMatches(CMatchFinderMt *p, UInt32 *d) { const UInt32 *bt = p->btBufPos; UInt32 len = *bt++; @@ -1398,3 +1397,10 @@ void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder2 *vTable) break; } } + +#undef RINOK_THREAD +#undef PRF +#undef MF +#undef GetUi24hi_from32 +#undef LOCK_BUFFER +#undef UNLOCK_BUFFER diff --git a/libraries/lzma/C/LzFindMt.h b/libraries/lzma/C/LzFindMt.h index 660b7244d..db5923ea0 100644 --- a/libraries/lzma/C/LzFindMt.h +++ b/libraries/lzma/C/LzFindMt.h @@ -1,15 +1,15 @@ /* LzFindMt.h -- multithreaded Match finder for LZ algorithms -2021-07-12 : Igor Pavlov : Public domain */ +2023-03-05 : Igor Pavlov : Public domain */ -#ifndef __LZ_FIND_MT_H -#define __LZ_FIND_MT_H +#ifndef ZIP7_INC_LZ_FIND_MT_H +#define ZIP7_INC_LZ_FIND_MT_H #include "LzFind.h" #include "Threads.h" EXTERN_C_BEGIN -typedef struct _CMtSync +typedef struct { UInt32 numProcessedBlocks; CThread thread; @@ -39,7 +39,7 @@ typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distance typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos, UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc); -typedef struct _CMatchFinderMt +typedef struct { /* LZ */ const Byte *pointerToCurPos; diff --git a/libraries/lzma/C/LzFindOpt.c b/libraries/lzma/C/LzFindOpt.c index 8ff006e07..85bdc136d 100644 --- a/libraries/lzma/C/LzFindOpt.c +++ b/libraries/lzma/C/LzFindOpt.c @@ -1,5 +1,5 @@ /* LzFindOpt.c -- multithreaded Match finder for LZ algorithms -2021-07-13 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -41,8 +41,8 @@ UInt64 g_NumIters_Bytes; // #define CYC_TO_POS_OFFSET 1 // for debug /* -MY_NO_INLINE -UInt32 * MY_FAST_CALL GetMatchesSpecN_1(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, +Z7_NO_INLINE +UInt32 * Z7_FASTCALL GetMatchesSpecN_1(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, UInt32 *posRes) { do @@ -214,13 +214,13 @@ else to eliminate "movsx" BUG in old MSVC x64 compiler. */ -UInt32 * MY_FAST_CALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, +UInt32 * Z7_FASTCALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 *posRes); -MY_NO_INLINE -UInt32 * MY_FAST_CALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, +Z7_NO_INLINE +UInt32 * Z7_FASTCALL GetMatchesSpecN_2(const Byte *lenLimit, size_t pos, const Byte *cur, CLzRef *son, UInt32 _cutValue, UInt32 *d, size_t _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 *posRes) @@ -404,7 +404,7 @@ else /* typedef UInt32 uint32plus; // size_t -UInt32 * MY_FAST_CALL GetMatchesSpecN_3(uint32plus lenLimit, size_t pos, const Byte *cur, CLzRef *son, +UInt32 * Z7_FASTCALL GetMatchesSpecN_3(uint32plus lenLimit, size_t pos, const Byte *cur, CLzRef *son, UInt32 _cutValue, UInt32 *d, uint32plus _maxLen, const UInt32 *hash, const UInt32 *limit, const UInt32 *size, size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 *posRes) diff --git a/libraries/lzma/C/LzHash.h b/libraries/lzma/C/LzHash.h index 77b898cfa..2b6290b64 100644 --- a/libraries/lzma/C/LzHash.h +++ b/libraries/lzma/C/LzHash.h @@ -1,8 +1,8 @@ -/* LzHash.h -- HASH functions for LZ algorithms -2019-10-30 : Igor Pavlov : Public domain */ +/* LzHash.h -- HASH constants for LZ algorithms +2023-03-05 : Igor Pavlov : Public domain */ -#ifndef __LZ_HASH_H -#define __LZ_HASH_H +#ifndef ZIP7_INC_LZ_HASH_H +#define ZIP7_INC_LZ_HASH_H /* (kHash2Size >= (1 << 8)) : Required diff --git a/libraries/lzma/C/Lzma2Dec.c b/libraries/lzma/C/Lzma2Dec.c index ac970a843..388cbc717 100644 --- a/libraries/lzma/C/Lzma2Dec.c +++ b/libraries/lzma/C/Lzma2Dec.c @@ -1,5 +1,5 @@ /* Lzma2Dec.c -- LZMA2 Decoder -2021-02-09 : Igor Pavlov : Public domain */ +2023-03-03 : Igor Pavlov : Public domain */ /* #define SHOW_DEBUG_INFO */ @@ -71,14 +71,14 @@ static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props) SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) { Byte props[LZMA_PROPS_SIZE]; - RINOK(Lzma2Dec_GetOldProps(prop, props)); + RINOK(Lzma2Dec_GetOldProps(prop, props)) return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); } SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc) { Byte props[LZMA_PROPS_SIZE]; - RINOK(Lzma2Dec_GetOldProps(prop, props)); + RINOK(Lzma2Dec_GetOldProps(prop, props)) return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); } @@ -474,8 +474,8 @@ SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, SizeT outSize = *destLen, inSize = *srcLen; *destLen = *srcLen = 0; *status = LZMA_STATUS_NOT_SPECIFIED; - Lzma2Dec_Construct(&p); - RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)); + Lzma2Dec_CONSTRUCT(&p) + RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc)) p.decoder.dic = dest; p.decoder.dicBufSize = outSize; Lzma2Dec_Init(&p); @@ -487,3 +487,5 @@ SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, Lzma2Dec_FreeProbs(&p, alloc); return res; } + +#undef PRF diff --git a/libraries/lzma/C/Lzma2Dec.h b/libraries/lzma/C/Lzma2Dec.h index b8ddeac89..1f5233a72 100644 --- a/libraries/lzma/C/Lzma2Dec.h +++ b/libraries/lzma/C/Lzma2Dec.h @@ -1,8 +1,8 @@ /* Lzma2Dec.h -- LZMA2 Decoder -2018-02-19 : Igor Pavlov : Public domain */ +2023-03-03 : Igor Pavlov : Public domain */ -#ifndef __LZMA2_DEC_H -#define __LZMA2_DEC_H +#ifndef ZIP7_INC_LZMA2_DEC_H +#define ZIP7_INC_LZMA2_DEC_H #include "LzmaDec.h" @@ -22,9 +22,10 @@ typedef struct CLzmaDec decoder; } CLzma2Dec; -#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) -#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc) -#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc) +#define Lzma2Dec_CONSTRUCT(p) LzmaDec_CONSTRUCT(&(p)->decoder) +#define Lzma2Dec_Construct(p) Lzma2Dec_CONSTRUCT(p) +#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc) +#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc) SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc); @@ -90,7 +91,7 @@ Lzma2Dec_GetUnpackExtra() returns the value that shows at current input positon. */ -#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0); +#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0) /* ---------- One Call Interface ---------- */ diff --git a/libraries/lzma/C/Lzma2DecMt.c b/libraries/lzma/C/Lzma2DecMt.c new file mode 100644 index 000000000..4bc4ddeb5 --- /dev/null +++ b/libraries/lzma/C/Lzma2DecMt.c @@ -0,0 +1,1095 @@ +/* Lzma2DecMt.c -- LZMA2 Decoder Multi-thread +2023-04-13 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #define SHOW_DEBUG_INFO +// #define Z7_ST + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include "Alloc.h" + +#include "Lzma2Dec.h" +#include "Lzma2DecMt.h" + +#ifndef Z7_ST +#include "MtDec.h" + +#define LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT (1 << 28) +#endif + + +#ifndef Z7_ST +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif +#define PRF_STR(s) PRF(printf("\n" s "\n");) +#define PRF_STR_INT_2(s, d1, d2) PRF(printf("\n" s " %d %d\n", (unsigned)d1, (unsigned)d2);) +#endif + + +void Lzma2DecMtProps_Init(CLzma2DecMtProps *p) +{ + p->inBufSize_ST = 1 << 20; + p->outStep_ST = 1 << 20; + + #ifndef Z7_ST + p->numThreads = 1; + p->inBufSize_MT = 1 << 18; + p->outBlockMax = LZMA2DECMT_OUT_BLOCK_MAX_DEFAULT; + p->inBlockMax = p->outBlockMax + p->outBlockMax / 16; + #endif +} + + + +#ifndef Z7_ST + +/* ---------- CLzma2DecMtThread ---------- */ + +typedef struct +{ + CLzma2Dec dec; + Byte dec_created; + Byte needInit; + + Byte *outBuf; + size_t outBufSize; + + EMtDecParseState state; + ELzma2ParseStatus parseStatus; + + size_t inPreSize; + size_t outPreSize; + + size_t inCodeSize; + size_t outCodeSize; + SRes codeRes; + + CAlignOffsetAlloc alloc; + + Byte mtPad[1 << 7]; +} CLzma2DecMtThread; + +#endif + + +/* ---------- CLzma2DecMt ---------- */ + +struct CLzma2DecMt +{ + // ISzAllocPtr alloc; + ISzAllocPtr allocMid; + + CAlignOffsetAlloc alignOffsetAlloc; + CLzma2DecMtProps props; + Byte prop; + + ISeqInStreamPtr inStream; + ISeqOutStreamPtr outStream; + ICompressProgressPtr progress; + + BoolInt finishMode; + BoolInt outSize_Defined; + UInt64 outSize; + + UInt64 outProcessed; + UInt64 inProcessed; + BoolInt readWasFinished; + SRes readRes; + + Byte *inBuf; + size_t inBufSize; + Byte dec_created; + CLzma2Dec dec; + + size_t inPos; + size_t inLim; + + #ifndef Z7_ST + UInt64 outProcessed_Parse; + BoolInt mtc_WasConstructed; + CMtDec mtc; + CLzma2DecMtThread coders[MTDEC_THREADS_MAX]; + #endif +}; + + + +CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid) +{ + CLzma2DecMt *p = (CLzma2DecMt *)ISzAlloc_Alloc(alloc, sizeof(CLzma2DecMt)); + if (!p) + return NULL; + + // p->alloc = alloc; + p->allocMid = allocMid; + + AlignOffsetAlloc_CreateVTable(&p->alignOffsetAlloc); + p->alignOffsetAlloc.numAlignBits = 7; + p->alignOffsetAlloc.offset = 0; + p->alignOffsetAlloc.baseAlloc = alloc; + + p->inBuf = NULL; + p->inBufSize = 0; + p->dec_created = False; + + // Lzma2DecMtProps_Init(&p->props); + + #ifndef Z7_ST + p->mtc_WasConstructed = False; + { + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CLzma2DecMtThread *t = &p->coders[i]; + t->dec_created = False; + t->outBuf = NULL; + t->outBufSize = 0; + } + } + #endif + + return (CLzma2DecMtHandle)(void *)p; +} + + +#ifndef Z7_ST + +static void Lzma2DecMt_FreeOutBufs(CLzma2DecMt *p) +{ + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CLzma2DecMtThread *t = &p->coders[i]; + if (t->outBuf) + { + ISzAlloc_Free(p->allocMid, t->outBuf); + t->outBuf = NULL; + t->outBufSize = 0; + } + } +} + +#endif + + +static void Lzma2DecMt_FreeSt(CLzma2DecMt *p) +{ + if (p->dec_created) + { + Lzma2Dec_Free(&p->dec, &p->alignOffsetAlloc.vt); + p->dec_created = False; + } + if (p->inBuf) + { + ISzAlloc_Free(p->allocMid, p->inBuf); + p->inBuf = NULL; + } + p->inBufSize = 0; +} + + +// #define GET_CLzma2DecMt_p CLzma2DecMt *p = (CLzma2DecMt *)(void *)pp; + +void Lzma2DecMt_Destroy(CLzma2DecMtHandle p) +{ + // GET_CLzma2DecMt_p + + Lzma2DecMt_FreeSt(p); + + #ifndef Z7_ST + + if (p->mtc_WasConstructed) + { + MtDec_Destruct(&p->mtc); + p->mtc_WasConstructed = False; + } + { + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CLzma2DecMtThread *t = &p->coders[i]; + if (t->dec_created) + { + // we don't need to free dict here + Lzma2Dec_FreeProbs(&t->dec, &t->alloc.vt); // p->alloc !!! + t->dec_created = False; + } + } + } + Lzma2DecMt_FreeOutBufs(p); + + #endif + + ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, p); +} + + + +#ifndef Z7_ST + +static void Lzma2DecMt_MtCallback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc) +{ + CLzma2DecMt *me = (CLzma2DecMt *)obj; + CLzma2DecMtThread *t = &me->coders[coderIndex]; + + PRF_STR_INT_2("Parse", coderIndex, cc->srcSize) + + cc->state = MTDEC_PARSE_CONTINUE; + + if (cc->startCall) + { + if (!t->dec_created) + { + Lzma2Dec_CONSTRUCT(&t->dec) + t->dec_created = True; + AlignOffsetAlloc_CreateVTable(&t->alloc); + { + /* (1 << 12) is expected size of one way in data cache. + We optimize alignment for cache line size of 128 bytes and smaller */ + const unsigned kNumAlignBits = 12; + const unsigned kNumCacheLineBits = 7; /* <= kNumAlignBits */ + t->alloc.numAlignBits = kNumAlignBits; + t->alloc.offset = ((UInt32)coderIndex * (((unsigned)1 << 11) + (1 << 8) + (1 << 6))) & (((unsigned)1 << kNumAlignBits) - ((unsigned)1 << kNumCacheLineBits)); + t->alloc.baseAlloc = me->alignOffsetAlloc.baseAlloc; + } + } + Lzma2Dec_Init(&t->dec); + + t->inPreSize = 0; + t->outPreSize = 0; + // t->blockWasFinished = False; + // t->finishedWithMark = False; + t->parseStatus = (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED; + t->state = MTDEC_PARSE_CONTINUE; + + t->inCodeSize = 0; + t->outCodeSize = 0; + t->codeRes = SZ_OK; + + // (cc->srcSize == 0) is allowed + } + + { + ELzma2ParseStatus status; + BoolInt overflow; + UInt32 unpackRem = 0; + + int checkFinishBlock = True; + size_t limit = me->props.outBlockMax; + if (me->outSize_Defined) + { + UInt64 rem = me->outSize - me->outProcessed_Parse; + if (limit >= rem) + { + limit = (size_t)rem; + if (!me->finishMode) + checkFinishBlock = False; + } + } + + // checkFinishBlock = False, if we want to decode partial data + // that must be finished at position <= outBlockMax. + + { + const size_t srcOrig = cc->srcSize; + SizeT srcSize_Point = 0; + SizeT dicPos_Point = 0; + + cc->srcSize = 0; + overflow = False; + + for (;;) + { + SizeT srcCur = (SizeT)(srcOrig - cc->srcSize); + + status = Lzma2Dec_Parse(&t->dec, + (SizeT)limit - t->dec.decoder.dicPos, + cc->src + cc->srcSize, &srcCur, + checkFinishBlock); + + cc->srcSize += srcCur; + + if (status == LZMA2_PARSE_STATUS_NEW_CHUNK) + { + if (t->dec.unpackSize > me->props.outBlockMax - t->dec.decoder.dicPos) + { + overflow = True; + break; + } + continue; + } + + if (status == LZMA2_PARSE_STATUS_NEW_BLOCK) + { + if (t->dec.decoder.dicPos == 0) + continue; + // we decode small blocks in one thread + if (t->dec.decoder.dicPos >= (1 << 14)) + break; + dicPos_Point = t->dec.decoder.dicPos; + srcSize_Point = (SizeT)cc->srcSize; + continue; + } + + if ((int)status == LZMA_STATUS_NOT_FINISHED && checkFinishBlock + // && limit == t->dec.decoder.dicPos + // && limit == me->props.outBlockMax + ) + { + overflow = True; + break; + } + + unpackRem = Lzma2Dec_GetUnpackExtra(&t->dec); + break; + } + + if (dicPos_Point != 0 + && (int)status != LZMA2_PARSE_STATUS_NEW_BLOCK + && (int)status != LZMA_STATUS_FINISHED_WITH_MARK + && (int)status != LZMA_STATUS_NOT_SPECIFIED) + { + // we revert to latest newBlock state + status = LZMA2_PARSE_STATUS_NEW_BLOCK; + unpackRem = 0; + t->dec.decoder.dicPos = dicPos_Point; + cc->srcSize = srcSize_Point; + overflow = False; + } + } + + t->inPreSize += cc->srcSize; + t->parseStatus = status; + + if (overflow) + cc->state = MTDEC_PARSE_OVERFLOW; + else + { + size_t dicPos = t->dec.decoder.dicPos; + + if ((int)status != LZMA_STATUS_NEEDS_MORE_INPUT) + { + if (status == LZMA2_PARSE_STATUS_NEW_BLOCK) + { + cc->state = MTDEC_PARSE_NEW; + cc->srcSize--; // we don't need control byte of next block + t->inPreSize--; + } + else + { + cc->state = MTDEC_PARSE_END; + if ((int)status != LZMA_STATUS_FINISHED_WITH_MARK) + { + // (status == LZMA_STATUS_NOT_SPECIFIED) + // (status == LZMA_STATUS_NOT_FINISHED) + if (unpackRem != 0) + { + /* we also reserve space for max possible number of output bytes of current LZMA chunk */ + size_t rem = limit - dicPos; + if (rem > unpackRem) + rem = unpackRem; + dicPos += rem; + } + } + } + + me->outProcessed_Parse += dicPos; + } + + cc->outPos = dicPos; + t->outPreSize = (size_t)dicPos; + } + + t->state = cc->state; + return; + } +} + + +static SRes Lzma2DecMt_MtCallback_PreCode(void *pp, unsigned coderIndex) +{ + CLzma2DecMt *me = (CLzma2DecMt *)pp; + CLzma2DecMtThread *t = &me->coders[coderIndex]; + Byte *dest = t->outBuf; + + if (t->inPreSize == 0) + { + t->codeRes = SZ_ERROR_DATA; + return t->codeRes; + } + + if (!dest || t->outBufSize < t->outPreSize) + { + if (dest) + { + ISzAlloc_Free(me->allocMid, dest); + t->outBuf = NULL; + t->outBufSize = 0; + } + + dest = (Byte *)ISzAlloc_Alloc(me->allocMid, t->outPreSize + // + (1 << 28) + ); + // Sleep(200); + if (!dest) + return SZ_ERROR_MEM; + t->outBuf = dest; + t->outBufSize = t->outPreSize; + } + + t->dec.decoder.dic = dest; + t->dec.decoder.dicBufSize = (SizeT)t->outPreSize; + + t->needInit = True; + + return Lzma2Dec_AllocateProbs(&t->dec, me->prop, &t->alloc.vt); // alloc.vt +} + + +static SRes Lzma2DecMt_MtCallback_Code(void *pp, unsigned coderIndex, + const Byte *src, size_t srcSize, int srcFinished, + // int finished, int blockFinished, + UInt64 *inCodePos, UInt64 *outCodePos, int *stop) +{ + CLzma2DecMt *me = (CLzma2DecMt *)pp; + CLzma2DecMtThread *t = &me->coders[coderIndex]; + + UNUSED_VAR(srcFinished) + + PRF_STR_INT_2("Code", coderIndex, srcSize) + + *inCodePos = t->inCodeSize; + *outCodePos = 0; + *stop = True; + + if (t->needInit) + { + Lzma2Dec_Init(&t->dec); + t->needInit = False; + } + + { + ELzmaStatus status; + SizeT srcProcessed = (SizeT)srcSize; + BoolInt blockWasFinished = + ((int)t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK + || t->parseStatus == LZMA2_PARSE_STATUS_NEW_BLOCK); + + SRes res = Lzma2Dec_DecodeToDic(&t->dec, + (SizeT)t->outPreSize, + src, &srcProcessed, + blockWasFinished ? LZMA_FINISH_END : LZMA_FINISH_ANY, + &status); + + t->codeRes = res; + + t->inCodeSize += srcProcessed; + *inCodePos = t->inCodeSize; + t->outCodeSize = t->dec.decoder.dicPos; + *outCodePos = t->dec.decoder.dicPos; + + if (res != SZ_OK) + return res; + + if (srcProcessed == srcSize) + *stop = False; + + if (blockWasFinished) + { + if (srcSize != srcProcessed) + return SZ_ERROR_FAIL; + + if (t->inPreSize == t->inCodeSize) + { + if (t->outPreSize != t->outCodeSize) + return SZ_ERROR_FAIL; + *stop = True; + } + } + else + { + if (t->outPreSize == t->outCodeSize) + *stop = True; + } + + return SZ_OK; + } +} + + +#define LZMA2DECMT_STREAM_WRITE_STEP (1 << 24) + +static SRes Lzma2DecMt_MtCallback_Write(void *pp, unsigned coderIndex, + BoolInt needWriteToStream, + const Byte *src, size_t srcSize, BoolInt isCross, + BoolInt *needContinue, BoolInt *canRecode) +{ + CLzma2DecMt *me = (CLzma2DecMt *)pp; + const CLzma2DecMtThread *t = &me->coders[coderIndex]; + size_t size = t->outCodeSize; + const Byte *data = t->outBuf; + BoolInt needContinue2 = True; + + UNUSED_VAR(src) + UNUSED_VAR(srcSize) + UNUSED_VAR(isCross) + + PRF_STR_INT_2("Write", coderIndex, srcSize) + + *needContinue = False; + *canRecode = True; + + if ( + // t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK + t->state == MTDEC_PARSE_OVERFLOW + || t->state == MTDEC_PARSE_END) + needContinue2 = False; + + + if (!needWriteToStream) + return SZ_OK; + + me->mtc.inProcessed += t->inCodeSize; + + if (t->codeRes == SZ_OK) + if ((int)t->parseStatus == LZMA_STATUS_FINISHED_WITH_MARK + || t->parseStatus == LZMA2_PARSE_STATUS_NEW_BLOCK) + if (t->outPreSize != t->outCodeSize + || t->inPreSize != t->inCodeSize) + return SZ_ERROR_FAIL; + + *canRecode = False; + + if (me->outStream) + { + for (;;) + { + size_t cur = size; + size_t written; + if (cur > LZMA2DECMT_STREAM_WRITE_STEP) + cur = LZMA2DECMT_STREAM_WRITE_STEP; + + written = ISeqOutStream_Write(me->outStream, data, cur); + + me->outProcessed += written; + // me->mtc.writtenTotal += written; + if (written != cur) + return SZ_ERROR_WRITE; + data += cur; + size -= cur; + if (size == 0) + { + *needContinue = needContinue2; + return SZ_OK; + } + RINOK(MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0)) + } + } + + return SZ_ERROR_FAIL; + /* + if (size > me->outBufSize) + return SZ_ERROR_OUTPUT_EOF; + memcpy(me->outBuf, data, size); + me->outBufSize -= size; + me->outBuf += size; + *needContinue = needContinue2; + return SZ_OK; + */ +} + +#endif + + +static SRes Lzma2Dec_Prepare_ST(CLzma2DecMt *p) +{ + if (!p->dec_created) + { + Lzma2Dec_CONSTRUCT(&p->dec) + p->dec_created = True; + } + + RINOK(Lzma2Dec_Allocate(&p->dec, p->prop, &p->alignOffsetAlloc.vt)) + + if (!p->inBuf || p->inBufSize != p->props.inBufSize_ST) + { + ISzAlloc_Free(p->allocMid, p->inBuf); + p->inBufSize = 0; + p->inBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.inBufSize_ST); + if (!p->inBuf) + return SZ_ERROR_MEM; + p->inBufSize = p->props.inBufSize_ST; + } + + Lzma2Dec_Init(&p->dec); + + return SZ_OK; +} + + +static SRes Lzma2Dec_Decode_ST(CLzma2DecMt *p + #ifndef Z7_ST + , BoolInt tMode + #endif + ) +{ + SizeT wrPos; + size_t inPos, inLim; + const Byte *inData; + UInt64 inPrev, outPrev; + + CLzma2Dec *dec; + + #ifndef Z7_ST + if (tMode) + { + Lzma2DecMt_FreeOutBufs(p); + tMode = MtDec_PrepareRead(&p->mtc); + } + #endif + + RINOK(Lzma2Dec_Prepare_ST(p)) + + dec = &p->dec; + + inPrev = p->inProcessed; + outPrev = p->outProcessed; + + inPos = 0; + inLim = 0; + inData = NULL; + wrPos = dec->decoder.dicPos; + + for (;;) + { + SizeT dicPos; + SizeT size; + ELzmaFinishMode finishMode; + SizeT inProcessed; + ELzmaStatus status; + SRes res; + + SizeT outProcessed; + BoolInt outFinished; + BoolInt needStop; + + if (inPos == inLim) + { + #ifndef Z7_ST + if (tMode) + { + inData = MtDec_Read(&p->mtc, &inLim); + inPos = 0; + if (inData) + continue; + tMode = False; + inLim = 0; + } + #endif + + if (!p->readWasFinished) + { + inPos = 0; + inLim = p->inBufSize; + inData = p->inBuf; + p->readRes = ISeqInStream_Read(p->inStream, (void *)(p->inBuf), &inLim); + // p->readProcessed += inLim; + // inLim -= 5; p->readWasFinished = True; // for test + if (inLim == 0 || p->readRes != SZ_OK) + p->readWasFinished = True; + } + } + + dicPos = dec->decoder.dicPos; + { + SizeT next = dec->decoder.dicBufSize; + if (next - wrPos > p->props.outStep_ST) + next = wrPos + (SizeT)p->props.outStep_ST; + size = next - dicPos; + } + + finishMode = LZMA_FINISH_ANY; + if (p->outSize_Defined) + { + const UInt64 rem = p->outSize - p->outProcessed; + if (size >= rem) + { + size = (SizeT)rem; + if (p->finishMode) + finishMode = LZMA_FINISH_END; + } + } + + inProcessed = (SizeT)(inLim - inPos); + + res = Lzma2Dec_DecodeToDic(dec, dicPos + size, inData + inPos, &inProcessed, finishMode, &status); + + inPos += inProcessed; + p->inProcessed += inProcessed; + outProcessed = dec->decoder.dicPos - dicPos; + p->outProcessed += outProcessed; + + outFinished = (p->outSize_Defined && p->outSize <= p->outProcessed); + + needStop = (res != SZ_OK + || (inProcessed == 0 && outProcessed == 0) + || status == LZMA_STATUS_FINISHED_WITH_MARK + || (!p->finishMode && outFinished)); + + if (needStop || outProcessed >= size) + { + SRes res2; + { + size_t writeSize = dec->decoder.dicPos - wrPos; + size_t written = ISeqOutStream_Write(p->outStream, dec->decoder.dic + wrPos, writeSize); + res2 = (written == writeSize) ? SZ_OK : SZ_ERROR_WRITE; + } + + if (dec->decoder.dicPos == dec->decoder.dicBufSize) + dec->decoder.dicPos = 0; + wrPos = dec->decoder.dicPos; + + RINOK(res2) + + if (needStop) + { + if (res != SZ_OK) + return res; + + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + { + if (p->finishMode) + { + if (p->outSize_Defined && p->outSize != p->outProcessed) + return SZ_ERROR_DATA; + } + return SZ_OK; + } + + if (!p->finishMode && outFinished) + return SZ_OK; + + if (status == LZMA_STATUS_NEEDS_MORE_INPUT) + return SZ_ERROR_INPUT_EOF; + + return SZ_ERROR_DATA; + } + } + + if (p->progress) + { + UInt64 inDelta = p->inProcessed - inPrev; + UInt64 outDelta = p->outProcessed - outPrev; + if (inDelta >= (1 << 22) || outDelta >= (1 << 22)) + { + RINOK(ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed)) + inPrev = p->inProcessed; + outPrev = p->outProcessed; + } + } + } +} + + + +SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p, + Byte prop, + const CLzma2DecMtProps *props, + ISeqOutStreamPtr outStream, const UInt64 *outDataSize, int finishMode, + // Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + // const Byte *inData, size_t inDataSize, + UInt64 *inProcessed, + // UInt64 *outProcessed, + int *isMT, + ICompressProgressPtr progress) +{ + // GET_CLzma2DecMt_p + #ifndef Z7_ST + BoolInt tMode; + #endif + + *inProcessed = 0; + + if (prop > 40) + return SZ_ERROR_UNSUPPORTED; + + p->prop = prop; + p->props = *props; + + p->inStream = inStream; + p->outStream = outStream; + p->progress = progress; + + p->outSize = 0; + p->outSize_Defined = False; + if (outDataSize) + { + p->outSize_Defined = True; + p->outSize = *outDataSize; + } + p->finishMode = finishMode; + + p->outProcessed = 0; + p->inProcessed = 0; + + p->readWasFinished = False; + p->readRes = SZ_OK; + + *isMT = False; + + + #ifndef Z7_ST + + tMode = False; + + // p->mtc.parseRes = SZ_OK; + + // p->mtc.numFilledThreads = 0; + // p->mtc.crossStart = 0; + // p->mtc.crossEnd = 0; + // p->mtc.allocError_for_Read_BlockIndex = 0; + // p->mtc.isAllocError = False; + + if (p->props.numThreads > 1) + { + IMtDecCallback2 vt; + + Lzma2DecMt_FreeSt(p); + + p->outProcessed_Parse = 0; + + if (!p->mtc_WasConstructed) + { + p->mtc_WasConstructed = True; + MtDec_Construct(&p->mtc); + } + + p->mtc.progress = progress; + p->mtc.inStream = inStream; + + // p->outBuf = NULL; + // p->outBufSize = 0; + /* + if (!outStream) + { + // p->outBuf = outBuf; + // p->outBufSize = *outBufSize; + // *outBufSize = 0; + return SZ_ERROR_PARAM; + } + */ + + // p->mtc.inBlockMax = p->props.inBlockMax; + p->mtc.alloc = &p->alignOffsetAlloc.vt; + // p->alignOffsetAlloc.baseAlloc; + // p->mtc.inData = inData; + // p->mtc.inDataSize = inDataSize; + p->mtc.mtCallback = &vt; + p->mtc.mtCallbackObject = p; + + p->mtc.inBufSize = p->props.inBufSize_MT; + + p->mtc.numThreadsMax = p->props.numThreads; + + *isMT = True; + + vt.Parse = Lzma2DecMt_MtCallback_Parse; + vt.PreCode = Lzma2DecMt_MtCallback_PreCode; + vt.Code = Lzma2DecMt_MtCallback_Code; + vt.Write = Lzma2DecMt_MtCallback_Write; + + { + BoolInt needContinue = False; + + SRes res = MtDec_Code(&p->mtc); + + /* + if (!outStream) + *outBufSize = p->outBuf - outBuf; + */ + + *inProcessed = p->mtc.inProcessed; + + needContinue = False; + + if (res == SZ_OK) + { + if (p->mtc.mtProgress.res != SZ_OK) + res = p->mtc.mtProgress.res; + else + needContinue = p->mtc.needContinue; + } + + if (!needContinue) + { + if (res == SZ_OK) + return p->mtc.readRes; + return res; + } + + tMode = True; + p->readRes = p->mtc.readRes; + p->readWasFinished = p->mtc.readWasFinished; + p->inProcessed = p->mtc.inProcessed; + + PRF_STR("----- decoding ST -----") + } + } + + #endif + + + *isMT = False; + + { + SRes res = Lzma2Dec_Decode_ST(p + #ifndef Z7_ST + , tMode + #endif + ); + + *inProcessed = p->inProcessed; + + // res = SZ_OK; // for test + if (res == SZ_ERROR_INPUT_EOF) + { + if (p->readRes != SZ_OK) + res = p->readRes; + } + else if (res == SZ_OK && p->readRes != SZ_OK) + res = p->readRes; + + /* + #ifndef Z7_ST + if (res == SZ_OK && tMode && p->mtc.parseRes != SZ_OK) + res = p->mtc.parseRes; + #endif + */ + + return res; + } +} + + +/* ---------- Read from CLzma2DecMtHandle Interface ---------- */ + +SRes Lzma2DecMt_Init(CLzma2DecMtHandle p, + Byte prop, + const CLzma2DecMtProps *props, + const UInt64 *outDataSize, int finishMode, + ISeqInStreamPtr inStream) +{ + // GET_CLzma2DecMt_p + + if (prop > 40) + return SZ_ERROR_UNSUPPORTED; + + p->prop = prop; + p->props = *props; + + p->inStream = inStream; + + p->outSize = 0; + p->outSize_Defined = False; + if (outDataSize) + { + p->outSize_Defined = True; + p->outSize = *outDataSize; + } + p->finishMode = finishMode; + + p->outProcessed = 0; + p->inProcessed = 0; + + p->inPos = 0; + p->inLim = 0; + + return Lzma2Dec_Prepare_ST(p); +} + + +SRes Lzma2DecMt_Read(CLzma2DecMtHandle p, + Byte *data, size_t *outSize, + UInt64 *inStreamProcessed) +{ + // GET_CLzma2DecMt_p + ELzmaFinishMode finishMode; + SRes readRes; + size_t size = *outSize; + + *outSize = 0; + *inStreamProcessed = 0; + + finishMode = LZMA_FINISH_ANY; + if (p->outSize_Defined) + { + const UInt64 rem = p->outSize - p->outProcessed; + if (size >= rem) + { + size = (size_t)rem; + if (p->finishMode) + finishMode = LZMA_FINISH_END; + } + } + + readRes = SZ_OK; + + for (;;) + { + SizeT inCur; + SizeT outCur; + ELzmaStatus status; + SRes res; + + if (p->inPos == p->inLim && readRes == SZ_OK) + { + p->inPos = 0; + p->inLim = p->props.inBufSize_ST; + readRes = ISeqInStream_Read(p->inStream, p->inBuf, &p->inLim); + } + + inCur = (SizeT)(p->inLim - p->inPos); + outCur = (SizeT)size; + + res = Lzma2Dec_DecodeToBuf(&p->dec, data, &outCur, + p->inBuf + p->inPos, &inCur, finishMode, &status); + + p->inPos += inCur; + p->inProcessed += inCur; + *inStreamProcessed += inCur; + p->outProcessed += outCur; + *outSize += outCur; + size -= outCur; + data += outCur; + + if (res != 0) + return res; + + /* + if (status == LZMA_STATUS_FINISHED_WITH_MARK) + return readRes; + + if (size == 0 && status != LZMA_STATUS_NEEDS_MORE_INPUT) + { + if (p->finishMode && p->outSize_Defined && p->outProcessed >= p->outSize) + return SZ_ERROR_DATA; + return readRes; + } + */ + + if (inCur == 0 && outCur == 0) + return readRes; + } +} + +#undef PRF +#undef PRF_STR +#undef PRF_STR_INT_2 diff --git a/libraries/lzma/C/Lzma2DecMt.h b/libraries/lzma/C/Lzma2DecMt.h new file mode 100644 index 000000000..93a5cd59e --- /dev/null +++ b/libraries/lzma/C/Lzma2DecMt.h @@ -0,0 +1,81 @@ +/* Lzma2DecMt.h -- LZMA2 Decoder Multi-thread +2023-04-13 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA2_DEC_MT_H +#define ZIP7_INC_LZMA2_DEC_MT_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +typedef struct +{ + size_t inBufSize_ST; + size_t outStep_ST; + + #ifndef Z7_ST + unsigned numThreads; + size_t inBufSize_MT; + size_t outBlockMax; + size_t inBlockMax; + #endif +} CLzma2DecMtProps; + +/* init to single-thread mode */ +void Lzma2DecMtProps_Init(CLzma2DecMtProps *p); + + +/* ---------- CLzma2DecMtHandle Interface ---------- */ + +/* Lzma2DecMt_ * functions can return the following exit codes: +SRes: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - ISeqOutStream write callback error + // SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) +*/ + +typedef struct CLzma2DecMt CLzma2DecMt; +typedef CLzma2DecMt * CLzma2DecMtHandle; +// Z7_DECLARE_HANDLE(CLzma2DecMtHandle) + +CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid); +void Lzma2DecMt_Destroy(CLzma2DecMtHandle p); + +SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p, + Byte prop, + const CLzma2DecMtProps *props, + ISeqOutStreamPtr outStream, + const UInt64 *outDataSize, // NULL means undefined + int finishMode, // 0 - partial unpacking is allowed, 1 - if lzma2 stream must be finished + // Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + // const Byte *inData, size_t inDataSize, + + // out variables: + UInt64 *inProcessed, + int *isMT, /* out: (*isMT == 0), if single thread decoding was used */ + + // UInt64 *outProcessed, + ICompressProgressPtr progress); + + +/* ---------- Read from CLzma2DecMtHandle Interface ---------- */ + +SRes Lzma2DecMt_Init(CLzma2DecMtHandle pp, + Byte prop, + const CLzma2DecMtProps *props, + const UInt64 *outDataSize, int finishMode, + ISeqInStreamPtr inStream); + +SRes Lzma2DecMt_Read(CLzma2DecMtHandle pp, + Byte *data, size_t *outSize, + UInt64 *inStreamProcessed); + + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/Lzma2Enc.c b/libraries/lzma/C/Lzma2Enc.c new file mode 100644 index 000000000..703e146b5 --- /dev/null +++ b/libraries/lzma/C/Lzma2Enc.c @@ -0,0 +1,805 @@ +/* Lzma2Enc.c -- LZMA2 Encoder +2023-04-13 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +/* #define Z7_ST */ + +#include "Lzma2Enc.h" + +#ifndef Z7_ST +#include "MtCoder.h" +#else +#define MTCODER_THREADS_MAX 1 +#endif + +#define LZMA2_CONTROL_LZMA (1 << 7) +#define LZMA2_CONTROL_COPY_NO_RESET 2 +#define LZMA2_CONTROL_COPY_RESET_DIC 1 +#define LZMA2_CONTROL_EOF 0 + +#define LZMA2_LCLP_MAX 4 + +#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11)) + +#define LZMA2_PACK_SIZE_MAX (1 << 16) +#define LZMA2_COPY_CHUNK_SIZE LZMA2_PACK_SIZE_MAX +#define LZMA2_UNPACK_SIZE_MAX (1 << 21) +#define LZMA2_KEEP_WINDOW_SIZE LZMA2_UNPACK_SIZE_MAX + +#define LZMA2_CHUNK_SIZE_COMPRESSED_MAX ((1 << 16) + 16) + + +#define PRF(x) /* x */ + + +/* ---------- CLimitedSeqInStream ---------- */ + +typedef struct +{ + ISeqInStream vt; + ISeqInStreamPtr realStream; + UInt64 limit; + UInt64 processed; + int finished; +} CLimitedSeqInStream; + +static void LimitedSeqInStream_Init(CLimitedSeqInStream *p) +{ + p->limit = (UInt64)(Int64)-1; + p->processed = 0; + p->finished = 0; +} + +static SRes LimitedSeqInStream_Read(ISeqInStreamPtr pp, void *data, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLimitedSeqInStream) + size_t size2 = *size; + SRes res = SZ_OK; + + if (p->limit != (UInt64)(Int64)-1) + { + const UInt64 rem = p->limit - p->processed; + if (size2 > rem) + size2 = (size_t)rem; + } + if (size2 != 0) + { + res = ISeqInStream_Read(p->realStream, data, &size2); + p->finished = (size2 == 0 ? 1 : 0); + p->processed += size2; + } + *size = size2; + return res; +} + + +/* ---------- CLzma2EncInt ---------- */ + +typedef struct +{ + CLzmaEncHandle enc; + Byte propsAreSet; + Byte propsByte; + Byte needInitState; + Byte needInitProp; + UInt64 srcPos; +} CLzma2EncInt; + + +static SRes Lzma2EncInt_InitStream(CLzma2EncInt *p, const CLzma2EncProps *props) +{ + if (!p->propsAreSet) + { + SizeT propsSize = LZMA_PROPS_SIZE; + Byte propsEncoded[LZMA_PROPS_SIZE]; + RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps)) + RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize)) + p->propsByte = propsEncoded[0]; + p->propsAreSet = True; + } + return SZ_OK; +} + +static void Lzma2EncInt_InitBlock(CLzma2EncInt *p) +{ + p->srcPos = 0; + p->needInitState = True; + p->needInitProp = True; +} + + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, ISeqInStreamPtr inStream, UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p); +void LzmaEnc_Finish(CLzmaEncHandle p); +void LzmaEnc_SaveState(CLzmaEncHandle p); +void LzmaEnc_RestoreState(CLzmaEncHandle p); + +/* +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle p); +*/ + +static SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf, + size_t *packSizeRes, ISeqOutStreamPtr outStream) +{ + size_t packSizeLimit = *packSizeRes; + size_t packSize = packSizeLimit; + UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX; + unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0); + BoolInt useCopyBlock; + SRes res; + + *packSizeRes = 0; + if (packSize < lzHeaderSize) + return SZ_ERROR_OUTPUT_EOF; + packSize -= lzHeaderSize; + + LzmaEnc_SaveState(p->enc); + res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState, + outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize); + + PRF(printf("\npackSize = %7d unpackSize = %7d ", packSize, unpackSize)); + + if (unpackSize == 0) + return res; + + if (res == SZ_OK) + useCopyBlock = (packSize + 2 >= unpackSize || packSize > (1 << 16)); + else + { + if (res != SZ_ERROR_OUTPUT_EOF) + return res; + res = SZ_OK; + useCopyBlock = True; + } + + if (useCopyBlock) + { + size_t destPos = 0; + PRF(printf("################# COPY ")); + + while (unpackSize > 0) + { + const UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE; + if (packSizeLimit - destPos < u + 3) + return SZ_ERROR_OUTPUT_EOF; + outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET); + outBuf[destPos++] = (Byte)((u - 1) >> 8); + outBuf[destPos++] = (Byte)(u - 1); + memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u); + unpackSize -= u; + destPos += u; + p->srcPos += u; + + if (outStream) + { + *packSizeRes += destPos; + if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos) + return SZ_ERROR_WRITE; + destPos = 0; + } + else + *packSizeRes = destPos; + /* needInitState = True; */ + } + + LzmaEnc_RestoreState(p->enc); + return SZ_OK; + } + + { + size_t destPos = 0; + const UInt32 u = unpackSize - 1; + const UInt32 pm = (UInt32)(packSize - 1); + const unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0); + + PRF(printf(" ")); + + outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F)); + outBuf[destPos++] = (Byte)(u >> 8); + outBuf[destPos++] = (Byte)u; + outBuf[destPos++] = (Byte)(pm >> 8); + outBuf[destPos++] = (Byte)pm; + + if (p->needInitProp) + outBuf[destPos++] = p->propsByte; + + p->needInitProp = False; + p->needInitState = False; + destPos += packSize; + p->srcPos += unpackSize; + + if (outStream) + if (ISeqOutStream_Write(outStream, outBuf, destPos) != destPos) + return SZ_ERROR_WRITE; + + *packSizeRes = destPos; + return SZ_OK; + } +} + + +/* ---------- Lzma2 Props ---------- */ + +void Lzma2EncProps_Init(CLzma2EncProps *p) +{ + LzmaEncProps_Init(&p->lzmaProps); + p->blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO; + p->numBlockThreads_Reduced = -1; + p->numBlockThreads_Max = -1; + p->numTotalThreads = -1; +} + +void Lzma2EncProps_Normalize(CLzma2EncProps *p) +{ + UInt64 fileSize; + int t1, t1n, t2, t2r, t3; + { + CLzmaEncProps lzmaProps = p->lzmaProps; + LzmaEncProps_Normalize(&lzmaProps); + t1n = lzmaProps.numThreads; + } + + t1 = p->lzmaProps.numThreads; + t2 = p->numBlockThreads_Max; + t3 = p->numTotalThreads; + + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; + + if (t3 <= 0) + { + if (t2 <= 0) + t2 = 1; + t3 = t1n * t2; + } + else if (t2 <= 0) + { + t2 = t3 / t1n; + if (t2 == 0) + { + t1 = 1; + t2 = t3; + } + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; + } + else if (t1 <= 0) + { + t1 = t3 / t2; + if (t1 == 0) + t1 = 1; + } + else + t3 = t1n * t2; + + p->lzmaProps.numThreads = t1; + + t2r = t2; + + fileSize = p->lzmaProps.reduceSize; + + if ( p->blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + && p->blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO + && (p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1)) + p->lzmaProps.reduceSize = p->blockSize; + + LzmaEncProps_Normalize(&p->lzmaProps); + + p->lzmaProps.reduceSize = fileSize; + + t1 = p->lzmaProps.numThreads; + + if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) + { + t2r = t2 = 1; + t3 = t1; + } + else if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO && t2 <= 1) + { + /* if there is no block multi-threading, we use SOLID block */ + p->blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID; + } + else + { + if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) + { + const UInt32 kMinSize = (UInt32)1 << 20; + const UInt32 kMaxSize = (UInt32)1 << 28; + const UInt32 dictSize = p->lzmaProps.dictSize; + UInt64 blockSize = (UInt64)dictSize << 2; + if (blockSize < kMinSize) blockSize = kMinSize; + if (blockSize > kMaxSize) blockSize = kMaxSize; + if (blockSize < dictSize) blockSize = dictSize; + blockSize += (kMinSize - 1); + blockSize &= ~(UInt64)(kMinSize - 1); + p->blockSize = blockSize; + } + + if (t2 > 1 && fileSize != (UInt64)(Int64)-1) + { + UInt64 numBlocks = fileSize / p->blockSize; + if (numBlocks * p->blockSize != fileSize) + numBlocks++; + if (numBlocks < (unsigned)t2) + { + t2r = (int)numBlocks; + if (t2r == 0) + t2r = 1; + t3 = t1 * t2r; + } + } + } + + p->numBlockThreads_Max = t2; + p->numBlockThreads_Reduced = t2r; + p->numTotalThreads = t3; +} + + +static SRes Progress(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize) +{ + return (p && ICompressProgress_Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK; +} + + +/* ---------- Lzma2 ---------- */ + +struct CLzma2Enc +{ + Byte propEncoded; + CLzma2EncProps props; + UInt64 expectedDataSize; + + Byte *tempBufLzma; + + ISzAllocPtr alloc; + ISzAllocPtr allocBig; + + CLzma2EncInt coders[MTCODER_THREADS_MAX]; + + #ifndef Z7_ST + + ISeqOutStreamPtr outStream; + Byte *outBuf; + size_t outBuf_Rem; /* remainder in outBuf */ + + size_t outBufSize; /* size of allocated outBufs[i] */ + size_t outBufsDataSizes[MTCODER_BLOCKS_MAX]; + BoolInt mtCoder_WasConstructed; + CMtCoder mtCoder; + Byte *outBufs[MTCODER_BLOCKS_MAX]; + + #endif +}; + + + +CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CLzma2Enc *p = (CLzma2Enc *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Enc)); + if (!p) + return NULL; + Lzma2EncProps_Init(&p->props); + Lzma2EncProps_Normalize(&p->props); + p->expectedDataSize = (UInt64)(Int64)-1; + p->tempBufLzma = NULL; + p->alloc = alloc; + p->allocBig = allocBig; + { + unsigned i; + for (i = 0; i < MTCODER_THREADS_MAX; i++) + p->coders[i].enc = NULL; + } + + #ifndef Z7_ST + p->mtCoder_WasConstructed = False; + { + unsigned i; + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + p->outBufs[i] = NULL; + p->outBufSize = 0; + } + #endif + + return (CLzma2EncHandle)p; +} + + +#ifndef Z7_ST + +static void Lzma2Enc_FreeOutBufs(CLzma2Enc *p) +{ + unsigned i; + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + if (p->outBufs[i]) + { + ISzAlloc_Free(p->alloc, p->outBufs[i]); + p->outBufs[i] = NULL; + } + p->outBufSize = 0; +} + +#endif + +// #define GET_CLzma2Enc_p CLzma2Enc *p = (CLzma2Enc *)(void *)p; + +void Lzma2Enc_Destroy(CLzma2EncHandle p) +{ + // GET_CLzma2Enc_p + unsigned i; + for (i = 0; i < MTCODER_THREADS_MAX; i++) + { + CLzma2EncInt *t = &p->coders[i]; + if (t->enc) + { + LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig); + t->enc = NULL; + } + } + + + #ifndef Z7_ST + if (p->mtCoder_WasConstructed) + { + MtCoder_Destruct(&p->mtCoder); + p->mtCoder_WasConstructed = False; + } + Lzma2Enc_FreeOutBufs(p); + #endif + + ISzAlloc_Free(p->alloc, p->tempBufLzma); + p->tempBufLzma = NULL; + + ISzAlloc_Free(p->alloc, p); +} + + +SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props) +{ + // GET_CLzma2Enc_p + CLzmaEncProps lzmaProps = props->lzmaProps; + LzmaEncProps_Normalize(&lzmaProps); + if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX) + return SZ_ERROR_PARAM; + p->props = *props; + Lzma2EncProps_Normalize(&p->props); + return SZ_OK; +} + + +void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize) +{ + // GET_CLzma2Enc_p + p->expectedDataSize = expectedDataSiize; +} + + +Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p) +{ + // GET_CLzma2Enc_p + unsigned i; + UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps); + for (i = 0; i < 40; i++) + if (dicSize <= LZMA2_DIC_SIZE_FROM_PROP(i)) + break; + return (Byte)i; +} + + +static SRes Lzma2Enc_EncodeMt1( + CLzma2Enc *me, + CLzma2EncInt *p, + ISeqOutStreamPtr outStream, + Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + const Byte *inData, size_t inDataSize, + int finished, + ICompressProgressPtr progress) +{ + UInt64 unpackTotal = 0; + UInt64 packTotal = 0; + size_t outLim = 0; + CLimitedSeqInStream limitedInStream; + + if (outBuf) + { + outLim = *outBufSize; + *outBufSize = 0; + } + + if (!p->enc) + { + p->propsAreSet = False; + p->enc = LzmaEnc_Create(me->alloc); + if (!p->enc) + return SZ_ERROR_MEM; + } + + limitedInStream.realStream = inStream; + if (inStream) + { + limitedInStream.vt.Read = LimitedSeqInStream_Read; + } + + if (!outBuf) + { + // outStream version works only in one thread. So we use CLzma2Enc::tempBufLzma + if (!me->tempBufLzma) + { + me->tempBufLzma = (Byte *)ISzAlloc_Alloc(me->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX); + if (!me->tempBufLzma) + return SZ_ERROR_MEM; + } + } + + RINOK(Lzma2EncInt_InitStream(p, &me->props)) + + for (;;) + { + SRes res = SZ_OK; + SizeT inSizeCur = 0; + + Lzma2EncInt_InitBlock(p); + + LimitedSeqInStream_Init(&limitedInStream); + limitedInStream.limit = me->props.blockSize; + + if (inStream) + { + UInt64 expected = (UInt64)(Int64)-1; + // inStream version works only in one thread. So we use CLzma2Enc::expectedDataSize + if (me->expectedDataSize != (UInt64)(Int64)-1 + && me->expectedDataSize >= unpackTotal) + expected = me->expectedDataSize - unpackTotal; + if (me->props.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + && expected > me->props.blockSize) + expected = (size_t)me->props.blockSize; + + LzmaEnc_SetDataSize(p->enc, expected); + + RINOK(LzmaEnc_PrepareForLzma2(p->enc, + &limitedInStream.vt, + LZMA2_KEEP_WINDOW_SIZE, + me->alloc, + me->allocBig)) + } + else + { + inSizeCur = (SizeT)(inDataSize - (size_t)unpackTotal); + if (me->props.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + && inSizeCur > me->props.blockSize) + inSizeCur = (SizeT)(size_t)me->props.blockSize; + + // LzmaEnc_SetDataSize(p->enc, inSizeCur); + + RINOK(LzmaEnc_MemPrepare(p->enc, + inData + (size_t)unpackTotal, inSizeCur, + LZMA2_KEEP_WINDOW_SIZE, + me->alloc, + me->allocBig)) + } + + for (;;) + { + size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX; + if (outBuf) + packSize = outLim - (size_t)packTotal; + + res = Lzma2EncInt_EncodeSubblock(p, + outBuf ? outBuf + (size_t)packTotal : me->tempBufLzma, &packSize, + outBuf ? NULL : outStream); + + if (res != SZ_OK) + break; + + packTotal += packSize; + if (outBuf) + *outBufSize = (size_t)packTotal; + + res = Progress(progress, unpackTotal + p->srcPos, packTotal); + if (res != SZ_OK) + break; + + /* + if (LzmaEnc_GetNumAvailableBytes(p->enc) == 0) + break; + */ + + if (packSize == 0) + break; + } + + LzmaEnc_Finish(p->enc); + + unpackTotal += p->srcPos; + + RINOK(res) + + if (p->srcPos != (inStream ? limitedInStream.processed : inSizeCur)) + return SZ_ERROR_FAIL; + + if (inStream ? limitedInStream.finished : (unpackTotal == inDataSize)) + { + if (finished) + { + if (outBuf) + { + const size_t destPos = *outBufSize; + if (destPos >= outLim) + return SZ_ERROR_OUTPUT_EOF; + outBuf[destPos] = LZMA2_CONTROL_EOF; // 0 + *outBufSize = destPos + 1; + } + else + { + const Byte b = LZMA2_CONTROL_EOF; // 0; + if (ISeqOutStream_Write(outStream, &b, 1) != 1) + return SZ_ERROR_WRITE; + } + } + return SZ_OK; + } + } +} + + + +#ifndef Z7_ST + +static SRes Lzma2Enc_MtCallback_Code(void *p, unsigned coderIndex, unsigned outBufIndex, + const Byte *src, size_t srcSize, int finished) +{ + CLzma2Enc *me = (CLzma2Enc *)p; + size_t destSize = me->outBufSize; + SRes res; + CMtProgressThunk progressThunk; + + Byte *dest = me->outBufs[outBufIndex]; + + me->outBufsDataSizes[outBufIndex] = 0; + + if (!dest) + { + dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize); + if (!dest) + return SZ_ERROR_MEM; + me->outBufs[outBufIndex] = dest; + } + + MtProgressThunk_CreateVTable(&progressThunk); + progressThunk.mtProgress = &me->mtCoder.mtProgress; + progressThunk.inSize = 0; + progressThunk.outSize = 0; + + res = Lzma2Enc_EncodeMt1(me, + &me->coders[coderIndex], + NULL, dest, &destSize, + NULL, src, srcSize, + finished, + &progressThunk.vt); + + me->outBufsDataSizes[outBufIndex] = destSize; + + return res; +} + + +static SRes Lzma2Enc_MtCallback_Write(void *p, unsigned outBufIndex) +{ + CLzma2Enc *me = (CLzma2Enc *)p; + size_t size = me->outBufsDataSizes[outBufIndex]; + const Byte *data = me->outBufs[outBufIndex]; + + if (me->outStream) + return ISeqOutStream_Write(me->outStream, data, size) == size ? SZ_OK : SZ_ERROR_WRITE; + + if (size > me->outBuf_Rem) + return SZ_ERROR_OUTPUT_EOF; + memcpy(me->outBuf, data, size); + me->outBuf_Rem -= size; + me->outBuf += size; + return SZ_OK; +} + +#endif + + + +SRes Lzma2Enc_Encode2(CLzma2EncHandle p, + ISeqOutStreamPtr outStream, + Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + const Byte *inData, size_t inDataSize, + ICompressProgressPtr progress) +{ + // GET_CLzma2Enc_p + + if (inStream && inData) + return SZ_ERROR_PARAM; + + if (outStream && outBuf) + return SZ_ERROR_PARAM; + + { + unsigned i; + for (i = 0; i < MTCODER_THREADS_MAX; i++) + p->coders[i].propsAreSet = False; + } + + #ifndef Z7_ST + + if (p->props.numBlockThreads_Reduced > 1) + { + IMtCoderCallback2 vt; + + if (!p->mtCoder_WasConstructed) + { + p->mtCoder_WasConstructed = True; + MtCoder_Construct(&p->mtCoder); + } + + vt.Code = Lzma2Enc_MtCallback_Code; + vt.Write = Lzma2Enc_MtCallback_Write; + + p->outStream = outStream; + p->outBuf = NULL; + p->outBuf_Rem = 0; + if (!outStream) + { + p->outBuf = outBuf; + p->outBuf_Rem = *outBufSize; + *outBufSize = 0; + } + + p->mtCoder.allocBig = p->allocBig; + p->mtCoder.progress = progress; + p->mtCoder.inStream = inStream; + p->mtCoder.inData = inData; + p->mtCoder.inDataSize = inDataSize; + p->mtCoder.mtCallback = &vt; + p->mtCoder.mtCallbackObject = p; + + p->mtCoder.blockSize = (size_t)p->props.blockSize; + if (p->mtCoder.blockSize != p->props.blockSize) + return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */ + + { + const size_t destBlockSize = p->mtCoder.blockSize + (p->mtCoder.blockSize >> 10) + 16; + if (destBlockSize < p->mtCoder.blockSize) + return SZ_ERROR_PARAM; + if (p->outBufSize != destBlockSize) + Lzma2Enc_FreeOutBufs(p); + p->outBufSize = destBlockSize; + } + + p->mtCoder.numThreadsMax = (unsigned)p->props.numBlockThreads_Max; + p->mtCoder.expectedDataSize = p->expectedDataSize; + + { + const SRes res = MtCoder_Code(&p->mtCoder); + if (!outStream) + *outBufSize = (size_t)(p->outBuf - outBuf); + return res; + } + } + + #endif + + + return Lzma2Enc_EncodeMt1(p, + &p->coders[0], + outStream, outBuf, outBufSize, + inStream, inData, inDataSize, + True, /* finished */ + progress); +} + +#undef PRF diff --git a/libraries/lzma/C/Lzma2Enc.h b/libraries/lzma/C/Lzma2Enc.h new file mode 100644 index 000000000..cb25275c6 --- /dev/null +++ b/libraries/lzma/C/Lzma2Enc.h @@ -0,0 +1,57 @@ +/* Lzma2Enc.h -- LZMA2 Encoder +2023-04-13 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA2_ENC_H +#define ZIP7_INC_LZMA2_ENC_H + +#include "LzmaEnc.h" + +EXTERN_C_BEGIN + +#define LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO 0 +#define LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID ((UInt64)(Int64)-1) + +typedef struct +{ + CLzmaEncProps lzmaProps; + UInt64 blockSize; + int numBlockThreads_Reduced; + int numBlockThreads_Max; + int numTotalThreads; +} CLzma2EncProps; + +void Lzma2EncProps_Init(CLzma2EncProps *p); +void Lzma2EncProps_Normalize(CLzma2EncProps *p); + +/* ---------- CLzmaEnc2Handle Interface ---------- */ + +/* Lzma2Enc_* functions can return the following exit codes: +SRes: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater in props + SZ_ERROR_WRITE - ISeqOutStream write callback error + SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) +*/ + +typedef struct CLzma2Enc CLzma2Enc; +typedef CLzma2Enc * CLzma2EncHandle; +// Z7_DECLARE_HANDLE(CLzma2EncHandle) + +CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig); +void Lzma2Enc_Destroy(CLzma2EncHandle p); +SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props); +void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize); +Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p); +SRes Lzma2Enc_Encode2(CLzma2EncHandle p, + ISeqOutStreamPtr outStream, + Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + const Byte *inData, size_t inDataSize, + ICompressProgressPtr progress); + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/Lzma86.h b/libraries/lzma/C/Lzma86.h new file mode 100644 index 000000000..e7707e2c4 --- /dev/null +++ b/libraries/lzma/C/Lzma86.h @@ -0,0 +1,111 @@ +/* Lzma86.h -- LZMA + x86 (BCJ) Filter +2023-03-03 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA86_H +#define ZIP7_INC_LZMA86_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define LZMA86_SIZE_OFFSET (1 + 5) +#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) + +/* +It's an example for LZMA + x86 Filter use. +You can use .lzma86 extension, if you write that stream to file. +.lzma86 header adds one additional byte to standard .lzma header. +.lzma86 header (14 bytes): + Offset Size Description + 0 1 = 0 - no filter, pure LZMA + = 1 - x86 filter + LZMA + 1 1 lc, lp and pb in encoded form + 2 4 dictSize (little endian) + 6 8 uncompressed size (little endian) + + +Lzma86_Encode +------------- +level - compression level: 0 <= level <= 9, the default value for "level" is 5. + +dictSize - The dictionary size in bytes. The maximum value is + 128 MB = (1 << 27) bytes for 32-bit version + 1 GB = (1 << 30) bytes for 64-bit version + The default value is 16 MB = (1 << 24) bytes, for level = 5. + It's recommended to use the dictionary that is larger than 4 KB and + that can be calculated as (1 << N) or (3 << N) sizes. + For better compression ratio dictSize must be >= inSize. + +filterMode: + SZ_FILTER_NO - no Filter + SZ_FILTER_YES - x86 Filter + SZ_FILTER_AUTO - it tries both alternatives to select best. + Encoder will use 2 or 3 passes: + 2 passes when FILTER_NO provides better compression. + 3 passes when FILTER_YES provides better compression. + +Lzma86Encode allocates Data with MyAlloc functions. +RAM Requirements for compressing: + RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize + filterMode FilterBlockSize + SZ_FILTER_NO 0 + SZ_FILTER_YES inSize + SZ_FILTER_AUTO inSize + + +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +enum ESzFilterMode +{ + SZ_FILTER_NO, + SZ_FILTER_YES, + SZ_FILTER_AUTO +}; + +SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, + int level, UInt32 dictSize, int filterMode); + + +/* +Lzma86_GetUnpackSize: + In: + src - input data + srcLen - input data size + Out: + unpackSize - size of uncompressed stream + Return code: + SZ_OK - OK + SZ_ERROR_INPUT_EOF - Error in headers +*/ + +SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize); + +/* +Lzma86_Decode: + In: + dest - output data + destLen - output data size + src - input data + srcLen - input data size + Out: + destLen - processed output size + srcLen - processed input size + Return code: + SZ_OK - OK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - unsupported file + SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer +*/ + +SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen); + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/Lzma86Dec.c b/libraries/lzma/C/Lzma86Dec.c new file mode 100644 index 000000000..f094d4c35 --- /dev/null +++ b/libraries/lzma/C/Lzma86Dec.c @@ -0,0 +1,53 @@ +/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder +2023-03-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Lzma86.h" + +#include "Alloc.h" +#include "Bra.h" +#include "LzmaDec.h" + +SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) +{ + unsigned i; + if (srcLen < LZMA86_HEADER_SIZE) + return SZ_ERROR_INPUT_EOF; + *unpackSize = 0; + for (i = 0; i < sizeof(UInt64); i++) + *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i); + return SZ_OK; +} + +SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) +{ + SRes res; + int useFilter; + SizeT inSizePure; + ELzmaStatus status; + + if (*srcLen < LZMA86_HEADER_SIZE) + return SZ_ERROR_INPUT_EOF; + + useFilter = src[0]; + + if (useFilter > 1) + { + *destLen = 0; + return SZ_ERROR_UNSUPPORTED; + } + + inSizePure = *srcLen - LZMA86_HEADER_SIZE; + res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, + src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); + *srcLen = inSizePure + LZMA86_HEADER_SIZE; + if (res != SZ_OK) + return res; + if (useFilter == 1) + { + UInt32 x86State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + z7_BranchConvSt_X86_Dec(dest, *destLen, 0, &x86State); + } + return SZ_OK; +} diff --git a/libraries/lzma/C/Lzma86Enc.c b/libraries/lzma/C/Lzma86Enc.c new file mode 100644 index 000000000..0cdde1c9a --- /dev/null +++ b/libraries/lzma/C/Lzma86Enc.c @@ -0,0 +1,103 @@ +/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder +2023-03-03 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "Lzma86.h" + +#include "Alloc.h" +#include "Bra.h" +#include "LzmaEnc.h" + +int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, + int level, UInt32 dictSize, int filterMode) +{ + size_t outSize2 = *destLen; + Byte *filteredStream; + BoolInt useFilter; + int mainResult = SZ_ERROR_OUTPUT_EOF; + CLzmaEncProps props; + LzmaEncProps_Init(&props); + props.level = level; + props.dictSize = dictSize; + + *destLen = 0; + if (outSize2 < LZMA86_HEADER_SIZE) + return SZ_ERROR_OUTPUT_EOF; + + { + int i; + UInt64 t = srcLen; + for (i = 0; i < 8; i++, t >>= 8) + dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; + } + + filteredStream = 0; + useFilter = (filterMode != SZ_FILTER_NO); + if (useFilter) + { + if (srcLen != 0) + { + filteredStream = (Byte *)MyAlloc(srcLen); + if (filteredStream == 0) + return SZ_ERROR_MEM; + memcpy(filteredStream, src, srcLen); + } + { + UInt32 x86State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + z7_BranchConvSt_X86_Enc(filteredStream, srcLen, 0, &x86State); + } + } + + { + size_t minSize = 0; + BoolInt bestIsFiltered = False; + + /* passes for SZ_FILTER_AUTO: + 0 - BCJ + LZMA + 1 - LZMA + 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. + */ + int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; + + int i; + for (i = 0; i < numPasses; i++) + { + size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; + size_t outPropsSize = 5; + SRes curRes; + BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); + if (curModeIsFiltered && !bestIsFiltered) + break; + if (useFilter && i == 0) + curModeIsFiltered = True; + + curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, + curModeIsFiltered ? filteredStream : src, srcLen, + &props, dest + 1, &outPropsSize, 0, + NULL, &g_Alloc, &g_Alloc); + + if (curRes != SZ_ERROR_OUTPUT_EOF) + { + if (curRes != SZ_OK) + { + mainResult = curRes; + break; + } + if (outSizeProcessed <= minSize || mainResult != SZ_OK) + { + minSize = outSizeProcessed; + bestIsFiltered = curModeIsFiltered; + mainResult = SZ_OK; + } + } + } + dest[0] = (Byte)(bestIsFiltered ? 1 : 0); + *destLen = LZMA86_HEADER_SIZE + minSize; + } + if (useFilter) + MyFree(filteredStream); + return mainResult; +} diff --git a/libraries/lzma/C/LzmaDec.c b/libraries/lzma/C/LzmaDec.c index d6742e5af..69bb8bba9 100644 --- a/libraries/lzma/C/LzmaDec.c +++ b/libraries/lzma/C/LzmaDec.c @@ -1,5 +1,5 @@ /* LzmaDec.c -- LZMA Decoder -2021-04-01 : Igor Pavlov : Public domain */ +2023-04-07 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -8,15 +8,15 @@ /* #include "CpuArch.h" */ #include "LzmaDec.h" -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) +// #define kNumTopBits 24 +#define kTopValue ((UInt32)1 << 24) #define kNumBitModelTotalBits 11 #define kBitModelTotal (1 << kNumBitModelTotalBits) #define RC_INIT_SIZE 5 -#ifndef _LZMA_DEC_OPT +#ifndef Z7_LZMA_DEC_OPT #define kNumMoveBits 5 #define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } @@ -25,14 +25,14 @@ #define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); #define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ - { UPDATE_0(p); i = (i + i); A0; } else \ - { UPDATE_1(p); i = (i + i) + 1; A1; } + { UPDATE_0(p) i = (i + i); A0; } else \ + { UPDATE_1(p) i = (i + i) + 1; A1; } #define TREE_GET_BIT(probs, i) { GET_BIT2(probs + i, i, ;, ;); } #define REV_BIT(p, i, A0, A1) IF_BIT_0(p + i) \ - { UPDATE_0(p + i); A0; } else \ - { UPDATE_1(p + i); A1; } + { UPDATE_0(p + i) A0; } else \ + { UPDATE_1(p + i) A1; } #define REV_BIT_VAR( p, i, m) REV_BIT(p, i, i += m; m += m, m += m; i += m; ) #define REV_BIT_CONST(p, i, m) REV_BIT(p, i, i += m; , i += m * 2; ) #define REV_BIT_LAST( p, i, m) REV_BIT(p, i, i -= m , ; ) @@ -40,19 +40,19 @@ #define TREE_DECODE(probs, limit, i) \ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } -/* #define _LZMA_SIZE_OPT */ +/* #define Z7_LZMA_SIZE_OPT */ -#ifdef _LZMA_SIZE_OPT +#ifdef Z7_LZMA_SIZE_OPT #define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) #else #define TREE_6_DECODE(probs, i) \ { i = 1; \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ + TREE_GET_BIT(probs, i) \ i -= 0x40; } #endif @@ -64,25 +64,25 @@ probLit = prob + (offs + bit + symbol); \ GET_BIT2(probLit, symbol, offs ^= bit; , ;) -#endif // _LZMA_DEC_OPT +#endif // Z7_LZMA_DEC_OPT #define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_INPUT_EOF; range <<= 8; code = (code << 8) | (*buf++); } -#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK bound = (range >> kNumBitModelTotalBits) * (UInt32)ttt; if (code < bound) #define UPDATE_0_CHECK range = bound; #define UPDATE_1_CHECK range -= bound; code -= bound; #define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ - { UPDATE_0_CHECK; i = (i + i); A0; } else \ - { UPDATE_1_CHECK; i = (i + i) + 1; A1; } + { UPDATE_0_CHECK i = (i + i); A0; } else \ + { UPDATE_1_CHECK i = (i + i) + 1; A1; } #define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) #define TREE_DECODE_CHECK(probs, limit, i) \ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } #define REV_BIT_CHECK(p, i, m) IF_BIT_0_CHECK(p + i) \ - { UPDATE_0_CHECK; i += m; m += m; } else \ - { UPDATE_1_CHECK; m += m; i += m; } + { UPDATE_0_CHECK i += m; m += m; } else \ + { UPDATE_1_CHECK m += m; i += m; } #define kNumPosBitsMax 4 @@ -224,14 +224,14 @@ Out: */ -#ifdef _LZMA_DEC_OPT +#ifdef Z7_LZMA_DEC_OPT -int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit); +int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit); #else static -int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +int Z7_FASTCALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit) { CLzmaProb *probs = GET_PROBS; unsigned state = (unsigned)p->state; @@ -263,7 +263,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit IF_BIT_0(prob) { unsigned symbol; - UPDATE_0(prob); + UPDATE_0(prob) prob = probs + Literal; if (processedPos != 0 || checkDicSize != 0) prob += (UInt32)3 * ((((processedPos << 8) + dic[(dicPos == 0 ? dicBufSize : dicPos) - 1]) & lpMask) << lc); @@ -273,7 +273,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit { state -= (state < 4) ? state : 3; symbol = 1; - #ifdef _LZMA_SIZE_OPT + #ifdef Z7_LZMA_SIZE_OPT do { NORMAL_LITER_DEC } while (symbol < 0x100); #else NORMAL_LITER_DEC @@ -292,7 +292,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit unsigned offs = 0x100; state -= (state < 10) ? 3 : 6; symbol = 1; - #ifdef _LZMA_SIZE_OPT + #ifdef Z7_LZMA_SIZE_OPT do { unsigned bit; @@ -321,25 +321,25 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit } { - UPDATE_1(prob); + UPDATE_1(prob) prob = probs + IsRep + state; IF_BIT_0(prob) { - UPDATE_0(prob); + UPDATE_0(prob) state += kNumStates; prob = probs + LenCoder; } else { - UPDATE_1(prob); + UPDATE_1(prob) prob = probs + IsRepG0 + state; IF_BIT_0(prob) { - UPDATE_0(prob); + UPDATE_0(prob) prob = probs + IsRep0Long + COMBINED_PS_STATE; IF_BIT_0(prob) { - UPDATE_0(prob); + UPDATE_0(prob) // that case was checked before with kBadRepCode // if (checkDicSize == 0 && processedPos == 0) { len = kMatchSpecLen_Error_Data + 1; break; } @@ -353,30 +353,30 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit state = state < kNumLitStates ? 9 : 11; continue; } - UPDATE_1(prob); + UPDATE_1(prob) } else { UInt32 distance; - UPDATE_1(prob); + UPDATE_1(prob) prob = probs + IsRepG1 + state; IF_BIT_0(prob) { - UPDATE_0(prob); + UPDATE_0(prob) distance = rep1; } else { - UPDATE_1(prob); + UPDATE_1(prob) prob = probs + IsRepG2 + state; IF_BIT_0(prob) { - UPDATE_0(prob); + UPDATE_0(prob) distance = rep2; } else { - UPDATE_1(prob); + UPDATE_1(prob) distance = rep3; rep3 = rep2; } @@ -389,37 +389,37 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit prob = probs + RepLenCoder; } - #ifdef _LZMA_SIZE_OPT + #ifdef Z7_LZMA_SIZE_OPT { unsigned lim, offset; CLzmaProb *probLen = prob + LenChoice; IF_BIT_0(probLen) { - UPDATE_0(probLen); + UPDATE_0(probLen) probLen = prob + LenLow + GET_LEN_STATE; offset = 0; lim = (1 << kLenNumLowBits); } else { - UPDATE_1(probLen); + UPDATE_1(probLen) probLen = prob + LenChoice2; IF_BIT_0(probLen) { - UPDATE_0(probLen); + UPDATE_0(probLen) probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); offset = kLenNumLowSymbols; lim = (1 << kLenNumLowBits); } else { - UPDATE_1(probLen); + UPDATE_1(probLen) probLen = prob + LenHigh; offset = kLenNumLowSymbols * 2; lim = (1 << kLenNumHighBits); } } - TREE_DECODE(probLen, lim, len); + TREE_DECODE(probLen, lim, len) len += offset; } #else @@ -427,32 +427,32 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit CLzmaProb *probLen = prob + LenChoice; IF_BIT_0(probLen) { - UPDATE_0(probLen); + UPDATE_0(probLen) probLen = prob + LenLow + GET_LEN_STATE; len = 1; - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) len -= 8; } else { - UPDATE_1(probLen); + UPDATE_1(probLen) probLen = prob + LenChoice2; IF_BIT_0(probLen) { - UPDATE_0(probLen); + UPDATE_0(probLen) probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); len = 1; - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); - TREE_GET_BIT(probLen, len); + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) + TREE_GET_BIT(probLen, len) } else { - UPDATE_1(probLen); + UPDATE_1(probLen) probLen = prob + LenHigh; - TREE_DECODE(probLen, (1 << kLenNumHighBits), len); + TREE_DECODE(probLen, (1 << kLenNumHighBits), len) len += kLenNumLowSymbols * 2; } } @@ -464,7 +464,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit UInt32 distance; prob = probs + PosSlot + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); - TREE_6_DECODE(prob, distance); + TREE_6_DECODE(prob, distance) if (distance >= kStartPosModelIndex) { unsigned posSlot = (unsigned)distance; @@ -479,7 +479,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit distance++; do { - REV_BIT_VAR(prob, distance, m); + REV_BIT_VAR(prob, distance, m) } while (--numDirectBits); distance -= m; @@ -514,10 +514,10 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit distance <<= kNumAlignBits; { unsigned i = 1; - REV_BIT_CONST(prob, i, 1); - REV_BIT_CONST(prob, i, 2); - REV_BIT_CONST(prob, i, 4); - REV_BIT_LAST (prob, i, 8); + REV_BIT_CONST(prob, i, 1) + REV_BIT_CONST(prob, i, 2) + REV_BIT_CONST(prob, i, 4) + REV_BIT_LAST (prob, i, 8) distance |= i; } if (distance == (UInt32)0xFFFFFFFF) @@ -592,7 +592,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit } while (dicPos < limit && buf < bufLimit); - NORMALIZE; + NORMALIZE p->buf = buf; p->range = range; @@ -613,7 +613,7 @@ int MY_FAST_CALL LZMA_DECODE_REAL(CLzmaDec *p, SizeT limit, const Byte *bufLimit -static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) +static void Z7_FASTCALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) { unsigned len = (unsigned)p->remainLen; if (len == 0 /* || len >= kMatchSpecLenStart */) @@ -683,7 +683,7 @@ and we support the following state of (p->checkDicSize): (p->checkDicSize == p->prop.dicSize) */ -static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) +static int Z7_FASTCALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) { if (p->checkDicSize == 0) { @@ -767,54 +767,54 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byt else { unsigned len; - UPDATE_1_CHECK; + UPDATE_1_CHECK prob = probs + IsRep + state; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK state = 0; prob = probs + LenCoder; res = DUMMY_MATCH; } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK res = DUMMY_REP; prob = probs + IsRepG0 + state; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK prob = probs + IsRep0Long + COMBINED_PS_STATE; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK break; } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK } } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK prob = probs + IsRepG1 + state; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK prob = probs + IsRepG2 + state; IF_BIT_0_CHECK(prob) { - UPDATE_0_CHECK; + UPDATE_0_CHECK } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK } } } @@ -826,31 +826,31 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byt const CLzmaProb *probLen = prob + LenChoice; IF_BIT_0_CHECK(probLen) { - UPDATE_0_CHECK; + UPDATE_0_CHECK probLen = prob + LenLow + GET_LEN_STATE; offset = 0; limit = 1 << kLenNumLowBits; } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK probLen = prob + LenChoice2; IF_BIT_0_CHECK(probLen) { - UPDATE_0_CHECK; + UPDATE_0_CHECK probLen = prob + LenLow + GET_LEN_STATE + (1 << kLenNumLowBits); offset = kLenNumLowSymbols; limit = 1 << kLenNumLowBits; } else { - UPDATE_1_CHECK; + UPDATE_1_CHECK probLen = prob + LenHigh; offset = kLenNumLowSymbols * 2; limit = 1 << kLenNumHighBits; } } - TREE_DECODE_CHECK(probLen, limit, len); + TREE_DECODE_CHECK(probLen, limit, len) len += offset; } @@ -860,7 +860,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byt prob = probs + PosSlot + ((len < kNumLenToPosStates - 1 ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); - TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot) if (posSlot >= kStartPosModelIndex) { unsigned numDirectBits = ((posSlot >> 1) - 1); @@ -888,7 +888,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byt unsigned m = 1; do { - REV_BIT_CHECK(prob, i, m); + REV_BIT_CHECK(prob, i, m) } while (--numDirectBits); } @@ -897,7 +897,7 @@ static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, const Byt } break; } - NORMALIZE_CHECK; + NORMALIZE_CHECK *bufOut = buf; return res; @@ -943,7 +943,7 @@ When the decoder lookahead, and the lookahead symbol is not end_marker, we have */ -#define RETURN__NOT_FINISHED__FOR_FINISH \ +#define RETURN_NOT_FINISHED_FOR_FINISH \ *status = LZMA_STATUS_NOT_FINISHED; \ return SZ_ERROR_DATA; // for strict mode // return SZ_OK; // for relaxed mode @@ -1029,7 +1029,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr } if (p->remainLen != 0) { - RETURN__NOT_FINISHED__FOR_FINISH; + RETURN_NOT_FINISHED_FOR_FINISH } checkEndMarkNow = 1; } @@ -1072,7 +1072,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr for (i = 0; i < (unsigned)dummyProcessed; i++) p->tempBuf[i] = src[i]; // p->remainLen = kMatchSpecLen_Error_Data; - RETURN__NOT_FINISHED__FOR_FINISH; + RETURN_NOT_FINISHED_FOR_FINISH } bufLimit = src; @@ -1150,7 +1150,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *sr (*srcLen) += (unsigned)dummyProcessed - p->tempBufSize; p->tempBufSize = (unsigned)dummyProcessed; // p->remainLen = kMatchSpecLen_Error_Data; - RETURN__NOT_FINISHED__FOR_FINISH; + RETURN_NOT_FINISHED_FOR_FINISH } } @@ -1299,8 +1299,8 @@ static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAl SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc) { CLzmaProps propNew; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + RINOK(LzmaProps_Decode(&propNew, props, propsSize)) + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)) p->prop = propNew; return SZ_OK; } @@ -1309,14 +1309,14 @@ SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAll { CLzmaProps propNew; SizeT dicBufSize; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + RINOK(LzmaProps_Decode(&propNew, props, propsSize)) + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)) { UInt32 dictSize = propNew.dicSize; SizeT mask = ((UInt32)1 << 12) - 1; if (dictSize >= ((UInt32)1 << 30)) mask = ((UInt32)1 << 22) - 1; - else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1;; + else if (dictSize >= ((UInt32)1 << 22)) mask = ((UInt32)1 << 20) - 1; dicBufSize = ((SizeT)dictSize + mask) & ~mask; if (dicBufSize < dictSize) dicBufSize = dictSize; @@ -1348,8 +1348,8 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, *status = LZMA_STATUS_NOT_SPECIFIED; if (inSize < RC_INIT_SIZE) return SZ_ERROR_INPUT_EOF; - LzmaDec_Construct(&p); - RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)); + LzmaDec_CONSTRUCT(&p) + RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc)) p.dic = dest; p.dicBufSize = outSize; LzmaDec_Init(&p); diff --git a/libraries/lzma/C/LzmaDec.h b/libraries/lzma/C/LzmaDec.h index 6f1296250..b0ce28fa0 100644 --- a/libraries/lzma/C/LzmaDec.h +++ b/libraries/lzma/C/LzmaDec.h @@ -1,19 +1,19 @@ /* LzmaDec.h -- LZMA Decoder -2020-03-19 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __LZMA_DEC_H -#define __LZMA_DEC_H +#ifndef ZIP7_INC_LZMA_DEC_H +#define ZIP7_INC_LZMA_DEC_H #include "7zTypes.h" EXTERN_C_BEGIN -/* #define _LZMA_PROB32 */ -/* _LZMA_PROB32 can increase the speed on some CPUs, +/* #define Z7_LZMA_PROB32 */ +/* Z7_LZMA_PROB32 can increase the speed on some CPUs, but memory usage for CLzmaDec::probs will be doubled in that case */ typedef -#ifdef _LZMA_PROB32 +#ifdef Z7_LZMA_PROB32 UInt32 #else UInt16 @@ -25,7 +25,7 @@ typedef #define LZMA_PROPS_SIZE 5 -typedef struct _CLzmaProps +typedef struct { Byte lc; Byte lp; @@ -73,7 +73,8 @@ typedef struct Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; } CLzmaDec; -#define LzmaDec_Construct(p) { (p)->dic = NULL; (p)->probs = NULL; } +#define LzmaDec_CONSTRUCT(p) { (p)->dic = NULL; (p)->probs = NULL; } +#define LzmaDec_Construct(p) LzmaDec_CONSTRUCT(p) void LzmaDec_Init(CLzmaDec *p); diff --git a/libraries/lzma/C/LzmaEnc.c b/libraries/lzma/C/LzmaEnc.c index b04a7b7b7..6d13cac8c 100644 --- a/libraries/lzma/C/LzmaEnc.c +++ b/libraries/lzma/C/LzmaEnc.c @@ -1,5 +1,5 @@ /* LzmaEnc.c -- LZMA Encoder -2021-11-18: Igor Pavlov : Public domain */ +2023-04-13: Igor Pavlov : Public domain */ #include "Precomp.h" @@ -16,22 +16,22 @@ #include "LzmaEnc.h" #include "LzFind.h" -#ifndef _7ZIP_ST +#ifndef Z7_ST #include "LzFindMt.h" #endif /* the following LzmaEnc_* declarations is internal LZMA interface for LZMA2 encoder */ -SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize, +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, ISeqInStreamPtr inStream, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); -SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, const Byte *src, SizeT srcLen, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig); -SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit, +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize); -const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp); -void LzmaEnc_Finish(CLzmaEncHandle pp); -void LzmaEnc_SaveState(CLzmaEncHandle pp); -void LzmaEnc_RestoreState(CLzmaEncHandle pp); +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p); +void LzmaEnc_Finish(CLzmaEncHandle p); +void LzmaEnc_SaveState(CLzmaEncHandle p); +void LzmaEnc_RestoreState(CLzmaEncHandle p); #ifdef SHOW_STAT static unsigned g_STAT_OFFSET = 0; @@ -40,8 +40,8 @@ static unsigned g_STAT_OFFSET = 0; /* for good normalization speed we still reserve 256 MB before 4 GB range */ #define kLzmaMaxHistorySize ((UInt32)15 << 28) -#define kNumTopBits 24 -#define kTopValue ((UInt32)1 << kNumTopBits) +// #define kNumTopBits 24 +#define kTopValue ((UInt32)1 << 24) #define kNumBitModelTotalBits 11 #define kBitModelTotal (1 << kNumBitModelTotalBits) @@ -60,6 +60,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p) p->dictSize = p->mc = 0; p->reduceSize = (UInt64)(Int64)-1; p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; + p->numHashOutBits = 0; p->writeEndMark = 0; p->affinity = 0; } @@ -99,7 +100,7 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p) if (p->numThreads < 0) p->numThreads = - #ifndef _7ZIP_ST + #ifndef Z7_ST ((p->btMode && p->algo) ? 2 : 1); #else 1; @@ -293,7 +294,7 @@ typedef struct #define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) typedef -#ifdef _LZMA_PROB32 +#ifdef Z7_LZMA_PROB32 UInt32 #else UInt16 @@ -350,7 +351,7 @@ typedef struct Byte *buf; Byte *bufLim; Byte *bufBase; - ISeqOutStream *outStream; + ISeqOutStreamPtr outStream; UInt64 processed; SRes res; } CRangeEnc; @@ -383,7 +384,7 @@ typedef struct typedef UInt32 CProbPrice; -typedef struct +struct CLzmaEnc { void *matchFinderObj; IMatchFinder2 matchFinder; @@ -426,7 +427,7 @@ typedef struct UInt32 dictSize; SRes result; - #ifndef _7ZIP_ST + #ifndef Z7_ST BoolInt mtMode; // begin of CMatchFinderMt is used in LZ thread CMatchFinderMt matchFinderMt; @@ -439,7 +440,7 @@ typedef struct // we suppose that we have 8-bytes alignment after CMatchFinder - #ifndef _7ZIP_ST + #ifndef Z7_ST Byte pad[128]; #endif @@ -479,77 +480,59 @@ typedef struct CSaveState saveState; // BoolInt mf_Failure; - #ifndef _7ZIP_ST + #ifndef Z7_ST Byte pad2[128]; #endif -} CLzmaEnc; +}; #define MFB (p->matchFinderBase) /* -#ifndef _7ZIP_ST +#ifndef Z7_ST #define MFB (p->matchFinderMt.MatchFinder) #endif */ -#define COPY_ARR(dest, src, arr) memcpy(dest->arr, src->arr, sizeof(src->arr)); +// #define GET_CLzmaEnc_p CLzmaEnc *p = (CLzmaEnc*)(void *)p; +// #define GET_const_CLzmaEnc_p const CLzmaEnc *p = (const CLzmaEnc*)(const void *)p; -void LzmaEnc_SaveState(CLzmaEncHandle pp) +#define COPY_ARR(dest, src, arr) memcpy((dest)->arr, (src)->arr, sizeof((src)->arr)); + +#define COPY_LZMA_ENC_STATE(d, s, p) \ + (d)->state = (s)->state; \ + COPY_ARR(d, s, reps) \ + COPY_ARR(d, s, posAlignEncoder) \ + COPY_ARR(d, s, isRep) \ + COPY_ARR(d, s, isRepG0) \ + COPY_ARR(d, s, isRepG1) \ + COPY_ARR(d, s, isRepG2) \ + COPY_ARR(d, s, isMatch) \ + COPY_ARR(d, s, isRep0Long) \ + COPY_ARR(d, s, posSlotEncoder) \ + COPY_ARR(d, s, posEncoders) \ + (d)->lenProbs = (s)->lenProbs; \ + (d)->repLenProbs = (s)->repLenProbs; \ + memcpy((d)->litProbs, (s)->litProbs, ((UInt32)0x300 << (p)->lclp) * sizeof(CLzmaProb)); + +void LzmaEnc_SaveState(CLzmaEncHandle p) { - CLzmaEnc *p = (CLzmaEnc *)pp; - CSaveState *dest = &p->saveState; - - dest->state = p->state; - - dest->lenProbs = p->lenProbs; - dest->repLenProbs = p->repLenProbs; + // GET_CLzmaEnc_p + CSaveState *v = &p->saveState; + COPY_LZMA_ENC_STATE(v, p, p) +} - COPY_ARR(dest, p, reps); - - COPY_ARR(dest, p, posAlignEncoder); - COPY_ARR(dest, p, isRep); - COPY_ARR(dest, p, isRepG0); - COPY_ARR(dest, p, isRepG1); - COPY_ARR(dest, p, isRepG2); - COPY_ARR(dest, p, isMatch); - COPY_ARR(dest, p, isRep0Long); - COPY_ARR(dest, p, posSlotEncoder); - COPY_ARR(dest, p, posEncoders); - - memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb)); +void LzmaEnc_RestoreState(CLzmaEncHandle p) +{ + // GET_CLzmaEnc_p + const CSaveState *v = &p->saveState; + COPY_LZMA_ENC_STATE(p, v, p) } -void LzmaEnc_RestoreState(CLzmaEncHandle pp) +Z7_NO_INLINE +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props2) { - CLzmaEnc *dest = (CLzmaEnc *)pp; - const CSaveState *p = &dest->saveState; - - dest->state = p->state; - - dest->lenProbs = p->lenProbs; - dest->repLenProbs = p->repLenProbs; - - COPY_ARR(dest, p, reps); - - COPY_ARR(dest, p, posAlignEncoder); - COPY_ARR(dest, p, isRep); - COPY_ARR(dest, p, isRepG0); - COPY_ARR(dest, p, isRepG1); - COPY_ARR(dest, p, isRepG2); - COPY_ARR(dest, p, isMatch); - COPY_ARR(dest, p, isRep0Long); - COPY_ARR(dest, p, posSlotEncoder); - COPY_ARR(dest, p, posEncoders); - - memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb)); -} - - - -SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; + // GET_CLzmaEnc_p CLzmaEncProps props = *props2; LzmaEncProps_Normalize(&props); @@ -585,6 +568,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) p->fastMode = (props.algo == 0); // p->_maxMode = True; MFB.btMode = (Byte)(props.btMode ? 1 : 0); + // MFB.btMode = (Byte)(props.btMode); { unsigned numHashBytes = 4; if (props.btMode) @@ -595,13 +579,15 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) if (props.numHashBytes >= 5) numHashBytes = 5; MFB.numHashBytes = numHashBytes; + // MFB.numHashBytes_Min = 2; + MFB.numHashOutBits = (Byte)props.numHashOutBits; } MFB.cutValue = props.mc; p->writeEndMark = (BoolInt)props.writeEndMark; - #ifndef _7ZIP_ST + #ifndef Z7_ST /* if (newMultiThread != _multiThread) { @@ -618,9 +604,9 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) } -void LzmaEnc_SetDataSize(CLzmaEncHandle pp, UInt64 expectedDataSiize) +void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize) { - CLzmaEnc *p = (CLzmaEnc *)pp; + // GET_CLzmaEnc_p MFB.expectedDataSize = expectedDataSiize; } @@ -684,7 +670,7 @@ static void RangeEnc_Init(CRangeEnc *p) p->res = SZ_OK; } -MY_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p) +Z7_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p) { const size_t num = (size_t)(p->buf - p->bufBase); if (p->res == SZ_OK) @@ -696,7 +682,7 @@ MY_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p) p->buf = p->bufBase; } -MY_NO_INLINE static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) +Z7_NO_INLINE static void Z7_FASTCALL RangeEnc_ShiftLow(CRangeEnc *p) { UInt32 low = (UInt32)p->low; unsigned high = (unsigned)(p->low >> 32); @@ -741,9 +727,9 @@ static void RangeEnc_FlushData(CRangeEnc *p) ttt = *(prob); \ newBound = (range >> kNumBitModelTotalBits) * ttt; -// #define _LZMA_ENC_USE_BRANCH +// #define Z7_LZMA_ENC_USE_BRANCH -#ifdef _LZMA_ENC_USE_BRANCH +#ifdef Z7_LZMA_ENC_USE_BRANCH #define RC_BIT(p, prob, bit) { \ RC_BIT_PRE(p, prob) \ @@ -811,7 +797,7 @@ static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 sym) CLzmaProb *prob = probs + (sym >> 8); UInt32 bit = (sym >> 7) & 1; sym <<= 1; - RC_BIT(p, prob, bit); + RC_BIT(p, prob, bit) } while (sym < 0x10000); p->range = range; @@ -833,7 +819,7 @@ static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 sym, UIn bit = (sym >> 7) & 1; sym <<= 1; offs &= ~(matchByte ^ sym); - RC_BIT(p, prob, bit); + RC_BIT(p, prob, bit) } while (sym < 0x10000); p->range = range; @@ -867,10 +853,10 @@ static void LzmaEnc_InitPriceTables(CProbPrice *ProbPrices) #define GET_PRICE(prob, bit) \ - p->ProbPrices[((prob) ^ (unsigned)(((-(int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + p->ProbPrices[((prob) ^ (unsigned)(((-(int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits] #define GET_PRICEa(prob, bit) \ - ProbPrices[((prob) ^ (unsigned)((-((int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + ProbPrices[((prob) ^ (unsigned)((-((int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits] #define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] #define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] @@ -921,7 +907,7 @@ static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, unsigned numBi unsigned bit = sym & 1; // RangeEnc_EncodeBit(rc, probs + m, bit); sym >>= 1; - RC_BIT(rc, probs + m, bit); + RC_BIT(rc, probs + m, bit) m = (m << 1) | bit; } while (--numBits); @@ -944,15 +930,15 @@ static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned sym, unsigned posS UInt32 range, ttt, newBound; CLzmaProb *probs = p->low; range = rc->range; - RC_BIT_PRE(rc, probs); + RC_BIT_PRE(rc, probs) if (sym >= kLenNumLowSymbols) { - RC_BIT_1(rc, probs); + RC_BIT_1(rc, probs) probs += kLenNumLowSymbols; - RC_BIT_PRE(rc, probs); + RC_BIT_PRE(rc, probs) if (sym >= kLenNumLowSymbols * 2) { - RC_BIT_1(rc, probs); + RC_BIT_1(rc, probs) rc->range = range; // RcTree_Encode(rc, p->high, kLenNumHighBits, sym - kLenNumLowSymbols * 2); LitEnc_Encode(rc, p->high, sym - kLenNumLowSymbols * 2); @@ -965,11 +951,11 @@ static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned sym, unsigned posS { unsigned m; unsigned bit; - RC_BIT_0(rc, probs); + RC_BIT_0(rc, probs) probs += (posState << (1 + kLenNumLowBits)); - bit = (sym >> 2) ; RC_BIT(rc, probs + 1, bit); m = (1 << 1) + bit; - bit = (sym >> 1) & 1; RC_BIT(rc, probs + m, bit); m = (m << 1) + bit; - bit = sym & 1; RC_BIT(rc, probs + m, bit); + bit = (sym >> 2) ; RC_BIT(rc, probs + 1, bit) m = (1 << 1) + bit; + bit = (sym >> 1) & 1; RC_BIT(rc, probs + m, bit) m = (m << 1) + bit; + bit = sym & 1; RC_BIT(rc, probs + m, bit) rc->range = range; } } @@ -990,7 +976,7 @@ static void SetPrices_3(const CLzmaProb *probs, UInt32 startPrice, UInt32 *price } -MY_NO_INLINE static void MY_FAST_CALL LenPriceEnc_UpdateTables( +Z7_NO_INLINE static void Z7_FASTCALL LenPriceEnc_UpdateTables( CLenPriceEnc *p, unsigned numPosStates, const CLenEnc *enc, @@ -1152,7 +1138,7 @@ static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes) + GET_PRICE_1(p->isRep[state]) \ + GET_PRICE_0(p->isRepG0[state]) -MY_FORCE_INLINE +Z7_FORCE_INLINE static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState) { UInt32 price; @@ -1331,7 +1317,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) LitEnc_GetPrice(probs, curByte, p->ProbPrices)); } - MakeAs_Lit(&p->opt[1]); + MakeAs_Lit(&p->opt[1]) matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); @@ -1343,7 +1329,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) if (shortRepPrice < p->opt[1].price) { p->opt[1].price = shortRepPrice; - MakeAs_ShortRep(&p->opt[1]); + MakeAs_ShortRep(&p->opt[1]) } if (last < 2) { @@ -1410,7 +1396,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) else { unsigned slot; - GetPosSlot2(dist, slot); + GetPosSlot2(dist, slot) price += p->alignPrices[dist & kAlignMask]; price += p->posSlotPrices[lenToPosState][slot]; } @@ -1486,7 +1472,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) unsigned delta = best - cur; if (delta != 0) { - MOVE_POS(p, delta); + MOVE_POS(p, delta) } } cur = best; @@ -1633,7 +1619,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) { nextOpt->price = litPrice; nextOpt->len = 1; - MakeAs_Lit(nextOpt); + MakeAs_Lit(nextOpt) nextIsLit = True; } } @@ -1667,7 +1653,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) { nextOpt->price = shortRepPrice; nextOpt->len = 1; - MakeAs_ShortRep(nextOpt); + MakeAs_ShortRep(nextOpt) nextIsLit = False; } } @@ -1871,7 +1857,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) dist = MATCHES[(size_t)offs + 1]; // if (dist >= kNumFullDistances) - GetPosSlot2(dist, posSlot); + GetPosSlot2(dist, posSlot) for (len = /*2*/ startLen; ; len++) { @@ -1962,7 +1948,7 @@ static unsigned GetOptimum(CLzmaEnc *p, UInt32 position) break; dist = MATCHES[(size_t)offs + 1]; // if (dist >= kNumFullDistances) - GetPosSlot2(dist, posSlot); + GetPosSlot2(dist, posSlot) } } } @@ -2138,7 +2124,7 @@ static void WriteEndMarker(CLzmaEnc *p, unsigned posState) { UInt32 ttt, newBound; RC_BIT_PRE(p, probs + m) - RC_BIT_1(&p->rc, probs + m); + RC_BIT_1(&p->rc, probs + m) m = (m << 1) + 1; } while (m < (1 << kNumPosSlotBits)); @@ -2163,7 +2149,7 @@ static void WriteEndMarker(CLzmaEnc *p, unsigned posState) { UInt32 ttt, newBound; RC_BIT_PRE(p, probs + m) - RC_BIT_1(&p->rc, probs + m); + RC_BIT_1(&p->rc, probs + m) m = (m << 1) + 1; } while (m < kAlignTableSize); @@ -2179,7 +2165,7 @@ static SRes CheckErrors(CLzmaEnc *p) if (p->rc.res != SZ_OK) p->result = SZ_ERROR_WRITE; - #ifndef _7ZIP_ST + #ifndef Z7_ST if ( // p->mf_Failure || (p->mtMode && @@ -2187,7 +2173,7 @@ static SRes CheckErrors(CLzmaEnc *p) p->matchFinderMt.failure_LZ_BT)) ) { - p->result = MY_HRES_ERROR__INTERNAL_ERROR; + p->result = MY_HRES_ERROR_INTERNAL_ERROR; // printf("\nCheckErrors p->matchFinderMt.failureLZ\n"); } #endif @@ -2201,7 +2187,7 @@ static SRes CheckErrors(CLzmaEnc *p) } -MY_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos) +Z7_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos) { /* ReleaseMFStream(); */ p->finished = True; @@ -2213,7 +2199,7 @@ MY_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos) } -MY_NO_INLINE static void FillAlignPrices(CLzmaEnc *p) +Z7_NO_INLINE static void FillAlignPrices(CLzmaEnc *p) { unsigned i; const CProbPrice *ProbPrices = p->ProbPrices; @@ -2237,7 +2223,7 @@ MY_NO_INLINE static void FillAlignPrices(CLzmaEnc *p) } -MY_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p) +Z7_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p) { // int y; for (y = 0; y < 100; y++) { @@ -2337,7 +2323,7 @@ static void LzmaEnc_Construct(CLzmaEnc *p) RangeEnc_Construct(&p->rc); MatchFinder_Construct(&MFB); - #ifndef _7ZIP_ST + #ifndef Z7_ST p->matchFinderMt.MatchFinder = &MFB; MatchFinderMt_Construct(&p->matchFinderMt); #endif @@ -2345,7 +2331,7 @@ static void LzmaEnc_Construct(CLzmaEnc *p) { CLzmaEncProps props; LzmaEncProps_Init(&props); - LzmaEnc_SetProps(p, &props); + LzmaEnc_SetProps((CLzmaEncHandle)(void *)p, &props); } #ifndef LZMA_LOG_BSR @@ -2376,7 +2362,7 @@ static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc) static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - #ifndef _7ZIP_ST + #ifndef Z7_ST MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); #endif @@ -2387,21 +2373,22 @@ static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBi void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); + // GET_CLzmaEnc_p + LzmaEnc_Destruct(p, alloc, allocBig); ISzAlloc_Free(alloc, p); } -MY_NO_INLINE +Z7_NO_INLINE static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize) { UInt32 nowPos32, startPos32; if (p->needInit) { - #ifndef _7ZIP_ST + #ifndef Z7_ST if (p->mtMode) { - RINOK(MatchFinderMt_InitMt(&p->matchFinderMt)); + RINOK(MatchFinderMt_InitMt(&p->matchFinderMt)) } #endif p->matchFinder.Init(p->matchFinderObj); @@ -2410,7 +2397,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa if (p->finished) return p->result; - RINOK(CheckErrors(p)); + RINOK(CheckErrors(p)) nowPos32 = (UInt32)p->nowPos64; startPos32 = nowPos32; @@ -2473,7 +2460,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa const Byte *data; unsigned state; - RC_BIT_0(&p->rc, probs); + RC_BIT_0(&p->rc, probs) p->rc.range = range; data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; probs = LIT_PROBS(nowPos32, *(data - 1)); @@ -2487,53 +2474,53 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa } else { - RC_BIT_1(&p->rc, probs); + RC_BIT_1(&p->rc, probs) probs = &p->isRep[p->state]; RC_BIT_PRE(&p->rc, probs) if (dist < LZMA_NUM_REPS) { - RC_BIT_1(&p->rc, probs); + RC_BIT_1(&p->rc, probs) probs = &p->isRepG0[p->state]; RC_BIT_PRE(&p->rc, probs) if (dist == 0) { - RC_BIT_0(&p->rc, probs); + RC_BIT_0(&p->rc, probs) probs = &p->isRep0Long[p->state][posState]; RC_BIT_PRE(&p->rc, probs) if (len != 1) { - RC_BIT_1_BASE(&p->rc, probs); + RC_BIT_1_BASE(&p->rc, probs) } else { - RC_BIT_0_BASE(&p->rc, probs); + RC_BIT_0_BASE(&p->rc, probs) p->state = kShortRepNextStates[p->state]; } } else { - RC_BIT_1(&p->rc, probs); + RC_BIT_1(&p->rc, probs) probs = &p->isRepG1[p->state]; RC_BIT_PRE(&p->rc, probs) if (dist == 1) { - RC_BIT_0_BASE(&p->rc, probs); + RC_BIT_0_BASE(&p->rc, probs) dist = p->reps[1]; } else { - RC_BIT_1(&p->rc, probs); + RC_BIT_1(&p->rc, probs) probs = &p->isRepG2[p->state]; RC_BIT_PRE(&p->rc, probs) if (dist == 2) { - RC_BIT_0_BASE(&p->rc, probs); + RC_BIT_0_BASE(&p->rc, probs) dist = p->reps[2]; } else { - RC_BIT_1_BASE(&p->rc, probs); + RC_BIT_1_BASE(&p->rc, probs) dist = p->reps[3]; p->reps[3] = p->reps[2]; } @@ -2557,7 +2544,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa else { unsigned posSlot; - RC_BIT_0(&p->rc, probs); + RC_BIT_0(&p->rc, probs) p->rc.range = range; p->state = kMatchNextStates[p->state]; @@ -2571,7 +2558,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa p->reps[0] = dist + 1; p->matchPriceCount++; - GetPosSlot(dist, posSlot); + GetPosSlot(dist, posSlot) // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot); { UInt32 sym = (UInt32)posSlot + (1 << kNumPosSlotBits); @@ -2582,7 +2569,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa CLzmaProb *prob = probs + (sym >> kNumPosSlotBits); UInt32 bit = (sym >> (kNumPosSlotBits - 1)) & 1; sym <<= 1; - RC_BIT(&p->rc, prob, bit); + RC_BIT(&p->rc, prob, bit) } while (sym < (1 << kNumPosSlotBits * 2)); p->rc.range = range; @@ -2626,10 +2613,10 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpa { unsigned m = 1; unsigned bit; - bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit; - bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit; - bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); m = (m << 1) + bit; - bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit); + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit; + bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) p->rc.range = range; // p->alignPriceCount++; } @@ -2704,7 +2691,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, if (!RangeEnc_Alloc(&p->rc, alloc)) return SZ_ERROR_MEM; - #ifndef _7ZIP_ST + #ifndef Z7_ST p->mtMode = (p->multiThread && !p->fastMode && (MFB.btMode != 0)); #endif @@ -2748,15 +2735,14 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, (numFastBytes + LZMA_MATCH_LEN_MAX + 1) */ - #ifndef _7ZIP_ST + #ifndef Z7_ST if (p->mtMode) { RINOK(MatchFinderMt_Create(&p->matchFinderMt, dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 18.04 */ - , allocBig)); + , allocBig)) p->matchFinderObj = &p->matchFinderMt; - MFB.bigHash = (Byte)( - (p->dictSize > kBigHashDicLimit && MFB.hashMask >= 0xFFFFFF) ? 1 : 0); + MFB.bigHash = (Byte)(MFB.hashMask >= 0xFFFFFF ? 1 : 0); MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); } else @@ -2872,59 +2858,53 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr p->finished = False; p->result = SZ_OK; - RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); + p->nowPos64 = 0; + p->needInit = 1; + RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)) LzmaEnc_Init(p); LzmaEnc_InitPrices(p); - p->nowPos64 = 0; return SZ_OK; } -static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, +static SRes LzmaEnc_Prepare(CLzmaEncHandle p, + ISeqOutStreamPtr outStream, + ISeqInStreamPtr inStream, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - CLzmaEnc *p = (CLzmaEnc *)pp; - MFB.stream = inStream; - p->needInit = 1; + // GET_CLzmaEnc_p + MatchFinder_SET_STREAM(&MFB, inStream) p->rc.outStream = outStream; return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); } -SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, - ISeqInStream *inStream, UInt32 keepWindowSize, +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, + ISeqInStreamPtr inStream, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - CLzmaEnc *p = (CLzmaEnc *)pp; - MFB.stream = inStream; - p->needInit = 1; + // GET_CLzmaEnc_p + MatchFinder_SET_STREAM(&MFB, inStream) return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); } -static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) +SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, + const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, + ISzAllocPtr alloc, ISzAllocPtr allocBig) { - MFB.directInput = 1; - MFB.bufferBase = (Byte *)src; - MFB.directInputRem = srcLen; -} - -SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, - UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig) -{ - CLzmaEnc *p = (CLzmaEnc *)pp; - LzmaEnc_SetInputBuf(p, src, srcLen); - p->needInit = 1; - - LzmaEnc_SetDataSize(pp, srcLen); + // GET_CLzmaEnc_p + MatchFinder_SET_DIRECT_INPUT_BUF(&MFB, src, srcLen) + LzmaEnc_SetDataSize(p, srcLen); return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); } -void LzmaEnc_Finish(CLzmaEncHandle pp) +void LzmaEnc_Finish(CLzmaEncHandle p) { - #ifndef _7ZIP_ST - CLzmaEnc *p = (CLzmaEnc *)pp; + #ifndef Z7_ST + // GET_CLzmaEnc_p if (p->mtMode) MatchFinderMt_ReleaseStream(&p->matchFinderMt); #else - UNUSED_VAR(pp); + UNUSED_VAR(p) #endif } @@ -2933,13 +2913,13 @@ typedef struct { ISeqOutStream vt; Byte *data; - SizeT rem; + size_t rem; BoolInt overflow; } CLzmaEnc_SeqOutStreamBuf; -static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, size_t size) +static size_t SeqOutStreamBuf_Write(ISeqOutStreamPtr pp, const void *data, size_t size) { - CLzmaEnc_SeqOutStreamBuf *p = CONTAINER_FROM_VTBL(pp, CLzmaEnc_SeqOutStreamBuf, vt); + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLzmaEnc_SeqOutStreamBuf) if (p->rem < size) { size = p->rem; @@ -2956,24 +2936,25 @@ static size_t SeqOutStreamBuf_Write(const ISeqOutStream *pp, const void *data, s /* -UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle p) { - const CLzmaEnc *p = (CLzmaEnc *)pp; + GET_const_CLzmaEnc_p return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); } */ -const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p) { - const CLzmaEnc *p = (CLzmaEnc *)pp; + // GET_const_CLzmaEnc_p return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; } -SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit, +// (desiredPackSize == 0) is not allowed +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit, Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) { - CLzmaEnc *p = (CLzmaEnc *)pp; + // GET_CLzmaEnc_p UInt64 nowPos64; SRes res; CLzmaEnc_SeqOutStreamBuf outStream; @@ -2990,14 +2971,10 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit, if (reInit) LzmaEnc_Init(p); LzmaEnc_InitPrices(p); - - nowPos64 = p->nowPos64; RangeEnc_Init(&p->rc); p->rc.outStream = &outStream.vt; - - if (desiredPackSize == 0) - return SZ_ERROR_OUTPUT_EOF; - + nowPos64 = p->nowPos64; + res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize); *unpackSize = (UInt32)(p->nowPos64 - nowPos64); @@ -3009,12 +2986,12 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, BoolInt reInit, } -MY_NO_INLINE -static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) +Z7_NO_INLINE +static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgressPtr progress) { SRes res = SZ_OK; - #ifndef _7ZIP_ST + #ifndef Z7_ST Byte allocaDummy[0x300]; allocaDummy[0] = 0; allocaDummy[1] = allocaDummy[0]; @@ -3036,7 +3013,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) } } - LzmaEnc_Finish(p); + LzmaEnc_Finish((CLzmaEncHandle)(void *)p); /* if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&MFB)) @@ -3048,21 +3025,22 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) } -SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); - return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); + // GET_CLzmaEnc_p + RINOK(LzmaEnc_Prepare(p, outStream, inStream, alloc, allocBig)) + return LzmaEnc_Encode2(p, progress); } -SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *props, SizeT *size) { if (*size < LZMA_PROPS_SIZE) return SZ_ERROR_PARAM; *size = LZMA_PROPS_SIZE; { - const CLzmaEnc *p = (const CLzmaEnc *)pp; + // GET_CLzmaEnc_p const UInt32 dictSize = p->dictSize; UInt32 v; props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); @@ -3086,23 +3064,24 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) while (v < dictSize); } - SetUi32(props + 1, v); + SetUi32(props + 1, v) return SZ_OK; } } -unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle pp) +unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p) { - return (unsigned)((CLzmaEnc *)pp)->writeEndMark; + // GET_CLzmaEnc_p + return (unsigned)p->writeEndMark; } -SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) { SRes res; - CLzmaEnc *p = (CLzmaEnc *)pp; + // GET_CLzmaEnc_p CLzmaEnc_SeqOutStreamBuf outStream; @@ -3114,7 +3093,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte p->writeEndMark = writeEndMark; p->rc.outStream = &outStream.vt; - res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); + res = LzmaEnc_MemPrepare(p, src, srcLen, 0, alloc, allocBig); if (res == SZ_OK) { @@ -3123,7 +3102,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte res = SZ_ERROR_FAIL; } - *destLen -= outStream.rem; + *destLen -= (SizeT)outStream.rem; if (outStream.overflow) return SZ_ERROR_OUTPUT_EOF; return res; @@ -3132,9 +3111,9 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig) { - CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); + CLzmaEncHandle p = LzmaEnc_Create(alloc); SRes res; if (!p) return SZ_ERROR_MEM; @@ -3154,10 +3133,10 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, /* -#ifndef _7ZIP_ST -void LzmaEnc_GetLzThreads(CLzmaEncHandle pp, HANDLE lz_threads[2]) +#ifndef Z7_ST +void LzmaEnc_GetLzThreads(CLzmaEncHandle p, HANDLE lz_threads[2]) { - const CLzmaEnc *p = (CLzmaEnc *)pp; + GET_const_CLzmaEnc_p lz_threads[0] = p->matchFinderMt.hashSync.thread; lz_threads[1] = p->matchFinderMt.btSync.thread; } diff --git a/libraries/lzma/C/LzmaEnc.h b/libraries/lzma/C/LzmaEnc.h index bc2ed5042..9f8039a10 100644 --- a/libraries/lzma/C/LzmaEnc.h +++ b/libraries/lzma/C/LzmaEnc.h @@ -1,8 +1,8 @@ /* LzmaEnc.h -- LZMA Encoder -2019-10-30 : Igor Pavlov : Public domain */ +2023-04-13 : Igor Pavlov : Public domain */ -#ifndef __LZMA_ENC_H -#define __LZMA_ENC_H +#ifndef ZIP7_INC_LZMA_ENC_H +#define ZIP7_INC_LZMA_ENC_H #include "7zTypes.h" @@ -10,7 +10,7 @@ EXTERN_C_BEGIN #define LZMA_PROPS_SIZE 5 -typedef struct _CLzmaEncProps +typedef struct { int level; /* 0 <= level <= 9 */ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version @@ -23,10 +23,13 @@ typedef struct _CLzmaEncProps int fb; /* 5 <= fb <= 273, default = 32 */ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ int numHashBytes; /* 2, 3 or 4, default = 4 */ + unsigned numHashOutBits; /* default = ? */ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ int numThreads; /* 1 or 2, default = 2 */ + // int _pad; + UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1. Encoder uses this value to reduce dictionary size */ @@ -51,7 +54,9 @@ SRes: SZ_ERROR_THREAD - error in multithreading functions (only for Mt version) */ -typedef void * CLzmaEncHandle; +typedef struct CLzmaEnc CLzmaEnc; +typedef CLzmaEnc * CLzmaEncHandle; +// Z7_DECLARE_HANDLE(CLzmaEncHandle) CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc); void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig); @@ -61,17 +66,17 @@ void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize); SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p); -SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, - ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, - int writeEndMark, ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); + int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); /* ---------- One Call Interface ---------- */ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, - ICompressProgress *progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); + ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig); EXTERN_C_END diff --git a/libraries/lzma/C/LzmaLib.c b/libraries/lzma/C/LzmaLib.c new file mode 100644 index 000000000..785e88487 --- /dev/null +++ b/libraries/lzma/C/LzmaLib.c @@ -0,0 +1,42 @@ +/* LzmaLib.c -- LZMA library wrapper +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Alloc.h" +#include "LzmaDec.h" +#include "LzmaEnc.h" +#include "LzmaLib.h" + +Z7_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, + unsigned char *outProps, size_t *outPropsSize, + int level, /* 0 <= level <= 9, default = 5 */ + unsigned dictSize, /* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */ + int lc, /* 0 <= lc <= 8, default = 3 */ + int lp, /* 0 <= lp <= 4, default = 0 */ + int pb, /* 0 <= pb <= 4, default = 2 */ + int fb, /* 5 <= fb <= 273, default = 32 */ + int numThreads /* 1 or 2, default = 2 */ +) +{ + CLzmaEncProps props; + LzmaEncProps_Init(&props); + props.level = level; + props.dictSize = dictSize; + props.lc = lc; + props.lp = lp; + props.pb = pb; + props.fb = fb; + props.numThreads = numThreads; + + return LzmaEncode(dest, destLen, src, srcLen, &props, outProps, outPropsSize, 0, + NULL, &g_Alloc, &g_Alloc); +} + + +Z7_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t *srcLen, + const unsigned char *props, size_t propsSize) +{ + ELzmaStatus status; + return LzmaDecode(dest, destLen, src, srcLen, props, (unsigned)propsSize, LZMA_FINISH_ANY, &status, &g_Alloc); +} diff --git a/libraries/lzma/C/LzmaLib.h b/libraries/lzma/C/LzmaLib.h new file mode 100644 index 000000000..d7c0724de --- /dev/null +++ b/libraries/lzma/C/LzmaLib.h @@ -0,0 +1,138 @@ +/* LzmaLib.h -- LZMA library interface +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_LZMA_LIB_H +#define ZIP7_INC_LZMA_LIB_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define Z7_STDAPI int Z7_STDCALL + +#define LZMA_PROPS_SIZE 5 + +/* +RAM requirements for LZMA: + for compression: (dictSize * 11.5 + 6 MB) + state_size + for decompression: dictSize + state_size + state_size = (4 + (1.5 << (lc + lp))) KB + by default (lc=3, lp=0), state_size = 16 KB. + +LZMA properties (5 bytes) format + Offset Size Description + 0 1 lc, lp and pb in encoded form. + 1 4 dictSize (little endian). +*/ + +/* +LzmaCompress +------------ + +outPropsSize - + In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. + Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5. + + LZMA Encoder will use defult values for any parameter, if it is + -1 for any from: level, loc, lp, pb, fb, numThreads + 0 for dictSize + +level - compression level: 0 <= level <= 9; + + level dictSize algo fb + 0: 64 KB 0 32 + 1: 256 KB 0 32 + 2: 1 MB 0 32 + 3: 4 MB 0 32 + 4: 16 MB 0 32 + 5: 16 MB 1 32 + 6: 32 MB 1 32 + 7: 32 MB 1 64 + 8: 64 MB 1 64 + 9: 64 MB 1 64 + + The default value for "level" is 5. + + algo = 0 means fast method + algo = 1 means normal method + +dictSize - The dictionary size in bytes. The maximum value is + 128 MB = (1 << 27) bytes for 32-bit version + 1 GB = (1 << 30) bytes for 64-bit version + The default value is 16 MB = (1 << 24) bytes. + It's recommended to use the dictionary that is larger than 4 KB and + that can be calculated as (1 << N) or (3 << N) sizes. + +lc - The number of literal context bits (high bits of previous literal). + It can be in the range from 0 to 8. The default value is 3. + Sometimes lc=4 gives the gain for big files. + +lp - The number of literal pos bits (low bits of current position for literals). + It can be in the range from 0 to 4. The default value is 0. + The lp switch is intended for periodical data when the period is equal to 2^lp. + For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's + better to set lc=0, if you change lp switch. + +pb - The number of pos bits (low bits of current position). + It can be in the range from 0 to 4. The default value is 2. + The pb switch is intended for periodical data when the period is equal 2^pb. + +fb - Word size (the number of fast bytes). + It can be in the range from 5 to 273. The default value is 32. + Usually, a big number gives a little bit better compression ratio and + slower compression process. + +numThreads - The number of thereads. 1 or 2. The default value is 2. + Fast mode (algo = 0) can use only 1 thread. + +In: + dest - output data buffer + destLen - output data buffer size + src - input data + srcLen - input data size +Out: + destLen - processed output size +Returns: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect paramater + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +Z7_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen, + unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */ + int level, /* 0 <= level <= 9, default = 5 */ + unsigned dictSize, /* default = (1 << 24) */ + int lc, /* 0 <= lc <= 8, default = 3 */ + int lp, /* 0 <= lp <= 4, default = 0 */ + int pb, /* 0 <= pb <= 4, default = 2 */ + int fb, /* 5 <= fb <= 273, default = 32 */ + int numThreads /* 1 or 2, default = 2 */ + ); + +/* +LzmaUncompress +-------------- +In: + dest - output data buffer + destLen - output data buffer size + src - input data + srcLen - input data size +Out: + destLen - processed output size + srcLen - processed input size +Returns: + SZ_OK - OK + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation arror + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src) +*/ + +Z7_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen, + const unsigned char *props, size_t propsSize); + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/MtCoder.c b/libraries/lzma/C/MtCoder.c new file mode 100644 index 000000000..6f58abb2a --- /dev/null +++ b/libraries/lzma/C/MtCoder.c @@ -0,0 +1,571 @@ +/* MtCoder.c -- Multi-thread Coder +2023-04-13 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "MtCoder.h" + +#ifndef Z7_ST + +static SRes MtProgressThunk_Progress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CMtProgressThunk) + UInt64 inSize2 = 0; + UInt64 outSize2 = 0; + if (inSize != (UInt64)(Int64)-1) + { + inSize2 = inSize - p->inSize; + p->inSize = inSize; + } + if (outSize != (UInt64)(Int64)-1) + { + outSize2 = outSize - p->outSize; + p->outSize = outSize; + } + return MtProgress_ProgressAdd(p->mtProgress, inSize2, outSize2); +} + + +void MtProgressThunk_CreateVTable(CMtProgressThunk *p) +{ + p->vt.Progress = MtProgressThunk_Progress; +} + + + +#define RINOK_THREAD(x) { if ((x) != 0) return SZ_ERROR_THREAD; } + + +static THREAD_FUNC_DECL ThreadFunc(void *pp); + + +static SRes MtCoderThread_CreateAndStart(CMtCoderThread *t) +{ + WRes wres = AutoResetEvent_OptCreate_And_Reset(&t->startEvent); + if (wres == 0) + { + t->stop = False; + if (!Thread_WasCreated(&t->thread)) + wres = Thread_Create(&t->thread, ThreadFunc, t); + if (wres == 0) + wres = Event_Set(&t->startEvent); + } + if (wres == 0) + return SZ_OK; + return MY_SRes_HRESULT_FROM_WRes(wres); +} + + +static void MtCoderThread_Destruct(CMtCoderThread *t) +{ + if (Thread_WasCreated(&t->thread)) + { + t->stop = 1; + Event_Set(&t->startEvent); + Thread_Wait_Close(&t->thread); + } + + Event_Close(&t->startEvent); + + if (t->inBuf) + { + ISzAlloc_Free(t->mtCoder->allocBig, t->inBuf); + t->inBuf = NULL; + } +} + + + + +/* + ThreadFunc2() returns: + SZ_OK - in all normal cases (even for stream error or memory allocation error) + SZ_ERROR_THREAD - in case of failure in system synch function +*/ + +static SRes ThreadFunc2(CMtCoderThread *t) +{ + CMtCoder *mtc = t->mtCoder; + + for (;;) + { + unsigned bi; + SRes res; + SRes res2; + BoolInt finished; + unsigned bufIndex; + size_t size; + const Byte *inData; + UInt64 readProcessed = 0; + + RINOK_THREAD(Event_Wait(&mtc->readEvent)) + + /* after Event_Wait(&mtc->readEvent) we must call Event_Set(&mtc->readEvent) in any case to unlock another threads */ + + if (mtc->stopReading) + { + return Event_Set(&mtc->readEvent) == 0 ? SZ_OK : SZ_ERROR_THREAD; + } + + res = MtProgress_GetError(&mtc->mtProgress); + + size = 0; + inData = NULL; + finished = True; + + if (res == SZ_OK) + { + size = mtc->blockSize; + if (mtc->inStream) + { + if (!t->inBuf) + { + t->inBuf = (Byte *)ISzAlloc_Alloc(mtc->allocBig, mtc->blockSize); + if (!t->inBuf) + res = SZ_ERROR_MEM; + } + if (res == SZ_OK) + { + res = SeqInStream_ReadMax(mtc->inStream, t->inBuf, &size); + readProcessed = mtc->readProcessed + size; + mtc->readProcessed = readProcessed; + } + if (res != SZ_OK) + { + mtc->readRes = res; + /* after reading error - we can stop encoding of previous blocks */ + MtProgress_SetError(&mtc->mtProgress, res); + } + else + finished = (size != mtc->blockSize); + } + else + { + size_t rem; + readProcessed = mtc->readProcessed; + rem = mtc->inDataSize - (size_t)readProcessed; + if (size > rem) + size = rem; + inData = mtc->inData + (size_t)readProcessed; + readProcessed += size; + mtc->readProcessed = readProcessed; + finished = (mtc->inDataSize == (size_t)readProcessed); + } + } + + /* we must get some block from blocksSemaphore before Event_Set(&mtc->readEvent) */ + + res2 = SZ_OK; + + if (Semaphore_Wait(&mtc->blocksSemaphore) != 0) + { + res2 = SZ_ERROR_THREAD; + if (res == SZ_OK) + { + res = res2; + // MtProgress_SetError(&mtc->mtProgress, res); + } + } + + bi = mtc->blockIndex; + + if (++mtc->blockIndex >= mtc->numBlocksMax) + mtc->blockIndex = 0; + + bufIndex = (unsigned)(int)-1; + + if (res == SZ_OK) + res = MtProgress_GetError(&mtc->mtProgress); + + if (res != SZ_OK) + finished = True; + + if (!finished) + { + if (mtc->numStartedThreads < mtc->numStartedThreadsLimit + && mtc->expectedDataSize != readProcessed) + { + res = MtCoderThread_CreateAndStart(&mtc->threads[mtc->numStartedThreads]); + if (res == SZ_OK) + mtc->numStartedThreads++; + else + { + MtProgress_SetError(&mtc->mtProgress, res); + finished = True; + } + } + } + + if (finished) + mtc->stopReading = True; + + RINOK_THREAD(Event_Set(&mtc->readEvent)) + + if (res2 != SZ_OK) + return res2; + + if (res == SZ_OK) + { + CriticalSection_Enter(&mtc->cs); + bufIndex = mtc->freeBlockHead; + mtc->freeBlockHead = mtc->freeBlockList[bufIndex]; + CriticalSection_Leave(&mtc->cs); + + res = mtc->mtCallback->Code(mtc->mtCallbackObject, t->index, bufIndex, + mtc->inStream ? t->inBuf : inData, size, finished); + + // MtProgress_Reinit(&mtc->mtProgress, t->index); + + if (res != SZ_OK) + MtProgress_SetError(&mtc->mtProgress, res); + } + + { + CMtCoderBlock *block = &mtc->blocks[bi]; + block->res = res; + block->bufIndex = bufIndex; + block->finished = finished; + } + + #ifdef MTCODER_USE_WRITE_THREAD + RINOK_THREAD(Event_Set(&mtc->writeEvents[bi])) + #else + { + unsigned wi; + { + CriticalSection_Enter(&mtc->cs); + wi = mtc->writeIndex; + if (wi == bi) + mtc->writeIndex = (unsigned)(int)-1; + else + mtc->ReadyBlocks[bi] = True; + CriticalSection_Leave(&mtc->cs); + } + + if (wi != bi) + { + if (res != SZ_OK || finished) + return 0; + continue; + } + + if (mtc->writeRes != SZ_OK) + res = mtc->writeRes; + + for (;;) + { + if (res == SZ_OK && bufIndex != (unsigned)(int)-1) + { + res = mtc->mtCallback->Write(mtc->mtCallbackObject, bufIndex); + if (res != SZ_OK) + { + mtc->writeRes = res; + MtProgress_SetError(&mtc->mtProgress, res); + } + } + + if (++wi >= mtc->numBlocksMax) + wi = 0; + { + BoolInt isReady; + + CriticalSection_Enter(&mtc->cs); + + if (bufIndex != (unsigned)(int)-1) + { + mtc->freeBlockList[bufIndex] = mtc->freeBlockHead; + mtc->freeBlockHead = bufIndex; + } + + isReady = mtc->ReadyBlocks[wi]; + + if (isReady) + mtc->ReadyBlocks[wi] = False; + else + mtc->writeIndex = wi; + + CriticalSection_Leave(&mtc->cs); + + RINOK_THREAD(Semaphore_Release1(&mtc->blocksSemaphore)) + + if (!isReady) + break; + } + + { + CMtCoderBlock *block = &mtc->blocks[wi]; + if (res == SZ_OK && block->res != SZ_OK) + res = block->res; + bufIndex = block->bufIndex; + finished = block->finished; + } + } + } + #endif + + if (finished || res != SZ_OK) + return 0; + } +} + + +static THREAD_FUNC_DECL ThreadFunc(void *pp) +{ + CMtCoderThread *t = (CMtCoderThread *)pp; + for (;;) + { + if (Event_Wait(&t->startEvent) != 0) + return (THREAD_FUNC_RET_TYPE)SZ_ERROR_THREAD; + if (t->stop) + return 0; + { + SRes res = ThreadFunc2(t); + CMtCoder *mtc = t->mtCoder; + if (res != SZ_OK) + { + MtProgress_SetError(&mtc->mtProgress, res); + } + + #ifndef MTCODER_USE_WRITE_THREAD + { + unsigned numFinished = (unsigned)InterlockedIncrement(&mtc->numFinishedThreads); + if (numFinished == mtc->numStartedThreads) + if (Event_Set(&mtc->finishedEvent) != 0) + return (THREAD_FUNC_RET_TYPE)SZ_ERROR_THREAD; + } + #endif + } + } +} + + + +void MtCoder_Construct(CMtCoder *p) +{ + unsigned i; + + p->blockSize = 0; + p->numThreadsMax = 0; + p->expectedDataSize = (UInt64)(Int64)-1; + + p->inStream = NULL; + p->inData = NULL; + p->inDataSize = 0; + + p->progress = NULL; + p->allocBig = NULL; + + p->mtCallback = NULL; + p->mtCallbackObject = NULL; + + p->allocatedBufsSize = 0; + + Event_Construct(&p->readEvent); + Semaphore_Construct(&p->blocksSemaphore); + + for (i = 0; i < MTCODER_THREADS_MAX; i++) + { + CMtCoderThread *t = &p->threads[i]; + t->mtCoder = p; + t->index = i; + t->inBuf = NULL; + t->stop = False; + Event_Construct(&t->startEvent); + Thread_CONSTRUCT(&t->thread) + } + + #ifdef MTCODER_USE_WRITE_THREAD + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + Event_Construct(&p->writeEvents[i]); + #else + Event_Construct(&p->finishedEvent); + #endif + + CriticalSection_Init(&p->cs); + CriticalSection_Init(&p->mtProgress.cs); +} + + + + +static void MtCoder_Free(CMtCoder *p) +{ + unsigned i; + + /* + p->stopReading = True; + if (Event_IsCreated(&p->readEvent)) + Event_Set(&p->readEvent); + */ + + for (i = 0; i < MTCODER_THREADS_MAX; i++) + MtCoderThread_Destruct(&p->threads[i]); + + Event_Close(&p->readEvent); + Semaphore_Close(&p->blocksSemaphore); + + #ifdef MTCODER_USE_WRITE_THREAD + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + Event_Close(&p->writeEvents[i]); + #else + Event_Close(&p->finishedEvent); + #endif +} + + +void MtCoder_Destruct(CMtCoder *p) +{ + MtCoder_Free(p); + + CriticalSection_Delete(&p->cs); + CriticalSection_Delete(&p->mtProgress.cs); +} + + +SRes MtCoder_Code(CMtCoder *p) +{ + unsigned numThreads = p->numThreadsMax; + unsigned numBlocksMax; + unsigned i; + SRes res = SZ_OK; + + if (numThreads > MTCODER_THREADS_MAX) + numThreads = MTCODER_THREADS_MAX; + numBlocksMax = MTCODER_GET_NUM_BLOCKS_FROM_THREADS(numThreads); + + if (p->blockSize < ((UInt32)1 << 26)) numBlocksMax++; + if (p->blockSize < ((UInt32)1 << 24)) numBlocksMax++; + if (p->blockSize < ((UInt32)1 << 22)) numBlocksMax++; + + if (numBlocksMax > MTCODER_BLOCKS_MAX) + numBlocksMax = MTCODER_BLOCKS_MAX; + + if (p->blockSize != p->allocatedBufsSize) + { + for (i = 0; i < MTCODER_THREADS_MAX; i++) + { + CMtCoderThread *t = &p->threads[i]; + if (t->inBuf) + { + ISzAlloc_Free(p->allocBig, t->inBuf); + t->inBuf = NULL; + } + } + p->allocatedBufsSize = p->blockSize; + } + + p->readRes = SZ_OK; + + MtProgress_Init(&p->mtProgress, p->progress); + + #ifdef MTCODER_USE_WRITE_THREAD + for (i = 0; i < numBlocksMax; i++) + { + RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->writeEvents[i])) + } + #else + RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->finishedEvent)) + #endif + + { + RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->readEvent)) + RINOK_THREAD(Semaphore_OptCreateInit(&p->blocksSemaphore, numBlocksMax, numBlocksMax)) + } + + for (i = 0; i < MTCODER_BLOCKS_MAX - 1; i++) + p->freeBlockList[i] = i + 1; + p->freeBlockList[MTCODER_BLOCKS_MAX - 1] = (unsigned)(int)-1; + p->freeBlockHead = 0; + + p->readProcessed = 0; + p->blockIndex = 0; + p->numBlocksMax = numBlocksMax; + p->stopReading = False; + + #ifndef MTCODER_USE_WRITE_THREAD + p->writeIndex = 0; + p->writeRes = SZ_OK; + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + p->ReadyBlocks[i] = False; + p->numFinishedThreads = 0; + #endif + + p->numStartedThreadsLimit = numThreads; + p->numStartedThreads = 0; + + // for (i = 0; i < numThreads; i++) + { + CMtCoderThread *nextThread = &p->threads[p->numStartedThreads++]; + RINOK(MtCoderThread_CreateAndStart(nextThread)) + } + + RINOK_THREAD(Event_Set(&p->readEvent)) + + #ifdef MTCODER_USE_WRITE_THREAD + { + unsigned bi = 0; + + for (;; bi++) + { + if (bi >= numBlocksMax) + bi = 0; + + RINOK_THREAD(Event_Wait(&p->writeEvents[bi])) + + { + const CMtCoderBlock *block = &p->blocks[bi]; + unsigned bufIndex = block->bufIndex; + BoolInt finished = block->finished; + if (res == SZ_OK && block->res != SZ_OK) + res = block->res; + + if (bufIndex != (unsigned)(int)-1) + { + if (res == SZ_OK) + { + res = p->mtCallback->Write(p->mtCallbackObject, bufIndex); + if (res != SZ_OK) + MtProgress_SetError(&p->mtProgress, res); + } + + CriticalSection_Enter(&p->cs); + { + p->freeBlockList[bufIndex] = p->freeBlockHead; + p->freeBlockHead = bufIndex; + } + CriticalSection_Leave(&p->cs); + } + + RINOK_THREAD(Semaphore_Release1(&p->blocksSemaphore)) + + if (finished) + break; + } + } + } + #else + { + WRes wres = Event_Wait(&p->finishedEvent); + res = MY_SRes_HRESULT_FROM_WRes(wres); + } + #endif + + if (res == SZ_OK) + res = p->readRes; + + if (res == SZ_OK) + res = p->mtProgress.res; + + #ifndef MTCODER_USE_WRITE_THREAD + if (res == SZ_OK) + res = p->writeRes; + #endif + + if (res != SZ_OK) + MtCoder_Free(p); + return res; +} + +#endif + +#undef RINOK_THREAD diff --git a/libraries/lzma/C/MtCoder.h b/libraries/lzma/C/MtCoder.h new file mode 100644 index 000000000..1231d3c2a --- /dev/null +++ b/libraries/lzma/C/MtCoder.h @@ -0,0 +1,141 @@ +/* MtCoder.h -- Multi-thread Coder +2023-04-13 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_MT_CODER_H +#define ZIP7_INC_MT_CODER_H + +#include "MtDec.h" + +EXTERN_C_BEGIN + +/* + if ( defined MTCODER_USE_WRITE_THREAD) : main thread writes all data blocks to output stream + if (not defined MTCODER_USE_WRITE_THREAD) : any coder thread can write data blocks to output stream +*/ +/* #define MTCODER_USE_WRITE_THREAD */ + +#ifndef Z7_ST + #define MTCODER_GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1) + #define MTCODER_THREADS_MAX 64 + #define MTCODER_BLOCKS_MAX (MTCODER_GET_NUM_BLOCKS_FROM_THREADS(MTCODER_THREADS_MAX) + 3) +#else + #define MTCODER_THREADS_MAX 1 + #define MTCODER_BLOCKS_MAX 1 +#endif + + +#ifndef Z7_ST + + +typedef struct +{ + ICompressProgress vt; + CMtProgress *mtProgress; + UInt64 inSize; + UInt64 outSize; +} CMtProgressThunk; + +void MtProgressThunk_CreateVTable(CMtProgressThunk *p); + +#define MtProgressThunk_INIT(p) { (p)->inSize = 0; (p)->outSize = 0; } + + +struct CMtCoder_; + + +typedef struct +{ + struct CMtCoder_ *mtCoder; + unsigned index; + int stop; + Byte *inBuf; + + CAutoResetEvent startEvent; + CThread thread; +} CMtCoderThread; + + +typedef struct +{ + SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex, + const Byte *src, size_t srcSize, int finished); + SRes (*Write)(void *p, unsigned outBufIndex); +} IMtCoderCallback2; + + +typedef struct +{ + SRes res; + unsigned bufIndex; + BoolInt finished; +} CMtCoderBlock; + + +typedef struct CMtCoder_ +{ + /* input variables */ + + size_t blockSize; /* size of input block */ + unsigned numThreadsMax; + UInt64 expectedDataSize; + + ISeqInStreamPtr inStream; + const Byte *inData; + size_t inDataSize; + + ICompressProgressPtr progress; + ISzAllocPtr allocBig; + + IMtCoderCallback2 *mtCallback; + void *mtCallbackObject; + + + /* internal variables */ + + size_t allocatedBufsSize; + + CAutoResetEvent readEvent; + CSemaphore blocksSemaphore; + + BoolInt stopReading; + SRes readRes; + + #ifdef MTCODER_USE_WRITE_THREAD + CAutoResetEvent writeEvents[MTCODER_BLOCKS_MAX]; + #else + CAutoResetEvent finishedEvent; + SRes writeRes; + unsigned writeIndex; + Byte ReadyBlocks[MTCODER_BLOCKS_MAX]; + LONG numFinishedThreads; + #endif + + unsigned numStartedThreadsLimit; + unsigned numStartedThreads; + + unsigned numBlocksMax; + unsigned blockIndex; + UInt64 readProcessed; + + CCriticalSection cs; + + unsigned freeBlockHead; + unsigned freeBlockList[MTCODER_BLOCKS_MAX]; + + CMtProgress mtProgress; + CMtCoderBlock blocks[MTCODER_BLOCKS_MAX]; + CMtCoderThread threads[MTCODER_THREADS_MAX]; +} CMtCoder; + + +void MtCoder_Construct(CMtCoder *p); +void MtCoder_Destruct(CMtCoder *p); +SRes MtCoder_Code(CMtCoder *p); + + +#endif + + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/MtDec.c b/libraries/lzma/C/MtDec.c new file mode 100644 index 000000000..782069926 --- /dev/null +++ b/libraries/lzma/C/MtDec.c @@ -0,0 +1,1114 @@ +/* MtDec.c -- Multi-thread Decoder +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #define SHOW_DEBUG_INFO + +// #include +#include + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#include "MtDec.h" + +#ifndef Z7_ST + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) + +void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress) +{ + p->progress = progress; + p->res = SZ_OK; + p->totalInSize = 0; + p->totalOutSize = 0; +} + + +SRes MtProgress_Progress_ST(CMtProgress *p) +{ + if (p->res == SZ_OK && p->progress) + if (ICompressProgress_Progress(p->progress, p->totalInSize, p->totalOutSize) != SZ_OK) + p->res = SZ_ERROR_PROGRESS; + return p->res; +} + + +SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize) +{ + SRes res; + CriticalSection_Enter(&p->cs); + + p->totalInSize += inSize; + p->totalOutSize += outSize; + if (p->res == SZ_OK && p->progress) + if (ICompressProgress_Progress(p->progress, p->totalInSize, p->totalOutSize) != SZ_OK) + p->res = SZ_ERROR_PROGRESS; + res = p->res; + + CriticalSection_Leave(&p->cs); + return res; +} + + +SRes MtProgress_GetError(CMtProgress *p) +{ + SRes res; + CriticalSection_Enter(&p->cs); + res = p->res; + CriticalSection_Leave(&p->cs); + return res; +} + + +void MtProgress_SetError(CMtProgress *p, SRes res) +{ + CriticalSection_Enter(&p->cs); + if (p->res == SZ_OK) + p->res = res; + CriticalSection_Leave(&p->cs); +} + + +#define RINOK_THREAD(x) RINOK_WRes(x) + + +struct CMtDecBufLink_ +{ + struct CMtDecBufLink_ *next; + void *pad[3]; +}; + +typedef struct CMtDecBufLink_ CMtDecBufLink; + +#define MTDEC__LINK_DATA_OFFSET sizeof(CMtDecBufLink) +#define MTDEC__DATA_PTR_FROM_LINK(link) ((Byte *)(link) + MTDEC__LINK_DATA_OFFSET) + + + +static THREAD_FUNC_DECL MtDec_ThreadFunc(void *pp); + + +static WRes MtDecThread_CreateEvents(CMtDecThread *t) +{ + WRes wres = AutoResetEvent_OptCreate_And_Reset(&t->canWrite); + if (wres == 0) + { + wres = AutoResetEvent_OptCreate_And_Reset(&t->canRead); + if (wres == 0) + return SZ_OK; + } + return wres; +} + + +static SRes MtDecThread_CreateAndStart(CMtDecThread *t) +{ + WRes wres = MtDecThread_CreateEvents(t); + // wres = 17; // for test + if (wres == 0) + { + if (Thread_WasCreated(&t->thread)) + return SZ_OK; + wres = Thread_Create(&t->thread, MtDec_ThreadFunc, t); + if (wres == 0) + return SZ_OK; + } + return MY_SRes_HRESULT_FROM_WRes(wres); +} + + +void MtDecThread_FreeInBufs(CMtDecThread *t) +{ + if (t->inBuf) + { + void *link = t->inBuf; + t->inBuf = NULL; + do + { + void *next = ((CMtDecBufLink *)link)->next; + ISzAlloc_Free(t->mtDec->alloc, link); + link = next; + } + while (link); + } +} + + +static void MtDecThread_CloseThread(CMtDecThread *t) +{ + if (Thread_WasCreated(&t->thread)) + { + Event_Set(&t->canWrite); /* we can disable it. There are no threads waiting canWrite in normal cases */ + Event_Set(&t->canRead); + Thread_Wait_Close(&t->thread); + } + + Event_Close(&t->canRead); + Event_Close(&t->canWrite); +} + +static void MtDec_CloseThreads(CMtDec *p) +{ + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + MtDecThread_CloseThread(&p->threads[i]); +} + +static void MtDecThread_Destruct(CMtDecThread *t) +{ + MtDecThread_CloseThread(t); + MtDecThread_FreeInBufs(t); +} + + + +static SRes MtDec_GetError_Spec(CMtDec *p, UInt64 interruptIndex, BoolInt *wasInterrupted) +{ + SRes res; + CriticalSection_Enter(&p->mtProgress.cs); + *wasInterrupted = (p->needInterrupt && interruptIndex > p->interruptIndex); + res = p->mtProgress.res; + CriticalSection_Leave(&p->mtProgress.cs); + return res; +} + +static SRes MtDec_Progress_GetError_Spec(CMtDec *p, UInt64 inSize, UInt64 outSize, UInt64 interruptIndex, BoolInt *wasInterrupted) +{ + SRes res; + CriticalSection_Enter(&p->mtProgress.cs); + + p->mtProgress.totalInSize += inSize; + p->mtProgress.totalOutSize += outSize; + if (p->mtProgress.res == SZ_OK && p->mtProgress.progress) + if (ICompressProgress_Progress(p->mtProgress.progress, p->mtProgress.totalInSize, p->mtProgress.totalOutSize) != SZ_OK) + p->mtProgress.res = SZ_ERROR_PROGRESS; + + *wasInterrupted = (p->needInterrupt && interruptIndex > p->interruptIndex); + res = p->mtProgress.res; + + CriticalSection_Leave(&p->mtProgress.cs); + + return res; +} + +static void MtDec_Interrupt(CMtDec *p, UInt64 interruptIndex) +{ + CriticalSection_Enter(&p->mtProgress.cs); + if (!p->needInterrupt || interruptIndex < p->interruptIndex) + { + p->interruptIndex = interruptIndex; + p->needInterrupt = True; + } + CriticalSection_Leave(&p->mtProgress.cs); +} + +Byte *MtDec_GetCrossBuff(CMtDec *p) +{ + Byte *cr = p->crossBlock; + if (!cr) + { + cr = (Byte *)ISzAlloc_Alloc(p->alloc, MTDEC__LINK_DATA_OFFSET + p->inBufSize); + if (!cr) + return NULL; + p->crossBlock = cr; + } + return MTDEC__DATA_PTR_FROM_LINK(cr); +} + + +/* + MtDec_ThreadFunc2() returns: + 0 - in all normal cases (even for stream error or memory allocation error) + (!= 0) - WRes error return by system threading function +*/ + +// #define MTDEC_ProgessStep (1 << 22) +#define MTDEC_ProgessStep (1 << 0) + +static WRes MtDec_ThreadFunc2(CMtDecThread *t) +{ + CMtDec *p = t->mtDec; + + PRF_STR_INT("MtDec_ThreadFunc2", t->index) + + // SetThreadAffinityMask(GetCurrentThread(), 1 << t->index); + + for (;;) + { + SRes res, codeRes; + BoolInt wasInterrupted, isAllocError, overflow, finish; + SRes threadingErrorSRes; + BoolInt needCode, needWrite, needContinue; + + size_t inDataSize_Start; + UInt64 inDataSize; + // UInt64 inDataSize_Full; + + UInt64 blockIndex; + + UInt64 inPrev = 0; + UInt64 outPrev = 0; + UInt64 inCodePos; + UInt64 outCodePos; + + Byte *afterEndData = NULL; + size_t afterEndData_Size = 0; + BoolInt afterEndData_IsCross = False; + + BoolInt canCreateNewThread = False; + // CMtDecCallbackInfo parse; + CMtDecThread *nextThread; + + PRF_STR_INT("=============== Event_Wait(&t->canRead)", t->index) + + RINOK_THREAD(Event_Wait(&t->canRead)) + if (p->exitThread) + return 0; + + PRF_STR_INT("after Event_Wait(&t->canRead)", t->index) + + // if (t->index == 3) return 19; // for test + + blockIndex = p->blockIndex++; + + // PRF(printf("\ncanRead\n")) + + res = MtDec_Progress_GetError_Spec(p, 0, 0, blockIndex, &wasInterrupted); + + finish = p->readWasFinished; + needCode = False; + needWrite = False; + isAllocError = False; + overflow = False; + + inDataSize_Start = 0; + inDataSize = 0; + // inDataSize_Full = 0; + + if (res == SZ_OK && !wasInterrupted) + { + // if (p->inStream) + { + CMtDecBufLink *prev = NULL; + CMtDecBufLink *link = (CMtDecBufLink *)t->inBuf; + size_t crossSize = p->crossEnd - p->crossStart; + + PRF(printf("\ncrossSize = %d\n", crossSize)); + + for (;;) + { + if (!link) + { + link = (CMtDecBufLink *)ISzAlloc_Alloc(p->alloc, MTDEC__LINK_DATA_OFFSET + p->inBufSize); + if (!link) + { + finish = True; + // p->allocError_for_Read_BlockIndex = blockIndex; + isAllocError = True; + break; + } + link->next = NULL; + if (prev) + { + // static unsigned g_num = 0; + // printf("\n%6d : %x", ++g_num, (unsigned)(size_t)((Byte *)link - (Byte *)prev)); + prev->next = link; + } + else + t->inBuf = (void *)link; + } + + { + Byte *data = MTDEC__DATA_PTR_FROM_LINK(link); + Byte *parseData = data; + size_t size; + + if (crossSize != 0) + { + inDataSize = crossSize; + // inDataSize_Full = inDataSize; + inDataSize_Start = crossSize; + size = crossSize; + parseData = MTDEC__DATA_PTR_FROM_LINK(p->crossBlock) + p->crossStart; + PRF(printf("\ncross : crossStart = %7d crossEnd = %7d finish = %1d", + (int)p->crossStart, (int)p->crossEnd, (int)finish)); + } + else + { + size = p->inBufSize; + + res = SeqInStream_ReadMax(p->inStream, data, &size); + + // size = 10; // test + + inDataSize += size; + // inDataSize_Full = inDataSize; + if (!prev) + inDataSize_Start = size; + + p->readProcessed += size; + finish = (size != p->inBufSize); + if (finish) + p->readWasFinished = True; + + // res = E_INVALIDARG; // test + + if (res != SZ_OK) + { + // PRF(printf("\nRead error = %d\n", res)) + // we want to decode all data before error + p->readRes = res; + // p->readError_BlockIndex = blockIndex; + p->readWasFinished = True; + finish = True; + res = SZ_OK; + // break; + } + + if (inDataSize - inPrev >= MTDEC_ProgessStep) + { + res = MtDec_Progress_GetError_Spec(p, 0, 0, blockIndex, &wasInterrupted); + if (res != SZ_OK || wasInterrupted) + break; + inPrev = inDataSize; + } + } + + { + CMtDecCallbackInfo parse; + + parse.startCall = (prev == NULL); + parse.src = parseData; + parse.srcSize = size; + parse.srcFinished = finish; + parse.canCreateNewThread = True; + + PRF(printf("\nParse size = %d\n", (unsigned)size)); + + p->mtCallback->Parse(p->mtCallbackObject, t->index, &parse); + + PRF(printf(" Parse processed = %d, state = %d \n", (unsigned)parse.srcSize, (unsigned)parse.state)); + + needWrite = True; + canCreateNewThread = parse.canCreateNewThread; + + // printf("\n\n%12I64u %12I64u", (UInt64)p->mtProgress.totalInSize, (UInt64)p->mtProgress.totalOutSize); + + if ( + // parseRes != SZ_OK || + // inDataSize - (size - parse.srcSize) > p->inBlockMax + // || + parse.state == MTDEC_PARSE_OVERFLOW + // || wasInterrupted + ) + { + // Overflow or Parse error - switch from MT decoding to ST decoding + finish = True; + overflow = True; + + { + PRF(printf("\n Overflow")); + // PRF(printf("\nisBlockFinished = %d", (unsigned)parse.blockWasFinished)); + PRF(printf("\n inDataSize = %d", (unsigned)inDataSize)); + } + + if (crossSize != 0) + memcpy(data, parseData, size); + p->crossStart = 0; + p->crossEnd = 0; + break; + } + + if (crossSize != 0) + { + memcpy(data, parseData, parse.srcSize); + p->crossStart += parse.srcSize; + } + + if (parse.state != MTDEC_PARSE_CONTINUE || finish) + { + // we don't need to parse in current thread anymore + + if (parse.state == MTDEC_PARSE_END) + finish = True; + + needCode = True; + // p->crossFinished = finish; + + if (parse.srcSize == size) + { + // full parsed - no cross transfer + p->crossStart = 0; + p->crossEnd = 0; + break; + } + + if (parse.state == MTDEC_PARSE_END) + { + afterEndData = parseData + parse.srcSize; + afterEndData_Size = size - parse.srcSize; + if (crossSize != 0) + afterEndData_IsCross = True; + // we reduce data size to required bytes (parsed only) + inDataSize -= afterEndData_Size; + if (!prev) + inDataSize_Start = parse.srcSize; + break; + } + + { + // partial parsed - need cross transfer + if (crossSize != 0) + inDataSize = parse.srcSize; // it's only parsed now + else + { + // partial parsed - is not in initial cross block - we need to copy new data to cross block + Byte *cr = MtDec_GetCrossBuff(p); + if (!cr) + { + { + PRF(printf("\ncross alloc error error\n")); + // res = SZ_ERROR_MEM; + finish = True; + // p->allocError_for_Read_BlockIndex = blockIndex; + isAllocError = True; + break; + } + } + + { + size_t crSize = size - parse.srcSize; + inDataSize -= crSize; + p->crossEnd = crSize; + p->crossStart = 0; + memcpy(cr, parseData + parse.srcSize, crSize); + } + } + + // inDataSize_Full = inDataSize; + if (!prev) + inDataSize_Start = parse.srcSize; // it's partial size (parsed only) + + finish = False; + break; + } + } + + if (parse.srcSize != size) + { + res = SZ_ERROR_FAIL; + PRF(printf("\nfinished error SZ_ERROR_FAIL = %d\n", res)); + break; + } + } + } + + prev = link; + link = link->next; + + if (crossSize != 0) + { + crossSize = 0; + p->crossStart = 0; + p->crossEnd = 0; + } + } + } + + if (res == SZ_OK) + res = MtDec_GetError_Spec(p, blockIndex, &wasInterrupted); + } + + codeRes = SZ_OK; + + if (res == SZ_OK && needCode && !wasInterrupted) + { + codeRes = p->mtCallback->PreCode(p->mtCallbackObject, t->index); + if (codeRes != SZ_OK) + { + needCode = False; + finish = True; + // SZ_ERROR_MEM is expected error here. + // if (codeRes == SZ_ERROR_MEM) - we will try single-thread decoding later. + // if (codeRes != SZ_ERROR_MEM) - we can stop decoding or try single-thread decoding. + } + } + + if (res != SZ_OK || wasInterrupted) + finish = True; + + nextThread = NULL; + threadingErrorSRes = SZ_OK; + + if (!finish) + { + if (p->numStartedThreads < p->numStartedThreads_Limit && canCreateNewThread) + { + SRes res2 = MtDecThread_CreateAndStart(&p->threads[p->numStartedThreads]); + if (res2 == SZ_OK) + { + // if (p->numStartedThreads % 1000 == 0) PRF(printf("\n numStartedThreads=%d\n", p->numStartedThreads)); + p->numStartedThreads++; + } + else + { + PRF(printf("\nERROR: numStartedThreads=%d\n", p->numStartedThreads)); + if (p->numStartedThreads == 1) + { + // if only one thread is possible, we leave muti-threading code + finish = True; + needCode = False; + threadingErrorSRes = res2; + } + else + p->numStartedThreads_Limit = p->numStartedThreads; + } + } + + if (!finish) + { + unsigned nextIndex = t->index + 1; + nextThread = &p->threads[nextIndex >= p->numStartedThreads ? 0 : nextIndex]; + RINOK_THREAD(Event_Set(&nextThread->canRead)) + // We have started executing for new iteration (with next thread) + // And that next thread now is responsible for possible exit from decoding (threading_code) + } + } + + // each call of Event_Set(&nextThread->canRead) must be followed by call of Event_Set(&nextThread->canWrite) + // if ( !finish ) we must call Event_Set(&nextThread->canWrite) in any case + // if ( finish ) we switch to single-thread mode and there are 2 ways at the end of current iteration (current block): + // - if (needContinue) after Write(&needContinue), we restore decoding with new iteration + // - otherwise we stop decoding and exit from MtDec_ThreadFunc2() + + // Don't change (finish) variable in the further code + + + // ---------- CODE ---------- + + inPrev = 0; + outPrev = 0; + inCodePos = 0; + outCodePos = 0; + + if (res == SZ_OK && needCode && codeRes == SZ_OK) + { + BoolInt isStartBlock = True; + CMtDecBufLink *link = (CMtDecBufLink *)t->inBuf; + + for (;;) + { + size_t inSize; + int stop; + + if (isStartBlock) + inSize = inDataSize_Start; + else + { + UInt64 rem = inDataSize - inCodePos; + inSize = p->inBufSize; + if (inSize > rem) + inSize = (size_t)rem; + } + + inCodePos += inSize; + stop = True; + + codeRes = p->mtCallback->Code(p->mtCallbackObject, t->index, + (const Byte *)MTDEC__DATA_PTR_FROM_LINK(link), inSize, + (inCodePos == inDataSize), // srcFinished + &inCodePos, &outCodePos, &stop); + + if (codeRes != SZ_OK) + { + PRF(printf("\nCode Interrupt error = %x\n", codeRes)); + // we interrupt only later blocks + MtDec_Interrupt(p, blockIndex); + break; + } + + if (stop || inCodePos == inDataSize) + break; + + { + const UInt64 inDelta = inCodePos - inPrev; + const UInt64 outDelta = outCodePos - outPrev; + if (inDelta >= MTDEC_ProgessStep || outDelta >= MTDEC_ProgessStep) + { + // Sleep(1); + res = MtDec_Progress_GetError_Spec(p, inDelta, outDelta, blockIndex, &wasInterrupted); + if (res != SZ_OK || wasInterrupted) + break; + inPrev = inCodePos; + outPrev = outCodePos; + } + } + + link = link->next; + isStartBlock = False; + } + } + + + // ---------- WRITE ---------- + + RINOK_THREAD(Event_Wait(&t->canWrite)) + + { + BoolInt isErrorMode = False; + BoolInt canRecode = True; + BoolInt needWriteToStream = needWrite; + + if (p->exitThread) return 0; // it's never executed in normal cases + + if (p->wasInterrupted) + wasInterrupted = True; + else + { + if (codeRes != SZ_OK) // || !needCode // check it !!! + { + p->wasInterrupted = True; + p->codeRes = codeRes; + if (codeRes == SZ_ERROR_MEM) + isAllocError = True; + } + + if (threadingErrorSRes) + { + p->wasInterrupted = True; + p->threadingErrorSRes = threadingErrorSRes; + needWriteToStream = False; + } + if (isAllocError) + { + p->wasInterrupted = True; + p->isAllocError = True; + needWriteToStream = False; + } + if (overflow) + { + p->wasInterrupted = True; + p->overflow = True; + needWriteToStream = False; + } + } + + if (needCode) + { + if (wasInterrupted) + { + inCodePos = 0; + outCodePos = 0; + } + { + const UInt64 inDelta = inCodePos - inPrev; + const UInt64 outDelta = outCodePos - outPrev; + // if (inDelta != 0 || outDelta != 0) + res = MtProgress_ProgressAdd(&p->mtProgress, inDelta, outDelta); + } + } + + needContinue = (!finish); + + // if (res == SZ_OK && needWrite && !wasInterrupted) + if (needWrite) + { + // p->inProcessed += inCodePos; + + PRF(printf("\n--Write afterSize = %d\n", (unsigned)afterEndData_Size)); + + res = p->mtCallback->Write(p->mtCallbackObject, t->index, + res == SZ_OK && needWriteToStream && !wasInterrupted, // needWrite + afterEndData, afterEndData_Size, afterEndData_IsCross, + &needContinue, + &canRecode); + + // res = SZ_ERROR_FAIL; // for test + + PRF(printf("\nAfter Write needContinue = %d\n", (unsigned)needContinue)); + PRF(printf("\nprocessed = %d\n", (unsigned)p->inProcessed)); + + if (res != SZ_OK) + { + PRF(printf("\nWrite error = %d\n", res)); + isErrorMode = True; + p->wasInterrupted = True; + } + if (res != SZ_OK + || (!needContinue && !finish)) + { + PRF(printf("\nWrite Interrupt error = %x\n", res)); + MtDec_Interrupt(p, blockIndex); + } + } + + if (canRecode) + if (!needCode + || res != SZ_OK + || p->wasInterrupted + || codeRes != SZ_OK + || wasInterrupted + || p->numFilledThreads != 0 + || isErrorMode) + { + if (p->numFilledThreads == 0) + p->filledThreadStart = t->index; + if (inDataSize != 0 || !finish) + { + t->inDataSize_Start = inDataSize_Start; + t->inDataSize = inDataSize; + p->numFilledThreads++; + } + PRF(printf("\np->numFilledThreads = %d\n", p->numFilledThreads)); + PRF(printf("p->filledThreadStart = %d\n", p->filledThreadStart)); + } + + if (!finish) + { + RINOK_THREAD(Event_Set(&nextThread->canWrite)) + } + else + { + if (needContinue) + { + // we restore decoding with new iteration + RINOK_THREAD(Event_Set(&p->threads[0].canWrite)) + } + else + { + // we exit from decoding + if (t->index == 0) + return SZ_OK; + p->exitThread = True; + } + RINOK_THREAD(Event_Set(&p->threads[0].canRead)) + } + } + } +} + +#ifdef _WIN32 +#define USE_ALLOCA +#endif + +#ifdef USE_ALLOCA +#ifdef _WIN32 +#include +#else +#include +#endif +#endif + + +static THREAD_FUNC_DECL MtDec_ThreadFunc1(void *pp) +{ + WRes res; + + CMtDecThread *t = (CMtDecThread *)pp; + CMtDec *p; + + // fprintf(stdout, "\n%d = %p\n", t->index, &t); + + res = MtDec_ThreadFunc2(t); + p = t->mtDec; + if (res == 0) + return (THREAD_FUNC_RET_TYPE)(UINT_PTR)p->exitThreadWRes; + { + // it's unexpected situation for some threading function error + if (p->exitThreadWRes == 0) + p->exitThreadWRes = res; + PRF(printf("\nthread exit error = %d\n", res)); + p->exitThread = True; + Event_Set(&p->threads[0].canRead); + Event_Set(&p->threads[0].canWrite); + MtProgress_SetError(&p->mtProgress, MY_SRes_HRESULT_FROM_WRes(res)); + } + return (THREAD_FUNC_RET_TYPE)(UINT_PTR)res; +} + +static Z7_NO_INLINE THREAD_FUNC_DECL MtDec_ThreadFunc(void *pp) +{ + #ifdef USE_ALLOCA + CMtDecThread *t = (CMtDecThread *)pp; + // fprintf(stderr, "\n%d = %p - before", t->index, &t); + t->allocaPtr = alloca(t->index * 128); + #endif + return MtDec_ThreadFunc1(pp); +} + + +int MtDec_PrepareRead(CMtDec *p) +{ + if (p->crossBlock && p->crossStart == p->crossEnd) + { + ISzAlloc_Free(p->alloc, p->crossBlock); + p->crossBlock = NULL; + } + + { + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + if (i > p->numStartedThreads + || p->numFilledThreads <= + (i >= p->filledThreadStart ? + i - p->filledThreadStart : + i + p->numStartedThreads - p->filledThreadStart)) + MtDecThread_FreeInBufs(&p->threads[i]); + } + + return (p->numFilledThreads != 0) || (p->crossStart != p->crossEnd); +} + + +const Byte *MtDec_Read(CMtDec *p, size_t *inLim) +{ + while (p->numFilledThreads != 0) + { + CMtDecThread *t = &p->threads[p->filledThreadStart]; + + if (*inLim != 0) + { + { + void *link = t->inBuf; + void *next = ((CMtDecBufLink *)link)->next; + ISzAlloc_Free(p->alloc, link); + t->inBuf = next; + } + + if (t->inDataSize == 0) + { + MtDecThread_FreeInBufs(t); + if (--p->numFilledThreads == 0) + break; + if (++p->filledThreadStart == p->numStartedThreads) + p->filledThreadStart = 0; + t = &p->threads[p->filledThreadStart]; + } + } + + { + size_t lim = t->inDataSize_Start; + if (lim != 0) + t->inDataSize_Start = 0; + else + { + UInt64 rem = t->inDataSize; + lim = p->inBufSize; + if (lim > rem) + lim = (size_t)rem; + } + t->inDataSize -= lim; + *inLim = lim; + return (const Byte *)MTDEC__DATA_PTR_FROM_LINK(t->inBuf); + } + } + + { + size_t crossSize = p->crossEnd - p->crossStart; + if (crossSize != 0) + { + const Byte *data = MTDEC__DATA_PTR_FROM_LINK(p->crossBlock) + p->crossStart; + *inLim = crossSize; + p->crossStart = 0; + p->crossEnd = 0; + return data; + } + *inLim = 0; + if (p->crossBlock) + { + ISzAlloc_Free(p->alloc, p->crossBlock); + p->crossBlock = NULL; + } + return NULL; + } +} + + +void MtDec_Construct(CMtDec *p) +{ + unsigned i; + + p->inBufSize = (size_t)1 << 18; + + p->numThreadsMax = 0; + + p->inStream = NULL; + + // p->inData = NULL; + // p->inDataSize = 0; + + p->crossBlock = NULL; + p->crossStart = 0; + p->crossEnd = 0; + + p->numFilledThreads = 0; + + p->progress = NULL; + p->alloc = NULL; + + p->mtCallback = NULL; + p->mtCallbackObject = NULL; + + p->allocatedBufsSize = 0; + + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CMtDecThread *t = &p->threads[i]; + t->mtDec = p; + t->index = i; + t->inBuf = NULL; + Event_Construct(&t->canRead); + Event_Construct(&t->canWrite); + Thread_CONSTRUCT(&t->thread) + } + + // Event_Construct(&p->finishedEvent); + + CriticalSection_Init(&p->mtProgress.cs); +} + + +static void MtDec_Free(CMtDec *p) +{ + unsigned i; + + p->exitThread = True; + + for (i = 0; i < MTDEC_THREADS_MAX; i++) + MtDecThread_Destruct(&p->threads[i]); + + // Event_Close(&p->finishedEvent); + + if (p->crossBlock) + { + ISzAlloc_Free(p->alloc, p->crossBlock); + p->crossBlock = NULL; + } +} + + +void MtDec_Destruct(CMtDec *p) +{ + MtDec_Free(p); + + CriticalSection_Delete(&p->mtProgress.cs); +} + + +SRes MtDec_Code(CMtDec *p) +{ + unsigned i; + + p->inProcessed = 0; + + p->blockIndex = 1; // it must be larger than not_defined index (0) + p->isAllocError = False; + p->overflow = False; + p->threadingErrorSRes = SZ_OK; + + p->needContinue = True; + + p->readWasFinished = False; + p->needInterrupt = False; + p->interruptIndex = (UInt64)(Int64)-1; + + p->readProcessed = 0; + p->readRes = SZ_OK; + p->codeRes = SZ_OK; + p->wasInterrupted = False; + + p->crossStart = 0; + p->crossEnd = 0; + + p->filledThreadStart = 0; + p->numFilledThreads = 0; + + { + unsigned numThreads = p->numThreadsMax; + if (numThreads > MTDEC_THREADS_MAX) + numThreads = MTDEC_THREADS_MAX; + p->numStartedThreads_Limit = numThreads; + p->numStartedThreads = 0; + } + + if (p->inBufSize != p->allocatedBufsSize) + { + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CMtDecThread *t = &p->threads[i]; + if (t->inBuf) + MtDecThread_FreeInBufs(t); + } + if (p->crossBlock) + { + ISzAlloc_Free(p->alloc, p->crossBlock); + p->crossBlock = NULL; + } + + p->allocatedBufsSize = p->inBufSize; + } + + MtProgress_Init(&p->mtProgress, p->progress); + + // RINOK_THREAD(AutoResetEvent_OptCreate_And_Reset(&p->finishedEvent)) + p->exitThread = False; + p->exitThreadWRes = 0; + + { + WRes wres; + SRes sres; + CMtDecThread *nextThread = &p->threads[p->numStartedThreads++]; + // wres = MtDecThread_CreateAndStart(nextThread); + wres = MtDecThread_CreateEvents(nextThread); + if (wres == 0) { wres = Event_Set(&nextThread->canWrite); + if (wres == 0) { wres = Event_Set(&nextThread->canRead); + if (wres == 0) { THREAD_FUNC_RET_TYPE res = MtDec_ThreadFunc(nextThread); + wres = (WRes)(UINT_PTR)res; + if (wres != 0) + { + p->needContinue = False; + MtDec_CloseThreads(p); + }}}} + + // wres = 17; // for test + // wres = Event_Wait(&p->finishedEvent); + + sres = MY_SRes_HRESULT_FROM_WRes(wres); + + if (sres != 0) + p->threadingErrorSRes = sres; + + if ( + // wres == 0 + // wres != 0 + // || p->mtc.codeRes == SZ_ERROR_MEM + p->isAllocError + || p->threadingErrorSRes != SZ_OK + || p->overflow) + { + // p->needContinue = True; + } + else + p->needContinue = False; + + if (p->needContinue) + return SZ_OK; + + // if (sres != SZ_OK) + return sres; + // return SZ_ERROR_FAIL; + } +} + +#endif + +#undef PRF diff --git a/libraries/lzma/C/MtDec.h b/libraries/lzma/C/MtDec.h new file mode 100644 index 000000000..c28e8d9ac --- /dev/null +++ b/libraries/lzma/C/MtDec.h @@ -0,0 +1,202 @@ +/* MtDec.h -- Multi-thread Decoder +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_MT_DEC_H +#define ZIP7_INC_MT_DEC_H + +#include "7zTypes.h" + +#ifndef Z7_ST +#include "Threads.h" +#endif + +EXTERN_C_BEGIN + +#ifndef Z7_ST + +#ifndef Z7_ST + #define MTDEC_THREADS_MAX 32 +#else + #define MTDEC_THREADS_MAX 1 +#endif + + +typedef struct +{ + ICompressProgressPtr progress; + SRes res; + UInt64 totalInSize; + UInt64 totalOutSize; + CCriticalSection cs; +} CMtProgress; + +void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress); +SRes MtProgress_Progress_ST(CMtProgress *p); +SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize); +SRes MtProgress_GetError(CMtProgress *p); +void MtProgress_SetError(CMtProgress *p, SRes res); + +struct CMtDec; + +typedef struct +{ + struct CMtDec_ *mtDec; + unsigned index; + void *inBuf; + + size_t inDataSize_Start; // size of input data in start block + UInt64 inDataSize; // total size of input data in all blocks + + CThread thread; + CAutoResetEvent canRead; + CAutoResetEvent canWrite; + void *allocaPtr; +} CMtDecThread; + +void MtDecThread_FreeInBufs(CMtDecThread *t); + + +typedef enum +{ + MTDEC_PARSE_CONTINUE, // continue this block with more input data + MTDEC_PARSE_OVERFLOW, // MT buffers overflow, need switch to single-thread + MTDEC_PARSE_NEW, // new block + MTDEC_PARSE_END // end of block threading. But we still can return to threading after Write(&needContinue) +} EMtDecParseState; + +typedef struct +{ + // in + int startCall; + const Byte *src; + size_t srcSize; + // in : (srcSize == 0) is allowed + // out : it's allowed to return less that actually was used ? + int srcFinished; + + // out + EMtDecParseState state; + BoolInt canCreateNewThread; + UInt64 outPos; // check it (size_t) +} CMtDecCallbackInfo; + + +typedef struct +{ + void (*Parse)(void *p, unsigned coderIndex, CMtDecCallbackInfo *ci); + + // PreCode() and Code(): + // (SRes_return_result != SZ_OK) means stop decoding, no need another blocks + SRes (*PreCode)(void *p, unsigned coderIndex); + SRes (*Code)(void *p, unsigned coderIndex, + const Byte *src, size_t srcSize, int srcFinished, + UInt64 *inCodePos, UInt64 *outCodePos, int *stop); + // stop - means stop another Code calls + + + /* Write() must be called, if Parse() was called + set (needWrite) if + { + && (was not interrupted by progress) + && (was not interrupted in previous block) + } + + out: + if (*needContinue), decoder still need to continue decoding with new iteration, + even after MTDEC_PARSE_END + if (*canRecode), we didn't flush current block data, so we still can decode current block later. + */ + SRes (*Write)(void *p, unsigned coderIndex, + BoolInt needWriteToStream, + const Byte *src, size_t srcSize, BoolInt isCross, + // int srcFinished, + BoolInt *needContinue, + BoolInt *canRecode); + +} IMtDecCallback2; + + + +typedef struct CMtDec_ +{ + /* input variables */ + + size_t inBufSize; /* size of input block */ + unsigned numThreadsMax; + // size_t inBlockMax; + unsigned numThreadsMax_2; + + ISeqInStreamPtr inStream; + // const Byte *inData; + // size_t inDataSize; + + ICompressProgressPtr progress; + ISzAllocPtr alloc; + + IMtDecCallback2 *mtCallback; + void *mtCallbackObject; + + + /* internal variables */ + + size_t allocatedBufsSize; + + BoolInt exitThread; + WRes exitThreadWRes; + + UInt64 blockIndex; + BoolInt isAllocError; + BoolInt overflow; + SRes threadingErrorSRes; + + BoolInt needContinue; + + // CAutoResetEvent finishedEvent; + + SRes readRes; + SRes codeRes; + + BoolInt wasInterrupted; + + unsigned numStartedThreads_Limit; + unsigned numStartedThreads; + + Byte *crossBlock; + size_t crossStart; + size_t crossEnd; + UInt64 readProcessed; + BoolInt readWasFinished; + UInt64 inProcessed; + + unsigned filledThreadStart; + unsigned numFilledThreads; + + #ifndef Z7_ST + BoolInt needInterrupt; + UInt64 interruptIndex; + CMtProgress mtProgress; + CMtDecThread threads[MTDEC_THREADS_MAX]; + #endif +} CMtDec; + + +void MtDec_Construct(CMtDec *p); +void MtDec_Destruct(CMtDec *p); + +/* +MtDec_Code() returns: + SZ_OK - in most cases + MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function +*/ + +SRes MtDec_Code(CMtDec *p); +Byte *MtDec_GetCrossBuff(CMtDec *p); + +int MtDec_PrepareRead(CMtDec *p); +const Byte *MtDec_Read(CMtDec *p, size_t *inLim); + +#endif + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/Ppmd.h b/libraries/lzma/C/Ppmd.h index b19879208..66b26266f 100644 --- a/libraries/lzma/C/Ppmd.h +++ b/libraries/lzma/C/Ppmd.h @@ -1,9 +1,9 @@ /* Ppmd.h -- PPMD codec common code -2021-04-13 : Igor Pavlov : Public domain +2023-03-05 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ -#ifndef __PPMD_H -#define __PPMD_H +#ifndef ZIP7_INC_PPMD_H +#define ZIP7_INC_PPMD_H #include "CpuArch.h" @@ -48,8 +48,10 @@ typedef struct Byte Count; /* Count to next change of Shift */ } CPpmd_See; -#define Ppmd_See_Update(p) if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ - { (p)->Summ = (UInt16)((p)->Summ << 1); (p)->Count = (Byte)(3 << (p)->Shift++); } +#define Ppmd_See_UPDATE(p) \ + { if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \ + { (p)->Summ = (UInt16)((p)->Summ << 1); \ + (p)->Count = (Byte)(3 << (p)->Shift++); }} typedef struct diff --git a/libraries/lzma/C/Ppmd7.c b/libraries/lzma/C/Ppmd7.c index cf401cb37..6e1307e2d 100644 --- a/libraries/lzma/C/Ppmd7.c +++ b/libraries/lzma/C/Ppmd7.c @@ -1,5 +1,5 @@ /* Ppmd7.c -- PPMdH codec -2021-04-13 : Igor Pavlov : Public domain +2023-04-02 : Igor Pavlov : Public domain This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ #include "Precomp.h" @@ -14,7 +14,7 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */ MY_ALIGN(16) static const Byte PPMD7_kExpEscape[16] = { 25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 }; MY_ALIGN(16) -static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; +static const UInt16 PPMD7_kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051}; #define MAX_FREQ 124 #define UNIT_SIZE 12 @@ -33,7 +33,7 @@ static const UInt16 kInitBinEsc[] = { 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x #define ONE_STATE(ctx) Ppmd7Context_OneState(ctx) #define SUFFIX(ctx) CTX((ctx)->Suffix) -typedef CPpmd7_Context * CTX_PTR; +typedef CPpmd7_Context * PPMD7_CTX_PTR; struct CPpmd7_Node_; @@ -107,14 +107,14 @@ BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc) // ---------- Internal Memory Allocator ---------- /* We can use CPpmd7_Node in list of free units (as in Ppmd8) - But we still need one additional list walk pass in GlueFreeBlocks(). - So we use simple CPpmd_Void_Ref instead of CPpmd7_Node in InsertNode() / RemoveNode() + But we still need one additional list walk pass in Ppmd7_GlueFreeBlocks(). + So we use simple CPpmd_Void_Ref instead of CPpmd7_Node in Ppmd7_InsertNode() / Ppmd7_RemoveNode() */ #define EMPTY_NODE 0 -static void InsertNode(CPpmd7 *p, void *node, unsigned indx) +static void Ppmd7_InsertNode(CPpmd7 *p, void *node, unsigned indx) { *((CPpmd_Void_Ref *)node) = p->FreeList[indx]; // ((CPpmd7_Node *)node)->Next = (CPpmd7_Node_Ref)p->FreeList[indx]; @@ -124,7 +124,7 @@ static void InsertNode(CPpmd7 *p, void *node, unsigned indx) } -static void *RemoveNode(CPpmd7 *p, unsigned indx) +static void *Ppmd7_RemoveNode(CPpmd7 *p, unsigned indx) { CPpmd_Void_Ref *node = (CPpmd_Void_Ref *)Ppmd7_GetPtr(p, p->FreeList[indx]); p->FreeList[indx] = *node; @@ -134,32 +134,32 @@ static void *RemoveNode(CPpmd7 *p, unsigned indx) } -static void SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) +static void Ppmd7_SplitBlock(CPpmd7 *p, void *ptr, unsigned oldIndx, unsigned newIndx) { unsigned i, nu = I2U(oldIndx) - I2U(newIndx); ptr = (Byte *)ptr + U2B(I2U(newIndx)); if (I2U(i = U2I(nu)) != nu) { unsigned k = I2U(--i); - InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); + Ppmd7_InsertNode(p, ((Byte *)ptr) + U2B(k), nu - k - 1); } - InsertNode(p, ptr, i); + Ppmd7_InsertNode(p, ptr, i); } /* we use CPpmd7_Node_Union union to solve XLC -O2 strict pointer aliasing problem */ -typedef union _CPpmd7_Node_Union +typedef union { CPpmd7_Node Node; CPpmd7_Node_Ref NextRef; } CPpmd7_Node_Union; -/* Original PPmdH (Ppmd7) code uses doubly linked list in GlueFreeBlocks() +/* Original PPmdH (Ppmd7) code uses doubly linked list in Ppmd7_GlueFreeBlocks() we use single linked list similar to Ppmd8 code */ -static void GlueFreeBlocks(CPpmd7 *p) +static void Ppmd7_GlueFreeBlocks(CPpmd7 *p) { /* we use first UInt16 field of 12-bytes UNITs as record type stamp @@ -239,27 +239,27 @@ static void GlueFreeBlocks(CPpmd7 *p) if (nu == 0) continue; for (; nu > 128; nu -= 128, node += 128) - InsertNode(p, node, PPMD_NUM_INDEXES - 1); + Ppmd7_InsertNode(p, node, PPMD_NUM_INDEXES - 1); if (I2U(i = U2I(nu)) != nu) { unsigned k = I2U(--i); - InsertNode(p, node + k, (unsigned)nu - k - 1); + Ppmd7_InsertNode(p, node + k, (unsigned)nu - k - 1); } - InsertNode(p, node, i); + Ppmd7_InsertNode(p, node, i); } } -MY_NO_INLINE -static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) +Z7_NO_INLINE +static void *Ppmd7_AllocUnitsRare(CPpmd7 *p, unsigned indx) { unsigned i; if (p->GlueCount == 0) { - GlueFreeBlocks(p); + Ppmd7_GlueFreeBlocks(p); if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); + return Ppmd7_RemoveNode(p, indx); } i = indx; @@ -277,17 +277,17 @@ static void *AllocUnitsRare(CPpmd7 *p, unsigned indx) while (p->FreeList[i] == 0); { - void *block = RemoveNode(p, i); - SplitBlock(p, block, i, indx); + void *block = Ppmd7_RemoveNode(p, i); + Ppmd7_SplitBlock(p, block, i, indx); return block; } } -static void *AllocUnits(CPpmd7 *p, unsigned indx) +static void *Ppmd7_AllocUnits(CPpmd7 *p, unsigned indx) { if (p->FreeList[indx] != 0) - return RemoveNode(p, indx); + return Ppmd7_RemoveNode(p, indx); { UInt32 numBytes = U2B(I2U(indx)); Byte *lo = p->LoUnit; @@ -297,11 +297,11 @@ static void *AllocUnits(CPpmd7 *p, unsigned indx) return lo; } } - return AllocUnitsRare(p, indx); + return Ppmd7_AllocUnitsRare(p, indx); } -#define MyMem12Cpy(dest, src, num) \ +#define MEM_12_CPY(dest, src, num) \ { UInt32 *d = (UInt32 *)dest; const UInt32 *z = (const UInt32 *)src; UInt32 n = num; \ do { d[0] = z[0]; d[1] = z[1]; d[2] = z[2]; z += 3; d += 3; } while (--n); } @@ -315,12 +315,12 @@ static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU return oldPtr; if (p->FreeList[i1] != 0) { - void *ptr = RemoveNode(p, i1); - MyMem12Cpy(ptr, oldPtr, newNU); - InsertNode(p, oldPtr, i0); + void *ptr = Ppmd7_RemoveNode(p, i1); + MEM_12_CPY(ptr, oldPtr, newNU) + Ppmd7_InsertNode(p, oldPtr, i0); return ptr; } - SplitBlock(p, oldPtr, i0, i1); + Ppmd7_SplitBlock(p, oldPtr, i0, i1); return oldPtr; } */ @@ -329,14 +329,14 @@ static void *ShrinkUnits(CPpmd7 *p, void *oldPtr, unsigned oldNU, unsigned newNU #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) { - Ppmd_SET_SUCCESSOR(p, v); + Ppmd_SET_SUCCESSOR(p, v) } -MY_NO_INLINE +Z7_NO_INLINE static -void RestartModel(CPpmd7 *p) +void Ppmd7_RestartModel(CPpmd7 *p) { unsigned i, k; @@ -352,8 +352,8 @@ void RestartModel(CPpmd7 *p) p->PrevSuccess = 0; { - CPpmd7_Context *mc = (CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ - CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ + CPpmd7_Context *mc = (PPMD7_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); /* AllocContext(p); */ + CPpmd_State *s = (CPpmd_State *)p->LoUnit; /* Ppmd7_AllocUnits(p, PPMD_NUM_INDEXES - 1); */ p->LoUnit += U2B(256 / 2); p->MaxContext = p->MinContext = mc; @@ -391,7 +391,7 @@ void RestartModel(CPpmd7 *p) { unsigned m; UInt16 *dest = p->BinSumm[i] + k; - UInt16 val = (UInt16)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); + const UInt16 val = (UInt16)(PPMD_BIN_SCALE - PPMD7_kInitBinEsc[k] / (i + 2)); for (m = 0; m < 64; m += 8) dest[m] = val; } @@ -423,13 +423,13 @@ void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) { p->MaxOrder = maxOrder; - RestartModel(p); + Ppmd7_RestartModel(p); } /* - CreateSuccessors() + Ppmd7_CreateSuccessors() It's called when (FoundState->Successor) is RAW-Successor, that is the link to position in Raw text. So we create Context records and write the links to @@ -445,10 +445,10 @@ void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder) also it can return pointer to real context of same order, */ -MY_NO_INLINE -static CTX_PTR CreateSuccessors(CPpmd7 *p) +Z7_NO_INLINE +static PPMD7_CTX_PTR Ppmd7_CreateSuccessors(CPpmd7 *p) { - CTX_PTR c = p->MinContext; + PPMD7_CTX_PTR c = p->MinContext; CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p->FoundState); Byte newSym, newFreq; unsigned numPs = 0; @@ -522,15 +522,15 @@ static CTX_PTR CreateSuccessors(CPpmd7 *p) do { - CTX_PTR c1; + PPMD7_CTX_PTR c1; /* = AllocContext(p); */ if (p->HiUnit != p->LoUnit) - c1 = (CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); + c1 = (PPMD7_CTX_PTR)(void *)(p->HiUnit -= UNIT_SIZE); else if (p->FreeList[0] != 0) - c1 = (CTX_PTR)RemoveNode(p, 0); + c1 = (PPMD7_CTX_PTR)Ppmd7_RemoveNode(p, 0); else { - c1 = (CTX_PTR)AllocUnitsRare(p, 0); + c1 = (PPMD7_CTX_PTR)Ppmd7_AllocUnitsRare(p, 0); if (!c1) return NULL; } @@ -550,16 +550,16 @@ static CTX_PTR CreateSuccessors(CPpmd7 *p) -#define SwapStates(s) \ +#define SWAP_STATES(s) \ { CPpmd_State tmp = s[0]; s[0] = s[-1]; s[-1] = tmp; } void Ppmd7_UpdateModel(CPpmd7 *p); -MY_NO_INLINE +Z7_NO_INLINE void Ppmd7_UpdateModel(CPpmd7 *p) { CPpmd_Void_Ref maxSuccessor, minSuccessor; - CTX_PTR c, mc; + PPMD7_CTX_PTR c, mc; unsigned s0, ns; @@ -592,7 +592,7 @@ void Ppmd7_UpdateModel(CPpmd7 *p) if (s[0].Freq >= s[-1].Freq) { - SwapStates(s); + SWAP_STATES(s) s--; } } @@ -610,10 +610,10 @@ void Ppmd7_UpdateModel(CPpmd7 *p) { /* MAX ORDER context */ /* (FoundState->Successor) is RAW-Successor. */ - p->MaxContext = p->MinContext = CreateSuccessors(p); + p->MaxContext = p->MinContext = Ppmd7_CreateSuccessors(p); if (!p->MinContext) { - RestartModel(p); + Ppmd7_RestartModel(p); return; } SetSuccessor(p->FoundState, REF(p->MinContext)); @@ -629,7 +629,7 @@ void Ppmd7_UpdateModel(CPpmd7 *p) p->Text = text; if (text >= p->UnitsStart) { - RestartModel(p); + Ppmd7_RestartModel(p); return; } maxSuccessor = REF(text); @@ -645,10 +645,10 @@ void Ppmd7_UpdateModel(CPpmd7 *p) if (minSuccessor <= maxSuccessor) { // minSuccessor is RAW-Successor. So we will create real contexts records: - CTX_PTR cs = CreateSuccessors(p); + PPMD7_CTX_PTR cs = Ppmd7_CreateSuccessors(p); if (!cs) { - RestartModel(p); + Ppmd7_RestartModel(p); return; } minSuccessor = REF(cs); @@ -715,16 +715,16 @@ void Ppmd7_UpdateModel(CPpmd7 *p) unsigned i = U2I(oldNU); if (i != U2I((size_t)oldNU + 1)) { - void *ptr = AllocUnits(p, i + 1); + void *ptr = Ppmd7_AllocUnits(p, i + 1); void *oldPtr; if (!ptr) { - RestartModel(p); + Ppmd7_RestartModel(p); return; } oldPtr = STATS(c); - MyMem12Cpy(ptr, oldPtr, oldNU); - InsertNode(p, oldPtr, i); + MEM_12_CPY(ptr, oldPtr, oldNU) + Ppmd7_InsertNode(p, oldPtr, i); c->Union4.Stats = STATS_REF(ptr); } } @@ -739,10 +739,10 @@ void Ppmd7_UpdateModel(CPpmd7 *p) else { // instead of One-symbol context we create 2-symbol context - CPpmd_State *s = (CPpmd_State*)AllocUnits(p, 0); + CPpmd_State *s = (CPpmd_State*)Ppmd7_AllocUnits(p, 0); if (!s) { - RestartModel(p); + Ppmd7_RestartModel(p); return; } { @@ -795,8 +795,8 @@ void Ppmd7_UpdateModel(CPpmd7 *p) -MY_NO_INLINE -static void Rescale(CPpmd7 *p) +Z7_NO_INLINE +static void Ppmd7_Rescale(CPpmd7 *p) { unsigned i, adder, sumFreq, escFreq; CPpmd_State *stats = STATS(p->MinContext); @@ -885,7 +885,7 @@ static void Rescale(CPpmd7 *p) *s = *stats; s->Freq = (Byte)freq; // (freq <= 260 / 4) p->FoundState = s; - InsertNode(p, stats, U2I(n0)); + Ppmd7_InsertNode(p, stats, U2I(n0)); return; } @@ -899,13 +899,13 @@ static void Rescale(CPpmd7 *p) { if (p->FreeList[i1] != 0) { - void *ptr = RemoveNode(p, i1); + void *ptr = Ppmd7_RemoveNode(p, i1); p->MinContext->Union4.Stats = STATS_REF(ptr); - MyMem12Cpy(ptr, (const void *)stats, n1); - InsertNode(p, stats, i0); + MEM_12_CPY(ptr, (const void *)stats, n1) + Ppmd7_InsertNode(p, stats, i0); } else - SplitBlock(p, stats, i0, i1); + Ppmd7_SplitBlock(p, stats, i0, i1); } } } @@ -948,9 +948,9 @@ CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *escFreq) } -static void NextContext(CPpmd7 *p) +static void Ppmd7_NextContext(CPpmd7 *p) { - CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); + PPMD7_CTX_PTR c = CTX(SUCCESSOR(p->FoundState)); if (p->OrderFall == 0 && (const Byte *)c > p->Text) p->MaxContext = p->MinContext = c; else @@ -967,12 +967,12 @@ void Ppmd7_Update1(CPpmd7 *p) s->Freq = (Byte)freq; if (freq > s[-1].Freq) { - SwapStates(s); + SWAP_STATES(s) p->FoundState = --s; if (freq > MAX_FREQ) - Rescale(p); + Ppmd7_Rescale(p); } - NextContext(p); + Ppmd7_NextContext(p); } @@ -988,8 +988,8 @@ void Ppmd7_Update1_0(CPpmd7 *p) freq += 4; s->Freq = (Byte)freq; if (freq > MAX_FREQ) - Rescale(p); - NextContext(p); + Ppmd7_Rescale(p); + Ppmd7_NextContext(p); } @@ -1000,7 +1000,7 @@ void Ppmd7_UpdateBin(CPpmd7 *p) p->FoundState->Freq = (Byte)(freq + (freq < 128)); p->PrevSuccess = 1; p->RunLength++; - NextContext(p); + Ppmd7_NextContext(p); } */ @@ -1013,7 +1013,7 @@ void Ppmd7_Update2(CPpmd7 *p) p->MinContext->Union2.SummFreq = (UInt16)(p->MinContext->Union2.SummFreq + 4); s->Freq = (Byte)freq; if (freq > MAX_FREQ) - Rescale(p); + Ppmd7_Rescale(p); Ppmd7_UpdateModel(p); } @@ -1042,8 +1042,8 @@ Last UNIT of array at offset (Size - 12) is root order-0 CPpmd7_Context record. The code can free UNITs memory blocks that were allocated to store CPpmd_State vectors. The code doesn't free UNITs allocated for CPpmd7_Context records. -The code calls RestartModel(), when there is no free memory for allocation. -And RestartModel() changes the state to orignal start state, with full free block. +The code calls Ppmd7_RestartModel(), when there is no free memory for allocation. +And Ppmd7_RestartModel() changes the state to orignal start state, with full free block. The code allocates UNITs with the following order: @@ -1051,14 +1051,14 @@ The code allocates UNITs with the following order: Allocation of 1 UNIT for Context record - from free space (HiUnit) down to (LoUnit) - from FreeList[0] - - AllocUnitsRare() + - Ppmd7_AllocUnitsRare() -AllocUnits() for CPpmd_State vectors: +Ppmd7_AllocUnits() for CPpmd_State vectors: - from FreeList[i] - from free space (LoUnit) up to (HiUnit) - - AllocUnitsRare() + - Ppmd7_AllocUnitsRare() -AllocUnitsRare() +Ppmd7_AllocUnitsRare() - if (GlueCount == 0) { Glue lists, GlueCount = 255, allocate from FreeList[i]] } - loop for all higher sized FreeList[...] lists @@ -1093,8 +1093,8 @@ The PPMd code tries to fulfill the condition: We have (Sum(Stats[].Freq) <= 256 * 124), because of (MAX_FREQ = 124) So (4 = 128 - 124) is average reserve for Escape_Freq for each symbol. If (CPpmd_State::Freq) is not aligned for 4, the reserve can be 5, 6 or 7. -SummFreq and Escape_Freq can be changed in Rescale() and *Update*() functions. -Rescale() can remove symbols only from max-order contexts. So Escape_Freq can increase after multiple calls of Rescale() for +SummFreq and Escape_Freq can be changed in Ppmd7_Rescale() and *Update*() functions. +Ppmd7_Rescale() can remove symbols only from max-order contexts. So Escape_Freq can increase after multiple calls of Ppmd7_Rescale() for max-order context. When the PPMd code still break (Total <= RC::Range) condition in range coder, @@ -1102,3 +1102,21 @@ we have two ways to resolve that problem: 1) we can report error, if we want to keep compatibility with original PPMd code that has no fix for such cases. 2) we can reduce (Total) value to (RC::Range) by reducing (Escape_Freq) part of (Total) value. */ + +#undef MAX_FREQ +#undef UNIT_SIZE +#undef U2B +#undef U2I +#undef I2U +#undef I2U_UInt16 +#undef REF +#undef STATS_REF +#undef CTX +#undef STATS +#undef ONE_STATE +#undef SUFFIX +#undef NODE +#undef EMPTY_NODE +#undef MEM_12_CPY +#undef SUCCESSOR +#undef SWAP_STATES diff --git a/libraries/lzma/C/Ppmd7.h b/libraries/lzma/C/Ppmd7.h index d31809aeb..d9eb326d6 100644 --- a/libraries/lzma/C/Ppmd7.h +++ b/libraries/lzma/C/Ppmd7.h @@ -1,11 +1,11 @@ /* Ppmd7.h -- Ppmd7 (PPMdH) compression codec -2021-04-13 : Igor Pavlov : Public domain +2023-04-02 : Igor Pavlov : Public domain This code is based on: PPMd var.H (2001): Dmitry Shkarin : Public domain */ -#ifndef __PPMD7_H -#define __PPMD7_H +#ifndef ZIP7_INC_PPMD7_H +#define ZIP7_INC_PPMD7_H #include "Ppmd.h" @@ -55,7 +55,7 @@ typedef struct UInt32 Range; UInt32 Code; UInt32 Low; - IByteIn *Stream; + IByteInPtr Stream; } CPpmd7_RangeDec; @@ -66,7 +66,7 @@ typedef struct // Byte _dummy_[3]; UInt64 Low; UInt64 CacheSize; - IByteOut *Stream; + IByteOutPtr Stream; } CPpmd7z_RangeEnc; diff --git a/libraries/lzma/C/Ppmd7Dec.c b/libraries/lzma/C/Ppmd7Dec.c index 55d74ff9d..832382828 100644 --- a/libraries/lzma/C/Ppmd7Dec.c +++ b/libraries/lzma/C/Ppmd7Dec.c @@ -1,5 +1,5 @@ /* Ppmd7Dec.c -- Ppmd7z (PPMdH with 7z Range Coder) Decoder -2021-04-13 : Igor Pavlov : Public domain +2023-04-02 : Igor Pavlov : Public domain This code is based on: PPMd var.H (2001): Dmitry Shkarin : Public domain */ @@ -8,7 +8,7 @@ This code is based on: #include "Ppmd7.h" -#define kTopValue (1 << 24) +#define kTopValue ((UInt32)1 << 24) #define READ_BYTE(p) IByteIn_Read((p)->Stream) @@ -37,9 +37,9 @@ BoolInt Ppmd7z_RangeDec_Init(CPpmd7_RangeDec *p) #define R (&p->rc.dec) -MY_FORCE_INLINE -// MY_NO_INLINE -static void RangeDec_Decode(CPpmd7 *p, UInt32 start, UInt32 size) +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd7z_RD_Decode(CPpmd7 *p, UInt32 start, UInt32 size) { @@ -48,18 +48,18 @@ static void RangeDec_Decode(CPpmd7 *p, UInt32 start, UInt32 size) RC_NORM_LOCAL(R) } -#define RC_Decode(start, size) RangeDec_Decode(p, start, size); -#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) -#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) +#define RC_Decode(start, size) Ppmd7z_RD_Decode(p, start, size); +#define RC_DecodeFinal(start, size) RC_Decode(start, size) RC_NORM_REMOTE(R) +#define RC_GetThreshold(total) (R->Code / (R->Range /= (total))) #define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) -typedef CPpmd7_Context * CTX_PTR; +// typedef CPpmd7_Context * CTX_PTR; #define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) void Ppmd7_UpdateModel(CPpmd7 *p); #define MASK(sym) ((unsigned char *)charMask)[sym] -// MY_FORCE_INLINE +// Z7_FORCE_INLINE // static int Ppmd7z_DecodeSymbol(CPpmd7 *p) { @@ -70,7 +70,7 @@ int Ppmd7z_DecodeSymbol(CPpmd7 *p) CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); unsigned i; UInt32 count, hiCnt; - UInt32 summFreq = p->MinContext->Union2.SummFreq; + const UInt32 summFreq = p->MinContext->Union2.SummFreq; @@ -81,7 +81,7 @@ int Ppmd7z_DecodeSymbol(CPpmd7 *p) if ((Int32)(count -= s->Freq) < 0) { Byte sym; - RC_DecodeFinal(0, s->Freq); + RC_DecodeFinal(0, s->Freq) p->FoundState = s; sym = s->Symbol; Ppmd7_Update1_0(p); @@ -96,7 +96,7 @@ int Ppmd7z_DecodeSymbol(CPpmd7 *p) if ((Int32)(count -= (++s)->Freq) < 0) { Byte sym; - RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq); + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) p->FoundState = s; sym = s->Symbol; Ppmd7_Update1(p); @@ -109,10 +109,10 @@ int Ppmd7z_DecodeSymbol(CPpmd7 *p) return PPMD7_SYM_ERROR; hiCnt -= count; - RC_Decode(hiCnt, summFreq - hiCnt); + RC_Decode(hiCnt, summFreq - hiCnt) p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol); - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) // i = p->MinContext->NumStats - 1; // do { MASK((--s)->Symbol) = 0; } while (--i); { @@ -152,7 +152,7 @@ int Ppmd7z_DecodeSymbol(CPpmd7 *p) // Ppmd7_UpdateBin(p); { unsigned freq = s->Freq; - CTX_PTR c = CTX(SUCCESSOR(s)); + CPpmd7_Context *c = CTX(SUCCESSOR(s)); sym = s->Symbol; p->FoundState = s; p->PrevSuccess = 1; @@ -176,7 +176,7 @@ int Ppmd7z_DecodeSymbol(CPpmd7 *p) R->Range -= size0; RC_NORM_LOCAL(R) - PPMD_SetAllBitsIn256Bytes(charMask); + PPMD_SetAllBitsIn256Bytes(charMask) MASK(Ppmd7Context_OneState(p->MinContext)->Symbol) = 0; p->PrevSuccess = 0; } @@ -245,13 +245,13 @@ int Ppmd7z_DecodeSymbol(CPpmd7 *p) { count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; // count -= s->Freq & (unsigned)(MASK((s)->Symbol)); s++; if ((Int32)count < 0) break; - }; + } } s--; - RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq); + RC_DecodeFinal((hiCnt - count) - s->Freq, s->Freq) // new (see->Summ) value can overflow over 16-bits in some rare cases - Ppmd_See_Update(see); + Ppmd_See_UPDATE(see) p->FoundState = s; sym = s->Symbol; Ppmd7_Update2(p); @@ -261,7 +261,7 @@ int Ppmd7z_DecodeSymbol(CPpmd7 *p) if (count >= freqSum) return PPMD7_SYM_ERROR; - RC_Decode(hiCnt, freqSum - hiCnt); + RC_Decode(hiCnt, freqSum - hiCnt) // We increase (see->Summ) for sum of Freqs of all non_Masked symbols. // new (see->Summ) value can overflow over 16-bits in some rare cases @@ -295,3 +295,18 @@ Byte *Ppmd7z_DecodeSymbols(CPpmd7 *p, Byte *buf, const Byte *lim) return buf; } */ + +#undef kTopValue +#undef READ_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Decode +#undef RC_DecodeFinal +#undef RC_GetThreshold +#undef CTX +#undef SUCCESSOR +#undef MASK diff --git a/libraries/lzma/C/Ppmd7Enc.c b/libraries/lzma/C/Ppmd7Enc.c new file mode 100644 index 000000000..41106bab4 --- /dev/null +++ b/libraries/lzma/C/Ppmd7Enc.c @@ -0,0 +1,338 @@ +/* Ppmd7Enc.c -- Ppmd7z (PPMdH with 7z Range Coder) Encoder +2023-04-02 : Igor Pavlov : Public domain +This code is based on: + PPMd var.H (2001): Dmitry Shkarin : Public domain */ + + +#include "Precomp.h" + +#include "Ppmd7.h" + +#define kTopValue ((UInt32)1 << 24) + +#define R (&p->rc.enc) + +void Ppmd7z_Init_RangeEnc(CPpmd7 *p) +{ + R->Low = 0; + R->Range = 0xFFFFFFFF; + R->Cache = 0; + R->CacheSize = 1; +} + +Z7_NO_INLINE +static void Ppmd7z_RangeEnc_ShiftLow(CPpmd7 *p) +{ + if ((UInt32)R->Low < (UInt32)0xFF000000 || (unsigned)(R->Low >> 32) != 0) + { + Byte temp = R->Cache; + do + { + IByteOut_Write(R->Stream, (Byte)(temp + (Byte)(R->Low >> 32))); + temp = 0xFF; + } + while (--R->CacheSize != 0); + R->Cache = (Byte)((UInt32)R->Low >> 24); + } + R->CacheSize++; + R->Low = (UInt32)((UInt32)R->Low << 8); +} + +#define RC_NORM_BASE(p) if (R->Range < kTopValue) { R->Range <<= 8; Ppmd7z_RangeEnc_ShiftLow(p); +#define RC_NORM_1(p) RC_NORM_BASE(p) } +#define RC_NORM(p) RC_NORM_BASE(p) RC_NORM_BASE(p) }} + +// we must use only one type of Normalization from two: LOCAL or REMOTE +#define RC_NORM_LOCAL(p) // RC_NORM(p) +#define RC_NORM_REMOTE(p) RC_NORM(p) + +/* +#define Ppmd7z_RangeEnc_Encode(p, start, _size_) \ + { UInt32 size = _size_; \ + R->Low += start * R->Range; \ + R->Range *= size; \ + RC_NORM_LOCAL(p); } +*/ + +Z7_FORCE_INLINE +// Z7_NO_INLINE +static void Ppmd7z_RangeEnc_Encode(CPpmd7 *p, UInt32 start, UInt32 size) +{ + R->Low += start * R->Range; + R->Range *= size; + RC_NORM_LOCAL(p) +} + +void Ppmd7z_Flush_RangeEnc(CPpmd7 *p) +{ + unsigned i; + for (i = 0; i < 5; i++) + Ppmd7z_RangeEnc_ShiftLow(p); +} + + + +#define RC_Encode(start, size) Ppmd7z_RangeEnc_Encode(p, start, size); +#define RC_EncodeFinal(start, size) RC_Encode(start, size) RC_NORM_REMOTE(p) + +#define CTX(ref) ((CPpmd7_Context *)Ppmd7_GetContext(p, ref)) +#define SUFFIX(ctx) CTX((ctx)->Suffix) +// typedef CPpmd7_Context * CTX_PTR; +#define SUCCESSOR(p) Ppmd_GET_SUCCESSOR(p) + +void Ppmd7_UpdateModel(CPpmd7 *p); + +#define MASK(sym) ((unsigned char *)charMask)[sym] + +Z7_FORCE_INLINE +static +void Ppmd7z_EncodeSymbol(CPpmd7 *p, int symbol) +{ + size_t charMask[256 / sizeof(size_t)]; + + if (p->MinContext->NumStats != 1) + { + CPpmd_State *s = Ppmd7_GetStats(p, p->MinContext); + UInt32 sum; + unsigned i; + + + + + R->Range /= p->MinContext->Union2.SummFreq; + + if (s->Symbol == symbol) + { + // R->Range /= p->MinContext->Union2.SummFreq; + RC_EncodeFinal(0, s->Freq) + p->FoundState = s; + Ppmd7_Update1_0(p); + return; + } + p->PrevSuccess = 0; + sum = s->Freq; + i = (unsigned)p->MinContext->NumStats - 1; + do + { + if ((++s)->Symbol == symbol) + { + // R->Range /= p->MinContext->Union2.SummFreq; + RC_EncodeFinal(sum, s->Freq) + p->FoundState = s; + Ppmd7_Update1(p); + return; + } + sum += s->Freq; + } + while (--i); + + // R->Range /= p->MinContext->Union2.SummFreq; + RC_Encode(sum, p->MinContext->Union2.SummFreq - sum) + + p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol); + PPMD_SetAllBitsIn256Bytes(charMask) + // MASK(s->Symbol) = 0; + // i = p->MinContext->NumStats - 1; + // do { MASK((--s)->Symbol) = 0; } while (--i); + { + CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext); + MASK(s->Symbol) = 0; + do + { + unsigned sym0 = s2[0].Symbol; + unsigned sym1 = s2[1].Symbol; + s2 += 2; + MASK(sym0) = 0; + MASK(sym1) = 0; + } + while (s2 < s); + } + } + else + { + UInt16 *prob = Ppmd7_GetBinSumm(p); + CPpmd_State *s = Ppmd7Context_OneState(p->MinContext); + UInt32 pr = *prob; + const UInt32 bound = (R->Range >> 14) * pr; + pr = PPMD_UPDATE_PROB_1(pr); + if (s->Symbol == symbol) + { + *prob = (UInt16)(pr + (1 << PPMD_INT_BITS)); + // RangeEnc_EncodeBit_0(p, bound); + R->Range = bound; + RC_NORM_1(p) + + // p->FoundState = s; + // Ppmd7_UpdateBin(p); + { + const unsigned freq = s->Freq; + CPpmd7_Context *c = CTX(SUCCESSOR(s)); + p->FoundState = s; + p->PrevSuccess = 1; + p->RunLength++; + s->Freq = (Byte)(freq + (freq < 128)); + // NextContext(p); + if (p->OrderFall == 0 && (const Byte *)c > p->Text) + p->MaxContext = p->MinContext = c; + else + Ppmd7_UpdateModel(p); + } + return; + } + + *prob = (UInt16)pr; + p->InitEsc = p->ExpEscape[pr >> 10]; + // RangeEnc_EncodeBit_1(p, bound); + R->Low += bound; + R->Range -= bound; + RC_NORM_LOCAL(p) + + PPMD_SetAllBitsIn256Bytes(charMask) + MASK(s->Symbol) = 0; + p->PrevSuccess = 0; + } + + for (;;) + { + CPpmd_See *see; + CPpmd_State *s; + UInt32 sum, escFreq; + CPpmd7_Context *mc; + unsigned i, numMasked; + + RC_NORM_REMOTE(p) + + mc = p->MinContext; + numMasked = mc->NumStats; + + do + { + p->OrderFall++; + if (!mc->Suffix) + return; /* EndMarker (symbol = -1) */ + mc = Ppmd7_GetContext(p, mc->Suffix); + i = mc->NumStats; + } + while (i == numMasked); + + p->MinContext = mc; + + // see = Ppmd7_MakeEscFreq(p, numMasked, &escFreq); + { + if (i != 256) + { + unsigned nonMasked = i - numMasked; + see = p->See[(unsigned)p->NS2Indx[(size_t)nonMasked - 1]] + + p->HiBitsFlag + + (nonMasked < (unsigned)SUFFIX(mc)->NumStats - i) + + 2 * (unsigned)(mc->Union2.SummFreq < 11 * i) + + 4 * (unsigned)(numMasked > nonMasked); + { + // if (see->Summ) field is larger than 16-bit, we need only low 16 bits of Summ + unsigned summ = (UInt16)see->Summ; // & 0xFFFF + unsigned r = (summ >> see->Shift); + see->Summ = (UInt16)(summ - r); + escFreq = r + (r == 0); + } + } + else + { + see = &p->DummySee; + escFreq = 1; + } + } + + s = Ppmd7_GetStats(p, mc); + sum = 0; + // i = mc->NumStats; + + do + { + const unsigned cur = s->Symbol; + if ((int)cur == symbol) + { + const UInt32 low = sum; + const UInt32 freq = s->Freq; + unsigned num2; + + Ppmd_See_UPDATE(see) + p->FoundState = s; + sum += escFreq; + + num2 = i / 2; + i &= 1; + sum += freq & (0 - (UInt32)i); + if (num2 != 0) + { + s += i; + for (;;) + { + unsigned sym0 = s[0].Symbol; + unsigned sym1 = s[1].Symbol; + s += 2; + sum += (s[-2].Freq & (unsigned)(MASK(sym0))); + sum += (s[-1].Freq & (unsigned)(MASK(sym1))); + if (--num2 == 0) + break; + } + } + + + R->Range /= sum; + RC_EncodeFinal(low, freq) + Ppmd7_Update2(p); + return; + } + sum += (s->Freq & (unsigned)(MASK(cur))); + s++; + } + while (--i); + + { + const UInt32 total = sum + escFreq; + see->Summ = (UInt16)(see->Summ + total); + + R->Range /= total; + RC_Encode(sum, escFreq) + } + + { + const CPpmd_State *s2 = Ppmd7_GetStats(p, p->MinContext); + s--; + MASK(s->Symbol) = 0; + do + { + const unsigned sym0 = s2[0].Symbol; + const unsigned sym1 = s2[1].Symbol; + s2 += 2; + MASK(sym0) = 0; + MASK(sym1) = 0; + } + while (s2 < s); + } + } +} + + +void Ppmd7z_EncodeSymbols(CPpmd7 *p, const Byte *buf, const Byte *lim) +{ + for (; buf < lim; buf++) + { + Ppmd7z_EncodeSymbol(p, *buf); + } +} + +#undef kTopValue +#undef WRITE_BYTE +#undef RC_NORM_BASE +#undef RC_NORM_1 +#undef RC_NORM +#undef RC_NORM_LOCAL +#undef RC_NORM_REMOTE +#undef R +#undef RC_Encode +#undef RC_EncodeFinal +#undef SUFFIX +#undef CTX +#undef SUCCESSOR +#undef MASK diff --git a/libraries/lzma/C/Precomp.h b/libraries/lzma/C/Precomp.h index e8ff8b40e..69afb2ffd 100644 --- a/libraries/lzma/C/Precomp.h +++ b/libraries/lzma/C/Precomp.h @@ -1,8 +1,8 @@ /* Precomp.h -- StdAfx -2013-11-12 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __7Z_PRECOMP_H -#define __7Z_PRECOMP_H +#ifndef ZIP7_INC_PRECOMP_H +#define ZIP7_INC_PRECOMP_H #include "Compiler.h" /* #include "7zTypes.h" */ diff --git a/libraries/lzma/C/RotateDefs.h b/libraries/lzma/C/RotateDefs.h new file mode 100644 index 000000000..c16b4f8e6 --- /dev/null +++ b/libraries/lzma/C/RotateDefs.h @@ -0,0 +1,50 @@ +/* RotateDefs.h -- Rotate functions +2023-06-18 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_ROTATE_DEFS_H +#define ZIP7_INC_ROTATE_DEFS_H + +#ifdef _MSC_VER + +#include + +/* don't use _rotl with old MINGW. It can insert slow call to function. */ + +/* #if (_MSC_VER >= 1200) */ +#pragma intrinsic(_rotl) +#pragma intrinsic(_rotr) +/* #endif */ + +#define rotlFixed(x, n) _rotl((x), (n)) +#define rotrFixed(x, n) _rotr((x), (n)) + +#if (_MSC_VER >= 1300) +#define Z7_ROTL64(x, n) _rotl64((x), (n)) +#define Z7_ROTR64(x, n) _rotr64((x), (n)) +#else +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) +#endif + +#else + +/* new compilers can translate these macros to fast commands. */ + +#if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(__GNUC__) && (__GNUC__ >= 5) +/* GCC 4.9.0 and clang 3.5 can recognize more correct version: */ +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (-(n) & 31))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (-(n) & 31))) +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (-(n) & 63))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (-(n) & 63))) +#else +/* for old GCC / clang: */ +#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) +#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n)))) +#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) +#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n)))) +#endif + +#endif + +#endif diff --git a/libraries/lzma/C/Sha256.c b/libraries/lzma/C/Sha256.c new file mode 100644 index 000000000..018cf6f4b --- /dev/null +++ b/libraries/lzma/C/Sha256.c @@ -0,0 +1,516 @@ +/* Sha256.c -- SHA-256 Hash +2023-04-02 : Igor Pavlov : Public domain +This code is based on public domain code from Wei Dai's Crypto++ library. */ + +#include "Precomp.h" + +#include + +#include "CpuArch.h" +#include "RotateDefs.h" +#include "Sha256.h" + +#if defined(_MSC_VER) && (_MSC_VER < 1900) +// #define USE_MY_MM +#endif + +#ifdef MY_CPU_X86_OR_AMD64 + #ifdef _MSC_VER + #if _MSC_VER >= 1200 + #define Z7_COMPILER_SHA256_SUPPORTED + #endif + #elif defined(__clang__) + #if (__clang_major__ >= 8) // fix that check + #define Z7_COMPILER_SHA256_SUPPORTED + #endif + #elif defined(__GNUC__) + #if (__GNUC__ >= 8) // fix that check + #define Z7_COMPILER_SHA256_SUPPORTED + #endif + #elif defined(__INTEL_COMPILER) + #if (__INTEL_COMPILER >= 1800) // fix that check + #define Z7_COMPILER_SHA256_SUPPORTED + #endif + #endif +#elif defined(MY_CPU_ARM_OR_ARM64) + #ifdef _MSC_VER + #if _MSC_VER >= 1910 + #define Z7_COMPILER_SHA256_SUPPORTED + #endif + #elif defined(__clang__) + #if (__clang_major__ >= 8) // fix that check + #define Z7_COMPILER_SHA256_SUPPORTED + #endif + #elif defined(__GNUC__) + #if (__GNUC__ >= 6) // fix that check + #define Z7_COMPILER_SHA256_SUPPORTED + #endif + #endif +#endif + +void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks); + +#ifdef Z7_COMPILER_SHA256_SUPPORTED + void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); + + static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS = Sha256_UpdateBlocks; + static SHA256_FUNC_UPDATE_BLOCKS g_SHA256_FUNC_UPDATE_BLOCKS_HW; + + #define SHA256_UPDATE_BLOCKS(p) p->func_UpdateBlocks +#else + #define SHA256_UPDATE_BLOCKS(p) Sha256_UpdateBlocks +#endif + + +BoolInt Sha256_SetFunction(CSha256 *p, unsigned algo) +{ + SHA256_FUNC_UPDATE_BLOCKS func = Sha256_UpdateBlocks; + + #ifdef Z7_COMPILER_SHA256_SUPPORTED + if (algo != SHA256_ALGO_SW) + { + if (algo == SHA256_ALGO_DEFAULT) + func = g_SHA256_FUNC_UPDATE_BLOCKS; + else + { + if (algo != SHA256_ALGO_HW) + return False; + func = g_SHA256_FUNC_UPDATE_BLOCKS_HW; + if (!func) + return False; + } + } + #else + if (algo > 1) + return False; + #endif + + p->func_UpdateBlocks = func; + return True; +} + + +/* define it for speed optimization */ + +#ifdef Z7_SFX + #define STEP_PRE 1 + #define STEP_MAIN 1 +#else + #define STEP_PRE 2 + #define STEP_MAIN 4 + // #define Z7_SHA256_UNROLL +#endif + +#undef Z7_SHA256_BIG_W +#if STEP_MAIN != 16 + #define Z7_SHA256_BIG_W +#endif + + + + +void Sha256_InitState(CSha256 *p) +{ + p->count = 0; + p->state[0] = 0x6a09e667; + p->state[1] = 0xbb67ae85; + p->state[2] = 0x3c6ef372; + p->state[3] = 0xa54ff53a; + p->state[4] = 0x510e527f; + p->state[5] = 0x9b05688c; + p->state[6] = 0x1f83d9ab; + p->state[7] = 0x5be0cd19; +} + +void Sha256_Init(CSha256 *p) +{ + p->func_UpdateBlocks = + #ifdef Z7_COMPILER_SHA256_SUPPORTED + g_SHA256_FUNC_UPDATE_BLOCKS; + #else + NULL; + #endif + Sha256_InitState(p); +} + +#define S0(x) (rotrFixed(x, 2) ^ rotrFixed(x,13) ^ rotrFixed(x, 22)) +#define S1(x) (rotrFixed(x, 6) ^ rotrFixed(x,11) ^ rotrFixed(x, 25)) +#define s0(x) (rotrFixed(x, 7) ^ rotrFixed(x,18) ^ (x >> 3)) +#define s1(x) (rotrFixed(x,17) ^ rotrFixed(x,19) ^ (x >> 10)) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + + +#define W_PRE(i) (W[(i) + (size_t)(j)] = GetBe32(data + ((size_t)(j) + i) * 4)) + +#define blk2_main(j, i) s1(w(j, (i)-2)) + w(j, (i)-7) + s0(w(j, (i)-15)) + +#ifdef Z7_SHA256_BIG_W + // we use +i instead of +(i) to change the order to solve CLANG compiler warning for signed/unsigned. + #define w(j, i) W[(size_t)(j) + i] + #define blk2(j, i) (w(j, i) = w(j, (i)-16) + blk2_main(j, i)) +#else + #if STEP_MAIN == 16 + #define w(j, i) W[(i) & 15] + #else + #define w(j, i) W[((size_t)(j) + (i)) & 15] + #endif + #define blk2(j, i) (w(j, i) += blk2_main(j, i)) +#endif + +#define W_MAIN(i) blk2(j, i) + + +#define T1(wx, i) \ + tmp = h + S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + h = g; \ + g = f; \ + f = e; \ + e = d + tmp; \ + tmp += S0(a) + Maj(a, b, c); \ + d = c; \ + c = b; \ + b = a; \ + a = tmp; \ + +#define R1_PRE(i) T1( W_PRE, i) +#define R1_MAIN(i) T1( W_MAIN, i) + +#if (!defined(Z7_SHA256_UNROLL) || STEP_MAIN < 8) && (STEP_MAIN >= 4) +#define R2_MAIN(i) \ + R1_MAIN(i) \ + R1_MAIN(i + 1) \ + +#endif + + + +#if defined(Z7_SHA256_UNROLL) && STEP_MAIN >= 8 + +#define T4( a,b,c,d,e,f,g,h, wx, i) \ + h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + tmp = h; \ + h += d; \ + d = tmp + S0(a) + Maj(a, b, c); \ + +#define R4( wx, i) \ + T4 ( a,b,c,d,e,f,g,h, wx, (i )); \ + T4 ( d,a,b,c,h,e,f,g, wx, (i+1)); \ + T4 ( c,d,a,b,g,h,e,f, wx, (i+2)); \ + T4 ( b,c,d,a,f,g,h,e, wx, (i+3)); \ + +#define R4_PRE(i) R4( W_PRE, i) +#define R4_MAIN(i) R4( W_MAIN, i) + + +#define T8( a,b,c,d,e,f,g,h, wx, i) \ + h += S1(e) + Ch(e,f,g) + K[(i)+(size_t)(j)] + wx(i); \ + d += h; \ + h += S0(a) + Maj(a, b, c); \ + +#define R8( wx, i) \ + T8 ( a,b,c,d,e,f,g,h, wx, i ); \ + T8 ( h,a,b,c,d,e,f,g, wx, i+1); \ + T8 ( g,h,a,b,c,d,e,f, wx, i+2); \ + T8 ( f,g,h,a,b,c,d,e, wx, i+3); \ + T8 ( e,f,g,h,a,b,c,d, wx, i+4); \ + T8 ( d,e,f,g,h,a,b,c, wx, i+5); \ + T8 ( c,d,e,f,g,h,a,b, wx, i+6); \ + T8 ( b,c,d,e,f,g,h,a, wx, i+7); \ + +#define R8_PRE(i) R8( W_PRE, i) +#define R8_MAIN(i) R8( W_MAIN, i) + +#endif + +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); + +// static +extern MY_ALIGN(64) +const UInt32 SHA256_K_ARRAY[64]; + +MY_ALIGN(64) +const UInt32 SHA256_K_ARRAY[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +#define K SHA256_K_ARRAY + + +Z7_NO_INLINE +void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks) +{ + UInt32 W + #ifdef Z7_SHA256_BIG_W + [64]; + #else + [16]; + #endif + + unsigned j; + + UInt32 a,b,c,d,e,f,g,h; + + #if !defined(Z7_SHA256_UNROLL) || (STEP_MAIN <= 4) || (STEP_PRE <= 4) + UInt32 tmp; + #endif + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + while (numBlocks) + { + + for (j = 0; j < 16; j += STEP_PRE) + { + #if STEP_PRE > 4 + + #if STEP_PRE < 8 + R4_PRE(0); + #else + R8_PRE(0); + #if STEP_PRE == 16 + R8_PRE(8); + #endif + #endif + + #else + + R1_PRE(0) + #if STEP_PRE >= 2 + R1_PRE(1) + #if STEP_PRE >= 4 + R1_PRE(2) + R1_PRE(3) + #endif + #endif + + #endif + } + + for (j = 16; j < 64; j += STEP_MAIN) + { + #if defined(Z7_SHA256_UNROLL) && STEP_MAIN >= 8 + + #if STEP_MAIN < 8 + R4_MAIN(0) + #else + R8_MAIN(0) + #if STEP_MAIN == 16 + R8_MAIN(8) + #endif + #endif + + #else + + R1_MAIN(0) + #if STEP_MAIN >= 2 + R1_MAIN(1) + #if STEP_MAIN >= 4 + R2_MAIN(2) + #if STEP_MAIN >= 8 + R2_MAIN(4) + R2_MAIN(6) + #if STEP_MAIN >= 16 + R2_MAIN(8) + R2_MAIN(10) + R2_MAIN(12) + R2_MAIN(14) + #endif + #endif + #endif + #endif + #endif + } + + a += state[0]; state[0] = a; + b += state[1]; state[1] = b; + c += state[2]; state[2] = c; + d += state[3]; state[3] = d; + e += state[4]; state[4] = e; + f += state[5]; state[5] = f; + g += state[6]; state[6] = g; + h += state[7]; state[7] = h; + + data += 64; + numBlocks--; + } + + /* Wipe variables */ + /* memset(W, 0, sizeof(W)); */ +} + +#undef S0 +#undef S1 +#undef s0 +#undef s1 +#undef K + +#define Sha256_UpdateBlock(p) SHA256_UPDATE_BLOCKS(p)(p->state, p->buffer, 1) + +void Sha256_Update(CSha256 *p, const Byte *data, size_t size) +{ + if (size == 0) + return; + + { + unsigned pos = (unsigned)p->count & 0x3F; + unsigned num; + + p->count += size; + + num = 64 - pos; + if (num > size) + { + memcpy(p->buffer + pos, data, size); + return; + } + + if (pos != 0) + { + size -= num; + memcpy(p->buffer + pos, data, num); + data += num; + Sha256_UpdateBlock(p); + } + } + { + size_t numBlocks = size >> 6; + SHA256_UPDATE_BLOCKS(p)(p->state, data, numBlocks); + size &= 0x3F; + if (size == 0) + return; + data += (numBlocks << 6); + memcpy(p->buffer, data, size); + } +} + + +void Sha256_Final(CSha256 *p, Byte *digest) +{ + unsigned pos = (unsigned)p->count & 0x3F; + unsigned i; + + p->buffer[pos++] = 0x80; + + if (pos > (64 - 8)) + { + while (pos != 64) { p->buffer[pos++] = 0; } + // memset(&p->buf.buffer[pos], 0, 64 - pos); + Sha256_UpdateBlock(p); + pos = 0; + } + + /* + if (pos & 3) + { + p->buffer[pos] = 0; + p->buffer[pos + 1] = 0; + p->buffer[pos + 2] = 0; + pos += 3; + pos &= ~3; + } + { + for (; pos < 64 - 8; pos += 4) + *(UInt32 *)(&p->buffer[pos]) = 0; + } + */ + + memset(&p->buffer[pos], 0, (64 - 8) - pos); + + { + UInt64 numBits = (p->count << 3); + SetBe32(p->buffer + 64 - 8, (UInt32)(numBits >> 32)) + SetBe32(p->buffer + 64 - 4, (UInt32)(numBits)) + } + + Sha256_UpdateBlock(p); + + for (i = 0; i < 8; i += 2) + { + UInt32 v0 = p->state[i]; + UInt32 v1 = p->state[(size_t)i + 1]; + SetBe32(digest , v0) + SetBe32(digest + 4, v1) + digest += 8; + } + + Sha256_InitState(p); +} + + +void Sha256Prepare(void) +{ + #ifdef Z7_COMPILER_SHA256_SUPPORTED + SHA256_FUNC_UPDATE_BLOCKS f, f_hw; + f = Sha256_UpdateBlocks; + f_hw = NULL; + #ifdef MY_CPU_X86_OR_AMD64 + #ifndef USE_MY_MM + if (CPU_IsSupported_SHA() + && CPU_IsSupported_SSSE3() + // && CPU_IsSupported_SSE41() + ) + #endif + #else + if (CPU_IsSupported_SHA2()) + #endif + { + // printf("\n========== HW SHA256 ======== \n"); + f = f_hw = Sha256_UpdateBlocks_HW; + } + g_SHA256_FUNC_UPDATE_BLOCKS = f; + g_SHA256_FUNC_UPDATE_BLOCKS_HW = f_hw; + #endif +} + +#undef S0 +#undef S1 +#undef s0 +#undef s1 +#undef Ch +#undef Maj +#undef W_MAIN +#undef W_PRE +#undef w +#undef blk2_main +#undef blk2 +#undef T1 +#undef T4 +#undef T8 +#undef R1_PRE +#undef R1_MAIN +#undef R2_MAIN +#undef R4 +#undef R4_PRE +#undef R4_MAIN +#undef R8 +#undef R8_PRE +#undef R8_MAIN +#undef STEP_PRE +#undef STEP_MAIN +#undef Z7_SHA256_BIG_W +#undef Z7_SHA256_UNROLL +#undef Z7_COMPILER_SHA256_SUPPORTED diff --git a/libraries/lzma/C/Sha256.h b/libraries/lzma/C/Sha256.h new file mode 100644 index 000000000..9e0422320 --- /dev/null +++ b/libraries/lzma/C/Sha256.h @@ -0,0 +1,76 @@ +/* Sha256.h -- SHA-256 Hash +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_SHA256_H +#define ZIP7_INC_SHA256_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +#define SHA256_NUM_BLOCK_WORDS 16 +#define SHA256_NUM_DIGEST_WORDS 8 + +#define SHA256_BLOCK_SIZE (SHA256_NUM_BLOCK_WORDS * 4) +#define SHA256_DIGEST_SIZE (SHA256_NUM_DIGEST_WORDS * 4) + +typedef void (Z7_FASTCALL *SHA256_FUNC_UPDATE_BLOCKS)(UInt32 state[8], const Byte *data, size_t numBlocks); + +/* + if (the system supports different SHA256 code implementations) + { + (CSha256::func_UpdateBlocks) will be used + (CSha256::func_UpdateBlocks) can be set by + Sha256_Init() - to default (fastest) + Sha256_SetFunction() - to any algo + } + else + { + (CSha256::func_UpdateBlocks) is ignored. + } +*/ + +typedef struct +{ + SHA256_FUNC_UPDATE_BLOCKS func_UpdateBlocks; + UInt64 count; + UInt64 _pad_2[2]; + UInt32 state[SHA256_NUM_DIGEST_WORDS]; + + Byte buffer[SHA256_BLOCK_SIZE]; +} CSha256; + + +#define SHA256_ALGO_DEFAULT 0 +#define SHA256_ALGO_SW 1 +#define SHA256_ALGO_HW 2 + +/* +Sha256_SetFunction() +return: + 0 - (algo) value is not supported, and func_UpdateBlocks was not changed + 1 - func_UpdateBlocks was set according (algo) value. +*/ + +BoolInt Sha256_SetFunction(CSha256 *p, unsigned algo); + +void Sha256_InitState(CSha256 *p); +void Sha256_Init(CSha256 *p); +void Sha256_Update(CSha256 *p, const Byte *data, size_t size); +void Sha256_Final(CSha256 *p, Byte *digest); + + + + +// void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks); + +/* +call Sha256Prepare() once at program start. +It prepares all supported implementations, and detects the fastest implementation. +*/ + +void Sha256Prepare(void); + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/Sha256Opt.c b/libraries/lzma/C/Sha256Opt.c new file mode 100644 index 000000000..e4465e3e7 --- /dev/null +++ b/libraries/lzma/C/Sha256Opt.c @@ -0,0 +1,386 @@ +/* Sha256Opt.c -- SHA-256 optimized code for SHA-256 hardware instructions +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" +#include "Compiler.h" +#include "CpuArch.h" + +#if defined(_MSC_VER) +#if (_MSC_VER < 1900) && (_MSC_VER >= 1200) +// #define USE_MY_MM +#endif +#endif + +#ifdef MY_CPU_X86_OR_AMD64 + #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) // fix that check + #define USE_HW_SHA + #elif defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \ + || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) + #define USE_HW_SHA + #if !defined(_INTEL_COMPILER) + // icc defines __GNUC__, but icc doesn't support __attribute__(__target__) + #if !defined(__SHA__) || !defined(__SSSE3__) + #define ATTRIB_SHA __attribute__((__target__("sha,ssse3"))) + #endif + #endif + #elif defined(_MSC_VER) + #ifdef USE_MY_MM + #define USE_VER_MIN 1300 + #else + #define USE_VER_MIN 1900 + #endif + #if (_MSC_VER >= USE_VER_MIN) + #define USE_HW_SHA + #endif + #endif +// #endif // MY_CPU_X86_OR_AMD64 + +#ifdef USE_HW_SHA + +// #pragma message("Sha256 HW") + +// sse/sse2/ssse3: +#include +// sha*: +#include + +#if defined (__clang__) && defined(_MSC_VER) + // #if !defined(__SSSE3__) + // #endif + #if !defined(__SHA__) + #include + #endif +#else + +#ifdef USE_MY_MM +#include "My_mm.h" +#endif + +#endif + +/* +SHA256 uses: +SSE2: + _mm_loadu_si128 + _mm_storeu_si128 + _mm_set_epi32 + _mm_add_epi32 + _mm_shuffle_epi32 / pshufd + + + +SSSE3: + _mm_shuffle_epi8 / pshufb + _mm_alignr_epi8 +SHA: + _mm_sha256* +*/ + +// K array must be aligned for 16-bytes at least. +// The compiler can look align attribute and selects +// movdqu - for code without align attribute +// movdqa - for code with align attribute +extern +MY_ALIGN(64) +const UInt32 SHA256_K_ARRAY[64]; + +#define K SHA256_K_ARRAY + + +#define ADD_EPI32(dest, src) dest = _mm_add_epi32(dest, src); +#define SHA256_MSG1(dest, src) dest = _mm_sha256msg1_epu32(dest, src); +#define SHA25G_MSG2(dest, src) dest = _mm_sha256msg2_epu32(dest, src); + + +#define LOAD_SHUFFLE(m, k) \ + m = _mm_loadu_si128((const __m128i *)(const void *)(data + (k) * 16)); \ + m = _mm_shuffle_epi8(m, mask); \ + +#define SM1(g0, g1, g2, g3) \ + SHA256_MSG1(g3, g0); \ + +#define SM2(g0, g1, g2, g3) \ + tmp = _mm_alignr_epi8(g1, g0, 4); \ + ADD_EPI32(g2, tmp) \ + SHA25G_MSG2(g2, g1); \ + +// #define LS0(k, g0, g1, g2, g3) LOAD_SHUFFLE(g0, k) +// #define LS1(k, g0, g1, g2, g3) LOAD_SHUFFLE(g1, k+1) + + +#define NNN(g0, g1, g2, g3) + + +#define RND2(t0, t1) \ + t0 = _mm_sha256rnds2_epu32(t0, t1, msg); + +#define RND2_0(m, k) \ + msg = _mm_add_epi32(m, *(const __m128i *) (const void *) &K[(k) * 4]); \ + RND2(state0, state1); \ + msg = _mm_shuffle_epi32(msg, 0x0E); \ + + +#define RND2_1 \ + RND2(state1, state0); \ + + +// We use scheme with 3 rounds ahead for SHA256_MSG1 / 2 rounds ahead for SHA256_MSG2 + +#define R4(k, g0, g1, g2, g3, OP0, OP1) \ + RND2_0(g0, k) \ + OP0(g0, g1, g2, g3) \ + RND2_1 \ + OP1(g0, g1, g2, g3) \ + +#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \ + R4 ( (k)*4+0, m0,m1,m2,m3, OP0, OP1 ) \ + R4 ( (k)*4+1, m1,m2,m3,m0, OP2, OP3 ) \ + R4 ( (k)*4+2, m2,m3,m0,m1, OP4, OP5 ) \ + R4 ( (k)*4+3, m3,m0,m1,m2, OP6, OP7 ) \ + +#define PREPARE_STATE \ + tmp = _mm_shuffle_epi32(state0, 0x1B); /* abcd */ \ + state0 = _mm_shuffle_epi32(state1, 0x1B); /* efgh */ \ + state1 = state0; \ + state0 = _mm_unpacklo_epi64(state0, tmp); /* cdgh */ \ + state1 = _mm_unpackhi_epi64(state1, tmp); /* abef */ \ + + +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +#ifdef ATTRIB_SHA +ATTRIB_SHA +#endif +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +{ + const __m128i mask = _mm_set_epi32(0x0c0d0e0f, 0x08090a0b, 0x04050607, 0x00010203); + __m128i tmp; + __m128i state0, state1; + + if (numBlocks == 0) + return; + + state0 = _mm_loadu_si128((const __m128i *) (const void *) &state[0]); + state1 = _mm_loadu_si128((const __m128i *) (const void *) &state[4]); + + PREPARE_STATE + + do + { + __m128i state0_save, state1_save; + __m128i m0, m1, m2, m3; + __m128i msg; + // #define msg tmp + + state0_save = state0; + state1_save = state1; + + LOAD_SHUFFLE (m0, 0) + LOAD_SHUFFLE (m1, 1) + LOAD_SHUFFLE (m2, 2) + LOAD_SHUFFLE (m3, 3) + + + + R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 ) + R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ) + R16 ( 3, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN ) + + ADD_EPI32(state0, state0_save) + ADD_EPI32(state1, state1_save) + + data += 64; + } + while (--numBlocks); + + PREPARE_STATE + + _mm_storeu_si128((__m128i *) (void *) &state[0], state0); + _mm_storeu_si128((__m128i *) (void *) &state[4], state1); +} + +#endif // USE_HW_SHA + +#elif defined(MY_CPU_ARM_OR_ARM64) + + #if defined(__clang__) + #if (__clang_major__ >= 8) // fix that check + #define USE_HW_SHA + #endif + #elif defined(__GNUC__) + #if (__GNUC__ >= 6) // fix that check + #define USE_HW_SHA + #endif + #elif defined(_MSC_VER) + #if _MSC_VER >= 1910 + #define USE_HW_SHA + #endif + #endif + +#ifdef USE_HW_SHA + +// #pragma message("=== Sha256 HW === ") + +#if defined(__clang__) || defined(__GNUC__) + #ifdef MY_CPU_ARM64 + #define ATTRIB_SHA __attribute__((__target__("+crypto"))) + #else + #define ATTRIB_SHA __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) + #endif +#else + // _MSC_VER + // for arm32 + #define _ARM_USE_NEW_NEON_INTRINSICS +#endif + +#if defined(_MSC_VER) && defined(MY_CPU_ARM64) +#include +#else +#include +#endif + +typedef uint32x4_t v128; +// typedef __n128 v128; // MSVC + +#ifdef MY_CPU_BE + #define MY_rev32_for_LE(x) +#else + #define MY_rev32_for_LE(x) x = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(x))) +#endif + +#define LOAD_128(_p) (*(const v128 *)(const void *)(_p)) +#define STORE_128(_p, _v) *(v128 *)(void *)(_p) = (_v) + +#define LOAD_SHUFFLE(m, k) \ + m = LOAD_128((data + (k) * 16)); \ + MY_rev32_for_LE(m); \ + +// K array must be aligned for 16-bytes at least. +extern +MY_ALIGN(64) +const UInt32 SHA256_K_ARRAY[64]; + +#define K SHA256_K_ARRAY + + +#define SHA256_SU0(dest, src) dest = vsha256su0q_u32(dest, src); +#define SHA25G_SU1(dest, src2, src3) dest = vsha256su1q_u32(dest, src2, src3); + +#define SM1(g0, g1, g2, g3) SHA256_SU0(g3, g0) +#define SM2(g0, g1, g2, g3) SHA25G_SU1(g2, g0, g1) +#define NNN(g0, g1, g2, g3) + + +#define R4(k, g0, g1, g2, g3, OP0, OP1) \ + msg = vaddq_u32(g0, *(const v128 *) (const void *) &K[(k) * 4]); \ + tmp = state0; \ + state0 = vsha256hq_u32( state0, state1, msg ); \ + state1 = vsha256h2q_u32( state1, tmp, msg ); \ + OP0(g0, g1, g2, g3); \ + OP1(g0, g1, g2, g3); \ + + +#define R16(k, OP0, OP1, OP2, OP3, OP4, OP5, OP6, OP7) \ + R4 ( (k)*4+0, m0, m1, m2, m3, OP0, OP1 ) \ + R4 ( (k)*4+1, m1, m2, m3, m0, OP2, OP3 ) \ + R4 ( (k)*4+2, m2, m3, m0, m1, OP4, OP5 ) \ + R4 ( (k)*4+3, m3, m0, m1, m2, OP6, OP7 ) \ + + +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +#ifdef ATTRIB_SHA +ATTRIB_SHA +#endif +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +{ + v128 state0, state1; + + if (numBlocks == 0) + return; + + state0 = LOAD_128(&state[0]); + state1 = LOAD_128(&state[4]); + + do + { + v128 state0_save, state1_save; + v128 m0, m1, m2, m3; + v128 msg, tmp; + + state0_save = state0; + state1_save = state1; + + LOAD_SHUFFLE (m0, 0) + LOAD_SHUFFLE (m1, 1) + LOAD_SHUFFLE (m2, 2) + LOAD_SHUFFLE (m3, 3) + + R16 ( 0, NNN, NNN, SM1, NNN, SM1, SM2, SM1, SM2 ); + R16 ( 1, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ); + R16 ( 2, SM1, SM2, SM1, SM2, SM1, SM2, SM1, SM2 ); + R16 ( 3, SM1, SM2, NNN, SM2, NNN, NNN, NNN, NNN ); + + state0 = vaddq_u32(state0, state0_save); + state1 = vaddq_u32(state1, state1_save); + + data += 64; + } + while (--numBlocks); + + STORE_128(&state[0], state0); + STORE_128(&state[4], state1); +} + +#endif // USE_HW_SHA + +#endif // MY_CPU_ARM_OR_ARM64 + + +#ifndef USE_HW_SHA + +// #error Stop_Compiling_UNSUPPORTED_SHA +// #include + +// #include "Sha256.h" +void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks); + +#pragma message("Sha256 HW-SW stub was used") + +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks); +void Z7_FASTCALL Sha256_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks) +{ + Sha256_UpdateBlocks(state, data, numBlocks); + /* + UNUSED_VAR(state); + UNUSED_VAR(data); + UNUSED_VAR(numBlocks); + exit(1); + return; + */ +} + +#endif + + + +#undef K +#undef RND2 +#undef RND2_0 +#undef RND2_1 + +#undef MY_rev32_for_LE +#undef NNN +#undef LOAD_128 +#undef STORE_128 +#undef LOAD_SHUFFLE +#undef SM1 +#undef SM2 + +#undef NNN +#undef R4 +#undef R16 +#undef PREPARE_STATE +#undef USE_HW_SHA +#undef ATTRIB_SHA +#undef USE_VER_MIN diff --git a/libraries/lzma/C/Sort.c b/libraries/lzma/C/Sort.c new file mode 100644 index 000000000..e1097e380 --- /dev/null +++ b/libraries/lzma/C/Sort.c @@ -0,0 +1,141 @@ +/* Sort.c -- Sort functions +2014-04-05 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Sort.h" + +#define HeapSortDown(p, k, size, temp) \ + { for (;;) { \ + size_t s = (k << 1); \ + if (s > size) break; \ + if (s < size && p[s + 1] > p[s]) s++; \ + if (temp >= p[s]) break; \ + p[k] = p[s]; k = s; \ + } p[k] = temp; } + +void HeapSort(UInt32 *p, size_t size) +{ + if (size <= 1) + return; + p--; + { + size_t i = size / 2; + do + { + UInt32 temp = p[i]; + size_t k = i; + HeapSortDown(p, k, size, temp) + } + while (--i != 0); + } + /* + do + { + size_t k = 1; + UInt32 temp = p[size]; + p[size--] = p[1]; + HeapSortDown(p, k, size, temp) + } + while (size > 1); + */ + while (size > 3) + { + UInt32 temp = p[size]; + size_t k = (p[3] > p[2]) ? 3 : 2; + p[size--] = p[1]; + p[1] = p[k]; + HeapSortDown(p, k, size, temp) + } + { + UInt32 temp = p[size]; + p[size] = p[1]; + if (size > 2 && p[2] < temp) + { + p[1] = p[2]; + p[2] = temp; + } + else + p[1] = temp; + } +} + +void HeapSort64(UInt64 *p, size_t size) +{ + if (size <= 1) + return; + p--; + { + size_t i = size / 2; + do + { + UInt64 temp = p[i]; + size_t k = i; + HeapSortDown(p, k, size, temp) + } + while (--i != 0); + } + /* + do + { + size_t k = 1; + UInt64 temp = p[size]; + p[size--] = p[1]; + HeapSortDown(p, k, size, temp) + } + while (size > 1); + */ + while (size > 3) + { + UInt64 temp = p[size]; + size_t k = (p[3] > p[2]) ? 3 : 2; + p[size--] = p[1]; + p[1] = p[k]; + HeapSortDown(p, k, size, temp) + } + { + UInt64 temp = p[size]; + p[size] = p[1]; + if (size > 2 && p[2] < temp) + { + p[1] = p[2]; + p[2] = temp; + } + else + p[1] = temp; + } +} + +/* +#define HeapSortRefDown(p, vals, n, size, temp) \ + { size_t k = n; UInt32 val = vals[temp]; for (;;) { \ + size_t s = (k << 1); \ + if (s > size) break; \ + if (s < size && vals[p[s + 1]] > vals[p[s]]) s++; \ + if (val >= vals[p[s]]) break; \ + p[k] = p[s]; k = s; \ + } p[k] = temp; } + +void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size) +{ + if (size <= 1) + return; + p--; + { + size_t i = size / 2; + do + { + UInt32 temp = p[i]; + HeapSortRefDown(p, vals, i, size, temp); + } + while (--i != 0); + } + do + { + UInt32 temp = p[size]; + p[size--] = p[1]; + HeapSortRefDown(p, vals, 1, size, temp); + } + while (size > 1); +} +*/ diff --git a/libraries/lzma/C/Sort.h b/libraries/lzma/C/Sort.h new file mode 100644 index 000000000..1817b652f --- /dev/null +++ b/libraries/lzma/C/Sort.h @@ -0,0 +1,18 @@ +/* Sort.h -- Sort functions +2023-03-05 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_SORT_H +#define ZIP7_INC_SORT_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +void HeapSort(UInt32 *p, size_t size); +void HeapSort64(UInt64 *p, size_t size); + +/* void HeapSortRef(UInt32 *p, UInt32 *vals, size_t size); */ + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/SwapBytes.c b/libraries/lzma/C/SwapBytes.c new file mode 100644 index 000000000..7901bbaa8 --- /dev/null +++ b/libraries/lzma/C/SwapBytes.c @@ -0,0 +1,800 @@ +/* SwapBytes.c -- Byte Swap conversion filter +2023-04-07 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "Compiler.h" +#include "CpuArch.h" +#include "RotateDefs.h" +#include "SwapBytes.h" + +typedef UInt16 CSwapUInt16; +typedef UInt32 CSwapUInt32; + +// #define k_SwapBytes_Mode_BASE 0 + +#ifdef MY_CPU_X86_OR_AMD64 + +#define k_SwapBytes_Mode_SSE2 1 +#define k_SwapBytes_Mode_SSSE3 2 +#define k_SwapBytes_Mode_AVX2 3 + + // #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1900) + #if defined(__clang__) && (__clang_major__ >= 4) \ + || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40701) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_AVX2 + #define SWAP_ATTRIB_SSE2 __attribute__((__target__("sse2"))) + #define SWAP_ATTRIB_SSSE3 __attribute__((__target__("ssse3"))) + #define SWAP_ATTRIB_AVX2 __attribute__((__target__("avx2"))) + #elif defined(_MSC_VER) + #if (_MSC_VER == 1900) + #pragma warning(disable : 4752) // found Intel(R) Advanced Vector Extensions; consider using /arch:AVX + #endif + #if (_MSC_VER >= 1900) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_AVX2 + #elif (_MSC_VER >= 1500) // (VS2008) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_SSSE3 + #elif (_MSC_VER >= 1310) // (VS2003) + #define k_SwapBytes_Mode_MAX k_SwapBytes_Mode_SSE2 + #endif + #endif // _MSC_VER + +/* +// for debug +#ifdef k_SwapBytes_Mode_MAX +#undef k_SwapBytes_Mode_MAX +#endif +*/ + +#ifndef k_SwapBytes_Mode_MAX +#define k_SwapBytes_Mode_MAX 0 +#endif + +#if (k_SwapBytes_Mode_MAX != 0) && defined(MY_CPU_AMD64) + #define k_SwapBytes_Mode_MIN k_SwapBytes_Mode_SSE2 +#else + #define k_SwapBytes_Mode_MIN 0 +#endif + +#if (k_SwapBytes_Mode_MAX >= k_SwapBytes_Mode_AVX2) + #define USE_SWAP_AVX2 +#endif +#if (k_SwapBytes_Mode_MAX >= k_SwapBytes_Mode_SSSE3) + #define USE_SWAP_SSSE3 +#endif +#if (k_SwapBytes_Mode_MAX >= k_SwapBytes_Mode_SSE2) + #define USE_SWAP_128 +#endif + +#if k_SwapBytes_Mode_MAX <= k_SwapBytes_Mode_MIN || !defined(USE_SWAP_128) +#define FORCE_SWAP_MODE +#endif + + +#ifdef USE_SWAP_128 +/* + MMX + SSE + SSE2 + SSE3 + SSSE3 + SSE4.1 + SSE4.2 + SSE4A + AES + AVX, AVX2, FMA +*/ + +#include // sse2 +// typedef __m128i v128; + +#define SWAP2_128(i) { \ + const __m128i v = *(const __m128i *)(const void *)(items + (i) * 8); \ + *( __m128i *)( void *)(items + (i) * 8) = \ + _mm_or_si128( \ + _mm_slli_epi16(v, 8), \ + _mm_srli_epi16(v, 8)); } +// _mm_or_si128() has more ports to execute than _mm_add_epi16(). + +static +#ifdef SWAP_ATTRIB_SSE2 +SWAP_ATTRIB_SSE2 +#endif +void +Z7_FASTCALL +SwapBytes2_128(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + } + while (items != lim); +} + +/* +// sse2 +#define SWAP4_128_pack(i) { \ + __m128i v = *(const __m128i *)(const void *)(items + (i) * 4); \ + __m128i v0 = _mm_unpacklo_epi8(v, mask); \ + __m128i v1 = _mm_unpackhi_epi8(v, mask); \ + v0 = _mm_shufflelo_epi16(v0, 0x1b); \ + v1 = _mm_shufflelo_epi16(v1, 0x1b); \ + v0 = _mm_shufflehi_epi16(v0, 0x1b); \ + v1 = _mm_shufflehi_epi16(v1, 0x1b); \ + *(__m128i *)(void *)(items + (i) * 4) = _mm_packus_epi16(v0, v1); } + +static +#ifdef SWAP_ATTRIB_SSE2 +SWAP_ATTRIB_SSE2 +#endif +void +Z7_FASTCALL +SwapBytes4_128_pack(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + const __m128i mask = _mm_setzero_si128(); + // const __m128i mask = _mm_set_epi16(0, 0, 0, 0, 0, 0, 0, 0); + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_128_pack(0); items += 1 * 4; + // SWAP4_128_pack(0); SWAP4_128_pack(1); items += 2 * 4; + } + while (items != lim); +} + +// sse2 +#define SWAP4_128_shift(i) { \ + __m128i v = *(const __m128i *)(const void *)(items + (i) * 4); \ + __m128i v2; \ + v2 = _mm_or_si128( \ + _mm_slli_si128(_mm_and_si128(v, mask), 1), \ + _mm_and_si128(_mm_srli_si128(v, 1), mask)); \ + v = _mm_or_si128( \ + _mm_slli_epi32(v, 24), \ + _mm_srli_epi32(v, 24)); \ + *(__m128i *)(void *)(items + (i) * 4) = _mm_or_si128(v2, v); } + +static +#ifdef SWAP_ATTRIB_SSE2 +SWAP_ATTRIB_SSE2 +#endif +void +Z7_FASTCALL +SwapBytes4_128_shift(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + #define M1 0xff00 + const __m128i mask = _mm_set_epi32(M1, M1, M1, M1); + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + // SWAP4_128_shift(0) SWAP4_128_shift(1) items += 2 * 4; + // SWAP4_128_shift(0) SWAP4_128_shift(1) items += 2 * 4; + SWAP4_128_shift(0); items += 1 * 4; + } + while (items != lim); +} +*/ + + +#if defined(USE_SWAP_SSSE3) || defined(USE_SWAP_AVX2) + +#define SWAP_SHUF_REV_SEQ_2_VALS(v) (v)+1, (v) +#define SWAP_SHUF_REV_SEQ_4_VALS(v) (v)+3, (v)+2, (v)+1, (v) + +#define SWAP2_SHUF_MASK_16_BYTES \ + SWAP_SHUF_REV_SEQ_2_VALS (0 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (1 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (2 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (3 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (4 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (5 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (6 * 2), \ + SWAP_SHUF_REV_SEQ_2_VALS (7 * 2) + +#define SWAP4_SHUF_MASK_16_BYTES \ + SWAP_SHUF_REV_SEQ_4_VALS (0 * 4), \ + SWAP_SHUF_REV_SEQ_4_VALS (1 * 4), \ + SWAP_SHUF_REV_SEQ_4_VALS (2 * 4), \ + SWAP_SHUF_REV_SEQ_4_VALS (3 * 4) + +#if defined(USE_SWAP_AVX2) +/* if we use 256_BIT_INIT_MASK, each static array mask will be larger for 16 bytes */ +// #define SWAP_USE_256_BIT_INIT_MASK +#endif + +#if defined(SWAP_USE_256_BIT_INIT_MASK) && defined(USE_SWAP_AVX2) +#define SWAP_MASK_INIT_SIZE 32 +#else +#define SWAP_MASK_INIT_SIZE 16 +#endif + +MY_ALIGN(SWAP_MASK_INIT_SIZE) +static const Byte k_ShufMask_Swap2[] = +{ + SWAP2_SHUF_MASK_16_BYTES + #if SWAP_MASK_INIT_SIZE > 16 + , SWAP2_SHUF_MASK_16_BYTES + #endif +}; + +MY_ALIGN(SWAP_MASK_INIT_SIZE) +static const Byte k_ShufMask_Swap4[] = +{ + SWAP4_SHUF_MASK_16_BYTES + #if SWAP_MASK_INIT_SIZE > 16 + , SWAP4_SHUF_MASK_16_BYTES + #endif +}; + + +#ifdef USE_SWAP_SSSE3 + +#include // ssse3 + +#define SHUF_128(i) *(items + (i)) = \ + _mm_shuffle_epi8(*(items + (i)), mask); // SSSE3 + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_SSSE3 +SWAP_ATTRIB_SSSE3 +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +ShufBytes_128(void *items8, const void *lim8, const void *mask128_ptr) +{ + __m128i *items = (__m128i *)items8; + const __m128i *lim = (const __m128i *)lim8; + // const __m128i mask = _mm_set_epi8(SHUF_SWAP2_MASK_16_VALS); + // const __m128i mask = _mm_set_epi8(SHUF_SWAP4_MASK_16_VALS); + // const __m128i mask = _mm_load_si128((const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + // const __m128i mask = _mm_load_si128((const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + // const __m128i mask = *(const __m128i *)(const void *)&(k_ShufMask_Swap4[0]); + const __m128i mask = *(const __m128i *)mask128_ptr; + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SHUF_128(0) SHUF_128(1) items += 2; + SHUF_128(0) SHUF_128(1) items += 2; + } + while (items != lim); +} + +#endif // USE_SWAP_SSSE3 + + + +#ifdef USE_SWAP_AVX2 + +#include // avx, avx2 +#if defined(__clang__) +#include +#include +#endif + +#define SHUF_256(i) *(items + (i)) = \ + _mm256_shuffle_epi8(*(items + (i)), mask); // AVX2 + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_AVX2 +SWAP_ATTRIB_AVX2 +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +ShufBytes_256(void *items8, const void *lim8, const void *mask128_ptr) +{ + __m256i *items = (__m256i *)items8; + const __m256i *lim = (const __m256i *)lim8; + /* + UNUSED_VAR(mask128_ptr) + __m256i mask = + for Swap4: _mm256_setr_epi8(SWAP4_SHUF_MASK_16_BYTES, SWAP4_SHUF_MASK_16_BYTES); + for Swap2: _mm256_setr_epi8(SWAP2_SHUF_MASK_16_BYTES, SWAP2_SHUF_MASK_16_BYTES); + */ + const __m256i mask = + #if SWAP_MASK_INIT_SIZE > 16 + *(const __m256i *)(const void *)mask128_ptr; + #else + /* msvc: broadcastsi128() version reserves the stack for no reason + msvc 19.29-: _mm256_insertf128_si256() / _mm256_set_m128i)) versions use non-avx movdqu xmm0,XMMWORD PTR [r8] + msvc 19.30+ (VS2022): replaces _mm256_set_m128i(m,m) to vbroadcastf128(m) as we want + */ + // _mm256_broadcastsi128_si256(*mask128_ptr); + /* + #define MY_mm256_set_m128i(hi, lo) _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 1) + MY_mm256_set_m128i + */ + _mm256_set_m128i( + *(const __m128i *)mask128_ptr, + *(const __m128i *)mask128_ptr); + #endif + + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SHUF_256(0) SHUF_256(1) items += 2; + SHUF_256(0) SHUF_256(1) items += 2; + } + while (items != lim); +} + +#endif // USE_SWAP_AVX2 +#endif // USE_SWAP_SSSE3 || USE_SWAP_AVX2 +#endif // USE_SWAP_128 + + + +// compile message "NEON intrinsics not available with the soft-float ABI" +#elif defined(MY_CPU_ARM_OR_ARM64) || \ + (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) +// #elif defined(MY_CPU_ARM64) + + #if defined(__clang__) && (__clang_major__ >= 8) \ + || defined(__GNUC__) && (__GNUC__ >= 8) + #if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) \ + || defined(MY_CPU_ARM64) + #define USE_SWAP_128 + #endif + #ifdef MY_CPU_ARM64 + // #define SWAP_ATTRIB_NEON __attribute__((__target__(""))) + #else + // #define SWAP_ATTRIB_NEON __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) + #endif + #elif defined(_MSC_VER) + #if (_MSC_VER >= 1910) + #define USE_SWAP_128 + #endif + #endif + + #if defined(_MSC_VER) && defined(MY_CPU_ARM64) + #include + #else + #include + #endif + +#ifndef USE_SWAP_128 + #define FORCE_SWAP_MODE +#else + +#ifdef MY_CPU_ARM64 + // for debug : comment it + #define FORCE_SWAP_MODE +#else + #define k_SwapBytes_Mode_NEON 1 +#endif +// typedef uint8x16_t v128; +#define SWAP2_128(i) *(uint8x16_t *) (void *)(items + (i) * 8) = \ + vrev16q_u8(*(const uint8x16_t *)(const void *)(items + (i) * 8)); +#define SWAP4_128(i) *(uint8x16_t *) (void *)(items + (i) * 4) = \ + vrev32q_u8(*(const uint8x16_t *)(const void *)(items + (i) * 4)); + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_NEON +SWAP_ATTRIB_NEON +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +SwapBytes2_128(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + SWAP2_128(0) SWAP2_128(1) items += 2 * 8; + } + while (items != lim); +} + +// Z7_NO_INLINE +static +#ifdef SWAP_ATTRIB_NEON +SWAP_ATTRIB_NEON +#endif +Z7_ATTRIB_NO_VECTORIZE +void +Z7_FASTCALL +SwapBytes4_128(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_128(0) SWAP4_128(1) items += 2 * 4; + SWAP4_128(0) SWAP4_128(1) items += 2 * 4; + } + while (items != lim); +} + +#endif // USE_SWAP_128 + +#else // MY_CPU_ARM_OR_ARM64 +#define FORCE_SWAP_MODE +#endif // MY_CPU_ARM_OR_ARM64 + + + + + + +#if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_X86) + /* _byteswap_ushort() in MSVC x86 32-bit works via slow { mov dh, al; mov dl, ah } + So we use own versions of byteswap function */ + #if (_MSC_VER < 1400 ) // old MSVC-X86 without _rotr16() support + #define SWAP2_16(i) { UInt32 v = items[i]; v += (v << 16); v >>= 8; items[i] = (CSwapUInt16)v; } + #else // is new MSVC-X86 with fast _rotr16() + #include + #define SWAP2_16(i) { items[i] = _rotr16(items[i], 8); } + #endif +#else // is not MSVC-X86 + #define SWAP2_16(i) { CSwapUInt16 v = items[i]; items[i] = Z7_BSWAP16(v); } +#endif // MSVC-X86 + +#if defined(Z7_CPU_FAST_BSWAP_SUPPORTED) + #define SWAP4_32(i) { CSwapUInt32 v = items[i]; items[i] = Z7_BSWAP32(v); } +#else + #define SWAP4_32(i) \ + { UInt32 v = items[i]; \ + v = ((v & 0xff00ff) << 8) + ((v >> 8) & 0xff00ff); \ + v = rotlFixed(v, 16); \ + items[i] = v; } +#endif + + + + +#if defined(FORCE_SWAP_MODE) && defined(USE_SWAP_128) + #define DEFAULT_Swap2 SwapBytes2_128 + #if !defined(MY_CPU_X86_OR_AMD64) + #define DEFAULT_Swap4 SwapBytes4_128 + #endif +#endif + +#if !defined(DEFAULT_Swap2) || !defined(DEFAULT_Swap4) + +#define SWAP_BASE_FUNCS_PREFIXES \ +Z7_FORCE_INLINE \ +static \ +Z7_ATTRIB_NO_VECTOR \ +void Z7_FASTCALL + + +#ifdef MY_CPU_64BIT + +#if defined(MY_CPU_ARM64) \ + && defined(__ARM_ARCH) && (__ARM_ARCH >= 8) \ + && ( (defined(__GNUC__) && (__GNUC__ >= 4)) \ + || (defined(__clang__) && (__clang_major__ >= 4))) + + #define SWAP2_64_VAR(v) asm ("rev16 %x0,%x0" : "+r" (v)); + #define SWAP4_64_VAR(v) asm ("rev32 %x0,%x0" : "+r" (v)); + +#else // is not ARM64-GNU + +#if !defined(MY_CPU_X86_OR_AMD64) || (k_SwapBytes_Mode_MIN == 0) || !defined(USE_SWAP_128) + #define SWAP2_64_VAR(v) \ + v = ( 0x00ff00ff00ff00ff & (v >> 8)) \ + + ((0x00ff00ff00ff00ff & v) << 8); + /* plus gives faster code in MSVC */ +#endif + +#ifdef Z7_CPU_FAST_BSWAP_SUPPORTED + #define SWAP4_64_VAR(v) \ + v = Z7_BSWAP64(v); \ + v = Z7_ROTL64(v, 32); +#else + #define SWAP4_64_VAR(v) \ + v = ( 0x000000ff000000ff & (v >> 24)) \ + + ((0x000000ff000000ff & v) << 24 ) \ + + ( 0x0000ff000000ff00 & (v >> 8)) \ + + ((0x0000ff000000ff00 & v) << 8 ) \ + ; +#endif + +#endif // ARM64-GNU + + +#ifdef SWAP2_64_VAR + +#define SWAP2_64(i) { \ + UInt64 v = *(const UInt64 *)(const void *)(items + (i) * 4); \ + SWAP2_64_VAR(v) \ + *(UInt64 *)(void *)(items + (i) * 4) = v; } + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes2_64(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_64(0) SWAP2_64(1) items += 2 * 4; + SWAP2_64(0) SWAP2_64(1) items += 2 * 4; + } + while (items != lim); +} + + #define DEFAULT_Swap2 SwapBytes2_64 + #if !defined(FORCE_SWAP_MODE) + #define SWAP2_DEFAULT_MODE 0 + #endif +#else // !defined(SWAP2_64_VAR) + #define DEFAULT_Swap2 SwapBytes2_128 + #if !defined(FORCE_SWAP_MODE) + #define SWAP2_DEFAULT_MODE 1 + #endif +#endif // SWAP2_64_VAR + + +#define SWAP4_64(i) { \ + UInt64 v = *(const UInt64 *)(const void *)(items + (i) * 2); \ + SWAP4_64_VAR(v) \ + *(UInt64 *)(void *)(items + (i) * 2) = v; } + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes4_64(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_64(0) SWAP4_64(1) items += 2 * 2; + SWAP4_64(0) SWAP4_64(1) items += 2 * 2; + } + while (items != lim); +} + +#define DEFAULT_Swap4 SwapBytes4_64 + +#else // is not 64BIT + + +#if defined(MY_CPU_ARM_OR_ARM64) \ + && defined(__ARM_ARCH) && (__ARM_ARCH >= 6) \ + && ( (defined(__GNUC__) && (__GNUC__ >= 4)) \ + || (defined(__clang__) && (__clang_major__ >= 4))) + +#ifdef MY_CPU_64BIT + #define SWAP2_32_VAR(v) asm ("rev16 %w0,%w0" : "+r" (v)); +#else + #define SWAP2_32_VAR(v) asm ("rev16 %0,%0" : "+r" (v)); // for clang/gcc + // asm ("rev16 %r0,%r0" : "+r" (a)); // for gcc +#endif + +#elif defined(_MSC_VER) && (_MSC_VER < 1300) && defined(MY_CPU_X86) \ + || !defined(Z7_CPU_FAST_BSWAP_SUPPORTED) \ + || !defined(Z7_CPU_FAST_ROTATE_SUPPORTED) + // old msvc doesn't support _byteswap_ulong() + #define SWAP2_32_VAR(v) \ + v = ((v & 0xff00ff) << 8) + ((v >> 8) & 0xff00ff); + +#else // is not ARM and is not old-MSVC-X86 and fast BSWAP/ROTATE are supported + #define SWAP2_32_VAR(v) \ + v = Z7_BSWAP32(v); \ + v = rotlFixed(v, 16); + +#endif // GNU-ARM* + +#define SWAP2_32(i) { \ + UInt32 v = *(const UInt32 *)(const void *)(items + (i) * 2); \ + SWAP2_32_VAR(v); \ + *(UInt32 *)(void *)(items + (i) * 2) = v; } + + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes2_32(CSwapUInt16 *items, const CSwapUInt16 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP2_32(0) SWAP2_32(1) items += 2 * 2; + SWAP2_32(0) SWAP2_32(1) items += 2 * 2; + } + while (items != lim); +} + + +SWAP_BASE_FUNCS_PREFIXES +SwapBytes4_32(CSwapUInt32 *items, const CSwapUInt32 *lim) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + do + { + SWAP4_32(0) SWAP4_32(1) items += 2; + SWAP4_32(0) SWAP4_32(1) items += 2; + } + while (items != lim); +} + +#define DEFAULT_Swap2 SwapBytes2_32 +#define DEFAULT_Swap4 SwapBytes4_32 +#if !defined(FORCE_SWAP_MODE) + #define SWAP2_DEFAULT_MODE 0 +#endif + +#endif // MY_CPU_64BIT +#endif // if !defined(DEFAULT_Swap2) || !defined(DEFAULT_Swap4) + + + +#if !defined(FORCE_SWAP_MODE) +static unsigned g_SwapBytes_Mode; +#endif + +/* size of largest unrolled loop iteration: 128 bytes = 4 * 32 bytes (AVX). */ +#define SWAP_ITERATION_BLOCK_SIZE_MAX (1 << 7) + +// 32 bytes for (AVX) or 2 * 16-bytes for NEON. +#define SWAP_VECTOR_ALIGN_SIZE (1 << 5) + +Z7_NO_INLINE +void z7_SwapBytes2(CSwapUInt16 *items, size_t numItems) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (SWAP_VECTOR_ALIGN_SIZE - 1)) != 0; numItems--) + { + SWAP2_16(0) + items++; + } + { + const size_t k_Align_Mask = SWAP_ITERATION_BLOCK_SIZE_MAX / sizeof(CSwapUInt16) - 1; + size_t numItems2 = numItems; + CSwapUInt16 *lim; + numItems &= k_Align_Mask; + numItems2 &= ~(size_t)k_Align_Mask; + lim = items + numItems2; + if (numItems2 != 0) + { + #if !defined(FORCE_SWAP_MODE) + #ifdef MY_CPU_X86_OR_AMD64 + #ifdef USE_SWAP_AVX2 + if (g_SwapBytes_Mode > k_SwapBytes_Mode_SSSE3) + ShufBytes_256((__m256i *)(void *)items, + (const __m256i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap2[0])); + else + #endif + #ifdef USE_SWAP_SSSE3 + if (g_SwapBytes_Mode >= k_SwapBytes_Mode_SSSE3) + ShufBytes_128((__m128i *)(void *)items, + (const __m128i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap2[0])); + else + #endif + #endif // MY_CPU_X86_OR_AMD64 + #if SWAP2_DEFAULT_MODE == 0 + if (g_SwapBytes_Mode != 0) + SwapBytes2_128(items, lim); + else + #endif + #endif // FORCE_SWAP_MODE + DEFAULT_Swap2(items, lim); + } + items = lim; + } + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0; numItems--) + { + SWAP2_16(0) + items++; + } +} + + +Z7_NO_INLINE +void z7_SwapBytes4(CSwapUInt32 *items, size_t numItems) +{ + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0 && ((unsigned)(ptrdiff_t)items & (SWAP_VECTOR_ALIGN_SIZE - 1)) != 0; numItems--) + { + SWAP4_32(0) + items++; + } + { + const size_t k_Align_Mask = SWAP_ITERATION_BLOCK_SIZE_MAX / sizeof(CSwapUInt32) - 1; + size_t numItems2 = numItems; + CSwapUInt32 *lim; + numItems &= k_Align_Mask; + numItems2 &= ~(size_t)k_Align_Mask; + lim = items + numItems2; + if (numItems2 != 0) + { + #if !defined(FORCE_SWAP_MODE) + #ifdef MY_CPU_X86_OR_AMD64 + #ifdef USE_SWAP_AVX2 + if (g_SwapBytes_Mode > k_SwapBytes_Mode_SSSE3) + ShufBytes_256((__m256i *)(void *)items, + (const __m256i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + else + #endif + #ifdef USE_SWAP_SSSE3 + if (g_SwapBytes_Mode >= k_SwapBytes_Mode_SSSE3) + ShufBytes_128((__m128i *)(void *)items, + (const __m128i *)(const void *)lim, + (const __m128i *)(const void *)&(k_ShufMask_Swap4[0])); + else + #endif + #else // MY_CPU_X86_OR_AMD64 + + if (g_SwapBytes_Mode != 0) + SwapBytes4_128(items, lim); + else + #endif // MY_CPU_X86_OR_AMD64 + #endif // FORCE_SWAP_MODE + DEFAULT_Swap4(items, lim); + } + items = lim; + } + Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE + for (; numItems != 0; numItems--) + { + SWAP4_32(0) + items++; + } +} + + +// #define SHOW_HW_STATUS + +#ifdef SHOW_HW_STATUS +#include +#define PRF(x) x +#else +#define PRF(x) +#endif + +void z7_SwapBytesPrepare(void) +{ +#ifndef FORCE_SWAP_MODE + unsigned mode = 0; // k_SwapBytes_Mode_BASE; + +#ifdef MY_CPU_ARM_OR_ARM64 + { + if (CPU_IsSupported_NEON()) + { + // #pragma message ("=== SwapBytes NEON") + PRF(printf("\n=== SwapBytes NEON\n");) + mode = k_SwapBytes_Mode_NEON; + } + } +#else // MY_CPU_ARM_OR_ARM64 + { + #ifdef USE_SWAP_AVX2 + if (CPU_IsSupported_AVX2()) + { + // #pragma message ("=== SwapBytes AVX2") + PRF(printf("\n=== SwapBytes AVX2\n");) + mode = k_SwapBytes_Mode_AVX2; + } + else + #endif + #ifdef USE_SWAP_SSSE3 + if (CPU_IsSupported_SSSE3()) + { + // #pragma message ("=== SwapBytes SSSE3") + PRF(printf("\n=== SwapBytes SSSE3\n");) + mode = k_SwapBytes_Mode_SSSE3; + } + else + #endif + #if !defined(MY_CPU_AMD64) + if (CPU_IsSupported_SSE2()) + #endif + { + // #pragma message ("=== SwapBytes SSE2") + PRF(printf("\n=== SwapBytes SSE2\n");) + mode = k_SwapBytes_Mode_SSE2; + } + } +#endif // MY_CPU_ARM_OR_ARM64 + g_SwapBytes_Mode = mode; + // g_SwapBytes_Mode = 0; // for debug +#endif // FORCE_SWAP_MODE + PRF(printf("\n=== SwapBytesPrepare\n");) +} + +#undef PRF diff --git a/libraries/lzma/C/SwapBytes.h b/libraries/lzma/C/SwapBytes.h new file mode 100644 index 000000000..d44246738 --- /dev/null +++ b/libraries/lzma/C/SwapBytes.h @@ -0,0 +1,17 @@ +/* SwapBytes.h -- Byte Swap conversion filter +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_SWAP_BYTES_H +#define ZIP7_INC_SWAP_BYTES_H + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +void z7_SwapBytes2(UInt16 *data, size_t numItems); +void z7_SwapBytes4(UInt32 *data, size_t numItems); +void z7_SwapBytesPrepare(void); + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/Threads.c b/libraries/lzma/C/Threads.c index 58eb90ffa..cf52bd303 100644 --- a/libraries/lzma/C/Threads.c +++ b/libraries/lzma/C/Threads.c @@ -1,5 +1,5 @@ /* Threads.c -- multithreading library -2021-12-21 : Igor Pavlov : Public domain */ +2023-03-04 : Igor Pavlov : Public domain */ #include "Precomp.h" @@ -11,9 +11,9 @@ #include "Threads.h" -static WRes GetError() +static WRes GetError(void) { - DWORD res = GetLastError(); + const DWORD res = GetLastError(); return res ? (WRes)res : 1; } @@ -173,6 +173,9 @@ WRes CriticalSection_Init(CCriticalSection *p) Windows XP, 2003 : can raise a STATUS_NO_MEMORY exception Windows Vista+ : no exceptions */ #ifdef _MSC_VER + #ifdef __clang__ + #pragma GCC diagnostic ignored "-Wlanguage-extension-token" + #endif __try #endif { @@ -193,18 +196,26 @@ WRes CriticalSection_Init(CCriticalSection *p) // ---------- POSIX ---------- #ifndef __APPLE__ -#ifndef _7ZIP_AFFINITY_DISABLE +#ifndef Z7_AFFINITY_DISABLE // _GNU_SOURCE can be required for pthread_setaffinity_np() / CPU_ZERO / CPU_SET +// clang < 3.6 : unknown warning group '-Wreserved-id-macro' +// clang 3.6 - 12.01 : gives warning "macro name is a reserved identifier" +// clang >= 13 : do not give warning +#if !defined(_GNU_SOURCE) + #if defined(__clang__) && (__clang_major__ >= 4) && (__clang_major__ <= 12) + #pragma GCC diagnostic ignored "-Wreserved-id-macro" + #endif #define _GNU_SOURCE -#endif -#endif +#endif // !defined(_GNU_SOURCE) +#endif // Z7_AFFINITY_DISABLE +#endif // __APPLE__ #include "Threads.h" #include #include #include -#ifdef _7ZIP_AFFINITY_SUPPORTED +#ifdef Z7_AFFINITY_SUPPORTED // #include #endif @@ -212,15 +223,12 @@ WRes CriticalSection_Init(CCriticalSection *p) // #include // #define PRF(p) p #define PRF(p) - -#define Print(s) PRF(printf("\n%s\n", s)) - -// #include +#define Print(s) PRF(printf("\n%s\n", s);) WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, const CCpuSet *cpuSet) { // new thread in Posix probably inherits affinity from parrent thread - Print("Thread_Create_With_CpuSet"); + Print("Thread_Create_With_CpuSet") pthread_attr_t attr; int ret; @@ -228,7 +236,7 @@ WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, p->_created = 0; - RINOK(pthread_attr_init(&attr)); + RINOK(pthread_attr_init(&attr)) ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); @@ -236,7 +244,7 @@ WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, { if (cpuSet) { - #ifdef _7ZIP_AFFINITY_SUPPORTED + #ifdef Z7_AFFINITY_SUPPORTED /* printf("\n affinity :"); @@ -292,7 +300,7 @@ WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param) WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity) { - Print("Thread_Create_WithAffinity"); + Print("Thread_Create_WithAffinity") CCpuSet cs; unsigned i; CpuSet_Zero(&cs); @@ -312,7 +320,7 @@ WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param WRes Thread_Close(CThread *p) { - // Print("Thread_Close"); + // Print("Thread_Close") int ret; if (!p->_created) return 0; @@ -326,7 +334,7 @@ WRes Thread_Close(CThread *p) WRes Thread_Wait_Close(CThread *p) { - // Print("Thread_Wait_Close"); + // Print("Thread_Wait_Close") void *thread_return; int ret; if (!p->_created) @@ -343,8 +351,8 @@ WRes Thread_Wait_Close(CThread *p) static WRes Event_Create(CEvent *p, int manualReset, int signaled) { - RINOK(pthread_mutex_init(&p->_mutex, NULL)); - RINOK(pthread_cond_init(&p->_cond, NULL)); + RINOK(pthread_mutex_init(&p->_mutex, NULL)) + RINOK(pthread_cond_init(&p->_cond, NULL)) p->_manual_reset = manualReset; p->_state = (signaled ? True : False); p->_created = 1; @@ -363,7 +371,7 @@ WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) WRes Event_Set(CEvent *p) { - RINOK(pthread_mutex_lock(&p->_mutex)); + RINOK(pthread_mutex_lock(&p->_mutex)) p->_state = True; int res1 = pthread_cond_broadcast(&p->_cond); int res2 = pthread_mutex_unlock(&p->_mutex); @@ -372,14 +380,14 @@ WRes Event_Set(CEvent *p) WRes Event_Reset(CEvent *p) { - RINOK(pthread_mutex_lock(&p->_mutex)); + RINOK(pthread_mutex_lock(&p->_mutex)) p->_state = False; return pthread_mutex_unlock(&p->_mutex); } WRes Event_Wait(CEvent *p) { - RINOK(pthread_mutex_lock(&p->_mutex)); + RINOK(pthread_mutex_lock(&p->_mutex)) while (p->_state == False) { // ETIMEDOUT @@ -411,8 +419,8 @@ WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount) { if (initCount > maxCount || maxCount < 1) return EINVAL; - RINOK(pthread_mutex_init(&p->_mutex, NULL)); - RINOK(pthread_cond_init(&p->_cond, NULL)); + RINOK(pthread_mutex_init(&p->_mutex, NULL)) + RINOK(pthread_cond_init(&p->_cond, NULL)) p->_count = initCount; p->_maxCount = maxCount; p->_created = 1; @@ -448,7 +456,7 @@ WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) if (releaseCount < 1) return EINVAL; - RINOK(pthread_mutex_lock(&p->_mutex)); + RINOK(pthread_mutex_lock(&p->_mutex)) newCount = p->_count + releaseCount; if (newCount > p->_maxCount) @@ -458,13 +466,13 @@ WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount) p->_count = newCount; ret = pthread_cond_broadcast(&p->_cond); } - RINOK(pthread_mutex_unlock(&p->_mutex)); + RINOK(pthread_mutex_unlock(&p->_mutex)) return ret; } WRes Semaphore_Wait(CSemaphore *p) { - RINOK(pthread_mutex_lock(&p->_mutex)); + RINOK(pthread_mutex_lock(&p->_mutex)) while (p->_count < 1) { pthread_cond_wait(&p->_cond, &p->_mutex); @@ -489,7 +497,7 @@ WRes Semaphore_Close(CSemaphore *p) WRes CriticalSection_Init(CCriticalSection *p) { - // Print("CriticalSection_Init"); + // Print("CriticalSection_Init") if (!p) return EINTR; return pthread_mutex_init(&p->_mutex, NULL); @@ -497,7 +505,7 @@ WRes CriticalSection_Init(CCriticalSection *p) void CriticalSection_Enter(CCriticalSection *p) { - // Print("CriticalSection_Enter"); + // Print("CriticalSection_Enter") if (p) { // int ret = @@ -507,7 +515,7 @@ void CriticalSection_Enter(CCriticalSection *p) void CriticalSection_Leave(CCriticalSection *p) { - // Print("CriticalSection_Leave"); + // Print("CriticalSection_Leave") if (p) { // int ret = @@ -517,7 +525,7 @@ void CriticalSection_Leave(CCriticalSection *p) void CriticalSection_Delete(CCriticalSection *p) { - // Print("CriticalSection_Delete"); + // Print("CriticalSection_Delete") if (p) { // int ret = @@ -527,14 +535,28 @@ void CriticalSection_Delete(CCriticalSection *p) LONG InterlockedIncrement(LONG volatile *addend) { - // Print("InterlockedIncrement"); + // Print("InterlockedIncrement") #ifdef USE_HACK_UNSAFE_ATOMIC LONG val = *addend + 1; *addend = val; return val; #else + + #if defined(__clang__) && (__clang_major__ >= 8) + #pragma GCC diagnostic ignored "-Watomic-implicit-seq-cst" + #endif return __sync_add_and_fetch(addend, 1); #endif } #endif // _WIN32 + +WRes AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent *p) +{ + if (Event_IsCreated(p)) + return Event_Reset(p); + return AutoResetEvent_CreateNotSignaled(p); +} + +#undef PRF +#undef Print diff --git a/libraries/lzma/C/Threads.h b/libraries/lzma/C/Threads.h index 89ecb92be..4028464a3 100644 --- a/libraries/lzma/C/Threads.h +++ b/libraries/lzma/C/Threads.h @@ -1,18 +1,19 @@ /* Threads.h -- multithreading library -2021-12-21 : Igor Pavlov : Public domain */ +2023-04-02 : Igor Pavlov : Public domain */ -#ifndef __7Z_THREADS_H -#define __7Z_THREADS_H +#ifndef ZIP7_INC_THREADS_H +#define ZIP7_INC_THREADS_H #ifdef _WIN32 -#include +#include "7zWindows.h" + #else #if defined(__linux__) #if !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__) -#ifndef _7ZIP_AFFINITY_DISABLE -#define _7ZIP_AFFINITY_SUPPORTED -// #pragma message(" ==== _7ZIP_AFFINITY_SUPPORTED") +#ifndef Z7_AFFINITY_DISABLE +#define Z7_AFFINITY_SUPPORTED +// #pragma message(" ==== Z7_AFFINITY_SUPPORTED") // #define _GNU_SOURCE #endif #endif @@ -33,7 +34,7 @@ WRes Handle_WaitObject(HANDLE h); typedef HANDLE CThread; -#define Thread_Construct(p) { *(p) = NULL; } +#define Thread_CONSTRUCT(p) { *(p) = NULL; } #define Thread_WasCreated(p) (*(p) != NULL) #define Thread_Close(p) HandlePtr_Close(p) // #define Thread_Wait(p) Handle_WaitObject(*(p)) @@ -52,42 +53,46 @@ typedef #endif THREAD_FUNC_RET_TYPE; +#define THREAD_FUNC_RET_ZERO 0 + typedef DWORD_PTR CAffinityMask; typedef DWORD_PTR CCpuSet; -#define CpuSet_Zero(p) { *(p) = 0; } -#define CpuSet_Set(p, cpu) { *(p) |= ((DWORD_PTR)1 << (cpu)); } +#define CpuSet_Zero(p) *(p) = (0) +#define CpuSet_Set(p, cpu) *(p) |= ((DWORD_PTR)1 << (cpu)) #else // _WIN32 -typedef struct _CThread +typedef struct { pthread_t _tid; int _created; } CThread; -#define Thread_Construct(p) { (p)->_tid = 0; (p)->_created = 0; } -#define Thread_WasCreated(p) ((p)->_created != 0) +#define Thread_CONSTRUCT(p) { (p)->_tid = 0; (p)->_created = 0; } +#define Thread_WasCreated(p) ((p)->_created != 0) WRes Thread_Close(CThread *p); // #define Thread_Wait Thread_Wait_Close typedef void * THREAD_FUNC_RET_TYPE; +#define THREAD_FUNC_RET_ZERO NULL + typedef UInt64 CAffinityMask; -#ifdef _7ZIP_AFFINITY_SUPPORTED +#ifdef Z7_AFFINITY_SUPPORTED typedef cpu_set_t CCpuSet; -#define CpuSet_Zero(p) CPU_ZERO(p) -#define CpuSet_Set(p, cpu) CPU_SET(cpu, p) -#define CpuSet_IsSet(p, cpu) CPU_ISSET(cpu, p) +#define CpuSet_Zero(p) CPU_ZERO(p) +#define CpuSet_Set(p, cpu) CPU_SET(cpu, p) +#define CpuSet_IsSet(p, cpu) CPU_ISSET(cpu, p) #else typedef UInt64 CCpuSet; -#define CpuSet_Zero(p) { *(p) = 0; } -#define CpuSet_Set(p, cpu) { *(p) |= ((UInt64)1 << (cpu)); } -#define CpuSet_IsSet(p, cpu) ((*(p) & ((UInt64)1 << (cpu))) != 0) +#define CpuSet_Zero(p) *(p) = (0) +#define CpuSet_Set(p, cpu) *(p) |= ((UInt64)1 << (cpu)) +#define CpuSet_IsSet(p, cpu) ((*(p) & ((UInt64)1 << (cpu))) != 0) #endif @@ -95,7 +100,7 @@ typedef UInt64 CCpuSet; #endif // _WIN32 -#define THREAD_FUNC_CALL_TYPE MY_STD_CALL +#define THREAD_FUNC_CALL_TYPE Z7_STDCALL #if defined(_WIN32) && defined(__GNUC__) /* GCC compiler for x86 32-bit uses the rule: @@ -187,6 +192,7 @@ WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled); WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p); WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled); WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p); + WRes Event_Set(CEvent *p); WRes Event_Reset(CEvent *p); WRes Event_Wait(CEvent *p); @@ -227,6 +233,8 @@ LONG InterlockedIncrement(LONG volatile *addend); #endif // _WIN32 +WRes AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent *p); + EXTERN_C_END #endif diff --git a/libraries/lzma/C/Xz.c b/libraries/lzma/C/Xz.c new file mode 100644 index 000000000..4ad071060 --- /dev/null +++ b/libraries/lzma/C/Xz.c @@ -0,0 +1,90 @@ +/* Xz.c - Xz +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "7zCrc.h" +#include "CpuArch.h" +#include "Xz.h" +#include "XzCrc64.h" + +const Byte XZ_SIG[XZ_SIG_SIZE] = { 0xFD, '7', 'z', 'X', 'Z', 0 }; +/* const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE] = { 'Y', 'Z' }; */ + +unsigned Xz_WriteVarInt(Byte *buf, UInt64 v) +{ + unsigned i = 0; + do + { + buf[i++] = (Byte)((v & 0x7F) | 0x80); + v >>= 7; + } + while (v != 0); + buf[(size_t)i - 1] &= 0x7F; + return i; +} + +void Xz_Construct(CXzStream *p) +{ + p->numBlocks = 0; + p->blocks = NULL; + p->flags = 0; +} + +void Xz_Free(CXzStream *p, ISzAllocPtr alloc) +{ + ISzAlloc_Free(alloc, p->blocks); + p->numBlocks = 0; + p->blocks = NULL; +} + +unsigned XzFlags_GetCheckSize(CXzStreamFlags f) +{ + unsigned t = XzFlags_GetCheckType(f); + return (t == 0) ? 0 : ((unsigned)4 << ((t - 1) / 3)); +} + +void XzCheck_Init(CXzCheck *p, unsigned mode) +{ + p->mode = mode; + switch (mode) + { + case XZ_CHECK_CRC32: p->crc = CRC_INIT_VAL; break; + case XZ_CHECK_CRC64: p->crc64 = CRC64_INIT_VAL; break; + case XZ_CHECK_SHA256: Sha256_Init(&p->sha); break; + } +} + +void XzCheck_Update(CXzCheck *p, const void *data, size_t size) +{ + switch (p->mode) + { + case XZ_CHECK_CRC32: p->crc = CrcUpdate(p->crc, data, size); break; + case XZ_CHECK_CRC64: p->crc64 = Crc64Update(p->crc64, data, size); break; + case XZ_CHECK_SHA256: Sha256_Update(&p->sha, (const Byte *)data, size); break; + } +} + +int XzCheck_Final(CXzCheck *p, Byte *digest) +{ + switch (p->mode) + { + case XZ_CHECK_CRC32: + SetUi32(digest, CRC_GET_DIGEST(p->crc)) + break; + case XZ_CHECK_CRC64: + { + int i; + UInt64 v = CRC64_GET_DIGEST(p->crc64); + for (i = 0; i < 8; i++, v >>= 8) + digest[i] = (Byte)(v & 0xFF); + break; + } + case XZ_CHECK_SHA256: + Sha256_Final(&p->sha, digest); + break; + default: + return 0; + } + return 1; +} diff --git a/libraries/lzma/C/Xz.h b/libraries/lzma/C/Xz.h new file mode 100644 index 000000000..d5001f6ca --- /dev/null +++ b/libraries/lzma/C/Xz.h @@ -0,0 +1,535 @@ +/* Xz.h - Xz interface +2023-04-13 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_XZ_H +#define ZIP7_INC_XZ_H + +#include "Sha256.h" +#include "Delta.h" + +EXTERN_C_BEGIN + +#define XZ_ID_Subblock 1 +#define XZ_ID_Delta 3 +#define XZ_ID_X86 4 +#define XZ_ID_PPC 5 +#define XZ_ID_IA64 6 +#define XZ_ID_ARM 7 +#define XZ_ID_ARMT 8 +#define XZ_ID_SPARC 9 +#define XZ_ID_ARM64 0xa +#define XZ_ID_LZMA2 0x21 + +unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value); +unsigned Xz_WriteVarInt(Byte *buf, UInt64 v); + +/* ---------- xz block ---------- */ + +#define XZ_BLOCK_HEADER_SIZE_MAX 1024 + +#define XZ_NUM_FILTERS_MAX 4 +#define XZ_BF_NUM_FILTERS_MASK 3 +#define XZ_BF_PACK_SIZE (1 << 6) +#define XZ_BF_UNPACK_SIZE (1 << 7) + +#define XZ_FILTER_PROPS_SIZE_MAX 20 + +typedef struct +{ + UInt64 id; + UInt32 propsSize; + Byte props[XZ_FILTER_PROPS_SIZE_MAX]; +} CXzFilter; + +typedef struct +{ + UInt64 packSize; + UInt64 unpackSize; + Byte flags; + CXzFilter filters[XZ_NUM_FILTERS_MAX]; +} CXzBlock; + +#define XzBlock_GetNumFilters(p) (((unsigned)(p)->flags & XZ_BF_NUM_FILTERS_MASK) + 1) +#define XzBlock_HasPackSize(p) (((p)->flags & XZ_BF_PACK_SIZE) != 0) +#define XzBlock_HasUnpackSize(p) (((p)->flags & XZ_BF_UNPACK_SIZE) != 0) +#define XzBlock_HasUnsupportedFlags(p) (((p)->flags & ~(XZ_BF_NUM_FILTERS_MASK | XZ_BF_PACK_SIZE | XZ_BF_UNPACK_SIZE)) != 0) + +SRes XzBlock_Parse(CXzBlock *p, const Byte *header); +SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStreamPtr inStream, BoolInt *isIndex, UInt32 *headerSizeRes); + +/* ---------- xz stream ---------- */ + +#define XZ_SIG_SIZE 6 +#define XZ_FOOTER_SIG_SIZE 2 + +extern const Byte XZ_SIG[XZ_SIG_SIZE]; + +/* +extern const Byte XZ_FOOTER_SIG[XZ_FOOTER_SIG_SIZE]; +*/ + +#define XZ_FOOTER_SIG_0 'Y' +#define XZ_FOOTER_SIG_1 'Z' + +#define XZ_STREAM_FLAGS_SIZE 2 +#define XZ_STREAM_CRC_SIZE 4 + +#define XZ_STREAM_HEADER_SIZE (XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE) +#define XZ_STREAM_FOOTER_SIZE (XZ_FOOTER_SIG_SIZE + XZ_STREAM_FLAGS_SIZE + XZ_STREAM_CRC_SIZE + 4) + +#define XZ_CHECK_MASK 0xF +#define XZ_CHECK_NO 0 +#define XZ_CHECK_CRC32 1 +#define XZ_CHECK_CRC64 4 +#define XZ_CHECK_SHA256 10 + +typedef struct +{ + unsigned mode; + UInt32 crc; + UInt64 crc64; + CSha256 sha; +} CXzCheck; + +void XzCheck_Init(CXzCheck *p, unsigned mode); +void XzCheck_Update(CXzCheck *p, const void *data, size_t size); +int XzCheck_Final(CXzCheck *p, Byte *digest); + +typedef UInt16 CXzStreamFlags; + +#define XzFlags_IsSupported(f) ((f) <= XZ_CHECK_MASK) +#define XzFlags_GetCheckType(f) ((f) & XZ_CHECK_MASK) +#define XzFlags_HasDataCrc32(f) (Xz_GetCheckType(f) == XZ_CHECK_CRC32) +unsigned XzFlags_GetCheckSize(CXzStreamFlags f); + +SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf); +SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStreamPtr inStream); + +typedef struct +{ + UInt64 unpackSize; + UInt64 totalSize; +} CXzBlockSizes; + +typedef struct +{ + CXzStreamFlags flags; + // Byte _pad[6]; + size_t numBlocks; + CXzBlockSizes *blocks; + UInt64 startOffset; +} CXzStream; + +void Xz_Construct(CXzStream *p); +void Xz_Free(CXzStream *p, ISzAllocPtr alloc); + +#define XZ_SIZE_OVERFLOW ((UInt64)(Int64)-1) + +UInt64 Xz_GetUnpackSize(const CXzStream *p); +UInt64 Xz_GetPackSize(const CXzStream *p); + +typedef struct +{ + size_t num; + size_t numAllocated; + CXzStream *streams; +} CXzs; + +void Xzs_Construct(CXzs *p); +void Xzs_Free(CXzs *p, ISzAllocPtr alloc); +SRes Xzs_ReadBackward(CXzs *p, ILookInStreamPtr inStream, Int64 *startOffset, ICompressProgressPtr progress, ISzAllocPtr alloc); + +UInt64 Xzs_GetNumBlocks(const CXzs *p); +UInt64 Xzs_GetUnpackSize(const CXzs *p); + + +// ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder + +typedef enum +{ + CODER_STATUS_NOT_SPECIFIED, /* use main error code instead */ + CODER_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + CODER_STATUS_NOT_FINISHED, /* stream was not finished */ + CODER_STATUS_NEEDS_MORE_INPUT /* you must provide more input bytes */ +} ECoderStatus; + + +// ECoderFinishMode values are identical to ELzmaFinishMode + +typedef enum +{ + CODER_FINISH_ANY, /* finish at any point */ + CODER_FINISH_END /* block must be finished at the end */ +} ECoderFinishMode; + + +typedef struct +{ + void *p; // state object; + void (*Free)(void *p, ISzAllocPtr alloc); + SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAllocPtr alloc); + void (*Init)(void *p); + SRes (*Code2)(void *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + int srcWasFinished, ECoderFinishMode finishMode, + // int *wasFinished, + ECoderStatus *status); + SizeT (*Filter)(void *p, Byte *data, SizeT size); +} IStateCoder; + + +typedef struct +{ + UInt32 methodId; + UInt32 delta; + UInt32 ip; + UInt32 X86_State; + Byte delta_State[DELTA_STATE_SIZE]; +} CXzBcFilterStateBase; + +typedef SizeT (*Xz_Func_BcFilterStateBase_Filter)(CXzBcFilterStateBase *p, Byte *data, SizeT size); + +SRes Xz_StateCoder_Bc_SetFromMethod_Func(IStateCoder *p, UInt64 id, + Xz_Func_BcFilterStateBase_Filter func, ISzAllocPtr alloc); + + +#define MIXCODER_NUM_FILTERS_MAX 4 + +typedef struct +{ + ISzAllocPtr alloc; + Byte *buf; + unsigned numCoders; + + Byte *outBuf; + size_t outBufSize; + size_t outWritten; // is equal to lzmaDecoder.dicPos (in outBuf mode) + BoolInt wasFinished; + SRes res; + ECoderStatus status; + // BoolInt SingleBufMode; + + int finished[MIXCODER_NUM_FILTERS_MAX - 1]; + size_t pos[MIXCODER_NUM_FILTERS_MAX - 1]; + size_t size[MIXCODER_NUM_FILTERS_MAX - 1]; + UInt64 ids[MIXCODER_NUM_FILTERS_MAX]; + SRes results[MIXCODER_NUM_FILTERS_MAX]; + IStateCoder coders[MIXCODER_NUM_FILTERS_MAX]; +} CMixCoder; + + +typedef enum +{ + XZ_STATE_STREAM_HEADER, + XZ_STATE_STREAM_INDEX, + XZ_STATE_STREAM_INDEX_CRC, + XZ_STATE_STREAM_FOOTER, + XZ_STATE_STREAM_PADDING, + XZ_STATE_BLOCK_HEADER, + XZ_STATE_BLOCK, + XZ_STATE_BLOCK_FOOTER +} EXzState; + + +typedef struct +{ + EXzState state; + UInt32 pos; + unsigned alignPos; + unsigned indexPreSize; + + CXzStreamFlags streamFlags; + + UInt32 blockHeaderSize; + UInt64 packSize; + UInt64 unpackSize; + + UInt64 numBlocks; // number of finished blocks in current stream + UInt64 indexSize; + UInt64 indexPos; + UInt64 padSize; + + UInt64 numStartedStreams; + UInt64 numFinishedStreams; + UInt64 numTotalBlocks; + + UInt32 crc; + CMixCoder decoder; + CXzBlock block; + CXzCheck check; + CSha256 sha; + + BoolInt parseMode; + BoolInt headerParsedOk; + BoolInt decodeToStreamSignature; + unsigned decodeOnlyOneBlock; + + Byte *outBuf; + size_t outBufSize; + size_t outDataWritten; // the size of data in (outBuf) that were fully unpacked + + Byte shaDigest[SHA256_DIGEST_SIZE]; + Byte buf[XZ_BLOCK_HEADER_SIZE_MAX]; +} CXzUnpacker; + +/* alloc : aligned for cache line allocation is better */ +void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc); +void XzUnpacker_Init(CXzUnpacker *p); +void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize); +void XzUnpacker_Free(CXzUnpacker *p); + +/* + XzUnpacker + The sequence for decoding functions: + { + XzUnpacker_Construct() + [Decoding_Calls] + XzUnpacker_Free() + } + + [Decoding_Calls] + + There are 3 types of interfaces for [Decoding_Calls] calls: + + Interface-1 : Partial output buffers: + { + XzUnpacker_Init() + for() + { + XzUnpacker_Code(); + } + XzUnpacker_IsStreamWasFinished() + } + + Interface-2 : Direct output buffer: + Use it, if you know exact size of decoded data, and you need + whole xz unpacked data in one output buffer. + xz unpacker doesn't allocate additional buffer for lzma2 dictionary in that mode. + { + XzUnpacker_Init() + XzUnpacker_SetOutBufMode(); // to set output buffer and size + for() + { + XzUnpacker_Code(); // (dest = NULL) in XzUnpacker_Code() + } + XzUnpacker_IsStreamWasFinished() + } + + Interface-3 : Direct output buffer : One call full decoding + It unpacks whole input buffer to output buffer in one call. + It uses Interface-2 internally. + { + XzUnpacker_CodeFull() + XzUnpacker_IsStreamWasFinished() + } +*/ + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + CODER_FINISH_ANY - use smallest number of input bytes + CODER_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + CODER_STATUS_NOT_FINISHED, + CODER_STATUS_NEEDS_MORE_INPUT - the decoder can return it in two cases: + 1) it needs more input data to finish current xz stream + 2) xz stream was finished successfully. But the decoder supports multiple + concatented xz streams. So it expects more input data for new xz streams. + Call XzUnpacker_IsStreamWasFinished() to check that latest xz stream was finished successfully. + + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_DATA - Data error + SZ_ERROR_UNSUPPORTED - Unsupported method or method properties + SZ_ERROR_CRC - CRC error + // SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). + + SZ_ERROR_NO_ARCHIVE - the error with xz Stream Header with one of the following reasons: + - xz Stream Signature failure + - CRC32 of xz Stream Header is failed + - The size of Stream padding is not multiple of four bytes. + It's possible to get that error, if xz stream was finished and the stream + contains some another data. In that case you can call XzUnpacker_GetExtraSize() + function to get real size of xz stream. +*/ + + +SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, int srcFinished, + ECoderFinishMode finishMode, ECoderStatus *status); + +SRes XzUnpacker_CodeFull(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, + ECoderFinishMode finishMode, ECoderStatus *status); + +/* +If you decode full xz stream(s), then you can call XzUnpacker_IsStreamWasFinished() +after successful XzUnpacker_CodeFull() or after last call of XzUnpacker_Code(). +*/ + +BoolInt XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p); + +/* +XzUnpacker_GetExtraSize() returns then number of unconfirmed bytes, + if it's in (XZ_STATE_STREAM_HEADER) state or in (XZ_STATE_STREAM_PADDING) state. +These bytes can be some data after xz archive, or +it can be start of new xz stream. + +Call XzUnpacker_GetExtraSize() after XzUnpacker_Code() function to detect real size of +xz stream in two cases, if XzUnpacker_Code() returns: + res == SZ_OK && status == CODER_STATUS_NEEDS_MORE_INPUT + res == SZ_ERROR_NO_ARCHIVE +*/ + +UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p); + + +/* + for random block decoding: + XzUnpacker_Init(); + set CXzUnpacker::streamFlags + XzUnpacker_PrepareToRandomBlockDecoding() + loop + { + XzUnpacker_Code() + XzUnpacker_IsBlockFinished() + } +*/ + +void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p); +BoolInt XzUnpacker_IsBlockFinished(const CXzUnpacker *p); + +#define XzUnpacker_GetPackSizeForIndex(p) ((p)->packSize + (p)->blockHeaderSize + XzFlags_GetCheckSize((p)->streamFlags)) + + + + + + +/* ---- Single-Thread and Multi-Thread xz Decoding with Input/Output Streams ---- */ + +/* + if (CXzDecMtProps::numThreads > 1), the decoder can try to use + Multi-Threading. The decoder analyses xz block header, and if + there are pack size and unpack size values stored in xz block header, + the decoder reads compressed data of block to internal buffers, + and then it can start parallel decoding, if there are another blocks. + The decoder can switch back to Single-Thread decoding after some conditions. + + The sequence of calls for xz decoding with in/out Streams: + { + XzDecMt_Create() + XzDecMtProps_Init(XzDecMtProps) to set default values of properties + // then you can change some XzDecMtProps parameters with required values + // here you can set the number of threads and (memUseMax) - the maximum + Memory usage for multithreading decoding. + for() + { + XzDecMt_Decode() // one call per one file + } + XzDecMt_Destroy() + } +*/ + + +typedef struct +{ + size_t inBufSize_ST; // size of input buffer for Single-Thread decoding + size_t outStep_ST; // size of output buffer for Single-Thread decoding + BoolInt ignoreErrors; // if set to 1, the decoder can ignore some errors and it skips broken parts of data. + + #ifndef Z7_ST + unsigned numThreads; // the number of threads for Multi-Thread decoding. if (umThreads == 1) it will use Single-thread decoding + size_t inBufSize_MT; // size of small input data buffers for Multi-Thread decoding. Big number of such small buffers can be created + size_t memUseMax; // the limit of total memory usage for Multi-Thread decoding. + // it's recommended to set (memUseMax) manually to value that is smaller of total size of RAM in computer. + #endif +} CXzDecMtProps; + +void XzDecMtProps_Init(CXzDecMtProps *p); + +typedef struct CXzDecMt CXzDecMt; +typedef CXzDecMt * CXzDecMtHandle; +// Z7_DECLARE_HANDLE(CXzDecMtHandle) + +/* + alloc : XzDecMt uses CAlignOffsetAlloc internally for addresses allocated by (alloc). + allocMid : for big allocations, aligned allocation is better +*/ + +CXzDecMtHandle XzDecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid); +void XzDecMt_Destroy(CXzDecMtHandle p); + + +typedef struct +{ + Byte UnpackSize_Defined; + Byte NumStreams_Defined; + Byte NumBlocks_Defined; + + Byte DataAfterEnd; // there are some additional data after good xz streams, and that data is not new xz stream. + Byte DecodingTruncated; // Decoding was Truncated, we need only partial output data + + UInt64 InSize; // pack size processed. That value doesn't include the data after + // end of xz stream, if that data was not correct + UInt64 OutSize; + + UInt64 NumStreams; + UInt64 NumBlocks; + + SRes DecodeRes; // the error code of xz streams data decoding + SRes ReadRes; // error code from ISeqInStream:Read() + SRes ProgressRes; // error code from ICompressProgress:Progress() + + SRes CombinedRes; // Combined result error code that shows main rusult + // = S_OK, if there is no error. + // but check also (DataAfterEnd) that can show additional minor errors. + + SRes CombinedRes_Type; // = SZ_ERROR_READ, if error from ISeqInStream + // = SZ_ERROR_PROGRESS, if error from ICompressProgress + // = SZ_ERROR_WRITE, if error from ISeqOutStream + // = SZ_ERROR_* codes for decoding +} CXzStatInfo; + +void XzStatInfo_Clear(CXzStatInfo *p); + +/* + +XzDecMt_Decode() +SRes: it's combined decoding result. It also is equal to stat->CombinedRes. + + SZ_OK - no error + check also output value in (stat->DataAfterEnd) + that can show additional possible error + + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_NO_ARCHIVE - is not xz archive + SZ_ERROR_ARCHIVE - Headers error + SZ_ERROR_DATA - Data Error + SZ_ERROR_UNSUPPORTED - Unsupported method or method properties + SZ_ERROR_CRC - CRC Error + SZ_ERROR_INPUT_EOF - it needs more input data + SZ_ERROR_WRITE - ISeqOutStream error + (SZ_ERROR_READ) - ISeqInStream errors + (SZ_ERROR_PROGRESS) - ICompressProgress errors + // SZ_ERROR_THREAD - error in multi-threading functions + MY_SRes_HRESULT_FROM_WRes(WRes_error) - error in multi-threading function +*/ + +SRes XzDecMt_Decode(CXzDecMtHandle p, + const CXzDecMtProps *props, + const UInt64 *outDataSize, // NULL means undefined + int finishMode, // 0 - partial unpacking is allowed, 1 - xz stream(s) must be finished + ISeqOutStreamPtr outStream, + // Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + // const Byte *inData, size_t inDataSize, + CXzStatInfo *stat, // out: decoding results and statistics + int *isMT, // out: 0 means that ST (Single-Thread) version was used + // 1 means that MT (Multi-Thread) version was used + ICompressProgressPtr progress); + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/XzCrc64.c b/libraries/lzma/C/XzCrc64.c new file mode 100644 index 000000000..c2fad6cda --- /dev/null +++ b/libraries/lzma/C/XzCrc64.c @@ -0,0 +1,80 @@ +/* XzCrc64.c -- CRC64 calculation +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "XzCrc64.h" +#include "CpuArch.h" + +#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42) + +#ifdef MY_CPU_LE + #define CRC64_NUM_TABLES 4 +#else + #define CRC64_NUM_TABLES 5 + + UInt64 Z7_FASTCALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif + +#ifndef MY_CPU_BE + UInt64 Z7_FASTCALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table); +#endif + +typedef UInt64 (Z7_FASTCALL *CRC64_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table); + +static CRC64_FUNC g_Crc64Update; +UInt64 g_Crc64Table[256 * CRC64_NUM_TABLES]; + +UInt64 Z7_FASTCALL Crc64Update(UInt64 v, const void *data, size_t size) +{ + return g_Crc64Update(v, data, size, g_Crc64Table); +} + +UInt64 Z7_FASTCALL Crc64Calc(const void *data, size_t size) +{ + return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL; +} + +void Z7_FASTCALL Crc64GenerateTable(void) +{ + UInt32 i; + for (i = 0; i < 256; i++) + { + UInt64 r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1))); + g_Crc64Table[i] = r; + } + for (i = 256; i < 256 * CRC64_NUM_TABLES; i++) + { + const UInt64 r = g_Crc64Table[(size_t)i - 256]; + g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8); + } + + #ifdef MY_CPU_LE + + g_Crc64Update = XzCrc64UpdateT4; + + #else + { + #ifndef MY_CPU_BE + UInt32 k = 1; + if (*(const Byte *)&k == 1) + g_Crc64Update = XzCrc64UpdateT4; + else + #endif + { + for (i = 256 * CRC64_NUM_TABLES - 1; i >= 256; i--) + { + const UInt64 x = g_Crc64Table[(size_t)i - 256]; + g_Crc64Table[i] = Z7_BSWAP64(x); + } + g_Crc64Update = XzCrc64UpdateT1_BeT4; + } + } + #endif +} + +#undef kCrc64Poly +#undef CRC64_NUM_TABLES diff --git a/libraries/lzma/C/XzCrc64.h b/libraries/lzma/C/XzCrc64.h new file mode 100644 index 000000000..ca46869a6 --- /dev/null +++ b/libraries/lzma/C/XzCrc64.h @@ -0,0 +1,26 @@ +/* XzCrc64.h -- CRC64 calculation +2023-04-02 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_XZ_CRC64_H +#define ZIP7_INC_XZ_CRC64_H + +#include + +#include "7zTypes.h" + +EXTERN_C_BEGIN + +extern UInt64 g_Crc64Table[]; + +void Z7_FASTCALL Crc64GenerateTable(void); + +#define CRC64_INIT_VAL UINT64_CONST(0xFFFFFFFFFFFFFFFF) +#define CRC64_GET_DIGEST(crc) ((crc) ^ CRC64_INIT_VAL) +#define CRC64_UPDATE_BYTE(crc, b) (g_Crc64Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt64 Z7_FASTCALL Crc64Update(UInt64 crc, const void *data, size_t size); +UInt64 Z7_FASTCALL Crc64Calc(const void *data, size_t size); + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/XzCrc64Opt.c b/libraries/lzma/C/XzCrc64Opt.c new file mode 100644 index 000000000..d03374c00 --- /dev/null +++ b/libraries/lzma/C/XzCrc64Opt.c @@ -0,0 +1,61 @@ +/* XzCrc64Opt.c -- CRC64 calculation +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include "CpuArch.h" + +#ifndef MY_CPU_BE + +#define CRC64_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +UInt64 Z7_FASTCALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table); +UInt64 Z7_FASTCALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table) +{ + const Byte *p = (const Byte *)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC64_UPDATE_BYTE_2(v, *p); + for (; size >= 4; size -= 4, p += 4) + { + const UInt32 d = (UInt32)v ^ *(const UInt32 *)(const void *)p; + v = (v >> 32) + ^ (table + 0x300)[((d ) & 0xFF)] + ^ (table + 0x200)[((d >> 8) & 0xFF)] + ^ (table + 0x100)[((d >> 16) & 0xFF)] + ^ (table + 0x000)[((d >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC64_UPDATE_BYTE_2(v, *p); + return v; +} + +#endif + + +#ifndef MY_CPU_LE + +#define CRC64_UPDATE_BYTE_2_BE(crc, b) (table[(Byte)((crc) >> 56) ^ (b)] ^ ((crc) << 8)) + +UInt64 Z7_FASTCALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table); +UInt64 Z7_FASTCALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table) +{ + const Byte *p = (const Byte *)data; + table += 0x100; + v = Z7_BSWAP64(v); + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC64_UPDATE_BYTE_2_BE(v, *p); + for (; size >= 4; size -= 4, p += 4) + { + const UInt32 d = (UInt32)(v >> 32) ^ *(const UInt32 *)(const void *)p; + v = (v << 32) + ^ (table + 0x000)[((d ) & 0xFF)] + ^ (table + 0x100)[((d >> 8) & 0xFF)] + ^ (table + 0x200)[((d >> 16) & 0xFF)] + ^ (table + 0x300)[((d >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC64_UPDATE_BYTE_2_BE(v, *p); + return Z7_BSWAP64(v); +} + +#endif diff --git a/libraries/lzma/C/XzDec.c b/libraries/lzma/C/XzDec.c new file mode 100644 index 000000000..a5f703966 --- /dev/null +++ b/libraries/lzma/C/XzDec.c @@ -0,0 +1,2875 @@ +/* XzDec.c -- Xz Decode +2023-04-13 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +// #include + +// #define XZ_DUMP + +/* #define XZ_DUMP */ + +#ifdef XZ_DUMP +#include +#endif + +// #define SHOW_DEBUG_INFO + +#ifdef SHOW_DEBUG_INFO +#include +#endif + +#ifdef SHOW_DEBUG_INFO +#define PRF(x) x +#else +#define PRF(x) +#endif + +#define PRF_STR(s) PRF(printf("\n" s "\n")) +#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) + +#include +#include + +#include "7zCrc.h" +#include "Alloc.h" +#include "Bra.h" +#include "CpuArch.h" +#include "Delta.h" +#include "Lzma2Dec.h" + +// #define USE_SUBBLOCK + +#ifdef USE_SUBBLOCK +#include "Bcj3Dec.c" +#include "SbDec.h" +#endif + +#include "Xz.h" + +#define XZ_CHECK_SIZE_MAX 64 + +#define CODER_BUF_SIZE ((size_t)1 << 17) + +unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value) +{ + unsigned i, limit; + *value = 0; + limit = (maxSize > 9) ? 9 : (unsigned)maxSize; + + for (i = 0; i < limit;) + { + Byte b = p[i]; + *value |= (UInt64)(b & 0x7F) << (7 * i++); + if ((b & 0x80) == 0) + return (b == 0 && i != 1) ? 0 : i; + } + return 0; +} + + +/* ---------- XzBcFilterState ---------- */ + +#define BRA_BUF_SIZE (1 << 14) + +typedef struct +{ + size_t bufPos; + size_t bufConv; + size_t bufTotal; + Byte *buf; // must be aligned for 4 bytes + Xz_Func_BcFilterStateBase_Filter filter_func; + // int encodeMode; + CXzBcFilterStateBase base; + // Byte buf[BRA_BUF_SIZE]; +} CXzBcFilterState; + + +static void XzBcFilterState_Free(void *pp, ISzAllocPtr alloc) +{ + if (pp) + { + CXzBcFilterState *p = ((CXzBcFilterState *)pp); + ISzAlloc_Free(alloc, p->buf); + ISzAlloc_Free(alloc, pp); + } +} + + +static SRes XzBcFilterState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) +{ + CXzBcFilterStateBase *p = &((CXzBcFilterState *)pp)->base; + UNUSED_VAR(alloc) + p->ip = 0; + if (p->methodId == XZ_ID_Delta) + { + if (propSize != 1) + return SZ_ERROR_UNSUPPORTED; + p->delta = (unsigned)props[0] + 1; + } + else + { + if (propSize == 4) + { + UInt32 v = GetUi32(props); + switch (p->methodId) + { + case XZ_ID_PPC: + case XZ_ID_ARM: + case XZ_ID_SPARC: + case XZ_ID_ARM64: + if ((v & 3) != 0) + return SZ_ERROR_UNSUPPORTED; + break; + case XZ_ID_ARMT: + if ((v & 1) != 0) + return SZ_ERROR_UNSUPPORTED; + break; + case XZ_ID_IA64: + if ((v & 0xF) != 0) + return SZ_ERROR_UNSUPPORTED; + break; + } + p->ip = v; + } + else if (propSize != 0) + return SZ_ERROR_UNSUPPORTED; + } + return SZ_OK; +} + + +static void XzBcFilterState_Init(void *pp) +{ + CXzBcFilterState *p = ((CXzBcFilterState *)pp); + p->bufPos = p->bufConv = p->bufTotal = 0; + p->base.X86_State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; + if (p->base.methodId == XZ_ID_Delta) + Delta_Init(p->base.delta_State); +} + + +static const z7_Func_BranchConv g_Funcs_BranchConv_RISC_Dec[] = +{ + Z7_BRANCH_CONV_DEC(PPC), + Z7_BRANCH_CONV_DEC(IA64), + Z7_BRANCH_CONV_DEC(ARM), + Z7_BRANCH_CONV_DEC(ARMT), + Z7_BRANCH_CONV_DEC(SPARC), + Z7_BRANCH_CONV_DEC(ARM64) +}; + +static SizeT XzBcFilterStateBase_Filter_Dec(CXzBcFilterStateBase *p, Byte *data, SizeT size) +{ + switch (p->methodId) + { + case XZ_ID_Delta: + Delta_Decode(p->delta_State, p->delta, data, size); + break; + case XZ_ID_X86: + size = (SizeT)(z7_BranchConvSt_X86_Dec(data, size, p->ip, &p->X86_State) - data); + break; + default: + if (p->methodId >= XZ_ID_PPC) + { + const UInt32 i = p->methodId - XZ_ID_PPC; + if (i < Z7_ARRAY_SIZE(g_Funcs_BranchConv_RISC_Dec)) + size = (SizeT)(g_Funcs_BranchConv_RISC_Dec[i](data, size, p->ip) - data); + } + break; + } + p->ip += (UInt32)size; + return size; +} + + +static SizeT XzBcFilterState_Filter(void *pp, Byte *data, SizeT size) +{ + CXzBcFilterState *p = ((CXzBcFilterState *)pp); + return p->filter_func(&p->base, data, size); +} + + +static SRes XzBcFilterState_Code2(void *pp, + Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, int srcWasFinished, + ECoderFinishMode finishMode, + // int *wasFinished + ECoderStatus *status) +{ + CXzBcFilterState *p = ((CXzBcFilterState *)pp); + SizeT destRem = *destLen; + SizeT srcRem = *srcLen; + UNUSED_VAR(finishMode) + + *destLen = 0; + *srcLen = 0; + // *wasFinished = False; + *status = CODER_STATUS_NOT_FINISHED; + + while (destRem != 0) + { + { + size_t size = p->bufConv - p->bufPos; + if (size) + { + if (size > destRem) + size = destRem; + memcpy(dest, p->buf + p->bufPos, size); + p->bufPos += size; + *destLen += size; + dest += size; + destRem -= size; + continue; + } + } + + p->bufTotal -= p->bufPos; + memmove(p->buf, p->buf + p->bufPos, p->bufTotal); + p->bufPos = 0; + p->bufConv = 0; + { + size_t size = BRA_BUF_SIZE - p->bufTotal; + if (size > srcRem) + size = srcRem; + memcpy(p->buf + p->bufTotal, src, size); + *srcLen += size; + src += size; + srcRem -= size; + p->bufTotal += size; + } + if (p->bufTotal == 0) + break; + + p->bufConv = p->filter_func(&p->base, p->buf, p->bufTotal); + + if (p->bufConv == 0) + { + if (!srcWasFinished) + break; + p->bufConv = p->bufTotal; + } + } + + if (p->bufTotal == p->bufPos && srcRem == 0 && srcWasFinished) + { + *status = CODER_STATUS_FINISHED_WITH_MARK; + // *wasFinished = 1; + } + + return SZ_OK; +} + + +#define XZ_IS_SUPPORTED_FILTER_ID(id) \ + ((id) >= XZ_ID_Delta && (id) <= XZ_ID_ARM64) + +SRes Xz_StateCoder_Bc_SetFromMethod_Func(IStateCoder *p, UInt64 id, + Xz_Func_BcFilterStateBase_Filter func, ISzAllocPtr alloc) +{ + CXzBcFilterState *decoder; + if (!XZ_IS_SUPPORTED_FILTER_ID(id)) + return SZ_ERROR_UNSUPPORTED; + decoder = (CXzBcFilterState *)p->p; + if (!decoder) + { + decoder = (CXzBcFilterState *)ISzAlloc_Alloc(alloc, sizeof(CXzBcFilterState)); + if (!decoder) + return SZ_ERROR_MEM; + decoder->buf = ISzAlloc_Alloc(alloc, BRA_BUF_SIZE); + if (!decoder->buf) + { + ISzAlloc_Free(alloc, decoder); + return SZ_ERROR_MEM; + } + p->p = decoder; + p->Free = XzBcFilterState_Free; + p->SetProps = XzBcFilterState_SetProps; + p->Init = XzBcFilterState_Init; + p->Code2 = XzBcFilterState_Code2; + p->Filter = XzBcFilterState_Filter; + decoder->filter_func = func; + } + decoder->base.methodId = (UInt32)id; + // decoder->encodeMode = encodeMode; + return SZ_OK; +} + + + +/* ---------- SbState ---------- */ + +#ifdef USE_SUBBLOCK + +static void SbState_Free(void *pp, ISzAllocPtr alloc) +{ + CSbDec *p = (CSbDec *)pp; + SbDec_Free(p); + ISzAlloc_Free(alloc, pp); +} + +static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) +{ + UNUSED_VAR(pp) + UNUSED_VAR(props) + UNUSED_VAR(alloc) + return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED; +} + +static void SbState_Init(void *pp) +{ + SbDec_Init((CSbDec *)pp); +} + +static SRes SbState_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + int srcWasFinished, ECoderFinishMode finishMode, + // int *wasFinished + ECoderStatus *status) +{ + CSbDec *p = (CSbDec *)pp; + SRes res; + UNUSED_VAR(srcWasFinished) + p->dest = dest; + p->destLen = *destLen; + p->src = src; + p->srcLen = *srcLen; + p->finish = finishMode; /* change it */ + res = SbDec_Decode((CSbDec *)pp); + *destLen -= p->destLen; + *srcLen -= p->srcLen; + // *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */ + *status = (*destLen == 0 && *srcLen == 0) ? + CODER_STATUS_FINISHED_WITH_MARK : + CODER_STATUS_NOT_FINISHED; + return res; +} + +static SRes SbState_SetFromMethod(IStateCoder *p, ISzAllocPtr alloc) +{ + CSbDec *decoder = (CSbDec *)p->p; + if (!decoder) + { + decoder = (CSbDec *)ISzAlloc_Alloc(alloc, sizeof(CSbDec)); + if (!decoder) + return SZ_ERROR_MEM; + p->p = decoder; + p->Free = SbState_Free; + p->SetProps = SbState_SetProps; + p->Init = SbState_Init; + p->Code2 = SbState_Code2; + p->Filter = NULL; + } + SbDec_Construct(decoder); + SbDec_SetAlloc(decoder, alloc); + return SZ_OK; +} + +#endif + + + +/* ---------- Lzma2 ---------- */ + +typedef struct +{ + CLzma2Dec decoder; + BoolInt outBufMode; +} CLzma2Dec_Spec; + + +static void Lzma2State_Free(void *pp, ISzAllocPtr alloc) +{ + CLzma2Dec_Spec *p = (CLzma2Dec_Spec *)pp; + if (p->outBufMode) + Lzma2Dec_FreeProbs(&p->decoder, alloc); + else + Lzma2Dec_Free(&p->decoder, alloc); + ISzAlloc_Free(alloc, pp); +} + +static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) +{ + if (propSize != 1) + return SZ_ERROR_UNSUPPORTED; + { + CLzma2Dec_Spec *p = (CLzma2Dec_Spec *)pp; + if (p->outBufMode) + return Lzma2Dec_AllocateProbs(&p->decoder, props[0], alloc); + else + return Lzma2Dec_Allocate(&p->decoder, props[0], alloc); + } +} + +static void Lzma2State_Init(void *pp) +{ + Lzma2Dec_Init(&((CLzma2Dec_Spec *)pp)->decoder); +} + + +/* + if (outBufMode), then (dest) is not used. Use NULL. + Data is unpacked to (spec->decoder.decoder.dic) output buffer. +*/ + +static SRes Lzma2State_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, + int srcWasFinished, ECoderFinishMode finishMode, + // int *wasFinished, + ECoderStatus *status) +{ + CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)pp; + ELzmaStatus status2; + /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ + SRes res; + UNUSED_VAR(srcWasFinished) + if (spec->outBufMode) + { + SizeT dicPos = spec->decoder.decoder.dicPos; + SizeT dicLimit = dicPos + *destLen; + res = Lzma2Dec_DecodeToDic(&spec->decoder, dicLimit, src, srcLen, (ELzmaFinishMode)finishMode, &status2); + *destLen = spec->decoder.decoder.dicPos - dicPos; + } + else + res = Lzma2Dec_DecodeToBuf(&spec->decoder, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status2); + // *wasFinished = (status2 == LZMA_STATUS_FINISHED_WITH_MARK); + // ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder + *status = (ECoderStatus)status2; + return res; +} + + +static SRes Lzma2State_SetFromMethod(IStateCoder *p, Byte *outBuf, size_t outBufSize, ISzAllocPtr alloc) +{ + CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)p->p; + if (!spec) + { + spec = (CLzma2Dec_Spec *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Dec_Spec)); + if (!spec) + return SZ_ERROR_MEM; + p->p = spec; + p->Free = Lzma2State_Free; + p->SetProps = Lzma2State_SetProps; + p->Init = Lzma2State_Init; + p->Code2 = Lzma2State_Code2; + p->Filter = NULL; + Lzma2Dec_CONSTRUCT(&spec->decoder) + } + spec->outBufMode = False; + if (outBuf) + { + spec->outBufMode = True; + spec->decoder.decoder.dic = outBuf; + spec->decoder.decoder.dicBufSize = outBufSize; + } + return SZ_OK; +} + + +static SRes Lzma2State_ResetOutBuf(IStateCoder *p, Byte *outBuf, size_t outBufSize) +{ + CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)p->p; + if ((spec->outBufMode && !outBuf) || (!spec->outBufMode && outBuf)) + return SZ_ERROR_FAIL; + if (outBuf) + { + spec->decoder.decoder.dic = outBuf; + spec->decoder.decoder.dicBufSize = outBufSize; + } + return SZ_OK; +} + + + +static void MixCoder_Construct(CMixCoder *p, ISzAllocPtr alloc) +{ + unsigned i; + p->alloc = alloc; + p->buf = NULL; + p->numCoders = 0; + + p->outBufSize = 0; + p->outBuf = NULL; + // p->SingleBufMode = False; + + for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++) + p->coders[i].p = NULL; +} + + +static void MixCoder_Free(CMixCoder *p) +{ + unsigned i; + p->numCoders = 0; + for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++) + { + IStateCoder *sc = &p->coders[i]; + if (sc->p) + { + sc->Free(sc->p, p->alloc); + sc->p = NULL; + } + } + if (p->buf) + { + ISzAlloc_Free(p->alloc, p->buf); + p->buf = NULL; /* 9.31: the BUG was fixed */ + } +} + +static void MixCoder_Init(CMixCoder *p) +{ + unsigned i; + for (i = 0; i < MIXCODER_NUM_FILTERS_MAX - 1; i++) + { + p->size[i] = 0; + p->pos[i] = 0; + p->finished[i] = 0; + } + for (i = 0; i < p->numCoders; i++) + { + IStateCoder *coder = &p->coders[i]; + coder->Init(coder->p); + p->results[i] = SZ_OK; + } + p->outWritten = 0; + p->wasFinished = False; + p->res = SZ_OK; + p->status = CODER_STATUS_NOT_SPECIFIED; +} + + +static SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize) +{ + IStateCoder *sc = &p->coders[coderIndex]; + p->ids[coderIndex] = methodId; + switch (methodId) + { + case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, outBuf, outBufSize, p->alloc); + #ifdef USE_SUBBLOCK + case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc); + #endif + } + if (coderIndex == 0) + return SZ_ERROR_UNSUPPORTED; + return Xz_StateCoder_Bc_SetFromMethod_Func(sc, methodId, + XzBcFilterStateBase_Filter_Dec, p->alloc); +} + + +static SRes MixCoder_ResetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize) +{ + IStateCoder *sc = &p->coders[coderIndex]; + switch (methodId) + { + case XZ_ID_LZMA2: return Lzma2State_ResetOutBuf(sc, outBuf, outBufSize); + } + return SZ_ERROR_UNSUPPORTED; +} + + + +/* + if (destFinish) - then unpack data block is finished at (*destLen) position, + and we can return data that were not processed by filter + +output (status) can be : + CODER_STATUS_NOT_FINISHED + CODER_STATUS_FINISHED_WITH_MARK + CODER_STATUS_NEEDS_MORE_INPUT - not implemented still +*/ + +static SRes MixCoder_Code(CMixCoder *p, + Byte *dest, SizeT *destLen, int destFinish, + const Byte *src, SizeT *srcLen, int srcWasFinished, + ECoderFinishMode finishMode) +{ + SizeT destLenOrig = *destLen; + SizeT srcLenOrig = *srcLen; + + *destLen = 0; + *srcLen = 0; + + if (p->wasFinished) + return p->res; + + p->status = CODER_STATUS_NOT_FINISHED; + + // if (p->SingleBufMode) + if (p->outBuf) + { + SRes res; + SizeT destLen2, srcLen2; + int wasFinished; + + PRF_STR("------- MixCoder Single ----------") + + srcLen2 = srcLenOrig; + destLen2 = destLenOrig; + + { + IStateCoder *coder = &p->coders[0]; + res = coder->Code2(coder->p, NULL, &destLen2, src, &srcLen2, srcWasFinished, finishMode, + // &wasFinished, + &p->status); + wasFinished = (p->status == CODER_STATUS_FINISHED_WITH_MARK); + } + + p->res = res; + + /* + if (wasFinished) + p->status = CODER_STATUS_FINISHED_WITH_MARK; + else + { + if (res == SZ_OK) + if (destLen2 != destLenOrig) + p->status = CODER_STATUS_NEEDS_MORE_INPUT; + } + */ + + + *srcLen = srcLen2; + src += srcLen2; + p->outWritten += destLen2; + + if (res != SZ_OK || srcWasFinished || wasFinished) + p->wasFinished = True; + + if (p->numCoders == 1) + *destLen = destLen2; + else if (p->wasFinished) + { + unsigned i; + size_t processed = p->outWritten; + + for (i = 1; i < p->numCoders; i++) + { + IStateCoder *coder = &p->coders[i]; + processed = coder->Filter(coder->p, p->outBuf, processed); + if (wasFinished || (destFinish && p->outWritten == destLenOrig)) + processed = p->outWritten; + PRF_STR_INT("filter", i) + } + *destLen = processed; + } + return res; + } + + PRF_STR("standard mix") + + if (p->numCoders != 1) + { + if (!p->buf) + { + p->buf = (Byte *)ISzAlloc_Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1)); + if (!p->buf) + return SZ_ERROR_MEM; + } + + finishMode = CODER_FINISH_ANY; + } + + for (;;) + { + BoolInt processed = False; + BoolInt allFinished = True; + SRes resMain = SZ_OK; + unsigned i; + + p->status = CODER_STATUS_NOT_FINISHED; + /* + if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY) + break; + */ + + for (i = 0; i < p->numCoders; i++) + { + SRes res; + IStateCoder *coder = &p->coders[i]; + Byte *dest2; + SizeT destLen2, srcLen2; // destLen2_Orig; + const Byte *src2; + int srcFinished2; + int encodingWasFinished; + ECoderStatus status2; + + if (i == 0) + { + src2 = src; + srcLen2 = srcLenOrig - *srcLen; + srcFinished2 = srcWasFinished; + } + else + { + size_t k = i - 1; + src2 = p->buf + (CODER_BUF_SIZE * k) + p->pos[k]; + srcLen2 = p->size[k] - p->pos[k]; + srcFinished2 = p->finished[k]; + } + + if (i == p->numCoders - 1) + { + dest2 = dest; + destLen2 = destLenOrig - *destLen; + } + else + { + if (p->pos[i] != p->size[i]) + continue; + dest2 = p->buf + (CODER_BUF_SIZE * i); + destLen2 = CODER_BUF_SIZE; + } + + // destLen2_Orig = destLen2; + + if (p->results[i] != SZ_OK) + { + if (resMain == SZ_OK) + resMain = p->results[i]; + continue; + } + + res = coder->Code2(coder->p, + dest2, &destLen2, + src2, &srcLen2, srcFinished2, + finishMode, + // &encodingWasFinished, + &status2); + + if (res != SZ_OK) + { + p->results[i] = res; + if (resMain == SZ_OK) + resMain = res; + } + + encodingWasFinished = (status2 == CODER_STATUS_FINISHED_WITH_MARK); + + if (!encodingWasFinished) + { + allFinished = False; + if (p->numCoders == 1 && res == SZ_OK) + p->status = status2; + } + + if (i == 0) + { + *srcLen += srcLen2; + src += srcLen2; + } + else + p->pos[(size_t)i - 1] += srcLen2; + + if (i == p->numCoders - 1) + { + *destLen += destLen2; + dest += destLen2; + } + else + { + p->size[i] = destLen2; + p->pos[i] = 0; + p->finished[i] = encodingWasFinished; + } + + if (destLen2 != 0 || srcLen2 != 0) + processed = True; + } + + if (!processed) + { + if (allFinished) + p->status = CODER_STATUS_FINISHED_WITH_MARK; + return resMain; + } + } +} + + +SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf) +{ + *p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE); + if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) != + GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE)) + return SZ_ERROR_NO_ARCHIVE; + return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED; +} + +static BoolInt Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf) +{ + return indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) + && GetUi32(buf) == CrcCalc(buf + 4, 6) + && flags == GetBe16(buf + 8) + && buf[10] == XZ_FOOTER_SIG_0 + && buf[11] == XZ_FOOTER_SIG_1; +} + +#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ + { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ + if (s == 0) return SZ_ERROR_ARCHIVE; \ + pos += s; } + + +static BoolInt XzBlock_AreSupportedFilters(const CXzBlock *p) +{ + const unsigned numFilters = XzBlock_GetNumFilters(p) - 1; + unsigned i; + { + const CXzFilter *f = &p->filters[numFilters]; + if (f->id != XZ_ID_LZMA2 || f->propsSize != 1 || f->props[0] > 40) + return False; + } + + for (i = 0; i < numFilters; i++) + { + const CXzFilter *f = &p->filters[i]; + if (f->id == XZ_ID_Delta) + { + if (f->propsSize != 1) + return False; + } + else if (!XZ_IS_SUPPORTED_FILTER_ID(f->id) + || (f->propsSize != 0 && f->propsSize != 4)) + return False; + } + return True; +} + + +SRes XzBlock_Parse(CXzBlock *p, const Byte *header) +{ + unsigned pos; + unsigned numFilters, i; + unsigned headerSize = (unsigned)header[0] << 2; + + /* (headerSize != 0) : another code checks */ + + if (CrcCalc(header, headerSize) != GetUi32(header + headerSize)) + return SZ_ERROR_ARCHIVE; + + pos = 1; + p->flags = header[pos++]; + + p->packSize = (UInt64)(Int64)-1; + if (XzBlock_HasPackSize(p)) + { + READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize) + if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63) + return SZ_ERROR_ARCHIVE; + } + + p->unpackSize = (UInt64)(Int64)-1; + if (XzBlock_HasUnpackSize(p)) + { + READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize) + } + + numFilters = XzBlock_GetNumFilters(p); + for (i = 0; i < numFilters; i++) + { + CXzFilter *filter = p->filters + i; + UInt64 size; + READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id) + READ_VARINT_AND_CHECK(header, pos, headerSize, &size) + if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX) + return SZ_ERROR_ARCHIVE; + filter->propsSize = (UInt32)size; + memcpy(filter->props, header + pos, (size_t)size); + pos += (unsigned)size; + + #ifdef XZ_DUMP + printf("\nf[%u] = %2X: ", i, (unsigned)filter->id); + { + unsigned i; + for (i = 0; i < size; i++) + printf(" %2X", filter->props[i]); + } + #endif + } + + if (XzBlock_HasUnsupportedFlags(p)) + return SZ_ERROR_UNSUPPORTED; + + while (pos < headerSize) + if (header[pos++] != 0) + return SZ_ERROR_ARCHIVE; + return SZ_OK; +} + + + + +static SRes XzDecMix_Init(CMixCoder *p, const CXzBlock *block, Byte *outBuf, size_t outBufSize) +{ + unsigned i; + BoolInt needReInit = True; + unsigned numFilters = XzBlock_GetNumFilters(block); + + if (numFilters == p->numCoders && ((p->outBuf && outBuf) || (!p->outBuf && !outBuf))) + { + needReInit = False; + for (i = 0; i < numFilters; i++) + if (p->ids[i] != block->filters[numFilters - 1 - i].id) + { + needReInit = True; + break; + } + } + + // p->SingleBufMode = (outBuf != NULL); + p->outBuf = outBuf; + p->outBufSize = outBufSize; + + // p->SingleBufMode = False; + // outBuf = NULL; + + if (needReInit) + { + MixCoder_Free(p); + for (i = 0; i < numFilters; i++) + { + RINOK(MixCoder_SetFromMethod(p, i, block->filters[numFilters - 1 - i].id, outBuf, outBufSize)) + } + p->numCoders = numFilters; + } + else + { + RINOK(MixCoder_ResetFromMethod(p, 0, block->filters[numFilters - 1].id, outBuf, outBufSize)) + } + + for (i = 0; i < numFilters; i++) + { + const CXzFilter *f = &block->filters[numFilters - 1 - i]; + IStateCoder *sc = &p->coders[i]; + RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc)) + } + + MixCoder_Init(p); + return SZ_OK; +} + + + +void XzUnpacker_Init(CXzUnpacker *p) +{ + p->state = XZ_STATE_STREAM_HEADER; + p->pos = 0; + p->numStartedStreams = 0; + p->numFinishedStreams = 0; + p->numTotalBlocks = 0; + p->padSize = 0; + p->decodeOnlyOneBlock = 0; + + p->parseMode = False; + p->decodeToStreamSignature = False; + + // p->outBuf = NULL; + // p->outBufSize = 0; + p->outDataWritten = 0; +} + + +void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize) +{ + p->outBuf = outBuf; + p->outBufSize = outBufSize; +} + + +void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc) +{ + MixCoder_Construct(&p->decoder, alloc); + p->outBuf = NULL; + p->outBufSize = 0; + XzUnpacker_Init(p); +} + + +void XzUnpacker_Free(CXzUnpacker *p) +{ + MixCoder_Free(&p->decoder); +} + + +void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p) +{ + p->indexSize = 0; + p->numBlocks = 0; + Sha256_Init(&p->sha); + p->state = XZ_STATE_BLOCK_HEADER; + p->pos = 0; + p->decodeOnlyOneBlock = 1; +} + + +static void XzUnpacker_UpdateIndex(CXzUnpacker *p, UInt64 packSize, UInt64 unpackSize) +{ + Byte temp[32]; + unsigned num = Xz_WriteVarInt(temp, packSize); + num += Xz_WriteVarInt(temp + num, unpackSize); + Sha256_Update(&p->sha, temp, num); + p->indexSize += num; + p->numBlocks++; +} + + + +SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, int srcFinished, + ECoderFinishMode finishMode, ECoderStatus *status) +{ + SizeT destLenOrig = *destLen; + SizeT srcLenOrig = *srcLen; + *destLen = 0; + *srcLen = 0; + *status = CODER_STATUS_NOT_SPECIFIED; + + for (;;) + { + SizeT srcRem; + + if (p->state == XZ_STATE_BLOCK) + { + SizeT destLen2 = destLenOrig - *destLen; + SizeT srcLen2 = srcLenOrig - *srcLen; + SRes res; + + ECoderFinishMode finishMode2 = finishMode; + BoolInt srcFinished2 = srcFinished; + BoolInt destFinish = False; + + if (p->block.packSize != (UInt64)(Int64)-1) + { + UInt64 rem = p->block.packSize - p->packSize; + if (srcLen2 >= rem) + { + srcFinished2 = True; + srcLen2 = (SizeT)rem; + } + if (rem == 0 && p->block.unpackSize == p->unpackSize) + return SZ_ERROR_DATA; + } + + if (p->block.unpackSize != (UInt64)(Int64)-1) + { + UInt64 rem = p->block.unpackSize - p->unpackSize; + if (destLen2 >= rem) + { + destFinish = True; + finishMode2 = CODER_FINISH_END; + destLen2 = (SizeT)rem; + } + } + + /* + if (srcLen2 == 0 && destLen2 == 0) + { + *status = CODER_STATUS_NOT_FINISHED; + return SZ_OK; + } + */ + + { + res = MixCoder_Code(&p->decoder, + (p->outBuf ? NULL : dest), &destLen2, destFinish, + src, &srcLen2, srcFinished2, + finishMode2); + + *status = p->decoder.status; + XzCheck_Update(&p->check, (p->outBuf ? p->outBuf + p->outDataWritten : dest), destLen2); + if (!p->outBuf) + dest += destLen2; + p->outDataWritten += destLen2; + } + + (*srcLen) += srcLen2; + src += srcLen2; + p->packSize += srcLen2; + (*destLen) += destLen2; + p->unpackSize += destLen2; + + RINOK(res) + + if (*status != CODER_STATUS_FINISHED_WITH_MARK) + { + if (p->block.packSize == p->packSize + && *status == CODER_STATUS_NEEDS_MORE_INPUT) + { + PRF_STR("CODER_STATUS_NEEDS_MORE_INPUT") + *status = CODER_STATUS_NOT_SPECIFIED; + return SZ_ERROR_DATA; + } + + return SZ_OK; + } + { + XzUnpacker_UpdateIndex(p, XzUnpacker_GetPackSizeForIndex(p), p->unpackSize); + p->state = XZ_STATE_BLOCK_FOOTER; + p->pos = 0; + p->alignPos = 0; + *status = CODER_STATUS_NOT_SPECIFIED; + + if ((p->block.packSize != (UInt64)(Int64)-1 && p->block.packSize != p->packSize) + || (p->block.unpackSize != (UInt64)(Int64)-1 && p->block.unpackSize != p->unpackSize)) + { + PRF_STR("ERROR: block.size mismatch") + return SZ_ERROR_DATA; + } + } + // continue; + } + + srcRem = srcLenOrig - *srcLen; + + // XZ_STATE_BLOCK_FOOTER can transit to XZ_STATE_BLOCK_HEADER without input bytes + if (srcRem == 0 && p->state != XZ_STATE_BLOCK_FOOTER) + { + *status = CODER_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + switch (p->state) + { + case XZ_STATE_STREAM_HEADER: + { + if (p->pos < XZ_STREAM_HEADER_SIZE) + { + if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos]) + return SZ_ERROR_NO_ARCHIVE; + if (p->decodeToStreamSignature) + return SZ_OK; + p->buf[p->pos++] = *src++; + (*srcLen)++; + } + else + { + RINOK(Xz_ParseHeader(&p->streamFlags, p->buf)) + p->numStartedStreams++; + p->indexSize = 0; + p->numBlocks = 0; + Sha256_Init(&p->sha); + p->state = XZ_STATE_BLOCK_HEADER; + p->pos = 0; + } + break; + } + + case XZ_STATE_BLOCK_HEADER: + { + if (p->pos == 0) + { + p->buf[p->pos++] = *src++; + (*srcLen)++; + if (p->buf[0] == 0) + { + if (p->decodeOnlyOneBlock) + return SZ_ERROR_DATA; + p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks); + p->indexPos = p->indexPreSize; + p->indexSize += p->indexPreSize; + Sha256_Final(&p->sha, p->shaDigest); + Sha256_Init(&p->sha); + p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize); + p->state = XZ_STATE_STREAM_INDEX; + break; + } + p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4; + break; + } + + if (p->pos != p->blockHeaderSize) + { + UInt32 cur = p->blockHeaderSize - p->pos; + if (cur > srcRem) + cur = (UInt32)srcRem; + memcpy(p->buf + p->pos, src, cur); + p->pos += cur; + (*srcLen) += cur; + src += cur; + } + else + { + RINOK(XzBlock_Parse(&p->block, p->buf)) + if (!XzBlock_AreSupportedFilters(&p->block)) + return SZ_ERROR_UNSUPPORTED; + p->numTotalBlocks++; + p->state = XZ_STATE_BLOCK; + p->packSize = 0; + p->unpackSize = 0; + XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags)); + if (p->parseMode) + { + p->headerParsedOk = True; + return SZ_OK; + } + RINOK(XzDecMix_Init(&p->decoder, &p->block, p->outBuf, p->outBufSize)) + } + break; + } + + case XZ_STATE_BLOCK_FOOTER: + { + if ((((unsigned)p->packSize + p->alignPos) & 3) != 0) + { + if (srcRem == 0) + { + *status = CODER_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + (*srcLen)++; + p->alignPos++; + if (*src++ != 0) + return SZ_ERROR_CRC; + } + else + { + UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags); + UInt32 cur = checkSize - p->pos; + if (cur != 0) + { + if (srcRem == 0) + { + *status = CODER_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (cur > srcRem) + cur = (UInt32)srcRem; + memcpy(p->buf + p->pos, src, cur); + p->pos += cur; + (*srcLen) += cur; + src += cur; + if (checkSize != p->pos) + break; + } + { + Byte digest[XZ_CHECK_SIZE_MAX]; + p->state = XZ_STATE_BLOCK_HEADER; + p->pos = 0; + if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0) + return SZ_ERROR_CRC; + if (p->decodeOnlyOneBlock) + { + *status = CODER_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + } + } + } + break; + } + + case XZ_STATE_STREAM_INDEX: + { + if (p->pos < p->indexPreSize) + { + (*srcLen)++; + if (*src++ != p->buf[p->pos++]) + return SZ_ERROR_CRC; + } + else + { + if (p->indexPos < p->indexSize) + { + UInt64 cur = p->indexSize - p->indexPos; + if (srcRem > cur) + srcRem = (SizeT)cur; + p->crc = CrcUpdate(p->crc, src, srcRem); + Sha256_Update(&p->sha, src, srcRem); + (*srcLen) += srcRem; + src += srcRem; + p->indexPos += srcRem; + } + else if ((p->indexPos & 3) != 0) + { + Byte b = *src++; + p->crc = CRC_UPDATE_BYTE(p->crc, b); + (*srcLen)++; + p->indexPos++; + p->indexSize++; + if (b != 0) + return SZ_ERROR_CRC; + } + else + { + Byte digest[SHA256_DIGEST_SIZE]; + p->state = XZ_STATE_STREAM_INDEX_CRC; + p->indexSize += 4; + p->pos = 0; + Sha256_Final(&p->sha, digest); + if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0) + return SZ_ERROR_CRC; + } + } + break; + } + + case XZ_STATE_STREAM_INDEX_CRC: + { + if (p->pos < 4) + { + (*srcLen)++; + p->buf[p->pos++] = *src++; + } + else + { + const Byte *ptr = p->buf; + p->state = XZ_STATE_STREAM_FOOTER; + p->pos = 0; + if (CRC_GET_DIGEST(p->crc) != GetUi32(ptr)) + return SZ_ERROR_CRC; + } + break; + } + + case XZ_STATE_STREAM_FOOTER: + { + UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos; + if (cur > srcRem) + cur = (UInt32)srcRem; + memcpy(p->buf + p->pos, src, cur); + p->pos += cur; + (*srcLen) += cur; + src += cur; + if (p->pos == XZ_STREAM_FOOTER_SIZE) + { + p->state = XZ_STATE_STREAM_PADDING; + p->numFinishedStreams++; + p->padSize = 0; + if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf)) + return SZ_ERROR_CRC; + } + break; + } + + case XZ_STATE_STREAM_PADDING: + { + if (*src != 0) + { + if (((UInt32)p->padSize & 3) != 0) + return SZ_ERROR_NO_ARCHIVE; + p->pos = 0; + p->state = XZ_STATE_STREAM_HEADER; + } + else + { + (*srcLen)++; + src++; + p->padSize++; + } + break; + } + + case XZ_STATE_BLOCK: break; /* to disable GCC warning */ + } + } + /* + if (p->state == XZ_STATE_FINISHED) + *status = CODER_STATUS_FINISHED_WITH_MARK; + return SZ_OK; + */ +} + + +SRes XzUnpacker_CodeFull(CXzUnpacker *p, Byte *dest, SizeT *destLen, + const Byte *src, SizeT *srcLen, + ECoderFinishMode finishMode, ECoderStatus *status) +{ + XzUnpacker_Init(p); + XzUnpacker_SetOutBuf(p, dest, *destLen); + + return XzUnpacker_Code(p, + NULL, destLen, + src, srcLen, True, + finishMode, status); +} + + +BoolInt XzUnpacker_IsBlockFinished(const CXzUnpacker *p) +{ + return (p->state == XZ_STATE_BLOCK_HEADER) && (p->pos == 0); +} + +BoolInt XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p) +{ + return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0); +} + +UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p) +{ + UInt64 num = 0; + if (p->state == XZ_STATE_STREAM_PADDING) + num = p->padSize; + else if (p->state == XZ_STATE_STREAM_HEADER) + num = p->padSize + p->pos; + return num; +} + + + + + + + + + + + + + + + + + + + + + +#ifndef Z7_ST +#include "MtDec.h" +#endif + + +void XzDecMtProps_Init(CXzDecMtProps *p) +{ + p->inBufSize_ST = 1 << 18; + p->outStep_ST = 1 << 20; + p->ignoreErrors = False; + + #ifndef Z7_ST + p->numThreads = 1; + p->inBufSize_MT = 1 << 18; + p->memUseMax = sizeof(size_t) << 28; + #endif +} + + + +#ifndef Z7_ST + +/* ---------- CXzDecMtThread ---------- */ + +typedef struct +{ + Byte *outBuf; + size_t outBufSize; + size_t outPreSize; + size_t inPreSize; + size_t inPreHeaderSize; + size_t blockPackSize_for_Index; // including block header and checksum. + size_t blockPackTotal; // including stream header, block header and checksum. + size_t inCodeSize; + size_t outCodeSize; + ECoderStatus status; + SRes codeRes; + BoolInt skipMode; + // BoolInt finishedWithMark; + EMtDecParseState parseState; + BoolInt parsing_Truncated; + BoolInt atBlockHeader; + CXzStreamFlags streamFlags; + // UInt64 numFinishedStreams + UInt64 numStreams; + UInt64 numTotalBlocks; + UInt64 numBlocks; + + BoolInt dec_created; + CXzUnpacker dec; + + Byte mtPad[1 << 7]; +} CXzDecMtThread; + +#endif + + +/* ---------- CXzDecMt ---------- */ + +struct CXzDecMt +{ + CAlignOffsetAlloc alignOffsetAlloc; + ISzAllocPtr allocMid; + + CXzDecMtProps props; + size_t unpackBlockMaxSize; + + ISeqInStreamPtr inStream; + ISeqOutStreamPtr outStream; + ICompressProgressPtr progress; + + BoolInt finishMode; + BoolInt outSize_Defined; + UInt64 outSize; + + UInt64 outProcessed; + UInt64 inProcessed; + UInt64 readProcessed; + BoolInt readWasFinished; + SRes readRes; + SRes writeRes; + + Byte *outBuf; + size_t outBufSize; + Byte *inBuf; + size_t inBufSize; + + CXzUnpacker dec; + + ECoderStatus status; + SRes codeRes; + + #ifndef Z7_ST + BoolInt mainDecoderWasCalled; + // int statErrorDefined; + int finishedDecoderIndex; + + // global values that are used in Parse stage + CXzStreamFlags streamFlags; + // UInt64 numFinishedStreams + UInt64 numStreams; + UInt64 numTotalBlocks; + UInt64 numBlocks; + + // UInt64 numBadBlocks; + SRes mainErrorCode; // it's set to error code, if the size Code() output doesn't patch the size from Parsing stage + // it can be = SZ_ERROR_INPUT_EOF + // it can be = SZ_ERROR_DATA, in some another cases + BoolInt isBlockHeaderState_Parse; + BoolInt isBlockHeaderState_Write; + UInt64 outProcessed_Parse; + BoolInt parsing_Truncated; + + BoolInt mtc_WasConstructed; + CMtDec mtc; + CXzDecMtThread coders[MTDEC_THREADS_MAX]; + #endif +}; + + + +CXzDecMtHandle XzDecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid) +{ + CXzDecMt *p = (CXzDecMt *)ISzAlloc_Alloc(alloc, sizeof(CXzDecMt)); + if (!p) + return NULL; + + AlignOffsetAlloc_CreateVTable(&p->alignOffsetAlloc); + p->alignOffsetAlloc.baseAlloc = alloc; + p->alignOffsetAlloc.numAlignBits = 7; + p->alignOffsetAlloc.offset = 0; + + p->allocMid = allocMid; + + p->outBuf = NULL; + p->outBufSize = 0; + p->inBuf = NULL; + p->inBufSize = 0; + + XzUnpacker_Construct(&p->dec, &p->alignOffsetAlloc.vt); + + p->unpackBlockMaxSize = 0; + + XzDecMtProps_Init(&p->props); + + #ifndef Z7_ST + p->mtc_WasConstructed = False; + { + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CXzDecMtThread *coder = &p->coders[i]; + coder->dec_created = False; + coder->outBuf = NULL; + coder->outBufSize = 0; + } + } + #endif + + return (CXzDecMtHandle)p; +} + + +#ifndef Z7_ST + +static void XzDecMt_FreeOutBufs(CXzDecMt *p) +{ + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CXzDecMtThread *coder = &p->coders[i]; + if (coder->outBuf) + { + ISzAlloc_Free(p->allocMid, coder->outBuf); + coder->outBuf = NULL; + coder->outBufSize = 0; + } + } + p->unpackBlockMaxSize = 0; +} + +#endif + + + +static void XzDecMt_FreeSt(CXzDecMt *p) +{ + XzUnpacker_Free(&p->dec); + + if (p->outBuf) + { + ISzAlloc_Free(p->allocMid, p->outBuf); + p->outBuf = NULL; + } + p->outBufSize = 0; + + if (p->inBuf) + { + ISzAlloc_Free(p->allocMid, p->inBuf); + p->inBuf = NULL; + } + p->inBufSize = 0; +} + + +// #define GET_CXzDecMt_p CXzDecMt *p = pp; + +void XzDecMt_Destroy(CXzDecMtHandle p) +{ + // GET_CXzDecMt_p + + XzDecMt_FreeSt(p); + + #ifndef Z7_ST + + if (p->mtc_WasConstructed) + { + MtDec_Destruct(&p->mtc); + p->mtc_WasConstructed = False; + } + { + unsigned i; + for (i = 0; i < MTDEC_THREADS_MAX; i++) + { + CXzDecMtThread *t = &p->coders[i]; + if (t->dec_created) + { + // we don't need to free dict here + XzUnpacker_Free(&t->dec); + t->dec_created = False; + } + } + } + XzDecMt_FreeOutBufs(p); + + #endif + + ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, p); +} + + + +#ifndef Z7_ST + +static void XzDecMt_Callback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc) +{ + CXzDecMt *me = (CXzDecMt *)obj; + CXzDecMtThread *coder = &me->coders[coderIndex]; + size_t srcSize = cc->srcSize; + + cc->srcSize = 0; + cc->outPos = 0; + cc->state = MTDEC_PARSE_CONTINUE; + + cc->canCreateNewThread = True; + + if (cc->startCall) + { + coder->outPreSize = 0; + coder->inPreSize = 0; + coder->inPreHeaderSize = 0; + coder->parseState = MTDEC_PARSE_CONTINUE; + coder->parsing_Truncated = False; + coder->skipMode = False; + coder->codeRes = SZ_OK; + coder->status = CODER_STATUS_NOT_SPECIFIED; + coder->inCodeSize = 0; + coder->outCodeSize = 0; + + coder->numStreams = me->numStreams; + coder->numTotalBlocks = me->numTotalBlocks; + coder->numBlocks = me->numBlocks; + + if (!coder->dec_created) + { + XzUnpacker_Construct(&coder->dec, &me->alignOffsetAlloc.vt); + coder->dec_created = True; + } + + XzUnpacker_Init(&coder->dec); + + if (me->isBlockHeaderState_Parse) + { + coder->dec.streamFlags = me->streamFlags; + coder->atBlockHeader = True; + XzUnpacker_PrepareToRandomBlockDecoding(&coder->dec); + } + else + { + coder->atBlockHeader = False; + me->isBlockHeaderState_Parse = True; + } + + coder->dec.numStartedStreams = me->numStreams; + coder->dec.numTotalBlocks = me->numTotalBlocks; + coder->dec.numBlocks = me->numBlocks; + } + + while (!coder->skipMode) + { + ECoderStatus status; + SRes res; + size_t srcSize2 = srcSize; + size_t destSize = (size_t)0 - 1; + + coder->dec.parseMode = True; + coder->dec.headerParsedOk = False; + + PRF_STR_INT("Parse", srcSize2) + + res = XzUnpacker_Code(&coder->dec, + NULL, &destSize, + cc->src, &srcSize2, cc->srcFinished, + CODER_FINISH_END, &status); + + // PRF(printf(" res = %d, srcSize2 = %d", res, (unsigned)srcSize2)); + + coder->codeRes = res; + coder->status = status; + cc->srcSize += srcSize2; + srcSize -= srcSize2; + coder->inPreHeaderSize += srcSize2; + coder->inPreSize = coder->inPreHeaderSize; + + if (res != SZ_OK) + { + cc->state = + coder->parseState = MTDEC_PARSE_END; + /* + if (res == SZ_ERROR_MEM) + return res; + return SZ_OK; + */ + return; // res; + } + + if (coder->dec.headerParsedOk) + { + const CXzBlock *block = &coder->dec.block; + if (XzBlock_HasUnpackSize(block) + // && block->unpackSize <= me->props.outBlockMax + && XzBlock_HasPackSize(block)) + { + { + if (block->unpackSize * 2 * me->mtc.numStartedThreads > me->props.memUseMax) + { + cc->state = MTDEC_PARSE_OVERFLOW; + return; // SZ_OK; + } + } + { + UInt64 packSize = block->packSize; + UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3); + UInt32 checkSize = XzFlags_GetCheckSize(coder->dec.streamFlags); + UInt64 blockPackSum = coder->inPreSize + packSizeAligned + checkSize; + // if (blockPackSum <= me->props.inBlockMax) + // unpackBlockMaxSize + { + coder->blockPackSize_for_Index = (size_t)(coder->dec.blockHeaderSize + packSize + checkSize); + coder->blockPackTotal = (size_t)blockPackSum; + coder->outPreSize = (size_t)block->unpackSize; + coder->streamFlags = coder->dec.streamFlags; + me->streamFlags = coder->dec.streamFlags; + coder->skipMode = True; + break; + } + } + } + } + else + // if (coder->inPreSize <= me->props.inBlockMax) + { + if (!cc->srcFinished) + return; // SZ_OK; + cc->state = + coder->parseState = MTDEC_PARSE_END; + return; // SZ_OK; + } + cc->state = MTDEC_PARSE_OVERFLOW; + return; // SZ_OK; + } + + // ---------- skipMode ---------- + { + UInt64 rem = coder->blockPackTotal - coder->inPreSize; + size_t cur = srcSize; + if (cur > rem) + cur = (size_t)rem; + cc->srcSize += cur; + coder->inPreSize += cur; + srcSize -= cur; + + if (coder->inPreSize == coder->blockPackTotal) + { + if (srcSize == 0) + { + if (!cc->srcFinished) + return; // SZ_OK; + cc->state = MTDEC_PARSE_END; + } + else if ((cc->src)[cc->srcSize] == 0) // we check control byte of next block + cc->state = MTDEC_PARSE_END; + else + { + cc->state = MTDEC_PARSE_NEW; + + { + size_t blockMax = me->unpackBlockMaxSize; + if (blockMax < coder->outPreSize) + blockMax = coder->outPreSize; + { + UInt64 required = (UInt64)blockMax * (me->mtc.numStartedThreads + 1) * 2; + if (me->props.memUseMax < required) + cc->canCreateNewThread = False; + } + } + + if (me->outSize_Defined) + { + // next block can be zero size + const UInt64 rem2 = me->outSize - me->outProcessed_Parse; + if (rem2 < coder->outPreSize) + { + coder->parsing_Truncated = True; + cc->state = MTDEC_PARSE_END; + } + me->outProcessed_Parse += coder->outPreSize; + } + } + } + else if (cc->srcFinished) + cc->state = MTDEC_PARSE_END; + else + return; // SZ_OK; + + coder->parseState = cc->state; + cc->outPos = coder->outPreSize; + + me->numStreams = coder->dec.numStartedStreams; + me->numTotalBlocks = coder->dec.numTotalBlocks; + me->numBlocks = coder->dec.numBlocks + 1; + return; // SZ_OK; + } +} + + +static SRes XzDecMt_Callback_PreCode(void *pp, unsigned coderIndex) +{ + CXzDecMt *me = (CXzDecMt *)pp; + CXzDecMtThread *coder = &me->coders[coderIndex]; + Byte *dest; + + if (!coder->dec.headerParsedOk) + return SZ_OK; + + dest = coder->outBuf; + + if (!dest || coder->outBufSize < coder->outPreSize) + { + if (dest) + { + ISzAlloc_Free(me->allocMid, dest); + coder->outBuf = NULL; + coder->outBufSize = 0; + } + { + size_t outPreSize = coder->outPreSize; + if (outPreSize == 0) + outPreSize = 1; + dest = (Byte *)ISzAlloc_Alloc(me->allocMid, outPreSize); + } + if (!dest) + return SZ_ERROR_MEM; + coder->outBuf = dest; + coder->outBufSize = coder->outPreSize; + + if (coder->outBufSize > me->unpackBlockMaxSize) + me->unpackBlockMaxSize = coder->outBufSize; + } + + // return SZ_ERROR_MEM; + + XzUnpacker_SetOutBuf(&coder->dec, coder->outBuf, coder->outBufSize); + + { + SRes res = XzDecMix_Init(&coder->dec.decoder, &coder->dec.block, coder->outBuf, coder->outBufSize); + // res = SZ_ERROR_UNSUPPORTED; // to test + coder->codeRes = res; + if (res != SZ_OK) + { + // if (res == SZ_ERROR_MEM) return res; + if (me->props.ignoreErrors && res != SZ_ERROR_MEM) + return SZ_OK; + return res; + } + } + + return SZ_OK; +} + + +static SRes XzDecMt_Callback_Code(void *pp, unsigned coderIndex, + const Byte *src, size_t srcSize, int srcFinished, + // int finished, int blockFinished, + UInt64 *inCodePos, UInt64 *outCodePos, int *stop) +{ + CXzDecMt *me = (CXzDecMt *)pp; + CXzDecMtThread *coder = &me->coders[coderIndex]; + + *inCodePos = coder->inCodeSize; + *outCodePos = coder->outCodeSize; + *stop = True; + + if (srcSize > coder->inPreSize - coder->inCodeSize) + return SZ_ERROR_FAIL; + + if (coder->inCodeSize < coder->inPreHeaderSize) + { + size_t step = coder->inPreHeaderSize - coder->inCodeSize; + if (step > srcSize) + step = srcSize; + src += step; + srcSize -= step; + coder->inCodeSize += step; + *inCodePos = coder->inCodeSize; + if (coder->inCodeSize < coder->inPreHeaderSize) + { + *stop = False; + return SZ_OK; + } + } + + if (!coder->dec.headerParsedOk) + return SZ_OK; + if (!coder->outBuf) + return SZ_OK; + + if (coder->codeRes == SZ_OK) + { + ECoderStatus status; + SRes res; + size_t srcProcessed = srcSize; + size_t outSizeCur = coder->outPreSize - coder->dec.outDataWritten; + + // PRF(printf("\nCallback_Code: Code %d %d\n", (unsigned)srcSize, (unsigned)outSizeCur)); + + res = XzUnpacker_Code(&coder->dec, + NULL, &outSizeCur, + src, &srcProcessed, srcFinished, + // coder->finishedWithMark ? CODER_FINISH_END : CODER_FINISH_ANY, + CODER_FINISH_END, + &status); + + // PRF(printf(" res = %d, srcSize2 = %d, outSizeCur = %d", res, (unsigned)srcProcessed, (unsigned)outSizeCur)); + + coder->codeRes = res; + coder->status = status; + coder->inCodeSize += srcProcessed; + coder->outCodeSize = coder->dec.outDataWritten; + *inCodePos = coder->inCodeSize; + *outCodePos = coder->outCodeSize; + + if (res == SZ_OK) + { + if (srcProcessed == srcSize) + *stop = False; + return SZ_OK; + } + } + + if (me->props.ignoreErrors && coder->codeRes != SZ_ERROR_MEM) + { + *inCodePos = coder->inPreSize; + *outCodePos = coder->outPreSize; + return SZ_OK; + } + return coder->codeRes; +} + + +#define XZDECMT_STREAM_WRITE_STEP (1 << 24) + +static SRes XzDecMt_Callback_Write(void *pp, unsigned coderIndex, + BoolInt needWriteToStream, + const Byte *src, size_t srcSize, BoolInt isCross, + // int srcFinished, + BoolInt *needContinue, + BoolInt *canRecode) +{ + CXzDecMt *me = (CXzDecMt *)pp; + const CXzDecMtThread *coder = &me->coders[coderIndex]; + + // PRF(printf("\nWrite processed = %d srcSize = %d\n", (unsigned)me->mtc.inProcessed, (unsigned)srcSize)); + + *needContinue = False; + *canRecode = True; + + if (!needWriteToStream) + return SZ_OK; + + if (!coder->dec.headerParsedOk || !coder->outBuf) + { + if (me->finishedDecoderIndex < 0) + me->finishedDecoderIndex = (int)coderIndex; + return SZ_OK; + } + + if (me->finishedDecoderIndex >= 0) + return SZ_OK; + + me->mtc.inProcessed += coder->inCodeSize; + + *canRecode = False; + + { + SRes res; + size_t size = coder->outCodeSize; + Byte *data = coder->outBuf; + + // we use in me->dec: sha, numBlocks, indexSize + + if (!me->isBlockHeaderState_Write) + { + XzUnpacker_PrepareToRandomBlockDecoding(&me->dec); + me->dec.decodeOnlyOneBlock = False; + me->dec.numStartedStreams = coder->dec.numStartedStreams; + me->dec.streamFlags = coder->streamFlags; + + me->isBlockHeaderState_Write = True; + } + + me->dec.numTotalBlocks = coder->dec.numTotalBlocks; + XzUnpacker_UpdateIndex(&me->dec, coder->blockPackSize_for_Index, coder->outPreSize); + + if (coder->outPreSize != size) + { + if (me->props.ignoreErrors) + { + memset(data + size, 0, coder->outPreSize - size); + size = coder->outPreSize; + } + // me->numBadBlocks++; + if (me->mainErrorCode == SZ_OK) + { + if ((int)coder->status == LZMA_STATUS_NEEDS_MORE_INPUT) + me->mainErrorCode = SZ_ERROR_INPUT_EOF; + else + me->mainErrorCode = SZ_ERROR_DATA; + } + } + + if (me->writeRes != SZ_OK) + return me->writeRes; + + res = SZ_OK; + { + if (me->outSize_Defined) + { + const UInt64 rem = me->outSize - me->outProcessed; + if (size > rem) + size = (SizeT)rem; + } + + for (;;) + { + size_t cur = size; + size_t written; + if (cur > XZDECMT_STREAM_WRITE_STEP) + cur = XZDECMT_STREAM_WRITE_STEP; + + written = ISeqOutStream_Write(me->outStream, data, cur); + + // PRF(printf("\nWritten ask = %d written = %d\n", (unsigned)cur, (unsigned)written)); + + me->outProcessed += written; + if (written != cur) + { + me->writeRes = SZ_ERROR_WRITE; + res = me->writeRes; + break; + } + data += cur; + size -= cur; + // PRF_STR_INT("Written size =", size) + if (size == 0) + break; + res = MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0); + if (res != SZ_OK) + break; + } + } + + if (coder->codeRes != SZ_OK) + if (!me->props.ignoreErrors) + { + me->finishedDecoderIndex = (int)coderIndex; + return res; + } + + RINOK(res) + + if (coder->inPreSize != coder->inCodeSize + || coder->blockPackTotal != coder->inCodeSize) + { + me->finishedDecoderIndex = (int)coderIndex; + return SZ_OK; + } + + if (coder->parseState != MTDEC_PARSE_END) + { + *needContinue = True; + return SZ_OK; + } + } + + // (coder->state == MTDEC_PARSE_END) means that there are no other working threads + // so we can use mtc variables without lock + + PRF_STR_INT("Write MTDEC_PARSE_END", me->mtc.inProcessed) + + me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; + { + CXzUnpacker *dec = &me->dec; + + PRF_STR_INT("PostSingle", srcSize) + + { + size_t srcProcessed = srcSize; + ECoderStatus status; + size_t outSizeCur = 0; + SRes res; + + // dec->decodeOnlyOneBlock = False; + dec->decodeToStreamSignature = True; + + me->mainDecoderWasCalled = True; + + if (coder->parsing_Truncated) + { + me->parsing_Truncated = True; + return SZ_OK; + } + + /* + We have processed all xz-blocks of stream, + And xz unpacker is at XZ_STATE_BLOCK_HEADER state, where + (src) is a pointer to xz-Index structure. + We finish reading of current xz-Stream, including Zero padding after xz-Stream. + We exit, if we reach extra byte (first byte of new-Stream or another data). + But we don't update input stream pointer for that new extra byte. + If extra byte is not correct first byte of xz-signature, + we have SZ_ERROR_NO_ARCHIVE error here. + */ + + res = XzUnpacker_Code(dec, + NULL, &outSizeCur, + src, &srcProcessed, + me->mtc.readWasFinished, // srcFinished + CODER_FINISH_END, // CODER_FINISH_ANY, + &status); + + // res = SZ_ERROR_ARCHIVE; // for failure test + + me->status = status; + me->codeRes = res; + + if (isCross) + me->mtc.crossStart += srcProcessed; + + me->mtc.inProcessed += srcProcessed; + me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; + + srcSize -= srcProcessed; + src += srcProcessed; + + if (res != SZ_OK) + { + return SZ_OK; + // return res; + } + + if (dec->state == XZ_STATE_STREAM_HEADER) + { + *needContinue = True; + me->isBlockHeaderState_Parse = False; + me->isBlockHeaderState_Write = False; + + if (!isCross) + { + Byte *crossBuf = MtDec_GetCrossBuff(&me->mtc); + if (!crossBuf) + return SZ_ERROR_MEM; + if (srcSize != 0) + memcpy(crossBuf, src, srcSize); + me->mtc.crossStart = 0; + me->mtc.crossEnd = srcSize; + } + + PRF_STR_INT("XZ_STATE_STREAM_HEADER crossEnd = ", (unsigned)me->mtc.crossEnd) + + return SZ_OK; + } + + if (status != CODER_STATUS_NEEDS_MORE_INPUT || srcSize != 0) + { + return SZ_ERROR_FAIL; + } + + if (me->mtc.readWasFinished) + { + return SZ_OK; + } + } + + { + size_t inPos; + size_t inLim; + // const Byte *inData; + UInt64 inProgressPrev = me->mtc.inProcessed; + + // XzDecMt_Prepare_InBuf_ST(p); + Byte *crossBuf = MtDec_GetCrossBuff(&me->mtc); + if (!crossBuf) + return SZ_ERROR_MEM; + + inPos = 0; + inLim = 0; + + // inData = crossBuf; + + for (;;) + { + SizeT inProcessed; + SizeT outProcessed; + ECoderStatus status; + SRes res; + + if (inPos == inLim) + { + if (!me->mtc.readWasFinished) + { + inPos = 0; + inLim = me->mtc.inBufSize; + me->mtc.readRes = ISeqInStream_Read(me->inStream, (void *)crossBuf, &inLim); + me->mtc.readProcessed += inLim; + if (inLim == 0 || me->mtc.readRes != SZ_OK) + me->mtc.readWasFinished = True; + } + } + + inProcessed = inLim - inPos; + outProcessed = 0; + + res = XzUnpacker_Code(dec, + NULL, &outProcessed, + crossBuf + inPos, &inProcessed, + (inProcessed == 0), // srcFinished + CODER_FINISH_END, &status); + + me->codeRes = res; + me->status = status; + inPos += inProcessed; + me->mtc.inProcessed += inProcessed; + me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; + + if (res != SZ_OK) + { + return SZ_OK; + // return res; + } + + if (dec->state == XZ_STATE_STREAM_HEADER) + { + *needContinue = True; + me->mtc.crossStart = inPos; + me->mtc.crossEnd = inLim; + me->isBlockHeaderState_Parse = False; + me->isBlockHeaderState_Write = False; + return SZ_OK; + } + + if (status != CODER_STATUS_NEEDS_MORE_INPUT) + return SZ_ERROR_FAIL; + + if (me->mtc.progress) + { + UInt64 inDelta = me->mtc.inProcessed - inProgressPrev; + if (inDelta >= (1 << 22)) + { + RINOK(MtProgress_Progress_ST(&me->mtc.mtProgress)) + inProgressPrev = me->mtc.inProcessed; + } + } + if (me->mtc.readWasFinished) + return SZ_OK; + } + } + } +} + + +#endif + + + +void XzStatInfo_Clear(CXzStatInfo *p) +{ + p->InSize = 0; + p->OutSize = 0; + + p->NumStreams = 0; + p->NumBlocks = 0; + + p->UnpackSize_Defined = False; + + p->NumStreams_Defined = False; + p->NumBlocks_Defined = False; + + p->DataAfterEnd = False; + p->DecodingTruncated = False; + + p->DecodeRes = SZ_OK; + p->ReadRes = SZ_OK; + p->ProgressRes = SZ_OK; + + p->CombinedRes = SZ_OK; + p->CombinedRes_Type = SZ_OK; +} + + + +/* + XzDecMt_Decode_ST() can return SZ_OK or the following errors + - SZ_ERROR_MEM for memory allocation error + - error from XzUnpacker_Code() function + - SZ_ERROR_WRITE for ISeqOutStream::Write(). stat->CombinedRes_Type = SZ_ERROR_WRITE in that case + - ICompressProgress::Progress() error, stat->CombinedRes_Type = SZ_ERROR_PROGRESS. + But XzDecMt_Decode_ST() doesn't return ISeqInStream::Read() errors. + ISeqInStream::Read() result is set to p->readRes. + also it can set stat->CombinedRes_Type to SZ_ERROR_WRITE or SZ_ERROR_PROGRESS. +*/ + +static SRes XzDecMt_Decode_ST(CXzDecMt *p + #ifndef Z7_ST + , BoolInt tMode + #endif + , CXzStatInfo *stat) +{ + size_t outPos; + size_t inPos, inLim; + const Byte *inData; + UInt64 inPrev, outPrev; + + CXzUnpacker *dec; + + #ifndef Z7_ST + if (tMode) + { + XzDecMt_FreeOutBufs(p); + tMode = MtDec_PrepareRead(&p->mtc); + } + #endif + + if (!p->outBuf || p->outBufSize != p->props.outStep_ST) + { + ISzAlloc_Free(p->allocMid, p->outBuf); + p->outBufSize = 0; + p->outBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.outStep_ST); + if (!p->outBuf) + return SZ_ERROR_MEM; + p->outBufSize = p->props.outStep_ST; + } + + if (!p->inBuf || p->inBufSize != p->props.inBufSize_ST) + { + ISzAlloc_Free(p->allocMid, p->inBuf); + p->inBufSize = 0; + p->inBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.inBufSize_ST); + if (!p->inBuf) + return SZ_ERROR_MEM; + p->inBufSize = p->props.inBufSize_ST; + } + + dec = &p->dec; + dec->decodeToStreamSignature = False; + // dec->decodeOnlyOneBlock = False; + + XzUnpacker_SetOutBuf(dec, NULL, 0); + + inPrev = p->inProcessed; + outPrev = p->outProcessed; + + inPos = 0; + inLim = 0; + inData = NULL; + outPos = 0; + + for (;;) + { + SizeT outSize; + BoolInt finished; + ECoderFinishMode finishMode; + SizeT inProcessed; + ECoderStatus status; + SRes res; + + SizeT outProcessed; + + + + if (inPos == inLim) + { + #ifndef Z7_ST + if (tMode) + { + inData = MtDec_Read(&p->mtc, &inLim); + inPos = 0; + if (inData) + continue; + tMode = False; + inLim = 0; + } + #endif + + if (!p->readWasFinished) + { + inPos = 0; + inLim = p->inBufSize; + inData = p->inBuf; + p->readRes = ISeqInStream_Read(p->inStream, (void *)p->inBuf, &inLim); + p->readProcessed += inLim; + if (inLim == 0 || p->readRes != SZ_OK) + p->readWasFinished = True; + } + } + + outSize = p->props.outStep_ST - outPos; + + finishMode = CODER_FINISH_ANY; + if (p->outSize_Defined) + { + const UInt64 rem = p->outSize - p->outProcessed; + if (outSize >= rem) + { + outSize = (SizeT)rem; + if (p->finishMode) + finishMode = CODER_FINISH_END; + } + } + + inProcessed = inLim - inPos; + outProcessed = outSize; + + res = XzUnpacker_Code(dec, p->outBuf + outPos, &outProcessed, + inData + inPos, &inProcessed, + (inPos == inLim), // srcFinished + finishMode, &status); + + p->codeRes = res; + p->status = status; + + inPos += inProcessed; + outPos += outProcessed; + p->inProcessed += inProcessed; + p->outProcessed += outProcessed; + + finished = ((inProcessed == 0 && outProcessed == 0) || res != SZ_OK); + + if (finished || outProcessed >= outSize) + if (outPos != 0) + { + const size_t written = ISeqOutStream_Write(p->outStream, p->outBuf, outPos); + // p->outProcessed += written; // 21.01: BUG fixed + if (written != outPos) + { + stat->CombinedRes_Type = SZ_ERROR_WRITE; + return SZ_ERROR_WRITE; + } + outPos = 0; + } + + if (p->progress && res == SZ_OK) + { + if (p->inProcessed - inPrev >= (1 << 22) || + p->outProcessed - outPrev >= (1 << 22)) + { + res = ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed); + if (res != SZ_OK) + { + stat->CombinedRes_Type = SZ_ERROR_PROGRESS; + stat->ProgressRes = res; + return res; + } + inPrev = p->inProcessed; + outPrev = p->outProcessed; + } + } + + if (finished) + { + // p->codeRes is preliminary error from XzUnpacker_Code. + // and it can be corrected later as final result + // so we return SZ_OK here instead of (res); + return SZ_OK; + // return res; + } + } +} + + + +/* +XzStatInfo_SetStat() transforms + CXzUnpacker return code and status to combined CXzStatInfo results. + it can convert SZ_OK to SZ_ERROR_INPUT_EOF + it can convert SZ_ERROR_NO_ARCHIVE to SZ_OK and (DataAfterEnd = 1) +*/ + +static void XzStatInfo_SetStat(const CXzUnpacker *dec, + int finishMode, + // UInt64 readProcessed, + UInt64 inProcessed, + SRes res, // it's result from CXzUnpacker unpacker + ECoderStatus status, + BoolInt decodingTruncated, + CXzStatInfo *stat) +{ + UInt64 extraSize; + + stat->DecodingTruncated = (Byte)(decodingTruncated ? 1 : 0); + stat->InSize = inProcessed; + stat->NumStreams = dec->numStartedStreams; + stat->NumBlocks = dec->numTotalBlocks; + + stat->UnpackSize_Defined = True; + stat->NumStreams_Defined = True; + stat->NumBlocks_Defined = True; + + extraSize = XzUnpacker_GetExtraSize(dec); + + if (res == SZ_OK) + { + if (status == CODER_STATUS_NEEDS_MORE_INPUT) + { + // CODER_STATUS_NEEDS_MORE_INPUT is expected status for correct xz streams + // any extra data is part of correct data + extraSize = 0; + // if xz stream was not finished, then we need more data + if (!XzUnpacker_IsStreamWasFinished(dec)) + res = SZ_ERROR_INPUT_EOF; + } + else + { + // CODER_STATUS_FINISHED_WITH_MARK is not possible for multi stream xz decoding + // so he we have (status == CODER_STATUS_NOT_FINISHED) + // if (status != CODER_STATUS_FINISHED_WITH_MARK) + if (!decodingTruncated || finishMode) + res = SZ_ERROR_DATA; + } + } + else if (res == SZ_ERROR_NO_ARCHIVE) + { + /* + SZ_ERROR_NO_ARCHIVE is possible for 2 states: + XZ_STATE_STREAM_HEADER - if bad signature or bad CRC + XZ_STATE_STREAM_PADDING - if non-zero padding data + extraSize and inProcessed don't include "bad" byte + */ + // if (inProcessed == extraSize), there was no any good xz stream header, and we keep error + if (inProcessed != extraSize) // if there were good xz streams before error + { + // if (extraSize != 0 || readProcessed != inProcessed) + { + // he we suppose that all xz streams were finsihed OK, and we have + // some extra data after all streams + stat->DataAfterEnd = True; + res = SZ_OK; + } + } + } + + if (stat->DecodeRes == SZ_OK) + stat->DecodeRes = res; + + stat->InSize -= extraSize; +} + + + +SRes XzDecMt_Decode(CXzDecMtHandle p, + const CXzDecMtProps *props, + const UInt64 *outDataSize, int finishMode, + ISeqOutStreamPtr outStream, + // Byte *outBuf, size_t *outBufSize, + ISeqInStreamPtr inStream, + // const Byte *inData, size_t inDataSize, + CXzStatInfo *stat, + int *isMT, + ICompressProgressPtr progress) +{ + // GET_CXzDecMt_p + #ifndef Z7_ST + BoolInt tMode; + #endif + + XzStatInfo_Clear(stat); + + p->props = *props; + + p->inStream = inStream; + p->outStream = outStream; + p->progress = progress; + // p->stat = stat; + + p->outSize = 0; + p->outSize_Defined = False; + if (outDataSize) + { + p->outSize_Defined = True; + p->outSize = *outDataSize; + } + + p->finishMode = finishMode; + + // p->outSize = 457; p->outSize_Defined = True; p->finishMode = False; // for test + + p->writeRes = SZ_OK; + p->outProcessed = 0; + p->inProcessed = 0; + p->readProcessed = 0; + p->readWasFinished = False; + p->readRes = SZ_OK; + + p->codeRes = SZ_OK; + p->status = CODER_STATUS_NOT_SPECIFIED; + + XzUnpacker_Init(&p->dec); + + *isMT = False; + + /* + p->outBuf = NULL; + p->outBufSize = 0; + if (!outStream) + { + p->outBuf = outBuf; + p->outBufSize = *outBufSize; + *outBufSize = 0; + } + */ + + + #ifndef Z7_ST + + p->isBlockHeaderState_Parse = False; + p->isBlockHeaderState_Write = False; + // p->numBadBlocks = 0; + p->mainErrorCode = SZ_OK; + p->mainDecoderWasCalled = False; + + tMode = False; + + if (p->props.numThreads > 1) + { + IMtDecCallback2 vt; + BoolInt needContinue; + SRes res; + // we just free ST buffers here + // but we still keep state variables, that was set in XzUnpacker_Init() + XzDecMt_FreeSt(p); + + p->outProcessed_Parse = 0; + p->parsing_Truncated = False; + + p->numStreams = 0; + p->numTotalBlocks = 0; + p->numBlocks = 0; + p->finishedDecoderIndex = -1; + + if (!p->mtc_WasConstructed) + { + p->mtc_WasConstructed = True; + MtDec_Construct(&p->mtc); + } + + p->mtc.mtCallback = &vt; + p->mtc.mtCallbackObject = p; + + p->mtc.progress = progress; + p->mtc.inStream = inStream; + p->mtc.alloc = &p->alignOffsetAlloc.vt; + // p->mtc.inData = inData; + // p->mtc.inDataSize = inDataSize; + p->mtc.inBufSize = p->props.inBufSize_MT; + // p->mtc.inBlockMax = p->props.inBlockMax; + p->mtc.numThreadsMax = p->props.numThreads; + + *isMT = True; + + vt.Parse = XzDecMt_Callback_Parse; + vt.PreCode = XzDecMt_Callback_PreCode; + vt.Code = XzDecMt_Callback_Code; + vt.Write = XzDecMt_Callback_Write; + + + res = MtDec_Code(&p->mtc); + + + stat->InSize = p->mtc.inProcessed; + + p->inProcessed = p->mtc.inProcessed; + p->readRes = p->mtc.readRes; + p->readWasFinished = p->mtc.readWasFinished; + p->readProcessed = p->mtc.readProcessed; + + tMode = True; + needContinue = False; + + if (res == SZ_OK) + { + if (p->mtc.mtProgress.res != SZ_OK) + { + res = p->mtc.mtProgress.res; + stat->ProgressRes = res; + stat->CombinedRes_Type = SZ_ERROR_PROGRESS; + } + else + needContinue = p->mtc.needContinue; + } + + if (!needContinue) + { + { + SRes codeRes; + BoolInt truncated = False; + ECoderStatus status; + const CXzUnpacker *dec; + + stat->OutSize = p->outProcessed; + + if (p->finishedDecoderIndex >= 0) + { + const CXzDecMtThread *coder = &p->coders[(unsigned)p->finishedDecoderIndex]; + codeRes = coder->codeRes; + dec = &coder->dec; + status = coder->status; + } + else if (p->mainDecoderWasCalled) + { + codeRes = p->codeRes; + dec = &p->dec; + status = p->status; + truncated = p->parsing_Truncated; + } + else + return SZ_ERROR_FAIL; + + if (p->mainErrorCode != SZ_OK) + stat->DecodeRes = p->mainErrorCode; + + XzStatInfo_SetStat(dec, p->finishMode, + // p->mtc.readProcessed, + p->mtc.inProcessed, + codeRes, status, + truncated, + stat); + } + + if (res == SZ_OK) + { + stat->ReadRes = p->mtc.readRes; + + if (p->writeRes != SZ_OK) + { + res = p->writeRes; + stat->CombinedRes_Type = SZ_ERROR_WRITE; + } + else if (p->mtc.readRes != SZ_OK + // && p->mtc.inProcessed == p->mtc.readProcessed + && stat->DecodeRes == SZ_ERROR_INPUT_EOF) + { + res = p->mtc.readRes; + stat->CombinedRes_Type = SZ_ERROR_READ; + } + else if (stat->DecodeRes != SZ_OK) + res = stat->DecodeRes; + } + + stat->CombinedRes = res; + if (stat->CombinedRes_Type == SZ_OK) + stat->CombinedRes_Type = res; + return res; + } + + PRF_STR("----- decoding ST -----") + } + + #endif + + + *isMT = False; + + { + SRes res = XzDecMt_Decode_ST(p + #ifndef Z7_ST + , tMode + #endif + , stat + ); + + #ifndef Z7_ST + // we must set error code from MT decoding at first + if (p->mainErrorCode != SZ_OK) + stat->DecodeRes = p->mainErrorCode; + #endif + + XzStatInfo_SetStat(&p->dec, + p->finishMode, + // p->readProcessed, + p->inProcessed, + p->codeRes, p->status, + False, // truncated + stat); + + stat->ReadRes = p->readRes; + + if (res == SZ_OK) + { + if (p->readRes != SZ_OK + // && p->inProcessed == p->readProcessed + && stat->DecodeRes == SZ_ERROR_INPUT_EOF) + { + // we set read error as combined error, only if that error was the reason + // of decoding problem + res = p->readRes; + stat->CombinedRes_Type = SZ_ERROR_READ; + } + else if (stat->DecodeRes != SZ_OK) + res = stat->DecodeRes; + } + + stat->CombinedRes = res; + if (stat->CombinedRes_Type == SZ_OK) + stat->CombinedRes_Type = res; + return res; + } +} + +#undef PRF +#undef PRF_STR +#undef PRF_STR_INT_2 diff --git a/libraries/lzma/C/XzEnc.c b/libraries/lzma/C/XzEnc.c new file mode 100644 index 000000000..22408e261 --- /dev/null +++ b/libraries/lzma/C/XzEnc.c @@ -0,0 +1,1362 @@ +/* XzEnc.c -- Xz Encode +2023-04-13 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include +#include + +#include "7zCrc.h" +#include "Bra.h" +#include "CpuArch.h" + +#ifdef USE_SUBBLOCK +#include "Bcj3Enc.c" +#include "SbFind.c" +#include "SbEnc.c" +#endif + +#include "XzEnc.h" + +// #define Z7_ST + +#ifndef Z7_ST +#include "MtCoder.h" +#else +#define MTCODER_THREADS_MAX 1 +#define MTCODER_BLOCKS_MAX 1 +#endif + +#define XZ_GET_PAD_SIZE(dataSize) ((4 - ((unsigned)(dataSize) & 3)) & 3) + +/* max pack size for LZMA2 block + check-64bytrs: */ +#define XZ_GET_MAX_BLOCK_PACK_SIZE(unpackSize) ((unpackSize) + ((unpackSize) >> 10) + 16 + 64) + +#define XZ_GET_ESTIMATED_BLOCK_TOTAL_PACK_SIZE(unpackSize) (XZ_BLOCK_HEADER_SIZE_MAX + XZ_GET_MAX_BLOCK_PACK_SIZE(unpackSize)) + + +// #define XzBlock_ClearFlags(p) (p)->flags = 0; +#define XzBlock_ClearFlags_SetNumFilters(p, n) (p)->flags = (Byte)((n) - 1); +#define XzBlock_SetHasPackSize(p) (p)->flags |= XZ_BF_PACK_SIZE; +#define XzBlock_SetHasUnpackSize(p) (p)->flags |= XZ_BF_UNPACK_SIZE; + + +static SRes WriteBytes(ISeqOutStreamPtr s, const void *buf, size_t size) +{ + return (ISeqOutStream_Write(s, buf, size) == size) ? SZ_OK : SZ_ERROR_WRITE; +} + +static SRes WriteBytes_UpdateCrc(ISeqOutStreamPtr s, const void *buf, size_t size, UInt32 *crc) +{ + *crc = CrcUpdate(*crc, buf, size); + return WriteBytes(s, buf, size); +} + + +static SRes Xz_WriteHeader(CXzStreamFlags f, ISeqOutStreamPtr s) +{ + UInt32 crc; + Byte header[XZ_STREAM_HEADER_SIZE]; + memcpy(header, XZ_SIG, XZ_SIG_SIZE); + header[XZ_SIG_SIZE] = (Byte)(f >> 8); + header[XZ_SIG_SIZE + 1] = (Byte)(f & 0xFF); + crc = CrcCalc(header + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE); + SetUi32(header + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE, crc) + return WriteBytes(s, header, XZ_STREAM_HEADER_SIZE); +} + + +static SRes XzBlock_WriteHeader(const CXzBlock *p, ISeqOutStreamPtr s) +{ + Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; + + unsigned pos = 1; + unsigned numFilters, i; + header[pos++] = p->flags; + + if (XzBlock_HasPackSize(p)) pos += Xz_WriteVarInt(header + pos, p->packSize); + if (XzBlock_HasUnpackSize(p)) pos += Xz_WriteVarInt(header + pos, p->unpackSize); + numFilters = XzBlock_GetNumFilters(p); + + for (i = 0; i < numFilters; i++) + { + const CXzFilter *f = &p->filters[i]; + pos += Xz_WriteVarInt(header + pos, f->id); + pos += Xz_WriteVarInt(header + pos, f->propsSize); + memcpy(header + pos, f->props, f->propsSize); + pos += f->propsSize; + } + + while ((pos & 3) != 0) + header[pos++] = 0; + + header[0] = (Byte)(pos >> 2); + SetUi32(header + pos, CrcCalc(header, pos)) + return WriteBytes(s, header, pos + 4); +} + + + + +typedef struct +{ + size_t numBlocks; + size_t size; + size_t allocated; + Byte *blocks; +} CXzEncIndex; + + +static void XzEncIndex_Construct(CXzEncIndex *p) +{ + p->numBlocks = 0; + p->size = 0; + p->allocated = 0; + p->blocks = NULL; +} + +static void XzEncIndex_Init(CXzEncIndex *p) +{ + p->numBlocks = 0; + p->size = 0; +} + +static void XzEncIndex_Free(CXzEncIndex *p, ISzAllocPtr alloc) +{ + if (p->blocks) + { + ISzAlloc_Free(alloc, p->blocks); + p->blocks = NULL; + } + p->numBlocks = 0; + p->size = 0; + p->allocated = 0; +} + + +static SRes XzEncIndex_ReAlloc(CXzEncIndex *p, size_t newSize, ISzAllocPtr alloc) +{ + Byte *blocks = (Byte *)ISzAlloc_Alloc(alloc, newSize); + if (!blocks) + return SZ_ERROR_MEM; + if (p->size != 0) + memcpy(blocks, p->blocks, p->size); + if (p->blocks) + ISzAlloc_Free(alloc, p->blocks); + p->blocks = blocks; + p->allocated = newSize; + return SZ_OK; +} + + +static SRes XzEncIndex_PreAlloc(CXzEncIndex *p, UInt64 numBlocks, UInt64 unpackSize, UInt64 totalSize, ISzAllocPtr alloc) +{ + UInt64 pos; + { + Byte buf[32]; + unsigned pos2 = Xz_WriteVarInt(buf, totalSize); + pos2 += Xz_WriteVarInt(buf + pos2, unpackSize); + pos = numBlocks * pos2; + } + + if (pos <= p->allocated - p->size) + return SZ_OK; + { + UInt64 newSize64 = p->size + pos; + size_t newSize = (size_t)newSize64; + if (newSize != newSize64) + return SZ_ERROR_MEM; + return XzEncIndex_ReAlloc(p, newSize, alloc); + } +} + + +static SRes XzEncIndex_AddIndexRecord(CXzEncIndex *p, UInt64 unpackSize, UInt64 totalSize, ISzAllocPtr alloc) +{ + Byte buf[32]; + unsigned pos = Xz_WriteVarInt(buf, totalSize); + pos += Xz_WriteVarInt(buf + pos, unpackSize); + + if (pos > p->allocated - p->size) + { + size_t newSize = p->allocated * 2 + 16 * 2; + if (newSize < p->size + pos) + return SZ_ERROR_MEM; + RINOK(XzEncIndex_ReAlloc(p, newSize, alloc)) + } + memcpy(p->blocks + p->size, buf, pos); + p->size += pos; + p->numBlocks++; + return SZ_OK; +} + + +static SRes XzEncIndex_WriteFooter(const CXzEncIndex *p, CXzStreamFlags flags, ISeqOutStreamPtr s) +{ + Byte buf[32]; + UInt64 globalPos; + UInt32 crc = CRC_INIT_VAL; + unsigned pos = 1 + Xz_WriteVarInt(buf + 1, p->numBlocks); + + globalPos = pos; + buf[0] = 0; + RINOK(WriteBytes_UpdateCrc(s, buf, pos, &crc)) + RINOK(WriteBytes_UpdateCrc(s, p->blocks, p->size, &crc)) + globalPos += p->size; + + pos = XZ_GET_PAD_SIZE(globalPos); + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + globalPos += pos; + + crc = CrcUpdate(crc, buf + 4 - pos, pos); + SetUi32(buf + 4, CRC_GET_DIGEST(crc)) + + SetUi32(buf + 8 + 4, (UInt32)(globalPos >> 2)) + buf[8 + 8] = (Byte)(flags >> 8); + buf[8 + 9] = (Byte)(flags & 0xFF); + SetUi32(buf + 8, CrcCalc(buf + 8 + 4, 6)) + buf[8 + 10] = XZ_FOOTER_SIG_0; + buf[8 + 11] = XZ_FOOTER_SIG_1; + + return WriteBytes(s, buf + 4 - pos, pos + 4 + 12); +} + + + +/* ---------- CSeqCheckInStream ---------- */ + +typedef struct +{ + ISeqInStream vt; + ISeqInStreamPtr realStream; + const Byte *data; + UInt64 limit; + UInt64 processed; + int realStreamFinished; + CXzCheck check; +} CSeqCheckInStream; + +static void SeqCheckInStream_Init(CSeqCheckInStream *p, unsigned checkMode) +{ + p->limit = (UInt64)(Int64)-1; + p->processed = 0; + p->realStreamFinished = 0; + XzCheck_Init(&p->check, checkMode); +} + +static void SeqCheckInStream_GetDigest(CSeqCheckInStream *p, Byte *digest) +{ + XzCheck_Final(&p->check, digest); +} + +static SRes SeqCheckInStream_Read(ISeqInStreamPtr pp, void *data, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqCheckInStream) + size_t size2 = *size; + SRes res = SZ_OK; + + if (p->limit != (UInt64)(Int64)-1) + { + UInt64 rem = p->limit - p->processed; + if (size2 > rem) + size2 = (size_t)rem; + } + if (size2 != 0) + { + if (p->realStream) + { + res = ISeqInStream_Read(p->realStream, data, &size2); + p->realStreamFinished = (size2 == 0) ? 1 : 0; + } + else + memcpy(data, p->data + (size_t)p->processed, size2); + XzCheck_Update(&p->check, data, size2); + p->processed += size2; + } + *size = size2; + return res; +} + + +/* ---------- CSeqSizeOutStream ---------- */ + +typedef struct +{ + ISeqOutStream vt; + ISeqOutStreamPtr realStream; + Byte *outBuf; + size_t outBufLimit; + UInt64 processed; +} CSeqSizeOutStream; + +static size_t SeqSizeOutStream_Write(ISeqOutStreamPtr pp, const void *data, size_t size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqSizeOutStream) + if (p->realStream) + size = ISeqOutStream_Write(p->realStream, data, size); + else + { + if (size > p->outBufLimit - (size_t)p->processed) + return 0; + memcpy(p->outBuf + (size_t)p->processed, data, size); + } + p->processed += size; + return size; +} + + +/* ---------- CSeqInFilter ---------- */ + +#define FILTER_BUF_SIZE (1 << 20) + +typedef struct +{ + ISeqInStream vt; + ISeqInStreamPtr realStream; + IStateCoder StateCoder; + Byte *buf; + size_t curPos; + size_t endPos; + int srcWasFinished; +} CSeqInFilter; + + +static const z7_Func_BranchConv g_Funcs_BranchConv_RISC_Enc[] = +{ + Z7_BRANCH_CONV_ENC(PPC), + Z7_BRANCH_CONV_ENC(IA64), + Z7_BRANCH_CONV_ENC(ARM), + Z7_BRANCH_CONV_ENC(ARMT), + Z7_BRANCH_CONV_ENC(SPARC), + Z7_BRANCH_CONV_ENC(ARM64) +}; + +static SizeT XzBcFilterStateBase_Filter_Enc(CXzBcFilterStateBase *p, Byte *data, SizeT size) +{ + switch (p->methodId) + { + case XZ_ID_Delta: + Delta_Encode(p->delta_State, p->delta, data, size); + break; + case XZ_ID_X86: + size = (SizeT)(z7_BranchConvSt_X86_Enc(data, size, p->ip, &p->X86_State) - data); + break; + default: + if (p->methodId >= XZ_ID_PPC) + { + const UInt32 i = p->methodId - XZ_ID_PPC; + if (i < Z7_ARRAY_SIZE(g_Funcs_BranchConv_RISC_Enc)) + size = (SizeT)(g_Funcs_BranchConv_RISC_Enc[i](data, size, p->ip) - data); + } + break; + } + p->ip += (UInt32)size; + return size; +} + + +static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props, ISzAllocPtr alloc) +{ + if (!p->buf) + { + p->buf = (Byte *)ISzAlloc_Alloc(alloc, FILTER_BUF_SIZE); + if (!p->buf) + return SZ_ERROR_MEM; + } + p->curPos = p->endPos = 0; + p->srcWasFinished = 0; + RINOK(Xz_StateCoder_Bc_SetFromMethod_Func(&p->StateCoder, props->id, XzBcFilterStateBase_Filter_Enc, alloc)) + RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, alloc)) + p->StateCoder.Init(p->StateCoder.p); + return SZ_OK; +} + + +static SRes SeqInFilter_Read(ISeqInStreamPtr pp, void *data, size_t *size) +{ + Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CSeqInFilter) + const size_t sizeOriginal = *size; + if (sizeOriginal == 0) + return SZ_OK; + *size = 0; + + for (;;) + { + if (!p->srcWasFinished && p->curPos == p->endPos) + { + p->curPos = 0; + p->endPos = FILTER_BUF_SIZE; + RINOK(ISeqInStream_Read(p->realStream, p->buf, &p->endPos)) + if (p->endPos == 0) + p->srcWasFinished = 1; + } + { + SizeT srcLen = p->endPos - p->curPos; + ECoderStatus status; + SRes res; + *size = sizeOriginal; + res = p->StateCoder.Code2(p->StateCoder.p, + (Byte *)data, size, + p->buf + p->curPos, &srcLen, + p->srcWasFinished, CODER_FINISH_ANY, + &status); + p->curPos += srcLen; + if (*size != 0 || srcLen == 0 || res != SZ_OK) + return res; + } + } +} + +static void SeqInFilter_Construct(CSeqInFilter *p) +{ + p->buf = NULL; + p->StateCoder.p = NULL; + p->vt.Read = SeqInFilter_Read; +} + +static void SeqInFilter_Free(CSeqInFilter *p, ISzAllocPtr alloc) +{ + if (p->StateCoder.p) + { + p->StateCoder.Free(p->StateCoder.p, alloc); + p->StateCoder.p = NULL; + } + if (p->buf) + { + ISzAlloc_Free(alloc, p->buf); + p->buf = NULL; + } +} + + +/* ---------- CSbEncInStream ---------- */ + +#ifdef USE_SUBBLOCK + +typedef struct +{ + ISeqInStream vt; + ISeqInStreamPtr inStream; + CSbEnc enc; +} CSbEncInStream; + +static SRes SbEncInStream_Read(ISeqInStreamPtr pp, void *data, size_t *size) +{ + CSbEncInStream *p = Z7_CONTAINER_FROM_VTBL(pp, CSbEncInStream, vt); + size_t sizeOriginal = *size; + if (sizeOriginal == 0) + return SZ_OK; + + for (;;) + { + if (p->enc.needRead && !p->enc.readWasFinished) + { + size_t processed = p->enc.needReadSizeMax; + RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed)) + p->enc.readPos += processed; + if (processed == 0) + { + p->enc.readWasFinished = True; + p->enc.isFinalFinished = True; + } + p->enc.needRead = False; + } + + *size = sizeOriginal; + RINOK(SbEnc_Read(&p->enc, data, size)) + if (*size != 0 || !p->enc.needRead) + return SZ_OK; + } +} + +void SbEncInStream_Construct(CSbEncInStream *p, ISzAllocPtr alloc) +{ + SbEnc_Construct(&p->enc, alloc); + p->vt.Read = SbEncInStream_Read; +} + +SRes SbEncInStream_Init(CSbEncInStream *p) +{ + return SbEnc_Init(&p->enc); +} + +void SbEncInStream_Free(CSbEncInStream *p) +{ + SbEnc_Free(&p->enc); +} + +#endif + + + +/* ---------- CXzProps ---------- */ + + +void XzFilterProps_Init(CXzFilterProps *p) +{ + p->id = 0; + p->delta = 0; + p->ip = 0; + p->ipDefined = False; +} + +void XzProps_Init(CXzProps *p) +{ + p->checkId = XZ_CHECK_CRC32; + p->blockSize = XZ_PROPS_BLOCK_SIZE_AUTO; + p->numBlockThreads_Reduced = -1; + p->numBlockThreads_Max = -1; + p->numTotalThreads = -1; + p->reduceSize = (UInt64)(Int64)-1; + p->forceWriteSizesInHeader = 0; + // p->forceWriteSizesInHeader = 1; + + XzFilterProps_Init(&p->filterProps); + Lzma2EncProps_Init(&p->lzma2Props); +} + + +static void XzEncProps_Normalize_Fixed(CXzProps *p) +{ + UInt64 fileSize; + int t1, t1n, t2, t2r, t3; + { + CLzma2EncProps tp = p->lzma2Props; + if (tp.numTotalThreads <= 0) + tp.numTotalThreads = p->numTotalThreads; + Lzma2EncProps_Normalize(&tp); + t1n = tp.numTotalThreads; + } + + t1 = p->lzma2Props.numTotalThreads; + t2 = p->numBlockThreads_Max; + t3 = p->numTotalThreads; + + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; + + if (t3 <= 0) + { + if (t2 <= 0) + t2 = 1; + t3 = t1n * t2; + } + else if (t2 <= 0) + { + t2 = t3 / t1n; + if (t2 == 0) + { + t1 = 1; + t2 = t3; + } + if (t2 > MTCODER_THREADS_MAX) + t2 = MTCODER_THREADS_MAX; + } + else if (t1 <= 0) + { + t1 = t3 / t2; + if (t1 == 0) + t1 = 1; + } + else + t3 = t1n * t2; + + p->lzma2Props.numTotalThreads = t1; + + t2r = t2; + + fileSize = p->reduceSize; + + if ((p->blockSize < fileSize || fileSize == (UInt64)(Int64)-1)) + p->lzma2Props.lzmaProps.reduceSize = p->blockSize; + + Lzma2EncProps_Normalize(&p->lzma2Props); + + t1 = p->lzma2Props.numTotalThreads; + + { + if (t2 > 1 && fileSize != (UInt64)(Int64)-1) + { + UInt64 numBlocks = fileSize / p->blockSize; + if (numBlocks * p->blockSize != fileSize) + numBlocks++; + if (numBlocks < (unsigned)t2) + { + t2r = (int)numBlocks; + if (t2r == 0) + t2r = 1; + t3 = t1 * t2r; + } + } + } + + p->numBlockThreads_Max = t2; + p->numBlockThreads_Reduced = t2r; + p->numTotalThreads = t3; +} + + +static void XzProps_Normalize(CXzProps *p) +{ + /* we normalize xzProps properties, but we normalize only some of CXzProps::lzma2Props properties. + Lzma2Enc_SetProps() will normalize lzma2Props later. */ + + if (p->blockSize == XZ_PROPS_BLOCK_SIZE_SOLID) + { + p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; + p->numBlockThreads_Reduced = 1; + p->numBlockThreads_Max = 1; + if (p->lzma2Props.numTotalThreads <= 0) + p->lzma2Props.numTotalThreads = p->numTotalThreads; + return; + } + else + { + CLzma2EncProps *lzma2 = &p->lzma2Props; + if (p->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) + { + // xz-auto + p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; + + if (lzma2->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) + { + // if (xz-auto && lzma2-solid) - we use solid for both + p->blockSize = XZ_PROPS_BLOCK_SIZE_SOLID; + p->numBlockThreads_Reduced = 1; + p->numBlockThreads_Max = 1; + if (p->lzma2Props.numTotalThreads <= 0) + p->lzma2Props.numTotalThreads = p->numTotalThreads; + } + else + { + // if (xz-auto && (lzma2-auto || lzma2-fixed_) + // we calculate block size for lzma2 and use that block size for xz, lzma2 uses single-chunk per block + CLzma2EncProps tp = p->lzma2Props; + if (tp.numTotalThreads <= 0) + tp.numTotalThreads = p->numTotalThreads; + + Lzma2EncProps_Normalize(&tp); + + p->blockSize = tp.blockSize; // fixed or solid + p->numBlockThreads_Reduced = tp.numBlockThreads_Reduced; + p->numBlockThreads_Max = tp.numBlockThreads_Max; + if (lzma2->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) + lzma2->blockSize = tp.blockSize; // fixed or solid, LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + if (lzma2->lzmaProps.reduceSize > tp.blockSize && tp.blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) + lzma2->lzmaProps.reduceSize = tp.blockSize; + lzma2->numBlockThreads_Reduced = 1; + lzma2->numBlockThreads_Max = 1; + return; + } + } + else + { + // xz-fixed + // we can use xz::reduceSize or xz::blockSize as base for lzmaProps::reduceSize + + p->lzma2Props.lzmaProps.reduceSize = p->reduceSize; + { + UInt64 r = p->reduceSize; + if (r > p->blockSize || r == (UInt64)(Int64)-1) + r = p->blockSize; + lzma2->lzmaProps.reduceSize = r; + } + if (lzma2->blockSize == LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO) + lzma2->blockSize = LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID; + else if (lzma2->blockSize > p->blockSize && lzma2->blockSize != LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID) + lzma2->blockSize = p->blockSize; + + XzEncProps_Normalize_Fixed(p); + } + } +} + + +/* ---------- CLzma2WithFilters ---------- */ + +typedef struct +{ + CLzma2EncHandle lzma2; + CSeqInFilter filter; + + #ifdef USE_SUBBLOCK + CSbEncInStream sb; + #endif +} CLzma2WithFilters; + + +static void Lzma2WithFilters_Construct(CLzma2WithFilters *p) +{ + p->lzma2 = NULL; + SeqInFilter_Construct(&p->filter); + + #ifdef USE_SUBBLOCK + SbEncInStream_Construct(&p->sb, alloc); + #endif +} + + +static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p, ISzAllocPtr alloc, ISzAllocPtr bigAlloc) +{ + if (!p->lzma2) + { + p->lzma2 = Lzma2Enc_Create(alloc, bigAlloc); + if (!p->lzma2) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + + +static void Lzma2WithFilters_Free(CLzma2WithFilters *p, ISzAllocPtr alloc) +{ + #ifdef USE_SUBBLOCK + SbEncInStream_Free(&p->sb); + #endif + + SeqInFilter_Free(&p->filter, alloc); + if (p->lzma2) + { + Lzma2Enc_Destroy(p->lzma2); + p->lzma2 = NULL; + } +} + + +typedef struct +{ + UInt64 unpackSize; + UInt64 totalSize; + size_t headerSize; +} CXzEncBlockInfo; + + +static SRes Xz_CompressBlock( + CLzma2WithFilters *lzmaf, + + ISeqOutStreamPtr outStream, + Byte *outBufHeader, + Byte *outBufData, size_t outBufDataLimit, + + ISeqInStreamPtr inStream, + // UInt64 expectedSize, + const Byte *inBuf, // used if (!inStream) + size_t inBufSize, // used if (!inStream), it's block size, props->blockSize is ignored + + const CXzProps *props, + ICompressProgressPtr progress, + int *inStreamFinished, /* only for inStream version */ + CXzEncBlockInfo *blockSizes, + ISzAllocPtr alloc, + ISzAllocPtr allocBig) +{ + CSeqCheckInStream checkInStream; + CSeqSizeOutStream seqSizeOutStream; + CXzBlock block; + unsigned filterIndex = 0; + CXzFilter *filter = NULL; + const CXzFilterProps *fp = &props->filterProps; + if (fp->id == 0) + fp = NULL; + + *inStreamFinished = False; + + RINOK(Lzma2WithFilters_Create(lzmaf, alloc, allocBig)) + + RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, &props->lzma2Props)) + + // XzBlock_ClearFlags(&block) + XzBlock_ClearFlags_SetNumFilters(&block, 1 + (fp ? 1 : 0)) + + if (fp) + { + filter = &block.filters[filterIndex++]; + filter->id = fp->id; + filter->propsSize = 0; + + if (fp->id == XZ_ID_Delta) + { + filter->props[0] = (Byte)(fp->delta - 1); + filter->propsSize = 1; + } + else if (fp->ipDefined) + { + Byte *ptr = filter->props; + SetUi32(ptr, fp->ip) + filter->propsSize = 4; + } + } + + { + CXzFilter *f = &block.filters[filterIndex++]; + f->id = XZ_ID_LZMA2; + f->propsSize = 1; + f->props[0] = Lzma2Enc_WriteProperties(lzmaf->lzma2); + } + + seqSizeOutStream.vt.Write = SeqSizeOutStream_Write; + seqSizeOutStream.realStream = outStream; + seqSizeOutStream.outBuf = outBufData; + seqSizeOutStream.outBufLimit = outBufDataLimit; + seqSizeOutStream.processed = 0; + + /* + if (expectedSize != (UInt64)(Int64)-1) + { + block.unpackSize = expectedSize; + if (props->blockSize != (UInt64)(Int64)-1) + if (expectedSize > props->blockSize) + block.unpackSize = props->blockSize; + XzBlock_SetHasUnpackSize(&block) + } + */ + + if (outStream) + { + RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt)) + } + + checkInStream.vt.Read = SeqCheckInStream_Read; + SeqCheckInStream_Init(&checkInStream, props->checkId); + + checkInStream.realStream = inStream; + checkInStream.data = inBuf; + checkInStream.limit = props->blockSize; + if (!inStream) + checkInStream.limit = inBufSize; + + if (fp) + { + #ifdef USE_SUBBLOCK + if (fp->id == XZ_ID_Subblock) + { + lzmaf->sb.inStream = &checkInStream.vt; + RINOK(SbEncInStream_Init(&lzmaf->sb)) + } + else + #endif + { + lzmaf->filter.realStream = &checkInStream.vt; + RINOK(SeqInFilter_Init(&lzmaf->filter, filter, alloc)) + } + } + + { + SRes res; + Byte *outBuf = NULL; + size_t outSize = 0; + BoolInt useStream = (fp || inStream); + // useStream = True; + + if (!useStream) + { + XzCheck_Update(&checkInStream.check, inBuf, inBufSize); + checkInStream.processed = inBufSize; + } + + if (!outStream) + { + outBuf = seqSizeOutStream.outBuf; // + (size_t)seqSizeOutStream.processed; + outSize = seqSizeOutStream.outBufLimit; // - (size_t)seqSizeOutStream.processed; + } + + res = Lzma2Enc_Encode2(lzmaf->lzma2, + outBuf ? NULL : &seqSizeOutStream.vt, + outBuf, + outBuf ? &outSize : NULL, + + useStream ? + (fp ? + ( + #ifdef USE_SUBBLOCK + (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.vt: + #endif + &lzmaf->filter.vt) : + &checkInStream.vt) : NULL, + + useStream ? NULL : inBuf, + useStream ? 0 : inBufSize, + + progress); + + if (outBuf) + seqSizeOutStream.processed += outSize; + + RINOK(res) + blockSizes->unpackSize = checkInStream.processed; + } + { + Byte buf[4 + 64]; + unsigned padSize = XZ_GET_PAD_SIZE(seqSizeOutStream.processed); + UInt64 packSize = seqSizeOutStream.processed; + + buf[0] = 0; + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; + + SeqCheckInStream_GetDigest(&checkInStream, buf + 4); + RINOK(WriteBytes(&seqSizeOutStream.vt, buf + (4 - padSize), padSize + XzFlags_GetCheckSize((CXzStreamFlags)props->checkId))) + + blockSizes->totalSize = seqSizeOutStream.processed - padSize; + + if (!outStream) + { + seqSizeOutStream.outBuf = outBufHeader; + seqSizeOutStream.outBufLimit = XZ_BLOCK_HEADER_SIZE_MAX; + seqSizeOutStream.processed = 0; + + block.unpackSize = blockSizes->unpackSize; + XzBlock_SetHasUnpackSize(&block) + + block.packSize = packSize; + XzBlock_SetHasPackSize(&block) + + RINOK(XzBlock_WriteHeader(&block, &seqSizeOutStream.vt)) + + blockSizes->headerSize = (size_t)seqSizeOutStream.processed; + blockSizes->totalSize += seqSizeOutStream.processed; + } + } + + if (inStream) + *inStreamFinished = checkInStream.realStreamFinished; + else + { + *inStreamFinished = False; + if (checkInStream.processed != inBufSize) + return SZ_ERROR_FAIL; + } + + return SZ_OK; +} + + + +typedef struct +{ + ICompressProgress vt; + ICompressProgressPtr progress; + UInt64 inOffset; + UInt64 outOffset; +} CCompressProgress_XzEncOffset; + + +static SRes CompressProgress_XzEncOffset_Progress(ICompressProgressPtr pp, UInt64 inSize, UInt64 outSize) +{ + const CCompressProgress_XzEncOffset *p = Z7_CONTAINER_FROM_VTBL_CONST(pp, CCompressProgress_XzEncOffset, vt); + inSize += p->inOffset; + outSize += p->outOffset; + return ICompressProgress_Progress(p->progress, inSize, outSize); +} + + + + +struct CXzEnc +{ + ISzAllocPtr alloc; + ISzAllocPtr allocBig; + + CXzProps xzProps; + UInt64 expectedDataSize; + + CXzEncIndex xzIndex; + + CLzma2WithFilters lzmaf_Items[MTCODER_THREADS_MAX]; + + size_t outBufSize; /* size of allocated outBufs[i] */ + Byte *outBufs[MTCODER_BLOCKS_MAX]; + + #ifndef Z7_ST + unsigned checkType; + ISeqOutStreamPtr outStream; + BoolInt mtCoder_WasConstructed; + CMtCoder mtCoder; + CXzEncBlockInfo EncBlocks[MTCODER_BLOCKS_MAX]; + #endif +}; + + +static void XzEnc_Construct(CXzEnc *p) +{ + unsigned i; + + XzEncIndex_Construct(&p->xzIndex); + + for (i = 0; i < MTCODER_THREADS_MAX; i++) + Lzma2WithFilters_Construct(&p->lzmaf_Items[i]); + + #ifndef Z7_ST + p->mtCoder_WasConstructed = False; + { + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + p->outBufs[i] = NULL; + p->outBufSize = 0; + } + #endif +} + + +static void XzEnc_FreeOutBufs(CXzEnc *p) +{ + unsigned i; + for (i = 0; i < MTCODER_BLOCKS_MAX; i++) + if (p->outBufs[i]) + { + ISzAlloc_Free(p->alloc, p->outBufs[i]); + p->outBufs[i] = NULL; + } + p->outBufSize = 0; +} + + +static void XzEnc_Free(CXzEnc *p, ISzAllocPtr alloc) +{ + unsigned i; + + XzEncIndex_Free(&p->xzIndex, alloc); + + for (i = 0; i < MTCODER_THREADS_MAX; i++) + Lzma2WithFilters_Free(&p->lzmaf_Items[i], alloc); + + #ifndef Z7_ST + if (p->mtCoder_WasConstructed) + { + MtCoder_Destruct(&p->mtCoder); + p->mtCoder_WasConstructed = False; + } + XzEnc_FreeOutBufs(p); + #endif +} + + +CXzEncHandle XzEnc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig) +{ + CXzEnc *p = (CXzEnc *)ISzAlloc_Alloc(alloc, sizeof(CXzEnc)); + if (!p) + return NULL; + XzEnc_Construct(p); + XzProps_Init(&p->xzProps); + XzProps_Normalize(&p->xzProps); + p->expectedDataSize = (UInt64)(Int64)-1; + p->alloc = alloc; + p->allocBig = allocBig; + return (CXzEncHandle)p; +} + +// #define GET_CXzEnc_p CXzEnc *p = (CXzEnc *)(void *)pp; + +void XzEnc_Destroy(CXzEncHandle p) +{ + // GET_CXzEnc_p + XzEnc_Free(p, p->alloc); + ISzAlloc_Free(p->alloc, p); +} + + +SRes XzEnc_SetProps(CXzEncHandle p, const CXzProps *props) +{ + // GET_CXzEnc_p + p->xzProps = *props; + XzProps_Normalize(&p->xzProps); + return SZ_OK; +} + + +void XzEnc_SetDataSize(CXzEncHandle p, UInt64 expectedDataSiize) +{ + // GET_CXzEnc_p + p->expectedDataSize = expectedDataSiize; +} + + + + +#ifndef Z7_ST + +static SRes XzEnc_MtCallback_Code(void *pp, unsigned coderIndex, unsigned outBufIndex, + const Byte *src, size_t srcSize, int finished) +{ + CXzEnc *me = (CXzEnc *)pp; + SRes res; + CMtProgressThunk progressThunk; + + Byte *dest = me->outBufs[outBufIndex]; + + UNUSED_VAR(finished) + + { + CXzEncBlockInfo *bInfo = &me->EncBlocks[outBufIndex]; + bInfo->totalSize = 0; + bInfo->unpackSize = 0; + bInfo->headerSize = 0; + } + + if (!dest) + { + dest = (Byte *)ISzAlloc_Alloc(me->alloc, me->outBufSize); + if (!dest) + return SZ_ERROR_MEM; + me->outBufs[outBufIndex] = dest; + } + + MtProgressThunk_CreateVTable(&progressThunk); + progressThunk.mtProgress = &me->mtCoder.mtProgress; + MtProgressThunk_INIT(&progressThunk) + + { + CXzEncBlockInfo blockSizes; + int inStreamFinished; + + res = Xz_CompressBlock( + &me->lzmaf_Items[coderIndex], + + NULL, + dest, + dest + XZ_BLOCK_HEADER_SIZE_MAX, me->outBufSize - XZ_BLOCK_HEADER_SIZE_MAX, + + NULL, + // srcSize, // expectedSize + src, srcSize, + + &me->xzProps, + &progressThunk.vt, + &inStreamFinished, + &blockSizes, + me->alloc, + me->allocBig); + + if (res == SZ_OK) + me->EncBlocks[outBufIndex] = blockSizes; + + return res; + } +} + + +static SRes XzEnc_MtCallback_Write(void *pp, unsigned outBufIndex) +{ + CXzEnc *me = (CXzEnc *)pp; + + const CXzEncBlockInfo *bInfo = &me->EncBlocks[outBufIndex]; + const Byte *data = me->outBufs[outBufIndex]; + + RINOK(WriteBytes(me->outStream, data, bInfo->headerSize)) + + { + UInt64 totalPackFull = bInfo->totalSize + XZ_GET_PAD_SIZE(bInfo->totalSize); + RINOK(WriteBytes(me->outStream, data + XZ_BLOCK_HEADER_SIZE_MAX, (size_t)totalPackFull - bInfo->headerSize)) + } + + return XzEncIndex_AddIndexRecord(&me->xzIndex, bInfo->unpackSize, bInfo->totalSize, me->alloc); +} + +#endif + + + +SRes XzEnc_Encode(CXzEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress) +{ + // GET_CXzEnc_p + + const CXzProps *props = &p->xzProps; + + XzEncIndex_Init(&p->xzIndex); + { + UInt64 numBlocks = 1; + UInt64 blockSize = props->blockSize; + + if (blockSize != XZ_PROPS_BLOCK_SIZE_SOLID + && props->reduceSize != (UInt64)(Int64)-1) + { + numBlocks = props->reduceSize / blockSize; + if (numBlocks * blockSize != props->reduceSize) + numBlocks++; + } + else + blockSize = (UInt64)1 << 62; + + RINOK(XzEncIndex_PreAlloc(&p->xzIndex, numBlocks, blockSize, XZ_GET_ESTIMATED_BLOCK_TOTAL_PACK_SIZE(blockSize), p->alloc)) + } + + RINOK(Xz_WriteHeader((CXzStreamFlags)props->checkId, outStream)) + + + #ifndef Z7_ST + if (props->numBlockThreads_Reduced > 1) + { + IMtCoderCallback2 vt; + + if (!p->mtCoder_WasConstructed) + { + p->mtCoder_WasConstructed = True; + MtCoder_Construct(&p->mtCoder); + } + + vt.Code = XzEnc_MtCallback_Code; + vt.Write = XzEnc_MtCallback_Write; + + p->checkType = props->checkId; + p->xzProps = *props; + + p->outStream = outStream; + + p->mtCoder.allocBig = p->allocBig; + p->mtCoder.progress = progress; + p->mtCoder.inStream = inStream; + p->mtCoder.inData = NULL; + p->mtCoder.inDataSize = 0; + p->mtCoder.mtCallback = &vt; + p->mtCoder.mtCallbackObject = p; + + if ( props->blockSize == XZ_PROPS_BLOCK_SIZE_SOLID + || props->blockSize == XZ_PROPS_BLOCK_SIZE_AUTO) + return SZ_ERROR_FAIL; + + p->mtCoder.blockSize = (size_t)props->blockSize; + if (p->mtCoder.blockSize != props->blockSize) + return SZ_ERROR_PARAM; /* SZ_ERROR_MEM */ + + { + size_t destBlockSize = XZ_BLOCK_HEADER_SIZE_MAX + XZ_GET_MAX_BLOCK_PACK_SIZE(p->mtCoder.blockSize); + if (destBlockSize < p->mtCoder.blockSize) + return SZ_ERROR_PARAM; + if (p->outBufSize != destBlockSize) + XzEnc_FreeOutBufs(p); + p->outBufSize = destBlockSize; + } + + p->mtCoder.numThreadsMax = (unsigned)props->numBlockThreads_Max; + p->mtCoder.expectedDataSize = p->expectedDataSize; + + RINOK(MtCoder_Code(&p->mtCoder)) + } + else + #endif + { + int writeStartSizes; + CCompressProgress_XzEncOffset progress2; + Byte *bufData = NULL; + size_t bufSize = 0; + + progress2.vt.Progress = CompressProgress_XzEncOffset_Progress; + progress2.inOffset = 0; + progress2.outOffset = 0; + progress2.progress = progress; + + writeStartSizes = 0; + + if (props->blockSize != XZ_PROPS_BLOCK_SIZE_SOLID) + { + writeStartSizes = (props->forceWriteSizesInHeader > 0); + + if (writeStartSizes) + { + size_t t2; + size_t t = (size_t)props->blockSize; + if (t != props->blockSize) + return SZ_ERROR_PARAM; + t = XZ_GET_MAX_BLOCK_PACK_SIZE(t); + if (t < props->blockSize) + return SZ_ERROR_PARAM; + t2 = XZ_BLOCK_HEADER_SIZE_MAX + t; + if (!p->outBufs[0] || t2 != p->outBufSize) + { + XzEnc_FreeOutBufs(p); + p->outBufs[0] = (Byte *)ISzAlloc_Alloc(p->alloc, t2); + if (!p->outBufs[0]) + return SZ_ERROR_MEM; + p->outBufSize = t2; + } + bufData = p->outBufs[0] + XZ_BLOCK_HEADER_SIZE_MAX; + bufSize = t; + } + } + + for (;;) + { + CXzEncBlockInfo blockSizes; + int inStreamFinished; + + /* + UInt64 rem = (UInt64)(Int64)-1; + if (props->reduceSize != (UInt64)(Int64)-1 + && props->reduceSize >= progress2.inOffset) + rem = props->reduceSize - progress2.inOffset; + */ + + blockSizes.headerSize = 0; // for GCC + + RINOK(Xz_CompressBlock( + &p->lzmaf_Items[0], + + writeStartSizes ? NULL : outStream, + writeStartSizes ? p->outBufs[0] : NULL, + bufData, bufSize, + + inStream, + // rem, + NULL, 0, + + props, + progress ? &progress2.vt : NULL, + &inStreamFinished, + &blockSizes, + p->alloc, + p->allocBig)) + + { + UInt64 totalPackFull = blockSizes.totalSize + XZ_GET_PAD_SIZE(blockSizes.totalSize); + + if (writeStartSizes) + { + RINOK(WriteBytes(outStream, p->outBufs[0], blockSizes.headerSize)) + RINOK(WriteBytes(outStream, bufData, (size_t)totalPackFull - blockSizes.headerSize)) + } + + RINOK(XzEncIndex_AddIndexRecord(&p->xzIndex, blockSizes.unpackSize, blockSizes.totalSize, p->alloc)) + + progress2.inOffset += blockSizes.unpackSize; + progress2.outOffset += totalPackFull; + } + + if (inStreamFinished) + break; + } + } + + return XzEncIndex_WriteFooter(&p->xzIndex, (CXzStreamFlags)props->checkId, outStream); +} + + +#include "Alloc.h" + +SRes Xz_Encode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + const CXzProps *props, ICompressProgressPtr progress) +{ + SRes res; + CXzEncHandle xz = XzEnc_Create(&g_Alloc, &g_BigAlloc); + if (!xz) + return SZ_ERROR_MEM; + res = XzEnc_SetProps(xz, props); + if (res == SZ_OK) + res = XzEnc_Encode(xz, outStream, inStream, progress); + XzEnc_Destroy(xz); + return res; +} + + +SRes Xz_EncodeEmpty(ISeqOutStreamPtr outStream) +{ + SRes res; + CXzEncIndex xzIndex; + XzEncIndex_Construct(&xzIndex); + res = Xz_WriteHeader((CXzStreamFlags)0, outStream); + if (res == SZ_OK) + res = XzEncIndex_WriteFooter(&xzIndex, (CXzStreamFlags)0, outStream); + XzEncIndex_Free(&xzIndex, NULL); // g_Alloc + return res; +} diff --git a/libraries/lzma/C/XzEnc.h b/libraries/lzma/C/XzEnc.h new file mode 100644 index 000000000..77b78c014 --- /dev/null +++ b/libraries/lzma/C/XzEnc.h @@ -0,0 +1,61 @@ +/* XzEnc.h -- Xz Encode +2023-04-13 : Igor Pavlov : Public domain */ + +#ifndef ZIP7_INC_XZ_ENC_H +#define ZIP7_INC_XZ_ENC_H + +#include "Lzma2Enc.h" + +#include "Xz.h" + +EXTERN_C_BEGIN + + +#define XZ_PROPS_BLOCK_SIZE_AUTO LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO +#define XZ_PROPS_BLOCK_SIZE_SOLID LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID + + +typedef struct +{ + UInt32 id; + UInt32 delta; + UInt32 ip; + int ipDefined; +} CXzFilterProps; + +void XzFilterProps_Init(CXzFilterProps *p); + + +typedef struct +{ + CLzma2EncProps lzma2Props; + CXzFilterProps filterProps; + unsigned checkId; + UInt64 blockSize; + int numBlockThreads_Reduced; + int numBlockThreads_Max; + int numTotalThreads; + int forceWriteSizesInHeader; + UInt64 reduceSize; +} CXzProps; + +void XzProps_Init(CXzProps *p); + +typedef struct CXzEnc CXzEnc; +typedef CXzEnc * CXzEncHandle; +// Z7_DECLARE_HANDLE(CXzEncHandle) + +CXzEncHandle XzEnc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig); +void XzEnc_Destroy(CXzEncHandle p); +SRes XzEnc_SetProps(CXzEncHandle p, const CXzProps *props); +void XzEnc_SetDataSize(CXzEncHandle p, UInt64 expectedDataSiize); +SRes XzEnc_Encode(CXzEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress); + +SRes Xz_Encode(ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, + const CXzProps *props, ICompressProgressPtr progress); + +SRes Xz_EncodeEmpty(ISeqOutStreamPtr outStream); + +EXTERN_C_END + +#endif diff --git a/libraries/lzma/C/XzIn.c b/libraries/lzma/C/XzIn.c new file mode 100644 index 000000000..d0fc76367 --- /dev/null +++ b/libraries/lzma/C/XzIn.c @@ -0,0 +1,340 @@ +/* XzIn.c - Xz input +2023-04-02 : Igor Pavlov : Public domain */ + +#include "Precomp.h" + +#include + +#include "7zCrc.h" +#include "CpuArch.h" +#include "Xz.h" + +/* +#define XZ_FOOTER_SIG_CHECK(p) (memcmp((p), XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0) +*/ +#define XZ_FOOTER_SIG_CHECK(p) ((p)[0] == XZ_FOOTER_SIG_0 && (p)[1] == XZ_FOOTER_SIG_1) + + +SRes Xz_ReadHeader(CXzStreamFlags *p, ISeqInStreamPtr inStream) +{ + Byte sig[XZ_STREAM_HEADER_SIZE]; + size_t processedSize = XZ_STREAM_HEADER_SIZE; + RINOK(SeqInStream_ReadMax(inStream, sig, &processedSize)) + if (processedSize != XZ_STREAM_HEADER_SIZE + || memcmp(sig, XZ_SIG, XZ_SIG_SIZE) != 0) + return SZ_ERROR_NO_ARCHIVE; + return Xz_ParseHeader(p, sig); +} + +#define READ_VARINT_AND_CHECK(buf, pos, size, res) \ + { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ + if (s == 0) return SZ_ERROR_ARCHIVE; \ + pos += s; } + +SRes XzBlock_ReadHeader(CXzBlock *p, ISeqInStreamPtr inStream, BoolInt *isIndex, UInt32 *headerSizeRes) +{ + Byte header[XZ_BLOCK_HEADER_SIZE_MAX]; + unsigned headerSize; + *headerSizeRes = 0; + RINOK(SeqInStream_ReadByte(inStream, &header[0])) + headerSize = (unsigned)header[0]; + if (headerSize == 0) + { + *headerSizeRes = 1; + *isIndex = True; + return SZ_OK; + } + + *isIndex = False; + headerSize = (headerSize << 2) + 4; + *headerSizeRes = headerSize; + { + size_t processedSize = headerSize - 1; + RINOK(SeqInStream_ReadMax(inStream, header + 1, &processedSize)) + if (processedSize != headerSize - 1) + return SZ_ERROR_INPUT_EOF; + } + return XzBlock_Parse(p, header); +} + +#define ADD_SIZE_CHECK(size, val) \ + { UInt64 newSize = size + (val); if (newSize < size) return XZ_SIZE_OVERFLOW; size = newSize; } + +UInt64 Xz_GetUnpackSize(const CXzStream *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->numBlocks; i++) + { + ADD_SIZE_CHECK(size, p->blocks[i].unpackSize) + } + return size; +} + +UInt64 Xz_GetPackSize(const CXzStream *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->numBlocks; i++) + { + ADD_SIZE_CHECK(size, (p->blocks[i].totalSize + 3) & ~(UInt64)3) + } + return size; +} + +/* +SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStreamPtr inStream) +{ + return SeqInStream_Read(inStream, p->check, XzFlags_GetCheckSize(f)); +} +*/ + +static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAllocPtr alloc) +{ + size_t numBlocks, pos = 1; + UInt32 crc; + + if (size < 5 || buf[0] != 0) + return SZ_ERROR_ARCHIVE; + + size -= 4; + crc = CrcCalc(buf, size); + if (crc != GetUi32(buf + size)) + return SZ_ERROR_ARCHIVE; + + { + UInt64 numBlocks64; + READ_VARINT_AND_CHECK(buf, pos, size, &numBlocks64) + numBlocks = (size_t)numBlocks64; + if (numBlocks != numBlocks64 || numBlocks * 2 > size) + return SZ_ERROR_ARCHIVE; + } + + Xz_Free(p, alloc); + if (numBlocks != 0) + { + size_t i; + p->numBlocks = numBlocks; + p->blocks = (CXzBlockSizes *)ISzAlloc_Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks); + if (!p->blocks) + return SZ_ERROR_MEM; + for (i = 0; i < numBlocks; i++) + { + CXzBlockSizes *block = &p->blocks[i]; + READ_VARINT_AND_CHECK(buf, pos, size, &block->totalSize) + READ_VARINT_AND_CHECK(buf, pos, size, &block->unpackSize) + if (block->totalSize == 0) + return SZ_ERROR_ARCHIVE; + } + } + while ((pos & 3) != 0) + if (buf[pos++] != 0) + return SZ_ERROR_ARCHIVE; + return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; +} + +static SRes Xz_ReadIndex(CXzStream *p, ILookInStreamPtr stream, UInt64 indexSize, ISzAllocPtr alloc) +{ + SRes res; + size_t size; + Byte *buf; + if (indexSize > ((UInt32)1 << 31)) + return SZ_ERROR_UNSUPPORTED; + size = (size_t)indexSize; + if (size != indexSize) + return SZ_ERROR_UNSUPPORTED; + buf = (Byte *)ISzAlloc_Alloc(alloc, size); + if (!buf) + return SZ_ERROR_MEM; + res = LookInStream_Read2(stream, buf, size, SZ_ERROR_UNSUPPORTED); + if (res == SZ_OK) + res = Xz_ReadIndex2(p, buf, size, alloc); + ISzAlloc_Free(alloc, buf); + return res; +} + +static SRes LookInStream_SeekRead_ForArc(ILookInStreamPtr stream, UInt64 offset, void *buf, size_t size) +{ + RINOK(LookInStream_SeekTo(stream, offset)) + return LookInStream_Read(stream, buf, size); + /* return LookInStream_Read2(stream, buf, size, SZ_ERROR_NO_ARCHIVE); */ +} + +static SRes Xz_ReadBackward(CXzStream *p, ILookInStreamPtr stream, Int64 *startOffset, ISzAllocPtr alloc) +{ + UInt64 indexSize; + Byte buf[XZ_STREAM_FOOTER_SIZE]; + UInt64 pos = (UInt64)*startOffset; + + if ((pos & 3) != 0 || pos < XZ_STREAM_FOOTER_SIZE) + return SZ_ERROR_NO_ARCHIVE; + + pos -= XZ_STREAM_FOOTER_SIZE; + RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)) + + if (!XZ_FOOTER_SIG_CHECK(buf + 10)) + { + UInt32 total = 0; + pos += XZ_STREAM_FOOTER_SIZE; + + for (;;) + { + size_t i; + #define TEMP_BUF_SIZE (1 << 10) + Byte temp[TEMP_BUF_SIZE]; + + i = (pos > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)pos; + pos -= i; + RINOK(LookInStream_SeekRead_ForArc(stream, pos, temp, i)) + total += (UInt32)i; + for (; i != 0; i--) + if (temp[i - 1] != 0) + break; + if (i != 0) + { + if ((i & 3) != 0) + return SZ_ERROR_NO_ARCHIVE; + pos += i; + break; + } + if (pos < XZ_STREAM_FOOTER_SIZE || total > (1 << 16)) + return SZ_ERROR_NO_ARCHIVE; + } + + if (pos < XZ_STREAM_FOOTER_SIZE) + return SZ_ERROR_NO_ARCHIVE; + pos -= XZ_STREAM_FOOTER_SIZE; + RINOK(LookInStream_SeekRead_ForArc(stream, pos, buf, XZ_STREAM_FOOTER_SIZE)) + if (!XZ_FOOTER_SIG_CHECK(buf + 10)) + return SZ_ERROR_NO_ARCHIVE; + } + + p->flags = (CXzStreamFlags)GetBe16(buf + 8); + + if (!XzFlags_IsSupported(p->flags)) + return SZ_ERROR_UNSUPPORTED; + + { + /* to eliminate GCC 6.3 warning: + dereferencing type-punned pointer will break strict-aliasing rules */ + const Byte *buf_ptr = buf; + if (GetUi32(buf_ptr) != CrcCalc(buf + 4, 6)) + return SZ_ERROR_ARCHIVE; + } + + indexSize = ((UInt64)GetUi32(buf + 4) + 1) << 2; + + if (pos < indexSize) + return SZ_ERROR_ARCHIVE; + + pos -= indexSize; + RINOK(LookInStream_SeekTo(stream, pos)) + RINOK(Xz_ReadIndex(p, stream, indexSize, alloc)) + + { + UInt64 totalSize = Xz_GetPackSize(p); + if (totalSize == XZ_SIZE_OVERFLOW + || totalSize >= ((UInt64)1 << 63) + || pos < totalSize + XZ_STREAM_HEADER_SIZE) + return SZ_ERROR_ARCHIVE; + pos -= (totalSize + XZ_STREAM_HEADER_SIZE); + RINOK(LookInStream_SeekTo(stream, pos)) + *startOffset = (Int64)pos; + } + { + CXzStreamFlags headerFlags; + CSecToRead secToRead; + SecToRead_CreateVTable(&secToRead); + secToRead.realStream = stream; + + RINOK(Xz_ReadHeader(&headerFlags, &secToRead.vt)) + return (p->flags == headerFlags) ? SZ_OK : SZ_ERROR_ARCHIVE; + } +} + + +/* ---------- Xz Streams ---------- */ + +void Xzs_Construct(CXzs *p) +{ + p->num = p->numAllocated = 0; + p->streams = 0; +} + +void Xzs_Free(CXzs *p, ISzAllocPtr alloc) +{ + size_t i; + for (i = 0; i < p->num; i++) + Xz_Free(&p->streams[i], alloc); + ISzAlloc_Free(alloc, p->streams); + p->num = p->numAllocated = 0; + p->streams = 0; +} + +UInt64 Xzs_GetNumBlocks(const CXzs *p) +{ + UInt64 num = 0; + size_t i; + for (i = 0; i < p->num; i++) + num += p->streams[i].numBlocks; + return num; +} + +UInt64 Xzs_GetUnpackSize(const CXzs *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->num; i++) + { + ADD_SIZE_CHECK(size, Xz_GetUnpackSize(&p->streams[i])) + } + return size; +} + +/* +UInt64 Xzs_GetPackSize(const CXzs *p) +{ + UInt64 size = 0; + size_t i; + for (i = 0; i < p->num; i++) + { + ADD_SIZE_CHECK(size, Xz_GetTotalSize(&p->streams[i])) + } + return size; +} +*/ + +SRes Xzs_ReadBackward(CXzs *p, ILookInStreamPtr stream, Int64 *startOffset, ICompressProgressPtr progress, ISzAllocPtr alloc) +{ + Int64 endOffset = 0; + RINOK(ILookInStream_Seek(stream, &endOffset, SZ_SEEK_END)) + *startOffset = endOffset; + for (;;) + { + CXzStream st; + SRes res; + Xz_Construct(&st); + res = Xz_ReadBackward(&st, stream, startOffset, alloc); + st.startOffset = (UInt64)*startOffset; + RINOK(res) + if (p->num == p->numAllocated) + { + const size_t newNum = p->num + p->num / 4 + 1; + void *data = ISzAlloc_Alloc(alloc, newNum * sizeof(CXzStream)); + if (!data) + return SZ_ERROR_MEM; + p->numAllocated = newNum; + if (p->num != 0) + memcpy(data, p->streams, p->num * sizeof(CXzStream)); + ISzAlloc_Free(alloc, p->streams); + p->streams = (CXzStream *)data; + } + p->streams[p->num++] = st; + if (*startOffset == 0) + break; + RINOK(LookInStream_SeekTo(stream, (UInt64)*startOffset)) + if (progress && ICompressProgress_Progress(progress, (UInt64)(endOffset - *startOffset), (UInt64)(Int64)-1) != SZ_OK) + return SZ_ERROR_PROGRESS; + } + return SZ_OK; +} diff --git a/libraries/lzma/CMakeLists.txt b/libraries/lzma/CMakeLists.txt index 462419226..bfb8e327e 100644 --- a/libraries/lzma/CMakeLists.txt +++ b/libraries/lzma/CMakeLists.txt @@ -5,26 +5,52 @@ set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_7ZIP_PPMD_SUPPPORT" ) find_package(Threads) add_library( lzma STATIC + C/7zAlloc.c C/7zArcIn.c C/7zBuf.c + C/7zBuf2.c C/7zCrc.c C/7zCrcOpt.c C/7zDec.c + C/7zFile.c C/7zStream.c + C/Aes.c + C/AesOpt.c + C/Alloc.c C/Bcj2.c + C/Bcj2Enc.c C/Bra.c C/Bra86.c C/BraIA64.c C/CpuArch.c C/Delta.c + C/DllSecur.c C/LzFind.c C/LzFindMt.c C/LzFindOpt.c C/Lzma2Dec.c + C/Lzma2DecMt.c + C/Lzma2Enc.c + C/Lzma86Dec.c + C/Lzma86Enc.c C/LzmaDec.c C/LzmaEnc.c + C/LzmaLib.c + C/MtCoder.c + C/MtDec.c C/Ppmd7.c C/Ppmd7Dec.c + C/Ppmd7Enc.c + C/Sha256.c + C/Sha256Opt.c + C/Sort.c + C/SwapBytes.c C/Threads.c + C/Xz.c + C/XzCrc64.c + C/XzCrc64Opt.c + C/XzDec.c + C/XzEnc.c + C/XzIn.c ) target_link_libraries( lzma Threads::Threads ) diff --git a/src/common/filesystem/include/fs_files.h b/src/common/filesystem/include/fs_files.h index 06160d258..756a15007 100644 --- a/src/common/filesystem/include/fs_files.h +++ b/src/common/filesystem/include/fs_files.h @@ -81,6 +81,7 @@ enum METHOD_DEFLATE = 8, METHOD_BZIP2 = 12, METHOD_LZMA = 14, + METHOD_XZ = 95, METHOD_PPMD = 98, METHOD_LZSS = 1337, // not used in Zips - this is for Console Doom compression METHOD_ZLIB = 1338, // Zlib stream with header, used by compressed nodes. diff --git a/src/common/filesystem/source/file_7z.cpp b/src/common/filesystem/source/file_7z.cpp index 9201ead99..1be0d6a1c 100644 --- a/src/common/filesystem/source/file_7z.cpp +++ b/src/common/filesystem/source/file_7z.cpp @@ -121,7 +121,7 @@ struct C7zArchive file.Seek(0, FileReader::SeekSet); LookToRead2_CreateVTable(&LookStream, false); LookStream.realStream = &ArchiveStream.s; - LookToRead2_Init(&LookStream); + LookToRead2_INIT(&LookStream); LookStream.bufSize = sizeof(StreamBuffer); LookStream.buf = StreamBuffer; SzArEx_Init(&DB); diff --git a/src/common/filesystem/source/file_zip.cpp b/src/common/filesystem/source/file_zip.cpp index 28c2dedec..9aa34095a 100644 --- a/src/common/filesystem/source/file_zip.cpp +++ b/src/common/filesystem/source/file_zip.cpp @@ -65,6 +65,7 @@ static bool UncompressZipLump(char *Cache, FileReader &Reader, int Method, int L case METHOD_DEFLATE: case METHOD_BZIP2: case METHOD_LZMA: + case METHOD_XZ: { FileReader frz; if (frz.OpenDecompressor(Reader, LumpSize, Method, false, exceptions)) @@ -349,7 +350,8 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) zip_fh->Method != METHOD_LZMA && zip_fh->Method != METHOD_BZIP2 && zip_fh->Method != METHOD_IMPLODE && - zip_fh->Method != METHOD_SHRINK) + zip_fh->Method != METHOD_SHRINK && + zip_fh->Method != METHOD_XZ) { Printf(FSMessageLevel::Error, "%s: '%s' uses an unsupported compression algorithm (#%d).\n", FileName, name.c_str(), zip_fh->Method); skipped++; diff --git a/src/common/filesystem/source/files_decompress.cpp b/src/common/filesystem/source/files_decompress.cpp index 1b6c373b3..28046ad41 100644 --- a/src/common/filesystem/source/files_decompress.cpp +++ b/src/common/filesystem/source/files_decompress.cpp @@ -36,6 +36,9 @@ // Caution: LzmaDec also pulls in windows.h! #define NOMINMAX #include "LzmaDec.h" +#include "Xz.h" +// CRC table needs to be generated prior to reading XZ compressed files. +#include "7zCrc.h" #include #include #include @@ -505,6 +508,142 @@ public: }; +//========================================================================== +// +// DecompressorXZ +// +// The XZ wrapper +// reads data from a XZ compressed stream +// +//========================================================================== + +// Wraps around a Decompressor to decompress a XZ stream +class DecompressorXZ : public DecompressorBase +{ + enum { BUFF_SIZE = 4096 }; + + bool SawEOF = false; + CXzUnpacker Stream; + size_t Size; + size_t InPos, InSize; + size_t OutProcessed; + uint8_t InBuff[BUFF_SIZE]; + +public: + + bool Open(FileReader *file, size_t uncompressed_size) + { + if (File != nullptr) + { + DecompressionError("File already open"); + return false; + } + + uint8_t header[12]; + int err; + File = file; + + Size = uncompressed_size; + OutProcessed = 0; + + // Read zip XZ properties header + if (File->Read(header, sizeof(header)) < (long)sizeof(header)) + { + DecompressionError("DecompressorXZ: File too short\n"); + return false; + } + + File->Seek(-sizeof(header), FileReader::SeekCur); + + FillBuffer(); + + XzUnpacker_Construct(&Stream, &g_Alloc); + XzUnpacker_Init(&Stream); + + return true; + } + + ~DecompressorXZ () + { + XzUnpacker_Free(&Stream); + } + + ptrdiff_t Read (void *buffer, ptrdiff_t len) override + { + if (File == nullptr) + { + DecompressionError("File not open"); + return 0; + } + + if (g_CrcTable[1] == 0) + { + CrcGenerateTable(); + } + + int err; + Byte *next_out = (Byte *)buffer; + + do + { + ECoderFinishMode finish_mode = CODER_FINISH_ANY; + ECoderStatus status; + size_t out_processed = len; + size_t in_processed = InSize; + + err = XzUnpacker_Code(&Stream, next_out, &out_processed, InBuff + InPos, &in_processed, SawEOF, finish_mode, &status); + InPos += in_processed; + InSize -= in_processed; + next_out += out_processed; + len = (long)(len - out_processed); + if (err != SZ_OK) + { + DecompressionError ("Corrupt XZ stream", err); + return 0; + } + if (in_processed == 0 && out_processed == 0) + { + if (status != CODER_STATUS_FINISHED_WITH_MARK) + { + DecompressionError ("Corrupt XZ stream"); + return 0; + } + } + if (InSize == 0 && !SawEOF) + { + FillBuffer (); + } + } while (err == SZ_OK && len != 0); + + if (err != Z_OK && err != Z_STREAM_END) + { + DecompressionError ("Corrupt XZ stream"); + return 0; + } + + if (len != 0) + { + DecompressionError ("Ran out of data in XZ stream"); + return 0; + } + + return (long)(next_out - (Byte *)buffer); + } + + void FillBuffer () + { + auto numread = File->Read(InBuff, BUFF_SIZE); + + if (numread < BUFF_SIZE) + { + SawEOF = true; + } + InPos = 0; + InSize = numread; + } + +}; + //========================================================================== // // Console Doom LZSS wrapper. @@ -748,6 +887,18 @@ bool FileReader::OpenDecompressor(FileReader &parent, Size length, int method, b } break; } + case METHOD_XZ: + { + auto idec = new DecompressorXZ; + dec = idec; + idec->EnableExceptions(exceptions); + if (!idec->Open(p, length)) + { + delete idec; + return false; + } + break; + } case METHOD_LZSS: { auto idec = new DecompressorLZSS; From 56c44182d13776423f299e047826f2280cab5293 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Tue, 19 Sep 2023 23:23:23 +0600 Subject: [PATCH 189/223] Fix wrong define for PPMd --- libraries/lzma/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/lzma/CMakeLists.txt b/libraries/lzma/CMakeLists.txt index bfb8e327e..3ef9184bd 100644 --- a/libraries/lzma/CMakeLists.txt +++ b/libraries/lzma/CMakeLists.txt @@ -1,6 +1,6 @@ make_release_only() -set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_7ZIP_PPMD_SUPPPORT" ) +set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DZ7_PPMD_SUPPPORT" ) find_package(Threads) From 07582a6bf763de186331fec54ac9411109289353 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sat, 23 Sep 2023 00:44:09 +0600 Subject: [PATCH 190/223] Remove Aes, BraIA64.c and Lzma86 files --- libraries/lzma/C/Aes.c | 393 ---------------- libraries/lzma/C/Aes.h | 60 --- libraries/lzma/C/AesOpt.c | 840 ---------------------------------- libraries/lzma/C/BraIA64.c | 14 - libraries/lzma/C/Lzma86.h | 111 ----- libraries/lzma/C/Lzma86Dec.c | 53 --- libraries/lzma/C/Lzma86Enc.c | 103 ----- libraries/lzma/CMakeLists.txt | 5 - 8 files changed, 1579 deletions(-) delete mode 100644 libraries/lzma/C/Aes.c delete mode 100644 libraries/lzma/C/Aes.h delete mode 100644 libraries/lzma/C/AesOpt.c delete mode 100644 libraries/lzma/C/BraIA64.c delete mode 100644 libraries/lzma/C/Lzma86.h delete mode 100644 libraries/lzma/C/Lzma86Dec.c delete mode 100644 libraries/lzma/C/Lzma86Enc.c diff --git a/libraries/lzma/C/Aes.c b/libraries/lzma/C/Aes.c deleted file mode 100644 index bcaafab11..000000000 --- a/libraries/lzma/C/Aes.c +++ /dev/null @@ -1,393 +0,0 @@ -/* Aes.c -- AES encryption / decryption -2023-04-02 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "CpuArch.h" -#include "Aes.h" - -AES_CODE_FUNC g_AesCbc_Decode; -#ifndef Z7_SFX -AES_CODE_FUNC g_AesCbc_Encode; -AES_CODE_FUNC g_AesCtr_Code; -UInt32 g_Aes_SupportedFunctions_Flags; -#endif - -static UInt32 T[256 * 4]; -static const Byte Sbox[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; - - -static UInt32 D[256 * 4]; -static Byte InvS[256]; - -#define xtime(x) ((((x) << 1) ^ (((x) & 0x80) != 0 ? 0x1B : 0)) & 0xFF) - -#define Ui32(a0, a1, a2, a3) ((UInt32)(a0) | ((UInt32)(a1) << 8) | ((UInt32)(a2) << 16) | ((UInt32)(a3) << 24)) - -#define gb0(x) ( (x) & 0xFF) -#define gb1(x) (((x) >> ( 8)) & 0xFF) -#define gb2(x) (((x) >> (16)) & 0xFF) -#define gb3(x) (((x) >> (24))) - -#define gb(n, x) gb ## n(x) - -#define TT(x) (T + (x << 8)) -#define DD(x) (D + (x << 8)) - - -// #define Z7_SHOW_AES_STATUS - -#ifdef MY_CPU_X86_OR_AMD64 - #define USE_HW_AES -#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) - #if defined(__clang__) - #if (__clang_major__ >= 8) // fix that check - #define USE_HW_AES - #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 6) // fix that check - #define USE_HW_AES - #endif - #elif defined(_MSC_VER) - #if _MSC_VER >= 1910 - #define USE_HW_AES - #endif - #endif -#endif - -#ifdef USE_HW_AES -#ifdef Z7_SHOW_AES_STATUS -#include -#define PRF(x) x -#else -#define PRF(x) -#endif -#endif - - -void AesGenTables(void) -{ - unsigned i; - for (i = 0; i < 256; i++) - InvS[Sbox[i]] = (Byte)i; - - for (i = 0; i < 256; i++) - { - { - const UInt32 a1 = Sbox[i]; - const UInt32 a2 = xtime(a1); - const UInt32 a3 = a2 ^ a1; - TT(0)[i] = Ui32(a2, a1, a1, a3); - TT(1)[i] = Ui32(a3, a2, a1, a1); - TT(2)[i] = Ui32(a1, a3, a2, a1); - TT(3)[i] = Ui32(a1, a1, a3, a2); - } - { - const UInt32 a1 = InvS[i]; - const UInt32 a2 = xtime(a1); - const UInt32 a4 = xtime(a2); - const UInt32 a8 = xtime(a4); - const UInt32 a9 = a8 ^ a1; - const UInt32 aB = a8 ^ a2 ^ a1; - const UInt32 aD = a8 ^ a4 ^ a1; - const UInt32 aE = a8 ^ a4 ^ a2; - DD(0)[i] = Ui32(aE, a9, aD, aB); - DD(1)[i] = Ui32(aB, aE, a9, aD); - DD(2)[i] = Ui32(aD, aB, aE, a9); - DD(3)[i] = Ui32(a9, aD, aB, aE); - } - } - - { - AES_CODE_FUNC d = AesCbc_Decode; - #ifndef Z7_SFX - AES_CODE_FUNC e = AesCbc_Encode; - AES_CODE_FUNC c = AesCtr_Code; - UInt32 flags = 0; - #endif - - #ifdef USE_HW_AES - if (CPU_IsSupported_AES()) - { - // #pragma message ("AES HW") - PRF(printf("\n===AES HW\n")); - d = AesCbc_Decode_HW; - - #ifndef Z7_SFX - e = AesCbc_Encode_HW; - c = AesCtr_Code_HW; - flags = k_Aes_SupportedFunctions_HW; - #endif - - #ifdef MY_CPU_X86_OR_AMD64 - if (CPU_IsSupported_VAES_AVX2()) - { - PRF(printf("\n===vaes avx2\n")); - d = AesCbc_Decode_HW_256; - #ifndef Z7_SFX - c = AesCtr_Code_HW_256; - flags |= k_Aes_SupportedFunctions_HW_256; - #endif - } - #endif - } - #endif - - g_AesCbc_Decode = d; - #ifndef Z7_SFX - g_AesCbc_Encode = e; - g_AesCtr_Code = c; - g_Aes_SupportedFunctions_Flags = flags; - #endif - } -} - - -#define HT(i, x, s) TT(x)[gb(x, s[(i + x) & 3])] - -#define HT4(m, i, s, p) m[i] = \ - HT(i, 0, s) ^ \ - HT(i, 1, s) ^ \ - HT(i, 2, s) ^ \ - HT(i, 3, s) ^ w[p + i] - -#define HT16(m, s, p) \ - HT4(m, 0, s, p); \ - HT4(m, 1, s, p); \ - HT4(m, 2, s, p); \ - HT4(m, 3, s, p); \ - -#define FT(i, x) Sbox[gb(x, m[(i + x) & 3])] -#define FT4(i) dest[i] = Ui32(FT(i, 0), FT(i, 1), FT(i, 2), FT(i, 3)) ^ w[i]; - - -#define HD(i, x, s) DD(x)[gb(x, s[(i - x) & 3])] - -#define HD4(m, i, s, p) m[i] = \ - HD(i, 0, s) ^ \ - HD(i, 1, s) ^ \ - HD(i, 2, s) ^ \ - HD(i, 3, s) ^ w[p + i]; - -#define HD16(m, s, p) \ - HD4(m, 0, s, p); \ - HD4(m, 1, s, p); \ - HD4(m, 2, s, p); \ - HD4(m, 3, s, p); \ - -#define FD(i, x) InvS[gb(x, m[(i - x) & 3])] -#define FD4(i) dest[i] = Ui32(FD(i, 0), FD(i, 1), FD(i, 2), FD(i, 3)) ^ w[i]; - -void Z7_FASTCALL Aes_SetKey_Enc(UInt32 *w, const Byte *key, unsigned keySize) -{ - unsigned i, m; - const UInt32 *wLim; - UInt32 t; - UInt32 rcon = 1; - - keySize /= 4; - w[0] = ((UInt32)keySize / 2) + 3; - w += 4; - - for (i = 0; i < keySize; i++, key += 4) - w[i] = GetUi32(key); - - t = w[(size_t)keySize - 1]; - wLim = w + (size_t)keySize * 3 + 28; - m = 0; - do - { - if (m == 0) - { - t = Ui32(Sbox[gb1(t)] ^ rcon, Sbox[gb2(t)], Sbox[gb3(t)], Sbox[gb0(t)]); - rcon <<= 1; - if (rcon & 0x100) - rcon = 0x1b; - m = keySize; - } - else if (m == 4 && keySize > 6) - t = Ui32(Sbox[gb0(t)], Sbox[gb1(t)], Sbox[gb2(t)], Sbox[gb3(t)]); - m--; - t ^= w[0]; - w[keySize] = t; - } - while (++w != wLim); -} - -void Z7_FASTCALL Aes_SetKey_Dec(UInt32 *w, const Byte *key, unsigned keySize) -{ - unsigned i, num; - Aes_SetKey_Enc(w, key, keySize); - num = keySize + 20; - w += 8; - for (i = 0; i < num; i++) - { - UInt32 r = w[i]; - w[i] = - DD(0)[Sbox[gb0(r)]] ^ - DD(1)[Sbox[gb1(r)]] ^ - DD(2)[Sbox[gb2(r)]] ^ - DD(3)[Sbox[gb3(r)]]; - } -} - -/* Aes_Encode and Aes_Decode functions work with little-endian words. - src and dest are pointers to 4 UInt32 words. - src and dest can point to same block */ - -// Z7_FORCE_INLINE -static void Aes_Encode(const UInt32 *w, UInt32 *dest, const UInt32 *src) -{ - UInt32 s[4]; - UInt32 m[4]; - UInt32 numRounds2 = w[0]; - w += 4; - s[0] = src[0] ^ w[0]; - s[1] = src[1] ^ w[1]; - s[2] = src[2] ^ w[2]; - s[3] = src[3] ^ w[3]; - w += 4; - for (;;) - { - HT16(m, s, 0) - if (--numRounds2 == 0) - break; - HT16(s, m, 4) - w += 8; - } - w += 4; - FT4(0) - FT4(1) - FT4(2) - FT4(3) -} - -Z7_FORCE_INLINE -static void Aes_Decode(const UInt32 *w, UInt32 *dest, const UInt32 *src) -{ - UInt32 s[4]; - UInt32 m[4]; - UInt32 numRounds2 = w[0]; - w += 4 + numRounds2 * 8; - s[0] = src[0] ^ w[0]; - s[1] = src[1] ^ w[1]; - s[2] = src[2] ^ w[2]; - s[3] = src[3] ^ w[3]; - for (;;) - { - w -= 8; - HD16(m, s, 4) - if (--numRounds2 == 0) - break; - HD16(s, m, 0) - } - FD4(0) - FD4(1) - FD4(2) - FD4(3) -} - -void AesCbc_Init(UInt32 *p, const Byte *iv) -{ - unsigned i; - for (i = 0; i < 4; i++) - p[i] = GetUi32(iv + i * 4); -} - -void Z7_FASTCALL AesCbc_Encode(UInt32 *p, Byte *data, size_t numBlocks) -{ - for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) - { - p[0] ^= GetUi32(data); - p[1] ^= GetUi32(data + 4); - p[2] ^= GetUi32(data + 8); - p[3] ^= GetUi32(data + 12); - - Aes_Encode(p + 4, p, p); - - SetUi32(data, p[0]) - SetUi32(data + 4, p[1]) - SetUi32(data + 8, p[2]) - SetUi32(data + 12, p[3]) - } -} - -void Z7_FASTCALL AesCbc_Decode(UInt32 *p, Byte *data, size_t numBlocks) -{ - UInt32 in[4], out[4]; - for (; numBlocks != 0; numBlocks--, data += AES_BLOCK_SIZE) - { - in[0] = GetUi32(data); - in[1] = GetUi32(data + 4); - in[2] = GetUi32(data + 8); - in[3] = GetUi32(data + 12); - - Aes_Decode(p + 4, out, in); - - SetUi32(data, p[0] ^ out[0]) - SetUi32(data + 4, p[1] ^ out[1]) - SetUi32(data + 8, p[2] ^ out[2]) - SetUi32(data + 12, p[3] ^ out[3]) - - p[0] = in[0]; - p[1] = in[1]; - p[2] = in[2]; - p[3] = in[3]; - } -} - -void Z7_FASTCALL AesCtr_Code(UInt32 *p, Byte *data, size_t numBlocks) -{ - for (; numBlocks != 0; numBlocks--) - { - UInt32 temp[4]; - unsigned i; - - if (++p[0] == 0) - p[1]++; - - Aes_Encode(p + 4, temp, p); - - for (i = 0; i < 4; i++, data += 4) - { - const UInt32 t = temp[i]; - - #ifdef MY_CPU_LE_UNALIGN - *((UInt32 *)(void *)data) ^= t; - #else - data[0] = (Byte)(data[0] ^ (t & 0xFF)); - data[1] = (Byte)(data[1] ^ ((t >> 8) & 0xFF)); - data[2] = (Byte)(data[2] ^ ((t >> 16) & 0xFF)); - data[3] = (Byte)(data[3] ^ ((t >> 24))); - #endif - } - } -} - -#undef xtime -#undef Ui32 -#undef gb0 -#undef gb1 -#undef gb2 -#undef gb3 -#undef gb -#undef TT -#undef DD -#undef USE_HW_AES -#undef PRF diff --git a/libraries/lzma/C/Aes.h b/libraries/lzma/C/Aes.h deleted file mode 100644 index 7f0182ac0..000000000 --- a/libraries/lzma/C/Aes.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Aes.h -- AES encryption / decryption -2023-04-02 : Igor Pavlov : Public domain */ - -#ifndef ZIP7_INC_AES_H -#define ZIP7_INC_AES_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define AES_BLOCK_SIZE 16 - -/* Call AesGenTables one time before other AES functions */ -void AesGenTables(void); - -/* UInt32 pointers must be 16-byte aligned */ - -/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */ -#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4) - -/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */ -/* keySize = 16 or 24 or 32 (bytes) */ -typedef void (Z7_FASTCALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize); -void Z7_FASTCALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize); -void Z7_FASTCALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize); - -/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */ -void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */ - -/* data - 16-byte aligned pointer to data */ -/* numBlocks - the number of 16-byte blocks in data array */ -typedef void (Z7_FASTCALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks); - -extern AES_CODE_FUNC g_AesCbc_Decode; -#ifndef Z7_SFX -extern AES_CODE_FUNC g_AesCbc_Encode; -extern AES_CODE_FUNC g_AesCtr_Code; -#define k_Aes_SupportedFunctions_HW (1 << 2) -#define k_Aes_SupportedFunctions_HW_256 (1 << 3) -extern UInt32 g_Aes_SupportedFunctions_Flags; -#endif - - -#define Z7_DECLARE_AES_CODE_FUNC(funcName) \ - void Z7_FASTCALL funcName(UInt32 *ivAes, Byte *data, size_t numBlocks); - -Z7_DECLARE_AES_CODE_FUNC (AesCbc_Encode) -Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode) -Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code) - -Z7_DECLARE_AES_CODE_FUNC (AesCbc_Encode_HW) -Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode_HW) -Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code_HW) - -Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode_HW_256) -Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code_HW_256) - -EXTERN_C_END - -#endif diff --git a/libraries/lzma/C/AesOpt.c b/libraries/lzma/C/AesOpt.c deleted file mode 100644 index cfa6413f4..000000000 --- a/libraries/lzma/C/AesOpt.c +++ /dev/null @@ -1,840 +0,0 @@ -/* AesOpt.c -- AES optimized code for x86 AES hardware instructions -2023-04-02 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Aes.h" -#include "CpuArch.h" - -#ifdef MY_CPU_X86_OR_AMD64 - - #if defined(__INTEL_COMPILER) - #if (__INTEL_COMPILER >= 1110) - #define USE_INTEL_AES - #if (__INTEL_COMPILER >= 1900) - #define USE_INTEL_VAES - #endif - #endif - #elif defined(__clang__) && (__clang_major__ > 3 || __clang_major__ == 3 && __clang_minor__ >= 8) \ - || defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 4) - #define USE_INTEL_AES - #if !defined(__AES__) - #define ATTRIB_AES __attribute__((__target__("aes"))) - #endif - #if defined(__clang__) && (__clang_major__ >= 8) \ - || defined(__GNUC__) && (__GNUC__ >= 8) - #define USE_INTEL_VAES - #if !defined(__AES__) || !defined(__VAES__) || !defined(__AVX__) || !defined(__AVX2__) - #define ATTRIB_VAES __attribute__((__target__("aes,vaes,avx,avx2"))) - #endif - #endif - #elif defined(_MSC_VER) - #if (_MSC_VER > 1500) || (_MSC_FULL_VER >= 150030729) - #define USE_INTEL_AES - #if (_MSC_VER >= 1910) - #define USE_INTEL_VAES - #endif - #endif - #endif - -#ifndef ATTRIB_AES - #define ATTRIB_AES -#endif -#ifndef ATTRIB_VAES - #define ATTRIB_VAES -#endif - - -#ifdef USE_INTEL_AES - -#include - -#ifndef USE_INTEL_VAES -#define AES_TYPE_keys UInt32 -#define AES_TYPE_data Byte -// #define AES_TYPE_keys __m128i -// #define AES_TYPE_data __m128i -#endif - -#define AES_FUNC_START(name) \ - void Z7_FASTCALL name(UInt32 *ivAes, Byte *data8, size_t numBlocks) - // void Z7_FASTCALL name(__m128i *p, __m128i *data, size_t numBlocks) - -#define AES_FUNC_START2(name) \ -AES_FUNC_START (name); \ -ATTRIB_AES \ -AES_FUNC_START (name) - -#define MM_OP(op, dest, src) dest = op(dest, src); -#define MM_OP_m(op, src) MM_OP(op, m, src) - -#define MM_XOR( dest, src) MM_OP(_mm_xor_si128, dest, src) -#define AVX_XOR(dest, src) MM_OP(_mm256_xor_si256, dest, src) - - -AES_FUNC_START2 (AesCbc_Encode_HW) -{ - __m128i *p = (__m128i *)(void *)ivAes; - __m128i *data = (__m128i *)(void *)data8; - __m128i m = *p; - const __m128i k0 = p[2]; - const __m128i k1 = p[3]; - const UInt32 numRounds2 = *(const UInt32 *)(p + 1) - 1; - for (; numBlocks != 0; numBlocks--, data++) - { - UInt32 r = numRounds2; - const __m128i *w = p + 4; - __m128i temp = *data; - MM_XOR (temp, k0) - MM_XOR (m, temp) - MM_OP_m (_mm_aesenc_si128, k1) - do - { - MM_OP_m (_mm_aesenc_si128, w[0]) - MM_OP_m (_mm_aesenc_si128, w[1]) - w += 2; - } - while (--r); - MM_OP_m (_mm_aesenclast_si128, w[0]) - *data = m; - } - *p = m; -} - - -#define WOP_1(op) -#define WOP_2(op) WOP_1 (op) op (m1, 1) -#define WOP_3(op) WOP_2 (op) op (m2, 2) -#define WOP_4(op) WOP_3 (op) op (m3, 3) -#ifdef MY_CPU_AMD64 -#define WOP_5(op) WOP_4 (op) op (m4, 4) -#define WOP_6(op) WOP_5 (op) op (m5, 5) -#define WOP_7(op) WOP_6 (op) op (m6, 6) -#define WOP_8(op) WOP_7 (op) op (m7, 7) -#endif -/* -#define WOP_9(op) WOP_8 (op) op (m8, 8); -#define WOP_10(op) WOP_9 (op) op (m9, 9); -#define WOP_11(op) WOP_10(op) op (m10, 10); -#define WOP_12(op) WOP_11(op) op (m11, 11); -#define WOP_13(op) WOP_12(op) op (m12, 12); -#define WOP_14(op) WOP_13(op) op (m13, 13); -*/ - -#ifdef MY_CPU_AMD64 - #define NUM_WAYS 8 - #define WOP_M1 WOP_8 -#else - #define NUM_WAYS 4 - #define WOP_M1 WOP_4 -#endif - -#define WOP(op) op (m0, 0) WOP_M1(op) - - -#define DECLARE_VAR(reg, ii) __m128i reg; -#define LOAD_data( reg, ii) reg = data[ii]; -#define STORE_data( reg, ii) data[ii] = reg; -#if (NUM_WAYS > 1) -#define XOR_data_M1(reg, ii) MM_XOR (reg, data[ii- 1]) -#endif - -#define AVX_DECLARE_VAR(reg, ii) __m256i reg; -#define AVX_LOAD_data( reg, ii) reg = ((const __m256i *)(const void *)data)[ii]; -#define AVX_STORE_data( reg, ii) ((__m256i *)(void *)data)[ii] = reg; -#define AVX_XOR_data_M1(reg, ii) AVX_XOR (reg, (((const __m256i *)(const void *)(data - 1))[ii])) - -#define MM_OP_key(op, reg) MM_OP(op, reg, key); - -#define AES_DEC( reg, ii) MM_OP_key (_mm_aesdec_si128, reg) -#define AES_DEC_LAST( reg, ii) MM_OP_key (_mm_aesdeclast_si128, reg) -#define AES_ENC( reg, ii) MM_OP_key (_mm_aesenc_si128, reg) -#define AES_ENC_LAST( reg, ii) MM_OP_key (_mm_aesenclast_si128, reg) -#define AES_XOR( reg, ii) MM_OP_key (_mm_xor_si128, reg) - - -#define AVX_AES_DEC( reg, ii) MM_OP_key (_mm256_aesdec_epi128, reg) -#define AVX_AES_DEC_LAST( reg, ii) MM_OP_key (_mm256_aesdeclast_epi128, reg) -#define AVX_AES_ENC( reg, ii) MM_OP_key (_mm256_aesenc_epi128, reg) -#define AVX_AES_ENC_LAST( reg, ii) MM_OP_key (_mm256_aesenclast_epi128, reg) -#define AVX_AES_XOR( reg, ii) MM_OP_key (_mm256_xor_si256, reg) - -#define CTR_START(reg, ii) MM_OP (_mm_add_epi64, ctr, one) reg = ctr; -#define CTR_END( reg, ii) MM_XOR (data[ii], reg) - -#define AVX_CTR_START(reg, ii) MM_OP (_mm256_add_epi64, ctr2, two) reg = _mm256_xor_si256(ctr2, key); -#define AVX_CTR_END( reg, ii) AVX_XOR (((__m256i *)(void *)data)[ii], reg) - -#define WOP_KEY(op, n) { \ - const __m128i key = w[n]; \ - WOP(op); } - -#define AVX_WOP_KEY(op, n) { \ - const __m256i key = w[n]; \ - WOP(op); } - - -#define WIDE_LOOP_START \ - dataEnd = data + numBlocks; \ - if (numBlocks >= NUM_WAYS) \ - { dataEnd -= NUM_WAYS; do { \ - - -#define WIDE_LOOP_END \ - data += NUM_WAYS; \ - } while (data <= dataEnd); \ - dataEnd += NUM_WAYS; } \ - - -#define SINGLE_LOOP \ - for (; data < dataEnd; data++) - - -#define NUM_AES_KEYS_MAX 15 - -#define WIDE_LOOP_START_AVX(OP) \ - dataEnd = data + numBlocks; \ - if (numBlocks >= NUM_WAYS * 2) \ - { __m256i keys[NUM_AES_KEYS_MAX]; \ - UInt32 ii; \ - OP \ - for (ii = 0; ii < numRounds; ii++) \ - keys[ii] = _mm256_broadcastsi128_si256(p[ii]); \ - dataEnd -= NUM_WAYS * 2; do { \ - - -#define WIDE_LOOP_END_AVX(OP) \ - data += NUM_WAYS * 2; \ - } while (data <= dataEnd); \ - dataEnd += NUM_WAYS * 2; \ - OP \ - _mm256_zeroupper(); \ - } \ - -/* MSVC for x86: If we don't call _mm256_zeroupper(), and -arch:IA32 is not specified, - MSVC still can insert vzeroupper instruction. */ - - -AES_FUNC_START2 (AesCbc_Decode_HW) -{ - __m128i *p = (__m128i *)(void *)ivAes; - __m128i *data = (__m128i *)(void *)data8; - __m128i iv = *p; - const __m128i *wStart = p + *(const UInt32 *)(p + 1) * 2 + 2 - 1; - const __m128i *dataEnd; - p += 2; - - WIDE_LOOP_START - { - const __m128i *w = wStart; - - WOP (DECLARE_VAR) - WOP (LOAD_data) - WOP_KEY (AES_XOR, 1) - - do - { - WOP_KEY (AES_DEC, 0) - w--; - } - while (w != p); - WOP_KEY (AES_DEC_LAST, 0) - - MM_XOR (m0, iv) - WOP_M1 (XOR_data_M1) - iv = data[NUM_WAYS - 1]; - WOP (STORE_data) - } - WIDE_LOOP_END - - SINGLE_LOOP - { - const __m128i *w = wStart - 1; - __m128i m = _mm_xor_si128 (w[2], *data); - do - { - MM_OP_m (_mm_aesdec_si128, w[1]) - MM_OP_m (_mm_aesdec_si128, w[0]) - w -= 2; - } - while (w != p); - MM_OP_m (_mm_aesdec_si128, w[1]) - MM_OP_m (_mm_aesdeclast_si128, w[0]) - - MM_XOR (m, iv) - iv = *data; - *data = m; - } - - p[-2] = iv; -} - - -AES_FUNC_START2 (AesCtr_Code_HW) -{ - __m128i *p = (__m128i *)(void *)ivAes; - __m128i *data = (__m128i *)(void *)data8; - __m128i ctr = *p; - UInt32 numRoundsMinus2 = *(const UInt32 *)(p + 1) * 2 - 1; - const __m128i *dataEnd; - __m128i one = _mm_cvtsi32_si128(1); - - p += 2; - - WIDE_LOOP_START - { - const __m128i *w = p; - UInt32 r = numRoundsMinus2; - WOP (DECLARE_VAR) - WOP (CTR_START) - WOP_KEY (AES_XOR, 0) - w += 1; - do - { - WOP_KEY (AES_ENC, 0) - w += 1; - } - while (--r); - WOP_KEY (AES_ENC_LAST, 0) - - WOP (CTR_END) - } - WIDE_LOOP_END - - SINGLE_LOOP - { - UInt32 numRounds2 = *(const UInt32 *)(p - 2 + 1) - 1; - const __m128i *w = p; - __m128i m; - MM_OP (_mm_add_epi64, ctr, one) - m = _mm_xor_si128 (ctr, p[0]); - w += 1; - do - { - MM_OP_m (_mm_aesenc_si128, w[0]) - MM_OP_m (_mm_aesenc_si128, w[1]) - w += 2; - } - while (--numRounds2); - MM_OP_m (_mm_aesenc_si128, w[0]) - MM_OP_m (_mm_aesenclast_si128, w[1]) - MM_XOR (*data, m) - } - - p[-2] = ctr; -} - - - -#ifdef USE_INTEL_VAES - -/* -GCC before 2013-Jun: - : - #ifdef __AVX__ - #include - #endif -GCC after 2013-Jun: - : - #include -CLANG 3.8+: -{ - : - #if !defined(_MSC_VER) || defined(__AVX__) - #include - #endif - - if (the compiler is clang for Windows and if global arch is not set for __AVX__) - [ if (defined(_MSC_VER) && !defined(__AVX__)) ] - { - doesn't include - and we have 2 ways to fix it: - 1) we can define required __AVX__ before - or - 2) we can include after - } -} - -If we include manually for GCC/CLANG, it's -required that must be included before . -*/ - -/* -#if defined(__clang__) && defined(_MSC_VER) -#define __AVX__ -#define __AVX2__ -#define __VAES__ -#endif -*/ - -#include -#if defined(__clang__) && defined(_MSC_VER) - #if !defined(__AVX__) - #include - #endif - #if !defined(__AVX2__) - #include - #endif - #if !defined(__VAES__) - #include - #endif -#endif // __clang__ && _MSC_VER - - -#define VAES_FUNC_START2(name) \ -AES_FUNC_START (name); \ -ATTRIB_VAES \ -AES_FUNC_START (name) - -VAES_FUNC_START2 (AesCbc_Decode_HW_256) -{ - __m128i *p = (__m128i *)(void *)ivAes; - __m128i *data = (__m128i *)(void *)data8; - __m128i iv = *p; - const __m128i *dataEnd; - UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1; - p += 2; - - WIDE_LOOP_START_AVX(;) - { - const __m256i *w = keys + numRounds - 2; - - WOP (AVX_DECLARE_VAR) - WOP (AVX_LOAD_data) - AVX_WOP_KEY (AVX_AES_XOR, 1) - - do - { - AVX_WOP_KEY (AVX_AES_DEC, 0) - w--; - } - while (w != keys); - AVX_WOP_KEY (AVX_AES_DEC_LAST, 0) - - AVX_XOR (m0, _mm256_setr_m128i(iv, data[0])) - WOP_M1 (AVX_XOR_data_M1) - iv = data[NUM_WAYS * 2 - 1]; - WOP (AVX_STORE_data) - } - WIDE_LOOP_END_AVX(;) - - SINGLE_LOOP - { - const __m128i *w = p + *(const UInt32 *)(p + 1 - 2) * 2 + 1 - 3; - __m128i m = _mm_xor_si128 (w[2], *data); - do - { - MM_OP_m (_mm_aesdec_si128, w[1]) - MM_OP_m (_mm_aesdec_si128, w[0]) - w -= 2; - } - while (w != p); - MM_OP_m (_mm_aesdec_si128, w[1]) - MM_OP_m (_mm_aesdeclast_si128, w[0]) - - MM_XOR (m, iv) - iv = *data; - *data = m; - } - - p[-2] = iv; -} - - -/* -SSE2: _mm_cvtsi32_si128 : movd -AVX: _mm256_setr_m128i : vinsertf128 -AVX2: _mm256_add_epi64 : vpaddq ymm, ymm, ymm - _mm256_extracti128_si256 : vextracti128 - _mm256_broadcastsi128_si256 : vbroadcasti128 -*/ - -#define AVX_CTR_LOOP_START \ - ctr2 = _mm256_setr_m128i(_mm_sub_epi64(ctr, one), ctr); \ - two = _mm256_setr_m128i(one, one); \ - two = _mm256_add_epi64(two, two); \ - -// two = _mm256_setr_epi64x(2, 0, 2, 0); - -#define AVX_CTR_LOOP_ENC \ - ctr = _mm256_extracti128_si256 (ctr2, 1); \ - -VAES_FUNC_START2 (AesCtr_Code_HW_256) -{ - __m128i *p = (__m128i *)(void *)ivAes; - __m128i *data = (__m128i *)(void *)data8; - __m128i ctr = *p; - UInt32 numRounds = *(const UInt32 *)(p + 1) * 2 + 1; - const __m128i *dataEnd; - __m128i one = _mm_cvtsi32_si128(1); - __m256i ctr2, two; - p += 2; - - WIDE_LOOP_START_AVX (AVX_CTR_LOOP_START) - { - const __m256i *w = keys; - UInt32 r = numRounds - 2; - WOP (AVX_DECLARE_VAR) - AVX_WOP_KEY (AVX_CTR_START, 0) - - w += 1; - do - { - AVX_WOP_KEY (AVX_AES_ENC, 0) - w += 1; - } - while (--r); - AVX_WOP_KEY (AVX_AES_ENC_LAST, 0) - - WOP (AVX_CTR_END) - } - WIDE_LOOP_END_AVX (AVX_CTR_LOOP_ENC) - - SINGLE_LOOP - { - UInt32 numRounds2 = *(const UInt32 *)(p - 2 + 1) - 1; - const __m128i *w = p; - __m128i m; - MM_OP (_mm_add_epi64, ctr, one) - m = _mm_xor_si128 (ctr, p[0]); - w += 1; - do - { - MM_OP_m (_mm_aesenc_si128, w[0]) - MM_OP_m (_mm_aesenc_si128, w[1]) - w += 2; - } - while (--numRounds2); - MM_OP_m (_mm_aesenc_si128, w[0]) - MM_OP_m (_mm_aesenclast_si128, w[1]) - MM_XOR (*data, m) - } - - p[-2] = ctr; -} - -#endif // USE_INTEL_VAES - -#else // USE_INTEL_AES - -/* no USE_INTEL_AES */ - -#pragma message("AES HW_SW stub was used") - -#define AES_TYPE_keys UInt32 -#define AES_TYPE_data Byte - -#define AES_FUNC_START(name) \ - void Z7_FASTCALL name(UInt32 *p, Byte *data, size_t numBlocks) \ - -#define AES_COMPAT_STUB(name) \ - AES_FUNC_START(name); \ - AES_FUNC_START(name ## _HW) \ - { name(p, data, numBlocks); } - -AES_COMPAT_STUB (AesCbc_Encode) -AES_COMPAT_STUB (AesCbc_Decode) -AES_COMPAT_STUB (AesCtr_Code) - -#endif // USE_INTEL_AES - - -#ifndef USE_INTEL_VAES - -#pragma message("VAES HW_SW stub was used") - -#define VAES_COMPAT_STUB(name) \ - void Z7_FASTCALL name ## _256(UInt32 *p, Byte *data, size_t numBlocks); \ - void Z7_FASTCALL name ## _256(UInt32 *p, Byte *data, size_t numBlocks) \ - { name((AES_TYPE_keys *)(void *)p, (AES_TYPE_data *)(void *)data, numBlocks); } - -VAES_COMPAT_STUB (AesCbc_Decode_HW) -VAES_COMPAT_STUB (AesCtr_Code_HW) - -#endif // ! USE_INTEL_VAES - - -#elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) - - #if defined(__clang__) - #if (__clang_major__ >= 8) // fix that check - #define USE_HW_AES - #endif - #elif defined(__GNUC__) - #if (__GNUC__ >= 6) // fix that check - #define USE_HW_AES - #endif - #elif defined(_MSC_VER) - #if _MSC_VER >= 1910 - #define USE_HW_AES - #endif - #endif - -#ifdef USE_HW_AES - -// #pragma message("=== AES HW === ") - -#if defined(__clang__) || defined(__GNUC__) - #ifdef MY_CPU_ARM64 - #define ATTRIB_AES __attribute__((__target__("+crypto"))) - #else - #define ATTRIB_AES __attribute__((__target__("fpu=crypto-neon-fp-armv8"))) - #endif -#else - // _MSC_VER - // for arm32 - #define _ARM_USE_NEW_NEON_INTRINSICS -#endif - -#ifndef ATTRIB_AES - #define ATTRIB_AES -#endif - -#if defined(_MSC_VER) && defined(MY_CPU_ARM64) -#include -#else -#include -#endif - -typedef uint8x16_t v128; - -#define AES_FUNC_START(name) \ - void Z7_FASTCALL name(UInt32 *ivAes, Byte *data8, size_t numBlocks) - // void Z7_FASTCALL name(v128 *p, v128 *data, size_t numBlocks) - -#define AES_FUNC_START2(name) \ -AES_FUNC_START (name); \ -ATTRIB_AES \ -AES_FUNC_START (name) - -#define MM_OP(op, dest, src) dest = op(dest, src); -#define MM_OP_m(op, src) MM_OP(op, m, src) -#define MM_OP1_m(op) m = op(m); - -#define MM_XOR( dest, src) MM_OP(veorq_u8, dest, src) -#define MM_XOR_m( src) MM_XOR(m, src) - -#define AES_E_m(k) MM_OP_m (vaeseq_u8, k) -#define AES_E_MC_m(k) AES_E_m (k) MM_OP1_m(vaesmcq_u8) - - -AES_FUNC_START2 (AesCbc_Encode_HW) -{ - v128 *p = (v128*)(void*)ivAes; - v128 *data = (v128*)(void*)data8; - v128 m = *p; - const v128 k0 = p[2]; - const v128 k1 = p[3]; - const v128 k2 = p[4]; - const v128 k3 = p[5]; - const v128 k4 = p[6]; - const v128 k5 = p[7]; - const v128 k6 = p[8]; - const v128 k7 = p[9]; - const v128 k8 = p[10]; - const v128 k9 = p[11]; - const UInt32 numRounds2 = *(const UInt32 *)(p + 1); - const v128 *w = p + ((size_t)numRounds2 * 2); - const v128 k_z1 = w[1]; - const v128 k_z0 = w[2]; - for (; numBlocks != 0; numBlocks--, data++) - { - MM_XOR_m (*data); - AES_E_MC_m (k0) - AES_E_MC_m (k1) - AES_E_MC_m (k2) - AES_E_MC_m (k3) - AES_E_MC_m (k4) - AES_E_MC_m (k5) - AES_E_MC_m (k6) - AES_E_MC_m (k7) - AES_E_MC_m (k8) - if (numRounds2 >= 6) - { - AES_E_MC_m (k9) - AES_E_MC_m (p[12]) - if (numRounds2 != 6) - { - AES_E_MC_m (p[13]) - AES_E_MC_m (p[14]) - } - } - AES_E_m (k_z1) - MM_XOR_m (k_z0); - *data = m; - } - *p = m; -} - - -#define WOP_1(op) -#define WOP_2(op) WOP_1 (op) op (m1, 1) -#define WOP_3(op) WOP_2 (op) op (m2, 2) -#define WOP_4(op) WOP_3 (op) op (m3, 3) -#define WOP_5(op) WOP_4 (op) op (m4, 4) -#define WOP_6(op) WOP_5 (op) op (m5, 5) -#define WOP_7(op) WOP_6 (op) op (m6, 6) -#define WOP_8(op) WOP_7 (op) op (m7, 7) - - #define NUM_WAYS 8 - #define WOP_M1 WOP_8 - -#define WOP(op) op (m0, 0) WOP_M1(op) - -#define DECLARE_VAR(reg, ii) v128 reg; -#define LOAD_data( reg, ii) reg = data[ii]; -#define STORE_data( reg, ii) data[ii] = reg; -#if (NUM_WAYS > 1) -#define XOR_data_M1(reg, ii) MM_XOR (reg, data[ii- 1]) -#endif - -#define MM_OP_key(op, reg) MM_OP (op, reg, key) - -#define AES_D_m(k) MM_OP_m (vaesdq_u8, k) -#define AES_D_IMC_m(k) AES_D_m (k) MM_OP1_m (vaesimcq_u8) - -#define AES_XOR( reg, ii) MM_OP_key (veorq_u8, reg) -#define AES_D( reg, ii) MM_OP_key (vaesdq_u8, reg) -#define AES_E( reg, ii) MM_OP_key (vaeseq_u8, reg) - -#define AES_D_IMC( reg, ii) AES_D (reg, ii) reg = vaesimcq_u8(reg); -#define AES_E_MC( reg, ii) AES_E (reg, ii) reg = vaesmcq_u8(reg); - -#define CTR_START(reg, ii) MM_OP (vaddq_u64, ctr, one) reg = vreinterpretq_u8_u64(ctr); -#define CTR_END( reg, ii) MM_XOR (data[ii], reg) - -#define WOP_KEY(op, n) { \ - const v128 key = w[n]; \ - WOP(op) } - -#define WIDE_LOOP_START \ - dataEnd = data + numBlocks; \ - if (numBlocks >= NUM_WAYS) \ - { dataEnd -= NUM_WAYS; do { \ - -#define WIDE_LOOP_END \ - data += NUM_WAYS; \ - } while (data <= dataEnd); \ - dataEnd += NUM_WAYS; } \ - -#define SINGLE_LOOP \ - for (; data < dataEnd; data++) - - -AES_FUNC_START2 (AesCbc_Decode_HW) -{ - v128 *p = (v128*)(void*)ivAes; - v128 *data = (v128*)(void*)data8; - v128 iv = *p; - const v128 *wStart = p + ((size_t)*(const UInt32 *)(p + 1)) * 2; - const v128 *dataEnd; - p += 2; - - WIDE_LOOP_START - { - const v128 *w = wStart; - WOP (DECLARE_VAR) - WOP (LOAD_data) - WOP_KEY (AES_D_IMC, 2) - do - { - WOP_KEY (AES_D_IMC, 1) - WOP_KEY (AES_D_IMC, 0) - w -= 2; - } - while (w != p); - WOP_KEY (AES_D, 1) - WOP_KEY (AES_XOR, 0) - MM_XOR (m0, iv); - WOP_M1 (XOR_data_M1) - iv = data[NUM_WAYS - 1]; - WOP (STORE_data) - } - WIDE_LOOP_END - - SINGLE_LOOP - { - const v128 *w = wStart; - v128 m = *data; - AES_D_IMC_m (w[2]) - do - { - AES_D_IMC_m (w[1]); - AES_D_IMC_m (w[0]); - w -= 2; - } - while (w != p); - AES_D_m (w[1]); - MM_XOR_m (w[0]); - MM_XOR_m (iv); - iv = *data; - *data = m; - } - - p[-2] = iv; -} - - -AES_FUNC_START2 (AesCtr_Code_HW) -{ - v128 *p = (v128*)(void*)ivAes; - v128 *data = (v128*)(void*)data8; - uint64x2_t ctr = vreinterpretq_u64_u8(*p); - const v128 *wEnd = p + ((size_t)*(const UInt32 *)(p + 1)) * 2; - const v128 *dataEnd; - uint64x2_t one = vdupq_n_u64(0); - one = vsetq_lane_u64(1, one, 0); - p += 2; - - WIDE_LOOP_START - { - const v128 *w = p; - WOP (DECLARE_VAR) - WOP (CTR_START) - do - { - WOP_KEY (AES_E_MC, 0) - WOP_KEY (AES_E_MC, 1) - w += 2; - } - while (w != wEnd); - WOP_KEY (AES_E_MC, 0) - WOP_KEY (AES_E, 1) - WOP_KEY (AES_XOR, 2) - WOP (CTR_END) - } - WIDE_LOOP_END - - SINGLE_LOOP - { - const v128 *w = p; - v128 m; - CTR_START (m, 0); - do - { - AES_E_MC_m (w[0]); - AES_E_MC_m (w[1]); - w += 2; - } - while (w != wEnd); - AES_E_MC_m (w[0]) - AES_E_m (w[1]) - MM_XOR_m (w[2]) - CTR_END (m, 0) - } - - p[-2] = vreinterpretq_u8_u64(ctr); -} - -#endif // USE_HW_AES - -#endif // MY_CPU_ARM_OR_ARM64 - -#undef NUM_WAYS -#undef WOP_M1 -#undef WOP -#undef DECLARE_VAR -#undef LOAD_data -#undef STORE_data -#undef USE_INTEL_AES -#undef USE_HW_AES diff --git a/libraries/lzma/C/BraIA64.c b/libraries/lzma/C/BraIA64.c deleted file mode 100644 index 9dfe3e289..000000000 --- a/libraries/lzma/C/BraIA64.c +++ /dev/null @@ -1,14 +0,0 @@ -/* BraIA64.c -- Converter for IA-64 code -2023-02-20 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -// the code was moved to Bra.c - -#ifdef _MSC_VER -#pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty -#endif - -#if defined(__clang__) -#pragma GCC diagnostic ignored "-Wempty-translation-unit" -#endif diff --git a/libraries/lzma/C/Lzma86.h b/libraries/lzma/C/Lzma86.h deleted file mode 100644 index e7707e2c4..000000000 --- a/libraries/lzma/C/Lzma86.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Lzma86.h -- LZMA + x86 (BCJ) Filter -2023-03-03 : Igor Pavlov : Public domain */ - -#ifndef ZIP7_INC_LZMA86_H -#define ZIP7_INC_LZMA86_H - -#include "7zTypes.h" - -EXTERN_C_BEGIN - -#define LZMA86_SIZE_OFFSET (1 + 5) -#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8) - -/* -It's an example for LZMA + x86 Filter use. -You can use .lzma86 extension, if you write that stream to file. -.lzma86 header adds one additional byte to standard .lzma header. -.lzma86 header (14 bytes): - Offset Size Description - 0 1 = 0 - no filter, pure LZMA - = 1 - x86 filter + LZMA - 1 1 lc, lp and pb in encoded form - 2 4 dictSize (little endian) - 6 8 uncompressed size (little endian) - - -Lzma86_Encode -------------- -level - compression level: 0 <= level <= 9, the default value for "level" is 5. - -dictSize - The dictionary size in bytes. The maximum value is - 128 MB = (1 << 27) bytes for 32-bit version - 1 GB = (1 << 30) bytes for 64-bit version - The default value is 16 MB = (1 << 24) bytes, for level = 5. - It's recommended to use the dictionary that is larger than 4 KB and - that can be calculated as (1 << N) or (3 << N) sizes. - For better compression ratio dictSize must be >= inSize. - -filterMode: - SZ_FILTER_NO - no Filter - SZ_FILTER_YES - x86 Filter - SZ_FILTER_AUTO - it tries both alternatives to select best. - Encoder will use 2 or 3 passes: - 2 passes when FILTER_NO provides better compression. - 3 passes when FILTER_YES provides better compression. - -Lzma86Encode allocates Data with MyAlloc functions. -RAM Requirements for compressing: - RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize - filterMode FilterBlockSize - SZ_FILTER_NO 0 - SZ_FILTER_YES inSize - SZ_FILTER_AUTO inSize - - -Return code: - SZ_OK - OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_PARAM - Incorrect paramater - SZ_ERROR_OUTPUT_EOF - output buffer overflow - SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) -*/ - -enum ESzFilterMode -{ - SZ_FILTER_NO, - SZ_FILTER_YES, - SZ_FILTER_AUTO -}; - -SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, - int level, UInt32 dictSize, int filterMode); - - -/* -Lzma86_GetUnpackSize: - In: - src - input data - srcLen - input data size - Out: - unpackSize - size of uncompressed stream - Return code: - SZ_OK - OK - SZ_ERROR_INPUT_EOF - Error in headers -*/ - -SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize); - -/* -Lzma86_Decode: - In: - dest - output data - destLen - output data size - src - input data - srcLen - input data size - Out: - destLen - processed output size - srcLen - processed input size - Return code: - SZ_OK - OK - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - unsupported file - SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer -*/ - -SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen); - -EXTERN_C_END - -#endif diff --git a/libraries/lzma/C/Lzma86Dec.c b/libraries/lzma/C/Lzma86Dec.c deleted file mode 100644 index f094d4c35..000000000 --- a/libraries/lzma/C/Lzma86Dec.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder -2023-03-03 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include "Lzma86.h" - -#include "Alloc.h" -#include "Bra.h" -#include "LzmaDec.h" - -SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) -{ - unsigned i; - if (srcLen < LZMA86_HEADER_SIZE) - return SZ_ERROR_INPUT_EOF; - *unpackSize = 0; - for (i = 0; i < sizeof(UInt64); i++) - *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i); - return SZ_OK; -} - -SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen) -{ - SRes res; - int useFilter; - SizeT inSizePure; - ELzmaStatus status; - - if (*srcLen < LZMA86_HEADER_SIZE) - return SZ_ERROR_INPUT_EOF; - - useFilter = src[0]; - - if (useFilter > 1) - { - *destLen = 0; - return SZ_ERROR_UNSUPPORTED; - } - - inSizePure = *srcLen - LZMA86_HEADER_SIZE; - res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure, - src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc); - *srcLen = inSizePure + LZMA86_HEADER_SIZE; - if (res != SZ_OK) - return res; - if (useFilter == 1) - { - UInt32 x86State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; - z7_BranchConvSt_X86_Dec(dest, *destLen, 0, &x86State); - } - return SZ_OK; -} diff --git a/libraries/lzma/C/Lzma86Enc.c b/libraries/lzma/C/Lzma86Enc.c deleted file mode 100644 index 0cdde1c9a..000000000 --- a/libraries/lzma/C/Lzma86Enc.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder -2023-03-03 : Igor Pavlov : Public domain */ - -#include "Precomp.h" - -#include - -#include "Lzma86.h" - -#include "Alloc.h" -#include "Bra.h" -#include "LzmaEnc.h" - -int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, - int level, UInt32 dictSize, int filterMode) -{ - size_t outSize2 = *destLen; - Byte *filteredStream; - BoolInt useFilter; - int mainResult = SZ_ERROR_OUTPUT_EOF; - CLzmaEncProps props; - LzmaEncProps_Init(&props); - props.level = level; - props.dictSize = dictSize; - - *destLen = 0; - if (outSize2 < LZMA86_HEADER_SIZE) - return SZ_ERROR_OUTPUT_EOF; - - { - int i; - UInt64 t = srcLen; - for (i = 0; i < 8; i++, t >>= 8) - dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; - } - - filteredStream = 0; - useFilter = (filterMode != SZ_FILTER_NO); - if (useFilter) - { - if (srcLen != 0) - { - filteredStream = (Byte *)MyAlloc(srcLen); - if (filteredStream == 0) - return SZ_ERROR_MEM; - memcpy(filteredStream, src, srcLen); - } - { - UInt32 x86State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; - z7_BranchConvSt_X86_Enc(filteredStream, srcLen, 0, &x86State); - } - } - - { - size_t minSize = 0; - BoolInt bestIsFiltered = False; - - /* passes for SZ_FILTER_AUTO: - 0 - BCJ + LZMA - 1 - LZMA - 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. - */ - int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; - - int i; - for (i = 0; i < numPasses; i++) - { - size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; - size_t outPropsSize = 5; - SRes curRes; - BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); - if (curModeIsFiltered && !bestIsFiltered) - break; - if (useFilter && i == 0) - curModeIsFiltered = True; - - curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, - curModeIsFiltered ? filteredStream : src, srcLen, - &props, dest + 1, &outPropsSize, 0, - NULL, &g_Alloc, &g_Alloc); - - if (curRes != SZ_ERROR_OUTPUT_EOF) - { - if (curRes != SZ_OK) - { - mainResult = curRes; - break; - } - if (outSizeProcessed <= minSize || mainResult != SZ_OK) - { - minSize = outSizeProcessed; - bestIsFiltered = curModeIsFiltered; - mainResult = SZ_OK; - } - } - } - dest[0] = (Byte)(bestIsFiltered ? 1 : 0); - *destLen = LZMA86_HEADER_SIZE + minSize; - } - if (useFilter) - MyFree(filteredStream); - return mainResult; -} diff --git a/libraries/lzma/CMakeLists.txt b/libraries/lzma/CMakeLists.txt index 3ef9184bd..1d07f87e7 100644 --- a/libraries/lzma/CMakeLists.txt +++ b/libraries/lzma/CMakeLists.txt @@ -14,14 +14,11 @@ add_library( lzma STATIC C/7zDec.c C/7zFile.c C/7zStream.c - C/Aes.c - C/AesOpt.c C/Alloc.c C/Bcj2.c C/Bcj2Enc.c C/Bra.c C/Bra86.c - C/BraIA64.c C/CpuArch.c C/Delta.c C/DllSecur.c @@ -31,8 +28,6 @@ add_library( lzma STATIC C/Lzma2Dec.c C/Lzma2DecMt.c C/Lzma2Enc.c - C/Lzma86Dec.c - C/Lzma86Enc.c C/LzmaDec.c C/LzmaEnc.c C/LzmaLib.c From 61b7a4922ae0bdfaf84210ea3e7c3741e0887ff0 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 25 Sep 2023 17:02:34 +0600 Subject: [PATCH 191/223] Fix typo --- libraries/lzma/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/lzma/CMakeLists.txt b/libraries/lzma/CMakeLists.txt index 1d07f87e7..e1c668b29 100644 --- a/libraries/lzma/CMakeLists.txt +++ b/libraries/lzma/CMakeLists.txt @@ -1,6 +1,6 @@ make_release_only() -set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DZ7_PPMD_SUPPPORT" ) +set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DZ7_PPMD_SUPPORT" ) find_package(Threads) From 89535b803a8234898d66b9420eebd1442e09f512 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Oct 2023 18:42:24 +0200 Subject: [PATCH 192/223] Backend update from Raze. --- src/am_map.cpp | 2 +- src/common/audio/sound/s_sound.cpp | 10 +- src/common/filesystem/source/file_whres.cpp | 4 +- src/common/filesystem/source/file_zip.cpp | 2 +- src/common/filesystem/source/files.cpp | 6 +- .../filesystem/source/files_decompress.cpp | 10 +- src/common/filesystem/source/filesystem.cpp | 4 +- src/common/filesystem/source/resourcefile.cpp | 2 +- src/common/objects/dobjgc.cpp | 21 +- .../rendering/hwrenderer/data/hw_aabbtree.cpp | 8 +- src/common/scripting/frontend/zcc-parse.lemon | 10 + src/common/scripting/frontend/zcc_compile.cpp | 5 + src/common/scripting/frontend/zcc_compile.h | 1 + src/common/scripting/vm/vm.h | 5 + src/common/textures/animlib.cpp | 4 +- src/common/textures/formats/qoitexture.cpp | 4 +- src/common/textures/texturemanager.cpp | 4 +- src/common/thirdparty/math/asin.c | 6 +- src/common/thirdparty/math/atan.c | 8 +- src/common/thirdparty/math/cosh.c | 3 +- src/common/thirdparty/math/exp.c | 5 +- src/common/thirdparty/math/isnan.c | 9 +- src/common/thirdparty/math/log.c | 3 +- src/common/thirdparty/math/log10.c | 3 +- src/common/thirdparty/math/mtherr.c | 4 +- src/common/thirdparty/math/polevl.c | 10 +- src/common/thirdparty/math/pow.c | 6 +- src/common/thirdparty/math/powi.c | 4 +- src/common/thirdparty/math/sin.c | 9 +- src/common/thirdparty/math/sinh.c | 3 +- src/common/thirdparty/math/sqrt.c | 3 +- src/common/thirdparty/math/tan.c | 10 +- src/common/thirdparty/math/tanh.c | 3 +- src/common/utility/cmdlib.cpp | 40 +- src/common/utility/cmdlib.h | 7 +- src/common/utility/filereadermusicinterface.h | 6 +- src/common/utility/tarray.h | 4 +- src/common/utility/vectors.h | 437 ++++++++++-------- src/common/utility/zstring.cpp | 4 +- src/g_game.cpp | 2 +- src/g_levellocals.h | 12 +- src/gamedata/r_defs.h | 10 + src/maploader/polyobjects.cpp | 4 +- src/maploader/slopes.cpp | 2 +- src/maploader/specials.cpp | 2 +- src/playsim/actor.h | 10 +- src/playsim/bots/b_func.cpp | 2 +- src/playsim/bots/b_think.cpp | 2 +- src/playsim/fragglescript/t_func.cpp | 2 +- src/playsim/p_actionfunctions.cpp | 4 +- src/playsim/p_destructible.cpp | 2 +- src/playsim/p_effect.cpp | 2 +- src/playsim/p_enemy.cpp | 6 +- src/playsim/p_lnspec.cpp | 4 +- src/playsim/p_map.cpp | 70 +-- src/playsim/p_maputl.h | 5 + src/playsim/p_mobj.cpp | 26 +- src/playsim/p_secnodes.cpp | 4 +- src/playsim/p_sight.cpp | 2 +- src/playsim/p_teleport.cpp | 6 +- src/playsim/p_things.cpp | 6 +- src/playsim/p_trace.cpp | 2 +- src/playsim/po_man.cpp | 4 +- src/rendering/hwrenderer/scene/hw_bsp.cpp | 2 +- src/rendering/hwrenderer/scene/hw_portal.cpp | 2 +- src/rendering/hwrenderer/scene/hw_sprites.cpp | 4 +- src/rendering/r_utility.cpp | 2 +- .../swrenderer/line/r_farclip_line.cpp | 2 +- src/rendering/swrenderer/line/r_line.cpp | 2 +- .../swrenderer/plane/r_slopeplane.cpp | 2 +- .../swrenderer/scene/r_opaque_pass.cpp | 2 +- .../swrenderer/things/r_particle.cpp | 2 +- .../swrenderer/things/r_visiblesprite.cpp | 4 +- src/sound/s_doomsound.cpp | 4 +- 74 files changed, 506 insertions(+), 402 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index efd33ae70..bf0c61b7d 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2808,7 +2808,7 @@ void DAutomap::drawPlayers () int numarrowlines; double vh = players[consoleplayer].viewheight; - DVector2 pos = players[consoleplayer].camera->InterpolatedPosition(r_viewpoint.TicFrac); + DVector2 pos = players[consoleplayer].camera->InterpolatedPosition(r_viewpoint.TicFrac).XY(); pt.x = pos.X; pt.y = pos.Y; if (am_rotate == 1 || (am_rotate == 2 && viewactive)) diff --git a/src/common/audio/sound/s_sound.cpp b/src/common/audio/sound/s_sound.cpp index 58e4a981f..6f53e663e 100644 --- a/src/common/audio/sound/s_sound.cpp +++ b/src/common/audio/sound/s_sound.cpp @@ -1856,12 +1856,18 @@ CCMD(snd_listdrivers) GSnd->PrintDriversList(); } +//========================================================================== +// +// CCMD listsounds +// +//========================================================================== + CCMD(listsounds) { for (unsigned i = 1; i < soundEngine->GetNumSounds(); i++) { - auto S_sfx = soundEngine->GetSfx(FSoundID::fromInt(i)); - Printf("%04d: %s\n", i, S_sfx->name.GetChars()); + auto sfx = soundEngine->GetSfx(FSoundID::fromInt(i)); + Printf("%4d: name = %s, resId = %d, lumpnum = %d\n", i, sfx->name.GetChars(), sfx->ResourceId, sfx->lumpnum); } } diff --git a/src/common/filesystem/source/file_whres.cpp b/src/common/filesystem/source/file_whres.cpp index efdfd5d39..cef800a0f 100644 --- a/src/common/filesystem/source/file_whres.cpp +++ b/src/common/filesystem/source/file_whres.cpp @@ -91,8 +91,8 @@ bool FWHResFile::Open(LumpFilterInfo*) uint32_t offset = LittleLong(directory[k*3]) * 4096; uint32_t length = LittleLong(directory[k*3+1]); if (length == 0) break; - char num[5]; - snprintf(num, 5, "/%04d", k); + char num[6]; + snprintf(num, 6, "/%04d", k); std::string synthname = BaseName; synthname += num; Lumps[i].LumpNameSetup(synthname.c_str(), stringpool); diff --git a/src/common/filesystem/source/file_zip.cpp b/src/common/filesystem/source/file_zip.cpp index 9aa34095a..155cbf45a 100644 --- a/src/common/filesystem/source/file_zip.cpp +++ b/src/common/filesystem/source/file_zip.cpp @@ -298,7 +298,7 @@ bool FZipFile::Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf) // at least one of the more common definition lumps must be present. for (auto &p : filter->requiredPrefixes) { - if (name.find(name0 + p) == 0 || name.rfind(p) == ptrdiff_t(name.length() - p.length())) + if (name.find(name0 + p) == 0 || name.rfind(p) == size_t(name.length() - p.length())) { foundspeciallump = true; break; diff --git a/src/common/filesystem/source/files.cpp b/src/common/filesystem/source/files.cpp index a17f7c1b8..271831e36 100644 --- a/src/common/filesystem/source/files.cpp +++ b/src/common/filesystem/source/files.cpp @@ -142,10 +142,10 @@ public: char *Gets(char *strbuf, ptrdiff_t len) override { if (len <= 0 || len > 0x7fffffff || FilePos >= StartPos + Length) return nullptr; - char *p = fgets(strbuf, len, File); + char *p = fgets(strbuf, (int)len, File); if (p != nullptr) { - int old = FilePos; + ptrdiff_t old = FilePos; FilePos = ftell(File); if (FilePos - StartPos > Length) { @@ -240,7 +240,7 @@ public: char *p = mReader->Gets(strbuf, len); if (p != nullptr) { - int old = FilePos; + ptrdiff_t old = FilePos; FilePos = mReader->Tell(); if (FilePos - StartPos > Length) { diff --git a/src/common/filesystem/source/files_decompress.cpp b/src/common/filesystem/source/files_decompress.cpp index 28046ad41..6b32bf660 100644 --- a/src/common/filesystem/source/files_decompress.cpp +++ b/src/common/filesystem/source/files_decompress.cpp @@ -176,7 +176,7 @@ public: ptrdiff_t Read (void *buffer, ptrdiff_t len) override { - int err; + int err = 0; if (File == nullptr) { @@ -188,7 +188,7 @@ public: while (len > 0) { Stream.next_out = (Bytef*)buffer; - auto rlen = std::min(len, 0x40000000); + unsigned rlen = (unsigned)std::min(len, 0x40000000); Stream.avail_out = rlen; buffer = Stream.next_out + rlen; len -= rlen; @@ -304,7 +304,7 @@ public: while (len > 0) { Stream.next_out = (char*)buffer; - auto rlen = std::min(len, 0x40000000); + unsigned rlen = (unsigned)std::min(len, 0x40000000); Stream.avail_out = rlen; buffer = Stream.next_out + rlen; len -= rlen; @@ -798,7 +798,7 @@ public: if (len > 0xffffffff) len = 0xffffffff; // this format cannot be larger than 4GB. uint8_t *Out = (uint8_t*)buffer; - unsigned AvailOut = len; + ptrdiff_t AvailOut = len; do { @@ -812,7 +812,7 @@ public: break; } - unsigned int copy = std::min(Stream.InternalOut, AvailOut); + unsigned int copy = (unsigned)std::min(Stream.InternalOut, AvailOut); if(copy > 0) { memcpy(Out, Stream.WindowData, copy); diff --git a/src/common/filesystem/source/filesystem.cpp b/src/common/filesystem/source/filesystem.cpp index 1cdb6692b..0841ea68e 100644 --- a/src/common/filesystem/source/filesystem.cpp +++ b/src/common/filesystem/source/filesystem.cpp @@ -147,7 +147,7 @@ struct FileSystem::LumpRecord { std::string longName = LongName; ptrdiff_t encodedResID = longName.find_last_of(".{"); - if (resourceId == -1 && encodedResID != std::string::npos) + if (resourceId == -1 && (size_t)encodedResID != std::string::npos) { const char* p = LongName + encodedResID; char* q; @@ -978,7 +978,7 @@ void FileSystem::MoveLumpsInFolder(const char *path) int FileSystem::FindLump (const char *name, int *lastlump, bool anyns) { - if (*lastlump >= FileInfo.size()) return -1; + if ((size_t)*lastlump >= FileInfo.size()) return -1; union { char name8[8]; diff --git a/src/common/filesystem/source/resourcefile.cpp b/src/common/filesystem/source/resourcefile.cpp index 1da4aa04d..64c620c3b 100644 --- a/src/common/filesystem/source/resourcefile.cpp +++ b/src/common/filesystem/source/resourcefile.cpp @@ -415,7 +415,7 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterI ptrdiff_t lastpos = -1; std::string file; std::string& LumpFilter = filter->dotFilter; - while ((len = LumpFilter.find_first_of('.', lastpos+1)) != LumpFilter.npos) + while (size_t(len = LumpFilter.find_first_of('.', lastpos+1)) != LumpFilter.npos) { max -= FilterLumps(std::string(LumpFilter, 0, len), lumps, lumpsize, max); lastpos = len; diff --git a/src/common/objects/dobjgc.cpp b/src/common/objects/dobjgc.cpp index 64f36a129..d388e4836 100644 --- a/src/common/objects/dobjgc.cpp +++ b/src/common/objects/dobjgc.cpp @@ -287,11 +287,22 @@ static size_t DestroyObjects(size_t count) while ((curr = ToDestroy) != nullptr && count-- > 0) { - assert(!(curr->ObjectFlags & OF_EuthanizeMe)); - bytes_destroyed += curr->GetClass()->Size + GCDESTROYCOST; - ToDestroy = curr->GCNext; - curr->GCNext = nullptr; - curr->Destroy(); + // Note that we cannot assume here that the object has not yet been destroyed. + // If destruction happens as the result of another object's destruction we may + // get entries here that have been destroyed already if that owning object was + // first in the list. + if (!(curr->ObjectFlags & OF_EuthanizeMe)) + { + bytes_destroyed += curr->GetClass()->Size + GCDESTROYCOST; + ToDestroy = curr->GCNext; + curr->GCNext = nullptr; + curr->Destroy(); + } + else + { + ToDestroy = curr->GCNext; + curr->GCNext = nullptr; + } } return bytes_destroyed; } diff --git a/src/common/rendering/hwrenderer/data/hw_aabbtree.cpp b/src/common/rendering/hwrenderer/data/hw_aabbtree.cpp index 20a1d39a1..d7d221fe3 100644 --- a/src/common/rendering/hwrenderer/data/hw_aabbtree.cpp +++ b/src/common/rendering/hwrenderer/data/hw_aabbtree.cpp @@ -56,10 +56,10 @@ TArray LevelAABBTree::FindNodePath(unsigned int line, unsigned int node) double LevelAABBTree::RayTest(const DVector3 &ray_start, const DVector3 &ray_end) { // Precalculate some of the variables used by the ray/line intersection test - DVector2 raydelta = ray_end - ray_start; + DVector2 raydelta = (ray_end - ray_start).XY(); double raydist2 = raydelta | raydelta; DVector2 raynormal = DVector2(raydelta.Y, -raydelta.X); - double rayd = raynormal | ray_start; + double rayd = raynormal | ray_start.XY(); if (raydist2 < 1.0) return 1.0f; @@ -73,7 +73,7 @@ double LevelAABBTree::RayTest(const DVector3 &ray_start, const DVector3 &ray_end { int node_index = stack[stack_pos - 1]; - if (!OverlapRayAABB(ray_start, ray_end, nodes[node_index])) + if (!OverlapRayAABB(ray_start.XY(), ray_end.XY(), nodes[node_index])) { // If the ray doesn't overlap this node's AABB we're done for this subtree stack_pos--; @@ -81,7 +81,7 @@ double LevelAABBTree::RayTest(const DVector3 &ray_start, const DVector3 &ray_end else if (nodes[node_index].line_index != -1) // isLeaf(node_index) { // We reached a leaf node. Do a ray/line intersection test to see if we hit the line. - hit_fraction = std::min(IntersectRayLine(ray_start, ray_end, nodes[node_index].line_index, raydelta, rayd, raydist2), hit_fraction); + hit_fraction = std::min(IntersectRayLine(ray_start.XY(), ray_end.XY(), nodes[node_index].line_index, raydelta, rayd, raydist2), hit_fraction); stack_pos--; } else if (stack_pos == 32) diff --git a/src/common/scripting/frontend/zcc-parse.lemon b/src/common/scripting/frontend/zcc-parse.lemon index d25820dda..295c58dd9 100644 --- a/src/common/scripting/frontend/zcc-parse.lemon +++ b/src/common/scripting/frontend/zcc-parse.lemon @@ -378,6 +378,15 @@ flag_def(X) ::= FLAGDEF(T) IDENTIFIER(A) COLON IDENTIFIER(B) COMMA INTCONST(C) S X = def; } +flag_def(X) ::= FLAGDEF(T) INTERNAL IDENTIFIER(A) COLON IDENTIFIER(B) COMMA INTCONST(C) SEMICOLON. +{ + NEW_AST_NODE(FlagDef,def,T); + def->NodeName = A.Name(); + def->RefName = B.Name(); + def->BitValue = C.Int | 0x10000; + X = def; +} + identifier_list(X) ::= IDENTIFIER(A). { @@ -437,6 +446,7 @@ struct_member(X) ::= declarator(A). { X = A; /*X-overwrites-A*/ } struct_member(X) ::= enum_def(A). { X = A; /*X-overwrites-A*/ } struct_member(X) ::= const_def(A). { X = A; /*X-overwrites-A*/ } struct_member(X) ::= staticarray_statement(A). { X = A; /*X-overwrites-A*/ } +struct_member(X) ::= flag_def(A). { X = A; /*X-overwrites-A*/ } /*----- Constant Definition ------*/ /* Like UnrealScript, a constant's type is implied by its value's type. */ diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index b43e9622f..fbe3d80dd 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -452,6 +452,11 @@ void ZCCCompiler::ProcessStruct(ZCC_Struct *cnode, PSymbolTreeNode *treenode, ZC } break; + case AST_FlagDef: + cls->FlagDefs.Push(static_cast(node)); + break; + + default: assert(0 && "Unhandled AST node type"); break; diff --git a/src/common/scripting/frontend/zcc_compile.h b/src/common/scripting/frontend/zcc_compile.h index b6f32018d..82c6342ff 100644 --- a/src/common/scripting/frontend/zcc_compile.h +++ b/src/common/scripting/frontend/zcc_compile.h @@ -23,6 +23,7 @@ struct ZCC_StructWork TArray Fields; TArray Functions; TArray Arrays; + TArray FlagDefs; ZCC_StructWork() { diff --git a/src/common/scripting/vm/vm.h b/src/common/scripting/vm/vm.h index 73c4b48bb..6442034c1 100644 --- a/src/common/scripting/vm/vm.h +++ b/src/common/scripting/vm/vm.h @@ -724,6 +724,11 @@ struct AFuncDesc extern FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr; \ MSVC_FSEG FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr GCC_FSEG = &VMField_##cls##_##scriptname; +#define DEFINE_FIELD_NAMED_UNSIZED(cls, name, scriptname) \ + static const FieldDesc VMField_##cls##_##scriptname = { #cls, #scriptname, (unsigned)myoffsetof(cls, name), ~0u, 0 }; \ + extern FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr; \ + MSVC_FSEG FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr GCC_FSEG = &VMField_##cls##_##scriptname; + #define DEFINE_FIELD_BIT(cls, name, scriptname, bitval) \ static const FieldDesc VMField_##cls##_##scriptname = { #cls, #scriptname, (unsigned)myoffsetof(cls, name), (unsigned)sizeof(cls::name), bitval }; \ extern FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr; \ diff --git a/src/common/textures/animlib.cpp b/src/common/textures/animlib.cpp index cc83f87ba..4791a1313 100644 --- a/src/common/textures/animlib.cpp +++ b/src/common/textures/animlib.cpp @@ -222,7 +222,7 @@ int32_t ANIM_LoadAnim(anim_t *anim, const uint8_t *buffer, size_t length) if (memcmp(buffer, "LPF ", 4)) return -1; length -= sizeof(lpfileheader)+128+768; - if (length < 0) + if ((signed)length < 0) return -1; anim->curlpnum = 0xffff; @@ -244,7 +244,7 @@ int32_t ANIM_LoadAnim(anim_t *anim, const uint8_t *buffer, size_t length) lpheader.framesPerSecond = LittleShort(lpheader.framesPerSecond); length -= lpheader.nLps * sizeof(lp_descriptor); - if (length < 0) + if ((signed)length < 0) return -2; buffer += sizeof(lpfileheader)+128; diff --git a/src/common/textures/formats/qoitexture.cpp b/src/common/textures/formats/qoitexture.cpp index 663472f20..2df651756 100644 --- a/src/common/textures/formats/qoitexture.cpp +++ b/src/common/textures/formats/qoitexture.cpp @@ -59,7 +59,7 @@ FImageSource *QOIImage_TryCreate(FileReader &file, int lumpnum) { QOIHeader header; - if (file.GetLength() < (sizeof(header) + 8)) + if ((size_t)file.GetLength() < (sizeof(header) + 8)) { return nullptr; } @@ -86,7 +86,7 @@ FQOITexture::FQOITexture(int lumpnum, QOIHeader& header) LeftOffset = TopOffset = 0; Width = header.width; Height = header.height; - if (header.channels == 3) bMasked = bTranslucent = false; + if (header.channels == 3) bMasked = (bTranslucent = false); } PalettedPixels FQOITexture::CreatePalettedPixels(int conversion, int frame) diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index c2ebe6249..b742ca787 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -1632,7 +1632,7 @@ void FTextureManager::Listaliases() void FTextureManager::SetLinkedTexture(int lump, FGameTexture* tex) { - if ((size_t)lump < fileSystem.GetNumEntries()) + if (lump < fileSystem.GetNumEntries()) { linkedMap.Insert(lump, tex); } @@ -1646,7 +1646,7 @@ void FTextureManager::SetLinkedTexture(int lump, FGameTexture* tex) FGameTexture* FTextureManager::GetLinkedTexture(int lump) { - if ((size_t)lump < fileSystem.GetNumEntries()) + if (lump < fileSystem.GetNumEntries()) { auto check = linkedMap.CheckKey(lump); if (check) return *check; diff --git a/src/common/thirdparty/math/asin.c b/src/common/thirdparty/math/asin.c index 8bc342dd1..72dc9b3e9 100644 --- a/src/common/thirdparty/math/asin.c +++ b/src/common/thirdparty/math/asin.c @@ -276,8 +276,7 @@ double c_asin(); #endif extern double PIO2, PIO4, NAN; -double c_asin(x) -double x; +double c_asin(double x) { double a, p, z, zz; short sign; @@ -327,8 +326,7 @@ return(z); -double c_acos(x) -double x; +double c_acos(double x) { if( (x < -1.0) || (x > 1.0) ) { diff --git a/src/common/thirdparty/math/atan.c b/src/common/thirdparty/math/atan.c index d73ed1ee4..68e10310a 100644 --- a/src/common/thirdparty/math/atan.c +++ b/src/common/thirdparty/math/atan.c @@ -212,8 +212,7 @@ extern double PI, PIO2, PIO4, INFINITY, NEGZERO, MAXNUM; #endif -double c_atan(x) -double x; +double c_atan(double x) { double y, z; short sign, flag; @@ -269,11 +268,10 @@ return(y); /* atan2 */ #ifdef ANSIC -double c_atan2( y, x ) +double c_atan2(double y, double x) #else -double c_atan2( x, y ) +double c_atan2(double x, double y) #endif -double x, y; { double z, w; short code; diff --git a/src/common/thirdparty/math/cosh.c b/src/common/thirdparty/math/cosh.c index 778ccd951..bd4df2f39 100644 --- a/src/common/thirdparty/math/cosh.c +++ b/src/common/thirdparty/math/cosh.c @@ -79,8 +79,7 @@ int isnan(), isfinite(); #endif extern double MAXLOG, INFINITY, LOGE2; -double c_cosh(x) -double x; +double c_cosh(double x) { double y; diff --git a/src/common/thirdparty/math/exp.c b/src/common/thirdparty/math/exp.c index 29ec8d5da..46cd0f559 100644 --- a/src/common/thirdparty/math/exp.c +++ b/src/common/thirdparty/math/exp.c @@ -164,12 +164,11 @@ static short sc2[] = {0x3eb7,0xf7d1,0xcf79,0xabca}; extern double LOGE2, LOG2E, MAXLOG, MINLOG, MAXNUM; -double c_exp(x) -double x; +double c_exp(double x) { double px, xx; int n; -double polevl(), floor(), ldexp(); +double polevl(double, void *, int), floor(double), ldexp(double, int); if( x > MAXLOG) { diff --git a/src/common/thirdparty/math/isnan.c b/src/common/thirdparty/math/isnan.c index 6c421441f..b09ce01a3 100644 --- a/src/common/thirdparty/math/isnan.c +++ b/src/common/thirdparty/math/isnan.c @@ -99,8 +99,7 @@ POSSIBILITY OF SUCH DAMAGE. /* Return 1 if the sign bit of x is 1, else 0. */ -int signbit(x) -double x; +int signbit(double x) { union { @@ -140,8 +139,7 @@ else /* Return 1 if x is a number that is Not a Number, else return 0. */ -int isnan(x) -double x; +int isnan(double x) { #ifdef NANS union @@ -209,8 +207,7 @@ return(0); /* Return 1 if x is not infinite and is not a NaN. */ -int isfinite(x) -double x; +int isfinite(double x) { #ifdef INFINITIES union diff --git a/src/common/thirdparty/math/log.c b/src/common/thirdparty/math/log.c index 81595120c..8ad060c7e 100644 --- a/src/common/thirdparty/math/log.c +++ b/src/common/thirdparty/math/log.c @@ -230,8 +230,7 @@ int isnan(), isfinite(); #define SQRTH 0.70710678118654752440 extern double INFINITY, NAN; -double c_log(x) -double x; +double c_log(double x) { int e; #ifdef DEC diff --git a/src/common/thirdparty/math/log10.c b/src/common/thirdparty/math/log10.c index 037741c60..b7662dc0e 100644 --- a/src/common/thirdparty/math/log10.c +++ b/src/common/thirdparty/math/log10.c @@ -178,8 +178,7 @@ int isnan(), isfinite(); #endif extern double LOGE2, SQRT2, INFINITY, NAN; -double c_log10(x) -double x; +double c_log10(double x) { VOLATILE double z; double y; diff --git a/src/common/thirdparty/math/mtherr.c b/src/common/thirdparty/math/mtherr.c index 5650e07ed..3f24da2b7 100644 --- a/src/common/thirdparty/math/mtherr.c +++ b/src/common/thirdparty/math/mtherr.c @@ -99,9 +99,7 @@ static char *ermsg[7] = { }; -int mtherr( name, code ) -char *name; -int code; +int mtherr(char* name, int code) { /* Display string passed by calling program, diff --git a/src/common/thirdparty/math/polevl.c b/src/common/thirdparty/math/polevl.c index bc17a1210..dde27daff 100644 --- a/src/common/thirdparty/math/polevl.c +++ b/src/common/thirdparty/math/polevl.c @@ -75,10 +75,7 @@ Direct inquiries to 30 Frost Street, Cambridge, MA 02140 */ -double polevl( x, coef, N ) -double x; -double coef[]; -int N; +double polevl(double x, double coef[], int N) { double ans; int i; @@ -101,10 +98,7 @@ return( ans ); * Otherwise same as polevl. */ -double p1evl( x, coef, N ) -double x; -double coef[]; -int N; +double p1evl(double x, double coef[], int N) { double ans; double *p; diff --git a/src/common/thirdparty/math/pow.c b/src/common/thirdparty/math/pow.c index 49d091445..3631c4c78 100644 --- a/src/common/thirdparty/math/pow.c +++ b/src/common/thirdparty/math/pow.c @@ -387,8 +387,7 @@ extern double NAN; extern double NEGZERO; #endif -double c_pow( x, y ) -double x, y; +double c_pow(double x, double y) { double w, z, W, Wa, Wb, ya, yb, u; /* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */ @@ -768,8 +767,7 @@ return( z ); /* Find a multiple of 1/16 that is within 1/16 of x. */ -static double reduc(x) -double x; +static double reduc(double x) { double t; diff --git a/src/common/thirdparty/math/powi.c b/src/common/thirdparty/math/powi.c index d4d5a07f6..75a22f8f1 100644 --- a/src/common/thirdparty/math/powi.c +++ b/src/common/thirdparty/math/powi.c @@ -78,9 +78,7 @@ int signbit(); #endif extern double NEGZERO, INFINITY, MAXNUM, MAXLOG, MINLOG, LOGE2; -double c_powi( x, nn ) -double x; -int nn; +double c_powi(double x, int nn) { int n, e, sign, asign, lx; double w, y, s; diff --git a/src/common/thirdparty/math/sin.c b/src/common/thirdparty/math/sin.c index 76c6a1938..4b4275f2e 100644 --- a/src/common/thirdparty/math/sin.c +++ b/src/common/thirdparty/math/sin.c @@ -238,8 +238,7 @@ extern double INFINITY; #endif -double c_sin(x) -double x; +double c_sin(double x) { double y, z, zz; int j, sign; @@ -318,8 +317,7 @@ return(y); -double c_cos(x) -double x; +double c_cos(double x) { double y, z, zz; int i; @@ -403,8 +401,7 @@ static unsigned short P648[] = {034513,054170,0176773,0116043,}; static double P64800 = 4.8481368110953599358991410e-5; #endif -double radian(d,m,s) -double d,m,s; +double radian(double d, double m, double s) { return( ((d*60.0 + m)*60.0 + s)*P64800 ); diff --git a/src/common/thirdparty/math/sinh.c b/src/common/thirdparty/math/sinh.c index eb868b765..3b54760c4 100644 --- a/src/common/thirdparty/math/sinh.c +++ b/src/common/thirdparty/math/sinh.c @@ -132,8 +132,7 @@ double fabs(), c_exp(), polevl(), p1evl(); #endif extern double INFINITY, MINLOG, MAXLOG, LOGE2; -double c_sinh(x) -double x; +double c_sinh(double x) { double a; diff --git a/src/common/thirdparty/math/sqrt.c b/src/common/thirdparty/math/sqrt.c index de214aff0..67f7376f1 100644 --- a/src/common/thirdparty/math/sqrt.c +++ b/src/common/thirdparty/math/sqrt.c @@ -78,8 +78,7 @@ double frexp(), ldexp(); #endif extern double SQRT2; /* _sqrt2 = 1.41421356237309504880 */ -double c_sqrt(x) -double x; +double c_sqrt(double x) { int e; #ifndef UNK diff --git a/src/common/thirdparty/math/tan.c b/src/common/thirdparty/math/tan.c index 0b5fecc9c..adeade460 100644 --- a/src/common/thirdparty/math/tan.c +++ b/src/common/thirdparty/math/tan.c @@ -220,8 +220,7 @@ extern double PIO4; extern double INFINITY; extern double NAN; -double c_tan(x) -double x; +double c_tan(double x) { #ifdef MINUSZERO if( x == 0.0 ) @@ -240,8 +239,7 @@ return( tancot(x,0) ); } -double c_cot(x) -double x; +double c_cot(double x) { if( x == 0.0 ) @@ -253,9 +251,7 @@ return( tancot(x,1) ); } -static double tancot( xx, cotflg ) -double xx; -int cotflg; +static double tancot(double xx, int cotflg) { double x, y, z, zz; int j, sign; diff --git a/src/common/thirdparty/math/tanh.c b/src/common/thirdparty/math/tanh.c index 1836d35cc..92452c10f 100644 --- a/src/common/thirdparty/math/tanh.c +++ b/src/common/thirdparty/math/tanh.c @@ -128,8 +128,7 @@ double fabs(), c_exp(), polevl(), p1evl(); #endif extern double MAXLOG; -double c_tanh(x) -double x; +double c_tanh(double x) { double s, z; diff --git a/src/common/utility/cmdlib.cpp b/src/common/utility/cmdlib.cpp index b5fd87224..88a37f362 100644 --- a/src/common/utility/cmdlib.cpp +++ b/src/common/utility/cmdlib.cpp @@ -69,13 +69,16 @@ FString progdir; // //========================================================================== -static inline bool IsSeperator (int c) +static inline bool IsSeperator (int c, bool forcebackslash = false) { if (c == '/') return true; #ifdef _WIN32 if (c == '\\') return true; +#else + if (forcebackslash && c == '\\') + return true; #endif return false; } @@ -243,11 +246,11 @@ bool GetFileInfo(const char* pathname, size_t *size, time_t *time) // //========================================================================== -void DefaultExtension (FString &path, const char *extension) +void DefaultExtension (FString &path, const char *extension, bool forcebackslash) { const char *src = &path[int(path.Len())-1]; - while (src != &path[0] && !IsSeperator(*src)) + while (src != &path[0] && !IsSeperator(*src, forcebackslash)) { if (*src == '.') return; // it has an extension @@ -269,7 +272,7 @@ void DefaultExtension (FString &path, const char *extension) // //========================================================================== -FString ExtractFilePath (const char *path) +FString ExtractFilePath (const char *path, bool forcebackslash) { const char *src; @@ -278,7 +281,7 @@ FString ExtractFilePath (const char *path) // // back up until a \ or the start // - while (src != path && !IsSeperator(*(src-1))) + while (src != path && !IsSeperator(*(src-1), forcebackslash)) src--; return FString(path, src - path); @@ -292,7 +295,7 @@ FString ExtractFilePath (const char *path) // //========================================================================== -FString ExtractFileBase (const char *path, bool include_extension) +FString ExtractFileBase (const char *path, bool include_extension, bool forcebackslash) { const char *src, *dot; @@ -301,7 +304,7 @@ FString ExtractFileBase (const char *path, bool include_extension) if (src >= path) { // back up until a / or the start - while (src != path && !IsSeperator(*(src-1))) + while (src != path && !IsSeperator(*(src-1), forcebackslash)) src--; // Check for files with drive specification but no path @@ -325,6 +328,29 @@ FString ExtractFileBase (const char *path, bool include_extension) return FString(); } +//========================================================================== +// +// SplitPath +// +// splits a path into directory, base name and extension +// +//========================================================================== + + void SplitPath(const char* path, FString& directory, FString& base, FString& ext, bool forcebackslash) +{ + directory = ExtractFilePath(path, forcebackslash); + base = ExtractFileBase(path, forcebackslash); + auto dot = base.LastIndexOf('.'); + if (dot > -1) + { + ext = base.Mid(dot + 1); + base.Truncate(dot); + } + else + ext = ""; +} + + //========================================================================== // // StripExtension diff --git a/src/common/utility/cmdlib.h b/src/common/utility/cmdlib.h index 6f5c6b584..df779a975 100644 --- a/src/common/utility/cmdlib.h +++ b/src/common/utility/cmdlib.h @@ -48,12 +48,13 @@ extern FString progdir; void FixPathSeperator (char *path); static void inline FixPathSeperator (FString &path) { path.ReplaceChars('\\', '/'); } -void DefaultExtension (FString &path, const char *extension); +void DefaultExtension (FString &path, const char *extension, bool forcebackslash = false); void NormalizeFileName(FString &str); -FString ExtractFilePath (const char *path); -FString ExtractFileBase (const char *path, bool keep_extension=false); +FString ExtractFilePath (const char *path, bool forcebackslash = false); +FString ExtractFileBase (const char *path, bool keep_extension=false, bool forcebackslash = false); FString StripExtension(const char* path); +void SplitPath(const char* path, FString& directory, FString& base, FString& ext, bool forcebackslash = false); struct FScriptPosition; bool IsNum (const char *str); // [RH] added diff --git a/src/common/utility/filereadermusicinterface.h b/src/common/utility/filereadermusicinterface.h index 042804b53..c30ac6c55 100644 --- a/src/common/utility/filereadermusicinterface.h +++ b/src/common/utility/filereadermusicinterface.h @@ -11,9 +11,9 @@ inline ZMusicCustomReader *GetMusicReader(FileReader& fr) zcr->handle = fr.GetInterface(); zcr->gets = [](ZMusicCustomReader* zr, char* buff, int n) { return reinterpret_cast(zr->handle)->Gets(buff, n); }; - zcr->read = [](ZMusicCustomReader* zr, void* buff, int32_t size) -> long { return reinterpret_cast(zr->handle)->Read(buff, size); }; - zcr->seek = [](ZMusicCustomReader* zr, long offset, int whence) -> long { return reinterpret_cast(zr->handle)->Seek(offset, whence); }; - zcr->tell = [](ZMusicCustomReader* zr) -> long { return reinterpret_cast(zr->handle)->Tell(); }; + zcr->read = [](ZMusicCustomReader* zr, void* buff, int32_t size) -> long { return (long)reinterpret_cast(zr->handle)->Read(buff, size); }; + zcr->seek = [](ZMusicCustomReader* zr, long offset, int whence) -> long { return (long)reinterpret_cast(zr->handle)->Seek(offset, whence); }; + zcr->tell = [](ZMusicCustomReader* zr) -> long { return (long)reinterpret_cast(zr->handle)->Tell(); }; zcr->close = [](ZMusicCustomReader* zr) { delete reinterpret_cast(zr->handle); diff --git a/src/common/utility/tarray.h b/src/common/utility/tarray.h index c377f330b..760dd6092 100644 --- a/src/common/utility/tarray.h +++ b/src/common/utility/tarray.h @@ -1142,12 +1142,12 @@ public: Node *n = FindKey(key); if (n != NULL) { - n->Pair.Value = std::move(value); + n->Pair.Value = value; } else { n = NewKey(key); - ::new(&n->Pair.Value) VT(std::move(value)); + ::new(&n->Pair.Value) VT(value); } return n->Pair.Value; } diff --git a/src/common/utility/vectors.h b/src/common/utility/vectors.h index a7bc2b2f3..c861ffdfa 100644 --- a/src/common/utility/vectors.h +++ b/src/common/utility/vectors.h @@ -44,6 +44,7 @@ #include #include #include +#include // this is needed to properly normalize angles. We cannot do that with compiler provided conversions because they differ too much #include "xs_Float.h" @@ -79,61 +80,56 @@ struct TVector2 { vec_t X, Y; - TVector2() = default; + constexpr TVector2() = default; - TVector2 (vec_t a, vec_t b) + constexpr TVector2 (vec_t a, vec_t b) : X(a), Y(b) { } - TVector2(const TVector2 &other) = default; + constexpr TVector2(const TVector2 &other) = default; - TVector2 (const TVector3 &other) // Copy the X and Y from the 3D vector and discard the Z - : X(other.X), Y(other.Y) - { - } - - TVector2(vec_t *o) + constexpr TVector2(vec_t *o) : X(o[0]), Y(o[1]) { } template - explicit operator TVector2 () const noexcept { + constexpr explicit operator TVector2 () const noexcept { return TVector2(static_cast(X), static_cast(Y)); } - void Zero() + constexpr void Zero() { Y = X = 0; } - bool isZero() const + constexpr bool isZero() const { return X == 0 && Y == 0; } - TVector2 &operator= (const TVector2 &other) = default; + constexpr TVector2 &operator= (const TVector2 &other) = default; // Access X and Y as an array - vec_t &operator[] (int index) + constexpr vec_t &operator[] (int index) { return index == 0 ? X : Y; } - const vec_t &operator[] (int index) const + constexpr const vec_t &operator[] (int index) const { return index == 0 ? X : Y; } // Test for equality - bool operator== (const TVector2 &other) const + constexpr bool operator== (const TVector2 &other) const { return X == other.X && Y == other.Y; } // Test for inequality - bool operator!= (const TVector2 &other) const + constexpr bool operator!= (const TVector2 &other) const { return X != other.X || Y != other.Y; } @@ -151,92 +147,92 @@ struct TVector2 } // Unary negation - TVector2 operator- () const + constexpr TVector2 operator- () const { return TVector2(-X, -Y); } // Scalar addition #if 0 - TVector2 &operator+= (double scalar) + constexpr TVector2 &operator+= (double scalar) { X += scalar, Y += scalar; return *this; } #endif - friend TVector2 operator+ (const TVector2 &v, vec_t scalar) + constexpr friend TVector2 operator+ (const TVector2 &v, vec_t scalar) { return TVector2(v.X + scalar, v.Y + scalar); } - friend TVector2 operator+ (vec_t scalar, const TVector2 &v) + constexpr friend TVector2 operator+ (vec_t scalar, const TVector2 &v) { return TVector2(v.X + scalar, v.Y + scalar); } // Scalar subtraction - TVector2 &operator-= (vec_t scalar) + constexpr TVector2 &operator-= (vec_t scalar) { X -= scalar, Y -= scalar; return *this; } - TVector2 operator- (vec_t scalar) const + constexpr TVector2 operator- (vec_t scalar) const { return TVector2(X - scalar, Y - scalar); } // Scalar multiplication - TVector2 &operator*= (vec_t scalar) + constexpr TVector2 &operator*= (vec_t scalar) { X *= scalar, Y *= scalar; return *this; } - friend TVector2 operator* (const TVector2 &v, vec_t scalar) + constexpr friend TVector2 operator* (const TVector2 &v, vec_t scalar) { return TVector2(v.X * scalar, v.Y * scalar); } - friend TVector2 operator* (vec_t scalar, const TVector2 &v) + constexpr friend TVector2 operator* (vec_t scalar, const TVector2 &v) { return TVector2(v.X * scalar, v.Y * scalar); } // Scalar division - TVector2 &operator/= (vec_t scalar) + constexpr TVector2 &operator/= (vec_t scalar) { scalar = 1 / scalar, X *= scalar, Y *= scalar; return *this; } - TVector2 operator/ (vec_t scalar) const + constexpr TVector2 operator/ (vec_t scalar) const { scalar = 1 / scalar; return TVector2(X * scalar, Y * scalar); } // Vector addition - TVector2 &operator+= (const TVector2 &other) + constexpr TVector2 &operator+= (const TVector2 &other) { X += other.X, Y += other.Y; return *this; } - TVector2 operator+ (const TVector2 &other) const + constexpr TVector2 operator+ (const TVector2 &other) const { return TVector2(X + other.X, Y + other.Y); } // Vector subtraction - TVector2 &operator-= (const TVector2 &other) + constexpr TVector2 &operator-= (const TVector2 &other) { X -= other.X, Y -= other.Y; return *this; } - TVector2 operator- (const TVector2 &other) const + constexpr TVector2 operator- (const TVector2 &other) const { return TVector2(X - other.X, Y - other.Y); } @@ -247,7 +243,7 @@ struct TVector2 return (vec_t)g_sqrt (LengthSquared()); } - vec_t LengthSquared() const + constexpr vec_t LengthSquared() const { return X*X + Y*Y; } @@ -300,12 +296,12 @@ struct TVector2 } // Dot product - vec_t operator | (const TVector2 &other) const + constexpr vec_t operator | (const TVector2 &other) const { return X*other.X + Y*other.Y; } - vec_t dot(const TVector2 &other) const + constexpr vec_t dot(const TVector2 &other) const { return X*other.X + Y*other.Y; } @@ -331,19 +327,19 @@ struct TVector2 } // Returns a rotated vector. angle is in degrees. - TVector2 Rotated(const double cosval, const double sinval) const + constexpr TVector2 Rotated(const double cosval, const double sinval) const { return TVector2(X*cosval - Y*sinval, Y*cosval + X*sinval); } // Returns a vector rotated 90 degrees clockwise. - TVector2 Rotated90CW() const + constexpr TVector2 Rotated90CW() const { return TVector2(Y, -X); } // Returns a vector rotated 90 degrees counterclockwise. - TVector2 Rotated90CCW() const + constexpr TVector2 Rotated90CCW() const { return TVector2(-Y, X); } @@ -358,23 +354,23 @@ struct TVector3 vec_t X, Y, Z; - TVector3() = default; + constexpr TVector3() = default; - TVector3 (vec_t a, vec_t b, vec_t c) + constexpr TVector3 (vec_t a, vec_t b, vec_t c) : X(a), Y(b), Z(c) { } - TVector3(vec_t *o) + constexpr TVector3(vec_t *o) : X(o[0]), Y(o[1]), Z(o[2]) { } - TVector3(std::nullptr_t nul) = delete; + constexpr TVector3(std::nullptr_t nul) = delete; - TVector3(const TVector3 &other) = default; + constexpr TVector3(const TVector3 &other) = default; - TVector3 (const Vector2 &xy, vec_t z) + constexpr TVector3 (const Vector2 &xy, vec_t z) : X(xy.X), Y(xy.Y), Z(z) { } @@ -382,46 +378,46 @@ struct TVector3 TVector3 (const TRotator &rot); template - explicit operator TVector3 () const noexcept { + constexpr explicit operator TVector3 () const noexcept { return TVector3(static_cast(X), static_cast(Y), static_cast(Z)); } - void Zero() + constexpr void Zero() { Z = Y = X = 0; } - bool isZero() const + constexpr bool isZero() const { return X == 0 && Y == 0 && Z == 0; } - TVector3 plusZ(double z) const + constexpr TVector3 plusZ(double z) const { return { X, Y, Z + z }; } - TVector3 &operator= (const TVector3 &other) = default; + constexpr TVector3 &operator= (const TVector3 &other) = default; // Access X and Y and Z as an array - vec_t &operator[] (int index) + constexpr vec_t &operator[] (int index) { return index == 0 ? X : index == 1 ? Y : Z; } - const vec_t &operator[] (int index) const + constexpr const vec_t &operator[] (int index) const { return index == 0 ? X : index == 1 ? Y : Z; } // Test for equality - bool operator== (const TVector3 &other) const + constexpr bool operator== (const TVector3 &other) const { return X == other.X && Y == other.Y && Z == other.Z; } // Test for inequality - bool operator!= (const TVector3 &other) const + constexpr bool operator!= (const TVector3 &other) const { return X != other.X || Y != other.Y || Z != other.Z; } @@ -439,140 +435,140 @@ struct TVector3 } // Unary negation - TVector3 operator- () const + constexpr TVector3 operator- () const { return TVector3(-X, -Y, -Z); } // Scalar addition #if 0 - TVector3 &operator+= (vec_t scalar) + constexpr TVector3 &operator+= (vec_t scalar) { X += scalar, Y += scalar, Z += scalar; return *this; } #endif - friend TVector3 operator+ (const TVector3 &v, vec_t scalar) + constexpr friend TVector3 operator+ (const TVector3 &v, vec_t scalar) { return TVector3(v.X + scalar, v.Y + scalar, v.Z + scalar); } - friend TVector3 operator+ (vec_t scalar, const TVector3 &v) + constexpr friend TVector3 operator+ (vec_t scalar, const TVector3 &v) { return TVector3(v.X + scalar, v.Y + scalar, v.Z + scalar); } // Scalar subtraction - TVector3 &operator-= (vec_t scalar) + constexpr TVector3 &operator-= (vec_t scalar) { X -= scalar, Y -= scalar, Z -= scalar; return *this; } - TVector3 operator- (vec_t scalar) const + constexpr TVector3 operator- (vec_t scalar) const { return TVector3(X - scalar, Y - scalar, Z - scalar); } // Scalar multiplication - TVector3 &operator*= (vec_t scalar) + constexpr TVector3 &operator*= (vec_t scalar) { X = vec_t(X *scalar), Y = vec_t(Y * scalar), Z = vec_t(Z * scalar); return *this; } - friend TVector3 operator* (const TVector3 &v, vec_t scalar) + constexpr friend TVector3 operator* (const TVector3 &v, vec_t scalar) { return TVector3(v.X * scalar, v.Y * scalar, v.Z * scalar); } - friend TVector3 operator* (vec_t scalar, const TVector3 &v) + constexpr friend TVector3 operator* (vec_t scalar, const TVector3 &v) { return TVector3(v.X * scalar, v.Y * scalar, v.Z * scalar); } // Scalar division - TVector3 &operator/= (vec_t scalar) + constexpr TVector3 &operator/= (vec_t scalar) { scalar = 1 / scalar, X = vec_t(X * scalar), Y = vec_t(Y * scalar), Z = vec_t(Z * scalar); return *this; } - TVector3 operator/ (vec_t scalar) const + constexpr TVector3 operator/ (vec_t scalar) const { scalar = 1 / scalar; return TVector3(X * scalar, Y * scalar, Z * scalar); } // Vector addition - TVector3 &operator+= (const TVector3 &other) + constexpr TVector3 &operator+= (const TVector3 &other) { X += other.X, Y += other.Y, Z += other.Z; return *this; } - TVector3 operator+ (const TVector3 &other) const + constexpr TVector3 operator+ (const TVector3 &other) const { return TVector3(X + other.X, Y + other.Y, Z + other.Z); } // Vector subtraction - TVector3 &operator-= (const TVector3 &other) + constexpr TVector3 &operator-= (const TVector3 &other) { X -= other.X, Y -= other.Y, Z -= other.Z; return *this; } - TVector3 operator- (const TVector3 &other) const + constexpr TVector3 operator- (const TVector3 &other) const { return TVector3(X - other.X, Y - other.Y, Z - other.Z); } // Add a 2D vector to this 3D vector, leaving Z unchanged. - TVector3 &operator+= (const Vector2 &other) + constexpr TVector3 &operator+= (const Vector2 &other) { X += other.X, Y += other.Y; return *this; } // Subtract a 2D vector from this 3D vector, leaving Z unchanged. - TVector3 &operator-= (const Vector2 &other) + constexpr TVector3 &operator-= (const Vector2 &other) { X -= other.X, Y -= other.Y; return *this; } // returns the XY fields as a 2D-vector. - const Vector2& XY() const + constexpr const Vector2& XY() const { return *reinterpret_cast(this); } - Vector2& XY() + constexpr Vector2& XY() { return *reinterpret_cast(this); } // Add a 3D vector and a 2D vector. - friend TVector3 operator+ (const TVector3 &v3, const Vector2 &v2) + constexpr friend TVector3 operator+ (const TVector3 &v3, const Vector2 &v2) { return TVector3(v3.X + v2.X, v3.Y + v2.Y, v3.Z); } - friend TVector3 operator- (const TVector3 &v3, const Vector2 &v2) + constexpr friend TVector3 operator- (const TVector3 &v3, const Vector2 &v2) { return TVector3(v3.X - v2.X, v3.Y - v2.Y, v3.Z); } - friend Vector2 operator+ (const Vector2 &v2, const TVector3 &v3) + constexpr friend Vector2 operator+ (const Vector2 &v2, const TVector3 &v3) { return Vector2(v2.X + v3.X, v2.Y + v3.Y); } // Subtract a 3D vector and a 2D vector. // Discards the Z component of the 3D vector and returns a 2D vector. - friend Vector2 operator- (const TVector2 &v2, const TVector3 &v3) + constexpr friend Vector2 operator- (const TVector2 &v2, const TVector3 &v3) { return Vector2(v2.X - v3.X, v2.Y - v3.Y); } @@ -635,7 +631,7 @@ struct TVector3 return g_sqrt (LengthSquared()); } - double LengthSquared() const + constexpr double LengthSquared() const { return X*X + Y*Y + Z*Z; } @@ -691,25 +687,25 @@ struct TVector3 } // Dot product - vec_t operator | (const TVector3 &other) const + constexpr vec_t operator | (const TVector3 &other) const { return X*other.X + Y*other.Y + Z*other.Z; } - vec_t dot (const TVector3& other) const + constexpr vec_t dot (const TVector3& other) const { return X * other.X + Y * other.Y + Z * other.Z; } // Cross product - TVector3 operator ^ (const TVector3 &other) const + constexpr TVector3 operator ^ (const TVector3 &other) const { return TVector3(Y*other.Z - Z*other.Y, Z*other.X - X*other.Z, X*other.Y - Y*other.X); } - TVector3 &operator ^= (const TVector3 &other) + constexpr TVector3 &operator ^= (const TVector3 &other) { *this = *this ^ other; return *this; @@ -724,88 +720,88 @@ struct TVector4 vec_t X, Y, Z, W; - TVector4() = default; + constexpr TVector4() = default; - TVector4(vec_t a, vec_t b, vec_t c, vec_t d) + constexpr TVector4(vec_t a, vec_t b, vec_t c, vec_t d) : X(a), Y(b), Z(c), W(d) { } - TVector4(vec_t *o) + constexpr TVector4(vec_t *o) : X(o[0]), Y(o[1]), Z(o[2]), W(o[3]) { } - TVector4(const TVector4 &other) = default; + constexpr TVector4(const TVector4 &other) = default; - TVector4(const Vector3 &xyz, vec_t w) + constexpr TVector4(const Vector3 &xyz, vec_t w) : X(xyz.X), Y(xyz.Y), Z(xyz.Z), W(w) { } - TVector4(const vec_t v[4]) + constexpr TVector4(const vec_t v[4]) : TVector4(v[0], v[1], v[2], v[3]) { } template - explicit operator TVector4 () const noexcept { + constexpr explicit operator TVector4 () const noexcept { return TVector4(static_cast(X), static_cast(Y), static_cast(Z), static_cast(W)); } - void Zero() + constexpr void Zero() { Z = Y = X = W = 0; } - bool isZero() const + constexpr bool isZero() const { return X == 0 && Y == 0 && Z == 0 && W == 0; } - TVector4 &operator= (const TVector4 &other) = default; + constexpr TVector4 &operator= (const TVector4 &other) = default; // Access X and Y and Z as an array - vec_t &operator[] (int index) + constexpr vec_t &operator[] (int index) { return (&X)[index]; } - const vec_t &operator[] (int index) const + constexpr const vec_t &operator[] (int index) const { return (&X)[index]; } // Test for equality - bool operator== (const TVector4 &other) const + constexpr bool operator== (const TVector4 &other) const { return X == other.X && Y == other.Y && Z == other.Z && W == other.W; } // Test for inequality - bool operator!= (const TVector4 &other) const + constexpr bool operator!= (const TVector4 &other) const { return X != other.X || Y != other.Y || Z != other.Z || W != other.W; } // returns the XY fields as a 2D-vector. - const Vector2& XY() const + constexpr const Vector2& XY() const { return *reinterpret_cast(this); } - Vector2& XY() + constexpr Vector2& XY() { return *reinterpret_cast(this); } // returns the XY fields as a 2D-vector. - const Vector3& XYZ() const + constexpr const Vector3& XYZ() const { return *reinterpret_cast(this); } - Vector3& XYZ() + constexpr Vector3& XYZ() { return *reinterpret_cast(this); } @@ -824,127 +820,127 @@ struct TVector4 } // Unary negation - TVector4 operator- () const + constexpr TVector4 operator- () const { return TVector4(-X, -Y, -Z, -W); } // Scalar addition - TVector4 &operator+= (vec_t scalar) + constexpr TVector4 &operator+= (vec_t scalar) { X += scalar, Y += scalar, Z += scalar; W += scalar; return *this; } - friend TVector4 operator+ (const TVector4 &v, vec_t scalar) + constexpr friend TVector4 operator+ (const TVector4 &v, vec_t scalar) { return TVector4(v.X + scalar, v.Y + scalar, v.Z + scalar, v.W + scalar); } - friend TVector4 operator+ (vec_t scalar, const TVector4 &v) + constexpr friend TVector4 operator+ (vec_t scalar, const TVector4 &v) { return TVector4(v.X + scalar, v.Y + scalar, v.Z + scalar, v.W + scalar); } // Scalar subtraction - TVector4 &operator-= (vec_t scalar) + constexpr TVector4 &operator-= (vec_t scalar) { X -= scalar, Y -= scalar, Z -= scalar, W -= scalar; return *this; } - TVector4 operator- (vec_t scalar) const + constexpr TVector4 operator- (vec_t scalar) const { return TVector4(X - scalar, Y - scalar, Z - scalar, W - scalar); } // Scalar multiplication - TVector4 &operator*= (vec_t scalar) + constexpr TVector4 &operator*= (vec_t scalar) { X = vec_t(X *scalar), Y = vec_t(Y * scalar), Z = vec_t(Z * scalar), W = vec_t(W * scalar); return *this; } - friend TVector4 operator* (const TVector4 &v, vec_t scalar) + constexpr friend TVector4 operator* (const TVector4 &v, vec_t scalar) { return TVector4(v.X * scalar, v.Y * scalar, v.Z * scalar, v.W * scalar); } - friend TVector4 operator* (vec_t scalar, const TVector4 &v) + constexpr friend TVector4 operator* (vec_t scalar, const TVector4 &v) { return TVector4(v.X * scalar, v.Y * scalar, v.Z * scalar, v.W * scalar); } // Scalar division - TVector4 &operator/= (vec_t scalar) + constexpr TVector4 &operator/= (vec_t scalar) { scalar = 1 / scalar, X = vec_t(X * scalar), Y = vec_t(Y * scalar), Z = vec_t(Z * scalar), W = vec_t(W * scalar); return *this; } - TVector4 operator/ (vec_t scalar) const + constexpr TVector4 operator/ (vec_t scalar) const { scalar = 1 / scalar; return TVector4(X * scalar, Y * scalar, Z * scalar, W * scalar); } // Vector addition - TVector4 &operator+= (const TVector4 &other) + constexpr TVector4 &operator+= (const TVector4 &other) { X += other.X, Y += other.Y, Z += other.Z, W += other.W; return *this; } - TVector4 operator+ (const TVector4 &other) const + constexpr TVector4 operator+ (const TVector4 &other) const { return TVector4(X + other.X, Y + other.Y, Z + other.Z, W + other.W); } // Vector subtraction - TVector4 &operator-= (const TVector4 &other) + constexpr TVector4 &operator-= (const TVector4 &other) { X -= other.X, Y -= other.Y, Z -= other.Z, W -= other.W; return *this; } - TVector4 operator- (const TVector4 &other) const + constexpr TVector4 operator- (const TVector4 &other) const { return TVector4(X - other.X, Y - other.Y, Z - other.Z, W - other.W); } // Add a 3D vector to this 4D vector, leaving W unchanged. - TVector4 &operator+= (const Vector3 &other) + constexpr TVector4 &operator+= (const Vector3 &other) { X += other.X, Y += other.Y, Z += other.Z; return *this; } // Subtract a 3D vector from this 4D vector, leaving W unchanged. - TVector4 &operator-= (const Vector3 &other) + constexpr TVector4 &operator-= (const Vector3 &other) { X -= other.X, Y -= other.Y, Z -= other.Z; return *this; } // Add a 4D vector and a 3D vector. - friend TVector4 operator+ (const TVector4 &v4, const Vector3 &v3) + constexpr friend TVector4 operator+ (const TVector4 &v4, const Vector3 &v3) { return TVector4(v4.X + v3.X, v4.Y + v3.Y, v4.Z + v3.Z, v4.W); } - friend TVector4 operator- (const TVector4 &v4, const Vector3 &v3) + constexpr friend TVector4 operator- (const TVector4 &v4, const Vector3 &v3) { return TVector4(v4.X - v3.X, v4.Y - v3.Y, v4.Z - v3.Z, v4.W); } - friend Vector3 operator+ (const Vector3 &v3, const TVector4 &v4) + constexpr friend Vector3 operator+ (const Vector3 &v3, const TVector4 &v4) { return Vector3(v3.X + v4.X, v3.Y + v4.Y, v3.Z + v4.Z); } // Subtract a 4D vector and a 3D vector. // Discards the W component of the 4D vector and returns a 3D vector. - friend Vector3 operator- (const TVector3 &v3, const TVector4 &v4) + constexpr friend Vector3 operator- (const TVector3 &v3, const TVector4 &v4) { return Vector3(v3.X - v4.X, v3.Y - v4.Y, v3.Z - v4.Z); } @@ -955,7 +951,7 @@ struct TVector4 return g_sqrt(LengthSquared()); } - double LengthSquared() const + constexpr double LengthSquared() const { return X*X + Y*Y + Z*Z + W*W; } @@ -1012,12 +1008,12 @@ struct TVector4 } // Dot product - vec_t operator | (const TVector4 &other) const + constexpr vec_t operator | (const TVector4 &other) const { return X*other.X + Y*other.Y + Z*other.Z + W*other.W; } - vec_t dot(const TVector4 &other) const + constexpr vec_t dot(const TVector4 &other) const { return X*other.X + Y*other.Y + Z*other.Z + W*other.W; } @@ -1030,11 +1026,11 @@ struct TMatrix3x3 vec_t Cells[3][3]; - TMatrix3x3() = default; - TMatrix3x3(const TMatrix3x3 &other) = default; - TMatrix3x3& operator=(const TMatrix3x3& other) = default; + constexpr TMatrix3x3() = default; + constexpr TMatrix3x3(const TMatrix3x3 &other) = default; + constexpr TMatrix3x3& operator=(const TMatrix3x3& other) = default; - TMatrix3x3(const Vector3 &row1, const Vector3 &row2, const Vector3 &row3) + constexpr TMatrix3x3(const Vector3 &row1, const Vector3 &row2, const Vector3 &row3) { (*this)[0] = row1; (*this)[1] = row2; @@ -1043,16 +1039,16 @@ struct TMatrix3x3 // Construct a rotation matrix about an arbitrary axis. // (The axis vector must be normalized.) - TMatrix3x3(const Vector3 &axis, double degrees) + constexpr TMatrix3x3(const Vector3 &axis, double degrees) : TMatrix3x3(axis, g_sindeg(degrees), g_cosdeg(degrees)) { } - TMatrix3x3(const Vector3 &axis, double c/*cosine*/, double s/*sine*/) + constexpr TMatrix3x3(const Vector3 &axis, double c/*cosine*/, double s/*sine*/) { double t = 1 - c; double sx = s*axis.X, sy = s*axis.Y, sz = s*axis.Z; - double tx, ty, txx, tyy, u, v; + double tx = 0, ty = 0, txx = 0, tyy = 0, u = 0, v = 0; tx = t*axis.X; Cells[0][0] = vec_t( (txx=tx*axis.X) + c ); @@ -1082,7 +1078,7 @@ struct TMatrix3x3 return ret; } - static TMatrix3x3 Scale2D(TVector2 scaleVec) + constexpr static TMatrix3x3 Scale2D(TVector2 scaleVec) { TMatrix3x3 ret; ret.Cells[0][0] = scaleVec.X; ret.Cells[0][1] = 0; ret.Cells[0][2] = 0; @@ -1091,7 +1087,7 @@ struct TMatrix3x3 return ret; } - static TMatrix3x3 Translate2D(TVector2 translateVec) + constexpr static TMatrix3x3 Translate2D(TVector2 translateVec) { TMatrix3x3 ret; ret.Cells[0][0] = 1; ret.Cells[0][1] = 0; ret.Cells[0][2] = translateVec.X; @@ -1100,30 +1096,30 @@ struct TMatrix3x3 return ret; } - void Zero() + constexpr void Zero() { memset (this, 0, sizeof *this); } - void Identity() + constexpr void Identity() { Cells[0][0] = 1; Cells[0][1] = 0; Cells[0][2] = 0; Cells[1][0] = 0; Cells[1][1] = 1; Cells[1][2] = 0; Cells[2][0] = 0; Cells[2][1] = 0; Cells[2][2] = 1; } - Vector3 &operator[] (int index) + constexpr Vector3 &operator[] (int index) { return *((Vector3 *)&Cells[index]); } - const Vector3 &operator[] (int index) const + constexpr const Vector3 &operator[] (int index) const { return *((Vector3 *)&Cells[index]); } // Multiply a scalar - TMatrix3x3 &operator*= (double scalar) + constexpr TMatrix3x3 &operator*= (double scalar) { (*this)[0] *= scalar; (*this)[1] *= scalar; @@ -1131,29 +1127,29 @@ struct TMatrix3x3 return *this; } - friend TMatrix3x3 operator* (double s, const TMatrix3x3 &m) + constexpr friend TMatrix3x3 operator* (double s, const TMatrix3x3 &m) { return TMatrix3x3(m[0]*s, m[1]*s, m[2]*s); } - TMatrix3x3 operator* (double s) const + constexpr TMatrix3x3 operator* (double s) const { return TMatrix3x3((*this)[0]*s, (*this)[1]*s, (*this)[2]*s); } // Divide a scalar - TMatrix3x3 &operator/= (double scalar) + constexpr TMatrix3x3 &operator/= (double scalar) { return *this *= 1 / scalar; } - TMatrix3x3 operator/ (double s) const + constexpr TMatrix3x3 operator/ (double s) const { return *this * (1 / s); } // Add two 3x3 matrices together - TMatrix3x3 &operator+= (const TMatrix3x3 &o) + constexpr TMatrix3x3 &operator+= (const TMatrix3x3 &o) { (*this)[0] += o[0]; (*this)[1] += o[1]; @@ -1161,13 +1157,13 @@ struct TMatrix3x3 return *this; } - TMatrix3x3 operator+ (const TMatrix3x3 &o) const + constexpr TMatrix3x3 operator+ (const TMatrix3x3 &o) const { return TMatrix3x3((*this)[0] + o[0], (*this)[1] + o[1], (*this)[2] + o[2]); } // Subtract two 3x3 matrices - TMatrix3x3 &operator-= (const TMatrix3x3 &o) + constexpr TMatrix3x3 &operator-= (const TMatrix3x3 &o) { (*this)[0] -= o[0]; (*this)[1] -= o[1]; @@ -1175,18 +1171,18 @@ struct TMatrix3x3 return *this; } - TMatrix3x3 operator- (const TMatrix3x3 &o) const + constexpr TMatrix3x3 operator- (const TMatrix3x3 &o) const { return TMatrix3x3((*this)[0] - o[0], (*this)[1] - o[1], (*this)[2] - o[2]); } // Concatenate two 3x3 matrices - TMatrix3x3 &operator*= (const TMatrix3x3 &o) + constexpr TMatrix3x3 &operator*= (const TMatrix3x3 &o) { return *this = *this * o; } - TMatrix3x3 operator* (const TMatrix3x3 &o) const + constexpr TMatrix3x3 operator* (const TMatrix3x3 &o) const { return TMatrix3x3( Vector3(Cells[0][0]*o[0][0] + Cells[0][1]*o[1][0] + Cells[0][2]*o[2][0], @@ -1201,12 +1197,12 @@ struct TMatrix3x3 } // Multiply a 3D vector by a rotation matrix - friend Vector3 operator* (const Vector3 &v, const TMatrix3x3 &m) + constexpr friend Vector3 operator* (const Vector3 &v, const TMatrix3x3 &m) { return Vector3(m[0] | v, m[1] | v, m[2] | v); } - friend Vector3 operator* (const TMatrix3x3 &m, const Vector3 &v) + constexpr friend Vector3 operator* (const TMatrix3x3 &m, const Vector3 &v) { return Vector3(m[0] | v, m[1] | v, m[2] | v); } @@ -1243,7 +1239,7 @@ private: } public: - vec_t& Degrees__() { return Degrees_; } + constexpr vec_t& Degrees__() { return Degrees_; } static constexpr TAngle fromDeg(float deg) { @@ -1290,8 +1286,8 @@ public: return TAngle(bang * (90. / 16384)); } - TAngle(const TAngle &other) = default; - TAngle &operator= (const TAngle &other) = default; + constexpr TAngle(const TAngle &other) = default; + constexpr TAngle &operator= (const TAngle &other) = default; constexpr TAngle operator- () const { @@ -1462,6 +1458,24 @@ public: } }; +typedef TAngle FAngle; +typedef TAngle DAngle; + +constexpr DAngle nullAngle = DAngle::fromDeg(0.); +constexpr FAngle nullFAngle = FAngle::fromDeg(0.); +constexpr DAngle minAngle = DAngle::fromDeg(1. / 65536.); +constexpr FAngle minFAngle = FAngle::fromDeg(1. / 65536.); + +constexpr DAngle DAngle1 = DAngle::fromDeg(1); +constexpr DAngle DAngle15 = DAngle::fromDeg(15); +constexpr DAngle DAngle22_5 = DAngle::fromDeg(22.5); +constexpr DAngle DAngle45 = DAngle::fromDeg(45); +constexpr DAngle DAngle60 = DAngle::fromDeg(60); +constexpr DAngle DAngle90 = DAngle::fromDeg(90); +constexpr DAngle DAngle180 = DAngle::fromDeg(180); +constexpr DAngle DAngle270 = DAngle::fromDeg(270); +constexpr DAngle DAngle360 = DAngle::fromDeg(360); + template inline TAngle fabs (const TAngle °) { @@ -1522,11 +1536,23 @@ TAngle TVector3::Pitch() const } template -inline TVector2 clamp(const TVector2 &vec, const TVector2 &min, const TVector2 &max) +constexpr inline TVector2 clamp(const TVector2 &vec, const TVector2 &min, const TVector2 &max) { return TVector2(clamp(vec.X, min.X, max.X), clamp(vec.Y, min.Y, max.Y)); } +template +constexpr inline TVector3 clamp(const TVector3 &vec, const TVector3 &min, const TVector3 &max) +{ + return TVector3(std::clamp(vec.X, min.X, max.X), std::clamp(vec.Y, min.Y, max.Y), std::clamp(vec.Z, min.Z, max.Z)); +} + +template +constexpr inline TRotator clamp(const TRotator &rot, const TRotator &min, const TRotator &max) +{ + return TRotator(clamp(rot.Pitch, min.Pitch, max.Pitch), clamp(rot.Yaw, min.Yaw, max.Yaw), clamp(rot.Roll, min.Roll, max.Roll)); +} + template inline TAngle interpolatedvalue(const TAngle &oang, const TAngle &ang, const double interpfrac) { @@ -1544,7 +1570,7 @@ inline TRotator interpolatedvalue(const TRotator &oang, const TRotator } template -inline T interpolatedvalue(const T& oval, const T& val, const double interpfrac) +constexpr inline T interpolatedvalue(const T& oval, const T& val, const double interpfrac) { return T(oval + (val - oval) * interpfrac); } @@ -1559,125 +1585,162 @@ struct TRotator Angle Yaw; // left/right Angle Roll; // rotation about the forward axis. - TRotator() = default; + constexpr TRotator() = default; - TRotator (const Angle &p, const Angle &y, const Angle &r) + constexpr TRotator (const Angle &p, const Angle &y, const Angle &r) : Pitch(p), Yaw(y), Roll(r) { } - TRotator(const TRotator &other) = default; - TRotator &operator= (const TRotator &other) = default; + constexpr TRotator(const TRotator &other) = default; + constexpr TRotator &operator= (const TRotator &other) = default; + + constexpr void Zero() + { + Roll = Yaw = Pitch = nullAngle; + } + + constexpr bool isZero() const + { + return Pitch == nullAngle && Yaw == nullAngle && Roll == nullAngle; + } // Access angles as an array - Angle &operator[] (int index) + constexpr Angle &operator[] (int index) { return *(&Pitch + index); } - const Angle &operator[] (int index) const + constexpr const Angle &operator[] (int index) const { return *(&Pitch + index); } // Test for equality - bool operator== (const TRotator &other) const + constexpr bool operator== (const TRotator &other) const { - return fabs(Pitch - other.Pitch) < Angle(EQUAL_EPSILON) && fabs(Yaw - other.Yaw) < Angle(EQUAL_EPSILON) && fabs(Roll - other.Roll) < Angle(EQUAL_EPSILON); + return Pitch == other.Pitch && Yaw == other.Yaw && Roll == other.Roll; } // Test for inequality - bool operator!= (const TRotator &other) const + constexpr bool operator!= (const TRotator &other) const { - return fabs(Pitch - other.Pitch) >= Angle(EQUAL_EPSILON) && fabs(Yaw - other.Yaw) >= Angle(EQUAL_EPSILON) && fabs(Roll - other.Roll) >= Angle(EQUAL_EPSILON); + return Pitch != other.Pitch || Yaw != other.Yaw || Roll != other.Roll; + } + + // Test for approximate equality + bool ApproximatelyEquals (const TRotator &other) const + { + constexpr auto epsilon = Angle(EQUAL_EPSILON); + return fabs(Pitch - other.Pitch) < epsilon && fabs(Yaw - other.Yaw) < epsilon && fabs(Roll - other.Roll) < epsilon; + } + + // Test for approximate inequality + bool DoesNotApproximatelyEqual (const TRotator &other) const + { + constexpr auto epsilon = Angle(EQUAL_EPSILON); + return fabs(Pitch - other.Pitch) >= epsilon && fabs(Yaw - other.Yaw) >= epsilon && fabs(Roll - other.Roll) >= epsilon; } // Unary negation - TRotator operator- () const + constexpr TRotator operator- () const { return TRotator(-Pitch, -Yaw, -Roll); } // Scalar addition - TRotator &operator+= (const Angle &scalar) + constexpr TRotator &operator+= (const Angle &scalar) { Pitch += scalar, Yaw += scalar, Roll += scalar; return *this; } - friend TRotator operator+ (const TRotator &v, const Angle &scalar) + constexpr friend TRotator operator+ (const TRotator &v, const Angle &scalar) { return TRotator(v.Pitch + scalar, v.Yaw + scalar, v.Roll + scalar); } - friend TRotator operator+ (const Angle &scalar, const TRotator &v) + constexpr friend TRotator operator+ (const Angle &scalar, const TRotator &v) { return TRotator(v.Pitch + scalar, v.Yaw + scalar, v.Roll + scalar); } // Scalar subtraction - TRotator &operator-= (const Angle &scalar) + constexpr TRotator &operator-= (const Angle &scalar) { Pitch -= scalar, Yaw -= scalar, Roll -= scalar; return *this; } - TRotator operator- (const Angle &scalar) const + constexpr TRotator operator- (const Angle &scalar) const { return TRotator(Pitch - scalar, Yaw - scalar, Roll - scalar); } // Scalar multiplication - TRotator &operator*= (const Angle &scalar) + constexpr TRotator &operator*= (const Angle &scalar) { Pitch *= scalar, Yaw *= scalar, Roll *= scalar; return *this; } - friend TRotator operator* (const TRotator &v, const Angle &scalar) + constexpr friend TRotator operator* (const TRotator &v, const Angle &scalar) { return TRotator(v.Pitch * scalar, v.Yaw * scalar, v.Roll * scalar); } - friend TRotator operator* (const Angle &scalar, const TRotator &v) + constexpr friend TRotator operator* (const Angle &scalar, const TRotator &v) { return TRotator(v.Pitch * scalar, v.Yaw * scalar, v.Roll * scalar); } // Scalar division - TRotator &operator/= (const Angle &scalar) + constexpr TRotator &operator/= (const Angle &scalar) { Angle mul(1 / scalar.Degrees_); Pitch *= mul, Yaw *= mul, Roll *= mul; return *this; } - TRotator operator/ (const Angle &scalar) const + constexpr TRotator &operator/= (const vec_t &scalar) + { + const auto mul = 1. / scalar; + Pitch *= mul, Yaw *= mul, Roll *= mul; + return *this; + } + + constexpr TRotator operator/ (const Angle &scalar) const { Angle mul(1 / scalar.Degrees_); return TRotator(Pitch * mul, Yaw * mul, Roll * mul); } + constexpr TRotator operator/ (const vec_t &scalar) const + { + const auto mul = 1. / scalar; + return TRotator(Pitch * mul, Yaw * mul, Roll * mul); + } + // Vector addition - TRotator &operator+= (const TRotator &other) + constexpr TRotator &operator+= (const TRotator &other) { Pitch += other.Pitch, Yaw += other.Yaw, Roll += other.Roll; return *this; } - TRotator operator+ (const TRotator &other) const + constexpr TRotator operator+ (const TRotator &other) const { return TRotator(Pitch + other.Pitch, Yaw + other.Yaw, Roll + other.Roll); } // Vector subtraction - TRotator &operator-= (const TRotator &other) + constexpr TRotator &operator-= (const TRotator &other) { Pitch -= other.Pitch, Yaw -= other.Yaw, Roll -= other.Roll; return *this; } - TRotator operator- (const TRotator &other) const + constexpr TRotator operator- (const TRotator &other) const { return TRotator(Pitch - other.Pitch, Yaw - other.Yaw, Roll - other.Roll); } @@ -1718,28 +1781,12 @@ typedef TVector3 FVector3; typedef TVector4 FVector4; typedef TRotator FRotator; typedef TMatrix3x3 FMatrix3x3; -typedef TAngle FAngle; typedef TVector2 DVector2; typedef TVector3 DVector3; typedef TVector4 DVector4; typedef TRotator DRotator; typedef TMatrix3x3 DMatrix3x3; -typedef TAngle DAngle; - -constexpr DAngle nullAngle = DAngle::fromDeg(0.); -constexpr DAngle minAngle = DAngle::fromDeg(1. / 65536.); -constexpr FAngle nullFAngle = FAngle::fromDeg(0.); - -constexpr DAngle DAngle1 = DAngle::fromDeg(1); -constexpr DAngle DAngle15 = DAngle::fromDeg(15); -constexpr DAngle DAngle22_5 = DAngle::fromDeg(22.5); -constexpr DAngle DAngle45 = DAngle::fromDeg(45); -constexpr DAngle DAngle60 = DAngle::fromDeg(60); -constexpr DAngle DAngle90 = DAngle::fromDeg(90); -constexpr DAngle DAngle180 = DAngle::fromDeg(180); -constexpr DAngle DAngle270 = DAngle::fromDeg(270); -constexpr DAngle DAngle360 = DAngle::fromDeg(360); class Plane { diff --git a/src/common/utility/zstring.cpp b/src/common/utility/zstring.cpp index c8d8e7b5b..160647b7b 100644 --- a/src/common/utility/zstring.cpp +++ b/src/common/utility/zstring.cpp @@ -842,12 +842,12 @@ void FString::StripLeftRight () if (max == 0) return; for (i = 0; i < max; ++i) { - if (Chars[i] < 0 || !isspace((unsigned char)Chars[i])) + if ((signed char)Chars[i] < 0 || !isspace((unsigned char)Chars[i])) break; } for (j = max - 1; j >= i; --j) { - if (Chars[j] < 0 || !isspace((unsigned char)Chars[j])) + if ((signed char)Chars[j] < 0 || !isspace((unsigned char)Chars[j])) break; } if (i == 0 && j == max - 1) diff --git a/src/g_game.cpp b/src/g_game.cpp index 2d69009e8..ba3b8ea4b 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1471,7 +1471,7 @@ bool FLevelLocals::CheckSpot (int playernum, FPlayerStart *mthing) // return false; players[playernum].mo->flags |= MF_SOLID; - i = P_CheckPosition(players[playernum].mo, spot); + i = P_CheckPosition(players[playernum].mo, spot.XY()); players[playernum].mo->flags &= ~MF_SOLID; players[playernum].mo->SetZ(oldz); // [RH] Restore corpse's height if (!i) diff --git a/src/g_levellocals.h b/src/g_levellocals.h index b50b19fe4..504eea607 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -379,6 +379,11 @@ public: return PointInSubsector(pos.X, pos.Y)->sector; } + sector_t* PointInSector(const DVector3& pos) + { + return PointInSubsector(pos.X, pos.Y)->sector; + } + sector_t *PointInSector(double x, double y) { return PointInSubsector(x, y)->sector; @@ -389,6 +394,11 @@ public: return PointInRenderSubsector(FloatToFixed(pos.X), FloatToFixed(pos.Y)); } + subsector_t* PointInRenderSubsector(const DVector3& pos) + { + return PointInRenderSubsector(FloatToFixed(pos.X), FloatToFixed(pos.Y)); + } + FPolyObj *GetPolyobj (int polyNum) { auto index = Polyobjects.FindEx([=](const auto &poly) { return poly.tag == polyNum; }); @@ -873,7 +883,7 @@ inline bool line_t::hitSkyWall(AActor* mo) const { return backsector && backsector->GetTexture(sector_t::ceiling) == skyflatnum && - mo->Z() >= backsector->ceilingplane.ZatPoint(mo->PosRelative(this)); + mo->Z() >= backsector->ceilingplane.ZatPoint(mo->PosRelative(this).XY()); } // This must later be extended to return an array with all levels. diff --git a/src/gamedata/r_defs.h b/src/gamedata/r_defs.h index c6284b2f1..4af030b28 100644 --- a/src/gamedata/r_defs.h +++ b/src/gamedata/r_defs.h @@ -364,11 +364,21 @@ public: return (D + normal.X*pos.X + normal.Y*pos.Y) * negiC; } + double ZatPoint(const DVector3& pos) const + { + return (D + normal.X * pos.X + normal.Y * pos.Y) * negiC; + } + double ZatPoint(const FVector2 &pos) const { return (D + normal.X*pos.X + normal.Y*pos.Y) * negiC; } + double ZatPoint(const FVector3& pos) const + { + return (D + normal.X * pos.X + normal.Y * pos.Y) * negiC; + } + double ZatPoint(const vertex_t *v) const { return (D + normal.X*v->fX() + normal.Y*v->fY()) * negiC; diff --git a/src/maploader/polyobjects.cpp b/src/maploader/polyobjects.cpp index 00b7ccca4..b16942429 100644 --- a/src/maploader/polyobjects.cpp +++ b/src/maploader/polyobjects.cpp @@ -364,7 +364,7 @@ void MapLoader::PO_Init (void) if (type >= SMT_PolySpawn && type <= SMT_PolySpawnHurt) { // Polyobj StartSpot Pt. - Level->Polyobjects[polyIndex].StartSpot.pos = polythings[i]->pos; + Level->Polyobjects[polyIndex].StartSpot.pos = polythings[i]->pos.XY(); SpawnPolyobj(polyIndex, polythings[i]->angle, type); polyIndex++; } @@ -375,7 +375,7 @@ void MapLoader::PO_Init (void) if (type == SMT_PolyAnchor) { // Polyobj Anchor Pt. - TranslateToStartSpot (polythings[i]->angle, polythings[i]->pos); + TranslateToStartSpot (polythings[i]->angle, polythings[i]->pos.XY()); } } diff --git a/src/maploader/slopes.cpp b/src/maploader/slopes.cpp index 9567c6ef4..77c33cd74 100644 --- a/src/maploader/slopes.cpp +++ b/src/maploader/slopes.cpp @@ -424,7 +424,7 @@ void MapLoader::SpawnSlopeMakers (FMapThing *firstmt, FMapThing *lastmt, const i if (mt->info != NULL && mt->info->Type == NULL && (mt->info->Special == SMT_CopyFloorPlane || mt->info->Special == SMT_CopyCeilingPlane)) { - CopyPlane (mt->args[0], mt->pos, mt->info->Special == SMT_CopyCeilingPlane); + CopyPlane (mt->args[0], mt->pos.XY(), mt->info->Special == SMT_CopyCeilingPlane); mt->EdNum = 0; } } diff --git a/src/maploader/specials.cpp b/src/maploader/specials.cpp index 117e266c9..6becec6e9 100644 --- a/src/maploader/specials.cpp +++ b/src/maploader/specials.cpp @@ -281,7 +281,7 @@ void MapLoader::SetupPortals() { if (s.mType == PORTS_STACKEDSECTORTHING && s.mSkybox) { - s.mDisplacement = s.mSkybox->Pos() - s.mSkybox->target->Pos(); + s.mDisplacement = s.mSkybox->Pos().XY() - s.mSkybox->target->Pos().XY(); s.mSkybox = nullptr; } } diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 6ebb7f1cd..5a58dfb44 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -960,13 +960,13 @@ public: double Distance2DSquared(AActor *other, bool absolute = false) { - DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); + DVector2 otherpos = absolute ? other->Pos().XY() : other->PosRelative(this).XY(); return (Pos().XY() - otherpos).LengthSquared(); } double Distance2D(AActor *other, bool absolute = false) const { - DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); + DVector2 otherpos = absolute ? other->Pos().XY() : other->PosRelative(this).XY(); return (Pos().XY() - otherpos).Length(); } @@ -997,19 +997,19 @@ public: DAngle AngleTo(AActor *other, bool absolute = false) { - DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); + DVector2 otherpos = absolute ? other->Pos().XY() : other->PosRelative(this).XY(); return VecToAngle(otherpos - Pos().XY()); } DAngle AngleTo(AActor *other, double oxofs, double oyofs, bool absolute = false) const { - DVector2 otherpos = absolute ? other->Pos() : other->PosRelative(this); + DVector2 otherpos = absolute ? other->Pos().XY() : other->PosRelative(this).XY(); return VecToAngle(otherpos - Pos() + DVector2(oxofs, oyofs)); } DVector2 Vec2To(AActor *other) const { - return other->PosRelative(this) - Pos(); + return other->PosRelative(this).XY() - Pos().XY(); } DVector3 Vec3To(AActor *other) const diff --git a/src/playsim/bots/b_func.cpp b/src/playsim/bots/b_func.cpp index 07cdd08d0..e537bf9f7 100644 --- a/src/playsim/bots/b_func.cpp +++ b/src/playsim/bots/b_func.cpp @@ -541,7 +541,7 @@ DAngle DBot::FireRox (AActor *enemy, ticcmd_t *cmd) //Predict. m = ((dist+1) / GetDefaultByName("Rocket")->Speed); - Level->BotInfo.SetBodyAt(Level, DVector3((enemy->Pos() + enemy->Vel * (m + 2)), ONFLOORZ), 1); + Level->BotInfo.SetBodyAt(Level, DVector3((enemy->Pos().XY() + enemy->Vel * (m + 2)), ONFLOORZ), 1); //try the predicted location if (P_CheckSight (actor, Level->BotInfo.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile diff --git a/src/playsim/bots/b_think.cpp b/src/playsim/bots/b_think.cpp index 12c7d4113..9fba192d5 100644 --- a/src/playsim/bots/b_think.cpp +++ b/src/playsim/bots/b_think.cpp @@ -339,7 +339,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd) if (t_fight<(AFTERTICS/2)) player->mo->flags |= MF_DROPOFF; - old = player->mo->Pos(); + old = player->mo->Pos().XY(); } int P_GetRealMaxHealth(AActor *actor, int max); diff --git a/src/playsim/fragglescript/t_func.cpp b/src/playsim/fragglescript/t_func.cpp index 28ff091c6..f9fff1b9e 100644 --- a/src/playsim/fragglescript/t_func.cpp +++ b/src/playsim/fragglescript/t_func.cpp @@ -2714,7 +2714,7 @@ void FParser::SF_MoveCamera(void) double targetheight = floatvalue(t_argv[2]); double movespeed = floatvalue(t_argv[3]); DVector3 campos = cam->Pos(); - DVector3 targpos = DVector3(target->Pos(), targetheight); + DVector3 targpos = DVector3(target->Pos().XY(), targetheight); DVector3 movement = targpos - campos; double movelen = movement.Length(); diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index de0abf053..681983f4f 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -2055,7 +2055,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Respawn) } else { - oktorespawn = P_CheckPosition(self, self->Pos(), true); + oktorespawn = P_CheckPosition(self, self->Pos().XY(), true); } if (oktorespawn) @@ -4752,7 +4752,7 @@ DEFINE_ACTION_FUNCTION(AActor, CheckBlock) if (flags & CBF_NOACTORS) fpass |= PCM_NOACTORS; if (flags & CBF_NOLINES) fpass |= PCM_NOLINES; mobj->SetZ(pos.Z); - checker = P_CheckMove(mobj, pos, fpass); + checker = P_CheckMove(mobj, pos.XY(), fpass); mobj->SetZ(oldpos.Z); } else diff --git a/src/playsim/p_destructible.cpp b/src/playsim/p_destructible.cpp index 126ddbd42..a40970c76 100644 --- a/src/playsim/p_destructible.cpp +++ b/src/playsim/p_destructible.cpp @@ -716,7 +716,7 @@ bool P_ProjectileHitLinedef(AActor* mo, line_t* line) } } - int wside = P_PointOnLineSide(mo->Pos(), line); + int wside = P_PointOnLineSide(mo->Pos().XY(), line); int oside = !wside; side_t* otherside = line->sidedef[oside]; // check if hit upper or lower part diff --git a/src/playsim/p_effect.cpp b/src/playsim/p_effect.cpp index a7588d1ba..6f9275257 100644 --- a/src/playsim/p_effect.cpp +++ b/src/playsim/p_effect.cpp @@ -703,7 +703,7 @@ void P_DrawRailTrail(AActor *source, TArray &portalhits, int color1, AActor *mo = player->camera; double r = ((seg.start.Y - mo->Y()) * (-seg.dir.Y) - (seg.start.X - mo->X()) * (seg.dir.X)) / (seg.length * seg.length); r = clamp(r, 0., 1.); - seg.soundpos = seg.start + r * seg.dir; + seg.soundpos = seg.start.XY() + r * seg.dir.XY(); seg.sounddist = (seg.soundpos - mo->Pos()).LengthSquared(); } else diff --git a/src/playsim/p_enemy.cpp b/src/playsim/p_enemy.cpp index b93f528a4..ab40fea65 100644 --- a/src/playsim/p_enemy.cpp +++ b/src/playsim/p_enemy.cpp @@ -604,7 +604,7 @@ static int P_Move (AActor *actor) move = move.Rotated(anglediff); oldangle = actor->Angles.Yaw; } - start = actor->Pos() - move * i / steps; + start = actor->Pos().XY() - move * i / steps; } } @@ -2640,7 +2640,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi if ((!fastchase || !actor->FastChaseStrafeCount) && !dontmove) { // CANTLEAVEFLOORPIC handling was completely missing in the non-serpent functions. - DVector2 old = actor->Pos(); + DVector2 old = actor->Pos().XY(); int oldgroup = actor->PrevPortalGroup; FTextureID oldFloor = actor->floorpic; @@ -2802,7 +2802,7 @@ bool P_CheckForResurrection(AActor* self, bool usevilestates, FState* state = nu corpsehit->flags |= MF_SOLID; corpsehit->Height = corpsehit->GetDefault()->Height; - bool check = P_CheckPosition(corpsehit, corpsehit->Pos()); + bool check = P_CheckPosition(corpsehit, corpsehit->Pos().XY()); corpsehit->flags = oldflags; corpsehit->radius = oldradius; corpsehit->Height = oldheight; diff --git a/src/playsim/p_lnspec.cpp b/src/playsim/p_lnspec.cpp index 0ac2c977e..407cc23e4 100644 --- a/src/playsim/p_lnspec.cpp +++ b/src/playsim/p_lnspec.cpp @@ -175,7 +175,7 @@ FUNC(LS_Polyobj_MoveToSpot) auto iterator = Level->GetActorIterator(arg2); AActor *spot = iterator.Next(); if (spot == NULL) return false; - return EV_MovePolyTo (Level, ln, arg0, SPEED(arg1), spot->Pos(), false); + return EV_MovePolyTo (Level, ln, arg0, SPEED(arg1), spot->Pos().XY(), false); } FUNC(LS_Polyobj_DoorSwing) @@ -226,7 +226,7 @@ FUNC(LS_Polyobj_OR_MoveToSpot) auto iterator = Level->GetActorIterator(arg2); AActor *spot = iterator.Next(); if (spot == NULL) return false; - return EV_MovePolyTo (Level, ln, arg0, SPEED(arg1), spot->Pos(), true); + return EV_MovePolyTo (Level, ln, arg0, SPEED(arg1), spot->Pos().XY(), true); } FUNC(LS_Polyobj_Stop) diff --git a/src/playsim/p_map.cpp b/src/playsim/p_map.cpp index edb865b16..015d40b11 100644 --- a/src/playsim/p_map.cpp +++ b/src/playsim/p_map.cpp @@ -267,7 +267,7 @@ static bool PIT_FindFloorCeiling(FMultiBlockLinesIterator &mit, FMultiBlockLines return true; } - DVector2 refpoint = FindRefPoint(ld, cres.Position); + DVector2 refpoint = FindRefPoint(ld, cres.Position.XY()); FLineOpening open; P_LineOpening(open, tmf.thing, ld, refpoint, &cres.Position, flags); @@ -851,8 +851,8 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec { spechit_t spec; spec.line = ld; - spec.Refpos = cres.Position; - spec.Oldrefpos = tm.thing->PosRelative(ld); + spec.Refpos = cres.Position.XY(); + spec.Oldrefpos = tm.thing->PosRelative(ld).XY(); portalhit.Push(spec); return true; } @@ -963,12 +963,12 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec tm.thing->BlockingLine = ld; } // Calculate line side based on the actor's original position, not the new one. - CheckForPushSpecial(ld, P_PointOnLineSide(cres.Position, ld), tm.thing); + CheckForPushSpecial(ld, P_PointOnLineSide(cres.Position.XY(), ld), tm.thing); return false; } } } - DVector2 ref = FindRefPoint(ld, cres.Position); + DVector2 ref = FindRefPoint(ld, cres.Position.XY()); FLineOpening open; P_LineOpening(open, tm.thing, ld, ref, &cres.Position, cres.portalflags); @@ -1089,15 +1089,15 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec if (ld->special) { spec.line = ld; - spec.Refpos = cres.Position; - spec.Oldrefpos = tm.thing->PosRelative(ld); + spec.Refpos = cres.Position.XY(); + spec.Oldrefpos = tm.thing->PosRelative(ld).XY(); spechit.Push(spec); } if (ld->isLinePortal()) { spec.line = ld; - spec.Refpos = cres.Position; - spec.Oldrefpos = tm.thing->PosRelative(ld); + spec.Refpos = cres.Position.XY(); + spec.Oldrefpos = tm.thing->PosRelative(ld).XY(); portalhit.Push(spec); } @@ -1153,7 +1153,7 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera if (ld->backsector == NULL) continue; - DVector2 ref = FindRefPoint(ld, cres.Position); + DVector2 ref = FindRefPoint(ld, cres.Position.XY()); FLineOpening open; P_LineOpening(open, tm.thing, ld, ref, &cres.Position, 0); @@ -2017,7 +2017,7 @@ int P_TestMobjLocation(AActor *mobj) flags = mobj->flags; mobj->flags &= ~MF_PICKUP; - if (P_CheckPosition(mobj, mobj->Pos())) + if (P_CheckPosition(mobj, mobj->Pos().XY())) { // XY is ok, now check Z mobj->flags = flags; if ((mobj->Z() < mobj->floorz) || (mobj->Top() > mobj->ceilingz)) @@ -2547,7 +2547,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, { FLinkContext ctx; thing->UnlinkFromWorld(&ctx); - thing->SetXY(tm.pos + port->mDisplacement); + thing->SetXY(tm.pos.XY() + port->mDisplacement); thing->Prev += port->mDisplacement; thing->LinkToWorld(&ctx); P_FindFloorCeiling(thing); @@ -2557,15 +2557,15 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, } else if (!portalcrossed) { - DVector3 pos(tm.pos, thing->Z()); + DVector3 pos(tm.pos.XY(), thing->Z()); DVector3 oldthingpos = thing->Pos(); - DVector2 thingpos = oldthingpos; + DVector2 thingpos = oldthingpos.XY(); P_TranslatePortalXY(ld, pos.X, pos.Y); P_TranslatePortalXY(ld, thingpos.X, thingpos.Y); P_TranslatePortalZ(ld, pos.Z); thing->SetXYZ(thingpos.X, thingpos.Y, pos.Z); - if (!P_CheckPosition(thing, pos, true)) // check if some actor blocks us on the other side. (No line checks, because of the mess that'd create.) + if (!P_CheckPosition(thing, pos.XY(), true)) // check if some actor blocks us on the other side. (No line checks, because of the mess that'd create.) { thing->SetXYZ(oldthingpos); thing->flags6 &= ~MF6_INTRYMOVE; @@ -2644,7 +2644,7 @@ bool P_TryMove(AActor *thing, const DVector2 &pos, if (!(thing->flags & (MF_TELEPORT | MF_NOCLIP))) { spechit_t spec; - DVector2 lastpos = thing->Pos(); + DVector2 lastpos = thing->Pos().XY(); while (spechit.Pop(spec)) { line_t *ld = spec.line; @@ -2988,7 +2988,7 @@ void FSlide::HitSlideLine(line_t* ld) // less than 45 degrees. // phares DVector3 pos = slidemo->PosRelative(ld); - side = P_PointOnLineSide(pos, ld); + side = P_PointOnLineSide(pos.XY(), ld); lineangle = ld->Delta().Angle(); @@ -3081,7 +3081,7 @@ void FSlide::SlideTraverse(const DVector2 &start, const DVector2 &end) if (!(li->flags & ML_TWOSIDED) || !li->backsector) { DVector3 pos = slidemo->PosRelative(li); - if (P_PointOnLineSide(pos, li)) + if (P_PointOnLineSide(pos.XY(), li)) { // don't hit the back side continue; @@ -3203,11 +3203,11 @@ retry: // killough 3/15/98: Allow objects to drop off ledges move = { 0, tryp.Y }; walkplane = P_CheckSlopeWalk(mo, move); - if (!P_TryMove(mo, mo->Pos() + move, true, walkplane)) + if (!P_TryMove(mo, mo->Pos().XY() + move, true, walkplane)) { move = { tryp.X, 0 }; walkplane = P_CheckSlopeWalk(mo, move); - P_TryMove(mo, mo->Pos() + move, true, walkplane); + P_TryMove(mo, mo->Pos().XY() + move, true, walkplane); } return; } @@ -3222,7 +3222,7 @@ retry: const DVector2 startvel = mo->Vel.XY(); // killough 3/15/98: Allow objects to drop off ledges - if (!P_TryMove(mo, mo->Pos() + newpos, true)) + if (!P_TryMove(mo, mo->Pos().XY() + newpos, true)) goto stairstep; if (mo->Vel.XY() != startvel) @@ -3255,7 +3255,7 @@ retry: walkplane = P_CheckSlopeWalk(mo, tmmove); // killough 3/15/98: Allow objects to drop off ledges - if (!P_TryMove(mo, mo->Pos() + tmmove, true, walkplane)) + if (!P_TryMove(mo, mo->Pos().XY() + tmmove, true, walkplane)) { goto retry; } @@ -3335,7 +3335,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move) DVector2 dest; double t; - dest = actor->Pos() + move; + dest = actor->Pos().XY() + move; t = (plane->Normal() | DVector3(dest, actor->Z())) + plane->fD(); if (t < 0) { // Desired location is behind (below) the plane @@ -3370,7 +3370,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move) } if (dopush) { - move = plane->Normal() * 2; + move = plane->Normal().XY() * 2; actor->Vel.X = move.X; actor->Vel.Y = move.Y; } @@ -3379,7 +3379,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move) } // Slide the desired location along the plane's normal // so that it lies on the plane's surface - dest -= plane->Normal() * t; + dest -= plane->Normal().XY() * t; move = dest - actor->Pos().XY(); return (actor->floorsector == actor->Sector) ? plane : NULL; } @@ -3389,7 +3389,7 @@ const secplane_t * P_CheckSlopeWalk(AActor *actor, DVector2 &move) { // Actor's current spot is on/in the plane, so walk down it // Same principle as walking up, except reversed - dest += plane->Normal() * t; + dest += plane->Normal().XY() * t; move = dest - actor->Pos().XY(); return (actor->floorsector == actor->Sector) ? plane : NULL; } @@ -3428,7 +3428,7 @@ bool FSlide::BounceTraverse(const DVector2 &start, const DVector2 &end) } if (!(li->flags&ML_TWOSIDED) || !li->backsector) { - if (P_PointOnLineSide(slidemo->Pos(), li)) + if (P_PointOnLineSide(slidemo->Pos().XY(), li)) continue; // don't hit the back side goto bounceblocking; } @@ -3557,7 +3557,7 @@ bool FSlide::BounceWall(AActor *mo) return true; } - side = P_PointOnLineSide(mo->Pos(), line); + side = P_PointOnLineSide(mo->Pos().XY(), line); lineangle = line->Delta().Angle(); if (side == 1) { @@ -4047,7 +4047,7 @@ struct aim_t newtrace.startfrac = frac + 1 / attackrange; // this is to skip the transition line to the portal which would produce a bogus opening - DVector2 pos = newtrace.startpos + newtrace.aimtrace * newtrace.startfrac; + DVector2 pos = newtrace.startpos.XY() + newtrace.aimtrace * newtrace.startfrac; newtrace.lastsector = li->GetLevel()->PointInSector(pos); P_TranslatePortalZ(li, limitz); @@ -5694,7 +5694,7 @@ bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end, return true; } - sec = P_PointOnLineSide(xpos, in->d.line) == 0 ? + sec = P_PointOnLineSide(xpos.XY(), in->d.line) == 0 ? in->d.line->frontsector : in->d.line->backsector; if (sec != NULL && sec->SecActTarget && @@ -5713,7 +5713,7 @@ bool P_UseTraverse(AActor *usething, const DVector2 &start, const DVector2 &end, continue; // not a special line, but keep checking } - if (P_PointOnLineSide(xpos, in->d.line) == 1) + if (P_PointOnLineSide(xpos.XY(), in->d.line) == 1) { if (!(in->d.line->activation & SPAC_UseBack)) { @@ -5807,7 +5807,7 @@ void P_UseLines(player_t *player) bool foundline = false; // If the player is transitioning a portal, use the group that is at its vertical center. - DVector2 start = player->mo->GetPortalTransition(player->mo->Height / 2); + DVector2 start = player->mo->GetPortalTransition(player->mo->Height / 2).XY(); // [NS] Now queries the Player's UseRange. DVector2 end = start + player->mo->Angles.Yaw.ToVector(player->mo->FloatVar(NAME_UseRange)); @@ -5847,7 +5847,7 @@ int P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType) else usedist = USERANGE; - start = PuzzleItemUser->GetPortalTransition(PuzzleItemUser->Height / 2); + start = PuzzleItemUser->GetPortalTransition(PuzzleItemUser->Height / 2).XY(); end = PuzzleItemUser->Angles.Yaw.ToVector(usedist); FPathTraverse it(PuzzleItemUser->Level, start.X, start.Y, end.X, end.Y, PT_DELTA | PT_ADDLINES | PT_ADDTHINGS); @@ -5869,7 +5869,7 @@ int P_UsePuzzleItem(AActor *PuzzleItemUser, int PuzzleItemType) } continue; } - if (P_PointOnLineSide(PuzzleItemUser->Pos(), in->d.line) == 1) + if (P_PointOnLineSide(PuzzleItemUser->Pos().XY(), in->d.line) == 1) { // Don't use back sides return false; } @@ -6311,7 +6311,7 @@ bool P_AdjustFloorCeil(AActor *thing, FChangePosition *cpos) thing->flags2 |= MF2_PASSMOBJ; } - bool isgood = P_CheckPosition(thing, thing->Pos(), tm); + bool isgood = P_CheckPosition(thing, thing->Pos().XY(), tm); if (!(thing->flags4 & MF4_ACTLIKEBRIDGE)) { thing->floorz = tm.floorz; diff --git a/src/playsim/p_maputl.h b/src/playsim/p_maputl.h index 53984f1d3..7c89bab06 100644 --- a/src/playsim/p_maputl.h +++ b/src/playsim/p_maputl.h @@ -49,6 +49,11 @@ inline int P_PointOnLineSidePrecise(const DVector2 &pt, const linebase_t *line) return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > EQUAL_EPSILON; } +inline int P_PointOnLineSidePrecise(const DVector3& pt, const linebase_t* line) +{ + return (pt.Y - line->v1->fY()) * line->Delta().X + (line->v1->fX() - pt.X) * line->Delta().Y > EQUAL_EPSILON; +} + inline int P_PointOnLineSide (double x, double y, const line_t *line) { extern int P_VanillaPointOnLineSide(double x, double y, const line_t* line); diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index bc0b85961..1dcf511da 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -1879,7 +1879,7 @@ static double P_XYMovement (AActor *mo, DVector2 scroll) { mo->Vel.MakeResize(VELOCITY_THRESHOLD); } - move = mo->Vel; + move = mo->Vel.XY(); // [RH] Carrying sectors didn't work with low speeds in BOOM. This is // because BOOM relied on the speed being fast enough to accumulate // despite friction. If the speed is too low, then its movement will get @@ -1965,7 +1965,7 @@ static double P_XYMovement (AActor *mo, DVector2 scroll) // because it also calls P_CheckSlopeWalk on its clipped steps. DVector2 onestep = startmove / steps; - start = mo->Pos(); + start = mo->Pos().XY(); step = 1; totalsteps = steps; @@ -1990,7 +1990,7 @@ static double P_XYMovement (AActor *mo, DVector2 scroll) ptry = start + move * step / steps; - DVector2 startvel = mo->Vel; + DVector2 startvel = mo->Vel.XY(); // killough 3/15/98: Allow objects to drop off // [RH] If walking on a slope, stay on the slope @@ -2044,7 +2044,7 @@ static double P_XYMovement (AActor *mo, DVector2 scroll) // If the move is done a second time (because it was too fast for one move), it // is still clipped against the wall at its full speed, so you effectively // execute two moves in one tic. - P_SlideMove (mo, mo->Vel, 1); + P_SlideMove (mo, mo->Vel.XY(), 1); } else { @@ -2058,7 +2058,7 @@ static double P_XYMovement (AActor *mo, DVector2 scroll) { if (!player || !(mo->Level->i_compatflags & COMPATF_WALLRUN)) { - move = mo->Vel; + move = mo->Vel.XY(); onestep = move / steps; P_CheckSlopeWalk (mo, move); } @@ -2075,7 +2075,7 @@ static double P_XYMovement (AActor *mo, DVector2 scroll) DVector2 t; t.X = 0, t.Y = onestep.Y; walkplane = P_CheckSlopeWalk (mo, t); - if (P_TryMove (mo, mo->Pos() + t, true, walkplane, tm)) + if (P_TryMove (mo, mo->Pos().XY() + t, true, walkplane, tm)) { mo->Vel.X = 0; } @@ -2083,7 +2083,7 @@ static double P_XYMovement (AActor *mo, DVector2 scroll) { t.X = onestep.X, t.Y = 0; walkplane = P_CheckSlopeWalk (mo, t); - if (P_TryMove (mo, mo->Pos() + t, true, walkplane, tm)) + if (P_TryMove (mo, mo->Pos().XY() + t, true, walkplane, tm)) { mo->Vel.Y = 0; } @@ -2194,7 +2194,7 @@ static double P_XYMovement (AActor *mo, DVector2 scroll) move = move.Rotated(anglediff); oldangle = mo->Angles.Yaw; } - start = mo->Pos() - move * step / steps; + start = mo->Pos().XY() - move * step / steps; } } } @@ -2877,7 +2877,7 @@ void P_NightmareRespawn (AActor *mobj) } // something is occupying its position? - if (!P_CheckPosition(mo, mo->Pos(), true)) + if (!P_CheckPosition(mo, mo->Pos().XY(), true)) { //[GrafZahl] MF_COUNTKILL still needs to be checked here. mo->ClearCounters(); @@ -2906,7 +2906,7 @@ void P_NightmareRespawn (AActor *mobj) P_SpawnTeleportFog(mobj, mobj->Pos(), true, true); // spawn a teleport fog at the new spot - P_SpawnTeleportFog(mobj, DVector3(mobj->SpawnPoint, z), false, true); + P_SpawnTeleportFog(mobj, DVector3(mobj->SpawnPoint.XY(), z), false, true); // remove the old monster mobj->Destroy (); @@ -5728,7 +5728,7 @@ AActor *FLevelLocals::SpawnMapThing (FMapThing *mthing, int position) else sz = ONFLOORZ; - mobj = AActor::StaticSpawn (this, i, DVector3(mthing->pos, sz), NO_REPLACE, true); + mobj = AActor::StaticSpawn (this, i, DVector3(mthing->pos.XY(), sz), NO_REPLACE, true); if (sz == ONFLOORZ) { @@ -6538,7 +6538,7 @@ bool P_CheckMissileSpawn (AActor* th, double maxdist) // killough 3/15/98: no dropoff (really = don't care for missiles) auto oldf2 = th->flags2; th->flags2 &= ~(MF2_MCROSS|MF2_PCROSS); // The following check is not supposed to activate missile triggers. - if (!(P_TryMove (th, newpos, false, NULL, tm, true))) + if (!(P_TryMove (th, newpos.XY(), false, NULL, tm, true))) { // [RH] Don't explode ripping missiles that spawn inside something if (th->BlockingMobj == NULL || !(th->flags2 & MF2_RIP) || (th->BlockingMobj->flags5 & MF5_DONTRIP)) @@ -7576,7 +7576,7 @@ static FRandom pr_restore("RestorePos"); void AActor::RestoreSpecialPosition() { // Move item back to its original location - DVector2 sp = SpawnPoint; + DVector2 sp = SpawnPoint.XY(); FLinkContext ctx; UnlinkFromWorld(&ctx); diff --git a/src/playsim/p_secnodes.cpp b/src/playsim/p_secnodes.cpp index f43b0e30e..e19846c75 100644 --- a/src/playsim/p_secnodes.cpp +++ b/src/playsim/p_secnodes.cpp @@ -414,7 +414,7 @@ void AActor::UpdateRenderSectorList() if (planeh <= lasth) break; // broken setup. if (Top() + SPRITE_SPACE < planeh) break; lasth = planeh; - DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::ceiling); + DVector2 newpos = Pos().XY() + sec->GetPortalDisplacement(sector_t::ceiling); sec = sec->Level->PointInSector(newpos); touching_sectorportallist = P_AddSecnode(sec, this, touching_sectorportallist, sec->sectorportal_thinglist); } @@ -426,7 +426,7 @@ void AActor::UpdateRenderSectorList() if (planeh >= lasth) break; // broken setup. if (Z() - SPRITE_SPACE > planeh) break; lasth = planeh; - DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::floor); + DVector2 newpos = Pos().XY() + sec->GetPortalDisplacement(sector_t::floor); sec = sec->Level->PointInSector(newpos); touching_sectorportallist = P_AddSecnode(sec, this, touching_sectorportallist, sec->sectorportal_thinglist); } diff --git a/src/playsim/p_sight.cpp b/src/playsim/p_sight.cpp index b5564346a..2cf957c8c 100644 --- a/src/playsim/p_sight.cpp +++ b/src/playsim/p_sight.cpp @@ -127,7 +127,7 @@ public: void init(AActor * t1, AActor * t2, sector_t *startsector, SightTask *task, int flags) { sightstart = t1->PosRelative(task->portalgroup); - sightend = t2->PosRelative(task->portalgroup); + sightend = t2->PosRelative(task->portalgroup).XY(); sightstart.Z += t1->Height * 0.75; portalgroup = task->portalgroup; diff --git a/src/playsim/p_teleport.cpp b/src/playsim/p_teleport.cpp index fb2217ef0..1643b1b76 100644 --- a/src/playsim/p_teleport.cpp +++ b/src/playsim/p_teleport.cpp @@ -60,7 +60,7 @@ void P_SpawnTeleportFog(AActor *mobj, const DVector3 &pos, bool beforeTele, bool else { double fogDelta = mobj->flags & MF_MISSILE ? 0 : TELEFOGHEIGHT; - mo = Spawn(mobj->Level, (beforeTele ? mobj->TeleFogSourceType : mobj->TeleFogDestType), DVector3(pos, pos.Z + fogDelta), ALLOW_REPLACE); + mo = Spawn(mobj->Level, (beforeTele ? mobj->TeleFogSourceType : mobj->TeleFogDestType), pos.plusZ(fogDelta), ALLOW_REPLACE); } if (mo != NULL && setTarget) @@ -414,7 +414,7 @@ bool FLevelLocals::EV_Teleport (int tid, int tag, line_t *line, int side, AActor { badangle = DAngle::fromDeg(0.01); } - if (P_Teleport (thing, DVector3(searcher->Pos(), z), searcher->Angles.Yaw + badangle, flags)) + if (P_Teleport (thing, DVector3(searcher->Pos().XY(), z), searcher->Angles.Yaw + badangle, flags)) { // [RH] Lee Killough's changes for silent teleporters from BOOM if (line) @@ -658,7 +658,7 @@ bool FLevelLocals::EV_TeleportOther (int other_tid, int dest_tid, bool fog) bool DoGroupForOne (AActor *victim, AActor *source, AActor *dest, bool floorz, bool fog) { DAngle an = dest->Angles.Yaw - source->Angles.Yaw; - DVector2 off = victim->Pos() - source->Pos(); + DVector2 off = victim->Pos().XY() - source->Pos().XY(); DAngle offAngle = victim->Angles.Yaw - source->Angles.Yaw; DVector2 newp = { off.X * an.Cos() - off.Y * an.Sin(), off.X * an.Sin() + off.Y * an.Cos() }; double z = floorz ? ONFLOORZ : dest->Z() + victim->Z() - source->Z(); diff --git a/src/playsim/p_things.cpp b/src/playsim/p_things.cpp index 0089a29c2..3391030aa 100644 --- a/src/playsim/p_things.cpp +++ b/src/playsim/p_things.cpp @@ -468,7 +468,7 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser, int flags) thing->flags |= MF_SOLID; thing->Height = info->Height; // [RH] Use real height thing->radius = info->radius; // [RH] Use real radius - if (!(flags & RF_NOCHECKPOSITION) && !P_CheckPosition (thing, thing->Pos())) + if (!(flags & RF_NOCHECKPOSITION) && !P_CheckPosition (thing, thing->Pos().XY())) { thing->flags = oldflags; thing->radius = oldradius; @@ -512,7 +512,7 @@ bool P_Thing_CanRaise(AActor *thing) thing->Height = info->Height; thing->radius = info->radius; - bool check = P_CheckPosition (thing, thing->Pos()); + bool check = P_CheckPosition (thing, thing->Pos().XY()); // Restore checked properties thing->flags = oldflags; @@ -813,7 +813,7 @@ int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, do { caller->AddZ(reference->GetBobOffset()); } - P_TryMove(caller, caller->Pos(), false); + P_TryMove(caller, caller->Pos().XY(), false); } return true; } diff --git a/src/playsim/p_trace.cpp b/src/playsim/p_trace.cpp index d8b362ca7..7e47a7323 100644 --- a/src/playsim/p_trace.cpp +++ b/src/playsim/p_trace.cpp @@ -406,7 +406,7 @@ bool FTraceInfo::LineCheck(intercept_t *in, double dist, DVector3 hit, bool spec } else { - lineside = P_PointOnLineSide(Start, in->d.line); + lineside = P_PointOnLineSide(Start.XY(), in->d.line); CurSector = lineside ? in->d.line->backsector : in->d.line->frontsector; } } diff --git a/src/playsim/po_man.cpp b/src/playsim/po_man.cpp index f29001b9f..a547d619a 100644 --- a/src/playsim/po_man.cpp +++ b/src/playsim/po_man.cpp @@ -1097,7 +1097,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) performBlockingThrust = true; } - DVector2 pos = mobj->PosRelative(ld); + DVector2 pos = mobj->PosRelative(ld).XY(); FBoundingBox box(pos.X, pos.Y, mobj->radius); if (!inRange(box, ld) || BoxOnLineSide(box, ld) != -1) @@ -1108,7 +1108,7 @@ bool FPolyObj::CheckMobjBlocking (side_t *sd) if (ld->isLinePortal()) { // Fixme: this still needs to figure out if the polyobject move made the player cross the portal line. - if (P_TryMove(mobj, mobj->Pos(), false)) + if (P_TryMove(mobj, mobj->Pos().XY(), false)) { continue; } diff --git a/src/rendering/hwrenderer/scene/hw_bsp.cpp b/src/rendering/hwrenderer/scene/hw_bsp.cpp index 822f7c2ca..4110063e8 100644 --- a/src/rendering/hwrenderer/scene/hw_bsp.cpp +++ b/src/rendering/hwrenderer/scene/hw_bsp.cpp @@ -598,7 +598,7 @@ void HWDrawInfo::RenderParticles(subsector_t *sub, sector_t *front) { if (mClipPortal) { - int clipres = mClipPortal->ClipPoint(Level->Particles[i].Pos); + int clipres = mClipPortal->ClipPoint(Level->Particles[i].Pos.XY()); if (clipres == PClip_InFront) continue; } diff --git a/src/rendering/hwrenderer/scene/hw_portal.cpp b/src/rendering/hwrenderer/scene/hw_portal.cpp index 18de9babf..e8e887567 100644 --- a/src/rendering/hwrenderer/scene/hw_portal.cpp +++ b/src/rendering/hwrenderer/scene/hw_portal.cpp @@ -447,7 +447,7 @@ int HWLinePortal::ClipSeg(seg_t *seg, const DVector3 &viewpos) { return PClip_Inside; // should be handled properly. } - return P_ClipLineToPortal(linedef, this, viewpos) ? PClip_InFront : PClip_Inside; + return P_ClipLineToPortal(linedef, this, viewpos.XY()) ? PClip_InFront : PClip_Inside; } int HWLinePortal::ClipSubsector(subsector_t *sub) diff --git a/src/rendering/hwrenderer/scene/hw_sprites.cpp b/src/rendering/hwrenderer/scene/hw_sprites.cpp index 80b2170db..ec9a8d2b9 100644 --- a/src/rendering/hwrenderer/scene/hw_sprites.cpp +++ b/src/rendering/hwrenderer/scene/hw_sprites.cpp @@ -806,7 +806,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t if (thruportal != 2 && di->mClipPortal != nullptr) { - int clipres = di->mClipPortal->ClipPoint(thingpos); + int clipres = di->mClipPortal->ClipPoint(thingpos.XY()); if (clipres == PClip_InFront) return; } // disabled because almost none of the actual game code is even remotely prepared for this. If desired, use the INTERPOLATE flag. @@ -961,7 +961,7 @@ void HWSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t // Tests show that this doesn't look good for many decorations and corpses if (spriteheight > 0 && gl_spriteclip > 0 && (thing->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE) { - PerformSpriteClipAdjustment(thing, thingpos, spriteheight); + PerformSpriteClipAdjustment(thing, thingpos.XY(), spriteheight); } switch (spritetype) diff --git a/src/rendering/r_utility.cpp b/src/rendering/r_utility.cpp index 694223688..70a70ad51 100644 --- a/src/rendering/r_utility.cpp +++ b/src/rendering/r_utility.cpp @@ -528,7 +528,7 @@ void R_InterpolateView (FRenderViewpoint &viewpoint, player_t *player, double Fr nviewz -= totalzdiff - zdiff; oviewangle += adiff; nviewangle -= totaladiff - adiff; - DVector2 viewpos = start.pos + (fragfrac * (end.pos - start.pos)); + DVector2 viewpos = start.pos.XY() + (fragfrac * (end.pos - start.pos).XY()); viewpoint.Pos = { viewpos, oviewz + Frac * (nviewz - oviewz) }; break; } diff --git a/src/rendering/swrenderer/line/r_farclip_line.cpp b/src/rendering/swrenderer/line/r_farclip_line.cpp index 8b2cd07f2..fd662952e 100644 --- a/src/rendering/swrenderer/line/r_farclip_line.cpp +++ b/src/rendering/swrenderer/line/r_farclip_line.cpp @@ -93,7 +93,7 @@ namespace swrenderer // reject lines that aren't seen from the portal (if any) // [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes. - if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && P_ClipLineToPortal(line->linedef, renderportal->CurrentPortal->dst, Thread->Viewport->viewpoint.Pos)) + if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && P_ClipLineToPortal(line->linedef, renderportal->CurrentPortal->dst, Thread->Viewport->viewpoint.Pos.XY())) return; mFrontCeilingZ1 = mFrontSector->ceilingplane.ZatPoint(line->v1); diff --git a/src/rendering/swrenderer/line/r_line.cpp b/src/rendering/swrenderer/line/r_line.cpp index 1a6717450..c09801d5a 100644 --- a/src/rendering/swrenderer/line/r_line.cpp +++ b/src/rendering/swrenderer/line/r_line.cpp @@ -106,7 +106,7 @@ namespace swrenderer // reject lines that aren't seen from the portal (if any) // [ZZ] 10.01.2016: lines inside a skybox shouldn't be clipped, although this imposes some limitations on portals in skyboxes. - if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && P_ClipLineToPortal(line->linedef, renderportal->CurrentPortal->dst, Thread->Viewport->viewpoint.Pos)) + if (!renderportal->CurrentPortalInSkybox && renderportal->CurrentPortal && P_ClipLineToPortal(line->linedef, renderportal->CurrentPortal->dst, Thread->Viewport->viewpoint.Pos.XY())) return; mFrontCeilingZ1 = mFrontSector->ceilingplane.ZatPoint(line->v1); diff --git a/src/rendering/swrenderer/plane/r_slopeplane.cpp b/src/rendering/swrenderer/plane/r_slopeplane.cpp index 808a1a0b7..0a13c11eb 100644 --- a/src/rendering/swrenderer/plane/r_slopeplane.cpp +++ b/src/rendering/swrenderer/plane/r_slopeplane.cpp @@ -89,7 +89,7 @@ namespace swrenderer auto viewport = Thread->Viewport.get(); // Stupid way of doing it, but at least it works - DVector3 worldP0(viewport->viewpoint.Pos, pl->height.ZatPoint(viewport->viewpoint.Pos)); + DVector3 worldP0(viewport->viewpoint.Pos.XY(), pl->height.ZatPoint(viewport->viewpoint.Pos)); DVector3 worldP1 = worldP0 + pl->height.Normal(); DVector3 viewP0 = viewport->PointWorldToView(worldP0); DVector3 viewP1 = viewport->PointWorldToView(worldP1); diff --git a/src/rendering/swrenderer/scene/r_opaque_pass.cpp b/src/rendering/swrenderer/scene/r_opaque_pass.cpp index bcd864d05..b688ef636 100644 --- a/src/rendering/swrenderer/scene/r_opaque_pass.cpp +++ b/src/rendering/swrenderer/scene/r_opaque_pass.cpp @@ -853,7 +853,7 @@ namespace swrenderer node_t *bsp = (node_t *)node; // Decide which side the view point is on. - int side = R_PointOnSide(Thread->Viewport->viewpoint.Pos, bsp); + int side = R_PointOnSide(Thread->Viewport->viewpoint.Pos.XY(), bsp); // Recursively divide front space (toward the viewer). RenderBSPNode(bsp->children[side]); diff --git a/src/rendering/swrenderer/things/r_particle.cpp b/src/rendering/swrenderer/things/r_particle.cpp index 23a859c0e..058a2609a 100644 --- a/src/rendering/swrenderer/things/r_particle.cpp +++ b/src/rendering/swrenderer/things/r_particle.cpp @@ -90,7 +90,7 @@ namespace swrenderer RenderPortal *renderportal = thread->Portal.get(); // [ZZ] Particle not visible through the portal plane - if (renderportal->CurrentPortal && !!P_PointOnLineSide(particle->Pos, renderportal->CurrentPortal->dst)) + if (renderportal->CurrentPortal && !!P_PointOnLineSide(particle->Pos.XY(), renderportal->CurrentPortal->dst)) return; // transform the origin point diff --git a/src/rendering/swrenderer/things/r_visiblesprite.cpp b/src/rendering/swrenderer/things/r_visiblesprite.cpp index 1878008cd..a91b851a4 100644 --- a/src/rendering/swrenderer/things/r_visiblesprite.cpp +++ b/src/rendering/swrenderer/things/r_visiblesprite.cpp @@ -193,7 +193,7 @@ namespace swrenderer { // only things in specially marked sectors if (spr->FakeFlatStat != WaterFakeSide::AboveCeiling) { - double hz = spr->heightsec->floorplane.ZatPoint(spr->gpos); + double hz = spr->heightsec->floorplane.ZatPoint(spr->gpos.XY()); int h = xs_RoundToInt(viewport->CenterY - (hz - viewport->viewpoint.Pos.Z) * scale); if (spr->FakeFlatStat == WaterFakeSide::BelowFloor) @@ -215,7 +215,7 @@ namespace swrenderer } if (spr->FakeFlatStat != WaterFakeSide::BelowFloor && !(spr->heightsec->MoreFlags & SECMF_FAKEFLOORONLY)) { - double hz = spr->heightsec->ceilingplane.ZatPoint(spr->gpos); + double hz = spr->heightsec->ceilingplane.ZatPoint(spr->gpos.XY()); int h = xs_RoundToInt(viewport->CenterY - (hz - viewport->viewpoint.Pos.Z) * scale); if (spr->FakeFlatStat == WaterFakeSide::AboveCeiling) diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index 31a46ca2d..c46e1dfa9 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -946,7 +946,7 @@ static void CalcSectorSoundOrg(const DVector3& listenpos, const sector_t* sec, i // Find the closest point on the sector's boundary lines and use // that as the perceived origin of the sound. DVector2 xy; - sec->ClosestPoint(listenpos, xy); + sec->ClosestPoint(listenpos.XY(), xy); pos.X = (float)xy.X; pos.Z = (float)xy.Y; } @@ -989,7 +989,7 @@ static void CalcPolyobjSoundOrg(const DVector3& listenpos, const FPolyObj* poly, sector_t* sec; DVector2 ppos; - poly->ClosestPoint(listenpos, ppos, &side); + poly->ClosestPoint(listenpos.XY(), ppos, &side); pos.X = (float)ppos.X; pos.Z = (float)ppos.Y; sec = side->sector; From c94c63110eb5f1f680f0b19f1996dd2a24a5a5ae Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Oct 2023 23:03:40 +0200 Subject: [PATCH 193/223] added a third batch of GetChars call to FStrings. --- src/common/audio/music/i_music.cpp | 6 +- src/common/audio/sound/i_sound.cpp | 2 +- src/common/engine/i_net.cpp | 4 +- src/common/engine/stringtable.h | 1 + src/common/rendering/gl/gl_renderbuffers.cpp | 4 +- src/common/rendering/gl/gl_shader.cpp | 10 +- src/common/rendering/gl/gl_shaderprogram.cpp | 10 +- .../hwrenderer/data/hw_shaderpatcher.cpp | 2 +- .../hw_postprocessshader_ccmds.cpp | 6 +- src/common/scripting/core/imports.cpp | 4 +- src/common/startscreen/endoom.cpp | 2 +- src/common/textures/gametexture.cpp | 4 +- .../libsmackerdec/src/FileStream.cpp | 2 +- src/common/utility/engineerrors.cpp | 2 +- src/console/c_notifybuffer.cpp | 4 +- src/d_netinfo.cpp | 18 +-- src/events.cpp | 2 +- src/g_dumpinfo.cpp | 2 +- src/g_game.cpp | 60 +++++----- src/g_level.cpp | 106 +++++++++--------- src/g_statusbar/hudmessages.cpp | 18 +-- src/gameconfigfile.cpp | 4 +- src/gamedata/g_mapinfo.cpp | 34 +++--- src/gamedata/g_skill.cpp | 6 +- src/gamedata/gi.cpp | 4 +- src/intermission/intermission.cpp | 18 +-- src/intermission/intermission_parse.cpp | 4 +- src/maploader/edata.cpp | 4 +- src/maploader/glnodes.cpp | 14 +-- src/menu/doommenu.cpp | 58 +++++----- src/r_data/gldefs.cpp | 18 +-- 31 files changed, 216 insertions(+), 217 deletions(-) diff --git a/src/common/audio/music/i_music.cpp b/src/common/audio/music/i_music.cpp index b3f0a3d0d..9f6165102 100644 --- a/src/common/audio/music/i_music.cpp +++ b/src/common/audio/music/i_music.cpp @@ -312,8 +312,8 @@ static ZMusic_MidiSource GetMIDISource(const char *fn) FString src = fn; if (src.Compare("*") == 0) src = mus_playing.name; - auto lump = fileSystem.CheckNumForName(src, ns_music); - if (lump < 0) lump = fileSystem.CheckNumForFullName(src); + auto lump = fileSystem.CheckNumForName(src.GetChars(), ns_music); + if (lump < 0) lump = fileSystem.CheckNumForFullName(src.GetChars()); if (lump < 0) { Printf("Cannot find MIDI lump %s.\n", src.GetChars()); @@ -391,7 +391,7 @@ UNSAFE_CCMD (writewave) Printf("MIDI dump of %s failed: %s\n",argv[1], ZMusic_GetLastError()); } - S_ChangeMusic(savedsong.name, savedsong.baseorder, savedsong.loop, true); + S_ChangeMusic(savedsong.name.GetChars(), savedsong.baseorder, savedsong.loop, true); } else { diff --git a/src/common/audio/sound/i_sound.cpp b/src/common/audio/sound/i_sound.cpp index 5f9fdda18..dda757e8d 100644 --- a/src/common/audio/sound/i_sound.cpp +++ b/src/common/audio/sound/i_sound.cpp @@ -248,7 +248,7 @@ public: void I_InitSound () { - FModule_SetProgDir(progdir); + FModule_SetProgDir(progdir.GetChars()); /* Get command line options: */ nosound = !!Args->CheckParm ("-nosound"); nosfx = !!Args->CheckParm ("-nosfx"); diff --git a/src/common/engine/i_net.cpp b/src/common/engine/i_net.cpp index 07dc7fdd9..65dc60cb1 100644 --- a/src/common/engine/i_net.cpp +++ b/src/common/engine/i_net.cpp @@ -419,12 +419,12 @@ void BuildAddress (sockaddr_in *address, const char *name) if (!isnamed) { - address->sin_addr.s_addr = inet_addr (target); + address->sin_addr.s_addr = inet_addr (target.GetChars()); Printf ("Node number %d, address %s\n", doomcom.numnodes, target.GetChars()); } else { - hostentry = gethostbyname (target); + hostentry = gethostbyname (target.GetChars()); if (!hostentry) I_FatalError ("gethostbyname: couldn't find %s\n%s", target.GetChars(), neterror()); address->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; diff --git a/src/common/engine/stringtable.h b/src/common/engine/stringtable.h index 6850f8832..57827aa04 100644 --- a/src/common/engine/stringtable.h +++ b/src/common/engine/stringtable.h @@ -97,6 +97,7 @@ public: bool MatchDefaultString(const char *name, const char *content) const; const char *GetString(const char *name, uint32_t *langtable, int gender = -1) const; const char *operator() (const char *name) const; // Never returns NULL + const char* operator() (const FString& name) const { return operator()(name.GetChars()); } const char *operator[] (const char *name) const { return GetString(name, nullptr); diff --git a/src/common/rendering/gl/gl_renderbuffers.cpp b/src/common/rendering/gl/gl_renderbuffers.cpp index 4f49cdce3..3ce335d7a 100644 --- a/src/common/rendering/gl/gl_renderbuffers.cpp +++ b/src/common/rendering/gl/gl_renderbuffers.cpp @@ -836,8 +836,8 @@ FShaderProgram *GLPPRenderState::GetGLShader(PPShader *shader) prolog = UniformBlockDecl::Create("Uniforms", shader->Uniforms, POSTPROCESS_BINDINGPOINT); prolog += shader->Defines; - glshader->Compile(FShaderProgram::Vertex, shader->VertexShader, "", shader->Version); - glshader->Compile(FShaderProgram::Fragment, shader->FragmentShader, prolog, shader->Version); + glshader->Compile(FShaderProgram::Vertex, shader->VertexShader.GetChars(), "", shader->Version); + glshader->Compile(FShaderProgram::Fragment, shader->FragmentShader.GetChars(), prolog.GetChars(), shader->Version); glshader->Link(shader->FragmentShader.GetChars()); if (!shader->Uniforms.empty()) glshader->SetUniformBufferLocation(POSTPROCESS_BINDINGPOINT, "Uniforms"); diff --git a/src/common/rendering/gl/gl_shader.cpp b/src/common/rendering/gl/gl_shader.cpp index afa05b863..7340236ab 100644 --- a/src/common/rendering/gl/gl_shader.cpp +++ b/src/common/rendering/gl/gl_shader.cpp @@ -109,7 +109,7 @@ static FString CalcProgramBinaryChecksum(const FString &vertex, const FString &f static FString CreateProgramCacheName(bool create) { FString path = M_GetCachePath(create); - if (create) CreatePath(path); + if (create) CreatePath(path.GetChars()); path << "/shadercache.zdsc"; return path; } @@ -125,7 +125,7 @@ static void LoadShaders() { FString path = CreateProgramCacheName(false); FileReader fr; - if (!fr.OpenFile(path)) + if (!fr.OpenFile(path.GetChars())) I_Error("Could not open shader file"); char magic[4]; @@ -166,7 +166,7 @@ static void LoadShaders() static void SaveShaders() { FString path = CreateProgramCacheName(true); - std::unique_ptr fw(FileWriter::Open(path)); + std::unique_ptr fw(FileWriter::Open(path.GetChars())); if (fw) { uint32_t count = (uint32_t)ShaderCache.size(); @@ -837,9 +837,9 @@ bool FShaderCollection::CompileNextShader() } else if (mCompileState == 2) { - FString name = ExtractFileBase(usershaders[i].shader); + FString name = ExtractFileBase(usershaders[i].shader.GetChars()); FString defines = defaultshaders[usershaders[i].shaderType].Defines + usershaders[i].defines; - FShader *shc = Compile(name, usershaders[i].shader, defaultshaders[usershaders[i].shaderType].lightfunc, defines, true, mPassType); + FShader *shc = Compile(name.GetChars(), usershaders[i].shader.GetChars(), defaultshaders[usershaders[i].shaderType].lightfunc, defines.GetChars(), true, mPassType); mMaterialShaders.Push(shc); mCompileIndex++; if (mCompileIndex >= (int)usershaders.Size()) diff --git a/src/common/rendering/gl/gl_shaderprogram.cpp b/src/common/rendering/gl/gl_shaderprogram.cpp index feca86aa8..d5e8dd321 100644 --- a/src/common/rendering/gl/gl_shaderprogram.cpp +++ b/src/common/rendering/gl/gl_shaderprogram.cpp @@ -107,7 +107,7 @@ void FShaderProgram::CompileShader(ShaderType type) const auto &handle = mShaders[type]; - FGLDebug::LabelObject(GL_SHADER, handle, mShaderNames[type]); + FGLDebug::LabelObject(GL_SHADER, handle, mShaderNames[type].GetChars()); const FString &patchedCode = mShaderSources[type]; int lengths[1] = { (int)patchedCode.Len() }; @@ -186,7 +186,7 @@ void FShaderProgram::Link(const char *name) glUseProgram(mProgram); for (auto &uni : samplerstobind) { - auto index = glGetUniformLocation(mProgram, uni.first); + auto index = glGetUniformLocation(mProgram, uni.first.GetChars()); if (index >= 0) { glUniform1i(index, uni.second); @@ -300,8 +300,8 @@ void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program FString prolog = Uniforms.CreateDeclaration("Uniforms", PresentUniforms::Desc()); mShader.reset(new FShaderProgram()); - mShader->Compile(FShaderProgram::Vertex, "shaders/pp/screenquad.vp", prolog, 330); - mShader->Compile(FShaderProgram::Fragment, vtx_shader_name, prolog, 330); + mShader->Compile(FShaderProgram::Vertex, "shaders/pp/screenquad.vp", prolog.GetChars(), 330); + mShader->Compile(FShaderProgram::Fragment, vtx_shader_name, prolog.GetChars(), 330); mShader->Link(program_name); mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms"); Uniforms.Init(); @@ -355,7 +355,7 @@ void FShadowMapShader::Bind() mShader.reset(new FShaderProgram()); mShader->Compile(FShaderProgram::Vertex, "shaders/pp/screenquad.vp", "", 430); - mShader->Compile(FShaderProgram::Fragment, "shaders/pp/shadowmap.fp", prolog, 430); + mShader->Compile(FShaderProgram::Fragment, "shaders/pp/shadowmap.fp", prolog.GetChars(), 430); mShader->Link("shaders/glsl/shadowmap"); mShader->SetUniformBufferLocation(Uniforms.BindingPoint(), "Uniforms"); Uniforms.Init(); diff --git a/src/common/rendering/hwrenderer/data/hw_shaderpatcher.cpp b/src/common/rendering/hwrenderer/data/hw_shaderpatcher.cpp index 2b391d185..9049e5090 100644 --- a/src/common/rendering/hwrenderer/data/hw_shaderpatcher.cpp +++ b/src/common/rendering/hwrenderer/data/hw_shaderpatcher.cpp @@ -188,7 +188,7 @@ FString RemoveSamplerBindings(FString code, TArray> &sam FString type = NextGlslToken(chars, len, pos); FString identifier = NextGlslToken(chars, len, pos); - isSamplerUniformName = uniform.Compare("uniform") == 0 && isShaderType(type); + isSamplerUniformName = uniform.Compare("uniform") == 0 && isShaderType(type.GetChars()); if (isSamplerUniformName) { samplerstobind.Push(std::make_pair(identifier, val)); diff --git a/src/common/rendering/hwrenderer/postprocessing/hw_postprocessshader_ccmds.cpp b/src/common/rendering/hwrenderer/postprocessing/hw_postprocessshader_ccmds.cpp index 4608b9ce9..7ab93b3ec 100644 --- a/src/common/rendering/hwrenderer/postprocessing/hw_postprocessshader_ccmds.cpp +++ b/src/common/rendering/hwrenderer/postprocessing/hw_postprocessshader_ccmds.cpp @@ -39,7 +39,7 @@ CCMD (shaderenable) for (unsigned int i = 0; i < PostProcessShaders.Size(); i++) { PostProcessShader &shader = PostProcessShaders[i]; - if (strcmp(shader.Name, shaderName) == 0) + if (shader.Name.Compare(shaderName) == 0) { if (value != -1) shader.Enabled = value; @@ -70,7 +70,7 @@ CCMD (shaderuniform) for (unsigned int i = 0; i < PostProcessShaders.Size(); i++) { PostProcessShader &shader = PostProcessShaders[i]; - if (strcmp(shader.Name, shaderName) == 0) + if (shader.Name.Compare(shaderName) == 0) { if (argv.argc() > 3) { @@ -116,7 +116,7 @@ CCMD(listuniforms) for (unsigned int i = 0; i < PostProcessShaders.Size(); i++) { PostProcessShader &shader = PostProcessShaders[i]; - if (strcmp(shader.Name, shaderName) == 0) + if (shader.Name.Compare(shaderName) == 0) { Printf("Shader '%s' uniforms:\n", shaderName); diff --git a/src/common/scripting/core/imports.cpp b/src/common/scripting/core/imports.cpp index 3006462cd..eed84980a 100644 --- a/src/common/scripting/core/imports.cpp +++ b/src/common/scripting/core/imports.cpp @@ -198,8 +198,8 @@ void InitImports() { assert(afunc->VMPointer != NULL); *(afunc->VMPointer) = new VMNativeFunction(afunc->Function, afunc->FuncName); - (*(afunc->VMPointer))->QualifiedName = ClassDataAllocator.Strdup(FStringf("%s.%s", afunc->ClassName + 1, afunc->FuncName)); - (*(afunc->VMPointer))->PrintableName = ClassDataAllocator.Strdup(FStringf("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName)); + (*(afunc->VMPointer))->QualifiedName = ClassDataAllocator.Strdup(FStringf("%s.%s", afunc->ClassName + 1, afunc->FuncName).GetChars()); + (*(afunc->VMPointer))->PrintableName = ClassDataAllocator.Strdup(FStringf("%s.%s [Native]", afunc->ClassName+1, afunc->FuncName).GetChars()); (*(afunc->VMPointer))->DirectNativeCall = afunc->DirectNative; AFTable.Push(*afunc); }); diff --git a/src/common/startscreen/endoom.cpp b/src/common/startscreen/endoom.cpp index 0fff948c0..4a7565dbc 100644 --- a/src/common/startscreen/endoom.cpp +++ b/src/common/startscreen/endoom.cpp @@ -153,7 +153,7 @@ int RunEndoom() return 0; } - int endoom_lump = fileSystem.CheckNumForFullName (endoomName, true); + int endoom_lump = fileSystem.CheckNumForFullName (endoomName.GetChars(), true); if (endoom_lump < 0 || fileSystem.FileLength (endoom_lump) != 4000) { diff --git a/src/common/textures/gametexture.cpp b/src/common/textures/gametexture.cpp index 2c873d15f..755f48b49 100644 --- a/src/common/textures/gametexture.cpp +++ b/src/common/textures/gametexture.cpp @@ -182,7 +182,7 @@ void FGameTexture::AddAutoMaterials() if (this->*(layer.pointer) == nullptr) // only if no explicit assignment had been done. { FStringf lookup("%s%s%s", layer.path, fullname ? "" : "auto/", searchname.GetChars()); - auto lump = fileSystem.CheckNumForFullName(lookup, false, FileSys::ns_global, true); + auto lump = fileSystem.CheckNumForFullName(lookup.GetChars(), false, FileSys::ns_global, true); if (lump != -1) { auto bmtex = TexMan.FindGameTexture(fileSystem.GetFileFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny); @@ -199,7 +199,7 @@ void FGameTexture::AddAutoMaterials() if (!this->Layers || this->Layers.get()->*(layer.pointer) == nullptr) // only if no explicit assignment had been done. { FStringf lookup("%s%s%s", layer.path, fullname ? "" : "auto/", searchname.GetChars()); - auto lump = fileSystem.CheckNumForFullName(lookup, false, FileSys::ns_global, true); + auto lump = fileSystem.CheckNumForFullName(lookup.GetChars(), false, FileSys::ns_global, true); if (lump != -1) { auto bmtex = TexMan.FindGameTexture(fileSystem.GetFileFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny); diff --git a/src/common/thirdparty/libsmackerdec/src/FileStream.cpp b/src/common/thirdparty/libsmackerdec/src/FileStream.cpp index 454143ff1..f7845136b 100644 --- a/src/common/thirdparty/libsmackerdec/src/FileStream.cpp +++ b/src/common/thirdparty/libsmackerdec/src/FileStream.cpp @@ -28,7 +28,7 @@ bool FileStream::Open(const char *fileName) { FString fixedname = fileName; FixPathSeperator(fixedname); - file = fileSystem.OpenFileReader(fixedname); + file = fileSystem.OpenFileReader(fixedname.GetChars()); if (!file.isOpen()) { // log error diff --git a/src/common/utility/engineerrors.cpp b/src/common/utility/engineerrors.cpp index 4d0125819..41485778a 100644 --- a/src/common/utility/engineerrors.cpp +++ b/src/common/utility/engineerrors.cpp @@ -60,7 +60,7 @@ void I_DebugPrintf(const char *fmt,...) va_end(args); - auto wstr = WideString(s); + auto wstr = WideString(s.GetChars()); OutputDebugStringW(wstr.c_str()); } } diff --git a/src/console/c_notifybuffer.cpp b/src/console/c_notifybuffer.cpp index d25b320e4..4c394c376 100644 --- a/src/console/c_notifybuffer.cpp +++ b/src/console/c_notifybuffer.cpp @@ -146,7 +146,7 @@ void FNotifyBuffer::Draw() int scale = active_con_scaletext(twod, generic_ui); if (!center) - DrawText(twod, font, color, 0, line, notify.Text, + DrawText(twod, font, color, 0, line, notify.Text.GetChars(), DTA_VirtualWidth, twod->GetWidth() / scale, DTA_VirtualHeight, twod->GetHeight() / scale, DTA_KeepRatio, true, @@ -154,7 +154,7 @@ void FNotifyBuffer::Draw() else DrawText(twod, font, color, (twod->GetWidth() - font->StringWidth (notify.Text) * scale) / 2 / scale, - line, notify.Text, + line, notify.Text.GetChars(), DTA_VirtualWidth, twod->GetWidth() / scale, DTA_VirtualHeight, twod->GetHeight() / scale, DTA_KeepRatio, true, diff --git a/src/d_netinfo.cpp b/src/d_netinfo.cpp index 0db1c94e6..51c6e0dc0 100644 --- a/src/d_netinfo.cpp +++ b/src/d_netinfo.cpp @@ -161,7 +161,7 @@ int D_PlayerClassToInt (const char *classname) { auto type = PlayerClasses[i].Type; - if (type->GetDisplayName().IsNotEmpty() && stricmp(type->GetDisplayName(), classname) == 0) + if (type->GetDisplayName().IsNotEmpty() && type->GetDisplayName().CompareNoCase(classname) == 0) { return i; } @@ -786,7 +786,7 @@ FString D_GetUserInfoStrings(int pnum, bool compact) break; case NAME_Skin: - result.AppendFormat("\\%s", D_EscapeUserInfo(Skins[info->GetSkin()].Name).GetChars()); + result.AppendFormat("\\%s", D_EscapeUserInfo(Skins[info->GetSkin()].Name.GetChars()).GetChars()); break; default: @@ -870,15 +870,15 @@ void D_ReadUserInfoStrings (int pnum, uint8_t **stream, bool update) switch (keyname.GetIndex()) { case NAME_Gender: - info->GenderChanged(value); + info->GenderChanged(value.GetChars()); break; case NAME_PlayerClass: - info->PlayerClassChanged(value); + info->PlayerClassChanged(value.GetChars()); break; case NAME_Skin: - info->SkinChanged(value, players[pnum].CurrentPlayerClass); + info->SkinChanged(value.GetChars(), players[pnum].CurrentPlayerClass); if (players[pnum].mo != NULL) { if (players[pnum].cls != NULL && @@ -895,11 +895,11 @@ void D_ReadUserInfoStrings (int pnum, uint8_t **stream, bool update) break; case NAME_Team: - UpdateTeam(pnum, atoi(value), update); + UpdateTeam(pnum, atoi(value.GetChars()), update); break; case NAME_Color: - info->ColorChanged(value); + info->ColorChanged(value.GetChars()); break; default: @@ -956,7 +956,7 @@ void WriteUserInfo(FSerializer &arc, userinfo_t &info) switch (pair->Key.GetIndex()) { case NAME_Skin: - string = Skins[info.GetSkin()].Name; + string = Skins[info.GetSkin()].Name.GetChars(); break; case NAME_PlayerClass: @@ -969,7 +969,7 @@ void WriteUserInfo(FSerializer &arc, userinfo_t &info) string = val.String; break; } - arc.StringPtr(name, string); + arc.StringPtr(name.GetChars(), string); } arc.EndObject(); } diff --git a/src/events.cpp b/src/events.cpp index d179ac50a..3fe1cef31 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -166,7 +166,7 @@ bool EventManager::SendNetworkEvent(FString name, int arg1, int arg2, int arg3, return false; Net_WriteByte(DEM_NETEVENT); - Net_WriteString(name); + Net_WriteString(name.GetChars()); Net_WriteByte(3); Net_WriteLong(arg1); Net_WriteLong(arg2); diff --git a/src/g_dumpinfo.cpp b/src/g_dumpinfo.cpp index 96951df6f..768733d44 100644 --- a/src/g_dumpinfo.cpp +++ b/src/g_dumpinfo.cpp @@ -366,7 +366,7 @@ CCMD(listmaps) for (unsigned i = 0; i < wadlevelinfos.Size(); i++) { level_info_t *info = &wadlevelinfos[i]; - MapData *map = P_OpenMapData(info->MapName, true); + MapData *map = P_OpenMapData(info->MapName.GetChars(), true); if (map != NULL) { diff --git a/src/g_game.cpp b/src/g_game.cpp index ba3b8ea4b..6d891a2e4 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -770,8 +770,8 @@ void G_BuildTiccmd (ticcmd_t *cmd) { sendsave = false; Net_WriteByte (DEM_SAVEGAME); - Net_WriteString (savegamefile); - Net_WriteString (savedescription); + Net_WriteString (savegamefile.GetChars()); + Net_WriteString (savedescription.GetChars()); savegamefile = ""; } if (SendItemUse == (const AActor *)1) @@ -1142,8 +1142,8 @@ void G_Ticker () { case ga_recordgame: G_CheckDemoStatus(); - G_RecordDemo(newdemoname); - G_BeginRecording(newdemomap); + G_RecordDemo(newdemoname.GetChars()); + G_BeginRecording(newdemomap.GetChars()); [[fallthrough]]; case ga_newgame2: // Silence GCC (see above) case ga_newgame: @@ -1155,7 +1155,7 @@ void G_Ticker () G_DoLoadGame (); break; case ga_savegame: - G_DoSaveGame (true, false, savegamefile, savedescription); + G_DoSaveGame (true, false, savegamefile, savedescription.GetChars()); gameaction = ga_nothing; savegamefile = ""; savedescription = ""; @@ -1177,7 +1177,7 @@ void G_Ticker () G_DoWorldDone (); break; case ga_screenshot: - M_ScreenShot (shotfile); + M_ScreenShot (shotfile.GetChars()); shotfile = ""; gameaction = ga_nothing; break; @@ -1732,7 +1732,7 @@ void FLevelLocals::DoReborn (int playernum, bool freshbot) { // Reload the level from scratch bool indemo = demoplayback; BackupSaveName = ""; - G_InitNew (MapName, false); + G_InitNew (MapName.GetChars(), false); demoplayback = indemo; } } @@ -1893,9 +1893,9 @@ bool G_CheckSaveGameWads (FSerializer &arc, bool printwarn) FString text; arc("Game WAD", text); - CheckSingleWad (text, printRequires, printwarn); + CheckSingleWad (text.GetChars(), printRequires, printwarn); arc("Map WAD", text); - CheckSingleWad (text, printRequires, printwarn); + CheckSingleWad (text.GetChars(), printRequires, printwarn); if (printRequires) { @@ -2035,7 +2035,7 @@ void G_DoLoadGame () message.Substitute("%e", FStringf("%d", SAVEVER)); } message.Substitute("%d", FStringf("%d", SaveVersion)); - LoadGameError(message); + LoadGameError(message.GetChars()); return; } @@ -2107,7 +2107,7 @@ void G_DoLoadGame () // load a base level bool demoplaybacksave = demoplayback; - G_InitNew(map, false); + G_InitNew(map.GetChars(), false); demoplayback = demoplaybacksave; savegamerestore = false; @@ -2129,7 +2129,7 @@ void G_DoLoadGame () { FString modelFilePath = smf.Left(smf.LastIndexOf("/")+1); FString modelFileName = smf.Right(smf.Len() - smf.Left(smf.LastIndexOf("/") + 1).Len()); - FindModel(modelFilePath, modelFileName); + FindModel(modelFilePath.GetChars(), modelFileName.GetChars()); } // At this point, the GC threshold is likely a lot higher than the @@ -2173,8 +2173,8 @@ void G_SaveGame (const char *filename, const char *description) CCMD(opensaves) { FString name = G_GetSavegamesFolder(); - CreatePath(name); - I_OpenShellFolder(name); + CreatePath(name.GetChars()); + I_OpenShellFolder(name.GetChars()); } CVAR (Int, autosavenum, 0, CVAR_NOSET|CVAR_ARCHIVE|CVAR_GLOBALCONFIG) @@ -2212,7 +2212,7 @@ void G_DoAutoSave () num.Int = nextautosave; autosavenum->ForceSet (num, CVAR_Int); - file = G_BuildSaveName(FStringf("auto%02d", nextautosave)); + file = G_BuildSaveName(FStringf("auto%02d", nextautosave).GetChars()); // The hint flag is only relevant on the primary level. if (!(primaryLevel->flags2 & LEVEL2_NOAUTOSAVEHINT)) @@ -2227,7 +2227,7 @@ void G_DoAutoSave () readableTime = myasctime (); description.Format("Autosave %s", readableTime); - G_DoSaveGame (false, false, file, description); + G_DoSaveGame (false, false, file, description.GetChars()); } void G_DoQuickSave () @@ -2251,11 +2251,11 @@ void G_DoQuickSave () num.Int = lastquicksave; quicksavenum->ForceSet (num, CVAR_Int); - file = G_BuildSaveName(FStringf("quick%02d", lastquicksave)); + file = G_BuildSaveName(FStringf("quick%02d", lastquicksave).GetChars()); readableTime = myasctime (); description.Format("Quicksave %s", readableTime); - G_DoSaveGame (true, true, file, description); + G_DoSaveGame (true, true, file, description.GetChars()); } @@ -2281,7 +2281,7 @@ static void PutSaveComment (FSerializer &arc) FString comment = myasctime(); - arc.AddString("Creation Time", comment); + arc.AddString("Creation Time", comment.GetChars()); // Get level name comment.Format("%s - %s\n", primaryLevel->MapName.GetChars(), primaryLevel->LevelName.GetChars()); @@ -2292,7 +2292,7 @@ static void PutSaveComment (FSerializer &arc) comment.AppendFormat("%s: %02d:%02d:%02d", time, levelTime/3600, (levelTime%3600)/60, levelTime%60); // Write out the comment - arc.AddString("Comment", comment); + arc.AddString("Comment", comment.GetChars()); } static void PutSavePic (FileWriter *file, int width, int height) @@ -2370,7 +2370,7 @@ void G_DoSaveGame (bool okForQuicksave, bool forceQuicksave, FString filename, c // put some basic info into the PNG so that this isn't lost when the image gets extracted. M_AppendPNGText(&savepic, "Software", buf); M_AppendPNGText(&savepic, "Title", description); - M_AppendPNGText(&savepic, "Current Map", primaryLevel->MapName); + M_AppendPNGText(&savepic, "Current Map", primaryLevel->MapName.GetChars()); M_FinishPNG(&savepic); int ver = SAVEVER; @@ -2378,7 +2378,7 @@ void G_DoSaveGame (bool okForQuicksave, bool forceQuicksave, FString filename, c .AddString("Engine", GAMESIG) ("Save Version", ver) .AddString("Title", description) - .AddString("Current Map", primaryLevel->MapName); + .AddString("Current Map", primaryLevel->MapName.GetChars()); PutSaveWads (savegameinfo); @@ -2423,10 +2423,10 @@ void G_DoSaveGame (bool okForQuicksave, bool forceQuicksave, FString filename, c bool succeeded = false; - if (WriteZip(filename, savegame_content.Data(), savegame_content.Size())) + if (WriteZip(filename.GetChars(), savegame_content.Data(), savegame_content.Size())) { // Check whether the file is ok by trying to open it. - FResourceFile *test = FResourceFile::OpenResourceFile(filename, true); + FResourceFile *test = FResourceFile::OpenResourceFile(filename.GetChars(), true); if (test != nullptr) { delete test; @@ -2595,7 +2595,7 @@ void G_BeginRecording (const char *startmap) if (startmap == NULL) { - startmap = primaryLevel->MapName; + startmap = primaryLevel->MapName.GetChars(); } demo_p = demobuffer; @@ -2861,7 +2861,7 @@ void G_DoPlayDemo (void) gameaction = ga_nothing; // [RH] Allow for demos not loaded as lumps - demolump = fileSystem.CheckNumForFullName (defdemoname, true); + demolump = fileSystem.CheckNumForFullName (defdemoname.GetChars(), true); if (demolump >= 0) { int demolen = fileSystem.FileLength (demolump); @@ -2873,7 +2873,7 @@ void G_DoPlayDemo (void) FixPathSeperator (defdemoname); DefaultExtension (defdemoname, ".lmp"); FileReader fr; - if (!fr.OpenFile(defdemoname)) + if (!fr.OpenFile(defdemoname.GetChars())) { I_Error("Unable to open demo '%s'", defdemoname.GetChars()); } @@ -2920,7 +2920,7 @@ void G_DoPlayDemo (void) demonew = true; if (mapname.Len() != 0) { - G_InitNew (mapname, false); + G_InitNew (mapname.GetChars(), false); } else if (primaryLevel->sectors.Size() == 0) { @@ -3048,14 +3048,14 @@ bool G_CheckDemoStatus (void) formlen = demobuffer + 4; WriteLong (int(demo_p - demobuffer - 8), &formlen); - auto fw = FileWriter::Open(demoname); + auto fw = FileWriter::Open(demoname.GetChars()); bool saved = false; if (fw != nullptr) { const size_t size = demo_p - demobuffer; saved = fw->Write(demobuffer, size) == size; delete fw; - if (!saved) remove(demoname); + if (!saved) remove(demoname.GetChars()); } M_Free (demobuffer); demorecording = false; diff --git a/src/g_level.cpp b/src/g_level.cpp index 474f85a38..953980386 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -238,7 +238,7 @@ bool CreateCutscene(CutsceneDef* cs, DObject* runner, level_info_t* map) return true; // play nothing but return as being validated if (cs->function.IsNotEmpty()) { - CallCreateMapFunction(cs->function, runner, map); + CallCreateMapFunction(cs->function.GetChars(), runner, map); return true; } else if (cs->video.IsNotEmpty()) @@ -270,7 +270,7 @@ void G_DeferedInitNew (const char *mapname, int newskill) void G_DeferedInitNew (FNewGameStartup *gs) { - if (gs->hasPlayerClass) playerclass = gs->PlayerClass; + if (gs->hasPlayerClass) playerclass = gs->PlayerClass.GetChars(); d_mapname = AllEpisodes[gs->Episode].mEpisodeMap; d_skill = gs->Skill; CheckWarpTransMap (d_mapname, true); @@ -418,7 +418,7 @@ UNSAFE_CCMD (open) { d_mapname = "file:"; d_mapname += argv[1]; - if (!P_CheckMapData(d_mapname)) + if (!P_CheckMapData(d_mapname.GetChars())) { Printf ("No map %s\n", d_mapname.GetChars()); } @@ -515,7 +515,7 @@ void G_DoNewGame (void) { gameskill = d_skill; } - G_InitNew (d_mapname, false); + G_InitNew (d_mapname.GetChars(), false); gameaction = ga_nothing; } @@ -574,8 +574,8 @@ void G_InitNew (const char *mapname, bool bTitleLevel) auto redirectmap = FindLevelInfo(mapname); if (redirectmap->RedirectCVAR != NAME_None) redirectmap = redirectmap->CheckLevelRedirect(); - if (redirectmap && redirectmap->MapName.GetChars()[0]) - mapname = redirectmap->MapName; + if (redirectmap && redirectmap->MapName.IsNotEmpty()) + mapname = redirectmap->MapName.GetChars(); } G_VerifySkill(); @@ -738,7 +738,7 @@ void FLevelLocals::ChangeLevel(const char *levelname, int position, int inflags, { FString reallevelname = levelname; CheckWarpTransMap(reallevelname, true); - nextinfo = FindLevelInfo (reallevelname, false); + nextinfo = FindLevelInfo (reallevelname.GetChars(), false); if (nextinfo != NULL) { level_info_t *nextredir = nextinfo->CheckLevelRedirect(); @@ -803,7 +803,7 @@ void FLevelLocals::ChangeLevel(const char *levelname, int position, int inflags, staticEventManager.WorldUnloaded(nextlevel); unloading = false; - STAT_ChangeLevel(nextlevel, this); + STAT_ChangeLevel(nextlevel.GetChars(), this); if (thiscluster && (thiscluster->flags & CLUSTER_HUB)) { @@ -850,7 +850,7 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, ChangeLevel) PARAM_INT(position); PARAM_INT(inflags); PARAM_INT(nextSkill); - self->ChangeLevel(levelname, position, inflags, nextSkill); + self->ChangeLevel(levelname.GetChars(), position, inflags, nextSkill); return 0; } @@ -861,13 +861,13 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, ChangeLevel) const char *FLevelLocals::GetSecretExitMap() { - const char *nextmap = NextMap; + const char *nextmap = NextMap.GetChars(); if (NextSecretMap.Len() > 0) { - if (NextSecretMap.Compare("enDSeQ", 6) == 0 || P_CheckMapData(NextSecretMap)) + if (NextSecretMap.Compare("enDSeQ", 6) == 0 || P_CheckMapData(NextSecretMap.GetChars())) { - nextmap = NextSecretMap; + nextmap = NextSecretMap.GetChars(); } } return nextmap; @@ -882,7 +882,7 @@ const char *FLevelLocals::GetSecretExitMap() void FLevelLocals::ExitLevel (int position, bool keepFacing) { flags3 |= LEVEL3_EXITNORMALUSED; - ChangeLevel(NextMap, position, keepFacing ? CHANGELEVEL_KEEPFACING : 0); + ChangeLevel(NextMap.GetChars(), position, keepFacing ? CHANGELEVEL_KEEPFACING : 0); } static void LevelLocals_ExitLevel(FLevelLocals *self, int position, bool keepFacing) @@ -935,7 +935,7 @@ DIntermissionController* FLevelLocals::CreateIntermission() thiscluster = FindClusterInfo (cluster); - bool endgame = strncmp (nextlevel, "enDSeQ", 6) == 0; + bool endgame = strncmp (nextlevel.GetChars(), "enDSeQ", 6) == 0; if (endgame) { FName endsequence = ENamedName(strtoll(nextlevel.GetChars()+6, NULL, 16)); @@ -956,11 +956,11 @@ DIntermissionController* FLevelLocals::CreateIntermission() auto ext = info->ExitMapTexts.CheckKey(flags3 & LEVEL3_EXITSECRETUSED ? NAME_Secret : NAME_Normal); if (ext != nullptr && (ext->mDefined & FExitText::DEF_TEXT)) { - controller = F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic, + controller = F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic.GetChars() : gameinfo.finaleMusic.GetChars(), ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder, -1, 0, - ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat, - ext->mText, + ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop.GetChars() : gameinfo.FinaleFlat.GetChars(), + ext->mText.GetChars(), false, ext->mDefined & FExitText::DEF_PIC, ext->mDefined & FExitText::DEF_LOOKUP, @@ -968,9 +968,9 @@ DIntermissionController* FLevelLocals::CreateIntermission() } else if (!(info->flags2 & LEVEL2_NOCLUSTERTEXT)) { - controller = F_StartFinale(thiscluster->MessageMusic, thiscluster->musicorder, + controller = F_StartFinale(thiscluster->MessageMusic.GetChars(), thiscluster->musicorder, thiscluster->cdtrack, thiscluster->cdid, - thiscluster->FinaleFlat, thiscluster->ExitText, + thiscluster->FinaleFlat.GetChars(), thiscluster->ExitText.GetChars(), thiscluster->flags & CLUSTER_EXITTEXTINLUMP, thiscluster->flags & CLUSTER_FINALEPIC, thiscluster->flags & CLUSTER_LOOKUPEXITTEXT, @@ -989,11 +989,11 @@ DIntermissionController* FLevelLocals::CreateIntermission() { if ((ext->mDefined & FExitText::DEF_TEXT)) { - controller = F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic, + controller = F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic.GetChars() : gameinfo.finaleMusic.GetChars(), ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder, -1, 0, - ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat, - ext->mText, + ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop.GetChars() : gameinfo.FinaleFlat.GetChars(), + ext->mText.GetChars(), false, ext->mDefined & FExitText::DEF_PIC, ext->mDefined & FExitText::DEF_LOOKUP, @@ -1002,7 +1002,7 @@ DIntermissionController* FLevelLocals::CreateIntermission() return controller; } - nextcluster = FindClusterInfo (FindLevelInfo (nextlevel)->cluster); + nextcluster = FindClusterInfo (FindLevelInfo (nextlevel.GetChars())->cluster); if (nextcluster->cluster != cluster && !(info->flags2 & LEVEL2_NOCLUSTERTEXT)) { @@ -1010,9 +1010,9 @@ DIntermissionController* FLevelLocals::CreateIntermission() // than the current one and we're not in deathmatch. if (nextcluster->EnterText.IsNotEmpty()) { - controller = F_StartFinale (nextcluster->MessageMusic, nextcluster->musicorder, + controller = F_StartFinale (nextcluster->MessageMusic.GetChars(), nextcluster->musicorder, nextcluster->cdtrack, nextcluster->cdid, - nextcluster->FinaleFlat, nextcluster->EnterText, + nextcluster->FinaleFlat.GetChars(), nextcluster->EnterText.GetChars(), nextcluster->flags & CLUSTER_ENTERTEXTINLUMP, nextcluster->flags & CLUSTER_FINALEPIC, nextcluster->flags & CLUSTER_LOOKUPENTERTEXT, @@ -1020,9 +1020,9 @@ DIntermissionController* FLevelLocals::CreateIntermission() } else if (thiscluster->ExitText.IsNotEmpty()) { - controller = F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder, + controller = F_StartFinale (thiscluster->MessageMusic.GetChars(), thiscluster->musicorder, thiscluster->cdtrack, nextcluster->cdid, - thiscluster->FinaleFlat, thiscluster->ExitText, + thiscluster->FinaleFlat.GetChars(), thiscluster->ExitText.GetChars(), thiscluster->flags & CLUSTER_EXITTEXTINLUMP, thiscluster->flags & CLUSTER_FINALEPIC, thiscluster->flags & CLUSTER_LOOKUPEXITTEXT, @@ -1128,9 +1128,9 @@ void G_DoCompleted (void) statusScreen = WI_Start (&staticWmInfo); } - bool endgame = strncmp(nextlevel, "enDSeQ", 6) == 0; + bool endgame = strncmp(nextlevel.GetChars(), "enDSeQ", 6) == 0; intermissionScreen = primaryLevel->CreateIntermission(); - auto nextinfo = !playinter || endgame? nullptr : FindLevelInfo(nextlevel, false); + auto nextinfo = !playinter || endgame? nullptr : FindLevelInfo(nextlevel.GetChars(), false); RunIntermission(primaryLevel->info, nextinfo, intermissionScreen, statusScreen, [=](bool) { if (!endgame) primaryLevel->WorldDone(); @@ -1155,7 +1155,7 @@ bool FLevelLocals::DoCompleted (FString nextlevel, wbstartstruct_t &wminfo) uint32_t langtable[2] = {}; wminfo.finished_ep = cluster - 1; - wminfo.LName0 = TexMan.CheckForTexture(info->PName, ETextureType::MiscPatch); + wminfo.LName0 = TexMan.CheckForTexture(info->PName.GetChars(), ETextureType::MiscPatch); wminfo.thisname = info->LookupLevelName(&langtable[0]); // re-get the name so we have more info about its origin. if (!wminfo.LName0.isValid() || !(info->flags3 & LEVEL3_HIDEAUTHORNAME)) wminfo.thisauthor = info->AuthorName; wminfo.current = MapName; @@ -1171,8 +1171,8 @@ bool FLevelLocals::DoCompleted (FString nextlevel, wbstartstruct_t &wminfo) } else { - level_info_t *nextinfo = FindLevelInfo (nextlevel, false); - if (nextinfo == NULL || strncmp (nextlevel, "enDSeQ", 6) == 0) + level_info_t *nextinfo = FindLevelInfo (nextlevel.GetChars(), false); + if (nextinfo == NULL || strncmp (nextlevel.GetChars(), "enDSeQ", 6) == 0) { wminfo.next = ""; wminfo.LName1.SetInvalid(); @@ -1182,7 +1182,7 @@ bool FLevelLocals::DoCompleted (FString nextlevel, wbstartstruct_t &wminfo) else { wminfo.next = nextinfo->MapName; - wminfo.LName1 = TexMan.CheckForTexture(nextinfo->PName, ETextureType::MiscPatch); + wminfo.LName1 = TexMan.CheckForTexture(nextinfo->PName.GetChars(), ETextureType::MiscPatch); wminfo.nextname = nextinfo->LookupLevelName(&langtable[1]); if (!wminfo.LName1.isValid() || !(nextinfo->flags3 & LEVEL3_HIDEAUTHORNAME)) wminfo.nextauthor = nextinfo->AuthorName; } @@ -1210,7 +1210,7 @@ bool FLevelLocals::DoCompleted (FString nextlevel, wbstartstruct_t &wminfo) CheckWarpTransMap (wminfo.next, true); nextlevel = wminfo.next; - wminfo.next_ep = FindLevelInfo (wminfo.next)->cluster - 1; + wminfo.next_ep = FindLevelInfo (wminfo.next.GetChars())->cluster - 1; wminfo.totalkills = killed_monsters; wminfo.maxkills = total_monsters; wminfo.maxitems = total_items; @@ -1411,7 +1411,7 @@ void FLevelLocals::DoLoadLevel(const FString &nextmapname, int position, bool au // a flat. The data is in the WAD only because // we look for an actual index, instead of simply // setting one. - skyflatnum = TexMan.GetTextureID (gameinfo.SkyFlatName, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); + skyflatnum = TexMan.GetTextureID (gameinfo.SkyFlatName.GetChars(), ETextureType::Flat, FTextureManager::TEXMAN_Overridable); // [RH] Set up details about sky rendering InitSkyMap (this); @@ -1804,19 +1804,19 @@ void FLevelLocals::Init() ImpactDecalCount = 0; frozenstate = 0; - info = FindLevelInfo (MapName); + info = FindLevelInfo (MapName.GetChars()); skyspeed1 = info->skyspeed1; skyspeed2 = info->skyspeed2; - skytexture1 = TexMan.GetTextureID(info->SkyPic1, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); - skytexture2 = TexMan.GetTextureID(info->SkyPic2, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); + skytexture1 = TexMan.GetTextureID(info->SkyPic1.GetChars(), ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); + skytexture2 = TexMan.GetTextureID(info->SkyPic2.GetChars(), ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); fadeto = info->fadeto; cdtrack = info->cdtrack; cdid = info->cdid; FromSnapshot = false; if (fadeto == 0) { - if (strnicmp (info->FadeTable, "COLORMAP", 8) != 0) + if (strnicmp (info->FadeTable.GetChars(), "COLORMAP", 8) != 0) { flags |= LEVEL_HASFADETABLE; } @@ -1962,7 +1962,7 @@ void G_WriteVisited(FSerializer &arc) { if (wi.flags & LEVEL_VISITED) { - arc.AddString(nullptr, wi.MapName); + arc.AddString(nullptr, wi.MapName.GetChars()); } } arc.EndArray(); @@ -1980,9 +1980,8 @@ void G_WriteVisited(FSerializer &arc) { if (playeringame[i]) { - FString key; - key.Format("%d", i); - arc(key, players[i].cls); + FStringf key("%d", i); + arc(key.GetChars(), players[i].cls); } } arc.EndObject(); @@ -2012,7 +2011,7 @@ void G_ReadSnapshots(FResourceFile *resf) { ptrdiff_t maplen = ptr - name; FString mapname(name, (size_t)maplen); - i = FindLevelInfo(mapname); + i = FindLevelInfo(mapname.GetChars()); if (i != nullptr) { i->Snapshot = resl->GetRawData(); @@ -2045,7 +2044,7 @@ void G_ReadVisited(FSerializer &arc) { FString str; arc(nullptr, str); - auto i = FindLevelInfo(str); + auto i = FindLevelInfo(str.GetChars()); if (i != nullptr) i->flags |= LEVEL_VISITED; } arc.EndArray(); @@ -2057,9 +2056,8 @@ void G_ReadVisited(FSerializer &arc) { for (int i = 0; i < MAXPLAYERS; ++i) { - FString key; - key.Format("%d", i); - arc(key, players[i].cls); + FStringf key("%d", i); + arc(key.GetChars(), players[i].cls); } arc.EndObject(); } @@ -2091,7 +2089,7 @@ void P_WriteACSDefereds (FSerializer &arc) { if (wi.deferred.Size() > 0) { - arc(wi.MapName, wi.deferred); + arc(wi.MapName.GetChars(), wi.deferred); } } } @@ -2319,9 +2317,9 @@ void FLevelLocals::SetInterMusic(const char *nextmap) { auto mus = info->MapInterMusic.CheckKey(nextmap); if (mus != nullptr) - S_ChangeMusic(mus->first, mus->second); + S_ChangeMusic(mus->first.GetChars(), mus->second); else if (info->InterMusic.IsNotEmpty()) - S_ChangeMusic(info->InterMusic, info->intermusicorder); + S_ChangeMusic(info->InterMusic.GetChars(), info->intermusicorder); else S_ChangeMusic(gameinfo.intermissionMusic.GetChars(), gameinfo.intermissionOrder); } @@ -2330,7 +2328,7 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, SetInterMusic) { PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); PARAM_STRING(map); - self->SetInterMusic(map); + self->SetInterMusic(map.GetChars()); return 0; } @@ -2437,7 +2435,7 @@ int IsPointInMap(FLevelLocals *Level, double x, double y, double z) void FLevelLocals::SetMusic() { - S_ChangeMusic(Music, musicorder); + S_ChangeMusic(Music.GetChars(), musicorder); } @@ -2464,6 +2462,6 @@ DEFINE_ACTION_FUNCTION(FLevelLocals, GetEpisodeName) // This will need some heuristics to assign a proper episode to each existing level. // Stuff for later. for now this just checks the STAT module for the currently running episode, // which should be fine unless cheating. - ACTION_RETURN_STRING(GStrings.localize(STAT_EpisodeName())); + ACTION_RETURN_STRING(GStrings.localize(STAT_EpisodeName().GetChars())); } diff --git a/src/g_statusbar/hudmessages.cpp b/src/g_statusbar/hudmessages.cpp index c03d3cdd4..c03922505 100644 --- a/src/g_statusbar/hudmessages.cpp +++ b/src/g_statusbar/hudmessages.cpp @@ -212,7 +212,7 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h VisibilityFlags = 0; Style = STYLE_Translucent; Alpha = 1.; - ResetText (SourceText); + ResetText (SourceText.GetChars()); } //============================================================================ @@ -478,7 +478,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) if (hudheight == 0) { int scale = active_con_scaletext(twod); - DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text, + DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text.GetChars(), DTA_VirtualWidth, twod->GetWidth() / scale, DTA_VirtualHeight, twod->GetHeight() / scale, DTA_Alpha, Alpha, @@ -488,7 +488,7 @@ void DHUDMessage::DoDraw (int linenum, int x, int y, bool clean, int hudheight) } else { - DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text, + DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text.GetChars(), DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, DTA_ClipLeft, ClipLeft, @@ -571,7 +571,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh if (hudheight == 0) { int scale = active_con_scaletext(twod); - DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text, + DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text.GetChars(), DTA_VirtualWidth, twod->GetWidth() / scale, DTA_VirtualHeight, twod->GetHeight() / scale, DTA_Alpha, trans, @@ -581,7 +581,7 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh } else { - DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text, + DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text.GetChars(), DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, DTA_ClipLeft, ClipLeft, @@ -660,7 +660,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu if (hudheight == 0) { int scale = active_con_scaletext(twod); - DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text, + DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text.GetChars(), DTA_VirtualWidth, twod->GetWidth() / scale, DTA_VirtualHeight, twod->GetHeight() / scale, DTA_Alpha, trans, @@ -670,7 +670,7 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu } else { - DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text, + DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text.GetChars(), DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, DTA_ClipLeft, ClipLeft, @@ -844,7 +844,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in if (hudheight == 0) { int scale = active_con_scaletext(twod); - DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text, + DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text.GetChars(), DTA_VirtualWidth, twod->GetWidth() / scale, DTA_VirtualHeight, twod->GetHeight() / scale, DTA_KeepRatio, true, @@ -855,7 +855,7 @@ void DHUDMessageTypeOnFadeOut::DoDraw (int linenum, int x, int y, bool clean, in } else { - DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text, + DrawText(twod, Font, TextColor, x, y, Lines[linenum].Text.GetChars(), DTA_VirtualWidth, HUDWidth, DTA_VirtualHeight, hudheight, DTA_ClipLeft, ClipLeft, diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 0b3931e88..3e4f96c00 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -92,14 +92,14 @@ FGameConfigFile::FGameConfigFile () OkayToWrite = false; // Do not allow saving of the config before DoKeySetup() bModSetup = false; pathname = GetConfigPath (true); - ChangePathName (pathname); + ChangePathName (pathname.GetChars()); LoadConfigFile (); // If zdoom.ini was read from the program directory, switch // to the user directory now. If it was read from the user // directory, this effectively does nothing. pathname = GetConfigPath (false); - ChangePathName (pathname); + ChangePathName (pathname.GetChars()); // Set default IWAD search paths if none present if (!SetSection ("IWADSearch.Directories")) diff --git a/src/gamedata/g_mapinfo.cpp b/src/gamedata/g_mapinfo.cpp index ab842582f..13ca12c9a 100644 --- a/src/gamedata/g_mapinfo.cpp +++ b/src/gamedata/g_mapinfo.cpp @@ -321,10 +321,10 @@ FString level_info_t::LookupLevelName(uint32_t *langtable) if (flags & LEVEL_LOOKUPLEVELNAME) { const char *thename; - const char *lookedup = GStrings.GetString(LevelName, langtable); + const char *lookedup = GStrings.GetString(LevelName.GetChars(), langtable); if (lookedup == NULL) { - thename = LevelName; + thename = LevelName.GetChars(); } else { @@ -381,9 +381,9 @@ level_info_t *level_info_t::CheckLevelRedirect () if (playeringame[i] && players[i].mo->FindInventory(type)) { // check for actual presence of the map. - if (P_CheckMapData(RedirectMapName)) + if (P_CheckMapData(RedirectMapName.GetChars())) { - return FindLevelInfo(RedirectMapName); + return FindLevelInfo(RedirectMapName.GetChars()); } break; } @@ -403,14 +403,14 @@ level_info_t *level_info_t::CheckLevelRedirect () if (playeringame[i] && (var = GetCVar(i, RedirectCVAR.GetChars()))) { if (var->ToInt()) - if (P_CheckMapData(RedirectCVARMapName)) - return FindLevelInfo(RedirectCVARMapName); + if (P_CheckMapData(RedirectCVARMapName.GetChars())) + return FindLevelInfo(RedirectCVARMapName.GetChars()); } } } else if (var->ToInt()) - if (P_CheckMapData(RedirectCVARMapName)) - return FindLevelInfo(RedirectCVARMapName); + if (P_CheckMapData(RedirectCVARMapName.GetChars())) + return FindLevelInfo(RedirectCVARMapName.GetChars()); } } return NULL; @@ -830,7 +830,7 @@ void FMapInfoParser::ParseCluster() else { FStringf testlabel("CLUSTERENTER%d", clusterinfo->cluster); - if (GStrings.MatchDefaultString(testlabel, clusterinfo->EnterText)) + if (GStrings.MatchDefaultString(testlabel.GetChars(), clusterinfo->EnterText.GetChars())) { clusterinfo->EnterText = testlabel; clusterinfo->flags |= CLUSTER_LOOKUPENTERTEXT; @@ -845,7 +845,7 @@ void FMapInfoParser::ParseCluster() else { FStringf testlabel("CLUSTEREXIT%d", clusterinfo->cluster); - if (GStrings.MatchDefaultString(testlabel, clusterinfo->ExitText)) + if (GStrings.MatchDefaultString(testlabel.GetChars(), clusterinfo->ExitText.GetChars())) { clusterinfo->ExitText = testlabel; clusterinfo->flags |= CLUSTER_LOOKUPEXITTEXT; @@ -922,7 +922,7 @@ void FMapInfoParser::ParseCluster() // Remap Hexen's CLUS?MSG lumps to the string table, if applicable. The code here only checks what can actually be in an IWAD. if (clusterinfo->flags & CLUSTER_EXITTEXTINLUMP) { - int lump = fileSystem.CheckNumForFullName(clusterinfo->ExitText, true); + int lump = fileSystem.CheckNumForFullName(clusterinfo->ExitText.GetChars(), true); if (lump > 0) { // Check if this comes from either Hexen.wad or Hexdd.wad and if so, map to the string table. @@ -931,7 +931,7 @@ void FMapInfoParser::ParseCluster() if (fn && (!stricmp(fn, "HEXEN.WAD") || !stricmp(fn, "HEXDD.WAD"))) { FStringf key("TXT_%.5s_%s", fn, clusterinfo->ExitText.GetChars()); - if (GStrings.exists(key)) + if (GStrings.exists(key.GetChars())) { clusterinfo->ExitText = key; clusterinfo->flags &= ~CLUSTER_EXITTEXTINLUMP; @@ -2144,7 +2144,7 @@ level_info_t *FMapInfoParser::ParseMapHeader(level_info_t &defaultinfo) // This checks for a string labelled with the MapName and if that is identical to what got parsed here // the string table entry will be used. - if (GStrings.MatchDefaultString(levelinfo->MapName, sc.String)) + if (GStrings.MatchDefaultString(levelinfo->MapName.GetChars(), sc.String)) { levelinfo->flags |= LEVEL_LOOKUPLEVELNAME; levelinfo->LevelName = levelinfo->MapName; @@ -2161,7 +2161,7 @@ level_info_t *FMapInfoParser::ParseMapHeader(level_info_t &defaultinfo) if (fn && (!stricmp(fn, "HEXEN.WAD") || !stricmp(fn, "HEXDD.WAD"))) { FStringf key("TXT_%.5s_%s", fn, levelinfo->MapName.GetChars()); - if (GStrings.exists(key)) + if (GStrings.exists(key.GetChars())) { levelinfo->flags |= LEVEL_LOOKUPLEVELNAME; levelinfo->LevelName = key; @@ -2174,7 +2174,7 @@ level_info_t *FMapInfoParser::ParseMapHeader(level_info_t &defaultinfo) // Set up levelnum now so that you can use Teleport_NewMap specials // to teleport to maps with standard names without needing a levelnum. - levelinfo->levelnum = GetDefaultLevelNum(levelinfo->MapName); + levelinfo->levelnum = GetDefaultLevelNum(levelinfo->MapName.GetChars()); // Does this map have a song defined via SNDINFO's $map command? // Set that as this map's default music if it does. @@ -2295,7 +2295,7 @@ void FMapInfoParser::ParseEpisodeInfo () if (optional && !remove) { - if (!P_CheckMapData(map)) + if (!P_CheckMapData(map.GetChars())) { // If the episode is optional and the map does not exist // just ignore this episode definition. @@ -2585,7 +2585,7 @@ void G_ParseMapInfo (FString basemapinfo) { FMapInfoParser parse; level_info_t defaultinfo; - int baselump = fileSystem.GetNumForFullName(basemapinfo); + int baselump = fileSystem.GetNumForFullName(basemapinfo.GetChars()); if (fileSystem.GetFileContainer(baselump) > 0) { I_FatalError("File %s is overriding core lump %s.", diff --git a/src/gamedata/g_skill.cpp b/src/gamedata/g_skill.cpp index 34dde60e1..53b685cd3 100644 --- a/src/gamedata/g_skill.cpp +++ b/src/gamedata/g_skill.cpp @@ -488,15 +488,15 @@ DEFINE_ACTION_FUNCTION(DObject, G_SkillPropertyFloat) const char * G_SkillName() { - const char *name = AllSkills[gameskill].MenuName; + const char *name = AllSkills[gameskill].MenuName.GetChars(); player_t *player = &players[consoleplayer]; - const char *playerclass = player->mo->GetInfo()->DisplayName; + const char *playerclass = player->mo->GetInfo()->DisplayName.GetChars(); if (playerclass != NULL) { FString * pmnm = AllSkills[gameskill].MenuNamesForPlayerClass.CheckKey(playerclass); - if (pmnm != NULL) name = *pmnm; + if (pmnm != NULL) name = pmnm->GetChars(); } if (*name == '$') name = GStrings(name+1); diff --git a/src/gamedata/gi.cpp b/src/gamedata/gi.cpp index 643f63fc3..e907722e9 100644 --- a/src/gamedata/gi.cpp +++ b/src/gamedata/gi.cpp @@ -212,10 +212,10 @@ const char* GameInfoBorders[] = { \ sc.MustGetToken(TK_StringConst); \ FString color = sc.String; \ - FString colorName = V_GetColorStringByName(color); \ + FString colorName = V_GetColorStringByName(color.GetChars()); \ if(!colorName.IsEmpty()) \ color = colorName; \ - gameinfo.key = V_GetColorFromString(color); \ + gameinfo.key = V_GetColorFromString(color.GetChars()); \ } #define GAMEINFOKEY_BOOL(key, variable) \ diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index fdcdd0325..8b5135b99 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -129,7 +129,7 @@ void DrawFullscreenSubtitle(FFont* font, const char *text) y += 10; for (const FBrokenLines &line : lines) { - DrawText(twod, font, CR_UNTRANSLATED, x, y, line.Text, + DrawText(twod, font, CR_UNTRANSLATED, x, y, line.Text.GetChars(), DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE); y += font->GetHeight(); @@ -146,11 +146,11 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) { if (!first && desc->mMusic.IsNotEmpty()) { - S_ChangeMusic (desc->mMusic, desc->mMusicOrder, desc->mMusicLooping); + S_ChangeMusic (desc->mMusic.GetChars(), desc->mMusicOrder, desc->mMusicLooping); } mDuration = desc->mDuration; - const char *texname = desc->mBackground; + const char *texname = desc->mBackground.GetChars(); if (*texname == '@') { char *pp; @@ -184,7 +184,7 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) mOverlays[i].x = desc->mOverlays[i].x; mOverlays[i].y = desc->mOverlays[i].y; mOverlays[i].mCondition = desc->mOverlays[i].mCondition; - mOverlays[i].mPic = TexMan.CheckForTexture(desc->mOverlays[i].mName, ETextureType::MiscPatch); + mOverlays[i].mPic = TexMan.CheckForTexture(desc->mOverlays[i].mName.GetChars(), ETextureType::MiscPatch); } mTicker = 0; mSubtitle = desc->mSubtitle; @@ -201,11 +201,11 @@ void DIntermissionScreen::Start() { if (mMusic.IsEmpty()) { - S_ChangeMusic(gameinfo.finaleMusic, gameinfo.finaleOrder, mMusicLooping); + S_ChangeMusic(gameinfo.finaleMusic.GetChars(), gameinfo.finaleOrder, mMusicLooping); } else { - S_ChangeMusic(mMusic, mMusicOrder, mMusicLooping); + S_ChangeMusic(mMusic.GetChars(), mMusicOrder, mMusicLooping); } } } @@ -261,7 +261,7 @@ void DIntermissionScreen::Drawer () DrawTexture(twod, mOverlays[i].mPic, false, mOverlays[i].x, mOverlays[i].y, DTA_320x200, true, TAG_DONE); } FFont* font = generic_ui ? NewSmallFont : SmallFont; - DrawFullscreenSubtitle(font, mSubtitle); + DrawFullscreenSubtitle(font, mSubtitle.GetChars()); } void DIntermissionScreen::OnDestroy() @@ -488,7 +488,7 @@ void DIntermissionScreenText::Drawer () void DIntermissionScreenCast::Init(FIntermissionAction *desc, bool first) { Super::Init(desc, first); - mName = static_cast(desc)->mName; + mName = static_cast(desc)->mName.GetChars(); mClass = PClass::FindActor(static_cast(desc)->mCastClass); if (mClass != NULL) mDefaults = GetDefaultByType(mClass); else @@ -722,7 +722,7 @@ void DIntermissionScreenScroller::Init(FIntermissionAction *desc, bool first) { Super::Init(desc, first); mFirstPic = mBackground; - mSecondPic = TexMan.CheckForTexture(static_cast(desc)->mSecondPic, ETextureType::MiscPatch); + mSecondPic = TexMan.CheckForTexture(static_cast(desc)->mSecondPic.GetChars(), ETextureType::MiscPatch); mScrollDelay = static_cast(desc)->mScrollDelay; mScrollTime = static_cast(desc)->mScrollTime; mScrollDir = static_cast(desc)->mScrollDir; diff --git a/src/intermission/intermission_parse.cpp b/src/intermission/intermission_parse.cpp index b5a51aab5..4f75c3bcb 100644 --- a/src/intermission/intermission_parse.cpp +++ b/src/intermission/intermission_parse.cpp @@ -313,7 +313,7 @@ bool FIntermissionActionTextscreen::ParseKey(FScanner &sc) if (fn && (!stricmp(fn, "HEXEN.WAD") || !stricmp(fn, "HEXDD.WAD"))) { FStringf key("TXT_%.5s_%s", fn, sc.String); - if (GStrings.exists(key)) + if (GStrings.exists(key.GetChars())) { mText = "$" + key; done = true; @@ -954,7 +954,7 @@ CCMD(testfinale) return; } - auto controller = F_StartFinale(gameinfo.finaleMusic, gameinfo.finaleOrder, -1, 0, gameinfo.FinaleFlat, text, false, false, true, true); + auto controller = F_StartFinale(gameinfo.finaleMusic.GetChars(), gameinfo.finaleOrder, -1, 0, gameinfo.FinaleFlat.GetChars(), text, false, false, true, true); RunIntermission(nullptr, nullptr, controller, nullptr, [=](bool) { gameaction = ga_nothing; }); } diff --git a/src/maploader/edata.cpp b/src/maploader/edata.cpp index fcf82a10d..044fb0811 100644 --- a/src/maploader/edata.cpp +++ b/src/maploader/edata.cpp @@ -520,7 +520,7 @@ void MapLoader::InitED() FScanner sc; if (filename.IsEmpty()) return; - int lump = fileSystem.CheckNumForFullName(filename, true, FileSys::ns_global); + int lump = fileSystem.CheckNumForFullName(filename.GetChars(), true, FileSys::ns_global); if (lump == -1) return; sc.OpenLumpNum(lump); @@ -659,7 +659,7 @@ void MapLoader::LoadMapinfoACSLump() { if (Level->info->acsName.IsNotEmpty()) { - int lump = fileSystem.CheckNumForName(Level->info->acsName); + int lump = fileSystem.CheckNumForName(Level->info->acsName.GetChars()); if (lump >= 0) Level->Behaviors.LoadModule(lump); } } diff --git a/src/maploader/glnodes.cpp b/src/maploader/glnodes.cpp index 63f738dde..a17374a64 100644 --- a/src/maploader/glnodes.cpp +++ b/src/maploader/glnodes.cpp @@ -736,7 +736,7 @@ static int FindGLNodesInWAD(int labellump) glheader.Format("GL_%s", fileSystem.GetFileFullName(labellump)); if (glheader.Len()<=8) { - int gllabel = fileSystem.CheckNumForName(glheader, FileSys::ns_global, wadfile); + int gllabel = fileSystem.CheckNumForName(glheader.GetChars(), FileSys::ns_global, wadfile); if (gllabel >= 0) return gllabel; } else @@ -754,7 +754,7 @@ static int FindGLNodesInWAD(int labellump) if (fileSystem.GetFileContainer(lump)==wadfile) { auto mem = fileSystem.ReadFile(lump); - if (MatchHeader(fileSystem.GetFileFullName(labellump), GetStringFromLump(lump))) return lump; + if (MatchHeader(fileSystem.GetFileFullName(labellump), GetStringFromLump(lump).GetChars())) return lump; } } } @@ -793,7 +793,7 @@ static int FindGLNodesInFile(FResourceFile * f, const char * label) { for(uint32_t i=0;iGetLump(i)->getName(), glheader, 8)) + if (!strnicmp(f->GetLump(i)->getName(), glheader.GetChars(), 8)) { if (mustcheck) { @@ -1004,7 +1004,7 @@ static FString CreateCacheName(MapData *map, bool create) FString lumpname = fileSystem.GetFileFullPath(map->lumpnum).c_str(); auto separator = lumpname.IndexOf(':'); path << '/' << lumpname.Left(separator); - if (create) CreatePath(path); + if (create) CreatePath(path.GetChars()); lumpname.ReplaceChars('/', '%'); lumpname.ReplaceChars(':', '$'); @@ -1125,7 +1125,7 @@ void MapLoader::CreateCachedNodes(MapData *map) memcpy(&compressed[offset - 4], "ZGL3", 4); FString path = CreateCacheName(map, true); - FileWriter *fw = FileWriter::Open(path); + FileWriter *fw = FileWriter::Open(path.GetChars()); if (fw != nullptr) { @@ -1154,7 +1154,7 @@ bool MapLoader::CheckCachedNodes(MapData *map) FString path = CreateCacheName(map, false); FileReader fr; - if (!fr.OpenFile(path)) return false; + if (!fr.OpenFile(path.GetChars())) return false; if (fr.Read(magic, 4) != 4) return false; if (memcmp(magic, "CACH", 4)) return false; @@ -1203,7 +1203,7 @@ UNSAFE_CCMD(clearnodecache) FString path = M_GetCachePath(false); path += "/"; - if (!FileSys::ScanDirectory(list, path, "*", false)) + if (!FileSys::ScanDirectory(list, path.GetChars(), "*", false)) { Printf("Unable to scan node cache directory %s\n", path.GetChars()); return; diff --git a/src/menu/doommenu.cpp b/src/menu/doommenu.cpp index 50857f76a..ac73a9b0a 100644 --- a/src/menu/doommenu.cpp +++ b/src/menu/doommenu.cpp @@ -403,7 +403,7 @@ CCMD (menu_quit) } else EndString = gameinfo.quitmessages[messageindex]; - DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, EndString, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, EndString.GetChars(), 0, false, NAME_None, []() { if (!netgame) { @@ -431,7 +431,7 @@ CCMD (menu_quit) void ActivateEndGameMenu() { FString tempstring = GStrings(netgame ? "NETEND" : "ENDGAME"); - DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring.GetChars(), 0, false, NAME_None, []() { M_ClearMenus(); if (!netgame) @@ -503,7 +503,7 @@ CCMD (quicksave) FString tempstring = GStrings("QSPROMPT"); tempstring.Substitute("%s", savegameManager.quickSaveSlot->SaveTitle.GetChars()); - DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring.GetChars(), 0, false, NAME_None, []() { G_SaveGame(savegameManager.quickSaveSlot->Filename.GetChars(), savegameManager.quickSaveSlot->SaveTitle.GetChars()); S_Sound(CHAN_VOICE, CHANF_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); @@ -548,7 +548,7 @@ CCMD (quickload) M_StartControlPanel(true); - DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring.GetChars(), 0, false, NAME_None, []() { G_LoadGame(savegameManager.quickSaveSlot->Filename.GetChars()); S_Sound(CHAN_VOICE, CHANF_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); @@ -615,8 +615,8 @@ CCMD(reset2defaults) CCMD(reset2saved) { GameConfig->DoGlobalSetup (); - GameConfig->DoGameSetup (gameinfo.ConfigName); - GameConfig->DoModSetup (gameinfo.ConfigName); + GameConfig->DoGameSetup (gameinfo.ConfigName.GetChars()); + GameConfig->DoModSetup (gameinfo.ConfigName.GetChars()); R_SetViewSize (screenblocks); } @@ -674,8 +674,8 @@ void M_StartupEpisodeMenu(FNewGameStartup *gs) { if (AllEpisodes[i].mPicName.IsNotEmpty()) { - FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName); - if (AllEpisodes[i].mEpisodeName.IsEmpty() || OkForLocalization(tex, AllEpisodes[i].mEpisodeName)) + FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName.GetChars()); + if (AllEpisodes[i].mEpisodeName.IsEmpty() || OkForLocalization(tex, AllEpisodes[i].mEpisodeName.GetChars())) continue; } if ((gameinfo.gametype & GAME_DoomStrifeChex) && spacing == 16) spacing = 18; @@ -706,11 +706,11 @@ void M_StartupEpisodeMenu(FNewGameStartup *gs) DMenuItemBase *it = nullptr; if (AllEpisodes[i].mPicName.IsNotEmpty()) { - FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName); - if (AllEpisodes[i].mEpisodeName.IsEmpty() || OkForLocalization(tex, AllEpisodes[i].mEpisodeName)) + FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName.GetChars()); + if (AllEpisodes[i].mEpisodeName.IsEmpty() || OkForLocalization(tex, AllEpisodes[i].mEpisodeName.GetChars())) continue; // We do not measure patch based entries. They are assumed to fit } - const char *c = AllEpisodes[i].mEpisodeName; + const char *c = AllEpisodes[i].mEpisodeName.GetChars(); if (*c == '$') c = GStrings(c + 1); int textwidth = ld->mFont->StringWidth(c); int textright = posx + textwidth; @@ -722,14 +722,14 @@ void M_StartupEpisodeMenu(FNewGameStartup *gs) DMenuItemBase *it = nullptr; if (AllEpisodes[i].mPicName.IsNotEmpty()) { - FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName); - if (AllEpisodes[i].mEpisodeName.IsEmpty() || OkForLocalization(tex, AllEpisodes[i].mEpisodeName)) + FTextureID tex = GetMenuTexture(AllEpisodes[i].mPicName.GetChars()); + if (AllEpisodes[i].mEpisodeName.IsEmpty() || OkForLocalization(tex, AllEpisodes[i].mEpisodeName.GetChars())) it = CreateListMenuItemPatch(posx, posy, spacing, AllEpisodes[i].mShortcut, tex, NAME_Skillmenu, i); } if (it == nullptr) { it = CreateListMenuItemText(posx, posy, spacing, AllEpisodes[i].mShortcut, - AllEpisodes[i].mEpisodeName, ld->mFont, ld->mFontColor, ld->mFontColor2, NAME_Skillmenu, i); + AllEpisodes[i].mEpisodeName.GetChars(), ld->mFont, ld->mFontColor, ld->mFontColor2, NAME_Skillmenu, i); } ld->mItems.Push(it); posy += spacing; @@ -769,7 +769,7 @@ void M_StartupEpisodeMenu(FNewGameStartup *gs) GC::WriteBarrier(od); for(unsigned i = 0; i < AllEpisodes.Size(); i++) { - auto it = CreateOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i); + auto it = CreateOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName.GetChars(), "Skillmenu", i); od->mItems.Push(it); GC::WriteBarrier(od, it); } @@ -813,7 +813,7 @@ static void BuildPlayerclassMenu() { if (!(PlayerClasses[i].Flags & PCF_NOMENU)) { - const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); + const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type).GetChars(); if (pname != nullptr) { numclassitems++; @@ -850,7 +850,7 @@ static void BuildPlayerclassMenu() { if (!(PlayerClasses[i].Flags & PCF_NOMENU)) { - const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); + const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type).GetChars(); if (pname != nullptr) { auto it = CreateListMenuItemText(ld->mXpos, ld->mYpos, ld->mLinespacing, *pname, @@ -869,7 +869,7 @@ static void BuildPlayerclassMenu() } if (n == 0) { - const char *pname = GetPrintableDisplayName(PlayerClasses[0].Type); + const char *pname = GetPrintableDisplayName(PlayerClasses[0].Type).GetChars(); if (pname != nullptr) { auto it = CreateListMenuItemText(ld->mXpos, ld->mYpos, ld->mLinespacing, *pname, @@ -910,7 +910,7 @@ static void BuildPlayerclassMenu() { if (!(PlayerClasses[i].Flags & PCF_NOMENU)) { - const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); + const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type).GetChars(); if (pname != nullptr) { auto it = CreateOptionMenuItemSubmenu(pname, "Episodemenu", i); @@ -1002,12 +1002,12 @@ static void InitKeySections() FKeySection *sect = &KeySections[i]; DMenuItemBase *item = CreateOptionMenuItemStaticText(" "); menu->mItems.Push(item); - item = CreateOptionMenuItemStaticText(sect->mTitle, 1); + item = CreateOptionMenuItemStaticText(sect->mTitle.GetChars(), 1); menu->mItems.Push(item); for (unsigned j = 0; j < sect->mActions.Size(); j++) { FKeyAction *act = §->mActions[j]; - item = CreateOptionMenuItemControl(act->mTitle, act->mAction, &Bindings); + item = CreateOptionMenuItemControl(act->mTitle.GetChars(), act->mAction, &Bindings); menu->mItems.Push(item); } } @@ -1210,8 +1210,8 @@ void M_StartupSkillMenu(FNewGameStartup *gs) { if (MenuSkills[i]->PicName.IsNotEmpty()) { - FTextureID tex = GetMenuTexture(MenuSkills[i]->PicName); - if (MenuSkills[i]->MenuName.IsEmpty() || OkForLocalization(tex, MenuSkills[i]->MenuName)) + FTextureID tex = GetMenuTexture(MenuSkills[i]->PicName.GetChars()); + if (MenuSkills[i]->MenuName.IsEmpty() || OkForLocalization(tex, MenuSkills[i]->MenuName.GetChars())) continue; } if ((gameinfo.gametype & GAME_DoomStrifeChex) && spacing == 16) spacing = 18; @@ -1256,8 +1256,8 @@ void M_StartupSkillMenu(FNewGameStartup *gs) if (skill.PicName.Len() != 0 && pItemText == nullptr) { - FTextureID tex = GetMenuTexture(skill.PicName); - if (skill.MenuName.IsEmpty() || OkForLocalization(tex, skill.MenuName)) + FTextureID tex = GetMenuTexture(skill.PicName.GetChars()); + if (skill.MenuName.IsEmpty() || OkForLocalization(tex, skill.MenuName.GetChars())) continue; } const char *c = pItemText ? pItemText->GetChars() : skill.MenuName.GetChars(); @@ -1285,14 +1285,14 @@ void M_StartupSkillMenu(FNewGameStartup *gs) if (color == CR_UNTRANSLATED) color = ld->mFontColor; if (skill.PicName.Len() != 0 && pItemText == nullptr) { - FTextureID tex = GetMenuTexture(skill.PicName); - if (skill.MenuName.IsEmpty() || OkForLocalization(tex, skill.MenuName)) + FTextureID tex = GetMenuTexture(skill.PicName.GetChars()); + if (skill.MenuName.IsEmpty() || OkForLocalization(tex, skill.MenuName.GetChars())) li = CreateListMenuItemPatch(posx, y, spacing, skill.Shortcut, tex, action, SkillIndices[i]); } if (li == nullptr) { li = CreateListMenuItemText(posx, y, spacing, skill.Shortcut, - pItemText? *pItemText : skill.MenuName, ld->mFont, color,ld->mFontColor2, action, SkillIndices[i]); + pItemText? pItemText->GetChars() : skill.MenuName.GetChars(), ld->mFont, color, ld->mFontColor2, action, SkillIndices[i]); } ld->mItems.Push(li); GC::WriteBarrier(*desc, li); @@ -1350,7 +1350,7 @@ fail: { pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); } - li = CreateOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, SkillIndices[i]); + li = CreateOptionMenuItemSubmenu(pItemText? pItemText->GetChars() : skill.MenuName.GetChars(), action, SkillIndices[i]); od->mItems.Push(li); GC::WriteBarrier(od, li); if (!done) diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 9718c77ec..07df23fdb 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -76,7 +76,7 @@ static void do_uniform_set(float value, ExtraUniformCVARData* data) for (unsigned int i = 0; i < PostProcessShaders.Size(); i++) { PostProcessShader& shader = PostProcessShaders[i]; - if (strcmp(shader.Name, data->Shader) == 0) + if (strcmp(shader.Name.GetChars(), data->Shader.GetChars()) == 0) { data->vec4 = shader.Uniforms[data->Uniform].Values; } @@ -154,7 +154,7 @@ static void ParseVavoomSkybox() sb->SetSize(); if (!error) { - TexMan.AddGameTexture(MakeGameTexture(sb, s, ETextureType::Override)); + TexMan.AddGameTexture(MakeGameTexture(sb, s.GetChars(), ETextureType::Override)); } } } @@ -997,7 +997,7 @@ class GLDefsParser break; case LIGHTTAG_LIGHT: ParseString(sc); - AddLightAssociation(name, frameName, sc.String); + AddLightAssociation(name.GetChars(), frameName.GetChars(), sc.String); break; default: sc.ScriptError("Unknown tag: %s\n", sc.String); @@ -1072,7 +1072,7 @@ class GLDefsParser sc.MustGetString(); FString s = sc.String; - FSkyBox * sb = new FSkyBox(s); + FSkyBox * sb = new FSkyBox(s.GetChars()); if (sc.CheckString("fliptop")) { sb->fliptop = true; @@ -1092,7 +1092,7 @@ class GLDefsParser sc.ScriptError("%s: Skybox definition requires either 3 or 6 faces", s.GetChars()); } sb->SetSize(); - TexMan.AddGameTexture(MakeGameTexture(sb, s, ETextureType::Override)); + TexMan.AddGameTexture(MakeGameTexture(sb, s.GetChars(), ETextureType::Override)); } //=========================================================================== @@ -1588,7 +1588,7 @@ class GLDefsParser } sc.MustGetString(); cvarname = sc.String; - cvar = FindCVar(cvarname, NULL); + cvar = FindCVar(cvarname.GetChars(), NULL); UCVarValue oldval; UCVarValue val; @@ -1606,7 +1606,7 @@ class GLDefsParser { if (!cvar) { - cvar = C_CreateCVar(cvarname, cvartype, cvarflags); + cvar = C_CreateCVar(cvarname.GetChars(), cvartype, cvarflags); } else if (cvar && (((cvar->GetFlags()) & CVAR_MOD) == CVAR_MOD)) { @@ -1626,7 +1626,7 @@ class GLDefsParser { oldval.Float = cvar->GetGenericRep(CVAR_Float).Float; delete cvar; - cvar = C_CreateCVar(cvarname, cvartype, cvarflags); + cvar = C_CreateCVar(cvarname.GetChars(), cvartype, cvarflags); oldextra = (ExtraUniformCVARData*)cvar->GetExtraDataPointer(); } @@ -1904,7 +1904,7 @@ public: if (!sc.GetToken ()) { if (addedcvars) - GameConfig->DoModSetup (gameinfo.ConfigName); + GameConfig->DoModSetup (gameinfo.ConfigName.GetChars()); return; } type = sc.MatchString(CoreKeywords); From 7a5a2858a25cf204a727074126fb0408a6fd5a92 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Oct 2023 23:29:24 +0200 Subject: [PATCH 194/223] yet even more GetChars calls added. --- src/common/audio/music/i_soundfont.cpp | 24 ++++----- src/common/audio/music/music.cpp | 14 ++--- src/common/audio/sound/oalsound.cpp | 2 +- src/common/cutscenes/movieplayer.cpp | 6 +-- src/common/cutscenes/screenjob.cpp | 4 +- src/common/engine/m_joy.cpp | 2 +- src/common/engine/serializer.cpp | 6 +-- src/common/engine/stats.cpp | 2 +- src/common/engine/stringtable.cpp | 4 +- src/common/menu/joystickmenu.cpp | 2 +- src/common/menu/menu.cpp | 2 +- src/common/menu/menudef.cpp | 2 +- src/common/menu/messagebox.cpp | 2 +- src/common/menu/savegamemanager.cpp | 12 ++--- src/common/models/models_ue1.cpp | 4 +- .../scripting/interface/stringformat.cpp | 4 +- src/common/scripting/jit/jit_move.cpp | 2 +- src/common/startscreen/startscreen.cpp | 6 +-- .../textures/multipatchtexturebuilder.cpp | 8 +-- src/common/utility/m_argv.cpp | 2 +- src/common/utility/memarena.cpp | 2 +- src/common/utility/palette.cpp | 2 +- src/g_statusbar/sbar_mugshot.cpp | 8 +-- src/g_statusbar/sbarinfo.cpp | 6 +-- src/g_statusbar/sbarinfo_commands.cpp | 14 ++--- src/g_statusbar/shared_sbar.cpp | 52 +++++++++---------- src/gamedata/keysections.cpp | 2 +- src/gamedata/statistics.cpp | 16 +++--- src/m_misc.cpp | 16 +++--- src/maploader/maploader.cpp | 16 +++--- src/maploader/strifedialogue.cpp | 4 +- src/menu/loadsavemenu.cpp | 2 +- src/menu/playermenu.cpp | 6 +-- src/p_conversation.cpp | 6 +-- src/p_openmap.cpp | 4 +- src/p_saveg.cpp | 4 +- src/p_setup.cpp | 6 +-- src/playsim/p_acs.cpp | 22 ++++---- src/playsim/p_actionfunctions.cpp | 16 +++--- src/playsim/p_interaction.cpp | 12 ++--- src/playsim/p_lnspec.cpp | 24 ++++----- src/playsim/p_mobj.cpp | 2 +- src/playsim/p_user.cpp | 12 ++--- src/r_data/r_canvastexture.cpp | 2 +- src/r_data/r_translate.cpp | 2 +- src/r_data/sprites.cpp | 12 ++--- 46 files changed, 190 insertions(+), 190 deletions(-) diff --git a/src/common/audio/music/i_soundfont.cpp b/src/common/audio/music/i_soundfont.cpp index dd610e0b4..e1059fc12 100644 --- a/src/common/audio/music/i_soundfont.cpp +++ b/src/common/audio/music/i_soundfont.cpp @@ -68,7 +68,7 @@ std::pair FSoundFontReader::LookupFile(const char *name) for(int i = mPaths.Size()-1; i>=0; i--) { FString fullname = mPaths[i] + name; - auto fr = OpenFile(fullname); + auto fr = OpenFile(fullname.GetChars()); if (fr.isOpen()) return std::make_pair(std::move(fr), fullname); } } @@ -93,7 +93,7 @@ void FSoundFontReader::AddPath(const char *strp) if (str.Back() != '/') str += '/'; // always let it end with a slash. for (auto &s : mPaths) { - if (pathcmp(s.GetChars(), str) == 0) + if (pathcmp(s.GetChars(), str.GetChars()) == 0) { // move string to the back. mPaths.Delete(i); @@ -122,13 +122,13 @@ FileReader FSoundFontReader::Open(const char *name, std::string& filename) if (name == nullptr) { fr = OpenMainConfigFile(); - filename = MainConfigFileName(); + filename = MainConfigFileName().GetChars(); } else { auto res = LookupFile(name); fr = std::move(res.first); - filename = res.second; + filename = res.second.GetChars(); } return fr; } @@ -244,7 +244,7 @@ FPatchSetReader::FPatchSetReader(const char *filename) const char *paths[] = { "C:/TIMIDITY", "/TIMIDITY", - progdir + progdir.GetChars() }; #endif mAllowAbsolutePaths = true; @@ -258,7 +258,7 @@ FPatchSetReader::FPatchSetReader(const char *filename) for(auto c : paths) { FStringf fullname("%s/%s", c, filename); - if (fr.OpenFile(fullname)) + if (fr.OpenFile(fullname.GetChars())) { mFullPathToConfig = fullname; } @@ -267,7 +267,7 @@ FPatchSetReader::FPatchSetReader(const char *filename) if (mFullPathToConfig.Len() > 0) { FixPathSeperator(mFullPathToConfig); - mBasePath = ExtractFilePath(mFullPathToConfig); + mBasePath = ExtractFilePath(mFullPathToConfig.GetChars()); if (mBasePath.Len() > 0 && mBasePath.Back() != '/') mBasePath += '/'; } } @@ -276,7 +276,7 @@ FPatchSetReader::FPatchSetReader(const char *filename) FileReader FPatchSetReader::OpenMainConfigFile() { FileReader fr; - fr.OpenFile(mFullPathToConfig); + fr.OpenFile(mFullPathToConfig.GetChars()); return fr; } @@ -286,7 +286,7 @@ FileReader FPatchSetReader::OpenFile(const char *name) if (IsAbsPath(name)) path = name; else path = mBasePath + name; FileReader fr; - fr.OpenFile(path); + fr.OpenFile(path.GetChars()); return fr; } @@ -302,7 +302,7 @@ FLumpPatchSetReader::FLumpPatchSetReader(const char *filename) mBasePath = filename; FixPathSeperator(mBasePath); - mBasePath = ExtractFilePath(mBasePath); + mBasePath = ExtractFilePath(mBasePath.GetChars()); if (mBasePath.Len() > 0 && mBasePath.Back() != '/') mBasePath += '/'; } @@ -523,8 +523,8 @@ FSoundFontReader *FSoundFontManager::OpenSoundFont(const char *name, int allowed auto sfi = FindSoundFont(name, allowed); if (sfi != nullptr) { - if (sfi->type == SF_SF2) return new FSF2Reader(sfi->mFilename); - else return new FZipPatReader(sfi->mFilename); + if (sfi->type == SF_SF2) return new FSF2Reader(sfi->mFilename.GetChars()); + else return new FZipPatReader(sfi->mFilename.GetChars()); } return nullptr; diff --git a/src/common/audio/music/music.cpp b/src/common/audio/music/music.cpp index adffe332f..51797220e 100644 --- a/src/common/audio/music/music.cpp +++ b/src/common/audio/music/music.cpp @@ -463,7 +463,7 @@ static void SaveGains() { auto path = M_GetAppDataPath(true); path << "/replaygain.ini"; - FConfigFile gains(path); + FConfigFile gains(path.GetChars()); TMap::Iterator it(gainMap); TMap::Pair* pair; @@ -471,7 +471,7 @@ static void SaveGains() { while (it.NextPair(pair)) { - gains.SetValueForKey(pair->Key, std::to_string(pair->Value).c_str()); + gains.SetValueForKey(pair->Key.GetChars(), std::to_string(pair->Value).c_str()); } } gains.WriteConfigFile(); @@ -484,7 +484,7 @@ static void ReadGains() done = true; auto path = M_GetAppDataPath(true); path << "/replaygain.ini"; - FConfigFile gains(path); + FConfigFile gains(path.GetChars()); if (gains.SetSection("Gains")) { const char* key; @@ -669,7 +669,7 @@ bool S_ChangeMusic(const char* musicname, int order, bool looping, bool force) if (!mus_playing.name.IsEmpty() && mus_playing.handle != nullptr && - stricmp(mus_playing.name, musicname) == 0 && + mus_playing.name.CompareNoCase(musicname) == 0 && ZMusic_IsLooping(mus_playing.handle) == zmusic_bool(looping)) { if (order != mus_playing.baseorder) @@ -768,7 +768,7 @@ void S_RestartMusic () { FString song = mus_playing.LastSong; mus_playing.LastSong = ""; - S_ChangeMusic (song, mus_playing.baseorder, mus_playing.loop, true); + S_ChangeMusic (song.GetChars(), mus_playing.baseorder, mus_playing.loop, true); } else { @@ -791,7 +791,7 @@ void S_MIDIDeviceChanged(int newdev) // Reload the song to change the device auto mi = mus_playing; S_StopMusic(true); - S_ChangeMusic(mi.name, mi.baseorder, mi.loop); + S_ChangeMusic(mi.name.GetChars(), mi.baseorder, mi.loop); } } @@ -807,7 +807,7 @@ int S_GetMusic (const char **name) if (mus_playing.name.IsNotEmpty()) { - *name = mus_playing.name; + *name = mus_playing.name.GetChars(); order = mus_playing.baseorder; } else diff --git a/src/common/audio/sound/oalsound.cpp b/src/common/audio/sound/oalsound.cpp index 6f6e4e3ee..96809e7be 100644 --- a/src/common/audio/sound/oalsound.cpp +++ b/src/common/audio/sound/oalsound.cpp @@ -75,7 +75,7 @@ CVAR (String, snd_alresampler, "Default", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) #define OPENALLIB1 "libopenal.1.dylib" #define OPENALLIB2 "OpenAL.framework/OpenAL" #else // !__APPLE__ -#define OPENALLIB1 NicePath("$PROGDIR/" OPENALLIB) +#define OPENALLIB1 NicePath("$PROGDIR/" OPENALLIB).GetChars() #define OPENALLIB2 OPENALLIB #endif diff --git a/src/common/cutscenes/movieplayer.cpp b/src/common/cutscenes/movieplayer.cpp index ac915bfb0..917c11cbc 100644 --- a/src/common/cutscenes/movieplayer.cpp +++ b/src/common/cutscenes/movieplayer.cpp @@ -837,7 +837,7 @@ MoviePlayer* OpenMovie(const char* filename, TArray& ans, const int* framet { auto fn = StripExtension(filename); DefaultExtension(fn, ".ivf"); - fr = fileSystem.OpenFileReader(fn); + fr = fileSystem.OpenFileReader(fn.GetChars()); } if (!fr.isOpen()) fr = fileSystem.OpenFileReader(filename); @@ -905,7 +905,7 @@ MoviePlayer* OpenMovie(const char* filename, TArray& ans, const int* framet // VPX files have no sound track, so look for a same-named sound file with a known extension as the soundtrack to be played. static const char* knownSoundExts[] = { "OGG", "FLAC", "MP3", "OPUS", "WAV" }; FString name = StripExtension(filename); - anm->soundtrack = fileSystem.FindFileWithExtensions(name, knownSoundExts, countof(knownSoundExts)); + anm->soundtrack = fileSystem.FindFileWithExtensions(name.GetChars(), knownSoundExts, countof(knownSoundExts)); return anm; } // add more formats here. @@ -936,7 +936,7 @@ DEFINE_ACTION_FUNCTION(_MoviePlayer, Create) if (firstframetime == -1) firstframetime = frametime; if (lastframetime == -1) lastframetime = frametime; int frametimes[] = { firstframetime, frametime, lastframetime }; - auto movie = OpenMovie(filename, *sndinf, frametime == -1? nullptr : frametimes, flags, error); + auto movie = OpenMovie(filename.GetChars(), *sndinf, frametime == -1? nullptr : frametimes, flags, error); if (!movie) { Printf(TEXTCOLOR_YELLOW "%s", error.GetChars()); diff --git a/src/common/cutscenes/screenjob.cpp b/src/common/cutscenes/screenjob.cpp index c22745956..fa3752ba7 100644 --- a/src/common/cutscenes/screenjob.cpp +++ b/src/common/cutscenes/screenjob.cpp @@ -154,7 +154,7 @@ void AddGenericVideo(DObject* runner, const FString& fn, int soundid, int fps) int CutsceneDef::GetSound() { FSoundID id = INVALID_SOUND; - if (soundName.IsNotEmpty()) id = soundEngine->FindSound(soundName); + if (soundName.IsNotEmpty()) id = soundEngine->FindSound(soundName.GetChars()); if (id == INVALID_SOUND) id = soundEngine->FindSoundByResID(soundID); return id.index(); } @@ -163,7 +163,7 @@ void CutsceneDef::Create(DObject* runner) { if (function.IsNotEmpty()) { - CallCreateFunction(function, runner); + CallCreateFunction(function.GetChars(), runner); } else if (video.IsNotEmpty()) { diff --git a/src/common/engine/m_joy.cpp b/src/common/engine/m_joy.cpp index 49ad103ae..a2ab71103 100644 --- a/src/common/engine/m_joy.cpp +++ b/src/common/engine/m_joy.cpp @@ -98,7 +98,7 @@ static bool M_SetJoystickConfigSection(IJoystickConfig *joy, bool create, FConfi FString id = "Joy:"; id += joy->GetIdentifier(); if (!GameConfig) return false; - return GameConfig->SetSection(id, create); + return GameConfig->SetSection(id.GetChars(), create); } //========================================================================== diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index 3ea5bdb0b..bb54c0d2b 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -1145,7 +1145,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe } else { - name = pic->GetName(); + name = pic->GetName().GetChars(); } arc.WriteKey(key); arc.w->StartArray(); @@ -1507,8 +1507,8 @@ FString DictionaryToString(const Dictionary &dict) while (i.NextPair(pair)) { - writer.Key(pair->Key); - writer.String(pair->Value); + writer.Key(pair->Key.GetChars()); + writer.String(pair->Value.GetChars()); } writer.EndObject(); diff --git a/src/common/engine/stats.cpp b/src/common/engine/stats.cpp index 0a295c8c6..70ad8e2f1 100644 --- a/src/common/engine/stats.cpp +++ b/src/common/engine/stats.cpp @@ -116,7 +116,7 @@ void FStat::PrintStat (F2DDrawer *drawer) // Count number of linefeeds but ignore terminating ones. if (stattext[i] == '\n') y -= fontheight; } - DrawText(drawer, NewConsoleFont, CR_GREEN, 5 / textScale, y, stattext, + DrawText(drawer, NewConsoleFont, CR_GREEN, 5 / textScale, y, stattext.GetChars(), DTA_VirtualWidth, twod->GetWidth() / textScale, DTA_VirtualHeight, twod->GetHeight() / textScale, DTA_KeepRatio, true, TAG_DONE); diff --git a/src/common/engine/stringtable.cpp b/src/common/engine/stringtable.cpp index 0774a7a9b..d507b281c 100644 --- a/src/common/engine/stringtable.cpp +++ b/src/common/engine/stringtable.cpp @@ -241,7 +241,7 @@ bool FStringTable::ParseLanguageCSV(int lumpnum, const char* buffer, size_t size auto filter = filterstr.Split(" ", FString::TOK_SKIPEMPTY); for (auto& entry : filter) { - if (sysCallbacks.CheckGame(entry)) + if (sysCallbacks.CheckGame(entry.GetChars())) { ok = true; break; @@ -639,7 +639,7 @@ bool FStringTable::MatchDefaultString(const char *name, const char *content) con // Check a secondary key, in case the text comparison cannot be done due to needed orthographic fixes (see Harmony's exit text) FStringf checkkey("%s_CHECK", name); - auto cc = GetLanguageString(checkkey, FStringTable::default_table); + auto cc = GetLanguageString(checkkey.GetChars(), FStringTable::default_table); if (cc) c = cc; return (c && !strnicmp(c, content, strcspn(content, "\n\r\t"))); diff --git a/src/common/menu/joystickmenu.cpp b/src/common/menu/joystickmenu.cpp index 10408d916..ae152b5f0 100644 --- a/src/common/menu/joystickmenu.cpp +++ b/src/common/menu/joystickmenu.cpp @@ -176,7 +176,7 @@ void UpdateJoystickMenu(IJoystickConfig *selected) for (int ii = 0; ii < (int)Joysticks.Size(); ++ii) { - it = CreateOptionMenuItemJoyConfigMenu(Joysticks[ii]->GetName(), Joysticks[ii]); + it = CreateOptionMenuItemJoyConfigMenu(Joysticks[ii]->GetName().GetChars(), Joysticks[ii]); GC::WriteBarrier(opt, it); opt->mItems.Push(it); if (ii == itemnum) opt->mSelectedItem = opt->mItems.Size(); diff --git a/src/common/menu/menu.cpp b/src/common/menu/menu.cpp index 67ed85a6e..448b196a1 100644 --- a/src/common/menu/menu.cpp +++ b/src/common/menu/menu.cpp @@ -1209,7 +1209,7 @@ bool DMenuItemBase::GetString(int i, char *s, int len) FString retstr; VMReturn ret[2]; ret[0].IntAt(&retval); ret[1].StringAt(&retstr); VMCall(func, params, countof(params), ret, 2); - strncpy(s, retstr, len); + strncpy(s, retstr.GetChars(), len); return !!retval; } return false; diff --git a/src/common/menu/menudef.cpp b/src/common/menu/menudef.cpp index 34ef1fc9d..dcef0e1de 100644 --- a/src/common/menu/menudef.cpp +++ b/src/common/menu/menudef.cpp @@ -1628,7 +1628,7 @@ static void InitMusicMenus() { FString display = entry.mName; display.ReplaceChars("_", ' '); - auto it = CreateOptionMenuItemCommand(display, FStringf("%s \"%s\"", std::get<2>(p), entry.mName.GetChars()), true); + auto it = CreateOptionMenuItemCommand(display.GetChars(), FStringf("%s \"%s\"", std::get<2>(p), entry.mName.GetChars()), true); static_cast(*menu)->mItems.Push(it); } } diff --git a/src/common/menu/messagebox.cpp b/src/common/menu/messagebox.cpp index 8b8334b02..21f22d190 100644 --- a/src/common/menu/messagebox.cpp +++ b/src/common/menu/messagebox.cpp @@ -99,6 +99,6 @@ DEFINE_ACTION_FUNCTION(DMenu, StartMessage) PARAM_STRING(msg); PARAM_INT(mode); PARAM_NAME(action); - M_StartMessage(msg, mode, action); + M_StartMessage(msg.GetChars(), mode, action); return 0; } diff --git a/src/common/menu/savegamemanager.cpp b/src/common/menu/savegamemanager.cpp index 29b0f447b..35cf6674d 100644 --- a/src/common/menu/savegamemanager.cpp +++ b/src/common/menu/savegamemanager.cpp @@ -252,7 +252,7 @@ void FSavegameManagerBase::DoSave(int Selected, const char *savegamestring) break; } } - PerformSaveGame(filename, savegamestring); + PerformSaveGame(filename.GetChars(), savegamestring); } M_ClearMenus(); } @@ -262,7 +262,7 @@ DEFINE_ACTION_FUNCTION(FSavegameManager, DoSave) PARAM_SELF_STRUCT_PROLOGUE(FSavegameManagerBase); PARAM_INT(sel); PARAM_STRING(name); - self->DoSave(sel, name); + self->DoSave(sel, name.GetChars()); return 0; } @@ -559,7 +559,7 @@ FString G_GetSavegamesFolder() } else { - name = **save_dir ? save_dir : M_GetSavegamesPath(); + name = **save_dir ? FString(save_dir) : M_GetSavegamesPath(); usefilter = true; } @@ -574,8 +574,8 @@ FString G_GetSavegamesFolder() if (usefilter && SavegameFolder.IsNotEmpty()) name << SavegameFolder << '/'; - name = NicePath(name); - CreatePath(name); + name = NicePath(name.GetChars()); + CreatePath(name.GetChars()); return name; } @@ -589,7 +589,7 @@ FString G_BuildSaveName(const char* prefix) { FString name = G_GetSavegamesFolder() + prefix; DefaultExtension(name, "." SAVEGAME_EXT); // only add an extension if the prefix doesn't have one already. - name = NicePath(name); + name = NicePath(name.GetChars()); name.Substitute("\\", "/"); return name; } diff --git a/src/common/models/models_ue1.cpp b/src/common/models/models_ue1.cpp index 742ef4aaf..408860185 100644 --- a/src/common/models/models_ue1.cpp +++ b/src/common/models/models_ue1.cpp @@ -53,14 +53,14 @@ bool FUE1Model::Load( const char *filename, int lumpnum, const char *buffer, int if ( (size_t)realfilename.IndexOf("_d.3d") == realfilename.Len()-5 ) { realfilename.Substitute("_d.3d","_a.3d"); - lumpnum2 = fileSystem.CheckNumForFullName(realfilename); + lumpnum2 = fileSystem.CheckNumForFullName(realfilename.GetChars()); mDataLump = lumpnum; mAnivLump = lumpnum2; } else { realfilename.Substitute("_a.3d","_d.3d"); - lumpnum2 = fileSystem.CheckNumForFullName(realfilename); + lumpnum2 = fileSystem.CheckNumForFullName(realfilename.GetChars()); mAnivLump = lumpnum; mDataLump = lumpnum2; } diff --git a/src/common/scripting/interface/stringformat.cpp b/src/common/scripting/interface/stringformat.cpp index 77ce54ed6..e43c1ae24 100644 --- a/src/common/scripting/interface/stringformat.cpp +++ b/src/common/scripting/interface/stringformat.cpp @@ -408,13 +408,13 @@ DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, ByteAt, StringByteAt) static void StringFilter(FString *self, FString *result) { - *result = strbin1(*self); + *result = strbin1(self->GetChars()); } DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, Filter, StringFilter) { PARAM_SELF_STRUCT_PROLOGUE(FString); - ACTION_RETURN_STRING(strbin1(*self)); + ACTION_RETURN_STRING(strbin1(self->GetChars())); } static int StringIndexOf(FString *self, const FString &substr, int startIndex) diff --git a/src/common/scripting/jit/jit_move.cpp b/src/common/scripting/jit/jit_move.cpp index 840a6487c..edff1763c 100644 --- a/src/common/scripting/jit/jit_move.cpp +++ b/src/common/scripting/jit/jit_move.cpp @@ -58,7 +58,7 @@ static int CastS2I(FString *b) { return (int)b->ToLong(); } static double CastS2F(FString *b) { return b->ToDouble(); } static int CastS2N(FString *b) { return b->Len() == 0 ? NAME_None : FName(*b).GetIndex(); } static void CastN2S(FString *a, int b) { FName name = FName(ENamedName(b)); *a = name.IsValidName() ? name.GetChars() : ""; } -static int CastS2Co(FString *b) { return V_GetColor(*b); } +static int CastS2Co(FString *b) { return V_GetColor(b->GetChars()); } static void CastCo2S(FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %02x", c.r, c.g, c.b); } static int CastS2So(FString *b) { return S_FindSound(*b).index(); } static void CastSo2S(FString* a, int b) { *a = soundEngine->GetSoundName(FSoundID::fromInt(b)); } diff --git a/src/common/startscreen/startscreen.cpp b/src/common/startscreen/startscreen.cpp index 660561fd2..50974fd0e 100644 --- a/src/common/startscreen/startscreen.cpp +++ b/src/common/startscreen/startscreen.cpp @@ -570,8 +570,8 @@ void FStartScreen::CreateHeader() fcolor.rgbBlue = BPART(GameStartupInfo.FgColor); fcolor.rgbReserved = 255; ClearBlock(HeaderBitmap, bcolor, 0, 0, HeaderBitmap.GetWidth(), HeaderBitmap.GetHeight()); - int textlen = SizeOfText(GameStartupInfo.Name); - DrawString(HeaderBitmap, (HeaderBitmap.GetWidth() >> 4) - (textlen >> 1), 0.5, GameStartupInfo.Name, fcolor, bcolor); + int textlen = SizeOfText(GameStartupInfo.Name.GetChars()); + DrawString(HeaderBitmap, (HeaderBitmap.GetWidth() >> 4) - (textlen >> 1), 0.5, GameStartupInfo.Name.GetChars(), fcolor, bcolor); NetBitmap.Create(StartupBitmap.GetWidth() * Scale, 16); } @@ -588,7 +588,7 @@ void FStartScreen::DrawNetStatus(int found, int total) RgbQuad black = { 0, 0, 0, 255 }; RgbQuad gray = { 100, 100, 100, 255 }; ClearBlock(NetBitmap, black, 0, NetBitmap.GetHeight() - 16, NetBitmap.GetWidth(), 16); - DrawString(NetBitmap, 0, 0, NetMessageString, gray, black); + DrawString(NetBitmap, 0, 0, NetMessageString.GetChars(), gray, black); char of[10]; mysnprintf(of, 10, "%d/%d", found, total); int siz = SizeOfText(of); diff --git a/src/common/textures/multipatchtexturebuilder.cpp b/src/common/textures/multipatchtexturebuilder.cpp index c032372c3..7f94437d2 100644 --- a/src/common/textures/multipatchtexturebuilder.cpp +++ b/src/common/textures/multipatchtexturebuilder.cpp @@ -137,7 +137,7 @@ struct FPatchLookup void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType usetype) { - buildinfo.texture = new FGameTexture(nullptr, buildinfo.Name); + buildinfo.texture = new FGameTexture(nullptr, buildinfo.Name.GetChars()); buildinfo.texture->SetUseType(usetype); buildinfo.texture->SetSize(buildinfo.Width, buildinfo.Height); buildinfo.texture->SetOffsets(0, buildinfo.LeftOffset[0], buildinfo.TopOffset[0]); // These are needed for construction of other multipatch textures. @@ -373,7 +373,7 @@ void FMultipatchTextureBuilder::AddTexturesLump(const void *lumpdata, int lumpsi int j; for (j = (int)TexMan.NumTextures() - 1; j >= firstdup; --j) { - if (strnicmp(TexMan.GameByIndex(j)->GetName(), (const char *)maptex + offset, 8) == 0) + if (strnicmp(TexMan.GameByIndex(j)->GetName().GetChars(), (const char *)maptex + offset, 8) == 0) break; } if (j + 1 == firstdup) @@ -778,11 +778,11 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo) { for (unsigned i = 0; i < buildinfo.Inits.Size(); i++) { - FTextureID texno = TexMan.CheckForTexture(buildinfo.Inits[i].TexName, buildinfo.Inits[i].UseType); + FTextureID texno = TexMan.CheckForTexture(buildinfo.Inits[i].TexName.GetChars(), buildinfo.Inits[i].UseType); if (texno == buildinfo.texture->GetID()) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself. { TArray list; - TexMan.ListTextures(buildinfo.Inits[i].TexName, list, true); + TexMan.ListTextures(buildinfo.Inits[i].TexName.GetChars(), list, true); for (int ii = list.Size() - 1; ii >= 0; ii--) { auto gtex = TexMan.GetGameTexture(list[ii]); diff --git a/src/common/utility/m_argv.cpp b/src/common/utility/m_argv.cpp index d6f834d88..b9b05c3e9 100644 --- a/src/common/utility/m_argv.cpp +++ b/src/common/utility/m_argv.cpp @@ -158,7 +158,7 @@ int FArgs::CheckParm(const char** check, int start) const { for (unsigned i = start; i < Argv.Size(); ++i) { - if (0 == stricmp(check, Argv[i])) + if (0 == stricmp(check, Argv[i].GetChars())) { return i; } diff --git a/src/common/utility/memarena.cpp b/src/common/utility/memarena.cpp index 767824a64..83621df47 100644 --- a/src/common/utility/memarena.cpp +++ b/src/common/utility/memarena.cpp @@ -342,7 +342,7 @@ FString *FSharedStringArena::Alloc(const FString &source) unsigned int hash; Node *strnode; - strnode = FindString(source, source.Len(), hash); + strnode = FindString(source.GetChars(), source.Len(), hash); if (strnode == NULL) { strnode = (Node *)iAlloc(sizeof(Node)); diff --git a/src/common/utility/palette.cpp b/src/common/utility/palette.cpp index 0b5cca67b..c0fcd9f5d 100644 --- a/src/common/utility/palette.cpp +++ b/src/common/utility/palette.cpp @@ -759,7 +759,7 @@ int V_GetColor(const char* str, FScriptPosition* sc) if (!string.IsEmpty()) { - res = V_GetColorFromString(string, sc); + res = V_GetColorFromString(string.GetChars(), sc); } else { diff --git a/src/g_statusbar/sbar_mugshot.cpp b/src/g_statusbar/sbar_mugshot.cpp index 3f79b9643..f1d43af28 100644 --- a/src/g_statusbar/sbar_mugshot.cpp +++ b/src/g_statusbar/sbar_mugshot.cpp @@ -97,7 +97,7 @@ FGameTexture *FMugShotFrame::GetTexture(const char *default_face, const char *sk } sprite.UnlockBuffer(); } - return TexMan.GetGameTexture(TexMan.CheckForTexture(sprite, ETextureType::Any, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_AllowSkins)); + return TexMan.GetGameTexture(TexMan.CheckForTexture(sprite.GetChars(), ETextureType::Any, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_AllowSkins)); } //=========================================================================== @@ -376,7 +376,7 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags) full_state_name = "pain."; } full_state_name += player->LastDamageType.GetChars(); - if (SetState(full_state_name, false, true)) + if (SetState(full_state_name.GetChars(), false, true)) { bDamageFaceActive = (CurrentState != NULL); LastDamageAngle = damage_angle; @@ -403,7 +403,7 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags) full_state_name = "pain."; } full_state_name += player->LastDamageType.GetChars(); - if (SetState(full_state_name)) + if (SetState(full_state_name.GetChars())) { bOuchActive = use_ouch; } @@ -445,7 +445,7 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags) full_state_name = "xdeath."; } full_state_name += player->LastDamageType.GetChars(); - SetState(full_state_name); + SetState(full_state_name.GetChars()); bNormal = true; //Allow the face to return to alive states when the player respawns. } return 0; diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index 6d6b8b7b3..dd864a550 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -443,7 +443,7 @@ void SBarInfo::Load() { if(gameinfo.statusbar.IsNotEmpty()) { - int lump = fileSystem.CheckNumForFullName(gameinfo.statusbar, true); + int lump = fileSystem.CheckNumForFullName(gameinfo.statusbar.GetChars(), true); if(lump != -1) { if (!batchrun) Printf ("ParseSBarInfo: Loading default status bar definition.\n"); @@ -795,7 +795,7 @@ int SBarInfo::newImage(const char *patchname) } for(unsigned int i = 0;i < this->Images.Size();i++) //did we already load it? { - if(stricmp(this->Images[i], patchname) == 0) + if(stricmp(this->Images[i].GetChars(), patchname) == 0) { return i; } @@ -996,7 +996,7 @@ public: unsigned int i = 0; for(i = 0;i < script->Images.Size();i++) { - patchnames[i] = script->Images[i]; + patchnames[i] = script->Images[i].GetChars(); } for(i = 0;i < 9;i++) { diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index a6e084ea3..fb54f7481 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -692,7 +692,7 @@ class CommandDrawString : public SBarInfoCommand auto lines = V_BreakLines(font, breakWidth, str.GetChars()); for(unsigned i = 0; i < lines.Size();i++) { - statusBar->DrawString(font, lines[i].Text, x, y+i*(font->GetHeight()+4), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), translation, spacing, shadow, shadowX, shadowY); + statusBar->DrawString(font, lines[i].Text.GetChars(), x, y+i*(font->GetHeight()+4), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), translation, spacing, shadow, shadowX, shadowY); } } else @@ -1183,7 +1183,7 @@ class CommandDrawNumber : public CommandDrawString // We have a name, but make sure it exists. If not, send notification so modders // are aware of the situation. - FBaseCVar *CVar = FindCVar(cvarName, nullptr); + FBaseCVar *CVar = FindCVar(cvarName.GetChars(), nullptr); if (CVar != nullptr) { @@ -1484,7 +1484,7 @@ class CommandDrawNumber : public CommandDrawString break; case INTCVAR: { - FBaseCVar *CVar = GetCVar(int(statusBar->CPlayer - players), cvarName); + FBaseCVar *CVar = GetCVar(int(statusBar->CPlayer - players), cvarName.GetChars()); if (CVar != nullptr) { ECVarType cvartype = CVar->GetRealType(); @@ -1618,7 +1618,7 @@ class CommandDrawMugShot : public SBarInfoCommand void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar) { - FGameTexture *face = statusBar->wrapper->mugshot.GetFace(statusBar->CPlayer, defaultFace, accuracy, stateFlags); + FGameTexture *face = statusBar->wrapper->mugshot.GetFace(statusBar->CPlayer, defaultFace.GetChars(), accuracy, stateFlags); if (face != NULL) statusBar->DrawGraphic(face, x, y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); } @@ -2954,7 +2954,7 @@ class CommandPlayerClass : public SBarInfoCommandFlowControl bool foundClass = false; for(unsigned int c = 0;c < PlayerClasses.Size();c++) { - if(stricmp(sc.String, PlayerClasses[c].Type->GetDisplayName()) == 0) + if(stricmp(sc.String, PlayerClasses[c].Type->GetDisplayName().GetChars()) == 0) { foundClass = true; classes.Push(PlayerClasses[c].Type); @@ -3499,7 +3499,7 @@ class CommandIfCVarInt : public SBarInfoNegatableFlowControl } cvarname = sc.String; - cvar = FindCVar(cvarname, nullptr); + cvar = FindCVar(cvarname.GetChars(), nullptr); if (cvar != nullptr) { @@ -3536,7 +3536,7 @@ class CommandIfCVarInt : public SBarInfoNegatableFlowControl SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged); bool result = false; - cvar = GetCVar(int(statusBar->CPlayer - players), cvarname); + cvar = GetCVar(int(statusBar->CPlayer - players), cvarname.GetChars()); if (cvar != nullptr) { diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 55d18333b..ce3dc84a3 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -157,45 +157,45 @@ void V_DrawFrame(F2DDrawer* drawer, int left, int top, int width, int height, bo if (!scalemode) { // Draw top and bottom sides. - p = TexMan.GetGameTextureByName(border->t); + p = TexMan.GetGameTextureByName(border->t.GetChars()); drawer->AddFlatFill(left, top - (int)p->GetDisplayHeight(), right, top, p, true); - p = TexMan.GetGameTextureByName(border->b); + p = TexMan.GetGameTextureByName(border->b.GetChars()); drawer->AddFlatFill(left, bottom, right, bottom + (int)p->GetDisplayHeight(), p, true); // Draw left and right sides. - p = TexMan.GetGameTextureByName(border->l); + p = TexMan.GetGameTextureByName(border->l.GetChars()); drawer->AddFlatFill(left - (int)p->GetDisplayWidth(), top, left, bottom, p, true); - p = TexMan.GetGameTextureByName(border->r); + p = TexMan.GetGameTextureByName(border->r.GetChars()); drawer->AddFlatFill(right, top, right + (int)p->GetDisplayWidth(), bottom, p, true); // Draw beveled corners. - DrawTexture(drawer, TexMan.GetGameTextureByName(border->tl), left - offset, top - offset, TAG_DONE); - DrawTexture(drawer, TexMan.GetGameTextureByName(border->tr), left + width, top - offset, TAG_DONE); - DrawTexture(drawer, TexMan.GetGameTextureByName(border->bl), left - offset, top + height, TAG_DONE); - DrawTexture(drawer, TexMan.GetGameTextureByName(border->br), left + width, top + height, TAG_DONE); + DrawTexture(drawer, TexMan.GetGameTextureByName(border->tl.GetChars()), left - offset, top - offset, TAG_DONE); + DrawTexture(drawer, TexMan.GetGameTextureByName(border->tr.GetChars()), left + width, top - offset, TAG_DONE); + DrawTexture(drawer, TexMan.GetGameTextureByName(border->bl.GetChars()), left - offset, top + height, TAG_DONE); + DrawTexture(drawer, TexMan.GetGameTextureByName(border->br.GetChars()), left + width, top + height, TAG_DONE); } else { // Draw top and bottom sides. - p = TexMan.GetGameTextureByName(border->t); + p = TexMan.GetGameTextureByName(border->t.GetChars()); drawer->AddFlatFill(left, top - (int)(p->GetDisplayHeight() / sh), right, top, p, -2); - p = TexMan.GetGameTextureByName(border->b); + p = TexMan.GetGameTextureByName(border->b.GetChars()); drawer->AddFlatFill(left, bottom, right, bottom + (int)(p->GetDisplayHeight() / sh), p, -2); // Draw left and right sides. - p = TexMan.GetGameTextureByName(border->l); + p = TexMan.GetGameTextureByName(border->l.GetChars()); drawer->AddFlatFill(left - (int)(p->GetDisplayWidth() / sw), top, left, bottom, p, -2); - p = TexMan.GetGameTextureByName(border->r); + p = TexMan.GetGameTextureByName(border->r.GetChars()); drawer->AddFlatFill(right, top, right + (int)(p->GetDisplayWidth() / sw), bottom, p, -2); // Draw beveled corners. - p = TexMan.GetGameTextureByName(border->tl); + p = TexMan.GetGameTextureByName(border->tl.GetChars()); drawer->AddFlatFill(left - (int)(p->GetDisplayWidth() / sw), top - (int)(p->GetDisplayHeight() / sh), left, top, p, -2); - p = TexMan.GetGameTextureByName(border->tr); + p = TexMan.GetGameTextureByName(border->tr.GetChars()); drawer->AddFlatFill(right, top - (int)(p->GetDisplayHeight() / sh), right + (int)(p->GetDisplayWidth() / sw), top, p, -2); - p = TexMan.GetGameTextureByName(border->bl); + p = TexMan.GetGameTextureByName(border->bl.GetChars()); drawer->AddFlatFill(left - (int)(p->GetDisplayWidth() / sw), bottom, left, bottom + (int)(p->GetDisplayHeight() / sh), p, -2); - p = TexMan.GetGameTextureByName(border->br); + p = TexMan.GetGameTextureByName(border->br.GetChars()); drawer->AddFlatFill(right, bottom, right + (int)(p->GetDisplayWidth() / sw), bottom + (int)(p->GetDisplayHeight() / sh), p, -2); } } @@ -553,7 +553,7 @@ void DBaseStatusBar::DoDrawAutomapHUD(int crdefault, int highlight) { sec = Tics2Seconds(primaryLevel->time); textbuffer.Format("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); - DrawText(twod, font, crdefault, vwidth - zerowidth * 8 - textdist, y, textbuffer, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, + DrawText(twod, font, crdefault, vwidth - zerowidth * 8 - textdist, y, textbuffer.GetChars(), DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, DTA_Monospace, EMonospacing::CellCenter, DTA_Spacing, zerowidth, DTA_KeepRatio, true, TAG_END); y += fheight; } @@ -562,7 +562,7 @@ void DBaseStatusBar::DoDrawAutomapHUD(int crdefault, int highlight) { sec = Tics2Seconds(primaryLevel->totaltime); textbuffer.Format("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60); - DrawText(twod, font, crdefault, vwidth - zerowidth * 8 - textdist, y, textbuffer, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, + DrawText(twod, font, crdefault, vwidth - zerowidth * 8 - textdist, y, textbuffer.GetChars(), DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, DTA_Monospace, EMonospacing::CellCenter, DTA_Spacing, zerowidth, DTA_KeepRatio, true, TAG_END); } @@ -572,14 +572,14 @@ void DBaseStatusBar::DoDrawAutomapHUD(int crdefault, int highlight) if (am_showmonsters) { textbuffer.Format("%s\34%c %d/%d", GStrings("AM_MONSTERS"), crdefault + 65, primaryLevel->killed_monsters, primaryLevel->total_monsters); - DrawText(twod, font2, highlight, textdist, y, textbuffer, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); + DrawText(twod, font2, highlight, textdist, y, textbuffer.GetChars(), DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); y += fheight; } if (am_showsecrets) { textbuffer.Format("%s\34%c %d/%d", GStrings("AM_SECRETS"), crdefault + 65, primaryLevel->found_secrets, primaryLevel->total_secrets); - DrawText(twod, font2, highlight, textdist, y, textbuffer, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); + DrawText(twod, font2, highlight, textdist, y, textbuffer.GetChars(), DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); y += fheight; } @@ -587,7 +587,7 @@ void DBaseStatusBar::DoDrawAutomapHUD(int crdefault, int highlight) if (am_showitems) { textbuffer.Format("%s\34%c %d/%d", GStrings("AM_ITEMS"), crdefault + 65, primaryLevel->found_items, primaryLevel->total_items); - DrawText(twod, font2, highlight, textdist, y, textbuffer, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); + DrawText(twod, font2, highlight, textdist, y, textbuffer.GetChars(), DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); y += fheight; } @@ -627,7 +627,7 @@ void DBaseStatusBar::DoDrawAutomapHUD(int crdefault, int highlight) for (unsigned i = 0; i < numlines; i++) { int x = (vwidth - font->StringWidth(lines[i].Text)) / 2; - DrawText(twod, font, highlight, x, y, lines[i].Text, DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); + DrawText(twod, font, highlight, x, y, lines[i].Text.GetChars(), DTA_KeepRatio, true, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, TAG_DONE); y += fheight; } } @@ -876,10 +876,10 @@ static FTextureID GetBorderTexture(FLevelLocals *Level) { if (Level != nullptr && Level->info != nullptr && Level->info->BorderTexture.Len() != 0) { - auto picnum = TexMan.CheckForTexture (Level->info->BorderTexture, ETextureType::Flat); + auto picnum = TexMan.CheckForTexture (Level->info->BorderTexture.GetChars(), ETextureType::Flat); if (picnum.isValid()) return picnum; } - return TexMan.CheckForTexture (gameinfo.BorderFlat, ETextureType::Flat); + return TexMan.CheckForTexture (gameinfo.BorderFlat.GetChars(), ETextureType::Flat); } //========================================================================== @@ -958,7 +958,7 @@ void DBaseStatusBar::RefreshBackground () const if (setblocks >= 10) { - FGameTexture *p = TexMan.GetGameTextureByName(gameinfo.Border.b); + FGameTexture *p = TexMan.GetGameTextureByName(gameinfo.Border.b.GetChars()); if (p != NULL) { if (!ui_screenborder_classic_scaling) @@ -1143,7 +1143,7 @@ void DBaseStatusBar::DrawLog () y+=10; for (const FBrokenLines &line : lines) { - DrawText(twod, font, CPlayer->SubtitleCounter? CR_CYAN : CR_UNTRANSLATED, x, y, line.Text, + DrawText(twod, font, CPlayer->SubtitleCounter? CR_CYAN : CR_UNTRANSLATED, x, y, line.Text.GetChars(), DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, TAG_DONE); y += font->GetHeight (); diff --git a/src/gamedata/keysections.cpp b/src/gamedata/keysections.cpp index 30a3f8d2a..5a218638f 100644 --- a/src/gamedata/keysections.cpp +++ b/src/gamedata/keysections.cpp @@ -72,7 +72,7 @@ static void DoSaveKeys (FConfigFile *config, const char *section, FKeySection *k FKeyBindings *bindings = dbl? &DoubleBindings : &Bindings; for (unsigned i = 0; i < keysection->mActions.Size(); ++i) { - bindings->ArchiveBindings (config, keysection->mActions[i].mAction); + bindings->ArchiveBindings (config, keysection->mActions[i].mAction.GetChars()); } } diff --git a/src/gamedata/statistics.cpp b/src/gamedata/statistics.cpp index 39f67a998..f1ebbd483 100644 --- a/src/gamedata/statistics.cpp +++ b/src/gamedata/statistics.cpp @@ -202,7 +202,7 @@ int compare_episode_names(const void *a, const void *b) FStatistics *A = (FStatistics*)a; FStatistics *B = (FStatistics*)b; - return strnatcasecmp(A->epi_header, B->epi_header); + return strnatcasecmp(A->epi_header.GetChars(), B->epi_header.GetChars()); } int compare_dates(const void *a, const void *b) @@ -291,7 +291,7 @@ static FStatistics *GetStatisticsList(TArray &statlist, const char { for(unsigned int i=0;iLevelname, B->Levelname); + return strnatcasecmp(A->Levelname.GetChars(), B->Levelname.GetChars()); } @@ -458,7 +458,7 @@ void STAT_ChangeLevel(const char *newl, FLevelLocals *Level) { // we reached the end of this episode int wad = 0; - MapData * map = P_OpenMapData(StartEpisode->mEpisodeMap, false); + MapData * map = P_OpenMapData(StartEpisode->mEpisodeMap.GetChars(), false); if (map != NULL) { wad = fileSystem.GetFileContainer(map->lumpnum); @@ -468,9 +468,9 @@ void STAT_ChangeLevel(const char *newl, FLevelLocals *Level) FString section = ExtractFileBase(name) + "." + StartEpisode->mEpisodeMap; section.ToUpper(); - const char *ep_name = StartEpisode->mEpisodeName; + const char *ep_name = StartEpisode->mEpisodeName.GetChars(); if (*ep_name == '$') ep_name = GStrings(ep_name+1); - FStatistics *sl = GetStatisticsList(EpisodeStatistics, section, ep_name); + FStatistics *sl = GetStatisticsList(EpisodeStatistics, section.GetChars(), ep_name); int statvals[6] = {0,0,0,0,0,0}; FString infostring; @@ -486,7 +486,7 @@ void STAT_ChangeLevel(const char *newl, FLevelLocals *Level) } infostring.Format("%4d/%4d, %4d/%4d, %3d/%3d, %2d", statvals[0], statvals[1], statvals[2], statvals[3], statvals[4], statvals[5], validlevels); - FSessionStatistics *es = StatisticsEntry(sl, infostring, Level->totaltime); + FSessionStatistics *es = StatisticsEntry(sl, infostring.GetChars(), Level->totaltime); for(unsigned i = 0; i < LevelData.Size(); i++) { @@ -495,7 +495,7 @@ void STAT_ChangeLevel(const char *newl, FLevelLocals *Level) infostring.Format("%4d/%4d, %4d/%4d, %3d/%3d", LevelData[i].killcount, LevelData[i].totalkills, LevelData[i].itemcount, LevelData[i].totalitems, LevelData[i].secretcount, LevelData[i].totalsecrets); - LevelStatEntry(es, lsection, infostring, LevelData[i].leveltime); + LevelStatEntry(es, lsection.GetChars(), infostring.GetChars(), LevelData[i].leveltime); } SaveStatistics(statfile, EpisodeStatistics); } diff --git a/src/m_misc.cpp b/src/m_misc.cpp index 5960dfa36..dfef16eb2 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -281,7 +281,7 @@ bool M_SaveDefaults (const char *filename) GameConfig->ArchiveGlobalData (); if (gameinfo.ConfigName.IsNotEmpty()) { - GameConfig->ArchiveGameData (gameinfo.ConfigName); + GameConfig->ArchiveGameData (gameinfo.ConfigName.GetChars()); } success = GameConfig->WriteConfigFile (); if (filename != nullptr) @@ -318,7 +318,7 @@ UNSAFE_CCMD (writeini) CCMD(openconfig) { M_SaveDefaults(nullptr); - I_OpenShellFolder(ExtractFilePath(GameConfig->GetPathName())); + I_OpenShellFolder(ExtractFilePath(GameConfig->GetPathName()).GetChars()); } // @@ -537,7 +537,7 @@ static bool FindFreeName (FString &fullname, const char *extension) for (i = 0; i <= 9999; i++) { - const char *gamename = gameinfo.ConfigName; + const char *gamename = gameinfo.ConfigName.GetChars(); time_t now; tm *tm; @@ -601,8 +601,8 @@ void M_ScreenShot (const char *filename) autoname += '/'; } } - autoname = NicePath(autoname); - CreatePath(autoname); + autoname = NicePath(autoname.GetChars()); + CreatePath(autoname.GetChars()); if (!FindFreeName (autoname, writepcx ? "pcx" : "png")) { Printf ("M_ScreenShot: Delete some screenshots\n"); @@ -623,7 +623,7 @@ void M_ScreenShot (const char *filename) auto buffer = screen->GetScreenshotBuffer(pitch, color_type, gamma); if (buffer.Size() > 0) { - file = FileWriter::Open(autoname); + file = FileWriter::Open(autoname.GetChars()); if (file == NULL) { Printf ("Could not open %s\n", autoname.GetChars()); @@ -687,9 +687,9 @@ CCMD(openscreenshots) autoname += '/'; } } - autoname = NicePath(autoname); + autoname = NicePath(autoname.GetChars()); - CreatePath(autoname); + CreatePath(autoname.GetChars()); I_OpenShellFolder(autoname.GetChars()); } diff --git a/src/maploader/maploader.cpp b/src/maploader/maploader.cpp index 095c795ec..727415be1 100644 --- a/src/maploader/maploader.cpp +++ b/src/maploader/maploader.cpp @@ -2058,9 +2058,9 @@ void MapLoader::ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec // instead of figuring something out from the colormap. if (sec != nullptr) { - SetTexture (sd, side_t::bottom, &sec->bottommap, msd->bottomtexture); - SetTexture (sd, side_t::mid, &sec->midmap, msd->midtexture); - SetTexture (sd, side_t::top, &sec->topmap, msd->toptexture); + SetTexture (sd, side_t::bottom, &sec->bottommap, msd->bottomtexture.GetChars()); + SetTexture (sd, side_t::mid, &sec->midmap, msd->midtexture.GetChars()); + SetTexture (sd, side_t::top, &sec->topmap, msd->toptexture.GetChars()); } break; @@ -2072,9 +2072,9 @@ void MapLoader::ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec uint32_t color = MAKERGB(255,255,255), fog = 0; bool colorgood, foggood; - SetTextureNoErr (sd, side_t::bottom, &fog, msd->bottomtexture, &foggood, true); - SetTextureNoErr (sd, side_t::top, &color, msd->toptexture, &colorgood, false); - SetTexture(sd, side_t::mid, msd->midtexture, missingtex); + SetTextureNoErr (sd, side_t::bottom, &fog, msd->bottomtexture.GetChars(), &foggood, true); + SetTextureNoErr (sd, side_t::top, &color, msd->toptexture.GetChars(), &colorgood, false); + SetTexture(sd, side_t::mid, msd->midtexture.GetChars(), missingtex); if (colorgood | foggood) { @@ -2114,12 +2114,12 @@ void MapLoader::ProcessSideTextures(bool checktranmap, side_t *sd, sector_t *sec { int lumpnum; - if (strnicmp ("TRANMAP", msd->midtexture, 8) == 0) + if (strnicmp ("TRANMAP", msd->midtexture.GetChars(), 8) == 0) { // The translator set the alpha argument already; no reason to do it again. sd->SetTexture(side_t::mid, FNullTextureID()); } - else if ((lumpnum = fileSystem.CheckNumForName (msd->midtexture)) > 0 && + else if ((lumpnum = fileSystem.CheckNumForName (msd->midtexture.GetChars())) > 0 && fileSystem.FileLength (lumpnum) == 65536) { auto fr = fileSystem.OpenFileReader(lumpnum); diff --git a/src/maploader/strifedialogue.cpp b/src/maploader/strifedialogue.cpp index cb2b2665b..ac9273621 100644 --- a/src/maploader/strifedialogue.cpp +++ b/src/maploader/strifedialogue.cpp @@ -109,7 +109,7 @@ void MapLoader::LoadStrifeConversations (MapData *map, const char *mapname) bool addedDialogues = false; for (const FString &addd : gameinfo.AddDialogues) { - if (!LoadScriptFile(addd, true, 0)) + if (!LoadScriptFile(addd.GetChars(), true, 0)) { continue; } @@ -133,7 +133,7 @@ void MapLoader::LoadStrifeConversations (MapData *map, const char *mapname) if (gameinfo.Dialogue.IsNotEmpty()) { - if (LoadScriptFile(gameinfo.Dialogue, false, 0)) + if (LoadScriptFile(gameinfo.Dialogue.GetChars(), false, 0)) { if (addedDialogues) { diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 2651f24b4..4202ba23e 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -171,7 +171,7 @@ FString FSavegameManager::ExtractSaveComment(FSerializer &arc) FString FSavegameManager::BuildSaveName(const char* prefix, int slot) { - return G_BuildSaveName(FStringf("%s%02d", prefix, slot)); + return G_BuildSaveName(FStringf("%s%02d", prefix, slot).GetChars()); } //============================================================================= diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index 6c930147c..07192a2d9 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -81,7 +81,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, PlayerNameChanged) { PARAM_PROLOGUE; PARAM_STRING(s); - const char *pp = s; + const char *pp = s.GetChars(); FString command("name \""); if (DMenu::InMenu) @@ -96,7 +96,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, PlayerNameChanged) command << *p; } command << '"'; - C_DoCommand(command); + C_DoCommand(command.GetChars()); } return 0; } @@ -155,7 +155,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, SkinChanged) if (DMenu::InMenu) { players[consoleplayer].userinfo.SkinNumChanged(sel); - cvar_set("skin", Skins[sel].Name); + cvar_set("skin", Skins[sel].Name.GetChars()); } return 0; } diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 47d9a896f..a772c1dd3 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -503,7 +503,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply // No, you don't. Say so and let the NPC animate negatively. if (reply->QuickNo.IsNotEmpty() && isconsole) { - TerminalResponse(reply->QuickNo); + TerminalResponse(reply->QuickNo.GetChars()); } npc->ConversationAnimation(2); if (!(npc->flags8 & MF8_DONTFACETALKER)) @@ -576,7 +576,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply { TakeStrifeItem (player, reply->ItemCheck[i].Item, reply->ItemCheck[i].Amount); } - replyText = reply->QuickYes; + replyText = reply->QuickYes.GetChars(); } else { @@ -586,7 +586,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply // Update the quest log, if needed. if (reply->LogString.IsNotEmpty()) { - const char *log = reply->LogString; + const char *log = reply->LogString.GetChars(); if (log[0] == '$') { log = GStrings(log + 1); diff --git a/src/p_openmap.cpp b/src/p_openmap.cpp index 759c54022..e744755ba 100644 --- a/src/p_openmap.cpp +++ b/src/p_openmap.cpp @@ -140,9 +140,9 @@ MapData *P_OpenMapData(const char * mapname, bool justcheck) // Names with more than 8 characters will only be checked as .wad and .map. if (strlen(mapname) <= 8) lump_name = fileSystem.CheckNumForName(mapname); fmt.Format("maps/%s.wad", mapname); - lump_wad = fileSystem.CheckNumForFullName(fmt); + lump_wad = fileSystem.CheckNumForFullName(fmt.GetChars()); fmt.Format("maps/%s.map", mapname); - lump_map = fileSystem.CheckNumForFullName(fmt); + lump_map = fileSystem.CheckNumForFullName(fmt.GetChars()); if (lump_name > lump_wad && lump_name > lump_map && lump_name != -1) { diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index ad729b018..156226b57 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -870,11 +870,11 @@ void FLevelLocals::CopyPlayer(player_t *dst, player_t *src, const char *name) { dst->userinfo.TransferFrom(uibackup); // The player class must come from the save, so that the menu reflects the currently playing one. - dst->userinfo.PlayerClassChanged(src->mo->GetInfo()->DisplayName); + dst->userinfo.PlayerClassChanged(src->mo->GetInfo()->DisplayName.GetChars()); } // Validate the skin - dst->userinfo.SkinNumChanged(R_FindSkin(Skins[dst->userinfo.GetSkin()].Name, dst->CurrentPlayerClass)); + dst->userinfo.SkinNumChanged(R_FindSkin(Skins[dst->userinfo.GetSkin()].Name.GetChars(), dst->CurrentPlayerClass)); // Make sure the player pawn points to the proper player struct. if (dst->mo != nullptr) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index a0707357e..2563e5a4f 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -213,12 +213,12 @@ static void PrecacheLevel(FLevelLocals *Level) for (auto n : gameinfo.PrecachedTextures) { - FTextureID tex = TexMan.CheckForTexture(n, ETextureType::Wall, checkForTextureFlags); + FTextureID tex = TexMan.CheckForTexture(n.GetChars(), ETextureType::Wall, checkForTextureFlags); if (tex.Exists()) AddToList(hitlist.Data(), tex, FTextureManager::HIT_Wall); } for (unsigned i = 0; i < Level->info->PrecacheTextures.Size(); i++) { - FTextureID tex = TexMan.CheckForTexture(Level->info->PrecacheTextures[i], ETextureType::Wall, checkForTextureFlags); + FTextureID tex = TexMan.CheckForTexture(Level->info->PrecacheTextures[i].GetChars(), ETextureType::Wall, checkForTextureFlags); if (tex.Exists()) AddToList(hitlist.Data(), tex, FTextureManager::HIT_Wall); } @@ -451,7 +451,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame) // Free all level data from the previous map P_FreeLevelData(); - MapData *map = P_OpenMapData(Level->MapName, true); + MapData *map = P_OpenMapData(Level->MapName.GetChars(), true); if (map == nullptr) { I_Error("Unable to open map '%s'\n", Level->MapName.GetChars()); diff --git a/src/playsim/p_acs.cpp b/src/playsim/p_acs.cpp index fdaebf97f..79dc64a0a 100644 --- a/src/playsim/p_acs.cpp +++ b/src/playsim/p_acs.cpp @@ -979,7 +979,7 @@ int ACSStringPool::AddString(FString &str) { unsigned int h = SuperFastHash(str.GetChars(), str.Len()); unsigned int bucketnum = h % NUM_BUCKETS; - int i = FindString(str, str.Len(), h, bucketnum); + int i = FindString(str.GetChars(), str.Len(), h, bucketnum); if (i >= 0) { return i | STRPOOL_LIBRARYID_OR; @@ -999,7 +999,7 @@ const char *ACSStringPool::GetString(int strnum) strnum &= ~LIBRARYID_MASK; if ((unsigned)strnum < Pool.Size() && Pool[strnum].Next != FREE_ENTRY) { - return Pool[strnum].Str; + return Pool[strnum].Str.GetChars(); } return NULL; } @@ -1299,7 +1299,7 @@ void ACSStringPool::ReadStrings(FSerializer &file, const char *key) file("string", Pool[ii].Str) ("locks", Pool[ii].Locks); - unsigned h = SuperFastHash(Pool[ii].Str, Pool[ii].Str.Len()); + unsigned h = SuperFastHash(Pool[ii].Str.GetChars(), Pool[ii].Str.Len()); unsigned bucketnum = h % NUM_BUCKETS; Pool[ii].Hash = h; Pool[ii].Next = PoolBuckets[bucketnum]; @@ -1595,7 +1595,7 @@ static void WriteArrayVars (FSerializer &file, FWorldGlobalArray *vars, unsigned FString arraykey; arraykey.Format("%d", i); - if (file.BeginObject(arraykey)) + if (file.BeginObject(arraykey.GetChars())) { FWorldGlobalArray::ConstIterator it(vars[i]); const FWorldGlobalArray::Pair *pair; @@ -3248,7 +3248,7 @@ const char *FBehavior::LookupString (uint32_t index, bool forprint) const token.Truncate(5); FStringf label("TXT_ACS_%s_%d_%.5s", Level->MapName.GetChars(), index, token.GetChars()); - auto p = GStrings[label]; + auto p = GStrings[label.GetChars()]; if (p) return p; } @@ -6093,7 +6093,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) { newlen = oldlen - pos; } - return GlobalACSStrings.AddString(FString(oldstr + pos, newlen)); + return GlobalACSStrings.AddString(FString(oldstr + pos, newlen).GetChars()); } break; @@ -6674,7 +6674,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) auto a = Level->SingleActorFromTID(args[0], activator); if (a != nullptr) { - return GlobalACSStrings.AddString(TexMan.GetGameTexture(a->floorpic)->GetName()); + return GlobalACSStrings.AddString(TexMan.GetGameTexture(a->floorpic)->GetName().GetChars()); } else { @@ -8729,7 +8729,7 @@ scriptwait: if (pcd == PCD_ENDPRINTBOLD || screen == NULL || screen->CheckLocalView()) { - C_MidPrint (activefont, work, pcd == PCD_ENDPRINTBOLD && (gameinfo.correctprintbold || (Level->flags2 & LEVEL2_HEXENHACK))); + C_MidPrint (activefont, work.GetChars(), pcd == PCD_ENDPRINTBOLD && (gameinfo.correctprintbold || (Level->flags2 & LEVEL2_HEXENHACK))); } STRINGBUILDER_FINISH(work); } @@ -10504,7 +10504,7 @@ EXTERN_CVAR (Bool, sv_cheats) int P_StartScript (FLevelLocals *Level, AActor *who, line_t *where, int script, const char *map, const int *args, int argcount, int flags) { - if (map == NULL || 0 == strnicmp (Level->MapName, map, 8)) + if (map == NULL || 0 == strnicmp (Level->MapName.GetChars(), map, 8)) { FBehavior *module = NULL; const ScriptPtr *scriptdata; @@ -10559,7 +10559,7 @@ int P_StartScript (FLevelLocals *Level, AActor *who, line_t *where, int script, void P_SuspendScript (FLevelLocals *Level, int script, const char *map) { - if (strnicmp (Level->MapName, map, 8)) + if (strnicmp (Level->MapName.GetChars(), map, 8)) addDefered (FindLevelInfo (map), acsdefered_t::defsuspend, script, NULL, 0, NULL); else SetScriptState (Level->ACSThinker, script, DLevelScript::SCRIPT_Suspended); @@ -10567,7 +10567,7 @@ void P_SuspendScript (FLevelLocals *Level, int script, const char *map) void P_TerminateScript (FLevelLocals *Level, int script, const char *map) { - if (strnicmp (Level->MapName, map, 8)) + if (strnicmp (Level->MapName.GetChars(), map, 8)) addDefered (FindLevelInfo (map), acsdefered_t::defterminate, script, NULL, 0, NULL); else SetScriptState (Level->ACSThinker, script, DLevelScript::SCRIPT_PleaseRemove); diff --git a/src/playsim/p_actionfunctions.cpp b/src/playsim/p_actionfunctions.cpp index 681983f4f..4715fced5 100644 --- a/src/playsim/p_actionfunctions.cpp +++ b/src/playsim/p_actionfunctions.cpp @@ -384,7 +384,7 @@ DEFINE_ACTION_FUNCTION(AActor, GetCVar) PARAM_SELF_PROLOGUE(AActor); PARAM_STRING(cvarname); - FBaseCVar *cvar = GetCVar(self->player ? int(self->player - players) : -1, cvarname); + FBaseCVar *cvar = GetCVar(self->player ? int(self->player - players) : -1, cvarname.GetChars()); if (cvar == nullptr) { ret->SetFloat(0); @@ -414,7 +414,7 @@ DEFINE_ACTION_FUNCTION(AActor, GetCVarString) PARAM_SELF_PROLOGUE(AActor); PARAM_STRING(cvarname); - FBaseCVar *cvar = GetCVar(self->player? int(self->player - players) : -1, cvarname); + FBaseCVar *cvar = GetCVar(self->player? int(self->player - players) : -1, cvarname.GetChars()); if (cvar == nullptr) { ret->SetString(""); @@ -1306,7 +1306,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Print) { con_midtime = float(time); } - FString formatted = strbin1(text); + FString formatted = strbin1(text.GetChars()); C_MidPrint(font, formatted.GetChars()); con_midtime = saved; } @@ -1338,7 +1338,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_PrintBold) { con_midtime = float(time); } - FString formatted = strbin1(text); + FString formatted = strbin1(text.GetChars()); C_MidPrint(font, formatted.GetChars(), true); con_midtime = saved; return 0; @@ -1359,7 +1359,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Log) if (local && !self->CheckLocalView()) return 0; if (text[0] == '$') text = GStrings(&text[1]); - FString formatted = strbin1(text); + FString formatted = strbin1(text.GetChars()); Printf("%s\n", formatted.GetChars()); return 0; } @@ -2686,7 +2686,7 @@ DEFINE_ACTION_FUNCTION(AActor, CheckFlag) PARAM_INT (checkpointer); AActor *owner = COPY_AAPTR(self, checkpointer); - ACTION_RETURN_BOOL(owner != nullptr && CheckActorFlag(owner, flagname)); + ACTION_RETURN_BOOL(owner != nullptr && CheckActorFlag(owner, flagname.GetChars())); } @@ -5080,7 +5080,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SprayDecal) PARAM_FLOAT(direction_z); PARAM_BOOL(useBloodColor); PARAM_COLOR(decalColor); - SprayDecal(self, name, dist, DVector3(offset_x, offset_y, offset_z), DVector3(direction_x, direction_y, direction_z), useBloodColor, decalColor); + SprayDecal(self, name.GetChars(), dist, DVector3(offset_x, offset_y, offset_z), DVector3(direction_x, direction_y, direction_z), useBloodColor, decalColor); return 0; } @@ -5089,7 +5089,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SetMugshotState) PARAM_SELF_PROLOGUE(AActor); PARAM_STRING(name); if (self->CheckLocalView()) - StatusBar->SetMugShotState(name); + StatusBar->SetMugShotState(name.GetChars()); return 0; } diff --git a/src/playsim/p_interaction.cpp b/src/playsim/p_interaction.cpp index 88a06e435..e80194622 100644 --- a/src/playsim/p_interaction.cpp +++ b/src/playsim/p_interaction.cpp @@ -219,7 +219,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf } FString obit = DamageTypeDefinition::GetObituary(mod); - if (attacker == nullptr && obit.IsNotEmpty()) messagename = obit; + if (attacker == nullptr && obit.IsNotEmpty()) messagename = obit.GetChars(); else { switch (mod.GetIndex()) @@ -249,11 +249,11 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf else { lookup.Format("$Obituary_%s_%s", attacker->GetClass()->TypeName.GetChars(), mod.GetChars()); - if (GStrings[lookup.GetChars() + 1]) message = lookup; + if (GStrings[lookup.GetChars() + 1]) message = lookup.GetChars(); else { lookup.Format("$Obituary_%s", attacker->GetClass()->TypeName.GetChars()); - if (GStrings[lookup.GetChars() + 1]) message = lookup; + if (GStrings[lookup.GetChars() + 1]) message = lookup.GetChars(); else { IFVIRTUALPTR(attacker, AActor, GetObituary) @@ -261,7 +261,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf VMValue params[] = { attacker, self, inflictor, mod.GetIndex(), !!(dmgflags & DMG_PLAYERATTACK) }; VMReturn rett(&ret); VMCall(func, params, countof(params), &rett, 1); - if (ret.IsNotEmpty()) message = ret; + if (ret.IsNotEmpty()) message = ret.GetChars(); } } } @@ -283,12 +283,12 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf if (mod == NAME_Melee) { FStringf ob("DEFHITOB_%s", cls); - message = GStrings.GetString(ob, nullptr, self->player->userinfo.GetGender()); + message = GStrings.GetString(ob.GetChars(), nullptr, self->player->userinfo.GetGender()); } if (message == nullptr) { FStringf ob("DEFOB_%s", cls); - message = GStrings.GetString(ob, nullptr, self->player->userinfo.GetGender()); + message = GStrings.GetString(ob.GetChars(), nullptr, self->player->userinfo.GetGender()); } if (message == nullptr) { diff --git a/src/playsim/p_lnspec.cpp b/src/playsim/p_lnspec.cpp index 407cc23e4..3eb4835ec 100644 --- a/src/playsim/p_lnspec.cpp +++ b/src/playsim/p_lnspec.cpp @@ -1082,7 +1082,7 @@ FUNC(LS_Generic_Lift) FUNC(LS_Exit_Normal) // Exit_Normal (position) { - if (Level->CheckIfExitIsGood (it, FindLevelInfo(Level->NextMap))) + if (Level->CheckIfExitIsGood (it, FindLevelInfo(Level->NextMap.GetChars()))) { Level->ExitLevel (arg0, false); return true; @@ -1110,7 +1110,7 @@ FUNC(LS_Teleport_NewMap) if (info && Level->CheckIfExitIsGood (it, info)) { - Level->ChangeLevel(info->MapName, arg1, arg2 ? CHANGELEVEL_KEEPFACING : 0); + Level->ChangeLevel(info->MapName.GetChars(), arg1, arg2 ? CHANGELEVEL_KEEPFACING : 0); return true; } } @@ -1928,11 +1928,11 @@ FUNC(LS_ACS_Execute) if (arg1 == 0) { - mapname = Level->MapName; + mapname = Level->MapName.GetChars(); } else if ((info = FindLevelByNum(arg1)) != NULL) { - mapname = info->MapName; + mapname = info->MapName.GetChars(); } else { @@ -1951,11 +1951,11 @@ FUNC(LS_ACS_ExecuteAlways) if (arg1 == 0) { - mapname = Level->MapName; + mapname = Level->MapName.GetChars(); } else if ((info = FindLevelByNum(arg1)) != NULL) { - mapname = info->MapName; + mapname = info->MapName.GetChars(); } else { @@ -1991,7 +1991,7 @@ FUNC(LS_ACS_ExecuteWithResult) int args[4] = { arg1, arg2, arg3, arg4 }; int flags = (backSide ? ACS_BACKSIDE : 0) | ACS_ALWAYS | ACS_WANTRESULT; - return P_StartScript (Level, it, ln, arg0, Level->MapName, args, 4, flags); + return P_StartScript (Level, it, ln, arg0, Level->MapName.GetChars(), args, 4, flags); } FUNC(LS_ACS_Suspend) @@ -2000,9 +2000,9 @@ FUNC(LS_ACS_Suspend) level_info_t *info; if (arg1 == 0) - P_SuspendScript (Level, arg0, Level->MapName); + P_SuspendScript (Level, arg0, Level->MapName.GetChars()); else if ((info = FindLevelByNum (arg1)) ) - P_SuspendScript (Level, arg0, info->MapName); + P_SuspendScript (Level, arg0, info->MapName.GetChars()); return true; } @@ -2013,9 +2013,9 @@ FUNC(LS_ACS_Terminate) level_info_t *info; if (arg1 == 0) - P_TerminateScript (Level, arg0, Level->MapName); + P_TerminateScript (Level, arg0, Level->MapName.GetChars()); else if ((info = FindLevelByNum (arg1)) ) - P_TerminateScript (Level, arg0, info->MapName); + P_TerminateScript (Level, arg0, info->MapName.GetChars()); return true; } @@ -3258,7 +3258,7 @@ FUNC(LS_SendToCommunicator) // Get the message from the LANGUAGE lump. FString msg; msg.Format("TXT_COMM%d", arg2); - const char *str = GStrings[msg]; + const char *str = GStrings[msg.GetChars()]; if (str != NULL) { Printf (PRINT_CHAT, "%s\n", str); diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 1dcf511da..dc445fc00 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -5299,7 +5299,7 @@ AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flag } // [GRB] Reset skin - p->userinfo.SkinNumChanged(R_FindSkin (Skins[p->userinfo.GetSkin()].Name, p->CurrentPlayerClass)); + p->userinfo.SkinNumChanged(R_FindSkin (Skins[p->userinfo.GetSkin()].Name.GetChars(), p->CurrentPlayerClass)); if (!(mobj->flags2 & MF2_DONTTRANSLATE)) { diff --git a/src/playsim/p_user.cpp b/src/playsim/p_user.cpp index 66a7e83bb..eec52a77d 100644 --- a/src/playsim/p_user.cpp +++ b/src/playsim/p_user.cpp @@ -430,7 +430,7 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, SetLogText) { PARAM_SELF_STRUCT_PROLOGUE(player_t); PARAM_STRING(log); - self->SetLogText(log); + self->SetLogText(log.GetChars()); return 0; } @@ -828,16 +828,16 @@ static int SetupCrouchSprite(AActor *self, int crouchsprite) FString normspritename = sprites[self->SpawnState->sprite].name; FString crouchspritename = sprites[crouchsprite].name; - int spritenorm = fileSystem.CheckNumForName(normspritename + "A1", FileSys::ns_sprites); + int spritenorm = fileSystem.CheckNumForName((normspritename + "A1").GetChars(), FileSys::ns_sprites); if (spritenorm == -1) { - spritenorm = fileSystem.CheckNumForName(normspritename + "A0", FileSys::ns_sprites); + spritenorm = fileSystem.CheckNumForName((normspritename + "A0").GetChars(), FileSys::ns_sprites); } - int spritecrouch = fileSystem.CheckNumForName(crouchspritename + "A1", FileSys::ns_sprites); + int spritecrouch = fileSystem.CheckNumForName((crouchspritename + "A1").GetChars(), FileSys::ns_sprites); if (spritecrouch == -1) { - spritecrouch = fileSystem.CheckNumForName(crouchspritename + "A0", FileSys::ns_sprites); + spritecrouch = fileSystem.CheckNumForName((crouchspritename + "A0").GetChars(), FileSys::ns_sprites); } if (spritenorm == -1 || spritecrouch == -1) @@ -1711,7 +1711,7 @@ void player_t::Serialize(FSerializer &arc) } if (skinname.IsNotEmpty()) { - userinfo.SkinChanged(skinname, CurrentPlayerClass); + userinfo.SkinChanged(skinname.GetChars(), CurrentPlayerClass); } } diff --git a/src/r_data/r_canvastexture.cpp b/src/r_data/r_canvastexture.cpp index c12d42e76..49e4e8ab2 100644 --- a/src/r_data/r_canvastexture.cpp +++ b/src/r_data/r_canvastexture.cpp @@ -98,7 +98,7 @@ void FCanvasTextureInfo::Add (AActor *viewpoint, FTextureID picnum, double fov) void SetCameraToTexture(AActor *viewpoint, const FString &texturename, double fov) { - FTextureID textureid = TexMan.CheckForTexture(texturename, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); + FTextureID textureid = TexMan.CheckForTexture(texturename.GetChars(), ETextureType::Wall, FTextureManager::TEXMAN_Overridable); if (textureid.isValid()) { // Only proceed if the texture actually has a canvas. diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index 86100a1cb..c2b34f005 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -614,7 +614,7 @@ DEFINE_ACTION_FUNCTION(_Translation, SetPlayerTranslation) if (cls != nullptr) { - PlayerSkin = R_FindSkin(Skins[PlayerSkin].Name, int(cls - &PlayerClasses[0])); + PlayerSkin = R_FindSkin(Skins[PlayerSkin].Name.GetChars(), int(cls - &PlayerClasses[0])); FRemapTable remap; R_GetPlayerTranslation(PlayerColor, GetColorSet(cls->Type, PlayerColorset), &Skins[PlayerSkin], &remap); diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 58b9336a1..63314f23e 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -335,7 +335,7 @@ void R_InitSpriteDefs () for (i = 0; i < smax; ++i) { auto tex = TexMan.GameByIndex(i); - if (tex->GetUseType() == ETextureType::Sprite && strlen(tex->GetName()) >= 6) + if (tex->GetUseType() == ETextureType::Sprite && strlen(tex->GetName().GetChars()) >= 6) { size_t bucket = TEX_DWNAME(tex) % smax; hashes[i].Next = hashes[bucket].Head; @@ -721,11 +721,11 @@ void R_InitSkins (void) { if (stricmp (key, "*pain") == 0) { // Replace all pain sounds in one go - aliasid = S_AddPlayerSound (Skins[i].Name, Skins[i].gender, + aliasid = S_AddPlayerSound (Skins[i].Name.GetChars(), Skins[i].gender, playersoundrefs[0], lump, true); for (int l = 3; l > 0; --l) { - S_AddPlayerSoundExisting (Skins[i].Name, Skins[i].gender, + S_AddPlayerSoundExisting (Skins[i].Name.GetChars(), Skins[i].gender, playersoundrefs[l], aliasid, true); } } @@ -734,7 +734,7 @@ void R_InitSkins (void) auto sndref = soundEngine->FindSoundNoHash (key); if (sndref.isvalid()) { - S_AddPlayerSound (Skins[i].Name, Skins[i].gender, sndref, lump, true); + S_AddPlayerSound (Skins[i].Name.GetChars(), Skins[i].gender, sndref, lump, true); } } } @@ -888,12 +888,12 @@ void R_InitSkins (void) { if (j == 0 || sndlumps[j] != sndlumps[j-1]) { - aliasid = S_AddPlayerSound (Skins[i].Name, Skins[i].gender, + aliasid = S_AddPlayerSound (Skins[i].Name.GetChars(), Skins[i].gender, playersoundrefs[j], sndlumps[j], true); } else { - S_AddPlayerSoundExisting (Skins[i].Name, Skins[i].gender, + S_AddPlayerSoundExisting (Skins[i].Name.GetChars(), Skins[i].gender, playersoundrefs[j], aliasid, true); } } From 6055ff029d5e87e84aaaf698bb430656e1e16588 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 7 Oct 2023 23:44:01 +0200 Subject: [PATCH 195/223] the remaining GetChars additions. The offending operator const char * no longer exists. --- src/common/audio/sound/s_reverbedit.cpp | 6 +++--- src/common/textures/texturemanager.cpp | 20 +++++++++--------- src/common/utility/s_playlist.cpp | 4 ++-- src/common/utility/zstring.h | 2 -- src/gamedata/teaminfo.cpp | 2 +- src/playsim/p_acs.cpp | 8 ++++---- src/scripting/decorate/thingdef_parse.cpp | 16 +++++++-------- src/scripting/decorate/thingdef_states.cpp | 8 ++++---- src/scripting/thingdef_properties.cpp | 12 +++++------ src/sound/s_advsound.cpp | 24 +++++++++++----------- src/sound/s_doomsound.cpp | 6 +++--- 11 files changed, 53 insertions(+), 55 deletions(-) diff --git a/src/common/audio/sound/s_reverbedit.cpp b/src/common/audio/sound/s_reverbedit.cpp index a8ce5ac0d..4c01da23a 100644 --- a/src/common/audio/sound/s_reverbedit.cpp +++ b/src/common/audio/sound/s_reverbedit.cpp @@ -227,7 +227,7 @@ void ExportEnvironments(const char *filename, uint32_t count, const ReverbContai { FString dest = M_GetDocumentsPath() + filename; - FileWriter *f = FileWriter::Open(dest); + FileWriter *f = FileWriter::Open(dest.GetChars()); if (f != nullptr) { @@ -509,13 +509,13 @@ CCMD(createenvironment) { if (S_FindEnvironment(reverbedit_name)) { - M_StartMessage(FStringf("An environment with the name '%s' already exists", *reverbedit_name), 1); + M_StartMessage(FStringf("An environment with the name '%s' already exists", *reverbedit_name).GetChars(), 1); return; } int id = (reverbedit_id1 << 8) + reverbedit_id2; if (S_FindEnvironment(id)) { - M_StartMessage(FStringf("An environment with the ID (%d, %d) already exists", *reverbedit_id1, *reverbedit_id2), 1); + M_StartMessage(FStringf("An environment with the ID (%d, %d) already exists", *reverbedit_id1, *reverbedit_id2).GetChars(), 1); return; } diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index b742ca787..570e01315 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -178,7 +178,7 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset auto tex = Textures[i].Texture; - if (stricmp (tex->GetName(), name) == 0 ) + if (tex->GetName().CompareNoCase(name) == 0 ) { // If we look for short names, we must ignore any long name texture. if ((flags & TEXMAN_ShortNameOnly) && tex->isFullNameTexture()) @@ -306,7 +306,7 @@ int FTextureManager::ListTextures (const char *name, TArray &list, b { auto tex = Textures[i].Texture; - if (stricmp (tex->GetName(), name) == 0) + if (tex->GetName().CompareNoCase(name) == 0) { auto texUseType = tex->GetUseType(); // NULL textures must be ignored. @@ -422,7 +422,7 @@ FTextureID FTextureManager::AddGameTexture (FGameTexture *texture, bool addtohas // Textures without name can't be looked for if (addtohash && texture->GetName().IsNotEmpty()) { - bucket = int(MakeKey (texture->GetName()) % HASH_SIZE); + bucket = int(MakeKey (texture->GetName().GetChars()) % HASH_SIZE); hash = HashFirst[bucket]; } else @@ -460,7 +460,7 @@ FTextureID FTextureManager::CreateTexture (int lumpnum, ETextureType usetype) auto fn = fileSystem.GetFileFullName(lumpnum); str = ExtractFileBase(fn); } - auto out = MakeGameTexture(CreateTextureFromLump(lumpnum, usetype == ETextureType::Flat), str, usetype); + auto out = MakeGameTexture(CreateTextureFromLump(lumpnum, usetype == ETextureType::Flat), str.GetChars(), usetype); if (out != NULL) { @@ -514,7 +514,7 @@ void FTextureManager::ReplaceTexture (FTextureID texid, FGameTexture *newtexture auto oldtexture = Textures[index].Texture; - newtexture->SetName(oldtexture->GetName()); + newtexture->SetName(oldtexture->GetName().GetChars()); newtexture->SetUseType(oldtexture->GetUseType()); Textures[index].Texture = newtexture; newtexture->SetID(oldtexture->GetID()); @@ -793,7 +793,7 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build if (lumpnum>=0) { - auto newtex = MakeGameTexture(CreateTextureFromLump(lumpnum), src, ETextureType::Override); + auto newtex = MakeGameTexture(CreateTextureFromLump(lumpnum), src.GetChars(), ETextureType::Override); if (newtex != NULL) { @@ -801,7 +801,7 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build newtex->SetWorldPanning(true); newtex->SetDisplaySize((float)width, (float)height); - FTextureID oldtex = TexMan.CheckForTexture(src, ETextureType::MiscPatch); + FTextureID oldtex = TexMan.CheckForTexture(src.GetChars(), ETextureType::MiscPatch); if (oldtex.isValid()) { ReplaceTexture(oldtex, newtex, true); @@ -1127,8 +1127,8 @@ void FTextureManager::AddLocalizedVariants() } if (tokens.Size() >= 2) { - FString base = ExtractFileBase(tokens[0]); - FTextureID origTex = CheckForTexture(base, ETextureType::MiscPatch); + FString base = ExtractFileBase(tokens[0].GetChars()); + FTextureID origTex = CheckForTexture(base.GetChars(), ETextureType::MiscPatch); if (origTex.isValid()) { FTextureID tex = CheckForTexture(entry.name, ETextureType::MiscPatch); @@ -1367,7 +1367,7 @@ FTextureID FTextureManager::GetFrontSkyLayer(FTextureID texid) // But do not link the new texture into the hash chain! auto itex = new FImageTexture(image); itex->SetNoRemap0(); - auto FrontSkyLayer = MakeGameTexture(itex, tex->GetName(), ETextureType::Wall); + auto FrontSkyLayer = MakeGameTexture(itex, tex->GetName().GetChars(), ETextureType::Wall); FrontSkyLayer->SetUseType(tex->GetUseType()); texid = TexMan.AddGameTexture(FrontSkyLayer, false); Textures[texidx].FrontSkyLayer = texid.GetIndex(); diff --git a/src/common/utility/s_playlist.cpp b/src/common/utility/s_playlist.cpp index d457d0137..694329b58 100644 --- a/src/common/utility/s_playlist.cpp +++ b/src/common/utility/s_playlist.cpp @@ -80,7 +80,7 @@ bool FPlayList::ChangeList (const char *path) // For a .PLS file, skip anything that doesn't start with File[0-9]+= if (pls) { - if (strncmp(song, "File", 4) != 0) + if (strncmp(song.GetChars(), "File", 4) != 0) { continue; } @@ -205,5 +205,5 @@ const char *FPlayList::GetSong (int position) const if ((unsigned)position >= Songs.Size()) return NULL; - return Songs[position]; + return Songs[position].GetChars(); } diff --git a/src/common/utility/zstring.h b/src/common/utility/zstring.h index 7777bbf61..b76113f00 100644 --- a/src/common/utility/zstring.h +++ b/src/common/utility/zstring.h @@ -163,8 +163,6 @@ public: explicit operator bool() = delete; // this is needed to render the operator const char * ineffective when used in boolean constructs. bool operator !() = delete; - operator const char *() const { return Chars; } - const char *GetChars() const { return Chars; } const char &operator[] (int index) const { return Chars[index]; } diff --git a/src/gamedata/teaminfo.cpp b/src/gamedata/teaminfo.cpp index 629d110b9..3a28da984 100644 --- a/src/gamedata/teaminfo.cpp +++ b/src/gamedata/teaminfo.cpp @@ -260,7 +260,7 @@ bool FTeam::IsValidTeam (unsigned int uiTeam) const char *FTeam::GetName () const { - return m_Name; + return m_Name.GetChars(); } //========================================================================== diff --git a/src/playsim/p_acs.cpp b/src/playsim/p_acs.cpp index 79dc64a0a..bc945a003 100644 --- a/src/playsim/p_acs.cpp +++ b/src/playsim/p_acs.cpp @@ -8784,13 +8784,13 @@ scriptwait: { default: // normal alpha = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 1.f; - msg = Create (activefont, work, x, y, hudwidth, hudheight, color, holdTime); + msg = Create (activefont, work.GetChars(), x, y, hudwidth, hudheight, color, holdTime); break; case 1: // fade out { float fadeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f; alpha = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 1.f; - msg = Create (activefont, work, x, y, hudwidth, hudheight, color, holdTime, fadeTime); + msg = Create (activefont, work.GetChars(), x, y, hudwidth, hudheight, color, holdTime, fadeTime); } break; case 2: // type on, then fade out @@ -8798,7 +8798,7 @@ scriptwait: float typeTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.05f; float fadeTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f; alpha = (optstart < sp-2) ? ACSToFloat(Stack[optstart+2]) : 1.f; - msg = Create (activefont, work, x, y, hudwidth, hudheight, color, typeTime, holdTime, fadeTime); + msg = Create (activefont, work.GetChars(), x, y, hudwidth, hudheight, color, typeTime, holdTime, fadeTime); } break; case 3: // fade in, then fade out @@ -8806,7 +8806,7 @@ scriptwait: float inTime = (optstart < sp) ? ACSToFloat(Stack[optstart]) : 0.5f; float outTime = (optstart < sp-1) ? ACSToFloat(Stack[optstart+1]) : 0.5f; alpha = (optstart < sp-2) ? ACSToFloat(Stack[optstart + 2]) : 1.f; - msg = Create (activefont, work, x, y, hudwidth, hudheight, color, holdTime, inTime, outTime); + msg = Create (activefont, work.GetChars(), x, y, hudwidth, hudheight, color, holdTime, inTime, outTime); } break; } diff --git a/src/scripting/decorate/thingdef_parse.cpp b/src/scripting/decorate/thingdef_parse.cpp index eb1cd5ee3..a1cc7702e 100644 --- a/src/scripting/decorate/thingdef_parse.cpp +++ b/src/scripting/decorate/thingdef_parse.cpp @@ -458,7 +458,7 @@ static void ParseActorFlag (FScanner &sc, Baggage &bag, int mod) sc.MustGetString (); part2 = sc.String; } - HandleActorFlag(sc, bag, part1, part2, mod); + HandleActorFlag(sc, bag, part1.GetChars(), part2, mod); } //========================================================================== @@ -722,12 +722,12 @@ static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defau case 'S': sc.MustGetString(); - conv.s = strings[strings.Reserve(1)] = sc.String; + conv.s = (strings[strings.Reserve(1)] = sc.String).GetChars(); break; case 'T': sc.MustGetString(); - conv.s = strings[strings.Reserve(1)] = strbin1(sc.String); + conv.s = (strings[strings.Reserve(1)] = strbin1(sc.String)).GetChars(); break; case 'C': @@ -747,7 +747,7 @@ static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defau else { sc.MustGetString (); - conv.s = strings[strings.Reserve(1)] = sc.String; + conv.s = (strings[strings.Reserve(1)] = sc.String).GetChars(); pref.i = 1; } break; @@ -775,7 +775,7 @@ static bool ParsePropertyParams(FScanner &sc, FPropertyInfo *prop, AActor *defau do { sc.MustGetString (); - conv.s = strings[strings.Reserve(1)] = sc.String; + conv.s = (strings[strings.Reserve(1)] = sc.String).GetChars(); params.Push(conv); params[0].i++; } @@ -961,7 +961,7 @@ static void ParseActorProperty(FScanner &sc, Baggage &bag) sc.UnGet (); } - FPropertyInfo *prop = FindProperty(propname); + FPropertyInfo *prop = FindProperty(propname.GetChars()); if (prop != NULL) { @@ -976,9 +976,9 @@ static void ParseActorProperty(FScanner &sc, Baggage &bag) FScriptPosition::ErrorCounter++; } } - else if (MatchString(propname, statenames) != -1) + else if (MatchString(propname.GetChars(), statenames) != -1) { - bag.statedef.SetStateLabel(propname, CheckState (sc, bag.Info)); + bag.statedef.SetStateLabel(propname.GetChars(), CheckState (sc, bag.Info)); } else { diff --git a/src/scripting/decorate/thingdef_states.cpp b/src/scripting/decorate/thingdef_states.cpp index 636d07d3c..36a209d69 100644 --- a/src/scripting/decorate/thingdef_states.cpp +++ b/src/scripting/decorate/thingdef_states.cpp @@ -170,7 +170,7 @@ do_goto: statestring += '+'; statestring += sc.String; } - if (!bag.statedef.SetGotoLabel(statestring)) + if (!bag.statedef.SetGotoLabel(statestring.GetChars())) { sc.ScriptError("GOTO before first state"); } @@ -207,7 +207,7 @@ do_stop: { do { - bag.statedef.AddStateLabel(statestring); + bag.statedef.AddStateLabel(statestring.GetChars()); statestring = ParseStateString(sc); if (!statestring.CompareNoCase("GOTO")) { @@ -230,7 +230,7 @@ do_stop: } scp = sc; - state.sprite = GetSpriteIndex(statestring); + state.sprite = GetSpriteIndex(statestring.GetChars()); state.Misc1 = state.Misc2 = 0; sc.MustGetString(); statestring = sc.String; @@ -334,7 +334,7 @@ endofstate: auto funcsym = CreateAnonymousFunction(actor->VMType, nullptr, state.UseFlags); state.ActionFunc = FunctionBuildList.AddFunction(bag.Namespace, bag.Version, funcsym, ScriptCode, FStringf("%s.StateFunction.%d", actor->TypeName.GetChars(), bag.statedef.GetStateCount()), true, bag.statedef.GetStateCount(), int(statestring.Len()), sc.LumpNum); } - int count = bag.statedef.AddStates(&state, statestring, scp); + int count = bag.statedef.AddStates(&state, statestring.GetChars(), scp); if (count < 0) { sc.ScriptError("Invalid frame character string '%s'", statestring.GetChars()); diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 675fef34a..11a3313bc 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -152,18 +152,18 @@ bool ModActorFlag(AActor *actor, const FString &flagname, bool set, bool printer if (actor != NULL) { auto Level = actor->Level; - const char *dot = strchr(flagname, '.'); + const char *dot = strchr(flagname.GetChars(), '.'); FFlagDef *fd; PClassActor *cls = actor->GetClass(); if (dot != NULL) { - FString part1(flagname.GetChars(), dot - flagname); - fd = FindFlag(cls, part1, dot + 1); + FString part1(flagname.GetChars(), dot - flagname.GetChars()); + fd = FindFlag(cls, part1.GetChars(), dot + 1); } else { - fd = FindFlag(cls, flagname, NULL); + fd = FindFlag(cls, flagname.GetChars(), NULL); } if (fd != NULL) @@ -245,7 +245,7 @@ INTBOOL CheckActorFlag(AActor *owner, const char *flagname, bool printerror) if (dot != NULL) { FString part1(flagname, dot-flagname); - fd = FindFlag (cls, part1, dot+1); + fd = FindFlag (cls, part1.GetChars(), dot+1); } else { @@ -1377,7 +1377,7 @@ DEFINE_CLASS_PROPERTY_PREFIX(powerup, type, S, PowerupGiver) { FString st; st.Format("%s%s", strnicmp(str, "power", 5) ? "Power" : "", str); - cls = FindClassTentative(st, pow); + cls = FindClassTentative(st.GetChars(), pow); } else { diff --git a/src/sound/s_advsound.cpp b/src/sound/s_advsound.cpp index 884ae7114..c354de1aa 100644 --- a/src/sound/s_advsound.cpp +++ b/src/sound/s_advsound.cpp @@ -497,7 +497,7 @@ FSoundID S_AddPlayerSound (const char *pclass, int gender, FSoundID refid, int l fakename += '"'; fakename += sfx->name.GetChars(); - id = soundEngine->AddSoundLump (fakename, lumpnum, CurrentPitchMask); + id = soundEngine->AddSoundLump (fakename.GetChars(), lumpnum, CurrentPitchMask); int classnum = S_AddPlayerClass (pclass); int soundlist = S_AddPlayerGender (classnum, gender); @@ -791,8 +791,8 @@ static void S_AddSNDINFO (int lump) int gender; FSoundID refid, sfxnum; - S_ParsePlayerSoundCommon (sc, pclass, gender, refid); - sfxnum = S_AddPlayerSound (pclass, gender, refid, sc.String); + S_ParsePlayerSoundCommon(sc, pclass, gender, refid); + sfxnum = S_AddPlayerSound(pclass.GetChars(), gender, refid, sc.String); if (0 == stricmp(sc.String, "dsempty")) { soundEngine->GetWritableSfx(sfxnum)->UserData[0] |= SND_PlayerSilent; @@ -813,7 +813,7 @@ static void S_AddSNDINFO (int lump) { sc.ScriptError("%s is not a player sound", sc.String); } - S_DupPlayerSound (pclass, gender, refid, targid); + S_DupPlayerSound (pclass.GetChars(), gender, refid, targid); } break; @@ -826,7 +826,7 @@ static void S_AddSNDINFO (int lump) S_ParsePlayerSoundCommon (sc, pclass, gender, refid); sfxfrom = S_AddSound (sc.String, -1, &sc); - aliasto = S_LookupPlayerSound (pclass, gender, refid); + aliasto = S_LookupPlayerSound (pclass.GetChars(), gender, refid); auto sfx = soundEngine->GetWritableSfx(sfxfrom); sfx->link = aliasto; sfx->UserData[0] |= SND_PlayerCompat; @@ -841,7 +841,7 @@ static void S_AddSNDINFO (int lump) S_ParsePlayerSoundCommon (sc, pclass, gender, refid); soundnum = soundEngine->FindSoundTentative (sc.String); - S_AddPlayerSoundExisting (pclass, gender, refid, soundnum); + S_AddPlayerSoundExisting (pclass.GetChars(), gender, refid, soundnum); } break; @@ -1124,7 +1124,7 @@ static void S_AddSNDINFO (int lump) } sc.MustGetString (); - S_AddSound (name, sc.String, &sc); + S_AddSound (name.GetChars(), sc.String, &sc); } } } @@ -1226,7 +1226,7 @@ static int S_FindPlayerClass (const char *name) for (i = 0; i < PlayerClassLookups.Size(); ++i) { - if (stricmp (name, PlayerClassLookups[i].Name) == 0) + if (stricmp (name, PlayerClassLookups[i].Name.GetChars()) == 0) { return (int)i; } @@ -1240,7 +1240,7 @@ static int S_FindPlayerClass (const char *name) while (min <= max) { int mid = (min + max) / 2; - int lexx = stricmp (PlayerClassLookups[mid].Name, name); + int lexx = stricmp (PlayerClassLookups[mid].Name.GetChars(), name); if (lexx == 0) { return mid; @@ -1295,13 +1295,13 @@ void S_ShrinkPlayerSoundLists () qsort (&PlayerClassLookups[0], PlayerClassLookups.Size(), sizeof(FPlayerClassLookup), SortPlayerClasses); PlayerClassesIsSorted = true; - DefPlayerClass = S_FindPlayerClass (DefPlayerClassName); + DefPlayerClass = S_FindPlayerClass (DefPlayerClassName.GetChars()); } static int SortPlayerClasses (const void *a, const void *b) { - return stricmp (((const FPlayerClassLookup *)a)->Name, - ((const FPlayerClassLookup *)b)->Name); + return stricmp (((const FPlayerClassLookup *)a)->Name.GetChars(), + ((const FPlayerClassLookup *)b)->Name.GetChars()); } //========================================================================== diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index c46e1dfa9..9000f958b 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -158,7 +158,7 @@ static FString LookupMusic(const char* musicname, int& order) if (mus_string != nullptr) { DEH_Music << "D_" << mus_string; - musicname = DEH_Music; + musicname = DEH_Music.GetChars(); } } @@ -314,7 +314,7 @@ void S_Start() if (LocalSndInfo.IsNotEmpty()) { // Now parse the local SNDINFO - int j = fileSystem.CheckNumForFullName(LocalSndInfo, true); + int j = fileSystem.CheckNumForFullName(LocalSndInfo.GetChars(), true); if (j >= 0) S_AddLocalSndInfo(j); } @@ -328,7 +328,7 @@ void S_Start() if (parse_ss) { - S_ParseSndSeq(LocalSndSeq.IsNotEmpty() ? fileSystem.CheckNumForFullName(LocalSndSeq, true) : -1); + S_ParseSndSeq(LocalSndSeq.IsNotEmpty() ? fileSystem.CheckNumForFullName(LocalSndSeq.GetChars(), true) : -1); } LastLocalSndInfo = LocalSndInfo; From c69941e49d74747f593ac8a1095b4834d842f550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 7 Oct 2023 19:34:06 -0300 Subject: [PATCH 196/223] fix GetChars in linux/macOS --- src/common/platform/posix/cocoa/i_main.mm | 2 +- .../platform/posix/osx/i_specialpaths.mm | 12 +++++----- .../platform/posix/osx/iwadpicker_cocoa.mm | 10 ++++---- src/common/utility/cmdlib.cpp | 2 +- src/gameconfigfile.cpp | 24 +++++++++---------- src/posix/i_steam.cpp | 4 ++-- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/common/platform/posix/cocoa/i_main.mm b/src/common/platform/posix/cocoa/i_main.mm index 50353ba3d..10f3a60ab 100644 --- a/src/common/platform/posix/cocoa/i_main.mm +++ b/src/common/platform/posix/cocoa/i_main.mm @@ -348,7 +348,7 @@ extern bool AppActive; for (size_t i = 0, count = s_argv.Size(); i < count; ++i) { - if (0 == strcmp(s_argv[i], charFileName)) + if (0 == strcmp(s_argv[i].GetChars(), charFileName)) { return FALSE; } diff --git a/src/common/platform/posix/osx/i_specialpaths.mm b/src/common/platform/posix/osx/i_specialpaths.mm index d51bd4ca5..7d55157ef 100644 --- a/src/common/platform/posix/osx/i_specialpaths.mm +++ b/src/common/platform/posix/osx/i_specialpaths.mm @@ -105,7 +105,7 @@ FString M_GetAppDataPath(bool create) } path += "/" GAMENAMELOWERCASE; - if (create) CreatePath(path); + if (create) CreatePath(path.GetChars()); return path; } @@ -127,7 +127,7 @@ FString M_GetCachePath(bool create) } path += "/zdoom/cache"; - if (create) CreatePath(path); + if (create) CreatePath(path.GetChars()); return path; } @@ -169,9 +169,9 @@ FString M_GetConfigPath(bool for_reading) { // There seems to be no way to get Preferences path via NSFileManager path += "/Preferences/"; - CreatePath(path); + CreatePath(path.GetChars()); - if (!DirExists(path)) + if (!DirExists(path.GetChars())) { path = FString(); } @@ -200,7 +200,7 @@ FString M_GetScreenshotsPath() { path += "/" GAME_DIR "/Screenshots/"; } - CreatePath(path); + CreatePath(path.GetChars()); return path; } @@ -241,7 +241,7 @@ FString M_GetDocumentsPath() path += "/" GAME_DIR "/"; } - CreatePath(path); + CreatePath(path.GetChars()); return path; } diff --git a/src/common/platform/posix/osx/iwadpicker_cocoa.mm b/src/common/platform/posix/osx/iwadpicker_cocoa.mm index e72aa5aad..f680829bf 100644 --- a/src/common/platform/posix/osx/iwadpicker_cocoa.mm +++ b/src/common/platform/posix/osx/iwadpicker_cocoa.mm @@ -86,13 +86,13 @@ static const char* const tableHeaders[NUM_COLUMNS] = { "IWAD", "Game" }; for(int i = 0;i < numwads;i++) { NSMutableDictionary *record = [[NSMutableDictionary alloc] initWithCapacity:NUM_COLUMNS]; - const char* filename = strrchr(wads[i].Path, '/'); + const char* filename = strrchr(wads[i].Path.GetChars(), '/'); if(filename == NULL) - filename = wads[i].Path; + filename = wads[i].Path.GetChars(); else filename++; [record setObject:[NSString stringWithUTF8String:filename] forKey:[NSString stringWithUTF8String:tableHeaders[COLUMN_IWAD]]]; - [record setObject:[NSString stringWithUTF8String:wads[i].Name] forKey:[NSString stringWithUTF8String:tableHeaders[COLUMN_GAME]]]; + [record setObject:[NSString stringWithUTF8String:wads[i].Name.GetChars()] forKey:[NSString stringWithUTF8String:tableHeaders[COLUMN_GAME]]]; [data addObject:record]; [record release]; } @@ -397,9 +397,9 @@ static void RestartWithParameters(const WadStuff& wad, NSString* parameters) [arguments addObject:GetArchitectureString()]; [arguments addObject:executablePath]; [arguments addObject:@"-iwad"]; - [arguments addObject:[NSString stringWithUTF8String:wad.Path]]; + [arguments addObject:[NSString stringWithUTF8String:wad.Path.GetChars()]]; [arguments addObject:@"+defaultiwad"]; - [arguments addObject:[NSString stringWithUTF8String:wad.Name]]; + [arguments addObject:[NSString stringWithUTF8String:wad.Name.GetChars()]]; [arguments addObject:cvarArgument]; for (int i = 1, count = Args->NumArgs(); i < count; ++i) diff --git a/src/common/utility/cmdlib.cpp b/src/common/utility/cmdlib.cpp index 88a37f362..b8c140453 100644 --- a/src/common/utility/cmdlib.cpp +++ b/src/common/utility/cmdlib.cpp @@ -905,7 +905,7 @@ FString NicePath(const char *path) slash = path + strlen(path); } FString who(path, slash - path); - pwstruct = getpwnam(who); + pwstruct = getpwnam(who.GetChars()); } if (pwstruct == NULL) { diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 3e4f96c00..a0f27899e 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -108,10 +108,10 @@ FGameConfigFile::FGameConfigFile () SetValueForKey ("Path", ".", true); SetValueForKey ("Path", "$DOOMWADDIR", true); #ifdef __APPLE__ - SetValueForKey ("Path", user_docs, true); - SetValueForKey ("Path", user_app_support, true); + SetValueForKey ("Path", user_docs.GetChars(), true); + SetValueForKey ("Path", user_app_support.GetChars(), true); SetValueForKey ("Path", "$PROGDIR", true); - SetValueForKey ("Path", local_app_support, true); + SetValueForKey ("Path", local_app_support.GetChars(), true); #elif !defined(__unix__) SetValueForKey ("Path", "$HOME", true); SetValueForKey ("Path", "$PROGDIR", true); @@ -133,10 +133,10 @@ FGameConfigFile::FGameConfigFile () { SetSection ("FileSearch.Directories", true); #ifdef __APPLE__ - SetValueForKey ("Path", user_docs, true); - SetValueForKey ("Path", user_app_support, true); + SetValueForKey ("Path", user_docs.GetChars(), true); + SetValueForKey ("Path", user_app_support.GetChars(), true); SetValueForKey ("Path", "$PROGDIR", true); - SetValueForKey ("Path", local_app_support, true); + SetValueForKey ("Path", local_app_support.GetChars(), true); #elif !defined(__unix__) SetValueForKey ("Path", "$PROGDIR", true); #else @@ -156,14 +156,14 @@ FGameConfigFile::FGameConfigFile () { SetSection("SoundfontSearch.Directories", true); #ifdef __APPLE__ - SetValueForKey("Path", user_docs + "/soundfonts", true); - SetValueForKey("Path", user_docs + "/fm_banks", true); - SetValueForKey("Path", user_app_support + "/soundfonts", true); - SetValueForKey("Path", user_app_support + "/fm_banks", true); + SetValueForKey("Path", (user_docs + "/soundfonts").GetChars(), true); + SetValueForKey("Path", (user_docs + "/fm_banks").GetChars(), true); + SetValueForKey("Path", (user_app_support + "/soundfonts").GetChars(), true); + SetValueForKey("Path", (user_app_support + "/fm_banks").GetChars(), true); SetValueForKey("Path", "$PROGDIR/soundfonts", true); SetValueForKey("Path", "$PROGDIR/fm_banks", true); - SetValueForKey("Path", local_app_support + "/soundfonts", true); - SetValueForKey("Path", local_app_support + "/fm_banks", true); + SetValueForKey("Path", (local_app_support + "/soundfonts").GetChars(), true); + SetValueForKey("Path", (local_app_support + "/fm_banks").GetChars(), true); #elif !defined(__unix__) SetValueForKey("Path", "$PROGDIR/soundfonts", true); SetValueForKey("Path", "$PROGDIR/fm_banks", true); diff --git a/src/posix/i_steam.cpp b/src/posix/i_steam.cpp index 82c2c9d98..913ae3989 100644 --- a/src/posix/i_steam.cpp +++ b/src/posix/i_steam.cpp @@ -202,7 +202,7 @@ TArray I_GetSteamPath() try { - SteamInstallFolders = ParseSteamRegistry(regPath); + SteamInstallFolders = ParseSteamRegistry(regPath.GetChars()); } catch(class CRecoverableError &error) { @@ -221,7 +221,7 @@ TArray I_GetSteamPath() { struct stat st; FString candidate(SteamInstallFolders[i] + "/" + AppInfo[app].BasePath); - if(DirExists(candidate)) + if(DirExists(candidate.GetChars())) result.Push(candidate); } } From f4fb583c6c959accdd36279197357a4fc3173993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 7 Oct 2023 19:46:27 -0300 Subject: [PATCH 197/223] more GetChars fixes in linux/macOS --- src/common/platform/posix/sdl/i_system.cpp | 16 ++++++++-------- src/common/platform/posix/sdl/sdlglvideo.cpp | 4 ++-- .../platform/posix/unix/i_specialpaths.cpp | 16 ++++++++-------- src/ct_chat.cpp | 2 +- src/d_main.cpp | 2 +- src/posix/i_steam.cpp | 2 +- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/common/platform/posix/sdl/i_system.cpp b/src/common/platform/posix/sdl/i_system.cpp index ab0c6bd7d..183d11fc3 100644 --- a/src/common/platform/posix/sdl/i_system.cpp +++ b/src/common/platform/posix/sdl/i_system.cpp @@ -118,7 +118,7 @@ void Unix_I_FatalError(const char* errortext) FString cmd; cmd << "kdialog --title \"" GAMENAME " " << GetVersionString() << "\" --msgbox \"" << errortext << "\""; - popen(cmd, "r"); + popen(cmd.GetChars(), "r"); } #ifndef NO_GTK else if (I_GtkAvailable()) @@ -131,7 +131,7 @@ void Unix_I_FatalError(const char* errortext) FString title; title << GAMENAME " " << GetVersionString(); - if (SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, errortext, NULL) < 0) + if (SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title.GetChars(), errortext, NULL) < 0) { printf("\n%s\n", errortext); } @@ -316,9 +316,9 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& for(i = 0; i < numwads; ++i) { - const char *filepart = strrchr(wads[i].Path, '/'); + const char *filepart = strrchr(wads[i].Path.GetChars(), '/'); if(filepart == NULL) - filepart = wads[i].Path; + filepart = wads[i].Path.GetChars(); else filepart++; // Menu entries are specified in "tag" "item" pairs, where when a @@ -329,9 +329,9 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& if(defaultiwad >= 0 && defaultiwad < numwads) { - const char *filepart = strrchr(wads[defaultiwad].Path, '/'); + const char *filepart = strrchr(wads[defaultiwad].Path.GetChars(), '/'); if(filepart == NULL) - filepart = wads[defaultiwad].Path; + filepart = wads[defaultiwad].Path.GetChars(); else filepart++; cmd.AppendFormat(" --default \"%s (%s)\"", wads[defaultiwad].Name.GetChars(), filepart); @@ -377,9 +377,9 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& printf ("Please select a game wad (or 0 to exit):\n"); for (i = 0; i < numwads; ++i) { - const char *filepart = strrchr (wads[i].Path, '/'); + const char *filepart = strrchr (wads[i].Path.GetChars(), '/'); if (filepart == NULL) - filepart = wads[i].Path; + filepart = wads[i].Path.GetChars(); else filepart++; printf ("%d. %s (%s)\n", i+1, wads[i].Name.GetChars(), filepart); diff --git a/src/common/platform/posix/sdl/sdlglvideo.cpp b/src/common/platform/posix/sdl/sdlglvideo.cpp index 86a31c0c3..edea37aa3 100644 --- a/src/common/platform/posix/sdl/sdlglvideo.cpp +++ b/src/common/platform/posix/sdl/sdlglvideo.cpp @@ -139,7 +139,7 @@ namespace Priv caption.Format(GAMENAME " %s (%s)", GetVersionString(), GetGitTime()); const uint32_t windowFlags = (win_maximized ? SDL_WINDOW_MAXIMIZED : 0) | SDL_WINDOW_RESIZABLE | extraFlags; - Priv::window = SDL_CreateWindow(caption, + Priv::window = SDL_CreateWindow(caption.GetChars(), (win_x <= 0) ? SDL_WINDOWPOS_CENTERED_DISPLAY(vid_adapter) : win_x, (win_y <= 0) ? SDL_WINDOWPOS_CENTERED_DISPLAY(vid_adapter) : win_y, win_w, win_h, windowFlags); @@ -585,7 +585,7 @@ void I_SetWindowTitle(const char* caption) { FString default_caption; default_caption.Format(GAMENAME " %s (%s)", GetVersionString(), GetGitTime()); - SDL_SetWindowTitle(Priv::window, default_caption); + SDL_SetWindowTitle(Priv::window, default_caption.GetChars()); } } diff --git a/src/common/platform/posix/unix/i_specialpaths.cpp b/src/common/platform/posix/unix/i_specialpaths.cpp index f844f0dd0..81cf2ae66 100644 --- a/src/common/platform/posix/unix/i_specialpaths.cpp +++ b/src/common/platform/posix/unix/i_specialpaths.cpp @@ -50,15 +50,15 @@ FString GetUserFile (const char *file) path = NicePath("$HOME/" GAME_DIR "/"); - if (stat (path, &info) == -1) + if (stat (path.GetChars(), &info) == -1) { struct stat extrainfo; // Sanity check for $HOME/.config FString configPath = NicePath("$HOME/.config/"); - if (stat (configPath, &extrainfo) == -1) + if (stat (configPath.GetChars(), &extrainfo) == -1) { - if (mkdir (configPath, S_IRUSR | S_IWUSR | S_IXUSR) == -1) + if (mkdir (configPath.GetChars(), S_IRUSR | S_IWUSR | S_IXUSR) == -1) { I_FatalError ("Failed to create $HOME/.config directory:\n%s", strerror(errno)); } @@ -72,9 +72,9 @@ FString GetUserFile (const char *file) // Transfer the old zdoom directory to the new location bool moved = false; FString oldpath = NicePath("$HOME/." GAMENAMELOWERCASE "/"); - if (stat (oldpath, &extrainfo) != -1) + if (stat (oldpath.GetChars(), &extrainfo) != -1) { - if (rename(oldpath, path) == -1) + if (rename(oldpath.GetChars(), path) == -1) { I_Error ("Failed to move old " GAMENAMELOWERCASE " directory (%s) to new location (%s).", oldpath.GetChars(), path.GetChars()); @@ -115,7 +115,7 @@ FString M_GetAppDataPath(bool create) FString path = NicePath("$HOME/.config/" GAMENAMELOWERCASE); if (create) { - CreatePath(path); + CreatePath(path.GetChars()); } return path; } @@ -135,7 +135,7 @@ FString M_GetCachePath(bool create) FString path = NicePath("$HOME/.config/zdoom/cache"); if (create) { - CreatePath(path); + CreatePath(path.GetChars()); } return path; } @@ -231,7 +231,7 @@ FString M_GetDemoPath() FString M_GetNormalizedPath(const char* path) { char *actualpath; - actualpath = realpath(path, NULL); + actualpath = realpath(path.GetChars(), NULL); if (!actualpath) // error ? return nullptr; FString fullpath = actualpath; diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index acad5b35a..ad4c99484 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -193,7 +193,7 @@ bool CT_Responder (event_t *ev) #ifdef __unix__ else if (ev->subtype == EV_GUI_MButtonDown) { - CT_PasteChat(I_GetFromClipboard(true)); + CT_PasteChat(I_GetFromClipboard(true).GetChars()); } #endif } diff --git a/src/d_main.cpp b/src/d_main.cpp index 70c938ebf..78421e707 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2041,7 +2041,7 @@ static void AddAutoloadFiles(const char *autoname, std::vector& all #ifdef __unix__ file = NicePath("$HOME/" GAME_DIR "/skins"); - D_AddDirectory (allwads, file, "*.wad", GameConfig); + D_AddDirectory (allwads, file.GetChars(), "*.wad", GameConfig); #endif // Add common (global) wads diff --git a/src/posix/i_steam.cpp b/src/posix/i_steam.cpp index 913ae3989..046adca49 100644 --- a/src/posix/i_steam.cpp +++ b/src/posix/i_steam.cpp @@ -179,7 +179,7 @@ TArray I_GetSteamPath() FString regPath = appSupportPath + "/Steam/config/config.vdf"; try { - SteamInstallFolders = ParseSteamRegistry(regPath); + SteamInstallFolders = ParseSteamRegistry(regPath.GetChars()); } catch(class CRecoverableError &error) { From f0be58e8621b094af7ee4e4dacbb4d000bf33acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 7 Oct 2023 19:54:21 -0300 Subject: [PATCH 198/223] hopefully the last few GetChars fixes for linux --- src/common/platform/posix/sdl/i_system.cpp | 2 +- src/common/platform/posix/unix/i_specialpaths.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/platform/posix/sdl/i_system.cpp b/src/common/platform/posix/sdl/i_system.cpp index 183d11fc3..58a6a2f37 100644 --- a/src/common/platform/posix/sdl/i_system.cpp +++ b/src/common/platform/posix/sdl/i_system.cpp @@ -337,7 +337,7 @@ int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad, int& cmd.AppendFormat(" --default \"%s (%s)\"", wads[defaultiwad].Name.GetChars(), filepart); } - FILE *f = popen(cmd, "r"); + FILE *f = popen(cmd.GetChars(), "r"); if(f != NULL) { char gotstr[16]; diff --git a/src/common/platform/posix/unix/i_specialpaths.cpp b/src/common/platform/posix/unix/i_specialpaths.cpp index 81cf2ae66..112e92ee7 100644 --- a/src/common/platform/posix/unix/i_specialpaths.cpp +++ b/src/common/platform/posix/unix/i_specialpaths.cpp @@ -74,7 +74,7 @@ FString GetUserFile (const char *file) FString oldpath = NicePath("$HOME/." GAMENAMELOWERCASE "/"); if (stat (oldpath.GetChars(), &extrainfo) != -1) { - if (rename(oldpath.GetChars(), path) == -1) + if (rename(oldpath.GetChars(), path.GetChars()) == -1) { I_Error ("Failed to move old " GAMENAMELOWERCASE " directory (%s) to new location (%s).", oldpath.GetChars(), path.GetChars()); @@ -83,7 +83,7 @@ FString GetUserFile (const char *file) moved = true; } - if (!moved && mkdir (path, S_IRUSR | S_IWUSR | S_IXUSR) == -1) + if (!moved && mkdir (path.GetChars(), S_IRUSR | S_IWUSR | S_IXUSR) == -1) { I_FatalError ("Failed to create %s directory:\n%s", path.GetChars(), strerror (errno)); @@ -231,7 +231,7 @@ FString M_GetDemoPath() FString M_GetNormalizedPath(const char* path) { char *actualpath; - actualpath = realpath(path.GetChars(), NULL); + actualpath = realpath(path, NULL); if (!actualpath) // error ? return nullptr; FString fullpath = actualpath; From 04c167f18197eaa8c517cb19a24e5be4ebd4b644 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 7 Oct 2023 20:05:01 -0300 Subject: [PATCH 199/223] final final GetChars fix on linux --- src/common/platform/posix/unix/gtk_dialogs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/platform/posix/unix/gtk_dialogs.cpp b/src/common/platform/posix/unix/gtk_dialogs.cpp index 28da8c11b..01fb5ee2c 100644 --- a/src/common/platform/posix/unix/gtk_dialogs.cpp +++ b/src/common/platform/posix/unix/gtk_dialogs.cpp @@ -292,9 +292,9 @@ public: store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT); for (int i = 0; i < numwads; ++i) { - const char *filepart = strrchr (wads[i].Path, '/'); + const char *filepart = strrchr (wads[i].Path.GetChars(), '/'); if (filepart == NULL) - filepart = wads[i].Path; + filepart = wads[i].Path.GetChars(); else filepart++; gtk_list_store_append (store, &iter); From bfe589fecd1998c66644bef23af5965a551079cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 7 Oct 2023 20:31:50 -0300 Subject: [PATCH 200/223] try to fix gcc thinking the vectors are uninitialized --- src/playsim/actor.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 5a58dfb44..1bef8815a 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -960,14 +960,14 @@ public: double Distance2DSquared(AActor *other, bool absolute = false) { - DVector2 otherpos = absolute ? other->Pos().XY() : other->PosRelative(this).XY(); - return (Pos().XY() - otherpos).LengthSquared(); + DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return (Pos().XY() - otherpos.XY()).LengthSquared(); } double Distance2D(AActor *other, bool absolute = false) const { - DVector2 otherpos = absolute ? other->Pos().XY() : other->PosRelative(this).XY(); - return (Pos().XY() - otherpos).Length(); + DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return (Pos().XY() - otherpos.XY()).Length(); } double Distance2D(double x, double y) const @@ -997,14 +997,14 @@ public: DAngle AngleTo(AActor *other, bool absolute = false) { - DVector2 otherpos = absolute ? other->Pos().XY() : other->PosRelative(this).XY(); - return VecToAngle(otherpos - Pos().XY()); + DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return VecToAngle(otherpos.XY() - Pos().XY()); } DAngle AngleTo(AActor *other, double oxofs, double oyofs, bool absolute = false) const { - DVector2 otherpos = absolute ? other->Pos().XY() : other->PosRelative(this).XY(); - return VecToAngle(otherpos - Pos() + DVector2(oxofs, oyofs)); + DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this); + return VecToAngle(otherpos.XY() - Pos().XY() + DVector2(oxofs, oyofs)); } DVector2 Vec2To(AActor *other) const From 448ca88bfd17e33380152f116ad2745349085641 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 8 Oct 2023 08:11:56 +0200 Subject: [PATCH 201/223] fixed some signed-ness issues. --- src/common/filesystem/source/files_decompress.cpp | 3 +-- src/common/utility/zstring.h | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/common/filesystem/source/files_decompress.cpp b/src/common/filesystem/source/files_decompress.cpp index 6b32bf660..c5552018f 100644 --- a/src/common/filesystem/source/files_decompress.cpp +++ b/src/common/filesystem/source/files_decompress.cpp @@ -540,7 +540,6 @@ public: } uint8_t header[12]; - int err; File = file; Size = uncompressed_size; @@ -553,7 +552,7 @@ public: return false; } - File->Seek(-sizeof(header), FileReader::SeekCur); + File->Seek(-(ptrdiff_t)sizeof(header), FileReader::SeekCur); FillBuffer(); diff --git a/src/common/utility/zstring.h b/src/common/utility/zstring.h index b76113f00..dfbe47706 100644 --- a/src/common/utility/zstring.h +++ b/src/common/utility/zstring.h @@ -324,13 +324,13 @@ public: int Compare (const FString &other) const { return strcmp (Chars, other.Chars); } int Compare (const char *other) const { return strcmp (Chars, other); } - int Compare(const FString &other, int len) const { return strncmp(Chars, other.Chars, len); } - int Compare(const char *other, int len) const { return strncmp(Chars, other, len); } + int Compare(const FString &other, size_t len) const { return strncmp(Chars, other.Chars, len); } + int Compare(const char *other, size_t len) const { return strncmp(Chars, other, len); } int CompareNoCase (const FString &other) const { return stricmp (Chars, other.Chars); } int CompareNoCase (const char *other) const { return stricmp (Chars, other); } - int CompareNoCase(const FString &other, int len) const { return strnicmp(Chars, other.Chars, len); } - int CompareNoCase(const char *other, int len) const { return strnicmp(Chars, other, len); } + int CompareNoCase(const FString &other, size_t len) const { return strnicmp(Chars, other.Chars, len); } + int CompareNoCase(const char *other, size_t len) const { return strnicmp(Chars, other, len); } enum EmptyTokenType { From 56929833f03e01a2c4a5426f1dc9b4e54677e2f1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 8 Oct 2023 09:27:46 +0200 Subject: [PATCH 202/223] fixed two bad validations of FName's. --- src/console/c_cmds.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/console/c_cmds.cpp b/src/console/c_cmds.cpp index af88ce41e..0a54fde26 100644 --- a/src/console/c_cmds.cpp +++ b/src/console/c_cmds.cpp @@ -1326,13 +1326,13 @@ CCMD (mapinfo) Printf(" PixelStretch: %f\n", myLevel->pixelstretch); - if (myLevel->RedirectType.GetChars()) + if (myLevel->RedirectType != NAME_None) Printf(" Redirect (Item): %s\n", myLevel->RedirectType.GetChars()); if (myLevel->RedirectMapName.IsNotEmpty()) Printf(" Redirect (Map): %s\n", myLevel->RedirectMapName.GetChars()); - if (myLevel->RedirectCVAR.GetChars()) + if (myLevel->RedirectCVAR != NAME_None) Printf("CVAR_Redirect (CVAR): %s\n", myLevel->RedirectCVAR.GetChars()); if (myLevel->RedirectCVARMapName.IsNotEmpty()) From c8ee0cd5cc3125d1261e6f0c41854b9f9fd6dff2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 8 Oct 2023 09:37:12 +0200 Subject: [PATCH 203/223] fixed another bad string validation check involving GetChars --- src/r_data/gldefs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 07df23fdb..9b5be0e25 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -1564,7 +1564,7 @@ class GLDefsParser if (is_cvar) { addedcvars = true; - if (!shaderdesc.Name.GetChars()) + if (shaderdesc.Name.IsEmpty()) sc.ScriptError("Shader must have a name to use cvar uniforms"); ECVarType cvartype = CVAR_Dummy; From 4f5df7b9efad602db13f1a6385ba9e418679c58e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 8 Oct 2023 11:40:34 +0200 Subject: [PATCH 204/223] allocate temporary state label strings from the compiler backend's allocator. They share appoximate lifetime so this gets rid of 3 more copystring calls. --- src/p_states.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_states.cpp b/src/p_states.cpp index 90241dd54..46a7d0e54 100644 --- a/src/p_states.cpp +++ b/src/p_states.cpp @@ -40,6 +40,7 @@ #include "thingdef.h" #include "r_state.h" #include "templates.h" +#include "codegen.h" // stores indices for symbolic state labels for some old-style DECORATE functions. @@ -702,7 +703,7 @@ void FStateDefinitions::RetargetStatePointers (intptr_t count, const char *targe } else { - statelist[i].State = (FState *)copystring (target); + statelist[i].State = (FState *)FxAlloc.Strdup(target); statelist[i].DefineFlags = SDF_LABEL; } } @@ -803,7 +804,6 @@ FState *FStateDefinitions::ResolveGotoLabel (PClassActor *mytype, char *name) { Printf (TEXTCOLOR_RED "Attempt to get invalid state %s from actor %s.\n", label, type->TypeName.GetChars()); } - delete[] namestart; // free the allocated string buffer return state; } @@ -867,7 +867,7 @@ bool FStateDefinitions::SetGotoLabel(const char *string) // copy the text - this must be resolved later! if (laststate != NULL) { // Following a state definition: Modify it. - laststate->NextState = (FState*)copystring(string); + laststate->NextState = (FState*)FxAlloc.Strdup(string); laststate->DefineFlags = SDF_LABEL; laststatebeforelabel = NULL; return true; @@ -877,7 +877,7 @@ bool FStateDefinitions::SetGotoLabel(const char *string) RetargetStates (lastlabel+1, string); if (laststatebeforelabel != NULL) { - laststatebeforelabel->NextState = (FState*)copystring(string); + laststatebeforelabel->NextState = (FState*)FxAlloc.Strdup(string); laststatebeforelabel->DefineFlags = SDF_LABEL; laststatebeforelabel = NULL; } From ac646e96befa225637efe4744bd77dc3f1ff7d32 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 8 Oct 2023 11:54:14 +0200 Subject: [PATCH 205/223] use copystring instead of strdup when reading environments. The mismatched the underlying code which allocates via copystring. --- src/common/audio/sound/s_environment.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/audio/sound/s_environment.cpp b/src/common/audio/sound/s_environment.cpp index 7a2dbd9a5..5b4ea79f1 100644 --- a/src/common/audio/sound/s_environment.cpp +++ b/src/common/audio/sound/s_environment.cpp @@ -538,7 +538,7 @@ void S_ReadReverbDef (FScanner &sc) while (sc.GetString ()) { - name = strdup (sc.String); + name = copystring(sc.String); sc.MustGetNumber (); id1 = sc.Number; sc.MustGetNumber (); From 06466b90178388844659b1491c6606fba2014765 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 8 Oct 2023 12:14:50 +0200 Subject: [PATCH 206/223] add missing include to a_quake.cpp. The GCC AppImage build reported /usr/bin/ld: CMakeFiles/zdoom.dir/playsim/mapthinkers/a_quake.cpp.o: in function `AActor::Distance2D(AActor*, bool) const': a_quake.cpp:(.text._ZNK6AActor10Distance2DEPS_b[_ZNK6AActor10Distance2DEPS_b]+0x2c): undefined reference to `AActor::PosRelative(AActor const*) const' --- src/playsim/mapthinkers/a_quake.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/playsim/mapthinkers/a_quake.cpp b/src/playsim/mapthinkers/a_quake.cpp index 6cb82cd3e..aae1061bf 100644 --- a/src/playsim/mapthinkers/a_quake.cpp +++ b/src/playsim/mapthinkers/a_quake.cpp @@ -33,6 +33,7 @@ #include "d_player.h" #include "r_utility.h" #include "g_levellocals.h" +#include "actorinlines.h" #include static FRandom pr_quake ("Quake"); From 79f2fc65532441f85a9d26a7523373079d1eb958 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Oct 2023 18:45:30 +0200 Subject: [PATCH 207/223] backend update from Raze. Mainly a VMFunction script type and some associated utilities. --- src/common/objects/dobject.h | 8 ++++++-- src/common/scripting/backend/codegen.cpp | 19 +++++++++++++++++++ src/common/scripting/backend/codegen.h | 7 +++++++ src/common/scripting/core/imports.cpp | 18 ++++++++++++++++++ src/common/scripting/core/types.cpp | 2 ++ src/common/scripting/core/types.h | 2 ++ src/common/scripting/frontend/zcc_compile.cpp | 7 +++++++ src/common/scripting/frontend/zcc_compile.h | 1 - src/common/scripting/vm/vm.h | 1 + src/common/utility/configfile.h | 4 ++++ src/g_statusbar/sbar.h | 1 + src/scripting/thingdef.h | 7 +++++++ src/scripting/zscript/zcc_compile_doom.cpp | 5 +++++ 13 files changed, 79 insertions(+), 3 deletions(-) diff --git a/src/common/objects/dobject.h b/src/common/objects/dobject.h index ce591b6d6..aed223071 100644 --- a/src/common/objects/dobject.h +++ b/src/common/objects/dobject.h @@ -179,8 +179,6 @@ public: \ #include "dobjgc.h" -class AActor; - class DObject { public: @@ -245,6 +243,7 @@ public: inline DAngle &AngleVar(FName field); inline FString &StringVar(FName field); template T*& PointerVar(FName field); + inline int* IntArray(FName field); // This is only needed for swapping out PlayerPawns and absolutely nothing else! virtual size_t PointerSubstitution (DObject *old, DObject *notOld); @@ -435,6 +434,11 @@ inline int &DObject::IntVar(FName field) return *(int*)ScriptVar(field, nullptr); } +inline int* DObject::IntArray(FName field) +{ + return (int*)ScriptVar(field, nullptr); +} + inline FTextureID &DObject::TextureIDVar(FName field) { return *(FTextureID*)ScriptVar(field, nullptr); diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 9711abf72..1e30148c7 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -6358,6 +6358,16 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) ABORT(newex); goto foundit; } + else if (sym->IsKindOf(RUNTIME_CLASS(PFunction))) + { + if (ctx.Version >= MakeVersion(4, 11, 100)) + { + // VMFunction is only supported since 4.12 and Raze 1.8. + newex = new FxConstant(static_cast(sym)->Variants[0].Implementation, ScriptPosition); + goto foundit; + + } + } } // now check in the owning class. @@ -6369,6 +6379,15 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) newex = FxConstant::MakeConstant(sym, ScriptPosition); goto foundit; } + else if (sym->IsKindOf(RUNTIME_CLASS(PFunction))) + { + if (ctx.Version >= MakeVersion(4, 11, 100)) + { + // VMFunction is only supported since 4.12 and Raze 1.8. + newex = new FxConstant(static_cast(sym)->Variants[0].Implementation, ScriptPosition); + goto foundit; + } + } else if (ctx.Function == nullptr) { ScriptPosition.Message(MSG_ERROR, "Unable to access class member %s from constant declaration", sym->SymbolName.GetChars()); diff --git a/src/common/scripting/backend/codegen.h b/src/common/scripting/backend/codegen.h index 2781adbe5..5dd066b57 100644 --- a/src/common/scripting/backend/codegen.h +++ b/src/common/scripting/backend/codegen.h @@ -506,6 +506,13 @@ public: isresolved = true; } + FxConstant(VMFunction* state, const FScriptPosition& pos) : FxExpression(EFX_Constant, pos) + { + value.pointer = state; + ValueType = value.Type = TypeVMFunction; + isresolved = true; + } + FxConstant(const FScriptPosition &pos) : FxExpression(EFX_Constant, pos) { value.pointer = nullptr; diff --git a/src/common/scripting/core/imports.cpp b/src/common/scripting/core/imports.cpp index eed84980a..ff6d7ceba 100644 --- a/src/common/scripting/core/imports.cpp +++ b/src/common/scripting/core/imports.cpp @@ -147,6 +147,24 @@ VMFunction *FindVMFunction(PClass *cls, const char *name) } +//========================================================================== +// +// Find an action function in AActor's table from a qualified name +// This cannot search in structs. sorry. :( +// +//========================================================================== + +VMFunction* FindVMFunction( const char* name) +{ + auto p = strchr(name, '.'); + if (p == nullptr) return nullptr; + std::string clsname(name, p - name); + auto cls = PClass::FindClass(clsname.c_str()); + if (cls == nullptr) return nullptr; + return FindVMFunction(cls, p + 1); +} + + //========================================================================== // // Sorting helpers diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index 6543dde9e..f27faa7ab 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -75,6 +75,7 @@ PStruct *TypeStringStruct; PStruct* TypeQuaternionStruct; PPointer *TypeNullPtr; PPointer *TypeVoidPtr; +PPointer* TypeVMFunction; // CODE -------------------------------------------------------------------- @@ -322,6 +323,7 @@ void PType::StaticInit() TypeTable.AddType(TypeTextureID = new PTextureID, NAME_TextureID); TypeVoidPtr = NewPointer(TypeVoid, false); + TypeVMFunction = NewPointer(NewStruct("VMFunction", nullptr, true)); TypeColorStruct = NewStruct("@ColorStruct", nullptr); //This name is intentionally obfuscated so that it cannot be used explicitly. The point of this type is to gain access to the single channels of a color value. TypeStringStruct = NewStruct("Stringstruct", nullptr, true); TypeQuaternionStruct = NewStruct("QuatStruct", nullptr, true); diff --git a/src/common/scripting/core/types.h b/src/common/scripting/core/types.h index 789cc7d3e..850c354a8 100644 --- a/src/common/scripting/core/types.h +++ b/src/common/scripting/core/types.h @@ -697,6 +697,8 @@ extern PPointer *TypeFont; extern PStateLabel *TypeStateLabel; extern PPointer *TypeNullPtr; extern PPointer *TypeVoidPtr; +extern PPointer* TypeVMFunction; + inline FString &DObject::StringVar(FName field) { diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index fbe3d80dd..815af694b 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -57,6 +57,13 @@ double GetFloatConst(FxExpression *ex, FCompileContext &ctx) return ex ? static_cast(ex)->GetValue().GetFloat() : 0; } +VMFunction* GetFuncConst(FxExpression* ex, FCompileContext& ctx) +{ + ex = new FxTypeCast(ex, TypeVMFunction, false); + ex = ex->Resolve(ctx); + return static_cast(ex ? static_cast(ex)->GetValue().GetPointer() : nullptr); +} + const char * ZCCCompiler::GetStringConst(FxExpression *ex, FCompileContext &ctx) { ex = new FxStringCast(ex); diff --git a/src/common/scripting/frontend/zcc_compile.h b/src/common/scripting/frontend/zcc_compile.h index 82c6342ff..19e9f8ff0 100644 --- a/src/common/scripting/frontend/zcc_compile.h +++ b/src/common/scripting/frontend/zcc_compile.h @@ -6,7 +6,6 @@ struct Baggage; struct FPropertyInfo; -class AActor; class FxExpression; typedef TDeletingArray FArgumentList; diff --git a/src/common/scripting/vm/vm.h b/src/common/scripting/vm/vm.h index 6442034c1..2b7344d5d 100644 --- a/src/common/scripting/vm/vm.h +++ b/src/common/scripting/vm/vm.h @@ -797,6 +797,7 @@ class AActor; class PFunction; VMFunction *FindVMFunction(PClass *cls, const char *name); +VMFunction* FindVMFunction(const char* name); #define DECLARE_VMFUNC(cls, name) static VMFunction *name; if (name == nullptr) name = FindVMFunction(RUNTIME_CLASS(cls), #name); FString FStringFormat(VM_ARGS, int offset = 0); diff --git a/src/common/utility/configfile.h b/src/common/utility/configfile.h index cc484a3c2..f1a5ab87d 100644 --- a/src/common/utility/configfile.h +++ b/src/common/utility/configfile.h @@ -66,6 +66,10 @@ public: bool NextInSection (const char *&key, const char *&value); const char *GetValueForKey (const char *key) const; void SetValueForKey (const char *key, const char *value, bool duplicates=false); + void SetValueForKey(const char* key, const FString& value, bool duplicates = false) + { + SetValueForKey(key, value.GetChars(), duplicates); + } const char *GetPathName () const { return PathName.GetChars(); } void ChangePathName (const char *path); diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index 767e4de6e..b19a29245 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -43,6 +43,7 @@ #include "v_draw.h" #include "c_cvars.h" +class AActor; EXTERN_CVAR(Int, con_scaletext); inline int active_con_scaletext(F2DDrawer* drawer, bool newconfont = false) diff --git a/src/scripting/thingdef.h b/src/scripting/thingdef.h index 320c28cd4..34cd34666 100644 --- a/src/scripting/thingdef.h +++ b/src/scripting/thingdef.h @@ -256,6 +256,7 @@ union FPropParam int i; double d; const char *s; + VMFunction* fu; FxExpression *exp; }; @@ -313,6 +314,9 @@ int MatchString (const char *in, const char **strings); #define PROP_STRING_PARM(var, no) \ const char *var = params[(no)+1].s; +#define PROP_NAME_PARM(var, no) \ + FName var = params[(no)+1].s; + #define PROP_EXP_PARM(var, no) \ FxExpression *var = params[(no)+1].exp; @@ -325,6 +329,9 @@ int MatchString (const char *in, const char **strings); #define PROP_DOUBLE_PARM(var, no) \ double var = params[(no)+1].d; +#define PROP_FUNC_PARM(var, no) \ + auto var = params[(no)+1].fu; + #define PROP_COLOR_PARM(var, no, scriptpos) \ int var = params[(no)+1].i== 0? params[(no)+2].i : V_GetColor(params[(no)+2].s, scriptpos); diff --git a/src/scripting/zscript/zcc_compile_doom.cpp b/src/scripting/zscript/zcc_compile_doom.cpp index d6b8780f9..8c21659dc 100644 --- a/src/scripting/zscript/zcc_compile_doom.cpp +++ b/src/scripting/zscript/zcc_compile_doom.cpp @@ -50,6 +50,7 @@ bool isActor(PContainerType *type); void AddActorInfo(PClass *cls); int GetIntConst(FxExpression* ex, FCompileContext& ctx); double GetFloatConst(FxExpression* ex, FCompileContext& ctx); +VMFunction* GetFuncConst(FxExpression* ex, FCompileContext& ctx); //========================================================================== // @@ -282,6 +283,10 @@ void ZCCDoomCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *pr conv.d = GetFloatConst(ex, ctx); break; + case 'G': + conv.fu = GetFuncConst(ex, ctx); + break; + case 'Z': // an optional string. Does not allow any numeric value. if (ex->ValueType != TypeString) { From 0044da1ca2f02c62898a8097e1ec85a516b21cf7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 9 Oct 2023 19:20:44 +0200 Subject: [PATCH 208/223] added missing VMFunction struct definition --- wadsrc/static/zscript/engine/base.zs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index dd9813ae6..6b78ead56 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -934,3 +934,8 @@ struct QuatStruct native // native double LengthSquared(); // native Quat Unit(); } + +// this struct does not exist. It is just a type for being referenced by an opaque pointer. +struct VMFunction native version("4.10") +{ +} From 88b5d9aba15fbfb07c766a29bcb0e2cb7804efce Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Tue, 10 Oct 2023 10:29:01 -0400 Subject: [PATCH 209/223] - fix $PROGDIR expansion being case sensitive --- src/common/utility/cmdlib.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/utility/cmdlib.cpp b/src/common/utility/cmdlib.cpp index b8c140453..9bb06fb38 100644 --- a/src/common/utility/cmdlib.cpp +++ b/src/common/utility/cmdlib.cpp @@ -831,7 +831,7 @@ FString ExpandEnvVars(const char *searchpathstring) if (length != 0) { FString varname = FString(dollar + 1, length); - if (varname.Compare("progdir") == 0) + if (varname.CompareNoCase("progdir") == 0) { out += progdir; } From e3704605d814a29c0b648e3cbb523966bb27ed7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Fri, 10 Feb 2023 09:44:32 -0300 Subject: [PATCH 210/223] Implement Static Function Pointers --- src/common/engine/namedef.h | 3 + src/common/engine/sc_man_scanner.re | 1 + src/common/engine/sc_man_tokens.h | 1 + src/common/engine/serializer.cpp | 78 ++++++ src/common/engine/serializer.h | 8 + src/common/scripting/backend/codegen.cpp | 208 ++++++++++++--- src/common/scripting/backend/codegen.h | 20 ++ src/common/scripting/backend/vmbuilder.cpp | 53 +++- src/common/scripting/backend/vmbuilder.h | 9 +- src/common/scripting/core/scopebarrier.cpp | 8 + src/common/scripting/core/scopebarrier.h | 3 + src/common/scripting/core/types.cpp | 242 +++++++++++++++++- src/common/scripting/core/types.h | 32 ++- src/common/scripting/frontend/ast.cpp | 33 +++ src/common/scripting/frontend/zcc-parse.lemon | 69 +++++ src/common/scripting/frontend/zcc_compile.cpp | 57 +++++ src/common/scripting/frontend/zcc_exprlist.h | 1 + src/common/scripting/frontend/zcc_parser.cpp | 38 +++ src/common/scripting/frontend/zcc_parser.h | 22 ++ src/common/scripting/interface/vmnatives.cpp | 32 +++ src/scripting/backend/codegen_doom.cpp | 3 +- wadsrc/static/zscript.txt | 2 +- wadsrc/static/zscript/engine/base.zs | 4 + 23 files changed, 876 insertions(+), 51 deletions(-) diff --git a/src/common/engine/namedef.h b/src/common/engine/namedef.h index 948228cb9..70080a965 100644 --- a/src/common/engine/namedef.h +++ b/src/common/engine/namedef.h @@ -120,6 +120,7 @@ xx(Vector) xx(Map) xx(MapIterator) xx(Array) +xx(Function) xx(Include) xx(Sound) xx(State) @@ -190,6 +191,7 @@ xx(SetNull) xx(Key) xx(Index) xx(Find) +xx(Call) // color channels xx(a) @@ -269,6 +271,7 @@ xx(BuiltinRandom2) xx(BuiltinFRandom) xx(BuiltinNameToClass) xx(BuiltinClassCast) +xx(BuiltinFunctionPtrCast) xx(ScreenJobRunner) xx(Action) diff --git a/src/common/engine/sc_man_scanner.re b/src/common/engine/sc_man_scanner.re index dfc3f050f..e5d507a28 100644 --- a/src/common/engine/sc_man_scanner.re +++ b/src/common/engine/sc_man_scanner.re @@ -169,6 +169,7 @@ std2: 'map' { RET(TK_Map); } 'mapiterator' { RET(TK_MapIterator); } 'array' { RET(TK_Array); } + 'function' { RET(ParseVersion >= MakeVersion(4, 11, 0)? TK_FunctionType : TK_Identifier); } 'in' { RET(TK_In); } 'sizeof' { RET(TK_SizeOf); } 'alignof' { RET(TK_AlignOf); } diff --git a/src/common/engine/sc_man_tokens.h b/src/common/engine/sc_man_tokens.h index 8fb2f88e3..487003125 100644 --- a/src/common/engine/sc_man_tokens.h +++ b/src/common/engine/sc_man_tokens.h @@ -131,6 +131,7 @@ xx(TK_Vector3, "'vector3'") xx(TK_Map, "'map'") xx(TK_MapIterator, "'mapiterator'") xx(TK_Array, "'array'") +xx(TK_FunctionType, "'function'") xx(TK_In, "'in'") xx(TK_SizeOf, "'sizeof'") xx(TK_AlignOf, "'alignof'") diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index bb54c0d2b..34fd6956b 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -1656,6 +1656,84 @@ FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &value, N return arc; } +//========================================================================== +// +// PFunctionPointer +// +//========================================================================== + +void SerializeFunctionPointer(FSerializer &arc, const char *key, FunctionPointerValue *&p) +{ + if (arc.isWriting()) + { + if(p) + { + arc.BeginObject(key); + arc("Class",p->ClassName); + arc("Function",p->FunctionName); + arc.EndObject(); + } + else + { + arc.WriteKey(key); + arc.w->Null(); + } + } + else + { + assert(p); + auto v = arc.r->FindKey(key); + if(!v || v->IsNull()) + { + p = nullptr; + } + else if(v->IsObject()) + { + arc.r->mObjects.Push(FJSONObject(v)); // BeginObject + + const char * cstr; + arc.StringPtr("Class", cstr); + + if(!cstr) + { + arc.StringPtr("Function", cstr); + if(!cstr) + { + Printf(TEXTCOLOR_RED "Function Pointer missing Class and Function Fields in Object\n"); + } + else + { + Printf(TEXTCOLOR_RED "Function Pointer missing Class Field in Object\n"); + } + arc.mErrors++; + arc.EndObject(); + p = nullptr; + return; + } + + p->ClassName = FString(cstr); + arc.StringPtr("Function", cstr); + + if(!cstr) + { + Printf(TEXTCOLOR_RED "Function Pointer missing Function Field in Object\n"); + arc.mErrors++; + arc.EndObject(); + p = nullptr; + return; + } + p->FunctionName = FString(cstr); + arc.EndObject(); + } + else + { + Printf(TEXTCOLOR_RED "Function Pointer is not an Object\n"); + arc.mErrors++; + p = nullptr; + } + } +} + #include "renderstyle.h" FSerializer& Serialize(FSerializer& arc, const char* key, FRenderStyle& style, FRenderStyle* def) { diff --git a/src/common/engine/serializer.h b/src/common/engine/serializer.h index a6f74c037..9328f2f22 100644 --- a/src/common/engine/serializer.h +++ b/src/common/engine/serializer.h @@ -54,6 +54,12 @@ struct NumericValue } }; +struct FunctionPointerValue +{ + FString ClassName; + FString FunctionName; +}; + class FSerializer { @@ -235,6 +241,8 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FString &sid, FString FSerializer &Serialize(FSerializer &arc, const char *key, NumericValue &sid, NumericValue *def); FSerializer &Serialize(FSerializer &arc, const char *key, struct ModelOverride &sid, struct ModelOverride *def); +void SerializeFunctionPointer(FSerializer &arc, const char *key, FunctionPointerValue *&p); + template >*/> FSerializer &Serialize(FSerializer &arc, const char *key, T *&value, T **) { diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 1e30148c7..49999ae68 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -297,6 +297,13 @@ bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare) if (forcompare && tocls->IsDescendantOf(fromcls)) return true; return (fromcls->IsDescendantOf(tocls)); } + if(source->isFunctionPointer() && dest->isFunctionPointer()) + { + auto from = static_cast(source); + auto to = static_cast(dest); + return to->PointedType == TypeVoid || (from->PointedType == to->PointedType && from->ArgFlags == to->ArgFlags && FScopeBarrier::CheckSidesForFunctionPointer(from->Scope, to->Scope)); + // TODO allow narrowing argument types and widening return types via cast, ex.: Function)> to Function)> + } } return false; } @@ -8379,6 +8386,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) PContainerType *cls = nullptr; bool staticonly = false; bool novirtual = false; + bool fnptr = false; bool isreadonly = false; PContainerType *ccls = nullptr; @@ -8996,6 +9004,22 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) cls = static_cast(Self->ValueType); Self->ValueType = NewPointer(Self->ValueType); } + else if (Self->ValueType->isFunctionPointer()) + { + auto fn = static_cast(Self->ValueType); + + if(MethodName == NAME_Call && fn->PointedType != TypeVoid) + { // calling a Function pointer isn't allowed + fnptr = true; + afd_override = fn->FakeFunction; + } + else + { + ScriptPosition.Message(MSG_ERROR, "Unknown function %s", MethodName.GetChars()); + delete this; + return nullptr; + } + } else { ScriptPosition.Message(MSG_ERROR, "Invalid expression on left hand side of %s", MethodName.GetChars()); @@ -9115,8 +9139,8 @@ isresolved: } // do not pass the self pointer to static functions. - auto self = (afd->Variants[0].Flags & VARF_Method) ? Self : nullptr; - auto x = new FxVMFunctionCall(self, afd, ArgList, ScriptPosition, staticonly|novirtual); + auto self = ( fnptr || (afd->Variants[0].Flags & VARF_Method)) ? Self : nullptr; + auto x = new FxVMFunctionCall(self, afd, ArgList, ScriptPosition, (staticonly || novirtual) && !fnptr); if (Self == self) Self = nullptr; delete this; return x->Resolve(ctx); @@ -9130,7 +9154,7 @@ isresolved: //========================================================================== FxVMFunctionCall::FxVMFunctionCall(FxExpression *self, PFunction *func, FArgumentList &args, const FScriptPosition &pos, bool novirtual) -: FxExpression(EFX_VMFunctionCall, pos) +: FxExpression(EFX_VMFunctionCall, pos) , FnPtrCall((self && self->ValueType) ? self->ValueType->isFunctionPointer() : false) { Self = self; Function = func; @@ -9204,7 +9228,7 @@ VMFunction *FxVMFunctionCall::GetDirectFunction(PFunction *callingfunc, const Ve // definition can call that function directly without wrapping // it inside VM code. - if (ArgList.Size() == 0 && !(Function->Variants[0].Flags & VARF_Virtual) && CheckAccessibility(ver) && CheckFunctionCompatiblity(ScriptPosition, callingfunc, Function)) + if (ArgList.Size() == 0 && !(Function->Variants[0].Flags & VARF_Virtual) && !FnPtrCall && CheckAccessibility(ver) && CheckFunctionCompatiblity(ScriptPosition, callingfunc, Function)) { unsigned imp = Function->GetImplicitArgs(); if (Function->Variants[0].ArgFlags.Size() > imp && !(Function->Variants[0].ArgFlags[imp] & VARF_Optional)) return nullptr; @@ -9229,7 +9253,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) auto &argtypes = proto->ArgumentTypes; auto &argnames = Function->Variants[0].ArgNames; auto &argflags = Function->Variants[0].ArgFlags; - auto &defaults = Function->Variants[0].Implementation->DefaultArgs; + auto *defaults = FnPtrCall ? nullptr : &Function->Variants[0].Implementation->DefaultArgs; int implicit = Function->GetImplicitArgs(); @@ -9297,6 +9321,12 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) if (ArgList[i]->ExprType == EFX_NamedNode) { + if(FnPtrCall) + { + ScriptPosition.Message(MSG_ERROR, "Named arguments not supported in function pointer calls"); + delete this; + return nullptr; + } if (!(flag & VARF_Optional)) { ScriptPosition.Message(MSG_ERROR, "Cannot use a named argument here - not all required arguments have been passed."); @@ -9346,7 +9376,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) } if (ntype->GetRegCount() == 1) { - auto x = new FxConstant(ntype, defaults[i + k + skipdefs + implicit], ScriptPosition); + auto x = new FxConstant(ntype, (*defaults)[i + k + skipdefs + implicit], ScriptPosition); ArgList.Insert(i + k, x); } else @@ -9355,7 +9385,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) FxConstant *cs[4] = { nullptr }; for (int l = 0; l < ntype->GetRegCount(); l++) { - cs[l] = new FxConstant(TypeFloat64, defaults[l + i + k + skipdefs + implicit], ScriptPosition); + cs[l] = new FxConstant(TypeFloat64, (*defaults)[l + i + k + skipdefs + implicit], ScriptPosition); } FxExpression *x = new FxVectorValue(cs[0], cs[1], cs[2], cs[3], ScriptPosition); ArgList.Insert(i + k, x); @@ -9492,6 +9522,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx) { ValueType = TypeVoid; } + return this; } @@ -9517,11 +9548,14 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build) } } - VMFunction *vmfunc = Function->Variants[0].Implementation; - bool staticcall = ((vmfunc->VarFlags & VARF_Final) || vmfunc->VirtualIndex == ~0u || NoVirtual); + VMFunction *vmfunc = FnPtrCall ? nullptr : Function->Variants[0].Implementation; + bool staticcall = (FnPtrCall || (vmfunc->VarFlags & VARF_Final) || vmfunc->VirtualIndex == ~0u || NoVirtual); count = 0; - FunctionCallEmitter emitters(vmfunc); + + assert(!FnPtrCall || (FnPtrCall && Self && Self->ValueType && Self->ValueType->isFunctionPointer())); + + FunctionCallEmitter emitters(FnPtrCall ? FunctionCallEmitter(PType::toFunctionPointer(Self->ValueType)) : FunctionCallEmitter(vmfunc)); // Emit code to pass implied parameters ExpEmit selfemit; if (Function->Variants[0].Flags & VARF_Method) @@ -9565,43 +9599,56 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build) } } } + else if (FnPtrCall) + { + assert(Self != nullptr); + selfemit = Self->Emit(build); + assert(selfemit.RegType == REGT_POINTER); + staticcall = false; + } else staticcall = true; // Emit code to pass explicit parameters for (unsigned i = 0; i < ArgList.Size(); ++i) { emitters.AddParameter(build, ArgList[i]); } - // Complete the parameter list from the defaults. - auto &defaults = Function->Variants[0].Implementation->DefaultArgs; - for (unsigned i = emitters.Count(); i < defaults.Size(); i++) + if(!FnPtrCall) { - switch (defaults[i].Type) + // Complete the parameter list from the defaults. + auto &defaults = Function->Variants[0].Implementation->DefaultArgs; + for (unsigned i = emitters.Count(); i < defaults.Size(); i++) { - default: - case REGT_INT: - emitters.AddParameterIntConst(defaults[i].i); - break; - case REGT_FLOAT: - emitters.AddParameterFloatConst(defaults[i].f); - break; - case REGT_POINTER: - emitters.AddParameterPointerConst(defaults[i].a); - break; - case REGT_STRING: - emitters.AddParameterStringConst(defaults[i].s()); - break; + switch (defaults[i].Type) + { + default: + case REGT_INT: + emitters.AddParameterIntConst(defaults[i].i); + break; + case REGT_FLOAT: + emitters.AddParameterFloatConst(defaults[i].f); + break; + case REGT_POINTER: + emitters.AddParameterPointerConst(defaults[i].a); + break; + case REGT_STRING: + emitters.AddParameterStringConst(defaults[i].s()); + break; + } } } ArgList.DeleteAndClear(); ArgList.ShrinkToFit(); if (!staticcall) emitters.SetVirtualReg(selfemit.RegNum); - int resultcount = vmfunc->Proto->ReturnTypes.Size() == 0 ? 0 : max(AssignCount, 1); - assert((unsigned)resultcount <= vmfunc->Proto->ReturnTypes.Size()); + PPrototype * proto = FnPtrCall ? static_cast(static_cast(Self->ValueType)->PointedType) : vmfunc->Proto; + + int resultcount = proto->ReturnTypes.Size() == 0 ? 0 : max(AssignCount, 1); + + assert((unsigned)resultcount <= proto->ReturnTypes.Size()); for (int i = 0; i < resultcount; i++) { - emitters.AddReturn(vmfunc->Proto->ReturnTypes[i]->GetRegType(), vmfunc->Proto->ReturnTypes[i]->GetRegCount()); + emitters.AddReturn(proto->ReturnTypes[i]->GetRegType(), proto->ReturnTypes[i]->GetRegCount()); } return emitters.EmitCall(build, resultcount > 1? &ReturnRegs : nullptr); } @@ -11629,6 +11676,107 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build) return emitters.EmitCall(build); } +//========================================================================== +// +//========================================================================== + +FxFunctionPtrCast::FxFunctionPtrCast(PFunctionPointer *ftype, FxExpression *x) + : FxExpression(EFX_FunctionPtrCast, x->ScriptPosition) +{ + ValueType = ftype; + basex = x; +} + +//========================================================================== +// +// +// +//========================================================================== + +FxFunctionPtrCast::~FxFunctionPtrCast() +{ + SAFE_DELETE(basex); +} + +//========================================================================== +// +// +// +//========================================================================== + +FxExpression *FxFunctionPtrCast::Resolve(FCompileContext &ctx) +{ + CHECKRESOLVED(); + SAFE_RESOLVE(basex, ctx); + + if (!(basex->ValueType && basex->ValueType->isFunctionPointer())) + { + delete this; + return nullptr; + } + auto to = static_cast(ValueType); + auto from = static_cast(basex->ValueType); + + if(to->PointedType == TypeVoid) + { // no need to do anything for (FunctionValueType = ValueType; + auto x = basex; + basex = nullptr; + delete this; + return x; + } + else if(from->PointedType == TypeVoid) + { // nothing to check at compile-time for casts from Function + return this; + } + else + { + // TODO allow narrowing argument types and widening return types via cast, ex.: Function)> to Function)> + ScriptPosition.Message(MSG_ERROR, "Cannot cast %s to %s. The types are incompatible.", basex->ValueType->DescriptiveName(), to->DescriptiveName()); + delete this; + return nullptr; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +PFunction *NativeFunctionPointerCast(PFunction *from, const PFunctionPointer *to) +{ + // TODO allow narrowing argument types and widening return types via cast, ex.: Function)> to Function)> + return (to->PointedType == TypeVoid || (from && + ( from->Variants[0].Proto == static_cast(to->PointedType) + && from->Variants[0].ArgFlags == to->ArgFlags + && FScopeBarrier::CheckSidesForFunctionPointer(FScopeBarrier::SideFromFlags(from->Variants[0].Flags), to->Scope) + ))) ? from : nullptr; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DObject, BuiltinFunctionPtrCast, NativeFunctionPointerCast) +{ + PARAM_PROLOGUE; + PARAM_POINTER(from, PFunction); + PARAM_POINTER(to, PFunctionPointer); + ACTION_RETURN_POINTER(NativeFunctionPointerCast(from, to)); +} + +ExpEmit FxFunctionPtrCast::Emit(VMFunctionBuilder *build) +{ + ExpEmit funcptr = basex->Emit(build); + + auto sym = FindBuiltinFunction(NAME_BuiltinFunctionPtrCast); + assert(sym); + + FunctionCallEmitter emitters(sym->Variants[0].Implementation); + emitters.AddParameter(funcptr, false); + emitters.AddParameterPointerConst(ValueType); + + emitters.AddReturn(REGT_POINTER); + return emitters.EmitCall(build); +} + //========================================================================== // // declares a single local variable (no arrays) diff --git a/src/common/scripting/backend/codegen.h b/src/common/scripting/backend/codegen.h index 5dd066b57..2b2257a7a 100644 --- a/src/common/scripting/backend/codegen.h +++ b/src/common/scripting/backend/codegen.h @@ -277,6 +277,7 @@ enum EFxType EFX_ReturnStatement, EFX_ClassTypeCast, EFX_ClassPtrCast, + EFX_FunctionPtrCast, EFX_StateByIndex, EFX_RuntimeStateIndex, EFX_MultiNameState, @@ -1818,6 +1819,7 @@ class FxVMFunctionCall : public FxExpression bool CheckAccessibility(const VersionInfo &ver); public: + const bool FnPtrCall; FArgumentList ArgList; PFunction* Function; @@ -2127,6 +2129,24 @@ public: // //========================================================================== +class FxFunctionPtrCast : public FxExpression +{ + FxExpression *basex; + +public: + + FxFunctionPtrCast (PFunctionPointer *ftype, FxExpression *x); + ~FxFunctionPtrCast(); + FxExpression *Resolve(FCompileContext&); + ExpEmit Emit(VMFunctionBuilder *build); +}; + +//========================================================================== +// +// +// +//========================================================================== + class FxNop : public FxExpression { public: diff --git a/src/common/scripting/backend/vmbuilder.cpp b/src/common/scripting/backend/vmbuilder.cpp index d063790d2..b64950e34 100644 --- a/src/common/scripting/backend/vmbuilder.cpp +++ b/src/common/scripting/backend/vmbuilder.cpp @@ -949,6 +949,18 @@ void FFunctionBuildList::DumpJit(bool include_gzdoom_pk3) #endif // HAVE_VM_JIT } +FunctionCallEmitter::FunctionCallEmitter(VMFunction *func) +{ + target = func; + is_vararg = target->VarFlags & VARF_VarArg; +} + +FunctionCallEmitter::FunctionCallEmitter(class PFunctionPointer *func) +{ + fnptr = func; + is_vararg = false; // function pointers cannot point to vararg functions +} + void FunctionCallEmitter::AddParameter(VMFunctionBuilder *build, FxExpression *operand) { @@ -959,7 +971,7 @@ void FunctionCallEmitter::AddParameter(VMFunctionBuilder *build, FxExpression *o operand->ScriptPosition.Message(MSG_ERROR, "Attempted to pass a non-value"); } numparams += where.RegCount; - if (target->VarFlags & VARF_VarArg) + if (is_vararg) for (unsigned i = 0; i < where.RegCount; i++) reginfo.Push(where.RegType & REGT_TYPE); emitters.push_back([=](VMFunctionBuilder *build) -> int @@ -982,7 +994,7 @@ void FunctionCallEmitter::AddParameter(VMFunctionBuilder *build, FxExpression *o void FunctionCallEmitter::AddParameter(ExpEmit &emit, bool reference) { numparams += emit.RegCount; - if (target->VarFlags & VARF_VarArg) + if (is_vararg) { if (reference) reginfo.Push(REGT_POINTER); else for (unsigned i = 0; i < emit.RegCount; i++) reginfo.Push(emit.RegType & REGT_TYPE); @@ -999,7 +1011,7 @@ void FunctionCallEmitter::AddParameter(ExpEmit &emit, bool reference) void FunctionCallEmitter::AddParameterPointerConst(void *konst) { numparams++; - if (target->VarFlags & VARF_VarArg) + if (is_vararg) reginfo.Push(REGT_POINTER); emitters.push_back([=](VMFunctionBuilder *build) ->int { @@ -1011,7 +1023,7 @@ void FunctionCallEmitter::AddParameterPointerConst(void *konst) void FunctionCallEmitter::AddParameterPointer(int index, bool konst) { numparams++; - if (target->VarFlags & VARF_VarArg) + if (is_vararg) reginfo.Push(REGT_POINTER); emitters.push_back([=](VMFunctionBuilder *build) ->int { @@ -1023,7 +1035,7 @@ void FunctionCallEmitter::AddParameterPointer(int index, bool konst) void FunctionCallEmitter::AddParameterFloatConst(double konst) { numparams++; - if (target->VarFlags & VARF_VarArg) + if (is_vararg) reginfo.Push(REGT_FLOAT); emitters.push_back([=](VMFunctionBuilder *build) ->int { @@ -1035,7 +1047,7 @@ void FunctionCallEmitter::AddParameterFloatConst(double konst) void FunctionCallEmitter::AddParameterIntConst(int konst) { numparams++; - if (target->VarFlags & VARF_VarArg) + if (is_vararg) reginfo.Push(REGT_INT); emitters.push_back([=](VMFunctionBuilder *build) ->int { @@ -1055,7 +1067,7 @@ void FunctionCallEmitter::AddParameterIntConst(int konst) void FunctionCallEmitter::AddParameterStringConst(const FString &konst) { numparams++; - if (target->VarFlags & VARF_VarArg) + if (is_vararg) reginfo.Push(REGT_STRING); emitters.push_back([=](VMFunctionBuilder *build) ->int { @@ -1074,7 +1086,7 @@ ExpEmit FunctionCallEmitter::EmitCall(VMFunctionBuilder *build, TArray paramcount += func(build); } assert(paramcount == numparams); - if (target->VarFlags & VARF_VarArg) + if (is_vararg) { // Pass a hidden type information parameter to vararg functions. // It would really be nicer to actually pass real types but that'd require a far more complex interface on the compiler side than what we have. @@ -1084,9 +1096,24 @@ ExpEmit FunctionCallEmitter::EmitCall(VMFunctionBuilder *build, TArray paramcount++; } + if(fnptr) + { + ExpEmit reg(build, REGT_POINTER); + assert(fnptr->Scope != -1); + assert(fnptr->PointedType != TypeVoid); + + // OP_LP , Load from memory. rA = *(rB + rkC) + // reg = &PFunction->Variants[0] -- PFunction::Variant* + build->Emit(OP_LP, reg.RegNum, virtualselfreg, build->GetConstantInt(offsetof(PFunction, Variants) + offsetof(FArray, Array))); + // reg = (&PFunction->Variants[0])->Implementation -- VMFunction* + build->Emit(OP_LP, reg.RegNum, reg.RegNum, build->GetConstantInt(offsetof(PFunction::Variant, Implementation))); - if (virtualselfreg == -1) + build->Emit(OP_CALL, reg.RegNum, paramcount, vm_jit? static_cast(fnptr->PointedType)->ReturnTypes.Size() : returns.Size()); + + reg.Free(build); + } + else if (virtualselfreg == -1) { build->Emit(OP_CALL_K, build->GetConstantAddress(target), paramcount, vm_jit ? target->Proto->ReturnTypes.Size() : returns.Size()); } @@ -1110,9 +1137,13 @@ ExpEmit FunctionCallEmitter::EmitCall(VMFunctionBuilder *build, TArray } if (vm_jit) // The JIT compiler needs this, but the VM interpreter does not. { - for (unsigned i = returns.Size(); i < target->Proto->ReturnTypes.Size(); i++) + assert(!fnptr || fnptr->PointedType != TypeVoid); + + PPrototype * proto = fnptr ? static_cast(fnptr->PointedType) : target->Proto; + + for (unsigned i = returns.Size(); i < proto->ReturnTypes.Size(); i++) { - ExpEmit reg(build, target->Proto->ReturnTypes[i]->RegType, target->Proto->ReturnTypes[i]->RegCount); + ExpEmit reg(build, proto->ReturnTypes[i]->RegType, proto->ReturnTypes[i]->RegCount); build->Emit(OP_RESULT, 0, EncodeRegType(reg), reg.RegNum); reg.Free(build); } diff --git a/src/common/scripting/backend/vmbuilder.h b/src/common/scripting/backend/vmbuilder.h index 43ef1bc4c..f1c8d889f 100644 --- a/src/common/scripting/backend/vmbuilder.h +++ b/src/common/scripting/backend/vmbuilder.h @@ -180,13 +180,12 @@ class FunctionCallEmitter TArray reginfo; unsigned numparams = 0; // This counts the number of pushed elements, which can differ from the number of emitters with vectors. VMFunction *target = nullptr; + class PFunctionPointer *fnptr = nullptr; int virtualselfreg = -1; - + bool is_vararg; public: - FunctionCallEmitter(VMFunction *func) - { - target = func; - } + FunctionCallEmitter(VMFunction *func); + FunctionCallEmitter(class PFunctionPointer *func); void SetVirtualReg(int virtreg) { diff --git a/src/common/scripting/core/scopebarrier.cpp b/src/common/scripting/core/scopebarrier.cpp index 8e03f757f..b27443570 100644 --- a/src/common/scripting/core/scopebarrier.cpp +++ b/src/common/scripting/core/scopebarrier.cpp @@ -208,6 +208,14 @@ void FScopeBarrier::AddFlags(int flags1, int flags2, const char* name) } } +bool FScopeBarrier::CheckSidesForFunctionPointer(int from, int to) +{ + if(to == -1) return true; + + if(from == Side_Clear) from = Side_PlainData; + return ((from == to) || (from == Side_PlainData)); +} + // these are for vmexec.h void FScopeBarrier::ValidateNew(PClass* cls, int outerside) { diff --git a/src/common/scripting/core/scopebarrier.h b/src/common/scripting/core/scopebarrier.h index b5eeae78f..08fc0a195 100644 --- a/src/common/scripting/core/scopebarrier.h +++ b/src/common/scripting/core/scopebarrier.h @@ -62,6 +62,9 @@ struct FScopeBarrier // This struct is used so that the logic is in a single place. void AddFlags(int flags1, int flags2, const char* name); + + static bool CheckSidesForFunctionPointer(int from, int to); + // this is called from vmexec.h static void ValidateNew(PClass* cls, int scope); static void ValidateCall(PClass* selftype, VMFunction *calledfunc, int outerside); diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index f27faa7ab..0b9666e30 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -2818,6 +2818,232 @@ PMapIterator *NewMapIterator(PType *keyType, PType *valueType) return (PMapIterator *)mapIteratorType; } +/* PFunctionPointer *******************************************************/ + +//========================================================================== +// +// PFunctionPointer - Parameterized Constructor +// +//========================================================================== + +static FString MakeFunctionPointerDescriptiveName(PPrototype * proto,const TArray &ArgFlags, int scope) +{ + FString mDescriptiveName; + + mDescriptiveName = "Function<"; + switch(scope) + { + case FScopeBarrier::Side_PlainData: + mDescriptiveName += "clearscope "; + break; + case FScopeBarrier::Side_Play: + mDescriptiveName += "play "; + break; + case FScopeBarrier::Side_UI: + mDescriptiveName += "ui "; + break; + } + if(proto->ReturnTypes.Size() > 0) + { + mDescriptiveName += proto->ReturnTypes[0]->DescriptiveName(); + + const unsigned n = proto->ReturnTypes.Size(); + for(unsigned i = 1; i < n; i++) + { + mDescriptiveName += ", "; + mDescriptiveName += proto->ReturnTypes[i]->DescriptiveName(); + } + mDescriptiveName += " ("; + } + else + { + mDescriptiveName += "void ("; + } + if(proto->ArgumentTypes.Size() > 0) + { + if(ArgFlags[0] == VARF_Out) mDescriptiveName += "out "; + mDescriptiveName += proto->ArgumentTypes[0]->DescriptiveName(); + const unsigned n = proto->ArgumentTypes.Size(); + for(unsigned i = 1; i < n; i++) + { + mDescriptiveName += ", "; + if(ArgFlags[i] == VARF_Out) mDescriptiveName += "out "; + mDescriptiveName += proto->ArgumentTypes[i]->DescriptiveName(); + } + mDescriptiveName += ")>"; + } + else + { + mDescriptiveName += "void)>"; + } + + return mDescriptiveName; +} + +PFunctionPointer::PFunctionPointer(PPrototype * proto, TArray && argflags, int scope) + : PPointer(proto ? (PType*) proto : TypeVoid, false), ArgFlags(std::move(argflags)), Scope(scope) +{ + if(!proto) + { + mDescriptiveName = "Function"; + } + else + { + mDescriptiveName = MakeFunctionPointerDescriptiveName(proto, ArgFlags, scope); + } + + Flags |= TYPE_FunctionPointer; + + if(proto) + { + assert(Scope != -1); // for now, a scope is always required + + TArray ArgNames; + TArray ArgFlags2(ArgFlags); // AddVariant calls std::move on this, so it needs to be a copy, + // but it takes it as a regular reference, so it needs to be a full variable instead of a temporary + ArgNames.Resize(ArgFlags.Size()); + FakeFunction = Create(); + FakeFunction->AddVariant(proto, ArgFlags2, ArgNames, nullptr, FScopeBarrier::FlagsFromSide(Scope), 0); + } + else + { + FakeFunction = nullptr; + } +} + +void PFunctionPointer::WriteValue(FSerializer &ar, const char *key, const void *addr) const +{ + auto p = *(const PFunction**)(addr); + if(p) + { + FunctionPointerValue val; + FunctionPointerValue *fpv = &val; + val.ClassName = FString((p->OwningClass ? p->OwningClass->TypeName : NAME_None).GetChars()); + val.FunctionName = FString(p->SymbolName.GetChars()); + SerializeFunctionPointer(ar, key, fpv); + } + else + { + FunctionPointerValue *fpv = nullptr; + SerializeFunctionPointer(ar, key, fpv); + } +} + +PFunction *NativeFunctionPointerCast(PFunction *from, const PFunctionPointer *to); + +bool PFunctionPointer::ReadValue(FSerializer &ar, const char *key, void *addr) const +{ + FunctionPointerValue val; + FunctionPointerValue *fpv = &val; + SerializeFunctionPointer(ar, key, fpv); + + PFunction ** fn = (PFunction**)(addr); + + if(fpv) + { + auto cls = PClass::FindClass(val.ClassName); + if(!cls) + { + *fn = nullptr; + Printf(TEXTCOLOR_RED "Function Pointer ('%s::%s'): '%s' is not a valid class\n", + val.ClassName.GetChars(), + val.FunctionName.GetChars(), + val.ClassName.GetChars() + ); + ar.mErrors++; + return false; + } + auto sym = cls->FindSymbol(FName(val.FunctionName), true); + if(!sym) + { + *fn = nullptr; + Printf(TEXTCOLOR_RED "Function Pointer ('%s::%s'): symbol '%s' does not exist in class '%s'\n", + val.ClassName.GetChars(), + val.FunctionName.GetChars(), + val.FunctionName.GetChars(), + val.ClassName.GetChars() + ); + ar.mErrors++; + return false; + } + PFunction* p = dyn_cast(sym); + if(!p) + { + *fn = nullptr; + Printf(TEXTCOLOR_RED "Function Pointer (%s::%s): symbol '%s' in class '%s' is a variable, not a function\n", + val.ClassName.GetChars(), + val.FunctionName.GetChars(), + val.FunctionName.GetChars(), + val.ClassName.GetChars() + ); + ar.mErrors++; + return false; + } + else if(p->GetImplicitArgs() > 0) + { + *fn = nullptr; + Printf(TEXTCOLOR_RED "Function Pointer (%s::%s): function '%s' in class '%s' is %s, not a static function\n", + val.ClassName.GetChars(), + val.FunctionName.GetChars(), + val.FunctionName.GetChars(), + val.ClassName.GetChars(), + (p->GetImplicitArgs() == 1 ? "a method" : "an action function") + ); + ar.mErrors++; + return false; + } + *fn = NativeFunctionPointerCast(p, this); + if(!*fn) + { + FString fn_name = MakeFunctionPointerDescriptiveName(p->Variants[0].Proto,p->Variants[0].ArgFlags, FScopeBarrier::SideFromFlags(p->Variants[0].Flags)); + Printf(TEXTCOLOR_RED "Function Pointer (%s::%s) has incompatible type (Pointer is '%s', Function is '%s')\n", + val.ClassName.GetChars(), + val.FunctionName.GetChars(), + fn_name.GetChars(), + mDescriptiveName.GetChars() + ); + ar.mErrors++; + return false; + } + return true; + } + else + { + *fn = nullptr; + } + return true; +} + +bool PFunctionPointer::IsMatch(intptr_t id1, intptr_t id2) const +{ + const PPrototype * proto = (const PPrototype*) id1; + const PFunctionPointer::FlagsAndScope * flags_and_scope = (const PFunctionPointer::FlagsAndScope *) id2; + return (proto == (PointedType == TypeVoid ? nullptr : PointedType)) + && (Scope == flags_and_scope->Scope) + && (ArgFlags == *flags_and_scope->ArgFlags); +} + +void PFunctionPointer::GetTypeIDs(intptr_t &id1, intptr_t &id2) const +{ //NOT SUPPORTED + assert(0 && "GetTypeIDs not supported for PFunctionPointer"); +} + +PFunctionPointer * NewFunctionPointer(PPrototype * proto, TArray && argflags, int scope) +{ + size_t bucket; + + PFunctionPointer::FlagsAndScope flags_and_scope { &argflags, scope }; + + PType *fn = TypeTable.FindType(NAME_Function, (intptr_t)proto, (intptr_t)&flags_and_scope, &bucket); + if (fn == nullptr) + { + fn = new PFunctionPointer(proto, std::move(argflags), scope); + flags_and_scope.ArgFlags = &static_cast(fn)->ArgFlags; + TypeTable.AddType(fn, NAME_Function, (intptr_t)proto, (intptr_t)&flags_and_scope, bucket); + } + return (PFunctionPointer *)fn; +} + /* PStruct ****************************************************************/ //========================================================================== @@ -3227,13 +3453,13 @@ size_t FTypeTable::Hash(FName p1, intptr_t p2, intptr_t p3) // to transform this into a ROR or ROL. i1 = (i1 >> (sizeof(size_t)*4)) | (i1 << (sizeof(size_t)*4)); - if (p1 != NAME_Prototype) + if (p1 != NAME_Prototype && p1 != NAME_Function) { size_t i2 = (size_t)p2; size_t i3 = (size_t)p3; return (~i1 ^ i2) + i3 * 961748927; // i3 is multiplied by a prime } - else + else if(p1 == NAME_Prototype) { // Prototypes need to hash the TArrays at p2 and p3 const TArray *a2 = (const TArray *)p2; const TArray *a3 = (const TArray *)p3; @@ -3247,6 +3473,18 @@ size_t FTypeTable::Hash(FName p1, intptr_t p2, intptr_t p3) } return i1; } + else // if(p1 == NAME_Function) + { // functions need custom hashing as well + size_t i2 = (size_t)p2; + const PFunctionPointer::FlagsAndScope * flags_and_scope = (const PFunctionPointer::FlagsAndScope *) p3; + const TArray * a3 = flags_and_scope->ArgFlags; + i1 = (~i1 ^ i2); + for (unsigned i = 0; i < a3->Size(); ++i) + { + i1 = (i1 * 961748927) + (size_t)((*a3)[i]); + } + return (i1 * 961748927) + (size_t)flags_and_scope->Scope; + } } //========================================================================== diff --git a/src/common/scripting/core/types.h b/src/common/scripting/core/types.h index 850c354a8..7fdd8706d 100644 --- a/src/common/scripting/core/types.h +++ b/src/common/scripting/core/types.h @@ -66,6 +66,7 @@ enum class PContainerType; class PPointer; class PClassPointer; +class PFunctionPointer; class PArray; class PStruct; class PClassType; @@ -86,6 +87,7 @@ protected: TYPE_ObjectPointer = 64, TYPE_ClassPointer = 128, TYPE_Array = 256, + TYPE_FunctionPointer = 512, TYPE_IntCompatible = TYPE_Int | TYPE_IntNotInt, // must be the combination of all flags that are subtypes of int and can be cast to an int. }; @@ -194,9 +196,10 @@ public: bool isIntCompatible() const { return !!(Flags & TYPE_IntCompatible); } bool isFloat() const { return !!(Flags & TYPE_Float); } bool isPointer() const { return !!(Flags & TYPE_Pointer); } - bool isRealPointer() const { return (Flags & (TYPE_Pointer|TYPE_ClassPointer)) == TYPE_Pointer; } // This excludes class pointers which use their PointedType differently + bool isRealPointer() const { return (Flags & (TYPE_Pointer | TYPE_ClassPointer | TYPE_FunctionPointer)) == TYPE_Pointer; } // This excludes class and function pointers which use their PointedType differently bool isObjectPointer() const { return !!(Flags & TYPE_ObjectPointer); } bool isClassPointer() const { return !!(Flags & TYPE_ClassPointer); } + bool isFunctionPointer() const { return !!(Flags & TYPE_FunctionPointer); } bool isEnum() const { return TypeTableType == NAME_Enum; } bool isArray() const { return !!(Flags & TYPE_Array); } bool isStaticArray() const { return TypeTableType == NAME_StaticArray; } @@ -210,6 +213,7 @@ public: PContainerType *toContainer() { return isContainer() ? (PContainerType*)this : nullptr; } PPointer *toPointer() { return isPointer() ? (PPointer*)this : nullptr; } static PClassPointer *toClassPointer(PType *t) { return t && t->isClassPointer() ? (PClassPointer*)t : nullptr; } + static PFunctionPointer *toFunctionPointer(PType *t) { return t && t->isFunctionPointer() ? (PFunctionPointer*)t : nullptr; } static PClassType *toClass(PType *t) { return t && t->isClass() ? (PClassType*)t : nullptr; } }; @@ -595,6 +599,31 @@ public: void DestroyValue(void *addr) const override; }; +class PFunctionPointer : public PPointer +{ +public: + //PointedType = PPrototype or TypeVoid + PFunctionPointer(PPrototype * proto, TArray &&argflags, int scope); + + TArray ArgFlags; + int Scope; + + PFunction *FakeFunction; // used for type checking in FxFunctionCall + + void WriteValue(FSerializer &ar, const char *key, const void *addr) const override; + bool ReadValue(FSerializer &ar, const char *key, void *addr) const override; + + + struct FlagsAndScope + { // used for IsMatch's id2 + TArray * ArgFlags; + int Scope; + }; + + bool IsMatch(intptr_t id1, intptr_t id2) const override; + void GetTypeIDs(intptr_t &id1, intptr_t &id2) const override; //NOT SUPPORTED +}; + class PStruct : public PContainerType { public: @@ -657,6 +686,7 @@ PMapIterator *NewMapIterator(PType *keytype, PType *valuetype); PArray *NewArray(PType *type, unsigned int count); PStaticArray *NewStaticArray(PType *type); PDynArray *NewDynArray(PType *type); +PFunctionPointer *NewFunctionPointer(PPrototype * proto, TArray && argflags, int scope); PPointer *NewPointer(PType *type, bool isconst = false); PPointer *NewPointer(PClass *type, bool isconst = false); PClassPointer *NewClassPointer(PClass *restrict); diff --git a/src/common/scripting/frontend/ast.cpp b/src/common/scripting/frontend/ast.cpp index 50e1c2e9f..2841c1643 100644 --- a/src/common/scripting/frontend/ast.cpp +++ b/src/common/scripting/frontend/ast.cpp @@ -521,6 +521,26 @@ static void PrintDynArrayType(FLispString &out, const ZCC_TreeNode *node) out.Close(); } +static void PrintFuncPtrParamDecl(FLispString &out, const ZCC_TreeNode *node) +{ + ZCC_FuncPtrParamDecl *dnode = (ZCC_FuncPtrParamDecl *)node; + out.Break(); + out.Open("func-ptr-param-decl"); + PrintNodes(out, dnode->Type); + out.AddHex(dnode->Flags); + out.Close(); +} + +static void PrintFuncPtrType(FLispString &out, const ZCC_TreeNode *node){ + ZCC_FuncPtrType *dnode = (ZCC_FuncPtrType *)node; + out.Break(); + out.Open("func-ptr-type"); + PrintNodes(out, dnode->RetType); + PrintNodes(out, dnode->Params); + out.AddHex(dnode->Scope); + out.Close(); +} + static void PrintClassType(FLispString &out, const ZCC_TreeNode *node) { ZCC_ClassType *tnode = (ZCC_ClassType *)node; @@ -628,6 +648,16 @@ static void PrintExprClassCast(FLispString &out, const ZCC_TreeNode *node) out.Close(); } +static void PrintExprFunctionPtrCast(FLispString &out, const ZCC_TreeNode *node) +{ + ZCC_FunctionPtrCast *enode = (ZCC_FunctionPtrCast *)node; + assert(enode->Operation == PEX_FunctionPtrCast); + out.Open("expr-func-ptr-cast"); + PrintNodes(out, enode->PtrType, false); + PrintNodes(out, enode->Expr, false); + out.Close(); +} + static void PrintStaticArray(FLispString &out, const ZCC_TreeNode *node) { ZCC_StaticArrayStatement *enode = (ZCC_StaticArrayStatement *)node; @@ -976,6 +1006,8 @@ static const NodePrinterFunc TreeNodePrinter[] = PrintMapType, PrintMapIteratorType, PrintDynArrayType, + PrintFuncPtrParamDecl, + PrintFuncPtrType, PrintClassType, PrintExpression, PrintExprID, @@ -1011,6 +1043,7 @@ static const NodePrinterFunc TreeNodePrinter[] = PrintVectorInitializer, PrintDeclFlags, PrintExprClassCast, + PrintExprFunctionPtrCast, PrintStaticArrayState, PrintProperty, PrintFlagDef, diff --git a/src/common/scripting/frontend/zcc-parse.lemon b/src/common/scripting/frontend/zcc-parse.lemon index 295c58dd9..a222afa60 100644 --- a/src/common/scripting/frontend/zcc-parse.lemon +++ b/src/common/scripting/frontend/zcc-parse.lemon @@ -988,6 +988,63 @@ aggregate_type(X) ::= ARRAY(T) LT type_or_array(A) GT. /* TArray */ X = arr; } +aggregate_type(X) ::= func_ptr_type(A). { X = A; /*X-overwrites-A*/ } + +%type func_ptr_type {ZCC_FuncPtrType *} +%type func_ptr_params {ZCC_FuncPtrParamDecl *} +%type func_ptr_param_list {ZCC_FuncPtrParamDecl *} +%type func_ptr_param {ZCC_FuncPtrParamDecl *} + +//fn_ptr_flag(X) ::= . { X.Int = 0; } //implicit scope not allowed +fn_ptr_flag(X) ::= UI. { X.Int = ZCC_UIFlag; } +fn_ptr_flag(X) ::= PLAY. { X.Int = ZCC_Play; } +fn_ptr_flag(X) ::= CLEARSCOPE. { X.Int = ZCC_ClearScope; } +//fn_ptr_flag(X) ::= VIRTUALSCOPE. { X.Int = ZCC_VirtualScope; } //virtual scope not allowed + + +func_ptr_type(X) ::= FNTYPE(T) LT fn_ptr_flag(F) type_list_or_void(A) LPAREN func_ptr_params(B) RPAREN GT. /* Function<...(...)> */ +{ + NEW_AST_NODE(FuncPtrType,fn_ptr,T); + fn_ptr->RetType = A; + fn_ptr->Params = B; + fn_ptr->Scope = F.Int; + X = fn_ptr; +} + +func_ptr_type(X) ::= FNTYPE(T) LT VOID GT. /* Function */ +{ + NEW_AST_NODE(FuncPtrType,fn_ptr,T); + fn_ptr->RetType = nullptr; + fn_ptr->Params = nullptr; + fn_ptr->Scope = -1; + X = fn_ptr; +} + +func_ptr_params(X) ::= . /* empty */ { X = NULL; } +func_ptr_params(X) ::= VOID. { X = NULL; } +func_ptr_params(X) ::= func_ptr_param_list(X). + +// varargs function pointers not currently supported +//func_ptr_params(X) ::= func_ptr_param_list(A) COMMA ELLIPSIS. +//{ +// NEW_AST_NODE(FuncPtrParamDecl,parm,stat->sc->GetMessageLine()); +// parm->Type = nullptr; +// parm->Flags = 0; +// X = A; /*X-overwrites-A*/ +// AppendTreeNodeSibling(X, parm); +//} + +func_ptr_param_list(X) ::= func_ptr_param(X). +func_ptr_param_list(X) ::= func_ptr_param_list(A) COMMA func_ptr_param(B). { X = A; /*X-overwrites-A*/ AppendTreeNodeSibling(X, B); } + +func_ptr_param(X) ::= func_param_flags(A) type(B). +{ + NEW_AST_NODE(FuncPtrParamDecl,parm,A.SourceLoc ? A.SourceLoc : B->SourceLoc); + parm->Type = B; + parm->Flags = A.Int; + X = parm; +} + aggregate_type(X) ::= CLASS(T) class_restrictor(A). /* class */ { NEW_AST_NODE(ClassType,cls,T); @@ -1408,6 +1465,17 @@ primary(X) ::= LPAREN CLASS LT IDENTIFIER(A) GT RPAREN LPAREN func_expr_list(B) expr->Parameters = B; X = expr; } + +primary(X) ::= LPAREN func_ptr_type(A) RPAREN LPAREN expr(B) RPAREN. [DOT] // function pointer type cast +{ + NEW_AST_NODE(FunctionPtrCast, expr, A); + expr->Operation = PEX_FunctionPtrCast; + A->ArraySize = NULL; + expr->PtrType = A; + expr->Expr = B; + X = expr; +} + primary(X) ::= primary(A) LBRACKET expr(B) RBRACKET. [DOT] // Array access { NEW_AST_NODE(ExprBinary, expr, B); @@ -1417,6 +1485,7 @@ primary(X) ::= primary(A) LBRACKET expr(B) RBRACKET. [DOT] // Array access expr->Right = B; X = expr; } + primary(X) ::= primary(A) DOT IDENTIFIER(B). // Member access { NEW_AST_NODE(ExprMemberAccess, expr, B); diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index 815af694b..c29a580a3 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -2024,6 +2024,52 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n } break; } + case AST_FuncPtrType: + { + auto fn = static_cast(ztype); + + if(fn->Scope == -1) + { // Function + retval = NewFunctionPointer(nullptr, {}, -1); + } + else + { + TArray returns; + TArray args; + TArray argflags; + + if(auto *t = fn->RetType; t != nullptr) do { + returns.Push(DetermineType(outertype, field, name, t, false, false)); + } while( (t = (ZCC_Type *)t->SiblingNext) != fn->RetType); + + if(auto *t = fn->Params; t != nullptr) do { + args.Push(DetermineType(outertype, field, name, t->Type, false, false)); + argflags.Push(t->Flags == ZCC_Out ? VARF_Out : 0); + } while( (t = (ZCC_FuncPtrParamDecl *) t->SiblingNext) != fn->Params); + + auto proto = NewPrototype(returns,args); + switch(fn->Scope) + { // only play/ui/clearscope functions are allowed, no data or virtual scope functions + case ZCC_Play: + fn->Scope = FScopeBarrier::Side_Play; + break; + case ZCC_UIFlag: + fn->Scope = FScopeBarrier::Side_UI; + break; + case ZCC_ClearScope: + fn->Scope = FScopeBarrier::Side_PlainData; + break; + case 0: + fn->Scope = -1; + break; + default: + Error(field, "Invalid Scope for Function Pointer"); + break; + } + retval = NewFunctionPointer(proto, std::move(argflags), fn->Scope); + } + break; + } case AST_ClassType: { auto ctype = static_cast(ztype); @@ -2992,6 +3038,17 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast, bool substitute) return new FxClassPtrCast(cls, ConvertNode(cc->Parameters)); } + case AST_FunctionPtrCast: + { + auto cast = static_cast(ast); + + auto type = DetermineType(ConvertClass, cast, NAME_None, cast->PtrType, false, false); + assert(type->isFunctionPointer()); + auto ptrType = static_cast(type); + + return new FxFunctionPtrCast(ptrType, ConvertNode(cast->Expr)); + } + case AST_StaticArrayStatement: { auto sas = static_cast(ast); diff --git a/src/common/scripting/frontend/zcc_exprlist.h b/src/common/scripting/frontend/zcc_exprlist.h index faf6af6a4..f05758379 100644 --- a/src/common/scripting/frontend/zcc_exprlist.h +++ b/src/common/scripting/frontend/zcc_exprlist.h @@ -9,6 +9,7 @@ xx(FuncCall, '(') xx(ArrayAccess, TK_Array) xx(MemberAccess, '.') xx(ClassCast, TK_Class) +xx(FunctionPtrCast, TK_FunctionType) xx(TypeRef, TK_Class) xx(Vector, TK_Vector2) diff --git a/src/common/scripting/frontend/zcc_parser.cpp b/src/common/scripting/frontend/zcc_parser.cpp index e689d4249..24b2ecb1f 100644 --- a/src/common/scripting/frontend/zcc_parser.cpp +++ b/src/common/scripting/frontend/zcc_parser.cpp @@ -222,6 +222,7 @@ static void InitTokenMap() TOKENDEF2(TK_Map, ZCC_MAP, NAME_Map); TOKENDEF2(TK_MapIterator, ZCC_MAPITERATOR,NAME_MapIterator); TOKENDEF2(TK_Array, ZCC_ARRAY, NAME_Array); + TOKENDEF2(TK_FunctionType, ZCC_FNTYPE, NAME_Function); TOKENDEF2(TK_Include, ZCC_INCLUDE, NAME_Include); TOKENDEF (TK_Void, ZCC_VOID); TOKENDEF (TK_True, ZCC_TRUE); @@ -925,6 +926,29 @@ ZCC_TreeNode *TreeNodeDeepCopy_Internal(ZCC_AST *ast, ZCC_TreeNode *orig, bool c break; } + case AST_FuncPtrParamDecl: + { + TreeNodeDeepCopy_Start(FuncPtrParamDecl); + + // ZCC_FuncPtrParamDecl + copy->Type = static_cast(TreeNodeDeepCopy_Internal(ast, origCasted->Type, true, copiedNodesList)); + copy->Flags = origCasted->Flags; + + break; + } + + case AST_FuncPtrType: + { + TreeNodeDeepCopy_Start(FuncPtrType); + + // ZCC_FuncPtrType + copy->RetType = static_cast(TreeNodeDeepCopy_Internal(ast, origCasted->RetType, true, copiedNodesList)); + copy->Params = static_cast(TreeNodeDeepCopy_Internal(ast, origCasted->Params, true, copiedNodesList)); + copy->Scope = origCasted->Scope; + + break; + } + case AST_ClassType: { TreeNodeDeepCopy_Start(ClassType); @@ -1371,7 +1395,21 @@ ZCC_TreeNode *TreeNodeDeepCopy_Internal(ZCC_AST *ast, ZCC_TreeNode *orig, bool c break; } + + case AST_FunctionPtrCast: + { + TreeNodeDeepCopy_Start(FunctionPtrCast); + // ZCC_Expression + copy->Operation = origCasted->Operation; + copy->Type = origCasted->Type; + // ZCC_FunctionPtrCast + copy->PtrType = static_cast(TreeNodeDeepCopy_Internal(ast, origCasted->PtrType, true, copiedNodesList)); + copy->Expr = static_cast(TreeNodeDeepCopy_Internal(ast, origCasted->Expr, true, copiedNodesList)); + + break; + } + case AST_StaticArrayStatement: { TreeNodeDeepCopy_Start(StaticArrayStatement); diff --git a/src/common/scripting/frontend/zcc_parser.h b/src/common/scripting/frontend/zcc_parser.h index e4e4ea363..c9c1a2933 100644 --- a/src/common/scripting/frontend/zcc_parser.h +++ b/src/common/scripting/frontend/zcc_parser.h @@ -101,6 +101,8 @@ enum EZCCTreeNodeType AST_MapType, AST_MapIteratorType, AST_DynArrayType, + AST_FuncPtrParamDecl, + AST_FuncPtrType, AST_ClassType, AST_Expression, AST_ExprID, @@ -136,6 +138,7 @@ enum EZCCTreeNodeType AST_VectorValue, AST_DeclFlags, AST_ClassCast, + AST_FunctionPtrCast, AST_StaticArrayStatement, AST_Property, AST_FlagDef, @@ -382,6 +385,19 @@ struct ZCC_DynArrayType : ZCC_Type ZCC_Type *ElementType; }; +struct ZCC_FuncPtrParamDecl : ZCC_TreeNode +{ + ZCC_Type *Type; + int Flags; +}; + +struct ZCC_FuncPtrType : ZCC_Type +{ + ZCC_Type *RetType; + ZCC_FuncPtrParamDecl *Params; + int Scope; +}; + struct ZCC_ClassType : ZCC_Type { ZCC_Identifier *Restriction; @@ -428,6 +444,12 @@ struct ZCC_ClassCast : ZCC_Expression ZCC_FuncParm *Parameters; }; +struct ZCC_FunctionPtrCast : ZCC_Expression +{ + ZCC_FuncPtrType *PtrType; + ZCC_Expression *Expr; +}; + struct ZCC_ExprMemberAccess : ZCC_Expression { ZCC_Expression *Left; diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index daed2f091..00e110b71 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -1348,3 +1348,35 @@ DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, Inverse, QuatInverse) QuatInverse(self->X, self->Y, self->Z, self->W, &quat); ACTION_RETURN_QUAT(quat); } + +PFunction * FindFunctionPointer(PClass * cls, int fn_name) +{ + auto fn = dyn_cast(cls->FindSymbol(ENamedName(fn_name), true)); + return (fn && fn->GetImplicitArgs() == 0) ? fn : nullptr; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DObject, FindFunction, FindFunctionPointer) +{ + PARAM_PROLOGUE; + PARAM_CLASS(cls, DObject); + PARAM_NAME(fn); + + ACTION_RETURN_POINTER(FindFunctionPointer(cls, fn.GetIndex())); +} + +/* +PFunction * FindMethodPointer(PClass * cls, int fn_name) +{ + auto fn = dyn_cast(cls->FindSymbol(ENamedName(fn_name), true)); + return (fn && fn->GetImplicitArgs() == 1) ? fn : nullptr; +} + +DEFINE_ACTION_FUNCTION_NATIVE(DObject, FindMethod, FindMethodPointer) +{ + PARAM_PROLOGUE; + PARAM_CLASS(cls, DObject); + PARAM_NAME(fn); + + ACTION_RETURN_POINTER(FindMethodPointer(cls, fn.GetIndex())); +} +*/ diff --git a/src/scripting/backend/codegen_doom.cpp b/src/scripting/backend/codegen_doom.cpp index f93422e30..7aa0474c8 100644 --- a/src/scripting/backend/codegen_doom.cpp +++ b/src/scripting/backend/codegen_doom.cpp @@ -309,7 +309,8 @@ static bool UnravelVarArgAJump(FxVMFunctionCall *func, FCompileContext &ctx) static bool AJumpProcessing(FxVMFunctionCall *func, FCompileContext &ctx) { // Unfortunately the PrintableName is the only safe thing to catch this special case here. - if (stricmp(func->Function->Variants[0].Implementation->QualifiedName, "Actor.A_Jump") == 0) + // [RL0] It's not valid to access Variant::Implementation on function pointer calls, so skip this + if (!func->FnPtrCall && stricmp(func->Function->Variants[0].Implementation->QualifiedName, "Actor.A_Jump") == 0) { // Unravel the varargs part of this function here so that the VM->native interface does not have to deal with it anymore. if (func->ArgList.Size() > 2) diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 409acc2e3..27888cca9 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -1,4 +1,4 @@ -version "4.10" +version "4.11" // Generic engine code #include "zscript/engine/base.zs" diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index 6b78ead56..bd89aae10 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -748,11 +748,15 @@ class Object native private native static void BuiltinRandomSeed(voidptr rng, int seed); private native static Class BuiltinNameToClass(Name nm, Class filter); private native static Object BuiltinClassCast(Object inptr, Class test); + private native static Function BuiltinFunctionPtrCast(Function inptr, voidptr newtype); native static uint MSTime(); native static double MSTimeF(); native vararg static void ThrowAbortException(String fmt, ...); + native static Function FindFunction(Class cls, Name fn); + //native static Method FindMethod(Class cls, Name fn); + native virtualscope void Destroy(); // This does not call into the native method of the same name to avoid problems with objects that get garbage collected late on shutdown. From 0ce4b3e7fb84dfa591b0b073f82b3a699198e290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Mon, 9 Oct 2023 13:44:20 -0300 Subject: [PATCH 211/223] update/cleanup function pointers --- src/common/engine/sc_man_scanner.re | 2 +- src/version.h | 10 +++++----- wadsrc/static/zscript.txt | 2 +- wadsrc/static/zscript/engine/base.zs | 1 - 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/common/engine/sc_man_scanner.re b/src/common/engine/sc_man_scanner.re index e5d507a28..8bca2ccc6 100644 --- a/src/common/engine/sc_man_scanner.re +++ b/src/common/engine/sc_man_scanner.re @@ -169,7 +169,7 @@ std2: 'map' { RET(TK_Map); } 'mapiterator' { RET(TK_MapIterator); } 'array' { RET(TK_Array); } - 'function' { RET(ParseVersion >= MakeVersion(4, 11, 0)? TK_FunctionType : TK_Identifier); } + 'function' { RET(ParseVersion >= MakeVersion(4, 12, 0)? TK_FunctionType : TK_Identifier); } 'in' { RET(TK_In); } 'sizeof' { RET(TK_SizeOf); } 'alignof' { RET(TK_AlignOf); } diff --git a/src/version.h b/src/version.h index e995dad82..722439183 100644 --- a/src/version.h +++ b/src/version.h @@ -41,20 +41,20 @@ const char *GetVersionString(); /** Lots of different version numbers **/ -#define VERSIONSTR "4.11pre" +#define VERSIONSTR "4.12pre" // The version as seen in the Windows resource -#define RC_FILEVERSION 4,10,9999,0 -#define RC_PRODUCTVERSION 4,10,9999,0 +#define RC_FILEVERSION 4,11,9999,0 +#define RC_PRODUCTVERSION 4,11,9999,0 #define RC_PRODUCTVERSION2 VERSIONSTR // These are for content versioning. #define VER_MAJOR 4 -#define VER_MINOR 11 +#define VER_MINOR 12 #define VER_REVISION 0 // This should always refer to the GZDoom version a derived port is based on and not reflect the derived port's version number! #define ENG_MAJOR 4 -#define ENG_MINOR 11 +#define ENG_MINOR 12 #define ENG_REVISION 0 // Version identifier for network games. diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 27888cca9..04331c388 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -1,4 +1,4 @@ -version "4.11" +version "4.12" // Generic engine code #include "zscript/engine/base.zs" diff --git a/wadsrc/static/zscript/engine/base.zs b/wadsrc/static/zscript/engine/base.zs index bd89aae10..c0754f705 100644 --- a/wadsrc/static/zscript/engine/base.zs +++ b/wadsrc/static/zscript/engine/base.zs @@ -755,7 +755,6 @@ class Object native native vararg static void ThrowAbortException(String fmt, ...); native static Function FindFunction(Class cls, Name fn); - //native static Method FindMethod(Class cls, Name fn); native virtualscope void Destroy(); From 23c21b23c397e5617d4d90bdd5589259a57ee1b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Mon, 9 Oct 2023 14:16:12 -0300 Subject: [PATCH 212/223] cleanup. --- src/common/scripting/interface/vmnatives.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index 00e110b71..87437832b 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -1364,19 +1364,3 @@ DEFINE_ACTION_FUNCTION_NATIVE(DObject, FindFunction, FindFunctionPointer) ACTION_RETURN_POINTER(FindFunctionPointer(cls, fn.GetIndex())); } -/* -PFunction * FindMethodPointer(PClass * cls, int fn_name) -{ - auto fn = dyn_cast(cls->FindSymbol(ENamedName(fn_name), true)); - return (fn && fn->GetImplicitArgs() == 1) ? fn : nullptr; -} - -DEFINE_ACTION_FUNCTION_NATIVE(DObject, FindMethod, FindMethodPointer) -{ - PARAM_PROLOGUE; - PARAM_CLASS(cls, DObject); - PARAM_NAME(fn); - - ACTION_RETURN_POINTER(FindMethodPointer(cls, fn.GetIndex())); -} -*/ From e61bd10bbfc5b1b58fb08e80ecb1728bdfcad05f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 11 Oct 2023 12:46:23 -0300 Subject: [PATCH 213/223] Finish implementing function pointers Allow using function literals with function pointers, allow narrowing classes parameter types, and widening classes in return types, allow pointers to non-static, non-virtual functions, add null checking to function calls --- src/common/scripting/backend/codegen.cpp | 229 +++++++++++++++++++++-- src/common/scripting/backend/codegen.h | 11 ++ src/common/scripting/core/types.cpp | 3 + src/common/scripting/core/types.h | 1 + src/common/scripting/core/vmdisasm.cpp | 3 + src/common/scripting/jit/jit_call.cpp | 5 + src/common/scripting/vm/vmexec.h | 9 + src/common/scripting/vm/vmops.h | 3 + 8 files changed, 244 insertions(+), 20 deletions(-) diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 49999ae68..2e4bb7e9e 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -268,6 +268,8 @@ PFunction *FindBuiltinFunction(FName funcname) // //========================================================================== +static bool AreCompatibleFnPtrTypes(PPrototype *to, PPrototype *from); + bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare) { if (dest->isPointer() && source->isPointer()) @@ -301,8 +303,9 @@ bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare) { auto from = static_cast(source); auto to = static_cast(dest); - return to->PointedType == TypeVoid || (from->PointedType == to->PointedType && from->ArgFlags == to->ArgFlags && FScopeBarrier::CheckSidesForFunctionPointer(from->Scope, to->Scope)); - // TODO allow narrowing argument types and widening return types via cast, ex.: Function)> to Function)> + if(from->PointedType == TypeVoid) return false; + + return to->PointedType == TypeVoid || (AreCompatibleFnPtrTypes((PPrototype *)to->PointedType, (PPrototype *)from->PointedType) && from->ArgFlags == to->ArgFlags && FScopeBarrier::CheckSidesForFunctionPointer(from->Scope, to->Scope)); } } return false; @@ -1615,6 +1618,35 @@ FxTypeCast::~FxTypeCast() // //========================================================================== +FxConstant * FxTypeCast::convertRawFunctionToFunctionPointer(FxExpression * in, FScriptPosition &ScriptPosition) +{ + assert(in->isConstant() && in->ValueType == TypeRawFunction); + FxConstant *val = static_cast(in); + PFunction * fn = static_cast(val->value.pointer); + if(fn && (fn->Variants[0].Flags & (VARF_Virtual | VARF_Action | VARF_Method)) == 0) + { + val->ValueType = val->value.Type = NewFunctionPointer(fn->Variants[0].Proto, TArray(fn->Variants[0].ArgFlags), FScopeBarrier::SideFromFlags(fn->Variants[0].Flags)); + return val; + } + else if(fn && (fn->Variants[0].Flags & (VARF_Virtual | VARF_Action | VARF_Method)) == VARF_Method) + { + TArray flags(fn->Variants[0].ArgFlags); + flags[0] = 0; + val->ValueType = val->value.Type = NewFunctionPointer(fn->Variants[0].Proto, std::move(flags), FScopeBarrier::SideFromFlags(fn->Variants[0].Flags)); + return val; + } + else if(!fn) + { + val->ValueType = val->value.Type = NewFunctionPointer(nullptr, {}, -1); // Function + return val; + } + else + { + ScriptPosition.Message(MSG_ERROR, "virtual/action function pointers are not allowed"); + return nullptr; + } +} + FxExpression *FxTypeCast::Resolve(FCompileContext &ctx) { CHECKRESOLVED(); @@ -1626,6 +1658,22 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx) if (result != this) return result; } + if (basex->isConstant() && basex->ValueType == TypeRawFunction && ValueType->isFunctionPointer()) + { + FxConstant *val = convertRawFunctionToFunctionPointer(basex, ScriptPosition); + if(!val) + { + delete this; + return nullptr; + } + } + else if (basex->isConstant() && basex->ValueType == TypeRawFunction && ValueType == TypeVMFunction) + { + FxConstant *val = static_cast(basex); + val->ValueType = val->value.Type = TypeVMFunction; + val->value.pointer = static_cast(val->value.pointer)->Variants[0].Implementation; + } + // first deal with the simple types if (ValueType == TypeError || basex->ValueType == TypeError || basex->ValueType == nullptr) { @@ -6370,9 +6418,8 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) if (ctx.Version >= MakeVersion(4, 11, 100)) { // VMFunction is only supported since 4.12 and Raze 1.8. - newex = new FxConstant(static_cast(sym)->Variants[0].Implementation, ScriptPosition); + newex = new FxConstant(static_cast(sym), ScriptPosition); goto foundit; - } } } @@ -6391,7 +6438,7 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) if (ctx.Version >= MakeVersion(4, 11, 100)) { // VMFunction is only supported since 4.12 and Raze 1.8. - newex = new FxConstant(static_cast(sym)->Variants[0].Implementation, ScriptPosition); + newex = new FxConstant(static_cast(sym), ScriptPosition); goto foundit; } } @@ -6539,7 +6586,6 @@ FxExpression *FxIdentifier::ResolveMember(FCompileContext &ctx, PContainerType * if (result != this) return result; } - if (objtype != nullptr && (sym = objtype->Symbols.FindSymbolInTable(Identifier, symtbl)) != nullptr) { if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst))) @@ -6755,7 +6801,7 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx) SAFE_RESOLVE(Object, ctx); - // check for class or struct constants if the left side is a type name. + // check for class or struct constants/functions if the left side is a type name. if (Object->ValueType == TypeError) { if (ccls != nullptr) @@ -6769,6 +6815,16 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx) delete this; return FxConstant::MakeConstant(sym, ScriptPosition); } + else if(sym->IsKindOf(RUNTIME_CLASS(PFunction))) + { + if (ctx.Version >= MakeVersion(4, 11, 100)) + { + // VMFunction is only supported since 4.12 and Raze 1.8. + auto x = new FxConstant(static_cast(sym), ScriptPosition); + delete this; + return x->Resolve(ctx); + } + } else { auto f = dyn_cast(sym); @@ -9604,6 +9660,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build) assert(Self != nullptr); selfemit = Self->Emit(build); assert(selfemit.RegType == REGT_POINTER); + build->Emit(OP_NULLCHECK, selfemit.RegNum, 0, 0); staticcall = false; } else staticcall = true; @@ -11704,11 +11761,118 @@ FxFunctionPtrCast::~FxFunctionPtrCast() // //========================================================================== +static bool AreCompatibleFnPtrs(PFunctionPointer * to, PFunctionPointer * from); + +bool CanNarrowTo(PClass * from, PClass * to) +{ + return from->IsAncestorOf(to); +} + +bool CanWidenTo(PClass * from, PClass * to) +{ + return to->IsAncestorOf(from); +} + +static bool AreCompatibleFnPtrTypes(PPrototype *to, PPrototype *from) +{ + if(to->ArgumentTypes.Size() != from->ArgumentTypes.Size() + || to->ReturnTypes.Size() != from->ReturnTypes.Size()) return false; + int n = to->ArgumentTypes.Size(); + + //allow narrowing of arguments + for(int i = 0; i < n; i++) + { + PType * fromType = from->ArgumentTypes[i]; + PType * toType = to->ArgumentTypes[i]; + if(fromType->isFunctionPointer() && toType->isFunctionPointer()) + { + if(!AreCompatibleFnPtrs(static_cast(toType), static_cast(fromType))) return false; + } + else if(fromType->isClassPointer() && toType->isClassPointer()) + { + PClassPointer * fromClass = static_cast(fromType); + PClassPointer * toClass = static_cast(toType); + //allow narrowing parameters + if(!CanNarrowTo(fromClass->ClassRestriction, toClass->ClassRestriction)) return false; + } + else if(fromType->isObjectPointer() && toType->isObjectPointer()) + { + PObjectPointer * fromObj = static_cast(fromType); + PObjectPointer * toObj = static_cast(toType); + //allow narrowing parameters + if(!CanNarrowTo(fromObj->PointedClass(), toObj->PointedClass())) return false; + } + else if(fromType != toType) + { + return false; + } + } + + n = to->ReturnTypes.Size(); + + for(int i = 0; i < n; i++) + { + PType * fromType = from->ReturnTypes[i]; + PType * toType = to->ReturnTypes[i]; + if(fromType->isFunctionPointer() && toType->isFunctionPointer()) + { + if(!AreCompatibleFnPtrs(static_cast(toType), static_cast(fromType))) return false; + } + else if(fromType->isClassPointer() && toType->isClassPointer()) + { + PClassPointer * fromClass = static_cast(fromType); + PClassPointer * toClass = static_cast(toType); + //allow widening returns + if(!CanWidenTo(fromClass->ClassRestriction, toClass->ClassRestriction)) return false; + } + else if(fromType->isObjectPointer() && toType->isObjectPointer()) + { + PObjectPointer * fromObj = static_cast(fromType); + PObjectPointer * toObj = static_cast(toType); + //allow widening returns + if(!CanWidenTo(fromObj->PointedClass(), toObj->PointedClass())) return false; + } + else if(fromType != toType) + { + return false; + } + } + return true; +} + +static bool AreCompatibleFnPtrs(PFunctionPointer * to, PFunctionPointer * from) +{ + if(to->PointedType == TypeVoid) return true; + else if(from->PointedType == TypeVoid) return false; + + PPrototype * toProto = (PPrototype *)to->PointedType; + PPrototype * fromProto = (PPrototype *)from->PointedType; + return + ( FScopeBarrier::CheckSidesForFunctionPointer(from->Scope, to->Scope) + /* + && toProto->ArgumentTypes == fromProto->ArgumentTypes + && toProto->ReturnTypes == fromProto->ReturnTypes + */ + && AreCompatibleFnPtrTypes(toProto, fromProto) + && to->ArgFlags == from->ArgFlags + ); +} + FxExpression *FxFunctionPtrCast::Resolve(FCompileContext &ctx) { CHECKRESOLVED(); SAFE_RESOLVE(basex, ctx); + if (basex->isConstant() && basex->ValueType == TypeRawFunction) + { + FxConstant *val = FxTypeCast::convertRawFunctionToFunctionPointer(basex, ScriptPosition); + if(!val) + { + delete this; + return nullptr; + } + } + if (!(basex->ValueType && basex->ValueType->isFunctionPointer())) { delete this; @@ -11717,21 +11881,20 @@ FxExpression *FxFunctionPtrCast::Resolve(FCompileContext &ctx) auto to = static_cast(ValueType); auto from = static_cast(basex->ValueType); - if(to->PointedType == TypeVoid) - { // no need to do anything for (FunctionPointedType == TypeVoid) + { // nothing to check at compile-time for casts from Function + return this; + } + else if(AreCompatibleFnPtrs(to, from)) + { // no need to do anything for (Function)(...) or compatible casts basex->ValueType = ValueType; auto x = basex; basex = nullptr; delete this; return x; } - else if(from->PointedType == TypeVoid) - { // nothing to check at compile-time for casts from Function - return this; - } else { - // TODO allow narrowing argument types and widening return types via cast, ex.: Function)> to Function)> ScriptPosition.Message(MSG_ERROR, "Cannot cast %s to %s. The types are incompatible.", basex->ValueType->DescriptiveName(), to->DescriptiveName()); delete this; return nullptr; @@ -11746,12 +11909,27 @@ FxExpression *FxFunctionPtrCast::Resolve(FCompileContext &ctx) PFunction *NativeFunctionPointerCast(PFunction *from, const PFunctionPointer *to) { - // TODO allow narrowing argument types and widening return types via cast, ex.: Function)> to Function)> - return (to->PointedType == TypeVoid || (from && - ( from->Variants[0].Proto == static_cast(to->PointedType) - && from->Variants[0].ArgFlags == to->ArgFlags - && FScopeBarrier::CheckSidesForFunctionPointer(FScopeBarrier::SideFromFlags(from->Variants[0].Flags), to->Scope) - ))) ? from : nullptr; + if(to->PointedType == TypeVoid) + { + return from; + } + else if(from && ((from->Variants[0].Flags & (VARF_Virtual | VARF_Action)) == 0) && FScopeBarrier::CheckSidesForFunctionPointer(FScopeBarrier::SideFromFlags(from->Variants[0].Flags), to->Scope)) + { + if(to->ArgFlags.Size() != from->Variants[0].ArgFlags.Size()) return nullptr; + int n = to->ArgFlags.Size(); + for(int i = from->GetImplicitArgs(); i < n; i++) // skip checking flags for implicit self + { + if(from->Variants[0].ArgFlags[i] != to->ArgFlags[i]) + { + return nullptr; + } + } + return AreCompatibleFnPtrTypes(static_cast(to->PointedType), from->Variants[0].Proto) ? from : nullptr; + } + else + { // cannot cast virtual/action functions to anything + return nullptr; + } } DEFINE_ACTION_FUNCTION_NATIVE(DObject, BuiltinFunctionPtrCast, NativeFunctionPointerCast) @@ -11841,6 +12019,17 @@ FxExpression *FxLocalVariableDeclaration::Resolve(FCompileContext &ctx) return nullptr; } SAFE_RESOLVE(Init, ctx); + + if(Init->isConstant() && Init->ValueType == TypeRawFunction) + { + FxConstant *val = FxTypeCast::convertRawFunctionToFunctionPointer(Init, ScriptPosition); + if(!val) + { + delete this; + return nullptr; + } + } + ValueType = Init->ValueType; if (ValueType->RegType == REGT_NIL) { diff --git a/src/common/scripting/backend/codegen.h b/src/common/scripting/backend/codegen.h index 2b2257a7a..6aff3b75d 100644 --- a/src/common/scripting/backend/codegen.h +++ b/src/common/scripting/backend/codegen.h @@ -513,6 +513,13 @@ public: ValueType = value.Type = TypeVMFunction; isresolved = true; } + + FxConstant(PFunction* rawptr, const FScriptPosition& pos) : FxExpression(EFX_Constant, pos) + { + value.pointer = rawptr; + ValueType = value.Type = TypeRawFunction; + isresolved = true; + } FxConstant(const FScriptPosition &pos) : FxExpression(EFX_Constant, pos) { @@ -558,6 +565,8 @@ public: return value; } ExpEmit Emit(VMFunctionBuilder *build); + + friend class FxTypeCast; }; //========================================================================== @@ -736,6 +745,8 @@ public: FxExpression *Resolve(FCompileContext&); ExpEmit Emit(VMFunctionBuilder *build); + + static FxConstant * convertRawFunctionToFunctionPointer(FxExpression * in, FScriptPosition &ScriptPosition); }; //========================================================================== diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index 0b9666e30..a2caeea3d 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -75,6 +75,7 @@ PStruct *TypeStringStruct; PStruct* TypeQuaternionStruct; PPointer *TypeNullPtr; PPointer *TypeVoidPtr; +PPointer *TypeRawFunction; PPointer* TypeVMFunction; @@ -323,6 +324,8 @@ void PType::StaticInit() TypeTable.AddType(TypeTextureID = new PTextureID, NAME_TextureID); TypeVoidPtr = NewPointer(TypeVoid, false); + TypeRawFunction = new PPointer; + TypeRawFunction->mDescriptiveName = "Raw Function Pointer"; TypeVMFunction = NewPointer(NewStruct("VMFunction", nullptr, true)); TypeColorStruct = NewStruct("@ColorStruct", nullptr); //This name is intentionally obfuscated so that it cannot be used explicitly. The point of this type is to gain access to the single channels of a color value. TypeStringStruct = NewStruct("Stringstruct", nullptr, true); diff --git a/src/common/scripting/core/types.h b/src/common/scripting/core/types.h index 7fdd8706d..d33840596 100644 --- a/src/common/scripting/core/types.h +++ b/src/common/scripting/core/types.h @@ -727,6 +727,7 @@ extern PPointer *TypeFont; extern PStateLabel *TypeStateLabel; extern PPointer *TypeNullPtr; extern PPointer *TypeVoidPtr; +extern PPointer* TypeRawFunction; extern PPointer* TypeVMFunction; diff --git a/src/common/scripting/core/vmdisasm.cpp b/src/common/scripting/core/vmdisasm.cpp index 86d566985..09524d3b5 100644 --- a/src/common/scripting/core/vmdisasm.cpp +++ b/src/common/scripting/core/vmdisasm.cpp @@ -46,6 +46,9 @@ #define LKP MODE_AP | MODE_BCJOINT | MODE_BCKP #define LFP MODE_AP | MODE_BUNUSED | MODE_CUNUSED + +#define RP MODE_AP | MODE_BUNUSED | MODE_CUNUSED + #define RIRPKI MODE_AI | MODE_BP | MODE_CKI #define RIRPRI MODE_AI | MODE_BP | MODE_CI #define RFRPKI MODE_AF | MODE_BP | MODE_CKI diff --git a/src/common/scripting/jit/jit_call.cpp b/src/common/scripting/jit/jit_call.cpp index d7074edc9..7154d9e27 100644 --- a/src/common/scripting/jit/jit_call.cpp +++ b/src/common/scripting/jit/jit_call.cpp @@ -719,3 +719,8 @@ asmjit::FuncSignature JitCompiler::CreateFuncSignature() signature.init(CallConv::kIdHost, rettype, cachedArgs->Data(), cachedArgs->Size()); return signature; } + +void JitCompiler::EmitNULLCHECK() +{ + EmitNullPointerThrow(A, X_READ_NIL); +} \ No newline at end of file diff --git a/src/common/scripting/vm/vmexec.h b/src/common/scripting/vm/vmexec.h index f1e0cb235..0d5737d25 100644 --- a/src/common/scripting/vm/vmexec.h +++ b/src/common/scripting/vm/vmexec.h @@ -1937,6 +1937,15 @@ static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret) CMPJMP(reg.a[B] == konsta[C].v); NEXTOP; + OP(NULLCHECK): + ASSERTA(a); + if (PA == nullptr) + { + ThrowAbortException(X_WRITE_NIL, nullptr); + return 0; + } + NEXTOP; + OP(NOP): NEXTOP; } diff --git a/src/common/scripting/vm/vmops.h b/src/common/scripting/vm/vmops.h index 1782e78b7..9280b746c 100644 --- a/src/common/scripting/vm/vmops.h +++ b/src/common/scripting/vm/vmops.h @@ -289,4 +289,7 @@ xx(SUBA, sub, RIRPRP, NOP, 0, 0) // dA = pB - pC xx(EQA_R, beq, CPRR, NOP, 0, 0) // if ((pB == pkC) != A) then pc++ xx(EQA_K, beq, CPRK, EQA_R, 4, REGT_POINTER) +// Null check +xx(NULLCHECK, nullcheck, RP, NOP, 0, 0) // EmitNullPointerThrow(pA) + #undef xx From d9a88d708097b3b9195e9c4fa191c4b29f13f1f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 11 Oct 2023 12:55:08 -0300 Subject: [PATCH 214/223] Fix deserialization of methods inside function pointers --- src/common/scripting/core/types.cpp | 43 +++++++++++++++-------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index a2caeea3d..72b80482b 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -2973,7 +2973,7 @@ bool PFunctionPointer::ReadValue(FSerializer &ar, const char *key, void *addr) c if(!p) { *fn = nullptr; - Printf(TEXTCOLOR_RED "Function Pointer (%s::%s): symbol '%s' in class '%s' is a variable, not a function\n", + Printf(TEXTCOLOR_RED "Function Pointer (%s::%s): '%s' in class '%s' is a variable, not a function\n", val.ClassName.GetChars(), val.FunctionName.GetChars(), val.FunctionName.GetChars(), @@ -2982,29 +2982,30 @@ bool PFunctionPointer::ReadValue(FSerializer &ar, const char *key, void *addr) c ar.mErrors++; return false; } - else if(p->GetImplicitArgs() > 0) - { - *fn = nullptr; - Printf(TEXTCOLOR_RED "Function Pointer (%s::%s): function '%s' in class '%s' is %s, not a static function\n", - val.ClassName.GetChars(), - val.FunctionName.GetChars(), - val.FunctionName.GetChars(), - val.ClassName.GetChars(), - (p->GetImplicitArgs() == 1 ? "a method" : "an action function") - ); - ar.mErrors++; - return false; - } *fn = NativeFunctionPointerCast(p, this); if(!*fn) { - FString fn_name = MakeFunctionPointerDescriptiveName(p->Variants[0].Proto,p->Variants[0].ArgFlags, FScopeBarrier::SideFromFlags(p->Variants[0].Flags)); - Printf(TEXTCOLOR_RED "Function Pointer (%s::%s) has incompatible type (Pointer is '%s', Function is '%s')\n", - val.ClassName.GetChars(), - val.FunctionName.GetChars(), - fn_name.GetChars(), - mDescriptiveName.GetChars() - ); + if((p->Variants[0].Flags & (VARF_Action | VARF_Virtual)) != 0) + { + *fn = nullptr; + Printf(TEXTCOLOR_RED "Function Pointer (%s::%s): function '%s' in class '%s' is %s, not a static function\n", + val.ClassName.GetChars(), + val.FunctionName.GetChars(), + val.FunctionName.GetChars(), + val.ClassName.GetChars(), + (p->GetImplicitArgs() == 1 ? "a virtual function" : "an action function") + ); + } + else + { + FString fn_name = MakeFunctionPointerDescriptiveName(p->Variants[0].Proto,p->Variants[0].ArgFlags, FScopeBarrier::SideFromFlags(p->Variants[0].Flags)); + Printf(TEXTCOLOR_RED "Function Pointer (%s::%s) has incompatible type (Pointer is '%s', Function is '%s')\n", + val.ClassName.GetChars(), + val.FunctionName.GetChars(), + fn_name.GetChars(), + mDescriptiveName.GetChars() + ); + } ar.mErrors++; return false; } From 0e9135132daa464134f735b91817ece8f946951e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 11 Oct 2023 13:01:57 -0300 Subject: [PATCH 215/223] Allow FindFunctionPointer to return non-virtual methods --- src/common/scripting/interface/vmnatives.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/scripting/interface/vmnatives.cpp b/src/common/scripting/interface/vmnatives.cpp index 87437832b..096722e76 100644 --- a/src/common/scripting/interface/vmnatives.cpp +++ b/src/common/scripting/interface/vmnatives.cpp @@ -54,6 +54,7 @@ #include "i_time.h" #include "maps.h" +#include "types.h" static ZSMap AllServices; @@ -1352,7 +1353,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(_QuatStruct, Inverse, QuatInverse) PFunction * FindFunctionPointer(PClass * cls, int fn_name) { auto fn = dyn_cast(cls->FindSymbol(ENamedName(fn_name), true)); - return (fn && fn->GetImplicitArgs() == 0) ? fn : nullptr; + return (fn && (fn->Variants[0].Flags & (VARF_Action | VARF_Virtual)) == 0 ) ? fn : nullptr; } DEFINE_ACTION_FUNCTION_NATIVE(DObject, FindFunction, FindFunctionPointer) From c935a95cb0c54537fe935f6999aebfbf8c4bb698 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Wed, 11 Oct 2023 13:03:32 -0300 Subject: [PATCH 216/223] Add function pointer Properties --- src/common/scripting/core/types.cpp | 6 ++ src/common/scripting/core/types.h | 2 + src/scripting/zscript/zcc_compile_doom.cpp | 79 ++++++++++++++++++++++ src/scripting/zscript/zcc_compile_doom.h | 1 + 4 files changed, 88 insertions(+) diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index 72b80482b..efe4dfec5 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -2883,6 +2883,12 @@ static FString MakeFunctionPointerDescriptiveName(PPrototype * proto,const TArra return mDescriptiveName; } + +FString PFunctionPointer::GenerateNameForError(const PFunction * from) +{ + return MakeFunctionPointerDescriptiveName(from->Variants[0].Proto, from->Variants[0].ArgFlags, FScopeBarrier::SideFromFlags(from->Variants[0].Flags)); +} + PFunctionPointer::PFunctionPointer(PPrototype * proto, TArray && argflags, int scope) : PPointer(proto ? (PType*) proto : TypeVoid, false), ArgFlags(std::move(argflags)), Scope(scope) { diff --git a/src/common/scripting/core/types.h b/src/common/scripting/core/types.h index d33840596..e24bcd38b 100644 --- a/src/common/scripting/core/types.h +++ b/src/common/scripting/core/types.h @@ -605,6 +605,8 @@ public: //PointedType = PPrototype or TypeVoid PFunctionPointer(PPrototype * proto, TArray &&argflags, int scope); + static FString GenerateNameForError(const PFunction * from); + TArray ArgFlags; int Scope; diff --git a/src/scripting/zscript/zcc_compile_doom.cpp b/src/scripting/zscript/zcc_compile_doom.cpp index 8c21659dc..4becfc4fe 100644 --- a/src/scripting/zscript/zcc_compile_doom.cpp +++ b/src/scripting/zscript/zcc_compile_doom.cpp @@ -70,6 +70,7 @@ int ZCCDoomCompiler::Compile() InitDefaults(); InitFunctions(); CompileStates(); + InitDefaultFunctionPointers(); return FScriptPosition::ErrorCounter; } @@ -395,6 +396,46 @@ void ZCCDoomCompiler::DispatchProperty(FPropertyInfo *prop, ZCC_PropertyStmt *pr // //========================================================================== +PFunction * FindFunctionPointer(PClass * cls, int fn_name); +PFunction *NativeFunctionPointerCast(PFunction *from, const PFunctionPointer *to); + +struct FunctionPointerProperties +{ + ZCC_PropertyStmt *prop; + PClass * cls; + FName name; + const PFunctionPointer * type; + PFunction ** addr; +}; + +TArray DefaultFunctionPointers; + +void ZCCDoomCompiler::InitDefaultFunctionPointers() +{ + for(auto &d : DefaultFunctionPointers) + { + PFunction * fn = FindFunctionPointer(d.cls, d.name.GetIndex()); + if(!fn) + { + Error(d.prop, "Could not find function '%s' in class '%s'",d.name.GetChars(), d.cls->TypeName.GetChars()); + } + else + { + PFunction * casted = NativeFunctionPointerCast(fn,d.type); + if(!casted) + { + FString fn_proto_name = PFunctionPointer::GenerateNameForError(fn); + Error(d.prop, "Function has incompatible types, cannot convert from '%s' to '%s'",fn_proto_name.GetChars(), d.type->DescriptiveName()); + } + else + { + (*d.addr) = casted; + } + } + } + DefaultFunctionPointers.Clear(); +} + void ZCCDoomCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *property, AActor *defaults, Baggage &bag) { ZCC_ExprConstant one; @@ -608,6 +649,44 @@ void ZCCDoomCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt * *(PClass**)addr = cls; } } + else if (f->Type->isFunctionPointer()) + { + const char * fn_str = GetStringConst(ex, ctx); + if (*fn_str == 0 || !stricmp(fn_str, "none")) + { + *(PFunction**)addr = nullptr; + } + else + { + TArray fn_info(FString(fn_str).Split("::", FString::TOK_SKIPEMPTY)); + if(fn_info.Size() != 2) + { + Error(property, "Malformed function pointer property \"%s\", must be \"Class::Function\"",fn_str); + } + PClass * cls = PClass::FindClass(fn_info[0]); + if(!cls) + { + Error(property, "Could not find class '%s'",fn_info[0].GetChars()); + *(PFunction**)addr = nullptr; + } + else + { + FName fn_name(fn_info[1], true); + if(fn_name.GetIndex() == 0) + { + Error(property, "Could not find function '%s' in class '%s'",fn_info[1].GetChars(),fn_info[0].GetChars()); + *(PFunction**)addr = nullptr; + } + else + { + DefaultFunctionPointers.Push({property, cls, fn_name, static_cast(f->Type), (PFunction**)addr}); + *(PFunction**)addr = nullptr; + } + + } + } + + } else { Error(property, "unhandled property type %s", f->Type->DescriptiveName()); diff --git a/src/scripting/zscript/zcc_compile_doom.h b/src/scripting/zscript/zcc_compile_doom.h index 36d7a4680..1fb894372 100644 --- a/src/scripting/zscript/zcc_compile_doom.h +++ b/src/scripting/zscript/zcc_compile_doom.h @@ -25,6 +25,7 @@ private: void ProcessDefaultProperty(PClassActor *cls, ZCC_PropertyStmt *prop, Baggage &bag); void ProcessDefaultFlag(PClassActor *cls, ZCC_FlagStmt *flg); void InitDefaults() override final; + void InitDefaultFunctionPointers(); FxExpression *SetupActionFunction(PClass *cls, ZCC_TreeNode *af, int StateFlags); void CompileStates(); int CheckActionKeyword(ZCC_FuncDeclarator *f, uint32_t &varflags, int useflags, ZCC_StructWork *c); From dccce46d5b89344703b153921869606e10b01318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sat, 7 Oct 2023 11:32:51 -0300 Subject: [PATCH 217/223] allow "&" instead of "out" in function pointer parameters --- src/common/scripting/frontend/zcc-parse.lemon | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/common/scripting/frontend/zcc-parse.lemon b/src/common/scripting/frontend/zcc-parse.lemon index a222afa60..347fddcc1 100644 --- a/src/common/scripting/frontend/zcc-parse.lemon +++ b/src/common/scripting/frontend/zcc-parse.lemon @@ -1045,6 +1045,14 @@ func_ptr_param(X) ::= func_param_flags(A) type(B). X = parm; } +func_ptr_param(X) ::= func_param_flags(A) type(B) AND. +{ + NEW_AST_NODE(FuncPtrParamDecl,parm,A.SourceLoc ? A.SourceLoc : B->SourceLoc); + parm->Type = B; + parm->Flags = A.Int | ZCC_Out; + X = parm; +} + aggregate_type(X) ::= CLASS(T) class_restrictor(A). /* class */ { NEW_AST_NODE(ClassType,cls,T); From bac12948e5f1a62b1820dc8d66e5fd1a8a503d8c Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sat, 14 Oct 2023 10:35:28 -0400 Subject: [PATCH 218/223] - add `forcecullbackfaces` in `modeldef` --- src/r_data/models.cpp | 4 ++++ src/r_data/models.h | 29 +++++++++++++------------- src/rendering/hwrenderer/hw_models.cpp | 4 ++-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/r_data/models.cpp b/src/r_data/models.cpp index ab632b34f..85f646b41 100644 --- a/src/r_data/models.cpp +++ b/src/r_data/models.cpp @@ -931,6 +931,10 @@ static void ParseModelDefLump(int Lump) { smf.flags |= MDL_CORRECTPIXELSTRETCH; } + else if (sc.Compare("forcecullbackfaces")) + { + smf.flags |= MDL_FORCECULLBACKFACES; + } else { sc.ScriptMessage("Unrecognized string \"%s\"", sc.String); diff --git a/src/r_data/models.h b/src/r_data/models.h index 568ad5399..b80550ab2 100644 --- a/src/r_data/models.h +++ b/src/r_data/models.h @@ -45,20 +45,21 @@ enum { // [BB] Color translations for the model skin are ignored. This is // useful if the skin texture is not using the game palette. - MDL_IGNORETRANSLATION = 1, - MDL_PITCHFROMMOMENTUM = 2, - MDL_ROTATING = 4, - MDL_INTERPOLATEDOUBLEDFRAMES = 8, - MDL_NOINTERPOLATION = 16, - MDL_USEACTORPITCH = 32, - MDL_USEACTORROLL = 64, - MDL_BADROTATION = 128, - MDL_DONTCULLBACKFACES = 256, - MDL_USEROTATIONCENTER = 512, - MDL_NOPERPIXELLIGHTING = 1024, // forces a model to not use per-pixel lighting. useful for voxel-converted-to-model objects. - MDL_SCALEWEAPONFOV = 2048, // scale weapon view model with higher user FOVs - MDL_MODELSAREATTACHMENTS = 4096, // any model index after 0 is treated as an attachment, and therefore will use the bone results of index 0 - MDL_CORRECTPIXELSTRETCH = 8192, // ensure model does not distort with pixel stretch when pitch/roll is applied + MDL_IGNORETRANSLATION = 1>>0, + MDL_PITCHFROMMOMENTUM = 1>>1, + MDL_ROTATING = 1>>2, + MDL_INTERPOLATEDOUBLEDFRAMES = 1>>3, + MDL_NOINTERPOLATION = 1>>4, + MDL_USEACTORPITCH = 1>>5, + MDL_USEACTORROLL = 1>>6, + MDL_BADROTATION = 1>>7, + MDL_DONTCULLBACKFACES = 1>>8, + MDL_USEROTATIONCENTER = 1>>9, + MDL_NOPERPIXELLIGHTING = 1>>10, // forces a model to not use per-pixel lighting. useful for voxel-converted-to-model objects. + MDL_SCALEWEAPONFOV = 1>11, // scale weapon view model with higher user FOVs + MDL_MODELSAREATTACHMENTS = 1>>12, // any model index after 0 is treated as an attachment, and therefore will use the bone results of index 0 + MDL_CORRECTPIXELSTRETCH = 1>>13, // ensure model does not distort with pixel stretch when pitch/roll is applied + MDL_FORCECULLBACKFACES = 1>>14, }; FSpriteModelFrame * FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped); diff --git a/src/rendering/hwrenderer/hw_models.cpp b/src/rendering/hwrenderer/hw_models.cpp index b0fb572be..733f54d2f 100644 --- a/src/rendering/hwrenderer/hw_models.cpp +++ b/src/rendering/hwrenderer/hw_models.cpp @@ -61,7 +61,7 @@ void FHWModelRenderer::BeginDrawModel(FRenderStyle style, FSpriteModelFrame *smf // This solves a few of the problems caused by the lack of depth sorting. // [Nash] Don't do back face culling if explicitly specified in MODELDEF // TO-DO: Implement proper depth sorting. - if (!(style == DefaultRenderStyle()) && !(smf->flags & MDL_DONTCULLBACKFACES)) + if ((smf->flags & MDL_FORCECULLBACKFACES) || (!(style == DefaultRenderStyle()) && !(smf->flags & MDL_DONTCULLBACKFACES))) { state.SetCulling((mirrored ^ portalState.isMirrored()) ? Cull_CCW : Cull_CW); } @@ -75,7 +75,7 @@ void FHWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) state.SetBoneIndexBase(-1); state.EnableModelMatrix(false); state.SetDepthFunc(DF_Less); - if (!(style == DefaultRenderStyle()) && !(smf->flags & MDL_DONTCULLBACKFACES)) + if ((smf->flags & MDL_FORCECULLBACKFACES) || (!(style == DefaultRenderStyle()) && !(smf->flags & MDL_DONTCULLBACKFACES))) state.SetCulling(Cull_None); } From e2a9208c568a084c9c0b24832c51fe367395c13c Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 15 Oct 2023 11:16:24 -0400 Subject: [PATCH 219/223] - fix error in last commit, >> should be << --- src/r_data/models.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/r_data/models.h b/src/r_data/models.h index b80550ab2..6f0e4d816 100644 --- a/src/r_data/models.h +++ b/src/r_data/models.h @@ -45,21 +45,21 @@ enum { // [BB] Color translations for the model skin are ignored. This is // useful if the skin texture is not using the game palette. - MDL_IGNORETRANSLATION = 1>>0, - MDL_PITCHFROMMOMENTUM = 1>>1, - MDL_ROTATING = 1>>2, - MDL_INTERPOLATEDOUBLEDFRAMES = 1>>3, - MDL_NOINTERPOLATION = 1>>4, - MDL_USEACTORPITCH = 1>>5, - MDL_USEACTORROLL = 1>>6, - MDL_BADROTATION = 1>>7, - MDL_DONTCULLBACKFACES = 1>>8, - MDL_USEROTATIONCENTER = 1>>9, - MDL_NOPERPIXELLIGHTING = 1>>10, // forces a model to not use per-pixel lighting. useful for voxel-converted-to-model objects. - MDL_SCALEWEAPONFOV = 1>11, // scale weapon view model with higher user FOVs - MDL_MODELSAREATTACHMENTS = 1>>12, // any model index after 0 is treated as an attachment, and therefore will use the bone results of index 0 - MDL_CORRECTPIXELSTRETCH = 1>>13, // ensure model does not distort with pixel stretch when pitch/roll is applied - MDL_FORCECULLBACKFACES = 1>>14, + MDL_IGNORETRANSLATION = 1<<0, + MDL_PITCHFROMMOMENTUM = 1<<1, + MDL_ROTATING = 1<<2, + MDL_INTERPOLATEDOUBLEDFRAMES = 1<<3, + MDL_NOINTERPOLATION = 1<<4, + MDL_USEACTORPITCH = 1<<5, + MDL_USEACTORROLL = 1<<6, + MDL_BADROTATION = 1<<7, + MDL_DONTCULLBACKFACES = 1<<8, + MDL_USEROTATIONCENTER = 1<<9, + MDL_NOPERPIXELLIGHTING = 1<<10, // forces a model to not use per-pixel lighting. useful for voxel-converted-to-model objects. + MDL_SCALEWEAPONFOV = 1<<11, // scale weapon view model with higher user FOVs + MDL_MODELSAREATTACHMENTS = 1<<12, // any model index after 0 is treated as an attachment, and therefore will use the bone results of index 0 + MDL_CORRECTPIXELSTRETCH = 1<<13, // ensure model does not distort with pixel stretch when pitch/roll is applied + MDL_FORCECULLBACKFACES = 1<<14, }; FSpriteModelFrame * FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped); From d699ba248e939c82e525e8c5785d26ff9ea093a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 15 Oct 2023 11:21:07 -0300 Subject: [PATCH 220/223] warn when fewer returns than expected are given for a function --- src/common/scripting/backend/codegen.cpp | 4 ++++ wadsrc/static/zscript/actors/inventory/stateprovider.zs | 4 ++-- wadsrc/static/zscript/doombase.zs | 6 ++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index 2e4bb7e9e..d3d0a7186 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -11330,6 +11330,10 @@ FxExpression *FxReturnStatement::Resolve(FCompileContext &ctx) { mismatchSeverity = MSG_ERROR; } + else if (protoRetCount > retCount) + { // also warn when returning less values then the return count + mismatchSeverity = MSG_WARNING; + } } if (mismatchSeverity != -1) diff --git a/wadsrc/static/zscript/actors/inventory/stateprovider.zs b/wadsrc/static/zscript/actors/inventory/stateprovider.zs index 21295c315..e02287258 100644 --- a/wadsrc/static/zscript/actors/inventory/stateprovider.zs +++ b/wadsrc/static/zscript/actors/inventory/stateprovider.zs @@ -210,7 +210,7 @@ class StateProvider : Inventory action Actor, Actor A_FireProjectile(class missiletype, double angle = 0, bool useammo = true, double spawnofs_xy = 0, double spawnheight = 0, int flags = 0, double pitch = 0) { let player = self.player; - if (!player) return null; + if (!player) return null, null; let weapon = player.ReadyWeapon; @@ -220,7 +220,7 @@ class StateProvider : Inventory if (useammo && weapon && stateinfo != null && stateinfo.mStateType == STATE_Psprite) { if (!weapon.DepleteAmmo(weapon.bAltFire, true)) - return null; // out of ammo + return null, null; // out of ammo } if (missiletype) diff --git a/wadsrc/static/zscript/doombase.zs b/wadsrc/static/zscript/doombase.zs index 1ff7cead3..f6c8dcb00 100644 --- a/wadsrc/static/zscript/doombase.zs +++ b/wadsrc/static/zscript/doombase.zs @@ -122,11 +122,13 @@ extend class Object native static double G_SkillPropertyFloat(int p); deprecated("3.8", "Use Level.PickDeathMatchStart() instead") static vector3, int G_PickDeathmatchStart() { - return level.PickDeathmatchStart(); + let [a,b] = level.PickDeathmatchStart(); + return a, b; } deprecated("3.8", "Use Level.PickPlayerStart() instead") static vector3, int G_PickPlayerStart(int pnum, int flags = 0) { - return level.PickPlayerStart(pnum, flags); + let [a,b] = level.PickPlayerStart(pnum, flags); + return a, b; } deprecated("4.3", "Use S_StartSound() instead") native static void S_Sound (Sound sound_id, int channel, float volume = 1, float attenuation = ATTN_NORM, float pitch = 0.0, float startTime = 0.0); native static void S_StartSound (Sound sound_id, int channel, int flags = 0, float volume = 1, float attenuation = ATTN_NORM, float pitch = 0.0, float startTime = 0.0); From 1957c15a41d4b90c2b6aa624b5559ee950e1eb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Lu=C3=ADs=20Vaz=20Silva?= Date: Sun, 15 Oct 2023 12:23:13 -0300 Subject: [PATCH 221/223] give error instead of warning for zscript 4.12+ on return count mismatch --- src/common/scripting/backend/codegen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/scripting/backend/codegen.cpp b/src/common/scripting/backend/codegen.cpp index d3d0a7186..2fcdb118b 100644 --- a/src/common/scripting/backend/codegen.cpp +++ b/src/common/scripting/backend/codegen.cpp @@ -11332,7 +11332,7 @@ FxExpression *FxReturnStatement::Resolve(FCompileContext &ctx) } else if (protoRetCount > retCount) { // also warn when returning less values then the return count - mismatchSeverity = MSG_WARNING; + mismatchSeverity = ctx.Version >= MakeVersion(4, 12) ? MSG_ERROR : MSG_WARNING; } } From d65d1a3b8266c0703b69a19626b9736be6695c49 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 17 Oct 2023 20:54:04 +0200 Subject: [PATCH 222/223] minor backend update from Raze. --- src/common/objects/dobjgc.h | 5 +++++ src/common/utility/geometry.h | 1 + src/common/utility/tarray.h | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/src/common/objects/dobjgc.h b/src/common/objects/dobjgc.h index a844a16db..25e27bfb3 100644 --- a/src/common/objects/dobjgc.h +++ b/src/common/objects/dobjgc.h @@ -282,6 +282,11 @@ public: return GC::ReadBarrier(o) == u; } + constexpr bool operator==(TObjPtr u) noexcept + { + return ForceGet() == u.ForceGet(); + } + template friend inline void GC::Mark(TObjPtr &obj); template friend FSerializer &Serialize(FSerializer &arc, const char *key, TObjPtr &value, TObjPtr *); template friend FSerializer &Serialize(FSerializer &arc, const char *key, TObjPtr &value, U *); diff --git a/src/common/utility/geometry.h b/src/common/utility/geometry.h index cbe0fc72d..e6b19db38 100644 --- a/src/common/utility/geometry.h +++ b/src/common/utility/geometry.h @@ -232,3 +232,4 @@ inline bool BoxInRange(const DVector2& boxtl, const DVector2& boxbr, const DVect boxtl.Y < max(start.Y, end.Y) && boxbr.Y > min(start.Y, end.Y); } + diff --git a/src/common/utility/tarray.h b/src/common/utility/tarray.h index 760dd6092..e60772688 100644 --- a/src/common/utility/tarray.h +++ b/src/common/utility/tarray.h @@ -455,6 +455,13 @@ public: return start; } + unsigned AddUnique(const T& obj) + { + auto f = Find(obj); + if (f == Size()) Push(obj); + return f; + } + bool Pop () { if (Count > 0) From 9cd57faec1b5e625bb6ffd93d80d97f5be0fd76c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 19 Oct 2023 18:35:51 +0200 Subject: [PATCH 223/223] rewrite of HWWalls to allow grabbing the output from the render item generator. --- src/rendering/hwrenderer/scene/hw_bsp.cpp | 7 +- src/rendering/hwrenderer/scene/hw_drawinfo.h | 1 - .../hwrenderer/scene/hw_drawstructs.h | 174 ++++---- .../hwrenderer/scene/hw_lighting.cpp | 2 +- .../hwrenderer/scene/hw_renderhacks.cpp | 4 +- src/rendering/hwrenderer/scene/hw_sky.cpp | 41 +- .../hwrenderer/scene/hw_walldispatcher.h | 80 ++++ src/rendering/hwrenderer/scene/hw_walls.cpp | 421 ++++++++++-------- 8 files changed, 431 insertions(+), 299 deletions(-) create mode 100644 src/rendering/hwrenderer/scene/hw_walldispatcher.h diff --git a/src/rendering/hwrenderer/scene/hw_bsp.cpp b/src/rendering/hwrenderer/scene/hw_bsp.cpp index 4110063e8..c79e34110 100644 --- a/src/rendering/hwrenderer/scene/hw_bsp.cpp +++ b/src/rendering/hwrenderer/scene/hw_bsp.cpp @@ -42,6 +42,7 @@ #include "hw_clock.h" #include "flatvertices.h" #include "hw_vertexbuilder.h" +#include "hw_walldispatcher.h" #ifdef ARCH_IA32 #include @@ -105,6 +106,7 @@ static RenderJobQueue jobQueue; // One static queue is sufficient here. This cod void HWDrawInfo::WorkerThread() { sector_t *front, *back; + HWWallDispatcher disp(this); WTTotal.Clock(); isWorkerThread = true; // for adding asserts in GL API code. The worker thread may never call any GL API. @@ -169,7 +171,7 @@ void HWDrawInfo::WorkerThread() } else back = nullptr; - wall.Process(this, job->seg, front, back); + wall.Process(&disp, job->seg, front, back); rendered_lines++; SetupWall.Unclock(); break; @@ -348,9 +350,10 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip) else { HWWall wall; + HWWallDispatcher disp(this); SetupWall.Clock(); wall.sub = seg->Subsector; - wall.Process(this, seg, currentsector, backsector); + wall.Process(&disp, seg, currentsector, backsector); rendered_lines++; SetupWall.Unclock(); } diff --git a/src/rendering/hwrenderer/scene/hw_drawinfo.h b/src/rendering/hwrenderer/scene/hw_drawinfo.h index 68afcb246..af043f035 100644 --- a/src/rendering/hwrenderer/scene/hw_drawinfo.h +++ b/src/rendering/hwrenderer/scene/hw_drawinfo.h @@ -214,7 +214,6 @@ private: int CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor); PalEntry CalcLightColor(int light, PalEntry pe, int blendfactor); float GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor); - bool CheckFog(sector_t *frontsector, sector_t *backsector); WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &pos, int cm, area_t in_area, const DVector3 &playerpos); void PreparePlayerSprites2D(sector_t * viewsector, area_t in_area); diff --git a/src/rendering/hwrenderer/scene/hw_drawstructs.h b/src/rendering/hwrenderer/scene/hw_drawstructs.h index 1ccd2603d..af65baf09 100644 --- a/src/rendering/hwrenderer/scene/hw_drawstructs.h +++ b/src/rendering/hwrenderer/scene/hw_drawstructs.h @@ -13,6 +13,8 @@ #pragma warning(disable:4244) #endif +bool CheckFog(FLevelLocals* Level, sector_t* frontsector, sector_t* backsector, ELightMode lightmode); + struct HWHorizonInfo; struct HWSkyInfo; struct F3DFloor; @@ -113,6 +115,11 @@ struct texcoord }; struct HWDrawInfo; +class HWWall; + +// this only exists to keep HWWallDispatcher trivial + +struct HWWallDispatcher; class HWWall { @@ -121,13 +128,13 @@ public: enum { - HWF_CLAMPX=1, - HWF_CLAMPY=2, - HWF_SKYHACK=4, - HWF_GLOW=8, // illuminated by glowing flats - HWF_NOSPLITUPPER=16, - HWF_NOSPLITLOWER=32, - HWF_NOSPLIT=64, + HWF_CLAMPX = 1, + HWF_CLAMPY = 2, + HWF_SKYHACK = 4, + HWF_GLOW = 8, // illuminated by glowing flats + HWF_NOSPLITUPPER = 16, + HWF_NOSPLITLOWER = 32, + HWF_NOSPLIT = 64, HWF_TRANSLUCENT = 128, HWF_NOSLICE = 256 }; @@ -151,13 +158,13 @@ public: friend struct HWDrawList; friend class HWPortal; - vertex_t * vertexes[2]; // required for polygon splitting - FGameTexture *texture; - TArray *lightlist; - LightmapSurface *lightmap; + vertex_t* vertexes[2]; // required for polygon splitting + FGameTexture* texture; + TArray* lightlist; + LightmapSurface* lightmap; HWSeg glseg; - float ztop[2],zbottom[2]; + float ztop[2], zbottom[2]; texcoord tcs[4]; texcoord lightuv[4]; float lindex; @@ -165,7 +172,7 @@ public: FColormap Colormap; ERenderStyle RenderStyle; - + float ViewDistance; short lightlevel; @@ -181,12 +188,17 @@ public: union { // it's either one of them but never more! - FSectorPortal *secportal; // sector portal (formerly skybox) - HWSkyInfo * sky; // for normal sky - HWHorizonInfo * horizon; // for horizon information - FSectorPortalGroup * portal; // stacked sector portals - secplane_t * planemirror; // for plane mirrors - FLinePortalSpan *lineportal; // line-to-line portals + FSectorPortal* secportal; // sector portal (formerly skybox) + HWSkyInfo* sky; // for normal sky + HWHorizonInfo* horizon; // for horizon information + FSectorPortalGroup* portal; // stacked sector portals + secplane_t* planemirror; // for plane mirrors + FLinePortalSpan* lineportal; // line-to-line portals + struct + { + int portaltype; // for the mesh builder. Real portals can only be assigned when being rendered. + int portalplane; + }; }; @@ -199,92 +211,92 @@ public: unsigned int vertcount; public: - seg_t * seg; // this gives the easiest access to all other structs involved - subsector_t * sub; // For polyobjects - sector_t *frontsector, *backsector; -//private: + seg_t* seg; // this gives the easiest access to all other structs involved + subsector_t* sub; // For polyobjects + sector_t* frontsector, * backsector; + //private: - void PutWall(HWDrawInfo *di, bool translucent); - void PutPortal(HWDrawInfo *di, int ptype, int plane); - void CheckTexturePosition(FTexCoordInfo *tci); + void PutWall(HWWallDispatcher* di, bool translucent); + void PutPortal(HWWallDispatcher* di, int ptype, int plane); + void CheckTexturePosition(FTexCoordInfo* tci); - void Put3DWall(HWDrawInfo *di, lightlist_t * lightlist, bool translucent); - bool SplitWallComplex(HWDrawInfo *di, sector_t * frontsector, bool translucent, float& maplightbottomleft, float& maplightbottomright); - void SplitWall(HWDrawInfo *di, sector_t * frontsector, bool translucent); + void Put3DWall(HWWallDispatcher* di, lightlist_t* lightlist, bool translucent); + bool SplitWallComplex(HWWallDispatcher* di, sector_t* frontsector, bool translucent, float& maplightbottomleft, float& maplightbottomright); + void SplitWall(HWWallDispatcher* di, sector_t* frontsector, bool translucent); - void SetupLights(HWDrawInfo *di, FDynLightData &lightdata); + void SetupLights(HWDrawInfo* di, FDynLightData& lightdata); - void MakeVertices(HWDrawInfo *di, bool nosplit); + void MakeVertices(HWDrawInfo* di, bool nosplit); - void SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowmirror); - void SkyLine(HWDrawInfo *di, sector_t *sec, line_t *line); - void SkyNormal(HWDrawInfo *di, sector_t * fs,vertex_t * v1,vertex_t * v2); - void SkyTop(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2); - void SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2); + void SkyPlane(HWWallDispatcher* di, sector_t* sector, int plane, bool allowmirror); + void SkyLine(HWWallDispatcher* di, sector_t* sec, line_t* line); + void SkyNormal(HWWallDispatcher* di, sector_t* fs, vertex_t* v1, vertex_t* v2); + void SkyTop(HWWallDispatcher* di, seg_t* seg, sector_t* fs, sector_t* bs, vertex_t* v1, vertex_t* v2); + void SkyBottom(HWWallDispatcher* di, seg_t* seg, sector_t* fs, sector_t* bs, vertex_t* v1, vertex_t* v2); - bool DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2); + bool DoHorizon(HWWallDispatcher* di, seg_t* seg, sector_t* fs, vertex_t* v1, vertex_t* v2); - bool SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float ceilingrefheight, + bool SetWallCoordinates(seg_t* seg, FTexCoordInfo* tci, float ceilingrefheight, float topleft, float topright, float bottomleft, float bottomright, float t_ofs); - void DoTexture(HWDrawInfo *di, int type,seg_t * seg,int peg, - float ceilingrefheight, float floorrefheight, - float CeilingHeightstart,float CeilingHeightend, - float FloorHeightstart,float FloorHeightend, - float v_offset); + void DoTexture(HWWallDispatcher* di, int type, seg_t* seg, int peg, + float ceilingrefheight, float floorrefheight, + float CeilingHeightstart, float CeilingHeightend, + float FloorHeightstart, float FloorHeightend, + float v_offset); - void DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, - sector_t * front, sector_t * back, - sector_t * realfront, sector_t * realback, - float fch1, float fch2, float ffh1, float ffh2, - float bch1, float bch2, float bfh1, float bfh2, float zalign); + void DoMidTexture(HWWallDispatcher* di, seg_t* seg, bool drawfogboundary, + sector_t* front, sector_t* back, + sector_t* realfront, sector_t* realback, + float fch1, float fch2, float ffh1, float ffh2, + float bch1, float bch2, float bfh1, float bfh2, float zalign); - void GetPlanePos(F3DFloor::planeref * planeref, float & left, float & right); + void GetPlanePos(F3DFloor::planeref* planeref, float& left, float& right); - void BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover, int roverIndex, - float ff_topleft, float ff_topright, - float ff_bottomleft, float ff_bottomright); - void InverseFloors(HWDrawInfo *di, seg_t * seg, sector_t * frontsector, - float topleft, float topright, - float bottomleft, float bottomright); - void ClipFFloors(HWDrawInfo *di, seg_t * seg, F3DFloor * ffloor, int ffloorIndex, sector_t * frontsector, - float topleft, float topright, - float bottomleft, float bottomright); - void DoFFloorBlocks(HWDrawInfo *di, seg_t * seg, sector_t * frontsector, sector_t * backsector, - float fch1, float fch2, float ffh1, float ffh2, - float bch1, float bch2, float bfh1, float bfh2); + void BuildFFBlock(HWWallDispatcher* di, seg_t* seg, F3DFloor* rover, int roverIndex, + float ff_topleft, float ff_topright, + float ff_bottomleft, float ff_bottomright); + void InverseFloors(HWWallDispatcher* di, seg_t* seg, sector_t* frontsector, + float topleft, float topright, + float bottomleft, float bottomright); + void ClipFFloors(HWWallDispatcher* di, seg_t* seg, F3DFloor* ffloor, int ffloorIndex, sector_t* frontsector, + float topleft, float topright, + float bottomleft, float bottomright); + void DoFFloorBlocks(HWWallDispatcher* di, seg_t* seg, sector_t* frontsector, sector_t* backsector, + float fch1, float fch2, float ffh1, float ffh2, + float bch1, float bch2, float bfh1, float bfh2); - void ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &normal); - void ProcessDecals(HWDrawInfo *di); + void ProcessDecal(HWDrawInfo* di, DBaseDecal* decal, const FVector3& normal); + void ProcessDecals(HWDrawInfo* di); - int CreateVertices(FFlatVertex *&ptr, bool nosplit); - void SplitLeftEdge (FFlatVertex *&ptr); - void SplitRightEdge(FFlatVertex *&ptr); - void SplitUpperEdge(FFlatVertex *&ptr); - void SplitLowerEdge(FFlatVertex *&ptr); + int CreateVertices(FFlatVertex*& ptr, bool nosplit); + void SplitLeftEdge(FFlatVertex*& ptr); + void SplitRightEdge(FFlatVertex*& ptr); + void SplitUpperEdge(FFlatVertex*& ptr); + void SplitLowerEdge(FFlatVertex*& ptr); - void CountLeftEdge (unsigned &ptr); - void CountRightEdge(unsigned &ptr); + void CountLeftEdge(unsigned& ptr); + void CountRightEdge(unsigned& ptr); int CountVertices(); - void RenderWall(HWDrawInfo *di, FRenderState &state, int textured); - void RenderFogBoundary(HWDrawInfo *di, FRenderState &state); - void RenderMirrorSurface(HWDrawInfo *di, FRenderState &state); - void RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags); - void RenderTranslucentWall(HWDrawInfo *di, FRenderState &state); - void DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArray &decals); + void RenderWall(HWDrawInfo* di, FRenderState& state, int textured); + void RenderFogBoundary(HWDrawInfo* di, FRenderState& state); + void RenderMirrorSurface(HWDrawInfo* di, FRenderState& state); + void RenderTexturedWall(HWDrawInfo* di, FRenderState& state, int rflags); + void RenderTranslucentWall(HWDrawInfo* di, FRenderState& state); + void DrawDecalsForMirror(HWDrawInfo* di, FRenderState& state, TArray& decals); public: - void Process(HWDrawInfo *di, seg_t *seg, sector_t *frontsector, sector_t *backsector); - void ProcessLowerMiniseg(HWDrawInfo *di, seg_t *seg, sector_t *frontsector, sector_t *backsector); + void Process(HWWallDispatcher* di, seg_t* seg, sector_t* frontsector, sector_t* backsector); + void ProcessLowerMiniseg(HWWallDispatcher* di, seg_t* seg, sector_t* frontsector, sector_t* backsector); - float PointOnSide(float x,float y) + float PointOnSide(float x, float y) { - return -((y-glseg.y1)*(glseg.x2-glseg.x1)-(x-glseg.x1)*(glseg.y2-glseg.y1)); + return -((y - glseg.y1) * (glseg.x2 - glseg.x1) - (x - glseg.x1) * (glseg.y2 - glseg.y1)); } - void DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent); + void DrawWall(HWDrawInfo* di, FRenderState& state, bool translucent); }; diff --git a/src/rendering/hwrenderer/scene/hw_lighting.cpp b/src/rendering/hwrenderer/scene/hw_lighting.cpp index ca8fa546d..84cf1dc13 100644 --- a/src/rendering/hwrenderer/scene/hw_lighting.cpp +++ b/src/rendering/hwrenderer/scene/hw_lighting.cpp @@ -227,7 +227,7 @@ float HWDrawInfo::GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfog // //========================================================================== -bool HWDrawInfo::CheckFog(sector_t *frontsector, sector_t *backsector) +bool CheckFog(FLevelLocals* Level, sector_t *frontsector, sector_t *backsector, ELightMode lightmode) { if (frontsector == backsector) return false; // there can't be a boundary if both sides are in the same sector. diff --git a/src/rendering/hwrenderer/scene/hw_renderhacks.cpp b/src/rendering/hwrenderer/scene/hw_renderhacks.cpp index d0775d109..6cb221752 100644 --- a/src/rendering/hwrenderer/scene/hw_renderhacks.cpp +++ b/src/rendering/hwrenderer/scene/hw_renderhacks.cpp @@ -41,6 +41,7 @@ #include "hw_lightbuffer.h" #include "hwrenderer/scene/hw_portal.h" #include "hw_fakeflat.h" +#include "hw_walldispatcher.h" //========================================================================== // @@ -1117,7 +1118,8 @@ void HWDrawInfo::ProcessLowerMinisegs(TArray &lowersegs) { seg_t * seg=lowersegs[j]; HWWall wall; - wall.ProcessLowerMiniseg(this, seg, seg->Subsector->render_sector, seg->PartnerSeg->Subsector->render_sector); + HWWallDispatcher disp(this); + wall.ProcessLowerMiniseg(&disp, seg, seg->Subsector->render_sector, seg->PartnerSeg->Subsector->render_sector); rendered_lines++; } } diff --git a/src/rendering/hwrenderer/scene/hw_sky.cpp b/src/rendering/hwrenderer/scene/hw_sky.cpp index 0af7309b2..830bb7b9c 100644 --- a/src/rendering/hwrenderer/scene/hw_sky.cpp +++ b/src/rendering/hwrenderer/scene/hw_sky.cpp @@ -33,6 +33,7 @@ #include "hwrenderer/scene/hw_portal.h" #include "hw_lighting.h" #include "hw_material.h" +#include "hw_walldispatcher.h" CVAR(Bool,gl_noskyboxes, false, 0) @@ -111,7 +112,7 @@ void HWSkyInfo::init(HWDrawInfo *di, int sky1, PalEntry FadeColor) // //========================================================================== -void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowreflect) +void HWWall::SkyPlane(HWWallDispatcher *di, sector_t *sector, int plane, bool allowreflect) { int ptype = -1; @@ -121,10 +122,13 @@ void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowref // Either a regular sky or a skybox with skyboxes disabled if ((sportal == nullptr && sector->GetTexture(plane) == skyflatnum) || (gl_noskyboxes && sportal != nullptr && sportal->mType == PORTS_SKYVIEWPOINT)) { - HWSkyInfo skyinfo; - skyinfo.init(di, sector->sky, Colormap.FadeColor); - ptype = PORTALTYPE_SKY; - sky = &skyinfo; + if (di->di) + { + HWSkyInfo skyinfo; + skyinfo.init(di->di, sector->sky, Colormap.FadeColor); + ptype = PORTALTYPE_SKY; + sky = &skyinfo; + } PutPortal(di, ptype, plane); } else if (sportal != nullptr) @@ -140,7 +144,7 @@ void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowref { if (sector->PortalBlocksView(plane)) return; - if (screen->instack[1 - plane]) return; + if (di->di && screen->instack[1 - plane]) return; ptype = PORTALTYPE_SECTORSTACK; portal = glport; } @@ -157,11 +161,14 @@ void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowref } else if (allowreflect && sector->GetReflect(plane) > 0 && !(di->Level->ib_compatflags & BCOMPATF_NOMIRRORS)) { - auto vpz = di->Viewpoint.Pos.Z; - if ((plane == sector_t::ceiling && vpz > sector->ceilingplane.fD()) || - (plane == sector_t::floor && vpz < -sector->floorplane.fD())) return; + if (di->di) + { + auto vpz = di->di->Viewpoint.Pos.Z; + if ((plane == sector_t::ceiling && vpz > sector->ceilingplane.fD()) || + (plane == sector_t::floor && vpz < -sector->floorplane.fD())) return; + planemirror = plane == sector_t::ceiling ? §or->ceilingplane : §or->floorplane; + } ptype = PORTALTYPE_PLANEMIRROR; - planemirror = plane == sector_t::ceiling ? §or->ceilingplane : §or->floorplane; } if (ptype != -1) { @@ -176,7 +183,7 @@ void HWWall::SkyPlane(HWDrawInfo *di, sector_t *sector, int plane, bool allowref // //========================================================================== -void HWWall::SkyLine(HWDrawInfo *di, sector_t *fs, line_t *line) +void HWWall::SkyLine(HWWallDispatcher *di, sector_t *fs, line_t *line) { FSectorPortal *secport = line->GetTransferredPortal(); HWSkyInfo skyinfo; @@ -192,7 +199,7 @@ void HWWall::SkyLine(HWDrawInfo *di, sector_t *fs, line_t *line) } else { - skyinfo.init(di, fs->sky, Colormap.FadeColor); + if (di->di) skyinfo.init(di->di, fs->sky, Colormap.FadeColor); ptype = PORTALTYPE_SKY; sky = &skyinfo; } @@ -210,7 +217,7 @@ void HWWall::SkyLine(HWDrawInfo *di, sector_t *fs, line_t *line) // //========================================================================== -void HWWall::SkyNormal(HWDrawInfo *di, sector_t * fs,vertex_t * v1,vertex_t * v2) +void HWWall::SkyNormal(HWWallDispatcher *di, sector_t * fs,vertex_t * v1,vertex_t * v2) { ztop[0]=ztop[1]=32768.0f; zbottom[0]=zceil[0]; @@ -229,7 +236,7 @@ void HWWall::SkyNormal(HWDrawInfo *di, sector_t * fs,vertex_t * v1,vertex_t * v2 // //========================================================================== -void HWWall::SkyTop(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2) +void HWWall::SkyTop(HWWallDispatcher *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2) { if (fs->GetTexture(sector_t::ceiling)==skyflatnum) { @@ -323,7 +330,7 @@ void HWWall::SkyTop(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vert // //========================================================================== -void HWWall::SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2) +void HWWall::SkyBottom(HWWallDispatcher *di, seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex_t * v2) { if (fs->GetTexture(sector_t::floor)==skyflatnum) { @@ -343,8 +350,8 @@ void HWWall::SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,v } else { - // Special hack for Vrack2b - if (bs->floorplane.ZatPoint(di->Viewpoint.Pos) > di->Viewpoint.Pos.Z) return; + // Special hack for Vrack2b. For mesh based rendering this check needs to be done in the actual render pass! + if (di->di && bs->floorplane.ZatPoint(di->di->Viewpoint.Pos) > di->di->Viewpoint.Pos.Z) return; } } zbottom[0]=zbottom[1]=-32768.0f; diff --git a/src/rendering/hwrenderer/scene/hw_walldispatcher.h b/src/rendering/hwrenderer/scene/hw_walldispatcher.h new file mode 100644 index 000000000..4a2855391 --- /dev/null +++ b/src/rendering/hwrenderer/scene/hw_walldispatcher.h @@ -0,0 +1,80 @@ +#pragma once + +struct HWMissing +{ + side_t* side; + subsector_t* sub; + double plane; +}; + +struct HWMeshHelper +{ + TArray list; + TArray translucent; + TArray portals; + TArray lower; + TArray upper; +}; + + +struct HWWallDispatcher +{ + FLevelLocals* Level; + HWDrawInfo* di; + HWMeshHelper* mh; + ELightMode lightmode; + + HWWallDispatcher(HWDrawInfo* info) + { + Level = info->Level; + di = info; + mh = nullptr; + lightmode = info->lightmode; + } + + HWWallDispatcher(FLevelLocals* lev, HWMeshHelper* help, ELightMode lm) + { + Level = lev; + di = nullptr; + mh = help; + lightmode = lm; + } + + void AddUpperMissingTexture(side_t* side, subsector_t* sub, float height) + { + if (di) di->AddUpperMissingTexture(side, sub, height); + else + { + mh->upper.Reserve(1); + mh->upper.Last() = { side, sub, height }; + } + } + void AddLowerMissingTexture(side_t* side, subsector_t* sub, float height) + { + if (di) di->AddUpperMissingTexture(side, sub, height); + else + { + mh->lower.Reserve(1); + mh->lower.Last() = { side, sub, height }; + } + } + + bool isFullbrightScene() + { + // The mesh builder cannot know this and must treat everything as not fullbright. + return di && di->isFullbrightScene(); + } + + void AddWall(HWWall* wal) + { + if (di) di->AddWall(wal); + else if (!(wal->flags & HWWall::HWF_TRANSLUCENT)) mh->list.Push(*wal); + else mh->translucent.Push(*wal); + } + + void AddPortal(HWWall* wal) + { + mh->portals.Push(*wal); + } + +}; diff --git a/src/rendering/hwrenderer/scene/hw_walls.cpp b/src/rendering/hwrenderer/scene/hw_walls.cpp index b049ee172..c92481102 100644 --- a/src/rendering/hwrenderer/scene/hw_walls.cpp +++ b/src/rendering/hwrenderer/scene/hw_walls.cpp @@ -43,6 +43,7 @@ #include "hw_lightbuffer.h" #include "hw_renderstate.h" #include "hw_skydome.h" +#include "hw_walldispatcher.h" void SetGlowPlanes(FRenderState &state, const secplane_t& top, const secplane_t& bottom) @@ -80,7 +81,7 @@ void SetSplitPlanes(FRenderState& state, const secplane_t& top, const secplane_t // //========================================================================== -void HWWall::RenderWall(HWDrawInfo *di, FRenderState &state, int textured) +void HWWall::RenderWall(HWDrawInfo*di, FRenderState &state, int textured) { assert(vertcount > 0); state.SetLightIndex(dynlightindex); @@ -94,7 +95,7 @@ void HWWall::RenderWall(HWDrawInfo *di, FRenderState &state, int textured) // //========================================================================== -void HWWall::RenderFogBoundary(HWDrawInfo *di, FRenderState &state) +void HWWall::RenderFogBoundary(HWDrawInfo*di, FRenderState &state) { if (gl_fogmode && !di->isFullbrightScene()) { @@ -117,7 +118,7 @@ void HWWall::RenderFogBoundary(HWDrawInfo *di, FRenderState &state) // // //========================================================================== -void HWWall::RenderMirrorSurface(HWDrawInfo *di, FRenderState &state) +void HWWall::RenderMirrorSurface(HWDrawInfo*di, FRenderState &state) { if (!TexMan.mirrorTexture.isValid()) return; @@ -179,7 +180,7 @@ static const uint8_t renderwalltotier[] = CVAR(Bool, hw_npottest, false, 0) #endif -void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) +void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags) { int tmode = state.GetTextureMode(); int rel = rellight + getExtraLight(); @@ -312,7 +313,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) // //========================================================================== -void HWWall::RenderTranslucentWall(HWDrawInfo *di, FRenderState &state) +void HWWall::RenderTranslucentWall(HWDrawInfo*di, FRenderState &state) { state.SetRenderStyle(RenderStyle); if (texture) @@ -338,7 +339,7 @@ void HWWall::RenderTranslucentWall(HWDrawInfo *di, FRenderState &state) // // //========================================================================== -void HWWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent) +void HWWall::DrawWall(HWDrawInfo*di, FRenderState &state, bool translucent) { if (screen->BuffersArePersistent()) { @@ -379,7 +380,7 @@ void HWWall::DrawWall(HWDrawInfo *di, FRenderState &state, bool translucent) // //========================================================================== -void HWWall::SetupLights(HWDrawInfo *di, FDynLightData &lightdata) +void HWWall::SetupLights(HWDrawInfo*di, FDynLightData &lightdata) { lightdata.Clear(); @@ -493,58 +494,67 @@ const char HWWall::passflag[] = { // // //========================================================================== -void HWWall::PutWall(HWDrawInfo *di, bool translucent) +void HWWall::PutWall(HWWallDispatcher *di, bool translucent) { if (texture && texture->GetTranslucency() && passflag[type] == 2) { translucent = true; } + + auto ddi = di->di; if (translucent) { flags |= HWF_TRANSLUCENT; - ViewDistance = (di->Viewpoint.Pos - (seg->linedef->v1->fPos() + seg->linedef->Delta() / 2)).XY().LengthSquared(); } - - if (di->isFullbrightScene()) + + if (di->di) { - // light planes don't get drawn with fullbright rendering - if (texture == NULL) return; - Colormap.Clear(); - } - - if (di->isFullbrightScene() || (Colormap.LightColor.isWhite() && lightlevel == 255)) - { - flags &= ~HWF_GLOW; - } - - if (!screen->BuffersArePersistent()) - { - if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr) + if (translucent) { - SetupLights(di, lightdata); + ViewDistance = (ddi->Viewpoint.Pos - (seg->linedef->v1->fPos() + seg->linedef->Delta() / 2)).XY().LengthSquared(); } - MakeVertices(di, translucent); - } - - - bool solid; - if (passflag[type] == 1) solid = true; - else if (type == RENDERWALL_FFBLOCK) solid = texture && !texture->isMasked(); - else solid = false; - - bool hasDecals = solid && seg->sidedef && seg->sidedef->AttachedDecals; - if (hasDecals) - { - // If we want to use the light infos for the decal we cannot delay the creation until the render pass. - if (screen->BuffersArePersistent()) + if (ddi->isFullbrightScene()) { - if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr) + // light planes don't get drawn with fullbright rendering + if (texture == NULL) return; + Colormap.Clear(); + } + + if (ddi->isFullbrightScene() || (Colormap.LightColor.isWhite() && lightlevel == 255)) + { + flags &= ~HWF_GLOW; + } + + if (!screen->BuffersArePersistent()) + { + if (ddi->Level->HasDynamicLights && !ddi->isFullbrightScene() && texture != nullptr) { - SetupLights(di, lightdata); + SetupLights(ddi, lightdata); } + MakeVertices(ddi, translucent); + } + + + + bool solid; + if (passflag[type] == 1) solid = true; + else if (type == RENDERWALL_FFBLOCK) solid = texture && !texture->isMasked(); + else solid = false; + + bool hasDecals = solid && seg->sidedef && seg->sidedef->AttachedDecals; + if (hasDecals) + { + // If we want to use the light infos for the decal we cannot delay the creation until the render pass. + if (screen->BuffersArePersistent()) + { + if (ddi->Level->HasDynamicLights && !ddi->isFullbrightScene() && texture != nullptr) + { + SetupLights(ddi, lightdata); + } + } + ProcessDecals(ddi); } - ProcessDecals(di); } @@ -563,113 +573,123 @@ void HWWall::PutWall(HWDrawInfo *di, bool translucent) // //========================================================================== -void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane) +void HWWall::PutPortal(HWWallDispatcher *di, int ptype, int plane) { HWPortal * portal = nullptr; - MakeVertices(di, false); - switch (ptype) + auto ddi = di->di; + if (ddi) { - // portals don't go into the draw list. - // Instead they are added to the portal manager - case PORTALTYPE_HORIZON: - horizon = portalState.UniqueHorizons.Get(horizon); - portal = di->FindPortal(horizon); - if (!portal) + MakeVertices(ddi, false); + switch (ptype) { - portal = new HWHorizonPortal(&portalState, horizon, di->Viewpoint); - di->Portals.Push(portal); - } - portal->AddLine(this); - break; - - case PORTALTYPE_SKYBOX: - portal = di->FindPortal(secportal); - if (!portal) - { - // either a regular skybox or an Eternity-style horizon - if (secportal->mType != PORTS_SKYVIEWPOINT) portal = new HWEEHorizonPortal(&portalState, secportal); - else - { - portal = new HWSkyboxPortal(&portalState, secportal); - di->Portals.Push(portal); - } - } - portal->AddLine(this); - break; - - case PORTALTYPE_SECTORSTACK: - portal = di->FindPortal(this->portal); - if (!portal) - { - portal = new HWSectorStackPortal(&portalState, this->portal); - di->Portals.Push(portal); - } - portal->AddLine(this); - break; - - case PORTALTYPE_PLANEMIRROR: - if (portalState.PlaneMirrorMode * planemirror->fC() <= 0) - { - planemirror = portalState.UniquePlaneMirrors.Get(planemirror); - portal = di->FindPortal(planemirror); + // portals don't go into the draw list. + // Instead they are added to the portal manager + case PORTALTYPE_HORIZON: + horizon = portalState.UniqueHorizons.Get(horizon); + portal = ddi->FindPortal(horizon); if (!portal) { - portal = new HWPlaneMirrorPortal(&portalState, planemirror); - di->Portals.Push(portal); + portal = new HWHorizonPortal(&portalState, horizon, ddi->Viewpoint); + ddi->Portals.Push(portal); } portal->AddLine(this); - } - break; + break; - case PORTALTYPE_MIRROR: - portal = di->FindPortal(seg->linedef); - if (!portal) - { - portal = new HWMirrorPortal(&portalState, seg->linedef); - di->Portals.Push(portal); - } - portal->AddLine(this); - if (gl_mirror_envmap) - { - // draw a reflective layer over the mirror - di->AddMirrorSurface(this); - } - break; - - case PORTALTYPE_LINETOLINE: - if (!lineportal) - return; - portal = di->FindPortal(lineportal); - if (!portal) - { - line_t *otherside = lineportal->lines[0]->mDestination; - if (otherside != nullptr && otherside->portalindex < di->Level->linePortals.Size()) + case PORTALTYPE_SKYBOX: + portal = ddi->FindPortal(secportal); + if (!portal) { - di->ProcessActorsInPortal(otherside->getPortal()->mGroup, di->in_area); + // either a regular skybox or an Eternity-style horizon + if (secportal->mType != PORTS_SKYVIEWPOINT) portal = new HWEEHorizonPortal(&portalState, secportal); + else + { + portal = new HWSkyboxPortal(&portalState, secportal); + ddi->Portals.Push(portal); + } } - portal = new HWLineToLinePortal(&portalState, lineportal); - di->Portals.Push(portal); - } - portal->AddLine(this); - break; + portal->AddLine(this); + break; - case PORTALTYPE_SKY: - sky = portalState.UniqueSkies.Get(sky); - portal = di->FindPortal(sky); - if (!portal) + case PORTALTYPE_SECTORSTACK: + portal = ddi->FindPortal(this->portal); + if (!portal) + { + portal = new HWSectorStackPortal(&portalState, this->portal); + ddi->Portals.Push(portal); + } + portal->AddLine(this); + break; + + case PORTALTYPE_PLANEMIRROR: + if (portalState.PlaneMirrorMode * planemirror->fC() <= 0) + { + planemirror = portalState.UniquePlaneMirrors.Get(planemirror); + portal = ddi->FindPortal(planemirror); + if (!portal) + { + portal = new HWPlaneMirrorPortal(&portalState, planemirror); + ddi->Portals.Push(portal); + } + portal->AddLine(this); + } + break; + + case PORTALTYPE_MIRROR: + portal = ddi->FindPortal(seg->linedef); + if (!portal) + { + portal = new HWMirrorPortal(&portalState, seg->linedef); + ddi->Portals.Push(portal); + } + portal->AddLine(this); + if (gl_mirror_envmap) + { + // draw a reflective layer over the mirror + ddi->AddMirrorSurface(this); + } + break; + + case PORTALTYPE_LINETOLINE: + if (!lineportal) + return; + portal = ddi->FindPortal(lineportal); + if (!portal) + { + line_t* otherside = lineportal->lines[0]->mDestination; + if (otherside != nullptr && otherside->portalindex < ddi->Level->linePortals.Size()) + { + ddi->ProcessActorsInPortal(otherside->getPortal()->mGroup, ddi->in_area); + } + portal = new HWLineToLinePortal(&portalState, lineportal); + ddi->Portals.Push(portal); + } + portal->AddLine(this); + break; + + case PORTALTYPE_SKY: + sky = portalState.UniqueSkies.Get(sky); + portal = ddi->FindPortal(sky); + if (!portal) + { + portal = new HWSkyPortal(screen->mSkyData, &portalState, sky); + ddi->Portals.Push(portal); + } + portal->AddLine(this); + break; + } + vertcount = 0; + + if (plane != -1 && portal) { - portal = new HWSkyPortal(screen->mSkyData, &portalState, sky); - di->Portals.Push(portal); + portal->planesused |= (1 << plane); } - portal->AddLine(this); - break; } - vertcount = 0; - - if (plane != -1 && portal) + else { - portal->planesused |= (1<AddPortal(this); } } @@ -679,7 +699,7 @@ void HWWall::PutPortal(HWDrawInfo *di, int ptype, int plane) // //========================================================================== -void HWWall::Put3DWall(HWDrawInfo *di, lightlist_t * lightlist, bool translucent) +void HWWall::Put3DWall(HWWallDispatcher *di, lightlist_t * lightlist, bool translucent) { // only modify the light di->Level-> if it doesn't originate from the seg's frontsector. This is to account for light transferring effects if (lightlist->p_lightlevel != &seg->sidedef->sector->lightlevel) @@ -699,7 +719,7 @@ void HWWall::Put3DWall(HWDrawInfo *di, lightlist_t * lightlist, bool translucent // //========================================================================== -bool HWWall::SplitWallComplex(HWDrawInfo *di, sector_t * frontsector, bool translucent, float& maplightbottomleft, float& maplightbottomright) +bool HWWall::SplitWallComplex(HWWallDispatcher *di, sector_t * frontsector, bool translucent, float& maplightbottomleft, float& maplightbottomright) { // check for an intersection with the upper plane if ((maplightbottomleftztop[1]) || @@ -793,7 +813,7 @@ bool HWWall::SplitWallComplex(HWDrawInfo *di, sector_t * frontsector, bool trans return false; } -void HWWall::SplitWall(HWDrawInfo *di, sector_t * frontsector, bool translucent) +void HWWall::SplitWall(HWWallDispatcher *di, sector_t * frontsector, bool translucent) { float maplightbottomleft; float maplightbottomright; @@ -908,7 +928,7 @@ out: // // //========================================================================== -bool HWWall::DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) +bool HWWall::DoHorizon(HWWallDispatcher *di, seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2) { HWHorizonInfo hi; lightlist_t * light; @@ -917,64 +937,73 @@ bool HWWall::DoHorizon(HWDrawInfo *di, seg_t * seg,sector_t * fs, vertex_t * v1, ztop[1] = ztop[0] = fs->GetPlaneTexZ(sector_t::ceiling); zbottom[1] = zbottom[0] = fs->GetPlaneTexZ(sector_t::floor); - auto vpz = di->Viewpoint.Pos.Z; - if (vpz < fs->GetPlaneTexZ(sector_t::ceiling)) + auto ddi = di->di; + if (ddi) { + auto vpz = ddi->Viewpoint.Pos.Z; + if (vpz < fs->GetPlaneTexZ(sector_t::ceiling)) + { + if (vpz > fs->GetPlaneTexZ(sector_t::floor)) + zbottom[1] = zbottom[0] = vpz; + + if (fs->GetTexture(sector_t::ceiling) == skyflatnum) + { + SkyPlane(di, fs, sector_t::ceiling, false); + } + else + { + hi.plane.GetFromSector(fs, sector_t::ceiling); + hi.lightlevel = hw_ClampLight(fs->GetCeilingLight()); + hi.colormap = fs->Colormap; + hi.specialcolor = fs->SpecialColors[sector_t::ceiling]; + + if (fs->e->XFloor.ffloors.Size()) + { + light = P_GetPlaneLight(fs, &fs->ceilingplane, true); + + if (!(fs->GetFlags(sector_t::ceiling) & PLANEF_ABSLIGHTING)) hi.lightlevel = hw_ClampLight(*light->p_lightlevel); + hi.colormap.CopyLight(light->extra_colormap); + } + + if (ddi->isFullbrightScene()) hi.colormap.Clear(); + horizon = &hi; + PutPortal(di, PORTALTYPE_HORIZON, -1); + } + ztop[1] = ztop[0] = zbottom[0]; + } + if (vpz > fs->GetPlaneTexZ(sector_t::floor)) - zbottom[1] = zbottom[0] = vpz; - - if (fs->GetTexture(sector_t::ceiling) == skyflatnum) { - SkyPlane(di, fs, sector_t::ceiling, false); - } - else - { - hi.plane.GetFromSector(fs, sector_t::ceiling); - hi.lightlevel = hw_ClampLight(fs->GetCeilingLight()); - hi.colormap = fs->Colormap; - hi.specialcolor = fs->SpecialColors[sector_t::ceiling]; - - if (fs->e->XFloor.ffloors.Size()) + zbottom[1] = zbottom[0] = fs->GetPlaneTexZ(sector_t::floor); + if (fs->GetTexture(sector_t::floor) == skyflatnum) { - light = P_GetPlaneLight(fs, &fs->ceilingplane, true); - - if(!(fs->GetFlags(sector_t::ceiling)&PLANEF_ABSLIGHTING)) hi.lightlevel = hw_ClampLight(*light->p_lightlevel); - hi.colormap.CopyLight(light->extra_colormap); + SkyPlane(di, fs, sector_t::floor, false); } + else + { + hi.plane.GetFromSector(fs, sector_t::floor); + hi.lightlevel = hw_ClampLight(fs->GetFloorLight()); + hi.colormap = fs->Colormap; + hi.specialcolor = fs->SpecialColors[sector_t::floor]; - if (di->isFullbrightScene()) hi.colormap.Clear(); - horizon = &hi; - PutPortal(di, PORTALTYPE_HORIZON, -1); + if (fs->e->XFloor.ffloors.Size()) + { + light = P_GetPlaneLight(fs, &fs->floorplane, false); + + if (!(fs->GetFlags(sector_t::floor) & PLANEF_ABSLIGHTING)) hi.lightlevel = hw_ClampLight(*light->p_lightlevel); + hi.colormap.CopyLight(light->extra_colormap); + } + + if (ddi->isFullbrightScene()) hi.colormap.Clear(); + horizon = &hi; + PutPortal(di, PORTALTYPE_HORIZON, -1); + } } - ztop[1] = ztop[0] = zbottom[0]; - } - - if (vpz > fs->GetPlaneTexZ(sector_t::floor)) + } + else { - zbottom[1] = zbottom[0] = fs->GetPlaneTexZ(sector_t::floor); - if (fs->GetTexture(sector_t::floor) == skyflatnum) - { - SkyPlane(di, fs, sector_t::floor, false); - } - else - { - hi.plane.GetFromSector(fs, sector_t::floor); - hi.lightlevel = hw_ClampLight(fs->GetFloorLight()); - hi.colormap = fs->Colormap; - hi.specialcolor = fs->SpecialColors[sector_t::floor]; - - if (fs->e->XFloor.ffloors.Size()) - { - light = P_GetPlaneLight(fs, &fs->floorplane, false); - - if(!(fs->GetFlags(sector_t::floor)&PLANEF_ABSLIGHTING)) hi.lightlevel = hw_ClampLight(*light->p_lightlevel); - hi.colormap.CopyLight(light->extra_colormap); - } - - if (di->isFullbrightScene()) hi.colormap.Clear(); - horizon = &hi; - PutPortal(di, PORTALTYPE_HORIZON, -1); - } + // we cannot build the real portal yet, the mesh builder just needs a generic 'horizon' portal that needs to be filled in in the render pass. + PutPortal(di, PORTALTYPE_HORIZON, -1); } return true; } @@ -1225,7 +1254,7 @@ static void GetTexCoordInfo(FGameTexture *tex, FTexCoordInfo *tci, side_t *side, // Handle one sided walls, upper and lower texture // //========================================================================== -void HWWall::DoTexture(HWDrawInfo *di, int _type,seg_t * seg, int peg, +void HWWall::DoTexture(HWWallDispatcher *di, int _type,seg_t * seg, int peg, float ceilingrefheight,float floorrefheight, float topleft,float topright, float bottomleft,float bottomright, @@ -1284,7 +1313,7 @@ void HWWall::DoTexture(HWDrawInfo *di, int _type,seg_t * seg, int peg, // Add this wall to the render list sector_t * sec = sub ? sub->sector : seg->frontsector; - if (sec->e->XFloor.lightlist.Size()==0 || di->isFullbrightScene()) PutWall(di, false); + if (sec->e->XFloor.lightlist.Size()==0 || di->isFullbrightScene()) PutWall(di, false); else SplitWall(di, sec, false); } @@ -1299,7 +1328,7 @@ void HWWall::DoTexture(HWDrawInfo *di, int _type,seg_t * seg, int peg, // //========================================================================== -void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, +void HWWall::DoMidTexture(HWWallDispatcher *di, seg_t * seg, bool drawfogboundary, sector_t * front, sector_t * back, sector_t * realfront, sector_t * realback, float fch1, float fch2, float ffh1, float ffh2, @@ -1634,7 +1663,7 @@ void HWWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, // // //========================================================================== -void HWWall::BuildFFBlock(HWDrawInfo *di, seg_t * seg, F3DFloor * rover, int roverIndex, +void HWWall::BuildFFBlock(HWWallDispatcher *di, seg_t * seg, F3DFloor * rover, int roverIndex, float ff_topleft, float ff_topright, float ff_bottomleft, float ff_bottomright) { @@ -1788,7 +1817,7 @@ __forceinline void HWWall::GetPlanePos(F3DFloor::planeref *planeref, float &left // // //========================================================================== -void HWWall::InverseFloors(HWDrawInfo *di, seg_t * seg, sector_t * frontsector, +void HWWall::InverseFloors(HWWallDispatcher *di, seg_t * seg, sector_t * frontsector, float topleft, float topright, float bottomleft, float bottomright) { @@ -1839,7 +1868,7 @@ void HWWall::InverseFloors(HWDrawInfo *di, seg_t * seg, sector_t * frontsector, // // //========================================================================== -void HWWall::ClipFFloors(HWDrawInfo *di, seg_t * seg, F3DFloor * ffloor, int ffloorIndex, sector_t * frontsector, +void HWWall::ClipFFloors(HWWallDispatcher *di, seg_t * seg, F3DFloor * ffloor, int ffloorIndex, sector_t * frontsector, float topleft, float topright, float bottomleft, float bottomright) { @@ -1913,7 +1942,7 @@ done: // // //========================================================================== -void HWWall::DoFFloorBlocks(HWDrawInfo *di, seg_t * seg, sector_t * frontsector, sector_t * backsector, +void HWWall::DoFFloorBlocks(HWWallDispatcher *di, seg_t * seg, sector_t * frontsector, sector_t * backsector, float fch1, float fch2, float ffh1, float ffh2, float bch1, float bch2, float bfh1, float bfh2) @@ -2018,7 +2047,7 @@ inline int CalcRelLight(int lightlevel, int orglightlevel, int rel) // // //========================================================================== -void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_t * backsector) +void HWWall::Process(HWWallDispatcher *di, seg_t *seg, sector_t * frontsector, sector_t * backsector) { vertex_t * v1, *v2; float fch1; @@ -2273,7 +2302,7 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ /* mid texture */ sector_t *backsec = isportal? seg->linedef->getPortalDestination()->frontsector : backsector; - bool drawfogboundary = !di->isFullbrightScene() && di->CheckFog(frontsector, backsec); + bool drawfogboundary = !di->isFullbrightScene() && CheckFog(di->Level, frontsector, backsec, di->lightmode); auto tex = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::mid), true); if (tex != NULL && tex->isValid()) { @@ -2378,7 +2407,7 @@ void HWWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ // // //========================================================================== -void HWWall::ProcessLowerMiniseg(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_t * backsector) +void HWWall::ProcessLowerMiniseg(HWWallDispatcher *di, seg_t *seg, sector_t * frontsector, sector_t * backsector) { if (frontsector->GetTexture(sector_t::floor) == skyflatnum) return; lightlist = NULL;